summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-08 14:30:41 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2014-08-12 13:49:54 +0200
commitab0a50979b9eb4dfa3320eff7e187e41efedf7a9 (patch)
tree498dfb8a97ff3361a9f7486863a52bb4e26bb898 /chromium/third_party/WebKit/Source/core
parent4ce69f7403811819800e7c5ae1318b2647e778d1 (diff)
Update Chromium to beta version 37.0.2062.68
Change-Id: I188e3b5aff1bec75566014291b654eb19f5bc8ca Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'chromium/third_party/WebKit/Source/core')
-rw-r--r--chromium/third_party/WebKit/Source/core/BUILD.gn1072
-rw-r--r--chromium/third_party/WebKit/Source/core/DEPS19
-rw-r--r--chromium/third_party/WebKit/Source/core/Init.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/Init.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/OWNERS13
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.cpp3
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXList.cpp41
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXList.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXListBox.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXListBox.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.cpp41
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXMockObject.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.cpp347
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXObject.cpp66
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXObject.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.cpp151
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXProgressIndicator.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.cpp324
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXSVGRoot.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXSlider.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXSpinButton.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTable.cpp83
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTable.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableColor.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableColor.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableColorTest.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableDoubleTest.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableImage.cpp49
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableImage.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLength.cpp206
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLength.h125
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint3D.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint3D.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableLengthTest.cpp378
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableNeutral.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableNeutralTest.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.cpp49
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayListTest.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableUnknown.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableUnknownTest.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableValue.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableValue.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableValueKeyframe.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableValueKeyframe.h75
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelperTest.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/Animation.cpp218
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/Animation.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/Animation.idl41
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationClock.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationClock.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationClockTest.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationEffect.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationEffect.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationHelpers.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationHelpersTest.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationNode.cpp195
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationNode.h171
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationNode.idl47
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationNodeTest.cpp775
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationNodeTiming.cpp180
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationNodeTiming.h46
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.cpp460
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.h195
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.idl51
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationPlayerTest.cpp737
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationStack.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationStack.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationStackTest.cpp163
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTest.cpp467
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTestHelper.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTestHelper.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.cpp232
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.h143
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.idl11
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTimelineTest.cpp293
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp127
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtil.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtilTest.cpp115
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp202
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsImpl.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp458
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp108
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/DocumentAnimation.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/DocumentAnimation.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/DocumentTimeline.cpp187
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/DocumentTimeline.h141
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/DocumentTimelineTest.cpp287
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/EffectInput.cpp128
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/EffectInput.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/EffectInputTest.cpp125
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/ElementAnimation.cpp142
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/ElementAnimation.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/ElementAnimation.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/ElementAnimationTest.cpp208
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/InertAnimation.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/InertAnimation.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/InterpolableValue.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/InterpolableValue.h167
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/InterpolableValueTest.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/InterpolationEffect.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/InterpolationEffect.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/InterpolationEffectTest.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/Keyframe.h102
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp367
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.h155
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffectTest.cpp379
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp255
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModel.h179
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp564
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/Player.cpp204
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/Player.h102
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/PlayerTest.cpp364
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/SampledEffect.cpp66
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/SampledEffect.h51
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/StringKeyframe.cpp152
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/StringKeyframe.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimedItem.cpp148
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimedItem.h148
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimedItemCalculations.h200
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimedItemCalculationsTest.cpp227
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimedItemTest.cpp782
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/Timing.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/Timing.idl29
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimingCalculations.h198
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimingCalculationsTest.cpp214
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimingInput.cpp154
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimingInput.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/TimingInputTest.cpp181
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp173
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSAnimationData.h61
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp726
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.h146
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp94
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp318
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSTimingData.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSTimingData.h50
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSTransitionData.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/CSSTransitionData.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/css/TransitionTimeline.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/DefaultStyleInterpolation.h46
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolation.cpp152
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolation.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolationTest.cpp94
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/Interpolation.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/Interpolation.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/LegacyStyleInterpolation.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolation.cpp109
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolation.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolationTest.cpp119
-rw-r--r--chromium/third_party/WebKit/Source/core/animation/interpolation/StyleInterpolation.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/Clipboard.cpp543
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/Clipboard.h144
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/ClipboardAccessPolicy.h (renamed from chromium/third_party/WebKit/Source/core/dom/ClipboardAccessPolicy.h)0
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataObject.cpp267
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataObject.h119
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataObjectItem.cpp179
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataObjectItem.h98
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataTransfer.idl45
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp106
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.h74
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.idl41
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp116
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.h72
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.idl44
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/Pasteboard.cpp139
-rw-r--r--chromium/third_party/WebKit/Source/core/clipboard/Pasteboard.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/core.gni37
-rw-r--r--chromium/third_party/WebKit/Source/core/core.gyp441
-rw-r--r--chromium/third_party/WebKit/Source/core/core.gypi1394
-rw-r--r--chromium/third_party/WebKit/Source/core/core_derived_sources.gyp662
-rw-r--r--chromium/third_party/WebKit/Source/core/core_generated.gyp828
-rw-r--r--chromium/third_party/WebKit/Source/core/core_generated.gypi9
-rw-r--r--chromium/third_party/WebKit/Source/core/css/AffectedByFocusTest.cpp316
-rw-r--r--chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp237
-rw-r--r--chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSS.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSAspectRatioValue.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.cpp427
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.h240
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSBorderImage.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSBorderImage.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp345
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp196
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.idl2
-rw-r--r--[-rwxr-xr-x]chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp1142
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h104
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSCustomFontData.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.cpp175
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFilterRule.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFilterRule.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFilterValue.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFilterValue.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFace.cpp232
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFace.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.cpp266
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFaceTest.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontFeatureValue.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontSelector.cpp142
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontSelector.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontSelectorClient.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontValue.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFontValue.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGradientValue.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGradientValue.h92
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGrammar.y267
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGridTemplateValue.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGridTemplateValue.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSImageValue.cpp66
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSImageValue.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSImportRule.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSImportRule.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSInheritedValue.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSInitialValue.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSLengthFunctions.cpp149
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSLengthFunctions.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSLineBoxContainValue.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSMarkup.cpp189
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSMarkup.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSMatrix.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSMatrix.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSMediaRule.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSMediaRule.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSMixFunctionValue.cpp61
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSMixFunctionValue.h61
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSOMUtils.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSOMUtils.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSPageRule.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSPageRule.h14
-rwxr-xr-xchromium/third_party/WebKit/Source/core/css/CSSParser-in.cpp10465
-rwxr-xr-xchromium/third_party/WebKit/Source/core/css/CSSParser.h676
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSParserMode.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSParserMode.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSParserValues.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSParserValues.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSParserValuesTest.cpp41
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp697
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h197
-rw-r--r--[-rwxr-xr-x]chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h475
-rw-r--r--[-rwxr-xr-x]chromium/third_party/WebKit/Source/core/css/CSSProperties.in145
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSProperty.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSProperty.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSPropertyNames.in35
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSReflectValue.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSReflectValue.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSRegionRule.cpp61
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSRegionRule.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSRule.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSRule.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSRule.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSRuleList.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSRuleList.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSRuleList.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.cpp151
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFaceCache.cpp208
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFaceCache.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSelector.cpp391
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSelector.h156
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSelectorList.cpp41
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSelectorList.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSelectorTest.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSShaderValue.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSShaderValue.h72
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSShadowValue.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSShadowValue.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSShorthands.in2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSStyleRule.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSStyleRule.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp222
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSSupportsRule.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSTestHelper.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSTestHelper.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp56
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSTokenizer-in.cpp174
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSTokenizer.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSTransformValue.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSTransformValue.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSUnicodeRangeValue.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSUnknownRule.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSValue.cpp302
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSValue.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSValue.idl1
-rw-r--r--[-rwxr-xr-x]chromium/third_party/WebKit/Source/core/css/CSSValueKeywords.in244
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSValueList.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSValueList.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSValuePool.cpp77
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSValuePool.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSVariableValue.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSVariablesIterator.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.cpp121
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.idl36
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSVariablesMapForEachCallback.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSVariablesMapForEachCallback.idl31
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSViewportRule.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/CSSViewportRule.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/css/Counter.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/css/Counter.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/css/Counter.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/DragUpdateTest.cpp69
-rw-r--r--chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp161
-rw-r--r--chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.h87
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFace.cpp393
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFace.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFace.idl29
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFaceCache.cpp225
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFaceCache.h85
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFaceSet.cpp421
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFaceSet.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFaceSet.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFaceSetForEachCallback.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontFaceSetForEachCallback.idl34
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontLoader.cpp95
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontLoader.h51
-rw-r--r--chromium/third_party/WebKit/Source/core/css/FontSize.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/HashTools.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/css/InspectorCSSOMWrappers.cpp125
-rw-r--r--chromium/third_party/WebKit/Source/core/css/InspectorCSSOMWrappers.h61
-rw-r--r--chromium/third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/css/LocalFontFaceSource.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.h87
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.in42
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaList.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaList.h50
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaList.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQuery.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQuery.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp440
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryExp.cpp301
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryExp.h73
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryList.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryList.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryList.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaQuerySetTest.cpp171
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaTypeNames.in15
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaValues.cpp206
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaValues.h88
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaValuesCached.cpp169
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaValuesCached.h85
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp132
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaValuesDynamic.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/css/MediaValuesTest.cpp61
-rw-r--r--chromium/third_party/WebKit/Source/core/css/PageRuleCollector.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/css/PageRuleCollector.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/css/Pair.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/css/Pair.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp234
-rw-r--r--chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h109
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RGBColor.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RGBColor.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RGBColor.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/css/Rect.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/css/Rect.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/css/Rect.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp193
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RemoteFontFaceSource.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RuleFeature.cpp513
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RuleFeature.h156
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RuleSet.cpp340
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RuleSet.h126
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RuleSetTest.cpp139
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SVGCSSParser.cpp427
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in1
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SelectorChecker.cpp396
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SelectorChecker.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp224
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SelectorFilter.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SelectorFilter.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/SiblingTraversalStrategies.h91
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleColor.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleInvalidationAnalysis.cpp218
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleInvalidationAnalysis.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleMedia.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleMedia.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleMedia.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp323
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StylePropertySet.cpp318
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StylePropertySet.h97
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StylePropertyShorthandCustom.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleRule.cpp162
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleRule.h134
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleRuleImport.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleSheet.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleSheet.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleSheetContents.cpp287
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleSheetList.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleSheetList.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/css/StyleSheetList.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/css/WebKitCSSFilterValue.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/css/WebKitCSSMatrix.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/css/WebKitCSSMixFunctionValue.idl34
-rw-r--r--chromium/third_party/WebKit/Source/core/css/WebKitCSSRegionRule.idl36
-rw-r--r--chromium/third_party/WebKit/Source/core/css/WebKitCSSTransformValue.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/css/fullscreen.css1
-rw-r--r--chromium/third_party/WebKit/Source/core/css/html.css84
-rw-r--r--chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSet.cpp196
-rw-r--r--chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSet.h103
-rw-r--r--chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSetTest.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp167
-rw-r--r--chromium/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h96
-rw-r--r--chromium/third_party/WebKit/Source/core/css/invalidation/StyleSheetInvalidationAnalysis.cpp216
-rw-r--r--chromium/third_party/WebKit/Source/core/css/invalidation/StyleSheetInvalidationAnalysis.h59
-rwxr-xr-xchromium/third_party/WebKit/Source/core/css/make-css-file-arrays.pl6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/mathml.css49
-rw-r--r--chromium/third_party/WebKit/Source/core/css/mediaControls.css74
-rw-r--r--chromium/third_party/WebKit/Source/core/css/mediaControlsAndroid.css34
-rw-r--r--chromium/third_party/WebKit/Source/core/css/navigationTransitions.css13
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParser-in.cpp2119
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParser.h327
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParserTest.cpp67
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/CSSParserIdioms.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/CSSParserObserver.h69
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp8435
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h410
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaConditionTest.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryBlockWatcher.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryBlockWatcher.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp66
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.h57
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp265
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h107
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp129
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryToken.h88
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp527
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.h85
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizerTest.cpp173
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.cpp141
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParserTest.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParser.cpp214
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParser.h59
-rw-r--r--chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParserTest.cpp136
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp152
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp245
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp304
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp164
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/FontBuilderTest.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/MatchRequest.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/MatchResult.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp65
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleTree.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp79
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp412
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilder.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp314
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h23
-rw-r--r--[-rwxr-xr-x]chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp1908
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp890
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.h142
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverIncludes.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverParentScope.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverParentScope.h78
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp41
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp78
-rw-r--r--chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/css/svg.css11
-rw-r--r--chromium/third_party/WebKit/Source/core/css/themeChromium.css2
-rw-r--r--chromium/third_party/WebKit/Source/core/css/themeChromiumAndroid.css17
-rw-r--r--chromium/third_party/WebKit/Source/core/css/themeMac.css20
-rw-r--r--chromium/third_party/WebKit/Source/core/css/themeWin.css1
-rw-r--r--chromium/third_party/WebKit/Source/core/css/view-source.css5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ActiveDOMObjectTest.cpp107
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Attr.cpp115
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Attr.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Attr.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CDATASection.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CharacterData.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp106
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildNode.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildNode.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClassCollection.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClassCollection.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClassNodeList.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClassNodeList.h75
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRect.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRect.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRectList.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Clipboard.cpp525
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Clipboard.h140
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Clipboard.idl43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Comment.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Comment.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Comment.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp536
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContainerNode.h262
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.cpp158
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h240
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMError.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMError.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMException.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMException.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMException.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp134
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMImplementationTest.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMStringList.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURL.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItem.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItem.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItem.idl40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.cpp110
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.h69
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.idl40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp88
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Document.cpp2925
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Document.h765
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Document.idl83
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.cpp56
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentInit.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp118
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h110
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp136
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentParser.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp167
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentTest.cpp207
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentType.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/DocumentType.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Element.cpp1778
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Element.h382
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Element.idl107
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementData.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementData.h148
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementDataCache.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementDataCache.h59
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementRareData.h202
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h302
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Entity.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Entity.idl25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp168
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl53
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IconURL.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IconURL.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h193
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.h198
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessageChannel.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessagePort.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MessagePort.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Microtask.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Microtask.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationCallback.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp119
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserver.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationRecord.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NameNodeList.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedFlow.cpp249
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedFlow.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.cpp131
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.h75
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl22
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NoEventDispatchAssertion.h76
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Node.cpp871
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Node.h364
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Node.idl33
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilter.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIterator.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeList.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeList.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeList.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRareData.h283
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.cpp281
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.h76
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp170
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h106
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Notation.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ParentNode.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ParentNode.idl40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PendingScript.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Position.cpp126
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Position.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PositionIterator.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp199
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Promise.h46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Promise.idl46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/PseudoElement.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/QualifiedName.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Range.cpp657
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Range.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Range.idl25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RangeTest.cpp144
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp177
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.h78
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp39
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SecurityContext.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp531
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h69
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleElement.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp485
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleEngine.h146
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp140
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h78
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp221
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h100
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TagCollection.cpp65
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TagCollection.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TagNodeList.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TagNodeList.h91
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Text.cpp95
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Text.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Text.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Touch.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Touch.h74
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Touch.idl24
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchController.cpp162
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchController.h76
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchList.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchList.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TouchList.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TransformSource.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Traversal.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/Traversal.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp247
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScope.h69
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp233
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h116
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeShared.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeWalker.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl22
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/URL.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/URLUtils.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp121
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlow.idl42
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlowCollection.idl39
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WheelController.cpp121
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/WheelController.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/XMLDocument.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/XMLDocument.h59
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/XMLDocument.idl27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.cpp121
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp134
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h89
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStep.h61
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementProcessingStep.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.cpp155
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h86
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp137
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp151
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl23
-rw-r--r--chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.cpp317
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/Caret.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/Caret.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.cpp404
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.h111
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/CompositionUnderline.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilter.cpp39
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilter.h78
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilterTest.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.cpp175
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/EditCommand.cpp50
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/EditCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/EditingBehavior.cpp267
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/EditingBehavior.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/EditingStyle.cpp337
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/EditingStyle.h50
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/Editor.cpp376
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/Editor.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/EditorCommand.cpp789
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/EditorKeyBindings.cpp243
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/FrameSelection.cpp257
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/FrameSelection.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.cpp71
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InputMethodController.cpp69
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InputMethodController.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertListCommand.cpp118
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertListCommand.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.cpp377
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ModifySelectionListLevel.cpp293
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ModifySelectionListLevel.h92
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/PlainTextRange.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/PlainTextRange.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RenderedPosition.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/RenderedPosition.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.cpp274
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SetSelectionCommand.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SetSelectionCommand.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SpellChecker.cpp156
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SpellChecker.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SpellingCorrectionCommand.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SpellingCorrectionCommand.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SurroundingText.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SurroundingText.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp264
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextGranularity.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextIterator.cpp368
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextIterator.h82
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp148
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TypingCommand.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/TypingCommand.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/UndoStack.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/UndoStack.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/UndoStep.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/UnlinkCommand.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/VisiblePosition.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/VisiblePosition.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/VisibleSelection.cpp166
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/VisibleSelection.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/VisibleSelectionTest.cpp171
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/VisibleUnits.cpp138
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/VisibleUnits.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/htmlediting.cpp261
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/htmlediting.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/markup.cpp387
-rw-r--r--chromium/third_party/WebKit/Source/core/editing/markup.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.idl12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.idl12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/AutocompleteErrorEvent.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/events/BeforeLoadEvent.h89
-rw-r--r--chromium/third_party/WebKit/Source/core/events/BeforeLoadEvent.idl32
-rw-r--r--chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ClipboardEvent.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ClipboardEvent.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/events/CompositionEvent.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/events/CompositionEvent.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/events/CompositionEvent.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/events/CustomEvent.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/events/CustomEvent.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ErrorEvent.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ErrorEvent.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/events/Event.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/events/Event.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/events/Event.idl13
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventAliases.in2
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventContext.cpp100
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventContext.h117
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventDispatcher.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventDispatcher.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventFactory.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventListener.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventListenerMap.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventPath.cpp305
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventPath.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventQueue.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventRetargeter.cpp187
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventRetargeter.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventSender.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventTarget.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventTarget.h130
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventTarget.idl11
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventTargetFactory.in34
-rw-r--r--chromium/third_party/WebKit/Source/core/events/EventTypeNames.in19
-rw-r--r--chromium/third_party/WebKit/Source/core/events/FocusEvent.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/core/events/FocusEvent.h50
-rw-r--r--chromium/third_party/WebKit/Source/core/events/GenericEventQueue.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/events/GenericEventQueue.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/events/GestureEvent.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/events/GestureEvent.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/events/HashChangeEvent.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/events/KeyboardEvent.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/events/KeyboardEvent.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MessageEvent.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MessageEvent.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MessageEvent.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MouseEvent.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MouseEvent.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MouseEvent.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MutationEvent.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/MutationEvent.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/events/NavigatorEvents.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/events/NavigatorEvents.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/events/NavigatorEvents.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/events/NodeEventContext.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/events/NodeEventContext.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/events/OverflowEvent.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/events/OverflowEvent.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/events/PopStateEvent.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/events/PopStateEvent.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ProgressEvent.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ProgressEvent.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TextEvent.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TextEvent.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/events/ThreadLocalEventNames.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TouchEvent.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TouchEvent.h57
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TouchEvent.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TouchEventContext.cpp66
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TouchEventContext.h61
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TransitionEvent.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TransitionEvent.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TreeScopeEventContext.cpp97
-rw-r--r--chromium/third_party/WebKit/Source/core/events/TreeScopeEventContext.h120
-rw-r--r--chromium/third_party/WebKit/Source/core/events/UIEvent.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/UIEvent.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/events/UIEventWithKeyState.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/events/WheelEvent.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/events/WheelEvent.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/events/WheelEvent.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/events/WindowEventContext.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/events/WindowEventContext.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/CachedMetadata.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/CachingCorrectnessTest.cpp580
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/DocumentResource.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/DocumentResource.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/DocumentResourceReference.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/FetchContext.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/FetchContext.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/FetchInitiatorTypeNames.in3
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/FetchRequest.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/FetchRequest.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/FontResource.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/FontResource.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ImageResource.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ImageResource.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ImageResourceClient.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/MemoryCache.cpp362
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/MemoryCache.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/RawResource.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/RawResource.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/Resource.cpp516
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/Resource.h127
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp579
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.h103
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp131
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderHost.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderOptions.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ScriptResource.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ScriptResource.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ShaderResource.cpp61
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/ShaderResource.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/StyleSheetResource.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/TextResource.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/TextResource.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/TextResourceDecoder.cpp437
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/TextResourceDecoder.h105
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/Blob.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/Blob.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/Blob.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/BlobBuilder.cpp155
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/BlobBuilder.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/File.cpp78
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/File.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/File.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileError.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileList.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileList.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileList.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileReader.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileReader.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileReader.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/Stream.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/fileapi/Stream.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/AdjustViewSizeOrNot.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/BarProp.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/BarProp.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/BarProp.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Console.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Console.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ConsoleBase.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ConsoleBase.h46
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ConsoleBase.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp2032
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicy.h171
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp41
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMPoint.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMSecurityPolicy.cpp174
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMSecurityPolicy.h72
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMTimer.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMTimer.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindow.cpp1890
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindow.h390
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DeprecatedScheduleStyleRecalcDuringLayout.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DeviceEventControllerBase.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DeviceEventControllerBase.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DeviceEventDispatcherBase.cpp87
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DeviceEventDispatcherBase.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/EventHandlerRegistry.cpp255
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/EventHandlerRegistry.h96
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Frame.cpp601
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Frame.h364
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameClient.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameConsole.cpp123
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameConsole.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameHost.cpp94
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameHost.h92
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameOwner.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameView.cpp1847
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/FrameView.h333
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/GraphicsLayerDebugInfo.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/GraphicsLayerDebugInfo.h50
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/History.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/History.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/History.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ImageBitmap.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ImageBitmap.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ImageBitmap.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp95
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp1946
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/LocalDOMWindow.h414
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp660
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/LocalFrame.h249
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Location.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Location.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Location.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Navigator.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Navigator.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Navigator.idl12
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorBase.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorID.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorID.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorID.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/PRESUBMIT.py57
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/PinchViewport.cpp453
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/PinchViewport.h165
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/RemoteFrame.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/RemoteFrame.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/RemoteFrameView.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Screen.cpp49
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Screen.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Screen.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/SecurityPolicy.idl45
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Settings.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Settings.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Settings.in88
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/SettingsDelegate.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/SmartClip.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/SmartClip.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/UseCounter.cpp254
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/UseCounter.h662
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/WebKitPoint.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/Window.idl128
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/WindowBase64.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/WindowTimers.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/AnimationBase.cpp585
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/AnimationBase.h228
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/AnimationController.cpp542
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/AnimationController.h104
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/AnimationControllerPrivate.h140
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/CSSPropertyAnimation.cpp1153
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/CSSPropertyAnimation.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/CompositeAnimation.cpp510
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/CompositeAnimation.h96
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/ImplicitAnimation.cpp283
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/ImplicitAnimation.h98
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/KeyframeAnimation.cpp455
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/animation/KeyframeAnimation.h102
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/CSPDirective.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp679
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h141
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp93
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/CSPSource.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp485
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/CSPSourceList.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp786
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h203
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/MediaListDirective.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/frame/csp/SourceListDirective.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/history/HistoryItem.cpp262
-rw-r--r--chromium/third_party/WebKit/Source/core/history/HistoryItem.h146
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ClassList.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ClassList.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/CollectionIndexCache.h208
-rw-r--r--chromium/third_party/WebKit/Source/core/html/CollectionType.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/DOMFormData.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp165
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormData.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormDataList.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/FormDataList.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp215
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp167
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp298
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h74
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp666
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCollection.h152
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLContentElement.cpp131
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h96
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLContentElement.idl31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp94
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDocument.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp372
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLElement.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLElement.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp141
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp157
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp565
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h98
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp131
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp349
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h73
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImport.cpp190
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImport.h193
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportChild.cpp174
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportChild.h97
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportChildClient.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.cpp181
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.h101
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportLoaderClient.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportsController.cpp175
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLImportsController.h95
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp402
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h202
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp258
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLLinkElementSizesAttributeTest.cpp77
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp1580
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h349
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp138
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLModElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp159
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp107
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp174
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLRTElement.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLRTElement.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp399
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.cpp83
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.idl33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp163
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp176
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp100
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp123
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp135
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp107
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp89
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageData.cpp83
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageData.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageData.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp85
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ImageDocument.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LabelableElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkImport.cpp126
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkImport.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkManifest.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkManifest.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp67
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkResource.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/LinkResource.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaController.cpp249
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaController.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaController.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaControllerInterface.h89
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaDocument.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaError.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaError.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/core/html/PluginDocument.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/PublicURLManager.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/html/RadioNodeList.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TextDocument.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TextDocument.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TextMetrics.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TextMetrics.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/URLRegistry.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ValidityState.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ValidityState.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/WindowNameCollection.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/WindowNameCollection.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.idl20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp87
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.idl32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp1395
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h143
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl266
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/DOMPath.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/DataView.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.idl12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Path.idl68
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Path2D.h90
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/Path2D.idl41
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.idl11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp81
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtensionName.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp211
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp5569
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h887
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl641
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp5728
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h914
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.idl689
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.cpp269
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/FormController.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp216
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/InputType.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp282
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/StepRange.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp144
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/Composition.cpp83
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/Composition.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/Composition.idl39
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.cpp143
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.h147
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp236
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.h112
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChildClient.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp229
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.h133
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportState.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp83
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp110
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp184
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.h95
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/LinkImport.cpp150
-rw-r--r--chromium/third_party/WebKit/Source/core/html/imports/LinkImport.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp56
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp114
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp224
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp106
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h51
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp100
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp135
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThreadTest.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp201
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp279
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParserTest.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizerNames.in8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp186
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.cpp439
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.h106
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp371
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp8
-rwxr-xr-xchromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table133
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h104
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp120
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.h107
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.idl32
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.idl35
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp128
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h84
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp411
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h130
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp410
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h137
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.cpp225
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp172
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.h73
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp277
-rw-r--r--chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h83
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrack.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrack.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrack.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp118
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrack.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl21
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp71
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackBase.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackBase.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/TrackListBase.h139
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrack.cpp88
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrack.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrack.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp357
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp190
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp149
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp171
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h233
-rw-r--r--chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp352
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp215
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/BUILD.gn98
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/BindingVisitors.h8
-rwxr-xr-xchromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py109
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspectorStrings.py132
-rwxr-xr-x[-rw-r--r--]chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py13
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp81
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp119
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/DOMEditor.cpp214
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/DOMEditor.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/DOMPatchSupport.cpp150
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScript.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScript.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js557
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptExterns.js24
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptModule.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InjectedScriptSource.js701
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorAgent.cpp169
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorAgent.h98
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp1193
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h141
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.cpp93
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasInstrumentation.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorClient.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorClient.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleInstrumentation.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorController.cpp237
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorController.h61
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorCounters.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp563
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h164
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp135
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseAgent.cpp334
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseAgent.h87
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseInstrumentation.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseResource.cpp65
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseResource.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp375
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h149
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorFileSystemAgent.cpp729
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorFileSystemAgent.h72
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendChannel.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendClient.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp175
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorIndexedDBAgent.cpp773
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorIndexedDBAgent.h73
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorInspectorAgent.cpp161
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorInspectorAgent.h98
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp35
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl193
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentationCustomInl.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp235
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorNodeIds.cpp35
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorNodeIds.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.cpp336
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html80
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp509
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h169
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp195
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp134
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.cpp81
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorState.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.cpp1072
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h205
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.cpp540
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.h157
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp334
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h144
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h50
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/InstrumentingAgents.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/JSONParser.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp110
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptDebugListener.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.cpp91
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.h156
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.cpp39
-rw-r--r--chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.h20
-rwxr-xr-xchromium/third_party/WebKit/Source/core/inspector/combine-javascript-resources.pl81
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/BeaconLoader.cpp130
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/BeaconLoader.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp332
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h96
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp293
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h88
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoaderClient.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp52
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/EmptyClients.h137
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FormState.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FormState.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FormSubmission.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp981
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameLoader.h106
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h90
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/HistoryController.cpp347
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/HistoryController.h180
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/HistoryItem.cpp217
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/HistoryItem.h138
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp270
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/ImageLoader.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/LinkLoader.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/NavigationAction.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp140
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/PingLoader.h50
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp77
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/SinkDocument.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/SubstituteData.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClientWrapper.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridge.cpp162
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridge.h73
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp146
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp156
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp280
-rw-r--r--chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/make_core_derived_sources.xml68
-rw-r--r--chromium/third_party/WebKit/Source/core/page/AutoscrollController.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/page/AutoscrollController.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/page/Chrome.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/page/Chrome.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/page/ChromeClient.h108
-rw-r--r--chromium/third_party/WebKit/Source/core/page/ContextMenuController.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/page/CreateWindow.cpp93
-rw-r--r--chromium/third_party/WebKit/Source/core/page/CreateWindow.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DOMSelection.cpp138
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DOMSelection.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DragActions.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DragClient.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DragController.cpp163
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DragController.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DragData.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DragData.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/page/DragState.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/page/EditorClient.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/page/EventHandler.cpp1296
-rw-r--r--chromium/third_party/WebKit/Source/core/page/EventHandler.h118
-rw-r--r--chromium/third_party/WebKit/Source/core/page/EventSource.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/page/EventSource.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/page/EventSource.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/page/FocusController.cpp394
-rw-r--r--chromium/third_party/WebKit/Source/core/page/FocusController.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/page/FocusDirection.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/page/FocusType.h50
-rw-r--r--chromium/third_party/WebKit/Source/core/page/FrameTree.cpp155
-rw-r--r--chromium/third_party/WebKit/Source/core/page/FrameTree.h116
-rw-r--r--chromium/third_party/WebKit/Source/core/page/InjectedStyleSheet.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/page/InjectedStyleSheets.cpp65
-rw-r--r--chromium/third_party/WebKit/Source/core/page/InjectedStyleSheets.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp122
-rw-r--r--chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/page/NetworkStateNotifierTest.cpp280
-rw-r--r--chromium/third_party/WebKit/Source/core/page/Page.cpp418
-rw-r--r--chromium/third_party/WebKit/Source/core/page/Page.h146
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageAnimator.cpp82
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageAnimator.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageConsole.cpp123
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageConsole.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageGroup.cpp88
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageGroup.h78
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp77
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageLifecycleNotifier.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageLifecycleObserver.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PagePopupClient.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PagePopupClient.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PagePopupController.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PagePopupController.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PagePopupController.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageSerializer.cpp206
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PageSerializer.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PointerLockController.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PointerLockController.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PrintContext.cpp56
-rw-r--r--chromium/third_party/WebKit/Source/core/page/PrintContext.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp79
-rw-r--r--chromium/third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/page/Selection.idl35
-rw-r--r--chromium/third_party/WebKit/Source/core/page/SpatialNavigation.cpp422
-rw-r--r--chromium/third_party/WebKit/Source/core/page/SpatialNavigation.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/page/StorageClient.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/page/TouchAdjustment.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/core/page/TouchAdjustment.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.cpp38
-rw-r--r--chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/page/ValidationMessageClient.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/page/WindowFeatures.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/page/WindowPagePopup.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingConstraints.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp508
-rw-r--r--chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/CryptoResult.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/DEPS15
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/DragImage.cpp267
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/DragImage.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/Pasteboard.cpp139
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/Pasteboard.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtil.cpp355
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtil.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtilTest.cpp352
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/AnimationValue.h114
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationData.cpp128
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationData.h192
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationDataList.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationDataList.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/KeyframeValueList.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/KeyframeValueList.h90
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/TimingFunction.h330
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelper.cpp253
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelper.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelperTest.cpp326
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObject.cpp266
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObject.h109
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObjectItem.cpp182
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObjectItem.h98
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversion.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversionAndroid.cpp329
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversionGtk.cpp436
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/support/WebArrayBuffer.cpp103
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/support/WebCrypto.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/support/WebMediaStream.cpp161
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/support/WebMediaStreamTrack.cpp146
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCSessionDescription.cpp109
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCSessionDescriptionRequest.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCStatsRequest.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mac/ThemeMac.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mac/ThemeMac.mm728
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamCenter.cpp127
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamCenter.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamDescriptor.cpp136
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamDescriptor.h105
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandler.cpp135
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandler.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandlerClient.h51
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandler.cpp219
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandler.h108
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandlerClient.h86
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mediastream/RTCStatsRequest.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mock/GeolocationClientMock.cpp190
-rw-r--r--chromium/third_party/WebKit/Source/core/platform/mock/GeolocationClientMock.h99
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/MimeType.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/MimeTypeArray.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/Plugin.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/PluginArray.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/PluginOcclusionSupport.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/plugins/PluginView.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/BidiRun.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/BidiRun.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ClipPathOperation.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ClipRect.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ColumnInfo.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp2228
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMapping.h359
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/CompositingReasons.h105
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp1104
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.h248
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FixedTableLayout.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.cpp191
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.cpp210
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.h51
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/HitTestRequest.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/HitTestResult.cpp95
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/HitTestResult.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/InlineBox.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/InlineBox.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.cpp345
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h130
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.cpp502
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayerPaintingInfo.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayoutIndicator.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayoutIndicator.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayoutRectRecorder.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayoutRectRecorder.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayoutState.cpp233
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LayoutState.h104
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LineWidth.cpp197
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/LineWidth.h88
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/OrderIterator.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/OrderIterator.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/Pagination.cpp67
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/Pagination.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/PaintInfo.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/PartialLayoutState.h103
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RegionOversetState.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderApplet.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderApplet.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBR.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBR.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBlock.cpp1820
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBlock.h323
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.cpp987
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.h162
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBlockLineLayout.cpp1282
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBox.cpp1502
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBox.h206
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.cpp415
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.h59
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderBoxRegionInfo.h59
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderButton.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderButton.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderCounter.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderCounter.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp127
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.cpp106
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.cpp323
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.cpp678
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.h120
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFrame.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFrame.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderGrid.cpp769
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderGrid.h51
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.cpp94
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderImage.cpp201
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderImage.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderInline.cpp156
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderInline.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderInputSpeech.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderInputSpeech.h55
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayer.cpp1991
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayer.h438
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp114
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.h91
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp244
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp2605
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerCompositor.h372
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp78
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.cpp174
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp715
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.h43
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.cpp434
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.h102
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNodeIterator.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderListBox.cpp299
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderListBox.h69
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderListItem.cpp196
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderListItem.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.cpp64
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.cpp20
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMedia.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMedia.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.cpp205
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMeter.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMeter.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp200
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.h83
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp294
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h105
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp351
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h161
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowFragment.cpp108
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowFragment.h74
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowThread.cpp730
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowThread.h144
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderObject.cpp1497
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderObject.h492
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderObjectChildList.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderOverflow.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderPart.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderPart.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderProgress.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderProgress.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRegion.cpp495
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRegion.h130
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRegionSet.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRegionSet.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.cpp166
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderReplica.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderReplica.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRuby.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRuby.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderSelectionInfo.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderSlider.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderSlider.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTable.cpp366
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTable.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.cpp92
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.h75
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.cpp113
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.cpp374
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderText.cpp245
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderText.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.cpp149
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTheme.cpp223
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTheme.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.mm175
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.h92
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumWin.cpp660
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumWin.h114
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.cpp149
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderVideo.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderVideo.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderView.cpp590
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderView.h268
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderWidget.cpp223
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderWidget.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RenderWordBreak.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.cpp279
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ScrollAlignment.cpp146
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ScrollAlignment.h83
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp146
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.h83
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp288
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/TrailingFloatsRootInlineBox.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/animation/WebAnimationProvider.cpp214
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/animation/WebAnimationProvider.h76
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp2246
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.h419
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMappingPtr.h (renamed from chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMappingPtr.h)0
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingInputsUpdater.cpp94
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingInputsUpdater.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingLayerAssigner.cpp279
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingLayerAssigner.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp236
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingRequirementsUpdater.cpp460
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingRequirementsUpdater.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingState.h (renamed from chromium/third_party/WebKit/Source/core/rendering/CompositingState.h)0
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingTriggers.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerTreeBuilder.cpp124
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerTreeBuilder.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp117
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp1259
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.h280
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp69
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/BreakingContextInlineHeaders.h488
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp114
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/LineBreaker.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/LineInfo.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/LineLayoutState.h130
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/LineWidth.cpp214
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/LineWidth.h92
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/RenderTextInfo.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/TrailingObjects.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/TrailingObjects.h94
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/line/WordMeasurement.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShapeTest.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.cpp506
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.h51
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.cpp244
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.h71
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.cpp133
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.cpp161
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInfo.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInfo.h179
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInsideInfo.cpp121
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInsideInfo.h122
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInterval.h177
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.cpp297
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.h83
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/AppliedTextDecoration.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/AppliedTextDecoration.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.cpp202
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.h256
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/BorderData.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/BorderValue.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/CachedUAStyle.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/CollapsedBorderValue.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/ContentData.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/CursorList.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/DataEquivalency.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/GridCoordinate.h85
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/GridLength.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/GridPosition.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/GridResolvedPosition.cpp253
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/GridResolvedPosition.h125
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/GridTrackSize.h46
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/NinePieceImage.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/OutlineValue.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.cpp1005
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.h681
-rw-r--r--[-rwxr-xr-x]chromium/third_party/WebKit/Source/core/rendering/style/RenderStyleConstants.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.cpp81
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.h103
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.cpp32
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.h44
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.cpp35
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/ShapeValue.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleBoxData.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgram.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgram.h193
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgramCache.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgramCache.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleDifference.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedShader.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedShader.h57
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleImage.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.cpp3
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.h1
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StylePendingImage.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StylePendingShader.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp113
-rw-r--r--[-rwxr-xr-x]chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleShader.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleVariableData.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp24
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/ReferenceFilterBuilder.cpp43
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.cpp41
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.cpp59
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.cpp137
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGPath.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.cpp71
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.cpp61
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.cpp218
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceGradient.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceLinearGradient.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.cpp33
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceRadialGradient.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.cpp239
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.cpp136
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.cpp114
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.h46
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp45
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.cpp69
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.cpp79
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.cpp350
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.h45
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGMarkerData.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGPathData.cpp93
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.cpp111
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.cpp116
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.cpp72
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.cpp180
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.cpp154
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.cpp81
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextChunkBuilder.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.cpp50
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineBaseline.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp51
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.cpp29
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp238
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp18
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInput.cpp130
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInput.h90
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputClient.h76
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.h59
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.idl31
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputListener.h67
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.h61
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.idl33
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.cpp56
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.idl33
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/Storage.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/Storage.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/Storage.idl29
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/StorageArea.cpp197
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/StorageArea.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/StorageEvent.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/StorageEvent.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/StorageNamespace.cpp66
-rw-r--r--chromium/third_party/WebKit/Source/core/storage/StorageNamespace.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/ColorDistance.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/ColorDistance.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/LinearGradientAttributes.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/PatternAttributes.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/RadialGradientAttributes.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAElement.cpp117
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAElement.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp25
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAngle.cpp274
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAngle.h84
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAngle.idl14
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp125
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAngleTearOff.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.idl28
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp245
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp15
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp165
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.h88
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.cpp88
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp95
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.h86
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp163
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.h94
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp116
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.h91
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp125
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp138
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.h82
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.cpp135
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.h73
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp126
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.h89
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.cpp110
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp85
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp156
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.h68
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.cpp117
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.cpp88
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.cpp102
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.h81
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.cpp97
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp152
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.h72
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp330
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedType.h306
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp250
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.h214
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp65
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.idl12
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAnimatorFactory.h102
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGAttributeNames.in5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGBoolean.cpp85
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGBoolean.h86
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp44
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGColor.cpp110
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGColor.h100
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGColor.idl38
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp128
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.h72
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.cpp78
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDescElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDescElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp58
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.h59
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.idl32
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDocument.cpp109
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDocument.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDocument.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp171
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElement.cpp721
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElement.h166
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElement.idl12
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.cpp272
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.h194
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.idl82
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.h46
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.idl30
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGElementRareData.h87
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGEnumeration.cpp127
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGEnumeration.h127
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.cpp120
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.idl33
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp77
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.idl19
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp88
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.h57
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.idl16
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp55
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp135
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.h77
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.idl28
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp279
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.h86
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.idl33
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp126
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp110
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.h65
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.idl18
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp73
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp79
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.cpp157
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp21
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp103
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.idl20
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp60
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp144
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp137
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.h93
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.idl20
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.cpp177
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp54
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.cpp80
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontData.cpp69
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontData.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontElement.cpp189
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontElement.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp76
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp39
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSource.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp19
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp104
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGElement.cpp23
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGElement.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGlyphMap.h82
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp100
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp149
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGImageElement.cpp132
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGImageElement.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGImageElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGInteger.cpp101
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGInteger.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGIntegerOptionalInteger.cpp115
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGIntegerOptionalInteger.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLength.cpp345
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLength.h151
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLength.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.h11
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLengthList.cpp159
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLengthList.h85
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLengthList.idl22
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLengthListTearOff.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp148
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLengthTearOff.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLineElement.cpp63
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLineElement.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLineElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp152
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.cpp61
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp178
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.h117
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.idl31
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.h49
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMatrix.h129
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMatrix.idl36
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp179
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMatrixTearOff.h105
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumber.cpp143
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumber.h74
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumber.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumberList.cpp166
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumberList.h91
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumberList.idl22
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumberListTearOff.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp112
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp57
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGNumberTearOff.h56
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPaint.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPaint.h85
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPaint.idl44
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.cpp297
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.h46
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathBuilder.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathByteStream.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp119
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.h75
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathElement.cpp250
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathElement.h96
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathElement.idl62
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathParser.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.cpp50
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.h47
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.idl19
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.idl19
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.idl13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.cpp207
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.h180
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.idl23
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.h34
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegListTearOff.h82
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathSegWithContext.h48
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.cpp116
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathStringSource.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp142
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.h22
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.cpp201
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.idl19
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPoint.cpp147
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPoint.h105
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPoint.idl13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPointList.cpp182
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPointList.h83
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPointList.idl23
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPointListTearOff.h58
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPointTearOff.cpp75
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPointTearOff.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.cpp179
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.h53
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatioTearOff.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatioTearOff.h78
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.cpp177
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRect.cpp169
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRect.h97
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRect.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRectElement.cpp81
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRectElement.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRectElement.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp90
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRectTearOff.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGRenderingIntent.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp571
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.h150
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.idl35
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp105
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.h59
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSetElement.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSetElement.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStaticStringList.cpp96
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStaticStringList.h74
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStopElement.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStopElement.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGString.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGString.h96
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStringList.cpp134
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStringList.h107
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStringList.idl22
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStringListTearOff.cpp42
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStringListTearOff.h147
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp12
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.cpp36
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.h16
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.cpp49
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTagNames.in46
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTests.cpp177
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTests.h35
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTests.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp156
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.h80
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextElement.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextElement.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp100
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.h89
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp99
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.h33
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransform.cpp86
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransform.h76
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransform.idl22
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp199
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformList.cpp336
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformList.h88
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformList.idl25
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp65
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformListTearOff.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp124
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGTransformTearOff.h79
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGURIReference.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGURIReference.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGURIReference.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.h32
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGUseElement.cpp708
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGUseElement.h88
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGUseElement.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGViewElement.cpp46
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGViewElement.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGViewElement.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.cpp219
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.h72
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.idl15
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.cpp35
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.idl10
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.idl9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/animation/SMILTime.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp267
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.h54
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp498
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.h88
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp204
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.h25
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.cpp9
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp93
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp1
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp184
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h64
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedListPropertyTearOff.h191
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h118
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp93
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.h330
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyDescription.h87
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyMacros.h190
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyTearOff.h124
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedStaticPropertyTearOff.h116
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp147
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGListProperty.h482
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyHelper.h371
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyTearOff.h231
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyTearOffHelper.h228
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGMatrixTearOff.h108
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp137
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.h164
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGProperty.h109
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyInfo.h40
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h209
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTraits.h63
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGStaticListPropertyTearOff.h122
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGStaticPropertyTearOff.h66
-rw-r--r--chromium/third_party/WebKit/Source/core/svg/properties/SVGTransformListPropertyTearOff.h82
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/GCObservation.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/GCObservation.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/InspectorFrontendClientLocal.cpp129
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/InspectorFrontendClientLocal.h72
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/InternalProfilers.cpp2
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/InternalProfilers.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/InternalProfilers.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/InternalSettings.cpp128
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/InternalSettings.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/InternalSettings.idl11
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/Internals.cpp1046
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/Internals.h136
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/Internals.idl58
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/LayerRect.h29
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/LayerRect.idl11
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/LayerRectList.cpp13
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/LayerRectList.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/LayerRectList.idl2
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/MallocStatistics.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/MallocStatistics.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.cpp48
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/NullExecutionContext.h57
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/TypeConversions.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/TypeConversions.idl17
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp34
-rw-r--r--chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/MemoryInfo.cpp14
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/MemoryInfo.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/MemoryInfo.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/Performance.cpp69
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/Performance.h37
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/Performance.idl25
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceMark.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceMeasure.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h19
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp37
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/timing/ResourceTimingInfo.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/AbstractWorker.cpp4
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/AbstractWorker.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/AbstractWorker.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp49
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorker.cpp28
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorker.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorker.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h3
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/Worker.cpp27
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/Worker.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/Worker.idl3
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerClients.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerConsole.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerConsole.h23
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.h13
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp146
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h111
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.h6
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerLoaderProxy.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerLocation.h9
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerLocation.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.cpp26
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp5
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.idl6
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.h62
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h39
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp174
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.h31
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp22
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h8
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerSupplementable.h42
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerThread.cpp79
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerThread.h24
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.h20
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/DOMParser.cpp8
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/DOMParser.h12
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/DOMParser.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.cpp50
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.idl7
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.cpp10
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.h14
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLErrors.cpp47
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLErrors.h7
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.cpp286
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.h70
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.idl8
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.idl4
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp53
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.h36
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLSerializer.cpp7
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLSerializer.h10
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLSerializer.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.cpp11
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.cpp16
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.h18
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathExpression.cpp31
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathExpression.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathExpression.idl5
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.h122
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathFunctions.cpp203
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathFunctions.h41
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathGrammar.y54
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.h5
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp85
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.h75
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathParser.cpp98
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathParser.h28
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathPath.cpp70
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathPath.h82
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathPredicate.cpp153
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathPredicate.h179
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathResult.cpp127
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathResult.h15
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathResult.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathStep.cpp452
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathStep.h27
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathUtil.cpp62
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathUtil.h21
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathValue.cpp117
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathValue.h141
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.cpp6
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.h30
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLImportRule.cpp30
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLImportRule.h17
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLStyleSheet.h38
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp68
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLTExtensions.cpp17
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp40
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.h26
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.idl1
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp74
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp212
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.h2
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp77
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReader.h60
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReaderTest.cpp119
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp396
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h249
-rw-r--r--chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.h33
3690 files changed, 171801 insertions, 166746 deletions
diff --git a/chromium/third_party/WebKit/Source/core/BUILD.gn b/chromium/third_party/WebKit/Source/core/BUILD.gn
new file mode 100644
index 00000000000..a44296af42a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/BUILD.gn
@@ -0,0 +1,1072 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/ui.gni")
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+import("//third_party/WebKit/Source/bindings/core/v8/generated.gni")
+import("//third_party/WebKit/Source/bindings/modules/modules.gni")
+import("//third_party/WebKit/Source/bindings/modules/v8/generated.gni")
+import("//third_party/WebKit/Source/bindings/scripts/scripts.gni")
+import("//third_party/WebKit/Source/config.gni")
+import("//third_party/WebKit/Source/core/core.gni")
+import("//third_party/WebKit/Source/build/scripts/scripts.gni")
+import("//third_party/WebKit/Source/platform/platform_generated.gni")
+
+visibility = "//third_party/WebKit/Source/*"
+
+rel_blink_core_gen_dir = rebase_path(blink_core_output_dir, root_build_dir)
+
+# Compute the optimization level. The GYP code sets "optimize: max" which sets
+# speed-over-size optimization for official builds on Windows only. The GN's
+# build optimize_max config applies this optimization on all platforms, so
+# compute how to modify the config list to duplicate the GYP behavior.
+if (is_debug) {
+ core_config_remove = [ "//build/config/compiler:no_optimize" ]
+ core_config_add = core_config_remove # NOP
+} else {
+ core_config_remove = [ "//build/config/compiler:optimize" ]
+
+ if (is_win && is_official_build) {
+ core_config_add = [ "//build/config/compiler:optimize_max" ]
+ } else {
+ core_config_add = core_config_remove # NOP
+ }
+}
+
+# Core targets also get wexit time destructors.
+core_config_add += [ "//build/config/compiler:wexit_time_destructors" ]
+
+config("core_include_dirs") {
+ include_dirs = [
+ "..",
+ "../..",
+ # FIXME: Remove these once core scripts generates qualified
+ # includes correctly: http://crbug.com/358074
+ blink_core_output_dir,
+ blink_modules_output_dir,
+ bindings_core_v8_output_dir,
+ bindings_modules_v8_output_dir,
+ # FIXME: MediaQueryListListener.cpp includes
+ # "gen/blink/bindings/core/v8/V8MediaQueryList.h" relative to "gen/blink"
+ # which is busted. This file (and any other ones that do a similar thing)
+ # should be fixed and this can be removed.
+ "$root_gen_dir/blink",
+ ]
+ if (is_android && use_openmax_dl_fft) {
+ include_dirs += [ "//third_party/openmax_dl" ]
+ }
+}
+
+# GYP version: WebKit/Source/core/core.gyp:webcore_generated
+source_set("generated") {
+ deps = [
+ ":make_core_generated",
+ ":prerequisites",
+ "inspector:debugger_script_source",
+ "inspector:inspector_overlay_page",
+ "inspector:protocol_sources",
+ "inspector:injected_script_source",
+ "inspector:injected_canvas_script_source",
+ "inspector:instrumentation_sources",
+ "//gin",
+ "//skia",
+ "//third_party/iccjpeg",
+ "//third_party/libpng",
+ "//third_party/libwebp",
+ "//third_party/libxml",
+ "//third_party/libxslt",
+ "//third_party/npapi",
+ "//third_party/qcms",
+ "//third_party/sqlite",
+ "//third_party/WebKit/Source/bindings/core/v8:bindings_core_v8_generated",
+ # FIXME: don't depend on bindings/modules http://crbug.com/358074
+ "//third_party/WebKit/Source/bindings/modules:bindings_modules_generated",
+ "//third_party/WebKit/Source/bindings/modules/v8:bindings_modules_generated",
+ "//third_party/WebKit/Source/platform:make_platform_generated",
+ "//third_party/WebKit/Source/wtf",
+ "//url",
+ "//v8",
+ ]
+}
+
+# GYP version: WebKit/Source/core/core.gyp:webcore_prerequisites
+source_set("prerequisites") {
+ exported_deps = [
+ "//third_party/WebKit/Source/wtf",
+ "//gpu/command_buffer/client:gles2_c_lib",
+ "//skia",
+ "//third_party/angle:translator",
+ "//third_party/iccjpeg",
+ "//third_party/libpng",
+ "//third_party/libwebp",
+ "//third_party/libxml",
+ "//third_party/libxslt",
+ "//third_party/npapi",
+ "//third_party/ots",
+ "//third_party/qcms",
+ "//third_party/sqlite",
+ "//third_party/zlib",
+ "//url",
+ "//v8",
+ ]
+
+ deps = [
+ ":make_core_generated",
+ "inspector:debugger_script_source",
+ "inspector:injected_canvas_script_source",
+ "inspector:injected_script_source",
+ "inspector:inspector_overlay_page",
+ "inspector:protocol_sources",
+ "inspector:instrumentation_sources",
+ "//third_party/WebKit/Source/bindings/core/v8:bindings_core_v8_generated",
+ # FIXME: don't depend on bindings_modules http://crbug.com/358074
+ "//third_party/WebKit/Source/bindings/modules/v8:bindings_modules_generated",
+ "//third_party/WebKit/Source/platform",
+ ] + exported_deps
+
+ forward_dependent_configs_from = exported_deps
+
+ direct_dependent_configs = [
+ ":core_include_dirs",
+ "//third_party/WebKit/Source:config",
+ "//third_party/WebKit/Source:inside_blink",
+ ]
+}
+
+# Note that this is a source set rather than a group, even though it has no
+# sources. A group would implicitly forward all direct dependent configs
+# through it, but we want to keep our internal targets'
+# direct_dependent_configs private and only forward some of them.
+#
+# GYP version: WebKit/Source/core/core.gyp:webcore
+source_set("core") {
+ visibility = "//third_party/WebKit/*"
+
+ exported_deps = [
+ ":core_generated",
+ "//skia",
+ "//third_party/npapi",
+ "//third_party/qcms",
+ "//third_party/WebKit/Source/wtf",
+ "//url",
+ "//v8",
+ ]
+
+ configs -= core_config_remove
+ configs += core_config_add
+
+ deps = [
+ ":dom",
+ ":html",
+ ":remaining",
+ ":rendering",
+ ":svg",
+ ] + exported_deps
+
+ forward_dependent_configs_from = exported_deps
+
+ direct_dependent_configs = [
+ ":core_include_dirs",
+ ]
+
+ # TODO(GYP) IPP libraries pkg-config. These seem to be experimental and used
+ # only on x86 Android. See also below. There should be one pkg-config call
+ # that creates a config used in both of these cases.
+}
+
+# GYP version: //third_party/WebKit/Source/core/core.gyp:webcore_dom
+source_set("dom") {
+ sources = rebase_path(webcore_dom_files, ".", "//")
+
+ configs -= core_config_remove
+ configs += core_config_add
+
+ if (is_win) {
+ cflags = [ "/wd4267" ] # size_t to int truncation.
+ }
+
+ deps = [
+ ":prerequisites",
+ ]
+}
+
+# GYP version: //third_party/WebKit/Source/core/core.gyp:webcore_html
+source_set("html") {
+ sources = rebase_path(webcore_html_files, ".", "//")
+
+ configs -= core_config_remove
+ configs += core_config_add
+
+ deps = [
+ ":prerequisites",
+ ]
+
+ # TODO(GYP)
+ # Shard this target into parts to work around linker limitations.
+ # on link time code generation builds.
+ #['OS=="win" and buildtype=="Official"', {
+ # 'msvs_shard': 5,
+ #}],
+}
+
+# GYP version: //third_party/WebKit/Source/core/core.gyp:webcore_svg
+source_set("svg") {
+ sources = rebase_path(webcore_svg_files, ".", "//")
+
+ configs -= core_config_remove
+ configs += core_config_add
+
+ deps = [
+ ":prerequisites",
+ ]
+
+ # TODO(GYP)
+ # Shard this taret into parts to work around linker limitations.
+ # on link time code generation builds.
+ #['OS=="win" and buildtype=="Official"', {
+ # 'msvs_shard': 5,
+ #}],
+}
+
+# GYP version: //third_party/WebKit/Source/core/core.gyp:webcore_remaining
+source_set("remaining") {
+ # This is currently a mashup of "webcore_rendering" and "webcore_remaining"
+ # in GYP. The file list variable is the same and then GYP filters on wether
+ # the path starts with "rendering/" or not. We should tweak the .gypis a bit
+ # to separate out the rendering files.
+ sources = rebase_path(webcore_files, ".", "//")
+
+ configs -= core_config_remove
+ configs += core_config_add
+
+ cflags = []
+ libs = []
+
+ deps = [
+ ":prerequisites",
+ ]
+
+ if (is_win) {
+ cflags += [
+ "/wd4267",
+ "/wd4334",
+ ]
+ } else { # !is_win
+ sources -= [
+ "rendering/RenderThemeChromiumFontProviderWin.cpp",
+ ]
+ }
+ if (!is_linux) {
+ sources -= [
+ "rendering/RenderThemeChromiumFontProviderLinux.cpp",
+ ]
+ }
+
+ if (is_android) {
+ # Due to a bug in gcc 4.6 in android NDK, we got warnings about
+ # uninitialized variable.
+ # TODO: try removing now that we are on GCC 4.8.
+ cflags += [ "-Wno-uninitialized" ]
+ } else { # !is_android
+ sources -= [
+ "rendering/RenderThemeChromiumAndroid.cpp",
+ "rendering/RenderThemeChromiumAndroid.h",
+ ]
+ }
+
+ if (is_mac) {
+ sources -= [
+ "rendering/RenderThemeChromiumFontProvider.cpp",
+ "rendering/RenderThemeChromiumFontProvider.h",
+ "rendering/RenderThemeChromiumSkia.cpp",
+ "rendering/RenderThemeChromiumSkia.h",
+ ]
+ libs += [ "Carbon.framework" ]
+ } else { # !is_mac
+ sources -= [
+ "editing/SmartReplaceCF.cpp",
+ ]
+ }
+
+ if (!use_default_render_theme) {
+ sources -= [
+ "rendering/RenderThemeChromiumDefault.cpp",
+ "rendering/RenderThemeChromiumDefault.h",
+ ]
+ }
+}
+
+# GYP version: //third_party/WebKit/Source/core/core.gyp:webcore_rendering
+source_set("rendering") {
+ # The files that go here are currently in "remaining".
+}
+
+# GYP version: //third_party/WebKit/Source/core/core.gyp:webcore_generated
+source_set("core_generated") {
+ sources = bindings_v8_files
+ # These files include all the .cpp files generated from the .idl files
+ # in webcore_files.
+ sources += bindings_core_generated_aggregate_files
+
+ sources += [
+ # Additional .cpp files for HashTools.h
+ "$blink_core_output_dir/CSSPropertyNames.cpp",
+ "$blink_core_output_dir/CSSValueKeywords.cpp",
+
+ # Additional .cpp files from make_core_generated actions.
+ "$blink_core_output_dir/Event.cpp",
+ "$blink_core_output_dir/EventHeaders.h",
+ "$blink_core_output_dir/EventInterfaces.h",
+ "$blink_core_output_dir/EventNames.cpp",
+ "$blink_core_output_dir/EventNames.h",
+ "$blink_core_output_dir/EventTargetHeaders.h",
+ "$blink_core_output_dir/EventTargetInterfaces.h",
+ "$blink_core_output_dir/EventTargetNames.cpp",
+ "$blink_core_output_dir/EventTargetNames.h",
+ "$blink_core_output_dir/EventTypeNames.cpp",
+ "$blink_core_output_dir/EventTypeNames.h",
+ "$blink_core_output_dir/FetchInitiatorTypeNames.cpp",
+ "$blink_core_output_dir/HTMLElementFactory.cpp",
+ "$blink_core_output_dir/HTMLElementFactory.h",
+ "$blink_core_output_dir/HTMLElementLookupTrie.cpp",
+ "$blink_core_output_dir/HTMLElementLookupTrie.h",
+ "$blink_core_output_dir/HTMLNames.cpp",
+ "$blink_core_output_dir/HTMLTokenizerNames.cpp",
+ "$blink_core_output_dir/InputTypeNames.cpp",
+ "$blink_core_output_dir/MathMLNames.cpp",
+ "$blink_core_output_dir/SVGNames.cpp",
+ "$blink_core_output_dir/UserAgentStyleSheetsData.cpp",
+ "$blink_core_output_dir/V8HTMLElementWrapperFactory.cpp",
+ "$blink_core_output_dir/XLinkNames.cpp",
+ "$blink_core_output_dir/XMLNSNames.cpp",
+ "$blink_core_output_dir/XMLNames.cpp",
+
+ # Generated from HTMLEntityNames.in
+ "$blink_core_output_dir/HTMLEntityTable.cpp",
+
+ # Generated from MediaFeatureNames.in
+ "$blink_core_output_dir/MediaFeatureNames.cpp",
+
+ # Generated from MediaTypeNames.in
+ "$blink_core_output_dir/MediaTypeNames.cpp",
+
+ # Generated from CSSTokenizer-in.cpp
+ "$blink_core_output_dir/CSSTokenizer.cpp",
+
+ # Generated from BisonCSSParser-in.cpp
+ "$blink_core_output_dir/BisonCSSParser.cpp",
+
+ # Generated from HTMLMetaElement-in.cpp
+ "$blink_core_output_dir/HTMLMetaElement.cpp",
+
+ # Additional .cpp files from the make_core_generated rules.
+ "$blink_core_output_dir/CSSGrammar.cpp",
+ "$blink_core_output_dir/XPathGrammar.cpp",
+
+ # Additional .cpp files from the inspector_protocol_sources list.
+ "$blink_core_output_dir/InspectorFrontend.cpp",
+ "$blink_core_output_dir/InspectorBackendDispatcher.cpp",
+ "$blink_core_output_dir/InspectorTypeBuilder.cpp",
+
+ # Additional .cpp files from the inspector_instrumentation_sources list.
+ "$blink_core_output_dir/InspectorCanvasInstrumentationInl.h",
+ "$blink_core_output_dir/InspectorConsoleInstrumentationInl.h",
+ "$blink_core_output_dir/InspectorInstrumentationInl.h",
+ "$blink_core_output_dir/InspectorOverridesInl.h",
+ "$blink_core_output_dir/InstrumentingAgentsInl.h",
+ "$blink_core_output_dir/InspectorInstrumentationImpl.cpp",
+
+ # Additional .cpp files for SVG.
+ "$blink_core_output_dir/SVGElementFactory.cpp",
+ "$blink_core_output_dir/V8SVGElementWrapperFactory.cpp",
+
+ # Generated from make_style_shorthands.py
+ "$blink_core_output_dir/StylePropertyShorthand.cpp",
+
+ # Generated from make_style_builder.py
+ "$blink_core_output_dir/StyleBuilder.cpp",
+ "$blink_core_output_dir/StyleBuilderFunctions.cpp",
+ ]
+
+ configs -= core_config_remove
+ configs += core_config_add
+
+ configs += [
+ "..:inside_blink",
+ ]
+
+ deps = [
+ ":make_core_generated",
+ ":prerequisites",
+ "inspector:inspector_overlay_page",
+ "inspector:protocol_sources",
+ "inspector:instrumentation_sources",
+ "inspector:injected_canvas_script_source",
+ "inspector:injected_script_source",
+ "inspector:debugger_script_source",
+ "//gin",
+ "//skia",
+ "//third_party/iccjpeg",
+ "//third_party/libpng",
+ "//third_party/libwebp",
+ "//third_party/libxml",
+ "//third_party/libxslt",
+ "//third_party/npapi",
+ "//third_party/qcms",
+ "//third_party/sqlite",
+ "//third_party/WebKit/Source/bindings/core/v8:bindings_core_v8_generated",
+ # FIXME: don't depend on bindings/modules http://crbug.com/358074
+ "//third_party/WebKit/Source/bindings/modules:bindings_modules_generated",
+ "//third_party/WebKit/Source/bindings/modules/v8:bindings_modules_generated",
+ "//third_party/WebKit/Source/platform:make_platform_generated",
+ "//third_party/WebKit/Source/wtf",
+ "//url",
+ "//v8",
+ ]
+
+ configs += [ ":core_include_dirs" ]
+ include_dirs = [
+ "$root_gen_dir/blink",
+ ]
+
+ cflags = []
+ defines = []
+
+ if (is_win && component_mode == "shared_library") {
+ defines += [ "USING_V8_SHARED" ]
+ }
+
+ if (is_win) {
+ cflags += [
+ # In generated bindings code: "switch contains default but no case".
+ # Disable c4267 warnings until we fix size_t to int truncations.
+ # 4702 is disabled because of issues in Bison-generated
+ # XPathGrammar.cpp and CSSGrammar.cpp.
+ "/wd4065",
+ "/wd4267",
+ "/wd4702",
+ ]
+ }
+
+ # TODO(GYP) More IPP libraries, see above.
+ #if ((is_linux || is_android) && use_webaudio_ipp)
+ # ["OS in ("linux", "android") and "WTF_USE_WEBAUDIO_IPP=1" in feature_defines", {
+ # "cflags": [
+ # "<!@(pkg-config --cflags-only-I ipp)",
+ # ],
+ # }],
+ #],
+}
+
+# core_bindings_generated ------------------------------------------------------
+
+# GYP version: WebKit/Source/core/core_generated.gyp:core_event_interfaces
+generate_event_interfaces("core_event_interfaces") {
+ sources = core_event_idl_files
+ output_file = "core/EventInterfaces.in"
+}
+
+# generated_testing_idls -------------------------------------------------------
+
+# GYP version: WebKit/Source/core/core_generated.gyp:generated_testing_idls
+group("generated_testing_idls") {
+ deps = [
+ ":generated_testing_idls_settings",
+ ":generated_testing_idls_internal_runtime_flags",
+ ]
+}
+
+# "Settings" action in generated_testing_idls from GYP.
+action("generated_testing_idls_settings") {
+ script = "../build/scripts/make_settings.py"
+
+ source_prereqs = scripts_for_in_files + [
+ "../build/scripts/make_settings.py",
+ "../build/scripts/templates/InternalSettingsGenerated.idl.tmpl",
+ "../build/scripts/templates/InternalSettingsGenerated.cpp.tmpl",
+ "../build/scripts/templates/InternalSettingsGenerated.h.tmpl",
+ "../build/scripts/templates/SettingsMacros.h.tmpl",
+ "frame/Settings.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/SettingsMacros.h",
+ "$blink_core_output_dir/InternalSettingsGenerated.idl",
+ "$blink_core_output_dir/InternalSettingsGenerated.cpp",
+ "$blink_core_output_dir/InternalSettingsGenerated.h",
+ ]
+
+ args = [
+ rebase_path("frame/Settings.in", root_build_dir),
+ "--output_dir", rel_blink_core_gen_dir,
+ ]
+}
+
+# "InternalRuntimeFlags" action in generated_testing_idls from GYP.
+action("generated_testing_idls_internal_runtime_flags") {
+ script = "../build/scripts/make_internal_runtime_flags.py"
+
+ source_prereqs = scripts_for_in_files + [
+ "../build/scripts/make_internal_runtime_flags.py",
+ "../platform/RuntimeEnabledFeatures.in",
+ "../build/scripts/templates/InternalRuntimeFlags.h.tmpl",
+ "../build/scripts/templates/InternalRuntimeFlags.idl.tmpl",
+ ]
+ outputs = [
+ "$blink_core_output_dir/InternalRuntimeFlags.idl",
+ "$blink_core_output_dir/InternalRuntimeFlags.h",
+ ]
+
+ args = [
+ rebase_path("../platform/RuntimeEnabledFeatures.in", root_build_dir),
+ "--output_dir", rel_blink_core_gen_dir,
+ ]
+}
+
+# make_core_generated ----------------------------------------------------------
+
+# GYP version: WebKit/Source/core/core_generated.gyp:make_core_generated
+group("make_core_generated") {
+ deps = [
+ ":make_core_generated_xml_viewer_css",
+ ":make_core_generated_xml_viewer_js",
+ ":make_core_generated_html_entity_table",
+ ":make_core_generated_css_property_names",
+ ":make_core_generated_media_feature_names",
+ ":make_core_generated_media_features",
+ ":make_core_generated_media_type_names",
+ ":make_core_generated_media_query_tokenizer_codepoints",
+ ":make_core_generated_style_property_shorthand",
+ ":make_core_generated_style_builder",
+ ":make_core_generated_css_value_keywords",
+ ":make_core_generated_html_element_factory",
+ ":make_core_generated_html_element_type_helpers",
+ ":make_core_generated_svg_names",
+ ":make_core_generated_svg_element_type_helpers",
+ ":make_core_generated_event_factory",
+ ":make_core_generated_event_names",
+ ":make_core_generated_event_target_factory",
+ ":make_core_generated_event_target_names",
+ ":make_core_generated_math_ml_names",
+ ":make_core_generated_user_agent_style_sheets",
+ ":make_core_generated_fetch_initiator_type_names",
+ ":make_core_generated_event_type_names",
+ ":make_core_generated_html_tokenizer_names",
+ ":make_core_generated_input_type_names",
+ ":make_core_generated_xlink_names",
+ ":make_core_generated_xml_ns_names",
+ ":make_core_generated_xml_names",
+ ":make_core_generated_make_token_matcher",
+ ":make_core_generated_make_parser",
+ ":make_core_generated_make_token_matcher_for_viewport",
+ ":make_core_generated_html_element_lookup_trie",
+ ":make_core_generated_bison",
+ ]
+}
+
+# "CSSPropertyNames" in make_core_generated from GYP.
+process_in_files("make_core_generated_css_property_names") {
+ script = "../build/scripts/make_css_property_names.py"
+ in_files = [
+ "css/CSSPropertyNames.in",
+ "css/SVGCSSPropertyNames.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/CSSPropertyNames.cpp",
+ "$blink_core_output_dir/CSSPropertyNames.h",
+ ]
+ other_args = [ "--defines", feature_defines_string ]
+}
+
+# "MediaFeatures" in make_core_generated from GYP.
+process_in_files("make_core_generated_media_features") {
+ script = "../build/scripts/make_media_features.py"
+ in_files = [
+ "css/MediaFeatureNames.in",
+ ]
+ other_inputs = [
+ "../build/scripts/make_media_features.py",
+ "../build/scripts/templates/MediaFeatures.h.tmpl",
+ ]
+ outputs = [
+ "$blink_core_output_dir/MediaFeatures.h",
+ ]
+ other_args = [ "--defines", feature_defines_string ]
+}
+
+# "StylePropertyShorthand" in make_core_generated from GYP.
+process_in_files("make_core_generated_style_property_shorthand") {
+ script = "../build/scripts/make_style_shorthands.py"
+ in_files = [
+ "css/CSSShorthands.in",
+ ]
+ other_inputs = [
+ "../build/scripts/templates/StylePropertyShorthand.cpp.tmpl",
+ "../build/scripts/templates/StylePropertyShorthand.h.tmpl",
+ ]
+ outputs = [
+ "$blink_core_output_dir/StylePropertyShorthand.cpp",
+ "$blink_core_output_dir/StylePropertyShorthand.h",
+ ]
+}
+
+# "StyleBuilder" in make_core_generated from GYP.
+process_in_files("make_core_generated_style_builder") {
+ script = "../build/scripts/make_style_builder.py"
+
+ in_files = [
+ "css/CSSProperties.in",
+ ]
+ other_inputs = [
+ "../build/scripts/templates/StyleBuilder.cpp.tmpl",
+ "../build/scripts/templates/StyleBuilderFunctions.cpp.tmpl",
+ "../build/scripts/templates/StyleBuilderFunctions.h.tmpl",
+ ]
+ outputs = [
+ "$blink_core_output_dir/StyleBuilder.cpp",
+ "$blink_core_output_dir/StyleBuilderFunctions.h",
+ "$blink_core_output_dir/StyleBuilderFunctions.cpp",
+ ]
+}
+
+# "CSSValueKeywords" in make_core_generated from GYP.
+process_in_files("make_core_generated_css_value_keywords") {
+ script = "../build/scripts/make_css_value_keywords.py"
+
+ in_files = [
+ "css/CSSValueKeywords.in",
+ "css/SVGCSSValueKeywords.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/CSSValueKeywords.cpp",
+ "$blink_core_output_dir/CSSValueKeywords.h",
+ ]
+ other_args = [
+ "--gperf", gperf_exe,
+ "--defines", feature_defines_string
+ ]
+}
+
+# "HTMLElementFactory" in make_core_generated from GYP.
+process_in_files("make_core_generated_html_element_factory") {
+ script = "../build/scripts/make_element_factory.py"
+
+ in_files = [
+ "html/HTMLTagNames.in",
+ "html/HTMLAttributeNames.in",
+ ]
+ other_inputs = make_element_factory_files
+ outputs = [
+ "$blink_core_output_dir/HTMLElementFactory.cpp",
+ "$blink_core_output_dir/HTMLElementFactory.h",
+ "$blink_core_output_dir/HTMLNames.cpp",
+ "$blink_core_output_dir/HTMLNames.h",
+ "$blink_core_output_dir/V8HTMLElementWrapperFactory.cpp",
+ "$blink_core_output_dir/V8HTMLElementWrapperFactory.h",
+ ]
+}
+
+# "HTMLElementTypeHelpers" in make_core_generated from GYP.
+process_in_files("make_core_generated_html_element_type_helpers") {
+ script = "../build/scripts/make_element_type_helpers.py"
+
+ in_files = [
+ "html/HTMLTagNames.in",
+ ]
+ other_inputs = make_element_type_helpers_files
+ outputs = [
+ "$blink_core_output_dir/HTMLElementTypeHelpers.h",
+ ]
+}
+
+# "SVGNames" in make_core_generated from GYP.
+process_in_files("make_core_generated_svg_names") {
+ script = "../build/scripts/make_element_factory.py"
+
+ in_files = [
+ "svg/SVGTagNames.in",
+ "svg/SVGAttributeNames.in",
+ ]
+ other_inputs = make_element_factory_files
+ outputs = [
+ "$blink_core_output_dir/SVGElementFactory.cpp",
+ "$blink_core_output_dir/SVGElementFactory.h",
+ "$blink_core_output_dir/SVGNames.cpp",
+ "$blink_core_output_dir/SVGNames.h",
+ "$blink_core_output_dir/V8SVGElementWrapperFactory.cpp",
+ "$blink_core_output_dir/V8SVGElementWrapperFactory.h",
+ ]
+}
+
+# "SVGElementTypeHelpers" in make_core_generated from GYP.
+process_in_files("make_core_generated_svg_element_type_helpers") {
+ script = "../build/scripts/make_element_type_helpers.py"
+
+ in_files = [
+ "svg/SVGTagNames.in",
+ ]
+ other_inputs = make_element_type_helpers_files
+ outputs = [
+ "$blink_core_output_dir/SVGElementTypeHelpers.h",
+ ]
+}
+
+# "EventFactory" in make_core_generated from GYP.
+process_in_files("make_core_generated_event_factory") {
+ script = "../build/scripts/make_event_factory.py"
+
+ in_files = [
+ "$blink_core_output_dir/EventInterfaces.in",
+ "events/EventAliases.in",
+ ]
+ other_inputs = make_event_factory_files
+ outputs = [
+ "$blink_core_output_dir/Event.cpp",
+ "$blink_core_output_dir/EventHeaders.h",
+ "$blink_core_output_dir/EventInterfaces.h",
+ ]
+}
+
+# make_event_factory -----------------------------------------------------------
+
+# "EventTargetFactory" in make_core_generated from GYP.
+make_event_factory("make_core_generated_event_target_factory") {
+ in_files = [
+ "events/EventTargetFactory.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/EventTargetHeaders.h",
+ "$blink_core_output_dir/EventTargetInterfaces.h",
+ ]
+}
+
+# "MediaFeatureNames" in make_core_generated from GYP.
+process_in_files("make_core_generated_media_feature_names") {
+ script = "../build/scripts/make_media_feature_names.py"
+ in_files = [
+ "css/MediaFeatureNames.in",
+ ]
+ other_inputs = make_names_files
+ outputs = [
+ "$blink_core_output_dir/MediaFeatureNames.cpp",
+ "$blink_core_output_dir/MediaFeatureNames.h",
+ ]
+ other_args = [ "--defines", feature_defines_string ]
+}
+
+# make_names -------------------------------------------------------------------
+
+# "MediaTypeNames" in make_core_generated from GYP.
+make_names("make_core_generated_media_type_names") {
+ in_files = [
+ "css/MediaTypeNames.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/MediaTypeNames.cpp",
+ "$blink_core_output_dir/MediaTypeNames.h",
+ ]
+}
+
+# "EventNames" in make_core_generated from GYP.
+make_names("make_core_generated_event_names") {
+ in_files = [
+ "$blink_core_output_dir/EventInterfaces.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/EventNames.cpp",
+ "$blink_core_output_dir/EventNames.h",
+ ]
+}
+
+# "EventTargetNames" in make_core_generated from GYP.
+make_names("make_core_generated_event_target_names") {
+ in_files = [
+ "events/EventTargetFactory.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/EventTargetNames.cpp",
+ "$blink_core_output_dir/EventTargetNames.h",
+ ]
+}
+
+# "FetchInitiatorTypeNames" in make_core_generated from GYP.
+make_names("make_core_generated_fetch_initiator_type_names") {
+ in_files = [
+ "fetch/FetchInitiatorTypeNames.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/FetchInitiatorTypeNames.cpp",
+ "$blink_core_output_dir/FetchInitiatorTypeNames.h",
+ ]
+}
+
+# "EventTypeNames" in make_core_generated from GYP.
+make_names("make_core_generated_event_type_names") {
+ in_files = [
+ "events/EventTypeNames.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/EventTypeNames.cpp",
+ "$blink_core_output_dir/EventTypeNames.h",
+ ]
+}
+
+# "HTMLTokenizerNames" in make_core_generated from GYP.
+make_names("make_core_generated_html_tokenizer_names") {
+ in_files = [
+ "html/parser/HTMLTokenizerNames.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/HTMLTokenizerNames.cpp",
+ "$blink_core_output_dir/HTMLTokenizerNames.h",
+ ]
+}
+
+# "InputTypeNames" in make_core_generated from GYP.
+make_names("make_core_generated_input_type_names") {
+ in_files = [
+ "html/forms/InputTypeNames.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/InputTypeNames.cpp",
+ "$blink_core_output_dir/InputTypeNames.h",
+ ]
+}
+
+# make_qualified_names ---------------------------------------------------------
+
+# "MathMLNames" in make_core_generated from GYP.
+make_qualified_names("make_core_generated_math_ml_names") {
+ in_files = [
+ "html/parser/MathMLTagNames.in",
+ "html/parser/MathMLAttributeNames.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/MathMLNames.cpp",
+ "$blink_core_output_dir/MathMLNames.h",
+ ]
+}
+
+# "XLinkNames" in make_core_generated from GYP.
+make_qualified_names("make_core_generated_xlink_names") {
+ in_files = [
+ "svg/xlinkattrs.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/XLinkNames.cpp",
+ "$blink_core_output_dir/XLinkNames.h",
+ ]
+}
+
+# "XMLNSNames" in make_core_generated from GYP.
+make_qualified_names("make_core_generated_xml_ns_names") {
+ in_files = [
+ "xml/xmlnsattrs.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/XMLNSNames.cpp",
+ "$blink_core_output_dir/XMLNSNames.h",
+ ]
+}
+
+# "XMLNames" in make_core_generated from GYP.
+make_qualified_names("make_core_generated_xml_names") {
+ in_files = [
+ "xml/xmlattrs.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/XMLNames.cpp",
+ "$blink_core_output_dir/XMLNames.h",
+ ]
+}
+
+# make_token_matcher -----------------------------------------------------------
+
+# "MakeTokenMatcher" in make_core_generated from GYP.
+make_token_matcher("make_core_generated_make_token_matcher") {
+ input_file = "css/CSSTokenizer-in.cpp"
+ output_file = "$blink_core_output_dir/CSSTokenizer.cpp"
+}
+
+# "MakeParser" in make_core_generated from GYP.
+make_token_matcher("make_core_generated_make_parser") {
+ input_file = "css/parser/BisonCSSParser-in.cpp"
+ output_file = "$blink_core_output_dir/BisonCSSParser.cpp"
+}
+
+# "MakeTokenMatcherForViewport" in make_core_generated from GYP.
+make_token_matcher("make_core_generated_make_token_matcher_for_viewport") {
+ input_file = "html/HTMLMetaElement-in.cpp"
+ output_file = "$blink_core_output_dir/HTMLMetaElement.cpp"
+}
+
+# One-off scripts --------------------------------------------------------------
+
+# "generateXMLViewerCSS" in make_core_generated from GYP.
+action("make_core_generated_xml_viewer_css") {
+ visibility = ":make_core_generated"
+ script = "../build/scripts/xxd.py"
+
+ source_prereqs = [
+ "xml/XMLViewer.css",
+ ]
+ outputs = [
+ "$blink_core_output_dir/XMLViewerCSS.h",
+ ]
+
+ args = [
+ "XMLViewer_css",
+ rebase_path(source_prereqs[0], root_build_dir),
+ rebase_path(outputs[0], root_build_dir),
+ ]
+
+ deps = make_core_generated_deps
+}
+
+# "generateXMLViewerJS" in make_core_generated from GYP.
+action("make_core_generated_xml_viewer_js") {
+ visibility = ":make_core_generated"
+ script = "../build/scripts/xxd.py"
+
+ source_prereqs = [
+ "xml/XMLViewer.js",
+ ]
+ outputs = [
+ "$blink_core_output_dir/XMLViewerJS.h",
+ ]
+
+ args = [
+ "XMLViewer_js",
+ rebase_path(source_prereqs[0], root_build_dir),
+ rebase_path(outputs[0], root_build_dir),
+ ]
+
+ deps = make_core_generated_deps
+}
+
+# "HTMLEntityTable" in make_core_generated from GYP.
+action("make_core_generated_html_entity_table") {
+ visibility = ":make_core_generated"
+ script = "html/parser/create-html-entity-table"
+
+ source_prereqs = [
+ "html/parser/HTMLEntityNames.in",
+ ]
+ outputs = [
+ "$blink_core_output_dir/HTMLEntityTable.cpp",
+ ]
+
+ args = [ "-o" ] + rebase_path(outputs, root_build_dir)
+ args += rebase_path(source_prereqs, root_build_dir)
+
+ deps = make_core_generated_deps
+}
+
+# "MediaQueryTokenizerCodepoints" in make_core_generated from GYP.
+action("make_core_generated_media_query_tokenizer_codepoints") {
+ visibility = ":make_core_generated"
+ script = "../build/scripts/make_mediaquery_tokenizer_codepoints.py"
+
+ outputs = [
+ "$blink_core_output_dir/MediaQueryTokenizerCodepoints.cpp",
+ ]
+
+ args = [
+ "--output_dir", rel_blink_core_gen_dir,
+ "--defines", feature_defines_string
+ ]
+
+ deps = make_core_generated_deps
+}
+
+# "UserAgentStyleSheets" in make_core_generated from GYP.
+action("make_core_generated_user_agent_style_sheets") {
+ visibility = ":make_core_generated"
+ script = "../build/scripts/action_useragentstylesheets.py"
+
+ scripts = [
+ "css/make-css-file-arrays.pl",
+ "../build/scripts/preprocessor.pm",
+ ]
+ stylesheets = [
+ "css/html.css",
+ "css/quirks.css",
+ "css/view-source.css",
+ "css/themeChromium.css",
+ "css/themeChromiumAndroid.css",
+ "css/themeChromiumLinux.css",
+ "css/themeChromiumSkia.css",
+ "css/themeMac.css",
+ "css/themeWin.css",
+ "css/themeWinQuirks.css",
+ "css/svg.css",
+ "css/navigationTransitions.css",
+ "css/mathml.css",
+ "css/mediaControls.css",
+ "css/mediaControlsAndroid.css",
+ "css/fullscreen.css",
+ "css/xhtmlmp.css",
+ "css/viewportAndroid.css",
+ ]
+
+ source_prereqs = scripts + stylesheets
+ outputs = [
+ "$blink_core_output_dir/UserAgentStyleSheets.h",
+ "$blink_core_output_dir/UserAgentStyleSheetsData.cpp",
+ ]
+
+ args =
+ rebase_path(outputs, root_build_dir) +
+ rebase_path(stylesheets, root_build_dir) +
+ [ "--" ] +
+ rebase_path(scripts, root_build_dir) +
+ [ "--", "--defines", feature_defines_string ] +
+ [ preprocessor ] +
+ [ "--perl", perl_exe ]
+
+ deps = make_core_generated_deps
+}
+
+# "HTMLElementLookupTrie" in make_core_generated from GYP.
+action("make_core_generated_html_element_lookup_trie") {
+ visibility = ":make_core_generated"
+ script = "../build/scripts/make_element_lookup_trie.py"
+
+ input_file = "html/HTMLTagNames.in"
+ source_prereqs = scripts_for_in_files + [
+ input_file,
+ "../build/scripts/templates/ElementLookupTrie.cpp.tmpl",
+ "../build/scripts/templates/ElementLookupTrie.h.tmpl",
+ ]
+ outputs = [
+ "$blink_core_output_dir/HTMLElementLookupTrie.cpp",
+ "$blink_core_output_dir/HTMLElementLookupTrie.h",
+ ]
+
+ args = [
+ rebase_path(input_file, root_build_dir),
+ "--output_dir", rel_blink_core_gen_dir,
+ ]
+
+ deps = make_core_generated_deps
+}
+
+# The bison rules from make_core_generated.
+action_foreach("make_core_generated_bison") {
+ script = "../build/scripts/rule_bison.py"
+ sources = [
+ "css/CSSGrammar.y",
+ "xml/XPathGrammar.y",
+ ]
+ outputs = [
+ "$blink_core_output_dir/{{source_name_part}}.cpp",
+ "$blink_core_output_dir/{{source_name_part}}.h",
+ ]
+ args = [
+ "{{source}}",
+ rel_blink_core_gen_dir,
+ bison_exe,
+ ]
+
+ deps = make_core_generated_deps
+}
diff --git a/chromium/third_party/WebKit/Source/core/DEPS b/chromium/third_party/WebKit/Source/core/DEPS
index da61cbd2353..56d516b7fba 100644
--- a/chromium/third_party/WebKit/Source/core/DEPS
+++ b/chromium/third_party/WebKit/Source/core/DEPS
@@ -1,25 +1,6 @@
include_rules = [
"+bindings",
"+core",
- "+heap",
- "+mozilla",
"+platform",
"+public/platform",
- "+sys",
-
-# core/ should not depend on modules/ at all, but there are a number of pieces
-# of code that do. Please don't add to this list of exceptions.
- "!modules/encryptedmedia/MediaKeyNeededEvent.h",
- "!modules/encryptedmedia/MediaKeys.h",
- "!modules/filesystem/DraggedIsolatedFileSystem.h",
- "!modules/geolocation/GeolocationClient.h",
- "!modules/geolocation/GeolocationController.h",
- "!modules/geolocation/GeolocationError.h",
- "!modules/geolocation/GeolocationPosition.h",
- "!modules/mediastream/MediaStreamRegistry.h",
- "!modules/mediastream/MediaStreamTrackSourcesRequest.h",
- "!modules/mediastream/RTCStatsResponse.h",
- "!modules/webaudio/MediaElementAudioSourceNode.h",
- "!modules/webdatabase/DatabaseManager.h",
- "!modules/webdatabase/DatabaseTask.h",
]
diff --git a/chromium/third_party/WebKit/Source/core/Init.cpp b/chromium/third_party/WebKit/Source/core/Init.cpp
index 8b7304d14ad..6342b1ff560 100644
--- a/chromium/third_party/WebKit/Source/core/Init.cpp
+++ b/chromium/third_party/WebKit/Source/core/Init.cpp
@@ -31,32 +31,57 @@
#include "config.h"
#include "Init.h"
-#include "EventNames.h"
-#include "EventTargetNames.h"
-#include "EventTypeNames.h"
-#include "FetchInitiatorTypeNames.h"
-#include "FontFamilyNames.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-#include "XMLNSNames.h"
-#include "XMLNames.h"
-#include "core/css/MediaFeatureNames.h"
+#include "core/EventNames.h"
+#include "core/EventTargetNames.h"
+#include "core/EventTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/HTMLTokenizerNames.h"
+#include "core/InputTypeNames.h"
+#include "core/MathMLNames.h"
+#include "core/MediaFeatureNames.h"
+#include "core/MediaTypeNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
+#include "core/XMLNSNames.h"
+#include "core/XMLNames.h"
+#include "core/dom/Document.h"
+#include "core/events/EventFactory.h"
+#include "core/html/parser/HTMLParserThread.h"
#include "platform/EventTracer.h"
+#include "platform/FontFamilyNames.h"
#include "platform/Partitions.h"
#include "platform/PlatformThreadData.h"
+#include "platform/heap/Heap.h"
#include "wtf/text/StringStatics.h"
namespace WebCore {
-void init()
+void CoreInitializer::initEventNames()
{
- static bool isInited;
- if (isInited)
+ EventNames::init();
+}
+
+void CoreInitializer::initEventTargetNames()
+{
+ EventTargetNames::init();
+}
+
+void CoreInitializer::registerEventFactory()
+{
+ static bool isRegistered = false;
+ if (isRegistered)
+ return;
+ isRegistered = true;
+
+ Document::registerEventFactory(EventFactory::create());
+}
+
+void CoreInitializer::init()
+{
+ if (m_isInited)
return;
- isInited = true;
+ m_isInited = true;
// It would make logical sense to do this and WTF::StringStatics::init() in
// WTF::initialize() but there are ordering dependencies.
@@ -67,27 +92,39 @@ void init()
MathMLNames::init();
XMLNSNames::init();
XMLNames::init();
- EventNames::init();
- EventTargetNames::init();
+
+ initEventNames();
+ initEventTargetNames();
EventTypeNames::init();
FetchInitiatorTypeNames::init();
FontFamilyNames::init();
+ HTMLTokenizerNames::init();
InputTypeNames::init();
MediaFeatureNames::init();
+ MediaTypeNames::init();
+
WTF::StringStatics::init();
QualifiedName::init();
Partitions::init();
EventTracer::initialize();
+ registerEventFactory();
+
// Ensure that the main thread's thread-local data is initialized before
// starting any worker threads.
PlatformThreadData::current();
StringImpl::freezeStaticStrings();
+
+ // Creates HTMLParserThread::shared, but does not start the thread.
+ HTMLParserThread::init();
}
void shutdown()
{
+ // Make sure we stop the HTMLParserThread before Platform::current() is cleared.
+ HTMLParserThread::shutdown();
+
Partitions::shutdown();
}
diff --git a/chromium/third_party/WebKit/Source/core/Init.h b/chromium/third_party/WebKit/Source/core/Init.h
index 002a6b33265..a20cc3329e2 100644
--- a/chromium/third_party/WebKit/Source/core/Init.h
+++ b/chromium/third_party/WebKit/Source/core/Init.h
@@ -33,8 +33,19 @@
namespace WebCore {
-// Should be called by clients before trying to create Frames.
-void init();
+class CoreInitializer {
+public:
+ CoreInitializer() : m_isInited(false) { }
+ // Should be called by clients before trying to create Frames.
+ void init();
+
+ virtual void registerEventFactory();
+ virtual void initEventNames();
+ virtual void initEventTargetNames();
+
+private:
+ bool m_isInited;
+};
void shutdown();
diff --git a/chromium/third_party/WebKit/Source/core/OWNERS b/chromium/third_party/WebKit/Source/core/OWNERS
index c82d8e69312..46cb3f53c27 100644
--- a/chromium/third_party/WebKit/Source/core/OWNERS
+++ b/chromium/third_party/WebKit/Source/core/OWNERS
@@ -1,10 +1,13 @@
abarth@chromium.org
+acolwell@chromium.org
adamk@chromium.org
+ager@chromium.org
alexis.menard@intel.com
apavlov@chromium.org
arv@chromium.org
ch.dumez@samsung.com
darin@chromium.org
+dcheng@chromium.org
dglazkov@chromium.org
dimich@chromium.org
dmazzoni@chromium.org
@@ -17,6 +20,7 @@ enne@chromium.org
eseidel@chromium.org
esprehn@chromium.org
fmalita@chromium.org
+fs@opera.com
hamaji@chromium.org
haraken@chromium.org
hayato@chromium.org
@@ -26,7 +30,9 @@ japhet@chromium.org
jchaffraix@chromium.org
jianli@chromium.org
jochen@chromium.org
+junov@chromium.org
kbr@chromium.org
+keishi@chromium.org
kenneth.r.christiansen@intel.com
kinuko@chromium.org
levin@chromium.org
@@ -36,13 +42,18 @@ morrita@chromium.org
ojan@chromium.org
pdr@chromium.org
pfeldman@chromium.org
+philipj@opera.com
pkasting@chromium.org
+rbyers@chromium.org
+rob.buis@samsung.com
+rune@opera.com
schenney@chromium.org
senorblanco@chromium.org
+sigbjornf@opera.com
steveblock@chromium.org
thakis@chromium.org
+timloh@chromium.org
tkent@chromium.org
-tony@chromium.org
tonyg@chromium.org
vollick@chromium.org
vsevik@chromium.org
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.cpp
index beac9c9e6e3..71cf33fd3b5 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.cpp
@@ -34,7 +34,6 @@
#include "core/accessibility/AXTableRow.h"
#include "core/rendering/RenderObject.h"
-using namespace std;
namespace WebCore {
@@ -74,7 +73,7 @@ bool AXARIAGrid::addTableCellChild(AXObject* child, HashSet<AXObject*>& appended
if (!row->accessibilityIsIgnored())
m_children.append(row);
else
- m_children.append(row->children());
+ m_children.appendVector(row->children());
appendedRows.add(row);
return true;
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.h b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.h
index e108151e56f..652512bd093 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGrid.h
@@ -37,7 +37,7 @@ namespace WebCore {
class AXTableCell;
class AXTableHeaderContainer;
-class AXARIAGrid : public AXTable {
+class AXARIAGrid FINAL : public AXTable {
private:
explicit AXARIAGrid(RenderObject*);
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.cpp
index 8602bb1fcba..e62847b6c0a 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.cpp
@@ -32,7 +32,6 @@
#include "core/accessibility/AXTable.h"
#include "core/accessibility/AXTableRow.h"
-using namespace std;
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.h b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.h
index 0bf53fbbfd7..4e34c69ee67 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridCell.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class AXARIAGridCell : public AXTableCell {
+class AXARIAGridCell FINAL : public AXTableCell {
private:
explicit AXARIAGridCell(RenderObject*);
@@ -47,7 +47,7 @@ public:
virtual void columnIndexRange(pair<unsigned, unsigned>& columnRange) OVERRIDE;
protected:
- virtual AXObject* parentTable() const;
+ virtual AXObject* parentTable() const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.cpp
index 36d0da6bdcc..e8e487a9944 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.cpp
@@ -31,7 +31,6 @@
#include "core/accessibility/AXTable.h"
-using namespace std;
namespace WebCore {
@@ -58,62 +57,6 @@ bool AXARIAGridRow::isARIATreeGridRow() const
return parent->ariaRoleAttribute() == TreeGridRole;
}
-void AXARIAGridRow::disclosedRows(AccessibilityChildrenVector& disclosedRows)
-{
- // The contiguous disclosed rows will be the rows in the table that
- // have an aria-level of plus 1 from this row.
- AXObject* parent = parentObjectUnignored();
- if (!parent || !parent->isAXTable())
- return;
-
- // Search for rows that match the correct level.
- // Only take the subsequent rows from this one that are +1 from this row's level.
- int index = rowIndex();
- if (index < 0)
- return;
-
- unsigned level = hierarchicalLevel();
- AccessibilityChildrenVector& allRows = toAXTable(parent)->rows();
- int rowCount = allRows.size();
- for (int k = index + 1; k < rowCount; ++k) {
- AXObject* row = allRows[k].get();
- // Stop at the first row that doesn't match the correct level.
- if (row->hierarchicalLevel() != level + 1)
- break;
-
- disclosedRows.append(row);
- }
-}
-
-AXObject* AXARIAGridRow::disclosedByRow() const
-{
- // The row that discloses this one is the row in the table
- // that is aria-level subtract 1 from this row.
- AXObject* parent = parentObjectUnignored();
- if (!parent || !parent->isAXTable())
- return 0;
-
- // If the level is 1 or less, than nothing discloses this row.
- unsigned level = hierarchicalLevel();
- if (level <= 1)
- return 0;
-
- // Search for the previous row that matches the correct level.
- int index = rowIndex();
- AccessibilityChildrenVector& allRows = toAXTable(parent)->rows();
- int rowCount = allRows.size();
- if (index >= rowCount)
- return 0;
-
- for (int k = index - 1; k >= 0; --k) {
- AXObject* row = allRows[k].get();
- if (row->hierarchicalLevel() == level - 1)
- return row;
- }
-
- return 0;
-}
-
AXObject* AXARIAGridRow::headerObject()
{
AccessibilityChildrenVector rowChildren = children();
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.h b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.h
index 54dc1f0ebfb..91a36722811 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXARIAGridRow.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class AXARIAGridRow : public AXTableRow {
+class AXARIAGridRow FINAL : public AXTableRow {
private:
explicit AXARIAGridRow(RenderObject*);
@@ -41,13 +41,10 @@ public:
static PassRefPtr<AXARIAGridRow> create(RenderObject*);
virtual ~AXARIAGridRow();
- void disclosedRows(AccessibilityChildrenVector&);
- AXObject* disclosedByRow() const;
-
virtual AXObject* headerObject() OVERRIDE;
private:
- virtual bool isARIATreeGridRow() const;
+ virtual bool isARIATreeGridRow() const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.cpp
index e4977049bcb..b45600d720b 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.cpp
@@ -37,8 +37,8 @@ namespace WebCore {
using namespace HTMLNames;
AXImageMapLink::AXImageMapLink()
- : m_areaElement(0)
- , m_mapElement(0)
+ : m_areaElement(nullptr)
+ , m_mapElement(nullptr)
{
}
@@ -49,8 +49,8 @@ AXImageMapLink::~AXImageMapLink()
void AXImageMapLink::detachFromParent()
{
AXMockObject::detachFromParent();
- m_areaElement = 0;
- m_mapElement = 0;
+ m_areaElement = nullptr;
+ m_mapElement = nullptr;
}
PassRefPtr<AXImageMapLink> AXImageMapLink::create()
@@ -99,21 +99,6 @@ KURL AXImageMapLink::url() const
return m_areaElement->href();
}
-void AXImageMapLink::accessibilityText(Vector<AccessibilityText>& textOrder)
-{
- String description = accessibilityDescription();
- if (!description.isEmpty())
- textOrder.append(AccessibilityText(description, AlternativeText));
-
- const AtomicString& titleText = getAttribute(titleAttr);
- if (!titleText.isEmpty())
- textOrder.append(AccessibilityText(titleText, TitleTagText));
-
- const AtomicString& summary = getAttribute(summaryAttr);
- if (!summary.isEmpty())
- textOrder.append(AccessibilityText(summary, SummaryText));
-}
-
String AXImageMapLink::accessibilityDescription() const
{
const AtomicString& ariaLabel = getAttribute(aria_labelAttr);
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.h b/chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.h
index 08276a8e30e..70d11abc52b 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXImageMapLink.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class AXImageMapLink : public AXMockObject {
+class AXImageMapLink FINAL : public AXMockObject {
private:
AXImageMapLink();
@@ -57,7 +57,7 @@ public:
virtual Element* anchorElement() const OVERRIDE;
virtual Element* actionElement() const OVERRIDE;
virtual KURL url() const OVERRIDE;
- virtual bool isLink() const { return true; }
+ virtual bool isLink() const OVERRIDE { return true; }
virtual bool isLinked() const OVERRIDE { return true; }
virtual String title() const OVERRIDE;
virtual String accessibilityDescription() const OVERRIDE;
@@ -66,12 +66,11 @@ public:
virtual LayoutRect elementRect() const OVERRIDE;
private:
- RefPtr<HTMLAreaElement> m_areaElement;
- RefPtr<HTMLMapElement> m_mapElement;
+ RefPtrWillBePersistent<HTMLAreaElement> m_areaElement;
+ RefPtrWillBePersistent<HTMLMapElement> m_mapElement;
virtual void detachFromParent() OVERRIDE;
- virtual void accessibilityText(Vector<AccessibilityText>&) OVERRIDE;
virtual bool isImageMapLink() const OVERRIDE { return true; }
};
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.cpp
index 9c5d7037e9c..ff8120c8794 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.cpp
@@ -34,7 +34,6 @@
#include "core/rendering/RenderText.h"
#include "platform/LayoutUnit.h"
-using namespace std;
namespace WebCore {
@@ -64,7 +63,7 @@ void AXInlineTextBox::init()
void AXInlineTextBox::detach()
{
- m_inlineTextBox = 0;
+ m_inlineTextBox = nullptr;
m_axObjectCache = 0;
AXObject::detach();
}
@@ -99,7 +98,7 @@ void AXInlineTextBox::textCharacterOffsets(Vector<int>& offsets) const
float widthSoFar = 0;
for (unsigned i = 0; i < len; i++) {
widthSoFar += widths[i];
- offsets[i] = LayoutUnit::fromFloatRound(widthSoFar);
+ offsets[i] = lroundf(widthSoFar);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.h b/chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.h
index b80b558ed47..715a62e658f 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXInlineTextBox.h
@@ -34,7 +34,7 @@
namespace WebCore {
-class AXInlineTextBox : public AXObject {
+class AXInlineTextBox FINAL : public AXObject {
private:
AXInlineTextBox(PassRefPtr<AbstractInlineTextBox>);
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXList.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXList.cpp
index c1cbe2764de..e28c1f107f1 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXList.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXList.cpp
@@ -29,9 +29,9 @@
#include "config.h"
#include "core/accessibility/AXList.h"
+#include "core/html/HTMLUListElement.h"
#include "core/rendering/RenderObject.h"
-using namespace std;
namespace WebCore {
@@ -56,43 +56,4 @@ bool AXList::computeAccessibilityIsIgnored() const
return accessibilityIsIgnoredByDefault();
}
-bool AXList::isUnorderedList() const
-{
- if (!m_renderer)
- return false;
-
- Node* node = m_renderer->node();
-
- // The ARIA spec says the "list" role is supposed to mimic a UL or OL tag.
- // Since it can't be both, it's probably OK to say that it's an un-ordered list.
- // On the Mac, there's no distinction to the client.
- if (ariaRoleAttribute() == ListRole)
- return true;
-
- return node && node->hasTagName(ulTag);
-}
-
-bool AXList::isOrderedList() const
-{
- if (!m_renderer)
- return false;
-
- // ARIA says a directory is like a static table of contents, which sounds like an ordered list.
- if (ariaRoleAttribute() == DirectoryRole)
- return true;
-
- Node* node = m_renderer->node();
- return node && node->hasTagName(olTag);
-}
-
-bool AXList::isDescriptionList() const
-{
- if (!m_renderer)
- return false;
-
- Node* node = m_renderer->node();
- return node && node->hasTagName(dlTag);
-}
-
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXList.h b/chromium/third_party/WebKit/Source/core/accessibility/AXList.h
index cba99d50a6d..4b23f9eff4d 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXList.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXList.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class AXList : public AXRenderObject {
+class AXList FINAL : public AXRenderObject {
private:
explicit AXList(RenderObject*);
@@ -41,14 +41,11 @@ public:
static PassRefPtr<AXList> create(RenderObject*);
virtual ~AXList();
- virtual bool isList() const { return true; }
- bool isUnorderedList() const;
- bool isOrderedList() const;
- bool isDescriptionList() const;
+ virtual bool isList() const OVERRIDE { return true; }
- virtual AccessibilityRole roleValue() const { return ListRole; }
+ virtual AccessibilityRole roleValue() const OVERRIDE { return ListRole; }
private:
- virtual bool computeAccessibilityIsIgnored() const;
+ virtual bool computeAccessibilityIsIgnored() const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXListBox.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXListBox.cpp
index 444c3047fe0..432302b6c8c 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXListBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXListBox.cpp
@@ -34,7 +34,6 @@
#include "core/html/HTMLSelectElement.h"
#include "core/rendering/RenderListBox.h"
-using namespace std;
namespace WebCore {
@@ -54,15 +53,6 @@ PassRefPtr<AXListBox> AXListBox::create(RenderObject* renderer)
return adoptRef(new AXListBox(renderer));
}
-bool AXListBox::canSetSelectedChildrenAttribute() const
-{
- Node* selectNode = m_renderer->node();
- if (!selectNode)
- return false;
-
- return !toHTMLSelectElement(selectNode)->isDisabledFormControl();
-}
-
void AXListBox::addChildren()
{
Node* selectNode = m_renderer->node();
@@ -71,7 +61,7 @@ void AXListBox::addChildren()
m_haveChildren = true;
- const Vector<HTMLElement*>& listItems = toHTMLSelectElement(selectNode)->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = toHTMLSelectElement(selectNode)->listItems();
unsigned length = listItems.size();
for (unsigned i = 0; i < length; i++) {
// The cast to HTMLElement below is safe because the only other possible listItem type
@@ -82,51 +72,10 @@ void AXListBox::addChildren()
}
}
-void AXListBox::setSelectedChildren(AccessibilityChildrenVector& children)
-{
- if (!canSetSelectedChildrenAttribute())
- return;
-
- Node* selectNode = m_renderer->node();
- if (!selectNode)
- return;
-
- // disable any selected options
- unsigned length = m_children.size();
- for (unsigned i = 0; i < length; i++) {
- AXListBoxOption* listBoxOption = toAXListBoxOption(m_children[i].get());
- if (listBoxOption->isSelected())
- listBoxOption->setSelected(false);
- }
-
- length = children.size();
- for (unsigned i = 0; i < length; i++) {
- AXObject* obj = children[i].get();
- if (obj->roleValue() != ListBoxOptionRole)
- continue;
-
- toAXListBoxOption(obj)->setSelected(true);
- }
-}
-
-void AXListBox::selectedChildren(AccessibilityChildrenVector& result)
-{
- ASSERT(result.isEmpty());
-
- if (!hasChildren())
- addChildren();
-
- unsigned length = m_children.size();
- for (unsigned i = 0; i < length; i++) {
- if (toAXListBoxOption(m_children[i].get())->isSelected())
- result.append(m_children[i]);
- }
-}
-
AXObject* AXListBox::listBoxOptionAXObject(HTMLElement* element) const
{
// skip hr elements
- if (!element || element->hasTagName(hrTag))
+ if (!element || isHTMLHRElement(*element))
return 0;
AXObject* listBoxObject = m_renderer->document().axObjectCache()->getOrCreate(ListBoxOptionRole);
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXListBox.h b/chromium/third_party/WebKit/Source/core/accessibility/AXListBox.h
index 6d46e0e8de0..76890c57259 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXListBox.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXListBox.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class AXListBox : public AXRenderObject {
+class AXListBox FINAL : public AXRenderObject {
private:
explicit AXListBox(RenderObject*);
@@ -41,12 +41,8 @@ public:
static PassRefPtr<AXListBox> create(RenderObject*);
virtual ~AXListBox();
- virtual bool canSetSelectedChildrenAttribute() const OVERRIDE;
- void setSelectedChildren(AccessibilityChildrenVector&);
virtual AccessibilityRole roleValue() const OVERRIDE { return ListBoxRole; }
- virtual void selectedChildren(AccessibilityChildrenVector&) OVERRIDE;
-
virtual void addChildren() OVERRIDE;
private:
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.cpp
index 31eb9d10c45..8e24712572e 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.cpp
@@ -35,7 +35,6 @@
#include "core/html/HTMLSelectElement.h"
#include "core/rendering/RenderListBox.h"
-using namespace std;
namespace WebCore {
@@ -60,7 +59,7 @@ bool AXListBoxOption::isEnabled() const
if (!m_optionElement)
return false;
- if (isHTMLOptGroupElement(m_optionElement))
+ if (isHTMLOptGroupElement(*m_optionElement))
return false;
if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true"))
@@ -74,10 +73,7 @@ bool AXListBoxOption::isEnabled() const
bool AXListBoxOption::isSelected() const
{
- if (!m_optionElement)
- return false;
-
- if (!m_optionElement->hasTagName(optionTag))
+ if (!isHTMLOptionElement(m_optionElement))
return false;
return toHTMLOptionElement(m_optionElement)->selected();
@@ -127,10 +123,7 @@ bool AXListBoxOption::computeAccessibilityIsIgnored() const
bool AXListBoxOption::canSetSelectedAttribute() const
{
- if (!m_optionElement)
- return false;
-
- if (!m_optionElement->hasTagName(optionTag))
+ if (!isHTMLOptionElement(m_optionElement))
return false;
if (m_optionElement->isDisabledFormControl())
@@ -152,10 +145,10 @@ String AXListBoxOption::stringValue() const
if (!ariaLabel.isNull())
return ariaLabel;
- if (m_optionElement->hasTagName(optionTag))
+ if (isHTMLOptionElement(*m_optionElement))
return toHTMLOptionElement(m_optionElement)->text();
- if (isHTMLOptGroupElement(m_optionElement))
+ if (isHTMLOptGroupElement(*m_optionElement))
return toHTMLOptGroupElement(m_optionElement)->groupLabelText();
return String();
@@ -198,10 +191,10 @@ HTMLSelectElement* AXListBoxOption::listBoxOptionParentNode() const
if (!m_optionElement)
return 0;
- if (m_optionElement->hasTagName(optionTag))
+ if (isHTMLOptionElement(*m_optionElement))
return toHTMLOptionElement(m_optionElement)->ownerSelectElement();
- if (isHTMLOptGroupElement(m_optionElement))
+ if (isHTMLOptGroupElement(*m_optionElement))
return toHTMLOptGroupElement(m_optionElement)->ownerSelectElement();
return 0;
@@ -216,7 +209,7 @@ int AXListBoxOption::listBoxOptionIndex() const
if (!selectElement)
return -1;
- const Vector<HTMLElement*>& listItems = selectElement->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement->listItems();
unsigned length = listItems.size();
for (unsigned i = 0; i < length; i++) {
if (listItems[i] == m_optionElement)
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.h b/chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.h
index 02e04330ebc..6ea9ab8af88 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXListBoxOption.h
@@ -40,7 +40,7 @@ class Element;
class HTMLElement;
class HTMLSelectElement;
-class AXListBoxOption : public AXObject {
+class AXListBoxOption FINAL : public AXObject {
private:
AXListBoxOption();
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.cpp
index 5f426306750..e445b5409a0 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.cpp
@@ -30,6 +30,7 @@
#include "config.h"
#include "core/accessibility/AXMediaControls.h"
+#include "core/html/HTMLMediaElement.h"
#include "platform/text/PlatformLocale.h"
namespace WebCore {
@@ -76,22 +77,6 @@ MediaControlElementType AccessibilityMediaControl::controlType() const
return mediaControlElementType(renderer()->node());
}
-void AccessibilityMediaControl::accessibilityText(Vector<AccessibilityText>& textOrder)
-{
- String description = accessibilityDescription();
- if (!description.isEmpty())
- textOrder.append(AccessibilityText(description, AlternativeText));
-
- String title = this->title();
- if (!title.isEmpty())
- textOrder.append(AccessibilityText(title, AlternativeText));
-
- String helptext = helpText();
- if (!helptext.isEmpty())
- textOrder.append(AccessibilityText(helptext, HelpText));
-}
-
-
String AccessibilityMediaControl::title() const
{
// FIXME: the ControlsPanel container should never be visible in the
@@ -113,14 +98,6 @@ String AccessibilityMediaControl::accessibilityDescription() const
return queryString(WebLocalizedString::AXMediaMuteButton);
case MediaPlayButton:
return queryString(WebLocalizedString::AXMediaPlayButton);
- case MediaSeekBackButton:
- return queryString(WebLocalizedString::AXMediaSeekBackButton);
- case MediaSeekForwardButton:
- return queryString(WebLocalizedString::AXMediaSeekForwardButton);
- case MediaRewindButton:
- return queryString(WebLocalizedString::AXMediaRewindButton);
- case MediaReturnToRealtimeButton:
- return queryString(WebLocalizedString::AXMediaReturnToRealTime);
case MediaUnMuteButton:
return queryString(WebLocalizedString::AXMediaUnMuteButton);
case MediaPauseButton:
@@ -151,14 +128,6 @@ String AccessibilityMediaControl::helpText() const
return queryString(WebLocalizedString::AXMediaMuteButtonHelp);
case MediaPlayButton:
return queryString(WebLocalizedString::AXMediaPlayButtonHelp);
- case MediaSeekBackButton:
- return queryString(WebLocalizedString::AXMediaSeekBackButtonHelp);
- case MediaSeekForwardButton:
- return queryString(WebLocalizedString::AXMediaSeekForwardButtonHelp);
- case MediaRewindButton:
- return queryString(WebLocalizedString::AXMediaRewindButtonHelp);
- case MediaReturnToRealtimeButton:
- return queryString(WebLocalizedString::AXMediaReturnToRealTimeHelp);
case MediaUnMuteButton:
return queryString(WebLocalizedString::AXMediaUnMuteButtonHelp);
case MediaPauseButton:
@@ -193,10 +162,6 @@ AccessibilityRole AccessibilityMediaControl::roleValue() const
case MediaExitFullscreenButton:
case MediaMuteButton:
case MediaPlayButton:
- case MediaSeekBackButton:
- case MediaSeekForwardButton:
- case MediaRewindButton:
- case MediaReturnToRealtimeButton:
case MediaUnMuteButton:
case MediaPauseButton:
case MediaShowClosedCaptionsButton:
@@ -248,7 +213,7 @@ bool AXMediaControlsContainer::controllingVideoElement() const
MediaControlTimeDisplayElement* element = static_cast<MediaControlTimeDisplayElement*>(m_renderer->node());
- return toParentMediaElement(element)->isVideo();
+ return isHTMLVideoElement(toParentMediaElement(element));
}
bool AXMediaControlsContainer::computeAccessibilityIsIgnored() const
@@ -279,7 +244,7 @@ PassRefPtr<AXObject> AccessibilityMediaTimeline::create(RenderObject* renderer)
String AccessibilityMediaTimeline::valueDescription() const
{
Node* node = m_renderer->node();
- if (!node->hasTagName(inputTag))
+ if (!isHTMLInputElement(node))
return String();
return localizedMediaTimeDescription(toHTMLInputElement(node)->value().toFloat());
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.h b/chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.h
index cbf6a2f5662..0a627be15e7 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMediaControls.h
@@ -43,19 +43,18 @@ public:
virtual AccessibilityRole roleValue() const OVERRIDE;
- virtual String title() const OVERRIDE;
+ virtual String title() const OVERRIDE FINAL;
virtual String accessibilityDescription() const OVERRIDE;
virtual String helpText() const OVERRIDE;
protected:
explicit AccessibilityMediaControl(RenderObject*);
MediaControlElementType controlType() const;
- virtual void accessibilityText(Vector<AccessibilityText>&) OVERRIDE;
virtual bool computeAccessibilityIsIgnored() const OVERRIDE;
};
-class AccessibilityMediaTimeline : public AXSlider {
+class AccessibilityMediaTimeline FINAL : public AXSlider {
public:
static PassRefPtr<AXObject> create(RenderObject*);
@@ -70,7 +69,7 @@ private:
};
-class AXMediaControlsContainer : public AccessibilityMediaControl {
+class AXMediaControlsContainer FINAL : public AccessibilityMediaControl {
public:
static PassRefPtr<AXObject> create(RenderObject*);
@@ -88,7 +87,7 @@ private:
};
-class AccessibilityMediaTimeDisplay : public AccessibilityMediaControl {
+class AccessibilityMediaTimeDisplay FINAL : public AccessibilityMediaControl {
public:
static PassRefPtr<AXObject> create(RenderObject*);
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.cpp
index 990d6c84601..9bc5b229c5a 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.cpp
@@ -97,7 +97,7 @@ bool AXMenuList::canSetFocusAttribute() const
void AXMenuList::didUpdateActiveOption(int optionIndex)
{
- RefPtr<Document> document(m_renderer->document());
+ RefPtrWillBeRawPtr<Document> document(m_renderer->document());
AXObjectCache* cache = document->axObjectCache();
const AccessibilityChildrenVector& childObjects = children();
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.h b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.h
index b7e3be0863f..93efd64ae30 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuList.h
@@ -35,7 +35,7 @@ class AXMenuListPopup;
class HTMLOptionElement;
class RenderMenuList;
-class AXMenuList : public AXRenderObject {
+class AXMenuList FINAL : public AXRenderObject {
public:
static PassRefPtr<AXMenuList> create(RenderMenuList* renderer);
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.cpp
index 7dc61b759b4..0c657b36248 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.cpp
@@ -38,7 +38,7 @@ AXMenuListOption::AXMenuListOption()
void AXMenuListOption::setElement(HTMLElement* element)
{
- ASSERT_ARG(element, element->hasTagName(optionTag));
+ ASSERT_ARG(element, isHTMLOptionElement(element));
m_element = element;
}
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.h b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.h
index 8c20d8d3067..9af6e9e03b1 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListOption.h
@@ -33,7 +33,7 @@ namespace WebCore {
class AXMenuListPopup;
class HTMLElement;
-class AXMenuListOption : public AXMockObject {
+class AXMenuListOption FINAL : public AXMockObject {
public:
static PassRefPtr<AXMenuListOption> create() { return adoptRef(new AXMenuListOption); }
@@ -58,7 +58,7 @@ private:
virtual String stringValue() const OVERRIDE;
virtual bool computeAccessibilityIsIgnored() const OVERRIDE;
- RefPtr<HTMLElement> m_element;
+ RefPtrWillBePersistent<HTMLElement> m_element;
};
DEFINE_AX_OBJECT_TYPE_CASTS(AXMenuListOption, isMenuListOption());
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.cpp
index 145792aa05f..74353491094 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.cpp
@@ -66,7 +66,8 @@ bool AXMenuListPopup::computeAccessibilityIsIgnored() const
AXMenuListOption* AXMenuListPopup::menuListOptionAXObject(HTMLElement* element) const
{
- if (!element->hasTagName(optionTag))
+ ASSERT(element);
+ if (!isHTMLOptionElement(*element))
return 0;
AXObject* object = document()->axObjectCache()->getOrCreate(MenuListOptionRole);
@@ -98,7 +99,7 @@ void AXMenuListPopup::addChildren()
m_haveChildren = true;
- const Vector<HTMLElement*>& listItems = toHTMLSelectElement(selectNode)->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = toHTMLSelectElement(selectNode)->listItems();
unsigned length = listItems.size();
for (unsigned i = 0; i < length; i++) {
AXMenuListOption* option = menuListOptionAXObject(listItems[i]);
@@ -112,6 +113,8 @@ void AXMenuListPopup::addChildren()
void AXMenuListPopup::childrenChanged()
{
AXObjectCache* cache = axObjectCache();
+ if (!cache)
+ return;
for (size_t i = m_children.size(); i > 0 ; --i) {
AXObject* child = m_children[i - 1].get();
// FIXME: How could children end up in here that have no actionElement(), the check
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.h b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.h
index 44b8917aefa..f9f204d0d7e 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMenuListPopup.h
@@ -35,7 +35,7 @@ class AXMenuListOption;
class HTMLElement;
class HTMLSelectElement;
-class AXMenuListPopup : public AXMockObject {
+class AXMenuListPopup FINAL : public AXMockObject {
public:
static PassRefPtr<AXMenuListPopup> create() { return adoptRef(new AXMenuListPopup); }
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXMockObject.h b/chromium/third_party/WebKit/Source/core/accessibility/AXMockObject.h
index edd6179713c..fcb50aa02c1 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXMockObject.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXMockObject.h
@@ -37,7 +37,7 @@ protected:
public:
virtual ~AXMockObject();
- virtual void setParent(AXObject* parent) { m_parent = parent; };
+ virtual void setParent(AXObject* parent) { m_parent = parent; }
// AXObject overrides.
virtual AXObject* parentObject() const OVERRIDE { return m_parent; }
@@ -50,7 +50,7 @@ protected:
virtual void detachFromParent() OVERRIDE { m_parent = 0; }
private:
- virtual bool isMockObject() const OVERRIDE { return true; }
+ virtual bool isMockObject() const OVERRIDE FINAL { return true; }
virtual bool computeAccessibilityIsIgnored() const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.cpp
index 439e7cd4985..6410e9cafdb 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.cpp
@@ -32,7 +32,6 @@
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/Text.h"
-#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLFieldSetElement.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/html/HTMLInputElement.h"
@@ -44,7 +43,6 @@
#include "platform/UserGestureIndicator.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
namespace WebCore {
@@ -75,11 +73,14 @@ AXNodeObject::~AXNodeObject()
// ARIA Implementer's Guide.
static String accessibleNameForNode(Node* node)
{
+ if (!node)
+ return String();
+
if (node->isTextNode())
return toText(node)->data();
- if (node->hasTagName(inputTag))
- return toHTMLInputElement(node)->value();
+ if (isHTMLInputElement(*node))
+ return toHTMLInputElement(*node).value();
if (node->isHTMLElement()) {
const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr);
@@ -186,43 +187,47 @@ AccessibilityRole AXNodeObject::determineAccessibilityRole()
return LinkRole;
if (node()->isTextNode())
return StaticTextRole;
- if (node()->hasTagName(buttonTag))
+ if (isHTMLButtonElement(*node()))
return buttonRoleType();
- if (node()->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(node());
- if (input->isCheckbox())
+ if (isHTMLInputElement(*node())) {
+ HTMLInputElement& input = toHTMLInputElement(*node());
+ if (input.isCheckbox())
return CheckBoxRole;
- if (input->isRadioButton())
+ if (input.isRadioButton())
return RadioButtonRole;
- if (input->isTextButton())
+ if (input.isTextButton())
return buttonRoleType();
- if (input->isRangeControl())
+ if (input.isRangeControl())
return SliderRole;
- const AtomicString& type = input->getAttribute(typeAttr);
+ const AtomicString& type = input.getAttribute(typeAttr);
if (equalIgnoringCase(type, "color"))
return ColorWellRole;
return TextFieldRole;
}
- if (node()->hasTagName(selectTag)) {
- HTMLSelectElement* selectElement = toHTMLSelectElement(node());
- return selectElement->multiple() ? ListBoxRole : PopUpButtonRole;
+ if (isHTMLSelectElement(*node())) {
+ HTMLSelectElement& selectElement = toHTMLSelectElement(*node());
+ return selectElement.multiple() ? ListBoxRole : PopUpButtonRole;
}
- if (isHTMLTextAreaElement(node()))
+ if (isHTMLTextAreaElement(*node()))
return TextAreaRole;
if (headingLevel())
return HeadingRole;
- if (node()->hasTagName(divTag))
+ if (isHTMLDivElement(*node()))
return DivRole;
- if (node()->hasTagName(pTag))
+ if (isHTMLParagraphElement(*node()))
return ParagraphRole;
- if (isHTMLLabelElement(node()))
+ if (isHTMLLabelElement(*node()))
return LabelRole;
if (node()->isElementNode() && toElement(node())->isFocusable())
return GroupRole;
- if (node()->hasTagName(aTag) && isClickable())
+ if (isHTMLAnchorElement(*node()) && isClickable())
return LinkRole;
+ if (node()->hasTagName(iframeTag))
+ return IframeRole;
+ if (isEmbeddedObject())
+ return EmbeddedObjectRole;
return UnknownRole;
}
@@ -323,7 +328,7 @@ bool AXNodeObject::isGenericFocusableElement() const
// cases already, so we don't need to include them here.
if (roleValue() == WebAreaRole)
return false;
- if (node() && node()->hasTagName(bodyTag))
+ if (isHTMLBodyElement(node()))
return false;
// An SVG root is focusable by default, but it's probably not interactive, so don't
@@ -346,7 +351,7 @@ HTMLLabelElement* AXNodeObject::labelForElement(Element* element) const
}
for (Element* parent = element->parentElement(); parent; parent = parent->parentElement()) {
- if (isHTMLLabelElement(parent))
+ if (isHTMLLabelElement(*parent))
return toHTMLLabelElement(parent);
}
@@ -372,12 +377,10 @@ static Element* siblingWithAriaRole(String role, Node* node)
if (!parent)
return 0;
- for (Node* sibling = parent->firstChild(); sibling; sibling = sibling->nextSibling()) {
- if (sibling->isElementNode()) {
- const AtomicString& siblingAriaRole = toElement(sibling)->getAttribute(roleAttr);
- if (equalIgnoringCase(siblingAriaRole, role))
- return toElement(sibling);
- }
+ for (Element* sibling = ElementTraversal::firstChild(*parent); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {
+ const AtomicString& siblingAriaRole = sibling->getAttribute(roleAttr);
+ if (equalIgnoringCase(siblingAriaRole, role))
+ return sibling;
}
return 0;
@@ -472,13 +475,16 @@ bool AXNodeObject::isControl() const
|| AXObject::isARIAControl(ariaRoleAttribute()));
}
-bool AXNodeObject::isFieldset() const
+bool AXNodeObject::isEmbeddedObject() const
{
- Node* node = this->node();
- if (!node)
- return false;
+ return node()
+ && (node()->hasTagName(objectTag) || node()->hasTagName(embedTag)
+ || node()->hasTagName(appletTag));
+}
- return node->hasTagName(fieldsetTag);
+bool AXNodeObject::isFieldset() const
+{
+ return isHTMLFieldSetElement(node());
}
bool AXNodeObject::isHeading() const
@@ -508,11 +514,8 @@ bool AXNodeObject::isImageButton() const
bool AXNodeObject::isInputImage() const
{
Node* node = this->node();
- if (!node)
- return false;
-
- if (roleValue() == ButtonRole && node->hasTagName(inputTag))
- return toHTMLInputElement(node)->isImageButton();
+ if (roleValue() == ButtonRole && isHTMLInputElement(node))
+ return toHTMLInputElement(*node).isImageButton();
return false;
}
@@ -540,13 +543,13 @@ bool AXNodeObject::isMultiSelectable() const
if (equalIgnoringCase(ariaMultiSelectable, "false"))
return false;
- return node() && node()->hasTagName(selectTag) && toHTMLSelectElement(node())->multiple();
+ return isHTMLSelectElement(node()) && toHTMLSelectElement(*node()).multiple();
}
bool AXNodeObject::isNativeCheckboxOrRadio() const
{
Node* node = this->node();
- if (!node || !node->hasTagName(inputTag))
+ if (!isHTMLInputElement(node))
return false;
HTMLInputElement* input = toHTMLInputElement(node);
@@ -559,14 +562,14 @@ bool AXNodeObject::isNativeImage() const
if (!node)
return false;
- if (node->hasTagName(imgTag))
+ if (isHTMLImageElement(*node))
return true;
- if (node->hasTagName(appletTag) || node->hasTagName(embedTag) || node->hasTagName(objectTag))
+ if (isHTMLAppletElement(*node) || isHTMLEmbedElement(*node) || isHTMLObjectElement(*node))
return true;
- if (node->hasTagName(inputTag))
- return toHTMLInputElement(node)->isImageButton();
+ if (isHTMLInputElement(*node))
+ return toHTMLInputElement(*node).isImageButton();
return false;
}
@@ -577,10 +580,10 @@ bool AXNodeObject::isNativeTextControl() const
if (!node)
return false;
- if (isHTMLTextAreaElement(node))
+ if (isHTMLTextAreaElement(*node))
return true;
- if (node->hasTagName(inputTag)) {
+ if (isHTMLInputElement(*node)) {
HTMLInputElement* input = toHTMLInputElement(node);
return input->isText() || input->isNumberField();
}
@@ -605,7 +608,7 @@ bool AXNodeObject::isNonNativeTextControl() const
bool AXNodeObject::isPasswordField() const
{
Node* node = this->node();
- if (!node || !node->hasTagName(inputTag))
+ if (!isHTMLInputElement(node))
return false;
if (ariaRoleAttribute() != UnknownRole)
@@ -631,8 +634,8 @@ bool AXNodeObject::isChecked() const
return false;
// First test for native checkedness semantics
- if (node->hasTagName(inputTag))
- return toHTMLInputElement(node)->shouldAppearChecked();
+ if (isHTMLInputElement(*node))
+ return toHTMLInputElement(*node).shouldAppearChecked();
// Else, if this is an ARIA checkbox or radio, respect the aria-checked attribute
AccessibilityRole ariaRole = ariaRoleAttribute();
@@ -675,7 +678,7 @@ bool AXNodeObject::isEnabled() const
bool AXNodeObject::isIndeterminate() const
{
Node* node = this->node();
- if (!node || !node->hasTagName(inputTag))
+ if (!isHTMLInputElement(node))
return false;
return toHTMLInputElement(node)->shouldAppearIndeterminate();
@@ -706,13 +709,13 @@ bool AXNodeObject::isReadOnly() const
if (!node)
return true;
- if (isHTMLTextAreaElement(node))
- return toHTMLFormControlElement(node)->isReadOnly();
+ if (isHTMLTextAreaElement(*node))
+ return toHTMLTextAreaElement(*node).isReadOnly();
- if (node->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(node);
- if (input->isTextField())
- return input->isReadOnly();
+ if (isHTMLInputElement(*node)) {
+ HTMLInputElement& input = toHTMLInputElement(*node);
+ if (input.isTextField())
+ return input.isReadOnly();
}
return !node->rendererIsEditable();
@@ -770,18 +773,13 @@ bool AXNodeObject::canSetValueAttribute() const
bool AXNodeObject::canvasHasFallbackContent() const
{
Node* node = this->node();
- if (!node || !node->hasTagName(canvasTag))
+ if (!isHTMLCanvasElement(node))
return false;
// If it has any children that are elements, we'll assume it might be fallback
// content. If it has no children or its only children are not elements
// (e.g. just text nodes), it doesn't have fallback content.
- for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
- if (child->isElementNode())
- return true;
- }
-
- return false;
+ return ElementTraversal::firstChild(*node);
}
bool AXNodeObject::exposesTitleUIElement() const
@@ -883,8 +881,8 @@ String AXNodeObject::text() const
if (!node)
return String();
- if (isNativeTextControl() && (isHTMLTextAreaElement(node) || node->hasTagName(inputTag)))
- return toHTMLTextFormControlElement(node)->value();
+ if (isNativeTextControl() && (isHTMLTextAreaElement(*node) || isHTMLInputElement(*node)))
+ return toHTMLTextFormControlElement(*node).value();
if (!node->isElementNode())
return String();
@@ -924,7 +922,7 @@ void AXNodeObject::colorValue(int& r, int& g, int& b) const
if (!isColorWell())
return;
- if (!node() || !node()->hasTagName(inputTag))
+ if (!isHTMLInputElement(node()))
return;
HTMLInputElement* input = toHTMLInputElement(node());
@@ -932,8 +930,10 @@ void AXNodeObject::colorValue(int& r, int& g, int& b) const
if (!equalIgnoringCase(type, "color"))
return;
- // HTMLInputElement::value always returns a string parseable by Color().
- Color color(input->value());
+ // HTMLInputElement::value always returns a string parseable by Color.
+ Color color;
+ bool success = color.setFromString(input->value());
+ ASSERT_UNUSED(success, success);
r = color.red();
g = color.green();
b = color.blue();
@@ -952,10 +952,10 @@ float AXNodeObject::valueForRange() const
if (hasAttribute(aria_valuenowAttr))
return getAttribute(aria_valuenowAttr).toFloat();
- if (node() && node()->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(node());
- if (input->isRangeControl())
- return input->valueAsNumber();
+ if (isHTMLInputElement(node())) {
+ HTMLInputElement& input = toHTMLInputElement(*node());
+ if (input.isRangeControl())
+ return input.valueAsNumber();
}
return 0.0;
@@ -966,10 +966,10 @@ float AXNodeObject::maxValueForRange() const
if (hasAttribute(aria_valuemaxAttr))
return getAttribute(aria_valuemaxAttr).toFloat();
- if (node() && node()->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(node());
- if (input->isRangeControl())
- return input->maximum();
+ if (isHTMLInputElement(node())) {
+ HTMLInputElement& input = toHTMLInputElement(*node());
+ if (input.isRangeControl())
+ return input.maximum();
}
return 0.0;
@@ -980,10 +980,10 @@ float AXNodeObject::minValueForRange() const
if (hasAttribute(aria_valueminAttr))
return getAttribute(aria_valueminAttr).toFloat();
- if (node() && node()->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(node());
- if (input->isRangeControl())
- return input->minimum();
+ if (isHTMLInputElement(node())) {
+ HTMLInputElement& input = toHTMLInputElement(*node());
+ if (input.isRangeControl())
+ return input.minimum();
}
return 0.0;
@@ -1010,17 +1010,17 @@ String AXNodeObject::stringValue() const
if (node->isTextNode())
return textUnderElement();
- if (node->hasTagName(selectTag)) {
- HTMLSelectElement* selectElement = toHTMLSelectElement(node);
- int selectedIndex = selectElement->selectedIndex();
- const Vector<HTMLElement*> listItems = selectElement->listItems();
+ if (isHTMLSelectElement(*node)) {
+ HTMLSelectElement& selectElement = toHTMLSelectElement(*node);
+ int selectedIndex = selectElement.selectedIndex();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement.listItems();
if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {
const AtomicString& overriddenDescription = listItems[selectedIndex]->fastGetAttribute(aria_labelAttr);
if (!overriddenDescription.isNull())
return overriddenDescription;
}
- if (!selectElement->multiple())
- return selectElement->value();
+ if (!selectElement.multiple())
+ return selectElement.value();
return String();
}
@@ -1056,18 +1056,6 @@ AccessibilityRole AXNodeObject::ariaRoleAttribute() const
return m_ariaRole;
}
-void AXNodeObject::accessibilityText(Vector<AccessibilityText>& textOrder)
-{
- titleElementText(textOrder);
- alternativeText(textOrder);
- visibleText(textOrder);
- helpText(textOrder);
-
- String placeholder = placeholderValue();
- if (!placeholder.isEmpty())
- textOrder.append(AccessibilityText(placeholder, PlaceholderText));
-}
-
// When building the textUnderElement for an object, determine whether or not
// we should include the inner text of this given descendant object or skip it.
static bool shouldUseAccessiblityObjectInnerText(AXObject* obj)
@@ -1164,27 +1152,27 @@ String AXNodeObject::title() const
if (!node)
return String();
- bool isInputTag = node->hasTagName(inputTag);
- if (isInputTag) {
- HTMLInputElement* input = toHTMLInputElement(node);
- if (input->isTextButton())
- return input->valueWithDefault();
+ bool isInputElement = isHTMLInputElement(*node);
+ if (isInputElement) {
+ HTMLInputElement& input = toHTMLInputElement(*node);
+ if (input.isTextButton())
+ return input.valueWithDefault();
}
- if (isInputTag || AXObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
+ if (isInputElement || AXObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
HTMLLabelElement* label = labelForElement(toElement(node));
if (label && !exposesTitleUIElement())
return label->innerText();
}
// If this node isn't rendered, there's no inner text we can extract from a select element.
- if (!isAXRenderObject() && node->hasTagName(selectTag))
+ if (!isAXRenderObject() && isHTMLSelectElement(*node))
return String();
switch (roleValue()) {
case PopUpButtonRole:
// Native popup buttons should not use their button children's text as a title. That value is retrieved through stringValue().
- if (node->hasTagName(selectTag))
+ if (isHTMLSelectElement(*node))
return String();
case ButtonRole:
case ToggleButtonRole:
@@ -1331,7 +1319,7 @@ void AXNodeObject::addChildren()
m_haveChildren = true;
// The only time we add children from the DOM tree to a node with a renderer is when it's a canvas.
- if (renderer() && !m_node->hasTagName(canvasTag))
+ if (renderer() && !isHTMLCanvasElement(*m_node))
return;
for (Node* child = m_node->firstChild(); child; child = child->nextSibling())
@@ -1398,11 +1386,11 @@ Element* AXNodeObject::actionElement() const
if (!node)
return 0;
- if (node->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(node);
- if (!input->isDisabledFormControl() && (isCheckboxOrRadio() || input->isTextButton()))
- return input;
- } else if (node->hasTagName(buttonTag)) {
+ if (isHTMLInputElement(*node)) {
+ HTMLInputElement& input = toHTMLInputElement(*node);
+ if (!input.isDisabledFormControl() && (isCheckboxOrRadio() || input.isTextButton()))
+ return &input;
+ } else if (isHTMLButtonElement(*node)) {
return toElement(node);
}
@@ -1415,7 +1403,7 @@ Element* AXNodeObject::actionElement() const
if (isImageButton())
return toElement(node);
- if (node->hasTagName(selectTag))
+ if (isHTMLSelectElement(*node))
return toElement(node);
switch (roleValue()) {
@@ -1447,7 +1435,7 @@ Element* AXNodeObject::anchorElement() const
// search up the DOM tree for an anchor element
// NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
for ( ; node; node = node->parentNode()) {
- if (isHTMLAnchorElement(node) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
+ if (isHTMLAnchorElement(*node) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
return toElement(node);
}
@@ -1493,13 +1481,8 @@ HTMLLabelElement* AXNodeObject::labelElementContainer() const
if (isControl())
return 0;
- // find if this has a parent that is a label
- for (Node* parentNode = node(); parentNode; parentNode = parentNode->parentNode()) {
- if (isHTMLLabelElement(parentNode))
- return toHTMLLabelElement(parentNode);
- }
-
- return 0;
+ // find if this has a ancestor that is a label
+ return Traversal<HTMLLabelElement>::firstAncestorOrSelf(*node());
}
void AXNodeObject::setFocused(bool on)
@@ -1509,7 +1492,7 @@ void AXNodeObject::setFocused(bool on)
Document* document = this->document();
if (!on) {
- document->setFocusedElement(0);
+ document->setFocusedElement(nullptr);
} else {
Node* node = this->node();
if (node && node->isElementNode()) {
@@ -1517,11 +1500,11 @@ void AXNodeObject::setFocused(bool on)
// That is a problem when focus is removed from the webpage to chrome, and then returns.
// In these cases, we need to do what keyboard and mouse focus do, which is reset focus first.
if (document->focusedElement() == node)
- document->setFocusedElement(0);
+ document->setFocusedElement(nullptr);
toElement(node)->focus();
} else {
- document->setFocusedElement(0);
+ document->setFocusedElement(nullptr);
}
}
}
@@ -1569,10 +1552,10 @@ void AXNodeObject::childrenChanged()
void AXNodeObject::selectionChanged()
{
- // When the selection changes, post the notification on the first ancestor that's an
- // ARIA text box, or that's marked as contentEditable, otherwise post the notification
- // on the web area.
- if (isNonNativeTextControl() || isWebArea())
+ // Post the selected text changed event on the first ancestor that's
+ // focused (to handle form controls, ARIA text boxes and contentEditable),
+ // or the web area if the selection is just in the document somewhere.
+ if (isFocused() || isWebArea())
axObjectCache()->postNotification(this, document(), AXObjectCache::AXSelectedTextChanged, true);
else
AXObject::selectionChanged(); // Calls selectionChanged on parent.
@@ -1633,7 +1616,7 @@ String AXNodeObject::alternativeTextForWebArea() const
Node* owner = document->ownerElement();
if (owner) {
- if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
+ if (isHTMLFrameElementBase(*owner)) {
const AtomicString& title = toElement(owner)->getAttribute(titleAttr);
if (!title.isEmpty())
return title;
@@ -1704,110 +1687,4 @@ void AXNodeObject::changeValueByPercent(float percentChange)
axObjectCache()->postNotification(node(), AXObjectCache::AXValueChanged, true);
}
-void AXNodeObject::helpText(Vector<AccessibilityText>& textOrder) const
-{
- const AtomicString& ariaHelp = getAttribute(aria_helpAttr);
- if (!ariaHelp.isEmpty())
- textOrder.append(AccessibilityText(ariaHelp, HelpText));
-
- String describedBy = ariaDescribedByAttribute();
- if (!describedBy.isEmpty())
- textOrder.append(AccessibilityText(describedBy, SummaryText));
-
- // Add help type text that is derived from ancestors.
- for (Node* curr = node(); curr; curr = curr->parentNode()) {
- const AtomicString& summary = getAttribute(summaryAttr);
- if (!summary.isEmpty())
- textOrder.append(AccessibilityText(summary, SummaryText));
-
- // The title attribute should be used as help text unless it is already being used as descriptive text.
- const AtomicString& title = getAttribute(titleAttr);
- if (!title.isEmpty())
- textOrder.append(AccessibilityText(title, TitleTagText));
-
- // Only take help text from an ancestor element if its a group or an unknown role. If help was
- // added to those kinds of elements, it is likely it was meant for a child element.
- AXObject* axObj = axObjectCache()->getOrCreate(curr);
- if (!axObj)
- return;
-
- AccessibilityRole role = axObj->roleValue();
- if (role != GroupRole && role != UnknownRole)
- break;
- }
-}
-
-void AXNodeObject::titleElementText(Vector<AccessibilityText>& textOrder)
-{
- Node* node = this->node();
- if (!node)
- return;
-
- bool isInputTag = node->hasTagName(inputTag);
- if (isInputTag || AXObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
- HTMLLabelElement* label = labelForElement(toElement(node));
- if (label) {
- AXObject* labelObject = axObjectCache()->getOrCreate(label);
- textOrder.append(AccessibilityText(label->innerText(), LabelByElementText, labelObject));
- return;
- }
- }
-
- AXObject* titleUIElement = this->titleUIElement();
- if (titleUIElement)
- textOrder.append(AccessibilityText(String(), LabelByElementText, titleUIElement));
-}
-
-void AXNodeObject::visibleText(Vector<AccessibilityText>& textOrder) const
-{
- Node* node = this->node();
- if (!node)
- return;
-
- bool isInputTag = node->hasTagName(inputTag);
- if (isInputTag) {
- HTMLInputElement* input = toHTMLInputElement(node);
- if (input->isTextButton()) {
- textOrder.append(AccessibilityText(input->valueWithDefault(), VisibleText));
- return;
- }
- }
-
- // If this node isn't rendered, there's no inner text we can extract from a select element.
- if (!isAXRenderObject() && node->hasTagName(selectTag))
- return;
-
- bool useTextUnderElement = false;
-
- switch (roleValue()) {
- case PopUpButtonRole:
- // Native popup buttons should not use their button children's text as a title. That value is retrieved through stringValue().
- if (node->hasTagName(selectTag))
- break;
- case ButtonRole:
- case ToggleButtonRole:
- case CheckBoxRole:
- case ListBoxOptionRole:
- case MenuButtonRole:
- case MenuItemRole:
- case RadioButtonRole:
- case TabRole:
- useTextUnderElement = true;
- break;
- default:
- break;
- }
-
- // If it's focusable but it's not content editable or a known control type, then it will appear to
- // the user as a single atomic object, so we should use its text as the default title.
- if (isHeading() || isLink() || isGenericFocusableElement())
- useTextUnderElement = true;
-
- if (useTextUnderElement) {
- String text = textUnderElement();
- if (!text.isEmpty())
- textOrder.append(AccessibilityText(text, ChildrenText));
- }
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.h b/chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.h
index 829aaf1bc76..ca2d2b0ceaa 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXNodeObject.h
@@ -37,7 +37,7 @@ namespace WebCore {
class AXObjectCache;
class Element;
-class Frame;
+class LocalFrame;
class FrameView;
class HitTestResult;
class HTMLAnchorElement;
@@ -102,52 +102,53 @@ protected:
virtual void init() OVERRIDE;
virtual void detach() OVERRIDE;
virtual bool isDetached() const OVERRIDE { return !m_node; }
- virtual bool isAXNodeObject() const OVERRIDE { return true; }
+ virtual bool isAXNodeObject() const OVERRIDE FINAL { return true; }
// Check object role or purpose.
- virtual bool isAnchor() const OVERRIDE;
+ virtual bool isAnchor() const OVERRIDE FINAL;
virtual bool isControl() const OVERRIDE;
- virtual bool isFieldset() const OVERRIDE;
- virtual bool isHeading() const OVERRIDE;
- virtual bool isHovered() const OVERRIDE;
- virtual bool isImage() const OVERRIDE;
+ virtual bool isEmbeddedObject() const OVERRIDE FINAL;
+ virtual bool isFieldset() const OVERRIDE FINAL;
+ virtual bool isHeading() const OVERRIDE FINAL;
+ virtual bool isHovered() const OVERRIDE FINAL;
+ virtual bool isImage() const OVERRIDE FINAL;
bool isImageButton() const;
- virtual bool isInputImage() const OVERRIDE;
- virtual bool isLink() const;
- virtual bool isMenu() const OVERRIDE;
- virtual bool isMenuButton() const OVERRIDE;
+ virtual bool isInputImage() const OVERRIDE FINAL;
+ virtual bool isLink() const OVERRIDE FINAL;
+ virtual bool isMenu() const OVERRIDE FINAL;
+ virtual bool isMenuButton() const OVERRIDE FINAL;
virtual bool isMultiSelectable() const OVERRIDE;
bool isNativeImage() const;
- virtual bool isNativeTextControl() const OVERRIDE;
- virtual bool isNonNativeTextControl() const OVERRIDE;
- virtual bool isPasswordField() const OVERRIDE;
+ virtual bool isNativeTextControl() const OVERRIDE FINAL;
+ virtual bool isNonNativeTextControl() const OVERRIDE FINAL;
+ virtual bool isPasswordField() const OVERRIDE FINAL;
virtual bool isProgressIndicator() const OVERRIDE;
virtual bool isSlider() const OVERRIDE;
// Check object state.
- virtual bool isChecked() const OVERRIDE;
- virtual bool isClickable() const OVERRIDE;
+ virtual bool isChecked() const OVERRIDE FINAL;
+ virtual bool isClickable() const OVERRIDE FINAL;
virtual bool isEnabled() const OVERRIDE;
- virtual bool isIndeterminate() const OVERRIDE;
- virtual bool isPressed() const OVERRIDE;
+ virtual bool isIndeterminate() const OVERRIDE FINAL;
+ virtual bool isPressed() const OVERRIDE FINAL;
virtual bool isReadOnly() const OVERRIDE;
- virtual bool isRequired() const OVERRIDE;
+ virtual bool isRequired() const OVERRIDE FINAL;
// Check whether certain properties can be modified.
virtual bool canSetFocusAttribute() const OVERRIDE;
virtual bool canSetValueAttribute() const OVERRIDE;
// Properties of static elements.
- virtual bool canvasHasFallbackContent() const OVERRIDE;
+ virtual bool canvasHasFallbackContent() const OVERRIDE FINAL;
virtual bool exposesTitleUIElement() const OVERRIDE;
- virtual int headingLevel() const OVERRIDE;
- virtual unsigned hierarchicalLevel() const OVERRIDE;
+ virtual int headingLevel() const OVERRIDE FINAL;
+ virtual unsigned hierarchicalLevel() const OVERRIDE FINAL;
virtual String text() const OVERRIDE;
virtual AXObject* titleUIElement() const OVERRIDE;
// Properties of interactive elements.
- virtual AccessibilityButtonState checkboxOrRadioValue() const OVERRIDE;
- virtual void colorValue(int& r, int& g, int& b) const OVERRIDE;
+ virtual AccessibilityButtonState checkboxOrRadioValue() const OVERRIDE FINAL;
+ virtual void colorValue(int& r, int& g, int& b) const OVERRIDE FINAL;
virtual String valueDescription() const OVERRIDE;
virtual float valueForRange() const OVERRIDE;
virtual float maxValueForRange() const OVERRIDE;
@@ -155,12 +156,11 @@ protected:
virtual String stringValue() const OVERRIDE;
// ARIA attributes.
- virtual String ariaDescribedByAttribute() const;
- virtual String ariaLabeledByAttribute() const OVERRIDE;
- virtual AccessibilityRole ariaRoleAttribute() const OVERRIDE;
+ virtual String ariaDescribedByAttribute() const OVERRIDE FINAL;
+ virtual String ariaLabeledByAttribute() const OVERRIDE FINAL;
+ virtual AccessibilityRole ariaRoleAttribute() const OVERRIDE FINAL;
// Accessibility Text.
- virtual void accessibilityText(Vector<AccessibilityText>&) OVERRIDE;
virtual String textUnderElement() const OVERRIDE;
// Accessibility Text - (To be deprecated).
@@ -184,21 +184,21 @@ protected:
void insertChild(AXObject*, unsigned index);
// DOM and Render tree access.
- virtual Element* actionElement() const OVERRIDE;
+ virtual Element* actionElement() const OVERRIDE FINAL;
virtual Element* anchorElement() const OVERRIDE;
virtual Document* document() const OVERRIDE;
virtual Node* node() const OVERRIDE { return m_node; }
// Modify or take an action on an object.
- virtual void setFocused(bool) OVERRIDE;
- virtual void increment() OVERRIDE;
- virtual void decrement() OVERRIDE;
+ virtual void setFocused(bool) OVERRIDE FINAL;
+ virtual void increment() OVERRIDE FINAL;
+ virtual void decrement() OVERRIDE FINAL;
// Notifications that this object may have changed.
virtual void childrenChanged() OVERRIDE;
- virtual void selectionChanged() OVERRIDE;
+ virtual void selectionChanged() OVERRIDE FINAL;
virtual void textChanged() OVERRIDE;
- virtual void updateAccessibilityRole() OVERRIDE;
+ virtual void updateAccessibilityRole() OVERRIDE FINAL;
private:
Node* m_node;
@@ -207,9 +207,6 @@ private:
void alternativeText(Vector<AccessibilityText>&) const;
void ariaLabeledByText(Vector<AccessibilityText>&) const;
void changeValueByPercent(float percentChange);
- void helpText(Vector<AccessibilityText>&) const;
- void titleElementText(Vector<AccessibilityText>&);
- void visibleText(Vector<AccessibilityText>&) const;
float stepValueForRange() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXObject.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXObject.cpp
index 24f3285b863..08d9104b400 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXObject.cpp
@@ -33,7 +33,7 @@
#include "core/dom/NodeTraversal.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/RenderListItem.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
@@ -43,7 +43,6 @@
#include "wtf/text/WTFString.h"
using blink::WebLocalizedString;
-using namespace std;
namespace WebCore {
@@ -70,7 +69,7 @@ static ARIARoleMap* createARIARoleMap()
{ "contentinfo", ContentInfoRole },
{ "dialog", DialogRole },
{ "directory", DirectoryRole },
- { "grid", TableRole },
+ { "grid", GridRole },
{ "gridcell", CellRole },
{ "columnheader", ColumnHeaderRole },
{ "combobox", ComboBoxRole },
@@ -164,13 +163,6 @@ AXObjectCache* AXObject::axObjectCache() const
return 0;
}
-void AXObject::updateBackingStore()
-{
- // Updating the layout may delete this object.
- if (Document* document = this->document())
- document->updateLayoutIgnorePendingStylesheets();
-}
-
bool AXObject::isARIATextControl() const
{
return ariaRoleAttribute() == TextAreaRole || ariaRoleAttribute() == TextFieldRole;
@@ -183,6 +175,25 @@ bool AXObject::isButton() const
return role == ButtonRole || role == PopUpButtonRole || role == ToggleButtonRole;
}
+bool AXObject::isLandmarkRelated() const
+{
+ switch (roleValue()) {
+ case ApplicationRole:
+ case ArticleRole:
+ case BannerRole:
+ case ComplementaryRole:
+ case ContentInfoRole:
+ case FooterRole:
+ case MainRole:
+ case NavigationRole:
+ case RegionRole:
+ case SearchRole:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool AXObject::isMenuRelated() const
{
switch (roleValue()) {
@@ -242,7 +253,11 @@ bool AXObject::isExpanded() const
bool AXObject::accessibilityIsIgnored() const
{
- AXComputedObjectAttributeCache* attributeCache = axObjectCache()->computedObjectAttributeCache();
+ AXObjectCache* cache = axObjectCache();
+ if (!cache)
+ return true;
+
+ AXComputedObjectAttributeCache* attributeCache = cache->computedObjectAttributeCache();
if (attributeCache) {
AXObjectInclusion ignored = attributeCache->getIgnored(axObjectID());
switch (ignored) {
@@ -376,15 +391,6 @@ AccessibilityButtonState AXObject::checkboxOrRadioValue() const
return ButtonStateOff;
}
-const AtomicString& AXObject::placeholderValue() const
-{
- const AtomicString& placeholder = getAttribute(placeholderAttr);
- if (!placeholder.isEmpty())
- return placeholder;
-
- return nullAtom;
-}
-
bool AXObject::ariaIsMultiline() const
{
return equalIgnoringCase(getAttribute(aria_multilineAttr), "true");
@@ -395,20 +401,6 @@ bool AXObject::ariaPressedIsPresent() const
return !getAttribute(aria_pressedAttr).isEmpty();
}
-const AtomicString& AXObject::invalidStatus() const
-{
- DEFINE_STATIC_LOCAL(const AtomicString, invalidStatusFalse, ("false", AtomicString::ConstructFromLiteral));
-
- // aria-invalid can return false (default), grammer, spelling, or true.
- const AtomicString& ariaInvalid = getAttribute(aria_invalidAttr);
-
- // If empty or not present, it should return false.
- if (ariaInvalid.isEmpty())
- return invalidStatusFalse;
-
- return ariaInvalid;
-}
-
bool AXObject::supportsARIAAttributes() const
{
return supportsARIALiveRegion()
@@ -735,7 +727,7 @@ void AXObject::scrollToMakeVisibleWithSubFocus(const IntRect& subfocus) const
if (!scrollableArea)
return;
- LayoutRect objectRect = elementRect();
+ IntRect objectRect = pixelSnappedIntRect(elementRect());
IntPoint scrollPosition = scrollableArea->scrollPosition();
IntRect scrollVisibleRect = scrollableArea->visibleContentRect();
@@ -780,8 +772,8 @@ void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const
ScrollableArea* scrollableArea = outer->getScrollableAreaIfScrollable();
- LayoutRect innerRect = inner->isAXScrollView() ? inner->parentObject()->elementRect() : inner->elementRect();
- LayoutRect objectRect = innerRect;
+ IntRect innerRect = inner->isAXScrollView() ? pixelSnappedIntRect(inner->parentObject()->elementRect()) : pixelSnappedIntRect(inner->elementRect());
+ IntRect objectRect = innerRect;
IntPoint scrollPosition = scrollableArea->scrollPosition();
// Convert the object rect into local coordinates.
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXObject.h b/chromium/third_party/WebKit/Source/core/accessibility/AXObject.h
index e66ba18dd7b..b10d5db8307 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXObject.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXObject.h
@@ -42,7 +42,7 @@ namespace WebCore {
class AXObject;
class AXObjectCache;
class Element;
-class Frame;
+class LocalFrame;
class FrameView;
class HTMLAnchorElement;
class HTMLAreaElement;
@@ -86,6 +86,7 @@ enum AccessibilityRole {
DocumentRole,
DrawerRole,
EditableTextRole,
+ EmbeddedObjectRole,
FooterRole,
FormRole,
GridRole,
@@ -94,6 +95,7 @@ enum AccessibilityRole {
HeadingRole,
HelpTagRole,
HorizontalRuleRole,
+ IframeRole,
IgnoredRole,
ImageMapLinkRole,
ImageMapRole,
@@ -291,9 +293,6 @@ public:
AXObjectCache* axObjectCache() const;
AXID axObjectID() const { return m_id; }
- // Lays out the page so that the accessibility tree is based on up-to-date information.
- void updateBackingStore();
-
// Determine subclass type.
virtual bool isAXNodeObject() const { return false; }
virtual bool isAXRenderObject() const { return false; }
@@ -316,12 +315,14 @@ public:
bool isComboBox() const { return roleValue() == ComboBoxRole; }
virtual bool isControl() const { return false; }
virtual bool isDataTable() const { return false; }
+ virtual bool isEmbeddedObject() const { return false; }
virtual bool isFieldset() const { return false; }
virtual bool isFileUploadButton() const { return false; }
virtual bool isHeading() const { return false; }
virtual bool isImage() const { return false; }
virtual bool isImageMapLink() const { return false; }
virtual bool isInputImage() const { return false; }
+ bool isLandmarkRelated() const;
virtual bool isLink() const { return false; }
virtual bool isList() const { return false; }
bool isListItem() const { return roleValue() == ListItemRole; }
@@ -340,7 +341,6 @@ public:
virtual bool isProgressIndicator() const { return false; }
bool isRadioButton() const { return roleValue() == RadioButtonRole; }
bool isScrollbar() const { return roleValue() == ScrollBarRole; }
- bool isSeamlessWebArea() const { return roleValue() == SeamlessWebAreaRole; }
virtual bool isSlider() const { return false; }
virtual bool isSpinButton() const { return roleValue() == SpinButtonRole; }
virtual bool isSpinButtonPart() const { return false; }
@@ -378,7 +378,6 @@ public:
virtual bool canSetFocusAttribute() const { return false; }
virtual bool canSetValueAttribute() const { return false; }
virtual bool canSetSelectedAttribute() const { return false; }
- virtual bool canSetSelectedChildrenAttribute() const { return false; }
// Whether objects are ignored, i.e. not included in the tree.
bool accessibilityIsIgnored() const;
@@ -397,7 +396,6 @@ public:
// 1-based, to match the aria-level spec.
virtual unsigned hierarchicalLevel() const { return 0; }
virtual AccessibilityOrientation orientation() const;
- virtual int tableLevel() const { return 0; }
virtual String text() const { return String(); }
virtual int textLength() const { return 0; }
virtual AXObject* titleUIElement() const { return 0; }
@@ -418,21 +416,22 @@ public:
virtual float valueForRange() const { return 0.0f; }
virtual float maxValueForRange() const { return 0.0f; }
virtual float minValueForRange() const { return 0.0f; }
- const AtomicString& placeholderValue() const;
- virtual void selectedChildren(AccessibilityChildrenVector&) { }
virtual String stringValue() const { return String(); }
// ARIA attributes.
virtual AXObject* activeDescendant() const { return 0; }
virtual String ariaDescribedByAttribute() const { return String(); }
virtual void ariaFlowToElements(AccessibilityChildrenVector&) const { }
+ virtual void ariaControlsElements(AccessibilityChildrenVector&) const { }
+ virtual void ariaDescribedbyElements(AccessibilityChildrenVector& describedby) const { };
+ virtual void ariaLabelledbyElements(AccessibilityChildrenVector& labelledby) const { };
+ virtual void ariaOwnsElements(AccessibilityChildrenVector& owns) const { };
virtual bool ariaHasPopup() const { return false; }
bool ariaIsMultiline() const;
virtual String ariaLabeledByAttribute() const { return String(); }
bool ariaPressedIsPresent() const;
virtual AccessibilityRole ariaRoleAttribute() const { return UnknownRole; }
virtual bool ariaRoleHasPresentationalChildren() const { return false; }
- const AtomicString& invalidStatus() const;
virtual bool isARIAGrabbed() { return false; }
virtual bool isPresentationalChildOfAriaRole() const { return false; }
virtual bool shouldFocusActiveDescendant() const { return false; }
@@ -455,7 +454,6 @@ public:
virtual bool ariaLiveRegionBusy() const { return false; }
// Accessibility Text.
- virtual void accessibilityText(Vector<AccessibilityText>&) { };
virtual String textUnderElement() const { return String(); }
// Accessibility Text - (To be deprecated).
@@ -489,6 +487,7 @@ public:
virtual bool canHaveChildren() const { return true; }
bool hasChildren() const { return m_haveChildren; }
virtual void updateChildrenIfNecessary();
+ virtual bool needsToUpdateChildren() const { return false; }
virtual void setNeedsToUpdateChildren() { }
virtual void clearChildren();
virtual void detachFromParent() { }
@@ -513,7 +512,6 @@ public:
// Selected text.
virtual PlainTextRange selectedTextRange() const { return PlainTextRange(); }
- virtual String selectedText() const { return String(); }
// Modify or take an action on an object.
virtual void increment() { }
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.cpp
index 34d6f630f5c..dff32cf5b93 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.cpp
@@ -30,7 +30,7 @@
#include "core/accessibility/AXObjectCache.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXARIAGrid.h"
#include "core/accessibility/AXARIAGridCell.h"
#include "core/accessibility/AXARIAGridRow.h"
@@ -56,7 +56,7 @@
#include "core/accessibility/AXTableHeaderContainer.h"
#include "core/accessibility/AXTableRow.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAreaElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLInputElement.h"
@@ -107,10 +107,10 @@ void AXComputedObjectAttributeCache::clear()
bool AXObjectCache::gAccessibilityEnabled = false;
bool AXObjectCache::gInlineTextBoxAccessibility = false;
-AXObjectCache::AXObjectCache(const Document* doc)
- : m_notificationPostTimer(this, &AXObjectCache::notificationPostTimerFired)
+AXObjectCache::AXObjectCache(Document& document)
+ : m_document(document)
+ , m_notificationPostTimer(this, &AXObjectCache::notificationPostTimerFired)
{
- m_document = const_cast<Document*>(doc);
m_computedObjectAttributeCache = AXComputedObjectAttributeCache::create();
}
@@ -161,13 +161,17 @@ AXObject* AXObjectCache::focusedUIElementForPage(const Page* page)
if (!gAccessibilityEnabled)
return 0;
+ // Cross-process accessibility is not yet implemented.
+ if (!page->focusController().focusedOrMainFrame()->isLocalFrame())
+ return 0;
+
// get the focused node in the page
- Document* focusedDocument = page->focusController().focusedOrMainFrame()->document();
+ Document* focusedDocument = toLocalFrame(page->focusController().focusedOrMainFrame())->document();
Node* focusedNode = focusedDocument->focusedElement();
if (!focusedNode)
focusedNode = focusedDocument;
- if (isHTMLAreaElement(focusedNode))
+ if (isHTMLAreaElement(*focusedNode))
return focusedImageMapUIElement(toHTMLAreaElement(focusedNode));
AXObject* obj = focusedNode->document().axObjectCache()->getOrCreate(focusedNode);
@@ -271,7 +275,7 @@ static PassRefPtr<AXObject> createFromRenderer(RenderObject* renderer)
// If the node is aria role="list" or the aria role is empty and its a
// ul/ol/dl type (it shouldn't be a list if aria says otherwise).
if (node && ((nodeHasRole(node, "list") || nodeHasRole(node, "directory"))
- || (nodeHasRole(node, nullAtom) && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(dlTag)))))
+ || (nodeHasRole(node, nullAtom) && (isHTMLUListElement(*node) || isHTMLOListElement(*node) || isHTMLDListElement(*node)))))
return AXList::create(renderer);
// aria tables
@@ -334,7 +338,7 @@ AXObject* AXObjectCache::getOrCreate(Widget* widget)
if (AXObject* obj = get(widget))
return obj;
- RefPtr<AXObject> newObj = 0;
+ RefPtr<AXObject> newObj = nullptr;
if (widget->isFrameView())
newObj = AXScrollView::create(toScrollView(widget));
else if (widget->isScrollbar())
@@ -343,6 +347,11 @@ AXObject* AXObjectCache::getOrCreate(Widget* widget)
// Will crash later if we have two objects for the same widget.
ASSERT(!get(widget));
+ // Catch the case if an (unsupported) widget type is used. Only FrameView and ScrollBar are supported now.
+ ASSERT(newObj);
+ if (!newObj)
+ return 0;
+
getAXID(newObj.get());
m_widgetObjectMapping.set(widget, newObj->axObjectID());
@@ -442,12 +451,12 @@ AXObject* AXObjectCache::rootObject()
if (!gAccessibilityEnabled)
return 0;
- return getOrCreate(m_document->view());
+ return getOrCreate(m_document.view());
}
AXObject* AXObjectCache::getOrCreate(AccessibilityRole role)
{
- RefPtr<AXObject> obj = 0;
+ RefPtr<AXObject> obj = nullptr;
// will be filled in...
switch (role) {
@@ -479,7 +488,7 @@ AXObject* AXObjectCache::getOrCreate(AccessibilityRole role)
obj = AXSpinButtonPart::create();
break;
default:
- obj = 0;
+ obj = nullptr;
}
if (obj)
@@ -562,6 +571,18 @@ void AXObjectCache::remove(AbstractInlineTextBox* inlineTextBox)
m_inlineTextBoxObjectMapping.remove(inlineTextBox);
}
+// FIXME: Oilpan: Use a weak hashmap for this instead.
+void AXObjectCache::clearWeakMembers(Visitor* visitor)
+{
+ Vector<Node*> deadNodes;
+ for (HashMap<Node*, AXID>::iterator it = m_nodeObjectMapping.begin(); it != m_nodeObjectMapping.end(); ++it) {
+ if (!visitor->isAlive(it->key))
+ deadNodes.append(it->key);
+ }
+ for (unsigned i = 0; i < deadNodes.size(); ++i)
+ remove(deadNodes[i]);
+}
+
AXID AXObjectCache::platformGenerateAXID() const
{
static AXID lastUsedID = 0;
@@ -670,7 +691,7 @@ void AXObjectCache::childrenChanged(AXObject* obj)
void AXObjectCache::notificationPostTimerFired(Timer<AXObjectCache>*)
{
- RefPtr<Document> protectorForCacheOwner(m_document);
+ RefPtrWillBeRawPtr<Document> protectorForCacheOwner(m_document);
m_notificationPostTimer.stop();
@@ -754,7 +775,7 @@ void AXObjectCache::postNotification(AXObject* object, Document* document, AXNot
object = object->observableObject();
if (!object && document)
- object = get(document->renderer());
+ object = get(document->renderView());
if (!object)
return;
@@ -762,7 +783,7 @@ void AXObjectCache::postNotification(AXObject* object, Document* document, AXNot
if (postType == PostAsynchronously) {
m_notificationsToPost.append(std::make_pair(object, notification));
if (!m_notificationPostTimer.isActive())
- m_notificationPostTimer.startOneShot(0);
+ m_notificationPostTimer.startOneShot(0, FROM_HERE);
} else {
postPlatformNotification(object, notification);
}
@@ -799,6 +820,20 @@ void AXObjectCache::handleScrollbarUpdate(ScrollView* view)
}
}
+void AXObjectCache::handleLayoutComplete(RenderObject* renderer)
+{
+ if (!renderer)
+ return;
+
+ m_computedObjectAttributeCache->clear();
+
+ // Create the AXObject if it didn't yet exist - that's always safe at the end of a layout, and it
+ // allows an AX notification to be sent when a page has its first layout, rather than when the
+ // document first loads.
+ if (AXObject* obj = getOrCreate(renderer))
+ postNotification(obj, obj->document(), AXLayoutComplete, true);
+}
+
void AXObjectCache::handleAriaExpandedChange(Node* node)
{
if (AXObject* obj = getOrCreate(node))
@@ -826,7 +861,7 @@ void AXObjectCache::handleAttributeChanged(const QualifiedName& attrName, Elemen
handleAriaRoleChanged(element);
else if (attrName == altAttr || attrName == titleAttr)
textChanged(element);
- else if (attrName == forAttr && isHTMLLabelElement(element))
+ else if (attrName == forAttr && isHTMLLabelElement(*element))
labelChanged(element);
if (!attrName.localName().string().startsWith("aria-"))
@@ -863,71 +898,19 @@ void AXObjectCache::recomputeIsIgnored(RenderObject* renderer)
obj->notifyIfIgnoredValueChanged();
}
-void AXObjectCache::startCachingComputedObjectAttributesUntilTreeMutates()
-{
- // FIXME: no longer needed. When Chromium no longer calls
- // WebAXObject::startCachingComputedObjectAttributesUntilTreeMutates,
- // delete this function and the WebAXObject interfaces.
-}
-
-void AXObjectCache::stopCachingComputedObjectAttributes()
-{
- // FIXME: no longer needed (see above).
-}
-
-VisiblePosition AXObjectCache::visiblePositionForTextMarkerData(TextMarkerData& textMarkerData)
-{
- if (!isNodeInUse(textMarkerData.node))
- return VisiblePosition();
-
- // FIXME: Accessability should make it clear these are DOM-compliant offsets or store Position objects.
- VisiblePosition visiblePos = VisiblePosition(createLegacyEditingPosition(textMarkerData.node, textMarkerData.offset), textMarkerData.affinity);
- Position deepPos = visiblePos.deepEquivalent();
- if (deepPos.isNull())
- return VisiblePosition();
-
- RenderObject* renderer = deepPos.deprecatedNode()->renderer();
- if (!renderer)
- return VisiblePosition();
-
- AXObjectCache* cache = renderer->document().axObjectCache();
- if (!cache->isIDinUse(textMarkerData.axID))
- return VisiblePosition();
-
- if (deepPos.deprecatedNode() != textMarkerData.node || deepPos.deprecatedEditingOffset() != textMarkerData.offset)
- return VisiblePosition();
-
- return visiblePos;
-}
-
-void AXObjectCache::textMarkerDataForVisiblePosition(TextMarkerData& textMarkerData, const VisiblePosition& visiblePos)
+void AXObjectCache::inlineTextBoxesUpdated(RenderObject* renderer)
{
- // This memory must be bzero'd so instances of TextMarkerData can be tested for byte-equivalence.
- // This also allows callers to check for failure by looking at textMarkerData upon return.
- memset(&textMarkerData, 0, sizeof(TextMarkerData));
-
- if (visiblePos.isNull())
+ if (!gInlineTextBoxAccessibility)
return;
- Position deepPos = visiblePos.deepEquivalent();
- Node* domNode = deepPos.deprecatedNode();
- ASSERT(domNode);
- if (!domNode)
- return;
-
- if (domNode->hasTagName(inputTag) && toHTMLInputElement(domNode)->isPasswordField())
- return;
-
- // find or create an accessibility object for this node
- AXObjectCache* cache = domNode->document().axObjectCache();
- RefPtr<AXObject> obj = cache->getOrCreate(domNode);
-
- textMarkerData.axID = obj.get()->axObjectID();
- textMarkerData.node = domNode;
- textMarkerData.offset = deepPos.deprecatedEditingOffset();
- textMarkerData.affinity = visiblePos.affinity();
-
- cache->setNodeInUse(domNode);
+ // Only update if the accessibility object already exists and it's
+ // not already marked as dirty.
+ if (AXObject* obj = get(renderer)) {
+ if (!obj->needsToUpdateChildren()) {
+ obj->setNeedsToUpdateChildren();
+ postNotification(renderer, AXChildrenChanged, true);
+ }
+ }
}
const Element* AXObjectCache::rootAXEditableElement(const Node* node)
@@ -983,7 +966,7 @@ void AXObjectCache::postPlatformNotification(AXObject* obj, AXNotification notif
Document* document = toFrameView(scrollBar->parent())->frame().document();
if (document != document->topDocument())
return;
- obj = get(document->renderer());
+ obj = get(document->renderView());
}
if (!obj || !obj->document() || !obj->documentFrameView() || !obj->documentFrameView()->frame().page())
@@ -1025,4 +1008,14 @@ void AXObjectCache::handleScrolledToAnchor(const Node* anchorNode)
postPlatformNotification(AXObject::firstAccessibleObjectFromNode(anchorNode), AXScrolledToAnchor);
}
+void AXObjectCache::handleScrollPositionChanged(ScrollView* scrollView)
+{
+ postPlatformNotification(getOrCreate(scrollView), AXScrollPositionChanged);
+}
+
+void AXObjectCache::handleScrollPositionChanged(RenderObject* renderObject)
+{
+ postPlatformNotification(getOrCreate(renderObject), AXScrollPositionChanged);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.h b/chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.h
index 11df342365f..7784da5c5ba 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXObjectCache.h
@@ -79,7 +79,7 @@ enum PostType { PostSynchronously, PostAsynchronously };
class AXObjectCache {
WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED;
public:
- explicit AXObjectCache(const Document*);
+ explicit AXObjectCache(Document&);
~AXObjectCache();
static AXObject* focusedUIElementForPage(const Page*);
@@ -108,6 +108,8 @@ public:
void remove(AbstractInlineTextBox*);
void remove(AXID);
+ void clearWeakMembers(Visitor*);
+
void detachWrapper(AXObject*);
void attachWrapper(AXObject*);
void childrenChanged(Node*);
@@ -128,11 +130,21 @@ public:
void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
void handleScrolledToAnchor(const Node* anchorNode);
void handleAriaExpandedChange(Node*);
+
+ // Called when scroll bars are added / removed (as the view resizes).
void handleScrollbarUpdate(ScrollView*);
+ void handleLayoutComplete(RenderObject*);
+
+ // Called when the scroll offset changes.
+ void handleScrollPositionChanged(ScrollView*);
+ void handleScrollPositionChanged(RenderObject*);
+
void handleAttributeChanged(const QualifiedName& attrName, Element*);
void recomputeIsIgnored(RenderObject* renderer);
+ void inlineTextBoxesUpdated(RenderObject* renderer);
+
static void enableAccessibility() { gAccessibilityEnabled = true; }
static bool accessibilityEnabled() { return gAccessibilityEnabled; }
static void setInlineTextBoxAccessibility(bool flag) { gInlineTextBoxAccessibility = flag; }
@@ -148,10 +160,6 @@ public:
AXID platformGenerateAXID() const;
AXObject* objectFromAXID(AXID id) const { return m_objects.get(id); }
- // Text marker utilities.
- void textMarkerDataForVisiblePosition(TextMarkerData&, const VisiblePosition&);
- VisiblePosition visiblePositionForTextMarkerData(TextMarkerData&);
-
enum AXNotification {
AXActiveDescendantChanged,
AXAlert,
@@ -172,6 +180,7 @@ public:
AXRowCollapsed,
AXRowCountChanged,
AXRowExpanded,
+ AXScrollPositionChanged,
AXScrolledToAnchor,
AXSelectedChildrenChanged,
AXSelectedTextChanged,
@@ -188,9 +197,6 @@ public:
bool nodeHasRole(Node*, const AtomicString& role);
- void startCachingComputedObjectAttributesUntilTreeMutates();
- void stopCachingComputedObjectAttributes();
-
AXComputedObjectAttributeCache* computedObjectAttributeCache() { return m_computedObjectAttributeCache.get(); }
protected:
@@ -204,7 +210,7 @@ protected:
bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
private:
- Document* m_document;
+ Document& m_document;
HashMap<AXID, RefPtr<AXObject> > m_objects;
HashMap<RenderObject*, AXID> m_renderObjectMapping;
HashMap<Widget*, AXID> m_widgetObjectMapping;
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXProgressIndicator.h b/chromium/third_party/WebKit/Source/core/accessibility/AXProgressIndicator.h
index 13ea890b43b..1d4dc78a39a 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXProgressIndicator.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXProgressIndicator.h
@@ -28,12 +28,12 @@ namespace WebCore {
class HTMLProgressElement;
class RenderProgress;
-class AXProgressIndicator : public AXRenderObject {
+class AXProgressIndicator FINAL : public AXRenderObject {
public:
static PassRefPtr<AXProgressIndicator> create(RenderProgress*);
private:
- virtual AccessibilityRole roleValue() const { return ProgressIndicatorRole; }
+ virtual AccessibilityRole roleValue() const OVERRIDE { return ProgressIndicatorRole; }
virtual bool isProgressIndicator() const OVERRIDE { return true; }
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.cpp
index 595135959b6..41a7288f69c 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.cpp
@@ -43,8 +43,7 @@
#include "core/editing/TextIterator.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
-#include "core/html/HTMLHtmlElement.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLOptionElement.h"
@@ -66,27 +65,26 @@
#include "core/rendering/RenderTextFragment.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/RenderWidget.h"
-#include "core/svg/SVGDocument.h"
+#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGSVGElement.h"
#include "core/svg/graphics/SVGImage.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/StdLibExtras.h"
using blink::WebLocalizedString;
-using namespace std;
namespace WebCore {
using namespace HTMLNames;
-static inline RenderObject* firstChildInContinuation(RenderObject* renderer)
+static inline RenderObject* firstChildInContinuation(const RenderInline& renderer)
{
- RenderObject* r = toRenderInline(renderer)->continuation();
+ RenderBoxModelObject* r = renderer.continuation();
while (r) {
if (r->isRenderBlock())
return r;
- if (RenderObject* child = r->firstChild())
+ if (RenderObject* child = r->slowFirstChild())
return child;
r = toRenderInline(r)->continuation();
}
@@ -108,10 +106,10 @@ static inline bool isInlineWithContinuation(RenderObject* object)
static inline RenderObject* firstChildConsideringContinuation(RenderObject* renderer)
{
- RenderObject* firstChild = renderer->firstChild();
+ RenderObject* firstChild = renderer->slowFirstChild();
if (!firstChild && isInlineWithContinuation(renderer))
- firstChild = firstChildInContinuation(renderer);
+ firstChild = firstChildInContinuation(toRenderInline(*renderer));
return firstChild;
}
@@ -152,7 +150,8 @@ static inline RenderObject* endOfContinuations(RenderObject* renderer)
static inline bool lastChildHasContinuation(RenderObject* renderer)
{
- return renderer->lastChild() && isInlineWithContinuation(renderer->lastChild());
+ RenderObject* lastChild = renderer->slowLastChild();
+ return lastChild && isInlineWithContinuation(lastChild);
}
static RenderBoxModelObject* nextContinuation(RenderObject* renderer)
@@ -219,20 +218,11 @@ RenderBoxModelObject* AXRenderObject::renderBoxModelObject() const
return toRenderBoxModelObject(m_renderer);
}
-RenderView* AXRenderObject::topRenderer() const
-{
- Document* topDoc = topDocument();
- if (!topDoc)
- return 0;
-
- return topDoc->renderView();
-}
-
Document* AXRenderObject::topDocument() const
{
if (!document())
return 0;
- return document()->topDocument();
+ return &document()->topDocument();
}
bool AXRenderObject::shouldNotifyActiveDescendant() const
@@ -284,14 +274,14 @@ AccessibilityRole AXRenderObject::determineAccessibilityRole()
return ListItemRole;
if (m_renderer->isListMarker())
return ListMarkerRole;
- if (node && node->hasTagName(buttonTag))
+ if (isHTMLButtonElement(node))
return buttonRoleType();
- if (node && node->hasTagName(legendTag))
+ if (isHTMLLegendElement(node))
return LegendRole;
if (m_renderer->isText())
return StaticTextRole;
if (cssBox && cssBox->isImage()) {
- if (node && node->hasTagName(inputTag))
+ if (isHTMLInputElement(node))
return ariaHasPopup() ? PopUpButtonRole : ButtonRole;
if (isSVGImage())
return SVGRootRole;
@@ -299,15 +289,11 @@ AccessibilityRole AXRenderObject::determineAccessibilityRole()
}
// Note: if JavaScript is disabled, the renderer won't be a RenderHTMLCanvas.
- if (node && node->hasTagName(canvasTag) && m_renderer->isCanvas())
+ if (isHTMLCanvasElement(node) && m_renderer->isCanvas())
return CanvasRole;
- if (cssBox && cssBox->isRenderView()) {
- // If the iframe is seamless, it should not be announced as a web area to AT clients.
- if (document() && document()->shouldDisplaySeamlesslyWithParent())
- return SeamlessWebAreaRole;
+ if (cssBox && cssBox->isRenderView())
return WebAreaRole;
- }
if (cssBox && cssBox->isTextField())
return TextFieldRole;
@@ -315,16 +301,16 @@ AccessibilityRole AXRenderObject::determineAccessibilityRole()
if (cssBox && cssBox->isTextArea())
return TextAreaRole;
- if (node && node->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(node);
- if (input->isCheckbox())
+ if (isHTMLInputElement(node)) {
+ HTMLInputElement& input = toHTMLInputElement(*node);
+ if (input.isCheckbox())
return CheckBoxRole;
- if (input->isRadioButton())
+ if (input.isRadioButton())
return RadioButtonRole;
- if (input->isTextButton())
+ if (input.isTextButton())
return buttonRoleType();
- const AtomicString& type = input->getAttribute(typeAttr);
+ const AtomicString& type = input.getAttribute(typeAttr);
if (equalIgnoringCase(type, "color"))
return ColorWellRole;
}
@@ -359,16 +345,16 @@ AccessibilityRole AXRenderObject::determineAccessibilityRole()
if (m_renderer->isHR())
return HorizontalRuleRole;
- if (node && node->hasTagName(pTag))
+ if (isHTMLParagraphElement(node))
return ParagraphRole;
- if (node && isHTMLLabelElement(node))
+ if (isHTMLLabelElement(node))
return LabelRole;
- if (node && node->hasTagName(divTag))
+ if (isHTMLDivElement(node))
return DivRole;
- if (node && node->hasTagName(formTag))
+ if (isHTMLFormElement(node))
return FormRole;
if (node && node->hasTagName(articleTag))
@@ -393,9 +379,15 @@ AccessibilityRole AXRenderObject::determineAccessibilityRole()
return DialogRole;
// The HTML element should not be exposed as an element. That's what the RenderView element does.
- if (node && isHTMLHtmlElement(node))
+ if (isHTMLHtmlElement(node))
return IgnoredRole;
+ if (node && node->hasTagName(iframeTag))
+ return IframeRole;
+
+ if (isEmbeddedObject())
+ return EmbeddedObjectRole;
+
// There should only be one banner/contentInfo per page. If header/footer are being used within an article or section
// then it should not be exposed as whole page's banner/contentInfo
if (node && node->hasTagName(headerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag))
@@ -403,7 +395,7 @@ AccessibilityRole AXRenderObject::determineAccessibilityRole()
if (node && node->hasTagName(footerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag))
return FooterRole;
- if (node && node->hasTagName(aTag) && isClickable())
+ if (isHTMLAnchorElement(node) && isClickable())
return LinkRole;
if (m_renderer->isRenderBlockFlow())
@@ -451,9 +443,9 @@ bool AXRenderObject::isAttachment() const
bool AXRenderObject::isFileUploadButton() const
{
- if (m_renderer && m_renderer->node() && m_renderer->node()->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(m_renderer->node());
- return input->isFileUpload();
+ if (m_renderer && isHTMLInputElement(m_renderer->node())) {
+ HTMLInputElement& input = toHTMLInputElement(*m_renderer->node());
+ return input.isFileUpload();
}
return false;
@@ -475,10 +467,10 @@ bool AXRenderObject::isLinked() const
return false;
Element* anchor = anchorElement();
- if (!anchor || !isHTMLAnchorElement(anchor))
+ if (!isHTMLAnchorElement(anchor))
return false;
- return !toHTMLAnchorElement(anchor)->href().isEmpty();
+ return !toHTMLAnchorElement(*anchor).href().isEmpty();
}
bool AXRenderObject::isLoaded() const
@@ -638,19 +630,23 @@ bool AXRenderObject::computeAccessibilityIsIgnored() const
if (m_renderer->isBR() || !renderText->firstTextBox())
return true;
- // static text beneath TextControls is reported along with the text control text so it's ignored.
+ // Don't ignore static text in editable text controls.
for (AXObject* parent = parentObject(); parent; parent = parent->parentObject()) {
- if (parent->roleValue() == TextFieldRole)
- return true;
+ if (parent->roleValue() == TextFieldRole || parent->roleValue() == TextAreaRole)
+ return false;
}
// text elements that are just empty whitespace should not be returned
+ // FIXME(dmazzoni): we probably shouldn't ignore this if the style is 'pre', or similar...
return renderText->text().impl()->containsOnlyWhitespace();
}
if (isHeading())
return false;
+ if (isLandmarkRelated())
+ return false;
+
if (isLink())
return false;
@@ -663,7 +659,7 @@ bool AXRenderObject::computeAccessibilityIsIgnored() const
// don't ignore labels, because they serve as TitleUIElements
Node* node = m_renderer->node();
- if (node && isHTMLLabelElement(node))
+ if (isHTMLLabelElement(node))
return false;
// Anything that is content editable should not be ignored.
@@ -689,7 +685,7 @@ bool AXRenderObject::computeAccessibilityIsIgnored() const
// objects are often containers with meaningful information, the inclusion of a span can have
// the side effect of causing the immediate parent accessible to be ignored. This is especially
// problematic for platforms which have distinct roles for textual block elements.
- if (node && node->hasTagName(spanTag))
+ if (isHTMLSpanElement(node))
return true;
if (m_renderer->isRenderBlockFlow() && m_renderer->childrenInline() && !canSetFocusAttribute())
@@ -737,7 +733,7 @@ bool AXRenderObject::computeAccessibilityIsIgnored() const
// Otherwise fall through; use presence of help text, title, or description to decide.
}
- if (isWebArea() || isSeamlessWebArea() || m_renderer->isListMarker())
+ if (isWebArea() || m_renderer->isListMarker())
return false;
// Using the help text, title or accessibility description (so we
@@ -799,7 +795,8 @@ String AXRenderObject::text() const
int AXRenderObject::textLength() const
{
- ASSERT(isTextControl());
+ if (!isTextControl())
+ return -1;
if (isPasswordField())
return -1; // need to return something distinct from 0
@@ -817,8 +814,8 @@ KURL AXRenderObject::url() const
if (isWebArea())
return m_renderer->document().url();
- if (isImage() && m_renderer->node() && m_renderer->node()->hasTagName(imgTag))
- return toHTMLImageElement(m_renderer->node())->src();
+ if (isImage() && isHTMLImageElement(m_renderer->node()))
+ return toHTMLImageElement(*m_renderer->node()).src();
if (isInputImage())
return toHTMLInputElement(m_renderer->node())->src();
@@ -855,18 +852,6 @@ String AXRenderObject::actionVerb() const
}
}
-void AXRenderObject::selectedChildren(AccessibilityChildrenVector& result)
-{
- ASSERT(result.isEmpty());
-
- // only listboxes should be asked for their selected children.
- AccessibilityRole role = roleValue();
- if (role == ListBoxRole) // native list boxes would be AXListBoxes, so only check for aria list boxes
- ariaListboxSelectedChildren(result);
- else if (role == TreeRole || role == TreeGridRole || role == TableRole)
- ariaSelectedRows(result);
-}
-
String AXRenderObject::stringValue() const
{
if (!m_renderer)
@@ -892,7 +877,7 @@ String AXRenderObject::stringValue() const
// This has to be overridden in the case where the selected item has an ARIA label.
HTMLSelectElement* selectElement = toHTMLSelectElement(m_renderer->node());
int selectedIndex = selectElement->selectedIndex();
- const Vector<HTMLElement*> listItems = selectElement->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement->listItems();
if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {
const AtomicString& overriddenDescription = listItems[selectedIndex]->fastGetAttribute(aria_labelAttr);
if (!overriddenDescription.isNull())
@@ -936,7 +921,10 @@ AXObject* AXRenderObject::activeDescendant() const
if (m_renderer->node() && !m_renderer->node()->isElementNode())
return 0;
+
Element* element = toElement(m_renderer->node());
+ if (!element)
+ return 0;
const AtomicString& activeDescendantAttrStr = element->getAttribute(aria_activedescendantAttr);
if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
@@ -955,21 +943,46 @@ AXObject* AXRenderObject::activeDescendant() const
return 0;
}
-void AXRenderObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) const
+void AXRenderObject::accessibilityChildrenFromAttribute(QualifiedName attr, AccessibilityChildrenVector& children) const
{
Vector<Element*> elements;
- elementsFromAttribute(elements, aria_flowtoAttr);
+ elementsFromAttribute(elements, attr);
AXObjectCache* cache = axObjectCache();
unsigned count = elements.size();
for (unsigned k = 0; k < count; ++k) {
Element* element = elements[k];
- AXObject* flowToElement = cache->getOrCreate(element);
- if (flowToElement)
- flowTo.append(flowToElement);
+ AXObject* child = cache->getOrCreate(element);
+ if (child)
+ children.append(child);
}
}
+void AXRenderObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) const
+{
+ accessibilityChildrenFromAttribute(aria_flowtoAttr, flowTo);
+}
+
+void AXRenderObject::ariaControlsElements(AccessibilityChildrenVector& controls) const
+{
+ accessibilityChildrenFromAttribute(aria_controlsAttr, controls);
+}
+
+void AXRenderObject::ariaDescribedbyElements(AccessibilityChildrenVector& describedby) const
+{
+ accessibilityChildrenFromAttribute(aria_describedbyAttr, describedby);
+}
+
+void AXRenderObject::ariaLabelledbyElements(AccessibilityChildrenVector& labelledby) const
+{
+ accessibilityChildrenFromAttribute(aria_labelledbyAttr, labelledby);
+}
+
+void AXRenderObject::ariaOwnsElements(AccessibilityChildrenVector& owns) const
+{
+ accessibilityChildrenFromAttribute(aria_ownsAttr, owns);
+}
+
bool AXRenderObject::ariaHasPopup() const
{
return elementAttributeValue(aria_haspopupAttr);
@@ -1003,25 +1016,21 @@ bool AXRenderObject::isPresentationalChildOfAriaRole() const
bool AXRenderObject::shouldFocusActiveDescendant() const
{
switch (ariaRoleAttribute()) {
+ case ComboBoxRole:
+ case GridRole:
case GroupRole:
case ListBoxRole:
case MenuRole:
case MenuBarRole:
- case RadioGroupRole:
- case RowRole:
+ case OutlineRole:
case PopUpButtonRole:
case ProgressIndicatorRole:
+ case RadioGroupRole:
+ case RowRole:
+ case TabListRole:
case ToolbarRole:
- case OutlineRole:
case TreeRole:
- case GridRole:
- /* FIXME: replace these with actual roles when they are added to AccessibilityRole
- composite
- alert
- alertdialog
- status
- timer
- */
+ case TreeGridRole:
return true;
default:
return false;
@@ -1243,7 +1252,7 @@ IntPoint AXRenderObject::clickPoint()
if (!isWebArea() || isReadOnly())
return AXObject::clickPoint();
- LayoutRect bounds = elementRect();
+ IntRect bounds = pixelSnappedIntRect(elementRect());
return IntPoint(bounds.x() + (bounds.width() / 2), bounds.y() - (bounds.height() / 2));
}
@@ -1268,8 +1277,8 @@ AXObject* AXRenderObject::accessibilityHitTest(const IntPoint& point) const
if (isHTMLAreaElement(node))
return accessibilityImageMapHitTest(toHTMLAreaElement(node), point);
- if (node->hasTagName(optionTag))
- node = toHTMLOptionElement(node)->ownerSelectElement();
+ if (isHTMLOptionElement(node))
+ node = toHTMLOptionElement(*node).ownerSelectElement();
RenderObject* obj = node->renderer();
if (!obj)
@@ -1327,7 +1336,7 @@ AXObject* AXRenderObject::parentObject() const
return axObjectCache()->getOrCreate(parentObj);
// WebArea's parent should be the scroll view containing it.
- if (isWebArea() || isSeamlessWebArea())
+ if (isWebArea())
return axObjectCache()->getOrCreate(m_renderer->frame()->view());
return 0;
@@ -1336,7 +1345,7 @@ AXObject* AXRenderObject::parentObject() const
AXObject* AXRenderObject::parentObjectIfExists() const
{
// WebArea's parent should be the scroll view containing it.
- if (isWebArea() || isSeamlessWebArea())
+ if (isWebArea())
return axObjectCache()->get(m_renderer->frame()->view());
return axObjectCache()->get(renderParentObject());
@@ -1373,9 +1382,9 @@ AXObject* AXRenderObject::nextSibling() const
} else if (m_renderer->isAnonymousBlock() && lastChildHasContinuation(m_renderer)) {
// Case 2: Anonymous block parent of the start of a continuation - skip all the way to
// after the parent of the end, since everything in between will be linked up via the continuation.
- RenderObject* lastParent = endOfContinuations(m_renderer->lastChild())->parent();
+ RenderObject* lastParent = endOfContinuations(toRenderBlock(m_renderer)->lastChild())->parent();
while (lastChildHasContinuation(lastParent))
- lastParent = endOfContinuations(lastParent->lastChild())->parent();
+ lastParent = endOfContinuations(lastParent->slowLastChild())->parent();
nextSibling = lastParent->nextSibling();
} else if (RenderObject* ns = m_renderer->nextSibling()) {
// Case 3: node has an actual next sibling
@@ -1471,8 +1480,8 @@ double AXRenderObject::estimatedLoadingProgress() const
if (isLoaded())
return 1.0;
- if (Page* page = m_renderer->document().page())
- return page->progress().estimatedProgress();
+ if (LocalFrame* frame = m_renderer->document().frame())
+ return frame->loader().progress().estimatedProgress();
return 0;
}
@@ -1497,7 +1506,7 @@ FrameView* AXRenderObject::documentFrameView() const
if (!m_renderer)
return 0;
- // this is the RenderObject's Document's Frame's FrameView
+ // this is the RenderObject's Document's LocalFrame's FrameView
return m_renderer->document().view();
}
@@ -1526,7 +1535,7 @@ Element* AXRenderObject::anchorElement() const
// NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
Node* node = currRenderer->node();
for ( ; node; node = node->parentNode()) {
- if (isHTMLAnchorElement(node) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
+ if (isHTMLAnchorElement(*node) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
return toElement(node);
}
@@ -1546,7 +1555,8 @@ Widget* AXRenderObject::widgetForAttachmentView() const
AXObject::PlainTextRange AXRenderObject::selectedTextRange() const
{
- ASSERT(isTextControl());
+ if (!isTextControl())
+ return PlainTextRange();
if (isPasswordField())
return PlainTextRange();
@@ -1568,24 +1578,6 @@ VisibleSelection AXRenderObject::selection() const
return m_renderer->frame()->selection().selection();
}
-String AXRenderObject::selectedText() const
-{
- ASSERT(isTextControl());
-
- if (isPasswordField())
- return String(); // need to return something distinct from empty string
-
- if (isNativeTextControl() && m_renderer->isTextControl()) {
- HTMLTextFormControlElement* textControl = toRenderTextControl(m_renderer)->textFormControlElement();
- return textControl->selectedText();
- }
-
- if (ariaRoleAttribute() == UnknownRole)
- return String();
-
- return stringForRange(ariaSelectedTextRange());
-}
-
//
// Modify or take an action on an object.
//
@@ -1599,7 +1591,7 @@ void AXRenderObject::setSelectedTextRange(const PlainTextRange& range)
}
Document& document = m_renderer->document();
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
if (!frame)
return;
Node* node = m_renderer->node();
@@ -1615,11 +1607,10 @@ void AXRenderObject::setValue(const String& string)
return;
RenderBoxModelObject* renderer = toRenderBoxModelObject(m_renderer);
- if (renderer->isTextField() && node()->hasTagName(inputTag)) {
- toHTMLInputElement(node())->setValue(string);
- } else if (renderer->isTextArea() && node()->hasTagName(textareaTag)) {
- toHTMLTextAreaElement(node())->setValue(string);
- }
+ if (renderer->isTextField() && isHTMLInputElement(*node()))
+ toHTMLInputElement(*node()).setValue(string);
+ else if (renderer->isTextArea() && isHTMLTextAreaElement(*node()))
+ toHTMLTextAreaElement(*node()).setValue(string);
}
// FIXME: This function should use an IntSize to avoid the conversion below.
@@ -1734,7 +1725,7 @@ VisiblePosition AXRenderObject::visiblePositionForIndex(int index) const
if (index <= 0)
return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
- RefPtr<Range> range = Range::create(m_renderer->document());
+ RefPtrWillBeRawPtr<Range> range = Range::create(m_renderer->document());
range->selectNodeContents(node, IGNORE_EXCEPTION);
CharacterIterator it(range.get());
it.advance(index - 1);
@@ -1760,7 +1751,7 @@ int AXRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const
if (indexPosition.isNull() || highestEditableRoot(indexPosition, HasEditableAXRole) != node)
return 0;
- RefPtr<Range> range = Range::create(m_renderer->document());
+ RefPtrWillBeRawPtr<Range> range = Range::create(m_renderer->document());
range->setStart(node, 0, IGNORE_EXCEPTION);
range->setEnd(indexPosition, IGNORE_EXCEPTION);
@@ -1775,10 +1766,14 @@ void AXRenderObject::addInlineTextBoxChildren()
if (!renderer() || !renderer()->isText())
return;
- RenderText* renderText = toRenderText(renderer());
- if (renderText->needsLayout())
- renderText->document().updateLayoutIgnorePendingStylesheets();
+ if (renderer()->needsLayout()) {
+ // If a RenderText needs layout, its inline text boxes are either
+ // nonexistent or invalid, so defer until the layout happens and
+ // the renderer calls AXObjectCache::inlineTextBoxesUpdated.
+ return;
+ }
+ RenderText* renderText = toRenderText(renderer());
for (RefPtr<AbstractInlineTextBox> box = renderText->firstAbstractInlineTextBox(); box.get(); box = box->nextInlineTextBox()) {
AXObject* axObject = axObjectCache()->getOrCreate(box.get());
if (!axObject->accessibilityIsIgnored())
@@ -1801,23 +1796,6 @@ void AXRenderObject::lineBreaks(Vector<int>& lineBreaks) const
}
}
-// A substring of the text associated with this accessibility object that is
-// specified by the given character range.
-String AXRenderObject::stringForRange(const PlainTextRange& range) const
-{
- if (!range.length)
- return String();
-
- if (!isTextControl())
- return String();
-
- String elementText = isPasswordField() ? String() : text();
- if (range.start + range.length > elementText.length())
- return String();
-
- return elementText.substring(range.start, range.length);
-}
-
//
// Private.
//
@@ -1868,12 +1846,12 @@ AXObject::PlainTextRange AXRenderObject::ariaSelectedTextRange() const
return PlainTextRange();
VisibleSelection visibleSelection = selection();
- RefPtr<Range> currentSelectionRange = visibleSelection.toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> currentSelectionRange = visibleSelection.toNormalizedRange();
if (!currentSelectionRange || !currentSelectionRange->intersectsNode(node, IGNORE_EXCEPTION))
return PlainTextRange();
- int start = indexForVisiblePosition(visibleSelection.start());
- int end = indexForVisiblePosition(visibleSelection.end());
+ int start = indexForVisiblePosition(visibleSelection.visibleStart());
+ int end = indexForVisiblePosition(visibleSelection.visibleEnd());
return PlainTextRange(start, end - start);
}
@@ -1930,35 +1908,6 @@ bool AXRenderObject::isTabItemSelected() const
return false;
}
-AXObject* AXRenderObject::internalLinkElement() const
-{
- Element* element = anchorElement();
- if (!element)
- return 0;
-
- // Right now, we do not support ARIA links as internal link elements
- if (!isHTMLAnchorElement(element))
- return 0;
- HTMLAnchorElement* anchor = toHTMLAnchorElement(element);
-
- KURL linkURL = anchor->href();
- String fragmentIdentifier = linkURL.fragmentIdentifier();
- if (fragmentIdentifier.isEmpty())
- return 0;
-
- // check if URL is the same as current URL
- KURL documentURL = m_renderer->document().url();
- if (!equalIgnoringFragmentIdentifier(documentURL, linkURL))
- return 0;
-
- Node* linkedNode = m_renderer->document().findAnchor(fragmentIdentifier);
- if (!linkedNode)
- return 0;
-
- // The element we find may not be accessible, so find the first accessible object.
- return firstAccessibleObjectFromNode(linkedNode);
-}
-
AXObject* AXRenderObject::accessibilityImageMapHitTest(HTMLAreaElement* area, const IntPoint& point) const
{
if (!area)
@@ -2013,7 +1962,7 @@ RenderObject* AXRenderObject::renderParentObject() const
// Case 2: node's parent is an inline which is some node's continuation; parent is
// the earliest node in the continuation chain.
parent = startOfConts;
- } else if (parent && (firstChild = parent->firstChild()) && firstChild->node()) {
+ } else if (parent && (firstChild = parent->slowFirstChild()) && firstChild->node()) {
// Case 3: The first sibling is the beginning of a continuation chain. Find the origin of that continuation.
// Get the node's renderer and follow that continuation chain until the first child is found.
RenderObject* nodeRenderFirstChild = firstChild->node()->renderer();
@@ -2024,9 +1973,10 @@ RenderObject* AXRenderObject::renderParentObject() const
break;
}
}
- if (firstChild == parent->firstChild())
+ RenderObject* newFirstChild = parent->slowFirstChild();
+ if (firstChild == newFirstChild)
break;
- firstChild = parent->firstChild();
+ firstChild = newFirstChild;
if (!firstChild->node())
break;
nodeRenderFirstChild = firstChild->node()->renderer();
@@ -2076,7 +2026,7 @@ AXSVGRoot* AXRenderObject::remoteSVGRootElement() const
if (!doc || !doc->isSVGDocument())
return 0;
- SVGSVGElement* rootElement = toSVGDocument(doc)->rootElement();
+ SVGSVGElement* rootElement = doc->accessSVGExtensions().rootElement();
if (!rootElement)
return 0;
RenderObject* rendererRoot = rootElement->renderer();
@@ -2172,11 +2122,11 @@ void AXRenderObject::addHiddenChildren()
void AXRenderObject::addTextFieldChildren()
{
Node* node = this->node();
- if (!node || !node->hasTagName(inputTag))
+ if (!isHTMLInputElement(node))
return;
- HTMLInputElement* input = toHTMLInputElement(node);
- Element* spinButtonElement = input->userAgentShadowRoot()->getElementById(ShadowElementNames::spinButton());
+ HTMLInputElement& input = toHTMLInputElement(*node);
+ Element* spinButtonElement = input.userAgentShadowRoot()->getElementById(ShadowElementNames::spinButton());
if (!spinButtonElement || !spinButtonElement->isSpinButtonElement())
return;
@@ -2196,11 +2146,11 @@ void AXRenderObject::addImageMapChildren()
if (!map)
return;
- for (Element* current = ElementTraversal::firstWithin(*map); current; current = ElementTraversal::next(*current, map)) {
+ for (HTMLAreaElement* area = Traversal<HTMLAreaElement>::firstWithin(*map); area; area = Traversal<HTMLAreaElement>::next(*area, map)) {
// add an <area> element for this child if it has a link
- if (isHTMLAreaElement(current) && current->isLink()) {
+ if (area->isLink()) {
AXImageMapLink* areaObject = toAXImageMapLink(axObjectCache()->getOrCreate(ImageMapLinkRole));
- areaObject->setHTMLAreaElement(toHTMLAreaElement(current));
+ areaObject->setHTMLAreaElement(area);
areaObject->setHTMLMapElement(map);
areaObject->setParent(this);
if (!areaObject->accessibilityIsIgnored())
@@ -2213,7 +2163,7 @@ void AXRenderObject::addImageMapChildren()
void AXRenderObject::addCanvasChildren()
{
- if (!node() || !node()->hasTagName(canvasTag))
+ if (!isHTMLCanvasElement(node()))
return;
// If it's a canvas, it won't have rendered children, but it might have accessible fallback content.
@@ -2338,7 +2288,7 @@ LayoutRect AXRenderObject::computeElementRect() const
if (obj->isText())
toRenderText(obj)->absoluteQuads(quads, 0, RenderText::ClipToEllipsis);
- else if (isWebArea() || isSeamlessWebArea() || obj->isSVGRoot())
+ else if (isWebArea() || obj->isSVGRoot())
obj->absoluteQuads(quads);
else
obj->absoluteFocusRingQuads(quads);
@@ -2350,7 +2300,7 @@ LayoutRect AXRenderObject::computeElementRect() const
offsetBoundingBoxForRemoteSVGElement(result);
// The size of the web area should be the content size, not the clipped size.
- if ((isWebArea() || isSeamlessWebArea()) && obj->frame()->view())
+ if (isWebArea() && obj->frame()->view())
result.setSize(obj->frame()->view()->contentsSize());
// Checkboxes and radio buttons include their label as part of their rect.
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.h b/chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.h
index 160d0d7db3a..10ae64601d3 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXRenderObject.h
@@ -38,7 +38,7 @@ namespace WebCore {
class AXSVGRoot;
class AXObjectCache;
class Element;
-class Frame;
+class LocalFrame;
class FrameView;
class HitTestResult;
class HTMLAnchorElement;
@@ -64,16 +64,14 @@ public:
virtual ~AXRenderObject();
// Public, overridden from AXObject.
- virtual RenderObject* renderer() const OVERRIDE { return m_renderer; }
+ virtual RenderObject* renderer() const OVERRIDE FINAL { return m_renderer; }
virtual LayoutRect elementRect() const OVERRIDE;
void setRenderer(RenderObject*);
RenderBoxModelObject* renderBoxModelObject() const;
- RenderView* topRenderer() const;
Document* topDocument() const;
bool shouldNotifyActiveDescendant() const;
- bool needsToUpdateChildren() const { return m_childrenDirty; }
- ScrollableArea* getScrollableAreaIfScrollable() const;
+ virtual ScrollableArea* getScrollableAreaIfScrollable() const OVERRIDE FINAL;
virtual AccessibilityRole determineAccessibilityRole() OVERRIDE;
void checkCachedElementRect() const;
void updateCachedElementRect() const;
@@ -120,12 +118,16 @@ protected:
// Properties of interactive elements.
virtual String actionVerb() const OVERRIDE;
- virtual void selectedChildren(AccessibilityChildrenVector&) OVERRIDE;
virtual String stringValue() const OVERRIDE;
// ARIA attributes.
virtual AXObject* activeDescendant() const OVERRIDE;
virtual void ariaFlowToElements(AccessibilityChildrenVector&) const OVERRIDE;
+ virtual void ariaControlsElements(AccessibilityChildrenVector&) const OVERRIDE;
+ virtual void ariaDescribedbyElements(AccessibilityChildrenVector&) const OVERRIDE;
+ virtual void ariaLabelledbyElements(AccessibilityChildrenVector&) const OVERRIDE;
+ virtual void ariaOwnsElements(AccessibilityChildrenVector&) const OVERRIDE;
+
virtual bool ariaHasPopup() const OVERRIDE;
virtual bool ariaRoleHasPresentationalChildren() const OVERRIDE;
virtual bool isPresentationalChildOfAriaRole() const OVERRIDE;
@@ -165,6 +167,7 @@ protected:
virtual void addChildren() OVERRIDE;
virtual bool canHaveChildren() const OVERRIDE;
virtual void updateChildrenIfNecessary() OVERRIDE;
+ virtual bool needsToUpdateChildren() const { return m_childrenDirty; }
virtual void setNeedsToUpdateChildren() OVERRIDE { m_childrenDirty = true; }
virtual void clearChildren() OVERRIDE;
virtual AXObject* observableObject() const OVERRIDE;
@@ -181,7 +184,6 @@ protected:
// Selected text.
virtual PlainTextRange selectedTextRange() const OVERRIDE;
- virtual String selectedText() const OVERRIDE;
// Modify or take an action on an object.
virtual void setSelectedTextRange(const PlainTextRange&) OVERRIDE;
@@ -204,7 +206,6 @@ private:
PlainTextRange ariaSelectedTextRange() const;
bool nodeIsTextControl(const Node*) const;
bool isTabItemSelected() const;
- AXObject* internalLinkElement() const;
AXObject* accessibilityImageMapHitTest(HTMLAreaElement*, const IntPoint&) const;
bool renderObjectIsObservable(RenderObject*) const;
RenderObject* renderParentObject() const;
@@ -227,8 +228,8 @@ private:
bool inheritsPresentationalRole() const;
LayoutRect computeElementRect() const;
VisibleSelection selection() const;
- String stringForRange(const PlainTextRange&) const;
int indexForVisiblePosition(const VisiblePosition&) const;
+ void accessibilityChildrenFromAttribute(QualifiedName attr, AccessibilityChildrenVector&) const;
};
DEFINE_AX_OBJECT_TYPE_CASTS(AXRenderObject, isAXRenderObject());
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXSVGRoot.h b/chromium/third_party/WebKit/Source/core/accessibility/AXSVGRoot.h
index 4febd09f851..183cac2ed17 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXSVGRoot.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXSVGRoot.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class AXSVGRoot : public AXRenderObject {
+class AXSVGRoot FINAL : public AXRenderObject {
protected:
explicit AXSVGRoot(RenderObject*);
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.cpp
index 2626bb6fdfc..e6774042f14 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.cpp
@@ -28,8 +28,8 @@
#include "core/accessibility/AXObjectCache.h"
#include "core/accessibility/AXScrollbar.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
namespace WebCore {
@@ -103,14 +103,14 @@ void AXScrollView::updateScrollbars()
m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar());
} else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) {
removeChildScrollbar(m_horizontalScrollbar.get());
- m_horizontalScrollbar = 0;
+ m_horizontalScrollbar = nullptr;
}
if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar) {
m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar());
} else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) {
removeChildScrollbar(m_verticalScrollbar.get());
- m_verticalScrollbar = 0;
+ m_verticalScrollbar = nullptr;
}
}
@@ -137,8 +137,8 @@ AXScrollbar* AXScrollView::addChildScrollbar(Scrollbar* scrollbar)
void AXScrollView::clearChildren()
{
AXObject::clearChildren();
- m_verticalScrollbar = 0;
- m_horizontalScrollbar = 0;
+ m_verticalScrollbar = nullptr;
+ m_horizontalScrollbar = nullptr;
}
bool AXScrollView::computeAccessibilityIsIgnored() const
@@ -168,7 +168,7 @@ AXObject* AXScrollView::webAreaObject() const
return 0;
Document* doc = toFrameView(m_scrollView)->frame().document();
- if (!doc || !doc->renderer())
+ if (!doc || !doc->renderView())
return 0;
return axObjectCache()->getOrCreate(doc);
@@ -209,7 +209,8 @@ AXObject* AXScrollView::parentObject() const
if (!m_scrollView || !m_scrollView->isFrameView())
return 0;
- HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame().ownerElement();
+ // FIXME: Broken for OOPI.
+ HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame().deprecatedLocalOwner();
if (owner && owner->renderer())
return axObjectCache()->getOrCreate(owner);
@@ -221,7 +222,7 @@ AXObject* AXScrollView::parentObjectIfExists() const
if (!m_scrollView || !m_scrollView->isFrameView())
return 0;
- HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame().ownerElement();
+ HTMLFrameOwnerElement* owner = toFrameView(m_scrollView)->frame().deprecatedLocalOwner();
if (owner && owner->renderer())
return axObjectCache()->get(owner);
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.h b/chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.h
index cf7e291024e..5da75f3afc0 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXScrollView.h
@@ -34,10 +34,10 @@ class AXScrollbar;
class Scrollbar;
class ScrollView;
-class AXScrollView : public AXObject {
+class AXScrollView FINAL : public AXObject {
public:
static PassRefPtr<AXScrollView> create(ScrollView*);
- virtual AccessibilityRole roleValue() const { return ScrollAreaRole; }
+ virtual AccessibilityRole roleValue() const OVERRIDE { return ScrollAreaRole; }
ScrollView* scrollView() const { return m_scrollView; }
virtual ~AXScrollView();
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.cpp
index 0b478487330..d8828dc85ce 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.cpp
@@ -41,7 +41,7 @@ AXScrollbar::AXScrollbar(Scrollbar* scrollbar)
void AXScrollbar::detachFromParent()
{
- m_scrollbar = 0;
+ m_scrollbar = nullptr;
AXMockObject::detachFromParent();
}
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.h b/chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.h
index 42eaca23470..ec9bef0cf01 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXScrollbar.h
@@ -35,7 +35,7 @@ namespace WebCore {
class Scrollbar;
-class AXScrollbar : public AXMockObject {
+class AXScrollbar FINAL : public AXMockObject {
public:
static PassRefPtr<AXScrollbar> create(Scrollbar*);
@@ -44,7 +44,7 @@ public:
private:
explicit AXScrollbar(Scrollbar*);
- virtual void detachFromParent();
+ virtual void detachFromParent() OVERRIDE;
virtual bool canSetValueAttribute() const OVERRIDE { return true; }
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXSlider.h b/chromium/third_party/WebKit/Source/core/accessibility/AXSlider.h
index 54b8a1b2a53..aa9d01b986e 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXSlider.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXSlider.h
@@ -47,22 +47,22 @@ protected:
private:
HTMLInputElement* element() const;
- virtual AXObject* elementAccessibilityHitTest(const IntPoint&) const OVERRIDE;
+ virtual AXObject* elementAccessibilityHitTest(const IntPoint&) const OVERRIDE FINAL;
virtual AccessibilityRole roleValue() const OVERRIDE { return SliderRole; }
- virtual bool isSlider() const OVERRIDE { return true; }
- virtual bool isControl() const OVERRIDE { return true; }
+ virtual bool isSlider() const OVERRIDE FINAL { return true; }
+ virtual bool isControl() const OVERRIDE FINAL { return true; }
- virtual void addChildren() OVERRIDE;
+ virtual void addChildren() OVERRIDE FINAL;
- virtual bool canSetValueAttribute() const OVERRIDE { return true; }
+ virtual bool canSetValueAttribute() const OVERRIDE FINAL { return true; }
const AtomicString& getAttribute(const QualifiedName& attribute) const;
- virtual void setValue(const String&) OVERRIDE;
- virtual AccessibilityOrientation orientation() const OVERRIDE;
+ virtual void setValue(const String&) OVERRIDE FINAL;
+ virtual AccessibilityOrientation orientation() const OVERRIDE FINAL;
};
-class AXSliderThumb : public AXMockObject {
+class AXSliderThumb FINAL : public AXMockObject {
public:
static PassRefPtr<AXSliderThumb> create();
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXSpinButton.h b/chromium/third_party/WebKit/Source/core/accessibility/AXSpinButton.h
index 12ae3adb23b..b26e6f7d008 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXSpinButton.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXSpinButton.h
@@ -32,7 +32,7 @@
namespace WebCore {
-class AXSpinButton : public AXMockObject {
+class AXSpinButton FINAL : public AXMockObject {
public:
static PassRefPtr<AXSpinButton> create();
virtual ~AXSpinButton();
@@ -52,7 +52,7 @@ private:
SpinButtonElement* m_spinButtonElement;
};
-class AXSpinButtonPart : public AXMockObject {
+class AXSpinButtonPart FINAL : public AXMockObject {
public:
static PassRefPtr<AXSpinButtonPart> create();
virtual ~AXSpinButtonPart() { }
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTable.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXTable.cpp
index f9f753096c1..22a0d454264 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTable.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTable.cpp
@@ -33,9 +33,15 @@
#include "core/accessibility/AXTableCell.h"
#include "core/accessibility/AXTableColumn.h"
#include "core/accessibility/AXTableRow.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/html/HTMLCollection.h"
#include "core/html/HTMLTableCaptionElement.h"
#include "core/html/HTMLTableCellElement.h"
+#include "core/html/HTMLTableColElement.h"
#include "core/html/HTMLTableElement.h"
+#include "core/html/HTMLTableRowElement.h"
+#include "core/html/HTMLTableRowsCollection.h"
+#include "core/html/HTMLTableSectionElement.h"
#include "core/rendering/RenderTableCell.h"
namespace WebCore {
@@ -44,7 +50,7 @@ using namespace HTMLNames;
AXTable::AXTable(RenderObject* renderer)
: AXRenderObject(renderer)
- , m_headerContainer(0)
+ , m_headerContainer(nullptr)
, m_isAXTable(true)
{
}
@@ -84,9 +90,18 @@ bool AXTable::isAXTable() const
return m_isAXTable;
}
+static bool elementHasAriaRole(const Element* element)
+{
+ if (!element)
+ return false;
+
+ const AtomicString& ariaRole = element->fastGetAttribute(roleAttr);
+ return (!ariaRole.isNull() && !ariaRole.isEmpty());
+}
+
bool AXTable::isDataTable() const
{
- if (!m_renderer)
+ if (!m_renderer || !node())
return false;
// Do not consider it a data table is it has an ARIA role.
@@ -106,11 +121,40 @@ bool AXTable::isDataTable() const
RenderTable* table = toRenderTable(m_renderer);
Node* tableNode = table->node();
- if (!tableNode || !isHTMLTableElement(tableNode))
+ if (!isHTMLTableElement(tableNode))
return false;
- // if there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table
+ // Do not consider it a data table if any of its descendants have an ARIA role.
HTMLTableElement* tableElement = toHTMLTableElement(tableNode);
+ if (elementHasAriaRole(tableElement->tHead()))
+ return false;
+ if (elementHasAriaRole(tableElement->tFoot()))
+ return false;
+
+ RefPtrWillBeRawPtr<HTMLCollection> bodies = tableElement->tBodies();
+ for (unsigned bodyIndex = 0; bodyIndex < bodies->length(); ++bodyIndex) {
+ Element* bodyElement = bodies->item(bodyIndex);
+ if (elementHasAriaRole(bodyElement))
+ return false;
+ }
+
+ RefPtrWillBeRawPtr<HTMLTableRowsCollection> rows = tableElement->rows();
+ unsigned rowCount = rows->length();
+ for (unsigned rowIndex = 0; rowIndex < rowCount; ++rowIndex) {
+ Element* rowElement = rows->item(rowIndex);
+ if (elementHasAriaRole(rowElement))
+ return false;
+ if (rowElement->hasTagName(trTag)) {
+ HTMLTableRowElement* row = static_cast<HTMLTableRowElement*>(rowElement);
+ RefPtrWillBeRawPtr<HTMLCollection> cells = row->cells();
+ for (unsigned cellIndex = 0; cellIndex < cells->length(); ++cellIndex) {
+ if (elementHasAriaRole(cells->item(cellIndex)))
+ return false;
+ }
+ }
+ }
+
+ // If there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table
if (!tableElement->summary().isEmpty() || tableElement->tHead() || tableElement->tFoot() || tableElement->caption())
return true;
@@ -119,10 +163,8 @@ bool AXTable::isDataTable() const
return true;
// if there's a colgroup or col element, it's probably a data table.
- for (Node* child = tableElement->firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(colTag) || child->hasTagName(colgroupTag))
- return true;
- }
+ if (Traversal<HTMLTableColElement>::firstChild(*tableElement))
+ return true;
// go through the cell's and check for tell-tale signs of "data" table status
// cells have borders, or use attributes like headers, abbr, scope or axis
@@ -191,10 +233,10 @@ bool AXTable::isDataTable() const
headersInFirstColumnCount++;
// in this case, the developer explicitly assigned a "data" table attribute
- if (cellNode->hasTagName(tdTag) || cellNode->hasTagName(thTag)) {
- HTMLTableCellElement* cellElement = toHTMLTableCellElement(cellNode);
- if (!cellElement->headers().isEmpty() || !cellElement->abbr().isEmpty()
- || !cellElement->axis().isEmpty() || !cellElement->scope().isEmpty())
+ if (isHTMLTableCellElement(*cellNode)) {
+ HTMLTableCellElement& cellElement = toHTMLTableCellElement(*cellNode);
+ if (!cellElement.headers().isEmpty() || !cellElement.abbr().isEmpty()
+ || !cellElement.axis().isEmpty() || !cellElement.scope().isEmpty())
return true;
}
@@ -314,7 +356,7 @@ void AXTable::clearChildren()
if (m_headerContainer) {
m_headerContainer->detachFromParent();
- m_headerContainer = 0;
+ m_headerContainer = nullptr;
}
}
@@ -439,7 +481,7 @@ void AXTable::cells(AXObject::AccessibilityChildrenVector& cells)
int numRows = m_rows.size();
for (int row = 0; row < numRows; ++row) {
AccessibilityChildrenVector rowChildren = m_rows[row]->children();
- cells.append(rowChildren);
+ cells.appendVector(rowChildren);
}
}
@@ -457,17 +499,6 @@ unsigned AXTable::rowCount()
return m_rows.size();
}
-int AXTable::tableLevel() const
-{
- int level = 0;
- for (AXObject* obj = static_cast<AXObject*>(const_cast<AXTable*>(this)); obj; obj = obj->parentObject()) {
- if (obj->isAXTable())
- ++level;
- }
-
- return level;
-}
-
AXTableCell* AXTable::cellForColumnAndRow(unsigned column, unsigned row)
{
updateChildrenIfNecessary();
@@ -535,7 +566,7 @@ String AXTable::title() const
// see if there is a caption
Node* tableElement = m_renderer->node();
- if (tableElement && isHTMLTableElement(tableElement)) {
+ if (isHTMLTableElement(tableElement)) {
HTMLTableCaptionElement* caption = toHTMLTableElement(tableElement)->caption();
if (caption)
title = caption->innerText();
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTable.h b/chromium/third_party/WebKit/Source/core/accessibility/AXTable.h
index bca782cba82..3897e10cd17 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTable.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTable.h
@@ -45,15 +45,15 @@ public:
static PassRefPtr<AXTable> create(RenderObject*);
virtual ~AXTable();
- virtual void init() OVERRIDE;
+ virtual void init() OVERRIDE FINAL;
- virtual bool isAXTable() const OVERRIDE;
- virtual bool isDataTable() const OVERRIDE;
+ virtual bool isAXTable() const OVERRIDE FINAL;
+ virtual bool isDataTable() const OVERRIDE FINAL;
- virtual AccessibilityRole roleValue() const OVERRIDE;
+ virtual AccessibilityRole roleValue() const OVERRIDE FINAL;
virtual void addChildren() OVERRIDE;
- virtual void clearChildren() OVERRIDE;
+ virtual void clearChildren() OVERRIDE FINAL;
// To be overridden by AXARIAGrid.
virtual bool isAriaTable() const { return false; }
@@ -64,9 +64,8 @@ public:
unsigned columnCount();
unsigned rowCount();
- virtual int tableLevel() const OVERRIDE;
- virtual String title() const OVERRIDE;
+ virtual String title() const OVERRIDE FINAL;
// all the cells in the table
void cells(AccessibilityChildrenVector&);
@@ -86,7 +85,7 @@ protected:
bool hasARIARole() const;
virtual bool isTableExposableThroughAccessibility() const;
- virtual bool computeAccessibilityIsIgnored() const OVERRIDE;
+ virtual bool computeAccessibilityIsIgnored() const OVERRIDE FINAL;
};
DEFINE_AX_OBJECT_TYPE_CASTS(AXTable, isAXTable());
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.cpp
index 7335a272db6..4097500bf88 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.cpp
@@ -32,7 +32,6 @@
#include "core/accessibility/AXObjectCache.h"
#include "core/rendering/RenderTableCell.h"
-using namespace std;
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.h b/chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.h
index c62d0d32c5a..205eb700c93 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTableCell.h
@@ -41,7 +41,7 @@ public:
static PassRefPtr<AXTableCell> create(RenderObject*);
virtual ~AXTableCell();
- virtual bool isTableCell() const OVERRIDE;
+ virtual bool isTableCell() const OVERRIDE FINAL;
// fills in the start location and row span of cell
virtual void rowIndexRange(pair<unsigned, unsigned>& rowRange);
@@ -51,13 +51,13 @@ public:
protected:
virtual AXObject* parentTable() const;
int m_rowIndex;
- virtual AccessibilityRole determineAccessibilityRole() OVERRIDE;
+ virtual AccessibilityRole determineAccessibilityRole() OVERRIDE FINAL;
private:
// If a table cell is not exposed as a table cell, a TH element can serve as its title UI element.
- virtual AXObject* titleUIElement() const OVERRIDE;
- virtual bool exposesTitleUIElement() const OVERRIDE { return true; }
- virtual bool computeAccessibilityIsIgnored() const OVERRIDE;
+ virtual AXObject* titleUIElement() const OVERRIDE FINAL;
+ virtual bool exposesTitleUIElement() const OVERRIDE FINAL { return true; }
+ virtual bool computeAccessibilityIsIgnored() const OVERRIDE FINAL;
};
DEFINE_AX_OBJECT_TYPE_CASTS(AXTableCell, isTableCell());
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.cpp
index 1b58379accd..5f51e825ebc 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.cpp
@@ -33,7 +33,6 @@
#include "core/accessibility/AXTableCell.h"
#include "core/rendering/RenderTableCell.h"
-using namespace std;
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.h b/chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.h
index 9da318774da..0163ffff8d6 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTableColumn.h
@@ -36,7 +36,7 @@ namespace WebCore {
class RenderTableSection;
-class AXTableColumn : public AXMockObject {
+class AXTableColumn FINAL : public AXMockObject {
private:
AXTableColumn();
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.cpp
index 5abb0a3857c..7851217353e 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.cpp
@@ -30,7 +30,6 @@
#include "core/accessibility/AXTableHeaderContainer.h"
-using namespace std;
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.h b/chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.h
index 3870aa7d67c..3997784bf01 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTableHeaderContainer.h
@@ -34,7 +34,7 @@
namespace WebCore {
-class AXTableHeaderContainer : public AXMockObject {
+class AXTableHeaderContainer FINAL : public AXMockObject {
private:
AXTableHeaderContainer();
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.cpp b/chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.cpp
index bf3dabb4065..e3465fee01b 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.cpp
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.cpp
@@ -32,7 +32,6 @@
#include "core/accessibility/AXTableCell.h"
#include "core/rendering/RenderTableRow.h"
-using namespace std;
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.h b/chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.h
index 90eca7fba49..37364cfbe85 100644
--- a/chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.h
+++ b/chromium/third_party/WebKit/Source/core/accessibility/AXTableRow.h
@@ -41,11 +41,11 @@ public:
static PassRefPtr<AXTableRow> create(RenderObject*);
virtual ~AXTableRow();
- virtual bool isTableRow() const OVERRIDE;
+ virtual bool isTableRow() const OVERRIDE FINAL;
// retrieves the "row" header (a th tag in the rightmost column)
virtual AXObject* headerObject();
- virtual AXObject* parentTable() const;
+ AXObject* parentTable() const;
void setRowIndex(int rowIndex) { m_rowIndex = rowIndex; }
int rowIndex() const { return m_rowIndex; }
@@ -55,13 +55,13 @@ public:
void appendChild(AXObject*);
protected:
- virtual AccessibilityRole determineAccessibilityRole() OVERRIDE;
+ virtual AccessibilityRole determineAccessibilityRole() OVERRIDE FINAL;
private:
int m_rowIndex;
- virtual AXObject* observableObject() const OVERRIDE;
- virtual bool computeAccessibilityIsIgnored() const OVERRIDE;
+ virtual AXObject* observableObject() const OVERRIDE FINAL;
+ virtual bool computeAccessibilityIsIgnored() const OVERRIDE FINAL;
};
DEFINE_AX_OBJECT_TYPE_CASTS(AXTableRow, isTableRow());
diff --git a/chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.cpp b/chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.cpp
index d27161d6a10..8743e5c4c8b 100644
--- a/chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.cpp
@@ -31,71 +31,71 @@
#include "config.h"
#include "core/animation/ActiveAnimations.h"
-#include "core/frame/animation/AnimationController.h"
#include "core/rendering/RenderObject.h"
namespace WebCore {
-bool shouldCompositeForActiveAnimations(const RenderObject& renderer)
+ActiveAnimations::~ActiveAnimations()
{
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
-
- if (!renderer.node() || !renderer.node()->isElementNode())
- return false;
-
- const Element* element = toElement(renderer.node());
- if (const ActiveAnimations* activeAnimations = element->activeAnimations()) {
- if (activeAnimations->hasActiveAnimations(CSSPropertyOpacity)
- || activeAnimations->hasActiveAnimations(CSSPropertyWebkitTransform)
- || activeAnimations->hasActiveAnimations(CSSPropertyWebkitFilter))
- return true;
- }
-
- return false;
+#if !ENABLE(OILPAN)
+ for (size_t i = 0; i < m_animations.size(); ++i)
+ m_animations[i]->notifyElementDestroyed();
+ m_animations.clear();
+#endif
}
-bool hasActiveAnimations(const RenderObject& renderer, CSSPropertyID property)
+void ActiveAnimations::addPlayer(AnimationPlayer* player)
{
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
-
- if (!renderer.node() || !renderer.node()->isElementNode())
- return false;
-
- const Element* element = toElement(renderer.node());
- if (const ActiveAnimations* activeAnimations = element->activeAnimations())
- return activeAnimations->hasActiveAnimations(property);
-
- return false;
+ ++m_players.add(player, 0).storedValue->value;
}
-bool hasActiveAnimationsOnCompositor(const RenderObject& renderer, CSSPropertyID property)
+void ActiveAnimations::removePlayer(AnimationPlayer* player)
{
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
-
- if (!renderer.node() || !renderer.node()->isElementNode())
- return false;
-
- const Element* element = toElement(renderer.node());
- if (const ActiveAnimations* activeAnimations = element->activeAnimations())
- return activeAnimations->hasActiveAnimationsOnCompositor(property);
-
- return false;
+ AnimationPlayerCountedSet::iterator it = m_players.find(player);
+ ASSERT(it != m_players.end());
+ ASSERT(it->value > 0);
+ --it->value;
+ if (!it->value)
+ m_players.remove(it);
}
-bool ActiveAnimations::hasActiveAnimations(CSSPropertyID property) const
+void ActiveAnimations::updateAnimationFlags(RenderStyle& style)
{
- return m_defaultStack.affects(property);
-}
+ for (AnimationPlayerCountedSet::const_iterator it = m_players.begin(); it != m_players.end(); ++it) {
+ const AnimationPlayer& player = *it->key;
+ ASSERT(player.source());
+ // FIXME: Needs to consider AnimationGroup once added.
+ ASSERT(player.source()->isAnimation());
+ const Animation& animation = *toAnimation(player.source());
+ if (animation.isCurrent()) {
+ if (animation.affects(CSSPropertyOpacity))
+ style.setHasCurrentOpacityAnimation(true);
+ if (animation.affects(CSSPropertyTransform))
+ style.setHasCurrentTransformAnimation(true);
+ if (animation.affects(CSSPropertyWebkitFilter))
+ style.setHasCurrentFilterAnimation(true);
+ }
+ }
-bool ActiveAnimations::hasActiveAnimationsOnCompositor(CSSPropertyID property) const
-{
- return m_defaultStack.hasActiveAnimationsOnCompositor(property);
+ if (style.hasCurrentOpacityAnimation())
+ style.setIsRunningOpacityAnimationOnCompositor(m_defaultStack.hasActiveAnimationsOnCompositor(CSSPropertyOpacity));
+ if (style.hasCurrentTransformAnimation())
+ style.setIsRunningTransformAnimationOnCompositor(m_defaultStack.hasActiveAnimationsOnCompositor(CSSPropertyTransform));
+ if (style.hasCurrentFilterAnimation())
+ style.setIsRunningFilterAnimationOnCompositor(m_defaultStack.hasActiveAnimationsOnCompositor(CSSPropertyWebkitFilter));
}
void ActiveAnimations::cancelAnimationOnCompositor()
{
- for (PlayerSet::iterator it = m_players.begin(); it != players().end(); ++it)
+ for (AnimationPlayerCountedSet::iterator it = m_players.begin(); it != m_players.end(); ++it)
it->key->cancelAnimationOnCompositor();
}
+void ActiveAnimations::trace(Visitor* visitor)
+{
+ visitor->trace(m_cssAnimations);
+ visitor->trace(m_defaultStack);
+ visitor->trace(m_players);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.h b/chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.h
index b12a9bf95dd..ad5ba4b6891 100644
--- a/chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.h
+++ b/chromium/third_party/WebKit/Source/core/animation/ActiveAnimations.h
@@ -44,15 +44,15 @@ class CSSAnimations;
class RenderObject;
class Element;
-// FIXME: Move these to CompositorAnimations
-bool shouldCompositeForActiveAnimations(const RenderObject&);
-bool hasActiveAnimations(const RenderObject&, CSSPropertyID);
-bool hasActiveAnimationsOnCompositor(const RenderObject&, CSSPropertyID);
-
-class ActiveAnimations {
+class ActiveAnimations : public NoBaseWillBeGarbageCollectedFinalized<ActiveAnimations> {
+ WTF_MAKE_NONCOPYABLE(ActiveAnimations);
public:
ActiveAnimations()
- : m_animationStyleChange(false) { }
+ : m_animationStyleChange(false)
+ {
+ }
+
+ ~ActiveAnimations();
// Animations that are currently active for this element, their effects will be applied
// during a style recalc. CSS Transitions are included in this stack.
@@ -63,27 +63,44 @@ public:
CSSAnimations& cssAnimations() { return m_cssAnimations; }
const CSSAnimations& cssAnimations() const { return m_cssAnimations; }
- typedef HashCountedSet<Player*> PlayerSet;
- // Players which have animations targeting this element.
- const PlayerSet& players() const { return m_players; }
- PlayerSet& players() { return m_players; }
+ typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<AnimationPlayer>, int> AnimationPlayerCountedSet;
+ // AnimationPlayers which have animations targeting this element.
+ const AnimationPlayerCountedSet& players() const { return m_players; }
+ void addPlayer(AnimationPlayer*);
+ void removePlayer(AnimationPlayer*);
+#if ENABLE(OILPAN)
bool isEmpty() const { return m_defaultStack.isEmpty() && m_cssAnimations.isEmpty(); }
+#else
+ bool isEmpty() const { return m_defaultStack.isEmpty() && m_cssAnimations.isEmpty() && m_animations.isEmpty(); }
+#endif
- bool hasActiveAnimations(CSSPropertyID) const;
- bool hasActiveAnimationsOnCompositor(CSSPropertyID) const;
void cancelAnimationOnCompositor();
+ void updateAnimationFlags(RenderStyle&);
void setAnimationStyleChange(bool animationStyleChange) { m_animationStyleChange = animationStyleChange; }
+#if !ENABLE(OILPAN)
+ void addAnimation(Animation* animation) { m_animations.append(animation); }
+ void notifyAnimationDestroyed(Animation* animation) { m_animations.remove(m_animations.find(animation)); }
+#endif
+
+ void trace(Visitor*);
+
private:
bool isAnimationStyleChange() const { return m_animationStyleChange; }
AnimationStack m_defaultStack;
CSSAnimations m_cssAnimations;
- PlayerSet m_players;
+ AnimationPlayerCountedSet m_players;
bool m_animationStyleChange;
+#if !ENABLE(OILPAN)
+ // FIXME: Oilpan: This is to avoid a reference cycle that keeps Elements alive
+ // and won't be needed once the Node hierarchy becomes traceable.
+ Vector<Animation*> m_animations;
+#endif
+
// CSSAnimations checks if a style change is due to animation.
friend class CSSAnimations;
};
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.cpp
index f539df4d1fb..1b1705a08c9 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.cpp
@@ -33,19 +33,28 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableClipPathOperation::interpolateTo(const AnimatableValue* value, double fraction) const
+bool AnimatableClipPathOperation::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
const AnimatableClipPathOperation* toOperation = toAnimatableClipPathOperation(value);
if (m_operation->type() != ClipPathOperation::SHAPE || toOperation->m_operation->type() != ClipPathOperation::SHAPE)
- return defaultInterpolateTo(this, value, fraction);
+ return true;
const BasicShape* fromShape = toShapeClipPathOperation(clipPathOperation())->basicShape();
const BasicShape* toShape = toShapeClipPathOperation(toOperation->clipPathOperation())->basicShape();
- if (!fromShape->canBlend(toShape))
+ return !fromShape->canBlend(toShape);
+}
+
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableClipPathOperation::interpolateTo(const AnimatableValue* value, double fraction) const
+{
+ if (usesDefaultInterpolationWith(value))
return defaultInterpolateTo(this, value, fraction);
+ const AnimatableClipPathOperation* toOperation = toAnimatableClipPathOperation(value);
+ const BasicShape* fromShape = toShapeClipPathOperation(clipPathOperation())->basicShape();
+ const BasicShape* toShape = toShapeClipPathOperation(toOperation->clipPathOperation())->basicShape();
+
return AnimatableClipPathOperation::create(ShapeClipPathOperation::create(toShape->blend(fromShape, fraction)).get());
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.h
index 0a2401f2bdb..0a0188d7bd8 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableClipPathOperation.h
@@ -36,17 +36,20 @@
namespace WebCore {
-class AnimatableClipPathOperation : public AnimatableValue {
+class AnimatableClipPathOperation FINAL : public AnimatableValue {
public:
virtual ~AnimatableClipPathOperation() { }
- static PassRefPtr<AnimatableClipPathOperation> create(ClipPathOperation* operation)
+ static PassRefPtrWillBeRawPtr<AnimatableClipPathOperation> create(ClipPathOperation* operation)
{
- return adoptRef(new AnimatableClipPathOperation(operation));
+ return adoptRefWillBeNoop(new AnimatableClipPathOperation(operation));
}
ClipPathOperation* clipPathOperation() const { return m_operation.get(); }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
AnimatableClipPathOperation(ClipPathOperation* operation)
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableColor.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableColor.cpp
index d501a81f4c1..8170b6cc801 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableColor.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableColor.cpp
@@ -34,6 +34,15 @@
#include "platform/animation/AnimationUtilities.h"
#include "wtf/MathExtras.h"
+namespace {
+
+double square(double x)
+{
+ return x * x;
+}
+
+} // namespace
+
namespace WebCore {
AnimatableColorImpl::AnimatableColorImpl(float red, float green, float blue, float alpha)
@@ -67,14 +76,6 @@ AnimatableColorImpl AnimatableColorImpl::interpolateTo(const AnimatableColorImpl
blend(m_alpha, to.m_alpha, fraction));
}
-AnimatableColorImpl AnimatableColorImpl::addWith(const AnimatableColorImpl& addend) const
-{
- return AnimatableColorImpl(m_red + addend.m_red,
- m_green + addend.m_green,
- m_blue + addend.m_blue,
- m_alpha + addend.m_alpha);
-}
-
bool AnimatableColorImpl::operator==(const AnimatableColorImpl& other) const
{
return m_red == other.m_red
@@ -83,29 +84,36 @@ bool AnimatableColorImpl::operator==(const AnimatableColorImpl& other) const
&& m_alpha == other.m_alpha;
}
-PassRefPtr<AnimatableColor> AnimatableColor::create(const AnimatableColorImpl& color, const AnimatableColorImpl& visitedLinkColor)
+double AnimatableColorImpl::distanceTo(const AnimatableColorImpl& other) const
{
- return adoptRef(new AnimatableColor(color, visitedLinkColor));
+ return sqrt(square(m_red - other.m_red)
+ + square(m_green - other.m_green)
+ + square(m_blue - other.m_blue)
+ + square(m_alpha - other.m_alpha));
}
-PassRefPtr<AnimatableValue> AnimatableColor::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableColor> AnimatableColor::create(const AnimatableColorImpl& color, const AnimatableColorImpl& visitedLinkColor)
+{
+ return adoptRefWillBeNoop(new AnimatableColor(color, visitedLinkColor));
+}
+
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableColor::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableColor* color = toAnimatableColor(value);
return create(m_color.interpolateTo(color->m_color, fraction),
m_visitedLinkColor.interpolateTo(color->m_visitedLinkColor, fraction));
}
-PassRefPtr<AnimatableValue> AnimatableColor::addWith(const AnimatableValue* value) const
+bool AnimatableColor::equalTo(const AnimatableValue* value) const
{
const AnimatableColor* color = toAnimatableColor(value);
- return create(m_color.addWith(color->m_color),
- m_visitedLinkColor.addWith(color->m_visitedLinkColor));
+ return m_color == color->m_color && m_visitedLinkColor == color->m_visitedLinkColor;
}
-bool AnimatableColor::equalTo(const AnimatableValue* value) const
+double AnimatableColor::distanceTo(const AnimatableValue* value) const
{
const AnimatableColor* color = toAnimatableColor(value);
- return m_color == color->m_color && m_visitedLinkColor == color->m_visitedLinkColor;
+ return m_color.distanceTo(color->m_color);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableColor.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableColor.h
index 57c8fd3cfeb..87196a0aa60 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableColor.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableColor.h
@@ -42,8 +42,8 @@ public:
AnimatableColorImpl(Color);
Color toColor() const;
AnimatableColorImpl interpolateTo(const AnimatableColorImpl&, double fraction) const;
- AnimatableColorImpl addWith(const AnimatableColorImpl&) const;
bool operator==(const AnimatableColorImpl&) const;
+ double distanceTo(const AnimatableColorImpl&) const;
private:
float m_alpha;
@@ -56,15 +56,16 @@ private:
// property. Currently it is used for all properties, even those which do not
// support a separate 'visited link' color (eg SVG properties). This is correct
// but inefficient.
-class AnimatableColor : public AnimatableValue {
+class AnimatableColor FINAL : public AnimatableValue {
public:
- static PassRefPtr<AnimatableColor> create(const AnimatableColorImpl&, const AnimatableColorImpl& visitedLinkColor);
+ static PassRefPtrWillBeRawPtr<AnimatableColor> create(const AnimatableColorImpl&, const AnimatableColorImpl& visitedLinkColor);
Color color() const { return m_color.toColor(); }
Color visitedLinkColor() const { return m_visitedLinkColor.toColor(); }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
AnimatableColor(const AnimatableColorImpl& color, const AnimatableColorImpl& visitedLinkColor)
@@ -74,6 +75,7 @@ private:
}
virtual AnimatableType type() const OVERRIDE { return TypeColor; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
+ virtual double distanceTo(const AnimatableValue*) const OVERRIDE;
const AnimatableColorImpl m_color;
const AnimatableColorImpl m_visitedLinkColor;
};
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableColorTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableColorTest.cpp
index 1e6ae355430..de4de666f37 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableColorTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableColorTest.cpp
@@ -40,10 +40,8 @@ namespace {
TEST(AnimationAnimatableColorTest, ToColor)
{
Color transparent = AnimatableColorImpl(Color::transparent).toColor();
- EXPECT_TRUE(transparent.isValid());
EXPECT_EQ(transparent.rgb(), Color::transparent);
Color red = AnimatableColorImpl(Color(0xFFFF0000)).toColor();
- EXPECT_TRUE(red.isValid());
EXPECT_EQ(red.rgb(), 0xFFFF0000);
}
@@ -67,15 +65,16 @@ TEST(AnimationAnimatableColorTest, Interpolate)
EXPECT_EQ(AnimatableColorImpl(Color(0x10204080)).interpolateTo(Color(0x104080C0), 0.5).toColor().rgb(), 0x103060A0u);
}
-TEST(AnimationAnimatableColorTest, Add)
+TEST(AnimationAnimatableColorTest, Distance)
{
- EXPECT_EQ(AnimatableColorImpl(Color(0xFF012345)).addWith(Color(0xFF543210)).toColor().rgb(), 0xFF555555);
- EXPECT_EQ(AnimatableColorImpl(Color(0xFF808080)).addWith(Color(0xFF808080)).toColor().rgb(), 0xFFFFFFFF);
- EXPECT_EQ(AnimatableColorImpl(Color(0x80FFFFFF)).addWith(Color(0x80FFFFFF)).toColor().rgb(), 0xFFFFFFFF);
- EXPECT_EQ(AnimatableColorImpl(Color(0x40FFFFFF)).addWith(Color(0x40FFFFFF)).toColor().rgb(), 0x80FFFFFF);
- EXPECT_EQ(AnimatableColorImpl(Color(0x40004080)).addWith(Color(0x80804000)).toColor().rgb(), 0xC055402B);
- EXPECT_EQ(AnimatableColorImpl(Color(0x10204080)).addWith(Color(0x104080C0)).toColor().rgb(), 0x203060A0u);
-}
+ EXPECT_NEAR(1.0, AnimatableColorImpl(Color(0xFF000000)).distanceTo(Color(0xFFFF0000)), 0.00000001);
+ EXPECT_NEAR(13.0 / 255, AnimatableColorImpl(Color(0xFF53647C)).distanceTo(Color(0xFF506070)), 0.00000001);
+ EXPECT_NEAR(60.0 / 255, AnimatableColorImpl(Color(0x3C000000)).distanceTo(Color(0x00FFFFFF)), 0.00000001);
+ EXPECT_NEAR(60.0 / 255, AnimatableColorImpl(Color(0x3C000000)).distanceTo(Color(0x3C00FF00)), 0.00000001);
+ RefPtrWillBeRawPtr<AnimatableColor> first = AnimatableColor::create(AnimatableColorImpl(Color(0xFF53647C)), AnimatableColorImpl(Color(0xFF000000)));
+ RefPtrWillBeRawPtr<AnimatableColor> second = AnimatableColor::create(AnimatableColorImpl(Color(0xFF506070)), AnimatableColorImpl(Color(0xFF000000)));
+ EXPECT_NEAR(13.0 / 255, AnimatableValue::distance(first.get(), second.get()), 0.00000001);
}
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.cpp
index 0e6cc0e2851..b27e515056f 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.cpp
@@ -31,18 +31,18 @@
#include "config.h"
#include "core/animation/AnimatableDouble.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/css/CSSValuePool.h"
#include "platform/animation/AnimationUtilities.h"
+#include <math.h>
namespace WebCore {
-PassRefPtr<CSSValue> AnimatableDouble::toCSSValue() const
+bool AnimatableDouble::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
- return cssValuePool().createValue(m_number, CSSPrimitiveValue::CSS_NUMBER);
+ const AnimatableDouble* other = toAnimatableDouble(value);
+ return (m_constraint == InterpolationIsNonContinuousWithZero) && (!m_number || !other->m_number);
}
-PassRefPtr<AnimatableValue> AnimatableDouble::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableDouble::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableDouble* other = toAnimatableDouble(value);
ASSERT(m_constraint == other->m_constraint);
@@ -51,21 +51,15 @@ PassRefPtr<AnimatableValue> AnimatableDouble::interpolateTo(const AnimatableValu
return AnimatableDouble::create(blend(m_number, other->m_number, fraction));
}
-PassRefPtr<AnimatableValue> AnimatableDouble::addWith(const AnimatableValue* value) const
+bool AnimatableDouble::equalTo(const AnimatableValue* value) const
{
- // Optimization for adding with 0.
- if (!m_number)
- return takeConstRef(value);
- const AnimatableDouble* other = toAnimatableDouble(value);
- if (!other->m_number)
- return takeConstRef(this);
-
- return AnimatableDouble::create(m_number + other->m_number);
+ return m_number == toAnimatableDouble(value)->m_number;
}
-bool AnimatableDouble::equalTo(const AnimatableValue* value) const
+double AnimatableDouble::distanceTo(const AnimatableValue* value) const
{
- return m_number == toAnimatableDouble(value)->m_number;
+ const AnimatableDouble* other = toAnimatableDouble(value);
+ return fabs(m_number - other->m_number);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.h
index b2b71165a6a..88ef247c4e5 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableDouble.h
@@ -32,11 +32,10 @@
#define AnimatableDouble_h
#include "core/animation/AnimatableValue.h"
-#include "core/css/CSSValue.h"
namespace WebCore {
-class AnimatableDouble : public AnimatableValue {
+class AnimatableDouble FINAL : public AnimatableValue {
public:
virtual ~AnimatableDouble() { }
@@ -45,17 +44,18 @@ public:
InterpolationIsNonContinuousWithZero,
};
- static PassRefPtr<AnimatableDouble> create(double number, Constraint constraint = Unconstrained)
+ static PassRefPtrWillBeRawPtr<AnimatableDouble> create(double number, Constraint constraint = Unconstrained)
{
- return adoptRef(new AnimatableDouble(number, constraint));
+ return adoptRefWillBeNoop(new AnimatableDouble(number, constraint));
}
- PassRefPtr<CSSValue> toCSSValue() const;
double toDouble() const { return m_number; }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
AnimatableDouble(double number, Constraint constraint)
@@ -65,6 +65,7 @@ private:
}
virtual AnimatableType type() const OVERRIDE { return TypeDouble; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
+ virtual double distanceTo(const AnimatableValue*) const OVERRIDE;
double m_number;
Constraint m_constraint;
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableDoubleTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableDoubleTest.cpp
index ce8510bd544..f1948fb18b8 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableDoubleTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableDoubleTest.cpp
@@ -31,8 +31,6 @@
#include "config.h"
#include "core/animation/AnimatableDouble.h"
-#include "core/css/CSSPrimitiveValue.h"
-
#include <gtest/gtest.h>
using namespace WebCore;
@@ -51,14 +49,6 @@ TEST(AnimationAnimatableDoubleTest, Equal)
EXPECT_FALSE(AnimatableDouble::create(5)->equals(AnimatableDouble::create(10).get()));
}
-TEST(AnimationAnimatableDoubleTest, ToCSSValue)
-{
- RefPtr<CSSValue> cssValue5 = CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_NUMBER);
- RefPtr<CSSValue> cssValue10 = CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_NUMBER);
- EXPECT_TRUE(AnimatableDouble::create(5)->toCSSValue()->equals(*cssValue5.get()));
- EXPECT_FALSE(AnimatableDouble::create(5)->toCSSValue()->equals(*cssValue10.get()));
-}
-
TEST(AnimationAnimatableDoubleTest, ToDouble)
{
EXPECT_EQ(5.9, AnimatableDouble::create(5.9)->toDouble());
@@ -68,8 +58,8 @@ TEST(AnimationAnimatableDoubleTest, ToDouble)
TEST(AnimationAnimatableDoubleTest, Interpolate)
{
- RefPtr<AnimatableDouble> from10 = AnimatableDouble::create(10);
- RefPtr<AnimatableDouble> to20 = AnimatableDouble::create(20);
+ RefPtrWillBeRawPtr<AnimatableDouble> from10 = AnimatableDouble::create(10);
+ RefPtrWillBeRawPtr<AnimatableDouble> to20 = AnimatableDouble::create(20);
EXPECT_EQ(5, toAnimatableDouble(AnimatableValue::interpolate(from10.get(), to20.get(), -0.5).get())->toDouble());
EXPECT_EQ(10, toAnimatableDouble(AnimatableValue::interpolate(from10.get(), to20.get(), 0).get())->toDouble());
EXPECT_EQ(14, toAnimatableDouble(AnimatableValue::interpolate(from10.get(), to20.get(), 0.4).get())->toDouble());
@@ -79,13 +69,15 @@ TEST(AnimationAnimatableDoubleTest, Interpolate)
EXPECT_EQ(25, toAnimatableDouble(AnimatableValue::interpolate(from10.get(), to20.get(), 1.5).get())->toDouble());
}
-TEST(AnimationAnimatableDoubleTest, Add)
+TEST(AnimationAnimatableDoubleTest, Distance)
{
- EXPECT_EQ(-10, toAnimatableDouble(AnimatableValue::add(AnimatableDouble::create(-2).get(), AnimatableDouble::create(-8).get()).get())->toDouble());
- EXPECT_EQ(0, toAnimatableDouble(AnimatableValue::add(AnimatableDouble::create(50).get(), AnimatableDouble::create(-50).get()).get())->toDouble());
- EXPECT_EQ(10, toAnimatableDouble(AnimatableValue::add(AnimatableDouble::create(4).get(), AnimatableDouble::create(6).get()).get())->toDouble());
- EXPECT_EQ(20, toAnimatableDouble(AnimatableValue::add(AnimatableDouble::create(0).get(), AnimatableDouble::create(20).get()).get())->toDouble());
- EXPECT_EQ(30, toAnimatableDouble(AnimatableValue::add(AnimatableDouble::create(30).get(), AnimatableDouble::create(0).get()).get())->toDouble());
+ RefPtrWillBeRawPtr<AnimatableDouble> first = AnimatableDouble::create(-1.5);
+ RefPtrWillBeRawPtr<AnimatableDouble> second = AnimatableDouble::create(2.25);
+ RefPtrWillBeRawPtr<AnimatableDouble> third = AnimatableDouble::create(3);
+
+ EXPECT_DOUBLE_EQ(3.75, AnimatableValue::distance(first.get(), second.get()));
+ EXPECT_DOUBLE_EQ(0.75, AnimatableValue::distance(second.get(), third.get()));
+ EXPECT_DOUBLE_EQ(4.5, AnimatableValue::distance(third.get(), first.get()));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.cpp
index 31edeabb24b..d0aebf007d4 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.cpp
@@ -35,12 +35,18 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableFilterOperations::interpolateTo(const AnimatableValue* value, double fraction) const
+bool AnimatableFilterOperations::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
const AnimatableFilterOperations* target = toAnimatableFilterOperations(value);
- if (!operations().canInterpolateWith(target->operations()))
+ return !operations().canInterpolateWith(target->operations());
+}
+
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableFilterOperations::interpolateTo(const AnimatableValue* value, double fraction) const
+{
+ if (usesDefaultInterpolationWith(value))
return defaultInterpolateTo(this, value, fraction);
+ const AnimatableFilterOperations* target = toAnimatableFilterOperations(value);
FilterOperations result;
size_t fromSize = operations().size();
size_t toSize = target->operations().size();
@@ -57,12 +63,6 @@ PassRefPtr<AnimatableValue> AnimatableFilterOperations::interpolateTo(const Anim
return AnimatableFilterOperations::create(result);
}
-PassRefPtr<AnimatableValue> AnimatableFilterOperations::addWith(const AnimatableValue* value) const
-{
- ASSERT_WITH_MESSAGE(false, "Web Animations not yet implemented: AnimatableFilterOperations::addWith()");
- return defaultAddWith(this, value);
-}
-
bool AnimatableFilterOperations::equalTo(const AnimatableValue* value) const
{
return operations() == toAnimatableFilterOperations(value)->operations();
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.h
index 17c694474ce..e047201652f 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableFilterOperations.h
@@ -36,18 +36,20 @@
namespace WebCore {
-class AnimatableFilterOperations : public AnimatableValue {
+class AnimatableFilterOperations FINAL : public AnimatableValue {
public:
virtual ~AnimatableFilterOperations() { }
- static PassRefPtr<AnimatableFilterOperations> create(const FilterOperations& operations)
+ static PassRefPtrWillBeRawPtr<AnimatableFilterOperations> create(const FilterOperations& operations)
{
- return adoptRef(new AnimatableFilterOperations(operations));
+ return adoptRefWillBeNoop(new AnimatableFilterOperations(operations));
}
const FilterOperations& operations() const { return m_operations; }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
AnimatableFilterOperations(const FilterOperations& operations)
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableImage.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableImage.cpp
index eee86c39987..a347e82696f 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableImage.cpp
@@ -37,45 +37,32 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableImage::interpolateTo(const AnimatableValue* value, double fraction) const
+// FIXME: Once cross-fade works on generated image types, remove this method.
+bool AnimatableImage::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
- if (fraction <= 0 || fraction >= 1)
- return defaultInterpolateTo(this, value, fraction);
- RefPtr<CSSValue> fromValue = this->toCSSValue();
- // FIXME: Once cross-fade works on generated image types, remove this check.
- if (fromValue->isImageGeneratorValue())
- return defaultInterpolateTo(this, value, fraction);
- if (!fromValue->isImageValue() && !fromValue->isImageGeneratorValue()) {
- if (!m_image->isImageResource())
- return defaultInterpolateTo(this, value, fraction);
- ImageResource* resource = static_cast<ImageResource*>(m_image->data());
- fromValue = CSSImageValue::create(resource->url(), m_image.get());
- }
- const AnimatableImage* image = toAnimatableImage(value);
- RefPtr<CSSValue> toValue = image->toCSSValue();
- // FIXME: Once cross-fade works on generated image types, remove this check.
- if (toValue->isImageGeneratorValue())
- return defaultInterpolateTo(this, value, fraction);
- if (!toValue->isImageValue() && !toValue->isImageGeneratorValue()) {
- if (!image->m_image->isImageResource())
- return defaultInterpolateTo(this, value, fraction);
- ImageResource* resource = static_cast<ImageResource*>(image->m_image->data());
- toValue = CSSImageValue::create(resource->url(), image->m_image.get());
- }
- RefPtr<CSSCrossfadeValue> crossfadeValue = CSSCrossfadeValue::create(fromValue, toValue);
- crossfadeValue->setPercentage(CSSPrimitiveValue::create(fraction, CSSPrimitiveValue::CSS_NUMBER));
- return create(StyleGeneratedImage::create(crossfadeValue.get()).get());
+ if (!m_value->isImageValue())
+ return true;
+ if (!toAnimatableImage(value)->toCSSValue()->isImageValue())
+ return true;
+ return false;
}
-PassRefPtr<AnimatableValue> AnimatableImage::addWith(const AnimatableValue* value) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableImage::interpolateTo(const AnimatableValue* value, double fraction) const
{
- // FIXME: Correct procedure is defined here: http://dev.w3.org/fxtf/web-animations/#the--image--type
- return defaultAddWith(this, value);
+ if (fraction <= 0 || fraction >= 1 || usesDefaultInterpolationWith(value))
+ return defaultInterpolateTo(this, value, fraction);
+
+ CSSValue* fromValue = toCSSValue();
+ CSSValue* toValue = toAnimatableImage(value)->toCSSValue();
+
+ RefPtrWillBeRawPtr<CSSCrossfadeValue> crossfadeValue = CSSCrossfadeValue::create(fromValue, toValue);
+ crossfadeValue->setPercentage(CSSPrimitiveValue::create(fraction, CSSPrimitiveValue::CSS_NUMBER));
+ return create(crossfadeValue);
}
bool AnimatableImage::equalTo(const AnimatableValue* value) const
{
- return StyleImage::imagesEquivalent(m_image.get(), toAnimatableImage(value)->m_image.get());
+ return m_value->equals(*toAnimatableImage(value)->m_value.get());
}
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableImage.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableImage.h
index 40152f95c5e..e76b6196e8c 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableImage.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableImage.h
@@ -37,30 +37,35 @@
namespace WebCore {
-class AnimatableImage : public AnimatableValue {
+class AnimatableImage FINAL : public AnimatableValue {
public:
virtual ~AnimatableImage() { }
- static PassRefPtr<AnimatableImage> create(StyleImage* image)
+ static PassRefPtrWillBeRawPtr<AnimatableImage> create(PassRefPtrWillBeRawPtr<CSSValue> value)
{
- return adoptRef(new AnimatableImage(image));
+ return adoptRefWillBeNoop(new AnimatableImage(value));
+ }
+ CSSValue* toCSSValue() const { return m_value.get(); }
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_value);
+ AnimatableValue::trace(visitor);
}
- PassRefPtr<CSSValue> toCSSValue() const { return m_image->cssValue(); }
- StyleImage* toStyleImage() const { return m_image.get(); }
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
- AnimatableImage(StyleImage* image)
- : m_image(image)
+ AnimatableImage(PassRefPtrWillBeRawPtr<CSSValue> value)
+ : m_value(value)
{
- ASSERT(m_image);
+ ASSERT(m_value.get());
}
virtual AnimatableType type() const OVERRIDE { return TypeImage; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- const RefPtr<StyleImage> m_image;
+ const RefPtrWillBeMember<CSSValue> m_value;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableImage, isImage());
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLength.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableLength.cpp
index 38a46590dbb..c167c20a752 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLength.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLength.cpp
@@ -31,211 +31,53 @@
#include "config.h"
#include "core/animation/AnimatableLength.h"
-#include "core/css/CSSPrimitiveValueMappings.h"
#include "platform/CalculationValue.h"
#include "platform/animation/AnimationUtilities.h"
namespace WebCore {
-PassRefPtr<AnimatableLength> AnimatableLength::create(CSSValue* value)
-{
- ASSERT(canCreateFrom(value));
- if (value->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(value);
- const CSSCalcValue* calcValue = primitiveValue->cssCalcValue();
- if (calcValue)
- return create(calcValue->expressionNode(), primitiveValue);
- NumberUnitType unitType;
- bool isPrimitiveLength = primitiveUnitToNumberType(primitiveValue->primitiveType(), unitType);
- ASSERT_UNUSED(isPrimitiveLength, isPrimitiveLength);
- const double scale = CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(primitiveValue->primitiveType());
- return create(primitiveValue->getDoubleValue() * scale, unitType, primitiveValue);
- }
-
- if (value->isCalcValue())
- return create(toCSSCalcValue(value)->expressionNode());
-
- ASSERT_NOT_REACHED();
- return 0;
-}
+namespace {
-bool AnimatableLength::canCreateFrom(const CSSValue* value)
+double clampNumber(double value, ValueRange range)
{
- ASSERT(value);
- if (value->isPrimitiveValue()) {
- const CSSPrimitiveValue* primitiveValue = WebCore::toCSSPrimitiveValue(value);
- if (primitiveValue->cssCalcValue())
- return true;
-
- NumberUnitType unitType;
- // Only returns true if the type is a primitive length unit.
- return primitiveUnitToNumberType(primitiveValue->primitiveType(), unitType);
- }
- return value->isCalcValue();
+ if (range == ValueRangeNonNegative)
+ return std::max(value, 0.0);
+ ASSERT(range == ValueRangeAll);
+ return value;
}
-PassRefPtr<CSSValue> AnimatableLength::toCSSValue(NumberRange range) const
-{
- return toCSSPrimitiveValue(range);
-}
+} // namespace
-Length AnimatableLength::toLength(const CSSToLengthConversionData& conversionData, NumberRange range) const
+AnimatableLength::AnimatableLength(const Length& length, float zoom)
{
- // Avoid creating a CSSValue in the common cases
- if (m_unitType == UnitTypePixels)
- return Length(clampedNumber(range) * conversionData.zoom(), Fixed);
- if (m_unitType == UnitTypePercentage)
- return Length(clampedNumber(range), Percent);
-
- return toCSSPrimitiveValue(range)->convertToLength<AnyConversion>(conversionData);
+ ASSERT(zoom);
+ PixelsAndPercent pixelsAndPercent = length.pixelsAndPercent();
+ m_pixels = pixelsAndPercent.pixels / zoom;
+ m_percent = pixelsAndPercent.percent;
+ m_hasPixels = length.type() != Percent;
+ m_hasPercent = !length.isFixed();
}
-PassRefPtr<AnimatableValue> AnimatableLength::interpolateTo(const AnimatableValue* value, double fraction) const
+Length AnimatableLength::length(float zoom, ValueRange range) const
{
- const AnimatableLength* length = toAnimatableLength(value);
- NumberUnitType type = commonUnitType(length);
- if (type != UnitTypeCalc)
- return AnimatableLength::create(blend(m_number, length->m_number, fraction), type);
-
- // FIXME(crbug.com/168840): Support for viewport units in calc needs to be added before we can blend them with other units.
- if (isViewportUnit() || length->isViewportUnit())
- return defaultInterpolateTo(this, value, fraction);
-
- return AnimatableLength::create(scale(1 - fraction).get(), length->scale(fraction).get());
+ if (!m_hasPercent)
+ return Length(clampNumber(m_pixels, range) * zoom, Fixed);
+ if (!m_hasPixels)
+ return Length(clampNumber(m_percent, range), Percent);
+ return Length(CalculationValue::create(PixelsAndPercent(m_pixels * zoom, m_percent), range));
}
-PassRefPtr<AnimatableValue> AnimatableLength::addWith(const AnimatableValue* value) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableLength::interpolateTo(const AnimatableValue* value, double fraction) const
{
- // Optimization for adding with 0.
- if (isUnitlessZero())
- return takeConstRef(value);
-
const AnimatableLength* length = toAnimatableLength(value);
- if (length->isUnitlessZero())
- return takeConstRef(this);
-
- NumberUnitType type = commonUnitType(length);
- if (type != UnitTypeCalc)
- return AnimatableLength::create(m_number + length->m_number, type);
-
- return AnimatableLength::create(this, length);
+ return create(blend(m_pixels, length->m_pixels, fraction), blend(m_percent, length->m_percent, fraction),
+ m_hasPixels || length->m_hasPixels, m_hasPercent || length->m_hasPercent);
}
bool AnimatableLength::equalTo(const AnimatableValue* value) const
{
const AnimatableLength* length = toAnimatableLength(value);
- if (m_unitType != length->m_unitType)
- return false;
- if (isCalc())
- return m_calcExpression == length->m_calcExpression || m_calcExpression->equals(*length->m_calcExpression);
- return m_number == length->m_number;
-}
-
-PassRefPtr<CSSCalcExpressionNode> AnimatableLength::toCSSCalcExpressionNode() const
-{
- if (isCalc())
- return m_calcExpression;
- return CSSCalcValue::createExpressionNode(toCSSPrimitiveValue(AllValues), m_number == trunc(m_number));
-}
-
-static bool isCompatibleWithRange(const CSSPrimitiveValue* primitiveValue, NumberRange range)
-{
- ASSERT(primitiveValue);
- if (range == AllValues)
- return true;
- if (primitiveValue->isCalculated())
- return primitiveValue->cssCalcValue()->permittedValueRange() == ValueRangeNonNegative;
- return primitiveValue->getDoubleValue() >= 0;
-}
-
-PassRefPtr<CSSPrimitiveValue> AnimatableLength::toCSSPrimitiveValue(NumberRange range) const
-{
- if (!m_cachedCSSPrimitiveValue || !isCompatibleWithRange(m_cachedCSSPrimitiveValue.get(), range)) {
- if (isCalc())
- m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(CSSCalcValue::create(m_calcExpression, range == AllValues ? ValueRangeAll : ValueRangeNonNegative));
- else
- m_cachedCSSPrimitiveValue = CSSPrimitiveValue::create(clampedNumber(range), static_cast<CSSPrimitiveValue::UnitTypes>(numberTypeToPrimitiveUnit(m_unitType)));
- }
- return m_cachedCSSPrimitiveValue;
-}
-
-PassRefPtr<AnimatableLength> AnimatableLength::scale(double factor) const
-{
- if (isCalc()) {
- return AnimatableLength::create(CSSCalcValue::createExpressionNode(
- m_calcExpression,
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(factor, CSSPrimitiveValue::CSS_NUMBER)),
- CalcMultiply));
- }
- return AnimatableLength::create(m_number * factor, m_unitType);
-}
-
-bool AnimatableLength::primitiveUnitToNumberType(unsigned short primitiveUnit, NumberUnitType& numberType)
-{
- switch (primitiveUnit) {
- case CSSPrimitiveValue::CSS_PX:
- case CSSPrimitiveValue::CSS_CM:
- case CSSPrimitiveValue::CSS_MM:
- case CSSPrimitiveValue::CSS_IN:
- case CSSPrimitiveValue::CSS_PT:
- case CSSPrimitiveValue::CSS_PC:
- numberType = UnitTypePixels;
- return true;
- case CSSPrimitiveValue::CSS_EMS:
- numberType = UnitTypeFontSize;
- return true;
- case CSSPrimitiveValue::CSS_EXS:
- numberType = UnitTypeFontXSize;
- return true;
- case CSSPrimitiveValue::CSS_REMS:
- numberType = UnitTypeRootFontSize;
- return true;
- case CSSPrimitiveValue::CSS_PERCENTAGE:
- numberType = UnitTypePercentage;
- return true;
- case CSSPrimitiveValue::CSS_VW:
- numberType = UnitTypeViewportWidth;
- return true;
- case CSSPrimitiveValue::CSS_VH:
- numberType = UnitTypeViewportHeight;
- return true;
- case CSSPrimitiveValue::CSS_VMIN:
- numberType = UnitTypeViewportMin;
- return true;
- case CSSPrimitiveValue::CSS_VMAX:
- numberType = UnitTypeViewportMax;
- return true;
- default:
- return false;
- }
-}
-
-unsigned short AnimatableLength::numberTypeToPrimitiveUnit(NumberUnitType numberType)
-{
- switch (numberType) {
- case UnitTypePixels:
- return CSSPrimitiveValue::CSS_PX;
- case UnitTypeFontSize:
- return CSSPrimitiveValue::CSS_EMS;
- case UnitTypeFontXSize:
- return CSSPrimitiveValue::CSS_EXS;
- case UnitTypeRootFontSize:
- return CSSPrimitiveValue::CSS_REMS;
- case UnitTypePercentage:
- return CSSPrimitiveValue::CSS_PERCENTAGE;
- case UnitTypeViewportWidth:
- return CSSPrimitiveValue::CSS_VW;
- case UnitTypeViewportHeight:
- return CSSPrimitiveValue::CSS_VH;
- case UnitTypeViewportMin:
- return CSSPrimitiveValue::CSS_VMIN;
- case UnitTypeViewportMax:
- return CSSPrimitiveValue::CSS_VMAX;
- case UnitTypeCalc:
- return CSSPrimitiveValue::CSS_UNKNOWN;
- }
- ASSERT_NOT_REACHED();
- return CSSPrimitiveValue::CSS_UNKNOWN;
+ return m_pixels == length->m_pixels && m_percent == length->m_percent && m_hasPixels == length->m_hasPixels && m_hasPercent == length->m_hasPercent;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLength.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableLength.h
index 14745761248..754c0436230 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLength.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLength.h
@@ -32,131 +32,44 @@
#define AnimatableLength_h
#include "core/animation/AnimatableValue.h"
-#include "core/css/CSSCalculationValue.h"
-#include "core/css/CSSPrimitiveValue.h"
#include "platform/Length.h"
namespace WebCore {
-enum NumberRange {
- AllValues,
- NonNegativeValues,
-};
-
-// Handles animation of CSS length and percentage values including CSS calc.
-// See primitiveUnitToNumberType() for the list of supported units.
-// If created from a CSSPrimitiveValue this class will cache it to be returned in toCSSValue().
-class AnimatableLength : public AnimatableValue {
+class AnimatableLength FINAL : public AnimatableValue {
public:
- enum NumberUnitType {
- UnitTypeCalc,
- UnitTypePixels,
- UnitTypePercentage,
- UnitTypeFontSize,
- UnitTypeFontXSize,
- UnitTypeRootFontSize,
- UnitTypeViewportWidth,
- UnitTypeViewportHeight,
- UnitTypeViewportMin,
- UnitTypeViewportMax,
- };
-
- virtual ~AnimatableLength() { }
- static bool canCreateFrom(const CSSValue*);
- static PassRefPtr<AnimatableLength> create(CSSValue*);
- static PassRefPtr<AnimatableLength> create(double number, NumberUnitType unitType, CSSPrimitiveValue* cssPrimitiveValue = 0)
- {
- return adoptRef(new AnimatableLength(number, unitType, cssPrimitiveValue));
- }
- static PassRefPtr<AnimatableLength> create(PassRefPtr<CSSCalcExpressionNode> calcExpression, CSSPrimitiveValue* cssPrimitiveValue = 0)
+ static PassRefPtrWillBeRawPtr<AnimatableLength> create(const Length& length, float zoom)
{
- return adoptRef(new AnimatableLength(calcExpression, cssPrimitiveValue));
+ return adoptRefWillBeNoop(new AnimatableLength(length, zoom));
}
- PassRefPtr<CSSValue> toCSSValue(NumberRange = AllValues) const;
- Length toLength(const CSSToLengthConversionData&, NumberRange = AllValues) const;
+ Length length(float zoom, ValueRange) const;
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
- AnimatableLength(double number, NumberUnitType unitType, CSSPrimitiveValue* cssPrimitiveValue)
- : m_number(number)
- , m_unitType(unitType)
- , m_cachedCSSPrimitiveValue(cssPrimitiveValue)
+ static PassRefPtrWillBeRawPtr<AnimatableLength> create(double pixels, double percent, bool hasPixels, bool hasPercent)
{
- ASSERT(m_unitType != UnitTypeCalc);
+ return adoptRefWillBeNoop(new AnimatableLength(pixels, percent, hasPixels, hasPercent));
}
- AnimatableLength(PassRefPtr<CSSCalcExpressionNode> calcExpression, CSSPrimitiveValue* cssPrimitiveValue)
- : m_unitType(UnitTypeCalc)
- , m_calcExpression(calcExpression)
- , m_cachedCSSPrimitiveValue(cssPrimitiveValue)
+ AnimatableLength(const Length&, float zoom);
+ AnimatableLength(double pixels, double percent, bool hasPixels, bool hasPercent)
+ : m_pixels(pixels)
+ , m_percent(percent)
+ , m_hasPixels(hasPixels)
+ , m_hasPercent(hasPercent)
{
- ASSERT(m_calcExpression);
+ ASSERT(m_hasPixels || m_hasPercent);
}
virtual AnimatableType type() const OVERRIDE { return TypeLength; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- bool isCalc() const
- {
- return m_unitType == UnitTypeCalc;
- }
-
- bool isViewportUnit() const
- {
- return m_unitType == UnitTypeViewportWidth || m_unitType == UnitTypeViewportHeight || m_unitType == UnitTypeViewportMin || m_unitType == UnitTypeViewportMax;
- }
-
- static PassRefPtr<AnimatableLength> create(const AnimatableLength* leftAddend, const AnimatableLength* rightAddend)
- {
- ASSERT(leftAddend && rightAddend);
- return create(CSSCalcValue::createExpressionNode(leftAddend->toCSSCalcExpressionNode(), rightAddend->toCSSCalcExpressionNode(), CalcAdd));
- }
-
- PassRefPtr<CSSPrimitiveValue> toCSSPrimitiveValue(NumberRange) const;
- PassRefPtr<CSSCalcExpressionNode> toCSSCalcExpressionNode() const;
-
- PassRefPtr<AnimatableLength> scale(double) const;
- double clampedNumber(NumberRange range) const
- {
- ASSERT(!isCalc());
- return (range == NonNegativeValues && m_number <= 0) ? 0 : m_number;
- }
-
- // Returns true and populates numberType, if primitiveUnit is a primitive length unit. Otherwise, returns false.
- static bool primitiveUnitToNumberType(unsigned short primitiveUnit, NumberUnitType& numberType);
-
- static unsigned short numberTypeToPrimitiveUnit(NumberUnitType numberType);
-
- // Zero is effectively unitless, except in the case of percentage.
- // http://www.w3.org/TR/css3-values/#calc-computed-value
- // e.g. calc(100% - 100% + 1em) resolves to calc(0% + 1em), not to calc(1em)
- bool isUnitlessZero() const
- {
- return !isCalc() && !m_number && m_unitType != UnitTypePercentage;
- }
-
- NumberUnitType commonUnitType(const AnimatableLength* length) const
- {
- if (m_unitType == length->m_unitType)
- return m_unitType;
-
- if (isUnitlessZero())
- return length->m_unitType;
- if (length->isUnitlessZero())
- return m_unitType;
-
- return UnitTypeCalc;
- }
-
- double m_number;
- const NumberUnitType m_unitType;
-
- RefPtr<CSSCalcExpressionNode> m_calcExpression;
-
- mutable RefPtr<CSSPrimitiveValue> m_cachedCSSPrimitiveValue;
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
- friend class AnimationAnimatableLengthTest;
+ double m_pixels;
+ double m_percent;
+ bool m_hasPixels;
+ bool m_hasPercent;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableLength, isLength());
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.cpp
index 825a1351655..25896210c9e 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.cpp
@@ -33,7 +33,7 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableLengthBox::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableLengthBox::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableLengthBox* lengthBox = toAnimatableLengthBox(value);
return AnimatableLengthBox::create(
@@ -43,16 +43,6 @@ PassRefPtr<AnimatableValue> AnimatableLengthBox::interpolateTo(const AnimatableV
AnimatableValue::interpolate(this->bottom(), lengthBox->bottom(), fraction));
}
-PassRefPtr<AnimatableValue> AnimatableLengthBox::addWith(const AnimatableValue* value) const
-{
- const AnimatableLengthBox* lengthBox = toAnimatableLengthBox(value);
- return AnimatableLengthBox::create(
- AnimatableValue::add(this->left(), lengthBox->left()),
- AnimatableValue::add(this->right(), lengthBox->right()),
- AnimatableValue::add(this->top(), lengthBox->top()),
- AnimatableValue::add(this->bottom(), lengthBox->bottom()));
-}
-
bool AnimatableLengthBox::equalTo(const AnimatableValue* value) const
{
const AnimatableLengthBox* lengthBox = toAnimatableLengthBox(value);
@@ -62,4 +52,13 @@ bool AnimatableLengthBox::equalTo(const AnimatableValue* value) const
&& bottom()->equals(lengthBox->bottom());
}
+void AnimatableLengthBox::trace(Visitor* visitor)
+{
+ visitor->trace(m_left);
+ visitor->trace(m_right);
+ visitor->trace(m_top);
+ visitor->trace(m_bottom);
+ AnimatableValue::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.h
index b7ea5be5f6a..f796e753bc3 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBox.h
@@ -35,24 +35,25 @@
namespace WebCore {
-class AnimatableLengthBox : public AnimatableValue {
+class AnimatableLengthBox FINAL : public AnimatableValue {
public:
virtual ~AnimatableLengthBox() { }
- static PassRefPtr<AnimatableLengthBox> create(PassRefPtr<AnimatableValue> left, PassRefPtr<AnimatableValue> right, PassRefPtr<AnimatableValue> top, PassRefPtr<AnimatableValue> bottom)
+ static PassRefPtrWillBeRawPtr<AnimatableLengthBox> create(PassRefPtrWillBeRawPtr<AnimatableValue> left, PassRefPtrWillBeRawPtr<AnimatableValue> right, PassRefPtrWillBeRawPtr<AnimatableValue> top, PassRefPtrWillBeRawPtr<AnimatableValue> bottom)
{
- return adoptRef(new AnimatableLengthBox(left, right, top, bottom));
+ return adoptRefWillBeNoop(new AnimatableLengthBox(left, right, top, bottom));
}
const AnimatableValue* left() const { return m_left.get(); }
const AnimatableValue* right() const { return m_right.get(); }
const AnimatableValue* top() const { return m_top.get(); }
const AnimatableValue* bottom() const { return m_bottom.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
- AnimatableLengthBox(PassRefPtr<AnimatableValue> left, PassRefPtr<AnimatableValue> right, PassRefPtr<AnimatableValue> top, PassRefPtr<AnimatableValue> bottom)
+ AnimatableLengthBox(PassRefPtrWillBeRawPtr<AnimatableValue> left, PassRefPtrWillBeRawPtr<AnimatableValue> right, PassRefPtrWillBeRawPtr<AnimatableValue> top, PassRefPtrWillBeRawPtr<AnimatableValue> bottom)
: m_left(left)
, m_right(right)
, m_top(top)
@@ -62,10 +63,10 @@ private:
virtual AnimatableType type() const OVERRIDE { return TypeLengthBox; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- RefPtr<AnimatableValue> m_left;
- RefPtr<AnimatableValue> m_right;
- RefPtr<AnimatableValue> m_top;
- RefPtr<AnimatableValue> m_bottom;
+ RefPtrWillBeMember<AnimatableValue> m_left;
+ RefPtrWillBeMember<AnimatableValue> m_right;
+ RefPtrWillBeMember<AnimatableValue> m_top;
+ RefPtrWillBeMember<AnimatableValue> m_bottom;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableLengthBox, isLengthBox());
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.cpp
index da92ac24181..c598ec435a9 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.cpp
@@ -33,26 +33,23 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableLengthBoxAndBool::interpolateTo(const AnimatableValue* value, double fraction) const
+bool AnimatableLengthBoxAndBool::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
const AnimatableLengthBoxAndBool* lengthBox = toAnimatableLengthBoxAndBool(value);
- if (lengthBox->flag() == flag()) {
- return AnimatableLengthBoxAndBool::create(
- AnimatableValue::interpolate(box(), lengthBox->box(), fraction),
- flag());
- }
- return defaultInterpolateTo(this, value, fraction);
+ if (lengthBox->flag() != flag())
+ return true;
+ return AnimatableValue::usesDefaultInterpolation(lengthBox->box(), box());
}
-PassRefPtr<AnimatableValue> AnimatableLengthBoxAndBool::addWith(const AnimatableValue* value) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableLengthBoxAndBool::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableLengthBoxAndBool* lengthBox = toAnimatableLengthBoxAndBool(value);
if (lengthBox->flag() == flag()) {
return AnimatableLengthBoxAndBool::create(
- AnimatableValue::add(box(), lengthBox->box()),
+ AnimatableValue::interpolate(box(), lengthBox->box(), fraction),
flag());
}
- return defaultAddWith(this, value);
+ return defaultInterpolateTo(this, value, fraction);
}
bool AnimatableLengthBoxAndBool::equalTo(const AnimatableValue* value) const
@@ -61,4 +58,10 @@ bool AnimatableLengthBoxAndBool::equalTo(const AnimatableValue* value) const
return box()->equals(lengthBox->box()) && flag() == lengthBox->flag();
}
+void AnimatableLengthBoxAndBool::trace(Visitor* visitor)
+{
+ visitor->trace(m_box);
+ AnimatableValue::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.h
index 9e3379791fd..76bd94c097e 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthBoxAndBool.h
@@ -35,22 +35,24 @@
namespace WebCore {
-class AnimatableLengthBoxAndBool : public AnimatableValue {
+class AnimatableLengthBoxAndBool FINAL : public AnimatableValue {
public:
virtual ~AnimatableLengthBoxAndBool() { }
- static PassRefPtr<AnimatableLengthBoxAndBool> create(PassRefPtr<AnimatableValue> box, bool flag)
+ static PassRefPtrWillBeRawPtr<AnimatableLengthBoxAndBool> create(PassRefPtrWillBeRawPtr<AnimatableValue> box, bool flag)
{
- return adoptRef(new AnimatableLengthBoxAndBool(box, flag));
+ return adoptRefWillBeNoop(new AnimatableLengthBoxAndBool(box, flag));
}
const AnimatableValue* box() const { return m_box.get(); }
bool flag() const { return m_flag; }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
- AnimatableLengthBoxAndBool(PassRefPtr<AnimatableValue> box, bool flag)
+ AnimatableLengthBoxAndBool(PassRefPtrWillBeRawPtr<AnimatableValue> box, bool flag)
: m_box(box)
, m_flag(flag)
{
@@ -58,7 +60,7 @@ private:
virtual AnimatableType type() const OVERRIDE { return TypeLengthBoxAndBool; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- RefPtr<AnimatableValue> m_box;
+ RefPtrWillBeMember<AnimatableValue> m_box;
bool m_flag;
};
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.cpp
index e779699d93d..b8805d05685 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.cpp
@@ -33,7 +33,7 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableLengthPoint::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableLengthPoint::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableLengthPoint* lengthPoint = toAnimatableLengthPoint(value);
return AnimatableLengthPoint::create(
@@ -41,18 +41,17 @@ PassRefPtr<AnimatableValue> AnimatableLengthPoint::interpolateTo(const Animatabl
AnimatableValue::interpolate(this->y(), lengthPoint->y(), fraction));
}
-PassRefPtr<AnimatableValue> AnimatableLengthPoint::addWith(const AnimatableValue* value) const
+bool AnimatableLengthPoint::equalTo(const AnimatableValue* value) const
{
const AnimatableLengthPoint* lengthPoint = toAnimatableLengthPoint(value);
- return AnimatableLengthPoint::create(
- AnimatableValue::add(this->x(), lengthPoint->x()),
- AnimatableValue::add(this->y(), lengthPoint->y()));
+ return x()->equals(lengthPoint->x()) && y()->equals(lengthPoint->y());
}
-bool AnimatableLengthPoint::equalTo(const AnimatableValue* value) const
+void AnimatableLengthPoint::trace(Visitor* visitor)
{
- const AnimatableLengthPoint* lengthPoint = toAnimatableLengthPoint(value);
- return x()->equals(lengthPoint->x()) && y()->equals(lengthPoint->y());
+ visitor->trace(m_x);
+ visitor->trace(m_y);
+ AnimatableValue::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.h
index 60b3e03f152..f2f479b11ef 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint.h
@@ -35,22 +35,23 @@
namespace WebCore {
-class AnimatableLengthPoint : public AnimatableValue {
+class AnimatableLengthPoint FINAL : public AnimatableValue {
public:
virtual ~AnimatableLengthPoint() { }
- static PassRefPtr<AnimatableLengthPoint> create(PassRefPtr<AnimatableValue> x, PassRefPtr<AnimatableValue> y)
+ static PassRefPtrWillBeRawPtr<AnimatableLengthPoint> create(PassRefPtrWillBeRawPtr<AnimatableValue> x, PassRefPtrWillBeRawPtr<AnimatableValue> y)
{
- return adoptRef(new AnimatableLengthPoint(x, y));
+ return adoptRefWillBeNoop(new AnimatableLengthPoint(x, y));
}
const AnimatableValue* x() const { return m_x.get(); }
const AnimatableValue* y() const { return m_y.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
- AnimatableLengthPoint(PassRefPtr<AnimatableValue> x, PassRefPtr<AnimatableValue> y)
+ AnimatableLengthPoint(PassRefPtrWillBeRawPtr<AnimatableValue> x, PassRefPtrWillBeRawPtr<AnimatableValue> y)
: m_x(x)
, m_y(y)
{
@@ -58,8 +59,8 @@ private:
virtual AnimatableType type() const OVERRIDE { return TypeLengthPoint; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- RefPtr<AnimatableValue> m_x;
- RefPtr<AnimatableValue> m_y;
+ RefPtrWillBeMember<AnimatableValue> m_x;
+ RefPtrWillBeMember<AnimatableValue> m_y;
};
inline const AnimatableLengthPoint* toAnimatableLengthPoint(const AnimatableValue* value)
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint3D.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint3D.cpp
new file mode 100644
index 00000000000..402f0a8a707
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint3D.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/AnimatableLengthPoint3D.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableLengthPoint3D::interpolateTo(const AnimatableValue* value, double fraction) const
+{
+ const AnimatableLengthPoint3D* lengthPoint = toAnimatableLengthPoint3D(value);
+ return AnimatableLengthPoint3D::create(
+ AnimatableValue::interpolate(this->x(), lengthPoint->x(), fraction),
+ AnimatableValue::interpolate(this->y(), lengthPoint->y(), fraction),
+ AnimatableValue::interpolate(this->z(), lengthPoint->z(), fraction));
+}
+
+bool AnimatableLengthPoint3D::equalTo(const AnimatableValue* value) const
+{
+ const AnimatableLengthPoint3D* lengthPoint = toAnimatableLengthPoint3D(value);
+ return x()->equals(lengthPoint->x()) && y()->equals(lengthPoint->y()) && z()->equals(lengthPoint->z());
+}
+
+void AnimatableLengthPoint3D::trace(Visitor* visitor)
+{
+ visitor->trace(m_x);
+ visitor->trace(m_y);
+ visitor->trace(m_z);
+ AnimatableValue::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint3D.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint3D.h
new file mode 100644
index 00000000000..0e3650ffae5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthPoint3D.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AnimatableLengthPoint3D_h
+#define AnimatableLengthPoint3D_h
+
+#include "core/animation/AnimatableValue.h"
+
+namespace WebCore {
+
+class AnimatableLengthPoint3D FINAL : public AnimatableValue {
+public:
+ virtual ~AnimatableLengthPoint3D() { }
+ static PassRefPtrWillBeRawPtr<AnimatableLengthPoint3D> create(PassRefPtrWillBeRawPtr<AnimatableValue> x, PassRefPtrWillBeRawPtr<AnimatableValue> y, PassRefPtrWillBeRawPtr<AnimatableValue> z)
+ {
+ return adoptRefWillBeNoop(new AnimatableLengthPoint3D(x, y, z));
+ }
+ const AnimatableValue* x() const { return m_x.get(); }
+ const AnimatableValue* y() const { return m_y.get(); }
+ const AnimatableValue* z() const { return m_z.get(); }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+protected:
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+
+private:
+ AnimatableLengthPoint3D(PassRefPtrWillBeRawPtr<AnimatableValue> x, PassRefPtrWillBeRawPtr<AnimatableValue> y, PassRefPtrWillBeRawPtr<AnimatableValue> z)
+ : m_x(x)
+ , m_y(y)
+ , m_z(z)
+ {
+ }
+ virtual AnimatableType type() const OVERRIDE { return TypeLengthPoint3D; }
+ virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
+
+ RefPtrWillBeMember<AnimatableValue> m_x;
+ RefPtrWillBeMember<AnimatableValue> m_y;
+ RefPtrWillBeMember<AnimatableValue> m_z;
+};
+
+inline const AnimatableLengthPoint3D* toAnimatableLengthPoint3D(const AnimatableValue* value)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(value && value->isLengthPoint3D());
+ return static_cast<const AnimatableLengthPoint3D*>(value);
+}
+
+} // namespace WebCore
+
+#endif // AnimatableLengthPoint3D_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.cpp
index b422f39a931..c63239536c0 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.cpp
@@ -33,7 +33,7 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableLengthSize::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableLengthSize::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableLengthSize* lengthSize = toAnimatableLengthSize(value);
return AnimatableLengthSize::create(
@@ -41,18 +41,17 @@ PassRefPtr<AnimatableValue> AnimatableLengthSize::interpolateTo(const Animatable
AnimatableValue::interpolate(this->height(), lengthSize->height(), fraction));
}
-PassRefPtr<AnimatableValue> AnimatableLengthSize::addWith(const AnimatableValue* value) const
+bool AnimatableLengthSize::equalTo(const AnimatableValue* value) const
{
const AnimatableLengthSize* lengthSize = toAnimatableLengthSize(value);
- return AnimatableLengthSize::create(
- AnimatableValue::add(this->width(), lengthSize->width()),
- AnimatableValue::add(this->height(), lengthSize->height()));
+ return width()->equals(lengthSize->width()) && height()->equals(lengthSize->height());
}
-bool AnimatableLengthSize::equalTo(const AnimatableValue* value) const
+void AnimatableLengthSize::trace(Visitor* visitor)
{
- const AnimatableLengthSize* lengthSize = toAnimatableLengthSize(value);
- return width()->equals(lengthSize->width()) && height()->equals(lengthSize->height());
+ visitor->trace(m_width);
+ visitor->trace(m_height);
+ AnimatableValue::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.h
index 55dcc4090d3..a572468e18e 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthSize.h
@@ -35,22 +35,23 @@
namespace WebCore {
-class AnimatableLengthSize : public AnimatableValue {
+class AnimatableLengthSize FINAL : public AnimatableValue {
public:
virtual ~AnimatableLengthSize() { }
- static PassRefPtr<AnimatableLengthSize> create(PassRefPtr<AnimatableValue> width, PassRefPtr<AnimatableValue> height)
+ static PassRefPtrWillBeRawPtr<AnimatableLengthSize> create(PassRefPtrWillBeRawPtr<AnimatableValue> width, PassRefPtrWillBeRawPtr<AnimatableValue> height)
{
- return adoptRef(new AnimatableLengthSize(width, height));
+ return adoptRefWillBeNoop(new AnimatableLengthSize(width, height));
}
const AnimatableValue* width() const { return m_width.get(); }
const AnimatableValue* height() const { return m_height.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
- AnimatableLengthSize(PassRefPtr<AnimatableValue> width, PassRefPtr<AnimatableValue> height)
+ AnimatableLengthSize(PassRefPtrWillBeRawPtr<AnimatableValue> width, PassRefPtrWillBeRawPtr<AnimatableValue> height)
: m_width(width)
, m_height(height)
{
@@ -58,8 +59,8 @@ private:
virtual AnimatableType type() const OVERRIDE { return TypeLengthSize; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- RefPtr<AnimatableValue> m_width;
- RefPtr<AnimatableValue> m_height;
+ RefPtrWillBeMember<AnimatableValue> m_width;
+ RefPtrWillBeMember<AnimatableValue> m_height;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableLengthSize, isLengthSize());
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthTest.cpp
index 3574a66279b..c5887e239c8 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableLengthTest.cpp
@@ -1,367 +1,73 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "config.h"
#include "core/animation/AnimatableLength.h"
-
-#include "core/animation/AnimatableValueTestHelper.h"
-#include "core/css/CSSCalculationValue.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/css/CSSToLengthConversionData.h"
-#include "core/rendering/style/RenderStyle.h"
-#include "core/rendering/style/StyleInheritedData.h"
#include "platform/CalculationValue.h"
-#include "wtf/MathExtras.h"
#include <gtest/gtest.h>
-#define EXPECT_ROUNDTRIP(a, f) EXPECT_REFV_EQ(a, f(a.get()))
-
namespace WebCore {
-class AnimationAnimatableLengthTest : public ::testing::Test {
-protected:
- AnimationAnimatableLengthTest()
- : style(RenderStyle::createDefaultStyle())
- , conversionDataZoom1(style.get(), style.get(), 1.0f)
- , conversionDataZoom3(style.get(), style.get(), 3.0f)
- {
- }
-
- PassRefPtr<AnimatableLength> create(double value, CSSPrimitiveValue::UnitTypes type)
- {
- return AnimatableLength::create(CSSPrimitiveValue::create(value, type).get());
- }
-
- PassRefPtr<AnimatableLength> create(double valueLeft, CSSPrimitiveValue::UnitTypes typeLeft, double valueRight, CSSPrimitiveValue::UnitTypes typeRight)
- {
- return AnimatableLength::create(createCalc(valueLeft, typeLeft, valueRight, typeRight).get());
- }
-
- PassRefPtr<CSSCalcValue> createCalc(double valueLeft, CSSPrimitiveValue::UnitTypes typeLeft, double valueRight, CSSPrimitiveValue::UnitTypes typeRight)
- {
- return CSSCalcValue::create(CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(valueLeft, typeLeft), valueLeft == trunc(valueLeft)),
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(valueRight, typeRight), valueRight == trunc(valueRight)),
- CalcAdd
- ));
- }
-
- PassRefPtr<CSSValue> toCSSValue(CSSValue* cssValue)
- {
- return AnimatableLength::create(cssValue)->toCSSValue();
- }
-
- AnimatableLength::NumberUnitType commonUnitType(PassRefPtr<AnimatableLength> a, PassRefPtr<AnimatableLength> b)
- {
- return a->commonUnitType(b.get());
- }
+namespace {
- bool isUnitlessZero(PassRefPtr<AnimatableLength> a)
+ PassRefPtrWillBeRawPtr<AnimatableLength> create(const Length& length, double zoom = 1)
{
- return a->isUnitlessZero();
+ return AnimatableLength::create(length, zoom);
}
- RefPtr<RenderStyle> style;
- CSSToLengthConversionData conversionDataZoom1;
- CSSToLengthConversionData conversionDataZoom3;
-};
-
-TEST_F(AnimationAnimatableLengthTest, CanCreateFrom)
-{
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_MM).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_IN).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PT).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PC).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_EXS).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_REMS).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VW).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VH).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VMIN).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_VMAX).get()));
-
- EXPECT_TRUE(AnimatableLength::canCreateFrom(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_TRUE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM)).get()));
-
- EXPECT_FALSE(AnimatableLength::canCreateFrom(CSSPrimitiveValue::create("NaN", CSSPrimitiveValue::CSS_STRING).get()));
-}
-
-TEST_F(AnimationAnimatableLengthTest, Create)
-{
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_MM).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_IN).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PT).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PC).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_EXS).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_REMS).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VW).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VH).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VMIN).get()));
- EXPECT_TRUE(static_cast<bool>(create(5, CSSPrimitiveValue::CSS_VMAX).get()));
-
- EXPECT_TRUE(static_cast<bool>(
- AnimatableLength::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()).get()
- ));
- EXPECT_TRUE(static_cast<bool>(
- AnimatableLength::create(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM)).get()).get()
- ));
-}
-
-
-TEST_F(AnimationAnimatableLengthTest, ToCSSValue)
-{
-
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PX), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_CM), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_MM), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_IN), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PT), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PC), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_EMS), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_EXS), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_REMS), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_PERCENTAGE), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VW), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VH), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VMIN), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(-5, CSSPrimitiveValue::CSS_VMAX), toCSSValue);
-
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_IN)), toCSSValue);
- EXPECT_ROUNDTRIP(CSSPrimitiveValue::create(createCalc(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_IN)), toCSSValue);
-}
-
+} // namespace
-TEST_F(AnimationAnimatableLengthTest, ToLength)
+TEST(AnimationAnimatableLengthTest, RoundTripConversion)
{
- EXPECT_EQ(Length(-5, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom1));
- EXPECT_EQ(Length(-15, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom3));
- EXPECT_EQ(Length(0, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom1, NonNegativeValues));
- EXPECT_EQ(Length(0, WebCore::Fixed), create(-5, CSSPrimitiveValue::CSS_PX)->toLength(conversionDataZoom3, NonNegativeValues));
-
- EXPECT_EQ(Length(-5, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1));
- EXPECT_EQ(Length(-5, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3));
- EXPECT_EQ(Length(0, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1, NonNegativeValues));
- EXPECT_EQ(Length(0, Percent), create(-5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3, NonNegativeValues));
-
- EXPECT_EQ(
- Length(CalculationValue::create(
- adoptPtr(new CalcExpressionBinaryOperation(
- adoptPtr(new CalcExpressionLength(Length(-5, WebCore::Fixed))),
- adoptPtr(new CalcExpressionLength(Length(-5, Percent))),
- CalcAdd)),
- ValueRangeAll)),
- create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1));
- EXPECT_EQ(
- Length(CalculationValue::create(
- adoptPtr(new CalcExpressionBinaryOperation(
- adoptPtr(new CalcExpressionLength(Length(-15, WebCore::Fixed))),
- adoptPtr(new CalcExpressionLength(Length(-5, Percent))),
- CalcAdd)),
- ValueRangeAll)),
- create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3));
- EXPECT_EQ(
- Length(CalculationValue::create(
- adoptPtr(new CalcExpressionBinaryOperation(
- adoptPtr(new CalcExpressionLength(Length(-5, WebCore::Fixed))),
- adoptPtr(new CalcExpressionLength(Length(-5, Percent))),
- CalcAdd)),
- ValueRangeNonNegative)),
- create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom1, NonNegativeValues));
- EXPECT_EQ(
- Length(CalculationValue::create(
- adoptPtr(new CalcExpressionBinaryOperation(
- adoptPtr(new CalcExpressionLength(Length(-15, WebCore::Fixed))),
- adoptPtr(new CalcExpressionLength(Length(-5, Percent))),
- CalcAdd)),
- ValueRangeNonNegative)),
- create(-5, CSSPrimitiveValue::CSS_PX, -5, CSSPrimitiveValue::CSS_PERCENTAGE)->toLength(conversionDataZoom3, NonNegativeValues));
+ EXPECT_EQ(Length(0, Fixed), create(Length(0, Fixed))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(0, Percent), create(Length(0, Percent))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(10, Fixed), create(Length(10, Fixed))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(10, Percent), create(Length(10, Percent))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(-10, Fixed), create(Length(-10, Fixed))->length(1, ValueRangeAll));
+ EXPECT_EQ(Length(-10, Percent), create(Length(-10, Percent))->length(1, ValueRangeAll));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(5, 10), ValueRangeAll));
+ EXPECT_EQ(calc, create(calc)->length(1, ValueRangeAll));
}
-TEST_F(AnimationAnimatableLengthTest, Interpolate)
+TEST(AnimationAnimatableLengthTest, ValueRangeNonNegative)
{
- RefPtr<AnimatableLength> from10px = create(10, CSSPrimitiveValue::CSS_PX);
- RefPtr<AnimatableLength> to20pxAsInches = create(20.0 / 96, CSSPrimitiveValue::CSS_IN);
-
- EXPECT_REFV_EQ(create(5, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), -0.5));
-
- EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 0));
- EXPECT_REFV_EQ(create(14, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 0.4));
- EXPECT_REFV_EQ(create(15, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 0.5));
- EXPECT_REFV_EQ(create(16, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 0.6));
- EXPECT_REFV_EQ(create(20.0 / 96, CSSPrimitiveValue::CSS_IN),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 1));
- EXPECT_REFV_EQ(create(25, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from10px.get(), to20pxAsInches.get(), 1.5));
-
- RefPtr<AnimatableLength> from10em = create(10, CSSPrimitiveValue::CSS_EMS);
- RefPtr<AnimatableLength> to20rem = create(20, CSSPrimitiveValue::CSS_REMS);
- EXPECT_REFV_EQ(create(15, CSSPrimitiveValue::CSS_EMS, -10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), -0.5));
- EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_EMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 0));
- EXPECT_REFV_EQ(create(6, CSSPrimitiveValue::CSS_EMS, 8, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 0.4));
- EXPECT_REFV_EQ(create(5, CSSPrimitiveValue::CSS_EMS, 10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 0.5));
- EXPECT_REFV_EQ(create(4, CSSPrimitiveValue::CSS_EMS, 12, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 0.6));
- EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 1));
- EXPECT_REFV_EQ(create(-5, CSSPrimitiveValue::CSS_EMS, 30, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from10em.get(), to20rem.get(), 1.5));
-
- // Zero values are typeless and hence we can don't get a calc
- RefPtr<AnimatableLength> from0px = create(0, CSSPrimitiveValue::CSS_PX);
- EXPECT_REFV_EQ(create(-10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), -0.5));
- // At t=0, interpolate always returns the "from" value.
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), 0));
- EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), 0.5));
- EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), 1.0));
- EXPECT_REFV_EQ(create(30, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0px.get(), to20rem.get(), 1.5));
-
- // Except 0% which is special
- RefPtr<AnimatableLength> from0percent = create(0, CSSPrimitiveValue::CSS_PERCENTAGE);
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, -10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), -0.5));
- // At t=0, interpolate always returns the "from" value.
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 0));
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, 10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 0.5));
- // At t=1, interpolate always returns the "to" value.
- EXPECT_REFV_EQ(create(20, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 1.0));
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, 30, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::interpolate(from0percent.get(), to20rem.get(), 1.5));
+ EXPECT_EQ(Length(10, Fixed), create(Length(10, Fixed))->length(1, ValueRangeNonNegative));
+ EXPECT_EQ(Length(10, Percent), create(Length(10, Percent))->length(1, ValueRangeNonNegative));
+ EXPECT_EQ(Length(0, Fixed), create(Length(-10, Fixed))->length(1, ValueRangeNonNegative));
+ EXPECT_EQ(Length(0, Percent), create(Length(-10, Percent))->length(1, ValueRangeNonNegative));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(-5, -10), ValueRangeNonNegative));
+ EXPECT_TRUE(calc == create(calc)->length(1, ValueRangeNonNegative));
}
-TEST_F(AnimationAnimatableLengthTest, Add)
+TEST(AnimationAnimatableLengthTest, Zoom)
{
- EXPECT_REFV_EQ(create(10, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::add(create(10, CSSPrimitiveValue::CSS_PX).get(), create(0, CSSPrimitiveValue::CSS_MM).get()));
- EXPECT_REFV_EQ(create(100, CSSPrimitiveValue::CSS_PX),
- AnimatableValue::add(create(4, CSSPrimitiveValue::CSS_PX).get(), create(1, CSSPrimitiveValue::CSS_IN).get()));
- EXPECT_REFV_EQ(
- create(10, CSSPrimitiveValue::CSS_EMS, 20, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::add(create(10, CSSPrimitiveValue::CSS_EMS).get(), create(20, CSSPrimitiveValue::CSS_REMS).get()));
- EXPECT_REFV_EQ(
- create(10, CSSPrimitiveValue::CSS_EMS),
- AnimatableValue::add(create(10, CSSPrimitiveValue::CSS_EMS).get(), create(0, CSSPrimitiveValue::CSS_REMS).get()));
- EXPECT_REFV_EQ(
- create(20, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::add(create(0, CSSPrimitiveValue::CSS_EMS).get(), create(20, CSSPrimitiveValue::CSS_REMS).get()));
-
- // Check you actually get the reference back for zero optimization
- RefPtr<AnimatableLength> rems20 = create(20, CSSPrimitiveValue::CSS_REMS);
- EXPECT_EQ(rems20.get(), AnimatableValue::add(create(0, CSSPrimitiveValue::CSS_EMS).get(), rems20.get()).get());
- EXPECT_EQ(rems20.get(), AnimatableValue::add(rems20.get(), create(0, CSSPrimitiveValue::CSS_EMS).get()).get());
-
- // Except 0% which is special
- RefPtr<AnimatableLength> zeropercent = create(0, CSSPrimitiveValue::CSS_PERCENTAGE);
- EXPECT_REFV_EQ(create(0, CSSPrimitiveValue::CSS_PERCENTAGE, -10, CSSPrimitiveValue::CSS_REMS),
- AnimatableValue::add(zeropercent.get(), create(-10, CSSPrimitiveValue::CSS_REMS).get()));
- EXPECT_REFV_EQ(create(-10, CSSPrimitiveValue::CSS_REMS, 0, CSSPrimitiveValue::CSS_PERCENTAGE),
- AnimatableValue::add(create(-10, CSSPrimitiveValue::CSS_REMS).get(), zeropercent.get()));
+ EXPECT_EQ(Length(4, Fixed), create(Length(10, Fixed), 5)->length(2, ValueRangeAll));
+ EXPECT_EQ(Length(10, Percent), create(Length(10, Percent), 5)->length(2, ValueRangeAll));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(5, 10), ValueRangeAll));
+ Length result = Length(CalculationValue::create(PixelsAndPercent(2, 10), ValueRangeAll));
+ EXPECT_TRUE(result == create(calc, 5)->length(2, ValueRangeAll));
}
-TEST_F(AnimationAnimatableLengthTest, IsUnitless)
+TEST(AnimationAnimatableLengthTest, Equals)
{
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_PX)));
- EXPECT_FALSE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_PERCENTAGE)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_EMS)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_EXS)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_REMS)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VW)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VH)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VMIN)));
- EXPECT_TRUE(isUnitlessZero(create(0, CSSPrimitiveValue::CSS_VMAX)));
-
- EXPECT_FALSE(isUnitlessZero(create(1, CSSPrimitiveValue::CSS_PX)));
- EXPECT_FALSE(isUnitlessZero(create(2, CSSPrimitiveValue::CSS_PERCENTAGE)));
- EXPECT_FALSE(isUnitlessZero(create(3, CSSPrimitiveValue::CSS_EMS)));
- EXPECT_FALSE(isUnitlessZero(create(4, CSSPrimitiveValue::CSS_EXS)));
- EXPECT_FALSE(isUnitlessZero(create(5, CSSPrimitiveValue::CSS_REMS)));
- EXPECT_FALSE(isUnitlessZero(create(6, CSSPrimitiveValue::CSS_VW)));
- EXPECT_FALSE(isUnitlessZero(create(7, CSSPrimitiveValue::CSS_VH)));
- EXPECT_FALSE(isUnitlessZero(create(8, CSSPrimitiveValue::CSS_VMIN)));
- EXPECT_FALSE(isUnitlessZero(create(9, CSSPrimitiveValue::CSS_VMAX)));
+ EXPECT_TRUE(create(Length(10, Fixed))->equals(create(Length(10, Fixed)).get()));
+ EXPECT_TRUE(create(Length(20, Percent))->equals(create(Length(20, Percent)).get()));
+ EXPECT_FALSE(create(Length(10, Fixed))->equals(create(Length(10, Percent)).get()));
+ EXPECT_FALSE(create(Length(0, Percent))->equals(create(Length(0, Fixed)).get()));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(5, 10), ValueRangeAll));
+ EXPECT_TRUE(create(calc)->equals(create(calc).get()));
+ EXPECT_FALSE(create(calc)->equals(create(Length(10, Percent)).get()));
}
-TEST_F(AnimationAnimatableLengthTest, CommonUnitType)
+TEST(AnimationAnimatableLengthTest, Interpolate)
{
- RefPtr<AnimatableLength> length10px = create(10, CSSPrimitiveValue::CSS_PX);
- EXPECT_EQ(AnimatableLength::UnitTypePixels, commonUnitType(length10px, create(1, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length10px, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length10px, create(3, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length10px, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length10px, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
-
- RefPtr<AnimatableLength> length0px = create(0, CSSPrimitiveValue::CSS_PX);
- EXPECT_EQ(AnimatableLength::UnitTypePixels, commonUnitType(length0px, create(1, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_EQ(AnimatableLength::UnitTypePercentage, commonUnitType(length0px, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeFontSize, commonUnitType(length0px, create(3, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length0px, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_EQ(AnimatableLength::UnitTypePercentage, commonUnitType(length0px, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
-
- RefPtr<AnimatableLength> length0percent = create(0, CSSPrimitiveValue::CSS_PERCENTAGE);
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length0percent, create(1, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_EQ(AnimatableLength::UnitTypePercentage, commonUnitType(length0percent, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length0percent, create(3, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(length0percent, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_EQ(AnimatableLength::UnitTypePercentage, commonUnitType(length0percent, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
-
- RefPtr<AnimatableLength> lengthCalc = create(3, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM);
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(1, CSSPrimitiveValue::CSS_PX).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(2, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(3, CSSPrimitiveValue::CSS_EMS).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(4, CSSPrimitiveValue::CSS_PX, 5, CSSPrimitiveValue::CSS_CM).get()));
- EXPECT_EQ(AnimatableLength::UnitTypeCalc, commonUnitType(lengthCalc, create(0, CSSPrimitiveValue::CSS_PERCENTAGE).get()));
+ EXPECT_TRUE(AnimatableValue::interpolate(create(Length(10, Fixed)).get(), create(Length(0, Fixed)).get(), 0.2)->equals(create(Length(8, Fixed)).get()));
+ EXPECT_TRUE(AnimatableValue::interpolate(create(Length(4, Percent)).get(), create(Length(12, Percent)).get(), 0.25)->equals(create(Length(6, Percent)).get()));
+ Length calc = Length(CalculationValue::create(PixelsAndPercent(12, 4), ValueRangeAll));
+ EXPECT_TRUE(AnimatableValue::interpolate(create(Length(20, Fixed)).get(), create(Length(10, Percent)).get(), 0.4)->equals(create(calc).get()));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableNeutral.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableNeutral.h
index 5b8759ce45b..16f8595b29f 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableNeutral.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableNeutral.h
@@ -35,16 +35,18 @@
namespace WebCore {
-class AnimatableNeutral : public AnimatableValue {
+class AnimatableNeutral FINAL : public AnimatableValue {
public:
virtual ~AnimatableNeutral() { }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- static PassRefPtr<AnimatableNeutral> create() { return adoptRef(new AnimatableNeutral()); }
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue* value, double fraction) const OVERRIDE
+ static PassRefPtrWillBeRawPtr<AnimatableNeutral> create() { return adoptRefWillBeNoop(new AnimatableNeutral()); }
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue* value, double fraction) const OVERRIDE
{
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
private:
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableNeutralTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableNeutralTest.cpp
index dbf685ab8fd..755aa77e514 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableNeutralTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableNeutralTest.cpp
@@ -45,13 +45,4 @@ TEST(AnimationAnimatableNeutralTest, Create)
EXPECT_TRUE(AnimatableValue::neutralValue());
}
-TEST(AnimationAnimatableNeutralTest, Add)
-{
- RefPtr<CSSValue> cssValue = CSSArrayFunctionValue::create();
- RefPtr<AnimatableValue> animatableUnknown = AnimatableUnknown::create(cssValue);
-
- EXPECT_EQ(cssValue, toAnimatableUnknown(AnimatableValue::add(animatableUnknown.get(), AnimatableValue::neutralValue()).get())->toCSSValue());
- EXPECT_EQ(cssValue, toAnimatableUnknown(AnimatableValue::add(AnimatableValue::neutralValue(), animatableUnknown.get()).get())->toCSSValue());
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.cpp
index a9f1ae6d982..2c2f63e4e8b 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.cpp
@@ -31,63 +31,57 @@
#include "config.h"
#include "core/animation/AnimatableRepeatable.h"
-namespace {
+#include "wtf/MathExtras.h"
-size_t greatestCommonDivisor(size_t a, size_t b)
-{
- return b ? greatestCommonDivisor(b, a % b) : a;
-}
+namespace WebCore {
-size_t lowestCommonMultiple(size_t a, size_t b)
+bool AnimatableRepeatable::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
- ASSERT(a && b);
- return a / greatestCommonDivisor(a, b) * b;
+ const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& fromValues = m_values;
+ const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& toValues = toAnimatableRepeatable(value)->m_values;
+ ASSERT(!fromValues.isEmpty() && !toValues.isEmpty());
+ size_t size = lowestCommonMultiple(fromValues.size(), toValues.size());
+ ASSERT(size > 0);
+ for (size_t i = 0; i < size; ++i) {
+ const AnimatableValue* from = fromValues[i % fromValues.size()].get();
+ const AnimatableValue* to = toValues[i % toValues.size()].get();
+ // Spec: If a pair of values cannot be interpolated, then the lists are not interpolable.
+ if (AnimatableValue::usesDefaultInterpolation(from, to))
+ return true;
+ }
+ return false;
}
-} // namespace
-
-namespace WebCore {
-
-bool AnimatableRepeatable::interpolateLists(const Vector<RefPtr<AnimatableValue> >& fromValues, const Vector<RefPtr<AnimatableValue> >& toValues, double fraction, Vector<RefPtr<AnimatableValue> >& interpolatedValues)
+bool AnimatableRepeatable::interpolateLists(const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& fromValues, const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& toValues, double fraction, WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& interpolatedValues)
{
// Interpolation behaviour spec: http://www.w3.org/TR/css3-transitions/#animtype-repeatable-list
ASSERT(interpolatedValues.isEmpty());
ASSERT(!fromValues.isEmpty() && !toValues.isEmpty());
size_t size = lowestCommonMultiple(fromValues.size(), toValues.size());
+ ASSERT(size > 0);
for (size_t i = 0; i < size; ++i) {
const AnimatableValue* from = fromValues[i % fromValues.size()].get();
const AnimatableValue* to = toValues[i % toValues.size()].get();
// Spec: If a pair of values cannot be interpolated, then the lists are not interpolable.
- if (!from->usesNonDefaultInterpolationWith(to))
+ if (AnimatableValue::usesDefaultInterpolation(from, to))
return false;
interpolatedValues.append(interpolate(from, to, fraction));
}
return true;
}
-PassRefPtr<AnimatableValue> AnimatableRepeatable::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableRepeatable::interpolateTo(const AnimatableValue* value, double fraction) const
{
- Vector<RefPtr<AnimatableValue> > interpolatedValues;
+ WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> > interpolatedValues;
bool success = interpolateLists(m_values, toAnimatableRepeatable(value)->m_values, fraction, interpolatedValues);
- return success ? create(interpolatedValues) : defaultInterpolateTo(this, value, fraction);
-}
-
-PassRefPtr<AnimatableValue> AnimatableRepeatable::addWith(const AnimatableValue* value) const
-{
- const Vector<RefPtr<AnimatableValue> >& otherValues = toAnimatableRepeatable(value)->m_values;
- ASSERT(!m_values.isEmpty() && !otherValues.isEmpty());
- Vector<RefPtr<AnimatableValue> > addedValues(lowestCommonMultiple(m_values.size(), otherValues.size()));
- for (size_t i = 0; i < addedValues.size(); ++i) {
- const AnimatableValue* left = m_values[i % m_values.size()].get();
- const AnimatableValue* right = otherValues[i % otherValues.size()].get();
- addedValues[i] = add(left, right);
- }
- return create(addedValues);
+ if (success)
+ return create(interpolatedValues);
+ return defaultInterpolateTo(this, value, fraction);
}
bool AnimatableRepeatable::equalTo(const AnimatableValue* value) const
{
- const Vector<RefPtr<AnimatableValue> >& otherValues = toAnimatableRepeatable(value)->m_values;
+ const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& otherValues = toAnimatableRepeatable(value)->m_values;
if (m_values.size() != otherValues.size())
return false;
for (size_t i = 0; i < m_values.size(); ++i) {
@@ -97,4 +91,10 @@ bool AnimatableRepeatable::equalTo(const AnimatableValue* value) const
return true;
}
+void AnimatableRepeatable::trace(Visitor* visitor)
+{
+ visitor->trace(m_values);
+ AnimatableValue::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.h
index b1c74949c11..317fbfc113f 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableRepeatable.h
@@ -43,33 +43,36 @@ public:
virtual ~AnimatableRepeatable() { }
// This will consume the vector passed into it.
- static PassRefPtr<AnimatableRepeatable> create(Vector<RefPtr<AnimatableValue> >& values)
+ static PassRefPtrWillBeRawPtr<AnimatableRepeatable> create(WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& values)
{
- return adoptRef(new AnimatableRepeatable(values));
+ return adoptRefWillBeNoop(new AnimatableRepeatable(values));
}
- const Vector<RefPtr<AnimatableValue> >& values() const { return m_values; }
+ const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& values() const { return m_values; }
+
+ virtual void trace(Visitor*) OVERRIDE;
protected:
AnimatableRepeatable()
{
}
- AnimatableRepeatable(Vector<RefPtr<AnimatableValue> >& values)
+ AnimatableRepeatable(WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& values)
{
ASSERT(!values.isEmpty());
m_values.swap(values);
}
- static bool interpolateLists(const Vector<RefPtr<AnimatableValue> >& fromValues, const Vector<RefPtr<AnimatableValue> >& toValues, double fraction, Vector<RefPtr<AnimatableValue> >& interpolatedValues);
+ static bool interpolateLists(const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& fromValues, const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& toValues, double fraction, WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& interpolatedValues);
+
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
- Vector<RefPtr<AnimatableValue> > m_values;
+ WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> > m_values;
private:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
virtual AnimatableType type() const OVERRIDE { return TypeRepeatable; }
- virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
+ virtual bool equalTo(const AnimatableValue*) const OVERRIDE FINAL;
};
DEFINE_TYPE_CASTS(AnimatableRepeatable, AnimatableValue, value, (value->isRepeatable() || value->isStrokeDasharrayList()), (value.isRepeatable() || value.isStrokeDasharrayList()));
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.cpp
index 97f4158d0b3..829140e7b7c 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.cpp
@@ -35,20 +35,14 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableSVGLength::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableSVGLength::interpolateTo(const AnimatableValue* value, double fraction) const
{
- return create(toAnimatableSVGLength(value)->toSVGLength().blend(m_length, narrowPrecisionToFloat(fraction)));
-}
-
-PassRefPtr<AnimatableValue> AnimatableSVGLength::addWith(const AnimatableValue* value) const
-{
- ASSERT_WITH_MESSAGE(false, "Web Animations not yet implemented: AnimatableSVGLength::addWith()");
- return defaultAddWith(this, value);
+ return create(toAnimatableSVGLength(value)->toSVGLength()->blend(m_length.get(), narrowPrecisionToFloat(fraction)));
}
bool AnimatableSVGLength::equalTo(const AnimatableValue* value) const
{
- return m_length == toAnimatableSVGLength(value)->m_length;
+ return *m_length == *toAnimatableSVGLength(value)->m_length;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.h
index 27dba9a48c1..5b7f7912bb3 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGLength.h
@@ -36,34 +36,35 @@
namespace WebCore {
-class AnimatableSVGLength: public AnimatableValue {
+class AnimatableSVGLength FINAL : public AnimatableValue {
public:
virtual ~AnimatableSVGLength() { }
- static PassRefPtr<AnimatableSVGLength> create(const SVGLength& length)
+ static PassRefPtrWillBeRawPtr<AnimatableSVGLength> create(PassRefPtr<SVGLength> length)
{
- return adoptRef(new AnimatableSVGLength(length));
+ return adoptRefWillBeNoop(new AnimatableSVGLength(length));
}
- const SVGLength& toSVGLength() const
+ SVGLength* toSVGLength() const
{
- return m_length;
+ return m_length.get();
}
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
- AnimatableSVGLength(const SVGLength& length)
+ AnimatableSVGLength(PassRefPtr<SVGLength> length)
: m_length(length)
{
}
- virtual AnimatableType type() const { return TypeSVGLength; }
+ virtual AnimatableType type() const OVERRIDE { return TypeSVGLength; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- SVGLength m_length;
+ RefPtr<SVGLength> m_length;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableSVGLength, isSVGLength());
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.cpp
index 784c9d32558..94eca3cd587 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.cpp
@@ -33,32 +33,33 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableSVGPaint::interpolateTo(const AnimatableValue* value, double fraction) const
+bool AnimatableSVGPaint::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
- if (paintType() == SVGPaint::SVG_PAINTTYPE_RGBCOLOR && svgPaint->paintType() == SVGPaint::SVG_PAINTTYPE_RGBCOLOR) {
- ASSERT(uri().isNull());
- return AnimatableSVGPaint::create(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, m_color.interpolateTo(svgPaint->m_color, fraction), String());
- }
- return defaultInterpolateTo(this, value, fraction);
+ return (paintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || svgPaint->paintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR)
+ && (visitedLinkPaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || svgPaint->visitedLinkPaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR);
}
-PassRefPtr<AnimatableValue> AnimatableSVGPaint::addWith(const AnimatableValue* value) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableSVGPaint::interpolateTo(const AnimatableValue* value, double fraction) const
{
+ if (usesDefaultInterpolationWith(value))
+ return defaultInterpolateTo(this, value, fraction);
+
const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
- if (paintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || svgPaint->paintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR) {
- ASSERT(uri().isNull());
- return AnimatableSVGPaint::create(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, m_color.addWith(svgPaint->m_color), String());
- }
- return defaultAddWith(this, value);
+ RefPtrWillBeRawPtr<AnimatableColor> color = toAnimatableColor(AnimatableValue::interpolate(m_color.get(), svgPaint->m_color.get(), fraction).get());
+ if (fraction < 0.5)
+ return create(paintType(), visitedLinkPaintType(), color, uri(), visitedLinkURI());
+ return create(svgPaint->paintType(), svgPaint->visitedLinkPaintType(), color, svgPaint->uri(), svgPaint->visitedLinkURI());
}
bool AnimatableSVGPaint::equalTo(const AnimatableValue* value) const
{
const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
return paintType() == svgPaint->paintType()
+ && visitedLinkPaintType() == svgPaint->visitedLinkPaintType()
&& color() == svgPaint->color()
- && uri() == svgPaint->uri();
+ && uri() == svgPaint->uri()
+ && visitedLinkURI() == svgPaint->visitedLinkURI();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.h
index 93ebd2e8ca6..ff54142b43c 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableSVGPaint.h
@@ -37,38 +37,58 @@
namespace WebCore {
-class AnimatableSVGPaint : public AnimatableValue {
+class AnimatableSVGPaint FINAL : public AnimatableValue {
public:
virtual ~AnimatableSVGPaint() { }
- static PassRefPtr<AnimatableSVGPaint> create(SVGPaint::SVGPaintType type, const Color& color, const String& uri)
+ static PassRefPtrWillBeRawPtr<AnimatableSVGPaint> create(
+ SVGPaint::SVGPaintType type, SVGPaint::SVGPaintType visitedLinkType,
+ const Color& color, const Color& visitedLinkColor,
+ const String& uri, const String& visitedLinkURI)
{
- return create(type, AnimatableColorImpl(color), uri);
+ return create(type, visitedLinkType, AnimatableColor::create(color, visitedLinkColor), uri, visitedLinkURI);
}
- static PassRefPtr<AnimatableSVGPaint> create(SVGPaint::SVGPaintType type, const AnimatableColorImpl& color, const String& uri)
+ static PassRefPtrWillBeRawPtr<AnimatableSVGPaint> create(
+ SVGPaint::SVGPaintType type, SVGPaint::SVGPaintType visitedLinkType,
+ PassRefPtrWillBeRawPtr<AnimatableColor> color,
+ const String& uri, const String& visitedLinkURI)
{
- return adoptRef(new AnimatableSVGPaint(type, color, uri));
+ return adoptRefWillBeNoop(new AnimatableSVGPaint(type, visitedLinkType, color, uri, visitedLinkURI));
}
SVGPaint::SVGPaintType paintType() const { return m_type; };
- Color color() const { return m_color.toColor(); };
+ SVGPaint::SVGPaintType visitedLinkPaintType() const { return m_visitedLinkType; };
+ Color color() const { return m_color->color(); };
+ Color visitedLinkColor() const { return m_color->visitedLinkColor(); };
const String& uri() const { return m_uri; };
+ const String& visitedLinkURI() const { return m_visitedLinkURI; };
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_color);
+ AnimatableValue::trace(visitor);
+ }
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
- AnimatableSVGPaint(SVGPaint::SVGPaintType type, const AnimatableColorImpl& color, const String& uri)
+ AnimatableSVGPaint(SVGPaint::SVGPaintType type, SVGPaint::SVGPaintType visitedLinkType, PassRefPtrWillBeRawPtr<AnimatableColor> color, const String& uri, const String& visitedLinkURI)
: m_type(type)
+ , m_visitedLinkType(visitedLinkType)
, m_color(color)
, m_uri(uri)
+ , m_visitedLinkURI(visitedLinkURI)
{
}
virtual AnimatableType type() const OVERRIDE { return TypeSVGPaint; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
SVGPaint::SVGPaintType m_type;
- AnimatableColorImpl m_color;
+ SVGPaint::SVGPaintType m_visitedLinkType;
+ // AnimatableColor includes a visited link color.
+ RefPtrWillBeMember<AnimatableColor> m_color;
String m_uri;
+ String m_visitedLinkURI;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableSVGPaint, isSVGPaint());
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.cpp
index 4d1a847f319..63719bbe99a 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.cpp
@@ -33,19 +33,12 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableShadow::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableShadow::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableShadow* shadowList = toAnimatableShadow(value);
return AnimatableShadow::create(ShadowList::blend(m_shadowList.get(), shadowList->m_shadowList.get(), fraction));
}
-PassRefPtr<AnimatableValue> AnimatableShadow::addWith(const AnimatableValue* value) const
-{
- // FIXME: The spec doesn't specify anything for shadow in particular, but
- // the default behaviour is probably not what one would expect.
- return AnimatableValue::defaultAddWith(this, value);
-}
-
bool AnimatableShadow::equalTo(const AnimatableValue* value) const
{
const ShadowList* shadowList = toAnimatableShadow(value)->m_shadowList.get();
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.h
index 23fb59b7a08..80a7cf51886 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableShadow.h
@@ -36,18 +36,19 @@
namespace WebCore {
-class AnimatableShadow : public AnimatableValue {
+class AnimatableShadow FINAL : public AnimatableValue {
public:
virtual ~AnimatableShadow() { }
- static PassRefPtr<AnimatableShadow> create(PassRefPtr<ShadowList> shadowList)
+ static PassRefPtrWillBeRawPtr<AnimatableShadow> create(PassRefPtr<ShadowList> shadowList)
{
- return adoptRef(new AnimatableShadow(shadowList));
+ return adoptRefWillBeNoop(new AnimatableShadow(shadowList));
}
ShadowList* shadowList() const { return m_shadowList.get(); }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
explicit AnimatableShadow(PassRefPtr<ShadowList> shadowList)
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.cpp
index 9b17295c273..2e71e0dc88a 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.cpp
@@ -33,20 +33,30 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableShapeValue::interpolateTo(const AnimatableValue* value, double fraction) const
+bool AnimatableShapeValue::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
const AnimatableShapeValue* shapeValue = toAnimatableShapeValue(value);
- if (m_shape->type() != ShapeValue::Shape || shapeValue->m_shape->type() != ShapeValue::Shape)
- return defaultInterpolateTo(this, value, fraction);
+ if (m_shape->type() != ShapeValue::Shape
+ || shapeValue->m_shape->type() != ShapeValue::Shape
+ || m_shape->cssBox() != shapeValue->m_shape->cssBox())
+ return true;
const BasicShape* fromShape = this->m_shape->shape();
const BasicShape* toShape = shapeValue->m_shape->shape();
- if (!fromShape->canBlend(toShape))
+ return !fromShape->canBlend(toShape);
+}
+
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableShapeValue::interpolateTo(const AnimatableValue* value, double fraction) const
+{
+ if (usesDefaultInterpolationWith(value))
return defaultInterpolateTo(this, value, fraction);
- return AnimatableShapeValue::create(ShapeValue::createShapeValue(toShape->blend(fromShape, fraction)).get());
+ const AnimatableShapeValue* shapeValue = toAnimatableShapeValue(value);
+ const BasicShape* fromShape = this->m_shape->shape();
+ const BasicShape* toShape = shapeValue->m_shape->shape();
+ return AnimatableShapeValue::create(ShapeValue::createShapeValue(toShape->blend(fromShape, fraction), shapeValue->m_shape->cssBox()).get());
}
bool AnimatableShapeValue::equalTo(const AnimatableValue* value) const
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.h
index 1d5382b0548..decc6f33f03 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableShapeValue.h
@@ -36,17 +36,20 @@
namespace WebCore {
-class AnimatableShapeValue : public AnimatableValue {
+class AnimatableShapeValue FINAL : public AnimatableValue {
public:
virtual ~AnimatableShapeValue() { }
- static PassRefPtr<AnimatableShapeValue> create(ShapeValue* shape)
+ static PassRefPtrWillBeRawPtr<AnimatableShapeValue> create(ShapeValue* shape)
{
- return adoptRef(new AnimatableShapeValue(shape));
+ return adoptRefWillBeNoop(new AnimatableShapeValue(shape));
}
ShapeValue* shapeValue() const { return m_shape.get(); }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
AnimatableShapeValue(ShapeValue* shape)
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.cpp
index b8951cc4cad..f81e3513a1e 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.cpp
@@ -36,27 +36,36 @@
namespace WebCore {
-AnimatableStrokeDasharrayList::AnimatableStrokeDasharrayList(const Vector<SVGLength>& lengths)
+AnimatableStrokeDasharrayList::AnimatableStrokeDasharrayList(PassRefPtr<SVGLengthList> passLengths)
{
- for (size_t i = 0; i < lengths.size(); ++i)
- m_values.append(AnimatableSVGLength::create(lengths[i]));
+ RefPtr<SVGLengthList> lengths = passLengths;
+ SVGLengthList::ConstIterator it = lengths->begin();
+ SVGLengthList::ConstIterator itEnd = lengths->end();
+ for (; it != itEnd; ++it)
+ m_values.append(AnimatableSVGLength::create(*it));
}
-Vector<SVGLength> AnimatableStrokeDasharrayList::toSVGLengthVector() const
+PassRefPtr<SVGLengthList> AnimatableStrokeDasharrayList::toSVGLengthList() const
{
- Vector<SVGLength> lengths(m_values.size());
+ RefPtr<SVGLengthList> lengths = SVGLengthList::create();
for (size_t i = 0; i < m_values.size(); ++i) {
- lengths[i] = toAnimatableSVGLength(m_values[i].get())->toSVGLength();
- if (lengths[i].valueInSpecifiedUnits() < 0)
- lengths[i].setValueInSpecifiedUnits(0);
+ RefPtr<SVGLength> length = toAnimatableSVGLength(m_values[i].get())->toSVGLength()->clone();
+ if (length->valueInSpecifiedUnits() < 0)
+ length->setValueInSpecifiedUnits(0);
+ lengths->append(length);
}
- return lengths;
+ return lengths.release();
}
-PassRefPtr<AnimatableValue> AnimatableStrokeDasharrayList::interpolateTo(const AnimatableValue* value, double fraction) const
+bool AnimatableStrokeDasharrayList::usesDefaultInterpolationWith(const AnimatableValue* value) const
{
- Vector<RefPtr<AnimatableValue> > from = m_values;
- Vector<RefPtr<AnimatableValue> > to = toAnimatableStrokeDasharrayList(value)->m_values;
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableStrokeDasharrayList::interpolateTo(const AnimatableValue* value, double fraction) const
+{
+ WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> > from = m_values;
+ WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> > to = toAnimatableStrokeDasharrayList(value)->m_values;
// The spec states that if the sum of all values is zero, this should be
// treated like a value of 'none', which means that a solid line is drawn.
@@ -66,12 +75,7 @@ PassRefPtr<AnimatableValue> AnimatableStrokeDasharrayList::interpolateTo(const A
if (from.isEmpty() && to.isEmpty())
return takeConstRef(this);
if (from.isEmpty() || to.isEmpty()) {
- DEFINE_STATIC_REF(AnimatableSVGLength, zeroPixels, 0);
- if (!zeroPixels) {
- SVGLength length;
- length.newValueSpecifiedUnits(LengthTypePX, 0, IGNORE_EXCEPTION);
- zeroPixels = AnimatableSVGLength::create(length).leakRef();
- }
+ DEFINE_STATIC_REF_WILL_BE_PERSISTENT(AnimatableSVGLength, zeroPixels, (AnimatableSVGLength::create(SVGLength::create())));
if (from.isEmpty()) {
from.append(zeroPixels);
from.append(zeroPixels);
@@ -82,10 +86,15 @@ PassRefPtr<AnimatableValue> AnimatableStrokeDasharrayList::interpolateTo(const A
}
}
- Vector<RefPtr<AnimatableValue> > interpolatedValues;
+ WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> > interpolatedValues;
bool success = interpolateLists(from, to, fraction, interpolatedValues);
ASSERT_UNUSED(success, success);
- return adoptRef(new AnimatableStrokeDasharrayList(interpolatedValues));
+ return adoptRefWillBeNoop(new AnimatableStrokeDasharrayList(interpolatedValues));
+}
+
+void AnimatableStrokeDasharrayList::trace(Visitor* visitor)
+{
+ AnimatableRepeatable::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.h
index d19b2e017ac..c7f5d8fafd7 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayList.h
@@ -32,33 +32,36 @@
#define AnimatableStrokeDasharrayList_h
#include "core/animation/AnimatableRepeatable.h"
-#include "core/svg/SVGLength.h"
+#include "core/svg/SVGLengthList.h"
namespace WebCore {
-class AnimatableStrokeDasharrayList: public AnimatableRepeatable {
+class AnimatableStrokeDasharrayList FINAL : public AnimatableRepeatable {
public:
virtual ~AnimatableStrokeDasharrayList() { }
- static PassRefPtr<AnimatableStrokeDasharrayList> create(const Vector<SVGLength>& lengths)
+ static PassRefPtrWillBeRawPtr<AnimatableStrokeDasharrayList> create(PassRefPtr<SVGLengthList> lengths)
{
- return adoptRef(new AnimatableStrokeDasharrayList(lengths));
+ return adoptRefWillBeNoop(new AnimatableStrokeDasharrayList(lengths));
}
- Vector<SVGLength> toSVGLengthVector() const;
+ PassRefPtr<SVGLengthList> toSVGLengthList() const;
+
+ virtual void trace(Visitor*) OVERRIDE;
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
- AnimatableStrokeDasharrayList(const Vector<SVGLength>&);
+ AnimatableStrokeDasharrayList(PassRefPtr<SVGLengthList>);
// This will consume the vector passed into it.
- AnimatableStrokeDasharrayList(Vector<RefPtr<AnimatableValue> >& values)
+ AnimatableStrokeDasharrayList(WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& values)
: AnimatableRepeatable(values)
{
}
- virtual AnimatableType type() const { return TypeStrokeDasharrayList; }
+ virtual AnimatableType type() const OVERRIDE { return TypeStrokeDasharrayList; }
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableStrokeDasharrayList, isStrokeDasharrayList());
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayListTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayListTest.cpp
index 6a2756d2504..97f3330fcce 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayListTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableStrokeDasharrayListTest.cpp
@@ -39,21 +39,29 @@ using namespace WebCore;
namespace {
+PassRefPtr<SVGLengthList> createSVGLengthList(size_t length)
+{
+ RefPtr<SVGLengthList> list = SVGLengthList::create();
+ for (size_t i = 0; i < length; ++i)
+ list->append(SVGLength::create());
+ return list.release();
+}
+
TEST(AnimationAnimatableStrokeDasharrayListTest, EqualTo)
{
- Vector<SVGLength> vectorA(4);
- Vector<SVGLength> vectorB(4);
- RefPtr<AnimatableStrokeDasharrayList> listA = AnimatableStrokeDasharrayList::create(vectorA);
- RefPtr<AnimatableStrokeDasharrayList> listB = AnimatableStrokeDasharrayList::create(vectorB);
+ RefPtr<SVGLengthList> svgListA = createSVGLengthList(4);
+ RefPtr<SVGLengthList> svgListB = createSVGLengthList(4);
+ RefPtrWillBeRawPtr<AnimatableStrokeDasharrayList> listA = AnimatableStrokeDasharrayList::create(svgListA);
+ RefPtrWillBeRawPtr<AnimatableStrokeDasharrayList> listB = AnimatableStrokeDasharrayList::create(svgListB);
EXPECT_TRUE(listA->equals(listB.get()));
TrackExceptionState exceptionState;
- vectorB[3].newValueSpecifiedUnits(LengthTypePX, 50, exceptionState);
- listB = AnimatableStrokeDasharrayList::create(vectorB);
+ svgListB->at(3)->newValueSpecifiedUnits(LengthTypePX, 50);
+ listB = AnimatableStrokeDasharrayList::create(svgListB);
EXPECT_FALSE(listA->equals(listB.get()));
- vectorB = Vector<SVGLength>(5);
- listB = AnimatableStrokeDasharrayList::create(vectorB);
+ svgListB = createSVGLengthList(5);
+ listB = AnimatableStrokeDasharrayList::create(svgListB);
EXPECT_FALSE(listA->equals(listB.get()));
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.cpp
index 542d8c315b0..98ea3e19930 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.cpp
@@ -33,23 +33,17 @@
namespace WebCore {
-PassRefPtr<AnimatableTransform> AnimatableTransform::create(const TransformOperations& transform)
+PassRefPtrWillBeRawPtr<AnimatableTransform> AnimatableTransform::create(const TransformOperations& transform)
{
- return adoptRef(new AnimatableTransform(transform));
+ return adoptRefWillBeNoop(new AnimatableTransform(transform));
}
-PassRefPtr<AnimatableValue> AnimatableTransform::interpolateTo(const AnimatableValue* value, double fraction) const
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableTransform::interpolateTo(const AnimatableValue* value, double fraction) const
{
const AnimatableTransform* transform = toAnimatableTransform(value);
return AnimatableTransform::create(transform->m_transform.blend(m_transform, fraction));
}
-PassRefPtr<AnimatableValue> AnimatableTransform::addWith(const AnimatableValue* value) const
-{
- const AnimatableTransform* transform = toAnimatableTransform(value);
- return AnimatableTransform::create(m_transform.add(transform->m_transform));
-}
-
bool AnimatableTransform::equalTo(const AnimatableValue* value) const
{
return m_transform == toAnimatableTransform(value)->m_transform;
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.h
index 7fa85323fbc..51896af426b 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableTransform.h
@@ -36,18 +36,19 @@
namespace WebCore {
-class AnimatableTransform : public AnimatableValue {
+class AnimatableTransform FINAL : public AnimatableValue {
public:
virtual ~AnimatableTransform() { }
- static PassRefPtr<AnimatableTransform> create(const TransformOperations&);
+ static PassRefPtrWillBeRawPtr<AnimatableTransform> create(const TransformOperations&);
const TransformOperations& transformOperations() const
{
return m_transform;
}
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
private:
explicit AnimatableTransform(const TransformOperations& transform)
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableUnknown.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableUnknown.h
index 43be1c8568c..820c656ef6d 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableUnknown.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableUnknown.h
@@ -31,36 +31,44 @@
#ifndef AnimatableUnknown_h
#define AnimatableUnknown_h
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "core/animation/AnimatableValue.h"
#include "core/css/CSSValuePool.h"
namespace WebCore {
-class AnimatableUnknown : public AnimatableValue {
+class AnimatableUnknown FINAL : public AnimatableValue {
public:
virtual ~AnimatableUnknown() { }
- static PassRefPtr<AnimatableUnknown> create(PassRefPtr<CSSValue> value)
+ static PassRefPtrWillBeRawPtr<AnimatableUnknown> create(PassRefPtrWillBeRawPtr<CSSValue> value)
{
- return adoptRef(new AnimatableUnknown(value));
+ return adoptRefWillBeNoop(new AnimatableUnknown(value));
}
- static PassRefPtr<AnimatableUnknown> create(CSSValueID value)
+ static PassRefPtrWillBeRawPtr<AnimatableUnknown> create(CSSValueID value)
{
- return adoptRef(new AnimatableUnknown(cssValuePool().createIdentifierValue(value)));
+ return adoptRefWillBeNoop(new AnimatableUnknown(cssValuePool().createIdentifierValue(value)));
}
- PassRefPtr<CSSValue> toCSSValue() const { return m_value; }
+ PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const { return m_value; }
CSSValueID toCSSValueID() const { return toCSSPrimitiveValue(m_value.get())->getValueID(); }
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_value);
+ AnimatableValue::trace(visitor);
+ }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue* value, double fraction) const OVERRIDE
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue* value, double fraction) const OVERRIDE
{
return defaultInterpolateTo(this, value, fraction);
}
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE { return true; }
+
private:
- explicit AnimatableUnknown(PassRefPtr<CSSValue> value)
+ explicit AnimatableUnknown(PassRefPtrWillBeRawPtr<CSSValue> value)
: m_value(value)
{
ASSERT(m_value);
@@ -68,7 +76,7 @@ private:
virtual AnimatableType type() const OVERRIDE { return TypeUnknown; }
virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
- const RefPtr<CSSValue> m_value;
+ const RefPtrWillBeMember<CSSValue> m_value;
};
DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableUnknown, isUnknown());
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableUnknownTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableUnknownTest.cpp
index 5ca17607108..ad40dd76e57 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableUnknownTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableUnknownTest.cpp
@@ -51,11 +51,10 @@ protected:
otherAnimatableUnknown = AnimatableUnknown::create(otherCSSValue);
}
- RefPtr<CSSValue> cssValue;
- RefPtr<AnimatableValue> animatableUnknown;
-
- RefPtr<CSSValue> otherCSSValue;
- RefPtr<AnimatableValue> otherAnimatableUnknown;
+ RefPtrWillBePersistent<CSSValue> cssValue;
+ RefPtrWillBePersistent<AnimatableValue> animatableUnknown;
+ RefPtrWillBePersistent<CSSValue> otherCSSValue;
+ RefPtrWillBePersistent<AnimatableValue> otherAnimatableUnknown;
};
TEST_F(AnimationAnimatableUnknownTest, Create)
@@ -83,10 +82,4 @@ TEST_F(AnimationAnimatableUnknownTest, Interpolate)
EXPECT_EQ(cssValue, toAnimatableUnknown(AnimatableValue::interpolate(otherAnimatableUnknown.get(), animatableUnknown.get(), 1).get())->toCSSValue());
}
-TEST_F(AnimationAnimatableUnknownTest, Add)
-{
- EXPECT_EQ(otherCSSValue, toAnimatableUnknown(AnimatableValue::add(animatableUnknown.get(), otherAnimatableUnknown.get()).get())->toCSSValue());
- EXPECT_EQ(cssValue, toAnimatableUnknown(AnimatableValue::add(otherAnimatableUnknown.get(), animatableUnknown.get()).get())->toCSSValue());
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableValue.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableValue.cpp
index 1c9d1751ca0..af0aec9ac4a 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableValue.cpp
@@ -34,15 +34,21 @@
#include "wtf/StdLibExtras.h"
#include <algorithm>
+namespace {
+
+const double defaultDistance = 1;
+
+} // namespace
+
namespace WebCore {
const AnimatableValue* AnimatableValue::neutralValue()
{
- DEFINE_STATIC_REF(AnimatableNeutral, neutralSentinelValue, (AnimatableNeutral::create()));
+ DEFINE_STATIC_REF_WILL_BE_PERSISTENT(AnimatableNeutral, neutralSentinelValue, (AnimatableNeutral::create()));
return neutralSentinelValue;
}
-PassRefPtr<AnimatableValue> AnimatableValue::interpolate(const AnimatableValue* left, const AnimatableValue* right, double fraction)
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableValue::interpolate(const AnimatableValue* left, const AnimatableValue* right, double fraction)
{
ASSERT(left);
ASSERT(right);
@@ -55,25 +61,20 @@ PassRefPtr<AnimatableValue> AnimatableValue::interpolate(const AnimatableValue*
return defaultInterpolateTo(left, right, fraction);
}
-PassRefPtr<AnimatableValue> AnimatableValue::add(const AnimatableValue* left, const AnimatableValue* right)
+double AnimatableValue::distance(const AnimatableValue* left, const AnimatableValue* right)
{
ASSERT(left);
ASSERT(right);
- if (left->isNeutral())
- return takeConstRef(right);
- if (right->isNeutral())
- return takeConstRef(left);
-
if (left->isSameType(right))
- return left->addWith(right);
+ return left->distanceTo(right);
- return defaultAddWith(left, right);
+ return defaultDistance;
}
-PassRefPtr<AnimatableValue> AnimatableValue::addWith(const AnimatableValue* value) const
+double AnimatableValue::distanceTo(const AnimatableValue*) const
{
- return defaultAddWith(this, value);
+ return defaultDistance;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableValue.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableValue.h
index 2e52c321e95..2306142cc1c 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableValue.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableValue.h
@@ -32,19 +32,23 @@
#define AnimatableValue_h
#include "core/css/CSSValue.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class AnimatableValue : public RefCounted<AnimatableValue> {
+class AnimatableValue : public RefCountedWillBeGarbageCollectedFinalized<AnimatableValue> {
public:
virtual ~AnimatableValue() { }
static const AnimatableValue* neutralValue();
- static PassRefPtr<AnimatableValue> interpolate(const AnimatableValue*, const AnimatableValue*, double fraction);
- // For noncommutative values read add(A, B) to mean the value A with B composed onto it.
- static PassRefPtr<AnimatableValue> add(const AnimatableValue*, const AnimatableValue*);
+ static PassRefPtrWillBeRawPtr<AnimatableValue> interpolate(const AnimatableValue*, const AnimatableValue*, double fraction);
+ static double distance(const AnimatableValue* from, const AnimatableValue* to);
+ static bool usesDefaultInterpolation(const AnimatableValue* from, const AnimatableValue* to)
+ {
+ return !from->isSameType(to) || from->usesDefaultInterpolationWith(to);
+ }
bool equals(const AnimatableValue* value) const
{
@@ -64,6 +68,7 @@ public:
bool isLengthBox() const { return type() == TypeLengthBox; }
bool isLengthBoxAndBool() const { return type() == TypeLengthBoxAndBool; }
bool isLengthPoint() const { return type() == TypeLengthPoint; }
+ bool isLengthPoint3D() const { return type() == TypeLengthPoint3D; }
bool isLengthSize() const { return type() == TypeLengthSize; }
bool isNeutral() const { return type() == TypeNeutral; }
bool isRepeatable() const { return type() == TypeRepeatable; }
@@ -82,10 +87,7 @@ public:
return value->type() == type();
}
- bool usesNonDefaultInterpolationWith(const AnimatableValue* value) const
- {
- return isSameType(value) && !isUnknown();
- }
+ virtual void trace(Visitor*) { }
protected:
enum AnimatableType {
@@ -98,6 +100,7 @@ protected:
TypeLengthBox,
TypeLengthBoxAndBool,
TypeLengthPoint,
+ TypeLengthPoint3D,
TypeLengthSize,
TypeNeutral,
TypeRepeatable,
@@ -111,20 +114,21 @@ protected:
TypeVisibility,
};
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const = 0;
- static PassRefPtr<AnimatableValue> defaultInterpolateTo(const AnimatableValue* left, const AnimatableValue* right, double fraction) { return takeConstRef((fraction < 0.5) ? left : right); }
-
- // For noncommutative values read A->addWith(B) to mean the value A with B composed onto it.
- virtual PassRefPtr<AnimatableValue> addWith(const AnimatableValue*) const;
- static PassRefPtr<AnimatableValue> defaultAddWith(const AnimatableValue* left, const AnimatableValue* right) { return takeConstRef(right); }
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue* value) const { return false; }
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const = 0;
+ static PassRefPtrWillBeRawPtr<AnimatableValue> defaultInterpolateTo(const AnimatableValue* left, const AnimatableValue* right, double fraction) { return takeConstRef((fraction < 0.5) ? left : right); }
template <class T>
- static PassRefPtr<T> takeConstRef(const T* value) { return PassRefPtr<T>(const_cast<T*>(value)); }
+ static PassRefPtrWillBeRawPtr<T> takeConstRef(const T* value) { return PassRefPtrWillBeRawPtr<T>(const_cast<T*>(value)); }
private:
virtual AnimatableType type() const = 0;
// Implementations can assume that the object being compared has the same type as the object this is called on
virtual bool equalTo(const AnimatableValue*) const = 0;
+
+ virtual double distanceTo(const AnimatableValue*) const;
+
+ template <class Keyframe> friend class KeyframeEffectModel;
};
#define DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(thisType, predicate) \
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableValueKeyframe.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueKeyframe.cpp
new file mode 100644
index 00000000000..43e9bfdee32
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueKeyframe.cpp
@@ -0,0 +1,80 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/AnimatableValueKeyframe.h"
+
+#include "core/animation/interpolation/LegacyStyleInterpolation.h"
+
+namespace WebCore {
+
+AnimatableValueKeyframe::AnimatableValueKeyframe(const AnimatableValueKeyframe& copyFrom)
+ : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing)
+{
+ for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin(); iter != copyFrom.m_propertyValues.end(); ++iter)
+ setPropertyValue(iter->key, iter->value.get());
+}
+
+PropertySet AnimatableValueKeyframe::properties() const
+{
+ // This is not used in time-critical code, so we probably don't need to
+ // worry about caching this result.
+ PropertySet properties;
+ for (PropertyValueMap::const_iterator iter = m_propertyValues.begin(); iter != m_propertyValues.end(); ++iter)
+ properties.add(*iter.keys());
+ return properties;
+}
+
+PassRefPtrWillBeRawPtr<Keyframe> AnimatableValueKeyframe::clone() const
+{
+ return adoptRefWillBeNoop(new AnimatableValueKeyframe(*this));
+}
+
+PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> AnimatableValueKeyframe::createPropertySpecificKeyframe(CSSPropertyID property) const
+{
+ return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset(), easing(), propertyValue(property), composite()));
+}
+
+void AnimatableValueKeyframe::trace(Visitor* visitor)
+{
+ visitor->trace(m_propertyValues);
+ Keyframe::trace(visitor);
+}
+
+AnimatableValueKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, const AnimatableValue* value, AnimationEffect::CompositeOperation op)
+ : Keyframe::PropertySpecificKeyframe(offset, easing, op)
+ , m_value(const_cast<AnimatableValue*>(value))
+{ }
+
+AnimatableValueKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, PassRefPtrWillBeRawPtr<AnimatableValue> value)
+ : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::CompositeReplace)
+ , m_value(value)
+{
+ ASSERT(!isNull(m_offset));
+}
+
+PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> AnimatableValueKeyframe::PropertySpecificKeyframe::cloneWithOffset(double offset) const
+{
+ Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe(offset, m_easing, m_value);
+ return adoptPtrWillBeNoop(theClone);
+}
+
+PassRefPtrWillBeRawPtr<Interpolation> AnimatableValueKeyframe::PropertySpecificKeyframe::createInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyframe* end, Element*) const
+{
+ AnimatableValuePropertySpecificKeyframe* to = toAnimatableValuePropertySpecificKeyframe(end);
+ return LegacyStyleInterpolation::create(value(), to->value(), property);
+}
+
+PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> AnimatableValueKeyframe::PropertySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const
+{
+ return adoptPtrWillBeNoop(new AnimatableValueKeyframe::PropertySpecificKeyframe(offset, easing, AnimatableValue::neutralValue(), AnimationEffect::CompositeAdd));
+}
+
+void AnimatableValueKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ Keyframe::PropertySpecificKeyframe::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableValueKeyframe.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueKeyframe.h
new file mode 100644
index 00000000000..c3fd15584e9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueKeyframe.h
@@ -0,0 +1,75 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AnimatableValueKeyframe_h
+#define AnimatableValueKeyframe_h
+
+#include "core/animation/AnimatableValue.h"
+#include "core/animation/Keyframe.h"
+
+namespace WebCore {
+
+class AnimatableValueKeyframe : public Keyframe {
+public:
+ static PassRefPtrWillBeRawPtr<AnimatableValueKeyframe> create()
+ {
+ return adoptRefWillBeNoop(new AnimatableValueKeyframe);
+ }
+ void setPropertyValue(CSSPropertyID property, PassRefPtrWillBeRawPtr<AnimatableValue> value)
+ {
+ m_propertyValues.add(property, value);
+ }
+ void clearPropertyValue(CSSPropertyID property) { m_propertyValues.remove(property); }
+ AnimatableValue* propertyValue(CSSPropertyID property) const
+ {
+ ASSERT(m_propertyValues.contains(property));
+ return m_propertyValues.get(property);
+ }
+ virtual PropertySet properties() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ class PropertySpecificKeyframe : public Keyframe::PropertySpecificKeyframe {
+ public:
+ PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, const AnimatableValue*, AnimationEffect::CompositeOperation);
+
+ AnimatableValue* value() const { return m_value.get(); }
+ virtual const PassRefPtrWillBeRawPtr<AnimatableValue> getAnimatableValue() const OVERRIDE FINAL { return m_value; }
+
+ virtual PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<Interpolation> createInterpolation(CSSPropertyID, WebCore::Keyframe::PropertySpecificKeyframe* end, Element*) const OVERRIDE FINAL;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ private:
+ PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, PassRefPtrWillBeRawPtr<AnimatableValue>);
+
+ virtual PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> cloneWithOffset(double offset) const OVERRIDE;
+ virtual bool isAnimatableValuePropertySpecificKeyframe() const OVERRIDE { return true; }
+
+ RefPtrWillBeMember<AnimatableValue> m_value;
+ };
+
+private:
+ AnimatableValueKeyframe() { }
+
+ AnimatableValueKeyframe(const AnimatableValueKeyframe& copyFrom);
+
+ virtual PassRefPtrWillBeRawPtr<Keyframe> clone() const OVERRIDE;
+ virtual PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> createPropertySpecificKeyframe(CSSPropertyID) const OVERRIDE;
+
+ virtual bool isAnimatableValueKeyframe() const OVERRIDE { return true; }
+
+ typedef HashMap<CSSPropertyID, RefPtrWillBeMember<AnimatableValue> > PropertyValueMap;
+ PropertyValueMap m_propertyValues;
+};
+
+typedef AnimatableValueKeyframe::PropertySpecificKeyframe AnimatableValuePropertySpecificKeyframe;
+
+DEFINE_TYPE_CASTS(AnimatableValueKeyframe, Keyframe, value, value->isAnimatableValueKeyframe(), value.isAnimatableValueKeyframe());
+DEFINE_TYPE_CASTS(AnimatableValuePropertySpecificKeyframe, Keyframe::PropertySpecificKeyframe, value, value->isAnimatableValuePropertySpecificKeyframe(), value.isAnimatableValuePropertySpecificKeyframe());
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.cpp
index da6958cfc21..f43065913a3 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.cpp
@@ -32,8 +32,6 @@
#include "core/animation/AnimatableValueTestHelper.h"
-
-
namespace WebCore {
bool operator==(const AnimatableValue& a, const AnimatableValue& b)
@@ -53,50 +51,9 @@ void PrintTo(const AnimatableColor& animColor, ::std::ostream* os)
<< animColor.visitedLinkColor().serialized().utf8().data() << ")";
}
-void PrintTo(const AnimatableDouble& animDouble, ::std::ostream* os)
-{
- PrintTo(*(animDouble.toCSSValue().get()), os, "AnimatableDouble");
-}
-
void PrintTo(const AnimatableImage& animImage, ::std::ostream* os)
{
- PrintTo(*(animImage.toCSSValue().get()), os, "AnimatableImage");
-}
-
-void PrintTo(const AnimatableLength& animLength, ::std::ostream* os)
-{
- PrintTo(*(animLength.toCSSValue().get()), os, "AnimatableLength");
-}
-
-void PrintTo(const AnimatableLengthBox& animLengthBox, ::std::ostream* os)
-{
- *os << "AnimatableLengthBox(";
- PrintTo(*(animLengthBox.left()), os);
- *os << ", ";
- PrintTo(*(animLengthBox.right()), os);
- *os << ", ";
- PrintTo(*(animLengthBox.top()), os);
- *os << ", ";
- PrintTo(*(animLengthBox.bottom()), os);
- *os << ")";
-}
-
-void PrintTo(const AnimatableLengthPoint& animLengthPoint, ::std::ostream* os)
-{
- *os << "AnimatableLengthPoint(";
- PrintTo(*(animLengthPoint.x()), os);
- *os << ", ";
- PrintTo(*(animLengthPoint.y()), os);
- *os << ")";
-}
-
-void PrintTo(const AnimatableLengthSize& animLengthSize, ::std::ostream* os)
-{
- *os << "AnimatableLengthSize(";
- PrintTo(*(animLengthSize.width()), os);
- *os << ", ";
- PrintTo(*(animLengthSize.height()), os);
- *os << ")";
+ PrintTo(*(animImage.toCSSValue()), os, "AnimatableImage");
}
void PrintTo(const AnimatableNeutral& animValue, ::std::ostream* os)
@@ -108,8 +65,8 @@ void PrintTo(const AnimatableRepeatable& animValue, ::std::ostream* os)
{
*os << "AnimatableRepeatable(";
- const Vector<RefPtr<AnimatableValue> > v = animValue.values();
- for (Vector<RefPtr<AnimatableValue> >::const_iterator it = v.begin(); it != v.end(); ++it) {
+ const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> > v = animValue.values();
+ for (WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >::const_iterator it = v.begin(); it != v.end(); ++it) {
PrintTo(*(it->get()), os);
if (it+1 != v.end())
*os << ", ";
@@ -120,19 +77,7 @@ void PrintTo(const AnimatableRepeatable& animValue, ::std::ostream* os)
void PrintTo(const AnimatableSVGLength& animSVGLength, ::std::ostream* os)
{
*os << "AnimatableSVGLength("
- << animSVGLength.toSVGLength().valueAsString().utf8().data() << ")";
-}
-
-void PrintTo(const AnimatableSVGPaint& animSVGPaint, ::std::ostream* os)
-{
- *os << "AnimatableSVGPaint(";
- if (animSVGPaint.paintType() == SVGPaint::SVG_PAINTTYPE_RGBCOLOR)
- *os << animSVGPaint.color().serialized().utf8().data();
- else if (animSVGPaint.paintType() == SVGPaint::SVG_PAINTTYPE_URI)
- *os << "url(" << animSVGPaint.uri().utf8().data() << ")";
- else
- *os << animSVGPaint.paintType();
- *os << ")";
+ << animSVGLength.toSVGLength()->valueAsString().utf8().data() << ")";
}
void PrintTo(const AnimatableShapeValue& animValue, ::std::ostream* os)
@@ -143,10 +88,11 @@ void PrintTo(const AnimatableShapeValue& animValue, ::std::ostream* os)
void PrintTo(const AnimatableStrokeDasharrayList& animValue, ::std::ostream* os)
{
*os << "AnimatableStrokeDasharrayList(";
- const Vector<SVGLength> v = animValue.toSVGLengthVector();
- for (Vector<SVGLength>::const_iterator it = v.begin(); it != v.end(); ++it) {
- *os << it->valueAsString().utf8().data();
- if (it+1 != v.end())
+ RefPtr<SVGLengthList> list = animValue.toSVGLengthList();
+ size_t length = list->length();
+ for (size_t i = 0; i < length; ++i) {
+ *os << list->at(i)->valueAsString().utf8().data();
+ if (i != length-1)
*os << ", ";
}
*os << ")";
@@ -232,18 +178,8 @@ void PrintTo(const AnimatableValue& animValue, ::std::ostream* os)
PrintTo(*(toAnimatableClipPathOperation(&animValue)), os);
else if (animValue.isColor())
PrintTo(*(toAnimatableColor(&animValue)), os);
- else if (animValue.isDouble())
- PrintTo(*(toAnimatableDouble(&animValue)), os);
else if (animValue.isImage())
PrintTo(*(toAnimatableImage(&animValue)), os);
- else if (animValue.isLength())
- PrintTo(*(toAnimatableLength(&animValue)), os);
- else if (animValue.isLengthBox())
- PrintTo(*(toAnimatableLengthBox(&animValue)), os);
- else if (animValue.isLengthPoint())
- PrintTo(*(toAnimatableLengthPoint(&animValue)), os);
- else if (animValue.isLengthSize())
- PrintTo(*(toAnimatableLengthSize(&animValue)), os);
else if (animValue.isNeutral())
PrintTo(*(static_cast<const AnimatableNeutral*>(&animValue)), os);
else if (animValue.isRepeatable())
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.h
index 65a86606768..ceed1bd85a7 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelper.h
@@ -38,12 +38,7 @@
#include "core/animation/AnimatableClipPathOperation.h"
#include "core/animation/AnimatableColor.h"
-#include "core/animation/AnimatableDouble.h"
#include "core/animation/AnimatableImage.h"
-#include "core/animation/AnimatableLength.h"
-#include "core/animation/AnimatableLengthBox.h"
-#include "core/animation/AnimatableLengthPoint.h"
-#include "core/animation/AnimatableLengthSize.h"
#include "core/animation/AnimatableNeutral.h"
#include "core/animation/AnimatableRepeatable.h"
#include "core/animation/AnimatableSVGLength.h"
@@ -68,16 +63,10 @@ bool operator==(const AnimatableValue&, const AnimatableValue&);
void PrintTo(const AnimatableClipPathOperation&, ::std::ostream*);
void PrintTo(const AnimatableColor&, ::std::ostream*);
-void PrintTo(const AnimatableDouble&, ::std::ostream*);
void PrintTo(const AnimatableImage&, ::std::ostream*);
-void PrintTo(const AnimatableLength&, ::std::ostream*);
-void PrintTo(const AnimatableLengthBox&, ::std::ostream*);
-void PrintTo(const AnimatableLengthPoint&, ::std::ostream*);
-void PrintTo(const AnimatableLengthSize&, ::std::ostream*);
void PrintTo(const AnimatableNeutral&, ::std::ostream*);
void PrintTo(const AnimatableRepeatable&, ::std::ostream*);
void PrintTo(const AnimatableSVGLength&, ::std::ostream*);
-void PrintTo(const AnimatableSVGPaint&, ::std::ostream*);
void PrintTo(const AnimatableShapeValue&, ::std::ostream*);
void PrintTo(const AnimatableStrokeDasharrayList&, ::std::ostream*);
void PrintTo(const AnimatableTransform&, ::std::ostream*);
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelperTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelperTest.cpp
index fad1a5a55e4..16bffd4eacc 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelperTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableValueTestHelperTest.cpp
@@ -50,14 +50,9 @@ namespace {
class AnimationAnimatableValueTestHelperTest : public ::testing::Test {
protected:
- ::std::string PrintToString(PassRefPtr<AnimatableValue> animValue)
+ ::std::string PrintToString(PassRefPtrWillBeRawPtr<AnimatableValue> animValue)
{
- return PrintToString(animValue.get());
- }
-
- ::std::string PrintToString(const AnimatableValue* animValue)
- {
- return ::testing::PrintToString(*animValue);
+ return ::testing::PrintToString(*animValue.get());
}
};
@@ -72,70 +67,29 @@ TEST_F(AnimationAnimatableValueTestHelperTest, PrintTo)
::std::string("AnimatableColor(rgba(0, 0, 0, 0), #ff0000)"),
PrintToString(AnimatableColor::create(Color(0x000000FF), Color(0xFFFF0000))));
- EXPECT_EQ(
- ::std::string("AnimatableDouble(1)"),
- PrintToString(AnimatableDouble::create(1.0)));
-
- EXPECT_EQ(
- ::std::string("AnimatableLength(5px)"),
- PrintToString(AnimatableLength::create(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PX).get())));
-
- EXPECT_EQ(
- ::std::string("AnimatableLengthBox(AnimatableLength(1px), AnimatableLength(2em), AnimatableLength(3rem), AnimatableLength(4pt))"),
- PrintToString(AnimatableLengthBox::create(
- AnimatableLength::create(CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_PX).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(2, CSSPrimitiveValue::CSS_EMS).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(3, CSSPrimitiveValue::CSS_REMS).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(4, CSSPrimitiveValue::CSS_PT).get())
- )));
-
- EXPECT_EQ(
- ::std::string("AnimatableLengthPoint(AnimatableLength(5%), AnimatableLength(6px))"),
- PrintToString(AnimatableLengthPoint::create(
- AnimatableLength::create(CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_PERCENTAGE).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(6, CSSPrimitiveValue::CSS_PX).get())
- )));
-
- EXPECT_EQ(
- ::std::string("AnimatableLengthSize(AnimatableLength(3rem), AnimatableLength(4pt))"),
- PrintToString(AnimatableLengthSize::create(
- AnimatableLength::create(CSSPrimitiveValue::create(3, CSSPrimitiveValue::CSS_REMS).get()),
- AnimatableLength::create(CSSPrimitiveValue::create(4, CSSPrimitiveValue::CSS_PT).get())
- )));
-
EXPECT_THAT(
- PrintToString(AnimatableValue::neutralValue()),
+ PrintToString(const_cast<AnimatableValue*>(AnimatableValue::neutralValue())),
testing::StartsWith("AnimatableNeutral@"));
- Vector<RefPtr<AnimatableValue> > v1;
- v1.append(AnimatableLength::create(CSSPrimitiveValue::create(3, CSSPrimitiveValue::CSS_REMS).get()));
- v1.append(AnimatableLength::create(CSSPrimitiveValue::create(4, CSSPrimitiveValue::CSS_PT).get()));
- EXPECT_EQ(
- ::std::string("AnimatableRepeatable(AnimatableLength(3rem), AnimatableLength(4pt))"),
- PrintToString(AnimatableRepeatable::create(v1)));
+ RefPtr<SVGLength> length1cm = SVGLength::create(LengthModeOther);
+ RefPtr<SVGLength> length2cm = SVGLength::create(LengthModeOther);
+ length1cm->setValueAsString("1cm", ASSERT_NO_EXCEPTION);
+ length2cm->setValueAsString("2cm", ASSERT_NO_EXCEPTION);
EXPECT_EQ(
::std::string("AnimatableSVGLength(1cm)"),
- PrintToString(AnimatableSVGLength::create(SVGLength(LengthModeOther, "1cm"))));
-
- EXPECT_EQ(
- ::std::string("AnimatableSVGPaint(#ff0000)"),
- PrintToString(AnimatableSVGPaint::create(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, Color(0xFFFF0000), "")));
-
- EXPECT_EQ(
- ::std::string("AnimatableSVGPaint(url(abc))"),
- PrintToString(AnimatableSVGPaint::create(SVGPaint::SVG_PAINTTYPE_URI, Color(0xFFFF0000), "abc")));
+ PrintToString(AnimatableSVGLength::create(length1cm)));
EXPECT_THAT(
- PrintToString(AnimatableShapeValue::create(ShapeValue::createShapeValue(BasicShapeCircle::create().get()).get())),
+ PrintToString(AnimatableShapeValue::create(ShapeValue::createShapeValue(BasicShapeCircle::create().get(), ContentBox).get())),
testing::StartsWith("AnimatableShapeValue@"));
- Vector<SVGLength> v2;
- v2.append(SVGLength(LengthModeOther, "1cm"));
- v2.append(SVGLength(LengthModeOther, "2cm"));
+ RefPtr<SVGLengthList> l2 = SVGLengthList::create();
+ l2->append(length1cm);
+ l2->append(length2cm);
EXPECT_EQ(
::std::string("AnimatableStrokeDasharrayList(1cm, 2cm)"),
- PrintToString(AnimatableStrokeDasharrayList::create(v2)));
+ PrintToString(AnimatableStrokeDasharrayList::create(l2)));
TransformOperations operations1;
operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp
index a395efa2b2c..573783f9e1b 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp
@@ -33,7 +33,14 @@
namespace WebCore {
-PassRefPtr<AnimatableValue> AnimatableVisibility::interpolateTo(const AnimatableValue* value, double fraction) const
+bool AnimatableVisibility::usesDefaultInterpolationWith(const AnimatableValue* value) const
+{
+ EVisibility from = m_visibility;
+ EVisibility to = toAnimatableVisibility(value)->m_visibility;
+ return from != VISIBLE && to != VISIBLE;
+}
+
+PassRefPtrWillBeRawPtr<AnimatableValue> AnimatableVisibility::interpolateTo(const AnimatableValue* value, double fraction) const
{
EVisibility from = m_visibility;
EVisibility to = toAnimatableVisibility(value)->m_visibility;
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.h b/chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.h
index bbd377105d0..72d653ebc66 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimatableVisibility.h
@@ -36,18 +36,21 @@
namespace WebCore {
-class AnimatableVisibility : public AnimatableValue {
+class AnimatableVisibility FINAL : public AnimatableValue {
public:
virtual ~AnimatableVisibility() { }
- static PassRefPtr<AnimatableVisibility> create(EVisibility visibility)
+ static PassRefPtrWillBeRawPtr<AnimatableVisibility> create(EVisibility visibility)
{
- return adoptRef(new AnimatableVisibility(visibility));
+ return adoptRefWillBeNoop(new AnimatableVisibility(visibility));
}
EVisibility visibility() const { return m_visibility; }
+ virtual void trace(Visitor* visitor) OVERRIDE { AnimatableValue::trace(visitor); }
+
protected:
- virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<AnimatableValue> interpolateTo(const AnimatableValue*, double fraction) const OVERRIDE;
+ virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE;
private:
explicit AnimatableVisibility(EVisibility visibility)
diff --git a/chromium/third_party/WebKit/Source/core/animation/Animation.cpp b/chromium/third_party/WebKit/Source/core/animation/Animation.cpp
index 6e40086d6f2..4eedf009903 100644
--- a/chromium/third_party/WebKit/Source/core/animation/Animation.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -31,136 +31,236 @@
#include "config.h"
#include "core/animation/Animation.h"
+#include "bindings/v8/Dictionary.h"
+#include "bindings/v8/ExceptionState.h"
#include "core/animation/ActiveAnimations.h"
+#include "core/animation/AnimationHelpers.h"
+#include "core/animation/AnimationPlayer.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/animation/CompositorAnimations.h"
-#include "core/animation/KeyframeAnimationEffect.h"
-#include "core/animation/Player.h"
+#include "core/animation/KeyframeEffectModel.h"
+#include "core/animation/interpolation/Interpolation.h"
#include "core/dom/Element.h"
+#include "core/frame/UseCounter.h"
+#include "core/rendering/RenderLayer.h"
namespace WebCore {
-PassRefPtr<Animation> Animation::create(PassRefPtr<Element> target, PassRefPtr<AnimationEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelegate> eventDelegate)
+PassRefPtrWillBeRawPtr<Animation> Animation::create(Element* target, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelegate> eventDelegate)
{
- return adoptRef(new Animation(target, effect, timing, priority, eventDelegate));
+ return adoptRefWillBeNoop(new Animation(target, effect, timing, priority, eventDelegate));
}
-Animation::Animation(PassRefPtr<Element> target, PassRefPtr<AnimationEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelegate> eventDelegate)
- : TimedItem(timing, eventDelegate)
+PassRefPtrWillBeRawPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Dictionary& timingInputDictionary)
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+ return create(element, effect, TimingInput::convert(timingInputDictionary));
+}
+PassRefPtrWillBeRawPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, double duration)
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+ return create(element, effect, TimingInput::convert(duration));
+}
+PassRefPtrWillBeRawPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr<AnimationEffect> effect)
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+ return create(element, effect, Timing());
+}
+PassRefPtrWillBeRawPtr<Animation> Animation::create(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, const Dictionary& timingInputDictionary, ExceptionState& exceptionState)
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+ if (element)
+ UseCounter::count(element->document(), UseCounter::AnimationConstructorKeyframeListEffectObjectTiming);
+ return create(element, EffectInput::convert(element, keyframeDictionaryVector, exceptionState), TimingInput::convert(timingInputDictionary));
+}
+PassRefPtrWillBeRawPtr<Animation> Animation::create(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, double duration, ExceptionState& exceptionState)
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+ if (element)
+ UseCounter::count(element->document(), UseCounter::AnimationConstructorKeyframeListEffectDoubleTiming);
+ return create(element, EffectInput::convert(element, keyframeDictionaryVector, exceptionState), TimingInput::convert(duration));
+}
+PassRefPtrWillBeRawPtr<Animation> Animation::create(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState& exceptionState)
+{
+ ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+ if (element)
+ UseCounter::count(element->document(), UseCounter::AnimationConstructorKeyframeListEffectNoTiming);
+ return create(element, EffectInput::convert(element, keyframeDictionaryVector, exceptionState), Timing());
+}
+
+Animation::Animation(Element* target, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelegate> eventDelegate)
+ : AnimationNode(timing, eventDelegate)
, m_target(target)
, m_effect(effect)
- , m_activeInAnimationStack(false)
+ , m_sampledEffect(nullptr)
, m_priority(priority)
{
+#if !ENABLE(OILPAN)
+ if (m_target)
+ m_target->ensureActiveAnimations().addAnimation(this);
+#endif
}
-void Animation::didAttach()
+Animation::~Animation()
{
+#if !ENABLE(OILPAN)
if (m_target)
- m_target->ensureActiveAnimations()->players().add(player());
+ m_target->activeAnimations()->notifyAnimationDestroyed(this);
+#endif
}
-void Animation::willDetach()
+void Animation::attach(AnimationPlayer* player)
+{
+ if (m_target) {
+ m_target->ensureActiveAnimations().addPlayer(player);
+ m_target->setNeedsAnimationStyleRecalc();
+ }
+ AnimationNode::attach(player);
+}
+
+void Animation::detach()
{
if (m_target)
- m_target->activeAnimations()->players().remove(player());
- if (m_activeInAnimationStack)
+ m_target->activeAnimations()->removePlayer(player());
+ if (m_sampledEffect)
clearEffects();
+ AnimationNode::detach();
+}
+
+void Animation::specifiedTimingChanged()
+{
+ cancelAnimationOnCompositor();
+ if (player()) {
+ // FIXME: Needs to consider groups when added.
+ ASSERT(player()->source() == this);
+ player()->schedulePendingAnimationOnCompositor();
+ }
}
static AnimationStack& ensureAnimationStack(Element* element)
{
- return element->ensureActiveAnimations()->defaultStack();
+ return element->ensureActiveAnimations().defaultStack();
}
-bool Animation::applyEffects(bool previouslyInEffect)
+void Animation::applyEffects()
{
ASSERT(isInEffect());
+ ASSERT(player());
if (!m_target || !m_effect)
- return false;
-
- if (player() && !previouslyInEffect) {
- ensureAnimationStack(m_target.get()).add(this);
- m_activeInAnimationStack = true;
- }
+ return;
double iteration = currentIteration();
ASSERT(iteration >= 0);
// FIXME: Handle iteration values which overflow int.
- m_compositableValues = m_effect->sample(static_cast<int>(iteration), timeFraction());
- if (player()) {
- m_target->setNeedsAnimationStyleRecalc();
- return true;
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > interpolations = m_effect->sample(static_cast<int>(iteration), timeFraction(), iterationDuration());
+ if (m_sampledEffect) {
+ m_sampledEffect->setInterpolations(interpolations.release());
+ } else if (!interpolations->isEmpty()) {
+ OwnPtrWillBeRawPtr<SampledEffect> sampledEffect = SampledEffect::create(this, interpolations.release());
+ m_sampledEffect = sampledEffect.get();
+ ensureAnimationStack(m_target).add(sampledEffect.release());
+ } else {
+ return;
}
- return false;
+
+ m_target->setNeedsAnimationStyleRecalc();
}
void Animation::clearEffects()
{
ASSERT(player());
- ASSERT(m_activeInAnimationStack);
- ensureAnimationStack(m_target.get()).remove(this);
+ ASSERT(m_sampledEffect);
+
+ m_sampledEffect->clear();
+ m_sampledEffect = nullptr;
cancelAnimationOnCompositor();
- m_activeInAnimationStack = false;
- m_compositableValues.clear();
m_target->setNeedsAnimationStyleRecalc();
invalidate();
}
-bool Animation::updateChildrenAndEffects() const
+void Animation::updateChildrenAndEffects() const
{
if (!m_effect)
- return false;
-
+ return;
if (isInEffect())
- return const_cast<Animation*>(this)->applyEffects(m_activeInAnimationStack);
-
- if (m_activeInAnimationStack) {
+ const_cast<Animation*>(this)->applyEffects();
+ else if (m_sampledEffect)
const_cast<Animation*>(this)->clearEffects();
- return true;
- }
- return false;
}
-double Animation::calculateTimeToEffectChange(double localTime, double timeToNextIteration) const
+double Animation::calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const
{
- const double activeStartTime = startTime() + specified().startDelay;
+ const double start = startTimeInternal() + specifiedTiming().startDelay;
+ const double end = start + activeDurationInternal();
+
switch (phase()) {
case PhaseBefore:
- return activeStartTime - localTime;
+ ASSERT(start >= localTime);
+ return forwards
+ ? start - localTime
+ : std::numeric_limits<double>::infinity();
case PhaseActive:
- if (hasActiveAnimationsOnCompositor()) {
+ if (forwards && hasActiveAnimationsOnCompositor()) {
+ ASSERT(specifiedTiming().playbackRate == 1);
// Need service to apply fill / fire events.
- const double activeEndTime = activeStartTime + activeDuration();
- return std::min(activeEndTime - localTime, timeToNextIteration);
+ const double timeToEnd = end - localTime;
+ if (hasEvents()) {
+ return std::min(timeToEnd, timeToNextIteration);
+ } else {
+ return timeToEnd;
+ }
}
return 0;
case PhaseAfter:
+ ASSERT(localTime >= end);
// If this Animation is still in effect then it will need to update
// when its parent goes out of effect. We have no way of knowing when
// that will be, however, so the parent will need to supply it.
- return std::numeric_limits<double>::infinity();
- case PhaseNone:
+ return forwards
+ ? std::numeric_limits<double>::infinity()
+ : localTime - end;
default:
ASSERT_NOT_REACHED();
- return 0;
+ return std::numeric_limits<double>::infinity();
}
}
+void Animation::notifySampledEffectRemovedFromAnimationStack()
+{
+ ASSERT(m_sampledEffect);
+ m_sampledEffect = nullptr;
+}
+
+#if !ENABLE(OILPAN)
+void Animation::notifyElementDestroyed()
+{
+ // If our player is kept alive just by the sampledEffect, we might get our
+ // destructor called when we call SampledEffect::clear(), so we need to
+ // clear m_sampledEffect first.
+ m_target = nullptr;
+ clearEventDelegate();
+ SampledEffect* sampledEffect = m_sampledEffect;
+ m_sampledEffect = nullptr;
+ if (sampledEffect)
+ sampledEffect->clear();
+}
+#endif
+
bool Animation::isCandidateForAnimationOnCompositor() const
{
if (!effect() || !m_target)
return false;
- return CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(specified(), *effect());
+ return CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(specifiedTiming(), *effect());
}
-bool Animation::maybeStartAnimationOnCompositor()
+bool Animation::maybeStartAnimationOnCompositor(double startTime)
{
ASSERT(!hasActiveAnimationsOnCompositor());
if (!isCandidateForAnimationOnCompositor())
return false;
- if (!CompositorAnimations::instance()->canStartAnimationOnCompositor(*m_target.get()))
+ if (!CompositorAnimations::instance()->canStartAnimationOnCompositor(*m_target))
return false;
- if (!CompositorAnimations::instance()->startAnimationOnCompositor(*m_target.get(), specified(), *effect(), m_compositorAnimationIds))
+ if (!CompositorAnimations::instance()->startAnimationOnCompositor(*m_target, startTime, specifiedTiming(), *effect(), m_compositorAnimationIds))
return false;
ASSERT(!m_compositorAnimationIds.isEmpty());
return true;
@@ -183,12 +283,16 @@ bool Animation::affects(CSSPropertyID property) const
void Animation::cancelAnimationOnCompositor()
{
+ // FIXME: cancelAnimationOnCompositor is called from withins style recalc.
+ // This queries compositingState, which is not necessarily up to date.
+ // https://code.google.com/p/chromium/issues/detail?id=339847
+ DisableCompositingQueryAsserts disabler;
if (!hasActiveAnimationsOnCompositor())
return;
if (!m_target || !m_target->renderer())
return;
for (size_t i = 0; i < m_compositorAnimationIds.size(); ++i)
- CompositorAnimations::instance()->cancelAnimationOnCompositor(*m_target.get(), m_compositorAnimationIds[i]);
+ CompositorAnimations::instance()->cancelAnimationOnCompositor(*m_target, m_compositorAnimationIds[i]);
m_compositorAnimationIds.clear();
}
@@ -198,7 +302,15 @@ void Animation::pauseAnimationForTestingOnCompositor(double pauseTime)
if (!m_target || !m_target->renderer())
return;
for (size_t i = 0; i < m_compositorAnimationIds.size(); ++i)
- CompositorAnimations::instance()->pauseAnimationForTestingOnCompositor(*m_target.get(), m_compositorAnimationIds[i], pauseTime);
+ CompositorAnimations::instance()->pauseAnimationForTestingOnCompositor(*m_target, m_compositorAnimationIds[i], pauseTime);
+}
+
+void Animation::trace(Visitor* visitor)
+{
+ visitor->trace(m_target);
+ visitor->trace(m_effect);
+ visitor->trace(m_sampledEffect);
+ AnimationNode::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/Animation.h b/chromium/third_party/WebKit/Source/core/animation/Animation.h
index f4ad206d503..f0340516108 100644
--- a/chromium/third_party/WebKit/Source/core/animation/Animation.h
+++ b/chromium/third_party/WebKit/Source/core/animation/Animation.h
@@ -32,66 +32,81 @@
#define Animation_h
#include "core/animation/AnimationEffect.h"
-#include "core/animation/TimedItem.h"
+#include "core/animation/AnimationNode.h"
+#include "core/animation/EffectInput.h"
+#include "core/animation/TimingInput.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
+class Dictionary;
class Element;
+class ExceptionState;
+class SampledEffect;
-class Animation FINAL : public TimedItem {
-
+class Animation FINAL : public AnimationNode {
public:
enum Priority { DefaultPriority, TransitionPriority };
- static PassRefPtr<Animation> create(PassRefPtr<Element>, PassRefPtr<AnimationEffect>, const Timing&, Priority = DefaultPriority, PassOwnPtr<EventDelegate> = nullptr);
- virtual bool isAnimation() const OVERRIDE FINAL { return true; }
+ static PassRefPtrWillBeRawPtr<Animation> create(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, Priority = DefaultPriority, PassOwnPtr<EventDelegate> = nullptr);
+ // Web Animations API Bindings constructors.
+ static PassRefPtrWillBeRawPtr<Animation> create(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>, const Dictionary& timingInputDictionary);
+ static PassRefPtrWillBeRawPtr<Animation> create(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>, double duration);
+ static PassRefPtrWillBeRawPtr<Animation> create(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>);
+ static PassRefPtrWillBeRawPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector, const Dictionary& timingInputDictionary, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector, double duration, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState&);
+
+ virtual ~Animation();
- const AnimationEffect::CompositableValueList* compositableValues() const
- {
- ASSERT(m_compositableValues);
- return m_compositableValues.get();
- }
+ virtual bool isAnimation() const OVERRIDE { return true; }
bool affects(CSSPropertyID) const;
const AnimationEffect* effect() const { return m_effect.get(); }
+ AnimationEffect* effect() { return m_effect.get(); }
Priority priority() const { return m_priority; }
- Element* target() { return m_target.get(); }
+ Element* target() { return m_target; }
+
+ void notifySampledEffectRemovedFromAnimationStack();
+#if !ENABLE(OILPAN)
+ void notifyElementDestroyed();
+#endif
bool isCandidateForAnimationOnCompositor() const;
- // Must only be called once and assumes to be part of a player without a start time.
- bool maybeStartAnimationOnCompositor();
+ // Must only be called once.
+ bool maybeStartAnimationOnCompositor(double startTime);
bool hasActiveAnimationsOnCompositor() const;
bool hasActiveAnimationsOnCompositor(CSSPropertyID) const;
void cancelAnimationOnCompositor();
void pauseAnimationForTestingOnCompositor(double pauseTime);
+ virtual void trace(Visitor*);
+
protected:
- // Returns whether style recalc was triggered.
- virtual bool applyEffects(bool previouslyInEffect);
- virtual void clearEffects();
- virtual bool updateChildrenAndEffects() const OVERRIDE FINAL;
- virtual void didAttach() OVERRIDE FINAL;
- virtual void willDetach() OVERRIDE FINAL;
- virtual double calculateTimeToEffectChange(double inheritedTime, double timeToNextIteration) const OVERRIDE FINAL;
+ void applyEffects();
+ void clearEffects();
+ virtual void updateChildrenAndEffects() const OVERRIDE;
+ virtual void attach(AnimationPlayer*) OVERRIDE;
+ virtual void detach() OVERRIDE;
+ virtual void specifiedTimingChanged() OVERRIDE;
+ virtual double calculateTimeToEffectChange(bool forwards, double inheritedTime, double timeToNextIteration) const OVERRIDE;
private:
- Animation(PassRefPtr<Element>, PassRefPtr<AnimationEffect>, const Timing&, Priority, PassOwnPtr<EventDelegate>);
-
- RefPtr<Element> m_target;
- RefPtr<AnimationEffect> m_effect;
+ Animation(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, Priority, PassOwnPtr<EventDelegate>);
- bool m_activeInAnimationStack;
- OwnPtr<AnimationEffect::CompositableValueList> m_compositableValues;
+ RawPtrWillBeMember<Element> m_target;
+ RefPtrWillBeMember<AnimationEffect> m_effect;
+ RawPtrWillBeMember<SampledEffect> m_sampledEffect;
Priority m_priority;
Vector<int> m_compositorAnimationIds;
- friend class CSSAnimations;
+ friend class AnimationAnimationV8Test;
};
-DEFINE_TYPE_CASTS(Animation, TimedItem, timedItem, timedItem->isAnimation(), timedItem.isAnimation());
+DEFINE_TYPE_CASTS(Animation, AnimationNode, animationNode, animationNode->isAnimation(), animationNode.isAnimation());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/Animation.idl b/chromium/third_party/WebKit/Source/core/animation/Animation.idl
new file mode 100644
index 00000000000..02b98bf8234
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/Animation.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// http://dev.w3.org/fxtf/web-animations/#idl-def-Animation
+
+[
+ // FIXME: should be optional union type http://crbug.com/240176
+ Constructor(Element? target, sequence<Dictionary> keyframes),
+ Constructor(Element? target, sequence<Dictionary> keyframes, double timingInput),
+ Constructor(Element? target, sequence<Dictionary> keyframes, Dictionary timingInput),
+ RaisesException=Constructor,
+ RuntimeEnabled=WebAnimationsAPI,
+] interface Animation : AnimationNode {
+};
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationClock.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationClock.cpp
new file mode 100644
index 00000000000..d51c95e7aed
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationClock.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/AnimationClock.h"
+
+#include "wtf/CurrentTime.h"
+#include <math.h>
+
+namespace {
+
+// FIXME: This is an approximation of time between frames, used when
+// ticking the animation clock outside of animation frame callbacks.
+// Ideally this would be generated by the compositor.
+const double approximateFrameTime = 1 / 60.0;
+
+}
+
+namespace WebCore {
+
+unsigned AnimationClock::s_currentTask = 0;
+
+void AnimationClock::updateTime(double time)
+{
+ if (time > m_time)
+ m_time = time;
+ m_currentTask = s_currentTask;
+}
+
+double AnimationClock::currentTime()
+{
+ if (m_currentTask != s_currentTask) {
+ const double currentTime = m_monotonicallyIncreasingTime();
+ if (m_time < currentTime) {
+ // Advance to the first estimated frame after the current time.
+ const double frameShift = fmod(currentTime - m_time, approximateFrameTime);
+ const double newTime = currentTime + (approximateFrameTime - frameShift);
+ ASSERT(newTime >= currentTime);
+ ASSERT(newTime <= currentTime + approximateFrameTime);
+ updateTime(newTime);
+ } else {
+ m_currentTask = s_currentTask;
+ }
+ }
+ return m_time;
+}
+
+void AnimationClock::resetTimeForTesting()
+{
+ m_time = 0;
+ m_currentTask = 0;
+ s_currentTask = 0;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationClock.h b/chromium/third_party/WebKit/Source/core/animation/AnimationClock.h
index f6a2cdb8499..b5bb0d9adc6 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimationClock.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationClock.h
@@ -32,45 +32,33 @@
#define AnimationClock_h
#include "wtf/CurrentTime.h"
+#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
+#include <limits>
namespace WebCore {
class AnimationClock {
+ WTF_MAKE_NONCOPYABLE(AnimationClock);
public:
- static PassOwnPtr<AnimationClock> create(WTF::TimeFunction monotonicallyIncreasingTime = WTF::monotonicallyIncreasingTime)
- {
- return adoptPtr(new AnimationClock(monotonicallyIncreasingTime));
- }
-
- void updateTime(double time)
- {
- if (time > m_time)
- m_time = time;
- m_frozen = true;
- }
-
- double currentTime()
+ explicit AnimationClock(WTF::TimeFunction monotonicallyIncreasingTime = WTF::monotonicallyIncreasingTime)
+ : m_monotonicallyIncreasingTime(monotonicallyIncreasingTime)
+ , m_time(0)
+ , m_currentTask(std::numeric_limits<unsigned>::max())
{
- if (!m_frozen)
- updateTime(m_monotonicallyIncreasingTime());
- return m_time;
}
- void unfreeze() { m_frozen = false; }
+ void updateTime(double time);
+ double currentTime();
+ void resetTimeForTesting();
- void resetTimeForTesting() { m_time = 0; m_frozen = true; }
+ static void notifyTaskStart() { ++s_currentTask; }
private:
- AnimationClock(WTF::TimeFunction monotonicallyIncreasingTime)
- : m_monotonicallyIncreasingTime(monotonicallyIncreasingTime)
- , m_time(0)
- , m_frozen(false)
- {
- }
WTF::TimeFunction m_monotonicallyIncreasingTime;
double m_time;
- bool m_frozen;
+ unsigned m_currentTask;
+ static unsigned s_currentTask;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationClockTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationClockTest.cpp
index 248da7badee..89412585331 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimationClockTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationClockTest.cpp
@@ -39,41 +39,105 @@ using namespace WebCore;
namespace {
class AnimationAnimationClockTest : public ::testing::Test {
+public:
+ AnimationAnimationClockTest()
+ : animationClock(mockTimeFunction)
+ { }
protected:
virtual void SetUp()
{
- animationClock = AnimationClock::create(mockTimeFunction);
- mockTime = 200;
+ mockTime = 0;
+ animationClock.resetTimeForTesting();
}
static double mockTimeFunction()
{
- return mockTime++;
+ return mockTime;
}
static double mockTime;
- OwnPtr<AnimationClock> animationClock;
+ AnimationClock animationClock;
};
double AnimationAnimationClockTest::mockTime;
-TEST_F(AnimationAnimationClockTest, CurrentTime)
+TEST_F(AnimationAnimationClockTest, TimeIsGreaterThanZeroForUnitTests)
{
- EXPECT_EQ(200, animationClock->currentTime());
- EXPECT_EQ(200, animationClock->currentTime());
- animationClock->unfreeze();
- EXPECT_EQ(201, animationClock->currentTime());
- EXPECT_EQ(201, animationClock->currentTime());
+ AnimationClock clock;
+ // unit tests outside core/animation shouldn't need to do anything to get
+ // a non-zero currentTime().
+ EXPECT_GT(clock.currentTime(), 0);
}
-TEST_F(AnimationAnimationClockTest, UpdateTime)
+TEST_F(AnimationAnimationClockTest, TimeDoesNotChange)
{
- animationClock->updateTime(100);
- EXPECT_EQ(100, animationClock->currentTime());
- EXPECT_EQ(100, animationClock->currentTime());
- animationClock->updateTime(150);
- EXPECT_EQ(150, animationClock->currentTime());
- EXPECT_EQ(150, animationClock->currentTime());
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+ EXPECT_EQ(100, animationClock.currentTime());
+}
+
+TEST_F(AnimationAnimationClockTest, TimeAdvancesWhenUpdated)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ animationClock.updateTime(200);
+ EXPECT_EQ(200, animationClock.currentTime());
+}
+
+TEST_F(AnimationAnimationClockTest, TimeAdvancesToTaskTime)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 150;
+ AnimationClock::notifyTaskStart();
+ EXPECT_GE(animationClock.currentTime(), mockTime);
+}
+
+TEST_F(AnimationAnimationClockTest, TimeAdvancesToTaskTimeOnlyWhenRequired)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ AnimationClock::notifyTaskStart();
+ animationClock.updateTime(125);
+ EXPECT_EQ(125, animationClock.currentTime());
+}
+
+TEST_F(AnimationAnimationClockTest, UpdateTimeIsMonotonic)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ // Update can't go backwards.
+ animationClock.updateTime(50);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 50;
+ AnimationClock::notifyTaskStart();
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 150;
+ AnimationClock::notifyTaskStart();
+ EXPECT_GE(animationClock.currentTime(), mockTime);
+
+ // Update can't go backwards after advance to estimate.
+ animationClock.updateTime(100);
+ EXPECT_GE(animationClock.currentTime(), mockTime);
+}
+
+TEST_F(AnimationAnimationClockTest, CurrentTimeUpdatesTask)
+{
+ animationClock.updateTime(100);
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 100;
+ AnimationClock::notifyTaskStart();
+ EXPECT_EQ(100, animationClock.currentTime());
+
+ mockTime = 150;
+ EXPECT_EQ(100, animationClock.currentTime());
}
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationEffect.h b/chromium/third_party/WebKit/Source/core/animation/AnimationEffect.h
index d675a5f4a9e..a8772648cf1 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimationEffect.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationEffect.h
@@ -31,38 +31,30 @@
#ifndef AnimationEffect_h
#define AnimationEffect_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class AnimatableValue;
+class Interpolation;
-class AnimationEffect : public RefCounted<AnimationEffect> {
+class AnimationEffect : public RefCountedWillBeGarbageCollectedFinalized<AnimationEffect> {
public:
enum CompositeOperation {
CompositeReplace,
CompositeAdd,
};
- // Encapsulates the value which results from applying a set of composition operations onto an
- // underlying value. It is used to represent the output of the effect phase of the Web
- // Animations model.
- class CompositableValue : public RefCounted<CompositableValue> {
- public:
- virtual ~CompositableValue() { }
- virtual bool dependsOnUnderlyingValue() const = 0;
- virtual PassRefPtr<AnimatableValue> compositeOnto(const AnimatableValue*) const = 0;
- };
virtual ~AnimationEffect() { }
- typedef HashMap<CSSPropertyID, RefPtr<CompositableValue> > CompositableValueMap;
- typedef Vector<std::pair<CSSPropertyID, RefPtr<CompositableValue> > > CompositableValueList;
- virtual PassOwnPtr<CompositableValueList> sample(int iteration, double fraction) const = 0;
+ virtual PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample(int iteration, double fraction, double iterationDuration) const = 0;
virtual bool affects(CSSPropertyID) { return false; };
- virtual bool isKeyframeAnimationEffect() const { return false; }
+ virtual bool isKeyframeEffectModel() const { return false; }
+
+ virtual void trace(Visitor*) { }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationEffect.idl b/chromium/third_party/WebKit/Source/core/animation/AnimationEffect.idl
new file mode 100644
index 00000000000..f5dc6ce2f57
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationEffect.idl
@@ -0,0 +1,10 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=WebAnimationsAPI,
+ NoInterfaceObject,
+ WillBeGarbageCollected
+] interface AnimationEffect {
+};
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationHelpers.h b/chromium/third_party/WebKit/Source/core/animation/AnimationHelpers.h
new file mode 100644
index 00000000000..daeb2d5b48f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationHelpers.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AnimationHelpers_h
+#define AnimationHelpers_h
+
+#include "core/css/parser/BisonCSSParser.h"
+#include "wtf/text/StringBuilder.h"
+
+namespace WebCore {
+
+static inline CSSPropertyID camelCaseCSSPropertyNameToID(const String& propertyName)
+{
+ if (propertyName.find('-') != kNotFound)
+ return CSSPropertyInvalid;
+
+ StringBuilder builder;
+ size_t position = 0;
+ size_t end;
+ while ((end = propertyName.find(isASCIIUpper, position)) != kNotFound) {
+ builder.append(propertyName.substring(position, end - position) + "-" + toASCIILower((propertyName)[end]));
+ position = end + 1;
+ }
+ builder.append(propertyName.substring(position));
+ // Doesn't handle prefixed properties.
+ CSSPropertyID id = cssPropertyID(builder.toString());
+ return id;
+}
+
+} // namespace WebCore
+
+#endif // AnimationHelpers_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationHelpersTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationHelpersTest.cpp
new file mode 100644
index 00000000000..df3727f7d98
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationHelpersTest.cpp
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/AnimationHelpers.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+TEST(AnimationAnimationHelpersTest, ParseCamelCasePropertyNames)
+{
+ EXPECT_EQ(CSSPropertyInvalid, camelCaseCSSPropertyNameToID(String("line-height")));
+ EXPECT_EQ(CSSPropertyLineHeight, camelCaseCSSPropertyNameToID(String("lineHeight")));
+ EXPECT_EQ(CSSPropertyBorderTopWidth, camelCaseCSSPropertyNameToID(String("borderTopWidth")));
+ EXPECT_EQ(CSSPropertyWidth, camelCaseCSSPropertyNameToID(String("width")));
+ EXPECT_EQ(CSSPropertyInvalid, camelCaseCSSPropertyNameToID(String("Width")));
+ EXPECT_EQ(CSSPropertyInvalid, camelCaseCSSPropertyNameToID(String("-webkit-transform")));
+ EXPECT_EQ(CSSPropertyInvalid, camelCaseCSSPropertyNameToID(String("webkitTransform")));
+ EXPECT_EQ(CSSPropertyInvalid, camelCaseCSSPropertyNameToID(String("cssFloat")));
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationNode.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationNode.cpp
new file mode 100644
index 00000000000..1e5f863074b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationNode.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/AnimationNode.h"
+
+#include "core/animation/AnimationNodeTiming.h"
+#include "core/animation/AnimationPlayer.h"
+#include "core/animation/TimingCalculations.h"
+
+namespace WebCore {
+
+namespace {
+
+Timing::FillMode resolvedFillMode(Timing::FillMode fillMode, bool isAnimation)
+{
+ if (fillMode != Timing::FillModeAuto)
+ return fillMode;
+ if (isAnimation)
+ return Timing::FillModeNone;
+ return Timing::FillModeBoth;
+}
+
+} // namespace
+
+AnimationNode::AnimationNode(const Timing& timing, PassOwnPtr<EventDelegate> eventDelegate)
+ : m_parent(nullptr)
+ , m_startTime(0)
+ , m_player(nullptr)
+ , m_timing(timing)
+ , m_eventDelegate(eventDelegate)
+ , m_calculated()
+ , m_needsUpdate(true)
+ , m_lastUpdateTime(nullValue())
+{
+ m_timing.assertValid();
+}
+
+double AnimationNode::iterationDuration() const
+{
+ double result = std::isnan(m_timing.iterationDuration) ? intrinsicIterationDuration() : m_timing.iterationDuration;
+ ASSERT(result >= 0);
+ return result;
+}
+
+double AnimationNode::repeatedDuration() const
+{
+ const double result = multiplyZeroAlwaysGivesZero(iterationDuration(), m_timing.iterationCount);
+ ASSERT(result >= 0);
+ return result;
+}
+
+double AnimationNode::activeDurationInternal() const
+{
+ const double result = m_timing.playbackRate
+ ? repeatedDuration() / std::abs(m_timing.playbackRate)
+ : std::numeric_limits<double>::infinity();
+ ASSERT(result >= 0);
+ return result;
+}
+
+void AnimationNode::updateSpecifiedTiming(const Timing& timing)
+{
+ // FIXME: Test whether the timing is actually different?
+ m_timing = timing;
+ invalidate();
+ if (m_player)
+ m_player->setOutdated();
+ specifiedTimingChanged();
+}
+
+void AnimationNode::updateInheritedTime(double inheritedTime, TimingUpdateReason reason) const
+{
+ bool needsUpdate = m_needsUpdate || (m_lastUpdateTime != inheritedTime && !(isNull(m_lastUpdateTime) && isNull(inheritedTime)));
+ m_needsUpdate = false;
+ m_lastUpdateTime = inheritedTime;
+
+ const double localTime = inheritedTime - m_startTime;
+ double timeToNextIteration = std::numeric_limits<double>::infinity();
+ if (needsUpdate) {
+ const double activeDuration = this->activeDurationInternal();
+
+ const Phase currentPhase = calculatePhase(activeDuration, localTime, m_timing);
+ // FIXME: parentPhase depends on groups being implemented.
+ const AnimationNode::Phase parentPhase = AnimationNode::PhaseActive;
+ const double activeTime = calculateActiveTime(activeDuration, resolvedFillMode(m_timing.fillMode, isAnimation()), localTime, parentPhase, currentPhase, m_timing);
+
+ double currentIteration;
+ double timeFraction;
+ if (const double iterationDuration = this->iterationDuration()) {
+ const double startOffset = multiplyZeroAlwaysGivesZero(m_timing.iterationStart, iterationDuration);
+ ASSERT(startOffset >= 0);
+ const double scaledActiveTime = calculateScaledActiveTime(activeDuration, activeTime, startOffset, m_timing);
+ const double iterationTime = calculateIterationTime(iterationDuration, repeatedDuration(), scaledActiveTime, startOffset, m_timing);
+
+ currentIteration = calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, m_timing);
+ timeFraction = calculateTransformedTime(currentIteration, iterationDuration, iterationTime, m_timing) / iterationDuration;
+
+ if (!isNull(iterationTime)) {
+ timeToNextIteration = (iterationDuration - iterationTime) / std::abs(m_timing.playbackRate);
+ if (activeDuration - activeTime < timeToNextIteration)
+ timeToNextIteration = std::numeric_limits<double>::infinity();
+ }
+ } else {
+ const double localIterationDuration = 1;
+ const double localRepeatedDuration = localIterationDuration * m_timing.iterationCount;
+ ASSERT(localRepeatedDuration >= 0);
+ const double localActiveDuration = m_timing.playbackRate ? localRepeatedDuration / std::abs(m_timing.playbackRate) : std::numeric_limits<double>::infinity();
+ ASSERT(localActiveDuration >= 0);
+ const double localLocalTime = localTime < m_timing.startDelay ? localTime : localActiveDuration + m_timing.startDelay;
+ const AnimationNode::Phase localCurrentPhase = calculatePhase(localActiveDuration, localLocalTime, m_timing);
+ const double localActiveTime = calculateActiveTime(localActiveDuration, resolvedFillMode(m_timing.fillMode, isAnimation()), localLocalTime, parentPhase, localCurrentPhase, m_timing);
+ const double startOffset = m_timing.iterationStart * localIterationDuration;
+ ASSERT(startOffset >= 0);
+ const double scaledActiveTime = calculateScaledActiveTime(localActiveDuration, localActiveTime, startOffset, m_timing);
+ const double iterationTime = calculateIterationTime(localIterationDuration, localRepeatedDuration, scaledActiveTime, startOffset, m_timing);
+
+ currentIteration = calculateCurrentIteration(localIterationDuration, iterationTime, scaledActiveTime, m_timing);
+ timeFraction = calculateTransformedTime(currentIteration, localIterationDuration, iterationTime, m_timing);
+ }
+
+ m_calculated.currentIteration = currentIteration;
+ m_calculated.timeFraction = timeFraction;
+
+ m_calculated.phase = currentPhase;
+ m_calculated.isInEffect = !isNull(activeTime);
+ m_calculated.isInPlay = phase() == PhaseActive && (!m_parent || m_parent->isInPlay());
+ m_calculated.isCurrent = phase() == PhaseBefore || isInPlay() || (m_parent && m_parent->isCurrent());
+ m_calculated.localTime = m_lastUpdateTime - m_startTime;
+ }
+
+ // Test for events even if timing didn't need an update as the player may have gained a start time.
+ // FIXME: Refactor so that we can ASSERT(m_player) here, this is currently required to be nullable for testing.
+ if (reason == TimingUpdateForAnimationFrame && (!m_player || m_player->hasStartTime())) {
+ if (m_eventDelegate)
+ m_eventDelegate->onEventCondition(this);
+ }
+
+ if (needsUpdate) {
+ // FIXME: This probably shouldn't be recursive.
+ updateChildrenAndEffects();
+ m_calculated.timeToForwardsEffectChange = calculateTimeToEffectChange(true, localTime, timeToNextIteration);
+ m_calculated.timeToReverseEffectChange = calculateTimeToEffectChange(false, localTime, timeToNextIteration);
+ }
+}
+
+const AnimationNode::CalculatedTiming& AnimationNode::ensureCalculated() const
+{
+ if (!m_player)
+ return m_calculated;
+ if (m_player->outdated())
+ m_player->update(TimingUpdateOnDemand);
+ ASSERT(!m_player->outdated());
+ return m_calculated;
+}
+
+PassRefPtrWillBeRawPtr<AnimationNodeTiming> AnimationNode::timing()
+{
+ return AnimationNodeTiming::create(this);
+}
+
+void AnimationNode::trace(Visitor* visitor)
+{
+ visitor->trace(m_parent);
+ visitor->trace(m_player);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationNode.h b/chromium/third_party/WebKit/Source/core/animation/AnimationNode.h
new file mode 100644
index 00000000000..4c548541b75
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationNode.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AnimationNode_h
+#define AnimationNode_h
+
+#include "core/animation/Timing.h"
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class AnimationPlayer;
+class AnimationNode;
+class AnimationNodeTiming;
+
+enum TimingUpdateReason {
+ TimingUpdateOnDemand,
+ TimingUpdateForAnimationFrame
+};
+
+static inline bool isNull(double value)
+{
+ return std::isnan(value);
+}
+
+static inline double nullValue()
+{
+ return std::numeric_limits<double>::quiet_NaN();
+}
+
+class AnimationNode : public RefCountedWillBeGarbageCollectedFinalized<AnimationNode> {
+ friend class AnimationPlayer; // Calls attach/detach, updateInheritedTime.
+public:
+ // Note that logic in CSSAnimations depends on the order of these values.
+ enum Phase {
+ PhaseBefore,
+ PhaseActive,
+ PhaseAfter,
+ PhaseNone,
+ };
+
+ class EventDelegate {
+ public:
+ virtual ~EventDelegate() { };
+ virtual void onEventCondition(const AnimationNode*) = 0;
+ };
+
+ virtual ~AnimationNode() { }
+
+ virtual bool isAnimation() const { return false; }
+
+ Phase phase() const { return ensureCalculated().phase; }
+ bool isCurrent() const { return ensureCalculated().isCurrent; }
+ bool isInEffect() const { return ensureCalculated().isInEffect; }
+ bool isInPlay() const { return ensureCalculated().isInPlay; }
+ double timeToForwardsEffectChange() const { return ensureCalculated().timeToForwardsEffectChange; }
+ double timeToReverseEffectChange() const { return ensureCalculated().timeToReverseEffectChange; }
+
+ double currentIteration() const { return ensureCalculated().currentIteration; }
+ double iterationDuration() const;
+
+ // This method returns time in ms as it is unused except via the API.
+ double duration() const { return iterationDuration() * 1000; }
+
+ double activeDuration() const { return activeDurationInternal() * 1000; }
+ double activeDurationInternal() const;
+ double timeFraction() const { return ensureCalculated().timeFraction; }
+ double startTime() const { return m_startTime * 1000; }
+ double startTimeInternal() const { return m_startTime; }
+ double endTime() const { return endTimeInternal() * 1000; }
+ double endTimeInternal() const { return startTime() + specifiedTiming().startDelay + activeDurationInternal() + specifiedTiming().endDelay; }
+
+ const AnimationPlayer* player() const { return m_player; }
+ AnimationPlayer* player() { return m_player; }
+ AnimationPlayer* player(bool& isNull) { isNull = !m_player; return m_player; }
+ const Timing& specifiedTiming() const { return m_timing; }
+ PassRefPtrWillBeRawPtr<AnimationNodeTiming> timing();
+ void updateSpecifiedTiming(const Timing&);
+
+ // This method returns time in ms as it is unused except via the API.
+ double localTime(bool& isNull) const { isNull = !m_player; return ensureCalculated().localTime * 1000; }
+ double currentIteration(bool& isNull) const { isNull = !ensureCalculated().isInEffect; return ensureCalculated().currentIteration; }
+
+ virtual void trace(Visitor*);
+
+protected:
+ explicit AnimationNode(const Timing&, PassOwnPtr<EventDelegate> = nullptr);
+
+ // When AnimationNode receives a new inherited time via updateInheritedTime
+ // it will (if necessary) recalculate timings and (if necessary) call
+ // updateChildrenAndEffects.
+ void updateInheritedTime(double inheritedTime, TimingUpdateReason) const;
+ void invalidate() const { m_needsUpdate = true; };
+ bool hasEvents() const { return m_eventDelegate; }
+ void clearEventDelegate() { m_eventDelegate = nullptr; }
+
+ virtual void attach(AnimationPlayer* player)
+ {
+ m_player = player;
+ }
+
+ virtual void detach()
+ {
+ ASSERT(m_player);
+ m_player = nullptr;
+ }
+
+ double repeatedDuration() const;
+
+ virtual void updateChildrenAndEffects() const = 0;
+ virtual double intrinsicIterationDuration() const { return 0; };
+ virtual double calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const = 0;
+ virtual void specifiedTimingChanged() { }
+
+ // FIXME: m_parent and m_startTime are placeholders, they depend on timing groups.
+ RawPtrWillBeMember<AnimationNode> m_parent;
+ const double m_startTime;
+ RawPtrWillBeMember<AnimationPlayer> m_player;
+ Timing m_timing;
+ OwnPtr<EventDelegate> m_eventDelegate;
+
+ mutable struct CalculatedTiming {
+ Phase phase;
+ double currentIteration;
+ double timeFraction;
+ bool isCurrent;
+ bool isInEffect;
+ bool isInPlay;
+ double localTime;
+ double timeToForwardsEffectChange;
+ double timeToReverseEffectChange;
+ } m_calculated;
+ mutable bool m_needsUpdate;
+ mutable double m_lastUpdateTime;
+
+ const CalculatedTiming& ensureCalculated() const;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationNode.idl b/chromium/third_party/WebKit/Source/core/animation/AnimationNode.idl
new file mode 100644
index 00000000000..c04ede67dfc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationNode.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ RuntimeEnabled=WebAnimationsAPI,
+ WillBeGarbageCollected,
+] interface AnimationNode {
+ // Playback state
+ readonly attribute double? localTime;
+ readonly attribute unsigned long? currentIteration;
+
+ // Calculated timing
+ readonly attribute double startTime;
+ readonly attribute double duration;
+ readonly attribute double activeDuration;
+ readonly attribute double endTime;
+
+ readonly attribute Timing timing;
+ readonly attribute AnimationPlayer? player;
+};
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTest.cpp
new file mode 100644
index 00000000000..944c3c4f63a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTest.cpp
@@ -0,0 +1,775 @@
+/*
+ * Copyright (c) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/AnimationNode.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class TestAnimationNodeEventDelegate : public AnimationNode::EventDelegate {
+public:
+ virtual void onEventCondition(const AnimationNode* animationNode) OVERRIDE
+ {
+ m_eventTriggered = true;
+
+ }
+ void reset()
+ {
+ m_eventTriggered = false;
+ }
+ bool eventTriggered() { return m_eventTriggered; }
+
+private:
+ bool m_eventTriggered;
+};
+
+class TestAnimationNode : public AnimationNode {
+public:
+ static PassRefPtrWillBeRawPtr<TestAnimationNode> create(const Timing& specified)
+ {
+ return adoptRefWillBeNoop(new TestAnimationNode(specified, new TestAnimationNodeEventDelegate()));
+ }
+
+ void updateInheritedTime(double time)
+ {
+ updateInheritedTime(time, TimingUpdateForAnimationFrame);
+ }
+
+ void updateInheritedTime(double time, TimingUpdateReason reason)
+ {
+ m_eventDelegate->reset();
+ AnimationNode::updateInheritedTime(time, reason);
+ }
+
+ virtual void updateChildrenAndEffects() const OVERRIDE { }
+ void willDetach() { }
+ TestAnimationNodeEventDelegate* eventDelegate() { return m_eventDelegate; }
+ virtual double calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const OVERRIDE
+ {
+ m_localTime = localTime;
+ m_timeToNextIteration = timeToNextIteration;
+ return -1;
+ }
+ double takeLocalTime()
+ {
+ const double result = m_localTime;
+ m_localTime = nullValue();
+ return result;
+ }
+
+ double takeTimeToNextIteration()
+ {
+ const double result = m_timeToNextIteration;
+ m_timeToNextIteration = nullValue();
+ return result;
+ }
+
+private:
+ TestAnimationNode(const Timing& specified, TestAnimationNodeEventDelegate* eventDelegate)
+ : AnimationNode(specified, adoptPtr(eventDelegate))
+ , m_eventDelegate(eventDelegate)
+ {
+ }
+
+ TestAnimationNodeEventDelegate* m_eventDelegate;
+ mutable double m_localTime;
+ mutable double m_timeToNextIteration;
+};
+
+TEST(AnimationAnimationNodeTest, Sanity)
+{
+ Timing timing;
+ timing.iterationDuration = 2;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ EXPECT_EQ(0, animationNode->startTime());
+
+ animationNode->updateInheritedTime(0);
+
+ EXPECT_EQ(AnimationNode::PhaseActive, animationNode->phase());
+ EXPECT_TRUE(animationNode->isInPlay());
+ EXPECT_TRUE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->startTime());
+ EXPECT_EQ(2, animationNode->activeDurationInternal());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+
+ EXPECT_EQ(AnimationNode::PhaseActive, animationNode->phase());
+ EXPECT_TRUE(animationNode->isInPlay());
+ EXPECT_TRUE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->startTime());
+ EXPECT_EQ(2, animationNode->activeDurationInternal());
+ EXPECT_EQ(0.5, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(2);
+
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_FALSE(animationNode->isInPlay());
+ EXPECT_FALSE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->startTime());
+ EXPECT_EQ(2, animationNode->activeDurationInternal());
+ EXPECT_EQ(1, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(3);
+
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_FALSE(animationNode->isInPlay());
+ EXPECT_FALSE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->startTime());
+ EXPECT_EQ(2, animationNode->activeDurationInternal());
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, FillAuto)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(2);
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, FillForwards)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeForwards;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(2);
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, FillBackwards)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeBackwards;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(2);
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+}
+
+TEST(AnimationAnimationNodeTest, FillBoth)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeBoth;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(2);
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, StartDelay)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.startDelay = 0.5;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(0.5);
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1.5);
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroIteration)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.iterationCount = 0;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(0, animationNode->activeDurationInternal());
+ EXPECT_TRUE(isNull(animationNode->currentIteration()));
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(0, animationNode->activeDurationInternal());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, InfiniteIteration)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.iterationCount = std::numeric_limits<double>::infinity();
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_TRUE(isNull(animationNode->currentIteration()));
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), animationNode->activeDurationInternal());
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, Iteration)
+{
+ Timing timing;
+ timing.iterationCount = 2;
+ timing.iterationDuration = 2;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0.5, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(2);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(2);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(5);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, IterationStart)
+{
+ Timing timing;
+ timing.iterationStart = 1.2;
+ timing.iterationCount = 2.2;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeBoth;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_NEAR(0.2, animationNode->timeFraction(), 0.000000000000001);
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_NEAR(0.2, animationNode->timeFraction(), 0.000000000000001);
+
+ animationNode->updateInheritedTime(10);
+ EXPECT_EQ(3, animationNode->currentIteration());
+ EXPECT_NEAR(0.4, animationNode->timeFraction(), 0.000000000000001);
+}
+
+TEST(AnimationAnimationNodeTest, IterationAlternate)
+{
+ Timing timing;
+ timing.iterationCount = 10;
+ timing.iterationDuration = 1;
+ timing.direction = Timing::PlaybackDirectionAlternate;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(0.75);
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0.75, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1.75);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(0.25, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(2.75);
+ EXPECT_EQ(2, animationNode->currentIteration());
+ EXPECT_EQ(0.75, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, IterationAlternateReverse)
+{
+ Timing timing;
+ timing.iterationCount = 10;
+ timing.iterationDuration = 1;
+ timing.direction = Timing::PlaybackDirectionAlternateReverse;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(0.75);
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0.25, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1.75);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(0.75, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(2.75);
+ EXPECT_EQ(2, animationNode->currentIteration());
+ EXPECT_EQ(0.25, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationSanity)
+{
+ Timing timing;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ EXPECT_EQ(0, animationNode->startTime());
+
+ animationNode->updateInheritedTime(0);
+
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_FALSE(animationNode->isInPlay());
+ EXPECT_FALSE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->startTime());
+ EXPECT_EQ(0, animationNode->activeDurationInternal());
+ EXPECT_EQ(1, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_FALSE(animationNode->isInPlay());
+ EXPECT_FALSE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->startTime());
+ EXPECT_EQ(0, animationNode->activeDurationInternal());
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationFillForwards)
+{
+ Timing timing;
+ timing.fillMode = Timing::FillModeForwards;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(1, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationFillBackwards)
+{
+ Timing timing;
+ timing.fillMode = Timing::FillModeBackwards;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(1);
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationFillBoth)
+{
+ Timing timing;
+ timing.fillMode = Timing::FillModeBoth;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(1, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationStartDelay)
+{
+ Timing timing;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.startDelay = 0.5;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(0.5);
+ EXPECT_EQ(1, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1.5);
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationIterationStartAndCount)
+{
+ Timing timing;
+ timing.iterationStart = 0.1;
+ timing.iterationCount = 0.2;
+ timing.fillMode = Timing::FillModeBoth;
+ timing.startDelay = 0.3;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(0.1, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(0.3);
+ EXPECT_DOUBLE_EQ(0.3, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+ EXPECT_DOUBLE_EQ(0.3, animationNode->timeFraction());
+}
+
+// FIXME: Needs specification work.
+TEST(AnimationAnimationNodeTest, ZeroDurationInfiniteIteration)
+{
+ Timing timing;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.iterationCount = std::numeric_limits<double>::infinity();
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(0, animationNode->activeDurationInternal());
+ EXPECT_TRUE(isNull(animationNode->currentIteration()));
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(0, animationNode->activeDurationInternal());
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), animationNode->currentIteration());
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationIteration)
+{
+ Timing timing;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.iterationCount = 2;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_TRUE(isNull(animationNode->currentIteration()));
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(1, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationIterationStart)
+{
+ Timing timing;
+ timing.iterationStart = 1.2;
+ timing.iterationCount = 2.2;
+ timing.fillMode = Timing::FillModeBoth;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_NEAR(0.2, animationNode->timeFraction(), 0.000000000000001);
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(3, animationNode->currentIteration());
+ EXPECT_NEAR(0.4, animationNode->timeFraction(), 0.000000000000001);
+
+ animationNode->updateInheritedTime(10);
+ EXPECT_EQ(3, animationNode->currentIteration());
+ EXPECT_NEAR(0.4, animationNode->timeFraction(), 0.000000000000001);
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationIterationAlternate)
+{
+ Timing timing;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.iterationCount = 2;
+ timing.direction = Timing::PlaybackDirectionAlternate;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_TRUE(isNull(animationNode->currentIteration()));
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, ZeroDurationIterationAlternateReverse)
+{
+ Timing timing;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.iterationCount = 2;
+ timing.direction = Timing::PlaybackDirectionAlternateReverse;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(-1);
+ EXPECT_TRUE(isNull(animationNode->currentIteration()));
+ EXPECT_TRUE(isNull(animationNode->timeFraction()));
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(1, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+ EXPECT_EQ(1, animationNode->currentIteration());
+ EXPECT_EQ(1, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, InfiniteDurationSanity)
+{
+ Timing timing;
+ timing.iterationDuration = std::numeric_limits<double>::infinity();
+ timing.iterationCount = 1;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ EXPECT_EQ(0, animationNode->startTime());
+
+ animationNode->updateInheritedTime(0);
+
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), animationNode->activeDurationInternal());
+ EXPECT_EQ(AnimationNode::PhaseActive, animationNode->phase());
+ EXPECT_TRUE(animationNode->isInPlay());
+ EXPECT_TRUE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), animationNode->activeDurationInternal());
+ EXPECT_EQ(AnimationNode::PhaseActive, animationNode->phase());
+ EXPECT_TRUE(animationNode->isInPlay());
+ EXPECT_TRUE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+}
+
+// FIXME: Needs specification work.
+TEST(AnimationAnimationNodeTest, InfiniteDurationZeroIterations)
+{
+ Timing timing;
+ timing.iterationDuration = std::numeric_limits<double>::infinity();
+ timing.iterationCount = 0;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ EXPECT_EQ(0, animationNode->startTime());
+
+ animationNode->updateInheritedTime(0);
+
+ EXPECT_EQ(0, animationNode->activeDurationInternal());
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_FALSE(animationNode->isInPlay());
+ EXPECT_FALSE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_FALSE(animationNode->isInPlay());
+ EXPECT_FALSE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, InfiniteDurationInfiniteIterations)
+{
+ Timing timing;
+ timing.iterationDuration = std::numeric_limits<double>::infinity();
+ timing.iterationCount = std::numeric_limits<double>::infinity();
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ EXPECT_EQ(0, animationNode->startTime());
+
+ animationNode->updateInheritedTime(0);
+
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), animationNode->activeDurationInternal());
+ EXPECT_EQ(AnimationNode::PhaseActive, animationNode->phase());
+ EXPECT_TRUE(animationNode->isInPlay());
+ EXPECT_TRUE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(1);
+
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), animationNode->activeDurationInternal());
+ EXPECT_EQ(AnimationNode::PhaseActive, animationNode->phase());
+ EXPECT_TRUE(animationNode->isInPlay());
+ EXPECT_TRUE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, InfiniteDurationZeroPlaybackRate)
+{
+ Timing timing;
+ timing.iterationDuration = std::numeric_limits<double>::infinity();
+ timing.playbackRate = 0;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ EXPECT_EQ(0, animationNode->startTime());
+
+ animationNode->updateInheritedTime(0);
+
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), animationNode->activeDurationInternal());
+ EXPECT_EQ(AnimationNode::PhaseActive, animationNode->phase());
+ EXPECT_TRUE(animationNode->isInPlay());
+ EXPECT_TRUE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+
+ animationNode->updateInheritedTime(std::numeric_limits<double>::infinity());
+
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), animationNode->activeDurationInternal());
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_FALSE(animationNode->isInPlay());
+ EXPECT_FALSE(animationNode->isCurrent());
+ EXPECT_TRUE(animationNode->isInEffect());
+ EXPECT_EQ(0, animationNode->currentIteration());
+ EXPECT_EQ(0, animationNode->timeFraction());
+}
+
+TEST(AnimationAnimationNodeTest, EndTime)
+{
+ Timing timing;
+ timing.startDelay = 1;
+ timing.endDelay = 2;
+ timing.iterationDuration = 4;
+ timing.iterationCount = 2;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+ EXPECT_EQ(11, animationNode->endTimeInternal());
+}
+
+TEST(AnimationAnimationNodeTest, Events)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.iterationCount = 2;
+ timing.startDelay = 1;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(0.0, TimingUpdateOnDemand);
+ EXPECT_FALSE(animationNode->eventDelegate()->eventTriggered());
+
+ animationNode->updateInheritedTime(0.0, TimingUpdateForAnimationFrame);
+ EXPECT_TRUE(animationNode->eventDelegate()->eventTriggered());
+
+ animationNode->updateInheritedTime(1.5, TimingUpdateOnDemand);
+ EXPECT_FALSE(animationNode->eventDelegate()->eventTriggered());
+
+ animationNode->updateInheritedTime(1.5, TimingUpdateForAnimationFrame);
+ EXPECT_TRUE(animationNode->eventDelegate()->eventTriggered());
+
+}
+
+TEST(AnimationAnimationNodeTest, TimeToEffectChange)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.fillMode = Timing::FillModeForwards;
+ timing.iterationStart = 0.2;
+ timing.iterationCount = 2.5;
+ timing.startDelay = 1;
+ timing.direction = Timing::PlaybackDirectionAlternate;
+ RefPtrWillBeRawPtr<TestAnimationNode> animationNode = TestAnimationNode::create(timing);
+
+ animationNode->updateInheritedTime(0);
+ EXPECT_EQ(0, animationNode->takeLocalTime());
+ EXPECT_TRUE(std::isinf(animationNode->takeTimeToNextIteration()));
+
+ // Normal iteration.
+ animationNode->updateInheritedTime(1.75);
+ EXPECT_EQ(1.75, animationNode->takeLocalTime());
+ EXPECT_NEAR(0.05, animationNode->takeTimeToNextIteration(), 0.000000000000001);
+
+ // Reverse iteration.
+ animationNode->updateInheritedTime(2.75);
+ EXPECT_EQ(2.75, animationNode->takeLocalTime());
+ EXPECT_NEAR(0.05, animationNode->takeTimeToNextIteration(), 0.000000000000001);
+
+ // Item ends before iteration finishes.
+ animationNode->updateInheritedTime(3.4);
+ EXPECT_EQ(AnimationNode::PhaseActive, animationNode->phase());
+ EXPECT_EQ(3.4, animationNode->takeLocalTime());
+ EXPECT_TRUE(std::isinf(animationNode->takeTimeToNextIteration()));
+
+ // Item has finished.
+ animationNode->updateInheritedTime(3.5);
+ EXPECT_EQ(AnimationNode::PhaseAfter, animationNode->phase());
+ EXPECT_EQ(3.5, animationNode->takeLocalTime());
+ EXPECT_TRUE(std::isinf(animationNode->takeTimeToNextIteration()));
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTiming.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTiming.cpp
new file mode 100644
index 00000000000..9c3ade81ab5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTiming.cpp
@@ -0,0 +1,180 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/AnimationNodeTiming.h"
+
+#include "core/animation/Animation.h"
+#include "core/animation/AnimationNode.h"
+#include "platform/animation/TimingFunction.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<AnimationNodeTiming> AnimationNodeTiming::create(AnimationNode* parent)
+{
+ return adoptRefWillBeNoop(new AnimationNodeTiming(parent));
+}
+
+AnimationNodeTiming::AnimationNodeTiming(AnimationNode* parent)
+: m_parent(parent)
+{
+}
+
+double AnimationNodeTiming::delay()
+{
+ return m_parent->specifiedTiming().startDelay * 1000;
+}
+
+double AnimationNodeTiming::endDelay()
+{
+ return m_parent->specifiedTiming().endDelay * 1000;
+}
+
+String AnimationNodeTiming::fill()
+{
+ Timing::FillMode fillMode = m_parent->specifiedTiming().fillMode;
+ switch (fillMode) {
+ case Timing::FillModeNone:
+ return "none";
+ case Timing::FillModeForwards:
+ return "forwards";
+ case Timing::FillModeBackwards:
+ return "backwards";
+ case Timing::FillModeBoth:
+ return "both";
+ case Timing::FillModeAuto:
+ return "auto";
+ }
+ ASSERT_NOT_REACHED();
+ return "auto";
+}
+
+double AnimationNodeTiming::iterationStart()
+{
+ return m_parent->specifiedTiming().iterationStart;
+}
+
+double AnimationNodeTiming::iterations()
+{
+ return m_parent->specifiedTiming().iterationCount;
+}
+
+// This logic was copied from the example in bindings/tests/idls/TestInterface.idl
+// and bindings/tests/results/V8TestInterface.cpp.
+// FIXME: It might be possible to have 'duration' defined as an attribute in the idl.
+// If possible, fix will be in a follow-up patch.
+void AnimationNodeTiming::getDuration(String propertyName, bool& element0Enabled, double& element0, bool& element1Enabled, String& element1)
+{
+ if (propertyName != "duration")
+ return;
+
+ if (std::isnan(m_parent->specifiedTiming().iterationDuration)) {
+ element1Enabled = true;
+ element1 = "auto";
+ return;
+ }
+ element0Enabled = true;
+ element0 = m_parent->specifiedTiming().iterationDuration * 1000;
+ return;
+}
+
+double AnimationNodeTiming::playbackRate()
+{
+ return m_parent->specifiedTiming().playbackRate;
+}
+
+String AnimationNodeTiming::direction()
+{
+ Timing::PlaybackDirection direction = m_parent->specifiedTiming().direction;
+ switch (direction) {
+ case Timing::PlaybackDirectionNormal:
+ return "normal";
+ case Timing::PlaybackDirectionReverse:
+ return "reverse";
+ case Timing::PlaybackDirectionAlternate:
+ return "alternate";
+ case Timing::PlaybackDirectionAlternateReverse:
+ return "alternate-reverse";
+ }
+ ASSERT_NOT_REACHED();
+ return "normal";
+}
+
+String AnimationNodeTiming::easing()
+{
+ return m_parent->specifiedTiming().timingFunction->toString();
+}
+
+void AnimationNodeTiming::setDelay(double delay)
+{
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setStartDelay(timing, delay);
+ m_parent->updateSpecifiedTiming(timing);
+}
+
+void AnimationNodeTiming::setEndDelay(double endDelay)
+{
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setEndDelay(timing, endDelay);
+ m_parent->updateSpecifiedTiming(timing);
+}
+
+void AnimationNodeTiming::setFill(String fill)
+{
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setFillMode(timing, fill);
+ m_parent->updateSpecifiedTiming(timing);
+}
+
+void AnimationNodeTiming::setIterationStart(double iterationStart)
+{
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setIterationStart(timing, iterationStart);
+ m_parent->updateSpecifiedTiming(timing);
+}
+
+void AnimationNodeTiming::setIterations(double iterations)
+{
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setIterationCount(timing, iterations);
+ m_parent->updateSpecifiedTiming(timing);
+}
+
+bool AnimationNodeTiming::setDuration(String name, double duration)
+{
+ if (name != "duration")
+ return false;
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setIterationDuration(timing, duration);
+ m_parent->updateSpecifiedTiming(timing);
+ return true;
+}
+
+void AnimationNodeTiming::setPlaybackRate(double playbackRate)
+{
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setPlaybackRate(timing, playbackRate);
+ m_parent->updateSpecifiedTiming(timing);
+}
+
+void AnimationNodeTiming::setDirection(String direction)
+{
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setPlaybackDirection(timing, direction);
+ m_parent->updateSpecifiedTiming(timing);
+}
+
+void AnimationNodeTiming::setEasing(String easing)
+{
+ Timing timing = m_parent->specifiedTiming();
+ TimingInput::setTimingFunction(timing, easing);
+ m_parent->updateSpecifiedTiming(timing);
+}
+
+void AnimationNodeTiming::trace(Visitor* visitor)
+{
+ visitor->trace(m_parent);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTiming.h b/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTiming.h
new file mode 100644
index 00000000000..c6570ec501f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationNodeTiming.h
@@ -0,0 +1,46 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AnimationNodeTiming_h
+#define AnimationNodeTiming_h
+
+#include "core/animation/AnimationNode.h"
+#include "wtf/RefCounted.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class AnimationNodeTiming : public RefCountedWillBeGarbageCollectedFinalized<AnimationNodeTiming> {
+public:
+ static PassRefPtrWillBeRawPtr<AnimationNodeTiming> create(AnimationNode* parent);
+ double delay();
+ double endDelay();
+ String fill();
+ double iterationStart();
+ double iterations();
+ void getDuration(String propertyName, bool& element0Enabled, double& element0, bool& element1Enabled, String& element1);
+ double playbackRate();
+ String direction();
+ String easing();
+
+ void setDelay(double);
+ void setEndDelay(double);
+ void setFill(String);
+ void setIterationStart(double);
+ void setIterations(double);
+ bool setDuration(String name, double duration);
+ void setPlaybackRate(double);
+ void setDirection(String);
+ void setEasing(String);
+
+ void trace(Visitor*);
+
+private:
+ RefPtrWillBeMember<AnimationNode> m_parent;
+ explicit AnimationNodeTiming(AnimationNode*);
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.cpp
new file mode 100644
index 00000000000..a99fec82f98
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.cpp
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/AnimationPlayer.h"
+
+#include "core/animation/Animation.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/dom/Document.h"
+#include "core/events/AnimationPlayerEvent.h"
+#include "core/frame/UseCounter.h"
+
+namespace WebCore {
+
+namespace {
+
+static unsigned nextSequenceNumber()
+{
+ static unsigned next = 0;
+ return ++next;
+}
+
+}
+
+PassRefPtrWillBeRawPtr<AnimationPlayer> AnimationPlayer::create(ExecutionContext* executionContext, AnimationTimeline& timeline, AnimationNode* content)
+{
+ RefPtrWillBeRawPtr<AnimationPlayer> player = adoptRefWillBeRefCountedGarbageCollected(new AnimationPlayer(executionContext, timeline, content));
+ player->suspendIfNeeded();
+ return player.release();
+}
+
+AnimationPlayer::AnimationPlayer(ExecutionContext* executionContext, AnimationTimeline& timeline, AnimationNode* content)
+ : ActiveDOMObject(executionContext)
+ , m_playbackRate(1)
+ , m_startTime(nullValue())
+ , m_holdTime(nullValue())
+ , m_storedTimeLag(0)
+ , m_sortInfo(nextSequenceNumber(), timeline.effectiveTime())
+ , m_content(content)
+ , m_timeline(&timeline)
+ , m_paused(false)
+ , m_held(false)
+ , m_isPausedForTesting(false)
+ , m_outdated(true)
+ , m_finished(false)
+{
+ if (m_content) {
+ if (m_content->player())
+ m_content->player()->cancel();
+ m_content->attach(this);
+ }
+}
+
+AnimationPlayer::~AnimationPlayer()
+{
+#if !ENABLE(OILPAN)
+ if (m_content)
+ m_content->detach();
+ if (m_timeline)
+ m_timeline->playerDestroyed(this);
+#endif
+}
+
+double AnimationPlayer::sourceEnd() const
+{
+ return m_content ? m_content->endTimeInternal() : 0;
+}
+
+bool AnimationPlayer::limited(double currentTime) const
+{
+ return (m_playbackRate < 0 && currentTime <= 0) || (m_playbackRate > 0 && currentTime >= sourceEnd());
+}
+
+double AnimationPlayer::currentTimeWithoutLag() const
+{
+ if (isNull(m_startTime) || !m_timeline)
+ return 0;
+ return (m_timeline->effectiveTime() - m_startTime) * m_playbackRate;
+}
+
+double AnimationPlayer::currentTimeWithLag() const
+{
+ ASSERT(!m_held);
+ double time = currentTimeWithoutLag();
+ return std::isinf(time) ? time : time - m_storedTimeLag;
+}
+
+void AnimationPlayer::updateTimingState(double newCurrentTime)
+{
+ ASSERT(!isNull(newCurrentTime));
+ bool oldHeld = m_held;
+ m_held = m_paused || !m_playbackRate || limited(newCurrentTime);
+ if (m_held) {
+ if (!oldHeld || m_holdTime != newCurrentTime)
+ setOutdated();
+ m_holdTime = newCurrentTime;
+ m_storedTimeLag = nullValue();
+ } else {
+ m_holdTime = nullValue();
+ m_storedTimeLag = currentTimeWithoutLag() - newCurrentTime;
+ m_finished = false;
+ setOutdated();
+ }
+}
+
+void AnimationPlayer::updateCurrentTimingState()
+{
+ if (m_held) {
+ updateTimingState(m_holdTime);
+ return;
+ }
+ if (!limited(currentTimeWithLag()))
+ return;
+ m_held = true;
+ m_holdTime = m_playbackRate < 0 ? 0 : sourceEnd();
+ m_storedTimeLag = nullValue();
+}
+
+double AnimationPlayer::currentTime()
+{
+ return currentTimeInternal() * 1000;
+}
+
+double AnimationPlayer::currentTimeInternal()
+{
+ updateCurrentTimingState();
+ if (m_held)
+ return m_holdTime;
+ return currentTimeWithLag();
+}
+
+void AnimationPlayer::setCurrentTime(double newCurrentTime)
+{
+ setCurrentTimeInternal(newCurrentTime / 1000);
+}
+
+void AnimationPlayer::setCurrentTimeInternal(double newCurrentTime)
+{
+ if (!std::isfinite(newCurrentTime))
+ return;
+ updateTimingState(newCurrentTime);
+ cancelAnimationOnCompositor();
+ schedulePendingAnimationOnCompositor();
+}
+
+void AnimationPlayer::setStartTimeInternal(double newStartTime, bool isUpdateFromCompositor)
+{
+ ASSERT(!isUpdateFromCompositor || !hasStartTime());
+
+ if (!std::isfinite(newStartTime))
+ return;
+ if (newStartTime == m_startTime)
+ return;
+ updateCurrentTimingState(); // Update the value of held
+ bool hadStartTime = hasStartTime();
+ double previousCurrentTime = currentTimeInternal();
+ m_startTime = newStartTime;
+ m_sortInfo.m_startTime = newStartTime;
+ updateCurrentTimingState();
+ if (previousCurrentTime != currentTimeInternal()) {
+ setOutdated();
+ } else if (!hadStartTime && m_timeline) {
+ // Even though this player is not outdated, time to effect change is
+ // infinity until start time is set.
+ m_timeline->wake();
+ }
+ if (!isUpdateFromCompositor) {
+ cancelAnimationOnCompositor();
+ schedulePendingAnimationOnCompositor();
+ }
+}
+
+void AnimationPlayer::setSource(AnimationNode* newSource)
+{
+ if (m_content == newSource)
+ return;
+ cancelAnimationOnCompositor();
+ double storedCurrentTime = currentTimeInternal();
+ if (m_content)
+ m_content->detach();
+ m_content = newSource;
+ if (newSource) {
+ // FIXME: This logic needs to be updated once groups are implemented
+ if (newSource->player())
+ newSource->player()->cancel();
+ newSource->attach(this);
+ }
+ updateTimingState(storedCurrentTime);
+ schedulePendingAnimationOnCompositor();
+}
+
+void AnimationPlayer::pause()
+{
+ if (m_paused)
+ return;
+ m_paused = true;
+ updateTimingState(currentTimeInternal());
+ cancelAnimationOnCompositor();
+}
+
+void AnimationPlayer::unpause()
+{
+ if (!m_paused)
+ return;
+ m_paused = false;
+ updateTimingState(currentTimeInternal());
+ schedulePendingAnimationOnCompositor();
+}
+
+void AnimationPlayer::play()
+{
+ cancelAnimationOnCompositor();
+ // Note, unpause schedules pending animation on compositor if necessary.
+ unpause();
+ if (!m_content)
+ return;
+ double currentTime = this->currentTimeInternal();
+ if (m_playbackRate > 0 && (currentTime < 0 || currentTime >= sourceEnd()))
+ setCurrentTimeInternal(0);
+ else if (m_playbackRate < 0 && (currentTime <= 0 || currentTime > sourceEnd()))
+ setCurrentTimeInternal(sourceEnd());
+ m_finished = false;
+}
+
+void AnimationPlayer::reverse()
+{
+ if (!m_playbackRate)
+ return;
+ if (m_content) {
+ if (m_playbackRate > 0 && currentTimeInternal() > sourceEnd())
+ setCurrentTimeInternal(sourceEnd());
+ else if (m_playbackRate < 0 && currentTimeInternal() < 0)
+ setCurrentTimeInternal(0);
+ }
+ setPlaybackRate(-m_playbackRate);
+ cancelAnimationOnCompositor();
+ // Note, unpause schedules pending animation on compositor if necessary.
+ unpause();
+}
+
+void AnimationPlayer::finish(ExceptionState& exceptionState)
+{
+ if (!m_playbackRate)
+ return;
+ if (m_playbackRate < 0) {
+ setCurrentTimeInternal(0);
+ } else {
+ if (sourceEnd() == std::numeric_limits<double>::infinity()) {
+ exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity.");
+ return;
+ }
+ setCurrentTimeInternal(sourceEnd());
+ }
+ ASSERT(finished());
+ cancelAnimationOnCompositor();
+}
+
+const AtomicString& AnimationPlayer::interfaceName() const
+{
+ return EventTargetNames::AnimationPlayer;
+}
+
+ExecutionContext* AnimationPlayer::executionContext() const
+{
+ return ActiveDOMObject::executionContext();
+}
+
+bool AnimationPlayer::hasPendingActivity() const
+{
+ return m_pendingFinishedEvent || (!m_finished && hasEventListeners(EventTypeNames::finish));
+}
+
+void AnimationPlayer::stop()
+{
+ m_finished = true;
+ m_pendingFinishedEvent = nullptr;
+}
+
+bool AnimationPlayer::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
+{
+ if (m_pendingFinishedEvent == event)
+ m_pendingFinishedEvent = nullptr;
+ return EventTargetWithInlineData::dispatchEvent(event);
+}
+
+void AnimationPlayer::setPlaybackRate(double playbackRate)
+{
+ if (!std::isfinite(playbackRate))
+ return;
+ double storedCurrentTime = currentTimeInternal();
+ if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && playbackRate <= 0))
+ m_finished = false;
+ m_playbackRate = playbackRate;
+ updateTimingState(storedCurrentTime);
+ cancelAnimationOnCompositor();
+ schedulePendingAnimationOnCompositor();
+}
+
+void AnimationPlayer::setOutdated()
+{
+ m_outdated = true;
+ if (m_timeline)
+ m_timeline->setOutdatedAnimationPlayer(this);
+}
+
+bool AnimationPlayer::canStartAnimationOnCompositor()
+{
+ // FIXME: Need compositor support for playback rate != 1.
+ if (playbackRate() != 1)
+ return false;
+
+ return m_timeline && m_content && m_content->isAnimation() && !m_held;
+}
+
+bool AnimationPlayer::maybeStartAnimationOnCompositor()
+{
+ if (!canStartAnimationOnCompositor())
+ return false;
+
+ return toAnimation(m_content.get())->maybeStartAnimationOnCompositor(timeline()->zeroTime() + startTimeInternal() + timeLagInternal());
+}
+
+void AnimationPlayer::schedulePendingAnimationOnCompositor()
+{
+ ASSERT(!hasActiveAnimationsOnCompositor());
+
+ if (canStartAnimationOnCompositor())
+ timeline()->document()->compositorPendingAnimations().add(this);
+}
+
+bool AnimationPlayer::hasActiveAnimationsOnCompositor()
+{
+ if (!m_content || !m_content->isAnimation())
+ return false;
+
+ return toAnimation(m_content.get())->hasActiveAnimationsOnCompositor();
+}
+
+void AnimationPlayer::cancelAnimationOnCompositor()
+{
+ if (hasActiveAnimationsOnCompositor())
+ toAnimation(m_content.get())->cancelAnimationOnCompositor();
+}
+
+bool AnimationPlayer::update(TimingUpdateReason reason)
+{
+ m_outdated = false;
+
+ if (!m_timeline)
+ return false;
+
+ if (m_content) {
+ double inheritedTime = isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal();
+ m_content->updateInheritedTime(inheritedTime, reason);
+ }
+
+ if (finished() && !m_finished) {
+ if (reason == TimingUpdateForAnimationFrame && hasStartTime()) {
+ const AtomicString& eventType = EventTypeNames::finish;
+ if (executionContext() && hasEventListeners(eventType)) {
+ m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, currentTime(), timeline()->currentTime());
+ m_pendingFinishedEvent->setTarget(this);
+ m_pendingFinishedEvent->setCurrentTarget(this);
+ m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFinishedEvent);
+ }
+ m_finished = true;
+ }
+ }
+ ASSERT(!m_outdated);
+ return !m_finished || !finished();
+}
+
+double AnimationPlayer::timeToEffectChange()
+{
+ ASSERT(!m_outdated);
+ if (m_held || !hasStartTime())
+ return std::numeric_limits<double>::infinity();
+ if (!m_content)
+ return -currentTimeInternal() / m_playbackRate;
+ if (m_playbackRate > 0)
+ return m_content->timeToForwardsEffectChange() / m_playbackRate;
+ return m_content->timeToReverseEffectChange() / -m_playbackRate;
+}
+
+void AnimationPlayer::cancel()
+{
+ setSource(0);
+}
+
+bool AnimationPlayer::SortInfo::operator<(const SortInfo& other) const
+{
+ ASSERT(!std::isnan(m_startTime) && !std::isnan(other.m_startTime));
+ if (m_startTime < other.m_startTime)
+ return true;
+ if (m_startTime > other.m_startTime)
+ return false;
+ return m_sequenceNumber < other.m_sequenceNumber;
+}
+
+#if !ENABLE(OILPAN)
+bool AnimationPlayer::canFree() const
+{
+ ASSERT(m_content);
+ return hasOneRef() && m_content->isAnimation() && m_content->hasOneRef();
+}
+#endif
+
+bool AnimationPlayer::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+{
+ if (eventType == EventTypeNames::finish)
+ UseCounter::count(executionContext(), UseCounter::AnimationPlayerFinishEvent);
+ return EventTargetWithInlineData::addEventListener(eventType, listener, useCapture);
+}
+
+void AnimationPlayer::pauseForTesting(double pauseTime)
+{
+ RELEASE_ASSERT(!paused());
+ updateTimingState(pauseTime);
+ if (!m_isPausedForTesting && hasActiveAnimationsOnCompositor())
+ toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTimeInternal());
+ m_isPausedForTesting = true;
+ pause();
+}
+
+void AnimationPlayer::trace(Visitor* visitor)
+{
+ visitor->trace(m_content);
+ visitor->trace(m_timeline);
+ visitor->trace(m_pendingFinishedEvent);
+ EventTargetWithInlineData::trace(visitor);
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.h b/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.h
new file mode 100644
index 00000000000..e0c44eb72a9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AnimationPlayer_h
+#define AnimationPlayer_h
+
+#include "core/animation/AnimationNode.h"
+#include "core/dom/ActiveDOMObject.h"
+#include "core/events/EventTarget.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class AnimationTimeline;
+class ExceptionState;
+
+class AnimationPlayer FINAL : public RefCountedWillBeRefCountedGarbageCollected<AnimationPlayer>
+ , public ActiveDOMObject
+ , public EventTargetWithInlineData {
+ REFCOUNTED_EVENT_TARGET(AnimationPlayer);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AnimationPlayer);
+public:
+
+ ~AnimationPlayer();
+ static PassRefPtrWillBeRawPtr<AnimationPlayer> create(ExecutionContext*, AnimationTimeline&, AnimationNode*);
+
+ // Returns whether the player is finished.
+ bool update(TimingUpdateReason);
+
+ // timeToEffectChange returns:
+ // infinity - if this player is no longer in effect
+ // 0 - if this player requires an update on the next frame
+ // n - if this player requires an update after 'n' units of time
+ double timeToEffectChange();
+
+ void cancel();
+
+ double currentTime();
+ void setCurrentTime(double newCurrentTime);
+
+ double currentTimeInternal();
+ void setCurrentTimeInternal(double newCurrentTime);
+
+ bool paused() const { return m_paused && !m_isPausedForTesting; }
+ void pause();
+ void play();
+ void reverse();
+ void finish(ExceptionState&);
+ bool finished() { return limited(currentTimeInternal()); }
+ // FIXME: Resolve whether finished() should just return the flag, and
+ // remove this method.
+ bool finishedInternal() const { return m_finished; }
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(finish);
+
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+ virtual ExecutionContext* executionContext() const OVERRIDE;
+ virtual bool hasPendingActivity() const OVERRIDE;
+ virtual void stop() OVERRIDE;
+ virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
+
+ double playbackRate() const { return m_playbackRate; }
+ void setPlaybackRate(double);
+ const AnimationTimeline* timeline() const { return m_timeline; }
+ AnimationTimeline* timeline() { return m_timeline; }
+
+#if !ENABLE(OILPAN)
+ void timelineDestroyed() { m_timeline = nullptr; }
+#endif
+
+ bool hasStartTime() const { return !isNull(m_startTime); }
+ double startTime() const { return m_startTime * 1000; }
+ double startTimeInternal() const { return m_startTime; }
+ void setStartTime(double startTime) { setStartTimeInternal(startTime / 1000); }
+ void setStartTimeInternal(double, bool isUpdateFromCompositor = false);
+
+ const AnimationNode* source() const { return m_content.get(); }
+ AnimationNode* source() { return m_content.get(); }
+ AnimationNode* source(bool& isNull) { isNull = !m_content; return m_content.get(); }
+ void setSource(AnimationNode*);
+
+ double timeLag() { return timeLagInternal() * 1000; }
+ double timeLagInternal() { return currentTimeWithoutLag() - currentTimeInternal(); }
+
+ // Pausing via this method is not reflected in the value returned by
+ // paused() and must never overlap with pausing via pause().
+ void pauseForTesting(double pauseTime);
+ // This should only be used for CSS
+ void unpause();
+
+ void setOutdated();
+ bool outdated() { return m_outdated; }
+
+ bool canStartAnimationOnCompositor();
+ bool maybeStartAnimationOnCompositor();
+ void cancelAnimationOnCompositor();
+ void schedulePendingAnimationOnCompositor();
+ bool hasActiveAnimationsOnCompositor();
+
+ class SortInfo {
+ public:
+ friend class AnimationPlayer;
+ bool operator<(const SortInfo& other) const;
+ double startTime() const { return m_startTime; }
+ private:
+ SortInfo(unsigned sequenceNumber, double startTime)
+ : m_sequenceNumber(sequenceNumber)
+ , m_startTime(startTime)
+ {
+ }
+ unsigned m_sequenceNumber;
+ double m_startTime;
+ };
+
+ const SortInfo& sortInfo() const { return m_sortInfo; }
+
+ static bool hasLowerPriority(AnimationPlayer* player1, AnimationPlayer* player2)
+ {
+ return player1->sortInfo() < player2->sortInfo();
+ }
+
+#if !ENABLE(OILPAN)
+ // Checks if the AnimationStack is the last reference holder to the Player.
+ // This won't be needed when AnimationPlayer is moved to Oilpan.
+ bool canFree() const;
+#endif
+
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ AnimationPlayer(ExecutionContext*, AnimationTimeline&, AnimationNode*);
+ double sourceEnd() const;
+ bool limited(double currentTime) const;
+ double currentTimeWithoutLag() const;
+ double currentTimeWithLag() const;
+ void updateTimingState(double newCurrentTime);
+ void updateCurrentTimingState();
+
+ double m_playbackRate;
+ double m_startTime;
+ double m_holdTime;
+ double m_storedTimeLag;
+
+ SortInfo m_sortInfo;
+
+ RefPtrWillBeMember<AnimationNode> m_content;
+ RawPtrWillBeMember<AnimationTimeline> m_timeline;
+ // Reflects all pausing, including via pauseForTesting().
+ bool m_paused;
+ bool m_held;
+ bool m_isPausedForTesting;
+
+ // This indicates timing information relevant to the player has changed by
+ // means other than the ordinary progression of time
+ bool m_outdated;
+
+ bool m_finished;
+ // Holds a 'finished' event queued for asynchronous dispatch via the
+ // ScriptedAnimationController. This object remains active until the
+ // event is actually dispatched.
+ RefPtrWillBeMember<Event> m_pendingFinishedEvent;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.idl b/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.idl
new file mode 100644
index 00000000000..8dc0d416d6a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationPlayer.idl
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ RuntimeEnabled=WebAnimationsElementAnimate,
+ NoInterfaceObject,
+ WillBeGarbageCollected,
+ ActiveDOMObject,
+] interface AnimationPlayer : EventTarget {
+ [RuntimeEnabled=WebAnimationsAPI] attribute AnimationNode? source;
+ [RuntimeEnabled=WebAnimationsAPI] attribute double startTime;
+ [RuntimeEnabled=WebAnimationsAPI] attribute double currentTime;
+ [RuntimeEnabled=WebAnimationsAPI] readonly attribute double timeLag;
+ [RuntimeEnabled=WebAnimationsAPI] attribute double playbackRate;
+ [RuntimeEnabled=WebAnimationsAPI] readonly attribute boolean paused;
+ [RuntimeEnabled=WebAnimationsAPI] readonly attribute boolean finished;
+ [RuntimeEnabled=WebAnimationsAPI, RaisesException] void finish();
+ [RuntimeEnabled=WebAnimationsAPI] void play();
+ [RuntimeEnabled=WebAnimationsAPI] void pause();
+ [RuntimeEnabled=WebAnimationsAPI] void reverse();
+
+ void cancel();
+ [MeasureAs=AnimationPlayerFinishEvent] attribute EventHandler onfinish;
+};
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationPlayerTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationPlayerTest.cpp
new file mode 100644
index 00000000000..37660e69b82
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationPlayerTest.cpp
@@ -0,0 +1,737 @@
+/*
+ * Copyright (c) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/AnimationPlayer.h"
+
+#include "core/animation/ActiveAnimations.h"
+#include "core/animation/Animation.h"
+#include "core/animation/AnimationClock.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/dom/Document.h"
+#include "core/dom/QualifiedName.h"
+#include "platform/weborigin/KURL.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class AnimationAnimationPlayerTest : public ::testing::Test {
+protected:
+ virtual void SetUp()
+ {
+ setUpWithoutStartingTimeline();
+ startTimeline();
+ }
+
+ void setUpWithoutStartingTimeline()
+ {
+ document = Document::create();
+ document->animationClock().resetTimeForTesting();
+ timeline = AnimationTimeline::create(document.get());
+ player = timeline->createAnimationPlayer(0);
+ player->setStartTimeInternal(0);
+ player->setSource(makeAnimation().get());
+ }
+
+ void startTimeline()
+ {
+ updateTimeline(0);
+ }
+
+ PassRefPtrWillBeRawPtr<Animation> makeAnimation(double duration = 30, double playbackRate = 1)
+ {
+ Timing timing;
+ timing.iterationDuration = duration;
+ timing.playbackRate = playbackRate;
+ return Animation::create(0, nullptr, timing);
+ }
+
+ bool updateTimeline(double time)
+ {
+ document->animationClock().updateTime(time);
+ // The timeline does not know about our player, so we have to explicitly call update().
+ return player->update(TimingUpdateOnDemand);
+ }
+
+ RefPtrWillBePersistent<Document> document;
+ RefPtrWillBePersistent<AnimationTimeline> timeline;
+ RefPtrWillBePersistent<AnimationPlayer> player;
+ TrackExceptionState exceptionState;
+};
+
+TEST_F(AnimationAnimationPlayerTest, InitialState)
+{
+ setUpWithoutStartingTimeline();
+ player = timeline->createAnimationPlayer(0);
+ EXPECT_EQ(0, player->currentTimeInternal());
+ EXPECT_FALSE(player->paused());
+ EXPECT_EQ(1, player->playbackRate());
+ EXPECT_EQ(0, player->timeLagInternal());
+ EXPECT_FALSE(player->hasStartTime());
+ EXPECT_TRUE(isNull(player->startTimeInternal()));
+
+ startTimeline();
+ player->setStartTimeInternal(0);
+ EXPECT_EQ(0, timeline->currentTimeInternal());
+ EXPECT_EQ(0, player->currentTimeInternal());
+ EXPECT_FALSE(player->paused());
+ EXPECT_EQ(1, player->playbackRate());
+ EXPECT_EQ(0, player->startTimeInternal());
+ EXPECT_EQ(0, player->timeLagInternal());
+ EXPECT_TRUE(player->hasStartTime());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, CurrentTimeDoesNotSetOutdated)
+{
+ EXPECT_FALSE(player->outdated());
+ EXPECT_EQ(0, player->currentTimeInternal());
+ EXPECT_FALSE(player->outdated());
+ // FIXME: We should split updateTimeline into a version that doesn't update
+ // the player and one that does, as most of the tests don't require update()
+ // to be called.
+ document->animationClock().updateTime(10);
+ EXPECT_EQ(10, player->currentTimeInternal());
+ EXPECT_FALSE(player->outdated());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTime)
+{
+ player->setCurrentTimeInternal(10);
+ EXPECT_EQ(10, player->currentTimeInternal());
+ updateTimeline(10);
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeNegative)
+{
+ player->setCurrentTimeInternal(-10);
+ EXPECT_EQ(-10, player->currentTimeInternal());
+ updateTimeline(20);
+ EXPECT_EQ(10, player->currentTimeInternal());
+
+ player->setPlaybackRate(-2);
+ player->setCurrentTimeInternal(-10);
+ EXPECT_EQ(-10, player->currentTimeInternal());
+ updateTimeline(40);
+ EXPECT_EQ(-10, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimePastContentEnd)
+{
+ player->setCurrentTimeInternal(50);
+ EXPECT_EQ(50, player->currentTimeInternal());
+ updateTimeline(20);
+ EXPECT_EQ(50, player->currentTimeInternal());
+
+ player->setPlaybackRate(-2);
+ player->setCurrentTimeInternal(50);
+ EXPECT_EQ(50, player->currentTimeInternal());
+ updateTimeline(40);
+ EXPECT_EQ(10, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeBeforeTimelineStarted)
+{
+ setUpWithoutStartingTimeline();
+ player->setCurrentTimeInternal(5);
+ EXPECT_EQ(5, player->currentTimeInternal());
+ startTimeline();
+ updateTimeline(10);
+ EXPECT_EQ(15, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimePastContentEndBeforeTimelineStarted)
+{
+ setUpWithoutStartingTimeline();
+ player->setCurrentTimeInternal(250);
+ EXPECT_EQ(250, player->currentTimeInternal());
+ startTimeline();
+ updateTimeline(10);
+ EXPECT_EQ(250, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeMax)
+{
+ player->setCurrentTimeInternal(std::numeric_limits<double>::max());
+ EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTimeInternal());
+ updateTimeline(100);
+ EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeUnrestrictedDouble)
+{
+ updateTimeline(10);
+ player->setCurrentTimeInternal(nullValue());
+ EXPECT_EQ(10, player->currentTimeInternal());
+ player->setCurrentTimeInternal(std::numeric_limits<double>::infinity());
+ EXPECT_EQ(10, player->currentTimeInternal());
+ player->setCurrentTimeInternal(-std::numeric_limits<double>::infinity());
+ EXPECT_EQ(10, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, TimeLag)
+{
+ player->setCurrentTimeInternal(10);
+ EXPECT_EQ(-10, player->timeLagInternal());
+ updateTimeline(10);
+ EXPECT_EQ(-10, player->timeLagInternal());
+ player->setCurrentTimeInternal(40);
+ EXPECT_EQ(-30, player->timeLagInternal());
+ updateTimeline(20);
+ EXPECT_EQ(-20, player->timeLagInternal());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, SetStartTime)
+{
+ updateTimeline(20);
+ EXPECT_EQ(0, player->startTimeInternal());
+ EXPECT_EQ(20, player->currentTimeInternal());
+ player->setStartTimeInternal(10);
+ EXPECT_EQ(10, player->startTimeInternal());
+ EXPECT_EQ(10, player->currentTimeInternal());
+ updateTimeline(30);
+ EXPECT_EQ(10, player->startTimeInternal());
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetStartTimeLimitsAnimationPlayer)
+{
+ player->setStartTimeInternal(-50);
+ EXPECT_EQ(30, player->currentTimeInternal());
+ player->setPlaybackRate(-1);
+ player->setStartTimeInternal(-100);
+ EXPECT_EQ(0, player->currentTimeInternal());
+ EXPECT_TRUE(player->finished());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetStartTimeOnLimitedAnimationPlayer)
+{
+ updateTimeline(30);
+ player->setStartTimeInternal(-10);
+ EXPECT_EQ(30, player->currentTimeInternal());
+ player->setCurrentTimeInternal(50);
+ player->setStartTimeInternal(-40);
+ EXPECT_EQ(50, player->currentTimeInternal());
+ EXPECT_TRUE(player->finished());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetStartTimeWhilePaused)
+{
+ updateTimeline(10);
+ player->pause();
+ player->setStartTimeInternal(-40);
+ EXPECT_EQ(10, player->currentTimeInternal());
+ updateTimeline(50);
+ player->setStartTimeInternal(60);
+ EXPECT_EQ(10, player->currentTimeInternal());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, PausePlay)
+{
+ updateTimeline(10);
+ player->pause();
+ EXPECT_TRUE(player->paused());
+ EXPECT_EQ(10, player->currentTimeInternal());
+ updateTimeline(20);
+ player->play();
+ EXPECT_FALSE(player->paused());
+ EXPECT_EQ(10, player->currentTimeInternal());
+ updateTimeline(30);
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, PauseBeforeTimelineStarted)
+{
+ setUpWithoutStartingTimeline();
+ player->pause();
+ EXPECT_TRUE(player->paused());
+ player->play();
+ EXPECT_FALSE(player->paused());
+
+ player->pause();
+ startTimeline();
+ updateTimeline(100);
+ EXPECT_TRUE(player->paused());
+ EXPECT_EQ(0, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, PauseBeforeStartTimeSet)
+{
+ player = timeline->createAnimationPlayer(makeAnimation().get());
+ updateTimeline(100);
+ player->pause();
+ updateTimeline(200);
+ EXPECT_EQ(0, player->currentTimeInternal());
+
+ player->setStartTimeInternal(150);
+ player->play();
+ EXPECT_EQ(0, player->currentTimeInternal());
+ updateTimeline(220);
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, PlayRewindsToStart)
+{
+ player->setCurrentTimeInternal(30);
+ player->play();
+ EXPECT_EQ(0, player->currentTimeInternal());
+
+ player->setCurrentTimeInternal(40);
+ player->play();
+ EXPECT_EQ(0, player->currentTimeInternal());
+
+ player->setCurrentTimeInternal(-10);
+ player->play();
+ EXPECT_EQ(0, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, PlayRewindsToEnd)
+{
+ player->setPlaybackRate(-1);
+ player->play();
+ EXPECT_EQ(30, player->currentTimeInternal());
+
+ player->setCurrentTimeInternal(40);
+ player->play();
+ EXPECT_EQ(30, player->currentTimeInternal());
+
+ player->setCurrentTimeInternal(-10);
+ player->play();
+ EXPECT_EQ(30, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, PlayWithPlaybackRateZeroDoesNotSeek)
+{
+ player->setPlaybackRate(0);
+ player->play();
+ EXPECT_EQ(0, player->currentTimeInternal());
+
+ player->setCurrentTimeInternal(40);
+ player->play();
+ EXPECT_EQ(40, player->currentTimeInternal());
+
+ player->setCurrentTimeInternal(-10);
+ player->play();
+ EXPECT_EQ(-10, player->currentTimeInternal());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, Reverse)
+{
+ player->setCurrentTimeInternal(10);
+ player->pause();
+ player->reverse();
+ EXPECT_FALSE(player->paused());
+ EXPECT_EQ(-1, player->playbackRate());
+ EXPECT_EQ(10, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, ReverseDoesNothingWithPlaybackRateZero)
+{
+ player->setCurrentTimeInternal(10);
+ player->setPlaybackRate(0);
+ player->pause();
+ player->reverse();
+ EXPECT_TRUE(player->paused());
+ EXPECT_EQ(0, player->playbackRate());
+ EXPECT_EQ(10, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, ReverseDoesNotSeekWithNoSource)
+{
+ player->setSource(0);
+ player->setCurrentTimeInternal(10);
+ player->reverse();
+ EXPECT_EQ(10, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, ReverseSeeksToStart)
+{
+ player->setCurrentTimeInternal(-10);
+ player->setPlaybackRate(-1);
+ player->reverse();
+ EXPECT_EQ(0, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, ReverseSeeksToEnd)
+{
+ player->setCurrentTimeInternal(40);
+ player->reverse();
+ EXPECT_EQ(30, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, ReverseLimitsAnimationPlayer)
+{
+ player->setCurrentTimeInternal(40);
+ player->setPlaybackRate(-1);
+ player->reverse();
+ EXPECT_TRUE(player->finished());
+ EXPECT_EQ(40, player->currentTimeInternal());
+
+ player->setCurrentTimeInternal(-10);
+ player->reverse();
+ EXPECT_TRUE(player->finished());
+ EXPECT_EQ(-10, player->currentTimeInternal());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, Finish)
+{
+ player->finish(exceptionState);
+ EXPECT_EQ(30, player->currentTimeInternal());
+ EXPECT_TRUE(player->finished());
+
+ player->setPlaybackRate(-1);
+ player->finish(exceptionState);
+ EXPECT_EQ(0, player->currentTimeInternal());
+ EXPECT_TRUE(player->finished());
+
+ EXPECT_FALSE(exceptionState.hadException());
+}
+
+TEST_F(AnimationAnimationPlayerTest, FinishAfterSourceEnd)
+{
+ player->setCurrentTimeInternal(40);
+ player->finish(exceptionState);
+ EXPECT_EQ(30, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, FinishBeforeStart)
+{
+ player->setCurrentTimeInternal(-10);
+ player->setPlaybackRate(-1);
+ player->finish(exceptionState);
+ EXPECT_EQ(0, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, FinishDoesNothingWithPlaybackRateZero)
+{
+ player->setCurrentTimeInternal(10);
+ player->setPlaybackRate(0);
+ player->finish(exceptionState);
+ EXPECT_EQ(10, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, FinishRaisesException)
+{
+ Timing timing;
+ timing.iterationDuration = 1;
+ timing.iterationCount = std::numeric_limits<double>::infinity();
+ player->setSource(Animation::create(0, nullptr, timing).get());
+ player->setCurrentTimeInternal(10);
+
+ player->finish(exceptionState);
+ EXPECT_EQ(10, player->currentTimeInternal());
+ EXPECT_TRUE(exceptionState.hadException());
+ EXPECT_EQ(InvalidStateError, exceptionState.code());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, LimitingAtSourceEnd)
+{
+ updateTimeline(30);
+ EXPECT_EQ(30, player->currentTimeInternal());
+ EXPECT_TRUE(player->finished());
+ updateTimeline(40);
+ EXPECT_EQ(30, player->currentTimeInternal());
+ EXPECT_FALSE(player->paused());
+}
+
+TEST_F(AnimationAnimationPlayerTest, LimitingAtStart)
+{
+ updateTimeline(30);
+ player->setPlaybackRate(-2);
+ updateTimeline(45);
+ EXPECT_EQ(0, player->currentTimeInternal());
+ EXPECT_TRUE(player->finished());
+ updateTimeline(60);
+ EXPECT_EQ(0, player->currentTimeInternal());
+ EXPECT_FALSE(player->paused());
+}
+
+TEST_F(AnimationAnimationPlayerTest, LimitingWithNoSource)
+{
+ player->setSource(0);
+ EXPECT_TRUE(player->finished());
+ updateTimeline(30);
+ EXPECT_EQ(0, player->currentTimeInternal());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRate)
+{
+ player->setPlaybackRate(2);
+ EXPECT_EQ(2, player->playbackRate());
+ EXPECT_EQ(0, player->currentTimeInternal());
+ updateTimeline(10);
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateBeforeTimelineStarted)
+{
+ setUpWithoutStartingTimeline();
+ player->setPlaybackRate(2);
+ EXPECT_EQ(2, player->playbackRate());
+ EXPECT_EQ(0, player->currentTimeInternal());
+ startTimeline();
+ updateTimeline(10);
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateWhilePaused)
+{
+ updateTimeline(10);
+ player->pause();
+ player->setPlaybackRate(2);
+ updateTimeline(20);
+ player->play();
+ EXPECT_EQ(10, player->currentTimeInternal());
+ updateTimeline(25);
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateWhileLimited)
+{
+ updateTimeline(40);
+ EXPECT_EQ(30, player->currentTimeInternal());
+ player->setPlaybackRate(2);
+ updateTimeline(50);
+ EXPECT_EQ(30, player->currentTimeInternal());
+ player->setPlaybackRate(-2);
+ EXPECT_FALSE(player->finished());
+ updateTimeline(60);
+ EXPECT_EQ(10, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateZero)
+{
+ updateTimeline(10);
+ player->setPlaybackRate(0);
+ EXPECT_EQ(10, player->currentTimeInternal());
+ updateTimeline(20);
+ EXPECT_EQ(10, player->currentTimeInternal());
+ player->setCurrentTimeInternal(20);
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateMax)
+{
+ player->setPlaybackRate(std::numeric_limits<double>::max());
+ EXPECT_EQ(std::numeric_limits<double>::max(), player->playbackRate());
+ EXPECT_EQ(0, player->currentTimeInternal());
+ updateTimeline(1);
+ EXPECT_EQ(30, player->currentTimeInternal());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, SetSource)
+{
+ player = timeline->createAnimationPlayer(0);
+ player->setStartTimeInternal(0);
+ RefPtrWillBeRawPtr<AnimationNode> source1 = makeAnimation();
+ RefPtrWillBeRawPtr<AnimationNode> source2 = makeAnimation();
+ player->setSource(source1.get());
+ EXPECT_EQ(source1, player->source());
+ EXPECT_EQ(0, player->currentTimeInternal());
+ player->setCurrentTimeInternal(15);
+ player->setSource(source2.get());
+ EXPECT_EQ(15, player->currentTimeInternal());
+ EXPECT_EQ(0, source1->player());
+ EXPECT_EQ(player.get(), source2->player());
+ EXPECT_EQ(source2, player->source());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetSourceLimitsAnimationPlayer)
+{
+ player->setCurrentTimeInternal(20);
+ player->setSource(makeAnimation(10).get());
+ EXPECT_EQ(20, player->currentTimeInternal());
+ EXPECT_TRUE(player->finished());
+ updateTimeline(10);
+ EXPECT_EQ(20, player->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetSourceUnlimitsAnimationPlayer)
+{
+ player->setCurrentTimeInternal(40);
+ player->setSource(makeAnimation(60).get());
+ EXPECT_FALSE(player->finished());
+ EXPECT_EQ(40, player->currentTimeInternal());
+ updateTimeline(10);
+ EXPECT_EQ(50, player->currentTimeInternal());
+}
+
+
+TEST_F(AnimationAnimationPlayerTest, EmptyAnimationPlayersDontUpdateEffects)
+{
+ player = timeline->createAnimationPlayer(0);
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
+
+ updateTimeline(1234);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
+}
+
+TEST_F(AnimationAnimationPlayerTest, AnimationPlayersDisassociateFromSource)
+{
+ AnimationNode* animationNode = player->source();
+ AnimationPlayer* player2 = timeline->createAnimationPlayer(animationNode);
+ EXPECT_EQ(0, player->source());
+ player->setSource(animationNode);
+ EXPECT_EQ(0, player2->source());
+}
+
+TEST_F(AnimationAnimationPlayerTest, AnimationPlayersReturnTimeToNextEffect)
+{
+ Timing timing;
+ timing.startDelay = 1;
+ timing.iterationDuration = 1;
+ timing.endDelay = 1;
+ RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing);
+ player = timeline->createAnimationPlayer(animation.get());
+ player->setStartTimeInternal(0);
+
+ updateTimeline(0);
+ EXPECT_EQ(1, player->timeToEffectChange());
+
+ updateTimeline(0.5);
+ EXPECT_EQ(0.5, player->timeToEffectChange());
+
+ updateTimeline(1);
+ EXPECT_EQ(0, player->timeToEffectChange());
+
+ updateTimeline(1.5);
+ EXPECT_EQ(0, player->timeToEffectChange());
+
+ updateTimeline(2);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
+
+ updateTimeline(3);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
+
+ player->setCurrentTimeInternal(0);
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(1, player->timeToEffectChange());
+
+ player->setPlaybackRate(2);
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(0.5, player->timeToEffectChange());
+
+ player->setPlaybackRate(0);
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
+
+ player->setCurrentTimeInternal(3);
+ player->setPlaybackRate(-1);
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(1, player->timeToEffectChange());
+
+ player->setPlaybackRate(-2);
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(0.5, player->timeToEffectChange());
+}
+
+TEST_F(AnimationAnimationPlayerTest, TimeToNextEffectWhenPaused)
+{
+ EXPECT_EQ(0, player->timeToEffectChange());
+ player->pause();
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
+}
+
+TEST_F(AnimationAnimationPlayerTest, TimeToNextEffectWhenCancelledBeforeStart)
+{
+ EXPECT_EQ(0, player->timeToEffectChange());
+ player->setCurrentTimeInternal(-8);
+ player->setPlaybackRate(2);
+ player->cancel();
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(4, player->timeToEffectChange());
+}
+
+TEST_F(AnimationAnimationPlayerTest, TimeToNextEffectWhenCancelledBeforeStartReverse)
+{
+ EXPECT_EQ(0, player->timeToEffectChange());
+ player->setCurrentTimeInternal(9);
+ player->setPlaybackRate(-3);
+ player->cancel();
+ player->update(TimingUpdateOnDemand);
+ EXPECT_EQ(3, player->timeToEffectChange());
+}
+
+TEST_F(AnimationAnimationPlayerTest, AttachedAnimationPlayers)
+{
+ RefPtrWillBePersistent<Element> element = document->createElement("foo", ASSERT_NO_EXCEPTION);
+
+ Timing timing;
+ RefPtrWillBeRawPtr<Animation> animation = Animation::create(element.get(), nullptr, timing);
+ RefPtrWillBeRawPtr<AnimationPlayer> player = timeline->createAnimationPlayer(animation.get());
+ player->setStartTime(0);
+ timeline->serviceAnimations(TimingUpdateForAnimationFrame);
+ EXPECT_EQ(1, element->activeAnimations()->players().find(player.get())->value);
+
+ player.release();
+ Heap::collectAllGarbage();
+ EXPECT_TRUE(element->activeAnimations()->players().isEmpty());
+}
+
+TEST_F(AnimationAnimationPlayerTest, HasLowerPriority)
+{
+ // Sort time defaults to timeline current time
+ updateTimeline(15);
+ RefPtrWillBeRawPtr<AnimationPlayer> player1 = timeline->createAnimationPlayer(0);
+ RefPtrWillBeRawPtr<AnimationPlayer> player2 = timeline->createAnimationPlayer(0);
+ player2->setStartTimeInternal(10);
+ RefPtrWillBeRawPtr<AnimationPlayer> player3 = timeline->createAnimationPlayer(0);
+ RefPtrWillBeRawPtr<AnimationPlayer> player4 = timeline->createAnimationPlayer(0);
+ player4->setStartTimeInternal(20);
+ RefPtrWillBeRawPtr<AnimationPlayer> player5 = timeline->createAnimationPlayer(0);
+ player5->setStartTimeInternal(10);
+ RefPtrWillBeRawPtr<AnimationPlayer> player6 = timeline->createAnimationPlayer(0);
+ player6->setStartTimeInternal(-10);
+ Vector<RefPtrWillBeMember<AnimationPlayer> > players;
+ players.append(player6);
+ players.append(player2);
+ players.append(player5);
+ players.append(player1);
+ players.append(player3);
+ players.append(player4);
+ for (size_t i = 0; i < players.size(); i++) {
+ for (size_t j = 0; j < players.size(); j++)
+ EXPECT_EQ(i < j, AnimationPlayer::hasLowerPriority(players[i].get(), players[j].get()));
+ }
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationStack.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationStack.cpp
index 601e7e598e4..7b840a16e8f 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimationStack.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationStack.cpp
@@ -32,25 +32,49 @@
#include "core/animation/AnimationStack.h"
#include "core/animation/css/CSSAnimations.h"
+#include "core/animation/interpolation/StyleInterpolation.h"
+#include "wtf/BitArray.h"
+#include "wtf/NonCopyingSort.h"
+#include <algorithm>
namespace WebCore {
namespace {
-void copyToCompositableValueMap(const AnimationEffect::CompositableValueList* source, AnimationEffect::CompositableValueMap& target)
+void copyToActiveInterpolationMap(const WillBeHeapVector<RefPtrWillBeMember<WebCore::Interpolation> >& source, WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<WebCore::Interpolation> >& target)
{
- if (!source)
- return;
- for (AnimationEffect::CompositableValueList::const_iterator iter = source->begin(); iter != source->end(); ++iter)
- target.set(iter->first, iter->second);
+ for (size_t i = 0; i < source.size(); ++i) {
+ Interpolation* interpolation = source[i].get();
+ target.set(toStyleInterpolation(interpolation)->id(), interpolation);
+ }
+}
+
+bool compareEffects(const OwnPtrWillBeMember<SampledEffect>& effect1, const OwnPtrWillBeMember<SampledEffect>& effect2)
+{
+ ASSERT(effect1 && effect2);
+ return effect1->sortInfo() < effect2->sortInfo();
+}
+
+void copyNewAnimationsToActiveInterpolationMap(const WillBeHeapVector<RawPtrWillBeMember<InertAnimation> >& newAnimations, WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& result)
+{
+ for (size_t i = 0; i < newAnimations.size(); ++i) {
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample = newAnimations[i]->sample(0);
+ if (sample) {
+ copyToActiveInterpolationMap(*sample, result);
+ }
+ }
}
} // namespace
+AnimationStack::AnimationStack()
+{
+}
+
bool AnimationStack::affects(CSSPropertyID property) const
{
- for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
- if (m_activeAnimations[i]->affects(property))
+ for (size_t i = 0; i < m_effects.size(); ++i) {
+ if (m_effects[i]->animation() && m_effects[i]->animation()->affects(property))
return true;
}
return false;
@@ -58,35 +82,71 @@ bool AnimationStack::affects(CSSPropertyID property) const
bool AnimationStack::hasActiveAnimationsOnCompositor(CSSPropertyID property) const
{
- for (size_t i = 0; i < m_activeAnimations.size(); ++i) {
- if (m_activeAnimations[i]->hasActiveAnimationsOnCompositor(property))
+ for (size_t i = 0; i < m_effects.size(); ++i) {
+ if (m_effects[i]->animation() && m_effects[i]->animation()->hasActiveAnimationsOnCompositor(property))
return true;
}
return false;
}
-AnimationEffect::CompositableValueMap AnimationStack::compositableValues(const AnimationStack* animationStack, const Vector<InertAnimation*>* newAnimations, const HashSet<const Player*>* cancelledPlayers, Animation::Priority priority)
+WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > AnimationStack::activeInterpolations(AnimationStack* animationStack, const WillBeHeapVector<RawPtrWillBeMember<InertAnimation> >* newAnimations, const WillBeHeapHashSet<RawPtrWillBeMember<const AnimationPlayer> >* cancelledAnimationPlayers, Animation::Priority priority, double timelineCurrentTime)
{
- AnimationEffect::CompositableValueMap result;
+ // We don't exactly know when new animations will start, but timelineCurrentTime is a good estimate.
+
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result;
if (animationStack) {
- const Vector<Animation*>& animations = animationStack->m_activeAnimations;
- for (size_t i = 0; i < animations.size(); ++i) {
- Animation* animation = animations[i];
- if (animation->priority() != priority)
- continue;
- if (cancelledPlayers && cancelledPlayers->contains(animation->player()))
+ WillBeHeapVector<OwnPtrWillBeMember<SampledEffect> >& effects = animationStack->m_effects;
+ // std::sort doesn't work with OwnPtrs
+ nonCopyingSort(effects.begin(), effects.end(), compareEffects);
+ animationStack->simplifyEffects();
+ for (size_t i = 0; i < effects.size(); ++i) {
+ const SampledEffect& effect = *effects[i];
+ if (effect.priority() != priority || (cancelledAnimationPlayers && effect.animation() && cancelledAnimationPlayers->contains(effect.animation()->player())))
continue;
- copyToCompositableValueMap(animation->compositableValues(), result);
+ if (newAnimations && effect.sortInfo().startTime() > timelineCurrentTime) {
+ copyNewAnimationsToActiveInterpolationMap(*newAnimations, result);
+ newAnimations = 0;
+ }
+ copyToActiveInterpolationMap(effect.interpolations(), result);
}
}
- if (newAnimations) {
- for (size_t i = 0; i < newAnimations->size(); ++i)
- copyToCompositableValueMap(newAnimations->at(i)->sample().get(), result);
- }
+ if (newAnimations)
+ copyNewAnimationsToActiveInterpolationMap(*newAnimations, result);
return result;
}
+void AnimationStack::simplifyEffects()
+{
+ // FIXME: This will need to be updated when we have 'add' keyframes.
+
+ BitArray<numCSSProperties> replacedProperties;
+ for (size_t i = m_effects.size(); i--; ) {
+ SampledEffect& effect = *m_effects[i];
+ effect.removeReplacedInterpolationsIfNeeded(replacedProperties);
+ if (!effect.canChange()) {
+ for (size_t i = 0; i < effect.interpolations().size(); ++i)
+ replacedProperties.set(toStyleInterpolation(effect.interpolations()[i].get())->id());
+ }
+ }
+
+ size_t dest = 0;
+ for (size_t i = 0; i < m_effects.size(); ++i) {
+ if (!m_effects[i]->interpolations().isEmpty()) {
+ m_effects[dest++].swap(m_effects[i]);
+ continue;
+ }
+ if (m_effects[i]->animation())
+ m_effects[i]->animation()->notifySampledEffectRemovedFromAnimationStack();
+ }
+ m_effects.shrink(dest);
+}
+
+void AnimationStack::trace(Visitor* visitor)
+{
+ visitor->trace(m_effects);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationStack.h b/chromium/third_party/WebKit/Source/core/animation/AnimationStack.h
index e7ad32f10b5..83371e8554f 100644
--- a/chromium/third_party/WebKit/Source/core/animation/AnimationStack.h
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationStack.h
@@ -33,6 +33,8 @@
#include "core/animation/Animation.h"
#include "core/animation/AnimationEffect.h"
+#include "core/animation/AnimationPlayer.h"
+#include "core/animation/SampledEffect.h"
#include "wtf/HashSet.h"
#include "wtf/Vector.h"
@@ -41,22 +43,25 @@ namespace WebCore {
class InertAnimation;
class AnimationStack {
-
+ DISALLOW_ALLOCATION();
+ WTF_MAKE_NONCOPYABLE(AnimationStack);
public:
- void add(Animation* animation) { m_activeAnimations.append(animation); }
- void remove(Animation* animation)
- {
- size_t position = m_activeAnimations.find(animation);
- ASSERT(position != kNotFound);
- m_activeAnimations.remove(position);
- }
- bool isEmpty() const { return m_activeAnimations.isEmpty(); }
+ AnimationStack();
+
+ void add(PassOwnPtrWillBeRawPtr<SampledEffect> effect) { m_effects.append(effect); }
+ bool isEmpty() const { return m_effects.isEmpty(); }
bool affects(CSSPropertyID) const;
bool hasActiveAnimationsOnCompositor(CSSPropertyID) const;
- static AnimationEffect::CompositableValueMap compositableValues(const AnimationStack*, const Vector<InertAnimation*>* newAnimations, const HashSet<const Player*>* cancelledPlayers, Animation::Priority);
+ static WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolations(AnimationStack*, const WillBeHeapVector<RawPtrWillBeMember<InertAnimation> >* newAnimations, const WillBeHeapHashSet<RawPtrWillBeMember<const AnimationPlayer> >* cancelledAnimationPlayers, Animation::Priority, double timelineCurrentTime);
+
+ void trace(Visitor*);
private:
- Vector<Animation*> m_activeAnimations;
+ void simplifyEffects();
+ // Effects sorted by priority. Lower priority at the start of the list.
+ WillBeHeapVector<OwnPtrWillBeMember<SampledEffect> > m_effects;
+
+ friend class AnimationAnimationStackTest;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationStackTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationStackTest.cpp
new file mode 100644
index 00000000000..5ebdf835d6f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationStackTest.cpp
@@ -0,0 +1,163 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/AnimationStack.h"
+
+#include "core/animation/ActiveAnimations.h"
+#include "core/animation/AnimatableDouble.h"
+#include "core/animation/AnimationClock.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/animation/KeyframeEffectModel.h"
+#include "core/animation/interpolation/LegacyStyleInterpolation.h"
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class AnimationAnimationStackTest : public ::testing::Test {
+protected:
+ virtual void SetUp()
+ {
+ document = Document::create();
+ document->animationClock().resetTimeForTesting();
+ timeline = AnimationTimeline::create(document.get());
+ element = document->createElement("foo", ASSERT_NO_EXCEPTION);
+ }
+
+ AnimationPlayer* play(Animation* animation, double startTime)
+ {
+ AnimationPlayer* player = timeline->createAnimationPlayer(animation);
+ player->setStartTimeInternal(startTime);
+ player->update(TimingUpdateOnDemand);
+ return player;
+ }
+
+ void updateTimeline(double time)
+ {
+ document->animationClock().updateTime(time);
+ timeline->serviceAnimations(TimingUpdateForAnimationFrame);
+ }
+
+ const WillBeHeapVector<OwnPtrWillBeMember<SampledEffect> >& effects()
+ {
+ return element->ensureActiveAnimations().defaultStack().m_effects;
+ }
+
+ PassRefPtrWillBeRawPtr<AnimationEffect> makeAnimationEffect(CSSPropertyID id, PassRefPtrWillBeRawPtr<AnimatableValue> value)
+ {
+ AnimatableValueKeyframeVector keyframes(2);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(id, value.get());
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(1.0);
+ keyframes[1]->setPropertyValue(id, value.get());
+ return AnimatableValueKeyframeEffectModel::create(keyframes);
+ }
+
+ PassRefPtrWillBeRawPtr<InertAnimation> makeInertAnimation(PassRefPtrWillBeRawPtr<AnimationEffect> effect)
+ {
+ Timing timing;
+ timing.fillMode = Timing::FillModeBoth;
+ return InertAnimation::create(effect, timing, false);
+ }
+
+ PassRefPtrWillBeRawPtr<Animation> makeAnimation(PassRefPtrWillBeRawPtr<AnimationEffect> effect, double duration = 10)
+ {
+ Timing timing;
+ timing.fillMode = Timing::FillModeBoth;
+ timing.iterationDuration = duration;
+ return Animation::create(element.get(), effect, timing);
+ }
+
+ AnimatableValue* interpolationValue(Interpolation* interpolation)
+ {
+ return toLegacyStyleInterpolation(interpolation)->currentValue().get();
+ }
+
+ RefPtrWillBePersistent<Document> document;
+ RefPtrWillBePersistent<AnimationTimeline> timeline;
+ RefPtrWillBePersistent<Element> element;
+};
+
+TEST_F(AnimationAnimationStackTest, ActiveAnimationsSorted)
+{
+ play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 10);
+ play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(2))).get(), 15);
+ play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(3))).get(), 5);
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0);
+ EXPECT_EQ(1u, result.size());
+ EXPECT_TRUE(interpolationValue(result.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(2).get()));
+}
+
+TEST_F(AnimationAnimationStackTest, NewAnimations)
+{
+ play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 15);
+ play(makeAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(2))).get(), 10);
+ WillBeHeapVector<RawPtrWillBeMember<InertAnimation> > newAnimations;
+ RefPtrWillBeRawPtr<InertAnimation> inert1 = makeInertAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(3)));
+ RefPtrWillBeRawPtr<InertAnimation> inert2 = makeInertAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(4)));
+ newAnimations.append(inert1.get());
+ newAnimations.append(inert2.get());
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), &newAnimations, 0, Animation::DefaultPriority, 10);
+ EXPECT_EQ(2u, result.size());
+ EXPECT_TRUE(interpolationValue(result.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(1).get()));
+ EXPECT_TRUE(interpolationValue(result.get(CSSPropertyZIndex))->equals(AnimatableDouble::create(4).get()));
+}
+
+TEST_F(AnimationAnimationStackTest, CancelledAnimationPlayers)
+{
+ WillBeHeapHashSet<RawPtrWillBeMember<const AnimationPlayer> > cancelledAnimationPlayers;
+ RefPtrWillBeRawPtr<AnimationPlayer> player = play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 0);
+ cancelledAnimationPlayers.add(player.get());
+ play(makeAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(2))).get(), 0);
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, &cancelledAnimationPlayers, Animation::DefaultPriority, 0);
+ EXPECT_EQ(1u, result.size());
+ EXPECT_TRUE(interpolationValue(result.get(CSSPropertyZIndex))->equals(AnimatableDouble::create(2).get()));
+}
+
+TEST_F(AnimationAnimationStackTest, ForwardsFillDiscarding)
+{
+ play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 2);
+ play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(2))).get(), 6);
+ play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(3))).get(), 4);
+ document->compositorPendingAnimations().startPendingAnimations();
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > interpolations;
+
+ updateTimeline(11);
+ Heap::collectAllGarbage();
+ interpolations = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0);
+ EXPECT_TRUE(interpolationValue(interpolations.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(2).get()));
+ EXPECT_EQ(3u, effects().size());
+ EXPECT_EQ(1u, interpolations.size());
+ EXPECT_EQ(2, effects()[0]->sortInfo().startTime());
+ EXPECT_EQ(4, effects()[1]->sortInfo().startTime());
+ EXPECT_EQ(6, effects()[2]->sortInfo().startTime());
+
+ updateTimeline(13);
+ Heap::collectAllGarbage();
+ interpolations = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0);
+ EXPECT_TRUE(interpolationValue(interpolations.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(2).get()));
+ EXPECT_EQ(3u, effects().size());
+ EXPECT_EQ(2, effects()[0]->sortInfo().startTime());
+ EXPECT_EQ(4, effects()[1]->sortInfo().startTime());
+ EXPECT_EQ(6, effects()[2]->sortInfo().startTime());
+
+ updateTimeline(15);
+ Heap::collectAllGarbage();
+ interpolations = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0);
+ EXPECT_TRUE(interpolationValue(interpolations.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(2).get()));
+ EXPECT_EQ(2u, effects().size());
+ EXPECT_EQ(4, effects()[0]->sortInfo().startTime());
+ EXPECT_EQ(6, effects()[1]->sortInfo().startTime());
+
+ updateTimeline(17);
+ Heap::collectAllGarbage();
+ interpolations = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0);
+ EXPECT_TRUE(interpolationValue(interpolations.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(2).get()));
+ EXPECT_EQ(1u, effects().size());
+ EXPECT_EQ(6, effects()[0]->sortInfo().startTime());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationTest.cpp
new file mode 100644
index 00000000000..2d6ea65a4fd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTest.cpp
@@ -0,0 +1,467 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/Animation.h"
+
+#include "bindings/v8/Dictionary.h"
+#include "core/animation/AnimationClock.h"
+#include "core/animation/AnimationHelpers.h"
+#include "core/animation/AnimationNodeTiming.h"
+#include "core/animation/AnimationTestHelper.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/animation/KeyframeEffectModel.h"
+#include "core/animation/Timing.h"
+#include "core/dom/Document.h"
+#include <gtest/gtest.h>
+#include <v8.h>
+
+namespace WebCore {
+
+class AnimationAnimationTest : public ::testing::Test {
+protected:
+ AnimationAnimationTest()
+ : document(Document::create())
+ , element(document->createElement("foo", ASSERT_NO_EXCEPTION))
+ {
+ document->animationClock().resetTimeForTesting();
+ EXPECT_EQ(0, document->timeline().currentTime());
+ }
+
+ RefPtrWillBePersistent<Document> document;
+ RefPtrWillBePersistent<Element> element;
+ TrackExceptionState exceptionState;
+};
+
+class AnimationAnimationV8Test : public AnimationAnimationTest {
+protected:
+ AnimationAnimationV8Test()
+ : m_isolate(v8::Isolate::GetCurrent())
+ , m_scope(m_isolate)
+ {
+ }
+
+ template<typename T>
+ static PassRefPtrWillBeRawPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, T timingInput, ExceptionState& exceptionState)
+ {
+ return Animation::create(element, EffectInput::convert(element, keyframeDictionaryVector, exceptionState), timingInput);
+ }
+ static PassRefPtrWillBeRawPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, ExceptionState& exceptionState)
+ {
+ return Animation::create(element, EffectInput::convert(element, keyframeDictionaryVector, exceptionState));
+ }
+
+ v8::Isolate* m_isolate;
+
+private:
+ V8TestingScope m_scope;
+};
+
+TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation)
+{
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "0");
+ setV8ObjectPropertyAsString(keyframe1, "easing", "ease-in-out");
+ setV8ObjectPropertyAsString(keyframe2, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe2, "offset", "1");
+ setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.3)");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+
+ String value1;
+ ASSERT_TRUE(jsKeyframes[0].get("width", value1));
+ ASSERT_EQ("100px", value1);
+
+ String value2;
+ ASSERT_TRUE(jsKeyframes[1].get("width", value2));
+ ASSERT_EQ("0px", value2);
+
+ RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, 0, exceptionState);
+
+ Element* target = animation->target();
+ EXPECT_EQ(*element.get(), *target);
+
+ const KeyframeVector keyframes = toKeyframeEffectModelBase(animation->effect())->getFrames();
+
+ EXPECT_EQ(0, keyframes[0]->offset());
+ EXPECT_EQ(1, keyframes[1]->offset());
+
+ const CSSValue* keyframe1Width = toStringKeyframe(keyframes[0].get())->propertyValue(CSSPropertyWidth);
+ const CSSValue* keyframe2Width = toStringKeyframe(keyframes[1].get())->propertyValue(CSSPropertyWidth);
+ ASSERT(keyframe1Width);
+ ASSERT(keyframe2Width);
+
+ EXPECT_EQ("100px", keyframe1Width->cssText());
+ EXPECT_EQ("0px", keyframe2Width->cssText());
+
+ EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut)), *keyframes[0]->easing());
+ EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), *keyframes[1]->easing());
+}
+
+TEST_F(AnimationAnimationV8Test, CanSetDuration)
+{
+ Vector<Dictionary, 0> jsKeyframes;
+ double duration = 2000;
+
+ RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, duration, exceptionState);
+
+ EXPECT_EQ(duration / 1000, animation->specifiedTiming().iterationDuration);
+}
+
+TEST_F(AnimationAnimationV8Test, CanOmitSpecifiedDuration)
+{
+ Vector<Dictionary, 0> jsKeyframes;
+ RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, exceptionState);
+ EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration));
+}
+
+TEST_F(AnimationAnimationV8Test, NegativeDurationIsAuto)
+{
+ Vector<Dictionary, 0> jsKeyframes;
+ RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, -2, exceptionState);
+ EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration));
+}
+
+TEST_F(AnimationAnimationV8Test, MismatchedKeyframePropertyRaisesException)
+{
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "0");
+
+ // Height property appears only in keyframe2
+ setV8ObjectPropertyAsString(keyframe2, "height", "100px");
+ setV8ObjectPropertyAsString(keyframe2, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe2, "offset", "1");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+
+ createAnimation(element.get(), jsKeyframes, 0, exceptionState);
+
+ EXPECT_TRUE(exceptionState.hadException());
+ EXPECT_EQ(NotSupportedError, exceptionState.code());
+}
+
+TEST_F(AnimationAnimationV8Test, MissingOffsetZeroRaisesException)
+{
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "0.1");
+ setV8ObjectPropertyAsString(keyframe2, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe2, "offset", "1");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+
+ createAnimation(element.get(), jsKeyframes, 0, exceptionState);
+
+ EXPECT_TRUE(exceptionState.hadException());
+ EXPECT_EQ(NotSupportedError, exceptionState.code());
+}
+
+TEST_F(AnimationAnimationV8Test, MissingOffsetOneRaisesException)
+{
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "0");
+ setV8ObjectPropertyAsString(keyframe2, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe2, "offset", "0.1");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+
+ createAnimation(element.get(), jsKeyframes, 0, exceptionState);
+
+ EXPECT_TRUE(exceptionState.hadException());
+ EXPECT_EQ(NotSupportedError, exceptionState.code());
+}
+
+TEST_F(AnimationAnimationV8Test, MissingOffsetZeroAndOneRaisesException)
+{
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "0.1");
+ setV8ObjectPropertyAsString(keyframe2, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe2, "offset", "0.2");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+
+ createAnimation(element.get(), jsKeyframes, 0, exceptionState);
+
+ EXPECT_TRUE(exceptionState.hadException());
+ EXPECT_EQ(NotSupportedError, exceptionState.code());
+}
+
+TEST_F(AnimationAnimationV8Test, SpecifiedGetters)
+{
+ Vector<Dictionary, 0> jsKeyframes;
+
+ v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+ setV8ObjectPropertyAsNumber(timingInput, "delay", 2);
+ setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5);
+ setV8ObjectPropertyAsString(timingInput, "fill", "backwards");
+ setV8ObjectPropertyAsNumber(timingInput, "iterationStart", 2);
+ setV8ObjectPropertyAsNumber(timingInput, "iterations", 10);
+ setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2);
+ setV8ObjectPropertyAsString(timingInput, "direction", "reverse");
+ setV8ObjectPropertyAsString(timingInput, "easing", "step-start");
+ Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+
+ RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState);
+
+ RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing();
+ EXPECT_EQ(2, specified->delay());
+ EXPECT_EQ(0.5, specified->endDelay());
+ EXPECT_EQ("backwards", specified->fill());
+ EXPECT_EQ(2, specified->iterationStart());
+ EXPECT_EQ(10, specified->iterations());
+ EXPECT_EQ(2, specified->playbackRate());
+ EXPECT_EQ("reverse", specified->direction());
+ EXPECT_EQ("step-start", specified->easing());
+}
+
+TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter)
+{
+ Vector<Dictionary, 0> jsKeyframes;
+
+ v8::Handle<v8::Object> timingInputWithDuration = v8::Object::New(m_isolate);
+ setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5);
+ Dictionary timingInputDictionaryWithDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputWithDuration), m_isolate);
+
+ RefPtrWillBeRawPtr<Animation> animationWithDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryWithDuration, exceptionState);
+
+ RefPtrWillBeRawPtr<AnimationNodeTiming> specifiedWithDuration = animationWithDuration->timing();
+ bool isNumber = false;
+ double numberDuration = std::numeric_limits<double>::quiet_NaN();
+ bool isString = false;
+ String stringDuration = "";
+ specifiedWithDuration->getDuration("duration", isNumber, numberDuration, isString, stringDuration);
+ EXPECT_TRUE(isNumber);
+ EXPECT_EQ(2.5, numberDuration);
+ EXPECT_FALSE(isString);
+ EXPECT_EQ("", stringDuration);
+
+
+ v8::Handle<v8::Object> timingInputNoDuration = v8::Object::New(m_isolate);
+ Dictionary timingInputDictionaryNoDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputNoDuration), m_isolate);
+
+ RefPtrWillBeRawPtr<Animation> animationNoDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryNoDuration, exceptionState);
+
+ RefPtrWillBeRawPtr<AnimationNodeTiming> specifiedNoDuration = animationNoDuration->timing();
+ isNumber = false;
+ numberDuration = std::numeric_limits<double>::quiet_NaN();
+ isString = false;
+ stringDuration = "";
+ specifiedNoDuration->getDuration("duration", isNumber, numberDuration, isString, stringDuration);
+ EXPECT_FALSE(isNumber);
+ EXPECT_TRUE(std::isnan(numberDuration));
+ EXPECT_TRUE(isString);
+ EXPECT_EQ("auto", stringDuration);
+}
+
+TEST_F(AnimationAnimationV8Test, SpecifiedSetters)
+{
+ Vector<Dictionary, 0> jsKeyframes;
+ v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+ Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+ RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState);
+
+ RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing();
+
+ EXPECT_EQ(0, specified->delay());
+ specified->setDelay(2);
+ EXPECT_EQ(2, specified->delay());
+
+ EXPECT_EQ(0, specified->endDelay());
+ specified->setEndDelay(0.5);
+ EXPECT_EQ(0.5, specified->endDelay());
+
+ EXPECT_EQ("auto", specified->fill());
+ specified->setFill("backwards");
+ EXPECT_EQ("backwards", specified->fill());
+
+ EXPECT_EQ(0, specified->iterationStart());
+ specified->setIterationStart(2);
+ EXPECT_EQ(2, specified->iterationStart());
+
+ EXPECT_EQ(1, specified->iterations());
+ specified->setIterations(10);
+ EXPECT_EQ(10, specified->iterations());
+
+ EXPECT_EQ(1, specified->playbackRate());
+ specified->setPlaybackRate(2);
+ EXPECT_EQ(2, specified->playbackRate());
+
+ EXPECT_EQ("normal", specified->direction());
+ specified->setDirection("reverse");
+ EXPECT_EQ("reverse", specified->direction());
+
+ EXPECT_EQ("linear", specified->easing());
+ specified->setEasing("step-start");
+ EXPECT_EQ("step-start", specified->easing());
+}
+
+TEST_F(AnimationAnimationV8Test, SetSpecifiedDuration)
+{
+ Vector<Dictionary, 0> jsKeyframes;
+ v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+ Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+ RefPtrWillBeRawPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary, exceptionState);
+
+ RefPtrWillBeRawPtr<AnimationNodeTiming> specified = animation->timing();
+
+ bool isNumber = false;
+ double numberDuration = std::numeric_limits<double>::quiet_NaN();
+ bool isString = false;
+ String stringDuration = "";
+ specified->getDuration("duration", isNumber, numberDuration, isString, stringDuration);
+ EXPECT_FALSE(isNumber);
+ EXPECT_TRUE(std::isnan(numberDuration));
+ EXPECT_TRUE(isString);
+ EXPECT_EQ("auto", stringDuration);
+
+ specified->setDuration("duration", 2.5);
+ isNumber = false;
+ numberDuration = std::numeric_limits<double>::quiet_NaN();
+ isString = false;
+ stringDuration = "";
+ specified->getDuration("duration", isNumber, numberDuration, isString, stringDuration);
+ EXPECT_TRUE(isNumber);
+ EXPECT_EQ(2.5, numberDuration);
+ EXPECT_FALSE(isString);
+ EXPECT_EQ("", stringDuration);
+}
+
+TEST_F(AnimationAnimationTest, TimeToEffectChange)
+{
+ Timing timing;
+ timing.iterationDuration = 100;
+ timing.startDelay = 100;
+ timing.endDelay = 100;
+ timing.fillMode = Timing::FillModeNone;
+ RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing);
+ RefPtrWillBeRawPtr<AnimationPlayer> player = document->timeline().play(animation.get());
+ double inf = std::numeric_limits<double>::infinity();
+
+ EXPECT_EQ(100, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(inf, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(100);
+ EXPECT_EQ(0, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(199);
+ EXPECT_EQ(0, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(200);
+ // End-exclusive.
+ EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(300);
+ EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(100, animation->timeToReverseEffectChange());
+}
+
+TEST_F(AnimationAnimationTest, TimeToEffectChangeWithPlaybackRate)
+{
+ Timing timing;
+ timing.iterationDuration = 100;
+ timing.startDelay = 100;
+ timing.endDelay = 100;
+ timing.playbackRate = 2;
+ timing.fillMode = Timing::FillModeNone;
+ RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing);
+ RefPtrWillBeRawPtr<AnimationPlayer> player = document->timeline().play(animation.get());
+ double inf = std::numeric_limits<double>::infinity();
+
+ EXPECT_EQ(100, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(inf, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(100);
+ EXPECT_EQ(0, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(149);
+ EXPECT_EQ(0, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(150);
+ // End-exclusive.
+ EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(200);
+ EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(50, animation->timeToReverseEffectChange());
+}
+
+TEST_F(AnimationAnimationTest, TimeToEffectChangeWithNegativePlaybackRate)
+{
+ Timing timing;
+ timing.iterationDuration = 100;
+ timing.startDelay = 100;
+ timing.endDelay = 100;
+ timing.playbackRate = -2;
+ timing.fillMode = Timing::FillModeNone;
+ RefPtrWillBeRawPtr<Animation> animation = Animation::create(0, nullptr, timing);
+ RefPtrWillBeRawPtr<AnimationPlayer> player = document->timeline().play(animation.get());
+ double inf = std::numeric_limits<double>::infinity();
+
+ EXPECT_EQ(100, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(inf, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(100);
+ EXPECT_EQ(0, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(149);
+ EXPECT_EQ(0, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(150);
+ EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(0, animation->timeToReverseEffectChange());
+
+ player->setCurrentTimeInternal(200);
+ EXPECT_EQ(inf, animation->timeToForwardsEffectChange());
+ EXPECT_EQ(50, animation->timeToReverseEffectChange());
+}
+
+TEST_F(AnimationAnimationTest, ElementDestructorClearsAnimationTarget)
+{
+ // This test expects incorrect behaviour should be removed once Element
+ // and Animation are moved to Oilpan. See crbug.com/362404 for context.
+ Timing timing;
+ timing.iterationDuration = 5;
+ RefPtrWillBeRawPtr<Animation> animation = Animation::create(element.get(), nullptr, timing);
+ EXPECT_EQ(element.get(), animation->target());
+ document->timeline().play(animation.get());
+ document.clear();
+ element.clear();
+#if !ENABLE(OILPAN)
+ EXPECT_EQ(0, animation->target());
+#endif
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTestHelper.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationTestHelper.cpp
new file mode 100644
index 00000000000..12f4e378527
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTestHelper.cpp
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/AnimationTestHelper.h"
+
+#include "bindings/v8/V8Binding.h"
+
+namespace WebCore {
+
+v8::Handle<v8::Value> stringToV8Value(String string)
+{
+ return v8::Handle<v8::Value>::Cast(v8String(v8::Isolate::GetCurrent(), string));
+}
+
+v8::Handle<v8::Value> doubleToV8Value(double number)
+{
+ return v8::Handle<v8::Value>::Cast(v8::Number::New(v8::Isolate::GetCurrent(), number));
+}
+
+void setV8ObjectPropertyAsString(v8::Handle<v8::Object> object, String name, String value)
+{
+ object->Set(stringToV8Value(name), stringToV8Value(value));
+}
+
+void setV8ObjectPropertyAsNumber(v8::Handle<v8::Object> object, String name, double value)
+{
+ object->Set(stringToV8Value(name), doubleToV8Value(value));
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTestHelper.h b/chromium/third_party/WebKit/Source/core/animation/AnimationTestHelper.h
new file mode 100644
index 00000000000..5d20c7c7152
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTestHelper.h
@@ -0,0 +1,23 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AnimationTestHelper_h
+#define AnimationTestHelper_h
+
+#include "wtf/text/WTFString.h"
+#include <v8.h>
+
+namespace WebCore {
+
+v8::Handle<v8::Value> stringToV8Value(String);
+
+v8::Handle<v8::Value> doubleToV8Value(double);
+
+void setV8ObjectPropertyAsString(v8::Handle<v8::Object>, String, String);
+
+void setV8ObjectPropertyAsNumber(v8::Handle<v8::Object>, String, double);
+
+} // namespace WebCore
+
+#endif // AnimationTestHelper_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.cpp
new file mode 100644
index 00000000000..4553fbe880f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.cpp
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/AnimationTimeline.h"
+
+#include "core/animation/ActiveAnimations.h"
+#include "core/animation/AnimationClock.h"
+#include "core/dom/Document.h"
+#include "core/frame/FrameView.h"
+#include "core/page/Page.h"
+#include "platform/TraceEvent.h"
+
+namespace WebCore {
+
+// This value represents 1 frame at 30Hz plus a little bit of wiggle room.
+// TODO: Plumb a nominal framerate through and derive this value from that.
+const double AnimationTimeline::s_minimumDelay = 0.04;
+
+
+PassRefPtrWillBeRawPtr<AnimationTimeline> AnimationTimeline::create(Document* document, PassOwnPtrWillBeRawPtr<PlatformTiming> timing)
+{
+ return adoptRefWillBeNoop(new AnimationTimeline(document, timing));
+}
+
+AnimationTimeline::AnimationTimeline(Document* document, PassOwnPtrWillBeRawPtr<PlatformTiming> timing)
+ : m_document(document)
+{
+ if (!timing)
+ m_timing = adoptPtrWillBeNoop(new AnimationTimelineTiming(this));
+ else
+ m_timing = timing;
+
+ ASSERT(document);
+}
+
+AnimationTimeline::~AnimationTimeline()
+{
+#if !ENABLE(OILPAN)
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<AnimationPlayer> >::iterator it = m_players.begin(); it != m_players.end(); ++it)
+ (*it)->timelineDestroyed();
+#endif
+}
+
+AnimationPlayer* AnimationTimeline::createAnimationPlayer(AnimationNode* child)
+{
+ RefPtrWillBeRawPtr<AnimationPlayer> player = AnimationPlayer::create(m_document->contextDocument().get(), *this, child);
+ AnimationPlayer* result = player.get();
+ m_players.add(result);
+ setOutdatedAnimationPlayer(result);
+ return result;
+}
+
+AnimationPlayer* AnimationTimeline::play(AnimationNode* child)
+{
+ if (!m_document)
+ return 0;
+ AnimationPlayer* player = createAnimationPlayer(child);
+ m_document->compositorPendingAnimations().add(player);
+ return player;
+}
+
+void AnimationTimeline::wake()
+{
+ m_timing->serviceOnNextFrame();
+}
+
+void AnimationTimeline::serviceAnimations(TimingUpdateReason reason)
+{
+ TRACE_EVENT0("webkit", "AnimationTimeline::serviceAnimations");
+
+ m_timing->cancelWake();
+
+ double timeToNextEffect = std::numeric_limits<double>::infinity();
+ WillBeHeapVector<RawPtrWillBeMember<AnimationPlayer> > players;
+ for (WillBeHeapHashSet<RefPtrWillBeMember<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it)
+ players.append(it->get());
+
+ std::sort(players.begin(), players.end(), AnimationPlayer::hasLowerPriority);
+
+ for (size_t i = 0; i < players.size(); ++i) {
+ AnimationPlayer* player = players[i];
+ if (player->update(reason))
+ timeToNextEffect = std::min(timeToNextEffect, player->timeToEffectChange());
+ else
+ m_playersNeedingUpdate.remove(player);
+ }
+
+ if (timeToNextEffect < s_minimumDelay)
+ m_timing->serviceOnNextFrame();
+ else if (timeToNextEffect != std::numeric_limits<double>::infinity())
+ m_timing->wakeAfter(timeToNextEffect - s_minimumDelay);
+
+ ASSERT(!hasOutdatedAnimationPlayer());
+}
+
+void AnimationTimeline::AnimationTimelineTiming::wakeAfter(double duration)
+{
+ m_timer.startOneShot(duration, FROM_HERE);
+}
+
+void AnimationTimeline::AnimationTimelineTiming::cancelWake()
+{
+ m_timer.stop();
+}
+
+void AnimationTimeline::AnimationTimelineTiming::serviceOnNextFrame()
+{
+ if (m_timeline->m_document && m_timeline->m_document->view())
+ m_timeline->m_document->view()->scheduleAnimation();
+}
+
+void AnimationTimeline::AnimationTimelineTiming::trace(Visitor* visitor)
+{
+ visitor->trace(m_timeline);
+ AnimationTimeline::PlatformTiming::trace(visitor);
+}
+
+double AnimationTimeline::currentTime(bool& isNull)
+{
+ return currentTimeInternal(isNull) * 1000;
+}
+
+double AnimationTimeline::currentTimeInternal(bool& isNull)
+{
+ if (!m_document) {
+ isNull = true;
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+ double result = m_document->animationClock().currentTime() - zeroTime();
+ isNull = std::isnan(result);
+ return result;
+}
+
+double AnimationTimeline::currentTime()
+{
+ return currentTimeInternal() * 1000;
+}
+
+double AnimationTimeline::currentTimeInternal()
+{
+ bool isNull;
+ return currentTimeInternal(isNull);
+}
+
+double AnimationTimeline::effectiveTime()
+{
+ double time = currentTimeInternal();
+ return std::isnan(time) ? 0 : time;
+}
+
+void AnimationTimeline::pauseAnimationsForTesting(double pauseTime)
+{
+ for (WillBeHeapHashSet<RefPtrWillBeMember<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it)
+ (*it)->pauseForTesting(pauseTime);
+ serviceAnimations(TimingUpdateOnDemand);
+}
+
+bool AnimationTimeline::hasOutdatedAnimationPlayer() const
+{
+ for (WillBeHeapHashSet<RefPtrWillBeMember<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it) {
+ if ((*it)->outdated())
+ return true;
+ }
+ return false;
+}
+
+void AnimationTimeline::setOutdatedAnimationPlayer(AnimationPlayer* player)
+{
+ ASSERT(player->outdated());
+ m_playersNeedingUpdate.add(player);
+ if (m_document && m_document->page() && !m_document->page()->animator().isServicingAnimations())
+ m_timing->serviceOnNextFrame();
+}
+
+size_t AnimationTimeline::numberOfActiveAnimationsForTesting() const
+{
+ // Includes all players whose directly associated timed items
+ // are current or in effect.
+ size_t count = 0;
+ for (WillBeHeapHashSet<RefPtrWillBeMember<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it) {
+ const AnimationNode* animationNode = (*it)->source();
+ if ((*it)->hasStartTime())
+ count += (animationNode && (animationNode->isCurrent() || animationNode->isInEffect()));
+ }
+ return count;
+}
+
+#if !ENABLE(OILPAN)
+void AnimationTimeline::detachFromDocument()
+{
+ // FIXME: AnimationTimeline should keep Document alive.
+ m_document = nullptr;
+}
+#endif
+
+void AnimationTimeline::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_timing);
+ visitor->trace(m_playersNeedingUpdate);
+ visitor->trace(m_players);
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.h b/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.h
new file mode 100644
index 00000000000..1a523a28651
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AnimationTimeline_h
+#define AnimationTimeline_h
+
+#include "core/animation/AnimationEffect.h"
+#include "core/animation/AnimationPlayer.h"
+#include "core/dom/Element.h"
+#include "core/events/Event.h"
+#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class Document;
+class AnimationNode;
+
+// AnimationTimeline is constructed and owned by Document, and tied to its lifecycle.
+class AnimationTimeline : public RefCountedWillBeGarbageCollectedFinalized<AnimationTimeline> {
+public:
+ class PlatformTiming : public NoBaseWillBeGarbageCollectedFinalized<PlatformTiming> {
+
+ public:
+ // Calls AnimationTimeline's wake() method after duration seconds.
+ virtual void wakeAfter(double duration) = 0;
+ virtual void cancelWake() = 0;
+ virtual void serviceOnNextFrame() = 0;
+ virtual ~PlatformTiming() { }
+ virtual void trace(Visitor*) { }
+ };
+
+ static PassRefPtrWillBeRawPtr<AnimationTimeline> create(Document*, PassOwnPtrWillBeRawPtr<PlatformTiming> = nullptr);
+ ~AnimationTimeline();
+
+ void serviceAnimations(TimingUpdateReason);
+
+ // Creates a player attached to this timeline, but without a start time.
+ AnimationPlayer* createAnimationPlayer(AnimationNode*);
+ AnimationPlayer* play(AnimationNode*);
+
+#if !ENABLE(OILPAN)
+ void playerDestroyed(AnimationPlayer* player)
+ {
+ ASSERT(m_players.contains(player));
+ m_players.remove(player);
+ }
+#endif
+
+ bool hasPendingUpdates() const { return !m_playersNeedingUpdate.isEmpty(); }
+ double zeroTime() const { return 0; }
+ double currentTime(bool& isNull);
+ double currentTime();
+ double currentTimeInternal(bool& isNull);
+ double currentTimeInternal();
+ double effectiveTime();
+ void pauseAnimationsForTesting(double);
+ size_t numberOfActiveAnimationsForTesting() const;
+
+ void setOutdatedAnimationPlayer(AnimationPlayer*);
+ bool hasOutdatedAnimationPlayer() const;
+
+ Document* document() { return m_document.get(); }
+#if !ENABLE(OILPAN)
+ void detachFromDocument();
+#endif
+ void wake();
+
+ void trace(Visitor*);
+
+protected:
+ AnimationTimeline(Document*, PassOwnPtrWillBeRawPtr<PlatformTiming>);
+
+private:
+ RawPtrWillBeMember<Document> m_document;
+ // AnimationPlayers which will be updated on the next frame
+ // i.e. current, in effect, or had timing changed
+ WillBeHeapHashSet<RefPtrWillBeMember<AnimationPlayer> > m_playersNeedingUpdate;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<AnimationPlayer> > m_players;
+
+ friend class SMILTimeContainer;
+ static const double s_minimumDelay;
+
+ OwnPtrWillBeMember<PlatformTiming> m_timing;
+
+ class AnimationTimelineTiming FINAL : public PlatformTiming {
+ public:
+ AnimationTimelineTiming(AnimationTimeline* timeline)
+ : m_timeline(timeline)
+ , m_timer(this, &AnimationTimelineTiming::timerFired)
+ {
+ ASSERT(m_timeline);
+ }
+
+ virtual void wakeAfter(double duration) OVERRIDE;
+ virtual void cancelWake() OVERRIDE;
+ virtual void serviceOnNextFrame() OVERRIDE;
+
+ void timerFired(Timer<AnimationTimelineTiming>*) { m_timeline->wake(); }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ private:
+ RawPtrWillBeMember<AnimationTimeline> m_timeline;
+ Timer<AnimationTimelineTiming> m_timer;
+ };
+
+ friend class AnimationAnimationTimelineTest;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.idl b/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.idl
new file mode 100644
index 00000000000..b2c627afde3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTimeline.idl
@@ -0,0 +1,11 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=WebAnimationsAPI,
+ WillBeGarbageCollected,
+] interface AnimationTimeline {
+ readonly attribute double? currentTime;
+ AnimationPlayer play(AnimationNode source);
+};
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTimelineTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationTimelineTest.cpp
new file mode 100644
index 00000000000..68cc2895a9b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTimelineTest.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/AnimationTimeline.h"
+
+#include "core/animation/Animation.h"
+#include "core/animation/AnimationClock.h"
+#include "core/animation/AnimationNode.h"
+#include "core/animation/KeyframeEffectModel.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/QualifiedName.h"
+#include "platform/weborigin/KURL.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class MockPlatformTiming : public AnimationTimeline::PlatformTiming {
+public:
+
+ MOCK_METHOD1(wakeAfter, void(double));
+ MOCK_METHOD0(cancelWake, void());
+ MOCK_METHOD0(serviceOnNextFrame, void());
+
+ /**
+ * AnimationTimelines should do one of the following things after servicing animations:
+ * - cancel the timer and not request to be woken again (expectNoMoreActions)
+ * - cancel the timer and request to be woken on the next frame (expectNextFrameAction)
+ * - cancel the timer and request to be woken at some point in the future (expectDelayedAction)
+ */
+
+ void expectNoMoreActions()
+ {
+ EXPECT_CALL(*this, cancelWake());
+ }
+
+ void expectNextFrameAction()
+ {
+ ::testing::Sequence sequence;
+ EXPECT_CALL(*this, cancelWake()).InSequence(sequence);
+ EXPECT_CALL(*this, serviceOnNextFrame()).InSequence(sequence);
+ }
+
+ void expectDelayedAction(double when)
+ {
+ ::testing::Sequence sequence;
+ EXPECT_CALL(*this, cancelWake()).InSequence(sequence);
+ EXPECT_CALL(*this, wakeAfter(when)).InSequence(sequence);
+ }
+
+ void trace(Visitor* visitor)
+ {
+ AnimationTimeline::PlatformTiming::trace(visitor);
+ }
+};
+
+class AnimationAnimationTimelineTest : public ::testing::Test {
+protected:
+ virtual void SetUp()
+ {
+ document = Document::create();
+ document->animationClock().resetTimeForTesting();
+ element = Element::create(QualifiedName::null() , document.get());
+ platformTiming = new MockPlatformTiming;
+ timeline = AnimationTimeline::create(document.get(), adoptPtrWillBeNoop(platformTiming));
+ ASSERT_EQ(0, timeline->currentTimeInternal());
+ }
+
+ virtual void TearDown()
+ {
+ document.release();
+ element.release();
+ timeline.release();
+ }
+
+ void updateClockAndService(double time)
+ {
+ document->animationClock().updateTime(time);
+ timeline->serviceAnimations(TimingUpdateForAnimationFrame);
+ }
+
+ RefPtrWillBePersistent<Document> document;
+ RefPtrWillBePersistent<Element> element;
+ RefPtrWillBePersistent<AnimationTimeline> timeline;
+ Timing timing;
+ MockPlatformTiming* platformTiming;
+
+ void wake()
+ {
+ timeline->wake();
+ }
+
+ double minimumDelay()
+ {
+ return AnimationTimeline::s_minimumDelay;
+ }
+};
+
+TEST_F(AnimationAnimationTimelineTest, HasStarted)
+{
+ timeline = AnimationTimeline::create(document.get());
+}
+
+TEST_F(AnimationAnimationTimelineTest, EmptyKeyframeAnimation)
+{
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector());
+ RefPtrWillBeRawPtr<Animation> anim = Animation::create(element.get(), effect, timing);
+
+ timeline->play(anim.get());
+
+ platformTiming->expectNoMoreActions();
+ updateClockAndService(0);
+ EXPECT_FLOAT_EQ(0, timeline->currentTimeInternal());
+ EXPECT_FALSE(anim->isInEffect());
+
+ platformTiming->expectNoMoreActions();
+ updateClockAndService(100);
+ EXPECT_FLOAT_EQ(100, timeline->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationTimelineTest, EmptyForwardsKeyframeAnimation)
+{
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector());
+ timing.fillMode = Timing::FillModeForwards;
+ RefPtrWillBeRawPtr<Animation> anim = Animation::create(element.get(), effect, timing);
+
+ timeline->play(anim.get());
+
+ platformTiming->expectNoMoreActions();
+ updateClockAndService(0);
+ EXPECT_FLOAT_EQ(0, timeline->currentTimeInternal());
+ EXPECT_TRUE(anim->isInEffect());
+
+ platformTiming->expectNoMoreActions();
+ updateClockAndService(100);
+ EXPECT_FLOAT_EQ(100, timeline->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationTimelineTest, ZeroTime)
+{
+ timeline = AnimationTimeline::create(document.get());
+ bool isNull;
+
+ document->animationClock().updateTime(100);
+ EXPECT_EQ(100, timeline->currentTimeInternal());
+ EXPECT_EQ(100, timeline->currentTimeInternal(isNull));
+ EXPECT_FALSE(isNull);
+
+ document->animationClock().updateTime(200);
+ EXPECT_EQ(200, timeline->currentTimeInternal());
+ EXPECT_EQ(200, timeline->currentTimeInternal(isNull));
+ EXPECT_FALSE(isNull);
+}
+
+TEST_F(AnimationAnimationTimelineTest, PauseForTesting)
+{
+ float seekTime = 1;
+ timing.fillMode = Timing::FillModeForwards;
+ RefPtrWillBeRawPtr<Animation> anim1 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timing);
+ RefPtrWillBeRawPtr<Animation> anim2 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timing);
+ AnimationPlayer* player1 = timeline->play(anim1.get());
+ AnimationPlayer* player2 = timeline->play(anim2.get());
+ timeline->pauseAnimationsForTesting(seekTime);
+
+ EXPECT_FLOAT_EQ(seekTime, player1->currentTimeInternal());
+ EXPECT_FLOAT_EQ(seekTime, player2->currentTimeInternal());
+}
+
+TEST_F(AnimationAnimationTimelineTest, NumberOfActiveAnimations)
+{
+ Timing timingForwardFill;
+ timingForwardFill.iterationDuration = 2;
+ timingForwardFill.fillMode = Timing::FillModeForwards;
+
+ Timing timingNoFill;
+ timingNoFill.iterationDuration = 2;
+ timingNoFill.fillMode = Timing::FillModeNone;
+
+ Timing timingBackwardFillDelay;
+ timingBackwardFillDelay.iterationDuration = 1;
+ timingBackwardFillDelay.fillMode = Timing::FillModeBackwards;
+ timingBackwardFillDelay.startDelay = 1;
+
+ Timing timingNoFillDelay;
+ timingNoFillDelay.iterationDuration = 1;
+ timingNoFillDelay.fillMode = Timing::FillModeNone;
+ timingNoFillDelay.startDelay = 1;
+
+ Timing timingAutoFill;
+ timingAutoFill.iterationDuration = 2;
+
+ RefPtrWillBeRawPtr<Animation> anim1 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingForwardFill);
+ RefPtrWillBeRawPtr<Animation> anim2 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingNoFill);
+ RefPtrWillBeRawPtr<Animation> anim3 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingBackwardFillDelay);
+ RefPtrWillBeRawPtr<Animation> anim4 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingNoFillDelay);
+ RefPtrWillBeRawPtr<Animation> anim5 = Animation::create(element.get(), AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector()), timingAutoFill);
+
+ timeline->play(anim1.get());
+ timeline->play(anim2.get());
+ timeline->play(anim3.get());
+ timeline->play(anim4.get());
+ timeline->play(anim5.get());
+
+ platformTiming->expectNextFrameAction();
+ updateClockAndService(0);
+ EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
+ platformTiming->expectNextFrameAction();
+ updateClockAndService(0.5);
+ EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
+ platformTiming->expectNextFrameAction();
+ updateClockAndService(1.5);
+ EXPECT_EQ(5U, timeline->numberOfActiveAnimationsForTesting());
+ platformTiming->expectNoMoreActions();
+ updateClockAndService(3);
+ EXPECT_EQ(0U, timeline->numberOfActiveAnimationsForTesting());
+}
+
+TEST_F(AnimationAnimationTimelineTest, DelayBeforeAnimationStart)
+{
+ timing.iterationDuration = 2;
+ timing.startDelay = 5;
+
+ RefPtrWillBeRawPtr<Animation> anim = Animation::create(element.get(), nullptr, timing);
+
+ timeline->play(anim.get());
+
+ // TODO: Put the player startTime in the future when we add the capability to change player startTime
+ platformTiming->expectDelayedAction(timing.startDelay - minimumDelay());
+ updateClockAndService(0);
+
+ platformTiming->expectDelayedAction(timing.startDelay - minimumDelay() - 1.5);
+ updateClockAndService(1.5);
+
+ EXPECT_CALL(*platformTiming, serviceOnNextFrame());
+ wake();
+
+ platformTiming->expectNextFrameAction();
+ updateClockAndService(4.98);
+}
+
+TEST_F(AnimationAnimationTimelineTest, PlayAfterDocumentDeref)
+{
+ timing.iterationDuration = 2;
+ timing.startDelay = 5;
+
+ timeline = &document->timeline();
+ element = nullptr;
+ document = nullptr;
+
+ RefPtrWillBeRawPtr<Animation> anim = Animation::create(0, nullptr, timing);
+ // Test passes if this does not crash.
+ timeline->play(anim.get());
+}
+
+TEST_F(AnimationAnimationTimelineTest, UseAnimationPlayerAfterTimelineDeref)
+{
+ RefPtrWillBeRawPtr<AnimationPlayer> player = timeline->createAnimationPlayer(0);
+ timeline.clear();
+ // Test passes if this does not crash.
+ player->setStartTime(0);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp
new file mode 100644
index 00000000000..3fbdf306611
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/animation/AnimationTranslationUtil.h"
+
+#include "platform/graphics/filters/FilterOperations.h"
+#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
+#include "platform/transforms/InterpolatedTransformOperation.h"
+#include "platform/transforms/Matrix3DTransformOperation.h"
+#include "platform/transforms/MatrixTransformOperation.h"
+#include "platform/transforms/PerspectiveTransformOperation.h"
+#include "platform/transforms/RotateTransformOperation.h"
+#include "platform/transforms/ScaleTransformOperation.h"
+#include "platform/transforms/SkewTransformOperation.h"
+#include "platform/transforms/TransformOperations.h"
+#include "platform/transforms/TransformationMatrix.h"
+#include "platform/transforms/TranslateTransformOperation.h"
+#include "public/platform/WebTransformOperations.h"
+
+using namespace blink;
+
+namespace WebCore {
+
+void toWebTransformOperations(const TransformOperations& transformOperations, WebTransformOperations* webTransformOperations)
+{
+ // We need to do a deep copy the transformOperations may contain ref pointers to TransformOperation objects.
+ for (size_t j = 0; j < transformOperations.size(); ++j) {
+ switch (transformOperations.operations()[j]->type()) {
+ case TransformOperation::ScaleX:
+ case TransformOperation::ScaleY:
+ case TransformOperation::ScaleZ:
+ case TransformOperation::Scale3D:
+ case TransformOperation::Scale: {
+ ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(transformOperations.operations()[j].get());
+ webTransformOperations->appendScale(transform->x(), transform->y(), transform->z());
+ break;
+ }
+ case TransformOperation::TranslateX:
+ case TransformOperation::TranslateY:
+ case TransformOperation::TranslateZ:
+ case TransformOperation::Translate3D:
+ case TransformOperation::Translate: {
+ TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(transformOperations.operations()[j].get());
+ ASSERT(transform->x().isFixed() && transform->y().isFixed());
+ webTransformOperations->appendTranslate(transform->x().value(), transform->y().value(), transform->z());
+ break;
+ }
+ case TransformOperation::RotateX:
+ case TransformOperation::RotateY:
+ case TransformOperation::Rotate3D:
+ case TransformOperation::Rotate: {
+ RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(transformOperations.operations()[j].get());
+ webTransformOperations->appendRotate(transform->x(), transform->y(), transform->z(), transform->angle());
+ break;
+ }
+ case TransformOperation::SkewX:
+ case TransformOperation::SkewY:
+ case TransformOperation::Skew: {
+ SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(transformOperations.operations()[j].get());
+ webTransformOperations->appendSkew(transform->angleX(), transform->angleY());
+ break;
+ }
+ case TransformOperation::Matrix: {
+ MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(transformOperations.operations()[j].get());
+ TransformationMatrix m = transform->matrix();
+ webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
+ break;
+ }
+ case TransformOperation::Matrix3D: {
+ Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(transformOperations.operations()[j].get());
+ TransformationMatrix m = transform->matrix();
+ webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
+ break;
+ }
+ case TransformOperation::Perspective: {
+ PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(transformOperations.operations()[j].get());
+ webTransformOperations->appendPerspective(transform->perspective());
+ break;
+ }
+ case TransformOperation::Interpolated: {
+ TransformationMatrix m;
+ transformOperations.operations()[j]->apply(m, FloatSize());
+ webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
+ break;
+ }
+ case TransformOperation::Identity:
+ webTransformOperations->appendIdentity();
+ break;
+ case TransformOperation::None:
+ // Do nothing.
+ break;
+ } // switch
+ } // for each operation
+}
+
+bool toWebFilterOperations(const FilterOperations& inOperations, WebFilterOperations* outOperations)
+{
+ SkiaImageFilterBuilder builder;
+ FilterOutsets outsets = inOperations.outsets();
+ builder.setCropOffset(FloatSize(outsets.left(), outsets.top()));
+ return builder.buildFilterOperations(inOperations, outOperations);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtil.h b/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtil.h
new file mode 100644
index 00000000000..c69635b5200
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtil.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AnimationTranslationUtil_h
+#define AnimationTranslationUtil_h
+
+namespace blink {
+class WebTransformOperations;
+class WebFilterOperations;
+}
+
+namespace WebCore {
+
+class FilterOperations;
+class TransformOperations;
+
+void toWebTransformOperations(const TransformOperations& inOperations, blink::WebTransformOperations* outOperations);
+bool toWebFilterOperations(const FilterOperations& inOperations, blink::WebFilterOperations* outOperations);
+
+} // namespace WebCore
+
+#endif // AnimationTranslationUtil_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtilTest.cpp b/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtilTest.cpp
new file mode 100644
index 00000000000..d55e790d2af
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/AnimationTranslationUtilTest.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/animation/AnimationTranslationUtil.h"
+
+#include "core/animation/css/CSSAnimationData.h"
+#include "platform/animation/KeyframeValueList.h"
+#include "platform/geometry/IntSize.h"
+#include "platform/graphics/filters/FilterOperations.h"
+#include "platform/transforms/Matrix3DTransformOperation.h"
+#include "platform/transforms/RotateTransformOperation.h"
+#include "platform/transforms/ScaleTransformOperation.h"
+#include "platform/transforms/TransformOperations.h"
+#include "platform/transforms/TranslateTransformOperation.h"
+#include "public/platform/WebAnimation.h"
+#include "public/platform/WebFilterOperations.h"
+#include "public/platform/WebTransformOperations.h"
+#include "wtf/RefPtr.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+using namespace blink;
+
+namespace {
+
+class WebTransformOperationsMock : public blink::WebTransformOperations {
+public:
+ MOCK_CONST_METHOD1(canBlendWith, bool(const WebTransformOperations&));
+ MOCK_METHOD3(appendTranslate, void(double, double, double));
+ MOCK_METHOD4(appendRotate, void(double, double, double, double));
+ MOCK_METHOD3(appendScale, void(double, double, double));
+ MOCK_METHOD2(appendSkew, void(double, double));
+ MOCK_METHOD1(appendPerspective, void(double));
+ MOCK_METHOD1(appendMatrix, void(const SkMatrix44&));
+ MOCK_METHOD0(appendIdentity, void());
+ MOCK_CONST_METHOD0(isIdentity, bool());
+};
+
+class WebFilterOperationsMock : public blink::WebFilterOperations {
+public:
+ MOCK_METHOD1(appendGrayscaleFilter, void(float));
+ MOCK_METHOD1(appendSepiaFilter, void(float));
+ MOCK_METHOD1(appendSaturateFilter, void(float));
+ MOCK_METHOD1(appendHueRotateFilter, void(float));
+ MOCK_METHOD1(appendInvertFilter, void(float));
+ MOCK_METHOD1(appendBrightnessFilter, void(float));
+ MOCK_METHOD1(appendContrastFilter, void(float));
+ MOCK_METHOD1(appendOpacityFilter, void(float));
+ MOCK_METHOD1(appendBlurFilter, void(float));
+ MOCK_METHOD3(appendDropShadowFilter, void(WebPoint, float, WebColor));
+ MOCK_METHOD1(appendColorMatrixFilter, void(SkScalar[20]));
+ MOCK_METHOD2(appendZoomFilter, void(float, int));
+ MOCK_METHOD1(appendSaturatingBrightnessFilter, void(float));
+ MOCK_METHOD1(appendReferenceFilter, void(SkImageFilter*));
+ MOCK_METHOD0(clear, void());
+};
+
+TEST(AnimationTranslationUtilTest, transformsWork)
+{
+ TransformOperations ops;
+ WebTransformOperationsMock outOps;
+
+ EXPECT_CALL(outOps, appendTranslate(2, 0, 0));
+ EXPECT_CALL(outOps, appendRotate(0.1, 0.2, 0.3, 200000.4));
+ EXPECT_CALL(outOps, appendScale(50.2, 100, -4));
+
+ ops.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
+ ops.operations().append(RotateTransformOperation::create(0.1, 0.2, 0.3, 200000.4, TransformOperation::Rotate3D));
+ ops.operations().append(ScaleTransformOperation::create(50.2, 100, -4, TransformOperation::Scale3D));
+ toWebTransformOperations(ops, &outOps);
+}
+
+TEST(AnimationTranslationUtilTest, filtersWork)
+{
+ FilterOperations ops;
+ WebFilterOperationsMock outOps;
+
+ EXPECT_CALL(outOps, appendSaturateFilter(0.5));
+ EXPECT_CALL(outOps, appendGrayscaleFilter(0.2f));
+ EXPECT_CALL(outOps, appendSepiaFilter(0.8f));
+ EXPECT_CALL(outOps, appendOpacityFilter(0.1f));
+
+ ops.operations().append(BasicColorMatrixFilterOperation::create(0.5, FilterOperation::SATURATE));
+ ops.operations().append(BasicColorMatrixFilterOperation::create(0.2, FilterOperation::GRAYSCALE));
+ ops.operations().append(BasicColorMatrixFilterOperation::create(0.8, FilterOperation::SEPIA));
+ ops.operations().append(BasicColorMatrixFilterOperation::create(0.1, FilterOperation::OPACITY));
+ toWebFilterOperations(ops, &outOps);
+}
+
+}
+
diff --git a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
index 929f0737165..f2128db3b61 100644
--- a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.cpp
@@ -35,12 +35,12 @@
#include "core/animation/AnimatableFilterOperations.h"
#include "core/animation/AnimatableTransform.h"
#include "core/animation/AnimatableValue.h"
+#include "core/animation/AnimationTranslationUtil.h"
#include "core/animation/CompositorAnimationsImpl.h"
-#include "core/platform/animation/AnimationTranslationUtil.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/RenderBoxModelObject.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderObject.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
#include "public/platform/Platform.h"
#include "public/platform/WebAnimation.h"
#include "public/platform/WebCompositorSupport.h"
@@ -58,10 +58,10 @@ namespace WebCore {
namespace {
-void getKeyframeValuesForProperty(const KeyframeAnimationEffect* effect, CSSPropertyID id, double scale, bool reverse, KeyframeVector& values)
+void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSPropertyID id, double scale, bool reverse, PropertySpecificKeyframeVector& values)
{
ASSERT(values.isEmpty());
- const KeyframeVector& group = effect->getPropertySpecificKeyframes(id);
+ const PropertySpecificKeyframeVector& group = effect->getPropertySpecificKeyframes(id);
if (reverse) {
for (size_t i = group.size(); i--;) {
@@ -105,18 +105,6 @@ PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c
}
}
-PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(const ChainedTimingFunction* timefunc)
-{
- RefPtr<ChainedTimingFunction> reversed = ChainedTimingFunction::create();
- for (size_t i = 0; i < timefunc->m_segments.size(); i++) {
- size_t index = timefunc->m_segments.size() - i - 1;
-
- RefPtr<TimingFunction> rtf = reverse(timefunc->m_segments[index].m_timingFunction.get());
- reversed->appendSegment(1 - timefunc->m_segments[index].m_min, rtf.get());
- }
- return reversed;
-}
-
PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(const TimingFunction* timefunc)
{
switch (timefunc->type()) {
@@ -128,10 +116,6 @@ PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c
const CubicBezierTimingFunction* cubic = toCubicBezierTimingFunction(timefunc);
return reverse(cubic);
}
- case TimingFunction::ChainedFunction: {
- const ChainedTimingFunction* chained = toChainedTimingFunction(timefunc);
- return reverse(chained);
- }
// Steps function can not be reversed.
case TimingFunction::StepsFunction:
@@ -147,103 +131,54 @@ PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(c
bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& timing, const AnimationEffect& effect)
{
- const KeyframeAnimationEffect& keyframeEffect = *toKeyframeAnimationEffect(&effect);
+ const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(&effect);
- // Are the keyframes convertible?
- const KeyframeAnimationEffect::KeyframeVector frames = keyframeEffect.getFrames();
- for (size_t i = 0; i < frames.size(); ++i) {
- // Only replace mode can be accelerated
- if (frames[i]->composite() != AnimationEffect::CompositeReplace)
- return false;
+ PropertySet properties = keyframeEffect.properties();
- // Check all the properties can be accelerated
- const PropertySet properties = frames[i]->properties(); // FIXME: properties creates a whole new PropertySet!
+ if (properties.isEmpty())
+ return false;
- if (properties.isEmpty())
- return false;
+ for (PropertySet::const_iterator it = properties.begin(); it != properties.end(); ++it) {
+ const PropertySpecificKeyframeVector& frames = keyframeEffect.getPropertySpecificKeyframes(*it);
+ ASSERT(frames.size() >= 2);
+ for (size_t i = 0; i < frames.size(); ++i) {
+ const Keyframe::PropertySpecificKeyframe *frame = frames[i].get();
+ // FIXME: Determine candidacy based on the CSSValue instead of a snapshot AnimatableValue.
+ if (frame->composite() != AnimationEffect::CompositeReplace || !frame->getAnimatableValue())
+ return false;
- for (PropertySet::const_iterator it = properties.begin(); it != properties.end(); ++it) {
switch (*it) {
case CSSPropertyOpacity:
- continue;
- case CSSPropertyWebkitTransform:
- if (toAnimatableTransform(frames[i]->propertyValue(CSSPropertyWebkitTransform))->transformOperations().dependsOnBoxSize())
+ break;
+ case CSSPropertyTransform:
+ if (toAnimatableTransform(frame->getAnimatableValue().get())->transformOperations().dependsOnBoxSize())
return false;
- continue;
+ break;
case CSSPropertyWebkitFilter: {
- const FilterOperations& operations = toAnimatableFilterOperations(frames[i]->propertyValue(CSSPropertyWebkitFilter))->operations();
+ const FilterOperations& operations = toAnimatableFilterOperations(frame->getAnimatableValue().get())->operations();
if (operations.hasFilterThatMovesPixels())
return false;
- for (size_t i = 0; i < operations.size(); i++) {
- const FilterOperation& op = *operations.at(i);
- if (op.type() == FilterOperation::VALIDATED_CUSTOM || op.type() == FilterOperation::CUSTOM)
- return false;
- }
- continue;
+ break;
}
default:
return false;
}
+
+ // FIXME: Remove this check when crbug.com/229405 is resolved
+ if (i < frames.size() - 1 && frame->easing()->type() == TimingFunction::StepsFunction)
+ return false;
}
}
- // Is the timing object convertible?
CompositorAnimationsImpl::CompositorTiming out;
if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, out))
return false;
- // Is the timing function convertible?
- switch (timing.timingFunction->type()) {
- case TimingFunction::LinearFunction:
- break;
-
- case TimingFunction::CubicBezierFunction:
- // Can have a cubic if we don't have to split it (IE only have two frames).
- if (frames.size() != 2)
- return false;
-
- ASSERT(frames[0]->offset() == 0.0 && frames[1]->offset() == 1.0);
- break;
-
- case TimingFunction::StepsFunction:
+ // FIXME: We should support non-linear timing functions in the compositor
+ // eventually.
+ if (timing.timingFunction->type() != TimingFunction::LinearFunction)
return false;
- case TimingFunction::ChainedFunction: {
- // Currently we only support chained segments in the form the CSS code
- // generates. These chained segments are only one level deep and have
- // one timing function per frame.
- const ChainedTimingFunction* chained = static_cast<const ChainedTimingFunction*>(timing.timingFunction.get());
- if (!chained->m_segments.size())
- return false;
-
- if (frames.size() != chained->m_segments.size() + 1)
- return false;
-
- for (size_t timeIndex = 0; timeIndex < chained->m_segments.size(); timeIndex++) {
- const ChainedTimingFunction::Segment& segment = chained->m_segments[timeIndex];
-
- if (frames[timeIndex]->offset() != segment.m_min || frames[timeIndex + 1]->offset() != segment.m_max)
- return false;
-
- switch (segment.m_timingFunction->type()) {
- case TimingFunction::LinearFunction:
- case TimingFunction::CubicBezierFunction:
- continue;
-
- case TimingFunction::StepsFunction:
- case TimingFunction::ChainedFunction:
- default:
- return false;
- }
- }
-
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
-
return true;
}
@@ -252,19 +187,19 @@ bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element)
return element.renderer() && element.renderer()->compositingState() == PaintsIntoOwnBacking;
}
-bool CompositorAnimations::startAnimationOnCompositor(const Element& element, const Timing& timing, const AnimationEffect& effect, Vector<int>& startedAnimationIds)
+bool CompositorAnimations::startAnimationOnCompositor(const Element& element, double startTime, const Timing& timing, const AnimationEffect& effect, Vector<int>& startedAnimationIds)
{
ASSERT(startedAnimationIds.isEmpty());
ASSERT(isCandidateForAnimationOnCompositor(timing, effect));
ASSERT(canStartAnimationOnCompositor(element));
- const KeyframeAnimationEffect& keyframeEffect = *toKeyframeAnimationEffect(&effect);
+ const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(&effect);
RenderLayer* layer = toRenderBoxModelObject(element.renderer())->layer();
ASSERT(layer);
Vector<OwnPtr<blink::WebAnimation> > animations;
- CompositorAnimationsImpl::getAnimationOnCompositor(timing, keyframeEffect, animations);
+ CompositorAnimationsImpl::getAnimationOnCompositor(timing, startTime, keyframeEffect, animations);
ASSERT(!animations.isEmpty());
for (size_t i = 0; i < animations.size(); ++i) {
int id = animations[i]->id();
@@ -284,7 +219,11 @@ bool CompositorAnimations::startAnimationOnCompositor(const Element& element, co
void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, int id)
{
if (!canStartAnimationOnCompositor(element)) {
- ASSERT_NOT_REACHED();
+ // When an element is being detached, we cancel any associated
+ // AnimationPlayers for CSS animations. But by the time we get
+ // here the mapping will have been removed.
+ // FIXME: Defer remove/pause operations until after the
+ // compositing update.
return;
}
toRenderBoxModelObject(element.renderer())->layer()->compositedLayerMapping()->mainGraphicsLayer()->removeAnimation(id);
@@ -292,6 +231,10 @@ void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, i
void CompositorAnimations::pauseAnimationForTestingOnCompositor(const Element& element, int id, double pauseTime)
{
+ // FIXME: canStartAnimationOnCompositor queries compositingState, which is not necessarily up to date.
+ // https://code.google.com/p/chromium/issues/detail?id=339847
+ DisableCompositingQueryAsserts disabler;
+
if (!canStartAnimationOnCompositor(element)) {
ASSERT_NOT_REACHED();
return;
@@ -318,7 +261,7 @@ bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing,
if ((std::floor(timing.iterationCount) != timing.iterationCount) || timing.iterationCount <= 0)
return false;
- if (!timing.iterationDuration)
+ if (std::isnan(timing.iterationDuration) || !timing.iterationDuration)
return false;
// FIXME: Support other playback rates
@@ -402,7 +345,6 @@ void addKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const Plat
}
case TimingFunction::StepsFunction:
- case TimingFunction::ChainedFunction:
default:
ASSERT_NOT_REACHED();
return;
@@ -411,39 +353,29 @@ void addKeyframeWithTimingFunction(PlatformAnimationCurveType& curve, const Plat
} // namespace anoymous
-void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& curve, const KeyframeVector& keyframes, const TimingFunction& timingFunction)
+void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& curve, const PropertySpecificKeyframeVector& keyframes, bool reverse)
{
for (size_t i = 0; i < keyframes.size(); i++) {
+ RefPtr<TimingFunction> reversedTimingFunction;
const TimingFunction* keyframeTimingFunction = 0;
- if (i + 1 < keyframes.size()) { // Last keyframe has no timing function
- switch (timingFunction.type()) {
- case TimingFunction::LinearFunction:
- case TimingFunction::CubicBezierFunction:
- keyframeTimingFunction = &timingFunction;
- break;
-
- case TimingFunction::ChainedFunction: {
- const ChainedTimingFunction& chained = toChainedTimingFunction(timingFunction);
- // ChainedTimingFunction criteria was checked in isCandidate,
- // assert it is valid.
- ASSERT(keyframes.size() == chained.m_segments.size() + 1);
-
- keyframeTimingFunction = chained.m_segments[i].m_timingFunction.get();
- break;
- }
- case TimingFunction::StepsFunction:
- default:
- ASSERT_NOT_REACHED();
+ if (i < keyframes.size() - 1) { // Ignore timing function of last frame.
+ if (reverse) {
+ reversedTimingFunction = CompositorAnimationsTimingFunctionReverser::reverse(keyframes[i + 1]->easing());
+ keyframeTimingFunction = reversedTimingFunction.get();
+ } else {
+ keyframeTimingFunction = keyframes[i]->easing();
}
}
- ASSERT(!keyframes[i]->value()->dependsOnUnderlyingValue());
- RefPtr<AnimatableValue> value = keyframes[i]->value()->compositeOnto(0);
+ // FIXME: This relies on StringKeyframes being eagerly evaluated, which will
+ // not happen eventually. Instead we should extract the CSSValue here
+ // and convert using another set of toAnimatableXXXOperations functions.
+ const AnimatableValue* value = keyframes[i]->getAnimatableValue().get();
switch (curve.type()) {
case blink::WebAnimationCurve::AnimationCurveTypeFilter: {
OwnPtr<blink::WebFilterOperations> ops = adoptPtr(blink::Platform::current()->compositorSupport()->createFilterOperations());
- bool converted = toWebFilterOperations(toAnimatableFilterOperations(value.get())->operations(), ops.get());
+ bool converted = toWebFilterOperations(toAnimatableFilterOperations(value)->operations(), ops.get());
ASSERT_UNUSED(converted, converted);
blink::WebFilterKeyframe filterKeyframe(keyframes[i]->offset(), ops.release());
@@ -452,14 +384,14 @@ void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& cur
break;
}
case blink::WebAnimationCurve::AnimationCurveTypeFloat: {
- blink::WebFloatKeyframe floatKeyframe(keyframes[i]->offset(), toAnimatableDouble(value.get())->toDouble());
+ blink::WebFloatKeyframe floatKeyframe(keyframes[i]->offset(), toAnimatableDouble(value)->toDouble());
blink::WebFloatAnimationCurve* floatCurve = static_cast<blink::WebFloatAnimationCurve*>(&curve);
addKeyframeWithTimingFunction(*floatCurve, floatKeyframe, keyframeTimingFunction);
break;
}
case blink::WebAnimationCurve::AnimationCurveTypeTransform: {
OwnPtr<blink::WebTransformOperations> ops = adoptPtr(blink::Platform::current()->compositorSupport()->createTransformOperations());
- toWebTransformOperations(toAnimatableTransform(value.get())->transformOperations(), FloatSize(), ops.get());
+ toWebTransformOperations(toAnimatableTransform(value)->transformOperations(), ops.get());
blink::WebTransformKeyframe transformKeyframe(keyframes[i]->offset(), ops.release());
blink::WebTransformAnimationCurve* transformCurve = static_cast<blink::WebTransformAnimationCurve*>(&curve);
@@ -472,23 +404,18 @@ void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& cur
}
}
-void CompositorAnimationsImpl::getAnimationOnCompositor(
- const Timing& timing, const KeyframeAnimationEffect& effect, Vector<OwnPtr<blink::WebAnimation> >& animations)
+void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, double startTime, const KeyframeEffectModelBase& effect, Vector<OwnPtr<blink::WebAnimation> >& animations)
{
ASSERT(animations.isEmpty());
CompositorTiming compositorTiming;
bool timingValid = convertTimingForCompositor(timing, compositorTiming);
ASSERT_UNUSED(timingValid, timingValid);
- RefPtr<TimingFunction> timingFunction = timing.timingFunction;
- if (compositorTiming.reverse)
- timingFunction = CompositorAnimationsTimingFunctionReverser::reverse(timingFunction.get());
-
PropertySet properties = effect.properties();
ASSERT(!properties.isEmpty());
for (PropertySet::iterator it = properties.begin(); it != properties.end(); ++it) {
- KeyframeVector values;
+ PropertySpecificKeyframeVector values;
getKeyframeValuesForProperty(&effect, *it, compositorTiming.scaledDuration, compositorTiming.reverse, values);
blink::WebAnimation::TargetProperty targetProperty;
@@ -498,21 +425,21 @@ void CompositorAnimationsImpl::getAnimationOnCompositor(
targetProperty = blink::WebAnimation::TargetPropertyOpacity;
blink::WebFloatAnimationCurve* floatCurve = blink::Platform::current()->compositorSupport()->createFloatAnimationCurve();
- addKeyframesToCurve(*floatCurve, values, *timingFunction.get());
+ addKeyframesToCurve(*floatCurve, values, compositorTiming.reverse);
curve = adoptPtr(floatCurve);
break;
}
case CSSPropertyWebkitFilter: {
targetProperty = blink::WebAnimation::TargetPropertyFilter;
blink::WebFilterAnimationCurve* filterCurve = blink::Platform::current()->compositorSupport()->createFilterAnimationCurve();
- addKeyframesToCurve(*filterCurve, values, *timingFunction);
+ addKeyframesToCurve(*filterCurve, values, compositorTiming.reverse);
curve = adoptPtr(filterCurve);
break;
}
- case CSSPropertyWebkitTransform: {
+ case CSSPropertyTransform: {
targetProperty = blink::WebAnimation::TargetPropertyTransform;
blink::WebTransformAnimationCurve* transformCurve = blink::Platform::current()->compositorSupport()->createTransformAnimationCurve();
- addKeyframesToCurve(*transformCurve, values, *timingFunction.get());
+ addKeyframesToCurve(*transformCurve, values, compositorTiming.reverse);
curve = adoptPtr(transformCurve);
break;
}
@@ -524,6 +451,9 @@ void CompositorAnimationsImpl::getAnimationOnCompositor(
OwnPtr<blink::WebAnimation> animation = adoptPtr(blink::Platform::current()->compositorSupport()->createAnimation(*curve, targetProperty));
+ if (!std::isnan(startTime))
+ animation->setStartTime(startTime);
+
animation->setIterations(compositorTiming.adjustedIterationCount);
animation->setTimeOffset(compositorTiming.scaledTimeOffset);
animation->setAlternatesDirection(compositorTiming.alternate);
diff --git a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.h b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.h
index 9a529731fa0..da2cf497de2 100644
--- a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.h
+++ b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimations.h
@@ -33,7 +33,7 @@
#include "core/animation/AnimationEffect.h"
#include "core/animation/Timing.h"
-#include "core/platform/animation/TimingFunction.h"
+#include "platform/animation/TimingFunction.h"
#include "wtf/Vector.h"
namespace WebCore {
@@ -49,7 +49,6 @@ class CompositorAnimationsTimingFunctionReverser {
public:
static PassRefPtr<TimingFunction> reverse(const LinearTimingFunction* timefunc);
static PassRefPtr<TimingFunction> reverse(const CubicBezierTimingFunction* timefunc);
- static PassRefPtr<TimingFunction> reverse(const ChainedTimingFunction* timefunc);
static PassRefPtr<TimingFunction> reverse(const TimingFunction* timefunc);
};
@@ -61,7 +60,7 @@ public:
virtual bool isCandidateForAnimationOnCompositor(const Timing&, const AnimationEffect&);
virtual bool canStartAnimationOnCompositor(const Element&);
// FIXME: This should return void. We should know ahead of time whether these animations can be started.
- virtual bool startAnimationOnCompositor(const Element&, const Timing&, const AnimationEffect&, Vector<int>& startedAnimationIds);
+ virtual bool startAnimationOnCompositor(const Element&, double startTime, const Timing&, const AnimationEffect&, Vector<int>& startedAnimationIds);
virtual void cancelAnimationOnCompositor(const Element&, int id);
virtual void pauseAnimationForTestingOnCompositor(const Element&, int id, double pauseTime);
diff --git a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsImpl.h b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsImpl.h
index 7c32705f23b..d2f06f5b81c 100644
--- a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsImpl.h
+++ b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsImpl.h
@@ -29,15 +29,13 @@
*/
#include "core/animation/AnimationEffect.h"
-#include "core/animation/KeyframeAnimationEffect.h"
+#include "core/animation/KeyframeEffectModel.h"
#include "core/animation/Timing.h"
-#include "core/platform/animation/TimingFunction.h"
+#include "platform/animation/TimingFunction.h"
#include "public/platform/WebAnimation.h"
namespace WebCore {
-typedef KeyframeAnimationEffect::PropertySpecificKeyframeVector KeyframeVector;
-
class CompositorAnimationsImpl {
private:
struct CompositorTiming {
@@ -50,9 +48,9 @@ private:
static bool convertTimingForCompositor(const Timing&, CompositorTiming& out);
- static void getAnimationOnCompositor(const Timing&, const KeyframeAnimationEffect&, Vector<OwnPtr<blink::WebAnimation> >& animations);
+ static void getAnimationOnCompositor(const Timing&, double startTime, const KeyframeEffectModelBase&, Vector<OwnPtr<blink::WebAnimation> >& animations);
- static void addKeyframesToCurve(blink::WebAnimationCurve&, const KeyframeVector&, const TimingFunction&);
+ static void addKeyframesToCurve(blink::WebAnimationCurve&, const AnimatableValuePropertySpecificKeyframeVector&, bool reverse);
friend class CompositorAnimations;
friend class AnimationCompositorAnimationsTest;
diff --git a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
index db0d9a6c4bd..ad88c352261 100644
--- a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
@@ -38,7 +38,6 @@
#include "core/animation/AnimatableValueTestHelper.h"
#include "core/animation/CompositorAnimationsImpl.h"
#include "core/animation/CompositorAnimationsTestHelper.h"
-#include "core/platform/animation/TimingFunctionTestHelper.h"
#include "platform/geometry/IntSize.h"
#include "platform/graphics/filters/FilterOperations.h"
#include "platform/transforms/TransformOperations.h"
@@ -62,7 +61,6 @@ using ::testing::Return;
using ::testing::_;
class AnimationCompositorAnimationsTest : public AnimationCompositorAnimationsTestBase {
-
protected:
RefPtr<TimingFunction> m_linearTimingFunction;
RefPtr<TimingFunction> m_cubicEaseTimingFunction;
@@ -71,19 +69,19 @@ protected:
Timing m_timing;
CompositorAnimationsImpl::CompositorTiming m_compositorTiming;
- KeyframeAnimationEffect::KeyframeVector m_keyframeVector2;
- RefPtr<KeyframeAnimationEffect> m_keyframeAnimationEffect2;
- KeyframeAnimationEffect::KeyframeVector m_keyframeVector5;
- RefPtr<KeyframeAnimationEffect> m_keyframeAnimationEffect5;
+ OwnPtrWillBePersistent<AnimatableValueKeyframeVector> m_keyframeVector2;
+ RefPtrWillBePersistent<AnimatableValueKeyframeEffectModel> m_keyframeAnimationEffect2;
+ OwnPtrWillBePersistent<AnimatableValueKeyframeVector> m_keyframeVector5;
+ RefPtrWillBePersistent<AnimatableValueKeyframeEffectModel> m_keyframeAnimationEffect5;
virtual void SetUp()
{
AnimationCompositorAnimationsTestBase::SetUp();
- m_linearTimingFunction = LinearTimingFunction::create();
+ m_linearTimingFunction = LinearTimingFunction::shared();
m_cubicEaseTimingFunction = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
m_cubicCustomTimingFunction = CubicBezierTimingFunction::create(1, 2, 3, 4);
- m_stepTimingFunction = StepsTimingFunction::create(1, false);
+ m_stepTimingFunction = StepsTimingFunction::create(1, StepsTimingFunction::StepAtEnd);
m_timing = createCompositableTiming();
m_compositorTiming = CompositorAnimationsImpl::CompositorTiming();
@@ -92,10 +90,10 @@ protected:
ASSERT(convertTimingForCompositor(m_timing, m_compositorTiming));
m_keyframeVector2 = createCompositableFloatKeyframeVector(2);
- m_keyframeAnimationEffect2 = KeyframeAnimationEffect::create(m_keyframeVector2);
+ m_keyframeAnimationEffect2 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector2);
m_keyframeVector5 = createCompositableFloatKeyframeVector(5);
- m_keyframeAnimationEffect5 = KeyframeAnimationEffect::create(m_keyframeVector5);
+ m_keyframeAnimationEffect5 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector5);
}
public:
@@ -108,19 +106,20 @@ public:
{
return CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(timing, effect);
}
- void getAnimationOnCompositor(Timing& timing, KeyframeAnimationEffect& effect, Vector<OwnPtr<blink::WebAnimation> >& animations)
+ void getAnimationOnCompositor(Timing& timing, AnimatableValueKeyframeEffectModel& effect, Vector<OwnPtr<blink::WebAnimation> >& animations)
{
- return CompositorAnimationsImpl::getAnimationOnCompositor(timing, effect, animations);
+ return CompositorAnimationsImpl::getAnimationOnCompositor(timing, std::numeric_limits<double>::quiet_NaN(), effect, animations);
}
- bool isCandidateHelperForSingleKeyframe(Keyframe* frame)
+ bool duplicateSingleKeyframeAndTestIsCandidateOnResult(AnimatableValueKeyframe* frame)
{
EXPECT_EQ(frame->offset(), 0);
- KeyframeAnimationEffect::KeyframeVector frames;
+ AnimatableValueKeyframeVector frames;
+ RefPtrWillBeRawPtr<Keyframe> second = frame->cloneWithOffset(1);
+
frames.append(frame);
- EXPECT_EQ(m_keyframeVector2[1]->offset(), 1.0);
- frames.append(m_keyframeVector2[1]);
- return isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(frames).get());
+ frames.append(toAnimatableValueKeyframe(second.get()));
+ return isCandidateForAnimationOnCompositor(m_timing, *AnimatableValueKeyframeEffectModel::create(frames).get());
}
// -------------------------------------------------------------------
@@ -132,7 +131,6 @@ public:
timing.fillMode = Timing::FillModeNone;
timing.iterationStart = 0;
timing.iterationCount = 1;
- timing.hasIterationDuration = true;
timing.iterationDuration = 1.0;
timing.playbackRate = 1.0;
timing.direction = Timing::PlaybackDirectionNormal;
@@ -141,29 +139,30 @@ public:
return timing;
}
- PassRefPtr<Keyframe> createReplaceOpKeyframe(CSSPropertyID id, AnimatableValue* value, double offset = 0)
+ PassRefPtrWillBeRawPtr<AnimatableValueKeyframe> createReplaceOpKeyframe(CSSPropertyID id, AnimatableValue* value, double offset = 0)
{
- RefPtr<Keyframe> keyframe = Keyframe::create();
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> keyframe = AnimatableValueKeyframe::create();
keyframe->setPropertyValue(id, value);
keyframe->setComposite(AnimationEffect::CompositeReplace);
keyframe->setOffset(offset);
+ keyframe->setEasing(LinearTimingFunction::shared());
return keyframe;
}
- PassRefPtr<Keyframe> createDefaultKeyframe(CSSPropertyID id, AnimationEffect::CompositeOperation op, double offset = 0)
+ PassRefPtrWillBeRawPtr<AnimatableValueKeyframe> createDefaultKeyframe(CSSPropertyID id, AnimationEffect::CompositeOperation op, double offset = 0)
{
- RefPtr<AnimatableValue> value;
- if (id == CSSPropertyWebkitTransform)
+ RefPtrWillBeRawPtr<AnimatableValue> value = nullptr;
+ if (id == CSSPropertyTransform)
value = AnimatableTransform::create(TransformOperations());
else
value = AnimatableDouble::create(10.0);
- RefPtr<Keyframe> keyframe = createReplaceOpKeyframe(id, value.get(), offset);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> keyframe = createReplaceOpKeyframe(id, value.get(), offset);
keyframe->setComposite(op);
return keyframe;
}
- KeyframeAnimationEffect::KeyframeVector createCompositableFloatKeyframeVector(size_t n)
+ PassOwnPtrWillBeRawPtr<AnimatableValueKeyframeVector> createCompositableFloatKeyframeVector(size_t n)
{
Vector<double> values;
for (size_t i = 0; i < n; i++) {
@@ -172,26 +171,26 @@ public:
return createCompositableFloatKeyframeVector(values);
}
- KeyframeAnimationEffect::KeyframeVector createCompositableFloatKeyframeVector(Vector<double>& values)
+ PassOwnPtrWillBeRawPtr<AnimatableValueKeyframeVector> createCompositableFloatKeyframeVector(Vector<double>& values)
{
- KeyframeAnimationEffect::KeyframeVector frames;
+ OwnPtrWillBeRawPtr<AnimatableValueKeyframeVector> frames = adoptPtrWillBeNoop(new AnimatableValueKeyframeVector);
for (size_t i = 0; i < values.size(); i++) {
double offset = 1.0 / (values.size() - 1) * i;
- RefPtr<AnimatableDouble> value = AnimatableDouble::create(values[i]);
- frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, value.get(), offset).get());
+ RefPtrWillBeRawPtr<AnimatableDouble> value = AnimatableDouble::create(values[i]);
+ frames->append(createReplaceOpKeyframe(CSSPropertyOpacity, value.get(), offset).get());
}
- return frames;
+ return frames.release();
}
- PassRefPtr<KeyframeAnimationEffect> createKeyframeAnimationEffect(PassRefPtr<Keyframe> prpFrom, PassRefPtr<Keyframe> prpTo, PassRefPtr<Keyframe> prpC = 0, PassRefPtr<Keyframe> prpD = 0)
+ PassRefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> createKeyframeEffectModel(PassRefPtrWillBeRawPtr<AnimatableValueKeyframe> prpFrom, PassRefPtrWillBeRawPtr<AnimatableValueKeyframe> prpTo, PassRefPtrWillBeRawPtr<AnimatableValueKeyframe> prpC = nullptr, PassRefPtrWillBeRawPtr<AnimatableValueKeyframe> prpD = nullptr)
{
- RefPtr<Keyframe> from = prpFrom;
- RefPtr<Keyframe> to = prpTo;
- RefPtr<Keyframe> c = prpC;
- RefPtr<Keyframe> d = prpD;
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> from = prpFrom;
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> to = prpTo;
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> c = prpC;
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> d = prpD;
EXPECT_EQ(from->offset(), 0);
- KeyframeAnimationEffect::KeyframeVector frames;
+ AnimatableValueKeyframeVector frames;
frames.append(from);
EXPECT_LE(from->offset(), to->offset());
frames.append(to);
@@ -207,31 +206,11 @@ public:
EXPECT_EQ(to->offset(), 1.0);
}
if (!HasFatalFailure()) {
- return KeyframeAnimationEffect::create(frames);
+ return AnimatableValueKeyframeEffectModel::create(frames);
}
- return PassRefPtr<KeyframeAnimationEffect>();
- }
-
-};
-
-class CustomFilterOperationMock : public FilterOperation {
-public:
- virtual bool operator==(const FilterOperation&) const OVERRIDE FINAL {
- ASSERT_NOT_REACHED();
- return false;
- }
-
- MOCK_CONST_METHOD2(blend, PassRefPtr<FilterOperation>(const FilterOperation*, double));
-
- static PassRefPtr<CustomFilterOperationMock> create()
- {
- return adoptRef(new CustomFilterOperationMock());
+ return nullptr;
}
- CustomFilterOperationMock()
- : FilterOperation(FilterOperation::CUSTOM)
- {
- }
};
// -----------------------------------------------------------------------
@@ -239,88 +218,57 @@ public:
TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeMultipleCSSProperties)
{
- RefPtr<Keyframe> keyframeGoodMultiple = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace);
- keyframeGoodMultiple->setPropertyValue(CSSPropertyWebkitTransform, AnimatableTransform::create(TransformOperations()).get());
- EXPECT_TRUE(isCandidateHelperForSingleKeyframe(keyframeGoodMultiple.get()));
-
- RefPtr<Keyframe> keyframeBadMultipleOp = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeAdd);
- keyframeBadMultipleOp->setPropertyValue(CSSPropertyWebkitTransform, AnimatableDouble::create(10.0).get());
- EXPECT_FALSE(isCandidateHelperForSingleKeyframe(keyframeBadMultipleOp.get()));
-
- // Check both an unsupported property which hashes before and after the
- // supported property.
- typedef DefaultHash<CSSPropertyID>::Hash HashFunctions;
-
- RefPtr<Keyframe> keyframeBadMultiple1ID = createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace);
- keyframeBadMultiple1ID->setPropertyValue(CSSPropertyOpacity, AnimatableDouble::create(10.0).get());
- EXPECT_FALSE(isCandidateHelperForSingleKeyframe(keyframeBadMultiple1ID.get()));
- EXPECT_LT(HashFunctions::hash(CSSPropertyColor), HashFunctions::hash(CSSPropertyOpacity));
-
- RefPtr<Keyframe> keyframeBadMultiple2ID = createDefaultKeyframe(CSSPropertyWebkitTransform, AnimationEffect::CompositeReplace);
- keyframeBadMultiple2ID->setPropertyValue(CSSPropertyWidth, AnimatableDouble::create(10.0).get());
- EXPECT_FALSE(isCandidateHelperForSingleKeyframe(keyframeBadMultiple2ID.get()));
- EXPECT_GT(HashFunctions::hash(CSSPropertyWebkitTransform), HashFunctions::hash(CSSPropertyWidth));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> keyframeGoodMultiple = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace);
+ keyframeGoodMultiple->setPropertyValue(CSSPropertyTransform, AnimatableTransform::create(TransformOperations()).get());
+ EXPECT_TRUE(duplicateSingleKeyframeAndTestIsCandidateOnResult(keyframeGoodMultiple.get()));
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> keyframeBadMultipleID = createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace);
+ keyframeBadMultipleID->setPropertyValue(CSSPropertyOpacity, AnimatableDouble::create(10.0).get());
+ EXPECT_FALSE(duplicateSingleKeyframeAndTestIsCandidateOnResult(keyframeBadMultipleID.get()));
}
TEST_F(AnimationCompositorAnimationsTest, isNotCandidateForCompositorAnimationTransformDependsOnBoxSize)
{
TransformOperations ops;
ops.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(2, WebCore::Fixed), TransformOperation::TranslateX));
- RefPtr<Keyframe> goodKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops).get());
- EXPECT_TRUE(isCandidateHelperForSingleKeyframe(goodKeyframe.get()));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> goodKeyframe = createReplaceOpKeyframe(CSSPropertyTransform, AnimatableTransform::create(ops).get());
+ EXPECT_TRUE(duplicateSingleKeyframeAndTestIsCandidateOnResult(goodKeyframe.get()));
ops.operations().append(TranslateTransformOperation::create(Length(50, WebCore::Percent), Length(2, WebCore::Fixed), TransformOperation::TranslateX));
- RefPtr<Keyframe> badKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops).get());
- EXPECT_FALSE(isCandidateHelperForSingleKeyframe(badKeyframe.get()));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> badKeyframe = createReplaceOpKeyframe(CSSPropertyTransform, AnimatableTransform::create(ops).get());
+ EXPECT_FALSE(duplicateSingleKeyframeAndTestIsCandidateOnResult(badKeyframe.get()));
TransformOperations ops2;
Length calcLength = Length(100, WebCore::Percent).blend(Length(100, WebCore::Fixed), 0.5, WebCore::ValueRangeAll);
ops2.operations().append(TranslateTransformOperation::create(calcLength, Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- RefPtr<Keyframe> badKeyframe2 = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops2).get());
- EXPECT_FALSE(isCandidateHelperForSingleKeyframe(badKeyframe2.get()));
-}
-
-TEST_F(AnimationCompositorAnimationsTest, isNotCandidateForCompositorAnimationCustomFilter)
-{
- FilterOperations ops;
- ops.operations().append(BasicColorMatrixFilterOperation::create(0.5, FilterOperation::SATURATE));
- RefPtr<Keyframe> goodKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitFilter, AnimatableFilterOperations::create(ops).get());
- EXPECT_TRUE(isCandidateHelperForSingleKeyframe(goodKeyframe.get()));
-
- ops.operations().append(CustomFilterOperationMock::create());
- RefPtr<Keyframe> badKeyframe = createReplaceOpKeyframe(CSSPropertyFilter, AnimatableFilterOperations::create(ops).get());
- EXPECT_FALSE(isCandidateHelperForSingleKeyframe(badKeyframe.get()));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> badKeyframe2 = createReplaceOpKeyframe(CSSPropertyTransform, AnimatableTransform::create(ops2).get());
+ EXPECT_FALSE(duplicateSingleKeyframeAndTestIsCandidateOnResult(badKeyframe2.get()));
}
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeEffectMultipleFramesOkay)
+TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeEffectModelMultipleFramesOkay)
{
- KeyframeAnimationEffect::KeyframeVector framesSame;
+ AnimatableValueKeyframeVector framesSame;
framesSame.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get());
framesSame.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 1.0).get());
- EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesSame).get()));
+ EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *AnimatableValueKeyframeEffectModel::create(framesSame).get()));
- KeyframeAnimationEffect::KeyframeVector framesMixed;
+ AnimatableValueKeyframeVector framesMixed;
framesMixed.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get());
- framesMixed.append(createDefaultKeyframe(CSSPropertyWebkitTransform, AnimationEffect::CompositeReplace, 1.0).get());
- EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesMixed).get()));
+ framesMixed.append(createDefaultKeyframe(CSSPropertyTransform, AnimationEffect::CompositeReplace, 1.0).get());
+ EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *AnimatableValueKeyframeEffectModel::create(framesMixed).get()));
}
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeEffectMultipleFramesNotOkay)
+TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeEffectModel)
{
- KeyframeAnimationEffect::KeyframeVector framesSame;
+ AnimatableValueKeyframeVector framesSame;
framesSame.append(createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace, 0.0).get());
framesSame.append(createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace, 1.0).get());
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesSame).get()));
+ EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *AnimatableValueKeyframeEffectModel::create(framesSame).get()));
- KeyframeAnimationEffect::KeyframeVector framesMixedProperties;
+ AnimatableValueKeyframeVector framesMixedProperties;
framesMixedProperties.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get());
framesMixedProperties.append(createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace, 1.0).get());
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesMixedProperties).get()));
-
- KeyframeAnimationEffect::KeyframeVector framesMixedOps;
- framesMixedOps.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get());
- framesMixedOps.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeAdd, 1.0).get());
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesMixedOps).get()));
+ EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *AnimatableValueKeyframeEffectModel::create(framesMixedProperties).get()));
}
TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorStartDelay)
@@ -477,13 +425,12 @@ TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTim
TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionCubic)
{
- // Cubic bezier are okay if we only have two keyframes
m_timing.timingFunction = m_cubicEaseTimingFunction;
- EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
+ EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
m_timing.timingFunction = m_cubicCustomTimingFunction;
- EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
+ EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
}
@@ -494,191 +441,65 @@ TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTim
EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
}
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedEmpty)
-{
- RefPtr<ChainedTimingFunction> chainedEmpty = ChainedTimingFunction::create();
- m_timing.timingFunction = chainedEmpty;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedLinear)
{
- RefPtr<ChainedTimingFunction> chainedLinearSingle = ChainedTimingFunction::create();
- chainedLinearSingle->appendSegment(1.0, m_linearTimingFunction.get());
- m_timing.timingFunction = chainedLinearSingle;
EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
-
- RefPtr<ChainedTimingFunction> chainedLinearMultiple = ChainedTimingFunction::create();
- chainedLinearMultiple->appendSegment(0.25, m_linearTimingFunction.get());
- chainedLinearMultiple->appendSegment(0.5, m_linearTimingFunction.get());
- chainedLinearMultiple->appendSegment(0.75, m_linearTimingFunction.get());
- chainedLinearMultiple->appendSegment(1.0, m_linearTimingFunction.get());
- m_timing.timingFunction = chainedLinearMultiple;
EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
- // FIXME: Technically a chained timing function of linear functions don't
- // have to be aligned to keyframes. We don't support that currently as
- // nothing generates that yet.
}
TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedCubicMatchingOffsets)
{
- RefPtr<ChainedTimingFunction> chainedSingleAGood = ChainedTimingFunction::create();
- chainedSingleAGood->appendSegment(1.0, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chainedSingleAGood;
+ (*m_keyframeVector2)[0]->setEasing(m_cubicEaseTimingFunction.get());
+ m_keyframeAnimationEffect2 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector2);
EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
- RefPtr<ChainedTimingFunction> chainedSingleBGood = ChainedTimingFunction::create();
- chainedSingleBGood->appendSegment(1.0, m_cubicCustomTimingFunction.get());
- m_timing.timingFunction = chainedSingleBGood;
+ (*m_keyframeVector2)[0]->setEasing(m_cubicCustomTimingFunction.get());
+ m_keyframeAnimationEffect2 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector2);
EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
- RefPtr<ChainedTimingFunction> chainedMultipleGood = ChainedTimingFunction::create();
- chainedMultipleGood->appendSegment(0.25, m_cubicEaseTimingFunction.get());
- chainedMultipleGood->appendSegment(0.5, m_cubicCustomTimingFunction.get());
- chainedMultipleGood->appendSegment(0.75, m_cubicCustomTimingFunction.get());
- chainedMultipleGood->appendSegment(1.0, m_cubicCustomTimingFunction.get());
- m_timing.timingFunction = chainedMultipleGood;
+ (*m_keyframeVector5)[0]->setEasing(m_cubicEaseTimingFunction.get());
+ (*m_keyframeVector5)[1]->setEasing(m_cubicCustomTimingFunction.get());
+ (*m_keyframeVector5)[2]->setEasing(m_cubicCustomTimingFunction.get());
+ (*m_keyframeVector5)[3]->setEasing(m_cubicCustomTimingFunction.get());
+ m_keyframeAnimationEffect5 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector5);
EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
}
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedCubicNonMatchingOffsets)
-{
- RefPtr<ChainedTimingFunction> chained0 = ChainedTimingFunction::create();
- chained0->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained0;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
-
- RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create();
- chained1->appendSegment(0.24, m_cubicEaseTimingFunction.get());
- chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- chained1->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- chained1->appendSegment(1.0, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained1;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
- RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create();
- chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(0.51, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained2;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
- RefPtr<ChainedTimingFunction> chained3 = ChainedTimingFunction::create();
- chained3->appendSegment(0.25, m_cubicEaseTimingFunction.get());
- chained3->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- chained3->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- chained3->appendSegment(0.8, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained3;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
- RefPtr<ChainedTimingFunction> chained4 = ChainedTimingFunction::create();
- chained4->appendSegment(0.25, m_cubicEaseTimingFunction.get());
- chained4->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- chained4->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- chained4->appendSegment(1.1, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained4;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionMissingFrames)
-{
- // Missing first
- RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create();
- chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- chained1->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- chained1->appendSegment(1.0, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained1;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
- // Missing middle
- RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create();
- chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained2;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
- // Missing last
- RefPtr<ChainedTimingFunction> chained3 = ChainedTimingFunction::create();
- chained3->appendSegment(0.25, m_cubicEaseTimingFunction.get());
- chained3->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- chained3->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained3;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionToManyFrames)
-{
- RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create();
- chained1->appendSegment(0.1, m_cubicEaseTimingFunction.get());
- chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained1;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
-
- RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create();
- chained2->appendSegment(0.1, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chained2;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionMixedGood)
{
- RefPtr<ChainedTimingFunction> chainedMixed = ChainedTimingFunction::create();
- chainedMixed->appendSegment(0.25, m_linearTimingFunction.get());
- chainedMixed->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- chainedMixed->appendSegment(0.75, m_cubicEaseTimingFunction.get());
- chainedMixed->appendSegment(1.0, m_linearTimingFunction.get());
- m_timing.timingFunction = chainedMixed;
+ (*m_keyframeVector5)[0]->setEasing(m_linearTimingFunction.get());
+ (*m_keyframeVector5)[1]->setEasing(m_cubicEaseTimingFunction.get());
+ (*m_keyframeVector5)[2]->setEasing(m_cubicEaseTimingFunction.get());
+ (*m_keyframeVector5)[3]->setEasing(m_linearTimingFunction.get());
+ m_keyframeAnimationEffect5 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector5);
EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
}
TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionWithStepNotOkay)
{
- RefPtr<ChainedTimingFunction> chainedStepSingle = ChainedTimingFunction::create();
- chainedStepSingle->appendSegment(1.0, m_stepTimingFunction.get());
- m_timing.timingFunction = chainedStepSingle;
+ (*m_keyframeVector2)[0]->setEasing(m_stepTimingFunction.get());
+ m_keyframeAnimationEffect2 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector2);
EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
- RefPtr<ChainedTimingFunction> chainedStepMixedA = ChainedTimingFunction::create();
- chainedStepMixedA->appendSegment(0.25, m_stepTimingFunction.get());
- chainedStepMixedA->appendSegment(0.5, m_linearTimingFunction.get());
- chainedStepMixedA->appendSegment(1.0, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chainedStepMixedA;
+ (*m_keyframeVector5)[0]->setEasing(m_stepTimingFunction.get());
+ (*m_keyframeVector5)[1]->setEasing(m_linearTimingFunction.get());
+ (*m_keyframeVector5)[2]->setEasing(m_cubicEaseTimingFunction.get());
+ (*m_keyframeVector5)[3]->setEasing(m_linearTimingFunction.get());
+ m_keyframeAnimationEffect5 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector5);
EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
- RefPtr<ChainedTimingFunction> chainedStepMixedB = ChainedTimingFunction::create();
- chainedStepMixedB->appendSegment(0.25, m_linearTimingFunction.get());
- chainedStepMixedB->appendSegment(0.5, m_stepTimingFunction.get());
- chainedStepMixedB->appendSegment(1.0, m_cubicEaseTimingFunction.get());
- m_timing.timingFunction = chainedStepMixedB;
+ (*m_keyframeVector5)[0]->setEasing(m_linearTimingFunction.get());
+ (*m_keyframeVector5)[1]->setEasing(m_stepTimingFunction.get());
+ (*m_keyframeVector5)[2]->setEasing(m_cubicEaseTimingFunction.get());
+ (*m_keyframeVector5)[3]->setEasing(m_linearTimingFunction.get());
+ m_keyframeAnimationEffect5 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector5);
EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
- RefPtr<ChainedTimingFunction> chainedStepMixedC = ChainedTimingFunction::create();
- chainedStepMixedC->appendSegment(0.25, m_linearTimingFunction.get());
- chainedStepMixedC->appendSegment(0.5, m_cubicEaseTimingFunction.get());
- chainedStepMixedC->appendSegment(1.0, m_stepTimingFunction.get());
- m_timing.timingFunction = chainedStepMixedC;
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionNestedNotOkay)
-{
- RefPtr<ChainedTimingFunction> chainedChild = ChainedTimingFunction::create();
- chainedChild->appendSegment(1.0, m_linearTimingFunction.get());
-
- RefPtr<ChainedTimingFunction> chainedParent = ChainedTimingFunction::create();
- chainedParent->appendSegment(0.25, m_linearTimingFunction.get());
- chainedParent->appendSegment(0.5, chainedChild.get());
- chainedParent->appendSegment(0.75, m_linearTimingFunction.get());
- chainedParent->appendSegment(1.0, m_linearTimingFunction.get());
- m_timing.timingFunction = chainedParent;
+ (*m_keyframeVector5)[0]->setEasing(m_linearTimingFunction.get());
+ (*m_keyframeVector5)[1]->setEasing(m_cubicEaseTimingFunction.get());
+ (*m_keyframeVector5)[2]->setEasing(m_cubicEaseTimingFunction.get());
+ (*m_keyframeVector5)[3]->setEasing(m_stepTimingFunction.get());
+ m_keyframeAnimationEffect5 = AnimatableValueKeyframeEffectModel::create(*m_keyframeVector5);
EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
}
@@ -686,35 +507,27 @@ TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositor)
{
Timing linearTiming(createCompositableTiming());
- RefPtr<TimingFunction> cubicTimingFunc = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
- Timing cubicTiming(createCompositableTiming());
- cubicTiming.timingFunction = cubicTimingFunc;
-
- RefPtr<ChainedTimingFunction> chainedTimingFunc = ChainedTimingFunction::create();
- chainedTimingFunc->appendSegment(0.5, m_linearTimingFunction.get());
- chainedTimingFunc->appendSegment(1.0, cubicTimingFunc.get());
- Timing chainedTiming(createCompositableTiming());
- chainedTiming.timingFunction = chainedTimingFunc;
-
- KeyframeAnimationEffect::KeyframeVector basicFramesVector;
+ AnimatableValueKeyframeVector basicFramesVector;
basicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get());
basicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 1.0).get());
- RefPtr<KeyframeAnimationEffect> basicFrames = KeyframeAnimationEffect::create(basicFramesVector).get();
-
- EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames.get()));
- EXPECT_TRUE(isCandidateForAnimationOnCompositor(cubicTiming, *basicFrames.get()));
- // number of timing function and keyframes don't match
- EXPECT_FALSE(isCandidateForAnimationOnCompositor(chainedTiming, *basicFrames.get()));
- KeyframeAnimationEffect::KeyframeVector nonBasicFramesVector;
+ AnimatableValueKeyframeVector nonBasicFramesVector;
nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get());
nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.5).get());
nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 1.0).get());
- RefPtr<KeyframeAnimationEffect> nonBasicFrames = KeyframeAnimationEffect::create(nonBasicFramesVector).get();
+ basicFramesVector[0]->setEasing(m_linearTimingFunction.get());
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> basicFrames = AnimatableValueKeyframeEffectModel::create(basicFramesVector).get();
+ EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames.get()));
+
+ basicFramesVector[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+ basicFrames = AnimatableValueKeyframeEffectModel::create(basicFramesVector).get();
+ EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames.get()));
+
+ nonBasicFramesVector[0]->setEasing(m_linearTimingFunction.get());
+ nonBasicFramesVector[1]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> nonBasicFrames = AnimatableValueKeyframeEffectModel::create(nonBasicFramesVector).get();
EXPECT_TRUE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(linearTiming, *nonBasicFrames.get()));
- EXPECT_FALSE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(cubicTiming, *nonBasicFrames.get()));
- EXPECT_TRUE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(chainedTiming, *nonBasicFrames.get()));
}
// -----------------------------------------------------------------------
@@ -723,7 +536,7 @@ TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositor)
TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimation)
{
// Animation to convert
- RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect(
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = createKeyframeEffectModel(
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
// --
@@ -768,7 +581,7 @@ TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimation)
TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationDuration)
{
// Animation to convert
- RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect(
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = createKeyframeEffectModel(
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
@@ -815,7 +628,7 @@ TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationDuration)
TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimationLinear)
{
// Animation to convert
- RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect(
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = createKeyframeEffectModel(
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25),
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5),
@@ -868,7 +681,7 @@ TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimation
TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationStartDelay)
{
// Animation to convert
- RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect(
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = createKeyframeEffectModel(
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
@@ -917,18 +730,17 @@ TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationStartDelay
TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimationChained)
{
// Animation to convert
- RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect(
- createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
- createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25),
- createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5),
- createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
-
- RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create();
- chainedTimingFunction->appendSegment(0.25, m_cubicEaseTimingFunction.get());
- chainedTimingFunction->appendSegment(0.5, m_linearTimingFunction.get());
- chainedTimingFunction->appendSegment(1.0, m_cubicCustomTimingFunction.get());
-
- m_timing.timingFunction = chainedTimingFunction;
+ AnimatableValueKeyframeVector frames;
+ frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0));
+ frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25));
+ frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5));
+ frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
+ frames[0]->setEasing(m_cubicEaseTimingFunction.get());
+ frames[1]->setEasing(m_linearTimingFunction.get());
+ frames[2]->setEasing(m_cubicCustomTimingFunction.get());
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(frames);
+
+ m_timing.timingFunction = m_linearTimingFunction.get();
m_timing.iterationDuration = 2.0;
m_timing.iterationCount = 10;
m_timing.direction = Timing::PlaybackDirectionAlternate;
@@ -976,20 +788,20 @@ TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimation
TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimation)
{
- // Animation to convert
- RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect(
- createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
- createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25),
- createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5),
- createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
-
RefPtr<TimingFunction> cubicEasyFlipTimingFunction = CubicBezierTimingFunction::create(0.0, 0.0, 0.0, 1.0);
- RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create();
- chainedTimingFunction->appendSegment(0.25, CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
- chainedTimingFunction->appendSegment(0.5, m_linearTimingFunction.get());
- chainedTimingFunction->appendSegment(1.0, cubicEasyFlipTimingFunction.get());
- m_timing.timingFunction = chainedTimingFunction;
+ // Animation to convert
+ AnimatableValueKeyframeVector frames;
+ frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0));
+ frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25));
+ frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5));
+ frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
+ frames[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+ frames[1]->setEasing(m_linearTimingFunction.get());
+ frames[2]->setEasing(cubicEasyFlipTimingFunction.get());
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(frames);
+
+ m_timing.timingFunction = m_linearTimingFunction.get();
m_timing.iterationCount = 10;
m_timing.direction = Timing::PlaybackDirectionAlternateReverse;
// --
@@ -1037,7 +849,7 @@ TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimation)
TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimationNegativeStartDelay)
{
// Animation to convert
- RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect(
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = createKeyframeEffectModel(
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
diff --git a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
index 732d34662e5..bb2761f75fc 100644
--- a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
+++ b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTestHelper.h
@@ -131,7 +131,7 @@ private:
virtual void cryptographicallyRandomValues(unsigned char* buffer, size_t length) { ASSERT_NOT_REACHED(); }
private:
WebCompositorSupportMock** m_compositor;
- blink::WebCompositorSupport* compositorSupport() OVERRIDE { return *m_compositor; }
+ virtual blink::WebCompositorSupport* compositorSupport() OVERRIDE { return *m_compositor; }
};
WebCompositorSupportMock* m_mockCompositor;
diff --git a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp
index 550b7f562c2..a62173efe62 100644
--- a/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp
@@ -32,8 +32,6 @@
#include "core/animation/CompositorAnimations.h"
-#include "core/platform/animation/TimingFunctionTestHelper.h"
-
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -60,7 +58,7 @@ public:
TEST_F(AnimationCompositorAnimationsTimingFunctionReverserTest, LinearReverse)
{
- RefPtr<TimingFunction> linearTiming = LinearTimingFunction::create();
+ RefPtr<TimingFunction> linearTiming = LinearTimingFunction::shared();
EXPECT_REFV_EQ(linearTiming, reverse(linearTiming));
}
@@ -84,24 +82,4 @@ TEST_F(AnimationCompositorAnimationsTimingFunctionReverserTest, CubicReverse)
EXPECT_REFV_EQ(cubicEaseTimingReversed, reverse(cubicEaseTiming));
}
-TEST_F(AnimationCompositorAnimationsTimingFunctionReverserTest, ChainedReverse)
-{
- RefPtr<TimingFunction> linearTiming = LinearTimingFunction::create();
- RefPtr<ChainedTimingFunction> chainedLinearSingle = ChainedTimingFunction::create();
- chainedLinearSingle->appendSegment(1.0, linearTiming.get());
- EXPECT_REFV_EQ(chainedLinearSingle, reverse(chainedLinearSingle));
-
- RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
- RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
-
- RefPtr<ChainedTimingFunction> chainedMixed = ChainedTimingFunction::create();
- chainedMixed->appendSegment(0.75, chainedLinearSingle.get());
- chainedMixed->appendSegment(1.0, cubicEaseInTiming.get());
-
- RefPtr<ChainedTimingFunction> chainedMixedReversed = ChainedTimingFunction::create();
- chainedMixedReversed->appendSegment(0.25, cubicEaseOutTiming.get());
- chainedMixedReversed->appendSegment(1.0, chainedLinearSingle.get());
- EXPECT_REFV_EQ(chainedMixedReversed, reverse(chainedMixed));
-}
-
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp b/chromium/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp
new file mode 100644
index 00000000000..803e98c9953
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/CompositorPendingAnimations.h"
+
+#include "core/animation/Animation.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/frame/FrameView.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderLayer.h"
+
+namespace WebCore {
+
+void CompositorPendingAnimations::add(AnimationPlayer* player)
+{
+ Page* page = player->timeline()->document()->page();
+ bool visible = page && page->visibilityState() == PageVisibilityStateVisible;
+ if (!player->hasStartTime() && !visible)
+ player->setStartTimeInternal(player->timeline()->currentTimeInternal(), true);
+
+ m_pending.append(player);
+}
+
+bool CompositorPendingAnimations::startPendingAnimations()
+{
+ bool startedSynchronizedOnCompositor = false;
+ for (size_t i = 0; i < m_pending.size(); ++i) {
+ if (!m_pending[i]->hasActiveAnimationsOnCompositor() && m_pending[i]->maybeStartAnimationOnCompositor() && !m_pending[i]->hasStartTime())
+ startedSynchronizedOnCompositor = true;
+ }
+
+ // If any synchronized animations were started on the compositor, all
+ // remaning synchronized animations need to wait for the synchronized
+ // start time. Otherwise they may start immediately.
+ if (startedSynchronizedOnCompositor) {
+ for (size_t i = 0; i < m_pending.size(); ++i) {
+ if (!m_pending[i]->hasStartTime()) {
+ m_waitingForCompositorAnimationStart.append(m_pending[i]);
+ }
+ }
+ } else {
+ for (size_t i = 0; i < m_pending.size(); ++i) {
+ if (!m_pending[i]->hasStartTime()) {
+ m_pending[i]->setStartTimeInternal(m_pending[i]->timeline()->currentTimeInternal(), true);
+ }
+ }
+ }
+ m_pending.clear();
+
+ if (startedSynchronizedOnCompositor || m_waitingForCompositorAnimationStart.isEmpty())
+ return !m_waitingForCompositorAnimationStart.isEmpty();
+
+ // Check if we're still waiting for any compositor animations to start.
+ for (size_t i = 0; i < m_waitingForCompositorAnimationStart.size(); ++i) {
+ if (m_waitingForCompositorAnimationStart[i].get()->hasActiveAnimationsOnCompositor())
+ return true;
+ }
+
+ // If not, go ahead and start any animations that were waiting.
+ notifyCompositorAnimationStarted(monotonicallyIncreasingTime());
+ return false;
+}
+
+void CompositorPendingAnimations::notifyCompositorAnimationStarted(double monotonicAnimationStartTime)
+{
+ for (size_t i = 0; i < m_waitingForCompositorAnimationStart.size(); ++i) {
+ AnimationPlayer* player = m_waitingForCompositorAnimationStart[i].get();
+ player->setStartTimeInternal(monotonicAnimationStartTime - player->timeline()->zeroTime(), true);
+ }
+
+ m_waitingForCompositorAnimationStart.clear();
+}
+
+void CompositorPendingAnimations::trace(Visitor* visitor)
+{
+ visitor->trace(m_pending);
+ visitor->trace(m_waitingForCompositorAnimationStart);
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h b/chromium/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h
new file mode 100644
index 00000000000..179c255a917
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/CompositorPendingAnimations.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CompositorPendingAnimations_h
+#define CompositorPendingAnimations_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class AnimationPlayer;
+
+// Manages the starting of pending animations on the compositor following a
+// compositing update.
+// For CSS Animations, used to synchronize the start of main-thread animations
+// with compositor animations when both classes of CSS Animations are triggered
+// by the same recalc
+class CompositorPendingAnimations FINAL {
+ DISALLOW_ALLOCATION();
+public:
+ void add(AnimationPlayer*);
+ // Returns whether we are waiting for an animation to start and should
+ // service again on the next frame.
+ bool startPendingAnimations();
+ void notifyCompositorAnimationStarted(double monotonicAnimationStartTime);
+
+ void trace(Visitor*);
+
+private:
+ WillBeHeapVector<RefPtrWillBeMember<AnimationPlayer> > m_pending;
+ WillBeHeapVector<RefPtrWillBeMember<AnimationPlayer> > m_waitingForCompositorAnimationStart;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/DocumentAnimation.h b/chromium/third_party/WebKit/Source/core/animation/DocumentAnimation.h
new file mode 100644
index 00000000000..f1f57265ec0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/DocumentAnimation.h
@@ -0,0 +1,19 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DocumentAnimation_h
+#define DocumentAnimation_h
+
+#include "core/dom/Document.h"
+
+namespace WebCore {
+
+class DocumentAnimation {
+public:
+ static AnimationTimeline* timeline(Document& document) { return &document.timeline(); }
+};
+
+} // namespace WebCore
+
+#endif // DocumentAnimation_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/DocumentAnimation.idl b/chromium/third_party/WebKit/Source/core/animation/DocumentAnimation.idl
new file mode 100644
index 00000000000..d2c2861c8b1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/DocumentAnimation.idl
@@ -0,0 +1,9 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=WebAnimationsAPI,
+] partial interface Document {
+ readonly attribute AnimationTimeline timeline;
+};
diff --git a/chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp b/chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp
index 34ea5ca4546..df35c02d312 100644
--- a/chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.cpp
@@ -31,78 +31,66 @@
#include "config.h"
#include "core/animation/DocumentAnimations.h"
-#include "core/animation/ActiveAnimations.h"
#include "core/animation/AnimationClock.h"
-#include "core/animation/DocumentTimeline.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/Node.h"
-#include "core/frame/Frame.h"
+#include "core/dom/NodeRenderStyle.h"
#include "core/frame/FrameView.h"
-#include "core/rendering/RenderLayerCompositor.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
namespace WebCore {
namespace {
-void updateAnimationTiming(Document& document, double monotonicAnimationStartTime)
+void updateAnimationTiming(Document& document, TimingUpdateReason reason)
{
- document.animationClock().updateTime(monotonicAnimationStartTime);
- bool didTriggerStyleRecalc = document.timeline()->serviceAnimations();
- didTriggerStyleRecalc |= document.transitionTimeline()->serviceAnimations();
- if (!didTriggerStyleRecalc)
- document.animationClock().unfreeze();
+ document.timeline().serviceAnimations(reason);
}
-void dispatchAnimationEvents(Document& document)
-{
- document.timeline()->dispatchEvents();
- document.transitionTimeline()->dispatchEvents();
-}
+} // namespace
-void dispatchAnimationEventsAsync(Document& document)
+void DocumentAnimations::updateAnimationTimingForAnimationFrame(Document& document, double monotonicAnimationStartTime)
{
- document.timeline()->dispatchEventsAsync();
- document.transitionTimeline()->dispatchEventsAsync();
+ document.animationClock().updateTime(monotonicAnimationStartTime);
+ updateAnimationTiming(document, TimingUpdateForAnimationFrame);
}
-} // namespace
-
-void DocumentAnimations::serviceOnAnimationFrame(Document& document, double monotonicAnimationStartTime)
+void DocumentAnimations::updateOutdatedAnimationPlayersIfNeeded(Document& document)
{
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- return;
-
- updateAnimationTiming(document, monotonicAnimationStartTime);
- dispatchAnimationEvents(document);
+ if (needsOutdatedAnimationPlayerUpdate(document))
+ updateAnimationTiming(document, TimingUpdateOnDemand);
}
-void DocumentAnimations::serviceBeforeGetComputedStyle(Node& node, CSSPropertyID property)
+void DocumentAnimations::updateAnimationTimingForGetComputedStyle(Node& node, CSSPropertyID property)
{
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
+ if (!node.isElementNode())
return;
-
- if (node.isElementNode()) {
- const Element& element = toElement(node);
- if (const ActiveAnimations* activeAnimations = element.activeAnimations()) {
- if (activeAnimations->hasActiveAnimationsOnCompositor(property))
- updateAnimationTiming(element.document(), monotonicallyIncreasingTime());
+ const Element& element = toElement(node);
+ if (RenderStyle* style = element.renderStyle()) {
+ if ((property == CSSPropertyOpacity && style->isRunningOpacityAnimationOnCompositor())
+ || ((property == CSSPropertyTransform || property == CSSPropertyWebkitTransform) && style->isRunningTransformAnimationOnCompositor())
+ || (property == CSSPropertyWebkitFilter && style->isRunningFilterAnimationOnCompositor())) {
+ updateAnimationTiming(element.document(), TimingUpdateOnDemand);
}
}
-
}
-void DocumentAnimations::serviceAfterStyleRecalc(Document& document)
+bool DocumentAnimations::needsOutdatedAnimationPlayerUpdate(const Document& document)
{
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- return;
+ return document.timeline().hasOutdatedAnimationPlayer();
+}
- if (document.cssPendingAnimations().startPendingAnimations() && document.view())
+void DocumentAnimations::startPendingAnimations(Document& document)
+{
+ ASSERT(document.lifecycle().state() == DocumentLifecycle::CompositingClean);
+ if (document.compositorPendingAnimations().startPendingAnimations()) {
+ ASSERT(document.view());
document.view()->scheduleAnimation();
-
- document.animationClock().unfreeze();
- dispatchAnimationEventsAsync(document);
+ }
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.h b/chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.h
index b952c532ec1..f92f9942b49 100644
--- a/chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.h
+++ b/chromium/third_party/WebKit/Source/core/animation/DocumentAnimations.h
@@ -31,7 +31,7 @@
#ifndef DocumentAnimations_h
#define DocumentAnimations_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
namespace WebCore {
@@ -39,11 +39,13 @@ class Document;
class FrameView;
class Node;
-class DocumentAnimations {
+class DocumentAnimations {
public:
- static void serviceOnAnimationFrame(Document&, double monotonicAnimationStartTime);
- static void serviceBeforeGetComputedStyle(Node&, CSSPropertyID);
- static void serviceAfterStyleRecalc(Document&);
+ static void updateAnimationTimingForAnimationFrame(Document&, double monotonicAnimationStartTime);
+ static bool needsOutdatedAnimationPlayerUpdate(const Document&);
+ static void updateOutdatedAnimationPlayersIfNeeded(Document&);
+ static void updateAnimationTimingForGetComputedStyle(Node&, CSSPropertyID);
+ static void startPendingAnimations(Document&);
private:
DocumentAnimations() { }
diff --git a/chromium/third_party/WebKit/Source/core/animation/DocumentTimeline.cpp b/chromium/third_party/WebKit/Source/core/animation/DocumentTimeline.cpp
deleted file mode 100644
index 21027f8b073..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/DocumentTimeline.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/DocumentTimeline.h"
-
-#include "core/animation/ActiveAnimations.h"
-#include "core/animation/AnimationClock.h"
-#include "core/dom/Document.h"
-#include "core/frame/FrameView.h"
-
-namespace WebCore {
-
-// This value represents 1 frame at 30Hz plus a little bit of wiggle room.
-// TODO: Plumb a nominal framerate through and derive this value from that.
-const double DocumentTimeline::s_minimumDelay = 0.04;
-
-
-PassRefPtr<DocumentTimeline> DocumentTimeline::create(Document* document, PassOwnPtr<PlatformTiming> timing)
-{
- return adoptRef(new DocumentTimeline(document, timing));
-}
-
-DocumentTimeline::DocumentTimeline(Document* document, PassOwnPtr<PlatformTiming> timing)
- : m_zeroTime(nullValue())
- , m_document(document)
- , m_eventDistpachTimer(this, &DocumentTimeline::eventDispatchTimerFired)
-{
- if (!timing)
- m_timing = adoptPtr(new DocumentTimelineTiming(this));
- else
- m_timing = timing;
-
- ASSERT(document);
-}
-
-Player* DocumentTimeline::createPlayer(TimedItem* child)
-{
- RefPtr<Player> player = Player::create(*this, child);
- Player* result = player.get();
- m_players.append(player.release());
- if (m_document->view())
- m_timing->serviceOnNextFrame();
- return result;
-}
-
-Player* DocumentTimeline::play(TimedItem* child)
-{
- Player* player = createPlayer(child);
- player->setStartTime(currentTime());
- return player;
-}
-
-void DocumentTimeline::wake()
-{
- m_timing->serviceOnNextFrame();
-}
-
-bool DocumentTimeline::serviceAnimations()
-{
- TRACE_EVENT0("webkit", "DocumentTimeline::serviceAnimations");
-
- m_timing->cancelWake();
-
- double timeToNextEffect = std::numeric_limits<double>::infinity();
- bool didTriggerStyleRecalc = false;
- for (int i = m_players.size() - 1; i >= 0; --i) {
- double playerNextEffect;
- bool playerDidTriggerStyleRecalc;
- if (!m_players[i]->update(&playerNextEffect, &playerDidTriggerStyleRecalc))
- m_players.remove(i);
- didTriggerStyleRecalc |= playerDidTriggerStyleRecalc;
- if (playerNextEffect < timeToNextEffect)
- timeToNextEffect = playerNextEffect;
- }
-
- if (!m_players.isEmpty()) {
- if (timeToNextEffect < s_minimumDelay)
- m_timing->serviceOnNextFrame();
- else if (timeToNextEffect != std::numeric_limits<double>::infinity())
- m_timing->wakeAfter(timeToNextEffect - s_minimumDelay);
- }
-
- return didTriggerStyleRecalc;
-}
-
-void DocumentTimeline::setZeroTime(double zeroTime)
-{
- ASSERT(isNull(m_zeroTime));
- m_zeroTime = zeroTime;
- ASSERT(!isNull(m_zeroTime));
-}
-
-void DocumentTimeline::DocumentTimelineTiming::wakeAfter(double duration)
-{
- m_timer.startOneShot(duration);
-}
-
-void DocumentTimeline::DocumentTimelineTiming::cancelWake()
-{
- m_timer.stop();
-}
-
-void DocumentTimeline::DocumentTimelineTiming::serviceOnNextFrame()
-{
- if (m_timeline->m_document->view())
- m_timeline->m_document->view()->scheduleAnimation();
-}
-
-double DocumentTimeline::currentTime()
-{
- return m_document->animationClock().currentTime() - m_zeroTime;
-}
-
-void DocumentTimeline::pauseAnimationsForTesting(double pauseTime)
-{
- for (size_t i = 0; i < m_players.size(); i++) {
- m_players[i]->pauseForTesting();
- m_players[i]->setCurrentTime(pauseTime);
- }
-}
-
-void DocumentTimeline::dispatchEvents()
-{
- Vector<EventToDispatch> events = m_events;
- m_events.clear();
- for (size_t i = 0; i < events.size(); i++)
- events[i].target->dispatchEvent(events[i].event.release());
-}
-
-void DocumentTimeline::dispatchEventsAsync()
-{
- if (m_events.isEmpty() || m_eventDistpachTimer.isActive())
- return;
- m_eventDistpachTimer.startOneShot(0);
-}
-
-void DocumentTimeline::eventDispatchTimerFired(Timer<DocumentTimeline>*)
-{
- dispatchEvents();
-}
-
-size_t DocumentTimeline::numberOfActiveAnimationsForTesting() const
-{
- if (isNull(m_zeroTime))
- return 0;
- // Includes all players whose directly associated timed items
- // are current or in effect.
- if (isNull(m_zeroTime))
- return 0;
- size_t count = 0;
- for (size_t i = 0; i < m_players.size(); ++i) {
- const TimedItem* timedItem = m_players[i]->source();
- if (m_players[i]->hasStartTime())
- count += (timedItem && (timedItem->isCurrent() || timedItem->isInEffect()));
- }
- return count;
-}
-
-} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/DocumentTimeline.h b/chromium/third_party/WebKit/Source/core/animation/DocumentTimeline.h
deleted file mode 100644
index 2bf58f852c6..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/DocumentTimeline.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DocumentTimeline_h
-#define DocumentTimeline_h
-
-#include "core/animation/AnimationEffect.h"
-#include "core/animation/Player.h"
-#include "core/dom/Element.h"
-#include "core/events/Event.h"
-#include "platform/Timer.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class Document;
-class TimedItem;
-
-// DocumentTimeline is constructed and owned by Document, and tied to its lifecycle.
-class DocumentTimeline : public RefCounted<DocumentTimeline> {
-public:
- class PlatformTiming {
-
- public:
- // Calls DocumentTimeline's wake() method after duration seconds.
- virtual void wakeAfter(double duration) = 0;
- virtual void cancelWake() = 0;
- virtual void serviceOnNextFrame() = 0;
- virtual ~PlatformTiming() { }
-
- };
-
- static PassRefPtr<DocumentTimeline> create(Document*, PassOwnPtr<PlatformTiming> = nullptr);
- // Returns whether style recalc was triggered.
- bool serviceAnimations();
-
- // Creates a player attached to this timeline, but without a start time.
- Player* createPlayer(TimedItem*);
- Player* play(TimedItem*);
-
- // Called from setReadyState() in Document.cpp to set m_zeroTime to
- // performance.timing.domInteractive
- void setZeroTime(double);
- bool hasStarted() const { return !isNull(m_zeroTime); }
- double zeroTime() const { return m_zeroTime; }
- double currentTime();
- void pauseAnimationsForTesting(double);
- size_t numberOfActiveAnimationsForTesting() const;
- const Vector<RefPtr<Player> >& players() const { return m_players; }
-
- void addEventToDispatch(EventTarget* target, PassRefPtr<Event> event)
- {
- m_events.append(EventToDispatch(target, event));
- }
-
- void dispatchEvents();
- void dispatchEventsAsync();
-
-protected:
- DocumentTimeline(Document*, PassOwnPtr<PlatformTiming>);
-
-private:
- double m_zeroTime;
- Document* m_document;
- Timer<DocumentTimeline> m_eventDistpachTimer;
- Vector<RefPtr<Player> > m_players;
-
- void eventDispatchTimerFired(Timer<DocumentTimeline>*);
- void wake();
-
- struct EventToDispatch {
- EventToDispatch(EventTarget* target, PassRefPtr<Event> event)
- : target(target)
- , event(event)
- {
- }
- RefPtr<EventTarget> target;
- RefPtr<Event> event;
- };
- Vector<EventToDispatch> m_events;
-
- static const double s_minimumDelay;
-
- OwnPtr<PlatformTiming> m_timing;
-
- class DocumentTimelineTiming : public PlatformTiming {
- public:
- DocumentTimelineTiming(DocumentTimeline* documentTimeline)
- : m_timeline(documentTimeline)
- , m_timer(this, &DocumentTimelineTiming::timerFired)
- {
- ASSERT(m_timeline);
- }
-
- virtual void wakeAfter(double duration) OVERRIDE;
- virtual void cancelWake() OVERRIDE;
- virtual void serviceOnNextFrame() OVERRIDE;
-
- void timerFired(Timer<DocumentTimelineTiming>*) { m_timeline->wake(); }
-
- private:
- DocumentTimeline* m_timeline;
- Timer<DocumentTimelineTiming> m_timer;
-
- };
-
- friend class AnimationDocumentTimelineTest;
-};
-
-} // namespace
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/DocumentTimelineTest.cpp b/chromium/third_party/WebKit/Source/core/animation/DocumentTimelineTest.cpp
deleted file mode 100644
index 41fad8ce2c4..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/DocumentTimelineTest.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/DocumentTimeline.h"
-
-#include "core/animation/Animation.h"
-#include "core/animation/AnimationClock.h"
-#include "core/animation/KeyframeAnimationEffect.h"
-#include "core/animation/TimedItem.h"
-#include "core/dom/Document.h"
-#include "core/dom/Element.h"
-#include "core/dom/QualifiedName.h"
-#include "platform/weborigin/KURL.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-namespace WebCore {
-
-class MockPlatformTiming : public DocumentTimeline::PlatformTiming {
-public:
-
- MOCK_METHOD1(wakeAfter, void(double));
- MOCK_METHOD0(cancelWake, void());
- MOCK_METHOD0(serviceOnNextFrame, void());
-
- /**
- * DocumentTimelines should do one of the following things after servicing animations:
- * - cancel the timer and not request to be woken again (expectNoMoreActions)
- * - cancel the timer and request to be woken on the next frame (expectNextFrameAction)
- * - cancel the timer and request to be woken at some point in the future (expectDelayedAction)
- */
-
- void expectNoMoreActions()
- {
- EXPECT_CALL(*this, cancelWake());
- }
-
- void expectNextFrameAction()
- {
- ::testing::Sequence sequence;
- EXPECT_CALL(*this, cancelWake()).InSequence(sequence);
- EXPECT_CALL(*this, serviceOnNextFrame()).InSequence(sequence);
- }
-
- void expectDelayedAction(double when)
- {
- ::testing::Sequence sequence;
- EXPECT_CALL(*this, cancelWake()).InSequence(sequence);
- EXPECT_CALL(*this, wakeAfter(when)).InSequence(sequence);
- }
-};
-
-class AnimationDocumentTimelineTest : public ::testing::Test {
-protected:
- virtual void SetUp()
- {
- document = Document::create();
- document->animationClock().resetTimeForTesting();
- element = Element::create(nullQName() , document.get());
- platformTiming = new MockPlatformTiming;
- timeline = DocumentTimeline::create(document.get(), adoptPtr(platformTiming));
- timeline->setZeroTime(0);
- ASSERT_EQ(0, timeline->currentTime());
- }
-
- virtual void TearDown()
- {
- timeline.release();
- document.release();
- element.release();
- }
-
- void updateClockAndService(double time)
- {
- document->animationClock().updateTime(time);
- timeline->serviceAnimations();
- }
-
- RefPtr<Document> document;
- RefPtr<Element> element;
- RefPtr<DocumentTimeline> timeline;
- Timing timing;
- MockPlatformTiming* platformTiming;
-
- void wake()
- {
- timeline->wake();
- }
-
- double minimumDelay()
- {
- return DocumentTimeline::s_minimumDelay;
- }
-};
-
-TEST_F(AnimationDocumentTimelineTest, HasStarted)
-{
- timeline = DocumentTimeline::create(document.get());
- EXPECT_FALSE(timeline->hasStarted());
- timeline->setZeroTime(0);
- EXPECT_TRUE(timeline->hasStarted());
-}
-
-TEST_F(AnimationDocumentTimelineTest, EmptyKeyframeAnimation)
-{
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector());
- RefPtr<Animation> anim = Animation::create(element.get(), effect, timing);
-
- timeline->play(anim.get());
-
- platformTiming->expectNoMoreActions();
- updateClockAndService(0);
- EXPECT_FLOAT_EQ(0, timeline->currentTime());
- EXPECT_TRUE(anim->compositableValues()->isEmpty());
-
- platformTiming->expectNoMoreActions();
- updateClockAndService(100);
- EXPECT_FLOAT_EQ(100, timeline->currentTime());
-}
-
-TEST_F(AnimationDocumentTimelineTest, EmptyTimelineDoesNotTriggerStyleRecalc)
-{
- document->animationClock().updateTime(100);
- EXPECT_FALSE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, EmptyPlayerDoesNotTriggerStyleRecalc)
-{
- timeline->play(0);
- document->animationClock().updateTime(100);
- EXPECT_FALSE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, EmptyTargetDoesNotTriggerStyleRecalc)
-{
- timing.iterationDuration = 200;
- timeline->play(Animation::create(0, KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector()), timing).get());
- document->animationClock().updateTime(100);
- EXPECT_FALSE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, EmptyEffectDoesNotTriggerStyleRecalc)
-{
- timeline->play(Animation::create(element.get(), 0, timing).get());
- document->animationClock().updateTime(100);
- EXPECT_FALSE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, TriggerStyleRecalc)
-{
- timeline->play(Animation::create(element.get(), KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector()), timing).get());
- document->animationClock().updateTime(100);
- EXPECT_TRUE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, ZeroTime)
-{
- timeline = DocumentTimeline::create(document.get());
-
- document->animationClock().updateTime(100);
- EXPECT_TRUE(isNull(timeline->currentTime()));
-
- document->animationClock().updateTime(200);
- EXPECT_TRUE(isNull(timeline->currentTime()));
-
- timeline->setZeroTime(300);
- document->animationClock().updateTime(300);
- EXPECT_EQ(0, timeline->currentTime());
-
- document->animationClock().updateTime(400);
- EXPECT_EQ(100, timeline->currentTime());
-}
-
-TEST_F(AnimationDocumentTimelineTest, PauseForTesting)
-{
- float seekTime = 1;
- RefPtr<Animation> anim1 = Animation::create(element.get(), KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector()), timing);
- RefPtr<Animation> anim2 = Animation::create(element.get(), KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector()), timing);
- Player* player1 = timeline->play(anim1.get());
- Player* player2 = timeline->play(anim2.get());
- timeline->pauseAnimationsForTesting(seekTime);
-
- EXPECT_FLOAT_EQ(seekTime, player1->currentTime());
- EXPECT_FLOAT_EQ(seekTime, player2->currentTime());
-}
-
-TEST_F(AnimationDocumentTimelineTest, NumberOfActiveAnimations)
-{
- Timing timingForwardFill;
- timingForwardFill.hasIterationDuration = true;
- timingForwardFill.iterationDuration = 2;
-
- Timing timingNoFill;
- timingNoFill.hasIterationDuration = true;
- timingNoFill.iterationDuration = 2;
- timingNoFill.fillMode = Timing::FillModeNone;
-
- Timing timingBackwardFillDelay;
- timingBackwardFillDelay.hasIterationDuration = true;
- timingBackwardFillDelay.iterationDuration = 1;
- timingBackwardFillDelay.fillMode = Timing::FillModeBackwards;
- timingBackwardFillDelay.startDelay = 1;
-
- Timing timingNoFillDelay;
- timingNoFillDelay.hasIterationDuration = true;
- timingNoFillDelay.iterationDuration = 1;
- timingNoFillDelay.fillMode = Timing::FillModeNone;
- timingNoFillDelay.startDelay = 1;
-
- RefPtr<Animation> anim1 = Animation::create(element.get(), KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector()), timingForwardFill);
- RefPtr<Animation> anim2 = Animation::create(element.get(), KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector()), timingNoFill);
- RefPtr<Animation> anim3 = Animation::create(element.get(), KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector()), timingBackwardFillDelay);
- RefPtr<Animation> anim4 = Animation::create(element.get(), KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector()), timingNoFillDelay);
-
- timeline->play(anim1.get());
- timeline->play(anim2.get());
- timeline->play(anim3.get());
- timeline->play(anim4.get());
-
- platformTiming->expectNextFrameAction();
- updateClockAndService(0);
- EXPECT_EQ(4U, timeline->numberOfActiveAnimationsForTesting());
- platformTiming->expectNextFrameAction();
- updateClockAndService(0.5);
- EXPECT_EQ(4U, timeline->numberOfActiveAnimationsForTesting());
- platformTiming->expectNextFrameAction();
- updateClockAndService(1.5);
- EXPECT_EQ(4U, timeline->numberOfActiveAnimationsForTesting());
- platformTiming->expectNoMoreActions();
- updateClockAndService(3);
- EXPECT_EQ(1U, timeline->numberOfActiveAnimationsForTesting());
-}
-
-TEST_F(AnimationDocumentTimelineTest, DelayBeforeAnimationStart)
-{
- timing.hasIterationDuration = true;
- timing.iterationDuration = 2;
- timing.startDelay = 5;
-
- RefPtr<Animation> anim = Animation::create(element.get(), 0, timing);
-
- timeline->play(anim.get());
-
- // TODO: Put the player startTime in the future when we add the capability to change player startTime
- platformTiming->expectDelayedAction(timing.startDelay - minimumDelay());
- updateClockAndService(0);
-
- platformTiming->expectDelayedAction(timing.startDelay - minimumDelay() - 1.5);
- updateClockAndService(1.5);
-
- EXPECT_CALL(*platformTiming, serviceOnNextFrame());
- wake();
-
- platformTiming->expectNextFrameAction();
- updateClockAndService(4.98);
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/animation/EffectInput.cpp b/chromium/third_party/WebKit/Source/core/animation/EffectInput.cpp
new file mode 100644
index 00000000000..466052c1346
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/EffectInput.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/EffectInput.h"
+
+#include "bindings/v8/Dictionary.h"
+#include "core/animation/AnimationHelpers.h"
+#include "core/animation/KeyframeEffectModel.h"
+#include "core/animation/StringKeyframe.h"
+#include "core/css/parser/BisonCSSParser.h"
+#include "core/css/resolver/CSSToStyleMap.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Element.h"
+#include "wtf/NonCopyingSort.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<AnimationEffect> EffectInput::convert(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState& exceptionState)
+{
+ // FIXME: Remove the dependency on element.
+ if (!element)
+ return nullptr;
+
+ StyleSheetContents* styleSheetContents = element->document().elementSheet().contents();
+ StringKeyframeVector keyframes;
+ bool everyFrameHasOffset = true;
+ bool looselySortedByOffset = true;
+ double lastOffset = -std::numeric_limits<double>::infinity();
+
+ for (size_t i = 0; i < keyframeDictionaryVector.size(); ++i) {
+ RefPtrWillBeRawPtr<StringKeyframe> keyframe = StringKeyframe::create();
+
+ bool frameHasOffset = false;
+ double offset;
+ if (keyframeDictionaryVector[i].get("offset", offset)) {
+ // Keyframes with offsets outside the range [0.0, 1.0] are ignored.
+ if (std::isnan(offset) || offset < 0 || offset > 1)
+ continue;
+
+ frameHasOffset = true;
+ // The JS value null gets converted to 0 so we need to check whether the original value is null.
+ if (offset == 0) {
+ ScriptValue scriptValue;
+ if (keyframeDictionaryVector[i].get("offset", scriptValue) && scriptValue.isNull())
+ frameHasOffset = false;
+ }
+ if (frameHasOffset) {
+ keyframe->setOffset(offset);
+ if (offset < lastOffset)
+ looselySortedByOffset = false;
+ lastOffset = offset;
+ }
+ }
+ everyFrameHasOffset = everyFrameHasOffset && frameHasOffset;
+
+ keyframes.append(keyframe);
+
+ String compositeString;
+ keyframeDictionaryVector[i].get("composite", compositeString);
+ if (compositeString == "add")
+ keyframe->setComposite(AnimationEffect::CompositeAdd);
+
+ String timingFunctionString;
+ if (keyframeDictionaryVector[i].get("easing", timingFunctionString)) {
+ if (RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString))
+ keyframe->setEasing(CSSToStyleMap::mapAnimationTimingFunction(timingFunctionValue.get(), true));
+ }
+
+ Vector<String> keyframeProperties;
+ keyframeDictionaryVector[i].getOwnPropertyNames(keyframeProperties);
+ for (size_t j = 0; j < keyframeProperties.size(); ++j) {
+ String property = keyframeProperties[j];
+ CSSPropertyID id = camelCaseCSSPropertyNameToID(property);
+ if (id == CSSPropertyInvalid)
+ continue;
+ String value;
+ keyframeDictionaryVector[i].get(property, value);
+ keyframe->setPropertyValue(id, value, styleSheetContents);
+ }
+ }
+
+ if (!looselySortedByOffset) {
+ if (!everyFrameHasOffset) {
+ exceptionState.throwDOMException(InvalidModificationError, "Keyframes are not loosely sorted by offset.");
+ return nullptr;
+ }
+ nonCopyingSort(keyframes.begin(), keyframes.end(), Keyframe::compareOffsets);
+ }
+
+ RefPtrWillBeRawPtr<StringKeyframeEffectModel> keyframeEffectModel = StringKeyframeEffectModel::create(keyframes);
+ if (!keyframeEffectModel->isReplaceOnly()) {
+ exceptionState.throwDOMException(NotSupportedError, "Partial keyframes are not supported.");
+ return nullptr;
+ }
+ keyframeEffectModel->forceConversionsToAnimatableValues(element);
+
+ return keyframeEffectModel;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/EffectInput.h b/chromium/third_party/WebKit/Source/core/animation/EffectInput.h
new file mode 100644
index 00000000000..e8948637813
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/EffectInput.h
@@ -0,0 +1,25 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EffectInput_h
+#define EffectInput_h
+
+#include "core/animation/AnimationEffect.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class AnimationEffect;
+class Dictionary;
+class Element;
+class ExceptionState;
+
+class EffectInput {
+public:
+ static PassRefPtrWillBeRawPtr<AnimationEffect> convert(Element*, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState&);
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/EffectInputTest.cpp b/chromium/third_party/WebKit/Source/core/animation/EffectInputTest.cpp
new file mode 100644
index 00000000000..d8e174ce2a0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/EffectInputTest.cpp
@@ -0,0 +1,125 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/EffectInput.h"
+
+#include "bindings/v8/Dictionary.h"
+#include "core/animation/AnimationTestHelper.h"
+#include "core/animation/KeyframeEffectModel.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include <gtest/gtest.h>
+#include <v8.h>
+
+using namespace WebCore;
+
+namespace {
+
+class AnimationEffectInputTest : public ::testing::Test {
+protected:
+ AnimationEffectInputTest()
+ : document(Document::create())
+ , element(document->createElement("foo", ASSERT_NO_EXCEPTION))
+ , m_isolate(v8::Isolate::GetCurrent())
+ , m_scope(m_isolate)
+ {
+ }
+
+ RefPtrWillBePersistent<Document> document;
+ RefPtrWillBePersistent<Element> element;
+ TrackExceptionState exceptionState;
+ v8::Isolate* m_isolate;
+
+private:
+ V8TestingScope m_scope;
+};
+
+TEST_F(AnimationEffectInputTest, SortedOffsets)
+{
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "0");
+ setV8ObjectPropertyAsString(keyframe2, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe2, "offset", "1");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+
+ RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState);
+ EXPECT_FALSE(exceptionState.hadException());
+ const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get());
+ EXPECT_EQ(1.0, keyframeEffect.getFrames()[1]->offset());
+}
+
+TEST_F(AnimationEffectInputTest, UnsortedOffsets)
+{
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "1");
+ setV8ObjectPropertyAsString(keyframe2, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe2, "offset", "0");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+
+ RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState);
+ EXPECT_FALSE(exceptionState.hadException());
+ const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get());
+ EXPECT_EQ(1.0, keyframeEffect.getFrames()[1]->offset());
+}
+
+TEST_F(AnimationEffectInputTest, LooslySorted)
+{
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "0");
+ setV8ObjectPropertyAsString(keyframe2, "width", "200px");
+ setV8ObjectPropertyAsString(keyframe3, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe3, "offset", "1");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe3, m_isolate));
+
+ RefPtrWillBeRawPtr<AnimationEffect> animationEffect = EffectInput::convert(element.get(), jsKeyframes, exceptionState);
+ EXPECT_FALSE(exceptionState.hadException());
+ const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect.get());
+ EXPECT_EQ(1, keyframeEffect.getFrames()[2]->offset());
+}
+
+TEST_F(AnimationEffectInputTest, Invalid)
+{
+ // Not loosely sorted by offset, and there exists a keyframe with null offset.
+ Vector<Dictionary> jsKeyframes;
+ v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
+ v8::Handle<v8::Object> keyframe3 = v8::Object::New(m_isolate);
+
+ setV8ObjectPropertyAsString(keyframe1, "width", "0px");
+ setV8ObjectPropertyAsString(keyframe1, "offset", "1");
+ setV8ObjectPropertyAsString(keyframe2, "width", "200px");
+ setV8ObjectPropertyAsString(keyframe3, "width", "100px");
+ setV8ObjectPropertyAsString(keyframe3, "offset", "0");
+
+ jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe2, m_isolate));
+ jsKeyframes.append(Dictionary(keyframe3, m_isolate));
+
+ RefPtrWillBeRawPtr<AnimationEffect> animationEffect ALLOW_UNUSED = EffectInput::convert(element.get(), jsKeyframes, exceptionState);
+ EXPECT_TRUE(exceptionState.hadException());
+ EXPECT_EQ(InvalidModificationError, exceptionState.code());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.cpp b/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.cpp
deleted file mode 100644
index 0beb346f7d6..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/ElementAnimation.h"
-
-#include "core/animation/DocumentTimeline.h"
-#include "core/css/RuntimeCSSEnabled.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "wtf/text/StringBuilder.h"
-#include <algorithm>
-
-namespace WebCore {
-
-CSSPropertyID ElementAnimation::camelCaseCSSPropertyNameToID(const String& propertyName)
-{
- if (propertyName.find('-') != kNotFound)
- return CSSPropertyInvalid;
-
- StringBuilder builder;
- size_t position = 0;
- size_t end;
- while ((end = propertyName.find(isASCIIUpper, position)) != kNotFound) {
- builder.append(propertyName.substring(position, end - position) + "-" + toASCIILower((propertyName)[end]));
- position = end + 1;
- }
- builder.append(propertyName.substring(position));
- // Doesn't handle prefixed properties.
- CSSPropertyID id = cssPropertyID(builder.toString());
- return id;
-}
-
-void ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDictionaryVector, double duration)
-{
- ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
-
- // FIXME: This test will not be neccessary once resolution of keyframe values occurs at
- // animation application time.
- if (!element->inActiveDocument())
- return;
- element->document().updateStyleIfNeeded();
- if (!element->renderer())
- return;
-
- startAnimation(element, keyframeDictionaryVector, duration);
-}
-
-void ElementAnimation::startAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, double duration)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes;
- Vector<RefPtr<MutableStylePropertySet> > propertySetVector;
-
- for (size_t i = 0; i < keyframeDictionaryVector.size(); ++i) {
- RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
- propertySetVector.append(propertySet);
-
- RefPtr<Keyframe> keyframe = Keyframe::create();
- keyframes.append(keyframe);
-
- double offset;
- if (keyframeDictionaryVector[i].get("offset", offset)) {
- keyframe->setOffset(offset);
- } else {
- // FIXME: Web Animations CSS engine does not yet implement handling of
- // keyframes without specified offsets. This check can be removed when
- // that funcitonality is implemented.
- ASSERT_NOT_REACHED();
- return;
- }
-
- String compositeString;
- keyframeDictionaryVector[i].get("composite", compositeString);
- if (compositeString == "add")
- keyframe->setComposite(AnimationEffect::CompositeAdd);
-
- Vector<String> keyframeProperties;
- keyframeDictionaryVector[i].getOwnPropertyNames(keyframeProperties);
-
- for (size_t j = 0; j < keyframeProperties.size(); ++j) {
- String property = keyframeProperties[j];
- CSSPropertyID id = camelCaseCSSPropertyNameToID(property);
-
- // FIXME: There is no way to store invalid properties or invalid values
- // in a Keyframe object, so for now I just skip over them. Eventually we
- // will need to support getFrames(), which should return exactly the
- // keyframes that were input through the API. We will add a layer to wrap
- // KeyframeAnimationEffect, store input keyframes and implement getFrames.
- if (id == CSSPropertyInvalid || !CSSAnimations::isAnimatableProperty(id))
- continue;
-
- String value;
- keyframeDictionaryVector[i].get(property, value);
- propertySet->setProperty(id, value);
- }
- }
-
- // FIXME: Replace this with code that just parses, when that code is available.
- RefPtr<KeyframeAnimationEffect> effect = StyleResolver::createKeyframeAnimationEffect(*element, propertySetVector, keyframes);
-
- // FIXME: Totally hardcoded Timing for now. Will handle timing parameters later.
- Timing timing;
- // FIXME: Currently there is no way to tell whether or not an iterationDuration
- // has been specified (becauser the default argument is 0). So any animation
- // created using Element.animate() will have a timing with hasIterationDuration()
- // == true.
- timing.hasIterationDuration = true;
- timing.iterationDuration = std::max<double>(duration, 0);
-
- RefPtr<Animation> animation = Animation::create(element, effect, timing);
- DocumentTimeline* timeline = element->document().timeline();
- ASSERT(timeline);
- timeline->play(animation.get());
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.h b/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.h
index cfc8f6999fa..5f60e2e79ee 100644
--- a/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.h
+++ b/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.h
@@ -31,22 +31,71 @@
#ifndef ElementAnimation_h
#define ElementAnimation_h
-#include "bindings/v8/Dictionary.h"
-#include "core/css/CSSParser.h"
+#include "core/animation/Animation.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/animation/EffectInput.h"
+#include "core/animation/TimingInput.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-class Element;
+class Dictionary;
class ElementAnimation {
public:
- static CSSPropertyID camelCaseCSSPropertyNameToID(const String& propertyName);
- static void animate(Element*, Vector<Dictionary> keyframesDictionaryVector, double duration = 0);
+ static AnimationPlayer* animate(Element& element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Dictionary& timingInputDictionary)
+ {
+ return animateInternal(element, effect, TimingInput::convert(timingInputDictionary));
+ }
-private:
- static void startAnimation(Element*, Vector<Dictionary> keyframesDictionaryVector, double duration = 0);
+ static AnimationPlayer* animate(Element& element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, double duration)
+ {
+ return animateInternal(element, effect, TimingInput::convert(duration));
+ }
+
+ static AnimationPlayer* animate(Element& element, PassRefPtrWillBeRawPtr<AnimationEffect> effect)
+ {
+ return animateInternal(element, effect, Timing());
+ }
+
+ static AnimationPlayer* animate(Element& element, const Vector<Dictionary>& keyframeDictionaryVector, const Dictionary& timingInputDictionary, ExceptionState& exceptionState)
+ {
+ RefPtrWillBeRawPtr<AnimationEffect> effect = EffectInput::convert(&element, keyframeDictionaryVector, exceptionState);
+ if (exceptionState.hadException())
+ return 0;
+ ASSERT(effect);
+ return animateInternal(element, effect.release(), TimingInput::convert(timingInputDictionary));
+ }
- friend class AnimationElementAnimationTest;
+ static AnimationPlayer* animate(Element& element, const Vector<Dictionary>& keyframeDictionaryVector, double duration, ExceptionState& exceptionState)
+ {
+ RefPtrWillBeRawPtr<AnimationEffect> effect = EffectInput::convert(&element, keyframeDictionaryVector, exceptionState);
+ if (exceptionState.hadException())
+ return 0;
+ ASSERT(effect);
+ return animateInternal(element, effect.release(), TimingInput::convert(duration));
+ }
+
+ static AnimationPlayer* animate(Element& element, const Vector<Dictionary>& keyframeDictionaryVector, ExceptionState& exceptionState)
+ {
+ RefPtrWillBeRawPtr<AnimationEffect> effect = EffectInput::convert(&element, keyframeDictionaryVector, exceptionState);
+ if (exceptionState.hadException())
+ return 0;
+ ASSERT(effect);
+ return animateInternal(element, effect.release(), Timing());
+ }
+
+private:
+ static AnimationPlayer* animateInternal(Element& element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing)
+ {
+ if (RuntimeEnabledFeatures::webAnimationsElementAnimateEnabled()) {
+ RefPtrWillBeRawPtr<Animation> animation = Animation::create(&element, effect, timing);
+ return element.document().timeline().play(animation.get());
+ }
+ return 0;
+ }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.idl b/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.idl
index e191d950bc0..f524939ba45 100644
--- a/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.idl
+++ b/chromium/third_party/WebKit/Source/core/animation/ElementAnimation.idl
@@ -28,6 +28,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/web-animations/#idl-def-Element
+// FIXME: move to Animatable
+// http://dev.w3.org/fxtf/web-animations/#idl-def-Animatable
+
partial interface Element {
- [RuntimeEnabled=WebAnimationsAPI] void animate(sequence<Dictionary> keyframes, optional double duration);
-}; \ No newline at end of file
+ // FIXME: needs support for union types http://crbug.com/240176
+ // AnimationPlayer animate((AnimationEffect or sequence<Dictionary>)? effect, optional (double or Dictionary) timing);
+ [Custom, RaisesException] AnimationPlayer animate(object effect, optional object timing);
+};
diff --git a/chromium/third_party/WebKit/Source/core/animation/ElementAnimationTest.cpp b/chromium/third_party/WebKit/Source/core/animation/ElementAnimationTest.cpp
deleted file mode 100644
index bb3f0d4f0ad..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/ElementAnimationTest.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/ElementAnimation.h"
-
-#include "core/animation/AnimatableLength.h"
-#include "core/animation/Animation.h"
-#include "core/animation/AnimationClock.h"
-#include "core/animation/DocumentTimeline.h"
-#include "core/animation/KeyframeAnimationEffect.h"
-#include "core/dom/Document.h"
-#include "core/dom/Element.h"
-
-#include <gtest/gtest.h>
-
-namespace WebCore {
-
-namespace {
-
-v8::Handle<v8::Value> stringToV8Value(String string)
-{
- return v8::Handle<v8::Value>::Cast(v8String(v8::Isolate::GetCurrent(), string));
-}
-
-void setV8ObjectProperty(v8::Handle<v8::Object> object, String name, String value)
-{
- object->Set(stringToV8Value(name), stringToV8Value(value));
-}
-
-} // namespace
-
-class AnimationElementAnimationTest : public ::testing::Test {
-protected:
- virtual void SetUp()
- {
- document = Document::create();
- document->animationClock().resetTimeForTesting();
- element = document->createElement("foo", ASSERT_NO_EXCEPTION);
- document->timeline()->setZeroTime(0);
- ASSERT_EQ(0, document->timeline()->currentTime());
- }
-
- RefPtr<Document> document;
- RefPtr<Element> element;
-
- void startAnimation(Element* element, Vector<Dictionary> keyframesDictionaryVector)
- {
- ElementAnimation::startAnimation(element, keyframesDictionaryVector);
- }
-
- void startAnimationWithSpecifiedDuration(Element* element, Vector<Dictionary> keyframesDictionaryVector, double duration)
- {
- ElementAnimation::startAnimation(element, keyframesDictionaryVector, duration);
- }
-};
-
-TEST_F(AnimationElementAnimationTest, CanStartAnAnimation)
-{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- v8::Context::Scope contextScope(context);
-
- Vector<Dictionary> jsKeyframes;
- v8::Handle<v8::Object> keyframe1 = v8::Object::New();
- v8::Handle<v8::Object> keyframe2 = v8::Object::New();
-
- setV8ObjectProperty(keyframe1, "width", "100px");
- setV8ObjectProperty(keyframe1, "offset", "0");
- setV8ObjectProperty(keyframe2, "width", "0px");
- setV8ObjectProperty(keyframe2, "offset", "1");
-
- jsKeyframes.append(Dictionary(keyframe1, isolate));
- jsKeyframes.append(Dictionary(keyframe2, isolate));
-
- String value1;
- ASSERT_TRUE(jsKeyframes[0].get("width", value1));
- ASSERT_EQ("100px", value1);
-
- String value2;
- ASSERT_TRUE(jsKeyframes[1].get("width", value2));
- ASSERT_EQ("0px", value2);
-
- startAnimationWithSpecifiedDuration(element.get(), jsKeyframes, 0);
-
- Player* player = document->timeline()->players().at(0).get();
-
- Animation* animation = toAnimation(player->source());
-
- Element* target = animation->target();
- EXPECT_EQ(*element.get(), *target);
-
- const KeyframeAnimationEffect::KeyframeVector keyframes =
- toKeyframeAnimationEffect(animation->effect())->getFrames();
-
- EXPECT_EQ(0, keyframes[0]->offset());
- EXPECT_EQ(1, keyframes[1]->offset());
-
- const AnimatableValue* keyframe1Width = keyframes[0]->propertyValue(CSSPropertyWidth);
- const AnimatableValue* keyframe2Width = keyframes[1]->propertyValue(CSSPropertyWidth);
- ASSERT(keyframe1Width);
- ASSERT(keyframe2Width);
-
- EXPECT_TRUE(keyframe1Width->isLength());
- EXPECT_TRUE(keyframe2Width->isLength());
-
- EXPECT_EQ("100px", toAnimatableLength(keyframe1Width)->toCSSValue()->cssText());
- EXPECT_EQ("0px", toAnimatableLength(keyframe2Width)->toCSSValue()->cssText());
-}
-
-TEST_F(AnimationElementAnimationTest, ParseCamelCasePropertyNames)
-{
- EXPECT_EQ(CSSPropertyInvalid, ElementAnimation::camelCaseCSSPropertyNameToID(String("line-height")));
- EXPECT_EQ(CSSPropertyLineHeight, ElementAnimation::camelCaseCSSPropertyNameToID(String("lineHeight")));
- EXPECT_EQ(CSSPropertyBorderTopWidth, ElementAnimation::camelCaseCSSPropertyNameToID(String("borderTopWidth")));
- EXPECT_EQ(CSSPropertyWidth, ElementAnimation::camelCaseCSSPropertyNameToID(String("width")));
- EXPECT_EQ(CSSPropertyInvalid, ElementAnimation::camelCaseCSSPropertyNameToID(String("Width")));
- EXPECT_EQ(CSSPropertyInvalid, ElementAnimation::camelCaseCSSPropertyNameToID(String("-webkit-transform")));
- EXPECT_EQ(CSSPropertyInvalid, ElementAnimation::camelCaseCSSPropertyNameToID(String("webkitTransform")));
- EXPECT_EQ(CSSPropertyInvalid, ElementAnimation::camelCaseCSSPropertyNameToID(String("cssFloat")));
-}
-
-TEST_F(AnimationElementAnimationTest, CanSetDuration)
-{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- v8::Context::Scope contextScope(context);
-
- Vector<Dictionary, 0> jsKeyframes;
- double duration = 2;
-
- startAnimationWithSpecifiedDuration(element.get(), jsKeyframes, duration);
-
- Player* player = document->timeline()->players().at(0).get();
-
- EXPECT_TRUE(player->source()->specified().hasIterationDuration);
- EXPECT_EQ(duration, player->source()->specified().iterationDuration);
-}
-
-TEST_F(AnimationElementAnimationTest, CanOmitSpecifiedDuration)
-{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- v8::Context::Scope contextScope(context);
-
- Vector<Dictionary, 0> jsKeyframes;
-
- startAnimation(element.get(), jsKeyframes);
-
- Player* player = document->timeline()->players().at(0).get();
-
- // FIXME: This is correct for the moment, as using c++ default arguments means
- // there is no way to tell whether a duration has been specified by the user.
- // Once we implment timing object arguments we should be able to tell, and this
- // check should be changed to EXPECT_FALSE.
- EXPECT_TRUE(player->source()->specified().hasIterationDuration);
- EXPECT_EQ(0, player->source()->specified().iterationDuration);
-}
-
-TEST_F(AnimationElementAnimationTest, ClipNegativeDurationToZero)
-{
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- v8::HandleScope scope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- v8::Context::Scope contextScope(context);
-
- Vector<Dictionary, 0> jsKeyframes;
- double duration = -2;
-
- startAnimationWithSpecifiedDuration(element.get(), jsKeyframes, duration);
-
- Player* player = document->timeline()->players().at(0).get();
-
- EXPECT_TRUE(player->source()->specified().hasIterationDuration);
- EXPECT_EQ(0, player->source()->specified().iterationDuration);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/InertAnimation.cpp b/chromium/third_party/WebKit/Source/core/animation/InertAnimation.cpp
index 3cb21505300..3ba61c06a8c 100644
--- a/chromium/third_party/WebKit/Source/core/animation/InertAnimation.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/InertAnimation.cpp
@@ -30,37 +30,43 @@
#include "config.h"
#include "core/animation/InertAnimation.h"
+#include "core/animation/interpolation/Interpolation.h"
namespace WebCore {
-PassRefPtr<InertAnimation> InertAnimation::create(PassRefPtr<AnimationEffect> effect, const Timing& timing, bool paused)
+PassRefPtrWillBeRawPtr<InertAnimation> InertAnimation::create(PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing, bool paused)
{
- return adoptRef(new InertAnimation(effect, timing, paused));
+ return adoptRefWillBeNoop(new InertAnimation(effect, timing, paused));
}
-InertAnimation::InertAnimation(PassRefPtr<AnimationEffect> effect, const Timing& timing, bool paused)
- : TimedItem(timing)
+InertAnimation::InertAnimation(PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing, bool paused)
+ : AnimationNode(timing)
, m_effect(effect)
, m_paused(paused)
{
}
-PassOwnPtr<AnimationEffect::CompositableValueList> InertAnimation::sample()
+PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > InertAnimation::sample(double inheritedTime)
{
- updateInheritedTime(0);
+ updateInheritedTime(inheritedTime, TimingUpdateOnDemand);
if (!isInEffect())
return nullptr;
double iteration = currentIteration();
ASSERT(iteration >= 0);
// FIXME: Handle iteration values which overflow int.
- return m_effect->sample(static_cast<int>(iteration), timeFraction());
+ return m_effect->sample(static_cast<int>(iteration), timeFraction(), iterationDuration());
}
-
-double InertAnimation::calculateTimeToEffectChange(double, double) const
+double InertAnimation::calculateTimeToEffectChange(bool, double, double) const
{
return std::numeric_limits<double>::infinity();
}
+void InertAnimation::trace(Visitor* visitor)
+{
+ visitor->trace(m_effect);
+ AnimationNode::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/InertAnimation.h b/chromium/third_party/WebKit/Source/core/animation/InertAnimation.h
index a52ba532ec6..633ad5030ca 100644
--- a/chromium/third_party/WebKit/Source/core/animation/InertAnimation.h
+++ b/chromium/third_party/WebKit/Source/core/animation/InertAnimation.h
@@ -32,27 +32,27 @@
#define InertAnimation_h
#include "core/animation/AnimationEffect.h"
-#include "core/animation/TimedItem.h"
+#include "core/animation/AnimationNode.h"
#include "wtf/RefPtr.h"
namespace WebCore {
-class InertAnimation FINAL : public TimedItem {
-
+class InertAnimation FINAL : public AnimationNode {
public:
- static PassRefPtr<InertAnimation> create(PassRefPtr<AnimationEffect>, const Timing&, bool paused);
- PassOwnPtr<AnimationEffect::CompositableValueList> sample();
+ static PassRefPtrWillBeRawPtr<InertAnimation> create(PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, bool paused);
+ PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample(double inheritedTime);
AnimationEffect* effect() const { return m_effect.get(); }
bool paused() const { return m_paused; }
+ virtual void trace(Visitor*);
+
protected:
- virtual bool updateChildrenAndEffects() const OVERRIDE { return false; };
- virtual void willDetach() OVERRIDE { };
- virtual double calculateTimeToEffectChange(double inheritedTime, double timeToNextIteration) const OVERRIDE FINAL;
+ virtual void updateChildrenAndEffects() const OVERRIDE { }
+ virtual double calculateTimeToEffectChange(bool forwards, double inheritedTime, double timeToNextIteration) const OVERRIDE;
private:
- InertAnimation(PassRefPtr<AnimationEffect>, const Timing&, bool paused);
- RefPtr<AnimationEffect> m_effect;
+ InertAnimation(PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, bool paused);
+ RefPtrWillBeMember<AnimationEffect> m_effect;
bool m_paused;
};
diff --git a/chromium/third_party/WebKit/Source/core/animation/InterpolableValue.cpp b/chromium/third_party/WebKit/Source/core/animation/InterpolableValue.cpp
new file mode 100644
index 00000000000..e1b43a9345c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/InterpolableValue.cpp
@@ -0,0 +1,75 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/InterpolableValue.h"
+
+namespace WebCore {
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(InterpolableValue);
+
+PassOwnPtrWillBeRawPtr<InterpolableValue> InterpolableNumber::interpolate(const InterpolableValue &to, const double progress) const
+{
+ const InterpolableNumber* toNumber = toInterpolableNumber(&to);
+ if (!progress)
+ return create(m_value);
+ if (progress == 1)
+ return create(toNumber->m_value);
+ return create(m_value * (1 - progress) + toNumber->m_value * progress);
+}
+
+PassOwnPtrWillBeRawPtr<InterpolableValue> InterpolableBool::interpolate(const InterpolableValue &to, const double progress) const
+{
+ if (progress < 0.5) {
+ return clone();
+ }
+ return to.clone();
+}
+
+PassOwnPtrWillBeRawPtr<InterpolableValue> InterpolableList::interpolate(const InterpolableValue &to, const double progress) const
+{
+ const InterpolableList* toList = toInterpolableList(&to);
+ ASSERT(toList->m_size == m_size);
+
+ if (!progress) {
+ return create(*this);
+ }
+ if (progress == 1) {
+ return InterpolableList::create(*toList);
+ }
+
+ OwnPtrWillBeRawPtr<InterpolableList> result = create(m_size);
+ for (size_t i = 0; i < m_size; i++) {
+ ASSERT(m_values[i]);
+ ASSERT(toList->m_values[i]);
+ result->set(i, m_values[i]->interpolate(*(toList->m_values[i]), progress));
+ }
+ return result.release();
+}
+
+void InterpolableList::trace(Visitor* visitor)
+{
+#if ENABLE_OILPAN
+ visitor->trace(m_values);
+#endif
+ InterpolableValue::trace(visitor);
+}
+
+PassOwnPtrWillBeRawPtr<InterpolableValue> InterpolableAnimatableValue::interpolate(const InterpolableValue &other, const double percentage) const
+{
+ const InterpolableAnimatableValue *otherValue = toInterpolableAnimatableValue(&other);
+ if (!percentage)
+ return create(m_value);
+ if (percentage == 1)
+ return create(otherValue->m_value);
+ return create(AnimatableValue::interpolate(m_value.get(), otherValue->m_value.get(), percentage));
+}
+
+void InterpolableAnimatableValue::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ InterpolableValue::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/InterpolableValue.h b/chromium/third_party/WebKit/Source/core/animation/InterpolableValue.h
new file mode 100644
index 00000000000..75484cf12b1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/InterpolableValue.h
@@ -0,0 +1,167 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef InterpolableValue_h
+#define InterpolableValue_h
+
+#include "core/animation/AnimatableValue.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class InterpolableValue : public NoBaseWillBeGarbageCollected<InterpolableValue> {
+ DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(InterpolableValue);
+public:
+ virtual bool isNumber() const { return false; }
+ virtual bool isBool() const { return false; }
+ virtual bool isList() const { return false; }
+ virtual bool isAnimatableValue() const { return false; }
+
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const = 0;
+
+ virtual void trace(Visitor*) { }
+
+private:
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const = 0;
+
+ friend class Interpolation;
+
+ // Keep interpolate private, but allow calls within the hierarchy without
+ // knowledge of type.
+ friend class DeferredLegacyStyleInterpolation;
+ friend class InterpolableNumber;
+ friend class InterpolableBool;
+ friend class InterpolableList;
+};
+
+class InterpolableNumber : public InterpolableValue {
+public:
+ static PassOwnPtrWillBeRawPtr<InterpolableNumber> create(double value)
+ {
+ return adoptPtrWillBeNoop(new InterpolableNumber(value));
+ }
+
+ virtual bool isNumber() const OVERRIDE FINAL { return true; }
+ double value() const { return m_value; }
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
+
+ virtual void trace(Visitor* visitor) OVERRIDE { InterpolableValue::trace(visitor); }
+
+private:
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const OVERRIDE FINAL;
+ double m_value;
+
+ explicit InterpolableNumber(double value)
+ : m_value(value)
+ {
+ }
+
+};
+
+class InterpolableBool : public InterpolableValue {
+public:
+ static PassOwnPtrWillBeRawPtr<InterpolableBool> create(bool value)
+ {
+ return adoptPtrWillBeNoop(new InterpolableBool(value));
+ }
+
+ virtual bool isBool() const OVERRIDE FINAL { return true; }
+ bool value() const { return m_value; }
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
+
+ virtual void trace(Visitor* visitor) OVERRIDE { InterpolableValue::trace(visitor); }
+
+private:
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const OVERRIDE FINAL;
+ bool m_value;
+
+ explicit InterpolableBool(bool value)
+ : m_value(value)
+ {
+ }
+
+};
+
+class InterpolableList : public InterpolableValue {
+public:
+ static PassOwnPtrWillBeRawPtr<InterpolableList> create(const InterpolableList &other)
+ {
+ return adoptPtrWillBeNoop(new InterpolableList(other));
+ }
+
+ static PassOwnPtrWillBeRawPtr<InterpolableList> create(size_t size)
+ {
+ return adoptPtrWillBeNoop(new InterpolableList(size));
+ }
+
+ virtual bool isList() const OVERRIDE FINAL { return true; }
+ void set(size_t position, PassOwnPtrWillBeRawPtr<InterpolableValue> value)
+ {
+ ASSERT(position < m_size);
+ m_values[position] = value;
+ }
+ const InterpolableValue* get(size_t position) const
+ {
+ ASSERT(position < m_size);
+ return m_values[position].get();
+ }
+ size_t length() const { return m_size; }
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(*this); }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &other, const double progress) const OVERRIDE FINAL;
+ explicit InterpolableList(size_t size)
+ : m_size(size)
+ , m_values(m_size)
+ {
+ }
+
+ InterpolableList(const InterpolableList& other)
+ : m_size(other.m_size)
+ , m_values(m_size)
+ {
+ for (size_t i = 0; i < m_size; i++)
+ set(i, other.m_values[i]->clone());
+ }
+
+ size_t m_size;
+ WillBeHeapVector<OwnPtrWillBeMember<InterpolableValue> > m_values;
+};
+
+// FIXME: Remove this when we can.
+class InterpolableAnimatableValue : public InterpolableValue {
+public:
+ static PassOwnPtrWillBeRawPtr<InterpolableAnimatableValue> create(PassRefPtrWillBeRawPtr<AnimatableValue> value)
+ {
+ return adoptPtrWillBeNoop(new InterpolableAnimatableValue(value));
+ }
+
+ virtual bool isAnimatableValue() const OVERRIDE FINAL { return true; }
+ AnimatableValue* value() const { return m_value.get(); }
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &other, const double progress) const OVERRIDE FINAL;
+ RefPtrWillBeMember<AnimatableValue> m_value;
+
+ InterpolableAnimatableValue(PassRefPtrWillBeRawPtr<AnimatableValue> value)
+ : m_value(value)
+ {
+ }
+};
+
+DEFINE_TYPE_CASTS(InterpolableNumber, InterpolableValue, value, value->isNumber(), value.isNumber());
+DEFINE_TYPE_CASTS(InterpolableBool, InterpolableValue, value, value->isBool(), value.isBool());
+DEFINE_TYPE_CASTS(InterpolableList, InterpolableValue, value, value->isList(), value.isList());
+DEFINE_TYPE_CASTS(InterpolableAnimatableValue, InterpolableValue, value, value->isAnimatableValue(), value.isAnimatableValue());
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/InterpolableValueTest.cpp b/chromium/third_party/WebKit/Source/core/animation/InterpolableValueTest.cpp
new file mode 100644
index 00000000000..69ed8f6084f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/InterpolableValueTest.cpp
@@ -0,0 +1,105 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/InterpolableValue.h"
+
+#include "core/animation/interpolation/Interpolation.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class AnimationInterpolableValueTest : public ::testing::Test {
+protected:
+ InterpolableValue* interpolationValue(Interpolation& interpolation)
+ {
+ return interpolation.getCachedValueForTesting();
+ }
+
+ double interpolateNumbers(double a, double b, double progress)
+ {
+ RefPtrWillBeRawPtr<Interpolation> i = Interpolation::create(InterpolableNumber::create(a), InterpolableNumber::create(b));
+ i->interpolate(0, progress);
+ return toInterpolableNumber(interpolationValue(*i.get()))->value();
+ }
+
+ bool interpolateBools(bool a, bool b, double progress)
+ {
+ RefPtrWillBeRawPtr<Interpolation> i = Interpolation::create(InterpolableBool::create(a), InterpolableBool::create(b));
+ i->interpolate(0, progress);
+ return toInterpolableBool(interpolationValue(*i.get()))->value();
+ }
+
+ PassRefPtrWillBeRawPtr<Interpolation> interpolateLists(PassOwnPtrWillBeRawPtr<InterpolableList> listA, PassOwnPtrWillBeRawPtr<InterpolableList> listB, double progress)
+ {
+ RefPtrWillBeRawPtr<Interpolation> i = Interpolation::create(listA, listB);
+ i->interpolate(0, progress);
+ return i;
+ }
+};
+
+TEST_F(AnimationInterpolableValueTest, InterpolateNumbers)
+{
+ EXPECT_FLOAT_EQ(126, interpolateNumbers(42, 0, -2));
+ EXPECT_FLOAT_EQ(42, interpolateNumbers(42, 0, 0));
+ EXPECT_FLOAT_EQ(29.4f, interpolateNumbers(42, 0, 0.3));
+ EXPECT_FLOAT_EQ(21, interpolateNumbers(42, 0, 0.5));
+ EXPECT_FLOAT_EQ(0, interpolateNumbers(42, 0, 1));
+ EXPECT_FLOAT_EQ(-21, interpolateNumbers(42, 0, 1.5));
+}
+
+TEST_F(AnimationInterpolableValueTest, InterpolateBools)
+{
+ EXPECT_FALSE(interpolateBools(false, true, -1));
+ EXPECT_FALSE(interpolateBools(false, true, 0));
+ EXPECT_FALSE(interpolateBools(false, true, 0.3));
+ EXPECT_TRUE(interpolateBools(false, true, 0.5));
+ EXPECT_TRUE(interpolateBools(false, true, 1));
+ EXPECT_TRUE(interpolateBools(false, true, 2));
+}
+
+TEST_F(AnimationInterpolableValueTest, SimpleList)
+{
+ OwnPtrWillBeRawPtr<InterpolableList> listA = InterpolableList::create(3);
+ listA->set(0, InterpolableNumber::create(0));
+ listA->set(1, InterpolableNumber::create(42));
+ listA->set(2, InterpolableNumber::create(20.5));
+
+ OwnPtrWillBeRawPtr<InterpolableList> listB = InterpolableList::create(3);
+ listB->set(0, InterpolableNumber::create(100));
+ listB->set(1, InterpolableNumber::create(-200));
+ listB->set(2, InterpolableNumber::create(300));
+
+ RefPtrWillBeRawPtr<Interpolation> i = interpolateLists(listA.release(), listB.release(), 0.3);
+ InterpolableList* outList = toInterpolableList(interpolationValue(*i.get()));
+ EXPECT_FLOAT_EQ(30, toInterpolableNumber(outList->get(0))->value());
+ EXPECT_FLOAT_EQ(-30.6f, toInterpolableNumber(outList->get(1))->value());
+ EXPECT_FLOAT_EQ(104.35f, toInterpolableNumber(outList->get(2))->value());
+}
+
+TEST_F(AnimationInterpolableValueTest, NestedList)
+{
+ OwnPtrWillBeRawPtr<InterpolableList> listA = InterpolableList::create(3);
+ listA->set(0, InterpolableNumber::create(0));
+ OwnPtrWillBeRawPtr<InterpolableList> subListA = InterpolableList::create(1);
+ subListA->set(0, InterpolableNumber::create(100));
+ listA->set(1, subListA.release());
+ listA->set(2, InterpolableBool::create(false));
+
+ OwnPtrWillBeRawPtr<InterpolableList> listB = InterpolableList::create(3);
+ listB->set(0, InterpolableNumber::create(100));
+ OwnPtrWillBeRawPtr<InterpolableList> subListB = InterpolableList::create(1);
+ subListB->set(0, InterpolableNumber::create(50));
+ listB->set(1, subListB.release());
+ listB->set(2, InterpolableBool::create(true));
+
+ RefPtrWillBeRawPtr<Interpolation> i = interpolateLists(listA.release(), listB.release(), 0.5);
+ InterpolableList* outList = toInterpolableList(interpolationValue(*i.get()));
+ EXPECT_FLOAT_EQ(50, toInterpolableNumber(outList->get(0))->value());
+ EXPECT_FLOAT_EQ(75, toInterpolableNumber(toInterpolableList(outList->get(1))->get(0))->value());
+ EXPECT_TRUE(toInterpolableBool(outList->get(2))->value());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/InterpolationEffect.cpp b/chromium/third_party/WebKit/Source/core/animation/InterpolationEffect.cpp
new file mode 100644
index 00000000000..c03fbab782c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/InterpolationEffect.cpp
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/InterpolationEffect.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > InterpolationEffect::getActiveInterpolations(double fraction, double iterationDuration) const
+{
+
+ WillBeHeapVector<RefPtrWillBeMember<Interpolation> >* result = new WillBeHeapVector<RefPtrWillBeMember<Interpolation> >();
+
+ for (size_t i = 0; i < m_interpolations.size(); ++i) {
+ const InterpolationRecord* record = m_interpolations[i].get();
+ if (fraction >= record->m_applyFrom && fraction < record->m_applyTo) {
+ RefPtrWillBeRawPtr<Interpolation> interpolation = record->m_interpolation;
+ double localFraction = (fraction - record->m_start) / (record->m_end - record->m_start);
+ if (record->m_easing)
+ localFraction = record->m_easing->evaluate(localFraction, accuracyForDuration(iterationDuration));
+ interpolation->interpolate(0, localFraction);
+ result->append(interpolation);
+ }
+ }
+
+ return adoptPtrWillBeNoop(result);
+}
+
+void InterpolationEffect::InterpolationRecord::trace(Visitor* visitor)
+{
+ visitor->trace(m_interpolation);
+}
+
+void InterpolationEffect::trace(Visitor* visitor)
+{
+#if ENABLE_OILPAN
+ visitor->trace(m_interpolations);
+#endif
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/InterpolationEffect.h b/chromium/third_party/WebKit/Source/core/animation/InterpolationEffect.h
new file mode 100644
index 00000000000..c189f86deca
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/InterpolationEffect.h
@@ -0,0 +1,66 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef InterpolationEffect_h
+#define InterpolationEffect_h
+
+#include "core/animation/interpolation/Interpolation.h"
+#include "platform/animation/TimingFunction.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class InterpolationEffect : public RefCountedWillBeGarbageCollected<InterpolationEffect> {
+public:
+ static PassRefPtrWillBeRawPtr<InterpolationEffect> create() { return adoptRefWillBeNoop(new InterpolationEffect()); }
+
+ PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > getActiveInterpolations(double fraction, double iterationDuration) const;
+
+ void addInterpolation(PassRefPtrWillBeRawPtr<Interpolation> interpolation, PassRefPtr<TimingFunction> easing, double start, double end, double applyFrom, double applyTo)
+ {
+ m_interpolations.append(InterpolationRecord::create(interpolation, easing, start, end, applyFrom, applyTo));
+ }
+
+ void trace(Visitor*);
+
+private:
+ InterpolationEffect()
+ {
+ }
+
+ class InterpolationRecord : public NoBaseWillBeGarbageCollectedFinalized<InterpolationRecord> {
+ public:
+ RefPtrWillBeMember<Interpolation> m_interpolation;
+ RefPtr<TimingFunction> m_easing;
+ double m_start;
+ double m_end;
+ double m_applyFrom;
+ double m_applyTo;
+
+ static PassOwnPtrWillBeRawPtr<InterpolationRecord> create(PassRefPtrWillBeRawPtr<Interpolation> interpolation, PassRefPtr<TimingFunction> easing, double start, double end, double applyFrom, double applyTo)
+ {
+ return adoptPtrWillBeNoop(new InterpolationRecord(interpolation, easing, start, end, applyFrom, applyTo));
+ }
+
+ void trace(Visitor*);
+
+ private:
+ InterpolationRecord(PassRefPtrWillBeRawPtr<Interpolation> interpolation, PassRefPtr<TimingFunction> easing, double start, double end, double applyFrom, double applyTo)
+ : m_interpolation(interpolation)
+ , m_easing(easing)
+ , m_start(start)
+ , m_end(end)
+ , m_applyFrom(applyFrom)
+ , m_applyTo(applyTo)
+ {
+ }
+ };
+
+ WillBeHeapVector<OwnPtrWillBeMember<InterpolationRecord> > m_interpolations;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/InterpolationEffectTest.cpp b/chromium/third_party/WebKit/Source/core/animation/InterpolationEffectTest.cpp
new file mode 100644
index 00000000000..8b84b755d05
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/InterpolationEffectTest.cpp
@@ -0,0 +1,98 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/InterpolationEffect.h"
+
+#include <gtest/gtest.h>
+
+namespace {
+
+const double duration = 1.0;
+
+} // namespace
+
+namespace WebCore {
+
+class AnimationInterpolationEffectTest : public ::testing::Test {
+protected:
+ InterpolableValue* interpolationValue(Interpolation& interpolation)
+ {
+ return interpolation.getCachedValueForTesting();
+ }
+
+ double getInterpolableNumber(PassRefPtrWillBeRawPtr<Interpolation> value)
+ {
+ return toInterpolableNumber(interpolationValue(*value.get()))->value();
+ }
+};
+
+TEST_F(AnimationInterpolationEffectTest, SingleInterpolation)
+{
+ RefPtrWillBeRawPtr<InterpolationEffect> interpolationEffect = InterpolationEffect::create();
+ interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(0), InterpolableNumber::create(10)),
+ RefPtr<TimingFunction>(), 0, 1, -1, 2);
+
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > activeInterpolations = interpolationEffect->getActiveInterpolations(-2, duration);
+ EXPECT_EQ(0ul, activeInterpolations->size());
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(-0.5, duration);
+ EXPECT_EQ(1ul, activeInterpolations->size());
+ EXPECT_EQ(-5, getInterpolableNumber(activeInterpolations->at(0)));
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(0.5, duration);
+ EXPECT_EQ(1ul, activeInterpolations->size());
+ EXPECT_FLOAT_EQ(5, getInterpolableNumber(activeInterpolations->at(0)));
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(1.5, duration);
+ EXPECT_EQ(1ul, activeInterpolations->size());
+ EXPECT_FLOAT_EQ(15, getInterpolableNumber(activeInterpolations->at(0)));
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(3, duration);
+ EXPECT_EQ(0ul, activeInterpolations->size());
+}
+
+TEST_F(AnimationInterpolationEffectTest, MultipleInterpolations)
+{
+ RefPtrWillBeRawPtr<InterpolationEffect> interpolationEffect = InterpolationEffect::create();
+ interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(10), InterpolableNumber::create(15)),
+ RefPtr<TimingFunction>(), 1, 2, 1, 3);
+ interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(0), InterpolableNumber::create(1)),
+ LinearTimingFunction::shared(), 0, 1, 0, 1);
+ interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(1), InterpolableNumber::create(6)),
+ CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease), 0.5, 1.5, 0.5, 1.5);
+
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > activeInterpolations = interpolationEffect->getActiveInterpolations(-0.5, duration);
+ EXPECT_EQ(0ul, activeInterpolations->size());
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(0, duration);
+ EXPECT_EQ(1ul, activeInterpolations->size());
+ EXPECT_FLOAT_EQ(0, getInterpolableNumber(activeInterpolations->at(0)));
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(0.5, duration);
+ EXPECT_EQ(2ul, activeInterpolations->size());
+ EXPECT_FLOAT_EQ(0.5f, getInterpolableNumber(activeInterpolations->at(0)));
+ EXPECT_FLOAT_EQ(1, getInterpolableNumber(activeInterpolations->at(1)));
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(1, duration);
+ EXPECT_EQ(2ul, activeInterpolations->size());
+ EXPECT_FLOAT_EQ(10, getInterpolableNumber(activeInterpolations->at(0)));
+ EXPECT_FLOAT_EQ(5.0282884f, getInterpolableNumber(activeInterpolations->at(1)));
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(1, duration * 1000);
+ EXPECT_EQ(2ul, activeInterpolations->size());
+ EXPECT_FLOAT_EQ(10, getInterpolableNumber(activeInterpolations->at(0)));
+ EXPECT_FLOAT_EQ(5.0120168f, getInterpolableNumber(activeInterpolations->at(1)));
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(1.5, duration);
+ EXPECT_EQ(1ul, activeInterpolations->size());
+ EXPECT_FLOAT_EQ(12.5f, getInterpolableNumber(activeInterpolations->at(0)));
+
+ activeInterpolations = interpolationEffect->getActiveInterpolations(2, duration);
+ EXPECT_EQ(1ul, activeInterpolations->size());
+ EXPECT_FLOAT_EQ(15, getInterpolableNumber(activeInterpolations->at(0)));
+}
+
+}
+
diff --git a/chromium/third_party/WebKit/Source/core/animation/Keyframe.h b/chromium/third_party/WebKit/Source/core/animation/Keyframe.h
new file mode 100644
index 00000000000..1f47c906117
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/Keyframe.h
@@ -0,0 +1,102 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef Keyframe_h
+#define Keyframe_h
+
+#include "core/CSSPropertyNames.h"
+#include "core/animation/AnimatableValue.h"
+#include "core/animation/AnimationEffect.h"
+#include "core/animation/AnimationNode.h"
+
+namespace WebCore {
+
+typedef HashSet<CSSPropertyID> PropertySet;
+
+class Element;
+
+// FIXME: Make Keyframe immutable
+class Keyframe : public RefCountedWillBeGarbageCollectedFinalized<Keyframe> {
+public:
+ virtual ~Keyframe() { }
+
+ void setOffset(double offset) { m_offset = offset; }
+ double offset() const { return m_offset; }
+
+ void setComposite(AnimationEffect::CompositeOperation composite) { m_composite = composite; }
+ AnimationEffect::CompositeOperation composite() const { return m_composite; }
+
+ void setEasing(PassRefPtr<TimingFunction> easing) { m_easing = easing; }
+ TimingFunction* easing() const { return m_easing.get(); }
+
+ static bool compareOffsets(const RefPtrWillBeMember<Keyframe>& a, const RefPtrWillBeMember<Keyframe>& b)
+ {
+ return a->offset() < b->offset();
+ }
+
+ virtual PropertySet properties() const = 0;
+
+ virtual PassRefPtrWillBeRawPtr<Keyframe> clone() const = 0;
+ PassRefPtrWillBeRawPtr<Keyframe> cloneWithOffset(double offset) const
+ {
+ RefPtrWillBeRawPtr<Keyframe> theClone = clone();
+ theClone->setOffset(offset);
+ return theClone.release();
+ }
+
+ virtual bool isAnimatableValueKeyframe() const { return false; }
+ virtual bool isStringKeyframe() const { return false; }
+
+ virtual void trace(Visitor*) { }
+
+ class PropertySpecificKeyframe : public NoBaseWillBeGarbageCollectedFinalized<PropertySpecificKeyframe> {
+ public:
+ virtual ~PropertySpecificKeyframe() { }
+ double offset() const { return m_offset; }
+ TimingFunction* easing() const { return m_easing.get(); }
+ AnimationEffect::CompositeOperation composite() const { return m_composite; }
+ virtual PassOwnPtrWillBeRawPtr<PropertySpecificKeyframe> cloneWithOffset(double offset) const = 0;
+
+ virtual const PassRefPtrWillBeRawPtr<AnimatableValue> getAnimatableValue() const = 0;
+
+ virtual bool isAnimatableValuePropertySpecificKeyframe() const { return false; }
+ virtual bool isStringPropertySpecificKeyframe() const { return false; }
+
+ virtual PassOwnPtrWillBeRawPtr<PropertySpecificKeyframe> neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const = 0;
+ virtual PassRefPtrWillBeRawPtr<Interpolation> createInterpolation(CSSPropertyID, WebCore::Keyframe::PropertySpecificKeyframe* end, Element*) const = 0;
+
+ virtual void trace(Visitor*) { }
+
+ protected:
+ PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, AnimationEffect::CompositeOperation);
+
+ double m_offset;
+ RefPtr<TimingFunction> m_easing;
+ AnimationEffect::CompositeOperation m_composite;
+ };
+
+ virtual PassOwnPtrWillBeRawPtr<PropertySpecificKeyframe> createPropertySpecificKeyframe(CSSPropertyID) const = 0;
+
+protected:
+ Keyframe()
+ : m_offset(nullValue())
+ , m_composite(AnimationEffect::CompositeReplace)
+ , m_easing(LinearTimingFunction::shared())
+ {
+ }
+ Keyframe(double offset, AnimationEffect::CompositeOperation composite, PassRefPtr<TimingFunction> easing)
+ : m_offset(offset)
+ , m_composite(composite)
+ , m_easing(easing)
+ {
+ }
+
+ double m_offset;
+ AnimationEffect::CompositeOperation m_composite;
+ RefPtr<TimingFunction> m_easing;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp b/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp
deleted file mode 100644
index dd6ffa3a832..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/KeyframeAnimationEffect.h"
-
-#include "core/animation/TimedItem.h"
-#include "wtf/text/StringHash.h"
-
-namespace {
-
-using namespace WebCore;
-
-class ReplaceCompositableValue : public AnimationEffect::CompositableValue {
-public:
- static PassRefPtr<ReplaceCompositableValue> create(const AnimatableValue* value)
- {
- return adoptRef(new ReplaceCompositableValue(value));
- }
- virtual bool dependsOnUnderlyingValue() const
- {
- return false;
- }
- virtual PassRefPtr<AnimatableValue> compositeOnto(const AnimatableValue* underlyingValue) const
- {
- return PassRefPtr<AnimatableValue>(m_value);
- }
-private:
- ReplaceCompositableValue(const AnimatableValue* value)
- : m_value(const_cast<AnimatableValue*>(value))
- {
- }
- RefPtr<AnimatableValue> m_value;
-};
-
-class AddCompositableValue : public AnimationEffect::CompositableValue {
-public:
- static PassRefPtr<AddCompositableValue> create(const AnimatableValue* value)
- {
- return adoptRef(new AddCompositableValue(value));
- }
- virtual bool dependsOnUnderlyingValue() const
- {
- return true;
- }
- virtual PassRefPtr<AnimatableValue> compositeOnto(const AnimatableValue* underlyingValue) const
- {
- return AnimatableValue::add(underlyingValue, m_value.get());
- }
-private:
- AddCompositableValue(const AnimatableValue* value)
- : m_value(const_cast<AnimatableValue*>(value))
- {
- }
- RefPtr<AnimatableValue> m_value;
-};
-
-class BlendedCompositableValue : public AnimationEffect::CompositableValue {
-public:
- static PassRefPtr<BlendedCompositableValue> create(const AnimationEffect::CompositableValue* before, const AnimationEffect::CompositableValue* after, double fraction)
- {
- return adoptRef(new BlendedCompositableValue(before, after, fraction));
- }
- virtual bool dependsOnUnderlyingValue() const
- {
- return m_dependsOnUnderlyingValue;
- }
- virtual PassRefPtr<AnimatableValue> compositeOnto(const AnimatableValue* underlyingValue) const
- {
- return AnimatableValue::interpolate(m_before->compositeOnto(underlyingValue).get(), m_after->compositeOnto(underlyingValue).get(), m_fraction);
- }
-private:
- BlendedCompositableValue(const AnimationEffect::CompositableValue* before, const AnimationEffect::CompositableValue* after, double fraction)
- : m_before(const_cast<AnimationEffect::CompositableValue*>(before))
- , m_after(const_cast<AnimationEffect::CompositableValue*>(after))
- , m_fraction(fraction)
- , m_dependsOnUnderlyingValue(before->dependsOnUnderlyingValue() || after->dependsOnUnderlyingValue())
- { }
- RefPtr<AnimationEffect::CompositableValue> m_before;
- RefPtr<AnimationEffect::CompositableValue> m_after;
- double m_fraction;
- bool m_dependsOnUnderlyingValue;
-};
-
-} // namespace
-
-
-namespace WebCore {
-
-Keyframe::Keyframe()
- : m_offset(nullValue())
- , m_composite(AnimationEffect::CompositeReplace)
-{ }
-
-Keyframe::Keyframe(const Keyframe& copyFrom)
- : m_offset(copyFrom.m_offset)
- , m_composite(copyFrom.m_composite)
-{
- for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin(); iter != copyFrom.m_propertyValues.end(); ++iter)
- setPropertyValue(iter->key, iter->value.get());
-}
-
-void Keyframe::setPropertyValue(CSSPropertyID property, const AnimatableValue* value)
-{
- m_propertyValues.add(property, const_cast<AnimatableValue*>(value));
-}
-
-void Keyframe::clearPropertyValue(CSSPropertyID property)
-{
- m_propertyValues.remove(property);
-}
-
-const AnimatableValue* Keyframe::propertyValue(CSSPropertyID property) const
-{
- ASSERT(m_propertyValues.contains(property));
- return m_propertyValues.get(property);
-}
-
-PropertySet Keyframe::properties() const
-{
- // This is not used in time-critical code, so we probably don't need to
- // worry about caching this result.
- PropertySet properties;
- for (PropertyValueMap::const_iterator iter = m_propertyValues.begin(); iter != m_propertyValues.end(); ++iter)
- properties.add(*iter.keys());
- return properties;
-}
-
-PassRefPtr<Keyframe> Keyframe::cloneWithOffset(double offset) const
-{
- RefPtr<Keyframe> theClone = clone();
- theClone->setOffset(offset);
- return theClone.release();
-}
-
-KeyframeAnimationEffect::KeyframeAnimationEffect(const KeyframeVector& keyframes)
- : m_keyframes(keyframes)
-{
-}
-
-PropertySet KeyframeAnimationEffect::properties() const
-{
- PropertySet result;
- const KeyframeVector& frames = getFrames();
- if (!frames.size()) {
- return result;
- }
- result = frames[0]->properties();
- for (size_t i = 1; i < frames.size(); i++) {
- PropertySet extras = frames[i]->properties();
- for (PropertySet::const_iterator it = extras.begin(); it != extras.end(); ++it) {
- result.add(*it);
- }
- }
- return result;
-}
-
-PassOwnPtr<AnimationEffect::CompositableValueList> KeyframeAnimationEffect::sample(int iteration, double fraction) const
-{
- ASSERT(iteration >= 0);
- ASSERT(!isNull(fraction));
- const_cast<KeyframeAnimationEffect*>(this)->ensureKeyframeGroups();
- OwnPtr<CompositableValueList> map = adoptPtr(new CompositableValueList());
- for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter)
- map->append(std::make_pair(iter->key, iter->value->sample(iteration, fraction)));
- return map.release();
-}
-
-KeyframeAnimationEffect::KeyframeVector KeyframeAnimationEffect::normalizedKeyframes() const
-{
- KeyframeVector keyframes = m_keyframes;
-
- // Set offsets at 0.0 and 1.0 at ends if unset.
- if (keyframes.size() >= 2) {
- Keyframe* firstKeyframe = keyframes.first().get();
- if (isNull(firstKeyframe->offset()))
- firstKeyframe->setOffset(0.0);
- }
- if (keyframes.size() >= 1) {
- Keyframe* lastKeyframe = keyframes.last().get();
- if (lastKeyframe && isNull(lastKeyframe->offset()))
- lastKeyframe->setOffset(1.0);
- }
-
- // FIXME: Distribute offsets where missing.
- for (KeyframeVector::iterator iter = keyframes.begin(); iter != keyframes.end(); ++iter)
- ASSERT(!isNull((*iter)->offset()));
-
- // Sort by offset.
- std::stable_sort(keyframes.begin(), keyframes.end(), Keyframe::compareOffsets);
- return keyframes;
-}
-
-void KeyframeAnimationEffect::ensureKeyframeGroups() const
-{
- if (m_keyframeGroups)
- return;
-
- m_keyframeGroups = adoptPtr(new KeyframeGroupMap);
- const KeyframeVector& keyframes = normalizedKeyframes();
- for (KeyframeVector::const_iterator keyframeIter = keyframes.begin(); keyframeIter != keyframes.end(); ++keyframeIter) {
- const Keyframe* keyframe = keyframeIter->get();
- PropertySet keyframeProperties = keyframe->properties();
- for (PropertySet::const_iterator propertyIter = keyframeProperties.begin(); propertyIter != keyframeProperties.end(); ++propertyIter) {
- CSSPropertyID property = *propertyIter;
- KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(property);
- if (groupIter == m_keyframeGroups->end()) {
- KeyframeGroupMap::AddResult result = m_keyframeGroups->add(property, adoptPtr(new PropertySpecificKeyframeGroup));
- ASSERT(result.isNewEntry);
- groupIter = result.iterator;
- }
- groupIter->value->appendKeyframe(adoptPtr(
- new PropertySpecificKeyframe(keyframe->offset(), keyframe->propertyValue(property), keyframe->composite())));
- }
- }
-
- // Add synthetic keyframes.
- for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) {
- iter->value->addSyntheticKeyframeIfRequired();
- iter->value->removeRedundantKeyframes();
- }
-}
-
-
-KeyframeAnimationEffect::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, const AnimatableValue* value, CompositeOperation composite)
- : m_offset(offset)
- , m_value(composite == AnimationEffect::CompositeReplace ?
- static_cast<PassRefPtr<CompositableValue> >(ReplaceCompositableValue::create(value)) :
- static_cast<PassRefPtr<CompositableValue> >(AddCompositableValue::create(value)))
-{
-}
-
-KeyframeAnimationEffect::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<CompositableValue> value)
- : m_offset(offset)
- , m_value(value)
-{
- ASSERT(!isNull(m_offset));
-}
-
-PassOwnPtr<KeyframeAnimationEffect::PropertySpecificKeyframe> KeyframeAnimationEffect::PropertySpecificKeyframe::cloneWithOffset(double offset) const
-{
- return adoptPtr(new PropertySpecificKeyframe(offset, PassRefPtr<CompositableValue>(m_value)));
-}
-
-
-void KeyframeAnimationEffect::PropertySpecificKeyframeGroup::appendKeyframe(PassOwnPtr<PropertySpecificKeyframe> keyframe)
-{
- ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->offset());
- m_keyframes.append(keyframe);
-}
-
-void KeyframeAnimationEffect::PropertySpecificKeyframeGroup::removeRedundantKeyframes()
-{
- // As an optimization, removes keyframes in the following categories, as
- // they will never be used by sample().
- // - End keyframes with the same offset as their neighbor
- // - Interior keyframes with the same offset as both their neighbors
- // Note that synthetic keyframes must be added before this method is
- // called.
- ASSERT(m_keyframes.size() >= 2);
- for (int i = m_keyframes.size() - 1; i >= 0; --i) {
- double offset = m_keyframes[i]->offset();
- bool hasSameOffsetAsPreviousNeighbor = !i || m_keyframes[i - 1]->offset() == offset;
- bool hasSameOffsetAsNextNeighbor = i == static_cast<int>(m_keyframes.size() - 1) || m_keyframes[i + 1]->offset() == offset;
- if (hasSameOffsetAsPreviousNeighbor && hasSameOffsetAsNextNeighbor)
- m_keyframes.remove(i);
- }
- ASSERT(m_keyframes.size() >= 2);
-}
-
-void KeyframeAnimationEffect::PropertySpecificKeyframeGroup::addSyntheticKeyframeIfRequired()
-{
- ASSERT(!m_keyframes.isEmpty());
- double offset = m_keyframes.first()->offset();
- bool allOffsetsEqual = true;
- for (PropertySpecificKeyframeVector::const_iterator iter = m_keyframes.begin() + 1; iter != m_keyframes.end(); ++iter) {
- if ((*iter)->offset() != offset) {
- allOffsetsEqual = false;
- break;
- }
- }
- if (!allOffsetsEqual)
- return;
-
- if (!offset)
- appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0));
- else
- m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, AnimatableValue::neutralValue(), CompositeAdd)));
-}
-
-PassRefPtr<AnimationEffect::CompositableValue> KeyframeAnimationEffect::PropertySpecificKeyframeGroup::sample(int iteration, double offset) const
-{
- // FIXME: Implement accumulation.
- ASSERT_UNUSED(iteration, iteration >= 0);
- ASSERT(!isNull(offset));
-
- // Bail if offset is null, as this can lead to buffer overflow below.
- if (isNull(offset))
- return const_cast<CompositableValue*>(m_keyframes.first()->value());
-
- double minimumOffset = m_keyframes.first()->offset();
- double maximumOffset = m_keyframes.last()->offset();
- ASSERT(minimumOffset != maximumOffset);
-
- PropertySpecificKeyframeVector::const_iterator before;
- PropertySpecificKeyframeVector::const_iterator after;
-
- // Note that this algorithm is simpler than that in the spec because we
- // have removed keyframes with equal offsets in
- // removeRedundantKeyframes().
- if (offset < minimumOffset) {
- before = m_keyframes.begin();
- after = before + 1;
- ASSERT((*before)->offset() > offset);
- ASSERT((*after)->offset() > offset);
- } else if (offset >= maximumOffset) {
- after = m_keyframes.end() - 1;
- before = after - 1;
- ASSERT((*before)->offset() < offset);
- ASSERT((*after)->offset() <= offset);
- } else {
- // FIXME: This is inefficient for large numbers of keyframes. Consider
- // using binary search.
- after = m_keyframes.begin();
- while ((*after)->offset() <= offset)
- ++after;
- before = after - 1;
- ASSERT((*before)->offset() <= offset);
- ASSERT((*after)->offset() > offset);
- }
-
- if ((*before)->offset() == offset)
- return const_cast<CompositableValue*>((*before)->value());
- if ((*after)->offset() == offset)
- return const_cast<CompositableValue*>((*after)->value());
- return BlendedCompositableValue::create((*before)->value(), (*after)->value(),
- (offset - (*before)->offset()) / ((*after)->offset() - (*before)->offset()));
-}
-
-} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.h b/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.h
deleted file mode 100644
index ee784299dc4..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffect.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef KeyframeAnimationEffect_h
-#define KeyframeAnimationEffect_h
-
-#include "core/animation/AnimatableValue.h"
-#include "core/animation/AnimationEffect.h"
-#include "wtf/HashMap.h"
-#include "wtf/HashSet.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-typedef HashSet<CSSPropertyID> PropertySet;
-
-// Represents the keyframes set through the API.
-class Keyframe : public RefCounted<Keyframe> {
-public:
- static PassRefPtr<Keyframe> create()
- {
- return adoptRef(new Keyframe);
- }
- static bool compareOffsets(const RefPtr<Keyframe>& a, const RefPtr<Keyframe>& b)
- {
- return a->offset() < b->offset();
- }
- void setOffset(double offset) { m_offset = offset; }
- double offset() const { return m_offset; }
- void setComposite(AnimationEffect::CompositeOperation composite) { m_composite = composite; }
- AnimationEffect::CompositeOperation composite() const { return m_composite; }
- void setPropertyValue(CSSPropertyID, const AnimatableValue*);
- void clearPropertyValue(CSSPropertyID);
- const AnimatableValue* propertyValue(CSSPropertyID) const;
- PropertySet properties() const;
- PassRefPtr<Keyframe> clone() const { return adoptRef(new Keyframe(*this)); }
- PassRefPtr<Keyframe> cloneWithOffset(double offset) const;
-private:
- Keyframe();
- Keyframe(const Keyframe&);
- double m_offset;
- AnimationEffect::CompositeOperation m_composite;
- typedef HashMap<CSSPropertyID, RefPtr<AnimatableValue> > PropertyValueMap;
- PropertyValueMap m_propertyValues;
-};
-
-class KeyframeAnimationEffect : public AnimationEffect {
-public:
- class PropertySpecificKeyframe;
- typedef Vector<RefPtr<Keyframe> > KeyframeVector;
- typedef Vector<OwnPtr<KeyframeAnimationEffect::PropertySpecificKeyframe> > PropertySpecificKeyframeVector;
- // FIXME: Implement accumulation.
- static PassRefPtr<KeyframeAnimationEffect> create(const KeyframeVector& keyframes)
- {
- return adoptRef(new KeyframeAnimationEffect(keyframes));
- }
-
- virtual bool affects(CSSPropertyID property) OVERRIDE
- {
- ensureKeyframeGroups();
- return m_keyframeGroups->contains(property);
- }
-
- // AnimationEffect implementation.
- virtual PassOwnPtr<CompositableValueList> sample(int iteration, double fraction) const OVERRIDE;
-
- // FIXME: Implement setFrames()
- const KeyframeVector& getFrames() const { return m_keyframes; }
-
- virtual bool isKeyframeAnimationEffect() const OVERRIDE { return true; }
-
- PropertySet properties() const;
-
- class PropertySpecificKeyframe {
- public:
- PropertySpecificKeyframe(double offset, const AnimatableValue*, CompositeOperation);
- double offset() const { return m_offset; }
- const CompositableValue* value() const { return m_value.get(); }
- PassOwnPtr<PropertySpecificKeyframe> cloneWithOffset(double offset) const;
- private:
- // Used by cloneWithOffset().
- PropertySpecificKeyframe(double offset, PassRefPtr<CompositableValue>);
- double m_offset;
- RefPtr<CompositableValue> m_value;
- };
-
- class PropertySpecificKeyframeGroup {
- public:
- void appendKeyframe(PassOwnPtr<PropertySpecificKeyframe>);
- PassRefPtr<CompositableValue> sample(int iteration, double offset) const;
- const PropertySpecificKeyframeVector& keyframes() const { return m_keyframes; }
- private:
- PropertySpecificKeyframeVector m_keyframes;
- void removeRedundantKeyframes();
- void addSyntheticKeyframeIfRequired();
-
- friend class KeyframeAnimationEffect;
- };
-
- const PropertySpecificKeyframeVector& getPropertySpecificKeyframes(CSSPropertyID id) const
- {
- ensureKeyframeGroups();
- return m_keyframeGroups->get(id)->keyframes();
- }
-
-private:
- KeyframeAnimationEffect(const KeyframeVector& keyframes);
-
- KeyframeVector normalizedKeyframes() const;
- // Lazily computes the groups of property-specific keyframes.
- void ensureKeyframeGroups() const;
-
- KeyframeVector m_keyframes;
- // The spec describes filtering the normalized keyframes at sampling time
- // to get the 'property-specific keyframes'. For efficiency, we cache the
- // property-specific lists.
- typedef HashMap<CSSPropertyID, OwnPtr<PropertySpecificKeyframeGroup> > KeyframeGroupMap;
- mutable OwnPtr<KeyframeGroupMap> m_keyframeGroups;
-};
-
-DEFINE_TYPE_CASTS(KeyframeAnimationEffect, AnimationEffect, value, value->isKeyframeAnimationEffect(), value.isKeyframeAnimationEffect());
-
-} // namespace WebCore
-
-#endif // KeyframeAnimationEffect_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffectTest.cpp b/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffectTest.cpp
deleted file mode 100644
index 4a493bd4f27..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/KeyframeAnimationEffectTest.cpp
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/KeyframeAnimationEffect.h"
-
-#include "core/animation/AnimatableLength.h"
-#include "core/animation/AnimatableUnknown.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include <gtest/gtest.h>
-
-using namespace WebCore;
-
-namespace {
-
-AnimatableValue* unknownAnimatableValue(double n)
-{
- return AnimatableUnknown::create(CSSPrimitiveValue::create(n, CSSPrimitiveValue::CSS_UNKNOWN).get()).leakRef();
-}
-
-AnimatableValue* pixelAnimatableValue(double n)
-{
- return AnimatableLength::create(CSSPrimitiveValue::create(n, CSSPrimitiveValue::CSS_PX).get()).leakRef();
-}
-
-KeyframeAnimationEffect::KeyframeVector keyframesAtZeroAndOne(AnimatableValue* zeroValue, AnimatableValue* oneValue)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(2);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, zeroValue);
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(1.0);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, oneValue);
- return keyframes;
-}
-
-void expectDoubleValue(double expectedValue, PassRefPtr<AnimatableValue> value)
-{
- ASSERT_TRUE(value->isLength() || value->isUnknown());
-
- double actualValue;
- if (value->isLength())
- actualValue = toCSSPrimitiveValue(toAnimatableLength(value.get())->toCSSValue().get())->getDoubleValue();
- else
- actualValue = toCSSPrimitiveValue(toAnimatableUnknown(value.get())->toCSSValue().get())->getDoubleValue();
-
- EXPECT_FLOAT_EQ(static_cast<float>(expectedValue), actualValue);
-}
-
-
-TEST(AnimationKeyframeAnimationEffectTest, BasicOperation)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
- ASSERT_EQ(1UL, values->size());
- EXPECT_EQ(CSSPropertyLeft, values->at(0).first);
- expectDoubleValue(5.0, values->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, CompositeReplaceNonInterpolable)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
- keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
- keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, CompositeReplace)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
- keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
- keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(3.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, CompositeAdd)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
- keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
- keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, ExtrapolateReplaceNonInterpolable)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
- keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
- expectDoubleValue(5.0, effect->sample(0, 1.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, ExtrapolateReplace)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
- keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
- expectDoubleValue(3.0 * -0.6 + 5.0 * 1.6, effect->sample(0, 1.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, ExtrapolateAdd)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
- keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
- keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue((7.0 + 3.0) * -0.6 + (7.0 + 5.0) * 1.6, effect->sample(0, 1.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, ZeroKeyframes)
-{
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(KeyframeAnimationEffect::KeyframeVector());
- EXPECT_TRUE(effect->sample(0, 0.5)->isEmpty());
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, SingleKeyframeAtOffsetZero)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(1);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(3.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, SingleKeyframeAtOffsetOne)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(1);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(1.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0));
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(7.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, MoreThanTwoKeyframes)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(3);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(0.5);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0));
- keyframes[2] = Keyframe::create();
- keyframes[2]->setOffset(1.0);
- keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(4.0, effect->sample(0, 0.3)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- expectDoubleValue(5.0, effect->sample(0, 0.8)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, EndKeyframeOffsetsUnspecified)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(3);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(0.5);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0));
- keyframes[2] = Keyframe::create();
- keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(3.0, effect->sample(0, 0.1)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- expectDoubleValue(4.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- expectDoubleValue(5.0, effect->sample(0, 0.9)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, SampleOnKeyframe)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(3);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(0.5);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0));
- keyframes[2] = Keyframe::create();
- keyframes[2]->setOffset(1.0);
- keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(3.0, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- expectDoubleValue(4.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- expectDoubleValue(5.0, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-// Note that this tests an implementation detail, not behaviour defined by the spec.
-TEST(AnimationKeyframeAnimationEffectTest, SampleReturnsSameAnimatableValueInstance)
-{
- AnimatableValue* threePixelsValue = unknownAnimatableValue(3.0);
- AnimatableValue* fourPixelsValue = unknownAnimatableValue(4.0);
- AnimatableValue* fivePixelsValue = unknownAnimatableValue(5.0);
-
- KeyframeAnimationEffect::KeyframeVector keyframes(3);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, threePixelsValue);
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(0.5);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, fourPixelsValue);
- keyframes[2] = Keyframe::create();
- keyframes[2]->setOffset(1.0);
- keyframes[2]->setPropertyValue(CSSPropertyLeft, fivePixelsValue);
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- EXPECT_EQ(threePixelsValue, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- EXPECT_EQ(threePixelsValue, effect->sample(0, 0.1)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.4)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- EXPECT_EQ(fivePixelsValue, effect->sample(0, 0.9)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- EXPECT_EQ(fivePixelsValue, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, MultipleKeyframesWithSameOffset)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(7);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.1);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(1.0));
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(0.1);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(2.0));
- keyframes[2] = Keyframe::create();
- keyframes[2]->setOffset(0.5);
- keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
- keyframes[3] = Keyframe::create();
- keyframes[3]->setOffset(0.5);
- keyframes[3]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0));
- keyframes[4] = Keyframe::create();
- keyframes[4]->setOffset(0.5);
- keyframes[4]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
- keyframes[5] = Keyframe::create();
- keyframes[5]->setOffset(0.9);
- keyframes[5]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(6.0));
- keyframes[6] = Keyframe::create();
- keyframes[6]->setOffset(0.9);
- keyframes[6]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(7.0));
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(2.0, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
- expectDoubleValue(2.0, effect->sample(0, 0.2)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
- expectDoubleValue(3.0, effect->sample(0, 0.4)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
- expectDoubleValue(5.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
- expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
- expectDoubleValue(6.0, effect->sample(0, 0.8)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
- expectDoubleValue(6.0, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, PerKeyframeComposite)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(2);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(3.0));
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(1.0);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0));
- keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(3.0 * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, MultipleProperties)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(2);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
- keyframes[0]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(4.0));
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(1.0);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
- keyframes[1]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(6.0));
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
- ASSERT_EQ(2UL, values->size());
- EXPECT_TRUE(values->at(0).first == CSSPropertyLeft);
- expectDoubleValue(5.0, values->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
- EXPECT_TRUE(values->at(1).first == CSSPropertyRight);
- expectDoubleValue(6.0, values->at(1).second->compositeOnto(unknownAnimatableValue(7.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, RecompositeCompositableValue)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
- keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
- keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
- expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, values->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
- expectDoubleValue((9.0 + 3.0) * 0.4 + (9.0 + 5.0) * 0.6, values->at(0).second->compositeOnto(pixelAnimatableValue(9.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, MultipleIterations)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(1.0), pixelAnimatableValue(3.0));
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- expectDoubleValue(2.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
- expectDoubleValue(2.0, effect->sample(1, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
- expectDoubleValue(2.0, effect->sample(2, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, DependsOnUnderlyingValue)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(3);
- keyframes[0] = Keyframe::create();
- keyframes[0]->setOffset(0.0);
- keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0));
- keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
- keyframes[1] = Keyframe::create();
- keyframes[1]->setOffset(0.5);
- keyframes[1]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0));
- keyframes[2] = Keyframe::create();
- keyframes[2]->setOffset(1.0);
- keyframes[2]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0));
-
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
- EXPECT_TRUE(effect->sample(0, 0)->at(0).second->dependsOnUnderlyingValue());
- EXPECT_TRUE(effect->sample(0, 0.1)->at(0).second->dependsOnUnderlyingValue());
- EXPECT_TRUE(effect->sample(0, 0.25)->at(0).second->dependsOnUnderlyingValue());
- EXPECT_TRUE(effect->sample(0, 0.4)->at(0).second->dependsOnUnderlyingValue());
- EXPECT_FALSE(effect->sample(0, 0.5)->at(0).second->dependsOnUnderlyingValue());
- EXPECT_FALSE(effect->sample(0, 0.6)->at(0).second->dependsOnUnderlyingValue());
- EXPECT_FALSE(effect->sample(0, 0.75)->at(0).second->dependsOnUnderlyingValue());
- EXPECT_FALSE(effect->sample(0, 0.8)->at(0).second->dependsOnUnderlyingValue());
- EXPECT_FALSE(effect->sample(0, 1)->at(0).second->dependsOnUnderlyingValue());
-}
-
-TEST(AnimationKeyframeAnimationEffectTest, ToKeyframeAnimationEffect)
-{
- KeyframeAnimationEffect::KeyframeVector keyframes(0);
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
-
- AnimationEffect* baseEffect = effect.get();
- EXPECT_TRUE(toKeyframeAnimationEffect(baseEffect));
-}
-
-} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp b/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp
new file mode 100644
index 00000000000..c9f2a3fbbe9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/KeyframeEffectModel.h"
+
+#include "core/StylePropertyShorthand.h"
+#include "core/animation/AnimationNode.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+PropertySet KeyframeEffectModelBase::properties() const
+{
+ PropertySet result;
+ if (!m_keyframes.size()) {
+ return result;
+ }
+ result = m_keyframes[0]->properties();
+ for (size_t i = 1; i < m_keyframes.size(); i++) {
+ PropertySet extras = m_keyframes[i]->properties();
+ for (PropertySet::const_iterator it = extras.begin(); it != extras.end(); ++it) {
+ result.add(*it);
+ }
+ }
+ return result;
+}
+
+PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > KeyframeEffectModelBase::sample(int iteration, double fraction, double iterationDuration) const
+{
+ ASSERT(iteration >= 0);
+ ASSERT(!isNull(fraction));
+ ensureKeyframeGroups();
+ ensureInterpolationEffect();
+
+ return m_interpolationEffect->getActiveInterpolations(fraction, iterationDuration);
+}
+
+KeyframeEffectModelBase::KeyframeVector KeyframeEffectModelBase::normalizedKeyframes(const KeyframeVector& keyframes)
+{
+ // keyframes [beginIndex, endIndex) will remain after removing all keyframes if they are not
+ // loosely sorted by offset, and after removing keyframes with positional offset outide [0, 1].
+ size_t beginIndex = 0;
+ size_t endIndex = keyframes.size();
+
+ // Becomes the most recent keyframe with an explicit offset.
+ size_t lastIndex = endIndex;
+ double lastOffset = std::numeric_limits<double>::quiet_NaN();
+
+ for (size_t i = 0; i < keyframes.size(); ++i) {
+ double offset = keyframes[i]->offset();
+ if (!isNull(offset)) {
+ if (lastIndex < i && offset < lastOffset) {
+ // The keyframes are not loosely sorted by offset. Exclude all.
+ endIndex = beginIndex;
+ break;
+ }
+
+ if (offset < 0) {
+ // Remove all keyframes up to and including this keyframe.
+ beginIndex = i + 1;
+ } else if (offset > 1) {
+ // Remove all keyframes from this keyframe onwards. Note we must complete our checking
+ // that the keyframes are loosely sorted by offset, so we can't exit the loop early.
+ endIndex = std::min(i, endIndex);
+ }
+
+ lastIndex = i;
+ lastOffset = offset;
+ }
+ }
+
+ KeyframeVector result;
+ if (beginIndex != endIndex) {
+ result.reserveCapacity(endIndex - beginIndex);
+ for (size_t i = beginIndex; i < endIndex; ++i) {
+ result.append(keyframes[i]->clone());
+ }
+
+ if (isNull(result[result.size() - 1]->offset()))
+ result[result.size() - 1]->setOffset(1);
+
+ if (result.size() > 1 && isNull(result[0]->offset()))
+ result[0]->setOffset(0);
+
+ lastIndex = 0;
+ lastOffset = result[0]->offset();
+ for (size_t i = 1; i < result.size(); ++i) {
+ double offset = result[i]->offset();
+ if (!isNull(offset)) {
+ if (lastIndex + 1 < i) {
+ for (size_t j = 1; j < i - lastIndex; ++j)
+ result[lastIndex + j]->setOffset(lastOffset + (offset - lastOffset) * j / (i - lastIndex));
+ }
+ lastIndex = i;
+ lastOffset = offset;
+ }
+ }
+ }
+ return result;
+}
+
+
+void KeyframeEffectModelBase::ensureKeyframeGroups() const
+{
+ if (m_keyframeGroups)
+ return;
+
+ m_keyframeGroups = adoptPtrWillBeNoop(new KeyframeGroupMap);
+ const KeyframeVector keyframes = normalizedKeyframes(getFrames());
+ for (KeyframeVector::const_iterator keyframeIter = keyframes.begin(); keyframeIter != keyframes.end(); ++keyframeIter) {
+ const Keyframe* keyframe = keyframeIter->get();
+ PropertySet keyframeProperties = keyframe->properties();
+ for (PropertySet::const_iterator propertyIter = keyframeProperties.begin(); propertyIter != keyframeProperties.end(); ++propertyIter) {
+ CSSPropertyID property = *propertyIter;
+ ASSERT_WITH_MESSAGE(!isExpandedShorthand(property), "Web Animations: Encountered shorthand CSS property (%d) in normalized keyframes.", property);
+ KeyframeGroupMap::iterator groupIter = m_keyframeGroups->find(property);
+ PropertySpecificKeyframeGroup* group;
+ if (groupIter == m_keyframeGroups->end())
+ group = m_keyframeGroups->add(property, adoptPtrWillBeNoop(new PropertySpecificKeyframeGroup)).storedValue->value.get();
+ else
+ group = groupIter->value.get();
+
+ group->appendKeyframe(keyframe->createPropertySpecificKeyframe(property));
+ }
+ }
+
+ // Add synthetic keyframes.
+ for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) {
+ iter->value->addSyntheticKeyframeIfRequired(this);
+ iter->value->removeRedundantKeyframes();
+ }
+}
+
+void KeyframeEffectModelBase::ensureInterpolationEffect(Element* element) const
+{
+ if (m_interpolationEffect)
+ return;
+ m_interpolationEffect = InterpolationEffect::create();
+
+ for (KeyframeGroupMap::const_iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) {
+ const PropertySpecificKeyframeVector& keyframes = iter->value->keyframes();
+ ASSERT(keyframes[0]->composite() == AnimationEffect::CompositeReplace);
+ for (size_t i = 0; i < keyframes.size() - 1; i++) {
+ ASSERT(keyframes[i + 1]->composite() == AnimationEffect::CompositeReplace);
+ double applyFrom = i ? keyframes[i]->offset() : (-std::numeric_limits<double>::infinity());
+ double applyTo = i == keyframes.size() - 2 ? std::numeric_limits<double>::infinity() : keyframes[i + 1]->offset();
+ if (applyTo == 1)
+ applyTo = std::numeric_limits<double>::infinity();
+
+ m_interpolationEffect->addInterpolation(keyframes[i]->createInterpolation(iter->key, keyframes[i + 1].get(), element),
+ keyframes[i]->easing(), keyframes[i]->offset(), keyframes[i + 1]->offset(), applyFrom, applyTo);
+ }
+ }
+}
+
+bool KeyframeEffectModelBase::isReplaceOnly()
+{
+ ensureKeyframeGroups();
+ for (KeyframeGroupMap::iterator iter = m_keyframeGroups->begin(); iter != m_keyframeGroups->end(); ++iter) {
+ const PropertySpecificKeyframeVector& keyframeVector = iter->value->keyframes();
+ for (size_t i = 0; i < keyframeVector.size(); ++i) {
+ if (keyframeVector[i]->composite() != AnimationEffect::CompositeReplace)
+ return false;
+ }
+ }
+ return true;
+}
+
+void KeyframeEffectModelBase::trace(Visitor* visitor)
+{
+ visitor->trace(m_keyframes);
+ visitor->trace(m_interpolationEffect);
+#if ENABLE_OILPAN
+ visitor->trace(m_keyframeGroups);
+#endif
+ AnimationEffect::trace(visitor);
+}
+
+Keyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, AnimationEffect::CompositeOperation composite)
+ : m_offset(offset)
+ , m_easing(easing)
+ , m_composite(composite)
+{
+}
+
+void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::appendKeyframe(PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> keyframe)
+{
+ ASSERT(m_keyframes.isEmpty() || m_keyframes.last()->offset() <= keyframe->offset());
+ m_keyframes.append(keyframe);
+}
+
+void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::removeRedundantKeyframes()
+{
+ // As an optimization, removes keyframes in the following categories, as
+ // they will never be used by sample().
+ // - End keyframes with the same offset as their neighbor
+ // - Interior keyframes with the same offset as both their neighbors
+ // Note that synthetic keyframes must be added before this method is
+ // called.
+ ASSERT(m_keyframes.size() >= 2);
+ for (int i = m_keyframes.size() - 1; i >= 0; --i) {
+ double offset = m_keyframes[i]->offset();
+ bool hasSameOffsetAsPreviousNeighbor = !i || m_keyframes[i - 1]->offset() == offset;
+ bool hasSameOffsetAsNextNeighbor = i == static_cast<int>(m_keyframes.size() - 1) || m_keyframes[i + 1]->offset() == offset;
+ if (hasSameOffsetAsPreviousNeighbor && hasSameOffsetAsNextNeighbor)
+ m_keyframes.remove(i);
+ }
+ ASSERT(m_keyframes.size() >= 2);
+}
+
+void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::addSyntheticKeyframeIfRequired(const KeyframeEffectModelBase* context)
+{
+ ASSERT(!m_keyframes.isEmpty());
+ if (m_keyframes.first()->offset() != 0.0)
+ m_keyframes.insert(0, m_keyframes.first()->neutralKeyframe(0, nullptr));
+ if (m_keyframes.last()->offset() != 1.0)
+ appendKeyframe(m_keyframes.last()->neutralKeyframe(1, nullptr));
+}
+
+void KeyframeEffectModelBase::PropertySpecificKeyframeGroup::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_keyframes);
+#endif
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModel.h b/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModel.h
new file mode 100644
index 00000000000..34feab36d91
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModel.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef KeyframeEffectModel_h
+#define KeyframeEffectModel_h
+
+#include "core/animation/AnimatableValueKeyframe.h"
+#include "core/animation/AnimationEffect.h"
+#include "core/animation/AnimationNode.h"
+#include "core/animation/InterpolationEffect.h"
+#include "core/animation/StringKeyframe.h"
+#include "platform/animation/TimingFunction.h"
+#include "platform/heap/Handle.h"
+#include "wtf/HashMap.h"
+#include "wtf/HashSet.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class Element;
+class KeyframeEffectModelTest;
+
+class KeyframeEffectModelBase : public AnimationEffect {
+public:
+ // FIXME: Implement accumulation.
+
+ typedef WillBeHeapVector<OwnPtrWillBeMember<Keyframe::PropertySpecificKeyframe> > PropertySpecificKeyframeVector;
+ class PropertySpecificKeyframeGroup : public NoBaseWillBeGarbageCollected<PropertySpecificKeyframeGroup> {
+ public:
+ void appendKeyframe(PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe>);
+ const PropertySpecificKeyframeVector& keyframes() const { return m_keyframes; }
+
+ void trace(Visitor*);
+
+ private:
+ void removeRedundantKeyframes();
+ void addSyntheticKeyframeIfRequired(const KeyframeEffectModelBase* context);
+
+ PropertySpecificKeyframeVector m_keyframes;
+
+ friend class KeyframeEffectModelBase;
+ };
+
+ bool isReplaceOnly();
+
+ PropertySet properties() const;
+
+ typedef WillBeHeapVector<RefPtrWillBeMember<Keyframe> > KeyframeVector;
+ const KeyframeVector& getFrames() const { return m_keyframes; }
+ // FIXME: Implement setFrames()
+
+ const PropertySpecificKeyframeVector& getPropertySpecificKeyframes(CSSPropertyID id) const
+ {
+ ensureKeyframeGroups();
+ return m_keyframeGroups->get(id)->keyframes();
+ }
+
+ // AnimationEffect implementation.
+ virtual PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample(int iteration, double fraction, double iterationDuration) const OVERRIDE;
+
+ virtual bool isKeyframeEffectModel() const OVERRIDE { return true; }
+
+ virtual bool isAnimatableValueKeyframeEffectModel() const { return false; }
+ virtual bool isStringKeyframeEffectModel() const { return false; }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ // FIXME: This is a hack used to resolve CSSValues to AnimatableValues while we have a valid handle on an element.
+ // This should be removed once StringKeyframes no longer uses InterpolableAnimatableValues.
+ void forceConversionsToAnimatableValues(Element* element)
+ {
+ ensureKeyframeGroups();
+ ensureInterpolationEffect(element);
+ }
+
+protected:
+ static KeyframeVector normalizedKeyframes(const KeyframeVector& keyframes);
+
+ // Lazily computes the groups of property-specific keyframes.
+ void ensureKeyframeGroups() const;
+ void ensureInterpolationEffect(Element* = 0) const;
+
+ KeyframeVector m_keyframes;
+ // The spec describes filtering the normalized keyframes at sampling time
+ // to get the 'property-specific keyframes'. For efficiency, we cache the
+ // property-specific lists.
+ typedef WillBeHeapHashMap<CSSPropertyID, OwnPtrWillBeMember<PropertySpecificKeyframeGroup> > KeyframeGroupMap;
+ mutable OwnPtrWillBeMember<KeyframeGroupMap> m_keyframeGroups;
+ mutable RefPtrWillBeMember<InterpolationEffect> m_interpolationEffect;
+
+ friend class KeyframeEffectModelTest;
+
+ bool affects(CSSPropertyID property)
+ {
+ ensureKeyframeGroups();
+ return m_keyframeGroups->contains(property);
+ }
+};
+
+template <class Keyframe>
+class KeyframeEffectModel FINAL : public KeyframeEffectModelBase {
+public:
+ typedef WillBeHeapVector<RefPtrWillBeMember<Keyframe> > KeyframeVector;
+ static PassRefPtrWillBeRawPtr<KeyframeEffectModel<Keyframe> > create(const KeyframeVector& keyframes) { return adoptRefWillBeNoop(new KeyframeEffectModel(keyframes)); }
+
+private:
+ KeyframeEffectModel(const KeyframeVector& keyframes)
+ {
+ m_keyframes.appendVector(keyframes);
+ }
+
+ virtual bool isAnimatableValueKeyframeEffectModel() const { return false; }
+ virtual bool isStringKeyframeEffectModel() const { return false; }
+
+};
+
+typedef KeyframeEffectModelBase::KeyframeVector KeyframeVector;
+typedef KeyframeEffectModelBase::PropertySpecificKeyframeVector PropertySpecificKeyframeVector;
+
+typedef KeyframeEffectModel<AnimatableValueKeyframe> AnimatableValueKeyframeEffectModel;
+typedef AnimatableValueKeyframeEffectModel::KeyframeVector AnimatableValueKeyframeVector;
+typedef AnimatableValueKeyframeEffectModel::PropertySpecificKeyframeVector AnimatableValuePropertySpecificKeyframeVector;
+
+typedef KeyframeEffectModel<StringKeyframe> StringKeyframeEffectModel;
+typedef StringKeyframeEffectModel::KeyframeVector StringKeyframeVector;
+typedef StringKeyframeEffectModel::PropertySpecificKeyframeVector StringPropertySpecificKeyframeVector;
+
+DEFINE_TYPE_CASTS(KeyframeEffectModelBase, AnimationEffect, value, value->isKeyframeEffectModel(), value.isKeyframeEffectModel());
+DEFINE_TYPE_CASTS(AnimatableValueKeyframeEffectModel, KeyframeEffectModelBase, value, value->isAnimatableValueKeyframeEffectModel(), value.isAnimatableValueKeyframeEffectModel());
+
+inline const AnimatableValueKeyframeEffectModel* toAnimatableValueKeyframeEffectModel(const AnimationEffect* base)
+{
+ return toAnimatableValueKeyframeEffectModel(toKeyframeEffectModelBase(base));
+}
+
+inline AnimatableValueKeyframeEffectModel* toAnimatableValueKeyframeEffectModel(AnimationEffect* base)
+{
+ return toAnimatableValueKeyframeEffectModel(toKeyframeEffectModelBase(base));
+}
+
+template <>
+inline bool KeyframeEffectModel<AnimatableValueKeyframe>::isAnimatableValueKeyframeEffectModel() const { return true; }
+
+template <>
+inline bool KeyframeEffectModel<StringKeyframe>::isStringKeyframeEffectModel() const { return true; }
+
+} // namespace WebCore
+
+#endif // KeyframeEffectModel_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp b/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp
new file mode 100644
index 00000000000..7287f9ac16f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/KeyframeEffectModelTest.cpp
@@ -0,0 +1,564 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/KeyframeEffectModel.h"
+
+#include "core/animation/AnimatableLength.h"
+#include "core/animation/AnimatableUnknown.h"
+#include "core/animation/interpolation/LegacyStyleInterpolation.h"
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/parser/BisonCSSParser.h"
+#include "core/css/resolver/CSSToStyleMap.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+const double duration = 1.0;
+
+PassRefPtrWillBeRawPtr<AnimatableValue> unknownAnimatableValue(double n)
+{
+ return AnimatableUnknown::create(CSSPrimitiveValue::create(n, CSSPrimitiveValue::CSS_UNKNOWN).get());
+}
+
+PassRefPtrWillBeRawPtr<AnimatableValue> pixelAnimatableValue(double n)
+{
+ return AnimatableLength::create(Length(n, Fixed), 1);
+}
+
+AnimatableValueKeyframeVector keyframesAtZeroAndOne(PassRefPtrWillBeRawPtr<AnimatableValue> zeroValue, PassRefPtrWillBeRawPtr<AnimatableValue> oneValue)
+{
+ AnimatableValueKeyframeVector keyframes(2);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, zeroValue.get());
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(1.0);
+ keyframes[1]->setPropertyValue(CSSPropertyLeft, oneValue.get());
+ return keyframes;
+}
+
+void expectProperty(CSSPropertyID property, PassRefPtrWillBeRawPtr<Interpolation> interpolationValue)
+{
+ LegacyStyleInterpolation* interpolation = toLegacyStyleInterpolation(interpolationValue.get());
+ ASSERT_EQ(property, interpolation->id());
+}
+
+void expectDoubleValue(double expectedValue, PassRefPtrWillBeRawPtr<Interpolation> interpolationValue)
+{
+ LegacyStyleInterpolation* interpolation = toLegacyStyleInterpolation(interpolationValue.get());
+ RefPtrWillBeRawPtr<AnimatableValue> value = interpolation->currentValue();
+
+ ASSERT_TRUE(value->isLength() || value->isUnknown());
+
+ double actualValue;
+ if (value->isLength())
+ actualValue = toAnimatableLength(value.get())->length(1, ValueRangeAll).value();
+ else
+ actualValue = toCSSPrimitiveValue(toAnimatableUnknown(value.get())->toCSSValue().get())->getDoubleValue();
+
+ EXPECT_FLOAT_EQ(static_cast<float>(expectedValue), actualValue);
+}
+
+Interpolation* findValue(WillBeHeapVector<RefPtrWillBeMember<Interpolation> >& values, CSSPropertyID id)
+{
+ for (size_t i = 0; i < values.size(); ++i) {
+ LegacyStyleInterpolation* value = toLegacyStyleInterpolation(values.at(i).get());
+ if (value->id() == id)
+ return value;
+ }
+ return 0;
+}
+
+
+TEST(AnimationKeyframeEffectModel, BasicOperation)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > values = effect->sample(0, 0.6, duration);
+ ASSERT_EQ(1UL, values->size());
+ expectProperty(CSSPropertyLeft, values->at(0));
+ expectDoubleValue(5.0, values->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, CompositeReplaceNonInterpolable)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
+ keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
+ keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(5.0, effect->sample(0, 0.6, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, CompositeReplace)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
+ keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
+ keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(3.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6, duration)->at(0));
+}
+
+// FIXME: Re-enable this test once compositing of CompositeAdd is supported.
+TEST(AnimationKeyframeEffectModel, DISABLED_CompositeAdd)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
+ keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
+ keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, CompositeEaseIn)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
+ RefPtrWillBeRawPtr<CSSValue> timingFunction = BisonCSSParser::parseAnimationTimingFunctionValue("ease-in");
+ keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
+ keyframes[0]->setEasing(CSSToStyleMap::mapAnimationTimingFunction(timingFunction.get(), true));
+ keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(3.8579516, effect->sample(0, 0.6, duration)->at(0));
+ expectDoubleValue(3.8582394, effect->sample(0, 0.6, duration * 100)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, CompositeCubicBezier)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
+ RefPtrWillBeRawPtr<CSSValue> timingFunction = BisonCSSParser::parseAnimationTimingFunctionValue("cubic-bezier(0.42, 0, 0.58, 1)");
+ keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
+ keyframes[0]->setEasing(CSSToStyleMap::mapAnimationTimingFunction(timingFunction.get(), true));
+ keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(4.3363357, effect->sample(0, 0.6, duration)->at(0));
+ expectDoubleValue(4.3362322, effect->sample(0, 0.6, duration * 1000)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, ExtrapolateReplaceNonInterpolable)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
+ keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
+ keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(5.0, effect->sample(0, 1.6, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, ExtrapolateReplace)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
+ keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
+ expectDoubleValue(3.0 * -0.6 + 5.0 * 1.6, effect->sample(0, 1.6, duration)->at(0));
+}
+
+// FIXME: Re-enable this test once compositing of CompositeAdd is supported.
+TEST(AnimationKeyframeEffectModel, DISABLED_ExtrapolateAdd)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
+ keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
+ keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue((7.0 + 3.0) * -0.6 + (7.0 + 5.0) * 1.6, effect->sample(0, 1.6, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, ZeroKeyframes)
+{
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(AnimatableValueKeyframeVector());
+ EXPECT_TRUE(effect->sample(0, 0.5, duration)->isEmpty());
+}
+
+// FIXME: Re-enable this test once compositing of CompositeAdd is supported.
+TEST(AnimationKeyframeEffectModel, DISABLED_SingleKeyframeAtOffsetZero)
+{
+ AnimatableValueKeyframeVector keyframes(1);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(3.0, effect->sample(0, 0.6, duration)->at(0));
+}
+
+// FIXME: Re-enable this test once compositing of CompositeAdd is supported.
+TEST(AnimationKeyframeEffectModel, DISABLED_SingleKeyframeAtOffsetOne)
+{
+ AnimatableValueKeyframeVector keyframes(1);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(1.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(7.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, MoreThanTwoKeyframes)
+{
+ AnimatableValueKeyframeVector keyframes(3);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(0.5);
+ keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[2]->setOffset(1.0);
+ keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(4.0, effect->sample(0, 0.3, duration)->at(0));
+ expectDoubleValue(5.0, effect->sample(0, 0.8, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, EndKeyframeOffsetsUnspecified)
+{
+ AnimatableValueKeyframeVector keyframes(3);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(0.5);
+ keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(3.0, effect->sample(0, 0.1, duration)->at(0));
+ expectDoubleValue(4.0, effect->sample(0, 0.6, duration)->at(0));
+ expectDoubleValue(5.0, effect->sample(0, 0.9, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, SampleOnKeyframe)
+{
+ AnimatableValueKeyframeVector keyframes(3);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(0.5);
+ keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[2]->setOffset(1.0);
+ keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(3.0, effect->sample(0, 0.0, duration)->at(0));
+ expectDoubleValue(4.0, effect->sample(0, 0.5, duration)->at(0));
+ expectDoubleValue(5.0, effect->sample(0, 1.0, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, MultipleKeyframesWithSameOffset)
+{
+ AnimatableValueKeyframeVector keyframes(9);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(0.0).get());
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(0.1);
+ keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(1.0).get());
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[2]->setOffset(0.1);
+ keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(2.0).get());
+ keyframes[3] = AnimatableValueKeyframe::create();
+ keyframes[3]->setOffset(0.5);
+ keyframes[3]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
+ keyframes[4] = AnimatableValueKeyframe::create();
+ keyframes[4]->setOffset(0.5);
+ keyframes[4]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
+ keyframes[5] = AnimatableValueKeyframe::create();
+ keyframes[5]->setOffset(0.5);
+ keyframes[5]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
+ keyframes[6] = AnimatableValueKeyframe::create();
+ keyframes[6]->setOffset(0.9);
+ keyframes[6]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(6.0).get());
+ keyframes[7] = AnimatableValueKeyframe::create();
+ keyframes[7]->setOffset(0.9);
+ keyframes[7]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(7.0).get());
+ keyframes[8] = AnimatableValueKeyframe::create();
+ keyframes[8]->setOffset(1.0);
+ keyframes[8]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(7.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(0.0, effect->sample(0, 0.0, duration)->at(0));
+ expectDoubleValue(2.0, effect->sample(0, 0.2, duration)->at(0));
+ expectDoubleValue(3.0, effect->sample(0, 0.4, duration)->at(0));
+ expectDoubleValue(5.0, effect->sample(0, 0.5, duration)->at(0));
+ expectDoubleValue(5.0, effect->sample(0, 0.6, duration)->at(0));
+ expectDoubleValue(6.0, effect->sample(0, 0.8, duration)->at(0));
+ expectDoubleValue(7.0, effect->sample(0, 1.0, duration)->at(0));
+}
+
+// FIXME: Re-enable this test once compositing of CompositeAdd is supported.
+TEST(AnimationKeyframeEffectModel, DISABLED_PerKeyframeComposite)
+{
+ AnimatableValueKeyframeVector keyframes(2);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(3.0).get());
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(1.0);
+ keyframes[1]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0).get());
+ keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(3.0 * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, MultipleProperties)
+{
+ AnimatableValueKeyframeVector keyframes(2);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
+ keyframes[0]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(4.0).get());
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(1.0);
+ keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
+ keyframes[1]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(6.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > values = effect->sample(0, 0.6, duration);
+ EXPECT_EQ(2UL, values->size());
+ Interpolation* leftValue = findValue(*values.get(), CSSPropertyLeft);
+ ASSERT_TRUE(leftValue);
+ expectDoubleValue(5.0, leftValue);
+ Interpolation* rightValue = findValue(*values.get(), CSSPropertyRight);
+ ASSERT_TRUE(rightValue);
+ expectDoubleValue(6.0, rightValue);
+}
+
+// FIXME: Re-enable this test once compositing of CompositeAdd is supported.
+TEST(AnimationKeyframeEffectModel, DISABLED_RecompositeCompositableValue)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
+ keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
+ keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > values = effect->sample(0, 0.6, duration);
+ expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, values->at(0));
+ expectDoubleValue((9.0 + 3.0) * 0.4 + (9.0 + 5.0) * 0.6, values->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, MultipleIterations)
+{
+ AnimatableValueKeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(1.0), pixelAnimatableValue(3.0));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ expectDoubleValue(2.0, effect->sample(0, 0.5, duration)->at(0));
+ expectDoubleValue(2.0, effect->sample(1, 0.5, duration)->at(0));
+ expectDoubleValue(2.0, effect->sample(2, 0.5, duration)->at(0));
+}
+
+// FIXME: Re-enable this test once compositing of CompositeAdd is supported.
+TEST(AnimationKeyframeEffectModel, DISABLED_DependsOnUnderlyingValue)
+{
+ AnimatableValueKeyframeVector keyframes(3);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.0);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0).get());
+ keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(0.5);
+ keyframes[1]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0).get());
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[2]->setOffset(1.0);
+ keyframes[2]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ EXPECT_TRUE(effect->sample(0, 0, duration)->at(0));
+ EXPECT_TRUE(effect->sample(0, 0.1, duration)->at(0));
+ EXPECT_TRUE(effect->sample(0, 0.25, duration)->at(0));
+ EXPECT_TRUE(effect->sample(0, 0.4, duration)->at(0));
+ EXPECT_FALSE(effect->sample(0, 0.5, duration)->at(0));
+ EXPECT_FALSE(effect->sample(0, 0.6, duration)->at(0));
+ EXPECT_FALSE(effect->sample(0, 0.75, duration)->at(0));
+ EXPECT_FALSE(effect->sample(0, 0.8, duration)->at(0));
+ EXPECT_FALSE(effect->sample(0, 1, duration)->at(0));
+}
+
+TEST(AnimationKeyframeEffectModel, AddSyntheticKeyframes)
+{
+ AnimatableValueKeyframeVector keyframes(1);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.5);
+ keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
+
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ const AnimatableValuePropertySpecificKeyframeVector& propertySpecificKeyframes = effect->getPropertySpecificKeyframes(CSSPropertyLeft);
+ EXPECT_EQ(3U, propertySpecificKeyframes.size());
+ EXPECT_DOUBLE_EQ(0.0, propertySpecificKeyframes[0]->offset());
+ EXPECT_DOUBLE_EQ(0.5, propertySpecificKeyframes[1]->offset());
+ EXPECT_DOUBLE_EQ(1.0, propertySpecificKeyframes[2]->offset());
+}
+
+TEST(AnimationKeyframeEffectModel, ToKeyframeEffectModel)
+{
+ AnimatableValueKeyframeVector keyframes(0);
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+
+ AnimationEffect* baseEffect = effect.get();
+ EXPECT_TRUE(toAnimatableValueKeyframeEffectModel(baseEffect));
+}
+
+} // namespace
+
+namespace WebCore {
+
+class KeyframeEffectModelTest : public ::testing::Test {
+public:
+ static KeyframeVector normalizedKeyframes(const KeyframeVector& keyframes)
+ {
+ return KeyframeEffectModelBase::normalizedKeyframes(keyframes);
+ }
+};
+
+TEST_F(KeyframeEffectModelTest, NotLooselySorted)
+{
+ KeyframeVector keyframes(4);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[1]->setOffset(9);
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[3] = AnimatableValueKeyframe::create();
+ keyframes[3]->setOffset(1);
+
+ const KeyframeVector result = normalizedKeyframes(keyframes);
+ EXPECT_EQ(0U, result.size());
+}
+
+TEST_F(KeyframeEffectModelTest, LastOne)
+{
+ KeyframeVector keyframes(3);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(-1);
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[2]->setOffset(2);
+
+ const KeyframeVector result = normalizedKeyframes(keyframes);
+ EXPECT_EQ(1U, result.size());
+ EXPECT_DOUBLE_EQ(1.0, result[0]->offset());
+}
+
+TEST_F(KeyframeEffectModelTest, FirstZero)
+{
+ KeyframeVector keyframes(3);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(-1);
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[2]->setOffset(0.25);
+
+ const KeyframeVector result = normalizedKeyframes(keyframes);
+ EXPECT_EQ(2U, result.size());
+ EXPECT_DOUBLE_EQ(0.0, result[0]->offset());
+ EXPECT_DOUBLE_EQ(0.25, result[1]->offset());
+}
+
+TEST_F(KeyframeEffectModelTest, EvenlyDistributed1)
+{
+ KeyframeVector keyframes(5);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0.125);
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[3] = AnimatableValueKeyframe::create();
+ keyframes[4] = AnimatableValueKeyframe::create();
+ keyframes[4]->setOffset(0.625);
+
+ const KeyframeVector result = normalizedKeyframes(keyframes);
+ EXPECT_EQ(5U, result.size());
+ EXPECT_DOUBLE_EQ(0.125, result[0]->offset());
+ EXPECT_DOUBLE_EQ(0.25, result[1]->offset());
+ EXPECT_DOUBLE_EQ(0.375, result[2]->offset());
+ EXPECT_DOUBLE_EQ(0.5, result[3]->offset());
+ EXPECT_DOUBLE_EQ(0.625, result[4]->offset());
+}
+
+TEST_F(KeyframeEffectModelTest, EvenlyDistributed2)
+{
+ KeyframeVector keyframes(8);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(-0.1);
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[3] = AnimatableValueKeyframe::create();
+ keyframes[4] = AnimatableValueKeyframe::create();
+ keyframes[4]->setOffset(0.75);
+ keyframes[5] = AnimatableValueKeyframe::create();
+ keyframes[6] = AnimatableValueKeyframe::create();
+ keyframes[7] = AnimatableValueKeyframe::create();
+ keyframes[7]->setOffset(1.1);
+
+ const KeyframeVector result = normalizedKeyframes(keyframes);
+ EXPECT_EQ(6U, result.size());
+ EXPECT_DOUBLE_EQ(0.0, result[0]->offset());
+ EXPECT_DOUBLE_EQ(0.25, result[1]->offset());
+ EXPECT_DOUBLE_EQ(0.5, result[2]->offset());
+ EXPECT_DOUBLE_EQ(0.75, result[3]->offset());
+ EXPECT_DOUBLE_EQ(0.875, result[4]->offset());
+ EXPECT_DOUBLE_EQ(1.0, result[5]->offset());
+}
+
+TEST_F(KeyframeEffectModelTest, EvenlyDistributed3)
+{
+ KeyframeVector keyframes(12);
+ keyframes[0] = AnimatableValueKeyframe::create();
+ keyframes[0]->setOffset(0);
+ keyframes[1] = AnimatableValueKeyframe::create();
+ keyframes[2] = AnimatableValueKeyframe::create();
+ keyframes[3] = AnimatableValueKeyframe::create();
+ keyframes[4] = AnimatableValueKeyframe::create();
+ keyframes[4]->setOffset(0.5);
+ keyframes[5] = AnimatableValueKeyframe::create();
+ keyframes[6] = AnimatableValueKeyframe::create();
+ keyframes[7] = AnimatableValueKeyframe::create();
+ keyframes[7]->setOffset(0.8);
+ keyframes[8] = AnimatableValueKeyframe::create();
+ keyframes[9] = AnimatableValueKeyframe::create();
+ keyframes[10] = AnimatableValueKeyframe::create();
+ keyframes[11] = AnimatableValueKeyframe::create();
+
+ const KeyframeVector result = normalizedKeyframes(keyframes);
+ EXPECT_EQ(12U, result.size());
+ EXPECT_DOUBLE_EQ(0.0, result[0]->offset());
+ EXPECT_DOUBLE_EQ(0.125, result[1]->offset());
+ EXPECT_DOUBLE_EQ(0.25, result[2]->offset());
+ EXPECT_DOUBLE_EQ(0.375, result[3]->offset());
+ EXPECT_DOUBLE_EQ(0.5, result[4]->offset());
+ EXPECT_DOUBLE_EQ(0.6, result[5]->offset());
+ EXPECT_DOUBLE_EQ(0.7, result[6]->offset());
+ EXPECT_DOUBLE_EQ(0.8, result[7]->offset());
+ EXPECT_DOUBLE_EQ(0.85, result[8]->offset());
+ EXPECT_DOUBLE_EQ(0.9, result[9]->offset());
+ EXPECT_DOUBLE_EQ(0.95, result[10]->offset());
+ EXPECT_DOUBLE_EQ(1.0, result[11]->offset());
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/Player.cpp b/chromium/third_party/WebKit/Source/core/animation/Player.cpp
deleted file mode 100644
index 2fabdd15e17..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/Player.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include "config.h"
-#include "core/animation/Player.h"
-
-#include "core/animation/Animation.h"
-#include "core/animation/DocumentTimeline.h"
-
-namespace WebCore {
-
-namespace {
-
-double effectiveTime(double time) { return isNull(time) ? 0 : time; }
-
-} // namespace
-
-PassRefPtr<Player> Player::create(DocumentTimeline& timeline, TimedItem* content)
-{
- return adoptRef(new Player(timeline, content));
-}
-
-Player::Player(DocumentTimeline& timeline, TimedItem* content)
- : m_pauseStartTime(nullValue())
- , m_playbackRate(1)
- , m_timeDrift(0)
- , m_startTime(nullValue())
- , m_content(content)
- , m_timeline(timeline)
- , m_isPausedForTesting(false)
-{
- if (m_content)
- m_content->attach(this);
-}
-
-Player::~Player()
-{
- if (m_content)
- m_content->detach();
-}
-
-void Player::setStartTime(double startTime)
-{
- ASSERT(!isNull(startTime));
- ASSERT(!hasStartTime());
- m_startTime = startTime;
- update();
-}
-
-double Player::currentTimeBeforeDrift() const
-{
- if (isNull(m_startTime))
- return 0;
- return (effectiveTime(m_timeline.currentTime()) - startTime()) * m_playbackRate;
-}
-
-bool Player::maybeStartAnimationOnCompositor()
-{
- // FIXME: Support starting compositor animations that have a fixed
- // start time.
- ASSERT(!hasStartTime());
- if (!m_content || !m_content->isAnimation())
- return false;
-
- return toAnimation(m_content.get())->maybeStartAnimationOnCompositor();
-}
-
-bool Player::hasActiveAnimationsOnCompositor()
-{
- if (!m_content || !m_content->isAnimation())
- return false;
- return toAnimation(m_content.get())->hasActiveAnimationsOnCompositor();
-}
-
-void Player::cancelAnimationOnCompositor()
-{
- if (hasActiveAnimationsOnCompositor())
- toAnimation(m_content.get())->cancelAnimationOnCompositor();
-}
-
-double Player::pausedTimeDrift() const
-{
- ASSERT(pausedInternal());
- return currentTimeBeforeDrift() - m_pauseStartTime;
-}
-
-double Player::timeDrift() const
-{
- return pausedInternal() ? pausedTimeDrift() : m_timeDrift;
-}
-
-double Player::currentTime() const
-{
- return currentTimeBeforeDrift() - timeDrift();
-}
-
-bool Player::update(double* timeToEffectChange, bool* didTriggerStyleRecalc)
-{
- if (!m_content) {
- if (timeToEffectChange)
- *timeToEffectChange = std::numeric_limits<double>::infinity();
- if (didTriggerStyleRecalc)
- *didTriggerStyleRecalc = false;
- return false;
- }
-
- double inheritedTime = isNull(m_timeline.currentTime()) ? nullValue() : currentTime();
- bool didTriggerStyleRecalcLocal = m_content->updateInheritedTime(inheritedTime);
-
- if (timeToEffectChange)
- *timeToEffectChange = m_content->timeToEffectChange();
- if (didTriggerStyleRecalc)
- *didTriggerStyleRecalc = didTriggerStyleRecalcLocal;
- return m_content->isCurrent() || m_content->isInEffect();
-}
-
-void Player::cancel()
-{
- if (!m_content)
- return;
-
- ASSERT(m_content->player() == this);
- m_content->detach();
- m_content = 0;
-}
-
-void Player::setCurrentTime(double seekTime)
-{
- if (pausedInternal())
- m_pauseStartTime = seekTime;
- else
- m_timeDrift = currentTimeBeforeDrift() - seekTime;
-
- if (m_isPausedForTesting && hasActiveAnimationsOnCompositor())
- toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTime());
- update();
-}
-
-void Player::pauseForTesting()
-{
- RELEASE_ASSERT(!paused());
- if (!m_isPausedForTesting && hasActiveAnimationsOnCompositor())
- toAnimation(m_content.get())->pauseAnimationForTestingOnCompositor(currentTime());
- m_isPausedForTesting = true;
- setPausedImpl(true);
-}
-
-void Player::setPaused(bool newValue)
-{
- ASSERT(!m_isPausedForTesting);
- setPausedImpl(newValue);
-}
-
-void Player::setPausedImpl(bool newValue)
-{
- if (pausedInternal() == newValue)
- return;
-
- if (newValue) {
- // FIXME: resume compositor animation rather than pull back to main-thread
- cancelAnimationOnCompositor();
- m_pauseStartTime = currentTime();
- } else {
- m_timeDrift = pausedTimeDrift();
- m_pauseStartTime = nullValue();
- }
-}
-
-void Player::setPlaybackRate(double newRate)
-{
- double previousTime = currentTime();
- m_playbackRate = newRate;
- setCurrentTime(previousTime);
-}
-
-} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/Player.h b/chromium/third_party/WebKit/Source/core/animation/Player.h
deleted file mode 100644
index df80447d51e..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/Player.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef Player_h
-#define Player_h
-
-#include "core/animation/TimedItem.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class DocumentTimeline;
-
-class Player FINAL : public RefCounted<Player> {
-
-public:
- ~Player();
- static PassRefPtr<Player> create(DocumentTimeline&, TimedItem*);
-
- // Returns whether this player is still current or in effect.
- // timeToEffectChange returns:
- // infinity - if this player is no longer in effect
- // 0 - if this player requires an update on the next frame
- // n - if this player requires an update after 'n' units of time
- bool update(double* timeToEffectChange = 0, bool* didTriggerStyleRecalc = 0);
- void cancel();
-
- double currentTime() const;
- void setCurrentTime(double);
-
- bool paused() const { return !m_isPausedForTesting && pausedInternal(); }
- void setPaused(bool);
-
- double playbackRate() const { return m_playbackRate; }
- void setPlaybackRate(double);
- double timeDrift() const;
- DocumentTimeline& timeline() { return m_timeline; }
-
- bool hasStartTime() const { return !isNull(m_startTime); }
- double startTime() const { return m_startTime; }
- void setStartTime(double);
-
- TimedItem* source() { return m_content.get(); }
-
- // Pausing via this method is not reflected in the value returned by
- // paused() and must never overlap with pausing via setPaused().
- void pauseForTesting();
-
- bool maybeStartAnimationOnCompositor();
- void cancelAnimationOnCompositor();
- bool hasActiveAnimationsOnCompositor();
-
-private:
- Player(DocumentTimeline&, TimedItem*);
- inline double pausedTimeDrift() const;
- inline double currentTimeBeforeDrift() const;
-
-
- void setPausedImpl(bool);
- // Reflects all pausing, including via pauseForTesting().
- bool pausedInternal() const { return !isNull(m_pauseStartTime); }
-
- double m_pauseStartTime;
- double m_playbackRate;
- double m_timeDrift;
- double m_startTime;
-
- RefPtr<TimedItem> m_content;
- DocumentTimeline& m_timeline;
- bool m_isPausedForTesting;
-};
-
-} // namespace
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/PlayerTest.cpp b/chromium/third_party/WebKit/Source/core/animation/PlayerTest.cpp
deleted file mode 100644
index 4ff5badddba..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/PlayerTest.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/Player.h"
-
-#include "core/animation/ActiveAnimations.h"
-#include "core/animation/Animation.h"
-#include "core/animation/AnimationClock.h"
-#include "core/animation/DocumentTimeline.h"
-#include "core/dom/Document.h"
-#include "core/dom/QualifiedName.h"
-#include "platform/weborigin/KURL.h"
-#include <gtest/gtest.h>
-
-using namespace WebCore;
-
-namespace {
-
-class AnimationPlayerTest : public ::testing::Test {
-protected:
- virtual void SetUp()
- {
- document = Document::create();
- document->animationClock().resetTimeForTesting();
- timeline = DocumentTimeline::create(document.get());
- player = Player::create(*timeline, 0);
- player->setStartTime(0);
- timeline->setZeroTime(0);
- }
-
- bool updateTimeline(double time, double* timeToEffectChange = 0)
- {
- document->animationClock().updateTime(time);
- // The timeline does not know about our player, so we have to explicitly call update().
- return player->update(timeToEffectChange);
- }
-
- RefPtr<Document> document;
- RefPtr<DocumentTimeline> timeline;
- RefPtr<Player> player;
-};
-
-TEST_F(AnimationPlayerTest, InitialState)
-{
- EXPECT_EQ(0, timeline->currentTime());
- EXPECT_EQ(0, player->currentTime());
- EXPECT_FALSE(player->paused());
- EXPECT_EQ(1, player->playbackRate());
- EXPECT_EQ(0, player->startTime());
- EXPECT_EQ(0, player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, PauseUnpause)
-{
- updateTimeline(200);
- player->setPaused(true);
- EXPECT_TRUE(player->paused());
- EXPECT_EQ(200, player->currentTime());
- EXPECT_EQ(0, player->timeDrift());
-
- updateTimeline(400);
- player->setPaused(false);
- EXPECT_FALSE(player->paused());
- EXPECT_EQ(200, player->currentTime());
- EXPECT_EQ(200, player->timeDrift());
-
- updateTimeline(600);
- EXPECT_EQ(400, player->currentTime());
- EXPECT_EQ(200, player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, PauseBeforeTimelineStarted)
-{
- player->setPaused(true);
- EXPECT_TRUE(player->paused());
- EXPECT_EQ(0, player->currentTime());
- EXPECT_EQ(0, player->timeDrift());
-
- player->setPaused(false);
- EXPECT_FALSE(player->paused());
- EXPECT_EQ(0, player->currentTime());
- EXPECT_EQ(0, player->timeDrift());
-
- player->setPaused(true);
- updateTimeline(100);
- EXPECT_TRUE(player->paused());
- EXPECT_EQ(0, player->currentTime());
- EXPECT_EQ(100, player->timeDrift());
-
- player->setPaused(false);
- EXPECT_EQ(0, player->currentTime());
- EXPECT_EQ(100, player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, PauseBeforeStartTimeSet)
-{
- player = Player::create(*timeline, 0);
- updateTimeline(100);
- EXPECT_EQ(0, player->currentTime());
-
- player->setPaused(true);
- updateTimeline(200);
- EXPECT_EQ(0, player->currentTime());
-
- player->setStartTime(150);
- EXPECT_EQ(0, player->currentTime());
-
- player->setPaused(false);
- EXPECT_EQ(0, player->currentTime());
-
- updateTimeline(300);
- EXPECT_EQ(100, player->currentTime());
-}
-
-TEST_F(AnimationPlayerTest, SetCurrentTime)
-{
- updateTimeline(0);
- player->setCurrentTime(250);
- EXPECT_EQ(250, player->currentTime());
- EXPECT_EQ(-250, player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, SetStartTime)
-{
- updateTimeline(0);
- player = Player::create(*timeline, 0);
- EXPECT_FALSE(player->hasStartTime());
- EXPECT_TRUE(isNull(player->startTime()));
- EXPECT_EQ(0, player->currentTime());
-
- updateTimeline(100);
- player->setStartTime(50);
- EXPECT_TRUE(player->hasStartTime());
- EXPECT_EQ(50, player->startTime());
- EXPECT_EQ(50, player->currentTime());
-
- updateTimeline(200);
- EXPECT_EQ(150, player->currentTime());
-}
-
-
-TEST_F(AnimationPlayerTest, SetCurrentTimeBeforeTimelineStarted)
-{
- player->setCurrentTime(250);
- EXPECT_EQ(250, player->currentTime());
- EXPECT_EQ(-250, player->timeDrift());
-
- updateTimeline(0);
- EXPECT_EQ(250, player->currentTime());
-}
-
-TEST_F(AnimationPlayerTest, SetCurrentTimeBeforeStartTimeSet)
-{
- updateTimeline(0);
- player = Player::create(*timeline, 0);
-
- player->setCurrentTime(250);
- EXPECT_EQ(250, player->currentTime());
- EXPECT_EQ(-250, player->timeDrift());
-
- updateTimeline(100);
- player->setStartTime(50);
- EXPECT_EQ(300, player->currentTime());
-}
-
-TEST_F(AnimationPlayerTest, SetPlaybackRate)
-{
- updateTimeline(0);
- player->setPlaybackRate(2);
- EXPECT_EQ(2, player->playbackRate());
- EXPECT_EQ(0, player->currentTime());
- EXPECT_EQ(0, player->timeDrift());
-
- updateTimeline(100);
- EXPECT_EQ(200, player->currentTime());
- EXPECT_EQ(0, player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, SetPlaybackRateBeforeTimelineStarted)
-{
- player->setPlaybackRate(2);
- EXPECT_EQ(0, player->currentTime());
- EXPECT_EQ(0, player->timeDrift());
-
- updateTimeline(100);
- EXPECT_EQ(200, player->currentTime());
- EXPECT_EQ(0, player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, SetPlaybackRateWhilePaused)
-{
- updateTimeline(100);
- player->setPaused(true);
- player->setPlaybackRate(2);
- EXPECT_EQ(100, player->currentTime());
- EXPECT_EQ(100, player->timeDrift());
-
- updateTimeline(200);
- player->setPaused(false);
- EXPECT_EQ(100, player->currentTime());
- EXPECT_EQ(300, player->timeDrift());
-
- updateTimeline(250);
- EXPECT_EQ(200, player->currentTime());
- EXPECT_EQ(300, player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, SetPlaybackRateNaN)
-{
- updateTimeline(0);
- player->setPlaybackRate(nullValue());
- EXPECT_TRUE(isNull(player->playbackRate()));
- EXPECT_TRUE(isNull(player->currentTime()));
- EXPECT_TRUE(isNull(player->timeDrift()));
-
- updateTimeline(100);
- EXPECT_TRUE(isNull(player->currentTime()));
- EXPECT_TRUE(isNull(player->timeDrift()));
-}
-
-TEST_F(AnimationPlayerTest, SetPlaybackRateInfinity)
-{
- updateTimeline(0);
- player->setPlaybackRate(std::numeric_limits<double>::infinity());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), player->playbackRate());
- EXPECT_TRUE(isNull(player->currentTime()));
- EXPECT_TRUE(isNull(player->timeDrift()));
-
- updateTimeline(100);
- EXPECT_TRUE(isNull(player->currentTime()));
- EXPECT_TRUE(isNull(player->timeDrift()));
-}
-
-TEST_F(AnimationPlayerTest, SetPlaybackRateMax)
-{
- updateTimeline(0);
- player->setPlaybackRate(std::numeric_limits<double>::max());
- EXPECT_EQ(std::numeric_limits<double>::max(), player->playbackRate());
- EXPECT_EQ(0, player->currentTime());
- EXPECT_EQ(0, player->timeDrift());
-
- updateTimeline(100);
- EXPECT_EQ(std::numeric_limits<double>::infinity(), player->currentTime());
-}
-
-TEST_F(AnimationPlayerTest, SetCurrentTimeNan)
-{
- updateTimeline(0);
- player->setCurrentTime(nullValue());
- EXPECT_TRUE(isNull(player->currentTime()));
- EXPECT_TRUE(isNull(player->timeDrift()));
-
- updateTimeline(100);
- EXPECT_TRUE(isNull(player->currentTime()));
- EXPECT_TRUE(isNull(player->timeDrift()));
-}
-
-TEST_F(AnimationPlayerTest, SetCurrentTimeInfinity)
-{
- updateTimeline(0);
- player->setCurrentTime(std::numeric_limits<double>::infinity());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), player->currentTime());
- EXPECT_EQ(-std::numeric_limits<double>::infinity(), player->timeDrift());
-
- updateTimeline(100);
- EXPECT_EQ(std::numeric_limits<double>::infinity(), player->currentTime());
- EXPECT_EQ(-std::numeric_limits<double>::infinity(), player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, SetCurrentTimeMax)
-{
- updateTimeline(0);
- player->setCurrentTime(std::numeric_limits<double>::max());
- EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTime());
- EXPECT_EQ(-std::numeric_limits<double>::max(), player->timeDrift());
-
- updateTimeline(100);
- EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTime());
- EXPECT_EQ(-std::numeric_limits<double>::max(), player->timeDrift());
-}
-
-TEST_F(AnimationPlayerTest, EmptyPlayersDontUpdateEffects)
-{
- double timeToNextEffect;
- updateTimeline(0, &timeToNextEffect);
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timeToNextEffect);
-
- timeToNextEffect = 0;
- updateTimeline(1234, &timeToNextEffect);
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timeToNextEffect);
-}
-
-TEST_F(AnimationPlayerTest, PlayersReturnTimeToNextEffect)
-{
- Timing timing;
- timing.startDelay = 1;
- timing.iterationDuration = 1;
- timing.hasIterationDuration = true;
- RefPtr<Animation> animation = Animation::create(0, 0, timing);
- player = Player::create(*timeline, animation.get());
- player->setStartTime(0);
-
- double timeToNextEffect;
- updateTimeline(0, &timeToNextEffect);
- EXPECT_EQ(1, timeToNextEffect);
-
- updateTimeline(0.5, &timeToNextEffect);
- EXPECT_EQ(0.5, timeToNextEffect);
-
- updateTimeline(1, &timeToNextEffect);
- EXPECT_EQ(0, timeToNextEffect);
-
- updateTimeline(1.5, &timeToNextEffect);
- EXPECT_EQ(0, timeToNextEffect);
-
- updateTimeline(2, &timeToNextEffect);
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timeToNextEffect);
-
- updateTimeline(3, &timeToNextEffect);
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timeToNextEffect);
-}
-
-TEST_F(AnimationPlayerTest, AttachedPlayers)
-{
- RefPtr<Element> element = document->createElement("foo", ASSERT_NO_EXCEPTION);
-
- Timing timing;
- RefPtr<Animation> animation = Animation::create(element, 0, timing);
- RefPtr<Player> player = Player::create(*timeline, animation.get());
- EXPECT_EQ(1U, element->activeAnimations()->players().find(player.get())->value);
-
- player.release();
- EXPECT_TRUE(element->activeAnimations()->players().isEmpty());
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/animation/SampledEffect.cpp b/chromium/third_party/WebKit/Source/core/animation/SampledEffect.cpp
new file mode 100644
index 00000000000..0c5e1548c71
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/SampledEffect.cpp
@@ -0,0 +1,66 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/SampledEffect.h"
+
+#include "core/animation/interpolation/StyleInterpolation.h"
+
+namespace WebCore {
+
+SampledEffect::SampledEffect(Animation* animation, PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > interpolations)
+ : m_animation(animation)
+#if !ENABLE(OILPAN)
+ , m_player(animation->player())
+#endif
+ , m_interpolations(interpolations)
+ , m_playerSortInfo(animation->player()->sortInfo())
+ , m_priority(animation->priority())
+{
+ ASSERT(m_interpolations && !m_interpolations->isEmpty());
+}
+
+bool SampledEffect::canChange() const
+{
+#if ENABLE(OILPAN)
+ return m_animation;
+#else
+ if (!m_animation)
+ return false;
+ // FIXME: This check won't be needed when Animation and AnimationPlayer are moved to Oilpan.
+ return !m_player->canFree();
+#endif
+}
+
+void SampledEffect::clear()
+{
+#if !ENABLE(OILPAN)
+ m_player = nullptr;
+#endif
+ m_animation = nullptr;
+ m_interpolations->clear();
+}
+
+void SampledEffect::removeReplacedInterpolationsIfNeeded(const BitArray<numCSSProperties>& replacedProperties)
+{
+ if (canChange() && m_animation->isCurrent())
+ return;
+
+ size_t dest = 0;
+ for (size_t i = 0; i < m_interpolations->size(); i++) {
+ if (!replacedProperties.get(toStyleInterpolation(m_interpolations->at(i).get())->id()))
+ m_interpolations->at(dest++) = m_interpolations->at(i);
+ }
+ m_interpolations->shrink(dest);
+}
+
+void SampledEffect::trace(Visitor* visitor)
+{
+ visitor->trace(m_animation);
+#if ENABLE(OILPAN)
+ visitor->trace(m_interpolations);
+#endif
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/SampledEffect.h b/chromium/third_party/WebKit/Source/core/animation/SampledEffect.h
new file mode 100644
index 00000000000..7b4f14617eb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/SampledEffect.h
@@ -0,0 +1,51 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SampledEffect_h
+#define SampledEffect_h
+
+#include "core/animation/Animation.h"
+#include "core/animation/AnimationPlayer.h"
+#include "core/animation/interpolation/Interpolation.h"
+#include "wtf/BitArray.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class SampledEffect : public NoBaseWillBeGarbageCollected<SampledEffect> {
+public:
+ static PassOwnPtrWillBeRawPtr<SampledEffect> create(Animation* animation, PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > interpolations)
+ {
+ return adoptPtrWillBeNoop(new SampledEffect(animation, interpolations));
+ }
+
+ bool canChange() const;
+ void clear();
+
+ const WillBeHeapVector<RefPtrWillBeMember<Interpolation> >& interpolations() const { return *m_interpolations; }
+ void setInterpolations(PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > interpolations) { m_interpolations = interpolations; }
+
+ Animation* animation() const { return m_animation; }
+ const AnimationPlayer::SortInfo& sortInfo() const { return m_playerSortInfo; }
+ Animation::Priority priority() const { return m_priority; }
+
+ void removeReplacedInterpolationsIfNeeded(const BitArray<numCSSProperties>&);
+
+ void trace(Visitor*);
+
+private:
+ SampledEffect(Animation*, PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > >);
+
+ RawPtrWillBeWeakMember<Animation> m_animation;
+#if !ENABLE(OILPAN)
+ RefPtr<AnimationPlayer> m_player;
+#endif
+ OwnPtrWillBeMember<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > m_interpolations;
+ AnimationPlayer::SortInfo m_playerSortInfo;
+ Animation::Priority m_priority;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/StringKeyframe.cpp b/chromium/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
new file mode 100644
index 00000000000..fe13572eb56
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
@@ -0,0 +1,152 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/StringKeyframe.h"
+
+#include "core/animation/css/CSSAnimations.h"
+#include "core/animation/interpolation/DefaultStyleInterpolation.h"
+#include "core/animation/interpolation/DeferredLegacyStyleInterpolation.h"
+#include "core/animation/interpolation/LegacyStyleInterpolation.h"
+#include "core/animation/interpolation/LengthStyleInterpolation.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/rendering/style/RenderStyle.h"
+
+namespace WebCore {
+
+StringKeyframe::StringKeyframe(const StringKeyframe& copyFrom)
+ : Keyframe(copyFrom.m_offset, copyFrom.m_composite, copyFrom.m_easing)
+ , m_propertySet(copyFrom.m_propertySet->mutableCopy())
+{
+}
+
+void StringKeyframe::setPropertyValue(CSSPropertyID property, const String& value, StyleSheetContents* styleSheetContents)
+{
+ ASSERT(property != CSSPropertyInvalid);
+ if (CSSAnimations::isAllowedAnimation(property))
+ m_propertySet->setProperty(property, value, false, styleSheetContents);
+}
+
+PropertySet StringKeyframe::properties() const
+{
+ // This is not used in time-critical code, so we probably don't need to
+ // worry about caching this result.
+ PropertySet properties;
+ for (unsigned i = 0; i < m_propertySet->propertyCount(); ++i)
+ properties.add(m_propertySet->propertyAt(i).id());
+ return properties;
+}
+
+PassRefPtrWillBeRawPtr<Keyframe> StringKeyframe::clone() const
+{
+ return adoptRefWillBeNoop(new StringKeyframe(*this));
+}
+PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::createPropertySpecificKeyframe(CSSPropertyID property) const
+{
+ return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset(), easing(), propertyValue(property), composite()));
+}
+
+void StringKeyframe::trace(Visitor* visitor)
+{
+ visitor->trace(m_propertySet);
+ Keyframe::trace(visitor);
+}
+
+StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, CSSValue* value, AnimationEffect::CompositeOperation op)
+ : Keyframe::PropertySpecificKeyframe(offset, easing, op)
+ , m_value(value)
+{ }
+
+StringKeyframe::PropertySpecificKeyframe::PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, CSSValue* value)
+ : Keyframe::PropertySpecificKeyframe(offset, easing, AnimationEffect::CompositeReplace)
+ , m_value(value)
+{
+ ASSERT(!isNull(m_offset));
+}
+
+PassRefPtrWillBeRawPtr<Interpolation> StringKeyframe::PropertySpecificKeyframe::createInterpolation(CSSPropertyID property, Keyframe::PropertySpecificKeyframe* end, Element* element) const
+{
+ CSSValue* fromCSSValue = m_value.get();
+ CSSValue* toCSSValue = toStringPropertySpecificKeyframe(end)->value();
+ ValueRange range = ValueRangeAll;
+
+ if (!CSSAnimations::isAnimatableProperty(property))
+ return DefaultStyleInterpolation::create(fromCSSValue, toCSSValue, property);
+
+ switch (property) {
+ case CSSPropertyBorderBottomWidth:
+ case CSSPropertyBorderLeftWidth:
+ case CSSPropertyBorderRightWidth:
+ case CSSPropertyBorderTopWidth:
+ case CSSPropertyFontSize:
+ case CSSPropertyHeight:
+ case CSSPropertyLineHeight:
+ case CSSPropertyMaxHeight:
+ case CSSPropertyMaxWidth:
+ case CSSPropertyMinHeight:
+ case CSSPropertyMinWidth:
+ case CSSPropertyOutlineWidth:
+ case CSSPropertyPaddingBottom:
+ case CSSPropertyPaddingLeft:
+ case CSSPropertyPaddingRight:
+ case CSSPropertyPaddingTop:
+ case CSSPropertyPerspective:
+ case CSSPropertyShapeMargin:
+ case CSSPropertyWidth:
+ range = ValueRangeNonNegative;
+ // Fall through
+ case CSSPropertyBottom:
+ case CSSPropertyLeft:
+ case CSSPropertyLetterSpacing:
+ case CSSPropertyMarginBottom:
+ case CSSPropertyMarginLeft:
+ case CSSPropertyMarginRight:
+ case CSSPropertyMarginTop:
+ case CSSPropertyOutlineOffset:
+ case CSSPropertyRight:
+ case CSSPropertyTop:
+ case CSSPropertyVerticalAlign:
+ case CSSPropertyWordSpacing:
+ if (LengthStyleInterpolation::canCreateFrom(*fromCSSValue) && LengthStyleInterpolation::canCreateFrom(*toCSSValue))
+ return LengthStyleInterpolation::create(fromCSSValue, toCSSValue, property, range);
+ break;
+ default:
+ break;
+ }
+
+ if (DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*fromCSSValue) || DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*toCSSValue))
+ return DeferredLegacyStyleInterpolation::create(fromCSSValue, toCSSValue, property);
+
+ // FIXME: Remove the use of AnimatableValues, RenderStyles and Elements here.
+ // FIXME: Remove this cache
+ ASSERT(element);
+ if (!m_animatableValueCache)
+ m_animatableValueCache = StyleResolver::createAnimatableValueSnapshot(*element, property, *fromCSSValue);
+
+ RefPtrWillBeRawPtr<AnimatableValue> to = StyleResolver::createAnimatableValueSnapshot(*element, property, *toCSSValue);
+ toStringPropertySpecificKeyframe(end)->m_animatableValueCache = to;
+
+ return LegacyStyleInterpolation::create(m_animatableValueCache.get(), to.release(), property);
+}
+
+PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::PropertySpecificKeyframe::neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const
+{
+ return adoptPtrWillBeNoop(new PropertySpecificKeyframe(offset, easing, 0, AnimationEffect::CompositeAdd));
+}
+
+PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> StringKeyframe::PropertySpecificKeyframe::cloneWithOffset(double offset) const
+{
+ Keyframe::PropertySpecificKeyframe* theClone = new PropertySpecificKeyframe(offset, m_easing, m_value.get());
+ toStringPropertySpecificKeyframe(theClone)->m_animatableValueCache = m_animatableValueCache;
+ return adoptPtrWillBeNoop(theClone);
+}
+
+void StringKeyframe::PropertySpecificKeyframe::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ visitor->trace(m_animatableValueCache);
+ Keyframe::PropertySpecificKeyframe::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/StringKeyframe.h b/chromium/third_party/WebKit/Source/core/animation/StringKeyframe.h
new file mode 100644
index 00000000000..c6a753e3a76
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/StringKeyframe.h
@@ -0,0 +1,79 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StringKeyframe_h
+#define StringKeyframe_h
+
+#include "core/animation/Keyframe.h"
+#include "core/css/StylePropertySet.h"
+
+namespace WebCore {
+
+class StyleSheetContents;
+
+class StringKeyframe : public Keyframe {
+public:
+ static PassRefPtrWillBeRawPtr<StringKeyframe> create()
+ {
+ return adoptRefWillBeNoop(new StringKeyframe);
+ }
+ void setPropertyValue(CSSPropertyID, const String& value, StyleSheetContents*);
+ void clearPropertyValue(CSSPropertyID property) { m_propertySet->removeProperty(property); }
+ CSSValue* propertyValue(CSSPropertyID property) const
+ {
+ int index = m_propertySet->findPropertyIndex(property);
+ RELEASE_ASSERT(index >= 0);
+ return m_propertySet->propertyAt(static_cast<unsigned>(index)).value();
+ }
+ virtual PropertySet properties() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ class PropertySpecificKeyframe : public Keyframe::PropertySpecificKeyframe {
+ public:
+ PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, CSSValue*, AnimationEffect::CompositeOperation);
+
+ CSSValue* value() const { return m_value.get(); }
+ virtual const PassRefPtrWillBeRawPtr<AnimatableValue> getAnimatableValue() const OVERRIDE FINAL {
+ return m_animatableValueCache.get();
+ }
+
+ virtual PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> neutralKeyframe(double offset, PassRefPtr<TimingFunction> easing) const OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<Interpolation> createInterpolation(CSSPropertyID, WebCore::Keyframe::PropertySpecificKeyframe* end, Element*) const OVERRIDE FINAL;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ private:
+ PropertySpecificKeyframe(double offset, PassRefPtr<TimingFunction> easing, CSSValue*);
+
+ virtual PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> cloneWithOffset(double offset) const;
+ virtual bool isStringPropertySpecificKeyframe() const OVERRIDE { return true; }
+
+ RefPtrWillBeMember<CSSValue> m_value;
+ mutable RefPtrWillBeMember<AnimatableValue> m_animatableValueCache;
+ };
+
+private:
+ StringKeyframe()
+ : m_propertySet(MutableStylePropertySet::create())
+ { }
+
+ StringKeyframe(const StringKeyframe& copyFrom);
+
+ virtual PassRefPtrWillBeRawPtr<Keyframe> clone() const OVERRIDE;
+ virtual PassOwnPtrWillBeRawPtr<Keyframe::PropertySpecificKeyframe> createPropertySpecificKeyframe(CSSPropertyID) const OVERRIDE;
+
+ virtual bool isStringKeyframe() const OVERRIDE { return true; }
+
+ RefPtrWillBeMember<MutableStylePropertySet> m_propertySet;
+};
+
+typedef StringKeyframe::PropertySpecificKeyframe StringPropertySpecificKeyframe;
+
+DEFINE_TYPE_CASTS(StringKeyframe, Keyframe, value, value->isStringKeyframe(), value.isStringKeyframe());
+DEFINE_TYPE_CASTS(StringPropertySpecificKeyframe, Keyframe::PropertySpecificKeyframe, value, value->isStringPropertySpecificKeyframe(), value.isStringPropertySpecificKeyframe());
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimedItem.cpp b/chromium/third_party/WebKit/Source/core/animation/TimedItem.cpp
deleted file mode 100644
index 3b7aa948c1f..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/TimedItem.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/TimedItem.h"
-
-#include "core/animation/Player.h"
-#include "core/animation/TimedItemCalculations.h"
-
-namespace WebCore {
-
-TimedItem::TimedItem(const Timing& timing, PassOwnPtr<EventDelegate> eventDelegate)
- : m_parent(0)
- , m_startTime(0)
- , m_player(0)
- , m_specified(timing)
- , m_eventDelegate(eventDelegate)
- , m_calculated()
- , m_isFirstSample(true)
- , m_needsUpdate(true)
- , m_lastUpdateTime(nullValue())
-{
- m_specified.assertValid();
-}
-
-bool TimedItem::updateInheritedTime(double inheritedTime) const
-{
- bool needsUpdate = m_needsUpdate || (m_lastUpdateTime != inheritedTime && !(isNull(m_lastUpdateTime) && isNull(inheritedTime)));
- m_needsUpdate = false;
- m_lastUpdateTime = inheritedTime;
-
- const double previousIteration = m_calculated.currentIteration;
- const Phase previousPhase = m_calculated.phase;
-
- const double localTime = inheritedTime - m_startTime;
- double timeToNextIteration = std::numeric_limits<double>::infinity();
- if (needsUpdate) {
- const double iterationDuration = m_specified.hasIterationDuration
- ? m_specified.iterationDuration
- : intrinsicIterationDuration();
- ASSERT(iterationDuration >= 0);
-
- // When iterationDuration = 0 and iterationCount = infinity, or vice-
- // versa, repeatedDuration should be 0, not NaN as operator*() would give.
- // FIXME: The spec is unclear about this.
- const double repeatedDuration = multiplyZeroAlwaysGivesZero(iterationDuration, m_specified.iterationCount);
- ASSERT(repeatedDuration >= 0);
- const double activeDuration = m_specified.playbackRate
- ? repeatedDuration / abs(m_specified.playbackRate)
- : std::numeric_limits<double>::infinity();
- ASSERT(activeDuration >= 0);
-
- const Phase currentPhase = calculatePhase(activeDuration, localTime, m_specified);
- // FIXME: parentPhase depends on groups being implemented.
- const TimedItem::Phase parentPhase = TimedItem::PhaseActive;
- const double activeTime = calculateActiveTime(activeDuration, localTime, parentPhase, currentPhase, m_specified);
-
- double currentIteration;
- double timeFraction;
- if (iterationDuration) {
- const double startOffset = multiplyZeroAlwaysGivesZero(m_specified.iterationStart, iterationDuration);
- ASSERT(startOffset >= 0);
- const double scaledActiveTime = calculateScaledActiveTime(activeDuration, activeTime, startOffset, m_specified);
- const double iterationTime = calculateIterationTime(iterationDuration, repeatedDuration, scaledActiveTime, startOffset, m_specified);
-
- currentIteration = calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, m_specified);
- timeFraction = calculateTransformedTime(currentIteration, iterationDuration, iterationTime, m_specified) / iterationDuration;
-
- if (!isNull(iterationTime)) {
- timeToNextIteration = (iterationDuration - iterationTime) / abs(m_specified.playbackRate);
- if (activeDuration - activeTime < timeToNextIteration)
- timeToNextIteration = std::numeric_limits<double>::infinity();
- }
- } else {
- const double localIterationDuration = 1;
- const double localRepeatedDuration = localIterationDuration * m_specified.iterationCount;
- ASSERT(localRepeatedDuration >= 0);
- const double localActiveDuration = m_specified.playbackRate ? localRepeatedDuration / abs(m_specified.playbackRate) : std::numeric_limits<double>::infinity();
- ASSERT(localActiveDuration >= 0);
- const double localLocalTime = localTime < m_specified.startDelay ? localTime : localActiveDuration + m_specified.startDelay;
- const TimedItem::Phase localCurrentPhase = calculatePhase(localActiveDuration, localLocalTime, m_specified);
- const double localActiveTime = calculateActiveTime(localActiveDuration, localLocalTime, parentPhase, localCurrentPhase, m_specified);
- const double startOffset = m_specified.iterationStart * localIterationDuration;
- ASSERT(startOffset >= 0);
- const double scaledActiveTime = calculateScaledActiveTime(localActiveDuration, localActiveTime, startOffset, m_specified);
- const double iterationTime = calculateIterationTime(localIterationDuration, localRepeatedDuration, scaledActiveTime, startOffset, m_specified);
-
- currentIteration = calculateCurrentIteration(localIterationDuration, iterationTime, scaledActiveTime, m_specified);
- timeFraction = calculateTransformedTime(currentIteration, localIterationDuration, iterationTime, m_specified);
- }
-
- m_calculated.currentIteration = currentIteration;
- m_calculated.activeDuration = activeDuration;
- m_calculated.timeFraction = timeFraction;
-
- m_calculated.phase = currentPhase;
- m_calculated.isInEffect = !isNull(activeTime);
- m_calculated.isInPlay = phase() == PhaseActive && (!m_parent || m_parent->isInPlay());
- m_calculated.isCurrent = phase() == PhaseBefore || isInPlay() || (m_parent && m_parent->isCurrent());
- }
-
- // Test for events even if timing didn't need an update as the player may have gained a start time.
- // FIXME: Refactor so that we can ASSERT(m_player) here, this is currently required to be nullable for testing.
- if (!m_player || m_player->hasStartTime()) {
- // This logic is specific to CSS animation events and assumes that all
- // animations start after the DocumentTimeline has started.
- if (m_eventDelegate && (m_isFirstSample || previousPhase != phase() || (phase() == PhaseActive && previousIteration != m_calculated.currentIteration)))
- m_eventDelegate->onEventCondition(this, m_isFirstSample, previousPhase, previousIteration);
- m_isFirstSample = false;
- }
-
- bool didTriggerStyleRecalc = false;
- if (needsUpdate) {
- // FIXME: This probably shouldn't be recursive.
- didTriggerStyleRecalc = updateChildrenAndEffects();
- m_calculated.timeToEffectChange = calculateTimeToEffectChange(localTime, timeToNextIteration);
- }
- return didTriggerStyleRecalc;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimedItem.h b/chromium/third_party/WebKit/Source/core/animation/TimedItem.h
deleted file mode 100644
index 82da5133f58..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/TimedItem.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TimedItem_h
-#define TimedItem_h
-
-#include "core/animation/Timing.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-class Player;
-class TimedItem;
-
-static inline bool isNull(double value)
-{
- return std::isnan(value);
-}
-
-static inline double nullValue()
-{
- return std::numeric_limits<double>::quiet_NaN();
-}
-
-class TimedItem : public RefCounted<TimedItem> {
- friend class Player; // Calls attach/detach, updateInheritedTime.
-public:
- // Note that logic in CSSAnimations depends on the order of these values.
- enum Phase {
- PhaseBefore,
- PhaseActive,
- PhaseAfter,
- PhaseNone,
- };
-
- class EventDelegate {
- public:
- virtual ~EventDelegate() { };
- virtual void onEventCondition(const TimedItem*, bool isFirstSample, Phase previousPhase, double previousIteration) = 0;
- };
-
- virtual ~TimedItem() { }
-
- virtual bool isAnimation() const { return false; }
-
- Phase phase() const { return ensureCalculated().phase; }
- bool isCurrent() const { return ensureCalculated().isCurrent; }
- bool isInEffect() const { return ensureCalculated().isInEffect; }
- bool isInPlay() const { return ensureCalculated().isInPlay; }
- double timeToEffectChange() const { return ensureCalculated().timeToEffectChange; }
-
- double currentIteration() const { return ensureCalculated().currentIteration; }
- double activeDuration() const { return ensureCalculated().activeDuration; }
- double timeFraction() const { return ensureCalculated().timeFraction; }
- double startTime() const { return m_startTime; }
- const Player* player() const { return m_player; }
- Player* player() { return m_player; }
- const Timing& specified() const { return m_specified; }
-
-protected:
- TimedItem(const Timing&, PassOwnPtr<EventDelegate> = nullptr);
-
- // When TimedItem receives a new inherited time via updateInheritedTime
- // it will (if necessary) recalculate timings and (if necessary) call
- // updateChildrenAndEffects.
- // Returns whether style recalc was triggered.
- bool updateInheritedTime(double inheritedTime) const;
- void invalidate() const { m_needsUpdate = true; };
-
-private:
- // Returns whether style recalc was triggered.
- virtual bool updateChildrenAndEffects() const = 0;
- virtual double intrinsicIterationDuration() const { return 0; };
- virtual double calculateTimeToEffectChange(double localTime, double timeToNextIteration) const = 0;
- virtual void didAttach() { };
- virtual void willDetach() { };
-
- void attach(Player* player)
- {
- m_player = player;
- didAttach();
- };
-
- void detach()
- {
- ASSERT(m_player);
- willDetach();
- m_player = 0;
- };
-
- // FIXME: m_parent and m_startTime are placeholders, they depend on timing groups.
- TimedItem* const m_parent;
- const double m_startTime;
- Player* m_player;
- Timing m_specified;
- OwnPtr<EventDelegate> m_eventDelegate;
-
- // FIXME: Should be versioned by monotonic value on player.
- mutable struct CalculatedTiming {
- double activeDuration;
- Phase phase;
- double currentIteration;
- double timeFraction;
- bool isCurrent;
- bool isInEffect;
- bool isInPlay;
- double timeToEffectChange;
- } m_calculated;
- mutable bool m_isFirstSample;
- mutable bool m_needsUpdate;
- mutable double m_lastUpdateTime;
-
- // FIXME: Should check the version and reinherit time if inconsistent.
- const CalculatedTiming& ensureCalculated() const { return m_calculated; }
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimedItemCalculations.h b/chromium/third_party/WebKit/Source/core/animation/TimedItemCalculations.h
deleted file mode 100644
index 28a6228554a..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/TimedItemCalculations.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TimedItemCalculations_h
-#define TimedItemCalculations_h
-
-#include "core/animation/TimedItem.h"
-#include "core/animation/Timing.h"
-#include "platform/animation/AnimationUtilities.h"
-#include "wtf/MathExtras.h"
-
-namespace WebCore {
-
-static inline double multiplyZeroAlwaysGivesZero(double x, double y)
-{
- ASSERT(!isNull(x));
- ASSERT(!isNull(y));
- return x && y ? x * y : 0;
-}
-
-static inline TimedItem::Phase calculatePhase(double activeDuration, double localTime, const Timing& specified)
-{
- ASSERT(activeDuration >= 0);
- if (isNull(localTime))
- return TimedItem::PhaseNone;
- if (localTime < specified.startDelay)
- return TimedItem::PhaseBefore;
- if (localTime >= specified.startDelay + activeDuration)
- return TimedItem::PhaseAfter;
- return TimedItem::PhaseActive;
-}
-
-static inline bool isActiveInParentPhase(TimedItem::Phase parentPhase, Timing::FillMode fillMode)
-{
- switch (parentPhase) {
- case TimedItem::PhaseBefore:
- return fillMode == Timing::FillModeBackwards || fillMode == Timing::FillModeBoth;
- case TimedItem::PhaseActive:
- return true;
- case TimedItem::PhaseAfter:
- return fillMode == Timing::FillModeForwards || fillMode == Timing::FillModeBoth;
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
-}
-
-static inline double calculateActiveTime(double activeDuration, double localTime, TimedItem::Phase parentPhase, TimedItem::Phase phase, const Timing& specified)
-{
- ASSERT(activeDuration >= 0);
- ASSERT(phase == calculatePhase(activeDuration, localTime, specified));
-
- switch (phase) {
- case TimedItem::PhaseBefore:
- if (specified.fillMode == Timing::FillModeBackwards || specified.fillMode == Timing::FillModeBoth)
- return 0;
- return nullValue();
- case TimedItem::PhaseActive:
- if (isActiveInParentPhase(parentPhase, specified.fillMode))
- return localTime - specified.startDelay;
- return nullValue();
- case TimedItem::PhaseAfter:
- if (specified.fillMode == Timing::FillModeForwards || specified.fillMode == Timing::FillModeBoth)
- return activeDuration;
- return nullValue();
- case TimedItem::PhaseNone:
- ASSERT(isNull(localTime));
- return nullValue();
- default:
- ASSERT_NOT_REACHED();
- return nullValue();
- }
-}
-
-static inline double calculateScaledActiveTime(double activeDuration, double activeTime, double startOffset, const Timing& specified)
-{
- ASSERT(activeDuration >= 0);
- ASSERT(startOffset >= 0);
-
- if (isNull(activeTime))
- return nullValue();
-
- ASSERT(activeTime >= 0 && activeTime <= activeDuration);
- return multiplyZeroAlwaysGivesZero(specified.playbackRate < 0 ? activeTime - activeDuration : activeTime, specified.playbackRate) + startOffset;
-}
-
-static inline bool endsOnIterationBoundary(double iterationCount, double iterationStart)
-{
- ASSERT(std::isfinite(iterationCount));
- return !fmod(iterationCount + iterationStart, 1);
-}
-
-static inline double calculateIterationTime(double iterationDuration, double repeatedDuration, double scaledActiveTime, double startOffset, const Timing& specified)
-{
- ASSERT(iterationDuration > 0);
- ASSERT(repeatedDuration == multiplyZeroAlwaysGivesZero(iterationDuration, specified.iterationCount));
-
- if (isNull(scaledActiveTime))
- return nullValue();
-
- ASSERT(scaledActiveTime >= 0);
- ASSERT(scaledActiveTime <= repeatedDuration + startOffset);
-
- if (!std::isfinite(scaledActiveTime)
- || (scaledActiveTime - startOffset == repeatedDuration && specified.iterationCount && endsOnIterationBoundary(specified.iterationCount, specified.iterationStart)))
- return iterationDuration;
-
- ASSERT(std::isfinite(scaledActiveTime));
- return fmod(scaledActiveTime, iterationDuration);
-}
-
-static inline double calculateCurrentIteration(double iterationDuration, double iterationTime, double scaledActiveTime, const Timing& specified)
-{
- ASSERT(iterationDuration > 0);
- ASSERT(isNull(iterationTime) || iterationTime >= 0);
-
- if (isNull(scaledActiveTime))
- return nullValue();
-
- ASSERT(iterationTime >= 0);
- ASSERT(iterationTime <= iterationDuration);
- ASSERT(scaledActiveTime >= 0);
-
- if (!scaledActiveTime)
- return 0;
-
- if (iterationTime == iterationDuration)
- return specified.iterationStart + specified.iterationCount - 1;
-
- return floor(scaledActiveTime / iterationDuration);
-}
-
-static inline double calculateDirectedTime(double currentIteration, double iterationDuration, double iterationTime, const Timing& specified)
-{
- ASSERT(isNull(currentIteration) || currentIteration >= 0);
- ASSERT(iterationDuration > 0);
-
- if (isNull(iterationTime))
- return nullValue();
-
- ASSERT(currentIteration >= 0);
- ASSERT(iterationTime >= 0);
- ASSERT(iterationTime <= iterationDuration);
-
- const bool currentIterationIsOdd = fmod(currentIteration, 2) >= 1;
- const bool currentDirectionIsForwards = specified.direction == Timing::PlaybackDirectionNormal
- || (specified.direction == Timing::PlaybackDirectionAlternate && !currentIterationIsOdd)
- || (specified.direction == Timing::PlaybackDirectionAlternateReverse && currentIterationIsOdd);
-
- return currentDirectionIsForwards ? iterationTime : iterationDuration - iterationTime;
-}
-
-static inline double calculateTransformedTime(double currentIteration, double iterationDuration, double iterationTime, const Timing& specified)
-{
- ASSERT(isNull(currentIteration) || currentIteration >= 0);
- ASSERT(iterationDuration > 0);
- ASSERT(isNull(iterationTime) || (iterationTime >= 0 && iterationTime <= iterationDuration));
-
- double directedTime = calculateDirectedTime(currentIteration, iterationDuration, iterationTime, specified);
- if (isNull(directedTime))
- return nullValue();
- if (!std::isfinite(iterationDuration))
- return directedTime;
- double timeFraction = directedTime / iterationDuration;
- ASSERT(timeFraction >= 0 && timeFraction <= 1);
- return specified.timingFunction
- ? multiplyZeroAlwaysGivesZero(iterationDuration, specified.timingFunction->evaluate(timeFraction, accuracyForDuration(iterationDuration)))
- : directedTime;
-}
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimedItemCalculationsTest.cpp b/chromium/third_party/WebKit/Source/core/animation/TimedItemCalculationsTest.cpp
deleted file mode 100644
index 6e053cdde8f..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/TimedItemCalculationsTest.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/TimedItemCalculations.h"
-
-#include <gtest/gtest.h>
-
-using namespace WebCore;
-
-namespace {
-
-TEST(AnimationTimedItemCalculationsTest, ActiveTime)
-{
- Timing timing;
-
- // calculateActiveTime(activeDuration, localTime, parentPhase, phase, timing)
-
- // Before Phase
- timing.startDelay = 10;
- timing.fillMode = Timing::FillModeForwards;
- EXPECT_TRUE(isNull(calculateActiveTime(20, 0, TimedItem::PhaseActive, TimedItem::PhaseBefore, timing)));
- timing.fillMode = Timing::FillModeNone;
- EXPECT_TRUE(isNull(calculateActiveTime(20, 0, TimedItem::PhaseActive, TimedItem::PhaseBefore, timing)));
- timing.fillMode = Timing::FillModeBackwards;
- EXPECT_EQ(0, calculateActiveTime(20, 0, TimedItem::PhaseActive, TimedItem::PhaseBefore, timing));
- timing.fillMode = Timing::FillModeBoth;
- EXPECT_EQ(0, calculateActiveTime(20, 0, TimedItem::PhaseActive, TimedItem::PhaseBefore, timing));
-
- // Active Phase
- timing.startDelay = 10;
- // Active, and parent Before
- timing.fillMode = Timing::FillModeNone;
- EXPECT_TRUE(isNull(calculateActiveTime(20, 15, TimedItem::PhaseBefore, TimedItem::PhaseActive, timing)));
- timing.fillMode = Timing::FillModeForwards;
- EXPECT_TRUE(isNull(calculateActiveTime(20, 15, TimedItem::PhaseBefore, TimedItem::PhaseActive, timing)));
- // Active, and parent After
- timing.fillMode = Timing::FillModeNone;
- EXPECT_TRUE(isNull(calculateActiveTime(20, 15, TimedItem::PhaseAfter, TimedItem::PhaseActive, timing)));
- timing.fillMode = Timing::FillModeBackwards;
- EXPECT_TRUE(isNull(calculateActiveTime(20, 15, TimedItem::PhaseAfter, TimedItem::PhaseActive, timing)));
- // Active, and parent Active
- timing.fillMode = Timing::FillModeForwards;
- EXPECT_EQ(5, calculateActiveTime(20, 15, TimedItem::PhaseActive, TimedItem::PhaseActive, timing));
-
- // After Phase
- timing.startDelay = 10;
- timing.fillMode = Timing::FillModeForwards;
- EXPECT_EQ(21, calculateActiveTime(21, 45, TimedItem::PhaseActive, TimedItem::PhaseAfter, timing));
- timing.fillMode = Timing::FillModeBoth;
- EXPECT_EQ(21, calculateActiveTime(21, 45, TimedItem::PhaseActive, TimedItem::PhaseAfter, timing));
- timing.fillMode = Timing::FillModeBackwards;
- EXPECT_TRUE(isNull(calculateActiveTime(21, 45, TimedItem::PhaseActive, TimedItem::PhaseAfter, timing)));
- timing.fillMode = Timing::FillModeNone;
- EXPECT_TRUE(isNull(calculateActiveTime(21, 45, TimedItem::PhaseActive, TimedItem::PhaseAfter, timing)));
-
- // None
- EXPECT_TRUE(isNull(calculateActiveTime(32, nullValue(), TimedItem::PhaseNone, TimedItem::PhaseNone, timing)));
-}
-
-TEST(AnimationTimedItemCalculationsTest, ScaledActiveTime)
-{
- Timing timing;
-
- // calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing)
-
- // if the active time is null
- EXPECT_TRUE(isNull(calculateScaledActiveTime(4, nullValue(), 5, timing)));
-
- // if the playback rate is negative
- timing.playbackRate = -1;
- EXPECT_EQ(35, calculateScaledActiveTime(40, 10, 5, timing));
-
- // otherwise
- timing.playbackRate = 0;
- EXPECT_EQ(5, calculateScaledActiveTime(40, 10, 5, timing));
- timing.playbackRate = 1;
- EXPECT_EQ(15, calculateScaledActiveTime(40, 10, 5, timing));
-
- // infinte activeTime
- timing.playbackRate = 0;
- EXPECT_EQ(0, calculateScaledActiveTime(std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), 0, timing));
- timing.playbackRate = 1;
- EXPECT_EQ(std::numeric_limits<double>::infinity(), calculateScaledActiveTime(std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), 0, timing));
-}
-
-TEST(AnimationTimedItemCalculationsTest, IterationTime)
-{
- Timing timing;
-
- // calculateIterationTime(iterationDuration, repeatedDuration, scaledActiveTime, startOffset, timing)
-
- // if the scaled active time is null
- EXPECT_TRUE(isNull(calculateIterationTime(1, 1, nullValue(), 1, timing)));
-
- // if (complex-conditions)...
- EXPECT_EQ(12, calculateIterationTime(12, 12, 12, 0, timing));
-
- // otherwise
- timing.iterationCount = 10;
- EXPECT_EQ(5, calculateIterationTime(10, 100, 25, 4, timing));
- EXPECT_EQ(7, calculateIterationTime(11, 110, 29, 1, timing));
- timing.iterationStart = 1.1;
- EXPECT_EQ(8, calculateIterationTime(12, 120, 20, 7, timing));
-}
-
-TEST(AnimationTimedItemCalculationsTest, CurrentIteration)
-{
- Timing timing;
-
- // calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, timing)
-
- // if the scaled active time is null
- EXPECT_TRUE(isNull(calculateCurrentIteration(1, 1, nullValue(), timing)));
-
- // if the scaled active time is zero
- EXPECT_EQ(0, calculateCurrentIteration(1, 1, 0, timing));
-
- // if the iteration time equals the iteration duration
- timing.iterationStart = 4;
- timing.iterationCount = 7;
- EXPECT_EQ(10, calculateCurrentIteration(5, 5, 9, timing));
-
- // otherwise
- EXPECT_EQ(3, calculateCurrentIteration(3.2, 3.1, 10, timing));
-}
-
-TEST(AnimationTimedItemCalculationsTest, DirectedTime)
-{
- Timing timing;
-
- // calculateDirectedTime(currentIteration, iterationDuration, iterationTime, timing)
-
- // if the iteration time is null
- EXPECT_TRUE(isNull(calculateDirectedTime(1, 2, nullValue(), timing)));
-
- // forwards
- EXPECT_EQ(17, calculateDirectedTime(0, 20, 17, timing));
- EXPECT_EQ(17, calculateDirectedTime(1, 20, 17, timing));
- timing.direction = Timing::PlaybackDirectionAlternate;
- EXPECT_EQ(17, calculateDirectedTime(0, 20, 17, timing));
- EXPECT_EQ(17, calculateDirectedTime(2, 20, 17, timing));
- timing.direction = Timing::PlaybackDirectionAlternateReverse;
- EXPECT_EQ(17, calculateDirectedTime(1, 20, 17, timing));
- EXPECT_EQ(17, calculateDirectedTime(3, 20, 17, timing));
-
- // reverse
- timing.direction = Timing::PlaybackDirectionReverse;
- EXPECT_EQ(3, calculateDirectedTime(0, 20, 17, timing));
- EXPECT_EQ(3, calculateDirectedTime(1, 20, 17, timing));
- timing.direction = Timing::PlaybackDirectionAlternate;
- EXPECT_EQ(3, calculateDirectedTime(1, 20, 17, timing));
- EXPECT_EQ(3, calculateDirectedTime(3, 20, 17, timing));
- timing.direction = Timing::PlaybackDirectionAlternateReverse;
- EXPECT_EQ(3, calculateDirectedTime(0, 20, 17, timing));
- EXPECT_EQ(3, calculateDirectedTime(2, 20, 17, timing));
-}
-
-TEST(AnimationTimedItemCalculationsTest, TransformedTime)
-{
- Timing timing;
-
- // calculateTransformedTime(currentIteration, iterationDuration, iterationTime, timing)
-
- // Iteration time is null
- EXPECT_TRUE(isNull(calculateTransformedTime(1, 2, nullValue(), timing)));
-
- // PlaybackDirectionForwards
- EXPECT_EQ(12, calculateTransformedTime(0, 20, 12, timing));
- EXPECT_EQ(12, calculateTransformedTime(1, 20, 12, timing));
-
- // PlaybackDirectionForwards with timing function
- timing.timingFunction = StepsTimingFunction::create(4, false /* stepAtStart */);
- EXPECT_EQ(10, calculateTransformedTime(0, 20, 12, timing));
- EXPECT_EQ(10, calculateTransformedTime(1, 20, 12, timing));
-
- // PlaybackDirectionReverse
- timing.timingFunction = 0;
- timing.direction = Timing::PlaybackDirectionReverse;
- EXPECT_EQ(8, calculateTransformedTime(0, 20, 12, timing));
- EXPECT_EQ(8, calculateTransformedTime(1, 20, 12, timing));
-
- // PlaybackDirectionReverse with timing function
- timing.timingFunction = StepsTimingFunction::create(4, false /* stepAtStart */);
- EXPECT_EQ(5, calculateTransformedTime(0, 20, 12, timing));
- EXPECT_EQ(5, calculateTransformedTime(1, 20, 12, timing));
-
- // Timing function when directed time is null.
- EXPECT_TRUE(isNull(calculateTransformedTime(1, 2, nullValue(), timing)));
-
- // Timing function when iterationDuration is infinity
- timing.direction = Timing::PlaybackDirectionNormal;
- EXPECT_EQ(0, calculateTransformedTime(0, std::numeric_limits<double>::infinity(), 0, timing));
- EXPECT_EQ(1, calculateTransformedTime(0, std::numeric_limits<double>::infinity(), 1, timing));
- timing.direction = Timing::PlaybackDirectionReverse;
- EXPECT_EQ(std::numeric_limits<double>::infinity(), calculateTransformedTime(0, std::numeric_limits<double>::infinity(), 0, timing));
- EXPECT_EQ(std::numeric_limits<double>::infinity(), calculateTransformedTime(0, std::numeric_limits<double>::infinity(), 1, timing));
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimedItemTest.cpp b/chromium/third_party/WebKit/Source/core/animation/TimedItemTest.cpp
deleted file mode 100644
index 6bd34ab67cc..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/TimedItemTest.cpp
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/TimedItem.h"
-
-#include <gtest/gtest.h>
-
-using namespace WebCore;
-
-namespace {
-
-class TestTimedItemEventDelegate : public TimedItem::EventDelegate {
-public:
- void onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration) OVERRIDE
- {
- m_eventTriggered = true;
- m_phaseChanged = previousPhase != timedItem->phase();
- m_iterationChanged = previousIteration != timedItem->currentIteration();
-
- }
- void reset()
- {
- m_eventTriggered = false;
- m_phaseChanged = false;
- m_iterationChanged = false;
- }
- bool eventTriggered() { return m_eventTriggered; }
- bool phaseChanged() { return m_phaseChanged; }
- bool iterationChanged() { return m_iterationChanged; }
-
-private:
- bool m_eventTriggered;
- bool m_phaseChanged;
- bool m_iterationChanged;
-};
-
-class TestTimedItem : public TimedItem {
-public:
- static PassRefPtr<TestTimedItem> create(const Timing& specified)
- {
- return adoptRef(new TestTimedItem(specified, new TestTimedItemEventDelegate()));
- }
-
- void updateInheritedTime(double time)
- {
- m_eventDelegate->reset();
- TimedItem::updateInheritedTime(time);
- }
-
- bool updateChildrenAndEffects() const OVERRIDE { return false; }
- void willDetach() { }
- TestTimedItemEventDelegate* eventDelegate() { return m_eventDelegate; }
- double calculateTimeToEffectChange(double localTime, double timeToNextIteration) const OVERRIDE
- {
- m_localTime = localTime;
- m_timeToNextIteration = timeToNextIteration;
- return -1;
- }
-
- double takeLocalTime()
- {
- const double result = m_localTime;
- m_localTime = nullValue();
- return result;
- }
-
- double takeTimeToNextIteration()
- {
- const double result = m_timeToNextIteration;
- m_timeToNextIteration = nullValue();
- return result;
- }
-
-private:
- TestTimedItem(const Timing& specified, TestTimedItemEventDelegate* eventDelegate)
- : TimedItem(specified, adoptPtr(eventDelegate))
- , m_eventDelegate(eventDelegate)
- {
- }
-
- TestTimedItemEventDelegate* m_eventDelegate;
- mutable double m_localTime;
- mutable double m_timeToNextIteration;
-};
-
-TEST(AnimationTimedItemTest, Sanity)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 2;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- EXPECT_EQ(0, timedItem->startTime());
-
- timedItem->updateInheritedTime(0);
-
- EXPECT_EQ(TimedItem::PhaseActive, timedItem->phase());
- EXPECT_TRUE(timedItem->isInPlay());
- EXPECT_TRUE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->startTime());
- EXPECT_EQ(2, timedItem->activeDuration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
-
- EXPECT_EQ(TimedItem::PhaseActive, timedItem->phase());
- EXPECT_TRUE(timedItem->isInPlay());
- EXPECT_TRUE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->startTime());
- EXPECT_EQ(2, timedItem->activeDuration());
- EXPECT_EQ(0.5, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(2);
-
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_FALSE(timedItem->isInPlay());
- EXPECT_FALSE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->startTime());
- EXPECT_EQ(2, timedItem->activeDuration());
- EXPECT_EQ(1, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(3);
-
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_FALSE(timedItem->isInPlay());
- EXPECT_FALSE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->startTime());
- EXPECT_EQ(2, timedItem->activeDuration());
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, FillForwards)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(2);
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, FillBackwards)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.fillMode = Timing::FillModeBackwards;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(2);
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-}
-
-TEST(AnimationTimedItemTest, FillBoth)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.fillMode = Timing::FillModeBoth;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(2);
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, StartDelay)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.startDelay = 0.5;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(0);
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(0.5);
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1.5);
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroIteration)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.iterationCount = 0;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_EQ(0, timedItem->activeDuration());
- EXPECT_TRUE(isNull(timedItem->currentIteration()));
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(0, timedItem->activeDuration());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, InfiniteIteration)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.iterationCount = std::numeric_limits<double>::infinity();
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_TRUE(isNull(timedItem->currentIteration()));
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timedItem->activeDuration());
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, Iteration)
-{
- Timing timing;
- timing.iterationCount = 2;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 2;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0.5, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(2);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(2);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(5);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, IterationStart)
-{
- Timing timing;
- timing.iterationStart = 1.2;
- timing.iterationCount = 2.2;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.fillMode = Timing::FillModeBoth;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_NEAR(0.2, timedItem->timeFraction(), 0.000000000000001);
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_NEAR(0.2, timedItem->timeFraction(), 0.000000000000001);
-
- timedItem->updateInheritedTime(10);
- EXPECT_EQ(3, timedItem->currentIteration());
- EXPECT_NEAR(0.4, timedItem->timeFraction(), 0.000000000000001);
-}
-
-TEST(AnimationTimedItemTest, IterationAlternate)
-{
- Timing timing;
- timing.iterationCount = 10;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.direction = Timing::PlaybackDirectionAlternate;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(0.75);
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0.75, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1.75);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(0.25, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(2.75);
- EXPECT_EQ(2, timedItem->currentIteration());
- EXPECT_EQ(0.75, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, IterationAlternateReverse)
-{
- Timing timing;
- timing.iterationCount = 10;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.direction = Timing::PlaybackDirectionAlternateReverse;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(0.75);
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0.25, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1.75);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(0.75, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(2.75);
- EXPECT_EQ(2, timedItem->currentIteration());
- EXPECT_EQ(0.25, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationSanity)
-{
- Timing timing;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- EXPECT_EQ(0, timedItem->startTime());
-
- timedItem->updateInheritedTime(0);
-
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_FALSE(timedItem->isInPlay());
- EXPECT_FALSE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->startTime());
- EXPECT_EQ(0, timedItem->activeDuration());
- EXPECT_EQ(1, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
-
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_FALSE(timedItem->isInPlay());
- EXPECT_FALSE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->startTime());
- EXPECT_EQ(0, timedItem->activeDuration());
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationFillForwards)
-{
- Timing timing;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(1, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationFillBackwards)
-{
- Timing timing;
- timing.fillMode = Timing::FillModeBackwards;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(0);
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(1);
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationFillBoth)
-{
- Timing timing;
- timing.fillMode = Timing::FillModeBoth;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(1, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationStartDelay)
-{
- Timing timing;
- timing.startDelay = 0.5;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(0);
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(0.5);
- EXPECT_EQ(1, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1.5);
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationIterationStartAndCount)
-{
- Timing timing;
- timing.iterationStart = 0.1;
- timing.iterationCount = 0.2;
- timing.fillMode = Timing::FillModeBoth;
- timing.startDelay = 0.3;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(0.1, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(0.3);
- EXPECT_DOUBLE_EQ(0.3, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
- EXPECT_DOUBLE_EQ(0.3, timedItem->timeFraction());
-}
-
-// FIXME: Needs specification work.
-TEST(AnimationTimedItemTest, ZeroDurationInfiniteIteration)
-{
- Timing timing;
- timing.iterationCount = std::numeric_limits<double>::infinity();
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_EQ(0, timedItem->activeDuration());
- EXPECT_TRUE(isNull(timedItem->currentIteration()));
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(0, timedItem->activeDuration());
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timedItem->currentIteration());
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationIteration)
-{
- Timing timing;
- timing.iterationCount = 2;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_TRUE(isNull(timedItem->currentIteration()));
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(1, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationIterationStart)
-{
- Timing timing;
- timing.iterationStart = 1.2;
- timing.iterationCount = 2.2;
- timing.fillMode = Timing::FillModeBoth;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_NEAR(0.2, timedItem->timeFraction(), 0.000000000000001);
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(3, timedItem->currentIteration());
- EXPECT_NEAR(0.4, timedItem->timeFraction(), 0.000000000000001);
-
- timedItem->updateInheritedTime(10);
- EXPECT_EQ(3, timedItem->currentIteration());
- EXPECT_NEAR(0.4, timedItem->timeFraction(), 0.000000000000001);
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationIterationAlternate)
-{
- Timing timing;
- timing.iterationCount = 2;
- timing.direction = Timing::PlaybackDirectionAlternate;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_TRUE(isNull(timedItem->currentIteration()));
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, ZeroDurationIterationAlternateReverse)
-{
- Timing timing;
- timing.iterationCount = 2;
- timing.direction = Timing::PlaybackDirectionAlternateReverse;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(-1);
- EXPECT_TRUE(isNull(timedItem->currentIteration()));
- EXPECT_TRUE(isNull(timedItem->timeFraction()));
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(1, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
- EXPECT_EQ(1, timedItem->currentIteration());
- EXPECT_EQ(1, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, InfiniteDurationSanity)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = std::numeric_limits<double>::infinity();
- timing.iterationCount = 1;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- EXPECT_EQ(0, timedItem->startTime());
-
- timedItem->updateInheritedTime(0);
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timedItem->activeDuration());
- EXPECT_EQ(TimedItem::PhaseActive, timedItem->phase());
- EXPECT_TRUE(timedItem->isInPlay());
- EXPECT_TRUE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timedItem->activeDuration());
- EXPECT_EQ(TimedItem::PhaseActive, timedItem->phase());
- EXPECT_TRUE(timedItem->isInPlay());
- EXPECT_TRUE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-}
-
-// FIXME: Needs specification work.
-TEST(AnimationTimedItemTest, InfiniteDurationZeroIterations)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = std::numeric_limits<double>::infinity();
- timing.iterationCount = 0;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- EXPECT_EQ(0, timedItem->startTime());
-
- timedItem->updateInheritedTime(0);
-
- EXPECT_EQ(0, timedItem->activeDuration());
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_FALSE(timedItem->isInPlay());
- EXPECT_FALSE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
-
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_FALSE(timedItem->isInPlay());
- EXPECT_FALSE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, InfiniteDurationInfiniteIterations)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = std::numeric_limits<double>::infinity();
- timing.iterationCount = std::numeric_limits<double>::infinity();
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- EXPECT_EQ(0, timedItem->startTime());
-
- timedItem->updateInheritedTime(0);
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timedItem->activeDuration());
- EXPECT_EQ(TimedItem::PhaseActive, timedItem->phase());
- EXPECT_TRUE(timedItem->isInPlay());
- EXPECT_TRUE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(1);
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timedItem->activeDuration());
- EXPECT_EQ(TimedItem::PhaseActive, timedItem->phase());
- EXPECT_TRUE(timedItem->isInPlay());
- EXPECT_TRUE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, InfiniteDurationZeroPlaybackRate)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = std::numeric_limits<double>::infinity();
- timing.playbackRate = 0;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- EXPECT_EQ(0, timedItem->startTime());
-
- timedItem->updateInheritedTime(0);
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timedItem->activeDuration());
- EXPECT_EQ(TimedItem::PhaseActive, timedItem->phase());
- EXPECT_TRUE(timedItem->isInPlay());
- EXPECT_TRUE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-
- timedItem->updateInheritedTime(std::numeric_limits<double>::infinity());
-
- EXPECT_EQ(std::numeric_limits<double>::infinity(), timedItem->activeDuration());
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_FALSE(timedItem->isInPlay());
- EXPECT_FALSE(timedItem->isCurrent());
- EXPECT_TRUE(timedItem->isInEffect());
- EXPECT_EQ(0, timedItem->currentIteration());
- EXPECT_EQ(0, timedItem->timeFraction());
-}
-
-TEST(AnimationTimedItemTest, Events)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.iterationCount = 2;
- timing.startDelay = 1;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- // First sample
- timedItem->updateInheritedTime(0.0);
- EXPECT_TRUE(timedItem->eventDelegate()->eventTriggered());
-
- // Before start
- timedItem->updateInheritedTime(0.5);
- EXPECT_FALSE(timedItem->eventDelegate()->eventTriggered());
-
- // First iteration
- timedItem->updateInheritedTime(1.5);
- EXPECT_TRUE(timedItem->eventDelegate()->eventTriggered());
- EXPECT_TRUE(timedItem->eventDelegate()->phaseChanged());
- EXPECT_TRUE(timedItem->eventDelegate()->iterationChanged());
-
- timedItem->updateInheritedTime(1.6);
- EXPECT_FALSE(timedItem->eventDelegate()->eventTriggered());
-
- // Second iteration
- timedItem->updateInheritedTime(2.5);
- EXPECT_TRUE(timedItem->eventDelegate()->eventTriggered());
- EXPECT_FALSE(timedItem->eventDelegate()->phaseChanged());
- EXPECT_TRUE(timedItem->eventDelegate()->iterationChanged());
-
- timedItem->updateInheritedTime(2.6);
- EXPECT_FALSE(timedItem->eventDelegate()->eventTriggered());
-
- // After end
- timedItem->updateInheritedTime(3.5);
- EXPECT_TRUE(timedItem->eventDelegate()->eventTriggered());
- EXPECT_TRUE(timedItem->eventDelegate()->phaseChanged());
- EXPECT_FALSE(timedItem->eventDelegate()->iterationChanged());
-
- timedItem->updateInheritedTime(3.6);
- EXPECT_FALSE(timedItem->eventDelegate()->eventTriggered());
-}
-
-TEST(AnimationTimedItemTest, TimeToEffectChange)
-{
- Timing timing;
- timing.hasIterationDuration = true;
- timing.iterationDuration = 1;
- timing.iterationStart = 0.2;
- timing.iterationCount = 2.5;
- timing.startDelay = 1;
- timing.direction = Timing::PlaybackDirectionAlternate;
- RefPtr<TestTimedItem> timedItem = TestTimedItem::create(timing);
-
- timedItem->updateInheritedTime(0);
- EXPECT_EQ(0, timedItem->takeLocalTime());
- EXPECT_TRUE(std::isinf(timedItem->takeTimeToNextIteration()));
-
- // Normal iteration.
- timedItem->updateInheritedTime(1.75);
- EXPECT_EQ(1.75, timedItem->takeLocalTime());
- EXPECT_NEAR(0.05, timedItem->takeTimeToNextIteration(), 0.000000000000001);
-
- // Reverse iteration.
- timedItem->updateInheritedTime(2.75);
- EXPECT_EQ(2.75, timedItem->takeLocalTime());
- EXPECT_NEAR(0.05, timedItem->takeTimeToNextIteration(), 0.000000000000001);
-
- // Item ends before iteration finishes.
- timedItem->updateInheritedTime(3.4);
- EXPECT_EQ(TimedItem::PhaseActive, timedItem->phase());
- EXPECT_EQ(3.4, timedItem->takeLocalTime());
- EXPECT_TRUE(std::isinf(timedItem->takeTimeToNextIteration()));
-
- // Item has finished.
- timedItem->updateInheritedTime(3.5);
- EXPECT_EQ(TimedItem::PhaseAfter, timedItem->phase());
- EXPECT_EQ(3.5, timedItem->takeLocalTime());
- EXPECT_TRUE(std::isinf(timedItem->takeTimeToNextIteration()));
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/animation/Timing.h b/chromium/third_party/WebKit/Source/core/animation/Timing.h
index 9a3bc4e6235..e862f653aec 100644
--- a/chromium/third_party/WebKit/Source/core/animation/Timing.h
+++ b/chromium/third_party/WebKit/Source/core/animation/Timing.h
@@ -31,7 +31,7 @@
#ifndef Timing_h
#define Timing_h
-#include "core/platform/animation/TimingFunction.h"
+#include "platform/animation/TimingFunction.h"
#include "wtf/MathExtras.h"
#include "wtf/RefPtr.h"
@@ -39,6 +39,7 @@ namespace WebCore {
struct Timing {
enum FillMode {
+ FillModeAuto,
FillModeNone,
FillModeForwards,
FillModeBackwards,
@@ -52,37 +53,43 @@ struct Timing {
PlaybackDirectionAlternateReverse
};
+ static const Timing& defaults()
+ {
+ DEFINE_STATIC_LOCAL(Timing, timing, ());
+ return timing;
+ }
+
Timing()
: startDelay(0)
- , fillMode(FillModeForwards)
+ , endDelay(0)
+ , fillMode(FillModeAuto)
, iterationStart(0)
, iterationCount(1)
- , hasIterationDuration(false)
- , iterationDuration(0)
+ , iterationDuration(std::numeric_limits<double>::quiet_NaN())
, playbackRate(1)
, direction(PlaybackDirectionNormal)
- , timingFunction(LinearTimingFunction::create())
+ , timingFunction(LinearTimingFunction::shared())
{
}
void assertValid() const
{
ASSERT(std::isfinite(startDelay));
+ ASSERT(std::isfinite(endDelay));
ASSERT(std::isfinite(iterationStart));
ASSERT(iterationStart >= 0);
ASSERT(iterationCount >= 0);
- ASSERT(iterationDuration >= 0);
+ ASSERT(std::isnan(iterationDuration) || iterationDuration >= 0);
ASSERT(std::isfinite(playbackRate));
ASSERT(timingFunction);
}
double startDelay;
+ double endDelay;
FillMode fillMode;
double iterationStart;
double iterationCount;
- bool hasIterationDuration;
double iterationDuration;
- // FIXME: Add activeDuration.
double playbackRate;
PlaybackDirection direction;
RefPtr<TimingFunction> timingFunction;
diff --git a/chromium/third_party/WebKit/Source/core/animation/Timing.idl b/chromium/third_party/WebKit/Source/core/animation/Timing.idl
new file mode 100644
index 00000000000..49e93e1d61f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/Timing.idl
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=WebAnimationsAPI,
+ ImplementedAs=AnimationNodeTiming,
+ WillBeGarbageCollected,
+] interface Timing {
+ attribute double delay;
+ attribute double endDelay;
+ attribute DOMString fill;
+ attribute double iterationStart;
+ attribute double iterations;
+
+ // FIXME: This uses a NamedPropertyGetter to implement the 'duration' attribute
+ // because duration has a union type (which is tricky to do with an attribute).
+ // Fix will be in a follow-up patch if there is a better solution.
+ [NotEnumerable, ImplementedAs=getDuration] getter (double or DOMString) (DOMString name);
+
+ // FIXME: If the user calls animation.specified.duration = "" (empty string) then duration
+ // gets set to 0 (This is correct behavior for IDL). Correct result is for duration to
+ // be set to 'auto'.
+ [TypeChecking=Interface|Nullable, ImplementedAs=setDuration] setter double (DOMString name, double duration);
+
+ attribute double playbackRate;
+ attribute DOMString direction;
+ attribute DOMString easing;
+};
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimingCalculations.h b/chromium/third_party/WebKit/Source/core/animation/TimingCalculations.h
new file mode 100644
index 00000000000..1954e42b665
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/TimingCalculations.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TimingCalculations_h
+#define TimingCalculations_h
+
+#include "core/animation/AnimationNode.h"
+#include "core/animation/Timing.h"
+#include "platform/animation/AnimationUtilities.h"
+#include "wtf/MathExtras.h"
+
+namespace WebCore {
+
+static inline double multiplyZeroAlwaysGivesZero(double x, double y)
+{
+ ASSERT(!isNull(x));
+ ASSERT(!isNull(y));
+ return x && y ? x * y : 0;
+}
+
+static inline AnimationNode::Phase calculatePhase(double activeDuration, double localTime, const Timing& specified)
+{
+ ASSERT(activeDuration >= 0);
+ if (isNull(localTime))
+ return AnimationNode::PhaseNone;
+ if (localTime < specified.startDelay)
+ return AnimationNode::PhaseBefore;
+ if (localTime >= specified.startDelay + activeDuration)
+ return AnimationNode::PhaseAfter;
+ return AnimationNode::PhaseActive;
+}
+
+static inline bool isActiveInParentPhase(AnimationNode::Phase parentPhase, Timing::FillMode fillMode)
+{
+ switch (parentPhase) {
+ case AnimationNode::PhaseBefore:
+ return fillMode == Timing::FillModeBackwards || fillMode == Timing::FillModeBoth;
+ case AnimationNode::PhaseActive:
+ return true;
+ case AnimationNode::PhaseAfter:
+ return fillMode == Timing::FillModeForwards || fillMode == Timing::FillModeBoth;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+}
+
+static inline double calculateActiveTime(double activeDuration, Timing::FillMode fillMode, double localTime, AnimationNode::Phase parentPhase, AnimationNode::Phase phase, const Timing& specified)
+{
+ ASSERT(activeDuration >= 0);
+ ASSERT(phase == calculatePhase(activeDuration, localTime, specified));
+
+ switch (phase) {
+ case AnimationNode::PhaseBefore:
+ if (fillMode == Timing::FillModeBackwards || fillMode == Timing::FillModeBoth)
+ return 0;
+ return nullValue();
+ case AnimationNode::PhaseActive:
+ if (isActiveInParentPhase(parentPhase, fillMode))
+ return localTime - specified.startDelay;
+ return nullValue();
+ case AnimationNode::PhaseAfter:
+ if (fillMode == Timing::FillModeForwards || fillMode == Timing::FillModeBoth)
+ return activeDuration;
+ return nullValue();
+ case AnimationNode::PhaseNone:
+ ASSERT(isNull(localTime));
+ return nullValue();
+ default:
+ ASSERT_NOT_REACHED();
+ return nullValue();
+ }
+}
+
+static inline double calculateScaledActiveTime(double activeDuration, double activeTime, double startOffset, const Timing& specified)
+{
+ ASSERT(activeDuration >= 0);
+ ASSERT(startOffset >= 0);
+
+ if (isNull(activeTime))
+ return nullValue();
+
+ ASSERT(activeTime >= 0 && activeTime <= activeDuration);
+ return multiplyZeroAlwaysGivesZero(specified.playbackRate < 0 ? activeTime - activeDuration : activeTime, specified.playbackRate) + startOffset;
+}
+
+static inline bool endsOnIterationBoundary(double iterationCount, double iterationStart)
+{
+ ASSERT(std::isfinite(iterationCount));
+ return !fmod(iterationCount + iterationStart, 1);
+}
+
+static inline double calculateIterationTime(double iterationDuration, double repeatedDuration, double scaledActiveTime, double startOffset, const Timing& specified)
+{
+ ASSERT(iterationDuration > 0);
+ ASSERT(repeatedDuration == multiplyZeroAlwaysGivesZero(iterationDuration, specified.iterationCount));
+
+ if (isNull(scaledActiveTime))
+ return nullValue();
+
+ ASSERT(scaledActiveTime >= 0);
+ ASSERT(scaledActiveTime <= repeatedDuration + startOffset);
+
+ if (!std::isfinite(scaledActiveTime)
+ || (scaledActiveTime - startOffset == repeatedDuration && specified.iterationCount && endsOnIterationBoundary(specified.iterationCount, specified.iterationStart)))
+ return iterationDuration;
+
+ ASSERT(std::isfinite(scaledActiveTime));
+ return fmod(scaledActiveTime, iterationDuration);
+}
+
+static inline double calculateCurrentIteration(double iterationDuration, double iterationTime, double scaledActiveTime, const Timing& specified)
+{
+ ASSERT(iterationDuration > 0);
+ ASSERT(isNull(iterationTime) || iterationTime >= 0);
+
+ if (isNull(scaledActiveTime))
+ return nullValue();
+
+ ASSERT(iterationTime >= 0);
+ ASSERT(iterationTime <= iterationDuration);
+ ASSERT(scaledActiveTime >= 0);
+
+ if (!scaledActiveTime)
+ return 0;
+
+ if (iterationTime == iterationDuration)
+ return specified.iterationStart + specified.iterationCount - 1;
+
+ return floor(scaledActiveTime / iterationDuration);
+}
+
+static inline double calculateDirectedTime(double currentIteration, double iterationDuration, double iterationTime, const Timing& specified)
+{
+ ASSERT(isNull(currentIteration) || currentIteration >= 0);
+ ASSERT(iterationDuration > 0);
+
+ if (isNull(iterationTime))
+ return nullValue();
+
+ ASSERT(currentIteration >= 0);
+ ASSERT(iterationTime >= 0);
+ ASSERT(iterationTime <= iterationDuration);
+
+ const bool currentIterationIsOdd = fmod(currentIteration, 2) >= 1;
+ const bool currentDirectionIsForwards = specified.direction == Timing::PlaybackDirectionNormal
+ || (specified.direction == Timing::PlaybackDirectionAlternate && !currentIterationIsOdd)
+ || (specified.direction == Timing::PlaybackDirectionAlternateReverse && currentIterationIsOdd);
+
+ return currentDirectionIsForwards ? iterationTime : iterationDuration - iterationTime;
+}
+
+static inline double calculateTransformedTime(double currentIteration, double iterationDuration, double iterationTime, const Timing& specified)
+{
+ ASSERT(isNull(currentIteration) || currentIteration >= 0);
+ ASSERT(iterationDuration > 0);
+ ASSERT(isNull(iterationTime) || (iterationTime >= 0 && iterationTime <= iterationDuration));
+
+ double directedTime = calculateDirectedTime(currentIteration, iterationDuration, iterationTime, specified);
+ if (isNull(directedTime))
+ return nullValue();
+ if (!std::isfinite(iterationDuration))
+ return directedTime;
+ double timeFraction = directedTime / iterationDuration;
+ ASSERT(timeFraction >= 0 && timeFraction <= 1);
+ return multiplyZeroAlwaysGivesZero(iterationDuration, specified.timingFunction->evaluate(timeFraction, accuracyForDuration(iterationDuration)));
+}
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimingCalculationsTest.cpp b/chromium/third_party/WebKit/Source/core/animation/TimingCalculationsTest.cpp
new file mode 100644
index 00000000000..ffd22058166
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/TimingCalculationsTest.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2013, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/TimingCalculations.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+TEST(AnimationTimingCalculationsTest, ActiveTime)
+{
+ Timing timing;
+
+ // calculateActiveTime(activeDuration, fillMode, localTime, parentPhase, phase, timing)
+
+ // Before Phase
+ timing.startDelay = 10;
+ EXPECT_TRUE(isNull(calculateActiveTime(20, Timing::FillModeForwards, 0, AnimationNode::PhaseActive, AnimationNode::PhaseBefore, timing)));
+ EXPECT_TRUE(isNull(calculateActiveTime(20, Timing::FillModeNone, 0, AnimationNode::PhaseActive, AnimationNode::PhaseBefore, timing)));
+ EXPECT_EQ(0, calculateActiveTime(20, Timing::FillModeBackwards, 0, AnimationNode::PhaseActive, AnimationNode::PhaseBefore, timing));
+ EXPECT_EQ(0, calculateActiveTime(20, Timing::FillModeBoth, 0, AnimationNode::PhaseActive, AnimationNode::PhaseBefore, timing));
+
+ // Active Phase
+ timing.startDelay = 10;
+ // Active, and parent Before
+ EXPECT_TRUE(isNull(calculateActiveTime(20, Timing::FillModeNone, 15, AnimationNode::PhaseBefore, AnimationNode::PhaseActive, timing)));
+ EXPECT_TRUE(isNull(calculateActiveTime(20, Timing::FillModeForwards, 15, AnimationNode::PhaseBefore, AnimationNode::PhaseActive, timing)));
+ // Active, and parent After
+ EXPECT_TRUE(isNull(calculateActiveTime(20, Timing::FillModeNone, 15, AnimationNode::PhaseAfter, AnimationNode::PhaseActive, timing)));
+ EXPECT_TRUE(isNull(calculateActiveTime(20, Timing::FillModeBackwards, 15, AnimationNode::PhaseAfter, AnimationNode::PhaseActive, timing)));
+ // Active, and parent Active
+ EXPECT_EQ(5, calculateActiveTime(20, Timing::FillModeForwards, 15, AnimationNode::PhaseActive, AnimationNode::PhaseActive, timing));
+
+ // After Phase
+ timing.startDelay = 10;
+ EXPECT_EQ(21, calculateActiveTime(21, Timing::FillModeForwards, 45, AnimationNode::PhaseActive, AnimationNode::PhaseAfter, timing));
+ EXPECT_EQ(21, calculateActiveTime(21, Timing::FillModeBoth, 45, AnimationNode::PhaseActive, AnimationNode::PhaseAfter, timing));
+ EXPECT_TRUE(isNull(calculateActiveTime(21, Timing::FillModeBackwards, 45, AnimationNode::PhaseActive, AnimationNode::PhaseAfter, timing)));
+ EXPECT_TRUE(isNull(calculateActiveTime(21, Timing::FillModeNone, 45, AnimationNode::PhaseActive, AnimationNode::PhaseAfter, timing)));
+
+ // None
+ EXPECT_TRUE(isNull(calculateActiveTime(32, Timing::FillModeNone, nullValue(), AnimationNode::PhaseNone, AnimationNode::PhaseNone, timing)));
+}
+
+TEST(AnimationTimingCalculationsTest, ScaledActiveTime)
+{
+ Timing timing;
+
+ // calculateScaledActiveTime(activeDuration, activeTime, startOffset, timing)
+
+ // if the active time is null
+ EXPECT_TRUE(isNull(calculateScaledActiveTime(4, nullValue(), 5, timing)));
+
+ // if the playback rate is negative
+ timing.playbackRate = -1;
+ EXPECT_EQ(35, calculateScaledActiveTime(40, 10, 5, timing));
+
+ // otherwise
+ timing.playbackRate = 0;
+ EXPECT_EQ(5, calculateScaledActiveTime(40, 10, 5, timing));
+ timing.playbackRate = 1;
+ EXPECT_EQ(15, calculateScaledActiveTime(40, 10, 5, timing));
+
+ // infinte activeTime
+ timing.playbackRate = 0;
+ EXPECT_EQ(0, calculateScaledActiveTime(std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), 0, timing));
+ timing.playbackRate = 1;
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), calculateScaledActiveTime(std::numeric_limits<double>::infinity(), std::numeric_limits<double>::infinity(), 0, timing));
+}
+
+TEST(AnimationTimingCalculationsTest, IterationTime)
+{
+ Timing timing;
+
+ // calculateIterationTime(iterationDuration, repeatedDuration, scaledActiveTime, startOffset, timing)
+
+ // if the scaled active time is null
+ EXPECT_TRUE(isNull(calculateIterationTime(1, 1, nullValue(), 1, timing)));
+
+ // if (complex-conditions)...
+ EXPECT_EQ(12, calculateIterationTime(12, 12, 12, 0, timing));
+
+ // otherwise
+ timing.iterationCount = 10;
+ EXPECT_EQ(5, calculateIterationTime(10, 100, 25, 4, timing));
+ EXPECT_EQ(7, calculateIterationTime(11, 110, 29, 1, timing));
+ timing.iterationStart = 1.1;
+ EXPECT_EQ(8, calculateIterationTime(12, 120, 20, 7, timing));
+}
+
+TEST(AnimationTimingCalculationsTest, CurrentIteration)
+{
+ Timing timing;
+
+ // calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, timing)
+
+ // if the scaled active time is null
+ EXPECT_TRUE(isNull(calculateCurrentIteration(1, 1, nullValue(), timing)));
+
+ // if the scaled active time is zero
+ EXPECT_EQ(0, calculateCurrentIteration(1, 1, 0, timing));
+
+ // if the iteration time equals the iteration duration
+ timing.iterationStart = 4;
+ timing.iterationCount = 7;
+ EXPECT_EQ(10, calculateCurrentIteration(5, 5, 9, timing));
+
+ // otherwise
+ EXPECT_EQ(3, calculateCurrentIteration(3.2, 3.1, 10, timing));
+}
+
+TEST(AnimationTimingCalculationsTest, DirectedTime)
+{
+ Timing timing;
+
+ // calculateDirectedTime(currentIteration, iterationDuration, iterationTime, timing)
+
+ // if the iteration time is null
+ EXPECT_TRUE(isNull(calculateDirectedTime(1, 2, nullValue(), timing)));
+
+ // forwards
+ EXPECT_EQ(17, calculateDirectedTime(0, 20, 17, timing));
+ EXPECT_EQ(17, calculateDirectedTime(1, 20, 17, timing));
+ timing.direction = Timing::PlaybackDirectionAlternate;
+ EXPECT_EQ(17, calculateDirectedTime(0, 20, 17, timing));
+ EXPECT_EQ(17, calculateDirectedTime(2, 20, 17, timing));
+ timing.direction = Timing::PlaybackDirectionAlternateReverse;
+ EXPECT_EQ(17, calculateDirectedTime(1, 20, 17, timing));
+ EXPECT_EQ(17, calculateDirectedTime(3, 20, 17, timing));
+
+ // reverse
+ timing.direction = Timing::PlaybackDirectionReverse;
+ EXPECT_EQ(3, calculateDirectedTime(0, 20, 17, timing));
+ EXPECT_EQ(3, calculateDirectedTime(1, 20, 17, timing));
+ timing.direction = Timing::PlaybackDirectionAlternate;
+ EXPECT_EQ(3, calculateDirectedTime(1, 20, 17, timing));
+ EXPECT_EQ(3, calculateDirectedTime(3, 20, 17, timing));
+ timing.direction = Timing::PlaybackDirectionAlternateReverse;
+ EXPECT_EQ(3, calculateDirectedTime(0, 20, 17, timing));
+ EXPECT_EQ(3, calculateDirectedTime(2, 20, 17, timing));
+}
+
+TEST(AnimationTimingCalculationsTest, TransformedTime)
+{
+ Timing timing;
+
+ // calculateTransformedTime(currentIteration, iterationDuration, iterationTime, timing)
+
+ // Iteration time is null
+ EXPECT_TRUE(isNull(calculateTransformedTime(1, 2, nullValue(), timing)));
+
+ // PlaybackDirectionForwards
+ EXPECT_EQ(12, calculateTransformedTime(0, 20, 12, timing));
+ EXPECT_EQ(12, calculateTransformedTime(1, 20, 12, timing));
+
+ // PlaybackDirectionForwards with timing function
+ timing.timingFunction = StepsTimingFunction::create(4, StepsTimingFunction::StepAtEnd);
+ EXPECT_EQ(10, calculateTransformedTime(0, 20, 12, timing));
+ EXPECT_EQ(10, calculateTransformedTime(1, 20, 12, timing));
+
+ // PlaybackDirectionReverse
+ timing.timingFunction = Timing::defaults().timingFunction;
+ timing.direction = Timing::PlaybackDirectionReverse;
+ EXPECT_EQ(8, calculateTransformedTime(0, 20, 12, timing));
+ EXPECT_EQ(8, calculateTransformedTime(1, 20, 12, timing));
+
+ // PlaybackDirectionReverse with timing function
+ timing.timingFunction = StepsTimingFunction::create(4, StepsTimingFunction::StepAtEnd);
+ EXPECT_EQ(5, calculateTransformedTime(0, 20, 12, timing));
+ EXPECT_EQ(5, calculateTransformedTime(1, 20, 12, timing));
+
+ // Timing function when directed time is null.
+ EXPECT_TRUE(isNull(calculateTransformedTime(1, 2, nullValue(), timing)));
+
+ // Timing function when iterationDuration is infinity
+ timing.direction = Timing::PlaybackDirectionNormal;
+ EXPECT_EQ(0, calculateTransformedTime(0, std::numeric_limits<double>::infinity(), 0, timing));
+ EXPECT_EQ(1, calculateTransformedTime(0, std::numeric_limits<double>::infinity(), 1, timing));
+ timing.direction = Timing::PlaybackDirectionReverse;
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), calculateTransformedTime(0, std::numeric_limits<double>::infinity(), 0, timing));
+ EXPECT_EQ(std::numeric_limits<double>::infinity(), calculateTransformedTime(0, std::numeric_limits<double>::infinity(), 1, timing));
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimingInput.cpp b/chromium/third_party/WebKit/Source/core/animation/TimingInput.cpp
new file mode 100644
index 00000000000..f9eeedaa668
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/TimingInput.cpp
@@ -0,0 +1,154 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/TimingInput.h"
+
+#include "bindings/v8/Dictionary.h"
+#include "core/css/parser/BisonCSSParser.h"
+#include "core/css/resolver/CSSToStyleMap.h"
+
+namespace WebCore {
+
+void TimingInput::setStartDelay(Timing& timing, double startDelay)
+{
+ if (std::isfinite(startDelay))
+ timing.startDelay = startDelay / 1000;
+ else
+ timing.startDelay = Timing::defaults().startDelay;
+}
+
+void TimingInput::setEndDelay(Timing& timing, double endDelay)
+{
+ if (std::isfinite(endDelay))
+ timing.endDelay = endDelay / 1000;
+ else
+ timing.endDelay = Timing::defaults().endDelay;
+}
+
+void TimingInput::setFillMode(Timing& timing, const String& fillMode)
+{
+ if (fillMode == "none") {
+ timing.fillMode = Timing::FillModeNone;
+ } else if (fillMode == "backwards") {
+ timing.fillMode = Timing::FillModeBackwards;
+ } else if (fillMode == "both") {
+ timing.fillMode = Timing::FillModeBoth;
+ } else if (fillMode == "forwards") {
+ timing.fillMode = Timing::FillModeForwards;
+ } else {
+ timing.fillMode = Timing::defaults().fillMode;
+ }
+}
+
+void TimingInput::setIterationStart(Timing& timing, double iterationStart)
+{
+ if (std::isfinite(iterationStart))
+ timing.iterationStart = std::max<double>(iterationStart, 0);
+ else
+ timing.iterationStart = Timing::defaults().iterationStart;
+}
+
+void TimingInput::setIterationCount(Timing& timing, double iterationCount)
+{
+ if (!std::isnan(iterationCount))
+ timing.iterationCount = std::max<double>(iterationCount, 0);
+ else
+ timing.iterationCount = Timing::defaults().iterationCount;
+}
+
+void TimingInput::setIterationDuration(Timing& timing, double iterationDuration)
+{
+ if (!std::isnan(iterationDuration) && iterationDuration >= 0)
+ timing.iterationDuration = iterationDuration / 1000;
+ else
+ timing.iterationDuration = Timing::defaults().iterationDuration;
+}
+
+void TimingInput::setPlaybackRate(Timing& timing, double playbackRate)
+{
+ if (std::isfinite(playbackRate))
+ timing.playbackRate = playbackRate;
+ else
+ timing.playbackRate = Timing::defaults().playbackRate;
+}
+
+void TimingInput::setPlaybackDirection(Timing& timing, const String& direction)
+{
+ if (direction == "reverse") {
+ timing.direction = Timing::PlaybackDirectionReverse;
+ } else if (direction == "alternate") {
+ timing.direction = Timing::PlaybackDirectionAlternate;
+ } else if (direction == "alternate-reverse") {
+ timing.direction = Timing::PlaybackDirectionAlternateReverse;
+ } else {
+ timing.direction = Timing::defaults().direction;
+ }
+}
+
+void TimingInput::setTimingFunction(Timing& timing, const String& timingFunctionString)
+{
+ if (RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString))
+ timing.timingFunction = CSSToStyleMap::mapAnimationTimingFunction(timingFunctionValue.get(), true);
+ else
+ timing.timingFunction = Timing::defaults().timingFunction;
+}
+
+Timing TimingInput::convert(const Dictionary& timingInputDictionary)
+{
+ Timing result;
+
+ // FIXME: This method needs to be refactored to handle invalid
+ // null, NaN, Infinity values better.
+ // See: http://www.w3.org/TR/WebIDL/#es-double
+ double startDelay = Timing::defaults().startDelay;
+ timingInputDictionary.get("delay", startDelay);
+ setStartDelay(result, startDelay);
+
+ double endDelay = Timing::defaults().endDelay;
+ timingInputDictionary.get("endDelay", endDelay);
+ setEndDelay(result, endDelay);
+
+ String fillMode;
+ timingInputDictionary.get("fill", fillMode);
+ setFillMode(result, fillMode);
+
+ double iterationStart = Timing::defaults().iterationStart;
+ timingInputDictionary.get("iterationStart", iterationStart);
+ setIterationStart(result, iterationStart);
+
+ double iterationCount = Timing::defaults().iterationCount;
+ timingInputDictionary.get("iterations", iterationCount);
+ setIterationCount(result, iterationCount);
+
+ double iterationDuration = 0;
+ if (timingInputDictionary.get("duration", iterationDuration)) {
+ setIterationDuration(result, iterationDuration);
+ }
+
+ double playbackRate = Timing::defaults().playbackRate;
+ timingInputDictionary.get("playbackRate", playbackRate);
+ setPlaybackRate(result, playbackRate);
+
+ String direction;
+ timingInputDictionary.get("direction", direction);
+ setPlaybackDirection(result, direction);
+
+ String timingFunctionString;
+ timingInputDictionary.get("easing", timingFunctionString);
+ setTimingFunction(result, timingFunctionString);
+
+ result.assertValid();
+
+ return result;
+}
+
+Timing TimingInput::convert(double duration)
+{
+ Timing result;
+ setIterationDuration(result, duration);
+ return result;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimingInput.h b/chromium/third_party/WebKit/Source/core/animation/TimingInput.h
new file mode 100644
index 00000000000..c338201e092
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/TimingInput.h
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TimingInput_h
+#define TimingInput_h
+
+#include "core/animation/Timing.h"
+
+namespace WebCore {
+
+class Dictionary;
+
+class TimingInput {
+public:
+ static Timing convert(const Dictionary& timingInputDictionary);
+ static Timing convert(double duration);
+
+ static void setStartDelay(Timing&, double startDelay);
+ static void setEndDelay(Timing&, double endDelay);
+ static void setFillMode(Timing&, const String& fillMode);
+ static void setIterationStart(Timing&, double iterationStart);
+ static void setIterationCount(Timing&, double iterationCount);
+ static void setIterationDuration(Timing&, double iterationDuration);
+ static void setPlaybackRate(Timing&, double playbackRate);
+ static void setPlaybackDirection(Timing&, const String& direction);
+ static void setTimingFunction(Timing&, const String& timingFunctionString);
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/TimingInputTest.cpp b/chromium/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
new file mode 100644
index 00000000000..57b6a0893bb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
@@ -0,0 +1,181 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/TimingInput.h"
+
+#include "bindings/v8/Dictionary.h"
+#include "core/animation/AnimationNodeTiming.h"
+#include "core/animation/AnimationTestHelper.h"
+#include <gtest/gtest.h>
+#include <v8.h>
+
+namespace WebCore {
+
+class AnimationTimingInputTest : public ::testing::Test {
+protected:
+ AnimationTimingInputTest()
+ : m_isolate(v8::Isolate::GetCurrent())
+ , m_scope(m_isolate)
+ {
+ }
+
+ Timing applyTimingInputNumber(String timingProperty, double timingPropertyValue)
+ {
+ v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+ setV8ObjectPropertyAsNumber(timingInput, timingProperty, timingPropertyValue);
+ Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+ return TimingInput::convert(timingInputDictionary);
+ }
+
+ Timing applyTimingInputString(String timingProperty, String timingPropertyValue)
+ {
+ v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+ setV8ObjectPropertyAsString(timingInput, timingProperty, timingPropertyValue);
+ Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+ return TimingInput::convert(timingInputDictionary);
+ }
+
+ v8::Isolate* m_isolate;
+
+private:
+ V8TestingScope m_scope;
+};
+
+TEST_F(AnimationTimingInputTest, TimingInputStartDelay)
+{
+ EXPECT_EQ(1.1, applyTimingInputNumber("delay", 1100).startDelay);
+ EXPECT_EQ(-1, applyTimingInputNumber("delay", -1000).startDelay);
+ EXPECT_EQ(1, applyTimingInputString("delay", "1000").startDelay);
+ EXPECT_EQ(0, applyTimingInputString("delay", "1s").startDelay);
+ EXPECT_EQ(0, applyTimingInputString("delay", "Infinity").startDelay);
+ EXPECT_EQ(0, applyTimingInputString("delay", "-Infinity").startDelay);
+ EXPECT_EQ(0, applyTimingInputString("delay", "NaN").startDelay);
+ EXPECT_EQ(0, applyTimingInputString("delay", "rubbish").startDelay);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputEndDelay)
+{
+ EXPECT_EQ(10, applyTimingInputNumber("endDelay", 10000).endDelay);
+ EXPECT_EQ(-2.5, applyTimingInputNumber("endDelay", -2500).endDelay);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputFillMode)
+{
+ Timing::FillMode defaultFillMode = Timing::FillModeAuto;
+
+ EXPECT_EQ(Timing::FillModeAuto, applyTimingInputString("fill", "auto").fillMode);
+ EXPECT_EQ(Timing::FillModeForwards, applyTimingInputString("fill", "forwards").fillMode);
+ EXPECT_EQ(Timing::FillModeNone, applyTimingInputString("fill", "none").fillMode);
+ EXPECT_EQ(Timing::FillModeBackwards, applyTimingInputString("fill", "backwards").fillMode);
+ EXPECT_EQ(Timing::FillModeBoth, applyTimingInputString("fill", "both").fillMode);
+ EXPECT_EQ(defaultFillMode, applyTimingInputString("fill", "everything!").fillMode);
+ EXPECT_EQ(defaultFillMode, applyTimingInputString("fill", "backwardsandforwards").fillMode);
+ EXPECT_EQ(defaultFillMode, applyTimingInputNumber("fill", 2).fillMode);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputIterationStart)
+{
+ EXPECT_EQ(1.1, applyTimingInputNumber("iterationStart", 1.1).iterationStart);
+ EXPECT_EQ(0, applyTimingInputNumber("iterationStart", -1).iterationStart);
+ EXPECT_EQ(0, applyTimingInputString("iterationStart", "Infinity").iterationStart);
+ EXPECT_EQ(0, applyTimingInputString("iterationStart", "-Infinity").iterationStart);
+ EXPECT_EQ(0, applyTimingInputString("iterationStart", "NaN").iterationStart);
+ EXPECT_EQ(0, applyTimingInputString("iterationStart", "rubbish").iterationStart);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputIterationCount)
+{
+ EXPECT_EQ(2.1, applyTimingInputNumber("iterations", 2.1).iterationCount);
+ EXPECT_EQ(0, applyTimingInputNumber("iterations", -1).iterationCount);
+
+ Timing timing = applyTimingInputString("iterations", "Infinity");
+ EXPECT_TRUE(std::isinf(timing.iterationCount));
+ EXPECT_GT(timing.iterationCount, 0);
+
+ EXPECT_EQ(0, applyTimingInputString("iterations", "-Infinity").iterationCount);
+ EXPECT_EQ(1, applyTimingInputString("iterations", "NaN").iterationCount);
+ EXPECT_EQ(1, applyTimingInputString("iterations", "rubbish").iterationCount);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputIterationDuration)
+{
+ EXPECT_EQ(1.1, applyTimingInputNumber("duration", 1100).iterationDuration);
+ EXPECT_TRUE(std::isnan(applyTimingInputNumber("duration", -1000).iterationDuration));
+ EXPECT_EQ(1, applyTimingInputString("duration", "1000").iterationDuration);
+
+ Timing timing = applyTimingInputString("duration", "Infinity");
+ EXPECT_TRUE(std::isinf(timing.iterationDuration));
+ EXPECT_GT(timing.iterationDuration, 0);
+
+ EXPECT_TRUE(std::isnan(applyTimingInputString("duration", "-Infinity").iterationDuration));
+ EXPECT_TRUE(std::isnan(applyTimingInputString("duration", "NaN").iterationDuration));
+ EXPECT_TRUE(std::isnan(applyTimingInputString("duration", "auto").iterationDuration));
+ EXPECT_TRUE(std::isnan(applyTimingInputString("duration", "rubbish").iterationDuration));
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputPlaybackRate)
+{
+ EXPECT_EQ(2.1, applyTimingInputNumber("playbackRate", 2.1).playbackRate);
+ EXPECT_EQ(-1, applyTimingInputNumber("playbackRate", -1).playbackRate);
+ EXPECT_EQ(1, applyTimingInputString("playbackRate", "Infinity").playbackRate);
+ EXPECT_EQ(1, applyTimingInputString("playbackRate", "-Infinity").playbackRate);
+ EXPECT_EQ(1, applyTimingInputString("playbackRate", "NaN").playbackRate);
+ EXPECT_EQ(1, applyTimingInputString("playbackRate", "rubbish").playbackRate);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputDirection)
+{
+ Timing::PlaybackDirection defaultPlaybackDirection = Timing::PlaybackDirectionNormal;
+
+ EXPECT_EQ(Timing::PlaybackDirectionNormal, applyTimingInputString("direction", "normal").direction);
+ EXPECT_EQ(Timing::PlaybackDirectionReverse, applyTimingInputString("direction", "reverse").direction);
+ EXPECT_EQ(Timing::PlaybackDirectionAlternate, applyTimingInputString("direction", "alternate").direction);
+ EXPECT_EQ(Timing::PlaybackDirectionAlternateReverse, applyTimingInputString("direction", "alternate-reverse").direction);
+ EXPECT_EQ(defaultPlaybackDirection, applyTimingInputString("direction", "rubbish").direction);
+ EXPECT_EQ(defaultPlaybackDirection, applyTimingInputNumber("direction", 2).direction);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputTimingFunction)
+{
+ const RefPtr<TimingFunction> defaultTimingFunction = LinearTimingFunction::shared();
+
+ EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease), *applyTimingInputString("easing", "ease").timingFunction);
+ EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn), *applyTimingInputString("easing", "ease-in").timingFunction);
+ EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut), *applyTimingInputString("easing", "ease-out").timingFunction);
+ EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut), *applyTimingInputString("easing", "ease-in-out").timingFunction);
+ EXPECT_EQ(*LinearTimingFunction::shared(), *applyTimingInputString("easing", "linear").timingFunction);
+ EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::Start), *applyTimingInputString("easing", "step-start").timingFunction);
+ EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::Middle), *applyTimingInputString("easing", "step-middle").timingFunction);
+ EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::End), *applyTimingInputString("easing", "step-end").timingFunction);
+ EXPECT_EQ(*CubicBezierTimingFunction::create(1, 1, 0.3, 0.3), *applyTimingInputString("easing", "cubic-bezier(1, 1, 0.3, 0.3)").timingFunction);
+ EXPECT_EQ(*StepsTimingFunction::create(3, StepsTimingFunction::StepAtStart), *applyTimingInputString("easing", "steps(3, start)").timingFunction);
+ EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepAtMiddle), *applyTimingInputString("easing", "steps(5, middle)").timingFunction);
+ EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepAtEnd), *applyTimingInputString("easing", "steps(5, end)").timingFunction);
+ EXPECT_EQ(*defaultTimingFunction, *applyTimingInputString("easing", "steps(5.6, end)").timingFunction);
+ EXPECT_EQ(*defaultTimingFunction, *applyTimingInputString("easing", "cubic-bezier(2, 2, 0.3, 0.3)").timingFunction);
+ EXPECT_EQ(*defaultTimingFunction, *applyTimingInputString("easing", "rubbish").timingFunction);
+ EXPECT_EQ(*defaultTimingFunction, *applyTimingInputNumber("easing", 2).timingFunction);
+ EXPECT_EQ(*defaultTimingFunction, *applyTimingInputString("easing", "initial").timingFunction);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputEmpty)
+{
+ Timing controlTiming;
+
+ v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+ Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+ Timing updatedTiming = TimingInput::convert(timingInputDictionary);
+
+ EXPECT_EQ(controlTiming.startDelay, updatedTiming.startDelay);
+ EXPECT_EQ(controlTiming.fillMode, updatedTiming.fillMode);
+ EXPECT_EQ(controlTiming.iterationStart, updatedTiming.iterationStart);
+ EXPECT_EQ(controlTiming.iterationCount, updatedTiming.iterationCount);
+ EXPECT_TRUE(std::isnan(updatedTiming.iterationDuration));
+ EXPECT_EQ(controlTiming.playbackRate, updatedTiming.playbackRate);
+ EXPECT_EQ(controlTiming.direction, updatedTiming.direction);
+ EXPECT_EQ(*controlTiming.timingFunction, *updatedTiming.timingFunction);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
index 41138cdd177..b401069725e 100644
--- a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "core/animation/css/CSSAnimatableValueFactory.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "core/animation/AnimatableClipPathOperation.h"
#include "core/animation/AnimatableColor.h"
#include "core/animation/AnimatableDouble.h"
@@ -41,6 +41,7 @@
#include "core/animation/AnimatableLengthBox.h"
#include "core/animation/AnimatableLengthBoxAndBool.h"
#include "core/animation/AnimatableLengthPoint.h"
+#include "core/animation/AnimatableLengthPoint3D.h"
#include "core/animation/AnimatableLengthSize.h"
#include "core/animation/AnimatableRepeatable.h"
#include "core/animation/AnimatableSVGLength.h"
@@ -61,23 +62,13 @@
namespace WebCore {
-static PassRefPtr<AnimatableValue> createFromLength(const Length& length, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<AnimatableValue> createFromLength(const Length& length, const RenderStyle& style)
{
switch (length.type()) {
case Fixed:
- return AnimatableLength::create(adjustFloatForAbsoluteZoom(length.value(), style), AnimatableLength::UnitTypePixels);
case Percent:
- return AnimatableLength::create(length.value(), AnimatableLength::UnitTypePercentage);
- case ViewportPercentageWidth:
- return AnimatableLength::create(length.value(), AnimatableLength::UnitTypeViewportWidth);
- case ViewportPercentageHeight:
- return AnimatableLength::create(length.value(), AnimatableLength::UnitTypeViewportHeight);
- case ViewportPercentageMin:
- return AnimatableLength::create(length.value(), AnimatableLength::UnitTypeViewportMin);
- case ViewportPercentageMax:
- return AnimatableLength::create(length.value(), AnimatableLength::UnitTypeViewportMax);
case Calculated:
- return AnimatableLength::create(CSSCalcValue::createExpressionNode(length.calculationValue()->expression(), style.effectiveZoom()));
+ return AnimatableLength::create(length, style.effectiveZoom());
case Auto:
case Intrinsic:
case MinIntrinsic:
@@ -85,18 +76,20 @@ static PassRefPtr<AnimatableValue> createFromLength(const Length& length, const
case MaxContent:
case FillAvailable:
case FitContent:
- return AnimatableUnknown::create(CSSPrimitiveValue::create(length));
+ return AnimatableUnknown::create(CSSPrimitiveValue::create(length, 1));
case Undefined:
return AnimatableUnknown::create(CSSValueNone);
case ExtendToZoom: // Does not apply to elements.
+ case DeviceWidth:
+ case DeviceHeight:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
-static PassRefPtr<AnimatableValue> createFromLineHeight(const Length& length, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<AnimatableValue> createFromLineHeight(const Length& length, const RenderStyle& style)
{
if (length.type() == Percent) {
double value = length.value();
@@ -108,12 +101,12 @@ static PassRefPtr<AnimatableValue> createFromLineHeight(const Length& length, co
return createFromLength(length, style);
}
-inline static PassRefPtr<AnimatableValue> createFromDouble(double value, AnimatableDouble::Constraint constraint = AnimatableDouble::Unconstrained)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromDouble(double value, AnimatableDouble::Constraint constraint = AnimatableDouble::Unconstrained)
{
return AnimatableDouble::create(value, constraint);
}
-inline static PassRefPtr<AnimatableValue> createFromLengthBox(const LengthBox& lengthBox, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromLengthBox(const LengthBox& lengthBox, const RenderStyle& style)
{
return AnimatableLengthBox::create(
createFromLength(lengthBox.left(), style),
@@ -122,14 +115,14 @@ inline static PassRefPtr<AnimatableValue> createFromLengthBox(const LengthBox& l
createFromLength(lengthBox.bottom(), style));
}
-static PassRefPtr<AnimatableValue> createFromBorderImageLength(const BorderImageLength& borderImageLength, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<AnimatableValue> createFromBorderImageLength(const BorderImageLength& borderImageLength, const RenderStyle& style)
{
if (borderImageLength.isNumber())
return createFromDouble(borderImageLength.number());
return createFromLength(borderImageLength.length(), style);
}
-inline static PassRefPtr<AnimatableValue> createFromBorderImageLengthBox(const BorderImageLengthBox& borderImageLengthBox, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromBorderImageLengthBox(const BorderImageLengthBox& borderImageLengthBox, const RenderStyle& style)
{
return AnimatableLengthBox::create(
createFromBorderImageLength(borderImageLengthBox.left(), style),
@@ -138,35 +131,37 @@ inline static PassRefPtr<AnimatableValue> createFromBorderImageLengthBox(const B
createFromBorderImageLength(borderImageLengthBox.bottom(), style));
}
-inline static PassRefPtr<AnimatableValue> createFromLengthBoxAndBool(const LengthBox lengthBox, const bool flag, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromLengthBoxAndBool(const LengthBox lengthBox, const bool flag, const RenderStyle& style)
{
return AnimatableLengthBoxAndBool::create(
createFromLengthBox(lengthBox, style),
flag);
}
-inline static PassRefPtr<AnimatableValue> createFromLengthPoint(const LengthPoint& lengthPoint, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromLengthPoint(const LengthPoint& lengthPoint, const RenderStyle& style)
{
return AnimatableLengthPoint::create(
createFromLength(lengthPoint.x(), style),
createFromLength(lengthPoint.y(), style));
}
-inline static PassRefPtr<AnimatableValue> createFromLengthSize(const LengthSize& lengthSize, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromLengthSize(const LengthSize& lengthSize, const RenderStyle& style)
{
return AnimatableLengthSize::create(
createFromLength(lengthSize.width(), style),
createFromLength(lengthSize.height(), style));
}
-inline static PassRefPtr<AnimatableValue> createFromStyleImage(StyleImage* image)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromStyleImage(StyleImage* image)
{
- if (image)
- return AnimatableImage::create(image);
+ if (image) {
+ if (RefPtrWillBeRawPtr<CSSValue> cssValue = image->cssValue())
+ return AnimatableImage::create(cssValue.release());
+ }
return AnimatableUnknown::create(CSSValueNone);
}
-inline static PassRefPtr<AnimatableValue> createFromFillSize(const FillSize& fillSize, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromFillSize(const FillSize& fillSize, const RenderStyle& style)
{
switch (fillSize.type) {
case SizeLength:
@@ -177,15 +172,22 @@ inline static PassRefPtr<AnimatableValue> createFromFillSize(const FillSize& fil
return AnimatableUnknown::create(CSSPrimitiveValue::create(fillSize.type));
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
}
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromBackgroundPosition(const Length& length, bool originIsSet, BackgroundEdgeOrigin origin, const RenderStyle& style)
+{
+ if (!originIsSet || origin == LeftEdge || origin == TopEdge)
+ return createFromLength(length, style);
+ return createFromLength(length.subtractFromOneHundredPercent(), style);
+}
+
template<CSSPropertyID property>
-inline static PassRefPtr<AnimatableValue> createFromFillLayers(const FillLayer* fillLayer, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromFillLayers(const FillLayer* fillLayer, const RenderStyle& style)
{
ASSERT(fillLayer);
- Vector<RefPtr<AnimatableValue> > values;
+ WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> > values;
while (fillLayer) {
if (property == CSSPropertyBackgroundImage || property == CSSPropertyWebkitMaskImage) {
if (!fillLayer->isImageSet())
@@ -194,11 +196,11 @@ inline static PassRefPtr<AnimatableValue> createFromFillLayers(const FillLayer*
} else if (property == CSSPropertyBackgroundPositionX || property == CSSPropertyWebkitMaskPositionX) {
if (!fillLayer->isXPositionSet())
break;
- values.append(createFromLength(fillLayer->xPosition(), style));
+ values.append(createFromBackgroundPosition(fillLayer->xPosition(), fillLayer->isBackgroundXOriginSet(), fillLayer->backgroundXOrigin(), style));
} else if (property == CSSPropertyBackgroundPositionY || property == CSSPropertyWebkitMaskPositionY) {
if (!fillLayer->isYPositionSet())
break;
- values.append(createFromLength(fillLayer->yPosition(), style));
+ values.append(createFromBackgroundPosition(fillLayer->yPosition(), fillLayer->isBackgroundYOriginSet(), fillLayer->backgroundYOrigin(), style));
} else if (property == CSSPropertyBackgroundSize || property == CSSPropertyWebkitMaskSize) {
if (!fillLayer->isSizeSet())
break;
@@ -211,42 +213,56 @@ inline static PassRefPtr<AnimatableValue> createFromFillLayers(const FillLayer*
return AnimatableRepeatable::create(values);
}
-PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::createFromColor(CSSPropertyID property, const RenderStyle& style)
+PassRefPtrWillBeRawPtr<AnimatableValue> CSSAnimatableValueFactory::createFromColor(CSSPropertyID property, const RenderStyle& style)
{
Color color = style.colorIncludingFallback(property, false);
Color visitedLinkColor = style.colorIncludingFallback(property, true);
- Color fallbackColor = style.color();
- Color fallbackVisitedLinkColor = style.visitedLinkColor();
- Color resolvedColor;
+ return AnimatableColor::create(color, visitedLinkColor);
+}
+
+inline static PassRefPtrWillBeRawPtr<AnimatableValue> createFromShapeValue(ShapeValue* value)
+{
+ if (value)
+ return AnimatableShapeValue::create(value);
+ return AnimatableUnknown::create(CSSValueNone);
+}
- if (property == CSSPropertyBackgroundColor) {
- // For background-color, invalid color means transparent and not currentColor.
- fallbackColor = Color::transparent;
- fallbackVisitedLinkColor = Color::transparent;
+static double fontWeightToDouble(FontWeight fontWeight)
+{
+ switch (fontWeight) {
+ case FontWeight100:
+ return 100;
+ case FontWeight200:
+ return 200;
+ case FontWeight300:
+ return 300;
+ case FontWeight400:
+ return 400;
+ case FontWeight500:
+ return 500;
+ case FontWeight600:
+ return 600;
+ case FontWeight700:
+ return 700;
+ case FontWeight800:
+ return 800;
+ case FontWeight900:
+ return 900;
}
- if (color.isValid())
- resolvedColor = color;
- else
- resolvedColor = fallbackColor;
- Color resolvedVisitedLinkColor;
- if (visitedLinkColor.isValid())
- resolvedVisitedLinkColor = visitedLinkColor;
- else
- resolvedVisitedLinkColor = fallbackVisitedLinkColor;
- return AnimatableColor::create(resolvedColor, resolvedVisitedLinkColor);
+ ASSERT_NOT_REACHED();
+ return 400;
}
-inline static PassRefPtr<AnimatableValue> createFromShapeValue(ShapeValue* value)
+static PassRefPtrWillBeRawPtr<AnimatableValue> createFromFontWeight(FontWeight fontWeight)
{
- if (value)
- return AnimatableShapeValue::create(value);
- return AnimatableUnknown::create(CSSValueAuto);
+ return createFromDouble(fontWeightToDouble(fontWeight));
}
// FIXME: Generate this function.
-PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID property, const RenderStyle& style)
+PassRefPtrWillBeRawPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID property, const RenderStyle& style)
{
+ ASSERT(CSSAnimations::isAnimatableProperty(property));
switch (property) {
case CSSPropertyBackgroundColor:
return createFromColor(property, style);
@@ -307,7 +323,10 @@ PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID prop
case CSSPropertyFillOpacity:
return createFromDouble(style.fillOpacity());
case CSSPropertyFill:
- return AnimatableSVGPaint::create(style.svgStyle()->fillPaintType(), style.svgStyle()->fillPaintColor(), style.svgStyle()->fillPaintUri());
+ return AnimatableSVGPaint::create(
+ style.svgStyle()->fillPaintType(), style.svgStyle()->visitedLinkFillPaintType(),
+ style.svgStyle()->fillPaintColor(), style.svgStyle()->visitedLinkFillPaintColor(),
+ style.svgStyle()->fillPaintUri(), style.svgStyle()->visitedLinkFillPaintUri());
case CSSPropertyFlexGrow:
return createFromDouble(style.flexGrow(), AnimatableDouble::InterpolationIsNonContinuousWithZero);
case CSSPropertyFlexShrink:
@@ -324,10 +343,10 @@ PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID prop
// FIXME: Should we introduce an option to pass the computed font size here, allowing consumers to
// enable text zoom rather than Text Autosizing? See http://crbug.com/227545.
return createFromDouble(style.specifiedFontSize());
+ case CSSPropertyFontWeight:
+ return createFromFontWeight(style.fontWeight());
case CSSPropertyHeight:
return createFromLength(style.height(), style);
- case CSSPropertyKerning:
- return AnimatableSVGLength::create(style.kerning());
case CSSPropertyLightingColor:
return createFromColor(property, style);
case CSSPropertyListStyleImage:
@@ -391,9 +410,12 @@ PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID prop
case CSSPropertyStrokeOpacity:
return createFromDouble(style.strokeOpacity());
case CSSPropertyStroke:
- return AnimatableSVGPaint::create(style.svgStyle()->strokePaintType(), style.svgStyle()->strokePaintColor(), style.svgStyle()->strokePaintUri());
+ return AnimatableSVGPaint::create(
+ style.svgStyle()->strokePaintType(), style.svgStyle()->visitedLinkStrokePaintType(),
+ style.svgStyle()->strokePaintColor(), style.svgStyle()->visitedLinkStrokePaintColor(),
+ style.svgStyle()->strokePaintUri(), style.svgStyle()->visitedLinkStrokePaintUri());
case CSSPropertyTextDecorationColor:
- return createFromColor(property, style);
+ return AnimatableColor::create(style.textDecorationColor().resolve(style.color()), style.visitedLinkTextDecorationColor().resolve(style.visitedLinkColor()));
case CSSPropertyTextIndent:
return createFromLength(style.textIndent(), style);
case CSSPropertyTextShadow:
@@ -436,14 +458,19 @@ PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID prop
return createFromFillLayers<CSSPropertyWebkitMaskPositionY>(style.maskLayers(), style);
case CSSPropertyWebkitMaskSize:
return createFromFillLayers<CSSPropertyWebkitMaskSize>(style.maskLayers(), style);
- case CSSPropertyWebkitPerspective:
+ case CSSPropertyPerspective:
return createFromDouble(style.perspective());
+ case CSSPropertyPerspectiveOrigin:
+ ASSERT(RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
+ return AnimatableLengthPoint::create(
+ createFromLength(style.perspectiveOriginX(), style),
+ createFromLength(style.perspectiveOriginY(), style));
case CSSPropertyWebkitPerspectiveOriginX:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
return createFromLength(style.perspectiveOriginX(), style);
case CSSPropertyWebkitPerspectiveOriginY:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
return createFromLength(style.perspectiveOriginY(), style);
- case CSSPropertyShapeInside:
- return createFromShapeValue(style.shapeInside());
case CSSPropertyShapeOutside:
return createFromShapeValue(style.shapeOutside());
case CSSPropertyShapeMargin:
@@ -452,13 +479,22 @@ PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID prop
return createFromDouble(style.shapeImageThreshold());
case CSSPropertyWebkitTextStrokeColor:
return createFromColor(property, style);
- case CSSPropertyWebkitTransform:
+ case CSSPropertyTransform:
return AnimatableTransform::create(style.transform());
+ case CSSPropertyTransformOrigin:
+ ASSERT(RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
+ return AnimatableLengthPoint3D::create(
+ createFromLength(style.transformOriginX(), style),
+ createFromLength(style.transformOriginY(), style),
+ createFromDouble(style.transformOriginZ()));
case CSSPropertyWebkitTransformOriginX:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
return createFromLength(style.transformOriginX(), style);
case CSSPropertyWebkitTransformOriginY:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
return createFromLength(style.transformOriginY(), style);
case CSSPropertyWebkitTransformOriginZ:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
return createFromDouble(style.transformOriginZ());
case CSSPropertyWidows:
return createFromDouble(style.widows());
@@ -466,6 +502,10 @@ PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID prop
return createFromLength(style.width(), style);
case CSSPropertyWordSpacing:
return createFromDouble(style.wordSpacing());
+ case CSSPropertyVerticalAlign:
+ if (style.verticalAlign() == LENGTH)
+ return createFromLength(style.verticalAlignLength(), style);
+ return AnimatableUnknown::create(CSSPrimitiveValue::create(style.verticalAlign()));
case CSSPropertyVisibility:
return AnimatableVisibility::create(style.visibility());
case CSSPropertyZIndex:
@@ -473,10 +513,9 @@ PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID prop
case CSSPropertyZoom:
return createFromDouble(style.zoom());
default:
- ASSERT_WITH_MESSAGE(!CSSAnimations::isAnimatableProperty(property), "Web Animations not yet implemented: Create AnimatableValue from render style: %s", getPropertyNameString(property).utf8().data());
ASSERT_NOT_REACHED();
// This return value is to avoid a release crash if possible.
- return AnimatableUnknown::create(0);
+ return AnimatableUnknown::create(nullptr);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.h b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.h
index bac18c19241..7e6ea3dc03d 100644
--- a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.h
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.h
@@ -31,7 +31,7 @@
#ifndef CSSAnimatableValueFactory_h
#define CSSAnimatableValueFactory_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/animation/AnimatableValue.h"
#include "wtf/PassRefPtr.h"
@@ -41,9 +41,9 @@ class RenderStyle;
class CSSAnimatableValueFactory {
public:
- static PassRefPtr<AnimatableValue> create(CSSPropertyID, const RenderStyle&);
+ static PassRefPtrWillBeRawPtr<AnimatableValue> create(CSSPropertyID, const RenderStyle&);
private:
- static PassRefPtr<AnimatableValue> createFromColor(CSSPropertyID, const RenderStyle&);
+ static PassRefPtrWillBeRawPtr<AnimatableValue> createFromColor(CSSPropertyID, const RenderStyle&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp
new file mode 100644
index 00000000000..bda53a4f535
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/css/CSSAnimationData.h"
+
+#include "core/animation/Timing.h"
+
+namespace WebCore {
+
+CSSAnimationData::CSSAnimationData()
+{
+ m_nameList.append(initialName());
+ m_iterationCountList.append(initialIterationCount());
+ m_directionList.append(initialDirection());
+ m_fillModeList.append(initialFillMode());
+ m_playStateList.append(initialPlayState());
+}
+
+CSSAnimationData::CSSAnimationData(const CSSAnimationData& other)
+ : CSSTimingData(other)
+ , m_nameList(other.m_nameList)
+ , m_iterationCountList(other.m_iterationCountList)
+ , m_directionList(other.m_directionList)
+ , m_fillModeList(other.m_fillModeList)
+ , m_playStateList(other.m_playStateList)
+{
+}
+
+const AtomicString& CSSAnimationData::initialName()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, name, ("none", AtomicString::ConstructFromLiteral));
+ return name;
+}
+
+bool CSSAnimationData::animationsMatchForStyleRecalc(const CSSAnimationData& other) const
+{
+ return m_nameList == other.m_nameList && m_playStateList == other.m_playStateList;
+}
+
+Timing CSSAnimationData::convertToTiming(size_t index) const
+{
+ ASSERT(index < m_nameList.size());
+ Timing timing = CSSTimingData::convertToTiming(index);
+
+ timing.iterationCount = getRepeated(m_iterationCountList, index);
+ timing.direction = getRepeated(m_directionList, index);
+ timing.fillMode = getRepeated(m_fillModeList, index);
+ timing.assertValid();
+ return timing;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimationData.h b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimationData.h
new file mode 100644
index 00000000000..5a23feedcc4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimationData.h
@@ -0,0 +1,61 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSSAnimationData_h
+#define CSSAnimationData_h
+
+#include "core/animation/Timing.h"
+#include "core/animation/css/CSSTimingData.h"
+#include "core/rendering/style/RenderStyleConstants.h"
+
+namespace WebCore {
+
+class CSSAnimationData FINAL : public CSSTimingData {
+public:
+ static PassOwnPtrWillBeRawPtr<CSSAnimationData> create()
+ {
+ return adoptPtrWillBeNoop(new CSSAnimationData);
+ }
+
+ static PassOwnPtrWillBeRawPtr<CSSAnimationData> create(const CSSAnimationData& animationData)
+ {
+ return adoptPtrWillBeNoop(new CSSAnimationData(animationData));
+ }
+
+ bool animationsMatchForStyleRecalc(const CSSAnimationData& other) const;
+
+ Timing convertToTiming(size_t index) const;
+
+ const Vector<AtomicString>& nameList() const { return m_nameList; }
+ const Vector<double>& iterationCountList() const { return m_iterationCountList; }
+ const Vector<Timing::PlaybackDirection>& directionList() const { return m_directionList; }
+ const Vector<Timing::FillMode>& fillModeList() const { return m_fillModeList; }
+ const Vector<EAnimPlayState>& playStateList() const { return m_playStateList; }
+
+ Vector<AtomicString>& nameList() { return m_nameList; }
+ Vector<double>& iterationCountList() { return m_iterationCountList; }
+ Vector<Timing::PlaybackDirection>& directionList() { return m_directionList; }
+ Vector<Timing::FillMode>& fillModeList() { return m_fillModeList; }
+ Vector<EAnimPlayState>& playStateList() { return m_playStateList; }
+
+ static const AtomicString& initialName();
+ static Timing::PlaybackDirection initialDirection() { return Timing::PlaybackDirectionNormal; }
+ static Timing::FillMode initialFillMode() { return Timing::FillModeNone; }
+ static double initialIterationCount() { return 1.0; }
+ static EAnimPlayState initialPlayState() { return AnimPlayStatePlaying; }
+
+private:
+ CSSAnimationData();
+ explicit CSSAnimationData(const CSSAnimationData&);
+
+ Vector<AtomicString> m_nameList;
+ Vector<double> m_iterationCountList;
+ Vector<Timing::PlaybackDirection> m_directionList;
+ Vector<Timing::FillMode> m_fillModeList;
+ Vector<EAnimPlayState> m_playStateList;
+};
+
+} // namespace WebCore
+
+#endif // CSSAnimationData_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
index 807c59096b5..05e358ec619 100644
--- a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp
@@ -31,25 +31,26 @@
#include "config.h"
#include "core/animation/css/CSSAnimations.h"
-#include "StylePropertyShorthand.h"
+#include "core/StylePropertyShorthand.h"
#include "core/animation/ActiveAnimations.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/animation/CompositorAnimations.h"
-#include "core/animation/DocumentTimeline.h"
-#include "core/animation/KeyframeAnimationEffect.h"
+#include "core/animation/KeyframeEffectModel.h"
#include "core/animation/css/CSSAnimatableValueFactory.h"
+#include "core/animation/css/CSSPropertyEquality.h"
+#include "core/animation/interpolation/LegacyStyleInterpolation.h"
#include "core/css/CSSKeyframeRule.h"
+#include "core/css/resolver/CSSToStyleMap.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Element.h"
#include "core/dom/PseudoElement.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/TransitionEvent.h"
#include "core/events/WebKitAnimationEvent.h"
#include "core/frame/UseCounter.h"
-#include "core/frame/animation/CSSPropertyAnimation.h"
-#include "core/platform/animation/CSSAnimationDataList.h"
-#include "core/platform/animation/TimingFunction.h"
+#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/style/KeyframeList.h"
+#include "platform/animation/TimingFunction.h"
#include "public/platform/Platform.h"
#include "wtf/BitArray.h"
#include "wtf/HashSet.h"
@@ -58,90 +59,81 @@ namespace WebCore {
namespace {
-bool isEarlierPhase(TimedItem::Phase target, TimedItem::Phase reference)
+CSSPropertyID propertyForAnimation(CSSPropertyID property)
{
- ASSERT(target != TimedItem::PhaseNone);
- ASSERT(reference != TimedItem::PhaseNone);
- return target < reference;
-}
-
-bool isLaterPhase(TimedItem::Phase target, TimedItem::Phase reference)
-{
- ASSERT(target != TimedItem::PhaseNone);
- ASSERT(reference != TimedItem::PhaseNone);
- return target > reference;
-}
-
-static PassRefPtr<TimingFunction> generateTimingFunction(const KeyframeAnimationEffect::KeyframeVector keyframes, const HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions)
-{
- // Generate the chained timing function. Note that timing functions apply
- // from the keyframe in which they're specified to the next keyframe.
- bool isTimingFunctionLinearThroughout = true;
- RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create();
- for (size_t i = 0; i < keyframes.size() - 1; ++i) {
- double lowerBound = keyframes[i]->offset();
- ASSERT(lowerBound >=0 && lowerBound < 1);
- double upperBound = keyframes[i + 1]->offset();
- ASSERT(upperBound > 0 && upperBound <= 1);
- TimingFunction* timingFunction = perKeyframeTimingFunctions.get(lowerBound);
- isTimingFunctionLinearThroughout &= timingFunction->type() == TimingFunction::LinearFunction;
- chainedTimingFunction->appendSegment(upperBound, timingFunction);
- }
- if (isTimingFunctionLinearThroughout)
- return LinearTimingFunction::create();
- return chainedTimingFunction;
+ switch (property) {
+ case CSSPropertyWebkitPerspective:
+ return CSSPropertyPerspective;
+ case CSSPropertyWebkitTransform:
+ return CSSPropertyTransform;
+ case CSSPropertyWebkitPerspectiveOriginX:
+ case CSSPropertyWebkitPerspectiveOriginY:
+ if (RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled())
+ return CSSPropertyPerspectiveOrigin;
+ break;
+ case CSSPropertyWebkitTransformOriginX:
+ case CSSPropertyWebkitTransformOriginY:
+ case CSSPropertyWebkitTransformOriginZ:
+ if (RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled())
+ return CSSPropertyTransformOrigin;
+ break;
+ default:
+ break;
+ }
+ return property;
}
static void resolveKeyframes(StyleResolver* resolver, Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction,
- Vector<std::pair<KeyframeAnimationEffect::KeyframeVector, RefPtr<TimingFunction> > >& keyframesAndTimingFunctions)
+ AnimatableValueKeyframeVector& keyframes)
{
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
// When the element is null, use its parent for scoping purposes.
const Element* elementForScoping = element ? element : &parentElement;
const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframesRule(resolver, elementForScoping, name.impl());
if (!keyframesRule)
return;
- const Vector<RefPtr<StyleKeyframe> >& styleKeyframes = keyframesRule->keyframes();
+ const WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >& styleKeyframes = keyframesRule->keyframes();
if (styleKeyframes.isEmpty())
return;
// Construct and populate the style for each keyframe
- PropertySet specifiedProperties;
- KeyframeAnimationEffect::KeyframeVector keyframes;
- HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions;
+ PropertySet specifiedPropertiesForUseCounter;
for (size_t i = 0; i < styleKeyframes.size(); ++i) {
const StyleKeyframe* styleKeyframe = styleKeyframes[i].get();
// It's OK to pass a null element here.
RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element, style, parentStyle, styleKeyframe, name);
- RefPtr<Keyframe> keyframe = Keyframe::create();
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> keyframe = AnimatableValueKeyframe::create();
const Vector<double>& offsets = styleKeyframe->keys();
ASSERT(!offsets.isEmpty());
keyframe->setOffset(offsets[0]);
- TimingFunction* timingFunction = defaultTimingFunction;
- const StylePropertySet* properties = styleKeyframe->properties();
- for (unsigned j = 0; j < properties->propertyCount(); j++) {
- CSSPropertyID property = properties->propertyAt(j).id();
- specifiedProperties.add(property);
- if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction)
- timingFunction = KeyframeValue::timingFunction(*keyframeStyle);
- else if (CSSAnimations::isAnimatableProperty(property))
+ keyframe->setEasing(defaultTimingFunction);
+ const StylePropertySet& properties = styleKeyframe->properties();
+ for (unsigned j = 0; j < properties.propertyCount(); j++) {
+ specifiedPropertiesForUseCounter.add(properties.propertyAt(j).id());
+ CSSPropertyID property = propertyForAnimation(properties.propertyAt(j).id());
+ if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction) {
+ CSSValue* value = properties.propertyAt(j).value();
+ RefPtr<TimingFunction> timingFunction;
+ if (value->isInheritedValue() && parentStyle->animations())
+ timingFunction = parentStyle->animations()->timingFunctionList()[0];
+ else if (value->isInheritedValue() || value->isInitialValue())
+ timingFunction = CSSTimingData::initialTimingFunction();
+ else
+ timingFunction = CSSToStyleMap::mapAnimationTimingFunction(toCSSValueList(value)->item(0));
+ keyframe->setEasing(timingFunction.release());
+ } else if (CSSAnimations::isAnimatableProperty(property)) {
keyframe->setPropertyValue(property, CSSAnimatableValueFactory::create(property, *keyframeStyle).get());
+ }
}
keyframes.append(keyframe);
// The last keyframe specified at a given offset is used.
- perKeyframeTimingFunctions.set(offsets[0], timingFunction);
for (size_t j = 1; j < offsets.size(); ++j) {
- keyframes.append(keyframe->cloneWithOffset(offsets[j]));
- perKeyframeTimingFunctions.set(offsets[j], timingFunction);
+ keyframes.append(toAnimatableValueKeyframe(keyframe->cloneWithOffset(offsets[j]).get()));
}
}
ASSERT(!keyframes.isEmpty());
- if (!perKeyframeTimingFunctions.contains(0))
- perKeyframeTimingFunctions.set(0, defaultTimingFunction);
-
- for (PropertySet::const_iterator iter = specifiedProperties.begin(); iter != specifiedProperties.end(); ++iter) {
+ for (PropertySet::const_iterator iter = specifiedPropertiesForUseCounter.begin(); iter != specifiedPropertiesForUseCounter.end(); ++iter) {
const CSSPropertyID property = *iter;
ASSERT(property != CSSPropertyInvalid);
blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProperties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(property));
@@ -159,16 +151,18 @@ static void resolveKeyframes(StyleResolver* resolver, Element* element, const El
keyframes.shrink(targetIndex + 1);
// Add 0% and 100% keyframes if absent.
- RefPtr<Keyframe> startKeyframe = keyframes[0];
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> startKeyframe = keyframes[0];
if (startKeyframe->offset()) {
- startKeyframe = Keyframe::create();
+ startKeyframe = AnimatableValueKeyframe::create();
startKeyframe->setOffset(0);
+ startKeyframe->setEasing(defaultTimingFunction);
keyframes.prepend(startKeyframe);
}
- RefPtr<Keyframe> endKeyframe = keyframes[keyframes.size() - 1];
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = keyframes[keyframes.size() - 1];
if (endKeyframe->offset() != 1) {
- endKeyframe = Keyframe::create();
+ endKeyframe = AnimatableValueKeyframe::create();
endKeyframe->setOffset(1);
+ endKeyframe->setEasing(defaultTimingFunction);
keyframes.append(endKeyframe);
}
ASSERT(keyframes.size() >= 2);
@@ -194,7 +188,7 @@ static void resolveKeyframes(StyleResolver* resolver, Element* element, const El
bool endNeedsValue = missingEndValues && !endKeyframeProperties.contains(property);
if (!startNeedsValue && !endNeedsValue)
continue;
- RefPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::create(property, style);
+ RefPtrWillBeRawPtr<AnimatableValue> snapshotValue = CSSAnimatableValueFactory::create(property, style);
if (startNeedsValue)
startKeyframe->setPropertyValue(property, snapshotValue.get());
if (endNeedsValue)
@@ -203,129 +197,6 @@ static void resolveKeyframes(StyleResolver* resolver, Element* element, const El
}
ASSERT(startKeyframe->properties().size() == allProperties.size());
ASSERT(endKeyframe->properties().size() == allProperties.size());
-
- // Determine how many keyframes specify each property. Note that this must
- // be done after we've filled in end keyframes.
- typedef HashCountedSet<CSSPropertyID> PropertyCountedSet;
- PropertyCountedSet propertyCounts;
- for (size_t i = 0; i < numKeyframes; ++i) {
- const PropertySet& properties = keyframes[i]->properties();
- for (PropertySet::const_iterator iter = properties.begin(); iter != properties.end(); ++iter)
- propertyCounts.add(*iter);
- }
-
- // Split keyframes into groups, where each group contains only keyframes
- // which specify all properties used in that group. Each group is animated
- // in a separate animation, to allow per-keyframe timing functions to be
- // applied correctly.
- for (PropertyCountedSet::const_iterator iter = propertyCounts.begin(); iter != propertyCounts.end(); ++iter) {
- const CSSPropertyID property = iter->key;
- const size_t count = iter->value;
- ASSERT(count <= numKeyframes);
- if (count == numKeyframes)
- continue;
- KeyframeAnimationEffect::KeyframeVector splitOutKeyframes;
- for (size_t i = 0; i < numKeyframes; i++) {
- Keyframe* keyframe = keyframes[i].get();
- if (!keyframe->properties().contains(property)) {
- ASSERT(i && i != numKeyframes - 1);
- continue;
- }
- RefPtr<Keyframe> clonedKeyframe = Keyframe::create();
- clonedKeyframe->setOffset(keyframe->offset());
- clonedKeyframe->setComposite(keyframe->composite());
- clonedKeyframe->setPropertyValue(property, keyframe->propertyValue(property));
- splitOutKeyframes.append(clonedKeyframe);
- // Note that it's OK if this keyframe ends up having no
- // properties. This can only happen when none of the properties
- // are specified in all keyframes, in which case we won't animate
- // anything with these keyframes.
- keyframe->clearPropertyValue(property);
- }
- ASSERT(!splitOutKeyframes.first()->offset());
- ASSERT(splitOutKeyframes.last()->offset() == 1);
-#ifndef NDEBUG
- for (size_t j = 0; j < splitOutKeyframes.size(); ++j)
- ASSERT(splitOutKeyframes[j]->properties().size() == 1);
-#endif
- keyframesAndTimingFunctions.append(std::make_pair(splitOutKeyframes, generateTimingFunction(splitOutKeyframes, perKeyframeTimingFunctions)));
- }
-
- unsigned numPropertiesSpecifiedInAllKeyframes = keyframes.first()->properties().size();
-#ifndef NDEBUG
- for (size_t i = 1; i < numKeyframes; ++i)
- ASSERT(keyframes[i]->properties().size() == numPropertiesSpecifiedInAllKeyframes);
-#endif
-
- // If the animation specifies any keyframes, we always provide at least one
- // vector of resolved keyframes, even if no properties are animated.
- if (numPropertiesSpecifiedInAllKeyframes || keyframesAndTimingFunctions.isEmpty())
- keyframesAndTimingFunctions.append(std::make_pair(keyframes, generateTimingFunction(keyframes, perKeyframeTimingFunctions)));
-}
-
-// Returns the default timing function.
-const PassRefPtr<TimingFunction> timingFromAnimationData(const CSSAnimationData* animationData, Timing& timing, bool& isPaused)
-{
- if (animationData->isDelaySet())
- timing.startDelay = animationData->delay();
- if (animationData->isDurationSet()) {
- timing.iterationDuration = animationData->duration();
- timing.hasIterationDuration = true;
- }
- if (animationData->isIterationCountSet()) {
- if (animationData->iterationCount() == CSSAnimationData::IterationCountInfinite)
- timing.iterationCount = std::numeric_limits<double>::infinity();
- else
- timing.iterationCount = animationData->iterationCount();
- }
- if (animationData->isFillModeSet()) {
- switch (animationData->fillMode()) {
- case AnimationFillModeForwards:
- timing.fillMode = Timing::FillModeForwards;
- break;
- case AnimationFillModeBackwards:
- timing.fillMode = Timing::FillModeBackwards;
- break;
- case AnimationFillModeBoth:
- timing.fillMode = Timing::FillModeBoth;
- break;
- case AnimationFillModeNone:
- timing.fillMode = Timing::FillModeNone;
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- } else {
- timing.fillMode = Timing::FillModeNone;
- }
- if (animationData->isDirectionSet()) {
- switch (animationData->direction()) {
- case CSSAnimationData::AnimationDirectionNormal:
- timing.direction = Timing::PlaybackDirectionNormal;
- break;
- case CSSAnimationData::AnimationDirectionAlternate:
- timing.direction = Timing::PlaybackDirectionAlternate;
- break;
- case CSSAnimationData::AnimationDirectionReverse:
- timing.direction = Timing::PlaybackDirectionReverse;
- break;
- case CSSAnimationData::AnimationDirectionAlternateReverse:
- timing.direction = Timing::PlaybackDirectionAlternateReverse;
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- // For CSS, the constraints on the timing properties are tighter than in
- // the general case of the Web Animations model.
- timing.assertValid();
- ASSERT(!timing.iterationStart);
- ASSERT(timing.playbackRate == 1);
- ASSERT(timing.iterationDuration >= 0 && std::isfinite(timing.iterationDuration));
-
- isPaused = animationData->isPlayStateSet() && animationData->playState() == AnimPlayStatePaused;
- return animationData->isTimingFunctionSet() ? animationData->timingFunction() : CSSAnimationData::initialAnimationTimingFunction();
}
} // namespace
@@ -347,21 +218,32 @@ const StyleRuleKeyframes* CSSAnimations::matchScopedKeyframesRule(StyleResolver*
return 0;
}
-PassOwnPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle, StyleResolver* resolver)
+CSSAnimations::CSSAnimations()
{
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
- OwnPtr<CSSAnimationUpdate> update = adoptPtr(new CSSAnimationUpdate());
+}
+
+PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> CSSAnimations::calculateUpdate(Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle, StyleResolver* resolver)
+{
+ OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = adoptPtrWillBeNoop(new CSSAnimationUpdate());
calculateAnimationUpdate(update.get(), element, parentElement, style, parentStyle, resolver);
- calculateAnimationCompositableValues(update.get(), element);
+ calculateAnimationActiveInterpolations(update.get(), element, parentElement.document().timeline().currentTimeInternal());
calculateTransitionUpdate(update.get(), element, style);
- calculateTransitionCompositableValues(update.get(), element);
+ calculateTransitionActiveInterpolations(update.get(), element, parentElement.document().timeline().currentTimeInternal());
return update->isEmpty() ? nullptr : update.release();
}
void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle, StyleResolver* resolver)
{
const ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0;
- const CSSAnimationDataList* animationDataList = style.animations();
+
+#if !ASSERT_ENABLED
+ // If we're in an animation style change, no animations can have started, been cancelled or changed play state.
+ // When ASSERT is enabled, we verify this optimization.
+ if (activeAnimations && activeAnimations->isAnimationStyleChange())
+ return;
+#endif
+
+ const CSSAnimationData* animationData = style.animations();
const CSSAnimations* cssAnimations = activeAnimations ? &activeAnimations->cssAnimations() : 0;
HashSet<AtomicString> inactive;
@@ -370,12 +252,12 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, Element
inactive.add(iter->key);
if (style.display() != NONE) {
- for (size_t i = 0; animationDataList && i < animationDataList->size(); ++i) {
- const CSSAnimationData* animationData = animationDataList->animation(i);
- if (animationData->isNoneAnimation())
+ for (size_t i = 0; animationData && i < animationData->nameList().size(); ++i) {
+ AtomicString animationName(animationData->nameList()[i]);
+ if (animationName == CSSAnimationData::initialName())
continue;
- ASSERT(animationData->isValidAnimation());
- AtomicString animationName(animationData->name());
+
+ bool isPaused = CSSTimingData::getRepeated(animationData->playStateList(), i) == AnimPlayStatePaused;
// Keyframes and animation properties are snapshotted when the
// animation starts, so we don't need to track changes to these,
@@ -384,85 +266,76 @@ void CSSAnimations::calculateAnimationUpdate(CSSAnimationUpdate* update, Element
AnimationMap::const_iterator existing(cssAnimations->m_animations.find(animationName));
if (existing != cssAnimations->m_animations.end()) {
inactive.remove(animationName);
- const HashSet<RefPtr<Player> >& players = existing->value;
- ASSERT(!players.isEmpty());
- bool isFirstPlayerPaused = (*players.begin())->paused();
-#ifndef NDEBUG
- for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
- ASSERT((*iter)->paused() == isFirstPlayerPaused);
-#endif
- if ((animationData->playState() == AnimPlayStatePaused) != isFirstPlayerPaused)
+ AnimationPlayer* player = existing->value.get();
+ if (isPaused != player->paused()) {
+ ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
update->toggleAnimationPaused(animationName);
+ }
continue;
}
}
- Timing timing;
- bool isPaused;
- RefPtr<TimingFunction> defaultTimingFunction = timingFromAnimationData(animationData, timing, isPaused);
- Vector<std::pair<KeyframeAnimationEffect::KeyframeVector, RefPtr<TimingFunction> > > keyframesAndTimingFunctions;
- resolveKeyframes(resolver, element, parentElement, style, parentStyle, animationName, defaultTimingFunction.get(), keyframesAndTimingFunctions);
- if (!keyframesAndTimingFunctions.isEmpty()) {
- HashSet<RefPtr<InertAnimation> > animations;
- for (size_t j = 0; j < keyframesAndTimingFunctions.size(); ++j) {
- ASSERT(!keyframesAndTimingFunctions[j].first.isEmpty());
- timing.timingFunction = keyframesAndTimingFunctions[j].second;
- // FIXME: crbug.com/268791 - Keyframes are already normalized, perhaps there should be a flag on KeyframeAnimationEffect to skip normalization.
- animations.add(InertAnimation::create(KeyframeAnimationEffect::create(keyframesAndTimingFunctions[j].first), timing, isPaused));
- }
- update->startAnimation(animationName, animations);
+ Timing timing = animationData->convertToTiming(i);
+ RefPtr<TimingFunction> keyframeTimingFunction = timing.timingFunction;
+ timing.timingFunction = Timing::defaults().timingFunction;
+ AnimatableValueKeyframeVector resolvedKeyframes;
+ resolveKeyframes(resolver, element, parentElement, style, parentStyle, animationName, keyframeTimingFunction.get(), resolvedKeyframes);
+ if (!resolvedKeyframes.isEmpty()) {
+ ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
+ update->startAnimation(animationName, InertAnimation::create(AnimatableValueKeyframeEffectModel::create(resolvedKeyframes), timing, isPaused));
}
}
}
ASSERT(inactive.isEmpty() || cssAnimations);
- for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter != inactive.end(); ++iter)
- update->cancelAnimation(*iter, cssAnimations->m_animations.get(*iter));
+ for (HashSet<AtomicString>::const_iterator iter = inactive.begin(); iter != inactive.end(); ++iter) {
+ ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
+ update->cancelAnimation(*iter, *cssAnimations->m_animations.get(*iter));
+ }
}
void CSSAnimations::maybeApplyPendingUpdate(Element* element)
{
if (!m_pendingUpdate) {
- m_previousCompositableValuesForAnimations.clear();
+ m_previousActiveInterpolationsForAnimations.clear();
return;
}
- OwnPtr<CSSAnimationUpdate> update = m_pendingUpdate.release();
+ OwnPtrWillBeRawPtr<CSSAnimationUpdate> update = m_pendingUpdate.release();
+
+ m_previousActiveInterpolationsForAnimations.swap(update->activeInterpolationsForAnimations());
- m_previousCompositableValuesForAnimations.swap(update->compositableValuesForAnimations());
+ // FIXME: cancelling, pausing, unpausing animations all query compositingState, which is not necessarily up to date here
+ // since we call this from recalc style.
+ // https://code.google.com/p/chromium/issues/detail?id=339847
+ DisableCompositingQueryAsserts disabler;
for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationNames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) {
- const HashSet<RefPtr<Player> >& players = m_animations.take(*iter);
- for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
- (*iter)->cancel();
+ RefPtr<AnimationPlayer> player = m_animations.take(*iter);
+ player->cancel();
+ player->update(TimingUpdateOnDemand);
}
for (Vector<AtomicString>::const_iterator iter = update->animationsWithPauseToggled().begin(); iter != update->animationsWithPauseToggled().end(); ++iter) {
- const HashSet<RefPtr<Player> >& players = m_animations.get(*iter);
- ASSERT(!players.isEmpty());
- bool isFirstPlayerPaused = (*players.begin())->paused();
- for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter) {
- Player* player = iter->get();
- ASSERT(player->paused() == isFirstPlayerPaused);
- player->setPaused(!isFirstPlayerPaused);
- }
+ AnimationPlayer* player = m_animations.get(*iter);
+ if (player->paused())
+ player->unpause();
+ else
+ player->pause();
+ if (player->outdated())
+ player->update(TimingUpdateOnDemand);
}
- for (Vector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update->newAnimations().begin(); iter != update->newAnimations().end(); ++iter) {
+ for (WillBeHeapVector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update->newAnimations().begin(); iter != update->newAnimations().end(); ++iter) {
+ const InertAnimation* inertAnimation = iter->animation.get();
OwnPtr<AnimationEventDelegate> eventDelegate = adoptPtr(new AnimationEventDelegate(element, iter->name));
- HashSet<RefPtr<Player> > players;
- for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = iter->animations.begin(); animationsIter != iter->animations.end(); ++animationsIter) {
- const InertAnimation* inertAnimation = animationsIter->get();
- // The event delegate is set on the the first animation only. We
- // rely on the behavior of OwnPtr::release() to achieve this.
- RefPtr<Animation> animation = Animation::create(element, inertAnimation->effect(), inertAnimation->specified(), Animation::DefaultPriority, eventDelegate.release());
- Player* player = element->document().timeline()->createPlayer(animation.get());
- player->setPaused(inertAnimation->paused());
- element->document().cssPendingAnimations().add(player);
- player->update();
- players.add(player);
- }
- m_animations.set(iter->name, players);
+ RefPtrWillBeRawPtr<Animation> animation = Animation::create(element, inertAnimation->effect(), inertAnimation->specifiedTiming(), Animation::DefaultPriority, eventDelegate.release());
+ RefPtrWillBeRawPtr<AnimationPlayer> player = element->document().timeline().createAnimationPlayer(animation.get());
+ element->document().compositorPendingAnimations().add(player.get());
+ if (inertAnimation->paused())
+ player->pause();
+ player->update(TimingUpdateOnDemand);
+ m_animations.set(iter->name, player.get());
}
// Transitions that are run on the compositor only update main-thread state
@@ -470,15 +343,17 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
// be when transitions are retargeted. Instead of triggering complete style
// recalculation, we find these cases by searching for new transitions that
// have matching cancelled animation property IDs on the compositor.
- HashMap<CSSPropertyID, std::pair<RefPtr<Animation>, double> > retargetedCompositorTransitions;
- const ActiveAnimations* activeAnimations = element->activeAnimations();
+ WillBeHeapHashMap<CSSPropertyID, std::pair<RefPtrWillBeMember<Animation>, double> > retargetedCompositorTransitions;
for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransitions().begin(); iter != update->cancelledTransitions().end(); ++iter) {
CSSPropertyID id = *iter;
ASSERT(m_transitions.contains(id));
- Player* player = m_transitions.take(id).transition->player();
- if (activeAnimations && activeAnimations->hasActiveAnimationsOnCompositor(id) && update->newTransitions().find(id) != update->newTransitions().end())
- retargetedCompositorTransitions.add(id, std::pair<RefPtr<Animation>, double>(toAnimation(player->source()), player->startTime()));
+
+ RefPtrWillBeRawPtr<AnimationPlayer> player = m_transitions.take(id).player;
+ Animation* animation = toAnimation(player->source());
+ if (animation->hasActiveAnimationsOnCompositor(id) && update->newTransitions().find(id) != update->newTransitions().end())
+ retargetedCompositorTransitions.add(id, std::pair<RefPtrWillBeMember<Animation>, double>(animation, player->startTimeInternal()));
player->cancel();
+ player->update(TimingUpdateOnDemand);
}
for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->newTransitions().begin(); iter != update->newTransitions().end(); ++iter) {
@@ -490,42 +365,46 @@ void CSSAnimations::maybeApplyPendingUpdate(Element* element)
CSSPropertyID id = newTransition.id;
InertAnimation* inertAnimation = newTransition.animation.get();
- OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionEventDelegate(element, id));
+ OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionEventDelegate(element, newTransition.eventId));
- RefPtr<AnimationEffect> effect = inertAnimation->effect();
+ RefPtrWillBeRawPtr<AnimationEffect> effect = inertAnimation->effect();
if (retargetedCompositorTransitions.contains(id)) {
- const std::pair<RefPtr<Animation>, double>& oldTransition = retargetedCompositorTransitions.get(id);
- RefPtr<Animation> oldAnimation = oldTransition.first;
+ const std::pair<RefPtrWillBeMember<Animation>, double>& oldTransition = retargetedCompositorTransitions.get(id);
+ RefPtrWillBeRawPtr<Animation> oldAnimation = oldTransition.first;
double oldStartTime = oldTransition.second;
- double inheritedTime = isNull(oldStartTime) ? 0 : element->document().transitionTimeline()->currentTime() - oldStartTime;
- oldAnimation->updateInheritedTime(inheritedTime);
- KeyframeAnimationEffect* oldEffect = toKeyframeAnimationEffect(inertAnimation->effect());
- const KeyframeAnimationEffect::KeyframeVector& frames = oldEffect->getFrames();
- KeyframeAnimationEffect::KeyframeVector newFrames;
- newFrames.append(frames[0]->clone());
+ double inheritedTime = isNull(oldStartTime) ? 0 : element->document().timeline().currentTimeInternal() - oldStartTime;
+
+ AnimatableValueKeyframeEffectModel* oldEffect = toAnimatableValueKeyframeEffectModel(inertAnimation->effect());
+ const KeyframeVector& frames = oldEffect->getFrames();
+
+ AnimatableValueKeyframeVector newFrames;
+ newFrames.append(toAnimatableValueKeyframe(frames[0]->clone().get()));
+ newFrames.append(toAnimatableValueKeyframe(frames[1]->clone().get()));
+
newFrames[0]->clearPropertyValue(id);
- ASSERT(oldAnimation->compositableValues()->size() == 1);
- const AnimationEffect::CompositableValue* compositableValue = oldAnimation->compositableValues()->at(0).second.get();
- ASSERT(!compositableValue->dependsOnUnderlyingValue());
- newFrames[0]->setPropertyValue(id, compositableValue->compositeOnto(0).get());
- newFrames.append(frames[1]->clone());
- effect = KeyframeAnimationEffect::create(newFrames);
+ RefPtrWillBeRawPtr<InertAnimation> inertAnimationForSampling = InertAnimation::create(oldAnimation->effect(), oldAnimation->specifiedTiming(), false);
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<Interpolation> > > sample = inertAnimationForSampling->sample(inheritedTime);
+ ASSERT(sample->size() == 1);
+ newFrames[0]->setPropertyValue(id, toLegacyStyleInterpolation(sample->at(0).get())->currentValue());
+
+ effect = AnimatableValueKeyframeEffectModel::create(newFrames);
}
- RefPtr<Animation> transition = Animation::create(element, effect, inertAnimation->specified(), Animation::TransitionPriority, eventDelegate.release());
- RefPtr<Player> player = element->document().transitionTimeline()->createPlayer(transition.get());
- player->update();
- element->document().cssPendingAnimations().add(player.get());
- runningTransition.transition = transition.get();
+
+ RefPtrWillBeRawPtr<Animation> transition = Animation::create(element, effect, inertAnimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.release());
+ RefPtrWillBeRawPtr<AnimationPlayer> player = element->document().timeline().createAnimationPlayer(transition.get());
+ element->document().compositorPendingAnimations().add(player.get());
+ player->update(TimingUpdateOnDemand);
+ runningTransition.player = player;
m_transitions.set(id, runningTransition);
ASSERT(id != CSSPropertyInvalid);
blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProperties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(id));
}
}
-void CSSAnimations::calculateTransitionUpdateForProperty(CSSPropertyID id, const CSSAnimationData* anim, const RenderStyle& oldStyle, const RenderStyle& style, const TransitionMap* activeTransitions, CSSAnimationUpdate* update, const Element* element)
+void CSSAnimations::calculateTransitionUpdateForProperty(CSSPropertyID id, CSSPropertyID eventId, const CSSTransitionData& transitionData, size_t transitionIndex, const RenderStyle& oldStyle, const RenderStyle& style, const TransitionMap* activeTransitions, CSSAnimationUpdate* update, const Element* element)
{
- RefPtr<AnimatableValue> to;
+ RefPtrWillBeRawPtr<AnimatableValue> to = nullptr;
if (activeTransitions) {
TransitionMap::const_iterator activeTransitionIter = activeTransitions->find(id);
if (activeTransitionIter != activeTransitions->end()) {
@@ -538,44 +417,37 @@ void CSSAnimations::calculateTransitionUpdateForProperty(CSSPropertyID id, const
}
}
- if (anim->duration() + anim->delay() <= 0)
+ if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style))
return;
-
- if (CSSPropertyAnimation::propertiesEqual(id, &oldStyle, &style))
- return;
-
if (!to)
to = CSSAnimatableValueFactory::create(id, style);
- RefPtr<AnimatableValue> from = CSSAnimatableValueFactory::create(id, oldStyle);
+ RefPtrWillBeRawPtr<AnimatableValue> from = CSSAnimatableValueFactory::create(id, oldStyle);
// If we have multiple transitions on the same property, we will use the
// last one since we iterate over them in order.
- if (!from->usesNonDefaultInterpolationWith(to.get()))
+ if (AnimatableValue::usesDefaultInterpolation(to.get(), from.get()))
+ return;
+
+ Timing timing = transitionData.convertToTiming(transitionIndex);
+ if (timing.startDelay + timing.iterationDuration <= 0)
return;
- KeyframeAnimationEffect::KeyframeVector keyframes;
+ AnimatableValueKeyframeVector keyframes;
- RefPtr<Keyframe> startKeyframe = Keyframe::create();
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> startKeyframe = AnimatableValueKeyframe::create();
startKeyframe->setPropertyValue(id, from.get());
startKeyframe->setOffset(0);
+ startKeyframe->setEasing(timing.timingFunction.release());
+ timing.timingFunction = LinearTimingFunction::shared();
keyframes.append(startKeyframe);
- RefPtr<Keyframe> endKeyframe = Keyframe::create();
+ RefPtrWillBeRawPtr<AnimatableValueKeyframe> endKeyframe = AnimatableValueKeyframe::create();
endKeyframe->setPropertyValue(id, to.get());
endKeyframe->setOffset(1);
keyframes.append(endKeyframe);
- RefPtr<KeyframeAnimationEffect> effect = KeyframeAnimationEffect::create(keyframes);
-
- Timing timing;
- bool isPaused;
- RefPtr<TimingFunction> timingFunction = timingFromAnimationData(anim, timing, isPaused);
- ASSERT(!isPaused);
- timing.timingFunction = timingFunction;
- // Note that the backwards part is required for delay to work.
- timing.fillMode = Timing::FillModeBoth;
-
- update->startTransition(id, from.get(), to.get(), InertAnimation::create(effect, timing, isPaused));
+ RefPtrWillBeRawPtr<AnimatableValueKeyframeEffectModel> effect = AnimatableValueKeyframeEffectModel::create(keyframes);
+ update->startTransition(id, eventId, from.get(), to.get(), InertAnimation::create(effect, timing, false));
ASSERT(!element->activeAnimations() || !element->activeAnimations()->isAnimationStyleChange());
}
@@ -586,37 +458,41 @@ void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
ActiveAnimations* activeAnimations = element->activeAnimations();
const TransitionMap* activeTransitions = activeAnimations ? &activeAnimations->cssAnimations().m_transitions : 0;
+ const CSSTransitionData* transitionData = style.transitions();
-#if ASSERT_DISABLED
- // In release builds we avoid the cost of checking for new and interrupted transitions if the style recalc is due to animation.
- const bool animationStyleRecalc = activeAnimations && activeAnimations->isAnimationStyleChange();
-#else
+#if ASSERT_ENABLED
// In debug builds we verify that it would have been safe to avoid populating and testing listedProperties if the style recalc is due to animation.
const bool animationStyleRecalc = false;
+#else
+ // In release builds we avoid the cost of checking for new and interrupted transitions if the style recalc is due to animation.
+ const bool animationStyleRecalc = activeAnimations && activeAnimations->isAnimationStyleChange();
#endif
BitArray<numCSSProperties> listedProperties;
- bool anyTransitionHadAnimateAll = false;
+ bool anyTransitionHadTransitionAll = false;
const RenderObject* renderer = element->renderer();
- if (!animationStyleRecalc && style.display() != NONE && renderer && renderer->style() && style.transitions()) {
+ if (!animationStyleRecalc && style.display() != NONE && renderer && renderer->style() && transitionData) {
const RenderStyle& oldStyle = *renderer->style();
- for (size_t i = 0; i < style.transitions()->size(); ++i) {
- const CSSAnimationData* anim = style.transitions()->animation(i);
- CSSAnimationData::AnimationMode mode = anim->animationMode();
- if (mode == CSSAnimationData::AnimateNone)
+ for (size_t i = 0; i < transitionData->propertyList().size(); ++i) {
+ const CSSTransitionData::TransitionProperty& transitionProperty = transitionData->propertyList()[i];
+ CSSTransitionData::TransitionPropertyType mode = transitionProperty.propertyType;
+ CSSPropertyID property = transitionProperty.propertyId;
+ if (mode == CSSTransitionData::TransitionNone || mode == CSSTransitionData::TransitionUnknown)
continue;
- bool animateAll = mode == CSSAnimationData::AnimateAll;
- ASSERT(animateAll || mode == CSSAnimationData::AnimateSingleProperty);
+ bool animateAll = mode == CSSTransitionData::TransitionAll;
+ ASSERT(animateAll || mode == CSSTransitionData::TransitionSingleProperty);
if (animateAll)
- anyTransitionHadAnimateAll = true;
- const StylePropertyShorthand& propertyList = animateAll ? CSSAnimations::animatableProperties() : shorthandForProperty(anim->property());
+ anyTransitionHadTransitionAll = true;
+ const StylePropertyShorthand& propertyList = animateAll ? CSSAnimations::animatableProperties() : shorthandForProperty(property);
// If not a shorthand we only execute one iteration of this loop, and refer to the property directly.
for (unsigned j = 0; !j || j < propertyList.length(); ++j) {
- CSSPropertyID id = propertyList.length() ? propertyList.properties()[j] : anim->property();
+ CSSPropertyID id = propertyList.length() ? propertyList.properties()[j] : property;
+ CSSPropertyID eventId = id;
if (!animateAll) {
+ id = propertyForAnimation(id);
if (CSSAnimations::isAnimatableProperty(id))
listedProperties.set(id);
else
@@ -625,9 +501,9 @@ void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
// FIXME: We should transition if an !important property changes even when an animation is running,
// but this is a bit hard to do with the current applyMatchedProperties system.
- if (!update->compositableValuesForAnimations().contains(id)
- && (!activeAnimations || !activeAnimations->cssAnimations().m_previousCompositableValuesForAnimations.contains(id))) {
- calculateTransitionUpdateForProperty(id, anim, oldStyle, style, activeTransitions, update, element);
+ if (!update->activeInterpolationsForAnimations().contains(id)
+ && (!activeAnimations || !activeAnimations->cssAnimations().m_previousActiveInterpolationsForAnimations.contains(id))) {
+ calculateTransitionUpdateForProperty(id, eventId, *transitionData, i, oldStyle, style, activeTransitions, update, element);
}
}
}
@@ -635,10 +511,11 @@ void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
if (activeTransitions) {
for (TransitionMap::const_iterator iter = activeTransitions->begin(); iter != activeTransitions->end(); ++iter) {
- const TimedItem* timedItem = iter->value.transition;
+ const AnimationPlayer& player = *iter->value.player;
CSSPropertyID id = iter->key;
- if (timedItem->phase() == TimedItem::PhaseAfter || (!anyTransitionHadAnimateAll && !animationStyleRecalc && !listedProperties.get(id))) {
- ASSERT(timedItem->phase() == TimedItem::PhaseAfter || !(activeAnimations && activeAnimations->isAnimationStyleChange()));
+ if (player.finishedInternal() || (!anyTransitionHadTransitionAll && !animationStyleRecalc && !listedProperties.get(id))) {
+ // TODO: Figure out why this fails on Chrome OS login page. crbug.com/365507
+ // ASSERT(player.finishedInternal() || !(activeAnimations && activeAnimations->isAnimationStyleChange()));
update->cancelTransition(id);
}
}
@@ -648,130 +525,129 @@ void CSSAnimations::calculateTransitionUpdate(CSSAnimationUpdate* update, const
void CSSAnimations::cancel()
{
for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animations.end(); ++iter) {
- const HashSet<RefPtr<Player> >& players = iter->value;
- for (HashSet<RefPtr<Player> >::const_iterator animationsIter = players.begin(); animationsIter != players.end(); ++animationsIter)
- (*animationsIter)->cancel();
+ iter->value->cancel();
+ iter->value->update(TimingUpdateOnDemand);
}
- for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transitions.end(); ++iter)
- iter->value.transition->player()->cancel();
+ for (TransitionMap::iterator iter = m_transitions.begin(); iter != m_transitions.end(); ++iter) {
+ iter->value.player->cancel();
+ iter->value.player->update(TimingUpdateOnDemand);
+ }
m_animations.clear();
m_transitions.clear();
m_pendingUpdate = nullptr;
}
-void CSSAnimations::calculateAnimationCompositableValues(CSSAnimationUpdate* update, const Element* element)
+void CSSAnimations::calculateAnimationActiveInterpolations(CSSAnimationUpdate* update, const Element* element, double timelineCurrentTime)
{
ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0;
AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0;
- if (update->newAnimations().isEmpty() && update->cancelledAnimationPlayers().isEmpty()) {
- AnimationEffect::CompositableValueMap compositableValuesForAnimations(AnimationStack::compositableValues(animationStack, 0, 0, Animation::DefaultPriority));
- update->adoptCompositableValuesForAnimations(compositableValuesForAnimations);
+ if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimationPlayers().isEmpty()) {
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::DefaultPriority, timelineCurrentTime));
+ update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
return;
}
- Vector<InertAnimation*> newAnimations;
+ WillBeHeapVector<RawPtrWillBeMember<InertAnimation> > newAnimations;
for (size_t i = 0; i < update->newAnimations().size(); ++i) {
- HashSet<RefPtr<InertAnimation> > animations = update->newAnimations()[i].animations;
- for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = animations.begin(); animationsIter != animations.end(); ++animationsIter)
- newAnimations.append(animationsIter->get());
+ newAnimations.append(update->newAnimations()[i].animation.get());
}
- AnimationEffect::CompositableValueMap compositableValuesForAnimations(AnimationStack::compositableValues(animationStack, &newAnimations, &update->cancelledAnimationPlayers(), Animation::DefaultPriority));
- update->adoptCompositableValuesForAnimations(compositableValuesForAnimations);
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForAnimations(AnimationStack::activeInterpolations(animationStack, &newAnimations, &update->cancelledAnimationAnimationPlayers(), Animation::DefaultPriority, timelineCurrentTime));
+ update->adoptActiveInterpolationsForAnimations(activeInterpolationsForAnimations);
}
-void CSSAnimations::calculateTransitionCompositableValues(CSSAnimationUpdate* update, const Element* element)
+void CSSAnimations::calculateTransitionActiveInterpolations(CSSAnimationUpdate* update, const Element* element, double timelineCurrentTime)
{
ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0;
AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0;
- AnimationEffect::CompositableValueMap compositableValuesForTransitions;
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > activeInterpolationsForTransitions;
if (update->newTransitions().isEmpty() && update->cancelledTransitions().isEmpty()) {
- compositableValuesForTransitions = AnimationStack::compositableValues(animationStack, 0, 0, Animation::TransitionPriority);
+ activeInterpolationsForTransitions = AnimationStack::activeInterpolations(animationStack, 0, 0, Animation::TransitionPriority, timelineCurrentTime);
} else {
- Vector<InertAnimation*> newTransitions;
+ WillBeHeapVector<RawPtrWillBeMember<InertAnimation> > newTransitions;
for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->newTransitions().begin(); iter != update->newTransitions().end(); ++iter)
newTransitions.append(iter->value.animation.get());
- HashSet<const Player*> cancelledPlayers;
+ WillBeHeapHashSet<RawPtrWillBeMember<const AnimationPlayer> > cancelledAnimationPlayers;
if (!update->cancelledTransitions().isEmpty()) {
ASSERT(activeAnimations);
const TransitionMap& transitionMap = activeAnimations->cssAnimations().m_transitions;
for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransitions().begin(); iter != update->cancelledTransitions().end(); ++iter) {
ASSERT(transitionMap.contains(*iter));
- cancelledPlayers.add(transitionMap.get(*iter).transition->player());
+ cancelledAnimationPlayers.add(transitionMap.get(*iter).player.get());
}
}
- compositableValuesForTransitions = AnimationStack::compositableValues(animationStack, &newTransitions, &cancelledPlayers, Animation::TransitionPriority);
+ activeInterpolationsForTransitions = AnimationStack::activeInterpolations(animationStack, &newTransitions, &cancelledAnimationPlayers, Animation::TransitionPriority, timelineCurrentTime);
}
// Properties being animated by animations don't get values from transitions applied.
- if (!update->compositableValuesForAnimations().isEmpty() && !compositableValuesForTransitions.isEmpty()) {
- for (AnimationEffect::CompositableValueMap::const_iterator iter = update->compositableValuesForAnimations().begin(); iter != update->compositableValuesForAnimations().end(); ++iter)
- compositableValuesForTransitions.remove(iter->key);
+ if (!update->activeInterpolationsForAnimations().isEmpty() && !activeInterpolationsForTransitions.isEmpty()) {
+ for (WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >::const_iterator iter = update->activeInterpolationsForAnimations().begin(); iter != update->activeInterpolationsForAnimations().end(); ++iter)
+ activeInterpolationsForTransitions.remove(iter->key);
}
- update->adoptCompositableValuesForTransitions(compositableValuesForTransitions);
+ update->adoptActiveInterpolationsForTransitions(activeInterpolationsForTransitions);
}
void CSSAnimations::AnimationEventDelegate::maybeDispatch(Document::ListenerType listenerType, const AtomicString& eventName, double elapsedTime)
{
- if (m_target->document().hasListenerType(listenerType))
- m_target->document().timeline()->addEventToDispatch(m_target, WebKitAnimationEvent::create(eventName, m_name, elapsedTime));
+ if (m_target->document().hasListenerType(listenerType)) {
+ RefPtrWillBeRawPtr<WebKitAnimationEvent> event = WebKitAnimationEvent::create(eventName, m_name, elapsedTime);
+ event->setTarget(m_target);
+ m_target->document().enqueueAnimationFrameEvent(event);
+ }
}
-void CSSAnimations::AnimationEventDelegate::onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration)
+void CSSAnimations::AnimationEventDelegate::onEventCondition(const AnimationNode* animationNode)
{
- // Events for a single document are queued and dispatched as a group at
- // the end of DocumentTimeline::serviceAnimations.
- // FIXME: Events which are queued outside of serviceAnimations should
- // trigger a timer to dispatch when control is released.
- const TimedItem::Phase currentPhase = timedItem->phase();
- const double currentIteration = timedItem->currentIteration();
-
- // Note that the elapsedTime is measured from when the animation starts playing.
- if (!isFirstSample && previousPhase == TimedItem::PhaseActive && currentPhase == TimedItem::PhaseActive && previousIteration != currentIteration) {
- ASSERT(!isNull(previousIteration));
- ASSERT(!isNull(currentIteration));
+ const AnimationNode::Phase currentPhase = animationNode->phase();
+ const double currentIteration = animationNode->currentIteration();
+
+ if (m_previousPhase != currentPhase
+ && (currentPhase == AnimationNode::PhaseActive || currentPhase == AnimationNode::PhaseAfter)
+ && (m_previousPhase == AnimationNode::PhaseNone || m_previousPhase == AnimationNode::PhaseBefore)) {
+ // The spec states that the elapsed time should be
+ // 'delay < 0 ? -delay : 0', but we always use 0 to match the existing
+ // implementation. See crbug.com/279611
+ maybeDispatch(Document::ANIMATIONSTART_LISTENER, EventTypeNames::animationstart, 0);
+ }
+
+ if (currentPhase == AnimationNode::PhaseActive && m_previousPhase == currentPhase && m_previousIteration != currentIteration) {
// We fire only a single event for all iterations thast terminate
// between a single pair of samples. See http://crbug.com/275263. For
// compatibility with the existing implementation, this event uses
// the elapsedTime for the first iteration in question.
- ASSERT(timedItem->specified().hasIterationDuration);
- const double elapsedTime = timedItem->specified().iterationDuration * (previousIteration + 1);
+ ASSERT(!std::isnan(animationNode->specifiedTiming().iterationDuration));
+ const double elapsedTime = animationNode->specifiedTiming().iterationDuration * (m_previousIteration + 1);
maybeDispatch(Document::ANIMATIONITERATION_LISTENER, EventTypeNames::animationiteration, elapsedTime);
- return;
}
- if ((isFirstSample || previousPhase == TimedItem::PhaseBefore) && isLaterPhase(currentPhase, TimedItem::PhaseBefore)) {
- ASSERT(timedItem->specified().startDelay > 0 || isFirstSample);
- // The spec states that the elapsed time should be
- // 'delay < 0 ? -delay : 0', but we always use 0 to match the existing
- // implementation. See crbug.com/279611
- maybeDispatch(Document::ANIMATIONSTART_LISTENER, EventTypeNames::animationstart, 0);
- }
- if ((isFirstSample || isEarlierPhase(previousPhase, TimedItem::PhaseAfter)) && currentPhase == TimedItem::PhaseAfter)
- maybeDispatch(Document::ANIMATIONEND_LISTENER, EventTypeNames::animationend, timedItem->activeDuration());
+
+ if (currentPhase == AnimationNode::PhaseAfter && m_previousPhase != AnimationNode::PhaseAfter)
+ maybeDispatch(Document::ANIMATIONEND_LISTENER, EventTypeNames::animationend, animationNode->activeDurationInternal());
+
+ m_previousPhase = currentPhase;
+ m_previousIteration = currentIteration;
}
-void CSSAnimations::TransitionEventDelegate::onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration)
+void CSSAnimations::TransitionEventDelegate::onEventCondition(const AnimationNode* animationNode)
{
- // Events for a single document are queued and dispatched as a group at
- // the end of DocumentTimeline::serviceAnimations.
- // FIXME: Events which are queued outside of serviceAnimations should
- // trigger a timer to dispatch when control is released.
- const TimedItem::Phase currentPhase = timedItem->phase();
- if (currentPhase == TimedItem::PhaseAfter && (isFirstSample || previousPhase != currentPhase) && m_target->document().hasListenerType(Document::TRANSITIONEND_LISTENER)) {
+ const AnimationNode::Phase currentPhase = animationNode->phase();
+ if (currentPhase == AnimationNode::PhaseAfter && currentPhase != m_previousPhase && m_target->document().hasListenerType(Document::TRANSITIONEND_LISTENER)) {
String propertyName = getPropertyNameString(m_property);
- const Timing& timing = timedItem->specified();
+ const Timing& timing = animationNode->specifiedTiming();
double elapsedTime = timing.iterationDuration;
const AtomicString& eventType = EventTypeNames::transitionend;
String pseudoElement = PseudoElement::pseudoElementNameForEvents(m_target->pseudoId());
- m_target->document().transitionTimeline()->addEventToDispatch(m_target, TransitionEvent::create(eventType, propertyName, elapsedTime, pseudoElement));
+ RefPtrWillBeRawPtr<TransitionEvent> event = TransitionEvent::create(eventType, propertyName, elapsedTime, pseudoElement);
+ event->setTarget(m_target);
+ m_target->document().enqueueAnimationFrameEvent(event);
}
-}
+ m_previousPhase = currentPhase;
+}
bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
{
@@ -810,8 +686,8 @@ bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
case CSSPropertyFloodColor:
case CSSPropertyFloodOpacity:
case CSSPropertyFontSize:
+ case CSSPropertyFontWeight:
case CSSPropertyHeight:
- case CSSPropertyKerning:
case CSSPropertyLeft:
case CSSPropertyLetterSpacing:
case CSSPropertyLightingColor:
@@ -848,6 +724,7 @@ bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
case CSSPropertyTextIndent:
case CSSPropertyTextShadow:
case CSSPropertyTop:
+ case CSSPropertyVerticalAlign:
case CSSPropertyVisibility:
case CSSPropertyWebkitBackgroundSize:
case CSSPropertyWebkitBorderHorizontalSpacing:
@@ -868,29 +745,27 @@ bool CSSAnimations::isAnimatableProperty(CSSPropertyID property)
case CSSPropertyWebkitMaskPositionX:
case CSSPropertyWebkitMaskPositionY:
case CSSPropertyWebkitMaskSize:
- case CSSPropertyWebkitPerspective:
- case CSSPropertyWebkitPerspectiveOriginX:
- case CSSPropertyWebkitPerspectiveOriginY:
- case CSSPropertyShapeInside:
+ case CSSPropertyPerspective:
case CSSPropertyShapeOutside:
case CSSPropertyShapeMargin:
case CSSPropertyShapeImageThreshold:
case CSSPropertyWebkitTextStrokeColor:
- case CSSPropertyWebkitTransform:
- case CSSPropertyWebkitTransformOriginX:
- case CSSPropertyWebkitTransformOriginY:
- case CSSPropertyWebkitTransformOriginZ:
+ case CSSPropertyTransform:
case CSSPropertyWidows:
case CSSPropertyWidth:
case CSSPropertyWordSpacing:
case CSSPropertyZIndex:
case CSSPropertyZoom:
return true;
- // FIXME: Shorthands should not be present in this list, but
- // CSSPropertyAnimation implements animation of these shorthands
- // directly and makes use of this method.
- case CSSPropertyFlex:
- return !RuntimeEnabledFeatures::webAnimationsCSSEnabled();
+ case CSSPropertyPerspectiveOrigin:
+ case CSSPropertyTransformOrigin:
+ return RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled();
+ case CSSPropertyWebkitPerspectiveOriginX:
+ case CSSPropertyWebkitPerspectiveOriginY:
+ case CSSPropertyWebkitTransformOriginX:
+ case CSSPropertyWebkitTransformOriginY:
+ case CSSPropertyWebkitTransformOriginZ:
+ return !RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled();
default:
return false;
}
@@ -911,4 +786,61 @@ const StylePropertyShorthand& CSSAnimations::animatableProperties()
return propertyShorthand;
}
+// Animation properties are not allowed to be affected by Web Animations.
+// http://dev.w3.org/fxtf/web-animations/#not-animatable
+bool CSSAnimations::isAllowedAnimation(CSSPropertyID property)
+{
+ switch (property) {
+ case CSSPropertyAnimation:
+ case CSSPropertyAnimationDelay:
+ case CSSPropertyAnimationDirection:
+ case CSSPropertyAnimationDuration:
+ case CSSPropertyAnimationFillMode:
+ case CSSPropertyAnimationIterationCount:
+ case CSSPropertyAnimationName:
+ case CSSPropertyAnimationPlayState:
+ case CSSPropertyAnimationTimingFunction:
+ case CSSPropertyDisplay:
+ case CSSPropertyTransition:
+ case CSSPropertyTransitionDelay:
+ case CSSPropertyTransitionDuration:
+ case CSSPropertyTransitionProperty:
+ case CSSPropertyTransitionTimingFunction:
+ case CSSPropertyWebkitAnimation:
+ case CSSPropertyWebkitAnimationDelay:
+ case CSSPropertyWebkitAnimationDirection:
+ case CSSPropertyWebkitAnimationDuration:
+ case CSSPropertyWebkitAnimationFillMode:
+ case CSSPropertyWebkitAnimationIterationCount:
+ case CSSPropertyWebkitAnimationName:
+ case CSSPropertyWebkitAnimationPlayState:
+ case CSSPropertyWebkitAnimationTimingFunction:
+ case CSSPropertyWebkitTransition:
+ case CSSPropertyWebkitTransitionDelay:
+ case CSSPropertyWebkitTransitionDuration:
+ case CSSPropertyWebkitTransitionProperty:
+ case CSSPropertyWebkitTransitionTimingFunction:
+ return false;
+ default:
+ return true;
+ }
+}
+
+void CSSAnimations::trace(Visitor* visitor)
+{
+ visitor->trace(m_transitions);
+ visitor->trace(m_pendingUpdate);
+ visitor->trace(m_animations);
+ visitor->trace(m_previousActiveInterpolationsForAnimations);
+}
+
+void CSSAnimationUpdate::trace(Visitor* visitor)
+{
+ visitor->trace(m_newTransitions);
+ visitor->trace(m_activeInterpolationsForAnimations);
+ visitor->trace(m_activeInterpolationsForTransitions);
+ visitor->trace(m_newAnimations);
+ visitor->trace(m_cancelledAnimationPlayers);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.h b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.h
index fb553d96232..31159f908ec 100644
--- a/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.h
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSAnimations.h
@@ -32,11 +32,11 @@
#define CSSAnimations_h
#include "core/animation/Animation.h"
+#include "core/animation/AnimationPlayer.h"
#include "core/animation/InertAnimation.h"
-#include "core/animation/Player.h"
+#include "core/animation/interpolation/Interpolation.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Document.h"
-#include "core/platform/animation/CSSAnimationData.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
@@ -44,39 +44,40 @@
namespace WebCore {
+class CSSTransitionData;
class Element;
class StylePropertyShorthand;
class StyleResolver;
class StyleRuleKeyframes;
// This class stores the CSS Animations/Transitions information we use during a style recalc.
-// This includes updates to animations/transitions as well as the CompositableValueMaps to be applied.
-class CSSAnimationUpdate FINAL {
+// This includes updates to animations/transitions as well as the Interpolations to be applied.
+class CSSAnimationUpdate FINAL : public NoBaseWillBeGarbageCollectedFinalized<CSSAnimationUpdate> {
public:
- void startAnimation(AtomicString& animationName, const HashSet<RefPtr<InertAnimation> >& animations)
+ void startAnimation(AtomicString& animationName, PassRefPtrWillBeRawPtr<InertAnimation> animation)
{
NewAnimation newAnimation;
newAnimation.name = animationName;
- newAnimation.animations = animations;
+ newAnimation.animation = animation;
m_newAnimations.append(newAnimation);
}
// Returns whether player has been cancelled and should be filtered during style application.
- bool isCancelledAnimation(const Player* player) const { return m_cancelledAnimationPlayers.contains(player); }
- void cancelAnimation(const AtomicString& name, const HashSet<RefPtr<Player> >& players)
+ bool isCancelledAnimation(const AnimationPlayer* player) const { return m_cancelledAnimationPlayers.contains(player); }
+ void cancelAnimation(const AtomicString& name, AnimationPlayer& player)
{
m_cancelledAnimationNames.append(name);
- for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
- m_cancelledAnimationPlayers.add(iter->get());
+ m_cancelledAnimationPlayers.add(&player);
}
void toggleAnimationPaused(const AtomicString& name)
{
m_animationsWithPauseToggled.append(name);
}
- void startTransition(CSSPropertyID id, const AnimatableValue* from, const AnimatableValue* to, PassRefPtr<InertAnimation> animation)
+ void startTransition(CSSPropertyID id, CSSPropertyID eventId, const AnimatableValue* from, const AnimatableValue* to, PassRefPtrWillBeRawPtr<InertAnimation> animation)
{
NewTransition newTransition;
newTransition.id = id;
+ newTransition.eventId = eventId;
newTransition.from = from;
newTransition.to = to;
newTransition.animation = animation;
@@ -86,29 +87,46 @@ public:
void cancelTransition(CSSPropertyID id) { m_cancelledTransitions.add(id); }
struct NewAnimation {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+ public:
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(animation);
+ }
+
AtomicString name;
- HashSet<RefPtr<InertAnimation> > animations;
+ RefPtrWillBeMember<InertAnimation> animation;
};
- const Vector<NewAnimation>& newAnimations() const { return m_newAnimations; }
+ const WillBeHeapVector<NewAnimation>& newAnimations() const { return m_newAnimations; }
const Vector<AtomicString>& cancelledAnimationNames() const { return m_cancelledAnimationNames; }
- const HashSet<const Player*>& cancelledAnimationPlayers() const { return m_cancelledAnimationPlayers; }
+ const WillBeHeapHashSet<RawPtrWillBeMember<const AnimationPlayer> >& cancelledAnimationAnimationPlayers() const { return m_cancelledAnimationPlayers; }
const Vector<AtomicString>& animationsWithPauseToggled() const { return m_animationsWithPauseToggled; }
struct NewTransition {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+ public:
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(from);
+ visitor->trace(to);
+ visitor->trace(animation);
+ }
+
CSSPropertyID id;
- const AnimatableValue* from;
- const AnimatableValue* to;
- RefPtr<InertAnimation> animation;
+ CSSPropertyID eventId;
+ RawPtrWillBeMember<const AnimatableValue> from;
+ RawPtrWillBeMember<const AnimatableValue> to;
+ RefPtrWillBeMember<InertAnimation> animation;
};
- typedef HashMap<CSSPropertyID, NewTransition> NewTransitionMap;
+ typedef WillBeHeapHashMap<CSSPropertyID, NewTransition> NewTransitionMap;
const NewTransitionMap& newTransitions() const { return m_newTransitions; }
const HashSet<CSSPropertyID>& cancelledTransitions() const { return m_cancelledTransitions; }
- void adoptCompositableValuesForAnimations(AnimationEffect::CompositableValueMap& newMap) { newMap.swap(m_compositableValuesForAnimations); }
- void adoptCompositableValuesForTransitions(AnimationEffect::CompositableValueMap& newMap) { newMap.swap(m_compositableValuesForTransitions); }
- const AnimationEffect::CompositableValueMap& compositableValuesForAnimations() const { return m_compositableValuesForAnimations; }
- const AnimationEffect::CompositableValueMap& compositableValuesForTransitions() const { return m_compositableValuesForTransitions; }
- AnimationEffect::CompositableValueMap& compositableValuesForAnimations() { return m_compositableValuesForAnimations; }
+ void adoptActiveInterpolationsForAnimations(WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& newMap) { newMap.swap(m_activeInterpolationsForAnimations); }
+ void adoptActiveInterpolationsForTransitions(WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& newMap) { newMap.swap(m_activeInterpolationsForTransitions); }
+ const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForAnimations() const { return m_activeInterpolationsForAnimations; }
+ const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForTransitions() const { return m_activeInterpolationsForTransitions; }
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForAnimations() { return m_activeInterpolationsForAnimations; }
bool isEmpty() const
{
@@ -118,28 +136,35 @@ public:
&& m_animationsWithPauseToggled.isEmpty()
&& m_newTransitions.isEmpty()
&& m_cancelledTransitions.isEmpty()
- && m_compositableValuesForAnimations.isEmpty()
- && m_compositableValuesForTransitions.isEmpty();
+ && m_activeInterpolationsForAnimations.isEmpty()
+ && m_activeInterpolationsForTransitions.isEmpty();
}
+
+ void trace(Visitor*);
+
private:
// Order is significant since it defines the order in which new animations
// will be started. Note that there may be multiple animations present
// with the same name, due to the way in which we split up animations with
// incomplete keyframes.
- Vector<NewAnimation> m_newAnimations;
+ WillBeHeapVector<NewAnimation> m_newAnimations;
Vector<AtomicString> m_cancelledAnimationNames;
- HashSet<const Player*> m_cancelledAnimationPlayers;
+ WillBeHeapHashSet<RawPtrWillBeMember<const AnimationPlayer> > m_cancelledAnimationPlayers;
Vector<AtomicString> m_animationsWithPauseToggled;
NewTransitionMap m_newTransitions;
HashSet<CSSPropertyID> m_cancelledTransitions;
- AnimationEffect::CompositableValueMap m_compositableValuesForAnimations;
- AnimationEffect::CompositableValueMap m_compositableValuesForTransitions;
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > m_activeInterpolationsForAnimations;
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > m_activeInterpolationsForTransitions;
};
class CSSAnimations FINAL {
+ WTF_MAKE_NONCOPYABLE(CSSAnimations);
+ DISALLOW_ALLOCATION();
public:
+ CSSAnimations();
+
// FIXME: This method is only used here and in the legacy animations
// implementation. It should be made private or file-scope when the legacy
// engine is removed.
@@ -147,68 +172,91 @@ public:
static bool isAnimatableProperty(CSSPropertyID);
static const StylePropertyShorthand& animatableProperties();
+ static bool isAllowedAnimation(CSSPropertyID);
// FIXME: This should take a const ScopedStyleTree instead of a StyleResolver.
// We should also change the Element* to a const Element*
- static PassOwnPtr<CSSAnimationUpdate> calculateUpdate(Element*, const Element& parentElement, const RenderStyle&, RenderStyle* parentStyle, StyleResolver*);
+ static PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> calculateUpdate(Element*, const Element& parentElement, const RenderStyle&, RenderStyle* parentStyle, StyleResolver*);
- void setPendingUpdate(PassOwnPtr<CSSAnimationUpdate> update) { m_pendingUpdate = update; }
+ void setPendingUpdate(PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> update) { m_pendingUpdate = update; }
void maybeApplyPendingUpdate(Element*);
bool isEmpty() const { return m_animations.isEmpty() && m_transitions.isEmpty() && !m_pendingUpdate; }
void cancel();
+ void trace(Visitor*);
+
private:
- // Note that a single animation name may map to multiple players due to
- // the way in which we split up animations with incomplete keyframes.
- // FIXME: Once the Web Animations model supports groups, we could use a
- // ParGroup to drive multiple animations from a single Player.
- typedef HashMap<AtomicString, HashSet<RefPtr<Player> > > AnimationMap;
struct RunningTransition {
- Animation* transition; // The TransitionTimeline keeps the Players alive
- const AnimatableValue* from;
- const AnimatableValue* to;
+ ALLOW_ONLY_INLINE_ALLOCATION();
+ public:
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(from);
+ visitor->trace(to);
+ visitor->trace(player);
+ }
+
+ RefPtrWillBeMember<AnimationPlayer> player;
+ RawPtrWillBeMember<const AnimatableValue> from;
+ RawPtrWillBeMember<const AnimatableValue> to;
};
- typedef HashMap<CSSPropertyID, RunningTransition > TransitionMap;
+
+ typedef WillBeHeapHashMap<AtomicString, RefPtrWillBeMember<AnimationPlayer> > AnimationMap;
AnimationMap m_animations;
+
+ typedef WillBeHeapHashMap<CSSPropertyID, RunningTransition> TransitionMap;
TransitionMap m_transitions;
- OwnPtr<CSSAnimationUpdate> m_pendingUpdate;
- AnimationEffect::CompositableValueMap m_previousCompositableValuesForAnimations;
+ OwnPtrWillBeMember<CSSAnimationUpdate> m_pendingUpdate;
+
+ WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > m_previousActiveInterpolationsForAnimations;
static void calculateAnimationUpdate(CSSAnimationUpdate*, Element*, const Element& parentElement, const RenderStyle&, RenderStyle* parentStyle, StyleResolver*);
static void calculateTransitionUpdate(CSSAnimationUpdate*, const Element*, const RenderStyle&);
- static void calculateTransitionUpdateForProperty(CSSPropertyID, const CSSAnimationData*, const RenderStyle& oldStyle, const RenderStyle&, const TransitionMap* activeTransitions, CSSAnimationUpdate*, const Element*);
+ static void calculateTransitionUpdateForProperty(CSSPropertyID, CSSPropertyID eventId, const CSSTransitionData&, size_t transitionIndex, const RenderStyle& oldStyle, const RenderStyle&, const TransitionMap* activeTransitions, CSSAnimationUpdate*, const Element*);
- static void calculateAnimationCompositableValues(CSSAnimationUpdate*, const Element*);
- static void calculateTransitionCompositableValues(CSSAnimationUpdate*, const Element*);
+ static void calculateAnimationActiveInterpolations(CSSAnimationUpdate*, const Element*, double timelineCurrentTime);
+ static void calculateTransitionActiveInterpolations(CSSAnimationUpdate*, const Element*, double timelineCurrentTime);
- class AnimationEventDelegate FINAL : public TimedItem::EventDelegate {
+ class AnimationEventDelegate FINAL : public AnimationNode::EventDelegate {
public:
AnimationEventDelegate(Element* target, const AtomicString& name)
: m_target(target)
, m_name(name)
+ , m_previousPhase(AnimationNode::PhaseNone)
+ , m_previousIteration(nullValue())
{
}
- virtual void onEventCondition(const TimedItem*, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration) OVERRIDE;
+ virtual void onEventCondition(const AnimationNode*) OVERRIDE;
private:
void maybeDispatch(Document::ListenerType, const AtomicString& eventName, double elapsedTime);
Element* m_target;
const AtomicString m_name;
+ AnimationNode::Phase m_previousPhase;
+ double m_previousIteration;
};
- class TransitionEventDelegate FINAL : public TimedItem::EventDelegate {
+ class TransitionEventDelegate FINAL : public AnimationNode::EventDelegate {
public:
TransitionEventDelegate(Element* target, CSSPropertyID property)
: m_target(target)
, m_property(property)
+ , m_previousPhase(AnimationNode::PhaseNone)
{
}
- virtual void onEventCondition(const TimedItem*, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration) OVERRIDE;
+ virtual void onEventCondition(const AnimationNode*) OVERRIDE;
private:
Element* m_target;
const CSSPropertyID m_property;
+ AnimationNode::Phase m_previousPhase;
};
};
} // namespace WebCore
+namespace WTF {
+template<> struct VectorTraits<WebCore::CSSAnimationUpdate::NewAnimation> : VectorTraitsBase<WebCore::CSSAnimationUpdate::NewAnimation> {
+ static const bool canInitializeWithMemset = true;
+};
+}
+
#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp b/chromium/third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp
deleted file mode 100644
index 3a4ec03d29e..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/css/CSSPendingAnimations.h"
-
-#include "core/animation/Animation.h"
-#include "core/animation/DocumentTimeline.h"
-#include "core/frame/FrameView.h"
-
-namespace WebCore {
-
-void CSSPendingAnimations::add(Player* player)
-{
- ASSERT(player->source()->isAnimation());
- // The actual start time is either this value, or the time that
- // this animation, or an animation that it is synchronized with
- // is started on the compositor.
- const double defaultStartTime = player->timeline().currentTime();
- m_pending.append(std::make_pair(player, defaultStartTime));
-}
-
-bool CSSPendingAnimations::startPendingAnimations()
-{
- bool startedOnCompositor = false;
- for (size_t i = 0; i < m_pending.size(); ++i) {
- if (m_pending[i].first->maybeStartAnimationOnCompositor())
- startedOnCompositor = true;
- }
-
- // If any animations were started on the compositor, all remaining
- // need to wait for a synchronized start time. Otherwise they may
- // start immediately.
- if (startedOnCompositor) {
- for (size_t i = 0; i < m_pending.size(); ++i)
- m_waitingForCompositorAnimationStart.append(m_pending[i].first);
- } else {
- for (size_t i = 0; i < m_pending.size(); ++i)
- m_pending[i].first->setStartTime(m_pending[i].second);
- }
- m_pending.clear();
-
- if (startedOnCompositor || m_waitingForCompositorAnimationStart.isEmpty())
- return !m_waitingForCompositorAnimationStart.isEmpty();
-
- // Check if we're still waiting for any compositor animations to start.
- for (size_t i = 0; i < m_waitingForCompositorAnimationStart.size(); ++i) {
- if (m_waitingForCompositorAnimationStart[i].get()->hasActiveAnimationsOnCompositor())
- return true;
- }
-
- // If not, go ahead and start any animations that were waiting.
- notifyCompositorAnimationStarted(monotonicallyIncreasingTime());
- return false;
-}
-
-void CSSPendingAnimations::notifyCompositorAnimationStarted(double monotonicAnimationStartTime)
-{
- for (size_t i = 0; i < m_waitingForCompositorAnimationStart.size(); ++i) {
- Player* player = m_waitingForCompositorAnimationStart[i].get();
- player->setStartTime(monotonicAnimationStartTime - player->timeline().zeroTime());
- }
-
- m_waitingForCompositorAnimationStart.clear();
-}
-
-} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.h b/chromium/third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.h
deleted file mode 100644
index 1bb3c28d4c0..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSPendingAnimations_h
-#define CSSPendingAnimations_h
-
-#include "core/animation/Player.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-// Used to synchronize the start of main-thread animations with compositor
-// animations when both classes of CSS Animations are triggered by the same recalc
-class CSSPendingAnimations FINAL {
-public:
- void add(Player*);
- // Returns whether we are waiting for an animation to start and should
- // service again on the next frame.
- bool startPendingAnimations();
- void notifyCompositorAnimationStarted(double monotonicAnimationStartTime);
-
-private:
- Vector<std::pair<RefPtr<Player>, double> > m_pending;
- Vector<RefPtr<Player> > m_waitingForCompositorAnimationStart;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp b/chromium/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp
new file mode 100644
index 00000000000..70ad01dbcb4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp
@@ -0,0 +1,318 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/css/CSSPropertyEquality.h"
+
+#include "core/animation/css/CSSAnimations.h"
+#include "core/rendering/style/DataEquivalency.h"
+#include "core/rendering/style/RenderStyle.h"
+#include "core/rendering/style/ShadowList.h"
+
+namespace WebCore {
+
+namespace {
+
+template <CSSPropertyID property>
+bool fillLayersEqual(const FillLayer* aLayer, const FillLayer* bLayer)
+{
+ if (aLayer == bLayer)
+ return true;
+ if (!aLayer || !bLayer)
+ return false;
+ while (aLayer && bLayer) {
+ switch (property) {
+ case CSSPropertyBackgroundPositionX:
+ case CSSPropertyWebkitMaskPositionX:
+ if (aLayer->xPosition() != bLayer->xPosition())
+ return false;
+ break;
+ case CSSPropertyBackgroundPositionY:
+ case CSSPropertyWebkitMaskPositionY:
+ if (aLayer->yPosition() != bLayer->yPosition())
+ return false;
+ break;
+ case CSSPropertyBackgroundSize:
+ case CSSPropertyWebkitBackgroundSize:
+ case CSSPropertyWebkitMaskSize:
+ if (!(aLayer->sizeLength() == bLayer->sizeLength()))
+ return false;
+ break;
+ case CSSPropertyBackgroundImage:
+ if (!dataEquivalent(aLayer->image(), bLayer->image()))
+ return false;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return true;
+ }
+
+ aLayer = aLayer->next();
+ bLayer = bLayer->next();
+ }
+
+ // FIXME: Shouldn't this be return !aLayer && !bLayer; ?
+ return true;
+}
+
+}
+
+bool CSSPropertyEquality::propertiesEqual(CSSPropertyID prop, const RenderStyle& a, const RenderStyle& b)
+{
+ switch (prop) {
+ case CSSPropertyBackgroundColor:
+ return a.backgroundColor().resolve(a.color()) == b.backgroundColor().resolve(b.color())
+ && a.visitedLinkBackgroundColor().resolve(a.color()) == b.visitedLinkBackgroundColor().resolve(b.color());
+ case CSSPropertyBackgroundImage:
+ return fillLayersEqual<CSSPropertyBackgroundImage>(a.backgroundLayers(), b.backgroundLayers());
+ case CSSPropertyBackgroundPositionX:
+ return fillLayersEqual<CSSPropertyBackgroundPositionX>(a.backgroundLayers(), b.backgroundLayers());
+ case CSSPropertyBackgroundPositionY:
+ return fillLayersEqual<CSSPropertyBackgroundPositionY>(a.backgroundLayers(), b.backgroundLayers());
+ case CSSPropertyBackgroundSize:
+ return fillLayersEqual<CSSPropertyBackgroundSize>(a.backgroundLayers(), b.backgroundLayers());
+ case CSSPropertyBaselineShift:
+ return dataEquivalent(a.baselineShiftValue(), b.baselineShiftValue());
+ case CSSPropertyBorderBottomColor:
+ return a.borderBottomColor().resolve(a.color()) == b.borderBottomColor().resolve(b.color())
+ && a.visitedLinkBorderBottomColor().resolve(a.color()) == b.visitedLinkBorderBottomColor().resolve(b.color());
+ case CSSPropertyBorderBottomLeftRadius:
+ return a.borderBottomLeftRadius() == b.borderBottomLeftRadius();
+ case CSSPropertyBorderBottomRightRadius:
+ return a.borderBottomRightRadius() == b.borderBottomRightRadius();
+ case CSSPropertyBorderBottomWidth:
+ return a.borderBottomWidth() == b.borderBottomWidth();
+ case CSSPropertyBorderImageOutset:
+ return a.borderImageOutset() == b.borderImageOutset();
+ case CSSPropertyBorderImageSlice:
+ return a.borderImageSlices() == b.borderImageSlices();
+ case CSSPropertyBorderImageSource:
+ return dataEquivalent(a.borderImageSource(), b.borderImageSource());
+ case CSSPropertyBorderImageWidth:
+ return a.borderImageWidth() == b.borderImageWidth();
+ case CSSPropertyBorderLeftColor:
+ return a.borderLeftColor().resolve(a.color()) == b.borderLeftColor().resolve(b.color())
+ && a.visitedLinkBorderLeftColor().resolve(a.color()) == b.visitedLinkBorderLeftColor().resolve(b.color());
+ case CSSPropertyBorderLeftWidth:
+ return a.borderLeftWidth() == b.borderLeftWidth();
+ case CSSPropertyBorderRightColor:
+ return a.borderRightColor().resolve(a.color()) == b.borderRightColor().resolve(b.color())
+ && a.visitedLinkBorderRightColor().resolve(a.color()) == b.visitedLinkBorderRightColor().resolve(b.color());
+ case CSSPropertyBorderRightWidth:
+ return a.borderRightWidth() == b.borderRightWidth();
+ case CSSPropertyBorderTopColor:
+ return a.borderTopColor().resolve(a.color()) == b.borderTopColor().resolve(b.color())
+ && a.visitedLinkBorderTopColor().resolve(a.color()) == b.visitedLinkBorderTopColor().resolve(b.color());
+ case CSSPropertyBorderTopLeftRadius:
+ return a.borderTopLeftRadius() == b.borderTopLeftRadius();
+ case CSSPropertyBorderTopRightRadius:
+ return a.borderTopRightRadius() == b.borderTopRightRadius();
+ case CSSPropertyBorderTopWidth:
+ return a.borderTopWidth() == b.borderTopWidth();
+ case CSSPropertyBottom:
+ return a.bottom() == b.bottom();
+ case CSSPropertyBoxShadow:
+ return dataEquivalent(a.boxShadow(), b.boxShadow());
+ case CSSPropertyClip:
+ return a.clip() == b.clip();
+ case CSSPropertyColor:
+ return a.color() == b.color() && a.visitedLinkColor() == b.visitedLinkColor();
+ case CSSPropertyFill: {
+ const SVGRenderStyle& aSVG = *a.svgStyle();
+ const SVGRenderStyle& bSVG = *b.svgStyle();
+ return aSVG.fillPaintType() == bSVG.fillPaintType()
+ && (aSVG.fillPaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || aSVG.fillPaintColor() == bSVG.fillPaintColor())
+ && aSVG.visitedLinkFillPaintType() == bSVG.visitedLinkFillPaintType()
+ && (aSVG.visitedLinkFillPaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || aSVG.visitedLinkFillPaintColor() == bSVG.visitedLinkFillPaintColor());
+ }
+ case CSSPropertyFillOpacity:
+ return a.fillOpacity() == b.fillOpacity();
+ case CSSPropertyFlexBasis:
+ return a.flexBasis() == b.flexBasis();
+ case CSSPropertyFlexGrow:
+ return a.flexGrow() == b.flexGrow();
+ case CSSPropertyFlexShrink:
+ return a.flexShrink() == b.flexShrink();
+ case CSSPropertyFloodColor:
+ return a.floodColor() == b.floodColor();
+ case CSSPropertyFloodOpacity:
+ return a.floodOpacity() == b.floodOpacity();
+ case CSSPropertyFontSize:
+ // CSSPropertyFontSize: Must pass a specified size to setFontSize if Text Autosizing is enabled, but a computed size
+ // if text zoom is enabled (if neither is enabled it's irrelevant as they're probably the same).
+ // FIXME: Should we introduce an option to pass the computed font size here, allowing consumers to
+ // enable text zoom rather than Text Autosizing? See http://crbug.com/227545.
+ return a.specifiedFontSize() == b.specifiedFontSize();
+ case CSSPropertyFontWeight:
+ return a.fontWeight() == b.fontWeight();
+ case CSSPropertyHeight:
+ return a.height() == b.height();
+ case CSSPropertyLeft:
+ return a.left() == b.left();
+ case CSSPropertyLetterSpacing:
+ return a.letterSpacing() == b.letterSpacing();
+ case CSSPropertyLightingColor:
+ return a.lightingColor() == b.lightingColor();
+ case CSSPropertyLineHeight:
+ return a.specifiedLineHeight() == b.specifiedLineHeight();
+ case CSSPropertyListStyleImage:
+ return dataEquivalent(a.listStyleImage(), b.listStyleImage());
+ case CSSPropertyMarginBottom:
+ return a.marginBottom() == b.marginBottom();
+ case CSSPropertyMarginLeft:
+ return a.marginLeft() == b.marginLeft();
+ case CSSPropertyMarginRight:
+ return a.marginRight() == b.marginRight();
+ case CSSPropertyMarginTop:
+ return a.marginTop() == b.marginTop();
+ case CSSPropertyMaxHeight:
+ return a.maxHeight() == b.maxHeight();
+ case CSSPropertyMaxWidth:
+ return a.maxWidth() == b.maxWidth();
+ case CSSPropertyMinHeight:
+ return a.minHeight() == b.minHeight();
+ case CSSPropertyMinWidth:
+ return a.minWidth() == b.minWidth();
+ case CSSPropertyObjectPosition:
+ return a.objectPosition() == b.objectPosition();
+ case CSSPropertyOpacity:
+ return a.opacity() == b.opacity();
+ case CSSPropertyOrphans:
+ return a.orphans() == b.orphans();
+ case CSSPropertyOutlineColor:
+ return a.outlineColor().resolve(a.color()) == b.outlineColor().resolve(b.color())
+ && a.visitedLinkOutlineColor().resolve(a.color()) == b.visitedLinkOutlineColor().resolve(b.color());
+ case CSSPropertyOutlineOffset:
+ return a.outlineOffset() == b.outlineOffset();
+ case CSSPropertyOutlineWidth:
+ return a.outlineWidth() == b.outlineWidth();
+ case CSSPropertyPaddingBottom:
+ return a.paddingBottom() == b.paddingBottom();
+ case CSSPropertyPaddingLeft:
+ return a.paddingLeft() == b.paddingLeft();
+ case CSSPropertyPaddingRight:
+ return a.paddingRight() == b.paddingRight();
+ case CSSPropertyPaddingTop:
+ return a.paddingTop() == b.paddingTop();
+ case CSSPropertyRight:
+ return a.right() == b.right();
+ case CSSPropertyShapeImageThreshold:
+ return a.shapeImageThreshold() == b.shapeImageThreshold();
+ case CSSPropertyShapeMargin:
+ return a.shapeMargin() == b.shapeMargin();
+ case CSSPropertyShapeOutside:
+ return dataEquivalent(a.shapeOutside(), b.shapeOutside());
+ case CSSPropertyStopColor:
+ return a.stopColor() == b.stopColor();
+ case CSSPropertyStopOpacity:
+ return a.stopOpacity() == b.stopOpacity();
+ case CSSPropertyStroke: {
+ const SVGRenderStyle& aSVG = *a.svgStyle();
+ const SVGRenderStyle& bSVG = *b.svgStyle();
+ return aSVG.strokePaintType() == bSVG.strokePaintType()
+ && (aSVG.strokePaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || aSVG.strokePaintColor() == bSVG.strokePaintColor())
+ && aSVG.visitedLinkStrokePaintType() == bSVG.visitedLinkStrokePaintType()
+ && (aSVG.visitedLinkStrokePaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || aSVG.visitedLinkStrokePaintColor() == bSVG.visitedLinkStrokePaintColor());
+ }
+ case CSSPropertyStrokeDasharray:
+ return dataEquivalent(a.strokeDashArray(), b.strokeDashArray());
+ case CSSPropertyStrokeDashoffset:
+ return dataEquivalent(a.strokeDashOffset(), b.strokeDashOffset());
+ case CSSPropertyStrokeMiterlimit:
+ return a.strokeMiterLimit() == b.strokeMiterLimit();
+ case CSSPropertyStrokeOpacity:
+ return a.strokeOpacity() == b.strokeOpacity();
+ case CSSPropertyStrokeWidth:
+ return dataEquivalent(a.strokeWidth(), b.strokeWidth());
+ case CSSPropertyTextDecorationColor:
+ return a.textDecorationColor().resolve(a.color()) == b.textDecorationColor().resolve(b.color())
+ && a.visitedLinkTextDecorationColor().resolve(a.color()) == b.visitedLinkTextDecorationColor().resolve(b.color());
+ case CSSPropertyTextIndent:
+ return a.textIndent() == b.textIndent();
+ case CSSPropertyTextShadow:
+ return dataEquivalent(a.textShadow(), b.textShadow());
+ case CSSPropertyTop:
+ return a.top() == b.top();
+ case CSSPropertyVerticalAlign:
+ return a.verticalAlign() == b.verticalAlign()
+ && (a.verticalAlign() != LENGTH || a.verticalAlignLength() == b.verticalAlignLength());
+ case CSSPropertyVisibility:
+ return a.visibility() == b.visibility();
+ case CSSPropertyWebkitBackgroundSize:
+ return fillLayersEqual<CSSPropertyWebkitBackgroundSize>(a.backgroundLayers(), b.backgroundLayers());
+ case CSSPropertyWebkitBorderHorizontalSpacing:
+ return a.horizontalBorderSpacing() == b.horizontalBorderSpacing();
+ case CSSPropertyWebkitBorderVerticalSpacing:
+ return a.verticalBorderSpacing() == b.verticalBorderSpacing();
+ case CSSPropertyWebkitBoxShadow:
+ return dataEquivalent(a.boxShadow(), b.boxShadow());
+ case CSSPropertyWebkitClipPath:
+ return dataEquivalent(a.clipPath(), b.clipPath());
+ case CSSPropertyWebkitColumnCount:
+ return a.columnCount() == b.columnCount();
+ case CSSPropertyWebkitColumnGap:
+ return a.columnGap() == b.columnGap();
+ case CSSPropertyWebkitColumnRuleColor:
+ return a.columnRuleColor().resolve(a.color()) == b.columnRuleColor().resolve(b.color())
+ && a.visitedLinkColumnRuleColor().resolve(a.color()) == b.visitedLinkColumnRuleColor().resolve(b.color());
+ case CSSPropertyWebkitColumnRuleWidth:
+ return a.columnRuleWidth() == b.columnRuleWidth();
+ case CSSPropertyWebkitColumnWidth:
+ return a.columnWidth() == b.columnWidth();
+ case CSSPropertyWebkitFilter:
+ return a.filter() == b.filter();
+ case CSSPropertyWebkitMaskBoxImageOutset:
+ return a.maskBoxImageOutset() == b.maskBoxImageOutset();
+ case CSSPropertyWebkitMaskBoxImageSlice:
+ return a.maskBoxImageSlices() == b.maskBoxImageSlices();
+ case CSSPropertyWebkitMaskBoxImageSource:
+ return dataEquivalent(a.maskBoxImageSource(), b.maskBoxImageSource());
+ case CSSPropertyWebkitMaskBoxImageWidth:
+ return a.maskBoxImageWidth() == b.maskBoxImageWidth();
+ case CSSPropertyWebkitMaskImage:
+ return dataEquivalent(a.maskImage(), b.maskImage());
+ case CSSPropertyWebkitMaskPositionX:
+ return fillLayersEqual<CSSPropertyWebkitMaskPositionX>(a.maskLayers(), b.maskLayers());
+ case CSSPropertyWebkitMaskPositionY:
+ return fillLayersEqual<CSSPropertyWebkitMaskPositionY>(a.maskLayers(), b.maskLayers());
+ case CSSPropertyWebkitMaskSize:
+ return fillLayersEqual<CSSPropertyWebkitMaskSize>(a.maskLayers(), b.maskLayers());
+ case CSSPropertyPerspective:
+ return a.perspective() == b.perspective();
+ case CSSPropertyPerspectiveOrigin:
+ return a.perspectiveOriginX() == b.perspectiveOriginX() && a.perspectiveOriginY() == b.perspectiveOriginY();
+ case CSSPropertyWebkitPerspectiveOriginX:
+ return a.perspectiveOriginX() == b.perspectiveOriginX();
+ case CSSPropertyWebkitPerspectiveOriginY:
+ return a.perspectiveOriginY() == b.perspectiveOriginY();
+ case CSSPropertyWebkitTextStrokeColor:
+ return a.textStrokeColor().resolve(a.color()) == b.textStrokeColor().resolve(b.color())
+ && a.visitedLinkTextStrokeColor().resolve(a.color()) == b.visitedLinkTextStrokeColor().resolve(b.color());
+ case CSSPropertyTransform:
+ return a.transform() == b.transform();
+ case CSSPropertyTransformOrigin:
+ return a.transformOriginX() == b.transformOriginX() && a.transformOriginY() == b.transformOriginY() && a.transformOriginZ() == b.transformOriginZ();
+ case CSSPropertyWebkitTransformOriginX:
+ return a.transformOriginX() == b.transformOriginX();
+ case CSSPropertyWebkitTransformOriginY:
+ return a.transformOriginY() == b.transformOriginY();
+ case CSSPropertyWebkitTransformOriginZ:
+ return a.transformOriginZ() == b.transformOriginZ();
+ case CSSPropertyWidows:
+ return a.widows() == b.widows();
+ case CSSPropertyWidth:
+ return a.width() == b.width();
+ case CSSPropertyWordSpacing:
+ return a.wordSpacing() == b.wordSpacing();
+ case CSSPropertyZIndex:
+ return a.zIndex() == b.zIndex();
+ case CSSPropertyZoom:
+ return a.zoom() == b.zoom();
+ default:
+ ASSERT_NOT_REACHED();
+ return true;
+ }
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.h b/chromium/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.h
new file mode 100644
index 00000000000..0a436f0046c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.h
@@ -0,0 +1,21 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSSPropertyEquality_h
+#define CSSPropertyEquality_h
+
+#include "core/CSSPropertyNames.h"
+
+namespace WebCore {
+
+class RenderStyle;
+
+class CSSPropertyEquality {
+public:
+ static bool propertiesEqual(CSSPropertyID, const RenderStyle&, const RenderStyle&);
+};
+
+} // namespace WebCore
+
+#endif // CSSPropertyEquality_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSTimingData.cpp b/chromium/third_party/WebKit/Source/core/animation/css/CSSTimingData.cpp
new file mode 100644
index 00000000000..9d628bd32c3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSTimingData.cpp
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/css/CSSTimingData.h"
+
+#include "core/animation/Timing.h"
+
+namespace WebCore {
+
+CSSTimingData::CSSTimingData()
+{
+ m_delayList.append(initialDelay());
+ m_durationList.append(initialDuration());
+ m_timingFunctionList.append(initialTimingFunction());
+}
+
+CSSTimingData::CSSTimingData(const CSSTimingData& other)
+ : m_delayList(other.m_delayList)
+ , m_durationList(other.m_durationList)
+ , m_timingFunctionList(other.m_timingFunctionList)
+{
+}
+
+Timing CSSTimingData::convertToTiming(size_t index) const
+{
+ Timing timing;
+ timing.startDelay = getRepeated(m_delayList, index);
+ timing.iterationDuration = getRepeated(m_durationList, index);
+ timing.timingFunction = getRepeated(m_timingFunctionList, index);
+ timing.assertValid();
+ return timing;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSTimingData.h b/chromium/third_party/WebKit/Source/core/animation/css/CSSTimingData.h
new file mode 100644
index 00000000000..33eab3b4b27
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSTimingData.h
@@ -0,0 +1,50 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSSTimingData_h
+#define CSSTimingData_h
+
+#include "platform/animation/TimingFunction.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+struct Timing;
+
+class CSSTimingData : public NoBaseWillBeGarbageCollectedFinalized<CSSTimingData> {
+public:
+ ~CSSTimingData() { }
+
+ void trace(Visitor*) { }
+
+ const Vector<double>& delayList() const { return m_delayList; }
+ const Vector<double>& durationList() const { return m_durationList; }
+ const Vector<RefPtr<TimingFunction> >& timingFunctionList() const { return m_timingFunctionList; }
+
+ Vector<double>& delayList() { return m_delayList; }
+ Vector<double>& durationList() { return m_durationList; }
+ Vector<RefPtr<TimingFunction> >& timingFunctionList() { return m_timingFunctionList; }
+
+ static double initialDelay() { return 0; }
+ static double initialDuration() { return 0; }
+ static PassRefPtr<TimingFunction> initialTimingFunction() { return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease); }
+
+ template <class T> static const T& getRepeated(const Vector<T>& v, size_t index) { return v[index % v.size()]; }
+
+protected:
+ CSSTimingData();
+ explicit CSSTimingData(const CSSTimingData&);
+
+ Timing convertToTiming(size_t index) const;
+
+private:
+ Vector<double> m_delayList;
+ Vector<double> m_durationList;
+ Vector<RefPtr<TimingFunction> > m_timingFunctionList;
+};
+
+} // namespace WebCore
+
+#endif // CSSTimingData_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSTransitionData.cpp b/chromium/third_party/WebKit/Source/core/animation/css/CSSTransitionData.cpp
new file mode 100644
index 00000000000..ad20621f30f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSTransitionData.cpp
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/css/CSSTransitionData.h"
+
+#include "core/animation/Timing.h"
+
+namespace WebCore {
+
+CSSTransitionData::CSSTransitionData()
+{
+ m_propertyList.append(initialProperty());
+}
+
+CSSTransitionData::CSSTransitionData(const CSSTransitionData& other)
+ : CSSTimingData(other)
+ , m_propertyList(other.m_propertyList)
+{
+}
+
+bool CSSTransitionData::transitionsMatchForStyleRecalc(const CSSTransitionData& other) const
+{
+ return m_propertyList == other.m_propertyList;
+}
+
+Timing CSSTransitionData::convertToTiming(size_t index) const
+{
+ ASSERT(index < m_propertyList.size());
+ // Note that the backwards fill part is required for delay to work.
+ Timing timing = CSSTimingData::convertToTiming(index);
+ timing.fillMode = Timing::FillModeBoth;
+ return timing;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/CSSTransitionData.h b/chromium/third_party/WebKit/Source/core/animation/css/CSSTransitionData.h
new file mode 100644
index 00000000000..792afc77afa
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/css/CSSTransitionData.h
@@ -0,0 +1,81 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSSTransitionData_h
+#define CSSTransitionData_h
+
+#include "core/CSSPropertyNames.h"
+#include "core/animation/css/CSSTimingData.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CSSTransitionData FINAL : public CSSTimingData {
+public:
+ enum TransitionPropertyType {
+ TransitionNone,
+ TransitionSingleProperty,
+ TransitionUnknown,
+ TransitionAll
+ };
+
+ // FIXME: We shouldn't allow 'none' to be used alongside other properties.
+ struct TransitionProperty {
+ TransitionProperty(CSSPropertyID id)
+ : propertyType(TransitionSingleProperty)
+ , propertyId(id)
+ {
+ ASSERT(id != CSSPropertyInvalid);
+ }
+
+ TransitionProperty(const String& string)
+ : propertyType(TransitionUnknown)
+ , propertyId(CSSPropertyInvalid)
+ , propertyString(string)
+ {
+ }
+
+ TransitionProperty(TransitionPropertyType type)
+ : propertyType(type)
+ , propertyId(CSSPropertyInvalid)
+ {
+ ASSERT(type == TransitionNone || type == TransitionAll);
+ }
+
+ bool operator==(const TransitionProperty& other) const { return propertyType == other.propertyType && propertyId == other.propertyId && propertyString == other.propertyString; }
+
+ TransitionPropertyType propertyType;
+ CSSPropertyID propertyId;
+ String propertyString;
+ };
+
+ static PassOwnPtrWillBeRawPtr<CSSTransitionData> create()
+ {
+ return adoptPtrWillBeNoop(new CSSTransitionData);
+ }
+
+ static PassOwnPtrWillBeRawPtr<CSSTransitionData> create(const CSSTransitionData& transitionData)
+ {
+ return adoptPtrWillBeNoop(new CSSTransitionData(transitionData));
+ }
+
+ bool transitionsMatchForStyleRecalc(const CSSTransitionData& other) const;
+
+ Timing convertToTiming(size_t index) const;
+
+ const Vector<TransitionProperty>& propertyList() const { return m_propertyList; }
+ Vector<TransitionProperty>& propertyList() { return m_propertyList; }
+
+ static TransitionProperty initialProperty() { return TransitionProperty(TransitionAll); }
+
+private:
+ CSSTransitionData();
+ explicit CSSTransitionData(const CSSTransitionData&);
+
+ Vector<TransitionProperty> m_propertyList;
+};
+
+} // namespace WebCore
+
+#endif // CSSTransitionData_h
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp b/chromium/third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp
deleted file mode 100644
index 33ec27f2b0b..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/css/TransitionTimeline.h"
-
-#include "core/animation/ActiveAnimations.h"
-#include "core/animation/AnimationClock.h"
-#include "core/animation/AnimationStack.h"
-
-namespace WebCore {
-
-PassRefPtr<TransitionTimeline> TransitionTimeline::create(Document* document, PassOwnPtr<PlatformTiming> timing)
-{
- return adoptRef(new TransitionTimeline(document, timing));
-}
-
-TransitionTimeline::TransitionTimeline(Document* document, PassOwnPtr<PlatformTiming> timing)
- : DocumentTimeline(document, timing)
-{
- setZeroTime(document->animationClock().currentTime());
- document->animationClock().unfreeze();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/animation/css/TransitionTimeline.h b/chromium/third_party/WebKit/Source/core/animation/css/TransitionTimeline.h
deleted file mode 100644
index 6d55f48772e..00000000000
--- a/chromium/third_party/WebKit/Source/core/animation/css/TransitionTimeline.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TransitionTimeline_h
-#define TransitionTimeline_h
-
-#include "core/animation/DocumentTimeline.h"
-
-namespace WebCore {
-
-class TransitionTimeline FINAL : public DocumentTimeline {
-public:
- static PassRefPtr<TransitionTimeline> create(Document*, PassOwnPtr<PlatformTiming> = nullptr);
-
-private:
- TransitionTimeline(Document*, PassOwnPtr<PlatformTiming>);
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/DefaultStyleInterpolation.h b/chromium/third_party/WebKit/Source/core/animation/interpolation/DefaultStyleInterpolation.h
new file mode 100644
index 00000000000..174c12b9fdd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/DefaultStyleInterpolation.h
@@ -0,0 +1,46 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DefaultStyleInterpolation_h
+#define DefaultStyleInterpolation_h
+
+#include "core/animation/interpolation/StyleInterpolation.h"
+#include "core/css/resolver/StyleBuilder.h"
+
+namespace WebCore {
+
+class DefaultStyleInterpolation : public StyleInterpolation {
+public:
+ static PassRefPtrWillBeRawPtr<DefaultStyleInterpolation> create(CSSValue* start, CSSValue* end, CSSPropertyID id)
+ {
+ return adoptRefWillBeNoop(new DefaultStyleInterpolation(start, end, id));
+ }
+
+ virtual void apply(StyleResolverState& state) const
+ {
+ StyleBuilder::applyProperty(m_id, state, toInterpolableBool(m_cachedValue.get())->value() ? m_endCSSValue.get() : m_startCSSValue.get());
+ }
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ StyleInterpolation::trace(visitor);
+ visitor->trace(m_startCSSValue);
+ visitor->trace(m_endCSSValue);
+ }
+
+private:
+ DefaultStyleInterpolation(CSSValue* start, CSSValue* end, CSSPropertyID id)
+ : StyleInterpolation(InterpolableBool::create(false), InterpolableBool::create(true), id)
+ , m_startCSSValue(start)
+ , m_endCSSValue(end)
+ {
+ }
+
+ RefPtrWillBeMember<CSSValue> m_startCSSValue;
+ RefPtrWillBeMember<CSSValue> m_endCSSValue;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolation.cpp b/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolation.cpp
new file mode 100644
index 00000000000..6a0be63049c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolation.cpp
@@ -0,0 +1,152 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/interpolation/DeferredLegacyStyleInterpolation.h"
+
+#include "core/animation/interpolation/LegacyStyleInterpolation.h"
+#include "core/css/CSSImageValue.h"
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSSVGDocumentValue.h"
+#include "core/css/CSSShadowValue.h"
+#include "core/css/CSSValueList.h"
+#include "core/css/Pair.h"
+#include "core/css/Rect.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/css/resolver/StyleResolverState.h"
+
+namespace WebCore {
+
+void DeferredLegacyStyleInterpolation::apply(StyleResolverState& state) const
+{
+ RefPtrWillBeRawPtr<LegacyStyleInterpolation> innerInterpolation = LegacyStyleInterpolation::create(
+ StyleResolver::createAnimatableValueSnapshot(state, m_id, *m_startCSSValue),
+ StyleResolver::createAnimatableValueSnapshot(state, m_id, *m_endCSSValue),
+ m_id);
+ innerInterpolation->interpolate(m_cachedIteration, m_cachedFraction);
+ innerInterpolation->apply(state);
+}
+
+bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValue& value)
+{
+ switch (value.cssValueType()) {
+ case CSSValue::CSS_INHERIT:
+ return true;
+ case CSSValue::CSS_PRIMITIVE_VALUE:
+ return interpolationRequiresStyleResolve(toCSSPrimitiveValue(value));
+ case CSSValue::CSS_VALUE_LIST:
+ return interpolationRequiresStyleResolve(toCSSValueList(value));
+ case CSSValue::CSS_CUSTOM:
+ if (value.isImageValue())
+ return interpolationRequiresStyleResolve(toCSSImageValue(value));
+ if (value.isShadowValue())
+ return interpolationRequiresStyleResolve(toCSSShadowValue(value));
+ if (value.isSVGDocumentValue())
+ return interpolationRequiresStyleResolve(toCSSSVGDocumentValue(value));
+ // FIXME: consider other custom types.
+ return true;
+ case CSSValue::CSS_INITIAL:
+ // FIXME: should not require resolving styles for initial.
+ return true;
+ default:
+ ASSERT_NOT_REACHED();
+ return true;
+ }
+}
+
+bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSPrimitiveValue& primitiveValue)
+{
+ // FIXME: consider other types.
+ if (primitiveValue.isNumber() || primitiveValue.isPercentage() || primitiveValue.isAngle() || primitiveValue.isRGBColor() || primitiveValue.isURI())
+ return false;
+
+ if (primitiveValue.isLength())
+ return primitiveValue.isFontRelativeLength() || primitiveValue.isViewportPercentageLength();
+
+ if (primitiveValue.isCalculated()) {
+ CSSLengthArray lengthArray(CSSPrimitiveValue::LengthUnitTypeCount);
+ primitiveValue.accumulateLengthArray(lengthArray);
+ return lengthArray[CSSPrimitiveValue::UnitTypeFontSize] != 0
+ || lengthArray[CSSPrimitiveValue::UnitTypeFontXSize] != 0
+ || lengthArray[CSSPrimitiveValue::UnitTypeRootFontSize] != 0
+ || lengthArray[CSSPrimitiveValue::UnitTypeZeroCharacterWidth] != 0
+ || lengthArray[CSSPrimitiveValue::UnitTypeViewportWidth] != 0
+ || lengthArray[CSSPrimitiveValue::UnitTypeViewportHeight] != 0
+ || lengthArray[CSSPrimitiveValue::UnitTypeViewportMin] != 0
+ || lengthArray[CSSPrimitiveValue::UnitTypeViewportMax] != 0;
+ }
+
+ if (Pair* pair = primitiveValue.getPairValue()) {
+ return interpolationRequiresStyleResolve(*pair->first())
+ || interpolationRequiresStyleResolve(*pair->second());
+ }
+
+ if (Rect* rect = primitiveValue.getRectValue()) {
+ return interpolationRequiresStyleResolve(*rect->top())
+ || interpolationRequiresStyleResolve(*rect->right())
+ || interpolationRequiresStyleResolve(*rect->bottom())
+ || interpolationRequiresStyleResolve(*rect->left());
+ }
+
+ if (Quad* quad = primitiveValue.getQuadValue()) {
+ return interpolationRequiresStyleResolve(*quad->top())
+ || interpolationRequiresStyleResolve(*quad->right())
+ || interpolationRequiresStyleResolve(*quad->bottom())
+ || interpolationRequiresStyleResolve(*quad->left());
+ }
+
+ if (primitiveValue.isShape())
+ return interpolationRequiresStyleResolve(*primitiveValue.getShapeValue());
+
+ CSSValueID id = primitiveValue.getValueID();
+ bool isColor = ((id >= CSSValueAqua && id <= CSSValueTransparent)
+ || (id >= CSSValueAliceblue && id <= CSSValueYellowgreen)
+ || id == CSSValueGrey);
+ return (id != CSSValueNone) && !isColor;
+}
+
+bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSImageValue& imageValue)
+{
+ return false;
+}
+
+bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSShadowValue& shadowValue)
+{
+ return (shadowValue.x && interpolationRequiresStyleResolve(*shadowValue.x))
+ || (shadowValue.y && interpolationRequiresStyleResolve(*shadowValue.y))
+ || (shadowValue.blur && interpolationRequiresStyleResolve(*shadowValue.blur))
+ || (shadowValue.spread && interpolationRequiresStyleResolve(*shadowValue.spread))
+ || (shadowValue.style && interpolationRequiresStyleResolve(*shadowValue.style))
+ || (shadowValue.color && interpolationRequiresStyleResolve(*shadowValue.color));
+}
+
+bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSSVGDocumentValue& documentValue)
+{
+ return true;
+}
+
+bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSValueList& valueList)
+{
+ size_t length = valueList.length();
+ for (size_t index = 0; index < length; ++index) {
+ if (interpolationRequiresStyleResolve(*valueList.item(index)))
+ return true;
+ }
+ return false;
+}
+
+bool DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(const CSSBasicShape& shape)
+{
+ // FIXME: Should determine the specific shape, and inspect the members.
+ return false;
+}
+
+void DeferredLegacyStyleInterpolation::trace(Visitor* visitor)
+{
+ visitor->trace(m_startCSSValue);
+ visitor->trace(m_endCSSValue);
+ StyleInterpolation::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolation.h b/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolation.h
new file mode 100644
index 00000000000..f1737bae269
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolation.h
@@ -0,0 +1,53 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DeferredLegacyStyleInterpolation_h
+#define DeferredLegacyStyleInterpolation_h
+
+#include "core/animation/interpolation/StyleInterpolation.h"
+#include "core/css/CSSValue.h"
+
+namespace WebCore {
+
+class CSSBasicShape;
+class CSSImageValue;
+class CSSPrimitiveValue;
+class CSSShadowValue;
+class CSSSVGDocumentValue;
+class CSSValueList;
+
+class DeferredLegacyStyleInterpolation : public StyleInterpolation {
+public:
+ static PassRefPtrWillBeRawPtr<DeferredLegacyStyleInterpolation> create(PassRefPtrWillBeRawPtr<CSSValue> start, PassRefPtrWillBeRawPtr<CSSValue> end, CSSPropertyID id)
+ {
+ return adoptRefWillBeNoop(new DeferredLegacyStyleInterpolation(start, end, id));
+ }
+
+ virtual void apply(StyleResolverState&) const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ static bool interpolationRequiresStyleResolve(const CSSValue&);
+ static bool interpolationRequiresStyleResolve(const CSSPrimitiveValue&);
+ static bool interpolationRequiresStyleResolve(const CSSImageValue&);
+ static bool interpolationRequiresStyleResolve(const CSSShadowValue&);
+ static bool interpolationRequiresStyleResolve(const CSSSVGDocumentValue&);
+ static bool interpolationRequiresStyleResolve(const CSSValueList&);
+ static bool interpolationRequiresStyleResolve(const CSSBasicShape&);
+
+private:
+ DeferredLegacyStyleInterpolation(PassRefPtrWillBeRawPtr<CSSValue> start, PassRefPtrWillBeRawPtr<CSSValue> end, CSSPropertyID id)
+ : StyleInterpolation(InterpolableNumber::create(0), InterpolableNumber::create(1), id)
+ , m_startCSSValue(start)
+ , m_endCSSValue(end)
+ {
+ }
+
+ RefPtrWillBeMember<CSSValue> m_startCSSValue;
+ RefPtrWillBeMember<CSSValue> m_endCSSValue;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolationTest.cpp b/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolationTest.cpp
new file mode 100644
index 00000000000..4c851f9648f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/DeferredLegacyStyleInterpolationTest.cpp
@@ -0,0 +1,94 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/interpolation/DeferredLegacyStyleInterpolation.h"
+
+#include "core/css/CSSInheritedValue.h"
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSValueList.h"
+#include "core/css/StylePropertySet.h"
+#include "core/css/parser/BisonCSSParser.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class AnimationDeferredLegacyStyleInterpolationTest : public ::testing::Test {
+protected:
+ static bool test(CSSPropertyID propertyID, const String& string)
+ {
+ CSSParserMode parserMode = HTMLStandardMode;
+ if (propertyID == CSSPropertyFloodColor)
+ parserMode = SVGAttributeMode;
+ RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
+ bool parseSuccess = BisonCSSParser::parseValue(dummyStyle.get(), propertyID, string, false, parserMode, 0);
+ ASSERT_UNUSED(parseSuccess, parseSuccess);
+ return DeferredLegacyStyleInterpolation::interpolationRequiresStyleResolve(*dummyStyle->getPropertyCSSValue(propertyID));
+ }
+};
+
+TEST_F(AnimationDeferredLegacyStyleInterpolationTest, Inherit)
+{
+ EXPECT_TRUE(test(CSSPropertyCaptionSide, "inherit"));
+}
+
+TEST_F(AnimationDeferredLegacyStyleInterpolationTest, Color)
+{
+ EXPECT_FALSE(test(CSSPropertyColor, "rgb(10, 20, 30)"));
+ EXPECT_FALSE(test(CSSPropertyColor, "aqua"));
+ EXPECT_FALSE(test(CSSPropertyColor, "yellow"));
+ EXPECT_FALSE(test(CSSPropertyColor, "transparent"));
+ EXPECT_FALSE(test(CSSPropertyFloodColor, "aliceblue"));
+ EXPECT_FALSE(test(CSSPropertyFloodColor, "yellowgreen"));
+ EXPECT_FALSE(test(CSSPropertyFloodColor, "grey"));
+ EXPECT_TRUE(test(CSSPropertyColor, "currentcolor"));
+}
+
+TEST_F(AnimationDeferredLegacyStyleInterpolationTest, Relative)
+{
+ EXPECT_TRUE(test(CSSPropertyFontWeight, "bolder"));
+ EXPECT_TRUE(test(CSSPropertyFontWeight, "lighter"));
+ EXPECT_TRUE(test(CSSPropertyFontSize, "smaller"));
+ EXPECT_TRUE(test(CSSPropertyFontSize, "larger"));
+}
+
+TEST_F(AnimationDeferredLegacyStyleInterpolationTest, Length)
+{
+ EXPECT_FALSE(test(CSSPropertyWidth, "10px"));
+ EXPECT_TRUE(test(CSSPropertyWidth, "10em"));
+ EXPECT_TRUE(test(CSSPropertyWidth, "10vh"));
+}
+
+TEST_F(AnimationDeferredLegacyStyleInterpolationTest, Number)
+{
+ EXPECT_FALSE(test(CSSPropertyOpacity, "0.5"));
+}
+
+TEST_F(AnimationDeferredLegacyStyleInterpolationTest, Transform)
+{
+ EXPECT_TRUE(test(CSSPropertyTransform, "translateX(1em)"));
+ EXPECT_FALSE(test(CSSPropertyTransform, "translateY(20px)"));
+ EXPECT_FALSE(test(CSSPropertyTransform, "skewX(10rad) perspective(400px)"));
+ EXPECT_TRUE(test(CSSPropertyTransform, "skewX(20rad) perspective(50em)"));
+}
+
+TEST_F(AnimationDeferredLegacyStyleInterpolationTest, Filter)
+{
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "hue-rotate(180deg) blur(6px)"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "grayscale(0) blur(0px)"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "none"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "brightness(0) contrast(0)"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "drop-shadow(20px 10px green)"));
+ EXPECT_TRUE(test(CSSPropertyWebkitFilter, "drop-shadow(20px 10vw green)"));
+ EXPECT_TRUE(test(CSSPropertyWebkitFilter, "drop-shadow(0px 0px 0px currentcolor)"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "opacity(1)"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "saturate(0)"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "grayscale(1)"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "invert(1)"));
+ EXPECT_FALSE(test(CSSPropertyWebkitFilter, "sepia(1)"));
+ EXPECT_TRUE(test(CSSPropertyWebkitFilter, "url(#svgfilter)"));
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/Interpolation.cpp b/chromium/third_party/WebKit/Source/core/animation/interpolation/Interpolation.cpp
new file mode 100644
index 00000000000..1ba5c6d74a8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/Interpolation.cpp
@@ -0,0 +1,63 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/interpolation/Interpolation.h"
+
+namespace WebCore {
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(Interpolation);
+
+namespace {
+
+bool typesMatch(const InterpolableValue* start, const InterpolableValue* end)
+{
+ if (start->isNumber())
+ return end->isNumber();
+ if (start->isBool())
+ return end->isBool();
+ if (start->isAnimatableValue())
+ return end->isAnimatableValue();
+ if (!(start->isList() && end->isList()))
+ return false;
+ const InterpolableList* startList = toInterpolableList(start);
+ const InterpolableList* endList = toInterpolableList(end);
+ if (startList->length() != endList->length())
+ return false;
+ for (size_t i = 0; i < startList->length(); ++i) {
+ if (!typesMatch(startList->get(i), endList->get(i)))
+ return false;
+ }
+ return true;
+}
+
+}
+
+Interpolation::Interpolation(PassOwnPtrWillBeRawPtr<InterpolableValue> start, PassOwnPtrWillBeRawPtr<InterpolableValue> end)
+ : m_start(start)
+ , m_end(end)
+ , m_cachedFraction(0)
+ , m_cachedIteration(0)
+ , m_cachedValue(m_start->clone())
+{
+ RELEASE_ASSERT(typesMatch(m_start.get(), m_end.get()));
+}
+
+void Interpolation::interpolate(int iteration, double fraction) const
+{
+ if (m_cachedFraction != fraction || m_cachedIteration != iteration) {
+ m_cachedValue = m_start->interpolate(*m_end, fraction);
+ m_cachedIteration = iteration;
+ m_cachedFraction = fraction;
+ }
+}
+
+void Interpolation::trace(Visitor* visitor)
+{
+ visitor->trace(m_start);
+ visitor->trace(m_end);
+ visitor->trace(m_cachedValue);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/Interpolation.h b/chromium/third_party/WebKit/Source/core/animation/interpolation/Interpolation.h
new file mode 100644
index 00000000000..ffa62b0cfca
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/Interpolation.h
@@ -0,0 +1,47 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef Interpolation_h
+#define Interpolation_h
+
+#include "core/animation/InterpolableValue.h"
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class Interpolation : public RefCountedWillBeGarbageCollected<Interpolation> {
+ DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(Interpolation);
+public:
+ static PassRefPtrWillBeRawPtr<Interpolation> create(PassOwnPtrWillBeRawPtr<InterpolableValue> start, PassOwnPtrWillBeRawPtr<InterpolableValue> end)
+ {
+ return adoptRefWillBeNoop(new Interpolation(start, end));
+ }
+
+ void interpolate(int iteration, double fraction) const;
+
+ virtual bool isStyleInterpolation() const { return false; }
+ virtual bool isLegacyStyleInterpolation() const { return false; }
+
+ virtual void trace(Visitor*);
+
+protected:
+ const OwnPtrWillBeMember<InterpolableValue> m_start;
+ const OwnPtrWillBeMember<InterpolableValue> m_end;
+
+ mutable double m_cachedFraction;
+ mutable int m_cachedIteration;
+ mutable OwnPtrWillBeMember<InterpolableValue> m_cachedValue;
+
+ Interpolation(PassOwnPtrWillBeRawPtr<InterpolableValue> start, PassOwnPtrWillBeRawPtr<InterpolableValue> end);
+
+private:
+ InterpolableValue* getCachedValueForTesting() const { return m_cachedValue.get(); }
+
+ friend class AnimationInterpolableValueTest;
+ friend class AnimationInterpolationEffectTest;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/LegacyStyleInterpolation.h b/chromium/third_party/WebKit/Source/core/animation/interpolation/LegacyStyleInterpolation.h
new file mode 100644
index 00000000000..d16bd994f4a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/LegacyStyleInterpolation.h
@@ -0,0 +1,48 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LegacyStyleInterpolation_h
+#define LegacyStyleInterpolation_h
+
+#include "core/animation/interpolation/StyleInterpolation.h"
+#include "core/css/resolver/AnimatedStyleBuilder.h"
+
+namespace WebCore {
+
+class LegacyStyleInterpolation : public StyleInterpolation {
+public:
+ static PassRefPtrWillBeRawPtr<LegacyStyleInterpolation> create(PassRefPtrWillBeRawPtr<AnimatableValue> start, PassRefPtrWillBeRawPtr<AnimatableValue> end, CSSPropertyID id)
+ {
+ return adoptRefWillBeNoop(new LegacyStyleInterpolation(InterpolableAnimatableValue::create(start), InterpolableAnimatableValue::create(end), id));
+ }
+
+ virtual void apply(StyleResolverState& state) const OVERRIDE
+ {
+ AnimatedStyleBuilder::applyProperty(m_id, state, currentValue().get());
+ }
+
+ virtual bool isLegacyStyleInterpolation() const OVERRIDE FINAL { return true; }
+ PassRefPtrWillBeRawPtr<AnimatableValue> currentValue() const
+ {
+ InterpolableAnimatableValue* value = static_cast<InterpolableAnimatableValue*>(m_cachedValue.get());
+ return value->value();
+ }
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ StyleInterpolation::trace(visitor);
+ }
+
+private:
+ LegacyStyleInterpolation(PassOwnPtrWillBeRawPtr<InterpolableValue> start, PassOwnPtrWillBeRawPtr<InterpolableValue> end, CSSPropertyID id)
+ : StyleInterpolation(start, end, id)
+ {
+ }
+};
+
+DEFINE_TYPE_CASTS(LegacyStyleInterpolation, Interpolation, value, value->isLegacyStyleInterpolation(), value.isLegacyStyleInterpolation());
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolation.cpp b/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolation.cpp
new file mode 100644
index 00000000000..013d3067be6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolation.cpp
@@ -0,0 +1,109 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/interpolation/LengthStyleInterpolation.h"
+
+#include "core/css/CSSCalculationValue.h"
+#include "core/css/resolver/StyleBuilder.h"
+
+namespace WebCore {
+
+bool LengthStyleInterpolation::canCreateFrom(const CSSValue& value)
+{
+ if (value.isPrimitiveValue()) {
+ const CSSPrimitiveValue& primitiveValue = WebCore::toCSSPrimitiveValue(value);
+ if (primitiveValue.cssCalcValue())
+ return true;
+
+ CSSPrimitiveValue::LengthUnitType type;
+ // Only returns true if the type is a primitive length unit.
+ return CSSPrimitiveValue::unitTypeToLengthUnitType(primitiveValue.primitiveType(), type);
+ }
+ return value.isCalcValue();
+}
+
+PassOwnPtrWillBeRawPtr<InterpolableValue> LengthStyleInterpolation::lengthToInterpolableValue(CSSValue* value)
+{
+ OwnPtrWillBeRawPtr<InterpolableList> result = InterpolableList::create(CSSPrimitiveValue::LengthUnitTypeCount);
+ CSSPrimitiveValue* primitive = toCSSPrimitiveValue(value);
+
+ CSSLengthArray array;
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++)
+ array.append(0);
+ primitive->accumulateLengthArray(array);
+
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++)
+ result->set(i, InterpolableNumber::create(array.at(i)));
+
+ return result.release();
+}
+
+namespace {
+
+static CSSPrimitiveValue::UnitType toUnitType(int lengthUnitType)
+{
+ return static_cast<CSSPrimitiveValue::UnitType>(CSSPrimitiveValue::lengthUnitTypeToUnitType(static_cast<CSSPrimitiveValue::LengthUnitType>(lengthUnitType)));
+}
+
+static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> constructCalcExpression(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> previous, InterpolableList* list, size_t position)
+{
+ while (position != CSSPrimitiveValue::LengthUnitTypeCount) {
+ const InterpolableNumber *subValue = toInterpolableNumber(list->get(position));
+ if (subValue->value()) {
+ RefPtrWillBeRawPtr<CSSCalcExpressionNode> next;
+ if (previous)
+ next = CSSCalcValue::createExpressionNode(previous, CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(subValue->value(), toUnitType(position))), CalcAdd);
+ else
+ next = CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(subValue->value(), toUnitType(position)));
+ return constructCalcExpression(next, list, position + 1);
+ }
+ position++;
+ }
+ return previous;
+}
+
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> LengthStyleInterpolation::interpolableValueToLength(InterpolableValue* value, ValueRange range)
+{
+ InterpolableList* listValue = toInterpolableList(value);
+ unsigned unitCount = 0;
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) {
+ const InterpolableNumber* subValue = toInterpolableNumber(listValue->get(i));
+ if (subValue->value()) {
+ unitCount++;
+ }
+ }
+
+ switch (unitCount) {
+ case 0:
+ return CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX);
+ case 1:
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; i++) {
+ const InterpolableNumber* subValue = toInterpolableNumber(listValue->get(i));
+ double value = subValue->value();
+ if (value) {
+ if (range == ValueRangeNonNegative && value < 0)
+ value = 0;
+ return CSSPrimitiveValue::create(value, toUnitType(i));
+ }
+ }
+ ASSERT_NOT_REACHED();
+ default:
+ return CSSPrimitiveValue::create(CSSCalcValue::create(constructCalcExpression(nullptr, listValue, 0), range));
+ }
+}
+
+void LengthStyleInterpolation::apply(StyleResolverState& state) const
+{
+ StyleBuilder::applyProperty(m_id, state, interpolableValueToLength(m_cachedValue.get(), m_range).get());
+}
+
+void LengthStyleInterpolation::trace(Visitor* visitor)
+{
+ StyleInterpolation::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolation.h b/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolation.h
new file mode 100644
index 00000000000..d344957da8c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolation.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LengthStyleInterpolation_h
+#define LengthStyleInterpolation_h
+
+#include "core/animation/interpolation/StyleInterpolation.h"
+#include "platform/Length.h"
+
+namespace WebCore {
+
+class LengthStyleInterpolation : public StyleInterpolation {
+public:
+ static PassRefPtrWillBeRawPtr<LengthStyleInterpolation> create(CSSValue* start, CSSValue* end, CSSPropertyID id, ValueRange range)
+ {
+ return adoptRefWillBeNoop(new LengthStyleInterpolation(lengthToInterpolableValue(start), lengthToInterpolableValue(end), id, range));
+ }
+
+ static bool canCreateFrom(const CSSValue&);
+
+ virtual void apply(StyleResolverState&) const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ LengthStyleInterpolation(PassOwnPtrWillBeRawPtr<InterpolableValue> start, PassOwnPtrWillBeRawPtr<InterpolableValue> end, CSSPropertyID id, ValueRange range)
+ : StyleInterpolation(start, end, id)
+ , m_range(range)
+ { }
+
+ static PassOwnPtrWillBeRawPtr<InterpolableValue> lengthToInterpolableValue(CSSValue*);
+ static PassRefPtrWillBeRawPtr<CSSValue> interpolableValueToLength(InterpolableValue*, ValueRange);
+
+ ValueRange m_range;
+
+ friend class AnimationLengthStyleInterpolationTest;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolationTest.cpp b/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolationTest.cpp
new file mode 100644
index 00000000000..8120e846fdf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/LengthStyleInterpolationTest.cpp
@@ -0,0 +1,119 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/interpolation/LengthStyleInterpolation.h"
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/StylePropertySet.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class AnimationLengthStyleInterpolationTest : public ::testing::Test {
+protected:
+ static PassOwnPtrWillBeRawPtr<InterpolableValue> lengthToInterpolableValue(CSSValue* value)
+ {
+ return LengthStyleInterpolation::lengthToInterpolableValue(value);
+ }
+
+ static PassRefPtrWillBeRawPtr<CSSValue> interpolableValueToLength(InterpolableValue* value, ValueRange range)
+ {
+ return LengthStyleInterpolation::interpolableValueToLength(value, range);
+ }
+
+ static PassRefPtrWillBeRawPtr<CSSValue> roundTrip(PassRefPtrWillBeRawPtr<CSSValue> value)
+ {
+ return interpolableValueToLength(lengthToInterpolableValue(value.get()).get(), ValueRangeAll);
+ }
+
+ static void testPrimitiveValue(RefPtrWillBeRawPtr<CSSValue> value, double doubleValue, CSSPrimitiveValue::UnitType unitType)
+ {
+ EXPECT_TRUE(value->isPrimitiveValue());
+ EXPECT_EQ(doubleValue, toCSSPrimitiveValue(value.get())->getDoubleValue());
+ EXPECT_EQ(unitType, toCSSPrimitiveValue(value.get())->primitiveType());
+ }
+
+ static PassOwnPtrWillBeRawPtr<InterpolableList> createInterpolableLength(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j)
+ {
+ OwnPtrWillBeRawPtr<InterpolableList> list = InterpolableList::create(10);
+ list->set(0, InterpolableNumber::create(a));
+ list->set(1, InterpolableNumber::create(b));
+ list->set(2, InterpolableNumber::create(c));
+ list->set(3, InterpolableNumber::create(d));
+ list->set(4, InterpolableNumber::create(e));
+ list->set(5, InterpolableNumber::create(f));
+ list->set(6, InterpolableNumber::create(g));
+ list->set(7, InterpolableNumber::create(h));
+ list->set(8, InterpolableNumber::create(i));
+ list->set(9, InterpolableNumber::create(j));
+
+ return list.release();
+ }
+
+ void initLengthArray(CSSLengthArray& lengthArray)
+ {
+ lengthArray.resize(CSSPrimitiveValue::LengthUnitTypeCount);
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i)
+ lengthArray.at(i) = 0;
+ }
+
+ CSSLengthArray& setLengthArray(CSSLengthArray& lengthArray, String text)
+ {
+ initLengthArray(lengthArray);
+ RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
+ propertySet->setProperty(CSSPropertyLeft, text);
+ toCSSPrimitiveValue(propertySet->getPropertyCSSValue(CSSPropertyLeft).get())->accumulateLengthArray(lengthArray);
+ return lengthArray;
+ }
+
+ bool lengthArraysEqual(CSSLengthArray& a, CSSLengthArray& b)
+ {
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i) {
+ if (a.at(i) != b.at(i))
+ return false;
+ }
+ return true;
+ }
+};
+
+TEST_F(AnimationLengthStyleInterpolationTest, ZeroLength)
+{
+ RefPtrWillBeRawPtr<CSSValue> value = roundTrip(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX));
+ testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_PX);
+
+ value = roundTrip(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_EMS));
+ testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_PX);
+}
+
+TEST_F(AnimationLengthStyleInterpolationTest, SingleUnit)
+{
+ RefPtrWillBeRawPtr<CSSValue> value = roundTrip(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX));
+ testPrimitiveValue(value, 10, CSSPrimitiveValue::CSS_PX);
+
+ value = roundTrip(CSSPrimitiveValue::create(30, CSSPrimitiveValue::CSS_PERCENTAGE));
+ testPrimitiveValue(value, 30, CSSPrimitiveValue::CSS_PERCENTAGE);
+
+ value = roundTrip(CSSPrimitiveValue::create(-10, CSSPrimitiveValue::CSS_EMS));
+ testPrimitiveValue(value, -10, CSSPrimitiveValue::CSS_EMS);
+}
+
+TEST_F(AnimationLengthStyleInterpolationTest, SingleClampedUnit)
+{
+ RefPtrWillBeRawPtr<CSSValue> value = CSSPrimitiveValue::create(-10, CSSPrimitiveValue::CSS_EMS);
+ value = interpolableValueToLength(lengthToInterpolableValue(value.get()).get(), ValueRangeNonNegative);
+ testPrimitiveValue(value, 0, CSSPrimitiveValue::CSS_EMS);
+}
+
+TEST_F(AnimationLengthStyleInterpolationTest, MultipleUnits)
+{
+ CSSLengthArray actual, expectation;
+ initLengthArray(expectation);
+ OwnPtrWillBeRawPtr<InterpolableList> list = createInterpolableLength(0, 10, 0, 10, 0, 10, 0, 10, 0, 10);
+ toCSSPrimitiveValue(interpolableValueToLength(list.get(), ValueRangeAll).get())->accumulateLengthArray(expectation);
+ EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc(10%% + 10ex + 10ch + 10vh + 10vmax)")));
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/animation/interpolation/StyleInterpolation.h b/chromium/third_party/WebKit/Source/core/animation/interpolation/StyleInterpolation.h
new file mode 100644
index 00000000000..5c277439ffd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/animation/interpolation/StyleInterpolation.h
@@ -0,0 +1,48 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StyleInterpolation_h
+#define StyleInterpolation_h
+
+#include "core/CSSPropertyNames.h"
+#include "core/animation/interpolation/Interpolation.h"
+
+namespace WebCore {
+
+class StyleResolverState;
+
+class StyleInterpolation : public Interpolation {
+public:
+ // 1) convert m_cachedValue into an X
+ // 2) shove X into StyleResolverState
+ // X can be:
+ // (1) a CSSValue (and applied via StyleBuilder::applyProperty)
+ // (2) an AnimatableValue (and applied via // AnimatedStyleBuilder::applyProperty)
+ // (3) a custom value that is inserted directly into the StyleResolverState.
+ virtual void apply(StyleResolverState&) const = 0;
+
+ virtual bool isStyleInterpolation() const OVERRIDE FINAL { return true; }
+
+ CSSPropertyID id() const { return m_id; }
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ Interpolation::trace(visitor);
+ }
+
+protected:
+ CSSPropertyID m_id;
+
+ StyleInterpolation(PassOwnPtrWillBeRawPtr<InterpolableValue> start, PassOwnPtrWillBeRawPtr<InterpolableValue> end, CSSPropertyID id)
+ : Interpolation(start, end)
+ , m_id(id)
+ {
+ }
+};
+
+DEFINE_TYPE_CASTS(StyleInterpolation, Interpolation, value, value->isStyleInterpolation(), value.isStyleInterpolation());
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/Clipboard.cpp b/chromium/third_party/WebKit/Source/core/clipboard/Clipboard.cpp
new file mode 100644
index 00000000000..137a2fed858
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/Clipboard.cpp
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/clipboard/Clipboard.h"
+
+#include "core/HTMLNames.h"
+#include "core/clipboard/DataObject.h"
+#include "core/clipboard/DataTransferItem.h"
+#include "core/clipboard/DataTransferItemList.h"
+#include "core/editing/markup.h"
+#include "core/fetch/ImageResource.h"
+#include "core/fileapi/FileList.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLImageElement.h"
+#include "core/rendering/RenderImage.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderObject.h"
+#include "platform/DragImage.h"
+#include "platform/MIMETypeRegistry.h"
+#include "platform/clipboard/ClipboardMimeTypes.h"
+#include "platform/clipboard/ClipboardUtilities.h"
+
+namespace WebCore {
+
+// These "conversion" methods are called by both WebCore and WebKit, and never make sense to JS, so we don't
+// worry about security for these. They don't allow access to the pasteboard anyway.
+static DragOperation dragOpFromIEOp(const String& op)
+{
+ // yep, it's really just this fixed set
+ if (op == "uninitialized")
+ return DragOperationEvery;
+ if (op == "none")
+ return DragOperationNone;
+ if (op == "copy")
+ return DragOperationCopy;
+ if (op == "link")
+ return DragOperationLink;
+ if (op == "move")
+ return (DragOperation)(DragOperationGeneric | DragOperationMove);
+ if (op == "copyLink")
+ return (DragOperation)(DragOperationCopy | DragOperationLink);
+ if (op == "copyMove")
+ return (DragOperation)(DragOperationCopy | DragOperationGeneric | DragOperationMove);
+ if (op == "linkMove")
+ return (DragOperation)(DragOperationLink | DragOperationGeneric | DragOperationMove);
+ if (op == "all")
+ return DragOperationEvery;
+ return DragOperationPrivate; // really a marker for "no conversion"
+}
+
+static String IEOpFromDragOp(DragOperation op)
+{
+ bool moveSet = !!((DragOperationGeneric | DragOperationMove) & op);
+
+ if ((moveSet && (op & DragOperationCopy) && (op & DragOperationLink))
+ || (op == DragOperationEvery))
+ return "all";
+ if (moveSet && (op & DragOperationCopy))
+ return "copyMove";
+ if (moveSet && (op & DragOperationLink))
+ return "linkMove";
+ if ((op & DragOperationCopy) && (op & DragOperationLink))
+ return "copyLink";
+ if (moveSet)
+ return "move";
+ if (op & DragOperationCopy)
+ return "copy";
+ if (op & DragOperationLink)
+ return "link";
+ return "none";
+}
+
+// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
+// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
+static String normalizeType(const String& type, bool* convertToURL = 0)
+{
+ String cleanType = type.stripWhiteSpace().lower();
+ if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc))
+ return mimeTypeTextPlain;
+ if (cleanType == mimeTypeURL) {
+ if (convertToURL)
+ *convertToURL = true;
+ return mimeTypeTextURIList;
+ }
+ return cleanType;
+}
+
+PassRefPtrWillBeRawPtr<Clipboard> Clipboard::create(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtrWillBeRawPtr<DataObject> dataObject)
+{
+ return adoptRefWillBeNoop(new Clipboard(type, policy , dataObject));
+}
+
+Clipboard::~Clipboard()
+{
+}
+
+void Clipboard::setDropEffect(const String &effect)
+{
+ if (!isForDragAndDrop())
+ return;
+
+ // The attribute must ignore any attempts to set it to a value other than none, copy, link, and move.
+ if (effect != "none" && effect != "copy" && effect != "link" && effect != "move")
+ return;
+
+ // FIXME: The spec actually allows this in all circumstances, even though there's no point in
+ // setting the drop effect when this condition is not true.
+ if (canReadTypes())
+ m_dropEffect = effect;
+}
+
+void Clipboard::setEffectAllowed(const String &effect)
+{
+ if (!isForDragAndDrop())
+ return;
+
+ if (dragOpFromIEOp(effect) == DragOperationPrivate) {
+ // This means that there was no conversion, and the effectAllowed that
+ // we are passed isn't a valid effectAllowed, so we should ignore it,
+ // and not set m_effectAllowed.
+
+ // The attribute must ignore any attempts to set it to a value other than
+ // none, copy, copyLink, copyMove, link, linkMove, move, all, and uninitialized.
+ return;
+ }
+
+
+ if (canWriteData())
+ m_effectAllowed = effect;
+}
+
+void Clipboard::clearData(const String& type)
+{
+ if (!canWriteData())
+ return;
+
+ if (type.isNull())
+ m_dataObject->clearAll();
+ else
+ m_dataObject->clearData(normalizeType(type));
+}
+
+String Clipboard::getData(const String& type) const
+{
+ if (!canReadData())
+ return String();
+
+ bool convertToURL = false;
+ String data = m_dataObject->getData(normalizeType(type, &convertToURL));
+ if (!convertToURL)
+ return data;
+ return convertURIListToURL(data);
+}
+
+bool Clipboard::setData(const String& type, const String& data)
+{
+ if (!canWriteData())
+ return false;
+
+ return m_dataObject->setData(normalizeType(type), data);
+}
+
+// extensions beyond IE's API
+Vector<String> Clipboard::types() const
+{
+ Vector<String> types;
+ if (!canReadTypes())
+ return types;
+
+ ListHashSet<String> typesSet = m_dataObject->types();
+ types.appendRange(typesSet.begin(), typesSet.end());
+ return types;
+}
+
+PassRefPtrWillBeRawPtr<FileList> Clipboard::files() const
+{
+ RefPtrWillBeRawPtr<FileList> files = FileList::create();
+ if (!canReadData())
+ return files.release();
+
+ for (size_t i = 0; i < m_dataObject->length(); ++i) {
+ if (m_dataObject->item(i)->kind() == DataObjectItem::FileKind) {
+ RefPtrWillBeRawPtr<Blob> blob = m_dataObject->item(i)->getAsFile();
+ if (blob && blob->isFile())
+ files->append(toFile(blob.get()));
+ }
+ }
+
+ return files.release();
+}
+
+void Clipboard::setDragImage(Element* image, int x, int y, ExceptionState& exceptionState)
+{
+ if (!isForDragAndDrop())
+ return;
+
+ if (!image) {
+ exceptionState.throwTypeError("setDragImage: Invalid first argument");
+ return;
+ }
+ IntPoint location(x, y);
+ if (isHTMLImageElement(*image) && !image->inDocument())
+ setDragImageResource(toHTMLImageElement(*image).cachedImage(), location);
+ else
+ setDragImageElement(image, location);
+}
+
+void Clipboard::clearDragImage()
+{
+ if (!canSetDragImage())
+ return;
+
+ m_dragImage = 0;
+ m_dragLoc = IntPoint();
+ m_dragImageElement = nullptr;
+}
+
+void Clipboard::setDragImageResource(ImageResource* img, const IntPoint& loc)
+{
+ setDragImage(img, 0, loc);
+}
+
+void Clipboard::setDragImageElement(Node* node, const IntPoint& loc)
+{
+ setDragImage(0, node, loc);
+}
+
+PassOwnPtr<DragImage> Clipboard::createDragImage(IntPoint& loc, LocalFrame* frame) const
+{
+ if (m_dragImageElement) {
+ loc = m_dragLoc;
+
+ return frame->nodeImage(*m_dragImageElement);
+ }
+ if (m_dragImage) {
+ loc = m_dragLoc;
+ return DragImage::create(m_dragImage->image());
+ }
+ return nullptr;
+}
+
+static ImageResource* getImageResource(Element* element)
+{
+ // Attempt to pull ImageResource from element
+ ASSERT(element);
+ RenderObject* renderer = element->renderer();
+ if (!renderer || !renderer->isImage())
+ return 0;
+
+ RenderImage* image = toRenderImage(renderer);
+ if (image->cachedImage() && !image->cachedImage()->errorOccurred())
+ return image->cachedImage();
+
+ return 0;
+}
+
+static void writeImageToDataObject(DataObject* dataObject, Element* element, const KURL& url)
+{
+ // Shove image data into a DataObject for use as a file
+ ImageResource* cachedImage = getImageResource(element);
+ if (!cachedImage || !cachedImage->imageForRenderer(element->renderer()) || !cachedImage->isLoaded())
+ return;
+
+ SharedBuffer* imageBuffer = cachedImage->imageForRenderer(element->renderer())->data();
+ if (!imageBuffer || !imageBuffer->size())
+ return;
+
+ String imageExtension = cachedImage->image()->filenameExtension();
+ ASSERT(!imageExtension.isEmpty());
+
+ // Determine the filename for the file contents of the image.
+ String filename = cachedImage->response().suggestedFilename();
+ if (filename.isEmpty())
+ filename = url.lastPathComponent();
+
+ String fileExtension;
+ if (filename.isEmpty()) {
+ filename = element->getAttribute(HTMLNames::altAttr);
+ } else {
+ // Strip any existing extension. Assume that alt text is usually not a filename.
+ int extensionIndex = filename.reverseFind('.');
+ if (extensionIndex != -1) {
+ fileExtension = filename.substring(extensionIndex + 1);
+ filename.truncate(extensionIndex);
+ }
+ }
+
+ if (!fileExtension.isEmpty() && fileExtension != imageExtension) {
+ String imageMimeType = MIMETypeRegistry::getMIMETypeForExtension(imageExtension);
+ ASSERT(imageMimeType.startsWith("image/"));
+ // Use the file extension only if it has imageMimeType: it's untrustworthy otherwise.
+ if (imageMimeType == MIMETypeRegistry::getMIMETypeForExtension(fileExtension))
+ imageExtension = fileExtension;
+ }
+
+ imageExtension = "." + imageExtension;
+ validateFilename(filename, imageExtension);
+
+ dataObject->addSharedBuffer(filename + imageExtension, imageBuffer);
+}
+
+void Clipboard::declareAndWriteDragImage(Element* element, const KURL& url, const String& title)
+{
+ if (!m_dataObject)
+ return;
+
+ m_dataObject->setURLAndTitle(url, title);
+
+ // Write the bytes in the image to the file format.
+ writeImageToDataObject(m_dataObject.get(), element, url);
+
+ // Put img tag on the clipboard referencing the image
+ m_dataObject->setData(mimeTypeTextHTML, createMarkup(element, IncludeNode, 0, ResolveAllURLs));
+}
+
+void Clipboard::writeURL(const KURL& url, const String& title)
+{
+ if (!m_dataObject)
+ return;
+ ASSERT(!url.isEmpty());
+
+ m_dataObject->setURLAndTitle(url, title);
+
+ // The URL can also be used as plain text.
+ m_dataObject->setData(mimeTypeTextPlain, url.string());
+
+ // The URL can also be used as an HTML fragment.
+ m_dataObject->setHTMLAndBaseURL(urlToMarkup(url, title), url);
+}
+
+void Clipboard::writeRange(Range* selectedRange, LocalFrame* frame)
+{
+ ASSERT(selectedRange);
+ if (!m_dataObject)
+ return;
+
+ m_dataObject->setHTMLAndBaseURL(createMarkup(selectedRange, 0, AnnotateForInterchange, false, ResolveNonLocalURLs), frame->document()->url());
+
+ String str = frame->selectedTextForClipboard();
+#if OS(WIN)
+ replaceNewlinesWithWindowsStyleNewlines(str);
+#endif
+ replaceNBSPWithSpace(str);
+ m_dataObject->setData(mimeTypeTextPlain, str);
+}
+
+void Clipboard::writePlainText(const String& text)
+{
+ if (!m_dataObject)
+ return;
+
+ String str = text;
+#if OS(WIN)
+ replaceNewlinesWithWindowsStyleNewlines(str);
+#endif
+ replaceNBSPWithSpace(str);
+
+ m_dataObject->setData(mimeTypeTextPlain, str);
+}
+
+bool Clipboard::hasData()
+{
+ ASSERT(isForDragAndDrop());
+
+ return m_dataObject->length() > 0;
+}
+
+void Clipboard::setAccessPolicy(ClipboardAccessPolicy policy)
+{
+ // once you go numb, can never go back
+ ASSERT(m_policy != ClipboardNumb || policy == ClipboardNumb);
+ m_policy = policy;
+}
+
+bool Clipboard::canReadTypes() const
+{
+ return m_policy == ClipboardReadable || m_policy == ClipboardTypesReadable || m_policy == ClipboardWritable;
+}
+
+bool Clipboard::canReadData() const
+{
+ return m_policy == ClipboardReadable || m_policy == ClipboardWritable;
+}
+
+bool Clipboard::canWriteData() const
+{
+ return m_policy == ClipboardWritable;
+}
+
+bool Clipboard::canSetDragImage() const
+{
+ return m_policy == ClipboardImageWritable || m_policy == ClipboardWritable;
+}
+
+DragOperation Clipboard::sourceOperation() const
+{
+ DragOperation op = dragOpFromIEOp(m_effectAllowed);
+ ASSERT(op != DragOperationPrivate);
+ return op;
+}
+
+DragOperation Clipboard::destinationOperation() const
+{
+ DragOperation op = dragOpFromIEOp(m_dropEffect);
+ ASSERT(op == DragOperationCopy || op == DragOperationNone || op == DragOperationLink || op == (DragOperation)(DragOperationGeneric | DragOperationMove) || op == DragOperationEvery);
+ return op;
+}
+
+void Clipboard::setSourceOperation(DragOperation op)
+{
+ ASSERT_ARG(op, op != DragOperationPrivate);
+ m_effectAllowed = IEOpFromDragOp(op);
+}
+
+void Clipboard::setDestinationOperation(DragOperation op)
+{
+ ASSERT_ARG(op, op == DragOperationCopy || op == DragOperationNone || op == DragOperationLink || op == DragOperationGeneric || op == DragOperationMove || op == (DragOperation)(DragOperationGeneric | DragOperationMove));
+ m_dropEffect = IEOpFromDragOp(op);
+}
+
+bool Clipboard::hasDropZoneType(const String& keyword)
+{
+ if (keyword.startsWith("file:"))
+ return hasFileOfType(keyword.substring(5));
+
+ if (keyword.startsWith("string:"))
+ return hasStringOfType(keyword.substring(7));
+
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<DataTransferItemList> Clipboard::items()
+{
+ // FIXME: According to the spec, we are supposed to return the same collection of items each
+ // time. We now return a wrapper that always wraps the *same* set of items, so JS shouldn't be
+ // able to tell, but we probably still want to fix this.
+ return DataTransferItemList::create(this, m_dataObject);
+}
+
+PassRefPtrWillBeRawPtr<DataObject> Clipboard::dataObject() const
+{
+ return m_dataObject;
+}
+
+Clipboard::Clipboard(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtrWillBeRawPtr<DataObject> dataObject)
+ : m_policy(policy)
+ , m_dropEffect("uninitialized")
+ , m_effectAllowed("uninitialized")
+ , m_clipboardType(type)
+ , m_dataObject(dataObject)
+{
+ ScriptWrappable::init(this);
+}
+
+void Clipboard::setDragImage(ImageResource* image, Node* node, const IntPoint& loc)
+{
+ if (!canSetDragImage())
+ return;
+
+ m_dragImage = image;
+ m_dragLoc = loc;
+ m_dragImageElement = node;
+}
+
+bool Clipboard::hasFileOfType(const String& type) const
+{
+ if (!canReadTypes())
+ return false;
+
+ RefPtrWillBeRawPtr<FileList> fileList = files();
+ if (fileList->isEmpty())
+ return false;
+
+ for (unsigned f = 0; f < fileList->length(); f++) {
+ if (equalIgnoringCase(fileList->item(f)->type(), type))
+ return true;
+ }
+ return false;
+}
+
+bool Clipboard::hasStringOfType(const String& type) const
+{
+ if (!canReadTypes())
+ return false;
+
+ return types().contains(type);
+}
+
+DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation)
+{
+ if (dragOperation == "copy")
+ return DragOperationCopy;
+ if (dragOperation == "move")
+ return DragOperationMove;
+ if (dragOperation == "link")
+ return DragOperationLink;
+ return DragOperationNone;
+}
+
+String convertDragOperationToDropZoneOperation(DragOperation operation)
+{
+ switch (operation) {
+ case DragOperationCopy:
+ return String("copy");
+ case DragOperationMove:
+ return String("move");
+ case DragOperationLink:
+ return String("link");
+ default:
+ return String("copy");
+ }
+}
+
+void Clipboard::trace(Visitor* visitor)
+{
+ visitor->trace(m_dataObject);
+ visitor->trace(m_dragImageElement);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/Clipboard.h b/chromium/third_party/WebKit/Source/core/clipboard/Clipboard.h
new file mode 100644
index 00000000000..66ed7630b8b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/Clipboard.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
+ * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef Clipboard_h
+#define Clipboard_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/clipboard/ClipboardAccessPolicy.h"
+#include "core/fetch/ResourcePtr.h"
+#include "core/page/DragActions.h"
+#include "platform/geometry/IntPoint.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class DataObject;
+class DataTransferItemList;
+class DragImage;
+class Element;
+class ExceptionState;
+class FileList;
+class LocalFrame;
+class ImageResource;
+class Node;
+class Range;
+
+// State available during IE's events for drag and drop and copy/paste
+class Clipboard : public RefCountedWillBeGarbageCollectedFinalized<Clipboard>, public ScriptWrappable {
+public:
+ // Whether this clipboard is serving a drag-drop or copy-paste request.
+ enum ClipboardType {
+ CopyAndPaste,
+ DragAndDrop,
+ };
+
+ static PassRefPtrWillBeRawPtr<Clipboard> create(ClipboardType, ClipboardAccessPolicy, PassRefPtrWillBeRawPtr<DataObject>);
+ ~Clipboard();
+
+ bool isForCopyAndPaste() const { return m_clipboardType == CopyAndPaste; }
+ bool isForDragAndDrop() const { return m_clipboardType == DragAndDrop; }
+
+ String dropEffect() const { return dropEffectIsUninitialized() ? "none" : m_dropEffect; }
+ void setDropEffect(const String&);
+ bool dropEffectIsUninitialized() const { return m_dropEffect == "uninitialized"; }
+ String effectAllowed() const { return m_effectAllowed; }
+ void setEffectAllowed(const String&);
+
+ void clearData(const String& type = String());
+ String getData(const String& type) const;
+ bool setData(const String& type, const String& data);
+
+ // extensions beyond IE's API
+ Vector<String> types() const;
+ PassRefPtrWillBeRawPtr<FileList> files() const;
+
+ IntPoint dragLocation() const { return m_dragLoc; }
+ void setDragImage(Element*, int x, int y, ExceptionState&);
+ void clearDragImage();
+ ImageResource* dragImageResource() const { return m_dragImage.get(); }
+ void setDragImageResource(ImageResource*, const IntPoint&);
+ Node* dragImageElement() const { return m_dragImageElement.get(); }
+ void setDragImageElement(Node*, const IntPoint&);
+
+ PassOwnPtr<DragImage> createDragImage(IntPoint& dragLocation, LocalFrame*) const;
+ void declareAndWriteDragImage(Element*, const KURL&, const String& title);
+ void writeURL(const KURL&, const String&);
+ void writeRange(Range*, LocalFrame*);
+ void writePlainText(const String&);
+
+ bool hasData();
+
+ void setAccessPolicy(ClipboardAccessPolicy);
+ bool canReadTypes() const;
+ bool canReadData() const;
+ bool canWriteData() const;
+ // Note that the spec doesn't actually allow drag image modification outside the dragstart
+ // event. This capability is maintained for backwards compatiblity for ports that have
+ // supported this in the past. On many ports, attempting to set a drag image outside the
+ // dragstart operation is a no-op anyway.
+ bool canSetDragImage() const;
+
+ DragOperation sourceOperation() const;
+ DragOperation destinationOperation() const;
+ void setSourceOperation(DragOperation);
+ void setDestinationOperation(DragOperation);
+
+ bool hasDropZoneType(const String&);
+
+ PassRefPtrWillBeRawPtr<DataTransferItemList> items();
+
+ PassRefPtrWillBeRawPtr<DataObject> dataObject() const;
+
+ void trace(Visitor*);
+
+private:
+ Clipboard(ClipboardType, ClipboardAccessPolicy, PassRefPtrWillBeRawPtr<DataObject>);
+
+ void setDragImage(ImageResource*, Node*, const IntPoint&);
+
+ bool hasFileOfType(const String&) const;
+ bool hasStringOfType(const String&) const;
+
+ // Instead of using this member directly, prefer to use the can*() methods above.
+ ClipboardAccessPolicy m_policy;
+ String m_dropEffect;
+ String m_effectAllowed;
+ ClipboardType m_clipboardType;
+ RefPtrWillBeMember<DataObject> m_dataObject;
+
+ IntPoint m_dragLoc;
+ ResourcePtr<ImageResource> m_dragImage;
+ RefPtrWillBeMember<Node> m_dragImageElement;
+};
+
+DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation);
+String convertDragOperationToDropZoneOperation(DragOperation);
+
+} // namespace WebCore
+
+#endif // Clipboard_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClipboardAccessPolicy.h b/chromium/third_party/WebKit/Source/core/clipboard/ClipboardAccessPolicy.h
index 969b3f66e95..969b3f66e95 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClipboardAccessPolicy.h
+++ b/chromium/third_party/WebKit/Source/core/clipboard/ClipboardAccessPolicy.h
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataObject.cpp b/chromium/third_party/WebKit/Source/core/clipboard/DataObject.cpp
new file mode 100644
index 00000000000..671af3d4e62
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataObject.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2008, 2009, 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/clipboard/DataObject.h"
+
+#include "core/clipboard/Pasteboard.h"
+#include "platform/clipboard/ClipboardMimeTypes.h"
+#include "platform/clipboard/ClipboardUtilities.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebClipboard.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<DataObject> DataObject::createFromPasteboard(PasteMode pasteMode)
+{
+ RefPtrWillBeRawPtr<DataObject> dataObject = create();
+ blink::WebClipboard::Buffer buffer = Pasteboard::generalPasteboard()->buffer();
+ uint64_t sequenceNumber = blink::Platform::current()->clipboard()->sequenceNumber(buffer);
+ bool ignored;
+ blink::WebVector<blink::WebString> webTypes = blink::Platform::current()->clipboard()->readAvailableTypes(buffer, &ignored);
+ ListHashSet<String> types;
+ for (size_t i = 0; i < webTypes.size(); ++i)
+ types.add(webTypes[i]);
+ for (ListHashSet<String>::const_iterator it = types.begin(); it != types.end(); ++it) {
+ if (pasteMode == PlainTextOnly && *it != mimeTypeTextPlain)
+ continue;
+ dataObject->m_itemList.append(DataObjectItem::createFromPasteboard(*it, sequenceNumber));
+ }
+ return dataObject.release();
+}
+
+PassRefPtrWillBeRawPtr<DataObject> DataObject::create()
+{
+ return adoptRefWillBeNoop(new DataObject());
+}
+
+PassRefPtrWillBeRawPtr<DataObject> DataObject::copy() const
+{
+ return adoptRefWillBeNoop(new DataObject(*this));
+}
+
+DataObject::~DataObject()
+{
+}
+
+size_t DataObject::length() const
+{
+ return m_itemList.size();
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::item(unsigned long index)
+{
+ if (index >= length())
+ return nullptr;
+ return m_itemList[index];
+}
+
+void DataObject::deleteItem(unsigned long index)
+{
+ if (index >= length())
+ return;
+ m_itemList.remove(index);
+}
+
+void DataObject::clearAll()
+{
+ m_itemList.clear();
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::add(const String& data, const String& type)
+{
+ RefPtrWillBeRawPtr<DataObjectItem> item = DataObjectItem::createFromString(type, data);
+ if (!internalAddStringItem(item))
+ return nullptr;
+ return item;
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::add(PassRefPtrWillBeRawPtr<File> file)
+{
+ if (!file)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<DataObjectItem> item = DataObjectItem::createFromFile(file);
+ m_itemList.append(item);
+ return item;
+}
+
+void DataObject::clearData(const String& type)
+{
+ for (size_t i = 0; i < m_itemList.size(); ++i) {
+ if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == type) {
+ // Per the spec, type must be unique among all items of kind 'string'.
+ m_itemList.remove(i);
+ return;
+ }
+ }
+}
+
+ListHashSet<String> DataObject::types() const
+{
+ ListHashSet<String> results;
+ bool containsFiles = false;
+ for (size_t i = 0; i < m_itemList.size(); ++i) {
+ switch (m_itemList[i]->kind()) {
+ case DataObjectItem::StringKind:
+ results.add(m_itemList[i]->type());
+ break;
+ case DataObjectItem::FileKind:
+ containsFiles = true;
+ break;
+ }
+ }
+ if (containsFiles)
+ results.add(mimeTypeFiles);
+ return results;
+}
+
+String DataObject::getData(const String& type) const
+{
+ for (size_t i = 0; i < m_itemList.size(); ++i) {
+ if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == type)
+ return m_itemList[i]->getAsString();
+ }
+ return String();
+}
+
+bool DataObject::setData(const String& type, const String& data)
+{
+ clearData(type);
+ if (!add(data, type))
+ ASSERT_NOT_REACHED();
+ return true;
+}
+
+void DataObject::urlAndTitle(String& url, String* title) const
+{
+ RefPtrWillBeRawPtr<DataObjectItem> item = findStringItem(mimeTypeTextURIList);
+ if (!item)
+ return;
+ url = convertURIListToURL(item->getAsString());
+ if (title)
+ *title = item->title();
+}
+
+void DataObject::setURLAndTitle(const String& url, const String& title)
+{
+ clearData(mimeTypeTextURIList);
+ internalAddStringItem(DataObjectItem::createFromURL(url, title));
+}
+
+void DataObject::htmlAndBaseURL(String& html, KURL& baseURL) const
+{
+ RefPtrWillBeRawPtr<DataObjectItem> item = findStringItem(mimeTypeTextHTML);
+ if (!item)
+ return;
+ html = item->getAsString();
+ baseURL = item->baseURL();
+}
+
+void DataObject::setHTMLAndBaseURL(const String& html, const KURL& baseURL)
+{
+ clearData(mimeTypeTextHTML);
+ internalAddStringItem(DataObjectItem::createFromHTML(html, baseURL));
+}
+
+bool DataObject::containsFilenames() const
+{
+ for (size_t i = 0; i < m_itemList.size(); ++i) {
+ if (m_itemList[i]->isFilename())
+ return true;
+ }
+ return false;
+}
+
+Vector<String> DataObject::filenames() const
+{
+ Vector<String> results;
+ for (size_t i = 0; i < m_itemList.size(); ++i) {
+ if (m_itemList[i]->isFilename())
+ results.append(static_cast<File*>(m_itemList[i]->getAsFile().get())->path());
+ }
+ return results;
+}
+
+void DataObject::addFilename(const String& filename, const String& displayName)
+{
+ internalAddFileItem(DataObjectItem::createFromFile(File::createWithName(filename, displayName, File::AllContentTypes)));
+}
+
+void DataObject::addSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
+{
+ internalAddFileItem(DataObjectItem::createFromSharedBuffer(name, buffer));
+}
+
+DataObject::DataObject()
+ : m_modifierKeyState(0)
+{
+}
+
+DataObject::DataObject(const DataObject& other)
+ : m_itemList(other.m_itemList)
+ , m_modifierKeyState(0)
+{
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::findStringItem(const String& type) const
+{
+ for (size_t i = 0; i < m_itemList.size(); ++i) {
+ if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == type)
+ return m_itemList[i];
+ }
+ return nullptr;
+}
+
+bool DataObject::internalAddStringItem(PassRefPtrWillBeRawPtr<DataObjectItem> item)
+{
+ ASSERT(item->kind() == DataObjectItem::StringKind);
+ for (size_t i = 0; i < m_itemList.size(); ++i) {
+ if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == item->type())
+ return false;
+ }
+
+ m_itemList.append(item);
+ return true;
+}
+
+void DataObject::internalAddFileItem(PassRefPtrWillBeRawPtr<DataObjectItem> item)
+{
+ ASSERT(item->kind() == DataObjectItem::FileKind);
+ m_itemList.append(item);
+}
+
+void DataObject::trace(Visitor* visitor)
+{
+ visitor->trace(m_itemList);
+ WillBeHeapSupplementable<DataObject>::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataObject.h b/chromium/third_party/WebKit/Source/core/clipboard/DataObject.h
new file mode 100644
index 00000000000..6402170e4a4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataObject.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DataObject_h
+#define DataObject_h
+
+#include "core/clipboard/DataObjectItem.h"
+#include "platform/PasteMode.h"
+#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
+#include "wtf/ListHashSet.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/StringHash.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class KURL;
+class SharedBuffer;
+
+// A data object for holding data that would be in a clipboard or moved
+// during a drag-n-drop operation. This is the data that WebCore is aware
+// of and is not specific to a platform.
+class DataObject : public RefCountedWillBeGarbageCollectedFinalized<DataObject>, public WillBeHeapSupplementable<DataObject> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DataObject);
+public:
+ static PassRefPtrWillBeRawPtr<DataObject> createFromPasteboard(PasteMode);
+ static PassRefPtrWillBeRawPtr<DataObject> create();
+
+ PassRefPtrWillBeRawPtr<DataObject> copy() const;
+
+ virtual ~DataObject();
+
+ // DataTransferItemList support.
+ size_t length() const;
+ PassRefPtrWillBeRawPtr<DataObjectItem> item(unsigned long index);
+ // FIXME: Implement V8DataTransferItemList::indexedPropertyDeleter to get this called.
+ void deleteItem(unsigned long index);
+ void clearAll();
+ // Returns null if an item already exists with the provided type.
+ PassRefPtrWillBeRawPtr<DataObjectItem> add(const String& data, const String& type);
+ PassRefPtrWillBeRawPtr<DataObjectItem> add(PassRefPtrWillBeRawPtr<File>);
+
+ // WebCore helpers.
+ void clearData(const String& type);
+
+ ListHashSet<String> types() const;
+ String getData(const String& type) const;
+ bool setData(const String& type, const String& data);
+
+ void urlAndTitle(String& url, String* title = 0) const;
+ void setURLAndTitle(const String& url, const String& title);
+ void htmlAndBaseURL(String& html, KURL& baseURL) const;
+ void setHTMLAndBaseURL(const String& html, const KURL& baseURL);
+
+ // Used for dragging in files from the desktop.
+ bool containsFilenames() const;
+ Vector<String> filenames() const;
+ void addFilename(const String& filename, const String& displayName);
+
+ // Used for dragging in filesystem from the desktop.
+ void setFilesystemId(const String& fileSystemId) { m_filesystemId = fileSystemId; }
+ const String& filesystemId() const { ASSERT(!m_filesystemId.isEmpty()); return m_filesystemId; }
+
+ // Used to handle files (images) being dragged out.
+ void addSharedBuffer(const String& name, PassRefPtr<SharedBuffer>);
+
+ int modifierKeyState() const { return m_modifierKeyState; }
+ void setModifierKeyState(int modifierKeyState) { m_modifierKeyState = modifierKeyState; }
+
+ void trace(Visitor*);
+
+private:
+ DataObject();
+ explicit DataObject(const DataObject&);
+
+ PassRefPtrWillBeRawPtr<DataObjectItem> findStringItem(const String& type) const;
+ bool internalAddStringItem(PassRefPtrWillBeRawPtr<DataObjectItem>);
+ void internalAddFileItem(PassRefPtrWillBeRawPtr<DataObjectItem>);
+
+ WillBeHeapVector<RefPtrWillBeMember<DataObjectItem> > m_itemList;
+
+ // State of Shift/Ctrl/Alt/Meta keys.
+ int m_modifierKeyState;
+ String m_filesystemId;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataObjectItem.cpp b/chromium/third_party/WebKit/Source/core/clipboard/DataObjectItem.cpp
new file mode 100644
index 00000000000..542d0d9c863
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataObjectItem.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/clipboard/DataObjectItem.h"
+
+#include "core/clipboard/Pasteboard.h"
+#include "core/fileapi/Blob.h"
+#include "platform/clipboard/ClipboardMimeTypes.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebClipboard.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromString(const String& type, const String& data)
+{
+ RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, type));
+ item->m_data = data;
+ return item.release();
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromFile(PassRefPtrWillBeRawPtr<File> file)
+{
+ RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(FileKind, file->type()));
+ item->m_file = file;
+ return item.release();
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromURL(const String& url, const String& title)
+{
+ RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, mimeTypeTextURIList));
+ item->m_data = url;
+ item->m_title = title;
+ return item.release();
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromHTML(const String& html, const KURL& baseURL)
+{
+ RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, mimeTypeTextHTML));
+ item->m_data = html;
+ item->m_baseURL = baseURL;
+ return item.release();
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
+{
+ RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(FileKind, String()));
+ item->m_sharedBuffer = buffer;
+ item->m_title = name;
+ return item.release();
+}
+
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromPasteboard(const String& type, uint64_t sequenceNumber)
+{
+ if (type == mimeTypeImagePng)
+ return adoptRefWillBeNoop(new DataObjectItem(FileKind, type, sequenceNumber));
+ return adoptRefWillBeNoop(new DataObjectItem(StringKind, type, sequenceNumber));
+}
+
+DataObjectItem::DataObjectItem(Kind kind, const String& type)
+ : m_source(InternalSource)
+ , m_kind(kind)
+ , m_type(type)
+ , m_sequenceNumber(0)
+{
+}
+
+DataObjectItem::DataObjectItem(Kind kind, const String& type, uint64_t sequenceNumber)
+ : m_source(PasteboardSource)
+ , m_kind(kind)
+ , m_type(type)
+ , m_sequenceNumber(sequenceNumber)
+{
+}
+
+PassRefPtrWillBeRawPtr<Blob> DataObjectItem::getAsFile() const
+{
+ if (kind() != FileKind)
+ return nullptr;
+
+ if (m_source == InternalSource) {
+ if (m_file)
+ return m_file.get();
+ ASSERT(m_sharedBuffer);
+ // FIXME: This code is currently impossible--we never populate m_sharedBuffer when dragging
+ // in. At some point though, we may need to support correctly converting a shared buffer
+ // into a file.
+ return nullptr;
+ }
+
+ ASSERT(m_source == PasteboardSource);
+ if (type() == mimeTypeImagePng) {
+ // FIXME: This is pretty inefficient. We copy the data from the browser
+ // to the renderer. We then place it in a blob in WebKit, which
+ // registers it and copies it *back* to the browser. When a consumer
+ // wants to read the data, we then copy the data back into the renderer.
+ // https://bugs.webkit.org/show_bug.cgi?id=58107 has been filed to track
+ // improvements to this code (in particular, add a registerClipboardBlob
+ // method to the blob registry; that way the data is only copied over
+ // into the renderer when it's actually read, not when the blob is
+ // initially constructed).
+ RefPtr<SharedBuffer> data = static_cast<PassRefPtr<SharedBuffer> >(blink::Platform::current()->clipboard()->readImage(blink::WebClipboard::BufferStandard));
+ RefPtr<RawData> rawData = RawData::create();
+ rawData->mutableData()->append(data->data(), data->size());
+ OwnPtr<BlobData> blobData = BlobData::create();
+ blobData->appendData(rawData, 0, -1);
+ blobData->setContentType(mimeTypeImagePng);
+ return Blob::create(BlobDataHandle::create(blobData.release(), data->size()));
+ }
+
+ return nullptr;
+}
+
+String DataObjectItem::getAsString() const
+{
+ ASSERT(m_kind == StringKind);
+
+ if (m_source == InternalSource)
+ return m_data;
+
+ ASSERT(m_source == PasteboardSource);
+
+ blink::WebClipboard::Buffer buffer = Pasteboard::generalPasteboard()->buffer();
+ String data;
+ // This is ugly but there's no real alternative.
+ if (m_type == mimeTypeTextPlain) {
+ data = blink::Platform::current()->clipboard()->readPlainText(buffer);
+ } else if (m_type == mimeTypeTextHTML) {
+ blink::WebURL ignoredSourceURL;
+ unsigned ignored;
+ data = blink::Platform::current()->clipboard()->readHTML(buffer, &ignoredSourceURL, &ignored, &ignored);
+ } else {
+ data = blink::Platform::current()->clipboard()->readCustomData(buffer, m_type);
+ }
+
+ return blink::Platform::current()->clipboard()->sequenceNumber(buffer) == m_sequenceNumber ? data : String();
+}
+
+bool DataObjectItem::isFilename() const
+{
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=81261: When we properly support File dragout,
+ // we'll need to make sure this works as expected for DragDataChromium.
+ return m_kind == FileKind && m_file;
+}
+
+void DataObjectItem::trace(Visitor* visitor)
+{
+ visitor->trace(m_file);
+}
+
+} // namespace WebCore
+
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataObjectItem.h b/chromium/third_party/WebKit/Source/core/clipboard/DataObjectItem.h
new file mode 100644
index 00000000000..e4ce5eb2b8d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataObjectItem.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DataObjectItem_h
+#define DataObjectItem_h
+
+#include "core/fileapi/File.h"
+#include "platform/SharedBuffer.h"
+#include "platform/heap/Handle.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class Blob;
+
+class DataObjectItem : public RefCountedWillBeGarbageCollectedFinalized<DataObjectItem> {
+public:
+ enum Kind {
+ StringKind,
+ FileKind
+ };
+
+ static PassRefPtrWillBeRawPtr<DataObjectItem> createFromString(const String& type, const String& data);
+ static PassRefPtrWillBeRawPtr<DataObjectItem> createFromFile(PassRefPtrWillBeRawPtr<File>);
+ static PassRefPtrWillBeRawPtr<DataObjectItem> createFromURL(const String& url, const String& title);
+ static PassRefPtrWillBeRawPtr<DataObjectItem> createFromHTML(const String& html, const KURL& baseURL);
+ static PassRefPtrWillBeRawPtr<DataObjectItem> createFromSharedBuffer(const String& filename, PassRefPtr<SharedBuffer>);
+ static PassRefPtrWillBeRawPtr<DataObjectItem> createFromPasteboard(const String& type, uint64_t sequenceNumber);
+
+ Kind kind() const { return m_kind; }
+ String type() const { return m_type; }
+ String getAsString() const;
+ PassRefPtrWillBeRawPtr<Blob> getAsFile() const;
+
+ // Used to support legacy DataTransfer APIs and renderer->browser serialization.
+ PassRefPtr<SharedBuffer> sharedBuffer() const { return m_sharedBuffer; }
+ String title() const { return m_title; }
+ KURL baseURL() const { return m_baseURL; }
+ bool isFilename() const;
+
+ void trace(Visitor*);
+
+private:
+ enum DataSource {
+ PasteboardSource,
+ InternalSource,
+ };
+
+ DataObjectItem(Kind, const String& type);
+ DataObjectItem(Kind, const String& type, uint64_t sequenceNumber);
+
+ DataSource m_source;
+ Kind m_kind;
+ String m_type;
+
+ String m_data;
+ RefPtrWillBeMember<File> m_file;
+ RefPtr<SharedBuffer> m_sharedBuffer;
+ // Optional metadata. Currently used for URL, HTML, and dragging files in.
+ String m_title;
+ KURL m_baseURL;
+
+ uint64_t m_sequenceNumber; // Only valid when m_source == PasteboardSource
+};
+
+} // namespace WebCore
+
+#endif // DataObjectItem_h
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataTransfer.idl b/chromium/third_party/WebKit/Source/core/clipboard/DataTransfer.idl
new file mode 100644
index 00000000000..497bfdf2c58
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataTransfer.idl
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ ImplementedAs=Clipboard,
+ WillBeGarbageCollected
+] interface DataTransfer {
+ [TreatReturnedNullStringAs=Undefined] attribute DOMString dropEffect;
+ [TreatReturnedNullStringAs=Undefined] attribute DOMString effectAllowed;
+ readonly attribute DOMString[] types;
+ readonly attribute FileList files;
+
+ void clearData(optional DOMString type);
+ DOMString getData(DOMString type);
+ boolean setData(DOMString type, DOMString data);
+ [RaisesException] void setDragImage(Element image, long x, long y);
+
+ readonly attribute DataTransferItemList items;
+};
+
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp
new file mode 100644
index 00000000000..392feaf2b76
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/clipboard/DataTransferItem.h"
+
+#include "bindings/v8/V8Binding.h"
+#include "core/clipboard/Clipboard.h"
+#include "core/clipboard/DataObjectItem.h"
+#include "core/dom/StringCallback.h"
+#include "wtf/StdLibExtras.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<DataTransferItem> DataTransferItem::create(PassRefPtrWillBeRawPtr<Clipboard> clipboard, PassRefPtrWillBeRawPtr<DataObjectItem> item)
+{
+ return adoptRefWillBeNoop(new DataTransferItem(clipboard, item));
+}
+
+DataTransferItem::~DataTransferItem()
+{
+}
+
+String DataTransferItem::kind() const
+{
+ DEFINE_STATIC_LOCAL(const String, kindString, ("string"));
+ DEFINE_STATIC_LOCAL(const String, kindFile, ("file"));
+ if (!m_clipboard->canReadTypes())
+ return String();
+ switch (m_item->kind()) {
+ case DataObjectItem::StringKind:
+ return kindString;
+ case DataObjectItem::FileKind:
+ return kindFile;
+ }
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+String DataTransferItem::type() const
+{
+ if (!m_clipboard->canReadTypes())
+ return String();
+ return m_item->type();
+}
+
+void DataTransferItem::getAsString(ExecutionContext* context, PassOwnPtr<StringCallback> callback) const
+{
+ if (!m_clipboard->canReadData())
+ return;
+ if (!callback || m_item->kind() != DataObjectItem::StringKind)
+ return;
+
+ StringCallback::scheduleCallback(callback, context, m_item->getAsString());
+}
+
+PassRefPtrWillBeRawPtr<Blob> DataTransferItem::getAsFile() const
+{
+ if (!m_clipboard->canReadData())
+ return nullptr;
+
+ return m_item->getAsFile();
+}
+
+DataTransferItem::DataTransferItem(PassRefPtrWillBeRawPtr<Clipboard> clipboard, PassRefPtrWillBeRawPtr<DataObjectItem> item)
+ : m_clipboard(clipboard)
+ , m_item(item)
+{
+ ScriptWrappable::init(this);
+}
+
+void DataTransferItem::trace(Visitor* visitor)
+{
+ visitor->trace(m_clipboard);
+ visitor->trace(m_item);
+}
+
+} // namespace WebCore
+
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.h b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.h
new file mode 100644
index 00000000000..e43013ba642
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DataTransferItem_h
+#define DataTransferItem_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class Blob;
+class DataObjectItem;
+class Clipboard;
+class File;
+class StringCallback;
+class ExecutionContext;
+
+class DataTransferItem : public RefCountedWillBeGarbageCollectedFinalized<DataTransferItem>, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<DataTransferItem> create(PassRefPtrWillBeRawPtr<Clipboard>, PassRefPtrWillBeRawPtr<DataObjectItem>);
+ ~DataTransferItem();
+
+ String kind() const;
+ String type() const;
+
+ void getAsString(ExecutionContext*, PassOwnPtr<StringCallback>) const;
+ PassRefPtrWillBeRawPtr<Blob> getAsFile() const;
+
+ Clipboard* clipboard() { return m_clipboard.get(); }
+ DataObjectItem* dataObjectItem() { return m_item.get(); }
+
+ void trace(Visitor*);
+
+private:
+ DataTransferItem(PassRefPtrWillBeRawPtr<Clipboard>, PassRefPtrWillBeRawPtr<DataObjectItem>);
+
+ RefPtrWillBeMember<Clipboard> m_clipboard;
+ RefPtrWillBeMember<DataObjectItem> m_item;
+};
+
+} // namespace WebCore
+
+#endif // DataTransferItem_h
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.idl b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.idl
new file mode 100644
index 00000000000..32e69045344
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItem.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+ WillBeGarbageCollected,
+ NoInterfaceObject
+] interface DataTransferItem {
+ readonly attribute DOMString kind;
+ readonly attribute DOMString type;
+
+ [CallWith=ExecutionContext] void getAsString(StringCallback? callback);
+ Blob getAsFile();
+};
+
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp
new file mode 100644
index 00000000000..3785f9902a3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/clipboard/DataTransferItemList.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/clipboard/Clipboard.h"
+#include "core/clipboard/DataObject.h"
+#include "core/clipboard/DataTransferItem.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<DataTransferItemList> DataTransferItemList::create(PassRefPtrWillBeRawPtr<Clipboard> clipboard, PassRefPtrWillBeRawPtr<DataObject> list)
+{
+ return adoptRefWillBeNoop(new DataTransferItemList(clipboard, list));
+}
+
+DataTransferItemList::~DataTransferItemList()
+{
+}
+
+size_t DataTransferItemList::length() const
+{
+ if (!m_clipboard->canReadTypes())
+ return 0;
+ return m_dataObject->length();
+}
+
+PassRefPtrWillBeRawPtr<DataTransferItem> DataTransferItemList::item(unsigned long index)
+{
+ if (!m_clipboard->canReadTypes())
+ return nullptr;
+ RefPtrWillBeRawPtr<DataObjectItem> item = m_dataObject->item(index);
+ if (!item)
+ return nullptr;
+
+ return DataTransferItem::create(m_clipboard, item);
+}
+
+void DataTransferItemList::deleteItem(unsigned long index, ExceptionState& exceptionState)
+{
+ if (!m_clipboard->canWriteData()) {
+ exceptionState.throwDOMException(InvalidStateError, "The list is not writable.");
+ return;
+ }
+ m_dataObject->deleteItem(index);
+}
+
+void DataTransferItemList::clear()
+{
+ if (!m_clipboard->canWriteData())
+ return;
+ m_dataObject->clearAll();
+}
+
+PassRefPtrWillBeRawPtr<DataTransferItem> DataTransferItemList::add(const String& data, const String& type, ExceptionState& exceptionState)
+{
+ if (!m_clipboard->canWriteData())
+ return nullptr;
+ RefPtrWillBeRawPtr<DataObjectItem> item = m_dataObject->add(data, type);
+ if (!item) {
+ exceptionState.throwDOMException(NotSupportedError, "An item already exists for type '" + type + "'.");
+ return nullptr;
+ }
+ return DataTransferItem::create(m_clipboard, item);
+}
+
+PassRefPtrWillBeRawPtr<DataTransferItem> DataTransferItemList::add(PassRefPtrWillBeRawPtr<File> file)
+{
+ if (!m_clipboard->canWriteData())
+ return nullptr;
+ RefPtrWillBeRawPtr<DataObjectItem> item = m_dataObject->add(file);
+ if (!item)
+ return nullptr;
+ return DataTransferItem::create(m_clipboard, item);
+}
+
+DataTransferItemList::DataTransferItemList(PassRefPtrWillBeRawPtr<Clipboard> clipboard, PassRefPtrWillBeRawPtr<DataObject> dataObject)
+ : m_clipboard(clipboard)
+ , m_dataObject(dataObject)
+{
+ ScriptWrappable::init(this);
+}
+
+void DataTransferItemList::trace(Visitor* visitor)
+{
+ visitor->trace(m_clipboard);
+ visitor->trace(m_dataObject);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.h b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.h
new file mode 100644
index 00000000000..53355ae8e8a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DataTransferItemList_h
+#define DataTransferItemList_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class DataObject;
+class Clipboard;
+class DataTransferItem;
+class File;
+
+class ExceptionState;
+
+class DataTransferItemList : public RefCountedWillBeGarbageCollectedFinalized<DataTransferItemList>, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<DataTransferItemList> create(PassRefPtrWillBeRawPtr<Clipboard>, PassRefPtrWillBeRawPtr<DataObject>);
+ ~DataTransferItemList();
+
+ size_t length() const;
+ PassRefPtrWillBeRawPtr<DataTransferItem> item(unsigned long index);
+ void deleteItem(unsigned long index, ExceptionState&);
+ void clear();
+ PassRefPtrWillBeRawPtr<DataTransferItem> add(const String& data, const String& type, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DataTransferItem> add(PassRefPtrWillBeRawPtr<File>);
+
+ void trace(Visitor*);
+
+private:
+ DataTransferItemList(PassRefPtrWillBeRawPtr<Clipboard>, PassRefPtrWillBeRawPtr<DataObject>);
+
+ RefPtrWillBeMember<Clipboard> m_clipboard;
+ RefPtrWillBeMember<DataObject> m_dataObject;
+};
+
+} // namespace WebCore
+
+#endif // DataTransferItemList_h
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.idl b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.idl
new file mode 100644
index 00000000000..7bdf22c9cf8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/DataTransferItemList.idl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#datatransferitemlist
+
+[
+ TypeChecking=Interface,
+ WillBeGarbageCollected,
+] interface DataTransferItemList {
+ readonly attribute long length;
+ [ImplementedAs=item] getter DataTransferItem (unsigned long index);
+
+ [RaisesException] DataTransferItem add(DOMString data, DOMString type);
+ DataTransferItem add(File? file);
+ [RaisesException, ImplementedAs=deleteItem] void remove(unsigned long index);
+ void clear();
+};
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/Pasteboard.cpp b/chromium/third_party/WebKit/Source/core/clipboard/Pasteboard.cpp
new file mode 100644
index 00000000000..4c38345adb0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/Pasteboard.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/clipboard/Pasteboard.h"
+
+#include "core/clipboard/DataObject.h"
+#include "platform/clipboard/ClipboardUtilities.h"
+#include "platform/graphics/Image.h"
+#include "platform/graphics/skia/NativeImageSkia.h"
+#include "platform/weborigin/KURL.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebDragData.h"
+#include "public/platform/WebString.h"
+#include "public/platform/WebURL.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+Pasteboard* Pasteboard::generalPasteboard()
+{
+ static Pasteboard* pasteboard = new Pasteboard;
+ return pasteboard;
+}
+
+Pasteboard::Pasteboard()
+ : m_buffer(blink::WebClipboard::BufferStandard)
+{
+}
+
+bool Pasteboard::isSelectionMode() const
+{
+ return m_buffer == blink::WebClipboard::BufferSelection;
+}
+
+void Pasteboard::setSelectionMode(bool selectionMode)
+{
+ m_buffer = selectionMode ? blink::WebClipboard::BufferSelection : blink::WebClipboard::BufferStandard;
+}
+
+void Pasteboard::writePlainText(const String& text, SmartReplaceOption)
+{
+ // FIXME: add support for smart replace
+#if OS(WIN)
+ String plainText(text);
+ replaceNewlinesWithWindowsStyleNewlines(plainText);
+ blink::Platform::current()->clipboard()->writePlainText(plainText);
+#else
+ blink::Platform::current()->clipboard()->writePlainText(text);
+#endif
+}
+
+void Pasteboard::writeImage(Image* image, const KURL& url, const String& title)
+{
+ ASSERT(image);
+
+ RefPtr<NativeImageSkia> bitmap = image->nativeImageForCurrentFrame();
+ if (!bitmap)
+ return;
+
+ blink::WebImage webImage = bitmap->bitmap();
+ blink::Platform::current()->clipboard()->writeImage(webImage, blink::WebURL(url), blink::WebString(title));
+}
+
+void Pasteboard::writeDataObject(PassRefPtrWillBeRawPtr<DataObject> dataObject)
+{
+ blink::Platform::current()->clipboard()->writeDataObject(blink::WebDragData(dataObject));
+}
+
+bool Pasteboard::canSmartReplace()
+{
+ return blink::Platform::current()->clipboard()->isFormatAvailable(blink::WebClipboard::FormatSmartPaste, m_buffer);
+}
+
+bool Pasteboard::isHTMLAvailable()
+{
+ return blink::Platform::current()->clipboard()->isFormatAvailable(blink::WebClipboard::FormatHTML, m_buffer);
+}
+
+String Pasteboard::plainText()
+{
+ return blink::Platform::current()->clipboard()->readPlainText(m_buffer);
+}
+
+String Pasteboard::readHTML(KURL& url, unsigned& fragmentStart, unsigned& fragmentEnd)
+{
+ blink::WebURL webURL;
+ blink::WebString markup = blink::Platform::current()->clipboard()->readHTML(m_buffer, &webURL, &fragmentStart, &fragmentEnd);
+ if (!markup.isEmpty()) {
+ url = webURL;
+ // fragmentStart and fragmentEnd are populated by WebClipboard::readHTML.
+ } else {
+ url = KURL();
+ fragmentStart = 0;
+ fragmentEnd = 0;
+ }
+ return markup;
+}
+
+void Pasteboard::writeHTML(const String& markup, const KURL& documentURL, const String& plainText, bool canSmartCopyOrDelete)
+{
+ String text = plainText;
+#if OS(WIN)
+ replaceNewlinesWithWindowsStyleNewlines(text);
+#endif
+ replaceNBSPWithSpace(text);
+
+ blink::Platform::current()->clipboard()->writeHTML(markup, documentURL, text, canSmartCopyOrDelete);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/clipboard/Pasteboard.h b/chromium/third_party/WebKit/Source/core/clipboard/Pasteboard.h
new file mode 100644
index 00000000000..fb430848fd3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/clipboard/Pasteboard.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Pasteboard_h
+#define Pasteboard_h
+
+#include "platform/heap/Handle.h"
+#include "public/platform/WebClipboard.h"
+#include "wtf/Forward.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class DataObject;
+class Image;
+class KURL;
+
+class Pasteboard {
+ WTF_MAKE_NONCOPYABLE(Pasteboard); WTF_MAKE_FAST_ALLOCATED;
+public:
+ enum SmartReplaceOption {
+ CanSmartReplace,
+ CannotSmartReplace
+ };
+
+ static Pasteboard* generalPasteboard();
+ void writePlainText(const String&, SmartReplaceOption);
+ void writeImage(Image*, const KURL&, const String& title);
+ void writeDataObject(PassRefPtrWillBeRawPtr<DataObject>);
+ bool canSmartReplace();
+ bool isHTMLAvailable();
+ String plainText();
+
+ // If no data is read, an empty string will be returned and all out parameters will be cleared.
+ // If applicable, the page URL will be assigned to the KURL parameter.
+ // fragmentStart and fragmentEnd are indexes into the returned markup that indicate
+ // the start and end of the returned markup. If there is no additional context,
+ // fragmentStart will be zero and fragmentEnd will be the same as the length of the markup.
+ String readHTML(KURL&, unsigned& fragmentStart, unsigned& fragmentEnd);
+
+ void writeHTML(const String& markup, const KURL& documentURL, const String& plainText, bool canSmartCopyOrDelete);
+
+ bool isSelectionMode() const;
+ void setSelectionMode(bool);
+
+ blink::WebClipboard::Buffer buffer() const { return m_buffer; }
+
+private:
+ Pasteboard();
+
+ blink::WebClipboard::Buffer m_buffer;
+};
+
+} // namespace WebCore
+
+#endif // Pasteboard_h
diff --git a/chromium/third_party/WebKit/Source/core/core.gni b/chromium/third_party/WebKit/Source/core/core.gni
new file mode 100644
index 00000000000..fd55894b204
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/core.gni
@@ -0,0 +1,37 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+blink_core_output_dir = "$root_gen_dir/blink/core"
+
+# This file is the GN version of core.gypi. We rebase most paths to be absolute
+# so these lists can be used by BUILD files in different directories without
+# worrying about the base directory.
+_gypi = exec_script(
+ "//build/gypi_to_gn.py",
+ [ rebase_path("core.gypi"),
+ "--replace=<(SHARED_INTERMEDIATE_DIR)=$root_gen_dir",
+ "--replace=<(blink_core_output_dir)=$blink_core_output_dir"],
+ "scope",
+ [ "core.gypi" ])
+
+# Files for which bindings (.cpp and .h files) will be generated.
+core_idl_files = get_path_info(_gypi.core_idl_files, "abspath")
+
+# 'partial interface', target (right side of) 'implements', and
+# interfaces with static bindings (in bindings/v8/)
+core_dependency_idl_files =
+ get_path_info(_gypi.core_dependency_idl_files, "abspath")
+
+# Interfaces that inherit from Event, including Event itself.
+core_event_idl_files = get_path_info(_gypi.core_event_idl_files, "abspath")
+
+webcore_files = get_path_info(_gypi.webcore_files, "abspath")
+webcore_dom_files = get_path_info(_gypi.webcore_dom_files, "abspath")
+webcore_html_files = get_path_info(_gypi.webcore_html_files, "abspath")
+webcore_svg_files = get_path_info(_gypi.webcore_svg_files, "abspath")
+webcore_testing_idl_files = get_path_info(_gypi.webcore_testing_idl_files, "abspath")
+generated_webcore_testing_idl_files =
+ get_path_info(_gypi.generated_webcore_testing_idl_files, "abspath")
+webcore_testing_files = get_path_info(_gypi.webcore_testing_files, "abspath")
+core_unittest_files = get_path_info(_gypi.core_unittest_files, "abspath")
diff --git a/chromium/third_party/WebKit/Source/core/core.gyp b/chromium/third_party/WebKit/Source/core/core.gyp
index 882565dec88..032d6250a9b 100644
--- a/chromium/third_party/WebKit/Source/core/core.gyp
+++ b/chromium/third_party/WebKit/Source/core/core.gyp
@@ -33,19 +33,25 @@
'../build/win/precompile.gypi',
'../build/features.gypi',
'../build/scripts/scripts.gypi',
- '../modules/modules.gypi',
- '../bindings/bindings.gypi',
+ '../bindings/core/core.gypi', # core can depend on bindings/core, but not on bindings
'core.gypi',
+ '../modules/modules_generated.gypi', # FIXME: Required by <(blink_modules_output_dir) below.
+ '../platform/platform_generated.gypi', # FIXME: Required by <(blink_platform_output_dir) below.
],
'variables': {
'enable_wexit_time_destructors': 1,
'webcore_include_dirs': [
- '../..',
- '..',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings',
+ '..', # WebKit/Source
+ # FIXME: Remove these once core scripts generate qualified
+ # includes correctly: http://crbug.com/380054
+ '<(blink_core_output_dir)',
+ '<(blink_modules_output_dir)',
+ '<(bindings_core_v8_output_dir)',
+ '<(bindings_modules_v8_output_dir)',
+ # Needed to include the generated binding headers.
+ '<(SHARED_INTERMEDIATE_DIR)/blink', # gen/blink
],
'conditions': [
@@ -65,6 +71,7 @@
'targets': [
{
+ # GN version: //third_party/WebKit/Source/core/inspector:protocol_sources
'target_name': 'inspector_protocol_sources',
'type': 'none',
'dependencies': [
@@ -82,12 +89,12 @@
'../devtools/protocol.json',
],
'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorBackendDispatcher.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorBackendDispatcher.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorFrontend.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorFrontend.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorTypeBuilder.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorTypeBuilder.h',
+ '<(blink_core_output_dir)/InspectorBackendDispatcher.cpp',
+ '<(blink_core_output_dir)/InspectorBackendDispatcher.h',
+ '<(blink_core_output_dir)/InspectorFrontend.cpp',
+ '<(blink_core_output_dir)/InspectorFrontend.h',
+ '<(blink_core_output_dir)/InspectorTypeBuilder.cpp',
+ '<(blink_core_output_dir)/InspectorTypeBuilder.h',
],
'variables': {
'generator_include_dirs': [
@@ -97,14 +104,14 @@
'python',
'inspector/CodeGeneratorInspector.py',
'../devtools/protocol.json',
- '--output_dir', '<(SHARED_INTERMEDIATE_DIR)/blink',
+ '--output_dir', '<(blink_core_output_dir)',
],
'message': 'Generating Inspector protocol backend sources from protocol.json',
- 'msvs_cygwin_shell': 1,
},
]
},
{
+ # GN version: //third_party/WebKit/Source/core/inspector:instrumentation_sources
'target_name': 'inspector_instrumentation_sources',
'type': 'none',
'dependencies': [],
@@ -118,26 +125,25 @@
'inspector/InspectorInstrumentation.idl',
],
'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorCanvasInstrumentationInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorConsoleInstrumentationInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorDatabaseInstrumentationInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorInstrumentationInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorOverridesInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InstrumentingAgentsInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorInstrumentationImpl.cpp',
+ '<(blink_core_output_dir)/InspectorCanvasInstrumentationInl.h',
+ '<(blink_core_output_dir)/InspectorConsoleInstrumentationInl.h',
+ '<(blink_core_output_dir)/InspectorInstrumentationInl.h',
+ '<(blink_core_output_dir)/InspectorOverridesInl.h',
+ '<(blink_core_output_dir)/InstrumentingAgentsInl.h',
+ '<(blink_core_output_dir)/InspectorInstrumentationImpl.cpp',
],
'action': [
'python',
'inspector/CodeGeneratorInstrumentation.py',
'inspector/InspectorInstrumentation.idl',
- '--output_dir', '<(SHARED_INTERMEDIATE_DIR)/blink',
+ '--output_dir', '<(blink_core_output_dir)',
],
'message': 'Generating Inspector instrumentation code from InspectorInstrumentation.idl',
- 'msvs_cygwin_shell': 1,
}
]
},
{
+ # GN version: //third_party/WebKit/Source/core/inspector:protocol_version
'target_name': 'generate_inspector_protocol_version',
'type': 'none',
'actions': [
@@ -148,7 +154,7 @@
'../devtools/protocol.json',
],
'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorProtocolVersion.h',
+ '<(blink_core_output_dir)/InspectorProtocolVersion.h',
],
'variables': {
'generator_include_dirs': [
@@ -166,60 +172,68 @@
]
},
{
+ # GN version: //third_party/WebKit/Source/core/inspector:inspector_overlay_page
'target_name': 'inspector_overlay_page',
'type': 'none',
'variables': {
'input_file_path': 'inspector/InspectorOverlayPage.html',
- 'output_file_path': '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorOverlayPage.h',
+ 'output_file_path': '<(blink_core_output_dir)/InspectorOverlayPage.h',
'character_array_name': 'InspectorOverlayPage_html',
},
'includes': [ '../build/ConvertFileToHeaderWithCharacterArray.gypi' ],
},
{
+ # GN version: //third_party/WebKit/Source/core/inspector:injected_canvas_script_source
'target_name': 'injected_canvas_script_source',
'type': 'none',
'variables': {
'input_file_path': 'inspector/InjectedScriptCanvasModuleSource.js',
- 'output_file_path': '<(SHARED_INTERMEDIATE_DIR)/blink/InjectedScriptCanvasModuleSource.h',
+ 'output_file_path': '<(blink_core_output_dir)/InjectedScriptCanvasModuleSource.h',
'character_array_name': 'InjectedScriptCanvasModuleSource_js',
},
'includes': [ '../build/ConvertFileToHeaderWithCharacterArray.gypi' ],
},
{
+ # GN version: //third_party/WebKit/Source/core/inspector:injected_script_source
'target_name': 'injected_script_source',
'type': 'none',
'variables': {
'input_file_path': 'inspector/InjectedScriptSource.js',
- 'output_file_path': '<(SHARED_INTERMEDIATE_DIR)/blink/InjectedScriptSource.h',
+ 'output_file_path': '<(blink_core_output_dir)/InjectedScriptSource.h',
'character_array_name': 'InjectedScriptSource_js',
},
'includes': [ '../build/ConvertFileToHeaderWithCharacterArray.gypi' ],
},
{
+ # GN version: //third_party/WebKit/Source/core/inspector:debugger_script_source
'target_name': 'debugger_script_source',
'type': 'none',
'variables': {
- 'input_file_path': '<(bindings_dir)/v8/DebuggerScript.js',
- 'output_file_path': '<(SHARED_INTERMEDIATE_DIR)/blink/DebuggerScriptSource.h',
+ 'input_file_path': '<(bindings_v8_dir)/DebuggerScript.js',
+ 'output_file_path': '<(blink_core_output_dir)/DebuggerScriptSource.h',
'character_array_name': 'DebuggerScriptSource_js',
},
'includes': [ '../build/ConvertFileToHeaderWithCharacterArray.gypi' ],
},
{
- 'target_name': 'webcore_derived',
+ # GN version: //third_party/WebKit/Source/core:core_generated
+ 'target_name': 'webcore_generated',
'type': 'static_library',
'hard_dependency': 1,
'dependencies': [
'webcore_prerequisites',
- '../bindings/derived_sources.gyp:bindings_derived_sources',
- 'core_derived_sources.gyp:make_core_derived_sources',
+ 'core_generated.gyp:make_core_generated',
'inspector_overlay_page',
'inspector_protocol_sources',
'inspector_instrumentation_sources',
'injected_canvas_script_source',
'injected_script_source',
'debugger_script_source',
- '../platform/platform_derived_sources.gyp:make_platform_derived_sources',
+ '../bindings/core/v8/generated.gyp:bindings_core_v8_generated',
+ # FIXME: don't depend on bindings_modules http://crbug.com/358074
+ '../bindings/modules/generated.gyp:modules_event_generated',
+ '../bindings/modules/v8/generated.gyp:bindings_modules_v8_generated',
+ '../platform/platform_generated.gyp:make_platform_generated',
'../wtf/wtf.gyp:wtf',
'<(DEPTH)/gin/gin.gyp:gin',
'<(DEPTH)/skia/skia.gyp:skia',
@@ -235,95 +249,92 @@
'<(DEPTH)/v8/tools/gyp/v8.gyp:v8',
],
'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings',
'<@(webcore_include_dirs)',
-
- # FIXME: Remove these once the bindings script generates qualified
- # includes for these correctly. (Sequences don't work yet.)
- '<(bindings_dir)/v8/custom',
- 'html',
- 'html/shadow',
- 'inspector',
- 'svg',
],
'sources': [
+ # FIXME: should be bindings_core_v8_files http://crbug.com/358074
+ '<@(bindings_v8_files)',
# These files include all the .cpp files generated from the .idl files
# in webcore_files.
- '<@(derived_sources_aggregate_files)',
- '<@(bindings_files)',
+ '<@(bindings_core_v8_generated_aggregate_files)',
# Additional .cpp files for HashTools.h
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSPropertyNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSValueKeywords.cpp',
+ '<(blink_core_output_dir)/CSSPropertyNames.cpp',
+ '<(blink_core_output_dir)/CSSValueKeywords.cpp',
- # Additional .cpp files from make_core_derived_sources actions.
- '<(SHARED_INTERMEDIATE_DIR)/blink/Event.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventHeaders.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventNames.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTargetHeaders.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTargetInterfaces.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTargetNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTargetNames.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTypeNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTypeNames.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/FetchInitiatorTypeNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementFactory.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementFactory.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementLookupTrie.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementLookupTrie.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InputTypeNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/MathMLNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/SVGNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/UserAgentStyleSheetsData.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/V8HTMLElementWrapperFactory.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/XLinkNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/XMLNSNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/XMLNames.cpp',
+ # Additional .cpp files from make_core_generated actions.
+ '<(blink_core_output_dir)/Event.cpp',
+ '<(blink_core_output_dir)/EventHeaders.h',
+ '<(blink_core_output_dir)/EventInterfaces.h',
+ '<(blink_core_output_dir)/EventNames.cpp',
+ '<(blink_core_output_dir)/EventNames.h',
+ '<(blink_core_output_dir)/EventTargetHeaders.h',
+ '<(blink_core_output_dir)/EventTargetInterfaces.h',
+ '<(blink_core_output_dir)/EventTargetNames.cpp',
+ '<(blink_core_output_dir)/EventTargetNames.h',
+ '<(blink_core_output_dir)/EventTypeNames.cpp',
+ '<(blink_core_output_dir)/EventTypeNames.h',
+ '<(blink_core_output_dir)/FetchInitiatorTypeNames.cpp',
+ '<(blink_core_output_dir)/HTMLElementFactory.cpp',
+ '<(blink_core_output_dir)/HTMLElementFactory.h',
+ '<(blink_core_output_dir)/HTMLElementLookupTrie.cpp',
+ '<(blink_core_output_dir)/HTMLElementLookupTrie.h',
+ '<(blink_core_output_dir)/HTMLNames.cpp',
+ '<(blink_core_output_dir)/HTMLTokenizerNames.cpp',
+ '<(blink_core_output_dir)/InputTypeNames.cpp',
+ '<(blink_core_output_dir)/MathMLNames.cpp',
+ '<(blink_core_output_dir)/SVGNames.cpp',
+ '<(blink_core_output_dir)/UserAgentStyleSheetsData.cpp',
+ '<(blink_core_output_dir)/V8HTMLElementWrapperFactory.cpp',
+ '<(blink_core_output_dir)/XLinkNames.cpp',
+ '<(blink_core_output_dir)/XMLNSNames.cpp',
+ '<(blink_core_output_dir)/XMLNames.cpp',
# Generated from HTMLEntityNames.in
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLEntityTable.cpp',
+ '<(blink_core_output_dir)/HTMLEntityTable.cpp',
+
+ # Generated from MediaFeatureNames.in
+ '<(blink_core_output_dir)/MediaFeatureNames.cpp',
+
+ # Generated from MediaTypeNames.in
+ '<(blink_core_output_dir)/MediaTypeNames.cpp',
# Generated from CSSTokenizer-in.cpp
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSTokenizer.cpp',
+ '<(blink_core_output_dir)/CSSTokenizer.cpp',
- # Generated from CSSParser-in.cpp
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSParser.cpp',
+ # Generated from BisonCSSParser-in.cpp
+ '<(blink_core_output_dir)/BisonCSSParser.cpp',
# Generated from HTMLMetaElement-in.cpp
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLMetaElement.cpp',
+ '<(blink_core_output_dir)/HTMLMetaElement.cpp',
- # Additional .cpp files from the make_core_derived_sources rules.
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSGrammar.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/XPathGrammar.cpp',
+ # Additional .cpp files from the make_core_generated rules.
+ '<(blink_core_output_dir)/CSSGrammar.cpp',
+ '<(blink_core_output_dir)/XPathGrammar.cpp',
# Additional .cpp files from the inspector_protocol_sources list.
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorFrontend.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorBackendDispatcher.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorTypeBuilder.cpp',
+ '<(blink_core_output_dir)/InspectorFrontend.cpp',
+ '<(blink_core_output_dir)/InspectorBackendDispatcher.cpp',
+ '<(blink_core_output_dir)/InspectorTypeBuilder.cpp',
# Additional .cpp files from the inspector_instrumentation_sources list.
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorCanvasInstrumentationInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorConsoleInstrumentationInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorDatabaseInstrumentationInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorInstrumentationInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorOverridesInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InstrumentingAgentsInl.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorInstrumentationImpl.cpp',
+ '<(blink_core_output_dir)/InspectorCanvasInstrumentationInl.h',
+ '<(blink_core_output_dir)/InspectorConsoleInstrumentationInl.h',
+ '<(blink_core_output_dir)/InspectorInstrumentationInl.h',
+ '<(blink_core_output_dir)/InspectorOverridesInl.h',
+ '<(blink_core_output_dir)/InstrumentingAgentsInl.h',
+ '<(blink_core_output_dir)/InspectorInstrumentationImpl.cpp',
# Additional .cpp files for SVG.
- '<(SHARED_INTERMEDIATE_DIR)/blink/SVGElementFactory.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/V8SVGElementWrapperFactory.cpp',
+ '<(blink_core_output_dir)/SVGElementFactory.cpp',
+ '<(blink_core_output_dir)/V8SVGElementWrapperFactory.cpp',
# Generated from make_style_shorthands.py
- '<(SHARED_INTERMEDIATE_DIR)/blink/StylePropertyShorthand.cpp',
+ '<(blink_core_output_dir)/StylePropertyShorthand.cpp',
# Generated from make_style_builder.py
- '<(SHARED_INTERMEDIATE_DIR)/blink/StyleBuilder.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/StyleBuilderFunctions.cpp',
+ '<(blink_core_output_dir)/StyleBuilder.cpp',
+ '<(blink_core_output_dir)/StyleBuilderFunctions.cpp',
],
'conditions': [
['OS=="win" and component=="shared_library"', {
@@ -334,7 +345,9 @@
['OS=="win"', {
# In generated bindings code: 'switch contains default but no case'.
# Disable c4267 warnings until we fix size_t to int truncations.
- 'msvs_disabled_warnings': [ 4065, 4267 ],
+ # 4702 is disabled because of issues in Bison-generated
+ # XPathGrammar.cpp and CSSGrammar.cpp.
+ 'msvs_disabled_warnings': [ 4065, 4267, 4702 ],
}],
['OS in ("linux", "android") and "WTF_USE_WEBAUDIO_IPP=1" in feature_defines', {
'cflags': [
@@ -346,6 +359,7 @@
{
# We'll soon split libwebcore in multiple smaller libraries.
# webcore_prerequisites will be the 'base' target of every sub-target.
+ # GN version: //third_party/WebKit/Source/core:prerequisites
'target_name': 'webcore_prerequisites',
'type': 'none',
'dependencies': [
@@ -355,11 +369,12 @@
'inspector_overlay_page',
'inspector_protocol_sources',
'inspector_instrumentation_sources',
- '../bindings/derived_sources.gyp:bindings_derived_sources',
- 'core_derived_sources.gyp:make_core_derived_sources',
+ 'core_generated.gyp:make_core_generated',
+ '../bindings/core/v8/generated.gyp:bindings_core_v8_generated',
+ # FIXME: don't depend on bindings_modules http://crbug.com/358074
+ '../bindings/modules/v8/generated.gyp:bindings_modules_v8_generated',
'../wtf/wtf.gyp:wtf',
'../config.gyp:config',
- '../heap/blink_heap.gyp:blink_heap',
'../platform/blink_platform.gyp:blink_platform',
'<(DEPTH)/gpu/gpu.gyp:gles2_c_lib',
'<(DEPTH)/skia/skia.gyp:skia',
@@ -380,7 +395,6 @@
'export_dependent_settings': [
'../wtf/wtf.gyp:wtf',
'../config.gyp:config',
- '../heap/blink_heap.gyp:blink_heap',
'<(DEPTH)/gpu/gpu.gyp:gles2_c_lib',
'<(DEPTH)/skia/skia.gyp:skia',
'<(angle_path)/src/build_angle.gyp:translator',
@@ -437,19 +451,18 @@
],
},
}],
- ['toolkit_uses_gtk == 1', {
- 'dependencies': [
- '<(DEPTH)/build/linux/system.gyp:gtk',
- ],
- 'export_dependent_settings': [
- '<(DEPTH)/build/linux/system.gyp:gtk',
- ],
- }],
['OS=="android"', {
'sources/': [
['exclude', 'accessibility/'],
],
}],
+ ['OS in ("linux", "android") and "WTF_USE_WEBAUDIO_IPP=1" in feature_defines', {
+ 'direct_dependent_settings': {
+ 'cflags': [
+ '<!@(pkg-config --cflags-only-I ipp)',
+ ],
+ },
+ }],
['OS=="mac"', {
'direct_dependent_settings': {
'defines': [
@@ -472,10 +485,9 @@
# If this is unhandled, the console will receive log messages
# such as:
# com.google.Chrome[] objc[]: Class ScrollbarPrefsObserver is implemented in both .../Google Chrome.app/Contents/Versions/.../Google Chrome Helper.app/Contents/MacOS/../../../Google Chrome Framework.framework/Google Chrome Framework and /System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/WebCore. One of the two will be used. Which one is undefined.
- 'WebCoreFlippedView=ChromiumWebCoreObjCWebCoreFlippedView',
'WebCoreTextFieldCell=ChromiumWebCoreObjCWebCoreTextFieldCell',
'WebCoreRenderThemeNotificationObserver=ChromiumWebCoreObjCWebCoreRenderThemeNotificationObserver',
- ],
+ ],
'postbuilds': [
{
# This step ensures that any Objective-C names that aren't
@@ -496,13 +508,6 @@
],
},
}],
- ['OS in ("linux", "android") and "WTF_USE_WEBAUDIO_IPP=1" in feature_defines', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags-only-I ipp)',
- ],
- },
- }],
['"WTF_USE_WEBAUDIO_FFMPEG=1" in feature_defines', {
# This directory needs to be on the include path for multiple sub-targets of webcore.
'direct_dependent_settings': {
@@ -533,6 +538,7 @@
],
},
{
+ # GN version: //third_party/WebKit/Source/core:dom
'target_name': 'webcore_dom',
'type': 'static_library',
'dependencies': [
@@ -545,6 +551,7 @@
'msvs_disabled_warnings': [ 4267, ],
},
{
+ # GN version: //third_party/WebKit/Source/core:html
'target_name': 'webcore_html',
'type': 'static_library',
'dependencies': [
@@ -554,6 +561,11 @@
'<@(webcore_html_files)',
],
'conditions': [
+ # Shard this taret into parts to work around linker limitations.
+ # on link time code generation builds.
+ ['OS=="win" and buildtype=="Official"', {
+ 'msvs_shard': 5,
+ }],
['OS!="android"', {
'sources/': [
['exclude', 'Android\\.cpp$'],
@@ -562,6 +574,7 @@
],
},
{
+ # GN version: //third_party/WebKit/Source/core:svg
'target_name': 'webcore_svg',
'type': 'static_library',
'dependencies': [
@@ -570,104 +583,14 @@
'sources': [
'<@(webcore_svg_files)',
],
- },
- {
- 'target_name': 'webcore_platform',
- 'type': 'static_library',
- 'dependencies': [
- 'webcore_prerequisites',
- ],
- # Disable c4267 warnings until we fix size_t to int truncations.
- # Disable c4724 warnings which is generated in VS2012 due to improper
- # compiler optimizations, see crbug.com/237063
- 'msvs_disabled_warnings': [ 4267, 4334, 4724 ],
- 'sources': [
- '<@(webcore_platform_files)',
- ],
- 'sources/': [
- # FIXME: Figure out how to store these patterns in a variable.
- ['exclude', '(cf|cg|harfbuzz|mac|opentype|svg|win)/'],
- ['exclude', '(?<!Chromium)(CF|CG|Mac|Win)\\.(cpp|mm?)$'],
-
- # Used only by mac.
- ['exclude', 'platform/Theme\\.cpp$'],
- ],
'conditions': [
- ['OS!="linux"', {
- 'sources/': [
- ['exclude', 'Linux\\.cpp$'],
- ],
- }],
- ['toolkit_uses_gtk == 0', {
- 'sources/': [
- ['exclude', 'platform/chromium/KeyCodeConversionGtk\\.cpp$'],
- ],
- }],
- ['OS=="mac"', {
- 'sources': [
- 'editing/SmartReplaceCF.cpp',
- ],
- 'link_settings': {
- 'libraries': [
- '$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
- ],
- },
- 'sources/': [
- # Additional files from the WebCore Mac build that are presently
- # used in the WebCore Chromium Mac build too.
-
- # The Mac build is USE(CF).
- ['include', 'CF\\.cpp$'],
-
- # Cherry-pick some files that can't be included by broader regexps.
- # Some of these are used instead of Chromium platform files, see
- # the specific exclusions in the "exclude" list below.
- ['include', 'platform/mac/ThemeMac\\.h$'],
- ['include', 'platform/mac/ThemeMac\\.mm$'],
- ['include', 'platform/mac/WebCoreSystemInterface\\.h$'],
- ['include', 'platform/mac/WebCoreTextRenderer\\.mm$'],
- ['include', 'platform/text/mac/ShapeArabic\\.c$'],
- ['include', 'platform/text/mac/String(Impl)?Mac\\.mm$'],
- # Use USE_NEW_THEME on Mac.
- ['include', 'platform/Theme\\.cpp$'],
- ],
- }],
- ['OS=="win"', {
- 'sources/': [
- ['exclude', 'Posix\\.cpp$'],
- ],
- },{ # OS!="win"
- 'sources/': [
- ['exclude', 'Win\\.cpp$'],
- ],
- }],
- ['OS=="win" and chromium_win_pch==1', {
- 'sources/': [
- ['include', '<(DEPTH)/third_party/WebKit/Source/build/win/Precompile.cpp'],
- ],
- }],
- ['OS=="android"', {
- 'sources/': [
- ['include', 'platform/chromium/ClipboardChromiumLinux\\.cpp$'],
- ['include', 'platform/chromium/FileSystemChromiumLinux\\.cpp$'],
- ],
- }, { # OS!="android"
- 'sources/': [
- ['exclude', 'Android\\.cpp$'],
- ],
- }],
- ['use_default_render_theme==1', {
- 'sources/': [
- ['exclude', 'platform/chromium/PlatformThemeChromiumWin\\.(cpp|h)'],
- ],
- }, { # use_default_render_theme==0
- 'sources/': [
- ['exclude', 'platform/chromium/PlatformThemeChromiumDefault\\.(cpp|h)'],
- ],
+ ['OS=="win" and buildtype=="Official"', {
+ 'msvs_shard': 5,
}],
],
},
{
+ # GN version: //third_party/WebKit/Source/core:rendering
'target_name': 'webcore_rendering',
'type': 'static_library',
'dependencies': [
@@ -697,11 +620,6 @@
['exclude', 'rendering/RenderThemeChromiumDefault.*'],
],
}],
- ['use_default_render_theme==1', {
- 'sources/': [
- ['exclude', 'RenderThemeChromiumWin.*'],
- ],
- }],
['OS=="win"', {
'sources/': [
['exclude', 'Posix\\.cpp$'],
@@ -737,11 +655,6 @@
['exclude', 'Linux\\.cpp$'],
],
}],
- ['toolkit_uses_gtk == 0', {
- 'sources/': [
- ['exclude', 'Gtk\\.cpp$'],
- ],
- }],
['OS=="android"', {
'sources/': [
['include', 'rendering/RenderThemeChromiumFontProviderLinux\\.cpp$'],
@@ -755,6 +668,7 @@
],
},
{
+ # GN version: //third_party/WebKit/Source/core:remaining
'target_name': 'webcore_remaining',
'type': 'static_library',
'dependencies': [
@@ -781,11 +695,6 @@
['exclude', 'Linux\\.cpp$'],
],
}],
- ['toolkit_uses_gtk == 0', {
- 'sources/': [
- ['exclude', 'Gtk\\.cpp$'],
- ],
- }],
['OS=="android"', {
'cflags': [
# WebCore does not work with strict aliasing enabled.
@@ -795,7 +704,33 @@
}, { # OS!="android"
'sources/': [['exclude', 'Android\\.cpp$']]
}],
- ['OS!="mac"', {
+ ['OS=="mac"', {
+ 'sources': [
+ 'editing/SmartReplaceCF.cpp',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '$(SDKROOT)/System/Library/Frameworks/Carbon.framework',
+ ],
+ },
+ 'sources/': [
+ # Additional files from the WebCore Mac build that are presently
+ # used in the WebCore Chromium Mac build too.
+
+ # The Mac build is USE(CF).
+ ['include', 'CF\\.cpp$'],
+
+ # Cherry-pick some files that can't be included by broader regexps.
+ # Some of these are used instead of Chromium platform files, see
+ # the specific exclusions in the "exclude" list below.
+ ['include', 'platform/mac/WebCoreSystemInterface\\.h$'],
+ ['include', 'platform/mac/WebCoreTextRenderer\\.mm$'],
+ ['include', 'platform/text/mac/ShapeArabic\\.c$'],
+ ['include', 'platform/text/mac/String(Impl)?Mac\\.mm$'],
+ # Use USE_NEW_THEME on Mac.
+ ['include', 'platform/Theme\\.cpp$'],
+ ],
+ }, { # OS!="mac"
'sources/': [['exclude', 'Mac\\.(cpp|mm?)$']]
}],
['OS=="win" and chromium_win_pch==1', {
@@ -808,17 +743,17 @@
'msvs_disabled_warnings': [ 4267, 4334, ],
},
{
+ # GN version: //third_party/WebKit/Source/core:core
'target_name': 'webcore',
'type': 'none',
'dependencies': [
'webcore_dom',
'webcore_html',
- 'webcore_platform',
'webcore_remaining',
'webcore_rendering',
'webcore_svg',
# Exported.
- 'webcore_derived',
+ 'webcore_generated',
'../wtf/wtf.gyp:wtf',
'<(DEPTH)/skia/skia.gyp:skia',
'<(DEPTH)/third_party/npapi/npapi.gyp:npapi',
@@ -828,7 +763,7 @@
],
'export_dependent_settings': [
'../wtf/wtf.gyp:wtf',
- 'webcore_derived',
+ 'webcore_generated',
'<(DEPTH)/skia/skia.gyp:skia',
'<(DEPTH)/third_party/npapi/npapi.gyp:npapi',
'<(DEPTH)/third_party/qcms/qcms.gyp:qcms',
@@ -863,7 +798,7 @@
],
},
{
- 'target_name': 'webcore_test_support',
+ 'target_name': 'webcore_testing',
'type': 'static_library',
'dependencies': [
'../config.gyp:config',
@@ -874,32 +809,32 @@
'INSIDE_BLINK',
],
'include_dirs': [
- '<(bindings_dir)/v8', # FIXME: Remove once http://crbug.com/236119 is fixed.
+ '<(bindings_v8_dir)', # FIXME: Remove once http://crbug.com/236119 is fixed.
'testing',
'testing/v8',
],
'sources': [
- '<@(webcore_test_support_files)',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8GCObservation.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8GCObservation.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8MallocStatistics.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8MallocStatistics.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8TypeConversions.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8TypeConversions.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8Internals.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8Internals.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8InternalProfilers.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8InternalProfilers.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8InternalSettings.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8InternalSettings.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8InternalSettingsGenerated.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8InternalSettingsGenerated.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8InternalRuntimeFlags.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8InternalRuntimeFlags.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8LayerRect.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8LayerRect.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8LayerRectList.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/bindings/V8LayerRectList.h',
+ '<@(webcore_testing_files)',
+ '<(bindings_core_v8_output_dir)/V8GCObservation.cpp',
+ '<(bindings_core_v8_output_dir)/V8GCObservation.h',
+ '<(bindings_core_v8_output_dir)/V8MallocStatistics.cpp',
+ '<(bindings_core_v8_output_dir)/V8MallocStatistics.h',
+ '<(bindings_core_v8_output_dir)/V8TypeConversions.cpp',
+ '<(bindings_core_v8_output_dir)/V8TypeConversions.h',
+ '<(bindings_core_v8_output_dir)/V8Internals.cpp',
+ '<(bindings_core_v8_output_dir)/V8Internals.h',
+ '<(bindings_core_v8_output_dir)/V8InternalProfilers.cpp',
+ '<(bindings_core_v8_output_dir)/V8InternalProfilers.h',
+ '<(bindings_core_v8_output_dir)/V8InternalSettings.cpp',
+ '<(bindings_core_v8_output_dir)/V8InternalSettings.h',
+ '<(bindings_core_v8_output_dir)/V8InternalSettingsGenerated.cpp',
+ '<(bindings_core_v8_output_dir)/V8InternalSettingsGenerated.h',
+ '<(bindings_core_v8_output_dir)/V8InternalRuntimeFlags.cpp',
+ '<(bindings_core_v8_output_dir)/V8InternalRuntimeFlags.h',
+ '<(bindings_core_v8_output_dir)/V8LayerRect.cpp',
+ '<(bindings_core_v8_output_dir)/V8LayerRect.h',
+ '<(bindings_core_v8_output_dir)/V8LayerRectList.cpp',
+ '<(bindings_core_v8_output_dir)/V8LayerRectList.h',
],
'sources/': [
['exclude', 'testing/js'],
diff --git a/chromium/third_party/WebKit/Source/core/core.gypi b/chromium/third_party/WebKit/Source/core/core.gypi
index 03c64b57f96..c1818326dd1 100644
--- a/chromium/third_party/WebKit/Source/core/core.gypi
+++ b/chromium/third_party/WebKit/Source/core/core.gypi
@@ -1,7 +1,19 @@
{
+ 'includes': [
+ 'core_generated.gypi',
+ ],
'variables': {
+ # Files for which bindings (.cpp and .h files) will be generated
'core_idl_files': [
- 'animation/ElementAnimation.idl',
+ 'animation/Animation.idl',
+ 'animation/AnimationEffect.idl',
+ 'animation/AnimationPlayer.idl',
+ 'animation/AnimationNode.idl',
+ 'animation/AnimationTimeline.idl',
+ 'animation/Timing.idl',
+ 'clipboard/DataTransfer.idl',
+ 'clipboard/DataTransferItem.idl',
+ 'clipboard/DataTransferItemList.idl',
'css/CSS.idl',
'css/CSSCharsetRule.idl',
'css/CSSFontFaceLoadEvent.idl',
@@ -18,18 +30,14 @@
'css/CSSStyleRule.idl',
'css/CSSStyleSheet.idl',
'css/CSSSupportsRule.idl',
- # We should probably add CSSUnknownRule.idl to this list,
- # but it currently causes a compile error.
- # 'css/CSSUnknownRule.idl',
+ 'css/CSSUnknownRule.idl',
'css/CSSValue.idl',
'css/CSSValueList.idl',
- 'css/CSSVariablesMap.idl',
- 'css/CSSVariablesMapForEachCallback.idl',
'css/CSSViewportRule.idl',
'css/Counter.idl',
- 'css/DocumentFontFaceSet.idl',
'css/FontFace.idl',
'css/FontFaceSet.idl',
+ 'css/FontFaceSetForEachCallback.idl',
'css/MediaList.idl',
'css/MediaQueryList.idl',
'css/RGBColor.idl',
@@ -40,16 +48,12 @@
'css/WebKitCSSFilterRule.idl',
'css/WebKitCSSFilterValue.idl',
'css/WebKitCSSMatrix.idl',
- 'css/WebKitCSSMixFunctionValue.idl',
- 'css/WebKitCSSRegionRule.idl',
'css/WebKitCSSTransformValue.idl',
'dom/Attr.idl',
'dom/CDATASection.idl',
'dom/CharacterData.idl',
- 'dom/ChildNode.idl',
'dom/ClientRect.idl',
'dom/ClientRectList.idl',
- 'dom/Clipboard.idl',
'dom/Comment.idl',
'dom/DOMError.idl',
'dom/DOMException.idl',
@@ -58,15 +62,10 @@
'dom/DOMStringList.idl',
'dom/DOMStringMap.idl',
'dom/DOMTokenList.idl',
- 'dom/DataTransferItem.idl',
- 'dom/DataTransferItemList.idl',
'dom/Document.idl',
'dom/DocumentFragment.idl',
- 'dom/DocumentFullscreen.idl',
'dom/DocumentType.idl',
'dom/Element.idl',
- 'dom/Entity.idl',
- 'dom/GlobalEventHandlers.idl',
'dom/MessageChannel.idl',
'dom/MessagePort.idl',
'dom/MutationObserver.idl',
@@ -77,9 +76,7 @@
'dom/NodeIterator.idl',
'dom/NodeList.idl',
'dom/Notation.idl',
- 'dom/ParentNode.idl',
'dom/ProcessingInstruction.idl',
- 'dom/Promise.idl',
'dom/Range.idl',
'dom/RequestAnimationFrameCallback.idl',
'dom/StringCallback.idl',
@@ -88,13 +85,11 @@
'dom/TouchList.idl',
'dom/TreeWalker.idl',
'dom/URL.idl',
- 'dom/URLUtils.idl',
- 'dom/URLUtilsReadOnly.idl',
- 'dom/WebKitNamedFlow.idl',
- 'dom/WebKitNamedFlowCollection.idl',
+ 'dom/XMLDocument.idl',
'dom/shadow/ShadowRoot.idl',
+ 'events/AnimationPlayerEvent.idl',
+ 'events/ApplicationCacheErrorEvent.idl',
'events/AutocompleteErrorEvent.idl',
- 'events/BeforeLoadEvent.idl',
'events/BeforeUnloadEvent.idl',
'events/CompositionEvent.idl',
'events/CustomEvent.idl',
@@ -107,7 +102,6 @@
'events/MessageEvent.idl',
'events/MouseEvent.idl',
'events/MutationEvent.idl',
- 'events/NavigatorEvents.idl',
'events/OverflowEvent.idl',
'events/PageTransitionEvent.idl',
'events/PopStateEvent.idl',
@@ -134,15 +128,9 @@
'frame/ImageBitmap.idl',
'frame/Location.idl',
'frame/Navigator.idl',
- 'frame/NavigatorID.idl',
- 'frame/NavigatorOnLine.idl',
'frame/Screen.idl',
- 'frame/SecurityPolicy.idl',
'frame/WebKitPoint.idl',
'frame/Window.idl',
- 'frame/WindowBase64.idl',
- 'frame/WindowEventHandlers.idl',
- 'frame/WindowTimers.idl',
'html/FormData.idl',
'html/HTMLAllCollection.idl',
'html/HTMLAnchorElement.idl',
@@ -155,6 +143,7 @@
'html/HTMLButtonElement.idl',
'html/HTMLCanvasElement.idl',
'html/HTMLCollection.idl',
+ 'html/HTMLContentElement.idl',
'html/HTMLDListElement.idl',
'html/HTMLDataListElement.idl',
'html/HTMLDetailsElement.idl',
@@ -197,11 +186,13 @@
'html/HTMLOutputElement.idl',
'html/HTMLParagraphElement.idl',
'html/HTMLParamElement.idl',
+ 'html/HTMLPictureElement.idl',
'html/HTMLPreElement.idl',
'html/HTMLProgressElement.idl',
'html/HTMLQuoteElement.idl',
'html/HTMLScriptElement.idl',
'html/HTMLSelectElement.idl',
+ 'html/HTMLShadowElement.idl',
'html/HTMLSourceElement.idl',
'html/HTMLSpanElement.idl',
'html/HTMLStyleElement.idl',
@@ -232,9 +223,10 @@
'html/canvas/Canvas2DContextAttributes.idl',
'html/canvas/CanvasGradient.idl',
'html/canvas/CanvasPattern.idl',
- 'html/canvas/CanvasRenderingContext.idl',
'html/canvas/CanvasRenderingContext2D.idl',
+ 'html/canvas/EXTBlendMinMax.idl',
'html/canvas/EXTFragDepth.idl',
+ 'html/canvas/EXTShaderTextureLOD.idl',
'html/canvas/EXTTextureFilterAnisotropic.idl',
'html/canvas/OESElementIndexUint.idl',
'html/canvas/OESStandardDerivatives.idl',
@@ -243,10 +235,11 @@
'html/canvas/OESTextureHalfFloat.idl',
'html/canvas/OESTextureHalfFloatLinear.idl',
'html/canvas/OESVertexArrayObject.idl',
- 'html/canvas/Path.idl',
+ 'html/canvas/Path2D.idl',
'html/canvas/WebGLActiveInfo.idl',
'html/canvas/WebGLBuffer.idl',
'html/canvas/WebGLCompressedTextureATC.idl',
+ 'html/canvas/WebGLCompressedTextureETC1.idl',
'html/canvas/WebGLCompressedTexturePVRTC.idl',
'html/canvas/WebGLCompressedTextureS3TC.idl',
'html/canvas/WebGLContextAttributes.idl',
@@ -265,15 +258,16 @@
'html/canvas/WebGLTexture.idl',
'html/canvas/WebGLUniformLocation.idl',
'html/canvas/WebGLVertexArrayObjectOES.idl',
- 'html/ime/Composition.idl',
'html/ime/InputMethodContext.idl',
- 'html/shadow/HTMLContentElement.idl',
- 'html/shadow/HTMLShadowElement.idl',
+ 'html/track/AudioTrack.idl',
+ 'html/track/AudioTrackList.idl',
'html/track/TextTrack.idl',
'html/track/TextTrackCue.idl',
'html/track/TextTrackCueList.idl',
'html/track/TextTrackList.idl',
'html/track/TrackEvent.idl',
+ 'html/track/VideoTrack.idl',
+ 'html/track/VideoTrackList.idl',
'html/track/vtt/VTTCue.idl',
'html/track/vtt/VTTRegion.idl',
'html/track/vtt/VTTRegionList.idl',
@@ -285,53 +279,17 @@
'page/EventSource.idl',
'page/PagePopupController.idl',
'page/Selection.idl',
- 'page/WindowPagePopup.idl',
'plugins/MimeType.idl',
'plugins/MimeTypeArray.idl',
'plugins/Plugin.idl',
'plugins/PluginArray.idl',
- 'speech/SpeechInputEvent.idl',
- 'speech/SpeechInputResult.idl',
- 'speech/SpeechInputResultList.idl',
'storage/Storage.idl',
'storage/StorageEvent.idl',
- 'timing/MemoryInfo.idl',
- 'timing/Performance.idl',
- 'timing/PerformanceEntry.idl',
- 'timing/PerformanceMark.idl',
- 'timing/PerformanceMeasure.idl',
- 'timing/PerformanceNavigation.idl',
- 'timing/PerformanceResourceTiming.idl',
- 'timing/PerformanceTiming.idl',
- 'workers/AbstractWorker.idl',
- 'workers/DedicatedWorkerGlobalScope.idl',
- 'workers/SharedWorker.idl',
- 'workers/SharedWorkerGlobalScope.idl',
- 'workers/Worker.idl',
- 'workers/WorkerConsole.idl',
- 'workers/WorkerGlobalScope.idl',
- 'workers/WorkerLocation.idl',
- 'workers/WorkerNavigator.idl',
- 'xml/DOMParser.idl',
- 'xml/DocumentXPathEvaluator.idl',
- 'xml/XMLHttpRequest.idl',
- 'xml/XMLHttpRequestEventTarget.idl',
- 'xml/XMLHttpRequestProgressEvent.idl',
- 'xml/XMLHttpRequestUpload.idl',
- 'xml/XMLSerializer.idl',
- 'xml/XPathEvaluator.idl',
- 'xml/XPathExpression.idl',
- 'xml/XPathNSResolver.idl',
- 'xml/XPathResult.idl',
- 'xml/XSLTProcessor.idl',
- ],
- 'svg_idl_files': [
'svg/SVGAElement.idl',
'svg/SVGAltGlyphDefElement.idl',
'svg/SVGAltGlyphElement.idl',
'svg/SVGAltGlyphItemElement.idl',
'svg/SVGAngle.idl',
- 'svg/SVGAnimateColorElement.idl',
'svg/SVGAnimateElement.idl',
'svg/SVGAnimateMotionElement.idl',
'svg/SVGAnimateTransformElement.idl',
@@ -350,17 +308,13 @@
'svg/SVGAnimationElement.idl',
'svg/SVGCircleElement.idl',
'svg/SVGClipPathElement.idl',
- 'svg/SVGColor.idl',
'svg/SVGComponentTransferFunctionElement.idl',
'svg/SVGCursorElement.idl',
'svg/SVGDefsElement.idl',
'svg/SVGDescElement.idl',
- 'svg/SVGDocument.idl',
+ 'svg/SVGDiscardElement.idl',
'svg/SVGElement.idl',
- 'svg/SVGElementInstance.idl',
- 'svg/SVGElementInstanceList.idl',
'svg/SVGEllipseElement.idl',
- 'svg/SVGExternalResourcesRequired.idl',
'svg/SVGFEBlendElement.idl',
'svg/SVGFEColorMatrixElement.idl',
'svg/SVGFEComponentTransferElement.idl',
@@ -387,8 +341,6 @@
'svg/SVGFETileElement.idl',
'svg/SVGFETurbulenceElement.idl',
'svg/SVGFilterElement.idl',
- 'svg/SVGFilterPrimitiveStandardAttributes.idl',
- 'svg/SVGFitToViewBox.idl',
'svg/SVGFontElement.idl',
'svg/SVGFontFaceElement.idl',
'svg/SVGFontFaceFormatElement.idl',
@@ -397,9 +349,9 @@
'svg/SVGFontFaceUriElement.idl',
'svg/SVGForeignObjectElement.idl',
'svg/SVGGElement.idl',
+ 'svg/SVGGeometryElement.idl',
'svg/SVGGlyphElement.idl',
'svg/SVGGlyphRefElement.idl',
- 'svg/SVGGeometryElement.idl',
'svg/SVGGradientElement.idl',
'svg/SVGGraphicsElement.idl',
'svg/SVGHKernElement.idl',
@@ -416,7 +368,6 @@
'svg/SVGMissingGlyphElement.idl',
'svg/SVGNumber.idl',
'svg/SVGNumberList.idl',
- 'svg/SVGPaint.idl',
'svg/SVGPathElement.idl',
'svg/SVGPathSeg.idl',
'svg/SVGPathSegArcAbs.idl',
@@ -458,7 +409,6 @@
'svg/SVGSwitchElement.idl',
'svg/SVGSymbolElement.idl',
'svg/SVGTSpanElement.idl',
- 'svg/SVGTests.idl',
'svg/SVGTextContentElement.idl',
'svg/SVGTextElement.idl',
'svg/SVGTextPathElement.idl',
@@ -466,19 +416,112 @@
'svg/SVGTitleElement.idl',
'svg/SVGTransform.idl',
'svg/SVGTransformList.idl',
- 'svg/SVGURIReference.idl',
'svg/SVGUnitTypes.idl',
'svg/SVGUseElement.idl',
'svg/SVGVKernElement.idl',
'svg/SVGViewElement.idl',
'svg/SVGViewSpec.idl',
+ 'svg/SVGZoomEvent.idl',
+ 'timing/MemoryInfo.idl',
+ 'timing/Performance.idl',
+ 'timing/PerformanceEntry.idl',
+ 'timing/PerformanceMark.idl',
+ 'timing/PerformanceMeasure.idl',
+ 'timing/PerformanceNavigation.idl',
+ 'timing/PerformanceResourceTiming.idl',
+ 'timing/PerformanceTiming.idl',
+ 'workers/DedicatedWorkerGlobalScope.idl',
+ 'workers/SharedWorker.idl',
+ 'workers/SharedWorkerGlobalScope.idl',
+ 'workers/Worker.idl',
+ 'workers/WorkerConsole.idl',
+ 'workers/WorkerGlobalScope.idl',
+ 'workers/WorkerLocation.idl',
+ 'workers/WorkerNavigator.idl',
+ 'xml/DOMParser.idl',
+ 'xml/XMLHttpRequest.idl',
+ 'xml/XMLHttpRequestEventTarget.idl',
+ 'xml/XMLHttpRequestProgressEvent.idl',
+ 'xml/XMLHttpRequestUpload.idl',
+ 'xml/XMLSerializer.idl',
+ 'xml/XPathEvaluator.idl',
+ 'xml/XPathExpression.idl',
+ 'xml/XPathNSResolver.idl',
+ 'xml/XPathResult.idl',
+ 'xml/XSLTProcessor.idl',
+ ],
+ # 'partial interface', target (right side of) 'implements', and
+ # interfaces with static bindings (in bindings/v8/)
+ 'core_dependency_idl_files': [
+ 'animation/DocumentAnimation.idl',
+ 'animation/ElementAnimation.idl',
+ 'css/DocumentFontFaceSet.idl',
+ 'dom/ChildNode.idl',
+ 'dom/DocumentFullscreen.idl',
+ 'dom/GlobalEventHandlers.idl',
+ 'dom/ParentNode.idl',
+ 'dom/URLUtils.idl',
+ 'dom/URLUtilsReadOnly.idl',
+ 'events/EventListener.idl',
+ 'events/NavigatorEvents.idl',
+ 'frame/NavigatorCPU.idl',
+ 'frame/NavigatorID.idl',
+ 'frame/NavigatorLanguage.idl',
+ 'frame/NavigatorOnLine.idl',
+ 'frame/WindowBase64.idl',
+ 'frame/WindowEventHandlers.idl',
+ 'frame/WindowTimers.idl',
+ 'html/canvas/CanvasPathMethods.idl',
+ 'html/canvas/WebGLRenderingContextBase.idl',
+ 'page/WindowPagePopup.idl',
+ 'svg/SVGDocument.idl',
+ 'svg/SVGFilterPrimitiveStandardAttributes.idl',
+ 'svg/SVGFitToViewBox.idl',
+ 'svg/SVGTests.idl',
+ 'svg/SVGURIReference.idl',
'svg/SVGZoomAndPan.idl',
+ 'workers/AbstractWorker.idl',
+ 'xml/DocumentXPathEvaluator.idl',
+ ],
+ # interfaces that inherit from Event, including Event itself
+ 'core_event_idl_files': [
+ 'css/CSSFontFaceLoadEvent.idl',
+ 'events/AnimationPlayerEvent.idl',
+ 'events/ApplicationCacheErrorEvent.idl',
+ 'events/AutocompleteErrorEvent.idl',
+ 'events/BeforeUnloadEvent.idl',
+ 'events/CompositionEvent.idl',
+ 'events/CustomEvent.idl',
+ 'events/ErrorEvent.idl',
+ 'events/Event.idl',
+ 'events/FocusEvent.idl',
+ 'events/HashChangeEvent.idl',
+ 'events/KeyboardEvent.idl',
+ 'events/MessageEvent.idl',
+ 'events/MouseEvent.idl',
+ 'events/MutationEvent.idl',
+ 'events/OverflowEvent.idl',
+ 'events/PageTransitionEvent.idl',
+ 'events/PopStateEvent.idl',
+ 'events/ProgressEvent.idl',
+ 'events/ResourceProgressEvent.idl',
+ 'events/SecurityPolicyViolationEvent.idl',
+ 'events/TextEvent.idl',
+ 'events/TouchEvent.idl',
+ 'events/TransitionEvent.idl',
+ 'events/UIEvent.idl',
+ 'events/WebKitAnimationEvent.idl',
+ 'events/WheelEvent.idl',
+ 'html/MediaKeyEvent.idl',
+ 'html/canvas/WebGLContextEvent.idl',
+ 'html/track/TrackEvent.idl',
+ 'storage/StorageEvent.idl',
'svg/SVGZoomEvent.idl',
+ 'xml/XMLHttpRequestProgressEvent.idl',
],
'webcore_files': [
'Init.cpp',
'Init.h',
- 'accessibility/AXObjectCache.cpp',
'accessibility/AXARIAGrid.cpp',
'accessibility/AXARIAGrid.h',
'accessibility/AXARIAGridCell.cpp',
@@ -508,10 +551,13 @@
'accessibility/AXNodeObject.cpp',
'accessibility/AXNodeObject.h',
'accessibility/AXObject.cpp',
+ 'accessibility/AXObjectCache.cpp',
'accessibility/AXProgressIndicator.cpp',
'accessibility/AXProgressIndicator.h',
'accessibility/AXRenderObject.cpp',
'accessibility/AXRenderObject.h',
+ 'accessibility/AXSVGRoot.cpp',
+ 'accessibility/AXSVGRoot.h',
'accessibility/AXScrollView.cpp',
'accessibility/AXScrollView.h',
'accessibility/AXScrollbar.cpp',
@@ -520,8 +566,6 @@
'accessibility/AXSlider.h',
'accessibility/AXSpinButton.cpp',
'accessibility/AXSpinButton.h',
- 'accessibility/AXSVGRoot.cpp',
- 'accessibility/AXSVGRoot.h',
'accessibility/AXTable.cpp',
'accessibility/AXTable.h',
'accessibility/AXTableCell.cpp',
@@ -552,6 +596,8 @@
'animation/AnimatableLengthBoxAndBool.h',
'animation/AnimatableLengthPoint.cpp',
'animation/AnimatableLengthPoint.h',
+ 'animation/AnimatableLengthPoint3D.cpp',
+ 'animation/AnimatableLengthPoint3D.h',
'animation/AnimatableLengthSize.cpp',
'animation/AnimatableLengthSize.h',
'animation/AnimatableNeutral.h',
@@ -572,42 +618,91 @@
'animation/AnimatableUnknown.h',
'animation/AnimatableValue.cpp',
'animation/AnimatableValue.h',
+ 'animation/AnimatableValueKeyframe.cpp',
+ 'animation/AnimatableValueKeyframe.h',
'animation/AnimatableVisibility.cpp',
'animation/AnimatableVisibility.h',
- 'animation/ElementAnimation.cpp',
- 'animation/ElementAnimation.h',
'animation/Animation.cpp',
'animation/Animation.h',
+ 'animation/AnimationClock.cpp',
'animation/AnimationClock.h',
'animation/AnimationEffect.h',
+ 'animation/AnimationHelpers.h',
+ 'animation/AnimationPlayer.cpp',
+ 'animation/AnimationPlayer.h',
+ 'animation/AnimationNode.cpp',
+ 'animation/AnimationNode.h',
+ 'animation/AnimationNodeTiming.cpp',
+ 'animation/AnimationNodeTiming.h',
'animation/AnimationStack.cpp',
'animation/AnimationStack.h',
+ 'animation/AnimationTimeline.cpp',
+ 'animation/AnimationTimeline.h',
+ 'animation/AnimationTranslationUtil.cpp',
+ 'animation/AnimationTranslationUtil.h',
'animation/CompositorAnimations.cpp',
'animation/CompositorAnimations.h',
'animation/CompositorAnimationsImpl.h',
+ 'animation/CompositorPendingAnimations.cpp',
+ 'animation/CompositorPendingAnimations.h',
+ 'animation/DocumentAnimation.h',
'animation/DocumentAnimations.cpp',
'animation/DocumentAnimations.h',
- 'animation/DocumentTimeline.cpp',
- 'animation/DocumentTimeline.h',
+ 'animation/EffectInput.cpp',
+ 'animation/EffectInput.h',
+ 'animation/ElementAnimation.h',
'animation/InertAnimation.cpp',
'animation/InertAnimation.h',
- 'animation/KeyframeAnimationEffect.cpp',
- 'animation/KeyframeAnimationEffect.h',
- 'animation/Player.cpp',
- 'animation/Player.h',
- 'animation/TimedItem.cpp',
- 'animation/TimedItem.h',
- 'animation/TimedItemCalculations.h',
+ 'animation/InterpolableValue.cpp',
+ 'animation/InterpolableValue.h',
+ 'animation/InterpolationEffect.cpp',
+ 'animation/InterpolationEffect.h',
+ 'animation/KeyframeEffectModel.cpp',
+ 'animation/KeyframeEffectModel.h',
+ 'animation/SampledEffect.cpp',
+ 'animation/SampledEffect.h',
+ 'animation/StringKeyframe.cpp',
+ 'animation/StringKeyframe.h',
'animation/Timing.h',
+ 'animation/TimingCalculations.h',
+ 'animation/TimingInput.cpp',
+ 'animation/TimingInput.h',
'animation/css/CSSAnimatableValueFactory.cpp',
'animation/css/CSSAnimatableValueFactory.h',
+ 'animation/css/CSSAnimationData.cpp',
+ 'animation/css/CSSAnimationData.h',
'animation/css/CSSAnimations.cpp',
'animation/css/CSSAnimations.h',
- 'animation/css/CSSPendingAnimations.cpp',
- 'animation/css/CSSPendingAnimations.h',
- 'animation/css/TransitionTimeline.cpp',
- 'animation/css/TransitionTimeline.h',
+ 'animation/css/CSSPropertyEquality.cpp',
+ 'animation/css/CSSPropertyEquality.h',
+ 'animation/css/CSSTimingData.cpp',
+ 'animation/css/CSSTimingData.h',
+ 'animation/css/CSSTransitionData.cpp',
+ 'animation/css/CSSTransitionData.h',
+ 'animation/interpolation/DefaultStyleInterpolation.h',
+ 'animation/interpolation/DeferredLegacyStyleInterpolation.h',
+ 'animation/interpolation/DeferredLegacyStyleInterpolation.cpp',
+ 'animation/interpolation/Interpolation.cpp',
+ 'animation/interpolation/Interpolation.h',
+ 'animation/interpolation/LegacyStyleInterpolation.h',
+ 'animation/interpolation/LengthStyleInterpolation.cpp',
+ 'animation/interpolation/LengthStyleInterpolation.h',
+ 'animation/interpolation/StyleInterpolation.h',
+ 'clipboard/Clipboard.cpp',
+ 'clipboard/Clipboard.h',
+ 'clipboard/DataObject.cpp',
+ 'clipboard/DataObject.h',
+ 'clipboard/DataObjectItem.cpp',
+ 'clipboard/DataObjectItem.h',
+ 'clipboard/DataTransferItem.cpp',
+ 'clipboard/DataTransferItem.h',
+ 'clipboard/DataTransferItemList.cpp',
+ 'clipboard/DataTransferItemList.h',
+ 'clipboard/Pasteboard.cpp',
+ 'clipboard/Pasteboard.h',
'css/BasicShapeFunctions.cpp',
+ 'css/BinaryDataFontFaceSource.cpp',
+ 'css/BinaryDataFontFaceSource.h',
'css/CSSArrayFunctionValue.cpp',
'css/CSSArrayFunctionValue.h',
'css/CSSAspectRatioValue.cpp',
@@ -617,17 +712,17 @@
'css/CSSBorderImage.h',
'css/CSSBorderImageSliceValue.cpp',
'css/CSSBorderImageSliceValue.h',
- 'css/CSSCanvasValue.cpp',
- 'css/CSSCanvasValue.h',
'css/CSSCalculationValue.cpp',
'css/CSSCalculationValue.h',
+ 'css/CSSCanvasValue.cpp',
+ 'css/CSSCanvasValue.h',
'css/CSSCharsetRule.cpp',
'css/CSSCharsetRule.h',
'css/CSSComputedStyleDeclaration.cpp',
'css/CSSCrossfadeValue.cpp',
'css/CSSCrossfadeValue.h',
- 'css/CSSCustomFontData.h',
'css/CSSCursorImageValue.cpp',
+ 'css/CSSCustomFontData.h',
'css/CSSDefaultStyleSheets.cpp',
'css/CSSDefaultStyleSheets.h',
'css/CSSFilterRule.cpp',
@@ -648,6 +743,7 @@
'css/CSSFontFeatureValue.h',
'css/CSSFontSelector.cpp',
'css/CSSFontSelector.h',
+ 'css/CSSFontSelectorClient.h',
'css/CSSFontValue.cpp',
'css/CSSFontValue.h',
'css/CSSFunctionValue.cpp',
@@ -656,8 +752,8 @@
'css/CSSGradientValue.h',
'css/CSSGridLineNamesValue.cpp',
'css/CSSGridLineNamesValue.h',
- 'css/CSSGridTemplateValue.cpp',
- 'css/CSSGridTemplateValue.h',
+ 'css/CSSGridTemplateAreasValue.cpp',
+ 'css/CSSGridTemplateAreasValue.h',
'css/CSSGroupingRule.cpp',
'css/CSSGroupingRule.h',
'css/CSSImageGeneratorValue.cpp',
@@ -673,20 +769,17 @@
'css/CSSKeyframeRule.h',
'css/CSSKeyframesRule.cpp',
'css/CSSKeyframesRule.h',
- 'css/CSSLengthFunctions.cpp',
- 'css/CSSLengthFunctions.h',
'css/CSSLineBoxContainValue.cpp',
+ 'css/CSSMarkup.cpp',
+ 'css/CSSMarkup.h',
'css/CSSMatrix.cpp',
'css/CSSMatrix.h',
'css/CSSMediaRule.cpp',
'css/CSSMediaRule.h',
- 'css/CSSMixFunctionValue.cpp',
- 'css/CSSMixFunctionValue.h',
'css/CSSOMUtils.cpp',
'css/CSSOMUtils.h',
'css/CSSPageRule.cpp',
'css/CSSPageRule.h',
- 'css/CSSParser.h',
'css/CSSParserMode.cpp',
'css/CSSParserMode.h',
'css/CSSParserValues.cpp',
@@ -695,24 +788,19 @@
'css/CSSProperty.cpp',
'css/CSSPropertySourceData.cpp',
'css/CSSReflectValue.cpp',
- 'css/CSSRegionRule.cpp',
- 'css/CSSRegionRule.h',
'css/CSSRule.cpp',
'css/CSSRule.h',
'css/CSSRuleList.cpp',
'css/CSSRuleList.h',
+ 'css/CSSSVGDocumentValue.cpp',
+ 'css/CSSSVGDocumentValue.h',
'css/CSSSegmentedFontFace.cpp',
'css/CSSSegmentedFontFace.h',
- 'css/CSSSegmentedFontFaceCache.cpp',
- 'css/CSSSegmentedFontFaceCache.h',
'css/CSSSelector.cpp',
'css/CSSSelectorList.cpp',
'css/CSSSelectorList.h',
- 'css/CSSShaderValue.cpp',
- 'css/CSSShaderValue.h',
'css/CSSShadowValue.cpp',
'css/CSSShadowValue.h',
- 'css/CSSStyleDeclaration.cpp',
'css/CSSStyleDeclaration.h',
'css/CSSStyleRule.cpp',
'css/CSSStyleRule.h',
@@ -720,13 +808,11 @@
'css/CSSStyleSheet.h',
'css/CSSSupportsRule.cpp',
'css/CSSSupportsRule.h',
- 'css/CSSSVGDocumentValue.cpp',
- 'css/CSSSVGDocumentValue.h',
'css/CSSTimingFunctionValue.cpp',
'css/CSSTimingFunctionValue.h',
- 'css/CSSTokenizer.h',
'css/CSSToLengthConversionData.cpp',
'css/CSSToLengthConversionData.h',
+ 'css/CSSTokenizer.h',
'css/CSSTransformValue.cpp',
'css/CSSUnicodeRangeValue.cpp',
'css/CSSUnicodeRangeValue.h',
@@ -735,31 +821,30 @@
'css/CSSValueList.cpp',
'css/CSSValuePool.cpp',
'css/CSSValuePool.h',
- 'css/CSSVariablesIterator.h',
- 'css/CSSVariablesMap.cpp',
- 'css/CSSVariablesMap.h',
- 'css/CSSVariablesMapForEachCallback.h',
- 'css/CSSVariableValue.h',
- 'css/CSSViewportRule.h',
'css/CSSViewportRule.cpp',
+ 'css/CSSViewportRule.h',
+ 'css/Counter.cpp',
'css/Counter.h',
'css/DOMWindowCSS.cpp',
'css/DOMWindowCSS.h',
- 'css/DocumentFontFaceSet.h',
'css/DocumentFontFaceSet.cpp',
+ 'css/DocumentFontFaceSet.h',
'css/ElementRuleCollector.cpp',
'css/ElementRuleCollector.h',
- 'css/FontFaceSet.h',
- 'css/FontFaceSet.cpp',
'css/FontFace.cpp',
'css/FontFace.h',
+ 'css/FontFaceCache.cpp',
+ 'css/FontFaceCache.h',
+ 'css/FontFaceSet.cpp',
+ 'css/FontFaceSet.h',
+ 'css/FontFaceSetForEachCallback.h',
+ 'css/FontLoader.cpp',
+ 'css/FontLoader.h',
'css/FontSize.cpp',
'css/FontSize.h',
'css/HashTools.h',
- 'css/InspectorCSSOMWrappers.cpp',
- 'css/InspectorCSSOMWrappers.h',
- 'css/MediaFeatureNames.cpp',
- 'css/MediaFeatureNames.h',
+ 'css/LocalFontFaceSource.cpp',
+ 'css/LocalFontFaceSource.h',
'css/MediaList.cpp',
'css/MediaList.h',
'css/MediaQuery.cpp',
@@ -774,30 +859,35 @@
'css/MediaQueryListListener.h',
'css/MediaQueryMatcher.cpp',
'css/MediaQueryMatcher.h',
+ 'css/MediaValues.cpp',
+ 'css/MediaValuesCached.cpp',
+ 'css/MediaValuesDynamic.cpp',
'css/PageRuleCollector.cpp',
'css/PageRuleCollector.h',
+ 'css/Pair.cpp',
+ 'css/Pair.h',
'css/PropertySetCSSStyleDeclaration.cpp',
'css/PropertySetCSSStyleDeclaration.h',
'css/PseudoStyleRequest.h',
'css/RGBColor.cpp',
'css/RGBColor.h',
+ 'css/Rect.cpp',
'css/Rect.h',
+ 'css/RemoteFontFaceSource.cpp',
+ 'css/RemoteFontFaceSource.h',
'css/RuleFeature.cpp',
'css/RuleFeature.h',
'css/RuleSet.cpp',
'css/RuleSet.h',
+ 'css/RuntimeCSSEnabled.cpp',
+ 'css/RuntimeCSSEnabled.h',
'css/SVGCSSComputedStyleDeclaration.cpp',
- 'css/SVGCSSParser.cpp',
'css/SelectorChecker.cpp',
'css/SelectorChecker.h',
- 'css/SelectorCheckerFastPath.cpp',
- 'css/SelectorCheckerFastPath.h',
'css/SelectorFilter.cpp',
'css/SelectorFilter.h',
'css/SiblingTraversalStrategies.h',
'css/StyleColor.h',
- 'css/StyleInvalidationAnalysis.cpp',
- 'css/StyleInvalidationAnalysis.h',
'css/StyleMedia.cpp',
'css/StyleMedia.h',
'css/StylePropertySerializer.cpp',
@@ -817,6 +907,22 @@
'css/StyleSheetList.h',
'css/TreeBoundaryCrossingRules.cpp',
'css/TreeBoundaryCrossingRules.h',
+ 'css/invalidation/DescendantInvalidationSet.cpp',
+ 'css/invalidation/DescendantInvalidationSet.h',
+ 'css/invalidation/StyleInvalidator.cpp',
+ 'css/invalidation/StyleInvalidator.h',
+ 'css/invalidation/StyleSheetInvalidationAnalysis.cpp',
+ 'css/invalidation/StyleSheetInvalidationAnalysis.h',
+ 'css/parser/BisonCSSParser.h',
+ 'css/parser/CSSPropertyParser.cpp',
+ 'css/parser/CSSPropertyParser.h',
+ 'css/parser/MediaQueryBlockWatcher.cpp',
+ 'css/parser/MediaQueryInputStream.cpp',
+ 'css/parser/MediaQueryParser.cpp',
+ 'css/parser/SizesCalcParser.cpp',
+ 'css/parser/MediaQueryToken.cpp',
+ 'css/parser/MediaQueryTokenizer.cpp',
+ 'css/parser/SizesAttributeParser.cpp',
'css/resolver/AnimatedStyleBuilder.cpp',
'css/resolver/AnimatedStyleBuilder.h',
'css/resolver/CSSToStyleMap.cpp',
@@ -829,11 +935,11 @@
'css/resolver/FilterOperationResolver.h',
'css/resolver/FontBuilder.cpp',
'css/resolver/FontBuilder.h',
- 'css/resolver/MatchedPropertiesCache.cpp',
- 'css/resolver/MatchedPropertiesCache.h',
+ 'css/resolver/MatchRequest.h',
'css/resolver/MatchResult.cpp',
'css/resolver/MatchResult.h',
- 'css/resolver/MatchRequest.h',
+ 'css/resolver/MatchedPropertiesCache.cpp',
+ 'css/resolver/MatchedPropertiesCache.h',
'css/resolver/MediaQueryResult.h',
'css/resolver/ScopedStyleResolver.cpp',
'css/resolver/ScopedStyleResolver.h',
@@ -848,7 +954,8 @@
'css/resolver/StyleBuilderCustom.cpp',
'css/resolver/StyleResolver.cpp',
'css/resolver/StyleResolver.h',
- 'css/resolver/StyleResolverIncludes.h',
+ 'css/resolver/StyleResolverParentScope.cpp',
+ 'css/resolver/StyleResolverParentScope.h',
'css/resolver/StyleResolverState.cpp',
'css/resolver/StyleResolverState.h',
'css/resolver/StyleResolverStats.cpp',
@@ -870,12 +977,16 @@
'editing/Caret.h',
'editing/CompositeEditCommand.cpp',
'editing/CompositionUnderline.h',
+ 'editing/CompositionUnderlineRangeFilter.cpp',
+ 'editing/CompositionUnderlineRangeFilter.h',
'editing/CreateLinkCommand.cpp',
'editing/CreateLinkCommand.h',
'editing/DeleteFromTextNodeCommand.cpp',
'editing/DeleteFromTextNodeCommand.h',
'editing/DeleteSelectionCommand.cpp',
'editing/EditCommand.cpp',
+ 'editing/EditingBehavior.cpp',
+ 'editing/EditingBehavior.h',
'editing/EditingStyle.cpp',
'editing/Editor.cpp',
'editing/EditorCommand.cpp',
@@ -904,11 +1015,9 @@
'editing/MarkupAccumulator.h',
'editing/MergeIdenticalElementsCommand.cpp',
'editing/MergeIdenticalElementsCommand.h',
- 'editing/ModifySelectionListLevel.cpp',
- 'editing/ModifySelectionListLevel.h',
'editing/MoveSelectionCommand.cpp',
- 'editing/PlainTextRange.h',
'editing/PlainTextRange.cpp',
+ 'editing/PlainTextRange.h',
'editing/RemoveCSSPropertyCommand.cpp',
'editing/RemoveCSSPropertyCommand.h',
'editing/RemoveFormatCommand.cpp',
@@ -925,17 +1034,13 @@
'editing/SelectionType.h',
'editing/SetNodeAttributeCommand.cpp',
'editing/SetNodeAttributeCommand.h',
- 'editing/SetSelectionCommand.cpp',
- 'editing/SetSelectionCommand.h',
'editing/SimplifyMarkupCommand.cpp',
'editing/SmartReplaceCF.cpp',
'editing/SmartReplaceICU.cpp',
- 'editing/SpellChecker.cpp',
- 'editing/SpellChecker.h',
'editing/SpellCheckRequester.cpp',
'editing/SpellCheckRequester.h',
- 'editing/SpellingCorrectionCommand.cpp',
- 'editing/SpellingCorrectionCommand.h',
+ 'editing/SpellChecker.cpp',
+ 'editing/SpellChecker.h',
'editing/SplitElementCommand.cpp',
'editing/SplitElementCommand.h',
'editing/SplitTextNodeCommand.cpp',
@@ -962,23 +1067,25 @@
'editing/WrapContentsInDummySpanCommand.h',
'editing/htmlediting.cpp',
'editing/markup.cpp',
- 'fetch/CachedMetadata.cpp',
+ 'fetch/CSSStyleSheetResource.cpp',
+ 'fetch/CSSStyleSheetResource.h',
'fetch/CachedMetadata.h',
'fetch/CrossOriginAccessControl.cpp',
'fetch/CrossOriginAccessControl.h',
- 'fetch/CSSStyleSheetResource.cpp',
- 'fetch/CSSStyleSheetResource.h',
'fetch/DocumentResource.cpp',
'fetch/DocumentResource.h',
'fetch/DocumentResourceReference.h',
'fetch/FetchContext.cpp',
'fetch/FetchContext.h',
+ 'fetch/FetchInitiatorInfo.h',
'fetch/FetchRequest.cpp',
'fetch/FetchRequest.h',
'fetch/FontResource.cpp',
'fetch/FontResource.h',
'fetch/ImageResource.cpp',
'fetch/ImageResource.h',
+ 'fetch/MemoryCache.cpp',
+ 'fetch/MemoryCache.h',
'fetch/RawResource.cpp',
'fetch/RawResource.h',
'fetch/Resource.cpp',
@@ -986,30 +1093,23 @@
'fetch/ResourceClientWalker.h',
'fetch/ResourceFetcher.cpp',
'fetch/ResourceFetcher.h',
+ 'fetch/ResourceLoadPriorityOptimizer.cpp',
+ 'fetch/ResourceLoadPriorityOptimizer.h',
'fetch/ResourceLoader.cpp',
'fetch/ResourceLoader.h',
'fetch/ResourceLoaderOptions.h',
'fetch/ResourceLoaderSet.cpp',
'fetch/ResourceLoaderSet.h',
- 'fetch/ResourceLoadPriorityOptimizer.cpp',
- 'fetch/ResourceLoadPriorityOptimizer.h',
'fetch/ResourcePtr.cpp',
'fetch/ResourcePtr.h',
- 'fetch/FetchInitiatorInfo.h',
'fetch/ScriptResource.cpp',
'fetch/ScriptResource.h',
- 'fetch/ShaderResource.cpp',
- 'fetch/ShaderResource.h',
- 'fetch/TextResourceDecoder.cpp',
- 'fetch/TextResourceDecoder.h',
+ 'fetch/TextResource.cpp',
+ 'fetch/TextResource.h',
'fetch/XSLStyleSheetResource.cpp',
'fetch/XSLStyleSheetResource.h',
- 'fetch/MemoryCache.cpp',
- 'fetch/MemoryCache.h',
'fileapi/Blob.cpp',
'fileapi/Blob.h',
- 'fileapi/BlobBuilder.cpp',
- 'fileapi/BlobBuilder.h',
'fileapi/File.cpp',
'fileapi/File.h',
'fileapi/FileError.cpp',
@@ -1025,7 +1125,86 @@
'fileapi/FileReaderSync.h',
'fileapi/Stream.cpp',
'fileapi/Stream.h',
- 'history/HistoryItem.cpp',
+ 'frame/BarProp.cpp',
+ 'frame/BarProp.h',
+ 'frame/Console.cpp',
+ 'frame/Console.h',
+ 'frame/ConsoleBase.cpp',
+ 'frame/ConsoleBase.h',
+ 'frame/DOMPoint.h',
+ 'frame/DOMTimer.cpp',
+ 'frame/DOMTimer.h',
+ 'frame/DOMWindowBase64.cpp',
+ 'frame/DOMWindowBase64.h',
+ 'frame/DOMWindowEventHandlers.h',
+ 'frame/DOMWindowLifecycleNotifier.cpp',
+ 'frame/DOMWindowLifecycleNotifier.h',
+ 'frame/DOMWindowLifecycleObserver.cpp',
+ 'frame/DOMWindowLifecycleObserver.h',
+ 'frame/DOMWindowProperty.cpp',
+ 'frame/DOMWindowProperty.h',
+ 'frame/DOMWindowTimers.cpp',
+ 'frame/DOMWindowTimers.h',
+ 'frame/DeprecatedScheduleStyleRecalcDuringLayout.cpp',
+ 'frame/DeprecatedScheduleStyleRecalcDuringLayout.h',
+ 'frame/DeviceEventControllerBase.cpp',
+ 'frame/DeviceEventControllerBase.h',
+ 'frame/DeviceEventDispatcherBase.cpp',
+ 'frame/DeviceEventDispatcherBase.h',
+ 'frame/DeviceSingleWindowEventController.cpp',
+ 'frame/DeviceSingleWindowEventController.h',
+ 'frame/EventHandlerRegistry.cpp',
+ 'frame/EventHandlerRegistry.h',
+ 'frame/Frame.cpp',
+ 'frame/Frame.h',
+ 'frame/FrameConsole.cpp',
+ 'frame/FrameDestructionObserver.cpp',
+ 'frame/FrameDestructionObserver.h',
+ 'frame/FrameHost.cpp',
+ 'frame/FrameHost.h',
+ 'frame/FrameOwner.h',
+ 'frame/FrameView.cpp',
+ 'frame/History.cpp',
+ 'frame/History.h',
+ 'frame/ImageBitmap.cpp',
+ 'frame/ImageBitmap.h',
+ 'frame/LocalDOMWindow.h',
+ 'frame/LocalDOMWindow.cpp',
+ 'frame/LocalFrame.cpp',
+ 'frame/LocalFrame.h',
+ 'frame/Location.cpp',
+ 'frame/Location.h',
+ 'frame/Navigator.cpp',
+ 'frame/Navigator.h',
+ 'frame/NavigatorCPU.cpp',
+ 'frame/NavigatorCPU.h',
+ 'frame/NavigatorID.cpp',
+ 'frame/NavigatorID.h',
+ 'frame/NavigatorLanguage.cpp',
+ 'frame/NavigatorLanguage.h',
+ 'frame/NavigatorOnLine.h',
+ 'frame/PinchViewport.cpp',
+ 'frame/PinchViewport.h',
+ 'frame/RemoteFrame.cpp',
+ 'frame/RemoteFrame.h',
+ 'frame/RemoteFrameView.cpp',
+ 'frame/RemoteFrameView.h',
+ 'frame/Screen.cpp',
+ 'frame/Screen.h',
+ 'frame/Settings.cpp',
+ 'frame/SettingsDelegate.cpp',
+ 'frame/SettingsDelegate.h',
+ 'frame/SmartClip.cpp',
+ 'frame/SmartClip.h',
+ 'frame/SuspendableTimer.cpp',
+ 'frame/SuspendableTimer.h',
+ 'frame/UseCounter.cpp',
+ 'frame/csp/CSPDirectiveList.cpp',
+ 'frame/csp/CSPSource.cpp',
+ 'frame/csp/CSPSourceList.cpp',
+ 'frame/csp/ContentSecurityPolicy.cpp',
+ 'frame/csp/MediaListDirective.cpp',
+ 'frame/csp/SourceListDirective.cpp',
'inspector/AsyncCallStackTracker.cpp',
'inspector/AsyncCallStackTracker.h',
'inspector/BindingVisitors.h',
@@ -1052,7 +1231,6 @@
'inspector/InjectedScriptManager.h',
'inspector/InjectedScriptModule.cpp',
'inspector/InjectedScriptModule.h',
- 'inspector/InspectorAgent.cpp',
'inspector/InspectorApplicationCacheAgent.cpp',
'inspector/InspectorApplicationCacheAgent.h',
'inspector/InspectorBaseAgent.cpp',
@@ -1061,11 +1239,11 @@
'inspector/InspectorCanvasAgent.cpp',
'inspector/InspectorCanvasAgent.h',
'inspector/InspectorCanvasInstrumentation.h',
- 'inspector/InspectorClient.cpp',
'inspector/InspectorConsoleAgent.cpp',
'inspector/InspectorConsoleAgent.h',
'inspector/InspectorConsoleInstrumentation.h',
'inspector/InspectorController.cpp',
+ 'inspector/InspectorController.h',
'inspector/InspectorCounters.cpp',
'inspector/InspectorCounters.h',
'inspector/InspectorDOMAgent.cpp',
@@ -1073,15 +1251,8 @@
'inspector/InspectorDOMDebuggerAgent.h',
'inspector/InspectorDOMStorageAgent.cpp',
'inspector/InspectorDOMStorageAgent.h',
- 'inspector/InspectorDatabaseAgent.cpp',
- 'inspector/InspectorDatabaseAgent.h',
- 'inspector/InspectorDatabaseInstrumentation.h',
- 'inspector/InspectorDatabaseResource.cpp',
- 'inspector/InspectorDatabaseResource.h',
'inspector/InspectorDebuggerAgent.cpp',
'inspector/InspectorDebuggerAgent.h',
- 'inspector/InspectorFileSystemAgent.cpp',
- 'inspector/InspectorFileSystemAgent.h',
'inspector/InspectorFrontendChannel.h',
'inspector/InspectorFrontendHost.cpp',
'inspector/InspectorFrontendHost.h',
@@ -1089,10 +1260,9 @@
'inspector/InspectorHeapProfilerAgent.h',
'inspector/InspectorHistory.cpp',
'inspector/InspectorHistory.h',
- 'inspector/InspectorIndexedDBAgent.cpp',
- 'inspector/InspectorIndexedDBAgent.h',
'inspector/InspectorInputAgent.cpp',
'inspector/InspectorInputAgent.h',
+ 'inspector/InspectorInspectorAgent.cpp',
'inspector/InspectorInstrumentation.cpp',
'inspector/InspectorInstrumentation.h',
'inspector/InspectorInstrumentationCustomInl.h',
@@ -1100,6 +1270,8 @@
'inspector/InspectorLayerTreeAgent.h',
'inspector/InspectorMemoryAgent.cpp',
'inspector/InspectorMemoryAgent.h',
+ 'inspector/InspectorNodeIds.cpp',
+ 'inspector/InspectorNodeIds.h',
'inspector/InspectorOverlay.cpp',
'inspector/InspectorOverlay.h',
'inspector/InspectorOverlayHost.cpp',
@@ -1110,6 +1282,8 @@
'inspector/InspectorProfilerAgent.h',
'inspector/InspectorResourceAgent.cpp',
'inspector/InspectorResourceAgent.h',
+ 'inspector/InspectorResourceContentLoader.cpp',
+ 'inspector/InspectorResourceContentLoader.h',
'inspector/InspectorRuntimeAgent.cpp',
'inspector/InspectorRuntimeAgent.h',
'inspector/InspectorState.cpp',
@@ -1121,13 +1295,17 @@
'inspector/InspectorStyleTextEditor.h',
'inspector/InspectorTimelineAgent.cpp',
'inspector/InspectorTimelineAgent.h',
+ 'inspector/InspectorTraceEvents.cpp',
+ 'inspector/InspectorTraceEvents.h',
+ 'inspector/InspectorTracingAgent.cpp',
+ 'inspector/InspectorTracingAgent.h',
'inspector/InspectorWorkerAgent.cpp',
'inspector/InspectorWorkerAgent.h',
'inspector/InstrumentingAgents.h',
- 'inspector/JavaScriptCallFrame.cpp',
- 'inspector/JavaScriptCallFrame.h',
'inspector/JSONParser.cpp',
'inspector/JSONParser.h',
+ 'inspector/JavaScriptCallFrame.cpp',
+ 'inspector/JavaScriptCallFrame.h',
'inspector/NetworkResourcesData.cpp',
'inspector/NetworkResourcesData.h',
'inspector/PageConsoleAgent.cpp',
@@ -1157,6 +1335,8 @@
'inspector/WorkerInspectorController.h',
'inspector/WorkerRuntimeAgent.cpp',
'inspector/WorkerRuntimeAgent.h',
+ 'loader/BeaconLoader.cpp',
+ 'loader/BeaconLoader.h',
'loader/CookieJar.cpp',
'loader/CrossOriginPreflightResultCache.cpp',
'loader/DocumentLoadTiming.cpp',
@@ -1169,12 +1349,13 @@
'loader/EmptyClients.h',
'loader/FormState.cpp',
'loader/FormSubmission.cpp',
- 'loader/FrameFetchContext.h',
'loader/FrameFetchContext.cpp',
+ 'loader/FrameFetchContext.h',
'loader/FrameLoadRequest.h',
'loader/FrameLoader.cpp',
'loader/FrameLoaderStateMachine.cpp',
- 'loader/HistoryController.cpp',
+ 'loader/HistoryItem.cpp',
+ 'loader/HistoryItem.h',
'loader/ImageLoader.cpp',
'loader/ImageLoader.h',
'loader/LinkLoader.cpp',
@@ -1206,146 +1387,71 @@
'loader/ThreadableLoaderClientWrapper.h',
'loader/UniqueIdentifier.cpp',
'loader/UniqueIdentifier.h',
+ 'loader/WorkerLoaderClientBridge.cpp',
+ 'loader/WorkerLoaderClientBridge.h',
+ 'loader/WorkerLoaderClientBridgeSyncHelper.cpp',
+ 'loader/WorkerLoaderClientBridgeSyncHelper.h',
'loader/WorkerThreadableLoader.cpp',
'loader/WorkerThreadableLoader.h',
'loader/appcache/ApplicationCache.cpp',
'loader/appcache/ApplicationCache.h',
+ 'loader/appcache/ApplicationCacheHost.cpp',
'loader/appcache/ApplicationCacheHost.h',
'page/AutoscrollController.cpp',
'page/AutoscrollController.h',
- 'frame/BarProp.cpp',
- 'frame/BarProp.h',
'page/BackForwardClient.h',
'page/Chrome.cpp',
- 'frame/Console.cpp',
- 'frame/Console.h',
- 'frame/ConsoleBase.cpp',
- 'frame/ConsoleBase.h',
- 'frame/ContentSecurityPolicy.cpp',
- 'frame/ContentSecurityPolicyResponseHeaders.cpp',
'page/ContextMenuController.cpp',
'page/ContextMenuProvider.h',
'page/CreateWindow.cpp',
'page/CreateWindow.h',
- 'frame/DOMPoint.h',
- 'frame/DOMSecurityPolicy.cpp',
'page/DOMSelection.cpp',
'page/DOMSelection.h',
- 'frame/DOMTimer.cpp',
- 'frame/DOMTimer.h',
- 'frame/DOMWindow.cpp',
- 'frame/DOMWindow.h',
- 'frame/DOMWindowBase64.cpp',
- 'frame/DOMWindowBase64.h',
- 'frame/DOMWindowEventHandlers.h',
- 'frame/DOMWindowLifecycleNotifier.cpp',
- 'frame/DOMWindowLifecycleNotifier.h',
- 'frame/DOMWindowLifecycleObserver.cpp',
- 'frame/DOMWindowLifecycleObserver.h',
- 'frame/DOMWindowTimers.cpp',
- 'frame/DOMWindowTimers.h',
'page/DOMWindowPagePopup.cpp',
'page/DOMWindowPagePopup.h',
- 'frame/DOMWindowProperty.cpp',
- 'frame/DOMWindowProperty.h',
'page/DragController.cpp',
'page/DragData.cpp',
'page/EventHandler.cpp',
'page/EventSource.cpp',
'page/EventSource.h',
'page/FocusController.cpp',
- 'frame/Frame.cpp',
- 'frame/FrameDestructionObserver.cpp',
- 'frame/FrameDestructionObserver.h',
+ 'page/FocusType.h',
'page/FrameTree.cpp',
- 'frame/FrameView.cpp',
- 'frame/GraphicsLayerDebugInfo.cpp',
- 'frame/History.cpp',
- 'frame/History.h',
- 'frame/ImageBitmap.cpp',
- 'frame/ImageBitmap.h',
- 'frame/Location.cpp',
- 'frame/Location.h',
- 'timing/MemoryInfo.cpp',
+ 'page/InjectedStyleSheets.cpp',
+ 'page/InjectedStyleSheets.h',
'page/MouseEventWithHitTestResults.cpp',
'page/MouseEventWithHitTestResults.h',
- 'frame/SmartClip.cpp',
- 'frame/SmartClip.h',
- 'frame/Navigator.cpp',
- 'frame/Navigator.h',
- 'frame/NavigatorBase.h',
- 'frame/NavigatorID.cpp',
- 'frame/NavigatorID.h',
- 'frame/NavigatorOnLine.h',
- 'frame/SettingsDelegate.cpp',
- 'frame/SettingsDelegate.h',
'page/NetworkStateNotifier.cpp',
'page/NetworkStateNotifier.h',
'page/Page.cpp',
- 'page/PageConsole.cpp',
- 'page/PageGroup.cpp',
- 'page/PageGroupLoadDeferrer.cpp',
- 'page/PageGroupLoadDeferrer.h',
+ 'page/Page.h',
+ 'page/PageAnimator.cpp',
+ 'page/PageAnimator.h',
'page/PageLifecycleNotifier.cpp',
'page/PageLifecycleNotifier.h',
'page/PageLifecycleObserver.cpp',
'page/PageLifecycleObserver.h',
- 'page/PagePopupController.cpp',
- 'page/PagePopupController.h',
'page/PagePopupClient.cpp',
'page/PagePopupClient.h',
+ 'page/PagePopupController.cpp',
+ 'page/PagePopupController.h',
'page/PageScaleConstraints.cpp',
'page/PageScaleConstraints.h',
'page/PageSerializer.cpp',
'page/PageVisibilityState.cpp',
- 'timing/Performance.cpp',
- 'timing/Performance.h',
- 'timing/PerformanceEntry.cpp',
- 'timing/PerformanceEntry.h',
- 'timing/PerformanceMark.h',
- 'timing/PerformanceMeasure.h',
- 'timing/PerformanceNavigation.cpp',
- 'timing/PerformanceNavigation.h',
- 'timing/PerformanceResourceTiming.cpp',
- 'timing/PerformanceResourceTiming.h',
- 'timing/PerformanceTiming.cpp',
- 'timing/PerformanceTiming.h',
- 'timing/PerformanceUserTiming.cpp',
- 'timing/PerformanceUserTiming.h',
'page/PointerLockController.cpp',
'page/PointerLockController.h',
'page/PopupOpeningObserver.h',
'page/PrintContext.cpp',
- 'timing/ResourceTimingInfo.h',
- 'css/RuntimeCSSEnabled.cpp',
- 'css/RuntimeCSSEnabled.h',
- 'frame/Screen.cpp',
- 'frame/Screen.h',
- 'frame/Settings.cpp',
+ 'page/ScopedPageLoadDeferrer.cpp',
+ 'page/ScopedPageLoadDeferrer.h',
'page/SpatialNavigation.cpp',
- 'frame/SuspendableTimer.cpp',
- 'frame/SuspendableTimer.h',
'page/TouchAdjustment.cpp',
'page/TouchAdjustment.h',
'page/TouchDisambiguation.cpp',
'page/TouchDisambiguation.h',
- 'frame/UseCounter.cpp',
'page/WindowFeatures.cpp',
'page/WindowFocusAllowedIndicator.cpp',
- 'workers/WorkerNavigator.cpp',
- 'workers/WorkerNavigator.h',
- 'frame/animation/AnimationBase.cpp',
- 'frame/animation/AnimationBase.h',
- 'frame/animation/AnimationController.cpp',
- 'frame/animation/AnimationControllerPrivate.h',
- 'frame/animation/CompositeAnimation.cpp',
- 'frame/animation/CompositeAnimation.h',
- 'frame/animation/CSSPropertyAnimation.cpp',
- 'frame/animation/CSSPropertyAnimation.h',
- 'frame/animation/ImplicitAnimation.cpp',
- 'frame/animation/ImplicitAnimation.h',
- 'frame/animation/KeyframeAnimation.cpp',
- 'frame/animation/KeyframeAnimation.h',
'page/scrolling/ScrollingConstraints.cpp',
'page/scrolling/ScrollingConstraints.h',
'page/scrolling/ScrollingCoordinator.cpp',
@@ -1365,14 +1471,9 @@
'rendering/AbstractInlineTextBox.h',
'rendering/AutoTableLayout.cpp',
'rendering/AutoTableLayout.h',
- 'rendering/BidiRun.cpp',
'rendering/BidiRun.h',
'rendering/ClipRect.cpp',
'rendering/ClipRect.h',
- 'rendering/CompositedLayerMapping.cpp',
- 'rendering/CompositedLayerMapping.h',
- 'rendering/CompositedLayerMappingPtr.h',
- 'rendering/CompositingReasons.h',
'rendering/CounterNode.cpp',
'rendering/CounterNode.h',
'rendering/EllipsisBox.cpp',
@@ -1389,31 +1490,21 @@
'rendering/FlowThreadController.h',
'rendering/GraphicsContextAnnotator.cpp',
'rendering/GraphicsContextAnnotator.h',
- 'rendering/TextAutosizer.cpp',
- 'rendering/TextAutosizer.h',
- 'rendering/HitTestingTransformState.cpp',
- 'rendering/HitTestingTransformState.h',
'rendering/HitTestLocation.cpp',
'rendering/HitTestLocation.h',
'rendering/HitTestResult.cpp',
+ 'rendering/HitTestingTransformState.cpp',
+ 'rendering/HitTestingTransformState.h',
+ 'rendering/ImageQualityController.cpp',
+ 'rendering/ImageQualityController.h',
'rendering/InlineBox.cpp',
'rendering/InlineFlowBox.cpp',
'rendering/InlineIterator.h',
'rendering/InlineTextBox.cpp',
- 'rendering/ImageQualityController.h',
- 'rendering/ImageQualityController.cpp',
+ 'rendering/LayoutRepainter.cpp',
'rendering/LayoutState.cpp',
'rendering/OrderIterator.cpp',
'rendering/OrderIterator.h',
- 'rendering/LayoutIndicator.cpp',
- 'rendering/LayoutIndicator.h',
- 'rendering/LayoutRectRecorder.cpp',
- 'rendering/LayoutRepainter.cpp',
- 'rendering/LineWidth.cpp',
- 'rendering/LineWidth.h',
- 'rendering/PartialLayoutState.h',
- 'rendering/Pagination.cpp',
- 'rendering/Pagination.h',
'rendering/PointerEventsHitRules.cpp',
'rendering/PointerEventsHitRules.h',
'rendering/RenderApplet.cpp',
@@ -1449,10 +1540,10 @@
'rendering/RenderFrameSet.h',
'rendering/RenderFullScreen.cpp',
'rendering/RenderFullScreen.h',
- 'rendering/RenderGrid.cpp',
- 'rendering/RenderGrid.h',
'rendering/RenderGeometryMap.cpp',
'rendering/RenderGeometryMap.h',
+ 'rendering/RenderGrid.cpp',
+ 'rendering/RenderGrid.h',
'rendering/RenderHTMLCanvas.cpp',
'rendering/RenderHTMLCanvas.h',
'rendering/RenderIFrame.cpp',
@@ -1462,20 +1553,17 @@
'rendering/RenderImageResourceStyleImage.cpp',
'rendering/RenderInline.cpp',
'rendering/RenderInline.h',
- 'rendering/RenderInputSpeech.cpp',
- 'rendering/RenderInputSpeech.h',
'rendering/RenderLayer.cpp',
+ 'rendering/RenderLayerBlendInfo.cpp',
'rendering/RenderLayerClipper.cpp',
- 'rendering/RenderLayerCompositor.cpp',
- 'rendering/RenderLayerCompositor.h',
'rendering/RenderLayerFilterInfo.cpp',
'rendering/RenderLayerFilterInfo.h',
+ 'rendering/RenderLayerModelObject.cpp',
+ 'rendering/RenderLayerReflectionInfo.cpp',
+ 'rendering/RenderLayerRepainter.cpp',
'rendering/RenderLayerScrollableArea.cpp',
'rendering/RenderLayerStackingNode.cpp',
'rendering/RenderLayerStackingNodeIterator.cpp',
- 'rendering/RenderLayerReflectionInfo.cpp',
- 'rendering/RenderLayerRepainter.cpp',
- 'rendering/RenderLayerModelObject.cpp',
'rendering/RenderLineBoxList.cpp',
'rendering/RenderListBox.cpp',
'rendering/RenderListBox.h',
@@ -1494,16 +1582,10 @@
'rendering/RenderMenuList.h',
'rendering/RenderMeter.cpp',
'rendering/RenderMeter.h',
- 'rendering/RenderMultiColumnBlock.cpp',
- 'rendering/RenderMultiColumnBlock.h',
'rendering/RenderMultiColumnFlowThread.cpp',
'rendering/RenderMultiColumnFlowThread.h',
'rendering/RenderMultiColumnSet.cpp',
'rendering/RenderMultiColumnSet.h',
- 'rendering/RenderNamedFlowFragment.cpp',
- 'rendering/RenderNamedFlowFragment.h',
- 'rendering/RenderNamedFlowThread.cpp',
- 'rendering/RenderNamedFlowThread.h',
'rendering/RenderObject.cpp',
'rendering/RenderObjectChildList.cpp',
'rendering/RenderPart.cpp',
@@ -1513,8 +1595,6 @@
'rendering/RenderQuote.h',
'rendering/RenderRegion.cpp',
'rendering/RenderRegion.h',
- 'rendering/RenderRegionSet.cpp',
- 'rendering/RenderRegionSet.h',
'rendering/RenderReplaced.cpp',
'rendering/RenderReplica.cpp',
'rendering/RenderReplica.h',
@@ -1572,8 +1652,6 @@
'rendering/RenderThemeChromiumMac.mm',
'rendering/RenderThemeChromiumSkia.cpp',
'rendering/RenderThemeChromiumSkia.h',
- 'rendering/RenderThemeChromiumWin.cpp',
- 'rendering/RenderThemeChromiumWin.h',
'rendering/RenderTreeAsText.cpp',
'rendering/RenderVTTCue.cpp',
'rendering/RenderVTTCue.h',
@@ -1584,16 +1662,42 @@
'rendering/RenderWordBreak.cpp',
'rendering/RenderWordBreak.h',
'rendering/RootInlineBox.cpp',
- 'rendering/ScrollBehavior.cpp',
+ 'rendering/ScrollAlignment.cpp',
'rendering/SubtreeLayoutScope.cpp',
'rendering/SubtreeLayoutScope.h',
'rendering/TableLayout.h',
+ 'rendering/TextAutosizer.cpp',
+ 'rendering/TextAutosizer.h',
'rendering/TrailingFloatsRootInlineBox.h',
'rendering/VerticalPositionCache.h',
'rendering/break_lines.cpp',
'rendering/break_lines.h',
- 'rendering/animation/WebAnimationProvider.cpp',
- 'rendering/animation/WebAnimationProvider.h',
+ 'rendering/compositing/CompositedLayerMapping.cpp',
+ 'rendering/compositing/CompositedLayerMapping.h',
+ 'rendering/compositing/CompositedLayerMappingPtr.h',
+ 'rendering/compositing/CompositingInputsUpdater.cpp',
+ 'rendering/compositing/CompositingInputsUpdater.h',
+ 'rendering/compositing/CompositingLayerAssigner.cpp',
+ 'rendering/compositing/CompositingLayerAssigner.h',
+ 'rendering/compositing/CompositingReasonFinder.cpp',
+ 'rendering/compositing/CompositingReasonFinder.h',
+ 'rendering/compositing/CompositingRequirementsUpdater.cpp',
+ 'rendering/compositing/CompositingRequirementsUpdater.h',
+ 'rendering/compositing/CompositingState.h',
+ 'rendering/compositing/CompositingTriggers.h',
+ 'rendering/compositing/GraphicsLayerTreeBuilder.cpp',
+ 'rendering/compositing/GraphicsLayerTreeBuilder.h',
+ 'rendering/compositing/GraphicsLayerUpdater.cpp',
+ 'rendering/compositing/GraphicsLayerUpdater.h',
+ 'rendering/compositing/RenderLayerCompositor.cpp',
+ 'rendering/compositing/RenderLayerCompositor.h',
+ 'rendering/line/BreakingContext.cpp',
+ 'rendering/line/LineBreaker.cpp',
+ 'rendering/line/LineBreaker.h',
+ 'rendering/line/LineWidth.cpp',
+ 'rendering/line/LineWidth.h',
+ 'rendering/line/TrailingObjects.cpp',
+ 'rendering/line/TrailingObjects.h',
'rendering/shapes/BoxShape.cpp',
'rendering/shapes/BoxShape.h',
'rendering/shapes/PolygonShape.cpp',
@@ -1604,13 +1708,10 @@
'rendering/shapes/RectangleShape.h',
'rendering/shapes/Shape.cpp',
'rendering/shapes/Shape.h',
- 'rendering/shapes/ShapeInfo.cpp',
- 'rendering/shapes/ShapeInfo.h',
- 'rendering/shapes/ShapeInsideInfo.cpp',
- 'rendering/shapes/ShapeInsideInfo.h',
'rendering/shapes/ShapeInterval.h',
'rendering/shapes/ShapeOutsideInfo.cpp',
'rendering/shapes/ShapeOutsideInfo.h',
+ 'rendering/style/AppliedTextDecoration.cpp',
'rendering/style/BasicShapes.cpp',
'rendering/style/BorderImageLength.h',
'rendering/style/BorderImageLengthBox.h',
@@ -1619,6 +1720,8 @@
'rendering/style/CounterDirectives.cpp',
'rendering/style/FillLayer.cpp',
'rendering/style/GridCoordinate.h',
+ 'rendering/style/GridResolvedPosition.cpp',
+ 'rendering/style/GridResolvedPosition.h',
'rendering/style/KeyframeList.cpp',
'rendering/style/KeyframeList.h',
'rendering/style/NinePieceImage.cpp',
@@ -1632,15 +1735,9 @@
'rendering/style/ShadowList.h',
'rendering/style/StyleBackgroundData.cpp',
'rendering/style/StyleBoxData.cpp',
+ 'rendering/style/StyleDeprecatedFlexibleBoxData.cpp',
'rendering/style/StyleFetchedImage.cpp',
'rendering/style/StyleFetchedImageSet.cpp',
- 'rendering/style/StyleFetchedShader.h',
- 'rendering/style/StyleFetchedShader.cpp',
- 'rendering/style/StyleCustomFilterProgramCache.cpp',
- 'rendering/style/StyleCustomFilterProgramCache.h',
- 'rendering/style/StyleCustomFilterProgram.cpp',
- 'rendering/style/StyleCustomFilterProgram.h',
- 'rendering/style/StyleDeprecatedFlexibleBoxData.cpp',
'rendering/style/StyleFilterData.cpp',
'rendering/style/StyleFlexibleBoxData.cpp',
'rendering/style/StyleGeneratedImage.cpp',
@@ -1650,13 +1747,12 @@
'rendering/style/StyleMarqueeData.cpp',
'rendering/style/StyleMultiColData.cpp',
'rendering/style/StylePendingImage.h',
- 'rendering/style/StylePendingShader.h',
'rendering/style/StyleRareInheritedData.cpp',
'rendering/style/StyleRareNonInheritedData.cpp',
- 'rendering/style/StyleShader.h',
'rendering/style/StyleSurroundData.cpp',
'rendering/style/StyleTransformData.cpp',
'rendering/style/StyleVisualData.cpp',
+ 'rendering/style/StyleWillChangeData.cpp',
'rendering/svg/SVGInlineFlowBox.cpp',
'rendering/svg/SVGInlineFlowBox.h',
'rendering/svg/SVGInlineTextBox.cpp',
@@ -1700,22 +1796,30 @@
'rendering/svg/SVGTextQuery.h',
'rendering/svg/SVGTextRunRenderingContext.cpp',
'rendering/svg/SVGTextRunRenderingContext.h',
- 'speech/SpeechInput.cpp',
- 'speech/SpeechInput.h',
- 'speech/SpeechInputClient.h',
- 'speech/SpeechInputEvent.cpp',
- 'speech/SpeechInputEvent.h',
- 'speech/SpeechInputListener.h',
- 'speech/SpeechInputResult.cpp',
- 'speech/SpeechInputResult.h',
- 'speech/SpeechInputResultList.cpp',
- 'speech/SpeechInputResultList.h',
'storage/Storage.cpp',
'storage/Storage.h',
+ 'storage/StorageArea.cpp',
'storage/StorageArea.h',
'storage/StorageEvent.cpp',
'storage/StorageEvent.h',
+ 'storage/StorageNamespace.cpp',
'storage/StorageNamespace.h',
+ 'timing/MemoryInfo.cpp',
+ 'timing/Performance.cpp',
+ 'timing/Performance.h',
+ 'timing/PerformanceEntry.cpp',
+ 'timing/PerformanceEntry.h',
+ 'timing/PerformanceMark.h',
+ 'timing/PerformanceMeasure.h',
+ 'timing/PerformanceNavigation.cpp',
+ 'timing/PerformanceNavigation.h',
+ 'timing/PerformanceResourceTiming.cpp',
+ 'timing/PerformanceResourceTiming.h',
+ 'timing/PerformanceTiming.cpp',
+ 'timing/PerformanceTiming.h',
+ 'timing/PerformanceUserTiming.cpp',
+ 'timing/PerformanceUserTiming.h',
+ 'timing/ResourceTimingInfo.h',
'workers/AbstractWorker.cpp',
'workers/AbstractWorker.h',
'workers/DedicatedWorkerGlobalScope.cpp',
@@ -1736,15 +1840,17 @@
'workers/WorkerConsole.h',
'workers/WorkerEventQueue.cpp',
'workers/WorkerEventQueue.h',
- 'workers/WorkerGlobalScopeProxy.h',
- 'workers/WorkerGlobalScopeProxyProvider.h',
- 'workers/WorkerGlobalScopeProxyProvider.cpp',
'workers/WorkerGlobalScope.cpp',
'workers/WorkerGlobalScope.h',
+ 'workers/WorkerGlobalScopeProxy.h',
+ 'workers/WorkerGlobalScopeProxyProvider.cpp',
+ 'workers/WorkerGlobalScopeProxyProvider.h',
'workers/WorkerLoaderProxy.h',
'workers/WorkerLocation.h',
'workers/WorkerMessagingProxy.cpp',
'workers/WorkerMessagingProxy.h',
+ 'workers/WorkerNavigator.cpp',
+ 'workers/WorkerNavigator.h',
'workers/WorkerObjectProxy.cpp',
'workers/WorkerObjectProxy.h',
'workers/WorkerReportingProxy.h',
@@ -1755,16 +1861,10 @@
'workers/WorkerThread.cpp',
'workers/WorkerThreadStartupData.cpp',
'workers/WorkerThreadStartupData.h',
- 'xml/parser/MarkupTokenizerInlines.h',
- 'xml/parser/XMLDocumentParser.cpp',
- 'xml/parser/XMLDocumentParser.h',
- 'xml/parser/XMLDocumentParserScope.cpp',
- 'xml/parser/XMLDocumentParserScope.h',
- 'xml/parser/XMLParserInput.h',
- 'xml/DocumentXPathEvaluator.cpp',
- 'xml/DocumentXPathEvaluator.h',
'xml/DOMParser.cpp',
'xml/DOMParser.h',
+ 'xml/DocumentXPathEvaluator.cpp',
+ 'xml/DocumentXPathEvaluator.h',
'xml/NativeXPathNSResolver.cpp',
'xml/NativeXPathNSResolver.h',
'xml/XMLErrors.cpp',
@@ -1820,6 +1920,14 @@
'xml/XSLTProcessorLibxslt.cpp',
'xml/XSLTUnicodeSort.cpp',
'xml/XSLTUnicodeSort.h',
+ 'xml/parser/MarkupTokenizerInlines.h',
+ 'xml/parser/SharedBufferReader.cpp',
+ 'xml/parser/SharedBufferReader.h',
+ 'xml/parser/XMLDocumentParser.cpp',
+ 'xml/parser/XMLDocumentParser.h',
+ 'xml/parser/XMLDocumentParserScope.cpp',
+ 'xml/parser/XMLDocumentParserScope.h',
+ 'xml/parser/XMLParserInput.h',
],
'webcore_dom_files': [
'dom/ActiveDOMObject.cpp',
@@ -1830,21 +1938,21 @@
'dom/CDATASection.h',
'dom/CSSSelectorWatch.cpp',
'dom/CharacterData.cpp',
+ 'dom/ChildFrameDisconnector.cpp',
+ 'dom/ChildFrameDisconnector.h',
'dom/ChildListMutationScope.cpp',
'dom/ChildListMutationScope.h',
'dom/ChildNodeList.cpp',
'dom/ChildNodeList.h',
- 'dom/ClassNodeList.cpp',
- 'dom/ClassNodeList.h',
+ 'dom/ClassCollection.cpp',
+ 'dom/ClassCollection.h',
'dom/ClientRect.cpp',
'dom/ClientRect.h',
'dom/ClientRectList.cpp',
'dom/ClientRectList.h',
- 'dom/Clipboard.cpp',
'dom/Comment.cpp',
'dom/Comment.h',
'dom/ContainerNode.cpp',
- 'dom/ContainerNodeAlgorithms.cpp',
'dom/ContainerNodeAlgorithms.h',
'dom/ContextFeatures.cpp',
'dom/ContextFeatures.h',
@@ -1853,15 +1961,31 @@
'dom/ContextLifecycleObserver.cpp',
'dom/ContextLifecycleObserver.h',
'dom/CrossThreadTask.h',
+ 'dom/DOMError.cpp',
+ 'dom/DOMError.h',
+ 'dom/DOMException.cpp',
+ 'dom/DOMException.h',
+ 'dom/DOMImplementation.cpp',
+ 'dom/DOMSettableTokenList.cpp',
+ 'dom/DOMSettableTokenList.h',
+ 'dom/DOMStringList.cpp',
+ 'dom/DOMStringList.h',
+ 'dom/DOMStringMap.cpp',
+ 'dom/DOMStringMap.h',
+ 'dom/DOMTokenList.cpp',
+ 'dom/DOMTokenList.h',
+ 'dom/DOMURL.cpp',
+ 'dom/DOMURL.h',
+ 'dom/DOMURLUtils.cpp',
+ 'dom/DOMURLUtils.h',
+ 'dom/DOMURLUtilsReadOnly.cpp',
+ 'dom/DOMURLUtilsReadOnly.h',
'dom/DatasetDOMStringMap.cpp',
'dom/DatasetDOMStringMap.h',
- 'dom/DataTransferItem.cpp',
- 'dom/DataTransferItem.h',
- 'dom/DataTransferItemList.cpp',
- 'dom/DataTransferItemList.h',
'dom/DecodedDataDocumentParser.cpp',
'dom/DecodedDataDocumentParser.h',
'dom/Document.cpp',
+ 'dom/DocumentEncodingData.cpp',
'dom/DocumentEncodingData.h',
'dom/DocumentFragment.cpp',
'dom/DocumentFullscreen.cpp',
@@ -1880,43 +2004,25 @@
'dom/DocumentOrderedList.h',
'dom/DocumentOrderedMap.cpp',
'dom/DocumentParser.cpp',
- 'dom/DocumentSharedObjectPool.cpp',
'dom/DocumentStyleSheetCollection.cpp',
'dom/DocumentStyleSheetCollection.h',
+ 'dom/DocumentStyleSheetCollector.cpp',
+ 'dom/DocumentStyleSheetCollector.h',
'dom/DocumentType.cpp',
- 'dom/DOMError.cpp',
- 'dom/DOMError.h',
- 'dom/DOMException.cpp',
- 'dom/DOMException.h',
- 'dom/DOMImplementation.cpp',
- 'dom/DOMNamedFlowCollection.cpp',
- 'dom/DOMNamedFlowCollection.h',
- 'dom/DOMSettableTokenList.cpp',
- 'dom/DOMSettableTokenList.h',
- 'dom/DOMStringList.cpp',
- 'dom/DOMStringList.h',
- 'dom/DOMStringMap.cpp',
- 'dom/DOMStringMap.h',
- 'dom/DOMTokenList.cpp',
- 'dom/DOMTokenList.h',
- 'dom/DOMURL.cpp',
- 'dom/DOMURL.h',
- 'dom/DOMURLUtils.cpp',
- 'dom/DOMURLUtils.h',
- 'dom/DOMURLUtilsReadOnly.cpp',
- 'dom/DOMURLUtilsReadOnly.h',
'dom/Element.cpp',
'dom/Element.h',
'dom/ElementData.cpp',
'dom/ElementData.h',
+ 'dom/ElementDataCache.cpp',
+ 'dom/ElementDataCache.h',
'dom/ElementRareData.cpp',
'dom/ElementRareData.h',
'dom/ElementTraversal.h',
- 'dom/Entity.h',
- 'dom/ExecutionContextTask.cpp',
+ 'dom/EmptyNodeList.cpp',
+ 'dom/EmptyNodeList.h',
+ 'dom/ExecutionContext.cpp',
+ 'dom/ExecutionContext.h',
'dom/ExecutionContextTask.h',
- 'dom/MainThreadTaskRunner.cpp',
- 'dom/MainThreadTaskRunner.h',
'dom/FullscreenElementStack.cpp',
'dom/FullscreenElementStack.h',
'dom/GlobalEventHandlers.h',
@@ -1927,8 +2033,14 @@
'dom/IdTargetObserverRegistry.cpp',
'dom/IdTargetObserverRegistry.h',
'dom/IgnoreDestructiveWriteCountIncrementer.h',
+ 'dom/IncrementLoadEventDelayCount.cpp',
+ 'dom/IncrementLoadEventDelayCount.h',
'dom/LiveNodeList.cpp',
'dom/LiveNodeList.h',
+ 'dom/LiveNodeListBase.cpp',
+ 'dom/LiveNodeListBase.h',
+ 'dom/MainThreadTaskRunner.cpp',
+ 'dom/MainThreadTaskRunner.h',
'dom/MessageChannel.cpp',
'dom/MessageChannel.h',
'dom/MessagePort.cpp',
@@ -1943,32 +2055,27 @@
'dom/MutationObserverRegistration.h',
'dom/MutationRecord.cpp',
'dom/MutationRecord.h',
- 'dom/NamedFlow.cpp',
- 'dom/NamedFlow.h',
- 'dom/NamedFlowCollection.cpp',
- 'dom/NamedFlowCollection.h',
+ 'dom/NameNodeList.cpp',
+ 'dom/NameNodeList.h',
'dom/NamedNodeMap.cpp',
'dom/NamedNodesCollection.cpp',
'dom/NamedNodesCollection.h',
- 'dom/NameNodeList.cpp',
- 'dom/NameNodeList.h',
'dom/Node.cpp',
- 'dom/NodeChildRemovalTracker.h',
'dom/NodeChildRemovalTracker.cpp',
+ 'dom/NodeChildRemovalTracker.h',
'dom/NodeFilter.cpp',
'dom/NodeFilter.h',
'dom/NodeFilterCondition.cpp',
'dom/NodeFilterCondition.h',
'dom/NodeIterator.cpp',
'dom/NodeIterator.h',
- 'dom/NodeList.cpp',
+ 'dom/NodeIteratorBase.cpp',
+ 'dom/NodeIteratorBase.h',
'dom/NodeRareData.cpp',
'dom/NodeRareData.h',
- 'dom/NodeRenderingContext.cpp',
- 'dom/NodeRenderingContext.h',
+ 'dom/NodeRenderStyle.h',
'dom/NodeRenderingTraversal.cpp',
'dom/NodeRenderingTraversal.h',
- 'dom/NodeRenderStyle.h',
'dom/NodeTraversal.cpp',
'dom/NodeTraversal.h',
'dom/NodeWithIndex.h',
@@ -1978,72 +2085,33 @@
'dom/Position.cpp',
'dom/PositionIterator.cpp',
'dom/PositionIterator.h',
- 'dom/PostAttachCallbacks.cpp',
- 'dom/PostAttachCallbacks.h',
'dom/PresentationAttributeStyle.cpp',
'dom/PresentationAttributeStyle.h',
'dom/ProcessingInstruction.cpp',
'dom/ProcessingInstruction.h',
- 'dom/Promise.h',
'dom/PseudoElement.cpp',
'dom/QualifiedName.cpp',
'dom/Range.cpp',
'dom/RawDataDocumentParser.h',
+ 'dom/RenderTreeBuilder.cpp',
+ 'dom/RenderTreeBuilder.h',
'dom/RequestAnimationFrameCallback.h',
- 'dom/SandboxFlags.h',
'dom/SandboxFlags.cpp',
+ 'dom/SandboxFlags.h',
+ 'dom/ScriptForbiddenScope.cpp',
+ 'dom/ScriptForbiddenScope.h',
+ 'dom/ScriptLoader.cpp',
+ 'dom/ScriptLoader.h',
+ 'dom/ScriptRunner.cpp',
+ 'dom/ScriptRunner.h',
'dom/ScriptableDocumentParser.cpp',
'dom/ScriptableDocumentParser.h',
'dom/ScriptedAnimationController.cpp',
'dom/ScriptedAnimationController.h',
- 'dom/ExecutionContext.cpp',
- 'dom/ScriptLoader.cpp',
- 'dom/ScriptLoader.h',
- 'dom/ScriptRunner.cpp',
'dom/SecurityContext.cpp',
'dom/SecurityContext.h',
'dom/SelectorQuery.cpp',
'dom/SelectorQuery.h',
- 'dom/custom/CustomElement.cpp',
- 'dom/custom/CustomElement.h',
- 'dom/custom/CustomElementBaseElementQueue.cpp',
- 'dom/custom/CustomElementBaseElementQueue.h',
- 'dom/custom/CustomElementCallbackDispatcher.cpp',
- 'dom/custom/CustomElementCallbackDispatcher.h',
- 'dom/custom/CustomElementCallbackInvocation.cpp',
- 'dom/custom/CustomElementCallbackInvocation.h',
- 'dom/custom/CustomElementCallbackQueue.cpp',
- 'dom/custom/CustomElementCallbackQueue.h',
- 'dom/custom/CustomElementCallbackScheduler.cpp',
- 'dom/custom/CustomElementCallbackScheduler.h',
- 'dom/custom/CustomElementDefinition.cpp',
- 'dom/custom/CustomElementDefinition.h',
- 'dom/custom/CustomElementDescriptor.h',
- 'dom/custom/CustomElementDescriptorHash.h',
- 'dom/custom/CustomElementException.cpp',
- 'dom/custom/CustomElementException.h',
- 'dom/custom/CustomElementLifecycleCallbacks.h',
- 'dom/custom/CustomElementObserver.cpp',
- 'dom/custom/CustomElementObserver.h',
- 'dom/custom/CustomElementRegistrationContext.cpp',
- 'dom/custom/CustomElementRegistrationContext.h',
- 'dom/custom/CustomElementRegistry.cpp',
- 'dom/custom/CustomElementRegistry.h',
- 'dom/custom/CustomElementUpgradeCandidateMap.cpp',
- 'dom/custom/CustomElementUpgradeCandidateMap.h',
- 'dom/shadow/ComposedTreeWalker.cpp',
- 'dom/shadow/ComposedTreeWalker.h',
- 'dom/shadow/ContentDistribution.cpp',
- 'dom/shadow/ContentDistribution.h',
- 'dom/shadow/ElementShadow.cpp',
- 'dom/shadow/ElementShadow.h',
- 'dom/shadow/InsertionPoint.cpp',
- 'dom/shadow/InsertionPoint.h',
- 'dom/shadow/SelectRuleFeatureSet.cpp',
- 'dom/shadow/SelectRuleFeatureSet.h',
- 'dom/shadow/ShadowRoot.cpp',
- 'dom/shadow/ShadowRoot.h',
- 'dom/shadow/ShadowRootRareData.h',
'dom/ShadowTreeStyleSheetCollection.cpp',
'dom/ShadowTreeStyleSheetCollection.h',
'dom/SimulatedClickOptions.h',
@@ -2056,12 +2124,14 @@
'dom/StyleElement.h',
'dom/StyleEngine.cpp',
'dom/StyleEngine.h',
+ 'dom/StyleSheetCandidate.cpp',
+ 'dom/StyleSheetCandidate.h',
'dom/StyleSheetCollection.cpp',
'dom/StyleSheetCollection.h',
'dom/StyleSheetScopingNodeList.cpp',
'dom/StyleSheetScopingNodeList.h',
- 'dom/TagNodeList.cpp',
- 'dom/TagNodeList.h',
+ 'dom/TagCollection.cpp',
+ 'dom/TagCollection.h',
'dom/Text.cpp',
'dom/TextLinkColors.cpp',
'dom/TextLinkColors.h',
@@ -2071,12 +2141,12 @@
'dom/TouchList.h',
'dom/TransformSource.h',
'dom/TransformSourceLibxslt.cpp',
- 'dom/Traversal.cpp',
- 'dom/Traversal.h',
'dom/TreeScope.cpp',
'dom/TreeScope.h',
'dom/TreeScopeAdopter.cpp',
'dom/TreeScopeAdopter.h',
+ 'dom/TreeScopeStyleSheetCollection.cpp',
+ 'dom/TreeScopeStyleSheetCollection.h',
'dom/TreeShared.h',
'dom/TreeWalker.cpp',
'dom/TreeWalker.h',
@@ -2086,10 +2156,69 @@
'dom/ViewportDescription.h',
'dom/VisitedLinkState.cpp',
'dom/VisitedLinkState.h',
- 'dom/WheelController.cpp',
- 'dom/WheelController.h',
+ 'dom/WeakNodeMap.cpp',
+ 'dom/WeakNodeMap.h',
+ 'dom/XMLDocument.cpp',
+ 'dom/XMLDocument.h',
+ 'dom/custom/CustomElement.cpp',
+ 'dom/custom/CustomElement.h',
+ 'dom/custom/CustomElementAsyncImportMicrotaskQueue.cpp',
+ 'dom/custom/CustomElementAsyncImportMicrotaskQueue.h',
+ 'dom/custom/CustomElementCallbackDispatcher.cpp',
+ 'dom/custom/CustomElementCallbackDispatcher.h',
+ 'dom/custom/CustomElementCallbackInvocation.cpp',
+ 'dom/custom/CustomElementCallbackInvocation.h',
+ 'dom/custom/CustomElementCallbackQueue.cpp',
+ 'dom/custom/CustomElementCallbackQueue.h',
+ 'dom/custom/CustomElementDefinition.cpp',
+ 'dom/custom/CustomElementDefinition.h',
+ 'dom/custom/CustomElementDescriptor.h',
+ 'dom/custom/CustomElementDescriptorHash.h',
+ 'dom/custom/CustomElementException.cpp',
+ 'dom/custom/CustomElementException.h',
+ 'dom/custom/CustomElementLifecycleCallbacks.h',
+ 'dom/custom/CustomElementMicrotaskDispatcher.cpp',
+ 'dom/custom/CustomElementMicrotaskDispatcher.h',
+ 'dom/custom/CustomElementMicrotaskImportStep.cpp',
+ 'dom/custom/CustomElementMicrotaskImportStep.h',
+ 'dom/custom/CustomElementMicrotaskQueueBase.cpp',
+ 'dom/custom/CustomElementMicrotaskQueueBase.h',
+ 'dom/custom/CustomElementMicrotaskResolutionStep.cpp',
+ 'dom/custom/CustomElementMicrotaskResolutionStep.h',
+ 'dom/custom/CustomElementMicrotaskStep.h',
+ 'dom/custom/CustomElementMicrotaskStepDispatcher.cpp',
+ 'dom/custom/CustomElementMicrotaskStepDispatcher.h',
+ 'dom/custom/CustomElementObserver.cpp',
+ 'dom/custom/CustomElementObserver.h',
+ 'dom/custom/CustomElementProcessingStep.h',
+ 'dom/custom/CustomElementRegistrationContext.cpp',
+ 'dom/custom/CustomElementRegistrationContext.h',
+ 'dom/custom/CustomElementRegistry.cpp',
+ 'dom/custom/CustomElementRegistry.h',
+ 'dom/custom/CustomElementScheduler.cpp',
+ 'dom/custom/CustomElementScheduler.h',
+ 'dom/custom/CustomElementSyncMicrotaskQueue.cpp',
+ 'dom/custom/CustomElementSyncMicrotaskQueue.h',
+ 'dom/custom/CustomElementUpgradeCandidateMap.cpp',
+ 'dom/custom/CustomElementUpgradeCandidateMap.h',
+ 'dom/shadow/ComposedTreeWalker.cpp',
+ 'dom/shadow/ComposedTreeWalker.h',
+ 'dom/shadow/ContentDistribution.cpp',
+ 'dom/shadow/ContentDistribution.h',
+ 'dom/shadow/ElementShadow.cpp',
+ 'dom/shadow/ElementShadow.h',
+ 'dom/shadow/InsertionPoint.cpp',
+ 'dom/shadow/InsertionPoint.h',
+ 'dom/shadow/SelectRuleFeatureSet.cpp',
+ 'dom/shadow/SelectRuleFeatureSet.h',
+ 'dom/shadow/ShadowRoot.cpp',
+ 'dom/shadow/ShadowRoot.h',
+ 'dom/shadow/ShadowRootRareData.h',
+ 'events/AnimationPlayerEvent.cpp',
+ 'events/AnimationPlayerEvent.h',
+ 'events/ApplicationCacheErrorEvent.cpp',
+ 'events/ApplicationCacheErrorEvent.h',
'events/AutocompleteErrorEvent.h',
- 'events/BeforeLoadEvent.h',
'events/BeforeTextInsertedEvent.cpp',
'events/BeforeTextInsertedEvent.h',
'events/BeforeUnloadEvent.cpp',
@@ -2105,18 +2234,14 @@
'events/ErrorEvent.cpp',
'events/ErrorEvent.h',
'events/Event.cpp',
- 'events/EventContext.cpp',
- 'events/EventContext.h',
- 'events/EventDispatcher.cpp',
- 'events/EventDispatcher.h',
'events/EventDispatchMediator.cpp',
'events/EventDispatchMediator.h',
+ 'events/EventDispatcher.cpp',
+ 'events/EventDispatcher.h',
'events/EventListenerMap.cpp',
'events/EventPath.cpp',
'events/EventPath.h',
'events/EventQueue.h',
- 'events/EventRetargeter.cpp',
- 'events/EventRetargeter.h',
'events/EventSender.h',
'events/EventTarget.cpp',
'events/FocusEvent.cpp',
@@ -2135,6 +2260,8 @@
'events/MutationEvent.h',
'events/NavigatorEvents.cpp',
'events/NavigatorEvents.h',
+ 'events/NodeEventContext.cpp',
+ 'events/NodeEventContext.h',
'events/OverflowEvent.cpp',
'events/OverflowEvent.h',
'events/PageTransitionEvent.cpp',
@@ -2153,8 +2280,12 @@
'events/ThreadLocalEventNames.h',
'events/TouchEvent.cpp',
'events/TouchEvent.h',
+ 'events/TouchEventContext.cpp',
+ 'events/TouchEventContext.h',
'events/TransitionEvent.cpp',
'events/TransitionEvent.h',
+ 'events/TreeScopeEventContext.cpp',
+ 'events/TreeScopeEventContext.h',
'events/UIEvent.cpp',
'events/UIEventWithKeyState.cpp',
'events/WebKitAnimationEvent.cpp',
@@ -2169,6 +2300,8 @@
'html/ClassList.h',
'html/DOMFormData.cpp',
'html/DOMFormData.h',
+ 'html/DocumentNameCollection.cpp',
+ 'html/DocumentNameCollection.h',
'html/FormAssociatedElement.cpp',
'html/FormDataList.cpp',
'html/FormDataList.h',
@@ -2193,6 +2326,8 @@
'html/HTMLCanvasElement.cpp',
'html/HTMLCanvasElement.h',
'html/HTMLCollection.cpp',
+ 'html/HTMLContentElement.cpp',
+ 'html/HTMLContentElement.h',
'html/HTMLDListElement.cpp',
'html/HTMLDListElement.h',
'html/HTMLDataListElement.cpp',
@@ -2215,10 +2350,10 @@
'html/HTMLFieldSetElement.h',
'html/HTMLFontElement.cpp',
'html/HTMLFontElement.h',
- 'html/HTMLFormControlsCollection.cpp',
- 'html/HTMLFormControlsCollection.h',
'html/HTMLFormControlElement.cpp',
'html/HTMLFormControlElementWithState.cpp',
+ 'html/HTMLFormControlsCollection.cpp',
+ 'html/HTMLFormControlsCollection.h',
'html/HTMLFormElement.cpp',
'html/HTMLFrameElement.cpp',
'html/HTMLFrameElementBase.cpp',
@@ -2237,18 +2372,6 @@
'html/HTMLImageElement.h',
'html/HTMLImageLoader.cpp',
'html/HTMLImageLoader.h',
- 'html/HTMLImport.cpp',
- 'html/HTMLImport.h',
- 'html/HTMLImportsController.cpp',
- 'html/HTMLImportsController.h',
- 'html/HTMLImportChild.cpp',
- 'html/HTMLImportChild.h',
- 'html/HTMLImportChildClient.h',
- 'html/HTMLImportLoader.cpp',
- 'html/HTMLImportLoader.h',
- 'html/HTMLImportLoaderClient.h',
- 'html/HTMLImportResourceOwner.cpp',
- 'html/HTMLImportResourceOwner.h',
'html/HTMLInputElement.cpp',
'html/HTMLKeygenElement.cpp',
'html/HTMLKeygenElement.h',
@@ -2265,6 +2388,8 @@
'html/HTMLMarqueeElement.cpp',
'html/HTMLMarqueeElement.h',
'html/HTMLMediaElement.cpp',
+ 'html/HTMLMediaSource.cpp',
+ 'html/HTMLMediaSource.h',
'html/HTMLMenuElement.cpp',
'html/HTMLMenuElement.h',
'html/HTMLMetaElement.h',
@@ -2274,6 +2399,10 @@
'html/HTMLModElement.h',
'html/HTMLNameCollection.cpp',
'html/HTMLNameCollection.h',
+ 'html/HTMLNoEmbedElement.cpp',
+ 'html/HTMLNoEmbedElement.h',
+ 'html/HTMLNoScriptElement.cpp',
+ 'html/HTMLNoScriptElement.h',
'html/HTMLOListElement.cpp',
'html/HTMLOListElement.h',
'html/HTMLObjectElement.cpp',
@@ -2290,6 +2419,7 @@
'html/HTMLParagraphElement.h',
'html/HTMLParamElement.cpp',
'html/HTMLParamElement.h',
+ 'html/HTMLPictureElement.cpp',
'html/HTMLPlugInElement.cpp',
'html/HTMLPlugInElement.h',
'html/HTMLPreElement.cpp',
@@ -2298,11 +2428,17 @@
'html/HTMLProgressElement.h',
'html/HTMLQuoteElement.cpp',
'html/HTMLQuoteElement.h',
+ 'html/HTMLRTElement.cpp',
+ 'html/HTMLRTElement.h',
+ 'html/HTMLRubyElement.cpp',
+ 'html/HTMLRubyElement.h',
'html/HTMLScriptElement.cpp',
'html/HTMLScriptElement.h',
'html/HTMLSelectElement.cpp',
'html/HTMLSelectElement.h',
'html/HTMLSelectElementWin.cpp',
+ 'html/HTMLShadowElement.cpp',
+ 'html/HTMLShadowElement.h',
'html/HTMLSourceElement.cpp',
'html/HTMLSourceElement.h',
'html/HTMLSpanElement.cpp',
@@ -2340,6 +2476,8 @@
'html/HTMLVideoElement.h',
'html/HTMLViewSourceDocument.cpp',
'html/HTMLViewSourceDocument.h',
+ 'html/HTMLWBRElement.cpp',
+ 'html/HTMLWBRElement.h',
'html/ImageData.cpp',
'html/ImageData.h',
'html/ImageDocument.cpp',
@@ -2347,8 +2485,8 @@
'html/LabelableElement.cpp',
'html/LabelsNodeList.cpp',
'html/LabelsNodeList.h',
- 'html/LinkImport.cpp',
- 'html/LinkImport.h',
+ 'html/LinkManifest.cpp',
+ 'html/LinkManifest.h',
'html/LinkRelAttribute.cpp',
'html/LinkRelAttribute.h',
'html/LinkResource.cpp',
@@ -2363,12 +2501,10 @@
'html/MediaKeyError.h',
'html/MediaKeyEvent.cpp',
'html/MediaKeyEvent.h',
- 'html/HTMLMediaSource.cpp',
- 'html/HTMLMediaSource.h',
'html/PluginDocument.cpp',
'html/PluginDocument.h',
- 'html/PublicURLManager.h',
'html/PublicURLManager.cpp',
+ 'html/PublicURLManager.h',
'html/RadioNodeList.cpp',
'html/RadioNodeList.h',
'html/TextDocument.cpp',
@@ -2379,6 +2515,8 @@
'html/URLRegistry.h',
'html/ValidityState.cpp',
'html/ValidityState.h',
+ 'html/WindowNameCollection.cpp',
+ 'html/WindowNameCollection.h',
'html/canvas/ANGLEInstancedArrays.cpp',
'html/canvas/ANGLEInstancedArrays.h',
'html/canvas/Canvas2DContextAttributes.cpp',
@@ -2387,6 +2525,7 @@
'html/canvas/CanvasContextAttributes.h',
'html/canvas/CanvasGradient.cpp',
'html/canvas/CanvasGradient.h',
+ 'html/canvas/CanvasImageSource.h',
'html/canvas/CanvasPathMethods.cpp',
'html/canvas/CanvasPathMethods.h',
'html/canvas/CanvasPattern.cpp',
@@ -2399,11 +2538,16 @@
'html/canvas/CanvasStyle.h',
'html/canvas/DataView.cpp',
'html/canvas/DataView.h',
- 'html/canvas/DOMPath.h',
+ 'html/canvas/EXTBlendMinMax.cpp',
+ 'html/canvas/EXTBlendMinMax.h',
'html/canvas/EXTFragDepth.cpp',
'html/canvas/EXTFragDepth.h',
+ 'html/canvas/EXTShaderTextureLOD.cpp',
+ 'html/canvas/EXTShaderTextureLOD.h',
'html/canvas/EXTTextureFilterAnisotropic.cpp',
'html/canvas/EXTTextureFilterAnisotropic.h',
+ 'html/canvas/OESElementIndexUint.cpp',
+ 'html/canvas/OESElementIndexUint.h',
'html/canvas/OESStandardDerivatives.cpp',
'html/canvas/OESStandardDerivatives.h',
'html/canvas/OESTextureFloat.cpp',
@@ -2416,13 +2560,14 @@
'html/canvas/OESTextureHalfFloatLinear.h',
'html/canvas/OESVertexArrayObject.cpp',
'html/canvas/OESVertexArrayObject.h',
- 'html/canvas/OESElementIndexUint.cpp',
- 'html/canvas/OESElementIndexUint.h',
+ 'html/canvas/Path2D.h',
'html/canvas/WebGLActiveInfo.h',
'html/canvas/WebGLBuffer.cpp',
'html/canvas/WebGLBuffer.h',
'html/canvas/WebGLCompressedTextureATC.cpp',
'html/canvas/WebGLCompressedTextureATC.h',
+ 'html/canvas/WebGLCompressedTextureETC1.cpp',
+ 'html/canvas/WebGLCompressedTextureETC1.h',
'html/canvas/WebGLCompressedTexturePVRTC.cpp',
'html/canvas/WebGLCompressedTexturePVRTC.h',
'html/canvas/WebGLCompressedTextureS3TC.cpp',
@@ -2445,6 +2590,7 @@
'html/canvas/WebGLDrawBuffers.h',
'html/canvas/WebGLExtension.cpp',
'html/canvas/WebGLExtension.h',
+ 'html/canvas/WebGLExtensionName.h',
'html/canvas/WebGLFramebuffer.cpp',
'html/canvas/WebGLFramebuffer.h',
'html/canvas/WebGLGetInfo.cpp',
@@ -2459,6 +2605,8 @@
'html/canvas/WebGLRenderbuffer.h',
'html/canvas/WebGLRenderingContext.cpp',
'html/canvas/WebGLRenderingContext.h',
+ 'html/canvas/WebGLRenderingContextBase.cpp',
+ 'html/canvas/WebGLRenderingContextBase.h',
'html/canvas/WebGLShader.cpp',
'html/canvas/WebGLShader.h',
'html/canvas/WebGLShaderPrecisionFormat.cpp',
@@ -2489,8 +2637,6 @@
'html/forms/ButtonInputType.h',
'html/forms/CheckboxInputType.cpp',
'html/forms/CheckboxInputType.h',
- 'html/forms/CheckedRadioButtons.cpp',
- 'html/forms/CheckedRadioButtons.h',
'html/forms/ColorInputType.cpp',
'html/forms/ColorInputType.h',
'html/forms/DateInputType.cpp',
@@ -2519,6 +2665,8 @@
'html/forms/NumberInputType.h',
'html/forms/PasswordInputType.cpp',
'html/forms/PasswordInputType.h',
+ 'html/forms/RadioButtonGroupScope.cpp',
+ 'html/forms/RadioButtonGroupScope.h',
'html/forms/RadioInputType.cpp',
'html/forms/RadioInputType.h',
'html/forms/RangeInputType.cpp',
@@ -2547,11 +2695,29 @@
'html/forms/ValidationMessage.h',
'html/forms/WeekInputType.cpp',
'html/forms/WeekInputType.h',
+ 'html/ime/InputMethodContext.cpp',
+ 'html/ime/InputMethodContext.h',
+ 'html/imports/HTMLImport.cpp',
+ 'html/imports/HTMLImport.h',
+ 'html/imports/HTMLImportChild.cpp',
+ 'html/imports/HTMLImportChild.h',
+ 'html/imports/HTMLImportChildClient.h',
+ 'html/imports/HTMLImportLoader.cpp',
+ 'html/imports/HTMLImportLoader.h',
+ 'html/imports/HTMLImportState.h',
+ 'html/imports/HTMLImportStateResolver.cpp',
+ 'html/imports/HTMLImportStateResolver.h',
+ 'html/imports/HTMLImportTreeRoot.cpp',
+ 'html/imports/HTMLImportTreeRoot.h',
+ 'html/imports/HTMLImportsController.cpp',
+ 'html/imports/HTMLImportsController.h',
+ 'html/imports/LinkImport.cpp',
+ 'html/imports/LinkImport.h',
'html/parser/AtomicHTMLToken.h',
- 'html/parser/BackgroundHTMLParser.cpp',
- 'html/parser/BackgroundHTMLParser.h',
'html/parser/BackgroundHTMLInputStream.cpp',
'html/parser/BackgroundHTMLInputStream.h',
+ 'html/parser/BackgroundHTMLParser.cpp',
+ 'html/parser/BackgroundHTMLParser.h',
'html/parser/CSSPreloadScanner.cpp',
'html/parser/CSSPreloadScanner.h',
'html/parser/CompactHTMLToken.cpp',
@@ -2604,12 +2770,12 @@
'html/parser/NestingLevelIncrementer.h',
'html/parser/TextDocumentParser.cpp',
'html/parser/TextDocumentParser.h',
+ 'html/parser/TextResourceDecoder.cpp',
+ 'html/parser/TextResourceDecoder.h',
'html/parser/XSSAuditor.cpp',
'html/parser/XSSAuditor.h',
'html/parser/XSSAuditorDelegate.cpp',
'html/parser/XSSAuditorDelegate.h',
- 'html/shadow/PickerIndicatorElement.cpp',
- 'html/shadow/PickerIndicatorElement.h',
'html/shadow/ClearButtonElement.cpp',
'html/shadow/ClearButtonElement.h',
'html/shadow/DateTimeEditElement.cpp',
@@ -2624,24 +2790,16 @@
'html/shadow/DateTimeSymbolicFieldElement.h',
'html/shadow/DetailsMarkerControl.cpp',
'html/shadow/DetailsMarkerControl.h',
- 'html/shadow/HTMLContentElement.cpp',
- 'html/shadow/HTMLContentElement.h',
- 'html/shadow/HTMLShadowElement.cpp',
- 'html/shadow/HTMLShadowElement.h',
- 'html/shadow/MediaControls.cpp',
- 'html/shadow/MediaControls.h',
'html/shadow/MediaControlElementTypes.cpp',
'html/shadow/MediaControlElementTypes.h',
'html/shadow/MediaControlElements.cpp',
'html/shadow/MediaControlElements.h',
- 'html/shadow/MediaControlsChromium.cpp',
- 'html/shadow/MediaControlsChromium.h',
- 'html/shadow/MediaControlsChromiumAndroid.cpp',
- 'html/shadow/MediaControlsChromiumAndroid.h',
+ 'html/shadow/MediaControls.cpp',
+ 'html/shadow/MediaControls.h',
'html/shadow/MeterShadowElement.cpp',
'html/shadow/MeterShadowElement.h',
- 'html/shadow/PasswordGeneratorButtonElement.cpp',
- 'html/shadow/PasswordGeneratorButtonElement.h',
+ 'html/shadow/PickerIndicatorElement.cpp',
+ 'html/shadow/PickerIndicatorElement.h',
'html/shadow/ProgressShadowElement.cpp',
'html/shadow/ProgressShadowElement.h',
'html/shadow/ShadowElementNames.cpp',
@@ -2652,10 +2810,10 @@
'html/shadow/SpinButtonElement.h',
'html/shadow/TextControlInnerElements.cpp',
'html/shadow/TextControlInnerElements.h',
- 'html/ime/Composition.cpp',
- 'html/ime/Composition.h',
- 'html/ime/InputMethodContext.cpp',
- 'html/ime/InputMethodContext.h',
+ 'html/track/AudioTrack.cpp',
+ 'html/track/AudioTrack.h',
+ 'html/track/AudioTrackList.cpp',
+ 'html/track/AudioTrackList.h',
'html/track/InbandTextTrack.cpp',
'html/track/InbandTextTrack.h',
'html/track/LoadableTextTrack.cpp',
@@ -2667,8 +2825,14 @@
'html/track/TextTrackCueList.cpp',
'html/track/TextTrackCueList.h',
'html/track/TextTrackList.cpp',
+ 'html/track/TrackBase.cpp',
'html/track/TrackBase.h',
'html/track/TrackEvent.cpp',
+ 'html/track/TrackListBase.h',
+ 'html/track/VideoTrack.cpp',
+ 'html/track/VideoTrack.h',
+ 'html/track/VideoTrackList.cpp',
+ 'html/track/VideoTrackList.h',
'html/track/vtt/BufferedLineReader.cpp',
'html/track/vtt/BufferedLineReader.h',
'html/track/vtt/VTTCue.cpp',
@@ -2681,43 +2845,12 @@
'html/track/vtt/VTTRegion.h',
'html/track/vtt/VTTRegionList.cpp',
'html/track/vtt/VTTRegionList.h',
+ 'html/track/vtt/VTTScanner.cpp',
+ 'html/track/vtt/VTTScanner.h',
'html/track/vtt/VTTToken.h',
'html/track/vtt/VTTTokenizer.cpp',
'html/track/vtt/VTTTokenizer.h',
],
- 'webcore_platform_files': [
- 'platform/DragImage.cpp',
- 'platform/Pasteboard.cpp',
- 'platform/Pasteboard.h',
- 'platform/animation/AnimationTranslationUtil.cpp',
- 'platform/animation/AnimationTranslationUtil.h',
- 'platform/animation/AnimationValue.h',
- 'platform/animation/CSSAnimationData.cpp',
- 'platform/animation/CSSAnimationDataList.cpp',
- 'platform/animation/KeyframeValueList.cpp',
- 'platform/animation/KeyframeValueList.h',
- 'platform/chromium/ChromiumDataObject.cpp',
- 'platform/chromium/ChromiumDataObject.h',
- 'platform/chromium/ChromiumDataObjectItem.cpp',
- 'platform/chromium/ChromiumDataObjectItem.h',
- 'platform/chromium/KeyCodeConversion.h',
- 'platform/chromium/KeyCodeConversionAndroid.cpp',
- 'platform/chromium/KeyCodeConversionGtk.cpp',
- 'platform/mac/ThemeMac.h',
- 'platform/mac/ThemeMac.mm',
- 'platform/mediastream/MediaStreamCenter.cpp',
- 'platform/mediastream/MediaStreamCenter.h',
- 'platform/mediastream/MediaStreamDescriptor.cpp',
- 'platform/mediastream/MediaStreamDescriptor.h',
- 'platform/mediastream/RTCDataChannelHandler.cpp',
- 'platform/mediastream/RTCDataChannelHandler.h',
- 'platform/mediastream/RTCDataChannelHandlerClient.h',
- 'platform/mediastream/RTCPeerConnectionHandler.cpp',
- 'platform/mediastream/RTCPeerConnectionHandler.h',
- 'platform/mediastream/RTCPeerConnectionHandlerClient.h',
- 'platform/mediastream/RTCStatsRequest.h',
- 'platform/mock/GeolocationClientMock.cpp',
- ],
'webcore_svg_files': [
'rendering/style/SVGRenderStyle.cpp',
'rendering/style/SVGRenderStyleDefs.cpp',
@@ -2843,41 +2976,32 @@
'svg/SVGAltGlyphItemElement.cpp',
'svg/SVGAltGlyphItemElement.h',
'svg/SVGAngle.cpp',
- 'svg/SVGAnimateColorElement.cpp',
- 'svg/SVGAnimateColorElement.h',
+ 'svg/SVGAngleTearOff.cpp',
+ 'svg/SVGAnimateElement.cpp',
+ 'svg/SVGAnimateElement.h',
+ 'svg/SVGAnimateMotionElement.cpp',
+ 'svg/SVGAnimateMotionElement.h',
+ 'svg/SVGAnimateTransformElement.cpp',
+ 'svg/SVGAnimateTransformElement.h',
'svg/SVGAnimatedAngle.cpp',
- 'svg/SVGAnimatedBoolean.cpp',
'svg/SVGAnimatedColor.cpp',
- 'svg/SVGAnimatedEnumeration.cpp',
+ 'svg/SVGAnimatedEnumerationBase.cpp',
'svg/SVGAnimatedInteger.cpp',
'svg/SVGAnimatedIntegerOptionalInteger.cpp',
'svg/SVGAnimatedLength.cpp',
- 'svg/SVGAnimatedLengthList.cpp',
'svg/SVGAnimatedNumber.cpp',
- 'svg/SVGAnimatedNumberList.cpp',
'svg/SVGAnimatedNumberOptionalNumber.cpp',
'svg/SVGAnimatedPath.cpp',
- 'svg/SVGAnimatedPointList.cpp',
- 'svg/SVGAnimatedPreserveAspectRatio.cpp',
- 'svg/SVGAnimatedRect.cpp',
- 'svg/SVGAnimatedString.cpp',
- 'svg/SVGAnimatedTransformList.cpp',
- 'svg/SVGAnimatedType.cpp',
'svg/SVGAnimatedTypeAnimator.cpp',
'svg/SVGAnimatedTypeAnimator.h',
- 'svg/SVGAnimateElement.cpp',
- 'svg/SVGAnimateElement.h',
- 'svg/SVGAnimateMotionElement.cpp',
- 'svg/SVGAnimateMotionElement.h',
- 'svg/SVGAnimateTransformElement.cpp',
- 'svg/SVGAnimateTransformElement.h',
'svg/SVGAnimationElement.cpp',
'svg/SVGAnimationElement.h',
+ 'svg/SVGBoolean.cpp',
+ 'svg/SVGBoolean.h',
'svg/SVGCircleElement.cpp',
'svg/SVGCircleElement.h',
'svg/SVGClipPathElement.cpp',
'svg/SVGClipPathElement.h',
- 'svg/SVGColor.cpp',
'svg/SVGComponentTransferFunctionElement.cpp',
'svg/SVGComponentTransferFunctionElement.h',
'svg/SVGCursorElement.cpp',
@@ -2886,19 +3010,14 @@
'svg/SVGDefsElement.h',
'svg/SVGDescElement.cpp',
'svg/SVGDescElement.h',
- 'svg/SVGDocument.cpp',
- 'svg/SVGDocument.h',
+ 'svg/SVGDiscardElement.cpp',
+ 'svg/SVGDiscardElement.h',
'svg/SVGDocumentExtensions.cpp',
'svg/SVGElement.cpp',
- 'svg/SVGElementInstance.cpp',
- 'svg/SVGElementInstance.h',
- 'svg/SVGElementInstanceList.cpp',
- 'svg/SVGElementInstanceList.h',
'svg/SVGElementRareData.h',
'svg/SVGEllipseElement.cpp',
'svg/SVGEllipseElement.h',
- 'svg/SVGExternalResourcesRequired.cpp',
- 'svg/SVGExternalResourcesRequired.h',
+ 'svg/SVGEnumeration.cpp',
'svg/SVGFEBlendElement.cpp',
'svg/SVGFEBlendElement.h',
'svg/SVGFEColorMatrixElement.cpp',
@@ -2967,6 +3086,8 @@
'svg/SVGFontFaceFormatElement.h',
'svg/SVGFontFaceNameElement.cpp',
'svg/SVGFontFaceNameElement.h',
+ 'svg/SVGFontFaceSource.cpp',
+ 'svg/SVGFontFaceSource.h',
'svg/SVGFontFaceSrcElement.cpp',
'svg/SVGFontFaceSrcElement.h',
'svg/SVGFontFaceUriElement.cpp',
@@ -2975,13 +3096,13 @@
'svg/SVGForeignObjectElement.h',
'svg/SVGGElement.cpp',
'svg/SVGGElement.h',
+ 'svg/SVGGeometryElement.cpp',
+ 'svg/SVGGeometryElement.h',
'svg/SVGGlyphElement.cpp',
'svg/SVGGlyphElement.h',
+ 'svg/SVGGlyphMap.h',
'svg/SVGGlyphRefElement.cpp',
'svg/SVGGlyphRefElement.h',
- 'svg/SVGGlyphMap.h',
- 'svg/SVGGeometryElement.cpp',
- 'svg/SVGGeometryElement.h',
'svg/SVGGradientElement.cpp',
'svg/SVGGradientElement.h',
'svg/SVGGraphicsElement.cpp',
@@ -2992,9 +3113,14 @@
'svg/SVGImageElement.h',
'svg/SVGImageLoader.cpp',
'svg/SVGImageLoader.h',
+ 'svg/SVGInteger.cpp',
+ 'svg/SVGInteger.h',
+ 'svg/SVGIntegerOptionalInteger.cpp',
+ 'svg/SVGIntegerOptionalInteger.h',
'svg/SVGLength.cpp',
'svg/SVGLengthContext.cpp',
'svg/SVGLengthList.cpp',
+ 'svg/SVGLengthTearOff.cpp',
'svg/SVGLineElement.cpp',
'svg/SVGLineElement.h',
'svg/SVGLinearGradientElement.cpp',
@@ -3005,13 +3131,20 @@
'svg/SVGMarkerElement.h',
'svg/SVGMaskElement.cpp',
'svg/SVGMaskElement.h',
+ 'svg/SVGMatrixTearOff.cpp',
+ 'svg/SVGMatrixTearOff.h',
'svg/SVGMetadataElement.cpp',
'svg/SVGMetadataElement.h',
'svg/SVGMissingGlyphElement.cpp',
'svg/SVGMissingGlyphElement.h',
+ 'svg/SVGNumber.cpp',
'svg/SVGNumber.h',
'svg/SVGNumberList.cpp',
'svg/SVGNumberList.h',
+ 'svg/SVGNumberOptionalNumber.cpp',
+ 'svg/SVGNumberOptionalNumber.h',
+ 'svg/SVGNumberTearOff.cpp',
+ 'svg/SVGNumberTearOff.h',
'svg/SVGPaint.cpp',
'svg/SVGParserUtilities.cpp',
'svg/SVGParserUtilities.h',
@@ -3030,6 +3163,7 @@
'svg/SVGPathElement.h',
'svg/SVGPathParser.cpp',
'svg/SVGPathParser.h',
+ 'svg/SVGPathSeg.cpp',
'svg/SVGPathSeg.h',
'svg/SVGPathSegArc.h',
'svg/SVGPathSegArcAbs.h',
@@ -3047,10 +3181,10 @@
'svg/SVGPathSegCurvetoQuadraticSmoothAbs.h',
'svg/SVGPathSegCurvetoQuadraticSmoothRel.h',
'svg/SVGPathSegLinetoAbs.h',
- 'svg/SVGPathSegLinetoRel.h',
'svg/SVGPathSegLinetoHorizontal.h',
'svg/SVGPathSegLinetoHorizontalAbs.h',
'svg/SVGPathSegLinetoHorizontalRel.h',
+ 'svg/SVGPathSegLinetoRel.h',
'svg/SVGPathSegLinetoVertical.h',
'svg/SVGPathSegLinetoVerticalAbs.h',
'svg/SVGPathSegLinetoVerticalRel.h',
@@ -3060,6 +3194,7 @@
'svg/SVGPathSegListBuilder.h',
'svg/SVGPathSegListSource.cpp',
'svg/SVGPathSegListSource.h',
+ 'svg/SVGPathSegListTearOff.h',
'svg/SVGPathSegMovetoAbs.h',
'svg/SVGPathSegMovetoRel.h',
'svg/SVGPathSegWithContext.h',
@@ -3074,9 +3209,12 @@
'svg/SVGPathUtilities.h',
'svg/SVGPatternElement.cpp',
'svg/SVGPatternElement.h',
+ 'svg/SVGPoint.cpp',
'svg/SVGPoint.h',
'svg/SVGPointList.cpp',
'svg/SVGPointList.h',
+ 'svg/SVGPointTearOff.cpp',
+ 'svg/SVGPointTearOff.h',
'svg/SVGPolyElement.cpp',
'svg/SVGPolyElement.h',
'svg/SVGPolygonElement.cpp',
@@ -3084,11 +3222,17 @@
'svg/SVGPolylineElement.cpp',
'svg/SVGPolylineElement.h',
'svg/SVGPreserveAspectRatio.cpp',
+ 'svg/SVGPreserveAspectRatioTearOff.cpp',
'svg/SVGRadialGradientElement.cpp',
'svg/SVGRadialGradientElement.h',
+ 'svg/SVGRect.cpp',
'svg/SVGRect.h',
'svg/SVGRectElement.cpp',
'svg/SVGRectElement.h',
+ 'svg/SVGRectTearOff.cpp',
+ 'svg/SVGRectTearOff.h',
+ 'svg/SVGRemoteFontFaceSource.cpp',
+ 'svg/SVGRemoteFontFaceSource.h',
'svg/SVGRenderingIntent.h',
'svg/SVGSVGElement.cpp',
'svg/SVGSVGElement.h',
@@ -3096,10 +3240,16 @@
'svg/SVGScriptElement.h',
'svg/SVGSetElement.cpp',
'svg/SVGSetElement.h',
+ 'svg/SVGStaticStringList.cpp',
+ 'svg/SVGStaticStringList.h',
'svg/SVGStopElement.cpp',
'svg/SVGStopElement.h',
+ 'svg/SVGString.cpp',
+ 'svg/SVGString.h',
'svg/SVGStringList.cpp',
'svg/SVGStringList.h',
+ 'svg/SVGStringListTearOff.cpp',
+ 'svg/SVGStringListTearOff.h',
'svg/SVGStyleElement.cpp',
'svg/SVGStyleElement.h',
'svg/SVGSwitchElement.cpp',
@@ -3124,8 +3274,11 @@
'svg/SVGTransformDistance.cpp',
'svg/SVGTransformDistance.h',
'svg/SVGTransformList.cpp',
+ 'svg/SVGTransformListTearOff.cpp',
+ 'svg/SVGTransformTearOff.cpp',
'svg/SVGURIReference.cpp',
'svg/SVGURIReference.h',
+ 'svg/SVGUnitTypes.cpp',
'svg/SVGUnitTypes.h',
'svg/SVGUnknownElement.cpp',
'svg/SVGUnknownElement.h',
@@ -3145,13 +3298,14 @@
'svg/animation/SMILTimeContainer.cpp',
'svg/animation/SMILTimeContainer.h',
'svg/animation/SVGSMILElement.cpp',
+ 'svg/graphics/SVGImage.cpp',
+ 'svg/graphics/SVGImage.h',
'svg/graphics/SVGImageCache.cpp',
'svg/graphics/SVGImageCache.h',
+ 'svg/graphics/SVGImageChromeClient.cpp',
'svg/graphics/SVGImageChromeClient.h',
- 'svg/graphics/SVGImage.cpp',
- 'svg/graphics/SVGImage.h',
- 'svg/graphics/SVGImageForContainer.h',
'svg/graphics/SVGImageForContainer.cpp',
+ 'svg/graphics/SVGImageForContainer.h',
'svg/graphics/filters/SVGFEImage.cpp',
'svg/graphics/filters/SVGFEImage.h',
'svg/graphics/filters/SVGFilter.cpp',
@@ -3159,58 +3313,46 @@
'svg/graphics/filters/SVGFilterBuilder.cpp',
'svg/graphics/filters/SVGFilterBuilder.h',
'svg/properties/SVGAnimatedProperty.cpp',
- 'svg/properties/SVGAnimatedProperty.h',
- 'svg/properties/SVGAttributeToPropertyMap.cpp',
- 'svg/properties/SVGAnimatedPathSegListPropertyTearOff.h',
- 'svg/properties/SVGPathSegListPropertyTearOff.cpp',
+ 'svg/properties/SVGPropertyTearOff.cpp',
],
- 'webcore_testing_support_idl_files': [
+ 'webcore_testing_idl_files': [
'testing/GCObservation.idl',
- 'testing/Internals.idl',
'testing/InternalProfilers.idl',
'testing/InternalSettings.idl',
+ 'testing/Internals.idl',
'testing/LayerRect.idl',
'testing/LayerRectList.idl',
'testing/MallocStatistics.idl',
'testing/TypeConversions.idl',
],
- 'generated_webcore_testing_support_idl_files': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalSettingsGenerated.idl',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalRuntimeFlags.idl',
+ 'generated_webcore_testing_idl_files': [
+ '<(blink_core_output_dir)/InternalRuntimeFlags.idl',
+ '<(blink_core_output_dir)/InternalSettingsGenerated.idl',
],
- 'webcore_test_support_files': [
- 'testing/v8/WebCoreTestSupport.cpp',
- 'testing/v8/WebCoreTestSupport.h',
+ 'webcore_testing_files': [
+ '<(blink_core_output_dir)/InternalSettingsGenerated.cpp',
+ '<(blink_core_output_dir)/InternalSettingsGenerated.h',
'testing/DummyPageHolder.cpp',
'testing/DummyPageHolder.h',
'testing/GCObservation.cpp',
'testing/GCObservation.h',
- 'testing/InspectorFrontendClientLocal.cpp',
- 'testing/InspectorFrontendClientLocal.h',
- 'testing/Internals.cpp',
- 'testing/Internals.h',
'testing/InternalProfilers.cpp',
'testing/InternalProfilers.h',
'testing/InternalSettings.cpp',
'testing/InternalSettings.h',
+ 'testing/Internals.cpp',
+ 'testing/Internals.h',
'testing/LayerRect.h',
'testing/LayerRectList.cpp',
'testing/LayerRectList.h',
'testing/MallocStatistics.h',
'testing/MockPagePopupDriver.cpp',
'testing/MockPagePopupDriver.h',
+ 'testing/NullExecutionContext.cpp',
+ 'testing/NullExecutionContext.h',
'testing/TypeConversions.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalSettingsGenerated.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalSettingsGenerated.h',
- ],
- 'webcore_platform_support_files': [
- 'platform/chromium/support/WebArrayBuffer.cpp',
- 'platform/chromium/support/WebCrypto.cpp',
- 'platform/chromium/support/WebMediaStream.cpp',
- 'platform/chromium/support/WebMediaStreamTrack.cpp',
- 'platform/chromium/support/WebRTCSessionDescription.cpp',
- 'platform/chromium/support/WebRTCSessionDescriptionRequest.cpp',
- 'platform/chromium/support/WebRTCStatsRequest.cpp',
+ 'testing/v8/WebCoreTestSupport.cpp',
+ 'testing/v8/WebCoreTestSupport.h',
],
'core_unittest_files': [
'animation/AnimatableColorTest.cpp',
@@ -3223,38 +3365,80 @@
'animation/AnimatableValueTestHelper.h',
'animation/AnimatableValueTestHelperTest.cpp',
'animation/AnimationClockTest.cpp',
+ 'animation/AnimationHelpersTest.cpp',
+ 'animation/AnimationPlayerTest.cpp',
+ 'animation/AnimationNodeTest.cpp',
+ 'animation/AnimationStackTest.cpp',
+ 'animation/AnimationTest.cpp',
+ 'animation/AnimationTestHelper.cpp',
+ 'animation/AnimationTestHelper.h',
+ 'animation/AnimationTimelineTest.cpp',
+ 'animation/AnimationTranslationUtilTest.cpp',
'animation/CompositorAnimationsTest.cpp',
'animation/CompositorAnimationsTestHelper.h',
'animation/CompositorAnimationsTimingFunctionReverserTest.cpp',
- 'animation/DocumentTimelineTest.cpp',
- 'animation/ElementAnimationTest.cpp',
- 'animation/KeyframeAnimationEffectTest.cpp',
- 'animation/PlayerTest.cpp',
- 'animation/TimedItemCalculationsTest.cpp',
- 'animation/TimedItemTest.cpp',
- 'css/CSSParserValuesTest.cpp',
+ 'animation/EffectInputTest.cpp',
+ 'animation/InterpolableValueTest.cpp',
+ 'animation/InterpolationEffectTest.cpp',
+ 'animation/InterpolableValueTest.cpp',
+ 'animation/KeyframeEffectModelTest.cpp',
+ 'animation/TimingCalculationsTest.cpp',
+ 'animation/TimingInputTest.cpp',
+ 'animation/interpolation/DeferredLegacyStyleInterpolationTest.cpp',
+ 'animation/interpolation/LengthStyleInterpolationTest.cpp',
+ 'css/AffectedByFocusTest.cpp',
'css/CSSCalculationValueTest.cpp',
+ 'css/CSSFontFaceTest.cpp',
+ 'css/CSSParserValuesTest.cpp',
+ 'css/CSSSelectorTest.cpp',
+ 'css/CSSTestHelper.cpp',
+ 'css/CSSTestHelper.h',
'css/CSSValueTestHelper.h',
+ 'css/DragUpdateTest.cpp',
+ 'css/MediaValuesTest.cpp',
+ 'css/MediaQueryEvaluatorTest.cpp',
+ 'css/MediaQuerySetTest.cpp',
+ 'css/RuleSetTest.cpp',
+ 'css/invalidation/DescendantInvalidationSetTest.cpp',
+ 'css/parser/BisonCSSParserTest.cpp',
+ 'css/parser/SizesCalcParserTest.cpp',
+ 'css/parser/MediaQueryTokenizerTest.cpp',
+ 'css/parser/SizesAttributeParserTest.cpp',
+ 'css/parser/MediaConditionTest.cpp',
+ 'css/resolver/FontBuilderTest.cpp',
+ 'dom/ActiveDOMObjectTest.cpp',
+ 'dom/DOMImplementationTest.cpp',
'dom/DocumentMarkerControllerTest.cpp',
- 'editing/TextIteratorTest.cpp',
+ 'dom/DocumentTest.cpp',
'dom/MainThreadTaskRunnerTest.cpp',
+ 'dom/RangeTest.cpp',
+ 'dom/TreeScopeTest.cpp',
+ 'editing/CompositionUnderlineRangeFilterTest.cpp',
+ 'editing/SurroundingTextTest.cpp',
+ 'editing/TextIteratorTest.cpp',
+ 'editing/VisibleSelectionTest.cpp',
+ 'fetch/CachingCorrectnessTest.cpp',
'fetch/ImageResourceTest.cpp',
'fetch/MemoryCacheTest.cpp',
'fetch/RawResourceTest.cpp',
'fetch/ResourceFetcherTest.cpp',
+ 'frame/ImageBitmapTest.cpp',
'html/HTMLDimensionTest.cpp',
+ 'html/HTMLLinkElementSizesAttributeTest.cpp',
+ 'html/HTMLTextFormControlElementTest.cpp',
'html/LinkRelAttributeTest.cpp',
'html/TimeRangesTest.cpp',
+ 'html/parser/HTMLParserThreadTest.cpp',
+ 'html/parser/HTMLSrcsetParserTest.cpp',
'html/track/vtt/BufferedLineReaderTest.cpp',
- 'frame/ImageBitmapTest.cpp',
- 'platform/animation/AnimationTranslationUtilTest.cpp',
- 'platform/animation/TimingFunctionTestHelper.h',
- 'platform/animation/TimingFunctionTestHelper.cpp',
- 'platform/animation/TimingFunctionTestHelperTest.cpp',
+ 'html/track/vtt/VTTScannerTest.cpp',
+ 'loader/MixedContentCheckerTest.cpp',
+ 'page/NetworkStateNotifierTest.cpp',
'rendering/RenderOverflowTest.cpp',
'rendering/shapes/BoxShapeTest.cpp',
- 'testing/UnitTestHelpers.h',
'testing/UnitTestHelpers.cpp',
+ 'testing/UnitTestHelpers.h',
+ 'xml/parser/SharedBufferReaderTest.cpp',
],
}
}
diff --git a/chromium/third_party/WebKit/Source/core/core_derived_sources.gyp b/chromium/third_party/WebKit/Source/core/core_derived_sources.gyp
deleted file mode 100644
index 1cc7c34b412..00000000000
--- a/chromium/third_party/WebKit/Source/core/core_derived_sources.gyp
+++ /dev/null
@@ -1,662 +0,0 @@
-#
-# Copyright (C) 2013 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-
-{
- 'includes': [
- 'core.gypi',
- '../bindings/bindings.gypi',
- '../build/features.gypi',
- '../build/scripts/scripts.gypi',
- ],
-
- 'targets': [
- {
- 'target_name': 'generate_test_support_idls',
- 'type': 'none',
- 'actions': [
- {
- 'action_name': 'Settings',
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_settings.py',
- '../build/scripts/templates/InternalSettingsGenerated.idl.tmpl',
- '../build/scripts/templates/InternalSettingsGenerated.cpp.tmpl',
- '../build/scripts/templates/InternalSettingsGenerated.h.tmpl',
- '../build/scripts/templates/SettingsMacros.h.tmpl',
- 'frame/Settings.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/SettingsMacros.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalSettingsGenerated.idl',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalSettingsGenerated.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalSettingsGenerated.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_settings.py',
- 'frame/Settings.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'InternalRuntimeFlags',
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_internal_runtime_flags.py',
- '../platform/RuntimeEnabledFeatures.in',
- '../build/scripts/templates/InternalRuntimeFlags.h.tmpl',
- '../build/scripts/templates/InternalRuntimeFlags.idl.tmpl',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalRuntimeFlags.idl',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InternalRuntimeFlags.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_internal_runtime_flags.py',
- '../platform/RuntimeEnabledFeatures.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- ]
- },
- {
- 'target_name': 'make_core_derived_sources',
- 'type': 'none',
- 'hard_dependency': 1,
- 'dependencies': [
- 'generate_test_support_idls',
- '../config.gyp:config',
- ],
- 'sources': [
- # bison rule
- 'css/CSSGrammar.y',
- 'xml/XPathGrammar.y',
- ],
- 'actions': [
- {
- 'action_name': 'generateV8ArrayBufferViewCustomScript',
- 'inputs': [
- '<(bindings_dir)/v8/custom/V8ArrayBufferViewCustomScript.js',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/V8ArrayBufferViewCustomScript.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/xxd.py',
- 'V8ArrayBufferViewCustomScript_js',
- '<@(_inputs)',
- '<@(_outputs)'
- ],
- 'message': 'Generating V8ArrayBufferViewCustomScript.h from V8ArrayBufferViewCustomScript.js',
- 'msvs_cygwin_shell': 0,
- },
- {
- 'action_name': 'generateXMLViewerCSS',
- 'inputs': [
- 'xml/XMLViewer.css',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/XMLViewerCSS.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/xxd.py',
- 'XMLViewer_css',
- '<@(_inputs)',
- '<@(_outputs)'
- ],
- 'msvs_cygwin_shell': 0,
- },
- {
- 'action_name': 'generateXMLViewerJS',
- 'inputs': [
- 'xml/XMLViewer.js',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/XMLViewerJS.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/xxd.py',
- 'XMLViewer_js',
- '<@(_inputs)',
- '<@(_outputs)'
- ],
- 'msvs_cygwin_shell': 0,
- },
- {
- 'action_name': 'HTMLEntityTable',
- 'inputs': [
- 'html/parser/create-html-entity-table',
- 'html/parser/HTMLEntityNames.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLEntityTable.cpp'
- ],
- 'action': [
- 'python',
- 'html/parser/create-html-entity-table',
- '-o',
- '<@(_outputs)',
- '<@(_inputs)'
- ],
- },
- {
- 'action_name': 'CSSPropertyNames',
- 'variables': {
- 'in_files': [
- 'css/CSSPropertyNames.in',
- 'css/SVGCSSPropertyNames.in',
- ],
- },
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_css_property_names.py',
- '<@(in_files)'
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSPropertyNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSPropertyNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_css_property_names.py',
- '<@(in_files)',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- '--defines', '<(feature_defines)',
- ],
- 'msvs_cygwin_shell': 1,
- },
- {
- 'action_name': 'StylePropertyShorthand',
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_style_shorthands.py',
- 'css/CSSShorthands.in',
- '../build/scripts/templates/StylePropertyShorthand.h.tmpl',
- '../build/scripts/templates/StylePropertyShorthand.cpp.tmpl',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/StylePropertyShorthand.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/StylePropertyShorthand.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_style_shorthands.py',
- 'css/CSSShorthands.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'StyleBuilder',
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_style_builder.py',
- 'css/CSSProperties.in',
- '../build/scripts/templates/StyleBuilder.cpp.tmpl',
- '../build/scripts/templates/StyleBuilderFunctions.h.tmpl',
- '../build/scripts/templates/StyleBuilderFunctions.cpp.tmpl',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/StyleBuilder.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/StyleBuilderFunctions.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/StyleBuilderFunctions.cpp',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_style_builder.py',
- 'css/CSSProperties.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'CSSValueKeywords',
- 'variables': {
- 'in_files': [
- 'css/CSSValueKeywords.in',
- 'css/SVGCSSValueKeywords.in',
- ],
- },
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_css_value_keywords.py',
- '<@(in_files)'
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSValueKeywords.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSValueKeywords.h',
- ],
- 'action': [
- '../build/scripts/make_css_value_keywords.py',
- '<@(in_files)',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- '--defines', '<(feature_defines)',
- ],
- 'msvs_cygwin_shell': 1,
- },
- {
- 'action_name': 'HTMLElementFactory',
- 'inputs': [
- '<@(make_element_factory_files)',
- 'html/HTMLTagNames.in',
- 'html/HTMLAttributeNames.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementFactory.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementFactory.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLNames.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/V8HTMLElementWrapperFactory.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/V8HTMLElementWrapperFactory.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_element_factory.py',
- 'html/HTMLTagNames.in',
- 'html/HTMLAttributeNames.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'SVGNames',
- 'inputs': [
- '<@(make_element_factory_files)',
- 'svg/SVGTagNames.in',
- 'svg/SVGAttributeNames.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/SVGElementFactory.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/SVGElementFactory.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/SVGNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/SVGNames.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/V8SVGElementWrapperFactory.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/V8SVGElementWrapperFactory.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_element_factory.py',
- 'svg/SVGTagNames.in',
- 'svg/SVGAttributeNames.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'EventFactory',
- 'inputs': [
- '<@(make_event_factory_files)',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
- 'events/EventAliases.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/Event.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventHeaders.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_event_factory.py',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
- 'events/EventAliases.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'EventNames',
- 'inputs': [
- '<@(make_names_files)',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_names.py',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventInterfaces.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'EventTargetFactory',
- 'inputs': [
- '<@(make_event_factory_files)',
- 'events/EventTargetFactory.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTargetHeaders.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTargetInterfaces.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_event_factory.py',
- 'events/EventTargetFactory.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'EventTargetNames',
- 'inputs': [
- '<@(make_names_files)',
- 'events/EventTargetFactory.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTargetNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTargetNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_names.py',
- 'events/EventTargetFactory.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'MathMLNames',
- 'inputs': [
- '<@(make_qualified_names_files)',
- 'html/parser/MathMLTagNames.in',
- 'html/parser/MathMLAttributeNames.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/MathMLNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/MathMLNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_qualified_names.py',
- 'html/parser/MathMLTagNames.in',
- 'html/parser/MathMLAttributeNames.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- '--defines', '<(feature_defines)'
- ],
- },
- {
- 'action_name': 'UserAgentStyleSheets',
- 'variables': {
- 'scripts': [
- 'css/make-css-file-arrays.pl',
- '../build/scripts/preprocessor.pm',
- ],
- 'stylesheets': [
- 'css/html.css',
- 'css/quirks.css',
- 'css/view-source.css',
- 'css/themeChromium.css',
- 'css/themeChromiumAndroid.css',
- 'css/themeChromiumLinux.css',
- 'css/themeChromiumSkia.css',
- 'css/themeWin.css',
- 'css/themeWinQuirks.css',
- 'css/svg.css',
- 'css/mediaControls.css',
- 'css/mediaControlsAndroid.css',
- 'css/fullscreen.css',
- 'css/xhtmlmp.css',
- 'css/viewportAndroid.css',
- ],
- },
- 'inputs': [
- '<@(scripts)',
- '<@(stylesheets)'
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/UserAgentStyleSheets.h',
- '<(SHARED_INTERMEDIATE_DIR)/blink/UserAgentStyleSheetsData.cpp',
- ],
- 'action': [
- 'python',
- '../build/scripts/action_useragentstylesheets.py',
- '<@(_outputs)',
- '<@(stylesheets)',
- '--',
- '<@(scripts)',
- '--',
- '--defines', '<(feature_defines)',
- ],
- 'msvs_cygwin_shell': 1,
- },
- {
- 'action_name': 'FetchInitiatorTypeNames',
- 'inputs': [
- '<@(make_names_files)',
- 'fetch/FetchInitiatorTypeNames.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/FetchInitiatorTypeNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/FetchInitiatorTypeNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_names.py',
- 'fetch/FetchInitiatorTypeNames.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'EventTypeNames',
- 'inputs': [
- '<@(make_names_files)',
- 'events/EventTypeNames.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTypeNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/EventTypeNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_names.py',
- 'events/EventTypeNames.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'InputTypeNames',
- 'inputs': [
- '<@(make_names_files)',
- 'html/forms/InputTypeNames.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/InputTypeNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/InputTypeNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_names.py',
- 'html/forms/InputTypeNames.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'XLinkNames',
- 'inputs': [
- '<@(make_qualified_names_files)',
- 'svg/xlinkattrs.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/XLinkNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/XLinkNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_qualified_names.py',
- 'svg/xlinkattrs.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'XMLNSNames',
- 'inputs': [
- '<@(make_qualified_names_files)',
- 'xml/xmlnsattrs.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/XMLNSNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/XMLNSNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_qualified_names.py',
- 'xml/xmlnsattrs.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'XMLNames',
- 'inputs': [
- '<@(make_qualified_names_files)',
- 'xml/xmlattrs.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/XMLNames.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/XMLNames.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_qualified_names.py',
- 'xml/xmlattrs.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- {
- 'action_name': 'MakeTokenMatcher',
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_token_matcher.py',
- '../core/css/CSSTokenizer-in.cpp',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSTokenizer.cpp',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_token_matcher.py',
- '../core/css/CSSTokenizer-in.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSTokenizer.cpp',
- ],
- },
- {
- 'action_name': 'MakeParser',
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_token_matcher.py',
- '../core/css/CSSParser-in.cpp',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSParser.cpp',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_token_matcher.py',
- '../core/css/CSSParser-in.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/CSSParser.cpp',
- ],
- },
- {
- 'action_name': 'MakeTokenMatcherForViewport',
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_token_matcher.py',
- '../core/html/HTMLMetaElement-in.cpp',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLMetaElement.cpp',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_token_matcher.py',
- '../core/html/HTMLMetaElement-in.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLMetaElement.cpp',
- ],
- },
- {
- 'action_name': 'HTMLElementLookupTrie',
- 'inputs': [
- '<@(scripts_for_in_files)',
- '../build/scripts/make_element_lookup_trie.py',
- '../build/scripts/templates/ElementLookupTrie.cpp.tmpl',
- '../build/scripts/templates/ElementLookupTrie.h.tmpl',
- 'html/HTMLTagNames.in',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementLookupTrie.cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementLookupTrie.h',
- ],
- 'action': [
- 'python',
- '../build/scripts/make_element_lookup_trie.py',
- 'html/HTMLTagNames.in',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- ],
- },
- ],
- 'rules': [
- {
- 'rule_name': 'bison',
- 'extension': 'y',
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/blink/<(RULE_INPUT_ROOT).cpp',
- '<(SHARED_INTERMEDIATE_DIR)/blink/<(RULE_INPUT_ROOT).h'
- ],
- 'action': [
- 'python',
- '../build/scripts/rule_bison.py',
- '<(RULE_INPUT_PATH)',
- '<(SHARED_INTERMEDIATE_DIR)/blink',
- '<(bison_exe)',
- ],
- 'msvs_cygwin_shell': 1,
- },
- ],
- },
- ],
-}
diff --git a/chromium/third_party/WebKit/Source/core/core_generated.gyp b/chromium/third_party/WebKit/Source/core/core_generated.gyp
new file mode 100644
index 00000000000..4140de0ce7b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/core_generated.gyp
@@ -0,0 +1,828 @@
+#
+# Copyright (C) 2013 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+{
+ 'includes': [
+ 'core.gypi',
+ '../bindings/scripts/scripts.gypi',
+ '../build/features.gypi',
+ '../build/scripts/scripts.gypi',
+ ],
+
+ 'targets': [
+ {
+ # GN version: //third_party/WebKit/Source/core:core_event_interfaces
+ 'target_name': 'core_event_interfaces',
+ 'type': 'none',
+ 'actions': [
+ {
+ 'action_name': 'make_core_event_interfaces',
+ 'variables': {
+ 'event_idl_files': [
+ '<@(core_event_idl_files)',
+ ],
+ 'event_idl_files_list':
+ '<|(event_idl_files_list.tmp <@(event_idl_files))',
+ },
+ 'inputs': [
+ # FIXME: should be in build/scripts, not bindings/scripts
+ '../bindings/scripts/generate_event_interfaces.py',
+ '../bindings/scripts/utilities.py',
+ '<(event_idl_files_list)',
+ '<@(event_idl_files)',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/EventInterfaces.in',
+ ],
+ 'action': [
+ 'python',
+ '../bindings/scripts/generate_event_interfaces.py',
+ '--event-idl-files-list',
+ '<(event_idl_files_list)',
+ '--event-interfaces-file',
+ '<(blink_core_output_dir)/EventInterfaces.in',
+ '--write-file-only-if-changed',
+ '<(write_file_only_if_changed)',
+ ],
+ },
+ ],
+ },
+ {
+ # GN version: //third_party/WebKit/Sources/core:generated_testing_idls
+ 'target_name': 'generated_testing_idls',
+ 'type': 'none',
+ 'actions': [
+ {
+ 'action_name': 'Settings',
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_settings.py',
+ '../build/scripts/templates/InternalSettingsGenerated.idl.tmpl',
+ '../build/scripts/templates/InternalSettingsGenerated.cpp.tmpl',
+ '../build/scripts/templates/InternalSettingsGenerated.h.tmpl',
+ '../build/scripts/templates/SettingsMacros.h.tmpl',
+ 'frame/Settings.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/SettingsMacros.h',
+ '<(blink_core_output_dir)/InternalSettingsGenerated.idl',
+ '<(blink_core_output_dir)/InternalSettingsGenerated.cpp',
+ '<(blink_core_output_dir)/InternalSettingsGenerated.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_settings.py',
+ 'frame/Settings.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'InternalRuntimeFlags',
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_internal_runtime_flags.py',
+ '../platform/RuntimeEnabledFeatures.in',
+ '../build/scripts/templates/InternalRuntimeFlags.h.tmpl',
+ '../build/scripts/templates/InternalRuntimeFlags.idl.tmpl',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/InternalRuntimeFlags.idl',
+ '<(blink_core_output_dir)/InternalRuntimeFlags.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_internal_runtime_flags.py',
+ '../platform/RuntimeEnabledFeatures.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ ]
+ },
+ {
+ # GN version: //third_party/WebKit/Source/core:make_core_generated
+ 'target_name': 'make_core_generated',
+ 'type': 'none',
+ 'hard_dependency': 1,
+ 'dependencies': [
+ 'generated_testing_idls',
+ 'core_event_interfaces',
+ '../config.gyp:config',
+ ],
+ 'sources': [
+ # bison rule
+ 'css/CSSGrammar.y',
+ 'xml/XPathGrammar.y',
+ ],
+ 'actions': [
+ {
+ 'action_name': 'generateXMLViewerCSS',
+ 'inputs': [
+ 'xml/XMLViewer.css',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/XMLViewerCSS.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/xxd.py',
+ 'XMLViewer_css',
+ '<@(_inputs)',
+ '<@(_outputs)'
+ ],
+ },
+ {
+ 'action_name': 'generateXMLViewerJS',
+ 'inputs': [
+ 'xml/XMLViewer.js',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/XMLViewerJS.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/xxd.py',
+ 'XMLViewer_js',
+ '<@(_inputs)',
+ '<@(_outputs)'
+ ],
+ },
+ {
+ 'action_name': 'HTMLEntityTable',
+ 'inputs': [
+ 'html/parser/create-html-entity-table',
+ 'html/parser/HTMLEntityNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/HTMLEntityTable.cpp'
+ ],
+ 'action': [
+ 'python',
+ 'html/parser/create-html-entity-table',
+ '-o',
+ '<@(_outputs)',
+ '<@(_inputs)'
+ ],
+ },
+ {
+ 'action_name': 'CSSPropertyNames',
+ 'variables': {
+ 'in_files': [
+ 'css/CSSPropertyNames.in',
+ 'css/SVGCSSPropertyNames.in',
+ ],
+ },
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_css_property_names.py',
+ '<@(in_files)'
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/CSSPropertyNames.cpp',
+ '<(blink_core_output_dir)/CSSPropertyNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_css_property_names.py',
+ '<@(in_files)',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ '--gperf', '<(gperf_exe)',
+ '--defines', '<(feature_defines)',
+ ],
+ },
+ {
+ 'action_name': 'MediaFeatureNames',
+ 'variables': {
+ 'in_files': [
+ 'css/MediaFeatureNames.in',
+ ],
+ },
+ 'inputs': [
+ '<@(make_names_files)',
+ '../build/scripts/make_media_feature_names.py',
+ '<@(in_files)'
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/MediaFeatureNames.cpp',
+ '<(blink_core_output_dir)/MediaFeatureNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_media_feature_names.py',
+ '<@(in_files)',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ '--defines', '<(feature_defines)',
+ ],
+ },
+ {
+ 'action_name': 'MediaFeatures',
+ 'variables': {
+ 'in_files': [
+ 'css/MediaFeatureNames.in',
+ ],
+ },
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_media_features.py',
+ '../build/scripts/templates/MediaFeatures.h.tmpl',
+ '<@(in_files)'
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/MediaFeatures.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_media_features.py',
+ '<@(in_files)',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ '--defines', '<(feature_defines)',
+ ],
+ },
+ {
+ 'action_name': 'MediaTypeNames',
+ 'variables': {
+ 'in_files': [
+ 'css/MediaTypeNames.in',
+ ],
+ },
+ 'inputs': [
+ '<@(make_names_files)',
+ '<@(in_files)'
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/MediaTypeNames.cpp',
+ '<(blink_core_output_dir)/MediaTypeNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_names.py',
+ '<@(in_files)',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ '--defines', '<(feature_defines)',
+ ],
+ },
+ {
+ 'action_name': 'MediaQueryTokenizerCodepoints',
+ 'inputs': [
+ '../build/scripts/make_mediaquery_tokenizer_codepoints.py',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/MediaQueryTokenizerCodepoints.cpp',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_mediaquery_tokenizer_codepoints.py',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ '--defines', '<(feature_defines)',
+ ],
+ },
+ {
+ 'action_name': 'StylePropertyShorthand',
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_style_shorthands.py',
+ '../build/scripts/templates/StylePropertyShorthand.cpp.tmpl',
+ '../build/scripts/templates/StylePropertyShorthand.h.tmpl',
+ 'css/CSSShorthands.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/StylePropertyShorthand.cpp',
+ '<(blink_core_output_dir)/StylePropertyShorthand.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_style_shorthands.py',
+ 'css/CSSShorthands.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'StyleBuilder',
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_style_builder.py',
+ '../build/scripts/templates/StyleBuilder.cpp.tmpl',
+ '../build/scripts/templates/StyleBuilderFunctions.cpp.tmpl',
+ '../build/scripts/templates/StyleBuilderFunctions.h.tmpl',
+ 'css/CSSProperties.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/StyleBuilder.cpp',
+ '<(blink_core_output_dir)/StyleBuilderFunctions.h',
+ '<(blink_core_output_dir)/StyleBuilderFunctions.cpp',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_style_builder.py',
+ 'css/CSSProperties.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'CSSValueKeywords',
+ 'variables': {
+ 'in_files': [
+ 'css/CSSValueKeywords.in',
+ 'css/SVGCSSValueKeywords.in',
+ ],
+ },
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_css_value_keywords.py',
+ '<@(in_files)'
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/CSSValueKeywords.cpp',
+ '<(blink_core_output_dir)/CSSValueKeywords.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_css_value_keywords.py',
+ '<@(in_files)',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ '--gperf', '<(gperf_exe)',
+ '--defines', '<(feature_defines)',
+ ],
+ },
+ {
+ 'action_name': 'HTMLElementFactory',
+ 'inputs': [
+ '<@(make_element_factory_files)',
+ 'html/HTMLTagNames.in',
+ 'html/HTMLAttributeNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/HTMLElementFactory.cpp',
+ '<(blink_core_output_dir)/HTMLElementFactory.h',
+ '<(blink_core_output_dir)/HTMLNames.cpp',
+ '<(blink_core_output_dir)/HTMLNames.h',
+ '<(blink_core_output_dir)/V8HTMLElementWrapperFactory.cpp',
+ '<(blink_core_output_dir)/V8HTMLElementWrapperFactory.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_element_factory.py',
+ 'html/HTMLTagNames.in',
+ 'html/HTMLAttributeNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'HTMLElementTypeHelpers',
+ 'inputs': [
+ '<@(make_element_type_helpers_files)',
+ 'html/HTMLTagNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/HTMLElementTypeHelpers.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_element_type_helpers.py',
+ 'html/HTMLTagNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'SVGNames',
+ 'inputs': [
+ '<@(make_element_factory_files)',
+ 'svg/SVGTagNames.in',
+ 'svg/SVGAttributeNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/SVGElementFactory.cpp',
+ '<(blink_core_output_dir)/SVGElementFactory.h',
+ '<(blink_core_output_dir)/SVGNames.cpp',
+ '<(blink_core_output_dir)/SVGNames.h',
+ '<(blink_core_output_dir)/V8SVGElementWrapperFactory.cpp',
+ '<(blink_core_output_dir)/V8SVGElementWrapperFactory.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_element_factory.py',
+ 'svg/SVGTagNames.in',
+ 'svg/SVGAttributeNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'SVGElementTypeHelpers',
+ 'inputs': [
+ '<@(make_element_type_helpers_files)',
+ 'svg/SVGTagNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/SVGElementTypeHelpers.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_element_type_helpers.py',
+ 'svg/SVGTagNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'EventFactory',
+ 'inputs': [
+ '<@(make_event_factory_files)',
+ '<(blink_core_output_dir)/EventInterfaces.in',
+ 'events/EventAliases.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/Event.cpp',
+ '<(blink_core_output_dir)/EventHeaders.h',
+ '<(blink_core_output_dir)/EventInterfaces.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_event_factory.py',
+ '<(blink_core_output_dir)/EventInterfaces.in',
+ 'events/EventAliases.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'EventNames',
+ 'inputs': [
+ '<@(make_names_files)',
+ '<(blink_core_output_dir)/EventInterfaces.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/EventNames.cpp',
+ '<(blink_core_output_dir)/EventNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_names.py',
+ '<(blink_core_output_dir)/EventInterfaces.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'EventTargetFactory',
+ 'inputs': [
+ '<@(make_event_factory_files)',
+ 'events/EventTargetFactory.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/EventTargetHeaders.h',
+ '<(blink_core_output_dir)/EventTargetInterfaces.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_event_factory.py',
+ 'events/EventTargetFactory.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'EventTargetNames',
+ 'inputs': [
+ '<@(make_names_files)',
+ 'events/EventTargetFactory.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/EventTargetNames.cpp',
+ '<(blink_core_output_dir)/EventTargetNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_names.py',
+ 'events/EventTargetFactory.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'MathMLNames',
+ 'inputs': [
+ '<@(make_qualified_names_files)',
+ 'html/parser/MathMLTagNames.in',
+ 'html/parser/MathMLAttributeNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/MathMLNames.cpp',
+ '<(blink_core_output_dir)/MathMLNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_qualified_names.py',
+ 'html/parser/MathMLTagNames.in',
+ 'html/parser/MathMLAttributeNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ '--defines', '<(feature_defines)'
+ ],
+ },
+ {
+ 'action_name': 'UserAgentStyleSheets',
+ 'variables': {
+ 'scripts': [
+ 'css/make-css-file-arrays.pl',
+ '../build/scripts/preprocessor.pm',
+ ],
+ 'stylesheets': [
+ 'css/html.css',
+ 'css/quirks.css',
+ 'css/view-source.css',
+ 'css/themeChromium.css',
+ 'css/themeChromiumAndroid.css',
+ 'css/themeChromiumLinux.css',
+ 'css/themeChromiumSkia.css',
+ 'css/themeMac.css',
+ 'css/themeWin.css',
+ 'css/themeWinQuirks.css',
+ 'css/svg.css',
+ 'css/navigationTransitions.css',
+ 'css/mathml.css',
+ 'css/mediaControls.css',
+ 'css/mediaControlsAndroid.css',
+ 'css/fullscreen.css',
+ 'css/xhtmlmp.css',
+ 'css/viewportAndroid.css',
+ ],
+ },
+ 'inputs': [
+ '<@(scripts)',
+ '<@(stylesheets)'
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/UserAgentStyleSheets.h',
+ '<(blink_core_output_dir)/UserAgentStyleSheetsData.cpp',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/action_useragentstylesheets.py',
+ '<@(_outputs)',
+ '<@(stylesheets)',
+ '--',
+ '<@(scripts)',
+ '--',
+ '--defines', '<(feature_defines)',
+ '<@(preprocessor)',
+ '--perl', '<(perl_exe)',
+ ],
+ },
+ {
+ 'action_name': 'FetchInitiatorTypeNames',
+ 'inputs': [
+ '<@(make_names_files)',
+ 'fetch/FetchInitiatorTypeNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/FetchInitiatorTypeNames.cpp',
+ '<(blink_core_output_dir)/FetchInitiatorTypeNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_names.py',
+ 'fetch/FetchInitiatorTypeNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'EventTypeNames',
+ 'inputs': [
+ '<@(make_names_files)',
+ 'events/EventTypeNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/EventTypeNames.cpp',
+ '<(blink_core_output_dir)/EventTypeNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_names.py',
+ 'events/EventTypeNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'HTMLTokenizerNames',
+ 'inputs': [
+ '<@(make_names_files)',
+ 'html/parser/HTMLTokenizerNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/HTMLTokenizerNames.cpp',
+ '<(blink_core_output_dir)/HTMLTokenizerNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_names.py',
+ 'html/parser/HTMLTokenizerNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'InputTypeNames',
+ 'inputs': [
+ '<@(make_names_files)',
+ 'html/forms/InputTypeNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/InputTypeNames.cpp',
+ '<(blink_core_output_dir)/InputTypeNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_names.py',
+ 'html/forms/InputTypeNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'XLinkNames',
+ 'inputs': [
+ '<@(make_qualified_names_files)',
+ 'svg/xlinkattrs.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/XLinkNames.cpp',
+ '<(blink_core_output_dir)/XLinkNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_qualified_names.py',
+ 'svg/xlinkattrs.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'XMLNSNames',
+ 'inputs': [
+ '<@(make_qualified_names_files)',
+ 'xml/xmlnsattrs.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/XMLNSNames.cpp',
+ '<(blink_core_output_dir)/XMLNSNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_qualified_names.py',
+ 'xml/xmlnsattrs.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'XMLNames',
+ 'inputs': [
+ '<@(make_qualified_names_files)',
+ 'xml/xmlattrs.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/XMLNames.cpp',
+ '<(blink_core_output_dir)/XMLNames.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_qualified_names.py',
+ 'xml/xmlattrs.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ {
+ 'action_name': 'MakeTokenMatcher',
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_token_matcher.py',
+ '../core/css/CSSTokenizer-in.cpp',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/CSSTokenizer.cpp',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_token_matcher.py',
+ '../core/css/CSSTokenizer-in.cpp',
+ '<(blink_core_output_dir)/CSSTokenizer.cpp',
+ ],
+ },
+ {
+ 'action_name': 'MakeParser',
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_token_matcher.py',
+ '../core/css/parser/BisonCSSParser-in.cpp',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/BisonCSSParser.cpp',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_token_matcher.py',
+ '../core/css/parser/BisonCSSParser-in.cpp',
+ '<(blink_core_output_dir)/BisonCSSParser.cpp',
+ ],
+ },
+ {
+ 'action_name': 'MakeTokenMatcherForViewport',
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_token_matcher.py',
+ '../core/html/HTMLMetaElement-in.cpp',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/HTMLMetaElement.cpp',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_token_matcher.py',
+ '../core/html/HTMLMetaElement-in.cpp',
+ '<(blink_core_output_dir)/HTMLMetaElement.cpp',
+ ],
+ },
+ {
+ 'action_name': 'HTMLElementLookupTrie',
+ 'inputs': [
+ '<@(scripts_for_in_files)',
+ '../build/scripts/make_element_lookup_trie.py',
+ '../build/scripts/templates/ElementLookupTrie.cpp.tmpl',
+ '../build/scripts/templates/ElementLookupTrie.h.tmpl',
+ 'html/HTMLTagNames.in',
+ ],
+ 'outputs': [
+ '<(blink_core_output_dir)/HTMLElementLookupTrie.cpp',
+ '<(blink_core_output_dir)/HTMLElementLookupTrie.h',
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/make_element_lookup_trie.py',
+ 'html/HTMLTagNames.in',
+ '--output_dir',
+ '<(blink_core_output_dir)',
+ ],
+ },
+ ],
+ 'rules': [
+ {
+ 'rule_name': 'bison',
+ 'extension': 'y',
+ 'outputs': [
+ '<(blink_core_output_dir)/<(RULE_INPUT_ROOT).cpp',
+ '<(blink_core_output_dir)/<(RULE_INPUT_ROOT).h'
+ ],
+ 'action': [
+ 'python',
+ '../build/scripts/rule_bison.py',
+ '<(RULE_INPUT_PATH)',
+ '<(blink_core_output_dir)',
+ '<(bison_exe)',
+ ],
+ },
+ ],
+ },
+ ],
+}
diff --git a/chromium/third_party/WebKit/Source/core/core_generated.gypi b/chromium/third_party/WebKit/Source/core/core_generated.gypi
new file mode 100644
index 00000000000..ad60ff009b6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/core_generated.gypi
@@ -0,0 +1,9 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+ 'variables': {
+ 'blink_core_output_dir': '<(SHARED_INTERMEDIATE_DIR)/blink/core',
+ },
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/AffectedByFocusTest.cpp b/chromium/third_party/WebKit/Source/core/css/AffectedByFocusTest.cpp
new file mode 100644
index 00000000000..c2c4467ba29
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/AffectedByFocusTest.cpp
@@ -0,0 +1,316 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/NodeRenderStyle.h"
+#include "core/frame/FrameView.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/HTMLElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+namespace {
+
+class AffectedByFocusTest : public ::testing::Test {
+
+protected:
+
+ struct ElementResult {
+ const WebCore::QualifiedName tag;
+ bool affectedBy;
+ bool childrenOrSiblingsAffectedBy;
+ };
+
+ virtual void SetUp() OVERRIDE;
+
+ HTMLDocument& document() const { return *m_document; }
+
+ void setHtmlInnerHTML(const char* htmlContent);
+
+ void checkElements(ElementResult expected[], unsigned expectedCount) const;
+
+private:
+ OwnPtr<DummyPageHolder> m_dummyPageHolder;
+
+ HTMLDocument* m_document;
+};
+
+void AffectedByFocusTest::SetUp()
+{
+ m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+ m_document = toHTMLDocument(&m_dummyPageHolder->document());
+ ASSERT(m_document);
+}
+
+void AffectedByFocusTest::setHtmlInnerHTML(const char* htmlContent)
+{
+ document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent), ASSERT_NO_EXCEPTION);
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+}
+
+void AffectedByFocusTest::checkElements(ElementResult expected[], unsigned expectedCount) const
+{
+ unsigned i = 0;
+ Element* elm = document().body();
+
+ for (; elm && i < expectedCount; elm = ElementTraversal::next(*elm), ++i) {
+ ASSERT_TRUE(elm->hasTagName(expected[i].tag));
+ ASSERT(elm->renderStyle());
+ ASSERT_EQ(expected[i].affectedBy, elm->renderStyle()->affectedByFocus());
+ ASSERT_EQ(expected[i].childrenOrSiblingsAffectedBy, elm->childrenOrSiblingsAffectedByFocus());
+ }
+
+ ASSERT(!elm && i == expectedCount);
+}
+
+// A global :focus rule in html.css currently causes every single element to be
+// affectedByFocus. Check that all elements in a document with no :focus rules
+// gets the affectedByFocus set on RenderStyle and not childrenOrSiblingsAffectedByFocus.
+TEST_F(AffectedByFocusTest, UAUniversalFocusRule)
+{
+ ElementResult expected[] = {
+ { bodyTag, true, false },
+ { divTag, true, false },
+ { divTag, true, false },
+ { divTag, true, false },
+ { spanTag, true, false }
+ };
+
+ setHtmlInnerHTML("<body>"
+ "<div><div></div></div>"
+ "<div><span></span></div>"
+ "</body>");
+
+ checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+// ":focus div" will mark ascendants of all divs with childrenOrSiblingsAffectedByFocus.
+TEST_F(AffectedByFocusTest, FocusedAscendant)
+{
+ ElementResult expected[] = {
+ { bodyTag, true, true },
+ { divTag, true, true },
+ { divTag, true, false },
+ { divTag, true, false },
+ { spanTag, true, false }
+ };
+
+ setHtmlInnerHTML("<head>"
+ "<style>:focus div { background-color: pink }</style>"
+ "</head>"
+ "<body>"
+ "<div><div></div></div>"
+ "<div><span></span></div>"
+ "</body>");
+
+ checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+// "body:focus div" will mark the body element with childrenOrSiblingsAffectedByFocus.
+TEST_F(AffectedByFocusTest, FocusedAscendantWithType)
+{
+ ElementResult expected[] = {
+ { bodyTag, true, true },
+ { divTag, true, false },
+ { divTag, true, false },
+ { divTag, true, false },
+ { spanTag, true, false }
+ };
+
+ setHtmlInnerHTML("<head>"
+ "<style>body:focus div { background-color: pink }</style>"
+ "</head>"
+ "<body>"
+ "<div><div></div></div>"
+ "<div><span></span></div>"
+ "</body>");
+
+ checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+// ":not(body):focus div" should not mark the body element with childrenOrSiblingsAffectedByFocus.
+// Note that currently ":focus:not(body)" does not do the same. Then the :focus is
+// checked and the childrenOrSiblingsAffectedByFocus flag set before the negated type selector
+// is found.
+TEST_F(AffectedByFocusTest, FocusedAscendantWithNegatedType)
+{
+ ElementResult expected[] = {
+ { bodyTag, true, false },
+ { divTag, true, true },
+ { divTag, true, false },
+ { divTag, true, false },
+ { spanTag, true, false }
+ };
+
+ setHtmlInnerHTML("<head>"
+ "<style>:not(body):focus div { background-color: pink }</style>"
+ "</head>"
+ "<body>"
+ "<div><div></div></div>"
+ "<div><span></span></div>"
+ "</body>");
+
+ checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+// Checking current behavior for ":focus + div", but this is a BUG or at best
+// sub-optimal. The focused element will also in this case get childrenOrSiblingsAffectedByFocus
+// even if it's really a sibling. Effectively, the whole sub-tree of the focused
+// element will have styles recalculated even though none of the children are
+// affected. There are other mechanisms that makes sure the sibling also gets its
+// styles recalculated.
+TEST_F(AffectedByFocusTest, FocusedSibling)
+{
+ ElementResult expected[] = {
+ { bodyTag, true, false },
+ { divTag, true, true },
+ { spanTag, true, false },
+ { divTag, true, false }
+ };
+
+ setHtmlInnerHTML("<head>"
+ "<style>:focus + div { background-color: pink }</style>"
+ "</head>"
+ "<body>"
+ "<div>"
+ " <span></span>"
+ "</div>"
+ "<div></div>"
+ "</body>");
+
+ checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+TEST_F(AffectedByFocusTest, AffectedByFocusUpdate)
+{
+ // Check that when focussing the outer div in the document below, you only
+ // get a single element style recalc.
+
+ setHtmlInnerHTML("<style>:focus { border: 1px solid lime; }</style>"
+ "<div id=d tabIndex=1>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "</div>");
+
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned startCount = document().styleEngine()->resolverAccessCount();
+
+ document().getElementById("d")->focus();
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned accessCount = document().styleEngine()->resolverAccessCount() - startCount;
+
+ ASSERT_EQ(1U, accessCount);
+}
+
+TEST_F(AffectedByFocusTest, ChildrenOrSiblingsAffectedByFocusUpdate)
+{
+ // Check that when focussing the outer div in the document below, you get a
+ // style recalc for the whole subtree.
+
+ setHtmlInnerHTML("<style>:focus div { border: 1px solid lime; }</style>"
+ "<div id=d tabIndex=1>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "</div>");
+
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned startCount = document().styleEngine()->resolverAccessCount();
+
+ document().getElementById("d")->focus();
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned accessCount = document().styleEngine()->resolverAccessCount() - startCount;
+
+ ASSERT_EQ(11U, accessCount);
+}
+
+TEST_F(AffectedByFocusTest, InvalidationSetFocusUpdate)
+{
+ // Check that when focussing the outer div in the document below, you get a
+ // style recalc for the outer div and the class=a div only.
+
+ setHtmlInnerHTML("<style>:focus .a { border: 1px solid lime; }</style>"
+ "<div id=d tabIndex=1>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div class='a'></div>"
+ "</div>");
+
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned startCount = document().styleEngine()->resolverAccessCount();
+
+ document().getElementById("d")->focus();
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned accessCount = document().styleEngine()->resolverAccessCount() - startCount;
+
+ ASSERT_EQ(2U, accessCount);
+}
+
+TEST_F(AffectedByFocusTest, NoInvalidationSetFocusUpdate)
+{
+ // Check that when focussing the outer div in the document below, you get a
+ // style recalc for the outer div only. The invalidation set for :focus will
+ // include 'a', but the id=d div should be affectedByFocus, not childrenOrSiblingsAffectedByFocus.
+
+ setHtmlInnerHTML("<style>#nomatch:focus .a { border: 1px solid lime; }</style>"
+ "<div id=d tabIndex=1>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div></div>"
+ "<div class='a'></div>"
+ "</div>");
+
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned startCount = document().styleEngine()->resolverAccessCount();
+
+ document().getElementById("d")->focus();
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned accessCount = document().styleEngine()->resolverAccessCount() - startCount;
+
+ ASSERT_EQ(1U, accessCount);
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp b/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp
index a49ea1495f1..e6399b99187 100644
--- a/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp
@@ -33,58 +33,68 @@
#include "core/css/CSSBasicShapes.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSValuePool.h"
+#include "core/css/Pair.h"
#include "core/css/resolver/StyleResolverState.h"
#include "core/rendering/style/BasicShapes.h"
#include "core/rendering/style/RenderStyle.h"
namespace WebCore {
-PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape* basicShape)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForCenterCoordinate(CSSValuePool& pool, const RenderStyle& style, const BasicShapeCenterCoordinate& center, EBoxOrient orientation)
+{
+ if (center.direction() == BasicShapeCenterCoordinate::TopLeft)
+ return pool.createValue(center.length(), style);
+
+ CSSValueID keyword = orientation == HORIZONTAL ? CSSValueRight : CSSValueBottom;
+
+ return pool.createValue(Pair::create(pool.createIdentifierValue(keyword), pool.createValue(center.length(), style), Pair::DropIdenticalValues));
+}
+
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> basicShapeRadiusToCSSValue(CSSValuePool& pool, const RenderStyle& style, const BasicShapeRadius& radius)
+{
+ switch (radius.type()) {
+ case BasicShapeRadius::Value:
+ return pool.createValue(radius.value(), style);
+ case BasicShapeRadius::ClosestSide:
+ return pool.createIdentifierValue(CSSValueClosestSide);
+ case BasicShapeRadius::FarthestSide:
+ return pool.createIdentifierValue(CSSValueFarthestSide);
+ }
+
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape* basicShape)
{
CSSValuePool& pool = cssValuePool();
- RefPtr<CSSBasicShape> basicShapeValue;
+ RefPtrWillBeRawPtr<CSSBasicShape> basicShapeValue = nullptr;
switch (basicShape->type()) {
- case BasicShape::BasicShapeRectangleType: {
- const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
- RefPtr<CSSBasicShapeRectangle> rectangleValue = CSSBasicShapeRectangle::create();
-
- rectangleValue->setX(pool.createValue(rectangle->x(), style));
- rectangleValue->setY(pool.createValue(rectangle->y(), style));
- rectangleValue->setWidth(pool.createValue(rectangle->width(), style));
- rectangleValue->setHeight(pool.createValue(rectangle->height(), style));
- rectangleValue->setRadiusX(pool.createValue(rectangle->cornerRadiusX(), style));
- rectangleValue->setRadiusY(pool.createValue(rectangle->cornerRadiusY(), style));
-
- basicShapeValue = rectangleValue.release();
- break;
- }
case BasicShape::BasicShapeCircleType: {
const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
- RefPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
-
- circleValue->setCenterX(pool.createValue(circle->centerX(), style));
- circleValue->setCenterY(pool.createValue(circle->centerY(), style));
- circleValue->setRadius(pool.createValue(circle->radius(), style));
+ RefPtrWillBeRawPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
+ circleValue->setCenterX(valueForCenterCoordinate(pool, style, circle->centerX(), HORIZONTAL));
+ circleValue->setCenterY(valueForCenterCoordinate(pool, style, circle->centerY(), VERTICAL));
+ circleValue->setRadius(basicShapeRadiusToCSSValue(pool, style, circle->radius()));
basicShapeValue = circleValue.release();
break;
}
case BasicShape::BasicShapeEllipseType: {
const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
- RefPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
-
- ellipseValue->setCenterX(pool.createValue(ellipse->centerX(), style));
- ellipseValue->setCenterY(pool.createValue(ellipse->centerY(), style));
- ellipseValue->setRadiusX(pool.createValue(ellipse->radiusX(), style));
- ellipseValue->setRadiusY(pool.createValue(ellipse->radiusY(), style));
+ RefPtrWillBeRawPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
+ ellipseValue->setCenterX(valueForCenterCoordinate(pool, style, ellipse->centerX(), HORIZONTAL));
+ ellipseValue->setCenterY(valueForCenterCoordinate(pool, style, ellipse->centerY(), VERTICAL));
+ ellipseValue->setRadiusX(basicShapeRadiusToCSSValue(pool, style, ellipse->radiusX()));
+ ellipseValue->setRadiusY(basicShapeRadiusToCSSValue(pool, style, ellipse->radiusY()));
basicShapeValue = ellipseValue.release();
break;
}
case BasicShape::BasicShapePolygonType: {
const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>(basicShape);
- RefPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();
+ RefPtrWillBeRawPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();
polygonValue->setWindRule(polygon->windRule());
const Vector<Length>& values = polygon->values();
@@ -94,65 +104,117 @@ PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicSha
basicShapeValue = polygonValue.release();
break;
}
- case BasicShape::BasicShapeInsetRectangleType: {
- const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShapeInsetRectangle*>(basicShape);
- RefPtr<CSSBasicShapeInsetRectangle> rectangleValue = CSSBasicShapeInsetRectangle::create();
-
- rectangleValue->setTop(cssValuePool().createValue(rectangle->top()));
- rectangleValue->setRight(cssValuePool().createValue(rectangle->right()));
- rectangleValue->setBottom(cssValuePool().createValue(rectangle->bottom()));
- rectangleValue->setLeft(cssValuePool().createValue(rectangle->left()));
- rectangleValue->setRadiusX(cssValuePool().createValue(rectangle->cornerRadiusX()));
- rectangleValue->setRadiusY(cssValuePool().createValue(rectangle->cornerRadiusY()));
-
- basicShapeValue = rectangleValue.release();
+ case BasicShape::BasicShapeInsetType: {
+ const BasicShapeInset* inset = static_cast<const BasicShapeInset*>(basicShape);
+ RefPtrWillBeRawPtr<CSSBasicShapeInset> insetValue = CSSBasicShapeInset::create();
+
+ insetValue->setTop(pool.createValue(inset->top(), style));
+ insetValue->setRight(pool.createValue(inset->right(), style));
+ insetValue->setBottom(pool.createValue(inset->bottom(), style));
+ insetValue->setLeft(pool.createValue(inset->left(), style));
+
+ insetValue->setTopLeftRadius(CSSPrimitiveValue::create(inset->topLeftRadius(), style));
+ insetValue->setTopRightRadius(CSSPrimitiveValue::create(inset->topRightRadius(), style));
+ insetValue->setBottomRightRadius(CSSPrimitiveValue::create(inset->bottomRightRadius(), style));
+ insetValue->setBottomLeftRadius(CSSPrimitiveValue::create(inset->bottomLeftRadius(), style));
+
+ basicShapeValue = insetValue.release();
break;
}
default:
break;
}
+
return pool.createValue(basicShapeValue.release());
}
static Length convertToLength(const StyleResolverState& state, CSSPrimitiveValue* value)
{
+ if (!value)
+ return Length(0, Fixed);
return value->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
}
+static LengthSize convertToLengthSize(const StyleResolverState& state, CSSPrimitiveValue* value)
+{
+ if (!value)
+ return LengthSize(Length(0, Fixed), Length(0, Fixed));
+
+ Pair* pair = value->getPairValue();
+ return LengthSize(convertToLength(state, pair->first()), convertToLength(state, pair->second()));
+}
+
+static BasicShapeCenterCoordinate convertToCenterCoordinate(const StyleResolverState& state, CSSPrimitiveValue* value)
+{
+ BasicShapeCenterCoordinate::Direction direction;
+ Length offset = Length(0, Fixed);
+
+ CSSValueID keyword = CSSValueTop;
+ if (!value) {
+ keyword = CSSValueCenter;
+ } else if (value->isValueID()) {
+ keyword = value->getValueID();
+ } else if (Pair* pair = value->getPairValue()) {
+ keyword = pair->first()->getValueID();
+ offset = convertToLength(state, pair->second());
+ } else {
+ offset = convertToLength(state, value);
+ }
+
+ switch (keyword) {
+ case CSSValueTop:
+ case CSSValueLeft:
+ direction = BasicShapeCenterCoordinate::TopLeft;
+ break;
+ case CSSValueRight:
+ case CSSValueBottom:
+ direction = BasicShapeCenterCoordinate::BottomRight;
+ break;
+ case CSSValueCenter:
+ direction = BasicShapeCenterCoordinate::TopLeft;
+ offset = Length(50, Percent);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ direction = BasicShapeCenterCoordinate::TopLeft;
+ break;
+ }
+
+ return BasicShapeCenterCoordinate(direction, offset);
+}
+
+static BasicShapeRadius cssValueToBasicShapeRadius(const StyleResolverState& state, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius)
+{
+ if (!radius)
+ return BasicShapeRadius(BasicShapeRadius::ClosestSide);
+
+ if (radius->isValueID()) {
+ switch (radius->getValueID()) {
+ case CSSValueClosestSide:
+ return BasicShapeRadius(BasicShapeRadius::ClosestSide);
+ case CSSValueFarthestSide:
+ return BasicShapeRadius(BasicShapeRadius::FarthestSide);
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+
+ return BasicShapeRadius(convertToLength(state, radius.get()));
+}
+
PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const CSSBasicShape* basicShapeValue)
{
RefPtr<BasicShape> basicShape;
switch (basicShapeValue->type()) {
- case CSSBasicShape::CSSBasicShapeRectangleType: {
- const CSSBasicShapeRectangle* rectValue = static_cast<const CSSBasicShapeRectangle *>(basicShapeValue);
- RefPtr<BasicShapeRectangle> rect = BasicShapeRectangle::create();
-
- rect->setX(convertToLength(state, rectValue->x()));
- rect->setY(convertToLength(state, rectValue->y()));
- rect->setWidth(convertToLength(state, rectValue->width()));
- rect->setHeight(convertToLength(state, rectValue->height()));
- if (rectValue->radiusX()) {
- Length radiusX = convertToLength(state, rectValue->radiusX());
- rect->setCornerRadiusX(radiusX);
- if (rectValue->radiusY())
- rect->setCornerRadiusY(convertToLength(state, rectValue->radiusY()));
- else
- rect->setCornerRadiusY(radiusX);
- } else {
- rect->setCornerRadiusX(Length(0, Fixed));
- rect->setCornerRadiusY(Length(0, Fixed));
- }
- basicShape = rect.release();
- break;
- }
case CSSBasicShape::CSSBasicShapeCircleType: {
const CSSBasicShapeCircle* circleValue = static_cast<const CSSBasicShapeCircle *>(basicShapeValue);
RefPtr<BasicShapeCircle> circle = BasicShapeCircle::create();
- circle->setCenterX(convertToLength(state, circleValue->centerX()));
- circle->setCenterY(convertToLength(state, circleValue->centerY()));
- circle->setRadius(convertToLength(state, circleValue->radius()));
+ circle->setCenterX(convertToCenterCoordinate(state, circleValue->centerX()));
+ circle->setCenterY(convertToCenterCoordinate(state, circleValue->centerY()));
+ circle->setRadius(cssValueToBasicShapeRadius(state, circleValue->radius()));
basicShape = circle.release();
break;
@@ -161,10 +223,10 @@ PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const
const CSSBasicShapeEllipse* ellipseValue = static_cast<const CSSBasicShapeEllipse *>(basicShapeValue);
RefPtr<BasicShapeEllipse> ellipse = BasicShapeEllipse::create();
- ellipse->setCenterX(convertToLength(state, ellipseValue->centerX()));
- ellipse->setCenterY(convertToLength(state, ellipseValue->centerY()));
- ellipse->setRadiusX(convertToLength(state, ellipseValue->radiusX()));
- ellipse->setRadiusY(convertToLength(state, ellipseValue->radiusY()));
+ ellipse->setCenterX(convertToCenterCoordinate(state, ellipseValue->centerX()));
+ ellipse->setCenterY(convertToCenterCoordinate(state, ellipseValue->centerY()));
+ ellipse->setRadiusX(cssValueToBasicShapeRadius(state, ellipseValue->radiusX()));
+ ellipse->setRadiusY(cssValueToBasicShapeRadius(state, ellipseValue->radiusY()));
basicShape = ellipse.release();
break;
@@ -174,38 +236,45 @@ PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState& state, const
RefPtr<BasicShapePolygon> polygon = BasicShapePolygon::create();
polygon->setWindRule(polygonValue->windRule());
- const Vector<RefPtr<CSSPrimitiveValue> >& values = polygonValue->values();
+ const WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> >& values = polygonValue->values();
for (unsigned i = 0; i < values.size(); i += 2)
polygon->appendPoint(convertToLength(state, values.at(i).get()), convertToLength(state, values.at(i + 1).get()));
basicShape = polygon.release();
break;
}
- case CSSBasicShape::CSSBasicShapeInsetRectangleType: {
- const CSSBasicShapeInsetRectangle* rectValue = static_cast<const CSSBasicShapeInsetRectangle *>(basicShapeValue);
- RefPtr<BasicShapeInsetRectangle> rect = BasicShapeInsetRectangle::create();
+ case CSSBasicShape::CSSBasicShapeInsetType: {
+ const CSSBasicShapeInset* rectValue = static_cast<const CSSBasicShapeInset* >(basicShapeValue);
+ RefPtr<BasicShapeInset> rect = BasicShapeInset::create();
rect->setTop(convertToLength(state, rectValue->top()));
rect->setRight(convertToLength(state, rectValue->right()));
rect->setBottom(convertToLength(state, rectValue->bottom()));
rect->setLeft(convertToLength(state, rectValue->left()));
- if (rectValue->radiusX()) {
- Length radiusX = convertToLength(state, rectValue->radiusX());
- rect->setCornerRadiusX(radiusX);
- if (rectValue->radiusY())
- rect->setCornerRadiusY(convertToLength(state, rectValue->radiusY()));
- else
- rect->setCornerRadiusY(radiusX);
- } else {
- rect->setCornerRadiusX(Length(0, Fixed));
- rect->setCornerRadiusY(Length(0, Fixed));
- }
+
+ rect->setTopLeftRadius(convertToLengthSize(state, rectValue->topLeftRadius()));
+ rect->setTopRightRadius(convertToLengthSize(state, rectValue->topRightRadius()));
+ rect->setBottomRightRadius(convertToLengthSize(state, rectValue->bottomRightRadius()));
+ rect->setBottomLeftRadius(convertToLengthSize(state, rectValue->bottomLeftRadius()));
+
basicShape = rect.release();
break;
}
default:
break;
}
+
return basicShape.release();
}
+
+FloatPoint floatPointForCenterCoordinate(const BasicShapeCenterCoordinate& centerX, const BasicShapeCenterCoordinate& centerY, FloatSize boxSize)
+{
+ FloatPoint p;
+ float offset = floatValueForLength(centerX.length(), boxSize.width());
+ p.setX(centerX.direction() == BasicShapeCenterCoordinate::TopLeft ? offset : boxSize.width() - offset);
+ offset = floatValueForLength(centerY.length(), boxSize.height());
+ p.setY(centerY.direction() == BasicShapeCenterCoordinate::TopLeft ? offset : boxSize.height() - offset);
+ return p;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.h b/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.h
index 7d07e311a2e..ab1fdcc93ca 100644
--- a/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.h
+++ b/chromium/third_party/WebKit/Source/core/css/BasicShapeFunctions.h
@@ -30,6 +30,8 @@
#ifndef BasicShapeFunctions_h
#define BasicShapeFunctions_h
+#include "core/rendering/style/BasicShapes.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
@@ -37,11 +39,13 @@ namespace WebCore {
class BasicShape;
class CSSBasicShape;
class CSSValue;
+class FloatPoint;
class StyleResolverState;
class RenderStyle;
-PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle&, const BasicShape*);
+PassRefPtrWillBeRawPtr<CSSValue> valueForBasicShape(const RenderStyle&, const BasicShape*);
PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState&, const CSSBasicShape*);
+FloatPoint floatPointForCenterCoordinate(const BasicShapeCenterCoordinate&, const BasicShapeCenterCoordinate&, FloatSize);
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp b/chromium/third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp
new file mode 100644
index 00000000000..c32f8ede4e9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/BinaryDataFontFaceSource.h"
+
+#include "platform/SharedBuffer.h"
+#include "platform/fonts/FontCustomPlatformData.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+
+namespace WebCore {
+
+BinaryDataFontFaceSource::BinaryDataFontFaceSource(SharedBuffer* data)
+ : m_customPlatformData(FontCustomPlatformData::create(data))
+{
+}
+
+BinaryDataFontFaceSource::~BinaryDataFontFaceSource()
+{
+}
+
+bool BinaryDataFontFaceSource::isValid() const
+{
+ return m_customPlatformData;
+}
+
+PassRefPtr<SimpleFontData> BinaryDataFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+ return SimpleFontData::create(
+ m_customPlatformData->fontPlatformData(fontDescription.effectiveFontSize(),
+ fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic(),
+ fontDescription.orientation(), fontDescription.widthVariant()), CustomFontData::create());
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.h b/chromium/third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.h
new file mode 100644
index 00000000000..766bbbb3b32
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.h
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BinaryDataFontFaceSource_h
+#define BinaryDataFontFaceSource_h
+
+#include "core/css/CSSFontFaceSource.h"
+#include "wtf/OwnPtr.h"
+
+namespace WebCore {
+
+class FontCustomPlatformData;
+class SharedBuffer;
+
+class BinaryDataFontFaceSource FINAL : public CSSFontFaceSource {
+public:
+ explicit BinaryDataFontFaceSource(SharedBuffer*);
+ virtual ~BinaryDataFontFaceSource();
+ virtual bool isValid() const OVERRIDE;
+
+private:
+ virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+
+ OwnPtr<FontCustomPlatformData> m_customPlatformData;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/CSS.idl b/chromium/third_party/WebKit/Source/core/css/CSS.idl
index 4ba9ba74af4..36fe6dacce8 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSS.idl
+++ b/chromium/third_party/WebKit/Source/core/css/CSS.idl
@@ -29,7 +29,8 @@
[
NoInterfaceObject,
- ImplementedAs=DOMWindowCSS
+ ImplementedAs=DOMWindowCSS,
+ WillBeGarbageCollected
] interface CSS {
boolean supports(DOMString property, DOMString value);
boolean supports(DOMString conditionText);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp
index 3ead9d8137b..1c1d6c44fe6 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp
@@ -47,9 +47,9 @@ String CSSArrayFunctionValue::customCSSText() const
return "array(" + CSSValueList::customCSSText() + ')';
}
-PassRefPtr<CSSArrayFunctionValue> CSSArrayFunctionValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSArrayFunctionValue> CSSArrayFunctionValue::cloneForCSSOM() const
{
- return adoptRef(new CSSArrayFunctionValue(*this));
+ return adoptRefWillBeNoop(new CSSArrayFunctionValue(*this));
}
bool CSSArrayFunctionValue::equals(const CSSArrayFunctionValue& other) const
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.h b/chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.h
index fffc616c32d..ebf1575a8e4 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSArrayFunctionValue.h
@@ -37,17 +37,19 @@ namespace WebCore {
class CSSArrayFunctionValue : public CSSValueList {
public:
- static PassRefPtr<CSSArrayFunctionValue> create()
+ static PassRefPtrWillBeRawPtr<CSSArrayFunctionValue> create()
{
- return adoptRef(new CSSArrayFunctionValue());
+ return adoptRefWillBeNoop(new CSSArrayFunctionValue());
}
String customCSSText() const;
- PassRefPtr<CSSArrayFunctionValue> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<CSSArrayFunctionValue> cloneForCSSOM() const;
bool equals(const CSSArrayFunctionValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValueList::traceAfterDispatch(visitor); }
+
private:
CSSArrayFunctionValue();
explicit CSSArrayFunctionValue(const CSSArrayFunctionValue& cloneFrom);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSAspectRatioValue.h b/chromium/third_party/WebKit/Source/core/css/CSSAspectRatioValue.h
index a92ac34c2bb..bb86a0bffc9 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSAspectRatioValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSAspectRatioValue.h
@@ -35,9 +35,9 @@ namespace WebCore {
class CSSAspectRatioValue : public CSSValue {
public:
- static PassRefPtr<CSSAspectRatioValue> create(float numeratorValue, float denominatorValue)
+ static PassRefPtrWillBeRawPtr<CSSAspectRatioValue> create(float numeratorValue, float denominatorValue)
{
- return adoptRef(new CSSAspectRatioValue(numeratorValue, denominatorValue));
+ return adoptRefWillBeNoop(new CSSAspectRatioValue(numeratorValue, denominatorValue));
}
String customCSSText() const;
@@ -47,6 +47,8 @@ public:
bool equals(const CSSAspectRatioValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
CSSAspectRatioValue(float numeratorValue, float denominatorValue)
: CSSValue(AspectRatioClass)
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.cpp b/chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.cpp
index 1104f176ef9..2f326c9e0f2 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.cpp
@@ -30,91 +30,98 @@
#include "config.h"
#include "core/css/CSSBasicShapes.h"
+#include "core/css/CSSValuePool.h"
+#include "core/css/Pair.h"
+#include "platform/Length.h"
#include "wtf/text/StringBuilder.h"
using namespace WTF;
namespace WebCore {
-static String buildRectangleString(const String& x, const String& y, const String& width, const String& height, const String& radiusX, const String& radiusY)
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSBasicShape)
+
+static String buildCircleString(const String& radius, const String& centerX, const String& centerY, const String& box)
{
- char opening[] = "rectangle(";
- char separator[] = ", ";
+ char at[] = "at";
+ char separator[] = " ";
StringBuilder result;
- // Compute the required capacity in advance to reduce allocations.
- result.reserveCapacity((sizeof(opening) - 1) + (5 * (sizeof(separator) - 1)) + 1 + x.length() + y.length() + width.length() + height.length() + radiusX.length() + radiusY.length());
- result.appendLiteral(opening);
- result.append(x);
- result.appendLiteral(separator);
- result.append(y);
- result.appendLiteral(separator);
- result.append(width);
- result.appendLiteral(separator);
- result.append(height);
- if (!radiusX.isNull()) {
- result.appendLiteral(separator);
- result.append(radiusX);
- if (!radiusY.isNull()) {
+ result.appendLiteral("circle(");
+ if (!radius.isNull())
+ result.append(radius);
+
+ if (!centerX.isNull() || !centerY.isNull()) {
+ if (!radius.isNull())
result.appendLiteral(separator);
- result.append(radiusY);
- }
+ result.append(at);
+ result.appendLiteral(separator);
+ result.append(centerX);
+ result.appendLiteral(separator);
+ result.append(centerY);
+ }
+ result.append(")");
+ if (box.length()) {
+ result.appendLiteral(separator);
+ result.append(box);
}
- result.append(')');
return result.toString();
}
-String CSSBasicShapeRectangle::cssText() const
+static String serializePositionOffset(const Pair& offset, const Pair& other)
{
- return buildRectangleString(m_x->cssText(),
- m_y->cssText(),
- m_width->cssText(),
- m_height->cssText(),
- m_radiusX.get() ? m_radiusX->cssText() : String(),
- m_radiusY.get() ? m_radiusY->cssText() : String());
+ if ((offset.first()->getValueID() == CSSValueLeft && other.first()->getValueID() == CSSValueTop)
+ || (offset.first()->getValueID() == CSSValueTop && other.first()->getValueID() == CSSValueLeft))
+ return offset.second()->cssText();
+ return offset.cssText();
}
-bool CSSBasicShapeRectangle::equals(const CSSBasicShape& shape) const
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> buildSerializablePositionOffset(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, CSSValueID defaultSide)
{
- if (shape.type() != CSSBasicShapeRectangleType)
- return false;
+ CSSValueID side = defaultSide;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> amount = nullptr;
+
+ if (!offset) {
+ side = CSSValueCenter;
+ } else if (offset->isValueID()) {
+ side = offset->getValueID();
+ } else if (Pair* pair = offset->getPairValue()) {
+ side = pair->first()->getValueID();
+ amount = pair->second();
+ } else {
+ amount = offset;
+ }
- const CSSBasicShapeRectangle& other = static_cast<const CSSBasicShapeRectangle&>(shape);
- return compareCSSValuePtr(m_x, other.m_x)
- && compareCSSValuePtr(m_y, other.m_y)
- && compareCSSValuePtr(m_width, other.m_width)
- && compareCSSValuePtr(m_height, other.m_height)
- && compareCSSValuePtr(m_radiusX, other.m_radiusX)
- && compareCSSValuePtr(m_radiusY, other.m_radiusY);
-}
+ if (side == CSSValueCenter) {
+ side = defaultSide;
+ amount = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+ } else if ((side == CSSValueRight || side == CSSValueBottom)
+ && amount->isPercentage()) {
+ side = defaultSide;
+ amount = cssValuePool().createValue(100 - amount->getFloatValue(), CSSPrimitiveValue::CSS_PERCENTAGE);
+ } else if (amount->isLength() && !amount->getFloatValue()) {
+ if (side == CSSValueRight || side == CSSValueBottom)
+ amount = cssValuePool().createValue(100, CSSPrimitiveValue::CSS_PERCENTAGE);
+ else
+ amount = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
+ side = defaultSide;
+ }
-String CSSBasicShapeRectangle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- return buildRectangleString(m_x->serializeResolvingVariables(variables),
- m_y->serializeResolvingVariables(variables),
- m_width->serializeResolvingVariables(variables),
- m_height->serializeResolvingVariables(variables),
- m_radiusX.get() ? m_radiusX->serializeResolvingVariables(variables) : String(),
- m_radiusY.get() ? m_radiusY->serializeResolvingVariables(variables) : String());
+ return cssValuePool().createValue(Pair::create(cssValuePool().createValue(side), amount.release(), Pair::KeepIdenticalValues));
}
-bool CSSBasicShapeRectangle::hasVariableReference() const
+String CSSBasicShapeCircle::cssText() const
{
- return m_x->hasVariableReference()
- || m_y->hasVariableReference()
- || m_width->hasVariableReference()
- || m_height->hasVariableReference()
- || (m_radiusX.get() && m_radiusX->hasVariableReference())
- || (m_radiusY.get() && m_radiusY->hasVariableReference());
-}
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCX = buildSerializablePositionOffset(m_centerX, CSSValueLeft);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCY = buildSerializablePositionOffset(m_centerY, CSSValueTop);
-static String buildCircleString(const String& x, const String& y, const String& radius)
-{
- return "circle(" + x + ", " + y + ", " + radius + ')';
-}
+ String radius;
+ if (m_radius && m_radius->getValueID() != CSSValueClosestSide)
+ radius = m_radius->cssText();
-String CSSBasicShapeCircle::cssText() const
-{
- return buildCircleString(m_centerX->cssText(), m_centerY->cssText(), m_radius->cssText());
+ return buildCircleString(radius,
+ serializePositionOffset(*normalizedCX->getPairValue(), *normalizedCY->getPairValue()),
+ serializePositionOffset(*normalizedCY->getPairValue(), *normalizedCX->getPairValue()),
+ m_referenceBox ? m_referenceBox->cssText() : String());
}
bool CSSBasicShapeCircle::equals(const CSSBasicShape& shape) const
@@ -125,31 +132,77 @@ bool CSSBasicShapeCircle::equals(const CSSBasicShape& shape) const
const CSSBasicShapeCircle& other = static_cast<const CSSBasicShapeCircle&>(shape);
return compareCSSValuePtr(m_centerX, other.m_centerX)
&& compareCSSValuePtr(m_centerY, other.m_centerY)
- && compareCSSValuePtr(m_radius, other.m_radius);
+ && compareCSSValuePtr(m_radius, other.m_radius)
+ && compareCSSValuePtr(m_referenceBox, other.m_referenceBox);
}
-String CSSBasicShapeCircle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
+void CSSBasicShapeCircle::trace(Visitor* visitor)
{
- return buildCircleString(m_centerX->serializeResolvingVariables(variables),
- m_centerY->serializeResolvingVariables(variables),
- m_radius->serializeResolvingVariables(variables));
+ visitor->trace(m_centerX);
+ visitor->trace(m_centerY);
+ visitor->trace(m_radius);
+ CSSBasicShape::trace(visitor);
}
-bool CSSBasicShapeCircle::hasVariableReference() const
+static String buildEllipseString(const String& radiusX, const String& radiusY, const String& centerX, const String& centerY, const String& box)
{
- return m_centerX->hasVariableReference()
- || m_centerY->hasVariableReference()
- || m_radius->hasVariableReference();
-}
+ char at[] = "at";
+ char separator[] = " ";
+ StringBuilder result;
+ result.appendLiteral("ellipse(");
+ bool needsSeparator = false;
+ if (!radiusX.isNull()) {
+ result.append(radiusX);
+ needsSeparator = true;
+ }
+ if (!radiusY.isNull()) {
+ if (needsSeparator)
+ result.appendLiteral(separator);
+ result.append(radiusY);
+ needsSeparator = true;
+ }
-static String buildEllipseString(const String& x, const String& y, const String& radiusX, const String& radiusY)
-{
- return "ellipse(" + x + ", " + y + ", " + radiusX + ", " + radiusY + ')';
+ if (!centerX.isNull() || !centerY.isNull()) {
+ if (needsSeparator)
+ result.appendLiteral(separator);
+ result.appendLiteral(at);
+ result.appendLiteral(separator);
+ result.append(centerX);
+ result.appendLiteral(separator);
+ result.append(centerY);
+ }
+ result.append(")");
+ if (box.length()) {
+ result.appendLiteral(separator);
+ result.append(box);
+ }
+ return result.toString();
}
String CSSBasicShapeEllipse::cssText() const
{
- return buildEllipseString(m_centerX->cssText(), m_centerY->cssText(), m_radiusX->cssText(), m_radiusY->cssText());
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCX = buildSerializablePositionOffset(m_centerX, CSSValueLeft);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCY = buildSerializablePositionOffset(m_centerY, CSSValueTop);
+
+ String radiusX;
+ String radiusY;
+ if (m_radiusX) {
+ bool shouldSerializeRadiusXValue = m_radiusX->getValueID() != CSSValueClosestSide;
+ bool shouldSerializeRadiusYValue = false;
+
+ if (m_radiusY) {
+ shouldSerializeRadiusYValue = m_radiusY->getValueID() != CSSValueClosestSide;
+ if (shouldSerializeRadiusYValue)
+ radiusY = m_radiusY->cssText();
+ }
+ if (shouldSerializeRadiusXValue || (!shouldSerializeRadiusXValue && shouldSerializeRadiusYValue))
+ radiusX = m_radiusX->cssText();
+ }
+
+ return buildEllipseString(radiusX, radiusY,
+ serializePositionOffset(*normalizedCX->getPairValue(), *normalizedCY->getPairValue()),
+ serializePositionOffset(*normalizedCY->getPairValue(), *normalizedCX->getPairValue()),
+ m_referenceBox ? m_referenceBox->cssText() : String());
}
bool CSSBasicShapeEllipse::equals(const CSSBasicShape& shape) const
@@ -161,34 +214,28 @@ bool CSSBasicShapeEllipse::equals(const CSSBasicShape& shape) const
return compareCSSValuePtr(m_centerX, other.m_centerX)
&& compareCSSValuePtr(m_centerY, other.m_centerY)
&& compareCSSValuePtr(m_radiusX, other.m_radiusX)
- && compareCSSValuePtr(m_radiusY, other.m_radiusY);
-}
-
-String CSSBasicShapeEllipse::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- return buildEllipseString(m_centerX->serializeResolvingVariables(variables),
- m_centerY->serializeResolvingVariables(variables),
- m_radiusX->serializeResolvingVariables(variables),
- m_radiusY->serializeResolvingVariables(variables));
+ && compareCSSValuePtr(m_radiusY, other.m_radiusY)
+ && compareCSSValuePtr(m_referenceBox, other.m_referenceBox);
}
-bool CSSBasicShapeEllipse::hasVariableReference() const
+void CSSBasicShapeEllipse::trace(Visitor* visitor)
{
- return m_centerX->hasVariableReference()
- || m_centerY->hasVariableReference()
- || m_radiusX->hasVariableReference()
- || m_radiusY->hasVariableReference();
+ visitor->trace(m_centerX);
+ visitor->trace(m_centerY);
+ visitor->trace(m_radiusX);
+ visitor->trace(m_radiusY);
+ CSSBasicShape::trace(visitor);
}
-static String buildPolygonString(const WindRule& windRule, const Vector<String>& points)
+static String buildPolygonString(const WindRule& windRule, const Vector<String>& points, const String& box)
{
ASSERT(!(points.size() % 2));
StringBuilder result;
- char evenOddOpening[] = "polygon(evenodd, ";
- char nonZeroOpening[] = "polygon(nonzero, ";
- char commaSeparator[] = ", ";
- COMPILE_ASSERT(sizeof(evenOddOpening) == sizeof(nonZeroOpening), polygon_string_openings_have_same_length);
+ const char evenOddOpening[] = "polygon(evenodd, ";
+ const char nonZeroOpening[] = "polygon(";
+ const char commaSeparator[] = ", ";
+ COMPILE_ASSERT(sizeof(evenOddOpening) > sizeof(nonZeroOpening), polygon_string_openings_have_same_length);
// Compute the required capacity in advance to reduce allocations.
size_t length = sizeof(evenOddOpening) - 1;
@@ -198,6 +245,8 @@ static String buildPolygonString(const WindRule& windRule, const Vector<String>&
// add length of two strings, plus one for the space separator.
length += points[i].length() + 1 + points[i + 1].length();
}
+ if (!box.isEmpty())
+ length += box.length() + 1;
result.reserveCapacity(length);
if (windRule == RULE_EVENODD)
@@ -215,6 +264,11 @@ static String buildPolygonString(const WindRule& windRule, const Vector<String>&
result.append(')');
+ if (!box.isEmpty()) {
+ result.append(' ');
+ result.append(box);
+ }
+
return result.toString();
}
@@ -226,7 +280,7 @@ String CSSBasicShapePolygon::cssText() const
for (size_t i = 0; i < m_values.size(); ++i)
points.append(m_values.at(i)->cssText());
- return buildPolygonString(m_windRule, points);
+ return buildPolygonString(m_windRule, points, m_referenceBox ? m_referenceBox->cssText() : String());
}
bool CSSBasicShapePolygon::equals(const CSSBasicShape& shape) const
@@ -235,98 +289,163 @@ bool CSSBasicShapePolygon::equals(const CSSBasicShape& shape) const
return false;
const CSSBasicShapePolygon& rhs = static_cast<const CSSBasicShapePolygon&>(shape);
- return compareCSSValueVector<CSSPrimitiveValue>(m_values, rhs.m_values);
-}
-String CSSBasicShapePolygon::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- Vector<String> points;
- points.reserveInitialCapacity(m_values.size());
+ if (!compareCSSValuePtr(m_referenceBox, rhs.m_referenceBox))
+ return false;
- for (size_t i = 0; i < m_values.size(); ++i)
- points.append(m_values.at(i)->serializeResolvingVariables(variables));
+ return compareCSSValueVector(m_values, rhs.m_values);
+}
- return buildPolygonString(m_windRule, points);
+void CSSBasicShapePolygon::trace(Visitor* visitor)
+{
+ visitor->trace(m_values);
+ CSSBasicShape::trace(visitor);
}
-bool CSSBasicShapePolygon::hasVariableReference() const
+static bool buildInsetRadii(Vector<String> &radii, const String& topLeftRadius, const String& topRightRadius, const String& bottomRightRadius, const String& bottomLeftRadius)
{
- for (size_t i = 0; i < m_values.size(); ++i) {
- if (m_values.at(i)->hasVariableReference())
- return true;
- }
- return false;
+ bool showBottomLeft = topRightRadius != bottomLeftRadius;
+ bool showBottomRight = showBottomLeft || (bottomRightRadius != topLeftRadius);
+ bool showTopRight = showBottomRight || (topRightRadius != topLeftRadius);
+
+ radii.append(topLeftRadius);
+ if (showTopRight)
+ radii.append(topRightRadius);
+ if (showBottomRight)
+ radii.append(bottomRightRadius);
+ if (showBottomLeft)
+ radii.append(bottomLeftRadius);
+
+ return radii.size() == 1 && radii[0] == "0px";
}
-static String buildInsetRectangleString(const String& top, const String& right, const String& bottom, const String& left, const String& radiusX, const String& radiusY)
+static String buildInsetString(const String& top, const String& right, const String& bottom, const String& left,
+ const String& topLeftRadiusWidth, const String& topLeftRadiusHeight,
+ const String& topRightRadiusWidth, const String& topRightRadiusHeight,
+ const String& bottomRightRadiusWidth, const String& bottomRightRadiusHeight,
+ const String& bottomLeftRadiusWidth, const String& bottomLeftRadiusHeight)
{
- char opening[] = "inset-rectangle(";
- char separator[] = ", ";
+ char opening[] = "inset(";
+ char separator[] = " ";
+ char cornersSeparator[] = "round";
StringBuilder result;
- // Compute the required capacity in advance to reduce allocations.
- result.reserveCapacity((sizeof(opening) - 1) + (5 * (sizeof(separator) - 1)) + 1 + top.length() + right.length() + bottom.length() + left.length() + radiusX.length() + radiusY.length());
result.appendLiteral(opening);
result.append(top);
- result.appendLiteral(separator);
- result.append(right);
- result.appendLiteral(separator);
- result.append(bottom);
- result.appendLiteral(separator);
- result.append(left);
- if (!radiusX.isNull()) {
+ bool showLeftArg = !left.isNull() && left != right;
+ bool showBottomArg = !bottom.isNull() && (bottom != top || showLeftArg);
+ bool showRightArg = !right.isNull() && (right != top || showBottomArg);
+ if (showRightArg) {
result.appendLiteral(separator);
- result.append(radiusX);
- if (!radiusY.isNull()) {
+ result.append(right);
+ }
+ if (showBottomArg) {
+ result.appendLiteral(separator);
+ result.append(bottom);
+ }
+ if (showLeftArg) {
+ result.appendLiteral(separator);
+ result.append(left);
+ }
+
+ if (!topLeftRadiusWidth.isNull() && !topLeftRadiusHeight.isNull()) {
+ Vector<String> horizontalRadii;
+ bool areDefaultCornerRadii = buildInsetRadii(horizontalRadii, topLeftRadiusWidth, topRightRadiusWidth, bottomRightRadiusWidth, bottomLeftRadiusWidth);
+
+ Vector<String> verticalRadii;
+ areDefaultCornerRadii &= buildInsetRadii(verticalRadii, topLeftRadiusHeight, topRightRadiusHeight, bottomRightRadiusHeight, bottomLeftRadiusHeight);
+
+ if (!areDefaultCornerRadii) {
result.appendLiteral(separator);
- result.append(radiusY);
+ result.appendLiteral(cornersSeparator);
+
+ for (size_t i = 0; i < horizontalRadii.size(); ++i) {
+ result.appendLiteral(separator);
+ result.append(horizontalRadii[i]);
+ }
+ if (horizontalRadii != verticalRadii) {
+ result.appendLiteral(separator);
+ result.appendLiteral("/");
+
+ for (size_t i = 0; i < verticalRadii.size(); ++i) {
+ result.appendLiteral(separator);
+ result.append(verticalRadii[i]);
+ }
+ }
}
}
result.append(')');
+
return result.toString();
}
-String CSSBasicShapeInsetRectangle::cssText() const
+static inline void updateCornerRadiusWidthAndHeight(CSSPrimitiveValue* corner, String& width, String& height)
+{
+ if (!corner)
+ return;
+
+ Pair* radius = corner->getPairValue();
+ width = radius->first() ? radius->first()->cssText() : String("0");
+ if (radius->second())
+ height = radius->second()->cssText();
+}
+
+String CSSBasicShapeInset::cssText() const
{
- return buildInsetRectangleString(m_top->cssText(),
- m_right->cssText(),
- m_bottom->cssText(),
- m_left->cssText(),
- m_radiusX.get() ? m_radiusX->cssText() : String(),
- m_radiusY.get() ? m_radiusY->cssText() : String());
+ String topLeftRadiusWidth;
+ String topLeftRadiusHeight;
+ String topRightRadiusWidth;
+ String topRightRadiusHeight;
+ String bottomRightRadiusWidth;
+ String bottomRightRadiusHeight;
+ String bottomLeftRadiusWidth;
+ String bottomLeftRadiusHeight;
+
+ updateCornerRadiusWidthAndHeight(topLeftRadius(), topLeftRadiusWidth, topLeftRadiusHeight);
+ updateCornerRadiusWidthAndHeight(topRightRadius(), topRightRadiusWidth, topRightRadiusHeight);
+ updateCornerRadiusWidthAndHeight(bottomRightRadius(), bottomRightRadiusWidth, bottomRightRadiusHeight);
+ updateCornerRadiusWidthAndHeight(bottomLeftRadius(), bottomLeftRadiusWidth, bottomLeftRadiusHeight);
+
+ return buildInsetString(m_top ? m_top->cssText() : String(),
+ m_right ? m_right->cssText() : String(),
+ m_bottom ? m_bottom->cssText() : String(),
+ m_left ? m_left->cssText() : String(),
+ topLeftRadiusWidth,
+ topLeftRadiusHeight,
+ topRightRadiusWidth,
+ topRightRadiusHeight,
+ bottomRightRadiusWidth,
+ bottomRightRadiusHeight,
+ bottomLeftRadiusWidth,
+ bottomLeftRadiusHeight);
}
-bool CSSBasicShapeInsetRectangle::equals(const CSSBasicShape& shape) const
+bool CSSBasicShapeInset::equals(const CSSBasicShape& shape) const
{
- if (shape.type() != CSSBasicShapeInsetRectangleType)
+ if (shape.type() != CSSBasicShapeInsetType)
return false;
- const CSSBasicShapeInsetRectangle& other = static_cast<const CSSBasicShapeInsetRectangle&>(shape);
+ const CSSBasicShapeInset& other = static_cast<const CSSBasicShapeInset&>(shape);
return compareCSSValuePtr(m_top, other.m_top)
&& compareCSSValuePtr(m_right, other.m_right)
&& compareCSSValuePtr(m_bottom, other.m_bottom)
&& compareCSSValuePtr(m_left, other.m_left)
- && compareCSSValuePtr(m_radiusX, other.m_radiusX)
- && compareCSSValuePtr(m_radiusY, other.m_radiusY);
-}
-
-String CSSBasicShapeInsetRectangle::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- return buildInsetRectangleString(m_top->serializeResolvingVariables(variables),
- m_right->serializeResolvingVariables(variables),
- m_bottom->serializeResolvingVariables(variables),
- m_left->serializeResolvingVariables(variables),
- m_radiusX.get() ? m_radiusX->serializeResolvingVariables(variables) : String(),
- m_radiusY.get() ? m_radiusY->serializeResolvingVariables(variables) : String());
+ && compareCSSValuePtr(m_topLeftRadius, other.m_topLeftRadius)
+ && compareCSSValuePtr(m_topRightRadius, other.m_topRightRadius)
+ && compareCSSValuePtr(m_bottomRightRadius, other.m_bottomRightRadius)
+ && compareCSSValuePtr(m_bottomLeftRadius, other.m_bottomLeftRadius);
}
-bool CSSBasicShapeInsetRectangle::hasVariableReference() const
+void CSSBasicShapeInset::trace(Visitor* visitor)
{
- return m_top->hasVariableReference()
- || m_right->hasVariableReference()
- || m_bottom->hasVariableReference()
- || m_left->hasVariableReference()
- || (m_radiusX.get() && m_radiusX->hasVariableReference())
- || (m_radiusY.get() && m_radiusY->hasVariableReference());
+ visitor->trace(m_top);
+ visitor->trace(m_right);
+ visitor->trace(m_bottom);
+ visitor->trace(m_left);
+ visitor->trace(m_topLeftRadius);
+ visitor->trace(m_topRightRadius);
+ visitor->trace(m_bottomRightRadius);
+ visitor->trace(m_bottomLeftRadius);
+ CSSBasicShape::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.h b/chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.h
index ca8c661fc47..4c510e0ca5c 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSBasicShapes.h
@@ -38,181 +38,107 @@
namespace WebCore {
-class CSSBasicShape : public RefCounted<CSSBasicShape> {
+class CSSBasicShape : public RefCountedWillBeGarbageCollected<CSSBasicShape> {
+ DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(CSSBasicShape);
public:
enum Type {
- CSSBasicShapeRectangleType = 1,
- CSSBasicShapeCircleType = 2,
- CSSBasicShapeEllipseType = 3,
- CSSBasicShapePolygonType = 4,
- CSSBasicShapeInsetRectangleType = 5
+ CSSBasicShapeEllipseType,
+ CSSBasicShapePolygonType,
+ CSSBasicShapeCircleType,
+ CSSBasicShapeInsetType
};
virtual Type type() const = 0;
virtual String cssText() const = 0;
virtual bool equals(const CSSBasicShape&) const = 0;
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const = 0;
- virtual bool hasVariableReference() const = 0;
+ CSSPrimitiveValue* referenceBox() const { return m_referenceBox.get(); }
+ void setReferenceBox(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> referenceBox) { m_referenceBox = referenceBox; }
-public:
- virtual ~CSSBasicShape() { }
+ virtual void trace(Visitor* visitor) { visitor->trace(m_referenceBox); }
protected:
CSSBasicShape() { }
+ RefPtrWillBeMember<CSSPrimitiveValue> m_referenceBox;
};
-class CSSBasicShapeRectangle : public CSSBasicShape {
+class CSSBasicShapeCircle FINAL : public CSSBasicShape {
public:
- static PassRefPtr<CSSBasicShapeRectangle> create() { return adoptRef(new CSSBasicShapeRectangle); }
-
- CSSPrimitiveValue* x() const { return m_x.get(); }
- CSSPrimitiveValue* y() const { return m_y.get(); }
- CSSPrimitiveValue* width() const { return m_width.get(); }
- CSSPrimitiveValue* height() const { return m_height.get(); }
- CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); }
- CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); }
-
- void setX(PassRefPtr<CSSPrimitiveValue> x) { m_x = x; }
- void setY(PassRefPtr<CSSPrimitiveValue> y) { m_y = y; }
- void setWidth(PassRefPtr<CSSPrimitiveValue> width) { m_width = width; }
- void setHeight(PassRefPtr<CSSPrimitiveValue> height) { m_height = height; }
- void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
- void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
-
- virtual Type type() const { return CSSBasicShapeRectangleType; }
- virtual String cssText() const;
- virtual bool equals(const CSSBasicShape&) const;
-
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
- virtual bool hasVariableReference() const;
-
-private:
- CSSBasicShapeRectangle() { }
-
- RefPtr<CSSPrimitiveValue> m_y;
- RefPtr<CSSPrimitiveValue> m_x;
- RefPtr<CSSPrimitiveValue> m_width;
- RefPtr<CSSPrimitiveValue> m_height;
- RefPtr<CSSPrimitiveValue> m_radiusX;
- RefPtr<CSSPrimitiveValue> m_radiusY;
-};
-
-class CSSBasicShapeInsetRectangle : public CSSBasicShape {
-public:
- static PassRefPtr<CSSBasicShapeInsetRectangle> create() { return adoptRef(new CSSBasicShapeInsetRectangle); }
-
- CSSPrimitiveValue* top() const { return m_top.get(); }
- CSSPrimitiveValue* right() const { return m_right.get(); }
- CSSPrimitiveValue* bottom() const { return m_bottom.get(); }
- CSSPrimitiveValue* left() const { return m_left.get(); }
- CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); }
- CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); }
+ static PassRefPtrWillBeRawPtr<CSSBasicShapeCircle> create() { return adoptRefWillBeNoop(new CSSBasicShapeCircle); }
- void setTop(PassRefPtr<CSSPrimitiveValue> top) { m_top = top; }
- void setRight(PassRefPtr<CSSPrimitiveValue> right) { m_right = right; }
- void setBottom(PassRefPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
- void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; }
- void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
- void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
-
- virtual Type type() const { return CSSBasicShapeInsetRectangleType; }
- virtual String cssText() const;
- virtual bool equals(const CSSBasicShape&) const;
-
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
- virtual bool hasVariableReference() const;
-
-private:
- CSSBasicShapeInsetRectangle() { }
-
- RefPtr<CSSPrimitiveValue> m_right;
- RefPtr<CSSPrimitiveValue> m_top;
- RefPtr<CSSPrimitiveValue> m_bottom;
- RefPtr<CSSPrimitiveValue> m_left;
- RefPtr<CSSPrimitiveValue> m_radiusX;
- RefPtr<CSSPrimitiveValue> m_radiusY;
-};
-
-class CSSBasicShapeCircle : public CSSBasicShape {
-public:
- static PassRefPtr<CSSBasicShapeCircle> create() { return adoptRef(new CSSBasicShapeCircle); }
+ virtual Type type() const OVERRIDE { return CSSBasicShapeCircleType; }
+ virtual String cssText() const OVERRIDE;
+ virtual bool equals(const CSSBasicShape&) const OVERRIDE;
CSSPrimitiveValue* centerX() const { return m_centerX.get(); }
CSSPrimitiveValue* centerY() const { return m_centerY.get(); }
CSSPrimitiveValue* radius() const { return m_radius.get(); }
- void setCenterX(PassRefPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
- void setCenterY(PassRefPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
- void setRadius(PassRefPtr<CSSPrimitiveValue> radius) { m_radius = radius; }
-
- virtual Type type() const { return CSSBasicShapeCircleType; }
- virtual String cssText() const;
- virtual bool equals(const CSSBasicShape&) const;
+ void setCenterX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
+ void setCenterY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
+ void setRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_radius = radius; }
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
- virtual bool hasVariableReference() const;
+ virtual void trace(Visitor*);
private:
CSSBasicShapeCircle() { }
- RefPtr<CSSPrimitiveValue> m_centerY;
- RefPtr<CSSPrimitiveValue> m_centerX;
- RefPtr<CSSPrimitiveValue> m_radius;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_centerX;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_centerY;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_radius;
};
-class CSSBasicShapeEllipse : public CSSBasicShape {
+class CSSBasicShapeEllipse FINAL : public CSSBasicShape {
public:
- static PassRefPtr<CSSBasicShapeEllipse> create() { return adoptRef(new CSSBasicShapeEllipse); }
+ static PassRefPtrWillBeRawPtr<CSSBasicShapeEllipse> create() { return adoptRefWillBeNoop(new CSSBasicShapeEllipse); }
+
+ virtual Type type() const OVERRIDE { return CSSBasicShapeEllipseType; }
+ virtual String cssText() const OVERRIDE;
+ virtual bool equals(const CSSBasicShape&) const OVERRIDE;
CSSPrimitiveValue* centerX() const { return m_centerX.get(); }
CSSPrimitiveValue* centerY() const { return m_centerY.get(); }
CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); }
CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); }
- void setCenterX(PassRefPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
- void setCenterY(PassRefPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
- void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
- void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
-
- virtual Type type() const { return CSSBasicShapeEllipseType; }
- virtual String cssText() const;
- virtual bool equals(const CSSBasicShape&) const;
+ void setCenterX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
+ void setCenterY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
+ void setRadiusX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
+ void setRadiusY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
- virtual bool hasVariableReference() const;
+ virtual void trace(Visitor*);
private:
CSSBasicShapeEllipse() { }
- RefPtr<CSSPrimitiveValue> m_centerX;
- RefPtr<CSSPrimitiveValue> m_centerY;
- RefPtr<CSSPrimitiveValue> m_radiusX;
- RefPtr<CSSPrimitiveValue> m_radiusY;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_centerX;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_centerY;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_radiusX;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_radiusY;
};
-class CSSBasicShapePolygon : public CSSBasicShape {
+class CSSBasicShapePolygon FINAL : public CSSBasicShape {
public:
- static PassRefPtr<CSSBasicShapePolygon> create() { return adoptRef(new CSSBasicShapePolygon); }
+ static PassRefPtrWillBeRawPtr<CSSBasicShapePolygon> create() { return adoptRefWillBeNoop(new CSSBasicShapePolygon); }
- void appendPoint(PassRefPtr<CSSPrimitiveValue> x, PassRefPtr<CSSPrimitiveValue> y)
+ void appendPoint(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> x, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> y)
{
m_values.append(x);
m_values.append(y);
}
- PassRefPtr<CSSPrimitiveValue> getXAt(unsigned i) const { return m_values.at(i * 2); }
- PassRefPtr<CSSPrimitiveValue> getYAt(unsigned i) const { return m_values.at(i * 2 + 1); }
- const Vector<RefPtr<CSSPrimitiveValue> >& values() const { return m_values; }
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> getXAt(unsigned i) const { return m_values.at(i * 2); }
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> getYAt(unsigned i) const { return m_values.at(i * 2 + 1); }
+ const WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> >& values() const { return m_values; }
void setWindRule(WindRule w) { m_windRule = w; }
WindRule windRule() const { return m_windRule; }
- virtual Type type() const { return CSSBasicShapePolygonType; }
- virtual String cssText() const;
- virtual bool equals(const CSSBasicShape&) const;
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
- virtual bool hasVariableReference() const;
+ virtual Type type() const OVERRIDE { return CSSBasicShapePolygonType; }
+ virtual String cssText() const OVERRIDE;
+ virtual bool equals(const CSSBasicShape&) const OVERRIDE;
+
+ virtual void trace(Visitor*);
private:
CSSBasicShapePolygon()
@@ -220,10 +146,78 @@ private:
{
}
- Vector<RefPtr<CSSPrimitiveValue> > m_values;
+ WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> > m_values;
WindRule m_windRule;
};
+class CSSBasicShapeInset : public CSSBasicShape {
+public:
+ static PassRefPtrWillBeRawPtr<CSSBasicShapeInset> create() { return adoptRefWillBeNoop(new CSSBasicShapeInset); }
+
+ CSSPrimitiveValue* top() const { return m_top.get(); }
+ CSSPrimitiveValue* right() const { return m_right.get(); }
+ CSSPrimitiveValue* bottom() const { return m_bottom.get(); }
+ CSSPrimitiveValue* left() const { return m_left.get(); }
+
+ CSSPrimitiveValue* topLeftRadius() const { return m_topLeftRadius.get(); }
+ CSSPrimitiveValue* topRightRadius() const { return m_topRightRadius.get(); }
+ CSSPrimitiveValue* bottomRightRadius() const { return m_bottomRightRadius.get(); }
+ CSSPrimitiveValue* bottomLeftRadius() const { return m_bottomLeftRadius.get(); }
+
+ void setTop(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> top) { m_top = top; }
+ void setRight(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> right) { m_right = right; }
+ void setBottom(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
+ void setLeft(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> left) { m_left = left; }
+
+ void updateShapeSize4Values(CSSPrimitiveValue* top, CSSPrimitiveValue* right, CSSPrimitiveValue* bottom, CSSPrimitiveValue* left)
+ {
+ setTop(top);
+ setRight(right);
+ setBottom(bottom);
+ setLeft(left);
+ }
+
+ void updateShapeSize1Value(CSSPrimitiveValue* value1)
+ {
+ updateShapeSize4Values(value1, value1, value1, value1);
+ }
+
+ void updateShapeSize2Values(CSSPrimitiveValue* value1, CSSPrimitiveValue* value2)
+ {
+ updateShapeSize4Values(value1, value2, value1, value2);
+ }
+
+ void updateShapeSize3Values(CSSPrimitiveValue* value1, CSSPrimitiveValue* value2, CSSPrimitiveValue* value3)
+ {
+ updateShapeSize4Values(value1, value2, value3, value2);
+ }
+
+
+ void setTopLeftRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_topLeftRadius = radius; }
+ void setTopRightRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_topRightRadius = radius; }
+ void setBottomRightRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_bottomRightRadius = radius; }
+ void setBottomLeftRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_bottomLeftRadius = radius; }
+
+ virtual Type type() const OVERRIDE { return CSSBasicShapeInsetType; }
+ virtual String cssText() const OVERRIDE;
+ virtual bool equals(const CSSBasicShape&) const OVERRIDE;
+
+ virtual void trace(Visitor*);
+
+private:
+ CSSBasicShapeInset() { }
+
+ RefPtrWillBeMember<CSSPrimitiveValue> m_top;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_right;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_bottom;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_left;
+
+ RefPtrWillBeMember<CSSPrimitiveValue> m_topLeftRadius;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_topRightRadius;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_bottomRightRadius;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_bottomLeftRadius;
+};
+
} // namespace WebCore
#endif // CSSBasicShapes_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSBorderImage.cpp b/chromium/third_party/WebKit/Source/core/css/CSSBorderImage.cpp
index d62711ddef7..fd05d0f5ff8 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSBorderImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSBorderImage.cpp
@@ -22,15 +22,15 @@
namespace WebCore {
-PassRefPtr<CSSValueList> createBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<CSSValue> imageSlice, PassRefPtr<CSSValue> borderSlice,
- PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat)
+PassRefPtrWillBeRawPtr<CSSValueList> createBorderImageValue(PassRefPtrWillBeRawPtr<CSSValue> image, PassRefPtrWillBeRawPtr<CSSValue> imageSlice,
+ PassRefPtrWillBeRawPtr<CSSValue> borderSlice, PassRefPtrWillBeRawPtr<CSSValue> outset, PassRefPtrWillBeRawPtr<CSSValue> repeat)
{
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (image)
list->append(image);
if (borderSlice || outset) {
- RefPtr<CSSValueList> listSlash = CSSValueList::createSlashSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> listSlash = CSSValueList::createSlashSeparated();
if (imageSlice)
listSlash->append(imageSlice);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSBorderImage.h b/chromium/third_party/WebKit/Source/core/css/CSSBorderImage.h
index bdf13fefd19..b9066fa29bf 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSBorderImage.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSBorderImage.h
@@ -26,8 +26,8 @@
namespace WebCore {
-PassRefPtr<CSSValueList> createBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<CSSValue> imageSlice, PassRefPtr<CSSValue> borderSlice,
- PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat);
+PassRefPtrWillBeRawPtr<CSSValueList> createBorderImageValue(PassRefPtrWillBeRawPtr<CSSValue> image, PassRefPtrWillBeRawPtr<CSSValue> imageSlice, PassRefPtrWillBeRawPtr<CSSValue> borderSlice,
+ PassRefPtrWillBeRawPtr<CSSValue> outset, PassRefPtrWillBeRawPtr<CSSValue> repeat);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp
index 7ffac3afb9b..34400a81137 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.cpp
@@ -30,7 +30,7 @@
namespace WebCore {
-CSSBorderImageSliceValue::CSSBorderImageSliceValue(PassRefPtr<CSSPrimitiveValue> slices, bool fill)
+CSSBorderImageSliceValue::CSSBorderImageSliceValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> slices, bool fill)
: CSSValue(BorderImageSliceClass)
, m_slices(slices)
, m_fill(fill)
@@ -53,4 +53,10 @@ bool CSSBorderImageSliceValue::equals(const CSSBorderImageSliceValue& other) con
return m_fill == other.m_fill && compareCSSValuePtr(m_slices, other.m_slices);
}
+void CSSBorderImageSliceValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_slices);
+ CSSValue::traceAfterDispatch(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.h b/chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.h
index 7d297ea9be0..c2b4716d790 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSBorderImageSliceValue.h
@@ -36,9 +36,9 @@ class Rect;
class CSSBorderImageSliceValue : public CSSValue {
public:
- static PassRefPtr<CSSBorderImageSliceValue> create(PassRefPtr<CSSPrimitiveValue> slices, bool fill)
+ static PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> slices, bool fill)
{
- return adoptRef(new CSSBorderImageSliceValue(slices, fill));
+ return adoptRefWillBeNoop(new CSSBorderImageSliceValue(slices, fill));
}
String customCSSText() const;
@@ -47,13 +47,15 @@ public:
bool equals(const CSSBorderImageSliceValue&) const;
+ void traceAfterDispatch(Visitor*);
+
// These four values are used to make "cuts" in the border image. They can be numbers
// or percentages.
- RefPtr<CSSPrimitiveValue> m_slices;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_slices;
bool m_fill;
private:
- CSSBorderImageSliceValue(PassRefPtr<CSSPrimitiveValue> slices, bool fill);
+ CSSBorderImageSliceValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> slices, bool fill);
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSBorderImageSliceValue, isBorderImageSliceValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
index e27cba3a66d..79de5eb33bf 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.cpp
@@ -47,7 +47,7 @@ enum ParseState {
namespace WebCore {
-static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
+static CalculationCategory unitCategory(CSSPrimitiveValue::UnitType type)
{
switch (type) {
case CSSPrimitiveValue::CSS_NUMBER:
@@ -65,15 +65,19 @@ static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
case CSSPrimitiveValue::CSS_PC:
case CSSPrimitiveValue::CSS_REMS:
case CSSPrimitiveValue::CSS_CHS:
+ case CSSPrimitiveValue::CSS_VW:
+ case CSSPrimitiveValue::CSS_VH:
+ case CSSPrimitiveValue::CSS_VMIN:
+ case CSSPrimitiveValue::CSS_VMAX:
return CalcLength;
- case CSSPrimitiveValue::CSS_VARIABLE_NAME:
- return CalcVariable;
+ // FIXME: Support angle, time and frequency units.
+ // http://www.w3.org/TR/css3-values/#calc-notation
default:
return CalcOther;
}
}
-static bool hasDoubleValue(CSSPrimitiveValue::UnitTypes type)
+static bool hasDoubleValue(CSSPrimitiveValue::UnitType type)
{
switch (type) {
case CSSPrimitiveValue::CSS_NUMBER:
@@ -126,7 +130,6 @@ static bool hasDoubleValue(CSSPrimitiveValue::UnitTypes type)
case CSSPrimitiveValue::CSS_CALC:
case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH:
- case CSSPrimitiveValue::CSS_VARIABLE_NAME:
case CSSPrimitiveValue::CSS_PROPERTY_ID:
case CSSPrimitiveValue::CSS_VALUE_ID:
return false;
@@ -158,16 +161,6 @@ bool CSSCalcValue::equals(const CSSCalcValue& other) const
return compareCSSValuePtr(m_expression, other.m_expression);
}
-String CSSCalcValue::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- return buildCSSText(m_expression->serializeResolvingVariables(variables));
-}
-
-bool CSSCalcValue::hasVariableReference() const
-{
- return m_expression->hasVariableReference();
-}
-
double CSSCalcValue::clampToPermittedRange(double value) const
{
return m_nonNegative && value < 0 ? 0 : value;
@@ -183,71 +176,50 @@ double CSSCalcValue::computeLengthPx(const CSSToLengthConversionData& conversion
return clampToPermittedRange(m_expression->computeLengthPx(conversionData));
}
-CSSCalcExpressionNode::~CSSCalcExpressionNode()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSCalcExpressionNode)
-class CSSCalcPrimitiveValue : public CSSCalcExpressionNode {
- WTF_MAKE_FAST_ALLOCATED;
+class CSSCalcPrimitiveValue FINAL : public CSSCalcExpressionNode {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<CSSCalcPrimitiveValue> create(PassRefPtr<CSSPrimitiveValue> value, bool isInteger)
+ static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger)
{
- return adoptRef(new CSSCalcPrimitiveValue(value, isInteger));
+ return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(value, isInteger));
}
- static PassRefPtr<CSSCalcPrimitiveValue> create(double value, CSSPrimitiveValue::UnitTypes type, bool isInteger)
+ static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(double value, CSSPrimitiveValue::UnitType type, bool isInteger)
{
if (std::isnan(value) || std::isinf(value))
- return 0;
- return adoptRef(new CSSCalcPrimitiveValue(CSSPrimitiveValue::create(value, type).get(), isInteger));
+ return nullptr;
+ return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(CSSPrimitiveValue::create(value, type).get(), isInteger));
}
- virtual bool isZero() const
+ virtual bool isZero() const OVERRIDE
{
return !m_value->getDoubleValue();
}
- virtual String customCSSText() const
+ virtual String customCSSText() const OVERRIDE
{
return m_value->cssText();
}
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
- {
- return m_value->customSerializeResolvingVariables(variables);
- }
-
- virtual bool hasVariableReference() const
- {
- return m_value->isVariableName();
- }
-
- virtual PassOwnPtr<CalcExpressionNode> toCalcValue(const CSSToLengthConversionData& conversionData) const
+ virtual void accumulatePixelsAndPercent(const CSSToLengthConversionData& conversionData, PixelsAndPercent& value, float multiplier) const OVERRIDE
{
switch (m_category) {
- case CalcNumber:
- return adoptPtr(new CalcExpressionNumber(m_value->getFloatValue()));
case CalcLength:
- return adoptPtr(new CalcExpressionLength(Length(m_value->computeLength<float>(conversionData), WebCore::Fixed)));
+ value.pixels += m_value->computeLength<float>(conversionData) * multiplier;
+ break;
case CalcPercent:
- case CalcPercentLength: {
- CSSPrimitiveValue* primitiveValue = m_value.get();
- return adoptPtr(new CalcExpressionLength(primitiveValue
- ? primitiveValue->convertToLength<FixedConversion | PercentConversion>(conversionData)
- : Length(Undefined)));
- }
- // Only types that could be part of a Length expression can be converted
- // to a CalcExpressionNode. CalcPercentNumber makes no sense as a Length.
- case CalcPercentNumber:
- case CalcVariable:
- case CalcOther:
+ ASSERT(m_value->isPercentage());
+ value.percent += m_value->getDoubleValue() * multiplier;
+ break;
+ default:
ASSERT_NOT_REACHED();
}
- return nullptr;
}
- virtual double doubleValue() const
+ virtual double doubleValue() const OVERRIDE
{
if (hasDoubleValue(primitiveType()))
return m_value->getDoubleValue();
@@ -255,7 +227,7 @@ public:
return 0;
}
- virtual double computeLengthPx(const CSSToLengthConversionData& conversionData) const
+ virtual double computeLengthPx(const CSSToLengthConversionData& conversionData) const OVERRIDE
{
switch (m_category) {
case CalcLength:
@@ -265,7 +237,6 @@ public:
return m_value->getDoubleValue();
case CalcPercentLength:
case CalcPercentNumber:
- case CalcVariable:
case CalcOther:
ASSERT_NOT_REACHED();
break;
@@ -274,7 +245,13 @@ public:
return 0;
}
- virtual bool equals(const CSSCalcExpressionNode& other) const
+ virtual void accumulateLengthArray(CSSLengthArray& lengthArray, double multiplier) const
+ {
+ ASSERT(category() != CalcNumber);
+ m_value->accumulateLengthArray(lengthArray, multiplier);
+ }
+
+ virtual bool equals(const CSSCalcExpressionNode& other) const OVERRIDE
{
if (type() != other.type())
return false;
@@ -282,20 +259,27 @@ public:
return compareCSSValuePtr(m_value, static_cast<const CSSCalcPrimitiveValue&>(other).m_value);
}
- virtual Type type() const { return CssCalcPrimitiveValue; }
- virtual CSSPrimitiveValue::UnitTypes primitiveType() const
+ virtual Type type() const OVERRIDE { return CssCalcPrimitiveValue; }
+ virtual CSSPrimitiveValue::UnitType primitiveType() const OVERRIDE
{
- return CSSPrimitiveValue::UnitTypes(m_value->primitiveType());
+ return m_value->primitiveType();
+ }
+
+
+ virtual void trace(Visitor* visitor)
+ {
+ visitor->trace(m_value);
+ CSSCalcExpressionNode::trace(visitor);
}
private:
- explicit CSSCalcPrimitiveValue(PassRefPtr<CSSPrimitiveValue> value, bool isInteger)
- : CSSCalcExpressionNode(unitCategory((CSSPrimitiveValue::UnitTypes)value->primitiveType()), isInteger)
+ CSSCalcPrimitiveValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger)
+ : CSSCalcExpressionNode(unitCategory(value->primitiveType()), isInteger)
, m_value(value)
{
}
- RefPtr<CSSPrimitiveValue> m_value;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_value;
};
static const CalculationCategory addSubtractResult[CalcOther][CalcOther] = {
@@ -315,9 +299,6 @@ static CalculationCategory determineCategory(const CSSCalcExpressionNode& leftSi
if (leftCategory == CalcOther || rightCategory == CalcOther)
return CalcOther;
- if (leftCategory == CalcVariable || rightCategory == CalcVariable)
- return CalcVariable;
-
switch (op) {
case CalcAdd:
case CalcSubtract:
@@ -344,21 +325,20 @@ static bool isIntegerResult(const CSSCalcExpressionNode* leftSide, const CSSCalc
return op != CalcDivide && leftSide->isInteger() && rightSide->isInteger();
}
-class CSSCalcBinaryOperation : public CSSCalcExpressionNode {
-
+class CSSCalcBinaryOperation FINAL : public CSSCalcExpressionNode {
public:
- static PassRefPtr<CSSCalcExpressionNode> create(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
+ static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> create(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
{
ASSERT(leftSide->category() != CalcOther && rightSide->category() != CalcOther);
CalculationCategory newCategory = determineCategory(*leftSide, *rightSide, op);
if (newCategory == CalcOther)
- return 0;
+ return nullptr;
- return adoptRef(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
+ return adoptRefWillBeNoop(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
}
- static PassRefPtr<CSSCalcExpressionNode> createSimplified(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
+ static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createSimplified(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
{
CalculationCategory leftCategory = leftSide->category();
CalculationCategory rightCategory = rightSide->category();
@@ -368,21 +348,21 @@ public:
// Simplify numbers.
if (leftCategory == CalcNumber && rightCategory == CalcNumber) {
- CSSPrimitiveValue::UnitTypes evaluationType = isInteger ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER;
+ CSSPrimitiveValue::UnitType evaluationType = isInteger ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER;
return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), evaluationType, isInteger);
}
// Simplify addition and subtraction between same types.
if (op == CalcAdd || op == CalcSubtract) {
if (leftCategory == rightSide->category()) {
- CSSPrimitiveValue::UnitTypes leftType = leftSide->primitiveType();
+ CSSPrimitiveValue::UnitType leftType = leftSide->primitiveType();
if (hasDoubleValue(leftType)) {
- CSSPrimitiveValue::UnitTypes rightType = rightSide->primitiveType();
+ CSSPrimitiveValue::UnitType rightType = rightSide->primitiveType();
if (leftType == rightType)
return CSSCalcPrimitiveValue::create(evaluateOperator(leftSide->doubleValue(), rightSide->doubleValue(), op), leftType, isInteger);
CSSPrimitiveValue::UnitCategory leftUnitCategory = CSSPrimitiveValue::unitCategory(leftType);
if (leftUnitCategory != CSSPrimitiveValue::UOther && leftUnitCategory == CSSPrimitiveValue::unitCategory(rightType)) {
- CSSPrimitiveValue::UnitTypes canonicalType = CSSPrimitiveValue::canonicalUnitTypeForCategory(leftUnitCategory);
+ CSSPrimitiveValue::UnitType canonicalType = CSSPrimitiveValue::canonicalUnitTypeForCategory(leftUnitCategory);
if (canonicalType != CSSPrimitiveValue::CSS_UNKNOWN) {
double leftValue = leftSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(leftType);
double rightValue = rightSide->doubleValue() * CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(rightType);
@@ -398,16 +378,16 @@ public:
if (!numberSide)
return create(leftSide, rightSide, op);
if (numberSide == leftSide && op == CalcDivide)
- return 0;
+ return nullptr;
CSSCalcExpressionNode* otherSide = leftSide == numberSide ? rightSide.get() : leftSide.get();
double number = numberSide->doubleValue();
if (std::isnan(number) || std::isinf(number))
- return 0;
+ return nullptr;
if (op == CalcDivide && !number)
- return 0;
+ return nullptr;
- CSSPrimitiveValue::UnitTypes otherType = otherSide->primitiveType();
+ CSSPrimitiveValue::UnitType otherType = otherSide->primitiveType();
if (hasDoubleValue(otherType))
return CSSCalcPrimitiveValue::create(evaluateOperator(otherSide->doubleValue(), number, op), otherType, isInteger);
}
@@ -415,34 +395,77 @@ public:
return create(leftSide, rightSide, op);
}
- virtual bool isZero() const
+ virtual bool isZero() const OVERRIDE
{
return !doubleValue();
}
- virtual PassOwnPtr<CalcExpressionNode> toCalcValue(const CSSToLengthConversionData& conversionData) const
+ virtual void accumulatePixelsAndPercent(const CSSToLengthConversionData& conversionData, PixelsAndPercent& value, float multiplier) const OVERRIDE
{
- OwnPtr<CalcExpressionNode> left(m_leftSide->toCalcValue(conversionData));
- if (!left)
- return nullptr;
- OwnPtr<CalcExpressionNode> right(m_rightSide->toCalcValue(conversionData));
- if (!right)
- return nullptr;
- return adoptPtr(new CalcExpressionBinaryOperation(left.release(), right.release(), m_operator));
+ switch (m_operator) {
+ case CalcAdd:
+ m_leftSide->accumulatePixelsAndPercent(conversionData, value, multiplier);
+ m_rightSide->accumulatePixelsAndPercent(conversionData, value, multiplier);
+ break;
+ case CalcSubtract:
+ m_leftSide->accumulatePixelsAndPercent(conversionData, value, multiplier);
+ m_rightSide->accumulatePixelsAndPercent(conversionData, value, -multiplier);
+ break;
+ case CalcMultiply:
+ ASSERT((m_leftSide->category() == CalcNumber) != (m_rightSide->category() == CalcNumber));
+ if (m_leftSide->category() == CalcNumber)
+ m_rightSide->accumulatePixelsAndPercent(conversionData, value, multiplier * m_leftSide->doubleValue());
+ else
+ m_leftSide->accumulatePixelsAndPercent(conversionData, value, multiplier * m_rightSide->doubleValue());
+ break;
+ case CalcDivide:
+ ASSERT(m_rightSide->category() == CalcNumber);
+ m_leftSide->accumulatePixelsAndPercent(conversionData, value, multiplier / m_rightSide->doubleValue());
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
}
- virtual double doubleValue() const
+ virtual double doubleValue() const OVERRIDE
{
return evaluate(m_leftSide->doubleValue(), m_rightSide->doubleValue());
}
- virtual double computeLengthPx(const CSSToLengthConversionData& conversionData) const
+ virtual double computeLengthPx(const CSSToLengthConversionData& conversionData) const OVERRIDE
{
const double leftValue = m_leftSide->computeLengthPx(conversionData);
const double rightValue = m_rightSide->computeLengthPx(conversionData);
return evaluate(leftValue, rightValue);
}
+ virtual void accumulateLengthArray(CSSLengthArray& lengthArray, double multiplier) const
+ {
+ switch (m_operator) {
+ case CalcAdd:
+ m_leftSide->accumulateLengthArray(lengthArray, multiplier);
+ m_rightSide->accumulateLengthArray(lengthArray, multiplier);
+ break;
+ case CalcSubtract:
+ m_leftSide->accumulateLengthArray(lengthArray, multiplier);
+ m_rightSide->accumulateLengthArray(lengthArray, -multiplier);
+ break;
+ case CalcMultiply:
+ ASSERT((m_leftSide->category() == CalcNumber) != (m_rightSide->category() == CalcNumber));
+ if (m_leftSide->category() == CalcNumber)
+ m_rightSide->accumulateLengthArray(lengthArray, multiplier * m_leftSide->doubleValue());
+ else
+ m_leftSide->accumulateLengthArray(lengthArray, multiplier * m_rightSide->doubleValue());
+ break;
+ case CalcDivide:
+ ASSERT(m_rightSide->category() == CalcNumber);
+ m_leftSide->accumulateLengthArray(lengthArray, multiplier / m_rightSide->doubleValue());
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
static String buildCSSText(const String& leftExpression, const String& rightExpression, CalcOperator op)
{
StringBuilder result;
@@ -457,22 +480,12 @@ public:
return result.toString();
}
- virtual String customCSSText() const
+ virtual String customCSSText() const OVERRIDE
{
return buildCSSText(m_leftSide->customCSSText(), m_rightSide->customCSSText(), m_operator);
}
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
- {
- return buildCSSText(m_leftSide->serializeResolvingVariables(variables), m_rightSide->serializeResolvingVariables(variables), m_operator);
- }
-
- virtual bool hasVariableReference() const
- {
- return m_leftSide->hasVariableReference() || m_rightSide->hasVariableReference();
- }
-
- virtual bool equals(const CSSCalcExpressionNode& exp) const
+ virtual bool equals(const CSSCalcExpressionNode& exp) const OVERRIDE
{
if (type() != exp.type())
return false;
@@ -483,9 +496,9 @@ public:
&& m_operator == other.m_operator;
}
- virtual Type type() const { return CssCalcBinaryOperation; }
+ virtual Type type() const OVERRIDE { return CssCalcBinaryOperation; }
- virtual CSSPrimitiveValue::UnitTypes primitiveType() const
+ virtual CSSPrimitiveValue::UnitType primitiveType() const OVERRIDE
{
switch (m_category) {
case CalcNumber:
@@ -499,13 +512,11 @@ public:
return m_rightSide->primitiveType();
if (m_rightSide->category() == CalcNumber)
return m_leftSide->primitiveType();
- CSSPrimitiveValue::UnitTypes leftType = m_leftSide->primitiveType();
+ CSSPrimitiveValue::UnitType leftType = m_leftSide->primitiveType();
if (leftType == m_rightSide->primitiveType())
return leftType;
return CSSPrimitiveValue::CSS_UNKNOWN;
}
- case CalcVariable:
- return CSSPrimitiveValue::CSS_VARIABLE_NAME;
case CalcPercentLength:
case CalcPercentNumber:
case CalcOther:
@@ -515,9 +526,15 @@ public:
return CSSPrimitiveValue::CSS_UNKNOWN;
}
+ virtual void trace(Visitor* visitor)
+ {
+ visitor->trace(m_leftSide);
+ visitor->trace(m_rightSide);
+ CSSCalcExpressionNode::trace(visitor);
+ }
private:
- CSSCalcBinaryOperation(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category)
+ CSSCalcBinaryOperation(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op, CalculationCategory category)
: CSSCalcExpressionNode(category, isIntegerResult(leftSide.get(), rightSide.get(), op))
, m_leftSide(leftSide)
, m_rightSide(rightSide)
@@ -556,8 +573,8 @@ private:
return 0;
}
- const RefPtr<CSSCalcExpressionNode> m_leftSide;
- const RefPtr<CSSCalcExpressionNode> m_rightSide;
+ const RefPtrWillBeMember<CSSCalcExpressionNode> m_leftSide;
+ const RefPtrWillBeMember<CSSCalcExpressionNode> m_rightSide;
const CalcOperator m_operator;
};
@@ -572,21 +589,24 @@ static ParseState checkDepthAndIndex(int* depth, unsigned index, CSSParserValueL
}
class CSSCalcExpressionNodeParser {
+ STACK_ALLOCATED();
public:
- PassRefPtr<CSSCalcExpressionNode> parseCalc(CSSParserValueList* tokens)
+ PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> parseCalc(CSSParserValueList* tokens)
{
unsigned index = 0;
Value result;
bool ok = parseValueExpression(tokens, 0, &index, &result);
ASSERT_WITH_SECURITY_IMPLICATION(index <= tokens->size());
if (!ok || index != tokens->size())
- return 0;
+ return nullptr;
return result.value;
}
private:
struct Value {
- RefPtr<CSSCalcExpressionNode> value;
+ STACK_ALLOCATED();
+ public:
+ RefPtrWillBeMember<CSSCalcExpressionNode> value;
};
char operatorValue(CSSParserValueList* tokens, unsigned index)
@@ -603,14 +623,18 @@ private:
bool parseValue(CSSParserValueList* tokens, unsigned* index, Value* result)
{
CSSParserValue* parserValue = tokens->valueAt(*index);
- if (parserValue->unit == CSSParserValue::Operator || parserValue->unit == CSSParserValue::Function)
+ if (parserValue->unit == CSSParserValue::Operator)
return false;
- RefPtr<CSSValue> value = parserValue->createCSSValue();
+ RefPtrWillBeRawPtr<CSSValue> value = parserValue->createCSSValue();
if (!value || !value->isPrimitiveValue())
return false;
- result->value = CSSCalcPrimitiveValue::create(toCSSPrimitiveValue(value.get()), parserValue->isInt);
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
+ if (unitCategory(primitiveValue->primitiveType()) == CalcOther)
+ return false;
+
+ result->value = CSSCalcPrimitiveValue::create(primitiveValue, parserValue->isInt);
++*index;
return true;
@@ -695,96 +719,45 @@ private:
}
};
-PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(PassRefPtr<CSSPrimitiveValue> value, bool isInteger)
+PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> value, bool isInteger)
{
return CSSCalcPrimitiveValue::create(value, isInteger);
}
-PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(PassRefPtr<CSSCalcExpressionNode> leftSide, PassRefPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
+PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> leftSide, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> rightSide, CalcOperator op)
{
return CSSCalcBinaryOperation::create(leftSide, rightSide, op);
}
-PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const CalcExpressionNode* node, float zoom)
-{
- switch (node->type()) {
- case CalcExpressionNodeNumber: {
- float value = toCalcExpressionNumber(node)->value();
- return createExpressionNode(CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER), value == trunc(value));
- }
- case CalcExpressionNodeLength:
- return createExpressionNode(toCalcExpressionLength(node)->length(), zoom);
- case CalcExpressionNodeBinaryOperation: {
- const CalcExpressionBinaryOperation* binaryNode = toCalcExpressionBinaryOperation(node);
- return createExpressionNode(createExpressionNode(binaryNode->leftSide(), zoom), createExpressionNode(binaryNode->rightSide(), zoom), binaryNode->getOperator());
- }
- case CalcExpressionNodeBlendLength: {
- // FIXME(crbug.com/269320): Create a CSSCalcExpressionNode equivalent of CalcExpressionBlendLength.
- const CalcExpressionBlendLength* blendNode = toCalcExpressionBlendLength(node);
- const double progress = blendNode->progress();
- const bool isInteger = !progress || (progress == 1);
- return createExpressionNode(
- createExpressionNode(
- createExpressionNode(blendNode->from(), zoom),
- createExpressionNode(CSSPrimitiveValue::create(1 - progress, CSSPrimitiveValue::CSS_NUMBER), isInteger),
- CalcMultiply),
- createExpressionNode(
- createExpressionNode(blendNode->to(), zoom),
- createExpressionNode(CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER), isInteger),
- CalcMultiply),
- CalcAdd);
- }
- case CalcExpressionNodeUndefined:
- ASSERT_NOT_REACHED();
- return 0;
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-PassRefPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const Length& length, float zoom)
+PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(double pixels, double percent)
{
- switch (length.type()) {
- case Percent:
- case ViewportPercentageWidth:
- case ViewportPercentageHeight:
- case ViewportPercentageMin:
- case ViewportPercentageMax:
- case Fixed:
- return createExpressionNode(CSSPrimitiveValue::create(length, zoom), length.value() == trunc(length.value()));
- case Calculated:
- return createExpressionNode(length.calculationValue()->expression(), zoom);
- case Auto:
- case Intrinsic:
- case MinIntrinsic:
- case MinContent:
- case MaxContent:
- case FillAvailable:
- case FitContent:
- case ExtendToZoom:
- case Undefined:
- ASSERT_NOT_REACHED();
- return 0;
- }
- ASSERT_NOT_REACHED();
- return 0;
+ return createExpressionNode(
+ createExpressionNode(CSSPrimitiveValue::create(pixels, CSSPrimitiveValue::CSS_PX), pixels == trunc(pixels)),
+ createExpressionNode(CSSPrimitiveValue::create(percent, CSSPrimitiveValue::CSS_PERCENTAGE), percent == trunc(percent)),
+ CalcAdd);
}
-PassRefPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList* parserValueList, ValueRange range)
+PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList* parserValueList, ValueRange range)
{
CSSCalcExpressionNodeParser parser;
- RefPtr<CSSCalcExpressionNode> expression;
+ RefPtrWillBeRawPtr<CSSCalcExpressionNode> expression = nullptr;
if (equalIgnoringCase(name, "calc(") || equalIgnoringCase(name, "-webkit-calc("))
expression = parser.parseCalc(parserValueList);
// FIXME calc (http://webkit.org/b/16662) Add parsing for min and max here
- return expression ? adoptRef(new CSSCalcValue(expression, range)) : 0;
+ return expression ? adoptRefWillBeNoop(new CSSCalcValue(expression, range)) : nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> expression, ValueRange range)
+{
+ return adoptRefWillBeNoop(new CSSCalcValue(expression, range));
}
-PassRefPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtr<CSSCalcExpressionNode> expression, ValueRange range)
+void CSSCalcValue::traceAfterDispatch(Visitor* visitor)
{
- return adoptRef(new CSSCalcValue(expression, range));
+ visitor->trace(m_expression);
+ CSSValue::traceAfterDispatch(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.h b/chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.h
index 6d58d608931..a7678850ffb 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCalculationValue.h
@@ -47,43 +47,51 @@ class CalculationValue;
class CalcExpressionNode;
class Length;
+enum CalcOperator {
+ CalcAdd = '+',
+ CalcSubtract = '-',
+ CalcMultiply = '*',
+ CalcDivide = '/'
+};
+
enum CalculationCategory {
CalcNumber = 0,
CalcLength,
CalcPercent,
CalcPercentNumber,
CalcPercentLength,
- CalcVariable,
CalcOther
};
-class CSSCalcExpressionNode : public RefCounted<CSSCalcExpressionNode> {
+class CSSCalcExpressionNode : public RefCountedWillBeGarbageCollected<CSSCalcExpressionNode> {
+ DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(CSSCalcExpressionNode);
public:
enum Type {
CssCalcPrimitiveValue = 1,
CssCalcBinaryOperation
};
- virtual ~CSSCalcExpressionNode() = 0;
virtual bool isZero() const = 0;
- virtual PassOwnPtr<CalcExpressionNode> toCalcValue(const CSSToLengthConversionData&) const = 0;
virtual double doubleValue() const = 0;
virtual double computeLengthPx(const CSSToLengthConversionData&) const = 0;
+ virtual void accumulateLengthArray(CSSLengthArray&, double multiplier) const = 0;
+ virtual void accumulatePixelsAndPercent(const CSSToLengthConversionData&, PixelsAndPercent&, float multiplier = 1) const = 0;
virtual String customCSSText() const = 0;
- virtual String serializeResolvingVariables(const HashMap<AtomicString, String>&) const = 0;
- virtual bool hasVariableReference() const = 0;
virtual bool equals(const CSSCalcExpressionNode& other) const { return m_category == other.m_category && m_isInteger == other.m_isInteger; }
virtual Type type() const = 0;
CalculationCategory category() const { return m_category; }
- virtual CSSPrimitiveValue::UnitTypes primitiveType() const = 0;
+ virtual CSSPrimitiveValue::UnitType primitiveType() const = 0;
bool isInteger() const { return m_isInteger; }
+ virtual void trace(Visitor*) { }
+
protected:
CSSCalcExpressionNode(CalculationCategory category, bool isInteger)
: m_category(category)
, m_isInteger(isInteger)
{
+ ASSERT(category != CalcOther);
}
CalculationCategory m_category;
@@ -92,18 +100,18 @@ protected:
class CSSCalcValue : public CSSValue {
public:
- static PassRefPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*, ValueRange);
- static PassRefPtr<CSSCalcValue> create(PassRefPtr<CSSCalcExpressionNode>, ValueRange = ValueRangeAll);
- static PassRefPtr<CSSCalcValue> create(const CalculationValue* value, float zoom) { return adoptRef(new CSSCalcValue(value, zoom)); }
+ static PassRefPtrWillBeRawPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*, ValueRange);
+ static PassRefPtrWillBeRawPtr<CSSCalcValue> create(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode>, ValueRange = ValueRangeAll);
- static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtr<CSSPrimitiveValue>, bool isInteger = false);
- static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtr<CSSCalcExpressionNode>, PassRefPtr<CSSCalcExpressionNode>, CalcOperator);
- static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const CalcExpressionNode*, float zoom);
- static PassRefPtr<CSSCalcExpressionNode> createExpressionNode(const Length&, float zoom);
+ static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtrWillBeRawPtr<CSSPrimitiveValue>, bool isInteger = false);
+ static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode>, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode>, CalcOperator);
+ static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createExpressionNode(double pixels, double percent);
PassRefPtr<CalculationValue> toCalcValue(const CSSToLengthConversionData& conversionData) const
{
- return CalculationValue::create(m_expression->toCalcValue(conversionData), m_nonNegative ? ValueRangeNonNegative : ValueRangeAll);
+ PixelsAndPercent value(0, 0);
+ m_expression->accumulatePixelsAndPercent(conversionData, value);
+ return CalculationValue::create(value, m_nonNegative ? ValueRangeNonNegative : ValueRangeAll);
}
CalculationCategory category() const { return m_expression->category(); }
bool isInt() const { return m_expression->isInteger(); }
@@ -111,30 +119,25 @@ public:
bool isNegative() const { return m_expression->doubleValue() < 0; }
ValueRange permittedValueRange() { return m_nonNegative ? ValueRangeNonNegative : ValueRangeAll; }
double computeLengthPx(const CSSToLengthConversionData&) const;
+ void accumulateLengthArray(CSSLengthArray& lengthArray, double multiplier) const { m_expression->accumulateLengthArray(lengthArray, multiplier); }
CSSCalcExpressionNode* expressionNode() const { return m_expression.get(); }
String customCSSText() const;
bool equals(const CSSCalcValue&) const;
- String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const;
- bool hasVariableReference() const;
+
+ void traceAfterDispatch(Visitor*);
private:
- CSSCalcValue(PassRefPtr<CSSCalcExpressionNode> expression, ValueRange range)
+ CSSCalcValue(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> expression, ValueRange range)
: CSSValue(CalculationClass)
, m_expression(expression)
, m_nonNegative(range == ValueRangeNonNegative)
{
}
- CSSCalcValue(const CalculationValue* value, float zoom)
- : CSSValue(CalculationClass)
- , m_expression(createExpressionNode(value->expression(), zoom))
- , m_nonNegative(value->isNonNegative())
- {
- }
double clampToPermittedRange(double) const;
- const RefPtr<CSSCalcExpressionNode> m_expression;
+ const RefPtrWillBeMember<CSSCalcExpressionNode> m_expression;
const bool m_nonNegative;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp b/chromium/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
index 57875523784..76179e5c653 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCalculationValueTest.cpp
@@ -33,116 +33,166 @@
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSToLengthConversionData.h"
+#include "core/css/StylePropertySet.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/StyleInheritedData.h"
#include <gtest/gtest.h>
+
+namespace WebCore {
+
+void PrintTo(const CSSLengthArray& lengthArray, ::std::ostream* os)
+{
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i)
+ *os << lengthArray.at(i) << ' ';
+}
+
+}
+
using namespace WebCore;
namespace {
-void testExpression(PassRefPtr<CSSCalcExpressionNode> expression, const RenderStyle* style)
+void testAccumulatePixelsAndPercent(const CSSToLengthConversionData& conversionData, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> expression, float expectedPixels, float expectedPercent)
{
- EXPECT_TRUE(
- expression->equals(
- *CSSCalcValue::createExpressionNode(
- expression->toCalcValue(CSSToLengthConversionData(style, style)).get(),
- style->effectiveZoom()).get()));
+ PixelsAndPercent value(0, 0);
+ expression->accumulatePixelsAndPercent(conversionData, value);
+ EXPECT_EQ(expectedPixels, value.pixels);
+ EXPECT_EQ(expectedPercent, value.percent);
}
-TEST(CSSCalculationValue, CreateExpressionNodeFromLength)
+void initLengthArray(CSSLengthArray& lengthArray)
{
- RefPtr<RenderStyle> style = RenderStyle::create();
- RefPtr<CSSCalcExpressionNode> expected;
- RefPtr<CSSCalcExpressionNode> actual;
+ lengthArray.resize(CSSPrimitiveValue::LengthUnitTypeCount);
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i)
+ lengthArray.at(i) = 0;
+}
- expected = CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX), true);
- actual = CSSCalcValue::createExpressionNode(Length(10, WebCore::Fixed), style->effectiveZoom());
- EXPECT_TRUE(actual->equals(*expected.get()));
+CSSLengthArray& setLengthArray(CSSLengthArray& lengthArray, String text)
+{
+ initLengthArray(lengthArray);
+ RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
+ propertySet->setProperty(CSSPropertyLeft, text);
+ toCSSPrimitiveValue(propertySet->getPropertyCSSValue(CSSPropertyLeft).get())->accumulateLengthArray(lengthArray);
+ return lengthArray;
+}
- expected = CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX), true),
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(20, CSSPrimitiveValue::CSS_PX), true),
- CalcAdd);
- actual = CSSCalcValue::createExpressionNode(
- Length(CalculationValue::create(
- adoptPtr(new CalcExpressionBinaryOperation(
- adoptPtr(new CalcExpressionLength(Length(10, WebCore::Fixed))),
- adoptPtr(new CalcExpressionLength(Length(20, WebCore::Fixed))),
- CalcAdd)),
- ValueRangeAll)),
- style->effectiveZoom());
- EXPECT_TRUE(actual->equals(*expected.get()));
-
- expected = CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(30, CSSPrimitiveValue::CSS_PX), true),
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(40, CSSPrimitiveValue::CSS_NUMBER), true),
- CalcMultiply);
- actual = CSSCalcValue::createExpressionNode(
- Length(CalculationValue::create(
- adoptPtr(new CalcExpressionBinaryOperation(
- adoptPtr(new CalcExpressionLength(Length(30, WebCore::Fixed))),
- adoptPtr(new CalcExpressionNumber(40)),
- CalcMultiply)),
- ValueRangeAll)),
- style->effectiveZoom());
- EXPECT_TRUE(actual->equals(*expected.get()));
-
- expected = CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(50, CSSPrimitiveValue::CSS_PX), true),
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(0.25, CSSPrimitiveValue::CSS_NUMBER), false),
- CalcMultiply),
- CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(60, CSSPrimitiveValue::CSS_PX), true),
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(0.75, CSSPrimitiveValue::CSS_NUMBER), false),
- CalcMultiply),
- CalcAdd);
- actual = CSSCalcValue::createExpressionNode(
- Length(CalculationValue::create(
- adoptPtr(new CalcExpressionBlendLength(Length(50, WebCore::Fixed), Length(60, WebCore::Fixed), 0.75)),
- ValueRangeAll)),
- style->effectiveZoom());
- EXPECT_TRUE(actual->equals(*expected.get()));
+bool lengthArraysEqual(CSSLengthArray& a, CSSLengthArray& b)
+{
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i) {
+ if (a.at(i) != b.at(i))
+ return false;
+ }
+ return true;
}
-TEST(CSSCalculationValue, CreateExpressionNodeFromLengthFromExpressionNode)
+TEST(CSSCalculationValue, AccumulatePixelsAndPercent)
{
- RefPtr<CSSCalcExpressionNode> expression;
RefPtr<RenderStyle> style = RenderStyle::createDefaultStyle();
style->setEffectiveZoom(5);
+ CSSToLengthConversionData conversionData(style.get(), style.get(), 0);
- testExpression(
+ testAccumulatePixelsAndPercent(conversionData,
CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX), true),
- style.get());
+ 50, 0);
- testExpression(
+ testAccumulatePixelsAndPercent(conversionData,
CSSCalcValue::createExpressionNode(
CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_PX), true),
CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(20, CSSPrimitiveValue::CSS_PX), true),
CalcAdd),
- style.get());
+ 150, 0);
- testExpression(
+ testAccumulatePixelsAndPercent(conversionData,
CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(30, CSSPrimitiveValue::CSS_PX), true),
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(40, CSSPrimitiveValue::CSS_NUMBER), true),
+ CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_IN), true),
+ CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(2, CSSPrimitiveValue::CSS_NUMBER), true),
CalcMultiply),
- style.get());
+ 960, 0);
- testExpression(
+ testAccumulatePixelsAndPercent(conversionData,
CSSCalcValue::createExpressionNode(
CSSCalcValue::createExpressionNode(
CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(50, CSSPrimitiveValue::CSS_PX), true),
CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(0.25, CSSPrimitiveValue::CSS_NUMBER), false),
CalcMultiply),
CSSCalcValue::createExpressionNode(
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(60, CSSPrimitiveValue::CSS_PX), true),
- CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(0.75, CSSPrimitiveValue::CSS_NUMBER), false),
- CalcMultiply),
- CalcAdd),
- style.get());
+ CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(20, CSSPrimitiveValue::CSS_PX), true),
+ CSSCalcValue::createExpressionNode(CSSPrimitiveValue::create(40, CSSPrimitiveValue::CSS_PERCENTAGE), false),
+ CalcSubtract),
+ CalcSubtract),
+ -37.5, 40);
+}
+
+TEST(CSSCalculationValue, RefCount)
+{
+ RefPtr<CalculationValue> calc = CalculationValue::create(PixelsAndPercent(1, 2), ValueRangeAll);
+ Length lengthA(calc);
+ EXPECT_EQ(calc->refCount(), 2);
+
+ Length lengthB;
+ lengthB = lengthA;
+ EXPECT_EQ(calc->refCount(), 3);
+
+ Length lengthC(calc);
+ lengthC = lengthA;
+ EXPECT_EQ(calc->refCount(), 4);
+
+ Length lengthD(CalculationValue::create(PixelsAndPercent(1, 2), ValueRangeAll));
+ lengthD = lengthA;
+ EXPECT_EQ(calc->refCount(), 5);
+}
+
+TEST(CSSCalculationValue, RefCountLeak)
+{
+ RefPtr<CalculationValue> calc = CalculationValue::create(PixelsAndPercent(1, 2), ValueRangeAll);
+ Length lengthA(calc);
+
+ Length lengthB = lengthA;
+ for (int i = 0; i < 100; ++i)
+ lengthB = lengthA;
+ EXPECT_EQ(calc->refCount(), 3);
+
+ Length lengthC(lengthA);
+ for (int i = 0; i < 100; ++i)
+ lengthC = lengthA;
+ EXPECT_EQ(calc->refCount(), 4);
+
+ Length lengthD(calc);
+ for (int i = 0; i < 100; ++i)
+ lengthD = lengthA;
+ EXPECT_EQ(calc->refCount(), 5);
+
+ lengthD = Length();
+ EXPECT_EQ(calc->refCount(), 4);
+}
+
+TEST(CSSCalculationValue, AddToLengthUnitValues)
+{
+ CSSLengthArray expectation, actual;
+ initLengthArray(expectation);
+ EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "0")));
+
+ expectation.at(CSSPrimitiveValue::UnitTypePixels) = 10;
+ EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "10px")));
+
+ expectation.at(CSSPrimitiveValue::UnitTypePixels) = 0;
+ expectation.at(CSSPrimitiveValue::UnitTypePercentage) = 20;
+ EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "20%%")));
+
+ expectation.at(CSSPrimitiveValue::UnitTypePixels) = 30;
+ expectation.at(CSSPrimitiveValue::UnitTypePercentage) = -40;
+ EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc(30px - 40%%)")));
+
+ expectation.at(CSSPrimitiveValue::UnitTypePixels) = 90;
+ expectation.at(CSSPrimitiveValue::UnitTypePercentage) = 10;
+ EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc(1in + 10%% - 6px)")));
+
+ expectation.at(CSSPrimitiveValue::UnitTypePixels) = 15;
+ expectation.at(CSSPrimitiveValue::UnitTypeFontSize) = 20;
+ expectation.at(CSSPrimitiveValue::UnitTypePercentage) = -40;
+ EXPECT_TRUE(lengthArraysEqual(expectation, setLengthArray(actual, "calc((1 * 2) * (5px + 20em / 2) - 80%% / (3 - 1) + 5px)")));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp
index ce46f047472..d770846aa40 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.cpp
@@ -33,8 +33,10 @@ namespace WebCore {
CSSCanvasValue::~CSSCanvasValue()
{
+#if !ENABLE(OILPAN)
if (m_element)
- m_element->removeObserver(&m_canvasObserver);
+ m_element->removeObserver(m_canvasObserver.get());
+#endif
}
String CSSCanvasValue::customCSSText() const
@@ -61,11 +63,13 @@ void CSSCanvasValue::canvasResized(HTMLCanvasElement*)
const_cast<RenderObject*>(curr->key)->imageChanged(static_cast<WrappedImagePtr>(this));
}
+#if !ENABLE(OILPAN)
void CSSCanvasValue::canvasDestroyed(HTMLCanvasElement* element)
{
ASSERT_UNUSED(element, element == m_element);
- m_element = 0;
+ m_element = nullptr;
}
+#endif
IntSize CSSCanvasValue::fixedSize(const RenderObject* renderer)
{
@@ -77,10 +81,8 @@ IntSize CSSCanvasValue::fixedSize(const RenderObject* renderer)
HTMLCanvasElement* CSSCanvasValue::element(Document* document)
{
if (!m_element) {
- m_element = document->getCSSCanvasElement(m_name);
- if (!m_element)
- return 0;
- m_element->addObserver(&m_canvasObserver);
+ m_element = &document->getCSSCanvasElement(m_name);
+ m_element->addObserver(m_canvasObserver.get());
}
return m_element;
}
@@ -90,7 +92,7 @@ PassRefPtr<Image> CSSCanvasValue::image(RenderObject* renderer, const IntSize& /
ASSERT(clients().contains(renderer));
HTMLCanvasElement* elt = element(&renderer->document());
if (!elt || !elt->buffer())
- return 0;
+ return nullptr;
return elt->copiedImage();
}
@@ -99,4 +101,11 @@ bool CSSCanvasValue::equals(const CSSCanvasValue& other) const
return m_name == other.m_name;
}
+void CSSCanvasValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_canvasObserver);
+ visitor->trace(m_element);
+ CSSImageGeneratorValue::traceAfterDispatch(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.h b/chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.h
index bb2325f2b8b..3e23b7eb0eb 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCanvasValue.h
@@ -35,7 +35,10 @@ class Document;
class CSSCanvasValue : public CSSImageGeneratorValue {
public:
- static PassRefPtr<CSSCanvasValue> create(const String& name) { return adoptRef(new CSSCanvasValue(name)); }
+ static PassRefPtrWillBeRawPtr<CSSCanvasValue> create(const String& name)
+ {
+ return adoptRefWillBeNoop(new CSSCanvasValue(name));
+ }
~CSSCanvasValue();
String customCSSText() const;
@@ -49,49 +52,63 @@ public:
bool equals(const CSSCanvasValue&) const;
+ void traceAfterDispatch(Visitor*);
+
private:
explicit CSSCanvasValue(const String& name)
: CSSImageGeneratorValue(CanvasClass)
- , m_canvasObserver(this)
+ , m_canvasObserver(adoptPtrWillBeNoop(new CanvasObserverProxy(this)))
, m_name(name)
- , m_element(0)
+ , m_element(nullptr)
{
}
// NOTE: We put the CanvasObserver in a member instead of inheriting from it
// to avoid adding a vptr to CSSCanvasValue.
- class CanvasObserverProxy : public CanvasObserver {
+ class CanvasObserverProxy FINAL : public NoBaseWillBeGarbageCollected<CanvasObserverProxy>, public CanvasObserver {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(CanvasObserverProxy);
public:
- CanvasObserverProxy(CSSCanvasValue* ownerValue) : m_ownerValue(ownerValue) { }
- virtual ~CanvasObserverProxy() { }
- virtual void canvasChanged(HTMLCanvasElement* canvas, const FloatRect& changedRect)
+ explicit CanvasObserverProxy(CSSCanvasValue* ownerValue) : m_ownerValue(ownerValue) { }
+
+ virtual void canvasChanged(HTMLCanvasElement* canvas, const FloatRect& changedRect) OVERRIDE
{
m_ownerValue->canvasChanged(canvas, changedRect);
}
- virtual void canvasResized(HTMLCanvasElement* canvas)
+ virtual void canvasResized(HTMLCanvasElement* canvas) OVERRIDE
{
m_ownerValue->canvasResized(canvas);
}
- virtual void canvasDestroyed(HTMLCanvasElement* canvas)
+#if !ENABLE(OILPAN)
+ virtual void canvasDestroyed(HTMLCanvasElement* canvas) OVERRIDE
{
m_ownerValue->canvasDestroyed(canvas);
}
+#endif
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_ownerValue);
+ CanvasObserver::trace(visitor);
+ }
+
private:
- CSSCanvasValue* m_ownerValue;
+ RawPtrWillBeMember<CSSCanvasValue> m_ownerValue;
};
void canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect);
void canvasResized(HTMLCanvasElement*);
+
+#if !ENABLE(OILPAN)
void canvasDestroyed(HTMLCanvasElement*);
+#endif
HTMLCanvasElement* element(Document*);
- CanvasObserverProxy m_canvasObserver;
+ OwnPtrWillBeMember<CanvasObserverProxy> m_canvasObserver;
// The name of the canvas.
String m_name;
// The document supplies the element and owns it.
- HTMLCanvasElement* m_element;
+ RawPtrWillBeWeakMember<HTMLCanvasElement> m_element;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSCanvasValue, isCanvasValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.h b/chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.h
index 26ae5fd793f..01c3a306c4a 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.h
@@ -28,11 +28,11 @@ namespace WebCore {
class ExceptionState;
-class CSSCharsetRule : public CSSRule {
+class CSSCharsetRule FINAL : public CSSRule {
public:
- static PassRefPtr<CSSCharsetRule> create(CSSStyleSheet* parent, const String& encoding)
+ static PassRefPtrWillBeRawPtr<CSSCharsetRule> create(CSSStyleSheet* parent, const String& encoding)
{
- return adoptRef(new CSSCharsetRule(parent, encoding));
+ return adoptRefWillBeNoop(new CSSCharsetRule(parent, encoding));
}
virtual ~CSSCharsetRule() { }
@@ -44,6 +44,8 @@ public:
const String& encoding() const { return m_encoding; }
void setEncoding(const String& encoding) { m_encoding = encoding; }
+ virtual void trace(Visitor* visitor) OVERRIDE { CSSRule::trace(visitor); }
+
private:
CSSCharsetRule(CSSStyleSheet* parent, const String& encoding);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.idl b/chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.idl
index 18216075aba..1635a719012 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.idl
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCharsetRule.idl
@@ -19,5 +19,5 @@
*/
interface CSSCharsetRule : CSSRule {
- attribute DOMString encoding;
+ [MeasureAs=CSSCharsetRuleEncoding] attribute DOMString encoding;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp b/chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
index d5888386226..733191a5147 100755..100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
@@ -24,11 +24,9 @@
#include "config.h"
#include "core/css/CSSComputedStyleDeclaration.h"
-#include "CSSPropertyNames.h"
-#include "FontFamilyNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "StylePropertyShorthand.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/CSSPropertyNames.h"
+#include "core/StylePropertyShorthand.h"
#include "core/animation/DocumentAnimations.h"
#include "core/css/BasicShapeFunctions.h"
#include "core/css/CSSArrayFunctionValue.h"
@@ -39,10 +37,9 @@
#include "core/css/CSSFontValue.h"
#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSGridLineNamesValue.h"
-#include "core/css/CSSGridTemplateValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
#include "core/css/CSSLineBoxContainValue.h"
-#include "core/css/CSSMixFunctionValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSReflectValue.h"
@@ -60,23 +57,16 @@
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/PseudoElement.h"
-#include "core/frame/animation/AnimationController.h"
#include "core/rendering/RenderBox.h"
#include "core/rendering/RenderGrid.h"
-#include "core/rendering/RenderView.h"
#include "core/rendering/style/ContentData.h"
#include "core/rendering/style/CounterContent.h"
-#include "core/rendering/style/CursorList.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/ShadowList.h"
#include "core/rendering/style/ShapeValue.h"
-#include "core/rendering/style/StyleCustomFilterProgram.h"
+#include "platform/FontFamilyNames.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/fonts/FontFeatureSettings.h"
-#include "platform/graphics/filters/custom/CustomFilterArrayParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterNumberParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterOperation.h"
-#include "platform/graphics/filters/custom/CustomFilterParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterTransformParameter.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -141,10 +131,12 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyFontSize,
CSSPropertyFontStyle,
CSSPropertyFontVariant,
+ CSSPropertyFontVariantLigatures,
CSSPropertyFontWeight,
CSSPropertyHeight,
CSSPropertyImageRendering,
CSSPropertyIsolation,
+ CSSPropertyJustifySelf,
CSSPropertyLeft,
CSSPropertyLetterSpacing,
CSSPropertyLineHeight,
@@ -182,6 +174,7 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyPosition,
CSSPropertyResize,
CSSPropertyRight,
+ CSSPropertyScrollBehavior,
CSSPropertySpeak,
CSSPropertyTableLayout,
CSSPropertyTabSize,
@@ -211,6 +204,7 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyWhiteSpace,
CSSPropertyWidows,
CSSPropertyWidth,
+ CSSPropertyWillChange,
CSSPropertyWordBreak,
CSSPropertyWordSpacing,
CSSPropertyWordWrap,
@@ -226,6 +220,7 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyWebkitAnimationPlayState,
CSSPropertyWebkitAnimationTimingFunction,
CSSPropertyWebkitAppearance,
+ CSSPropertyBackfaceVisibility,
CSSPropertyWebkitBackfaceVisibility,
CSSPropertyWebkitBackgroundClip,
CSSPropertyWebkitBackgroundComposite,
@@ -250,10 +245,8 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyWebkitColumnBreakAfter,
CSSPropertyWebkitColumnBreakBefore,
CSSPropertyWebkitColumnBreakInside,
- CSSPropertyWebkitColumnAxis,
CSSPropertyWebkitColumnCount,
CSSPropertyWebkitColumnGap,
- CSSPropertyWebkitColumnProgression,
CSSPropertyWebkitColumnRuleColor,
CSSPropertyWebkitColumnRuleStyle,
CSSPropertyWebkitColumnRuleWidth,
@@ -270,24 +263,21 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyFlexWrap,
CSSPropertyJustifyContent,
CSSPropertyWebkitFontSmoothing,
- CSSPropertyWebkitFontVariantLigatures,
CSSPropertyGridAutoColumns,
CSSPropertyGridAutoFlow,
CSSPropertyGridAutoRows,
CSSPropertyGridColumnEnd,
CSSPropertyGridColumnStart,
- CSSPropertyGridDefinitionColumns,
- CSSPropertyGridDefinitionRows,
+ CSSPropertyGridTemplateAreas,
+ CSSPropertyGridTemplateColumns,
+ CSSPropertyGridTemplateRows,
CSSPropertyGridRowEnd,
CSSPropertyGridRowStart,
CSSPropertyWebkitHighlight,
CSSPropertyWebkitHyphenateCharacter,
- CSSPropertyWebkitLineAlign,
CSSPropertyWebkitLineBoxContain,
CSSPropertyWebkitLineBreak,
CSSPropertyWebkitLineClamp,
- CSSPropertyWebkitLineGrid,
- CSSPropertyWebkitLineSnap,
CSSPropertyWebkitLocale,
CSSPropertyWebkitMarginBeforeCollapse,
CSSPropertyWebkitMarginAfterCollapse,
@@ -305,13 +295,13 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyWebkitMaskRepeat,
CSSPropertyWebkitMaskSize,
CSSPropertyOrder,
+ CSSPropertyPerspective,
CSSPropertyWebkitPerspective,
+ CSSPropertyPerspectiveOrigin,
CSSPropertyWebkitPerspectiveOrigin,
CSSPropertyWebkitPrintColorAdjust,
CSSPropertyWebkitRtlOrdering,
- CSSPropertyShapeInside,
CSSPropertyShapeOutside,
- CSSPropertyShapePadding,
CSSPropertyShapeImageThreshold,
CSSPropertyShapeMargin,
CSSPropertyWebkitTapHighlightColor,
@@ -325,8 +315,11 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyWebkitTextSecurity,
CSSPropertyWebkitTextStrokeColor,
CSSPropertyWebkitTextStrokeWidth,
+ CSSPropertyTransform,
CSSPropertyWebkitTransform,
+ CSSPropertyTransformOrigin,
CSSPropertyWebkitTransformOrigin,
+ CSSPropertyTransformStyle,
CSSPropertyWebkitTransformStyle,
CSSPropertyWebkitTransitionDelay,
CSSPropertyWebkitTransitionDuration,
@@ -336,12 +329,6 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyWebkitUserModify,
CSSPropertyWebkitUserSelect,
CSSPropertyWebkitWritingMode,
- CSSPropertyWebkitFlowInto,
- CSSPropertyWebkitFlowFrom,
- CSSPropertyWebkitRegionBreakAfter,
- CSSPropertyWebkitRegionBreakBefore,
- CSSPropertyWebkitRegionBreakInside,
- CSSPropertyWebkitRegionFragment,
CSSPropertyWebkitAppRegion,
CSSPropertyWebkitWrapFlow,
CSSPropertyWebkitWrapThrough,
@@ -378,7 +365,6 @@ static const CSSPropertyID staticComputableProperties[] = {
CSSPropertyAlignmentBaseline,
CSSPropertyBaselineShift,
CSSPropertyDominantBaseline,
- CSSPropertyKerning,
CSSPropertyTextAnchor,
CSSPropertyWritingMode,
CSSPropertyGlyphOrientationHorizontal,
@@ -409,13 +395,13 @@ static CSSValueID valueForRepeatRule(int rule)
}
}
-static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
+static PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const NinePieceImage& image)
{
// Create the slices.
- RefPtr<CSSPrimitiveValue> top;
- RefPtr<CSSPrimitiveValue> right;
- RefPtr<CSSPrimitiveValue> bottom;
- RefPtr<CSSPrimitiveValue> left;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> top = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> right = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> bottom = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> left = nullptr;
if (image.imageSlices().top().isPercent())
top = cssValuePool().createValue(image.imageSlices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
@@ -453,7 +439,7 @@ static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const Ni
}
}
- RefPtr<Quad> quad = Quad::create();
+ RefPtrWillBeRawPtr<Quad> quad = Quad::create();
quad->setTop(top);
quad->setRight(right);
quad->setBottom(bottom);
@@ -462,13 +448,13 @@ static PassRefPtr<CSSBorderImageSliceValue> valueForNinePieceImageSlice(const Ni
return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), image.fill());
}
-static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const BorderImageLengthBox& box, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const BorderImageLengthBox& box, const RenderStyle& style)
{
// Create the slices.
- RefPtr<CSSPrimitiveValue> top;
- RefPtr<CSSPrimitiveValue> right;
- RefPtr<CSSPrimitiveValue> bottom;
- RefPtr<CSSPrimitiveValue> left;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> top = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> right = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> bottom = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> left = nullptr;
if (box.top().isNumber())
top = cssValuePool().createValue(box.top().number(), CSSPrimitiveValue::CSS_NUMBER);
@@ -505,7 +491,7 @@ static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const BorderImag
}
}
- RefPtr<Quad> quad = Quad::create();
+ RefPtrWillBeRawPtr<Quad> quad = Quad::create();
quad->setTop(top);
quad->setRight(right);
quad->setBottom(bottom);
@@ -514,10 +500,10 @@ static PassRefPtr<CSSPrimitiveValue> valueForNinePieceImageQuad(const BorderImag
return cssValuePool().createValue(quad.release());
}
-static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
{
- RefPtr<CSSPrimitiveValue> horizontalRepeat;
- RefPtr<CSSPrimitiveValue> verticalRepeat;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRepeat = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRepeat = nullptr;
horizontalRepeat = cssValuePool().createIdentifierValue(valueForRepeatRule(image.horizontalRule()));
if (image.horizontalRule() == image.verticalRule())
@@ -527,60 +513,60 @@ static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& i
return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release(), Pair::DropIdenticalValues));
}
-static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, const RenderStyle& style)
{
if (!image.hasImage())
return cssValuePool().createIdentifierValue(CSSValueNone);
// Image first.
- RefPtr<CSSValue> imageValue;
+ RefPtrWillBeRawPtr<CSSValue> imageValue = nullptr;
if (image.image())
imageValue = image.image()->cssValue();
// Create the image slice.
- RefPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
+ RefPtrWillBeRawPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
// Create the border area slices.
- RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices(), style);
+ RefPtrWillBeRawPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices(), style);
// Create the border outset.
- RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset(), style);
+ RefPtrWillBeRawPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset(), style);
// Create the repeat rules.
- RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
+ RefPtrWillBeRawPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release());
}
-inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(double value, const RenderStyle& style)
{
return cssValuePool().createValue(adjustFloatForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
}
-inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style)
+inline static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle& style)
{
return cssValuePool().createValue(value / style.effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
}
-static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle& style)
{
if (length.isFixed())
return zoomAdjustedPixelValue(length.value(), style);
return cssValuePool().createValue(length, style);
}
-static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
{
if (!reflection)
return cssValuePool().createIdentifierValue(CSSValueNone);
- RefPtr<CSSPrimitiveValue> offset;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> offset = nullptr;
if (reflection->offset().isPercent())
offset = cssValuePool().createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
else
offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
- RefPtr<CSSPrimitiveValue> direction;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> direction = nullptr;
switch (reflection->direction()) {
case ReflectionBelow:
direction = cssValuePool().createIdentifierValue(CSSValueBelow);
@@ -599,9 +585,9 @@ static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection
return CSSReflectValue::create(direction.release(), offset.release(), valueForNinePieceImage(reflection->mask(), style));
}
-static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propertyID, const FillLayer* layer, const RenderStyle& style)
{
- RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated();
if (layer->isBackgroundXOriginSet()) {
ASSERT_UNUSED(propertyID, propertyID == CSSPropertyBackgroundPosition || propertyID == CSSPropertyWebkitMaskPosition);
positionList->append(cssValuePool().createValue(layer->backgroundXOrigin()));
@@ -615,7 +601,7 @@ static PassRefPtr<CSSValueList> createPositionListForLayer(CSSPropertyID propert
return positionList.release();
}
-static PassRefPtr<CSSValue> valueForPositionOffset(RenderStyle& style, CSSPropertyID propertyID, const RenderObject* renderer, RenderView* renderView)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForPositionOffset(RenderStyle& style, CSSPropertyID propertyID, const RenderObject* renderer)
{
Length l;
switch (propertyID) {
@@ -632,38 +618,34 @@ static PassRefPtr<CSSValue> valueForPositionOffset(RenderStyle& style, CSSProper
l = style.bottom();
break;
default:
- return 0;
+ return nullptr;
}
if (l.isPercent() && renderer && renderer->isBox()) {
LayoutUnit containingBlockSize = (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ?
toRenderBox(renderer)->containingBlockLogicalWidthForContent() :
toRenderBox(renderer)->containingBlockLogicalHeightForContent(ExcludeMarginBorderPadding);
- return zoomAdjustedPixelValue(valueForLength(l, containingBlockSize, 0), style);
+ return zoomAdjustedPixelValue(valueForLength(l, containingBlockSize), style);
}
- if (l.isViewportPercentage())
- return zoomAdjustedPixelValue(valueForLength(l, 0, renderView), style);
if (l.isAuto()) {
// FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
// In other words if left is auto and right is not auto, then left's computed value is negative right().
// So we should get the opposite length unit and see if it is auto.
- return cssValuePool().createValue(l);
+ return cssValuePool().createIdentifierValue(CSSValueAuto);
}
return zoomAdjustedPixelValueForLength(l, style);
}
-PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(const RenderStyle& style, const Color& color) const
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(const RenderStyle& style, const StyleColor& color) const
{
// This function does NOT look at visited information, so that computed style doesn't expose that.
- if (!color.isValid())
- return cssValuePool().createColorValue(style.color().rgb());
- return cssValuePool().createColorValue(color.rgb());
+ return cssValuePool().createColorValue(color.resolve(style.color()).rgb());
}
-static PassRefPtr<CSSValueList> valuesForBorderRadiusCorner(LengthSize radius, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValueList> valuesForBorderRadiusCorner(LengthSize radius, const RenderStyle& style)
{
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (radius.width().type() == Percent)
list->append(cssValuePool().createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
else
@@ -675,17 +657,17 @@ static PassRefPtr<CSSValueList> valuesForBorderRadiusCorner(LengthSize radius, c
return list.release();
}
-static PassRefPtr<CSSValue> valueForBorderRadiusCorner(LengthSize radius, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForBorderRadiusCorner(LengthSize radius, const RenderStyle& style)
{
- RefPtr<CSSValueList> list = valuesForBorderRadiusCorner(radius, style);
+ RefPtrWillBeRawPtr<CSSValueList> list = valuesForBorderRadiusCorner(radius, style);
if (list->item(0)->equals(*list->item(1)))
return list->item(0);
return list.release();
}
-static PassRefPtr<CSSValueList> valueForBorderRadiusShorthand(const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValueList> valueForBorderRadiusShorthand(const RenderStyle& style)
{
- RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
bool showHorizontalBottomLeft = style.borderTopRightRadius().width() != style.borderBottomLeftRadius().width();
bool showHorizontalBottomRight = showHorizontalBottomLeft || (style.borderBottomRightRadius().width() != style.borderTopLeftRadius().width());
@@ -695,12 +677,12 @@ static PassRefPtr<CSSValueList> valueForBorderRadiusShorthand(const RenderStyle&
bool showVerticalBottomRight = showVerticalBottomLeft || (style.borderBottomRightRadius().height() != style.borderTopLeftRadius().height());
bool showVerticalTopRight = showVerticalBottomRight || (style.borderTopRightRadius().height() != style.borderTopLeftRadius().height());
- RefPtr<CSSValueList> topLeftRadius = valuesForBorderRadiusCorner(style.borderTopLeftRadius(), style);
- RefPtr<CSSValueList> topRightRadius = valuesForBorderRadiusCorner(style.borderTopRightRadius(), style);
- RefPtr<CSSValueList> bottomRightRadius = valuesForBorderRadiusCorner(style.borderBottomRightRadius(), style);
- RefPtr<CSSValueList> bottomLeftRadius = valuesForBorderRadiusCorner(style.borderBottomLeftRadius(), style);
+ RefPtrWillBeRawPtr<CSSValueList> topLeftRadius = valuesForBorderRadiusCorner(style.borderTopLeftRadius(), style);
+ RefPtrWillBeRawPtr<CSSValueList> topRightRadius = valuesForBorderRadiusCorner(style.borderTopRightRadius(), style);
+ RefPtrWillBeRawPtr<CSSValueList> bottomRightRadius = valuesForBorderRadiusCorner(style.borderBottomRightRadius(), style);
+ RefPtrWillBeRawPtr<CSSValueList> bottomLeftRadius = valuesForBorderRadiusCorner(style.borderBottomLeftRadius(), style);
- RefPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> horizontalRadii = CSSValueList::createSpaceSeparated();
horizontalRadii->append(topLeftRadius->item(0));
if (showHorizontalTopRight)
horizontalRadii->append(topRightRadius->item(0));
@@ -711,7 +693,7 @@ static PassRefPtr<CSSValueList> valueForBorderRadiusShorthand(const RenderStyle&
list->append(horizontalRadii.release());
- RefPtr<CSSValueList> verticalRadii = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> verticalRadii = CSSValueList::createSpaceSeparated();
verticalRadii->append(topLeftRadius->item(1));
if (showVerticalTopRight)
verticalRadii->append(topRightRadius->item(1));
@@ -735,9 +717,9 @@ static LayoutRect sizingBox(RenderObject* renderer)
return box->style()->boxSizing() == BORDER_BOX ? box->borderBoxRect() : box->computedCSSContentBoxRect();
}
-static PassRefPtr<CSSTransformValue> valueForMatrixTransform(const TransformationMatrix& transform, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSTransformValue> valueForMatrixTransform(const TransformationMatrix& transform, const RenderStyle& style)
{
- RefPtr<CSSTransformValue> transformValue;
+ RefPtrWillBeRawPtr<CSSTransformValue> transformValue = nullptr;
if (transform.isAffine()) {
transformValue = CSSTransformValue::create(CSSTransformValue::MatrixTransformOperation);
@@ -774,7 +756,7 @@ static PassRefPtr<CSSTransformValue> valueForMatrixTransform(const Transformatio
return transformValue.release();
}
-static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
{
if (!renderer || !renderer->hasTransform() || !style.hasTransform())
return cssValuePool().createIdentifierValue(CSSValueNone);
@@ -787,69 +769,24 @@ static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const Rend
style.applyTransform(transform, box.size(), RenderStyle::ExcludeTransformOrigin);
// FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
list->append(valueForMatrixTransform(transform, style));
return list.release();
}
-static PassRefPtr<CSSValue> valueForCustomFilterArrayParameter(const CustomFilterArrayParameter* arrayParameter)
-{
- RefPtr<CSSArrayFunctionValue> arrayParameterValue = CSSArrayFunctionValue::create();
- for (unsigned i = 0, size = arrayParameter->size(); i < size; ++i)
- arrayParameterValue->append(cssValuePool().createValue(arrayParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
- return arrayParameterValue.release();
-}
-
-static PassRefPtr<CSSValue> valueForCustomFilterNumberParameter(const CustomFilterNumberParameter* numberParameter)
-{
- RefPtr<CSSValueList> numberParameterValue = CSSValueList::createSpaceSeparated();
- for (unsigned i = 0; i < numberParameter->size(); ++i)
- numberParameterValue->append(cssValuePool().createValue(numberParameter->valueAt(i), CSSPrimitiveValue::CSS_NUMBER));
- return numberParameterValue.release();
-}
-
-static PassRefPtr<CSSValue> valueForCustomFilterTransformParameter(const RenderObject* renderer, const RenderStyle& style, const CustomFilterTransformParameter* transformParameter)
-{
- IntSize size;
- if (renderer && renderer->isBox())
- size = pixelSnappedIntRect(toRenderBox(renderer)->borderBoxRect()).size();
-
- TransformationMatrix transform;
- transformParameter->applyTransform(transform, size);
- // FIXME: Need to print out individual functions (https://bugs.webkit.org/show_bug.cgi?id=23924)
- return valueForMatrixTransform(transform, style);
-}
-
-static PassRefPtr<CSSValue> valueForCustomFilterParameter(const RenderObject* renderer, const RenderStyle& style, const CustomFilterParameter* parameter)
-{
- // FIXME: Add here computed style for the other types: boolean, transform, matrix, texture.
- ASSERT(parameter);
- switch (parameter->parameterType()) {
- case CustomFilterParameter::Array:
- return valueForCustomFilterArrayParameter(static_cast<const CustomFilterArrayParameter*>(parameter));
- case CustomFilterParameter::Number:
- return valueForCustomFilterNumberParameter(static_cast<const CustomFilterNumberParameter*>(parameter));
- case CustomFilterParameter::Transform:
- return valueForCustomFilterTransformParameter(renderer, style, static_cast<const CustomFilterTransformParameter*>(parameter));
- }
-
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle& style) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle& style) const
{
if (style.filter().operations().isEmpty())
return cssValuePool().createIdentifierValue(CSSValueNone);
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- RefPtr<CSSFilterValue> filterValue;
+ RefPtrWillBeRawPtr<CSSFilterValue> filterValue = nullptr;
Vector<RefPtr<FilterOperation> >::const_iterator end = style.filter().operations().end();
for (Vector<RefPtr<FilterOperation> >::const_iterator it = style.filter().operations().begin(); it != end; ++it) {
- FilterOperation* filterOperation = (*it).get();
+ FilterOperation* filterOperation = it->get();
switch (filterOperation->type()) {
case FilterOperation::REFERENCE:
filterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
@@ -899,68 +836,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObj
filterValue->append(valueForShadowData(shadow, style, false));
break;
}
- case FilterOperation::VALIDATED_CUSTOM:
- // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
- ASSERT_NOT_REACHED();
- break;
- case FilterOperation::CUSTOM: {
- CustomFilterOperation* customOperation = toCustomFilterOperation(filterOperation);
- filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation);
-
- // The output should be verbose, even if the values are the default ones.
-
- ASSERT(customOperation->program());
- StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customOperation->program());
-
- RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated();
- if (program->vertexShader())
- shadersList->append(program->vertexShader()->cssValue());
- else
- shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
-
- const CustomFilterProgramMixSettings mixSettings = program->mixSettings();
- if (program->fragmentShader()) {
- if (program->programType() == ProgramTypeBlendsElementTexture) {
- RefPtr<CSSMixFunctionValue> mixFunction = CSSMixFunctionValue::create();
- mixFunction->append(program->fragmentShader()->cssValue());
- mixFunction->append(cssValuePool().createValue(mixSettings.blendMode));
- mixFunction->append(cssValuePool().createValue(mixSettings.compositeOperator));
- shadersList->append(mixFunction.release());
- } else
- shadersList->append(program->fragmentShader()->cssValue());
- }
- else
- shadersList->append(cssValuePool().createIdentifierValue(CSSValueNone));
-
- filterValue->append(shadersList.release());
-
- RefPtr<CSSValueList> meshParameters = CSSValueList::createSpaceSeparated();
- meshParameters->append(cssValuePool().createValue(customOperation->meshColumns(), CSSPrimitiveValue::CSS_NUMBER));
- meshParameters->append(cssValuePool().createValue(customOperation->meshRows(), CSSPrimitiveValue::CSS_NUMBER));
-
- // FIXME: The specification doesn't have any "attached" identifier. Should we add one?
- // https://bugs.webkit.org/show_bug.cgi?id=72700
- if (customOperation->meshType() == MeshTypeDetached)
- meshParameters->append(cssValuePool().createIdentifierValue(CSSValueDetached));
-
- filterValue->append(meshParameters.release());
-
- const CustomFilterParameterList& parameters = customOperation->parameters();
- size_t parametersSize = parameters.size();
- if (!parametersSize)
- break;
- RefPtr<CSSValueList> parametersCSSValue = CSSValueList::createCommaSeparated();
- for (size_t i = 0; i < parametersSize; ++i) {
- const CustomFilterParameter* parameter = parameters.at(i).get();
- RefPtr<CSSValueList> parameterCSSNameAndValue = CSSValueList::createSpaceSeparated();
- parameterCSSNameAndValue->append(cssValuePool().createValue(parameter->name(), CSSPrimitiveValue::CSS_STRING));
- parameterCSSNameAndValue->append(valueForCustomFilterParameter(renderer, style, parameter));
- parametersCSSValue->append(parameterCSSNameAndValue.release());
- }
-
- filterValue->append(parametersCSSValue.release());
- break;
- }
default:
filterValue = CSSFilterValue::create(CSSFilterValue::UnknownFilterOperation);
break;
@@ -971,7 +846,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObj
return list.release();
}
-static PassRefPtr<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style, RenderView* renderView)
+static PassRefPtrWillBeRawPtr<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style)
{
if (!trackBreadth.isLength())
return cssValuePool().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR);
@@ -979,24 +854,22 @@ static PassRefPtr<CSSValue> specifiedValueForGridTrackBreadth(const GridLength&
const Length& trackBreadthLength = trackBreadth.length();
if (trackBreadthLength.isAuto())
return cssValuePool().createIdentifierValue(CSSValueAuto);
- if (trackBreadthLength.isViewportPercentage())
- return zoomAdjustedPixelValue(valueForLength(trackBreadthLength, 0, renderView), style);
return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
}
-static PassRefPtr<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style, RenderView* renderView)
+static PassRefPtrWillBeRawPtr<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style)
{
switch (trackSize.type()) {
case LengthTrackSizing:
- return specifiedValueForGridTrackBreadth(trackSize.length(), style, renderView);
+ return specifiedValueForGridTrackBreadth(trackSize.length(), style);
case MinMaxTrackSizing:
- RefPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
- minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style, renderView));
- minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style, renderView));
+ RefPtrWillBeRawPtr<CSSValueList> minMaxTrackBreadths = CSSValueList::createCommaSeparated();
+ minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.minTrackBreadth(), style));
+ minMaxTrackBreadths->append(specifiedValueForGridTrackBreadth(trackSize.maxTrackBreadth(), style));
return CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
}
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
static void addValuesForNamedGridLinesAtIndex(const OrderedNamedGridLines& orderedNamedGridLines, size_t i, CSSValueList& list)
@@ -1005,15 +878,15 @@ static void addValuesForNamedGridLinesAtIndex(const OrderedNamedGridLines& order
if (namedGridLines.isEmpty())
return;
- RefPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
+ RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
for (size_t j = 0; j < namedGridLines.size(); ++j)
lineNames->append(cssValuePool().createValue(namedGridLines[j], CSSPrimitiveValue::CSS_STRING));
list.append(lineNames.release());
}
-static PassRefPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style, RenderView* renderView)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style)
{
- const Vector<GridTrackSize>& trackSizes = direction == ForColumns ? style.gridDefinitionColumns() : style.gridDefinitionRows();
+ const Vector<GridTrackSize>& trackSizes = direction == ForColumns ? style.gridTemplateColumns() : style.gridTemplateRows();
const OrderedNamedGridLines& orderedNamedGridLines = direction == ForColumns ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines();
// Handle the 'none' case here.
@@ -1022,7 +895,7 @@ static PassRefPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direc
return cssValuePool().createIdentifierValue(CSSValueNone);
}
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (renderer && renderer->isRenderGrid()) {
const Vector<LayoutUnit>& trackPositions = direction == ForColumns ? toRenderGrid(renderer)->columnPositions() : toRenderGrid(renderer)->rowPositions();
// There are at least #tracks + 1 grid lines (trackPositions). Apart from that, the grid container can generate implicit grid tracks,
@@ -1036,7 +909,7 @@ static PassRefPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direc
} else {
for (size_t i = 0; i < trackSizes.size(); ++i) {
addValuesForNamedGridLinesAtIndex(orderedNamedGridLines, i, *list);
- list->append(specifiedValueForGridTrackSize(trackSizes[i], style, renderView));
+ list->append(specifiedValueForGridTrackSize(trackSizes[i], style));
}
}
// Those are the trailing <string>* allowed in the syntax.
@@ -1044,7 +917,7 @@ static PassRefPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direc
return list.release();
}
-static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForGridPosition(const GridPosition& position)
{
if (position.isAuto())
return cssValuePool().createIdentifierValue(CSSValueAuto);
@@ -1052,7 +925,7 @@ static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
if (position.isNamedGridArea())
return cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING);
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (position.isSpan()) {
list->append(cssValuePool().createIdentifierValue(CSSValueSpan));
list->append(cssValuePool().createValue(position.spanPosition(), CSSPrimitiveValue::CSS_NUMBER));
@@ -1063,55 +936,71 @@ static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
list->append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
return list;
}
-static PassRefPtr<CSSValue> createTransitionPropertyValue(const CSSAnimationData* animation)
+
+static PassRefPtrWillBeRawPtr<CSSValue> createTransitionPropertyValue(const CSSTransitionData::TransitionProperty& property)
{
- RefPtr<CSSValue> propertyValue;
- if (animation->animationMode() == CSSAnimationData::AnimateNone)
- propertyValue = cssValuePool().createIdentifierValue(CSSValueNone);
- else if (animation->animationMode() == CSSAnimationData::AnimateAll)
- propertyValue = cssValuePool().createIdentifierValue(CSSValueAll);
- else
- propertyValue = cssValuePool().createValue(getPropertyNameString(animation->property()), CSSPrimitiveValue::CSS_STRING);
- return propertyValue.release();
+ if (property.propertyType == CSSTransitionData::TransitionNone)
+ return cssValuePool().createIdentifierValue(CSSValueNone);
+ if (property.propertyType == CSSTransitionData::TransitionAll)
+ return cssValuePool().createIdentifierValue(CSSValueAll);
+ if (property.propertyType == CSSTransitionData::TransitionUnknown)
+ return cssValuePool().createValue(property.propertyString, CSSPrimitiveValue::CSS_STRING);
+ ASSERT(property.propertyType == CSSTransitionData::TransitionSingleProperty);
+ return cssValuePool().createValue(getPropertyNameString(property.propertyId), CSSPrimitiveValue::CSS_STRING);
}
-static PassRefPtr<CSSValue> valueForTransitionProperty(const CSSAnimationDataList* animList)
+
+static PassRefPtrWillBeRawPtr<CSSValue> valueForTransitionProperty(const CSSTransitionData* transitionData)
{
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- if (animList) {
- for (size_t i = 0; i < animList->size(); ++i)
- list->append(createTransitionPropertyValue(animList->animation(i)));
- } else
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ if (transitionData) {
+ for (size_t i = 0; i < transitionData->propertyList().size(); ++i)
+ list->append(createTransitionPropertyValue(transitionData->propertyList()[i]));
+ } else {
list->append(cssValuePool().createIdentifierValue(CSSValueAll));
+ }
return list.release();
}
-static PassRefPtr<CSSValue> valueForAnimationDelay(const CSSAnimationDataList* animList)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationDelay(const CSSTimingData* timingData)
{
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- if (animList) {
- for (size_t i = 0; i < animList->size(); ++i)
- list->append(cssValuePool().createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ if (timingData) {
+ for (size_t i = 0; i < timingData->delayList().size(); ++i)
+ list->append(cssValuePool().createValue(timingData->delayList()[i], CSSPrimitiveValue::CSS_S));
} else {
- // Note that initialAnimationDelay() is used for both transitions and animations
- list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
+ list->append(cssValuePool().createValue(CSSTimingData::initialDelay(), CSSPrimitiveValue::CSS_S));
}
return list.release();
}
-static PassRefPtr<CSSValue> valueForAnimationDuration(const CSSAnimationDataList* animList)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationDuration(const CSSTimingData* timingData)
{
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- if (animList) {
- for (size_t i = 0; i < animList->size(); ++i)
- list->append(cssValuePool().createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ if (timingData) {
+ for (size_t i = 0; i < timingData->durationList().size(); ++i)
+ list->append(cssValuePool().createValue(timingData->durationList()[i], CSSPrimitiveValue::CSS_S));
} else {
- // Note that initialAnimationDuration() is used for both transitions and animations
- list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
+ list->append(cssValuePool().createValue(CSSTimingData::initialDuration(), CSSPrimitiveValue::CSS_S));
}
return list.release();
}
-static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationIterationCount(double iterationCount)
+{
+ if (iterationCount == std::numeric_limits<double>::infinity())
+ return cssValuePool().createIdentifierValue(CSSValueInfinite);
+ return cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER);
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationPlayState(EAnimPlayState playState)
+{
+ if (playState == AnimPlayStatePlaying)
+ return cssValuePool().createIdentifierValue(CSSValueRunning);
+ ASSERT(playState == AnimPlayStatePaused);
+ return cssValuePool().createIdentifierValue(CSSValuePaused);
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
{
switch (timingFunction->type()) {
case TimingFunction::CubicBezierFunction:
@@ -1134,7 +1023,7 @@ static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timi
break;
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
return cssValuePool().createIdentifierValue(valueId);
}
@@ -1145,7 +1034,8 @@ static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timi
{
const StepsTimingFunction* stepsTimingFunction = toStepsTimingFunction(timingFunction);
if (stepsTimingFunction->subType() == StepsTimingFunction::Custom)
- return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
+ return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtPosition());
+
CSSValueID valueId;
switch (stepsTimingFunction->subType()) {
case StepsTimingFunction::Start:
@@ -1156,7 +1046,7 @@ static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timi
break;
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
return cssValuePool().createIdentifierValue(valueId);
}
@@ -1166,63 +1056,79 @@ static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timi
}
}
-static PassRefPtr<CSSValue> valueForAnimationTimingFunction(const CSSAnimationDataList* animList)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationTimingFunction(const CSSTimingData* timingData)
{
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- if (animList) {
- for (size_t i = 0; i < animList->size(); ++i)
- list->append(createTimingFunctionValue(animList->animation(i)->timingFunction()));
- } else
- // Note that initialAnimationTimingFunction() is used for both transitions and animations
- list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ if (timingData) {
+ for (size_t i = 0; i < timingData->timingFunctionList().size(); ++i)
+ list->append(createTimingFunctionValue(timingData->timingFunctionList()[i].get()));
+ } else {
+ list->append(createTimingFunctionValue(CSSTimingData::initialTimingFunction().get()));
+ }
return list.release();
}
-static PassRefPtr<CSSValue> valueForAnimationFillMode(unsigned fillMode)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationFillMode(Timing::FillMode fillMode)
{
switch (fillMode) {
- case AnimationFillModeNone:
+ case Timing::FillModeNone:
return cssValuePool().createIdentifierValue(CSSValueNone);
- case AnimationFillModeForwards:
+ case Timing::FillModeForwards:
return cssValuePool().createIdentifierValue(CSSValueForwards);
- case AnimationFillModeBackwards:
+ case Timing::FillModeBackwards:
return cssValuePool().createIdentifierValue(CSSValueBackwards);
- case AnimationFillModeBoth:
+ case Timing::FillModeBoth:
return cssValuePool().createIdentifierValue(CSSValueBoth);
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
}
-static PassRefPtr<CSSValue> valueForAnimationDirection(CSSAnimationData::AnimationDirection direction)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationDirection(Timing::PlaybackDirection direction)
{
switch (direction) {
- case CSSAnimationData::AnimationDirectionNormal:
+ case Timing::PlaybackDirectionNormal:
return cssValuePool().createIdentifierValue(CSSValueNormal);
- case CSSAnimationData::AnimationDirectionAlternate:
+ case Timing::PlaybackDirectionAlternate:
return cssValuePool().createIdentifierValue(CSSValueAlternate);
- case CSSAnimationData::AnimationDirectionReverse:
+ case Timing::PlaybackDirectionReverse:
return cssValuePool().createIdentifierValue(CSSValueReverse);
- case CSSAnimationData::AnimationDirectionAlternateReverse:
+ case Timing::PlaybackDirectionAlternateReverse:
return cssValuePool().createIdentifierValue(CSSValueAlternateReverse);
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
}
-static PassRefPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForWillChange(const Vector<CSSPropertyID>& willChangeProperties, bool willChangeContents, bool willChangeScrollPosition)
+{
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ if (willChangeContents)
+ list->append(cssValuePool().createIdentifierValue(CSSValueContents));
+ if (willChangeScrollPosition)
+ list->append(cssValuePool().createIdentifierValue(CSSValueScrollPosition));
+ for (size_t i = 0; i < willChangeProperties.size(); ++i)
+ list->append(cssValuePool().createIdentifierValue(willChangeProperties[i]));
+ if (!list->length())
+ list->append(cssValuePool().createIdentifierValue(CSSValueAuto));
+ return list.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
{
if (!lineBoxContain)
return cssValuePool().createIdentifierValue(CSSValueNone);
return CSSLineBoxContainValue::create(lineBoxContain);
}
-CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
+CSSComputedStyleDeclaration::CSSComputedStyleDeclaration(PassRefPtrWillBeRawPtr<Node> n, bool allowVisitedStyle, const String& pseudoElementName)
: m_node(n)
, m_allowVisitedStyle(allowVisitedStyle)
+#if !ENABLE(OILPAN)
, m_refCount(1)
+#endif
{
unsigned nameWithoutColonsStart = pseudoElementName[0] == ':' ? (pseudoElementName[1] == ':' ? 2 : 1) : 0;
m_pseudoElementSpecifier = CSSSelector::pseudoId(CSSSelector::parsePseudoType(
@@ -1233,6 +1139,7 @@ CSSComputedStyleDeclaration::~CSSComputedStyleDeclaration()
{
}
+#if !ENABLE(OILPAN)
void CSSComputedStyleDeclaration::ref()
{
++m_refCount;
@@ -1244,6 +1151,7 @@ void CSSComputedStyleDeclaration::deref()
if (!--m_refCount)
delete this;
}
+#endif
String CSSComputedStyleDeclaration::cssText() const
{
@@ -1274,16 +1182,16 @@ static CSSValueID cssIdentifierForFontSizeKeyword(int keywordSize)
return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1);
}
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
{
if (!m_node)
- return 0;
+ return nullptr;
m_node->document().updateLayoutIgnorePendingStylesheets();
RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
if (!style)
- return 0;
+ return nullptr;
if (int keywordSize = style->fontDescription().keywordSize())
return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
@@ -1304,34 +1212,29 @@ bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
return style->fontDescription().useFixedDefaultSize();
}
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowData(const ShadowData& shadow, const RenderStyle& style, bool useSpread) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowData(const ShadowData& shadow, const RenderStyle& style, bool useSpread) const
{
- RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(shadow.x(), style);
- RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(shadow.y(), style);
- RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(shadow.blur(), style);
- RefPtr<CSSPrimitiveValue> spread = useSpread ? zoomAdjustedPixelValue(shadow.spread(), style) : PassRefPtr<CSSPrimitiveValue>();
- RefPtr<CSSPrimitiveValue> shadowStyle = shadow.style() == Normal ? PassRefPtr<CSSPrimitiveValue>() : cssValuePool().createIdentifierValue(CSSValueInset);
- RefPtr<CSSPrimitiveValue> color = currentColorOrValidColor(style, shadow.color());
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(shadow.x(), style);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(shadow.y(), style);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(shadow.blur(), style);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> spread = useSpread ? zoomAdjustedPixelValue(shadow.spread(), style) : PassRefPtrWillBeRawPtr<CSSPrimitiveValue>(nullptr);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> shadowStyle = shadow.style() == Normal ? PassRefPtrWillBeRawPtr<CSSPrimitiveValue>(nullptr) : cssValuePool().createIdentifierValue(CSSValueInset);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> color = currentColorOrValidColor(style, shadow.color());
return CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), shadowStyle.release(), color.release());
}
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowList(const ShadowList* shadowList, const RenderStyle& style, bool useSpread) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowList(const ShadowList* shadowList, const RenderStyle& style, bool useSpread) const
{
if (!shadowList)
return cssValuePool().createIdentifierValue(CSSValueNone);
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
size_t shadowCount = shadowList->shadows().size();
for (size_t i = 0; i < shadowCount; ++i)
list->append(valueForShadowData(shadowList->shadows()[i], style, useSpread));
return list.release();
}
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const
-{
- return getPropertyCSSValue(propertyID, UpdateLayout);
-}
-
static CSSValueID identifierForFamily(const AtomicString& family)
{
if (family == FontFamilyNames::webkit_cursive)
@@ -1349,17 +1252,17 @@ static CSSValueID identifierForFamily(const AtomicString& family)
return CSSValueInvalid;
}
-static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
{
if (CSSValueID familyIdentifier = identifierForFamily(family))
return cssValuePool().createIdentifierValue(familyIdentifier);
return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING);
}
-static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
+static PassRefPtrWillBeRawPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
{
// Blink value is ignored.
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (textDecoration & TextDecorationUnderline)
list->append(cssValuePool().createIdentifierValue(CSSValueUnderline));
if (textDecoration & TextDecorationOverline)
@@ -1372,7 +1275,7 @@ static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecorati
return list.release();
}
-static PassRefPtr<CSSValue> valueForTextDecorationStyle(TextDecorationStyle textDecorationStyle)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForTextDecorationStyle(TextDecorationStyle textDecorationStyle)
{
switch (textDecorationStyle) {
case TextDecorationStyleSolid:
@@ -1391,7 +1294,7 @@ static PassRefPtr<CSSValue> valueForTextDecorationStyle(TextDecorationStyle text
return cssValuePool().createExplicitInitialValue();
}
-static PassRefPtr<CSSValue> valueForFillRepeat(EFillRepeat xRepeat, EFillRepeat yRepeat)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForFillRepeat(EFillRepeat xRepeat, EFillRepeat yRepeat)
{
// For backwards compatibility, if both values are equal, just return one of them. And
// if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
@@ -1402,13 +1305,13 @@ static PassRefPtr<CSSValue> valueForFillRepeat(EFillRepeat xRepeat, EFillRepeat
if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
return cssValuePool().createIdentifierValue(CSSValueRepeatY);
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
list->append(cssValuePool().createValue(xRepeat));
list->append(cssValuePool().createValue(yRepeat));
return list.release();
}
-static PassRefPtr<CSSValue> valueForFillSourceType(EMaskSourceType type)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForFillSourceType(EMaskSourceType type)
{
switch (type) {
case MaskAlpha:
@@ -1419,10 +1322,10 @@ static PassRefPtr<CSSValue> valueForFillSourceType(EMaskSourceType type)
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
-static PassRefPtr<CSSValue> valueForFillSize(const FillSize& fillSize, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForFillSize(const FillSize& fillSize, const RenderStyle& style)
{
if (fillSize.type == Contain)
return cssValuePool().createIdentifierValue(CSSValueContain);
@@ -1433,15 +1336,15 @@ static PassRefPtr<CSSValue> valueForFillSize(const FillSize& fillSize, const Ren
if (fillSize.size.height().isAuto())
return zoomAdjustedPixelValueForLength(fillSize.size.width(), style);
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
list->append(zoomAdjustedPixelValueForLength(fillSize.size.width(), style));
list->append(zoomAdjustedPixelValueForLength(fillSize.size.height(), style));
return list.release();
}
-static PassRefPtr<CSSValue> valueForContentData(const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForContentData(const RenderStyle& style)
{
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
for (const ContentData* contentData = style.contentData(); contentData; contentData = contentData->next()) {
if (contentData->isCounter()) {
const CounterContent* counter = static_cast<const CounterContentData*>(contentData)->counter();
@@ -1454,18 +1357,16 @@ static PassRefPtr<CSSValue> valueForContentData(const RenderStyle& style)
} else if (contentData->isText())
list->append(cssValuePool().createValue(static_cast<const TextContentData*>(contentData)->text(), CSSPrimitiveValue::CSS_STRING));
}
- if (style.hasFlowFrom())
- list->append(cssValuePool().createValue(style.regionThread(), CSSPrimitiveValue::CSS_STRING));
return list.release();
}
-static PassRefPtr<CSSValue> valueForCounterDirectives(const RenderStyle& style, CSSPropertyID propertyID)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForCounterDirectives(const RenderStyle& style, CSSPropertyID propertyID)
{
const CounterDirectiveMap* map = style.counterDirectives();
if (!map)
- return 0;
+ return nullptr;
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
list->append(cssValuePool().createValue(it->key, CSSPrimitiveValue::CSS_STRING));
short number = propertyID == CSSPropertyCounterIncrement ? it->value.incrementValue() : it->value.resetValue();
@@ -1483,44 +1384,44 @@ static void logUnimplementedPropertyID(CSSPropertyID propertyID)
WTF_LOG_ERROR("WebKit does not yet implement getComputedStyle for '%s'.", getPropertyName(propertyID));
}
-static PassRefPtr<CSSValueList> valueForFontFamily(RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValueList> valueForFontFamily(RenderStyle& style)
{
const FontFamily& firstFamily = style.fontDescription().family();
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FontFamily* family = &firstFamily; family; family = family->next())
list->append(valueForFamily(family->family()));
return list.release();
}
-static PassRefPtr<CSSPrimitiveValue> valueForLineHeight(RenderStyle& style, RenderView* renderView)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForLineHeight(RenderStyle& style)
{
Length length = style.lineHeight();
if (length.isNegative())
return cssValuePool().createIdentifierValue(CSSValueNormal);
- return zoomAdjustedPixelValue(floatValueForLength(length, style.fontDescription().specifiedSize(), renderView), style);
+ return zoomAdjustedPixelValue(floatValueForLength(length, style.fontDescription().specifiedSize()), style);
}
-static PassRefPtr<CSSPrimitiveValue> valueForFontSize(RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontSize(RenderStyle& style)
{
return zoomAdjustedPixelValue(style.fontDescription().computedPixelSize(), style);
}
-static PassRefPtr<CSSPrimitiveValue> valueForFontStyle(RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontStyle(RenderStyle& style)
{
- if (style.fontDescription().italic())
+ if (style.fontDescription().style() == FontStyleItalic)
return cssValuePool().createIdentifierValue(CSSValueItalic);
return cssValuePool().createIdentifierValue(CSSValueNormal);
}
-static PassRefPtr<CSSPrimitiveValue> valueForFontVariant(RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontVariant(RenderStyle& style)
{
- if (style.fontDescription().smallCaps())
+ if (style.fontDescription().variant() == FontVariantSmallCaps)
return cssValuePool().createIdentifierValue(CSSValueSmallCaps);
return cssValuePool().createIdentifierValue(CSSValueNormal);
}
-static PassRefPtr<CSSPrimitiveValue> valueForFontWeight(RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontWeight(RenderStyle& style)
{
switch (style.fontDescription().weight()) {
case FontWeight100:
@@ -1546,20 +1447,44 @@ static PassRefPtr<CSSPrimitiveValue> valueForFontWeight(RenderStyle& style)
return cssValuePool().createIdentifierValue(CSSValueNormal);
}
-static PassRefPtr<CSSValue> touchActionFlagsToCSSValue(TouchAction touchAction)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForShape(const RenderStyle& style, ShapeValue* shapeValue)
+{
+ if (!shapeValue)
+ return cssValuePool().createIdentifierValue(CSSValueNone);
+ if (shapeValue->type() == ShapeValue::Box)
+ return cssValuePool().createValue(shapeValue->cssBox());
+ if (shapeValue->type() == ShapeValue::Image) {
+ if (shapeValue->image())
+ return shapeValue->image()->cssValue();
+ return cssValuePool().createIdentifierValue(CSSValueNone);
+ }
+
+ ASSERT(shapeValue->type() == ShapeValue::Shape);
+
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ list->append(valueForBasicShape(style, shapeValue->shape()));
+ if (shapeValue->cssBox() != BoxMissing)
+ list->append(cssValuePool().createValue(shapeValue->cssBox()));
+ return list.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> touchActionFlagsToCSSValue(TouchAction touchAction)
{
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (touchAction == TouchActionAuto)
list->append(cssValuePool().createIdentifierValue(CSSValueAuto));
if (touchAction & TouchActionNone) {
ASSERT(touchAction == TouchActionNone);
list->append(cssValuePool().createIdentifierValue(CSSValueNone));
}
- if (touchAction & TouchActionPanX)
- list->append(cssValuePool().createIdentifierValue(CSSValuePanX));
- if (touchAction & TouchActionPanY)
- list->append(cssValuePool().createIdentifierValue(CSSValuePanY));
-
+ if (touchAction == (TouchActionPanX | TouchActionPanY | TouchActionPinchZoom)) {
+ list->append(cssValuePool().createIdentifierValue(CSSValueManipulation));
+ } else {
+ if (touchAction & TouchActionPanX)
+ list->append(cssValuePool().createIdentifierValue(CSSValuePanX));
+ if (touchAction & TouchActionPanY)
+ list->append(cssValuePool().createIdentifierValue(CSSValuePanY));
+ }
ASSERT(list->length());
return list.release();
}
@@ -1573,14 +1498,17 @@ static bool isLayoutDependent(CSSPropertyID propertyID, PassRefPtr<RenderStyle>
// FIXME: Some of these cases could be narrowed down or optimized better.
switch (propertyID) {
case CSSPropertyBottom:
- case CSSPropertyGridDefinitionColumns:
- case CSSPropertyGridDefinitionRows:
+ case CSSPropertyGridTemplateColumns:
+ case CSSPropertyGridTemplateRows:
case CSSPropertyHeight:
case CSSPropertyLeft:
case CSSPropertyRight:
case CSSPropertyTop:
+ case CSSPropertyPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOrigin:
+ case CSSPropertyTransform:
case CSSPropertyWebkitTransform:
+ case CSSPropertyTransformOrigin:
case CSSPropertyWebkitTransformOrigin:
case CSSPropertyWidth:
case CSSPropertyWebkitFilter:
@@ -1614,16 +1542,6 @@ PassRefPtr<RenderStyle> CSSComputedStyleDeclaration::computeRenderStyle(CSSPrope
{
Node* styledNode = this->styledNode();
ASSERT(styledNode);
- RenderObject* renderer = styledNode->renderer();
- if (renderer && renderer->compositingState() == PaintsIntoOwnBacking
- && !RuntimeEnabledFeatures::webAnimationsCSSEnabled() && AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
- AnimationUpdateBlock animationUpdateBlock(renderer->animation());
- if (m_pseudoElementSpecifier && !styledNode->isPseudoElement()) {
- // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
- return renderer->animation().getAnimatedStyleForRenderer(renderer)->getCachedPseudoStyle(m_pseudoElementSpecifier);
- }
- return renderer->animation().getAnimatedStyleForRenderer(renderer);
- }
return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
}
@@ -1638,22 +1556,30 @@ Node* CSSComputedStyleDeclaration::styledNode() const
return m_node.get();
}
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
+static PassRefPtrWillBeRawPtr<CSSValueList> valueForItemPositionWithOverflowAlignment(ItemPosition itemPosition, OverflowAlignment overflowAlignment)
+{
+ RefPtrWillBeRawPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
+ result->append(CSSPrimitiveValue::create(itemPosition));
+ if (itemPosition >= ItemPositionCenter && overflowAlignment != OverflowAlignmentDefault)
+ result->append(CSSPrimitiveValue::create(overflowAlignment));
+ return result.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
{
Node* styledNode = this->styledNode();
if (!styledNode)
- return 0;
+ return nullptr;
RenderObject* renderer = styledNode->renderer();
RefPtr<RenderStyle> style;
if (updateLayout) {
Document& document = styledNode->document();
- // If a compositor animation is running we may need to service animations
- // in order to generate an up to date value.
- DocumentAnimations::serviceBeforeGetComputedStyle(*styledNode, propertyID);
+ // A timing update may be required if a compositor animation is running.
+ DocumentAnimations::updateAnimationTimingForGetComputedStyle(*styledNode, propertyID);
- document.updateStyleForNodeIfNeeded(styledNode);
+ document.updateRenderTreeForNodeIfNeeded(styledNode);
// The style recalc could have caused the styled node to be discarded or replaced
// if it was a PseudoElement so we need to update it.
@@ -1664,8 +1590,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
bool forceFullLayout = isLayoutDependent(propertyID, style, renderer)
|| styledNode->isInShadowTree()
- || (document.ownerElement() && document.ensureStyleResolver().hasViewportDependentMediaQueries())
- || document.seamlessParentIFrame();
+ || (document.ownerElement() && document.ensureStyleResolver().hasViewportDependentMediaQueries());
if (forceFullLayout) {
document.updateLayoutIgnorePendingStylesheets();
@@ -1678,17 +1603,16 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
}
if (!style)
- return 0;
+ return nullptr;
propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
switch (propertyID) {
case CSSPropertyInvalid:
- case CSSPropertyVariable:
break;
case CSSPropertyBackgroundColor:
- return cssValuePool().createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
+ return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyBackgroundColor).rgb()) : currentColorOrValidColor(*style, style->backgroundColor());
case CSSPropertyBackgroundImage:
case CSSPropertyWebkitMaskImage: {
const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
@@ -1702,7 +1626,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return cssValuePool().createIdentifierValue(CSSValueNone);
}
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
if (currLayer->image())
list->append(currLayer->image()->cssValue());
@@ -1718,7 +1642,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (!layers->next())
return valueForFillSize(layers->size(), *style);
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
list->append(valueForFillSize(currLayer->size(), *style));
@@ -1730,7 +1654,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (!layers->next())
return valueForFillRepeat(layers->repeatX(), layers->repeatY());
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
list->append(valueForFillRepeat(currLayer->repeatX(), currLayer->repeatY()));
@@ -1745,7 +1669,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (!layers->next())
return valueForFillSourceType(layers->maskSourceType());
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
list->append(valueForFillSourceType(currLayer->maskSourceType()));
@@ -1757,7 +1681,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (!layers->next())
return cssValuePool().createValue(layers->composite());
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
list->append(cssValuePool().createValue(currLayer->composite()));
@@ -1768,7 +1692,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (!layers->next())
return cssValuePool().createValue(layers->attachment());
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
list->append(cssValuePool().createValue(currLayer->attachment()));
@@ -1787,7 +1711,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return cssValuePool().createValue(box);
}
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
list->append(cssValuePool().createValue(box));
@@ -1801,7 +1725,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (!layers->next())
return createPositionListForLayer(propertyID, layers, *style);
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
list->append(createPositionListForLayer(propertyID, currLayer, *style));
return list.release();
@@ -1810,11 +1734,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyWebkitMaskPositionX: {
const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
if (!layers->next())
- return cssValuePool().createValue(layers->xPosition());
+ return zoomAdjustedPixelValueForLength(layers->xPosition(), *style);
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
- list->append(cssValuePool().createValue(currLayer->xPosition()));
+ list->append(zoomAdjustedPixelValueForLength(currLayer->xPosition(), *style));
return list.release();
}
@@ -1822,11 +1746,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyWebkitMaskPositionY: {
const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
if (!layers->next())
- return cssValuePool().createValue(layers->yPosition());
+ return zoomAdjustedPixelValueForLength(layers->yPosition(), *style);
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
- list->append(cssValuePool().createValue(currLayer->yPosition()));
+ list->append(zoomAdjustedPixelValueForLength(currLayer->yPosition(), *style));
return list.release();
}
@@ -1835,7 +1759,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return cssValuePool().createIdentifierValue(CSSValueCollapse);
return cssValuePool().createIdentifierValue(CSSValueSeparate);
case CSSPropertyBorderSpacing: {
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), *style));
list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), *style));
return list.release();
@@ -1873,7 +1797,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyBorderLeftWidth:
return zoomAdjustedPixelValue(style->borderLeftWidth(), *style);
case CSSPropertyBottom:
- return valueForPositionOffset(*style, CSSPropertyBottom, renderer, m_node->document().renderView());
+ return valueForPositionOffset(*style, CSSPropertyBottom, renderer);
case CSSPropertyWebkitBoxAlign:
return cssValuePool().createValue(style->boxAlign());
case CSSPropertyWebkitBoxDecorationBreak:
@@ -1907,8 +1831,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return cssValuePool().createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
case CSSPropertyWebkitPrintColorAdjust:
return cssValuePool().createValue(style->printColorAdjust());
- case CSSPropertyWebkitColumnAxis:
- return cssValuePool().createValue(style->columnAxis());
case CSSPropertyWebkitColumnCount:
if (style->hasAutoColumnCount())
return cssValuePool().createIdentifierValue(CSSValueAuto);
@@ -1916,13 +1838,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyColumnFill:
if (RuntimeEnabledFeatures::regionBasedColumnsEnabled())
return cssValuePool().createValue(style->columnFill());
- return 0;
+ return nullptr;
case CSSPropertyWebkitColumnGap:
if (style->hasNormalColumnGap())
return cssValuePool().createIdentifierValue(CSSValueNormal);
return zoomAdjustedPixelValue(style->columnGap(), *style);
- case CSSPropertyWebkitColumnProgression:
- return cssValuePool().createValue(style->columnProgression());
case CSSPropertyWebkitColumnRuleColor:
return m_allowVisitedStyle ? cssValuePool().createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(*style, style->columnRuleColor());
case CSSPropertyWebkitColumnRuleStyle:
@@ -1943,14 +1863,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return zoomAdjustedPixelValue(style->columnWidth(), *style);
case CSSPropertyTabSize:
return cssValuePool().createValue(style->tabSize(), CSSPrimitiveValue::CSS_NUMBER);
- case CSSPropertyWebkitRegionBreakAfter:
- return cssValuePool().createValue(style->regionBreakAfter());
- case CSSPropertyWebkitRegionBreakBefore:
- return cssValuePool().createValue(style->regionBreakBefore());
- case CSSPropertyWebkitRegionBreakInside:
- return cssValuePool().createValue(style->regionBreakInside());
case CSSPropertyCursor: {
- RefPtr<CSSValueList> list;
+ RefPtrWillBeRawPtr<CSSValueList> list = nullptr;
CursorList* cursors = style->cursors();
if (cursors && cursors->size() > 0) {
list = CSSValueList::createCommaSeparated();
@@ -1958,7 +1872,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (StyleImage* image = cursors->at(i).image())
list->append(image->cssValue());
}
- RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
+ RefPtrWillBeRawPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
if (list) {
list->append(value.release());
return list.release();
@@ -1974,19 +1888,22 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyAlignContent:
return cssValuePool().createValue(style->alignContent());
case CSSPropertyAlignItems:
- return cssValuePool().createValue(style->alignItems());
- case CSSPropertyAlignSelf:
- if (style->alignSelf() == AlignAuto) {
+ return valueForItemPositionWithOverflowAlignment(style->alignItems(), style->alignItemsOverflowAlignment());
+ case CSSPropertyAlignSelf: {
+ ItemPosition alignSelf = style->alignSelf();
+ if (alignSelf == ItemPositionAuto) {
Node* parent = styledNode->parentNode();
if (parent && parent->computedStyle())
- return cssValuePool().createValue(parent->computedStyle()->alignItems());
- return cssValuePool().createValue(AlignStretch);
+ alignSelf = parent->computedStyle()->alignItems();
+ else
+ alignSelf = ItemPositionStretch;
}
- return cssValuePool().createValue(style->alignSelf());
+ return valueForItemPositionWithOverflowAlignment(alignSelf, style->alignSelfOverflowAlignment());
+ }
case CSSPropertyFlex:
return valuesForShorthandProperty(flexShorthand());
case CSSPropertyFlexBasis:
- return cssValuePool().createValue(style->flexBasis());
+ return zoomAdjustedPixelValueForLength(style->flexBasis(), *style);
case CSSPropertyFlexDirection:
return cssValuePool().createValue(style->flexDirection());
case CSSPropertyFlexFlow:
@@ -2006,17 +1923,17 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return cssValuePool().createIdentifierValue(CSSValueNone);
return cssValuePool().createValue(style->floating());
case CSSPropertyFont: {
- RefPtr<CSSFontValue> computedFont = CSSFontValue::create();
+ RefPtrWillBeRawPtr<CSSFontValue> computedFont = CSSFontValue::create();
computedFont->style = valueForFontStyle(*style);
computedFont->variant = valueForFontVariant(*style);
computedFont->weight = valueForFontWeight(*style);
computedFont->size = valueForFontSize(*style);
- computedFont->lineHeight = valueForLineHeight(*style, m_node->document().renderView());
+ computedFont->lineHeight = valueForLineHeight(*style);
computedFont->family = valueForFontFamily(*style);
return computedFont.release();
}
case CSSPropertyFontFamily: {
- RefPtr<CSSValueList> fontFamilyList = valueForFontFamily(*style);
+ RefPtrWillBeRawPtr<CSSValueList> fontFamilyList = valueForFontFamily(*style);
// If there's only a single family, return that as a CSSPrimitiveValue.
// NOTE: Gecko always returns this as a comma-separated CSSPrimitiveValue string.
if (fontFamilyList->length() == 1)
@@ -2035,10 +1952,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
const FontFeatureSettings* featureSettings = style->fontDescription().featureSettings();
if (!featureSettings || !featureSettings->size())
return cssValuePool().createIdentifierValue(CSSValueNormal);
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (unsigned i = 0; i < featureSettings->size(); ++i) {
const FontFeature& feature = featureSettings->at(i);
- RefPtr<CSSFontFeatureValue> featureValue = CSSFontFeatureValue::create(feature.tag(), feature.value());
+ RefPtrWillBeRawPtr<CSSFontFeatureValue> featureValue = CSSFontFeatureValue::create(feature.tag(), feature.value());
list->append(featureValue.release());
}
return list.release();
@@ -2052,14 +1969,14 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
// depending on the size of the explicit grid or the number of implicit tracks added to the grid. See
// http://lists.w3.org/Archives/Public/www-style/2013Nov/0014.html
case CSSPropertyGridAutoColumns:
- return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style, m_node->document().renderView());
+ return specifiedValueForGridTrackSize(style->gridAutoColumns(), *style);
case CSSPropertyGridAutoRows:
- return specifiedValueForGridTrackSize(style->gridAutoRows(), *style, m_node->document().renderView());
+ return specifiedValueForGridTrackSize(style->gridAutoRows(), *style);
- case CSSPropertyGridDefinitionColumns:
- return valueForGridTrackList(ForColumns, renderer, *style, m_node->document().renderView());
- case CSSPropertyGridDefinitionRows:
- return valueForGridTrackList(ForRows, renderer, *style, m_node->document().renderView());
+ case CSSPropertyGridTemplateColumns:
+ return valueForGridTrackList(ForColumns, renderer, *style);
+ case CSSPropertyGridTemplateRows:
+ return valueForGridTrackList(ForRows, renderer, *style);
case CSSPropertyGridColumnStart:
return valueForGridPosition(style->gridColumnStart());
@@ -2075,14 +1992,17 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return valuesForGridShorthand(gridRowShorthand());
case CSSPropertyGridArea:
return valuesForGridShorthand(gridAreaShorthand());
-
case CSSPropertyGridTemplate:
+ return valuesForGridShorthand(gridTemplateShorthand());
+ case CSSPropertyGrid:
+ return valuesForGridShorthand(gridShorthand());
+ case CSSPropertyGridTemplateAreas:
if (!style->namedGridAreaRowCount()) {
ASSERT(!style->namedGridAreaColumnCount());
return cssValuePool().createIdentifierValue(CSSValueNone);
}
- return CSSGridTemplateValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
+ return CSSGridTemplateAreasValue::create(style->namedGridArea(), style->namedGridAreaRowCount(), style->namedGridAreaColumnCount());
case CSSPropertyHeight:
if (renderer) {
@@ -2109,8 +2029,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return CSSPrimitiveValue::create(style->imageRendering());
case CSSPropertyIsolation:
return cssValuePool().createValue(style->isolation());
+ case CSSPropertyJustifySelf:
+ return valueForItemPositionWithOverflowAlignment(style->justifySelf(), style->justifySelfOverflowAlignment());
case CSSPropertyLeft:
- return valueForPositionOffset(*style, CSSPropertyLeft, renderer, m_node->document().renderView());
+ return valueForPositionOffset(*style, CSSPropertyLeft, renderer);
case CSSPropertyLetterSpacing:
if (!style->letterSpacing())
return cssValuePool().createIdentifierValue(CSSValueNormal);
@@ -2120,7 +2042,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return cssValuePool().createIdentifierValue(CSSValueNone);
return cssValuePool().createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
case CSSPropertyLineHeight:
- return valueForLineHeight(*style, m_node->document().renderView());
+ return valueForLineHeight(*style);
case CSSPropertyListStyleImage:
if (style->listStyleImage())
return style->listStyleImage()->cssValue();
@@ -2144,13 +2066,13 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (marginRight.isFixed() || !renderer || !renderer->isBox())
return zoomAdjustedPixelValueForLength(marginRight, *style);
float value;
- if (marginRight.isPercent() || marginRight.isViewportPercentage()) {
+ if (marginRight.isPercent()) {
// RenderBox gives a marginRight() that is the distance between the right-edge of the child box
// and the right-edge of the containing box, when display == BLOCK. Let's calculate the absolute
// value of the specified margin-right % instead of relying on RenderBox's marginRight() value.
- value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent(), m_node->document().renderView());
+ value = minimumValueForLength(marginRight, toRenderBox(renderer)->containingBlockLogicalWidthForContent()).toFloat();
} else {
- value = toRenderBox(renderer)->marginRight();
+ value = toRenderBox(renderer)->marginRight().toFloat();
}
return zoomAdjustedPixelValue(value, *style);
}
@@ -2254,15 +2176,17 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
EPageBreak pageBreak = style->pageBreakInside();
ASSERT(pageBreak != PBALWAYS);
if (pageBreak == PBALWAYS)
- return 0;
+ return nullptr;
return cssValuePool().createValue(style->pageBreakInside());
}
case CSSPropertyPosition:
return cssValuePool().createValue(style->position());
case CSSPropertyRight:
- return valueForPositionOffset(*style, CSSPropertyRight, renderer, m_node->document().renderView());
+ return valueForPositionOffset(*style, CSSPropertyRight, renderer);
case CSSPropertyWebkitRubyPosition:
return cssValuePool().createValue(style->rubyPosition());
+ case CSSPropertyScrollBehavior:
+ return cssValuePool().createValue(style->scrollBehavior());
case CSSPropertyTableLayout:
return cssValuePool().createValue(style->tableLayout());
case CSSPropertyTextAlign:
@@ -2270,7 +2194,9 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyTextAlignLast:
return cssValuePool().createValue(style->textAlignLast());
case CSSPropertyTextDecoration:
- return valuesForShorthandProperty(textDecorationShorthand());
+ if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
+ return valuesForShorthandProperty(textDecorationShorthand());
+ // Fall through.
case CSSPropertyTextDecorationLine:
return renderTextDecorationFlagsToCSSValue(style->textDecoration());
case CSSPropertyTextDecorationStyle:
@@ -2303,18 +2229,25 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case TextEmphasisMarkDoubleCircle:
case TextEmphasisMarkTriangle:
case TextEmphasisMarkSesame: {
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
list->append(cssValuePool().createValue(style->textEmphasisFill()));
list->append(cssValuePool().createValue(style->textEmphasisMark()));
return list.release();
}
}
case CSSPropertyTextIndent: {
- RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
- if (RuntimeEnabledFeatures::css3TextEnabled() && style->textIndentLine() == TextIndentEachLine) {
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ // If RuntimeEnabledFeatures::css3TextEnabled() returns false or text-indent has only one value(<length> | <percentage>),
+ // getPropertyCSSValue() returns CSSValue.
+ // If RuntimeEnabledFeatures::css3TextEnabled() returns true and text-indent has each-line or hanging,
+ // getPropertyCSSValue() returns CSSValueList.
+ RefPtrWillBeRawPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
+ if (RuntimeEnabledFeatures::css3TextEnabled() && (style->textIndentLine() == TextIndentEachLine || style->textIndentType() == TextIndentHanging)) {
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
list->append(textIndent.release());
- list->append(cssValuePool().createIdentifierValue(CSSValueEachLine));
+ if (style->textIndentLine() == TextIndentEachLine)
+ list->append(cssValuePool().createIdentifierValue(CSSValueEachLine));
+ if (style->textIndentType() == TextIndentHanging)
+ list->append(cssValuePool().createIdentifierValue(CSSValueHanging));
return list.release();
}
return textIndent.release();
@@ -2322,7 +2255,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyTextShadow:
return valueForShadowList(style->textShadow(), *style, false);
case CSSPropertyTextRendering:
- return cssValuePool().createValue(style->fontDescription().textRenderingMode());
+ return cssValuePool().createValue(style->fontDescription().textRendering());
case CSSPropertyTextOverflow:
if (style->textOverflow())
return cssValuePool().createIdentifierValue(CSSValueEllipsis);
@@ -2336,7 +2269,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyTextTransform:
return cssValuePool().createValue(style->textTransform());
case CSSPropertyTop:
- return valueForPositionOffset(*style, CSSPropertyTop, renderer, m_node->document().renderView());
+ return valueForPositionOffset(*style, CSSPropertyTop, renderer);
case CSSPropertyTouchAction:
return touchActionFlagsToCSSValue(style->touchAction());
case CSSPropertyTouchActionDelay:
@@ -2364,10 +2297,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case BASELINE_MIDDLE:
return cssValuePool().createIdentifierValue(CSSValueWebkitBaselineMiddle);
case LENGTH:
- return cssValuePool().createValue(style->verticalAlignLength());
+ return zoomAdjustedPixelValueForLength(style->verticalAlignLength(), *style);
}
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
case CSSPropertyVisibility:
return cssValuePool().createValue(style->visibility());
case CSSPropertyWhiteSpace:
@@ -2385,6 +2318,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return zoomAdjustedPixelValue(sizingBox(renderer).width(), *style);
}
return zoomAdjustedPixelValueForLength(style->width(), *style);
+ case CSSPropertyWillChange:
+ return valueForWillChange(style->willChangeProperties(), style->willChangeContents(), style->willChangeScrollPosition());
case CSSPropertyWordBreak:
return cssValuePool().createValue(style->wordBreak());
case CSSPropertyWordSpacing:
@@ -2399,21 +2334,24 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return cssValuePool().createValue(style->fontDescription().kerning());
case CSSPropertyWebkitFontSmoothing:
return cssValuePool().createValue(style->fontDescription().fontSmoothing());
- case CSSPropertyWebkitFontVariantLigatures: {
+ case CSSPropertyFontVariantLigatures: {
FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
+ FontDescription::LigaturesState contextualLigaturesState = style->fontDescription().contextualLigaturesState();
if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
- && historicalLigaturesState == FontDescription::NormalLigaturesState)
+ && historicalLigaturesState == FontDescription::NormalLigaturesState && contextualLigaturesState == FontDescription::NormalLigaturesState)
return cssValuePool().createIdentifierValue(CSSValueNormal);
- RefPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
if (commonLigaturesState != FontDescription::NormalLigaturesState)
valueList->append(cssValuePool().createIdentifierValue(commonLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
if (discretionaryLigaturesState != FontDescription::NormalLigaturesState)
valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
if (historicalLigaturesState != FontDescription::NormalLigaturesState)
valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
+ if (contextualLigaturesState != FontDescription::NormalLigaturesState)
+ valueList->append(cssValuePool().createIdentifierValue(contextualLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoContextual : CSSValueContextual));
return valueList;
}
case CSSPropertyZIndex:
@@ -2435,13 +2373,14 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyAnimationDirection:
ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
case CSSPropertyWebkitAnimationDirection: {
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- const CSSAnimationDataList* t = style->animations();
- if (t) {
- for (size_t i = 0; i < t->size(); ++i)
- list->append(valueForAnimationDirection(t->animation(i)->direction()));
- } else
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ const CSSAnimationData* animationData = style->animations();
+ if (animationData) {
+ for (size_t i = 0; i < animationData->directionList().size(); ++i)
+ list->append(valueForAnimationDirection(animationData->directionList()[i]));
+ } else {
list->append(cssValuePool().createIdentifierValue(CSSValueNormal));
+ }
return list.release();
}
case CSSPropertyAnimationDuration:
@@ -2451,59 +2390,53 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyAnimationFillMode:
ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
case CSSPropertyWebkitAnimationFillMode: {
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- const CSSAnimationDataList* t = style->animations();
- if (t) {
- for (size_t i = 0; i < t->size(); ++i)
- list->append(valueForAnimationFillMode(t->animation(i)->fillMode()));
- } else
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ const CSSAnimationData* animationData = style->animations();
+ if (animationData) {
+ for (size_t i = 0; i < animationData->fillModeList().size(); ++i)
+ list->append(valueForAnimationFillMode(animationData->fillModeList()[i]));
+ } else {
list->append(cssValuePool().createIdentifierValue(CSSValueNone));
+ }
return list.release();
}
case CSSPropertyAnimationIterationCount:
ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
case CSSPropertyWebkitAnimationIterationCount: {
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- const CSSAnimationDataList* t = style->animations();
- if (t) {
- for (size_t i = 0; i < t->size(); ++i) {
- double iterationCount = t->animation(i)->iterationCount();
- if (iterationCount == CSSAnimationData::IterationCountInfinite)
- list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
- else
- list->append(cssValuePool().createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
- }
- } else
- list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ const CSSAnimationData* animationData = style->animations();
+ if (animationData) {
+ for (size_t i = 0; i < animationData->iterationCountList().size(); ++i)
+ list->append(valueForAnimationIterationCount(animationData->iterationCountList()[i]));
+ } else {
+ list->append(cssValuePool().createValue(CSSAnimationData::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
+ }
return list.release();
}
case CSSPropertyAnimationName:
ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
case CSSPropertyWebkitAnimationName: {
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- const CSSAnimationDataList* t = style->animations();
- if (t) {
- for (size_t i = 0; i < t->size(); ++i)
- list->append(cssValuePool().createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
- } else
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ const CSSAnimationData* animationData = style->animations();
+ if (animationData) {
+ for (size_t i = 0; i < animationData->nameList().size(); ++i)
+ list->append(cssValuePool().createValue(animationData->nameList()[i], CSSPrimitiveValue::CSS_STRING));
+ } else {
list->append(cssValuePool().createIdentifierValue(CSSValueNone));
+ }
return list.release();
}
case CSSPropertyAnimationPlayState:
ASSERT(RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
case CSSPropertyWebkitAnimationPlayState: {
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- const CSSAnimationDataList* t = style->animations();
- if (t) {
- for (size_t i = 0; i < t->size(); ++i) {
- int prop = t->animation(i)->playState();
- if (prop == AnimPlayStatePlaying)
- list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
- else
- list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
- }
- } else
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ const CSSAnimationData* animationData = style->animations();
+ if (animationData) {
+ for (size_t i = 0; i < animationData->playStateList().size(); ++i)
+ list->append(valueForAnimationPlayState(animationData->playStateList()[i]));
+ } else {
list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
+ }
return list.release();
}
case CSSPropertyAnimationTimingFunction:
@@ -2512,40 +2445,33 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return valueForAnimationTimingFunction(style->animations());
case CSSPropertyAnimation:
case CSSPropertyWebkitAnimation: {
- const CSSAnimationDataList* animations = style->animations();
- if (animations) {
- RefPtr<CSSValueList> animationsList = CSSValueList::createCommaSeparated();
- for (size_t i = 0; i < animations->size(); ++i) {
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- const CSSAnimationData* animation = animations->animation(i);
- list->append(cssValuePool().createValue(animation->name(), CSSPrimitiveValue::CSS_STRING));
- list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S));
- list->append(createTimingFunctionValue(animation->timingFunction()));
- list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S));
- if (animation->iterationCount() == CSSAnimationData::IterationCountInfinite)
- list->append(cssValuePool().createIdentifierValue(CSSValueInfinite));
- else
- list->append(cssValuePool().createValue(animation->iterationCount(), CSSPrimitiveValue::CSS_NUMBER));
- list->append(valueForAnimationDirection(animation->direction()));
- list->append(valueForAnimationFillMode(animation->fillMode()));
- if (animation->playState() == AnimPlayStatePaused)
- list->append(cssValuePool().createIdentifierValue(CSSValuePaused));
- else
- list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
+ const CSSAnimationData* animationData = style->animations();
+ if (animationData) {
+ RefPtrWillBeRawPtr<CSSValueList> animationsList = CSSValueList::createCommaSeparated();
+ for (size_t i = 0; i < animationData->nameList().size(); ++i) {
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ list->append(cssValuePool().createValue(animationData->nameList()[i], CSSPrimitiveValue::CSS_STRING));
+ list->append(cssValuePool().createValue(CSSTimingData::getRepeated(animationData->durationList(), i), CSSPrimitiveValue::CSS_S));
+ list->append(createTimingFunctionValue(CSSTimingData::getRepeated(animationData->timingFunctionList(), i).get()));
+ list->append(cssValuePool().createValue(CSSTimingData::getRepeated(animationData->delayList(), i), CSSPrimitiveValue::CSS_S));
+ list->append(valueForAnimationIterationCount(CSSTimingData::getRepeated(animationData->iterationCountList(), i)));
+ list->append(valueForAnimationDirection(CSSTimingData::getRepeated(animationData->directionList(), i)));
+ list->append(valueForAnimationFillMode(CSSTimingData::getRepeated(animationData->fillModeList(), i)));
+ list->append(valueForAnimationPlayState(CSSTimingData::getRepeated(animationData->playStateList(), i)));
animationsList->append(list);
}
return animationsList.release();
}
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
// animation-name default value.
list->append(cssValuePool().createIdentifierValue(CSSValueNone));
- list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
- list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
- list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
- list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
- list->append(valueForAnimationDirection(CSSAnimationData::initialAnimationDirection()));
- list->append(valueForAnimationFillMode(CSSAnimationData::initialAnimationFillMode()));
+ list->append(cssValuePool().createValue(CSSAnimationData::initialDuration(), CSSPrimitiveValue::CSS_S));
+ list->append(createTimingFunctionValue(CSSAnimationData::initialTimingFunction().get()));
+ list->append(cssValuePool().createValue(CSSAnimationData::initialDelay(), CSSPrimitiveValue::CSS_S));
+ list->append(cssValuePool().createValue(CSSAnimationData::initialIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
+ list->append(valueForAnimationDirection(CSSAnimationData::initialDirection()));
+ list->append(valueForAnimationFillMode(CSSAnimationData::initialFillMode()));
// Initial animation-play-state.
list->append(cssValuePool().createIdentifierValue(CSSValueRunning));
return list.release();
@@ -2556,6 +2482,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (!style->hasAspectRatio())
return cssValuePool().createIdentifierValue(CSSValueNone);
return CSSAspectRatioValue::create(style->aspectRatioNumerator(), style->aspectRatioDenominator());
+ case CSSPropertyBackfaceVisibility:
case CSSPropertyWebkitBackfaceVisibility:
return cssValuePool().createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
case CSSPropertyWebkitBorderImage:
@@ -2591,20 +2518,21 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyWebkitMarginTopCollapse:
case CSSPropertyWebkitMarginBeforeCollapse:
return cssValuePool().createValue(style->marginBeforeCollapse());
+ case CSSPropertyPerspective:
case CSSPropertyWebkitPerspective:
if (!style->hasPerspective())
return cssValuePool().createIdentifierValue(CSSValueNone);
return zoomAdjustedPixelValue(style->perspective(), *style);
+ case CSSPropertyPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOrigin: {
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (renderer) {
LayoutRect box;
if (renderer->isBox())
box = toRenderBox(renderer)->borderBoxRect();
- RenderView* renderView = m_node->document().renderView();
- list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width(), renderView), *style));
- list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height(), renderView), *style));
+ list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginX(), box.width()), *style));
+ list->append(zoomAdjustedPixelValue(minimumValueForLength(style->perspectiveOriginY(), box.height()), *style));
}
else {
list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), *style));
@@ -2632,7 +2560,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyClip: {
if (!style->hasClip())
return cssValuePool().createIdentifierValue(CSSValueAuto);
- RefPtr<Rect> rect = Rect::create();
+ RefPtrWillBeRawPtr<Rect> rect = Rect::create();
rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), *style));
rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), *style));
rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), *style));
@@ -2641,18 +2569,19 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
}
case CSSPropertySpeak:
return cssValuePool().createValue(style->speak());
+ case CSSPropertyTransform:
case CSSPropertyWebkitTransform:
return computedTransform(renderer, *style);
+ case CSSPropertyTransformOrigin:
case CSSPropertyWebkitTransformOrigin: {
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
if (renderer) {
LayoutRect box;
if (renderer->isBox())
box = toRenderBox(renderer)->borderBoxRect();
- RenderView* renderView = m_node->document().renderView();
- list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width(), renderView), *style));
- list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height(), renderView), *style));
+ list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginX(), box.width()), *style));
+ list->append(zoomAdjustedPixelValue(minimumValueForLength(style->transformOriginY(), box.height()), *style));
if (style->transformOriginZ() != 0)
list->append(zoomAdjustedPixelValue(style->transformOriginZ(), *style));
} else {
@@ -2663,6 +2592,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
}
return list.release();
}
+ case CSSPropertyTransformStyle:
case CSSPropertyWebkitTransformStyle:
return cssValuePool().createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
case CSSPropertyTransitionDelay:
@@ -2679,39 +2609,30 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return valueForAnimationTimingFunction(style->transitions());
case CSSPropertyTransition:
case CSSPropertyWebkitTransition: {
- const CSSAnimationDataList* animList = style->transitions();
- if (animList) {
- RefPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
- for (size_t i = 0; i < animList->size(); ++i) {
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- const CSSAnimationData* animation = animList->animation(i);
- list->append(createTransitionPropertyValue(animation));
- list->append(cssValuePool().createValue(animation->duration(), CSSPrimitiveValue::CSS_S));
- list->append(createTimingFunctionValue(animation->timingFunction()));
- list->append(cssValuePool().createValue(animation->delay(), CSSPrimitiveValue::CSS_S));
+ const CSSTransitionData* transitionData = style->transitions();
+ if (transitionData) {
+ RefPtrWillBeRawPtr<CSSValueList> transitionsList = CSSValueList::createCommaSeparated();
+ for (size_t i = 0; i < transitionData->propertyList().size(); ++i) {
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ list->append(createTransitionPropertyValue(transitionData->propertyList()[i]));
+ list->append(cssValuePool().createValue(CSSTimingData::getRepeated(transitionData->durationList(), i), CSSPrimitiveValue::CSS_S));
+ list->append(createTimingFunctionValue(CSSTimingData::getRepeated(transitionData->timingFunctionList(), i).get()));
+ list->append(cssValuePool().createValue(CSSTimingData::getRepeated(transitionData->delayList(), i), CSSPrimitiveValue::CSS_S));
transitionsList->append(list);
}
return transitionsList.release();
}
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
// transition-property default value.
list->append(cssValuePool().createIdentifierValue(CSSValueAll));
- list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
- list->append(createTimingFunctionValue(CSSAnimationData::initialAnimationTimingFunction().get()));
- list->append(cssValuePool().createValue(CSSAnimationData::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
+ list->append(cssValuePool().createValue(CSSTransitionData::initialDuration(), CSSPrimitiveValue::CSS_S));
+ list->append(createTimingFunctionValue(CSSTransitionData::initialTimingFunction().get()));
+ list->append(cssValuePool().createValue(CSSTransitionData::initialDelay(), CSSPrimitiveValue::CSS_S));
return list.release();
}
case CSSPropertyPointerEvents:
return cssValuePool().createValue(style->pointerEvents());
- case CSSPropertyWebkitLineGrid:
- if (style->lineGrid().isNull())
- return cssValuePool().createIdentifierValue(CSSValueNone);
- return cssValuePool().createValue(style->lineGrid(), CSSPrimitiveValue::CSS_STRING);
- case CSSPropertyWebkitLineSnap:
- return CSSPrimitiveValue::create(style->lineSnap());
- case CSSPropertyWebkitLineAlign:
- return CSSPrimitiveValue::create(style->lineAlign());
case CSSPropertyWebkitWritingMode:
return cssValuePool().createValue(style->writingMode());
case CSSPropertyWebkitTextCombine:
@@ -2734,50 +2655,14 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
return CSSPrimitiveValue::create(toReferenceClipPathOperation(operation)->url(), CSSPrimitiveValue::CSS_URI);
}
return cssValuePool().createIdentifierValue(CSSValueNone);
- case CSSPropertyWebkitFlowInto:
- if (style->flowThread().isNull())
- return cssValuePool().createIdentifierValue(CSSValueNone);
- return cssValuePool().createValue(style->flowThread(), CSSPrimitiveValue::CSS_STRING);
- case CSSPropertyWebkitFlowFrom:
- if (!style->hasFlowFrom())
- return cssValuePool().createIdentifierValue(CSSValueNone);
- return cssValuePool().createValue(style->regionThread(), CSSPrimitiveValue::CSS_STRING);
- case CSSPropertyWebkitRegionFragment:
- return cssValuePool().createValue(style->regionFragment());
case CSSPropertyWebkitWrapFlow:
return cssValuePool().createValue(style->wrapFlow());
case CSSPropertyShapeMargin:
- return cssValuePool().createValue(style->shapeMargin());
- case CSSPropertyShapePadding:
- return cssValuePool().createValue(style->shapePadding());
+ return cssValuePool().createValue(style->shapeMargin(), *style);
case CSSPropertyShapeImageThreshold:
return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
- case CSSPropertyShapeInside:
- if (!style->shapeInside())
- return cssValuePool().createIdentifierValue(CSSValueAuto);
- if (style->shapeInside()->type() == ShapeValue::Box)
- return cssValuePool().createValue(style->shapeInside()->layoutBox());
- if (style->shapeInside()->type() == ShapeValue::Outside)
- return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
- if (style->shapeInside()->type() == ShapeValue::Image) {
- if (style->shapeInside()->image())
- return style->shapeInside()->image()->cssValue();
- return cssValuePool().createIdentifierValue(CSSValueNone);
- }
- ASSERT(style->shapeInside()->type() == ShapeValue::Shape);
- return valueForBasicShape(*style, style->shapeInside()->shape());
case CSSPropertyShapeOutside:
- if (!style->shapeOutside())
- return cssValuePool().createIdentifierValue(CSSValueAuto);
- if (style->shapeOutside()->type() == ShapeValue::Box)
- return cssValuePool().createValue(style->shapeOutside()->layoutBox());
- if (style->shapeOutside()->type() == ShapeValue::Image) {
- if (style->shapeOutside()->image())
- return style->shapeOutside()->image()->cssValue();
- return cssValuePool().createIdentifierValue(CSSValueNone);
- }
- ASSERT(style->shapeOutside()->type() == ShapeValue::Shape);
- return valueForBasicShape(*style, style->shapeOutside()->shape());
+ return valueForShape(*style, style->shapeOutside());
case CSSPropertyWebkitWrapThrough:
return cssValuePool().createValue(style->wrapThrough());
case CSSPropertyWebkitFilter:
@@ -2790,7 +2675,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
if (!layers->next())
return cssValuePool().createValue(layers->blendMode());
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
list->append(cssValuePool().createValue(currLayer->blendMode()));
@@ -2799,12 +2684,12 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyBackground:
return valuesForBackgroundShorthand();
case CSSPropertyBorder: {
- RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom,
CSSPropertyBorderLeft };
for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout)))
- return 0;
+ return nullptr;
}
return value.release();
}
@@ -2844,7 +2729,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
break;
case CSSPropertyInternalCallback:
// This property is hidden from the web.
- return 0;
+ return nullptr;
/* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
case CSSPropertyWebkitTextEmphasis:
@@ -2936,7 +2821,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyInternalMarqueeSpeed:
case CSSPropertyInternalMarqueeStyle:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
case CSSPropertyBufferedRendering:
case CSSPropertyClipPath:
@@ -2951,7 +2836,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyStopOpacity:
case CSSPropertyColorInterpolation:
case CSSPropertyColorInterpolationFilters:
- case CSSPropertyColorProfile:
case CSSPropertyColorRendering:
case CSSPropertyFill:
case CSSPropertyFillOpacity:
@@ -2975,21 +2859,23 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
case CSSPropertyDominantBaseline:
case CSSPropertyGlyphOrientationHorizontal:
case CSSPropertyGlyphOrientationVertical:
- case CSSPropertyKerning:
case CSSPropertyTextAnchor:
case CSSPropertyVectorEffect:
case CSSPropertyPaintOrder:
case CSSPropertyWritingMode:
return getSVGPropertyCSSValue(propertyID, DoNotUpdateLayout);
+
+ case CSSPropertyAll:
+ return nullptr;
}
logUnimplementedPropertyID(propertyID);
- return 0;
+ return nullptr;
}
String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
{
- RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID);
if (value)
return value->cssText();
return "";
@@ -3029,37 +2915,37 @@ bool CSSComputedStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, c
return true;
}
}
- RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID);
return value && propertyValue && value->equals(*propertyValue);
}
-PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyProperties() const
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyProperties() const
{
return copyPropertiesInSet(computableProperties());
}
-PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForShorthandProperty(const StylePropertyShorthand& shorthand) const
+PassRefPtrWillBeRawPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForShorthandProperty(const StylePropertyShorthand& shorthand) const
{
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
for (size_t i = 0; i < shorthand.length(); ++i) {
- RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
list->append(value);
}
return list.release();
}
-PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForSidesShorthand(const StylePropertyShorthand& shorthand) const
+PassRefPtrWillBeRawPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForSidesShorthand(const StylePropertyShorthand& shorthand) const
{
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
// Assume the properties are in the usual order top, right, bottom, left.
- RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
- RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
- RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
- RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
+ RefPtrWillBeRawPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
+ RefPtrWillBeRawPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
+ RefPtrWillBeRawPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
+ RefPtrWillBeRawPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
// All 4 properties must be specified.
if (!topValue || !rightValue || !bottomValue || !leftValue)
- return 0;
+ return nullptr;
bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
@@ -3076,22 +2962,22 @@ PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForSidesShorthand(co
return list.release();
}
-PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForGridShorthand(const StylePropertyShorthand& shorthand) const
+PassRefPtrWillBeRawPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForGridShorthand(const StylePropertyShorthand& shorthand) const
{
- RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
for (size_t i = 0; i < shorthand.length(); ++i) {
- RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
list->append(value.release());
}
return list.release();
}
-PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
{
- Vector<CSSProperty, 256> list;
+ WillBeHeapVector<CSSProperty, 256> list;
list.reserveInitialCapacity(properties.size());
for (unsigned i = 0; i < properties.size(); ++i) {
- RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
if (value)
list.append(CSSProperty(properties[i], value.release(), false));
}
@@ -3103,13 +2989,13 @@ CSSRule* CSSComputedStyleDeclaration::parentRule() const
return 0;
}
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
- return 0;
- RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
- return value ? value->cloneForCSSOM() : 0;
+ return nullptr;
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+ return value ? value->cloneForCSSOM() : nullptr;
}
String CSSComputedStyleDeclaration::getPropertyValue(const String& propertyName)
@@ -3147,7 +3033,7 @@ String CSSComputedStyleDeclaration::removeProperty(const String& name, Exception
return String();
}
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
{
return getPropertyCSSValue(propertyID);
}
@@ -3162,89 +3048,7 @@ void CSSComputedStyleDeclaration::setPropertyInternal(CSSPropertyID id, const St
exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + getPropertyNameString(id) + "' property is read-only.");
}
-const HashMap<AtomicString, String>* CSSComputedStyleDeclaration::variableMap() const
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- Node* styledNode = this->styledNode();
- if (!styledNode)
- return 0;
- RefPtr<RenderStyle> style = styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : m_pseudoElementSpecifier);
- if (!style)
- return 0;
- return style->variables();
-}
-
-unsigned CSSComputedStyleDeclaration::variableCount() const
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- const HashMap<AtomicString, String>* variables = variableMap();
- if (!variables)
- return 0;
- return variables->size();
-}
-
-String CSSComputedStyleDeclaration::variableValue(const AtomicString& name) const
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- const HashMap<AtomicString, String>* variables = variableMap();
- if (!variables)
- return emptyString();
- HashMap<AtomicString, String>::const_iterator it = variables->find(name);
- if (it == variables->end())
- return emptyString();
- return it->value;
-}
-
-bool CSSComputedStyleDeclaration::setVariableValue(const AtomicString& name, const String&, ExceptionState& exceptionState)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore the '" + name + "' property is read-only.");
- return false;
-}
-
-bool CSSComputedStyleDeclaration::removeVariable(const AtomicString&)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- return false;
-}
-
-bool CSSComputedStyleDeclaration::clearVariables(ExceptionState& exceptionState)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- exceptionState.throwDOMException(NoModificationAllowedError, "These styles are computed, and therefore variables may not be cleared.");
- return false;
-}
-
-CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::ComputedCSSVariablesIterator(const HashMap<AtomicString, String>* variables)
- : m_active(variables)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- if (m_active) {
- m_it = variables->begin();
- m_end = variables->end();
- }
-}
-
-void CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::advance()
-{
- ASSERT(m_active);
- ++m_it;
- m_active = !atEnd();
-}
-
-AtomicString CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::name() const
-{
- ASSERT(m_active);
- return m_it->key;
-}
-
-String CSSComputedStyleDeclaration::ComputedCSSVariablesIterator::value() const
-{
- ASSERT(m_active);
- return m_it->value;
-}
-
-PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForBackgroundShorthand() const
+PassRefPtrWillBeRawPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForBackgroundShorthand() const
{
static const CSSPropertyID propertiesBeforeSlashSeperator[5] = { CSSPropertyBackgroundColor, CSSPropertyBackgroundImage,
CSSPropertyBackgroundRepeat, CSSPropertyBackgroundAttachment,
@@ -3252,10 +3056,16 @@ PassRefPtr<CSSValueList> CSSComputedStyleDeclaration::valuesForBackgroundShortha
static const CSSPropertyID propertiesAfterSlashSeperator[3] = { CSSPropertyBackgroundSize, CSSPropertyBackgroundOrigin,
CSSPropertyBackgroundClip };
- RefPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
list->append(valuesForShorthandProperty(StylePropertyShorthand(CSSPropertyBackground, propertiesBeforeSlashSeperator, WTF_ARRAY_LENGTH(propertiesBeforeSlashSeperator))));
list->append(valuesForShorthandProperty(StylePropertyShorthand(CSSPropertyBackground, propertiesAfterSlashSeperator, WTF_ARRAY_LENGTH(propertiesAfterSlashSeperator))));
return list.release();
}
+void CSSComputedStyleDeclaration::trace(Visitor* visitor)
+{
+ visitor->trace(m_node);
+ CSSStyleDeclaration::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h b/chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h
index a3ff8770319..d60072ab91a 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.h
@@ -33,9 +33,6 @@ namespace WebCore {
class CSSPrimitiveValue;
class CSSValueList;
-class Color;
-class CustomFilterNumberParameter;
-class CustomFilterParameter;
class ExceptionState;
class MutableStylePropertySet;
class Node;
@@ -44,54 +41,41 @@ class RenderStyle;
class SVGPaint;
class ShadowData;
class ShadowList;
+class StyleColor;
class StylePropertySet;
class StylePropertyShorthand;
enum EUpdateLayout { DoNotUpdateLayout = false, UpdateLayout = true };
-class CSSComputedStyleDeclaration : public CSSStyleDeclaration {
-private:
- class ComputedCSSVariablesIterator : public CSSVariablesIterator {
- public:
- virtual ~ComputedCSSVariablesIterator() { }
- static PassRefPtr<ComputedCSSVariablesIterator> create(const HashMap<AtomicString, String>* variableMap) { return adoptRef(new ComputedCSSVariablesIterator(variableMap)); }
- private:
- explicit ComputedCSSVariablesIterator(const HashMap<AtomicString, String>* variableMap);
- virtual void advance() OVERRIDE;
- virtual bool atEnd() const OVERRIDE { return m_it == m_end; }
- virtual AtomicString name() const OVERRIDE;
- virtual String value() const OVERRIDE;
- bool m_active;
- typedef HashMap<AtomicString, String>::const_iterator VariablesMapIterator;
- VariablesMapIterator m_it;
- VariablesMapIterator m_end;
- };
-
+class CSSComputedStyleDeclaration FINAL : public CSSStyleDeclaration {
public:
- static PassRefPtr<CSSComputedStyleDeclaration> create(PassRefPtr<Node> node, bool allowVisitedStyle = false, const String& pseudoElementName = String())
+ static PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> create(PassRefPtrWillBeRawPtr<Node> node, bool allowVisitedStyle = false, const String& pseudoElementName = String())
{
- return adoptRef(new CSSComputedStyleDeclaration(node, allowVisitedStyle, pseudoElementName));
+ return adoptRefWillBeNoop(new CSSComputedStyleDeclaration(node, allowVisitedStyle, pseudoElementName));
}
virtual ~CSSComputedStyleDeclaration();
+#if !ENABLE(OILPAN)
virtual void ref() OVERRIDE;
virtual void deref() OVERRIDE;
+#endif
- PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
String getPropertyValue(CSSPropertyID) const;
bool getPropertyPriority(CSSPropertyID) const;
- virtual PassRefPtr<MutableStylePropertySet> copyProperties() const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyProperties() const OVERRIDE;
- PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID, EUpdateLayout) const;
- PassRefPtr<CSSValue> getFontSizeCSSValuePreferringKeyword() const;
+ PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(CSSPropertyID, EUpdateLayout = UpdateLayout) const;
+ PassRefPtrWillBeRawPtr<CSSValue> getFontSizeCSSValuePreferringKeyword() const;
bool useFixedFontDefaultSize() const;
- PassRefPtr<CSSValue> getSVGPropertyCSSValue(CSSPropertyID, EUpdateLayout) const;
+ PassRefPtrWillBeRawPtr<CSSValue> getSVGPropertyCSSValue(CSSPropertyID, EUpdateLayout) const;
+
+ PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyPropertiesInSet(const Vector<CSSPropertyID>&) const;
- PassRefPtr<MutableStylePropertySet> copyPropertiesInSet(const Vector<CSSPropertyID>&) const;
+ virtual void trace(Visitor*) OVERRIDE;
private:
- CSSComputedStyleDeclaration(PassRefPtr<Node>, bool allowVisitedStyle, const String&);
+ CSSComputedStyleDeclaration(PassRefPtrWillBeRawPtr<Node>, bool allowVisitedStyle, const String&);
// The styled node is either the node passed into getComputedStyle, or the
// PseudoElement for :before and :after if they exist.
@@ -101,49 +85,43 @@ private:
Node* styledNode() const;
// CSSOM functions. Don't make these public.
- virtual CSSRule* parentRule() const;
- virtual unsigned length() const;
- virtual String item(unsigned index) const;
+ virtual CSSRule* parentRule() const OVERRIDE;
+ virtual unsigned length() const OVERRIDE;
+ virtual String item(unsigned index) const OVERRIDE;
PassRefPtr<RenderStyle> computeRenderStyle(CSSPropertyID) const;
- virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName);
- virtual String getPropertyValue(const String& propertyName);
- virtual String getPropertyPriority(const String& propertyName);
- virtual String getPropertyShorthand(const String& propertyName);
- virtual bool isPropertyImplicit(const String& propertyName);
- virtual void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState&);
- virtual String removeProperty(const String& propertyName, ExceptionState&);
- virtual String cssText() const;
- virtual void setCSSText(const String&, ExceptionState&);
- virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID);
- virtual String getPropertyValueInternal(CSSPropertyID);
- virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionState&);
-
- const HashMap<AtomicString, String>* variableMap() const;
- virtual unsigned variableCount() const OVERRIDE;
- virtual String variableValue(const AtomicString& name) const OVERRIDE;
- virtual bool setVariableValue(const AtomicString& name, const String& value, ExceptionState&) OVERRIDE;
- virtual bool removeVariable(const AtomicString& name) OVERRIDE;
- virtual bool clearVariables(ExceptionState&) OVERRIDE;
- virtual PassRefPtr<CSSVariablesIterator> variablesIterator() const OVERRIDE { return ComputedCSSVariablesIterator::create(variableMap()); }
+ virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(const String& propertyName) OVERRIDE;
+ virtual String getPropertyValue(const String& propertyName) OVERRIDE;
+ virtual String getPropertyPriority(const String& propertyName) OVERRIDE;
+ virtual String getPropertyShorthand(const String& propertyName) OVERRIDE;
+ virtual bool isPropertyImplicit(const String& propertyName) OVERRIDE;
+ virtual void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState&) OVERRIDE;
+ virtual String removeProperty(const String& propertyName, ExceptionState&) OVERRIDE;
+ virtual String cssText() const OVERRIDE;
+ virtual void setCSSText(const String&, ExceptionState&) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) OVERRIDE;
+ virtual String getPropertyValueInternal(CSSPropertyID) OVERRIDE;
+ virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionState&) OVERRIDE;
virtual bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const OVERRIDE;
- PassRefPtr<CSSValue> valueForShadowData(const ShadowData&, const RenderStyle&, bool useSpread) const;
- PassRefPtr<CSSValue> valueForShadowList(const ShadowList*, const RenderStyle&, bool useSpread) const;
- PassRefPtr<CSSPrimitiveValue> currentColorOrValidColor(const RenderStyle&, const Color&) const;
- PassRefPtr<SVGPaint> adjustSVGPaintForCurrentColor(PassRefPtr<SVGPaint>, RenderStyle&) const;
+ PassRefPtrWillBeRawPtr<CSSValue> valueForShadowData(const ShadowData&, const RenderStyle&, bool useSpread) const;
+ PassRefPtrWillBeRawPtr<CSSValue> valueForShadowList(const ShadowList*, const RenderStyle&, bool useSpread) const;
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> currentColorOrValidColor(const RenderStyle&, const StyleColor&) const;
+ PassRefPtrWillBeRawPtr<SVGPaint> adjustSVGPaintForCurrentColor(PassRefPtrWillBeRawPtr<SVGPaint>, RenderStyle&) const;
- PassRefPtr<CSSValue> valueForFilter(const RenderObject*, const RenderStyle&) const;
+ PassRefPtrWillBeRawPtr<CSSValue> valueForFilter(const RenderObject*, const RenderStyle&) const;
- PassRefPtr<CSSValueList> valuesForShorthandProperty(const StylePropertyShorthand&) const;
- PassRefPtr<CSSValueList> valuesForSidesShorthand(const StylePropertyShorthand&) const;
- PassRefPtr<CSSValueList> valuesForBackgroundShorthand() const;
- PassRefPtr<CSSValueList> valuesForGridShorthand(const StylePropertyShorthand&) const;
+ PassRefPtrWillBeRawPtr<CSSValueList> valuesForShorthandProperty(const StylePropertyShorthand&) const;
+ PassRefPtrWillBeRawPtr<CSSValueList> valuesForSidesShorthand(const StylePropertyShorthand&) const;
+ PassRefPtrWillBeRawPtr<CSSValueList> valuesForBackgroundShorthand() const;
+ PassRefPtrWillBeRawPtr<CSSValueList> valuesForGridShorthand(const StylePropertyShorthand&) const;
- RefPtr<Node> m_node;
+ RefPtrWillBeMember<Node> m_node;
PseudoId m_pseudoElementSpecifier;
bool m_allowVisitedStyle;
+#if !ENABLE(OILPAN)
unsigned m_refCount;
+#endif
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
index 801cbb66f99..daa45df9d05 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.cpp
@@ -167,7 +167,7 @@ void CSSCrossfadeValue::loadSubimages(ResourceFetcher* fetcher)
PassRefPtr<Image> CSSCrossfadeValue::image(RenderObject* renderer, const IntSize& size)
{
if (size.isEmpty())
- return 0;
+ return nullptr;
ResourceFetcher* fetcher = renderer->document().fetcher();
ImageResource* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), fetcher);
@@ -218,4 +218,12 @@ bool CSSCrossfadeValue::equals(const CSSCrossfadeValue& other) const
&& compareCSSValuePtr(m_percentageValue, other.m_percentageValue);
}
+void CSSCrossfadeValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_fromValue);
+ visitor->trace(m_toValue);
+ visitor->trace(m_percentageValue);
+ CSSImageGeneratorValue::traceAfterDispatch(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h b/chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
index ffb46aed9f1..617a5d25ff1 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCrossfadeValue.h
@@ -43,9 +43,9 @@ class Document;
class CSSCrossfadeValue : public CSSImageGeneratorValue {
friend class CrossfadeSubimageObserverProxy;
public:
- static PassRefPtr<CSSCrossfadeValue> create(PassRefPtr<CSSValue> fromValue, PassRefPtr<CSSValue> toValue)
+ static PassRefPtrWillBeRawPtr<CSSCrossfadeValue> create(PassRefPtrWillBeRawPtr<CSSValue> fromValue, PassRefPtrWillBeRawPtr<CSSValue> toValue)
{
- return adoptRef(new CSSCrossfadeValue(fromValue, toValue));
+ return adoptRefWillBeNoop(new CSSCrossfadeValue(fromValue, toValue));
}
~CSSCrossfadeValue();
@@ -61,14 +61,16 @@ public:
void loadSubimages(ResourceFetcher*);
- void setPercentage(PassRefPtr<CSSPrimitiveValue> percentageValue) { m_percentageValue = percentageValue; }
+ void setPercentage(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> percentageValue) { m_percentageValue = percentageValue; }
bool hasFailedOrCanceledSubresources() const;
bool equals(const CSSCrossfadeValue&) const;
+ void traceAfterDispatch(Visitor*);
+
private:
- CSSCrossfadeValue(PassRefPtr<CSSValue> fromValue, PassRefPtr<CSSValue> toValue)
+ CSSCrossfadeValue(PassRefPtrWillBeRawPtr<CSSValue> fromValue, PassRefPtrWillBeRawPtr<CSSValue> toValue)
: CSSImageGeneratorValue(CrossfadeClass)
, m_fromValue(fromValue)
, m_toValue(toValue)
@@ -76,7 +78,7 @@ private:
, m_cachedToImage(0)
, m_crossfadeSubimageObserver(this) { }
- class CrossfadeSubimageObserverProxy : public ImageResourceClient {
+ class CrossfadeSubimageObserverProxy FINAL : public ImageResourceClient {
public:
CrossfadeSubimageObserverProxy(CSSCrossfadeValue* ownerValue)
: m_ownerValue(ownerValue)
@@ -92,9 +94,9 @@ private:
void crossfadeChanged(const IntRect&);
- RefPtr<CSSValue> m_fromValue;
- RefPtr<CSSValue> m_toValue;
- RefPtr<CSSPrimitiveValue> m_percentageValue;
+ RefPtrWillBeMember<CSSValue> m_fromValue;
+ RefPtrWillBeMember<CSSValue> m_toValue;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_percentageValue;
ResourcePtr<ImageResource> m_cachedFromImage;
ResourcePtr<ImageResource> m_cachedToImage;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
index 878fd8910de..296375b29b9 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "core/css/CSSCursorImageValue.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/css/CSSImageSetValue.h"
#include "core/fetch/ImageResource.h"
#include "core/fetch/ResourceFetcher.h"
@@ -34,20 +34,18 @@
#include "core/svg/SVGLengthContext.h"
#include "core/svg/SVGURIReference.h"
#include "wtf/MathExtras.h"
+#include "wtf/text/StringBuilder.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-static inline SVGCursorElement* resourceReferencedByCursorElement(const String& url, Document& document)
+static inline SVGCursorElement* resourceReferencedByCursorElement(const String& url, TreeScope& treeScope)
{
- Element* element = SVGURIReference::targetElementFromIRIString(url, document);
- if (element && element->hasTagName(SVGNames::cursorTag))
- return static_cast<SVGCursorElement*>(element);
-
- return 0;
+ Element* element = SVGURIReference::targetElementFromIRIString(url, treeScope);
+ return isSVGCursorElement(element) ? toSVGCursorElement(element) : 0;
}
-CSSCursorImageValue::CSSCursorImageValue(PassRefPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot)
+CSSCursorImageValue::CSSCursorImageValue(PassRefPtrWillBeRawPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot)
: CSSValue(CursorImageClass)
, m_imageValue(imageValue)
, m_hasHotSpot(hasHotSpot)
@@ -58,6 +56,8 @@ CSSCursorImageValue::CSSCursorImageValue(PassRefPtr<CSSValue> imageValue, bool h
CSSCursorImageValue::~CSSCursorImageValue()
{
+ // The below teardown is all handled by weak pointer processing in oilpan.
+#if !ENABLE(OILPAN)
if (!isSVGCursor())
return;
@@ -68,9 +68,10 @@ CSSCursorImageValue::~CSSCursorImageValue()
for (; it != end; ++it) {
SVGElement* referencedElement = *it;
referencedElement->cursorImageValueRemoved();
- if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->document()))
+ if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, referencedElement->treeScope()))
cursorElement->removeClient(referencedElement);
}
+#endif
}
String CSSCursorImageValue::customCSSText() const
@@ -95,21 +96,23 @@ bool CSSCursorImageValue::updateIfSVGCursorIsUsed(Element* element)
return false;
String url = toCSSImageValue(m_imageValue.get())->url();
- if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, element->document())) {
+ if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(url, element->treeScope())) {
// FIXME: This will override hot spot specified in CSS, which is probably incorrect.
SVGLengthContext lengthContext(0);
m_hasHotSpot = true;
- float x = roundf(cursorElement->xCurrentValue().value(lengthContext));
+ float x = roundf(cursorElement->x()->currentValue()->value(lengthContext));
m_hotSpot.setX(static_cast<int>(x));
- float y = roundf(cursorElement->yCurrentValue().value(lengthContext));
+ float y = roundf(cursorElement->y()->currentValue()->value(lengthContext));
m_hotSpot.setY(static_cast<int>(y));
- if (cachedImageURL() != element->document().completeURL(cursorElement->hrefCurrentValue()))
+ if (cachedImageURL() != element->document().completeURL(cursorElement->href()->currentValue()->value()))
clearImageResource();
SVGElement* svgElement = toSVGElement(element);
+#if !ENABLE(OILPAN)
m_referencedElements.add(svgElement);
+#endif
svgElement->setCursorImageValue(this);
cursorElement->addClient(svgElement);
return true;
@@ -130,10 +133,11 @@ StyleImage* CSSCursorImageValue::cachedImage(ResourceFetcher* loader, float devi
// to change the URL of the CSSImageValue (which would then change behavior like cssText),
// we create an alternate CSSImageValue to use.
if (isSVGCursor() && loader && loader->document()) {
- RefPtr<CSSImageValue> imageValue = toCSSImageValue(m_imageValue.get());
+ RefPtrWillBeRawPtr<CSSImageValue> imageValue = toCSSImageValue(m_imageValue.get());
// FIXME: This will fail if the <cursor> element is in a shadow DOM (bug 59827)
if (SVGCursorElement* cursorElement = resourceReferencedByCursorElement(imageValue->url(), *loader->document())) {
- RefPtr<CSSImageValue> svgImageValue = CSSImageValue::create(cursorElement->hrefCurrentValue());
+ RefPtrWillBeRawPtr<CSSImageValue> svgImageValue = CSSImageValue::create(loader->document()->completeURL(cursorElement->href()->currentValue()->value()));
+ svgImageValue->setReferrer(imageValue->referrer());
StyleFetchedImage* cachedImage = svgImageValue->cachedImage(loader);
m_image = cachedImage;
return cachedImage;
@@ -164,7 +168,7 @@ StyleImage* CSSCursorImageValue::cachedOrPendingImage(float deviceScaleFactor)
bool CSSCursorImageValue::isSVGCursor() const
{
if (m_imageValue->isImageValue()) {
- RefPtr<CSSImageValue> imageValue = toCSSImageValue(m_imageValue.get());
+ RefPtrWillBeRawPtr<CSSImageValue> imageValue = toCSSImageValue(m_imageValue.get());
KURL kurl(ParsedURLString, imageValue->url());
return kurl.hasFragmentIdentifier();
}
@@ -180,14 +184,16 @@ String CSSCursorImageValue::cachedImageURL()
void CSSCursorImageValue::clearImageResource()
{
- m_image = 0;
+ m_image = nullptr;
m_accessedImage = false;
}
+#if !ENABLE(OILPAN)
void CSSCursorImageValue::removeReferencedElement(SVGElement* element)
{
m_referencedElements.remove(element);
}
+#endif
bool CSSCursorImageValue::equals(const CSSCursorImageValue& other) const
{
@@ -195,4 +201,10 @@ bool CSSCursorImageValue::equals(const CSSCursorImageValue& other) const
&& compareCSSValuePtr(m_imageValue, other.m_imageValue);
}
+void CSSCursorImageValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_imageValue);
+ CSSValue::traceAfterDispatch(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.h b/chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.h
index 17bba3188a1..abc54f73a3f 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCursorImageValue.h
@@ -32,9 +32,9 @@ class SVGElement;
class CSSCursorImageValue : public CSSValue {
public:
- static PassRefPtr<CSSCursorImageValue> create(PassRefPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot)
+ static PassRefPtrWillBeRawPtr<CSSCursorImageValue> create(PassRefPtrWillBeRawPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot)
{
- return adoptRef(new CSSCursorImageValue(imageValue, hasHotSpot, hotSpot));
+ return adoptRefWillBeNoop(new CSSCursorImageValue(imageValue, hasHotSpot, hotSpot));
}
~CSSCursorImageValue();
@@ -54,25 +54,31 @@ public:
StyleImage* cachedImage(ResourceFetcher*, float deviceScaleFactor);
StyleImage* cachedOrPendingImage(float deviceScaleFactor);
+#if !ENABLE(OILPAN)
void removeReferencedElement(SVGElement*);
+#endif
bool equals(const CSSCursorImageValue&) const;
+ void traceAfterDispatch(Visitor*);
+
private:
- CSSCursorImageValue(PassRefPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot);
+ CSSCursorImageValue(PassRefPtrWillBeRawPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot);
bool isSVGCursor() const;
String cachedImageURL();
void clearImageResource();
- RefPtr<CSSValue> m_imageValue;
+ RefPtrWillBeMember<CSSValue> m_imageValue;
bool m_hasHotSpot;
IntPoint m_hotSpot;
RefPtr<StyleImage> m_image;
bool m_accessedImage;
+#if !ENABLE(OILPAN)
HashSet<SVGElement*> m_referencedElements;
+#endif
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSCursorImageValue, isCursorImageValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSCustomFontData.h b/chromium/third_party/WebKit/Source/core/css/CSSCustomFontData.h
index 9436927cabb..ec2bb6dc885 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSCustomFontData.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSCustomFontData.h
@@ -28,32 +28,45 @@ namespace WebCore {
class CSSCustomFontData FINAL : public CustomFontData {
public:
- static PassRefPtr<CSSCustomFontData> create(bool isLoadingFallback = false)
+ enum FallbackVisibility { InvisibleFallback, VisibleFallback };
+
+ static PassRefPtr<CSSCustomFontData> create(RemoteFontFaceSource* source, FallbackVisibility visibility)
{
- return adoptRef(new CSSCustomFontData(isLoadingFallback));
+ return adoptRef(new CSSCustomFontData(source, visibility));
}
virtual ~CSSCustomFontData() { }
+ virtual bool shouldSkipDrawing() const OVERRIDE
+ {
+ if (m_fontFaceSource)
+ m_fontFaceSource->paintRequested();
+ return m_fallbackVisibility == InvisibleFallback && m_isUsed;
+ }
+
virtual void beginLoadIfNeeded() const OVERRIDE
{
- if (!m_isUsed && m_isLoadingFallback && m_fontFaceSource) {
+ if (!m_isUsed && m_fontFaceSource) {
m_isUsed = true;
m_fontFaceSource->beginLoadIfNeeded();
}
}
- virtual void setCSSFontFaceSource(CSSFontFaceSource* source) OVERRIDE { m_fontFaceSource = source; }
- virtual void clearCSSFontFaceSource() OVERRIDE { m_fontFaceSource = 0; }
+ virtual bool isLoading() const OVERRIDE { return m_isUsed; }
+ virtual bool isLoadingFallback() const OVERRIDE { return true; }
+ virtual void clearFontFaceSource() OVERRIDE { m_fontFaceSource = 0; }
private:
- CSSCustomFontData(bool isLoadingFallback)
- : CustomFontData(isLoadingFallback)
- , m_fontFaceSource(0)
+ CSSCustomFontData(RemoteFontFaceSource* source, FallbackVisibility visibility)
+ : m_fontFaceSource(source)
+ , m_fallbackVisibility(visibility)
+ , m_isUsed(false)
{
}
- CSSFontFaceSource* m_fontFaceSource;
+ RemoteFontFaceSource* m_fontFaceSource;
+ FallbackVisibility m_fallbackVisibility;
+ mutable bool m_isUsed;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.cpp b/chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.cpp
index cdd794828a7..1137f9b7ad9 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.cpp
@@ -29,33 +29,31 @@
#include "config.h"
#include "core/css/CSSDefaultStyleSheets.h"
-#include "UserAgentStyleSheets.h"
+#include "core/MathMLNames.h"
+#include "core/UserAgentStyleSheets.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/RuleSet.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLVideoElement.h"
#include "core/rendering/RenderTheme.h"
+#include "wtf/LeakAnnotations.h"
namespace WebCore {
using namespace HTMLNames;
-RuleSet* CSSDefaultStyleSheets::defaultStyle;
-RuleSet* CSSDefaultStyleSheets::defaultViewportStyle;
-RuleSet* CSSDefaultStyleSheets::defaultQuirksStyle;
-RuleSet* CSSDefaultStyleSheets::defaultPrintStyle;
-RuleSet* CSSDefaultStyleSheets::defaultViewSourceStyle;
-RuleSet* CSSDefaultStyleSheets::defaultXHTMLMobileProfileStyle;
-
-StyleSheetContents* CSSDefaultStyleSheets::defaultStyleSheet;
-StyleSheetContents* CSSDefaultStyleSheets::viewportStyleSheet;
-StyleSheetContents* CSSDefaultStyleSheets::quirksStyleSheet;
-StyleSheetContents* CSSDefaultStyleSheets::svgStyleSheet;
-StyleSheetContents* CSSDefaultStyleSheets::mediaControlsStyleSheet;
-StyleSheetContents* CSSDefaultStyleSheets::fullscreenStyleSheet;
+CSSDefaultStyleSheets& CSSDefaultStyleSheets::instance()
+{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<CSSDefaultStyleSheets>, cssDefaultStyleSheets, (new CSSDefaultStyleSheets()));
+ return *cssDefaultStyleSheets;
+#else
+ DEFINE_STATIC_LOCAL(CSSDefaultStyleSheets, cssDefaultStyleSheets, ());
+ return cssDefaultStyleSheets;
+#endif
+}
static const MediaQueryEvaluator& screenEval()
{
@@ -69,100 +67,153 @@ static const MediaQueryEvaluator& printEval()
return staticPrintEval;
}
-static StyleSheetContents* parseUASheet(const String& str)
+static PassRefPtrWillBeRawPtr<StyleSheetContents> parseUASheet(const String& str)
{
- StyleSheetContents* sheet = StyleSheetContents::create(CSSParserContext(UASheetMode)).leakRef(); // leak the sheet on purpose
+ RefPtrWillBeRawPtr<StyleSheetContents> sheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
sheet->parseString(str);
- return sheet;
+ // User Agent stylesheets are parsed once for the lifetime of the renderer
+ // and are intentionally leaked.
+ WTF_ANNOTATE_LEAKING_OBJECT_PTR(sheet.get());
+ return sheet.release();
}
-static StyleSheetContents* parseUASheet(const char* characters, unsigned size)
+static PassRefPtrWillBeRawPtr<StyleSheetContents> parseUASheet(const char* characters, unsigned size)
{
return parseUASheet(String(characters, size));
}
-void CSSDefaultStyleSheets::loadDefaultStylesheetIfNecessary()
+CSSDefaultStyleSheets::CSSDefaultStyleSheets()
+ : m_defaultStyle(nullptr)
+ , m_defaultViewportStyle(nullptr)
+ , m_defaultQuirksStyle(nullptr)
+ , m_defaultPrintStyle(nullptr)
+ , m_defaultViewSourceStyle(nullptr)
+ , m_defaultXHTMLMobileProfileStyle(nullptr)
+ , m_defaultTransitionStyle(nullptr)
+ , m_defaultStyleSheet(nullptr)
+ , m_viewportStyleSheet(nullptr)
+ , m_quirksStyleSheet(nullptr)
+ , m_svgStyleSheet(nullptr)
+ , m_mathmlStyleSheet(nullptr)
+ , m_mediaControlsStyleSheet(nullptr)
+ , m_fullscreenStyleSheet(nullptr)
{
- if (!defaultStyle)
- loadDefaultStyle();
-}
-
-void CSSDefaultStyleSheets::loadDefaultStyle()
-{
- ASSERT(!defaultStyle);
- defaultStyle = RuleSet::create().leakPtr();
- defaultViewportStyle = RuleSet::create().leakPtr();
- defaultPrintStyle = RuleSet::create().leakPtr();
- defaultQuirksStyle = RuleSet::create().leakPtr();
+ m_defaultStyle = RuleSet::create();
+ m_defaultViewportStyle = RuleSet::create();
+ m_defaultPrintStyle = RuleSet::create();
+ m_defaultQuirksStyle = RuleSet::create();
// Strict-mode rules.
String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::theme().extraDefaultStyleSheet();
- defaultStyleSheet = parseUASheet(defaultRules);
- defaultStyle->addRulesFromSheet(defaultStyleSheet, screenEval());
+ m_defaultStyleSheet = parseUASheet(defaultRules);
+ m_defaultStyle->addRulesFromSheet(defaultStyleSheet(), screenEval());
#if OS(ANDROID)
String viewportRules(viewportAndroidUserAgentStyleSheet, sizeof(viewportAndroidUserAgentStyleSheet));
#else
String viewportRules;
#endif
- viewportStyleSheet = parseUASheet(viewportRules);
- defaultViewportStyle->addRulesFromSheet(viewportStyleSheet, screenEval());
- defaultPrintStyle->addRulesFromSheet(defaultStyleSheet, printEval());
+ m_viewportStyleSheet = parseUASheet(viewportRules);
+ m_defaultViewportStyle->addRulesFromSheet(viewportStyleSheet(), screenEval());
+ m_defaultPrintStyle->addRulesFromSheet(defaultStyleSheet(), printEval());
// Quirks-mode rules.
String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::theme().extraQuirksStyleSheet();
- quirksStyleSheet = parseUASheet(quirksRules);
- defaultQuirksStyle->addRulesFromSheet(quirksStyleSheet, screenEval());
+ m_quirksStyleSheet = parseUASheet(quirksRules);
+ m_defaultQuirksStyle->addRulesFromSheet(quirksStyleSheet(), screenEval());
+}
+
+RuleSet* CSSDefaultStyleSheets::defaultViewSourceStyle()
+{
+ if (!m_defaultViewSourceStyle) {
+ m_defaultViewSourceStyle = RuleSet::create();
+ // Loaded stylesheet is leaked on purpose.
+ RefPtrWillBeRawPtr<StyleSheetContents> stylesheet = parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet));
+ m_defaultViewSourceStyle->addRulesFromSheet(stylesheet.release().leakRef(), screenEval());
+ }
+ return m_defaultViewSourceStyle.get();
}
-RuleSet* CSSDefaultStyleSheets::viewSourceStyle()
+RuleSet* CSSDefaultStyleSheets::defaultTransitionStyle()
{
- if (!defaultViewSourceStyle) {
- defaultViewSourceStyle = RuleSet::create().leakPtr();
- defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval());
+ if (!m_defaultTransitionStyle) {
+ m_defaultTransitionStyle = RuleSet::create();
+ // Loaded stylesheet is leaked on purpose.
+ RefPtrWillBeRawPtr<StyleSheetContents> stylesheet = parseUASheet(navigationTransitionsUserAgentStyleSheet, sizeof(navigationTransitionsUserAgentStyleSheet));
+ m_defaultTransitionStyle->addRulesFromSheet(stylesheet.release().leakRef(), screenEval());
}
- return defaultViewSourceStyle;
+ return m_defaultTransitionStyle.get();
}
-RuleSet* CSSDefaultStyleSheets::xhtmlMobileProfileStyle()
+RuleSet* CSSDefaultStyleSheets::defaultXHTMLMobileProfileStyle()
{
- if (!defaultXHTMLMobileProfileStyle) {
- defaultXHTMLMobileProfileStyle = RuleSet::create().leakPtr();
- defaultXHTMLMobileProfileStyle->addRulesFromSheet(parseUASheet(xhtmlmpUserAgentStyleSheet, sizeof(xhtmlmpUserAgentStyleSheet)), screenEval());
+ if (!m_defaultXHTMLMobileProfileStyle) {
+ m_defaultXHTMLMobileProfileStyle = RuleSet::create();
+ // Loaded stylesheet is leaked on purpose.
+ RefPtrWillBeRawPtr<StyleSheetContents> stylesheet = parseUASheet(xhtmlmpUserAgentStyleSheet, sizeof(xhtmlmpUserAgentStyleSheet));
+ m_defaultXHTMLMobileProfileStyle->addRulesFromSheet(stylesheet.release().leakRef(), screenEval());
}
- return defaultXHTMLMobileProfileStyle;
+ return m_defaultXHTMLMobileProfileStyle.get();
}
void CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(Element* element, bool& changedDefaultStyle)
{
// FIXME: We should assert that the sheet only styles SVG elements.
- if (element->isSVGElement() && !svgStyleSheet) {
- svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
- defaultStyle->addRulesFromSheet(svgStyleSheet, screenEval());
- defaultPrintStyle->addRulesFromSheet(svgStyleSheet, printEval());
+ if (element->isSVGElement() && !m_svgStyleSheet) {
+ m_svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
+ m_defaultStyle->addRulesFromSheet(svgStyleSheet(), screenEval());
+ m_defaultPrintStyle->addRulesFromSheet(svgStyleSheet(), printEval());
+ changedDefaultStyle = true;
+ }
+
+ // FIXME: We should assert that the sheet only styles MathML elements.
+ if (element->namespaceURI() == MathMLNames::mathmlNamespaceURI
+ && !m_mathmlStyleSheet) {
+ m_mathmlStyleSheet = parseUASheet(mathmlUserAgentStyleSheet,
+ sizeof(mathmlUserAgentStyleSheet));
+ m_defaultStyle->addRulesFromSheet(mathmlStyleSheet(), screenEval());
+ m_defaultPrintStyle->addRulesFromSheet(mathmlStyleSheet(), printEval());
changedDefaultStyle = true;
}
// FIXME: We should assert that this sheet only contains rules for <video> and <audio>.
- if (!mediaControlsStyleSheet && (isHTMLVideoElement(element) || element->hasTagName(audioTag))) {
+ if (!m_mediaControlsStyleSheet && (isHTMLVideoElement(*element) || isHTMLAudioElement(*element))) {
String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::theme().extraMediaControlsStyleSheet();
- mediaControlsStyleSheet = parseUASheet(mediaRules);
- defaultStyle->addRulesFromSheet(mediaControlsStyleSheet, screenEval());
- defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet, printEval());
+ m_mediaControlsStyleSheet = parseUASheet(mediaRules);
+ m_defaultStyle->addRulesFromSheet(mediaControlsStyleSheet(), screenEval());
+ m_defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet(), printEval());
changedDefaultStyle = true;
}
// FIXME: This only works because we Force recalc the entire document so the new sheet
// is loaded for <html> and the correct styles apply to everyone.
- if (!fullscreenStyleSheet && FullscreenElementStack::isFullScreen(&element->document())) {
+ if (!m_fullscreenStyleSheet && FullscreenElementStack::isFullScreen(element->document())) {
String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::theme().extraFullScreenStyleSheet();
- fullscreenStyleSheet = parseUASheet(fullscreenRules);
- defaultStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval());
- defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet, screenEval());
+ m_fullscreenStyleSheet = parseUASheet(fullscreenRules);
+ m_defaultStyle->addRulesFromSheet(fullscreenStyleSheet(), screenEval());
+ m_defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet(), screenEval());
changedDefaultStyle = true;
}
- ASSERT(defaultStyle->features().idsInRules.isEmpty());
- ASSERT(defaultStyle->features().siblingRules.isEmpty());
+ ASSERT(!m_defaultStyle->features().hasIdsInSelectors());
+ ASSERT(m_defaultStyle->features().siblingRules.isEmpty());
+}
+
+void CSSDefaultStyleSheets::trace(Visitor* visitor)
+{
+ visitor->trace(m_defaultStyle);
+ visitor->trace(m_defaultViewportStyle);
+ visitor->trace(m_defaultQuirksStyle);
+ visitor->trace(m_defaultPrintStyle);
+ visitor->trace(m_defaultViewSourceStyle);
+ visitor->trace(m_defaultXHTMLMobileProfileStyle);
+ visitor->trace(m_defaultTransitionStyle);
+ visitor->trace(m_defaultStyleSheet);
+ visitor->trace(m_viewportStyleSheet);
+ visitor->trace(m_quirksStyleSheet);
+ visitor->trace(m_svgStyleSheet);
+ visitor->trace(m_mathmlStyleSheet);
+ visitor->trace(m_mediaControlsStyleSheet);
+ visitor->trace(m_fullscreenStyleSheet);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.h b/chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.h
index c85fd226340..0efccd191ec 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSDefaultStyleSheets.h
@@ -23,39 +23,58 @@
#ifndef CSSDefaultStyleSheets_h
#define CSSDefaultStyleSheets_h
+#include "platform/heap/Handle.h"
+
namespace WebCore {
class Element;
class RuleSet;
class StyleSheetContents;
-class CSSDefaultStyleSheets {
+class CSSDefaultStyleSheets : public NoBaseWillBeGarbageCollected<CSSDefaultStyleSheets> {
public:
- static RuleSet* defaultStyle;
- static RuleSet* defaultViewportStyle;
- static RuleSet* defaultQuirksStyle;
- static RuleSet* defaultPrintStyle;
- static RuleSet* defaultViewSourceStyle;
- static RuleSet* defaultXHTMLMobileProfileStyle;
-
- static StyleSheetContents* defaultStyleSheet;
- static StyleSheetContents* viewportStyleSheet;
- static StyleSheetContents* quirksStyleSheet;
- static StyleSheetContents* svgStyleSheet;
- static StyleSheetContents* mediaControlsStyleSheet;
- static StyleSheetContents* fullscreenStyleSheet;
-
- static void ensureDefaultStyleSheetsForElement(Element*, bool& changedDefaultStyle);
- // FIXME: defaultStyleSheet should have an accessor which incorporates this branch:
- static void loadDefaultStylesheetIfNecessary();
-
- static RuleSet* viewSourceStyle();
+ static CSSDefaultStyleSheets& instance();
+
+ void ensureDefaultStyleSheetsForElement(Element*, bool& changedDefaultStyle);
+
+ RuleSet* defaultStyle() { return m_defaultStyle.get(); }
+ RuleSet* defaultViewportStyle() { return m_defaultViewportStyle.get(); }
+ RuleSet* defaultQuirksStyle() { return m_defaultQuirksStyle.get(); }
+ RuleSet* defaultPrintStyle() { return m_defaultPrintStyle.get(); }
+ RuleSet* defaultViewSourceStyle();
+ RuleSet* defaultTransitionStyle();
// FIXME: Remove WAP support.
- static RuleSet* xhtmlMobileProfileStyle();
+ RuleSet* defaultXHTMLMobileProfileStyle();
+
+ StyleSheetContents* defaultStyleSheet() { return m_defaultStyleSheet.get(); }
+ StyleSheetContents* viewportStyleSheet() { return m_viewportStyleSheet.get(); }
+ StyleSheetContents* quirksStyleSheet() { return m_quirksStyleSheet.get(); }
+ StyleSheetContents* svgStyleSheet() { return m_svgStyleSheet.get(); }
+ StyleSheetContents* mathmlStyleSheet() { return m_mathmlStyleSheet.get(); }
+ StyleSheetContents* mediaControlsStyleSheet() { return m_mediaControlsStyleSheet.get(); }
+ StyleSheetContents* fullscreenStyleSheet() { return m_fullscreenStyleSheet.get(); }
+
+ void trace(Visitor*);
private:
- static void loadDefaultStyle();
+ CSSDefaultStyleSheets();
+
+ OwnPtrWillBeMember<RuleSet> m_defaultStyle;
+ OwnPtrWillBeMember<RuleSet> m_defaultViewportStyle;
+ OwnPtrWillBeMember<RuleSet> m_defaultQuirksStyle;
+ OwnPtrWillBeMember<RuleSet> m_defaultPrintStyle;
+ OwnPtrWillBeMember<RuleSet> m_defaultViewSourceStyle;
+ OwnPtrWillBeMember<RuleSet> m_defaultXHTMLMobileProfileStyle;
+ OwnPtrWillBeMember<RuleSet> m_defaultTransitionStyle;
+
+ RefPtrWillBeMember<StyleSheetContents> m_defaultStyleSheet;
+ RefPtrWillBeMember<StyleSheetContents> m_viewportStyleSheet;
+ RefPtrWillBeMember<StyleSheetContents> m_quirksStyleSheet;
+ RefPtrWillBeMember<StyleSheetContents> m_svgStyleSheet;
+ RefPtrWillBeMember<StyleSheetContents> m_mathmlStyleSheet;
+ RefPtrWillBeMember<StyleSheetContents> m_mediaControlsStyleSheet;
+ RefPtrWillBeMember<StyleSheetContents> m_fullscreenStyleSheet;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFilterRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFilterRule.cpp
index dc44874be19..90b3390fcad 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFilterRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFilterRule.cpp
@@ -45,8 +45,10 @@ CSSFilterRule::CSSFilterRule(StyleRuleFilter* filterRule, CSSStyleSheet* parent)
CSSFilterRule::~CSSFilterRule()
{
+#if !ENABLE(OILPAN)
if (m_propertiesCSSOMWrapper)
m_propertiesCSSOMWrapper->clearParentRule();
+#endif
}
CSSStyleDeclaration* CSSFilterRule::style() const
@@ -65,7 +67,7 @@ String CSSFilterRule::cssText() const
result.append(filterName);
result.appendLiteral(" { ");
- String descs = m_filterRule->properties()->asText();
+ String descs = m_filterRule->properties().asText();
result.append(descs);
if (!descs.isEmpty())
result.append(' ');
@@ -82,5 +84,12 @@ void CSSFilterRule::reattach(StyleRuleBase* rule)
m_propertiesCSSOMWrapper->reattach(m_filterRule->mutableProperties());
}
+void CSSFilterRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_filterRule);
+ visitor->trace(m_propertiesCSSOMWrapper);
+ CSSRule::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFilterRule.h b/chromium/third_party/WebKit/Source/core/css/CSSFilterRule.h
index 9bb1b192c2a..bd3be8dfe3b 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFilterRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFilterRule.h
@@ -31,6 +31,7 @@
#define CSSFilterRule_h
#include "core/css/CSSRule.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -38,9 +39,12 @@ class CSSStyleDeclaration;
class StyleRuleFilter;
class StyleRuleCSSStyleDeclaration;
-class CSSFilterRule : public CSSRule {
+class CSSFilterRule FINAL : public CSSRule {
public:
- static PassRefPtr<CSSFilterRule> create(StyleRuleFilter* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSFilterRule(rule, sheet)); }
+ static PassRefPtrWillBeRawPtr<CSSFilterRule> create(StyleRuleFilter* rule, CSSStyleSheet* sheet)
+ {
+ return adoptRefWillBeNoop(new CSSFilterRule(rule, sheet));
+ }
virtual ~CSSFilterRule();
@@ -50,11 +54,13 @@ public:
CSSStyleDeclaration* style() const;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSFilterRule(StyleRuleFilter*, CSSStyleSheet* parent);
- RefPtr<StyleRuleFilter> m_filterRule;
- mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
+ RefPtrWillBeMember<StyleRuleFilter> m_filterRule;
+ mutable RefPtrWillBeMember<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
};
DEFINE_CSS_RULE_TYPE_CASTS(CSSFilterRule, WEBKIT_FILTER_RULE);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFilterValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFilterValue.cpp
index 75567a7eeb8..3f71adecdcb 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFilterValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFilterValue.cpp
@@ -26,66 +26,60 @@
#include "config.h"
#include "core/css/CSSFilterValue.h"
-#include "wtf/text/WTFString.h"
+#include "wtf/text/StringBuilder.h"
namespace WebCore {
CSSFilterValue::CSSFilterValue(FilterOperationType operationType)
- : CSSValueList(CSSFilterClass, typeUsesSpaceSeparator(operationType) ? SpaceSeparator : CommaSeparator)
+ : CSSValueList(CSSFilterClass, CommaSeparator)
, m_type(operationType)
{
}
-bool CSSFilterValue::typeUsesSpaceSeparator(FilterOperationType operationType)
-{
- return operationType != CustomFilterOperation;
-}
-
String CSSFilterValue::customCSSText() const
{
- String result;
+ StringBuilder result;
switch (m_type) {
case ReferenceFilterOperation:
- result = "url(";
+ result.append("url(");
break;
case GrayscaleFilterOperation:
- result = "grayscale(";
+ result.append("grayscale(");
break;
case SepiaFilterOperation:
- result = "sepia(";
+ result.append("sepia(");
break;
case SaturateFilterOperation:
- result = "saturate(";
+ result.append("saturate(");
break;
case HueRotateFilterOperation:
- result = "hue-rotate(";
+ result.append("hue-rotate(");
break;
case InvertFilterOperation:
- result = "invert(";
+ result.append("invert(");
break;
case OpacityFilterOperation:
- result = "opacity(";
+ result.append("opacity(");
break;
case BrightnessFilterOperation:
- result = "brightness(";
+ result.append("brightness(");
break;
case ContrastFilterOperation:
- result = "contrast(";
+ result.append("contrast(");
break;
case BlurFilterOperation:
- result = "blur(";
+ result.append("blur(");
break;
case DropShadowFilterOperation:
- result = "drop-shadow(";
- break;
- case CustomFilterOperation:
- result = "custom(";
+ result.append("drop-shadow(");
break;
default:
break;
}
- return result + CSSValueList::customCSSText() + ")";
+ result.append(CSSValueList::customCSSText());
+ result.append(')');
+ return result.toString();
}
CSSFilterValue::CSSFilterValue(const CSSFilterValue& cloneFrom)
@@ -94,9 +88,9 @@ CSSFilterValue::CSSFilterValue(const CSSFilterValue& cloneFrom)
{
}
-PassRefPtr<CSSFilterValue> CSSFilterValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSFilterValue> CSSFilterValue::cloneForCSSOM() const
{
- return adoptRef(new CSSFilterValue(*this));
+ return adoptRefWillBeNoop(new CSSFilterValue(*this));
}
bool CSSFilterValue::equals(const CSSFilterValue& other) const
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFilterValue.h b/chromium/third_party/WebKit/Source/core/css/CSSFilterValue.h
index 7a2f80c1a4c..4304e144cd4 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFilterValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFilterValue.h
@@ -47,24 +47,25 @@ public:
ContrastFilterOperation,
BlurFilterOperation,
DropShadowFilterOperation,
- CustomFilterOperation
};
static bool typeUsesSpaceSeparator(FilterOperationType);
- static PassRefPtr<CSSFilterValue> create(FilterOperationType type)
+ static PassRefPtrWillBeRawPtr<CSSFilterValue> create(FilterOperationType type)
{
- return adoptRef(new CSSFilterValue(type));
+ return adoptRefWillBeNoop(new CSSFilterValue(type));
}
String customCSSText() const;
FilterOperationType operationType() const { return m_type; }
- PassRefPtr<CSSFilterValue> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<CSSFilterValue> cloneForCSSOM() const;
bool equals(const CSSFilterValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValueList::traceAfterDispatch(visitor); }
+
private:
explicit CSSFilterValue(FilterOperationType);
explicit CSSFilterValue(const CSSFilterValue& cloneFrom);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFace.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFontFace.cpp
index c21c9125afb..9dddf489a46 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFace.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFace.cpp
@@ -26,60 +26,19 @@
#include "config.h"
#include "core/css/CSSFontFace.h"
+#include "core/css/CSSFontFaceSource.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSSegmentedFontFace.h"
#include "core/css/FontFaceSet.h"
+#include "core/css/RemoteFontFaceSource.h"
#include "core/dom/Document.h"
#include "core/frame/UseCounter.h"
+#include "platform/fonts/FontDescription.h"
#include "platform/fonts/SimpleFontData.h"
namespace WebCore {
-CSSFontFace::~CSSFontFace()
-{
- m_fontFace->cssFontFaceDestroyed();
-}
-
-PassRefPtr<CSSFontFace> CSSFontFace::createFromStyleRule(Document* document, const StyleRuleFontFace* fontFaceRule)
-{
- RefPtr<FontFace> fontFace = FontFace::create(fontFaceRule);
- if (!fontFace || fontFace->family().isEmpty())
- return 0;
-
- unsigned traitsMask = fontFace->traitsMask();
- if (!traitsMask)
- return 0;
-
- // FIXME: Plumbing back into createCSSFontFace seems odd.
- // Maybe move FontFace::createCSSFontFace logic here?
- RefPtr<CSSFontFace> cssFontFace = fontFace->createCSSFontFace(document);
- if (!cssFontFace || !cssFontFace->isValid())
- return 0;
-
- return cssFontFace;
-}
-
-bool CSSFontFace::isLoaded() const
-{
- size_t size = m_sources.size();
- for (size_t i = 0; i < size; i++) {
- if (!m_sources[i]->isLoaded())
- return false;
- }
- return true;
-}
-
-bool CSSFontFace::isValid() const
-{
- size_t size = m_sources.size();
- for (size_t i = 0; i < size; i++) {
- if (m_sources[i]->isValid())
- return true;
- }
- return false;
-}
-
-void CSSFontFace::addSource(PassOwnPtr<CSSFontFaceSource> source)
+void CSSFontFace::addSource(PassOwnPtrWillBeRawPtr<CSSFontFaceSource> source)
{
source->setFontFace(this);
m_sources.append(source);
@@ -91,99 +50,112 @@ void CSSFontFace::setSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
m_segmentedFontFace = segmentedFontFace;
}
-void CSSFontFace::beginLoadIfNeeded(CSSFontFaceSource* source)
+void CSSFontFace::didBeginLoad()
{
- if (!m_segmentedFontFace)
- return;
-
- if (source->resource() && source->resource()->stillNeedsLoad()) {
- CSSFontSelector* fontSelector = m_segmentedFontFace->fontSelector();
- fontSelector->beginLoadingFontSoon(source->resource());
- }
-
if (loadStatus() == FontFace::Unloaded)
setLoadStatus(FontFace::Loading);
}
-void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
+void CSSFontFace::fontLoaded(RemoteFontFaceSource* source)
{
- if (source != m_activeSource)
+ if (!isValid() || source != m_sources.first())
return;
- m_activeSource = 0;
- // FIXME: Can we assert that m_segmentedFontFace is non-null? That may
- // require stopping in-progress font loading when the last
- // CSSSegmentedFontFace is removed.
- if (!m_segmentedFontFace)
- return;
-
- CSSFontSelector* fontSelector = m_segmentedFontFace->fontSelector();
- fontSelector->fontLoaded();
-
- if (fontSelector->document() && loadStatus() == FontFace::Loading) {
+ if (loadStatus() == FontFace::Loading) {
if (source->ensureFontData()) {
setLoadStatus(FontFace::Loaded);
- if (source->isSVGFontFaceSource())
- UseCounter::count(*fontSelector->document(), UseCounter::SVGFontInCSS);
+#if ENABLE(SVG_FONTS)
+ Document* document = m_segmentedFontFace ? m_segmentedFontFace->fontSelector()->document() : 0;
+ if (document && source->isSVGFontFaceSource())
+ UseCounter::count(*document, UseCounter::SVGFontInCSS);
+#endif
+ } else {
+ m_sources.removeFirst();
+ load();
}
- else if (!isValid())
- setLoadStatus(FontFace::Error);
}
- m_segmentedFontFace->fontLoaded(this);
+ if (m_segmentedFontFace)
+ m_segmentedFontFace->fontLoaded(this);
+}
+
+void CSSFontFace::fontLoadWaitLimitExceeded(RemoteFontFaceSource* source)
+{
+ if (!isValid() || source != m_sources.first())
+ return;
+ if (m_segmentedFontFace)
+ m_segmentedFontFace->fontLoadWaitLimitExceeded(this);
}
PassRefPtr<SimpleFontData> CSSFontFace::getFontData(const FontDescription& fontDescription)
{
- m_activeSource = 0;
if (!isValid())
- return 0;
+ return nullptr;
- size_t size = m_sources.size();
- for (size_t i = 0; i < size; ++i) {
- if (RefPtr<SimpleFontData> result = m_sources[i]->getFontData(fontDescription)) {
- m_activeSource = m_sources[i].get();
- if (loadStatus() == FontFace::Unloaded && (m_sources[i]->isLoading() || m_sources[i]->isLoaded()))
+ while (!m_sources.isEmpty()) {
+ OwnPtrWillBeMember<CSSFontFaceSource>& source = m_sources.first();
+ if (RefPtr<SimpleFontData> result = source->getFontData(fontDescription)) {
+ if (loadStatus() == FontFace::Unloaded && (source->isLoading() || source->isLoaded()))
setLoadStatus(FontFace::Loading);
- if (loadStatus() == FontFace::Loading && m_sources[i]->isLoaded())
+ if (loadStatus() == FontFace::Loading && source->isLoaded())
setLoadStatus(FontFace::Loaded);
return result.release();
}
+ m_sources.removeFirst();
}
if (loadStatus() == FontFace::Unloaded)
setLoadStatus(FontFace::Loading);
if (loadStatus() == FontFace::Loading)
setLoadStatus(FontFace::Error);
- return 0;
+ return nullptr;
}
-void CSSFontFace::willUseFontData(const FontDescription& fontDescription)
+bool CSSFontFace::maybeScheduleFontLoad(const FontDescription& fontDescription, UChar32 character)
{
- if (loadStatus() != FontFace::Unloaded || m_activeSource)
- return;
-
- // Kicks off font load here only if the @font-face has no unicode-range.
- // @font-faces with unicode-range will be loaded when a GlyphPage for the
- // font is created.
- // FIXME: Pass around the text to render from RenderText, and kick download
- // if m_ranges intersects with the text. Make sure this does not cause
- // performance regression.
- if (!m_ranges.isEntireRange())
- return;
+ if (m_ranges.contains(character)) {
+ if (loadStatus() == FontFace::Unloaded)
+ load(fontDescription);
+ return true;
+ }
+ return false;
+}
- ASSERT(m_segmentedFontFace);
+void CSSFontFace::load()
+{
+ FontDescription fontDescription;
+ FontFamily fontFamily;
+ fontFamily.setFamily(m_fontFace->family());
+ fontDescription.setFamily(fontFamily);
+ fontDescription.setTraits(m_fontFace->traits());
+ load(fontDescription);
+}
- size_t size = m_sources.size();
- for (size_t i = 0; i < size; ++i) {
- if (!m_sources[i]->isValid() || (m_sources[i]->isLocal() && !m_sources[i]->isLocalFontAvailable(fontDescription)))
- continue;
- if (!m_sources[i]->isLocal() && !m_sources[i]->isLoaded()) {
- m_activeSource = m_sources[i].get();
- beginLoadIfNeeded(m_activeSource);
+void CSSFontFace::load(const FontDescription& fontDescription)
+{
+ if (loadStatus() == FontFace::Unloaded)
+ setLoadStatus(FontFace::Loading);
+ ASSERT(loadStatus() == FontFace::Loading);
+
+ while (!m_sources.isEmpty()) {
+ OwnPtrWillBeMember<CSSFontFaceSource>& source = m_sources.first();
+ if (source->isValid()) {
+ if (source->isLocal()) {
+ if (source->isLocalFontAvailable(fontDescription)) {
+ setLoadStatus(FontFace::Loaded);
+ return;
+ }
+ } else {
+ if (!source->isLoaded())
+ source->beginLoadIfNeeded();
+ else
+ setLoadStatus(FontFace::Loaded);
+ return;
+ }
}
- break;
+ m_sources.removeFirst();
}
+ setLoadStatus(FontFace::Error);
}
void CSSFontFace::setLoadStatus(FontFace::LoadStatus newStatus)
@@ -199,38 +171,76 @@ void CSSFontFace::setLoadStatus(FontFace::LoadStatus newStatus)
switch (newStatus) {
case FontFace::Loading:
- FontFaceSet::from(document)->beginFontLoading(m_fontFace.get());
+ FontFaceSet::from(*document)->beginFontLoading(m_fontFace);
break;
case FontFace::Loaded:
- FontFaceSet::from(document)->fontLoaded(m_fontFace.get());
+ FontFaceSet::from(*document)->fontLoaded(m_fontFace);
break;
case FontFace::Error:
- FontFaceSet::from(document)->loadError(m_fontFace.get());
+ FontFaceSet::from(*document)->loadError(m_fontFace);
break;
default:
break;
}
}
+CSSFontFace::UnicodeRangeSet::UnicodeRangeSet(const Vector<UnicodeRange>& ranges)
+ : m_ranges(ranges)
+{
+ if (m_ranges.isEmpty())
+ return;
+
+ std::sort(m_ranges.begin(), m_ranges.end());
+
+ // Unify overlapping ranges.
+ UChar32 from = m_ranges[0].from();
+ UChar32 to = m_ranges[0].to();
+ size_t targetIndex = 0;
+ for (size_t i = 1; i < m_ranges.size(); i++) {
+ if (to + 1 >= m_ranges[i].from()) {
+ to = std::max(to, m_ranges[i].to());
+ } else {
+ m_ranges[targetIndex++] = UnicodeRange(from, to);
+ from = m_ranges[i].from();
+ to = m_ranges[i].to();
+ }
+ }
+ m_ranges[targetIndex++] = UnicodeRange(from, to);
+ m_ranges.shrink(targetIndex);
+}
+
+bool CSSFontFace::UnicodeRangeSet::contains(UChar32 c) const
+{
+ if (isEntireRange())
+ return true;
+ Vector<UnicodeRange>::const_iterator it = std::lower_bound(m_ranges.begin(), m_ranges.end(), c);
+ return it != m_ranges.end() && it->contains(c);
+}
+
bool CSSFontFace::UnicodeRangeSet::intersectsWith(const String& text) const
{
if (text.isEmpty())
return false;
if (isEntireRange())
return true;
+ if (text.is8Bit() && m_ranges[0].from() >= 0x100)
+ return false;
- // FIXME: This takes O(text.length() * m_ranges.size()) time. It would be
- // better to make m_ranges sorted and use binary search.
unsigned index = 0;
while (index < text.length()) {
UChar32 c = text.characterStartingAt(index);
index += U16_LENGTH(c);
- for (unsigned i = 0; i < m_ranges.size(); i++) {
- if (m_ranges[i].contains(c))
- return true;
- }
+ if (contains(c))
+ return true;
}
return false;
}
+void CSSFontFace::trace(Visitor* visitor)
+{
+ visitor->trace(m_segmentedFontFace);
+ visitor->trace(m_sources);
+ visitor->trace(m_fontFace);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFace.h b/chromium/third_party/WebKit/Source/core/css/CSSFontFace.h
index e4ad5f048a1..96ddbf52601 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFace.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFace.h
@@ -27,44 +27,49 @@
#define CSSFontFace_h
#include "core/css/CSSFontFaceSource.h"
+#include "core/css/CSSSegmentedFontFace.h"
#include "core/css/FontFace.h"
+#include "wtf/Deque.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
namespace WebCore {
-class CSSSegmentedFontFace;
+class CSSFontSelector;
class Document;
class FontDescription;
+class RemoteFontFaceSource;
class SimpleFontData;
class StyleRuleFontFace;
-// FIXME: Can this be a subclass of FontFace?
-class CSSFontFace : public RefCounted<CSSFontFace> {
+class CSSFontFace FINAL : public NoBaseWillBeGarbageCollectedFinalized<CSSFontFace> {
public:
- static PassRefPtr<CSSFontFace> create(PassRefPtr<FontFace> fontFace) { return adoptRef(new CSSFontFace(fontFace)); }
- static PassRefPtr<CSSFontFace> createFromStyleRule(Document*, const StyleRuleFontFace*);
-
+ struct UnicodeRange;
class UnicodeRangeSet;
- ~CSSFontFace();
+ CSSFontFace(FontFace* fontFace, Vector<UnicodeRange>& ranges)
+ : m_ranges(ranges)
+ , m_segmentedFontFace(nullptr)
+ , m_fontFace(fontFace)
+ {
+ ASSERT(m_fontFace);
+ }
- FontFace* fontFace() const { return m_fontFace.get(); }
+ FontFace* fontFace() const { return m_fontFace; }
UnicodeRangeSet& ranges() { return m_ranges; }
void setSegmentedFontFace(CSSSegmentedFontFace*);
- void clearSegmentedFontFace() { m_segmentedFontFace = 0; }
+ void clearSegmentedFontFace() { m_segmentedFontFace = nullptr; }
- bool isLoaded() const;
- bool isValid() const;
+ bool isValid() const { return !m_sources.isEmpty(); }
- void addSource(PassOwnPtr<CSSFontFaceSource>);
+ void addSource(PassOwnPtrWillBeRawPtr<CSSFontFaceSource>);
- void beginLoadIfNeeded(CSSFontFaceSource*);
- void fontLoaded(CSSFontFaceSource*);
+ void didBeginLoad();
+ void fontLoaded(RemoteFontFaceSource*);
+ void fontLoadWaitLimitExceeded(RemoteFontFaceSource*);
PassRefPtr<SimpleFontData> getFontData(const FontDescription&);
@@ -78,6 +83,8 @@ public:
UChar32 from() const { return m_from; }
UChar32 to() const { return m_to; }
bool contains(UChar32 c) const { return m_from <= c && c <= m_to; }
+ bool operator<(const UnicodeRange& other) const { return m_from < other.m_from; }
+ bool operator<(UChar32 c) const { return m_to < c; }
private:
UChar32 m_from;
@@ -86,7 +93,8 @@ public:
class UnicodeRangeSet {
public:
- void add(UChar32 from, UChar32 to) { m_ranges.append(UnicodeRange(from, to)); }
+ explicit UnicodeRangeSet(const Vector<UnicodeRange>&);
+ bool contains(UChar32) const;
bool intersectsWith(const String&) const;
bool isEntireRange() const { return m_ranges.isEmpty(); }
size_t size() const { return m_ranges.size(); }
@@ -96,23 +104,21 @@ public:
};
FontFace::LoadStatus loadStatus() const { return m_fontFace->loadStatus(); }
- void willUseFontData(const FontDescription&);
+ bool maybeScheduleFontLoad(const FontDescription&, UChar32);
+ void load();
+ void load(const FontDescription&);
+
+ bool hadBlankText() { return isValid() && m_sources.first()->hadBlankText(); }
+
+ void trace(Visitor*);
private:
- CSSFontFace(PassRefPtr<FontFace> fontFace)
- : m_segmentedFontFace(0)
- , m_activeSource(0)
- , m_fontFace(fontFace)
- {
- ASSERT(m_fontFace);
- }
void setLoadStatus(FontFace::LoadStatus);
UnicodeRangeSet m_ranges;
- CSSSegmentedFontFace* m_segmentedFontFace;
- Vector<OwnPtr<CSSFontFaceSource> > m_sources;
- CSSFontFaceSource* m_activeSource;
- RefPtr<FontFace> m_fontFace;
+ RawPtrWillBeMember<CSSSegmentedFontFace> m_segmentedFontFace;
+ WillBeHeapDeque<OwnPtrWillBeMember<CSSFontFaceSource> > m_sources;
+ RawPtrWillBeMember<FontFace> m_fontFace;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.cpp
index 95aa3b27328..5d0d06b1d96 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.cpp
@@ -61,4 +61,10 @@ const AtomicString& CSSFontFaceLoadEvent::interfaceName() const
return EventNames::CSSFontFaceLoadEvent;
}
+void CSSFontFaceLoadEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_fontfaces);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.h b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.h
index e77ca32e86b..8597efc2b24 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceLoadEvent.h
@@ -34,7 +34,6 @@
#include "core/css/FontFace.h"
#include "core/dom/DOMError.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -44,28 +43,30 @@ struct CSSFontFaceLoadEventInit : public EventInit {
FontFaceArray fontfaces;
};
-class CSSFontFaceLoadEvent : public Event {
+class CSSFontFaceLoadEvent FINAL : public Event {
public:
- static PassRefPtr<CSSFontFaceLoadEvent> create()
+ static PassRefPtrWillBeRawPtr<CSSFontFaceLoadEvent> create()
{
- return adoptRef<CSSFontFaceLoadEvent>(new CSSFontFaceLoadEvent());
+ return adoptRefWillBeNoop(new CSSFontFaceLoadEvent());
}
- static PassRefPtr<CSSFontFaceLoadEvent> create(const AtomicString& type, const CSSFontFaceLoadEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<CSSFontFaceLoadEvent> create(const AtomicString& type, const CSSFontFaceLoadEventInit& initializer)
{
- return adoptRef<CSSFontFaceLoadEvent>(new CSSFontFaceLoadEvent(type, initializer));
+ return adoptRefWillBeNoop(new CSSFontFaceLoadEvent(type, initializer));
}
- static PassRefPtr<CSSFontFaceLoadEvent> createForFontFaces(const AtomicString& type, const FontFaceArray& fontfaces = FontFaceArray())
+ static PassRefPtrWillBeRawPtr<CSSFontFaceLoadEvent> createForFontFaces(const AtomicString& type, const FontFaceArray& fontfaces = FontFaceArray())
{
- return adoptRef<CSSFontFaceLoadEvent>(new CSSFontFaceLoadEvent(type, fontfaces));
+ return adoptRefWillBeNoop(new CSSFontFaceLoadEvent(type, fontfaces));
}
virtual ~CSSFontFaceLoadEvent();
FontFaceArray fontfaces() const { return m_fontfaces; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
CSSFontFaceLoadEvent();
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.cpp
index d6357bd3250..276ffbfc578 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.cpp
@@ -37,8 +37,10 @@ CSSFontFaceRule::CSSFontFaceRule(StyleRuleFontFace* fontFaceRule, CSSStyleSheet*
CSSFontFaceRule::~CSSFontFaceRule()
{
+#if !ENABLE(OILPAN)
if (m_propertiesCSSOMWrapper)
m_propertiesCSSOMWrapper->clearParentRule();
+#endif
}
CSSStyleDeclaration* CSSFontFaceRule::style() const
@@ -52,7 +54,7 @@ String CSSFontFaceRule::cssText() const
{
StringBuilder result;
result.appendLiteral("@font-face { ");
- String descs = m_fontFaceRule->properties()->asText();
+ String descs = m_fontFaceRule->properties().asText();
result.append(descs);
if (!descs.isEmpty())
result.append(' ');
@@ -68,4 +70,11 @@ void CSSFontFaceRule::reattach(StyleRuleBase* rule)
m_propertiesCSSOMWrapper->reattach(m_fontFaceRule->mutableProperties());
}
+void CSSFontFaceRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_fontFaceRule);
+ visitor->trace(m_propertiesCSSOMWrapper);
+ CSSRule::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.h b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.h
index 0b88f9b2eee..866389828bd 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceRule.h
@@ -23,6 +23,7 @@
#define CSSFontFaceRule_h
#include "core/css/CSSRule.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -30,9 +31,12 @@ class CSSStyleDeclaration;
class StyleRuleFontFace;
class StyleRuleCSSStyleDeclaration;
-class CSSFontFaceRule : public CSSRule {
+class CSSFontFaceRule FINAL : public CSSRule {
public:
- static PassRefPtr<CSSFontFaceRule> create(StyleRuleFontFace* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSFontFaceRule(rule, sheet)); }
+ static PassRefPtrWillBeRawPtr<CSSFontFaceRule> create(StyleRuleFontFace* rule, CSSStyleSheet* sheet)
+ {
+ return adoptRefWillBeNoop(new CSSFontFaceRule(rule, sheet));
+ }
virtual ~CSSFontFaceRule();
@@ -44,11 +48,13 @@ public:
StyleRuleFontFace* styleRule() const { return m_fontFaceRule.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSFontFaceRule(StyleRuleFontFace*, CSSStyleSheet* parent);
- RefPtr<StyleRuleFontFace> m_fontFaceRule;
- mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
+ RefPtrWillBeMember<StyleRuleFontFace> m_fontFaceRule;
+ mutable RefPtrWillBeMember<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
};
DEFINE_CSS_RULE_TYPE_CASTS(CSSFontFaceRule, FONT_FACE_RULE);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.cpp
index d235aea7edf..39dfcd7c291 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.cpp
@@ -26,292 +26,46 @@
#include "config.h"
#include "core/css/CSSFontFaceSource.h"
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/CSSCustomFontData.h"
#include "core/css/CSSFontFace.h"
-#include "platform/fonts/FontCache.h"
+#include "platform/fonts/FontCacheKey.h"
#include "platform/fonts/FontDescription.h"
#include "platform/fonts/SimpleFontData.h"
-#include "public/platform/Platform.h"
-#include "wtf/CurrentTime.h"
-
-#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
-#include "core/svg/SVGFontData.h"
-#include "core/svg/SVGFontElement.h"
-#include "core/svg/SVGFontFaceElement.h"
-#endif
namespace WebCore {
-CSSFontFaceSource::CSSFontFaceSource(const String& str, FontResource* font)
- : m_string(str)
- , m_font(font)
- , m_face(0)
-#if ENABLE(SVG_FONTS)
- , m_hasExternalSVGFont(false)
-#endif
+CSSFontFaceSource::CSSFontFaceSource()
+ : m_face(nullptr)
{
- if (m_font)
- m_font->addClient(this);
}
CSSFontFaceSource::~CSSFontFaceSource()
{
- if (m_font)
- m_font->removeClient(this);
- pruneTable();
-}
-
-void CSSFontFaceSource::pruneTable()
-{
- if (m_fontDataTable.isEmpty())
- return;
-
- for (FontDataTable::iterator it = m_fontDataTable.begin(); it != m_fontDataTable.end(); ++it) {
- SimpleFontData* fontData = it->value.get();
- if (fontData && fontData->customFontData())
- fontData->customFontData()->clearCSSFontFaceSource();
- }
- m_fontDataTable.clear();
-}
-
-bool CSSFontFaceSource::isLocal() const
-{
- if (m_font)
- return false;
-#if ENABLE(SVG_FONTS)
- if (m_svgFontFaceElement)
- return false;
-#endif
- return true;
-}
-
-bool CSSFontFaceSource::isLoading() const
-{
- if (m_font)
- return !m_font->stillNeedsLoad() && !m_font->isLoaded();
- return false;
-}
-
-bool CSSFontFaceSource::isLoaded() const
-{
- if (m_font)
- return m_font->isLoaded();
- return true;
-}
-
-bool CSSFontFaceSource::isValid() const
-{
- if (m_font)
- return !m_font->errorOccurred();
- return true;
-}
-
-void CSSFontFaceSource::didStartFontLoad(FontResource*)
-{
- // Avoid duplicated reports when multiple CSSFontFaceSource are registered
- // at this FontResource.
- if (!m_fontDataTable.isEmpty())
- m_histograms.loadStarted();
-}
-
-void CSSFontFaceSource::fontLoaded(FontResource*)
-{
- if (!m_fontDataTable.isEmpty())
- m_histograms.recordRemoteFont(m_font.get());
-
- pruneTable();
- if (m_face)
- m_face->fontLoaded(this);
}
PassRefPtr<SimpleFontData> CSSFontFaceSource::getFontData(const FontDescription& fontDescription)
{
// If the font hasn't loaded or an error occurred, then we've got nothing.
if (!isValid())
- return 0;
+ return nullptr;
if (isLocal()) {
// We're local. Just return a SimpleFontData from the normal cache.
- // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter.
- RefPtr<SimpleFontData> fontData = FontCache::fontCache()->getFontData(fontDescription, m_string, true);
- m_histograms.recordLocalFont(fontData);
- return fontData;
+ return createFontData(fontDescription);
}
// See if we have a mapping in our FontData cache.
AtomicString emptyFontFamily = "";
FontCacheKey key = fontDescription.cacheKey(emptyFontFamily);
- RefPtr<SimpleFontData>& fontData = m_fontDataTable.add(key.hash(), 0).iterator->value;
- if (fontData)
- return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable.
-
- // If we are still loading, then we let the system pick a font.
- if (isLoaded()) {
- if (m_font) {
-#if ENABLE(SVG_FONTS)
- if (m_hasExternalSVGFont) {
- // For SVG fonts parse the external SVG document, and extract the <font> element.
- if (!m_font->ensureSVGFontData())
- return 0;
-
- if (!m_externalSVGFontElement) {
- String fragmentIdentifier;
- size_t start = m_string.find('#');
- if (start != kNotFound)
- fragmentIdentifier = m_string.string().substring(start + 1);
- m_externalSVGFontElement = m_font->getSVGFontById(fragmentIdentifier);
- }
-
- if (!m_externalSVGFontElement)
- return 0;
-
- SVGFontFaceElement* fontFaceElement = 0;
-
- // Select first <font-face> child
- for (Node* fontChild = m_externalSVGFontElement->firstChild(); fontChild; fontChild = fontChild->nextSibling()) {
- if (fontChild->hasTagName(SVGNames::font_faceTag)) {
- fontFaceElement = toSVGFontFaceElement(fontChild);
- break;
- }
- }
-
- if (fontFaceElement) {
- if (!m_svgFontFaceElement) {
- // We're created using a CSS @font-face rule, that means we're not associated with a SVGFontFaceElement.
- // Use the imported <font-face> tag as referencing font-face element for these cases.
- m_svgFontFaceElement = fontFaceElement;
- }
-
- fontData = SimpleFontData::create(
- SVGFontData::create(fontFaceElement),
- fontDescription.effectiveFontSize(),
- fontDescription.isSyntheticBold(),
- fontDescription.isSyntheticItalic());
- }
- } else
-#endif
- {
- // Create new FontPlatformData from our CGFontRef, point size and ATSFontRef.
- if (!m_font->ensureCustomFontData())
- return 0;
-
- fontData = SimpleFontData::create(
- m_font->platformDataFromCustomData(fontDescription.effectiveFontSize(),
- fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic(),
- fontDescription.orientation(), fontDescription.widthVariant()), CustomFontData::create(false));
- }
- } else {
-#if ENABLE(SVG_FONTS)
- // In-Document SVG Fonts
- if (m_svgFontFaceElement) {
- fontData = SimpleFontData::create(
- SVGFontData::create(m_svgFontFaceElement.get()),
- fontDescription.effectiveFontSize(),
- fontDescription.isSyntheticBold(),
- fontDescription.isSyntheticItalic());
- }
-#endif
- }
- } else {
- // This temporary font is not retained and should not be returned.
- FontCachePurgePreventer fontCachePurgePreventer;
- SimpleFontData* temporaryFont = FontCache::fontCache()->getNonRetainedLastResortFallbackFont(fontDescription);
- RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create(true);
- cssFontData->setCSSFontFaceSource(this);
- fontData = SimpleFontData::create(temporaryFont->platformData(), cssFontData);
- }
-
+ RefPtr<SimpleFontData>& fontData = m_fontDataTable.add(key.hash(), nullptr).storedValue->value;
+ if (!fontData)
+ fontData = createFontData(fontDescription);
return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable.
}
-#if ENABLE(SVG_FONTS)
-SVGFontFaceElement* CSSFontFaceSource::svgFontFaceElement() const
-{
- return m_svgFontFaceElement.get();
-}
-
-void CSSFontFaceSource::setSVGFontFaceElement(PassRefPtr<SVGFontFaceElement> element)
-{
- m_svgFontFaceElement = element;
-}
-
-bool CSSFontFaceSource::isSVGFontFaceSource() const
-{
- return m_svgFontFaceElement || m_hasExternalSVGFont;
-}
-#endif
-
-bool CSSFontFaceSource::ensureFontData()
-{
- if (!m_font)
- return false;
-#if ENABLE(SVG_FONTS)
- if (m_hasExternalSVGFont)
- return m_font->ensureSVGFontData();
-#endif
- return m_font->ensureCustomFontData();
-}
-
-bool CSSFontFaceSource::isLocalFontAvailable(const FontDescription& fontDescription)
-{
- if (!isLocal())
- return false;
- return FontCache::fontCache()->isPlatformFontAvailable(fontDescription, m_string);
-}
-
-void CSSFontFaceSource::beginLoadIfNeeded()
+void CSSFontFaceSource::trace(Visitor* visitor)
{
- if (m_face && m_font)
- m_face->beginLoadIfNeeded(this);
-}
-
-void CSSFontFaceSource::FontLoadHistograms::loadStarted()
-{
- if (!m_loadStartTime)
- m_loadStartTime = currentTimeMS();
-}
-
-void CSSFontFaceSource::FontLoadHistograms::recordLocalFont(bool loadSuccess)
-{
- if (!m_loadStartTime) {
- blink::Platform::current()->histogramEnumeration("WebFont.LocalFontUsed", loadSuccess ? 1 : 0, 2);
- m_loadStartTime = -1; // Do not count this font again.
- }
-}
-
-void CSSFontFaceSource::FontLoadHistograms::recordRemoteFont(const FontResource* font)
-{
- if (m_loadStartTime > 0 && font && !font->isLoading()) {
- int duration = static_cast<int>(currentTimeMS() - m_loadStartTime);
- blink::Platform::current()->histogramCustomCounts(histogramName(font), duration, 0, 10000, 50);
- m_loadStartTime = -1;
-
- enum { Miss, Hit, DataUrl, CacheHitEnumMax };
- int histogramValue = font->url().protocolIsData() ? DataUrl
- : font->response().wasCached() ? Hit
- : Miss;
- blink::Platform::current()->histogramEnumeration("WebFont.CacheHit", histogramValue, CacheHitEnumMax);
- }
-}
-
-const char* CSSFontFaceSource::FontLoadHistograms::histogramName(const FontResource* font)
-{
- if (font->errorOccurred())
- return "WebFont.DownloadTime.LoadError";
-
- unsigned size = font->encodedSize();
- if (size < 10 * 1024)
- return "WebFont.DownloadTime.0.Under10KB";
- if (size < 50 * 1024)
- return "WebFont.DownloadTime.1.10KBTo50KB";
- if (size < 100 * 1024)
- return "WebFont.DownloadTime.2.50KBTo100KB";
- if (size < 1024 * 1024)
- return "WebFont.DownloadTime.3.100KBTo1MB";
- return "WebFont.DownloadTime.4.Over1MB";
+ visitor->trace(m_face);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.h b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.h
index 8ba3f027534..47da18a1ae2 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSource.h
@@ -26,11 +26,8 @@
#ifndef CSSFontFaceSource_h
#define CSSFontFaceSource_h
-#include "core/fetch/FontResource.h"
-#include "core/fetch/ResourcePtr.h"
-#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
-#include "wtf/text/AtomicString.h"
namespace WebCore {
@@ -38,69 +35,37 @@ class FontResource;
class CSSFontFace;
class FontDescription;
class SimpleFontData;
-#if ENABLE(SVG_FONTS)
-class SVGFontElement;
-class SVGFontFaceElement;
-#endif
-
-class CSSFontFaceSource : public FontResourceClient {
+class CSSFontFaceSource : public NoBaseWillBeGarbageCollectedFinalized<CSSFontFaceSource> {
public:
- CSSFontFaceSource(const String&, FontResource* = 0);
virtual ~CSSFontFaceSource();
- bool isLocal() const;
- bool isLoading() const;
- bool isLoaded() const;
- bool isValid() const;
+ virtual bool isLocal() const { return false; }
+ virtual bool isLoading() const { return false; }
+ virtual bool isLoaded() const { return true; }
+ virtual bool isValid() const { return true; }
- FontResource* resource() { return m_font.get(); }
+ virtual FontResource* resource() { return 0; }
void setFontFace(CSSFontFace* face) { m_face = face; }
- virtual void didStartFontLoad(FontResource*) OVERRIDE;
- virtual void fontLoaded(FontResource*);
-
PassRefPtr<SimpleFontData> getFontData(const FontDescription&);
-#if ENABLE(SVG_FONTS)
- SVGFontFaceElement* svgFontFaceElement() const;
- void setSVGFontFaceElement(PassRefPtr<SVGFontFaceElement>);
- bool isSVGFontFaceSource() const;
- void setHasExternalSVGFont(bool value) { m_hasExternalSVGFont = value; }
-#endif
+ virtual bool isLocalFontAvailable(const FontDescription&) { return false; }
+ virtual void beginLoadIfNeeded() { }
- bool ensureFontData();
- bool isLocalFontAvailable(const FontDescription&);
- void beginLoadIfNeeded();
+ // For UMA reporting
+ virtual bool hadBlankText() { return false; }
+
+ virtual void trace(Visitor*);
+
+protected:
+ CSSFontFaceSource();
+ virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) = 0;
-private:
typedef HashMap<unsigned, RefPtr<SimpleFontData> > FontDataTable; // The hash key is composed of size synthetic styles.
- class FontLoadHistograms {
- public:
- FontLoadHistograms() : m_loadStartTime(0) { }
- void loadStarted();
- void recordLocalFont(bool loadSuccess);
- void recordRemoteFont(const FontResource*);
- private:
- const char* histogramName(const FontResource*);
- double m_loadStartTime;
- };
-
- void pruneTable();
- void startLoadingTimerFired(Timer<CSSFontFaceSource>*);
-
- AtomicString m_string; // URI for remote, built-in font name for local.
- ResourcePtr<FontResource> m_font; // For remote fonts, a pointer to our cached resource.
- CSSFontFace* m_face; // Our owning font face.
+ RawPtrWillBeMember<CSSFontFace> m_face; // Our owning font face.
FontDataTable m_fontDataTable;
- FontLoadHistograms m_histograms;
-
-#if ENABLE(SVG_FONTS)
- RefPtr<SVGFontFaceElement> m_svgFontFaceElement;
- RefPtr<SVGFontElement> m_externalSVGFontElement;
- bool m_hasExternalSVGFont;
-#endif
};
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp
index 9e7f212554a..f0cde2c59ab 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/css/CSSFontFaceSrcValue.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/Document.h"
#include "core/dom/Node.h"
@@ -81,12 +81,6 @@ String CSSFontFaceSrcValue::customCSSText() const
return result.toString();
}
-void CSSFontFaceSrcValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const
-{
- if (!isLocal())
- addSubresourceURL(urls, styleSheet->completeURL(m_resource));
-}
-
bool CSSFontFaceSrcValue::hasFailedOrCanceledSubresources() const
{
if (!m_fetched)
@@ -94,15 +88,44 @@ bool CSSFontFaceSrcValue::hasFailedOrCanceledSubresources() const
return m_fetched->loadFailedOrCanceled();
}
+bool CSSFontFaceSrcValue::shouldSetCrossOriginAccessControl(const KURL& resource, SecurityOrigin* securityOrigin)
+{
+ if (resource.isLocalFile() || resource.protocolIsData())
+ return false;
+ return !securityOrigin->canRequest(resource);
+}
+
FontResource* CSSFontFaceSrcValue::fetch(Document* document)
{
if (!m_fetched) {
FetchRequest request(ResourceRequest(document->completeURL(m_resource)), FetchInitiatorTypeNames::css);
+ SecurityOrigin* securityOrigin = document->securityOrigin();
+ if (shouldSetCrossOriginAccessControl(request.url(), securityOrigin)) {
+ request.setCrossOriginAccessControl(securityOrigin, DoNotAllowStoredCredentials);
+ }
+ request.mutableResourceRequest().setHTTPReferrer(m_referrer);
m_fetched = document->fetcher()->fetchFont(request);
+ } else {
+ // FIXME: CSSFontFaceSrcValue::fetch is invoked when @font-face rule
+ // is processed by StyleResolver / StyleEngine.
+ restoreCachedResourceIfNeeded(document);
}
return m_fetched.get();
}
+void CSSFontFaceSrcValue::restoreCachedResourceIfNeeded(Document* document)
+{
+ ASSERT(m_fetched);
+ ASSERT(document && document->fetcher());
+
+ const String resourceURL = document->completeURL(m_resource);
+ if (document->fetcher()->cachedResource(KURL(ParsedURLString, resourceURL)))
+ return;
+
+ FetchRequest request(ResourceRequest(resourceURL), FetchInitiatorTypeNames::css);
+ document->fetcher()->requestLoadStarted(m_fetched.get(), request, ResourceFetcher::ResourceLoadingFromCache);
+}
+
bool CSSFontFaceSrcValue::equals(const CSSFontFaceSrcValue& other) const
{
return m_isLocal == other.m_isLocal && m_format == other.m_format && m_resource == other.m_resource;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.h b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.h
index 1be94d687ff..83f26f7ee64 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceSrcValue.h
@@ -28,6 +28,7 @@
#include "core/css/CSSValue.h"
#include "core/fetch/ResourcePtr.h"
+#include "platform/weborigin/Referrer.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/WTFString.h"
@@ -39,13 +40,13 @@ class SVGFontFaceElement;
class CSSFontFaceSrcValue : public CSSValue {
public:
- static PassRefPtr<CSSFontFaceSrcValue> create(const String& resource)
+ static PassRefPtrWillBeRawPtr<CSSFontFaceSrcValue> create(const String& resource)
{
- return adoptRef(new CSSFontFaceSrcValue(resource, false));
+ return adoptRefWillBeNoop(new CSSFontFaceSrcValue(resource, false));
}
- static PassRefPtr<CSSFontFaceSrcValue> createLocal(const String& resource)
+ static PassRefPtrWillBeRawPtr<CSSFontFaceSrcValue> createLocal(const String& resource)
{
- return adoptRef(new CSSFontFaceSrcValue(resource, true));
+ return adoptRefWillBeNoop(new CSSFontFaceSrcValue(resource, true));
}
const String& resource() const { return m_resource; }
@@ -53,6 +54,7 @@ public:
bool isLocal() const { return m_isLocal; }
void setFormat(const String& format) { m_format = format; }
+ void setReferrer(const Referrer& referrer) { m_referrer = referrer; }
bool isSupportedFormat() const;
@@ -65,14 +67,14 @@ public:
String customCSSText() const;
- void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
-
bool hasFailedOrCanceledSubresources() const;
FontResource* fetch(Document*);
bool equals(const CSSFontFaceSrcValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
CSSFontFaceSrcValue(const String& resource, bool local)
: CSSValue(FontFaceSrcClass)
@@ -84,8 +86,12 @@ private:
{
}
+ void restoreCachedResourceIfNeeded(Document*);
+ bool shouldSetCrossOriginAccessControl(const KURL& resource, SecurityOrigin*);
+
String m_resource;
String m_format;
+ Referrer m_referrer;
bool m_isLocal;
ResourcePtr<FontResource> m_fetched;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFaceTest.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceTest.cpp
new file mode 100644
index 00000000000..87b0bab86fd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFaceTest.cpp
@@ -0,0 +1,90 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/CSSFontFace.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+static const UChar hiraganaA[2] = { 0x3042, 0 };
+
+TEST(CSSFontFace, UnicodeRangeSetEmpty)
+{
+ Vector<CSSFontFace::UnicodeRange> ranges;
+ CSSFontFace::UnicodeRangeSet set(ranges);
+ EXPECT_TRUE(set.isEntireRange());
+ EXPECT_EQ(0u, set.size());
+ EXPECT_FALSE(set.intersectsWith(String()));
+ EXPECT_TRUE(set.intersectsWith(String("a")));
+ EXPECT_TRUE(set.intersectsWith(String(hiraganaA)));
+}
+
+TEST(CSSFontFace, UnicodeRangeSetSingleCharacter)
+{
+ Vector<CSSFontFace::UnicodeRange> ranges;
+ ranges.append(CSSFontFace::UnicodeRange('b', 'b'));
+ CSSFontFace::UnicodeRangeSet set(ranges);
+ EXPECT_FALSE(set.isEntireRange());
+ EXPECT_FALSE(set.intersectsWith(String()));
+ EXPECT_FALSE(set.intersectsWith(String("a")));
+ EXPECT_TRUE(set.intersectsWith(String("b")));
+ EXPECT_FALSE(set.intersectsWith(String("c")));
+ EXPECT_TRUE(set.intersectsWith(String("abc")));
+ EXPECT_FALSE(set.intersectsWith(String(hiraganaA)));
+ ASSERT_EQ(1u, set.size());
+ EXPECT_EQ('b', set.rangeAt(0).from());
+ EXPECT_EQ('b', set.rangeAt(0).to());
+}
+
+TEST(CSSFontFace, UnicodeRangeSetTwoRanges)
+{
+ Vector<CSSFontFace::UnicodeRange> ranges;
+ ranges.append(CSSFontFace::UnicodeRange('6', '7'));
+ ranges.append(CSSFontFace::UnicodeRange('2', '4'));
+ CSSFontFace::UnicodeRangeSet set(ranges);
+ EXPECT_FALSE(set.isEntireRange());
+ EXPECT_FALSE(set.intersectsWith(String()));
+ EXPECT_FALSE(set.intersectsWith(String("1")));
+ EXPECT_TRUE(set.intersectsWith(String("2")));
+ EXPECT_TRUE(set.intersectsWith(String("3")));
+ EXPECT_TRUE(set.intersectsWith(String("4")));
+ EXPECT_FALSE(set.intersectsWith(String("5")));
+ EXPECT_TRUE(set.intersectsWith(String("6")));
+ EXPECT_TRUE(set.intersectsWith(String("7")));
+ EXPECT_FALSE(set.intersectsWith(String("8")));
+ ASSERT_EQ(2u, set.size());
+ EXPECT_EQ('2', set.rangeAt(0).from());
+ EXPECT_EQ('4', set.rangeAt(0).to());
+ EXPECT_EQ('6', set.rangeAt(1).from());
+ EXPECT_EQ('7', set.rangeAt(1).to());
+}
+
+TEST(CSSFontFace, UnicodeRangeSetOverlap)
+{
+ Vector<CSSFontFace::UnicodeRange> ranges;
+ ranges.append(CSSFontFace::UnicodeRange('0', '2'));
+ ranges.append(CSSFontFace::UnicodeRange('1', '1'));
+ ranges.append(CSSFontFace::UnicodeRange('3', '5'));
+ ranges.append(CSSFontFace::UnicodeRange('4', '6'));
+ CSSFontFace::UnicodeRangeSet set(ranges);
+ ASSERT_EQ(1u, set.size());
+ EXPECT_EQ('0', set.rangeAt(0).from());
+ EXPECT_EQ('6', set.rangeAt(0).to());
+}
+
+TEST(CSSFontFace, UnicodeRangeSetNon8Bit)
+{
+ Vector<CSSFontFace::UnicodeRange> ranges;
+ ranges.append(CSSFontFace::UnicodeRange(0x3042, 0x3042));
+ CSSFontFace::UnicodeRangeSet set(ranges);
+ ASSERT_EQ(1u, set.size());
+ EXPECT_EQ(0x3042, set.rangeAt(0).from());
+ EXPECT_EQ(0x3042, set.rangeAt(0).to());
+ EXPECT_FALSE(set.intersectsWith(String("a")));
+ EXPECT_TRUE(set.intersectsWith(String(hiraganaA)));
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontFeatureValue.h b/chromium/third_party/WebKit/Source/core/css/CSSFontFeatureValue.h
index 8a0367fabe3..fc841792619 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontFeatureValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontFeatureValue.h
@@ -33,9 +33,9 @@ namespace WebCore {
class CSSFontFeatureValue : public CSSValue {
public:
- static PassRefPtr<CSSFontFeatureValue> create(const AtomicString& tag, int value)
+ static PassRefPtrWillBeRawPtr<CSSFontFeatureValue> create(const AtomicString& tag, int value)
{
- return adoptRef(new CSSFontFeatureValue(tag, value));
+ return adoptRefWillBeNoop(new CSSFontFeatureValue(tag, value));
}
const AtomicString& tag() const { return m_tag; }
@@ -44,6 +44,8 @@ public:
bool equals(const CSSFontFeatureValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
CSSFontFeatureValue(const AtomicString& tag, int value);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontSelector.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFontSelector.cpp
index 9b83e9e2182..2f1019c3312 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontSelector.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontSelector.cpp
@@ -27,87 +27,25 @@
#include "config.h"
#include "core/css/CSSFontSelector.h"
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/CSSFontFace.h"
-#include "core/css/CSSFontFaceRule.h"
-#include "core/css/CSSFontFaceSource.h"
+#include "core/css/CSSFontSelectorClient.h"
#include "core/css/CSSSegmentedFontFace.h"
#include "core/css/CSSValueList.h"
+#include "core/css/FontFaceSet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
-#include "core/fetch/FontResource.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/loader/FrameLoader.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/fonts/FontCache.h"
#include "platform/fonts/SimpleFontData.h"
#include "wtf/text/AtomicString.h"
-using namespace std;
-
namespace WebCore {
-FontLoader::FontLoader(ResourceFetcher* resourceFetcher)
- : m_beginLoadingTimer(this, &FontLoader::beginLoadTimerFired)
- , m_resourceFetcher(resourceFetcher)
-{
-}
-
-void FontLoader::addFontToBeginLoading(FontResource* fontResource)
-{
- if (!m_resourceFetcher || !fontResource->stillNeedsLoad())
- return;
-
- m_fontsToBeginLoading.append(fontResource);
- // FIXME: Use RequestCountTracker??!!
- // Increment the request count now, in order to prevent didFinishLoad from being dispatched
- // after this font has been requested but before it began loading. Balanced by
- // decrementRequestCount() in beginLoadTimerFired() and in clearDocument().
- m_resourceFetcher->incrementRequestCount(fontResource);
- m_beginLoadingTimer.startOneShot(0);
-}
-
-void FontLoader::beginLoadTimerFired(Timer<WebCore::FontLoader>*)
-{
- loadPendingFonts();
-}
-
-void FontLoader::loadPendingFonts()
-{
- ASSERT(m_resourceFetcher);
-
- Vector<ResourcePtr<FontResource> > fontsToBeginLoading;
- fontsToBeginLoading.swap(m_fontsToBeginLoading);
-
- for (size_t i = 0; i < fontsToBeginLoading.size(); ++i) {
- fontsToBeginLoading[i]->beginLoadIfNeeded(m_resourceFetcher);
- // Balances incrementRequestCount() in beginLoadingFontSoon().
- m_resourceFetcher->decrementRequestCount(fontsToBeginLoading[i].get());
- }
-}
-
-void FontLoader::clearResourceFetcher()
-{
- if (!m_resourceFetcher) {
- ASSERT(m_fontsToBeginLoading.isEmpty());
- return;
- }
-
- m_beginLoadingTimer.stop();
-
- for (size_t i = 0; i < m_fontsToBeginLoading.size(); ++i) {
- // Balances incrementRequestCount() in beginLoadingFontSoon().
- m_resourceFetcher->decrementRequestCount(m_fontsToBeginLoading[i].get());
- }
-
- m_fontsToBeginLoading.clear();
- m_resourceFetcher = 0;
-}
-
CSSFontSelector::CSSFontSelector(Document* document)
: m_document(document)
- , m_fontLoader(document->fetcher())
+ , m_fontLoader(FontLoader::create(this, document->fetcher()))
, m_genericFontFamilySettings(document->frame()->settings()->genericFontFamilySettings())
{
// FIXME: An old comment used to say there was no need to hold a reference to m_document
@@ -117,33 +55,38 @@ CSSFontSelector::CSSFontSelector(Document* document)
ASSERT(m_document);
ASSERT(m_document->frame());
FontCache::fontCache()->addClient(this);
+ FontFaceSet::from(*document)->addFontFacesToFontFaceCache(&m_fontFaceCache, this);
}
CSSFontSelector::~CSSFontSelector()
{
+#if !ENABLE(OILPAN)
clearDocument();
FontCache::fontCache()->removeClient(this);
+#endif
}
-void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient* client)
+void CSSFontSelector::registerForInvalidationCallbacks(CSSFontSelectorClient* client)
{
m_clients.add(client);
}
-void CSSFontSelector::unregisterForInvalidationCallbacks(FontSelectorClient* client)
+#if !ENABLE(OILPAN)
+void CSSFontSelector::unregisterForInvalidationCallbacks(CSSFontSelectorClient* client)
{
m_clients.remove(client);
}
+#endif
void CSSFontSelector::dispatchInvalidationCallbacks()
{
- Vector<FontSelectorClient*> clients;
+ WillBeHeapVector<RawPtrWillBeMember<CSSFontSelectorClient> > clients;
copyToVector(m_clients, clients);
for (size_t i = 0; i < clients.size(); ++i)
clients[i]->fontsNeedUpdate(this);
}
-void CSSFontSelector::fontLoaded()
+void CSSFontSelector::fontFaceInvalidated()
{
dispatchInvalidationCallbacks();
}
@@ -153,28 +96,18 @@ void CSSFontSelector::fontCacheInvalidated()
dispatchInvalidationCallbacks();
}
-void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, PassRefPtr<CSSFontFace> cssFontFace)
-{
- m_cssSegmentedFontFaceCache.add(this, fontFaceRule, cssFontFace);
-}
-
-void CSSFontSelector::removeFontFaceRule(const StyleRuleFontFace* fontFaceRule)
-{
- m_cssSegmentedFontFaceCache.remove(fontFaceRule);
-}
-
static AtomicString familyNameFromSettings(const GenericFontFamilySettings& settings, const FontDescription& fontDescription, const AtomicString& genericFamilyName)
{
UScriptCode script = fontDescription.script();
#if OS(ANDROID)
- if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
+ if (fontDescription.genericFamily() == FontDescription::StandardFamily)
return FontCache::getGenericFamilyNameForScript(FontFamilyNames::webkit_standard, script);
if (genericFamilyName.startsWith("-webkit-"))
return FontCache::getGenericFamilyNameForScript(genericFamilyName, script);
#else
- if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
+ if (fontDescription.genericFamily() == FontDescription::StandardFamily)
return settings.standard(script);
if (genericFamilyName == FontFamilyNames::webkit_serif)
return settings.serif(script);
@@ -196,43 +129,56 @@ static AtomicString familyNameFromSettings(const GenericFontFamilySettings& sett
PassRefPtr<FontData> CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName)
{
- if (CSSSegmentedFontFace* face = m_cssSegmentedFontFaceCache.get(fontDescription, familyName))
+ if (CSSSegmentedFontFace* face = m_fontFaceCache.get(fontDescription, familyName))
return face->getFontData(fontDescription);
// Try to return the correct font based off our settings, in case we were handed the generic font family name.
AtomicString settingsFamilyName = familyNameFromSettings(m_genericFontFamilySettings, fontDescription, familyName);
if (settingsFamilyName.isEmpty())
- return 0;
+ return nullptr;
return FontCache::fontCache()->getFontData(fontDescription, settingsFamilyName);
}
-CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDescription, const AtomicString& familyName)
+void CSSFontSelector::willUseFontData(const FontDescription& fontDescription, const AtomicString& family, UChar32 character)
{
- return m_cssSegmentedFontFaceCache.get(fontDescription, familyName);
+ CSSSegmentedFontFace* face = m_fontFaceCache.get(fontDescription, family);
+ if (face)
+ face->willUseFontData(fontDescription, character);
}
-void CSSFontSelector::willUseFontData(const FontDescription& fontDescription, const AtomicString& family)
+bool CSSFontSelector::isPlatformFontAvailable(const FontDescription& fontDescription, const AtomicString& passedFamily)
{
- CSSSegmentedFontFace* face = getFontFace(fontDescription, family);
- if (face)
- face->willUseFontData(fontDescription);
+ AtomicString family = familyNameFromSettings(m_genericFontFamilySettings, fontDescription, passedFamily);
+ if (family.isEmpty())
+ family = passedFamily;
+ return FontCache::fontCache()->isPlatformFontAvailable(fontDescription, family);
}
+#if !ENABLE(OILPAN)
void CSSFontSelector::clearDocument()
{
- m_fontLoader.clearResourceFetcher();
- m_document = 0;
+ m_fontLoader->clearResourceFetcherAndFontSelector();
+ m_document = nullptr;
}
+#endif
-void CSSFontSelector::beginLoadingFontSoon(FontResource* font)
+void CSSFontSelector::updateGenericFontFamilySettings(Document& document)
{
- m_fontLoader.addFontToBeginLoading(font);
+ if (!document.settings())
+ return;
+ m_genericFontFamilySettings = document.settings()->genericFontFamilySettings();
+ // Need to increment FontFaceCache version to update RenderStyles.
+ m_fontFaceCache.incrementVersion();
}
-void CSSFontSelector::loadPendingFonts()
+void CSSFontSelector::trace(Visitor* visitor)
{
- m_fontLoader.loadPendingFonts();
+ visitor->trace(m_document);
+ visitor->trace(m_fontFaceCache);
+ visitor->trace(m_clients);
+ visitor->trace(m_fontLoader);
+ FontSelector::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontSelector.h b/chromium/third_party/WebKit/Source/core/css/CSSFontSelector.h
index 34d33a8809d..94e2578ca1d 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontSelector.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontSelector.h
@@ -26,11 +26,11 @@
#ifndef CSSFontSelector_h
#define CSSFontSelector_h
-#include "core/css/CSSSegmentedFontFaceCache.h"
-#include "core/fetch/ResourcePtr.h"
-#include "platform/Timer.h"
+#include "core/css/FontFaceCache.h"
+#include "core/css/FontLoader.h"
#include "platform/fonts/FontSelector.h"
#include "platform/fonts/GenericFontFamilySettings.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
@@ -39,72 +39,63 @@ namespace WebCore {
class CSSFontFace;
class CSSFontFaceRule;
+class CSSFontSelectorClient;
class CSSSegmentedFontFace;
-class FontResource;
class Document;
class FontDescription;
class StyleRuleFontFace;
-class FontLoader {
+class CSSFontSelector FINAL : public FontSelector {
public:
- explicit FontLoader(ResourceFetcher*);
-
- void addFontToBeginLoading(FontResource*);
- void loadPendingFonts();
-
- void clearResourceFetcher();
-
-private:
- void beginLoadTimerFired(Timer<FontLoader>*);
-
- Timer<FontLoader> m_beginLoadingTimer;
- Vector<ResourcePtr<FontResource> > m_fontsToBeginLoading;
- ResourceFetcher* m_resourceFetcher;
-};
-
-class CSSFontSelector : public FontSelector {
-public:
- static PassRefPtr<CSSFontSelector> create(Document* document)
+ static PassRefPtrWillBeRawPtr<CSSFontSelector> create(Document* document)
{
- return adoptRef(new CSSFontSelector(document));
+ return adoptRefWillBeNoop(new CSSFontSelector(document));
}
virtual ~CSSFontSelector();
- virtual unsigned version() const OVERRIDE { return m_cssSegmentedFontFaceCache.version(); }
+ virtual unsigned version() const OVERRIDE { return m_fontFaceCache.version(); }
- virtual PassRefPtr<FontData> getFontData(const FontDescription&, const AtomicString&);
- CSSSegmentedFontFace* getFontFace(const FontDescription&, const AtomicString& family);
- virtual void willUseFontData(const FontDescription&, const AtomicString& family) OVERRIDE;
+ virtual PassRefPtr<FontData> getFontData(const FontDescription&, const AtomicString&) OVERRIDE;
+ virtual void willUseFontData(const FontDescription&, const AtomicString& family, UChar32) OVERRIDE;
+ bool isPlatformFontAvailable(const FontDescription&, const AtomicString& family);
+#if !ENABLE(OILPAN)
void clearDocument();
+#endif
- void addFontFaceRule(const StyleRuleFontFace*, PassRefPtr<CSSFontFace>);
- void removeFontFaceRule(const StyleRuleFontFace*);
+ void fontFaceInvalidated();
- void fontLoaded();
- virtual void fontCacheInvalidated();
+ // FontCacheClient implementation
+ virtual void fontCacheInvalidated() OVERRIDE;
- virtual void registerForInvalidationCallbacks(FontSelectorClient*);
- virtual void unregisterForInvalidationCallbacks(FontSelectorClient*);
+ void registerForInvalidationCallbacks(CSSFontSelectorClient*);
+#if !ENABLE(OILPAN)
+ void unregisterForInvalidationCallbacks(CSSFontSelectorClient*);
+#endif
Document* document() const { return m_document; }
+ FontFaceCache* fontFaceCache() { return &m_fontFaceCache; }
+ FontLoader* fontLoader() { return m_fontLoader.get(); }
const GenericFontFamilySettings& genericFontFamilySettings() const { return m_genericFontFamilySettings; }
+ void updateGenericFontFamilySettings(Document&);
- void beginLoadingFontSoon(FontResource*);
- void loadPendingFonts();
+ virtual void trace(Visitor*);
private:
explicit CSSFontSelector(Document*);
void dispatchInvalidationCallbacks();
- Document* m_document;
+ // FIXME: Oilpan: Ideally this should just be a traced Member but that will
+ // currently leak because RenderStyle and its data are not on the heap.
+ // See crbug.com/383860 for details.
+ RawPtrWillBeWeakMember<Document> m_document;
// FIXME: Move to Document or StyleEngine.
- CSSSegmentedFontFaceCache m_cssSegmentedFontFaceCache;
- HashSet<FontSelectorClient*> m_clients;
+ FontFaceCache m_fontFaceCache;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSFontSelectorClient> > m_clients;
- FontLoader m_fontLoader;
+ RefPtrWillBeMember<FontLoader> m_fontLoader;
GenericFontFamilySettings m_genericFontFamilySettings;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontSelectorClient.h b/chromium/third_party/WebKit/Source/core/css/CSSFontSelectorClient.h
new file mode 100644
index 00000000000..5a8c1c0892a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontSelectorClient.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSFontSelectorClient_h
+#define CSSFontSelectorClient_h
+
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class CSSFontSelector;
+class Visitor;
+
+class CSSFontSelectorClient : public NoBaseWillBeGarbageCollectedFinalized<CSSFontSelectorClient> {
+public:
+ virtual ~CSSFontSelectorClient() { }
+
+ virtual void fontsNeedUpdate(CSSFontSelector*) = 0;
+
+ virtual void trace(Visitor*) { }
+};
+
+} // namespace WebCore
+
+#endif // CSSFontSelectorClient_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFontValue.cpp
index aee5a9726d6..522c7f81a53 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontValue.cpp
@@ -74,4 +74,16 @@ bool CSSFontValue::equals(const CSSFontValue& other) const
&& compareCSSValuePtr(family, other.family);
}
+void CSSFontValue::traceAfterDispatch(Visitor* visitor)
+{
+
+ visitor->trace(style);
+ visitor->trace(variant);
+ visitor->trace(weight);
+ visitor->trace(size);
+ visitor->trace(lineHeight);
+ visitor->trace(family);
+ CSSValue::traceAfterDispatch(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFontValue.h b/chromium/third_party/WebKit/Source/core/css/CSSFontValue.h
index f0c99d55326..892d4e24b82 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFontValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFontValue.h
@@ -32,21 +32,23 @@ class CSSValueList;
class CSSFontValue : public CSSValue {
public:
- static PassRefPtr<CSSFontValue> create()
+ static PassRefPtrWillBeRawPtr<CSSFontValue> create()
{
- return adoptRef(new CSSFontValue);
+ return adoptRefWillBeNoop(new CSSFontValue);
}
String customCSSText() const;
bool equals(const CSSFontValue&) const;
- RefPtr<CSSPrimitiveValue> style;
- RefPtr<CSSPrimitiveValue> variant;
- RefPtr<CSSPrimitiveValue> weight;
- RefPtr<CSSPrimitiveValue> size;
- RefPtr<CSSPrimitiveValue> lineHeight;
- RefPtr<CSSValueList> family;
+ void traceAfterDispatch(Visitor*);
+
+ RefPtrWillBeMember<CSSPrimitiveValue> style;
+ RefPtrWillBeMember<CSSPrimitiveValue> variant;
+ RefPtrWillBeMember<CSSPrimitiveValue> weight;
+ RefPtrWillBeMember<CSSPrimitiveValue> size;
+ RefPtrWillBeMember<CSSPrimitiveValue> lineHeight;
+ RefPtrWillBeMember<CSSValueList> family;
private:
CSSFontValue()
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.cpp
index 7cbbf86d06f..9fb04dc43e2 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.cpp
@@ -40,7 +40,7 @@ CSSFunctionValue::CSSFunctionValue(CSSParserFunction* function)
m_args = CSSValueList::createFromParserValueList(function->args.get());
}
-CSSFunctionValue::CSSFunctionValue(String name, PassRefPtr<CSSValueList> args)
+CSSFunctionValue::CSSFunctionValue(String name, PassRefPtrWillBeRawPtr<CSSValueList> args)
: CSSValue(FunctionClass)
, m_name(name)
, m_args(args)
@@ -62,4 +62,10 @@ bool CSSFunctionValue::equals(const CSSFunctionValue& other) const
return m_name == other.m_name && compareCSSValuePtr(m_args, other.m_args);
}
+void CSSFunctionValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_args);
+ CSSValue::traceAfterDispatch(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.h b/chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.h
index 87fa8afacfb..aa678635978 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSFunctionValue.h
@@ -35,14 +35,14 @@ struct CSSParserFunction;
class CSSFunctionValue : public CSSValue {
public:
- static PassRefPtr<CSSFunctionValue> create(CSSParserFunction* function)
+ static PassRefPtrWillBeRawPtr<CSSFunctionValue> create(CSSParserFunction* function)
{
- return adoptRef(new CSSFunctionValue(function));
+ return adoptRefWillBeNoop(new CSSFunctionValue(function));
}
- static PassRefPtr<CSSFunctionValue> create(String name, PassRefPtr<CSSValueList> args)
+ static PassRefPtrWillBeRawPtr<CSSFunctionValue> create(String name, PassRefPtrWillBeRawPtr<CSSValueList> args)
{
- return adoptRef(new CSSFunctionValue(name, args));
+ return adoptRefWillBeNoop(new CSSFunctionValue(name, args));
}
String customCSSText() const;
@@ -51,12 +51,14 @@ public:
CSSValueList* arguments() const { return m_args.get(); }
+ void traceAfterDispatch(Visitor*);
+
private:
explicit CSSFunctionValue(CSSParserFunction*);
- CSSFunctionValue(String, PassRefPtr<CSSValueList>);
+ CSSFunctionValue(String, PassRefPtrWillBeRawPtr<CSSValueList>);
String m_name;
- RefPtr<CSSValueList> m_args;
+ RefPtrWillBeMember<CSSValueList> m_args;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSFunctionValue, isFunctionValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGradientValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
index 68269972045..277162fd89b 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGradientValue.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/css/CSSGradientValue.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSToLengthConversionData.h"
#include "core/dom/NodeRenderStyle.h"
@@ -39,19 +39,23 @@
#include "wtf/text/StringBuilder.h"
#include "wtf/text/WTFString.h"
-using namespace std;
-
namespace WebCore {
+void CSSGradientColorStop::trace(Visitor* visitor)
+{
+ visitor->trace(m_position);
+ visitor->trace(m_color);
+}
+
PassRefPtr<Image> CSSGradientValue::image(RenderObject* renderer, const IntSize& size)
{
if (size.isEmpty())
- return 0;
+ return nullptr;
bool cacheable = isCacheable();
if (cacheable) {
if (!clients().contains(renderer))
- return 0;
+ return nullptr;
// Need to look up our size. Create a string of width*height to use as a hash key.
Image* result = getImage(renderer, size);
@@ -63,7 +67,7 @@ PassRefPtr<Image> CSSGradientValue::image(RenderObject* renderer, const IntSize&
RefPtr<Gradient> gradient;
RenderStyle* rootStyle = renderer->document().documentElement()->renderStyle();
- CSSToLengthConversionData conversionData(renderer->style(), rootStyle);
+ CSSToLengthConversionData conversionData(renderer->style(), rootStyle, renderer->view());
if (isLinearGradientValue())
gradient = toCSSLinearGradientValue(this)->createGradient(conversionData, size);
else
@@ -106,7 +110,7 @@ struct GradientStop {
{ }
};
-PassRefPtr<CSSGradientValue> CSSGradientValue::gradientWithStylesResolved(const TextLinkColors& textLinkColors, Color currentColor)
+PassRefPtrWillBeRawPtr<CSSGradientValue> CSSGradientValue::gradientWithStylesResolved(const TextLinkColors& textLinkColors, Color currentColor)
{
bool derived = false;
for (unsigned i = 0; i < m_stops.size(); i++)
@@ -116,7 +120,7 @@ PassRefPtr<CSSGradientValue> CSSGradientValue::gradientWithStylesResolved(const
break;
}
- RefPtr<CSSGradientValue> result;
+ RefPtrWillBeRawPtr<CSSGradientValue> result = nullptr;
if (!derived)
result = this;
else if (isLinearGradientValue())
@@ -125,7 +129,7 @@ PassRefPtr<CSSGradientValue> CSSGradientValue::gradientWithStylesResolved(const
result = toCSSRadialGradientValue(this)->clone();
else {
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
for (unsigned i = 0; i < result->m_stops.size(); i++)
@@ -151,8 +155,6 @@ void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionD
gradient->addColorStop(offset, stop.m_resolvedColor);
}
- // The back end already sorted the stops.
- gradient->setStopsSorted(true);
return;
}
@@ -262,7 +264,6 @@ void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionD
stops.first().offset = 0;
stops.first().color = stops.last().color;
stops.shrink(1);
- numStops = 1;
} else {
float maxExtent = 1;
@@ -384,8 +385,6 @@ void CSSGradientValue::addStops(Gradient* gradient, const CSSToLengthConversionD
for (unsigned i = 0; i < numStops; i++)
gradient->addColorStop(stops[i].offset, stops[i].color);
-
- gradient->setStopsSorted(true);
}
static float positionFromValue(CSSPrimitiveValue* value, const CSSToLengthConversionData& conversionData, const IntSize& size, bool isHorizontal)
@@ -460,6 +459,16 @@ bool CSSGradientValue::knownToBeOpaque(const RenderObject*) const
return true;
}
+void CSSGradientValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_firstX);
+ visitor->trace(m_firstY);
+ visitor->trace(m_secondX);
+ visitor->trace(m_secondY);
+ visitor->trace(m_stops);
+ CSSImageGeneratorValue::traceAfterDispatch(visitor);
+}
+
String CSSLinearGradientValue::customCSSText() const
{
StringBuilder result;
@@ -733,6 +742,12 @@ bool CSSLinearGradientValue::equals(const CSSLinearGradientValue& other) const
return equalXandY && m_stops == other.m_stops;
}
+void CSSLinearGradientValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_angle);
+ CSSGradientValue::traceAfterDispatch(visitor);
+}
+
String CSSRadialGradientValue::customCSSText() const
{
StringBuilder result;
@@ -1039,10 +1054,10 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(const CSSToLengthCon
// Horizontal
switch (fill) {
case ClosestSide: {
- float xDist = min(secondPoint.x(), size.width() - secondPoint.x());
- float yDist = min(secondPoint.y(), size.height() - secondPoint.y());
+ float xDist = std::min(secondPoint.x(), size.width() - secondPoint.x());
+ float yDist = std::min(secondPoint.y(), size.height() - secondPoint.y());
if (shape == Circle) {
- float smaller = min(xDist, yDist);
+ float smaller = std::min(xDist, yDist);
xDist = smaller;
yDist = smaller;
}
@@ -1051,10 +1066,10 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(const CSSToLengthCon
break;
}
case FarthestSide: {
- float xDist = max(secondPoint.x(), size.width() - secondPoint.x());
- float yDist = max(secondPoint.y(), size.height() - secondPoint.y());
+ float xDist = std::max(secondPoint.x(), size.width() - secondPoint.x());
+ float yDist = std::max(secondPoint.y(), size.height() - secondPoint.y());
if (shape == Circle) {
- float larger = max(xDist, yDist);
+ float larger = std::max(xDist, yDist);
xDist = larger;
yDist = larger;
}
@@ -1070,8 +1085,8 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(const CSSToLengthCon
else {
// If <shape> is ellipse, the gradient-shape has the same ratio of width to height
// that it would if closest-side or farthest-side were specified, as appropriate.
- float xDist = min(secondPoint.x(), size.width() - secondPoint.x());
- float yDist = min(secondPoint.y(), size.height() - secondPoint.y());
+ float xDist = std::min(secondPoint.x(), size.width() - secondPoint.x());
+ float yDist = std::min(secondPoint.y(), size.height() - secondPoint.y());
secondRadius = horizontalEllipseRadius(corner - secondPoint, xDist / yDist);
aspectRatio = xDist / yDist;
@@ -1087,8 +1102,8 @@ PassRefPtr<Gradient> CSSRadialGradientValue::createGradient(const CSSToLengthCon
else {
// If <shape> is ellipse, the gradient-shape has the same ratio of width to height
// that it would if closest-side or farthest-side were specified, as appropriate.
- float xDist = max(secondPoint.x(), size.width() - secondPoint.x());
- float yDist = max(secondPoint.y(), size.height() - secondPoint.y());
+ float xDist = std::max(secondPoint.x(), size.width() - secondPoint.x());
+ float yDist = std::max(secondPoint.y(), size.height() - secondPoint.y());
secondRadius = horizontalEllipseRadius(corner - secondPoint, xDist / yDist);
aspectRatio = xDist / yDist;
@@ -1161,4 +1176,15 @@ bool CSSRadialGradientValue::equals(const CSSRadialGradientValue& other) const
return equalShape && equalSizingBehavior && equalHorizontalAndVerticalSize && m_stops == other.m_stops;
}
+void CSSRadialGradientValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_firstRadius);
+ visitor->trace(m_secondRadius);
+ visitor->trace(m_shape);
+ visitor->trace(m_sizingBehavior);
+ visitor->trace(m_endHorizontalSize);
+ visitor->trace(m_endVerticalSize);
+ CSSGradientValue::traceAfterDispatch(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGradientValue.h b/chromium/third_party/WebKit/Source/core/css/CSSGradientValue.h
index 7179b6fff80..4e3af429fc7 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSGradientValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGradientValue.h
@@ -47,10 +47,17 @@ enum CSSGradientType {
};
enum CSSGradientRepeat { NonRepeating, Repeating };
+// This struct is stack allocated and allocated as part of vectors.
+// When allocated on the stack its members are found by conservative
+// stack scanning. When allocated as part of Vectors in heap-allocated
+// objects its members are visited via the containing object's
+// (CSSGradientValue) traceAfterDispatch method.
struct CSSGradientColorStop {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
CSSGradientColorStop() : m_colorIsDerivedFromElement(false) { };
- RefPtr<CSSPrimitiveValue> m_position; // percentage or length
- RefPtr<CSSPrimitiveValue> m_color;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_position; // percentage or length
+ RefPtrWillBeMember<CSSPrimitiveValue> m_color;
Color m_resolvedColor;
bool m_colorIsDerivedFromElement;
bool operator==(const CSSGradientColorStop& other) const
@@ -58,16 +65,27 @@ struct CSSGradientColorStop {
return compareCSSValuePtr(m_color, other.m_color)
&& compareCSSValuePtr(m_position, other.m_position);
}
+
+ void trace(Visitor*);
};
+} // namespace WebCore
+
+
+// We have to declare the VectorTraits specialization before CSSGradientValue
+// declares its inline capacity vector below.
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::CSSGradientColorStop);
+
+namespace WebCore {
+
class CSSGradientValue : public CSSImageGeneratorValue {
public:
PassRefPtr<Image> image(RenderObject*, const IntSize&);
- void setFirstX(PassRefPtr<CSSPrimitiveValue> val) { m_firstX = val; }
- void setFirstY(PassRefPtr<CSSPrimitiveValue> val) { m_firstY = val; }
- void setSecondX(PassRefPtr<CSSPrimitiveValue> val) { m_secondX = val; }
- void setSecondY(PassRefPtr<CSSPrimitiveValue> val) { m_secondY = val; }
+ void setFirstX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_firstX = val; }
+ void setFirstY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_firstY = val; }
+ void setSecondX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_secondX = val; }
+ void setSecondY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_secondY = val; }
void addStop(const CSSGradientColorStop& stop) { m_stops.append(stop); }
@@ -86,7 +104,9 @@ public:
bool knownToBeOpaque(const RenderObject*) const;
void loadSubimages(ResourceFetcher*) { }
- PassRefPtr<CSSGradientValue> gradientWithStylesResolved(const TextLinkColors&, Color currentColor);
+ PassRefPtrWillBeRawPtr<CSSGradientValue> gradientWithStylesResolved(const TextLinkColors&, Color currentColor);
+
+ void traceAfterDispatch(Visitor*);
protected:
CSSGradientValue(ClassType classType, CSSGradientRepeat repeat, CSSGradientType gradientType)
@@ -118,14 +138,14 @@ protected:
bool isCacheable() const;
// Points. Some of these may be null.
- RefPtr<CSSPrimitiveValue> m_firstX;
- RefPtr<CSSPrimitiveValue> m_firstY;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_firstX;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_firstY;
- RefPtr<CSSPrimitiveValue> m_secondX;
- RefPtr<CSSPrimitiveValue> m_secondY;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_secondX;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_secondY;
// Stops
- Vector<CSSGradientColorStop, 2> m_stops;
+ WillBeHeapVector<CSSGradientColorStop, 2> m_stops;
bool m_stopsSorted;
CSSGradientType m_gradientType;
bool m_repeating;
@@ -136,25 +156,27 @@ DEFINE_CSS_VALUE_TYPE_CASTS(CSSGradientValue, isGradientValue());
class CSSLinearGradientValue : public CSSGradientValue {
public:
- static PassRefPtr<CSSLinearGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient)
+ static PassRefPtrWillBeRawPtr<CSSLinearGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient)
{
- return adoptRef(new CSSLinearGradientValue(repeat, gradientType));
+ return adoptRefWillBeNoop(new CSSLinearGradientValue(repeat, gradientType));
}
- void setAngle(PassRefPtr<CSSPrimitiveValue> val) { m_angle = val; }
+ void setAngle(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_angle = val; }
String customCSSText() const;
// Create the gradient for a given size.
PassRefPtr<Gradient> createGradient(const CSSToLengthConversionData&, const IntSize&);
- PassRefPtr<CSSLinearGradientValue> clone() const
+ PassRefPtrWillBeRawPtr<CSSLinearGradientValue> clone() const
{
- return adoptRef(new CSSLinearGradientValue(*this));
+ return adoptRefWillBeNoop(new CSSLinearGradientValue(*this));
}
bool equals(const CSSLinearGradientValue&) const;
+ void traceAfterDispatch(Visitor*);
+
private:
CSSLinearGradientValue(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient)
: CSSGradientValue(LinearGradientClass, repeat, gradientType)
@@ -167,39 +189,41 @@ private:
{
}
- RefPtr<CSSPrimitiveValue> m_angle; // may be null.
+ RefPtrWillBeMember<CSSPrimitiveValue> m_angle; // may be null.
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSLinearGradientValue, isLinearGradientValue());
class CSSRadialGradientValue : public CSSGradientValue {
public:
- static PassRefPtr<CSSRadialGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
+ static PassRefPtrWillBeRawPtr<CSSRadialGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
{
- return adoptRef(new CSSRadialGradientValue(repeat, gradientType));
+ return adoptRefWillBeNoop(new CSSRadialGradientValue(repeat, gradientType));
}
- PassRefPtr<CSSRadialGradientValue> clone() const
+ PassRefPtrWillBeRawPtr<CSSRadialGradientValue> clone() const
{
- return adoptRef(new CSSRadialGradientValue(*this));
+ return adoptRefWillBeNoop(new CSSRadialGradientValue(*this));
}
String customCSSText() const;
- void setFirstRadius(PassRefPtr<CSSPrimitiveValue> val) { m_firstRadius = val; }
- void setSecondRadius(PassRefPtr<CSSPrimitiveValue> val) { m_secondRadius = val; }
+ void setFirstRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_firstRadius = val; }
+ void setSecondRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_secondRadius = val; }
- void setShape(PassRefPtr<CSSPrimitiveValue> val) { m_shape = val; }
- void setSizingBehavior(PassRefPtr<CSSPrimitiveValue> val) { m_sizingBehavior = val; }
+ void setShape(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_shape = val; }
+ void setSizingBehavior(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_sizingBehavior = val; }
- void setEndHorizontalSize(PassRefPtr<CSSPrimitiveValue> val) { m_endHorizontalSize = val; }
- void setEndVerticalSize(PassRefPtr<CSSPrimitiveValue> val) { m_endVerticalSize = val; }
+ void setEndHorizontalSize(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_endHorizontalSize = val; }
+ void setEndVerticalSize(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_endVerticalSize = val; }
// Create the gradient for a given size.
PassRefPtr<Gradient> createGradient(const CSSToLengthConversionData&, const IntSize&);
bool equals(const CSSRadialGradientValue&) const;
+ void traceAfterDispatch(Visitor*);
+
private:
CSSRadialGradientValue(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
: CSSGradientValue(RadialGradientClass, repeat, gradientType)
@@ -222,15 +246,15 @@ private:
float resolveRadius(CSSPrimitiveValue*, const CSSToLengthConversionData&, float* widthOrHeight = 0);
// These may be null for non-deprecated gradients.
- RefPtr<CSSPrimitiveValue> m_firstRadius;
- RefPtr<CSSPrimitiveValue> m_secondRadius;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_firstRadius;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_secondRadius;
// The below are only used for non-deprecated gradients. Any of them may be null.
- RefPtr<CSSPrimitiveValue> m_shape;
- RefPtr<CSSPrimitiveValue> m_sizingBehavior;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_shape;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_sizingBehavior;
- RefPtr<CSSPrimitiveValue> m_endHorizontalSize;
- RefPtr<CSSPrimitiveValue> m_endVerticalSize;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_endHorizontalSize;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_endVerticalSize;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSRadialGradientValue, isRadialGradientValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGrammar.y b/chromium/third_party/WebKit/Source/core/css/CSSGrammar.y
index 2c2c3753094..e006812e9a4 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSGrammar.y
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGrammar.y
@@ -29,7 +29,7 @@
#include "HTMLNames.h"
#include "core/css/CSSKeyframeRule.h"
#include "core/css/CSSKeyframesRule.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSParserMode.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSSelector.h"
@@ -60,10 +60,10 @@ using namespace HTMLNames;
%}
-%pure_parser
+%pure-parser
-%parse-param { CSSParser* parser }
-%lex-param { CSSParser* parser }
+%parse-param { BisonCSSParser* parser }
+%lex-param { BisonCSSParser* parser }
%union {
bool boolean;
@@ -73,7 +73,12 @@ using namespace HTMLNames;
CSSParserString string;
StyleRuleBase* rule;
- Vector<RefPtr<StyleRuleBase> >* ruleList;
+ // The content of the three below HeapVectors are guaranteed to be kept alive by
+ // the corresponding m_parsedRules, m_floatingMediaQueryExpList, and m_parsedKeyFrames
+ // lists in BisonCSSParser.h.
+ WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >* ruleList;
+ WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* mediaQueryExpList;
+ WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* keyframeRuleList;
CSSParserSelector* selector;
Vector<OwnPtr<CSSParserSelector> >* selectorList;
CSSSelector::MarginBoxType marginBox;
@@ -84,9 +89,7 @@ using namespace HTMLNames;
MediaQueryExp* mediaQueryExp;
CSSParserValue value;
CSSParserValueList* valueList;
- Vector<OwnPtr<MediaQueryExp> >* mediaQueryExpList;
StyleKeyframe* keyframe;
- Vector<RefPtr<StyleKeyframe> >* keyframeRuleList;
float val;
CSSPropertyID id;
CSSParserLocation location;
@@ -114,12 +117,9 @@ static inline bool isCSSTokenAString(int yytype)
case FUNCTION:
case ANYFUNCTION:
case HOSTFUNCTION:
+ case HOSTCONTEXTFUNCTION:
case NOTFUNCTION:
case CALCFUNCTION:
- case MINFUNCTION:
- case MAXFUNCTION:
- case VARFUNCTION:
- case VAR_DEFINITION:
case UNICODERANGE:
return true;
default:
@@ -132,6 +132,7 @@ inline static CSSParserValue makeOperatorValue(int value)
{
CSSParserValue v;
v.id = CSSValueInvalid;
+ v.isInt = false;
v.unit = CSSParserValue::Operator;
v.iValue = value;
return v;
@@ -141,6 +142,7 @@ inline static CSSParserValue makeIdentValue(CSSParserString string)
{
CSSParserValue v;
v.id = cssValueKeywordID(string);
+ v.isInt = false;
v.unit = CSSPrimitiveValue::CSS_IDENT;
v.string = string;
return v;
@@ -194,8 +196,6 @@ inline static CSSParserValue makeIdentValue(CSSParserString string)
%token INTERNAL_SUPPORTS_CONDITION_SYM
%token KEYFRAMES_SYM
%token WEBKIT_KEYFRAMES_SYM
-%token WEBKIT_REGION_RULE_SYM
-%token WEBKIT_FILTER_RULE_SYM
%token <marginBox> TOPLEFTCORNER_SYM
%token <marginBox> TOPLEFT_SYM
%token <marginBox> TOPCENTER_SYM
@@ -265,11 +265,8 @@ inline static CSSParserValue makeIdentValue(CSSParserString string)
%token <string> NOTFUNCTION
%token <string> DISTRIBUTEDFUNCTION
%token <string> CALCFUNCTION
-%token <string> MINFUNCTION
-%token <string> MAXFUNCTION
-%token <string> VARFUNCTION
-%token <string> VAR_DEFINITION
%token <string> HOSTFUNCTION
+%token <string> HOSTCONTEXTFUNCTION
%token <string> UNICODERANGE
@@ -287,16 +284,10 @@ inline static CSSParserValue makeIdentValue(CSSParserString string)
%type <rule> valid_rule
%type <ruleList> block_rule_body
%type <ruleList> block_rule_list
-%type <ruleList> region_block_rule_body
-%type <ruleList> region_block_rule_list
%type <rule> block_rule
%type <rule> block_valid_rule
-%type <rule> region_block_rule
-%type <rule> region_block_valid_rule
-%type <rule> region
%type <rule> supports
%type <rule> viewport
-%type <rule> filter
%type <boolean> keyframes_rule_start
%type <string> maybe_ns_prefix
@@ -339,10 +330,8 @@ inline static CSSParserValue makeIdentValue(CSSParserString string)
%type <selector> specifier_list
%type <selector> simple_selector
%type <selector> selector
-%type <selector> relative_selector
%type <selectorList> selector_list
%type <selectorList> simple_selector_list
-%type <selectorList> region_selector
%type <selector> class
%type <selector> attrib
%type <selector> pseudo
@@ -368,11 +357,8 @@ inline static CSSParserValue makeIdentValue(CSSParserString string)
%type <value> calc_func_term
%type <character> calc_func_operator
%type <valueList> calc_func_expr
-%type <valueList> calc_func_expr_list
%type <valueList> calc_func_paren_expr
%type <value> calc_function
-%type <string> min_or_max
-%type <value> min_or_max_function
%type <string> element_name
%type <string> attr_name
@@ -511,10 +497,8 @@ valid_rule:
| keyframes
| namespace
| import
- | region
| supports
| viewport
- | filter
;
before_rule:
@@ -547,46 +531,12 @@ block_rule_list:
}
;
-region_block_rule_body:
- region_block_rule_list
- | region_block_rule_list block_rule_recovery
- ;
-
-region_block_rule_list:
- /* empty */ { $$ = 0; }
- | region_block_rule_list region_block_rule maybe_sgml {
- $$ = parser->appendRule($1, $2);
- }
- ;
-
-region_block_rule:
- before_rule region_block_valid_rule {
- $$ = $2;
- parser->endRule(!!$$);
- }
- | before_rule invalid_rule {
- $$ = 0;
- parser->endRule(false);
- }
- ;
-
block_rule_recovery:
before_rule invalid_rule_header {
parser->endRule(false);
}
;
-region_block_valid_rule:
- ruleset
- | page
- | font_face
- | media
- | keyframes
- | supports
- | viewport
- | filter
- ;
-
block_valid_rule:
ruleset
| page
@@ -595,9 +545,7 @@ block_valid_rule:
| keyframes
| supports
| viewport
- | filter
| namespace
- | region
;
block_rule:
@@ -716,11 +664,11 @@ valid_media_query:
media_query:
valid_media_query
| valid_media_query error error_location rule_error_recovery {
- parser->reportError(parser->lastLocationLabel(), CSSParser::InvalidMediaQueryError);
+ parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
$$ = parser->createFloatingNotAllQuery();
}
| error error_location rule_error_recovery {
- parser->reportError(parser->lastLocationLabel(), CSSParser::InvalidMediaQueryError);
+ parser->reportError(parser->lastLocationLabel(), InvalidMediaQueryCSSError);
$$ = parser->createFloatingNotAllQuery();
}
;
@@ -846,7 +794,7 @@ supports_condition_in_parens:
}
| supports_declaration_condition
| '(' error error_location error_recovery closing_parenthesis maybe_space {
- parser->reportError($3, CSSParser::InvalidSupportsConditionError);
+ parser->reportError($3, InvalidSupportsConditionCSSError);
$$ = false;
}
;
@@ -868,7 +816,7 @@ supports_declaration_condition:
}
| '(' maybe_space IDENT maybe_space ':' maybe_space error error_recovery closing_parenthesis maybe_space {
$$ = false;
- parser->endProperty(false, false, CSSParser::GeneralError);
+ parser->endProperty(false, false, GeneralCSSError);
}
;
@@ -953,7 +901,7 @@ key:
keyframes_error_recovery:
error rule_error_recovery {
- parser->reportError(parser->lastLocationLabel(), CSSParser::InvalidKeyframeSelectorError);
+ parser->reportError(parser->lastLocationLabel(), InvalidKeyframeSelectorCSSError);
}
;
@@ -1089,53 +1037,15 @@ viewport:
}
;
-region_selector:
- selector_list {
- parser->setReusableRegionSelectorVector($1);
- $$ = parser->reusableRegionSelectorVector();
- }
-;
-
-before_region_rule:
- /* empty */ {
- parser->startRuleHeader(CSSRuleSourceData::REGION_RULE);
- }
- ;
-
-region:
- before_region_rule WEBKIT_REGION_RULE_SYM maybe_space region_selector at_rule_header_end '{' at_rule_body_start maybe_space region_block_rule_body closing_brace {
- $$ = parser->createRegionRule($4, $9);
- }
-;
-
-before_filter_rule:
- /* empty */ {
- parser->startRuleHeader(CSSRuleSourceData::FILTER_RULE);
- parser->m_inFilterRule = true;
- }
- ;
-
-filter:
- before_filter_rule WEBKIT_FILTER_RULE_SYM maybe_space IDENT at_rule_header_end_maybe_space
- '{' at_rule_body_start maybe_space_before_declaration declaration_list closing_brace {
- parser->m_inFilterRule = false;
- $$ = parser->createFilterRule($4);
- }
- ;
-
combinator:
'+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
| '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
| '>' maybe_space { $$ = CSSSelector::Child; }
- | '^' maybe_space {
- if (!RuntimeEnabledFeatures::shadowDOMEnabled())
+ | '/' IDENT '/' maybe_space {
+ if ($2.equalIgnoringCase("deep"))
+ $$ = CSSSelector::ShadowDeep;
+ else
YYERROR;
- $$ = CSSSelector::ChildTree;
- }
- | '^' '^' maybe_space {
- if (!RuntimeEnabledFeatures::shadowDOMEnabled())
- YYERROR;
- $$ = CSSSelector::DescendantTree;
}
;
@@ -1197,17 +1107,6 @@ selector_list:
}
;
-relative_selector:
- combinator selector {
- $$ = $2;
- CSSParserSelector* end = $$;
- while (end->tagHistory())
- end = end->tagHistory();
- end->setRelation($1);
- }
- | selector
- ;
-
selector:
simple_selector
| selector WHITESPACE
@@ -1420,7 +1319,7 @@ pseudo:
$$->setValue($3);
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown) {
- parser->reportError($2, CSSParser::InvalidSelectorPseudoError);
+ parser->reportError($2, InvalidSelectorPseudoCSSError);
YYERROR;
}
}
@@ -1434,7 +1333,7 @@ pseudo:
// FIXME: This call is needed to force selector to compute the pseudoType early enough.
CSSSelector::PseudoType type = $$->pseudoType();
if (type == CSSSelector::PseudoUnknown) {
- parser->reportError($3, CSSParser::InvalidSelectorPseudoError);
+ parser->reportError($3, InvalidSelectorPseudoCSSError);
YYERROR;
}
}
@@ -1451,16 +1350,6 @@ pseudo:
| ':' ':' CUEFUNCTION selector_recovery closing_parenthesis {
YYERROR;
}
- | ':' ':' DISTRIBUTEDFUNCTION maybe_space relative_selector closing_parenthesis {
- $$ = parser->createFloatingSelector();
- $$->setMatch(CSSSelector::PseudoElement);
- $$->setFunctionArgumentSelector($5);
- parser->tokenToLowerCase($3);
- $$->setValue($3);
- }
- | ':' ':' DISTRIBUTEDFUNCTION selector_recovery closing_parenthesis {
- YYERROR;
- }
// use by :-webkit-any.
// FIXME: should we support generic selectors here or just simple_selectors?
// Use simple_selector_list for now to match -moz-any.
@@ -1549,17 +1438,21 @@ pseudo:
if (type != CSSSelector::PseudoHost)
YYERROR;
}
- // used by :host()
- | ':' HOSTFUNCTION maybe_space closing_parenthesis {
+ | ':' HOSTFUNCTION selector_recovery closing_parenthesis {
+ YYERROR;
+ }
+ // used by :host-context()
+ | ':' HOSTCONTEXTFUNCTION maybe_space simple_selector_list maybe_space closing_parenthesis {
$$ = parser->createFloatingSelector();
$$->setMatch(CSSSelector::PseudoClass);
+ $$->adoptSelectorVector(*parser->sinkFloatingSelectorVector($4));
parser->tokenToLowerCase($2);
- $$->setValue($2.atomicSubstring(0, $2.length() - 1));
+ $$->setValue($2);
CSSSelector::PseudoType type = $$->pseudoType();
- if (type != CSSSelector::PseudoHost)
+ if (type != CSSSelector::PseudoHostContext)
YYERROR;
}
- | ':' HOSTFUNCTION selector_recovery closing_parenthesis {
+ | ':' HOSTCONTEXTFUNCTION selector_recovery closing_parenthesis {
YYERROR;
}
;
@@ -1588,12 +1481,6 @@ decl_list:
;
declaration:
- VAR_DEFINITION maybe_space ':' maybe_space expr prio {
- parser->storeVariableDeclaration($1, parser->sinkFloatingValueList($5), $6);
- $$ = true;
- parser->endProperty($6, true);
- }
- |
property ':' maybe_space error_location expr prio {
$$ = false;
bool isPropertyParsed = false;
@@ -1603,7 +1490,7 @@ declaration:
$$ = parser->parseValue($1, $6);
if (!$$) {
parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);
- parser->reportError($4, CSSParser::InvalidPropertyValueError);
+ parser->reportError($4, InvalidPropertyValueCSSError);
} else
isPropertyParsed = true;
parser->m_valueList = nullptr;
@@ -1613,25 +1500,25 @@ declaration:
|
property ':' maybe_space error_location expr prio error error_recovery {
/* When we encounter something like p {color: red !important fail;} we should drop the declaration */
- parser->reportError($4, CSSParser::InvalidPropertyValueError);
+ parser->reportError($4, InvalidPropertyValueCSSError);
parser->endProperty(false, false);
$$ = false;
}
|
property ':' maybe_space error_location error error_recovery {
- parser->reportError($4, CSSParser::InvalidPropertyValueError);
+ parser->reportError($4, InvalidPropertyValueCSSError);
parser->endProperty(false, false);
$$ = false;
}
|
property error error_location error_recovery {
- parser->reportError($3, CSSParser::PropertyDeclarationError);
- parser->endProperty(false, false, CSSParser::GeneralError);
+ parser->reportError($3, PropertyDeclarationCSSError);
+ parser->endProperty(false, false, GeneralCSSError);
$$ = false;
}
|
error error_location error_recovery {
- parser->reportError($2, CSSParser::PropertyDeclarationError);
+ parser->reportError($2, PropertyDeclarationCSSError);
$$ = false;
}
;
@@ -1641,7 +1528,7 @@ property:
$$ = cssPropertyID($2);
parser->setCurrentProperty($$);
if ($$ == CSSPropertyInvalid)
- parser->reportError($1, CSSParser::InvalidPropertyError);
+ parser->reportError($1, InvalidPropertyCSSError);
}
;
@@ -1691,7 +1578,7 @@ expr:
expr_recovery:
error error_location error_recovery {
- parser->reportError($2, CSSParser::PropertyDeclarationError);
+ parser->reportError($2, PropertyDeclarationCSSError);
}
;
@@ -1707,29 +1594,20 @@ operator:
term:
unary_term maybe_space
| unary_operator unary_term maybe_space { $$ = $2; $$.fValue *= $1; }
- | STRING maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
+ | STRING maybe_space { $$.id = CSSValueInvalid; $$.isInt = false; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_STRING; }
| IDENT maybe_space { $$ = makeIdentValue($1); }
/* We might need to actually parse the number from a dimension, but we can't just put something that uses $$.string into unary_term. */
- | DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
- | unary_operator DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $2; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
- | URI maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_URI; }
- | UNICODERANGE maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
- | HEX maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
- | '#' maybe_space { $$.id = CSSValueInvalid; $$.string = CSSParserString(); $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
- | VARFUNCTION maybe_space IDENT closing_parenthesis maybe_space {
- $$.id = CSSValueInvalid;
- $$.string = $3;
- $$.unit = CSSPrimitiveValue::CSS_VARIABLE_NAME;
- }
- | VARFUNCTION maybe_space expr_recovery closing_parenthesis {
- YYERROR;
- }
+ | DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
+ | unary_operator DIMEN maybe_space { $$.id = CSSValueInvalid; $$.string = $2; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_DIMENSION; }
+ | URI maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_URI; }
+ | UNICODERANGE maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_UNICODE_RANGE; }
+ | HEX maybe_space { $$.id = CSSValueInvalid; $$.string = $1; $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; }
+ | '#' maybe_space { $$.id = CSSValueInvalid; $$.string = CSSParserString(); $$.isInt = false; $$.unit = CSSPrimitiveValue::CSS_PARSER_HEXCOLOR; } /* Handle error case: "color: #;" */
/* FIXME: according to the specs a function can have a unary_operator in front. I know no case where this makes sense */
| function maybe_space
| calc_function maybe_space
- | min_or_max_function maybe_space
| '%' maybe_space { /* Handle width: %; */
- $$.id = CSSValueInvalid; $$.unit = 0;
+ $$.id = CSSValueInvalid; $$.isInt = false; $$.unit = 0;
}
| track_names_list maybe_space
;
@@ -1785,11 +1663,6 @@ function:
calc_func_term:
unary_term
- | VARFUNCTION maybe_space IDENT closing_parenthesis {
- $$.id = CSSValueInvalid;
- $$.string = $3;
- $$.unit = CSSPrimitiveValue::CSS_VARIABLE_NAME;
- }
| unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
;
@@ -1837,20 +1710,11 @@ calc_func_expr:
| calc_func_expr calc_func_operator calc_func_paren_expr {
$$ = $1;
$$->addValue(makeOperatorValue($2));
- $$->extend(*($3));
+ $$->stealValues(*($3));
}
| calc_func_paren_expr
;
-calc_func_expr_list:
- calc_func_expr calc_maybe_space
- | calc_func_expr_list ',' maybe_space calc_func_expr calc_maybe_space {
- $$ = $1;
- $$->addValue(makeOperatorValue(','));
- $$->extend(*($4));
- }
- ;
-
calc_function:
CALCFUNCTION maybe_space calc_func_expr calc_maybe_space closing_parenthesis {
$$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
@@ -1861,20 +1725,6 @@ calc_function:
;
-min_or_max:
- MINFUNCTION
- | MAXFUNCTION
- ;
-
-min_or_max_function:
- min_or_max maybe_space calc_func_expr_list closing_parenthesis {
- $$.setFromFunction(parser->createFloatingFunction($1, parser->sinkFloatingValueList($3)));
- }
- | min_or_max maybe_space expr_recovery closing_parenthesis {
- YYERROR;
- }
- ;
-
invalid_at:
ATKEYWORD
| margin_sym
@@ -1886,7 +1736,7 @@ at_rule_recovery:
at_rule_header_recovery:
error error_location rule_error_recovery {
- parser->reportError($2, CSSParser::InvalidRuleError);
+ parser->reportError($2, InvalidRuleCSSError);
}
;
@@ -1900,25 +1750,23 @@ regular_invalid_at_rule_header:
| before_page_rule PAGE_SYM at_rule_header_recovery
| before_font_face_rule FONT_FACE_SYM at_rule_header_recovery
| before_supports_rule SUPPORTS_SYM error error_location rule_error_recovery {
- parser->reportError($4, CSSParser::InvalidSupportsConditionError);
+ parser->reportError($4, InvalidSupportsConditionCSSError);
parser->popSupportsRuleData();
}
| before_viewport_rule VIEWPORT_RULE_SYM at_rule_header_recovery {
parser->markViewportRuleBodyEnd();
}
- | before_filter_rule WEBKIT_FILTER_RULE_SYM at_rule_header_recovery
| import_rule_start at_rule_header_recovery
| NAMESPACE_SYM at_rule_header_recovery
- | before_region_rule WEBKIT_REGION_RULE_SYM at_rule_header_recovery
| error_location invalid_at at_rule_header_recovery {
parser->resumeErrorLogging();
- parser->reportError($1, CSSParser::InvalidRuleError);
+ parser->reportError($1, InvalidRuleCSSError);
}
;
invalid_rule:
error error_location rule_error_recovery at_invalid_rule_header_end invalid_block {
- parser->reportError($2, CSSParser::InvalidRuleError);
+ parser->reportError($2, InvalidRuleCSSError);
}
| regular_invalid_at_rule_header at_invalid_rule_header_end ';'
| regular_invalid_at_rule_header at_invalid_rule_header_end invalid_block
@@ -1927,7 +1775,7 @@ invalid_rule:
invalid_rule_header:
error error_location rule_error_recovery at_invalid_rule_header_end {
- parser->reportError($2, CSSParser::InvalidRuleError);
+ parser->reportError($2, InvalidRuleCSSError);
}
| regular_invalid_at_rule_header at_invalid_rule_header_end
| media_rule_start maybe_media_list
@@ -1953,7 +1801,7 @@ invalid_parentheses_block:
opening_parenthesis error_recovery closing_parenthesis;
opening_parenthesis:
- '(' | FUNCTION | CALCFUNCTION | VARFUNCTION | MINFUNCTION | MAXFUNCTION | ANYFUNCTION | NOTFUNCTION | CUEFUNCTION | DISTRIBUTEDFUNCTION | HOSTFUNCTION
+ '(' | FUNCTION | CALCFUNCTION | ANYFUNCTION | NOTFUNCTION | CUEFUNCTION | DISTRIBUTEDFUNCTION | HOSTFUNCTION
;
error_location: {
@@ -1982,4 +1830,3 @@ rule_error_recovery:
;
%%
-
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.cpp
index 3a2877d9ae9..5b100a553d8 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.cpp
@@ -43,9 +43,9 @@ CSSGridLineNamesValue::CSSGridLineNamesValue()
{
}
-PassRefPtr<CSSGridLineNamesValue> CSSGridLineNamesValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSGridLineNamesValue> CSSGridLineNamesValue::cloneForCSSOM() const
{
- return adoptRef(new CSSGridLineNamesValue(*this));
+ return adoptRefWillBeNoop(new CSSGridLineNamesValue(*this));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.h b/chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.h
index da97e059579..3e4298fa39f 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGridLineNamesValue.h
@@ -38,14 +38,16 @@ namespace WebCore {
class CSSGridLineNamesValue : public CSSValueList {
public:
- static PassRefPtr<CSSGridLineNamesValue> create()
+ static PassRefPtrWillBeRawPtr<CSSGridLineNamesValue> create()
{
- return adoptRef(new CSSGridLineNamesValue());
+ return adoptRefWillBeNoop(new CSSGridLineNamesValue());
}
String customCSSText() const;
- PassRefPtr<CSSGridLineNamesValue> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<CSSGridLineNamesValue> cloneForCSSOM() const;
+
+ void traceAfterDispatch(Visitor* visitor) { CSSValueList::traceAfterDispatch(visitor); }
private:
CSSGridLineNamesValue();
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.cpp
new file mode 100644
index 00000000000..9541f52715a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
+
+#include "wtf/text/StringBuilder.h"
+
+namespace WebCore {
+
+CSSGridTemplateAreasValue::CSSGridTemplateAreasValue(const NamedGridAreaMap& gridAreaMap, size_t rowCount, size_t columnCount)
+ : CSSValue(GridTemplateAreasClass)
+ , m_gridAreaMap(gridAreaMap)
+ , m_rowCount(rowCount)
+ , m_columnCount(columnCount)
+{
+ ASSERT(m_rowCount);
+ ASSERT(m_columnCount);
+}
+
+static String stringForPosition(const NamedGridAreaMap& gridAreaMap, size_t row, size_t column)
+{
+ Vector<String> candidates;
+
+ NamedGridAreaMap::const_iterator end = gridAreaMap.end();
+ for (NamedGridAreaMap::const_iterator it = gridAreaMap.begin(); it != end; ++it) {
+ const GridCoordinate& coordinate = it->value;
+ if (row >= coordinate.rows.resolvedInitialPosition.toInt() && row <= coordinate.rows.resolvedFinalPosition.toInt())
+ candidates.append(it->key);
+ }
+
+ end = gridAreaMap.end();
+ for (NamedGridAreaMap::const_iterator it = gridAreaMap.begin(); it != end; ++it) {
+ const GridCoordinate& coordinate = it->value;
+ if (column >= coordinate.columns.resolvedInitialPosition.toInt() && column <= coordinate.columns.resolvedFinalPosition.toInt() && candidates.contains(it->key))
+ return it->key;
+ }
+
+ return ".";
+}
+
+String CSSGridTemplateAreasValue::customCSSText() const
+{
+ StringBuilder builder;
+ for (size_t row = 0; row < m_rowCount; ++row) {
+ builder.append('\"');
+ for (size_t column = 0; column < m_columnCount; ++column) {
+ builder.append(stringForPosition(m_gridAreaMap, row, column));
+ if (column != m_columnCount - 1)
+ builder.append(' ');
+ }
+ builder.append('\"');
+ if (row != m_rowCount - 1)
+ builder.append(' ');
+ }
+ return builder.toString();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.h b/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.h
new file mode 100644
index 00000000000..070cc8488cd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateAreasValue.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSGridTemplateAreasValue_h
+#define CSSGridTemplateAreasValue_h
+
+#include "core/css/CSSValue.h"
+#include "core/rendering/style/GridCoordinate.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+class CSSGridTemplateAreasValue : public CSSValue {
+public:
+ static PassRefPtrWillBeRawPtr<CSSGridTemplateAreasValue> create(const NamedGridAreaMap& gridAreaMap, size_t rowCount, size_t columnCount)
+ {
+ return adoptRefWillBeNoop(new CSSGridTemplateAreasValue(gridAreaMap, rowCount, columnCount));
+ }
+ ~CSSGridTemplateAreasValue() { }
+
+ String customCSSText() const;
+
+ const NamedGridAreaMap& gridAreaMap() const { return m_gridAreaMap; }
+ size_t rowCount() const { return m_rowCount; }
+ size_t columnCount() const { return m_columnCount; }
+
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
+private:
+ CSSGridTemplateAreasValue(const NamedGridAreaMap&, size_t rowCount, size_t columnCount);
+
+ NamedGridAreaMap m_gridAreaMap;
+ size_t m_rowCount;
+ size_t m_columnCount;
+};
+
+DEFINE_CSS_VALUE_TYPE_CASTS(CSSGridTemplateAreasValue, isGridTemplateAreasValue());
+
+} // namespace WebCore
+
+#endif // CSSGridTemplateAreasValue_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateValue.cpp
deleted file mode 100644
index d1ad1d8d056..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateValue.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/css/CSSGridTemplateValue.h"
-
-#include "wtf/text/StringBuilder.h"
-
-namespace WebCore {
-
-CSSGridTemplateValue::CSSGridTemplateValue(const NamedGridAreaMap& gridAreaMap, size_t rowCount, size_t columnCount)
- : CSSValue(GridTemplateClass)
- , m_gridAreaMap(gridAreaMap)
- , m_rowCount(rowCount)
- , m_columnCount(columnCount)
-{
- ASSERT(m_rowCount);
- ASSERT(m_columnCount);
-}
-
-static String stringForPosition(const NamedGridAreaMap& gridAreaMap, size_t row, size_t column)
-{
- Vector<String> candidates;
-
- NamedGridAreaMap::const_iterator end = gridAreaMap.end();
- for (NamedGridAreaMap::const_iterator it = gridAreaMap.begin(); it != end; ++it) {
- const GridCoordinate& coordinate = it->value;
- if (row >= coordinate.rows.initialPositionIndex && row <= coordinate.rows.finalPositionIndex)
- candidates.append(it->key);
- }
-
- end = gridAreaMap.end();
- for (NamedGridAreaMap::const_iterator it = gridAreaMap.begin(); it != end; ++it) {
- const GridCoordinate& coordinate = it->value;
- if (column >= coordinate.columns.initialPositionIndex && column <= coordinate.columns.finalPositionIndex && candidates.contains(it->key))
- return it->key;
- }
-
- return ".";
-}
-
-String CSSGridTemplateValue::customCSSText() const
-{
- StringBuilder builder;
- for (size_t row = 0; row < m_rowCount; ++row) {
- builder.append('\"');
- for (size_t column = 0; column < m_columnCount; ++column) {
- builder.append(stringForPosition(m_gridAreaMap, row, column));
- if (column != m_columnCount - 1)
- builder.append(' ');
- }
- builder.append('\"');
- if (row != m_rowCount - 1)
- builder.append(' ');
- }
- return builder.toString();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateValue.h b/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateValue.h
deleted file mode 100644
index faa988053f6..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSGridTemplateValue.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSGridTemplateValue_h
-#define CSSGridTemplateValue_h
-
-#include "core/css/CSSValue.h"
-#include "core/rendering/style/GridCoordinate.h"
-#include "wtf/text/StringHash.h"
-
-namespace WebCore {
-
-class CSSGridTemplateValue : public CSSValue {
-public:
- static PassRefPtr<CSSGridTemplateValue> create(const NamedGridAreaMap& gridAreaMap, size_t rowCount, size_t columnCount) { return adoptRef(new CSSGridTemplateValue(gridAreaMap, rowCount, columnCount)); }
- ~CSSGridTemplateValue() { }
-
- String customCSSText() const;
-
- const NamedGridAreaMap& gridAreaMap() const { return m_gridAreaMap; }
- size_t rowCount() const { return m_rowCount; }
- size_t columnCount() const { return m_columnCount; }
-
-private:
- CSSGridTemplateValue(const NamedGridAreaMap&, size_t rowCount, size_t columnCount);
-
- NamedGridAreaMap m_gridAreaMap;
- size_t m_rowCount;
- size_t m_columnCount;
-};
-
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSGridTemplateValue, isGridTemplateValue());
-
-} // namespace WebCore
-
-#endif // CSSGridTemplateValue_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.cpp
index 0c0bf2a9d20..ec56762b027 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.cpp
@@ -32,10 +32,11 @@
#include "core/css/CSSGroupingRule.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSStyleSheet.h"
#include "core/dom/ExceptionCode.h"
+#include "core/frame/UseCounter.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -49,11 +50,13 @@ CSSGroupingRule::CSSGroupingRule(StyleRuleGroup* groupRule, CSSStyleSheet* paren
CSSGroupingRule::~CSSGroupingRule()
{
+#if !ENABLE(OILPAN)
ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
if (m_childRuleCSSOMWrappers[i])
m_childRuleCSSOMWrappers[i]->setParentRule(0);
}
+#endif
}
unsigned CSSGroupingRule::insertRule(const String& ruleString, unsigned index, ExceptionState& exceptionState)
@@ -66,8 +69,9 @@ unsigned CSSGroupingRule::insertRule(const String& ruleString, unsigned index, E
}
CSSStyleSheet* styleSheet = parentStyleSheet();
- CSSParser parser(parserContext(), UseCounter::getFrom(styleSheet));
- RefPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? styleSheet->contents() : 0, ruleString);
+ CSSParserContext context(parserContext(), UseCounter::getFrom(styleSheet));
+ BisonCSSParser parser(context);
+ RefPtrWillBeRawPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? styleSheet->contents() : 0, ruleString);
if (!newRule) {
exceptionState.throwDOMException(SyntaxError, "the rule '" + ruleString + "' is invalid and cannot be parsed.");
return 0;
@@ -84,7 +88,7 @@ unsigned CSSGroupingRule::insertRule(const String& ruleString, unsigned index, E
m_groupRule->wrapperInsertRule(index, newRule);
- m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
+ m_childRuleCSSOMWrappers.insert(index, RefPtrWillBeMember<CSSRule>(nullptr));
return index;
}
@@ -126,7 +130,7 @@ CSSRule* CSSGroupingRule::item(unsigned index) const
if (index >= length())
return 0;
ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
- RefPtr<CSSRule>& rule = m_childRuleCSSOMWrappers[index];
+ RefPtrWillBeMember<CSSRule>& rule = m_childRuleCSSOMWrappers[index];
if (!rule)
rule = m_groupRule->childRules()[index]->createCSSOMWrapper(const_cast<CSSGroupingRule*>(this));
return rule.get();
@@ -135,7 +139,7 @@ CSSRule* CSSGroupingRule::item(unsigned index) const
CSSRuleList* CSSGroupingRule::cssRules() const
{
if (!m_ruleListCSSOMWrapper)
- m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSGroupingRule>(const_cast<CSSGroupingRule*>(this)));
+ m_ruleListCSSOMWrapper = LiveCSSRuleList<CSSGroupingRule>::create(const_cast<CSSGroupingRule*>(this));
return m_ruleListCSSOMWrapper.get();
}
@@ -149,4 +153,14 @@ void CSSGroupingRule::reattach(StyleRuleBase* rule)
}
}
+void CSSGroupingRule::trace(Visitor* visitor)
+{
+ CSSRule::trace(visitor);
+#if ENABLE(OILPAN)
+ visitor->trace(m_childRuleCSSOMWrappers);
+#endif
+ visitor->trace(m_groupRule);
+ visitor->trace(m_ruleListCSSOMWrapper);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.h b/chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.h
index 9ba64484b95..cdc98da3477 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSGroupingRule.h
@@ -47,14 +47,16 @@ public:
unsigned length() const;
CSSRule* item(unsigned index) const;
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
CSSGroupingRule(StyleRuleGroup* groupRule, CSSStyleSheet* parent);
void appendCSSTextForItems(StringBuilder&) const;
- RefPtr<StyleRuleGroup> m_groupRule;
- mutable Vector<RefPtr<CSSRule> > m_childRuleCSSOMWrappers;
- mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
+ RefPtrWillBeMember<StyleRuleGroup> m_groupRule;
+ mutable WillBeHeapVector<RefPtrWillBeMember<CSSRule> > m_childRuleCSSOMWrappers;
+ mutable OwnPtrWillBeMember<CSSRuleList> m_ruleListCSSOMWrapper;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp
index fa3f22a05e6..41b0ea18c95 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.cpp
@@ -44,9 +44,16 @@ CSSImageGeneratorValue::~CSSImageGeneratorValue()
void CSSImageGeneratorValue::addClient(RenderObject* renderer, const IntSize& size)
{
+ ASSERT(renderer);
+#if !ENABLE(OILPAN)
ref();
+#else
+ if (m_clients.isEmpty()) {
+ ASSERT(!m_keepAlive);
+ m_keepAlive = adoptPtr(new Persistent<CSSImageGeneratorValue>(this));
+ }
+#endif
- ASSERT(renderer);
if (!size.isEmpty())
m_sizes.add(size);
@@ -77,7 +84,14 @@ void CSSImageGeneratorValue::removeClient(RenderObject* renderer)
if (!--sizeCount.count)
m_clients.remove(renderer);
+#if !ENABLE(OILPAN)
deref();
+#else
+ if (m_clients.isEmpty()) {
+ ASSERT(m_keepAlive);
+ m_keepAlive = nullptr;
+ }
+#endif
}
Image* CSSImageGeneratorValue::getImage(RenderObject* renderer, const IntSize& size)
@@ -87,7 +101,9 @@ Image* CSSImageGeneratorValue::getImage(RenderObject* renderer, const IntSize& s
SizeAndCount& sizeCount = it->value;
IntSize oldSize = sizeCount.size;
if (oldSize != size) {
+#if !ENABLE_OILPAN
RefPtr<CSSImageGeneratorValue> protect(this);
+#endif
removeClient(renderer);
addClient(renderer, size);
}
@@ -120,7 +136,7 @@ PassRefPtr<Image> CSSImageGeneratorValue::image(RenderObject* renderer, const In
default:
ASSERT_NOT_REACHED();
}
- return 0;
+ return nullptr;
}
bool CSSImageGeneratorValue::isFixedSize() const
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h b/chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h
index d5803d3d52f..09b63b08cff 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSImageGeneratorValue.h
@@ -67,6 +67,8 @@ public:
void loadSubimages(ResourceFetcher*);
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
protected:
explicit CSSImageGeneratorValue(ClassType);
@@ -77,6 +79,14 @@ protected:
HashCountedSet<IntSize> m_sizes; // A count of how many times a given image size is in use.
RenderObjectSizeCountMap m_clients; // A map from RenderObjects (with entry count) to image sizes.
HashMap<IntSize, RefPtr<Image> > m_images; // A cache of Image objects by image size.
+
+#if ENABLE(OILPAN)
+ // FIXME: Oilpan: when/if we can make the renderer point directly to the CSSImageGenerator value using
+ // a member we don't need to have this hack where we keep a persistent to the instance as long as
+ // there are clients in the RenderObjectSizeCountMap.
+ GC_PLUGIN_IGNORE("366546")
+ OwnPtr<Persistent<CSSImageGeneratorValue> > m_keepAlive;
+#endif
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSImageGeneratorValue, isImageGeneratorValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
index ef6321908a1..c081fbeea4c 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/css/CSSImageSetValue.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/css/CSSImageValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/dom/Document.h"
@@ -57,8 +57,8 @@ void CSSImageSetValue::fillImageSet()
size_t length = this->length();
size_t i = 0;
while (i < length) {
- CSSValue* imageValue = item(i);
- String imageURL = toCSSImageValue(imageValue)->url();
+ CSSImageValue* imageValue = toCSSImageValue(item(i));
+ String imageURL = imageValue->url();
++i;
ASSERT_WITH_SECURITY_IMPLICATION(i < length);
@@ -67,6 +67,7 @@ void CSSImageSetValue::fillImageSet()
ImageWithScale image;
image.imageURL = imageURL;
+ image.referrer = imageValue->referrer();
image.scaleFactor = scaleFactor;
m_imagesInSet.append(image);
++i;
@@ -88,7 +89,7 @@ CSSImageSetValue::ImageWithScale CSSImageSetValue::bestImageForScaleFactor()
return image;
}
-StyleFetchedImageSet* CSSImageSetValue::cachedImageSet(ResourceFetcher* loader, float deviceScaleFactor)
+StyleFetchedImageSet* CSSImageSetValue::cachedImageSet(ResourceFetcher* loader, float deviceScaleFactor, const ResourceLoaderOptions& options)
{
ASSERT(loader);
@@ -99,11 +100,16 @@ StyleFetchedImageSet* CSSImageSetValue::cachedImageSet(ResourceFetcher* loader,
if (!m_accessedBestFitImage) {
// FIXME: In the future, we want to take much more than deviceScaleFactor into acount here.
- // All forms of scale should be included: Page::pageScaleFactor(), Frame::pageZoomFactor(),
+ // All forms of scale should be included: Page::pageScaleFactor(), LocalFrame::pageZoomFactor(),
// and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698
ImageWithScale image = bestImageForScaleFactor();
if (Document* document = loader->document()) {
- FetchRequest request(ResourceRequest(document->completeURL(image.imageURL)), FetchInitiatorTypeNames::css);
+ FetchRequest request(ResourceRequest(document->completeURL(image.imageURL)), FetchInitiatorTypeNames::css, options);
+ request.mutableResourceRequest().setHTTPReferrer(image.referrer);
+
+ if (options.corsEnabled == IsCORSEnabled)
+ request.setCrossOriginAccessControl(loader->document()->securityOrigin(), options.allowCredentials, options.credentialsRequested);
+
if (ResourcePtr<ImageResource> cachedImage = loader->fetchImage(request)) {
m_imageSet = StyleFetchedImageSet::create(cachedImage.get(), image.scaleFactor, this);
m_accessedBestFitImage = true;
@@ -114,6 +120,11 @@ StyleFetchedImageSet* CSSImageSetValue::cachedImageSet(ResourceFetcher* loader,
return (m_imageSet && m_imageSet->isImageResourceSet()) ? toStyleFetchedImageSet(m_imageSet) : 0;
}
+StyleFetchedImageSet* CSSImageSetValue::cachedImageSet(ResourceFetcher* fetcher, float deviceScaleFactor)
+{
+ return cachedImageSet(fetcher, deviceScaleFactor, ResourceFetcher::defaultResourceOptions());
+}
+
StyleImage* CSSImageSetValue::cachedOrPendingImageSet(float deviceScaleFactor)
{
if (!m_imageSet) {
@@ -176,9 +187,9 @@ CSSImageSetValue::CSSImageSetValue(const CSSImageSetValue& cloneFrom)
// Non-CSSValueList data is not accessible through CSS OM, no need to clone.
}
-PassRefPtr<CSSImageSetValue> CSSImageSetValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSImageSetValue> CSSImageSetValue::cloneForCSSOM() const
{
- return adoptRef(new CSSImageSetValue(*this));
+ return adoptRefWillBeNoop(new CSSImageSetValue(*this));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.h b/chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.h
index ee6e86b4313..2b9ea861607 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSImageSetValue.h
@@ -27,6 +27,8 @@
#define CSSImageSetValue_h
#include "core/css/CSSValueList.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "platform/weborigin/Referrer.h"
namespace WebCore {
@@ -37,12 +39,13 @@ class StyleImage;
class CSSImageSetValue : public CSSValueList {
public:
- static PassRefPtr<CSSImageSetValue> create()
+ static PassRefPtrWillBeRawPtr<CSSImageSetValue> create()
{
- return adoptRef(new CSSImageSetValue());
+ return adoptRefWillBeNoop(new CSSImageSetValue());
}
~CSSImageSetValue();
+ StyleFetchedImageSet* cachedImageSet(ResourceFetcher*, float deviceScaleFactor, const ResourceLoaderOptions&);
StyleFetchedImageSet* cachedImageSet(ResourceFetcher*, float deviceScaleFactor);
// Returns a StyleFetchedImageSet if the best fit image has been cached already, otherwise a StylePendingImage.
@@ -54,12 +57,15 @@ public:
struct ImageWithScale {
String imageURL;
+ Referrer referrer;
float scaleFactor;
};
bool hasFailedOrCanceledSubresources() const;
- PassRefPtr<CSSImageSetValue> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<CSSImageSetValue> cloneForCSSOM() const;
+
+ void traceAfterDispatch(Visitor* visitor) { CSSValueList::traceAfterDispatch(visitor); }
protected:
ImageWithScale bestImageForScaleFactor();
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSImageValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSImageValue.cpp
index 4dd0799e101..7163e58c6f6 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSImageValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSImageValue.cpp
@@ -21,29 +21,24 @@
#include "config.h"
#include "core/css/CSSImageValue.h"
-#include "FetchInitiatorTypeNames.h"
-#include "core/css/CSSParser.h"
+#include "core/FetchInitiatorTypeNames.h"
+#include "core/css/CSSMarkup.h"
#include "core/dom/Document.h"
#include "core/fetch/CrossOriginAccessControl.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ImageResource.h"
#include "core/rendering/style/StyleFetchedImage.h"
#include "core/rendering/style/StylePendingImage.h"
+#include "platform/weborigin/KURL.h"
namespace WebCore {
-CSSImageValue::CSSImageValue(const String& url)
+CSSImageValue::CSSImageValue(const String& rawValue, const KURL& url, StyleImage* image)
: CSSValue(ImageClass)
- , m_url(url)
- , m_accessedImage(false)
-{
-}
-
-CSSImageValue::CSSImageValue(const String& url, StyleImage* image)
- : CSSValue(ImageClass)
- , m_url(url)
+ , m_relativeURL(rawValue)
+ , m_absoluteURL(url.string())
, m_image(image)
- , m_accessedImage(true)
+ , m_accessedImage(image)
{
}
@@ -59,17 +54,18 @@ StyleImage* CSSImageValue::cachedOrPendingImage()
return m_image.get();
}
-StyleFetchedImage* CSSImageValue::cachedImage(ResourceFetcher* fetcher, const ResourceLoaderOptions& options, CORSEnabled corsEnabled)
+StyleFetchedImage* CSSImageValue::cachedImage(ResourceFetcher* fetcher, const ResourceLoaderOptions& options)
{
ASSERT(fetcher);
if (!m_accessedImage) {
m_accessedImage = true;
- FetchRequest request(ResourceRequest(fetcher->document()->completeURL(m_url)), m_initiatorName.isEmpty() ? FetchInitiatorTypeNames::css : m_initiatorName, options);
+ FetchRequest request(ResourceRequest(m_absoluteURL), m_initiatorName.isEmpty() ? FetchInitiatorTypeNames::css : m_initiatorName, options);
+ request.mutableResourceRequest().setHTTPReferrer(m_referrer);
- if (corsEnabled == PotentiallyCORSEnabled)
- updateRequestForAccessControl(request.mutableResourceRequest(), fetcher->document()->securityOrigin(), options.allowCredentials);
+ if (options.corsEnabled == IsCORSEnabled)
+ request.setCrossOriginAccessControl(fetcher->document()->securityOrigin(), options.allowCredentials, options.credentialsRequested);
if (ResourcePtr<ImageResource> cachedImage = fetcher->fetchImage(request))
m_image = StyleFetchedImage::create(cachedImage.get());
@@ -78,6 +74,21 @@ StyleFetchedImage* CSSImageValue::cachedImage(ResourceFetcher* fetcher, const Re
return (m_image && m_image->isImageResource()) ? toStyleFetchedImage(m_image) : 0;
}
+void CSSImageValue::restoreCachedResourceIfNeeded(Document& document)
+{
+ if (!m_accessedImage || !m_image->isImageResource() || !document.fetcher())
+ return;
+ if (document.fetcher()->cachedResource(KURL(ParsedURLString, m_absoluteURL)))
+ return;
+
+ ImageResource* resource = m_image->cachedImage();
+ if (!resource)
+ return;
+
+ FetchRequest request(ResourceRequest(m_absoluteURL), m_initiatorName.isEmpty() ? FetchInitiatorTypeNames::css : m_initiatorName, resource->options());
+ document.fetcher()->requestLoadStarted(resource, request, ResourceFetcher::ResourceLoadingFromCache);
+}
+
bool CSSImageValue::hasFailedOrCanceledSubresources() const
{
if (!m_image || !m_image->isImageResource())
@@ -89,18 +100,18 @@ bool CSSImageValue::hasFailedOrCanceledSubresources() const
bool CSSImageValue::equals(const CSSImageValue& other) const
{
- return m_url == other.m_url;
+ return m_absoluteURL == other.m_absoluteURL;
}
String CSSImageValue::customCSSText() const
{
- return "url(" + quoteCSSURLIfNeeded(m_url) + ")";
+ return "url(" + quoteCSSURLIfNeeded(m_absoluteURL) + ")";
}
-PassRefPtr<CSSValue> CSSImageValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSValue> CSSImageValue::cloneForCSSOM() const
{
// NOTE: We expose CSSImageValues as URI primitive values in CSSOM to maintain old behavior.
- RefPtr<CSSPrimitiveValue> uriValue = CSSPrimitiveValue::create(m_url, CSSPrimitiveValue::CSS_URI);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> uriValue = CSSPrimitiveValue::create(m_absoluteURL, CSSPrimitiveValue::CSS_URI);
uriValue->setCSSOMSafe();
return uriValue.release();
}
@@ -110,4 +121,19 @@ bool CSSImageValue::knownToBeOpaque(const RenderObject* renderer) const
return m_image ? m_image->knownToBeOpaque(renderer) : false;
}
+void CSSImageValue::traceAfterDispatch(Visitor* visitor)
+{
+ CSSValue::traceAfterDispatch(visitor);
+}
+
+void CSSImageValue::reResolveURL(const Document& document)
+{
+ KURL url = document.completeURL(m_relativeURL);
+ if (url == m_absoluteURL)
+ return;
+ m_absoluteURL = url.string();
+ m_accessedImage = false;
+ m_image.clear();
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSImageValue.h b/chromium/third_party/WebKit/Source/core/css/CSSImageValue.h
index a84afa5947a..4dce66191bb 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSImageValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSImageValue.h
@@ -23,31 +23,45 @@
#include "core/css/CSSValue.h"
#include "core/fetch/ResourceFetcher.h"
+#include "platform/weborigin/Referrer.h"
#include "wtf/RefPtr.h"
namespace WebCore {
+class Document;
class Element;
+class KURL;
class StyleFetchedImage;
class StyleImage;
class RenderObject;
class CSSImageValue : public CSSValue {
public:
- static PassRefPtr<CSSImageValue> create(const String& url) { return adoptRef(new CSSImageValue(url)); }
- static PassRefPtr<CSSImageValue> create(const String& url, StyleImage* image) { return adoptRef(new CSSImageValue(url, image)); }
+ static PassRefPtrWillBeRawPtr<CSSImageValue> create(const KURL& url, StyleImage* image = 0)
+ {
+ return adoptRefWillBeNoop(new CSSImageValue(url, url, image));
+ }
+ static PassRefPtrWillBeRawPtr<CSSImageValue> create(const String& rawValue, const KURL& url, StyleImage* image = 0)
+ {
+ return adoptRefWillBeNoop(new CSSImageValue(rawValue, url, image));
+ }
~CSSImageValue();
- StyleFetchedImage* cachedImage(ResourceFetcher*, const ResourceLoaderOptions&, CORSEnabled);
- StyleFetchedImage* cachedImage(ResourceFetcher* fetcher) { return cachedImage(fetcher, ResourceFetcher::defaultResourceOptions(), NotCORSEnabled); }
+ StyleFetchedImage* cachedImage(ResourceFetcher*, const ResourceLoaderOptions&);
+ StyleFetchedImage* cachedImage(ResourceFetcher* fetcher) { return cachedImage(fetcher, ResourceFetcher::defaultResourceOptions()); }
// Returns a StyleFetchedImage if the image is cached already, otherwise a StylePendingImage.
StyleImage* cachedOrPendingImage();
- const String& url() { return m_url; }
+ const String& url() { return m_absoluteURL; }
+
+ void setReferrer(const Referrer& referrer) { m_referrer = referrer; }
+ const Referrer& referrer() const { return m_referrer; }
+
+ void reResolveURL(const Document&);
String customCSSText() const;
- PassRefPtr<CSSValue> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<CSSValue> cloneForCSSOM() const;
bool hasFailedOrCanceledSubresources() const;
@@ -57,11 +71,15 @@ public:
void setInitiator(const AtomicString& name) { m_initiatorName = name; }
+ void traceAfterDispatch(Visitor*);
+ void restoreCachedResourceIfNeeded(Document&);
+
private:
- explicit CSSImageValue(const String& url);
- CSSImageValue(const String& url, StyleImage*);
+ CSSImageValue(const String& rawValue, const KURL&, StyleImage*);
- String m_url;
+ String m_relativeURL;
+ String m_absoluteURL;
+ Referrer m_referrer;
RefPtr<StyleImage> m_image;
bool m_accessedImage;
AtomicString m_initiatorName;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSImportRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSImportRule.cpp
index cf733f70f3c..e7d6219cbc1 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSImportRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSImportRule.cpp
@@ -38,10 +38,13 @@ CSSImportRule::CSSImportRule(StyleRuleImport* importRule, CSSStyleSheet* parent)
CSSImportRule::~CSSImportRule()
{
+#if !ENABLE(OILPAN)
if (m_styleSheetCSSOMWrapper)
m_styleSheetCSSOMWrapper->clearOwnerRule();
+
if (m_mediaCSSOMWrapper)
m_mediaCSSOMWrapper->clearParentRule();
+#endif // ENABLE(OILPAN)
}
String CSSImportRule::href() const
@@ -91,4 +94,12 @@ void CSSImportRule::reattach(StyleRuleBase*)
ASSERT_NOT_REACHED();
}
+void CSSImportRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_importRule);
+ visitor->trace(m_mediaCSSOMWrapper);
+ visitor->trace(m_styleSheetCSSOMWrapper);
+ CSSRule::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSImportRule.h b/chromium/third_party/WebKit/Source/core/css/CSSImportRule.h
index 0abfc9a3284..117e60de469 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSImportRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSImportRule.h
@@ -23,6 +23,7 @@
#define CSSImportRule_h
#include "core/css/CSSRule.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -31,9 +32,12 @@ class MediaList;
class MediaQuerySet;
class StyleRuleImport;
-class CSSImportRule : public CSSRule {
+class CSSImportRule FINAL : public CSSRule {
public:
- static PassRefPtr<CSSImportRule> create(StyleRuleImport* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSImportRule(rule, sheet)); }
+ static PassRefPtrWillBeRawPtr<CSSImportRule> create(StyleRuleImport* rule, CSSStyleSheet* sheet)
+ {
+ return adoptRefWillBeNoop(new CSSImportRule(rule, sheet));
+ }
virtual ~CSSImportRule();
@@ -45,12 +49,14 @@ public:
MediaList* media() const;
CSSStyleSheet* styleSheet() const;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSImportRule(StyleRuleImport*, CSSStyleSheet*);
- RefPtr<StyleRuleImport> m_importRule;
- mutable RefPtr<MediaList> m_mediaCSSOMWrapper;
- mutable RefPtr<CSSStyleSheet> m_styleSheetCSSOMWrapper;
+ RefPtrWillBeMember<StyleRuleImport> m_importRule;
+ mutable RefPtrWillBeMember<MediaList> m_mediaCSSOMWrapper;
+ mutable RefPtrWillBeMember<CSSStyleSheet> m_styleSheetCSSOMWrapper;
};
DEFINE_CSS_RULE_TYPE_CASTS(CSSImportRule, IMPORT_RULE);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSInheritedValue.h b/chromium/third_party/WebKit/Source/core/css/CSSInheritedValue.h
index 7367707daf6..8f1fe97225a 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSInheritedValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSInheritedValue.h
@@ -28,15 +28,17 @@ namespace WebCore {
class CSSInheritedValue : public CSSValue {
public:
- static PassRefPtr<CSSInheritedValue> create()
+ static PassRefPtrWillBeRawPtr<CSSInheritedValue> create()
{
- return adoptRef(new CSSInheritedValue);
+ return adoptRefWillBeNoop(new CSSInheritedValue);
}
String customCSSText() const;
bool equals(const CSSInheritedValue&) const { return true; }
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
CSSInheritedValue()
: CSSValue(InheritedClass)
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSInitialValue.h b/chromium/third_party/WebKit/Source/core/css/CSSInitialValue.h
index f8f9e512fce..43d82de9631 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSInitialValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSInitialValue.h
@@ -28,13 +28,13 @@ namespace WebCore {
class CSSInitialValue : public CSSValue {
public:
- static PassRefPtr<CSSInitialValue> createExplicit()
+ static PassRefPtrWillBeRawPtr<CSSInitialValue> createExplicit()
{
- return adoptRef(new CSSInitialValue(/* implicit */ false));
+ return adoptRefWillBeNoop(new CSSInitialValue(/* implicit */ false));
}
- static PassRefPtr<CSSInitialValue> createImplicit()
+ static PassRefPtrWillBeRawPtr<CSSInitialValue> createImplicit()
{
- return adoptRef(new CSSInitialValue(/* implicit */ true));
+ return adoptRefWillBeNoop(new CSSInitialValue(/* implicit */ true));
}
String customCSSText() const;
@@ -43,6 +43,8 @@ public:
bool equals(const CSSInitialValue&) const { return true; }
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
explicit CSSInitialValue(bool implicit)
: CSSValue(InitialClass)
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.cpp
index 65aa3077c93..34e395660ad 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.cpp
@@ -27,9 +27,10 @@
#include "core/css/CSSKeyframeRule.h"
#include "core/css/CSSKeyframesRule.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
#include "core/css/StylePropertySet.h"
+#include "core/frame/UseCounter.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -76,7 +77,7 @@ const Vector<double>& StyleKeyframe::keys() const
// Keys can only be cleared by setting the key text from JavaScript
// and this can never be null.
ASSERT(!m_keyText.isNull());
- m_keys = CSSParser(HTMLStandardMode).parseKeyframeKeyList(m_keyText);
+ m_keys = BisonCSSParser(strictCSSParserContext()).parseKeyframeKeyList(m_keyText);
}
// If an invalid key string was set, m_keys may be empty.
ASSERT(m_keys);
@@ -91,15 +92,16 @@ void StyleKeyframe::setKeys(PassOwnPtr<Vector<double> > keys)
ASSERT(m_keyText.isNull());
}
-MutableStylePropertySet* StyleKeyframe::mutableProperties()
+MutableStylePropertySet& StyleKeyframe::mutableProperties()
{
if (!m_properties->isMutable())
m_properties = m_properties->mutableCopy();
- return toMutableStylePropertySet(m_properties);
+ return *toMutableStylePropertySet(m_properties);
}
void StyleKeyframe::setProperties(PassRefPtr<StylePropertySet> properties)
{
+ ASSERT(properties);
m_properties = properties;
}
@@ -144,8 +146,10 @@ CSSKeyframeRule::CSSKeyframeRule(StyleKeyframe* keyframe, CSSKeyframesRule* pare
CSSKeyframeRule::~CSSKeyframeRule()
{
+#if !ENABLE(OILPAN)
if (m_propertiesCSSOMWrapper)
m_propertiesCSSOMWrapper->clearParentRule();
+#endif
}
CSSStyleDeclaration* CSSKeyframeRule::style() const
@@ -161,4 +165,11 @@ void CSSKeyframeRule::reattach(StyleRuleBase*)
ASSERT_NOT_REACHED();
}
+void CSSKeyframeRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_keyframe);
+ visitor->trace(m_propertiesCSSOMWrapper);
+ CSSRule::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.h b/chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.h
index 594314808f9..48f1bfaf0a5 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSKeyframeRule.h
@@ -37,12 +37,12 @@ class MutableStylePropertySet;
class StylePropertySet;
class StyleRuleCSSStyleDeclaration;
-class StyleKeyframe FINAL : public RefCounted<StyleKeyframe> {
- WTF_MAKE_FAST_ALLOCATED;
+class StyleKeyframe FINAL : public RefCountedWillBeGarbageCollectedFinalized<StyleKeyframe> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<StyleKeyframe> create()
+ static PassRefPtrWillBeRawPtr<StyleKeyframe> create()
{
- return adoptRef(new StyleKeyframe());
+ return adoptRefWillBeNoop(new StyleKeyframe());
}
~StyleKeyframe();
@@ -52,15 +52,17 @@ public:
// Used by StyleResolver.
const Vector<double>& keys() const;
- // Used by CSSParser when constructing a new StyleKeyframe.
+ // Used by BisonCSSParser when constructing a new StyleKeyframe.
void setKeys(PassOwnPtr<Vector<double> >);
- const StylePropertySet* properties() const { return m_properties.get(); }
- MutableStylePropertySet* mutableProperties();
+ const StylePropertySet& properties() const { return *m_properties; }
+ MutableStylePropertySet& mutableProperties();
void setProperties(PassRefPtr<StylePropertySet>);
String cssText() const;
+ void trace(Visitor*) { }
+
static PassOwnPtr<Vector<double> > createKeyList(CSSParserValueList*);
private:
@@ -85,11 +87,13 @@ public:
CSSStyleDeclaration* style() const;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSKeyframeRule(StyleKeyframe*, CSSKeyframesRule* parent);
- RefPtr<StyleKeyframe> m_keyframe;
- mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
+ RefPtrWillBeMember<StyleKeyframe> m_keyframe;
+ mutable RefPtrWillBeMember<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
friend class CSSKeyframesRule;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.cpp
index 94d5dff8e6a..cd78e79f272 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.cpp
@@ -27,9 +27,10 @@
#include "core/css/CSSKeyframesRule.h"
#include "core/css/CSSKeyframeRule.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSStyleSheet.h"
+#include "core/frame/UseCounter.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -51,14 +52,14 @@ StyleRuleKeyframes::~StyleRuleKeyframes()
{
}
-void StyleRuleKeyframes::parserAppendKeyframe(PassRefPtr<StyleKeyframe> keyframe)
+void StyleRuleKeyframes::parserAppendKeyframe(PassRefPtrWillBeRawPtr<StyleKeyframe> keyframe)
{
if (!keyframe)
return;
m_keyframes.append(keyframe);
}
-void StyleRuleKeyframes::wrapperAppendKeyframe(PassRefPtr<StyleKeyframe> keyframe)
+void StyleRuleKeyframes::wrapperAppendKeyframe(PassRefPtrWillBeRawPtr<StyleKeyframe> keyframe)
{
m_keyframes.append(keyframe);
}
@@ -85,6 +86,12 @@ int StyleRuleKeyframes::findKeyframeIndex(const String& key) const
return -1;
}
+void StyleRuleKeyframes::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_keyframes);
+ StyleRuleBase::traceAfterDispatch(visitor);
+}
+
CSSKeyframesRule::CSSKeyframesRule(StyleRuleKeyframes* keyframesRule, CSSStyleSheet* parent)
: CSSRule(parent)
, m_keyframesRule(keyframesRule)
@@ -95,12 +102,13 @@ CSSKeyframesRule::CSSKeyframesRule(StyleRuleKeyframes* keyframesRule, CSSStyleSh
CSSKeyframesRule::~CSSKeyframesRule()
{
+#if !ENABLE(OILPAN)
ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
-
for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
if (m_childRuleCSSOMWrappers[i])
m_childRuleCSSOMWrappers[i]->setParentRule(0);
}
+#endif
}
void CSSKeyframesRule::setName(const String& name)
@@ -115,8 +123,9 @@ void CSSKeyframesRule::insertRule(const String& ruleText)
ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
CSSStyleSheet* styleSheet = parentStyleSheet();
- CSSParser parser(parserContext(), UseCounter::getFrom(styleSheet));
- RefPtr<StyleKeyframe> keyframe = parser.parseKeyframeRule(styleSheet ? styleSheet->contents() : 0, ruleText);
+ CSSParserContext context(parserContext(), UseCounter::getFrom(styleSheet));
+ BisonCSSParser parser(context);
+ RefPtrWillBeRawPtr<StyleKeyframe> keyframe = parser.parseKeyframeRule(styleSheet ? styleSheet->contents() : 0, ruleText);
if (!keyframe)
return;
@@ -181,9 +190,9 @@ CSSKeyframeRule* CSSKeyframesRule::item(unsigned index) const
return 0;
ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
- RefPtr<CSSKeyframeRule>& rule = m_childRuleCSSOMWrappers[index];
+ RefPtrWillBeMember<CSSKeyframeRule>& rule = m_childRuleCSSOMWrappers[index];
if (!rule)
- rule = adoptRef(new CSSKeyframeRule(m_keyframesRule->keyframes()[index].get(), const_cast<CSSKeyframesRule*>(this)));
+ rule = adoptRefWillBeNoop(new CSSKeyframeRule(m_keyframesRule->keyframes()[index].get(), const_cast<CSSKeyframesRule*>(this)));
return rule.get();
}
@@ -191,7 +200,7 @@ CSSKeyframeRule* CSSKeyframesRule::item(unsigned index) const
CSSRuleList* CSSKeyframesRule::cssRules()
{
if (!m_ruleListCSSOMWrapper)
- m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSKeyframesRule>(this));
+ m_ruleListCSSOMWrapper = LiveCSSRuleList<CSSKeyframesRule>::create(this);
return m_ruleListCSSOMWrapper.get();
}
@@ -201,4 +210,14 @@ void CSSKeyframesRule::reattach(StyleRuleBase* rule)
m_keyframesRule = toStyleRuleKeyframes(rule);
}
+void CSSKeyframesRule::trace(Visitor* visitor)
+{
+ CSSRule::trace(visitor);
+#if ENABLE(OILPAN)
+ visitor->trace(m_childRuleCSSOMWrappers);
+#endif
+ visitor->trace(m_keyframesRule);
+ visitor->trace(m_ruleListCSSOMWrapper);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.h b/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.h
index d74cf686e75..aebdc196933 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.h
@@ -39,14 +39,14 @@ class CSSKeyframeRule;
class StyleRuleKeyframes FINAL : public StyleRuleBase {
public:
- static PassRefPtr<StyleRuleKeyframes> create() { return adoptRef(new StyleRuleKeyframes()); }
+ static PassRefPtrWillBeRawPtr<StyleRuleKeyframes> create() { return adoptRefWillBeNoop(new StyleRuleKeyframes()); }
~StyleRuleKeyframes();
- const Vector<RefPtr<StyleKeyframe> >& keyframes() const { return m_keyframes; }
+ const WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >& keyframes() const { return m_keyframes; }
- void parserAppendKeyframe(PassRefPtr<StyleKeyframe>);
- void wrapperAppendKeyframe(PassRefPtr<StyleKeyframe>);
+ void parserAppendKeyframe(PassRefPtrWillBeRawPtr<StyleKeyframe>);
+ void wrapperAppendKeyframe(PassRefPtrWillBeRawPtr<StyleKeyframe>);
void wrapperRemoveKeyframe(unsigned);
String name() const { return m_name; }
@@ -57,13 +57,15 @@ public:
int findKeyframeIndex(const String& key) const;
- PassRefPtr<StyleRuleKeyframes> copy() const { return adoptRef(new StyleRuleKeyframes(*this)); }
+ PassRefPtrWillBeRawPtr<StyleRuleKeyframes> copy() const { return adoptRefWillBeNoop(new StyleRuleKeyframes(*this)); }
+
+ void traceAfterDispatch(Visitor*);
private:
StyleRuleKeyframes();
explicit StyleRuleKeyframes(const StyleRuleKeyframes&);
- Vector<RefPtr<StyleKeyframe> > m_keyframes;
+ WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > m_keyframes;
AtomicString m_name;
bool m_isPrefixed;
};
@@ -72,7 +74,10 @@ DEFINE_STYLE_RULE_TYPE_CASTS(Keyframes);
class CSSKeyframesRule FINAL : public CSSRule {
public:
- static PassRefPtr<CSSKeyframesRule> create(StyleRuleKeyframes* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSKeyframesRule(rule, sheet)); }
+ static PassRefPtrWillBeRawPtr<CSSKeyframesRule> create(StyleRuleKeyframes* rule, CSSStyleSheet* sheet)
+ {
+ return adoptRefWillBeNoop(new CSSKeyframesRule(rule, sheet));
+ }
virtual ~CSSKeyframesRule();
@@ -96,12 +101,14 @@ public:
bool isVendorPrefixed() const { return m_isPrefixed; }
void setVendorPrefixed(bool isPrefixed) { m_isPrefixed = isPrefixed; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSKeyframesRule(StyleRuleKeyframes*, CSSStyleSheet* parent);
- RefPtr<StyleRuleKeyframes> m_keyframesRule;
- mutable Vector<RefPtr<CSSKeyframeRule> > m_childRuleCSSOMWrappers;
- mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
+ RefPtrWillBeMember<StyleRuleKeyframes> m_keyframesRule;
+ mutable WillBeHeapVector<RefPtrWillBeMember<CSSKeyframeRule> > m_childRuleCSSOMWrappers;
+ mutable OwnPtrWillBeMember<CSSRuleList> m_ruleListCSSOMWrapper;
bool m_isPrefixed;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.idl b/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.idl
index d97dd4aae3b..d85f8d19f17 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.idl
+++ b/chromium/third_party/WebKit/Source/core/css/CSSKeyframesRule.idl
@@ -31,7 +31,7 @@ interface CSSKeyframesRule : CSSRule {
attribute DOMString name;
readonly attribute CSSRuleList cssRules;
- [ImplementedAs=item, NotEnumerable] getter CSSKeyframeRule(unsigned long index);
+ [ImplementedAs=item, NotEnumerable] getter CSSKeyframeRule (unsigned long index);
void insertRule([Default=Undefined] optional DOMString rule);
void deleteRule([Default=Undefined] optional DOMString key);
CSSKeyframeRule findRule([Default=Undefined] optional DOMString key);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSLengthFunctions.cpp b/chromium/third_party/WebKit/Source/core/css/CSSLengthFunctions.cpp
deleted file mode 100644
index 94acda3c866..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSLengthFunctions.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
- Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com)
- Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- Copyright (C) 2012 Motorola Mobility, Inc. All rights reserved.
- Copyright (C) 2013 Google, Inc. All rights reserved.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#include "config.h"
-#include "core/css/CSSLengthFunctions.h"
-
-#include "core/rendering/RenderView.h"
-#include "platform/LayoutUnit.h"
-#include "platform/Length.h"
-#include "platform/LengthFunctions.h"
-
-namespace WebCore {
-
-int minimumIntValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages)
-{
- return static_cast<int>(minimumValueForLength(length, maximumValue, renderView, roundPercentages));
-}
-
-int intValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages)
-{
- return static_cast<int>(valueForLength(length, maximumValue, renderView, roundPercentages));
-}
-
-LayoutUnit minimumValueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages)
-{
- switch (length.type()) {
- case Fixed:
- return length.value();
- case Percent:
- if (roundPercentages)
- return static_cast<LayoutUnit>(round(maximumValue * length.percent() / 100.0f));
- // Don't remove the extra cast to float. It is needed for rounding on 32-bit Intel machines that use the FPU stack.
- return static_cast<float>(maximumValue * length.percent() / 100.0f);
- case Calculated:
- return length.nonNanCalculatedValue(maximumValue);
- case ViewportPercentageWidth:
- return renderView ? renderView->viewportPercentageWidth(length.viewportPercentageLength()) : LayoutUnit(0);
- case ViewportPercentageHeight:
- return renderView ? renderView->viewportPercentageHeight(length.viewportPercentageLength()) : LayoutUnit(0);
- case ViewportPercentageMin:
- return renderView ? renderView->viewportPercentageMin(length.viewportPercentageLength()) : LayoutUnit(0);
- case ViewportPercentageMax:
- return renderView ? renderView->viewportPercentageMax(length.viewportPercentageLength()) : LayoutUnit(0);
- case FillAvailable:
- case Auto:
- return 0;
- case Intrinsic:
- case MinIntrinsic:
- case MinContent:
- case MaxContent:
- case FitContent:
- case ExtendToZoom:
- case Undefined:
- ASSERT_NOT_REACHED();
- return 0;
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-LayoutUnit valueForLength(const Length& length, LayoutUnit maximumValue, RenderView* renderView, bool roundPercentages)
-{
- switch (length.type()) {
- case Fixed:
- case Percent:
- case Calculated:
- case ViewportPercentageWidth:
- case ViewportPercentageHeight:
- case ViewportPercentageMin:
- case ViewportPercentageMax:
- return minimumValueForLength(length, maximumValue, renderView, roundPercentages);
- case FillAvailable:
- case Auto:
- return maximumValue;
- case Intrinsic:
- case MinIntrinsic:
- case MinContent:
- case MaxContent:
- case FitContent:
- case ExtendToZoom:
- case Undefined:
- ASSERT_NOT_REACHED();
- return 0;
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-// This method has code duplicated in platform/LengthFunctions.cpp.
-// Any changes here most likely also need to be applied there.
-float floatValueForLength(const Length& length, float maximumValue, RenderView* renderView)
-{
- if (!renderView)
- return floatValueForLength(length, maximumValue);
-
- switch (length.type()) {
- case Fixed:
- return length.getFloatValue();
- case Percent:
- return static_cast<float>(maximumValue * length.percent() / 100.0f);
- case FillAvailable:
- case Auto:
- return static_cast<float>(maximumValue);
- case Calculated:
- return length.nonNanCalculatedValue(maximumValue);
- case ViewportPercentageWidth:
- return static_cast<int>(renderView->viewportPercentageWidth(length.viewportPercentageLength()));
- case ViewportPercentageHeight:
- return static_cast<int>(renderView->viewportPercentageHeight(length.viewportPercentageLength()));
- case ViewportPercentageMin:
- return static_cast<int>(renderView->viewportPercentageMin(length.viewportPercentageLength()));
- case ViewportPercentageMax:
- return static_cast<int>(renderView->viewportPercentageMax(length.viewportPercentageLength()));
- case Intrinsic:
- case MinIntrinsic:
- case MinContent:
- case MaxContent:
- case FitContent:
- case ExtendToZoom:
- case Undefined:
- ASSERT_NOT_REACHED();
- return 0;
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSLengthFunctions.h b/chromium/third_party/WebKit/Source/core/css/CSSLengthFunctions.h
deleted file mode 100644
index 46e3540c180..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSLengthFunctions.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
- Copyright (C) 2011 Rik Cabanier (cabanier@adobe.com)
- Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- Copyright (C) 2012 Motorola Mobility, Inc. All rights reserved.
- Copyright (C) 2013 Google, Inc. All rights reserved.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#ifndef CSSLengthFunctions_h
-#define CSSLengthFunctions_h
-
-namespace WebCore {
-
-class LayoutUnit;
-class Length;
-class RenderView;
-
-int minimumIntValueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0, bool roundPercentages = false);
-int intValueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0, bool roundPercentages = false);
-LayoutUnit minimumValueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0, bool roundPercentages = false);
-LayoutUnit valueForLength(const Length&, LayoutUnit maximumValue, RenderView* = 0, bool roundPercentages = false);
-float floatValueForLength(const Length&, float maximumValue, RenderView*);
-
-} // namespace WebCore
-
-#endif // CSSLengthFunctions_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSLineBoxContainValue.h b/chromium/third_party/WebKit/Source/core/css/CSSLineBoxContainValue.h
index 657578ab251..92d6de2203f 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSLineBoxContainValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSLineBoxContainValue.h
@@ -40,15 +40,17 @@ typedef unsigned LineBoxContain;
// Used for text-CSSLineBoxContain and box-CSSLineBoxContain
class CSSLineBoxContainValue : public CSSValue {
public:
- static PassRefPtr<CSSLineBoxContainValue> create(LineBoxContain value)
+ static PassRefPtrWillBeRawPtr<CSSLineBoxContainValue> create(LineBoxContain value)
{
- return adoptRef(new CSSLineBoxContainValue(value));
+ return adoptRefWillBeNoop(new CSSLineBoxContainValue(value));
}
String customCSSText() const;
bool equals(const CSSLineBoxContainValue& other) const { return m_value == other.m_value; }
LineBoxContain value() const { return m_value; }
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
LineBoxContain m_value;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSMarkup.cpp b/chromium/third_party/WebKit/Source/core/css/CSSMarkup.cpp
new file mode 100644
index 00000000000..cc473538a06
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSMarkup.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/css/CSSMarkup.h"
+
+#include "wtf/HexNumber.h"
+#include "wtf/text/StringBuffer.h"
+
+namespace WebCore {
+
+template <typename CharacterType>
+static inline bool isCSSTokenizerIdentifier(const CharacterType* characters, unsigned length)
+{
+ const CharacterType* end = characters + length;
+
+ // -?
+ if (characters != end && characters[0] == '-')
+ ++characters;
+
+ // {nmstart}
+ if (characters == end || !(characters[0] == '_' || characters[0] >= 128 || isASCIIAlpha(characters[0])))
+ return false;
+ ++characters;
+
+ // {nmchar}*
+ for (; characters != end; ++characters) {
+ if (!(characters[0] == '_' || characters[0] == '-' || characters[0] >= 128 || isASCIIAlphanumeric(characters[0])))
+ return false;
+ }
+
+ return true;
+}
+
+// "ident" from the CSS tokenizer, minus backslash-escape sequences
+static bool isCSSTokenizerIdentifier(const String& string)
+{
+ unsigned length = string.length();
+
+ if (!length)
+ return false;
+
+ if (string.is8Bit())
+ return isCSSTokenizerIdentifier(string.characters8(), length);
+ return isCSSTokenizerIdentifier(string.characters16(), length);
+}
+
+template <typename CharacterType>
+static inline bool isCSSTokenizerURL(const CharacterType* characters, unsigned length)
+{
+ const CharacterType* end = characters + length;
+
+ for (; characters != end; ++characters) {
+ CharacterType c = characters[0];
+ switch (c) {
+ case '!':
+ case '#':
+ case '$':
+ case '%':
+ case '&':
+ break;
+ default:
+ if (c < '*')
+ return false;
+ if (c <= '~')
+ break;
+ if (c < 128)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// "url" from the CSS tokenizer, minus backslash-escape sequences
+static bool isCSSTokenizerURL(const String& string)
+{
+ unsigned length = string.length();
+
+ if (!length)
+ return true;
+
+ if (string.is8Bit())
+ return isCSSTokenizerURL(string.characters8(), length);
+ return isCSSTokenizerURL(string.characters16(), length);
+}
+
+template <typename CharacterType>
+static inline String quoteCSSStringInternal(const CharacterType* characters, unsigned length)
+{
+ // For efficiency, we first pre-calculate the length of the quoted string, then we build the actual one.
+ // Please see below for the actual logic.
+ unsigned quotedStringSize = 2; // Two quotes surrounding the entire string.
+ bool afterEscape = false;
+ for (unsigned i = 0; i < length; ++i) {
+ CharacterType ch = characters[i];
+ if (ch == '\\' || ch == '\'') {
+ quotedStringSize += 2;
+ afterEscape = false;
+ } else if (ch < 0x20 || ch == 0x7F) {
+ quotedStringSize += 2 + (ch >= 0x10);
+ afterEscape = true;
+ } else {
+ quotedStringSize += 1 + (afterEscape && (isASCIIHexDigit(ch) || ch == ' '));
+ afterEscape = false;
+ }
+ }
+
+ StringBuffer<CharacterType> buffer(quotedStringSize);
+ unsigned index = 0;
+ buffer[index++] = '\'';
+ afterEscape = false;
+ for (unsigned i = 0; i < length; ++i) {
+ CharacterType ch = characters[i];
+ if (ch == '\\' || ch == '\'') {
+ buffer[index++] = '\\';
+ buffer[index++] = ch;
+ afterEscape = false;
+ } else if (ch < 0x20 || ch == 0x7F) { // Control characters.
+ buffer[index++] = '\\';
+ placeByteAsHexCompressIfPossible(ch, buffer, index, Lowercase);
+ afterEscape = true;
+ } else {
+ // Space character may be required to separate backslash-escape sequence and normal characters.
+ if (afterEscape && (isASCIIHexDigit(ch) || ch == ' '))
+ buffer[index++] = ' ';
+ buffer[index++] = ch;
+ afterEscape = false;
+ }
+ }
+ buffer[index++] = '\'';
+
+ ASSERT(quotedStringSize == index);
+ return String::adopt(buffer);
+}
+
+// We use single quotes for now because markup.cpp uses double quotes.
+String quoteCSSString(const String& string)
+{
+ // This function expands each character to at most 3 characters ('\u0010' -> '\' '1' '0') as well as adds
+ // 2 quote characters (before and after). Make sure the resulting size (3 * length + 2) will not overflow unsigned.
+
+ unsigned length = string.length();
+
+ if (!length)
+ return String("\'\'");
+
+ if (length > std::numeric_limits<unsigned>::max() / 3 - 2)
+ return emptyString();
+
+ if (string.is8Bit())
+ return quoteCSSStringInternal(string.characters8(), length);
+ return quoteCSSStringInternal(string.characters16(), length);
+}
+
+String quoteCSSStringIfNeeded(const String& string)
+{
+ return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string);
+}
+
+String quoteCSSURLIfNeeded(const String& string)
+{
+ return isCSSTokenizerURL(string) ? string : quoteCSSString(string);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSMarkup.h b/chromium/third_party/WebKit/Source/core/css/CSSMarkup.h
new file mode 100644
index 00000000000..9d37fff3336
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSMarkup.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 - 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CSSMarkup_h
+#define CSSMarkup_h
+
+#include "wtf/text/WTFString.h"
+
+// Helper functions for converting from CSSValues to text.
+// FIXME: This file has a similar purpose to
+// CSSOMUtils.h. Perhaps the two should be combined?
+
+namespace WebCore {
+
+String quoteCSSString(const String&);
+String quoteCSSStringIfNeeded(const String&);
+String quoteCSSURLIfNeeded(const String&);
+
+} // namespace WebCore
+
+#endif // CSSMarkup_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSMatrix.cpp b/chromium/third_party/WebKit/Source/core/css/CSSMatrix.cpp
index 4926df97629..dc974c1a003 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSMatrix.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSMatrix.cpp
@@ -26,10 +26,10 @@
#include "config.h"
#include "core/css/CSSMatrix.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/css/CSSParser.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSToLengthConversionData.h"
#include "core/css/StylePropertySet.h"
#include "core/css/resolver/TransformBuilder.h"
@@ -57,11 +57,12 @@ void CSSMatrix::setMatrixValue(const String& string, ExceptionState& exceptionSt
if (string.isEmpty())
return;
- RefPtr<MutableStylePropertySet> styleDeclaration = MutableStylePropertySet::create();
- if (CSSParser::parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true, HTMLStandardMode, 0)) {
+ // FIXME: crbug.com/154722 - should this continue to use legacy style parsing?
+ RefPtrWillBeRawPtr<MutableStylePropertySet> styleDeclaration = MutableStylePropertySet::create();
+ if (BisonCSSParser::parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true, HTMLStandardMode, 0)) {
// Convert to TransformOperations. This can fail if a property
// requires style (i.e., param uses 'ems' or 'exs')
- RefPtr<CSSValue> value = styleDeclaration->getPropertyCSSValue(CSSPropertyWebkitTransform);
+ RefPtrWillBeRawPtr<CSSValue> value = styleDeclaration->getPropertyCSSValue(CSSPropertyWebkitTransform);
// Check for a "none" or empty transform. In these cases we can use the default identity matrix.
if (!value || (value->isPrimitiveValue() && (toCSSPrimitiveValue(value.get()))->getValueID() == CSSValueNone))
@@ -69,45 +70,45 @@ void CSSMatrix::setMatrixValue(const String& string, ExceptionState& exceptionSt
DEFINE_STATIC_REF(RenderStyle, defaultStyle, RenderStyle::createDefaultStyle());
TransformOperations operations;
- if (!TransformBuilder::createTransformOperations(value.get(), CSSToLengthConversionData(defaultStyle, defaultStyle), operations)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ if (!TransformBuilder::createTransformOperations(value.get(), CSSToLengthConversionData(defaultStyle, defaultStyle, 0, 0, 1.0f), operations)) {
+ exceptionState.throwDOMException(SyntaxError, "Failed to interpret '" + string + "' as a transformation operation.");
return;
}
// Convert transform operations to a TransformationMatrix. This can fail
// if a param has a percentage ('%')
if (operations.dependsOnBoxSize())
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The transformation depends on the box size, which is not supported.");
TransformationMatrix t;
operations.apply(FloatSize(0, 0), t);
// set the matrix
m_matrix = t;
} else { // There is something there but parsing failed.
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "Failed to parse '" + string + "'.");
}
}
// Perform a concatenation of the matrices (this * secondMatrix)
-PassRefPtr<CSSMatrix> CSSMatrix::multiply(CSSMatrix* secondMatrix) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::multiply(CSSMatrix* secondMatrix) const
{
if (!secondMatrix)
- return 0;
+ return nullptr;
return CSSMatrix::create(TransformationMatrix(m_matrix).multiply(secondMatrix->m_matrix));
}
-PassRefPtr<CSSMatrix> CSSMatrix::inverse(ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::inverse(ExceptionState& exceptionState) const
{
if (!m_matrix.isInvertible()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, "The matrix is not invertable.");
+ return nullptr;
}
return CSSMatrix::create(m_matrix.inverse());
}
-PassRefPtr<CSSMatrix> CSSMatrix::translate(double x, double y, double z) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::translate(double x, double y, double z) const
{
if (std::isnan(x))
x = 0;
@@ -118,7 +119,7 @@ PassRefPtr<CSSMatrix> CSSMatrix::translate(double x, double y, double z) const
return CSSMatrix::create(TransformationMatrix(m_matrix).translate3d(x, y, z));
}
-PassRefPtr<CSSMatrix> CSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const
{
if (std::isnan(scaleX))
scaleX = 1;
@@ -129,7 +130,7 @@ PassRefPtr<CSSMatrix> CSSMatrix::scale(double scaleX, double scaleY, double scal
return CSSMatrix::create(TransformationMatrix(m_matrix).scale3d(scaleX, scaleY, scaleZ));
}
-PassRefPtr<CSSMatrix> CSSMatrix::rotate(double rotX, double rotY, double rotZ) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::rotate(double rotX, double rotY, double rotZ) const
{
if (std::isnan(rotX))
rotX = 0;
@@ -147,7 +148,7 @@ PassRefPtr<CSSMatrix> CSSMatrix::rotate(double rotX, double rotY, double rotZ) c
return CSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(rotX, rotY, rotZ));
}
-PassRefPtr<CSSMatrix> CSSMatrix::rotateAxisAngle(double x, double y, double z, double angle) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::rotateAxisAngle(double x, double y, double z, double angle) const
{
if (std::isnan(x))
x = 0;
@@ -162,14 +163,14 @@ PassRefPtr<CSSMatrix> CSSMatrix::rotateAxisAngle(double x, double y, double z, d
return CSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(x, y, z, angle));
}
-PassRefPtr<CSSMatrix> CSSMatrix::skewX(double angle) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::skewX(double angle) const
{
if (std::isnan(angle))
angle = 0;
return CSSMatrix::create(TransformationMatrix(m_matrix).skewX(angle));
}
-PassRefPtr<CSSMatrix> CSSMatrix::skewY(double angle) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::skewY(double angle) const
{
if (std::isnan(angle))
angle = 0;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSMatrix.h b/chromium/third_party/WebKit/Source/core/css/CSSMatrix.h
index 92c6cb1ab08..e62009791c2 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSMatrix.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSMatrix.h
@@ -35,15 +35,15 @@ namespace WebCore {
class ExceptionState;
-class CSSMatrix FINAL : public ScriptWrappable, public RefCounted<CSSMatrix> {
+class CSSMatrix FINAL : public RefCountedWillBeGarbageCollectedFinalized<CSSMatrix>, public ScriptWrappable {
public:
- static PassRefPtr<CSSMatrix> create(const TransformationMatrix& m)
+ static PassRefPtrWillBeRawPtr<CSSMatrix> create(const TransformationMatrix& m)
{
- return adoptRef(new CSSMatrix(m));
+ return adoptRefWillBeNoop(new CSSMatrix(m));
}
- static PassRefPtr<CSSMatrix> create(const String& s, ExceptionState& exceptionState)
+ static PassRefPtrWillBeRawPtr<CSSMatrix> create(const String& s, ExceptionState& exceptionState)
{
- return adoptRef(new CSSMatrix(s, exceptionState));
+ return adoptRefWillBeNoop(new CSSMatrix(s, exceptionState));
}
double a() const { return m_matrix.a(); }
@@ -100,53 +100,55 @@ public:
// specified operation applied. The this value is not modified.
// Multiply this matrix by secondMatrix, on the right (result = this * secondMatrix)
- PassRefPtr<CSSMatrix> multiply(CSSMatrix* secondMatrix) const;
+ PassRefPtrWillBeRawPtr<CSSMatrix> multiply(CSSMatrix* secondMatrix) const;
// Return the inverse of this matrix. Throw an exception if the matrix is not invertible
- PassRefPtr<CSSMatrix> inverse(ExceptionState&) const;
+ PassRefPtrWillBeRawPtr<CSSMatrix> inverse(ExceptionState&) const;
// Return this matrix translated by the passed values.
// Passing a NaN will use a value of 0. This allows the 3D form to used for 2D operations
// Operation is performed as though the this matrix is multiplied by a matrix with
// the translation values on the left (result = translation(x,y,z) * this)
- PassRefPtr<CSSMatrix> translate(double x, double y, double z) const;
+ PassRefPtrWillBeRawPtr<CSSMatrix> translate(double x, double y, double z) const;
// Returns this matrix scaled by the passed values.
// Passing scaleX or scaleZ as NaN uses a value of 1, but passing scaleY of NaN
// makes it the same as scaleX. This allows the 3D form to used for 2D operations
// Operation is performed as though the this matrix is multiplied by a matrix with
// the scale values on the left (result = scale(x,y,z) * this)
- PassRefPtr<CSSMatrix> scale(double scaleX, double scaleY, double scaleZ) const;
+ PassRefPtrWillBeRawPtr<CSSMatrix> scale(double scaleX, double scaleY, double scaleZ) const;
// Returns this matrix rotated by the passed values.
// If rotY and rotZ are NaN, rotate about Z (rotX=0, rotateY=0, rotateZ=rotX).
// Otherwise use a rotation value of 0 for any passed NaN.
// Operation is performed as though the this matrix is multiplied by a matrix with
// the rotation values on the left (result = rotation(x,y,z) * this)
- PassRefPtr<CSSMatrix> rotate(double rotX, double rotY, double rotZ) const;
+ PassRefPtrWillBeRawPtr<CSSMatrix> rotate(double rotX, double rotY, double rotZ) const;
// Returns this matrix rotated about the passed axis by the passed angle.
// Passing a NaN will use a value of 0. If the axis is (0,0,0) use a value
// Operation is performed as though the this matrix is multiplied by a matrix with
// the rotation values on the left (result = rotation(x,y,z,angle) * this)
- PassRefPtr<CSSMatrix> rotateAxisAngle(double x, double y, double z, double angle) const;
+ PassRefPtrWillBeRawPtr<CSSMatrix> rotateAxisAngle(double x, double y, double z, double angle) const;
// Return this matrix skewed along the X axis by the passed values.
// Passing a NaN will use a value of 0.
// Operation is performed as though the this matrix is multiplied by a matrix with
// the skew values on the left (result = skewX(angle) * this)
- PassRefPtr<CSSMatrix> skewX(double angle) const;
+ PassRefPtrWillBeRawPtr<CSSMatrix> skewX(double angle) const;
// Return this matrix skewed along the Y axis by the passed values.
// Passing a NaN will use a value of 0.
// Operation is performed as though the this matrix is multiplied by a matrix with
// the skew values on the left (result = skewY(angle) * this)
- PassRefPtr<CSSMatrix> skewY(double angle) const;
+ PassRefPtrWillBeRawPtr<CSSMatrix> skewY(double angle) const;
const TransformationMatrix& transform() const { return m_matrix; }
String toString() const;
+ void trace(Visitor*) { }
+
protected:
CSSMatrix(const TransformationMatrix&);
CSSMatrix(const String&, ExceptionState&);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSMediaRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSMediaRule.cpp
index 7e8c34a5945..dedea18c4a3 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSMediaRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSMediaRule.cpp
@@ -35,8 +35,10 @@ CSSMediaRule::CSSMediaRule(StyleRuleMedia* mediaRule, CSSStyleSheet* parent)
CSSMediaRule::~CSSMediaRule()
{
+#if !ENABLE(OILPAN)
if (m_mediaCSSOMWrapper)
m_mediaCSSOMWrapper->clearParentRule();
+#endif
}
MediaQuerySet* CSSMediaRule::mediaQueries() const
@@ -74,4 +76,9 @@ void CSSMediaRule::reattach(StyleRuleBase* rule)
m_mediaCSSOMWrapper->reattach(mediaQueries());
}
+void CSSMediaRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_mediaCSSOMWrapper);
+ CSSGroupingRule::trace(visitor);
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSMediaRule.h b/chromium/third_party/WebKit/Source/core/css/CSSMediaRule.h
index 380c062c122..fb6895816d6 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSMediaRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSMediaRule.h
@@ -30,9 +30,12 @@ namespace WebCore {
class StyleRuleMedia;
-class CSSMediaRule : public CSSGroupingRule {
+class CSSMediaRule FINAL : public CSSGroupingRule {
public:
- static PassRefPtr<CSSMediaRule> create(StyleRuleMedia* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSMediaRule(rule, sheet)); }
+ static PassRefPtrWillBeRawPtr<CSSMediaRule> create(StyleRuleMedia* rule, CSSStyleSheet* sheet)
+ {
+ return adoptRefWillBeNoop(new CSSMediaRule(rule, sheet));
+ }
virtual ~CSSMediaRule();
@@ -42,12 +45,14 @@ public:
MediaList* media() const;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSMediaRule(StyleRuleMedia*, CSSStyleSheet*);
MediaQuerySet* mediaQueries() const;
- mutable RefPtr<MediaList> m_mediaCSSOMWrapper;
+ mutable RefPtrWillBeMember<MediaList> m_mediaCSSOMWrapper;
};
DEFINE_CSS_RULE_TYPE_CASTS(CSSMediaRule, MEDIA_RULE);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSMixFunctionValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSMixFunctionValue.cpp
deleted file mode 100644
index 0dd07a58fee..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSMixFunctionValue.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/css/CSSMixFunctionValue.h"
-
-namespace WebCore {
-
-CSSMixFunctionValue::CSSMixFunctionValue()
- : CSSValueList(CSSMixFunctionValueClass, SpaceSeparator)
-{
-}
-
-CSSMixFunctionValue::CSSMixFunctionValue(const CSSMixFunctionValue& cloneFrom)
- : CSSValueList(cloneFrom)
-{
-}
-
-String CSSMixFunctionValue::customCSSText() const
-{
- return "mix(" + CSSValueList::customCSSText() + ")";
-}
-
-PassRefPtr<CSSMixFunctionValue> CSSMixFunctionValue::cloneForCSSOM() const
-{
- return adoptRef(new CSSMixFunctionValue(*this));
-}
-
-bool CSSMixFunctionValue::equals(const CSSMixFunctionValue& other) const
-{
- return CSSValueList::equals(other);
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSMixFunctionValue.h b/chromium/third_party/WebKit/Source/core/css/CSSMixFunctionValue.h
deleted file mode 100644
index 04a5e2d6020..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSMixFunctionValue.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef CSSMixFunctionValue_h
-#define CSSMixFunctionValue_h
-
-#include "core/css/CSSValueList.h"
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-class CSSMixFunctionValue : public CSSValueList {
-public:
- static PassRefPtr<CSSMixFunctionValue> create()
- {
- return adoptRef(new CSSMixFunctionValue());
- }
-
- String customCSSText() const;
-
- PassRefPtr<CSSMixFunctionValue> cloneForCSSOM() const;
-
- bool equals(const CSSMixFunctionValue&) const;
-
-private:
- CSSMixFunctionValue();
- CSSMixFunctionValue(const CSSMixFunctionValue& cloneFrom);
-};
-
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSMixFunctionValue, isMixFunctionValue());
-
-} // namespace WebCore
-
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSOMUtils.cpp b/chromium/third_party/WebKit/Source/core/css/CSSOMUtils.cpp
index 36545dd12bc..1e7882f2c1c 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSOMUtils.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSOMUtils.cpp
@@ -49,13 +49,6 @@ void serializeCharacterAsCodePoint(UChar32 c, StringBuilder& appendTo)
appendTo.append(' ');
}
-void serializeIdentifier(const String& identifier, String& appendTo)
-{
- StringBuilder addend;
- serializeIdentifier(identifier, addend);
- appendTo.append(addend.toString());
-}
-
void serializeIdentifier(const String& identifier, StringBuilder& appendTo)
{
bool isFirst = true;
@@ -85,13 +78,6 @@ void serializeIdentifier(const String& identifier, StringBuilder& appendTo)
}
}
-void serializeString(const String& string, String& appendTo)
-{
- StringBuilder addend;
- serializeString(string, addend);
- appendTo.append(addend.toString());
-}
-
void serializeString(const String& string, StringBuilder& appendTo)
{
appendTo.append('\"');
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSOMUtils.h b/chromium/third_party/WebKit/Source/core/css/CSSOMUtils.h
index 3239ada94b4..813396b1e11 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSOMUtils.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSOMUtils.h
@@ -35,15 +35,15 @@
#include "wtf/unicode/Unicode.h"
// Utilities for CSSOM http://dev.w3.org/csswg/cssom/
+// FIXME: This file has a similar purpose to
+// CSSMarkup.h. Perhaps the two should be combined?
namespace WebCore {
// Common serializing methods. See: http://dev.w3.org/csswg/cssom/#common-serializing-idioms
void serializeCharacter(UChar32, StringBuilder& appendTo);
void serializeCharacterAsCodePoint(UChar32, StringBuilder& appendTo);
-void serializeIdentifier(const String& identifier, String& appendTo);
void serializeIdentifier(const String& identifier, StringBuilder& appendTo);
-void serializeString(const String&, String& appendTo);
void serializeString(const String&, StringBuilder& appendTo);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSPageRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSPageRule.cpp
index 0513e92dd99..20237e62c8b 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSPageRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSPageRule.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "core/css/CSSPageRule.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSSelector.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
@@ -40,8 +40,10 @@ CSSPageRule::CSSPageRule(StyleRulePage* pageRule, CSSStyleSheet* parent)
CSSPageRule::~CSSPageRule()
{
+#if !ENABLE(OILPAN)
if (m_propertiesCSSOMWrapper)
m_propertiesCSSOMWrapper->clearParentRule();
+#endif
}
CSSStyleDeclaration* CSSPageRule::style() const
@@ -68,7 +70,8 @@ String CSSPageRule::selectorText() const
void CSSPageRule::setSelectorText(const String& selectorText)
{
- CSSParser parser(parserContext());
+ CSSParserContext context(parserContext(), 0);
+ BisonCSSParser parser(context);
CSSSelectorList selectorList;
parser.parseSelector(selectorText, selectorList);
if (!selectorList.isValid())
@@ -84,7 +87,7 @@ String CSSPageRule::cssText() const
StringBuilder result;
result.append(selectorText());
result.appendLiteral(" { ");
- String decls = m_pageRule->properties()->asText();
+ String decls = m_pageRule->properties().asText();
result.append(decls);
if (!decls.isEmpty())
result.append(' ');
@@ -100,4 +103,11 @@ void CSSPageRule::reattach(StyleRuleBase* rule)
m_propertiesCSSOMWrapper->reattach(m_pageRule->mutableProperties());
}
+void CSSPageRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_pageRule);
+ visitor->trace(m_propertiesCSSOMWrapper);
+ CSSRule::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSPageRule.h b/chromium/third_party/WebKit/Source/core/css/CSSPageRule.h
index 4aa0f696e63..4fc9b1be4ba 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSPageRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSPageRule.h
@@ -23,6 +23,7 @@
#define CSSPageRule_h
#include "core/css/CSSRule.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -31,9 +32,12 @@ class CSSStyleSheet;
class StyleRulePage;
class StyleRuleCSSStyleDeclaration;
-class CSSPageRule : public CSSRule {
+class CSSPageRule FINAL : public CSSRule {
public:
- static PassRefPtr<CSSPageRule> create(StyleRulePage* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSPageRule(rule, sheet)); }
+ static PassRefPtrWillBeRawPtr<CSSPageRule> create(StyleRulePage* rule, CSSStyleSheet* sheet)
+ {
+ return adoptRefWillBeNoop(new CSSPageRule(rule, sheet));
+ }
virtual ~CSSPageRule();
@@ -46,11 +50,13 @@ public:
String selectorText() const;
void setSelectorText(const String&);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSPageRule(StyleRulePage*, CSSStyleSheet*);
- RefPtr<StyleRulePage> m_pageRule;
- mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
+ RefPtrWillBeMember<StyleRulePage> m_pageRule;
+ mutable RefPtrWillBeMember<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
};
DEFINE_CSS_RULE_TYPE_CASTS(CSSPageRule, PAGE_RULE);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSParser-in.cpp b/chromium/third_party/WebKit/Source/core/css/CSSParser-in.cpp
deleted file mode 100755
index 7b540fd7b14..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSParser-in.cpp
+++ /dev/null
@@ -1,10465 +0,0 @@
-/*
- * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
- * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- * Copyright (C) 2012 Intel Corporation. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/css/CSSParser.h"
-
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
-#include "StylePropertyShorthand.h"
-#include "core/css/CSSArrayFunctionValue.h"
-#include "core/css/CSSAspectRatioValue.h"
-#include "core/css/CSSBasicShapes.h"
-#include "core/css/CSSBorderImage.h"
-#include "core/css/CSSCanvasValue.h"
-#include "core/css/CSSCrossfadeValue.h"
-#include "core/css/CSSCursorImageValue.h"
-#include "core/css/CSSFontFaceSrcValue.h"
-#include "core/css/CSSFontFeatureValue.h"
-#include "core/css/CSSFunctionValue.h"
-#include "core/css/CSSGradientValue.h"
-#include "core/css/CSSGridLineNamesValue.h"
-#include "core/css/CSSGridTemplateValue.h"
-#include "core/css/CSSImageSetValue.h"
-#include "core/css/CSSImageValue.h"
-#include "core/css/CSSInheritedValue.h"
-#include "core/css/CSSInitialValue.h"
-#include "core/css/CSSKeyframeRule.h"
-#include "core/css/CSSKeyframesRule.h"
-#include "core/css/CSSLineBoxContainValue.h"
-#include "core/css/CSSMixFunctionValue.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/css/CSSPropertySourceData.h"
-#include "core/css/CSSReflectValue.h"
-#include "core/css/CSSSVGDocumentValue.h"
-#include "core/css/CSSSelector.h"
-#include "core/css/CSSShaderValue.h"
-#include "core/css/CSSShadowValue.h"
-#include "core/css/CSSStyleSheet.h"
-#include "core/css/CSSTimingFunctionValue.h"
-#include "core/css/CSSTransformValue.h"
-#include "core/css/CSSUnicodeRangeValue.h"
-#include "core/css/CSSValueList.h"
-#include "core/css/CSSValuePool.h"
-#include "core/css/CSSVariableValue.h"
-#include "core/css/Counter.h"
-#include "core/css/HashTools.h"
-#include "core/css/MediaList.h"
-#include "core/css/MediaQueryExp.h"
-#include "core/css/Pair.h"
-#include "core/css/Rect.h"
-#include "core/css/StylePropertySet.h"
-#include "core/css/StyleRule.h"
-#include "core/css/StyleRuleImport.h"
-#include "core/css/StyleSheetContents.h"
-#include "core/dom/Document.h"
-#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/page/PageConsole.h"
-#include "core/frame/Settings.h"
-#include "core/rendering/RenderTheme.h"
-#include "core/svg/SVGParserUtilities.h"
-#include "platform/FloatConversion.h"
-#include "wtf/BitArray.h"
-#include "wtf/HexNumber.h"
-#include "wtf/text/StringBuffer.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/StringImpl.h"
-#include "wtf/text/TextEncoding.h"
-#include <limits.h>
-
-#define YYDEBUG 0
-
-#if YYDEBUG > 0
-extern int cssyydebug;
-#endif
-
-extern int cssyyparse(WebCore::CSSParser*);
-
-using namespace std;
-using namespace WTF;
-
-namespace WebCore {
-
-static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
-static const double MAX_SCALE = 1000000;
-
-template <unsigned N>
-static bool equal(const CSSParserString& a, const char (&b)[N])
-{
- unsigned length = N - 1; // Ignore the trailing null character
- if (a.length() != length)
- return false;
-
- return a.is8Bit() ? WTF::equal(a.characters8(), reinterpret_cast<const LChar*>(b), length) : WTF::equal(a.characters16(), reinterpret_cast<const LChar*>(b), length);
-}
-
-template <unsigned N>
-static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N])
-{
- unsigned length = N - 1; // Ignore the trailing null character
- if (a.length() != length)
- return false;
-
- return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF::equalIgnoringCase(b, a.characters16(), length);
-}
-
-template <unsigned N>
-static bool equalIgnoringCase(CSSParserValue* value, const char (&b)[N])
-{
- ASSERT(value->unit == CSSPrimitiveValue::CSS_IDENT || value->unit == CSSPrimitiveValue::CSS_STRING);
- return equalIgnoringCase(value->string, b);
-}
-
-static PassRefPtr<CSSPrimitiveValue> createPrimitiveValuePair(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second, Pair::IdenticalValuesPolicy identicalValuesPolicy = Pair::DropIdenticalValues)
-{
- return cssValuePool().createValue(Pair::create(first, second, identicalValuesPolicy));
-}
-
-class AnimationParseContext {
-public:
- AnimationParseContext()
- : m_animationPropertyKeywordAllowed(true)
- , m_firstAnimationCommitted(false)
- , m_hasSeenAnimationPropertyKeyword(false)
- {
- }
-
- void commitFirstAnimation()
- {
- m_firstAnimationCommitted = true;
- }
-
- bool hasCommittedFirstAnimation() const
- {
- return m_firstAnimationCommitted;
- }
-
- void commitAnimationPropertyKeyword()
- {
- m_animationPropertyKeywordAllowed = false;
- }
-
- bool animationPropertyKeywordAllowed() const
- {
- return m_animationPropertyKeywordAllowed;
- }
-
- bool hasSeenAnimationPropertyKeyword() const
- {
- return m_hasSeenAnimationPropertyKeyword;
- }
-
- void sawAnimationPropertyKeyword()
- {
- m_hasSeenAnimationPropertyKeyword = true;
- }
-
-private:
- bool m_animationPropertyKeywordAllowed;
- bool m_firstAnimationCommitted;
- bool m_hasSeenAnimationPropertyKeyword;
-};
-
-CSSParser::CSSParser(const CSSParserContext& context, UseCounter* counter)
- : m_context(context)
- , m_important(false)
- , m_id(CSSPropertyInvalid)
- , m_styleSheet(0)
- , m_supportsCondition(false)
- , m_selectorListForParseSelector(0)
- , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
- , m_inParseShorthand(0)
- , m_currentShorthand(CSSPropertyInvalid)
- , m_implicitShorthand(false)
- , m_hasFontFaceOnlyValues(false)
- , m_hadSyntacticallyValidCSSRule(false)
- , m_logErrors(false)
- , m_ignoreErrors(false)
- , m_inFilterRule(false)
- , m_defaultNamespace(starAtom)
- , m_sourceDataHandler(0)
- , m_source(0)
- , m_ruleHeaderType(CSSRuleSourceData::UNKNOWN_RULE)
- , m_allowImportRules(true)
- , m_allowNamespaceDeclarations(true)
- , m_inViewport(false)
- , m_useCounter(counter)
- , m_tokenizer(*this)
-{
-#if YYDEBUG > 0
- cssyydebug = 1;
-#endif
- CSSPropertySourceData::init();
-}
-
-CSSParser::~CSSParser()
-{
- clearProperties();
-
- deleteAllValues(m_floatingSelectors);
- deleteAllValues(m_floatingSelectorVectors);
- deleteAllValues(m_floatingValueLists);
- deleteAllValues(m_floatingFunctions);
-}
-
-void CSSParser::setupParser(const char* prefix, unsigned prefixLength, const String& string, const char* suffix, unsigned suffixLength)
-{
- m_tokenizer.setupTokenizer(prefix, prefixLength, string, suffix, suffixLength);
- m_ruleHasHeader = true;
-}
-
-void CSSParser::parseSheet(StyleSheetContents* sheet, const String& string, const TextPosition& startPosition, SourceDataHandler* sourceDataHandler, bool logErrors)
-{
- setStyleSheet(sheet);
- m_defaultNamespace = starAtom; // Reset the default namespace.
- m_sourceDataHandler = sourceDataHandler;
- m_logErrors = logErrors && sheet->singleOwnerDocument() && !sheet->baseURL().isEmpty() && sheet->singleOwnerDocument()->page();
- m_ignoreErrors = false;
- m_tokenizer.m_lineNumber = 0;
- m_startPosition = startPosition;
- m_source = &string;
- m_tokenizer.m_internal = false;
- setupParser("", string, "");
- cssyyparse(this);
- sheet->shrinkToFit();
- m_source = 0;
- m_sourceDataHandler = 0;
- m_rule = 0;
- m_lineEndings.clear();
- m_ignoreErrors = false;
- m_logErrors = false;
- m_tokenizer.m_internal = true;
-}
-
-PassRefPtr<StyleRuleBase> CSSParser::parseRule(StyleSheetContents* sheet, const String& string)
-{
- setStyleSheet(sheet);
- m_allowNamespaceDeclarations = false;
- setupParser("@-internal-rule ", string, "");
- cssyyparse(this);
- return m_rule.release();
-}
-
-PassRefPtr<StyleKeyframe> CSSParser::parseKeyframeRule(StyleSheetContents* sheet, const String& string)
-{
- setStyleSheet(sheet);
- setupParser("@-internal-keyframe-rule ", string, "");
- cssyyparse(this);
- return m_keyframe.release();
-}
-
-PassOwnPtr<Vector<double> > CSSParser::parseKeyframeKeyList(const String& string)
-{
- setupParser("@-internal-keyframe-key-list ", string, "");
- cssyyparse(this);
- ASSERT(m_valueList);
- return StyleKeyframe::createKeyList(m_valueList.get());
-}
-
-bool CSSParser::parseSupportsCondition(const String& string)
-{
- m_supportsCondition = false;
- setupParser("@-internal-supports-condition ", string, "");
- cssyyparse(this);
- return m_supportsCondition;
-}
-
-static inline bool isColorPropertyID(CSSPropertyID propertyId)
-{
- switch (propertyId) {
- case CSSPropertyColor:
- case CSSPropertyBackgroundColor:
- case CSSPropertyBorderBottomColor:
- case CSSPropertyBorderLeftColor:
- case CSSPropertyBorderRightColor:
- case CSSPropertyBorderTopColor:
- case CSSPropertyOutlineColor:
- case CSSPropertyTextLineThroughColor:
- case CSSPropertyTextOverlineColor:
- case CSSPropertyTextUnderlineColor:
- case CSSPropertyWebkitBorderAfterColor:
- case CSSPropertyWebkitBorderBeforeColor:
- case CSSPropertyWebkitBorderEndColor:
- case CSSPropertyWebkitBorderStartColor:
- case CSSPropertyWebkitColumnRuleColor:
- case CSSPropertyWebkitTextEmphasisColor:
- case CSSPropertyWebkitTextFillColor:
- case CSSPropertyWebkitTextStrokeColor:
- return true;
- case CSSPropertyTextDecorationColor:
- return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
- default:
- return false;
- }
-}
-
-static bool parseColorValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
-{
- ASSERT(!string.isEmpty());
- bool quirksMode = isQuirksModeBehavior(cssParserMode);
- if (!isColorPropertyID(propertyId))
- return false;
- CSSParserString cssString;
- cssString.init(string);
- CSSValueID valueID = cssValueKeywordID(cssString);
- bool validPrimitive = false;
- if (valueID == CSSValueWebkitText) {
- validPrimitive = true;
- } else if (valueID == CSSValueCurrentcolor) {
- validPrimitive = true;
- } else if ((valueID >= CSSValueAqua && valueID <= CSSValueWindowtext) || valueID == CSSValueMenu
- || (quirksMode && valueID >= CSSValueWebkitFocusRingColor && valueID < CSSValueWebkitText)) {
- validPrimitive = true;
- }
-
- if (validPrimitive) {
- RefPtr<CSSValue> value = cssValuePool().createIdentifierValue(valueID);
- declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
- return true;
- }
- RGBA32 color;
- if (!CSSParser::fastParseColor(color, string, !quirksMode && string[0] != '#'))
- return false;
- RefPtr<CSSValue> value = cssValuePool().createColorValue(color);
- declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
- return true;
-}
-
-static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acceptsNegativeNumbers)
-{
- switch (propertyId) {
- case CSSPropertyFontSize:
- case CSSPropertyHeight:
- case CSSPropertyWidth:
- case CSSPropertyMinHeight:
- case CSSPropertyMinWidth:
- case CSSPropertyPaddingBottom:
- case CSSPropertyPaddingLeft:
- case CSSPropertyPaddingRight:
- case CSSPropertyPaddingTop:
- case CSSPropertyWebkitLogicalWidth:
- case CSSPropertyWebkitLogicalHeight:
- case CSSPropertyWebkitMinLogicalWidth:
- case CSSPropertyWebkitMinLogicalHeight:
- case CSSPropertyWebkitPaddingAfter:
- case CSSPropertyWebkitPaddingBefore:
- case CSSPropertyWebkitPaddingEnd:
- case CSSPropertyWebkitPaddingStart:
- acceptsNegativeNumbers = false;
- return true;
- case CSSPropertyShapeMargin:
- case CSSPropertyShapePadding:
- acceptsNegativeNumbers = false;
- return RuntimeEnabledFeatures::cssShapesEnabled();
- case CSSPropertyBottom:
- case CSSPropertyLeft:
- case CSSPropertyMarginBottom:
- case CSSPropertyMarginLeft:
- case CSSPropertyMarginRight:
- case CSSPropertyMarginTop:
- case CSSPropertyRight:
- case CSSPropertyTop:
- case CSSPropertyWebkitMarginAfter:
- case CSSPropertyWebkitMarginBefore:
- case CSSPropertyWebkitMarginEnd:
- case CSSPropertyWebkitMarginStart:
- acceptsNegativeNumbers = true;
- return true;
- default:
- return false;
- }
-}
-
-template <typename CharacterType>
-static inline bool parseSimpleLength(const CharacterType* characters, unsigned& length, CSSPrimitiveValue::UnitTypes& unit, double& number)
-{
- if (length > 2 && (characters[length - 2] | 0x20) == 'p' && (characters[length - 1] | 0x20) == 'x') {
- length -= 2;
- unit = CSSPrimitiveValue::CSS_PX;
- } else if (length > 1 && characters[length - 1] == '%') {
- length -= 1;
- unit = CSSPrimitiveValue::CSS_PERCENTAGE;
- }
-
- // We rely on charactersToDouble for validation as well. The function
- // will set "ok" to "false" if the entire passed-in character range does
- // not represent a double.
- bool ok;
- number = charactersToDouble(characters, length, &ok);
- return ok;
-}
-
-static bool parseSimpleLengthValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
-{
- ASSERT(!string.isEmpty());
- bool acceptsNegativeNumbers;
-
- // In @viewport, width and height are shorthands, not simple length values.
- if (isCSSViewportParsingEnabledForMode(cssParserMode) || !isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
- return false;
-
- unsigned length = string.length();
- double number;
- CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
-
- if (string.is8Bit()) {
- if (!parseSimpleLength(string.characters8(), length, unit, number))
- return false;
- } else {
- if (!parseSimpleLength(string.characters16(), length, unit, number))
- return false;
- }
-
- if (unit == CSSPrimitiveValue::CSS_NUMBER) {
- bool quirksMode = isQuirksModeBehavior(cssParserMode);
- if (number && !quirksMode)
- return false;
- unit = CSSPrimitiveValue::CSS_PX;
- }
- if (number < 0 && !acceptsNegativeNumbers)
- return false;
-
- RefPtr<CSSValue> value = cssValuePool().createValue(number, unit);
- declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
- return true;
-}
-
-static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext& parserContext)
-{
- if (!valueID)
- return false;
-
- switch (propertyId) {
- case CSSPropertyBorderCollapse: // collapse | separate | inherit
- if (valueID == CSSValueCollapse || valueID == CSSValueSeparate)
- return true;
- break;
- case CSSPropertyBorderTopStyle: // <border-style> | inherit
- case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed |
- case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset
- case CSSPropertyBorderLeftStyle:
- case CSSPropertyWebkitBorderAfterStyle:
- case CSSPropertyWebkitBorderBeforeStyle:
- case CSSPropertyWebkitBorderEndStyle:
- case CSSPropertyWebkitBorderStartStyle:
- case CSSPropertyWebkitColumnRuleStyle:
- if (valueID >= CSSValueNone && valueID <= CSSValueDouble)
- return true;
- break;
- case CSSPropertyBoxSizing:
- if (valueID == CSSValueBorderBox || valueID == CSSValueContentBox)
- return true;
- break;
- case CSSPropertyCaptionSide: // top | bottom | left | right | inherit
- if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueTop || valueID == CSSValueBottom)
- return true;
- break;
- case CSSPropertyClear: // none | left | right | both | inherit
- if (valueID == CSSValueNone || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueBoth)
- return true;
- break;
- case CSSPropertyDirection: // ltr | rtl | inherit
- if (valueID == CSSValueLtr || valueID == CSSValueRtl)
- return true;
- break;
- case CSSPropertyDisplay:
- // inline | block | list-item | inline-block | table |
- // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
- // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none | inherit
- // flex | inline-flex | -webkit-flex | -webkit-inline-flex | grid | inline-grid | lazy-block
- if ((valueID >= CSSValueInline && valueID <= CSSValueInlineFlex) || valueID == CSSValueWebkitFlex || valueID == CSSValueWebkitInlineFlex || valueID == CSSValueNone)
- return true;
- if (valueID == CSSValueGrid || valueID == CSSValueInlineGrid)
- return RuntimeEnabledFeatures::cssGridLayoutEnabled();
- break;
-
- case CSSPropertyEmptyCells: // show | hide | inherit
- if (valueID == CSSValueShow || valueID == CSSValueHide)
- return true;
- break;
- case CSSPropertyFloat: // left | right | none | center (for buggy CSS, maps to none)
- if (valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueNone || valueID == CSSValueCenter)
- return true;
- break;
- case CSSPropertyFontStyle: // normal | italic | oblique | inherit
- if (valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique)
- return true;
- break;
- case CSSPropertyImageRendering: // auto | optimizeContrast
- if (valueID == CSSValueAuto || valueID == CSSValueWebkitOptimizeContrast)
- return true;
- break;
- case CSSPropertyIsolation: // auto | isolate
- if (valueID == CSSValueAuto || valueID == CSSValueIsolate)
- return RuntimeEnabledFeatures::cssCompositingEnabled();
- break;
- case CSSPropertyListStylePosition: // inside | outside | inherit
- if (valueID == CSSValueInside || valueID == CSSValueOutside)
- return true;
- break;
- case CSSPropertyListStyleType:
- // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in
- // for the list of supported list-style-types.
- if ((valueID >= CSSValueDisc && valueID <= CSSValueKatakanaIroha) || valueID == CSSValueNone)
- return true;
- break;
- case CSSPropertyObjectFit:
- if (RuntimeEnabledFeatures::objectFitPositionEnabled()) {
- if (valueID == CSSValueFill || valueID == CSSValueContain || valueID == CSSValueCover || valueID == CSSValueNone || valueID == CSSValueScaleDown)
- return true;
- }
- break;
- case CSSPropertyOutlineStyle: // (<border-style> except hidden) | auto | inherit
- if (valueID == CSSValueAuto || valueID == CSSValueNone || (valueID >= CSSValueInset && valueID <= CSSValueDouble))
- return true;
- break;
- case CSSPropertyOverflowWrap: // normal | break-word
- case CSSPropertyWordWrap:
- if (valueID == CSSValueNormal || valueID == CSSValueBreakWord)
- return true;
- break;
- case CSSPropertyOverflowX: // visible | hidden | scroll | auto | overlay | inherit
- if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay)
- return true;
- break;
- case CSSPropertyOverflowY: // visible | hidden | scroll | auto | overlay | inherit | -webkit-paged-x | -webkit-paged-y
- if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitPagedX || valueID == CSSValueWebkitPagedY)
- return true;
- break;
- case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right | inherit
- case CSSPropertyPageBreakBefore:
- case CSSPropertyWebkitColumnBreakAfter:
- case CSSPropertyWebkitColumnBreakBefore:
- if (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight)
- return true;
- break;
- case CSSPropertyPageBreakInside: // avoid | auto | inherit
- case CSSPropertyWebkitColumnBreakInside:
- if (valueID == CSSValueAuto || valueID == CSSValueAvoid)
- return true;
- break;
- case CSSPropertyPointerEvents:
- // none | visiblePainted | visibleFill | visibleStroke | visible |
- // painted | fill | stroke | auto | all | bounding-box | inherit
- if (valueID == CSSValueVisible || valueID == CSSValueNone || valueID == CSSValueAll || valueID == CSSValueAuto || (valueID >= CSSValueVisiblepainted && valueID <= CSSValueBoundingBox))
- return true;
- break;
- case CSSPropertyPosition: // static | relative | absolute | fixed | sticky | inherit
- if (valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed
- || (RuntimeEnabledFeatures::cssStickyPositionEnabled() && valueID == CSSValueSticky))
- return true;
- break;
- case CSSPropertyResize: // none | both | horizontal | vertical | auto
- if (valueID == CSSValueNone || valueID == CSSValueBoth || valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueAuto)
- return true;
- break;
- case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation | inherit
- if (valueID == CSSValueNone || valueID == CSSValueNormal || valueID == CSSValueSpellOut || valueID == CSSValueDigits || valueID == CSSValueLiteralPunctuation || valueID == CSSValueNoPunctuation)
- return true;
- break;
- case CSSPropertyTableLayout: // auto | fixed | inherit
- if (valueID == CSSValueAuto || valueID == CSSValueFixed)
- return true;
- break;
- case CSSPropertyTextAlignLast:
- // auto | start | end | left | right | center | justify
- if (RuntimeEnabledFeatures::css3TextEnabled()
- && ((valueID >= CSSValueLeft && valueID <= CSSValueJustify) || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueAuto))
- return true;
- break;
- case CSSPropertyTextJustify:
- // auto | none | inter-word | distribute
- if (RuntimeEnabledFeatures::css3TextEnabled()
- && (valueID == CSSValueInterWord || valueID == CSSValueDistribute || valueID == CSSValueAuto || valueID == CSSValueNone))
- return true;
- break;
- case CSSPropertyTextLineThroughMode:
- case CSSPropertyTextOverlineMode:
- case CSSPropertyTextUnderlineMode:
- if (valueID == CSSValueContinuous || valueID == CSSValueSkipWhiteSpace)
- return true;
- break;
- case CSSPropertyTextLineThroughStyle:
- case CSSPropertyTextOverlineStyle:
- case CSSPropertyTextUnderlineStyle:
- if (valueID == CSSValueNone || valueID == CSSValueSolid || valueID == CSSValueDouble || valueID == CSSValueDashed || valueID == CSSValueDotDash || valueID == CSSValueDotDotDash || valueID == CSSValueWave)
- return true;
- break;
- case CSSPropertyTextOverflow: // clip | ellipsis
- if (valueID == CSSValueClip || valueID == CSSValueEllipsis)
- return true;
- break;
- case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision
- if (valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizelegibility || valueID == CSSValueGeometricprecision)
- return true;
- break;
- case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none | inherit
- if ((valueID >= CSSValueCapitalize && valueID <= CSSValueLowercase) || valueID == CSSValueNone)
- return true;
- break;
- case CSSPropertyTouchActionDelay: // none | script
- if (RuntimeEnabledFeatures::cssTouchActionEnabled() && (valueID == CSSValueScript || valueID == CSSValueNone))
- return true;
- break;
- case CSSPropertyVisibility: // visible | hidden | collapse | inherit
- if (valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueCollapse)
- return true;
- break;
- case CSSPropertyWebkitAppearance:
- if ((valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone)
- return true;
- break;
- case CSSPropertyWebkitBackfaceVisibility:
- if (valueID == CSSValueVisible || valueID == CSSValueHidden)
- return true;
- break;
- case CSSPropertyMixBlendMode:
- if (RuntimeEnabledFeatures::cssCompositingEnabled() && (valueID == CSSValueNormal || valueID == CSSValueMultiply || valueID == CSSValueScreen
- || valueID == CSSValueOverlay || valueID == CSSValueDarken || valueID == CSSValueLighten || valueID == CSSValueColorDodge
- || valueID == CSSValueColorBurn || valueID == CSSValueHardLight || valueID == CSSValueSoftLight || valueID == CSSValueDifference
- || valueID == CSSValueExclusion || valueID == CSSValueHue || valueID == CSSValueSaturation || valueID == CSSValueColor
- || valueID == CSSValueLuminosity))
- return true;
- break;
- case CSSPropertyWebkitBorderFit:
- if (valueID == CSSValueBorder || valueID == CSSValueLines)
- return true;
- break;
- case CSSPropertyWebkitBoxAlign:
- if (valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline)
- return true;
- break;
- case CSSPropertyWebkitBoxDecorationBreak:
- if (valueID == CSSValueClone || valueID == CSSValueSlice)
- return true;
- break;
- case CSSPropertyWebkitBoxDirection:
- if (valueID == CSSValueNormal || valueID == CSSValueReverse)
- return true;
- break;
- case CSSPropertyWebkitBoxLines:
- if (valueID == CSSValueSingle || valueID == CSSValueMultiple)
- return true;
- break;
- case CSSPropertyWebkitBoxOrient:
- if (valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueInlineAxis || valueID == CSSValueBlockAxis)
- return true;
- break;
- case CSSPropertyWebkitBoxPack:
- if (valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify)
- return true;
- break;
- case CSSPropertyInternalCallback:
- // This property is only injected programmatically, not parsed from stylesheets.
- return false;
- case CSSPropertyColumnFill:
- if (RuntimeEnabledFeatures::regionBasedColumnsEnabled()) {
- if (valueID == CSSValueAuto || valueID == CSSValueBalance)
- return true;
- }
- break;
- case CSSPropertyAlignContent:
- if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround || valueID == CSSValueStretch)
- return true;
- break;
- case CSSPropertyAlignItems:
- if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch)
- return true;
- break;
- case CSSPropertyAlignSelf:
- if (valueID == CSSValueAuto || valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch)
- return true;
- break;
- case CSSPropertyFlexDirection:
- if (valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse)
- return true;
- break;
- case CSSPropertyFlexWrap:
- if (valueID == CSSValueNowrap || valueID == CSSValueWrap || valueID == CSSValueWrapReverse)
- return true;
- break;
- case CSSPropertyJustifyContent:
- if (valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround)
- return true;
- break;
- case CSSPropertyFontKerning:
- if (valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone)
- return true;
- break;
- case CSSPropertyWebkitFontSmoothing:
- if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueAntialiased || valueID == CSSValueSubpixelAntialiased)
- return true;
- break;
- case CSSPropertyGridAutoFlow:
- if (valueID == CSSValueNone || valueID == CSSValueRow || valueID == CSSValueColumn)
- return RuntimeEnabledFeatures::cssGridLayoutEnabled();
- break;
- case CSSPropertyWebkitLineAlign:
- if (valueID == CSSValueNone || valueID == CSSValueEdges)
- return true;
- break;
- case CSSPropertyWebkitLineBreak: // auto | loose | normal | strict | after-white-space
- if (valueID == CSSValueAuto || valueID == CSSValueLoose || valueID == CSSValueNormal || valueID == CSSValueStrict || valueID == CSSValueAfterWhiteSpace)
- return true;
- break;
- case CSSPropertyWebkitLineSnap:
- if (valueID == CSSValueNone || valueID == CSSValueBaseline || valueID == CSSValueContain)
- return true;
- break;
- case CSSPropertyWebkitMarginAfterCollapse:
- case CSSPropertyWebkitMarginBeforeCollapse:
- case CSSPropertyWebkitMarginBottomCollapse:
- case CSSPropertyWebkitMarginTopCollapse:
- if (valueID == CSSValueCollapse || valueID == CSSValueSeparate || valueID == CSSValueDiscard)
- return true;
- break;
- case CSSPropertyInternalMarqueeDirection:
- if (valueID == CSSValueForwards || valueID == CSSValueBackwards || valueID == CSSValueAhead || valueID == CSSValueReverse || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueDown
- || valueID == CSSValueUp || valueID == CSSValueAuto)
- return true;
- break;
- case CSSPropertyInternalMarqueeStyle:
- if (valueID == CSSValueNone || valueID == CSSValueSlide || valueID == CSSValueScroll || valueID == CSSValueAlternate)
- return true;
- break;
- case CSSPropertyWebkitPrintColorAdjust:
- if (valueID == CSSValueExact || valueID == CSSValueEconomy)
- return true;
- break;
- case CSSPropertyWebkitRegionBreakAfter:
- case CSSPropertyWebkitRegionBreakBefore:
- if (RuntimeEnabledFeatures::cssRegionsEnabled() && (valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight))
- return true;
- break;
- case CSSPropertyWebkitRegionBreakInside:
- if (RuntimeEnabledFeatures::cssRegionsEnabled() && (valueID == CSSValueAuto || valueID == CSSValueAvoid))
- return true;
- break;
- case CSSPropertyWebkitRegionFragment:
- if (RuntimeEnabledFeatures::cssRegionsEnabled() && (valueID == CSSValueAuto || valueID == CSSValueBreak))
- return true;
- break;
- case CSSPropertyWebkitRtlOrdering:
- if (valueID == CSSValueLogical || valueID == CSSValueVisual)
- return true;
- break;
-
- case CSSPropertyWebkitRubyPosition:
- if (valueID == CSSValueBefore || valueID == CSSValueAfter)
- return true;
- break;
-
- case CSSPropertyWebkitTextCombine:
- if (valueID == CSSValueNone || valueID == CSSValueHorizontal)
- return true;
- break;
- case CSSPropertyWebkitTextEmphasisPosition:
- if (valueID == CSSValueOver || valueID == CSSValueUnder)
- return true;
- break;
- case CSSPropertyWebkitTextSecurity:
- // disc | circle | square | none | inherit
- if (valueID == CSSValueDisc || valueID == CSSValueCircle || valueID == CSSValueSquare || valueID == CSSValueNone)
- return true;
- break;
- case CSSPropertyWebkitTransformStyle:
- if (valueID == CSSValueFlat || valueID == CSSValuePreserve3d)
- return true;
- break;
- case CSSPropertyWebkitUserDrag: // auto | none | element
- if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueElement)
- return true;
- break;
- case CSSPropertyWebkitUserModify: // read-only | read-write
- if (valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly)
- return true;
- break;
- case CSSPropertyWebkitUserSelect: // auto | none | text | all
- if (valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText || valueID == CSSValueAll)
- return true;
- break;
- case CSSPropertyWebkitWrapFlow:
- if (!RuntimeEnabledFeatures::cssExclusionsEnabled())
- return false;
- if (valueID == CSSValueAuto || valueID == CSSValueBoth || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueMaximum || valueID == CSSValueClear)
- return true;
- break;
- case CSSPropertyWebkitWrapThrough:
- if (!RuntimeEnabledFeatures::cssExclusionsEnabled())
- return false;
- if (valueID == CSSValueWrap || valueID == CSSValueNone)
- return true;
- break;
- case CSSPropertyWebkitWritingMode:
- if (valueID >= CSSValueHorizontalTb && valueID <= CSSValueHorizontalBt)
- return true;
- break;
- case CSSPropertyWhiteSpace: // normal | pre | nowrap | inherit
- if (valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap)
- return true;
- break;
- case CSSPropertyWordBreak: // normal | break-all | break-word (this is a custom extension)
- if (valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueBreakWord)
- return true;
- break;
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
- return false;
-}
-
-static inline bool isKeywordPropertyID(CSSPropertyID propertyId)
-{
- switch (propertyId) {
- case CSSPropertyMixBlendMode:
- case CSSPropertyIsolation:
- case CSSPropertyBorderBottomStyle:
- case CSSPropertyBorderCollapse:
- case CSSPropertyBorderLeftStyle:
- case CSSPropertyBorderRightStyle:
- case CSSPropertyBorderTopStyle:
- case CSSPropertyBoxSizing:
- case CSSPropertyCaptionSide:
- case CSSPropertyClear:
- case CSSPropertyDirection:
- case CSSPropertyDisplay:
- case CSSPropertyEmptyCells:
- case CSSPropertyFloat:
- case CSSPropertyFontStyle:
- case CSSPropertyImageRendering:
- case CSSPropertyListStylePosition:
- case CSSPropertyListStyleType:
- case CSSPropertyObjectFit:
- case CSSPropertyOutlineStyle:
- case CSSPropertyOverflowWrap:
- case CSSPropertyOverflowX:
- case CSSPropertyOverflowY:
- case CSSPropertyPageBreakAfter:
- case CSSPropertyPageBreakBefore:
- case CSSPropertyPageBreakInside:
- case CSSPropertyPointerEvents:
- case CSSPropertyPosition:
- case CSSPropertyResize:
- case CSSPropertySpeak:
- case CSSPropertyTableLayout:
- case CSSPropertyTextAlignLast:
- case CSSPropertyTextJustify:
- case CSSPropertyTextLineThroughMode:
- case CSSPropertyTextLineThroughStyle:
- case CSSPropertyTextOverflow:
- case CSSPropertyTextOverlineMode:
- case CSSPropertyTextOverlineStyle:
- case CSSPropertyTextRendering:
- case CSSPropertyTextTransform:
- case CSSPropertyTextUnderlineMode:
- case CSSPropertyTextUnderlineStyle:
- case CSSPropertyTouchActionDelay:
- case CSSPropertyVisibility:
- case CSSPropertyWebkitAppearance:
- case CSSPropertyWebkitBackfaceVisibility:
- case CSSPropertyWebkitBorderAfterStyle:
- case CSSPropertyWebkitBorderBeforeStyle:
- case CSSPropertyWebkitBorderEndStyle:
- case CSSPropertyWebkitBorderFit:
- case CSSPropertyWebkitBorderStartStyle:
- case CSSPropertyWebkitBoxAlign:
- case CSSPropertyWebkitBoxDecorationBreak:
- case CSSPropertyWebkitBoxDirection:
- case CSSPropertyWebkitBoxLines:
- case CSSPropertyWebkitBoxOrient:
- case CSSPropertyWebkitBoxPack:
- case CSSPropertyInternalCallback:
- case CSSPropertyWebkitColumnBreakAfter:
- case CSSPropertyWebkitColumnBreakBefore:
- case CSSPropertyWebkitColumnBreakInside:
- case CSSPropertyColumnFill:
- case CSSPropertyWebkitColumnRuleStyle:
- case CSSPropertyAlignContent:
- case CSSPropertyAlignItems:
- case CSSPropertyAlignSelf:
- case CSSPropertyFlexDirection:
- case CSSPropertyFlexWrap:
- case CSSPropertyJustifyContent:
- case CSSPropertyFontKerning:
- case CSSPropertyWebkitFontSmoothing:
- case CSSPropertyGridAutoFlow:
- case CSSPropertyWebkitLineAlign:
- case CSSPropertyWebkitLineBreak:
- case CSSPropertyWebkitLineSnap:
- case CSSPropertyWebkitMarginAfterCollapse:
- case CSSPropertyWebkitMarginBeforeCollapse:
- case CSSPropertyWebkitMarginBottomCollapse:
- case CSSPropertyWebkitMarginTopCollapse:
- case CSSPropertyInternalMarqueeDirection:
- case CSSPropertyInternalMarqueeStyle:
- case CSSPropertyWebkitPrintColorAdjust:
- case CSSPropertyWebkitRegionBreakAfter:
- case CSSPropertyWebkitRegionBreakBefore:
- case CSSPropertyWebkitRegionBreakInside:
- case CSSPropertyWebkitRegionFragment:
- case CSSPropertyWebkitRtlOrdering:
- case CSSPropertyWebkitRubyPosition:
- case CSSPropertyWebkitTextCombine:
- case CSSPropertyWebkitTextEmphasisPosition:
- case CSSPropertyWebkitTextSecurity:
- case CSSPropertyWebkitTransformStyle:
- case CSSPropertyWebkitUserDrag:
- case CSSPropertyWebkitUserModify:
- case CSSPropertyWebkitUserSelect:
- case CSSPropertyWebkitWrapFlow:
- case CSSPropertyWebkitWrapThrough:
- case CSSPropertyWebkitWritingMode:
- case CSSPropertyWhiteSpace:
- case CSSPropertyWordBreak:
- case CSSPropertyWordWrap:
- return true;
- default:
- return false;
- }
-}
-
-static bool parseKeywordValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, const CSSParserContext& parserContext)
-{
- ASSERT(!string.isEmpty());
-
- if (!isKeywordPropertyID(propertyId)) {
- // All properties accept the values of "initial" and "inherit".
- String lowerCaseString = string.lower();
- if (lowerCaseString != "initial" && lowerCaseString != "inherit")
- return false;
-
- // Parse initial/inherit shorthands using the CSSParser.
- if (shorthandForProperty(propertyId).length())
- return false;
- }
-
- CSSParserString cssString;
- cssString.init(string);
- CSSValueID valueID = cssValueKeywordID(cssString);
-
- if (!valueID)
- return false;
-
- RefPtr<CSSValue> value;
- if (valueID == CSSValueInherit)
- value = cssValuePool().createInheritedValue();
- else if (valueID == CSSValueInitial)
- value = cssValuePool().createExplicitInitialValue();
- else if (isValidKeywordPropertyAndValue(propertyId, valueID, parserContext))
- value = cssValuePool().createIdentifierValue(valueID);
- else
- return false;
-
- declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
- return true;
-}
-
-template <typename CharacterType>
-static bool parseTransformTranslateArguments(CSSTransformValue* transformValue, CharacterType* characters, unsigned length, unsigned start, unsigned expectedCount)
-{
- while (expectedCount) {
- size_t end = WTF::find(characters, length, expectedCount == 1 ? ')' : ',', start);
- if (end == kNotFound || (expectedCount == 1 && end != length - 1))
- return false;
- unsigned argumentLength = end - start;
- CSSPrimitiveValue::UnitTypes unit = CSSPrimitiveValue::CSS_NUMBER;
- double number;
- if (!parseSimpleLength(characters + start, argumentLength, unit, number))
- return false;
- if (unit != CSSPrimitiveValue::CSS_PX && (number || unit != CSSPrimitiveValue::CSS_NUMBER))
- return false;
- transformValue->append(cssValuePool().createValue(number, CSSPrimitiveValue::CSS_PX));
- start = end + 1;
- --expectedCount;
- }
- return true;
-}
-
-static bool parseTranslateTransformValue(MutableStylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
-{
- if (propertyID != CSSPropertyWebkitTransform)
- return false;
- static const unsigned shortestValidTransformStringLength = 12;
- static const unsigned likelyMultipartTransformStringLengthCutoff = 32;
- if (string.length() < shortestValidTransformStringLength || string.length() > likelyMultipartTransformStringLengthCutoff)
- return false;
- if (!string.startsWith("translate", false))
- return false;
- UChar c9 = toASCIILower(string[9]);
- UChar c10 = toASCIILower(string[10]);
-
- CSSTransformValue::TransformOperationType transformType;
- unsigned expectedArgumentCount = 1;
- unsigned argumentStart = 11;
- if (c9 == 'x' && c10 == '(')
- transformType = CSSTransformValue::TranslateXTransformOperation;
- else if (c9 == 'y' && c10 == '(')
- transformType = CSSTransformValue::TranslateYTransformOperation;
- else if (c9 == 'z' && c10 == '(')
- transformType = CSSTransformValue::TranslateZTransformOperation;
- else if (c9 == '(') {
- transformType = CSSTransformValue::TranslateTransformOperation;
- expectedArgumentCount = 2;
- argumentStart = 10;
- } else if (c9 == '3' && c10 == 'd' && string[11] == '(') {
- transformType = CSSTransformValue::Translate3DTransformOperation;
- expectedArgumentCount = 3;
- argumentStart = 12;
- } else
- return false;
-
- RefPtr<CSSTransformValue> transformValue = CSSTransformValue::create(transformType);
- bool success;
- if (string.is8Bit())
- success = parseTransformTranslateArguments(transformValue.get(), string.characters8(), string.length(), argumentStart, expectedArgumentCount);
- else
- success = parseTransformTranslateArguments(transformValue.get(), string.characters16(), string.length(), argumentStart, expectedArgumentCount);
- if (!success)
- return false;
- RefPtr<CSSValueList> result = CSSValueList::createSpaceSeparated();
- result->append(transformValue.release());
- properties->addParsedProperty(CSSProperty(CSSPropertyWebkitTransform, result.release(), important));
- return true;
-}
-
-PassRefPtr<CSSValueList> CSSParser::parseFontFaceValue(const AtomicString& string)
-{
- if (string.isEmpty())
- return 0;
- RefPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
- if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, HTMLQuirksMode, 0))
- return 0;
-
- RefPtr<CSSValue> fontFamily = dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily);
- if (!fontFamily->isValueList())
- return 0;
-
- return toCSSValueList(dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily).get());
-}
-
-bool CSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, const Document& document)
-{
- ASSERT(!string.isEmpty());
-
- CSSParserContext context(document);
-
- if (parseSimpleLengthValue(declaration, propertyID, string, important, context.mode()))
- return true;
- if (parseColorValue(declaration, propertyID, string, important, context.mode()))
- return true;
- if (parseKeywordValue(declaration, propertyID, string, important, context))
- return true;
-
- CSSParser parser(context, UseCounter::getFrom(&document));
- return parser.parseValue(declaration, propertyID, string, important, static_cast<StyleSheetContents*>(0));
-}
-
-bool CSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
-{
- ASSERT(!string.isEmpty());
- if (parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode))
- return true;
- if (parseColorValue(declaration, propertyID, string, important, cssParserMode))
- return true;
-
- CSSParserContext context(cssParserMode);
- if (contextStyleSheet) {
- context = contextStyleSheet->parserContext();
- context.setMode(cssParserMode);
- }
-
- if (parseKeywordValue(declaration, propertyID, string, important, context))
- return true;
- if (parseTranslateTransformValue(declaration, propertyID, string, important))
- return true;
-
- CSSParser parser(context);
- return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet);
-}
-
-bool CSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, StyleSheetContents* contextStyleSheet)
-{
- // FIXME: Check RuntimeCSSEnabled::isPropertyEnabled or isValueEnabledForProperty.
-
- if (m_useCounter)
- m_useCounter->count(m_context, propertyID);
-
- setStyleSheet(contextStyleSheet);
-
- setupParser("@-internal-value ", string, "");
-
- m_id = propertyID;
- m_important = important;
-
- {
- StyleDeclarationScope scope(this, declaration);
- cssyyparse(this);
- }
-
- m_rule = 0;
- m_id = CSSPropertyInvalid;
-
- bool ok = false;
- if (m_hasFontFaceOnlyValues)
- deleteFontFaceOnlyValues();
- if (!m_parsedProperties.isEmpty()) {
- ok = true;
- declaration->addParsedProperties(m_parsedProperties);
- clearProperties();
- }
-
- return ok;
-}
-
-// The color will only be changed when string contains a valid CSS color, so callers
-// can set it to a default color and ignore the boolean result.
-bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict)
-{
- // First try creating a color specified by name, rgba(), rgb() or "#" syntax.
- if (fastParseColor(color, string, strict))
- return true;
-
- CSSParser parser(HTMLStandardMode);
-
- // In case the fast-path parser didn't understand the color, try the full parser.
- if (!parser.parseColor(string))
- return false;
-
- CSSValue* value = parser.m_parsedProperties.first().value();
- if (!value->isPrimitiveValue())
- return false;
-
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (!primitiveValue->isRGBColor())
- return false;
-
- color = primitiveValue->getRGBA32Value();
- return true;
-}
-
-bool CSSParser::parseColor(const String& string)
-{
- setupParser("@-internal-decls color:", string, "");
- cssyyparse(this);
- m_rule = 0;
-
- return !m_parsedProperties.isEmpty() && m_parsedProperties.first().id() == CSSPropertyColor;
-}
-
-bool CSSParser::parseSystemColor(RGBA32& color, const String& string, Document* document)
-{
- if (!document || !document->page())
- return false;
-
- CSSParserString cssColor;
- cssColor.init(string);
- CSSValueID id = cssValueKeywordID(cssColor);
- if (id <= 0)
- return false;
-
- color = RenderTheme::theme().systemColor(id).rgb();
- return true;
-}
-
-void CSSParser::parseSelector(const String& string, CSSSelectorList& selectorList)
-{
- m_selectorListForParseSelector = &selectorList;
-
- setupParser("@-internal-selector ", string, "");
-
- cssyyparse(this);
-
- m_selectorListForParseSelector = 0;
-}
-
-PassRefPtr<ImmutableStylePropertySet> CSSParser::parseInlineStyleDeclaration(const String& string, Element* element)
-{
- Document& document = element->document();
- CSSParserContext context = document.elementSheet()->contents()->parserContext();
- context.setMode((element->isHTMLElement() && !document.inQuirksMode()) ? HTMLStandardMode : HTMLQuirksMode);
- return CSSParser(context, UseCounter::getFrom(&document)).parseDeclaration(string, document.elementSheet()->contents());
-}
-
-PassRefPtr<ImmutableStylePropertySet> CSSParser::parseDeclaration(const String& string, StyleSheetContents* contextStyleSheet)
-{
- setStyleSheet(contextStyleSheet);
-
- setupParser("@-internal-decls ", string, "");
- cssyyparse(this);
- m_rule = 0;
-
- if (m_hasFontFaceOnlyValues)
- deleteFontFaceOnlyValues();
-
- RefPtr<ImmutableStylePropertySet> style = createStylePropertySet();
- clearProperties();
- return style.release();
-}
-
-
-bool CSSParser::parseDeclaration(MutableStylePropertySet* declaration, const String& string, SourceDataHandler* sourceDataHandler, StyleSheetContents* contextStyleSheet)
-{
- setStyleSheet(contextStyleSheet);
-
- m_sourceDataHandler = sourceDataHandler;
-
- setupParser("@-internal-decls ", string, "");
- if (m_sourceDataHandler) {
- m_sourceDataHandler->startRuleHeader(CSSRuleSourceData::STYLE_RULE, 0);
- m_sourceDataHandler->endRuleHeader(1);
- m_sourceDataHandler->startRuleBody(0);
- }
-
- {
- StyleDeclarationScope scope(this, declaration);
- cssyyparse(this);
- }
-
- m_rule = 0;
-
- bool ok = false;
- if (m_hasFontFaceOnlyValues)
- deleteFontFaceOnlyValues();
- if (!m_parsedProperties.isEmpty()) {
- ok = true;
- declaration->addParsedProperties(m_parsedProperties);
- clearProperties();
- }
-
- if (m_sourceDataHandler)
- m_sourceDataHandler->endRuleBody(string.length(), false);
- m_sourceDataHandler = 0;
-
- return ok;
-}
-
-PassRefPtr<MediaQuerySet> CSSParser::parseMediaQueryList(const String& string)
-{
- ASSERT(!m_mediaList);
-
- // can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
- // instead insert one " " (which is caught by maybe_space in CSSGrammar.y)
- setupParser("@-internal-medialist ", string, "");
- cssyyparse(this);
-
- ASSERT(m_mediaList);
- return m_mediaList.release();
-}
-
-static inline void filterProperties(bool important, const CSSParser::ParsedPropertyVector& input, Vector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties, HashSet<AtomicString>& seenVariables)
-{
- // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
- for (int i = input.size() - 1; i >= 0; --i) {
- const CSSProperty& property = input[i];
- if (property.isImportant() != important)
- continue;
- if (property.id() == CSSPropertyVariable) {
- const AtomicString& name = toCSSVariableValue(property.value())->name();
- if (!seenVariables.add(name).isNewEntry)
- continue;
- output[--unusedEntries] = property;
- continue;
- }
- const unsigned propertyIDIndex = property.id() - firstCSSProperty;
- if (seenProperties.get(propertyIDIndex))
- continue;
- seenProperties.set(propertyIDIndex);
- output[--unusedEntries] = property;
- }
-}
-
-PassRefPtr<ImmutableStylePropertySet> CSSParser::createStylePropertySet()
-{
- BitArray<numCSSProperties> seenProperties;
- size_t unusedEntries = m_parsedProperties.size();
- Vector<CSSProperty, 256> results(unusedEntries);
-
- // Important properties have higher priority, so add them first. Duplicate definitions can then be ignored when found.
- HashSet<AtomicString> seenVariables;
- filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties, seenVariables);
- filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties, seenVariables);
- if (unusedEntries)
- results.remove(0, unusedEntries);
-
- CSSParserMode mode = inViewport() ? CSSViewportRuleMode : m_context.mode();
-
- return ImmutableStylePropertySet::create(results.data(), results.size(), mode);
-}
-
-void CSSParser::addPropertyWithPrefixingVariant(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important, bool implicit)
-{
- RefPtr<CSSValue> val = value.get();
- addProperty(propId, value, important, implicit);
-
- CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(propId);
- if (prefixingVariant == propId)
- return;
-
- if (m_currentShorthand) {
- // We can't use ShorthandScope here as we can already be inside one (e.g we are parsing CSSTransition).
- m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
- addProperty(prefixingVariant, val.release(), important, implicit);
- m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
- } else {
- addProperty(prefixingVariant, val.release(), important, implicit);
- }
-}
-
-void CSSParser::addProperty(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important, bool implicit)
-{
- CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value.get()) : 0;
- // This property doesn't belong to a shorthand or is a CSS variable (which will be resolved later).
- if (!m_currentShorthand || (primitiveValue && primitiveValue->isVariableName())) {
- m_parsedProperties.append(CSSProperty(propId, value, important, false, CSSPropertyInvalid, m_implicitShorthand || implicit));
- return;
- }
-
- Vector<StylePropertyShorthand, 4> shorthands;
- getMatchingShorthandsForLonghand(propId, &shorthands);
- // The longhand does not belong to multiple shorthands.
- if (shorthands.size() == 1)
- m_parsedProperties.append(CSSProperty(propId, value, important, true, CSSPropertyInvalid, m_implicitShorthand || implicit));
- else
- m_parsedProperties.append(CSSProperty(propId, value, important, true, indexOfShorthandForLonghand(m_currentShorthand, shorthands), m_implicitShorthand || implicit));
-}
-
-void CSSParser::rollbackLastProperties(int num)
-{
- ASSERT(num >= 0);
- ASSERT(m_parsedProperties.size() >= static_cast<unsigned>(num));
- m_parsedProperties.shrink(m_parsedProperties.size() - num);
-}
-
-void CSSParser::clearProperties()
-{
- m_parsedProperties.clear();
- m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
- m_hasFontFaceOnlyValues = false;
-}
-
-// FIXME: Move to CSSParserContext?
-KURL CSSParser::completeURL(const CSSParserContext& context, const String& url)
-{
- if (url.isNull())
- return KURL();
- if (context.charset().isEmpty())
- return KURL(context.baseURL(), url);
- return KURL(context.baseURL(), url, context.charset());
-}
-
-KURL CSSParser::completeURL(const String& url) const
-{
- return completeURL(m_context, url);
-}
-
-bool CSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc)
-{
- bool mustBeNonNegative = unitflags & FNonNeg;
-
- if (!parseCalculation(value, mustBeNonNegative ? ValueRangeNonNegative : ValueRangeAll))
- return false;
-
- bool b = false;
- switch (m_parsedCalculation->category()) {
- case CalcLength:
- b = (unitflags & FLength);
- break;
- case CalcPercent:
- b = (unitflags & FPercent);
- if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
- b = false;
- break;
- case CalcNumber:
- b = (unitflags & FNumber);
- if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt())
- b = true;
- if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
- b = false;
- break;
- case CalcPercentLength:
- b = (unitflags & FPercent) && (unitflags & FLength);
- break;
- case CalcPercentNumber:
- b = (unitflags & FPercent) && (unitflags & FNumber);
- break;
- case CalcVariable:
- b = true;
- break;
- case CalcOther:
- break;
- }
- if (!b || releaseCalc == ReleaseParsedCalcValue)
- m_parsedCalculation.release();
- return b;
-}
-
-inline bool CSSParser::shouldAcceptUnitLessValues(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode)
-{
- // Quirks mode and presentation attributes accept unit less values.
- return (unitflags & (FLength | FAngle | FTime)) && (!value->fValue || isUnitLessLengthParsingEnabledForMode(cssParserMode));
-}
-
-bool CSSParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode, ReleaseParsedCalcValueCondition releaseCalc)
-{
- if (isCalculation(value))
- return validCalculationUnit(value, unitflags, releaseCalc);
-
- bool b = false;
- switch (value->unit) {
- case CSSPrimitiveValue::CSS_VARIABLE_NAME:
- // Variables are checked at the point they are dereferenced because unit type is not available here.
- b = true;
- break;
- case CSSPrimitiveValue::CSS_NUMBER:
- b = (unitflags & FNumber);
- if (!b && shouldAcceptUnitLessValues(value, unitflags, cssParserMode)) {
- value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX :
- ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
- b = true;
- }
- if (!b && (unitflags & FInteger) && value->isInt)
- b = true;
- if (!b && (unitflags & FPositiveInteger) && value->isInt && value->fValue > 0)
- b = true;
- break;
- case CSSPrimitiveValue::CSS_PERCENTAGE:
- b = (unitflags & FPercent);
- break;
- case CSSParserValue::Q_EMS:
- case CSSPrimitiveValue::CSS_EMS:
- case CSSPrimitiveValue::CSS_REMS:
- case CSSPrimitiveValue::CSS_CHS:
- case CSSPrimitiveValue::CSS_EXS:
- case CSSPrimitiveValue::CSS_PX:
- case CSSPrimitiveValue::CSS_CM:
- case CSSPrimitiveValue::CSS_MM:
- case CSSPrimitiveValue::CSS_IN:
- case CSSPrimitiveValue::CSS_PT:
- case CSSPrimitiveValue::CSS_PC:
- case CSSPrimitiveValue::CSS_VW:
- case CSSPrimitiveValue::CSS_VH:
- case CSSPrimitiveValue::CSS_VMIN:
- case CSSPrimitiveValue::CSS_VMAX:
- b = (unitflags & FLength);
- break;
- case CSSPrimitiveValue::CSS_MS:
- case CSSPrimitiveValue::CSS_S:
- b = (unitflags & FTime);
- break;
- case CSSPrimitiveValue::CSS_DEG:
- case CSSPrimitiveValue::CSS_RAD:
- case CSSPrimitiveValue::CSS_GRAD:
- case CSSPrimitiveValue::CSS_TURN:
- b = (unitflags & FAngle);
- break;
- case CSSPrimitiveValue::CSS_DPPX:
- case CSSPrimitiveValue::CSS_DPI:
- case CSSPrimitiveValue::CSS_DPCM:
- b = (unitflags & FResolution);
- break;
- case CSSPrimitiveValue::CSS_HZ:
- case CSSPrimitiveValue::CSS_KHZ:
- case CSSPrimitiveValue::CSS_DIMENSION:
- default:
- break;
- }
- if (b && unitflags & FNonNeg && value->fValue < 0)
- b = false;
- return b;
-}
-
-inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveNumericValue(CSSParserValue* value)
-{
- if (value->unit == CSSPrimitiveValue::CSS_VARIABLE_NAME)
- return createPrimitiveVariableNameValue(value);
-
- if (m_parsedCalculation) {
- ASSERT(isCalculation(value));
- return CSSPrimitiveValue::create(m_parsedCalculation.release());
- }
-
- ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
- || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
- || (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)
- || (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM));
- return cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
-}
-
-inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveStringValue(CSSParserValue* value)
-{
- ASSERT(value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT);
- return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING);
-}
-
-inline PassRefPtr<CSSPrimitiveValue> CSSParser::createPrimitiveVariableNameValue(CSSParserValue* value)
-{
- ASSERT(value->unit == CSSPrimitiveValue::CSS_VARIABLE_NAME);
- return CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_VARIABLE_NAME);
-}
-
-static inline bool isComma(CSSParserValue* value)
-{
- return value && value->unit == CSSParserValue::Operator && value->iValue == ',';
-}
-
-static inline bool isForwardSlashOperator(CSSParserValue* value)
-{
- ASSERT(value);
- return value->unit == CSSParserValue::Operator && value->iValue == '/';
-}
-
-static bool isGeneratedImageValue(CSSParserValue* val)
-{
- if (val->unit != CSSParserValue::Function)
- return false;
-
- return equalIgnoringCase(val->function->name, "-webkit-gradient(")
- || equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")
- || equalIgnoringCase(val->function->name, "linear-gradient(")
- || equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")
- || equalIgnoringCase(val->function->name, "repeating-linear-gradient(")
- || equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")
- || equalIgnoringCase(val->function->name, "radial-gradient(")
- || equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")
- || equalIgnoringCase(val->function->name, "repeating-radial-gradient(")
- || equalIgnoringCase(val->function->name, "-webkit-canvas(")
- || equalIgnoringCase(val->function->name, "-webkit-cross-fade(");
-}
-
-bool CSSParser::validWidthOrHeight(CSSParserValue* value)
-{
- int id = value->id;
- if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic || id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent || id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent)
- return true;
- return !id && validUnit(value, FLength | FPercent | FNonNeg);
-}
-
-inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(CSSValueID identifier, CSSParserValue* value)
-{
- if (identifier)
- return cssValuePool().createIdentifierValue(identifier);
- if (value->unit == CSSPrimitiveValue::CSS_STRING)
- return createPrimitiveStringValue(value);
- if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
- return createPrimitiveNumericValue(value);
- if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
- return createPrimitiveNumericValue(value);
- if (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)
- return createPrimitiveNumericValue(value);
- if (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM)
- return createPrimitiveNumericValue(value);
- if (value->unit == CSSPrimitiveValue::CSS_VARIABLE_NAME)
- return createPrimitiveVariableNameValue(value);
- if (value->unit >= CSSParserValue::Q_EMS)
- return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
- if (isCalculation(value))
- return CSSPrimitiveValue::create(m_parsedCalculation.release());
-
- return 0;
-}
-
-void CSSParser::addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue> prpValue, bool important)
-{
- const StylePropertyShorthand& shorthand = shorthandForProperty(propId);
- unsigned shorthandLength = shorthand.length();
- if (!shorthandLength) {
- addProperty(propId, prpValue, important);
- return;
- }
-
- RefPtr<CSSValue> value = prpValue;
- ShorthandScope scope(this, propId);
- const CSSPropertyID* longhands = shorthand.properties();
- for (unsigned i = 0; i < shorthandLength; ++i)
- addProperty(longhands[i], value, important);
-}
-
-void CSSParser::setCurrentProperty(CSSPropertyID propId)
-{
- m_id = propId;
-}
-
-bool CSSParser::parseValue(CSSPropertyID propId, bool important)
-{
- if (!isInternalPropertyAndValueParsingEnabledForMode(m_context.mode()) && isInternalProperty(propId))
- return false;
-
- // We don't count the UA style sheet in our statistics.
- if (m_useCounter)
- m_useCounter->count(m_context, propId);
-
- if (!m_valueList)
- return false;
-
- CSSParserValue* value = m_valueList->current();
-
- if (!value)
- return false;
-
- if (inViewport()) {
- // Allow @viewport rules from UA stylesheets even if the feature is disabled.
- if (!RuntimeEnabledFeatures::cssViewportEnabled() && !isUASheetBehavior(m_context.mode()))
- return false;
-
- return parseViewportProperty(propId, important);
- }
-
- // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function.
- // FIXME: This is to avoid having to pass parsedCalc to all validUnit callers.
- ASSERT(!m_parsedCalculation);
-
- CSSValueID id = value->id;
-
- int num = inShorthand() ? 1 : m_valueList->size();
-
- if (id == CSSValueInherit) {
- if (num != 1)
- return false;
- addExpandedPropertyForValue(propId, cssValuePool().createInheritedValue(), important);
- return true;
- }
- else if (id == CSSValueInitial) {
- if (num != 1)
- return false;
- addExpandedPropertyForValue(propId, cssValuePool().createExplicitInitialValue(), important);
- return true;
- }
-
- if (!id && value->unit == CSSPrimitiveValue::CSS_VARIABLE_NAME && num == 1) {
- addProperty(propId, createPrimitiveVariableNameValue(value), important);
- m_valueList->next();
- return true;
- }
- ASSERT(propId != CSSPropertyVariable);
-
- if (isKeywordPropertyID(propId)) {
- if (!isValidKeywordPropertyAndValue(propId, id, m_context))
- return false;
- if (m_valueList->next() && !inShorthand())
- return false;
- addProperty(propId, cssValuePool().createIdentifierValue(id), important);
- return true;
- }
-
- bool validPrimitive = false;
- RefPtr<CSSValue> parsedValue;
-
- switch (propId) {
- case CSSPropertySize: // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
- return parseSize(propId, important);
-
- case CSSPropertyQuotes: // [<string> <string>]+ | none | inherit
- if (id)
- validPrimitive = true;
- else
- return parseQuotes(propId, important);
- break;
- case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | isolate | isolate-override | plaintext | inherit
- if (id == CSSValueNormal
- || id == CSSValueEmbed
- || id == CSSValueBidiOverride
- || id == CSSValueWebkitIsolate
- || id == CSSValueWebkitIsolateOverride
- || id == CSSValueWebkitPlaintext)
- validPrimitive = true;
- break;
-
- case CSSPropertyContent: // [ <string> | <uri> | <counter> | attr(X) | open-quote |
- // close-quote | no-open-quote | no-close-quote ]+ | inherit
- return parseContent(propId, important);
-
- case CSSPropertyClip: // <shape> | auto | inherit
- if (id == CSSValueAuto)
- validPrimitive = true;
- else if (value->unit == CSSParserValue::Function)
- return parseClipShape(propId, important);
- break;
-
- /* Start of supported CSS properties with validation. This is needed for parseShorthand to work
- * correctly and allows optimization in WebCore::applyRule(..)
- */
- case CSSPropertyOverflow: {
- ShorthandScope scope(this, propId);
- if (num != 1 || !parseValue(CSSPropertyOverflowY, important))
- return false;
-
- RefPtr<CSSValue> overflowXValue;
-
- // FIXME: -webkit-paged-x or -webkit-paged-y only apply to overflow-y. If this value has been
- // set using the shorthand, then for now overflow-x will default to auto, but once we implement
- // pagination controls, it should default to hidden. If the overflow-y value is anything but
- // paged-x or paged-y, then overflow-x and overflow-y should have the same value.
- if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY)
- overflowXValue = cssValuePool().createIdentifierValue(CSSValueAuto);
- else
- overflowXValue = m_parsedProperties.last().value();
- addProperty(CSSPropertyOverflowX, overflowXValue.release(), important);
- return true;
- }
-
- case CSSPropertyTextAlign:
- // left | right | center | justify | -webkit-left | -webkit-right | -webkit-center | -webkit-match-parent
- // | start | end | <string> | inherit | -webkit-auto (converted to start)
- if ((id >= CSSValueWebkitAuto && id <= CSSValueWebkitMatchParent) || id == CSSValueStart || id == CSSValueEnd
- || value->unit == CSSPrimitiveValue::CSS_STRING)
- validPrimitive = true;
- break;
-
- case CSSPropertyFontWeight: { // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
- if (m_valueList->size() != 1)
- return false;
- return parseFontWeight(important);
- }
- case CSSPropertyBorderSpacing: {
- if (num == 1) {
- ShorthandScope scope(this, CSSPropertyBorderSpacing);
- if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important))
- return false;
- CSSValue* value = m_parsedProperties.last().value();
- addProperty(CSSPropertyWebkitBorderVerticalSpacing, value, important);
- return true;
- }
- else if (num == 2) {
- ShorthandScope scope(this, CSSPropertyBorderSpacing);
- if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important) || !parseValue(CSSPropertyWebkitBorderVerticalSpacing, important))
- return false;
- return true;
- }
- return false;
- }
- case CSSPropertyWebkitBorderHorizontalSpacing:
- case CSSPropertyWebkitBorderVerticalSpacing:
- validPrimitive = validUnit(value, FLength | FNonNeg);
- break;
- case CSSPropertyOutlineColor: // <color> | invert | inherit
- // Outline color has "invert" as additional keyword.
- // Also, we want to allow the special focus color even in HTML Standard parsing mode.
- if (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor) {
- validPrimitive = true;
- break;
- }
- /* nobreak */
- case CSSPropertyBackgroundColor: // <color> | inherit
- case CSSPropertyBorderTopColor: // <color> | inherit
- case CSSPropertyBorderRightColor:
- case CSSPropertyBorderBottomColor:
- case CSSPropertyBorderLeftColor:
- case CSSPropertyWebkitBorderStartColor:
- case CSSPropertyWebkitBorderEndColor:
- case CSSPropertyWebkitBorderBeforeColor:
- case CSSPropertyWebkitBorderAfterColor:
- case CSSPropertyColor: // <color> | inherit
- case CSSPropertyTextDecorationColor: // CSS3 text decoration colors
- case CSSPropertyTextLineThroughColor:
- case CSSPropertyTextUnderlineColor:
- case CSSPropertyTextOverlineColor:
- case CSSPropertyWebkitColumnRuleColor:
- case CSSPropertyWebkitTextEmphasisColor:
- case CSSPropertyWebkitTextFillColor:
- case CSSPropertyWebkitTextStrokeColor:
- if (propId == CSSPropertyTextDecorationColor
- && !RuntimeEnabledFeatures::css3TextDecorationsEnabled())
- return false;
-
- if ((id >= CSSValueAqua && id <= CSSValueWebkitText) || id == CSSValueMenu) {
- validPrimitive = isValueAllowedInMode(id, m_context.mode());
- } else {
- parsedValue = parseColor();
- if (parsedValue)
- m_valueList->next();
- }
- break;
-
- case CSSPropertyCursor: {
- // Grammar defined by CSS3 UI and modified by CSS4 images:
- // [ [<image> [<x> <y>]?,]*
- // [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
- // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize |
- // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help |
- // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed | -webkit-zoom-in
- // -webkit-zoom-out | all-scroll | -webkit-grab | -webkit-grabbing ] ] | inherit
- RefPtr<CSSValueList> list;
- while (value) {
- RefPtr<CSSValue> image = 0;
- if (value->unit == CSSPrimitiveValue::CSS_URI) {
- String uri = value->string;
- if (!uri.isNull())
- image = CSSImageValue::create(completeURL(uri));
- } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) {
- image = parseImageSet(m_valueList.get());
- if (!image)
- break;
- } else
- break;
-
- Vector<int> coords;
- value = m_valueList->next();
- while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) {
- coords.append(int(value->fValue));
- value = m_valueList->next();
- }
- bool hasHotSpot = false;
- IntPoint hotSpot(-1, -1);
- int nrcoords = coords.size();
- if (nrcoords > 0 && nrcoords != 2)
- return false;
- if (nrcoords == 2) {
- hasHotSpot = true;
- hotSpot = IntPoint(coords[0], coords[1]);
- }
-
- if (!list)
- list = CSSValueList::createCommaSeparated();
-
- if (image)
- list->append(CSSCursorImageValue::create(image, hasHotSpot, hotSpot));
-
- if (!value || !(value->unit == CSSParserValue::Operator && value->iValue == ','))
- return false;
- value = m_valueList->next(); // comma
- }
- if (list) {
- if (!value)
- return false;
- if (inQuirksMode() && value->id == CSSValueHand) // MSIE 5 compatibility :/
- list->append(cssValuePool().createIdentifierValue(CSSValuePointer));
- else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)
- list->append(cssValuePool().createIdentifierValue(value->id));
- m_valueList->next();
- parsedValue = list.release();
- break;
- } else if (value) {
- id = value->id;
- if (inQuirksMode() && value->id == CSSValueHand) { // MSIE 5 compatibility :/
- id = CSSValuePointer;
- validPrimitive = true;
- } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)
- validPrimitive = true;
- } else {
- ASSERT_NOT_REACHED();
- return false;
- }
- break;
- }
-
- case CSSPropertyBackgroundBlendMode:
- case CSSPropertyBackgroundAttachment:
- case CSSPropertyBackgroundClip:
- case CSSPropertyWebkitBackgroundClip:
- case CSSPropertyWebkitBackgroundComposite:
- case CSSPropertyBackgroundImage:
- case CSSPropertyBackgroundOrigin:
- case CSSPropertyMaskSourceType:
- case CSSPropertyWebkitBackgroundOrigin:
- case CSSPropertyBackgroundPosition:
- case CSSPropertyBackgroundPositionX:
- case CSSPropertyBackgroundPositionY:
- case CSSPropertyBackgroundSize:
- case CSSPropertyWebkitBackgroundSize:
- case CSSPropertyBackgroundRepeat:
- case CSSPropertyBackgroundRepeatX:
- case CSSPropertyBackgroundRepeatY:
- case CSSPropertyWebkitMaskClip:
- case CSSPropertyWebkitMaskComposite:
- case CSSPropertyWebkitMaskImage:
- case CSSPropertyWebkitMaskOrigin:
- case CSSPropertyWebkitMaskPosition:
- case CSSPropertyWebkitMaskPositionX:
- case CSSPropertyWebkitMaskPositionY:
- case CSSPropertyWebkitMaskSize:
- case CSSPropertyWebkitMaskRepeat:
- case CSSPropertyWebkitMaskRepeatX:
- case CSSPropertyWebkitMaskRepeatY:
- {
- RefPtr<CSSValue> val1;
- RefPtr<CSSValue> val2;
- CSSPropertyID propId1, propId2;
- bool result = false;
- if (parseFillProperty(propId, propId1, propId2, val1, val2)) {
- OwnPtr<ShorthandScope> shorthandScope;
- if (propId == CSSPropertyBackgroundPosition ||
- propId == CSSPropertyBackgroundRepeat ||
- propId == CSSPropertyWebkitMaskPosition ||
- propId == CSSPropertyWebkitMaskRepeat) {
- shorthandScope = adoptPtr(new ShorthandScope(this, propId));
- }
- addProperty(propId1, val1.release(), important);
- if (val2)
- addProperty(propId2, val2.release(), important);
- result = true;
- }
- m_implicitShorthand = false;
- return result;
- }
- case CSSPropertyObjectPosition:
- return RuntimeEnabledFeatures::objectFitPositionEnabled() && parseObjectPosition(important);
- case CSSPropertyListStyleImage: // <uri> | none | inherit
- case CSSPropertyBorderImageSource:
- case CSSPropertyWebkitMaskBoxImageSource:
- if (id == CSSValueNone) {
- parsedValue = cssValuePool().createIdentifierValue(CSSValueNone);
- m_valueList->next();
- } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
- parsedValue = CSSImageValue::create(completeURL(value->string));
- m_valueList->next();
- } else if (isGeneratedImageValue(value)) {
- if (parseGeneratedImage(m_valueList.get(), parsedValue))
- m_valueList->next();
- else
- return false;
- }
- else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) {
- parsedValue = parseImageSet(m_valueList.get());
- if (!parsedValue)
- return false;
- m_valueList->next();
- }
- break;
-
- case CSSPropertyWebkitTextStrokeWidth:
- case CSSPropertyOutlineWidth: // <border-width> | inherit
- case CSSPropertyBorderTopWidth: //// <border-width> | inherit
- case CSSPropertyBorderRightWidth: // Which is defined as
- case CSSPropertyBorderBottomWidth: // thin | medium | thick | <length>
- case CSSPropertyBorderLeftWidth:
- case CSSPropertyWebkitBorderStartWidth:
- case CSSPropertyWebkitBorderEndWidth:
- case CSSPropertyWebkitBorderBeforeWidth:
- case CSSPropertyWebkitBorderAfterWidth:
- case CSSPropertyWebkitColumnRuleWidth:
- if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FLength | FNonNeg);
- break;
-
- case CSSPropertyLetterSpacing: // normal | <length> | inherit
- case CSSPropertyWordSpacing: // normal | <length> | inherit
- if (id == CSSValueNormal)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FLength);
- break;
-
- case CSSPropertyTextIndent:
- parsedValue = parseTextIndent();
- break;
-
- case CSSPropertyPaddingTop: //// <padding-width> | inherit
- case CSSPropertyPaddingRight: // Which is defined as
- case CSSPropertyPaddingBottom: // <length> | <percentage>
- case CSSPropertyPaddingLeft: ////
- case CSSPropertyWebkitPaddingStart:
- case CSSPropertyWebkitPaddingEnd:
- case CSSPropertyWebkitPaddingBefore:
- case CSSPropertyWebkitPaddingAfter:
- validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
- break;
-
- case CSSPropertyMaxWidth:
- case CSSPropertyWebkitMaxLogicalWidth:
- case CSSPropertyMaxHeight:
- case CSSPropertyWebkitMaxLogicalHeight:
- validPrimitive = (id == CSSValueNone || validWidthOrHeight(value));
- break;
-
- case CSSPropertyMinWidth:
- case CSSPropertyWebkitMinLogicalWidth:
- case CSSPropertyMinHeight:
- case CSSPropertyWebkitMinLogicalHeight:
- validPrimitive = validWidthOrHeight(value);
- break;
-
- case CSSPropertyWidth:
- case CSSPropertyWebkitLogicalWidth:
- case CSSPropertyHeight:
- case CSSPropertyWebkitLogicalHeight:
- validPrimitive = (id == CSSValueAuto || validWidthOrHeight(value));
- break;
-
- case CSSPropertyFontSize:
- return parseFontSize(important);
-
- case CSSPropertyFontVariant: // normal | small-caps | inherit
- return parseFontVariant(important);
-
- case CSSPropertyVerticalAlign:
- // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
- // <percentage> | <length> | inherit
-
- if (id >= CSSValueBaseline && id <= CSSValueWebkitBaselineMiddle)
- validPrimitive = true;
- else
- validPrimitive = (!id && validUnit(value, FLength | FPercent));
- break;
-
- case CSSPropertyBottom: // <length> | <percentage> | auto | inherit
- case CSSPropertyLeft: // <length> | <percentage> | auto | inherit
- case CSSPropertyRight: // <length> | <percentage> | auto | inherit
- case CSSPropertyTop: // <length> | <percentage> | auto | inherit
- case CSSPropertyMarginTop: //// <margin-width> | inherit
- case CSSPropertyMarginRight: // Which is defined as
- case CSSPropertyMarginBottom: // <length> | <percentage> | auto | inherit
- case CSSPropertyMarginLeft: ////
- case CSSPropertyWebkitMarginStart:
- case CSSPropertyWebkitMarginEnd:
- case CSSPropertyWebkitMarginBefore:
- case CSSPropertyWebkitMarginAfter:
- if (id == CSSValueAuto)
- validPrimitive = true;
- else
- validPrimitive = (!id && validUnit(value, FLength | FPercent));
- break;
-
- case CSSPropertyZIndex: // auto | <integer> | inherit
- if (id == CSSValueAuto) {
- validPrimitive = true;
- break;
- }
- /* nobreak */
- case CSSPropertyOrphans: // <integer> | inherit | auto (We've added support for auto for backwards compatibility)
- case CSSPropertyWidows: // <integer> | inherit | auto (Ditto)
- if (id == CSSValueAuto)
- validPrimitive = true;
- else
- validPrimitive = (!id && validUnit(value, FInteger, HTMLQuirksMode));
- break;
-
- case CSSPropertyLineHeight:
- return parseLineHeight(important);
- case CSSPropertyCounterIncrement: // [ <identifier> <integer>? ]+ | none | inherit
- if (id != CSSValueNone)
- return parseCounter(propId, 1, important);
- validPrimitive = true;
- break;
- case CSSPropertyCounterReset: // [ <identifier> <integer>? ]+ | none | inherit
- if (id != CSSValueNone)
- return parseCounter(propId, 0, important);
- validPrimitive = true;
- break;
- case CSSPropertyFontFamily:
- // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit
- {
- parsedValue = parseFontFamily();
- break;
- }
-
- case CSSPropertyTextDecoration:
- // Fall through 'text-decoration-line' parsing if CSS 3 Text Decoration
- // is disabled to match CSS 2.1 rules for parsing 'text-decoration'.
- if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) {
- // [ <text-decoration-line> || <text-decoration-style> || <text-decoration-color> ] | inherit
- return parseShorthand(CSSPropertyTextDecoration, textDecorationShorthand(), important);
- }
- case CSSPropertyWebkitTextDecorationsInEffect:
- case CSSPropertyTextDecorationLine:
- // none | [ underline || overline || line-through || blink ] | inherit
- return parseTextDecoration(propId, important);
-
- case CSSPropertyTextDecorationStyle:
- // solid | double | dotted | dashed | wavy
- if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()
- && (id == CSSValueSolid || id == CSSValueDouble || id == CSSValueDotted || id == CSSValueDashed || id == CSSValueWavy))
- validPrimitive = true;
- break;
-
- case CSSPropertyTextUnderlinePosition:
- // auto | under | inherit
- if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
- return parseTextUnderlinePosition(important);
- return false;
-
- case CSSPropertyZoom: // normal | reset | document | <number> | <percentage> | inherit
- if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument)
- validPrimitive = true;
- else
- validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode));
- break;
-
- case CSSPropertySrc: // Only used within @font-face and @-webkit-filter, so cannot use inherit | initial or be !important. This is a list of urls or local references.
- if (m_inFilterRule)
- return parseFilterRuleSrc();
- return parseFontFaceSrc();
-
- case CSSPropertyUnicodeRange:
- return parseFontFaceUnicodeRange();
-
- /* CSS3 properties */
-
- case CSSPropertyBorderImage:
- case CSSPropertyWebkitMaskBoxImage:
- return parseBorderImageShorthand(propId, important);
- case CSSPropertyWebkitBorderImage: {
- if (RefPtr<CSSValue> result = parseBorderImage(propId)) {
- addProperty(propId, result, important);
- return true;
- }
- return false;
- }
-
- case CSSPropertyBorderImageOutset:
- case CSSPropertyWebkitMaskBoxImageOutset: {
- RefPtr<CSSPrimitiveValue> result;
- if (parseBorderImageOutset(result)) {
- addProperty(propId, result, important);
- return true;
- }
- break;
- }
- case CSSPropertyBorderImageRepeat:
- case CSSPropertyWebkitMaskBoxImageRepeat: {
- RefPtr<CSSValue> result;
- if (parseBorderImageRepeat(result)) {
- addProperty(propId, result, important);
- return true;
- }
- break;
- }
- case CSSPropertyBorderImageSlice:
- case CSSPropertyWebkitMaskBoxImageSlice: {
- RefPtr<CSSBorderImageSliceValue> result;
- if (parseBorderImageSlice(propId, result)) {
- addProperty(propId, result, important);
- return true;
- }
- break;
- }
- case CSSPropertyBorderImageWidth:
- case CSSPropertyWebkitMaskBoxImageWidth: {
- RefPtr<CSSPrimitiveValue> result;
- if (parseBorderImageWidth(result)) {
- addProperty(propId, result, important);
- return true;
- }
- break;
- }
- case CSSPropertyBorderTopRightRadius:
- case CSSPropertyBorderTopLeftRadius:
- case CSSPropertyBorderBottomLeftRadius:
- case CSSPropertyBorderBottomRightRadius: {
- if (num != 1 && num != 2)
- return false;
- validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
- if (!validPrimitive)
- return false;
- RefPtr<CSSPrimitiveValue> parsedValue1 = createPrimitiveNumericValue(value);
- RefPtr<CSSPrimitiveValue> parsedValue2;
- if (num == 2) {
- value = m_valueList->next();
- validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
- if (!validPrimitive)
- return false;
- parsedValue2 = createPrimitiveNumericValue(value);
- } else
- parsedValue2 = parsedValue1;
-
- addProperty(propId, createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release()), important);
- return true;
- }
- case CSSPropertyTabSize:
- validPrimitive = validUnit(value, FInteger | FNonNeg);
- break;
- case CSSPropertyWebkitAspectRatio:
- return parseAspectRatio(important);
- case CSSPropertyBorderRadius:
- case CSSPropertyWebkitBorderRadius:
- return parseBorderRadius(propId, important);
- case CSSPropertyOutlineOffset:
- validPrimitive = validUnit(value, FLength);
- break;
- case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
- case CSSPropertyBoxShadow:
- case CSSPropertyWebkitBoxShadow:
- if (id == CSSValueNone)
- validPrimitive = true;
- else {
- RefPtr<CSSValueList> shadowValueList = parseShadow(m_valueList.get(), propId);
- if (shadowValueList) {
- addProperty(propId, shadowValueList.release(), important);
- m_valueList->next();
- return true;
- }
- return false;
- }
- break;
- case CSSPropertyWebkitBoxReflect:
- if (id == CSSValueNone)
- validPrimitive = true;
- else
- return parseReflect(propId, important);
- break;
- case CSSPropertyOpacity:
- validPrimitive = validUnit(value, FNumber);
- break;
- case CSSPropertyWebkitBoxFlex:
- validPrimitive = validUnit(value, FNumber);
- break;
- case CSSPropertyWebkitBoxFlexGroup:
- validPrimitive = validUnit(value, FInteger | FNonNeg, HTMLStandardMode);
- break;
- case CSSPropertyWebkitBoxOrdinalGroup:
- validPrimitive = validUnit(value, FInteger | FNonNeg, HTMLStandardMode) && value->fValue;
- break;
- case CSSPropertyWebkitFilter:
- if (id == CSSValueNone)
- validPrimitive = true;
- else {
- RefPtr<CSSValue> val = parseFilter();
- if (val) {
- addProperty(propId, val, important);
- return true;
- }
- return false;
- }
- break;
- case CSSPropertyFlex: {
- ShorthandScope scope(this, propId);
- if (id == CSSValueNone) {
- addProperty(CSSPropertyFlexGrow, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
- addProperty(CSSPropertyFlexShrink, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
- addProperty(CSSPropertyFlexBasis, cssValuePool().createIdentifierValue(CSSValueAuto), important);
- return true;
- }
- return parseFlex(m_valueList.get(), important);
- }
- case CSSPropertyFlexBasis:
- // FIXME: Support intrinsic dimensions too.
- if (id == CSSValueAuto)
- validPrimitive = true;
- else
- validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
- break;
- case CSSPropertyFlexGrow:
- case CSSPropertyFlexShrink:
- validPrimitive = validUnit(value, FNumber | FNonNeg);
- break;
- case CSSPropertyOrder:
- if (validUnit(value, FInteger, HTMLStandardMode)) {
- if (value->unit != CSSPrimitiveValue::CSS_VARIABLE_NAME) {
- // We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set.
- parsedValue = cssValuePool().createValue(max(static_cast<double>(std::numeric_limits<int>::min() + 2), value->fValue),
- static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
- m_valueList->next();
- } else {
- validPrimitive = true;
- }
- }
- break;
- case CSSPropertyInternalMarqueeIncrement:
- if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FLength | FPercent);
- break;
- case CSSPropertyInternalMarqueeRepetition:
- if (id == CSSValueInfinite)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FInteger | FNonNeg);
- break;
- case CSSPropertyInternalMarqueeSpeed:
- if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FTime | FInteger | FNonNeg);
- break;
- case CSSPropertyWebkitFlowInto:
- if (!RuntimeEnabledFeatures::cssRegionsEnabled())
- return false;
- return parseFlowThread(propId, important);
- case CSSPropertyWebkitFlowFrom:
- if (!RuntimeEnabledFeatures::cssRegionsEnabled())
- return false;
- return parseRegionThread(propId, important);
- case CSSPropertyWebkitTransform:
- if (id == CSSValueNone)
- validPrimitive = true;
- else {
- RefPtr<CSSValue> transformValue = parseTransform();
- if (transformValue) {
- addProperty(propId, transformValue.release(), important);
- return true;
- }
- return false;
- }
- break;
- case CSSPropertyWebkitTransformOrigin:
- case CSSPropertyWebkitTransformOriginX:
- case CSSPropertyWebkitTransformOriginY:
- case CSSPropertyWebkitTransformOriginZ: {
- RefPtr<CSSValue> val1;
- RefPtr<CSSValue> val2;
- RefPtr<CSSValue> val3;
- CSSPropertyID propId1, propId2, propId3;
- if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
- addProperty(propId1, val1.release(), important);
- if (val2)
- addProperty(propId2, val2.release(), important);
- if (val3)
- addProperty(propId3, val3.release(), important);
- return true;
- }
- return false;
- }
- case CSSPropertyWebkitPerspective:
- if (id == CSSValueNone)
- validPrimitive = true;
- else {
- // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
- if (validUnit(value, FNumber | FLength | FNonNeg)) {
- RefPtr<CSSValue> val = createPrimitiveNumericValue(value);
- if (val) {
- addProperty(propId, val.release(), important);
- return true;
- }
- return false;
- }
- }
- break;
- case CSSPropertyWebkitPerspectiveOrigin:
- case CSSPropertyWebkitPerspectiveOriginX:
- case CSSPropertyWebkitPerspectiveOriginY: {
- RefPtr<CSSValue> val1;
- RefPtr<CSSValue> val2;
- CSSPropertyID propId1, propId2;
- if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
- addProperty(propId1, val1.release(), important);
- if (val2)
- addProperty(propId2, val2.release(), important);
- return true;
- }
- return false;
- }
- case CSSPropertyAnimationDelay:
- case CSSPropertyAnimationDirection:
- case CSSPropertyAnimationDuration:
- case CSSPropertyAnimationFillMode:
- case CSSPropertyAnimationName:
- case CSSPropertyAnimationPlayState:
- case CSSPropertyAnimationIterationCount:
- case CSSPropertyAnimationTimingFunction:
- if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
- break;
- case CSSPropertyWebkitAnimationDelay:
- case CSSPropertyWebkitAnimationDirection:
- case CSSPropertyWebkitAnimationDuration:
- case CSSPropertyWebkitAnimationFillMode:
- case CSSPropertyWebkitAnimationName:
- case CSSPropertyWebkitAnimationPlayState:
- case CSSPropertyWebkitAnimationIterationCount:
- case CSSPropertyWebkitAnimationTimingFunction:
- case CSSPropertyTransitionDelay:
- case CSSPropertyTransitionDuration:
- case CSSPropertyTransitionTimingFunction:
- case CSSPropertyTransitionProperty:
- case CSSPropertyWebkitTransitionDelay:
- case CSSPropertyWebkitTransitionDuration:
- case CSSPropertyWebkitTransitionTimingFunction:
- case CSSPropertyWebkitTransitionProperty: {
- RefPtr<CSSValue> val;
- AnimationParseContext context;
- if (parseAnimationProperty(propId, val, context)) {
- addPropertyWithPrefixingVariant(propId, val.release(), important);
- return true;
- }
- return false;
- }
-
- case CSSPropertyGridAutoColumns:
- case CSSPropertyGridAutoRows:
- if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
- return false;
- parsedValue = parseGridTrackSize(*m_valueList);
- break;
-
- case CSSPropertyGridDefinitionColumns:
- case CSSPropertyGridDefinitionRows:
- if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
- return false;
- return parseGridTrackList(propId, important);
-
- case CSSPropertyGridColumnEnd:
- case CSSPropertyGridColumnStart:
- case CSSPropertyGridRowEnd:
- case CSSPropertyGridRowStart:
- if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
- return false;
- parsedValue = parseGridPosition();
- break;
-
- case CSSPropertyGridColumn:
- case CSSPropertyGridRow:
- if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
- return false;
- return parseGridItemPositionShorthand(propId, important);
-
- case CSSPropertyGridArea:
- if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
- return false;
- return parseGridAreaShorthand(important);
-
- case CSSPropertyGridTemplate:
- if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
- return false;
- parsedValue = parseGridTemplate();
- break;
-
- case CSSPropertyWebkitMarginCollapse: {
- if (num == 1) {
- ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
- if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important))
- return false;
- CSSValue* value = m_parsedProperties.last().value();
- addProperty(webkitMarginCollapseShorthand().properties()[1], value, important);
- return true;
- }
- else if (num == 2) {
- ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
- if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important) || !parseValue(webkitMarginCollapseShorthand().properties()[1], important))
- return false;
- return true;
- }
- return false;
- }
- case CSSPropertyTextLineThroughWidth:
- case CSSPropertyTextOverlineWidth:
- case CSSPropertyTextUnderlineWidth:
- if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueThin ||
- id == CSSValueMedium || id == CSSValueThick)
- validPrimitive = true;
- else
- validPrimitive = !id && validUnit(value, FNumber | FLength | FPercent);
- break;
- case CSSPropertyWebkitColumnCount:
- parsedValue = parseColumnCount();
- break;
- case CSSPropertyWebkitColumnGap: // normal | <length>
- if (id == CSSValueNormal)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FLength | FNonNeg);
- break;
- case CSSPropertyWebkitColumnAxis:
- if (id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto)
- validPrimitive = true;
- break;
- case CSSPropertyWebkitColumnProgression:
- if (id == CSSValueNormal || id == CSSValueReverse)
- validPrimitive = true;
- break;
- case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property)
- if (id == CSSValueAll || id == CSSValueNone)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FNumber | FNonNeg) && value->fValue == 1;
- break;
- case CSSPropertyWebkitColumnWidth: // auto | <length>
- parsedValue = parseColumnWidth();
- break;
- // End of CSS3 properties
-
- // Apple specific properties. These will never be standardized and are purely to
- // support custom WebKit-based Apple applications.
- case CSSPropertyWebkitLineClamp:
- // When specifying number of lines, don't allow 0 as a valid value
- // When specifying either type of unit, require non-negative integers
- validPrimitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, HTMLQuirksMode));
- break;
-
- case CSSPropertyWebkitFontSizeDelta: // <length>
- validPrimitive = validUnit(value, FLength);
- break;
-
- case CSSPropertyWebkitHighlight:
- if (id == CSSValueNone || value->unit == CSSPrimitiveValue::CSS_STRING)
- validPrimitive = true;
- break;
-
- case CSSPropertyWebkitHyphenateCharacter:
- if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
- validPrimitive = true;
- break;
-
- case CSSPropertyWebkitLineGrid:
- if (id == CSSValueNone)
- validPrimitive = true;
- else if (value->unit == CSSPrimitiveValue::CSS_IDENT) {
- String lineGridValue = String(value->string);
- if (!lineGridValue.isEmpty()) {
- addProperty(propId, cssValuePool().createValue(lineGridValue, CSSPrimitiveValue::CSS_STRING), important);
- return true;
- }
- }
- break;
- case CSSPropertyWebkitLocale:
- if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
- validPrimitive = true;
- break;
-
- // End Apple-specific properties
-
- case CSSPropertyWebkitAppRegion:
- if (id >= CSSValueDrag && id <= CSSValueNoDrag)
- validPrimitive = true;
- break;
-
- case CSSPropertyWebkitTapHighlightColor:
- if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu
- || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) {
- validPrimitive = true;
- } else {
- parsedValue = parseColor();
- if (parsedValue)
- m_valueList->next();
- }
- break;
-
- /* shorthand properties */
- case CSSPropertyBackground: {
- // Position must come before color in this array because a plain old "0" is a legal color
- // in quirks mode but it's usually the X coordinate of a position.
- const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat,
- CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin,
- CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundSize };
- return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
- }
- case CSSPropertyWebkitMask: {
- const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat,
- CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip, CSSPropertyWebkitMaskSize };
- return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
- }
- case CSSPropertyBorder:
- // [ 'border-width' || 'border-style' || <color> ] | inherit
- {
- if (parseShorthand(propId, parsingShorthandForProperty(CSSPropertyBorder), important)) {
- // The CSS3 Borders and Backgrounds specification says that border also resets border-image. It's as
- // though a value of none was specified for the image.
- addExpandedPropertyForValue(CSSPropertyBorderImage, cssValuePool().createImplicitInitialValue(), important);
- return true;
- }
- return false;
- }
- case CSSPropertyBorderTop:
- // [ 'border-top-width' || 'border-style' || <color> ] | inherit
- return parseShorthand(propId, borderTopShorthand(), important);
- case CSSPropertyBorderRight:
- // [ 'border-right-width' || 'border-style' || <color> ] | inherit
- return parseShorthand(propId, borderRightShorthand(), important);
- case CSSPropertyBorderBottom:
- // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit
- return parseShorthand(propId, borderBottomShorthand(), important);
- case CSSPropertyBorderLeft:
- // [ 'border-left-width' || 'border-style' || <color> ] | inherit
- return parseShorthand(propId, borderLeftShorthand(), important);
- case CSSPropertyWebkitBorderStart:
- return parseShorthand(propId, webkitBorderStartShorthand(), important);
- case CSSPropertyWebkitBorderEnd:
- return parseShorthand(propId, webkitBorderEndShorthand(), important);
- case CSSPropertyWebkitBorderBefore:
- return parseShorthand(propId, webkitBorderBeforeShorthand(), important);
- case CSSPropertyWebkitBorderAfter:
- return parseShorthand(propId, webkitBorderAfterShorthand(), important);
- case CSSPropertyOutline:
- // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
- return parseShorthand(propId, outlineShorthand(), important);
- case CSSPropertyBorderColor:
- // <color>{1,4} | inherit
- return parse4Values(propId, borderColorShorthand().properties(), important);
- case CSSPropertyBorderWidth:
- // <border-width>{1,4} | inherit
- return parse4Values(propId, borderWidthShorthand().properties(), important);
- case CSSPropertyBorderStyle:
- // <border-style>{1,4} | inherit
- return parse4Values(propId, borderStyleShorthand().properties(), important);
- case CSSPropertyMargin:
- // <margin-width>{1,4} | inherit
- return parse4Values(propId, marginShorthand().properties(), important);
- case CSSPropertyPadding:
- // <padding-width>{1,4} | inherit
- return parse4Values(propId, paddingShorthand().properties(), important);
- case CSSPropertyFlexFlow:
- return parseShorthand(propId, flexFlowShorthand(), important);
- case CSSPropertyFont:
- // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
- // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
- if (id >= CSSValueCaption && id <= CSSValueStatusBar)
- validPrimitive = true;
- else
- return parseFont(important);
- break;
- case CSSPropertyListStyle:
- return parseShorthand(propId, listStyleShorthand(), important);
- case CSSPropertyWebkitColumns:
- return parseColumnsShorthand(important);
- case CSSPropertyWebkitColumnRule:
- return parseShorthand(propId, webkitColumnRuleShorthand(), important);
- case CSSPropertyWebkitTextStroke:
- return parseShorthand(propId, webkitTextStrokeShorthand(), important);
- case CSSPropertyAnimation:
- if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
- break;
- case CSSPropertyWebkitAnimation:
- return parseAnimationShorthand(propId, important);
- case CSSPropertyTransition:
- case CSSPropertyWebkitTransition:
- return parseTransitionShorthand(propId, important);
- case CSSPropertyInvalid:
- return false;
- case CSSPropertyPage:
- return parsePage(propId, important);
- case CSSPropertyFontStretch:
- return false;
- // CSS Text Layout Module Level 3: Vertical writing support
- case CSSPropertyWebkitTextEmphasis:
- return parseShorthand(propId, webkitTextEmphasisShorthand(), important);
-
- case CSSPropertyWebkitTextEmphasisStyle:
- return parseTextEmphasisStyle(important);
-
- case CSSPropertyWebkitTextOrientation:
- // FIXME: For now just support sideways, sideways-right, upright and vertical-right.
- if (id == CSSValueSideways || id == CSSValueSidewaysRight || id == CSSValueVerticalRight || id == CSSValueUpright)
- validPrimitive = true;
- break;
-
- case CSSPropertyWebkitLineBoxContain:
- if (id == CSSValueNone)
- validPrimitive = true;
- else
- return parseLineBoxContain(important);
- break;
- case CSSPropertyWebkitFontFeatureSettings:
- if (id == CSSValueNormal)
- validPrimitive = true;
- else
- return parseFontFeatureSettings(important);
- break;
-
- case CSSPropertyWebkitFontVariantLigatures:
- if (id == CSSValueNormal)
- validPrimitive = true;
- else
- return parseFontVariantLigatures(important);
- break;
- case CSSPropertyWebkitClipPath:
- if (id == CSSValueNone) {
- validPrimitive = true;
- } else if (value->unit == CSSParserValue::Function) {
- return parseBasicShape(propId, important);
- } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
- parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI);
- addProperty(propId, parsedValue.release(), important);
- return true;
- }
- break;
- case CSSPropertyShapeInside:
- case CSSPropertyShapeOutside:
- if (!RuntimeEnabledFeatures::cssShapesEnabled())
- return false;
- if (id == CSSValueAuto)
- validPrimitive = true;
- else if (id == CSSValueContentBox || id == CSSValuePaddingBox || id == CSSValueBorderBox || id == CSSValueMarginBox)
- validPrimitive = true;
- else if (propId == CSSPropertyShapeInside && id == CSSValueOutsideShape)
- validPrimitive = true;
- else if (value->unit == CSSParserValue::Function)
- return parseBasicShape(propId, important);
- else if (value->unit == CSSPrimitiveValue::CSS_URI) {
- parsedValue = CSSImageValue::create(completeURL(value->string));
- m_valueList->next();
- }
- break;
- case CSSPropertyShapeMargin:
- case CSSPropertyShapePadding:
- validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FLength | FNonNeg));
- break;
- case CSSPropertyShapeImageThreshold:
- validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FNumber));
- break;
-
- case CSSPropertyTouchAction:
- // auto | none | [pan-x || pan-y]
- return parseTouchAction(important);
-
- case CSSPropertyBorderBottomStyle:
- case CSSPropertyBorderCollapse:
- case CSSPropertyBorderLeftStyle:
- case CSSPropertyBorderRightStyle:
- case CSSPropertyBorderTopStyle:
- case CSSPropertyBoxSizing:
- case CSSPropertyCaptionSide:
- case CSSPropertyClear:
- case CSSPropertyDirection:
- case CSSPropertyDisplay:
- case CSSPropertyEmptyCells:
- case CSSPropertyFloat:
- case CSSPropertyFontStyle:
- case CSSPropertyImageRendering:
- case CSSPropertyListStylePosition:
- case CSSPropertyListStyleType:
- case CSSPropertyObjectFit:
- case CSSPropertyOutlineStyle:
- case CSSPropertyOverflowWrap:
- case CSSPropertyOverflowX:
- case CSSPropertyOverflowY:
- case CSSPropertyPageBreakAfter:
- case CSSPropertyPageBreakBefore:
- case CSSPropertyPageBreakInside:
- case CSSPropertyPointerEvents:
- case CSSPropertyPosition:
- case CSSPropertyResize:
- case CSSPropertySpeak:
- case CSSPropertyTableLayout:
- case CSSPropertyTextAlignLast:
- case CSSPropertyTextJustify:
- case CSSPropertyTextLineThroughMode:
- case CSSPropertyTextLineThroughStyle:
- case CSSPropertyTextOverflow:
- case CSSPropertyTextOverlineMode:
- case CSSPropertyTextOverlineStyle:
- case CSSPropertyTextRendering:
- case CSSPropertyTextTransform:
- case CSSPropertyTextUnderlineMode:
- case CSSPropertyTextUnderlineStyle:
- case CSSPropertyTouchActionDelay:
- case CSSPropertyVariable:
- case CSSPropertyVisibility:
- case CSSPropertyWebkitAppearance:
- case CSSPropertyWebkitBackfaceVisibility:
- case CSSPropertyWebkitBorderAfterStyle:
- case CSSPropertyWebkitBorderBeforeStyle:
- case CSSPropertyWebkitBorderEndStyle:
- case CSSPropertyWebkitBorderFit:
- case CSSPropertyWebkitBorderStartStyle:
- case CSSPropertyWebkitBoxAlign:
- case CSSPropertyWebkitBoxDecorationBreak:
- case CSSPropertyWebkitBoxDirection:
- case CSSPropertyWebkitBoxLines:
- case CSSPropertyWebkitBoxOrient:
- case CSSPropertyWebkitBoxPack:
- case CSSPropertyInternalCallback:
- case CSSPropertyWebkitColumnBreakAfter:
- case CSSPropertyWebkitColumnBreakBefore:
- case CSSPropertyWebkitColumnBreakInside:
- case CSSPropertyColumnFill:
- case CSSPropertyWebkitColumnRuleStyle:
- case CSSPropertyAlignContent:
- case CSSPropertyAlignItems:
- case CSSPropertyAlignSelf:
- case CSSPropertyFlexDirection:
- case CSSPropertyFlexWrap:
- case CSSPropertyJustifyContent:
- case CSSPropertyFontKerning:
- case CSSPropertyWebkitFontSmoothing:
- case CSSPropertyGridAutoFlow:
- case CSSPropertyWebkitLineAlign:
- case CSSPropertyWebkitLineBreak:
- case CSSPropertyWebkitLineSnap:
- case CSSPropertyWebkitMarginAfterCollapse:
- case CSSPropertyWebkitMarginBeforeCollapse:
- case CSSPropertyWebkitMarginBottomCollapse:
- case CSSPropertyWebkitMarginTopCollapse:
- case CSSPropertyInternalMarqueeDirection:
- case CSSPropertyInternalMarqueeStyle:
- case CSSPropertyWebkitPrintColorAdjust:
- case CSSPropertyWebkitRegionBreakAfter:
- case CSSPropertyWebkitRegionBreakBefore:
- case CSSPropertyWebkitRegionBreakInside:
- case CSSPropertyWebkitRegionFragment:
- case CSSPropertyWebkitRtlOrdering:
- case CSSPropertyWebkitRubyPosition:
- case CSSPropertyWebkitTextCombine:
- case CSSPropertyWebkitTextEmphasisPosition:
- case CSSPropertyWebkitTextSecurity:
- case CSSPropertyWebkitTransformStyle:
- case CSSPropertyWebkitUserDrag:
- case CSSPropertyWebkitUserModify:
- case CSSPropertyWebkitUserSelect:
- case CSSPropertyWebkitWrapFlow:
- case CSSPropertyWebkitWrapThrough:
- case CSSPropertyWebkitWritingMode:
- case CSSPropertyWhiteSpace:
- case CSSPropertyWordBreak:
- case CSSPropertyWordWrap:
- case CSSPropertyMixBlendMode:
- case CSSPropertyIsolation:
- // These properties should be handled before in isValidKeywordPropertyAndValue().
- ASSERT_NOT_REACHED();
- return false;
- // Properties below are validated inside parseViewportProperty, because we
- // check for parser state. We need to invalidate if someone adds them outside
- // a @viewport rule.
- case CSSPropertyMaxZoom:
- case CSSPropertyMinZoom:
- case CSSPropertyOrientation:
- case CSSPropertyUserZoom:
- validPrimitive = false;
- break;
- default:
- return parseSVGValue(propId, important);
- }
-
- if (validPrimitive) {
- parsedValue = parseValidPrimitive(id, value);
- m_valueList->next();
- }
- ASSERT(!m_parsedCalculation);
- if (parsedValue) {
- if (!m_valueList->current() || inShorthand()) {
- addProperty(propId, parsedValue.release(), important);
- return true;
- }
- }
- return false;
-}
-
-void CSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
-{
- if (lval) {
- if (lval->isBaseValueList())
- toCSSValueList(lval.get())->append(rval);
- else {
- PassRefPtr<CSSValue> oldlVal(lval.release());
- PassRefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- list->append(oldlVal);
- list->append(rval);
- lval = list;
- }
- }
- else
- lval = rval;
-}
-
-static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue)
-{
- if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox
- || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) {
- cssValue = cssValuePool().createIdentifierValue(parserValue->id);
- return true;
- }
- return false;
-}
-
-bool CSSParser::useLegacyBackgroundSizeShorthandBehavior() const
-{
- return m_context.useLegacyBackgroundSizeShorthandBehavior();
-}
-
-const int cMaxFillProperties = 9;
-
-bool CSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* properties, int numProperties, bool important)
-{
- ASSERT(numProperties <= cMaxFillProperties);
- if (numProperties > cMaxFillProperties)
- return false;
-
- ShorthandScope scope(this, propId);
-
- bool parsedProperty[cMaxFillProperties] = { false };
- RefPtr<CSSValue> values[cMaxFillProperties];
- RefPtr<CSSValue> clipValue;
- RefPtr<CSSValue> positionYValue;
- RefPtr<CSSValue> repeatYValue;
- bool foundClip = false;
- int i;
- bool foundPositionCSSProperty = false;
-
- while (m_valueList->current()) {
- CSSParserValue* val = m_valueList->current();
- if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
- // We hit the end. Fill in all remaining values with the initial value.
- m_valueList->next();
- for (i = 0; i < numProperties; ++i) {
- if (properties[i] == CSSPropertyBackgroundColor && parsedProperty[i])
- // Color is not allowed except as the last item in a list for backgrounds.
- // Reject the entire property.
- return false;
-
- if (!parsedProperty[i] && properties[i] != CSSPropertyBackgroundColor) {
- addFillValue(values[i], cssValuePool().createImplicitInitialValue());
- if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
- addFillValue(positionYValue, cssValuePool().createImplicitInitialValue());
- if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
- addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue());
- if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) && !parsedProperty[i]) {
- // If background-origin wasn't present, then reset background-clip also.
- addFillValue(clipValue, cssValuePool().createImplicitInitialValue());
- }
- }
- parsedProperty[i] = false;
- }
- if (!m_valueList->current())
- break;
- }
-
- bool sizeCSSPropertyExpected = false;
- if (isForwardSlashOperator(val) && foundPositionCSSProperty) {
- sizeCSSPropertyExpected = true;
- m_valueList->next();
- }
-
- foundPositionCSSProperty = false;
- bool found = false;
- for (i = 0; !found && i < numProperties; ++i) {
-
- if (sizeCSSPropertyExpected && (properties[i] != CSSPropertyBackgroundSize && properties[i] != CSSPropertyWebkitMaskSize))
- continue;
- if (!sizeCSSPropertyExpected && (properties[i] == CSSPropertyBackgroundSize || properties[i] == CSSPropertyWebkitMaskSize))
- continue;
-
- if (!parsedProperty[i]) {
- RefPtr<CSSValue> val1;
- RefPtr<CSSValue> val2;
- CSSPropertyID propId1, propId2;
- CSSParserValue* parserValue = m_valueList->current();
- // parseFillProperty() may modify m_implicitShorthand, so we MUST reset it
- // before EACH return below.
- if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) {
- parsedProperty[i] = found = true;
- addFillValue(values[i], val1.release());
- if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
- addFillValue(positionYValue, val2.release());
- if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
- addFillValue(repeatYValue, val2.release());
- if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
- // Reparse the value as a clip, and see if we succeed.
- if (parseBackgroundClip(parserValue, val1))
- addFillValue(clipValue, val1.release()); // The property parsed successfully.
- else
- addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
- }
- if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) {
- // Update clipValue
- addFillValue(clipValue, val1.release());
- foundClip = true;
- }
- if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
- foundPositionCSSProperty = true;
- }
- }
- }
-
- // if we didn't find at least one match, this is an
- // invalid shorthand and we have to ignore it
- if (!found) {
- m_implicitShorthand = false;
- return false;
- }
- }
-
- // Now add all of the properties we found.
- for (i = 0; i < numProperties; i++) {
- // Fill in any remaining properties with the initial value.
- if (!parsedProperty[i]) {
- addFillValue(values[i], cssValuePool().createImplicitInitialValue());
- if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
- addFillValue(positionYValue, cssValuePool().createImplicitInitialValue());
- if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
- addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue());
- if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
- // If background-origin wasn't present, then reset background-clip also.
- addFillValue(clipValue, cssValuePool().createImplicitInitialValue());
- }
- }
- if (properties[i] == CSSPropertyBackgroundPosition) {
- addProperty(CSSPropertyBackgroundPositionX, values[i].release(), important);
- // it's OK to call positionYValue.release() since we only see CSSPropertyBackgroundPosition once
- addProperty(CSSPropertyBackgroundPositionY, positionYValue.release(), important);
- } else if (properties[i] == CSSPropertyWebkitMaskPosition) {
- addProperty(CSSPropertyWebkitMaskPositionX, values[i].release(), important);
- // it's OK to call positionYValue.release() since we only see CSSPropertyWebkitMaskPosition once
- addProperty(CSSPropertyWebkitMaskPositionY, positionYValue.release(), important);
- } else if (properties[i] == CSSPropertyBackgroundRepeat) {
- addProperty(CSSPropertyBackgroundRepeatX, values[i].release(), important);
- // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
- addProperty(CSSPropertyBackgroundRepeatY, repeatYValue.release(), important);
- } else if (properties[i] == CSSPropertyWebkitMaskRepeat) {
- addProperty(CSSPropertyWebkitMaskRepeatX, values[i].release(), important);
- // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
- addProperty(CSSPropertyWebkitMaskRepeatY, repeatYValue.release(), important);
- } else if ((properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) && !foundClip)
- // Value is already set while updating origin
- continue;
- else if (properties[i] == CSSPropertyBackgroundSize && !parsedProperty[i] && useLegacyBackgroundSizeShorthandBehavior())
- continue;
- else
- addProperty(properties[i], values[i].release(), important);
-
- // Add in clip values when we hit the corresponding origin property.
- if (properties[i] == CSSPropertyBackgroundOrigin && !foundClip)
- addProperty(CSSPropertyBackgroundClip, clipValue.release(), important);
- else if (properties[i] == CSSPropertyWebkitMaskOrigin && !foundClip)
- addProperty(CSSPropertyWebkitMaskClip, clipValue.release(), important);
- }
-
- m_implicitShorthand = false;
- return true;
-}
-
-void CSSParser::storeVariableDeclaration(const CSSParserString& name, PassOwnPtr<CSSParserValueList> value, bool important)
-{
- // When CSSGrammar.y encounters an invalid declaration it passes null for the CSSParserValueList, just bail.
- if (!value)
- return;
-
- static const unsigned prefixLength = sizeof("var-") - 1;
-
- ASSERT(name.length() > prefixLength);
- AtomicString variableName = name.atomicSubstring(prefixLength, name.length() - prefixLength);
-
- StringBuilder builder;
- for (unsigned i = 0, size = value->size(); i < size; i++) {
- if (i)
- builder.append(' ');
- RefPtr<CSSValue> cssValue = value->valueAt(i)->createCSSValue();
- if (!cssValue)
- return;
- builder.append(cssValue->cssText());
- }
-
- addProperty(CSSPropertyVariable, CSSVariableValue::create(variableName, builder.toString()), important, false);
-}
-
-void CSSParser::addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
-{
- if (lval) {
- if (lval->isValueList())
- toCSSValueList(lval.get())->append(rval);
- else {
- PassRefPtr<CSSValue> oldVal(lval.release());
- PassRefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- list->append(oldVal);
- list->append(rval);
- lval = list;
- }
- }
- else
- lval = rval;
-}
-
-bool CSSParser::parseAnimationShorthand(CSSPropertyID propId, bool important)
-{
- const StylePropertyShorthand& animationProperties = parsingShorthandForProperty(propId);
- const unsigned numProperties = 8;
-
- // The list of properties in the shorthand should be the same
- // length as the list with animation name in last position, even though they are
- // in a different order.
- ASSERT(numProperties == animationProperties.length());
- ASSERT(numProperties == shorthandForProperty(propId).length());
-
- ShorthandScope scope(this, propId);
-
- bool parsedProperty[numProperties] = { false };
- AnimationParseContext context;
- RefPtr<CSSValue> values[numProperties];
-
- unsigned i;
- while (m_valueList->current()) {
- CSSParserValue* val = m_valueList->current();
- if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
- // We hit the end. Fill in all remaining values with the initial value.
- m_valueList->next();
- for (i = 0; i < numProperties; ++i) {
- if (!parsedProperty[i])
- addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
- parsedProperty[i] = false;
- }
- if (!m_valueList->current())
- break;
- context.commitFirstAnimation();
- }
-
- bool found = false;
- for (i = 0; i < numProperties; ++i) {
- if (!parsedProperty[i]) {
- RefPtr<CSSValue> val;
- if (parseAnimationProperty(animationProperties.properties()[i], val, context)) {
- parsedProperty[i] = found = true;
- addAnimationValue(values[i], val.release());
- break;
- }
- }
- }
-
- // if we didn't find at least one match, this is an
- // invalid shorthand and we have to ignore it
- if (!found)
- return false;
- }
-
- for (i = 0; i < numProperties; ++i) {
- // If we didn't find the property, set an intial value.
- if (!parsedProperty[i])
- addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
-
- addProperty(animationProperties.properties()[i], values[i].release(), important);
- }
-
- return true;
-}
-
-bool CSSParser::parseTransitionShorthand(CSSPropertyID propId, bool important)
-{
- const unsigned numProperties = 4;
- const StylePropertyShorthand& shorthand = shorthandForProperty(propId);
- ASSERT(numProperties == shorthand.length());
-
- ShorthandScope scope(this, propId);
-
- bool parsedProperty[numProperties] = { false };
- AnimationParseContext context;
- RefPtr<CSSValue> values[numProperties];
-
- unsigned i;
- while (m_valueList->current()) {
- CSSParserValue* val = m_valueList->current();
- if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
- // We hit the end. Fill in all remaining values with the initial value.
- m_valueList->next();
- for (i = 0; i < numProperties; ++i) {
- if (!parsedProperty[i])
- addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
- parsedProperty[i] = false;
- }
- if (!m_valueList->current())
- break;
- context.commitFirstAnimation();
- }
-
- bool found = false;
- for (i = 0; !found && i < numProperties; ++i) {
- if (!parsedProperty[i]) {
- RefPtr<CSSValue> val;
- if (parseAnimationProperty(shorthand.properties()[i], val, context)) {
- parsedProperty[i] = found = true;
- addAnimationValue(values[i], val.release());
- }
-
- // There are more values to process but 'none' or 'all' were already defined as the animation property, the declaration becomes invalid.
- if (!context.animationPropertyKeywordAllowed() && context.hasCommittedFirstAnimation())
- return false;
- }
- }
-
- // if we didn't find at least one match, this is an
- // invalid shorthand and we have to ignore it
- if (!found)
- return false;
- }
-
- // Fill in any remaining properties with the initial value.
- for (i = 0; i < numProperties; ++i) {
- if (!parsedProperty[i])
- addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
- }
-
- // Now add all of the properties we found.
- for (i = 0; i < numProperties; i++)
- addPropertyWithPrefixingVariant(shorthand.properties()[i], values[i].release(), important);
-
- return true;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseColumnWidth()
-{
- CSSParserValue* value = m_valueList->current();
- // Always parse lengths in strict mode here, since it would be ambiguous otherwise when used in
- // the 'columns' shorthand property.
- if (value->id == CSSValueAuto
- || (validUnit(value, FLength | FNonNeg, HTMLStandardMode) && value->fValue)) {
- RefPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
- m_valueList->next();
- return parsedValue;
- }
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseColumnCount()
-{
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueAuto
- || (!value->id && validUnit(value, FPositiveInteger, HTMLQuirksMode))) {
- RefPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
- m_valueList->next();
- return parsedValue;
- }
- return 0;
-}
-
-bool CSSParser::parseColumnsShorthand(bool important)
-{
- RefPtr <CSSValue> columnWidth;
- RefPtr <CSSValue> columnCount;
- bool hasPendingExplicitAuto = false;
-
- for (unsigned propertiesParsed = 0; CSSParserValue* value = m_valueList->current(); propertiesParsed++) {
- if (propertiesParsed >= 2)
- return false; // Too many values for this shorthand. Invalid declaration.
- if (!propertiesParsed && value->id == CSSValueAuto) {
- // 'auto' is a valid value for any of the two longhands, and at this point we
- // don't know which one(s) it is meant for. We need to see if there are other
- // values first.
- m_valueList->next();
- hasPendingExplicitAuto = true;
- } else {
- if (!columnWidth) {
- if ((columnWidth = parseColumnWidth()))
- continue;
- }
- if (!columnCount) {
- if ((columnCount = parseColumnCount()))
- continue;
- }
- // If we didn't find at least one match, this is an
- // invalid shorthand and we have to ignore it.
- return false;
- }
- }
- if (hasPendingExplicitAuto) {
- // Time to assign the previously skipped 'auto' value to a property. If both properties are
- // unassigned at this point (i.e. 'columns:auto'), it doesn't matter that much which one we
- // set (although it does make a slight difference to web-inspector). The one we don't set
- // here will get an implicit 'auto' value further down.
- if (!columnWidth) {
- columnWidth = cssValuePool().createIdentifierValue(CSSValueAuto);
- } else {
- ASSERT(!columnCount);
- columnCount = cssValuePool().createIdentifierValue(CSSValueAuto);
- }
- }
- ASSERT(columnCount || columnWidth);
-
- // Any unassigned property at this point will become implicit 'auto'.
- if (columnWidth)
- addProperty(CSSPropertyWebkitColumnWidth, columnWidth, important);
- else
- addProperty(CSSPropertyWebkitColumnWidth, cssValuePool().createIdentifierValue(CSSValueAuto), important, true /* implicit */);
- if (columnCount)
- addProperty(CSSPropertyWebkitColumnCount, columnCount, important);
- else
- addProperty(CSSPropertyWebkitColumnCount, cssValuePool().createIdentifierValue(CSSValueAuto), important, true /* implicit */);
- return true;
-}
-
-bool CSSParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthand& shorthand, bool important)
-{
- // We try to match as many properties as possible
- // We set up an array of booleans to mark which property has been found,
- // and we try to search for properties until it makes no longer any sense.
- ShorthandScope scope(this, propId);
-
- bool found = false;
- unsigned propertiesParsed = 0;
- bool propertyFound[6]= { false, false, false, false, false, false }; // 6 is enough size.
-
- while (m_valueList->current()) {
- found = false;
- for (unsigned propIndex = 0; !found && propIndex < shorthand.length(); ++propIndex) {
- if (!propertyFound[propIndex] && parseValue(shorthand.properties()[propIndex], important)) {
- propertyFound[propIndex] = found = true;
- propertiesParsed++;
- }
- }
-
- // if we didn't find at least one match, this is an
- // invalid shorthand and we have to ignore it
- if (!found)
- return false;
- }
-
- if (propertiesParsed == shorthand.length())
- return true;
-
- // Fill in any remaining properties with the initial value.
- ImplicitScope implicitScope(this, PropertyImplicit);
- const StylePropertyShorthand* const* const propertiesForInitialization = shorthand.propertiesForInitialization();
- for (unsigned i = 0; i < shorthand.length(); ++i) {
- if (propertyFound[i])
- continue;
-
- if (propertiesForInitialization) {
- const StylePropertyShorthand& initProperties = *(propertiesForInitialization[i]);
- for (unsigned propIndex = 0; propIndex < initProperties.length(); ++propIndex)
- addProperty(initProperties.properties()[propIndex], cssValuePool().createImplicitInitialValue(), important);
- } else
- addProperty(shorthand.properties()[i], cssValuePool().createImplicitInitialValue(), important);
- }
-
- return true;
-}
-
-bool CSSParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properties, bool important)
-{
- /* From the CSS 2 specs, 8.3
- * If there is only one value, it applies to all sides. If there are two values, the top and
- * bottom margins are set to the first value and the right and left margins are set to the second.
- * If there are three values, the top is set to the first value, the left and right are set to the
- * second, and the bottom is set to the third. If there are four values, they apply to the top,
- * right, bottom, and left, respectively.
- */
-
- int num = inShorthand() ? 1 : m_valueList->size();
-
- ShorthandScope scope(this, propId);
-
- // the order is top, right, bottom, left
- switch (num) {
- case 1: {
- if (!parseValue(properties[0], important))
- return false;
- CSSValue* value = m_parsedProperties.last().value();
- ImplicitScope implicitScope(this, PropertyImplicit);
- addProperty(properties[1], value, important);
- addProperty(properties[2], value, important);
- addProperty(properties[3], value, important);
- break;
- }
- case 2: {
- if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
- return false;
- CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
- ImplicitScope implicitScope(this, PropertyImplicit);
- addProperty(properties[2], value, important);
- value = m_parsedProperties[m_parsedProperties.size() - 2].value();
- addProperty(properties[3], value, important);
- break;
- }
- case 3: {
- if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important))
- return false;
- CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
- ImplicitScope implicitScope(this, PropertyImplicit);
- addProperty(properties[3], value, important);
- break;
- }
- case 4: {
- if (!parseValue(properties[0], important) || !parseValue(properties[1], important) ||
- !parseValue(properties[2], important) || !parseValue(properties[3], important))
- return false;
- break;
- }
- default: {
- return false;
- }
- }
-
- return true;
-}
-
-// auto | <identifier>
-bool CSSParser::parsePage(CSSPropertyID propId, bool important)
-{
- ASSERT(propId == CSSPropertyPage);
-
- if (m_valueList->size() != 1)
- return false;
-
- CSSParserValue* value = m_valueList->current();
- if (!value)
- return false;
-
- if (value->id == CSSValueAuto) {
- addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
- return true;
- } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) {
- addProperty(propId, createPrimitiveStringValue(value), important);
- return true;
- }
- return false;
-}
-
-// <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
-bool CSSParser::parseSize(CSSPropertyID propId, bool important)
-{
- ASSERT(propId == CSSPropertySize);
-
- if (m_valueList->size() > 2)
- return false;
-
- CSSParserValue* value = m_valueList->current();
- if (!value)
- return false;
-
- RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
-
- // First parameter.
- SizeParameterType paramType = parseSizeParameter(parsedValues.get(), value, None);
- if (paramType == None)
- return false;
-
- // Second parameter, if any.
- value = m_valueList->next();
- if (value) {
- paramType = parseSizeParameter(parsedValues.get(), value, paramType);
- if (paramType == None)
- return false;
- }
-
- addProperty(propId, parsedValues.release(), important);
- return true;
-}
-
-CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType)
-{
- switch (value->id) {
- case CSSValueAuto:
- if (prevParamType == None) {
- parsedValues->append(cssValuePool().createIdentifierValue(value->id));
- return Auto;
- }
- return None;
- case CSSValueLandscape:
- case CSSValuePortrait:
- if (prevParamType == None || prevParamType == PageSize) {
- parsedValues->append(cssValuePool().createIdentifierValue(value->id));
- return Orientation;
- }
- return None;
- case CSSValueA3:
- case CSSValueA4:
- case CSSValueA5:
- case CSSValueB4:
- case CSSValueB5:
- case CSSValueLedger:
- case CSSValueLegal:
- case CSSValueLetter:
- if (prevParamType == None || prevParamType == Orientation) {
- // Normalize to Page Size then Orientation order by prepending.
- // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (StyleResolver::applyPageSizeProperty).
- parsedValues->prepend(cssValuePool().createIdentifierValue(value->id));
- return PageSize;
- }
- return None;
- case 0:
- if (validUnit(value, FLength | FNonNeg) && (prevParamType == None || prevParamType == Length)) {
- parsedValues->append(createPrimitiveNumericValue(value));
- return Length;
- }
- return None;
- default:
- return None;
- }
-}
-
-// [ <string> <string> ]+ | inherit | none
-// inherit and none are handled in parseValue.
-bool CSSParser::parseQuotes(CSSPropertyID propId, bool important)
-{
- RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
- while (CSSParserValue* val = m_valueList->current()) {
- RefPtr<CSSValue> parsedValue;
- if (val->unit == CSSPrimitiveValue::CSS_STRING)
- parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
- else
- break;
- values->append(parsedValue.release());
- m_valueList->next();
- }
- if (values->length()) {
- addProperty(propId, values.release(), important);
- m_valueList->next();
- return true;
- }
- return false;
-}
-
-// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
-// in CSS 2.1 this got somewhat reduced:
-// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
-bool CSSParser::parseContent(CSSPropertyID propId, bool important)
-{
- RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
-
- while (CSSParserValue* val = m_valueList->current()) {
- RefPtr<CSSValue> parsedValue;
- if (val->unit == CSSPrimitiveValue::CSS_URI) {
- // url
- parsedValue = CSSImageValue::create(completeURL(val->string));
- } else if (val->unit == CSSParserValue::Function) {
- // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...)
- CSSParserValueList* args = val->function->args.get();
- if (!args)
- return false;
- if (equalIgnoringCase(val->function->name, "attr(")) {
- parsedValue = parseAttr(args);
- if (!parsedValue)
- return false;
- } else if (equalIgnoringCase(val->function->name, "counter(")) {
- parsedValue = parseCounterContent(args, false);
- if (!parsedValue)
- return false;
- } else if (equalIgnoringCase(val->function->name, "counters(")) {
- parsedValue = parseCounterContent(args, true);
- if (!parsedValue)
- return false;
- } else if (equalIgnoringCase(val->function->name, "-webkit-image-set(")) {
- parsedValue = parseImageSet(m_valueList.get());
- if (!parsedValue)
- return false;
- } else if (isGeneratedImageValue(val)) {
- if (!parseGeneratedImage(m_valueList.get(), parsedValue))
- return false;
- } else
- return false;
- } else if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
- // open-quote
- // close-quote
- // no-open-quote
- // no-close-quote
- // inherit
- // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503).
- // none
- // normal
- switch (val->id) {
- case CSSValueOpenQuote:
- case CSSValueCloseQuote:
- case CSSValueNoOpenQuote:
- case CSSValueNoCloseQuote:
- case CSSValueNone:
- case CSSValueNormal:
- parsedValue = cssValuePool().createIdentifierValue(val->id);
- default:
- break;
- }
- } else if (val->unit == CSSPrimitiveValue::CSS_STRING) {
- parsedValue = createPrimitiveStringValue(val);
- }
- if (!parsedValue)
- break;
- values->append(parsedValue.release());
- m_valueList->next();
- }
-
- if (values->length()) {
- addProperty(propId, values.release(), important);
- m_valueList->next();
- return true;
- }
-
- return false;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList* args)
-{
- if (args->size() != 1)
- return 0;
-
- CSSParserValue* a = args->current();
-
- if (a->unit != CSSPrimitiveValue::CSS_IDENT)
- return 0;
-
- String attrName = a->string;
- // CSS allows identifiers with "-" at the start, like "-webkit-mask-image".
- // But HTML attribute names can't have those characters, and we should not
- // even parse them inside attr().
- if (attrName[0] == '-')
- return 0;
-
- if (m_context.isHTMLDocument())
- attrName = attrName.lower();
-
- return cssValuePool().createValue(attrName, CSSPrimitiveValue::CSS_ATTR);
-}
-
-PassRefPtr<CSSValue> CSSParser::parseBackgroundColor()
-{
- CSSValueID id = m_valueList->current()->id;
- if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor ||
- (id >= CSSValueGrey && id < CSSValueWebkitText && inQuirksMode()))
- return cssValuePool().createIdentifierValue(id);
- return parseColor();
-}
-
-bool CSSParser::parseFillImage(CSSParserValueList* valueList, RefPtr<CSSValue>& value)
-{
- if (valueList->current()->id == CSSValueNone) {
- value = cssValuePool().createIdentifierValue(CSSValueNone);
- return true;
- }
- if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) {
- value = CSSImageValue::create(completeURL(valueList->current()->string));
- return true;
- }
-
- if (isGeneratedImageValue(valueList->current()))
- return parseGeneratedImage(valueList, value);
-
- if (valueList->current()->unit == CSSParserValue::Function && equalIgnoringCase(valueList->current()->function->name, "-webkit-image-set(")) {
- value = parseImageSet(m_valueList.get());
- if (value)
- return true;
- }
-
- return false;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseFillPositionX(CSSParserValueList* valueList)
-{
- int id = valueList->current()->id;
- if (id == CSSValueLeft || id == CSSValueRight || id == CSSValueCenter) {
- int percent = 0;
- if (id == CSSValueRight)
- percent = 100;
- else if (id == CSSValueCenter)
- percent = 50;
- return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
- }
- if (validUnit(valueList->current(), FPercent | FLength))
- return createPrimitiveNumericValue(valueList->current());
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseFillPositionY(CSSParserValueList* valueList)
-{
- int id = valueList->current()->id;
- if (id == CSSValueTop || id == CSSValueBottom || id == CSSValueCenter) {
- int percent = 0;
- if (id == CSSValueBottom)
- percent = 100;
- else if (id == CSSValueCenter)
- percent = 50;
- return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
- }
- if (validUnit(valueList->current(), FPercent | FLength))
- return createPrimitiveNumericValue(valueList->current());
- return 0;
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSParser::parseFillPositionComponent(CSSParserValueList* valueList, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode parsingMode)
-{
- CSSValueID id = valueList->current()->id;
- if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) {
- int percent = 0;
- if (id == CSSValueLeft || id == CSSValueRight) {
- if (cumulativeFlags & XFillPosition)
- return 0;
- cumulativeFlags |= XFillPosition;
- individualFlag = XFillPosition;
- if (id == CSSValueRight)
- percent = 100;
- }
- else if (id == CSSValueTop || id == CSSValueBottom) {
- if (cumulativeFlags & YFillPosition)
- return 0;
- cumulativeFlags |= YFillPosition;
- individualFlag = YFillPosition;
- if (id == CSSValueBottom)
- percent = 100;
- } else if (id == CSSValueCenter) {
- // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
- percent = 50;
- cumulativeFlags |= AmbiguousFillPosition;
- individualFlag = AmbiguousFillPosition;
- }
-
- if (parsingMode == ResolveValuesAsKeyword)
- return cssValuePool().createIdentifierValue(id);
-
- return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
- }
- if (validUnit(valueList->current(), FPercent | FLength)) {
- if (!cumulativeFlags) {
- cumulativeFlags |= XFillPosition;
- individualFlag = XFillPosition;
- } else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) {
- cumulativeFlags |= YFillPosition;
- individualFlag = YFillPosition;
- } else {
- if (m_parsedCalculation)
- m_parsedCalculation.release();
- return 0;
- }
- return createPrimitiveNumericValue(valueList->current());
- }
- return 0;
-}
-
-static bool isValueConflictingWithCurrentEdge(int value1, int value2)
-{
- if ((value1 == CSSValueLeft || value1 == CSSValueRight) && (value2 == CSSValueLeft || value2 == CSSValueRight))
- return true;
-
- if ((value1 == CSSValueTop || value1 == CSSValueBottom) && (value2 == CSSValueTop || value2 == CSSValueBottom))
- return true;
-
- return false;
-}
-
-static bool isFillPositionKeyword(CSSValueID value)
-{
- return value == CSSValueLeft || value == CSSValueTop || value == CSSValueBottom || value == CSSValueRight || value == CSSValueCenter;
-}
-
-void CSSParser::parse4ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, PassRefPtr<CSSPrimitiveValue> parsedValue1, PassRefPtr<CSSPrimitiveValue> parsedValue2)
-{
- // [ left | right ] [ <percentage] | <length> ] && [ top | bottom ] [ <percentage> | <length> ]
- // In the case of 4 values <position> requires the second value to be a length or a percentage.
- if (isFillPositionKeyword(parsedValue2->getValueID()))
- return;
-
- unsigned cumulativeFlags = 0;
- FillPositionFlag value3Flag = InvalidFillPosition;
- RefPtr<CSSPrimitiveValue> value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
- if (!value3)
- return;
-
- CSSValueID ident1 = parsedValue1->getValueID();
- CSSValueID ident3 = value3->getValueID();
-
- if (ident1 == CSSValueCenter)
- return;
-
- if (!isFillPositionKeyword(ident3) || ident3 == CSSValueCenter)
- return;
-
- // We need to check if the values are not conflicting, e.g. they are not on the same edge. It is
- // needed as the second call to parseFillPositionComponent was on purpose not checking it. In the
- // case of two values top 20px is invalid but in the case of 4 values it becomes valid.
- if (isValueConflictingWithCurrentEdge(ident1, ident3))
- return;
-
- valueList->next();
-
- cumulativeFlags = 0;
- FillPositionFlag value4Flag = InvalidFillPosition;
- RefPtr<CSSPrimitiveValue> value4 = parseFillPositionComponent(valueList, cumulativeFlags, value4Flag, ResolveValuesAsKeyword);
- if (!value4)
- return;
-
- // 4th value must be a length or a percentage.
- if (isFillPositionKeyword(value4->getValueID()))
- return;
-
- value1 = createPrimitiveValuePair(parsedValue1, parsedValue2);
- value2 = createPrimitiveValuePair(value3, value4);
-
- if (ident1 == CSSValueTop || ident1 == CSSValueBottom)
- value1.swap(value2);
-
- valueList->next();
-}
-void CSSParser::parse3ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, PassRefPtr<CSSPrimitiveValue> parsedValue1, PassRefPtr<CSSPrimitiveValue> parsedValue2)
-{
- unsigned cumulativeFlags = 0;
- FillPositionFlag value3Flag = InvalidFillPosition;
- RefPtr<CSSPrimitiveValue> value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
-
- // value3 is not an expected value, we return.
- if (!value3)
- return;
-
- valueList->next();
-
- bool swapNeeded = false;
- CSSValueID ident1 = parsedValue1->getValueID();
- CSSValueID ident2 = parsedValue2->getValueID();
- CSSValueID ident3 = value3->getValueID();
-
- CSSValueID firstPositionKeyword;
- CSSValueID secondPositionKeyword;
-
- if (ident1 == CSSValueCenter) {
- // <position> requires the first 'center' to be followed by a keyword.
- if (!isFillPositionKeyword(ident2))
- return;
-
- // If 'center' is the first keyword then the last one needs to be a length.
- if (isFillPositionKeyword(ident3))
- return;
-
- firstPositionKeyword = CSSValueLeft;
- if (ident2 == CSSValueLeft || ident2 == CSSValueRight) {
- firstPositionKeyword = CSSValueTop;
- swapNeeded = true;
- }
- value1 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(firstPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
- value2 = createPrimitiveValuePair(parsedValue2, value3);
- } else if (ident3 == CSSValueCenter) {
- if (isFillPositionKeyword(ident2))
- return;
-
- secondPositionKeyword = CSSValueTop;
- if (ident1 == CSSValueTop || ident1 == CSSValueBottom) {
- secondPositionKeyword = CSSValueLeft;
- swapNeeded = true;
- }
- value1 = createPrimitiveValuePair(parsedValue1, parsedValue2);
- value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
- } else {
- RefPtr<CSSPrimitiveValue> firstPositionValue;
- RefPtr<CSSPrimitiveValue> secondPositionValue;
-
- if (isFillPositionKeyword(ident2)) {
- // To match CSS grammar, we should only accept: [ center | left | right | bottom | top ] [ left | right | top | bottom ] [ <percentage> | <length> ].
- ASSERT(ident2 != CSSValueCenter);
-
- if (isFillPositionKeyword(ident3))
- return;
-
- secondPositionValue = value3;
- secondPositionKeyword = ident2;
- firstPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
- } else {
- // Per CSS, we should only accept: [ right | left | top | bottom ] [ <percentage> | <length> ] [ center | left | right | bottom | top ].
- if (!isFillPositionKeyword(ident3))
- return;
-
- firstPositionValue = parsedValue2;
- secondPositionKeyword = ident3;
- secondPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
- }
-
- if (isValueConflictingWithCurrentEdge(ident1, secondPositionKeyword))
- return;
-
- value1 = createPrimitiveValuePair(parsedValue1, firstPositionValue);
- value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), secondPositionValue);
- }
-
- if (ident1 == CSSValueTop || ident1 == CSSValueBottom || swapNeeded)
- value1.swap(value2);
-
-#ifndef NDEBUG
- CSSPrimitiveValue* first = toCSSPrimitiveValue(value1.get());
- CSSPrimitiveValue* second = toCSSPrimitiveValue(value2.get());
- ident1 = first->getPairValue()->first()->getValueID();
- ident2 = second->getPairValue()->first()->getValueID();
- ASSERT(ident1 == CSSValueLeft || ident1 == CSSValueRight);
- ASSERT(ident2 == CSSValueBottom || ident2 == CSSValueTop);
-#endif
-}
-
-inline bool CSSParser::isPotentialPositionValue(CSSParserValue* value)
-{
- return isFillPositionKeyword(value->id) || validUnit(value, FPercent | FLength, ReleaseParsedCalcValue);
-}
-
-void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
-{
- unsigned numberOfValues = 0;
- for (unsigned i = valueList->currentIndex(); i < valueList->size(); ++i, ++numberOfValues) {
- CSSParserValue* current = valueList->valueAt(i);
- if (isComma(current) || !current || isForwardSlashOperator(current) || !isPotentialPositionValue(current))
- break;
- }
-
- if (numberOfValues > 4)
- return;
-
- // If we are parsing two values, we can safely call the CSS 2.1 parsing function and return.
- if (numberOfValues <= 2) {
- parse2ValuesFillPosition(valueList, value1, value2);
- return;
- }
-
- ASSERT(numberOfValues > 2 && numberOfValues <= 4);
-
- CSSParserValue* value = valueList->current();
-
- // <position> requires the first value to be a background keyword.
- if (!isFillPositionKeyword(value->id))
- return;
-
- // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
- unsigned cumulativeFlags = 0;
- FillPositionFlag value1Flag = InvalidFillPosition;
- FillPositionFlag value2Flag = InvalidFillPosition;
- value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag, ResolveValuesAsKeyword);
- if (!value1)
- return;
-
- value = valueList->next();
-
- // In case we are parsing more than two values, relax the check inside of parseFillPositionComponent. top 20px is
- // a valid start for <position>.
- cumulativeFlags = AmbiguousFillPosition;
- value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag, ResolveValuesAsKeyword);
- if (value2)
- valueList->next();
- else {
- value1.clear();
- return;
- }
-
- RefPtr<CSSPrimitiveValue> parsedValue1 = toCSSPrimitiveValue(value1.get());
- RefPtr<CSSPrimitiveValue> parsedValue2 = toCSSPrimitiveValue(value2.get());
-
- value1.clear();
- value2.clear();
-
- // Per CSS3 syntax, <position> can't have 'center' as its second keyword as we have more arguments to follow.
- if (parsedValue2->getValueID() == CSSValueCenter)
- return;
-
- if (numberOfValues == 3)
- parse3ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release());
- else
- parse4ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release());
-}
-
-void CSSParser::parse2ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
-{
- CSSParserValue* value = valueList->current();
-
- // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
- unsigned cumulativeFlags = 0;
- FillPositionFlag value1Flag = InvalidFillPosition;
- FillPositionFlag value2Flag = InvalidFillPosition;
- value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag);
- if (!value1)
- return;
-
- // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
- // can assume that any other values belong to the rest of the shorthand). If we're not parsing a shorthand, though, the
- // value was explicitly specified for our property.
- value = valueList->next();
-
- // First check for the comma. If so, we are finished parsing this value or value pair.
- if (isComma(value))
- value = 0;
-
- if (value) {
- value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag);
- if (value2)
- valueList->next();
- else {
- if (!inShorthand()) {
- value1.clear();
- return;
- }
- }
- }
-
- if (!value2)
- // Only one value was specified. If that value was not a keyword, then it sets the x position, and the y position
- // is simply 50%. This is our default.
- // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
- // For left/right/center, the default of 50% in the y is still correct.
- value2 = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
-
- if (value1Flag == YFillPosition || value2Flag == XFillPosition)
- value1.swap(value2);
-}
-
-void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
-{
- CSSValueID id = m_valueList->current()->id;
- if (id == CSSValueRepeatX) {
- m_implicitShorthand = true;
- value1 = cssValuePool().createIdentifierValue(CSSValueRepeat);
- value2 = cssValuePool().createIdentifierValue(CSSValueNoRepeat);
- m_valueList->next();
- return;
- }
- if (id == CSSValueRepeatY) {
- m_implicitShorthand = true;
- value1 = cssValuePool().createIdentifierValue(CSSValueNoRepeat);
- value2 = cssValuePool().createIdentifierValue(CSSValueRepeat);
- m_valueList->next();
- return;
- }
- if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
- value1 = cssValuePool().createIdentifierValue(id);
- else {
- value1 = 0;
- return;
- }
-
- CSSParserValue* value = m_valueList->next();
-
- // Parse the second value if one is available
- if (value && !isComma(value)) {
- id = value->id;
- if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) {
- value2 = cssValuePool().createIdentifierValue(id);
- m_valueList->next();
- return;
- }
- }
-
- // If only one value was specified, value2 is the same as value1.
- m_implicitShorthand = true;
- value2 = cssValuePool().createIdentifierValue(toCSSPrimitiveValue(value1.get())->getValueID());
-}
-
-PassRefPtr<CSSValue> CSSParser::parseFillSize(CSSPropertyID propId, bool& allowComma)
-{
- allowComma = true;
- CSSParserValue* value = m_valueList->current();
-
- if (value->id == CSSValueContain || value->id == CSSValueCover)
- return cssValuePool().createIdentifierValue(value->id);
-
- RefPtr<CSSPrimitiveValue> parsedValue1;
-
- if (value->id == CSSValueAuto)
- parsedValue1 = cssValuePool().createIdentifierValue(CSSValueAuto);
- else {
- if (!validUnit(value, FLength | FPercent))
- return 0;
- parsedValue1 = createPrimitiveNumericValue(value);
- }
-
- RefPtr<CSSPrimitiveValue> parsedValue2;
- if ((value = m_valueList->next())) {
- if (value->unit == CSSParserValue::Operator && value->iValue == ',')
- allowComma = false;
- else if (value->id != CSSValueAuto) {
- if (!validUnit(value, FLength | FPercent)) {
- if (!inShorthand())
- return 0;
- // We need to rewind the value list, so that when it is advanced we'll end up back at this value.
- m_valueList->previous();
- } else
- parsedValue2 = createPrimitiveNumericValue(value);
- }
- } else if (!parsedValue2 && propId == CSSPropertyWebkitBackgroundSize) {
- // For backwards compatibility we set the second value to the first if it is omitted.
- // We only need to do this for -webkit-background-size. It should be safe to let masks match
- // the real property.
- parsedValue2 = parsedValue1;
- }
-
- if (!parsedValue2)
- return parsedValue1;
- return createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release());
-}
-
-bool CSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2,
- RefPtr<CSSValue>& retValue1, RefPtr<CSSValue>& retValue2)
-{
- RefPtr<CSSValueList> values;
- RefPtr<CSSValueList> values2;
- CSSParserValue* val;
- RefPtr<CSSValue> value;
- RefPtr<CSSValue> value2;
-
- bool allowComma = false;
-
- retValue1 = retValue2 = 0;
- propId1 = propId;
- propId2 = propId;
- if (propId == CSSPropertyBackgroundPosition) {
- propId1 = CSSPropertyBackgroundPositionX;
- propId2 = CSSPropertyBackgroundPositionY;
- } else if (propId == CSSPropertyWebkitMaskPosition) {
- propId1 = CSSPropertyWebkitMaskPositionX;
- propId2 = CSSPropertyWebkitMaskPositionY;
- } else if (propId == CSSPropertyBackgroundRepeat) {
- propId1 = CSSPropertyBackgroundRepeatX;
- propId2 = CSSPropertyBackgroundRepeatY;
- } else if (propId == CSSPropertyWebkitMaskRepeat) {
- propId1 = CSSPropertyWebkitMaskRepeatX;
- propId2 = CSSPropertyWebkitMaskRepeatY;
- }
-
- while ((val = m_valueList->current())) {
- RefPtr<CSSValue> currValue;
- RefPtr<CSSValue> currValue2;
-
- if (allowComma) {
- if (!isComma(val))
- return false;
- m_valueList->next();
- allowComma = false;
- } else {
- allowComma = true;
- switch (propId) {
- case CSSPropertyBackgroundColor:
- currValue = parseBackgroundColor();
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyBackgroundAttachment:
- if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) {
- currValue = cssValuePool().createIdentifierValue(val->id);
- m_valueList->next();
- }
- break;
- case CSSPropertyBackgroundImage:
- case CSSPropertyWebkitMaskImage:
- if (parseFillImage(m_valueList.get(), currValue))
- m_valueList->next();
- break;
- case CSSPropertyWebkitBackgroundClip:
- case CSSPropertyWebkitBackgroundOrigin:
- case CSSPropertyWebkitMaskClip:
- case CSSPropertyWebkitMaskOrigin:
- // The first three values here are deprecated and do not apply to the version of the property that has
- // the -webkit- prefix removed.
- if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent ||
- val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox ||
- ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) &&
- (val->id == CSSValueText || val->id == CSSValueWebkitText))) {
- currValue = cssValuePool().createIdentifierValue(val->id);
- m_valueList->next();
- }
- break;
- case CSSPropertyBackgroundClip:
- if (parseBackgroundClip(val, currValue))
- m_valueList->next();
- break;
- case CSSPropertyBackgroundOrigin:
- if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) {
- currValue = cssValuePool().createIdentifierValue(val->id);
- m_valueList->next();
- }
- break;
- case CSSPropertyBackgroundPosition:
- case CSSPropertyWebkitMaskPosition:
- parseFillPosition(m_valueList.get(), currValue, currValue2);
- // parseFillPosition advances the m_valueList pointer.
- break;
- case CSSPropertyBackgroundPositionX:
- case CSSPropertyWebkitMaskPositionX: {
- currValue = parseFillPositionX(m_valueList.get());
- if (currValue)
- m_valueList->next();
- break;
- }
- case CSSPropertyBackgroundPositionY:
- case CSSPropertyWebkitMaskPositionY: {
- currValue = parseFillPositionY(m_valueList.get());
- if (currValue)
- m_valueList->next();
- break;
- }
- case CSSPropertyWebkitBackgroundComposite:
- case CSSPropertyWebkitMaskComposite:
- if (val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) {
- currValue = cssValuePool().createIdentifierValue(val->id);
- m_valueList->next();
- }
- break;
- case CSSPropertyBackgroundBlendMode:
- if (RuntimeEnabledFeatures::cssCompositingEnabled() && (val->id == CSSValueNormal || val->id == CSSValueMultiply
- || val->id == CSSValueScreen || val->id == CSSValueOverlay || val->id == CSSValueDarken
- || val->id == CSSValueLighten || val->id == CSSValueColorDodge || val->id == CSSValueColorBurn
- || val->id == CSSValueHardLight || val->id == CSSValueSoftLight || val->id == CSSValueDifference
- || val->id == CSSValueExclusion || val->id == CSSValueHue || val->id == CSSValueSaturation
- || val->id == CSSValueColor || val->id == CSSValueLuminosity)) {
- currValue = cssValuePool().createIdentifierValue(val->id);
- m_valueList->next();
- }
- break;
- case CSSPropertyBackgroundRepeat:
- case CSSPropertyWebkitMaskRepeat:
- parseFillRepeat(currValue, currValue2);
- // parseFillRepeat advances the m_valueList pointer
- break;
- case CSSPropertyBackgroundSize:
- case CSSPropertyWebkitBackgroundSize:
- case CSSPropertyWebkitMaskSize: {
- currValue = parseFillSize(propId, allowComma);
- if (currValue)
- m_valueList->next();
- break;
- }
- case CSSPropertyMaskSourceType: {
- if (RuntimeEnabledFeatures::cssMaskSourceTypeEnabled()) {
- if (val->id == CSSValueAuto || val->id == CSSValueAlpha || val->id == CSSValueLuminance) {
- currValue = cssValuePool().createIdentifierValue(val->id);
- m_valueList->next();
- } else {
- currValue = 0;
- }
- }
- break;
- }
- default:
- break;
- }
- if (!currValue)
- return false;
-
- if (value && !values) {
- values = CSSValueList::createCommaSeparated();
- values->append(value.release());
- }
-
- if (value2 && !values2) {
- values2 = CSSValueList::createCommaSeparated();
- values2->append(value2.release());
- }
-
- if (values)
- values->append(currValue.release());
- else
- value = currValue.release();
- if (currValue2) {
- if (values2)
- values2->append(currValue2.release());
- else
- value2 = currValue2.release();
- }
- }
-
- // When parsing any fill shorthand property, we let it handle building up the lists for all
- // properties.
- if (inShorthand())
- break;
- }
-
- if (values && values->length()) {
- retValue1 = values.release();
- if (values2 && values2->length())
- retValue2 = values2.release();
- return true;
- }
- if (value) {
- retValue1 = value.release();
- retValue2 = value2.release();
- return true;
- }
- return false;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationDelay()
-{
- CSSParserValue* value = m_valueList->current();
- if (validUnit(value, FTime))
- return createPrimitiveNumericValue(value);
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationDirection()
-{
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueNormal || value->id == CSSValueAlternate || value->id == CSSValueReverse || value->id == CSSValueAlternateReverse)
- return cssValuePool().createIdentifierValue(value->id);
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationDuration()
-{
- CSSParserValue* value = m_valueList->current();
- if (validUnit(value, FTime | FNonNeg))
- return createPrimitiveNumericValue(value);
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationFillMode()
-{
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth)
- return cssValuePool().createIdentifierValue(value->id);
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationIterationCount()
-{
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueInfinite)
- return cssValuePool().createIdentifierValue(value->id);
- if (validUnit(value, FNumber | FNonNeg))
- return createPrimitiveNumericValue(value);
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationName()
-{
- CSSParserValue* value = m_valueList->current();
- if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) {
- if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value, "none"))) {
- return cssValuePool().createIdentifierValue(CSSValueNone);
- } else {
- return createPrimitiveStringValue(value);
- }
- }
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState()
-{
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueRunning || value->id == CSSValuePaused)
- return cssValuePool().createIdentifierValue(value->id);
- return 0;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationProperty(AnimationParseContext& context)
-{
- CSSParserValue* value = m_valueList->current();
- if (value->unit != CSSPrimitiveValue::CSS_IDENT)
- return 0;
- CSSPropertyID result = cssPropertyID(value->string);
- if (result)
- return cssValuePool().createIdentifierValue(result);
- if (equalIgnoringCase(value, "all")) {
- context.sawAnimationPropertyKeyword();
- return cssValuePool().createIdentifierValue(CSSValueAll);
- }
- if (equalIgnoringCase(value, "none")) {
- context.commitAnimationPropertyKeyword();
- context.sawAnimationPropertyKeyword();
- return cssValuePool().createIdentifierValue(CSSValueNone);
- }
- return 0;
-}
-
-bool CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3)
-{
- parse2ValuesFillPosition(m_valueList.get(), value1, value2);
-
- // now get z
- if (m_valueList->current()) {
- if (validUnit(m_valueList->current(), FLength)) {
- value3 = createPrimitiveNumericValue(m_valueList->current());
- m_valueList->next();
- return true;
- }
- return false;
- }
- value3 = cssValuePool().createImplicitInitialValue();
- return true;
-}
-
-bool CSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result)
-{
- CSSParserValue* v = args->current();
- if (!validUnit(v, FNumber))
- return false;
- result = v->fValue;
- v = args->next();
- if (!v)
- // The last number in the function has no comma after it, so we're done.
- return true;
- if (!isComma(v))
- return false;
- args->next();
- return true;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction()
-{
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut
- || value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd)
- return cssValuePool().createIdentifierValue(value->id);
-
- // We must be a function.
- if (value->unit != CSSParserValue::Function)
- return 0;
-
- CSSParserValueList* args = value->function->args.get();
-
- if (equalIgnoringCase(value->function->name, "steps(")) {
- // For steps, 1 or 2 params must be specified (comma-separated)
- if (!args || (args->size() != 1 && args->size() != 3))
- return 0;
-
- // There are two values.
- int numSteps;
- bool stepAtStart = false;
-
- CSSParserValue* v = args->current();
- if (!validUnit(v, FInteger))
- return 0;
- numSteps = clampToInteger(v->fValue);
- if (numSteps < 1)
- return 0;
- v = args->next();
-
- if (v) {
- // There is a comma so we need to parse the second value
- if (!isComma(v))
- return 0;
- v = args->next();
- if (v->id != CSSValueStart && v->id != CSSValueEnd)
- return 0;
- stepAtStart = v->id == CSSValueStart;
- }
-
- return CSSStepsTimingFunctionValue::create(numSteps, stepAtStart);
- }
-
- if (equalIgnoringCase(value->function->name, "cubic-bezier(")) {
- // For cubic bezier, 4 values must be specified.
- if (!args || args->size() != 7)
- return 0;
-
- // There are two points specified. The x values must be between 0 and 1 but the y values can exceed this range.
- double x1, y1, x2, y2;
-
- if (!parseCubicBezierTimingFunctionValue(args, x1))
- return 0;
- if (x1 < 0 || x1 > 1)
- return 0;
- if (!parseCubicBezierTimingFunctionValue(args, y1))
- return 0;
- if (!parseCubicBezierTimingFunctionValue(args, x2))
- return 0;
- if (x2 < 0 || x2 > 1)
- return 0;
- if (!parseCubicBezierTimingFunctionValue(args, y2))
- return 0;
-
- return CSSCubicBezierTimingFunctionValue::create(x1, y1, x2, y2);
- }
-
- return 0;
-}
-
-bool CSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr<CSSValue>& result, AnimationParseContext& context)
-{
- RefPtr<CSSValueList> values;
- CSSParserValue* val;
- RefPtr<CSSValue> value;
- bool allowComma = false;
-
- result = 0;
-
- while ((val = m_valueList->current())) {
- RefPtr<CSSValue> currValue;
- if (allowComma) {
- if (!isComma(val))
- return false;
- m_valueList->next();
- allowComma = false;
- }
- else {
- switch (propId) {
- case CSSPropertyAnimationDelay:
- case CSSPropertyWebkitAnimationDelay:
- case CSSPropertyTransitionDelay:
- case CSSPropertyWebkitTransitionDelay:
- currValue = parseAnimationDelay();
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyAnimationDirection:
- case CSSPropertyWebkitAnimationDirection:
- currValue = parseAnimationDirection();
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyAnimationDuration:
- case CSSPropertyWebkitAnimationDuration:
- case CSSPropertyTransitionDuration:
- case CSSPropertyWebkitTransitionDuration:
- currValue = parseAnimationDuration();
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyAnimationFillMode:
- case CSSPropertyWebkitAnimationFillMode:
- currValue = parseAnimationFillMode();
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyAnimationIterationCount:
- case CSSPropertyWebkitAnimationIterationCount:
- currValue = parseAnimationIterationCount();
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyAnimationName:
- case CSSPropertyWebkitAnimationName:
- currValue = parseAnimationName();
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyAnimationPlayState:
- case CSSPropertyWebkitAnimationPlayState:
- currValue = parseAnimationPlayState();
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyTransitionProperty:
- case CSSPropertyWebkitTransitionProperty:
- currValue = parseAnimationProperty(context);
- if (value && !context.animationPropertyKeywordAllowed())
- return false;
- if (currValue)
- m_valueList->next();
- break;
- case CSSPropertyAnimationTimingFunction:
- case CSSPropertyWebkitAnimationTimingFunction:
- case CSSPropertyTransitionTimingFunction:
- case CSSPropertyWebkitTransitionTimingFunction:
- currValue = parseAnimationTimingFunction();
- if (currValue)
- m_valueList->next();
- break;
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
-
- if (!currValue)
- return false;
-
- if (value && !values) {
- values = CSSValueList::createCommaSeparated();
- values->append(value.release());
- }
-
- if (values)
- values->append(currValue.release());
- else
- value = currValue.release();
-
- allowComma = true;
- }
-
- // When parsing the 'transition' shorthand property, we let it handle building up the lists for all
- // properties.
- if (inShorthand())
- break;
- }
-
- if (values && values->length()) {
- result = values.release();
- return true;
- }
- if (value) {
- result = value.release();
- return true;
- }
- return false;
-}
-
-// The function parses [ <integer> || <string> ] in <grid-line> (which can be stand alone or with 'span').
-bool CSSParser::parseIntegerOrStringFromGridPosition(RefPtr<CSSPrimitiveValue>& numericValue, RefPtr<CSSPrimitiveValue>& gridLineName)
-{
- CSSParserValue* value = m_valueList->current();
- if (validUnit(value, FInteger) && value->fValue) {
- numericValue = createPrimitiveNumericValue(value);
- value = m_valueList->next();
- if (value && value->unit == CSSPrimitiveValue::CSS_STRING) {
- gridLineName = createPrimitiveStringValue(m_valueList->current());
- m_valueList->next();
- }
- return true;
- }
-
- if (value->unit == CSSPrimitiveValue::CSS_STRING) {
- gridLineName = createPrimitiveStringValue(m_valueList->current());
- value = m_valueList->next();
- if (value && validUnit(value, FInteger) && value->fValue) {
- numericValue = createPrimitiveNumericValue(value);
- m_valueList->next();
- }
- return true;
- }
-
- return false;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseGridPosition()
-{
- ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueAuto) {
- m_valueList->next();
- return cssValuePool().createIdentifierValue(CSSValueAuto);
- }
-
- if (value->id != CSSValueSpan && value->unit == CSSPrimitiveValue::CSS_IDENT) {
- m_valueList->next();
- return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING);
- }
-
- RefPtr<CSSPrimitiveValue> numericValue;
- RefPtr<CSSPrimitiveValue> gridLineName;
- bool hasSeenSpanKeyword = false;
-
- if (parseIntegerOrStringFromGridPosition(numericValue, gridLineName)) {
- value = m_valueList->current();
- if (value && value->id == CSSValueSpan) {
- hasSeenSpanKeyword = true;
- m_valueList->next();
- }
- } else if (value->id == CSSValueSpan) {
- hasSeenSpanKeyword = true;
- if (m_valueList->next())
- parseIntegerOrStringFromGridPosition(numericValue, gridLineName);
- }
-
- // Check that we have consumed all the value list. For shorthands, the parser will pass
- // the whole value list (including the opposite position).
- if (m_valueList->current() && !isForwardSlashOperator(m_valueList->current()))
- return 0;
-
- // If we didn't parse anything, this is not a valid grid position.
- if (!hasSeenSpanKeyword && !gridLineName && !numericValue)
- return 0;
-
- // Negative numbers are not allowed for span (but are for <integer>).
- if (hasSeenSpanKeyword && numericValue && numericValue->getIntValue() < 0)
- return 0;
-
- RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
- if (hasSeenSpanKeyword)
- values->append(cssValuePool().createIdentifierValue(CSSValueSpan));
- if (numericValue)
- values->append(numericValue.release());
- if (gridLineName)
- values->append(gridLineName.release());
- ASSERT(values->length());
- return values.release();
-}
-
-static PassRefPtr<CSSValue> gridMissingGridPositionValue(CSSValue* value)
-{
- if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->isString())
- return value;
-
- return cssValuePool().createIdentifierValue(CSSValueAuto);
-}
-
-bool CSSParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool important)
-{
- ShorthandScope scope(this, shorthandId);
- const StylePropertyShorthand& shorthand = shorthandForProperty(shorthandId);
- ASSERT(shorthand.length() == 2);
-
- RefPtr<CSSValue> startValue = parseGridPosition();
- if (!startValue)
- return false;
-
- RefPtr<CSSValue> endValue;
- if (m_valueList->current()) {
- if (!isForwardSlashOperator(m_valueList->current()))
- return false;
-
- if (!m_valueList->next())
- return false;
-
- endValue = parseGridPosition();
- if (!endValue || m_valueList->current())
- return false;
- } else {
- endValue = gridMissingGridPositionValue(startValue.get());
- }
-
- addProperty(shorthand.properties()[0], startValue, important);
- addProperty(shorthand.properties()[1], endValue, important);
- return true;
-}
-
-bool CSSParser::parseGridAreaShorthand(bool important)
-{
- ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
- ShorthandScope scope(this, CSSPropertyGridArea);
- const StylePropertyShorthand& shorthand = gridAreaShorthand();
- ASSERT_UNUSED(shorthand, shorthand.length() == 4);
-
- RefPtr<CSSValue> rowStartValue = parseGridPosition();
- if (!rowStartValue)
- return false;
-
- RefPtr<CSSValue> columnStartValue;
- if (!parseSingleGridAreaLonghand(columnStartValue))
- return false;
-
- RefPtr<CSSValue> rowEndValue;
- if (!parseSingleGridAreaLonghand(rowEndValue))
- return false;
-
- RefPtr<CSSValue> columnEndValue;
- if (!parseSingleGridAreaLonghand(columnEndValue))
- return false;
-
- if (!columnStartValue)
- columnStartValue = gridMissingGridPositionValue(rowStartValue.get());
-
- if (!rowEndValue)
- rowEndValue = gridMissingGridPositionValue(rowStartValue.get());
-
- if (!columnEndValue)
- columnEndValue = gridMissingGridPositionValue(columnStartValue.get());
-
- addProperty(CSSPropertyGridRowStart, rowStartValue, important);
- addProperty(CSSPropertyGridColumnStart, columnStartValue, important);
- addProperty(CSSPropertyGridRowEnd, rowEndValue, important);
- addProperty(CSSPropertyGridColumnEnd, columnEndValue, important);
- return true;
-}
-
-bool CSSParser::parseSingleGridAreaLonghand(RefPtr<CSSValue>& property)
-{
- if (!m_valueList->current())
- return true;
-
- if (!isForwardSlashOperator(m_valueList->current()))
- return false;
-
- if (!m_valueList->next())
- return false;
-
- property = parseGridPosition();
- return true;
-}
-
-void CSSParser::parseGridLineNames(CSSParserValueList* parserValueList, CSSValueList& valueList)
-{
- ASSERT(parserValueList->current() && parserValueList->current()->unit == CSSParserValue::ValueList);
-
- CSSParserValueList* identList = parserValueList->current()->valueList;
- if (!identList->size()) {
- parserValueList->next();
- return;
- }
-
- RefPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
- while (CSSParserValue* identValue = identList->current()) {
- ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT);
- RefPtr<CSSPrimitiveValue> lineName = createPrimitiveStringValue(identValue);
- lineNames->append(lineName.release());
- identList->next();
- }
- valueList.append(lineNames.release());
-
- parserValueList->next();
-}
-
-bool CSSParser::parseGridTrackList(CSSPropertyID propId, bool important)
-{
- ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
- CSSParserValue* value = m_valueList->current();
- if (value->id == CSSValueNone) {
- if (m_valueList->next())
- return false;
-
- addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
- return true;
- }
-
- RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
- // Handle leading <ident>*.
- value = m_valueList->current();
- if (value && value->unit == CSSParserValue::ValueList)
- parseGridLineNames(m_valueList.get(), *values);
-
- bool seenTrackSizeOrRepeatFunction = false;
- while (CSSParserValue* currentValue = m_valueList->current()) {
- if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "repeat(")) {
- if (!parseGridTrackRepeatFunction(*values))
- return false;
- seenTrackSizeOrRepeatFunction = true;
- } else {
- RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
- if (!value)
- return false;
- values->append(value);
- seenTrackSizeOrRepeatFunction = true;
- }
- // This will handle the trailing <ident>* in the grammar.
- value = m_valueList->current();
- if (value && value->unit == CSSParserValue::ValueList)
- parseGridLineNames(m_valueList.get(), *values);
- }
-
- // We should have found a <track-size> or else it is not a valid <track-list>
- if (!seenTrackSizeOrRepeatFunction)
- return false;
-
- addProperty(propId, values.release(), important);
- return true;
-}
-
-bool CSSParser::parseGridTrackRepeatFunction(CSSValueList& list)
-{
- CSSParserValueList* arguments = m_valueList->current()->function->args.get();
- if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1)))
- return false;
-
- ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0);
- size_t repetitions = arguments->valueAt(0)->fValue;
- RefPtr<CSSValueList> repeatedValues = CSSValueList::createSpaceSeparated();
- arguments->next(); // Skip the repetition count.
- arguments->next(); // Skip the comma.
-
- // Handle leading <ident>*.
- CSSParserValue* currentValue = arguments->current();
- if (currentValue && currentValue->unit == CSSParserValue::ValueList)
- parseGridLineNames(arguments, *repeatedValues);
-
- while (arguments->current()) {
- RefPtr<CSSValue> trackSize = parseGridTrackSize(*arguments);
- if (!trackSize)
- return false;
-
- repeatedValues->append(trackSize);
-
- // This takes care of any trailing <ident>* in the grammar.
- currentValue = arguments->current();
- if (currentValue && currentValue->unit == CSSParserValue::ValueList)
- parseGridLineNames(arguments, *repeatedValues);
- }
-
- for (size_t i = 0; i < repetitions; ++i) {
- for (size_t j = 0; j < repeatedValues->length(); ++j)
- list.append(repeatedValues->itemWithoutBoundsCheck(j));
- }
-
- // parseGridTrackSize iterated over the repeat arguments, move to the next value.
- m_valueList->next();
- return true;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseGridTrackSize(CSSParserValueList& inputList)
-{
- ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
- CSSParserValue* currentValue = inputList.current();
- inputList.next();
-
- if (currentValue->id == CSSValueAuto)
- return cssValuePool().createIdentifierValue(CSSValueAuto);
-
- if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "minmax(")) {
- // The spec defines the following grammar: minmax( <track-breadth> , <track-breadth> )
- CSSParserValueList* arguments = currentValue->function->args.get();
- if (!arguments || arguments->size() != 3 || !isComma(arguments->valueAt(1)))
- return 0;
-
- RefPtr<CSSPrimitiveValue> minTrackBreadth = parseGridBreadth(arguments->valueAt(0));
- if (!minTrackBreadth)
- return 0;
-
- RefPtr<CSSPrimitiveValue> maxTrackBreadth = parseGridBreadth(arguments->valueAt(2));
- if (!maxTrackBreadth)
- return 0;
-
- RefPtr<CSSValueList> parsedArguments = CSSValueList::createCommaSeparated();
- parsedArguments->append(minTrackBreadth);
- parsedArguments->append(maxTrackBreadth);
- return CSSFunctionValue::create("minmax(", parsedArguments);
- }
-
- return parseGridBreadth(currentValue);
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSParser::parseGridBreadth(CSSParserValue* currentValue)
-{
- if (currentValue->id == CSSValueMinContent || currentValue->id == CSSValueMaxContent)
- return cssValuePool().createIdentifierValue(currentValue->id);
-
- if (currentValue->unit == CSSPrimitiveValue::CSS_FR) {
- double flexValue = currentValue->fValue;
-
- // Fractional unit is a non-negative dimension.
- if (flexValue <= 0)
- return 0;
-
- return cssValuePool().createValue(flexValue, CSSPrimitiveValue::CSS_FR);
- }
-
- if (!validUnit(currentValue, FNonNeg | FLength | FPercent))
- return 0;
-
- return createPrimitiveNumericValue(currentValue);
-}
-
-PassRefPtr<CSSValue> CSSParser::parseGridTemplate()
-{
- NamedGridAreaMap gridAreaMap;
- size_t rowCount = 0;
- size_t columnCount = 0;
-
- while (CSSParserValue* currentValue = m_valueList->current()) {
- if (currentValue->unit != CSSPrimitiveValue::CSS_STRING)
- return 0;
-
- String gridRowNames = currentValue->string;
- if (!gridRowNames.length())
- return 0;
-
- Vector<String> columnNames;
- gridRowNames.split(' ', columnNames);
-
- if (!columnCount) {
- columnCount = columnNames.size();
- ASSERT(columnCount);
- } else if (columnCount != columnNames.size()) {
- // The declaration is invalid is all the rows don't have the number of columns.
- return 0;
- }
-
- for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
- const String& gridAreaName = columnNames[currentCol];
-
- // Unamed areas are always valid (we consider them to be 1x1).
- if (gridAreaName == ".")
- continue;
-
- // We handle several grid areas with the same name at once to simplify the validation code.
- size_t lookAheadCol;
- for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++lookAheadCol) {
- if (columnNames[lookAheadCol + 1] != gridAreaName)
- break;
- }
-
- NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
- if (gridAreaIt == gridAreaMap.end()) {
- gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentCol, lookAheadCol)));
- } else {
- GridCoordinate& gridCoordinate = gridAreaIt->value;
-
- // The following checks test that the grid area is a single filled-in rectangle.
- // 1. The new row is adjacent to the previously parsed row.
- if (rowCount != gridCoordinate.rows.initialPositionIndex + 1)
- return 0;
-
- // 2. The new area starts at the same position as the previously parsed area.
- if (currentCol != gridCoordinate.columns.initialPositionIndex)
- return 0;
-
- // 3. The new area ends at the same position as the previously parsed area.
- if (lookAheadCol != gridCoordinate.columns.finalPositionIndex)
- return 0;
-
- ++gridCoordinate.rows.finalPositionIndex;
- }
- currentCol = lookAheadCol;
- }
-
- ++rowCount;
- m_valueList->next();
- }
-
- if (!rowCount || !columnCount)
- return 0;
-
- return CSSGridTemplateValue::create(gridAreaMap, rowCount, columnCount);
-}
-
-PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bool counters)
-{
- unsigned numArgs = args->size();
- if (counters && numArgs != 3 && numArgs != 5)
- return 0;
- if (!counters && numArgs != 1 && numArgs != 3)
- return 0;
-
- CSSParserValue* i = args->current();
- if (i->unit != CSSPrimitiveValue::CSS_IDENT)
- return 0;
- RefPtr<CSSPrimitiveValue> identifier = createPrimitiveStringValue(i);
-
- RefPtr<CSSPrimitiveValue> separator;
- if (!counters)
- separator = cssValuePool().createValue(String(), CSSPrimitiveValue::CSS_STRING);
- else {
- i = args->next();
- if (i->unit != CSSParserValue::Operator || i->iValue != ',')
- return 0;
-
- i = args->next();
- if (i->unit != CSSPrimitiveValue::CSS_STRING)
- return 0;
-
- separator = createPrimitiveStringValue(i);
- }
-
- RefPtr<CSSPrimitiveValue> listStyle;
- i = args->next();
- if (!i) // Make the list style default decimal
- listStyle = cssValuePool().createIdentifierValue(CSSValueDecimal);
- else {
- if (i->unit != CSSParserValue::Operator || i->iValue != ',')
- return 0;
-
- i = args->next();
- if (i->unit != CSSPrimitiveValue::CSS_IDENT)
- return 0;
-
- CSSValueID listStyleID = CSSValueInvalid;
- if (i->id == CSSValueNone || (i->id >= CSSValueDisc && i->id <= CSSValueKatakanaIroha))
- listStyleID = i->id;
- else
- return 0;
-
- listStyle = cssValuePool().createIdentifierValue(listStyleID);
- }
-
- return cssValuePool().createValue(Counter::create(identifier.release(), listStyle.release(), separator.release()));
-}
-
-bool CSSParser::parseClipShape(CSSPropertyID propId, bool important)
-{
- CSSParserValue* value = m_valueList->current();
- CSSParserValueList* args = value->function->args.get();
-
- if (!equalIgnoringCase(value->function->name, "rect(") || !args)
- return false;
-
- // rect(t, r, b, l) || rect(t r b l)
- if (args->size() != 4 && args->size() != 7)
- return false;
- RefPtr<Rect> rect = Rect::create();
- bool valid = true;
- int i = 0;
- CSSParserValue* a = args->current();
- while (a) {
- valid = a->id == CSSValueAuto || validUnit(a, FLength);
- if (!valid)
- break;
- RefPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ?
- cssValuePool().createIdentifierValue(CSSValueAuto) :
- createPrimitiveNumericValue(a);
- if (i == 0)
- rect->setTop(length);
- else if (i == 1)
- rect->setRight(length);
- else if (i == 2)
- rect->setBottom(length);
- else
- rect->setLeft(length);
- a = args->next();
- if (a && args->size() == 7) {
- if (a->unit == CSSParserValue::Operator && a->iValue == ',') {
- a = args->next();
- } else {
- valid = false;
- break;
- }
- }
- i++;
- }
- if (valid) {
- addProperty(propId, cssValuePool().createValue(rect.release()), important);
- m_valueList->next();
- return true;
- }
- return false;
-}
-
-PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeRectangle(CSSParserValueList* args)
-{
- ASSERT(args);
-
- // rect(x, y, width, height, [[rx], ry])
- if (args->size() != 7 && args->size() != 9 && args->size() != 11)
- return 0;
-
- RefPtr<CSSBasicShapeRectangle> shape = CSSBasicShapeRectangle::create();
-
- unsigned argumentNumber = 0;
- CSSParserValue* argument = args->current();
- while (argument) {
- Units unitFlags = FLength | FPercent;
- if (argumentNumber > 1) {
- // Arguments width, height, rx, and ry cannot be negative.
- unitFlags = unitFlags | FNonNeg;
- }
- if (!validUnit(argument, unitFlags))
- return 0;
-
- RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
- ASSERT(argumentNumber < 6);
- switch (argumentNumber) {
- case 0:
- shape->setX(length);
- break;
- case 1:
- shape->setY(length);
- break;
- case 2:
- shape->setWidth(length);
- break;
- case 3:
- shape->setHeight(length);
- break;
- case 4:
- shape->setRadiusX(length);
- break;
- case 5:
- shape->setRadiusY(length);
- break;
- }
- argument = args->next();
- if (argument) {
- if (!isComma(argument))
- return 0;
-
- argument = args->next();
- }
- argumentNumber++;
- }
-
- if (argumentNumber < 4)
- return 0;
- return shape;
-}
-
-PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeInsetRectangle(CSSParserValueList* args)
-{
- ASSERT(args);
-
- // inset-rectangle(top, right, bottom, left, [[rx], ry])
- if (args->size() != 7 && args->size() != 9 && args->size() != 11)
- return 0;
-
- RefPtr<CSSBasicShapeInsetRectangle> shape = CSSBasicShapeInsetRectangle::create();
-
- unsigned argumentNumber = 0;
- CSSParserValue* argument = args->current();
- while (argument) {
- Units unitFlags = FLength | FPercent | FNonNeg;
- if (!validUnit(argument, unitFlags))
- return 0;
-
- RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
- ASSERT(argumentNumber < 6);
- switch (argumentNumber) {
- case 0:
- shape->setTop(length);
- break;
- case 1:
- shape->setRight(length);
- break;
- case 2:
- shape->setBottom(length);
- break;
- case 3:
- shape->setLeft(length);
- break;
- case 4:
- shape->setRadiusX(length);
- break;
- case 5:
- shape->setRadiusY(length);
- break;
- }
- argument = args->next();
- if (argument) {
- if (!isComma(argument))
- return 0;
-
- argument = args->next();
- }
- argumentNumber++;
- }
-
- if (argumentNumber < 4)
- return 0;
- return shape;
-}
-
-PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeCircle(CSSParserValueList* args)
-{
- ASSERT(args);
-
- // circle(centerX, centerY, radius)
- if (args->size() != 5)
- return 0;
-
- RefPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create();
-
- unsigned argumentNumber = 0;
- CSSParserValue* argument = args->current();
- while (argument) {
- Units unitFlags = FLength | FPercent;
- if (argumentNumber == 2) {
- // Argument radius cannot be negative.
- unitFlags = unitFlags | FNonNeg;
- }
-
- if (!validUnit(argument, unitFlags))
- return 0;
-
- RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
- ASSERT(argumentNumber < 3);
- switch (argumentNumber) {
- case 0:
- shape->setCenterX(length);
- break;
- case 1:
- shape->setCenterY(length);
- break;
- case 2:
- shape->setRadius(length);
- break;
- }
-
- argument = args->next();
- if (argument) {
- if (!isComma(argument))
- return 0;
- argument = args->next();
- }
- argumentNumber++;
- }
-
- if (argumentNumber < 3)
- return 0;
- return shape;
-}
-
-PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapeEllipse(CSSParserValueList* args)
-{
- ASSERT(args);
-
- // ellipse(centerX, centerY, radiusX, radiusY)
- if (args->size() != 7)
- return 0;
-
- RefPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create();
- unsigned argumentNumber = 0;
- CSSParserValue* argument = args->current();
- while (argument) {
- Units unitFlags = FLength | FPercent;
- if (argumentNumber > 1) {
- // Arguments radiusX and radiusY cannot be negative.
- unitFlags = unitFlags | FNonNeg;
- }
- if (!validUnit(argument, unitFlags))
- return 0;
-
- RefPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
- ASSERT(argumentNumber < 4);
- switch (argumentNumber) {
- case 0:
- shape->setCenterX(length);
- break;
- case 1:
- shape->setCenterY(length);
- break;
- case 2:
- shape->setRadiusX(length);
- break;
- case 3:
- shape->setRadiusY(length);
- break;
- }
-
- argument = args->next();
- if (argument) {
- if (!isComma(argument))
- return 0;
- argument = args->next();
- }
- argumentNumber++;
- }
-
- if (argumentNumber < 4)
- return 0;
- return shape;
-}
-
-PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapePolygon(CSSParserValueList* args)
-{
- ASSERT(args);
-
- unsigned size = args->size();
- if (!size)
- return 0;
-
- RefPtr<CSSBasicShapePolygon> shape = CSSBasicShapePolygon::create();
-
- CSSParserValue* argument = args->current();
- if (argument->id == CSSValueEvenodd || argument->id == CSSValueNonzero) {
- shape->setWindRule(argument->id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO);
-
- if (!isComma(args->next()))
- return 0;
-
- argument = args->next();
- size -= 2;
- }
-
- // <length> <length>, ... <length> <length> -> each pair has 3 elements except the last one
- if (!size || (size % 3) - 2)
- return 0;
-
- CSSParserValue* argumentX = argument;
- while (argumentX) {
- if (!validUnit(argumentX, FLength | FPercent))
- return 0;
-
- CSSParserValue* argumentY = args->next();
- if (!argumentY || !validUnit(argumentY, FLength | FPercent))
- return 0;
-
- RefPtr<CSSPrimitiveValue> xLength = createPrimitiveNumericValue(argumentX);
- RefPtr<CSSPrimitiveValue> yLength = createPrimitiveNumericValue(argumentY);
-
- shape->appendPoint(xLength.release(), yLength.release());
-
- CSSParserValue* commaOrNull = args->next();
- if (!commaOrNull)
- argumentX = 0;
- else if (!isComma(commaOrNull))
- return 0;
- else
- argumentX = args->next();
- }
-
- return shape;
-}
-
-bool CSSParser::parseBasicShape(CSSPropertyID propId, bool important)
-{
- CSSParserValue* value = m_valueList->current();
- ASSERT(value->unit == CSSParserValue::Function);
- CSSParserValueList* args = value->function->args.get();
-
- if (!args)
- return false;
-
- RefPtr<CSSBasicShape> shape;
- if (equalIgnoringCase(value->function->name, "rectangle("))
- shape = parseBasicShapeRectangle(args);
- else if (equalIgnoringCase(value->function->name, "circle("))
- shape = parseBasicShapeCircle(args);
- else if (equalIgnoringCase(value->function->name, "ellipse("))
- shape = parseBasicShapeEllipse(args);
- else if (equalIgnoringCase(value->function->name, "polygon("))
- shape = parseBasicShapePolygon(args);
- else if (equalIgnoringCase(value->function->name, "inset-rectangle("))
- shape = parseBasicShapeInsetRectangle(args);
-
- if (!shape)
- return false;
-
- addProperty(propId, cssValuePool().createValue(shape.release()), important);
- m_valueList->next();
- return true;
-}
-
-// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family'
-bool CSSParser::parseFont(bool important)
-{
- // Let's check if there is an inherit or initial somewhere in the shorthand.
- for (unsigned i = 0; i < m_valueList->size(); ++i) {
- if (m_valueList->valueAt(i)->id == CSSValueInherit || m_valueList->valueAt(i)->id == CSSValueInitial)
- return false;
- }
-
- ShorthandScope scope(this, CSSPropertyFont);
- // Optional font-style, font-variant and font-weight.
- bool fontStyleParsed = false;
- bool fontVariantParsed = false;
- bool fontWeightParsed = false;
- CSSParserValue* value;
- while ((value = m_valueList->current())) {
- if (!fontStyleParsed && isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value->id, m_context)) {
- addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(value->id), important);
- fontStyleParsed = true;
- } else if (!fontVariantParsed && (value->id == CSSValueNormal || value->id == CSSValueSmallCaps)) {
- // Font variant in the shorthand is particular, it only accepts normal or small-caps.
- addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(value->id), important);
- fontVariantParsed = true;
- } else if (!fontWeightParsed && parseFontWeight(important))
- fontWeightParsed = true;
- else
- break;
- m_valueList->next();
- }
-
- if (!value)
- return false;
-
- if (!fontStyleParsed)
- addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
- if (!fontVariantParsed)
- addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
- if (!fontWeightParsed)
- addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
-
- // Now a font size _must_ come.
- // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
- if (!parseFontSize(important))
- return false;
-
- value = m_valueList->current();
- if (!value)
- return false;
-
- if (isForwardSlashOperator(value)) {
- // The line-height property.
- value = m_valueList->next();
- if (!value)
- return false;
- if (!parseLineHeight(important))
- return false;
- } else
- addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
-
- // Font family must come now.
- RefPtr<CSSValue> parsedFamilyValue = parseFontFamily();
- if (!parsedFamilyValue)
- return false;
-
- addProperty(CSSPropertyFontFamily, parsedFamilyValue.release(), important);
-
- // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires that
- // "font-stretch", "font-size-adjust", and "font-kerning" be reset to their initial values
- // but we don't seem to support them at the moment. They should also be added here once implemented.
- if (m_valueList->current())
- return false;
-
- return true;
-}
-
-class FontFamilyValueBuilder {
-public:
- FontFamilyValueBuilder(CSSValueList* list)
- : m_list(list)
- {
- }
-
- void add(const CSSParserString& string)
- {
- if (!m_builder.isEmpty())
- m_builder.append(' ');
-
- if (string.is8Bit()) {
- m_builder.append(string.characters8(), string.length());
- return;
- }
-
- m_builder.append(string.characters16(), string.length());
- }
-
- void commit()
- {
- if (m_builder.isEmpty())
- return;
- m_list->append(cssValuePool().createFontFamilyValue(m_builder.toString()));
- m_builder.clear();
- }
-
-private:
- StringBuilder m_builder;
- CSSValueList* m_list;
-};
-
-PassRefPtr<CSSValueList> CSSParser::parseFontFamily()
-{
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- CSSParserValue* value = m_valueList->current();
-
- FontFamilyValueBuilder familyBuilder(list.get());
- bool inFamily = false;
-
- while (value) {
- CSSParserValue* nextValue = m_valueList->next();
- bool nextValBreaksFont = !nextValue ||
- (nextValue->unit == CSSParserValue::Operator && nextValue->iValue == ',');
- bool nextValIsFontName = nextValue &&
- ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitBody) ||
- (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT));
-
- bool valueIsKeyword = value->id == CSSValueInitial || value->id == CSSValueInherit || value->id == CSSValueDefault;
- if (valueIsKeyword && !inFamily) {
- if (nextValBreaksFont)
- value = m_valueList->next();
- else if (nextValIsFontName)
- value = nextValue;
- continue;
- }
-
- if (value->id >= CSSValueSerif && value->id <= CSSValueWebkitBody) {
- if (inFamily)
- familyBuilder.add(value->string);
- else if (nextValBreaksFont || !nextValIsFontName)
- list->append(cssValuePool().createIdentifierValue(value->id));
- else {
- familyBuilder.commit();
- familyBuilder.add(value->string);
- inFamily = true;
- }
- } else if (value->unit == CSSPrimitiveValue::CSS_STRING) {
- // Strings never share in a family name.
- inFamily = false;
- familyBuilder.commit();
- list->append(cssValuePool().createFontFamilyValue(value->string));
- } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) {
- if (inFamily)
- familyBuilder.add(value->string);
- else if (nextValBreaksFont || !nextValIsFontName)
- list->append(cssValuePool().createFontFamilyValue(value->string));
- else {
- familyBuilder.commit();
- familyBuilder.add(value->string);
- inFamily = true;
- }
- } else {
- break;
- }
-
- if (!nextValue)
- break;
-
- if (nextValBreaksFont) {
- value = m_valueList->next();
- familyBuilder.commit();
- inFamily = false;
- }
- else if (nextValIsFontName)
- value = nextValue;
- else
- break;
- }
- familyBuilder.commit();
-
- if (!list->length())
- list = 0;
- return list.release();
-}
-
-bool CSSParser::parseLineHeight(bool important)
-{
- CSSParserValue* value = m_valueList->current();
- CSSValueID id = value->id;
- bool validPrimitive = false;
- // normal | <number> | <length> | <percentage> | inherit
- if (id == CSSValueNormal)
- validPrimitive = true;
- else
- validPrimitive = (!id && validUnit(value, FNumber | FLength | FPercent | FNonNeg));
- if (validPrimitive && (!m_valueList->next() || inShorthand()))
- addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, value), important);
- return validPrimitive;
-}
-
-bool CSSParser::parseFontSize(bool important)
-{
- CSSParserValue* value = m_valueList->current();
- CSSValueID id = value->id;
- bool validPrimitive = false;
- // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
- if (id >= CSSValueXxSmall && id <= CSSValueLarger)
- validPrimitive = true;
- else
- validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
- if (validPrimitive && (!m_valueList->next() || inShorthand()))
- addProperty(CSSPropertyFontSize, parseValidPrimitive(id, value), important);
- return validPrimitive;
-}
-
-bool CSSParser::parseFontVariant(bool important)
-{
- RefPtr<CSSValueList> values;
- if (m_valueList->size() > 1)
- values = CSSValueList::createCommaSeparated();
- CSSParserValue* val;
- bool expectComma = false;
- while ((val = m_valueList->current())) {
- RefPtr<CSSPrimitiveValue> parsedValue;
- if (!expectComma) {
- expectComma = true;
- if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps)
- parsedValue = cssValuePool().createIdentifierValue(val->id);
- else if (val->id == CSSValueAll && !values) {
- // 'all' is only allowed in @font-face and with no other values. Make a value list to
- // indicate that we are in the @font-face case.
- values = CSSValueList::createCommaSeparated();
- parsedValue = cssValuePool().createIdentifierValue(val->id);
- }
- } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
- expectComma = false;
- m_valueList->next();
- continue;
- }
-
- if (!parsedValue)
- return false;
-
- m_valueList->next();
-
- if (values)
- values->append(parsedValue.release());
- else {
- addProperty(CSSPropertyFontVariant, parsedValue.release(), important);
- return true;
- }
- }
-
- if (values && values->length()) {
- m_hasFontFaceOnlyValues = true;
- addProperty(CSSPropertyFontVariant, values.release(), important);
- return true;
- }
-
- return false;
-}
-
-bool CSSParser::parseFontWeight(bool important)
-{
- CSSParserValue* value = m_valueList->current();
- if ((value->id >= CSSValueNormal) && (value->id <= CSSValue900)) {
- addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(value->id), important);
- return true;
- }
- if (validUnit(value, FInteger | FNonNeg, HTMLQuirksMode)) {
- int weight = static_cast<int>(value->fValue);
- if (!(weight % 100) && weight >= 100 && weight <= 900) {
- addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue100 + weight / 100 - 1)), important);
- return true;
- }
- }
- return false;
-}
-
-bool CSSParser::parseFontFaceSrcURI(CSSValueList* valueList)
-{
- RefPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create(completeURL(m_valueList->current()->string)));
-
- CSSParserValue* value = m_valueList->next();
- if (!value) {
- valueList->append(uriValue.release());
- return true;
- }
- if (value->unit == CSSParserValue::Operator && value->iValue == ',') {
- m_valueList->next();
- valueList->append(uriValue.release());
- return true;
- }
-
- if (value->unit != CSSParserValue::Function || !equalIgnoringCase(value->function->name, "format("))
- return false;
-
- // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20111004/ says that format() contains a comma-separated list of strings,
- // but CSSFontFaceSrcValue stores only one format. Allowing one format for now.
- CSSParserValueList* args = value->function->args.get();
- if (!args || args->size() != 1 || (args->current()->unit != CSSPrimitiveValue::CSS_STRING && args->current()->unit != CSSPrimitiveValue::CSS_IDENT))
- return false;
- uriValue->setFormat(args->current()->string);
- valueList->append(uriValue.release());
- value = m_valueList->next();
- if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
- m_valueList->next();
- return true;
-}
-
-bool CSSParser::parseFontFaceSrcLocal(CSSValueList* valueList)
-{
- CSSParserValueList* args = m_valueList->current()->function->args.get();
- if (!args || !args->size())
- return false;
-
- if (args->size() == 1 && args->current()->unit == CSSPrimitiveValue::CSS_STRING)
- valueList->append(CSSFontFaceSrcValue::createLocal(args->current()->string));
- else if (args->current()->unit == CSSPrimitiveValue::CSS_IDENT) {
- StringBuilder builder;
- for (CSSParserValue* localValue = args->current(); localValue; localValue = args->next()) {
- if (localValue->unit != CSSPrimitiveValue::CSS_IDENT)
- return false;
- if (!builder.isEmpty())
- builder.append(' ');
- builder.append(localValue->string);
- }
- valueList->append(CSSFontFaceSrcValue::createLocal(builder.toString()));
- } else
- return false;
-
- if (CSSParserValue* value = m_valueList->next()) {
- if (value->unit == CSSParserValue::Operator && value->iValue == ',')
- m_valueList->next();
- }
- return true;
-}
-
-bool CSSParser::parseFontFaceSrc()
-{
- RefPtr<CSSValueList> values(CSSValueList::createCommaSeparated());
-
- while (CSSParserValue* value = m_valueList->current()) {
- if (value->unit == CSSPrimitiveValue::CSS_URI) {
- if (!parseFontFaceSrcURI(values.get()))
- return false;
- } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "local(")) {
- if (!parseFontFaceSrcLocal(values.get()))
- return false;
- } else
- return false;
- }
- if (!values->length())
- return false;
-
- addProperty(CSSPropertySrc, values.release(), m_important);
- m_valueList->next();
- return true;
-}
-
-bool CSSParser::parseFontFaceUnicodeRange()
-{
- RefPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
- bool failed = false;
- bool operatorExpected = false;
- for (; m_valueList->current(); m_valueList->next(), operatorExpected = !operatorExpected) {
- if (operatorExpected) {
- if (m_valueList->current()->unit == CSSParserValue::Operator && m_valueList->current()->iValue == ',')
- continue;
- failed = true;
- break;
- }
- if (m_valueList->current()->unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
- failed = true;
- break;
- }
-
- String rangeString = m_valueList->current()->string;
- UChar32 from = 0;
- UChar32 to = 0;
- unsigned length = rangeString.length();
-
- if (length < 3) {
- failed = true;
- break;
- }
-
- unsigned i = 2;
- while (i < length) {
- UChar c = rangeString[i];
- if (c == '-' || c == '?')
- break;
- from *= 16;
- if (c >= '0' && c <= '9')
- from += c - '0';
- else if (c >= 'A' && c <= 'F')
- from += 10 + c - 'A';
- else if (c >= 'a' && c <= 'f')
- from += 10 + c - 'a';
- else {
- failed = true;
- break;
- }
- i++;
- }
- if (failed)
- break;
-
- if (i == length)
- to = from;
- else if (rangeString[i] == '?') {
- unsigned span = 1;
- while (i < length && rangeString[i] == '?') {
- span *= 16;
- from *= 16;
- i++;
- }
- if (i < length)
- failed = true;
- to = from + span - 1;
- } else {
- if (length < i + 2) {
- failed = true;
- break;
- }
- i++;
- while (i < length) {
- UChar c = rangeString[i];
- to *= 16;
- if (c >= '0' && c <= '9')
- to += c - '0';
- else if (c >= 'A' && c <= 'F')
- to += 10 + c - 'A';
- else if (c >= 'a' && c <= 'f')
- to += 10 + c - 'a';
- else {
- failed = true;
- break;
- }
- i++;
- }
- if (failed)
- break;
- }
- if (from <= to)
- values->append(CSSUnicodeRangeValue::create(from, to));
- }
- if (failed || !values->length())
- return false;
- addProperty(CSSPropertyUnicodeRange, values.release(), m_important);
- return true;
-}
-
-// Returns the number of characters which form a valid double
-// and are terminated by the given terminator character
-template <typename CharacterType>
-static int checkForValidDouble(const CharacterType* string, const CharacterType* end, const char terminator)
-{
- int length = end - string;
- if (length < 1)
- return 0;
-
- bool decimalMarkSeen = false;
- int processedLength = 0;
-
- for (int i = 0; i < length; ++i) {
- if (string[i] == terminator) {
- processedLength = i;
- break;
- }
- if (!isASCIIDigit(string[i])) {
- if (!decimalMarkSeen && string[i] == '.')
- decimalMarkSeen = true;
- else
- return 0;
- }
- }
-
- if (decimalMarkSeen && processedLength == 1)
- return 0;
-
- return processedLength;
-}
-
-// Returns the number of characters consumed for parsing a valid double
-// terminated by the given terminator character
-template <typename CharacterType>
-static int parseDouble(const CharacterType* string, const CharacterType* end, const char terminator, double& value)
-{
- int length = checkForValidDouble(string, end, terminator);
- if (!length)
- return 0;
-
- int position = 0;
- double localValue = 0;
-
- // The consumed characters here are guaranteed to be
- // ASCII digits with or without a decimal mark
- for (; position < length; ++position) {
- if (string[position] == '.')
- break;
- localValue = localValue * 10 + string[position] - '0';
- }
-
- if (++position == length) {
- value = localValue;
- return length;
- }
-
- double fraction = 0;
- double scale = 1;
-
- while (position < length && scale < MAX_SCALE) {
- fraction = fraction * 10 + string[position++] - '0';
- scale *= 10;
- }
-
- value = localValue + fraction / scale;
- return length;
-}
-
-template <typename CharacterType>
-static bool parseColorIntOrPercentage(const CharacterType*& string, const CharacterType* end, const char terminator, CSSPrimitiveValue::UnitTypes& expect, int& value)
-{
- const CharacterType* current = string;
- double localValue = 0;
- bool negative = false;
- while (current != end && isHTMLSpace<CharacterType>(*current))
- current++;
- if (current != end && *current == '-') {
- negative = true;
- current++;
- }
- if (current == end || !isASCIIDigit(*current))
- return false;
- while (current != end && isASCIIDigit(*current)) {
- double newValue = localValue * 10 + *current++ - '0';
- if (newValue >= 255) {
- // Clamp values at 255.
- localValue = 255;
- while (current != end && isASCIIDigit(*current))
- ++current;
- break;
- }
- localValue = newValue;
- }
-
- if (current == end)
- return false;
-
- if (expect == CSSPrimitiveValue::CSS_NUMBER && (*current == '.' || *current == '%'))
- return false;
-
- if (*current == '.') {
- // We already parsed the integral part, try to parse
- // the fraction part of the percentage value.
- double percentage = 0;
- int numCharactersParsed = parseDouble(current, end, '%', percentage);
- if (!numCharactersParsed)
- return false;
- current += numCharactersParsed;
- if (*current != '%')
- return false;
- localValue += percentage;
- }
-
- if (expect == CSSPrimitiveValue::CSS_PERCENTAGE && *current != '%')
- return false;
-
- if (*current == '%') {
- expect = CSSPrimitiveValue::CSS_PERCENTAGE;
- localValue = localValue / 100.0 * 256.0;
- // Clamp values at 255 for percentages over 100%
- if (localValue > 255)
- localValue = 255;
- current++;
- } else
- expect = CSSPrimitiveValue::CSS_NUMBER;
-
- while (current != end && isHTMLSpace<CharacterType>(*current))
- current++;
- if (current == end || *current++ != terminator)
- return false;
- // Clamp negative values at zero.
- value = negative ? 0 : static_cast<int>(localValue);
- string = current;
- return true;
-}
-
-template <typename CharacterType>
-static inline bool isTenthAlpha(const CharacterType* string, const int length)
-{
- // "0.X"
- if (length == 3 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2]))
- return true;
-
- // ".X"
- if (length == 2 && string[0] == '.' && isASCIIDigit(string[1]))
- return true;
-
- return false;
-}
-
-template <typename CharacterType>
-static inline bool parseAlphaValue(const CharacterType*& string, const CharacterType* end, const char terminator, int& value)
-{
- while (string != end && isHTMLSpace<CharacterType>(*string))
- string++;
-
- bool negative = false;
-
- if (string != end && *string == '-') {
- negative = true;
- string++;
- }
-
- value = 0;
-
- int length = end - string;
- if (length < 2)
- return false;
-
- if (string[length - 1] != terminator || !isASCIIDigit(string[length - 2]))
- return false;
-
- if (string[0] != '0' && string[0] != '1' && string[0] != '.') {
- if (checkForValidDouble(string, end, terminator)) {
- value = negative ? 0 : 255;
- string = end;
- return true;
- }
- return false;
- }
-
- if (length == 2 && string[0] != '.') {
- value = !negative && string[0] == '1' ? 255 : 0;
- string = end;
- return true;
- }
-
- if (isTenthAlpha(string, length - 1)) {
- static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 };
- value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
- string = end;
- return true;
- }
-
- double alpha = 0;
- if (!parseDouble(string, end, terminator, alpha))
- return false;
- value = negative ? 0 : static_cast<int>(alpha * nextafter(256.0, 0.0));
- string = end;
- return true;
-}
-
-template <typename CharacterType>
-static inline bool mightBeRGBA(const CharacterType* characters, unsigned length)
-{
- if (length < 5)
- return false;
- return characters[4] == '('
- && isASCIIAlphaCaselessEqual(characters[0], 'r')
- && isASCIIAlphaCaselessEqual(characters[1], 'g')
- && isASCIIAlphaCaselessEqual(characters[2], 'b')
- && isASCIIAlphaCaselessEqual(characters[3], 'a');
-}
-
-template <typename CharacterType>
-static inline bool mightBeRGB(const CharacterType* characters, unsigned length)
-{
- if (length < 4)
- return false;
- return characters[3] == '('
- && isASCIIAlphaCaselessEqual(characters[0], 'r')
- && isASCIIAlphaCaselessEqual(characters[1], 'g')
- && isASCIIAlphaCaselessEqual(characters[2], 'b');
-}
-
-template <typename CharacterType>
-static inline bool fastParseColorInternal(RGBA32& rgb, const CharacterType* characters, unsigned length , bool strict)
-{
- CSSPrimitiveValue::UnitTypes expect = CSSPrimitiveValue::CSS_UNKNOWN;
-
- if (!strict && length >= 3) {
- if (characters[0] == '#') {
- if (Color::parseHexColor(characters + 1, length - 1, rgb))
- return true;
- } else {
- if (Color::parseHexColor(characters, length, rgb))
- return true;
- }
- }
-
- // Try rgba() syntax.
- if (mightBeRGBA(characters, length)) {
- const CharacterType* current = characters + 5;
- const CharacterType* end = characters + length;
- int red;
- int green;
- int blue;
- int alpha;
-
- if (!parseColorIntOrPercentage(current, end, ',', expect, red))
- return false;
- if (!parseColorIntOrPercentage(current, end, ',', expect, green))
- return false;
- if (!parseColorIntOrPercentage(current, end, ',', expect, blue))
- return false;
- if (!parseAlphaValue(current, end, ')', alpha))
- return false;
- if (current != end)
- return false;
- rgb = makeRGBA(red, green, blue, alpha);
- return true;
- }
-
- // Try rgb() syntax.
- if (mightBeRGB(characters, length)) {
- const CharacterType* current = characters + 4;
- const CharacterType* end = characters + length;
- int red;
- int green;
- int blue;
- if (!parseColorIntOrPercentage(current, end, ',', expect, red))
- return false;
- if (!parseColorIntOrPercentage(current, end, ',', expect, green))
- return false;
- if (!parseColorIntOrPercentage(current, end, ')', expect, blue))
- return false;
- if (current != end)
- return false;
- rgb = makeRGB(red, green, blue);
- return true;
- }
-
- return false;
-}
-
-template<typename StringType>
-bool CSSParser::fastParseColor(RGBA32& rgb, const StringType& name, bool strict)
-{
- unsigned length = name.length();
- bool parseResult;
-
- if (!length)
- return false;
-
- if (name.is8Bit())
- parseResult = fastParseColorInternal(rgb, name.characters8(), length, strict);
- else
- parseResult = fastParseColorInternal(rgb, name.characters16(), length, strict);
-
- if (parseResult)
- return true;
-
- // Try named colors.
- Color tc;
- tc.setNamedColor(name);
- if (tc.isValid()) {
- rgb = tc.rgb();
- return true;
- }
- return false;
-}
-
-inline double CSSParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc)
-{
- const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue;
- if (releaseCalc == ReleaseParsedCalcValue)
- m_parsedCalculation.release();
- return result;
-}
-
-bool CSSParser::isCalculation(CSSParserValue* value)
-{
- return (value->unit == CSSParserValue::Function)
- && (equalIgnoringCase(value->function->name, "calc(")
- || equalIgnoringCase(value->function->name, "-webkit-calc(")
- || equalIgnoringCase(value->function->name, "-webkit-min(")
- || equalIgnoringCase(value->function->name, "-webkit-max("));
-}
-
-inline int CSSParser::colorIntFromValue(CSSParserValue* v)
-{
- bool isPercent;
-
- if (m_parsedCalculation)
- isPercent = m_parsedCalculation->category() == CalcPercent;
- else
- isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE;
-
- const double value = parsedDouble(v, ReleaseParsedCalcValue);
-
- if (value <= 0.0)
- return 0;
-
- if (isPercent) {
- if (value >= 100.0)
- return 255;
- return static_cast<int>(value * 256.0 / 100.0);
- }
-
- if (value >= 255.0)
- return 255;
-
- return static_cast<int>(value);
-}
-
-bool CSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha)
-{
- CSSParserValueList* args = value->function->args.get();
- CSSParserValue* v = args->current();
- Units unitType = FUnknown;
- // Get the first value and its type
- if (validUnit(v, FInteger, HTMLStandardMode))
- unitType = FInteger;
- else if (validUnit(v, FPercent, HTMLStandardMode))
- unitType = FPercent;
- else
- return false;
-
- colorArray[0] = colorIntFromValue(v);
- for (int i = 1; i < 3; i++) {
- v = args->next();
- if (v->unit != CSSParserValue::Operator && v->iValue != ',')
- return false;
- v = args->next();
- if (!validUnit(v, unitType, HTMLStandardMode))
- return false;
- colorArray[i] = colorIntFromValue(v);
- }
- if (parseAlpha) {
- v = args->next();
- if (v->unit != CSSParserValue::Operator && v->iValue != ',')
- return false;
- v = args->next();
- if (!validUnit(v, FNumber, HTMLStandardMode))
- return false;
- const double value = parsedDouble(v, ReleaseParsedCalcValue);
- // Convert the floating pointer number of alpha to an integer in the range [0, 256),
- // with an equal distribution across all 256 values.
- colorArray[3] = static_cast<int>(max(0.0, min(1.0, value)) * nextafter(256.0, 0.0));
- }
- return true;
-}
-
-// The CSS3 specification defines the format of a HSL color as
-// hsl(<number>, <percent>, <percent>)
-// and with alpha, the format is
-// hsla(<number>, <percent>, <percent>, <number>)
-// The first value, HUE, is in an angle with a value between 0 and 360
-bool CSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bool parseAlpha)
-{
- CSSParserValueList* args = value->function->args.get();
- CSSParserValue* v = args->current();
- // Get the first value
- if (!validUnit(v, FNumber, HTMLStandardMode))
- return false;
- // normalize the Hue value and change it to be between 0 and 1.0
- colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0;
- for (int i = 1; i < 3; i++) {
- v = args->next();
- if (v->unit != CSSParserValue::Operator && v->iValue != ',')
- return false;
- v = args->next();
- if (!validUnit(v, FPercent, HTMLStandardMode))
- return false;
- colorArray[i] = max(0.0, min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0
- }
- if (parseAlpha) {
- v = args->next();
- if (v->unit != CSSParserValue::Operator && v->iValue != ',')
- return false;
- v = args->next();
- if (!validUnit(v, FNumber, HTMLStandardMode))
- return false;
- colorArray[3] = max(0.0, min(1.0, parsedDouble(v, ReleaseParsedCalcValue)));
- }
- return true;
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value)
-{
- RGBA32 c = Color::transparent;
- if (!parseColorFromValue(value ? value : m_valueList->current(), c))
- return 0;
- return cssValuePool().createColorValue(c);
-}
-
-bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
-{
- if (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_NUMBER
- && value->fValue >= 0. && value->fValue < 1000000.) {
- String str = String::format("%06d", static_cast<int>((value->fValue+.5)));
- // FIXME: This should be strict parsing for SVG as well.
- if (!fastParseColor(c, str, !inQuirksMode()))
- return false;
- } else if (value->unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR ||
- value->unit == CSSPrimitiveValue::CSS_IDENT ||
- (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) {
- if (!fastParseColor(c, value->string, !inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_IDENT))
- return false;
- } else if (value->unit == CSSParserValue::Function &&
- value->function->args != 0 &&
- value->function->args->size() == 5 /* rgb + two commas */ &&
- equalIgnoringCase(value->function->name, "rgb(")) {
- int colorValues[3];
- if (!parseColorParameters(value, colorValues, false))
- return false;
- c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
- } else {
- if (value->unit == CSSParserValue::Function &&
- value->function->args != 0 &&
- value->function->args->size() == 7 /* rgba + three commas */ &&
- equalIgnoringCase(value->function->name, "rgba(")) {
- int colorValues[4];
- if (!parseColorParameters(value, colorValues, true))
- return false;
- c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
- } else if (value->unit == CSSParserValue::Function &&
- value->function->args != 0 &&
- value->function->args->size() == 5 /* hsl + two commas */ &&
- equalIgnoringCase(value->function->name, "hsl(")) {
- double colorValues[3];
- if (!parseHSLParameters(value, colorValues, false))
- return false;
- c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
- } else if (value->unit == CSSParserValue::Function &&
- value->function->args != 0 &&
- value->function->args->size() == 7 /* hsla + three commas */ &&
- equalIgnoringCase(value->function->name, "hsla(")) {
- double colorValues[4];
- if (!parseHSLParameters(value, colorValues, true))
- return false;
- c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
- } else
- return false;
- }
-
- return true;
-}
-
-// This class tracks parsing state for shadow values. If it goes out of scope (e.g., due to an early return)
-// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
-struct ShadowParseContext {
- ShadowParseContext(CSSPropertyID prop, CSSParser* parser)
- : property(prop)
- , m_parser(parser)
- , allowX(true)
- , allowY(false)
- , allowBlur(false)
- , allowSpread(false)
- , allowColor(true)
- , allowStyle(prop == CSSPropertyWebkitBoxShadow || prop == CSSPropertyBoxShadow)
- , allowBreak(true)
- {
- }
-
- bool allowLength() { return allowX || allowY || allowBlur || allowSpread; }
-
- void commitValue()
- {
- // Handle the ,, case gracefully by doing nothing.
- if (x || y || blur || spread || color || style) {
- if (!values)
- values = CSSValueList::createCommaSeparated();
-
- // Construct the current shadow value and add it to the list.
- values->append(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
- }
-
- // Now reset for the next shadow value.
- x = 0;
- y = 0;
- blur = 0;
- spread = 0;
- style = 0;
- color = 0;
-
- allowX = true;
- allowColor = true;
- allowBreak = true;
- allowY = false;
- allowBlur = false;
- allowSpread = false;
- allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
- }
-
- void commitLength(CSSParserValue* v)
- {
- RefPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
-
- if (allowX) {
- x = val.release();
- allowX = false;
- allowY = true;
- allowColor = false;
- allowStyle = false;
- allowBreak = false;
- } else if (allowY) {
- y = val.release();
- allowY = false;
- allowBlur = true;
- allowColor = true;
- allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
- allowBreak = true;
- } else if (allowBlur) {
- blur = val.release();
- allowBlur = false;
- allowSpread = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
- } else if (allowSpread) {
- spread = val.release();
- allowSpread = false;
- }
- }
-
- void commitColor(PassRefPtr<CSSPrimitiveValue> val)
- {
- color = val;
- allowColor = false;
- if (allowX) {
- allowStyle = false;
- allowBreak = false;
- } else {
- allowBlur = false;
- allowSpread = false;
- allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
- }
- }
-
- void commitStyle(CSSParserValue* v)
- {
- style = cssValuePool().createIdentifierValue(v->id);
- allowStyle = false;
- if (allowX)
- allowBreak = false;
- else {
- allowBlur = false;
- allowSpread = false;
- allowColor = false;
- }
- }
-
- CSSPropertyID property;
- CSSParser* m_parser;
-
- RefPtr<CSSValueList> values;
- RefPtr<CSSPrimitiveValue> x;
- RefPtr<CSSPrimitiveValue> y;
- RefPtr<CSSPrimitiveValue> blur;
- RefPtr<CSSPrimitiveValue> spread;
- RefPtr<CSSPrimitiveValue> style;
- RefPtr<CSSPrimitiveValue> color;
-
- bool allowX;
- bool allowY;
- bool allowBlur;
- bool allowSpread;
- bool allowColor;
- bool allowStyle; // inset or not.
- bool allowBreak;
-};
-
-PassRefPtr<CSSValueList> CSSParser::parseShadow(CSSParserValueList* valueList, CSSPropertyID propId)
-{
- ShadowParseContext context(propId, this);
- CSSParserValue* val;
- while ((val = valueList->current())) {
- // Check for a comma break first.
- if (val->unit == CSSParserValue::Operator) {
- if (val->iValue != ',' || !context.allowBreak)
- // Other operators aren't legal or we aren't done with the current shadow
- // value. Treat as invalid.
- return 0;
- // The value is good. Commit it.
- context.commitValue();
- } else if (validUnit(val, FLength, HTMLStandardMode)) {
- // We required a length and didn't get one. Invalid.
- if (!context.allowLength())
- return 0;
-
- // Blur radius must be non-negative.
- if (context.allowBlur && !validUnit(val, FLength | FNonNeg, HTMLStandardMode))
- return 0;
-
- // A length is allowed here. Construct the value and add it.
- context.commitLength(val);
- } else if (val->id == CSSValueInset) {
- if (!context.allowStyle)
- return 0;
-
- context.commitStyle(val);
- } else {
- // The only other type of value that's ok is a color value.
- RefPtr<CSSPrimitiveValue> parsedColor;
- bool isColor = ((val->id >= CSSValueAqua && val->id <= CSSValueWindowtext) || val->id == CSSValueMenu
- || (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && inQuirksMode())
- || val->id == CSSValueCurrentcolor);
- if (isColor) {
- if (!context.allowColor)
- return 0;
- parsedColor = cssValuePool().createIdentifierValue(val->id);
- }
-
- if (!parsedColor)
- // It's not built-in. Try to parse it as a color.
- parsedColor = parseColor(val);
-
- if (!parsedColor || !context.allowColor)
- return 0; // This value is not a color or length and is invalid or
- // it is a color, but a color isn't allowed at this point.
-
- context.commitColor(parsedColor.release());
- }
-
- valueList->next();
- }
-
- if (context.allowBreak) {
- context.commitValue();
- if (context.values && context.values->length())
- return context.values.release();
- }
-
- return 0;
-}
-
-bool CSSParser::parseReflect(CSSPropertyID propId, bool important)
-{
- // box-reflect: <direction> <offset> <mask>
-
- // Direction comes first.
- CSSParserValue* val = m_valueList->current();
- RefPtr<CSSPrimitiveValue> direction;
- if (val->unit == CSSPrimitiveValue::CSS_VARIABLE_NAME)
- direction = createPrimitiveVariableNameValue(val);
- else
- switch (val->id) {
- case CSSValueAbove:
- case CSSValueBelow:
- case CSSValueLeft:
- case CSSValueRight:
- direction = cssValuePool().createIdentifierValue(val->id);
- break;
- default:
- return false;
- }
-
- // The offset comes next.
- val = m_valueList->next();
- RefPtr<CSSPrimitiveValue> offset;
- if (!val)
- offset = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
- else {
- if (!validUnit(val, FLength | FPercent))
- return false;
- offset = createPrimitiveNumericValue(val);
- }
-
- // Now for the mask.
- RefPtr<CSSValue> mask;
- val = m_valueList->next();
- if (val) {
- mask = parseBorderImage(propId);
- if (!mask)
- return false;
- }
-
- RefPtr<CSSReflectValue> reflectValue = CSSReflectValue::create(direction.release(), offset.release(), mask.release());
- addProperty(propId, reflectValue.release(), important);
- m_valueList->next();
- return true;
-}
-
-bool CSSParser::parseFlex(CSSParserValueList* args, bool important)
-{
- if (!args || !args->size() || args->size() > 3)
- return false;
- static const double unsetValue = -1;
- double flexGrow = unsetValue;
- double flexShrink = unsetValue;
- RefPtr<CSSPrimitiveValue> flexBasis;
-
- while (CSSParserValue* arg = args->current()) {
- if (validUnit(arg, FNumber | FNonNeg)) {
- if (flexGrow == unsetValue)
- flexGrow = arg->fValue;
- else if (flexShrink == unsetValue)
- flexShrink = arg->fValue;
- else if (!arg->fValue) {
- // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set.
- flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
- } else {
- // We only allow 3 numbers without units if the last value is 0. E.g., flex:1 1 1 is invalid.
- return false;
- }
- } else if (!flexBasis && (arg->id == CSSValueAuto || validUnit(arg, FLength | FPercent | FNonNeg)))
- flexBasis = parseValidPrimitive(arg->id, arg);
- else {
- // Not a valid arg for flex.
- return false;
- }
- args->next();
- }
-
- if (flexGrow == unsetValue)
- flexGrow = 1;
- if (flexShrink == unsetValue)
- flexShrink = 1;
- if (!flexBasis)
- flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
-
- addProperty(CSSPropertyFlexGrow, cssValuePool().createValue(clampToFloat(flexGrow), CSSPrimitiveValue::CSS_NUMBER), important);
- addProperty(CSSPropertyFlexShrink, cssValuePool().createValue(clampToFloat(flexShrink), CSSPrimitiveValue::CSS_NUMBER), important);
- addProperty(CSSPropertyFlexBasis, flexBasis, important);
- return true;
-}
-
-bool CSSParser::parseObjectPosition(bool important)
-{
- RefPtr<CSSValue> xValue;
- RefPtr<CSSValue> yValue;
- parseFillPosition(m_valueList.get(), xValue, yValue);
- if (!xValue || !yValue)
- return false;
- addProperty(
- CSSPropertyObjectPosition,
- createPrimitiveValuePair(toCSSPrimitiveValue(xValue.get()), toCSSPrimitiveValue(yValue.get()), Pair::KeepIdenticalValues),
- important);
- return true;
-}
-
-struct BorderImageParseContext {
- BorderImageParseContext()
- : m_canAdvance(false)
- , m_allowCommit(true)
- , m_allowImage(true)
- , m_allowImageSlice(true)
- , m_allowRepeat(true)
- , m_allowForwardSlashOperator(false)
- , m_requireWidth(false)
- , m_requireOutset(false)
- {}
-
- bool canAdvance() const { return m_canAdvance; }
- void setCanAdvance(bool canAdvance) { m_canAdvance = canAdvance; }
-
- bool allowCommit() const { return m_allowCommit; }
- bool allowImage() const { return m_allowImage; }
- bool allowImageSlice() const { return m_allowImageSlice; }
- bool allowRepeat() const { return m_allowRepeat; }
- bool allowForwardSlashOperator() const { return m_allowForwardSlashOperator; }
-
- bool requireWidth() const { return m_requireWidth; }
- bool requireOutset() const { return m_requireOutset; }
-
- void commitImage(PassRefPtr<CSSValue> image)
- {
- m_image = image;
- m_canAdvance = true;
- m_allowCommit = true;
- m_allowImage = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
- m_allowImageSlice = !m_imageSlice;
- m_allowRepeat = !m_repeat;
- }
- void commitImageSlice(PassRefPtr<CSSBorderImageSliceValue> slice)
- {
- m_imageSlice = slice;
- m_canAdvance = true;
- m_allowCommit = m_allowForwardSlashOperator = true;
- m_allowImageSlice = m_requireWidth = m_requireOutset = false;
- m_allowImage = !m_image;
- m_allowRepeat = !m_repeat;
- }
- void commitForwardSlashOperator()
- {
- m_canAdvance = true;
- m_allowCommit = m_allowImage = m_allowImageSlice = m_allowRepeat = m_allowForwardSlashOperator = false;
- if (!m_borderSlice) {
- m_requireWidth = true;
- m_requireOutset = false;
- } else {
- m_requireOutset = true;
- m_requireWidth = false;
- }
- }
- void commitBorderWidth(PassRefPtr<CSSPrimitiveValue> slice)
- {
- m_borderSlice = slice;
- m_canAdvance = true;
- m_allowCommit = m_allowForwardSlashOperator = true;
- m_allowImageSlice = m_requireWidth = m_requireOutset = false;
- m_allowImage = !m_image;
- m_allowRepeat = !m_repeat;
- }
- void commitBorderOutset(PassRefPtr<CSSPrimitiveValue> outset)
- {
- m_outset = outset;
- m_canAdvance = true;
- m_allowCommit = true;
- m_allowImageSlice = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
- m_allowImage = !m_image;
- m_allowRepeat = !m_repeat;
- }
- void commitRepeat(PassRefPtr<CSSValue> repeat)
- {
- m_repeat = repeat;
- m_canAdvance = true;
- m_allowCommit = true;
- m_allowRepeat = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
- m_allowImageSlice = !m_imageSlice;
- m_allowImage = !m_image;
- }
-
- PassRefPtr<CSSValue> commitCSSValue()
- {
- return createBorderImageValue(m_image, m_imageSlice, m_borderSlice, m_outset, m_repeat);
- }
-
- void commitMaskBoxImage(CSSParser* parser, bool important)
- {
- commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageSource, parser, m_image, important);
- commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageSlice, parser, m_imageSlice, important);
- commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageWidth, parser, m_borderSlice, important);
- commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageOutset, parser, m_outset, important);
- commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageRepeat, parser, m_repeat, important);
- }
-
- void commitBorderImage(CSSParser* parser, bool important)
- {
- commitBorderImageProperty(CSSPropertyBorderImageSource, parser, m_image, important);
- commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice, important);
- commitBorderImageProperty(CSSPropertyBorderImageWidth, parser, m_borderSlice, important);
- commitBorderImageProperty(CSSPropertyBorderImageOutset, parser, m_outset, important);
- commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, m_repeat, important);
- }
-
- void commitBorderImageProperty(CSSPropertyID propId, CSSParser* parser, PassRefPtr<CSSValue> value, bool important)
- {
- if (value)
- parser->addProperty(propId, value, important);
- else
- parser->addProperty(propId, cssValuePool().createImplicitInitialValue(), important, true);
- }
-
- bool m_canAdvance;
-
- bool m_allowCommit;
- bool m_allowImage;
- bool m_allowImageSlice;
- bool m_allowRepeat;
- bool m_allowForwardSlashOperator;
-
- bool m_requireWidth;
- bool m_requireOutset;
-
- RefPtr<CSSValue> m_image;
- RefPtr<CSSBorderImageSliceValue> m_imageSlice;
- RefPtr<CSSPrimitiveValue> m_borderSlice;
- RefPtr<CSSPrimitiveValue> m_outset;
-
- RefPtr<CSSValue> m_repeat;
-};
-
-static bool buildBorderImageParseContext(CSSParser& parser, CSSPropertyID propId, BorderImageParseContext& context)
-{
- ShorthandScope scope(&parser, propId);
- while (CSSParserValue* val = parser.m_valueList->current()) {
- context.setCanAdvance(false);
-
- if (!context.canAdvance() && context.allowForwardSlashOperator() && isForwardSlashOperator(val))
- context.commitForwardSlashOperator();
-
- if (!context.canAdvance() && context.allowImage()) {
- if (val->unit == CSSPrimitiveValue::CSS_URI) {
- context.commitImage(CSSImageValue::create(parser.completeURL(parser.m_context, val->string)));
- } else if (isGeneratedImageValue(val)) {
- RefPtr<CSSValue> value;
- if (parser.parseGeneratedImage(parser.m_valueList.get(), value))
- context.commitImage(value.release());
- else
- return false;
- } else if (val->unit == CSSParserValue::Function && equalIgnoringCase(val->function->name, "-webkit-image-set(")) {
- RefPtr<CSSValue> value = parser.parseImageSet(parser.m_valueList.get());
- if (value)
- context.commitImage(value.release());
- else
- return false;
- } else if (val->id == CSSValueNone)
- context.commitImage(cssValuePool().createIdentifierValue(CSSValueNone));
- }
-
- if (!context.canAdvance() && context.allowImageSlice()) {
- RefPtr<CSSBorderImageSliceValue> imageSlice;
- if (parser.parseBorderImageSlice(propId, imageSlice))
- context.commitImageSlice(imageSlice.release());
- }
-
- if (!context.canAdvance() && context.allowRepeat()) {
- RefPtr<CSSValue> repeat;
- if (parser.parseBorderImageRepeat(repeat))
- context.commitRepeat(repeat.release());
- }
-
- if (!context.canAdvance() && context.requireWidth()) {
- RefPtr<CSSPrimitiveValue> borderSlice;
- if (parser.parseBorderImageWidth(borderSlice))
- context.commitBorderWidth(borderSlice.release());
- }
-
- if (!context.canAdvance() && context.requireOutset()) {
- RefPtr<CSSPrimitiveValue> borderOutset;
- if (parser.parseBorderImageOutset(borderOutset))
- context.commitBorderOutset(borderOutset.release());
- }
-
- if (!context.canAdvance())
- return false;
-
- parser.m_valueList->next();
- }
-
- return context.allowCommit();
-}
-
-bool CSSParser::parseBorderImageShorthand(CSSPropertyID propId, bool important)
-{
- BorderImageParseContext context;
- if (buildBorderImageParseContext(*this, propId, context)) {
- switch (propId) {
- case CSSPropertyWebkitMaskBoxImage:
- context.commitMaskBoxImage(this, important);
- return true;
- case CSSPropertyBorderImage:
- context.commitBorderImage(this, important);
- return true;
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
- }
- return false;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseBorderImage(CSSPropertyID propId)
-{
- BorderImageParseContext context;
- if (buildBorderImageParseContext(*this, propId, context)) {
- return context.commitCSSValue();
- }
- return 0;
-}
-
-static bool isBorderImageRepeatKeyword(int id)
-{
- return id == CSSValueStretch || id == CSSValueRepeat || id == CSSValueSpace || id == CSSValueRound;
-}
-
-bool CSSParser::parseBorderImageRepeat(RefPtr<CSSValue>& result)
-{
- RefPtr<CSSPrimitiveValue> firstValue;
- RefPtr<CSSPrimitiveValue> secondValue;
- CSSParserValue* val = m_valueList->current();
- if (!val)
- return false;
- if (isBorderImageRepeatKeyword(val->id))
- firstValue = cssValuePool().createIdentifierValue(val->id);
- else
- return false;
-
- val = m_valueList->next();
- if (val) {
- if (isBorderImageRepeatKeyword(val->id))
- secondValue = cssValuePool().createIdentifierValue(val->id);
- else if (!inShorthand()) {
- // If we're not parsing a shorthand then we are invalid.
- return false;
- } else {
- // We need to rewind the value list, so that when its advanced we'll
- // end up back at this value.
- m_valueList->previous();
- secondValue = firstValue;
- }
- } else
- secondValue = firstValue;
-
- result = createPrimitiveValuePair(firstValue, secondValue);
- return true;
-}
-
-class BorderImageSliceParseContext {
-public:
- BorderImageSliceParseContext(CSSParser* parser)
- : m_parser(parser)
- , m_allowNumber(true)
- , m_allowFill(true)
- , m_allowFinalCommit(false)
- , m_fill(false)
- { }
-
- bool allowNumber() const { return m_allowNumber; }
- bool allowFill() const { return m_allowFill; }
- bool allowFinalCommit() const { return m_allowFinalCommit; }
- CSSPrimitiveValue* top() const { return m_top.get(); }
-
- void commitNumber(CSSParserValue* v)
- {
- RefPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
- if (!m_top)
- m_top = val;
- else if (!m_right)
- m_right = val;
- else if (!m_bottom)
- m_bottom = val;
- else {
- ASSERT(!m_left);
- m_left = val;
- }
-
- m_allowNumber = !m_left;
- m_allowFinalCommit = true;
- }
-
- void commitFill() { m_fill = true; m_allowFill = false; m_allowNumber = !m_top; }
-
- PassRefPtr<CSSBorderImageSliceValue> commitBorderImageSlice()
- {
- // We need to clone and repeat values for any omissions.
- ASSERT(m_top);
- if (!m_right) {
- m_right = m_top;
- m_bottom = m_top;
- m_left = m_top;
- }
- if (!m_bottom) {
- m_bottom = m_top;
- m_left = m_right;
- }
- if (!m_left)
- m_left = m_right;
-
- // Now build a rect value to hold all four of our primitive values.
- RefPtr<Quad> quad = Quad::create();
- quad->setTop(m_top);
- quad->setRight(m_right);
- quad->setBottom(m_bottom);
- quad->setLeft(m_left);
-
- // Make our new border image value now.
- return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), m_fill);
- }
-
-private:
- CSSParser* m_parser;
-
- bool m_allowNumber;
- bool m_allowFill;
- bool m_allowFinalCommit;
-
- RefPtr<CSSPrimitiveValue> m_top;
- RefPtr<CSSPrimitiveValue> m_right;
- RefPtr<CSSPrimitiveValue> m_bottom;
- RefPtr<CSSPrimitiveValue> m_left;
-
- bool m_fill;
-};
-
-bool CSSParser::parseBorderImageSlice(CSSPropertyID propId, RefPtr<CSSBorderImageSliceValue>& result)
-{
- BorderImageSliceParseContext context(this);
- CSSParserValue* val;
- while ((val = m_valueList->current())) {
- // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
- if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, HTMLStandardMode)) {
- context.commitNumber(val);
- } else if (context.allowFill() && val->id == CSSValueFill)
- context.commitFill();
- else if (!inShorthand()) {
- // If we're not parsing a shorthand then we are invalid.
- return false;
- } else {
- if (context.allowFinalCommit()) {
- // We're going to successfully parse, but we don't want to consume this token.
- m_valueList->previous();
- }
- break;
- }
- m_valueList->next();
- }
-
- if (context.allowFinalCommit()) {
- // FIXME: For backwards compatibility, -webkit-border-image, -webkit-mask-box-image and -webkit-box-reflect have to do a fill by default.
- // FIXME: What do we do with -webkit-box-reflect and -webkit-mask-box-image? Probably just have to leave them filling...
- if (propId == CSSPropertyWebkitBorderImage || propId == CSSPropertyWebkitMaskBoxImage || propId == CSSPropertyWebkitBoxReflect)
- context.commitFill();
-
- // Need to fully commit as a single value.
- result = context.commitBorderImageSlice();
- return true;
- }
-
- return false;
-}
-
-class BorderImageQuadParseContext {
-public:
- BorderImageQuadParseContext(CSSParser* parser)
- : m_parser(parser)
- , m_allowNumber(true)
- , m_allowFinalCommit(false)
- { }
-
- bool allowNumber() const { return m_allowNumber; }
- bool allowFinalCommit() const { return m_allowFinalCommit; }
- CSSPrimitiveValue* top() const { return m_top.get(); }
-
- void commitNumber(CSSParserValue* v)
- {
- RefPtr<CSSPrimitiveValue> val;
- if (v->id == CSSValueAuto)
- val = cssValuePool().createIdentifierValue(v->id);
- else
- val = m_parser->createPrimitiveNumericValue(v);
-
- if (!m_top)
- m_top = val;
- else if (!m_right)
- m_right = val;
- else if (!m_bottom)
- m_bottom = val;
- else {
- ASSERT(!m_left);
- m_left = val;
- }
-
- m_allowNumber = !m_left;
- m_allowFinalCommit = true;
- }
-
- void setAllowFinalCommit() { m_allowFinalCommit = true; }
- void setTop(PassRefPtr<CSSPrimitiveValue> val) { m_top = val; }
-
- PassRefPtr<CSSPrimitiveValue> commitBorderImageQuad()
- {
- // We need to clone and repeat values for any omissions.
- ASSERT(m_top);
- if (!m_right) {
- m_right = m_top;
- m_bottom = m_top;
- m_left = m_top;
- }
- if (!m_bottom) {
- m_bottom = m_top;
- m_left = m_right;
- }
- if (!m_left)
- m_left = m_right;
-
- // Now build a quad value to hold all four of our primitive values.
- RefPtr<Quad> quad = Quad::create();
- quad->setTop(m_top);
- quad->setRight(m_right);
- quad->setBottom(m_bottom);
- quad->setLeft(m_left);
-
- // Make our new value now.
- return cssValuePool().createValue(quad.release());
- }
-
-private:
- CSSParser* m_parser;
-
- bool m_allowNumber;
- bool m_allowFinalCommit;
-
- RefPtr<CSSPrimitiveValue> m_top;
- RefPtr<CSSPrimitiveValue> m_right;
- RefPtr<CSSPrimitiveValue> m_bottom;
- RefPtr<CSSPrimitiveValue> m_left;
-};
-
-bool CSSParser::parseBorderImageQuad(Units validUnits, RefPtr<CSSPrimitiveValue>& result)
-{
- BorderImageQuadParseContext context(this);
- CSSParserValue* val;
- while ((val = m_valueList->current())) {
- if (context.allowNumber() && (validUnit(val, validUnits, HTMLStandardMode) || val->id == CSSValueAuto)) {
- context.commitNumber(val);
- } else if (!inShorthand()) {
- // If we're not parsing a shorthand then we are invalid.
- return false;
- } else {
- if (context.allowFinalCommit())
- m_valueList->previous(); // The shorthand loop will advance back to this point.
- break;
- }
- m_valueList->next();
- }
-
- if (context.allowFinalCommit()) {
- // Need to fully commit as a single value.
- result = context.commitBorderImageQuad();
- return true;
- }
- return false;
-}
-
-bool CSSParser::parseBorderImageWidth(RefPtr<CSSPrimitiveValue>& result)
-{
- return parseBorderImageQuad(FLength | FNumber | FNonNeg | FPercent, result);
-}
-
-bool CSSParser::parseBorderImageOutset(RefPtr<CSSPrimitiveValue>& result)
-{
- return parseBorderImageQuad(FLength | FNumber | FNonNeg, result);
-}
-
-static void completeBorderRadii(RefPtr<CSSPrimitiveValue> radii[4])
-{
- if (radii[3])
- return;
- if (!radii[2]) {
- if (!radii[1])
- radii[1] = radii[0];
- radii[2] = radii[0];
- }
- radii[3] = radii[1];
-}
-
-bool CSSParser::parseBorderRadius(CSSPropertyID propId, bool important)
-{
- unsigned num = m_valueList->size();
- if (num > 9)
- return false;
-
- ShorthandScope scope(this, propId);
- RefPtr<CSSPrimitiveValue> radii[2][4];
-
- unsigned indexAfterSlash = 0;
- for (unsigned i = 0; i < num; ++i) {
- CSSParserValue* value = m_valueList->valueAt(i);
- if (value->unit == CSSParserValue::Operator) {
- if (value->iValue != '/')
- return false;
-
- if (!i || indexAfterSlash || i + 1 == num || num > i + 5)
- return false;
-
- indexAfterSlash = i + 1;
- completeBorderRadii(radii[0]);
- continue;
- }
-
- if (i - indexAfterSlash >= 4)
- return false;
-
- if (!validUnit(value, FLength | FPercent | FNonNeg))
- return false;
-
- RefPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value);
-
- if (!indexAfterSlash) {
- radii[0][i] = radius;
-
- // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
- if (num == 2 && propId == CSSPropertyWebkitBorderRadius) {
- indexAfterSlash = 1;
- completeBorderRadii(radii[0]);
- }
- } else
- radii[1][i - indexAfterSlash] = radius.release();
- }
-
- if (!indexAfterSlash) {
- completeBorderRadii(radii[0]);
- for (unsigned i = 0; i < 4; ++i)
- radii[1][i] = radii[0][i];
- } else
- completeBorderRadii(radii[1]);
-
- ImplicitScope implicitScope(this, PropertyImplicit);
- addProperty(CSSPropertyBorderTopLeftRadius, createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()), important);
- addProperty(CSSPropertyBorderTopRightRadius, createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()), important);
- addProperty(CSSPropertyBorderBottomRightRadius, createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()), important);
- addProperty(CSSPropertyBorderBottomLeftRadius, createPrimitiveValuePair(radii[0][3].release(), radii[1][3].release()), important);
- return true;
-}
-
-bool CSSParser::parseAspectRatio(bool important)
-{
- unsigned num = m_valueList->size();
- if (num == 1 && m_valueList->valueAt(0)->id == CSSValueNone) {
- addProperty(CSSPropertyWebkitAspectRatio, cssValuePool().createIdentifierValue(CSSValueNone), important);
- return true;
- }
-
- if (num != 3)
- return false;
-
- CSSParserValue* lvalue = m_valueList->valueAt(0);
- CSSParserValue* op = m_valueList->valueAt(1);
- CSSParserValue* rvalue = m_valueList->valueAt(2);
-
- if (!isForwardSlashOperator(op))
- return false;
-
- if (!validUnit(lvalue, FNumber | FNonNeg) || !validUnit(rvalue, FNumber | FNonNeg))
- return false;
-
- if (!lvalue->fValue || !rvalue->fValue)
- return false;
-
- addProperty(CSSPropertyWebkitAspectRatio, CSSAspectRatioValue::create(narrowPrecisionToFloat(lvalue->fValue), narrowPrecisionToFloat(rvalue->fValue)), important);
-
- return true;
-}
-
-bool CSSParser::parseCounter(CSSPropertyID propId, int defaultValue, bool important)
-{
- enum { ID, VAL } state = ID;
-
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- RefPtr<CSSPrimitiveValue> counterName;
-
- while (true) {
- CSSParserValue* val = m_valueList->current();
- switch (state) {
- case ID:
- if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
- counterName = createPrimitiveStringValue(val);
- state = VAL;
- m_valueList->next();
- continue;
- }
- break;
- case VAL: {
- int i = defaultValue;
- if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) {
- i = clampToInteger(val->fValue);
- m_valueList->next();
- }
-
- list->append(createPrimitiveValuePair(counterName.release(),
- cssValuePool().createValue(i, CSSPrimitiveValue::CSS_NUMBER)));
- state = ID;
- continue;
- }
- }
- break;
- }
-
- if (list->length() > 0) {
- addProperty(propId, list.release(), important);
- return true;
- }
-
- return false;
-}
-
-// This should go away once we drop support for -webkit-gradient
-static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal)
-{
- RefPtr<CSSPrimitiveValue> result;
- if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
- if ((equalIgnoringCase(a, "left") && horizontal)
- || (equalIgnoringCase(a, "top") && !horizontal))
- result = cssValuePool().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
- else if ((equalIgnoringCase(a, "right") && horizontal)
- || (equalIgnoringCase(a, "bottom") && !horizontal))
- result = cssValuePool().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
- else if (equalIgnoringCase(a, "center"))
- result = cssValuePool().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
- } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
- result = cssValuePool().createValue(a->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(a->unit));
- return result;
-}
-
-static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CSSGradientColorStop& stop)
-{
- if (a->unit != CSSParserValue::Function)
- return false;
-
- if (!equalIgnoringCase(a->function->name, "from(") &&
- !equalIgnoringCase(a->function->name, "to(") &&
- !equalIgnoringCase(a->function->name, "color-stop("))
- return false;
-
- CSSParserValueList* args = a->function->args.get();
- if (!args)
- return false;
-
- if (equalIgnoringCase(a->function->name, "from(")
- || equalIgnoringCase(a->function->name, "to(")) {
- // The "from" and "to" stops expect 1 argument.
- if (args->size() != 1)
- return false;
-
- if (equalIgnoringCase(a->function->name, "from("))
- stop.m_position = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
- else
- stop.m_position = cssValuePool().createValue(1, CSSPrimitiveValue::CSS_NUMBER);
-
- CSSValueID id = args->current()->id;
- if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
- stop.m_color = cssValuePool().createIdentifierValue(id);
- else
- stop.m_color = p->parseColor(args->current());
- if (!stop.m_color)
- return false;
- }
-
- // The "color-stop" function expects 3 arguments.
- if (equalIgnoringCase(a->function->name, "color-stop(")) {
- if (args->size() != 3)
- return false;
-
- CSSParserValue* stopArg = args->current();
- if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
- stop.m_position = cssValuePool().createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
- else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER)
- stop.m_position = cssValuePool().createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
- else
- return false;
-
- stopArg = args->next();
- if (stopArg->unit != CSSParserValue::Operator || stopArg->iValue != ',')
- return false;
-
- stopArg = args->next();
- CSSValueID id = stopArg->id;
- if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
- stop.m_color = cssValuePool().createIdentifierValue(id);
- else
- stop.m_color = p->parseColor(stopArg);
- if (!stop.m_color)
- return false;
- }
-
- return true;
-}
-
-bool CSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient)
-{
- // Walk the arguments.
- CSSParserValueList* args = valueList->current()->function->args.get();
- if (!args || args->size() == 0)
- return false;
-
- // The first argument is the gradient type. It is an identifier.
- CSSGradientType gradientType;
- CSSParserValue* a = args->current();
- if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
- return false;
- if (equalIgnoringCase(a, "linear"))
- gradientType = CSSDeprecatedLinearGradient;
- else if (equalIgnoringCase(a, "radial"))
- gradientType = CSSDeprecatedRadialGradient;
- else
- return false;
-
- RefPtr<CSSGradientValue> result;
- switch (gradientType) {
- case CSSDeprecatedLinearGradient:
- result = CSSLinearGradientValue::create(NonRepeating, gradientType);
- break;
- case CSSDeprecatedRadialGradient:
- result = CSSRadialGradientValue::create(NonRepeating, gradientType);
- break;
- default:
- // The rest of the gradient types shouldn't appear here.
- ASSERT_NOT_REACHED();
- }
-
- // Comma.
- a = args->next();
- if (!isComma(a))
- return false;
-
- // Next comes the starting point for the gradient as an x y pair. There is no
- // comma between the x and the y values.
- // First X. It can be left, right, number or percent.
- a = args->next();
- if (!a)
- return false;
- RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true);
- if (!point)
- return false;
- result->setFirstX(point.release());
-
- // First Y. It can be top, bottom, number or percent.
- a = args->next();
- if (!a)
- return false;
- point = parseDeprecatedGradientPoint(a, false);
- if (!point)
- return false;
- result->setFirstY(point.release());
-
- // Comma after the first point.
- a = args->next();
- if (!isComma(a))
- return false;
-
- // For radial gradients only, we now expect a numeric radius.
- if (gradientType == CSSDeprecatedRadialGradient) {
- a = args->next();
- if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
- return false;
- toCSSRadialGradientValue(result.get())->setFirstRadius(createPrimitiveNumericValue(a));
-
- // Comma after the first radius.
- a = args->next();
- if (!isComma(a))
- return false;
- }
-
- // Next is the ending point for the gradient as an x, y pair.
- // Second X. It can be left, right, number or percent.
- a = args->next();
- if (!a)
- return false;
- point = parseDeprecatedGradientPoint(a, true);
- if (!point)
- return false;
- result->setSecondX(point.release());
-
- // Second Y. It can be top, bottom, number or percent.
- a = args->next();
- if (!a)
- return false;
- point = parseDeprecatedGradientPoint(a, false);
- if (!point)
- return false;
- result->setSecondY(point.release());
-
- // For radial gradients only, we now expect the second radius.
- if (gradientType == CSSDeprecatedRadialGradient) {
- // Comma after the second point.
- a = args->next();
- if (!isComma(a))
- return false;
-
- a = args->next();
- if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
- return false;
- toCSSRadialGradientValue(result.get())->setSecondRadius(createPrimitiveNumericValue(a));
- }
-
- // We now will accept any number of stops (0 or more).
- a = args->next();
- while (a) {
- // Look for the comma before the next stop.
- if (!isComma(a))
- return false;
-
- // Now examine the stop itself.
- a = args->next();
- if (!a)
- return false;
-
- // The function name needs to be one of "from", "to", or "color-stop."
- CSSGradientColorStop stop;
- if (!parseDeprecatedGradientColorStop(this, a, stop))
- return false;
- result->addStop(stop);
-
- // Advance
- a = args->next();
- }
-
- gradient = result.release();
- return true;
-}
-
-static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal)
-{
- if (a->unit != CSSPrimitiveValue::CSS_IDENT)
- return 0;
-
- switch (a->id) {
- case CSSValueLeft:
- case CSSValueRight:
- isHorizontal = true;
- break;
- case CSSValueTop:
- case CSSValueBottom:
- isHorizontal = false;
- break;
- default:
- return 0;
- }
- return cssValuePool().createIdentifierValue(a->id);
-}
-
-static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser* p, CSSParserValue* value)
-{
- CSSValueID id = value->id;
- if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor)
- return cssValuePool().createIdentifierValue(id);
-
- return p->parseColor(value);
-}
-
-bool CSSParser::parseDeprecatedLinearGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
-{
- RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSPrefixedLinearGradient);
-
- // Walk the arguments.
- CSSParserValueList* args = valueList->current()->function->args.get();
- if (!args || !args->size())
- return false;
-
- CSSParserValue* a = args->current();
- if (!a)
- return false;
-
- bool expectComma = false;
- // Look for angle.
- if (validUnit(a, FAngle, HTMLStandardMode)) {
- result->setAngle(createPrimitiveNumericValue(a));
-
- args->next();
- expectComma = true;
- } else {
- // Look one or two optional keywords that indicate a side or corner.
- RefPtr<CSSPrimitiveValue> startX, startY;
-
- RefPtr<CSSPrimitiveValue> location;
- bool isHorizontal = false;
- if ((location = valueFromSideKeyword(a, isHorizontal))) {
- if (isHorizontal)
- startX = location;
- else
- startY = location;
-
- if ((a = args->next())) {
- if ((location = valueFromSideKeyword(a, isHorizontal))) {
- if (isHorizontal) {
- if (startX)
- return false;
- startX = location;
- } else {
- if (startY)
- return false;
- startY = location;
- }
-
- args->next();
- }
- }
-
- expectComma = true;
- }
-
- if (!startX && !startY)
- startY = cssValuePool().createIdentifierValue(CSSValueTop);
-
- result->setFirstX(startX.release());
- result->setFirstY(startY.release());
- }
-
- if (!parseGradientColorStops(args, result.get(), expectComma))
- return false;
-
- if (!result->stopCount())
- return false;
-
- gradient = result.release();
- return true;
-}
-
-bool CSSParser::parseDeprecatedRadialGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
-{
- RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient);
-
- // Walk the arguments.
- CSSParserValueList* args = valueList->current()->function->args.get();
- if (!args || !args->size())
- return false;
-
- CSSParserValue* a = args->current();
- if (!a)
- return false;
-
- bool expectComma = false;
-
- // Optional background-position
- RefPtr<CSSValue> centerX;
- RefPtr<CSSValue> centerY;
- // parse2ValuesFillPosition advances the args next pointer.
- parse2ValuesFillPosition(args, centerX, centerY);
- a = args->current();
- if (!a)
- return false;
-
- if (centerX || centerY) {
- // Comma
- if (!isComma(a))
- return false;
-
- a = args->next();
- if (!a)
- return false;
- }
-
- result->setFirstX(toCSSPrimitiveValue(centerX.get()));
- result->setSecondX(toCSSPrimitiveValue(centerX.get()));
- // CSS3 radial gradients always share the same start and end point.
- result->setFirstY(toCSSPrimitiveValue(centerY.get()));
- result->setSecondY(toCSSPrimitiveValue(centerY.get()));
-
- RefPtr<CSSPrimitiveValue> shapeValue;
- RefPtr<CSSPrimitiveValue> sizeValue;
-
- // Optional shape and/or size in any order.
- for (int i = 0; i < 2; ++i) {
- if (a->unit != CSSPrimitiveValue::CSS_IDENT)
- break;
-
- bool foundValue = false;
- switch (a->id) {
- case CSSValueCircle:
- case CSSValueEllipse:
- shapeValue = cssValuePool().createIdentifierValue(a->id);
- foundValue = true;
- break;
- case CSSValueClosestSide:
- case CSSValueClosestCorner:
- case CSSValueFarthestSide:
- case CSSValueFarthestCorner:
- case CSSValueContain:
- case CSSValueCover:
- sizeValue = cssValuePool().createIdentifierValue(a->id);
- foundValue = true;
- break;
- default:
- break;
- }
-
- if (foundValue) {
- a = args->next();
- if (!a)
- return false;
-
- expectComma = true;
- }
- }
-
- result->setShape(shapeValue);
- result->setSizingBehavior(sizeValue);
-
- // Or, two lengths or percentages
- RefPtr<CSSPrimitiveValue> horizontalSize;
- RefPtr<CSSPrimitiveValue> verticalSize;
-
- if (!shapeValue && !sizeValue) {
- if (validUnit(a, FLength | FPercent)) {
- horizontalSize = createPrimitiveNumericValue(a);
- a = args->next();
- if (!a)
- return false;
-
- expectComma = true;
- }
-
- if (validUnit(a, FLength | FPercent)) {
- verticalSize = createPrimitiveNumericValue(a);
-
- a = args->next();
- if (!a)
- return false;
- expectComma = true;
- }
- }
-
- // Must have neither or both.
- if (!horizontalSize != !verticalSize)
- return false;
-
- result->setEndHorizontalSize(horizontalSize);
- result->setEndVerticalSize(verticalSize);
-
- if (!parseGradientColorStops(args, result.get(), expectComma))
- return false;
-
- gradient = result.release();
- return true;
-}
-
-bool CSSParser::parseLinearGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
-{
- RefPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSLinearGradient);
-
- CSSParserValueList* args = valueList->current()->function->args.get();
- if (!args || !args->size())
- return false;
-
- CSSParserValue* a = args->current();
- if (!a)
- return false;
-
- bool expectComma = false;
- // Look for angle.
- if (validUnit(a, FAngle, HTMLStandardMode)) {
- result->setAngle(createPrimitiveNumericValue(a));
-
- args->next();
- expectComma = true;
- } else if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "to")) {
- // to [ [left | right] || [top | bottom] ]
- a = args->next();
- if (!a)
- return false;
-
- RefPtr<CSSPrimitiveValue> endX, endY;
- RefPtr<CSSPrimitiveValue> location;
- bool isHorizontal = false;
-
- location = valueFromSideKeyword(a, isHorizontal);
- if (!location)
- return false;
-
- if (isHorizontal)
- endX = location;
- else
- endY = location;
-
- a = args->next();
- if (!a)
- return false;
-
- location = valueFromSideKeyword(a, isHorizontal);
- if (location) {
- if (isHorizontal) {
- if (endX)
- return false;
- endX = location;
- } else {
- if (endY)
- return false;
- endY = location;
- }
-
- args->next();
- }
-
- expectComma = true;
- result->setFirstX(endX.release());
- result->setFirstY(endY.release());
- }
-
- if (!parseGradientColorStops(args, result.get(), expectComma))
- return false;
-
- if (!result->stopCount())
- return false;
-
- gradient = result.release();
- return true;
-}
-
-bool CSSParser::parseRadialGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
-{
- RefPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient);
-
- CSSParserValueList* args = valueList->current()->function->args.get();
- if (!args || !args->size())
- return false;
-
- CSSParserValue* a = args->current();
- if (!a)
- return false;
-
- bool expectComma = false;
-
- RefPtr<CSSPrimitiveValue> shapeValue;
- RefPtr<CSSPrimitiveValue> sizeValue;
- RefPtr<CSSPrimitiveValue> horizontalSize;
- RefPtr<CSSPrimitiveValue> verticalSize;
-
- // First part of grammar, the size/shape clause:
- // [ circle || <length> ] |
- // [ ellipse || [ <length> | <percentage> ]{2} ] |
- // [ [ circle | ellipse] || <size-keyword> ]
- for (int i = 0; i < 3; ++i) {
- if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
- bool badIdent = false;
- switch (a->id) {
- case CSSValueCircle:
- case CSSValueEllipse:
- if (shapeValue)
- return false;
- shapeValue = cssValuePool().createIdentifierValue(a->id);
- break;
- case CSSValueClosestSide:
- case CSSValueClosestCorner:
- case CSSValueFarthestSide:
- case CSSValueFarthestCorner:
- if (sizeValue || horizontalSize)
- return false;
- sizeValue = cssValuePool().createIdentifierValue(a->id);
- break;
- default:
- badIdent = true;
- }
-
- if (badIdent)
- break;
-
- a = args->next();
- if (!a)
- return false;
- } else if (validUnit(a, FLength | FPercent)) {
-
- if (sizeValue || horizontalSize)
- return false;
- horizontalSize = createPrimitiveNumericValue(a);
-
- a = args->next();
- if (!a)
- return false;
-
- if (validUnit(a, FLength | FPercent)) {
- verticalSize = createPrimitiveNumericValue(a);
- ++i;
- a = args->next();
- if (!a)
- return false;
- }
- } else
- break;
- }
-
- // You can specify size as a keyword or a length/percentage, not both.
- if (sizeValue && horizontalSize)
- return false;
- // Circles must have 0 or 1 lengths.
- if (shapeValue && shapeValue->getValueID() == CSSValueCircle && verticalSize)
- return false;
- // Ellipses must have 0 or 2 length/percentages.
- if (shapeValue && shapeValue->getValueID() == CSSValueEllipse && horizontalSize && !verticalSize)
- return false;
- // If there's only one size, it must be a length.
- if (!verticalSize && horizontalSize && horizontalSize->isPercentage())
- return false;
-
- result->setShape(shapeValue);
- result->setSizingBehavior(sizeValue);
- result->setEndHorizontalSize(horizontalSize);
- result->setEndVerticalSize(verticalSize);
-
- // Second part of grammar, the center-position clause:
- // at <position>
- RefPtr<CSSValue> centerX;
- RefPtr<CSSValue> centerY;
- if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "at")) {
- a = args->next();
- if (!a)
- return false;
-
- parseFillPosition(args, centerX, centerY);
- if (!(centerX && centerY))
- return false;
-
- a = args->current();
- if (!a)
- return false;
- result->setFirstX(toCSSPrimitiveValue(centerX.get()));
- result->setFirstY(toCSSPrimitiveValue(centerY.get()));
- // Right now, CSS radial gradients have the same start and end centers.
- result->setSecondX(toCSSPrimitiveValue(centerX.get()));
- result->setSecondY(toCSSPrimitiveValue(centerY.get()));
- }
-
- if (shapeValue || sizeValue || horizontalSize || centerX || centerY)
- expectComma = true;
-
- if (!parseGradientColorStops(args, result.get(), expectComma))
- return false;
-
- gradient = result.release();
- return true;
-}
-
-bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradientValue* gradient, bool expectComma)
-{
- CSSParserValue* a = valueList->current();
-
- // Now look for color stops.
- while (a) {
- // Look for the comma before the next stop.
- if (expectComma) {
- if (!isComma(a))
- return false;
-
- a = valueList->next();
- if (!a)
- return false;
- }
-
- // <color-stop> = <color> [ <percentage> | <length> ]?
- CSSGradientColorStop stop;
- stop.m_color = parseGradientColorOrKeyword(this, a);
- if (!stop.m_color)
- return false;
-
- a = valueList->next();
- if (a) {
- if (validUnit(a, FLength | FPercent)) {
- stop.m_position = createPrimitiveNumericValue(a);
- a = valueList->next();
- }
- }
-
- gradient->addStop(stop);
- expectComma = true;
- }
-
- // Must have 2 or more stops to be valid.
- return gradient->stopCount() >= 2;
-}
-
-bool CSSParser::parseGeneratedImage(CSSParserValueList* valueList, RefPtr<CSSValue>& value)
-{
- CSSParserValue* val = valueList->current();
-
- if (val->unit != CSSParserValue::Function)
- return false;
-
- if (equalIgnoringCase(val->function->name, "-webkit-gradient("))
- return parseDeprecatedGradient(valueList, value);
-
- if (equalIgnoringCase(val->function->name, "-webkit-linear-gradient("))
- return parseDeprecatedLinearGradient(valueList, value, NonRepeating);
-
- if (equalIgnoringCase(val->function->name, "linear-gradient("))
- return parseLinearGradient(valueList, value, NonRepeating);
-
- if (equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient("))
- return parseDeprecatedLinearGradient(valueList, value, Repeating);
-
- if (equalIgnoringCase(val->function->name, "repeating-linear-gradient("))
- return parseLinearGradient(valueList, value, Repeating);
-
- if (equalIgnoringCase(val->function->name, "-webkit-radial-gradient("))
- return parseDeprecatedRadialGradient(valueList, value, NonRepeating);
-
- if (equalIgnoringCase(val->function->name, "radial-gradient("))
- return parseRadialGradient(valueList, value, NonRepeating);
-
- if (equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient("))
- return parseDeprecatedRadialGradient(valueList, value, Repeating);
-
- if (equalIgnoringCase(val->function->name, "repeating-radial-gradient("))
- return parseRadialGradient(valueList, value, Repeating);
-
- if (equalIgnoringCase(val->function->name, "-webkit-canvas("))
- return parseCanvas(valueList, value);
-
- if (equalIgnoringCase(val->function->name, "-webkit-cross-fade("))
- return parseCrossfade(valueList, value);
-
- return false;
-}
-
-bool CSSParser::parseCrossfade(CSSParserValueList* valueList, RefPtr<CSSValue>& crossfade)
-{
- RefPtr<CSSCrossfadeValue> result;
-
- // Walk the arguments.
- CSSParserValueList* args = valueList->current()->function->args.get();
- if (!args || args->size() != 5)
- return false;
- CSSParserValue* a = args->current();
- RefPtr<CSSValue> fromImageValue;
- RefPtr<CSSValue> toImageValue;
-
- // The first argument is the "from" image. It is a fill image.
- if (!a || !parseFillImage(args, fromImageValue))
- return false;
- a = args->next();
-
- // Skip a comma
- if (!isComma(a))
- return false;
- a = args->next();
-
- // The second argument is the "to" image. It is a fill image.
- if (!a || !parseFillImage(args, toImageValue))
- return false;
- a = args->next();
-
- // Skip a comma
- if (!isComma(a))
- return false;
- a = args->next();
-
- // The third argument is the crossfade value. It is a percentage or a fractional number.
- RefPtr<CSSPrimitiveValue> percentage;
- if (!a)
- return false;
-
- if (a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
- percentage = cssValuePool().createValue(clampTo<double>(a->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
- else if (a->unit == CSSPrimitiveValue::CSS_NUMBER)
- percentage = cssValuePool().createValue(clampTo<double>(a->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
- else
- return false;
-
- result = CSSCrossfadeValue::create(fromImageValue, toImageValue);
- result->setPercentage(percentage);
-
- crossfade = result;
-
- return true;
-}
-
-bool CSSParser::parseCanvas(CSSParserValueList* valueList, RefPtr<CSSValue>& canvas)
-{
- // Walk the arguments.
- CSSParserValueList* args = valueList->current()->function->args.get();
- if (!args || args->size() != 1)
- return false;
-
- // The first argument is the canvas name. It is an identifier.
- CSSParserValue* value = args->current();
- if (!value || value->unit != CSSPrimitiveValue::CSS_IDENT)
- return false;
-
- canvas = CSSCanvasValue::create(value->string);
- return true;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseImageSet(CSSParserValueList* valueList)
-{
- CSSParserValue* function = valueList->current();
-
- if (function->unit != CSSParserValue::Function)
- return 0;
-
- CSSParserValueList* functionArgs = valueList->current()->function->args.get();
- if (!functionArgs || !functionArgs->size() || !functionArgs->current())
- return 0;
-
- RefPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create();
-
- CSSParserValue* arg = functionArgs->current();
- while (arg) {
- if (arg->unit != CSSPrimitiveValue::CSS_URI)
- return 0;
-
- RefPtr<CSSImageValue> image = CSSImageValue::create(completeURL(arg->string));
- imageSet->append(image);
-
- arg = functionArgs->next();
- if (!arg || arg->unit != CSSPrimitiveValue::CSS_DIMENSION)
- return 0;
-
- double imageScaleFactor = 0;
- const String& string = arg->string;
- unsigned length = string.length();
- if (!length)
- return 0;
- if (string.is8Bit()) {
- const LChar* start = string.characters8();
- parseDouble(start, start + length, 'x', imageScaleFactor);
- } else {
- const UChar* start = string.characters16();
- parseDouble(start, start + length, 'x', imageScaleFactor);
- }
- if (imageScaleFactor <= 0)
- return 0;
- imageSet->append(cssValuePool().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER));
-
- // If there are no more arguments, we're done.
- arg = functionArgs->next();
- if (!arg)
- break;
-
- // If there are more arguments, they should be after a comma.
- if (!isComma(arg))
- return 0;
-
- // Skip the comma and move on to the next argument.
- arg = functionArgs->next();
- }
-
- return imageSet.release();
-}
-
-class TransformOperationInfo {
-public:
- TransformOperationInfo(const CSSParserString& name)
- : m_type(CSSTransformValue::UnknownTransformOperation)
- , m_argCount(1)
- , m_allowSingleArgument(false)
- , m_unit(CSSParser::FUnknown)
- {
- const UChar* characters;
- unsigned nameLength = name.length();
-
- const unsigned longestNameLength = 12;
- UChar characterBuffer[longestNameLength];
- if (name.is8Bit()) {
- unsigned length = std::min(longestNameLength, nameLength);
- const LChar* characters8 = name.characters8();
- for (unsigned i = 0; i < length; ++i)
- characterBuffer[i] = characters8[i];
- characters = characterBuffer;
- } else
- characters = name.characters16();
-
- SWITCH(characters, nameLength) {
- CASE("skew(") {
- m_unit = CSSParser::FAngle;
- m_type = CSSTransformValue::SkewTransformOperation;
- m_allowSingleArgument = true;
- m_argCount = 3;
- }
- CASE("scale(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::ScaleTransformOperation;
- m_allowSingleArgument = true;
- m_argCount = 3;
- }
- CASE("skewx(") {
- m_unit = CSSParser::FAngle;
- m_type = CSSTransformValue::SkewXTransformOperation;
- }
- CASE("skewy(") {
- m_unit = CSSParser::FAngle;
- m_type = CSSTransformValue::SkewYTransformOperation;
- }
- CASE("matrix(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::MatrixTransformOperation;
- m_argCount = 11;
- }
- CASE("rotate(") {
- m_unit = CSSParser::FAngle;
- m_type = CSSTransformValue::RotateTransformOperation;
- }
- CASE("scalex(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::ScaleXTransformOperation;
- }
- CASE("scaley(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::ScaleYTransformOperation;
- }
- CASE("scalez(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::ScaleZTransformOperation;
- }
- CASE("scale3d(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::Scale3DTransformOperation;
- m_argCount = 5;
- }
- CASE("rotatex(") {
- m_unit = CSSParser::FAngle;
- m_type = CSSTransformValue::RotateXTransformOperation;
- }
- CASE("rotatey(") {
- m_unit = CSSParser::FAngle;
- m_type = CSSTransformValue::RotateYTransformOperation;
- }
- CASE("rotatez(") {
- m_unit = CSSParser::FAngle;
- m_type = CSSTransformValue::RotateZTransformOperation;
- }
- CASE("matrix3d(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::Matrix3DTransformOperation;
- m_argCount = 31;
- }
- CASE("rotate3d(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::Rotate3DTransformOperation;
- m_argCount = 7;
- }
- CASE("translate(") {
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- m_type = CSSTransformValue::TranslateTransformOperation;
- m_allowSingleArgument = true;
- m_argCount = 3;
- }
- CASE("translatex(") {
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- m_type = CSSTransformValue::TranslateXTransformOperation;
- }
- CASE("translatey(") {
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- m_type = CSSTransformValue::TranslateYTransformOperation;
- }
- CASE("translatez(") {
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- m_type = CSSTransformValue::TranslateZTransformOperation;
- }
- CASE("perspective(") {
- m_unit = CSSParser::FNumber;
- m_type = CSSTransformValue::PerspectiveTransformOperation;
- }
- CASE("translate3d(") {
- m_unit = CSSParser::FLength | CSSParser::FPercent;
- m_type = CSSTransformValue::Translate3DTransformOperation;
- m_argCount = 5;
- }
- }
- }
-
- CSSTransformValue::TransformOperationType type() const { return m_type; }
- unsigned argCount() const { return m_argCount; }
- CSSParser::Units unit() const { return m_unit; }
-
- bool unknown() const { return m_type == CSSTransformValue::UnknownTransformOperation; }
- bool hasCorrectArgCount(unsigned argCount) { return m_argCount == argCount || (m_allowSingleArgument && argCount == 1); }
-
-private:
- CSSTransformValue::TransformOperationType m_type;
- unsigned m_argCount;
- bool m_allowSingleArgument;
- CSSParser::Units m_unit;
-};
-
-PassRefPtr<CSSValueList> CSSParser::parseTransform()
-{
- if (!m_valueList)
- return 0;
-
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
- RefPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
- if (!parsedTransformValue)
- return 0;
-
- list->append(parsedTransformValue.release());
- }
-
- return list.release();
-}
-
-PassRefPtr<CSSValue> CSSParser::parseTransformValue(CSSParserValue *value)
-{
- if (value->unit != CSSParserValue::Function || !value->function)
- return 0;
-
- // Every primitive requires at least one argument.
- CSSParserValueList* args = value->function->args.get();
- if (!args)
- return 0;
-
- // See if the specified primitive is one we understand.
- TransformOperationInfo info(value->function->name);
- if (info.unknown())
- return 0;
-
- if (!info.hasCorrectArgCount(args->size()))
- return 0;
-
- // The transform is a list of functional primitives that specify transform operations.
- // We collect a list of CSSTransformValues, where each value specifies a single operation.
-
- // Create the new CSSTransformValue for this operation and add it to our list.
- RefPtr<CSSTransformValue> transformValue = CSSTransformValue::create(info.type());
-
- // Snag our values.
- CSSParserValue* a = args->current();
- unsigned argNumber = 0;
- while (a) {
- CSSParser::Units unit = info.unit();
-
- if (info.type() == CSSTransformValue::Rotate3DTransformOperation && argNumber == 3) {
- // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
- if (!validUnit(a, FAngle, HTMLStandardMode))
- return 0;
- } else if (info.type() == CSSTransformValue::Translate3DTransformOperation && argNumber == 2) {
- // 3rd param of translate3d() cannot be a percentage
- if (!validUnit(a, FLength, HTMLStandardMode))
- return 0;
- } else if (info.type() == CSSTransformValue::TranslateZTransformOperation && !argNumber) {
- // 1st param of translateZ() cannot be a percentage
- if (!validUnit(a, FLength, HTMLStandardMode))
- return 0;
- } else if (info.type() == CSSTransformValue::PerspectiveTransformOperation && !argNumber) {
- // 1st param of perspective() must be a non-negative number (deprecated) or length.
- if (!validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
- return 0;
- } else if (!validUnit(a, unit, HTMLStandardMode))
- return 0;
-
- // Add the value to the current transform operation.
- transformValue->append(createPrimitiveNumericValue(a));
-
- a = args->next();
- if (!a)
- break;
- if (a->unit != CSSParserValue::Operator || a->iValue != ',')
- return 0;
- a = args->next();
-
- argNumber++;
- }
-
- return transformValue.release();
-}
-
-bool CSSParser::isBlendMode(CSSValueID valueID)
-{
- return (valueID >= CSSValueMultiply && valueID <= CSSValueLuminosity)
- || valueID == CSSValueNormal
- || valueID == CSSValueOverlay;
-}
-
-bool CSSParser::isCompositeOperator(CSSValueID valueID)
-{
- // FIXME: Add CSSValueDestination and CSSValueLighter when the Compositing spec updates.
- return valueID >= CSSValueClear && valueID <= CSSValueXor;
-}
-
-static void filterInfoForName(const CSSParserString& name, CSSFilterValue::FilterOperationType& filterType, unsigned& maximumArgumentCount)
-{
- if (equalIgnoringCase(name, "grayscale("))
- filterType = CSSFilterValue::GrayscaleFilterOperation;
- else if (equalIgnoringCase(name, "sepia("))
- filterType = CSSFilterValue::SepiaFilterOperation;
- else if (equalIgnoringCase(name, "saturate("))
- filterType = CSSFilterValue::SaturateFilterOperation;
- else if (equalIgnoringCase(name, "hue-rotate("))
- filterType = CSSFilterValue::HueRotateFilterOperation;
- else if (equalIgnoringCase(name, "invert("))
- filterType = CSSFilterValue::InvertFilterOperation;
- else if (equalIgnoringCase(name, "opacity("))
- filterType = CSSFilterValue::OpacityFilterOperation;
- else if (equalIgnoringCase(name, "brightness("))
- filterType = CSSFilterValue::BrightnessFilterOperation;
- else if (equalIgnoringCase(name, "contrast("))
- filterType = CSSFilterValue::ContrastFilterOperation;
- else if (equalIgnoringCase(name, "blur("))
- filterType = CSSFilterValue::BlurFilterOperation;
- else if (equalIgnoringCase(name, "drop-shadow(")) {
- filterType = CSSFilterValue::DropShadowFilterOperation;
- maximumArgumentCount = 4; // x-offset, y-offset, blur-radius, color -- spread and inset style not allowed.
- }
- else if (equalIgnoringCase(name, "custom("))
- filterType = CSSFilterValue::CustomFilterOperation;
-}
-
-static bool acceptCommaOperator(CSSParserValueList* argsList)
-{
- if (CSSParserValue* arg = argsList->current()) {
- if (!isComma(arg))
- return false;
- argsList->next();
- }
- return true;
-}
-
-PassRefPtr<CSSArrayFunctionValue> CSSParser::parseCustomFilterArrayFunction(CSSParserValue* value)
-{
- ASSERT(value->unit == CSSParserValue::Function && value->function);
-
- if (!equalIgnoringCase(value->function->name, "array("))
- return 0;
-
- CSSParserValueList* arrayArgsParserValueList = value->function->args.get();
- if (!arrayArgsParserValueList || !arrayArgsParserValueList->size())
- return 0;
-
- // array() values are comma separated.
- RefPtr<CSSArrayFunctionValue> arrayFunction = CSSArrayFunctionValue::create();
- while (true) {
- // We parse pairs <Value, Comma> at each step.
- CSSParserValue* currentParserValue = arrayArgsParserValueList->current();
- if (!currentParserValue || !validUnit(currentParserValue, FNumber, HTMLStandardMode))
- return 0;
-
- RefPtr<CSSValue> arrayValue = cssValuePool().createValue(currentParserValue->fValue, CSSPrimitiveValue::CSS_NUMBER);
- arrayFunction->append(arrayValue.release());
-
- CSSParserValue* nextParserValue = arrayArgsParserValueList->next();
- if (!nextParserValue)
- break;
-
- if (!isComma(nextParserValue))
- return 0;
-
- arrayArgsParserValueList->next();
- }
-
- return arrayFunction;
-}
-
-PassRefPtr<CSSMixFunctionValue> CSSParser::parseMixFunction(CSSParserValue* value)
-{
- ASSERT(value->unit == CSSParserValue::Function && value->function);
-
- if (!equalIgnoringCase(value->function->name, "mix("))
- return 0;
-
- CSSParserValueList* argsList = value->function->args.get();
- if (!argsList)
- return 0;
-
- unsigned numArgs = argsList->size();
- if (numArgs < 1 || numArgs > 3)
- return 0;
-
- RefPtr<CSSMixFunctionValue> mixFunction = CSSMixFunctionValue::create();
-
- bool hasBlendMode = false;
- bool hasAlphaCompositing = false;
-
- for (CSSParserValue* arg = argsList->current(); arg; arg = argsList->next()) {
- RefPtr<CSSValue> value;
-
- unsigned argNumber = argsList->currentIndex();
- if (!argNumber) {
- if (arg->unit == CSSPrimitiveValue::CSS_URI) {
- KURL shaderURL = completeURL(arg->string);
- value = CSSShaderValue::create(shaderURL.string());
- }
- } else if (argNumber == 1 || argNumber == 2) {
- if (!hasBlendMode && isBlendMode(arg->id)) {
- hasBlendMode = true;
- value = cssValuePool().createIdentifierValue(arg->id);
- } else if (!hasAlphaCompositing && isCompositeOperator(arg->id)) {
- hasAlphaCompositing = true;
- value = cssValuePool().createIdentifierValue(arg->id);
- }
- }
-
- if (!value)
- return 0;
-
- mixFunction->append(value.release());
- }
-
- return mixFunction;
-}
-
-PassRefPtr<CSSValueList> CSSParser::parseCustomFilterParameters(CSSParserValueList* argsList)
-{
- //
- // params: [<param-def>[,<param-def>*]]
- // param-def: <param-name>wsp<param-value>
- // param-name: <ident>
- // param-value: true|false[wsp+true|false]{0-3} |
- // <number>[wsp+<number>]{0-3} |
- // <array> |
- // <transform> |
- // <texture(<uri>)>
- // array: 'array('<number>[wsp<number>]*')'
- // css-3d-transform: <transform-function>;[<transform-function>]*
- // transform: <css-3d-transform> | <mat>
- // mat: 'mat2('<number>(,<number>){3}')' |
- // 'mat3('<number>(,<number>){8}')' |
- // 'mat4('<number>(,<number>){15}')' )
- //
-
- RefPtr<CSSValueList> paramList = CSSValueList::createCommaSeparated();
-
- while (CSSParserValue* arg = argsList->current()) {
- if (arg->unit != CSSPrimitiveValue::CSS_IDENT)
- return 0;
-
- RefPtr<CSSValueList> parameter = CSSValueList::createSpaceSeparated();
- parameter->append(createPrimitiveStringValue(arg));
-
- arg = argsList->next();
- if (!arg)
- return 0;
-
- RefPtr<CSSValue> parameterValue;
-
- if (arg->unit == CSSParserValue::Function && arg->function) {
- // FIXME: Implement parsing for the other parameter types.
- // textures: https://bugs.webkit.org/show_bug.cgi?id=71442
- // mat2, mat3, mat4: https://bugs.webkit.org/show_bug.cgi?id=71444
- if (equalIgnoringCase(arg->function->name, "array(")) {
- parameterValue = parseCustomFilterArrayFunction(arg);
- // This parsing step only consumes function arguments,
- // argsList is therefore moved forward explicitely.
- argsList->next();
- } else
- parameterValue = parseCustomFilterTransform(argsList);
- } else {
- RefPtr<CSSValueList> paramValueList = CSSValueList::createSpaceSeparated();
- arg = argsList->current();
- while (arg) {
- // If we hit a comma, it means that we finished this parameter's values.
- if (isComma(arg))
- break;
- if (!validUnit(arg, FNumber, HTMLStandardMode))
- return 0;
- paramValueList->append(cssValuePool().createValue(arg->fValue, CSSPrimitiveValue::CSS_NUMBER));
- arg = argsList->next();
- }
- if (!paramValueList->length() || paramValueList->length() > 4)
- return 0;
- parameterValue = paramValueList.release();
- }
-
- if (!parameterValue || !acceptCommaOperator(argsList))
- return 0;
-
- parameter->append(parameterValue.release());
- paramList->append(parameter.release());
- }
-
- return paramList;
-}
-
-PassRefPtr<CSSFilterValue> CSSParser::parseCustomFilterFunctionWithAtRuleReferenceSyntax(CSSParserValue* value)
-{
- //
- // Custom filter function "at-rule reference" syntax:
- //
- // custom(<filter-name>wsp[,wsp<params>])
- //
- // filter-name: <filter-name>
- // params: See the comment in CSSParser::parseCustomFilterParameters.
- //
-
- ASSERT(value->function);
-
- CSSParserValueList* argsList = value->function->args.get();
- if (!argsList || !argsList->size())
- return 0;
-
- // 1. Parse the filter name.
- CSSParserValue* arg = argsList->current();
- if (arg->unit != CSSPrimitiveValue::CSS_IDENT)
- return 0;
-
- RefPtr<CSSFilterValue> filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation);
-
- RefPtr<CSSValue> filterName = createPrimitiveStringValue(arg);
- filterValue->append(filterName);
- argsList->next();
-
- if (!acceptCommaOperator(argsList))
- return 0;
-
- // 2. Parse the parameters.
- RefPtr<CSSValueList> paramList = parseCustomFilterParameters(argsList);
- if (!paramList)
- return 0;
-
- if (paramList->length())
- filterValue->append(paramList.release());
-
- return filterValue;
-}
-
-// FIXME: The custom filters "inline" syntax is deprecated. We will remove it eventually.
-PassRefPtr<CSSFilterValue> CSSParser::parseCustomFilterFunctionWithInlineSyntax(CSSParserValue* value)
-{
- //
- // Custom filter function "inline" syntax:
- //
- // custom(<vertex-shader>[wsp<fragment-shader>][,<vertex-mesh>][,<params>])
- //
- // vertexShader: <uri> | none
- // fragmentShader: <uri> | none | mix(<uri> [ <blend-mode> || <alpha-compositing> ]?)
- //
- // blend-mode: normal | multiply | screen | overlay | darken | lighten | color-dodge |
- // color-burn | hard-light | soft-light | difference | exclusion | hue |
- // saturation | color | luminosity
- // alpha-compositing: clear | src | dst | src-over | dst-over | src-in | dst-in |
- // src-out | dst-out | src-atop | dst-atop | xor | plus
- //
- // vertexMesh: +<integer>{1,2}[wsp<box>][wsp'detached']
- // box: filter-box | border-box | padding-box | content-box
- //
- // params: See the comment in CSSParser::parseCustomFilterParameters.
- //
-
- ASSERT(value->function);
-
- CSSParserValueList* argsList = value->function->args.get();
- if (!argsList)
- return 0;
-
- RefPtr<CSSFilterValue> filterValue = CSSFilterValue::create(CSSFilterValue::CustomFilterOperation);
-
- // 1. Parse the shader URLs: <vertex-shader>[wsp<fragment-shader>]
- RefPtr<CSSValueList> shadersList = CSSValueList::createSpaceSeparated();
- bool hadAtLeastOneCustomShader = false;
- CSSParserValue* arg;
- for (arg = argsList->current(); arg; arg = argsList->next()) {
- RefPtr<CSSValue> value;
- if (arg->id == CSSValueNone)
- value = cssValuePool().createIdentifierValue(CSSValueNone);
- else if (arg->unit == CSSPrimitiveValue::CSS_URI) {
- KURL shaderURL = completeURL(arg->string);
- value = CSSShaderValue::create(shaderURL.string());
- hadAtLeastOneCustomShader = true;
- } else if (argsList->currentIndex() == 1 && arg->unit == CSSParserValue::Function) {
- if (!(value = parseMixFunction(arg)))
- return 0;
- hadAtLeastOneCustomShader = true;
- }
-
- if (!value)
- break;
- shadersList->append(value.release());
- }
-
- if (!shadersList->length() || !hadAtLeastOneCustomShader || shadersList->length() > 2 || !acceptCommaOperator(argsList))
- return 0;
-
- filterValue->append(shadersList.release());
-
- // 2. Parse the mesh size <vertex-mesh>
- RefPtr<CSSValueList> meshSizeList = CSSValueList::createSpaceSeparated();
-
- for (arg = argsList->current(); arg; arg = argsList->next()) {
- if (!validUnit(arg, FInteger | FNonNeg, HTMLStandardMode))
- break;
- int integerValue = clampToInteger(arg->fValue);
- // According to the specification we can only accept positive non-zero values.
- if (integerValue < 1)
- return 0;
- meshSizeList->append(cssValuePool().createValue(integerValue, CSSPrimitiveValue::CSS_NUMBER));
- }
-
- if (meshSizeList->length() > 2)
- return 0;
-
- // FIXME: For legacy content, we accept the mesh box types. We don't do anything else with them.
- // Eventually, we'll remove them completely.
- // https://bugs.webkit.org/show_bug.cgi?id=103778
- if ((arg = argsList->current()) && (arg->id == CSSValueBorderBox || arg->id == CSSValuePaddingBox
- || arg->id == CSSValueContentBox || arg->id == CSSValueFilterBox))
- argsList->next();
-
- if ((arg = argsList->current()) && arg->id == CSSValueDetached) {
- meshSizeList->append(cssValuePool().createIdentifierValue(arg->id));
- argsList->next();
- }
-
- if (meshSizeList->length()) {
- if (!acceptCommaOperator(argsList))
- return 0;
- filterValue->append(meshSizeList.release());
- }
-
- // 3. Parse the parameters.
- RefPtr<CSSValueList> paramList = parseCustomFilterParameters(argsList);
- if (!paramList)
- return 0;
-
- if (paramList->length())
- filterValue->append(paramList.release());
-
- return filterValue;
-}
-
-PassRefPtr<CSSFilterValue> CSSParser::parseCustomFilterFunction(CSSParserValue* value)
-{
- ASSERT(value->function);
-
- // Look ahead to determine which syntax the custom function is using.
- // Both the at-rule reference syntax and the inline syntax require at least one argument.
- CSSParserValueList* argsList = value->function->args.get();
- if (!argsList || !argsList->size())
- return 0;
-
- // The at-rule reference syntax expects a single ident or an ident followed by a comma.
- // e.g. custom(my-filter) or custom(my-filter, ...)
- // In contrast, when the inline syntax starts with an ident like "none", it expects a uri or a mix function next.
- // e.g. custom(none url(...)) or custom(none mix(...)
- bool isAtRuleReferenceSyntax = argsList->valueAt(0)->unit == CSSPrimitiveValue::CSS_IDENT
- && (argsList->size() == 1 || isComma(argsList->valueAt(1)));
- return isAtRuleReferenceSyntax ? parseCustomFilterFunctionWithAtRuleReferenceSyntax(value) : parseCustomFilterFunctionWithInlineSyntax(value);
-}
-
-PassRefPtr<CSSValueList> CSSParser::parseCustomFilterTransform(CSSParserValueList* valueList)
-{
- if (!valueList)
- return 0;
-
- // CSS Shaders' custom() transforms are space separated and comma terminated.
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- for (CSSParserValue* value = valueList->current(); value; value = valueList->next()) {
- if (isComma(value))
- break;
-
- RefPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
- if (!parsedTransformValue)
- return 0;
-
- list->append(parsedTransformValue.release());
- }
-
- return list.release();
-}
-
-PassRefPtr<CSSShaderValue> CSSParser::parseFilterRuleSrcUriAndFormat(CSSParserValueList* valueList)
-{
- CSSParserValue* value = valueList->current();
- ASSERT(value && value->unit == CSSPrimitiveValue::CSS_URI);
- RefPtr<CSSShaderValue> shaderValue = CSSShaderValue::create(completeURL(value->string));
-
- value = valueList->next();
- if (value && value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "format(")) {
- CSSParserValueList* args = value->function->args.get();
- if (!args || args->size() != 1)
- return 0;
-
- CSSParserValue* arg = args->current();
- if (arg->unit != CSSPrimitiveValue::CSS_STRING)
- return 0;
-
- shaderValue->setFormat(arg->string);
- valueList->next();
- }
-
- return shaderValue.release();
-}
-
-bool CSSParser::parseFilterRuleSrc()
-{
- RefPtr<CSSValueList> srcList = CSSValueList::createCommaSeparated();
-
- CSSParserValue* value = m_valueList->current();
- while (value) {
- if (value->unit != CSSPrimitiveValue::CSS_URI)
- return false;
-
- RefPtr<CSSShaderValue> shaderValue = parseFilterRuleSrcUriAndFormat(m_valueList.get());
- if (!shaderValue)
- return false;
- srcList->append(shaderValue.release());
-
- if (!acceptCommaOperator(m_valueList.get()))
- return false;
-
- value = m_valueList->current();
- }
-
- if (!srcList->length())
- return false;
-
- addProperty(CSSPropertySrc, srcList.release(), m_important);
- return true;
-}
-
-StyleRuleBase* CSSParser::createFilterRule(const CSSParserString& filterName)
-{
- RefPtr<StyleRuleFilter> rule = StyleRuleFilter::create(filterName);
- rule->setProperties(createStylePropertySet());
- clearProperties();
- StyleRuleFilter* result = rule.get();
- m_parsedRules.append(rule.release());
- return result;
-}
-
-
-PassRefPtr<CSSFilterValue> CSSParser::parseBuiltinFilterArguments(CSSParserValueList* args, CSSFilterValue::FilterOperationType filterType)
-{
- RefPtr<CSSFilterValue> filterValue = CSSFilterValue::create(filterType);
- ASSERT(args);
-
- switch (filterType) {
- case CSSFilterValue::GrayscaleFilterOperation:
- case CSSFilterValue::SepiaFilterOperation:
- case CSSFilterValue::SaturateFilterOperation:
- case CSSFilterValue::InvertFilterOperation:
- case CSSFilterValue::OpacityFilterOperation:
- case CSSFilterValue::ContrastFilterOperation: {
- // One optional argument, 0-1 or 0%-100%, if missing use 100%.
- if (args->size() > 1)
- return 0;
-
- if (args->size()) {
- CSSParserValue* value = args->current();
- if (!validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode))
- return 0;
-
- double amount = value->fValue;
-
- // Saturate and Contrast allow values over 100%.
- if (filterType != CSSFilterValue::SaturateFilterOperation
- && filterType != CSSFilterValue::ContrastFilterOperation) {
- double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
- if (amount > maxAllowed)
- return 0;
- }
-
- filterValue->append(cssValuePool().createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
- }
- break;
- }
- case CSSFilterValue::BrightnessFilterOperation: {
- // One optional argument, if missing use 100%.
- if (args->size() > 1)
- return 0;
-
- if (args->size()) {
- CSSParserValue* value = args->current();
- if (!validUnit(value, FNumber | FPercent, HTMLStandardMode))
- return 0;
-
- filterValue->append(cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
- }
- break;
- }
- case CSSFilterValue::HueRotateFilterOperation: {
- // hue-rotate() takes one optional angle.
- if (args->size() > 1)
- return 0;
-
- if (args->size()) {
- CSSParserValue* argument = args->current();
- if (!validUnit(argument, FAngle, HTMLStandardMode))
- return 0;
-
- filterValue->append(createPrimitiveNumericValue(argument));
- }
- break;
- }
- case CSSFilterValue::BlurFilterOperation: {
- // Blur takes a single length. Zero parameters are allowed.
- if (args->size() > 1)
- return 0;
-
- if (args->size()) {
- CSSParserValue* argument = args->current();
- if (!validUnit(argument, FLength | FNonNeg, HTMLStandardMode))
- return 0;
-
- filterValue->append(createPrimitiveNumericValue(argument));
- }
- break;
- }
- case CSSFilterValue::DropShadowFilterOperation: {
- // drop-shadow() takes a single shadow.
- RefPtr<CSSValueList> shadowValueList = parseShadow(args, CSSPropertyWebkitFilter);
- if (!shadowValueList || shadowValueList->length() != 1)
- return 0;
-
- filterValue->append((shadowValueList.release())->itemWithoutBoundsCheck(0));
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- }
- return filterValue.release();
-}
-
-PassRefPtr<CSSValueList> CSSParser::parseFilter()
-{
- if (!m_valueList)
- return 0;
-
- // The filter is a list of functional primitives that specify individual operations.
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
- if (value->unit != CSSPrimitiveValue::CSS_URI && (value->unit != CSSParserValue::Function || !value->function))
- return 0;
-
- CSSFilterValue::FilterOperationType filterType = CSSFilterValue::UnknownFilterOperation;
-
- // See if the specified primitive is one we understand.
- if (value->unit == CSSPrimitiveValue::CSS_URI) {
- RefPtr<CSSFilterValue> referenceFilterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
- list->append(referenceFilterValue);
- referenceFilterValue->append(CSSSVGDocumentValue::create(value->string));
- } else {
- const CSSParserString name = value->function->name;
- unsigned maximumArgumentCount = 1;
-
- filterInfoForName(name, filterType, maximumArgumentCount);
-
- if (filterType == CSSFilterValue::UnknownFilterOperation)
- return 0;
-
- if (filterType == CSSFilterValue::CustomFilterOperation) {
- // Make sure parsing fails if custom filters are disabled.
- if (!RuntimeEnabledFeatures::cssCustomFilterEnabled())
- return 0;
-
- RefPtr<CSSFilterValue> filterValue = parseCustomFilterFunction(value);
- if (!filterValue)
- return 0;
- list->append(filterValue.release());
- continue;
- }
- CSSParserValueList* args = value->function->args.get();
- if (!args)
- return 0;
-
- RefPtr<CSSFilterValue> filterValue = parseBuiltinFilterArguments(args, filterType);
- if (!filterValue)
- return 0;
-
- list->append(filterValue);
- }
- }
-
- return list.release();
-}
-
-static bool validFlowName(const String& flowName)
-{
- return !(equalIgnoringCase(flowName, "auto")
- || equalIgnoringCase(flowName, "default")
- || equalIgnoringCase(flowName, "inherit")
- || equalIgnoringCase(flowName, "initial")
- || equalIgnoringCase(flowName, "none"));
-}
-
-bool CSSParser::parseFlowThread(const String& flowName)
-{
- setupParser("@-internal-decls -webkit-flow-into:", flowName, "");
- cssyyparse(this);
-
- m_rule = 0;
-
- return ((m_parsedProperties.size() == 1) && (m_parsedProperties.first().id() == CSSPropertyWebkitFlowInto));
-}
-
-// none | <ident>
-bool CSSParser::parseFlowThread(CSSPropertyID propId, bool important)
-{
- ASSERT(propId == CSSPropertyWebkitFlowInto);
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
-
- if (m_valueList->size() != 1)
- return false;
-
- CSSParserValue* value = m_valueList->current();
- if (!value)
- return false;
-
- if (value->unit != CSSPrimitiveValue::CSS_IDENT)
- return false;
-
- if (value->id == CSSValueNone) {
- addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
- return true;
- }
-
- String inputProperty = String(value->string);
- if (!inputProperty.isEmpty()) {
- if (!validFlowName(inputProperty))
- return false;
- addProperty(propId, cssValuePool().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important);
- } else
- addProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important);
-
- return true;
-}
-
-// -webkit-flow-from: none | <ident>
-bool CSSParser::parseRegionThread(CSSPropertyID propId, bool important)
-{
- ASSERT(propId == CSSPropertyWebkitFlowFrom);
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
-
- if (m_valueList->size() != 1)
- return false;
-
- CSSParserValue* value = m_valueList->current();
- if (!value)
- return false;
-
- if (value->unit != CSSPrimitiveValue::CSS_IDENT)
- return false;
-
- if (value->id == CSSValueNone)
- addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
- else {
- String inputProperty = String(value->string);
- if (!inputProperty.isEmpty()) {
- if (!validFlowName(inputProperty))
- return false;
- addProperty(propId, cssValuePool().createValue(inputProperty, CSSPrimitiveValue::CSS_STRING), important);
- } else
- addProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important);
- }
-
- return true;
-}
-
-bool CSSParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3)
-{
- propId1 = propId;
- propId2 = propId;
- propId3 = propId;
- if (propId == CSSPropertyWebkitTransformOrigin) {
- propId1 = CSSPropertyWebkitTransformOriginX;
- propId2 = CSSPropertyWebkitTransformOriginY;
- propId3 = CSSPropertyWebkitTransformOriginZ;
- }
-
- switch (propId) {
- case CSSPropertyWebkitTransformOrigin:
- if (!parseTransformOriginShorthand(value, value2, value3))
- return false;
- // parseTransformOriginShorthand advances the m_valueList pointer
- break;
- case CSSPropertyWebkitTransformOriginX: {
- value = parseFillPositionX(m_valueList.get());
- if (value)
- m_valueList->next();
- break;
- }
- case CSSPropertyWebkitTransformOriginY: {
- value = parseFillPositionY(m_valueList.get());
- if (value)
- m_valueList->next();
- break;
- }
- case CSSPropertyWebkitTransformOriginZ: {
- if (validUnit(m_valueList->current(), FLength))
- value = createPrimitiveNumericValue(m_valueList->current());
- if (value)
- m_valueList->next();
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
-
- return value;
-}
-
-bool CSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2)
-{
- propId1 = propId;
- propId2 = propId;
- if (propId == CSSPropertyWebkitPerspectiveOrigin) {
- propId1 = CSSPropertyWebkitPerspectiveOriginX;
- propId2 = CSSPropertyWebkitPerspectiveOriginY;
- }
-
- switch (propId) {
- case CSSPropertyWebkitPerspectiveOrigin:
- if (m_valueList->size() > 2)
- return false;
- parse2ValuesFillPosition(m_valueList.get(), value, value2);
- break;
- case CSSPropertyWebkitPerspectiveOriginX: {
- value = parseFillPositionX(m_valueList.get());
- if (value)
- m_valueList->next();
- break;
- }
- case CSSPropertyWebkitPerspectiveOriginY: {
- value = parseFillPositionY(m_valueList.get());
- if (value)
- m_valueList->next();
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- return false;
- }
-
- return value;
-}
-
-bool CSSParser::parseTouchAction(bool important)
-{
- if (!RuntimeEnabledFeatures::cssTouchActionEnabled())
- return false;
-
- CSSParserValue* value = m_valueList->current();
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- if (m_valueList->size() == 1 && value && (value->id == CSSValueAuto || value->id == CSSValueNone)) {
- list->append(cssValuePool().createIdentifierValue(value->id));
- addProperty(CSSPropertyTouchAction, list.release(), important);
- m_valueList->next();
- return true;
- }
-
- bool isValid = true;
- while (isValid && value) {
- switch (value->id) {
- case CSSValuePanX:
- case CSSValuePanY: {
- RefPtr<CSSValue> panValue = cssValuePool().createIdentifierValue(value->id);
- if (list->hasValue(panValue.get())) {
- isValid = false;
- break;
- }
- list->append(panValue.release());
- break;
- }
- default:
- isValid = false;
- break;
- }
- if (isValid)
- value = m_valueList->next();
- }
-
- if (list->length() && isValid) {
- addProperty(CSSPropertyTouchAction, list.release(), important);
- return true;
- }
-
- return false;
-}
-
-void CSSParser::addTextDecorationProperty(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important)
-{
- // The text-decoration-line property takes priority over text-decoration, unless the latter has important priority set.
- if (propId == CSSPropertyTextDecoration && !important && !inShorthand()) {
- for (unsigned i = 0; i < m_parsedProperties.size(); ++i) {
- if (m_parsedProperties[i].id() == CSSPropertyTextDecorationLine)
- return;
- }
- }
- addProperty(propId, value, important);
-}
-
-bool CSSParser::parseTextDecoration(CSSPropertyID propId, bool important)
-{
- if (propId == CSSPropertyTextDecorationLine
- && !RuntimeEnabledFeatures::css3TextDecorationsEnabled())
- return false;
-
- CSSParserValue* value = m_valueList->current();
- if (value && value->id == CSSValueNone) {
- addTextDecorationProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important);
- m_valueList->next();
- return true;
- }
-
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
- bool isValid = true;
- while (isValid && value) {
- switch (value->id) {
- case CSSValueUnderline:
- case CSSValueOverline:
- case CSSValueLineThrough:
- case CSSValueBlink:
- list->append(cssValuePool().createIdentifierValue(value->id));
- break;
- default:
- isValid = false;
- break;
- }
- if (isValid)
- value = m_valueList->next();
- }
-
- // Values are either valid or in shorthand scope.
- if (list->length() && (isValid || inShorthand())) {
- addTextDecorationProperty(propId, list.release(), important);
- return true;
- }
-
- return false;
-}
-
-bool CSSParser::parseTextUnderlinePosition(bool important)
-{
- // The text-underline-position property has syntax "auto | [ under || [ left | right ] ]".
- // However, values 'left' and 'right' are not implemented yet, so we will parse syntax
- // "auto | under" for now.
- CSSParserValue* value = m_valueList->current();
- switch (value->id) {
- case CSSValueAuto:
- case CSSValueUnder:
- if (m_valueList->next())
- return false;
- addProperty(CSSPropertyTextUnderlinePosition, cssValuePool().createIdentifierValue(value->id), important);
- return true;
- default:
- return false;
- }
-}
-
-bool CSSParser::parseTextEmphasisStyle(bool important)
-{
- unsigned valueListSize = m_valueList->size();
-
- RefPtr<CSSPrimitiveValue> fill;
- RefPtr<CSSPrimitiveValue> shape;
-
- for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
- if (value->unit == CSSPrimitiveValue::CSS_STRING) {
- if (fill || shape || (valueListSize != 1 && !inShorthand()))
- return false;
- addProperty(CSSPropertyWebkitTextEmphasisStyle, createPrimitiveStringValue(value), important);
- m_valueList->next();
- return true;
- }
-
- if (value->id == CSSValueNone) {
- if (fill || shape || (valueListSize != 1 && !inShorthand()))
- return false;
- addProperty(CSSPropertyWebkitTextEmphasisStyle, cssValuePool().createIdentifierValue(CSSValueNone), important);
- m_valueList->next();
- return true;
- }
-
- if (value->id == CSSValueOpen || value->id == CSSValueFilled) {
- if (fill)
- return false;
- fill = cssValuePool().createIdentifierValue(value->id);
- } else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) {
- if (shape)
- return false;
- shape = cssValuePool().createIdentifierValue(value->id);
- } else if (!inShorthand())
- return false;
- else
- break;
- }
-
- if (fill && shape) {
- RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
- parsedValues->append(fill.release());
- parsedValues->append(shape.release());
- addProperty(CSSPropertyWebkitTextEmphasisStyle, parsedValues.release(), important);
- return true;
- }
- if (fill) {
- addProperty(CSSPropertyWebkitTextEmphasisStyle, fill.release(), important);
- return true;
- }
- if (shape) {
- addProperty(CSSPropertyWebkitTextEmphasisStyle, shape.release(), important);
- return true;
- }
-
- return false;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseTextIndent()
-{
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-
- // <length> | <percentage> | inherit
- if (m_valueList->size() == 1) {
- CSSParserValue* value = m_valueList->current();
- if (!value->id && validUnit(value, FLength | FPercent)) {
- list->append(createPrimitiveNumericValue(value));
- m_valueList->next();
- return list.release();
- }
- }
-
- if (!RuntimeEnabledFeatures::css3TextEnabled())
- return 0;
-
- // The case where text-indent has only <length>(or <percentage>) value
- // is handled above if statement even though css3TextEnabled() returns true.
-
- // [ [ <length> | <percentage> ] && each-line ] | inherit
- if (m_valueList->size() != 2)
- return 0;
-
- CSSParserValue* firstValue = m_valueList->current();
- CSSParserValue* secondValue = m_valueList->next();
- CSSParserValue* lengthOrPercentageValue = 0;
-
- // [ <length> | <percentage> ] each-line
- if (validUnit(firstValue, FLength | FPercent) && secondValue->id == CSSValueEachLine)
- lengthOrPercentageValue = firstValue;
- // each-line [ <length> | <percentage> ]
- else if (firstValue->id == CSSValueEachLine && validUnit(secondValue, FLength | FPercent))
- lengthOrPercentageValue = secondValue;
-
- if (lengthOrPercentageValue) {
- list->append(createPrimitiveNumericValue(lengthOrPercentageValue));
- list->append(cssValuePool().createIdentifierValue(CSSValueEachLine));
- m_valueList->next();
- return list.release();
- }
-
- return 0;
-}
-
-bool CSSParser::parseLineBoxContain(bool important)
-{
- LineBoxContain lineBoxContain = LineBoxContainNone;
-
- for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
- if (value->id == CSSValueBlock) {
- if (lineBoxContain & LineBoxContainBlock)
- return false;
- lineBoxContain |= LineBoxContainBlock;
- } else if (value->id == CSSValueInline) {
- if (lineBoxContain & LineBoxContainInline)
- return false;
- lineBoxContain |= LineBoxContainInline;
- } else if (value->id == CSSValueFont) {
- if (lineBoxContain & LineBoxContainFont)
- return false;
- lineBoxContain |= LineBoxContainFont;
- } else if (value->id == CSSValueGlyphs) {
- if (lineBoxContain & LineBoxContainGlyphs)
- return false;
- lineBoxContain |= LineBoxContainGlyphs;
- } else if (value->id == CSSValueReplaced) {
- if (lineBoxContain & LineBoxContainReplaced)
- return false;
- lineBoxContain |= LineBoxContainReplaced;
- } else if (value->id == CSSValueInlineBox) {
- if (lineBoxContain & LineBoxContainInlineBox)
- return false;
- lineBoxContain |= LineBoxContainInlineBox;
- } else
- return false;
- }
-
- if (!lineBoxContain)
- return false;
-
- addProperty(CSSPropertyWebkitLineBoxContain, CSSLineBoxContainValue::create(lineBoxContain), important);
- return true;
-}
-
-bool CSSParser::parseFontFeatureTag(CSSValueList* settings)
-{
- // Feature tag name consists of 4-letter characters.
- static const unsigned tagNameLength = 4;
-
- CSSParserValue* value = m_valueList->current();
- // Feature tag name comes first
- if (value->unit != CSSPrimitiveValue::CSS_STRING)
- return false;
- if (value->string.length() != tagNameLength)
- return false;
- for (unsigned i = 0; i < tagNameLength; ++i) {
- // Limits the range of characters to 0x20-0x7E, following the tag name rules defiend in the OpenType specification.
- UChar character = value->string[i];
- if (character < 0x20 || character > 0x7E)
- return false;
- }
-
- AtomicString tag = value->string;
- int tagValue = 1;
- // Feature tag values could follow: <integer> | on | off
- value = m_valueList->next();
- if (value) {
- if (value->unit == CSSPrimitiveValue::CSS_NUMBER && value->isInt && value->fValue >= 0) {
- tagValue = clampToInteger(value->fValue);
- if (tagValue < 0)
- return false;
- m_valueList->next();
- } else if (value->id == CSSValueOn || value->id == CSSValueOff) {
- tagValue = value->id == CSSValueOn;
- m_valueList->next();
- }
- }
- settings->append(CSSFontFeatureValue::create(tag, tagValue));
- return true;
-}
-
-bool CSSParser::parseFontFeatureSettings(bool important)
-{
- if (m_valueList->size() == 1 && m_valueList->current()->id == CSSValueNormal) {
- RefPtr<CSSPrimitiveValue> normalValue = cssValuePool().createIdentifierValue(CSSValueNormal);
- m_valueList->next();
- addProperty(CSSPropertyWebkitFontFeatureSettings, normalValue.release(), important);
- return true;
- }
-
- RefPtr<CSSValueList> settings = CSSValueList::createCommaSeparated();
- for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
- if (!parseFontFeatureTag(settings.get()))
- return false;
-
- // If the list isn't parsed fully, the current value should be comma.
- value = m_valueList->current();
- if (value && !isComma(value))
- return false;
- }
- if (settings->length()) {
- addProperty(CSSPropertyWebkitFontFeatureSettings, settings.release(), important);
- return true;
- }
- return false;
-}
-
-bool CSSParser::parseFontVariantLigatures(bool important)
-{
- RefPtr<CSSValueList> ligatureValues = CSSValueList::createSpaceSeparated();
- bool sawCommonLigaturesValue = false;
- bool sawDiscretionaryLigaturesValue = false;
- bool sawHistoricalLigaturesValue = false;
-
- for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
- if (value->unit != CSSPrimitiveValue::CSS_IDENT)
- return false;
-
- switch (value->id) {
- case CSSValueNoCommonLigatures:
- case CSSValueCommonLigatures:
- if (sawCommonLigaturesValue)
- return false;
- sawCommonLigaturesValue = true;
- ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
- break;
- case CSSValueNoDiscretionaryLigatures:
- case CSSValueDiscretionaryLigatures:
- if (sawDiscretionaryLigaturesValue)
- return false;
- sawDiscretionaryLigaturesValue = true;
- ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
- break;
- case CSSValueNoHistoricalLigatures:
- case CSSValueHistoricalLigatures:
- if (sawHistoricalLigaturesValue)
- return false;
- sawHistoricalLigaturesValue = true;
- ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
- break;
- default:
- return false;
- }
- }
-
- if (!ligatureValues->length())
- return false;
-
- addProperty(CSSPropertyWebkitFontVariantLigatures, ligatureValues.release(), important);
- return true;
-}
-
-bool CSSParser::parseCalculation(CSSParserValue* value, ValueRange range)
-{
- ASSERT(isCalculation(value));
-
- CSSParserValueList* args = value->function->args.get();
- if (!args || !args->size())
- return false;
-
- ASSERT(!m_parsedCalculation);
- m_parsedCalculation = CSSCalcValue::create(value->function->name, args, range);
-
- if (!m_parsedCalculation)
- return false;
-
- return true;
-}
-
-#define END_TOKEN 0
-
-void CSSParser::ensureLineEndings()
-{
- if (!m_lineEndings)
- m_lineEndings = lineEndings(*m_source);
-}
-
-CSSParserSelector* CSSParser::createFloatingSelectorWithTagName(const QualifiedName& tagQName)
-{
- CSSParserSelector* selector = new CSSParserSelector(tagQName);
- m_floatingSelectors.append(selector);
- return selector;
-}
-
-CSSParserSelector* CSSParser::createFloatingSelector()
-{
- CSSParserSelector* selector = new CSSParserSelector;
- m_floatingSelectors.append(selector);
- return selector;
-}
-
-PassOwnPtr<CSSParserSelector> CSSParser::sinkFloatingSelector(CSSParserSelector* selector)
-{
- if (selector) {
- size_t index = m_floatingSelectors.reverseFind(selector);
- ASSERT(index != kNotFound);
- m_floatingSelectors.remove(index);
- }
- return adoptPtr(selector);
-}
-
-Vector<OwnPtr<CSSParserSelector> >* CSSParser::createFloatingSelectorVector()
-{
- Vector<OwnPtr<CSSParserSelector> >* selectorVector = new Vector<OwnPtr<CSSParserSelector> >;
- m_floatingSelectorVectors.append(selectorVector);
- return selectorVector;
-}
-
-PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > CSSParser::sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectorVector)
-{
- if (selectorVector) {
- size_t index = m_floatingSelectorVectors.reverseFind(selectorVector);
- ASSERT(index != kNotFound);
- m_floatingSelectorVectors.remove(index);
- }
- return adoptPtr(selectorVector);
-}
-
-CSSParserValueList* CSSParser::createFloatingValueList()
-{
- CSSParserValueList* list = new CSSParserValueList;
- m_floatingValueLists.append(list);
- return list;
-}
-
-PassOwnPtr<CSSParserValueList> CSSParser::sinkFloatingValueList(CSSParserValueList* list)
-{
- if (list) {
- size_t index = m_floatingValueLists.reverseFind(list);
- ASSERT(index != kNotFound);
- m_floatingValueLists.remove(index);
- }
- return adoptPtr(list);
-}
-
-CSSParserFunction* CSSParser::createFloatingFunction()
-{
- CSSParserFunction* function = new CSSParserFunction;
- m_floatingFunctions.append(function);
- return function;
-}
-
-CSSParserFunction* CSSParser::createFloatingFunction(const CSSParserString& name, PassOwnPtr<CSSParserValueList> args)
-{
- CSSParserFunction* function = createFloatingFunction();
- function->name = name;
- function->args = args;
- return function;
-}
-
-PassOwnPtr<CSSParserFunction> CSSParser::sinkFloatingFunction(CSSParserFunction* function)
-{
- if (function) {
- size_t index = m_floatingFunctions.reverseFind(function);
- ASSERT(index != kNotFound);
- m_floatingFunctions.remove(index);
- }
- return adoptPtr(function);
-}
-
-CSSParserValue& CSSParser::sinkFloatingValue(CSSParserValue& value)
-{
- if (value.unit == CSSParserValue::Function) {
- size_t index = m_floatingFunctions.reverseFind(value.function);
- ASSERT(index != kNotFound);
- m_floatingFunctions.remove(index);
- }
- return value;
-}
-
-MediaQueryExp* CSSParser::createFloatingMediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values)
-{
- m_floatingMediaQueryExp = MediaQueryExp::create(mediaFeature, values);
- return m_floatingMediaQueryExp.get();
-}
-
-PassOwnPtr<MediaQueryExp> CSSParser::sinkFloatingMediaQueryExp(MediaQueryExp* expression)
-{
- ASSERT_UNUSED(expression, expression == m_floatingMediaQueryExp);
- return m_floatingMediaQueryExp.release();
-}
-
-Vector<OwnPtr<MediaQueryExp> >* CSSParser::createFloatingMediaQueryExpList()
-{
- m_floatingMediaQueryExpList = adoptPtr(new Vector<OwnPtr<MediaQueryExp> >);
- return m_floatingMediaQueryExpList.get();
-}
-
-PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > CSSParser::sinkFloatingMediaQueryExpList(Vector<OwnPtr<MediaQueryExp> >* list)
-{
- ASSERT_UNUSED(list, list == m_floatingMediaQueryExpList);
- return m_floatingMediaQueryExpList.release();
-}
-
-MediaQuery* CSSParser::createFloatingMediaQuery(MediaQuery::Restrictor restrictor, const AtomicString& mediaType, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > expressions)
-{
- m_floatingMediaQuery = adoptPtr(new MediaQuery(restrictor, mediaType, expressions));
- return m_floatingMediaQuery.get();
-}
-
-MediaQuery* CSSParser::createFloatingMediaQuery(PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > expressions)
-{
- return createFloatingMediaQuery(MediaQuery::None, AtomicString("all", AtomicString::ConstructFromLiteral), expressions);
-}
-
-MediaQuery* CSSParser::createFloatingNotAllQuery()
-{
- return createFloatingMediaQuery(MediaQuery::Not, AtomicString("all", AtomicString::ConstructFromLiteral), sinkFloatingMediaQueryExpList(createFloatingMediaQueryExpList()));
-}
-
-PassOwnPtr<MediaQuery> CSSParser::sinkFloatingMediaQuery(MediaQuery* query)
-{
- ASSERT_UNUSED(query, query == m_floatingMediaQuery);
- return m_floatingMediaQuery.release();
-}
-
-Vector<RefPtr<StyleKeyframe> >* CSSParser::createFloatingKeyframeVector()
-{
- m_floatingKeyframeVector = adoptPtr(new Vector<RefPtr<StyleKeyframe> >());
- return m_floatingKeyframeVector.get();
-}
-
-PassOwnPtr<Vector<RefPtr<StyleKeyframe> > > CSSParser::sinkFloatingKeyframeVector(Vector<RefPtr<StyleKeyframe> >* keyframeVector)
-{
- ASSERT_UNUSED(keyframeVector, m_floatingKeyframeVector == keyframeVector);
- return m_floatingKeyframeVector.release();
-}
-
-MediaQuerySet* CSSParser::createMediaQuerySet()
-{
- RefPtr<MediaQuerySet> queries = MediaQuerySet::create();
- MediaQuerySet* result = queries.get();
- m_parsedMediaQuerySets.append(queries.release());
- return result;
-}
-
-StyleRuleBase* CSSParser::createImportRule(const CSSParserString& url, MediaQuerySet* media)
-{
- if (!media || !m_allowImportRules)
- return 0;
- RefPtr<StyleRuleImport> rule = StyleRuleImport::create(url, media);
- StyleRuleImport* result = rule.get();
- m_parsedRules.append(rule.release());
- return result;
-}
-
-StyleRuleBase* CSSParser::createMediaRule(MediaQuerySet* media, RuleList* rules)
-{
- m_allowImportRules = m_allowNamespaceDeclarations = false;
- RefPtr<StyleRuleMedia> rule;
- if (rules) {
- rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create(), *rules);
- } else {
- RuleList emptyRules;
- rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create(), emptyRules);
- }
- StyleRuleMedia* result = rule.get();
- m_parsedRules.append(rule.release());
- return result;
-}
-
-StyleRuleBase* CSSParser::createSupportsRule(bool conditionIsSupported, RuleList* rules)
-{
- m_allowImportRules = m_allowNamespaceDeclarations = false;
-
- RefPtr<CSSRuleSourceData> data = popSupportsRuleData();
- RefPtr<StyleRuleSupports> rule;
- String conditionText;
- unsigned conditionOffset = data->ruleHeaderRange.start + 9;
- unsigned conditionLength = data->ruleHeaderRange.length() - 9;
-
- if (m_tokenizer.is8BitSource())
- conditionText = String(m_tokenizer.m_dataStart8.get() + conditionOffset, conditionLength).stripWhiteSpace();
- else
- conditionText = String(m_tokenizer.m_dataStart16.get() + conditionOffset, conditionLength).stripWhiteSpace();
-
- if (rules) {
- rule = StyleRuleSupports::create(conditionText, conditionIsSupported, *rules);
- } else {
- RuleList emptyRules;
- rule = StyleRuleSupports::create(conditionText, conditionIsSupported, emptyRules);
- }
-
- StyleRuleSupports* result = rule.get();
- m_parsedRules.append(rule.release());
-
- return result;
-}
-
-void CSSParser::markSupportsRuleHeaderStart()
-{
- if (!m_supportsRuleDataStack)
- m_supportsRuleDataStack = adoptPtr(new RuleSourceDataList());
-
- RefPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
- data->ruleHeaderRange.start = m_tokenizer.tokenStartOffset();
- m_supportsRuleDataStack->append(data);
-}
-
-void CSSParser::markSupportsRuleHeaderEnd()
-{
- ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty());
-
- if (m_tokenizer.is8BitSource())
- m_supportsRuleDataStack->last()->ruleHeaderRange.end = m_tokenizer.tokenStart<LChar>() - m_tokenizer.m_dataStart8.get();
- else
- m_supportsRuleDataStack->last()->ruleHeaderRange.end = m_tokenizer.tokenStart<UChar>() - m_tokenizer.m_dataStart16.get();
-}
-
-PassRefPtr<CSSRuleSourceData> CSSParser::popSupportsRuleData()
-{
- ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty());
- RefPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
- m_supportsRuleDataStack->removeLast();
- return data.release();
-}
-
-CSSParser::RuleList* CSSParser::createRuleList()
-{
- OwnPtr<RuleList> list = adoptPtr(new RuleList);
- RuleList* listPtr = list.get();
-
- m_parsedRuleLists.append(list.release());
- return listPtr;
-}
-
-CSSParser::RuleList* CSSParser::appendRule(RuleList* ruleList, StyleRuleBase* rule)
-{
- if (rule) {
- if (!ruleList)
- ruleList = createRuleList();
- ruleList->append(rule);
- }
- return ruleList;
-}
-
-template <typename CharacterType>
-ALWAYS_INLINE static void makeLower(const CharacterType* input, CharacterType* output, unsigned length)
-{
- // FIXME: If we need Unicode lowercasing here, then we probably want the real kind
- // that can potentially change the length of the string rather than the character
- // by character kind. If we don't need Unicode lowercasing, it would be good to
- // simplify this function.
-
- if (charactersAreAllASCII(input, length)) {
- // Fast case for all-ASCII.
- for (unsigned i = 0; i < length; i++)
- output[i] = toASCIILower(input[i]);
- } else {
- for (unsigned i = 0; i < length; i++)
- output[i] = Unicode::toLower(input[i]);
- }
-}
-
-void CSSParser::tokenToLowerCase(const CSSParserString& token)
-{
- size_t length = token.length();
- if (m_tokenizer.is8BitSource()) {
- size_t offset = token.characters8() - m_tokenizer.m_dataStart8.get();
- makeLower(token.characters8(), m_tokenizer.m_dataStart8.get() + offset, length);
- } else {
- size_t offset = token.characters16() - m_tokenizer.m_dataStart16.get();
- makeLower(token.characters16(), m_tokenizer.m_dataStart16.get() + offset, length);
- }
-}
-
-void CSSParser::endInvalidRuleHeader()
-{
- if (m_ruleHeaderType == CSSRuleSourceData::UNKNOWN_RULE)
- return;
-
- CSSParserLocation location;
- location.lineNumber = m_tokenizer.m_lineNumber;
- location.offset = m_ruleHeaderStartOffset;
- if (m_tokenizer.is8BitSource())
- location.token.init(m_tokenizer.m_dataStart8.get() + m_ruleHeaderStartOffset, 0);
- else
- location.token.init(m_tokenizer.m_dataStart16.get() + m_ruleHeaderStartOffset, 0);
-
- reportError(location, m_ruleHeaderType == CSSRuleSourceData::STYLE_RULE ? InvalidSelectorError : InvalidRuleError);
-
- endRuleHeader();
-}
-
-void CSSParser::reportError(const CSSParserLocation&, ErrorType)
-{
- // FIXME: error reporting temporatily disabled.
-}
-
-bool CSSParser::isLoggingErrors()
-{
- return m_logErrors && !m_ignoreErrors;
-}
-
-void CSSParser::logError(const String& message, const CSSParserLocation& location)
-{
- unsigned lineNumberInStyleSheet;
- unsigned columnNumber = 0;
- PageConsole& console = m_styleSheet->singleOwnerDocument()->page()->console();
- if (InspectorInstrumentation::hasFrontends()) {
- ensureLineEndings();
- TextPosition tokenPosition = TextPosition::fromOffsetAndLineEndings(location.offset, *m_lineEndings);
- lineNumberInStyleSheet = tokenPosition.m_line.zeroBasedInt();
- columnNumber = (lineNumberInStyleSheet ? 0 : m_startPosition.m_column.zeroBasedInt()) + tokenPosition.m_column.zeroBasedInt();
- } else {
- lineNumberInStyleSheet = location.lineNumber;
- }
- console.addMessage(CSSMessageSource, WarningMessageLevel, message, m_styleSheet->baseURL().string(), lineNumberInStyleSheet + m_startPosition.m_line.zeroBasedInt() + 1, columnNumber + 1);
-}
-
-StyleRuleKeyframes* CSSParser::createKeyframesRule(const String& name, PassOwnPtr<Vector<RefPtr<StyleKeyframe> > > popKeyframes, bool isPrefixed)
-{
- OwnPtr<Vector<RefPtr<StyleKeyframe> > > keyframes = popKeyframes;
- m_allowImportRules = m_allowNamespaceDeclarations = false;
- RefPtr<StyleRuleKeyframes> rule = StyleRuleKeyframes::create();
- for (size_t i = 0; i < keyframes->size(); ++i)
- rule->parserAppendKeyframe(keyframes->at(i));
- rule->setName(name);
- rule->setVendorPrefixed(isPrefixed);
- StyleRuleKeyframes* rulePtr = rule.get();
- m_parsedRules.append(rule.release());
- return rulePtr;
-}
-
-StyleRuleBase* CSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors)
-{
- StyleRule* result = 0;
- if (selectors) {
- m_allowImportRules = m_allowNamespaceDeclarations = false;
- RefPtr<StyleRule> rule = StyleRule::create();
- rule->parserAdoptSelectorVector(*selectors);
- if (m_hasFontFaceOnlyValues)
- deleteFontFaceOnlyValues();
- rule->setProperties(createStylePropertySet());
- result = rule.get();
- m_parsedRules.append(rule.release());
- }
- clearProperties();
- return result;
-}
-
-StyleRuleBase* CSSParser::createFontFaceRule()
-{
- m_allowImportRules = m_allowNamespaceDeclarations = false;
- for (unsigned i = 0; i < m_parsedProperties.size(); ++i) {
- CSSProperty& property = m_parsedProperties[i];
- if (property.id() == CSSPropertyFontVariant && property.value()->isPrimitiveValue())
- property.wrapValueInCommaSeparatedList();
- else if (property.id() == CSSPropertyFontFamily && (!property.value()->isValueList() || toCSSValueList(property.value())->length() != 1)) {
- // Unlike font-family property, font-family descriptor in @font-face rule
- // has to be a value list with exactly one family name. It cannot have a
- // have 'initial' value and cannot 'inherit' from parent.
- // See http://dev.w3.org/csswg/css3-fonts/#font-family-desc
- clearProperties();
- return 0;
- }
- }
- RefPtr<StyleRuleFontFace> rule = StyleRuleFontFace::create();
- rule->setProperties(createStylePropertySet());
- clearProperties();
- StyleRuleFontFace* result = rule.get();
- m_parsedRules.append(rule.release());
- if (m_styleSheet)
- m_styleSheet->setHasFontFaceRule(true);
- return result;
-}
-
-void CSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri)
-{
- if (!m_styleSheet || !m_allowNamespaceDeclarations)
- return;
- m_allowImportRules = false;
- m_styleSheet->parserAddNamespace(prefix, uri);
- if (prefix.isEmpty() && !uri.isNull())
- m_defaultNamespace = uri;
-}
-
-QualifiedName CSSParser::determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName)
-{
- if (!m_styleSheet)
- return QualifiedName(prefix, localName, m_defaultNamespace);
- return QualifiedName(prefix, localName, m_styleSheet->determineNamespace(prefix));
-}
-
-CSSParserSelector* CSSParser::rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector* specifiers)
-{
- if (m_defaultNamespace != starAtom || specifiers->needsCrossingTreeScopeBoundary())
- return rewriteSpecifiersWithElementName(nullAtom, starAtom, specifiers, /*tagIsForNamespaceRule*/true);
- if (CSSParserSelector* distributedPseudoElementSelector = specifiers->findDistributedPseudoElementSelector()) {
- specifiers->prependTagSelector(QualifiedName(nullAtom, starAtom, m_defaultNamespace), /*tagIsForNamespaceRule*/true);
- return rewriteSpecifiersForShadowDistributed(specifiers, distributedPseudoElementSelector);
- }
- return specifiers;
-}
-
-CSSParserSelector* CSSParser::rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule)
-{
- AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace;
- QualifiedName tag(namespacePrefix, elementName, determinedNamespace);
-
- if (CSSParserSelector* distributedPseudoElementSelector = specifiers->findDistributedPseudoElementSelector()) {
- specifiers->prependTagSelector(tag, tagIsForNamespaceRule);
- return rewriteSpecifiersForShadowDistributed(specifiers, distributedPseudoElementSelector);
- }
-
- if (specifiers->needsCrossingTreeScopeBoundary())
- return rewriteSpecifiersWithElementNameForCustomPseudoElement(tag, elementName, specifiers, tagIsForNamespaceRule);
-
- if (specifiers->isContentPseudoElement())
- return rewriteSpecifiersWithElementNameForContentPseudoElement(tag, elementName, specifiers, tagIsForNamespaceRule);
-
- if (tag == anyQName())
- return specifiers;
- if (!(specifiers->pseudoType() == CSSSelector::PseudoCue))
- specifiers->prependTagSelector(tag, tagIsForNamespaceRule);
- return specifiers;
-}
-
-CSSParserSelector* CSSParser::rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule)
-{
- if (m_useCounter && specifiers->pseudoType() == CSSSelector::PseudoUserAgentCustomElement)
- m_useCounter->count(UseCounter::CSSPseudoElementUserAgentCustomPseudo);
-
- CSSParserSelector* lastShadowPseudo = specifiers;
- CSSParserSelector* history = specifiers;
- while (history->tagHistory()) {
- history = history->tagHistory();
- if (history->needsCrossingTreeScopeBoundary() || history->hasShadowPseudo())
- lastShadowPseudo = history;
- }
-
- if (lastShadowPseudo->tagHistory()) {
- if (tag != anyQName())
- lastShadowPseudo->tagHistory()->prependTagSelector(tag, tagIsForNamespaceRule);
- return specifiers;
- }
-
- // For shadow-ID pseudo-elements to be correctly matched, the ShadowPseudo combinator has to be used.
- // We therefore create a new Selector with that combinator here in any case, even if matching any (host) element in any namespace (i.e. '*').
- OwnPtr<CSSParserSelector> elementNameSelector = adoptPtr(new CSSParserSelector(tag));
- lastShadowPseudo->setTagHistory(elementNameSelector.release());
- lastShadowPseudo->setRelation(CSSSelector::ShadowPseudo);
- return specifiers;
-}
-
-CSSParserSelector* CSSParser::rewriteSpecifiersWithElementNameForContentPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule)
-{
- CSSParserSelector* last = specifiers;
- CSSParserSelector* history = specifiers;
- while (history->tagHistory()) {
- history = history->tagHistory();
- if (history->isContentPseudoElement() || history->relationIsAffectedByPseudoContent())
- last = history;
- }
-
- if (last->tagHistory()) {
- if (tag != anyQName())
- last->tagHistory()->prependTagSelector(tag, tagIsForNamespaceRule);
- return specifiers;
- }
-
- // For shadow-ID pseudo-elements to be correctly matched, the ShadowPseudo combinator has to be used.
- // We therefore create a new Selector with that combinator here in any case, even if matching any (host) element in any namespace (i.e. '*').
- OwnPtr<CSSParserSelector> elementNameSelector = adoptPtr(new CSSParserSelector(tag));
- last->setTagHistory(elementNameSelector.release());
- last->setRelation(CSSSelector::SubSelector);
- return specifiers;
-}
-
-CSSParserSelector* CSSParser::rewriteSpecifiersForShadowDistributed(CSSParserSelector* specifiers, CSSParserSelector* distributedPseudoElementSelector)
-{
- if (m_useCounter)
- m_useCounter->count(UseCounter::CSSPseudoElementPrefixedDistributed);
- CSSParserSelector* argumentSelector = distributedPseudoElementSelector->functionArgumentSelector();
- ASSERT(argumentSelector);
- ASSERT(!specifiers->isDistributedPseudoElement());
- for (CSSParserSelector* end = specifiers; end->tagHistory(); end = end->tagHistory()) {
- if (end->tagHistory()->isDistributedPseudoElement()) {
- end->clearTagHistory();
- break;
- }
- }
- CSSParserSelector* end = argumentSelector;
- while (end->tagHistory())
- end = end->tagHistory();
-
- switch (end->relation()) {
- case CSSSelector::Child:
- case CSSSelector::Descendant:
- end->setTagHistory(sinkFloatingSelector(specifiers));
- end->setRelationIsAffectedByPseudoContent();
- return argumentSelector;
- default:
- return 0;
- }
-}
-
-CSSParserSelector* CSSParser::rewriteSpecifiers(CSSParserSelector* specifiers, CSSParserSelector* newSpecifier)
-{
- if (newSpecifier->needsCrossingTreeScopeBoundary()) {
- // Unknown pseudo element always goes at the top of selector chain.
- newSpecifier->appendTagHistory(CSSSelector::ShadowPseudo, sinkFloatingSelector(specifiers));
- return newSpecifier;
- }
- if (newSpecifier->isContentPseudoElement()) {
- newSpecifier->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(specifiers));
- return newSpecifier;
- }
- if (specifiers->needsCrossingTreeScopeBoundary()) {
- // Specifiers for unknown pseudo element go right behind it in the chain.
- specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::ShadowPseudo);
- return specifiers;
- }
- if (specifiers->isContentPseudoElement()) {
- specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::SubSelector);
- return specifiers;
- }
- specifiers->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier));
- return specifiers;
-}
-
-StyleRuleBase* CSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector)
-{
- // FIXME: Margin at-rules are ignored.
- m_allowImportRules = m_allowNamespaceDeclarations = false;
- StyleRulePage* pageRule = 0;
- if (pageSelector) {
- RefPtr<StyleRulePage> rule = StyleRulePage::create();
- Vector<OwnPtr<CSSParserSelector> > selectorVector;
- selectorVector.append(pageSelector);
- rule->parserAdoptSelectorVector(selectorVector);
- rule->setProperties(createStylePropertySet());
- pageRule = rule.get();
- m_parsedRules.append(rule.release());
- }
- clearProperties();
- return pageRule;
-}
-
-void CSSParser::setReusableRegionSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectors)
-{
- if (selectors)
- m_reusableRegionSelectorVector.swap(*selectors);
-}
-
-StyleRuleBase* CSSParser::createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, RuleList* rules)
-{
- if (m_useCounter)
- m_useCounter->count(UseCounter::CSSWebkitRegionAtRule);
-
- if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !regionSelector || !rules)
- return 0;
-
- m_allowImportRules = m_allowNamespaceDeclarations = false;
-
- RefPtr<StyleRuleRegion> regionRule = StyleRuleRegion::create(regionSelector, *rules);
-
- StyleRuleRegion* result = regionRule.get();
- m_parsedRules.append(regionRule.release());
- if (m_sourceDataHandler)
- m_sourceDataHandler->startEndUnknownRule();
-
- return result;
-}
-
-StyleRuleBase* CSSParser::createMarginAtRule(CSSSelector::MarginBoxType /* marginBox */)
-{
- // FIXME: Implement margin at-rule here, using:
- // - marginBox: margin box
- // - m_parsedProperties: properties at [m_numParsedPropertiesBeforeMarginBox, m_parsedProperties.size()] are for this at-rule.
- // Don't forget to also update the action for page symbol in CSSGrammar.y such that margin at-rule data is cleared if page_selector is invalid.
-
- endDeclarationsForMarginBox();
- return 0; // until this method is implemented.
-}
-
-void CSSParser::startDeclarationsForMarginBox()
-{
- m_numParsedPropertiesBeforeMarginBox = m_parsedProperties.size();
-}
-
-void CSSParser::endDeclarationsForMarginBox()
-{
- rollbackLastProperties(m_parsedProperties.size() - m_numParsedPropertiesBeforeMarginBox);
- m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
-}
-
-void CSSParser::deleteFontFaceOnlyValues()
-{
- ASSERT(m_hasFontFaceOnlyValues);
- for (unsigned i = 0; i < m_parsedProperties.size();) {
- CSSProperty& property = m_parsedProperties[i];
- if (property.id() == CSSPropertyFontVariant && property.value()->isValueList()) {
- m_parsedProperties.remove(i);
- continue;
- }
- ++i;
- }
-}
-
-StyleKeyframe* CSSParser::createKeyframe(CSSParserValueList* keys)
-{
- OwnPtr<Vector<double> > keyVector = StyleKeyframe::createKeyList(keys);
- if (keyVector->isEmpty())
- return 0;
-
- RefPtr<StyleKeyframe> keyframe = StyleKeyframe::create();
- keyframe->setKeys(keyVector.release());
- keyframe->setProperties(createStylePropertySet());
-
- clearProperties();
-
- StyleKeyframe* keyframePtr = keyframe.get();
- m_parsedKeyframes.append(keyframe.release());
- return keyframePtr;
-}
-
-void CSSParser::invalidBlockHit()
-{
- if (m_styleSheet && !m_hadSyntacticallyValidCSSRule)
- m_styleSheet->setHasSyntacticallyValidCSSHeader(false);
-}
-
-void CSSParser::startRule()
-{
- if (!m_sourceDataHandler)
- return;
-
- ASSERT(m_ruleHasHeader);
- m_ruleHasHeader = false;
-}
-
-void CSSParser::endRule(bool valid)
-{
- if (!m_sourceDataHandler)
- return;
-
- if (m_ruleHasHeader)
- m_sourceDataHandler->endRuleBody(m_tokenizer.safeUserStringTokenOffset(), !valid);
- m_ruleHasHeader = true;
-}
-
-void CSSParser::startRuleHeader(CSSRuleSourceData::Type ruleType)
-{
- resumeErrorLogging();
- m_ruleHeaderType = ruleType;
- m_ruleHeaderStartOffset = m_tokenizer.safeUserStringTokenOffset();
- m_ruleHeaderStartLineNumber = m_tokenizer.m_tokenStartLineNumber;
- if (m_sourceDataHandler) {
- ASSERT(!m_ruleHasHeader);
- m_sourceDataHandler->startRuleHeader(ruleType, m_ruleHeaderStartOffset);
- m_ruleHasHeader = true;
- }
-}
-
-void CSSParser::endRuleHeader()
-{
- ASSERT(m_ruleHeaderType != CSSRuleSourceData::UNKNOWN_RULE);
- m_ruleHeaderType = CSSRuleSourceData::UNKNOWN_RULE;
- if (m_sourceDataHandler) {
- ASSERT(m_ruleHasHeader);
- m_sourceDataHandler->endRuleHeader(m_tokenizer.safeUserStringTokenOffset());
- }
-}
-
-void CSSParser::startSelector()
-{
- if (m_sourceDataHandler)
- m_sourceDataHandler->startSelector(m_tokenizer.safeUserStringTokenOffset());
-}
-
-void CSSParser::endSelector()
-{
- if (m_sourceDataHandler)
- m_sourceDataHandler->endSelector(m_tokenizer.safeUserStringTokenOffset());
-}
-
-void CSSParser::startRuleBody()
-{
- if (m_sourceDataHandler)
- m_sourceDataHandler->startRuleBody(m_tokenizer.safeUserStringTokenOffset());
-}
-
-void CSSParser::startProperty()
-{
- resumeErrorLogging();
- if (m_sourceDataHandler)
- m_sourceDataHandler->startProperty(m_tokenizer.safeUserStringTokenOffset());
-}
-
-void CSSParser::endProperty(bool isImportantFound, bool isPropertyParsed, ErrorType errorType)
-{
- m_id = CSSPropertyInvalid;
- if (m_sourceDataHandler)
- m_sourceDataHandler->endProperty(isImportantFound, isPropertyParsed, m_tokenizer.safeUserStringTokenOffset(), errorType);
-}
-
-void CSSParser::startEndUnknownRule()
-{
- if (m_sourceDataHandler)
- m_sourceDataHandler->startEndUnknownRule();
-}
-
-StyleRuleBase* CSSParser::createViewportRule()
-{
- // Allow @viewport rules from UA stylesheets even if the feature is disabled.
- if (!RuntimeEnabledFeatures::cssViewportEnabled() && !isUASheetBehavior(m_context.mode()))
- return 0;
-
- m_allowImportRules = m_allowNamespaceDeclarations = false;
-
- RefPtr<StyleRuleViewport> rule = StyleRuleViewport::create();
-
- rule->setProperties(createStylePropertySet());
- clearProperties();
-
- StyleRuleViewport* result = rule.get();
- m_parsedRules.append(rule.release());
-
- return result;
-}
-
-bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important)
-{
- ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_context.mode()));
-
- CSSParserValue* value = m_valueList->current();
- if (!value)
- return false;
-
- CSSValueID id = value->id;
- bool validPrimitive = false;
-
- switch (propId) {
- case CSSPropertyMinWidth: // auto | extend-to-zoom | <length> | <percentage>
- case CSSPropertyMaxWidth:
- case CSSPropertyMinHeight:
- case CSSPropertyMaxHeight:
- if (id == CSSValueAuto || id == CSSValueInternalExtendToZoom)
- validPrimitive = true;
- else
- validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
- break;
- case CSSPropertyWidth: // shorthand
- return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
- case CSSPropertyHeight:
- return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
- case CSSPropertyMinZoom: // auto | <number> | <percentage>
- case CSSPropertyMaxZoom:
- case CSSPropertyZoom:
- if (id == CSSValueAuto)
- validPrimitive = true;
- else
- validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg));
- break;
- case CSSPropertyUserZoom: // zoom | fixed
- if (id == CSSValueZoom || id == CSSValueFixed)
- validPrimitive = true;
- break;
- case CSSPropertyOrientation: // auto | portrait | landscape
- if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
- validPrimitive = true;
- default:
- break;
- }
-
- RefPtr<CSSValue> parsedValue;
- if (validPrimitive) {
- parsedValue = parseValidPrimitive(id, value);
- m_valueList->next();
- }
-
- if (parsedValue) {
- if (!m_valueList->current() || inShorthand()) {
- addProperty(propId, parsedValue.release(), important);
- return true;
- }
- }
-
- return false;
-}
-
-bool CSSParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
-{
- ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_context.mode()));
- unsigned numValues = m_valueList->size();
-
- if (numValues > 2)
- return false;
-
- ShorthandScope scope(this, propId);
-
- if (!parseViewportProperty(first, important))
- return false;
-
- // If just one value is supplied, the second value
- // is implicitly initialized with the first value.
- if (numValues == 1)
- m_valueList->previous();
-
- return parseViewportProperty(second, important);
-}
-
-template <typename CharacterType>
-static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned length)
-{
- char buffer[maxCSSPropertyNameLength + 1]; // 1 for null character
-
- for (unsigned i = 0; i != length; ++i) {
- CharacterType c = propertyName[i];
- if (c == 0 || c >= 0x7F)
- return CSSPropertyInvalid; // illegal character
- buffer[i] = toASCIILower(c);
- }
- buffer[length] = '\0';
-
- const char* name = buffer;
- const Property* hashTableEntry = findProperty(name, length);
- return hashTableEntry ? static_cast<CSSPropertyID>(hashTableEntry->id) : CSSPropertyInvalid;
-}
-
-CSSPropertyID cssPropertyID(const String& string)
-{
- unsigned length = string.length();
-
- if (!length)
- return CSSPropertyInvalid;
- if (length > maxCSSPropertyNameLength)
- return CSSPropertyInvalid;
-
- return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
-}
-
-CSSPropertyID cssPropertyID(const CSSParserString& string)
-{
- unsigned length = string.length();
-
- if (!length)
- return CSSPropertyInvalid;
- if (length > maxCSSPropertyNameLength)
- return CSSPropertyInvalid;
-
- return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
-}
-
-template <typename CharacterType>
-static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned length)
-{
- char buffer[maxCSSValueKeywordLength + 1]; // 1 for null character
-
- for (unsigned i = 0; i != length; ++i) {
- CharacterType c = valueKeyword[i];
- if (c == 0 || c >= 0x7F)
- return CSSValueInvalid; // illegal character
- buffer[i] = WTF::toASCIILower(c);
- }
- buffer[length] = '\0';
-
- const Value* hashTableEntry = findValue(buffer, length);
- return hashTableEntry ? static_cast<CSSValueID>(hashTableEntry->id) : CSSValueInvalid;
-}
-
-CSSValueID cssValueKeywordID(const CSSParserString& string)
-{
- unsigned length = string.length();
- if (!length)
- return CSSValueInvalid;
- if (length > maxCSSValueKeywordLength)
- return CSSValueInvalid;
-
- return string.is8Bit() ? cssValueKeywordID(string.characters8(), length) : cssValueKeywordID(string.characters16(), length);
-}
-
-template <typename CharacterType>
-static inline bool isCSSTokenizerIdentifier(const CharacterType* characters, unsigned length)
-{
- const CharacterType* end = characters + length;
-
- // -?
- if (characters != end && characters[0] == '-')
- ++characters;
-
- // {nmstart}
- if (characters == end || !(characters[0] == '_' || characters[0] >= 128 || isASCIIAlpha(characters[0])))
- return false;
- ++characters;
-
- // {nmchar}*
- for (; characters != end; ++characters) {
- if (!(characters[0] == '_' || characters[0] == '-' || characters[0] >= 128 || isASCIIAlphanumeric(characters[0])))
- return false;
- }
-
- return true;
-}
-
-// "ident" from the CSS tokenizer, minus backslash-escape sequences
-static bool isCSSTokenizerIdentifier(const String& string)
-{
- unsigned length = string.length();
-
- if (!length)
- return false;
-
- if (string.is8Bit())
- return isCSSTokenizerIdentifier(string.characters8(), length);
- return isCSSTokenizerIdentifier(string.characters16(), length);
-}
-
-template <typename CharacterType>
-static inline bool isCSSTokenizerURL(const CharacterType* characters, unsigned length)
-{
- const CharacterType* end = characters + length;
-
- for (; characters != end; ++characters) {
- CharacterType c = characters[0];
- switch (c) {
- case '!':
- case '#':
- case '$':
- case '%':
- case '&':
- break;
- default:
- if (c < '*')
- return false;
- if (c <= '~')
- break;
- if (c < 128)
- return false;
- }
- }
-
- return true;
-}
-
-// "url" from the CSS tokenizer, minus backslash-escape sequences
-static bool isCSSTokenizerURL(const String& string)
-{
- unsigned length = string.length();
-
- if (!length)
- return true;
-
- if (string.is8Bit())
- return isCSSTokenizerURL(string.characters8(), length);
- return isCSSTokenizerURL(string.characters16(), length);
-}
-
-
-template <typename CharacterType>
-static inline String quoteCSSStringInternal(const CharacterType* characters, unsigned length)
-{
- // For efficiency, we first pre-calculate the length of the quoted string, then we build the actual one.
- // Please see below for the actual logic.
- unsigned quotedStringSize = 2; // Two quotes surrounding the entire string.
- bool afterEscape = false;
- for (unsigned i = 0; i < length; ++i) {
- CharacterType ch = characters[i];
- if (ch == '\\' || ch == '\'') {
- quotedStringSize += 2;
- afterEscape = false;
- } else if (ch < 0x20 || ch == 0x7F) {
- quotedStringSize += 2 + (ch >= 0x10);
- afterEscape = true;
- } else {
- quotedStringSize += 1 + (afterEscape && (isASCIIHexDigit(ch) || ch == ' '));
- afterEscape = false;
- }
- }
-
- StringBuffer<CharacterType> buffer(quotedStringSize);
- unsigned index = 0;
- buffer[index++] = '\'';
- afterEscape = false;
- for (unsigned i = 0; i < length; ++i) {
- CharacterType ch = characters[i];
- if (ch == '\\' || ch == '\'') {
- buffer[index++] = '\\';
- buffer[index++] = ch;
- afterEscape = false;
- } else if (ch < 0x20 || ch == 0x7F) { // Control characters.
- buffer[index++] = '\\';
- placeByteAsHexCompressIfPossible(ch, buffer, index, Lowercase);
- afterEscape = true;
- } else {
- // Space character may be required to separate backslash-escape sequence and normal characters.
- if (afterEscape && (isASCIIHexDigit(ch) || ch == ' '))
- buffer[index++] = ' ';
- buffer[index++] = ch;
- afterEscape = false;
- }
- }
- buffer[index++] = '\'';
-
- ASSERT(quotedStringSize == index);
- return String::adopt(buffer);
-}
-
-// We use single quotes for now because markup.cpp uses double quotes.
-String quoteCSSString(const String& string)
-{
- // This function expands each character to at most 3 characters ('\u0010' -> '\' '1' '0') as well as adds
- // 2 quote characters (before and after). Make sure the resulting size (3 * length + 2) will not overflow unsigned.
-
- unsigned length = string.length();
-
- if (!length)
- return String("\'\'");
-
- if (length > std::numeric_limits<unsigned>::max() / 3 - 2)
- return emptyString();
-
- if (string.is8Bit())
- return quoteCSSStringInternal(string.characters8(), length);
- return quoteCSSStringInternal(string.characters16(), length);
-}
-
-String quoteCSSStringIfNeeded(const String& string)
-{
- return isCSSTokenizerIdentifier(string) ? string : quoteCSSString(string);
-}
-
-String quoteCSSURLIfNeeded(const String& string)
-{
- return isCSSTokenizerURL(string) ? string : quoteCSSString(string);
-}
-
-bool isValidNthToken(const CSSParserString& token)
-{
- // The tokenizer checks for the construct of an+b.
- // However, since the {ident} rule precedes the {nth} rule, some of those
- // tokens are identified as string literal. Furthermore we need to accept
- // "odd" and "even" which does not match to an+b.
- return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even")
- || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSParser.h b/chromium/third_party/WebKit/Source/core/css/CSSParser.h
deleted file mode 100755
index de263102892..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSParser.h
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2009 - 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef CSSParser_h
-#define CSSParser_h
-
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "core/css/CSSCalculationValue.h"
-#include "core/css/CSSFilterValue.h"
-#include "core/css/CSSGradientValue.h"
-#include "core/css/CSSParserMode.h"
-#include "core/css/CSSParserValues.h"
-#include "core/css/CSSProperty.h"
-#include "core/css/CSSPropertySourceData.h"
-#include "core/css/CSSSelector.h"
-#include "core/css/CSSTokenizer.h"
-#include "core/css/MediaQuery.h"
-#include "core/css/StylePropertySet.h"
-#include "core/frame/UseCounter.h"
-#include "platform/graphics/Color.h"
-#include "wtf/HashSet.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/Vector.h"
-#include "wtf/text/AtomicString.h"
-#include "wtf/text/TextPosition.h"
-
-namespace WebCore {
-
-class AnimationParseContext;
-class CSSArrayFunctionValue;
-class CSSBorderImageSliceValue;
-class CSSMixFunctionValue;
-class CSSPrimitiveValue;
-class CSSSelectorList;
-class CSSShaderValue;
-class CSSValue;
-class CSSValueList;
-class CSSBasicShape;
-class Document;
-class Element;
-class ImmutableStylePropertySet;
-class MediaQueryExp;
-class MediaQuerySet;
-class MutableStylePropertySet;
-class StyleKeyframe;
-class StylePropertyShorthand;
-class StyleRuleBase;
-class StyleRuleKeyframes;
-class StyleKeyframe;
-class StyleSheetContents;
-
-// FIXME: This class is shared with CSSTokenizer so should we rename it to CSSSourceLocation?
-struct CSSParserLocation {
- unsigned offset;
- unsigned lineNumber;
- CSSParserString token;
-};
-
-class CSSParser {
- friend inline int cssyylex(void*, CSSParser*);
-
-public:
- class SourceDataHandler;
- enum ErrorType {
- NoError,
- PropertyDeclarationError,
- InvalidPropertyValueError,
- InvalidPropertyError,
- InvalidSelectorError,
- InvalidSupportsConditionError,
- InvalidRuleError,
- InvalidMediaQueryError,
- InvalidKeyframeSelectorError,
- InvalidSelectorPseudoError,
- UnterminatedCommentError,
- GeneralError
- };
-
- CSSParser(const CSSParserContext&, UseCounter* = 0);
-
- ~CSSParser();
-
- void parseSheet(StyleSheetContents*, const String&, const TextPosition& startPosition = TextPosition::minimumPosition(), SourceDataHandler* = 0, bool = false);
- PassRefPtr<StyleRuleBase> parseRule(StyleSheetContents*, const String&);
- PassRefPtr<StyleKeyframe> parseKeyframeRule(StyleSheetContents*, const String&);
- bool parseSupportsCondition(const String&);
- static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetContents*);
- static bool parseColor(RGBA32& color, const String&, bool strict = false);
- static bool parseSystemColor(RGBA32& color, const String&, Document*);
- static PassRefPtr<CSSValueList> parseFontFaceValue(const AtomicString&);
- PassRefPtr<CSSPrimitiveValue> parseValidPrimitive(CSSValueID ident, CSSParserValue*);
- bool parseDeclaration(MutableStylePropertySet*, const String&, SourceDataHandler*, StyleSheetContents* contextStyleSheet);
- static PassRefPtr<ImmutableStylePropertySet> parseInlineStyleDeclaration(const String&, Element*);
- PassRefPtr<MediaQuerySet> parseMediaQueryList(const String&);
- PassOwnPtr<Vector<double> > parseKeyframeKeyList(const String&);
-
- void addPropertyWithPrefixingVariant(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
- void addProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
- void rollbackLastProperties(int num);
- bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
- void addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue>, bool);
- void setCurrentProperty(CSSPropertyID);
-
- bool parseValue(CSSPropertyID, bool important);
- bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&, bool important);
- bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important);
- bool parseContent(CSSPropertyID, bool important);
- bool parseQuotes(CSSPropertyID, bool important);
-
- static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, const Document&);
- void storeVariableDeclaration(const CSSParserString&, PassOwnPtr<CSSParserValueList>, bool important);
-
- PassRefPtr<CSSValue> parseAttr(CSSParserValueList* args);
-
- PassRefPtr<CSSValue> parseBackgroundColor();
-
- bool parseFillImage(CSSParserValueList*, RefPtr<CSSValue>&);
-
- enum FillPositionFlag { InvalidFillPosition = 0, AmbiguousFillPosition = 1, XFillPosition = 2, YFillPosition = 4 };
- enum FillPositionParsingMode { ResolveValuesAsPercent = 0, ResolveValuesAsKeyword = 1 };
- PassRefPtr<CSSPrimitiveValue> parseFillPositionComponent(CSSParserValueList*, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode = ResolveValuesAsPercent);
- PassRefPtr<CSSValue> parseFillPositionX(CSSParserValueList*);
- PassRefPtr<CSSValue> parseFillPositionY(CSSParserValueList*);
- void parse2ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
- bool isPotentialPositionValue(CSSParserValue*);
- void parseFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
- void parse3ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&, PassRefPtr<CSSPrimitiveValue>, PassRefPtr<CSSPrimitiveValue>);
- void parse4ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&, PassRefPtr<CSSPrimitiveValue>, PassRefPtr<CSSPrimitiveValue>);
-
- void parseFillRepeat(RefPtr<CSSValue>&, RefPtr<CSSValue>&);
- PassRefPtr<CSSValue> parseFillSize(CSSPropertyID, bool &allowComma);
-
- bool parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
- bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important);
-
- void addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
-
- void addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
-
- PassRefPtr<CSSValue> parseAnimationDelay();
- PassRefPtr<CSSValue> parseAnimationDirection();
- PassRefPtr<CSSValue> parseAnimationDuration();
- PassRefPtr<CSSValue> parseAnimationFillMode();
- PassRefPtr<CSSValue> parseAnimationIterationCount();
- PassRefPtr<CSSValue> parseAnimationName();
- PassRefPtr<CSSValue> parseAnimationPlayState();
- PassRefPtr<CSSValue> parseAnimationProperty(AnimationParseContext&);
- PassRefPtr<CSSValue> parseAnimationTimingFunction();
-
- bool parseTransformOriginShorthand(RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
- bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result);
- bool parseAnimationProperty(CSSPropertyID, RefPtr<CSSValue>&, AnimationParseContext&);
- bool parseTransitionShorthand(CSSPropertyID, bool important);
- bool parseAnimationShorthand(CSSPropertyID, bool important);
-
- PassRefPtr<CSSValue> parseColumnWidth();
- PassRefPtr<CSSValue> parseColumnCount();
- bool parseColumnsShorthand(bool important);
-
- PassRefPtr<CSSValue> parseGridPosition();
- bool parseIntegerOrStringFromGridPosition(RefPtr<CSSPrimitiveValue>& numericValue, RefPtr<CSSPrimitiveValue>& gridLineName);
- bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
- bool parseGridAreaShorthand(bool important);
- bool parseSingleGridAreaLonghand(RefPtr<CSSValue>&);
- bool parseGridTrackList(CSSPropertyID, bool important);
- bool parseGridTrackRepeatFunction(CSSValueList&);
- PassRefPtr<CSSValue> parseGridTrackSize(CSSParserValueList& inputList);
- PassRefPtr<CSSPrimitiveValue> parseGridBreadth(CSSParserValue*);
- PassRefPtr<CSSValue> parseGridTemplate();
- void parseGridLineNames(CSSParserValueList* inputList, CSSValueList&);
-
- bool parseClipShape(CSSPropertyID, bool important);
-
- bool parseBasicShape(CSSPropertyID, bool important);
- PassRefPtr<CSSBasicShape> parseBasicShapeRectangle(CSSParserValueList* args);
- PassRefPtr<CSSBasicShape> parseBasicShapeCircle(CSSParserValueList* args);
- PassRefPtr<CSSBasicShape> parseBasicShapeEllipse(CSSParserValueList* args);
- PassRefPtr<CSSBasicShape> parseBasicShapePolygon(CSSParserValueList* args);
- PassRefPtr<CSSBasicShape> parseBasicShapeInsetRectangle(CSSParserValueList* args);
-
- bool parseFont(bool important);
- PassRefPtr<CSSValueList> parseFontFamily();
-
- bool parseCounter(CSSPropertyID, int defaultValue, bool important);
- PassRefPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters);
-
- bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha);
- bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha);
- PassRefPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0);
- bool parseColorFromValue(CSSParserValue*, RGBA32&);
- void parseSelector(const String&, CSSSelectorList&);
-
- template<typename StringType>
- static bool fastParseColor(RGBA32&, const StringType&, bool strict);
-
- bool parseLineHeight(bool important);
- bool parseFontSize(bool important);
- bool parseFontVariant(bool important);
- bool parseFontWeight(bool important);
- bool parseFontFaceSrc();
- bool parseFontFaceUnicodeRange();
-
- bool parseSVGValue(CSSPropertyID propId, bool important);
- PassRefPtr<CSSValue> parseSVGPaint();
- PassRefPtr<CSSValue> parseSVGColor();
- PassRefPtr<CSSValue> parseSVGStrokeDasharray();
-
- PassRefPtr<CSSValue> parsePaintOrder() const;
-
- // CSS3 Parsing Routines (for properties specific to CSS3)
- PassRefPtr<CSSValueList> parseShadow(CSSParserValueList*, CSSPropertyID);
- bool parseBorderImageShorthand(CSSPropertyID, bool important);
- PassRefPtr<CSSValue> parseBorderImage(CSSPropertyID);
- bool parseBorderImageRepeat(RefPtr<CSSValue>&);
- bool parseBorderImageSlice(CSSPropertyID, RefPtr<CSSBorderImageSliceValue>&);
- bool parseBorderImageWidth(RefPtr<CSSPrimitiveValue>&);
- bool parseBorderImageOutset(RefPtr<CSSPrimitiveValue>&);
- bool parseBorderRadius(CSSPropertyID, bool important);
-
- bool parseAspectRatio(bool important);
-
- bool parseReflect(CSSPropertyID, bool important);
-
- bool parseFlex(CSSParserValueList* args, bool important);
-
- bool parseObjectPosition(bool important);
-
- // Image generators
- bool parseCanvas(CSSParserValueList*, RefPtr<CSSValue>&);
-
- bool parseDeprecatedGradient(CSSParserValueList*, RefPtr<CSSValue>&);
- bool parseDeprecatedLinearGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
- bool parseDeprecatedRadialGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
- bool parseLinearGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
- bool parseRadialGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
- bool parseGradientColorStops(CSSParserValueList*, CSSGradientValue*, bool expectComma);
-
- bool parseCrossfade(CSSParserValueList*, RefPtr<CSSValue>&);
-
- PassRefPtr<CSSValue> parseImageSet(CSSParserValueList*);
-
- PassRefPtr<CSSValueList> parseFilter();
- PassRefPtr<CSSFilterValue> parseBuiltinFilterArguments(CSSParserValueList*, CSSFilterValue::FilterOperationType);
- PassRefPtr<CSSMixFunctionValue> parseMixFunction(CSSParserValue*);
- PassRefPtr<CSSArrayFunctionValue> parseCustomFilterArrayFunction(CSSParserValue*);
- PassRefPtr<CSSValueList> parseCustomFilterTransform(CSSParserValueList*);
- PassRefPtr<CSSValueList> parseCustomFilterParameters(CSSParserValueList*);
- PassRefPtr<CSSFilterValue> parseCustomFilterFunctionWithAtRuleReferenceSyntax(CSSParserValue*);
- PassRefPtr<CSSFilterValue> parseCustomFilterFunctionWithInlineSyntax(CSSParserValue*);
- PassRefPtr<CSSFilterValue> parseCustomFilterFunction(CSSParserValue*);
- bool parseFilterRuleSrc();
- PassRefPtr<CSSShaderValue> parseFilterRuleSrcUriAndFormat(CSSParserValueList*);
-
- static bool isBlendMode(CSSValueID);
- static bool isCompositeOperator(CSSValueID);
-
- PassRefPtr<CSSValueList> parseTransform();
- PassRefPtr<CSSValue> parseTransformValue(CSSParserValue*);
- bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
- bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-
- bool parseTextEmphasisStyle(bool important);
-
- bool parseTouchAction(bool important);
-
- void addTextDecorationProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important);
- bool parseTextDecoration(CSSPropertyID propId, bool important);
- bool parseTextUnderlinePosition(bool important);
-
- PassRefPtr<CSSValue> parseTextIndent();
-
- bool parseLineBoxContain(bool important);
- bool parseCalculation(CSSParserValue*, ValueRange);
-
- bool parseFontFeatureTag(CSSValueList*);
- bool parseFontFeatureSettings(bool important);
-
- bool parseFlowThread(const String& flowName);
- bool parseFlowThread(CSSPropertyID, bool important);
- bool parseRegionThread(CSSPropertyID, bool important);
-
- bool parseFontVariantLigatures(bool important);
-
- bool parseGeneratedImage(CSSParserValueList*, RefPtr<CSSValue>&);
-
- CSSParserSelector* createFloatingSelector();
- CSSParserSelector* createFloatingSelectorWithTagName(const QualifiedName&);
- PassOwnPtr<CSSParserSelector> sinkFloatingSelector(CSSParserSelector*);
-
- Vector<OwnPtr<CSSParserSelector> >* createFloatingSelectorVector();
- PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >*);
-
- CSSParserValueList* createFloatingValueList();
- PassOwnPtr<CSSParserValueList> sinkFloatingValueList(CSSParserValueList*);
-
- CSSParserFunction* createFloatingFunction();
- CSSParserFunction* createFloatingFunction(const CSSParserString& name, PassOwnPtr<CSSParserValueList> args);
- PassOwnPtr<CSSParserFunction> sinkFloatingFunction(CSSParserFunction*);
-
- CSSParserValue& sinkFloatingValue(CSSParserValue&);
-
- MediaQuerySet* createMediaQuerySet();
- StyleRuleBase* createImportRule(const CSSParserString&, MediaQuerySet*);
- StyleKeyframe* createKeyframe(CSSParserValueList*);
- StyleRuleKeyframes* createKeyframesRule(const String&, PassOwnPtr<Vector<RefPtr<StyleKeyframe> > >, bool isPrefixed);
-
- typedef Vector<RefPtr<StyleRuleBase> > RuleList;
- StyleRuleBase* createMediaRule(MediaQuerySet*, RuleList*);
- RuleList* createRuleList();
- RuleList* appendRule(RuleList*, StyleRuleBase*);
- StyleRuleBase* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors);
- StyleRuleBase* createFontFaceRule();
- StyleRuleBase* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
- StyleRuleBase* createRegionRule(Vector<OwnPtr<CSSParserSelector> >* regionSelector, RuleList* rules);
- StyleRuleBase* createMarginAtRule(CSSSelector::MarginBoxType);
- StyleRuleBase* createSupportsRule(bool conditionIsSupported, RuleList*);
- void markSupportsRuleHeaderStart();
- void markSupportsRuleHeaderEnd();
- PassRefPtr<CSSRuleSourceData> popSupportsRuleData();
- StyleRuleBase* createHostRule(RuleList* rules);
- StyleRuleBase* createFilterRule(const CSSParserString&);
-
- void startDeclarationsForMarginBox();
- void endDeclarationsForMarginBox();
-
- MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
- PassOwnPtr<MediaQueryExp> sinkFloatingMediaQueryExp(MediaQueryExp*);
- Vector<OwnPtr<MediaQueryExp> >* createFloatingMediaQueryExpList();
- PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > sinkFloatingMediaQueryExpList(Vector<OwnPtr<MediaQueryExp> >*);
- MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const AtomicString&, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > >);
- MediaQuery* createFloatingMediaQuery(PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > >);
- MediaQuery* createFloatingNotAllQuery();
- PassOwnPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
-
- Vector<RefPtr<StyleKeyframe> >* createFloatingKeyframeVector();
- PassOwnPtr<Vector<RefPtr<StyleKeyframe> > > sinkFloatingKeyframeVector(Vector<RefPtr<StyleKeyframe> >*);
-
- void addNamespace(const AtomicString& prefix, const AtomicString& uri);
- QualifiedName determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName);
-
- CSSParserSelector* rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*, bool isNamespacePlaceholder = false);
- CSSParserSelector* rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule);
- CSSParserSelector* rewriteSpecifiersWithElementNameForContentPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule);
- CSSParserSelector* rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector*);
- CSSParserSelector* rewriteSpecifiers(CSSParserSelector*, CSSParserSelector*);
- CSSParserSelector* rewriteSpecifiersForShadowDistributed(CSSParserSelector* specifiers, CSSParserSelector* distributedPseudoElementSelector);
-
- void invalidBlockHit();
-
- Vector<OwnPtr<CSSParserSelector> >* reusableSelectorVector() { return &m_reusableSelectorVector; }
-
- void setReusableRegionSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectors);
- Vector<OwnPtr<CSSParserSelector> >* reusableRegionSelectorVector() { return &m_reusableRegionSelectorVector; }
-
- void clearProperties();
-
- PassRefPtr<ImmutableStylePropertySet> createStylePropertySet();
-
- CSSParserContext m_context;
-
- bool m_important;
- CSSPropertyID m_id;
- StyleSheetContents* m_styleSheet;
- RefPtr<StyleRuleBase> m_rule;
- RefPtr<StyleKeyframe> m_keyframe;
- RefPtr<MediaQuerySet> m_mediaList;
- OwnPtr<CSSParserValueList> m_valueList;
- bool m_supportsCondition;
-
- typedef Vector<CSSProperty, 256> ParsedPropertyVector;
- ParsedPropertyVector m_parsedProperties;
- CSSSelectorList* m_selectorListForParseSelector;
-
- unsigned m_numParsedPropertiesBeforeMarginBox;
-
- int m_inParseShorthand;
- CSSPropertyID m_currentShorthand;
- bool m_implicitShorthand;
-
- bool m_hasFontFaceOnlyValues;
- bool m_hadSyntacticallyValidCSSRule;
- bool m_logErrors;
- bool m_ignoreErrors;
-
- bool m_inFilterRule;
-
- AtomicString m_defaultNamespace;
-
- // tokenizer methods and data
- SourceDataHandler* m_sourceDataHandler;
-
- void startRule();
- void endRule(bool valid);
- void startRuleHeader(CSSRuleSourceData::Type);
- void endRuleHeader();
- void startSelector();
- void endSelector();
- void startRuleBody();
- void startProperty();
- void endProperty(bool isImportantFound, bool isPropertyParsed, ErrorType = NoError);
- void startEndUnknownRule();
-
- void endInvalidRuleHeader();
- void reportError(const CSSParserLocation&, ErrorType = GeneralError);
- void resumeErrorLogging() { m_ignoreErrors = false; }
- void setLocationLabel(const CSSParserLocation& location) { m_locationLabel = location; }
- const CSSParserLocation& lastLocationLabel() const { return m_locationLabel; }
-
- void tokenToLowerCase(const CSSParserString& token);
-
- void markViewportRuleBodyStart() { m_inViewport = true; }
- void markViewportRuleBodyEnd() { m_inViewport = false; }
- StyleRuleBase* createViewportRule();
-
- PassRefPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
- PassRefPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
- PassRefPtr<CSSPrimitiveValue> createPrimitiveVariableNameValue(CSSParserValue*);
-
- static KURL completeURL(const CSSParserContext&, const String& url);
-
- CSSParserLocation currentLocation() { return m_tokenizer.currentLocation(); }
-
-private:
- enum PropertyType {
- PropertyExplicit,
- PropertyImplicit
- };
-
- class ImplicitScope {
- WTF_MAKE_NONCOPYABLE(ImplicitScope);
- public:
- ImplicitScope(WebCore::CSSParser* parser, PropertyType propertyType)
- : m_parser(parser)
- {
- m_parser->m_implicitShorthand = propertyType == CSSParser::PropertyImplicit;
- }
-
- ~ImplicitScope()
- {
- m_parser->m_implicitShorthand = false;
- }
-
- private:
- WebCore::CSSParser* m_parser;
- };
-
- class StyleDeclarationScope {
- WTF_MAKE_NONCOPYABLE(StyleDeclarationScope);
- public:
- StyleDeclarationScope(CSSParser* parser, const StylePropertySet* declaration)
- : m_parser(parser)
- , m_mode(declaration->cssParserMode())
- {
- if (isCSSViewportParsingEnabledForMode(m_mode)) {
- ASSERT(!m_parser->inViewport());
- m_parser->markViewportRuleBodyStart();
- }
- }
-
- ~StyleDeclarationScope()
- {
- if (isCSSViewportParsingEnabledForMode(m_mode))
- m_parser->markViewportRuleBodyEnd();
- }
-
- private:
- CSSParser* m_parser;
- CSSParserMode m_mode;
- };
-
- inline void ensureLineEndings();
-
- void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
-
- bool inQuirksMode() const { return isQuirksModeBehavior(m_context.mode()); }
- bool inViewport() const { return m_inViewport; }
-
- KURL completeURL(const String& url) const;
-
- void recheckAtKeyword(const UChar* str, int len);
-
- template<unsigned prefixLength, unsigned suffixLength>
- inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength])
- {
- setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
- }
- void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
- bool inShorthand() const { return m_inParseShorthand; }
-
- bool validWidthOrHeight(CSSParserValue*);
-
- void deleteFontFaceOnlyValues();
-
- bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, StyleSheetContents* contextStyleSheet);
- PassRefPtr<ImmutableStylePropertySet> parseDeclaration(const String&, StyleSheetContents* contextStyleSheet);
-
- enum SizeParameterType {
- None,
- Auto,
- Length,
- PageSize,
- Orientation,
- };
-
- bool parsePage(CSSPropertyID propId, bool important);
- bool parseSize(CSSPropertyID propId, bool important);
- SizeParameterType parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType);
-
- bool parseFontFaceSrcURI(CSSValueList*);
- bool parseFontFaceSrcLocal(CSSValueList*);
-
- bool parseColor(const String&);
-
- const String* m_source;
- TextPosition m_startPosition;
- CSSRuleSourceData::Type m_ruleHeaderType;
- unsigned m_ruleHeaderStartOffset;
- int m_ruleHeaderStartLineNumber;
- OwnPtr<Vector<unsigned> > m_lineEndings;
-
- bool m_ruleHasHeader;
-
- bool m_allowImportRules;
- bool m_allowNamespaceDeclarations;
-
- bool parseViewportProperty(CSSPropertyID propId, bool important);
- bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
-
- bool m_inViewport;
-
- CSSParserLocation m_locationLabel;
-
- bool useLegacyBackgroundSizeShorthandBehavior() const;
-
- Vector<RefPtr<StyleRuleBase> > m_parsedRules;
- Vector<RefPtr<StyleKeyframe> > m_parsedKeyframes;
- Vector<RefPtr<MediaQuerySet> > m_parsedMediaQuerySets;
- Vector<OwnPtr<RuleList> > m_parsedRuleLists;
- Vector<CSSParserSelector*> m_floatingSelectors;
- Vector<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors;
- Vector<CSSParserValueList*> m_floatingValueLists;
- Vector<CSSParserFunction*> m_floatingFunctions;
-
- OwnPtr<MediaQuery> m_floatingMediaQuery;
- OwnPtr<MediaQueryExp> m_floatingMediaQueryExp;
- OwnPtr<Vector<OwnPtr<MediaQueryExp> > > m_floatingMediaQueryExpList;
-
- OwnPtr<Vector<RefPtr<StyleKeyframe> > > m_floatingKeyframeVector;
-
- Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
- Vector<OwnPtr<CSSParserSelector> > m_reusableRegionSelectorVector;
-
- RefPtr<CSSCalcValue> m_parsedCalculation;
-
- OwnPtr<RuleSourceDataList> m_supportsRuleDataStack;
-
- // defines units allowed for a certain property, used in parseUnit
- enum Units {
- FUnknown = 0x0000,
- FInteger = 0x0001,
- FNumber = 0x0002, // Real Numbers
- FPercent = 0x0004,
- FLength = 0x0008,
- FAngle = 0x0010,
- FTime = 0x0020,
- FFrequency = 0x0040,
- FPositiveInteger = 0x0080,
- FRelative = 0x0100,
- FResolution = 0x0200,
- FNonNeg = 0x0400
- };
-
- friend inline Units operator|(Units a, Units b)
- {
- return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
- }
-
- enum ReleaseParsedCalcValueCondition {
- ReleaseParsedCalcValue,
- DoNotReleaseParsedCalcValue
- };
-
- bool isLoggingErrors();
- void logError(const String& message, const CSSParserLocation&);
-
- bool validCalculationUnit(CSSParserValue*, Units, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
-
- bool shouldAcceptUnitLessValues(CSSParserValue*, Units, CSSParserMode);
-
- inline bool validUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue) { return validUnit(value, unitflags, m_context.mode(), releaseCalc); }
- bool validUnit(CSSParserValue*, Units, CSSParserMode, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
-
- bool parseBorderImageQuad(Units, RefPtr<CSSPrimitiveValue>&);
- int colorIntFromValue(CSSParserValue*);
- double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
- bool isCalculation(CSSParserValue*);
-
- UseCounter* m_useCounter;
-
- CSSTokenizer m_tokenizer;
-
- friend class TransformOperationInfo;
- friend class FilterOperationInfo;
-};
-
-CSSPropertyID cssPropertyID(const CSSParserString&);
-CSSPropertyID cssPropertyID(const String&);
-CSSValueID cssValueKeywordID(const CSSParserString&);
-
-class ShorthandScope {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- ShorthandScope(CSSParser* parser, CSSPropertyID propId) : m_parser(parser)
- {
- if (!(m_parser->m_inParseShorthand++))
- m_parser->m_currentShorthand = propId;
- }
- ~ShorthandScope()
- {
- if (!(--m_parser->m_inParseShorthand))
- m_parser->m_currentShorthand = CSSPropertyInvalid;
- }
-
-private:
- CSSParser* m_parser;
-};
-
-class CSSParser::SourceDataHandler {
-public:
- virtual void startRuleHeader(CSSRuleSourceData::Type, unsigned offset) = 0;
- virtual void endRuleHeader(unsigned offset) = 0;
- virtual void startSelector(unsigned offset) = 0;
- virtual void endSelector(unsigned offset) = 0;
- virtual void startRuleBody(unsigned offset) = 0;
- virtual void endRuleBody(unsigned offset, bool error) = 0;
- virtual void startEndUnknownRule() = 0;
- virtual void startProperty(unsigned offset) = 0;
- virtual void endProperty(bool isImportant, bool isParsed, unsigned offset, CSSParser::ErrorType) = 0;
- virtual void startComment(unsigned offset) = 0;
- virtual void endComment(unsigned offset) = 0;
-};
-
-String quoteCSSString(const String&);
-String quoteCSSStringIfNeeded(const String&);
-String quoteCSSURLIfNeeded(const String&);
-
-bool isValidNthToken(const CSSParserString&);
-
-inline int cssyylex(void* yylval, CSSParser* parser)
-{
- return parser->m_tokenizer.lex(yylval);
-}
-
-} // namespace WebCore
-
-#endif // CSSParser_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSParserMode.cpp b/chromium/third_party/WebKit/Source/core/css/CSSParserMode.cpp
index b4d94f8a135..d403eb81fee 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSParserMode.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSParserMode.cpp
@@ -32,19 +32,33 @@
namespace WebCore {
-CSSParserContext::CSSParserContext(CSSParserMode mode)
+CSSParserContext::CSSParserContext(CSSParserMode mode, UseCounter* useCounter)
: m_mode(mode)
, m_isHTMLDocument(false)
, m_useLegacyBackgroundSizeShorthandBehavior(false)
+ , m_useCounter(useCounter)
{
}
-CSSParserContext::CSSParserContext(const Document& document, const KURL& baseURL, const String& charset)
+CSSParserContext::CSSParserContext(const Document& document, UseCounter* useCounter, const KURL& baseURL, const String& charset)
: m_baseURL(baseURL.isNull() ? document.baseURL() : baseURL)
, m_charset(charset)
, m_mode(document.inQuirksMode() ? HTMLQuirksMode : HTMLStandardMode)
+ , m_referrer(m_baseURL.strippedForUseAsReferrer(), document.referrerPolicy())
, m_isHTMLDocument(document.isHTMLDocument())
, m_useLegacyBackgroundSizeShorthandBehavior(document.settings() ? document.settings()->useLegacyBackgroundSizeShorthandBehavior() : false)
+ , m_useCounter(useCounter)
+{
+}
+
+CSSParserContext::CSSParserContext(const CSSParserContext& other, UseCounter* useCounter)
+ : m_baseURL(other.m_baseURL)
+ , m_charset(other.m_charset)
+ , m_mode(other.m_mode)
+ , m_referrer(other.m_referrer)
+ , m_isHTMLDocument(other.m_isHTMLDocument)
+ , m_useLegacyBackgroundSizeShorthandBehavior(other.m_useLegacyBackgroundSizeShorthandBehavior)
+ , m_useCounter(useCounter)
{
}
@@ -59,8 +73,17 @@ bool CSSParserContext::operator==(const CSSParserContext& other) const
const CSSParserContext& strictCSSParserContext()
{
- DEFINE_STATIC_LOCAL(CSSParserContext, strictContext, (HTMLStandardMode));
+ DEFINE_STATIC_LOCAL(CSSParserContext, strictContext, (HTMLStandardMode, 0));
return strictContext;
}
+KURL CSSParserContext::completeURL(const String& url) const
+{
+ if (url.isNull())
+ return KURL();
+ if (charset().isEmpty())
+ return KURL(baseURL(), url);
+ return KURL(baseURL(), url, charset());
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSParserMode.h b/chromium/third_party/WebKit/Source/core/css/CSSParserMode.h
index efcac21a195..b379a68c77f 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSParserMode.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSParserMode.h
@@ -32,12 +32,13 @@
#define CSSParserMode_h
#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/Referrer.h"
namespace WebCore {
class Document;
-// Must not grow beyond 3 bytes, due to packing in StylePropertySet.
+// Must not grow beyond 3 bits, due to packing in StylePropertySet.
enum CSSParserMode {
HTMLStandardMode,
HTMLQuirksMode,
@@ -88,11 +89,18 @@ inline bool isUseCounterEnabledForMode(CSSParserMode mode)
return mode != UASheetMode;
}
+class UseCounter;
+
class CSSParserContext {
WTF_MAKE_FAST_ALLOCATED;
public:
- CSSParserContext(CSSParserMode);
- CSSParserContext(const Document&, const KURL& baseURL = KURL(), const String& charset = emptyString());
+ CSSParserContext(CSSParserMode, UseCounter*);
+ // FIXME: We shouldn't need the UseCounter argument as we could infer it from the Document
+ // but some callers want to disable use counting (e.g. the WebInspector).
+ CSSParserContext(const Document&, UseCounter*, const KURL& baseURL = KURL(), const String& charset = emptyString());
+ // FIXME: This constructor shouldn't exist if we properly piped the UseCounter through the CSS
+ // subsystem. Currently the UseCounter life time is too crazy and we need a way to override it.
+ CSSParserContext(const CSSParserContext&, UseCounter*);
bool operator==(const CSSParserContext&) const;
bool operator!=(const CSSParserContext& other) const { return !(*this == other); }
@@ -100,6 +108,7 @@ public:
CSSParserMode mode() const { return m_mode; }
const KURL& baseURL() const { return m_baseURL; }
const String& charset() const { return m_charset; }
+ const Referrer& referrer() const { return m_referrer; }
bool isHTMLDocument() const { return m_isHTMLDocument; }
// This quirk is to maintain compatibility with Android apps built on
@@ -112,13 +121,21 @@ public:
void setMode(CSSParserMode mode) { m_mode = mode; }
void setBaseURL(const KURL& baseURL) { m_baseURL = baseURL; }
void setCharset(const String& charset) { m_charset = charset; }
+ void setReferrer(const Referrer& referrer) { m_referrer = referrer; }
+
+ KURL completeURL(const String& url) const;
+
+ UseCounter* useCounter() const { return m_useCounter; }
private:
KURL m_baseURL;
String m_charset;
CSSParserMode m_mode;
+ Referrer m_referrer;
bool m_isHTMLDocument;
bool m_useLegacyBackgroundSizeShorthandBehavior;
+
+ UseCounter* m_useCounter;
};
const CSSParserContext& strictCSSParserContext();
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSParserValues.cpp b/chromium/third_party/WebKit/Source/core/css/CSSParserValues.cpp
index 10a940a6588..62196a77252 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSParserValues.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSParserValues.cpp
@@ -29,35 +29,26 @@ namespace WebCore {
using namespace WTF;
-AtomicString CSSParserString::atomicSubstring(unsigned position, unsigned length) const
+static void destroy(Vector<CSSParserValue, 4>& values)
{
- ASSERT(m_length >= position + length);
-
- if (is8Bit())
- return AtomicString(characters8() + position, length);
- return AtomicString(characters16() + position, length);
+ size_t numValues = values.size();
+ for (size_t i = 0; i < numValues; i++) {
+ if (values[i].unit == CSSParserValue::Function)
+ delete values[i].function;
+ else if (values[i].unit == CSSParserValue::ValueList)
+ delete values[i].valueList;
+ }
}
-void CSSParserString::trimTrailingWhitespace()
+void CSSParserValueList::destroyAndClear()
{
- if (is8Bit()) {
- while (m_length > 0 && isHTMLSpace<LChar>(m_data.characters8[m_length - 1]))
- --m_length;
- } else {
- while (m_length > 0 && isHTMLSpace<UChar>(m_data.characters16[m_length - 1]))
- --m_length;
- }
+ destroy(m_values);
+ clearAndLeakValues();
}
CSSParserValueList::~CSSParserValueList()
{
- size_t numValues = m_values.size();
- for (size_t i = 0; i < numValues; i++) {
- if (m_values[i].unit == CSSParserValue::Function)
- delete m_values[i].function;
- else if (m_values[i].unit == CSSParserValue::ValueList)
- delete m_values[i].valueList;
- }
+ destroy(m_values);
}
void CSSParserValueList::addValue(const CSSParserValue& v)
@@ -70,28 +61,20 @@ void CSSParserValueList::insertValueAt(unsigned i, const CSSParserValue& v)
m_values.insert(i, v);
}
-void CSSParserValueList::deleteValueAt(unsigned i)
+void CSSParserValueList::stealValues(CSSParserValueList& valueList)
{
- m_values.remove(i);
-}
-
-void CSSParserValueList::extend(CSSParserValueList& valueList)
-{
- for (unsigned int i = 0; i < valueList.size(); ++i)
+ for (unsigned i = 0; i < valueList.size(); ++i)
m_values.append(*(valueList.valueAt(i)));
+ valueList.clearAndLeakValues();
}
-PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
+PassRefPtrWillBeRawPtr<CSSValue> CSSParserValue::createCSSValue()
{
- RefPtr<CSSValue> parsedValue;
if (id)
return CSSPrimitiveValue::createIdentifier(id);
- if (unit == CSSParserValue::Operator) {
- RefPtr<CSSPrimitiveValue> primitiveValue = CSSPrimitiveValue::createParserOperator(iValue);
- primitiveValue->setPrimitiveType(CSSPrimitiveValue::CSS_PARSER_OPERATOR);
- return primitiveValue;
- }
+ if (unit == CSSParserValue::Operator)
+ return CSSPrimitiveValue::createParserOperator(iValue);
if (unit == CSSParserValue::Function)
return CSSFunctionValue::create(function);
if (unit == CSSParserValue::ValueList)
@@ -99,7 +82,7 @@ PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
if (unit >= CSSParserValue::Q_EMS)
return CSSPrimitiveValue::createAllowingMarginQuirk(fValue, CSSPrimitiveValue::CSS_EMS);
- CSSPrimitiveValue::UnitTypes primitiveUnit = static_cast<CSSPrimitiveValue::UnitTypes>(unit);
+ CSSPrimitiveValue::UnitType primitiveUnit = static_cast<CSSPrimitiveValue::UnitType>(unit);
switch (primitiveUnit) {
case CSSPrimitiveValue::CSS_IDENT:
case CSSPrimitiveValue::CSS_PROPERTY_ID:
@@ -109,7 +92,6 @@ PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
return CSSPrimitiveValue::create(fValue, isInt ? CSSPrimitiveValue::CSS_PARSER_INTEGER : CSSPrimitiveValue::CSS_NUMBER);
case CSSPrimitiveValue::CSS_STRING:
case CSSPrimitiveValue::CSS_URI:
- case CSSPrimitiveValue::CSS_VARIABLE_NAME:
case CSSPrimitiveValue::CSS_PARSER_HEXCOLOR:
return CSSPrimitiveValue::create(string, primitiveUnit);
case CSSPrimitiveValue::CSS_PERCENTAGE:
@@ -148,31 +130,29 @@ PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
case CSSPrimitiveValue::CSS_DPCM:
case CSSPrimitiveValue::CSS_PAIR:
case CSSPrimitiveValue::CSS_UNICODE_RANGE:
- case CSSPrimitiveValue::CSS_PARSER_OPERATOR:
case CSSPrimitiveValue::CSS_PARSER_INTEGER:
case CSSPrimitiveValue::CSS_PARSER_IDENTIFIER:
+ case CSSPrimitiveValue::CSS_PARSER_OPERATOR:
case CSSPrimitiveValue::CSS_COUNTER_NAME:
case CSSPrimitiveValue::CSS_SHAPE:
case CSSPrimitiveValue::CSS_QUAD:
case CSSPrimitiveValue::CSS_CALC:
case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH:
- return 0;
+ return nullptr;
}
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
CSSParserSelector::CSSParserSelector()
: m_selector(adoptPtr(new CSSSelector()))
- , m_functionArgumentSelector(0)
{
}
CSSParserSelector::CSSParserSelector(const QualifiedName& tagQName)
: m_selector(adoptPtr(new CSSSelector(tagQName)))
- , m_functionArgumentSelector(0)
{
}
@@ -206,7 +186,7 @@ bool CSSParserSelector::isSimple() const
if (!m_tagHistory)
return true;
- if (m_selector->m_match == CSSSelector::Tag) {
+ if (m_selector->match() == CSSSelector::Tag) {
// We can't check against anyQName() here because namespace may not be nullAtom.
// Example:
// @namespace "http://www.w3.org/2000/svg";
@@ -244,17 +224,17 @@ void CSSParserSelector::prependTagSelector(const QualifiedName& tagQName, bool t
m_tagHistory = second.release();
m_selector = adoptPtr(new CSSSelector(tagQName, tagIsForNamespaceRule));
- m_selector->m_relation = CSSSelector::SubSelector;
+ m_selector->setRelation(CSSSelector::SubSelector);
}
-CSSParserSelector* CSSParserSelector::findDistributedPseudoElementSelector() const
+bool CSSParserSelector::hasHostPseudoSelector() const
{
CSSParserSelector* selector = const_cast<CSSParserSelector*>(this);
do {
- if (selector->isDistributedPseudoElement())
- return selector;
+ if (selector->pseudoType() == CSSSelector::PseudoHost || selector->pseudoType() == CSSSelector::PseudoHostContext)
+ return true;
} while ((selector = selector->tagHistory()));
- return 0;
+ return false;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSParserValues.h b/chromium/third_party/WebKit/Source/core/css/CSSParserValues.h
index 8efd3250dcf..7ab5836b858 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSParserValues.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSParserValues.h
@@ -21,7 +21,7 @@
#ifndef CSSParserValues_h
#define CSSParserValues_h
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSSelector.h"
#include "core/css/CSSValueList.h"
@@ -77,8 +77,6 @@ struct CSSParserString {
m_is8Bit = true;
}
- void trimTrailingWhitespace();
-
bool is8Bit() const { return m_is8Bit; }
const LChar* characters8() const { ASSERT(is8Bit()); return m_data.characters8; }
const UChar* characters16() const { ASSERT(!is8Bit()); return m_data.characters16; }
@@ -98,9 +96,11 @@ struct CSSParserString {
bool equalIgnoringCase(const char* str) const
{
- if (is8Bit())
- return WTF::equalIgnoringCase(str, characters8(), length());
- return WTF::equalIgnoringCase(str, characters16(), length());
+ bool match = is8Bit() ? WTF::equalIgnoringCase(str, characters8(), length()) : WTF::equalIgnoringCase(str, characters16(), length());
+ if (!match)
+ return false;
+ ASSERT(strlen(str) >= length());
+ return str[length()] == '\0';
}
template <size_t strLength>
@@ -119,8 +119,6 @@ struct CSSParserString {
operator String() const { return is8Bit() ? String(m_data.characters8, m_length) : StringImpl::create8BitIfPossible(m_data.characters16, m_length); }
operator AtomicString() const { return is8Bit() ? AtomicString(m_data.characters8, m_length) : AtomicString(m_data.characters16, m_length); }
- AtomicString atomicSubstring(unsigned position, unsigned length) const;
-
bool isFunction() const { return length() > 0 && (*this)[length() - 1] == '('; }
union {
@@ -161,7 +159,7 @@ struct CSSParserValue {
inline void setFromFunction(CSSParserFunction*);
inline void setFromValueList(PassOwnPtr<CSSParserValueList>);
- PassRefPtr<CSSValue> createCSSValue();
+ PassRefPtrWillBeRawPtr<CSSValue> createCSSValue();
};
class CSSParserValueList {
@@ -175,8 +173,7 @@ public:
void addValue(const CSSParserValue&);
void insertValueAt(unsigned, const CSSParserValue&);
- void deleteValueAt(unsigned);
- void extend(CSSParserValueList&);
+ void stealValues(CSSParserValueList&);
unsigned size() const { return m_values.size(); }
unsigned currentIndex() { return m_current; }
@@ -189,10 +186,17 @@ public:
--m_current;
return current();
}
+ void setCurrentIndex(unsigned index)
+ {
+ ASSERT(index < m_values.size());
+ if (index < m_values.size())
+ m_current = index;
+ }
CSSParserValue* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
- void clear() { m_values.clear(); }
+ void clearAndLeakValues() { m_values.clear(); m_current = 0;}
+ void destroyAndClear();
private:
unsigned m_current;
@@ -219,23 +223,20 @@ public:
void setValue(const AtomicString& value) { m_selector->setValue(value); }
void setAttribute(const QualifiedName& value) { m_selector->setAttribute(value); }
void setArgument(const AtomicString& value) { m_selector->setArgument(value); }
- void setMatch(CSSSelector::Match value) { m_selector->m_match = value; }
- void setRelation(CSSSelector::Relation value) { m_selector->m_relation = value; }
+ void setMatch(CSSSelector::Match value) { m_selector->setMatch(value); }
+ void setRelation(CSSSelector::Relation value) { m_selector->setRelation(value); }
void setForPage() { m_selector->setForPage(); }
void setRelationIsAffectedByPseudoContent() { m_selector->setRelationIsAffectedByPseudoContent(); }
bool relationIsAffectedByPseudoContent() const { return m_selector->relationIsAffectedByPseudoContent(); }
void adoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectorVector);
- CSSParserSelector* functionArgumentSelector() const { return m_functionArgumentSelector; }
- void setFunctionArgumentSelector(CSSParserSelector* selector) { m_functionArgumentSelector = selector; }
- bool isDistributedPseudoElement() const { return m_selector->isDistributedPseudoElement(); }
- CSSParserSelector* findDistributedPseudoElementSelector() const;
+ bool hasHostPseudoSelector() const;
bool isContentPseudoElement() const { return m_selector->isContentPseudoElement(); }
CSSSelector::PseudoType pseudoType() const { return m_selector->pseudoType(); }
bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); }
- bool needsCrossingTreeScopeBoundary() const { return isCustomPseudoElement() || pseudoType() == CSSSelector::PseudoCue; }
+ bool crossesTreeScopes() const { return isCustomPseudoElement() || pseudoType() == CSSSelector::PseudoCue || pseudoType() == CSSSelector::PseudoShadow; }
bool isSimple() const;
bool hasShadowPseudo() const;
@@ -250,7 +251,6 @@ public:
private:
OwnPtr<CSSSelector> m_selector;
OwnPtr<CSSParserSelector> m_tagHistory;
- CSSParserSelector* m_functionArgumentSelector;
};
inline bool CSSParserSelector::hasShadowPseudo() const
@@ -274,6 +274,7 @@ inline void CSSParserValue::setFromFunction(CSSParserFunction* function)
id = CSSValueInvalid;
this->function = function;
unit = Function;
+ isInt = false;
}
inline void CSSParserValue::setFromValueList(PassOwnPtr<CSSParserValueList> valueList)
@@ -281,6 +282,7 @@ inline void CSSParserValue::setFromValueList(PassOwnPtr<CSSParserValueList> valu
id = CSSValueInvalid;
this->valueList = valueList.leakPtr();
unit = ValueList;
+ isInt = false;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSParserValuesTest.cpp b/chromium/third_party/WebKit/Source/core/css/CSSParserValuesTest.cpp
index 6d1ac8b939d..5e7bd926f40 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSParserValuesTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSParserValuesTest.cpp
@@ -56,4 +56,45 @@ TEST(CSSParserValuesTest, InitWithEmpty16BitsString)
ASSERT_EQ(0u, cssParserString.length());
}
+TEST(CSSParserValuesTest, EqualIgnoringCase8BitsString)
+{
+ CSSParserString cssParserString;
+ String string8bit("sHaDOw");
+ cssParserString.init(string8bit, 0, string8bit.length());
+
+ ASSERT_TRUE(cssParserString.equalIgnoringCase("shadow"));
+ ASSERT_TRUE(cssParserString.equalIgnoringCase("ShaDow"));
+ ASSERT_FALSE(cssParserString.equalIgnoringCase("shadow-all"));
+ ASSERT_FALSE(cssParserString.equalIgnoringCase("sha"));
+ ASSERT_FALSE(cssParserString.equalIgnoringCase("abCD"));
+}
+
+TEST(CSSParserValuesTest, EqualIgnoringCase16BitsString)
+{
+ String string16bit("sHaDOw");
+ string16bit.ensure16Bit();
+
+ CSSParserString cssParserString;
+ cssParserString.init(string16bit, 0, string16bit.length());
+
+ ASSERT_TRUE(cssParserString.equalIgnoringCase("shadow"));
+ ASSERT_TRUE(cssParserString.equalIgnoringCase("ShaDow"));
+ ASSERT_FALSE(cssParserString.equalIgnoringCase("shadow-all"));
+ ASSERT_FALSE(cssParserString.equalIgnoringCase("sha"));
+ ASSERT_FALSE(cssParserString.equalIgnoringCase("abCD"));
+}
+
+TEST(CSSParserValuesTest, CSSParserValuelistClear)
+{
+ CSSParserValueList list;
+ for (int i = 0; i < 3; ++i) {
+ CSSParserValue value;
+ value.setFromNumber(3);
+ list.addValue(value);
+ }
+ list.clearAndLeakValues();
+ ASSERT_FALSE(list.size());
+ ASSERT_FALSE(list.currentIndex());
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp
index eb350e7a9c0..97497512b54 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp
@@ -25,7 +25,7 @@
#include "core/css/CSSBasicShapes.h"
#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSHelper.h"
-#include "core/css/CSSParser.h"
+#include "core/css/CSSMarkup.h"
#include "core/css/CSSToLengthConversionData.h"
#include "core/css/Counter.h"
#include "core/css/Pair.h"
@@ -35,8 +35,9 @@
#include "core/dom/ExceptionCode.h"
#include "core/dom/Node.h"
#include "core/rendering/style/RenderStyle.h"
+#include "platform/Decimal.h"
#include "platform/LayoutUnit.h"
-#include "wtf/DecimalNumber.h"
+#include "platform/fonts/FontMetrics.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/StringBuffer.h"
#include "wtf/text/StringBuilder.h"
@@ -50,7 +51,7 @@ namespace WebCore {
const int maxValueForCssLength = INT_MAX / kFixedPointDenominator - 2;
const int minValueForCssLength = INT_MIN / kFixedPointDenominator + 2;
-static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::UnitTypes unitType)
+static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::UnitType unitType)
{
switch (unitType) {
case CSSPrimitiveValue::CSS_CALC:
@@ -105,7 +106,6 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit
case CSSPrimitiveValue::CSS_UNICODE_RANGE:
case CSSPrimitiveValue::CSS_UNKNOWN:
case CSSPrimitiveValue::CSS_URI:
- case CSSPrimitiveValue::CSS_VARIABLE_NAME:
return false;
}
@@ -113,7 +113,44 @@ static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::Unit
return false;
}
-CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValue::UnitTypes type)
+typedef HashMap<String, CSSPrimitiveValue::UnitType> StringToUnitTable;
+
+StringToUnitTable createStringToUnitTable()
+{
+ StringToUnitTable table;
+ table.set(String("em"), CSSPrimitiveValue::CSS_EMS);
+ table.set(String("ex"), CSSPrimitiveValue::CSS_EXS);
+ table.set(String("px"), CSSPrimitiveValue::CSS_PX);
+ table.set(String("cm"), CSSPrimitiveValue::CSS_CM);
+ table.set(String("mm"), CSSPrimitiveValue::CSS_MM);
+ table.set(String("in"), CSSPrimitiveValue::CSS_IN);
+ table.set(String("pt"), CSSPrimitiveValue::CSS_PT);
+ table.set(String("pc"), CSSPrimitiveValue::CSS_PC);
+ table.set(String("deg"), CSSPrimitiveValue::CSS_DEG);
+ table.set(String("rad"), CSSPrimitiveValue::CSS_RAD);
+ table.set(String("grad"), CSSPrimitiveValue::CSS_GRAD);
+ table.set(String("ms"), CSSPrimitiveValue::CSS_MS);
+ table.set(String("s"), CSSPrimitiveValue::CSS_S);
+ table.set(String("hz"), CSSPrimitiveValue::CSS_HZ);
+ table.set(String("khz"), CSSPrimitiveValue::CSS_KHZ);
+ table.set(String("dpi"), CSSPrimitiveValue::CSS_DPI);
+ table.set(String("dpcm"), CSSPrimitiveValue::CSS_DPCM);
+ table.set(String("dppx"), CSSPrimitiveValue::CSS_DPPX);
+ table.set(String("vw"), CSSPrimitiveValue::CSS_VW);
+ table.set(String("vh"), CSSPrimitiveValue::CSS_VH);
+ table.set(String("vmax"), CSSPrimitiveValue::CSS_VMIN);
+ table.set(String("vmin"), CSSPrimitiveValue::CSS_VMAX);
+ return table;
+}
+
+
+CSSPrimitiveValue::UnitType CSSPrimitiveValue::fromName(const String& unit)
+{
+ DEFINE_STATIC_LOCAL(StringToUnitTable, unitTable, (createStringToUnitTable()));
+ return unitTable.get(unit.lower());
+}
+
+CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(UnitType type)
{
// Here we violate the spec (http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue) and allow conversions
// between CSS_PX and relative lengths (see cssPixelsPerInch comment in core/css/CSSHelper.h for the topic treatment).
@@ -140,11 +177,6 @@ CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValu
case CSS_HZ:
case CSS_KHZ:
return CSSPrimitiveValue::UFrequency;
- case CSS_VW:
- case CSS_VH:
- case CSS_VMIN:
- case CSS_VMAX:
- return CSSPrimitiveValue::UViewportPercentageLength;
case CSS_DPPX:
case CSS_DPI:
case CSS_DPCM:
@@ -175,13 +207,13 @@ static CSSTextCache& cssTextCache()
return cache;
}
-unsigned short CSSPrimitiveValue::primitiveType() const
+CSSPrimitiveValue::UnitType CSSPrimitiveValue::primitiveType() const
{
if (m_primitiveUnitType == CSS_PROPERTY_ID || m_primitiveUnitType == CSS_VALUE_ID)
return CSS_IDENT;
if (m_primitiveUnitType != CSS_CALC)
- return m_primitiveUnitType;
+ return static_cast<UnitType>(m_primitiveUnitType);
switch (m_value.calc->category()) {
case CalcNumber:
@@ -194,8 +226,6 @@ unsigned short CSSPrimitiveValue::primitiveType() const
return CSS_CALC_PERCENTAGE_WITH_NUMBER;
case CalcPercentLength:
return CSS_CALC_PERCENTAGE_WITH_LENGTH;
- case CalcVariable:
- return CSS_UNKNOWN; // The type of a calculation containing a variable cannot be known until the value of the variable is determined.
case CalcOther:
return CSS_UNKNOWN;
}
@@ -242,14 +272,15 @@ CSSPrimitiveValue::CSSPrimitiveValue(CSSPropertyID propertyID)
m_value.propertyID = propertyID;
}
-CSSPrimitiveValue::CSSPrimitiveValue(int parserOperator)
+CSSPrimitiveValue::CSSPrimitiveValue(int parserOperator, UnitType type)
: CSSValue(PrimitiveClass)
{
+ ASSERT(type == CSS_PARSER_OPERATOR);
m_primitiveUnitType = CSS_PARSER_OPERATOR;
m_value.parserOperator = parserOperator;
}
-CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitTypes type)
+CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitType type)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = type;
@@ -257,7 +288,7 @@ CSSPrimitiveValue::CSSPrimitiveValue(double num, UnitTypes type)
m_value.num = num;
}
-CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitTypes type)
+CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitType type)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = type;
@@ -265,10 +296,16 @@ CSSPrimitiveValue::CSSPrimitiveValue(const String& str, UnitTypes type)
m_value.string->ref();
}
+CSSPrimitiveValue::CSSPrimitiveValue(const LengthSize& lengthSize, const RenderStyle& style)
+ : CSSValue(PrimitiveClass)
+{
+ init(lengthSize, style);
+}
-CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color)
+CSSPrimitiveValue::CSSPrimitiveValue(RGBA32 color, UnitType type)
: CSSValue(PrimitiveClass)
{
+ ASSERT(type == CSS_RGBCOLOR);
m_primitiveUnitType = CSS_RGBCOLOR;
m_value.rgbcolor = color;
}
@@ -278,136 +315,116 @@ CSSPrimitiveValue::CSSPrimitiveValue(const Length& length, float zoom)
{
switch (length.type()) {
case Auto:
+ m_primitiveUnitType = CSS_VALUE_ID;
+ m_value.valueID = CSSValueAuto;
+ break;
case Intrinsic:
+ m_primitiveUnitType = CSS_VALUE_ID;
+ m_value.valueID = CSSValueIntrinsic;
+ break;
case MinIntrinsic:
+ m_primitiveUnitType = CSS_VALUE_ID;
+ m_value.valueID = CSSValueMinIntrinsic;
+ break;
case MinContent:
+ m_primitiveUnitType = CSS_VALUE_ID;
+ m_value.valueID = CSSValueMinContent;
+ break;
case MaxContent:
+ m_primitiveUnitType = CSS_VALUE_ID;
+ m_value.valueID = CSSValueMaxContent;
+ break;
case FillAvailable:
+ m_primitiveUnitType = CSS_VALUE_ID;
+ m_value.valueID = CSSValueWebkitFillAvailable;
+ break;
case FitContent:
+ m_primitiveUnitType = CSS_VALUE_ID;
+ m_value.valueID = CSSValueWebkitFitContent;
+ break;
case ExtendToZoom:
+ m_primitiveUnitType = CSS_VALUE_ID;
+ m_value.valueID = CSSValueInternalExtendToZoom;
+ break;
case Percent:
- case ViewportPercentageWidth:
- case ViewportPercentageHeight:
- case ViewportPercentageMin:
- case ViewportPercentageMax:
- init(length);
- return;
+ m_primitiveUnitType = CSS_PERCENTAGE;
+ ASSERT(std::isfinite(length.percent()));
+ m_value.num = length.percent();
+ break;
case Fixed:
m_primitiveUnitType = CSS_PX;
m_value.num = length.value() / zoom;
- return;
- case Calculated:
- init(CSSCalcValue::create(length.calculationValue(), zoom));
- return;
+ break;
+ case Calculated: {
+ const CalculationValue& calc = length.calculationValue();
+ if (calc.pixels() && calc.percent()) {
+ init(CSSCalcValue::create(
+ CSSCalcValue::createExpressionNode(calc.pixels() / zoom, calc.percent()),
+ calc.isNonNegative() ? ValueRangeNonNegative : ValueRangeAll));
+ break;
+ }
+ if (calc.percent()) {
+ m_primitiveUnitType = CSS_PERCENTAGE;
+ m_value.num = calc.percent();
+ } else {
+ m_primitiveUnitType = CSS_PX;
+ m_value.num = calc.pixels() / zoom;
+ }
+ if (m_value.num < 0 && calc.isNonNegative())
+ m_value.num = 0;
+ break;
+ }
+ case DeviceWidth:
+ case DeviceHeight:
case Undefined:
ASSERT_NOT_REACHED();
break;
}
}
-void CSSPrimitiveValue::init(const Length& length)
+void CSSPrimitiveValue::init(const LengthSize& lengthSize, const RenderStyle& style)
{
- switch (length.type()) {
- case Auto:
- m_primitiveUnitType = CSS_VALUE_ID;
- m_value.valueID = CSSValueAuto;
- break;
- case Fixed:
- m_primitiveUnitType = CSS_PX;
- m_value.num = length.value();
- break;
- case Intrinsic:
- m_primitiveUnitType = CSS_VALUE_ID;
- m_value.valueID = CSSValueIntrinsic;
- break;
- case MinIntrinsic:
- m_primitiveUnitType = CSS_VALUE_ID;
- m_value.valueID = CSSValueMinIntrinsic;
- break;
- case MinContent:
- m_primitiveUnitType = CSS_VALUE_ID;
- m_value.valueID = CSSValueMinContent;
- break;
- case MaxContent:
- m_primitiveUnitType = CSS_VALUE_ID;
- m_value.valueID = CSSValueMaxContent;
- break;
- case FillAvailable:
- m_primitiveUnitType = CSS_VALUE_ID;
- m_value.valueID = CSSValueWebkitFillAvailable;
- break;
- case FitContent:
- m_primitiveUnitType = CSS_VALUE_ID;
- m_value.valueID = CSSValueWebkitFitContent;
- break;
- case ExtendToZoom:
- m_primitiveUnitType = CSS_VALUE_ID;
- m_value.valueID = CSSValueInternalExtendToZoom;
- break;
- case Percent:
- m_primitiveUnitType = CSS_PERCENTAGE;
- ASSERT(std::isfinite(length.percent()));
- m_value.num = length.percent();
- break;
- case ViewportPercentageWidth:
- m_primitiveUnitType = CSS_VW;
- m_value.num = length.viewportPercentageLength();
- break;
- case ViewportPercentageHeight:
- m_primitiveUnitType = CSS_VH;
- m_value.num = length.viewportPercentageLength();
- break;
- case ViewportPercentageMin:
- m_primitiveUnitType = CSS_VMIN;
- m_value.num = length.viewportPercentageLength();
- break;
- case ViewportPercentageMax:
- m_primitiveUnitType = CSS_VMAX;
- m_value.num = length.viewportPercentageLength();
- break;
- case Calculated:
- case Undefined:
- ASSERT_NOT_REACHED();
- break;
- }
+ m_primitiveUnitType = CSS_PAIR;
+ m_hasCachedCSSText = false;
+ m_value.pair = Pair::create(create(lengthSize.width(), style.effectiveZoom()), create(lengthSize.height(), style.effectiveZoom()), Pair::KeepIdenticalValues).leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Counter> c)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Counter> c)
{
m_primitiveUnitType = CSS_COUNTER;
m_hasCachedCSSText = false;
m_value.counter = c.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Rect> r)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Rect> r)
{
m_primitiveUnitType = CSS_RECT;
m_hasCachedCSSText = false;
m_value.rect = r.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Quad> quad)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Quad> quad)
{
m_primitiveUnitType = CSS_QUAD;
m_hasCachedCSSText = false;
m_value.quad = quad.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<Pair> p)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Pair> p)
{
m_primitiveUnitType = CSS_PAIR;
m_hasCachedCSSText = false;
m_value.pair = p.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<CSSCalcValue> c)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<CSSCalcValue> c)
{
m_primitiveUnitType = CSS_CALC;
m_hasCachedCSSText = false;
m_value.calc = c.leakRef();
}
-void CSSPrimitiveValue::init(PassRefPtr<CSSBasicShape> shape)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<CSSBasicShape> shape)
{
m_primitiveUnitType = CSS_SHAPE;
m_hasCachedCSSText = false;
@@ -421,37 +438,54 @@ CSSPrimitiveValue::~CSSPrimitiveValue()
void CSSPrimitiveValue::cleanup()
{
- switch (static_cast<UnitTypes>(m_primitiveUnitType)) {
+ switch (static_cast<UnitType>(m_primitiveUnitType)) {
case CSS_STRING:
case CSS_URI:
case CSS_ATTR:
case CSS_COUNTER_NAME:
- case CSS_VARIABLE_NAME:
case CSS_PARSER_HEXCOLOR:
if (m_value.string)
m_value.string->deref();
break;
case CSS_COUNTER:
+ // We must not call deref() when oilpan is enabled because m_value.counter is traced.
+#if !ENABLE(OILPAN)
m_value.counter->deref();
+#endif
break;
case CSS_RECT:
+ // We must not call deref() when oilpan is enabled because m_value.rect is traced.
+#if !ENABLE(OILPAN)
m_value.rect->deref();
+#endif
break;
case CSS_QUAD:
+ // We must not call deref() when oilpan is enabled because m_value.quad is traced.
+#if !ENABLE(OILPAN)
m_value.quad->deref();
+#endif
break;
case CSS_PAIR:
+ // We must not call deref() when oilpan is enabled because m_value.pair is traced.
+#if !ENABLE(OILPAN)
m_value.pair->deref();
+#endif
break;
case CSS_CALC:
+ // We must not call deref() when oilpan is enabled because m_value.calc is traced.
+#if !ENABLE(OILPAN)
m_value.calc->deref();
+#endif
break;
case CSS_CALC_PERCENTAGE_WITH_NUMBER:
case CSS_CALC_PERCENTAGE_WITH_LENGTH:
ASSERT_NOT_REACHED();
break;
case CSS_SHAPE:
+ // We must not call deref() when oilpan is enabled because m_value.shape is traced.
+#if !ENABLE(OILPAN)
m_value.shape->deref();
+#endif
break;
case CSS_NUMBER:
case CSS_PARSER_INTEGER:
@@ -554,11 +588,14 @@ template<> double CSSPrimitiveValue::computeLength(const CSSToLengthConversionDa
double CSSPrimitiveValue::computeLengthDouble(const CSSToLengthConversionData& conversionData)
{
+ // The logic in this function is duplicated in MediaValues::computeLength
+ // because MediaValues::computeLength needs nearly identical logic, but we haven't found a way to make
+ // CSSPrimitiveValue::computeLengthDouble more generic (to solve both cases) without hurting performance.
if (m_primitiveUnitType == CSS_CALC)
return m_value.calc->computeLengthPx(conversionData);
const RenderStyle& style = conversionData.style();
- const RenderStyle& rootStyle = conversionData.rootStyle();
+ const RenderStyle* rootStyle = conversionData.rootStyle();
bool computingFontSize = conversionData.computingFontSize();
double factor;
@@ -577,7 +614,10 @@ double CSSPrimitiveValue::computeLengthDouble(const CSSToLengthConversionData& c
factor = (computingFontSize ? style.fontDescription().specifiedSize() : style.fontDescription().computedSize()) / 2.0;
break;
case CSS_REMS:
- factor = computingFontSize ? rootStyle.fontDescription().specifiedSize() : rootStyle.fontDescription().computedSize();
+ if (rootStyle)
+ factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
+ else
+ factor = 1.0;
break;
case CSS_CHS:
factor = style.fontMetrics().zeroWidth();
@@ -600,6 +640,18 @@ double CSSPrimitiveValue::computeLengthDouble(const CSSToLengthConversionData& c
case CSS_PC:
factor = cssPixelsPerPica;
break;
+ case CSS_VW:
+ factor = conversionData.viewportWidthPercent();
+ break;
+ case CSS_VH:
+ factor = conversionData.viewportHeightPercent();
+ break;
+ case CSS_VMIN:
+ factor = conversionData.viewportMinPercent();
+ break;
+ case CSS_VMAX:
+ factor = conversionData.viewportMaxPercent();
+ break;
case CSS_CALC_PERCENTAGE_WITH_LENGTH:
case CSS_CALC_PERCENTAGE_WITH_NUMBER:
ASSERT_NOT_REACHED();
@@ -619,15 +671,29 @@ double CSSPrimitiveValue::computeLengthDouble(const CSSToLengthConversionData& c
return result * conversionData.zoom();
}
+void CSSPrimitiveValue::accumulateLengthArray(CSSLengthArray& lengthArray, double multiplier) const
+{
+ ASSERT(lengthArray.size() == LengthUnitTypeCount);
+
+ if (m_primitiveUnitType == CSS_CALC) {
+ cssCalcValue()->accumulateLengthArray(lengthArray, multiplier);
+ return;
+ }
+
+ LengthUnitType lengthType;
+ if (unitTypeToLengthUnitType(static_cast<UnitType>(m_primitiveUnitType), lengthType))
+ lengthArray.at(lengthType) += m_value.num * conversionToCanonicalUnitsScaleFactor(static_cast<UnitType>(m_primitiveUnitType)) * multiplier;
+}
+
void CSSPrimitiveValue::setFloatValue(unsigned short, double, ExceptionState& exceptionState)
{
// Keeping values immutable makes optimizations easier and allows sharing of the primitive value objects.
// No other engine supports mutating style through this API. Computed style is always read-only anyway.
// Supporting setter would require making primitive value copy-on-write and taking care of style invalidation.
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
+ exceptionState.throwDOMException(NoModificationAllowedError, "CSSPrimitiveValue objects are read-only.");
}
-double CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(unsigned short unitType)
+double CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(UnitType unitType)
{
double factor = 1.0;
// FIXME: the switch can be replaced by an array of scale factors.
@@ -679,22 +745,22 @@ double CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(unsigned short u
return factor;
}
-double CSSPrimitiveValue::getDoubleValue(unsigned short unitType, ExceptionState& exceptionState) const
+double CSSPrimitiveValue::getDoubleValue(UnitType unitType, ExceptionState& exceptionState) const
{
double result = 0;
- bool success = getDoubleValueInternal(static_cast<UnitTypes>(unitType), &result);
+ bool success = getDoubleValueInternal(unitType, &result);
if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "Failed to obtain a double value.");
return 0.0;
}
return result;
}
-double CSSPrimitiveValue::getDoubleValue(unsigned short unitType) const
+double CSSPrimitiveValue::getDoubleValue(UnitType unitType) const
{
double result = 0;
- getDoubleValueInternal(static_cast<UnitTypes>(unitType), &result);
+ getDoubleValueInternal(unitType, &result);
return result;
}
@@ -703,9 +769,9 @@ double CSSPrimitiveValue::getDoubleValue() const
return m_primitiveUnitType != CSS_CALC ? m_value.num : m_value.calc->doubleValue();
}
-CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(UnitCategory category)
+CSSPrimitiveValue::UnitType CSSPrimitiveValue::canonicalUnitTypeForCategory(UnitCategory category)
{
- // The canonical unit type is chosen according to the way CSSParser::validUnit() chooses the default unit
+ // The canonical unit type is chosen according to the way BisonCSSParser::validUnit() chooses the default unit
// in each category (based on unitflags).
switch (category) {
case UNumber:
@@ -720,8 +786,6 @@ CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(Uni
return CSS_DEG;
case UFrequency:
return CSS_HZ;
- case UViewportPercentageLength:
- return CSS_UNKNOWN; // Cannot convert between numbers and relative lengths.
case UResolution:
return CSS_DPPX;
default:
@@ -729,12 +793,12 @@ CSSPrimitiveValue::UnitTypes CSSPrimitiveValue::canonicalUnitTypeForCategory(Uni
}
}
-bool CSSPrimitiveValue::getDoubleValueInternal(UnitTypes requestedUnitType, double* result) const
+bool CSSPrimitiveValue::getDoubleValueInternal(UnitType requestedUnitType, double* result) const
{
- if (!isValidCSSUnitTypeForDoubleConversion(static_cast<UnitTypes>(m_primitiveUnitType)) || !isValidCSSUnitTypeForDoubleConversion(requestedUnitType))
+ if (!isValidCSSUnitTypeForDoubleConversion(static_cast<UnitType>(m_primitiveUnitType)) || !isValidCSSUnitTypeForDoubleConversion(requestedUnitType))
return false;
- UnitTypes sourceUnitType = static_cast<UnitTypes>(primitiveType());
+ UnitType sourceUnitType = primitiveType();
if (requestedUnitType == sourceUnitType || requestedUnitType == CSS_DIMENSION) {
*result = getDoubleValue();
return true;
@@ -743,7 +807,7 @@ bool CSSPrimitiveValue::getDoubleValueInternal(UnitTypes requestedUnitType, doub
UnitCategory sourceCategory = unitCategory(sourceUnitType);
ASSERT(sourceCategory != UOther);
- UnitTypes targetUnitType = requestedUnitType;
+ UnitType targetUnitType = requestedUnitType;
UnitCategory targetCategory = unitCategory(targetUnitType);
ASSERT(targetCategory != UOther);
@@ -759,7 +823,7 @@ bool CSSPrimitiveValue::getDoubleValueInternal(UnitTypes requestedUnitType, doub
}
if (sourceUnitType == CSS_NUMBER) {
- // We interpret conversion from CSS_NUMBER in the same way as CSSParser::validUnit() while using non-strict mode.
+ // We interpret conversion from CSS_NUMBER in the same way as BisonCSSParser::validUnit() while using non-strict mode.
sourceUnitType = canonicalUnitTypeForCategory(targetCategory);
if (sourceUnitType == CSS_UNKNOWN)
return false;
@@ -779,12 +843,85 @@ bool CSSPrimitiveValue::getDoubleValueInternal(UnitTypes requestedUnitType, doub
return true;
}
+bool CSSPrimitiveValue::unitTypeToLengthUnitType(UnitType unitType, LengthUnitType& lengthType)
+{
+ switch (unitType) {
+ case CSSPrimitiveValue::CSS_PX:
+ case CSSPrimitiveValue::CSS_CM:
+ case CSSPrimitiveValue::CSS_MM:
+ case CSSPrimitiveValue::CSS_IN:
+ case CSSPrimitiveValue::CSS_PT:
+ case CSSPrimitiveValue::CSS_PC:
+ lengthType = UnitTypePixels;
+ return true;
+ case CSSPrimitiveValue::CSS_EMS:
+ lengthType = UnitTypeFontSize;
+ return true;
+ case CSSPrimitiveValue::CSS_EXS:
+ lengthType = UnitTypeFontXSize;
+ return true;
+ case CSSPrimitiveValue::CSS_REMS:
+ lengthType = UnitTypeRootFontSize;
+ return true;
+ case CSSPrimitiveValue::CSS_CHS:
+ lengthType = UnitTypeZeroCharacterWidth;
+ return true;
+ case CSSPrimitiveValue::CSS_PERCENTAGE:
+ lengthType = UnitTypePercentage;
+ return true;
+ case CSSPrimitiveValue::CSS_VW:
+ lengthType = UnitTypeViewportWidth;
+ return true;
+ case CSSPrimitiveValue::CSS_VH:
+ lengthType = UnitTypeViewportHeight;
+ return true;
+ case CSSPrimitiveValue::CSS_VMIN:
+ lengthType = UnitTypeViewportMin;
+ return true;
+ case CSSPrimitiveValue::CSS_VMAX:
+ lengthType = UnitTypeViewportMax;
+ return true;
+ default:
+ return false;
+ }
+}
+
+CSSPrimitiveValue::UnitType CSSPrimitiveValue::lengthUnitTypeToUnitType(LengthUnitType type)
+{
+ switch (type) {
+ case UnitTypePixels:
+ return CSSPrimitiveValue::CSS_PX;
+ case UnitTypeFontSize:
+ return CSSPrimitiveValue::CSS_EMS;
+ case UnitTypeFontXSize:
+ return CSSPrimitiveValue::CSS_EXS;
+ case UnitTypeRootFontSize:
+ return CSSPrimitiveValue::CSS_REMS;
+ case UnitTypeZeroCharacterWidth:
+ return CSSPrimitiveValue::CSS_CHS;
+ case UnitTypePercentage:
+ return CSSPrimitiveValue::CSS_PERCENTAGE;
+ case UnitTypeViewportWidth:
+ return CSSPrimitiveValue::CSS_VW;
+ case UnitTypeViewportHeight:
+ return CSSPrimitiveValue::CSS_VH;
+ case UnitTypeViewportMin:
+ return CSSPrimitiveValue::CSS_VMIN;
+ case UnitTypeViewportMax:
+ return CSSPrimitiveValue::CSS_VMAX;
+ case LengthUnitTypeCount:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return CSSPrimitiveValue::CSS_UNKNOWN;
+}
+
void CSSPrimitiveValue::setStringValue(unsigned short, const String&, ExceptionState& exceptionState)
{
// Keeping values immutable makes optimizations easier and allows sharing of the primitive value objects.
// No other engine supports mutating style through this API. Computed style is always read-only anyway.
// Supporting setter would require making primitive value copy-on-write and taking care of style invalidation.
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
+ exceptionState.throwDOMException(NoModificationAllowedError, "CSSPrimitiveValue objects are read-only.");
}
String CSSPrimitiveValue::getStringValue(ExceptionState& exceptionState) const
@@ -793,14 +930,13 @@ String CSSPrimitiveValue::getStringValue(ExceptionState& exceptionState) const
case CSS_STRING:
case CSS_ATTR:
case CSS_URI:
- case CSS_VARIABLE_NAME:
return m_value.string;
case CSS_VALUE_ID:
return valueName(m_value.valueID);
case CSS_PROPERTY_ID:
return propertyName(m_value.propertyID);
default:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "This object's value cannot be represented as a string.");
break;
}
@@ -813,7 +949,6 @@ String CSSPrimitiveValue::getStringValue() const
case CSS_STRING:
case CSS_ATTR:
case CSS_URI:
- case CSS_VARIABLE_NAME:
return m_value.string;
case CSS_VALUE_ID:
return valueName(m_value.valueID);
@@ -829,7 +964,7 @@ String CSSPrimitiveValue::getStringValue() const
Counter* CSSPrimitiveValue::getCounterValue(ExceptionState& exceptionState) const
{
if (m_primitiveUnitType != CSS_COUNTER) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "This object is not a counter value.");
return 0;
}
@@ -839,7 +974,7 @@ Counter* CSSPrimitiveValue::getCounterValue(ExceptionState& exceptionState) cons
Rect* CSSPrimitiveValue::getRectValue(ExceptionState& exceptionState) const
{
if (m_primitiveUnitType != CSS_RECT) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "This object is not a rect value.");
return 0;
}
@@ -849,18 +984,18 @@ Rect* CSSPrimitiveValue::getRectValue(ExceptionState& exceptionState) const
Quad* CSSPrimitiveValue::getQuadValue(ExceptionState& exceptionState) const
{
if (m_primitiveUnitType != CSS_QUAD) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "This object is not a quad value.");
return 0;
}
return m_value.quad;
}
-PassRefPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionState& exceptionState) const
{
if (m_primitiveUnitType != CSS_RGBCOLOR) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, "This object is not an RGB color value.");
+ return nullptr;
}
// FIMXE: This should not return a new object for each invocation.
@@ -870,7 +1005,7 @@ PassRefPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionState& excepti
Pair* CSSPrimitiveValue::getPairValue(ExceptionState& exceptionState) const
{
if (m_primitiveUnitType != CSS_PAIR) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "This object is not a pair value.");
return 0;
}
@@ -879,16 +1014,10 @@ Pair* CSSPrimitiveValue::getPairValue(ExceptionState& exceptionState) const
static String formatNumber(double number, const char* suffix, unsigned suffixLength)
{
- DecimalNumber decimal(number);
-
- StringBuffer<LChar> buffer(decimal.bufferLengthForStringDecimal() + suffixLength);
- unsigned length = decimal.toStringDecimal(buffer.characters(), buffer.length());
- ASSERT(length + suffixLength == buffer.length());
-
- for (unsigned i = 0; i < suffixLength; ++i)
- buffer[length + i] = static_cast<LChar>(suffix[i]);
-
- return String::adopt(buffer);
+ Decimal decimal = Decimal::fromDouble(number);
+ String result = decimal.toString();
+ result.append(suffix, suffixLength);
+ return result;
}
template <unsigned characterCount>
@@ -897,6 +1026,99 @@ ALWAYS_INLINE static String formatNumber(double number, const char (&characters)
return formatNumber(number, characters, characterCount - 1);
}
+static String formatNumber(double number, const char* characters)
+{
+ return formatNumber(number, characters, strlen(characters));
+}
+
+const char* CSSPrimitiveValue::unitTypeToString(UnitType type)
+{
+ switch (type) {
+ case CSS_NUMBER:
+ case CSS_PARSER_INTEGER:
+ return "";
+ case CSS_PERCENTAGE:
+ return "%";
+ case CSS_EMS:
+ return "em";
+ case CSS_EXS:
+ return "ex";
+ case CSS_REMS:
+ return "rem";
+ case CSS_CHS:
+ return "ch";
+ case CSS_PX:
+ return "px";
+ case CSS_CM:
+ return "cm";
+ case CSS_DPPX:
+ return "dppx";
+ case CSS_DPI:
+ return "dpi";
+ case CSS_DPCM:
+ return "dpcm";
+ case CSS_MM:
+ return "mm";
+ case CSS_IN:
+ return "in";
+ case CSS_PT:
+ return "pt";
+ case CSS_PC:
+ return "pc";
+ case CSS_DEG:
+ return "deg";
+ case CSS_RAD:
+ return "rad";
+ case CSS_GRAD:
+ return "grad";
+ case CSS_MS:
+ return "ms";
+ case CSS_S:
+ return "s";
+ case CSS_HZ:
+ return "hz";
+ case CSS_KHZ:
+ return "khz";
+ case CSS_TURN:
+ return "turn";
+ case CSS_FR:
+ return "fr";
+ case CSS_VW:
+ return "vw";
+ case CSS_VH:
+ return "vh";
+ case CSS_VMIN:
+ return "vmin";
+ case CSS_VMAX:
+ return "vmax";
+ case CSS_UNKNOWN:
+ case CSS_DIMENSION:
+ case CSS_STRING:
+ case CSS_URI:
+ case CSS_VALUE_ID:
+ case CSS_PROPERTY_ID:
+ case CSS_ATTR:
+ case CSS_COUNTER_NAME:
+ case CSS_COUNTER:
+ case CSS_RECT:
+ case CSS_QUAD:
+ case CSS_RGBCOLOR:
+ case CSS_PARSER_HEXCOLOR:
+ case CSS_PAIR:
+ case CSS_PARSER_OPERATOR:
+ case CSS_PARSER_IDENTIFIER:
+ case CSS_CALC:
+ case CSS_SHAPE:
+ case CSS_IDENT:
+ case CSS_UNICODE_RANGE:
+ case CSS_CALC_PERCENTAGE_WITH_NUMBER:
+ case CSS_CALC_PERCENTAGE_WITH_LENGTH:
+ break;
+ };
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
String CSSPrimitiveValue::customCSSText(CSSTextFormattingFlags formattingFlag) const
{
// FIXME: return the original value instead of a generated one (e.g. color
@@ -914,74 +1136,34 @@ String CSSPrimitiveValue::customCSSText(CSSTextFormattingFlags formattingFlag) c
break;
case CSS_NUMBER:
case CSS_PARSER_INTEGER:
- text = formatNumber(m_value.num, "");
- break;
case CSS_PERCENTAGE:
- text = formatNumber(m_value.num, "%");
- break;
case CSS_EMS:
- text = formatNumber(m_value.num, "em");
- break;
case CSS_EXS:
- text = formatNumber(m_value.num, "ex");
- break;
case CSS_REMS:
- text = formatNumber(m_value.num, "rem");
- break;
case CSS_CHS:
- text = formatNumber(m_value.num, "ch");
- break;
case CSS_PX:
- text = formatNumber(m_value.num, "px");
- break;
case CSS_CM:
- text = formatNumber(m_value.num, "cm");
- break;
case CSS_DPPX:
- text = formatNumber(m_value.num, "dppx");
- break;
case CSS_DPI:
- text = formatNumber(m_value.num, "dpi");
- break;
case CSS_DPCM:
- text = formatNumber(m_value.num, "dpcm");
- break;
case CSS_MM:
- text = formatNumber(m_value.num, "mm");
- break;
case CSS_IN:
- text = formatNumber(m_value.num, "in");
- break;
case CSS_PT:
- text = formatNumber(m_value.num, "pt");
- break;
case CSS_PC:
- text = formatNumber(m_value.num, "pc");
- break;
case CSS_DEG:
- text = formatNumber(m_value.num, "deg");
- break;
case CSS_RAD:
- text = formatNumber(m_value.num, "rad");
- break;
case CSS_GRAD:
- text = formatNumber(m_value.num, "grad");
- break;
case CSS_MS:
- text = formatNumber(m_value.num, "ms");
- break;
case CSS_S:
- text = formatNumber(m_value.num, "s");
- break;
case CSS_HZ:
- text = formatNumber(m_value.num, "hz");
- break;
case CSS_KHZ:
- text = formatNumber(m_value.num, "khz");
- break;
case CSS_TURN:
- text = formatNumber(m_value.num, "turn");
- break;
+ case CSS_FR:
+ case CSS_VW:
+ case CSS_VH:
+ case CSS_VMIN:
+ case CSS_VMAX:
+ text = formatNumber(m_value.num, unitTypeToString((UnitType)m_primitiveUnitType));
case CSS_DIMENSION:
// FIXME: We currently don't handle CSS_DIMENSION properly as we don't store
// the actual dimension, just the numeric value as a string.
@@ -1046,37 +1228,9 @@ String CSSPrimitiveValue::customCSSText(CSSTextFormattingFlags formattingFlag) c
if (m_primitiveUnitType == CSS_PARSER_HEXCOLOR)
Color::parseHexColor(m_value.string, rgbColor);
Color color(rgbColor);
-
- StringBuilder result;
- result.reserveCapacity(32);
- bool colorHasAlpha = color.hasAlpha();
- if (colorHasAlpha)
- result.append("rgba(", 5);
- else
- result.append("rgb(", 4);
-
- result.appendNumber(static_cast<unsigned char>(color.red()));
- result.append(", ", 2);
-
- result.appendNumber(static_cast<unsigned char>(color.green()));
- result.append(", ", 2);
-
- result.appendNumber(static_cast<unsigned char>(color.blue()));
- if (colorHasAlpha) {
- result.append(", ", 2);
-
- NumberToStringBuffer buffer;
- const char* alphaString = numberToFixedPrecisionString(color.alpha() / 255.0f, 6, buffer, true);
- result.append(alphaString, strlen(alphaString));
- }
-
- result.append(')');
- text = result.toString();
+ text = color.serializedAsCSSComponentValue();
break;
}
- case CSS_FR:
- text = formatNumber(m_value.num, "fr");
- break;
case CSS_PAIR:
text = getPairValue()->cssText();
break;
@@ -1094,21 +1248,6 @@ String CSSPrimitiveValue::customCSSText(CSSTextFormattingFlags formattingFlag) c
case CSS_SHAPE:
text = m_value.shape->cssText();
break;
- case CSS_VW:
- text = formatNumber(m_value.num, "vw");
- break;
- case CSS_VH:
- text = formatNumber(m_value.num, "vh");
- break;
- case CSS_VMIN:
- text = formatNumber(m_value.num, "vmin");
- break;
- case CSS_VMAX:
- text = formatNumber(m_value.num, "vmax");
- break;
- case CSS_VARIABLE_NAME:
- text = "var(" + String(m_value.string) + ")";
- break;
}
ASSERT(!cssTextCache().contains(this));
@@ -1117,80 +1256,16 @@ String CSSPrimitiveValue::customCSSText(CSSTextFormattingFlags formattingFlag) c
return text;
}
-String CSSPrimitiveValue::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const
{
- if (isVariableName()) {
- AtomicString variableName(m_value.string);
- if (variables.contains(variableName))
- return variables.get(variableName);
- }
- if (CSSCalcValue* calcValue = cssCalcValue())
- return calcValue->customSerializeResolvingVariables(variables);
- if (Pair* pairValue = getPairValue())
- return pairValue->serializeResolvingVariables(variables);
- if (Rect* rectVal = getRectValue())
- return rectVal->serializeResolvingVariables(variables);
- if (Quad* quadVal = getQuadValue())
- return quadVal->serializeResolvingVariables(variables);
- if (CSSBasicShape* shapeValue = getShapeValue())
- return shapeValue->serializeResolvingVariables(variables);
- return customCSSText();
-}
-
-bool CSSPrimitiveValue::hasVariableReference() const
-{
- if (CSSCalcValue* calcValue = cssCalcValue())
- return calcValue->hasVariableReference();
- if (Pair* pairValue = getPairValue())
- return pairValue->hasVariableReference();
- if (Quad* quadValue = getQuadValue())
- return quadValue->hasVariableReference();
- if (Rect* rectValue = getRectValue())
- return rectValue->hasVariableReference();
- if (CSSBasicShape* shapeValue = getShapeValue())
- return shapeValue->hasVariableReference();
- return isVariableName();
-}
-
-void CSSPrimitiveValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const
-{
- if (m_primitiveUnitType == CSS_URI)
- addSubresourceURL(urls, styleSheet->completeURL(m_value.string));
-}
-
-Length CSSPrimitiveValue::viewportPercentageLength()
-{
- ASSERT(isViewportPercentageLength());
- Length viewportLength;
- switch (m_primitiveUnitType) {
- case CSS_VW:
- viewportLength = Length(getDoubleValue(), ViewportPercentageWidth);
- break;
- case CSS_VH:
- viewportLength = Length(getDoubleValue(), ViewportPercentageHeight);
- break;
- case CSS_VMIN:
- viewportLength = Length(getDoubleValue(), ViewportPercentageMin);
- break;
- case CSS_VMAX:
- viewportLength = Length(getDoubleValue(), ViewportPercentageMax);
- break;
- default:
- break;
- }
- return viewportLength;
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const
-{
- RefPtr<CSSPrimitiveValue> result;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = nullptr;
switch (m_primitiveUnitType) {
case CSS_STRING:
case CSS_URI:
case CSS_ATTR:
case CSS_COUNTER_NAME:
- result = CSSPrimitiveValue::create(m_value.string, static_cast<UnitTypes>(m_primitiveUnitType));
+ result = CSSPrimitiveValue::create(m_value.string, static_cast<UnitType>(m_primitiveUnitType));
break;
case CSS_COUNTER:
result = CSSPrimitiveValue::create(m_value.counter->cloneForCSSOM());
@@ -1242,7 +1317,7 @@ PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::cloneForCSSOM() const
case CSS_DPI:
case CSS_DPCM:
case CSS_FR:
- result = CSSPrimitiveValue::create(m_value.num, static_cast<UnitTypes>(m_primitiveUnitType));
+ result = CSSPrimitiveValue::create(m_value.num, static_cast<UnitType>(m_primitiveUnitType));
break;
case CSS_PROPERTY_ID:
result = CSSPrimitiveValue::createIdentifier(m_value.propertyID);
@@ -1315,7 +1390,6 @@ bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
case CSS_COUNTER_NAME:
case CSS_PARSER_IDENTIFIER:
case CSS_PARSER_HEXCOLOR:
- case CSS_VARIABLE_NAME:
return equal(m_value.string, other.m_value.string);
case CSS_COUNTER:
return m_value.counter && other.m_value.counter && m_value.counter->equals(*other.m_value.counter);
@@ -1337,4 +1411,31 @@ bool CSSPrimitiveValue::equals(const CSSPrimitiveValue& other) const
return false;
}
+void CSSPrimitiveValue::traceAfterDispatch(Visitor* visitor)
+{
+ switch (m_primitiveUnitType) {
+ case CSS_COUNTER:
+ visitor->trace(m_value.counter);
+ break;
+ case CSS_RECT:
+ visitor->trace(m_value.rect);
+ break;
+ case CSS_QUAD:
+ visitor->trace(m_value.quad);
+ break;
+ case CSS_PAIR:
+ visitor->trace(m_value.pair);
+ break;
+ case CSS_CALC:
+ visitor->trace(m_value.calc);
+ break;
+ case CSS_SHAPE:
+ visitor->trace(m_value.shape);
+ break;
+ default:
+ break;
+ }
+ CSSValue::traceAfterDispatch(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h b/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h
index 65b1cfbf66f..76846ab687d 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValue.h
@@ -22,8 +22,8 @@
#ifndef CSSPrimitiveValue_h
#define CSSPrimitiveValue_h
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
#include "core/css/CSSValue.h"
#include "platform/graphics/Color.h"
#include "wtf/Forward.h"
@@ -38,6 +38,7 @@ class CSSToLengthConversionData;
class Counter;
class ExceptionState;
class Length;
+class LengthSize;
class Pair;
class Quad;
class RGBColor;
@@ -64,9 +65,13 @@ template<> inline float roundForImpreciseConversion(double value)
return static_cast<float>(value);
}
+// CSSPrimitiveValues are immutable. This class has manual ref-counting
+// of unioned types and does not have the code necessary
+// to handle any kind of mutations. All DOM-exposed "setters" just throw
+// exceptions.
class CSSPrimitiveValue : public CSSValue {
public:
- enum UnitTypes {
+ enum UnitType {
CSS_UNKNOWN = 0,
CSS_NUMBER = 1,
CSS_PERCENTAGE = 2,
@@ -130,13 +135,31 @@ public:
CSS_CALC = 113,
CSS_CALC_PERCENTAGE_WITH_NUMBER = 114,
CSS_CALC_PERCENTAGE_WITH_LENGTH = 115,
- CSS_VARIABLE_NAME = 116,
CSS_PROPERTY_ID = 117,
CSS_VALUE_ID = 118
};
- // This enum follows the CSSParser::Units enum augmented with UNIT_FREQUENCY for frequencies.
+ enum LengthUnitType {
+ UnitTypePixels = 0,
+ UnitTypePercentage,
+ UnitTypeFontSize,
+ UnitTypeFontXSize,
+ UnitTypeRootFontSize,
+ UnitTypeZeroCharacterWidth,
+ UnitTypeViewportWidth,
+ UnitTypeViewportHeight,
+ UnitTypeViewportMin,
+ UnitTypeViewportMax,
+
+ // This value must come after the last length unit type to enable iteration over the length unit types.
+ LengthUnitTypeCount,
+ };
+
+ typedef Vector<double, CSSPrimitiveValue::LengthUnitTypeCount> CSSLengthArray;
+ void accumulateLengthArray(CSSLengthArray&, double multiplier = 1) const;
+
+ // This enum follows the BisonCSSParser::Units enum augmented with UNIT_FREQUENCY for frequencies.
enum UnitCategory {
UNumber,
UPercent,
@@ -144,11 +167,12 @@ public:
UAngle,
UTime,
UFrequency,
- UViewportPercentageLength,
UResolution,
UOther
};
- static UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes);
+ static UnitCategory unitCategory(UnitType);
+
+ static UnitType fromName(const String& unit);
bool isAngle() const
{
@@ -167,11 +191,13 @@ public:
|| m_primitiveUnitType == CSS_REMS
|| m_primitiveUnitType == CSS_CHS;
}
- bool isLength() const
+ bool isViewportPercentageLength() const { return isViewportPercentageLength(static_cast<UnitType>(m_primitiveUnitType)); }
+ static bool isViewportPercentageLength(UnitType type) { return type >= CSS_VW && type <= CSS_VMAX; }
+ static bool isLength(UnitType type)
{
- unsigned short type = primitiveType();
- return (type >= CSS_EMS && type <= CSS_PC) || type == CSS_REMS || type == CSS_CHS;
+ return (type >= CSS_EMS && type <= CSS_PC) || type == CSS_REMS || type == CSS_CHS || isViewportPercentageLength(type);
}
+ bool isLength() const { return isLength(primitiveType()); }
bool isNumber() const { return primitiveType() == CSS_NUMBER; }
bool isPercentage() const { return primitiveType() == CSS_PERCENTAGE; }
bool isPx() const { return primitiveType() == CSS_PX; }
@@ -184,49 +210,67 @@ public:
bool isCalculated() const { return m_primitiveUnitType == CSS_CALC; }
bool isCalculatedPercentageWithNumber() const { return primitiveType() == CSS_CALC_PERCENTAGE_WITH_NUMBER; }
bool isCalculatedPercentageWithLength() const { return primitiveType() == CSS_CALC_PERCENTAGE_WITH_LENGTH; }
- bool isDotsPerInch() const { return primitiveType() == CSS_DPI; }
- bool isDotsPerPixel() const { return primitiveType() == CSS_DPPX; }
- bool isDotsPerCentimeter() const { return primitiveType() == CSS_DPCM; }
- bool isResolution() const
- {
- unsigned short type = primitiveType();
- return type >= CSS_DPPX && type <= CSS_DPCM;
- }
- bool isVariableName() const { return primitiveType() == CSS_VARIABLE_NAME; }
- bool isViewportPercentageLength() const { return m_primitiveUnitType >= CSS_VW && m_primitiveUnitType <= CSS_VMAX; }
+ static bool isDotsPerInch(UnitType type) { return type == CSS_DPI; }
+ static bool isDotsPerPixel(UnitType type) { return type == CSS_DPPX; }
+ static bool isDotsPerCentimeter(UnitType type) { return type == CSS_DPCM; }
+ static bool isResolution(UnitType type) { return type >= CSS_DPPX && type <= CSS_DPCM; }
bool isFlex() const { return primitiveType() == CSS_FR; }
bool isValueID() const { return m_primitiveUnitType == CSS_VALUE_ID; }
bool colorIsDerivedFromElement() const;
- static PassRefPtr<CSSPrimitiveValue> createIdentifier(CSSValueID valueID) { return adoptRef(new CSSPrimitiveValue(valueID)); }
- static PassRefPtr<CSSPrimitiveValue> createIdentifier(CSSPropertyID propertyID) { return adoptRef(new CSSPrimitiveValue(propertyID)); }
- static PassRefPtr<CSSPrimitiveValue> createParserOperator(int parserOperator) { return adoptRef(new CSSPrimitiveValue(parserOperator)); }
- static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue) { return adoptRef(new CSSPrimitiveValue(rgbValue)); }
- static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); }
- static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); }
- static PassRefPtr<CSSPrimitiveValue> create(const Length& value, float zoom) { return adoptRef(new CSSPrimitiveValue(value, zoom)); }
-
- template<typename T> static PassRefPtr<CSSPrimitiveValue> create(T value)
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createIdentifier(CSSValueID valueID)
+ {
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(valueID));
+ }
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createIdentifier(CSSPropertyID propertyID)
+ {
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(propertyID));
+ }
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createParserOperator(int parserOperator)
+ {
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(parserOperator, CSS_PARSER_OPERATOR));
+ }
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createColor(unsigned rgbValue)
+ {
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(rgbValue, CSS_RGBCOLOR));
+ }
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(double value, UnitType type)
+ {
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(value, type));
+ }
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const String& value, UnitType type)
+ {
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(value, type));
+ }
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const Length& value, float zoom)
+ {
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(value, zoom));
+ }
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const LengthSize& value, const RenderStyle& style)
+ {
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(value, style));
+ }
+ template<typename T> static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(T value)
{
- return adoptRef(new CSSPrimitiveValue(value));
+ return adoptRefWillBeNoop(new CSSPrimitiveValue(value));
}
// This value is used to handle quirky margins in reflow roots (body, td, and th) like WinIE.
// The basic idea is that a stylesheet can use the value __qem (for quirky em) instead of em.
// When the quirky value is used, if you're in quirks mode, the margin will collapse away
// inside a table cell.
- static PassRefPtr<CSSPrimitiveValue> createAllowingMarginQuirk(double value, UnitTypes type)
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createAllowingMarginQuirk(double value, UnitType type)
{
CSSPrimitiveValue* quirkValue = new CSSPrimitiveValue(value, type);
quirkValue->m_isQuirkValue = true;
- return adoptRef(quirkValue);
+ return adoptRefWillBeNoop(quirkValue);
}
~CSSPrimitiveValue();
void cleanup();
- unsigned short primitiveType() const;
+ UnitType primitiveType() const;
double computeDegrees();
@@ -259,24 +303,22 @@ public:
// Converts to a Length, mapping various unit types appropriately.
template<int> Length convertToLength(const CSSToLengthConversionData&);
- // use with care!!!
- void setPrimitiveType(unsigned short type) { m_primitiveUnitType = type; }
-
- double getDoubleValue(unsigned short unitType, ExceptionState&) const;
- double getDoubleValue(unsigned short unitType) const;
+ double getDoubleValue(UnitType, ExceptionState&) const;
+ double getDoubleValue(UnitType) const;
double getDoubleValue() const;
+ // setFloatValue(..., ExceptionState&) and setStringValue() must use unsigned short instead of UnitType to match IDL bindings.
void setFloatValue(unsigned short unitType, double floatValue, ExceptionState&);
- float getFloatValue(unsigned short unitType, ExceptionState& exceptionState) const { return getValue<float>(unitType, exceptionState); }
- float getFloatValue(unsigned short unitType) const { return getValue<float>(unitType); }
+ float getFloatValue(unsigned short unitType, ExceptionState& exceptionState) const { return getValue<float>(static_cast<UnitType>(unitType), exceptionState); }
+ float getFloatValue(UnitType type) const { return getValue<float>(type); }
float getFloatValue() const { return getValue<float>(); }
- int getIntValue(unsigned short unitType, ExceptionState& exceptionState) const { return getValue<int>(unitType, exceptionState); }
- int getIntValue(unsigned short unitType) const { return getValue<int>(unitType); }
+ int getIntValue(UnitType type, ExceptionState& exceptionState) const { return getValue<int>(type, exceptionState); }
+ int getIntValue(UnitType type) const { return getValue<int>(type); }
int getIntValue() const { return getValue<int>(); }
- template<typename T> inline T getValue(unsigned short unitType, ExceptionState& exceptionState) const { return clampTo<T>(getDoubleValue(unitType, exceptionState)); }
- template<typename T> inline T getValue(unsigned short unitType) const { return clampTo<T>(getDoubleValue(unitType)); }
+ template<typename T> inline T getValue(UnitType type, ExceptionState& exceptionState) const { return clampTo<T>(getDoubleValue(type, exceptionState)); }
+ template<typename T> inline T getValue(UnitType type) const { return clampTo<T>(getDoubleValue(type)); }
template<typename T> inline T getValue() const { return clampTo<T>(getDoubleValue()); }
void setStringValue(unsigned short stringType, const String& stringValue, ExceptionState&);
@@ -292,7 +334,7 @@ public:
Quad* getQuadValue(ExceptionState&) const;
Quad* getQuadValue() const { return m_primitiveUnitType != CSS_QUAD ? 0 : m_value.quad; }
- PassRefPtr<RGBColor> getRGBColorValue(ExceptionState&) const;
+ PassRefPtrWillBeRawPtr<RGBColor> getRGBColorValue(ExceptionState&) const;
RGBA32 getRGBA32Value() const { return m_primitiveUnitType != CSS_RGBCOLOR ? 0 : m_value.rgbcolor; }
Pair* getPairValue(ExceptionState&) const;
@@ -307,47 +349,44 @@ public:
template<typename T> inline operator T() const; // Defined in CSSPrimitiveValueMappings.h
+ static const char* unitTypeToString(UnitType);
String customCSSText(CSSTextFormattingFlags = QuoteCSSStringIfNeeded) const;
- String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const;
- bool hasVariableReference() const;
bool isQuirkValue() { return m_isQuirkValue; }
- void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
-
- Length viewportPercentageLength();
-
- PassRefPtr<CSSPrimitiveValue> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> cloneForCSSOM() const;
void setCSSOMSafe() { m_isCSSOMSafe = true; }
bool equals(const CSSPrimitiveValue&) const;
- static UnitTypes canonicalUnitTypeForCategory(UnitCategory);
- static double conversionToCanonicalUnitsScaleFactor(unsigned short unitType);
+ void traceAfterDispatch(Visitor*);
+
+ static UnitType canonicalUnitTypeForCategory(UnitCategory);
+ static double conversionToCanonicalUnitsScaleFactor(UnitType);
+
+ // Returns true and populates lengthUnitType, if unitType is a length unit. Otherwise, returns false.
+ static bool unitTypeToLengthUnitType(UnitType, LengthUnitType&);
+ static UnitType lengthUnitTypeToUnitType(LengthUnitType);
private:
CSSPrimitiveValue(CSSValueID);
CSSPrimitiveValue(CSSPropertyID);
- // FIXME: int vs. unsigned overloading is too subtle to distinguish the color and operator cases.
- CSSPrimitiveValue(int parserOperator);
- CSSPrimitiveValue(unsigned color); // RGB value
- CSSPrimitiveValue(const Length& length)
- : CSSValue(PrimitiveClass)
- {
- init(length);
- }
+ // int vs. unsigned is too subtle to distinguish types, so require a UnitType.
+ CSSPrimitiveValue(int parserOperator, UnitType);
+ CSSPrimitiveValue(unsigned color, UnitType); // RGB value
CSSPrimitiveValue(const Length&, float zoom);
- CSSPrimitiveValue(const String&, UnitTypes);
- CSSPrimitiveValue(double, UnitTypes);
+ CSSPrimitiveValue(const LengthSize&, const RenderStyle&);
+ CSSPrimitiveValue(const String&, UnitType);
+ CSSPrimitiveValue(double, UnitType);
template<typename T> CSSPrimitiveValue(T); // Defined in CSSPrimitiveValueMappings.h
template<typename T> CSSPrimitiveValue(T* val)
: CSSValue(PrimitiveClass)
{
- init(PassRefPtr<T>(val));
+ init(PassRefPtrWillBeRawPtr<T>(val));
}
- template<typename T> CSSPrimitiveValue(PassRefPtr<T> val)
+ template<typename T> CSSPrimitiveValue(PassRefPtrWillBeRawPtr<T> val)
: CSSValue(PrimitiveClass)
{
init(val);
@@ -358,13 +397,14 @@ private:
template<typename T> operator T*(); // compile-time guard
void init(const Length&);
- void init(PassRefPtr<Counter>);
- void init(PassRefPtr<Rect>);
- void init(PassRefPtr<Pair>);
- void init(PassRefPtr<Quad>);
- void init(PassRefPtr<CSSBasicShape>);
- void init(PassRefPtr<CSSCalcValue>);
- bool getDoubleValueInternal(UnitTypes targetUnitType, double* result) const;
+ void init(const LengthSize&, const RenderStyle&);
+ void init(PassRefPtrWillBeRawPtr<Counter>);
+ void init(PassRefPtrWillBeRawPtr<Rect>);
+ void init(PassRefPtrWillBeRawPtr<Pair>);
+ void init(PassRefPtrWillBeRawPtr<Quad>);
+ void init(PassRefPtrWillBeRawPtr<CSSBasicShape>);
+ void init(PassRefPtrWillBeRawPtr<CSSCalcValue>);
+ bool getDoubleValueInternal(UnitType targetUnitType, double* result) const;
double computeLengthDouble(const CSSToLengthConversionData&);
@@ -374,16 +414,19 @@ private:
int parserOperator;
double num;
StringImpl* string;
- Counter* counter;
- Rect* rect;
- Quad* quad;
unsigned rgbcolor;
- Pair* pair;
+ // FIXME: oilpan: Should be members, but no support for members in unions. Just trace the raw ptr for now.
CSSBasicShape* shape;
CSSCalcValue* calc;
+ Counter* counter;
+ Pair* pair;
+ Rect* rect;
+ Quad* quad;
} m_value;
};
+typedef CSSPrimitiveValue::CSSLengthArray CSSLengthArray;
+
DEFINE_CSS_VALUE_TYPE_CASTS(CSSPrimitiveValue, isPrimitiveValue());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
index 3f386133793..c2bf9d8e714 100755..100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -30,7 +30,7 @@
#ifndef CSSPrimitiveValueMappings_h
#define CSSPrimitiveValueMappings_h
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSReflectionDirection.h"
@@ -45,6 +45,7 @@
#include "platform/fonts/TextRenderingMode.h"
#include "platform/graphics/GraphicsTypes.h"
#include "platform/graphics/Path.h"
+#include "platform/scroll/ScrollableArea.h"
#include "platform/text/TextDirection.h"
#include "platform/text/UnicodeBidi.h"
#include "platform/text/WritingMode.h"
@@ -61,11 +62,8 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(short i)
template<> inline CSSPrimitiveValue::operator short() const
{
- if (m_primitiveUnitType == CSS_NUMBER)
- return clampTo<short>(m_value.num);
-
- ASSERT_NOT_REACHED();
- return 0;
+ ASSERT(isNumber());
+ return clampTo<short>(getDoubleValue());
}
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(unsigned short i)
@@ -77,29 +75,20 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(unsigned short i)
template<> inline CSSPrimitiveValue::operator unsigned short() const
{
- if (m_primitiveUnitType == CSS_NUMBER)
- return clampTo<unsigned short>(m_value.num);
-
- ASSERT_NOT_REACHED();
- return 0;
+ ASSERT(isNumber());
+ return clampTo<unsigned short>(getDoubleValue());
}
template<> inline CSSPrimitiveValue::operator int() const
{
- if (m_primitiveUnitType == CSS_NUMBER)
- return clampTo<int>(m_value.num);
-
- ASSERT_NOT_REACHED();
- return 0;
+ ASSERT(isNumber());
+ return clampTo<int>(getDoubleValue());
}
template<> inline CSSPrimitiveValue::operator unsigned() const
{
- if (m_primitiveUnitType == CSS_NUMBER)
- return clampTo<unsigned>(m_value.num);
-
- ASSERT_NOT_REACHED();
- return 0;
+ ASSERT(isNumber());
+ return clampTo<unsigned>(getDoubleValue());
}
@@ -112,11 +101,8 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(float i)
template<> inline CSSPrimitiveValue::operator float() const
{
- if (m_primitiveUnitType == CSS_NUMBER)
- return clampTo<float>(m_value.num);
-
- ASSERT_NOT_REACHED();
- return 0.0f;
+ ASSERT(isNumber());
+ return clampTo<float>(getDoubleValue());
}
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineClampValue i)
@@ -460,18 +446,6 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ControlPart e)
case MediaMuteButtonPart:
m_value.valueID = CSSValueMediaMuteButton;
break;
- case MediaSeekBackButtonPart:
- m_value.valueID = CSSValueMediaSeekBackButton;
- break;
- case MediaSeekForwardButtonPart:
- m_value.valueID = CSSValueMediaSeekForwardButton;
- break;
- case MediaRewindButtonPart:
- m_value.valueID = CSSValueMediaRewindButton;
- break;
- case MediaReturnToRealtimeButtonPart:
- m_value.valueID = CSSValueMediaReturnToRealtimeButton;
- break;
case MediaToggleClosedCaptionsButtonPart:
m_value.valueID = CSSValueMediaToggleClosedCaptionsButton;
break;
@@ -487,9 +461,6 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ControlPart e)
case MediaVolumeSliderPart:
m_value.valueID = CSSValueMediaVolumeSlider;
break;
- case MediaVolumeSliderMuteButtonPart:
- m_value.valueID = CSSValueMediaVolumeSliderMuteButton;
- break;
case MediaVolumeSliderThumbPart:
m_value.valueID = CSSValueMediaVolumeSliderthumb;
break;
@@ -580,11 +551,6 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ControlPart e)
case CapsLockIndicatorPart:
m_value.valueID = CSSValueCapsLockIndicator;
break;
- case InputSpeechButtonPart:
-#if ENABLE(INPUT_SPEECH)
- m_value.valueID = CSSValueWebkitInputSpeechButton;
-#endif
- break;
}
}
@@ -1150,11 +1116,11 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ECursor e)
case CURSOR_NOT_ALLOWED:
m_value.valueID = CSSValueNotAllowed;
break;
- case CURSOR_WEBKIT_ZOOM_IN:
- m_value.valueID = CSSValueWebkitZoomIn;
+ case CURSOR_ZOOM_IN:
+ m_value.valueID = CSSValueZoomIn;
break;
- case CURSOR_WEBKIT_ZOOM_OUT:
- m_value.valueID = CSSValueWebkitZoomOut;
+ case CURSOR_ZOOM_OUT:
+ m_value.valueID = CSSValueZoomOut;
break;
case CURSOR_E_RESIZE:
m_value.valueID = CSSValueEResize;
@@ -1222,11 +1188,18 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ECursor e)
template<> inline CSSPrimitiveValue::operator ECursor() const
{
ASSERT(isValueID());
- if (m_value.valueID == CSSValueCopy)
+ switch (m_value.valueID) {
+ case CSSValueCopy:
return CURSOR_COPY;
- if (m_value.valueID == CSSValueNone)
+ case CSSValueWebkitZoomIn:
+ return CURSOR_ZOOM_IN;
+ case CSSValueWebkitZoomOut:
+ return CURSOR_ZOOM_OUT;
+ case CSSValueNone:
return CURSOR_NONE;
- return static_cast<ECursor>(m_value.valueID - CSSValueAuto);
+ default:
+ return static_cast<ECursor>(m_value.valueID - CSSValueAuto);
+ }
}
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EDisplay e)
@@ -1346,56 +1319,6 @@ template<> inline CSSPrimitiveValue::operator EEmptyCell() const
return SHOW;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EAlignItems e)
- : CSSValue(PrimitiveClass)
-{
- m_primitiveUnitType = CSS_VALUE_ID;
- switch (e) {
- case AlignAuto:
- m_value.valueID = CSSValueAuto;
- break;
- case AlignFlexStart:
- m_value.valueID = CSSValueFlexStart;
- break;
- case AlignFlexEnd:
- m_value.valueID = CSSValueFlexEnd;
- break;
- case AlignCenter:
- m_value.valueID = CSSValueCenter;
- break;
- case AlignStretch:
- m_value.valueID = CSSValueStretch;
- break;
- case AlignBaseline:
- m_value.valueID = CSSValueBaseline;
- break;
- }
-}
-
-template<> inline CSSPrimitiveValue::operator EAlignItems() const
-{
- ASSERT(isValueID());
- switch (m_value.valueID) {
- case CSSValueAuto:
- return AlignAuto;
- case CSSValueFlexStart:
- return AlignFlexStart;
- case CSSValueFlexEnd:
- return AlignFlexEnd;
- case CSSValueCenter:
- return AlignCenter;
- case CSSValueStretch:
- return AlignStretch;
- case CSSValueBaseline:
- return AlignBaseline;
- default:
- break;
- }
-
- ASSERT_NOT_REACHED();
- return AlignFlexStart;
-}
-
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EJustifyContent e)
: CSSValue(PrimitiveClass)
{
@@ -2014,36 +1937,6 @@ template<> inline CSSPrimitiveValue::operator EMarqueeBehavior() const
return MNONE;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(RegionFragment e)
- : CSSValue(PrimitiveClass)
-{
- m_primitiveUnitType = CSS_VALUE_ID;
- switch (e) {
- case AutoRegionFragment:
- m_value.valueID = CSSValueAuto;
- break;
- case BreakRegionFragment:
- m_value.valueID = CSSValueBreak;
- break;
- }
-}
-
-template<> inline CSSPrimitiveValue::operator RegionFragment() const
-{
- ASSERT(isValueID());
- switch (m_value.valueID) {
- case CSSValueAuto:
- return AutoRegionFragment;
- case CSSValueBreak:
- return BreakRegionFragment;
- default:
- break;
- }
-
- ASSERT_NOT_REACHED();
- return AutoRegionFragment;
-}
-
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EMarqueeDirection e)
: CSSValue(PrimitiveClass)
{
@@ -3591,15 +3484,15 @@ template<> inline CSSPrimitiveValue::operator FontWeight() const
return FontWeightNormal;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontItalic italic)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontStyle italic)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = CSS_VALUE_ID;
switch (italic) {
- case FontItalicOff:
+ case FontStyleNormal:
m_value.valueID = CSSValueNormal;
return;
- case FontItalicOn:
+ case FontStyleItalic:
m_value.valueID = CSSValueItalic;
return;
}
@@ -3608,32 +3501,32 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontItalic italic)
m_value.valueID = CSSValueNormal;
}
-template<> inline CSSPrimitiveValue::operator FontItalic() const
+template<> inline CSSPrimitiveValue::operator FontStyle() const
{
ASSERT(isValueID());
switch (m_value.valueID) {
case CSSValueOblique:
// FIXME: oblique is the same as italic for the moment...
case CSSValueItalic:
- return FontItalicOn;
+ return FontStyleItalic;
case CSSValueNormal:
- return FontItalicOff;
+ return FontStyleNormal;
default:
break;
}
ASSERT_NOT_REACHED();
- return FontItalicOff;
+ return FontStyleNormal;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmallCaps smallCaps)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontVariant smallCaps)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = CSS_VALUE_ID;
switch (smallCaps) {
- case FontSmallCapsOff:
+ case FontVariantNormal:
m_value.valueID = CSSValueNormal;
return;
- case FontSmallCapsOn:
+ case FontVariantSmallCaps:
m_value.valueID = CSSValueSmallCaps;
return;
}
@@ -3642,19 +3535,19 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmallCaps smallCaps)
m_value.valueID = CSSValueNormal;
}
-template<> inline CSSPrimitiveValue::operator FontSmallCaps() const
+template<> inline CSSPrimitiveValue::operator FontVariant() const
{
ASSERT(isValueID());
switch (m_value.valueID) {
case CSSValueSmallCaps:
- return FontSmallCapsOn;
+ return FontVariantSmallCaps;
case CSSValueNormal:
- return FontSmallCapsOff;
+ return FontVariantNormal;
default:
break;
}
ASSERT_NOT_REACHED();
- return FontSmallCapsOff;
+ return FontVariantNormal;
}
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextRenderingMode e)
@@ -3697,71 +3590,6 @@ template<> inline CSSPrimitiveValue::operator TextRenderingMode() const
return AutoTextRendering;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineSnap gridSnap)
- : CSSValue(PrimitiveClass)
-{
- m_primitiveUnitType = CSS_VALUE_ID;
- switch (gridSnap) {
- case LineSnapNone:
- m_value.valueID = CSSValueNone;
- break;
- case LineSnapBaseline:
- m_value.valueID = CSSValueBaseline;
- break;
- case LineSnapContain:
- m_value.valueID = CSSValueContain;
- break;
- }
-}
-
-template<> inline CSSPrimitiveValue::operator LineSnap() const
-{
- ASSERT(isValueID());
- switch (m_value.valueID) {
- case CSSValueNone:
- return LineSnapNone;
- case CSSValueBaseline:
- return LineSnapBaseline;
- case CSSValueContain:
- return LineSnapContain;
- default:
- break;
- }
-
- ASSERT_NOT_REACHED();
- return LineSnapNone;
-}
-
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LineAlign lineAlign)
- : CSSValue(PrimitiveClass)
-{
- m_primitiveUnitType = CSS_VALUE_ID;
- switch (lineAlign) {
- case LineAlignNone:
- m_value.valueID = CSSValueNone;
- break;
- case LineAlignEdges:
- m_value.valueID = CSSValueEdges;
- break;
- }
-}
-
-template<> inline CSSPrimitiveValue::operator LineAlign() const
-{
- ASSERT(isValueID());
- switch (m_value.valueID) {
- case CSSValueNone:
- return LineAlignNone;
- case CSSValueEdges:
- return LineAlignEdges;
- default:
- break;
- }
-
- ASSERT_NOT_REACHED();
- return LineAlignNone;
-}
-
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ESpeak e)
: CSSValue(PrimitiveClass)
{
@@ -4253,71 +4081,6 @@ template<> inline CSSPrimitiveValue::operator ETransformStyle3D() const
return TransformStyle3DFlat;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ColumnAxis e)
- : CSSValue(PrimitiveClass)
-{
- m_primitiveUnitType = CSS_VALUE_ID;
- switch (e) {
- case HorizontalColumnAxis:
- m_value.valueID = CSSValueHorizontal;
- break;
- case VerticalColumnAxis:
- m_value.valueID = CSSValueVertical;
- break;
- case AutoColumnAxis:
- m_value.valueID = CSSValueAuto;
- break;
- }
-}
-
-template<> inline CSSPrimitiveValue::operator ColumnAxis() const
-{
- ASSERT(isValueID());
- switch (m_value.valueID) {
- case CSSValueHorizontal:
- return HorizontalColumnAxis;
- case CSSValueVertical:
- return VerticalColumnAxis;
- case CSSValueAuto:
- return AutoColumnAxis;
- default:
- break;
- }
-
- ASSERT_NOT_REACHED();
- return AutoColumnAxis;
-}
-
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ColumnProgression e)
- : CSSValue(PrimitiveClass)
-{
- m_primitiveUnitType = CSS_VALUE_ID;
- switch (e) {
- case NormalColumnProgression:
- m_value.valueID = CSSValueNormal;
- break;
- case ReverseColumnProgression:
- m_value.valueID = CSSValueReverse;
- break;
- }
-}
-
-template<> inline CSSPrimitiveValue::operator ColumnProgression() const
-{
- ASSERT(isValueID());
- switch (m_value.valueID) {
- case CSSValueNormal:
- return NormalColumnProgression;
- case CSSValueReverse:
- return ReverseColumnProgression;
- default:
- break;
- }
-
- ASSERT_NOT_REACHED();
- return NormalColumnProgression;
-}
-
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(WrapFlow wrapFlow)
: CSSValue(PrimitiveClass)
{
@@ -4443,7 +4206,6 @@ enum LengthConversion {
template<int supported> Length CSSPrimitiveValue::convertToLength(const CSSToLengthConversionData& conversionData)
{
- ASSERT(!hasVariableReference());
if ((supported & FixedConversion) && isLength())
return computeLength<Length>(conversionData);
if ((supported & PercentConversion) && isPercentage())
@@ -4452,9 +4214,8 @@ template<int supported> Length CSSPrimitiveValue::convertToLength(const CSSToLen
return Length(Auto);
if ((supported & FixedConversion) && (supported & PercentConversion) && isCalculated())
return Length(cssCalcValue()->toCalcValue(conversionData));
- if ((supported & FixedConversion) && isViewportPercentageLength())
- return viewportPercentageLength();
- return Length(Undefined);
+ ASSERT_NOT_REACHED();
+ return Length(0, Fixed);
}
template<> inline CSSPrimitiveValue::CSSPrimitiveValue(EBufferedRendering e)
@@ -4878,6 +4639,8 @@ template<> inline CSSPrimitiveValue::operator TouchAction() const
return TouchActionPanX;
case CSSValuePanY:
return TouchActionPanY;
+ case CSSValueManipulation:
+ return TouchActionPanX | TouchActionPanY | TouchActionPinchZoom;
default:
break;
}
@@ -4945,11 +4708,11 @@ template<> inline CSSPrimitiveValue::operator TouchActionDelay() const
return TouchActionDelayNone;
}
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LayoutBox layoutBox)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(CSSBoxType cssBox)
: CSSValue(PrimitiveClass)
{
m_primitiveUnitType = CSS_VALUE_ID;
- switch (layoutBox) {
+ switch (cssBox) {
case MarginBox:
m_value.valueID = CSSValueMarginBox;
break;
@@ -4962,10 +4725,13 @@ template<> inline CSSPrimitiveValue::CSSPrimitiveValue(LayoutBox layoutBox)
case ContentBox:
m_value.valueID = CSSValueContentBox;
break;
+ case BoxMissing:
+ // The missing box should convert to a null primitive value.
+ ASSERT_NOT_REACHED();
}
}
-template<> inline CSSPrimitiveValue::operator LayoutBox() const
+template<> inline CSSPrimitiveValue::operator CSSBoxType() const
{
switch (getValueID()) {
case CSSValueMarginBox:
@@ -4983,6 +4749,147 @@ template<> inline CSSPrimitiveValue::operator LayoutBox() const
return ContentBox;
}
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ItemPosition itemPosition)
+ : CSSValue(PrimitiveClass)
+{
+ m_primitiveUnitType = CSS_VALUE_ID;
+ switch (itemPosition) {
+ case ItemPositionAuto:
+ m_value.valueID = CSSValueAuto;
+ break;
+ case ItemPositionStretch:
+ m_value.valueID = CSSValueStretch;
+ break;
+ case ItemPositionBaseline:
+ m_value.valueID = CSSValueBaseline;
+ break;
+ case ItemPositionCenter:
+ m_value.valueID = CSSValueCenter;
+ break;
+ case ItemPositionStart:
+ m_value.valueID = CSSValueStart;
+ break;
+ case ItemPositionEnd:
+ m_value.valueID = CSSValueEnd;
+ break;
+ case ItemPositionSelfStart:
+ m_value.valueID = CSSValueSelfStart;
+ break;
+ case ItemPositionSelfEnd:
+ m_value.valueID = CSSValueSelfEnd;
+ break;
+ case ItemPositionFlexStart:
+ m_value.valueID = CSSValueFlexStart;
+ break;
+ case ItemPositionFlexEnd:
+ m_value.valueID = CSSValueFlexEnd;
+ break;
+ case ItemPositionLeft:
+ m_value.valueID = CSSValueLeft;
+ break;
+ case ItemPositionRight:
+ m_value.valueID = CSSValueRight;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ItemPosition() const
+{
+ switch (m_value.valueID) {
+ case CSSValueAuto:
+ return ItemPositionAuto;
+ case CSSValueStretch:
+ return ItemPositionStretch;
+ case CSSValueBaseline:
+ return ItemPositionBaseline;
+ case CSSValueCenter:
+ return ItemPositionCenter;
+ case CSSValueStart:
+ return ItemPositionStart;
+ case CSSValueEnd:
+ return ItemPositionEnd;
+ case CSSValueSelfStart:
+ return ItemPositionSelfStart;
+ case CSSValueSelfEnd:
+ return ItemPositionSelfEnd;
+ case CSSValueFlexStart:
+ return ItemPositionFlexStart;
+ case CSSValueFlexEnd:
+ return ItemPositionFlexEnd;
+ case CSSValueLeft:
+ return ItemPositionLeft;
+ case CSSValueRight:
+ return ItemPositionRight;
+ default:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return ItemPositionAuto;
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(OverflowAlignment overflowAlignment)
+ : CSSValue(PrimitiveClass)
+{
+ m_primitiveUnitType = CSS_VALUE_ID;
+ switch (overflowAlignment) {
+ case OverflowAlignmentDefault:
+ m_value.valueID = CSSValueDefault;
+ break;
+ case OverflowAlignmentTrue:
+ m_value.valueID = CSSValueTrue;
+ break;
+ case OverflowAlignmentSafe:
+ m_value.valueID = CSSValueSafe;
+ break;
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator OverflowAlignment() const
+{
+ switch (m_value.valueID) {
+ case CSSValueTrue:
+ return OverflowAlignmentTrue;
+ case CSSValueSafe:
+ return OverflowAlignmentSafe;
+ default:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return OverflowAlignmentTrue;
+}
+
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(ScrollBehavior behavior)
+ : CSSValue(PrimitiveClass)
+{
+ m_primitiveUnitType = CSS_VALUE_ID;
+ switch (behavior) {
+ case ScrollBehaviorInstant:
+ m_value.valueID = CSSValueInstant;
+ break;
+ case ScrollBehaviorSmooth:
+ m_value.valueID = CSSValueSmooth;
+ break;
+ case ScrollBehaviorAuto:
+ // Behavior 'auto' is only allowed in ScrollOptions arguments passed to
+ // CSSOM scroll APIs.
+ ASSERT_NOT_REACHED();
+ }
+}
+
+template<> inline CSSPrimitiveValue::operator ScrollBehavior() const
+{
+ switch (getValueID()) {
+ case CSSValueInstant:
+ return ScrollBehaviorInstant;
+ case CSSValueSmooth:
+ return ScrollBehaviorSmooth;
+ default:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return ScrollBehaviorInstant;
+}
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSProperties.in b/chromium/third_party/WebKit/Source/core/css/CSSProperties.in
index 26318517545..ef861db7d13 100755..100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSProperties.in
+++ b/chromium/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -1,10 +1,12 @@
// FIXME: When we have all the properties using the new StyleBuilder, we
// should use this for make_css_property_names.py
+// Note that type_name is currently only used for non-custom value application
+// and when explicitly referred to in generated applicators.
// Note: Mandatory blank line to skip parameter parsing phase
align-content
-align-items
-align-self type_name=EAlignItems
+align-items custom_value
+align-self custom_value
background-attachment custom_all
background-blend-mode custom_all
background-clip custom_all
@@ -45,6 +47,7 @@ caption-side
clear
clip custom_all
color custom_all
+content custom_all
counter-increment custom_all
counter-reset custom_all
cursor custom_all
@@ -57,17 +60,30 @@ flex-grow type_name=float
flex-shrink type_name=float
flex-wrap
float type_name=EFloat, name_for_methods=Floating
+font custom_all
font-family custom_all
-font-kerning custom_all
+font-kerning font, type_name=FontDescription::Kerning, name_for_methods=Kerning
font-size custom_all
-font-style custom_all
-font-variant custom_all
+font-style font, type_name=FontStyle, name_for_methods=Style
+font-variant font, type_name=FontVariant, name_for_methods=Variant
+font-variant-ligatures custom_all
font-weight custom_all
grid-auto-flow type_name=GridAutoFlow
+grid-auto-columns converter=convertGridTrackSize
+grid-auto-rows converter=convertGridTrackSize
+grid-column-start converter=convertGridPosition
+grid-column-end converter=convertGridPosition
+grid-row-start converter=convertGridPosition
+grid-row-end converter=convertGridPosition
+grid-template-columns custom_all
+grid-template-rows custom_all
+grid-template-areas custom_all
height type_name=Length, initial=initialSize, converter=convertLengthSizing
justify-content
image-rendering
+internal-callback custom_all
isolation
+justify-self custom_value
left type_name=Length, initial=initialOffset, converter=convertLengthOrAuto
letter-spacing type_name=float, initial=initialLetterWordSpacing, converter=convertSpacing
line-height getter=specifiedLineHeight, custom_value
@@ -103,15 +119,16 @@ padding-top type_name=Length, initial=initialPadding, converter=convertLength
page-break-after type_name=EPageBreak, initial=initialPageBreak
page-break-before type_name=EPageBreak, initial=initialPageBreak
page-break-inside type_name=EPageBreak, initial=initialPageBreak
+perspective custom_value
pointer-events
position
+quotes converter=convertQuotes
resize custom_value
right type_name=Length, initial=initialOffset, converter=convertLengthOrAuto
+scroll-behavior type_name=ScrollBehavior
shape-image-threshold type_name=float
-shape-inside type_name=ShapeValue*, custom_value
shape-margin type_name=Length, converter=convertLength
shape-outside type_name=ShapeValue*, custom_value
-shape-padding type_name=Length, converter=convertLength
size custom_all
speak
table-layout
@@ -125,18 +142,19 @@ text-decoration-style type_name=TextDecorationStyle
text-indent custom_all
text-justify type_name=TextJustify
text-overflow type_name=TextOverflow
-text-rendering custom_all
+text-rendering font, type_name=TextRenderingMode
text-shadow converter=convertShadow
text-transform
top type_name=Length, initial=initialOffset, converter=convertLengthOrAuto
touch-action type_name=TouchAction, custom_value
touch-action-delay type_name=TouchActionDelay, initial=initialTouchActionDelay
unicode-bidi
-vertical-align custom_value
+vertical-align custom_inherit, custom_value
visibility
white-space
widows type_name=short, custom_all
width type_name=Length, initial=initialSize, converter=convertLengthSizing
+will-change custom_all
word-break
word-spacing type_name=float, initial=initialLetterWordSpacing, converter=convertSpacing
// UAs must treat 'word-wrap' as an alternate name for the 'overflow-wrap' property. So using the same handlers.
@@ -152,8 +170,10 @@ z-index type_name=int, custom_all
-webkit-animation-name custom_all
-webkit-animation-play-state custom_all
-webkit-animation-timing-function custom_all
+-webkit-app-region custom_all
-webkit-appearance type_name=ControlPart
-webkit-aspect-ratio custom_all
+backface-visibility
-webkit-backface-visibility
-webkit-background-clip use_handlers_for=CSSPropertyBackgroundClip
-webkit-background-composite custom_all
@@ -172,32 +192,29 @@ z-index type_name=int, custom_all
-webkit-box-ordinal-group type_name=unsigned int
-webkit-box-orient
-webkit-box-pack
+-webkit-box-reflect converter=convertBoxReflect
-webkit-box-shadow use_handlers_for=CSSPropertyBoxShadow
-webkit-clip-path custom_value
--webkit-column-axis type_name=ColumnAxis
-webkit-column-break-after type_name=EPageBreak, initial=initialPageBreak
-webkit-column-break-before type_name=EPageBreak, initial=initialPageBreak
-webkit-column-break-inside type_name=EPageBreak, initial=initialPageBreak
-webkit-column-count type_name=unsigned short, custom_all
column-fill type_name=ColumnFill
-webkit-column-gap type_name=float, custom_all
--webkit-column-progression type_name=ColumnProgression
-webkit-column-rule-color custom_all
-webkit-column-rule-style type_name=EBorderStyle, initial=initialBorderStyle
-webkit-column-rule-width type_name=unsigned short, converter=convertLineWidth<unsigned short>
-webkit-column-span type_name=ColumnSpan
-webkit-column-width type_name=float, custom_all
--webkit-flow-from type_name=AtomicString, name_for_methods=RegionThread, converter=convertString<CSSValueNone>
--webkit-flow-into type_name=AtomicString, name_for_methods=FlowThread, converter=convertString<CSSValueNone>
--webkit-font-smoothing custom_all
--webkit-font-variant-ligatures custom_all
+-webkit-filter custom_value
+-webkit-font-feature-settings custom_all
+-webkit-font-smoothing font, type_name=FontSmoothingMode
-webkit-highlight type_name=AtomicString, converter=convertString<CSSValueNone>
-webkit-hyphenate-character type_name=AtomicString, name_for_methods=HyphenationString, converter=convertString<CSSValueAuto>
--webkit-line-align type_name=LineAlign
+-webkit-line-box-contain converter=convertLineBoxContain
-webkit-line-break type_name=LineBreak
-webkit-line-clamp type_name=LineClampValue
--webkit-line-grid type_name=AtomicString, converter=convertString<CSSValueNone>
--webkit-line-snap type_name=LineSnap
+-webkit-locale custom_value
-webkit-margin-after-collapse type_name=EMarginCollapse
-webkit-margin-before-collapse type_name=EMarginCollapse
-webkit-margin-bottom-collapse type_name=EMarginCollapse, name_for_methods=MarginAfterCollapse
@@ -221,27 +238,32 @@ column-fill type_name=ColumnFill
-webkit-mask-repeat-x custom_all
-webkit-mask-repeat-y custom_all
-webkit-mask-size custom_all
+-webkit-perspective custom_all
+perspective-origin custom_all
-webkit-perspective-origin custom_all
-webkit-perspective-origin-x type_name=Length, converter=convertLength
-webkit-perspective-origin-y type_name=Length, converter=convertLength
-webkit-print-color-adjust type_name=PrintColorAdjust
--webkit-region-break-after type_name=EPageBreak, initial=initialPageBreak
--webkit-region-break-before type_name=EPageBreak, initial=initialPageBreak
--webkit-region-break-inside type_name=EPageBreak, initial=initialPageBreak
--webkit-region-fragment type_name=RegionFragment
-webkit-rtl-ordering type_name=Order, getter=rtlOrdering, setter=setRTLOrdering, initial=initialRTLOrdering
-webkit-ruby-position type_name=RubyPosition
+-webkit-tap-highlight-color custom_value
-webkit-text-combine type_name=TextCombine
-webkit-text-emphasis-color custom_all
-webkit-text-emphasis-position type_name=TextEmphasisPosition
-webkit-text-emphasis-style custom_all
-webkit-text-fill-color custom_all
+-webkit-text-orientation custom_value
-webkit-text-security
-webkit-text-stroke-color custom_all
+-webkit-text-stroke-width converter=convertTextStrokeWidth
text-underline-position custom_value
+transform custom_value
+-webkit-transform use_handlers_for=CSSPropertyTransform
+transform-origin custom_all
-webkit-transform-origin-x type_name=Length, converter=convertLength
-webkit-transform-origin-y type_name=Length, converter=convertLength
-webkit-transform-origin-z type_name=float, converter=convertComputedLength<float>
+transform-style name_for_methods=TransformStyle3D
-webkit-transform-style name_for_methods=TransformStyle3D
-webkit-transition-delay custom_all
-webkit-transition-duration custom_all
@@ -252,8 +274,10 @@ text-underline-position custom_value
-webkit-user-select
-webkit-wrap-flow type_name=WrapFlow
-webkit-wrap-through type_name=WrapThrough
+-webkit-writing-mode custom_value
alignment-baseline svg
+baseline-shift svg, custom_value
buffered-rendering svg
clip-path svg, type_name=String, name_for_methods=ClipperResource, converter=convertFragmentIdentifier
clip-rule svg, type_name=WindRule
@@ -261,18 +285,26 @@ color-interpolation svg
color-interpolation-filters svg, type_name=EColorInterpolation
color-rendering svg
dominant-baseline svg
+fill svg, setter=setFillPaint, custom_all
fill-opacity svg, type_name=float, converter=convertNumberOrPercentage
fill-rule svg, type_name=WindRule
filter svg, type_name=String, name_for_methods=FilterResource, converter=convertFragmentIdentifier
+flood-color svg, converter=convertSVGColor
flood-opacity svg, type_name=float, converter=convertNumberOrPercentage
-kerning svg, type_name=SVGLength, converter=convertSVGLength
+glyph-orientation-horizontal svg, converter=convertGlyphOrientation
+glyph-orientation-vertical svg, custom_value
+lighting-color svg, converter=convertSVGColor
marker-start svg, type_name=String, name_for_methods=MarkerStartResource, converter=convertFragmentIdentifier
marker-mid svg, type_name=String, name_for_methods=MarkerMidResource, converter=convertFragmentIdentifier
marker-end svg, type_name=String, name_for_methods=MarkerEndResource, converter=convertFragmentIdentifier
mask svg, type_name=String, name_for_methods=MaskerResource, converter=convertFragmentIdentifier
mask-type svg
+paint-order svg, converter=convertPaintOrder
shape-rendering svg
+stop-color svg, converter=convertSVGColor
stop-opacity svg, type_name=float, converter=convertNumberOrPercentage
+stroke svg, setter=setStrokePaint, custom_all
+stroke-dasharray svg, name_for_methods=StrokeDashArray, converter=convertStrokeDasharray
stroke-dashoffset svg, type_name=SVGLength, name_for_methods=StrokeDashOffset, converter=convertSVGLength
stroke-linecap svg, type_name=LineCap, name_for_methods=CapStyle
stroke-linejoin svg, type_name=LineJoin, name_for_methods=JoinStyle
@@ -282,3 +314,70 @@ stroke-width svg, type_name=SVGLength, converter=convertSVGLength
text-anchor svg
vector-effect svg
writing-mode svg, type_name=SVGWritingMode
+
+-webkit-border-end-color direction_aware
+-webkit-border-end-style direction_aware
+-webkit-border-end-width direction_aware
+-webkit-border-start-color direction_aware
+-webkit-border-start-style direction_aware
+-webkit-border-start-width direction_aware
+-webkit-border-before-color direction_aware
+-webkit-border-before-style direction_aware
+-webkit-border-before-width direction_aware
+-webkit-border-after-color direction_aware
+-webkit-border-after-style direction_aware
+-webkit-border-after-width direction_aware
+-webkit-margin-end direction_aware
+-webkit-margin-start direction_aware
+-webkit-margin-before direction_aware
+-webkit-margin-after direction_aware
+-webkit-padding-end direction_aware
+-webkit-padding-start direction_aware
+-webkit-padding-before direction_aware
+-webkit-padding-after direction_aware
+-webkit-logical-width direction_aware
+-webkit-logical-height direction_aware
+-webkit-min-logical-width direction_aware
+-webkit-min-logical-height direction_aware
+-webkit-max-logical-width direction_aware
+-webkit-max-logical-height direction_aware
+
+// FIXME: We should look over these and see if some should actually be
+// marked as unreachable.
+animation-delay skip
+animation-direction skip
+animation-duration skip
+animation-fill-mode skip
+animation-iteration-count skip
+animation-name skip
+animation-play-state skip
+animation-timing-function skip
+transition-delay skip
+transition-duration skip
+transition-property skip
+transition-timing-function skip
+font-stretch skip
+page skip
+src skip
+text-line-through-color skip
+text-line-through-mode skip
+text-line-through-style skip
+text-line-through-width skip
+text-overline-color skip
+text-overline-mode skip
+text-overline-style skip
+text-overline-width skip
+text-underline-color skip
+text-underline-mode skip
+text-underline-style skip
+text-underline-width skip
+unicode-range skip
+-webkit-font-size-delta skip
+-webkit-text-decorations-in-effect skip
+max-zoom skip
+min-zoom skip
+user-zoom skip
+orientation skip
+enable-background skip
+invalid skip
+all skip
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSProperty.cpp b/chromium/third_party/WebKit/Source/core/css/CSSProperty.cpp
index 59e3d9e68af..f36f4897f92 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSProperty.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSProperty.cpp
@@ -21,7 +21,7 @@
#include "config.h"
#include "core/css/CSSProperty.h"
-#include "StylePropertyShorthand.h"
+#include "core/StylePropertyShorthand.h"
#include "core/css/CSSValueList.h"
#include "core/rendering/style/RenderStyleConstants.h"
@@ -47,7 +47,7 @@ CSSPropertyID StylePropertyMetadata::shorthandID() const
void CSSProperty::wrapValueInCommaSeparatedList()
{
- RefPtr<CSSValue> value = m_value.release();
+ RefPtrWillBeRawPtr<CSSValue> value = m_value.release();
m_value = CSSValueList::createCommaSeparated();
toCSSValueList(m_value.get())->append(value.release());
}
@@ -282,7 +282,6 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyGlyphOrientationHorizontal:
case CSSPropertyGlyphOrientationVertical:
case CSSPropertyImageRendering:
- case CSSPropertyKerning:
case CSSPropertyLetterSpacing:
case CSSPropertyLineHeight:
case CSSPropertyListStyle:
@@ -317,7 +316,6 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyTextShadow:
case CSSPropertyTextTransform:
case CSSPropertyTouchActionDelay:
- case CSSPropertyVariable:
case CSSPropertyVisibility:
case CSSPropertyWebkitAspectRatio:
case CSSPropertyWebkitBorderHorizontalSpacing:
@@ -326,15 +324,12 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyWebkitFontFeatureSettings:
case CSSPropertyFontKerning:
case CSSPropertyWebkitFontSmoothing:
- case CSSPropertyWebkitFontVariantLigatures:
+ case CSSPropertyFontVariantLigatures:
case CSSPropertyWebkitLocale:
case CSSPropertyWebkitHighlight:
case CSSPropertyWebkitHyphenateCharacter:
- case CSSPropertyWebkitLineAlign:
case CSSPropertyWebkitLineBoxContain:
case CSSPropertyWebkitLineBreak:
- case CSSPropertyWebkitLineGrid:
- case CSSPropertyWebkitLineSnap:
case CSSPropertyWebkitPrintColorAdjust:
case CSSPropertyWebkitRtlOrdering:
case CSSPropertyWebkitRubyPosition:
@@ -425,7 +420,6 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyClear:
case CSSPropertyClip:
case CSSPropertyClipPath:
- case CSSPropertyColorProfile:
case CSSPropertyContent:
case CSSPropertyCounterIncrement:
case CSSPropertyCounterReset:
@@ -439,6 +433,7 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyFontStretch:
case CSSPropertyHeight:
case CSSPropertyIsolation:
+ case CSSPropertyJustifySelf:
case CSSPropertyLeft:
case CSSPropertyLightingColor:
case CSSPropertyMargin:
@@ -478,6 +473,7 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyPaintOrder:
case CSSPropertyPosition:
case CSSPropertyRight:
+ case CSSPropertyScrollBehavior:
case CSSPropertySize:
case CSSPropertySrc:
case CSSPropertyStopColor:
@@ -524,6 +520,7 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyWebkitAnimationPlayState:
case CSSPropertyWebkitAnimationTimingFunction:
case CSSPropertyWebkitAppearance:
+ case CSSPropertyBackfaceVisibility:
case CSSPropertyWebkitBackfaceVisibility:
case CSSPropertyWebkitBackgroundClip:
case CSSPropertyWebkitBackgroundComposite:
@@ -560,14 +557,12 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyWebkitBoxShadow:
case CSSPropertyInternalCallback:
case CSSPropertyWebkitClipPath:
- case CSSPropertyWebkitColumnAxis:
case CSSPropertyWebkitColumnBreakAfter:
case CSSPropertyWebkitColumnBreakBefore:
case CSSPropertyWebkitColumnBreakInside:
case CSSPropertyWebkitColumnCount:
case CSSPropertyColumnFill:
case CSSPropertyWebkitColumnGap:
- case CSSPropertyWebkitColumnProgression:
case CSSPropertyWebkitColumnRule:
case CSSPropertyWebkitColumnRuleColor:
case CSSPropertyWebkitColumnRuleStyle:
@@ -591,12 +586,14 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyGridColumn:
case CSSPropertyGridColumnEnd:
case CSSPropertyGridColumnStart:
- case CSSPropertyGridDefinitionColumns:
- case CSSPropertyGridDefinitionRows:
+ case CSSPropertyGrid:
+ case CSSPropertyGridTemplate:
+ case CSSPropertyGridTemplateColumns:
+ case CSSPropertyGridTemplateRows:
case CSSPropertyGridRow:
case CSSPropertyGridRowEnd:
case CSSPropertyGridRowStart:
- case CSSPropertyGridTemplate:
+ case CSSPropertyGridTemplateAreas:
case CSSPropertyJustifyContent:
case CSSPropertyWebkitLineClamp:
case CSSPropertyWebkitLogicalHeight:
@@ -642,15 +639,20 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyWebkitPaddingBefore:
case CSSPropertyWebkitPaddingEnd:
case CSSPropertyWebkitPaddingStart:
+ case CSSPropertyPerspective:
case CSSPropertyWebkitPerspective:
+ case CSSPropertyPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOrigin:
case CSSPropertyWebkitPerspectiveOriginX:
case CSSPropertyWebkitPerspectiveOriginY:
+ case CSSPropertyTransform:
case CSSPropertyWebkitTransform:
+ case CSSPropertyTransformOrigin:
case CSSPropertyWebkitTransformOrigin:
case CSSPropertyWebkitTransformOriginX:
case CSSPropertyWebkitTransformOriginY:
case CSSPropertyWebkitTransformOriginZ:
+ case CSSPropertyTransformStyle:
case CSSPropertyWebkitTransformStyle:
case CSSPropertyWebkitTransition:
case CSSPropertyWebkitTransitionDelay:
@@ -658,27 +660,21 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
case CSSPropertyWebkitTransitionProperty:
case CSSPropertyWebkitTransitionTimingFunction:
case CSSPropertyWebkitUserDrag:
- case CSSPropertyWebkitFlowInto:
- case CSSPropertyWebkitFlowFrom:
- case CSSPropertyWebkitRegionBreakAfter:
- case CSSPropertyWebkitRegionBreakBefore:
- case CSSPropertyWebkitRegionBreakInside:
- case CSSPropertyWebkitRegionFragment:
case CSSPropertyWebkitWrapFlow:
case CSSPropertyShapeMargin:
case CSSPropertyShapeImageThreshold:
- case CSSPropertyShapePadding:
- case CSSPropertyShapeInside:
case CSSPropertyShapeOutside:
case CSSPropertyWebkitWrapThrough:
case CSSPropertyWebkitAppRegion:
case CSSPropertyWidth:
+ case CSSPropertyWillChange:
case CSSPropertyMaxZoom:
case CSSPropertyMinZoom:
case CSSPropertyOrientation:
case CSSPropertyUserZoom:
case CSSPropertyZIndex:
case CSSPropertyZoom:
+ case CSSPropertyAll:
return false;
case CSSPropertyInvalid:
ASSERT_NOT_REACHED();
@@ -688,4 +684,18 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
return false;
}
+bool CSSProperty::isAffectedByAllProperty(CSSPropertyID propertyID)
+{
+ if (propertyID == CSSPropertyAll)
+ return false;
+
+ // all shorthand spec says:
+ // The all property is a shorthand that resets all CSS properties except
+ // direction and unicode-bidi. It only accepts the CSS-wide keywords.
+ // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand
+ // So CSSPropertyUnicodeBidi and CSSPropertyDirection are not
+ // affected by all property.
+ return propertyID != CSSPropertyUnicodeBidi && propertyID != CSSPropertyDirection;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSProperty.h b/chromium/third_party/WebKit/Source/core/css/CSSProperty.h
index a0fb377ce3f..bb54c659988 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSProperty.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSProperty.h
@@ -21,9 +21,9 @@
#ifndef CSSProperty_h
#define CSSProperty_h
-#include "CSSPropertyNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/CSSPropertyNames.h"
#include "core/css/CSSValue.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/TextDirection.h"
#include "platform/text/WritingMode.h"
#include "wtf/PassRefPtr.h"
@@ -53,12 +53,12 @@ struct StylePropertyMetadata {
};
class CSSProperty {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
- CSSProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue> value, bool important = false, bool isSetFromShorthand = false, int indexInShorthandsVector = 0, bool implicit = false)
+ CSSProperty(CSSPropertyID propertyID, PassRefPtrWillBeRawPtr<CSSValue> value, bool important = false, bool isSetFromShorthand = false, int indexInShorthandsVector = 0, bool implicit = false)
: m_metadata(propertyID, isSetFromShorthand, indexInShorthandsVector, important, implicit, isInheritedProperty(propertyID))
, m_value(value)
{
- ASSERT((propertyID == CSSPropertyVariable) == (m_value && m_value->isVariableValue()));
}
// FIXME: Remove this.
@@ -66,7 +66,6 @@ public:
: m_metadata(metadata)
, m_value(value)
{
- ASSERT((metadata.m_propertyID == CSSPropertyVariable) == (m_value && m_value->isVariableValue()));
}
CSSPropertyID id() const { return static_cast<CSSPropertyID>(m_metadata.m_propertyID); }
@@ -80,12 +79,15 @@ public:
static CSSPropertyID resolveDirectionAwareProperty(CSSPropertyID, TextDirection, WritingMode);
static bool isInheritedProperty(CSSPropertyID);
+ static bool isAffectedByAllProperty(CSSPropertyID);
const StylePropertyMetadata& metadata() const { return m_metadata; }
+ void trace(Visitor* visitor) { visitor->trace(m_value); }
+
private:
StylePropertyMetadata m_metadata;
- RefPtr<CSSValue> m_value;
+ RefPtrWillBeMember<CSSValue> m_value;
};
inline CSSPropertyID prefixingVariantForPropertyId(CSSPropertyID propId)
@@ -189,11 +191,6 @@ inline CSSPropertyID prefixingVariantForPropertyId(CSSPropertyID propId)
} // namespace WebCore
-namespace WTF {
-template <> struct VectorTraits<WebCore::CSSProperty> : VectorTraitsBase<false, WebCore::CSSProperty> {
- static const bool canInitializeWithMemset = true;
- static const bool canMoveWithMemcpy = true;
-};
-}
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::CSSProperty);
#endif // CSSProperty_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSPropertyNames.in b/chromium/third_party/WebKit/Source/core/css/CSSPropertyNames.in
index 880cb61d86b..d5c0ace1c6c 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSPropertyNames.in
+++ b/chromium/third_party/WebKit/Source/core/css/CSSPropertyNames.in
@@ -49,11 +49,11 @@ font-kerning
font-size
font-style
font-variant
+font-variant-ligatures
font-weight
text-rendering
-webkit-font-feature-settings
-webkit-font-smoothing
--webkit-font-variant-ligatures
-webkit-locale
-webkit-text-orientation
-epub-text-orientation alias_for=-webkit-text-orientation
@@ -136,6 +136,7 @@ font-stretch
height
image-rendering
isolation
+justify-self
left
letter-spacing
list-style
@@ -183,6 +184,7 @@ position
quotes
resize
right
+scroll-behavior
size
src
speak
@@ -224,6 +226,7 @@ visibility
white-space
widows
width
+will-change
word-break
-epub-word-break alias_for=word-break
word-spacing
@@ -231,6 +234,7 @@ word-wrap
z-index
-webkit-appearance
-webkit-aspect-ratio
+backface-visibility
-webkit-backface-visibility
-webkit-background-clip
-webkit-background-composite
@@ -274,14 +278,12 @@ z-index
-webkit-box-reflect
-webkit-box-shadow
-internal-callback
--webkit-column-axis
-webkit-column-break-after
-webkit-column-break-before
-webkit-column-break-inside
-webkit-column-count
column-fill
-webkit-column-gap
--webkit-column-progression
-webkit-column-rule
-webkit-column-rule-color
-webkit-column-rule-style
@@ -321,20 +323,19 @@ grid-area
grid-column
grid-column-end
grid-column-start
-grid-definition-columns
-grid-definition-rows
+grid
+grid-template
+grid-template-columns
+grid-template-rows
grid-row
grid-row-end
grid-row-start
-grid-template
+grid-template-areas
-webkit-highlight
-webkit-hyphenate-character
-webkit-line-box-contain
--webkit-line-align
-webkit-line-break
-webkit-line-clamp
--webkit-line-grid
--webkit-line-snap
-webkit-logical-width
-webkit-logical-height
-webkit-margin-after-collapse
@@ -374,7 +375,9 @@ order
-webkit-padding-before
-webkit-padding-end
-webkit-padding-start
+perspective
-webkit-perspective
+perspective-origin
-webkit-perspective-origin
-webkit-perspective-origin-x
-webkit-perspective-origin-y
@@ -396,30 +399,23 @@ order
-webkit-text-stroke
-webkit-text-stroke-color
-webkit-text-stroke-width
+transform
-webkit-transform
+transform-origin
-webkit-transform-origin
-webkit-transform-origin-x
-webkit-transform-origin-y
-webkit-transform-origin-z
+transform-style
-webkit-transform-style
-webkit-user-drag
-webkit-user-modify
-webkit-user-select
--webkit-flow-into
--webkit-flow-from
--webkit-region-fragment
--webkit-region-break-after
--webkit-region-break-before
--webkit-region-break-inside
--webkit-shape-inside alias_for=shape-inside
-webkit-shape-outside alias_for=shape-outside
-webkit-shape-margin alias_for=shape-margin
--webkit-shape-padding alias_for=shape-padding
-webkit-shape-image-threshold alias_for=shape-image-threshold
-shape-inside
shape-outside
shape-margin
-shape-padding
shape-image-threshold
-webkit-wrap-flow
-webkit-wrap-through
@@ -429,6 +425,7 @@ orientation
user-zoom
-webkit-tap-highlight-color
-webkit-app-region
+all
// Internal properties.
-internal-marquee-direction
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.cpp b/chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.cpp
index 6a5ff1b31bf..26bf1b68d75 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.cpp
@@ -30,10 +30,6 @@
#include "config.h"
-#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
-#define CSSPROPERTYSOURCEDATA_HIDE_GLOBALS 1
-#endif
-
#include "core/css/CSSPropertySourceData.h"
#include "wtf/StaticConstructors.h"
@@ -114,17 +110,13 @@ unsigned CSSPropertySourceData::hash() const
return StringHash::hash(name) + 3 * StringHash::hash(value) + 7 * important + 13 * parsedOk + 31;
}
-// Global init routines
-DEFINE_GLOBAL(CSSPropertySourceData, emptyCSSPropertySourceData, "", "e", false, false)
-
-// static
-void CSSPropertySourceData::init()
+void CSSRuleSourceData::trace(Visitor* visitor)
{
- static bool initialized;
- if (!initialized) {
- new ((void *) &emptyCSSPropertySourceData) CSSPropertySourceData("", "e", false, false, false, SourceRange(0, 0));
- initialized = true;
- }
+ visitor->trace(ruleHeaderRange);
+ visitor->trace(ruleBodyRange);
+ visitor->trace(selectorRanges);
+ visitor->trace(styleSourceData);
+ visitor->trace(childRules);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.h b/chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.h
index 7b964d45f26..704235a23a2 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSPropertySourceData.h
@@ -31,6 +31,7 @@
#ifndef CSSPropertySourceData_h
#define CSSPropertySourceData_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -41,17 +42,21 @@ namespace WebCore {
class StyleRuleBase;
struct SourceRange {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
SourceRange();
SourceRange(unsigned start, unsigned end);
unsigned length() const;
+ void trace(Visitor*) { }
+
unsigned start;
unsigned end;
};
struct CSSPropertySourceData {
- static void init();
-
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
CSSPropertySourceData(const String& name, const String& value, bool important, bool disabled, bool parsedOk, const SourceRange& range);
CSSPropertySourceData(const CSSPropertySourceData& other);
CSSPropertySourceData();
@@ -59,6 +64,8 @@ struct CSSPropertySourceData {
String toString() const;
unsigned hash() const;
+ void trace(Visitor* visitor) { visitor->trace(range); }
+
String name;
String value;
bool important;
@@ -67,24 +74,22 @@ struct CSSPropertySourceData {
SourceRange range;
};
-#ifndef CSSPROPERTYSOURCEDATA_HIDE_GLOBALS
-extern const CSSPropertySourceData emptyCSSPropertySourceData;
-#endif
-
-struct CSSStyleSourceData : public RefCounted<CSSStyleSourceData> {
- static PassRefPtr<CSSStyleSourceData> create()
+struct CSSStyleSourceData : public RefCountedWillBeGarbageCollected<CSSStyleSourceData> {
+ static PassRefPtrWillBeRawPtr<CSSStyleSourceData> create()
{
- return adoptRef(new CSSStyleSourceData());
+ return adoptRefWillBeNoop(new CSSStyleSourceData());
}
- Vector<CSSPropertySourceData> propertyData;
+ void trace(Visitor* visitor) { visitor->trace(propertyData); }
+
+ WillBeHeapVector<CSSPropertySourceData> propertyData;
};
struct CSSRuleSourceData;
-typedef Vector<RefPtr<CSSRuleSourceData> > RuleSourceDataList;
-typedef Vector<SourceRange> SelectorRangeList;
+typedef WillBeHeapVector<RefPtrWillBeMember<CSSRuleSourceData> > RuleSourceDataList;
+typedef WillBeHeapVector<SourceRange> SelectorRangeList;
-struct CSSRuleSourceData : public RefCounted<CSSRuleSourceData> {
+struct CSSRuleSourceData : public RefCountedWillBeGarbageCollected<CSSRuleSourceData> {
enum Type {
UNKNOWN_RULE,
STYLE_RULE,
@@ -94,20 +99,19 @@ struct CSSRuleSourceData : public RefCounted<CSSRuleSourceData> {
FONT_FACE_RULE,
PAGE_RULE,
KEYFRAMES_RULE,
- REGION_RULE,
VIEWPORT_RULE,
SUPPORTS_RULE,
FILTER_RULE
};
- static PassRefPtr<CSSRuleSourceData> create(Type type)
+ static PassRefPtrWillBeRawPtr<CSSRuleSourceData> create(Type type)
{
- return adoptRef(new CSSRuleSourceData(type));
+ return adoptRefWillBeNoop(new CSSRuleSourceData(type));
}
- static PassRefPtr<CSSRuleSourceData> createUnknown()
+ static PassRefPtrWillBeRawPtr<CSSRuleSourceData> createUnknown()
{
- return adoptRef(new CSSRuleSourceData(UNKNOWN_RULE));
+ return adoptRefWillBeNoop(new CSSRuleSourceData(UNKNOWN_RULE));
}
CSSRuleSourceData(Type type)
@@ -117,6 +121,8 @@ struct CSSRuleSourceData : public RefCounted<CSSRuleSourceData> {
styleSourceData = CSSStyleSourceData::create();
}
+ void trace(Visitor*);
+
Type type;
// Range of the selector list in the enclosing source.
@@ -129,7 +135,7 @@ struct CSSRuleSourceData : public RefCounted<CSSRuleSourceData> {
SelectorRangeList selectorRanges;
// Only for CSSStyleRules, CSSFontFaceRules, and CSSPageRules.
- RefPtr<CSSStyleSourceData> styleSourceData;
+ RefPtrWillBeMember<CSSStyleSourceData> styleSourceData;
// Only for CSSMediaRules.
RuleSourceDataList childRules;
@@ -137,4 +143,7 @@ struct CSSRuleSourceData : public RefCounted<CSSRuleSourceData> {
} // namespace WebCore
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::SourceRange);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::CSSPropertySourceData);
+
#endif // CSSPropertySourceData_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSReflectValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSReflectValue.cpp
index b13006ccc5e..066d6439862 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSReflectValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSReflectValue.cpp
@@ -28,8 +28,6 @@
#include "core/css/CSSPrimitiveValue.h"
-using namespace std;
-
namespace WebCore {
String CSSReflectValue::customCSSText() const
@@ -39,19 +37,6 @@ String CSSReflectValue::customCSSText() const
return m_direction->cssText() + ' ' + m_offset->cssText();
}
-String CSSReflectValue::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- if (m_mask)
- return m_direction->customSerializeResolvingVariables(variables) + ' ' + m_offset->customSerializeResolvingVariables(variables) + ' ' + m_mask->serializeResolvingVariables(variables);
- return m_direction->customSerializeResolvingVariables(variables) + ' ' + m_offset->customSerializeResolvingVariables(variables);
-}
-
-void CSSReflectValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const
-{
- if (m_mask)
- m_mask->addSubresourceStyleURLs(urls, styleSheet);
-}
-
bool CSSReflectValue::equals(const CSSReflectValue& other) const
{
return m_direction == other.m_direction
@@ -59,4 +44,12 @@ bool CSSReflectValue::equals(const CSSReflectValue& other) const
&& compareCSSValuePtr(m_mask, other.m_mask);
}
+void CSSReflectValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_direction);
+ visitor->trace(m_offset);
+ visitor->trace(m_mask);
+ CSSValue::traceAfterDispatch(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSReflectValue.h b/chromium/third_party/WebKit/Source/core/css/CSSReflectValue.h
index 0fd92a07da2..b85d430c002 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSReflectValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSReflectValue.h
@@ -36,10 +36,10 @@ class CSSPrimitiveValue;
class CSSReflectValue : public CSSValue {
public:
- static PassRefPtr<CSSReflectValue> create(PassRefPtr<CSSPrimitiveValue> direction,
- PassRefPtr<CSSPrimitiveValue> offset, PassRefPtr<CSSValue> mask)
+ static PassRefPtrWillBeRawPtr<CSSReflectValue> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> direction,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, PassRefPtrWillBeRawPtr<CSSValue> mask)
{
- return adoptRef(new CSSReflectValue(direction, offset, mask));
+ return adoptRefWillBeNoop(new CSSReflectValue(direction, offset, mask));
}
CSSPrimitiveValue* direction() const { return m_direction.get(); }
@@ -47,14 +47,13 @@ public:
CSSValue* mask() const { return m_mask.get(); }
String customCSSText() const;
- String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const;
-
- void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
bool equals(const CSSReflectValue&) const;
+ void traceAfterDispatch(Visitor*);
+
private:
- CSSReflectValue(PassRefPtr<CSSPrimitiveValue> direction, PassRefPtr<CSSPrimitiveValue> offset, PassRefPtr<CSSValue> mask)
+ CSSReflectValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> direction, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, PassRefPtrWillBeRawPtr<CSSValue> mask)
: CSSValue(ReflectClass)
, m_direction(direction)
, m_offset(offset)
@@ -62,9 +61,9 @@ private:
{
}
- RefPtr<CSSPrimitiveValue> m_direction;
- RefPtr<CSSPrimitiveValue> m_offset;
- RefPtr<CSSValue> m_mask;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_direction;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_offset;
+ RefPtrWillBeMember<CSSValue> m_mask;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSReflectValue, isReflectValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSRegionRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSRegionRule.cpp
deleted file mode 100644
index 94e9d0bae8c..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSRegionRule.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/css/CSSRegionRule.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/StyleRule.h"
-#include "wtf/text/StringBuilder.h"
-
-namespace WebCore {
-CSSRegionRule::CSSRegionRule(StyleRuleRegion* regionRule, CSSStyleSheet* parent)
- : CSSGroupingRule(regionRule, parent)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
-}
-
-String CSSRegionRule::cssText() const
-{
- StringBuilder result;
- result.appendLiteral("@-webkit-region ");
-
- // First add the selectors.
- result.append(toStyleRuleRegion(m_groupRule.get())->selectorList().selectorsText());
-
- // Then add the rules.
- result.appendLiteral(" { \n");
- appendCSSTextForItems(result);
- result.append('}');
- return result.toString();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSRegionRule.h b/chromium/third_party/WebKit/Source/core/css/CSSRegionRule.h
deleted file mode 100644
index e095da44af4..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSRegionRule.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef CSSRegionRule_h
-#define CSSRegionRule_h
-
-#include "core/css/CSSGroupingRule.h"
-
-namespace WebCore {
-
-class StyleRuleRegion;
-
-class CSSRegionRule : public CSSGroupingRule {
-public:
- static PassRefPtr<CSSRegionRule> create(StyleRuleRegion* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSRegionRule(rule, sheet)); }
-
- virtual CSSRule::Type type() const OVERRIDE { return WEBKIT_REGION_RULE; }
- virtual String cssText() const OVERRIDE;
-
-private:
- CSSRegionRule(StyleRuleRegion*, CSSStyleSheet* parent);
-};
-
-DEFINE_CSS_RULE_TYPE_CASTS(CSSRegionRule, WEBKIT_REGION_RULE);
-
-}
-
-#endif // CSSRegionRule_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSRule.cpp
index 7673640a990..60aa695022e 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSRule.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-struct SameSizeAsCSSRule : public RefCounted<SameSizeAsCSSRule> {
+struct SameSizeAsCSSRule : public RefCountedWillBeGarbageCollectedFinalized<SameSizeAsCSSRule> {
virtual ~SameSizeAsCSSRule();
unsigned char bitfields;
void* pointerUnion;
@@ -37,8 +37,6 @@ struct SameSizeAsCSSRule : public RefCounted<SameSizeAsCSSRule> {
COMPILE_ASSERT(sizeof(CSSRule) == sizeof(SameSizeAsCSSRule), CSSRule_should_stay_small);
-COMPILE_ASSERT(StyleRuleBase::Region == static_cast<StyleRuleBase::Type>(CSSRule::WEBKIT_REGION_RULE), enums_should_match);
-
COMPILE_ASSERT(StyleRuleBase::Viewport == static_cast<StyleRuleBase::Type>(CSSRule::VIEWPORT_RULE), enums_should_match);
void CSSRule::setCSSText(const String&)
@@ -52,4 +50,15 @@ const CSSParserContext& CSSRule::parserContext() const
return styleSheet ? styleSheet->contents()->parserContext() : strictCSSParserContext();
}
+void CSSRule::trace(Visitor* visitor)
+{
+ // This makes the parent link strong, which is different from the
+ // pre-oilpan world, where the parent link is mysteriously zeroed under
+ // some circumstances.
+ if (m_parentIsRule)
+ visitor->trace(m_parentRule);
+ else
+ visitor->trace(m_parentStyleSheet);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSRule.h b/chromium/third_party/WebKit/Source/core/css/CSSRule.h
index 9cd66086e23..b160a9e82da 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSRule.h
@@ -23,6 +23,7 @@
#ifndef CSSRule_h
#define CSSRule_h
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -32,7 +33,7 @@ class CSSParserContext;
class CSSStyleSheet;
class StyleRuleBase;
-class CSSRule : public RefCounted<CSSRule> {
+class CSSRule : public RefCountedWillBeGarbageCollectedFinalized<CSSRule> {
public:
virtual ~CSSRule() { }
@@ -53,7 +54,6 @@ public:
WEBKIT_KEYFRAME_RULE = KEYFRAME_RULE,
SUPPORTS_RULE = 12,
VIEWPORT_RULE = 15,
- WEBKIT_REGION_RULE = 16,
WEBKIT_FILTER_RULE = 17
};
@@ -73,6 +73,8 @@ public:
m_parentRule = rule;
}
+ virtual void trace(Visitor*);
+
CSSStyleSheet* parentStyleSheet() const
{
if (m_parentIsRule)
@@ -102,6 +104,7 @@ private:
mutable unsigned char m_hasCachedSelectorText : 1;
unsigned char m_parentIsRule : 1;
+ // These should be Members, but no Members in unions.
union {
CSSRule* m_parentRule;
CSSStyleSheet* m_parentStyleSheet;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSRule.idl b/chromium/third_party/WebKit/Source/core/css/CSSRule.idl
index 9dadad92a10..a70bd3ec983 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSRule.idl
+++ b/chromium/third_party/WebKit/Source/core/css/CSSRule.idl
@@ -22,6 +22,7 @@
[
Custom=Wrap,
DependentLifetime,
+ WillBeGarbageCollected,
] interface CSSRule {
// RuleType
@@ -38,7 +39,6 @@
const unsigned short WEBKIT_KEYFRAME_RULE = 8;
const unsigned short SUPPORTS_RULE = 12;
[RuntimeEnabled=CSSViewport] const unsigned short VIEWPORT_RULE = 15;
- [RuntimeEnabled=CSSRegions] const unsigned short WEBKIT_REGION_RULE = 16;
const unsigned short WEBKIT_FILTER_RULE = 17;
readonly attribute unsigned short type;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSRuleList.cpp b/chromium/third_party/WebKit/Source/core/css/CSSRuleList.cpp
index 499518bde5d..bfdf30c8719 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSRuleList.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSRuleList.cpp
@@ -35,7 +35,9 @@ CSSRuleList::~CSSRuleList()
}
StaticCSSRuleList::StaticCSSRuleList()
+#if !ENABLE(OILPAN)
: m_refCount(1)
+#endif
{
}
@@ -43,11 +45,20 @@ StaticCSSRuleList::~StaticCSSRuleList()
{
}
+#if !ENABLE(OILPAN)
void StaticCSSRuleList::deref()
{
ASSERT(m_refCount);
if (!--m_refCount)
delete this;
}
+#endif
+
+void StaticCSSRuleList::trace(Visitor* visitor)
+{
+ visitor->trace(m_rules);
+ CSSRuleList::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSRuleList.h b/chromium/third_party/WebKit/Source/core/css/CSSRuleList.h
index f65b3667a4f..81b0fcf9775 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSRuleList.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSRuleList.h
@@ -22,6 +22,7 @@
#ifndef CSSRuleList_h
#define CSSRuleList_h
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
@@ -31,60 +32,86 @@ namespace WebCore {
class CSSRule;
class CSSStyleSheet;
-class CSSRuleList {
- WTF_MAKE_NONCOPYABLE(CSSRuleList); WTF_MAKE_FAST_ALLOCATED;
+class CSSRuleList : public NoBaseWillBeGarbageCollectedFinalized<CSSRuleList> {
+ WTF_MAKE_NONCOPYABLE(CSSRuleList);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
virtual ~CSSRuleList();
+#if !ENABLE(OILPAN)
virtual void ref() = 0;
virtual void deref() = 0;
+#endif
virtual unsigned length() const = 0;
virtual CSSRule* item(unsigned index) const = 0;
virtual CSSStyleSheet* styleSheet() const = 0;
+ virtual void trace(Visitor*) { }
+
protected:
CSSRuleList();
};
-class StaticCSSRuleList : public CSSRuleList {
+class StaticCSSRuleList FINAL : public CSSRuleList {
public:
- static PassRefPtr<StaticCSSRuleList> create() { return adoptRef(new StaticCSSRuleList()); }
+ static PassRefPtrWillBeRawPtr<StaticCSSRuleList> create()
+ {
+ return adoptRefWillBeNoop(new StaticCSSRuleList());
+ }
+
+#if !ENABLE(OILPAN)
+ virtual void ref() OVERRIDE { ++m_refCount; }
+ virtual void deref() OVERRIDE;
+#endif
- virtual void ref() { ++m_refCount; }
- virtual void deref();
+ WillBeHeapVector<RefPtrWillBeMember<CSSRule> >& rules() { return m_rules; }
- Vector<RefPtr<CSSRule> >& rules() { return m_rules; }
+ virtual CSSStyleSheet* styleSheet() const OVERRIDE { return 0; }
- virtual CSSStyleSheet* styleSheet() const { return 0; }
+ virtual void trace(Visitor*) OVERRIDE;
private:
StaticCSSRuleList();
- ~StaticCSSRuleList();
+ virtual ~StaticCSSRuleList();
- virtual unsigned length() const { return m_rules.size(); }
- virtual CSSRule* item(unsigned index) const { return index < m_rules.size() ? m_rules[index].get() : 0; }
+ virtual unsigned length() const OVERRIDE { return m_rules.size(); }
+ virtual CSSRule* item(unsigned index) const OVERRIDE { return index < m_rules.size() ? m_rules[index].get() : 0; }
- Vector<RefPtr<CSSRule> > m_rules;
+ WillBeHeapVector<RefPtrWillBeMember<CSSRule> > m_rules;
+#if !ENABLE(OILPAN)
unsigned m_refCount;
+#endif
};
-// The rule owns the live list.
template <class Rule>
-class LiveCSSRuleList : public CSSRuleList {
+class LiveCSSRuleList FINAL : public CSSRuleList {
public:
- LiveCSSRuleList(Rule* rule) : m_rule(rule) { }
-
- virtual void ref() { m_rule->ref(); }
- virtual void deref() { m_rule->deref(); }
+ static PassOwnPtrWillBeRawPtr<LiveCSSRuleList> create(Rule* rule)
+ {
+ return adoptPtrWillBeNoop(new LiveCSSRuleList(rule));
+ }
+
+#if !ENABLE(OILPAN)
+ virtual void ref() OVERRIDE { m_rule->ref(); }
+ virtual void deref() OVERRIDE { m_rule->deref(); }
+#endif
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_rule);
+ CSSRuleList::trace(visitor);
+ }
private:
- virtual unsigned length() const { return m_rule->length(); }
- virtual CSSRule* item(unsigned index) const { return m_rule->item(index); }
- virtual CSSStyleSheet* styleSheet() const { return m_rule->parentStyleSheet(); }
+ LiveCSSRuleList(Rule* rule) : m_rule(rule) { }
+
+ virtual unsigned length() const OVERRIDE { return m_rule->length(); }
+ virtual CSSRule* item(unsigned index) const OVERRIDE { return m_rule->item(index); }
+ virtual CSSStyleSheet* styleSheet() const OVERRIDE { return m_rule->parentStyleSheet(); }
- Rule* m_rule;
+ RawPtrWillBeMember<Rule> m_rule;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSRuleList.idl b/chromium/third_party/WebKit/Source/core/css/CSSRuleList.idl
index dd189108786..35fb40069fe 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSRuleList.idl
+++ b/chromium/third_party/WebKit/Source/core/css/CSSRuleList.idl
@@ -25,7 +25,8 @@
// Introduced in DOM Level 2:
[
- DependentLifetime
+ DependentLifetime,
+ WillBeGarbageCollected,
] interface CSSRuleList {
readonly attribute unsigned long length;
getter CSSRule item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.cpp
index d0912d4263f..db01c5bbf62 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.cpp
@@ -26,8 +26,8 @@
#include "core/css/CSSSVGDocumentValue.h"
-#include "FetchInitiatorTypeNames.h"
-#include "core/css/CSSParser.h"
+#include "core/FetchInitiatorTypeNames.h"
+#include "core/css/CSSMarkup.h"
#include "core/dom/Document.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.h b/chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.h
index d2decc42d88..389b1797f60 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSVGDocumentValue.h
@@ -35,7 +35,10 @@ class ResourceFetcher;
class CSSSVGDocumentValue : public CSSValue {
public:
- static PassRefPtr<CSSSVGDocumentValue> create(const String& url) { return adoptRef(new CSSSVGDocumentValue(url)); }
+ static PassRefPtrWillBeRawPtr<CSSSVGDocumentValue> create(const String& url)
+ {
+ return adoptRefWillBeNoop(new CSSSVGDocumentValue(url));
+ }
~CSSSVGDocumentValue();
DocumentResource* cachedSVGDocument() const { return m_document.get(); }
@@ -46,6 +49,8 @@ public:
bool loadRequested() const { return m_loadRequested; }
bool equals(const CSSSVGDocumentValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
CSSSVGDocumentValue(const String& url);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.cpp b/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.cpp
index eaa1223b132..edb36fa9809 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.cpp
@@ -26,8 +26,9 @@
#include "config.h"
#include "core/css/CSSSegmentedFontFace.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/css/CSSFontFace.h"
+#include "core/css/CSSFontSelector.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/fonts/FontCache.h"
#include "platform/fonts/FontDescription.h"
#include "platform/fonts/SegmentedFontData.h"
@@ -35,18 +36,20 @@
namespace WebCore {
-CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector, FontTraitsMask traitsMask)
+CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector, FontTraits traits)
: m_fontSelector(fontSelector)
- , m_traitsMask(traitsMask)
+ , m_traits(traits)
+ , m_firstNonCssConnectedFace(m_fontFaces.end())
{
}
CSSSegmentedFontFace::~CSSSegmentedFontFace()
{
pruneTable();
- unsigned size = m_fontFaces.size();
- for (unsigned i = 0; i < size; i++)
- m_fontFaces[i]->clearSegmentedFontFace();
+#if !ENABLE(OILPAN)
+ for (FontFaceList::iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it)
+ (*it)->cssFontFace()->clearSegmentedFontFace();
+#endif
}
void CSSSegmentedFontFace::pruneTable()
@@ -61,9 +64,8 @@ void CSSSegmentedFontFace::pruneTable()
bool CSSSegmentedFontFace::isValid() const
{
// Valid if at least one font face is valid.
- unsigned size = m_fontFaces.size();
- for (unsigned i = 0; i < size; i++) {
- if (m_fontFaces[i]->isValid())
+ for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
+ if ((*it)->cssFontFace()->isValid())
return true;
}
return false;
@@ -72,36 +74,43 @@ bool CSSSegmentedFontFace::isValid() const
void CSSSegmentedFontFace::fontLoaded(CSSFontFace*)
{
pruneTable();
-
- if (RuntimeEnabledFeatures::fontLoadEventsEnabled() && !isLoading()) {
- Vector<RefPtr<LoadFontCallback> > callbacks;
- m_callbacks.swap(callbacks);
- for (size_t index = 0; index < callbacks.size(); ++index) {
- if (isLoaded())
- callbacks[index]->notifyLoaded(this);
- else
- callbacks[index]->notifyError(this);
- }
- }
}
-void CSSSegmentedFontFace::appendFontFace(PassRefPtr<CSSFontFace> fontFace)
+void CSSSegmentedFontFace::fontLoadWaitLimitExceeded(CSSFontFace*)
{
pruneTable();
- fontFace->setSegmentedFontFace(this);
- m_fontFaces.append(fontFace);
}
-void CSSSegmentedFontFace::removeFontFace(PassRefPtr<CSSFontFace> fontFace)
+void CSSSegmentedFontFace::addFontFace(PassRefPtrWillBeRawPtr<FontFace> prpFontFace, bool cssConnected)
{
- size_t index = m_fontFaces.find(fontFace);
- if (index != kNotFound) {
- pruneTable();
- m_fontFaces.remove(index);
- fontFace->clearSegmentedFontFace();
+ RefPtrWillBeRawPtr<FontFace> fontFace = prpFontFace;
+ pruneTable();
+ fontFace->cssFontFace()->setSegmentedFontFace(this);
+ if (cssConnected) {
+ m_fontFaces.insertBefore(m_firstNonCssConnectedFace, fontFace);
+ } else {
+ // This is the only place in Blink that is using addReturnIterator.
+ FontFaceList::iterator iterator = m_fontFaces.addReturnIterator(fontFace);
+ if (m_firstNonCssConnectedFace == m_fontFaces.end())
+ m_firstNonCssConnectedFace = iterator;
}
}
+void CSSSegmentedFontFace::removeFontFace(PassRefPtrWillBeRawPtr<FontFace> prpFontFace)
+{
+ RefPtrWillBeRawPtr<FontFace> fontFace = prpFontFace;
+ FontFaceList::iterator it = m_fontFaces.find(fontFace);
+ if (it == m_fontFaces.end())
+ return;
+
+ if (it == m_firstNonCssConnectedFace)
+ ++m_firstNonCssConnectedFace;
+ m_fontFaces.remove(it);
+
+ pruneTable();
+ fontFace->cssFontFace()->clearSegmentedFontFace();
+}
+
static void appendFontData(SegmentedFontData* newFontData, PassRefPtr<SimpleFontData> prpFaceFontData, const CSSFontFace::UnicodeRangeSet& ranges)
{
RefPtr<SimpleFontData> faceFontData = prpFaceFontData;
@@ -118,13 +127,13 @@ static void appendFontData(SegmentedFontData* newFontData, PassRefPtr<SimpleFont
PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription)
{
if (!isValid())
- return 0;
+ return nullptr;
- FontTraitsMask desiredTraitsMask = fontDescription.traitsMask();
+ FontTraits desiredTraits = fontDescription.traits();
AtomicString emptyFontFamily = "";
- FontCacheKey key = fontDescription.cacheKey(emptyFontFamily, desiredTraitsMask);
+ FontCacheKey key = fontDescription.cacheKey(emptyFontFamily, desiredTraits);
- RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(key.hash(), 0).iterator->value;
+ RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(key.hash(), nullptr).storedValue->value;
if (fontData && fontData->numRanges())
return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has.
@@ -132,35 +141,34 @@ PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fo
fontData = SegmentedFontData::create();
FontDescription requestedFontDescription(fontDescription);
- requestedFontDescription.setTraitsMask(m_traitsMask);
- requestedFontDescription.setSyntheticBold(!(m_traitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)) && (desiredTraitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)));
- requestedFontDescription.setSyntheticItalic(!(m_traitsMask & FontStyleItalicMask) && (desiredTraitsMask & FontStyleItalicMask));
+ requestedFontDescription.setTraits(m_traits);
+ requestedFontDescription.setSyntheticBold(m_traits.weight() < FontWeight600 && desiredTraits.weight() >= FontWeight600);
+ requestedFontDescription.setSyntheticItalic(m_traits.style() == FontStyleNormal && desiredTraits.style() == FontStyleItalic);
- for (int i = m_fontFaces.size() - 1; i >= 0; --i) {
- if (!m_fontFaces[i]->isValid())
+ for (FontFaceList::reverse_iterator it = m_fontFaces.rbegin(); it != m_fontFaces.rend(); ++it) {
+ if (!(*it)->cssFontFace()->isValid())
continue;
- if (RefPtr<SimpleFontData> faceFontData = m_fontFaces[i]->getFontData(requestedFontDescription)) {
+ if (RefPtr<SimpleFontData> faceFontData = (*it)->cssFontFace()->getFontData(requestedFontDescription)) {
ASSERT(!faceFontData->isSegmented());
#if ENABLE(SVG_FONTS)
// For SVG Fonts that specify that they only support the "normal" variant, we will assume they are incapable
// of small-caps synthesis and just ignore the font face.
- if (faceFontData->isSVGFont() && (desiredTraitsMask & FontVariantSmallCapsMask) && !(m_traitsMask & FontVariantSmallCapsMask))
+ if (faceFontData->isSVGFont() && desiredTraits.variant() == FontVariantSmallCaps && m_traits.variant() == FontVariantNormal)
continue;
#endif
- appendFontData(fontData.get(), faceFontData.release(), m_fontFaces[i]->ranges());
+ appendFontData(fontData.get(), faceFontData.release(), (*it)->cssFontFace()->ranges());
}
}
if (fontData->numRanges())
return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has.
- return 0;
+ return nullptr;
}
bool CSSSegmentedFontFace::isLoading() const
{
- unsigned size = m_fontFaces.size();
- for (unsigned i = 0; i < size; i++) {
- if (m_fontFaces[i]->loadStatus() == FontFace::Loading)
+ for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
+ if ((*it)->loadStatus() == FontFace::Loading)
return true;
}
return false;
@@ -168,61 +176,44 @@ bool CSSSegmentedFontFace::isLoading() const
bool CSSSegmentedFontFace::isLoaded() const
{
- unsigned size = m_fontFaces.size();
- for (unsigned i = 0; i < size; i++) {
- if (m_fontFaces[i]->loadStatus() != FontFace::Loaded)
+ for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
+ if ((*it)->loadStatus() != FontFace::Loaded)
return false;
}
return true;
}
-void CSSSegmentedFontFace::willUseFontData(const FontDescription& fontDescription)
+void CSSSegmentedFontFace::willUseFontData(const FontDescription& fontDescription, UChar32 character)
{
- unsigned size = m_fontFaces.size();
- for (unsigned i = 0; i < size; i++)
- m_fontFaces[i]->willUseFontData(fontDescription);
+ for (FontFaceList::reverse_iterator it = m_fontFaces.rbegin(); it != m_fontFaces.rend(); ++it) {
+ if ((*it)->loadStatus() != FontFace::Unloaded)
+ break;
+ if ((*it)->cssFontFace()->maybeScheduleFontLoad(fontDescription, character))
+ break;
+ }
}
bool CSSSegmentedFontFace::checkFont(const String& text) const
{
- unsigned size = m_fontFaces.size();
- for (unsigned i = 0; i < size; i++) {
- if (m_fontFaces[i]->loadStatus() != FontFace::Loaded && m_fontFaces[i]->ranges().intersectsWith(text))
+ for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
+ if ((*it)->loadStatus() != FontFace::Loaded && (*it)->cssFontFace()->ranges().intersectsWith(text))
return false;
}
return true;
}
-void CSSSegmentedFontFace::loadFont(const FontDescription& fontDescription, const String& text, PassRefPtr<LoadFontCallback> callback)
+void CSSSegmentedFontFace::match(const String& text, WillBeHeapVector<RefPtrWillBeMember<FontFace> >& faces) const
{
- unsigned size = m_fontFaces.size();
- for (unsigned i = 0; i < size; i++) {
- if (m_fontFaces[i]->loadStatus() == FontFace::Unloaded && m_fontFaces[i]->ranges().intersectsWith(text)) {
- RefPtr<SimpleFontData> fontData = m_fontFaces[i]->getFontData(fontDescription);
- if (fontData->customFontData())
- fontData->customFontData()->beginLoadIfNeeded();
- }
- }
-
- if (callback) {
- if (isLoading())
- m_callbacks.append(callback);
- else if (isLoaded())
- callback->notifyLoaded(this);
- else
- callback->notifyError(this);
+ for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
+ if ((*it)->cssFontFace()->ranges().intersectsWith(text))
+ faces.append(*it);
}
}
-Vector<RefPtr<FontFace> > CSSSegmentedFontFace::fontFaces(const String& text) const
+void CSSSegmentedFontFace::trace(Visitor* visitor)
{
- Vector<RefPtr<FontFace> > fontFaces;
- unsigned size = m_fontFaces.size();
- for (unsigned i = 0; i < size; i++) {
- if (m_fontFaces[i]->ranges().intersectsWith(text))
- fontFaces.append(m_fontFaces[i]->fontFace());
- }
- return fontFaces;
+ visitor->trace(m_fontSelector);
+ visitor->trace(m_fontFaces);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.h b/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.h
index 26c5bb1e0b0..a3630e38aa7 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFace.h
@@ -26,8 +26,10 @@
#ifndef CSSSegmentedFontFace_h
#define CSSSegmentedFontFace_h
-#include "platform/fonts/FontTraitsMask.h"
+#include "platform/fonts/FontTraits.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
+#include "wtf/ListHashSet.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -42,47 +44,48 @@ class FontDescription;
class FontFace;
class SegmentedFontData;
-class CSSSegmentedFontFace : public RefCounted<CSSSegmentedFontFace> {
+class CSSSegmentedFontFace FINAL : public RefCountedWillBeGarbageCollectedFinalized<CSSSegmentedFontFace> {
public:
- static PassRefPtr<CSSSegmentedFontFace> create(CSSFontSelector* selector, FontTraitsMask traitsMask) { return adoptRef(new CSSSegmentedFontFace(selector, traitsMask)); }
+ static PassRefPtrWillBeRawPtr<CSSSegmentedFontFace> create(CSSFontSelector* selector, FontTraits traits)
+ {
+ return adoptRefWillBeNoop(new CSSSegmentedFontFace(selector, traits));
+ }
~CSSSegmentedFontFace();
CSSFontSelector* fontSelector() const { return m_fontSelector; }
- FontTraitsMask traitsMask() const { return m_traitsMask; }
+ FontTraits traits() const { return m_traits; }
void fontLoaded(CSSFontFace*);
+ void fontLoadWaitLimitExceeded(CSSFontFace*);
- void appendFontFace(PassRefPtr<CSSFontFace>);
- void removeFontFace(PassRefPtr<CSSFontFace>);
+ void addFontFace(PassRefPtrWillBeRawPtr<FontFace>, bool cssConnected);
+ void removeFontFace(PassRefPtrWillBeRawPtr<FontFace>);
bool isEmpty() const { return m_fontFaces.isEmpty(); }
PassRefPtr<FontData> getFontData(const FontDescription&);
- class LoadFontCallback : public RefCounted<LoadFontCallback> {
- public:
- virtual ~LoadFontCallback() { }
- virtual void notifyLoaded(CSSSegmentedFontFace*) = 0;
- virtual void notifyError(CSSSegmentedFontFace*) = 0;
- };
-
bool checkFont(const String&) const;
- void loadFont(const FontDescription&, const String&, PassRefPtr<LoadFontCallback>);
- Vector<RefPtr<FontFace> > fontFaces(const String& text) const;
- void willUseFontData(const FontDescription&);
+ void match(const String&, WillBeHeapVector<RefPtrWillBeMember<FontFace> >&) const;
+ void willUseFontData(const FontDescription&, UChar32);
+
+ void trace(Visitor*);
private:
- CSSSegmentedFontFace(CSSFontSelector*, FontTraitsMask);
+ CSSSegmentedFontFace(CSSFontSelector*, FontTraits);
void pruneTable();
bool isValid() const;
bool isLoading() const;
bool isLoaded() const;
- CSSFontSelector* m_fontSelector;
- FontTraitsMask m_traitsMask;
+ typedef WillBeHeapListHashSet<RefPtrWillBeMember<FontFace> > FontFaceList;
+
+ RawPtrWillBeMember<CSSFontSelector> m_fontSelector;
+ FontTraits m_traits;
HashMap<unsigned, RefPtr<SegmentedFontData> > m_fontDataTable;
- Vector<RefPtr<CSSFontFace>, 1> m_fontFaces;
- Vector<RefPtr<LoadFontCallback> > m_callbacks;
+ // All non-CSS-connected FontFaces are stored after the CSS-connected ones.
+ FontFaceList m_fontFaces;
+ FontFaceList::iterator m_firstNonCssConnectedFace;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFaceCache.cpp b/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFaceCache.cpp
deleted file mode 100644
index 17803d82821..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFaceCache.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#include "config.h"
-#include "CSSSegmentedFontFaceCache.h"
-
-#include "FontFamilyNames.h"
-#include "core/css/CSSFontFace.h"
-#include "core/css/CSSFontFaceSource.h"
-#include "core/css/CSSFontSelector.h"
-#include "core/css/CSSSegmentedFontFace.h"
-#include "core/css/CSSValueList.h"
-#include "core/css/StyleRule.h"
-#include "core/fetch/FontResource.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "platform/fonts/FontDescription.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-CSSSegmentedFontFaceCache::CSSSegmentedFontFaceCache()
- : m_version(0)
-{
-}
-
-void CSSSegmentedFontFaceCache::add(CSSFontSelector* cssFontSelector, const StyleRuleFontFace* fontFaceRule, PassRefPtr<CSSFontFace> prpCssFontFace)
-{
- RefPtr<CSSFontFace> cssFontFace = prpCssFontFace;
-
- if (!m_styleRuleToFontFace.add(fontFaceRule, cssFontFace).isNewEntry)
- return;
-
- FontFace* fontFace = cssFontFace->fontFace();
-
- OwnPtr<TraitsMap>& familyFontFaces = m_fontFaces.add(fontFace->family(), nullptr).iterator->value;
- if (!familyFontFaces)
- familyFontFaces = adoptPtr(new TraitsMap);
-
- RefPtr<CSSSegmentedFontFace>& segmentedFontFace = familyFontFaces->add(fontFace->traitsMask(), 0).iterator->value;
- if (!segmentedFontFace)
- segmentedFontFace = CSSSegmentedFontFace::create(cssFontSelector, static_cast<FontTraitsMask>(fontFace->traitsMask()));
-
- segmentedFontFace->appendFontFace(cssFontFace);
-
- ++m_version;
-}
-
-void CSSSegmentedFontFaceCache::remove(const StyleRuleFontFace* fontFaceRule)
-{
- StyleRuleToFontFace::iterator styleRuleToFontFaceIter = m_styleRuleToFontFace.find(fontFaceRule);
- if (styleRuleToFontFaceIter == m_styleRuleToFontFace.end())
- return;
- RefPtr<CSSFontFace> cssFontFace = styleRuleToFontFaceIter->value;
-
- FamilyToTraitsMap::iterator fontFacesIter = m_fontFaces.find(cssFontFace->fontFace()->family());
- if (fontFacesIter == m_fontFaces.end())
- return;
- TraitsMap* familyFontFaces = fontFacesIter->value.get();
-
- TraitsMap::iterator familyFontFacesIter = familyFontFaces->find(cssFontFace->fontFace()->traitsMask());
- if (familyFontFacesIter == familyFontFaces->end())
- return;
- RefPtr<CSSSegmentedFontFace> segmentedFontFace = familyFontFacesIter->value;
-
- segmentedFontFace->removeFontFace(cssFontFace);
- if (segmentedFontFace->isEmpty()) {
- familyFontFaces->remove(familyFontFacesIter);
- if (familyFontFaces->isEmpty())
- m_fontFaces.remove(fontFacesIter);
- }
- m_styleRuleToFontFace.remove(styleRuleToFontFaceIter);
- m_fonts.clear();
- ++m_version;
-}
-
-static inline bool compareFontFaces(CSSSegmentedFontFace* first, CSSSegmentedFontFace* second, FontTraitsMask desiredTraitsMask)
-{
- FontTraitsMask firstTraitsMask = first->traitsMask();
- FontTraitsMask secondTraitsMask = second->traitsMask();
-
- bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMask & FontVariantMask;
- bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMask & FontVariantMask;
-
- if (firstHasDesiredVariant != secondHasDesiredVariant)
- return firstHasDesiredVariant;
-
- // We need to check font-variant css property for CSS2.1 compatibility.
- if (desiredTraitsMask & FontVariantSmallCapsMask) {
- // Prefer a font that has indicated that it can only support small-caps to a font that claims to support
- // all variants. The specialized font is more likely to be true small-caps and not require synthesis.
- bool firstRequiresSmallCaps = (firstTraitsMask & FontVariantSmallCapsMask) && !(firstTraitsMask & FontVariantNormalMask);
- bool secondRequiresSmallCaps = (secondTraitsMask & FontVariantSmallCapsMask) && !(secondTraitsMask & FontVariantNormalMask);
- if (firstRequiresSmallCaps != secondRequiresSmallCaps)
- return firstRequiresSmallCaps;
- }
-
- bool firstHasDesiredStyle = firstTraitsMask & desiredTraitsMask & FontStyleMask;
- bool secondHasDesiredStyle = secondTraitsMask & desiredTraitsMask & FontStyleMask;
-
- if (firstHasDesiredStyle != secondHasDesiredStyle)
- return firstHasDesiredStyle;
-
- if (desiredTraitsMask & FontStyleItalicMask) {
- // Prefer a font that has indicated that it can only support italics to a font that claims to support
- // all styles. The specialized font is more likely to be the one the author wants used.
- bool firstRequiresItalics = (firstTraitsMask & FontStyleItalicMask) && !(firstTraitsMask & FontStyleNormalMask);
- bool secondRequiresItalics = (secondTraitsMask & FontStyleItalicMask) && !(secondTraitsMask & FontStyleNormalMask);
- if (firstRequiresItalics != secondRequiresItalics)
- return firstRequiresItalics;
- }
-
- if (secondTraitsMask & desiredTraitsMask & FontWeightMask)
- return false;
- if (firstTraitsMask & desiredTraitsMask & FontWeightMask)
- return true;
-
- // http://www.w3.org/TR/2011/WD-css3-fonts-20111004/#font-matching-algorithm says :
- // - If the desired weight is less than 400, weights below the desired weight are checked in descending order followed by weights above the desired weight in ascending order until a match is found.
- // - If the desired weight is greater than 500, weights above the desired weight are checked in ascending order followed by weights below the desired weight in descending order until a match is found.
- // - If the desired weight is 400, 500 is checked first and then the rule for desired weights less than 400 is used.
- // - If the desired weight is 500, 400 is checked first and then the rule for desired weights less than 400 is used.
-
- static const unsigned fallbackRuleSets = 9;
- static const unsigned rulesPerSet = 8;
- static const FontTraitsMask weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = {
- { FontWeight200Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
- { FontWeight100Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
- { FontWeight200Mask, FontWeight100Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
- { FontWeight500Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
- { FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
- { FontWeight700Mask, FontWeight800Mask, FontWeight900Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
- { FontWeight800Mask, FontWeight900Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
- { FontWeight900Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
- { FontWeight800Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }
- };
-
- unsigned ruleSetIndex = 0;
- unsigned w = FontWeight100Bit;
- while (!(desiredTraitsMask & (1 << w))) {
- w++;
- ruleSetIndex++;
- }
-
- ASSERT(ruleSetIndex < fallbackRuleSets);
- const FontTraitsMask* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex];
- for (unsigned i = 0; i < rulesPerSet; ++i) {
- if (secondTraitsMask & weightFallbackRule[i])
- return false;
- if (firstTraitsMask & weightFallbackRule[i])
- return true;
- }
-
- return false;
-}
-
-CSSSegmentedFontFace* CSSSegmentedFontFaceCache::get(const FontDescription& fontDescription, const AtomicString& family)
-{
- TraitsMap* familyFontFaces = m_fontFaces.get(family);
- if (!familyFontFaces || familyFontFaces->isEmpty())
- return 0;
-
- OwnPtr<TraitsMap>& segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->value;
- if (!segmentedFontFaceCache)
- segmentedFontFaceCache = adoptPtr(new TraitsMap);
-
- FontTraitsMask traitsMask = fontDescription.traitsMask();
-
- RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).iterator->value;
- if (!face) {
- for (TraitsMap::const_iterator i = familyFontFaces->begin(); i != familyFontFaces->end(); ++i) {
- CSSSegmentedFontFace* candidate = i->value.get();
- unsigned candidateTraitsMask = candidate->traitsMask();
- if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask))
- continue;
- if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask))
- continue;
- if (!face || compareFontFaces(candidate, face.get(), traitsMask))
- face = candidate;
- }
- }
- return face.get();
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFaceCache.h b/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFaceCache.h
deleted file mode 100644
index c18220906eb..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSSegmentedFontFaceCache.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSSegmentedFontFaceCache_h
-#define CSSSegmentedFontFaceCache_h
-
-#include "wtf/Forward.h"
-#include "wtf/HashMap.h"
-#include "wtf/text/StringHash.h"
-
-namespace WebCore {
-
-class CSSFontFace;
-class CSSFontSelector;
-class CSSSegmentedFontFace;
-class FontDescription;
-class StyleRuleFontFace;
-
-class CSSSegmentedFontFaceCache {
-public:
- CSSSegmentedFontFaceCache();
-
- // FIXME: Remove CSSFontSelector as argument. Passing CSSFontSelector here is
- // a result of egregious spaghettification in CSSFontFace/FontFaceSet.
- void add(CSSFontSelector*, const StyleRuleFontFace*, PassRefPtr<CSSFontFace>);
- void remove(const StyleRuleFontFace*);
- // FIXME: It's sort of weird that add/remove uses StyleRuleFontFace* as key,
- // but this function uses FontDescription/family pair.
- CSSSegmentedFontFace* get(const FontDescription&, const AtomicString& family);
-
- unsigned version() const { return m_version; }
-
-private:
- typedef HashMap<unsigned, RefPtr<CSSSegmentedFontFace> > TraitsMap;
- typedef HashMap<String, OwnPtr<TraitsMap>, CaseFoldingHash> FamilyToTraitsMap;
- typedef HashMap<const StyleRuleFontFace*, RefPtr<CSSFontFace> > StyleRuleToFontFace;
- FamilyToTraitsMap m_fontFaces;
- FamilyToTraitsMap m_fonts;
- StyleRuleToFontFace m_styleRuleToFontFace;
-
- // FIXME: See if this could be ditched
- // Used to compare Font instances, and the usage seems suspect.
- unsigned m_version;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSelector.cpp b/chromium/third_party/WebKit/Source/core/css/CSSSelector.cpp
index b744726355b..293cb2fd7f9 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSelector.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSelector.cpp
@@ -26,15 +26,18 @@
#include "config.h"
#include "core/css/CSSSelector.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSOMUtils.h"
#include "core/css/CSSSelectorList.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/Assertions.h"
#include "wtf/HashMap.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/StringBuilder.h"
-#include "wtf/text/StringHash.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
namespace WebCore {
@@ -52,8 +55,10 @@ void CSSSelector::createRareData()
ASSERT(m_match != Tag);
if (m_hasRareData)
return;
- // Move the value to the rare data stucture.
- m_data.m_rareData = RareData::create(adoptRef(m_data.m_value)).leakRef();
+ AtomicString value(m_data.m_value);
+ if (m_data.m_value)
+ m_data.m_value->deref();
+ m_data.m_rareData = RareData::create(value).leakRef();
m_hasRareData = true;
}
@@ -94,7 +99,7 @@ inline unsigned CSSSelector::specificityForOneSelector() const
case Id:
return 0x10000;
case PseudoClass:
- if (pseudoType() == PseudoHost)
+ if (pseudoType() == PseudoHost || pseudoType() == PseudoHostContext)
return 0;
// fall through.
case Exact:
@@ -183,12 +188,6 @@ PseudoId CSSSelector::pseudoId(PseudoType type)
return SCROLLBAR_TRACK_PIECE;
case PseudoResizer:
return RESIZER;
- case PseudoFullScreen:
- return FULL_SCREEN;
- case PseudoFullScreenDocument:
- return FULL_SCREEN_DOCUMENT;
- case PseudoFullScreenAncestor:
- return FULL_SCREEN_ANCESTOR;
case PseudoUnknown:
case PseudoEmpty:
case PseudoFirstChild:
@@ -250,11 +249,14 @@ PseudoId CSSSelector::pseudoId(PseudoType type)
case PseudoCue:
case PseudoFutureCue:
case PseudoPastCue:
- case PseudoSeamlessDocument:
- case PseudoDistributed:
case PseudoUnresolved:
case PseudoContent:
case PseudoHost:
+ case PseudoHostContext:
+ case PseudoShadow:
+ case PseudoFullScreen:
+ case PseudoFullScreenDocument:
+ case PseudoFullScreenAncestor:
return NOPSEUDO;
case PseudoNotParsed:
ASSERT_NOT_REACHED();
@@ -265,191 +267,168 @@ PseudoId CSSSelector::pseudoId(PseudoType type)
return NOPSEUDO;
}
-static HashMap<StringImpl*, CSSSelector::PseudoType>* nameToPseudoTypeMap()
+// Could be made smaller and faster by replacing pointer with an
+// offset into a string buffer and making the bit fields smaller but
+// that could not be maintained by hand.
+struct NameToPseudoStruct {
+ const char* string;
+ unsigned type:8;
+};
+
+// This table should be kept sorted.
+const static NameToPseudoStruct pseudoTypeMap[] = {
+{"-webkit-any(", CSSSelector::PseudoAny},
+{"-webkit-any-link", CSSSelector::PseudoAnyLink},
+{"-webkit-autofill", CSSSelector::PseudoAutofill},
+{"-webkit-drag", CSSSelector::PseudoDrag},
+{"-webkit-full-page-media", CSSSelector::PseudoFullPageMedia},
+{"-webkit-full-screen", CSSSelector::PseudoFullScreen},
+{"-webkit-full-screen-ancestor", CSSSelector::PseudoFullScreenAncestor},
+{"-webkit-full-screen-document", CSSSelector::PseudoFullScreenDocument},
+{"-webkit-resizer", CSSSelector::PseudoResizer},
+{"-webkit-scrollbar", CSSSelector::PseudoScrollbar},
+{"-webkit-scrollbar-button", CSSSelector::PseudoScrollbarButton},
+{"-webkit-scrollbar-corner", CSSSelector::PseudoScrollbarCorner},
+{"-webkit-scrollbar-thumb", CSSSelector::PseudoScrollbarThumb},
+{"-webkit-scrollbar-track", CSSSelector::PseudoScrollbarTrack},
+{"-webkit-scrollbar-track-piece", CSSSelector::PseudoScrollbarTrackPiece},
+{"active", CSSSelector::PseudoActive},
+{"after", CSSSelector::PseudoAfter},
+{"backdrop", CSSSelector::PseudoBackdrop},
+{"before", CSSSelector::PseudoBefore},
+{"checked", CSSSelector::PseudoChecked},
+{"content", CSSSelector::PseudoContent},
+{"corner-present", CSSSelector::PseudoCornerPresent},
+{"cue", CSSSelector::PseudoWebKitCustomElement},
+{"cue(", CSSSelector::PseudoCue},
+{"decrement", CSSSelector::PseudoDecrement},
+{"default", CSSSelector::PseudoDefault},
+{"disabled", CSSSelector::PseudoDisabled},
+{"double-button", CSSSelector::PseudoDoubleButton},
+{"empty", CSSSelector::PseudoEmpty},
+{"enabled", CSSSelector::PseudoEnabled},
+{"end", CSSSelector::PseudoEnd},
+{"first", CSSSelector::PseudoFirstPage},
+{"first-child", CSSSelector::PseudoFirstChild},
+{"first-letter", CSSSelector::PseudoFirstLetter},
+{"first-line", CSSSelector::PseudoFirstLine},
+{"first-of-type", CSSSelector::PseudoFirstOfType},
+{"focus", CSSSelector::PseudoFocus},
+{"future", CSSSelector::PseudoFutureCue},
+{"horizontal", CSSSelector::PseudoHorizontal},
+{"host", CSSSelector::PseudoHost},
+{"host(", CSSSelector::PseudoHost},
+{"host-context(", CSSSelector::PseudoHostContext},
+{"hover", CSSSelector::PseudoHover},
+{"in-range", CSSSelector::PseudoInRange},
+{"increment", CSSSelector::PseudoIncrement},
+{"indeterminate", CSSSelector::PseudoIndeterminate},
+{"invalid", CSSSelector::PseudoInvalid},
+{"lang(", CSSSelector::PseudoLang},
+{"last-child", CSSSelector::PseudoLastChild},
+{"last-of-type", CSSSelector::PseudoLastOfType},
+{"left", CSSSelector::PseudoLeftPage},
+{"link", CSSSelector::PseudoLink},
+{"no-button", CSSSelector::PseudoNoButton},
+{"not(", CSSSelector::PseudoNot},
+{"nth-child(", CSSSelector::PseudoNthChild},
+{"nth-last-child(", CSSSelector::PseudoNthLastChild},
+{"nth-last-of-type(", CSSSelector::PseudoNthLastOfType},
+{"nth-of-type(", CSSSelector::PseudoNthOfType},
+{"only-child", CSSSelector::PseudoOnlyChild},
+{"only-of-type", CSSSelector::PseudoOnlyOfType},
+{"optional", CSSSelector::PseudoOptional},
+{"out-of-range", CSSSelector::PseudoOutOfRange},
+{"past", CSSSelector::PseudoPastCue},
+{"read-only", CSSSelector::PseudoReadOnly},
+{"read-write", CSSSelector::PseudoReadWrite},
+{"required", CSSSelector::PseudoRequired},
+{"right", CSSSelector::PseudoRightPage},
+{"root", CSSSelector::PseudoRoot},
+{"scope", CSSSelector::PseudoScope},
+{"selection", CSSSelector::PseudoSelection},
+{"shadow", CSSSelector::PseudoShadow},
+{"single-button", CSSSelector::PseudoSingleButton},
+{"start", CSSSelector::PseudoStart},
+{"target", CSSSelector::PseudoTarget},
+{"unresolved", CSSSelector::PseudoUnresolved},
+{"valid", CSSSelector::PseudoValid},
+{"vertical", CSSSelector::PseudoVertical},
+{"visited", CSSSelector::PseudoVisited},
+{"window-inactive", CSSSelector::PseudoWindowInactive},
+};
+
+class NameToPseudoCompare {
+public:
+ NameToPseudoCompare(const AtomicString& key) : m_key(key) { ASSERT(m_key.is8Bit()); }
+
+ bool operator()(const NameToPseudoStruct& entry, const NameToPseudoStruct&)
+ {
+ ASSERT(entry.string);
+ const char* key = reinterpret_cast<const char*>(m_key.characters8());
+ // If strncmp returns 0, then either the keys are equal, or |m_key| sorts before |entry|.
+ return strncmp(entry.string, key, m_key.length()) < 0;
+ }
+
+private:
+ const AtomicString& m_key;
+};
+
+static CSSSelector::PseudoType nameToPseudoType(const AtomicString& name)
{
- DEFINE_STATIC_LOCAL(AtomicString, active, ("active", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, after, ("after", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, any, ("-webkit-any(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, anyLink, ("-webkit-any-link", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, autofill, ("-webkit-autofill", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, backdrop, ("backdrop", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, before, ("before", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, checked, ("checked", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, defaultString, ("default", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, disabled, ("disabled", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, readOnly, ("read-only", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, readWrite, ("read-write", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, valid, ("valid", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, invalid, ("invalid", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, drag, ("-webkit-drag", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, empty, ("empty", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, enabled, ("enabled", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, firstChild, ("first-child", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, firstLetter, ("first-letter", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, firstLine, ("first-line", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, firstOfType, ("first-of-type", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, fullPageMedia, ("-webkit-full-page-media", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, nthChild, ("nth-child(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, nthOfType, ("nth-of-type(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, nthLastChild, ("nth-last-child(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, nthLastOfType, ("nth-last-of-type(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, focus, ("focus", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, hover, ("hover", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, indeterminate, ("indeterminate", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, lastChild, ("last-child", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, lastOfType, ("last-of-type", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, link, ("link", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, lang, ("lang(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, notStr, ("not(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, onlyChild, ("only-child", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, onlyOfType, ("only-of-type", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, optional, ("optional", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, required, ("required", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, resizer, ("-webkit-resizer", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, root, ("root", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, scrollbar, ("-webkit-scrollbar", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, scrollbarButton, ("-webkit-scrollbar-button", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, scrollbarCorner, ("-webkit-scrollbar-corner", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, scrollbarThumb, ("-webkit-scrollbar-thumb", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, scrollbarTrack, ("-webkit-scrollbar-track", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, scrollbarTrackPiece, ("-webkit-scrollbar-track-piece", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, selection, ("selection", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, target, ("target", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, visited, ("visited", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, windowInactive, ("window-inactive", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, decrement, ("decrement", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, increment, ("increment", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, start, ("start", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, end, ("end", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, horizontal, ("horizontal", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, vertical, ("vertical", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, doubleButton, ("double-button", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, singleButton, ("single-button", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, noButton, ("no-button", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, cornerPresent, ("corner-present", AtomicString::ConstructFromLiteral));
- // Paged Media pseudo-classes
- DEFINE_STATIC_LOCAL(AtomicString, firstPage, ("first", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, leftPage, ("left", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, rightPage, ("right", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, fullScreen, ("-webkit-full-screen", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, fullScreenDocument, ("-webkit-full-screen-document", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, fullScreenAncestor, ("-webkit-full-screen-ancestor", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, cue, ("cue(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, cueWithoutParen, ("cue", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, futureCue, ("future", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, pastCue, ("past", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, seamlessDocument, ("-webkit-seamless-document", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, distributed, ("-webkit-distributed(", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, inRange, ("in-range", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, outOfRange, ("out-of-range", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, scope, ("scope", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, unresolved, ("unresolved", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, content, ("content", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, host, ("host", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(AtomicString, hostWithParams, ("host(", AtomicString::ConstructFromLiteral));
-
- static HashMap<StringImpl*, CSSSelector::PseudoType>* nameToPseudoType = 0;
- if (!nameToPseudoType) {
- nameToPseudoType = new HashMap<StringImpl*, CSSSelector::PseudoType>;
- nameToPseudoType->set(active.impl(), CSSSelector::PseudoActive);
- nameToPseudoType->set(after.impl(), CSSSelector::PseudoAfter);
- nameToPseudoType->set(anyLink.impl(), CSSSelector::PseudoAnyLink);
- nameToPseudoType->set(any.impl(), CSSSelector::PseudoAny);
- nameToPseudoType->set(autofill.impl(), CSSSelector::PseudoAutofill);
- nameToPseudoType->set(backdrop.impl(), CSSSelector::PseudoBackdrop);
- nameToPseudoType->set(before.impl(), CSSSelector::PseudoBefore);
- nameToPseudoType->set(checked.impl(), CSSSelector::PseudoChecked);
- nameToPseudoType->set(defaultString.impl(), CSSSelector::PseudoDefault);
- nameToPseudoType->set(disabled.impl(), CSSSelector::PseudoDisabled);
- nameToPseudoType->set(readOnly.impl(), CSSSelector::PseudoReadOnly);
- nameToPseudoType->set(readWrite.impl(), CSSSelector::PseudoReadWrite);
- nameToPseudoType->set(valid.impl(), CSSSelector::PseudoValid);
- nameToPseudoType->set(invalid.impl(), CSSSelector::PseudoInvalid);
- nameToPseudoType->set(drag.impl(), CSSSelector::PseudoDrag);
- nameToPseudoType->set(enabled.impl(), CSSSelector::PseudoEnabled);
- nameToPseudoType->set(empty.impl(), CSSSelector::PseudoEmpty);
- nameToPseudoType->set(firstChild.impl(), CSSSelector::PseudoFirstChild);
- nameToPseudoType->set(fullPageMedia.impl(), CSSSelector::PseudoFullPageMedia);
- nameToPseudoType->set(lastChild.impl(), CSSSelector::PseudoLastChild);
- nameToPseudoType->set(lastOfType.impl(), CSSSelector::PseudoLastOfType);
- nameToPseudoType->set(onlyChild.impl(), CSSSelector::PseudoOnlyChild);
- nameToPseudoType->set(onlyOfType.impl(), CSSSelector::PseudoOnlyOfType);
- nameToPseudoType->set(firstLetter.impl(), CSSSelector::PseudoFirstLetter);
- nameToPseudoType->set(firstLine.impl(), CSSSelector::PseudoFirstLine);
- nameToPseudoType->set(firstOfType.impl(), CSSSelector::PseudoFirstOfType);
- nameToPseudoType->set(focus.impl(), CSSSelector::PseudoFocus);
- nameToPseudoType->set(hover.impl(), CSSSelector::PseudoHover);
- nameToPseudoType->set(indeterminate.impl(), CSSSelector::PseudoIndeterminate);
- nameToPseudoType->set(link.impl(), CSSSelector::PseudoLink);
- nameToPseudoType->set(lang.impl(), CSSSelector::PseudoLang);
- nameToPseudoType->set(notStr.impl(), CSSSelector::PseudoNot);
- nameToPseudoType->set(nthChild.impl(), CSSSelector::PseudoNthChild);
- nameToPseudoType->set(nthOfType.impl(), CSSSelector::PseudoNthOfType);
- nameToPseudoType->set(nthLastChild.impl(), CSSSelector::PseudoNthLastChild);
- nameToPseudoType->set(nthLastOfType.impl(), CSSSelector::PseudoNthLastOfType);
- nameToPseudoType->set(root.impl(), CSSSelector::PseudoRoot);
- nameToPseudoType->set(windowInactive.impl(), CSSSelector::PseudoWindowInactive);
- nameToPseudoType->set(decrement.impl(), CSSSelector::PseudoDecrement);
- nameToPseudoType->set(increment.impl(), CSSSelector::PseudoIncrement);
- nameToPseudoType->set(start.impl(), CSSSelector::PseudoStart);
- nameToPseudoType->set(end.impl(), CSSSelector::PseudoEnd);
- nameToPseudoType->set(horizontal.impl(), CSSSelector::PseudoHorizontal);
- nameToPseudoType->set(vertical.impl(), CSSSelector::PseudoVertical);
- nameToPseudoType->set(doubleButton.impl(), CSSSelector::PseudoDoubleButton);
- nameToPseudoType->set(singleButton.impl(), CSSSelector::PseudoSingleButton);
- nameToPseudoType->set(noButton.impl(), CSSSelector::PseudoNoButton);
- nameToPseudoType->set(optional.impl(), CSSSelector::PseudoOptional);
- nameToPseudoType->set(required.impl(), CSSSelector::PseudoRequired);
- nameToPseudoType->set(resizer.impl(), CSSSelector::PseudoResizer);
- nameToPseudoType->set(scope.impl(), CSSSelector::PseudoScope);
- nameToPseudoType->set(scrollbar.impl(), CSSSelector::PseudoScrollbar);
- nameToPseudoType->set(scrollbarButton.impl(), CSSSelector::PseudoScrollbarButton);
- nameToPseudoType->set(scrollbarCorner.impl(), CSSSelector::PseudoScrollbarCorner);
- nameToPseudoType->set(scrollbarThumb.impl(), CSSSelector::PseudoScrollbarThumb);
- nameToPseudoType->set(scrollbarTrack.impl(), CSSSelector::PseudoScrollbarTrack);
- nameToPseudoType->set(scrollbarTrackPiece.impl(), CSSSelector::PseudoScrollbarTrackPiece);
- nameToPseudoType->set(cornerPresent.impl(), CSSSelector::PseudoCornerPresent);
- nameToPseudoType->set(selection.impl(), CSSSelector::PseudoSelection);
- nameToPseudoType->set(target.impl(), CSSSelector::PseudoTarget);
- nameToPseudoType->set(visited.impl(), CSSSelector::PseudoVisited);
- nameToPseudoType->set(firstPage.impl(), CSSSelector::PseudoFirstPage);
- nameToPseudoType->set(leftPage.impl(), CSSSelector::PseudoLeftPage);
- nameToPseudoType->set(rightPage.impl(), CSSSelector::PseudoRightPage);
- nameToPseudoType->set(fullScreen.impl(), CSSSelector::PseudoFullScreen);
- nameToPseudoType->set(fullScreenDocument.impl(), CSSSelector::PseudoFullScreenDocument);
- nameToPseudoType->set(fullScreenAncestor.impl(), CSSSelector::PseudoFullScreenAncestor);
- nameToPseudoType->set(cue.impl(), CSSSelector::PseudoCue);
- nameToPseudoType->set(cueWithoutParen.impl(), CSSSelector::PseudoWebKitCustomElement);
- nameToPseudoType->set(futureCue.impl(), CSSSelector::PseudoFutureCue);
- nameToPseudoType->set(pastCue.impl(), CSSSelector::PseudoPastCue);
- nameToPseudoType->set(seamlessDocument.impl(), CSSSelector::PseudoSeamlessDocument);
- nameToPseudoType->set(distributed.impl(), CSSSelector::PseudoDistributed);
- nameToPseudoType->set(inRange.impl(), CSSSelector::PseudoInRange);
- nameToPseudoType->set(outOfRange.impl(), CSSSelector::PseudoOutOfRange);
- if (RuntimeEnabledFeatures::shadowDOMEnabled()) {
- nameToPseudoType->set(host.impl(), CSSSelector::PseudoHost);
- nameToPseudoType->set(hostWithParams.impl(), CSSSelector::PseudoHost);
- nameToPseudoType->set(content.impl(), CSSSelector::PseudoContent);
- }
- if (RuntimeEnabledFeatures::customElementsEnabled())
- nameToPseudoType->set(unresolved.impl(), CSSSelector::PseudoUnresolved);
+ if (name.isNull() || !name.is8Bit())
+ return CSSSelector::PseudoUnknown;
+
+ const NameToPseudoStruct* pseudoTypeMapEnd = pseudoTypeMap + WTF_ARRAY_LENGTH(pseudoTypeMap);
+ NameToPseudoStruct dummyKey = { 0, CSSSelector::PseudoUnknown };
+ const NameToPseudoStruct* match = std::lower_bound(pseudoTypeMap, pseudoTypeMapEnd, dummyKey, NameToPseudoCompare(name));
+ if (match == pseudoTypeMapEnd || match->string != name.string())
+ return CSSSelector::PseudoUnknown;
+
+ return static_cast<CSSSelector::PseudoType>(match->type);
+}
+
+#ifndef NDEBUG
+void CSSSelector::show(int indent) const
+{
+ printf("%*sselectorText(): %s\n", indent, "", selectorText().ascii().data());
+ printf("%*sm_match: %d\n", indent, "", m_match);
+ printf("%*sisCustomPseudoElement(): %d\n", indent, "", isCustomPseudoElement());
+ if (m_match != Tag)
+ printf("%*svalue(): %s\n", indent, "", value().ascii().data());
+ printf("%*spseudoType(): %d\n", indent, "", pseudoType());
+ if (m_match == Tag)
+ printf("%*stagQName().localName: %s\n", indent, "", tagQName().localName().ascii().data());
+ printf("%*sisAttributeSelector(): %d\n", indent, "", isAttributeSelector());
+ if (isAttributeSelector())
+ printf("%*sattribute(): %s\n", indent, "", attribute().localName().ascii().data());
+ printf("%*sargument(): %s\n", indent, "", argument().ascii().data());
+ printf("%*sspecificity(): %u\n", indent, "", specificity());
+ if (tagHistory()) {
+ printf("\n%*s--> (relation == %d)\n", indent, "", relation());
+ tagHistory()->show(indent + 2);
+ } else {
+ printf("\n%*s--> (relation == %d)\n", indent, "", relation());
}
- return nameToPseudoType;
}
-CSSSelector::PseudoType CSSSelector::parsePseudoType(const AtomicString& name)
+void CSSSelector::show() const
{
- if (name.isNull())
- return PseudoUnknown;
- HashMap<StringImpl*, CSSSelector::PseudoType>* nameToPseudoType = nameToPseudoTypeMap();
- HashMap<StringImpl*, CSSSelector::PseudoType>::iterator slot = nameToPseudoType->find(name.impl());
+ printf("\n******* CSSSelector::show(\"%s\") *******\n", selectorText().ascii().data());
+ show(2);
+ printf("******* end *******\n");
+}
+#endif
- if (slot != nameToPseudoType->end())
- return slot->value;
+CSSSelector::PseudoType CSSSelector::parsePseudoType(const AtomicString& name)
+{
+ CSSSelector::PseudoType pseudoType = nameToPseudoType(name);
+ if (pseudoType != PseudoUnknown)
+ return pseudoType;
if (name.startsWith("-webkit-"))
return PseudoWebKitCustomElement;
- if (name.startsWith("x-") || name.startsWith("cue"))
+ if (name.startsWith("cue"))
return PseudoUserAgentCustomElement;
return PseudoUnknown;
@@ -474,7 +453,6 @@ void CSSSelector::extractPseudoType() const
case PseudoFirstLine:
compat = true;
case PseudoBackdrop:
- case PseudoDistributed:
case PseudoResizer:
case PseudoScrollbar:
case PseudoScrollbarCorner:
@@ -486,6 +464,7 @@ void CSSSelector::extractPseudoType() const
case PseudoUserAgentCustomElement:
case PseudoWebKitCustomElement:
case PseudoContent:
+ case PseudoShadow:
element = true;
break;
case PseudoUnknown:
@@ -543,12 +522,12 @@ void CSSSelector::extractPseudoType() const
case PseudoFullScreen:
case PseudoFullScreenDocument:
case PseudoFullScreenAncestor:
- case PseudoSeamlessDocument:
case PseudoInRange:
case PseudoOutOfRange:
case PseudoFutureCue:
case PseudoPastCue:
case PseudoHost:
+ case PseudoHostContext:
case PseudoUnresolved:
break;
case PseudoFirstPage:
@@ -640,7 +619,7 @@ String CSSSelector::selectorText(const String& rightSide) const
break;
case PseudoAny: {
const CSSSelector* firstSubSelector = cs->selectorList()->first();
- for (const CSSSelector* subSelector = firstSubSelector; subSelector; subSelector = CSSSelectorList::next(subSelector)) {
+ for (const CSSSelector* subSelector = firstSubSelector; subSelector; subSelector = CSSSelectorList::next(*subSelector)) {
if (subSelector != firstSubSelector)
str.append(',');
str.append(subSelector->selectorText());
@@ -648,10 +627,11 @@ String CSSSelector::selectorText(const String& rightSide) const
str.append(')');
break;
}
- case PseudoHost: {
+ case PseudoHost:
+ case PseudoHostContext: {
if (cs->selectorList()) {
const CSSSelector* firstSubSelector = cs->selectorList()->first();
- for (const CSSSelector* subSelector = firstSubSelector; subSelector; subSelector = CSSSelectorList::next(subSelector)) {
+ for (const CSSSelector* subSelector = firstSubSelector; subSelector; subSelector = CSSSelectorList::next(*subSelector)) {
if (subSelector != firstSubSelector)
str.append(',');
str.append(subSelector->selectorText());
@@ -718,17 +698,11 @@ String CSSSelector::selectorText(const String& rightSide) const
if (const CSSSelector* tagHistory = cs->tagHistory()) {
switch (cs->relation()) {
case CSSSelector::Descendant:
- if (cs->relationIsAffectedByPseudoContent() && tagHistory->pseudoType() != CSSSelector::PseudoContent)
- return tagHistory->selectorText("::-webkit-distributed(" + str.toString() + rightSide + ")");
return tagHistory->selectorText(" " + str.toString() + rightSide);
case CSSSelector::Child:
- if (cs->relationIsAffectedByPseudoContent() && tagHistory->pseudoType() != CSSSelector::PseudoContent)
- return tagHistory->selectorText("::-webkit-distributed(> " + str.toString() + rightSide + ")");
return tagHistory->selectorText(" > " + str.toString() + rightSide);
- case CSSSelector::ChildTree:
- return tagHistory->selectorText(" ^ " + str.toString() + rightSide);
- case CSSSelector::DescendantTree:
- return tagHistory->selectorText(" ^^ " + str.toString() + rightSide);
+ case CSSSelector::ShadowDeep:
+ return tagHistory->selectorText(" /deep/ " + str.toString() + rightSide);
case CSSSelector::DirectAdjacent:
return tagHistory->selectorText(" + " + str.toString() + rightSide);
case CSSSelector::IndirectAdjacent:
@@ -762,7 +736,7 @@ void CSSSelector::setSelectorList(PassOwnPtr<CSSSelectorList> selectorList)
static bool validateSubSelector(const CSSSelector* selector)
{
- switch (selector->m_match) {
+ switch (selector->match()) {
case CSSSelector::Tag:
case CSSSelector::Id:
case CSSSelector::Class:
@@ -775,6 +749,7 @@ static bool validateSubSelector(const CSSSelector* selector)
case CSSSelector::End:
return true;
case CSSSelector::PseudoElement:
+ case CSSSelector::Unknown:
return false;
case CSSSelector::PagePseudoClass:
case CSSSelector::PseudoClass:
@@ -800,6 +775,8 @@ static bool validateSubSelector(const CSSSelector* selector)
case CSSSelector::PseudoLastOfType:
case CSSSelector::PseudoOnlyOfType:
case CSSSelector::PseudoHost:
+ case CSSSelector::PseudoHostContext:
+ case CSSSelector::PseudoNot:
return true;
default:
return false;
@@ -843,8 +820,8 @@ bool CSSSelector::matchNth(int count) const
return m_data.m_rareData->matchNth(count);
}
-CSSSelector::RareData::RareData(PassRefPtr<StringImpl> value)
- : m_value(value.leakRef())
+CSSSelector::RareData::RareData(const AtomicString& value)
+ : m_value(value)
, m_a(0)
, m_b(0)
, m_attribute(anyQName())
@@ -854,8 +831,6 @@ CSSSelector::RareData::RareData(PassRefPtr<StringImpl> value)
CSSSelector::RareData::~RareData()
{
- if (m_value)
- m_value->deref();
}
// a helper function for parsing nth-arguments
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSelector.h b/chromium/third_party/WebKit/Source/core/css/CSSSelector.h
index b0094687fb6..254ae9c5bb7 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSelector.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSelector.h
@@ -30,7 +30,57 @@
namespace WebCore {
class CSSSelectorList;
- // this class represents a selector for a StyleRule
+ // This class represents a selector for a StyleRule.
+
+ // CSS selector representation is somewhat complicated and subtle. A representative list of selectors is
+ // in CSSSelectorTest; run it in a debug build to see useful debugging output.
+ //
+ // ** tagHistory() and relation():
+ //
+ // Selectors are represented as a linked list of simple selectors (defined more or less according to
+ // http://www.w3.org/TR/css3-selectors/#simple-selectors-dfn). The tagHistory() method returns the next
+ // simple selector in the list. The relation() method returns the relationship of the current simple selector to
+ // the one in tagHistory(). For example, the CSS selector .a.b #c is represented as:
+ //
+ // selectorText(): .a.b #c
+ // --> (relation == Descendant)
+ // selectorText(): .a.b
+ // --> (relation == SubSelector)
+ // selectorText(): .b
+ //
+ // Note that currently a bare selector such as ".a" has a relation() of Descendant. This is a bug - instead the relation should be
+ // "None".
+ //
+ // The order of tagHistory() varies depending on the situation.
+ // * Relations using combinators (http://www.w3.org/TR/css3-selectors/#combinators), such as descendant, sibling, etc., are parsed
+ // right-to-left (in the example above, this is why .c is earlier in the tagHistory() chain than .a.b).
+ // * SubSelector relations are parsed left-to-right in most cases (such as the .a.b example above); a counter-example is the
+ // ::content pseudo-element. Most (all?) other pseudo elements and pseudo classes are parsed left-to-right.
+ // * ShadowPseudo relations are parsed right-to-left. Example: summary::-webkit-details-marker is parsed as:
+ // selectorText(): summary::-webkit-details-marker
+ // --> (relation == ShadowPseudo)
+ // selectorText(): summary
+ //
+ // ** match():
+ //
+ // The match of the current simple selector tells us the type of selector, such as class, id, tagname, or pseudo-class.
+ // Inline comments in the Match enum give examples of when each type would occur.
+ //
+ // ** value(), attribute():
+ //
+ // value() tells you the value of the simple selector. For example, for class selectors, value() will tell you the class string,
+ // and for id selectors it will tell you the id(). See below for the special case of attribute selectors.
+ //
+ // ** Attribute selectors.
+ //
+ // Attribute selectors return the attribute name in the attribute() method. The value() method returns the value matched against
+ // in case of selectors like [attr="value"].
+ //
+ // ** isCustomPseudoElement():
+ //
+ // It appears this is used only for pseudo elements that appear in user-agent shadow DOM. They are not exposed to author-created
+ // shadow DOM.
+
class CSSSelector {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -50,36 +100,37 @@ namespace WebCore {
// tag == -1 means apply to all elements (Selector = *)
+ // http://www.w3.org/TR/css3-selectors/#specificity
+ // We use 256 as the base of the specificity number system.
unsigned specificity() const;
/* how the attribute value has to match.... Default is Exact */
enum Match {
Unknown = 0,
- Tag,
- Id,
- Class,
- Exact,
- Set,
- List,
- Hyphen,
- PseudoClass,
- PseudoElement,
+ Tag, // Example: div
+ Id, // Example: #id
+ Class, // example: .class
+ PseudoClass, // Example: :nth-child(2)
+ PseudoElement, // Example: ::first-line
+ PagePseudoClass, // ??
+ Exact, // Example: E[foo="bar"]
+ Set, // Example: E[foo]
+ Hyphen, // Example: E[foo|="bar"]
+ List, // Example: E[foo~="bar"]
Contain, // css3: E[foo*="bar"]
Begin, // css3: E[foo^="bar"]
End, // css3: E[foo$="bar"]
- PagePseudoClass
+ FirstAttributeSelectorMatch = Exact,
};
enum Relation {
- Descendant = 0,
- Child,
- DirectAdjacent,
- IndirectAdjacent,
- SubSelector,
- ShadowPseudo,
- // FIXME: rename ChildTree and DescendantTree when the spec for this is written down.
- ChildTree,
- DescendantTree
+ Descendant = 0, // "Space" combinator
+ Child, // > combinator
+ DirectAdjacent, // + combinator
+ IndirectAdjacent, // ~ combinator
+ SubSelector, // "No space" combinator
+ ShadowPseudo, // Special case of shadow DOM pseudo elements / shadow pseudo element
+ ShadowDeep // /deep/ combinator
};
enum PseudoType {
@@ -161,11 +212,11 @@ namespace WebCore {
PseudoCue,
PseudoFutureCue,
PseudoPastCue,
- PseudoSeamlessDocument,
- PseudoDistributed,
PseudoUnresolved,
PseudoContent,
- PseudoHost
+ PseudoHost,
+ PseudoHostContext,
+ PseudoShadow
};
enum MarginBoxType {
@@ -210,9 +261,15 @@ namespace WebCore {
// how you use the returned QualifiedName.
// http://www.w3.org/TR/css3-selectors/#attrnmsp
const QualifiedName& attribute() const;
+ // Returns the argument of a parameterized selector. For example, nth-child(2) would have an argument of 2.
const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; }
const CSSSelectorList* selectorList() const { return m_hasRareData ? m_data.m_rareData->m_selectorList.get() : 0; }
+#ifndef NDEBUG
+ void show() const;
+ void show(int indent) const;
+#endif
+
void setValue(const AtomicString&);
void setAttribute(const QualifiedName&);
void setArgument(const AtomicString&);
@@ -228,11 +285,25 @@ namespace WebCore {
bool isDirectAdjacentSelector() const { return m_relation == DirectAdjacent; }
bool isSiblingSelector() const;
bool isAttributeSelector() const;
- bool isDistributedPseudoElement() const;
bool isContentPseudoElement() const;
+ bool isShadowPseudoElement() const;
bool isHostPseudoClass() const;
+ // FIXME: selectors with no tagHistory() get a relation() of Descendant (and sometimes even SubSelector). It should instead be
+ // None.
Relation relation() const { return static_cast<Relation>(m_relation); }
+ void setRelation(Relation relation)
+ {
+ m_relation = relation;
+ ASSERT(static_cast<Relation>(m_relation) == relation); // using a bitfield.
+ }
+
+ Match match() const { return static_cast<Match>(m_match); }
+ void setMatch(Match match)
+ {
+ m_match = match;
+ ASSERT(static_cast<Match>(m_match) == match); // using a bitfield.
+ }
bool isLastInSelectorList() const { return m_isLastInSelectorList; }
void setLastInSelectorList() { m_isLastInSelectorList = true; }
@@ -248,11 +319,10 @@ namespace WebCore {
bool relationIsAffectedByPseudoContent() const { return m_relationIsAffectedByPseudoContent; }
void setRelationIsAffectedByPseudoContent() { m_relationIsAffectedByPseudoContent = true; }
+ private:
unsigned m_relation : 3; // enum Relation
mutable unsigned m_match : 4; // enum Match
mutable unsigned m_pseudoType : 8; // PseudoType
-
- private:
mutable unsigned m_parsedNth : 1; // Used for :nth-*
unsigned m_isLastInSelectorList : 1;
unsigned m_isLastInTagHistory : 1;
@@ -269,13 +339,13 @@ namespace WebCore {
CSSSelector& operator=(const CSSSelector&);
struct RareData : public RefCounted<RareData> {
- static PassRefPtr<RareData> create(PassRefPtr<StringImpl> value) { return adoptRef(new RareData(value)); }
+ static PassRefPtr<RareData> create(const AtomicString& value) { return adoptRef(new RareData(value)); }
~RareData();
bool parseNth();
bool matchNth(int count);
- StringImpl* m_value; // Plain pointer to keep things uniform with the union.
+ AtomicString m_value;
int m_a; // Used for :nth-*
int m_b; // Used for :nth-*
QualifiedName m_attribute; // used for attribute selector
@@ -283,7 +353,7 @@ namespace WebCore {
OwnPtr<CSSSelectorList> m_selectorList; // Used for :-webkit-any and :not
private:
- RareData(PassRefPtr<StringImpl> value);
+ RareData(const AtomicString& value);
};
void createRareData();
@@ -321,7 +391,7 @@ inline bool CSSSelector::isCustomPseudoElement() const
inline bool CSSSelector::isHostPseudoClass() const
{
- return m_match == PseudoClass && m_pseudoType == PseudoHost;
+ return m_match == PseudoClass && (m_pseudoType == PseudoHost || m_pseudoType == PseudoHostContext);
}
inline bool CSSSelector::isSiblingSelector() const
@@ -344,23 +414,17 @@ inline bool CSSSelector::isSiblingSelector() const
inline bool CSSSelector::isAttributeSelector() const
{
- return m_match == CSSSelector::Exact
- || m_match == CSSSelector::Set
- || m_match == CSSSelector::List
- || m_match == CSSSelector::Hyphen
- || m_match == CSSSelector::Contain
- || m_match == CSSSelector::Begin
- || m_match == CSSSelector::End;
+ return m_match >= FirstAttributeSelectorMatch;
}
-inline bool CSSSelector::isDistributedPseudoElement() const
+inline bool CSSSelector::isContentPseudoElement() const
{
- return m_match == PseudoElement && pseudoType() == PseudoDistributed;
+ return m_match == PseudoElement && pseudoType() == PseudoContent;
}
-inline bool CSSSelector::isContentPseudoElement() const
+inline bool CSSSelector::isShadowPseudoElement() const
{
- return m_match == PseudoElement && pseudoType() == PseudoContent;
+ return m_match == PseudoElement && pseudoType() == PseudoShadow;
}
inline void CSSSelector::setValue(const AtomicString& value)
@@ -369,10 +433,7 @@ inline void CSSSelector::setValue(const AtomicString& value)
ASSERT(m_pseudoType == PseudoNotParsed);
// Need to do ref counting manually for the union.
if (m_hasRareData) {
- if (m_data.m_rareData->m_value)
- m_data.m_rareData->m_value->deref();
- m_data.m_rareData->m_value = value.impl();
- m_data.m_rareData->m_value->ref();
+ m_data.m_rareData->m_value = value;
return;
}
if (m_data.m_value)
@@ -454,12 +515,13 @@ inline const QualifiedName& CSSSelector::tagQName() const
inline const AtomicString& CSSSelector::value() const
{
ASSERT(m_match != Tag);
+ if (m_hasRareData)
+ return m_data.m_rareData->m_value;
// AtomicString is really just a StringImpl* so the cast below is safe.
// FIXME: Perhaps call sites could be changed to accept StringImpl?
- return *reinterpret_cast<const AtomicString*>(m_hasRareData ? &m_data.m_rareData->m_value : &m_data.m_value);
+ return *reinterpret_cast<const AtomicString*>(&m_data.m_value);
}
-
} // namespace WebCore
#endif // CSSSelector_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSelectorList.cpp b/chromium/third_party/WebKit/Source/core/css/CSSSelectorList.cpp
index a3b8bdc7c12..2710a0f2e42 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSelectorList.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSelectorList.cpp
@@ -112,7 +112,7 @@ String CSSSelectorList::selectorsText() const
{
StringBuilder result;
- for (const CSSSelector* s = first(); s; s = next(s)) {
+ for (const CSSSelector* s = first(); s; s = next(*s)) {
if (s != first())
result.append(", ");
result.append(s->selectorText());
@@ -122,20 +122,19 @@ String CSSSelectorList::selectorsText() const
}
template <typename Functor>
-static bool forEachTagSelector(Functor& functor, const CSSSelector* selector)
+static bool forEachTagSelector(Functor& functor, const CSSSelector& selector)
{
- ASSERT(selector);
-
+ const CSSSelector* current = &selector;
do {
- if (functor(selector))
+ if (functor(*current))
return true;
- if (const CSSSelectorList* selectorList = selector->selectorList()) {
- for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
- if (forEachTagSelector(functor, subSelector))
+ if (const CSSSelectorList* selectorList = current->selectorList()) {
+ for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(*subSelector)) {
+ if (forEachTagSelector(functor, *subSelector))
return true;
}
}
- } while ((selector = selector->tagHistory()));
+ } while ((current = current->tagHistory()));
return false;
}
@@ -143,8 +142,8 @@ static bool forEachTagSelector(Functor& functor, const CSSSelector* selector)
template <typename Functor>
static bool forEachSelector(Functor& functor, const CSSSelectorList* selectorList)
{
- for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(selector)) {
- if (forEachTagSelector(functor, selector))
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) {
+ if (forEachTagSelector(functor, *selector))
return true;
}
@@ -153,11 +152,11 @@ static bool forEachSelector(Functor& functor, const CSSSelectorList* selectorLis
class SelectorNeedsNamespaceResolutionFunctor {
public:
- bool operator()(const CSSSelector* selector)
+ bool operator()(const CSSSelector& selector)
{
- if (selector->m_match == CSSSelector::Tag && selector->tagQName().prefix() != nullAtom && selector->tagQName().prefix() != starAtom)
+ if (selector.match() == CSSSelector::Tag && selector.tagQName().prefix() != nullAtom && selector.tagQName().prefix() != starAtom)
return true;
- if (selector->isAttributeSelector() && selector->attribute().prefix() != nullAtom && selector->attribute().prefix() != starAtom)
+ if (selector.isAttributeSelector() && selector.attribute().prefix() != nullAtom && selector.attribute().prefix() != starAtom)
return true;
return false;
}
@@ -171,9 +170,9 @@ bool CSSSelectorList::selectorsNeedNamespaceResolution()
class SelectorHasShadowDistributed {
public:
- bool operator()(const CSSSelector* selector)
+ bool operator()(const CSSSelector& selector)
{
- return selector->relationIsAffectedByPseudoContent();
+ return selector.relationIsAffectedByPseudoContent();
}
};
@@ -183,17 +182,17 @@ bool CSSSelectorList::hasShadowDistributedAt(size_t index) const
return forEachTagSelector(functor, selectorAt(index));
}
-class SelectorHasCombinatorCrossingTreeBoundary {
+class SelectorCrossesTreeScopes {
public:
- bool operator()(const CSSSelector* selector)
+ bool operator()(const CSSSelector& selector)
{
- return selector->relation() == CSSSelector::ChildTree || selector->relation() == CSSSelector::DescendantTree;
+ return selector.relation() == CSSSelector::ShadowDeep || selector.isShadowPseudoElement();
}
};
-bool CSSSelectorList::hasCombinatorCrossingTreeBoundaryAt(size_t index) const
+bool CSSSelectorList::selectorCrossesTreeScopes(size_t index) const
{
- SelectorHasCombinatorCrossingTreeBoundary functor;
+ SelectorCrossesTreeScopes functor;
return forEachTagSelector(functor, selectorAt(index));
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSelectorList.h b/chromium/third_party/WebKit/Source/core/css/CSSSelectorList.h
index 320de3b4175..e8932fec6fc 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSelectorList.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSelectorList.h
@@ -45,23 +45,23 @@ public:
bool isValid() const { return !!m_selectorArray; }
const CSSSelector* first() const { return m_selectorArray; }
- static const CSSSelector* next(const CSSSelector*);
- bool hasOneSelector() const { return m_selectorArray && !next(m_selectorArray); }
- const CSSSelector* selectorAt(size_t index) const { return &m_selectorArray[index]; }
+ static const CSSSelector* next(const CSSSelector&);
+ bool hasOneSelector() const { return m_selectorArray && !next(*m_selectorArray); }
+ const CSSSelector& selectorAt(size_t index) const { return m_selectorArray[index]; }
size_t indexOfNextSelectorAfter(size_t index) const
{
- const CSSSelector* current = selectorAt(index);
- current = next(current);
- if (!current)
+ const CSSSelector& current = selectorAt(index);
+ const CSSSelector* next = this->next(current);
+ if (!next)
return kNotFound;
- return current - m_selectorArray;
+ return next - m_selectorArray;
}
bool selectorsNeedNamespaceResolution();
bool hasShadowDistributedAt(size_t index) const;
- bool hasCombinatorCrossingTreeBoundaryAt(size_t index) const;
+ bool selectorCrossesTreeScopes(size_t index) const;
String selectorsText() const;
@@ -77,12 +77,13 @@ private:
CSSSelector* m_selectorArray;
};
-inline const CSSSelector* CSSSelectorList::next(const CSSSelector* current)
+inline const CSSSelector* CSSSelectorList::next(const CSSSelector& current)
{
// Skip subparts of compound selectors.
- while (!current->isLastInTagHistory())
- current++;
- return current->isLastInSelectorList() ? 0 : current + 1;
+ const CSSSelector* last = &current;
+ while (!last->isLastInTagHistory())
+ last++;
+ return last->isLastInSelectorList() ? 0 : last + 1;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSelectorTest.cpp b/chromium/third_party/WebKit/Source/core/css/CSSSelectorTest.cpp
new file mode 100644
index 00000000000..baf04659d65
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSelectorTest.cpp
@@ -0,0 +1,58 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/CSSTestHelper.h"
+#include "core/css/RuleSet.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+TEST(CSSSelector, Representations)
+{
+ CSSTestHelper helper;
+
+ const char* cssRules =
+ "summary::-webkit-details-marker { }"
+ "* {}"
+ "div {}"
+ "#id {}"
+ ".class {}"
+ "[attr] {}"
+ "div:hover {}"
+ "div:nth-child(2){}"
+ ".class#id { }"
+ "#id.class { }"
+ "[attr]#id { }"
+ "div[attr]#id { }"
+ "div::content { }"
+ "div::first-line { }"
+ ".a.b.c { }"
+ "div:not(.a) { }" // without class a
+ "div:not(:visited) { }" // without the visited pseudo class
+
+ "[attr=\"value\"] { }" // Exact equality
+ "[attr~=\"value\"] { }" // One of a space-separated list
+ "[attr^=\"value\"] { }" // Begins with
+ "[attr$=\"value\"] { }" // Ends with
+ "[attr*=\"value\"] { }" // Substring equal to
+ "[attr|=\"value\"] { }" // One of a hyphen-separated list
+
+ ".a .b { }" // .b is a descendant of .a
+ ".a > .b { }" // .b is a direct descendant of .a
+ ".a ~ .b { }" // .a precedes .b in sibling order
+ ".a + .b { }" // .a element immediately precedes .b in sibling order
+ ".a, .b { }" // matches .a or .b
+
+ ".a.b .c {}";
+
+ helper.addCSSRules(cssRules);
+ EXPECT_EQ(30u, helper.ruleSet().ruleCount()); // .a, .b counts as two rules.
+#ifndef NDEBUG
+ helper.ruleSet().show();
+#endif
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSShaderValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSShaderValue.cpp
deleted file mode 100644
index 1fafe3008f1..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSShaderValue.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/css/CSSShaderValue.h"
-
-#include "FetchInitiatorTypeNames.h"
-#include "core/css/CSSParser.h"
-#include "core/dom/Document.h"
-#include "core/fetch/FetchRequest.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/rendering/style/StyleFetchedShader.h"
-#include "core/rendering/style/StylePendingShader.h"
-#include "wtf/text/StringBuilder.h"
-
-namespace WebCore {
-
-CSSShaderValue::CSSShaderValue(const String& url)
- : CSSValue(CSSShaderClass)
- , m_url(url)
- , m_accessedShader(false)
-{
-}
-
-CSSShaderValue::~CSSShaderValue()
-{
-}
-
-KURL CSSShaderValue::completeURL(ResourceFetcher* loader) const
-{
- return loader->document()->completeURL(m_url);
-}
-
-StyleFetchedShader* CSSShaderValue::resource(ResourceFetcher* loader)
-{
- ASSERT(loader);
-
- if (!m_accessedShader) {
- m_accessedShader = true;
-
- FetchRequest request(ResourceRequest(completeURL(loader)), FetchInitiatorTypeNames::css);
- if (ResourcePtr<ShaderResource> resource = loader->fetchShader(request))
- m_shader = StyleFetchedShader::create(resource.get());
- }
-
- return (m_shader && m_shader->isShaderResource()) ? static_cast<StyleFetchedShader*>(m_shader.get()) : 0;
-}
-
-StyleShader* CSSShaderValue::cachedOrPendingShader()
-{
- if (!m_shader)
- m_shader = StylePendingShader::create(this);
-
- return m_shader.get();
-}
-
-String CSSShaderValue::customCSSText() const
-{
- StringBuilder result;
- result.appendLiteral("url(");
- result.append(quoteCSSURLIfNeeded(m_url));
- result.append(')');
- if (!m_format.isEmpty()) {
- result.appendLiteral(" format('");
- result.append(m_format);
- result.appendLiteral("')");
- }
- return result.toString();
-}
-
-bool CSSShaderValue::equals(const CSSShaderValue& other) const
-{
- return m_url == other.m_url;
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSShaderValue.h b/chromium/third_party/WebKit/Source/core/css/CSSShaderValue.h
deleted file mode 100644
index 9c736262402..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSShaderValue.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef CSSShaderValue_h
-#define CSSShaderValue_h
-
-#include "core/css/CSSValue.h"
-
-namespace WebCore {
-
-class ResourceFetcher;
-class KURL;
-class StyleFetchedShader;
-class StyleShader;
-
-class CSSShaderValue : public CSSValue {
-public:
- static PassRefPtr<CSSShaderValue> create(const String& url) { return adoptRef(new CSSShaderValue(url)); }
- ~CSSShaderValue();
-
- const String& format() const { return m_format; }
- void setFormat(const String& format) { m_format = format; }
-
- KURL completeURL(ResourceFetcher*) const;
- StyleFetchedShader* resource(ResourceFetcher*);
- StyleShader* cachedOrPendingShader();
-
- String customCSSText() const;
-
- bool equals(const CSSShaderValue&) const;
-
-private:
- CSSShaderValue(const String& url);
-
- String m_url;
- String m_format;
- RefPtr<StyleShader> m_shader;
- bool m_accessedShader;
-};
-
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSShaderValue, isShaderValue());
-
-} // namespace WebCore
-
-
-#endif // CSSShaderValue_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSShadowValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSShadowValue.cpp
index 35ecefb8cf9..4bdecf5ec10 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSShadowValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSShadowValue.cpp
@@ -27,12 +27,12 @@
namespace WebCore {
// Used for text-shadow and box-shadow
-CSSShadowValue::CSSShadowValue(PassRefPtr<CSSPrimitiveValue> x,
- PassRefPtr<CSSPrimitiveValue> y,
- PassRefPtr<CSSPrimitiveValue> blur,
- PassRefPtr<CSSPrimitiveValue> spread,
- PassRefPtr<CSSPrimitiveValue> style,
- PassRefPtr<CSSPrimitiveValue> color)
+CSSShadowValue::CSSShadowValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> x,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> y,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> blur,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> spread,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> style,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> color)
: CSSValue(ShadowClass)
, x(x)
, y(y)
@@ -88,4 +88,15 @@ bool CSSShadowValue::equals(const CSSShadowValue& other) const
&& compareCSSValuePtr(style, other.style);
}
+void CSSShadowValue::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(x);
+ visitor->trace(y);
+ visitor->trace(blur);
+ visitor->trace(spread);
+ visitor->trace(style);
+ visitor->trace(color);
+ CSSValue::traceAfterDispatch(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSShadowValue.h b/chromium/third_party/WebKit/Source/core/css/CSSShadowValue.h
index 79fe736c6f5..ddd32ddab2c 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSShadowValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSShadowValue.h
@@ -32,34 +32,36 @@ class CSSPrimitiveValue;
// Used for text-shadow and box-shadow
class CSSShadowValue : public CSSValue {
public:
- static PassRefPtr<CSSShadowValue> create(PassRefPtr<CSSPrimitiveValue> x,
- PassRefPtr<CSSPrimitiveValue> y,
- PassRefPtr<CSSPrimitiveValue> blur,
- PassRefPtr<CSSPrimitiveValue> spread,
- PassRefPtr<CSSPrimitiveValue> style,
- PassRefPtr<CSSPrimitiveValue> color)
+ static PassRefPtrWillBeRawPtr<CSSShadowValue> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> x,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> y,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> blur,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> spread,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> style,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> color)
{
- return adoptRef(new CSSShadowValue(x, y, blur, spread, style, color));
+ return adoptRefWillBeNoop(new CSSShadowValue(x, y, blur, spread, style, color));
}
String customCSSText() const;
bool equals(const CSSShadowValue&) const;
- RefPtr<CSSPrimitiveValue> x;
- RefPtr<CSSPrimitiveValue> y;
- RefPtr<CSSPrimitiveValue> blur;
- RefPtr<CSSPrimitiveValue> spread;
- RefPtr<CSSPrimitiveValue> style;
- RefPtr<CSSPrimitiveValue> color;
+ RefPtrWillBeMember<CSSPrimitiveValue> x;
+ RefPtrWillBeMember<CSSPrimitiveValue> y;
+ RefPtrWillBeMember<CSSPrimitiveValue> blur;
+ RefPtrWillBeMember<CSSPrimitiveValue> spread;
+ RefPtrWillBeMember<CSSPrimitiveValue> style;
+ RefPtrWillBeMember<CSSPrimitiveValue> color;
+
+ void traceAfterDispatch(Visitor*);
private:
- CSSShadowValue(PassRefPtr<CSSPrimitiveValue> x,
- PassRefPtr<CSSPrimitiveValue> y,
- PassRefPtr<CSSPrimitiveValue> blur,
- PassRefPtr<CSSPrimitiveValue> spread,
- PassRefPtr<CSSPrimitiveValue> style,
- PassRefPtr<CSSPrimitiveValue> color);
+ CSSShadowValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> x,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> y,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> blur,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> spread,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> style,
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> color);
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSShadowValue, isShadowValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSShorthands.in b/chromium/third_party/WebKit/Source/core/css/CSSShorthands.in
index f66d64994df..9495b43504e 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSShorthands.in
+++ b/chromium/third_party/WebKit/Source/core/css/CSSShorthands.in
@@ -21,6 +21,8 @@ border-width longhands=border-top-width;border-right-width;border-bottom-width;b
flex longhands=flex-grow;flex-shrink;flex-basis
flex-flow longhands=flex-direction;flex-wrap
font longhands=font-family;font-size;font-style;font-variant;font-weight;line-height
+grid longhands=grid-template;grid-auto-flow;grid-auto-columns;grid-auto-rows
+grid-template longhands=grid-template-columns;grid-template-rows;grid-template-areas
grid-area longhands=grid-row-start;grid-column-start;grid-row-end;grid-column-end
grid-column longhands=grid-column-start;grid-column-end
grid-row longhands=grid-row-start;grid-row-end
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.cpp b/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.cpp
deleted file mode 100644
index 1347f99c5c0..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/css/CSSStyleDeclaration.h"
-
-
-namespace WebCore {
-
-PassRefPtr<CSSVariablesMap> CSSStyleDeclaration::var()
-{
- if (!m_variablesMap)
- m_variablesMap = CSSVariablesMap::create(this);
- return m_variablesMap;
-}
-
-CSSStyleDeclaration::~CSSStyleDeclaration()
-{
- if (m_variablesMap)
- m_variablesMap->clearStyleDeclaration();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h b/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h
index 5c2445af31a..3aa549510f4 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.h
@@ -21,10 +21,8 @@
#ifndef CSSStyleDeclaration_h
#define CSSStyleDeclaration_h
-#include "CSSPropertyNames.h"
#include "bindings/v8/ScriptWrappable.h"
-#include "core/css/CSSVariablesIterator.h"
-#include "core/css/CSSVariablesMap.h"
+#include "core/CSSPropertyNames.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
@@ -36,22 +34,23 @@ class CSSStyleSheet;
class CSSValue;
class ExceptionState;
class MutableStylePropertySet;
-class VariablesIterator;
-class CSSStyleDeclaration : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(CSSStyleDeclaration); WTF_MAKE_FAST_ALLOCATED;
+class CSSStyleDeclaration : public NoBaseWillBeGarbageCollectedFinalized<CSSStyleDeclaration>, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(CSSStyleDeclaration); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- virtual ~CSSStyleDeclaration();
+ virtual ~CSSStyleDeclaration() { }
+#if !ENABLE(OILPAN)
virtual void ref() = 0;
virtual void deref() = 0;
+#endif
virtual CSSRule* parentRule() const = 0;
virtual String cssText() const = 0;
virtual void setCSSText(const String&, ExceptionState&) = 0;
virtual unsigned length() const = 0;
virtual String item(unsigned index) const = 0;
- virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName) = 0;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(const String& propertyName) = 0;
virtual String getPropertyValue(const String& propertyName) = 0;
virtual String getPropertyPriority(const String& propertyName) = 0;
virtual String getPropertyShorthand(const String& propertyName) = 0;
@@ -59,32 +58,25 @@ public:
virtual void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState&) = 0;
virtual String removeProperty(const String& propertyName, ExceptionState&) = 0;
- PassRefPtr<CSSVariablesMap> var();
- virtual unsigned variableCount() const = 0;
- virtual String variableValue(const AtomicString& name) const = 0;
- virtual bool setVariableValue(const AtomicString& name, const String& value, ExceptionState&) = 0; // Return value indicates whether variable was added.
- virtual bool removeVariable(const AtomicString& name) = 0;
- virtual bool clearVariables(ExceptionState&) = 0;
- virtual PassRefPtr<CSSVariablesIterator> variablesIterator() const = 0;
-
// CSSPropertyID versions of the CSSOM functions to support bindings and editing.
// Use the non-virtual methods in the concrete subclasses when possible.
// The CSSValue returned by this function should not be exposed to the web as it may be used by multiple documents at the same time.
- virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) = 0;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) = 0;
virtual String getPropertyValueInternal(CSSPropertyID) = 0;
virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionState&) = 0;
- virtual PassRefPtr<MutableStylePropertySet> copyProperties() const = 0;
+ virtual PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyProperties() const = 0;
virtual bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const = 0;
virtual CSSStyleSheet* parentStyleSheet() const { return 0; }
+ virtual void trace(Visitor*) { }
+
protected:
CSSStyleDeclaration()
{
ScriptWrappable::init(this);
}
- RefPtr<CSSVariablesMap> m_variablesMap;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl b/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl
index f552573a8eb..1fc7e9c6abf 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl
+++ b/chromium/third_party/WebKit/Source/core/css/CSSStyleDeclaration.idl
@@ -20,23 +20,27 @@
// Introduced in DOM Level 2:
[
- DependentLifetime
+ DependentLifetime,
+ WillBeGarbageCollected
] interface CSSStyleDeclaration {
[TreatReturnedNullStringAs=Null, TreatNullAs=NullString, RaisesException=Setter] attribute DOMString cssText;
[TreatReturnedNullStringAs=Null] DOMString getPropertyValue([Default=Undefined] optional DOMString propertyName);
- CSSValue getPropertyCSSValue([Default=Undefined] optional DOMString propertyName);
[TreatReturnedNullStringAs=Null, RaisesException] DOMString removeProperty([Default=Undefined] optional DOMString propertyName);
[TreatReturnedNullStringAs=Null] DOMString getPropertyPriority([Default=Undefined] optional DOMString propertyName);
[RaisesException] void setProperty([Default=Undefined] optional DOMString propertyName,
[TreatNullAs=NullString,Default=Undefined] optional DOMString value,
- [Default=Undefined] optional DOMString priority);
+ [TreatNullAs=NullString] optional DOMString priority = null);
readonly attribute unsigned long length;
getter DOMString item([Default=Undefined] optional unsigned long index);
- [Custom, CustomEnumerateProperty] getter (DOMString or float) (DOMString name);
+ [Custom=PropertyGetter|PropertyEnumerator|PropertyQuery] getter (DOMString or float) (DOMString name);
[Custom] setter void (DOMString propertyName, [TreatNullAs=NullString] DOMString propertyValue);
readonly attribute CSSRule parentRule;
- [RuntimeEnabled=CSSVariables] readonly attribute CSSVariablesMap var;
+
+ // Deprecated as of 2003: http://lists.w3.org/Archives/Public/www-style/2003Oct/0347.html
+ // FIXME: This should be DeprecateAs=, but currently too many LayoutTests use
+ // this function and would need CONSOLE: message rebaselines!
+ [MeasureAs=CSSStyleDeclarationGetPropertyCSSValue] CSSValue getPropertyCSSValue([Default=Undefined] optional DOMString propertyName);
};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSStyleRule.cpp
index 1ab4c5203a4..775583f6464 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSStyleRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSStyleRule.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "core/css/CSSStyleRule.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSSelector.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
@@ -47,9 +47,10 @@ CSSStyleRule::CSSStyleRule(StyleRule* styleRule, CSSStyleSheet* parent)
CSSStyleRule::~CSSStyleRule()
{
+#if !ENABLE(OILPAN)
if (m_propertiesCSSOMWrapper)
m_propertiesCSSOMWrapper->clearParentRule();
-
+#endif
if (hasCachedSelectorText()) {
selectorTextCache().remove(this);
setHasCachedSelectorText(false);
@@ -67,7 +68,7 @@ CSSStyleDeclaration* CSSStyleRule::style() const
String CSSStyleRule::generateSelectorText() const
{
StringBuilder builder;
- for (const CSSSelector* selector = m_styleRule->selectorList().first(); selector; selector = CSSSelectorList::next(selector)) {
+ for (const CSSSelector* selector = m_styleRule->selectorList().first(); selector; selector = CSSSelectorList::next(*selector)) {
if (selector != m_styleRule->selectorList().first())
builder.append(", ");
builder.append(selector->selectorText());
@@ -91,7 +92,8 @@ String CSSStyleRule::selectorText() const
void CSSStyleRule::setSelectorText(const String& selectorText)
{
- CSSParser p(parserContext());
+ CSSParserContext context(parserContext(), 0);
+ BisonCSSParser p(context);
CSSSelectorList selectorList;
p.parseSelector(selectorText, selectorList);
if (!selectorList.isValid())
@@ -112,7 +114,7 @@ String CSSStyleRule::cssText() const
StringBuilder result;
result.append(selectorText());
result.appendLiteral(" { ");
- String decls = m_styleRule->properties()->asText();
+ String decls = m_styleRule->properties().asText();
result.append(decls);
if (!decls.isEmpty())
result.append(' ');
@@ -128,4 +130,11 @@ void CSSStyleRule::reattach(StyleRuleBase* rule)
m_propertiesCSSOMWrapper->reattach(m_styleRule->mutableProperties());
}
+void CSSStyleRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_styleRule);
+ visitor->trace(m_propertiesCSSOMWrapper);
+ CSSRule::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleRule.h b/chromium/third_party/WebKit/Source/core/css/CSSStyleRule.h
index 12b4562f039..e1258bf5bc7 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSStyleRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSStyleRule.h
@@ -23,6 +23,7 @@
#define CSSStyleRule_h
#include "core/css/CSSRule.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -30,13 +31,16 @@ class CSSStyleDeclaration;
class StyleRuleCSSStyleDeclaration;
class StyleRule;
-class CSSStyleRule : public CSSRule {
+class CSSStyleRule FINAL : public CSSRule {
public:
- static PassRefPtr<CSSStyleRule> create(StyleRule* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSStyleRule(rule, sheet)); }
+ static PassRefPtrWillBeRawPtr<CSSStyleRule> create(StyleRule* rule, CSSStyleSheet* sheet)
+ {
+ return adoptRefWillBeNoop(new CSSStyleRule(rule, sheet));
+ }
virtual ~CSSStyleRule();
- virtual CSSRule::Type type() const { return STYLE_RULE; }
+ virtual CSSRule::Type type() const OVERRIDE { return STYLE_RULE; }
virtual String cssText() const OVERRIDE;
virtual void reattach(StyleRuleBase*) OVERRIDE;
@@ -48,13 +52,15 @@ public:
// FIXME: Not CSSOM. Remove.
StyleRule* styleRule() const { return m_styleRule.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSStyleRule(StyleRule*, CSSStyleSheet*);
String generateSelectorText() const;
- RefPtr<StyleRule> m_styleRule;
- mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
+ RefPtrWillBeMember<StyleRule> m_styleRule;
+ mutable RefPtrWillBeMember<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
};
DEFINE_CSS_RULE_TYPE_CASTS(CSSStyleRule, STYLE_RULE);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp b/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
index e7fe16ecd27..f3b536719c0 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.cpp
@@ -21,14 +21,15 @@
#include "config.h"
#include "core/css/CSSStyleSheet.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/V8Binding.h"
+#include "bindings/v8/V8PerIsolateData.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/css/CSSCharsetRule.h"
#include "core/css/CSSImportRule.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSRuleList.h"
-#include "core/css/CSSStyleRule.h"
#include "core/css/MediaList.h"
#include "core/css/StyleRule.h"
#include "core/css/StyleSheetContents.h"
@@ -36,76 +37,103 @@
#include "core/dom/ExceptionCode.h"
#include "core/dom/Node.h"
#include "core/frame/UseCounter.h"
+#include "core/html/HTMLStyleElement.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/svg/SVGStyleElement.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
-class StyleSheetCSSRuleList : public CSSRuleList {
+class StyleSheetCSSRuleList FINAL : public CSSRuleList {
public:
- StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { }
+ static PassOwnPtrWillBeRawPtr<StyleSheetCSSRuleList> create(CSSStyleSheet* sheet)
+ {
+ return adoptPtrWillBeNoop(new StyleSheetCSSRuleList(sheet));
+ }
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_styleSheet);
+ CSSRuleList::trace(visitor);
+ }
private:
- virtual void ref() { m_styleSheet->ref(); }
- virtual void deref() { m_styleSheet->deref(); }
+ StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { }
- virtual unsigned length() const { return m_styleSheet->length(); }
- virtual CSSRule* item(unsigned index) const { return m_styleSheet->item(index); }
+#if !ENABLE(OILPAN)
+ virtual void ref() OVERRIDE { m_styleSheet->ref(); }
+ virtual void deref() OVERRIDE { m_styleSheet->deref(); }
+#endif
- virtual CSSStyleSheet* styleSheet() const { return m_styleSheet; }
+ virtual unsigned length() const OVERRIDE { return m_styleSheet->length(); }
+ virtual CSSRule* item(unsigned index) const OVERRIDE { return m_styleSheet->item(index); }
- CSSStyleSheet* m_styleSheet;
+ virtual CSSStyleSheet* styleSheet() const OVERRIDE { return m_styleSheet; }
+
+ RawPtrWillBeMember<CSSStyleSheet> m_styleSheet;
};
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
static bool isAcceptableCSSStyleSheetParent(Node* parentNode)
{
- // Only these nodes can be parents of StyleSheets, and they need to call clearOwnerNode() when moved out of document.
+ // Only these nodes can be parents of StyleSheets, and they need to call
+ // clearOwnerNode() when moved out of document.
+ // Destruction of the style sheet counts as being "moved out of the
+ // document", but only in the non-oilpan version of blink. I.e. don't call
+ // clearOwnerNode() in the owner's destructor in oilpan.
return !parentNode
|| parentNode->isDocumentNode()
- || parentNode->hasTagName(HTMLNames::linkTag)
- || parentNode->hasTagName(HTMLNames::styleTag)
- || parentNode->hasTagName(SVGNames::styleTag)
+ || isHTMLLinkElement(*parentNode)
+ || isHTMLStyleElement(*parentNode)
+ || isSVGStyleElement(*parentNode)
|| parentNode->nodeType() == Node::PROCESSING_INSTRUCTION_NODE;
}
#endif
-PassRefPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtr<StyleSheetContents> sheet, CSSImportRule* ownerRule)
+PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, CSSImportRule* ownerRule)
{
- return adoptRef(new CSSStyleSheet(sheet, ownerRule));
+ return adoptRefWillBeNoop(new CSSStyleSheet(sheet, ownerRule));
}
-PassRefPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtr<StyleSheetContents> sheet, Node* ownerNode)
+PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, Node* ownerNode)
{
- return adoptRef(new CSSStyleSheet(sheet, ownerNode, false, TextPosition::minimumPosition()));
+ return adoptRefWillBeNoop(new CSSStyleSheet(sheet, ownerNode, false, TextPosition::minimumPosition()));
}
-PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const TextPosition& startPosition, const String& encoding)
+PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::createInline(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, Node* ownerNode, const TextPosition& startPosition)
{
- CSSParserContext parserContext(ownerNode->document(), baseURL, encoding);
- RefPtr<StyleSheetContents> sheet = StyleSheetContents::create(baseURL.string(), parserContext);
- return adoptRef(new CSSStyleSheet(sheet.release(), ownerNode, true, startPosition));
+ ASSERT(sheet);
+ return adoptRefWillBeNoop(new CSSStyleSheet(sheet, ownerNode, true, startPosition));
}
-CSSStyleSheet::CSSStyleSheet(PassRefPtr<StyleSheetContents> contents, CSSImportRule* ownerRule)
+PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const TextPosition& startPosition, const String& encoding)
+{
+ CSSParserContext parserContext(ownerNode->document(), 0, baseURL, encoding);
+ RefPtrWillBeRawPtr<StyleSheetContents> sheet = StyleSheetContents::create(baseURL.string(), parserContext);
+ return adoptRefWillBeNoop(new CSSStyleSheet(sheet.release(), ownerNode, true, startPosition));
+}
+
+CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents, CSSImportRule* ownerRule)
: m_contents(contents)
, m_isInlineStylesheet(false)
, m_isDisabled(false)
- , m_ownerNode(0)
+ , m_ownerNode(nullptr)
, m_ownerRule(ownerRule)
, m_startPosition(TextPosition::minimumPosition())
+ , m_loadCompleted(false)
{
m_contents->registerClient(this);
}
-CSSStyleSheet::CSSStyleSheet(PassRefPtr<StyleSheetContents> contents, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition)
+CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition)
: m_contents(contents)
, m_isInlineStylesheet(isInlineStylesheet)
, m_isDisabled(false)
, m_ownerNode(ownerNode)
- , m_ownerRule(0)
+ , m_ownerRule(nullptr)
, m_startPosition(startPosition)
+ , m_loadCompleted(false)
{
ASSERT(isAcceptableCSSStyleSheetParent(ownerNode));
m_contents->registerClient(this);
@@ -113,6 +141,11 @@ CSSStyleSheet::CSSStyleSheet(PassRefPtr<StyleSheetContents> contents, Node* owne
CSSStyleSheet::~CSSStyleSheet()
{
+ // With oilpan the parent style sheet pointer is strong and the sheet and
+ // its RuleCSSOMWrappers die together and we don't need to clear them here.
+ // Also with oilpan the StyleSheetContents client pointers are weak and
+ // therefore do not need to be cleared here.
+#if !ENABLE(OILPAN)
// For style rules outside the document, .parentStyleSheet can become null even if the style rule
// is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but
// it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection.
@@ -121,53 +154,28 @@ CSSStyleSheet::~CSSStyleSheet()
m_childRuleCSSOMWrappers[i]->setParentStyleSheet(0);
}
- for (unsigned i = 0; i < m_extraChildRuleCSSOMWrappers.size(); ++i)
- m_extraChildRuleCSSOMWrappers[i]->setParentStyleSheet(0);
-
if (m_mediaCSSOMWrapper)
m_mediaCSSOMWrapper->clearParentStyleSheet();
m_contents->unregisterClient(this);
-}
-
-void CSSStyleSheet::extraCSSOMWrapperIndices(Vector<unsigned>& indices)
-{
- indices.grow(m_extraChildRuleCSSOMWrappers.size());
-
- for (unsigned i = 0; i < m_extraChildRuleCSSOMWrappers.size(); ++i) {
- CSSRule* cssRule = m_extraChildRuleCSSOMWrappers[i].get();
- ASSERT(cssRule->type() == CSSRule::STYLE_RULE);
- StyleRule* styleRule = toCSSStyleRule(cssRule)->styleRule();
-
- bool didFindIndex = false;
- for (unsigned j = 0; j < m_contents->ruleCount(); ++j) {
- if (m_contents->ruleAt(j) == styleRule) {
- didFindIndex = true;
- indices[i] = j;
- break;
- }
- }
- ASSERT(didFindIndex);
- if (!didFindIndex)
- indices[i] = 0;
- }
+#endif
}
void CSSStyleSheet::willMutateRules()
{
InspectorInstrumentation::willMutateRules(this);
+
// If we are the only client it is safe to mutate.
- if (m_contents->hasOneClient() && !m_contents->isInMemoryCache()) {
+ if (m_contents->clientSize() <= 1 && !m_contents->isInMemoryCache()) {
m_contents->clearRuleSet();
+ if (Document* document = ownerDocument())
+ m_contents->removeSheetFromCache(document);
m_contents->setMutable();
return;
}
// Only cacheable stylesheets should have multiple clients.
ASSERT(m_contents->isCacheable());
- Vector<unsigned> indices;
- extraCSSOMWrapperIndices(indices);
-
// Copy-on-write.
m_contents->unregisterClient(this);
m_contents = m_contents->copy();
@@ -176,13 +184,13 @@ void CSSStyleSheet::willMutateRules()
m_contents->setMutable();
// Any existing CSSOM wrappers need to be connected to the copied child rules.
- reattachChildRuleCSSOMWrappers(indices);
+ reattachChildRuleCSSOMWrappers();
}
void CSSStyleSheet::didMutateRules()
{
ASSERT(m_contents->isMutable());
- ASSERT(m_contents->hasOneClient());
+ ASSERT(m_contents->clientSize() <= 1);
InspectorInstrumentation::didMutateRules(this);
didMutate(PartialRuleUpdate);
@@ -197,20 +205,11 @@ void CSSStyleSheet::didMutate(StyleSheetUpdateType updateType)
// Need FullStyleUpdate when insertRule or deleteRule,
// because StyleSheetCollection::analyzeStyleSheetChange cannot detect partial rule update.
StyleResolverUpdateMode updateMode = updateType != PartialRuleUpdate ? AnalyzedStyleUpdate : FullStyleUpdate;
- owner->modifiedStyleSheet(this, RecalcStyleDeferred, updateMode);
-}
-
-void CSSStyleSheet::registerExtraChildRuleCSSOMWrapper(PassRefPtr<CSSRule> rule)
-{
- m_extraChildRuleCSSOMWrappers.append(rule);
+ owner->modifiedStyleSheet(this, updateMode);
}
-void CSSStyleSheet::reattachChildRuleCSSOMWrappers(const Vector<unsigned>& extraCSSOMWrapperIndices)
+void CSSStyleSheet::reattachChildRuleCSSOMWrappers()
{
- ASSERT(extraCSSOMWrapperIndices.size() == m_extraChildRuleCSSOMWrappers.size());
- for (unsigned i = 0; i < extraCSSOMWrapperIndices.size(); ++i)
- m_extraChildRuleCSSOMWrappers[i]->reattach(m_contents->ruleAt(extraCSSOMWrapperIndices[i]));
-
for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
if (!m_childRuleCSSOMWrappers[i])
continue;
@@ -227,7 +226,7 @@ void CSSStyleSheet::setDisabled(bool disabled)
didMutate();
}
-void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries)
+void CSSStyleSheet::setMediaQueries(PassRefPtrWillBeRawPtr<MediaQuerySet> mediaQueries)
{
m_mediaQueries = mediaQueries;
if (m_mediaCSSOMWrapper && m_mediaQueries)
@@ -252,7 +251,7 @@ CSSRule* CSSStyleSheet::item(unsigned index)
m_childRuleCSSOMWrappers.grow(ruleCount);
ASSERT(m_childRuleCSSOMWrappers.size() == ruleCount);
- RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index];
+ RefPtrWillBeMember<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index];
if (!cssRule) {
if (index == 0 && m_contents->hasCharsetRule()) {
ASSERT(!m_contents->ruleAt(0));
@@ -263,6 +262,14 @@ CSSRule* CSSStyleSheet::item(unsigned index)
return cssRule.get();
}
+void CSSStyleSheet::clearOwnerNode()
+{
+ didMutate(EntireStyleSheetUpdate);
+ if (m_ownerNode)
+ m_contents->unregisterClient(this);
+ m_ownerNode = nullptr;
+}
+
bool CSSStyleSheet::canAccessRules() const
{
if (m_isInlineStylesheet)
@@ -278,12 +285,12 @@ bool CSSStyleSheet::canAccessRules() const
return false;
}
-PassRefPtr<CSSRuleList> CSSStyleSheet::rules()
+PassRefPtrWillBeRawPtr<CSSRuleList> CSSStyleSheet::rules()
{
if (!canAccessRules())
- return 0;
+ return nullptr;
// IE behavior.
- RefPtr<StaticCSSRuleList> nonCharsetRules = StaticCSSRuleList::create();
+ RefPtrWillBeRawPtr<StaticCSSRuleList> nonCharsetRules(StaticCSSRuleList::create());
unsigned ruleCount = length();
for (unsigned i = 0; i < ruleCount; ++i) {
CSSRule* rule = item(i);
@@ -299,32 +306,33 @@ unsigned CSSStyleSheet::insertRule(const String& ruleString, unsigned index, Exc
ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_contents->ruleCount());
if (index > length()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is larger than the maximum index (" + String::number(length()) + ").");
return 0;
}
- CSSParser p(m_contents->parserContext(), UseCounter::getFrom(this));
- RefPtr<StyleRuleBase> rule = p.parseRule(m_contents.get(), ruleString);
+ CSSParserContext context(m_contents->parserContext(), UseCounter::getFrom(this));
+ BisonCSSParser p(context);
+ RefPtrWillBeRawPtr<StyleRuleBase> rule = p.parseRule(m_contents.get(), ruleString);
if (!rule) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "Failed to parse the rule '" + ruleString + "'.");
return 0;
}
RuleMutationScope mutationScope(this);
bool success = m_contents->wrapperInsertRule(rule, index);
if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "Failed to insert the rule.");
return 0;
}
if (!m_childRuleCSSOMWrappers.isEmpty())
- m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
+ m_childRuleCSSOMWrappers.insert(index, RefPtrWillBeMember<CSSRule>(nullptr));
return index;
}
unsigned CSSStyleSheet::insertRule(const String& rule, ExceptionState& exceptionState)
{
- UseCounter::countDeprecation(activeExecutionContext(), UseCounter::CSSStyleSheetInsertRuleOptionalArg);
+ UseCounter::countDeprecation(callingExecutionContext(V8PerIsolateData::mainThreadIsolate()), UseCounter::CSSStyleSheetInsertRuleOptionalArg);
return insertRule(rule, 0, exceptionState);
}
@@ -333,7 +341,7 @@ void CSSStyleSheet::deleteRule(unsigned index, ExceptionState& exceptionState)
ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_contents->ruleCount());
if (index >= length()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is larger than the maximum index (" + String::number(length() - 1) + ").");
return;
}
RuleMutationScope mutationScope(this);
@@ -368,12 +376,12 @@ int CSSStyleSheet::addRule(const String& selector, const String& style, Exceptio
}
-PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules()
+PassRefPtrWillBeRawPtr<CSSRuleList> CSSStyleSheet::cssRules()
{
if (!canAccessRules())
- return 0;
+ return nullptr;
if (!m_ruleListCSSOMWrapper)
- m_ruleListCSSOMWrapper = adoptPtr(new StyleSheetCSSRuleList(this));
+ m_ruleListCSSOMWrapper = StyleSheetCSSRuleList::create(this);
return m_ruleListCSSOMWrapper.get();
}
@@ -420,4 +428,42 @@ void CSSStyleSheet::clearChildRuleCSSOMWrappers()
m_childRuleCSSOMWrappers.clear();
}
+bool CSSStyleSheet::sheetLoaded()
+{
+ ASSERT(m_ownerNode);
+ setLoadCompleted(m_ownerNode->sheetLoaded());
+ return m_loadCompleted;
+}
+
+void CSSStyleSheet::startLoadingDynamicSheet()
+{
+ setLoadCompleted(false);
+ m_ownerNode->startLoadingDynamicSheet();
+}
+
+void CSSStyleSheet::setLoadCompleted(bool completed)
+{
+ if (completed == m_loadCompleted)
+ return;
+
+ m_loadCompleted = completed;
+
+ if (completed)
+ m_contents->clientLoadCompleted(this);
+ else
+ m_contents->clientLoadStarted(this);
+}
+
+void CSSStyleSheet::trace(Visitor* visitor)
+{
+ visitor->trace(m_contents);
+ visitor->trace(m_mediaQueries);
+ visitor->trace(m_ownerNode);
+ visitor->trace(m_ownerRule);
+ visitor->trace(m_mediaCSSOMWrapper);
+ visitor->trace(m_childRuleCSSOMWrappers);
+ visitor->trace(m_ruleListCSSOMWrapper);
+ StyleSheet::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.h b/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.h
index 3c02c230c9f..18d68d5716c 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.h
@@ -23,6 +23,7 @@
#include "core/css/CSSRule.h"
#include "core/css/StyleSheet.h"
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
#include "wtf/text/TextPosition.h"
@@ -30,7 +31,7 @@ namespace WebCore {
class CSSCharsetRule;
class CSSImportRule;
-class CSSParser;
+class BisonCSSParser;
class CSSRule;
class CSSRuleList;
class CSSStyleSheet;
@@ -46,11 +47,12 @@ enum StyleSheetUpdateType {
EntireStyleSheetUpdate
};
-class CSSStyleSheet : public StyleSheet {
+class CSSStyleSheet FINAL : public StyleSheet {
public:
- static PassRefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetContents>, CSSImportRule* ownerRule = 0);
- static PassRefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetContents>, Node* ownerNode);
- static PassRefPtr<CSSStyleSheet> createInline(Node*, const KURL&, const TextPosition& startPosition = TextPosition::minimumPosition(), const String& encoding = String());
+ static PassRefPtrWillBeRawPtr<CSSStyleSheet> create(PassRefPtrWillBeRawPtr<StyleSheetContents>, CSSImportRule* ownerRule = 0);
+ static PassRefPtrWillBeRawPtr<CSSStyleSheet> create(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode);
+ static PassRefPtrWillBeRawPtr<CSSStyleSheet> createInline(Node*, const KURL&, const TextPosition& startPosition = TextPosition::minimumPosition(), const String& encoding = String());
+ static PassRefPtrWillBeRawPtr<CSSStyleSheet> createInline(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode, const TextPosition& startPosition = TextPosition::minimumPosition());
virtual ~CSSStyleSheet();
@@ -62,13 +64,13 @@ public:
virtual bool disabled() const OVERRIDE { return m_isDisabled; }
virtual void setDisabled(bool) OVERRIDE;
- PassRefPtr<CSSRuleList> cssRules();
+ PassRefPtrWillBeRawPtr<CSSRuleList> cssRules();
unsigned insertRule(const String& rule, unsigned index, ExceptionState&);
unsigned insertRule(const String& rule, ExceptionState&); // Deprecated.
void deleteRule(unsigned index, ExceptionState&);
// IE Extensions
- PassRefPtr<CSSRuleList> rules();
+ PassRefPtrWillBeRawPtr<CSSRuleList> rules();
int addRule(const String& selector, const String& style, int index, ExceptionState&);
int addRule(const String& selector, const String& style, ExceptionState&);
void removeRule(unsigned index, ExceptionState& exceptionState) { deleteRule(index, exceptionState); }
@@ -77,26 +79,28 @@ public:
unsigned length() const;
CSSRule* item(unsigned index);
- virtual void clearOwnerNode() OVERRIDE { didMutate(EntireStyleSheetUpdate); m_ownerNode = 0; }
+ virtual void clearOwnerNode() OVERRIDE;
+
virtual CSSRule* ownerRule() const OVERRIDE { return m_ownerRule; }
virtual KURL baseURL() const OVERRIDE;
virtual bool isLoading() const OVERRIDE;
- void clearOwnerRule() { m_ownerRule = 0; }
+ void clearOwnerRule() { m_ownerRule = nullptr; }
Document* ownerDocument() const;
MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
- void setMediaQueries(PassRefPtr<MediaQuerySet>);
+ void setMediaQueries(PassRefPtrWillBeRawPtr<MediaQuerySet>);
void setTitle(const String& title) { m_title = title; }
class RuleMutationScope {
WTF_MAKE_NONCOPYABLE(RuleMutationScope);
+ STACK_ALLOCATED();
public:
- RuleMutationScope(CSSStyleSheet*);
- RuleMutationScope(CSSRule*);
+ explicit RuleMutationScope(CSSStyleSheet*);
+ explicit RuleMutationScope(CSSRule*);
~RuleMutationScope();
private:
- CSSStyleSheet* m_styleSheet;
+ RawPtrWillBeMember<CSSStyleSheet> m_styleSheet;
};
void willMutateRules();
@@ -105,42 +109,44 @@ public:
void clearChildRuleCSSOMWrappers();
- void registerExtraChildRuleCSSOMWrapper(PassRefPtr<CSSRule>);
-
StyleSheetContents* contents() const { return m_contents.get(); }
bool isInline() const { return m_isInlineStylesheet; }
TextPosition startPositionInSource() const { return m_startPosition; }
+ bool sheetLoaded();
+ bool loadCompleted() const { return m_loadCompleted; }
+ void startLoadingDynamicSheet();
+
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- CSSStyleSheet(PassRefPtr<StyleSheetContents>, CSSImportRule* ownerRule);
- CSSStyleSheet(PassRefPtr<StyleSheetContents>, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition);
+ CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>, CSSImportRule* ownerRule);
+ CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition);
- virtual bool isCSSStyleSheet() const { return true; }
- virtual String type() const { return "text/css"; }
+ virtual bool isCSSStyleSheet() const OVERRIDE { return true; }
+ virtual String type() const OVERRIDE { return "text/css"; }
- void extraCSSOMWrapperIndices(Vector<unsigned>& indices);
- void reattachChildRuleCSSOMWrappers(const Vector<unsigned>& extraCSSOMWrapperIndices);
+ void reattachChildRuleCSSOMWrappers();
bool canAccessRules() const;
- RefPtr<StyleSheetContents> m_contents;
+ void setLoadCompleted(bool);
+
+ RefPtrWillBeMember<StyleSheetContents> m_contents;
bool m_isInlineStylesheet;
bool m_isDisabled;
String m_title;
- RefPtr<MediaQuerySet> m_mediaQueries;
+ RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
- Node* m_ownerNode;
- CSSRule* m_ownerRule;
+ RawPtrWillBeMember<Node> m_ownerNode;
+ RawPtrWillBeMember<CSSRule> m_ownerRule;
TextPosition m_startPosition;
-
- mutable RefPtr<MediaList> m_mediaCSSOMWrapper;
- mutable Vector<RefPtr<CSSRule> > m_childRuleCSSOMWrappers;
- // These are CSSOMWrappers that come from getMatchedCSSRules and thus don't map 1-1 to
- // the StyleRules in the StyleSheetContents.
- mutable Vector<RefPtr<CSSRule> > m_extraChildRuleCSSOMWrappers;
- mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
+ bool m_loadCompleted;
+ mutable RefPtrWillBeMember<MediaList> m_mediaCSSOMWrapper;
+ mutable WillBeHeapVector<RefPtrWillBeMember<CSSRule> > m_childRuleCSSOMWrappers;
+ mutable OwnPtrWillBeMember<CSSRuleList> m_ruleListCSSOMWrapper;
};
inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSStyleSheet* sheet)
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.idl b/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.idl
index a9b09007967..71619f33e45 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.idl
+++ b/chromium/third_party/WebKit/Source/core/css/CSSStyleSheet.idl
@@ -20,7 +20,7 @@
// Introduced in DOM Level 2:
[
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
] interface CSSStyleSheet : StyleSheet {
readonly attribute CSSRule ownerRule;
readonly attribute CSSRuleList cssRules;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSSupportsRule.h b/chromium/third_party/WebKit/Source/core/css/CSSSupportsRule.h
index 4d15dd2523f..75f467553cd 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSSupportsRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSSupportsRule.h
@@ -36,11 +36,11 @@ namespace WebCore {
class CSSRule;
class StyleRuleSupports;
-class CSSSupportsRule : public CSSGroupingRule {
+class CSSSupportsRule FINAL : public CSSGroupingRule {
public:
- static PassRefPtr<CSSSupportsRule> create(StyleRuleSupports* rule, CSSStyleSheet* sheet)
+ static PassRefPtrWillBeRawPtr<CSSSupportsRule> create(StyleRuleSupports* rule, CSSStyleSheet* sheet)
{
- return adoptRef(new CSSSupportsRule(rule, sheet));
+ return adoptRefWillBeNoop(new CSSSupportsRule(rule, sheet));
}
virtual ~CSSSupportsRule() { }
@@ -50,6 +50,8 @@ public:
String conditionText() const;
+ virtual void trace(Visitor* visitor) OVERRIDE { CSSGroupingRule::trace(visitor); }
+
private:
CSSSupportsRule(StyleRuleSupports*, CSSStyleSheet*);
};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSTestHelper.cpp b/chromium/third_party/WebKit/Source/core/css/CSSTestHelper.cpp
new file mode 100644
index 00000000000..4edca948153
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSTestHelper.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/css/CSSTestHelper.h"
+
+#include "core/css/CSSRuleList.h"
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/RuleSet.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/dom/Document.h"
+#include "wtf/text/WTFString.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+CSSTestHelper::~CSSTestHelper()
+{
+}
+
+CSSTestHelper::CSSTestHelper()
+{
+ m_document = Document::create();
+ TextPosition position;
+ m_styleSheet = CSSStyleSheet::createInline(m_document.get(), KURL(), position, "UTF-8");
+}
+
+RuleSet& CSSTestHelper::ruleSet()
+{
+ RuleSet& ruleSet = m_styleSheet->contents()->ensureRuleSet(MediaQueryEvaluator(), RuleHasNoSpecialState);
+ ruleSet.compactRulesIfNeeded();
+ return ruleSet;
+}
+
+void CSSTestHelper::addCSSRules(const char* cssText)
+{
+ TextPosition position;
+ unsigned sheetLength = m_styleSheet->length();
+ ASSERT_TRUE(m_styleSheet->contents()->parseStringAtPosition(cssText, position, true));
+ ASSERT_TRUE(m_styleSheet->length() > sheetLength);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSTestHelper.h b/chromium/third_party/WebKit/Source/core/css/CSSTestHelper.h
new file mode 100644
index 00000000000..f217b77afbf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/CSSTestHelper.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSTestHelper_h
+#define CSSTestHelper_h
+
+#include "core/css/RuleSet.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class Document;
+class CSSStyleSheet;
+
+// A helper class for writing tests of CSS rules. Example usage:
+//
+// CSSTestHelper helper;
+// helper.addCSSRule("body { color: red} #a { position: absolute }");
+// RuleSet& ruleSet = helper.ruleSet();
+// ... examine RuleSet to find the rule and test properties on it.
+
+class CSSTestHelper {
+public:
+ CSSTestHelper();
+ ~CSSTestHelper();
+
+ void addCSSRules(const char* ruleText);
+ RuleSet& ruleSet();
+
+private:
+ RefPtrWillBePersistent<Document> m_document;
+ RefPtrWillBePersistent<CSSStyleSheet> m_styleSheet;
+};
+
+} // namespace WebCore
+
+#endif // CSSTestHelper_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp
index 49420cbb26b..b8eee452aca 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.cpp
@@ -46,12 +46,28 @@ bool CSSCubicBezierTimingFunctionValue::equals(const CSSCubicBezierTimingFunctio
String CSSStepsTimingFunctionValue::customCSSText() const
{
- return "steps(" + String::number(m_steps) + ", " + (m_stepAtStart ? "start" : "end") + ')';
+ String stepAtPositionString;
+ switch (m_stepAtPosition) {
+ case StepsTimingFunction::StepAtStart:
+ stepAtPositionString = "start";
+ break;
+ case StepsTimingFunction::StepAtMiddle:
+ stepAtPositionString = "middle";
+ break;
+ case StepsTimingFunction::StepAtEnd:
+ stepAtPositionString = "end";
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ stepAtPositionString = "end";
+ break;
+ }
+ return "steps(" + String::number(m_steps) + ", " + stepAtPositionString + ')';
}
bool CSSStepsTimingFunctionValue::equals(const CSSStepsTimingFunctionValue& other) const
{
- return m_steps == other.m_steps && m_stepAtStart == other.m_stepAtStart;
+ return m_steps == other.m_steps && m_stepAtPosition == other.m_stepAtPosition;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h b/chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h
index 54f566171c2..f0daa301a3e 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSTimingFunctionValue.h
@@ -27,15 +27,16 @@
#define CSSTimingFunctionValue_h
#include "core/css/CSSValue.h"
+#include "platform/animation/TimingFunction.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
class CSSCubicBezierTimingFunctionValue : public CSSValue {
public:
- static PassRefPtr<CSSCubicBezierTimingFunctionValue> create(double x1, double y1, double x2, double y2)
+ static PassRefPtrWillBeRawPtr<CSSCubicBezierTimingFunctionValue> create(double x1, double y1, double x2, double y2)
{
- return adoptRef(new CSSCubicBezierTimingFunctionValue(x1, y1, x2, y2));
+ return adoptRefWillBeNoop(new CSSCubicBezierTimingFunctionValue(x1, y1, x2, y2));
}
String customCSSText() const;
@@ -47,6 +48,8 @@ public:
bool equals(const CSSCubicBezierTimingFunctionValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
CSSCubicBezierTimingFunctionValue(double x1, double y1, double x2, double y2)
: CSSValue(CubicBezierTimingFunctionClass)
@@ -67,28 +70,30 @@ DEFINE_CSS_VALUE_TYPE_CASTS(CSSCubicBezierTimingFunctionValue, isCubicBezierTimi
class CSSStepsTimingFunctionValue : public CSSValue {
public:
- static PassRefPtr<CSSStepsTimingFunctionValue> create(int steps, bool stepAtStart)
+ static PassRefPtrWillBeRawPtr<CSSStepsTimingFunctionValue> create(int steps, StepsTimingFunction::StepAtPosition stepAtPosition)
{
- return adoptRef(new CSSStepsTimingFunctionValue(steps, stepAtStart));
+ return adoptRefWillBeNoop(new CSSStepsTimingFunctionValue(steps, stepAtPosition));
}
int numberOfSteps() const { return m_steps; }
- bool stepAtStart() const { return m_stepAtStart; }
+ StepsTimingFunction::StepAtPosition stepAtPosition() const { return m_stepAtPosition; }
String customCSSText() const;
bool equals(const CSSStepsTimingFunctionValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
- CSSStepsTimingFunctionValue(int steps, bool stepAtStart)
+ CSSStepsTimingFunctionValue(int steps, StepsTimingFunction::StepAtPosition stepAtPosition)
: CSSValue(StepsTimingFunctionClass)
, m_steps(steps)
- , m_stepAtStart(stepAtStart)
+ , m_stepAtPosition(stepAtPosition)
{
}
int m_steps;
- bool m_stepAtStart;
+ StepsTimingFunction::StepAtPosition m_stepAtPosition;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSStepsTimingFunctionValue, isStepsTimingFunctionValue());
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp b/chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
index 6085a69892b..66583963904 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.cpp
@@ -31,10 +31,45 @@
#include "config.h"
#include "core/css/CSSToLengthConversionData.h"
+#include "core/rendering/RenderView.h"
#include "core/rendering/style/RenderStyle.h"
namespace WebCore {
+CSSToLengthConversionData::CSSToLengthConversionData(const RenderStyle* style, const RenderStyle* rootStyle, const RenderView* renderView, float zoom, bool computingFontSize)
+ : m_style(style)
+ , m_rootStyle(rootStyle)
+ , m_viewportWidth(renderView ? renderView->layoutViewportWidth() : 0)
+ , m_viewportHeight(renderView ? renderView->layoutViewportHeight() : 0)
+ , m_zoom(zoom)
+ , m_useEffectiveZoom(false)
+ , m_computingFontSize(computingFontSize)
+{
+ ASSERT(zoom > 0);
+}
+
+CSSToLengthConversionData::CSSToLengthConversionData(const RenderStyle* style, const RenderStyle* rootStyle, const RenderView* renderView, bool computingFontSize)
+ : m_style(style)
+ , m_rootStyle(rootStyle)
+ , m_viewportWidth(renderView ? renderView->layoutViewportWidth() : 0)
+ , m_viewportHeight(renderView ? renderView->layoutViewportHeight() : 0)
+ , m_useEffectiveZoom(true)
+ , m_computingFontSize(computingFontSize)
+{
+}
+
+CSSToLengthConversionData::CSSToLengthConversionData(const RenderStyle* style, const RenderStyle* rootStyle, float viewportWidth, float viewportHeight, float zoom, bool computingFontSize)
+ : m_style(style)
+ , m_rootStyle(rootStyle)
+ , m_viewportWidth(viewportWidth)
+ , m_viewportHeight(viewportHeight)
+ , m_zoom(zoom)
+ , m_useEffectiveZoom(false)
+ , m_computingFontSize(computingFontSize)
+{
+ ASSERT(zoom > 0);
+}
+
float CSSToLengthConversionData::zoom() const
{
if (m_useEffectiveZoom)
@@ -42,4 +77,25 @@ float CSSToLengthConversionData::zoom() const
return m_zoom;
}
+double CSSToLengthConversionData::viewportWidthPercent() const
+{
+ m_style->setHasViewportUnits();
+ return m_viewportWidth / 100;
+}
+double CSSToLengthConversionData::viewportHeightPercent() const
+{
+ m_style->setHasViewportUnits();
+ return m_viewportHeight / 100;
+}
+double CSSToLengthConversionData::viewportMinPercent() const
+{
+ m_style->setHasViewportUnits();
+ return std::min(m_viewportWidth, m_viewportHeight) / 100;
+}
+double CSSToLengthConversionData::viewportMaxPercent() const
+{
+ m_style->setHasViewportUnits();
+ return std::max(m_viewportWidth, m_viewportHeight) / 100;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h b/chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h
index 975be5f2122..6b81ce993b9 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSToLengthConversionData.h
@@ -37,41 +37,38 @@
namespace WebCore {
class RenderStyle;
+class RenderView;
class CSSToLengthConversionData {
public:
- CSSToLengthConversionData(const RenderStyle* style, const RenderStyle* rootStyle, float zoom, bool computingFontSize = false)
- : m_style(style)
- , m_rootStyle(rootStyle)
- , m_zoom(zoom)
- , m_useEffectiveZoom(false)
- , m_computingFontSize(computingFontSize)
- {
- ASSERT(zoom > 0);
- }
- CSSToLengthConversionData(const RenderStyle* style, const RenderStyle* rootStyle, bool computingFontSize = false)
- : m_style(style)
- , m_rootStyle(rootStyle)
- , m_useEffectiveZoom(true)
- , m_computingFontSize(computingFontSize)
- {
- }
+ CSSToLengthConversionData(const RenderStyle* currStyle, const RenderStyle* rootStyle, const RenderView*, float zoom, bool computingFontSize = false);
+ CSSToLengthConversionData(const RenderStyle* currStyle, const RenderStyle* rootStyle, const RenderView*, bool computingFontSize = false);
+ CSSToLengthConversionData(const RenderStyle* currStyle, const RenderStyle* rootStyle, float viewportWidth, float viewportHeight, float zoom, bool computingFontSize = false);
+
const RenderStyle& style() const { return *m_style; }
- const RenderStyle& rootStyle() const { return *m_rootStyle; }
+ const RenderStyle* rootStyle() const { return m_rootStyle; }
float zoom() const;
bool computingFontSize() const { return m_computingFontSize; }
+ // Accessing these marks the style as having viewport units
+ double viewportWidthPercent() const;
+ double viewportHeightPercent() const;
+ double viewportMinPercent() const;
+ double viewportMaxPercent() const;
+
void setStyle(const RenderStyle* style) { m_style = style; }
void setRootStyle(const RenderStyle* rootStyle) { m_rootStyle = rootStyle; }
CSSToLengthConversionData copyWithAdjustedZoom(float newZoom) const
{
- return CSSToLengthConversionData(m_style, m_rootStyle, newZoom, m_computingFontSize);
+ return CSSToLengthConversionData(m_style, m_rootStyle, m_viewportWidth, m_viewportHeight, newZoom, m_computingFontSize);
}
private:
const RenderStyle* m_style;
const RenderStyle* m_rootStyle;
+ float m_viewportWidth;
+ float m_viewportHeight;
float m_zoom;
bool m_useEffectiveZoom;
bool m_computingFontSize;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSTokenizer-in.cpp b/chromium/third_party/WebKit/Source/core/css/CSSTokenizer-in.cpp
index 5ee194a188c..3b8aef115ae 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSTokenizer-in.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSTokenizer-in.cpp
@@ -28,7 +28,7 @@
#include "core/css/CSSTokenizer.h"
#include "core/css/CSSKeyframeRule.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSParserValues.h"
#include "core/css/MediaQuery.h"
#include "core/css/StyleRule.h"
@@ -37,7 +37,7 @@
namespace WebCore {
-#include "CSSGrammar.h"
+#include "core/CSSGrammar.h"
enum CharacterType {
// Types for the main switch.
@@ -304,14 +304,17 @@ inline UChar*& CSSTokenizer::currentCharacter<UChar>()
return m_currentCharacter16;
}
-UChar*& CSSTokenizer::currentCharacter16()
+UChar* CSSTokenizer::allocateStringBuffer16(size_t len)
{
- if (!m_currentCharacter16) {
- m_dataStart16 = adoptArrayPtr(new UChar[m_length]);
- m_currentCharacter16 = m_dataStart16.get();
- }
+ // Allocates and returns a CSSTokenizer owned buffer for storing
+ // UTF-16 data. Used to get a suitable life span for UTF-16
+ // strings, identifiers and URIs created by the tokenizer.
+ OwnPtr<UChar[]> buffer = adoptArrayPtr(new UChar[len]);
- return m_currentCharacter16;
+ UChar* bufferPtr = buffer.get();
+
+ m_cssStrings16.append(buffer.release());
+ return bufferPtr;
}
template <>
@@ -350,13 +353,17 @@ inline bool CSSTokenizer::isIdentifierStart()
return isIdentifierStartAfterDash((*currentCharacter<CharacterType>() != '-') ? currentCharacter<CharacterType>() : currentCharacter<CharacterType>() + 1);
}
+enum CheckStringValidationMode {
+ AbortIfInvalid,
+ SkipInvalid
+};
+
template <typename CharacterType>
-static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote)
+static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter, int quote, CheckStringValidationMode mode)
{
- // Returns with 0, if string check is failed. Otherwise
- // it returns with the following character. This is necessary
- // since we cannot revert escape sequences, thus strings
- // must be validated before parsing.
+ // If mode is AbortIfInvalid and the string check fails it returns
+ // with 0. Otherwise it returns with a pointer to the first
+ // character after the string.
while (true) {
if (UNLIKELY(*currentCharacter == quote)) {
// String parsing is successful.
@@ -366,7 +373,7 @@ static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter,
// String parsing is successful up to end of input.
return currentCharacter;
}
- if (UNLIKELY(*currentCharacter <= '\r' && (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) {
+ if (mode == AbortIfInvalid && UNLIKELY(*currentCharacter <= '\r' && (*currentCharacter == '\n' || (*currentCharacter | 0x1) == '\r'))) {
// String parsing is failed for character '\n', '\f' or '\r'.
return 0;
}
@@ -378,9 +385,13 @@ static inline CharacterType* checkAndSkipString(CharacterType* currentCharacter,
} else if (currentCharacter[1] == '\r') {
currentCharacter += currentCharacter[2] == '\n' ? 3 : 2;
} else {
- currentCharacter = checkAndSkipEscape(currentCharacter);
- if (!currentCharacter)
- return 0;
+ CharacterType* next = checkAndSkipEscape(currentCharacter);
+ if (!next) {
+ if (mode == AbortIfInvalid)
+ return 0;
+ next = currentCharacter + 1;
+ }
+ currentCharacter = next;
}
}
}
@@ -412,7 +423,7 @@ unsigned CSSTokenizer::parseEscape(CharacterType*& src)
return unicode;
}
- return *currentCharacter<CharacterType>()++;
+ return *src++;
}
template <>
@@ -438,6 +449,24 @@ inline void CSSTokenizer::UnicodeToChars<UChar>(UChar*& result, unsigned unicode
++result;
}
+template <typename SrcCharacterType>
+size_t CSSTokenizer::peekMaxIdentifierLen(SrcCharacterType* src)
+{
+ // The decoded form of an identifier (after resolving escape
+ // sequences) will not contain more characters (ASCII or UTF-16
+ // codepoints) than the input. This code can therefore ignore
+ // escape sequences completely.
+ SrcCharacterType* start = src;
+ do {
+ if (LIKELY(*src != '\\'))
+ src++;
+ else
+ parseEscape<SrcCharacterType>(src);
+ } while (isCSSLetter(src[0]) || (src[0] == '\\' && isCSSEscape(src[1])));
+
+ return src - start;
+}
+
template <typename SrcCharacterType, typename DestCharacterType>
inline bool CSSTokenizer::parseIdentifierInternal(SrcCharacterType*& src, DestCharacterType*& result, bool& hasEscape)
{
@@ -471,7 +500,7 @@ inline void CSSTokenizer::parseIdentifier(CharacterType*& result, CSSParserStrin
if (UNLIKELY(!parseIdentifierInternal(currentCharacter<CharacterType>(), result, hasEscape))) {
// Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
ASSERT(is8BitSource());
- UChar*& result16 = currentCharacter16();
+ UChar* result16 = allocateStringBuffer16((result - start) + peekMaxIdentifierLen(currentCharacter<CharacterType>()));
UChar* start16 = result16;
int i = 0;
for (; i < result - start; i++)
@@ -489,6 +518,18 @@ inline void CSSTokenizer::parseIdentifier(CharacterType*& result, CSSParserStrin
resultString.init(start, result - start);
}
+template <typename SrcCharacterType>
+size_t CSSTokenizer::peekMaxStringLen(SrcCharacterType* src, UChar quote)
+{
+ // The decoded form of a CSS string (after resolving escape
+ // sequences) will not contain more characters (ASCII or UTF-16
+ // codepoints) than the input. This code can therefore ignore
+ // escape sequences completely and just return the length of the
+ // input string (possibly including terminating quote if any).
+ SrcCharacterType* end = checkAndSkipString(src, quote, SkipInvalid);
+ return end ? end - src : 0;
+}
+
template <typename SrcCharacterType, typename DestCharacterType>
inline bool CSSTokenizer::parseStringInternal(SrcCharacterType*& src, DestCharacterType*& result, UChar quote)
{
@@ -502,8 +543,6 @@ inline bool CSSTokenizer::parseStringInternal(SrcCharacterType*& src, DestCharac
// String parsing is done, but don't advance pointer if at the end of input.
return true;
}
- ASSERT(*src > '\r' || (*src < '\n' && *src) || *src == '\v');
-
if (LIKELY(src[0] != '\\')) {
*result++ = *src++;
} else if (src[1] == '\n' || src[1] == '\f') {
@@ -532,7 +571,7 @@ inline void CSSTokenizer::parseString(CharacterType*& result, CSSParserString& r
if (UNLIKELY(!parseStringInternal(currentCharacter<CharacterType>(), result, quote))) {
// Found an escape we couldn't handle with 8 bits, copy what has been recognized and continue
ASSERT(is8BitSource());
- UChar*& result16 = currentCharacter16();
+ UChar* result16 = allocateStringBuffer16((result - start) + peekMaxStringLen(currentCharacter<CharacterType>(), quote));
UChar* start16 = result16;
int i = 0;
for (; i < result - start; i++)
@@ -556,7 +595,7 @@ inline bool CSSTokenizer::findURI(CharacterType*& start, CharacterType*& end, UC
if (*start == '"' || *start == '\'') {
quote = *start++;
- end = checkAndSkipString(start, quote);
+ end = checkAndSkipString(start, quote, AbortIfInvalid);
if (!end)
return false;
} else {
@@ -580,6 +619,29 @@ inline bool CSSTokenizer::findURI(CharacterType*& start, CharacterType*& end, UC
return true;
}
+template <typename SrcCharacterType>
+inline size_t CSSTokenizer::peekMaxURILen(SrcCharacterType* src, UChar quote)
+{
+ // The decoded form of a URI (after resolving escape sequences)
+ // will not contain more characters (ASCII or UTF-16 codepoints)
+ // than the input. This code can therefore ignore escape sequences
+ // completely.
+ SrcCharacterType* start = src;
+ if (quote) {
+ ASSERT(quote == '"' || quote == '\'');
+ return peekMaxStringLen(src, quote);
+ }
+
+ while (isURILetter(*src)) {
+ if (LIKELY(*src != '\\'))
+ src++;
+ else
+ parseEscape<SrcCharacterType>(src);
+ }
+
+ return src - start;
+}
+
template <typename SrcCharacterType, typename DestCharacterType>
inline bool CSSTokenizer::parseURIInternal(SrcCharacterType*& src, DestCharacterType*& dest, UChar quote)
{
@@ -593,7 +655,7 @@ inline bool CSSTokenizer::parseURIInternal(SrcCharacterType*& src, DestCharacter
*dest++ = *src++;
} else {
unsigned unicode = parseEscape<SrcCharacterType>(src);
- if (unicode > 0xff && sizeof(SrcCharacterType) == 1)
+ if (unicode > 0xff && sizeof(DestCharacterType) == 1)
return false;
UnicodeToChars(dest, unicode);
}
@@ -619,11 +681,12 @@ inline void CSSTokenizer::parseURI(CSSParserString& string)
// Reset the current character to the start of the URI and re-parse with
// a 16-bit destination.
ASSERT(is8BitSource());
- UChar* uriStart16 = currentCharacter16();
currentCharacter<CharacterType>() = uriStart;
- bool result = parseURIInternal(currentCharacter<CharacterType>(), currentCharacter16(), quote);
+ UChar* result16 = allocateStringBuffer16(peekMaxURILen(currentCharacter<CharacterType>(), quote));
+ UChar* uriStart16 = result16;
+ bool result = parseURIInternal(currentCharacter<CharacterType>(), result16, quote);
ASSERT_UNUSED(result, result);
- string.init(uriStart16, currentCharacter16() - uriStart16);
+ string.init(uriStart16, result16 - uriStart16);
}
currentCharacter<CharacterType>() = uriEnd + 1;
@@ -719,12 +782,6 @@ inline bool CSSTokenizer::detectFunctionTypeToken(int length)
m_token = CUEFUNCTION;
return true;
}
- CASE("var") {
- if (!RuntimeEnabledFeatures::cssVariablesEnabled())
- return false;
- m_token = VARFUNCTION;
- return true;
- }
CASE("calc") {
m_token = CALCFUNCTION;
return true;
@@ -733,6 +790,10 @@ inline bool CSSTokenizer::detectFunctionTypeToken(int length)
m_token = HOSTFUNCTION;
return true;
}
+ CASE("host-context") {
+ m_token = HOSTCONTEXTFUNCTION;
+ return true;
+ }
CASE("nth-child") {
m_parsingMode = NthChildMode;
return true;
@@ -881,18 +942,9 @@ inline void CSSTokenizer::detectDashToken(int length)
CASE("webkit-any") {
m_token = ANYFUNCTION;
}
- CASE("webkit-min") {
- m_token = MINFUNCTION;
- }
- CASE("webkit-max") {
- m_token = MAXFUNCTION;
- }
CASE("webkit-calc") {
m_token = CALCFUNCTION;
}
- CASE("webkit-distributed") {
- m_token = DISTRIBUTEDFUNCTION;
- }
}
}
@@ -1009,14 +1061,6 @@ inline void CSSTokenizer::detectAtToken(int length, bool hasEscape)
if (LIKELY(!hasEscape && m_internal))
m_token = INTERNAL_RULE_SYM;
}
- CASE("-webkit-region") {
- if (LIKELY(!hasEscape))
- m_token = WEBKIT_REGION_RULE_SYM;
- }
- CASE("-webkit-filter") {
- if (LIKELY(!hasEscape))
- m_token = WEBKIT_FILTER_RULE_SYM;
- }
CASE("-internal-decls") {
if (LIKELY(!hasEscape && m_internal))
m_token = INTERNAL_DECLS_SYM;
@@ -1075,18 +1119,6 @@ inline void CSSTokenizer::detectSupportsToken(int length)
}
}
-template <typename CharacterType>
-inline void CSSTokenizer::detectCSSVariableDefinitionToken(int length)
-{
- static const int prefixLength = static_cast<int>(sizeof("var-") - 1);
- if (length <= prefixLength)
- return;
- CharacterType* name = tokenStart<CharacterType>();
- COMPILE_ASSERT(prefixLength > 0, CSS_variable_prefix_must_be_nonempty);
- if (name[prefixLength - 1] == '-' && isIdentifierStartAfterDash(name + prefixLength) && isEqualToCSSCaseSensitiveIdentifier(name, "var"))
- m_token = VAR_DEFINITION;
-}
-
template <typename SrcCharacterType>
int CSSTokenizer::realLex(void* yylvalWithoutType)
{
@@ -1176,8 +1208,6 @@ restartAfterComment:
}
}
}
- } else if (UNLIKELY(RuntimeEnabledFeatures::cssVariablesEnabled())) {
- detectCSSVariableDefinitionToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>());
}
break;
@@ -1338,7 +1368,7 @@ restartAfterComment:
break;
case CharacterQuote:
- if (checkAndSkipString(currentCharacter<SrcCharacterType>(), m_token)) {
+ if (checkAndSkipString(currentCharacter<SrcCharacterType>(), m_token, AbortIfInvalid)) {
++result;
parseString<SrcCharacterType>(result, yylval->string, m_token);
m_token = STRING;
@@ -1388,9 +1418,9 @@ restartAfterComment:
// Ignore comments. They are not even considered as white spaces.
if (*currentCharacter<SrcCharacterType>() == '*') {
const CSSParserLocation startLocation = currentLocation();
- if (m_parser.m_sourceDataHandler) {
+ if (m_parser.m_observer) {
unsigned startOffset = currentCharacter<SrcCharacterType>() - dataStart<SrcCharacterType>() - 1; // Start with a slash.
- m_parser.m_sourceDataHandler->startComment(startOffset - m_parsedTextPrefixLength);
+ m_parser.m_observer->startComment(startOffset - m_parsedTextPrefixLength);
}
++currentCharacter<SrcCharacterType>();
while (currentCharacter<SrcCharacterType>()[0] != '*' || currentCharacter<SrcCharacterType>()[1] != '/') {
@@ -1399,16 +1429,16 @@ restartAfterComment:
if (*currentCharacter<SrcCharacterType>() == '\0') {
// Unterminated comments are simply ignored.
currentCharacter<SrcCharacterType>() -= 2;
- m_parser.reportError(startLocation, CSSParser::UnterminatedCommentError);
+ m_parser.reportError(startLocation, UnterminatedCommentCSSError);
break;
}
++currentCharacter<SrcCharacterType>();
}
currentCharacter<SrcCharacterType>() += 2;
- if (m_parser.m_sourceDataHandler) {
+ if (m_parser.m_observer) {
unsigned endOffset = currentCharacter<SrcCharacterType>() - dataStart<SrcCharacterType>();
unsigned userTextEndOffset = static_cast<unsigned>(m_length - 1 - m_parsedTextSuffixLength);
- m_parser.m_sourceDataHandler->endComment(std::min(endOffset, userTextEndOffset) - m_parsedTextPrefixLength);
+ m_parser.m_observer->endComment(std::min(endOffset, userTextEndOffset) - m_parsedTextPrefixLength);
}
goto restartAfterComment;
}
@@ -1451,7 +1481,9 @@ restartAfterComment:
m_token = ATKEYWORD;
++result;
parseIdentifier(result, resultString, hasEscape);
- detectAtToken<SrcCharacterType>(result - tokenStart<SrcCharacterType>(), hasEscape);
+ // The standard enables unicode escapes in at-rules. In this case only the resultString will contain the
+ // correct identifier, hence we have to use it to determine its length instead of the usual pointer arithmetic.
+ detectAtToken<SrcCharacterType>(resultString.length() + 1, hasEscape);
}
break;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSTokenizer.h b/chromium/third_party/WebKit/Source/core/css/CSSTokenizer.h
index 05b319c177a..508bf71ee29 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSTokenizer.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSTokenizer.h
@@ -29,7 +29,7 @@
namespace WebCore {
-class CSSParser;
+class BisonCSSParser;
struct CSSParserLocation;
struct CSSParserString;
@@ -37,9 +37,9 @@ class CSSTokenizer {
WTF_MAKE_NONCOPYABLE(CSSTokenizer);
public:
// FIXME: This should not be needed but there are still some ties between the 2 classes.
- friend class CSSParser;
+ friend class BisonCSSParser;
- CSSTokenizer(CSSParser& parser)
+ CSSTokenizer(BisonCSSParser& parser)
: m_parser(parser)
, m_parsedTextPrefixLength(0)
, m_parsedTextSuffixLength(0)
@@ -74,7 +74,7 @@ public:
inline unsigned tokenStartOffset();
private:
- UChar*& currentCharacter16();
+ UChar* allocateStringBuffer16(size_t len);
template <typename CharacterType>
inline CharacterType*& currentCharacter();
@@ -92,29 +92,33 @@ private:
inline CSSParserLocation tokenLocation();
template <typename CharacterType>
- unsigned parseEscape(CharacterType*&);
+ static unsigned parseEscape(CharacterType*&);
template <typename DestCharacterType>
- inline void UnicodeToChars(DestCharacterType*&, unsigned);
- template <typename SrcCharacterType, typename DestCharacterType>
- inline bool parseIdentifierInternal(SrcCharacterType*&, DestCharacterType*&, bool&);
+ static inline void UnicodeToChars(DestCharacterType*&, unsigned);
+ template <typename SrcCharacterType, typename DestCharacterType>
+ static inline bool parseIdentifierInternal(SrcCharacterType*&, DestCharacterType*&, bool&);
+ template <typename SrcCharacterType>
+ static size_t peekMaxIdentifierLen(SrcCharacterType*);
template <typename CharacterType>
inline void parseIdentifier(CharacterType*&, CSSParserString&, bool&);
+ template <typename SrcCharacterType>
+ static size_t peekMaxStringLen(SrcCharacterType*, UChar quote);
template <typename SrcCharacterType, typename DestCharacterType>
- inline bool parseStringInternal(SrcCharacterType*&, DestCharacterType*&, UChar);
-
+ static inline bool parseStringInternal(SrcCharacterType*&, DestCharacterType*&, UChar);
template <typename CharacterType>
inline void parseString(CharacterType*&, CSSParserString& resultString, UChar);
template <typename CharacterType>
inline bool findURI(CharacterType*& start, CharacterType*& end, UChar& quote);
-
+ template <typename SrcCharacterType>
+ static size_t peekMaxURILen(SrcCharacterType*, UChar quote);
template <typename SrcCharacterType, typename DestCharacterType>
- inline bool parseURIInternal(SrcCharacterType*&, DestCharacterType*&, UChar quote);
-
+ static inline bool parseURIInternal(SrcCharacterType*&, DestCharacterType*&, UChar quote);
template <typename CharacterType>
inline void parseURI(CSSParserString&);
+
template <typename CharacterType>
inline bool parseUnicodeRange();
template <typename CharacterType>
@@ -133,13 +137,11 @@ private:
inline void detectAtToken(int, bool);
template <typename CharacterType>
inline void detectSupportsToken(int);
- template <typename CharacterType>
- inline void detectCSSVariableDefinitionToken(int);
template <typename SourceCharacterType>
int realLex(void* yylval);
- CSSParser& m_parser;
+ BisonCSSParser& m_parser;
size_t m_parsedTextPrefixLength;
size_t m_parsedTextSuffixLength;
@@ -157,6 +159,13 @@ private:
OwnPtr<UChar[]> m_dataStart16;
LChar* m_currentCharacter8;
UChar* m_currentCharacter16;
+
+ // During parsing of an ASCII stylesheet we might locate escape
+ // sequences that expand into UTF-16 code points. Strings,
+ // identifiers and URIs containing such escape sequences are
+ // stored in m_cssStrings16 so that we don't have to store the
+ // whole stylesheet as UTF-16.
+ Vector<OwnPtr<UChar[]> > m_cssStrings16;
union {
LChar* ptr8;
UChar* ptr16;
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSTransformValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSTransformValue.cpp
index de981949bd3..ebb21b931ba 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSTransformValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSTransformValue.cpp
@@ -76,20 +76,15 @@ String CSSTransformValue::customCSSText() const
return transformValueToCssString(m_type, CSSValueList::customCSSText());
}
-String CSSTransformValue::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- return transformValueToCssString(m_type, CSSValueList::customSerializeResolvingVariables(variables));
-}
-
CSSTransformValue::CSSTransformValue(const CSSTransformValue& cloneFrom)
: CSSValueList(cloneFrom)
, m_type(cloneFrom.m_type)
{
}
-PassRefPtr<CSSTransformValue> CSSTransformValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSTransformValue> CSSTransformValue::cloneForCSSOM() const
{
- return adoptRef(new CSSTransformValue(*this));
+ return adoptRefWillBeNoop(new CSSTransformValue(*this));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSTransformValue.h b/chromium/third_party/WebKit/Source/core/css/CSSTransformValue.h
index 1ca3bbd45f1..11cd454a0d0 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSTransformValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSTransformValue.h
@@ -59,18 +59,19 @@ public:
Matrix3DTransformOperation
};
- static PassRefPtr<CSSTransformValue> create(TransformOperationType type)
+ static PassRefPtrWillBeRawPtr<CSSTransformValue> create(TransformOperationType type)
{
- return adoptRef(new CSSTransformValue(type));
+ return adoptRefWillBeNoop(new CSSTransformValue(type));
}
String customCSSText() const;
bool equals(const CSSTransformValue& other) const { return m_type == other.m_type && CSSValueList::equals(other); }
- String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const;
TransformOperationType operationType() const { return m_type; }
- PassRefPtr<CSSTransformValue> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<CSSTransformValue> cloneForCSSOM() const;
+
+ void traceAfterDispatch(Visitor* visitor) { CSSValueList::traceAfterDispatch(visitor); }
private:
CSSTransformValue(TransformOperationType);
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSUnicodeRangeValue.h b/chromium/third_party/WebKit/Source/core/css/CSSUnicodeRangeValue.h
index 3ce02a98cc6..c198a237d6e 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSUnicodeRangeValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSUnicodeRangeValue.h
@@ -33,9 +33,9 @@ namespace WebCore {
class CSSUnicodeRangeValue : public CSSValue {
public:
- static PassRefPtr<CSSUnicodeRangeValue> create(UChar32 from, UChar32 to)
+ static PassRefPtrWillBeRawPtr<CSSUnicodeRangeValue> create(UChar32 from, UChar32 to)
{
- return adoptRef(new CSSUnicodeRangeValue(from, to));
+ return adoptRefWillBeNoop(new CSSUnicodeRangeValue(from, to));
}
UChar32 from() const { return m_from; }
@@ -45,6 +45,8 @@ public:
bool equals(const CSSUnicodeRangeValue&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
CSSUnicodeRangeValue(UChar32 from, UChar32 to)
: CSSValue(UnicodeRangeClass)
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSUnknownRule.h b/chromium/third_party/WebKit/Source/core/css/CSSUnknownRule.h
index 629aaead0d3..06d1be4283a 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSUnknownRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSUnknownRule.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class CSSUnknownRule : public CSSRule {
+class CSSUnknownRule FINAL : public CSSRule {
public:
CSSUnknownRule() : CSSRule(0) { }
virtual ~CSSUnknownRule() { }
@@ -34,6 +34,7 @@ public:
virtual CSSRule::Type type() const OVERRIDE { return UNKNOWN_RULE; }
virtual String cssText() const OVERRIDE { return String(); }
virtual void reattach(StyleRuleBase*) OVERRIDE { }
+ virtual void trace(Visitor* visitor) OVERRIDE { CSSRule::trace(visitor); }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSValue.cpp b/chromium/third_party/WebKit/Source/core/css/CSSValue.cpp
index 6d74434cc11..332638e95eb 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSValue.cpp
@@ -41,29 +41,25 @@
#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSGradientValue.h"
#include "core/css/CSSGridLineNamesValue.h"
-#include "core/css/CSSGridTemplateValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
#include "core/css/CSSImageSetValue.h"
#include "core/css/CSSImageValue.h"
#include "core/css/CSSInheritedValue.h"
#include "core/css/CSSInitialValue.h"
#include "core/css/CSSLineBoxContainValue.h"
-#include "core/css/CSSMixFunctionValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSReflectValue.h"
#include "core/css/CSSSVGDocumentValue.h"
-#include "core/css/CSSShaderValue.h"
#include "core/css/CSSShadowValue.h"
#include "core/css/CSSTimingFunctionValue.h"
#include "core/css/CSSTransformValue.h"
#include "core/css/CSSUnicodeRangeValue.h"
#include "core/css/CSSValueList.h"
-#include "core/css/CSSVariableValue.h"
-#include "core/svg/SVGColor.h"
#include "core/svg/SVGPaint.h"
namespace WebCore {
-struct SameSizeAsCSSValue : public RefCounted<SameSizeAsCSSValue> {
+struct SameSizeAsCSSValue : public RefCountedWillBeGarbageCollectedFinalized<SameSizeAsCSSValue> {
uint32_t bitfields;
};
@@ -71,10 +67,15 @@ COMPILE_ASSERT(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), CSS_value_should_
class TextCloneCSSValue : public CSSValue {
public:
- static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); }
+ static PassRefPtrWillBeRawPtr<TextCloneCSSValue> create(ClassType classType, const String& text)
+ {
+ return adoptRefWillBeNoop(new TextCloneCSSValue(classType, text));
+ }
String cssText() const { return m_cssText; }
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
private:
TextCloneCSSValue(ClassType classType, const String& text)
: CSSValue(classType, /*isCSSOMSafe*/ true)
@@ -106,21 +107,6 @@ CSSValue::Type CSSValue::cssValueType() const
return CSS_CUSTOM;
}
-void CSSValue::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const
-{
- // This should get called for internal instances only.
- ASSERT(!isCSSOMSafe());
-
- if (isPrimitiveValue())
- toCSSPrimitiveValue(this)->addSubresourceStyleURLs(urls, styleSheet);
- else if (isValueList())
- toCSSValueList(this)->addSubresourceStyleURLs(urls, styleSheet);
- else if (classType() == FontFaceSrcClass)
- toCSSFontFaceSrcValue(this)->addSubresourceStyleURLs(urls, styleSheet);
- else if (classType() == ReflectClass)
- toCSSReflectValue(this)->addSubresourceStyleURLs(urls, styleSheet);
-}
-
bool CSSValue::hasFailedOrCanceledSubresources() const
{
// This should get called for internal instances only.
@@ -185,8 +171,8 @@ bool CSSValue::equals(const CSSValue& other) const
return compareCSSValues<CSSInitialValue>(*this, other);
case GridLineNamesClass:
return compareCSSValues<CSSGridLineNamesValue>(*this, other);
- case GridTemplateClass:
- return compareCSSValues<CSSGridTemplateValue>(*this, other);
+ case GridTemplateAreasClass:
+ return compareCSSValues<CSSGridTemplateAreasValue>(*this, other);
case PrimitiveClass:
return compareCSSValues<CSSPrimitiveValue>(*this, other);
case ReflectClass:
@@ -213,14 +199,6 @@ bool CSSValue::equals(const CSSValue& other) const
return compareCSSValues<CSSFilterValue>(*this, other);
case CSSArrayFunctionValueClass:
return compareCSSValues<CSSArrayFunctionValue>(*this, other);
- case CSSMixFunctionValueClass:
- return compareCSSValues<CSSMixFunctionValue>(*this, other);
- case CSSShaderClass:
- return compareCSSValues<CSSShaderValue>(*this, other);
- case VariableClass:
- return compareCSSValues<CSSVariableValue>(*this, other);
- case SVGColorClass:
- return compareCSSValues<SVGColor>(*this, other);
case SVGPaintClass:
return compareCSSValues<SVGPaint>(*this, other);
case CSSSVGDocumentClass:
@@ -275,8 +253,8 @@ String CSSValue::cssText() const
return toCSSInitialValue(this)->customCSSText();
case GridLineNamesClass:
return toCSSGridLineNamesValue(this)->customCSSText();
- case GridTemplateClass:
- return toCSSGridTemplateValue(this)->customCSSText();
+ case GridTemplateAreasClass:
+ return toCSSGridTemplateAreasValue(this)->customCSSText();
case PrimitiveClass:
return toCSSPrimitiveValue(this)->customCSSText();
case ReflectClass:
@@ -303,14 +281,6 @@ String CSSValue::cssText() const
return toCSSFilterValue(this)->customCSSText();
case CSSArrayFunctionValueClass:
return toCSSArrayFunctionValue(this)->customCSSText();
- case CSSMixFunctionValueClass:
- return toCSSMixFunctionValue(this)->customCSSText();
- case CSSShaderClass:
- return toCSSShaderValue(this)->customCSSText();
- case VariableClass:
- return toCSSVariableValue(this)->value();
- case SVGColorClass:
- return toSVGColor(this)->customCSSText();
case SVGPaintClass:
return toSVGPaint(this)->customCSSText();
case CSSSVGDocumentClass:
@@ -320,22 +290,6 @@ String CSSValue::cssText() const
return String();
}
-String CSSValue::serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- switch (classType()) {
- case PrimitiveClass:
- return toCSSPrimitiveValue(this)->customSerializeResolvingVariables(variables);
- case ReflectClass:
- return toCSSReflectValue(this)->customSerializeResolvingVariables(variables);
- case ValueListClass:
- return toCSSValueList(this)->customSerializeResolvingVariables(variables);
- case CSSTransformClass:
- return toCSSTransformValue(this)->customSerializeResolvingVariables(variables);
- default:
- return cssText();
- }
-}
-
void CSSValue::destroy()
{
if (m_isTextClone) {
@@ -391,8 +345,8 @@ void CSSValue::destroy()
case GridLineNamesClass:
delete toCSSGridLineNamesValue(this);
return;
- case GridTemplateClass:
- delete toCSSGridTemplateValue(this);
+ case GridTemplateAreasClass:
+ delete toCSSGridTemplateAreasValue(this);
return;
case PrimitiveClass:
delete toCSSPrimitiveValue(this);
@@ -433,29 +387,231 @@ void CSSValue::destroy()
case CSSArrayFunctionValueClass:
delete toCSSArrayFunctionValue(this);
return;
- case CSSMixFunctionValueClass:
- delete toCSSMixFunctionValue(this);
+ case SVGPaintClass:
+ delete toSVGPaint(this);
+ return;
+ case CSSSVGDocumentClass:
+ delete toCSSSVGDocumentValue(this);
+ return;
+ }
+ ASSERT_NOT_REACHED();
+}
+
+void CSSValue::finalizeGarbageCollectedObject()
+{
+ if (m_isTextClone) {
+ ASSERT(isCSSOMSafe());
+ static_cast<TextCloneCSSValue*>(this)->~TextCloneCSSValue();
+ return;
+ }
+ ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
+
+ switch (classType()) {
+ case AspectRatioClass:
+ toCSSAspectRatioValue(this)->~CSSAspectRatioValue();
+ return;
+ case BorderImageSliceClass:
+ toCSSBorderImageSliceValue(this)->~CSSBorderImageSliceValue();
+ return;
+ case CanvasClass:
+ toCSSCanvasValue(this)->~CSSCanvasValue();
+ return;
+ case CursorImageClass:
+ toCSSCursorImageValue(this)->~CSSCursorImageValue();
+ return;
+ case FontClass:
+ toCSSFontValue(this)->~CSSFontValue();
+ return;
+ case FontFaceSrcClass:
+ toCSSFontFaceSrcValue(this)->~CSSFontFaceSrcValue();
+ return;
+ case FontFeatureClass:
+ toCSSFontFeatureValue(this)->~CSSFontFeatureValue();
+ return;
+ case FunctionClass:
+ toCSSFunctionValue(this)->~CSSFunctionValue();
+ return;
+ case LinearGradientClass:
+ toCSSLinearGradientValue(this)->~CSSLinearGradientValue();
+ return;
+ case RadialGradientClass:
+ toCSSRadialGradientValue(this)->~CSSRadialGradientValue();
+ return;
+ case CrossfadeClass:
+ toCSSCrossfadeValue(this)->~CSSCrossfadeValue();
+ return;
+ case ImageClass:
+ toCSSImageValue(this)->~CSSImageValue();
+ return;
+ case InheritedClass:
+ toCSSInheritedValue(this)->~CSSInheritedValue();
+ return;
+ case InitialClass:
+ toCSSInitialValue(this)->~CSSInitialValue();
+ return;
+ case GridLineNamesClass:
+ toCSSGridLineNamesValue(this)->~CSSGridLineNamesValue();
+ return;
+ case GridTemplateAreasClass:
+ toCSSGridTemplateAreasValue(this)->~CSSGridTemplateAreasValue();
+ return;
+ case PrimitiveClass:
+ toCSSPrimitiveValue(this)->~CSSPrimitiveValue();
+ return;
+ case ReflectClass:
+ toCSSReflectValue(this)->~CSSReflectValue();
+ return;
+ case ShadowClass:
+ toCSSShadowValue(this)->~CSSShadowValue();
+ return;
+ case CubicBezierTimingFunctionClass:
+ toCSSCubicBezierTimingFunctionValue(this)->~CSSCubicBezierTimingFunctionValue();
+ return;
+ case StepsTimingFunctionClass:
+ toCSSStepsTimingFunctionValue(this)->~CSSStepsTimingFunctionValue();
+ return;
+ case UnicodeRangeClass:
+ toCSSUnicodeRangeValue(this)->~CSSUnicodeRangeValue();
+ return;
+ case ValueListClass:
+ toCSSValueList(this)->~CSSValueList();
+ return;
+ case CSSTransformClass:
+ toCSSTransformValue(this)->~CSSTransformValue();
+ return;
+ case LineBoxContainClass:
+ toCSSLineBoxContainValue(this)->~CSSLineBoxContainValue();
return;
- case CSSShaderClass:
- delete toCSSShaderValue(this);
+ case CalculationClass:
+ toCSSCalcValue(this)->~CSSCalcValue();
return;
- case VariableClass:
- delete toCSSVariableValue(this);
+ case ImageSetClass:
+ toCSSImageSetValue(this)->~CSSImageSetValue();
return;
- case SVGColorClass:
- delete toSVGColor(this);
+ case CSSFilterClass:
+ toCSSFilterValue(this)->~CSSFilterValue();
+ return;
+ case CSSArrayFunctionValueClass:
+ toCSSArrayFunctionValue(this)->~CSSArrayFunctionValue();
return;
case SVGPaintClass:
- delete toSVGPaint(this);
+ toSVGPaint(this)->~SVGPaint();
return;
case CSSSVGDocumentClass:
- delete toCSSSVGDocumentValue(this);
+ toCSSSVGDocumentValue(this)->~CSSSVGDocumentValue();
+ return;
+ }
+ ASSERT_NOT_REACHED();
+}
+
+void CSSValue::trace(Visitor* visitor)
+{
+ if (m_isTextClone) {
+ ASSERT(isCSSOMSafe());
+ static_cast<TextCloneCSSValue*>(this)->traceAfterDispatch(visitor);
+ return;
+ }
+ ASSERT(!isCSSOMSafe() || isSubtypeExposedToCSSOM());
+
+ switch (classType()) {
+ case AspectRatioClass:
+ toCSSAspectRatioValue(this)->traceAfterDispatch(visitor);
+ return;
+ case BorderImageSliceClass:
+ toCSSBorderImageSliceValue(this)->traceAfterDispatch(visitor);
+ return;
+ case CanvasClass:
+ toCSSCanvasValue(this)->traceAfterDispatch(visitor);
+ return;
+ case CursorImageClass:
+ toCSSCursorImageValue(this)->traceAfterDispatch(visitor);
+ return;
+ case FontClass:
+ toCSSFontValue(this)->traceAfterDispatch(visitor);
+ return;
+ case FontFaceSrcClass:
+ toCSSFontFaceSrcValue(this)->traceAfterDispatch(visitor);
+ return;
+ case FontFeatureClass:
+ toCSSFontFeatureValue(this)->traceAfterDispatch(visitor);
+ return;
+ case FunctionClass:
+ toCSSFunctionValue(this)->traceAfterDispatch(visitor);
+ return;
+ case LinearGradientClass:
+ toCSSLinearGradientValue(this)->traceAfterDispatch(visitor);
+ return;
+ case RadialGradientClass:
+ toCSSRadialGradientValue(this)->traceAfterDispatch(visitor);
+ return;
+ case CrossfadeClass:
+ toCSSCrossfadeValue(this)->traceAfterDispatch(visitor);
+ return;
+ case ImageClass:
+ toCSSImageValue(this)->traceAfterDispatch(visitor);
+ return;
+ case InheritedClass:
+ toCSSInheritedValue(this)->traceAfterDispatch(visitor);
+ return;
+ case InitialClass:
+ toCSSInitialValue(this)->traceAfterDispatch(visitor);
+ return;
+ case GridLineNamesClass:
+ toCSSGridLineNamesValue(this)->traceAfterDispatch(visitor);
+ return;
+ case GridTemplateAreasClass:
+ toCSSGridTemplateAreasValue(this)->traceAfterDispatch(visitor);
+ return;
+ case PrimitiveClass:
+ toCSSPrimitiveValue(this)->traceAfterDispatch(visitor);
+ return;
+ case ReflectClass:
+ toCSSReflectValue(this)->traceAfterDispatch(visitor);
+ return;
+ case ShadowClass:
+ toCSSShadowValue(this)->traceAfterDispatch(visitor);
+ return;
+ case CubicBezierTimingFunctionClass:
+ toCSSCubicBezierTimingFunctionValue(this)->traceAfterDispatch(visitor);
+ return;
+ case StepsTimingFunctionClass:
+ toCSSStepsTimingFunctionValue(this)->traceAfterDispatch(visitor);
+ return;
+ case UnicodeRangeClass:
+ toCSSUnicodeRangeValue(this)->traceAfterDispatch(visitor);
+ return;
+ case ValueListClass:
+ toCSSValueList(this)->traceAfterDispatch(visitor);
+ return;
+ case CSSTransformClass:
+ toCSSTransformValue(this)->traceAfterDispatch(visitor);
+ return;
+ case LineBoxContainClass:
+ toCSSLineBoxContainValue(this)->traceAfterDispatch(visitor);
+ return;
+ case CalculationClass:
+ toCSSCalcValue(this)->traceAfterDispatch(visitor);
+ return;
+ case ImageSetClass:
+ toCSSImageSetValue(this)->traceAfterDispatch(visitor);
+ return;
+ case CSSFilterClass:
+ toCSSFilterValue(this)->traceAfterDispatch(visitor);
+ return;
+ case CSSArrayFunctionValueClass:
+ toCSSArrayFunctionValue(this)->traceAfterDispatch(visitor);
+ return;
+ case SVGPaintClass:
+ toSVGPaint(this)->traceAfterDispatch(visitor);
+ return;
+ case CSSSVGDocumentClass:
+ toCSSSVGDocumentValue(this)->traceAfterDispatch(visitor);
return;
}
ASSERT_NOT_REACHED();
}
-PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSValue> CSSValue::cloneForCSSOM() const
{
switch (classType()) {
case PrimitiveClass:
@@ -469,14 +625,10 @@ PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const
return toCSSFilterValue(this)->cloneForCSSOM();
case CSSArrayFunctionValueClass:
return toCSSArrayFunctionValue(this)->cloneForCSSOM();
- case CSSMixFunctionValueClass:
- return toCSSMixFunctionValue(this)->cloneForCSSOM();
case CSSTransformClass:
return toCSSTransformValue(this)->cloneForCSSOM();
case ImageSetClass:
return toCSSImageSetValue(this)->cloneForCSSOM();
- case SVGColorClass:
- return toSVGColor(this)->cloneForCSSOM();
case SVGPaintClass:
return toSVGPaint(this)->cloneForCSSOM();
default:
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSValue.h b/chromium/third_party/WebKit/Source/core/css/CSSValue.h
index e6b21b8ce2b..a883479b899 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSValue.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSValue.h
@@ -22,6 +22,7 @@
#define CSSValue_h
#include "core/dom/ExceptionCode.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/HashMap.h"
#include "wtf/ListHashSet.h"
@@ -40,7 +41,7 @@ enum CSSTextFormattingFlags { QuoteCSSStringIfNeeded, AlwaysQuoteCSSString };
// They should be handled by separate wrapper classes.
// Please don't expose more CSSValue types to the web.
-class CSSValue : public RefCounted<CSSValue> {
+class CSSValue : public RefCountedWillBeGarbageCollectedFinalized<CSSValue> {
public:
enum Type {
CSS_INHERIT = 0,
@@ -53,17 +54,20 @@ public:
// Override RefCounted's deref() to ensure operator delete is called on
// the appropriate subclass type.
+ // When oilpan is enabled the finalize method is called by the garbage
+ // collector and not immediately when deref reached zero.
+#if !ENABLE(OILPAN)
void deref()
{
if (derefBase())
destroy();
}
+#endif // !ENABLE(OILPAN)
Type cssValueType() const;
String cssText() const;
void setCSSText(const String&, ExceptionState&) { } // FIXME: Not implemented.
- String serializeResolvingVariables(const HashMap<AtomicString, String>&) const;
bool isPrimitiveValue() const { return m_classType == PrimitiveClass; }
bool isValueList() const { return m_classType >= ValueListClass; }
@@ -98,11 +102,7 @@ public:
bool isCalcValue() const {return m_classType == CalculationClass; }
bool isFilterValue() const { return m_classType == CSSFilterClass; }
bool isArrayFunctionValue() const { return m_classType == CSSArrayFunctionValueClass; }
- bool isMixFunctionValue() const { return m_classType == CSSMixFunctionValueClass; }
- bool isShaderValue() const { return m_classType == CSSShaderClass; }
- bool isVariableValue() const { return m_classType == VariableClass; }
- bool isGridTemplateValue() const { return m_classType == GridTemplateClass; }
- bool isSVGColor() const { return m_classType == SVGColorClass || m_classType == SVGPaintClass; }
+ bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; }
bool isSVGPaint() const { return m_classType == SVGPaintClass; }
bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; }
bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
@@ -111,17 +111,19 @@ public:
bool isCSSOMSafe() const { return m_isCSSOMSafe; }
bool isSubtypeExposedToCSSOM() const
{
- return isPrimitiveValue() || isSVGColor() || isValueList();
+ return isPrimitiveValue() || isSVGPaint() || isValueList();
}
- PassRefPtr<CSSValue> cloneForCSSOM() const;
-
- void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
+ PassRefPtrWillBeRawPtr<CSSValue> cloneForCSSOM() const;
bool hasFailedOrCanceledSubresources() const;
bool equals(const CSSValue&) const;
+ void finalizeGarbageCollectedObject();
+ void traceAfterDispatch(Visitor*) { }
+ void trace(Visitor*);
+
protected:
static const size_t ClassTypeBits = 6;
@@ -158,12 +160,9 @@ protected:
UnicodeRangeClass,
LineBoxContainClass,
CalculationClass,
- CSSShaderClass,
- VariableClass,
- GridTemplateClass,
+ GridTemplateAreasClass,
// SVG classes.
- SVGColorClass,
SVGPaintClass,
CSSSVGDocumentClass,
@@ -172,7 +171,6 @@ protected:
ImageSetClass,
CSSFilterClass,
CSSArrayFunctionValueClass,
- CSSMixFunctionValueClass,
CSSTransformClass,
GridLineNamesClass,
// Do not append non-list class types here.
@@ -213,7 +211,7 @@ protected:
// to maximize struct packing.
// CSSPrimitiveValue bits:
- unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitTypes
+ unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType
mutable unsigned m_hasCachedCSSText : 1;
unsigned m_isQuirkValue : 1;
@@ -223,16 +221,16 @@ private:
unsigned m_classType : ClassTypeBits; // ClassType
};
-template<typename CSSValueType>
-inline bool compareCSSValueVector(const Vector<RefPtr<CSSValueType> >& firstVector, const Vector<RefPtr<CSSValueType> >& secondVector)
+template<typename CSSValueType, size_t inlineCapacity>
+inline bool compareCSSValueVector(const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>, inlineCapacity>& secondVector)
{
size_t size = firstVector.size();
if (size != secondVector.size())
return false;
for (size_t i = 0; i < size; i++) {
- const RefPtr<CSSValueType>& firstPtr = firstVector[i];
- const RefPtr<CSSValueType>& secondPtr = secondVector[i];
+ const RefPtrWillBeMember<CSSValueType>& firstPtr = firstVector[i];
+ const RefPtrWillBeMember<CSSValueType>& secondPtr = secondVector[i];
if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals(*secondPtr)))
continue;
return false;
@@ -246,6 +244,18 @@ inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<C
return first ? second && first->equals(*second) : !second;
}
+template<typename CSSValueType>
+inline bool compareCSSValuePtr(const RawPtr<CSSValueType>& first, const RawPtr<CSSValueType>& second)
+{
+ return first ? second && first->equals(*second) : !second;
+}
+
+template<typename CSSValueType>
+inline bool compareCSSValuePtr(const Member<CSSValueType>& first, const Member<CSSValueType>& second)
+{
+ return first ? second && first->equals(*second) : !second;
+}
+
#define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \
DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, value.predicate)
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSValue.idl b/chromium/third_party/WebKit/Source/core/css/CSSValue.idl
index dfdacd3a828..145010b29bb 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSValue.idl
+++ b/chromium/third_party/WebKit/Source/core/css/CSSValue.idl
@@ -21,6 +21,7 @@
[
Custom=Wrap,
DependentLifetime,
+ WillBeGarbageCollected,
] interface CSSValue {
// UnitTypes
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSValueKeywords.in b/chromium/third_party/WebKit/Source/core/css/CSSValueKeywords.in
index c2c3a1b4765..c8512398070 100755..100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSValueKeywords.in
+++ b/chromium/third_party/WebKit/Source/core/css/CSSValueKeywords.in
@@ -9,10 +9,11 @@
inherit
initial
//
-// CSS_PROP_OUTLINE_STYLE
-// CSS_PROP_BORDER_TOP_STYLE
-// CSS_PROP_BORDER_BOTTOM_STYLE
-// CSS_PROP_BORDER_LEFT_STYLE
+// outline-style
+// border-top-style
+// border-bottom-style
+// border-left-style
+// border-right-style
// The order here must match the order of the EBorderStyle enum in RenderStyleConstants.h.
none
hidden
@@ -26,7 +27,7 @@ solid
double
//
-// CSS_PROP_FONT:
+// font
//
caption
icon
@@ -39,20 +40,21 @@ small-caption
status-bar
//
-// CSS_PROP_FONT_STYLE:
+// font-style
//
//normal
italic
oblique
// The following is only allowed in @font-face:
all
+
//
-// CSS_PROP_FONT_VARIANT:
+// font-variant
//
//normal
small-caps
-// -webkit-font-variant-ligatures:
+// font-variant-ligatures:
//
// normal
common-ligatures
@@ -61,9 +63,11 @@ discretionary-ligatures
no-discretionary-ligatures
historical-ligatures
no-historical-ligatures
+contextual
+no-contextual
//
-// CSS_PROP_FONT_WEIGHT:
+// font-weigth
//
normal
bold
@@ -78,8 +82,9 @@ lighter
700
800
900
+
//
-// CSS_PROP_FONT_SIZE:
+// font-size
//
xx-small
x-small
@@ -91,22 +96,9 @@ xx-large
-webkit-xxx-large
smaller
larger
+
//
-// CSS_PROP_FONT_STRETCH:
-//
-//normal
-wider
-narrower
-ultra-condensed
-extra-condensed
-condensed
-semi-condensed
-semi-expanded
-expanded
-extra-expanded
-ultra-expanded
-//
-// CSS_PROP_GENERIC_FONT_FAMILY:
+// font-family (<generic-family> in CSS 2.1)
//
serif
sans-serif
@@ -115,9 +107,10 @@ fantasy
monospace
-webkit-body
-webkit-pictograph
+
//
//
-// CSS_PROP_*_COLOR
+// *-color
//
aqua
black
@@ -177,7 +170,7 @@ grey
// colors in non strict mode
-webkit-text mode=QuirksOrUASheet
//
-// CSS_PROP_BACKGROUND_REPEAT:
+// background-repeat
//
repeat
repeat-x
@@ -186,7 +179,7 @@ no-repeat
// round
// space
//
-// CSS_PROP__WEBKIT_BACKGROUND_COMPOSITE:
+// -webkit-background-composite
//
clear
copy
@@ -203,7 +196,7 @@ plus-darker
// highlight
plus-lighter
//
-// CSS_PROP_VERTICAL_ALIGN:
+// vertical-align
//
baseline
middle
@@ -216,7 +209,7 @@ bottom
// HTML alignment MIDDLE has no corresponding CSS alignment
-webkit-baseline-middle
//
-// CSS_PROP_TEXT_ALIGN:
+// text-align
// The order here must match the order of the ETextAlign enum in RenderStyleConstants.h.
//
-webkit-auto
@@ -229,19 +222,19 @@ justify
-webkit-center
-webkit-match-parent
//
-// CSS_PROP_TEXT_JUSTIFY:
+// text-justify
//
//auto
//none
inter-word
distribute
//
-// CSS_PROP_LIST_STYLE_POSITION:
+// list-style-position
//
outside
inside
//
-// CSS_PROP_LIST_STYLE_TYPE:
+// list-style-type
// The order here must match the order of the EListStyleType enum in RenderStyleConstants.h.
//
disc
@@ -326,7 +319,7 @@ hiragana-iroha
katakana-iroha
//none
//
-// CSS_PROP_DISPLAY:
+// display
// The order here must match the order of the EDisplay enum in RenderStyleConstants.h.
//
inline
@@ -349,12 +342,11 @@ flex
inline-flex
grid
inline-grid
-lazy-block
//none
-webkit-flex
-webkit-inline-flex
//
-// CSS_PROP_CURSOR:
+// cursor
// The order here must match the order of the ECursor enum in RenderStyleConstants.h.
//
auto
@@ -370,8 +362,8 @@ alias
progress
no-drop
not-allowed
--webkit-zoom-in
--webkit-zoom-out
+zoom-in
+zoom-out
e-resize
ne-resize
nw-resize
@@ -392,21 +384,23 @@ help
all-scroll
-webkit-grab
-webkit-grabbing
+-webkit-zoom-in
+-webkit-zoom-out
// none
//
-// CSS_PROP_DIRECTION:
+// direction
//
ltr
rtl
//
-// CSS_PROP_TEXT_TRANSFORM:
+// text-transform
//
capitalize
uppercase
lowercase
//none
//
-// CSS_PROP_VISIBILITY:
+// visibility
//
visible
//hidden
@@ -428,13 +422,10 @@ bidi-override
blink
both
close-quote
-crop
-cross
embed
fixed
hand
hide
-higher
invert
-webkit-isolate
-webkit-isolate-override
@@ -443,12 +434,8 @@ landscape
ledger
legal
letter
-level
line-through
local
-loud
-lower
-mix
no-close-quote
no-open-quote
nowrap
@@ -472,38 +459,38 @@ wavy
-webkit-nowrap
// CSS3 Values
-// CSS_PROP_BOX_ALIGN
+// box-align
stretch
start
end
//center
//baseline
-// CSS_PROP_BOX_DECORATION_BREAK
+// box-decoration-break
clone
slice
-// CSS_PROP_BOX_DIRECTION
+// box-direction
// normal
reverse
-// CSS_PROP_BOX_ORIENT
+// box-orient
horizontal
vertical
inline-axis
block-axis
-// CSS_PROP_BOX_PACK
+// box-pack
// start
// end
// center
// justify
-// CSS_PROP_BOX_LINES
+// box-lines
single
multiple
-// CSS_PROP_ALIGN_CONTENT
+// align-content
flex-start
flex-end
// center
@@ -511,21 +498,21 @@ space-between
space-around
// stretch
-// CSS_PROP_ALIGN_ITEMS / CSS_PROP_ALIGN_SELF
+// align-items / align-self
// flex-start
// flex-end
// center
// baseline
// stretch
-// CSS_PROP_JUSTIFY_CONTENT
+// justify-content
// flex-start
// flex-end
// center
// space-between
// space-around
-// CSS_PROP_FLEX_FLOW
+// flex-flow
row
row-reverse
column
@@ -534,7 +521,7 @@ column-reverse
// wrap
wrap-reverse
-// CSS_PROP_MARQUEE_DIRECTION
+// -internal-marquee-direction
forwards
backwards
ahead
@@ -545,39 +532,34 @@ up
down
// auto
-// CSS_PROP_MARQUEE_SPEED
+// -internal-marquee-speed
slow
// normal
fast
-// CSS_PROP_MARQUEE_REPETITION
+// -internal-marquee-repetition
infinite
-// CSS_PROP_MARQUEE_STYLE
+// -internal-marquee-style
// none
slide
// scroll
alternate
//
-// CSS_PROP__KHTML_USER_MODIFY
+// -webkit-user-modify
//
read-only
read-write
read-write-plaintext-only
//
-// CSS_PROP__KHTML_USER_DRAG
+// -webkit-user-drag
//
element
//
-// CSS_PROP__KHTML_USER_SELECT
-//
-ignore
-
-//
-// CSS_PROP_WIDTH/MIN_WIDTH/MAX_WIDTH
+// width/min-width/max-width
//
intrinsic
min-intrinsic
@@ -594,48 +576,48 @@ min-content
max-content
//
-// CSS_PROP_TEXT_OVERFLOW
+// text-overflow
//
clip
ellipsis
//
-// CSS_PROP__KHTML_MARGIN_COLLAPSE
+// -webkit-margin-collapse
//
// collapse
// separate
discard
//
-// CSS_PROP_TEXT_*_COLOR
+// text-*-color
//
dot-dash
dot-dot-dash
wave
//
-// CSS_PROP_TEXT_*_MODE
+// text-*-mode
//
continuous
skip-white-space
//
-// CSS_PROP_WORD_BREAK
+// word-break
//
break-all
//
-// CSS_PROP_WORD_WRAP
+// word-wrap
//
break-word
//
-// CSS_PROP__KHTML_NBSP_MODE
+// nbsp-mode
//
space
//
-// CSS_PROP__KHTML_LINE_BREAK
+// -webkit-line-break
//
// auto
loose
@@ -653,7 +635,6 @@ square-button
button
button-bevel
inner-spin-button
--webkit-input-speech-button
listbox
listitem
media-enter-fullscreen-button
@@ -663,17 +644,12 @@ media-fullscreen-volume-slider-thumb
media-mute-button
media-play-button
media-overlay-play-button
-media-seek-back-button
-media-seek-forward-button
-media-rewind-button
-media-return-to-realtime-button
media-toggle-closed-captions-button
media-slider
media-sliderthumb
media-volume-slider-container
media-volume-slider
media-volume-sliderthumb
-media-volume-slider-mute-button
media-controls-background
media-controls-fullscreen-background
media-current-time-display
@@ -704,14 +680,14 @@ textarea
caps-lock-indicator
//
-// CSS_PROP_BORDER_IMAGE
+// border-image
//
// stretch
// repeat
round
//
-// CSS_PROP_BACKGROUND_CLIP/ORIGIN
+// background-clip/background-origin
//
// border/content/padding are deprecated and ultimately will only apply to the -webkit- form of these properties.
// border-box/content-box/padding-box should be used instead.
@@ -723,7 +699,7 @@ content-box
padding
padding-box
-// CSS_SHAPES
+// CSS 3 SHAPES
margin-box
//
@@ -733,50 +709,50 @@ contain
cover
//
-// CSS_PROP__KHTML_RTL_ORDERING
+// -webkit-rtl-ordering
//
logical
visual
//
-// CSS_PROP__WEBKIT_BORDER_FIT
+// -webkit-border-fit
//
lines
//
-// CSS_PROP__WEBKIT_ANIMATION_DIRECTION
+// animation-direction
//
// alternate
alternate-reverse
//
-// CSS_PROP__WEBKIT_ANIMATION_FILL_MODE
+// animation-fill-mode
//
// forwards
// backwards
// both
//
-// CSS_PROP__WEBKIT_ANIMATION_ITERATION_COUNT
+// animation-iteration-count
//
// infinite
//
-// CSS_PROP__WEBKIT_ANIMATION_PLAY_STATE
+// animation-play-state
//
running
paused
//
-// CSS_PROP__WEBKIT_TRANSFORM_STYLE
+// transform-style
//
flat
preserve-3d
//
-// CSS_PROP__WEBKIT_TRANSITION_TIMING_FUNCTION
-// CSS_PROP__WEBKIT_ANIMATION_TIMING_FUNCTION
+// transition-timing-function
+// animation-timing-function
//
ease
linear
@@ -784,22 +760,23 @@ ease-in
ease-out
ease-in-out
step-start
+step-middle
step-end
//
-// CSS_PROP_ZOOM
+// zoom
//
document
reset
//
-// CSS_PROP_USER_ZOOM
+// user-zoom
//
// fixed
zoom
//
-// CSS_PROP_POINTER_EVENTS
+// pointer-events
//
visiblePainted
visibleFill
@@ -813,7 +790,7 @@ bounding-box
//none
//
-// CSS_PROP_SPEECH
+// speech
//
spell-out
digits
@@ -838,16 +815,6 @@ geometricPrecision
economy
exact
-// (-webkit-view-mode:) media feature:
-floating
-fullscreen
-maximized
-minimized
-windowed
-
-// -webkit-hyphenate-limit-lines
-no-limit
-
// -webkit-writing-mode
// SVG compatibility
lr
@@ -911,15 +878,12 @@ off
optimizeQuality
-webkit-optimize-contrast
-// shape-inside
// shape-outside
nonzero
evenodd
-outside-shape
-
-// -webkit-region-fragment
-// auto
-break
+at
+// closest-side
+// farthest-side
// -webkit-wrap-flow
// auto
@@ -933,9 +897,6 @@ maximum
wrap
// none
-// -webkit-line-align
-edges
-
alphabetic
// position
@@ -946,13 +907,6 @@ sticky
coarse
fine
-// -webkit-filter
-// values for the custom() function
-// border-box
-// padding-box
-// content-box
-filter-box
-detached
// blend modes
// normal
multiply
@@ -985,17 +939,20 @@ balance
drag
no-drag
-// -webkit-grid-{start|end|before|after}
+// grid-{column|row}-{start|end}
span
// text-indent
each-line
+//hanging // hanging exists in SVGCSSValueKeywords.in
// (scan:) media feature
progressive
interlace
-// CSS_PROP_PAINT_ORDER
+//
+// paint-order
+//
// normal
// fill
// stroke
@@ -1017,3 +974,34 @@ script
// touch-action
pan-x
pan-y
+manipulation
+
+// justify-self
+// auto
+// stretch
+// baseline
+// center
+// start
+// end
+self-start
+self-end
+// flex-start
+// flex-end
+// left
+// right
+true
+safe
+
+// scroll-behavior
+instant
+smooth
+
+// will-change
+// auto
+contents
+scroll-position
+
+// all
+// initial
+// inherit
+unset
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSValueList.cpp b/chromium/third_party/WebKit/Source/core/css/CSSValueList.cpp
index e1505c2e504..9d31f6bdf5b 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSValueList.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSValueList.cpp
@@ -53,7 +53,7 @@ bool CSSValueList::removeAll(CSSValue* val)
{
bool found = false;
for (size_t index = 0; index < m_values.size(); index++) {
- RefPtr<CSSValue>& value = m_values.at(index);
+ RefPtrWillBeMember<CSSValue>& value = m_values.at(index);
if (value && val && value->equals(*val)) {
m_values.remove(index);
found = true;
@@ -66,16 +66,16 @@ bool CSSValueList::removeAll(CSSValue* val)
bool CSSValueList::hasValue(CSSValue* val) const
{
for (size_t index = 0; index < m_values.size(); index++) {
- const RefPtr<CSSValue>& value = m_values.at(index);
+ const RefPtrWillBeMember<CSSValue>& value = m_values.at(index);
if (value && val && value->equals(*val))
return true;
}
return false;
}
-PassRefPtr<CSSValueList> CSSValueList::copy()
+PassRefPtrWillBeRawPtr<CSSValueList> CSSValueList::copy()
{
- RefPtr<CSSValueList> newList;
+ RefPtrWillBeRawPtr<CSSValueList> newList = nullptr;
switch (m_valueListSeparator) {
case SpaceSeparator:
newList = createSpaceSeparated();
@@ -127,9 +127,7 @@ String CSSValueList::customCSSText(CSSTextFormattingFlags formattingFlag) const
bool CSSValueList::equals(const CSSValueList& other) const
{
- // FIXME: the explicit Vector conversion copies into a temporary and is
- // wasteful.
- return m_valueListSeparator == other.m_valueListSeparator && compareCSSValueVector<CSSValue>(Vector<RefPtr<CSSValue> >(m_values), Vector<RefPtr<CSSValue> >(other.m_values));
+ return m_valueListSeparator == other.m_valueListSeparator && compareCSSValueVector(m_values, other.m_values);
}
bool CSSValueList::equals(const CSSValue& other) const
@@ -137,45 +135,10 @@ bool CSSValueList::equals(const CSSValue& other) const
if (m_values.size() != 1)
return false;
- const RefPtr<CSSValue>& value = m_values[0];
+ const RefPtrWillBeMember<CSSValue>& value = m_values[0];
return value && value->equals(other);
}
-String CSSValueList::customSerializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
-{
- StringBuilder result;
- String separator;
- switch (m_valueListSeparator) {
- case SpaceSeparator:
- separator = " ";
- break;
- case CommaSeparator:
- separator = ", ";
- break;
- case SlashSeparator:
- separator = " / ";
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- unsigned size = m_values.size();
- for (unsigned i = 0; i < size; i++) {
- if (!result.isEmpty())
- result.append(separator);
- result.append(m_values[i]->serializeResolvingVariables(variables));
- }
-
- return result.toString();
-}
-
-void CSSValueList::addSubresourceStyleURLs(ListHashSet<KURL>& urls, const StyleSheetContents* styleSheet) const
-{
- size_t size = m_values.size();
- for (size_t i = 0; i < size; ++i)
- m_values[i]->addSubresourceStyleURLs(urls, styleSheet);
-}
-
bool CSSValueList::hasFailedOrCanceledSubresources() const
{
for (unsigned i = 0; i < m_values.size(); ++i) {
@@ -194,9 +157,15 @@ CSSValueList::CSSValueList(const CSSValueList& cloneFrom)
m_values[i] = cloneFrom.m_values[i]->cloneForCSSOM();
}
-PassRefPtr<CSSValueList> CSSValueList::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSValueList> CSSValueList::cloneForCSSOM() const
+{
+ return adoptRefWillBeNoop(new CSSValueList(*this));
+}
+
+void CSSValueList::traceAfterDispatch(Visitor* visitor)
{
- return adoptRef(new CSSValueList(*this));
+ visitor->trace(m_values);
+ CSSValue::traceAfterDispatch(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSValueList.h b/chromium/third_party/WebKit/Source/core/css/CSSValueList.h
index 2f08014f190..2d34b4f9406 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSValueList.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSValueList.h
@@ -31,21 +31,21 @@ class CSSParserValueList;
class CSSValueList : public CSSValue {
public:
- static PassRefPtr<CSSValueList> createCommaSeparated()
+ static PassRefPtrWillBeRawPtr<CSSValueList> createCommaSeparated()
{
- return adoptRef(new CSSValueList(CommaSeparator));
+ return adoptRefWillBeNoop(new CSSValueList(CommaSeparator));
}
- static PassRefPtr<CSSValueList> createSpaceSeparated()
+ static PassRefPtrWillBeRawPtr<CSSValueList> createSpaceSeparated()
{
- return adoptRef(new CSSValueList(SpaceSeparator));
+ return adoptRefWillBeNoop(new CSSValueList(SpaceSeparator));
}
- static PassRefPtr<CSSValueList> createSlashSeparated()
+ static PassRefPtrWillBeRawPtr<CSSValueList> createSlashSeparated()
{
- return adoptRef(new CSSValueList(SlashSeparator));
+ return adoptRefWillBeNoop(new CSSValueList(SlashSeparator));
}
- static PassRefPtr<CSSValueList> createFromParserValueList(CSSParserValueList* list)
+ static PassRefPtrWillBeRawPtr<CSSValueList> createFromParserValueList(CSSParserValueList* list)
{
- return adoptRef(new CSSValueList(list));
+ return adoptRefWillBeNoop(new CSSValueList(list));
}
size_t length() const { return m_values.size(); }
@@ -53,22 +53,21 @@ public:
const CSSValue* item(size_t index) const { return index < m_values.size() ? m_values[index].get() : 0; }
CSSValue* itemWithoutBoundsCheck(size_t index) { return m_values[index].get(); }
- void append(PassRefPtr<CSSValue> value) { m_values.append(value); }
- void prepend(PassRefPtr<CSSValue> value) { m_values.prepend(value); }
+ void append(PassRefPtrWillBeRawPtr<CSSValue> value) { m_values.append(value); }
+ void prepend(PassRefPtrWillBeRawPtr<CSSValue> value) { m_values.prepend(value); }
bool removeAll(CSSValue*);
bool hasValue(CSSValue*) const;
- PassRefPtr<CSSValueList> copy();
+ PassRefPtrWillBeRawPtr<CSSValueList> copy();
String customCSSText(CSSTextFormattingFlags = QuoteCSSStringIfNeeded) const;
bool equals(const CSSValueList&) const;
bool equals(const CSSValue&) const;
- String customSerializeResolvingVariables(const HashMap<AtomicString, String>&) const;
-
- void addSubresourceStyleURLs(ListHashSet<KURL>&, const StyleSheetContents*) const;
bool hasFailedOrCanceledSubresources() const;
- PassRefPtr<CSSValueList> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<CSSValueList> cloneForCSSOM() const;
+
+ void traceAfterDispatch(Visitor*);
protected:
CSSValueList(ClassType, ValueListSeparator);
@@ -78,7 +77,7 @@ private:
explicit CSSValueList(ValueListSeparator);
explicit CSSValueList(CSSParserValueList*);
- Vector<RefPtr<CSSValue>, 4> m_values;
+ WillBeHeapVector<RefPtrWillBeMember<CSSValue>, 4> m_values;
};
DEFINE_CSS_VALUE_TYPE_CASTS(CSSValueList, isValueList());
@@ -86,6 +85,7 @@ DEFINE_CSS_VALUE_TYPE_CASTS(CSSValueList, isValueList());
// Objects of this class are intended to be stack-allocated and scoped to a single function.
// Please take care not to pass these around as they do hold onto a raw pointer.
class CSSValueListInspector {
+ STACK_ALLOCATED();
public:
CSSValueListInspector(CSSValue* value) : m_list((value && value->isValueList()) ? toCSSValueList(value) : 0) { }
CSSValue* item(size_t index) const { ASSERT_WITH_SECURITY_IMPLICATION(index < length()); return m_list->itemWithoutBoundsCheck(index); }
@@ -93,13 +93,14 @@ public:
CSSValue* second() const { return item(1); }
size_t length() const { return m_list ? m_list->length() : 0; }
private:
- CSSValueList* m_list;
+ RawPtrWillBeMember<CSSValueList> m_list;
};
// Wrapper that can be used to iterate over any CSSValue. Non-list values and 0 behave as zero-length lists.
// Objects of this class are intended to be stack-allocated and scoped to a single function.
// Please take care not to pass these around as they do hold onto a raw pointer.
class CSSValueListIterator {
+ STACK_ALLOCATED();
public:
CSSValueListIterator(CSSValue* value) : m_inspector(value), m_position(0) { }
bool hasMore() const { return m_position < m_inspector.length(); }
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSValuePool.cpp b/chromium/third_party/WebKit/Source/core/css/CSSValuePool.cpp
index 4550915eba4..3d914d33198 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSValuePool.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSValuePool.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/css/CSSValuePool.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSValueList.h"
#include "core/rendering/style/RenderStyle.h"
@@ -34,8 +34,13 @@ namespace WebCore {
CSSValuePool& cssValuePool()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<CSSValuePool>, pool, (new CSSValuePool()));
+ return *pool;
+#else
DEFINE_STATIC_LOCAL(CSSValuePool, pool, ());
return pool;
+#endif // ENABLE(OILPAN)
}
CSSValuePool::CSSValuePool()
@@ -46,9 +51,13 @@ CSSValuePool::CSSValuePool()
, m_colorWhite(CSSPrimitiveValue::createColor(Color::white))
, m_colorBlack(CSSPrimitiveValue::createColor(Color::black))
{
+ m_identifierValueCache.resize(numCSSValueKeywords);
+ m_pixelValueCache.resize(maximumCacheableIntegerValue + 1);
+ m_percentValueCache.resize(maximumCacheableIntegerValue + 1);
+ m_numberValueCache.resize(maximumCacheableIntegerValue + 1);
}
-PassRefPtr<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSValueID ident)
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSValueID ident)
{
if (ident <= 0)
return CSSPrimitiveValue::createIdentifier(ident);
@@ -58,12 +67,12 @@ PassRefPtr<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSValueID ide
return m_identifierValueCache[ident];
}
-PassRefPtr<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSPropertyID ident)
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSPropertyID ident)
{
return CSSPrimitiveValue::createIdentifier(ident);
}
-PassRefPtr<CSSPrimitiveValue> CSSValuePool::createColorValue(unsigned rgbValue)
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createColorValue(unsigned rgbValue)
{
// These are the empty and deleted values of the hash table.
if (rgbValue == Color::transparent)
@@ -79,15 +88,18 @@ PassRefPtr<CSSPrimitiveValue> CSSValuePool::createColorValue(unsigned rgbValue)
if (m_colorValueCache.size() > maximumColorCacheSize)
m_colorValueCache.clear();
- RefPtr<CSSPrimitiveValue> dummyValue;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> dummyValue = nullptr;
ColorValueCache::AddResult entry = m_colorValueCache.add(rgbValue, dummyValue);
if (entry.isNewEntry)
- entry.iterator->value = CSSPrimitiveValue::createColor(rgbValue);
- return entry.iterator->value;
+ entry.storedValue->value = CSSPrimitiveValue::createColor(rgbValue);
+ return entry.storedValue->value;
}
-PassRefPtr<CSSPrimitiveValue> CSSValuePool::createValue(double value, CSSPrimitiveValue::UnitTypes type)
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createValue(double value, CSSPrimitiveValue::UnitType type)
{
+ if (std::isinf(value))
+ value = 0;
+
if (value < 0 || value > maximumCacheableIntegerValue)
return CSSPrimitiveValue::create(value, type);
@@ -95,50 +107,65 @@ PassRefPtr<CSSPrimitiveValue> CSSValuePool::createValue(double value, CSSPrimiti
if (value != intValue)
return CSSPrimitiveValue::create(value, type);
- RefPtr<CSSPrimitiveValue>* cache;
switch (type) {
case CSSPrimitiveValue::CSS_PX:
- cache = m_pixelValueCache;
- break;
+ if (!m_pixelValueCache[intValue])
+ m_pixelValueCache[intValue] = CSSPrimitiveValue::create(value, type);
+ return m_pixelValueCache[intValue];
case CSSPrimitiveValue::CSS_PERCENTAGE:
- cache = m_percentValueCache;
- break;
+ if (!m_percentValueCache[intValue])
+ m_percentValueCache[intValue] = CSSPrimitiveValue::create(value, type);
+ return m_percentValueCache[intValue];
case CSSPrimitiveValue::CSS_NUMBER:
- cache = m_numberValueCache;
- break;
+ if (!m_numberValueCache[intValue])
+ m_numberValueCache[intValue] = CSSPrimitiveValue::create(value, type);
+ return m_numberValueCache[intValue];
default:
return CSSPrimitiveValue::create(value, type);
}
-
- if (!cache[intValue])
- cache[intValue] = CSSPrimitiveValue::create(value, type);
- return cache[intValue];
}
-PassRefPtr<CSSPrimitiveValue> CSSValuePool::createValue(const Length& value, const RenderStyle& style)
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createValue(const Length& value, const RenderStyle& style)
{
return CSSPrimitiveValue::create(value, style.effectiveZoom());
}
-PassRefPtr<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String& familyName)
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String& familyName)
{
- RefPtr<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, 0).iterator->value;
+ RefPtrWillBeMember<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, nullptr).storedValue->value;
if (!value)
value = CSSPrimitiveValue::create(familyName, CSSPrimitiveValue::CSS_STRING);
return value;
}
-PassRefPtr<CSSValueList> CSSValuePool::createFontFaceValue(const AtomicString& string)
+PassRefPtrWillBeRawPtr<CSSValueList> CSSValuePool::createFontFaceValue(const AtomicString& string)
{
// Just wipe out the cache and start rebuilding if it gets too big.
const unsigned maximumFontFaceCacheSize = 128;
if (m_fontFaceValueCache.size() > maximumFontFaceCacheSize)
m_fontFaceValueCache.clear();
- RefPtr<CSSValueList>& value = m_fontFaceValueCache.add(string, 0).iterator->value;
+ RefPtrWillBeMember<CSSValueList>& value = m_fontFaceValueCache.add(string, nullptr).storedValue->value;
if (!value)
- value = CSSParser::parseFontFaceValue(string);
+ value = BisonCSSParser::parseFontFaceValue(string);
return value;
}
+void CSSValuePool::trace(Visitor* visitor)
+{
+ visitor->trace(m_inheritedValue);
+ visitor->trace(m_implicitInitialValue);
+ visitor->trace(m_explicitInitialValue);
+ visitor->trace(m_identifierValueCache);
+ visitor->trace(m_colorValueCache);
+ visitor->trace(m_colorTransparent);
+ visitor->trace(m_colorWhite);
+ visitor->trace(m_colorBlack);
+ visitor->trace(m_pixelValueCache);
+ visitor->trace(m_percentValueCache);
+ visitor->trace(m_numberValueCache);
+ visitor->trace(m_fontFaceValueCache);
+ visitor->trace(m_fontFamilyValueCache);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSValuePool.h b/chromium/third_party/WebKit/Source/core/css/CSSValuePool.h
index 75b8984a1f7..87eacf6d385 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSValuePool.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSValuePool.h
@@ -26,8 +26,8 @@
#ifndef CSSValuePool_h
#define CSSValuePool_h
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
#include "core/css/CSSInheritedValue.h"
#include "core/css/CSSInitialValue.h"
#include "core/css/CSSPrimitiveValue.h"
@@ -39,48 +39,50 @@ namespace WebCore {
class CSSValueList;
-class CSSValuePool {
- WTF_MAKE_FAST_ALLOCATED;
+class CSSValuePool : public NoBaseWillBeGarbageCollected<CSSValuePool> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- PassRefPtr<CSSValueList> createFontFaceValue(const AtomicString&);
- PassRefPtr<CSSPrimitiveValue> createFontFamilyValue(const String&);
- PassRefPtr<CSSInheritedValue> createInheritedValue() { return m_inheritedValue; }
- PassRefPtr<CSSInitialValue> createImplicitInitialValue() { return m_implicitInitialValue; }
- PassRefPtr<CSSInitialValue> createExplicitInitialValue() { return m_explicitInitialValue; }
- PassRefPtr<CSSPrimitiveValue> createIdentifierValue(CSSValueID identifier);
- PassRefPtr<CSSPrimitiveValue> createIdentifierValue(CSSPropertyID identifier);
- PassRefPtr<CSSPrimitiveValue> createColorValue(unsigned rgbValue);
- PassRefPtr<CSSPrimitiveValue> createValue(double value, CSSPrimitiveValue::UnitTypes);
- PassRefPtr<CSSPrimitiveValue> createValue(const String& value, CSSPrimitiveValue::UnitTypes type) { return CSSPrimitiveValue::create(value, type); }
- PassRefPtr<CSSPrimitiveValue> createValue(const Length& value, const RenderStyle&);
- PassRefPtr<CSSPrimitiveValue> createValue(const Length& value, float zoom) { return CSSPrimitiveValue::create(value, zoom); }
- template<typename T> static PassRefPtr<CSSPrimitiveValue> createValue(T value) { return CSSPrimitiveValue::create(value); }
+ PassRefPtrWillBeRawPtr<CSSValueList> createFontFaceValue(const AtomicString&);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createFontFamilyValue(const String&);
+ PassRefPtrWillBeRawPtr<CSSInheritedValue> createInheritedValue() { return m_inheritedValue; }
+ PassRefPtrWillBeRawPtr<CSSInitialValue> createImplicitInitialValue() { return m_implicitInitialValue; }
+ PassRefPtrWillBeRawPtr<CSSInitialValue> createExplicitInitialValue() { return m_explicitInitialValue; }
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createIdentifierValue(CSSValueID identifier);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createIdentifierValue(CSSPropertyID identifier);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createColorValue(unsigned rgbValue);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createValue(double value, CSSPrimitiveValue::UnitType);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createValue(const String& value, CSSPrimitiveValue::UnitType type) { return CSSPrimitiveValue::create(value, type); }
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createValue(const Length& value, const RenderStyle&);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createValue(const Length& value, float zoom) { return CSSPrimitiveValue::create(value, zoom); }
+ template<typename T> static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createValue(T value) { return CSSPrimitiveValue::create(value); }
+
+ void trace(Visitor*);
private:
CSSValuePool();
- RefPtr<CSSInheritedValue> m_inheritedValue;
- RefPtr<CSSInitialValue> m_implicitInitialValue;
- RefPtr<CSSInitialValue> m_explicitInitialValue;
+ RefPtrWillBeMember<CSSInheritedValue> m_inheritedValue;
+ RefPtrWillBeMember<CSSInitialValue> m_implicitInitialValue;
+ RefPtrWillBeMember<CSSInitialValue> m_explicitInitialValue;
- RefPtr<CSSPrimitiveValue> m_identifierValueCache[numCSSValueKeywords];
+ WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue>, numCSSValueKeywords> m_identifierValueCache;
- typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue> > ColorValueCache;
+ typedef WillBeHeapHashMap<unsigned, RefPtrWillBeMember<CSSPrimitiveValue> > ColorValueCache;
ColorValueCache m_colorValueCache;
- RefPtr<CSSPrimitiveValue> m_colorTransparent;
- RefPtr<CSSPrimitiveValue> m_colorWhite;
- RefPtr<CSSPrimitiveValue> m_colorBlack;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_colorTransparent;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_colorWhite;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_colorBlack;
static const int maximumCacheableIntegerValue = 255;
- RefPtr<CSSPrimitiveValue> m_pixelValueCache[maximumCacheableIntegerValue + 1];
- RefPtr<CSSPrimitiveValue> m_percentValueCache[maximumCacheableIntegerValue + 1];
- RefPtr<CSSPrimitiveValue> m_numberValueCache[maximumCacheableIntegerValue + 1];
+ WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue>, maximumCacheableIntegerValue + 1> m_pixelValueCache;
+ WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue>, maximumCacheableIntegerValue + 1> m_percentValueCache;
+ WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue>, maximumCacheableIntegerValue + 1> m_numberValueCache;
- typedef HashMap<AtomicString, RefPtr<CSSValueList> > FontFaceValueCache;
+ typedef WillBeHeapHashMap<AtomicString, RefPtrWillBeMember<CSSValueList> > FontFaceValueCache;
FontFaceValueCache m_fontFaceValueCache;
- typedef HashMap<String, RefPtr<CSSPrimitiveValue> > FontFamilyValueCache;
+ typedef WillBeHeapHashMap<String, RefPtrWillBeMember<CSSPrimitiveValue> > FontFamilyValueCache;
FontFamilyValueCache m_fontFamilyValueCache;
friend CSSValuePool& cssValuePool();
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSVariableValue.h b/chromium/third_party/WebKit/Source/core/css/CSSVariableValue.h
deleted file mode 100644
index 525581ae19c..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSVariableValue.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSVariableValue_h
-#define CSSVariableValue_h
-
-#include "CSSPropertyNames.h"
-#include "core/css/CSSParserValues.h"
-#include "core/css/CSSValue.h"
-
-namespace WebCore {
-
-class CSSVariableValue : public CSSValue {
-public:
- static PassRefPtr<CSSVariableValue> create(const AtomicString& name, const String& value)
- {
- return adoptRef(new CSSVariableValue(name, value));
- }
-
- const AtomicString& name() const { return m_name; }
- const String& value() const { return m_value; }
-
- bool equals(const CSSVariableValue& other) const { return m_name == other.m_name && m_value == other.m_value; }
-
-private:
- CSSVariableValue(const AtomicString& name, const String& value)
- : CSSValue(VariableClass)
- , m_name(name)
- , m_value(value)
- {
- }
-
- const AtomicString m_name;
- const String m_value;
-};
-
-DEFINE_CSS_VALUE_TYPE_CASTS(CSSVariableValue, isVariableValue());
-
-}
-
-#endif /* CSSVariableValue_h */
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSVariablesIterator.h b/chromium/third_party/WebKit/Source/core/css/CSSVariablesIterator.h
deleted file mode 100644
index edfe3a7e9ed..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSVariablesIterator.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSVariablesIterator_h
-#define CSSVariablesIterator_h
-
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-class CSSVariablesIterator : public RefCounted<CSSVariablesIterator> {
-public:
- virtual ~CSSVariablesIterator() { }
- virtual void advance() = 0;
- virtual bool atEnd() const = 0;
- virtual AtomicString name() const = 0;
- virtual String value() const = 0;
- virtual void addedVariable(const AtomicString& name) { }
- virtual void removedVariable(const AtomicString& name) { }
- virtual void clearedVariables() { }
-};
-
-}
-
-#endif // CSSVariablesIterator_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.cpp b/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.cpp
deleted file mode 100644
index eb6232dd43a..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/css/CSSVariablesMap.h"
-
-#include "core/css/CSSStyleDeclaration.h"
-
-namespace WebCore {
-
-unsigned CSSVariablesMap::size() const
-{
- if (m_styleDeclaration)
- return m_styleDeclaration->variableCount();
- return 0;
-}
-
-String CSSVariablesMap::get(const AtomicString& name) const
-{
- if (m_styleDeclaration)
- return m_styleDeclaration->variableValue(name);
- return String();
-}
-
-bool CSSVariablesMap::has(const AtomicString& name) const
-{
- if (m_styleDeclaration)
- return !get(name).isEmpty();
- return false;
-}
-
-void CSSVariablesMap::set(const AtomicString& name, const String& value, ExceptionState& exceptionState)
-{
- if (!m_styleDeclaration)
- return;
- if (m_styleDeclaration->setVariableValue(name, value, exceptionState)) {
- Iterators::iterator end = m_activeIterators.end();
- for (Iterators::iterator it = m_activeIterators.begin(); it != end; ++it)
- (*it)->addedVariable(name);
- }
-}
-
-bool CSSVariablesMap::remove(const AtomicString& name)
-{
- if (!m_styleDeclaration)
- return false;
- if (m_styleDeclaration->removeVariable(name)) {
- Iterators::iterator end = m_activeIterators.end();
- for (Iterators::iterator it = m_activeIterators.begin(); it != end; ++it)
- (*it)->removedVariable(name);
- return true;
- }
- return false;
-}
-
-void CSSVariablesMap::clear(ExceptionState& exceptionState)
-{
- if (!m_styleDeclaration)
- return;
- if (m_styleDeclaration->clearVariables(exceptionState)) {
- Iterators::iterator end = m_activeIterators.end();
- for (Iterators::iterator it = m_activeIterators.begin(); it != end; ++it)
- (*it)->clearedVariables();
- }
-}
-
-void CSSVariablesMap::forEach(PassOwnPtr<CSSVariablesMapForEachCallback> callback, ScriptValue& thisArg) const
-{
- forEach(callback, &thisArg);
-}
-
-void CSSVariablesMap::forEach(PassOwnPtr<CSSVariablesMapForEachCallback> callback) const
-{
- forEach(callback, 0);
-}
-
-void CSSVariablesMap::forEach(PassOwnPtr<CSSVariablesMapForEachCallback> callback, ScriptValue* thisArg) const
-{
- if (!m_styleDeclaration)
- return;
- RefPtr<CSSVariablesIterator> iterator = m_styleDeclaration->variablesIterator();
- m_activeIterators.append(iterator.get());
- while (!iterator->atEnd()) {
- String name = iterator->name();
- String value = iterator->value();
- if (thisArg)
- callback->handleItem(*thisArg, value, name, const_cast<CSSVariablesMap*>(this));
- else
- callback->handleItem(value, name, const_cast<CSSVariablesMap*>(this));
- iterator->advance();
- }
- ASSERT(m_activeIterators.last() == iterator.get());
- m_activeIterators.removeLast();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.h b/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.h
deleted file mode 100644
index 12b1bee2845..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSVariablesMap_h
-#define CSSVariablesMap_h
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/CSSVariablesMapForEachCallback.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class CSSStyleDeclaration;
-class CSSVariablesIterator;
-class ExceptionState;
-
-class CSSVariablesMap FINAL : public RefCounted<CSSVariablesMap> {
-public:
- static PassRefPtr<CSSVariablesMap> create(CSSStyleDeclaration* styleDeclaration)
- {
- return adoptRef(new CSSVariablesMap(styleDeclaration));
- }
-
- unsigned size() const;
- String get(const AtomicString& name) const;
- bool has(const AtomicString& name) const;
- void set(const AtomicString& name, const String& value, ExceptionState&);
- bool remove(const AtomicString& name);
- void clear(ExceptionState&);
- void forEach(PassOwnPtr<CSSVariablesMapForEachCallback>, ScriptValue& thisArg) const;
- void forEach(PassOwnPtr<CSSVariablesMapForEachCallback>) const;
-
- void clearStyleDeclaration() { m_styleDeclaration = 0; }
-
-private:
- explicit CSSVariablesMap(CSSStyleDeclaration* styleDeclaration)
- : m_styleDeclaration(styleDeclaration)
- {
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- }
-
- void forEach(PassOwnPtr<CSSVariablesMapForEachCallback>, ScriptValue* thisArg) const;
-
- CSSStyleDeclaration* m_styleDeclaration;
- typedef Vector<CSSVariablesIterator*> Iterators;
- mutable Iterators m_activeIterators;
-};
-
-} // namespace WebCore
-
-#endif // CSSVariablesMap_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.idl b/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.idl
deleted file mode 100644
index 3c88025beb9..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMap.idl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-interface CSSVariablesMap {
- readonly attribute unsigned long size;
- DOMString get(DOMString name);
- boolean has(DOMString name);
- [RaisesException] void set(DOMString name, DOMString value);
- [ImplementedAs=remove] boolean delete(DOMString name);
- [RaisesException] void clear();
- void forEach(CSSVariablesMapForEachCallback callback, optional any thisArg);
-};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMapForEachCallback.h b/chromium/third_party/WebKit/Source/core/css/CSSVariablesMapForEachCallback.h
deleted file mode 100644
index 001ccbdcf74..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMapForEachCallback.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSVariablesMapForEachCallback_h
-#define CSSVariablesMapForEachCallback_h
-
-#include "bindings/v8/ScriptValue.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class CSSVariablesMap;
-
-class CSSVariablesMapForEachCallback {
-public:
- virtual ~CSSVariablesMapForEachCallback() { }
- virtual void handleItem(ScriptValue thisValue, const String& value, const String& name, CSSVariablesMap*) = 0;
- virtual void handleItem(const String& value, const String& name, CSSVariablesMap*) = 0;
-};
-
-} // namespace WebCore
-
-#endif // CSSVariablesMapForEachCallback_h
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMapForEachCallback.idl b/chromium/third_party/WebKit/Source/core/css/CSSVariablesMapForEachCallback.idl
deleted file mode 100644
index 11a6cfcb581..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/CSSVariablesMapForEachCallback.idl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-callback interface CSSVariablesMapForEachCallback {
- [CallWith=ThisValue] void handleItem(DOMString value, DOMString name, CSSVariablesMap map);
- void handleItem(DOMString value, DOMString name, CSSVariablesMap map);
-};
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSViewportRule.cpp b/chromium/third_party/WebKit/Source/core/css/CSSViewportRule.cpp
index a5d1f0e9cf9..9c56ee4a48b 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSViewportRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/CSSViewportRule.cpp
@@ -46,8 +46,10 @@ CSSViewportRule::CSSViewportRule(StyleRuleViewport* viewportRule, CSSStyleSheet*
CSSViewportRule::~CSSViewportRule()
{
+#if !ENABLE(OILPAN)
if (m_propertiesCSSOMWrapper)
m_propertiesCSSOMWrapper->clearParentRule();
+#endif
}
CSSStyleDeclaration* CSSViewportRule::style() const
@@ -63,7 +65,7 @@ String CSSViewportRule::cssText() const
StringBuilder result;
result.appendLiteral("@viewport { ");
- String decls = m_viewportRule->properties()->asText();
+ String decls = m_viewportRule->properties().asText();
result.append(decls);
if (!decls.isEmpty())
result.append(' ');
@@ -81,4 +83,11 @@ void CSSViewportRule::reattach(StyleRuleBase* rule)
m_propertiesCSSOMWrapper->reattach(m_viewportRule->mutableProperties());
}
+void CSSViewportRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_viewportRule);
+ visitor->trace(m_propertiesCSSOMWrapper);
+ CSSRule::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/CSSViewportRule.h b/chromium/third_party/WebKit/Source/core/css/CSSViewportRule.h
index 2ef8c81511f..20a84b5c73a 100644
--- a/chromium/third_party/WebKit/Source/core/css/CSSViewportRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/CSSViewportRule.h
@@ -32,6 +32,7 @@
#define CSSViewportRule_h
#include "core/css/CSSRule.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -39,13 +40,13 @@ class CSSStyleDeclaration;
class StyleRuleViewport;
class StyleRuleCSSStyleDeclaration;
-class CSSViewportRule: public CSSRule {
+class CSSViewportRule FINAL: public CSSRule {
public:
- static PassRefPtr<CSSViewportRule> create(StyleRuleViewport* viewportRule, CSSStyleSheet* sheet)
+ static PassRefPtrWillBeRawPtr<CSSViewportRule> create(StyleRuleViewport* viewportRule, CSSStyleSheet* sheet)
{
- return adoptRef(new CSSViewportRule(viewportRule, sheet));
+ return adoptRefWillBeNoop(new CSSViewportRule(viewportRule, sheet));
}
- ~CSSViewportRule();
+ virtual ~CSSViewportRule();
virtual CSSRule::Type type() const OVERRIDE { return VIEWPORT_RULE; }
virtual String cssText() const OVERRIDE;
@@ -53,11 +54,13 @@ public:
CSSStyleDeclaration* style() const;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CSSViewportRule(StyleRuleViewport*, CSSStyleSheet*);
- RefPtr<StyleRuleViewport> m_viewportRule;
- mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
+ RefPtrWillBeMember<StyleRuleViewport> m_viewportRule;
+ mutable RefPtrWillBeMember<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
};
DEFINE_CSS_RULE_TYPE_CASTS(CSSViewportRule, VIEWPORT_RULE);
diff --git a/chromium/third_party/WebKit/Source/core/css/Counter.cpp b/chromium/third_party/WebKit/Source/core/css/Counter.cpp
new file mode 100644
index 00000000000..d012b1a6c24
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/Counter.cpp
@@ -0,0 +1,17 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/Counter.h"
+
+namespace WebCore {
+
+void Counter::trace(Visitor* visitor)
+{
+ visitor->trace(m_identifier);
+ visitor->trace(m_listStyle);
+ visitor->trace(m_separator);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/Counter.h b/chromium/third_party/WebKit/Source/core/css/Counter.h
index cb73a3dd36d..68b3a7360fb 100644
--- a/chromium/third_party/WebKit/Source/core/css/Counter.h
+++ b/chromium/third_party/WebKit/Source/core/css/Counter.h
@@ -26,11 +26,11 @@
namespace WebCore {
-class Counter : public RefCounted<Counter> {
+class Counter : public RefCountedWillBeGarbageCollected<Counter> {
public:
- static PassRefPtr<Counter> create(PassRefPtr<CSSPrimitiveValue> identifier, PassRefPtr<CSSPrimitiveValue> listStyle, PassRefPtr<CSSPrimitiveValue> separator)
+ static PassRefPtrWillBeRawPtr<Counter> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> identifier, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> listStyle, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> separator)
{
- return adoptRef(new Counter(identifier, listStyle, separator));
+ return adoptRefWillBeNoop(new Counter(identifier, listStyle, separator));
}
String identifier() const { return m_identifier ? m_identifier->getStringValue() : String(); }
@@ -39,9 +39,9 @@ public:
CSSValueID listStyleIdent() const { return m_listStyle ? m_listStyle->getValueID() : CSSValueInvalid; }
- void setIdentifier(PassRefPtr<CSSPrimitiveValue> identifier) { m_identifier = identifier; }
- void setListStyle(PassRefPtr<CSSPrimitiveValue> listStyle) { m_listStyle = listStyle; }
- void setSeparator(PassRefPtr<CSSPrimitiveValue> separator) { m_separator = separator; }
+ void setIdentifier(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> identifier) { m_identifier = identifier; }
+ void setListStyle(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> listStyle) { m_listStyle = listStyle; }
+ void setSeparator(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> separator) { m_separator = separator; }
bool equals(const Counter& other) const
{
@@ -50,24 +50,26 @@ public:
&& separator() == other.separator();
}
- PassRefPtr<Counter> cloneForCSSOM() const
+ PassRefPtrWillBeRawPtr<Counter> cloneForCSSOM() const
{
- return create(m_identifier ? m_identifier->cloneForCSSOM() : 0
- , m_listStyle ? m_listStyle->cloneForCSSOM() : 0
- , m_separator ? m_separator->cloneForCSSOM() : 0);
+ return create(m_identifier ? m_identifier->cloneForCSSOM() : nullptr
+ , m_listStyle ? m_listStyle->cloneForCSSOM() : nullptr
+ , m_separator ? m_separator->cloneForCSSOM() : nullptr);
}
+ void trace(Visitor*);
+
private:
- Counter(PassRefPtr<CSSPrimitiveValue> identifier, PassRefPtr<CSSPrimitiveValue> listStyle, PassRefPtr<CSSPrimitiveValue> separator)
+ Counter(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> identifier, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> listStyle, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> separator)
: m_identifier(identifier)
, m_listStyle(listStyle)
, m_separator(separator)
{
}
- RefPtr<CSSPrimitiveValue> m_identifier; // string
- RefPtr<CSSPrimitiveValue> m_listStyle; // ident
- RefPtr<CSSPrimitiveValue> m_separator; // string
+ RefPtrWillBeMember<CSSPrimitiveValue> m_identifier; // string
+ RefPtrWillBeMember<CSSPrimitiveValue> m_listStyle; // ident
+ RefPtrWillBeMember<CSSPrimitiveValue> m_separator; // string
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/Counter.idl b/chromium/third_party/WebKit/Source/core/css/Counter.idl
index 7006aa5001d..886436eea9d 100644
--- a/chromium/third_party/WebKit/Source/core/css/Counter.idl
+++ b/chromium/third_party/WebKit/Source/core/css/Counter.idl
@@ -19,6 +19,7 @@
// Introduced in DOM Level 2:
[
+ WillBeGarbageCollected
] interface Counter {
readonly attribute DOMString identifier;
readonly attribute DOMString listStyle;
diff --git a/chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp b/chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp
index 248ddcc4648..d0edccaa075 100644
--- a/chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.cpp
@@ -30,16 +30,16 @@
#include "config.h"
#include "core/css/DOMWindowCSS.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/RuntimeCSSEnabled.h"
#include "core/css/StylePropertySet.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-PassRefPtr<DOMWindowCSS> DOMWindowCSS::create()
+PassRefPtrWillBeRawPtr<DOMWindowCSS> DOMWindowCSS::create()
{
- return adoptRef(new DOMWindowCSS());
+ return adoptRefWillBeNoop(new DOMWindowCSS());
}
static String valueWithoutImportant(const String& value)
@@ -65,7 +65,7 @@ bool DOMWindowCSS::supports(const String& property, const String& value) const
if (!RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID))
return false;
- // CSSParser::parseValue() won't work correctly if !important is present,
+ // BisonCSSParser::parseValue() won't work correctly if !important is present,
// so just get rid of it. It doesn't matter to supports() if it's actually
// there or not, provided how it's specified in the value is correct.
String normalizedValue = value.stripWhiteSpace().simplifyWhiteSpace();
@@ -74,14 +74,14 @@ bool DOMWindowCSS::supports(const String& property, const String& value) const
if (normalizedValue.isEmpty())
return false;
- RefPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
- return CSSParser::parseValue(dummyStyle.get(), propertyID, normalizedValue, false, HTMLStandardMode, 0);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
+ return BisonCSSParser::parseValue(dummyStyle.get(), propertyID, normalizedValue, false, HTMLStandardMode, 0);
}
bool DOMWindowCSS::supports(const String& conditionText) const
{
- CSSParserContext context(HTMLStandardMode);
- CSSParser parser(context);
+ CSSParserContext context(HTMLStandardMode, 0);
+ BisonCSSParser parser(context);
return parser.parseSupportsCondition(conditionText);
}
diff --git a/chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.h b/chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.h
index e6c6d19b2dc..25a7eb6f9e7 100644
--- a/chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.h
+++ b/chromium/third_party/WebKit/Source/core/css/DOMWindowCSS.h
@@ -30,19 +30,22 @@
#ifndef DOMWindowCSS_h
#define DOMWindowCSS_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class DOMWindowCSS : public RefCounted<DOMWindowCSS> {
+class DOMWindowCSS : public RefCountedWillBeGarbageCollected<DOMWindowCSS> {
public:
- static PassRefPtr<DOMWindowCSS> create();
+ static PassRefPtrWillBeRawPtr<DOMWindowCSS> create();
bool supports(const String& property, const String& value) const;
bool supports(const String& conditionText) const;
+ void trace(Visitor*) { }
+
private:
DOMWindowCSS()
{
diff --git a/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.cpp b/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.cpp
index 408668f70fc..2df6c3e27bc 100644
--- a/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.cpp
@@ -30,7 +30,7 @@
namespace WebCore {
-PassRefPtr<FontFaceSet> DocumentFontFaceSet::fonts(Document* document)
+PassRefPtrWillBeRawPtr<FontFaceSet> DocumentFontFaceSet::fonts(Document& document)
{
return FontFaceSet::from(document);
}
diff --git a/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.h b/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.h
index 910d878291e..b1ecf426d14 100644
--- a/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.h
+++ b/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.h
@@ -26,6 +26,7 @@
#ifndef DocumentFontFaceSet_h
#define DocumentFontFaceSet_h
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
@@ -35,7 +36,7 @@ class FontFaceSet;
class DocumentFontFaceSet {
public:
- static PassRefPtr<FontFaceSet> fonts(Document*);
+ static PassRefPtrWillBeRawPtr<FontFaceSet> fonts(Document&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.idl b/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.idl
index 820fdc899e9..6ed56abb6fb 100644
--- a/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.idl
+++ b/chromium/third_party/WebKit/Source/core/css/DocumentFontFaceSet.idl
@@ -28,6 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-partial interface Document {
- [RuntimeEnabled=FontLoadEvents] readonly attribute FontFaceSet fonts;
+[
+ RuntimeEnabled=FontLoadEvents,
+] partial interface Document {
+ [MeasureAs=DocumentFonts] readonly attribute FontFaceSet fonts;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/DragUpdateTest.cpp b/chromium/third_party/WebKit/Source/core/css/DragUpdateTest.cpp
new file mode 100644
index 00000000000..c801b6b11bc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/DragUpdateTest.cpp
@@ -0,0 +1,69 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/Element.h"
+#include "core/frame/FrameView.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/HTMLElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+TEST(DragUpdateTest, AffectedByDragUpdate)
+{
+ // Check that when dragging the div in the document below, you only get a
+ // single element style recalc.
+
+ OwnPtr<DummyPageHolder> dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+ HTMLDocument* document = toHTMLDocument(&dummyPageHolder->document());
+ document->documentElement()->setInnerHTML("<style>div {width:100px;height:100px} div:-webkit-drag { background-color: green }</style>"
+ "<div>"
+ "<span></span>"
+ "<span></span>"
+ "<span></span>"
+ "<span></span>"
+ "</div>", ASSERT_NO_EXCEPTION);
+
+ document->view()->updateLayoutAndStyleIfNeededRecursive();
+ unsigned startCount = document->styleEngine()->resolverAccessCount();
+
+ document->documentElement()->renderer()->updateDragState(true);
+ document->view()->updateLayoutAndStyleIfNeededRecursive();
+
+ unsigned accessCount = document->styleEngine()->resolverAccessCount() - startCount;
+
+ ASSERT_EQ(1U, accessCount);
+}
+
+TEST(DragUpdateTest, ChildrenOrSiblingsAffectedByDragUpdate)
+{
+ // Check that when dragging the div in the document below, you get a
+ // full subtree style recalc.
+
+ OwnPtr<DummyPageHolder> dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+ HTMLDocument* document = toHTMLDocument(&dummyPageHolder->document());
+ document->documentElement()->setInnerHTML("<style>div {width:100px;height:100px} div:-webkit-drag span { background-color: green }</style>"
+ "<div>"
+ "<span></span>"
+ "<span></span>"
+ "<span></span>"
+ "<span></span>"
+ "</div>", ASSERT_NO_EXCEPTION);
+
+ document->updateLayout();
+ unsigned startCount = document->styleEngine()->resolverAccessCount();
+
+ document->documentElement()->renderer()->updateDragState(true);
+ document->updateLayout();
+
+ unsigned accessCount = document->styleEngine()->resolverAccessCount() - startCount;
+
+ ASSERT_EQ(5U, accessCount);
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp b/chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp
index 4fdd44c8eb4..79ef923b697 100644
--- a/chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.cpp
@@ -29,31 +29,32 @@
#include "config.h"
#include "core/css/ElementRuleCollector.h"
+#include "core/css/CSSImportRule.h"
+#include "core/css/CSSKeyframesRule.h"
+#include "core/css/CSSMediaRule.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSSelector.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/CSSStyleSheet.h"
-#include "core/css/SelectorCheckerFastPath.h"
+#include "core/css/CSSSupportsRule.h"
#include "core/css/SiblingTraversalStrategies.h"
#include "core/css/StylePropertySet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/shadow/ShadowRoot.h"
-#include "core/rendering/RenderRegion.h"
+#include "core/rendering/style/StyleInheritedData.h"
namespace WebCore {
ElementRuleCollector::ElementRuleCollector(const ElementResolveContext& context,
- const SelectorFilter& filter, RenderStyle* style, ShouldIncludeStyleSheetInCSSOMWrapper includeStyleSheet)
+ const SelectorFilter& filter, RenderStyle* style)
: m_context(context)
, m_selectorFilter(filter)
, m_style(style)
- , m_regionForStyling(0)
, m_pseudoStyleRequest(NOPSEUDO)
, m_mode(SelectorChecker::ResolvingStyle)
, m_canUseFastReject(m_selectorFilter.parentStackIsConsistent(context.parentNode()))
, m_sameOriginOnly(false)
, m_matchingUARules(false)
- , m_includeStyleSheet(includeStyleSheet)
{ }
ElementRuleCollector::~ElementRuleCollector()
@@ -65,23 +66,23 @@ MatchResult& ElementRuleCollector::matchedResult()
return m_result;
}
-PassRefPtr<StyleRuleList> ElementRuleCollector::matchedStyleRuleList()
+PassRefPtrWillBeRawPtr<StyleRuleList> ElementRuleCollector::matchedStyleRuleList()
{
ASSERT(m_mode == SelectorChecker::CollectingStyleRules);
return m_styleRuleList.release();
}
-PassRefPtr<CSSRuleList> ElementRuleCollector::matchedCSSRuleList()
+PassRefPtrWillBeRawPtr<CSSRuleList> ElementRuleCollector::matchedCSSRuleList()
{
ASSERT(m_mode == SelectorChecker::CollectingCSSRules);
return m_cssRuleList.release();
}
-inline void ElementRuleCollector::addMatchedRule(const RuleData* rule, unsigned specificity, CascadeScope cascadeScope, CascadeOrder cascadeOrder, unsigned styleSheetIndex)
+inline void ElementRuleCollector::addMatchedRule(const RuleData* rule, unsigned specificity, CascadeScope cascadeScope, CascadeOrder cascadeOrder, unsigned styleSheetIndex, const CSSStyleSheet* parentStyleSheet)
{
if (!m_matchedRules)
- m_matchedRules = adoptPtr(new Vector<MatchedRule, 32>);
- m_matchedRules->append(MatchedRule(rule, specificity, cascadeScope, cascadeOrder, styleSheetIndex));
+ m_matchedRules = adoptPtrWillBeNoop(new WillBeHeapVector<MatchedRule, 32>);
+ m_matchedRules->append(MatchedRule(rule, specificity, cascadeScope, cascadeOrder, styleSheetIndex, parentStyleSheet));
}
void ElementRuleCollector::clearMatchedRules()
@@ -129,10 +130,7 @@ static bool rulesApplicableInCurrentTreeScope(const Element* element, const Cont
if (!scopingNode || treeScope == scopingNode->treeScope())
return true;
// d) the rules comes from a scoped style sheet within an active shadow root whose host is the given element
- if (element->isInShadowTree() && (behaviorAtBoundary & SelectorChecker::ScopeIsShadowHost) && scopingNode == element->containingShadowRoot()->host())
- return true;
- // e) the rules can cross boundaries
- if ((behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) == SelectorChecker::CrossesBoundary)
+ if (SelectorChecker::isHostInItsShadowTree(*element, behaviorAtBoundary, scopingNode))
return true;
return false;
}
@@ -146,7 +144,7 @@ void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest
const AtomicString& pseudoId = element.shadowPseudoId();
if (!pseudoId.isEmpty()) {
ASSERT(element.isStyledElement());
- collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRules(pseudoId.impl()), behaviorAtBoundary, ignoreCascadeScope, cascadeOrder, matchRequest, ruleRange);
+ collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRules(pseudoId), behaviorAtBoundary, ignoreCascadeScope, cascadeOrder, matchRequest, ruleRange);
}
if (element.isVTTElement())
@@ -164,65 +162,68 @@ void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest
// We need to collect the rules for id, class, tag, and everything else into a buffer and
// then sort the buffer.
if (element.hasID())
- collectMatchingRulesForList(matchRequest.ruleSet->idRules(element.idForStyleResolution().impl()), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+ collectMatchingRulesForList(matchRequest.ruleSet->idRules(element.idForStyleResolution()), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
if (element.isStyledElement() && element.hasClass()) {
for (size_t i = 0; i < element.classNames().size(); ++i)
- collectMatchingRulesForList(matchRequest.ruleSet->classRules(element.classNames()[i].impl()), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+ collectMatchingRulesForList(matchRequest.ruleSet->classRules(element.classNames()[i]), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
}
if (element.isLink())
collectMatchingRulesForList(matchRequest.ruleSet->linkPseudoClassRules(), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
if (SelectorChecker::matchesFocusPseudoClass(element))
collectMatchingRulesForList(matchRequest.ruleSet->focusPseudoClassRules(), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
- collectMatchingRulesForList(matchRequest.ruleSet->tagRules(element.localName().impl()), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+ collectMatchingRulesForList(matchRequest.ruleSet->tagRules(element.localName()), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
collectMatchingRulesForList(matchRequest.ruleSet->universalRules(), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
}
-void ElementRuleCollector::collectMatchingRulesForRegion(const MatchRequest& matchRequest, RuleRange& ruleRange, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder)
+CSSRuleList* ElementRuleCollector::nestedRuleList(CSSRule* rule)
{
- if (!m_regionForStyling)
- return;
-
- unsigned size = matchRequest.ruleSet->m_regionSelectorsAndRuleSets.size();
- for (unsigned i = 0; i < size; ++i) {
- const CSSSelector* regionSelector = matchRequest.ruleSet->m_regionSelectorsAndRuleSets.at(i).selector;
- if (checkRegionSelector(regionSelector, toElement(m_regionForStyling->nodeForRegion()))) {
- RuleSet* regionRules = matchRequest.ruleSet->m_regionSelectorsAndRuleSets.at(i).ruleSet.get();
- ASSERT(regionRules);
- collectMatchingRules(MatchRequest(regionRules, matchRequest.includeEmptyRules, matchRequest.scope), ruleRange, behaviorAtBoundary, cascadeScope, cascadeOrder);
- }
+ switch (rule->type()) {
+ case CSSRule::MEDIA_RULE:
+ return toCSSMediaRule(rule)->cssRules();
+ case CSSRule::KEYFRAMES_RULE:
+ return toCSSKeyframesRule(rule)->cssRules();
+ case CSSRule::SUPPORTS_RULE:
+ return toCSSSupportsRule(rule)->cssRules();
+ default:
+ return 0;
}
}
-
-static CSSStyleSheet* findStyleSheet(StyleEngine* styleEngine, StyleRule* rule)
+template<class CSSRuleCollection>
+CSSRule* ElementRuleCollector::findStyleRule(CSSRuleCollection* cssRules, StyleRule* styleRule)
{
- // FIXME: StyleEngine has a bunch of different accessors for StyleSheet lists, is this the only one we need to care about?
- const Vector<RefPtr<CSSStyleSheet> >& stylesheets = styleEngine->activeAuthorStyleSheets();
- for (size_t i = 0; i < stylesheets.size(); ++i) {
- CSSStyleSheet* sheet = stylesheets[i].get();
- for (unsigned j = 0; j < sheet->length(); ++j) {
- CSSRule* cssRule = sheet->item(j);
- if (cssRule->type() != CSSRule::STYLE_RULE)
- continue;
+ if (!cssRules)
+ return 0;
+ CSSRule* result = 0;
+ for (unsigned i = 0; i < cssRules->length() && !result; ++i) {
+ CSSRule* cssRule = cssRules->item(i);
+ CSSRule::Type cssRuleType = cssRule->type();
+ if (cssRuleType == CSSRule::STYLE_RULE) {
CSSStyleRule* cssStyleRule = toCSSStyleRule(cssRule);
- if (cssStyleRule->styleRule() == rule)
- return sheet;
+ if (cssStyleRule->styleRule() == styleRule)
+ result = cssRule;
+ } else if (cssRuleType == CSSRule::IMPORT_RULE) {
+ CSSImportRule* cssImportRule = toCSSImportRule(cssRule);
+ result = findStyleRule(cssImportRule->styleSheet(), styleRule);
+ } else {
+ result = findStyleRule(nestedRuleList(cssRule), styleRule);
}
}
- return 0;
+ return result;
}
-void ElementRuleCollector::appendCSSOMWrapperForRule(StyleRule* rule)
+void ElementRuleCollector::appendCSSOMWrapperForRule(CSSStyleSheet* parentStyleSheet, StyleRule* rule)
{
- // FIXME: There should be no codepath that creates a CSSOMWrapper without a parent stylesheet or rule because
- // then that codepath can lead to the CSSStyleSheet contents not getting correctly copied when the rule is modified
- // through the wrapper (e.g. rule.selectorText="div"). Right now, the inspector uses the pointers for identity though,
- // so calling CSSStyleSheet->willMutateRules breaks the inspector.
- CSSStyleSheet* sheet = m_includeStyleSheet == IncludeStyleSheetInCSSOMWrapper ? findStyleSheet(m_context.element()->document().styleEngine(), rule) : 0;
- RefPtr<CSSRule> cssRule = rule->createCSSOMWrapper(sheet);
- if (sheet)
- sheet->registerExtraChildRuleCSSOMWrapper(cssRule);
+ // |parentStyleSheet| is 0 if and only if the |rule| is coming from User Agent. In this case,
+ // it is safe to create CSSOM wrappers without parentStyleSheets as they will be used only
+ // by inspector which will not try to edit them.
+ RefPtrWillBeRawPtr<CSSRule> cssRule = nullptr;
+ if (parentStyleSheet)
+ cssRule = findStyleRule(parentStyleSheet, rule);
+ else
+ cssRule = rule->createCSSOMWrapper();
+ ASSERT(!parentStyleSheet || cssRule);
ensureRuleList()->rules().append(cssRule);
}
@@ -233,7 +234,7 @@ void ElementRuleCollector::sortAndTransferMatchedRules()
sortMatchedRules();
- Vector<MatchedRule, 32>& matchedRules = *m_matchedRules;
+ WillBeHeapVector<MatchedRule, 32>& matchedRules = *m_matchedRules;
if (m_mode == SelectorChecker::CollectingStyleRules) {
for (unsigned i = 0; i < matchedRules.size(); ++i)
ensureStyleRuleList()->m_list.append(matchedRules[i].ruleData()->rule());
@@ -242,7 +243,7 @@ void ElementRuleCollector::sortAndTransferMatchedRules()
if (m_mode == SelectorChecker::CollectingCSSRules) {
for (unsigned i = 0; i < matchedRules.size(); ++i)
- appendCSSOMWrapperForRule(matchedRules[i].ruleData()->rule());
+ appendCSSOMWrapperForRule(const_cast<CSSStyleSheet*>(matchedRules[i].parentStyleSheet()), matchedRules[i].ruleData()->rule());
return;
}
@@ -252,35 +253,12 @@ void ElementRuleCollector::sortAndTransferMatchedRules()
const RuleData* ruleData = matchedRules[i].ruleData();
if (m_style && ruleData->containsUncommonAttributeSelector())
m_style->setUnique();
- m_result.addMatchedProperties(ruleData->rule()->properties(), ruleData->rule(), ruleData->linkMatchType(), ruleData->propertyWhitelistType(m_matchingUARules));
+ m_result.addMatchedProperties(&ruleData->rule()->properties(), ruleData->rule(), ruleData->linkMatchType(), ruleData->propertyWhitelistType(m_matchingUARules));
}
}
inline bool ElementRuleCollector::ruleMatches(const RuleData& ruleData, const ContainerNode* scope, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, SelectorChecker::MatchResult* result)
{
- // Scoped rules can't match because the fast path uses a pool of tag/class/ids, collected from
- // elements in that tree and those will never match the host, since it's in a different pool.
- if (ruleData.hasFastCheckableSelector() && !scope) {
- // We know this selector does not include any pseudo elements.
- if (m_pseudoStyleRequest.pseudoId != NOPSEUDO)
- return false;
- // We know a sufficiently simple single part selector matches simply because we found it from the rule hash.
- // This is limited to HTML only so we don't need to check the namespace.
- ASSERT(m_context.element());
- if (ruleData.hasRightmostSelectorMatchingHTMLBasedOnRuleHash() && m_context.element()->isHTMLElement()) {
- if (!ruleData.hasMultipartSelector())
- return true;
- }
- if (ruleData.selector()->m_match == CSSSelector::Tag && !SelectorChecker::tagMatches(*m_context.element(), ruleData.selector()->tagQName()))
- return false;
- SelectorCheckerFastPath selectorCheckerFastPath(ruleData.selector(), *m_context.element());
- if (!selectorCheckerFastPath.matchesRightmostAttributeSelector())
- return false;
-
- return selectorCheckerFastPath.matches();
- }
-
- // Slow path.
SelectorChecker selectorChecker(m_context.element()->document(), m_mode);
SelectorChecker::SelectorCheckingContext context(ruleData.selector(), m_context.element(), SelectorChecker::VisitedMatchEnabled);
context.elementStyle = m_style.get();
@@ -306,8 +284,8 @@ void ElementRuleCollector::collectRuleIfMatches(const RuleData& ruleData, Select
SelectorChecker::MatchResult result;
if (ruleMatches(ruleData, matchRequest.scope, behaviorAtBoundary, &result)) {
// If the rule has no properties to apply, then ignore it in the non-debug mode.
- const StylePropertySet* properties = rule->properties();
- if (!properties || (properties->isEmpty() && !matchRequest.includeEmptyRules))
+ const StylePropertySet& properties = rule->properties();
+ if (properties.isEmpty() && !matchRequest.includeEmptyRules)
return;
// FIXME: Exposing the non-standard getMatchedCSSRules API to web is the only reason this is needed.
if (m_sameOriginOnly && !ruleData.hasDocumentSecurityOrigin())
@@ -329,30 +307,12 @@ void ElementRuleCollector::collectRuleIfMatches(const RuleData& ruleData, Select
ruleRange.firstRuleIndex = ruleRange.lastRuleIndex;
// Add this rule to our list of matched rules.
- addMatchedRule(&ruleData, result.specificity, cascadeScope, cascadeOrder, matchRequest.styleSheetIndex);
+ addMatchedRule(&ruleData, result.specificity, cascadeScope, cascadeOrder, matchRequest.styleSheetIndex, matchRequest.styleSheet);
return;
}
}
}
-void ElementRuleCollector::collectMatchingRulesForList(const RuleData* rules, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
-{
- if (!rules)
- return;
- while (!rules->isLastInArray())
- collectRuleIfMatches(*rules++, behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
- collectRuleIfMatches(*rules, behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
-}
-
-void ElementRuleCollector::collectMatchingRulesForList(const Vector<RuleData>* rules, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
-{
- if (!rules)
- return;
- unsigned size = rules->size();
- for (unsigned i = 0; i < size; ++i)
- collectRuleIfMatches(rules->at(i), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
-}
-
static inline bool compareRules(const MatchedRule& matchedRule1, const MatchedRule& matchedRule2)
{
if (matchedRule1.cascadeScope() != matchedRule2.cascadeScope())
@@ -363,9 +323,6 @@ static inline bool compareRules(const MatchedRule& matchedRule1, const MatchedRu
if (specificity1 != specificity2)
return specificity1 < specificity2;
- if (matchedRule1.styleSheetIndex() != matchedRule2.styleSheetIndex())
- return matchedRule1.styleSheetIndex() < matchedRule2.styleSheetIndex();
-
return matchedRule1.position() < matchedRule2.position();
}
diff --git a/chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.h b/chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.h
index cf47567909a..2423b1f23b3 100644
--- a/chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.h
+++ b/chromium/third_party/WebKit/Source/core/css/ElementRuleCollector.h
@@ -27,14 +27,13 @@
#include "core/css/resolver/ElementResolveContext.h"
#include "core/css/resolver/MatchRequest.h"
#include "core/css/resolver/MatchResult.h"
-#include "core/css/resolver/StyleResolverIncludes.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
namespace WebCore {
+class CSSStyleSheet;
class CSSRuleList;
-class RenderRegion;
class RuleData;
class RuleSet;
class ScopedStyleResolver;
@@ -48,37 +47,61 @@ const CascadeScope ignoreCascadeScope = 0;
const CascadeOrder ignoreCascadeOrder = 0;
class MatchedRule {
- WTF_MAKE_FAST_ALLOCATED;
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
- explicit MatchedRule(const RuleData* ruleData, unsigned specificity, CascadeScope cascadeScope, CascadeOrder cascadeOrder, unsigned styleSheetIndex)
+ MatchedRule(const RuleData* ruleData, unsigned specificity, CascadeScope cascadeScope, CascadeOrder cascadeOrder, unsigned styleSheetIndex, const CSSStyleSheet* parentStyleSheet)
: m_ruleData(ruleData)
, m_specificity(specificity)
, m_cascadeScope(cascadeScope)
- , m_styleSheetIndex(styleSheetIndex)
+ , m_parentStyleSheet(parentStyleSheet)
{
ASSERT(m_ruleData);
static const unsigned BitsForPositionInRuleData = 18;
- m_position = (cascadeOrder << BitsForPositionInRuleData) + m_ruleData->position();
+ static const unsigned BitsForStyleSheetIndex = 32;
+ m_position = ((uint64_t)cascadeOrder << (BitsForStyleSheetIndex + BitsForPositionInRuleData)) + ((uint64_t)styleSheetIndex << BitsForPositionInRuleData)+ m_ruleData->position();
}
const RuleData* ruleData() const { return m_ruleData; }
uint32_t cascadeScope() const { return m_cascadeScope; }
- uint32_t position() const { return m_position; }
+ uint64_t position() const { return m_position; }
unsigned specificity() const { return ruleData()->specificity() + m_specificity; }
- uint32_t styleSheetIndex() const { return m_styleSheetIndex; }
+ const CSSStyleSheet* parentStyleSheet() const { return m_parentStyleSheet; }
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_parentStyleSheet);
+ }
private:
+ // FIXME: Oilpan: RuleData is in the oilpan heap and this pointer
+ // really should be traced. However, RuleData objects are
+ // allocated inside larger TerminatedArray objects and we cannot
+ // trace a raw rule data pointer at this point.
const RuleData* m_ruleData;
unsigned m_specificity;
CascadeScope m_cascadeScope;
- uint32_t m_position;
- uint32_t m_styleSheetIndex;
+ uint64_t m_position;
+ RawPtrWillBeMember<const CSSStyleSheet> m_parentStyleSheet;
};
-class StyleRuleList : public RefCounted<StyleRuleList> {
+} // namespace WebCore
+
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::MatchedRule);
+
+namespace WebCore {
+
+// FIXME: oilpan: when transition types are gone this class can be replaced with HeapVector.
+class StyleRuleList FINAL : public RefCountedWillBeGarbageCollected<StyleRuleList> {
public:
- static PassRefPtr<StyleRuleList> create() { return adoptRef(new StyleRuleList()); }
- Vector<StyleRule*> m_list;
+ static PassRefPtrWillBeRawPtr<StyleRuleList> create() { return adoptRefWillBeNoop(new StyleRuleList()); }
+
+ void trace(Visitor* visitor)
+ {
+#if ENABLE(OILPAN)
+ visitor->trace(m_list);
+#endif
+ }
+
+ WillBeHeapVector<RawPtrWillBeMember<StyleRule> > m_list;
};
// ElementRuleCollector is designed to be used as a stack object.
@@ -86,25 +109,24 @@ public:
// and then let it go out of scope.
// FIXME: Currently it modifies the RenderStyle but should not!
class ElementRuleCollector {
+ STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(ElementRuleCollector);
public:
- ElementRuleCollector(const ElementResolveContext&, const SelectorFilter&, RenderStyle* = 0, ShouldIncludeStyleSheetInCSSOMWrapper = IncludeStyleSheetInCSSOMWrapper);
+ ElementRuleCollector(const ElementResolveContext&, const SelectorFilter&, RenderStyle* = 0);
~ElementRuleCollector();
void setMode(SelectorChecker::Mode mode) { m_mode = mode; }
void setPseudoStyleRequest(const PseudoStyleRequest& request) { m_pseudoStyleRequest = request; }
void setSameOriginOnly(bool f) { m_sameOriginOnly = f; }
- void setRegionForStyling(const RenderRegion* regionForStyling) { m_regionForStyling = regionForStyling; }
void setMatchingUARules(bool matchingUARules) { m_matchingUARules = matchingUARules; }
bool hasAnyMatchingRules(RuleSet*);
MatchResult& matchedResult();
- PassRefPtr<StyleRuleList> matchedStyleRuleList();
- PassRefPtr<CSSRuleList> matchedCSSRuleList();
+ PassRefPtrWillBeRawPtr<StyleRuleList> matchedStyleRuleList();
+ PassRefPtrWillBeRawPtr<CSSRuleList> matchedCSSRuleList();
void collectMatchingRules(const MatchRequest&, RuleRange&, SelectorChecker::BehaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
- void collectMatchingRulesForRegion(const MatchRequest&, RuleRange&, SelectorChecker::BehaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
void sortAndTransferMatchedRules();
void clearMatchedRules();
void addElementStyleProperties(const StylePropertySet*, bool isCacheable = true);
@@ -115,15 +137,26 @@ public:
private:
void collectRuleIfMatches(const RuleData&, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
- void collectMatchingRulesForList(const Vector<RuleData>*, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
- void collectMatchingRulesForList(const RuleData*, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
+
+ template<typename RuleDataListType>
+ void collectMatchingRulesForList(const RuleDataListType* rules, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
+ {
+ if (!rules)
+ return;
+
+ for (typename RuleDataListType::const_iterator it = rules->begin(), end = rules->end(); it != end; ++it)
+ collectRuleIfMatches(*it, behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+ }
+
bool ruleMatches(const RuleData&, const ContainerNode* scope, SelectorChecker::BehaviorAtBoundary, SelectorChecker::MatchResult*);
- void appendCSSOMWrapperForRule(StyleRule*);
+ CSSRuleList* nestedRuleList(CSSRule*);
+ template<class CSSRuleCollection>
+ CSSRule* findStyleRule(CSSRuleCollection*, StyleRule*);
+ void appendCSSOMWrapperForRule(CSSStyleSheet*, StyleRule*);
void sortMatchedRules();
- void addMatchedRule(const RuleData*, unsigned specificity, CascadeScope, CascadeOrder);
- void addMatchedRule(const RuleData*, unsigned specificity, CascadeScope, CascadeOrder, unsigned styleSheetIndex);
+ void addMatchedRule(const RuleData*, unsigned specificity, CascadeScope, CascadeOrder, unsigned styleSheetIndex, const CSSStyleSheet* parentStyleSheet);
StaticCSSRuleList* ensureRuleList();
StyleRuleList* ensureStyleRuleList();
@@ -133,19 +166,17 @@ private:
const SelectorFilter& m_selectorFilter;
RefPtr<RenderStyle> m_style; // FIXME: This can be mutated during matching!
- const RenderRegion* m_regionForStyling;
PseudoStyleRequest m_pseudoStyleRequest;
SelectorChecker::Mode m_mode;
bool m_canUseFastReject;
bool m_sameOriginOnly;
bool m_matchingUARules;
- bool m_includeStyleSheet;
- OwnPtr<Vector<MatchedRule, 32> > m_matchedRules;
+ OwnPtrWillBeMember<WillBeHeapVector<MatchedRule, 32> > m_matchedRules;
// Output.
- RefPtr<StaticCSSRuleList> m_cssRuleList;
- RefPtr<StyleRuleList> m_styleRuleList;
+ RefPtrWillBeMember<StaticCSSRuleList> m_cssRuleList;
+ RefPtrWillBeMember<StyleRuleList> m_styleRuleList;
MatchResult m_result;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFace.cpp b/chromium/third_party/WebKit/Source/core/css/FontFace.cpp
index 3b35cbca0fb..9590053c590 100644
--- a/chromium/third_party/WebKit/Source/core/css/FontFace.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/FontFace.cpp
@@ -31,134 +31,161 @@
#include "config.h"
#include "core/css/FontFace.h"
-#include "CSSValueKeywords.h"
-#include "FontFamilyNames.h"
#include "bindings/v8/Dictionary.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptPromiseResolver.h"
-#include "bindings/v8/ScriptScope.h"
+#include "bindings/v8/ScriptPromiseResolverWithContext.h"
#include "bindings/v8/ScriptState.h"
+#include "core/CSSValueKeywords.h"
+#include "core/css/BinaryDataFontFaceSource.h"
#include "core/css/CSSFontFace.h"
#include "core/css/CSSFontFaceSrcValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/CSSFontSelector.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSUnicodeRangeValue.h"
#include "core/css/CSSValueList.h"
+#include "core/css/LocalFontFaceSource.h"
+#include "core/css/RemoteFontFaceSource.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRule.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/dom/DOMError.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
-#include "core/frame/Frame.h"
+#include "core/dom/StyleEngine.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/svg/SVGFontFaceElement.h"
-#include "platform/fonts/FontDescription.h"
-#include "platform/fonts/FontTraitsMask.h"
-#include "platform/fonts/SimpleFontData.h"
+#include "core/svg/SVGFontFaceSource.h"
+#include "core/svg/SVGRemoteFontFaceSource.h"
+#include "platform/FontFamilyNames.h"
+#include "platform/SharedBuffer.h"
namespace WebCore {
class FontFaceReadyPromiseResolver {
public:
- static PassOwnPtr<FontFaceReadyPromiseResolver> create(ScriptPromise promise, ExecutionContext* context)
+ static PassOwnPtr<FontFaceReadyPromiseResolver> create(ScriptState* scriptState)
{
- return adoptPtr(new FontFaceReadyPromiseResolver(promise, context));
+ return adoptPtr(new FontFaceReadyPromiseResolver(scriptState));
}
- void resolve(PassRefPtr<FontFace> fontFace)
+ void resolve(PassRefPtrWillBeRawPtr<FontFace> fontFace)
{
- ScriptScope scope(m_scriptState);
switch (fontFace->loadStatus()) {
case FontFace::Loaded:
m_resolver->resolve(fontFace);
break;
case FontFace::Error:
- m_resolver->reject(DOMError::create(NetworkError));
+ m_resolver->reject(fontFace->error());
break;
default:
ASSERT_NOT_REACHED();
}
}
+ ScriptPromise promise() { return m_resolver->promise(); }
+
private:
- FontFaceReadyPromiseResolver(ScriptPromise promise, ExecutionContext* context)
- : m_scriptState(ScriptState::current())
- , m_resolver(ScriptPromiseResolver::create(promise, context))
- { }
- ScriptState* m_scriptState;
- RefPtr<ScriptPromiseResolver> m_resolver;
+ FontFaceReadyPromiseResolver(ScriptState* scriptState)
+ : m_resolver(ScriptPromiseResolverWithContext::create(scriptState))
+ {
+ }
+
+ RefPtr<ScriptPromiseResolverWithContext> m_resolver;
};
-static PassRefPtr<CSSValue> parseCSSValue(const String& s, CSSPropertyID propertyID)
+static PassRefPtrWillBeRawPtr<CSSValue> parseCSSValue(const Document* document, const String& s, CSSPropertyID propertyID)
{
if (s.isEmpty())
- return 0;
- RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::create();
- CSSParser::parseValue(parsedStyle.get(), propertyID, s, true, HTMLStandardMode, 0);
+ return nullptr;
+ RefPtrWillBeRawPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::create();
+ BisonCSSParser::parseValue(parsedStyle.get(), propertyID, s, true, *document);
return parsedStyle->getPropertyCSSValue(propertyID);
}
-PassRefPtr<FontFace> FontFace::create(const AtomicString& family, const String& source, const Dictionary& descriptors, ExceptionState& exceptionState)
+static bool initFontFace(FontFace* fontFace, ExecutionContext* context, const AtomicString& family, const Dictionary& descriptors, ExceptionState& exceptionState)
{
- RefPtr<CSSValue> src = parseCSSValue(source, CSSPropertySrc);
- if (!src || !src->isValueList()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return 0;
- }
-
- RefPtr<FontFace> fontFace = adoptRef<FontFace>(new FontFace(src));
- fontFace->setFamily(family, exceptionState);
+ fontFace->setFamily(context, family, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return false;
String value;
if (descriptors.get("style", value)) {
- fontFace->setStyle(value, exceptionState);
+ fontFace->setStyle(context, value, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return false;
}
if (descriptors.get("weight", value)) {
- fontFace->setWeight(value, exceptionState);
+ fontFace->setWeight(context, value, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return false;
}
if (descriptors.get("stretch", value)) {
- fontFace->setStretch(value, exceptionState);
+ fontFace->setStretch(context, value, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return false;
}
if (descriptors.get("unicodeRange", value)) {
- fontFace->setUnicodeRange(value, exceptionState);
+ fontFace->setUnicodeRange(context, value, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return false;
}
if (descriptors.get("variant", value)) {
- fontFace->setVariant(value, exceptionState);
+ fontFace->setVariant(context, value, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return false;
}
if (descriptors.get("featureSettings", value)) {
- fontFace->setFeatureSettings(value, exceptionState);
+ fontFace->setFeatureSettings(context, value, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return false;
+ }
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, const String& source, const Dictionary& descriptors, ExceptionState& exceptionState)
+{
+ RefPtrWillBeRawPtr<CSSValue> src = parseCSSValue(toDocument(context), source, CSSPropertySrc);
+ if (!src || !src->isValueList()) {
+ exceptionState.throwDOMException(SyntaxError, "The source provided ('" + source + "') could not be parsed as a value list.");
+ return nullptr;
}
- return fontFace;
+ RefPtrWillBeRawPtr<FontFace> fontFace = adoptRefWillBeNoop(new FontFace());
+ if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState))
+ fontFace->initCSSFontFace(toDocument(context), src);
+ return fontFace.release();
}
-PassRefPtr<FontFace> FontFace::create(const StyleRuleFontFace* fontFaceRule)
+PassRefPtrWillBeRawPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, PassRefPtr<ArrayBuffer> source, const Dictionary& descriptors, ExceptionState& exceptionState)
{
- const StylePropertySet* properties = fontFaceRule->properties();
+ RefPtrWillBeRawPtr<FontFace> fontFace = adoptRefWillBeNoop(new FontFace());
+ if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState))
+ fontFace->initCSSFontFace(static_cast<const unsigned char*>(source->data()), source->byteLength());
+ return fontFace.release();
+}
+
+PassRefPtrWillBeRawPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, PassRefPtr<ArrayBufferView> source, const Dictionary& descriptors, ExceptionState& exceptionState)
+{
+ RefPtrWillBeRawPtr<FontFace> fontFace = adoptRefWillBeNoop(new FontFace());
+ if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState))
+ fontFace->initCSSFontFace(static_cast<const unsigned char*>(source->baseAddress()), source->byteLength());
+ return fontFace.release();
+}
+
+PassRefPtrWillBeRawPtr<FontFace> FontFace::create(Document* document, const StyleRuleFontFace* fontFaceRule)
+{
+ const StylePropertySet& properties = fontFaceRule->properties();
// Obtain the font-family property and the src property. Both must be defined.
- RefPtr<CSSValue> family = properties->getPropertyCSSValue(CSSPropertyFontFamily);
+ RefPtrWillBeRawPtr<CSSValue> family = properties.getPropertyCSSValue(CSSPropertyFontFamily);
if (!family || !family->isValueList())
- return 0;
- RefPtr<CSSValue> src = properties->getPropertyCSSValue(CSSPropertySrc);
+ return nullptr;
+ RefPtrWillBeRawPtr<CSSValue> src = properties.getPropertyCSSValue(CSSPropertySrc);
if (!src || !src->isValueList())
- return 0;
+ return nullptr;
- RefPtr<FontFace> fontFace = adoptRef<FontFace>(new FontFace(src));
+ RefPtrWillBeRawPtr<FontFace> fontFace = adoptRefWillBeNoop(new FontFace());
if (fontFace->setFamilyValue(toCSSValueList(family.get()))
&& fontFace->setPropertyFromStyle(properties, CSSPropertyFontStyle)
@@ -166,15 +193,17 @@ PassRefPtr<FontFace> FontFace::create(const StyleRuleFontFace* fontFaceRule)
&& fontFace->setPropertyFromStyle(properties, CSSPropertyFontStretch)
&& fontFace->setPropertyFromStyle(properties, CSSPropertyUnicodeRange)
&& fontFace->setPropertyFromStyle(properties, CSSPropertyFontVariant)
- && fontFace->setPropertyFromStyle(properties, CSSPropertyWebkitFontFeatureSettings))
- return fontFace;
- return 0;
+ && fontFace->setPropertyFromStyle(properties, CSSPropertyWebkitFontFeatureSettings)
+ && !fontFace->family().isEmpty()
+ && fontFace->traits().mask()) {
+ fontFace->initCSSFontFace(document, src);
+ return fontFace.release();
+ }
+ return nullptr;
}
-FontFace::FontFace(PassRefPtr<CSSValue> src)
- : m_src(src)
- , m_status(Unloaded)
- , m_cssFontFace(0)
+FontFace::FontFace()
+ : m_status(Unloaded)
{
}
@@ -212,49 +241,49 @@ String FontFace::featureSettings() const
return m_featureSettings ? m_featureSettings->cssText() : "normal";
}
-void FontFace::setStyle(const String& s, ExceptionState& exceptionState)
+void FontFace::setStyle(ExecutionContext* context, const String& s, ExceptionState& exceptionState)
{
- setPropertyFromString(s, CSSPropertyFontStyle, exceptionState);
+ setPropertyFromString(toDocument(context), s, CSSPropertyFontStyle, exceptionState);
}
-void FontFace::setWeight(const String& s, ExceptionState& exceptionState)
+void FontFace::setWeight(ExecutionContext* context, const String& s, ExceptionState& exceptionState)
{
- setPropertyFromString(s, CSSPropertyFontWeight, exceptionState);
+ setPropertyFromString(toDocument(context), s, CSSPropertyFontWeight, exceptionState);
}
-void FontFace::setStretch(const String& s, ExceptionState& exceptionState)
+void FontFace::setStretch(ExecutionContext* context, const String& s, ExceptionState& exceptionState)
{
- setPropertyFromString(s, CSSPropertyFontStretch, exceptionState);
+ setPropertyFromString(toDocument(context), s, CSSPropertyFontStretch, exceptionState);
}
-void FontFace::setUnicodeRange(const String& s, ExceptionState& exceptionState)
+void FontFace::setUnicodeRange(ExecutionContext* context, const String& s, ExceptionState& exceptionState)
{
- setPropertyFromString(s, CSSPropertyUnicodeRange, exceptionState);
+ setPropertyFromString(toDocument(context), s, CSSPropertyUnicodeRange, exceptionState);
}
-void FontFace::setVariant(const String& s, ExceptionState& exceptionState)
+void FontFace::setVariant(ExecutionContext* context, const String& s, ExceptionState& exceptionState)
{
- setPropertyFromString(s, CSSPropertyFontVariant, exceptionState);
+ setPropertyFromString(toDocument(context), s, CSSPropertyFontVariant, exceptionState);
}
-void FontFace::setFeatureSettings(const String& s, ExceptionState& exceptionState)
+void FontFace::setFeatureSettings(ExecutionContext* context, const String& s, ExceptionState& exceptionState)
{
- setPropertyFromString(s, CSSPropertyWebkitFontFeatureSettings, exceptionState);
+ setPropertyFromString(toDocument(context), s, CSSPropertyWebkitFontFeatureSettings, exceptionState);
}
-void FontFace::setPropertyFromString(const String& s, CSSPropertyID propertyID, ExceptionState& exceptionState)
+void FontFace::setPropertyFromString(const Document* document, const String& s, CSSPropertyID propertyID, ExceptionState& exceptionState)
{
- RefPtr<CSSValue> value = parseCSSValue(s, propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = parseCSSValue(document, s, propertyID);
if (!value || !setPropertyValue(value, propertyID))
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "Failed to set '" + s + "' as a property value.");
}
-bool FontFace::setPropertyFromStyle(const StylePropertySet* properties, CSSPropertyID propertyID)
+bool FontFace::setPropertyFromStyle(const StylePropertySet& properties, CSSPropertyID propertyID)
{
- return setPropertyValue(properties->getPropertyCSSValue(propertyID), propertyID);
+ return setPropertyValue(properties.getPropertyCSSValue(propertyID), propertyID);
}
-bool FontFace::setPropertyValue(PassRefPtr<CSSValue> value, CSSPropertyID propertyID)
+bool FontFace::setPropertyValue(PassRefPtrWillBeRawPtr<CSSValue> value, CSSPropertyID propertyID)
{
switch (propertyID) {
case CSSPropertyFontStyle:
@@ -344,38 +373,62 @@ String FontFace::status() const
void FontFace::setLoadStatus(LoadStatus status)
{
m_status = status;
- if (m_status == Loaded || m_status == Error)
+ if (m_status == Error)
+ m_error = DOMError::create(NetworkError);
+ if (m_status == Loaded || m_status == Error) {
resolveReadyPromises();
-}
-
-void FontFace::load()
-{
- // FIXME: This does not load FontFace created by JavaScript, since m_cssFontFace is null.
- if (m_status != Unloaded || !m_cssFontFace)
- return;
-
- FontDescription fontDescription;
- FontFamily fontFamily;
- fontFamily.setFamily(m_family);
- fontDescription.setFamily(fontFamily);
- fontDescription.setTraitsMask(static_cast<FontTraitsMask>(traitsMask()));
- RefPtr<SimpleFontData> fontData = m_cssFontFace->getFontData(fontDescription);
- if (fontData && fontData->customFontData())
- fontData->customFontData()->beginLoadIfNeeded();
+ WillBeHeapVector<RefPtrWillBeMember<LoadFontCallback> > callbacks;
+ m_callbacks.swap(callbacks);
+ for (size_t i = 0; i < callbacks.size(); ++i) {
+ if (m_status == Loaded)
+ callbacks[i]->notifyLoaded(this);
+ else
+ callbacks[i]->notifyError(this);
+ }
+ }
}
-ScriptPromise FontFace::ready(ExecutionContext* context)
+ScriptPromise FontFace::fontStatusPromise(ScriptState* scriptState)
{
- ScriptPromise promise = ScriptPromise::createPending(context);
- OwnPtr<FontFaceReadyPromiseResolver> resolver = FontFaceReadyPromiseResolver::create(promise, context);
+ // Since we cannot hold a ScriptPromise as a member of FontFace (that will
+ // cause a circular reference), this creates new Promise every time.
+ OwnPtr<FontFaceReadyPromiseResolver> resolver = FontFaceReadyPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
if (m_status == Loaded || m_status == Error)
resolver->resolve(this);
else
m_readyResolvers.append(resolver.release());
+
return promise;
}
+ScriptPromise FontFace::load(ScriptState* scriptState)
+{
+ loadInternal(scriptState->executionContext());
+ return fontStatusPromise(scriptState);
+}
+
+void FontFace::loadWithCallback(PassRefPtrWillBeRawPtr<LoadFontCallback> callback, ExecutionContext* context)
+{
+ loadInternal(context);
+ if (m_status == Loaded)
+ callback->notifyLoaded(this);
+ else if (m_status == Error)
+ callback->notifyError(this);
+ else
+ m_callbacks.append(callback);
+}
+
+void FontFace::loadInternal(ExecutionContext* context)
+{
+ if (m_status != Unloaded)
+ return;
+
+ m_cssFontFace->load();
+ toDocument(context)->styleEngine()->fontSelector()->fontLoader()->loadPendingFonts();
+}
+
void FontFace::resolveReadyPromises()
{
for (size_t i = 0; i < m_readyResolvers.size(); i++)
@@ -383,29 +436,27 @@ void FontFace::resolveReadyPromises()
m_readyResolvers.clear();
}
-unsigned FontFace::traitsMask() const
+FontTraits FontFace::traits() const
{
- unsigned traitsMask = 0;
-
+ FontStyle style = FontStyleNormal;
if (m_style) {
if (!m_style->isPrimitiveValue())
return 0;
switch (toCSSPrimitiveValue(m_style.get())->getValueID()) {
case CSSValueNormal:
- traitsMask |= FontStyleNormalMask;
+ style = FontStyleNormal;
break;
case CSSValueItalic:
case CSSValueOblique:
- traitsMask |= FontStyleItalicMask;
+ style = FontStyleItalic;
break;
default:
break;
}
- } else {
- traitsMask |= FontStyleNormalMask;
}
+ FontWeight weight = FontWeight400;
if (m_weight) {
if (!m_weight->isPrimitiveValue())
return 0;
@@ -413,44 +464,45 @@ unsigned FontFace::traitsMask() const
switch (toCSSPrimitiveValue(m_weight.get())->getValueID()) {
case CSSValueBold:
case CSSValue700:
- traitsMask |= FontWeight700Mask;
+ weight = FontWeight700;
break;
case CSSValueNormal:
case CSSValue400:
- traitsMask |= FontWeight400Mask;
+ weight = FontWeight400;
break;
case CSSValue900:
- traitsMask |= FontWeight900Mask;
+ weight = FontWeight900;
break;
case CSSValue800:
- traitsMask |= FontWeight800Mask;
+ weight = FontWeight800;
break;
case CSSValue600:
- traitsMask |= FontWeight600Mask;
+ weight = FontWeight600;
break;
case CSSValue500:
- traitsMask |= FontWeight500Mask;
+ weight = FontWeight500;
break;
case CSSValue300:
- traitsMask |= FontWeight300Mask;
+ weight = FontWeight300;
break;
case CSSValue200:
- traitsMask |= FontWeight200Mask;
+ weight = FontWeight200;
break;
+ case CSSValueLighter:
case CSSValue100:
- traitsMask |= FontWeight100Mask;
+ weight = FontWeight100;
break;
default:
+ ASSERT_NOT_REACHED();
break;
}
- } else {
- traitsMask |= FontWeight400Mask;
}
- if (RefPtr<CSSValue> fontVariant = m_variant) {
+ FontVariant variant = FontVariantNormal;
+ if (RefPtrWillBeRawPtr<CSSValue> fontVariant = m_variant) {
// font-variant descriptor can be a value list.
if (fontVariant->isPrimitiveValue()) {
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
list->append(fontVariant);
fontVariant = list;
} else if (!fontVariant->isValueList()) {
@@ -465,31 +517,40 @@ unsigned FontFace::traitsMask() const
for (unsigned i = 0; i < numVariants; ++i) {
switch (toCSSPrimitiveValue(variantList->itemWithoutBoundsCheck(i))->getValueID()) {
case CSSValueNormal:
- traitsMask |= FontVariantNormalMask;
+ variant = FontVariantNormal;
break;
case CSSValueSmallCaps:
- traitsMask |= FontVariantSmallCapsMask;
+ variant = FontVariantSmallCaps;
break;
default:
break;
}
}
- } else {
- traitsMask |= FontVariantNormalMask;
}
- return traitsMask;
+
+ return FontTraits(style, variant, weight, FontStretchNormal);
}
-PassRefPtr<CSSFontFace> FontFace::createCSSFontFace(Document* document)
+static PassOwnPtrWillBeRawPtr<CSSFontFace> createCSSFontFace(FontFace* fontFace, CSSValue* unicodeRange)
{
- if (m_cssFontFace)
- return m_cssFontFace;
+ Vector<CSSFontFace::UnicodeRange> ranges;
+ if (CSSValueList* rangeList = toCSSValueList(unicodeRange)) {
+ unsigned numRanges = rangeList->length();
+ for (unsigned i = 0; i < numRanges; i++) {
+ CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->itemWithoutBoundsCheck(i));
+ ranges.append(CSSFontFace::UnicodeRange(range->from(), range->to()));
+ }
+ }
- RefPtr<CSSFontFace> cssFontFace = CSSFontFace::create(this);
- m_cssFontFace = cssFontFace.get();
+ return adoptPtrWillBeNoop(new CSSFontFace(fontFace, ranges));
+}
+
+void FontFace::initCSSFontFace(Document* document, PassRefPtrWillBeRawPtr<CSSValue> src)
+{
+ m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get());
// Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
- CSSValueList* srcList = toCSSValueList(m_src.get());
+ CSSValueList* srcList = toCSSValueList(src.get());
int srcLength = srcList->length();
bool foundSVGFont = false;
@@ -497,7 +558,7 @@ PassRefPtr<CSSFontFace> FontFace::createCSSFontFace(Document* document)
for (int i = 0; i < srcLength; i++) {
// An item in the list either specifies a string (local font name) or a URL (remote font to download).
CSSFontFaceSrcValue* item = toCSSFontFaceSrcValue(srcList->itemWithoutBoundsCheck(i));
- OwnPtr<CSSFontFaceSource> source;
+ OwnPtrWillBeRawPtr<CSSFontFaceSource> source = nullptr;
#if ENABLE(SVG_FONTS)
foundSVGFont = item->isSVGFontFaceSrc() || item->svgFontFaceElement();
@@ -508,33 +569,71 @@ PassRefPtr<CSSFontFace> FontFace::createCSSFontFace(Document* document)
if (allowDownloading && item->isSupportedFormat() && document) {
FontResource* fetched = item->fetch(document);
if (fetched) {
- source = adoptPtr(new CSSFontFaceSource(item->resource(), fetched));
+ FontLoader* fontLoader = document->styleEngine()->fontSelector()->fontLoader();
+
#if ENABLE(SVG_FONTS)
- if (foundSVGFont)
- source->setHasExternalSVGFont(true);
+ if (foundSVGFont) {
+ source = adoptPtrWillBeNoop(new SVGRemoteFontFaceSource(item->resource(), fetched, fontLoader));
+ } else
#endif
+ {
+ source = adoptPtrWillBeNoop(new RemoteFontFaceSource(fetched, fontLoader));
+ }
}
}
} else {
- source = adoptPtr(new CSSFontFaceSource(item->resource()));
- }
-
- if (source) {
#if ENABLE(SVG_FONTS)
- source->setSVGFontFaceElement(item->svgFontFaceElement());
+ if (item->svgFontFaceElement()) {
+ RefPtrWillBeRawPtr<SVGFontFaceElement> fontfaceElement = item->svgFontFaceElement();
+ // SVGFontFaceSource assumes that it is the case where <font-face> element resides in the same document.
+ // We put a RELEASE_ASSERT here as it will cause UAF if the assumption is false.
+ RELEASE_ASSERT(fontfaceElement->inDocument());
+ RELEASE_ASSERT(fontfaceElement->document() == document);
+ source = adoptPtrWillBeNoop(new SVGFontFaceSource(fontfaceElement.get()));
+ } else
#endif
- cssFontFace->addSource(source.release());
+ {
+ source = adoptPtrWillBeNoop(new LocalFontFaceSource(item->resource()));
+ }
}
+
+ if (source)
+ m_cssFontFace->addSource(source.release());
}
+}
- if (CSSValueList* rangeList = toCSSValueList(m_unicodeRange.get())) {
- unsigned numRanges = rangeList->length();
- for (unsigned i = 0; i < numRanges; i++) {
- CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->itemWithoutBoundsCheck(i));
- cssFontFace->ranges().add(range->from(), range->to());
- }
+void FontFace::initCSSFontFace(const unsigned char* data, unsigned size)
+{
+ m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get());
+
+ RefPtr<SharedBuffer> buffer = SharedBuffer::create(data, size);
+ OwnPtrWillBeRawPtr<BinaryDataFontFaceSource> source = adoptPtrWillBeNoop(new BinaryDataFontFaceSource(buffer.get()));
+ if (source->isValid()) {
+ m_status = Loaded;
+ } else {
+ m_status = Error;
+ m_error = DOMError::create(SyntaxError, "Invalid font data in ArrayBuffer.");
}
- return cssFontFace;
+ m_cssFontFace->addSource(source.release());
+}
+
+void FontFace::trace(Visitor* visitor)
+{
+ visitor->trace(m_src);
+ visitor->trace(m_style);
+ visitor->trace(m_weight);
+ visitor->trace(m_stretch);
+ visitor->trace(m_unicodeRange);
+ visitor->trace(m_variant);
+ visitor->trace(m_featureSettings);
+ visitor->trace(m_error);
+ visitor->trace(m_cssFontFace);
+ visitor->trace(m_callbacks);
+}
+
+bool FontFace::hadBlankText() const
+{
+ return m_cssFontFace->hadBlankText();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFace.h b/chromium/third_party/WebKit/Source/core/css/FontFace.h
index 900d3a7c962..c42316efdfa 100644
--- a/chromium/third_party/WebKit/Source/core/css/FontFace.h
+++ b/chromium/third_party/WebKit/Source/core/css/FontFace.h
@@ -31,9 +31,11 @@
#ifndef FontFace_h
#define FontFace_h
-#include "CSSPropertyNames.h"
#include "bindings/v8/ScriptPromise.h"
+#include "core/CSSPropertyNames.h"
#include "core/css/CSSValue.h"
+#include "core/dom/DOMError.h"
+#include "platform/fonts/FontTraits.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -49,12 +51,14 @@ class FontFaceReadyPromiseResolver;
class StylePropertySet;
class StyleRuleFontFace;
-class FontFace : public RefCounted<FontFace> {
+class FontFace : public RefCountedWillBeGarbageCollectedFinalized<FontFace> {
public:
enum LoadStatus { Unloaded, Loading, Loaded, Error };
- static PassRefPtr<FontFace> create(const AtomicString& family, const String& source, const Dictionary&, ExceptionState&);
- static PassRefPtr<FontFace> create(const StyleRuleFontFace*);
+ static PassRefPtrWillBeRawPtr<FontFace> create(ExecutionContext*, const AtomicString& family, PassRefPtr<ArrayBuffer> source, const Dictionary&, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<FontFace> create(ExecutionContext*, const AtomicString& family, PassRefPtr<ArrayBufferView>, const Dictionary&, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<FontFace> create(ExecutionContext*, const AtomicString& family, const String& source, const Dictionary&, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<FontFace> create(Document*, const StyleRuleFontFace*);
~FontFace();
@@ -67,49 +71,68 @@ public:
String featureSettings() const;
// FIXME: Changing these attributes should affect font matching.
- void setFamily(const AtomicString& s, ExceptionState&) { m_family = s; }
- void setStyle(const String&, ExceptionState&);
- void setWeight(const String&, ExceptionState&);
- void setStretch(const String&, ExceptionState&);
- void setUnicodeRange(const String&, ExceptionState&);
- void setVariant(const String&, ExceptionState&);
- void setFeatureSettings(const String&, ExceptionState&);
+ void setFamily(ExecutionContext*, const AtomicString& s, ExceptionState&) { m_family = s; }
+ void setStyle(ExecutionContext*, const String&, ExceptionState&);
+ void setWeight(ExecutionContext*, const String&, ExceptionState&);
+ void setStretch(ExecutionContext*, const String&, ExceptionState&);
+ void setUnicodeRange(ExecutionContext*, const String&, ExceptionState&);
+ void setVariant(ExecutionContext*, const String&, ExceptionState&);
+ void setFeatureSettings(ExecutionContext*, const String&, ExceptionState&);
String status() const;
+ ScriptPromise loaded(ScriptState* scriptState) { return fontStatusPromise(scriptState); }
- void load();
- ScriptPromise ready(ExecutionContext*);
+ ScriptPromise load(ScriptState*);
LoadStatus loadStatus() const { return m_status; }
void setLoadStatus(LoadStatus);
- unsigned traitsMask() const;
- PassRefPtr<CSSFontFace> createCSSFontFace(Document*);
- void cssFontFaceDestroyed() { m_cssFontFace = 0; }
+ DOMError* error() const { return m_error.get(); }
+ FontTraits traits() const;
+ CSSFontFace* cssFontFace() { return m_cssFontFace.get(); }
+
+ void trace(Visitor*);
+
+ bool hadBlankText() const;
+
+ class LoadFontCallback : public RefCountedWillBeGarbageCollectedFinalized<LoadFontCallback> {
+ public:
+ virtual ~LoadFontCallback() { }
+ virtual void notifyLoaded(FontFace*) = 0;
+ virtual void notifyError(FontFace*) = 0;
+ virtual void trace(Visitor*) { }
+ };
+ void loadWithCallback(PassRefPtrWillBeRawPtr<LoadFontCallback>, ExecutionContext*);
private:
- FontFace(PassRefPtr<CSSValue> source);
+ FontFace();
- void setPropertyFromString(const String&, CSSPropertyID, ExceptionState&);
- bool setPropertyFromStyle(const StylePropertySet*, CSSPropertyID);
- bool setPropertyValue(PassRefPtr<CSSValue>, CSSPropertyID);
+ void initCSSFontFace(Document*, PassRefPtrWillBeRawPtr<CSSValue> src);
+ void initCSSFontFace(const unsigned char* data, unsigned size);
+ void setPropertyFromString(const Document*, const String&, CSSPropertyID, ExceptionState&);
+ bool setPropertyFromStyle(const StylePropertySet&, CSSPropertyID);
+ bool setPropertyValue(PassRefPtrWillBeRawPtr<CSSValue>, CSSPropertyID);
bool setFamilyValue(CSSValueList*);
void resolveReadyPromises();
+ void loadInternal(ExecutionContext*);
+ ScriptPromise fontStatusPromise(ScriptState*);
AtomicString m_family;
- RefPtr<CSSValue> m_src;
- RefPtr<CSSValue> m_style;
- RefPtr<CSSValue> m_weight;
- RefPtr<CSSValue> m_stretch;
- RefPtr<CSSValue> m_unicodeRange;
- RefPtr<CSSValue> m_variant;
- RefPtr<CSSValue> m_featureSettings;
+ RefPtrWillBeMember<CSSValue> m_src;
+ RefPtrWillBeMember<CSSValue> m_style;
+ RefPtrWillBeMember<CSSValue> m_weight;
+ RefPtrWillBeMember<CSSValue> m_stretch;
+ RefPtrWillBeMember<CSSValue> m_unicodeRange;
+ RefPtrWillBeMember<CSSValue> m_variant;
+ RefPtrWillBeMember<CSSValue> m_featureSettings;
LoadStatus m_status;
+ RefPtrWillBeMember<DOMError> m_error;
Vector<OwnPtr<FontFaceReadyPromiseResolver> > m_readyResolvers;
- CSSFontFace* m_cssFontFace;
+ OwnPtrWillBeMember<CSSFontFace> m_cssFontFace;
+ WillBeHeapVector<RefPtrWillBeMember<LoadFontCallback> > m_callbacks;
};
-typedef Vector<RefPtr<FontFace> > FontFaceArray;
+typedef WillBeHeapVector<RefPtrWillBeMember<FontFace> > FontFaceArray;
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFace.idl b/chromium/third_party/WebKit/Source/core/css/FontFace.idl
index fcfef2d143b..77d12b268e7 100644
--- a/chromium/third_party/WebKit/Source/core/css/FontFace.idl
+++ b/chromium/third_party/WebKit/Source/core/css/FontFace.idl
@@ -28,6 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://dev.w3.org/csswg/css-font-loading/#dom-fontface
+
enum FontFaceLoadStatus {
"unloaded",
"loading",
@@ -36,21 +38,26 @@ enum FontFaceLoadStatus {
};
[
+ // FIXME: should be union type http://crbug.com/240176
+ Constructor(DOMString family, DOMString source, optional Dictionary descriptors),
+ Constructor(DOMString family, ArrayBuffer source, optional Dictionary descriptors),
+ Constructor(DOMString family, ArrayBufferView source, optional Dictionary descriptors),
+ ConstructorCallWith=ExecutionContext,
+ RaisesException=Constructor,
RuntimeEnabled=FontLoadEvents,
- Constructor(DOMString family, DOMString source, Dictionary descriptors),
- RaisesException=Constructor
+ WillBeGarbageCollected,
] interface FontFace {
- [RaisesException=Setter] attribute DOMString family;
- [RaisesException=Setter] attribute DOMString style;
- [RaisesException=Setter] attribute DOMString weight;
- [RaisesException=Setter] attribute DOMString stretch;
- [RaisesException=Setter] attribute DOMString unicodeRange;
- [RaisesException=Setter] attribute DOMString variant;
- [RaisesException=Setter] attribute DOMString featureSettings;
+ [RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString family;
+ [RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString style;
+ [RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString weight;
+ [RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString stretch;
+ [RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString unicodeRange;
+ [RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString variant;
+ [RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString featureSettings;
readonly attribute FontFaceLoadStatus status;
+ [CallWith=ScriptState] readonly attribute Promise loaded;
- void load();
- [CallWith=ExecutionContext] Promise ready();
+ [CallWith=ScriptState] Promise load();
};
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFaceCache.cpp b/chromium/third_party/WebKit/Source/core/css/FontFaceCache.cpp
new file mode 100644
index 00000000000..ad5dbdc8806
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/FontFaceCache.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "core/css/FontFaceCache.h"
+
+#include "core/css/CSSFontSelector.h"
+#include "core/css/CSSSegmentedFontFace.h"
+#include "core/css/CSSValueList.h"
+#include "core/css/FontFace.h"
+#include "core/css/StyleRule.h"
+#include "core/fetch/FontResource.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "platform/FontFamilyNames.h"
+#include "platform/fonts/FontDescription.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+FontFaceCache::FontFaceCache()
+ : m_version(0)
+{
+}
+
+void FontFaceCache::add(CSSFontSelector* cssFontSelector, const StyleRuleFontFace* fontFaceRule, PassRefPtrWillBeRawPtr<FontFace> prpFontFace)
+{
+ RefPtrWillBeRawPtr<FontFace> fontFace = prpFontFace;
+ if (!m_styleRuleToFontFace.add(fontFaceRule, fontFace).isNewEntry)
+ return;
+ addFontFace(cssFontSelector, fontFace, true);
+}
+
+void FontFaceCache::addFontFace(CSSFontSelector* cssFontSelector, PassRefPtrWillBeRawPtr<FontFace> prpFontFace, bool cssConnected)
+{
+ RefPtrWillBeRawPtr<FontFace> fontFace = prpFontFace;
+
+ FamilyToTraitsMap::AddResult traitsResult = m_fontFaces.add(fontFace->family(), nullptr);
+ if (!traitsResult.storedValue->value)
+ traitsResult.storedValue->value = adoptPtrWillBeNoop(new TraitsMap);
+
+ TraitsMap::AddResult segmentedFontFaceResult = traitsResult.storedValue->value->add(fontFace->traits().mask(), nullptr);
+ if (!segmentedFontFaceResult.storedValue->value)
+ segmentedFontFaceResult.storedValue->value = CSSSegmentedFontFace::create(cssFontSelector, fontFace->traits());
+
+ segmentedFontFaceResult.storedValue->value->addFontFace(fontFace, cssConnected);
+ if (cssConnected)
+ m_cssConnectedFontFaces.add(fontFace);
+
+ ++m_version;
+}
+
+void FontFaceCache::remove(const StyleRuleFontFace* fontFaceRule)
+{
+ StyleRuleToFontFace::iterator it = m_styleRuleToFontFace.find(fontFaceRule);
+ if (it != m_styleRuleToFontFace.end()) {
+ removeFontFace(it->value.get(), true);
+ m_styleRuleToFontFace.remove(it);
+ }
+}
+
+void FontFaceCache::removeFontFace(FontFace* fontFace, bool cssConnected)
+{
+ FamilyToTraitsMap::iterator fontFacesIter = m_fontFaces.find(fontFace->family());
+ if (fontFacesIter == m_fontFaces.end())
+ return;
+ TraitsMap* familyFontFaces = fontFacesIter->value.get();
+
+ TraitsMap::iterator familyFontFacesIter = familyFontFaces->find(fontFace->traits().mask());
+ if (familyFontFacesIter == familyFontFaces->end())
+ return;
+ RefPtrWillBeRawPtr<CSSSegmentedFontFace> segmentedFontFace = familyFontFacesIter->value;
+
+ segmentedFontFace->removeFontFace(fontFace);
+ if (segmentedFontFace->isEmpty()) {
+ familyFontFaces->remove(familyFontFacesIter);
+ if (familyFontFaces->isEmpty())
+ m_fontFaces.remove(fontFacesIter);
+ }
+ m_fonts.clear();
+ if (cssConnected)
+ m_cssConnectedFontFaces.remove(fontFace);
+
+ ++m_version;
+}
+
+void FontFaceCache::clear()
+{
+ for (StyleRuleToFontFace::iterator it = m_styleRuleToFontFace.begin(); it != m_styleRuleToFontFace.end(); ++it)
+ removeFontFace(it->value.get(), true);
+ m_styleRuleToFontFace.clear();
+}
+
+static inline bool compareFontFaces(CSSSegmentedFontFace* first, CSSSegmentedFontFace* second, FontTraits desiredTraits)
+{
+ const FontTraits& firstTraits = first->traits();
+ const FontTraits& secondTraits = second->traits();
+
+ bool firstHasDesiredVariant = firstTraits.variant() == desiredTraits.variant();
+ bool secondHasDesiredVariant = secondTraits.variant() == desiredTraits.variant();
+
+ if (firstHasDesiredVariant != secondHasDesiredVariant)
+ return firstHasDesiredVariant;
+
+ // We need to check font-variant css property for CSS2.1 compatibility.
+ if (desiredTraits.variant() == FontVariantSmallCaps) {
+ // Prefer a font that has indicated that it can only support small-caps to a font that claims to support
+ // all variants. The specialized font is more likely to be true small-caps and not require synthesis.
+ bool firstRequiresSmallCaps = firstTraits.variant() == FontVariantSmallCaps;
+ bool secondRequiresSmallCaps = secondTraits.variant() == FontVariantSmallCaps;
+ if (firstRequiresSmallCaps != secondRequiresSmallCaps)
+ return firstRequiresSmallCaps;
+ }
+
+ bool firstHasDesiredStyle = firstTraits.style() == desiredTraits.style();
+ bool secondHasDesiredStyle = secondTraits.style() == desiredTraits.style();
+
+ if (firstHasDesiredStyle != secondHasDesiredStyle)
+ return firstHasDesiredStyle;
+
+ if (desiredTraits.style() == FontStyleItalic) {
+ // Prefer a font that has indicated that it can only support italics to a font that claims to support
+ // all styles. The specialized font is more likely to be the one the author wants used.
+ bool firstRequiresItalics = firstTraits.style() == FontStyleItalic;
+ bool secondRequiresItalics = secondTraits.style() == FontStyleItalic;
+ if (firstRequiresItalics != secondRequiresItalics)
+ return firstRequiresItalics;
+ }
+ if (secondTraits.weight() == desiredTraits.weight())
+ return false;
+
+ if (firstTraits.weight() == desiredTraits.weight())
+ return true;
+
+ // http://www.w3.org/TR/2011/WD-css3-fonts-20111004/#font-matching-algorithm says :
+ // - If the desired weight is less than 400, weights below the desired weight are checked in descending order followed by weights above the desired weight in ascending order until a match is found.
+ // - If the desired weight is greater than 500, weights above the desired weight are checked in ascending order followed by weights below the desired weight in descending order until a match is found.
+ // - If the desired weight is 400, 500 is checked first and then the rule for desired weights less than 400 is used.
+ // - If the desired weight is 500, 400 is checked first and then the rule for desired weights less than 400 is used.
+ static const unsigned fallbackRuleSets = 9;
+ static const unsigned rulesPerSet = 8;
+ static const FontWeight weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = {
+ { FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+ { FontWeight100, FontWeight300, FontWeight400, FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+ { FontWeight200, FontWeight100, FontWeight400, FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+ { FontWeight500, FontWeight300, FontWeight200, FontWeight100, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+ { FontWeight400, FontWeight300, FontWeight200, FontWeight100, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+ { FontWeight700, FontWeight800, FontWeight900, FontWeight500, FontWeight400, FontWeight300, FontWeight200, FontWeight100 },
+ { FontWeight800, FontWeight900, FontWeight600, FontWeight500, FontWeight400, FontWeight300, FontWeight200, FontWeight100 },
+ { FontWeight900, FontWeight700, FontWeight600, FontWeight500, FontWeight400, FontWeight300, FontWeight200, FontWeight100 },
+ { FontWeight800, FontWeight700, FontWeight600, FontWeight500, FontWeight400, FontWeight300, FontWeight200, FontWeight100 }
+ };
+
+ unsigned ruleSetIndex = static_cast<unsigned>(desiredTraits.weight());
+ ASSERT(ruleSetIndex < fallbackRuleSets);
+ const FontWeight* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex];
+ for (unsigned i = 0; i < rulesPerSet; ++i) {
+ if (secondTraits.weight() == weightFallbackRule[i])
+ return false;
+ if (firstTraits.weight() == weightFallbackRule[i])
+ return true;
+ }
+
+ return false;
+}
+
+CSSSegmentedFontFace* FontFaceCache::get(const FontDescription& fontDescription, const AtomicString& family)
+{
+ TraitsMap* familyFontFaces = m_fontFaces.get(family);
+ if (!familyFontFaces || familyFontFaces->isEmpty())
+ return 0;
+
+ FamilyToTraitsMap::AddResult traitsResult = m_fonts.add(family, nullptr);
+ if (!traitsResult.storedValue->value)
+ traitsResult.storedValue->value = adoptPtrWillBeNoop(new TraitsMap);
+
+ FontTraits traits = fontDescription.traits();
+ TraitsMap::AddResult faceResult = traitsResult.storedValue->value->add(traits.mask(), nullptr);
+ if (!faceResult.storedValue->value) {
+ for (TraitsMap::const_iterator i = familyFontFaces->begin(); i != familyFontFaces->end(); ++i) {
+ CSSSegmentedFontFace* candidate = i->value.get();
+ FontTraits candidateTraits = candidate->traits();
+ if (traits.style() == FontStyleNormal && candidateTraits.style() != FontStyleNormal)
+ continue;
+ if (traits.variant() == FontVariantNormal && candidateTraits.variant() != FontVariantNormal)
+ continue;
+ if (!faceResult.storedValue->value || compareFontFaces(candidate, faceResult.storedValue->value.get(), traits))
+ faceResult.storedValue->value = candidate;
+ }
+ }
+ return faceResult.storedValue->value.get();
+}
+
+void FontFaceCache::trace(Visitor* visitor)
+{
+ visitor->trace(m_fontFaces);
+ visitor->trace(m_fonts);
+ visitor->trace(m_styleRuleToFontFace);
+ visitor->trace(m_cssConnectedFontFaces);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFaceCache.h b/chromium/third_party/WebKit/Source/core/css/FontFaceCache.h
new file mode 100644
index 00000000000..457bc3b2919
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/FontFaceCache.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FontFaceCache_h
+#define FontFaceCache_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/HashMap.h"
+#include "wtf/ListHashSet.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+class FontFace;
+class CSSFontSelector;
+class CSSSegmentedFontFace;
+class FontDescription;
+class StyleRuleFontFace;
+
+class FontFaceCache FINAL {
+ DISALLOW_ALLOCATION();
+public:
+ FontFaceCache();
+
+ // FIXME: Remove CSSFontSelector as argument. Passing CSSFontSelector here is
+ // a result of egregious spaghettification in FontFace/FontFaceSet.
+ void add(CSSFontSelector*, const StyleRuleFontFace*, PassRefPtrWillBeRawPtr<FontFace>);
+ void remove(const StyleRuleFontFace*);
+ void clear();
+ void addFontFace(CSSFontSelector*, PassRefPtrWillBeRawPtr<FontFace>, bool cssConnected);
+ void removeFontFace(FontFace*, bool cssConnected);
+
+ // FIXME: It's sort of weird that add/remove uses StyleRuleFontFace* as key,
+ // but this function uses FontDescription/family pair.
+ CSSSegmentedFontFace* get(const FontDescription&, const AtomicString& family);
+
+ const ListHashSet<RefPtrWillBeMember<FontFace> >& cssConnectedFontFaces() const { return m_cssConnectedFontFaces; }
+
+ unsigned version() const { return m_version; }
+ void incrementVersion() { ++m_version; }
+
+ void trace(Visitor*);
+
+private:
+ typedef WillBeHeapHashMap<unsigned, RefPtrWillBeMember<CSSSegmentedFontFace> > TraitsMap;
+ typedef WillBeHeapHashMap<String, OwnPtrWillBeMember<TraitsMap>, CaseFoldingHash> FamilyToTraitsMap;
+ typedef WillBeHeapHashMap<const StyleRuleFontFace*, RefPtrWillBeMember<FontFace> > StyleRuleToFontFace;
+ FamilyToTraitsMap m_fontFaces;
+ FamilyToTraitsMap m_fonts;
+ StyleRuleToFontFace m_styleRuleToFontFace;
+ // FIXME: Oilpan: Replace by HeapLinkedHashSet or HeapListHashSet.
+ ListHashSet<RefPtrWillBeMember<FontFace> > m_cssConnectedFontFaces;
+
+ // FIXME: See if this could be ditched
+ // Used to compare Font instances, and the usage seems suspect.
+ unsigned m_version;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFaceSet.cpp b/chromium/third_party/WebKit/Source/core/css/FontFaceSet.cpp
index 38165b8a9aa..668f6efa4ca 100644
--- a/chromium/third_party/WebKit/Source/core/css/FontFaceSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/FontFaceSet.cpp
@@ -26,21 +26,22 @@
#include "config.h"
#include "core/css/FontFaceSet.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/Dictionary.h"
-#include "bindings/v8/ScriptPromiseResolver.h"
-#include "bindings/v8/ScriptScope.h"
+#include "bindings/v8/ScriptPromiseResolverWithContext.h"
#include "bindings/v8/ScriptState.h"
#include "core/css/CSSFontFaceLoadEvent.h"
-#include "core/css/CSSFontFaceSource.h"
#include "core/css/CSSFontSelector.h"
-#include "core/css/CSSParser.h"
#include "core/css/CSSSegmentedFontFace.h"
+#include "core/css/FontFaceCache.h"
#include "core/css/StylePropertySet.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/dom/StyleEngine.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/rendering/style/StyleInheritedData.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "public/platform/Platform.h"
namespace WebCore {
@@ -48,89 +49,96 @@ namespace WebCore {
static const int defaultFontSize = 10;
static const char defaultFontFamily[] = "sans-serif";
-class LoadFontPromiseResolver : public CSSSegmentedFontFace::LoadFontCallback {
+class LoadFontPromiseResolver FINAL : public FontFace::LoadFontCallback {
public:
- static PassRefPtr<LoadFontPromiseResolver> create(const FontFamily& family, ScriptPromise promise, ExecutionContext* context)
+ static PassRefPtrWillBeRawPtr<LoadFontPromiseResolver> create(FontFaceArray faces, ScriptState* scriptState)
{
- int numFamilies = 0;
- for (const FontFamily* f = &family; f; f = f->next())
- numFamilies++;
- return adoptRef<LoadFontPromiseResolver>(new LoadFontPromiseResolver(numFamilies, promise, context));
+ return adoptRefWillBeNoop(new LoadFontPromiseResolver(faces, scriptState));
}
- virtual void notifyLoaded(CSSSegmentedFontFace*) OVERRIDE;
- virtual void notifyError(CSSSegmentedFontFace*) OVERRIDE;
- void loaded(Document*);
- void error(Document*);
+ void loadFonts(ExecutionContext*);
+ ScriptPromise promise() { return m_resolver->promise(); }
+
+ virtual void notifyLoaded(FontFace*) OVERRIDE;
+ virtual void notifyError(FontFace*) OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- LoadFontPromiseResolver(int numLoading, ScriptPromise promise, ExecutionContext* context)
- : m_numLoading(numLoading)
+ LoadFontPromiseResolver(FontFaceArray faces, ScriptState* scriptState)
+ : m_numLoading(faces.size())
, m_errorOccured(false)
- , m_scriptState(ScriptState::current())
- , m_resolver(ScriptPromiseResolver::create(promise, context))
- { }
+ , m_resolver(ScriptPromiseResolverWithContext::create(scriptState))
+ {
+ m_fontFaces.swap(faces);
+ }
+ WillBeHeapVector<RefPtrWillBeMember<FontFace> > m_fontFaces;
int m_numLoading;
bool m_errorOccured;
- ScriptState* m_scriptState;
- RefPtr<ScriptPromiseResolver> m_resolver;
+ RefPtr<ScriptPromiseResolverWithContext> m_resolver;
};
-void LoadFontPromiseResolver::loaded(Document* document)
+void LoadFontPromiseResolver::loadFonts(ExecutionContext* context)
{
- m_numLoading--;
- if (m_numLoading || !document)
+ if (!m_numLoading) {
+ m_resolver->resolve(m_fontFaces);
return;
+ }
- ScriptScope scope(m_scriptState);
- if (m_errorOccured)
- m_resolver->reject(ScriptValue::createNull());
- else
- m_resolver->resolve(ScriptValue::createNull());
+ for (size_t i = 0; i < m_fontFaces.size(); i++)
+ m_fontFaces[i]->loadWithCallback(this, context);
}
-void LoadFontPromiseResolver::error(Document* document)
+void LoadFontPromiseResolver::notifyLoaded(FontFace* fontFace)
{
- m_errorOccured = true;
- loaded(document);
+ m_numLoading--;
+ if (m_numLoading || m_errorOccured)
+ return;
+
+ m_resolver->resolve(m_fontFaces);
}
-void LoadFontPromiseResolver::notifyLoaded(CSSSegmentedFontFace* face)
+void LoadFontPromiseResolver::notifyError(FontFace* fontFace)
{
- loaded(face->fontSelector()->document());
+ m_numLoading--;
+ if (!m_errorOccured) {
+ m_errorOccured = true;
+ m_resolver->reject(fontFace->error());
+ }
}
-void LoadFontPromiseResolver::notifyError(CSSSegmentedFontFace* face)
+void LoadFontPromiseResolver::trace(Visitor* visitor)
{
- error(face->fontSelector()->document());
+ visitor->trace(m_fontFaces);
+ LoadFontCallback::trace(visitor);
}
class FontsReadyPromiseResolver {
public:
- static PassOwnPtr<FontsReadyPromiseResolver> create(ScriptPromise promise, ExecutionContext* context)
+ static PassOwnPtr<FontsReadyPromiseResolver> create(ScriptState* scriptState)
{
- return adoptPtr(new FontsReadyPromiseResolver(promise, context));
+ return adoptPtr(new FontsReadyPromiseResolver(scriptState));
}
- void resolve(PassRefPtr<FontFaceSet> fontFaceSet)
+ void resolve(PassRefPtrWillBeRawPtr<FontFaceSet> fontFaceSet)
{
- ScriptScope scope(m_scriptState);
m_resolver->resolve(fontFaceSet);
}
+ ScriptPromise promise() { return m_resolver->promise(); }
+
private:
- FontsReadyPromiseResolver(ScriptPromise promise, ExecutionContext* context)
- : m_scriptState(ScriptState::current())
- , m_resolver(ScriptPromiseResolver::create(promise, context))
- { }
- ScriptState* m_scriptState;
- RefPtr<ScriptPromiseResolver> m_resolver;
+ explicit FontsReadyPromiseResolver(ScriptState* scriptState)
+ : m_resolver(ScriptPromiseResolverWithContext::create(scriptState))
+ {
+ }
+
+ RefPtr<ScriptPromiseResolverWithContext> m_resolver;
};
-FontFaceSet::FontFaceSet(Document* document)
- : ActiveDOMObject(document)
- , m_loadingCount(0)
+FontFaceSet::FontFaceSet(Document& document)
+ : ActiveDOMObject(&document)
, m_shouldFireLoadingEvent(false)
, m_asyncRunner(this, &FontFaceSet::handlePendingEventsAndPromises)
{
@@ -146,6 +154,18 @@ Document* FontFaceSet::document() const
return toDocument(executionContext());
}
+bool FontFaceSet::inActiveDocumentContext() const
+{
+ ExecutionContext* context = executionContext();
+ return context && toDocument(context)->isActive();
+}
+
+void FontFaceSet::addFontFacesToFontFaceCache(FontFaceCache* fontFaceCache, CSSFontSelector* fontSelector)
+{
+ for (ListHashSet<RefPtrWillBeMember<FontFace> >::iterator it = m_nonCSSConnectedFaces.begin(); it != m_nonCSSConnectedFaces.end(); ++it)
+ fontFaceCache->addFontFace(fontSelector, *it, false);
+}
+
const AtomicString& FontFaceSet::interfaceName() const
{
return EventTargetNames::FontFaceSet;
@@ -160,7 +180,7 @@ AtomicString FontFaceSet::status() const
{
DEFINE_STATIC_LOCAL(AtomicString, loading, ("loading", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, loaded, ("loaded", AtomicString::ConstructFromLiteral));
- return (m_loadingCount > 0 || hasLoadedFonts()) ? loading : loaded;
+ return (!m_loadingFonts.isEmpty() || hasLoadedFonts()) ? loading : loaded;
}
void FontFaceSet::handlePendingEventsAndPromisesSoon()
@@ -172,11 +192,11 @@ void FontFaceSet::handlePendingEventsAndPromisesSoon()
void FontFaceSet::didLayout()
{
- if (document()->frame()->isMainFrame())
+ if (document()->frame()->isMainFrame() && m_loadingFonts.isEmpty())
m_histogram.record();
if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
return;
- if (m_loadingCount || (!hasLoadedFonts() && m_readyResolvers.isEmpty()))
+ if (!m_loadingFonts.isEmpty() || (!hasLoadedFonts() && m_readyResolvers.isEmpty()))
return;
handlePendingEventsAndPromisesSoon();
}
@@ -213,55 +233,178 @@ void FontFaceSet::stop()
void FontFaceSet::beginFontLoading(FontFace* fontFace)
{
m_histogram.incrementCount();
- if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
- return;
-
- if (!m_loadingCount && !hasLoadedFonts()) {
- ASSERT(!m_shouldFireLoadingEvent);
- m_shouldFireLoadingEvent = true;
- handlePendingEventsAndPromisesSoon();
- }
- ++m_loadingCount;
+ addToLoadingFonts(fontFace);
}
void FontFaceSet::fontLoaded(FontFace* fontFace)
{
- if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
- return;
- m_loadedFonts.append(fontFace);
- queueDoneEvent(fontFace);
+ m_histogram.updateStatus(fontFace);
+ if (RuntimeEnabledFeatures::fontLoadEventsEnabled())
+ m_loadedFonts.append(fontFace);
+ removeFromLoadingFonts(fontFace);
}
void FontFaceSet::loadError(FontFace* fontFace)
{
- if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
- return;
- m_failedFonts.append(fontFace);
- queueDoneEvent(fontFace);
+ m_histogram.updateStatus(fontFace);
+ if (RuntimeEnabledFeatures::fontLoadEventsEnabled())
+ m_failedFonts.append(fontFace);
+ removeFromLoadingFonts(fontFace);
+}
+
+void FontFaceSet::addToLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFace)
+{
+ if (RuntimeEnabledFeatures::fontLoadEventsEnabled() && m_loadingFonts.isEmpty() && !hasLoadedFonts()) {
+ m_shouldFireLoadingEvent = true;
+ handlePendingEventsAndPromisesSoon();
+ }
+ m_loadingFonts.add(fontFace);
}
-void FontFaceSet::queueDoneEvent(FontFace* fontFace)
+void FontFaceSet::removeFromLoadingFonts(PassRefPtrWillBeRawPtr<FontFace> fontFace)
{
- ASSERT(m_loadingCount > 0);
- --m_loadingCount;
- if (!m_loadingCount)
+ m_loadingFonts.remove(fontFace);
+ if (RuntimeEnabledFeatures::fontLoadEventsEnabled() && m_loadingFonts.isEmpty())
handlePendingEventsAndPromisesSoon();
}
-ScriptPromise FontFaceSet::ready()
+ScriptPromise FontFaceSet::ready(ScriptState* scriptState)
{
- ScriptPromise promise = ScriptPromise::createPending(executionContext());
- OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::create(promise, executionContext());
+ if (!inActiveDocumentContext())
+ return ScriptPromise();
+ OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
m_readyResolvers.append(resolver.release());
handlePendingEventsAndPromisesSoon();
return promise;
}
+void FontFaceSet::add(FontFace* fontFace, ExceptionState& exceptionState)
+{
+ if (!inActiveDocumentContext())
+ return;
+ if (!fontFace) {
+ exceptionState.throwTypeError("The argument is not a FontFace.");
+ return;
+ }
+ if (m_nonCSSConnectedFaces.contains(fontFace))
+ return;
+ if (isCSSConnectedFontFace(fontFace)) {
+ exceptionState.throwDOMException(InvalidModificationError, "Cannot add a CSS-connected FontFace.");
+ return;
+ }
+ CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
+ m_nonCSSConnectedFaces.add(fontFace);
+ fontSelector->fontFaceCache()->addFontFace(fontSelector, fontFace, false);
+ if (fontFace->loadStatus() == FontFace::Loading)
+ addToLoadingFonts(fontFace);
+ fontSelector->fontFaceInvalidated();
+}
+
+void FontFaceSet::clear()
+{
+ if (!inActiveDocumentContext() || m_nonCSSConnectedFaces.isEmpty())
+ return;
+ CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
+ FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();
+ for (ListHashSet<RefPtrWillBeMember<FontFace> >::iterator it = m_nonCSSConnectedFaces.begin(); it != m_nonCSSConnectedFaces.end(); ++it) {
+ fontFaceCache->removeFontFace(it->get(), false);
+ if ((*it)->loadStatus() == FontFace::Loading)
+ removeFromLoadingFonts(*it);
+ }
+ m_nonCSSConnectedFaces.clear();
+ fontSelector->fontFaceInvalidated();
+}
+
+bool FontFaceSet::remove(FontFace* fontFace, ExceptionState& exceptionState)
+{
+ if (!inActiveDocumentContext())
+ return false;
+ if (!fontFace) {
+ exceptionState.throwTypeError("The argument is not a FontFace.");
+ return false;
+ }
+ ListHashSet<RefPtrWillBeMember<FontFace> >::iterator it = m_nonCSSConnectedFaces.find(fontFace);
+ if (it != m_nonCSSConnectedFaces.end()) {
+ m_nonCSSConnectedFaces.remove(it);
+ CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
+ fontSelector->fontFaceCache()->removeFontFace(fontFace, false);
+ if (fontFace->loadStatus() == FontFace::Loading)
+ removeFromLoadingFonts(fontFace);
+ fontSelector->fontFaceInvalidated();
+ return true;
+ }
+ if (isCSSConnectedFontFace(fontFace))
+ exceptionState.throwDOMException(InvalidModificationError, "Cannot delete a CSS-connected FontFace.");
+ return false;
+}
+
+bool FontFaceSet::has(FontFace* fontFace, ExceptionState& exceptionState) const
+{
+ if (!inActiveDocumentContext())
+ return false;
+ if (!fontFace) {
+ exceptionState.throwTypeError("The argument is not a FontFace.");
+ return false;
+ }
+ return m_nonCSSConnectedFaces.contains(fontFace) || isCSSConnectedFontFace(fontFace);
+}
+
+const ListHashSet<RefPtrWillBeMember<FontFace> >& FontFaceSet::cssConnectedFontFaceList() const
+{
+ Document* d = document();
+ d->ensureStyleResolver(); // Flush pending style changes.
+ return d->styleEngine()->fontSelector()->fontFaceCache()->cssConnectedFontFaces();
+}
+
+bool FontFaceSet::isCSSConnectedFontFace(FontFace* fontFace) const
+{
+ return cssConnectedFontFaceList().contains(fontFace);
+}
+
+void FontFaceSet::forEach(PassOwnPtr<FontFaceSetForEachCallback> callback, ScriptValue& thisArg) const
+{
+ forEachInternal(callback, &thisArg);
+}
+
+void FontFaceSet::forEach(PassOwnPtr<FontFaceSetForEachCallback> callback) const
+{
+ forEachInternal(callback, 0);
+}
+
+void FontFaceSet::forEachInternal(PassOwnPtr<FontFaceSetForEachCallback> callback, ScriptValue* thisArg) const
+{
+ if (!inActiveDocumentContext())
+ return;
+ const ListHashSet<RefPtrWillBeMember<FontFace> >& cssConnectedFaces = cssConnectedFontFaceList();
+ WillBeHeapVector<RefPtrWillBeMember<FontFace> > fontFaces;
+ fontFaces.reserveInitialCapacity(cssConnectedFaces.size() + m_nonCSSConnectedFaces.size());
+ for (ListHashSet<RefPtrWillBeMember<FontFace> >::const_iterator it = cssConnectedFaces.begin(); it != cssConnectedFaces.end(); ++it)
+ fontFaces.append(*it);
+ for (ListHashSet<RefPtrWillBeMember<FontFace> >::const_iterator it = m_nonCSSConnectedFaces.begin(); it != m_nonCSSConnectedFaces.end(); ++it)
+ fontFaces.append(*it);
+
+ for (size_t i = 0; i < fontFaces.size(); ++i) {
+ FontFace* face = fontFaces[i].get();
+ if (thisArg)
+ callback->handleItem(*thisArg, face, face, const_cast<FontFaceSet*>(this));
+ else
+ callback->handleItem(face, face, const_cast<FontFaceSet*>(this));
+ }
+}
+
+unsigned long FontFaceSet::size() const
+{
+ if (!inActiveDocumentContext())
+ return m_nonCSSConnectedFaces.size();
+ return cssConnectedFontFaceList().size() + m_nonCSSConnectedFaces.size();
+}
+
void FontFaceSet::fireDoneEventIfPossible()
{
if (m_shouldFireLoadingEvent)
return;
- if (m_loadingCount || (!hasLoadedFonts() && m_readyResolvers.isEmpty()))
+ if (!m_loadingFonts.isEmpty() || (!hasLoadedFonts() && m_readyResolvers.isEmpty()))
return;
// If the layout was invalidated in between when we thought layout
@@ -272,8 +415,8 @@ void FontFaceSet::fireDoneEventIfPossible()
return;
if (hasLoadedFonts()) {
- RefPtr<CSSFontFaceLoadEvent> doneEvent;
- RefPtr<CSSFontFaceLoadEvent> errorEvent;
+ RefPtrWillBeRawPtr<CSSFontFaceLoadEvent> doneEvent = nullptr;
+ RefPtrWillBeRawPtr<CSSFontFaceLoadEvent> errorEvent = nullptr;
doneEvent = CSSFontFaceLoadEvent::createForFontFaces(EventTypeNames::loadingdone, m_loadedFonts);
m_loadedFonts.clear();
if (!m_failedFonts.isEmpty()) {
@@ -299,60 +442,63 @@ static const String& nullToSpace(const String& s)
return s.isNull() ? space : s;
}
-Vector<RefPtr<FontFace> > FontFaceSet::match(const String& fontString, const String& text, ExceptionState& exceptionState)
+ScriptPromise FontFaceSet::load(ScriptState* scriptState, const String& fontString, const String& text)
{
- Vector<RefPtr<FontFace> > matchedFonts;
+ if (!inActiveDocumentContext())
+ return ScriptPromise();
Font font;
if (!resolveFontStyle(fontString, font)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return matchedFonts;
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ resolver->reject(DOMError::create(SyntaxError, "Could not resolve '" + fontString + "' as a font."));
+ return promise;
}
- for (const FontFamily* f = &font.family(); f; f = f->next()) {
- CSSSegmentedFontFace* face = document()->styleEngine()->fontSelector()->getFontFace(font.fontDescription(), f->family());
- if (face)
- matchedFonts.append(face->fontFaces(nullToSpace(text)));
- }
- return matchedFonts;
-}
-
-ScriptPromise FontFaceSet::load(const String& fontString, const String& text, ExceptionState& exceptionState)
-{
- Font font;
- if (!resolveFontStyle(fontString, font)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return ScriptPromise();
+ FontFaceCache* fontFaceCache = document()->styleEngine()->fontSelector()->fontFaceCache();
+ FontFaceArray faces;
+ for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
+ CSSSegmentedFontFace* segmentedFontFace = fontFaceCache->get(font.fontDescription(), f->family());
+ if (segmentedFontFace)
+ segmentedFontFace->match(nullToSpace(text), faces);
}
- Document* d = document();
- ScriptPromise promise = ScriptPromise::createPending(executionContext());
- RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(font.family(), promise, executionContext());
- for (const FontFamily* f = &font.family(); f; f = f->next()) {
- CSSSegmentedFontFace* face = d->styleEngine()->fontSelector()->getFontFace(font.fontDescription(), f->family());
- if (!face) {
- resolver->error(d);
- continue;
- }
- face->loadFont(font.fontDescription(), nullToSpace(text), resolver);
- }
+ RefPtrWillBeRawPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(faces, scriptState);
+ ScriptPromise promise = resolver->promise();
+ resolver->loadFonts(executionContext()); // After this, resolver->promise() may return null.
return promise;
}
bool FontFaceSet::check(const String& fontString, const String& text, ExceptionState& exceptionState)
{
+ if (!inActiveDocumentContext())
+ return false;
+
Font font;
if (!resolveFontStyle(fontString, font)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "Could not resolve '" + fontString + "' as a font.");
return false;
}
- for (const FontFamily* f = &font.family(); f; f = f->next()) {
- CSSSegmentedFontFace* face = document()->styleEngine()->fontSelector()->getFontFace(font.fontDescription(), f->family());
- if (!face || !face->checkFont(nullToSpace(text)))
- return false;
+ CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
+ FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();
+
+ bool hasLoadedFaces = false;
+ for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
+ CSSSegmentedFontFace* face = fontFaceCache->get(font.fontDescription(), f->family());
+ if (face) {
+ if (!face->checkFont(nullToSpace(text)))
+ return false;
+ hasLoadedFaces = true;
+ }
}
- return true;
+ if (hasLoadedFaces)
+ return true;
+ for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
+ if (fontSelector->isPlatformFontAvailable(font.fontDescription(), f->family()))
+ return true;
+ }
+ return false;
}
bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font)
@@ -361,8 +507,8 @@ bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font)
return false;
// Interpret fontString in the same way as the 'font' attribute of CanvasRenderingContext2D.
- RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::create();
- CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, HTMLStandardMode, 0);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::create();
+ BisonCSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, fontString, true, HTMLStandardMode, 0);
if (parsedStyle->isEmpty())
return false;
@@ -401,12 +547,26 @@ bool FontFaceSet::resolveFontStyle(const String& fontString, Font& font)
return true;
}
-void FontFaceSet::FontLoadHistogram::record()
+void FontFaceSet::FontLoadHistogram::updateStatus(FontFace* fontFace)
{
- if (m_recorded)
+ if (m_status == Reported)
return;
- m_recorded = true;
- blink::Platform::current()->histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1, 100, 50);
+ if (fontFace->hadBlankText())
+ m_status = HadBlankText;
+ else if (m_status == NoWebFonts)
+ m_status = DidNotHaveBlankText;
+}
+
+void FontFaceSet::FontLoadHistogram::record()
+{
+ if (!m_recorded) {
+ m_recorded = true;
+ blink::Platform::current()->histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1, 100, 50);
+ }
+ if (m_status == HadBlankText || m_status == DidNotHaveBlankText) {
+ blink::Platform::current()->histogramEnumeration("WebFont.HadBlankText", m_status == HadBlankText ? 1 : 0, 2);
+ m_status = Reported;
+ }
}
static const char* supplementName()
@@ -414,9 +574,9 @@ static const char* supplementName()
return "FontFaceSet";
}
-PassRefPtr<FontFaceSet> FontFaceSet::from(Document* document)
+PassRefPtrWillBeRawPtr<FontFaceSet> FontFaceSet::from(Document& document)
{
- RefPtr<FontFaceSet> fonts = static_cast<FontFaceSet*>(SupplementType::from(document, supplementName()));
+ RefPtrWillBeRawPtr<FontFaceSet> fonts = static_cast<FontFaceSet*>(SupplementType::from(document, supplementName()));
if (!fonts) {
fonts = FontFaceSet::create(document);
SupplementType::provideTo(document, supplementName(), fonts);
@@ -425,11 +585,22 @@ PassRefPtr<FontFaceSet> FontFaceSet::from(Document* document)
return fonts.release();
}
-void FontFaceSet::didLayout(Document* document)
+void FontFaceSet::didLayout(Document& document)
{
if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(document, supplementName())))
fonts->didLayout();
}
+#if ENABLE(OILPAN)
+void FontFaceSet::trace(Visitor* visitor)
+{
+ visitor->trace(m_loadingFonts);
+ visitor->trace(m_loadedFonts);
+ visitor->trace(m_failedFonts);
+ visitor->trace(m_nonCSSConnectedFaces);
+ DocumentSupplement::trace(visitor);
+ EventTargetWithInlineData::trace(visitor);
+}
+#endif
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFaceSet.h b/chromium/third_party/WebKit/Source/core/css/FontFaceSet.h
index ebad1329e07..5e1f54347ea 100644
--- a/chromium/third_party/WebKit/Source/core/css/FontFaceSet.h
+++ b/chromium/third_party/WebKit/Source/core/css/FontFaceSet.h
@@ -28,10 +28,10 @@
#include "bindings/v8/ScriptPromise.h"
#include "core/css/FontFace.h"
+#include "core/css/FontFaceSetForEachCallback.h"
#include "core/dom/ActiveDOMObject.h"
#include "core/events/EventListener.h"
#include "core/events/EventTarget.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "platform/AsyncMethodRunner.h"
#include "platform/RefCountedSupplement.h"
#include "wtf/PassRefPtr.h"
@@ -45,17 +45,27 @@
namespace WebCore {
+class CSSFontFace;
class CSSFontFaceSource;
+class CSSFontSelector;
class Dictionary;
class Document;
class ExceptionState;
class Font;
+class FontFaceCache;
class FontResource;
class FontsReadyPromiseResolver;
class ExecutionContext;
-class FontFaceSet : public RefCountedSupplement<Document, FontFaceSet>, public ActiveDOMObject, public EventTargetWithInlineData {
- REFCOUNTED_EVENT_TARGET(FontFaceSet);
+#if ENABLE(OILPAN)
+class FontFaceSet FINAL : public GarbageCollectedFinalized<FontFaceSet>, public HeapSupplement<Document>, public ActiveDOMObject, public EventTargetWithInlineData {
+ USING_GARBAGE_COLLECTED_MIXIN(FontFaceSet);
+ typedef HeapSupplement<Document> SupplementType;
+#else
+class FontFaceSet FINAL : public RefCountedSupplement<Document, FontFaceSet>, public ActiveDOMObject, public EventTargetWithInlineData {
+ DEFINE_EVENT_TARGET_REFCOUNTING(RefCounted<FontFaceSet>);
+ typedef RefCountedSupplement<Document, FontFaceSet> SupplementType;
+#endif
public:
virtual ~FontFaceSet();
@@ -63,11 +73,18 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingdone);
DEFINE_ATTRIBUTE_EVENT_LISTENER(loadingerror);
- Vector<RefPtr<FontFace> > match(const String& font, const String& text, ExceptionState&);
bool check(const String& font, const String& text, ExceptionState&);
- ScriptPromise load(const String& font, const String& text, ExceptionState&);
- ScriptPromise ready();
+ ScriptPromise load(ScriptState*, const String& font, const String& text);
+ ScriptPromise ready(ScriptState*);
+ void add(FontFace*, ExceptionState&);
+ void clear();
+ bool remove(FontFace*, ExceptionState&);
+ void forEach(PassOwnPtr<FontFaceSetForEachCallback>, ScriptValue& thisArg) const;
+ void forEach(PassOwnPtr<FontFaceSetForEachCallback>) const;
+ bool has(FontFace*, ExceptionState&) const;
+
+ unsigned long size() const;
AtomicString status() const;
virtual ExecutionContext* executionContext() const OVERRIDE;
@@ -85,44 +102,58 @@ public:
virtual void resume() OVERRIDE;
virtual void stop() OVERRIDE;
- static PassRefPtr<FontFaceSet> from(Document*);
- static void didLayout(Document*);
+ static PassRefPtrWillBeRawPtr<FontFaceSet> from(Document&);
+ static void didLayout(Document&);
-private:
- typedef RefCountedSupplement<Document, FontFaceSet> SupplementType;
+ void addFontFacesToFontFaceCache(FontFaceCache*, CSSFontSelector*);
+
+#if ENABLE(OILPAN)
+ virtual void trace(Visitor*) OVERRIDE;
+#endif
- static PassRefPtr<FontFaceSet> create(Document* document)
+private:
+ static PassRefPtrWillBeRawPtr<FontFaceSet> create(Document& document)
{
- return adoptRef<FontFaceSet>(new FontFaceSet(document));
+ return adoptRefWillBeNoop(new FontFaceSet(document));
}
class FontLoadHistogram {
public:
- FontLoadHistogram() : m_count(0), m_recorded(false) { }
+ enum Status { NoWebFonts, HadBlankText, DidNotHaveBlankText, Reported };
+ FontLoadHistogram() : m_status(NoWebFonts), m_count(0), m_recorded(false) { }
void incrementCount() { m_count++; }
+ void updateStatus(FontFace*);
void record();
private:
+ Status m_status;
int m_count;
bool m_recorded;
};
- FontFaceSet(Document*);
+ FontFaceSet(Document&);
bool hasLoadedFonts() const { return !m_loadedFonts.isEmpty() || !m_failedFonts.isEmpty(); }
- void queueDoneEvent(FontFace*);
+ bool inActiveDocumentContext() const;
+ void forEachInternal(PassOwnPtr<FontFaceSetForEachCallback>, ScriptValue* thisArg) const;
+ void addToLoadingFonts(PassRefPtrWillBeRawPtr<FontFace>);
+ void removeFromLoadingFonts(PassRefPtrWillBeRawPtr<FontFace>);
void fireLoadingEvent();
void fireDoneEventIfPossible();
bool resolveFontStyle(const String&, Font&);
void handlePendingEventsAndPromisesSoon();
void handlePendingEventsAndPromises();
+ const ListHashSet<RefPtrWillBeMember<FontFace> >& cssConnectedFontFaceList() const;
+ bool isCSSConnectedFontFace(FontFace*) const;
- unsigned m_loadingCount;
+ WillBeHeapHashSet<RefPtrWillBeMember<FontFace> > m_loadingFonts;
bool m_shouldFireLoadingEvent;
Vector<OwnPtr<FontsReadyPromiseResolver> > m_readyResolvers;
FontFaceArray m_loadedFonts;
FontFaceArray m_failedFonts;
+ // FIXME: Oilpan: replace with a HeapListHashSet or HeapLinkedHashSet.
+ ListHashSet<RefPtrWillBeMember<FontFace> > m_nonCSSConnectedFaces;
AsyncMethodRunner<FontFaceSet> m_asyncRunner;
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFaceSet.idl b/chromium/third_party/WebKit/Source/core/css/FontFaceSet.idl
index 643c335b562..10bc2f71838 100644
--- a/chromium/third_party/WebKit/Source/core/css/FontFaceSet.idl
+++ b/chromium/third_party/WebKit/Source/core/css/FontFaceSet.idl
@@ -32,7 +32,7 @@ enum FontFaceSetLoadStatus { "loading", "loaded" };
[
ActiveDOMObject,
- GenerateVisitDOMWrapper=document,
+ SetWrapperReferenceFrom=document,
NoInterfaceObject,
RuntimeEnabled=FontLoadEvents,
] interface FontFaceSet : EventTarget {
@@ -41,10 +41,16 @@ enum FontFaceSetLoadStatus { "loading", "loaded" };
attribute EventHandler onloadingdone;
attribute EventHandler onloadingerror;
- [RaisesException] sequence<FontFace> match(DOMString font, [Default=NullString] optional DOMString text);
- [RaisesException] boolean check(DOMString font, [Default=NullString] optional DOMString text);
- [RaisesException] Promise load(DOMString font, [Default=NullString] optional DOMString text);
- Promise ready();
+ [RaisesException] boolean check(DOMString font, optional DOMString text = null);
+ [CallWith=ScriptState] Promise load(DOMString font, optional DOMString text = null);
+ [MeasureAs=FontFaceSetReady, CallWith=ScriptState] Promise ready();
+ [RaisesException] void add(FontFace fontFace);
+ void clear();
+ [RaisesException, ImplementedAs=remove] boolean delete(FontFace fontFace);
+ void forEach(FontFaceSetForEachCallback callback, optional any thisArg);
+ [RaisesException] boolean has(FontFace fontFace);
+
+ readonly attribute unsigned long size;
readonly attribute FontFaceSetLoadStatus status;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFaceSetForEachCallback.h b/chromium/third_party/WebKit/Source/core/css/FontFaceSetForEachCallback.h
new file mode 100644
index 00000000000..8550e24bbaf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/FontFaceSetForEachCallback.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#ifndef FontFaceSetForEachCallback_h
+#define FontFaceSetForEachCallback_h
+
+#include "bindings/v8/ScriptValue.h"
+
+namespace WebCore {
+
+class FontFace;
+class FontFaceSet;
+
+class FontFaceSetForEachCallback {
+public:
+ virtual ~FontFaceSetForEachCallback() { }
+ virtual bool handleItem(ScriptValue thisValue, FontFace*, FontFace*, FontFaceSet*) = 0;
+ virtual bool handleItem(FontFace*, FontFace*, FontFaceSet*) = 0;
+};
+
+} // namespace WebCore
+
+#endif // FontFaceSetForEachCallback_h
diff --git a/chromium/third_party/WebKit/Source/core/css/FontFaceSetForEachCallback.idl b/chromium/third_party/WebKit/Source/core/css/FontFaceSetForEachCallback.idl
new file mode 100644
index 00000000000..6b9fdab7731
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/FontFaceSetForEachCallback.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+callback interface FontFaceSetForEachCallback {
+ [CallWith=ThisValue] boolean handleItem(FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
+ boolean handleItem(FontFace fontFace, FontFace fontFaceAgain, FontFaceSet set);
+};
diff --git a/chromium/third_party/WebKit/Source/core/css/FontLoader.cpp b/chromium/third_party/WebKit/Source/core/css/FontLoader.cpp
new file mode 100644
index 00000000000..189c37cf93c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/FontLoader.cpp
@@ -0,0 +1,95 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/FontLoader.h"
+
+#include "core/css/CSSFontSelector.h"
+#include "core/fetch/FontResource.h"
+#include "core/fetch/ResourceFetcher.h"
+
+namespace WebCore {
+
+FontLoader::FontLoader(CSSFontSelector* fontSelector, ResourceFetcher* resourceFetcher)
+ : m_beginLoadingTimer(this, &FontLoader::beginLoadTimerFired)
+ , m_fontSelector(fontSelector)
+ , m_resourceFetcher(resourceFetcher)
+{
+}
+
+FontLoader::~FontLoader()
+{
+#if ENABLE(OILPAN)
+ if (!m_resourceFetcher) {
+ ASSERT(m_fontsToBeginLoading.isEmpty());
+ return;
+ }
+ m_beginLoadingTimer.stop();
+
+ // When the m_fontsToBeginLoading vector is destroyed it will decrement the
+ // request counts on the ResourceFetcher for all the fonts that were pending
+ // at the time the FontLoader dies.
+#endif
+}
+
+void FontLoader::addFontToBeginLoading(FontResource* fontResource)
+{
+ if (!m_resourceFetcher || !fontResource->stillNeedsLoad())
+ return;
+
+ m_fontsToBeginLoading.append(
+ std::make_pair(fontResource, ResourceLoader::RequestCountTracker(m_resourceFetcher, fontResource)));
+ if (!m_beginLoadingTimer.isActive())
+ m_beginLoadingTimer.startOneShot(0, FROM_HERE);
+}
+
+void FontLoader::beginLoadTimerFired(Timer<WebCore::FontLoader>*)
+{
+ loadPendingFonts();
+}
+
+void FontLoader::loadPendingFonts()
+{
+ ASSERT(m_resourceFetcher);
+
+ FontsToLoadVector fontsToBeginLoading;
+ fontsToBeginLoading.swap(m_fontsToBeginLoading);
+ for (FontsToLoadVector::iterator it = fontsToBeginLoading.begin(); it != fontsToBeginLoading.end(); ++it) {
+ FontResource* fontResource = it->first.get();
+ fontResource->beginLoadIfNeeded(m_resourceFetcher);
+ }
+
+ // When the local fontsToBeginLoading vector goes out of scope it will
+ // decrement the request counts on the ResourceFetcher for all the fonts
+ // that were just loaded.
+}
+
+void FontLoader::fontFaceInvalidated()
+{
+ if (m_fontSelector)
+ m_fontSelector->fontFaceInvalidated();
+}
+
+#if !ENABLE(OILPAN)
+void FontLoader::clearResourceFetcherAndFontSelector()
+{
+ if (!m_resourceFetcher) {
+ ASSERT(m_fontsToBeginLoading.isEmpty());
+ return;
+ }
+
+ m_beginLoadingTimer.stop();
+ m_fontsToBeginLoading.clear();
+ m_resourceFetcher = nullptr;
+ m_fontSelector = nullptr;
+}
+#endif
+
+void FontLoader::trace(Visitor* visitor)
+{
+ visitor->trace(m_resourceFetcher);
+ visitor->trace(m_fontSelector);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/FontLoader.h b/chromium/third_party/WebKit/Source/core/css/FontLoader.h
new file mode 100644
index 00000000000..92f37275730
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/FontLoader.h
@@ -0,0 +1,51 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FontLoader_h
+#define FontLoader_h
+
+#include "core/fetch/ResourceLoader.h"
+#include "core/fetch/ResourcePtr.h"
+#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CSSFontSelector;
+class FontResource;
+
+class FontLoader : public RefCountedWillBeGarbageCollectedFinalized<FontLoader> {
+public:
+ static PassRefPtrWillBeRawPtr<FontLoader> create(CSSFontSelector* fontSelector, ResourceFetcher* fetcher)
+ {
+ return adoptRefWillBeNoop(new FontLoader(fontSelector, fetcher));
+ }
+ ~FontLoader();
+
+ void addFontToBeginLoading(FontResource*);
+ void loadPendingFonts();
+ void fontFaceInvalidated();
+
+#if !ENABLE(OILPAN)
+ void clearResourceFetcherAndFontSelector();
+#endif
+
+ void trace(Visitor*);
+
+private:
+ FontLoader(CSSFontSelector*, ResourceFetcher*);
+ void beginLoadTimerFired(Timer<FontLoader>*);
+
+ Timer<FontLoader> m_beginLoadingTimer;
+
+ typedef Vector<std::pair<ResourcePtr<FontResource>, ResourceLoader::RequestCountTracker> > FontsToLoadVector;
+ FontsToLoadVector m_fontsToBeginLoading;
+ RawPtrWillBeMember<CSSFontSelector> m_fontSelector;
+ RawPtrWillBeMember<ResourceFetcher> m_resourceFetcher;
+};
+
+} // namespace WebCore
+
+#endif // FontLoader_h
diff --git a/chromium/third_party/WebKit/Source/core/css/FontSize.cpp b/chromium/third_party/WebKit/Source/core/css/FontSize.cpp
index 4b545c458a8..6c1b53c5282 100644
--- a/chromium/third_party/WebKit/Source/core/css/FontSize.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/FontSize.cpp
@@ -29,7 +29,7 @@
#include "config.h"
#include "core/css/FontSize.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "core/dom/Document.h"
#include "core/frame/Settings.h"
diff --git a/chromium/third_party/WebKit/Source/core/css/HashTools.h b/chromium/third_party/WebKit/Source/core/css/HashTools.h
index c86f62d3343..309ab164218 100644
--- a/chromium/third_party/WebKit/Source/core/css/HashTools.h
+++ b/chromium/third_party/WebKit/Source/core/css/HashTools.h
@@ -32,8 +32,8 @@ struct Value {
int id;
};
-const Property* findProperty(register const char* str, register unsigned int len);
-const Value* findValue(register const char* str, register unsigned int len);
+const Property* findProperty(register const char* str, register unsigned len);
+const Value* findValue(register const char* str, register unsigned len);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/InspectorCSSOMWrappers.cpp b/chromium/third_party/WebKit/Source/core/css/InspectorCSSOMWrappers.cpp
deleted file mode 100644
index 5a99c072010..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/InspectorCSSOMWrappers.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
- * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
- * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/css/InspectorCSSOMWrappers.h"
-
-#include "core/css/CSSDefaultStyleSheets.h"
-#include "core/css/CSSImportRule.h"
-#include "core/css/CSSMediaRule.h"
-#include "core/css/CSSRegionRule.h"
-#include "core/css/CSSRule.h"
-#include "core/css/CSSStyleRule.h"
-#include "core/css/CSSStyleSheet.h"
-#include "core/css/CSSSupportsRule.h"
-#include "core/css/StyleSheetContents.h"
-#include "core/dom/StyleEngine.h"
-
-namespace WebCore {
-
-void InspectorCSSOMWrappers::collectFromStyleSheetIfNeeded(CSSStyleSheet* styleSheet)
-{
- if (!m_styleRuleToCSSOMWrapperMap.isEmpty())
- collect(styleSheet);
-}
-
-void InspectorCSSOMWrappers::reset()
-{
- m_styleRuleToCSSOMWrapperMap.clear();
- m_styleSheetCSSOMWrapperSet.clear();
-}
-
-template <class ListType>
-void InspectorCSSOMWrappers::collect(ListType* listType)
-{
- if (!listType)
- return;
- unsigned size = listType->length();
- for (unsigned i = 0; i < size; ++i) {
- CSSRule* cssRule = listType->item(i);
- switch (cssRule->type()) {
- case CSSRule::IMPORT_RULE:
- collect(toCSSImportRule(cssRule)->styleSheet());
- break;
- case CSSRule::MEDIA_RULE:
- collect(toCSSMediaRule(cssRule));
- break;
- case CSSRule::SUPPORTS_RULE:
- collect(toCSSSupportsRule(cssRule));
- break;
- case CSSRule::WEBKIT_REGION_RULE:
- collect(toCSSRegionRule(cssRule));
- break;
- case CSSRule::STYLE_RULE:
- m_styleRuleToCSSOMWrapperMap.add(toCSSStyleRule(cssRule)->styleRule(), toCSSStyleRule(cssRule));
- break;
- default:
- break;
- }
- }
-}
-
-void InspectorCSSOMWrappers::collectFromStyleSheetContents(HashSet<RefPtr<CSSStyleSheet> >& sheetWrapperSet, StyleSheetContents* styleSheet)
-{
- if (!styleSheet)
- return;
- RefPtr<CSSStyleSheet> styleSheetWrapper = CSSStyleSheet::create(styleSheet);
- sheetWrapperSet.add(styleSheetWrapper);
- collect(styleSheetWrapper.get());
-}
-
-void InspectorCSSOMWrappers::collectFromStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& sheets)
-{
- for (unsigned i = 0; i < sheets.size(); ++i)
- collect(sheets[i].get());
-}
-
-void InspectorCSSOMWrappers::collectFromStyleEngine(StyleEngine* styleSheetCollection)
-{
- Vector<const Vector<RefPtr<CSSStyleSheet> >*> activeAuthorStyleSheets;
- styleSheetCollection->getActiveAuthorStyleSheets(activeAuthorStyleSheets);
- for (size_t i = 0; i < activeAuthorStyleSheets.size(); ++i)
- collectFromStyleSheets(*activeAuthorStyleSheets[i]);
-}
-
-CSSStyleRule* InspectorCSSOMWrappers::getWrapperForRuleInSheets(StyleRule* rule, StyleEngine* styleSheetCollection)
-{
- if (m_styleRuleToCSSOMWrapperMap.isEmpty()) {
- collectFromStyleSheetContents(m_styleSheetCSSOMWrapperSet, CSSDefaultStyleSheets::defaultStyleSheet);
- collectFromStyleSheetContents(m_styleSheetCSSOMWrapperSet, CSSDefaultStyleSheets::viewportStyleSheet);
- collectFromStyleSheetContents(m_styleSheetCSSOMWrapperSet, CSSDefaultStyleSheets::quirksStyleSheet);
- collectFromStyleSheetContents(m_styleSheetCSSOMWrapperSet, CSSDefaultStyleSheets::svgStyleSheet);
- collectFromStyleSheetContents(m_styleSheetCSSOMWrapperSet, CSSDefaultStyleSheets::mediaControlsStyleSheet);
- collectFromStyleSheetContents(m_styleSheetCSSOMWrapperSet, CSSDefaultStyleSheets::fullscreenStyleSheet);
-
- collectFromStyleEngine(styleSheetCollection);
- }
- return m_styleRuleToCSSOMWrapperMap.get(rule);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/InspectorCSSOMWrappers.h b/chromium/third_party/WebKit/Source/core/css/InspectorCSSOMWrappers.h
deleted file mode 100644
index fda87899fe7..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/InspectorCSSOMWrappers.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef InspectorCSSOMWrappers_h
-#define InspectorCSSOMWrappers_h
-
-#include "wtf/Forward.h"
-#include "wtf/HashMap.h"
-#include "wtf/HashSet.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class CSSStyleRule;
-class CSSStyleSheet;
-class StyleRule;
-class StyleEngine;
-class StyleSheetContents;
-
-class InspectorCSSOMWrappers {
-public:
- // WARNING. This will construct CSSOM wrappers for all style rules and cache them in a map for significant memory cost.
- // It is here to support inspector. Don't use for any regular engine functions.
- CSSStyleRule* getWrapperForRuleInSheets(StyleRule*, StyleEngine*);
- void collectFromStyleSheetIfNeeded(CSSStyleSheet*);
- void reset();
-
-private:
- template <class ListType>
- void collect(ListType*);
-
- void collectFromStyleSheetContents(HashSet<RefPtr<CSSStyleSheet> >& sheetWrapperSet, StyleSheetContents*);
- void collectFromStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&);
- void collectFromStyleEngine(StyleEngine*);
-
- HashMap<StyleRule*, RefPtr<CSSStyleRule> > m_styleRuleToCSSOMWrapperMap;
- HashSet<RefPtr<CSSStyleSheet> > m_styleSheetCSSOMWrapperSet;
-};
-
-} // namespace WebCore
-
-#endif // InspectorCSSOMWrappers_h
diff --git a/chromium/third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp b/chromium/third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp
new file mode 100644
index 00000000000..a920bdfd0bc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/LocalFontFaceSource.h"
+
+#include "platform/fonts/FontCache.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+#include "public/platform/Platform.h"
+
+namespace WebCore {
+
+bool LocalFontFaceSource::isLocalFontAvailable(const FontDescription& fontDescription)
+{
+ return FontCache::fontCache()->isPlatformFontAvailable(fontDescription, m_fontName);
+}
+
+PassRefPtr<SimpleFontData> LocalFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+ // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter.
+ RefPtr<SimpleFontData> fontData = FontCache::fontCache()->getFontData(fontDescription, m_fontName, true);
+ m_histograms.record(fontData);
+ return fontData.release();
+}
+
+void LocalFontFaceSource::LocalFontHistograms::record(bool loadSuccess)
+{
+ if (m_reported)
+ return;
+ m_reported = true;
+ blink::Platform::current()->histogramEnumeration("WebFont.LocalFontUsed", loadSuccess ? 1 : 0, 2);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/LocalFontFaceSource.h b/chromium/third_party/WebKit/Source/core/css/LocalFontFaceSource.h
new file mode 100644
index 00000000000..3036e4f9723
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/LocalFontFaceSource.h
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LocalFontFaceSource_h
+#define LocalFontFaceSource_h
+
+#include "core/css/CSSFontFaceSource.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class LocalFontFaceSource : public CSSFontFaceSource {
+public:
+ LocalFontFaceSource(const String& fontName) : m_fontName(fontName) { }
+ virtual bool isLocal() const { return true; }
+ virtual bool isLocalFontAvailable(const FontDescription&) OVERRIDE;
+
+private:
+ virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+
+ class LocalFontHistograms {
+ public:
+ LocalFontHistograms() : m_reported(false) { }
+ void record(bool loadSuccess);
+ private:
+ bool m_reported;
+ };
+
+ AtomicString m_fontName;
+ LocalFontHistograms m_histograms;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.cpp b/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.cpp
deleted file mode 100644
index 2db2bd92e9d..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-
-#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
-#define CSS_MEDIAQUERY_NAMES_HIDE_GLOBALS 1
-#endif
-
-#include "core/css/MediaFeatureNames.h"
-
-#include "wtf/StaticConstructors.h"
-
-namespace WebCore {
-namespace MediaFeatureNames {
-
-#define DEFINE_MEDIAFEATURE_GLOBAL(name, str) \
- DEFINE_GLOBAL(AtomicString, name##MediaFeature, str)
-CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(DEFINE_MEDIAFEATURE_GLOBAL)
-#undef DEFINE_MEDIAFEATURE_GLOBAL
-
-void init()
-{
-#define INITIALIZE_GLOBAL(name, str) new (NotNull, (void*)&name##MediaFeature) AtomicString(str, AtomicString::ConstructFromLiteral);
- CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(INITIALIZE_GLOBAL)
-#undef INITIALIZE_GLOBAL
-}
-
-} // namespace MediaFeatureNames
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.h b/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.h
deleted file mode 100644
index b249625420a..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2005, 2013 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-#ifndef MediaFeatureNames_h
-#define MediaFeatureNames_h
-
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-namespace MediaFeatureNames {
-
-#define CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(macro) \
- macro(deprecatedTransition, "-webkit-transition") \
- macro(color, "color") \
- macro(colorIndex, "color-index") \
- macro(grid, "grid") \
- macro(monochrome, "monochrome") \
- macro(height, "height") \
- macro(hover, "hover") \
- macro(width, "width") \
- macro(orientation, "orientation") \
- macro(aspectRatio, "aspect-ratio") \
- macro(deviceAspectRatio, "device-aspect-ratio") \
- macro(devicePixelRatio, "-webkit-device-pixel-ratio") \
- macro(deviceHeight, "device-height") \
- macro(deviceWidth, "device-width") \
- macro(maxColor, "max-color") \
- macro(maxColorIndex, "max-color-index") \
- macro(maxAspectRatio, "max-aspect-ratio") \
- macro(maxDeviceAspectRatio, "max-device-aspect-ratio") \
- macro(maxDevicePixelRatio, "-webkit-max-device-pixel-ratio") \
- macro(maxDeviceHeight, "max-device-height") \
- macro(maxDeviceWidth, "max-device-width") \
- macro(maxHeight, "max-height") \
- macro(maxMonochrome, "max-monochrome") \
- macro(maxWidth, "max-width") \
- macro(maxResolution, "max-resolution") \
- macro(minColor, "min-color") \
- macro(minColorIndex, "min-color-index") \
- macro(minAspectRatio, "min-aspect-ratio") \
- macro(minDeviceAspectRatio, "min-device-aspect-ratio") \
- macro(minDevicePixelRatio, "-webkit-min-device-pixel-ratio") \
- macro(minDeviceHeight, "min-device-height") \
- macro(minDeviceWidth, "min-device-width") \
- macro(minHeight, "min-height") \
- macro(minMonochrome, "min-monochrome") \
- macro(minWidth, "min-width") \
- macro(minResolution, "min-resolution") \
- macro(pointer, "pointer") \
- macro(resolution, "resolution") \
- macro(transform2d, "-webkit-transform-2d") \
- macro(transform3d, "-webkit-transform-3d") \
- macro(scan, "scan") \
- macro(animation, "-webkit-animation") \
- macro(viewMode, "-webkit-view-mode")
-
-// end of macro
-
-#ifndef CSS_MEDIAQUERY_NAMES_HIDE_GLOBALS
-#define CSS_MEDIAQUERY_NAMES_DECLARE(name, str) extern const AtomicString name##MediaFeature;
-CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(CSS_MEDIAQUERY_NAMES_DECLARE)
-#undef CSS_MEDIAQUERY_NAMES_DECLARE
-#endif
-
- void init();
-
-} // namespace MediaFeatureNames
-} // namespace WebCore
-
-#endif // MediaFeatureNames_h
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.in b/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.in
new file mode 100644
index 00000000000..f94bd9bdadd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaFeatureNames.in
@@ -0,0 +1,42 @@
+namespace="MediaFeature"
+export=""
+
+color
+color-index
+grid
+monochrome
+height
+hover
+width
+orientation
+aspect-ratio
+device-aspect-ratio
+-webkit-device-pixel-ratio
+device-height
+device-width
+max-color
+max-color-index
+max-aspect-ratio
+max-device-aspect-ratio
+-webkit-max-device-pixel-ratio
+max-device-height
+max-device-width
+max-height
+max-monochrome
+max-width
+max-resolution
+min-color
+min-color-index
+min-aspect-ratio
+min-device-aspect-ratio
+-webkit-min-device-pixel-ratio
+min-device-height
+min-device-width
+min-height
+min-monochrome
+min-width
+min-resolution
+pointer
+resolution
+-webkit-transform-3d
+scan
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaList.cpp b/chromium/third_party/WebKit/Source/core/css/MediaList.cpp
index 4a4442fb83d..69fe9145188 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaList.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/MediaList.cpp
@@ -21,13 +21,14 @@
#include "core/css/MediaList.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/css/CSSParser.h"
+#include "core/MediaFeatureNames.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSStyleSheet.h"
-#include "core/css/MediaFeatureNames.h"
#include "core/css/MediaQuery.h"
#include "core/css/MediaQueryExp.h"
+#include "core/css/parser/MediaQueryParser.h"
#include "core/dom/Document.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -57,29 +58,37 @@ MediaQuerySet::MediaQuerySet()
}
MediaQuerySet::MediaQuerySet(const MediaQuerySet& o)
- : RefCounted<MediaQuerySet>()
- , m_queries(o.m_queries.size())
+ : m_queries(o.m_queries.size())
{
for (unsigned i = 0; i < m_queries.size(); ++i)
m_queries[i] = o.m_queries[i]->copy();
}
-MediaQuerySet::~MediaQuerySet()
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQuerySet)
+
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQuerySet::create(const String& mediaString)
{
+ if (mediaString.isEmpty())
+ return MediaQuerySet::create();
+
+ if (RuntimeEnabledFeatures::mediaQueryParserEnabled())
+ return MediaQueryParser::parseMediaQuerySet(mediaString);
+
+ BisonCSSParser parser(strictCSSParserContext());
+ return parser.parseMediaQueryList(mediaString);
}
-PassRefPtr<MediaQuerySet> MediaQuerySet::create(const String& mediaString)
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQuerySet::createOffMainThread(const String& mediaString)
{
if (mediaString.isEmpty())
return MediaQuerySet::create();
- CSSParser parser(HTMLStandardMode);
- return parser.parseMediaQueryList(mediaString);
+ return MediaQueryParser::parseMediaQuerySet(mediaString);
}
bool MediaQuerySet::set(const String& mediaString)
{
- RefPtr<MediaQuerySet> result = create(mediaString);
+ RefPtrWillBeRawPtr<MediaQuerySet> result = create(mediaString);
m_queries.swap(result->m_queries);
return true;
}
@@ -89,13 +98,13 @@ bool MediaQuerySet::add(const String& queryString)
// To "parse a media query" for a given string means to follow "the parse
// a media query list" steps and return "null" if more than one media query
// is returned, or else the returned media query.
- RefPtr<MediaQuerySet> result = create(queryString);
+ RefPtrWillBeRawPtr<MediaQuerySet> result = create(queryString);
// Only continue if exactly one media query is found, as described above.
if (result->m_queries.size() != 1)
return true;
- OwnPtr<MediaQuery> newQuery = result->m_queries[0].release();
+ OwnPtrWillBeRawPtr<MediaQuery> newQuery = result->m_queries[0].release();
ASSERT(newQuery);
// If comparing with any of the media queries in the collection of media
@@ -115,13 +124,13 @@ bool MediaQuerySet::remove(const String& queryStringToRemove)
// To "parse a media query" for a given string means to follow "the parse
// a media query list" steps and return "null" if more than one media query
// is returned, or else the returned media query.
- RefPtr<MediaQuerySet> result = create(queryStringToRemove);
+ RefPtrWillBeRawPtr<MediaQuerySet> result = create(queryStringToRemove);
// Only continue if exactly one media query is found, as described above.
if (result->m_queries.size() != 1)
return true;
- OwnPtr<MediaQuery> newQuery = result->m_queries[0].release();
+ OwnPtrWillBeRawPtr<MediaQuery> newQuery = result->m_queries[0].release();
ASSERT(newQuery);
// Remove any media query from the collection of media queries for which
@@ -139,7 +148,7 @@ bool MediaQuerySet::remove(const String& queryStringToRemove)
return found;
}
-void MediaQuerySet::addMediaQuery(PassOwnPtr<MediaQuery> mediaQuery)
+void MediaQuerySet::addMediaQuery(PassOwnPtrWillBeRawPtr<MediaQuery> mediaQuery)
{
m_queries.append(mediaQuery);
}
@@ -159,16 +168,25 @@ String MediaQuerySet::mediaText() const
return text.toString();
}
+void MediaQuerySet::trace(Visitor* visitor)
+{
+ // We don't support tracing of vectors of OwnPtrs (ie. OwnPtr<Vector<OwnPtr<MediaQuery> > >).
+ // Since this is a transitional object we are just ifdef'ing it out when oilpan is not enabled.
+#if ENABLE(OILPAN)
+ visitor->trace(m_queries);
+#endif
+}
+
MediaList::MediaList(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet)
: m_mediaQueries(mediaQueries)
, m_parentStyleSheet(parentSheet)
- , m_parentRule(0)
+ , m_parentRule(nullptr)
{
}
MediaList::MediaList(MediaQuerySet* mediaQueries, CSSRule* parentRule)
: m_mediaQueries(mediaQueries)
- , m_parentStyleSheet(0)
+ , m_parentStyleSheet(nullptr)
, m_parentRule(parentRule)
{
}
@@ -189,7 +207,7 @@ void MediaList::setMediaText(const String& value)
String MediaList::item(unsigned index) const
{
- const Vector<OwnPtr<MediaQuery> >& queries = m_mediaQueries->queryVector();
+ const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& queries = m_mediaQueries->queryVector();
if (index < queries.size())
return queries[index]->cssText();
return String();
@@ -201,7 +219,7 @@ void MediaList::deleteMedium(const String& medium, ExceptionState& exceptionStat
bool success = m_mediaQueries->remove(medium);
if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "Failed to delete '" + medium + "'.");
return;
}
if (m_parentStyleSheet)
@@ -214,7 +232,7 @@ void MediaList::appendMedium(const String& medium, ExceptionState& exceptionStat
bool success = m_mediaQueries->add(medium);
if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ exceptionState.throwDOMException(InvalidCharacterError, "The value provided ('" + medium + "') is not a valid medium.");
return;
}
@@ -228,31 +246,37 @@ void MediaList::reattach(MediaQuerySet* mediaQueries)
m_mediaQueries = mediaQueries;
}
-static void addResolutionWarningMessageToConsole(Document* document, const String& serializedExpression, const CSSPrimitiveValue* value)
+void MediaList::trace(Visitor* visitor)
+{
+ visitor->trace(m_mediaQueries);
+ visitor->trace(m_parentStyleSheet);
+ visitor->trace(m_parentRule);
+}
+
+static void addResolutionWarningMessageToConsole(Document* document, const String& serializedExpression, CSSPrimitiveValue::UnitType type)
{
ASSERT(document);
- ASSERT(value);
- DEFINE_STATIC_LOCAL(String, mediaQueryMessage, ("Consider using 'dppx' units instead of '%replacementUnits%', as in CSS '%replacementUnits%' means dots-per-CSS-%lengthUnit%, not dots-per-physical-%lengthUnit%, so does not correspond to the actual '%replacementUnits%' of a screen. In media query expression: "));
+ DEFINE_STATIC_LOCAL(String, mediaQueryMessage, ("Consider using 'dppx' units, as in CSS '%replacementUnits%' means dots-per-CSS-%lengthUnit%, not dots-per-physical-%lengthUnit%, so does not correspond to the actual '%replacementUnits%' of a screen. In media query expression: "));
DEFINE_STATIC_LOCAL(String, mediaValueDPI, ("dpi"));
DEFINE_STATIC_LOCAL(String, mediaValueDPCM, ("dpcm"));
DEFINE_STATIC_LOCAL(String, lengthUnitInch, ("inch"));
DEFINE_STATIC_LOCAL(String, lengthUnitCentimeter, ("centimeter"));
- String message;
- if (value->isDotsPerInch())
- message = String(mediaQueryMessage).replace("%replacementUnits%", mediaValueDPI).replace("%lengthUnit%", lengthUnitInch);
- else if (value->isDotsPerCentimeter())
- message = String(mediaQueryMessage).replace("%replacementUnits%", mediaValueDPCM).replace("%lengthUnit%", lengthUnitCentimeter);
+ StringBuilder message;
+ if (CSSPrimitiveValue::isDotsPerInch(type))
+ message.append(String(mediaQueryMessage).replace("%replacementUnits%", mediaValueDPI).replace("%lengthUnit%", lengthUnitInch));
+ else if (CSSPrimitiveValue::isDotsPerCentimeter(type))
+ message.append(String(mediaQueryMessage).replace("%replacementUnits%", mediaValueDPCM).replace("%lengthUnit%", lengthUnitCentimeter));
else
ASSERT_NOT_REACHED();
message.append(serializedExpression);
- document->addConsoleMessage(CSSMessageSource, DebugMessageLevel, message);
+ document->addConsoleMessage(CSSMessageSource, DebugMessageLevel, message.toString());
}
-static inline bool isResolutionMediaFeature(const AtomicString& mediaFeature)
+static inline bool isResolutionMediaFeature(const String& mediaFeature)
{
return mediaFeature == MediaFeatureNames::resolutionMediaFeature
|| mediaFeature == MediaFeatureNames::maxResolutionMediaFeature
@@ -264,30 +288,36 @@ void reportMediaQueryWarningIfNeeded(Document* document, const MediaQuerySet* me
if (!mediaQuerySet || !document)
return;
- const Vector<OwnPtr<MediaQuery> >& mediaQueries = mediaQuerySet->queryVector();
+ const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& mediaQueries = mediaQuerySet->queryVector();
const size_t queryCount = mediaQueries.size();
if (!queryCount)
return;
+ CSSPrimitiveValue::UnitType suspiciousType = CSSPrimitiveValue::CSS_UNKNOWN;
+ bool dotsPerPixelUsed = false;
for (size_t i = 0; i < queryCount; ++i) {
const MediaQuery* query = mediaQueries[i].get();
if (equalIgnoringCase(query->mediaType(), "print"))
continue;
- const ExpressionVector& expressions = query->expressions();
+ const ExpressionHeapVector& expressions = query->expressions();
for (size_t j = 0; j < expressions.size(); ++j) {
const MediaQueryExp* expression = expressions.at(j).get();
if (isResolutionMediaFeature(expression->mediaFeature())) {
- CSSValue* cssValue = expression->value();
- if (cssValue && cssValue->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(cssValue);
- if (primitiveValue->isDotsPerInch() || primitiveValue->isDotsPerCentimeter())
- addResolutionWarningMessageToConsole(document, mediaQuerySet->mediaText(), primitiveValue);
+ MediaQueryExpValue expValue = expression->expValue();
+ if (expValue.isValue) {
+ if (CSSPrimitiveValue::isDotsPerPixel(expValue.unit))
+ dotsPerPixelUsed = true;
+ else if (CSSPrimitiveValue::isDotsPerInch(expValue.unit) || CSSPrimitiveValue::isDotsPerCentimeter(expValue.unit))
+ suspiciousType = expValue.unit;
}
}
}
}
+
+ if (suspiciousType && !dotsPerPixelUsed)
+ addResolutionWarningMessageToConsole(document, mediaQuerySet->mediaText(), suspiciousType);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaList.h b/chromium/third_party/WebKit/Source/core/css/MediaList.h
index 80223b03421..1e32424fa54 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaList.h
+++ b/chromium/third_party/WebKit/Source/core/css/MediaList.h
@@ -22,6 +22,7 @@
#define MediaList_h
#include "core/dom/ExceptionCode.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -37,43 +38,46 @@ class ExceptionState;
class MediaList;
class MediaQuery;
-class MediaQuerySet : public RefCounted<MediaQuerySet> {
+class MediaQuerySet : public RefCountedWillBeGarbageCollected<MediaQuerySet> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQuerySet);
public:
- static PassRefPtr<MediaQuerySet> create()
+ static PassRefPtrWillBeRawPtr<MediaQuerySet> create()
{
- return adoptRef(new MediaQuerySet());
+ return adoptRefWillBeNoop(new MediaQuerySet());
}
- static PassRefPtr<MediaQuerySet> create(const String& mediaString);
- ~MediaQuerySet();
+ static PassRefPtrWillBeRawPtr<MediaQuerySet> create(const String& mediaString);
+ static PassRefPtrWillBeRawPtr<MediaQuerySet> createOffMainThread(const String& mediaString);
bool set(const String&);
bool add(const String&);
bool remove(const String&);
- void addMediaQuery(PassOwnPtr<MediaQuery>);
+ void addMediaQuery(PassOwnPtrWillBeRawPtr<MediaQuery>);
- const Vector<OwnPtr<MediaQuery> >& queryVector() const { return m_queries; }
+ const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& queryVector() const { return m_queries; }
String mediaText() const;
- PassRefPtr<MediaQuerySet> copy() const { return adoptRef(new MediaQuerySet(*this)); }
+ PassRefPtrWillBeRawPtr<MediaQuerySet> copy() const { return adoptRefWillBeNoop(new MediaQuerySet(*this)); }
+
+ void trace(Visitor*);
private:
MediaQuerySet();
MediaQuerySet(const MediaQuerySet&);
- Vector<OwnPtr<MediaQuery> > m_queries;
+ WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> > m_queries;
};
-class MediaList : public RefCounted<MediaList> {
+class MediaList : public RefCountedWillBeGarbageCollectedFinalized<MediaList> {
public:
- static PassRefPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet)
+ static PassRefPtrWillBeRawPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet)
{
- return adoptRef(new MediaList(mediaQueries, parentSheet));
+ return adoptRefWillBeNoop(new MediaList(mediaQueries, parentSheet));
}
- static PassRefPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSRule* parentRule)
+ static PassRefPtrWillBeRawPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSRule* parentRule)
{
- return adoptRef(new MediaList(mediaQueries, parentRule));
+ return adoptRefWillBeNoop(new MediaList(mediaQueries, parentRule));
}
~MediaList();
@@ -89,20 +93,28 @@ public:
// Not part of CSSOM.
CSSRule* parentRule() const { return m_parentRule; }
CSSStyleSheet* parentStyleSheet() const { return m_parentStyleSheet; }
- void clearParentStyleSheet() { ASSERT(m_parentStyleSheet); m_parentStyleSheet = 0; }
- void clearParentRule() { ASSERT(m_parentRule); m_parentRule = 0; }
+
+#if !ENABLE(OILPAN)
+ void clearParentStyleSheet() { ASSERT(m_parentStyleSheet); m_parentStyleSheet = nullptr; }
+ void clearParentRule() { ASSERT(m_parentRule); m_parentRule = nullptr; }
+#endif
+
const MediaQuerySet* queries() const { return m_mediaQueries.get(); }
void reattach(MediaQuerySet*);
+ void trace(Visitor*);
+
private:
MediaList();
MediaList(MediaQuerySet*, CSSStyleSheet* parentSheet);
MediaList(MediaQuerySet*, CSSRule* parentRule);
- RefPtr<MediaQuerySet> m_mediaQueries;
- CSSStyleSheet* m_parentStyleSheet;
- CSSRule* m_parentRule;
+ RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
+ // Cleared in ~CSSStyleSheet destructor when oilpan is not enabled.
+ RawPtrWillBeMember<CSSStyleSheet> m_parentStyleSheet;
+ // Cleared in the ~CSSMediaRule and ~CSSImportRule destructors when oilpan is not enabled.
+ RawPtrWillBeMember<CSSRule> m_parentRule;
};
// Adds message to inspector console whenever dpi or dpcm values are used for "screen" media.
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaList.idl b/chromium/third_party/WebKit/Source/core/css/MediaList.idl
index 20ef3ec8835..8db9886f3f5 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaList.idl
+++ b/chromium/third_party/WebKit/Source/core/css/MediaList.idl
@@ -25,6 +25,7 @@
// Introduced in DOM Level 2:
[
+ WillBeGarbageCollected
] interface MediaList {
[TreatNullAs=NullString, TreatReturnedNullStringAs=Null] attribute DOMString mediaText;
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQuery.cpp b/chromium/third_party/WebKit/Source/core/css/MediaQuery.cpp
index 681ac137fa2..ab20c2145d9 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQuery.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQuery.cpp
@@ -29,7 +29,9 @@
#include "config.h"
#include "core/css/MediaQuery.h"
+#include "core/MediaTypeNames.h"
#include "core/css/MediaQueryExp.h"
+#include "core/html/parser/HTMLParserIdioms.h"
#include "wtf/NonCopyingSort.h"
#include "wtf/text/StringBuilder.h"
@@ -55,7 +57,7 @@ String MediaQuery::serialize() const
return result.toString();
}
- if (m_mediaType != "all" || m_restrictor != None) {
+ if (m_mediaType != MediaTypeNames::all || m_restrictor != None) {
result.append(m_mediaType);
result.append(" and ");
}
@@ -68,18 +70,23 @@ String MediaQuery::serialize() const
return result.toString();
}
-static bool expressionCompare(const OwnPtr<MediaQueryExp>& a, const OwnPtr<MediaQueryExp>& b)
+static bool expressionCompare(const OwnPtrWillBeMember<MediaQueryExp>& a, const OwnPtrWillBeMember<MediaQueryExp>& b)
{
return codePointCompare(a->serialize(), b->serialize()) < 0;
}
-MediaQuery::MediaQuery(Restrictor r, const AtomicString& mediaType, PassOwnPtr<ExpressionVector> expressions)
+PassOwnPtrWillBeRawPtr<MediaQuery> MediaQuery::createNotAll()
+{
+ return adoptPtrWillBeNoop(new MediaQuery(MediaQuery::Not, MediaTypeNames::all, nullptr));
+}
+
+MediaQuery::MediaQuery(Restrictor r, const String& mediaType, PassOwnPtrWillBeRawPtr<ExpressionHeapVector> expressions)
: m_restrictor(r)
- , m_mediaType(mediaType.lower())
+ , m_mediaType(attemptStaticStringCreation(mediaType.lower()))
, m_expressions(expressions)
{
if (!m_expressions) {
- m_expressions = adoptPtr(new ExpressionVector);
+ m_expressions = adoptPtrWillBeNoop(new ExpressionHeapVector);
return;
}
@@ -100,7 +107,7 @@ MediaQuery::MediaQuery(Restrictor r, const AtomicString& mediaType, PassOwnPtr<E
MediaQuery::MediaQuery(const MediaQuery& o)
: m_restrictor(o.m_restrictor)
, m_mediaType(o.m_mediaType)
- , m_expressions(adoptPtr(new ExpressionVector(o.m_expressions->size())))
+ , m_expressions(adoptPtrWillBeNoop(new ExpressionHeapVector(o.m_expressions->size())))
, m_serializationCache(o.m_serializationCache)
{
for (unsigned i = 0; i < m_expressions->size(); ++i)
@@ -126,4 +133,13 @@ String MediaQuery::cssText() const
return m_serializationCache;
}
+void MediaQuery::trace(Visitor* visitor)
+{
+ // We don't support tracing of vectors of OwnPtrs (ie. OwnPtr<Vector<OwnPtr<MediaQuery> > >).
+ // Since this is a transitional object we are just ifdef'ing it out when oilpan is not enabled.
+#if ENABLE(OILPAN)
+ visitor->trace(m_expressions);
+#endif
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQuery.h b/chromium/third_party/WebKit/Source/core/css/MediaQuery.h
index fa5463ee7df..6a5197578a7 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQuery.h
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQuery.h
@@ -29,6 +29,7 @@
#ifndef MediaQuery_h
#define MediaQuery_h
+#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/StringHash.h"
@@ -37,32 +38,36 @@
namespace WebCore {
class MediaQueryExp;
-typedef Vector<OwnPtr<MediaQueryExp> > ExpressionVector;
+typedef WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > ExpressionHeapVector;
-class MediaQuery {
- WTF_MAKE_FAST_ALLOCATED;
+class MediaQuery : public NoBaseWillBeGarbageCollectedFinalized<MediaQuery> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
enum Restrictor {
Only, Not, None
};
- MediaQuery(Restrictor, const AtomicString& mediaType, PassOwnPtr<ExpressionVector> exprs);
+ static PassOwnPtrWillBeRawPtr<MediaQuery> createNotAll();
+
+ MediaQuery(Restrictor, const String& mediaType, PassOwnPtrWillBeRawPtr<ExpressionHeapVector> exprs);
~MediaQuery();
Restrictor restrictor() const { return m_restrictor; }
- const ExpressionVector& expressions() const { return *m_expressions; }
- const AtomicString& mediaType() const { return m_mediaType; }
+ const ExpressionHeapVector& expressions() const { return *m_expressions; }
+ const String& mediaType() const { return m_mediaType; }
bool operator==(const MediaQuery& other) const;
String cssText() const;
- PassOwnPtr<MediaQuery> copy() const { return adoptPtr(new MediaQuery(*this)); }
+ PassOwnPtrWillBeRawPtr<MediaQuery> copy() const { return adoptPtrWillBeNoop(new MediaQuery(*this)); }
+
+ void trace(Visitor*);
private:
MediaQuery(const MediaQuery&);
Restrictor m_restrictor;
- AtomicString m_mediaType;
- OwnPtr<ExpressionVector> m_expressions;
+ String m_mediaType;
+ OwnPtrWillBeMember<ExpressionHeapVector> m_expressions;
String m_serializationCache;
String serialize() const;
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp b/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp
index 5673e6e98fc..51a48409071 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp
@@ -30,23 +30,26 @@
#include "config.h"
#include "core/css/MediaQueryEvaluator.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
+#include "core/MediaFeatureNames.h"
+#include "core/MediaFeatures.h"
+#include "core/MediaTypeNames.h"
#include "core/css/CSSAspectRatioValue.h"
#include "core/css/CSSHelper.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSToLengthConversionData.h"
-#include "core/css/MediaFeatureNames.h"
#include "core/css/MediaList.h"
#include "core/css/MediaQuery.h"
+#include "core/css/MediaValuesDynamic.h"
#include "core/css/resolver/MediaQueryResult.h"
#include "core/dom/NodeRenderStyle.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
-#include "core/rendering/RenderLayerCompositor.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/rendering/style/RenderStyle.h"
#include "platform/PlatformScreen.h"
#include "platform/geometry/FloatRect.h"
@@ -58,38 +61,38 @@ using namespace MediaFeatureNames;
enum MediaFeaturePrefix { MinPrefix, MaxPrefix, NoPrefix };
-typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, Frame*, MediaFeaturePrefix);
+typedef bool (*EvalFunc)(const MediaQueryExpValue&, MediaFeaturePrefix, const MediaValues&);
typedef HashMap<StringImpl*, EvalFunc> FunctionMap;
static FunctionMap* gFunctionMap;
MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult)
- : m_frame(0)
- , m_style(0)
- , m_expResult(mediaFeatureResult)
+ : m_expectedResult(mediaFeatureResult)
{
}
-MediaQueryEvaluator::MediaQueryEvaluator(const AtomicString& acceptedMediaType, bool mediaFeatureResult)
+MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult)
: m_mediaType(acceptedMediaType)
- , m_frame(0)
- , m_style(0)
- , m_expResult(mediaFeatureResult)
+ , m_expectedResult(mediaFeatureResult)
{
}
MediaQueryEvaluator::MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult)
: m_mediaType(acceptedMediaType)
- , m_frame(0)
- , m_style(0)
- , m_expResult(mediaFeatureResult)
+ , m_expectedResult(mediaFeatureResult)
{
}
-MediaQueryEvaluator::MediaQueryEvaluator(const AtomicString& acceptedMediaType, Frame* frame, RenderStyle* style)
+MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, LocalFrame* frame)
: m_mediaType(acceptedMediaType)
- , m_frame(frame)
- , m_style(style)
- , m_expResult(false) // Doesn't matter when we have m_frame and m_style.
+ , m_expectedResult(false) // Doesn't matter when we have m_frame and m_style.
+ , m_mediaValues(MediaValues::createDynamicIfFrameExists(frame))
+{
+}
+
+MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, const MediaValues& mediaValues)
+ : m_mediaType(acceptedMediaType)
+ , m_expectedResult(false) // Doesn't matter when we have mediaValues.
+ , m_mediaValues(mediaValues.copy())
{
}
@@ -97,10 +100,10 @@ MediaQueryEvaluator::~MediaQueryEvaluator()
{
}
-bool MediaQueryEvaluator::mediaTypeMatch(const AtomicString& mediaTypeToMatch) const
+bool MediaQueryEvaluator::mediaTypeMatch(const String& mediaTypeToMatch) const
{
return mediaTypeToMatch.isEmpty()
- || equalIgnoringCase(mediaTypeToMatch, "all")
+ || equalIgnoringCase(mediaTypeToMatch, MediaTypeNames::all)
|| equalIgnoringCase(mediaTypeToMatch, m_mediaType);
}
@@ -109,7 +112,7 @@ bool MediaQueryEvaluator::mediaTypeMatchSpecific(const char* mediaTypeToMatch) c
// Like mediaTypeMatch, but without the special cases for "" and "all".
ASSERT(mediaTypeToMatch);
ASSERT(mediaTypeToMatch[0] != '\0');
- ASSERT(!equalIgnoringCase(mediaTypeToMatch, AtomicString("all")));
+ ASSERT(!equalIgnoringCase(mediaTypeToMatch, MediaTypeNames::all));
return equalIgnoringCase(mediaTypeToMatch, m_mediaType);
}
@@ -123,7 +126,7 @@ bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet, MediaQueryResultLi
if (!querySet)
return true;
- const Vector<OwnPtr<MediaQuery> >& queries = querySet->queryVector();
+ const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& queries = querySet->queryVector();
if (!queries.size())
return true; // Empty query list evaluates to true.
@@ -133,21 +136,22 @@ bool MediaQueryEvaluator::eval(const MediaQuerySet* querySet, MediaQueryResultLi
MediaQuery* query = queries[i].get();
if (mediaTypeMatch(query->mediaType())) {
- const ExpressionVector& expressions = query->expressions();
+ const ExpressionHeapVector& expressions = query->expressions();
// Iterate through expressions, stop if any of them eval to false (AND semantics).
size_t j = 0;
for (; j < expressions.size(); ++j) {
bool exprResult = eval(expressions.at(j).get());
if (viewportDependentMediaQueryResults && expressions.at(j)->isViewportDependent())
- viewportDependentMediaQueryResults->append(adoptRef(new MediaQueryResult(*expressions.at(j), exprResult)));
+ viewportDependentMediaQueryResults->append(adoptRefWillBeNoop(new MediaQueryResult(*expressions.at(j), exprResult)));
if (!exprResult)
break;
}
// Assume true if we are at the end of the list, otherwise assume false.
result = applyRestrictor(query->restrictor(), expressions.size() == j);
- } else
+ } else {
result = applyRestrictor(query->restrictor(), false);
+ }
}
return result;
@@ -167,41 +171,38 @@ bool compareValue(T a, T b, MediaFeaturePrefix op)
return false;
}
-static bool compareAspectRatioValue(CSSValue* value, int width, int height, MediaFeaturePrefix op)
+static bool compareAspectRatioValue(const MediaQueryExpValue& value, int width, int height, MediaFeaturePrefix op)
{
- if (value->isAspectRatioValue()) {
- CSSAspectRatioValue* aspectRatio = toCSSAspectRatioValue(value);
- return compareValue(width * static_cast<int>(aspectRatio->denominatorValue()), height * static_cast<int>(aspectRatio->numeratorValue()), op);
- }
+ if (value.isRatio)
+ return compareValue(width * static_cast<int>(value.denominator), height * static_cast<int>(value.numerator), op);
return false;
}
-static bool numberValue(CSSValue* value, float& result)
+static bool numberValue(const MediaQueryExpValue& value, float& result)
{
- if (value->isPrimitiveValue()
- && toCSSPrimitiveValue(value)->isNumber()) {
- result = toCSSPrimitiveValue(value)->getFloatValue(CSSPrimitiveValue::CSS_NUMBER);
+ if (value.isValue && value.unit == CSSPrimitiveValue::CSS_NUMBER) {
+ result = value.value;
return true;
}
return false;
}
-static bool colorMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool colorMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- int bitsPerComponent = screenDepthPerComponent(frame->view());
float number;
- if (value)
+ int bitsPerComponent = mediaValues.colorBitsPerComponent();
+ if (value.isValid())
return numberValue(value, number) && compareValue(bitsPerComponent, static_cast<int>(number), op);
return bitsPerComponent != 0;
}
-static bool colorIndexMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
+static bool colorIndexMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues&)
{
// FIXME: We currently assume that we do not support indexed displays, as it is unknown
// how to retrieve the information if the display mode is indexed. This matches Firefox.
- if (!value)
+ if (!value.isValid())
return false;
// Acording to spec, if the device does not use a color lookup table, the value is zero.
@@ -209,65 +210,55 @@ static bool colorIndexMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, Me
return numberValue(value, number) && compareValue(0, static_cast<int>(number), op);
}
-static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool monochromeMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- if (!screenIsMonochrome(frame->view())) {
- if (value) {
+ if (!mediaValues.monochromeBitsPerComponent()) {
+ if (value.isValid()) {
float number;
return numberValue(value, number) && compareValue(0, static_cast<int>(number), op);
}
return false;
}
- return colorMediaFeatureEval(value, style, frame, op);
+ return colorMediaFeatureEval(value, op, mediaValues);
}
-static IntSize viewportSize(FrameView* view)
+static bool orientationMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return view->layoutSize(ScrollableArea::IncludeScrollbars);
-}
+ int width = mediaValues.viewportWidth();
+ int height = mediaValues.viewportHeight();
-static bool orientationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
-{
- FrameView* view = frame->view();
- int width = viewportSize(view).width();
- int height = viewportSize(view).height();
- if (value && value->isPrimitiveValue()) {
- const CSSValueID id = toCSSPrimitiveValue(value)->getValueID();
+ if (value.isID) {
if (width > height) // Square viewport is portrait.
- return CSSValueLandscape == id;
- return CSSValuePortrait == id;
+ return CSSValueLandscape == value.id;
+ return CSSValuePortrait == value.id;
}
// Expression (orientation) evaluates to true if width and height >= 0.
return height >= 0 && width >= 0;
}
-static bool aspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool aspectRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- if (value) {
- FrameView* view = frame->view();
- return compareAspectRatioValue(value, viewportSize(view).width(), viewportSize(view).height(), op);
- }
+ if (value.isValid())
+ return compareAspectRatioValue(value, mediaValues.viewportWidth(), mediaValues.viewportHeight(), op);
// ({,min-,max-}aspect-ratio)
// assume if we have a device, its aspect ratio is non-zero.
return true;
}
-static bool deviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool deviceAspectRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- if (value) {
- FloatRect sg = screenRect(frame->view());
- return compareAspectRatioValue(value, static_cast<int>(sg.width()), static_cast<int>(sg.height()), op);
- }
+ if (value.isValid())
+ return compareAspectRatioValue(value, mediaValues.deviceWidth(), mediaValues.deviceHeight(), op);
// ({,min-,max-}device-aspect-ratio)
// assume if we have a device, its aspect ratio is non-zero.
return true;
}
-static bool evalResolution(CSSValue* value, Frame* frame, MediaFeaturePrefix op)
+static bool evalResolution(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
// According to MQ4, only 'screen', 'print' and 'speech' may match.
// FIXME: What should speech match? https://www.w3.org/Style/CSS/Tracker/issues/348
@@ -277,31 +268,31 @@ static bool evalResolution(CSSValue* value, Frame* frame, MediaFeaturePrefix op)
// this method only got called if this media type matches the one defined
// in the query. Thus, if if the document's media type is "print", the
// media type of the query will either be "print" or "all".
- String mediaType = frame->view()->mediaType();
- if (equalIgnoringCase(mediaType, "screen"))
- actualResolution = clampTo<float>(frame->devicePixelRatio());
- else if (equalIgnoringCase(mediaType, "print")) {
+ if (mediaValues.screenMediaType()) {
+ actualResolution = clampTo<float>(mediaValues.devicePixelRatio());
+ } else if (mediaValues.printMediaType()) {
// The resolution of images while printing should not depend on the DPI
// of the screen. Until we support proper ways of querying this info
// we use 300px which is considered minimum for current printers.
actualResolution = 300 / cssPixelsPerInch;
}
- if (!value)
+ if (!value.isValid())
return !!actualResolution;
- if (!value->isPrimitiveValue())
+ if (!value.isValue)
return false;
- CSSPrimitiveValue* resolution = toCSSPrimitiveValue(value);
-
- if (resolution->isNumber())
- return compareValue(actualResolution, resolution->getFloatValue(), op);
+ if (value.unit == CSSPrimitiveValue::CSS_NUMBER)
+ return compareValue(actualResolution, clampTo<float>(value.value), op);
- if (!resolution->isResolution())
+ if (!CSSPrimitiveValue::isResolution(value.unit))
return false;
- if (resolution->isDotsPerCentimeter()) {
+ double canonicalFactor = CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(value.unit);
+ double dppxFactor = CSSPrimitiveValue::conversionToCanonicalUnitsScaleFactor(CSSPrimitiveValue::CSS_DPPX);
+ float valueInDppx = clampTo<float>(value.value * (canonicalFactor / dppxFactor));
+ if (CSSPrimitiveValue::isDotsPerCentimeter(value.unit)) {
// To match DPCM to DPPX values, we limit to 2 decimal points.
// The http://dev.w3.org/csswg/css3-values/#absolute-lengths recommends
// "that the pixel unit refer to the whole number of device pixels that best
@@ -309,111 +300,88 @@ static bool evalResolution(CSSValue* value, Frame* frame, MediaFeaturePrefix op)
// point precision seems appropriate.
return compareValue(
floorf(0.5 + 100 * actualResolution) / 100,
- floorf(0.5 + 100 * resolution->getFloatValue(CSSPrimitiveValue::CSS_DPPX)) / 100, op);
+ floorf(0.5 + 100 * valueInDppx) / 100, op);
}
- return compareValue(actualResolution, resolution->getFloatValue(CSSPrimitiveValue::CSS_DPPX), op);
+ return compareValue(actualResolution, valueInDppx, op);
}
-static bool devicePixelRatioMediaFeatureEval(CSSValue *value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool devicePixelRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- return (!value || toCSSPrimitiveValue(value)->isNumber()) && evalResolution(value, frame, op);
+ UseCounter::count(mediaValues.document(), UseCounter::PrefixedDevicePixelRatioMediaFeature);
+
+ return (!value.isValid() || value.unit == CSSPrimitiveValue::CSS_NUMBER) && evalResolution(value, op, mediaValues);
}
-static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool resolutionMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& MediaValues)
{
- return (!value || toCSSPrimitiveValue(value)->isResolution()) && evalResolution(value, frame, op);
+ return (!value.isValid() || CSSPrimitiveValue::isResolution(value.unit)) && evalResolution(value, op, MediaValues);
}
-static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
+static bool gridMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues&)
{
// if output device is bitmap, grid: 0 == true
// assume we have bitmap device
float number;
- if (value && numberValue(value, number))
+ if (value.isValid() && numberValue(value, number))
return compareValue(static_cast<int>(number), 0, op);
return false;
}
-static bool computeLength(CSSValue* value, bool strict, RenderStyle* initialStyle, int& result)
+static bool computeLength(const MediaQueryExpValue& value, const MediaValues& mediaValues, int& result)
{
- if (!value->isPrimitiveValue())
+ if (!value.isValue)
return false;
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
-
- if (primitiveValue->isNumber()) {
- result = primitiveValue->getIntValue();
- return !strict || !result;
- }
-
- if (primitiveValue->isLength()) {
- // Relative (like EM) and root relative (like REM) units are always resolved against
- // the initial values for media queries, hence the two initialStyle parameters.
- result = primitiveValue->computeLength<int>(CSSToLengthConversionData(initialStyle, initialStyle, 1.0 /* zoom */, true /* computingFontSize */));
- return true;
+ if (value.unit == CSSPrimitiveValue::CSS_NUMBER) {
+ result = clampTo<int>(value.value);
+ return !mediaValues.strictMode() || !result;
}
+ if (CSSPrimitiveValue::isLength(value.unit))
+ return mediaValues.computeLength(value.value, value.unit, result);
return false;
}
-static bool deviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool deviceHeightMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- if (value) {
+ if (value.isValid()) {
int length;
- if (!computeLength(value, !frame->document()->inQuirksMode(), style, length))
- return false;
- int height = static_cast<int>(screenRect(frame->view()).height());
- if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk())
- height = lroundf(height * frame->page()->deviceScaleFactor());
- return compareValue(height, length, op);
+ return computeLength(value, mediaValues, length) && compareValue(static_cast<int>(mediaValues.deviceHeight()), length, op);
}
// ({,min-,max-}device-height)
// assume if we have a device, assume non-zero
return true;
}
-static bool deviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool deviceWidthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- if (value) {
+ if (value.isValid()) {
int length;
- if (!computeLength(value, !frame->document()->inQuirksMode(), style, length))
- return false;
- int width = static_cast<int>(screenRect(frame->view()).width());
- if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk())
- width = lroundf(width * frame->page()->deviceScaleFactor());
- return compareValue(width, length, op);
+ return computeLength(value, mediaValues, length) && compareValue(static_cast<int>(mediaValues.deviceWidth()), length, op);
}
// ({,min-,max-}device-width)
// assume if we have a device, assume non-zero
return true;
}
-static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool heightMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- FrameView* view = frame->view();
-
- int height = viewportSize(view).height();
- if (value) {
- if (RenderView* renderView = frame->document()->renderView())
- height = adjustForAbsoluteZoom(height, renderView);
+ int height = mediaValues.viewportHeight();
+ if (value.isValid()) {
int length;
- return computeLength(value, !frame->document()->inQuirksMode(), style, length) && compareValue(height, length, op);
+ return computeLength(value, mediaValues, length) && compareValue(height, length, op);
}
return height;
}
-static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool widthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- FrameView* view = frame->view();
-
- int width = viewportSize(view).width();
- if (value) {
- if (RenderView* renderView = frame->document()->renderView())
- width = adjustForAbsoluteZoom(width, renderView);
+ int width = mediaValues.viewportWidth();
+ if (value.isValid()) {
int length;
- return computeLength(value, !frame->document()->inQuirksMode(), style, length) && compareValue(width, length, op);
+ return computeLength(value, mediaValues, length) && compareValue(width, length, op);
}
return width;
@@ -421,255 +389,203 @@ static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* fr
// Rest of the functions are trampolines which set the prefix according to the media feature expression used.
-static bool minColorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minColorMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return colorMediaFeatureEval(value, style, frame, MinPrefix);
+ return colorMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxColorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxColorMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return colorMediaFeatureEval(value, style, frame, MaxPrefix);
+ return colorMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minColorIndexMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return colorIndexMediaFeatureEval(value, style, frame, MinPrefix);
+ return colorIndexMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxColorIndexMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return colorIndexMediaFeatureEval(value, style, frame, MaxPrefix);
+ return colorIndexMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minMonochromeMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return monochromeMediaFeatureEval(value, style, frame, MinPrefix);
+ return monochromeMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxMonochromeMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return monochromeMediaFeatureEval(value, style, frame, MaxPrefix);
+ return monochromeMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minAspectRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return aspectRatioMediaFeatureEval(value, style, frame, MinPrefix);
+ return aspectRatioMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxAspectRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return aspectRatioMediaFeatureEval(value, style, frame, MaxPrefix);
+ return aspectRatioMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minDeviceAspectRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return deviceAspectRatioMediaFeatureEval(value, style, frame, MinPrefix);
+ return deviceAspectRatioMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxDeviceAspectRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return deviceAspectRatioMediaFeatureEval(value, style, frame, MaxPrefix);
+ return deviceAspectRatioMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minDevicePixelRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return devicePixelRatioMediaFeatureEval(value, style, frame, MinPrefix);
-}
+ UseCounter::count(mediaValues.document(), UseCounter::PrefixedMinDevicePixelRatioMediaFeature);
-static bool maxDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
-{
- return devicePixelRatioMediaFeatureEval(value, style, frame, MaxPrefix);
+ return devicePixelRatioMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool minHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxDevicePixelRatioMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return heightMediaFeatureEval(value, style, frame, MinPrefix);
-}
+ UseCounter::count(mediaValues.document(), UseCounter::PrefixedMaxDevicePixelRatioMediaFeature);
-static bool maxHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
-{
- return heightMediaFeatureEval(value, style, frame, MaxPrefix);
+ return devicePixelRatioMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minHeightMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return widthMediaFeatureEval(value, style, frame, MinPrefix);
+ return heightMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxHeightMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return widthMediaFeatureEval(value, style, frame, MaxPrefix);
+ return heightMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minWidthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return deviceHeightMediaFeatureEval(value, style, frame, MinPrefix);
+ return widthMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxWidthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return deviceHeightMediaFeatureEval(value, style, frame, MaxPrefix);
+ return widthMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minDeviceHeightMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return deviceWidthMediaFeatureEval(value, style, frame, MinPrefix);
+ return deviceHeightMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxDeviceHeightMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return deviceWidthMediaFeatureEval(value, style, frame, MaxPrefix);
+ return deviceHeightMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool minResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minDeviceWidthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return resolutionMediaFeatureEval(value, style, frame, MinPrefix);
+ return deviceWidthMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool maxResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxDeviceWidthMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- return resolutionMediaFeatureEval(value, style, frame, MaxPrefix);
+ return deviceWidthMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool animationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
+static bool minResolutionMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- if (value) {
- float number;
- return numberValue(value, number) && compareValue(1, static_cast<int>(number), op);
- }
- return true;
+ return resolutionMediaFeatureEval(value, MinPrefix, mediaValues);
}
-static bool deprecatedTransitionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool maxResolutionMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- UseCounter::countDeprecation(frame->document(), UseCounter::PrefixedTransitionMediaFeature);
-
- if (value) {
- float number;
- return numberValue(value, number) && compareValue(1, static_cast<int>(number), op);
- }
- return true;
+ return resolutionMediaFeatureEval(value, MaxPrefix, mediaValues);
}
-static bool transform2dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
+static bool transform3dMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix op, const MediaValues& mediaValues)
{
- if (value) {
- float number;
- return numberValue(value, number) && compareValue(1, static_cast<int>(number), op);
- }
- return true;
-}
+ UseCounter::count(mediaValues.document(), UseCounter::PrefixedTransform3dMediaFeature);
-static bool transform3dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
-{
bool returnValueIfNoParameter;
int have3dRendering;
- bool threeDEnabled = false;
- if (RenderView* view = frame->contentRenderer())
- threeDEnabled = view->compositor()->canRender3DTransforms();
+ bool threeDEnabled = mediaValues.threeDEnabled();
returnValueIfNoParameter = threeDEnabled;
have3dRendering = threeDEnabled ? 1 : 0;
- if (value) {
+ if (value.isValid()) {
float number;
return numberValue(value, number) && compareValue(have3dRendering, static_cast<int>(number), op);
}
return returnValueIfNoParameter;
}
-static bool viewModeMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
-{
- if (!value)
- return true;
-
- return toCSSPrimitiveValue(value)->getValueID() == CSSValueWindowed;
-}
-
-enum PointerDeviceType { TouchPointer, MousePointer, NoPointer, UnknownPointer };
-
-static PointerDeviceType leastCapablePrimaryPointerDeviceType(Frame* frame)
-{
- if (frame->settings()->deviceSupportsTouch())
- return TouchPointer;
-
- // FIXME: We should also try to determine if we know we have a mouse.
- // When we do this, we'll also need to differentiate between known not to
- // have mouse or touch screen (NoPointer) and unknown (UnknownPointer).
- // We could also take into account other preferences like accessibility
- // settings to decide which of the available pointers should be considered
- // "primary".
-
- return UnknownPointer;
-}
-
-static bool hoverMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
+static bool hoverMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame);
+ MediaValues::PointerDeviceType pointer = mediaValues.pointer();
// If we're on a port that hasn't explicitly opted into providing pointer device information
// (or otherwise can't be confident in the pointer hardware available), then behave exactly
// as if this feature feature isn't supported.
- if (pointer == UnknownPointer)
+ if (pointer == MediaValues::UnknownPointer)
return false;
float number = 1;
- if (value) {
+ if (value.isValid()) {
if (!numberValue(value, number))
return false;
}
- return (pointer == NoPointer && !number)
- || (pointer == TouchPointer && !number)
- || (pointer == MousePointer && number == 1);
+ return (pointer == MediaValues::NoPointer && !number)
+ || (pointer == MediaValues::TouchPointer && !number)
+ || (pointer == MediaValues::MousePointer && number == 1);
}
-static bool pointerMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
+static bool pointerMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame);
+ MediaValues::PointerDeviceType pointer = mediaValues.pointer();
// If we're on a port that hasn't explicitly opted into providing pointer device information
// (or otherwise can't be confident in the pointer hardware available), then behave exactly
// as if this feature feature isn't supported.
- if (pointer == UnknownPointer)
+ if (pointer == MediaValues::UnknownPointer)
return false;
- if (!value)
- return pointer != NoPointer;
+ if (!value.isValid())
+ return pointer != MediaValues::NoPointer;
- if (!value->isPrimitiveValue())
+ if (!value.isID)
return false;
- const CSSValueID id = toCSSPrimitiveValue(value)->getValueID();
- return (pointer == NoPointer && id == CSSValueNone)
- || (pointer == TouchPointer && id == CSSValueCoarse)
- || (pointer == MousePointer && id == CSSValueFine);
+ return (pointer == MediaValues::NoPointer && value.id == CSSValueNone)
+ || (pointer == MediaValues::TouchPointer && value.id == CSSValueCoarse)
+ || (pointer == MediaValues::MousePointer && value.id == CSSValueFine);
}
-static bool scanMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
+static bool scanMediaFeatureEval(const MediaQueryExpValue& value, MediaFeaturePrefix, const MediaValues& mediaValues)
{
- // Scan only applies to 'tv' media.
- if (!equalIgnoringCase(frame->view()->mediaType(), "tv"))
+ if (!mediaValues.scanMediaType())
return false;
- if (!value)
+ if (!value.isValid())
return true;
- if (!value->isPrimitiveValue())
+ if (!value.isID)
return false;
// If a platform interface supplies progressive/interlace info for TVs in the
// future, it needs to be handled here. For now, assume a modern TV with
// progressive display.
- return toCSSPrimitiveValue(value)->getValueID() == CSSValueProgressive;
+ return (value.id == CSSValueProgressive);
}
static void createFunctionMap()
{
// Create the table.
gFunctionMap = new FunctionMap;
-#define ADD_TO_FUNCTIONMAP(name, str) \
+#define ADD_TO_FUNCTIONMAP(name) \
gFunctionMap->set(name##MediaFeature.impl(), name##MediaFeatureEval);
CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(ADD_TO_FUNCTIONMAP);
#undef ADD_TO_FUNCTIONMAP
@@ -677,8 +593,8 @@ static void createFunctionMap()
bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const
{
- if (!m_frame || !m_style)
- return m_expResult;
+ if (!m_mediaValues || !m_mediaValues->hasValues())
+ return m_expectedResult;
if (!gFunctionMap)
createFunctionMap();
@@ -687,7 +603,7 @@ bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const
// trampoline functions override the prefix if prefix is used.
EvalFunc func = gFunctionMap->get(expr->mediaFeature().impl());
if (func)
- return func(expr->value(), m_style.get(), m_frame, NoPrefix);
+ return func(expr->expValue(), NoPrefix, *m_mediaValues);
return false;
}
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h b/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h
index 60bd9cd78f2..64f1894e507 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluator.h
@@ -28,64 +28,67 @@
#ifndef MediaQueryEvaluator_h
#define MediaQueryEvaluator_h
+#include "platform/heap/Handle.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
class MediaQueryExp;
class MediaQueryResult;
class MediaQuerySet;
class RenderStyle;
+class MediaValues;
-typedef Vector<RefPtr<MediaQueryResult> > MediaQueryResultList;
+typedef WillBeHeapVector<RefPtrWillBeMember<MediaQueryResult> > MediaQueryResultList;
+
+// Class that evaluates css media queries as defined in
+// CSS3 Module "Media Queries" (http://www.w3.org/TR/css3-mediaqueries/)
+// Special constructors are needed, if simple media queries are to be
+// evaluated without knowledge of the medium features. This can happen
+// for example when parsing UA stylesheets, if evaluation is done
+// right after parsing.
+//
+// the boolean parameter is used to approximate results of evaluation, if
+// the device characteristics are not known. This can be used to prune the loading
+// of stylesheets to only those which are probable to match.
-/**
- * Class that evaluates css media queries as defined in
- * CSS3 Module "Media Queries" (http://www.w3.org/TR/css3-mediaqueries/)
- * Special constructors are needed, if simple media queries are to be
- * evaluated without knowledge of the medium features. This can happen
- * for example when parsing UA stylesheets, if evaluation is done
- * right after parsing.
- *
- * the boolean parameter is used to approximate results of evaluation, if
- * the device characteristics are not known. This can be used to prune the loading
- * of stylesheets to only those which are probable to match.
- */
class MediaQueryEvaluator {
WTF_MAKE_NONCOPYABLE(MediaQueryEvaluator); WTF_MAKE_FAST_ALLOCATED;
public:
- /** Creates evaluator which evaluates only simple media queries
- * Evaluator returns true for "all", and returns value of \mediaFeatureResult
- * for any media features
- */
+ // Creates evaluator which evaluates only simple media queries
+ // Evaluator returns true for "all", and returns value of \mediaFeatureResult
+ // for any media features
+
explicit MediaQueryEvaluator(bool mediaFeatureResult = false);
- /** Creates evaluator which evaluates only simple media queries
- * Evaluator returns true for acceptedMediaType and returns value of \mediafeatureResult
- * for any media features
- */
- MediaQueryEvaluator(const AtomicString& acceptedMediaType, bool mediaFeatureResult = false);
+ // Creates evaluator which evaluates only simple media queries
+ // Evaluator returns true for acceptedMediaType and returns value of \mediafeatureResult
+ // for any media features
+
+ MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult = false);
MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult = false);
- /** Creates evaluator which evaluates full media queries */
- MediaQueryEvaluator(const AtomicString& acceptedMediaType, Frame*, RenderStyle*);
+ // Creates evaluator which evaluates full media queries
+ MediaQueryEvaluator(const String& acceptedMediaType, LocalFrame*);
+
+ // Creates evaluator which evaluates in a thread-safe manner a subset of media values
+ MediaQueryEvaluator(const String& acceptedMediaType, const MediaValues&);
~MediaQueryEvaluator();
- bool mediaTypeMatch(const AtomicString& mediaTypeToMatch) const;
+ bool mediaTypeMatch(const String& mediaTypeToMatch) const;
bool mediaTypeMatchSpecific(const char* mediaTypeToMatch) const;
- /** Evaluates a list of media queries */
+ // Evaluates a list of media queries
bool eval(const MediaQuerySet*, MediaQueryResultList* = 0) const;
- /** Evaluates media query subexpression, ie "and (media-feature: value)" part */
+ // Evaluates media query subexpression, ie "and (media-feature: value)" part
bool eval(const MediaQueryExp*) const;
private:
- AtomicString m_mediaType;
- Frame* m_frame; // Not owned.
- RefPtr<RenderStyle> m_style;
- bool m_expResult;
+ String m_mediaType;
+ bool m_expectedResult;
+ RefPtr<MediaValues> m_mediaValues;
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp b/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp
new file mode 100644
index 00000000000..668077ef683
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryEvaluatorTest.cpp
@@ -0,0 +1,102 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/MediaQueryEvaluator.h"
+
+#include "core/css/MediaList.h"
+#include "core/css/MediaValuesCached.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/text/StringBuilder.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+typedef struct {
+ const char* input;
+ const bool output;
+} TestCase;
+
+TEST(MediaQueryEvaluatorTest, Basic)
+{
+ // The first string represents the input string.
+ // The second string represents the output string, if present.
+ // Otherwise, the output string is identical to the first string.
+ TestCase screenTestCases[] = {
+ {"", 1},
+ {" ", 1},
+ {"screen", 1},
+ {"screen and (color)", 1},
+ {"all and (min-width: 500px)", 1},
+ {"not screen and (color)", 0},
+ {"(min-width: 500px)", 1},
+ {"(min-width: 501px)", 0},
+ {"(max-width: 500px)", 1},
+ {"(max-width: 499px)", 0},
+ {"(width: 500px)", 1},
+ {"(width: 501px)", 0},
+ {"(min-height: 500px)", 1},
+ {"(min-height: 501px)", 0},
+ {"(max-height: 500px)", 1},
+ {"(max-height: 499px)", 0},
+ {"(height: 500px)", 1},
+ {"(height: 501px)", 0},
+ {"screen and (min-width: 400px) and (max-width: 700px)", 1},
+ {"screen and (device-aspect-ratio: 16/9)", 0},
+ {"screen and (device-aspect-ratio: 1/1)", 1},
+ {"all and (min-color: 2)", 1},
+ {"all and (min-color: 32)", 0},
+ {"all and (min-color-index: 0)", 1},
+ {"all and (min-color-index: 1)", 0},
+ {"all and (monochrome)", 0},
+ {"all and (min-monochrome: 0)", 1},
+ {"all and (grid: 0)", 1},
+ {"(resolution: 2dppx)", 1},
+ {"(resolution: 1dppx)", 0},
+ {"(orientation: portrait)", 1},
+ {"(orientation: landscape)", 0},
+ {"tv and (scan: progressive)", 0},
+ {"(pointer: coarse)", 0},
+ {"(pointer: fine)", 1},
+ {"(hover: 1)", 1},
+ {"(hover: 0)", 0},
+ {0, 0} // Do not remove the terminator line.
+ };
+ TestCase printTestCases[] = {
+ {"print and (min-resolution: 1dppx)", 1},
+ {"print and (min-resolution: 118dpcm)", 0},
+ {0, 0} // Do not remove the terminator line.
+ };
+
+ MediaValuesCached::MediaValuesCachedData data;
+ data.viewportWidth = 500;
+ data.viewportHeight = 500;
+ data.deviceWidth = 500;
+ data.deviceHeight = 500;
+ data.devicePixelRatio = 2.0;
+ data.colorBitsPerComponent = 24;
+ data.monochromeBitsPerComponent = 0;
+ data.pointer = MediaValues::MousePointer;
+ data.defaultFontSize = 16;
+ data.threeDEnabled = true;
+ data.scanMediaType = false;
+ data.screenMediaType = true;
+ data.printMediaType = false;
+ data.strictMode = true;
+ RefPtr<MediaValues> mediaValues = MediaValuesCached::create(data);
+
+ for (unsigned i = 0; screenTestCases[i].input; ++i) {
+ RefPtrWillBeRawPtr<MediaQuerySet> querySet = MediaQuerySet::create(screenTestCases[i].input);
+ MediaQueryEvaluator mediaQueryEvaluator("screen", *mediaValues);
+ ASSERT_EQ(screenTestCases[i].output, mediaQueryEvaluator.eval(querySet.get()));
+ }
+ for (unsigned i = 0; printTestCases[i].input; ++i) {
+ RefPtrWillBeRawPtr<MediaQuerySet> querySet = MediaQuerySet::create(printTestCases[i].input);
+ MediaQueryEvaluator mediaQueryEvaluator("print", *mediaValues);
+ ASSERT_EQ(printTestCases[i].output, mediaQueryEvaluator.eval(querySet.get()));
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryExp.cpp b/chromium/third_party/WebKit/Source/core/css/MediaQueryExp.cpp
index 05c0e5cffd7..14348dfeaad 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryExp.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryExp.cpp
@@ -30,214 +30,211 @@
#include "config.h"
#include "core/css/MediaQueryExp.h"
-#include "CSSValueKeywords.h"
#include "core/css/CSSAspectRatioValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/CSSParserValues.h"
#include "core/css/CSSPrimitiveValue.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+#include "platform/Decimal.h"
+#include "wtf/text/StringBuffer.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
-static inline bool featureWithCSSValueID(const AtomicString& mediaFeature, const CSSParserValue* value)
+using namespace MediaFeatureNames;
+
+static inline bool featureWithCSSValueID(const String& mediaFeature, const CSSParserValue* value)
{
if (!value->id)
return false;
- return mediaFeature == MediaFeatureNames::orientationMediaFeature
- || mediaFeature == MediaFeatureNames::viewModeMediaFeature
- || mediaFeature == MediaFeatureNames::pointerMediaFeature
- || mediaFeature == MediaFeatureNames::scanMediaFeature;
+ return mediaFeature == orientationMediaFeature
+ || mediaFeature == pointerMediaFeature
+ || mediaFeature == scanMediaFeature;
}
-static inline bool featureWithValidIdent(const AtomicString& mediaFeature, CSSValueID ident)
+static inline bool featureWithValidIdent(const String& mediaFeature, CSSValueID ident)
{
- if (mediaFeature == MediaFeatureNames::orientationMediaFeature)
+ if (mediaFeature == orientationMediaFeature)
return ident == CSSValuePortrait || ident == CSSValueLandscape;
- if (mediaFeature == MediaFeatureNames::viewModeMediaFeature) {
- switch (ident) {
- case CSSValueWindowed:
- case CSSValueFloating:
- case CSSValueFullscreen:
- case CSSValueMaximized:
- case CSSValueMinimized:
- return true;
- default:
- return false;
- }
- }
-
- if (mediaFeature == MediaFeatureNames::pointerMediaFeature)
+ if (mediaFeature == pointerMediaFeature)
return ident == CSSValueNone || ident == CSSValueCoarse || ident == CSSValueFine;
- if (mediaFeature == MediaFeatureNames::scanMediaFeature)
+ if (mediaFeature == scanMediaFeature)
return ident == CSSValueInterlace || ident == CSSValueProgressive;
ASSERT_NOT_REACHED();
return false;
}
-static inline bool featureWithValidPositiveLenghtOrNumber(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithValidPositiveLength(const String& mediaFeature, const CSSParserValue* value)
{
- if (!(((value->unit >= CSSPrimitiveValue::CSS_EMS && value->unit <= CSSPrimitiveValue::CSS_PC) || value->unit == CSSPrimitiveValue::CSS_REMS) || value->unit == CSSPrimitiveValue::CSS_NUMBER) || value->fValue < 0)
+ if (!(((value->unit >= CSSPrimitiveValue::CSS_EMS && value->unit <= CSSPrimitiveValue::CSS_PC) || value->unit == CSSPrimitiveValue::CSS_REMS) || (value->unit == CSSPrimitiveValue::CSS_NUMBER && !(value->fValue))) || value->fValue < 0)
return false;
- return mediaFeature == MediaFeatureNames::heightMediaFeature
- || mediaFeature == MediaFeatureNames::maxHeightMediaFeature
- || mediaFeature == MediaFeatureNames::minHeightMediaFeature
- || mediaFeature == MediaFeatureNames::widthMediaFeature
- || mediaFeature == MediaFeatureNames::maxWidthMediaFeature
- || mediaFeature == MediaFeatureNames::minWidthMediaFeature
- || mediaFeature == MediaFeatureNames::deviceHeightMediaFeature
- || mediaFeature == MediaFeatureNames::maxDeviceHeightMediaFeature
- || mediaFeature == MediaFeatureNames::minDeviceHeightMediaFeature
- || mediaFeature == MediaFeatureNames::deviceWidthMediaFeature
- || mediaFeature == MediaFeatureNames::maxDeviceWidthMediaFeature
- || mediaFeature == MediaFeatureNames::minDeviceWidthMediaFeature;
+
+ return mediaFeature == heightMediaFeature
+ || mediaFeature == maxHeightMediaFeature
+ || mediaFeature == minHeightMediaFeature
+ || mediaFeature == widthMediaFeature
+ || mediaFeature == maxWidthMediaFeature
+ || mediaFeature == minWidthMediaFeature
+ || mediaFeature == deviceHeightMediaFeature
+ || mediaFeature == maxDeviceHeightMediaFeature
+ || mediaFeature == minDeviceHeightMediaFeature
+ || mediaFeature == deviceWidthMediaFeature
+ || mediaFeature == minDeviceWidthMediaFeature
+ || mediaFeature == maxDeviceWidthMediaFeature;
}
-static inline bool featureWithValidDensity(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithValidDensity(const String& mediaFeature, const CSSParserValue* value)
{
if ((value->unit != CSSPrimitiveValue::CSS_DPPX && value->unit != CSSPrimitiveValue::CSS_DPI && value->unit != CSSPrimitiveValue::CSS_DPCM) || value->fValue <= 0)
return false;
- return mediaFeature == MediaFeatureNames::resolutionMediaFeature
- || mediaFeature == MediaFeatureNames::maxResolutionMediaFeature
- || mediaFeature == MediaFeatureNames::minResolutionMediaFeature;
+ return mediaFeature == resolutionMediaFeature
+ || mediaFeature == minResolutionMediaFeature
+ || mediaFeature == maxResolutionMediaFeature;
}
-static inline bool featureWithPositiveInteger(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithPositiveInteger(const String& mediaFeature, const CSSParserValue* value)
{
if (!value->isInt || value->fValue < 0)
return false;
- return mediaFeature == MediaFeatureNames::colorMediaFeature
- || mediaFeature == MediaFeatureNames::maxColorMediaFeature
- || mediaFeature == MediaFeatureNames::minColorMediaFeature
- || mediaFeature == MediaFeatureNames::colorIndexMediaFeature
- || mediaFeature == MediaFeatureNames::maxColorIndexMediaFeature
- || mediaFeature == MediaFeatureNames::minColorIndexMediaFeature
- || mediaFeature == MediaFeatureNames::monochromeMediaFeature
- || mediaFeature == MediaFeatureNames::minMonochromeMediaFeature
- || mediaFeature == MediaFeatureNames::maxMonochromeMediaFeature;
+ return mediaFeature == colorMediaFeature
+ || mediaFeature == maxColorMediaFeature
+ || mediaFeature == minColorMediaFeature
+ || mediaFeature == colorIndexMediaFeature
+ || mediaFeature == maxColorIndexMediaFeature
+ || mediaFeature == minColorIndexMediaFeature
+ || mediaFeature == monochromeMediaFeature
+ || mediaFeature == maxMonochromeMediaFeature
+ || mediaFeature == minMonochromeMediaFeature;
}
-static inline bool featureWithPositiveNumber(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithPositiveNumber(const String& mediaFeature, const CSSParserValue* value)
{
if (value->unit != CSSPrimitiveValue::CSS_NUMBER || value->fValue < 0)
return false;
- return mediaFeature == MediaFeatureNames::transform2dMediaFeature
- || mediaFeature == MediaFeatureNames::transform3dMediaFeature
- || mediaFeature == MediaFeatureNames::deprecatedTransitionMediaFeature
- || mediaFeature == MediaFeatureNames::animationMediaFeature
- || mediaFeature == MediaFeatureNames::devicePixelRatioMediaFeature
- || mediaFeature == MediaFeatureNames::maxDevicePixelRatioMediaFeature
- || mediaFeature == MediaFeatureNames::minDevicePixelRatioMediaFeature;
+ return mediaFeature == transform3dMediaFeature
+ || mediaFeature == devicePixelRatioMediaFeature
+ || mediaFeature == maxDevicePixelRatioMediaFeature
+ || mediaFeature == minDevicePixelRatioMediaFeature;
}
-static inline bool featureWithZeroOrOne(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithZeroOrOne(const String& mediaFeature, const CSSParserValue* value)
{
if (!value->isInt || !(value->fValue == 1 || !value->fValue))
return false;
- return mediaFeature == MediaFeatureNames::gridMediaFeature
- || mediaFeature == MediaFeatureNames::hoverMediaFeature;
+ return mediaFeature == gridMediaFeature
+ || mediaFeature == hoverMediaFeature;
}
-static inline bool featureWithAspectRatio(const AtomicString& mediaFeature)
+static inline bool featureWithAspectRatio(const String& mediaFeature)
{
- return mediaFeature == MediaFeatureNames::aspectRatioMediaFeature
- || mediaFeature == MediaFeatureNames::deviceAspectRatioMediaFeature
- || mediaFeature == MediaFeatureNames::minAspectRatioMediaFeature
- || mediaFeature == MediaFeatureNames::maxAspectRatioMediaFeature
- || mediaFeature == MediaFeatureNames::minDeviceAspectRatioMediaFeature
- || mediaFeature == MediaFeatureNames::maxDeviceAspectRatioMediaFeature;
+ return mediaFeature == aspectRatioMediaFeature
+ || mediaFeature == deviceAspectRatioMediaFeature
+ || mediaFeature == minAspectRatioMediaFeature
+ || mediaFeature == maxAspectRatioMediaFeature
+ || mediaFeature == minDeviceAspectRatioMediaFeature
+ || mediaFeature == maxDeviceAspectRatioMediaFeature;
}
-static inline bool featureWithoutValue(const AtomicString& mediaFeature)
+static inline bool featureWithoutValue(const String& mediaFeature)
{
// Media features that are prefixed by min/max cannot be used without a value.
- return mediaFeature == MediaFeatureNames::monochromeMediaFeature
- || mediaFeature == MediaFeatureNames::colorMediaFeature
- || mediaFeature == MediaFeatureNames::colorIndexMediaFeature
- || mediaFeature == MediaFeatureNames::gridMediaFeature
- || mediaFeature == MediaFeatureNames::heightMediaFeature
- || mediaFeature == MediaFeatureNames::widthMediaFeature
- || mediaFeature == MediaFeatureNames::deviceHeightMediaFeature
- || mediaFeature == MediaFeatureNames::deviceWidthMediaFeature
- || mediaFeature == MediaFeatureNames::orientationMediaFeature
- || mediaFeature == MediaFeatureNames::aspectRatioMediaFeature
- || mediaFeature == MediaFeatureNames::deviceAspectRatioMediaFeature
- || mediaFeature == MediaFeatureNames::hoverMediaFeature
- || mediaFeature == MediaFeatureNames::transform2dMediaFeature
- || mediaFeature == MediaFeatureNames::transform3dMediaFeature
- || mediaFeature == MediaFeatureNames::deprecatedTransitionMediaFeature
- || mediaFeature == MediaFeatureNames::animationMediaFeature
- || mediaFeature == MediaFeatureNames::viewModeMediaFeature
- || mediaFeature == MediaFeatureNames::pointerMediaFeature
- || mediaFeature == MediaFeatureNames::devicePixelRatioMediaFeature
- || mediaFeature == MediaFeatureNames::resolutionMediaFeature
- || mediaFeature == MediaFeatureNames::scanMediaFeature;
+ return mediaFeature == monochromeMediaFeature
+ || mediaFeature == colorMediaFeature
+ || mediaFeature == colorIndexMediaFeature
+ || mediaFeature == gridMediaFeature
+ || mediaFeature == heightMediaFeature
+ || mediaFeature == widthMediaFeature
+ || mediaFeature == deviceHeightMediaFeature
+ || mediaFeature == deviceWidthMediaFeature
+ || mediaFeature == orientationMediaFeature
+ || mediaFeature == aspectRatioMediaFeature
+ || mediaFeature == deviceAspectRatioMediaFeature
+ || mediaFeature == hoverMediaFeature
+ || mediaFeature == transform3dMediaFeature
+ || mediaFeature == pointerMediaFeature
+ || mediaFeature == devicePixelRatioMediaFeature
+ || mediaFeature == resolutionMediaFeature
+ || mediaFeature == scanMediaFeature;
}
bool MediaQueryExp::isViewportDependent() const
{
- return m_mediaFeature == MediaFeatureNames::widthMediaFeature
- || m_mediaFeature == MediaFeatureNames::heightMediaFeature
- || m_mediaFeature == MediaFeatureNames::minWidthMediaFeature
- || m_mediaFeature == MediaFeatureNames::minHeightMediaFeature
- || m_mediaFeature == MediaFeatureNames::maxWidthMediaFeature
- || m_mediaFeature == MediaFeatureNames::maxHeightMediaFeature
- || m_mediaFeature == MediaFeatureNames::orientationMediaFeature
- || m_mediaFeature == MediaFeatureNames::aspectRatioMediaFeature
- || m_mediaFeature == MediaFeatureNames::minAspectRatioMediaFeature
- || m_mediaFeature == MediaFeatureNames::devicePixelRatioMediaFeature
- || m_mediaFeature == MediaFeatureNames::resolutionMediaFeature
- || m_mediaFeature == MediaFeatureNames::maxAspectRatioMediaFeature;
+ return m_mediaFeature == widthMediaFeature
+ || m_mediaFeature == heightMediaFeature
+ || m_mediaFeature == minWidthMediaFeature
+ || m_mediaFeature == minHeightMediaFeature
+ || m_mediaFeature == maxWidthMediaFeature
+ || m_mediaFeature == maxHeightMediaFeature
+ || m_mediaFeature == orientationMediaFeature
+ || m_mediaFeature == aspectRatioMediaFeature
+ || m_mediaFeature == minAspectRatioMediaFeature
+ || m_mediaFeature == devicePixelRatioMediaFeature
+ || m_mediaFeature == resolutionMediaFeature
+ || m_mediaFeature == maxAspectRatioMediaFeature;
}
-MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, PassRefPtr<CSSValue> value)
+MediaQueryExp::MediaQueryExp(const MediaQueryExp& other)
+ : m_mediaFeature(other.mediaFeature())
+ , m_expValue(other.expValue())
+{
+}
+
+MediaQueryExp::MediaQueryExp(const String& mediaFeature, const MediaQueryExpValue& expValue)
: m_mediaFeature(mediaFeature)
- , m_value(value)
+ , m_expValue(expValue)
{
}
-PassOwnPtr<MediaQueryExp> MediaQueryExp::create(const AtomicString& mediaFeature, CSSParserValueList* valueList)
+PassOwnPtrWillBeRawPtr<MediaQueryExp> MediaQueryExp::createIfValid(const String& mediaFeature, CSSParserValueList* valueList)
{
- RefPtr<CSSValue> cssValue;
+ ASSERT(!mediaFeature.isNull());
+
+ MediaQueryExpValue expValue;
bool isValid = false;
+ String lowerMediaFeature = attemptStaticStringCreation(mediaFeature.lower());
// Create value for media query expression that must have 1 or more values.
- if (valueList) {
+ if (valueList && valueList->size() > 0) {
if (valueList->size() == 1) {
CSSParserValue* value = valueList->current();
+ ASSERT(value);
- if (featureWithCSSValueID(mediaFeature, value)) {
+ if (featureWithCSSValueID(lowerMediaFeature, value) && featureWithValidIdent(lowerMediaFeature, value->id)) {
// Media features that use CSSValueIDs.
- cssValue = CSSPrimitiveValue::createIdentifier(value->id);
- if (!featureWithValidIdent(mediaFeature, toCSSPrimitiveValue(cssValue.get())->getValueID()))
- cssValue.clear();
- } else if (featureWithValidDensity(mediaFeature, value)) {
- // Media features that must have non-negative <density>, ie. dppx, dpi or dpcm.
- cssValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
- } else if (featureWithValidPositiveLenghtOrNumber(mediaFeature, value)) {
- // Media features that must have non-negative <lenght> or number value.
- cssValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
- } else if (featureWithPositiveInteger(mediaFeature, value)) {
- // Media features that must have non-negative integer value.
- cssValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);
- } else if (featureWithPositiveNumber(mediaFeature, value)) {
- // Media features that must have non-negative number value.
- cssValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);
- } else if (featureWithZeroOrOne(mediaFeature, value)) {
- // Media features that must have (0|1) value.
- cssValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);
+ expValue.id = value->id;
+ expValue.unit = CSSPrimitiveValue::CSS_VALUE_ID;
+ expValue.isID = true;
+ } else if (featureWithValidDensity(lowerMediaFeature, value)
+ || featureWithValidPositiveLength(lowerMediaFeature, value)) {
+ // Media features that must have non-negative <density>, ie. dppx, dpi or dpcm,
+ // or Media features that must have non-negative <length> or number value.
+ expValue.value = value->fValue;
+ expValue.unit = (CSSPrimitiveValue::UnitType)value->unit;
+ expValue.isValue = true;
+ expValue.isInteger = value->isInt;
+ } else if (featureWithPositiveInteger(lowerMediaFeature, value)
+ || featureWithPositiveNumber(lowerMediaFeature, value)
+ || featureWithZeroOrOne(lowerMediaFeature, value)) {
+ // Media features that must have non-negative integer value,
+ // or media features that must have non-negative number value,
+ // or media features that must have (0|1) value.
+ expValue.value = value->fValue;
+ expValue.unit = CSSPrimitiveValue::CSS_NUMBER;
+ expValue.isValue = true;
+ expValue.isInteger = value->isInt;
}
- isValid = cssValue;
+ isValid = (expValue.isID || expValue.isValue);
- } else if (valueList->size() == 3 && featureWithAspectRatio(mediaFeature)) {
+ } else if (valueList->size() == 3 && featureWithAspectRatio(lowerMediaFeature)) {
// Create list of values.
// Currently accepts only <integer>/<integer>.
// Applicable to device-aspect-ratio and aspec-ratio.
@@ -260,35 +257,67 @@ PassOwnPtr<MediaQueryExp> MediaQueryExp::create(const AtomicString& mediaFeature
}
}
- if (isValid)
- cssValue = CSSAspectRatioValue::create(numeratorValue, denominatorValue);
+ if (isValid) {
+ expValue.numerator = (unsigned)numeratorValue;
+ expValue.denominator = (unsigned)denominatorValue;
+ expValue.isRatio = true;
+ }
}
- } else if (featureWithoutValue(mediaFeature)) {
+ } else if (featureWithoutValue(lowerMediaFeature)) {
isValid = true;
}
if (!isValid)
return nullptr;
- return adoptPtr(new MediaQueryExp(mediaFeature, cssValue));
+ return adoptPtrWillBeNoop(new MediaQueryExp(lowerMediaFeature, expValue));
}
MediaQueryExp::~MediaQueryExp()
{
}
+bool MediaQueryExp::operator==(const MediaQueryExp& other) const
+{
+ return (other.m_mediaFeature == m_mediaFeature)
+ && ((!other.m_expValue.isValid() && !m_expValue.isValid())
+ || (other.m_expValue.isValid() && m_expValue.isValid() && other.m_expValue.equals(m_expValue)));
+}
+
String MediaQueryExp::serialize() const
{
StringBuilder result;
result.append("(");
result.append(m_mediaFeature.lower());
- if (m_value) {
+ if (m_expValue.isValid()) {
result.append(": ");
- result.append(m_value->cssText());
+ result.append(m_expValue.cssText());
}
result.append(")");
return result.toString();
}
+static inline String printNumber(double number)
+{
+ return Decimal::fromDouble(number).toString();
+}
+
+String MediaQueryExpValue::cssText() const
+{
+ StringBuilder output;
+ if (isValue) {
+ output.append(printNumber(value));
+ output.append(CSSPrimitiveValue::unitTypeToString(unit));
+ } else if (isRatio) {
+ output.append(printNumber(numerator));
+ output.append("/");
+ output.append(printNumber(denominator));
+ } else if (isID) {
+ output.append(getValueName(id));
+ }
+
+ return output.toString();
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryExp.h b/chromium/third_party/WebKit/Source/core/css/MediaQueryExp.h
index 0586b0a6bb3..1ca45c2fa70 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryExp.h
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryExp.h
@@ -29,43 +29,82 @@
#ifndef MediaQueryExp_h
#define MediaQueryExp_h
+#include "core/CSSValueKeywords.h"
+#include "core/MediaFeatureNames.h"
+#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSValue.h"
-#include "core/css/MediaFeatureNames.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefPtr.h"
-#include "wtf/text/AtomicString.h"
namespace WebCore {
class CSSParserValueList;
-class MediaQueryExp {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassOwnPtr<MediaQueryExp> create(const AtomicString& mediaFeature, CSSParserValueList*);
- ~MediaQueryExp();
+struct MediaQueryExpValue {
+ CSSValueID id;
+ double value;
+ CSSPrimitiveValue::UnitType unit;
+ unsigned numerator;
+ unsigned denominator;
- AtomicString mediaFeature() const { return m_mediaFeature; }
+ bool isID;
+ bool isValue;
+ bool isRatio;
+ bool isInteger;
- CSSValue* value() const { return m_value.get(); }
+ MediaQueryExpValue()
+ : id(CSSValueInvalid)
+ , value(0)
+ , unit(CSSPrimitiveValue::CSS_UNKNOWN)
+ , numerator(0)
+ , denominator(1)
+ , isID(false)
+ , isValue(false)
+ , isRatio(false)
+ , isInteger(false)
+ {
+ }
- bool operator==(const MediaQueryExp& other) const
+ bool isValid() const { return (isID || isValue || isRatio); }
+ String cssText() const;
+ bool equals(const MediaQueryExpValue& expValue) const
{
- return (other.m_mediaFeature == m_mediaFeature)
- && ((!other.m_value && !m_value)
- || (other.m_value && m_value && other.m_value->equals(*m_value)));
+ if (isID)
+ return (id == expValue.id);
+ if (isValue)
+ return (value == expValue.value);
+ if (isRatio)
+ return (numerator == expValue.numerator && denominator == expValue.denominator);
+ return !expValue.isValid();
}
+};
+
+class MediaQueryExp : public NoBaseWillBeGarbageCollectedFinalized<MediaQueryExp> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+ static PassOwnPtrWillBeRawPtr<MediaQueryExp> createIfValid(const String& mediaFeature, CSSParserValueList*);
+ ~MediaQueryExp();
+
+ const String& mediaFeature() const { return m_mediaFeature; }
+
+ MediaQueryExpValue expValue() const { return m_expValue; }
+
+ bool operator==(const MediaQueryExp& other) const;
bool isViewportDependent() const;
String serialize() const;
- PassOwnPtr<MediaQueryExp> copy() const { return adoptPtr(new MediaQueryExp(*this)); }
+ PassOwnPtrWillBeRawPtr<MediaQueryExp> copy() const { return adoptPtrWillBeNoop(new MediaQueryExp(*this)); }
+
+ MediaQueryExp(const MediaQueryExp& other);
+
+ void trace(Visitor* visitor) { }
private:
- MediaQueryExp(const AtomicString& mediaFeature, PassRefPtr<CSSValue>);
+ MediaQueryExp(const String&, const MediaQueryExpValue&);
- AtomicString m_mediaFeature;
- RefPtr<CSSValue> m_value;
+ String m_mediaFeature;
+ MediaQueryExpValue m_expValue;
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryList.cpp b/chromium/third_party/WebKit/Source/core/css/MediaQueryList.cpp
index b55f3fb482d..d76b5bbec15 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryList.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryList.cpp
@@ -27,12 +27,12 @@
namespace WebCore {
-PassRefPtr<MediaQueryList> MediaQueryList::create(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<MediaQuerySet> media, bool matches)
+PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryList::create(PassRefPtrWillBeRawPtr<MediaQueryMatcher> vector, PassRefPtrWillBeRawPtr<MediaQuerySet> media, bool matches)
{
- return adoptRef(new MediaQueryList(vector, media, matches));
+ return adoptRefWillBeNoop(new MediaQueryList(vector, media, matches));
}
-MediaQueryList::MediaQueryList(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<MediaQuerySet> media, bool matches)
+MediaQueryList::MediaQueryList(PassRefPtrWillBeRawPtr<MediaQueryMatcher> vector, PassRefPtrWillBeRawPtr<MediaQuerySet> media, bool matches)
: m_matcher(vector)
, m_media(media)
, m_evaluationRound(m_matcher->evaluationRound())
@@ -41,16 +41,14 @@ MediaQueryList::MediaQueryList(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<
{
}
-MediaQueryList::~MediaQueryList()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryList)
String MediaQueryList::media() const
{
return m_media->mediaText();
}
-void MediaQueryList::addListener(PassRefPtr<MediaQueryListListener> listener)
+void MediaQueryList::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)
{
if (!listener)
return;
@@ -58,7 +56,7 @@ void MediaQueryList::addListener(PassRefPtr<MediaQueryListListener> listener)
m_matcher->addListener(listener, this);
}
-void MediaQueryList::removeListener(PassRefPtr<MediaQueryListListener> listener)
+void MediaQueryList::removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)
{
if (!listener)
return;
@@ -66,11 +64,11 @@ void MediaQueryList::removeListener(PassRefPtr<MediaQueryListListener> listener)
m_matcher->removeListener(listener.get(), this);
}
-void MediaQueryList::evaluate(MediaQueryEvaluator* evaluator, bool& notificationNeeded)
+bool MediaQueryList::evaluate(MediaQueryEvaluator* evaluator)
{
if (m_evaluationRound != m_matcher->evaluationRound() && evaluator)
setMatches(evaluator->eval(m_media.get()));
- notificationNeeded = m_changeRound == m_matcher->evaluationRound();
+ return m_changeRound == m_matcher->evaluationRound();
}
void MediaQueryList::setMatches(bool newValue)
@@ -91,4 +89,10 @@ bool MediaQueryList::matches()
return m_matches;
}
+void MediaQueryList::trace(Visitor* visitor)
+{
+ visitor->trace(m_matcher);
+ visitor->trace(m_media);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryList.h b/chromium/third_party/WebKit/Source/core/css/MediaQueryList.h
index a15bc6a304f..ba04100cc72 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryList.h
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryList.h
@@ -20,6 +20,7 @@
#ifndef MediaQueryList_h
#define MediaQueryList_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -36,25 +37,26 @@ class MediaQuerySet;
// retrieve the current value of the given media query and to add/remove listeners that
// will be called whenever the value of the query changes.
-class MediaQueryList : public RefCounted<MediaQueryList> {
+class MediaQueryList FINAL : public RefCountedWillBeGarbageCollected<MediaQueryList> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryList);
public:
- static PassRefPtr<MediaQueryList> create(PassRefPtr<MediaQueryMatcher>, PassRefPtr<MediaQuerySet>, bool);
- ~MediaQueryList();
-
+ static PassRefPtrWillBeRawPtr<MediaQueryList> create(PassRefPtrWillBeRawPtr<MediaQueryMatcher>, PassRefPtrWillBeRawPtr<MediaQuerySet>, bool);
String media() const;
bool matches();
- void addListener(PassRefPtr<MediaQueryListListener>);
- void removeListener(PassRefPtr<MediaQueryListListener>);
+ void addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>);
+ void removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>);
+
+ bool evaluate(MediaQueryEvaluator*);
- void evaluate(MediaQueryEvaluator*, bool& notificationNeeded);
+ void trace(Visitor*);
private:
- MediaQueryList(PassRefPtr<MediaQueryMatcher>, PassRefPtr<MediaQuerySet>, bool matches);
+ MediaQueryList(PassRefPtrWillBeRawPtr<MediaQueryMatcher>, PassRefPtrWillBeRawPtr<MediaQuerySet>, bool matches);
void setMatches(bool);
- RefPtr<MediaQueryMatcher> m_matcher;
- RefPtr<MediaQuerySet> m_media;
+ RefPtrWillBeMember<MediaQueryMatcher> m_matcher;
+ RefPtrWillBeMember<MediaQuerySet> m_media;
unsigned m_evaluationRound; // Indicates if the query has been evaluated after the last style selector change.
unsigned m_changeRound; // Used to know if the query has changed in the last style selector change.
bool m_matches;
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryList.idl b/chromium/third_party/WebKit/Source/core/css/MediaQueryList.idl
index 7785d8dc2c6..c60c692ac79 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryList.idl
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryList.idl
@@ -17,7 +17,8 @@
* Boston, MA 02110-1301, USA.
*/
[
- NoInterfaceObject
+ NoInterfaceObject,
+ WillBeGarbageCollected
] interface MediaQueryList {
readonly attribute DOMString media;
readonly attribute boolean matches;
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.cpp b/chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.cpp
index 494883e7ed8..7cda1b4dc65 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.cpp
@@ -20,23 +20,26 @@
#include "config.h"
#include "core/css/MediaQueryListListener.h"
-#include "V8MediaQueryList.h"
-#include "bindings/v8/ScriptFunctionCall.h"
+#include "bindings/core/v8/V8MediaQueryList.h"
+#include "bindings/v8/V8Callback.h"
+#include <v8.h>
namespace WebCore {
-void MediaQueryListListener::queryChanged(ScriptState* state, MediaQueryList* query)
+MediaQueryListListener::MediaQueryListListener(ScriptState* scriptState, const ScriptValue& function)
+ : m_scriptState(scriptState)
+ , m_function(function)
{
- ScriptCallback callback(state, m_value);
- v8::HandleScope handleScope(state->isolate());
-
- v8::Handle<v8::Context> context = state->context();
- if (context.IsEmpty())
- return; // JS may not be enabled.
+ ASSERT(m_function.isFunction());
+}
- v8::Context::Scope scope(context);
- callback.appendArgument(ScriptValue(toV8(query, v8::Handle<v8::Object>(), context->GetIsolate()), context->GetIsolate()));
- callback.call();
+void MediaQueryListListener::queryChanged(MediaQueryList* query)
+{
+ if (m_scriptState->contextIsEmpty())
+ return;
+ ScriptState::Scope scope(m_scriptState.get());
+ v8::Handle<v8::Value> args[] = { toV8(query, m_scriptState->context()->Global(), m_scriptState->isolate()) };
+ invokeCallback(m_scriptState.get(), v8::Handle<v8::Function>::Cast(m_function.v8Value()), WTF_ARRAY_LENGTH(args), args);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.h b/chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.h
index fccf99dbef1..26a921f77db 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.h
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryListListener.h
@@ -22,6 +22,7 @@
#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptValue.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
namespace WebCore {
@@ -30,22 +31,25 @@ class MediaQueryList;
// See http://dev.w3.org/csswg/cssom-view/#the-mediaquerylist-interface
-class MediaQueryListListener : public RefCounted<MediaQueryListListener> {
+class MediaQueryListListener : public RefCountedWillBeGarbageCollectedFinalized<MediaQueryListListener> {
public:
- static PassRefPtr<MediaQueryListListener> create(const ScriptValue& value)
+ static PassRefPtrWillBeRawPtr<MediaQueryListListener> create(ScriptState* scriptState, const ScriptValue& value)
{
if (!value.isFunction())
- return 0;
- return adoptRef(new MediaQueryListListener(value));
+ return nullptr;
+ return adoptRefWillBeNoop(new MediaQueryListListener(scriptState, value));
}
- void queryChanged(ScriptState*, MediaQueryList*);
+ void queryChanged(MediaQueryList*);
- bool operator==(const MediaQueryListListener& other) const { return m_value == other.m_value; }
+ bool operator==(const MediaQueryListListener& other) const { return m_function == other.m_function; }
+
+ void trace(Visitor*) { }
private:
- MediaQueryListListener(const ScriptValue& value) : m_value(value) { }
+ MediaQueryListListener(ScriptState*, const ScriptValue&);
- ScriptValue m_value;
+ RefPtr<ScriptState> m_scriptState;
+ ScriptValue m_function;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp b/chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp
index 9051099e17c..1821634634a 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.cpp
@@ -26,27 +26,27 @@
#include "core/css/MediaQueryListListener.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-MediaQueryMatcher::Listener::Listener(PassRefPtr<MediaQueryListListener> listener, PassRefPtr<MediaQueryList> query)
+MediaQueryMatcher::Listener::Listener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query)
: m_listener(listener)
, m_query(query)
{
}
-MediaQueryMatcher::Listener::~Listener()
+void MediaQueryMatcher::Listener::evaluate(MediaQueryEvaluator* evaluator)
{
+ if (m_query->evaluate(evaluator))
+ m_listener->queryChanged(m_query.get());
}
-void MediaQueryMatcher::Listener::evaluate(ScriptState* state, MediaQueryEvaluator* evaluator)
+void MediaQueryMatcher::Listener::trace(Visitor* visitor)
{
- bool notify;
- m_query->evaluate(evaluator, notify);
- if (notify)
- m_listener->queryChanged(state, m_query.get());
+ visitor->trace(m_listener);
+ visitor->trace(m_query);
}
MediaQueryMatcher::MediaQueryMatcher(Document* document)
@@ -56,14 +56,12 @@ MediaQueryMatcher::MediaQueryMatcher(Document* document)
ASSERT(m_document);
}
-MediaQueryMatcher::~MediaQueryMatcher()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher)
void MediaQueryMatcher::documentDestroyed()
{
m_listeners.clear();
- m_document = 0;
+ m_document = nullptr;
}
AtomicString MediaQueryMatcher::mediaType() const
@@ -79,14 +77,7 @@ PassOwnPtr<MediaQueryEvaluator> MediaQueryMatcher::prepareEvaluator() const
if (!m_document || !m_document->frame())
return nullptr;
- Element* documentElement = m_document->documentElement();
- if (!documentElement)
- return nullptr;
-
- StyleResolver& styleResolver = m_document->ensureStyleResolver();
- RefPtr<RenderStyle> rootStyle = styleResolver.styleForElement(documentElement, 0 /*defaultParent*/, DisallowStyleSharing, MatchOnlyUserAgentRules);
-
- return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame(), rootStyle.get()));
+ return adoptPtr(new MediaQueryEvaluator(mediaType(), m_document->frame()));
}
bool MediaQueryMatcher::evaluate(const MediaQuerySet* media)
@@ -98,18 +89,18 @@ bool MediaQueryMatcher::evaluate(const MediaQuerySet* media)
return evaluator && evaluator->eval(media);
}
-PassRefPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query)
+PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query)
{
if (!m_document)
- return 0;
+ return nullptr;
- RefPtr<MediaQuerySet> media = MediaQuerySet::create(query);
+ RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query);
// Add warning message to inspector whenever dpi/dpcm values are used for "screen" media.
reportMediaQueryWarningIfNeeded(m_document, media.get());
return MediaQueryList::create(this, media, evaluate(media.get()));
}
-void MediaQueryMatcher::addListener(PassRefPtr<MediaQueryListListener> listener, PassRefPtr<MediaQueryList> query)
+void MediaQueryMatcher::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query)
{
if (!m_document)
return;
@@ -119,7 +110,7 @@ void MediaQueryMatcher::addListener(PassRefPtr<MediaQueryListListener> listener,
return;
}
- m_listeners.append(adoptPtr(new Listener(listener, query)));
+ m_listeners.append(adoptPtrWillBeNoop(new Listener(listener, query)));
}
void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQueryList* query)
@@ -140,17 +131,23 @@ void MediaQueryMatcher::styleResolverChanged()
if (!m_document)
return;
- ScriptState* scriptState = m_document->frame() ? mainWorldScriptState(m_document->frame()) : 0;
- if (!scriptState)
- return;
-
++m_evaluationRound;
OwnPtr<MediaQueryEvaluator> evaluator = prepareEvaluator();
if (!evaluator)
return;
for (size_t i = 0; i < m_listeners.size(); ++i)
- m_listeners[i]->evaluate(scriptState, evaluator.get());
+ m_listeners[i]->evaluate(evaluator.get());
+}
+
+void MediaQueryMatcher::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ // We don't support tracing of vectors of OwnPtrs (ie. Vector<OwnPtr<Listener> >).
+ // Since this is a transitional object we are just ifdef'ing it out when oilpan is not enabled.
+#if ENABLE(OILPAN)
+ visitor->trace(m_listeners);
+#endif
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.h b/chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.h
index 42945b485a1..abe862883b5 100644
--- a/chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.h
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQueryMatcher.h
@@ -20,7 +20,7 @@
#ifndef MediaQueryMatcher_h
#define MediaQueryMatcher_h
-#include "bindings/v8/ScriptState.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -38,43 +38,45 @@ class MediaQuerySet;
// whenever it is needed and to call the listeners if the corresponding query has changed.
// The listeners must be called in the very same order in which they have been added.
-class MediaQueryMatcher : public RefCounted<MediaQueryMatcher> {
+class MediaQueryMatcher FINAL : public RefCountedWillBeGarbageCollected<MediaQueryMatcher> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher);
public:
- static PassRefPtr<MediaQueryMatcher> create(Document* document) { return adoptRef(new MediaQueryMatcher(document)); }
- ~MediaQueryMatcher();
+ static PassRefPtrWillBeRawPtr<MediaQueryMatcher> create(Document* document) { return adoptRefWillBeNoop(new MediaQueryMatcher(document)); }
void documentDestroyed();
- void addListener(PassRefPtr<MediaQueryListListener>, PassRefPtr<MediaQueryList>);
+ void addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>, PassRefPtrWillBeRawPtr<MediaQueryList>);
void removeListener(MediaQueryListListener*, MediaQueryList*);
- PassRefPtr<MediaQueryList> matchMedia(const String&);
+ PassRefPtrWillBeRawPtr<MediaQueryList> matchMedia(const String&);
unsigned evaluationRound() const { return m_evaluationRound; }
void styleResolverChanged();
bool evaluate(const MediaQuerySet*);
+ void trace(Visitor*);
+
private:
- class Listener {
+ class Listener FINAL : public NoBaseWillBeGarbageCollected<Listener> {
public:
- Listener(PassRefPtr<MediaQueryListListener>, PassRefPtr<MediaQueryList>);
- ~Listener();
-
- void evaluate(ScriptState*, MediaQueryEvaluator*);
+ Listener(PassRefPtrWillBeRawPtr<MediaQueryListListener>, PassRefPtrWillBeRawPtr<MediaQueryList>);
+ void evaluate(MediaQueryEvaluator*);
MediaQueryListListener* listener() { return m_listener.get(); }
MediaQueryList* query() { return m_query.get(); }
+ void trace(Visitor*);
+
private:
- RefPtr<MediaQueryListListener> m_listener;
- RefPtr<MediaQueryList> m_query;
+ RefPtrWillBeMember<MediaQueryListListener> m_listener;
+ RefPtrWillBeMember<MediaQueryList> m_query;
};
MediaQueryMatcher(Document*);
PassOwnPtr<MediaQueryEvaluator> prepareEvaluator() const;
AtomicString mediaType() const;
- Document* m_document;
- Vector<OwnPtr<Listener> > m_listeners;
+ RawPtrWillBeMember<Document> m_document;
+ WillBeHeapVector<OwnPtrWillBeMember<Listener> > m_listeners;
// This value is incremented at style selector changes.
// It is used to avoid evaluating queries more then once and to make sure
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaQuerySetTest.cpp b/chromium/third_party/WebKit/Source/core/css/MediaQuerySetTest.cpp
new file mode 100644
index 00000000000..834625e3ece
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaQuerySetTest.cpp
@@ -0,0 +1,171 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/MediaQuery.h"
+
+#include "core/css/MediaList.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/text/StringBuilder.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+typedef struct {
+ const char* input;
+ const char* output;
+ bool shouldWorkOnOldParser;
+} TestCase;
+
+static void testMediaQuery(TestCase test, MediaQuerySet& querySet, bool oldParser)
+{
+ StringBuilder output;
+ size_t j = 0;
+ while (j < querySet.queryVector().size()) {
+ String queryText = querySet.queryVector()[j]->cssText();
+ output.append(queryText);
+ ++j;
+ if (j >= querySet.queryVector().size())
+ break;
+ output.append(", ");
+ }
+ if (!oldParser || test.shouldWorkOnOldParser) {
+ if (test.output)
+ ASSERT_STREQ(test.output, output.toString().ascii().data());
+ else
+ ASSERT_STREQ(test.input, output.toString().ascii().data());
+ }
+}
+
+TEST(MediaQuerySetTest, Basic)
+{
+ // The first string represents the input string.
+ // The second string represents the output string, if present.
+ // Otherwise, the output string is identical to the first string.
+ TestCase testCases[] = {
+ {"", 0, true},
+ {" ", "", true},
+ {"screen", 0, true},
+ {"screen and (color)", 0, true},
+ {"all and (min-width:500px)", "(min-width: 500px)", true},
+ {"all and (min-width:/*bla*/500px)", "(min-width: 500px)", true},
+ {"(min-width:500px)", "(min-width: 500px)", true},
+ {"screen and (color), projection and (color)", 0, true},
+ {"not screen and (color)", 0, true},
+ {"only screen and (color)", 0, true},
+ {"screen and (color), projection and (color)", 0, true},
+ {"aural and (device-aspect-ratio: 16/9)", 0, true},
+ {"speech and (min-device-width: 800px)", 0, true},
+ {"example", 0, true},
+ {"screen and (max-weight: 3kg) and (color), (monochrome)", "not all, (monochrome)", true},
+ {"(min-width: -100px)", "not all", true},
+ {"(example, all,), speech", "not all, speech", true},
+ {"&test, screen", "not all, screen", true},
+ {"print and (min-width: 25cm)", 0, true},
+ {"screen and (min-width: 400px) and (max-width: 700px)", "screen and (max-width: 700px) and (min-width: 400px)", true},
+ {"screen and (device-width: 800px)", 0, true},
+ {"screen and (device-height: 60em)", 0, true},
+ {"screen and (device-aspect-ratio: 16/9)", 0, true},
+ {"(device-aspect-ratio: 16.0/9.0)", "not all", true},
+ {"(device-aspect-ratio: 16/ 9)", "(device-aspect-ratio: 16/9)", true},
+ {"(device-aspect-ratio: 16/\r9)", "(device-aspect-ratio: 16/9)", true},
+ {"all and (color)", "(color)", true},
+ {"all and (min-color: 1)", "(min-color: 1)", true},
+ {"all and (min-color: 1.0)", "not all", true},
+ {"all and (min-color: 2)", "(min-color: 2)", true},
+ {"all and (color-index)", "(color-index)", true},
+ {"all and (min-color-index: 1)", "(min-color-index: 1)", true},
+ {"all and (monochrome)", "(monochrome)", true},
+ {"all and (min-monochrome: 1)", "(min-monochrome: 1)", true},
+ {"all and (min-monochrome: 2)", "(min-monochrome: 2)", true},
+ {"print and (monochrome)", 0, true},
+ {"handheld and (grid) and (max-width: 15em)", 0, true},
+ {"handheld and (grid) and (max-device-height: 7em)", 0, true},
+ {"screen and (max-width: 50%)", "not all", true},
+ {"screen and (max-WIDTH: 500px)", "screen and (max-width: 500px)", true},
+ {"screen and (max-width: 24.4em)", 0, true},
+ {"screen and (max-width: 24.4EM)", "screen and (max-width: 24.4em)", true},
+ {"screen and (max-width: blabla)", "not all", true},
+ {"screen and (max-width: 1)", "not all", true},
+ {"screen and (max-width: 0)", 0, true},
+ {"screen and (max-width: 1deg)", "not all", true},
+ {"handheld and (min-width: 20em), \nscreen and (min-width: 20em)", "handheld and (min-width: 20em), screen and (min-width: 20em)", true},
+ {"print and (min-resolution: 300dpi)", 0, true},
+ {"print and (min-resolution: 118dpcm)", 0, true},
+ {"(resolution: 0.83333333333333333333dppx)", "(resolution: 0.833333333333333dppx)", true},
+ {"(resolution: 2.4dppx)", 0, true},
+ {"all and(color)", "not all", true},
+ {"all and (", "not all", true},
+ {"test;,all", "not all, all", true},
+ {"(color:20example)", "not all", false},
+ {"not braille", 0, true},
+ {",screen", "not all, screen", true},
+ {",all", "not all, all", true},
+ {",,all,,", "not all, not all, all, not all, not all", true},
+ {",,all,, ", "not all, not all, all, not all, not all", true},
+ {",screen,,&invalid,,", "not all, screen, not all, not all, not all, not all", true},
+ {",screen,,(invalid,),,", "not all, screen, not all, not all, not all, not all", true},
+ {",(all,),,", "not all, not all, not all, not all", true},
+ {",", "not all, not all", true},
+ {" ", "", true},
+ {"(color", "(color)", true},
+ {"(min-color: 2", "(min-color: 2)", true},
+ {"(orientation: portrait)", 0, true},
+ {"tv and (scan: progressive)", 0, true},
+ {"(pointer: coarse)", 0, true},
+ {"(min-orientation:portrait)", "not all", true},
+ {"all and (orientation:portrait)", "(orientation: portrait)", true},
+ {"all and (orientation:landscape)", "(orientation: landscape)", true},
+ {"NOT braille, tv AND (max-width: 200px) and (min-WIDTH: 100px) and (orientation: landscape), (color)",
+ "not braille, tv and (max-width: 200px) and (min-width: 100px) and (orientation: landscape), (color)", true},
+ {"(m\\61x-width: 300px)", "(max-width: 300px)", true},
+ {"(max-width: 400\\70\\78)", "(max-width: 400px)", false},
+ {"(max-width: 500\\0070\\0078)", "(max-width: 500px)", false},
+ {"(max-width: 600\\000070\\000078)", "(max-width: 600px)", false},
+ {"(max-width: 700px), (max-width: 700px)", "(max-width: 700px), (max-width: 700px)", true},
+ {"(max-width: 800px()), (max-width: 800px)", "not all, (max-width: 800px)", true},
+ {"(max-width: 900px(()), (max-width: 900px)", "not all", true},
+ {"(max-width: 600px(())))), (max-width: 600px)", "not all, (max-width: 600px)", true},
+ {"(max-width: 500px(((((((((())))), (max-width: 500px)", "not all", true},
+ {"(max-width: 800px[]), (max-width: 800px)", "not all, (max-width: 800px)", true},
+ {"(max-width: 900px[[]), (max-width: 900px)", "not all", true},
+ {"(max-width: 600px[[]]]]), (max-width: 600px)", "not all, (max-width: 600px)", true},
+ {"(max-width: 500px[[[[[[[[[[]]]]), (max-width: 500px)", "not all", true},
+ {"(max-width: 800px{}), (max-width: 800px)", "not all, (max-width: 800px)", true},
+ {"(max-width: 900px{{}), (max-width: 900px)", "not all", true},
+ {"(max-width: 600px{{}}}}), (max-width: 600px)", "not all, (max-width: 600px)", true},
+ {"(max-width: 500px{{{{{{{{{{}}}}), (max-width: 500px)", "not all", true},
+ {"[(), (max-width: 400px)", "not all", true},
+ {"[{}, (max-width: 500px)", "not all", true},
+ {"[{]}], (max-width: 900px)", "not all, (max-width: 900px)", true},
+ {"[{[]{}{{{}}}}], (max-width: 900px)", "not all, (max-width: 900px)", true},
+ {"[{[}], (max-width: 900px)", "not all", true},
+ {"[({)}], (max-width: 900px)", "not all", true},
+ {"[]((), (max-width: 900px)", "not all", true},
+ {"((), (max-width: 900px)", "not all", true},
+ {"(foo(), (max-width: 900px)", "not all", true},
+ {"[](()), (max-width: 900px)", "not all, (max-width: 900px)", true},
+ {"all an[isdfs bla())()]icalc(i)(()), (max-width: 400px)", "not all, (max-width: 400px)", true},
+ {"all an[isdfs bla())(]icalc(i)(()), (max-width: 500px)", "not all", true},
+ {"all an[isdfs bla())(]icalc(i)(())), (max-width: 600px)", "not all", true},
+ {"all an[isdfs bla())(]icalc(i)(()))], (max-width: 800px)", "not all, (max-width: 800px)", true},
+ {"(max-width: '40px')", "not all", true},
+ {"('max-width': 40px)", "not all", true},
+ {"'\"'\", (max-width: 900px)", "not all", true},
+ {"'\"\"\"', (max-width: 900px)", "not all, (max-width: 900px)", true},
+ {"\"'\"', (max-width: 900px)", "not all", true},
+ {"\"'''\", (max-width: 900px)", "not all, (max-width: 900px)", true},
+ {0, 0} // Do not remove the terminator line.
+ };
+
+ for (unsigned i = 0; testCases[i].input; ++i) {
+ RefPtrWillBeRawPtr<MediaQuerySet> oldParserQuerySet = MediaQuerySet::create(testCases[i].input);
+ RefPtrWillBeRawPtr<MediaQuerySet> threadSafeQuerySet = MediaQuerySet::createOffMainThread(testCases[i].input);
+ testMediaQuery(testCases[i], *oldParserQuerySet, true);
+ testMediaQuery(testCases[i], *threadSafeQuerySet, false);
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaTypeNames.in b/chromium/third_party/WebKit/Source/core/css/MediaTypeNames.in
new file mode 100644
index 00000000000..556996d8c61
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaTypeNames.in
@@ -0,0 +1,15 @@
+namespace="MediaType"
+export=""
+
+# http://www.w3.org/TR/CSS2/media.html#media-types
+
+all
+braille
+embossed
+handheld
+print
+projection
+screen
+speech
+tty
+tv
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaValues.cpp b/chromium/third_party/WebKit/Source/core/css/MediaValues.cpp
new file mode 100644
index 00000000000..a2d5e1b63c6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaValues.cpp
@@ -0,0 +1,206 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/MediaValues.h"
+
+#include "core/css/CSSHelper.h"
+#include "core/css/MediaValuesCached.h"
+#include "core/css/MediaValuesDynamic.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderObject.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "core/rendering/style/RenderStyle.h"
+#include "platform/PlatformScreen.h"
+
+namespace WebCore {
+
+PassRefPtr<MediaValues> MediaValues::createDynamicIfFrameExists(LocalFrame* frame)
+{
+ if (frame)
+ return MediaValuesDynamic::create(frame);
+ return MediaValuesCached::create();
+}
+
+int MediaValues::calculateViewportWidth(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->view() && frame->document());
+ int viewportWidth = frame->view()->layoutSize(IncludeScrollbars).width();
+ return adjustForAbsoluteZoom(viewportWidth, frame->document()->renderView());
+}
+
+int MediaValues::calculateViewportHeight(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->view() && frame->document());
+ int viewportHeight = frame->view()->layoutSize(IncludeScrollbars).height();
+ return adjustForAbsoluteZoom(viewportHeight, frame->document()->renderView());
+}
+
+int MediaValues::calculateDeviceWidth(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->view() && frame->settings() && frame->host());
+ int deviceWidth = static_cast<int>(screenRect(frame->view()).width());
+ if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk())
+ deviceWidth = lroundf(deviceWidth * frame->host()->deviceScaleFactor());
+ return deviceWidth;
+}
+
+int MediaValues::calculateDeviceHeight(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->view() && frame->settings() && frame->host());
+ int deviceHeight = static_cast<int>(screenRect(frame->view()).height());
+ if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk())
+ deviceHeight = lroundf(deviceHeight * frame->host()->deviceScaleFactor());
+ return deviceHeight;
+}
+
+bool MediaValues::calculateStrictMode(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->document());
+ return !frame->document()->inQuirksMode();
+}
+
+float MediaValues::calculateDevicePixelRatio(LocalFrame* frame) const
+{
+ return frame->devicePixelRatio();
+}
+
+int MediaValues::calculateColorBitsPerComponent(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->page() && frame->page()->mainFrame());
+ if (!frame->page()->mainFrame()->isLocalFrame()
+ || screenIsMonochrome(frame->page()->deprecatedLocalMainFrame()->view()))
+ return 0;
+ return screenDepthPerComponent(frame->view());
+}
+
+int MediaValues::calculateMonochromeBitsPerComponent(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->page() && frame->page()->mainFrame());
+ if (!frame->page()->mainFrame()->isLocalFrame()
+ || !screenIsMonochrome(frame->page()->deprecatedLocalMainFrame()->view()))
+ return 0;
+ return screenDepthPerComponent(frame->view());
+}
+
+int MediaValues::calculateDefaultFontSize(LocalFrame* frame) const
+{
+ return frame->host()->settings().defaultFontSize();
+}
+
+bool MediaValues::calculateScanMediaType(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->view());
+ // Scan only applies to 'tv' media.
+ return equalIgnoringCase(frame->view()->mediaType(), "tv");
+}
+
+bool MediaValues::calculateScreenMediaType(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->view());
+ return equalIgnoringCase(frame->view()->mediaType(), "screen");
+}
+
+bool MediaValues::calculatePrintMediaType(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->view());
+ return equalIgnoringCase(frame->view()->mediaType(), "print");
+}
+
+bool MediaValues::calculateThreeDEnabled(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->contentRenderer() && frame->contentRenderer()->compositor());
+ bool threeDEnabled = false;
+ if (RenderView* view = frame->contentRenderer())
+ threeDEnabled = view->compositor()->hasAcceleratedCompositing();
+ return threeDEnabled;
+}
+
+MediaValues::PointerDeviceType MediaValues::calculateLeastCapablePrimaryPointerDeviceType(LocalFrame* frame) const
+{
+ ASSERT(frame && frame->settings());
+ if (frame->settings()->deviceSupportsTouch())
+ return MediaValues::TouchPointer;
+
+ // FIXME: We should also try to determine if we know we have a mouse.
+ // When we do this, we'll also need to differentiate between known not to
+ // have mouse or touch screen (NoPointer) and unknown (UnknownPointer).
+ // We could also take into account other preferences like accessibility
+ // settings to decide which of the available pointers should be considered
+ // "primary".
+
+ return MediaValues::UnknownPointer;
+}
+
+bool MediaValues::computeLengthImpl(double value, CSSPrimitiveValue::UnitType type, unsigned defaultFontSize, unsigned viewportWidth, unsigned viewportHeight, double& result)
+{
+ // The logic in this function is duplicated from CSSPrimitiveValue::computeLengthDouble
+ // because MediaValues::computeLength needs nearly identical logic, but we haven't found a way to make
+ // CSSPrimitiveValue::computeLengthDouble more generic (to solve both cases) without hurting performance.
+
+ // FIXME - Unite the logic here with CSSPrimitiveValue in a performant way.
+ double factor = 0;
+ switch (type) {
+ case CSSPrimitiveValue::CSS_EMS:
+ case CSSPrimitiveValue::CSS_REMS:
+ factor = defaultFontSize;
+ break;
+ case CSSPrimitiveValue::CSS_PX:
+ factor = 1;
+ break;
+ case CSSPrimitiveValue::CSS_EXS:
+ // FIXME: We have a bug right now where the zoom will be applied twice to EX units.
+ // FIXME: We don't seem to be able to cache fontMetrics related values.
+ // Trying to access them is triggering some sort of microtask. Serving the spec's default instead.
+ factor = defaultFontSize / 2.0;
+ break;
+ case CSSPrimitiveValue::CSS_CHS:
+ // FIXME: We don't seem to be able to cache fontMetrics related values.
+ // Trying to access them is triggering some sort of microtask. Serving the (future) spec default instead.
+ factor = defaultFontSize / 2.0;
+ break;
+ case CSSPrimitiveValue::CSS_VW:
+ factor = viewportWidth / 100.0;
+ break;
+ case CSSPrimitiveValue::CSS_VH:
+ factor = viewportHeight / 100.0;
+ break;
+ case CSSPrimitiveValue::CSS_VMIN:
+ factor = std::min(viewportWidth, viewportHeight) / 100.0;
+ break;
+ case CSSPrimitiveValue::CSS_VMAX:
+ factor = std::max(viewportWidth, viewportHeight) / 100.0;
+ break;
+ case CSSPrimitiveValue::CSS_CM:
+ factor = cssPixelsPerCentimeter;
+ break;
+ case CSSPrimitiveValue::CSS_MM:
+ factor = cssPixelsPerMillimeter;
+ break;
+ case CSSPrimitiveValue::CSS_IN:
+ factor = cssPixelsPerInch;
+ break;
+ case CSSPrimitiveValue::CSS_PT:
+ factor = cssPixelsPerPoint;
+ break;
+ case CSSPrimitiveValue::CSS_PC:
+ factor = cssPixelsPerPica;
+ break;
+ default:
+ return false;
+ }
+
+ ASSERT(factor > 0);
+ result = value * factor;
+ return true;
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaValues.h b/chromium/third_party/WebKit/Source/core/css/MediaValues.h
new file mode 100644
index 00000000000..eee54657b37
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaValues.h
@@ -0,0 +1,88 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaValues_h
+#define MediaValues_h
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class Document;
+class CSSPrimitiveValue;
+class LocalFrame;
+
+class MediaValues : public RefCounted<MediaValues> {
+public:
+
+ enum MediaValuesMode {
+ CachingMode,
+ DynamicMode
+ };
+
+ enum PointerDeviceType {
+ TouchPointer,
+ MousePointer,
+ NoPointer,
+ UnknownPointer
+ };
+
+ virtual ~MediaValues() { }
+
+ static PassRefPtr<MediaValues> createDynamicIfFrameExists(LocalFrame*);
+ virtual PassRefPtr<MediaValues> copy() const = 0;
+ virtual bool isSafeToSendToAnotherThread() const = 0;
+
+ static bool computeLengthImpl(double value, CSSPrimitiveValue::UnitType, unsigned defaultFontSize, unsigned viewportWidth, unsigned viewportHeight, double& result);
+ template<typename T>
+ static bool computeLength(double value, CSSPrimitiveValue::UnitType type, unsigned defaultFontSize, unsigned viewportWidth, unsigned viewportHeight, T& result)
+ {
+ double tempResult;
+ if (!computeLengthImpl(value, type, defaultFontSize, viewportWidth, viewportHeight, tempResult))
+ return false;
+ result = roundForImpreciseConversion<T>(tempResult);
+ return true;
+ }
+ virtual bool computeLength(double value, CSSPrimitiveValue::UnitType, int& result) const = 0;
+ virtual bool computeLength(double value, CSSPrimitiveValue::UnitType, double& result) const = 0;
+
+ virtual int viewportWidth() const = 0;
+ virtual int viewportHeight() const = 0;
+ virtual int deviceWidth() const = 0;
+ virtual int deviceHeight() const = 0;
+ virtual float devicePixelRatio() const = 0;
+ virtual int colorBitsPerComponent() const = 0;
+ virtual int monochromeBitsPerComponent() const = 0;
+ virtual PointerDeviceType pointer() const = 0;
+ virtual bool threeDEnabled() const = 0;
+ virtual bool scanMediaType() const = 0;
+ virtual bool screenMediaType() const = 0;
+ virtual bool printMediaType() const = 0;
+ virtual bool strictMode() const = 0;
+ virtual Document* document() const = 0;
+ virtual bool hasValues() const = 0;
+
+protected:
+ int calculateViewportWidth(LocalFrame*) const;
+ int calculateViewportHeight(LocalFrame*) const;
+ int calculateDeviceWidth(LocalFrame*) const;
+ int calculateDeviceHeight(LocalFrame*) const;
+ bool calculateStrictMode(LocalFrame*) const;
+ float calculateDevicePixelRatio(LocalFrame*) const;
+ int calculateColorBitsPerComponent(LocalFrame*) const;
+ int calculateMonochromeBitsPerComponent(LocalFrame*) const;
+ int calculateDefaultFontSize(LocalFrame*) const;
+ bool calculateScanMediaType(LocalFrame*) const;
+ bool calculateScreenMediaType(LocalFrame*) const;
+ bool calculatePrintMediaType(LocalFrame*) const;
+ bool calculateThreeDEnabled(LocalFrame*) const;
+ MediaValues::PointerDeviceType calculateLeastCapablePrimaryPointerDeviceType(LocalFrame*) const;
+
+};
+
+} // namespace
+
+#endif // MediaValues_h
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaValuesCached.cpp b/chromium/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
new file mode 100644
index 00000000000..570a3a51709
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaValuesCached.cpp
@@ -0,0 +1,169 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/MediaValuesCached.h"
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/imports/HTMLImportsController.h"
+#include "core/rendering/RenderObject.h"
+
+namespace WebCore {
+
+PassRefPtr<MediaValues> MediaValuesCached::create()
+{
+ return adoptRef(new MediaValuesCached());
+}
+
+PassRefPtr<MediaValues> MediaValuesCached::create(MediaValuesCachedData& data)
+{
+ return adoptRef(new MediaValuesCached(data));
+}
+
+PassRefPtr<MediaValues> MediaValuesCached::create(Document& document)
+{
+ Document* executingDocument = document.importsController() ? document.importsController()->master() : &document;
+ ASSERT(executingDocument);
+ return MediaValuesCached::create(executingDocument->frame());
+}
+
+PassRefPtr<MediaValues> MediaValuesCached::create(LocalFrame* frame)
+{
+ // FIXME - Added an assert here so we can better understand when a frame is present without its view().
+ ASSERT(!frame || frame->view());
+ // FIXME - Because of crbug.com/371084, document()->renderView() may be null here.
+ if (!frame || !frame->view() || !frame->document() || !frame->document()->renderView())
+ return adoptRef(new MediaValuesCached());
+ return adoptRef(new MediaValuesCached(frame));
+}
+
+MediaValuesCached::MediaValuesCached()
+{
+}
+
+MediaValuesCached::MediaValuesCached(LocalFrame* frame)
+{
+ ASSERT(isMainThread());
+ ASSERT(frame);
+ // In case that frame is missing (e.g. for images that their document does not have a frame)
+ // We simply leave the MediaValues object with the default MediaValuesCachedData values.
+ m_data.viewportWidth = calculateViewportWidth(frame);
+ m_data.viewportHeight = calculateViewportHeight(frame);
+ m_data.deviceWidth = calculateDeviceWidth(frame);
+ m_data.deviceHeight = calculateDeviceHeight(frame);
+ m_data.devicePixelRatio = calculateDevicePixelRatio(frame);
+ m_data.colorBitsPerComponent = calculateColorBitsPerComponent(frame);
+ m_data.monochromeBitsPerComponent = calculateMonochromeBitsPerComponent(frame);
+ m_data.pointer = calculateLeastCapablePrimaryPointerDeviceType(frame);
+ m_data.defaultFontSize = calculateDefaultFontSize(frame);
+ m_data.threeDEnabled = calculateThreeDEnabled(frame);
+ m_data.scanMediaType = calculateScanMediaType(frame);
+ m_data.screenMediaType = calculateScreenMediaType(frame);
+ m_data.printMediaType = calculatePrintMediaType(frame);
+ m_data.strictMode = calculateStrictMode(frame);
+}
+
+MediaValuesCached::MediaValuesCached(const MediaValuesCachedData& data)
+ : m_data(data)
+{
+}
+
+PassRefPtr<MediaValues> MediaValuesCached::copy() const
+{
+ return adoptRef(new MediaValuesCached(m_data));
+}
+
+bool MediaValuesCached::computeLength(double value, CSSPrimitiveValue::UnitType type, int& result) const
+{
+ return MediaValues::computeLength(value, type, m_data.defaultFontSize, m_data.viewportWidth, m_data.viewportHeight, result);
+}
+
+bool MediaValuesCached::computeLength(double value, CSSPrimitiveValue::UnitType type, double& result) const
+{
+ return MediaValues::computeLength(value, type, m_data.defaultFontSize, m_data.viewportWidth, m_data.viewportHeight, result);
+}
+
+bool MediaValuesCached::isSafeToSendToAnotherThread() const
+{
+ return hasOneRef();
+}
+
+int MediaValuesCached::viewportWidth() const
+{
+ return m_data.viewportWidth;
+}
+
+int MediaValuesCached::viewportHeight() const
+{
+ return m_data.viewportHeight;
+}
+
+int MediaValuesCached::deviceWidth() const
+{
+ return m_data.deviceWidth;
+}
+
+int MediaValuesCached::deviceHeight() const
+{
+ return m_data.deviceHeight;
+}
+
+float MediaValuesCached::devicePixelRatio() const
+{
+ return m_data.devicePixelRatio;
+}
+
+int MediaValuesCached::colorBitsPerComponent() const
+{
+ return m_data.colorBitsPerComponent;
+}
+
+int MediaValuesCached::monochromeBitsPerComponent() const
+{
+ return m_data.monochromeBitsPerComponent;
+}
+
+MediaValues::PointerDeviceType MediaValuesCached::pointer() const
+{
+ return m_data.pointer;
+}
+
+bool MediaValuesCached::threeDEnabled() const
+{
+ return m_data.threeDEnabled;
+}
+
+bool MediaValuesCached::scanMediaType() const
+{
+ return m_data.scanMediaType;
+}
+
+bool MediaValuesCached::screenMediaType() const
+{
+ return m_data.screenMediaType;
+}
+
+bool MediaValuesCached::printMediaType() const
+{
+ return m_data.printMediaType;
+}
+
+bool MediaValuesCached::strictMode() const
+{
+ return m_data.strictMode;
+}
+
+Document* MediaValuesCached::document() const
+{
+ return 0;
+}
+
+bool MediaValuesCached::hasValues() const
+{
+ return true;
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaValuesCached.h b/chromium/third_party/WebKit/Source/core/css/MediaValuesCached.h
new file mode 100644
index 00000000000..c3ff031c884
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaValuesCached.h
@@ -0,0 +1,85 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaValuesCached_h
+#define MediaValuesCached_h
+
+#include "core/css/MediaValues.h"
+
+namespace WebCore {
+
+class MediaValuesCached FINAL : public MediaValues {
+public:
+ struct MediaValuesCachedData {
+ // Members variables must be thread safe, since they're copied to the parser thread
+ int viewportWidth;
+ int viewportHeight;
+ int deviceWidth;
+ int deviceHeight;
+ float devicePixelRatio;
+ int colorBitsPerComponent;
+ int monochromeBitsPerComponent;
+ PointerDeviceType pointer;
+ int defaultFontSize;
+ bool threeDEnabled;
+ bool scanMediaType;
+ bool screenMediaType;
+ bool printMediaType;
+ bool strictMode;
+
+ MediaValuesCachedData()
+ : viewportWidth(0)
+ , viewportHeight(0)
+ , deviceWidth(0)
+ , deviceHeight(0)
+ , devicePixelRatio(1.0)
+ , colorBitsPerComponent(24)
+ , monochromeBitsPerComponent(0)
+ , pointer(UnknownPointer)
+ , defaultFontSize(16)
+ , threeDEnabled(false)
+ , scanMediaType(false)
+ , screenMediaType(true)
+ , printMediaType(false)
+ , strictMode(true)
+ {
+ }
+ };
+
+ static PassRefPtr<MediaValues> create();
+ static PassRefPtr<MediaValues> create(Document&);
+ static PassRefPtr<MediaValues> create(LocalFrame*);
+ static PassRefPtr<MediaValues> create(MediaValuesCachedData&);
+ virtual PassRefPtr<MediaValues> copy() const OVERRIDE;
+ virtual bool isSafeToSendToAnotherThread() const OVERRIDE;
+ virtual bool computeLength(double value, CSSPrimitiveValue::UnitType, int& result) const OVERRIDE;
+ virtual bool computeLength(double value, CSSPrimitiveValue::UnitType, double& result) const OVERRIDE;
+
+ virtual int viewportWidth() const OVERRIDE;
+ virtual int viewportHeight() const OVERRIDE;
+ virtual int deviceWidth() const OVERRIDE;
+ virtual int deviceHeight() const OVERRIDE;
+ virtual float devicePixelRatio() const OVERRIDE;
+ virtual int colorBitsPerComponent() const OVERRIDE;
+ virtual int monochromeBitsPerComponent() const OVERRIDE;
+ virtual PointerDeviceType pointer() const OVERRIDE;
+ virtual bool threeDEnabled() const OVERRIDE;
+ virtual bool scanMediaType() const OVERRIDE;
+ virtual bool screenMediaType() const OVERRIDE;
+ virtual bool printMediaType() const OVERRIDE;
+ virtual bool strictMode() const OVERRIDE;
+ virtual Document* document() const OVERRIDE;
+ virtual bool hasValues() const OVERRIDE;
+
+protected:
+ MediaValuesCached();
+ MediaValuesCached(LocalFrame*);
+ MediaValuesCached(const MediaValuesCachedData&);
+
+ MediaValuesCachedData m_data;
+};
+
+} // namespace
+
+#endif // MediaValuesCached_h
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp b/chromium/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
new file mode 100644
index 00000000000..2ac823feb98
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaValuesDynamic.cpp
@@ -0,0 +1,132 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/MediaValuesDynamic.h"
+
+#include "core/css/CSSHelper.h"
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSToLengthConversionData.h"
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+
+namespace WebCore {
+
+PassRefPtr<MediaValues> MediaValuesDynamic::create(LocalFrame* frame)
+{
+ return adoptRef(new MediaValuesDynamic(frame));
+}
+
+MediaValuesDynamic::MediaValuesDynamic(LocalFrame* frame)
+ : m_frame(frame)
+{
+ ASSERT(m_frame);
+}
+
+PassRefPtr<MediaValues> MediaValuesDynamic::copy() const
+{
+ return adoptRef(new MediaValuesDynamic(m_frame));
+}
+
+bool MediaValuesDynamic::computeLength(double value, CSSPrimitiveValue::UnitType type, int& result) const
+{
+ return MediaValues::computeLength(value,
+ type,
+ calculateDefaultFontSize(m_frame),
+ calculateViewportWidth(m_frame),
+ calculateViewportHeight(m_frame),
+ result);
+}
+
+bool MediaValuesDynamic::computeLength(double value, CSSPrimitiveValue::UnitType type, double& result) const
+{
+ return MediaValues::computeLength(value,
+ type,
+ calculateDefaultFontSize(m_frame),
+ calculateViewportWidth(m_frame),
+ calculateViewportHeight(m_frame),
+ result);
+}
+
+bool MediaValuesDynamic::isSafeToSendToAnotherThread() const
+{
+ return false;
+}
+
+int MediaValuesDynamic::viewportWidth() const
+{
+ return calculateViewportWidth(m_frame);
+}
+
+int MediaValuesDynamic::viewportHeight() const
+{
+ return calculateViewportHeight(m_frame);
+}
+
+int MediaValuesDynamic::deviceWidth() const
+{
+ return calculateDeviceWidth(m_frame);
+}
+
+int MediaValuesDynamic::deviceHeight() const
+{
+ return calculateDeviceHeight(m_frame);
+}
+
+float MediaValuesDynamic::devicePixelRatio() const
+{
+ return calculateDevicePixelRatio(m_frame);
+}
+
+int MediaValuesDynamic::colorBitsPerComponent() const
+{
+ return calculateColorBitsPerComponent(m_frame);
+}
+
+int MediaValuesDynamic::monochromeBitsPerComponent() const
+{
+ return calculateMonochromeBitsPerComponent(m_frame);
+}
+
+MediaValues::PointerDeviceType MediaValuesDynamic::pointer() const
+{
+ return calculateLeastCapablePrimaryPointerDeviceType(m_frame);
+}
+
+bool MediaValuesDynamic::threeDEnabled() const
+{
+ return calculateThreeDEnabled(m_frame);
+}
+
+bool MediaValuesDynamic::scanMediaType() const
+{
+ return calculateScanMediaType(m_frame);
+}
+
+bool MediaValuesDynamic::screenMediaType() const
+{
+ return calculateScreenMediaType(m_frame);
+}
+
+bool MediaValuesDynamic::printMediaType() const
+{
+ return calculatePrintMediaType(m_frame);
+}
+
+bool MediaValuesDynamic::strictMode() const
+{
+ return calculateStrictMode(m_frame);
+}
+
+Document* MediaValuesDynamic::document() const
+{
+ return m_frame->document();
+}
+
+bool MediaValuesDynamic::hasValues() const
+{
+ return m_frame;
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaValuesDynamic.h b/chromium/third_party/WebKit/Source/core/css/MediaValuesDynamic.h
new file mode 100644
index 00000000000..26fac877451
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaValuesDynamic.h
@@ -0,0 +1,49 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaValuesDynamic_h
+#define MediaValuesDynamic_h
+
+#include "core/css/MediaValues.h"
+
+namespace WebCore {
+
+class Document;
+
+class MediaValuesDynamic FINAL : public MediaValues {
+public:
+ static PassRefPtr<MediaValues> create(LocalFrame*);
+ virtual PassRefPtr<MediaValues> copy() const OVERRIDE;
+ virtual bool isSafeToSendToAnotherThread() const OVERRIDE;
+ virtual bool computeLength(double value, CSSPrimitiveValue::UnitType, int& result) const OVERRIDE;
+ virtual bool computeLength(double value, CSSPrimitiveValue::UnitType, double& result) const OVERRIDE;
+
+ virtual int viewportWidth() const OVERRIDE;
+ virtual int viewportHeight() const OVERRIDE;
+ virtual int deviceWidth() const OVERRIDE;
+ virtual int deviceHeight() const OVERRIDE;
+ virtual float devicePixelRatio() const OVERRIDE;
+ virtual int colorBitsPerComponent() const OVERRIDE;
+ virtual int monochromeBitsPerComponent() const OVERRIDE;
+ virtual PointerDeviceType pointer() const OVERRIDE;
+ virtual bool threeDEnabled() const OVERRIDE;
+ virtual bool scanMediaType() const OVERRIDE;
+ virtual bool screenMediaType() const OVERRIDE;
+ virtual bool printMediaType() const OVERRIDE;
+ virtual bool strictMode() const OVERRIDE;
+ virtual Document* document() const OVERRIDE;
+ virtual bool hasValues() const OVERRIDE;
+
+protected:
+ MediaValuesDynamic(LocalFrame*);
+
+ // This raw ptr is safe, as MediaValues would not outlive MediaQueryEvaluator, and
+ // MediaQueryEvaluator is reset on |Document::detach|.
+ // FIXME: Oilpan: This raw ptr should be changed to a Member when LocalFrame is migrated to the heap.
+ LocalFrame* m_frame;
+};
+
+} // namespace
+
+#endif // MediaValuesDynamic_h
diff --git a/chromium/third_party/WebKit/Source/core/css/MediaValuesTest.cpp b/chromium/third_party/WebKit/Source/core/css/MediaValuesTest.cpp
new file mode 100644
index 00000000000..f4b9c8b650a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/MediaValuesTest.cpp
@@ -0,0 +1,61 @@
+// Use of this source code is governed by a BSD-style license that can be
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/MediaValues.h"
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "wtf/text/StringBuilder.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+struct TestCase {
+ double value;
+ CSSPrimitiveValue::UnitType type;
+ unsigned fontSize;
+ unsigned viewportWidth;
+ unsigned viewportHeight;
+ bool success;
+ int output;
+};
+
+TEST(MediaValuesTest, Basic)
+{
+ TestCase testCases[] = {
+ { 40.0, CSSPrimitiveValue::CSS_PX, 16, 300, 300, true, 40 },
+ { 40.0, CSSPrimitiveValue::CSS_EMS, 16, 300, 300, true, 640 },
+ { 40.0, CSSPrimitiveValue::CSS_REMS, 16, 300, 300, true, 640 },
+ { 40.0, CSSPrimitiveValue::CSS_EXS, 16, 300, 300, true, 320 },
+ { 40.0, CSSPrimitiveValue::CSS_CHS, 16, 300, 300, true, 320 },
+ { 43.0, CSSPrimitiveValue::CSS_VW, 16, 848, 976, true, 364 },
+ { 43.0, CSSPrimitiveValue::CSS_VH, 16, 848, 976, true, 419 },
+ { 43.0, CSSPrimitiveValue::CSS_VMIN, 16, 848, 976, true, 364 },
+ { 43.0, CSSPrimitiveValue::CSS_VMAX, 16, 848, 976, true, 419 },
+ { 1.3, CSSPrimitiveValue::CSS_CM, 16, 300, 300, true, 49 },
+ { 1.3, CSSPrimitiveValue::CSS_MM, 16, 300, 300, true, 4 },
+ { 1.3, CSSPrimitiveValue::CSS_IN, 16, 300, 300, true, 124 },
+ { 13, CSSPrimitiveValue::CSS_PT, 16, 300, 300, true, 17 },
+ { 1.3, CSSPrimitiveValue::CSS_PC, 16, 300, 300, true, 20 },
+ { 1.3, CSSPrimitiveValue::CSS_UNKNOWN, 16, 300, 300, false, 20 },
+ { 0.0, CSSPrimitiveValue::CSS_UNKNOWN, 0, 0, 0, false, 0.0 } // Do not remove the terminating line.
+ };
+
+
+ for (unsigned i = 0; testCases[i].viewportWidth; ++i) {
+ int output = 0;
+ bool success = MediaValues::computeLength(testCases[i].value,
+ testCases[i].type,
+ testCases[i].fontSize,
+ testCases[i].viewportWidth,
+ testCases[i].viewportHeight,
+ output);
+ ASSERT_EQ(testCases[i].success, success);
+ if (success)
+ ASSERT_EQ(testCases[i].output, output);
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/PageRuleCollector.cpp b/chromium/third_party/WebKit/Source/core/css/PageRuleCollector.cpp
index e4494526d30..3e8c76f8919 100644
--- a/chromium/third_party/WebKit/Source/core/css/PageRuleCollector.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/PageRuleCollector.cpp
@@ -73,7 +73,7 @@ void PageRuleCollector::matchPageRules(RuleSet* rules)
return;
rules->compactRulesIfNeeded();
- Vector<StyleRulePage*> matchedPageRules;
+ WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> > matchedPageRules;
matchPageRulesForList(matchedPageRules, rules->pageRules(), m_isLeftPage, m_isFirstPage, m_pageName);
if (matchedPageRules.isEmpty())
return;
@@ -81,13 +81,13 @@ void PageRuleCollector::matchPageRules(RuleSet* rules)
std::stable_sort(matchedPageRules.begin(), matchedPageRules.end(), comparePageRules);
for (unsigned i = 0; i < matchedPageRules.size(); i++)
- m_result.addMatchedProperties(matchedPageRules[i]->properties());
+ m_result.addMatchedProperties(&matchedPageRules[i]->properties());
}
static bool checkPageSelectorComponents(const CSSSelector* selector, bool isLeftPage, bool isFirstPage, const String& pageName)
{
for (const CSSSelector* component = selector; component; component = component->tagHistory()) {
- if (component->m_match == CSSSelector::Tag) {
+ if (component->match() == CSSSelector::Tag) {
const AtomicString& localName = component->tagQName().localName();
if (localName != starAtom && localName != pageName)
return false;
@@ -104,7 +104,7 @@ static bool checkPageSelectorComponents(const CSSSelector* selector, bool isLeft
return true;
}
-void PageRuleCollector::matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName)
+void PageRuleCollector::matchPageRulesForList(WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& matchedRules, const WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& rules, bool isLeftPage, bool isFirstPage, const String& pageName)
{
for (unsigned i = 0; i < rules.size(); ++i) {
StyleRulePage* rule = rules[i];
@@ -113,8 +113,8 @@ void PageRuleCollector::matchPageRulesForList(Vector<StyleRulePage*>& matchedRul
continue;
// If the rule has no properties to apply, then ignore it.
- const StylePropertySet* properties = rule->properties();
- if (!properties || properties->isEmpty())
+ const StylePropertySet& properties = rule->properties();
+ if (properties.isEmpty())
continue;
// Add this rule to our list of matched rules.
diff --git a/chromium/third_party/WebKit/Source/core/css/PageRuleCollector.h b/chromium/third_party/WebKit/Source/core/css/PageRuleCollector.h
index 83251612aaf..af632809358 100644
--- a/chromium/third_party/WebKit/Source/core/css/PageRuleCollector.h
+++ b/chromium/third_party/WebKit/Source/core/css/PageRuleCollector.h
@@ -31,6 +31,7 @@ class ElementResolveContext;
class StyleRulePage;
class PageRuleCollector {
+ STACK_ALLOCATED();
public:
PageRuleCollector(const RenderStyle* rootElementStyle, int pageIndex);
@@ -43,7 +44,7 @@ private:
bool isFirstPage(int pageIndex) const;
String pageName(int pageIndex) const;
- void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName);
+ void matchPageRulesForList(WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& matchedRules, const WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& rules, bool isLeftPage, bool isFirstPage, const String& pageName);
const bool m_isLeftPage;
const bool m_isFirstPage;
diff --git a/chromium/third_party/WebKit/Source/core/css/Pair.cpp b/chromium/third_party/WebKit/Source/core/css/Pair.cpp
new file mode 100644
index 00000000000..5362b6b5274
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/Pair.cpp
@@ -0,0 +1,16 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/Pair.h"
+
+namespace WebCore {
+
+void Pair::trace(Visitor* visitor)
+{
+ visitor->trace(m_first);
+ visitor->trace(m_second);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/Pair.h b/chromium/third_party/WebKit/Source/core/css/Pair.h
index fc2edaa828b..5cafb532092 100644
--- a/chromium/third_party/WebKit/Source/core/css/Pair.h
+++ b/chromium/third_party/WebKit/Source/core/css/Pair.h
@@ -32,25 +32,22 @@ namespace WebCore {
// and border-spacing (all of which are space-separated sets of two values). At the moment we are only using it for
// border-radius and background-size, but (FIXME) border-spacing and background-position could be converted over to use
// it (eliminating some extra -webkit- internal properties).
-class Pair FINAL : public RefCounted<Pair> {
+class Pair FINAL : public RefCountedWillBeGarbageCollected<Pair> {
public:
enum IdenticalValuesPolicy { DropIdenticalValues, KeepIdenticalValues };
- static PassRefPtr<Pair> create()
+ static PassRefPtrWillBeRawPtr<Pair> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> first, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> second,
+ IdenticalValuesPolicy identicalValuesPolicy)
{
- return adoptRef(new Pair);
- }
- static PassRefPtr<Pair> create(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second, IdenticalValuesPolicy identicalValuesPolicy)
- {
- return adoptRef(new Pair(first, second, identicalValuesPolicy));
+ return adoptRefWillBeNoop(new Pair(first, second, identicalValuesPolicy));
}
CSSPrimitiveValue* first() const { return m_first.get(); }
CSSPrimitiveValue* second() const { return m_second.get(); }
IdenticalValuesPolicy identicalValuesPolicy() const { return m_identicalValuesPolicy; }
- void setFirst(PassRefPtr<CSSPrimitiveValue> first) { m_first = first; }
- void setSecond(PassRefPtr<CSSPrimitiveValue> second) { m_second = second; }
+ void setFirst(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> first) { m_first = first; }
+ void setSecond(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> second) { m_second = second; }
void setIdenticalValuesPolicy(IdenticalValuesPolicy identicalValuesPolicy) { m_identicalValuesPolicy = identicalValuesPolicy; }
String cssText() const
@@ -65,23 +62,15 @@ public:
&& m_identicalValuesPolicy == other.m_identicalValuesPolicy;
}
- String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
- {
- return generateCSSString(
- first()->customSerializeResolvingVariables(variables),
- second()->customSerializeResolvingVariables(variables),
- m_identicalValuesPolicy);
- }
-
- bool hasVariableReference() const { return first()->hasVariableReference() || second()->hasVariableReference(); }
+ void trace(Visitor*);
private:
Pair()
- : m_first(0)
- , m_second(0)
+ : m_first(nullptr)
+ , m_second(nullptr)
, m_identicalValuesPolicy(DropIdenticalValues) { }
- Pair(PassRefPtr<CSSPrimitiveValue> first, PassRefPtr<CSSPrimitiveValue> second, IdenticalValuesPolicy identicalValuesPolicy)
+ Pair(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> first, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> second, IdenticalValuesPolicy identicalValuesPolicy)
: m_first(first)
, m_second(second)
, m_identicalValuesPolicy(identicalValuesPolicy) { }
@@ -93,8 +82,8 @@ private:
return first + ' ' + second;
}
- RefPtr<CSSPrimitiveValue> m_first;
- RefPtr<CSSPrimitiveValue> m_second;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_first;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_second;
IdenticalValuesPolicy m_identicalValuesPolicy;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp b/chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp
index e30610ab3a2..b6d0f6eed1f 100644
--- a/chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp
@@ -22,18 +22,16 @@
#include "config.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/css/CSSParser.h"
+#include "core/HTMLNames.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Element.h"
#include "core/dom/MutationObserverInterestGroup.h"
#include "core/dom/MutationRecord.h"
#include "core/inspector/InspectorInstrumentation.h"
-
-using namespace std;
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -41,8 +39,9 @@ namespace {
class StyleAttributeMutationScope {
WTF_MAKE_NONCOPYABLE(StyleAttributeMutationScope);
+ STACK_ALLOCATED();
public:
- StyleAttributeMutationScope(PropertySetCSSStyleDeclaration* decl)
+ StyleAttributeMutationScope(AbstractPropertySetCSSStyleDeclaration* decl)
{
InspectorInstrumentation::willMutateStyle(decl);
++s_scopeCount;
@@ -86,7 +85,7 @@ public:
s_shouldDeliver = false;
// We have to clear internal state before calling Inspector's code.
- PropertySetCSSStyleDeclaration* localCopyStyleDecl = s_currentDecl;
+ AbstractPropertySetCSSStyleDeclaration* localCopyStyleDecl = s_currentDecl;
s_currentDecl = 0;
InspectorInstrumentation::didMutateStyle(localCopyStyleDecl, localCopyStyleDecl->parentElement());
@@ -110,21 +109,22 @@ public:
private:
static unsigned s_scopeCount;
- static PropertySetCSSStyleDeclaration* s_currentDecl;
+ static AbstractPropertySetCSSStyleDeclaration* s_currentDecl;
static bool s_shouldNotifyInspector;
static bool s_shouldDeliver;
- OwnPtr<MutationObserverInterestGroup> m_mutationRecipients;
- RefPtr<MutationRecord> m_mutation;
+ OwnPtrWillBeMember<MutationObserverInterestGroup> m_mutationRecipients;
+ RefPtrWillBeMember<MutationRecord> m_mutation;
};
unsigned StyleAttributeMutationScope::s_scopeCount = 0;
-PropertySetCSSStyleDeclaration* StyleAttributeMutationScope::s_currentDecl = 0;
+AbstractPropertySetCSSStyleDeclaration* StyleAttributeMutationScope::s_currentDecl = 0;
bool StyleAttributeMutationScope::s_shouldNotifyInspector = false;
bool StyleAttributeMutationScope::s_shouldDeliver = false;
} // namespace
+#if !ENABLE(OILPAN)
void PropertySetCSSStyleDeclaration::ref()
{
m_propertySet->ref();
@@ -134,103 +134,101 @@ void PropertySetCSSStyleDeclaration::deref()
{
m_propertySet->deref();
}
+#endif
-unsigned PropertySetCSSStyleDeclaration::length() const
+void PropertySetCSSStyleDeclaration::trace(Visitor* visitor)
{
- return m_propertySet->propertyCount();
+ visitor->trace(m_propertySet);
+ AbstractPropertySetCSSStyleDeclaration::trace(visitor);
}
-String PropertySetCSSStyleDeclaration::item(unsigned i) const
+unsigned AbstractPropertySetCSSStyleDeclaration::length() const
{
- if (i >= m_propertySet->propertyCount())
+ return propertySet().propertyCount();
+}
+
+String AbstractPropertySetCSSStyleDeclaration::item(unsigned i) const
+{
+ if (i >= propertySet().propertyCount())
return "";
- return m_propertySet->propertyAt(i).cssName();
+ return propertySet().propertyAt(i).cssName();
}
-String PropertySetCSSStyleDeclaration::cssText() const
+String AbstractPropertySetCSSStyleDeclaration::cssText() const
{
- return m_propertySet->asText();
+ return propertySet().asText();
}
-void PropertySetCSSStyleDeclaration::setCSSText(const String& text, ExceptionState& exceptionState)
+void AbstractPropertySetCSSStyleDeclaration::setCSSText(const String& text, ExceptionState& exceptionState)
{
StyleAttributeMutationScope mutationScope(this);
willMutate();
// FIXME: Detect syntax errors and set exceptionState.
- m_propertySet->parseDeclaration(text, contextStyleSheet());
+ propertySet().parseDeclaration(text, contextStyleSheet());
didMutate(PropertyChanged);
mutationScope.enqueueMutationRecord();
}
-PassRefPtr<CSSValue> PropertySetCSSStyleDeclaration::getPropertyCSSValue(const String& propertyName)
+PassRefPtrWillBeRawPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValue(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
- return 0;
- return cloneAndCacheForCSSOM(m_propertySet->getPropertyCSSValue(propertyID).get());
+ return nullptr;
+ return cloneAndCacheForCSSOM(propertySet().getPropertyCSSValue(propertyID).get());
}
-String PropertySetCSSStyleDeclaration::getPropertyValue(const String &propertyName)
+String AbstractPropertySetCSSStyleDeclaration::getPropertyValue(const String &propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return String();
- return m_propertySet->getPropertyValue(propertyID);
+ return propertySet().getPropertyValue(propertyID);
}
-String PropertySetCSSStyleDeclaration::getPropertyPriority(const String& propertyName)
+String AbstractPropertySetCSSStyleDeclaration::getPropertyPriority(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return String();
- return m_propertySet->propertyIsImportant(propertyID) ? "important" : "";
+ return propertySet().propertyIsImportant(propertyID) ? "important" : "";
}
-String PropertySetCSSStyleDeclaration::getPropertyShorthand(const String& propertyName)
+String AbstractPropertySetCSSStyleDeclaration::getPropertyShorthand(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return String();
- CSSPropertyID shorthandID = m_propertySet->getPropertyShorthand(propertyID);
+ CSSPropertyID shorthandID = propertySet().getPropertyShorthand(propertyID);
if (!shorthandID)
return String();
return getPropertyNameString(shorthandID);
}
-bool PropertySetCSSStyleDeclaration::isPropertyImplicit(const String& propertyName)
+bool AbstractPropertySetCSSStyleDeclaration::isPropertyImplicit(const String& propertyName)
{
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return false;
- return m_propertySet->isPropertyImplicit(propertyID);
+ return propertySet().isPropertyImplicit(propertyID);
}
-void PropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState& exceptionState)
+void AbstractPropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState& exceptionState)
{
- StyleAttributeMutationScope mutationScope(this);
CSSPropertyID propertyID = cssPropertyID(propertyName);
if (!propertyID)
return;
- bool important = priority.find("important", 0, false) != kNotFound;
-
- willMutate();
-
- bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet());
-
- didMutate(changed ? PropertyChanged : NoChanges);
+ bool important = equalIgnoringCase(priority, "important");
+ if (!important && !priority.isEmpty())
+ return;
- if (changed) {
- // CSS DOM requires raising SyntaxError of parsing failed, but this is too dangerous for compatibility,
- // see <http://bugs.webkit.org/show_bug.cgi?id=7296>.
- mutationScope.enqueueMutationRecord();
- }
+ setPropertyInternal(propertyID, value, important, exceptionState);
}
-String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionState& exceptionState)
+String AbstractPropertySetCSSStyleDeclaration::removeProperty(const String& propertyName, ExceptionState& exceptionState)
{
StyleAttributeMutationScope mutationScope(this);
CSSPropertyID propertyID = cssPropertyID(propertyName);
@@ -240,7 +238,7 @@ String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName
willMutate();
String result;
- bool changed = m_propertySet->removeProperty(propertyID, &result);
+ bool changed = propertySet().removeProperty(propertyID, &result);
didMutate(changed ? PropertyChanged : NoChanges);
@@ -249,22 +247,22 @@ String PropertySetCSSStyleDeclaration::removeProperty(const String& propertyName
return result;
}
-PassRefPtr<CSSValue> PropertySetCSSStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
+PassRefPtrWillBeRawPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
{
- return m_propertySet->getPropertyCSSValue(propertyID);
+ return propertySet().getPropertyCSSValue(propertyID);
}
-String PropertySetCSSStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
+String AbstractPropertySetCSSStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
{
- return m_propertySet->getPropertyValue(propertyID);
+ return propertySet().getPropertyValue(propertyID);
}
-void PropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyID, const String& value, bool important, ExceptionState&)
+void AbstractPropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyID, const String& value, bool important, ExceptionState&)
{
StyleAttributeMutationScope mutationScope(this);
willMutate();
- bool changed = m_propertySet->setProperty(propertyID, value, important, contextStyleSheet());
+ bool changed = propertySet().setProperty(propertyID, value, important, contextStyleSheet());
didMutate(changed ? PropertyChanged : NoChanges);
@@ -272,60 +270,7 @@ void PropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyI
mutationScope.enqueueMutationRecord();
}
-unsigned PropertySetCSSStyleDeclaration::variableCount() const
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- return m_propertySet->variableCount();
-}
-
-String PropertySetCSSStyleDeclaration::variableValue(const AtomicString& name) const
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- return m_propertySet->variableValue(name);
-}
-
-bool PropertySetCSSStyleDeclaration::setVariableValue(const AtomicString& name, const String& value, ExceptionState&)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- StyleAttributeMutationScope mutationScope(this);
- willMutate();
- bool changed = m_propertySet->setVariableValue(name, value);
- didMutate(changed ? PropertyChanged : NoChanges);
- if (changed)
- mutationScope.enqueueMutationRecord();
- return changed;
-}
-
-bool PropertySetCSSStyleDeclaration::removeVariable(const AtomicString& name)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- StyleAttributeMutationScope mutationScope(this);
- willMutate();
- bool changed = m_propertySet->removeVariable(name);
- didMutate(changed ? PropertyChanged : NoChanges);
- if (changed)
- mutationScope.enqueueMutationRecord();
- return changed;
-}
-
-bool PropertySetCSSStyleDeclaration::clearVariables(ExceptionState&)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- StyleAttributeMutationScope mutationScope(this);
- willMutate();
- bool changed = m_propertySet->clearVariables();
- didMutate(changed ? PropertyChanged : NoChanges);
- if (changed)
- mutationScope.enqueueMutationRecord();
- return changed;
-}
-
-PassRefPtr<CSSVariablesIterator> PropertySetCSSStyleDeclaration::variablesIterator() const
-{
- return m_propertySet->variablesIterator();
-}
-
-CSSValue* PropertySetCSSStyleDeclaration::cloneAndCacheForCSSOM(CSSValue* internalValue)
+CSSValue* AbstractPropertySetCSSStyleDeclaration::cloneAndCacheForCSSOM(CSSValue* internalValue)
{
if (!internalValue)
return 0;
@@ -333,43 +278,58 @@ CSSValue* PropertySetCSSStyleDeclaration::cloneAndCacheForCSSOM(CSSValue* intern
// The map is here to maintain the object identity of the CSSValues over multiple invocations.
// FIXME: It is likely that the identity is not important for web compatibility and this code should be removed.
if (!m_cssomCSSValueClones)
- m_cssomCSSValueClones = adoptPtr(new HashMap<CSSValue*, RefPtr<CSSValue> >);
+ m_cssomCSSValueClones = adoptPtrWillBeNoop(new WillBeHeapHashMap<RawPtrWillBeMember<CSSValue>, RefPtrWillBeMember<CSSValue> >);
- RefPtr<CSSValue>& clonedValue = m_cssomCSSValueClones->add(internalValue, RefPtr<CSSValue>()).iterator->value;
+ RefPtrWillBeMember<CSSValue>& clonedValue = m_cssomCSSValueClones->add(internalValue, RefPtrWillBeMember<CSSValue>()).storedValue->value;
if (!clonedValue)
clonedValue = internalValue->cloneForCSSOM();
return clonedValue.get();
}
-StyleSheetContents* PropertySetCSSStyleDeclaration::contextStyleSheet() const
+StyleSheetContents* AbstractPropertySetCSSStyleDeclaration::contextStyleSheet() const
{
CSSStyleSheet* cssStyleSheet = parentStyleSheet();
return cssStyleSheet ? cssStyleSheet->contents() : 0;
}
-PassRefPtr<MutableStylePropertySet> PropertySetCSSStyleDeclaration::copyProperties() const
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> AbstractPropertySetCSSStyleDeclaration::copyProperties() const
+{
+ return propertySet().mutableCopy();
+}
+
+bool AbstractPropertySetCSSStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
{
- return m_propertySet->mutableCopy();
+ return propertySet().propertyMatches(propertyID, propertyValue);
}
-bool PropertySetCSSStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
+void AbstractPropertySetCSSStyleDeclaration::trace(Visitor* visitor)
{
- return m_propertySet->propertyMatches(propertyID, propertyValue);
+#if ENABLE(OILPAN)
+ visitor->trace(m_cssomCSSValueClones);
+#endif
+ CSSStyleDeclaration::trace(visitor);
}
-StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(MutableStylePropertySet* propertySet, CSSRule* parentRule)
- : PropertySetCSSStyleDeclaration(propertySet)
+StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(MutableStylePropertySet& propertySetArg, CSSRule* parentRule)
+ : PropertySetCSSStyleDeclaration(propertySetArg)
+#if !ENABLE(OILPAN)
, m_refCount(1)
+#endif
, m_parentRule(parentRule)
{
+#if !ENABLE(OILPAN)
m_propertySet->ref();
+#endif
}
StyleRuleCSSStyleDeclaration::~StyleRuleCSSStyleDeclaration()
{
+#if !ENABLE(OILPAN)
m_propertySet->deref();
+#endif
}
+#if !ENABLE(OILPAN)
void StyleRuleCSSStyleDeclaration::ref()
{
++m_refCount;
@@ -381,6 +341,7 @@ void StyleRuleCSSStyleDeclaration::deref()
if (!--m_refCount)
delete this;
}
+#endif
void StyleRuleCSSStyleDeclaration::willMutate()
{
@@ -403,12 +364,26 @@ CSSStyleSheet* StyleRuleCSSStyleDeclaration::parentStyleSheet() const
return m_parentRule ? m_parentRule->parentStyleSheet() : 0;
}
-void StyleRuleCSSStyleDeclaration::reattach(MutableStylePropertySet* propertySet)
+void StyleRuleCSSStyleDeclaration::reattach(MutableStylePropertySet& propertySet)
{
- ASSERT(propertySet);
+#if !ENABLE(OILPAN)
m_propertySet->deref();
- m_propertySet = propertySet;
+#endif
+ m_propertySet = &propertySet;
+#if !ENABLE(OILPAN)
m_propertySet->ref();
+#endif
+}
+
+void StyleRuleCSSStyleDeclaration::trace(Visitor* visitor)
+{
+ visitor->trace(m_parentRule);
+ PropertySetCSSStyleDeclaration::trace(visitor);
+}
+
+MutableStylePropertySet& InlineCSSStyleDeclaration::propertySet() const
+{
+ return m_parentElement->ensureMutableInlineStyle();
}
void InlineCSSStyleDeclaration::didMutate(MutationType type)
@@ -421,6 +396,7 @@ void InlineCSSStyleDeclaration::didMutate(MutationType type)
if (!m_parentElement)
return;
+ m_parentElement->clearMutableInlineStyleIfEmpty();
m_parentElement->setNeedsStyleRecalc(LocalStyleChange);
m_parentElement->invalidateStyleAttribute();
StyleAttributeMutationScope(this).didInvalidateStyleAttr();
@@ -428,7 +404,25 @@ void InlineCSSStyleDeclaration::didMutate(MutationType type)
CSSStyleSheet* InlineCSSStyleDeclaration::parentStyleSheet() const
{
- return m_parentElement ? m_parentElement->document().elementSheet() : 0;
+ return m_parentElement ? &m_parentElement->document().elementSheet() : 0;
+}
+
+#if !ENABLE(OILPAN)
+void InlineCSSStyleDeclaration::ref()
+{
+ m_parentElement->ref();
+}
+
+void InlineCSSStyleDeclaration::deref()
+{
+ m_parentElement->deref();
+}
+#endif
+
+void InlineCSSStyleDeclaration::trace(Visitor* visitor)
+{
+ visitor->trace(m_parentElement);
+ AbstractPropertySetCSSStyleDeclaration::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h b/chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h
index 20b36855afe..e38bd4557f7 100644
--- a/chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h
+++ b/chromium/third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.h
@@ -40,43 +40,32 @@ class ExceptionState;
class MutableStylePropertySet;
class StyleSheetContents;
-class PropertySetCSSStyleDeclaration : public CSSStyleDeclaration {
+class AbstractPropertySetCSSStyleDeclaration : public CSSStyleDeclaration {
public:
- PropertySetCSSStyleDeclaration(MutableStylePropertySet* propertySet) : m_propertySet(propertySet) { }
-
virtual Element* parentElement() const { return 0; }
- virtual void clearParentElement() { ASSERT_NOT_REACHED(); }
StyleSheetContents* contextStyleSheet() const;
- virtual void ref() OVERRIDE;
- virtual void deref() OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
private:
- virtual CSSRule* parentRule() const OVERRIDE { return 0; };
- virtual unsigned length() const OVERRIDE;
- virtual String item(unsigned index) const OVERRIDE;
- virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName) OVERRIDE;
- virtual String getPropertyValue(const String& propertyName) OVERRIDE;
- virtual String getPropertyPriority(const String& propertyName) OVERRIDE;
- virtual String getPropertyShorthand(const String& propertyName) OVERRIDE;
- virtual bool isPropertyImplicit(const String& propertyName) OVERRIDE;
- virtual void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState&) OVERRIDE;
- virtual String removeProperty(const String& propertyName, ExceptionState&) OVERRIDE;
- virtual String cssText() const OVERRIDE;
- virtual void setCSSText(const String&, ExceptionState&) OVERRIDE;
- virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) OVERRIDE;
- virtual String getPropertyValueInternal(CSSPropertyID) OVERRIDE;
- virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionState&) OVERRIDE;
-
- virtual unsigned variableCount() const OVERRIDE;
- virtual String variableValue(const AtomicString& name) const OVERRIDE;
- virtual bool setVariableValue(const AtomicString& name, const String& value, ExceptionState&) OVERRIDE;
- virtual bool removeVariable(const AtomicString& name) OVERRIDE;
- virtual bool clearVariables(ExceptionState&) OVERRIDE;
- virtual PassRefPtr<CSSVariablesIterator> variablesIterator() const OVERRIDE;
-
- virtual bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const OVERRIDE;
- virtual PassRefPtr<MutableStylePropertySet> copyProperties() const OVERRIDE;
+ virtual CSSRule* parentRule() const OVERRIDE { return 0; }
+ virtual unsigned length() const OVERRIDE FINAL;
+ virtual String item(unsigned index) const OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(const String& propertyName) OVERRIDE FINAL;
+ virtual String getPropertyValue(const String& propertyName) OVERRIDE FINAL;
+ virtual String getPropertyPriority(const String& propertyName) OVERRIDE FINAL;
+ virtual String getPropertyShorthand(const String& propertyName) OVERRIDE FINAL;
+ virtual bool isPropertyImplicit(const String& propertyName) OVERRIDE FINAL;
+ virtual void setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState&) OVERRIDE FINAL;
+ virtual String removeProperty(const String& propertyName, ExceptionState&) OVERRIDE FINAL;
+ virtual String cssText() const OVERRIDE FINAL;
+ virtual void setCSSText(const String&, ExceptionState&) OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) OVERRIDE FINAL;
+ virtual String getPropertyValueInternal(CSSPropertyID) OVERRIDE FINAL;
+ virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionState&) OVERRIDE FINAL;
+
+ virtual bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyProperties() const OVERRIDE FINAL;
CSSValue* cloneAndCacheForCSSOM(CSSValue*);
@@ -84,28 +73,49 @@ protected:
enum MutationType { NoChanges, PropertyChanged };
virtual void willMutate() { }
virtual void didMutate(MutationType) { }
+ virtual MutableStylePropertySet& propertySet() const = 0;
- MutableStylePropertySet* m_propertySet;
- OwnPtr<HashMap<CSSValue*, RefPtr<CSSValue> > > m_cssomCSSValueClones;
+ OwnPtrWillBeMember<WillBeHeapHashMap<RawPtrWillBeMember<CSSValue>, RefPtrWillBeMember<CSSValue> > > m_cssomCSSValueClones;
};
-class StyleRuleCSSStyleDeclaration : public PropertySetCSSStyleDeclaration
+class PropertySetCSSStyleDeclaration : public AbstractPropertySetCSSStyleDeclaration {
+public:
+ PropertySetCSSStyleDeclaration(MutableStylePropertySet& propertySet) : m_propertySet(&propertySet) { }
+
+#if !ENABLE(OILPAN)
+ virtual void ref() OVERRIDE;
+ virtual void deref() OVERRIDE;
+#endif
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+protected:
+ virtual MutableStylePropertySet& propertySet() const OVERRIDE FINAL { ASSERT(m_propertySet); return *m_propertySet; }
+
+ RawPtrWillBeMember<MutableStylePropertySet> m_propertySet; // Cannot be null
+};
+
+class StyleRuleCSSStyleDeclaration FINAL : public PropertySetCSSStyleDeclaration
{
public:
- static PassRefPtr<StyleRuleCSSStyleDeclaration> create(MutableStylePropertySet* propertySet, CSSRule* parentRule)
+ static PassRefPtrWillBeRawPtr<StyleRuleCSSStyleDeclaration> create(MutableStylePropertySet& propertySet, CSSRule* parentRule)
{
- return adoptRef(new StyleRuleCSSStyleDeclaration(propertySet, parentRule));
+ return adoptRefWillBeNoop(new StyleRuleCSSStyleDeclaration(propertySet, parentRule));
}
- void clearParentRule() { m_parentRule = 0; }
+#if !ENABLE(OILPAN)
+ void clearParentRule() { m_parentRule = nullptr; }
virtual void ref() OVERRIDE;
virtual void deref() OVERRIDE;
+#endif
+
+ void reattach(MutableStylePropertySet&);
- void reattach(MutableStylePropertySet*);
+ virtual void trace(Visitor*) OVERRIDE;
private:
- StyleRuleCSSStyleDeclaration(MutableStylePropertySet*, CSSRule*);
+ StyleRuleCSSStyleDeclaration(MutableStylePropertySet&, CSSRule*);
virtual ~StyleRuleCSSStyleDeclaration();
virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE;
@@ -115,27 +125,34 @@ private:
virtual void willMutate() OVERRIDE;
virtual void didMutate(MutationType) OVERRIDE;
+#if !ENABLE(OILPAN)
unsigned m_refCount;
- CSSRule* m_parentRule;
+#endif
+ RawPtrWillBeMember<CSSRule> m_parentRule;
};
-class InlineCSSStyleDeclaration : public PropertySetCSSStyleDeclaration
+class InlineCSSStyleDeclaration FINAL : public AbstractPropertySetCSSStyleDeclaration
{
public:
- InlineCSSStyleDeclaration(MutableStylePropertySet* propertySet, Element* parentElement)
- : PropertySetCSSStyleDeclaration(propertySet)
- , m_parentElement(parentElement)
+ explicit InlineCSSStyleDeclaration(Element* parentElement)
+ : m_parentElement(parentElement)
{
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
+ virtual MutableStylePropertySet& propertySet() const OVERRIDE;
+#if !ENABLE(OILPAN)
+ virtual void ref() OVERRIDE;
+ virtual void deref() OVERRIDE;
+#endif
virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE;
virtual Element* parentElement() const OVERRIDE { return m_parentElement; }
- virtual void clearParentElement() OVERRIDE { m_parentElement = 0; }
virtual void didMutate(MutationType) OVERRIDE;
- Element* m_parentElement;
+ RawPtrWillBeMember<Element> m_parentElement;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/RGBColor.cpp b/chromium/third_party/WebKit/Source/core/css/RGBColor.cpp
index 6b131d04654..9994d231786 100644
--- a/chromium/third_party/WebKit/Source/core/css/RGBColor.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/RGBColor.cpp
@@ -30,39 +30,39 @@
namespace WebCore {
-PassRefPtr<RGBColor> RGBColor::create(unsigned rgbColor)
+PassRefPtrWillBeRawPtr<RGBColor> RGBColor::create(unsigned rgbColor)
{
- return adoptRef(new RGBColor(rgbColor));
+ return adoptRefWillBeNoop(new RGBColor(rgbColor));
}
-PassRefPtr<CSSPrimitiveValue> RGBColor::red()
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> RGBColor::red()
{
unsigned value = (m_rgbColor >> 16) & 0xFF;
- RefPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
result->setCSSOMSafe();
return result.release();
}
-PassRefPtr<CSSPrimitiveValue> RGBColor::green()
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> RGBColor::green()
{
unsigned value = (m_rgbColor >> 8) & 0xFF;
- RefPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
result->setCSSOMSafe();
return result.release();
}
-PassRefPtr<CSSPrimitiveValue> RGBColor::blue()
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> RGBColor::blue()
{
unsigned value = m_rgbColor & 0xFF;
- RefPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
result->setCSSOMSafe();
return result.release();
}
-PassRefPtr<CSSPrimitiveValue> RGBColor::alpha()
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> RGBColor::alpha()
{
float value = static_cast<float>((m_rgbColor >> 24) & 0xFF) / 0xFF;
- RefPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = CSSPrimitiveValue::create(value, CSSPrimitiveValue::CSS_NUMBER);
result->setCSSOMSafe();
return result.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/css/RGBColor.h b/chromium/third_party/WebKit/Source/core/css/RGBColor.h
index 5cd4697d4fb..51a98f8845a 100644
--- a/chromium/third_party/WebKit/Source/core/css/RGBColor.h
+++ b/chromium/third_party/WebKit/Source/core/css/RGBColor.h
@@ -28,23 +28,26 @@
#define RGBColor_h
#include "platform/graphics/Color.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
namespace WebCore {
class CSSPrimitiveValue;
- class RGBColor : public RefCounted<RGBColor> {
+ class RGBColor : public RefCountedWillBeGarbageCollected<RGBColor> {
public:
- static PassRefPtr<RGBColor> create(unsigned rgbColor);
+ static PassRefPtrWillBeRawPtr<RGBColor> create(unsigned rgbColor);
- PassRefPtr<CSSPrimitiveValue> red();
- PassRefPtr<CSSPrimitiveValue> green();
- PassRefPtr<CSSPrimitiveValue> blue();
- PassRefPtr<CSSPrimitiveValue> alpha();
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> red();
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> green();
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> blue();
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> alpha();
Color color() const { return Color(m_rgbColor); }
+ void trace(Visitor*) { }
+
private:
RGBColor(unsigned rgbColor)
: m_rgbColor(rgbColor)
diff --git a/chromium/third_party/WebKit/Source/core/css/RGBColor.idl b/chromium/third_party/WebKit/Source/core/css/RGBColor.idl
index 09fa76ef2ef..398fe1b5085 100644
--- a/chromium/third_party/WebKit/Source/core/css/RGBColor.idl
+++ b/chromium/third_party/WebKit/Source/core/css/RGBColor.idl
@@ -19,6 +19,7 @@
*/
[
+ WillBeGarbageCollected
] interface RGBColor {
readonly attribute CSSPrimitiveValue red;
readonly attribute CSSPrimitiveValue green;
diff --git a/chromium/third_party/WebKit/Source/core/css/Rect.cpp b/chromium/third_party/WebKit/Source/core/css/Rect.cpp
new file mode 100644
index 00000000000..13afc70a656
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/Rect.cpp
@@ -0,0 +1,20 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/Rect.h"
+
+namespace WebCore {
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(RectBase)
+
+void RectBase::trace(Visitor* visitor)
+{
+ visitor->trace(m_top);
+ visitor->trace(m_right);
+ visitor->trace(m_bottom);
+ visitor->trace(m_left);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/Rect.h b/chromium/third_party/WebKit/Source/core/css/Rect.h
index 21978cd15fa..2f9e08e4a6d 100644
--- a/chromium/third_party/WebKit/Source/core/css/Rect.h
+++ b/chromium/third_party/WebKit/Source/core/css/Rect.h
@@ -27,17 +27,18 @@
namespace WebCore {
-class RectBase {
+class RectBase : public RefCountedWillBeGarbageCollected<RectBase> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(RectBase);
public:
CSSPrimitiveValue* top() const { return m_top.get(); }
CSSPrimitiveValue* right() const { return m_right.get(); }
CSSPrimitiveValue* bottom() const { return m_bottom.get(); }
CSSPrimitiveValue* left() const { return m_left.get(); }
- void setTop(PassRefPtr<CSSPrimitiveValue> top) { m_top = top; }
- void setRight(PassRefPtr<CSSPrimitiveValue> right) { m_right = right; }
- void setBottom(PassRefPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
- void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; }
+ void setTop(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> top) { m_top = top; }
+ void setRight(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> right) { m_right = right; }
+ void setBottom(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
+ void setLeft(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> left) { m_left = left; }
bool equals(const RectBase& other) const
{
@@ -47,83 +48,63 @@ public:
&& compareCSSValuePtr(m_bottom, other.m_bottom);
}
- bool hasVariableReference() const
- {
- return m_top->hasVariableReference()
- || m_right->hasVariableReference()
- || m_bottom->hasVariableReference()
- || m_left->hasVariableReference();
- }
+ void trace(Visitor*);
protected:
RectBase() { }
RectBase(const RectBase& cloneFrom)
- : m_top(cloneFrom.m_top ? cloneFrom.m_top->cloneForCSSOM() : 0)
- , m_right(cloneFrom.m_right ? cloneFrom.m_right->cloneForCSSOM() : 0)
- , m_bottom(cloneFrom.m_bottom ? cloneFrom.m_bottom->cloneForCSSOM() : 0)
- , m_left(cloneFrom.m_left ? cloneFrom.m_left->cloneForCSSOM() : 0)
+ : m_top(cloneFrom.m_top ? cloneFrom.m_top->cloneForCSSOM() : nullptr)
+ , m_right(cloneFrom.m_right ? cloneFrom.m_right->cloneForCSSOM() : nullptr)
+ , m_bottom(cloneFrom.m_bottom ? cloneFrom.m_bottom->cloneForCSSOM() : nullptr)
+ , m_left(cloneFrom.m_left ? cloneFrom.m_left->cloneForCSSOM() : nullptr)
{
}
- ~RectBase() { }
-
private:
- RefPtr<CSSPrimitiveValue> m_top;
- RefPtr<CSSPrimitiveValue> m_right;
- RefPtr<CSSPrimitiveValue> m_bottom;
- RefPtr<CSSPrimitiveValue> m_left;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_top;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_right;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_bottom;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_left;
};
-class Rect : public RectBase, public RefCounted<Rect> {
+class Rect : public RectBase {
public:
- static PassRefPtr<Rect> create() { return adoptRef(new Rect); }
+ static PassRefPtrWillBeRawPtr<Rect> create() { return adoptRefWillBeNoop(new Rect); }
- PassRefPtr<Rect> cloneForCSSOM() const { return adoptRef(new Rect(*this)); }
+ PassRefPtrWillBeRawPtr<Rect> cloneForCSSOM() const { return adoptRefWillBeNoop(new Rect(*this)); }
String cssText() const
{
return generateCSSString(top()->cssText(), right()->cssText(), bottom()->cssText(), left()->cssText());
}
- String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
- {
- return generateCSSString(top()->customSerializeResolvingVariables(variables),
- right()->customSerializeResolvingVariables(variables),
- bottom()->customSerializeResolvingVariables(variables),
- left()->customSerializeResolvingVariables(variables));
- }
-
private:
Rect() { }
- Rect(const Rect& cloneFrom) : RectBase(cloneFrom), RefCounted<Rect>() { }
+ Rect(const Rect& cloneFrom) : RectBase(cloneFrom) { }
static String generateCSSString(const String& top, const String& right, const String& bottom, const String& left)
{
return "rect(" + top + ' ' + right + ' ' + bottom + ' ' + left + ')';
}
+
+ // NOTE: If adding fields to this class please make the RectBase trace
+ // method virtual and add a trace method in this subclass tracing the new
+ // fields.
};
-class Quad : public RectBase, public RefCounted<Quad> {
+class Quad : public RectBase {
public:
- static PassRefPtr<Quad> create() { return adoptRef(new Quad); }
+ static PassRefPtrWillBeRawPtr<Quad> create() { return adoptRefWillBeNoop(new Quad); }
- PassRefPtr<Quad> cloneForCSSOM() const { return adoptRef(new Quad(*this)); }
+ PassRefPtrWillBeRawPtr<Quad> cloneForCSSOM() const { return adoptRefWillBeNoop(new Quad(*this)); }
String cssText() const
{
return generateCSSString(top()->cssText(), right()->cssText(), bottom()->cssText(), left()->cssText());
}
- String serializeResolvingVariables(const HashMap<AtomicString, String>& variables) const
- {
- return generateCSSString(top()->customSerializeResolvingVariables(variables),
- right()->customSerializeResolvingVariables(variables),
- bottom()->customSerializeResolvingVariables(variables),
- left()->customSerializeResolvingVariables(variables));
- }
-
private:
Quad() { }
- Quad(const Quad& cloneFrom) : RectBase(cloneFrom), RefCounted<Quad>() { }
+ Quad(const Quad& cloneFrom) : RectBase(cloneFrom) { }
static String generateCSSString(const String& top, const String& right, const String& bottom, const String& left)
{
StringBuilder result;
@@ -144,6 +125,10 @@ private:
}
return result.toString();
}
+
+ // NOTE: If adding fields to this class please make the RectBase trace
+ // method virtual and add a trace method in this subclass tracing the new
+ // fields.
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/Rect.idl b/chromium/third_party/WebKit/Source/core/css/Rect.idl
index 3eac82fd539..87336d5bc06 100644
--- a/chromium/third_party/WebKit/Source/core/css/Rect.idl
+++ b/chromium/third_party/WebKit/Source/core/css/Rect.idl
@@ -18,6 +18,7 @@
*/
[
+ WillBeGarbageCollected
] interface Rect {
readonly attribute CSSPrimitiveValue top;
readonly attribute CSSPrimitiveValue right;
diff --git a/chromium/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp b/chromium/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
new file mode 100644
index 00000000000..5316a6ef55a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp
@@ -0,0 +1,193 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/RemoteFontFaceSource.h"
+
+#include "core/css/CSSCustomFontData.h"
+#include "core/css/CSSFontFace.h"
+#include "core/css/FontLoader.h"
+#include "platform/fonts/FontCache.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+#include "public/platform/Platform.h"
+#include "wtf/CurrentTime.h"
+
+namespace WebCore {
+
+RemoteFontFaceSource::RemoteFontFaceSource(FontResource* font, PassRefPtrWillBeRawPtr<FontLoader> fontLoader)
+ : m_font(font)
+ , m_fontLoader(fontLoader)
+{
+ m_font->addClient(this);
+}
+
+RemoteFontFaceSource::~RemoteFontFaceSource()
+{
+ m_font->removeClient(this);
+ pruneTable();
+}
+
+void RemoteFontFaceSource::pruneTable()
+{
+ if (m_fontDataTable.isEmpty())
+ return;
+
+ for (FontDataTable::iterator it = m_fontDataTable.begin(); it != m_fontDataTable.end(); ++it) {
+ SimpleFontData* fontData = it->value.get();
+ if (fontData && fontData->customFontData())
+ fontData->customFontData()->clearFontFaceSource();
+ }
+ m_fontDataTable.clear();
+}
+
+bool RemoteFontFaceSource::isLoading() const
+{
+ return !m_font->stillNeedsLoad() && !m_font->isLoaded();
+}
+
+bool RemoteFontFaceSource::isLoaded() const
+{
+ return m_font->isLoaded();
+}
+
+bool RemoteFontFaceSource::isValid() const
+{
+ return !m_font->errorOccurred();
+}
+
+void RemoteFontFaceSource::didStartFontLoad(FontResource*)
+{
+ // We may send duplicated reports when multiple CSSFontFaceSource are
+ // registered at this FontResource. Associating the same URL to different
+ // font-family causes the case, but we treat them as indivisual resources.
+ m_histograms.loadStarted();
+}
+
+void RemoteFontFaceSource::fontLoaded(FontResource*)
+{
+ m_histograms.recordRemoteFont(m_font.get());
+
+ pruneTable();
+ if (m_face) {
+ m_fontLoader->fontFaceInvalidated();
+ m_face->fontLoaded(this);
+ }
+}
+
+void RemoteFontFaceSource::fontLoadWaitLimitExceeded(FontResource*)
+{
+ pruneTable();
+ if (m_face) {
+ m_fontLoader->fontFaceInvalidated();
+ m_face->fontLoadWaitLimitExceeded(this);
+ }
+
+ m_histograms.recordFallbackTime(m_font.get());
+}
+
+PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+ if (!isLoaded())
+ return createLoadingFallbackFontData(fontDescription);
+
+ // Create new FontPlatformData from our CGFontRef, point size and ATSFontRef.
+ if (!m_font->ensureCustomFontData())
+ return nullptr;
+
+ m_histograms.recordFallbackTime(m_font.get());
+
+ return SimpleFontData::create(
+ m_font->platformDataFromCustomData(fontDescription.effectiveFontSize(),
+ fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic(),
+ fontDescription.orientation(), fontDescription.widthVariant()), CustomFontData::create());
+}
+
+PassRefPtr<SimpleFontData> RemoteFontFaceSource::createLoadingFallbackFontData(const FontDescription& fontDescription)
+{
+ // This temporary font is not retained and should not be returned.
+ FontCachePurgePreventer fontCachePurgePreventer;
+ SimpleFontData* temporaryFont = FontCache::fontCache()->getNonRetainedLastResortFallbackFont(fontDescription);
+ if (!temporaryFont) {
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+ RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create(this, m_font->exceedsFontLoadWaitLimit() ? CSSCustomFontData::VisibleFallback : CSSCustomFontData::InvisibleFallback);
+ return SimpleFontData::create(temporaryFont->platformData(), cssFontData);
+}
+
+void RemoteFontFaceSource::beginLoadIfNeeded()
+{
+ if (m_font->stillNeedsLoad())
+ m_fontLoader->addFontToBeginLoading(m_font.get());
+
+ if (m_face)
+ m_face->didBeginLoad();
+}
+
+bool RemoteFontFaceSource::ensureFontData()
+{
+ return m_font->ensureCustomFontData();
+}
+
+void RemoteFontFaceSource::trace(Visitor* visitor)
+{
+ visitor->trace(m_fontLoader);
+ CSSFontFaceSource::trace(visitor);
+}
+
+void RemoteFontFaceSource::FontLoadHistograms::loadStarted()
+{
+ if (!m_loadStartTime)
+ m_loadStartTime = currentTimeMS();
+}
+
+void RemoteFontFaceSource::FontLoadHistograms::fallbackFontPainted()
+{
+ if (!m_fallbackPaintTime)
+ m_fallbackPaintTime = currentTimeMS();
+}
+
+void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime(const FontResource* font)
+{
+ if (m_fallbackPaintTime <= 0)
+ return;
+ int duration = static_cast<int>(currentTimeMS() - m_fallbackPaintTime);
+ blink::Platform::current()->histogramCustomCounts("WebFont.BlankTextShownTime", duration, 0, 10000, 50);
+ m_fallbackPaintTime = -1;
+}
+
+void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont(const FontResource* font)
+{
+ if (m_loadStartTime > 0 && font && !font->isLoading()) {
+ int duration = static_cast<int>(currentTimeMS() - m_loadStartTime);
+ blink::Platform::current()->histogramCustomCounts(histogramName(font), duration, 0, 10000, 50);
+ m_loadStartTime = -1;
+
+ enum { Miss, Hit, DataUrl, CacheHitEnumMax };
+ int histogramValue = font->url().protocolIsData() ? DataUrl
+ : font->response().wasCached() ? Hit
+ : Miss;
+ blink::Platform::current()->histogramEnumeration("WebFont.CacheHit", histogramValue, CacheHitEnumMax);
+ }
+}
+
+const char* RemoteFontFaceSource::FontLoadHistograms::histogramName(const FontResource* font)
+{
+ if (font->errorOccurred())
+ return "WebFont.DownloadTime.LoadError";
+
+ unsigned size = font->encodedSize();
+ if (size < 10 * 1024)
+ return "WebFont.DownloadTime.0.Under10KB";
+ if (size < 50 * 1024)
+ return "WebFont.DownloadTime.1.10KBTo50KB";
+ if (size < 100 * 1024)
+ return "WebFont.DownloadTime.2.50KBTo100KB";
+ if (size < 1024 * 1024)
+ return "WebFont.DownloadTime.3.100KBTo1MB";
+ return "WebFont.DownloadTime.4.Over1MB";
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/RemoteFontFaceSource.h b/chromium/third_party/WebKit/Source/core/css/RemoteFontFaceSource.h
new file mode 100644
index 00000000000..f7d84ee5a36
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/RemoteFontFaceSource.h
@@ -0,0 +1,70 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef RemoteFontFaceSource_h
+#define RemoteFontFaceSource_h
+
+#include "core/css/CSSFontFaceSource.h"
+#include "core/fetch/FontResource.h"
+#include "core/fetch/ResourcePtr.h"
+
+namespace WebCore {
+
+class FontLoader;
+
+class RemoteFontFaceSource : public CSSFontFaceSource, public FontResourceClient {
+public:
+ explicit RemoteFontFaceSource(FontResource*, PassRefPtrWillBeRawPtr<FontLoader>);
+ virtual ~RemoteFontFaceSource();
+
+ virtual FontResource* resource() OVERRIDE { return m_font.get(); }
+ virtual bool isLoading() const OVERRIDE;
+ virtual bool isLoaded() const OVERRIDE;
+ virtual bool isValid() const OVERRIDE;
+
+ void beginLoadIfNeeded() OVERRIDE;
+ virtual bool ensureFontData();
+
+#if ENABLE(SVG_FONTS)
+ virtual bool isSVGFontFaceSource() const { return false; }
+#endif
+
+ virtual void didStartFontLoad(FontResource*) OVERRIDE;
+ virtual void fontLoaded(FontResource*) OVERRIDE;
+ virtual void fontLoadWaitLimitExceeded(FontResource*) OVERRIDE;
+
+ // For UMA reporting
+ virtual bool hadBlankText() OVERRIDE { return m_histograms.hadBlankText(); }
+ void paintRequested() { m_histograms.fallbackFontPainted(); }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+protected:
+ virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+ PassRefPtr<SimpleFontData> createLoadingFallbackFontData(const FontDescription&);
+ void pruneTable();
+
+private:
+ class FontLoadHistograms {
+ public:
+ FontLoadHistograms() : m_loadStartTime(0), m_fallbackPaintTime(0) { }
+ void loadStarted();
+ void fallbackFontPainted();
+ void recordRemoteFont(const FontResource*);
+ void recordFallbackTime(const FontResource*);
+ bool hadBlankText() { return m_fallbackPaintTime; }
+ private:
+ const char* histogramName(const FontResource*);
+ double m_loadStartTime;
+ double m_fallbackPaintTime;
+ };
+
+ ResourcePtr<FontResource> m_font;
+ RefPtrWillBeMember<FontLoader> m_fontLoader;
+ FontLoadHistograms m_histograms;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/RuleFeature.cpp b/chromium/third_party/WebKit/Source/core/css/RuleFeature.cpp
index 7c8f160ae43..26aea450ff0 100644
--- a/chromium/third_party/WebKit/Source/core/css/RuleFeature.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/RuleFeature.cpp
@@ -29,70 +29,501 @@
#include "config.h"
#include "core/css/RuleFeature.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSSelector.h"
#include "core/css/CSSSelectorList.h"
+#include "core/css/RuleSet.h"
+#include "core/css/StyleRule.h"
+#include "core/css/invalidation/DescendantInvalidationSet.h"
+#include "core/dom/Element.h"
+#include "core/dom/Node.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "wtf/BitVector.h"
namespace WebCore {
-void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector* selector)
-{
- if (selector->m_match == CSSSelector::Id)
- idsInRules.add(selector->value());
- else if (selector->m_match == CSSSelector::Class)
- classesInRules.add(selector->value());
- else if (selector->isAttributeSelector())
- attrsInRules.add(selector->attribute().localName());
- switch (selector->pseudoType()) {
- case CSSSelector::PseudoFirstLine:
- m_usesFirstLineRules = true;
- break;
- break;
- case CSSSelector::PseudoHost:
- collectFeaturesFromSelectorList(selector->selectorList());
- break;
+static bool isSkippableComponentForInvalidation(const CSSSelector& selector)
+{
+ if (selector.match() == CSSSelector::Tag
+ || selector.match() == CSSSelector::Id
+ || selector.isAttributeSelector())
+ return true;
+ if (selector.match() == CSSSelector::PseudoElement) {
+ switch (selector.pseudoType()) {
+ case CSSSelector::PseudoBefore:
+ case CSSSelector::PseudoAfter:
+ case CSSSelector::PseudoBackdrop:
+ case CSSSelector::PseudoShadow:
+ return true;
+ default:
+ return selector.isCustomPseudoElement();
+ }
+ }
+ if (selector.match() != CSSSelector::PseudoClass)
+ return false;
+ switch (selector.pseudoType()) {
+ case CSSSelector::PseudoEmpty:
+ case CSSSelector::PseudoFirstChild:
+ case CSSSelector::PseudoFirstOfType:
+ case CSSSelector::PseudoLastChild:
+ case CSSSelector::PseudoLastOfType:
+ case CSSSelector::PseudoOnlyChild:
+ case CSSSelector::PseudoOnlyOfType:
+ case CSSSelector::PseudoNthChild:
+ case CSSSelector::PseudoNthOfType:
+ case CSSSelector::PseudoNthLastChild:
+ case CSSSelector::PseudoNthLastOfType:
+ case CSSSelector::PseudoLink:
+ case CSSSelector::PseudoVisited:
+ case CSSSelector::PseudoAnyLink:
+ case CSSSelector::PseudoHover:
+ case CSSSelector::PseudoDrag:
+ case CSSSelector::PseudoFocus:
+ case CSSSelector::PseudoActive:
+ case CSSSelector::PseudoChecked:
+ case CSSSelector::PseudoEnabled:
+ case CSSSelector::PseudoDefault:
+ case CSSSelector::PseudoDisabled:
+ case CSSSelector::PseudoOptional:
+ case CSSSelector::PseudoRequired:
+ case CSSSelector::PseudoReadOnly:
+ case CSSSelector::PseudoReadWrite:
+ case CSSSelector::PseudoValid:
+ case CSSSelector::PseudoInvalid:
+ case CSSSelector::PseudoIndeterminate:
+ case CSSSelector::PseudoTarget:
+ case CSSSelector::PseudoLang:
+ case CSSSelector::PseudoRoot:
+ case CSSSelector::PseudoScope:
+ case CSSSelector::PseudoInRange:
+ case CSSSelector::PseudoOutOfRange:
+ case CSSSelector::PseudoUnresolved:
+ return true;
default:
- break;
+ return false;
+ }
+}
+
+RuleFeature::RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin)
+ : rule(rule)
+ , selectorIndex(selectorIndex)
+ , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin)
+{
+}
+
+void RuleFeature::trace(Visitor* visitor)
+{
+ visitor->trace(rule);
+}
+
+// This method is somewhat conservative in what it accepts.
+RuleFeatureSet::InvalidationSetMode RuleFeatureSet::invalidationSetModeForSelector(const CSSSelector& selector)
+{
+ bool foundDescendantRelation = false;
+ bool foundIdent = false;
+ for (const CSSSelector* component = &selector; component; component = component->tagHistory()) {
+
+ if (component->match() == CSSSelector::Class || component->match() == CSSSelector::Id
+ || (component->match() == CSSSelector::Tag && component->tagQName().localName() != starAtom)
+ || component->isAttributeSelector() || component->isCustomPseudoElement()) {
+ if (!foundDescendantRelation)
+ foundIdent = true;
+ } else if (component->pseudoType() == CSSSelector::PseudoHost || component->pseudoType() == CSSSelector::PseudoAny) {
+ if (const CSSSelectorList* selectorList = component->selectorList()) {
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) {
+ InvalidationSetMode hostMode = invalidationSetModeForSelector(*selector);
+ if (hostMode == UseSubtreeStyleChange)
+ return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeStyleChange;
+ if (!foundDescendantRelation && hostMode == AddFeatures)
+ foundIdent = true;
+ }
+ }
+ } else if (!isSkippableComponentForInvalidation(*component)) {
+ return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeStyleChange;
+ }
+ switch (component->relation()) {
+ case CSSSelector::Descendant:
+ case CSSSelector::Child:
+ case CSSSelector::ShadowPseudo:
+ case CSSSelector::ShadowDeep:
+ foundDescendantRelation = true;
+ // Fall through!
+ case CSSSelector::SubSelector:
+ case CSSSelector::DirectAdjacent:
+ case CSSSelector::IndirectAdjacent:
+ continue;
+ default:
+ // All combinators should be handled above.
+ ASSERT_NOT_REACHED();
+ return UseLocalStyleChange;
+ }
+ }
+ return foundIdent ? AddFeatures : UseLocalStyleChange;
+}
+
+void RuleFeatureSet::extractInvalidationSetFeature(const CSSSelector& selector, InvalidationSetFeatures& features)
+{
+ if (selector.match() == CSSSelector::Tag)
+ features.tagName = selector.tagQName().localName();
+ else if (selector.match() == CSSSelector::Id)
+ features.id = selector.value();
+ else if (selector.match() == CSSSelector::Class)
+ features.classes.append(selector.value());
+ else if (selector.isAttributeSelector())
+ features.attributes.append(selector.attribute().localName());
+ else if (selector.isCustomPseudoElement())
+ features.customPseudoElement = true;
+}
+
+RuleFeatureSet::RuleFeatureSet()
+ : m_targetedStyleRecalcEnabled(RuntimeEnabledFeatures::targetedStyleRecalcEnabled())
+{
+}
+
+RuleFeatureSet::~RuleFeatureSet()
+{
+}
+
+DescendantInvalidationSet* RuleFeatureSet::invalidationSetForSelector(const CSSSelector& selector)
+{
+ if (selector.match() == CSSSelector::Class)
+ return &ensureClassInvalidationSet(selector.value());
+ if (selector.isAttributeSelector())
+ return &ensureAttributeInvalidationSet(selector.attribute().localName());
+ if (selector.match() == CSSSelector::Id)
+ return &ensureIdInvalidationSet(selector.value());
+ if (selector.match() == CSSSelector::PseudoClass) {
+ CSSSelector::PseudoType pseudo = selector.pseudoType();
+ if (pseudo == CSSSelector::PseudoHover || pseudo == CSSSelector::PseudoActive || pseudo == CSSSelector::PseudoFocus)
+ return &ensurePseudoInvalidationSet(pseudo);
+ }
+ return 0;
+}
+
+RuleFeatureSet::InvalidationSetMode RuleFeatureSet::updateInvalidationSets(const CSSSelector& selector)
+{
+ InvalidationSetMode mode = invalidationSetModeForSelector(selector);
+ if (mode != AddFeatures)
+ return mode;
+
+ InvalidationSetFeatures features;
+ if (const CSSSelector* current = extractInvalidationSetFeatures(selector, features))
+ addFeaturesToInvalidationSets(*current, features);
+ return AddFeatures;
+}
+
+const CSSSelector* RuleFeatureSet::extractInvalidationSetFeatures(const CSSSelector& selector, InvalidationSetFeatures& features)
+{
+ for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
+ extractInvalidationSetFeature(*current, features);
+ // Initialize the entry in the invalidation set map, if supported.
+ invalidationSetForSelector(*current);
+ if (current->pseudoType() == CSSSelector::PseudoHost || current->pseudoType() == CSSSelector::PseudoAny) {
+ if (const CSSSelectorList* selectorList = current->selectorList()) {
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
+ extractInvalidationSetFeatures(*selector, features);
+ }
+ }
+
+ switch (current->relation()) {
+ case CSSSelector::SubSelector:
+ break;
+ case CSSSelector::ShadowPseudo:
+ case CSSSelector::ShadowDeep:
+ features.treeBoundaryCrossing = true;
+ return current->tagHistory();
+ case CSSSelector::DirectAdjacent:
+ case CSSSelector::IndirectAdjacent:
+ features.wholeSubtree = true;
+ return current->tagHistory();
+ case CSSSelector::Descendant:
+ case CSSSelector::Child:
+ return current->tagHistory();
+ }
+ }
+ return 0;
+}
+
+void RuleFeatureSet::addFeaturesToInvalidationSets(const CSSSelector& selector, InvalidationSetFeatures& features)
+{
+ for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
+ if (DescendantInvalidationSet* invalidationSet = invalidationSetForSelector(*current)) {
+ if (features.treeBoundaryCrossing)
+ invalidationSet->setTreeBoundaryCrossing();
+ if (features.wholeSubtree) {
+ invalidationSet->setWholeSubtreeInvalid();
+ } else {
+ if (!features.id.isEmpty())
+ invalidationSet->addId(features.id);
+ if (!features.tagName.isEmpty())
+ invalidationSet->addTagName(features.tagName);
+ for (Vector<AtomicString>::const_iterator it = features.classes.begin(); it != features.classes.end(); ++it)
+ invalidationSet->addClass(*it);
+ for (Vector<AtomicString>::const_iterator it = features.attributes.begin(); it != features.attributes.end(); ++it)
+ invalidationSet->addAttribute(*it);
+ if (features.customPseudoElement)
+ invalidationSet->setCustomPseudoInvalid();
+ }
+ } else if (current->pseudoType() == CSSSelector::PseudoHost || current->pseudoType() == CSSSelector::PseudoAny) {
+ if (current->pseudoType() == CSSSelector::PseudoHost)
+ features.treeBoundaryCrossing = true;
+ if (const CSSSelectorList* selectorList = current->selectorList()) {
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
+ addFeaturesToInvalidationSets(*selector, features);
+ }
+ }
+ switch (current->relation()) {
+ case CSSSelector::SubSelector:
+ break;
+ case CSSSelector::ShadowPseudo:
+ case CSSSelector::ShadowDeep:
+ features.treeBoundaryCrossing = true;
+ features.wholeSubtree = false;
+ break;
+ case CSSSelector::Descendant:
+ case CSSSelector::Child:
+ features.wholeSubtree = false;
+ break;
+ case CSSSelector::DirectAdjacent:
+ case CSSSelector::IndirectAdjacent:
+ features.wholeSubtree = true;
+ break;
+ }
+ }
+}
+
+void RuleFeatureSet::addContentAttr(const AtomicString& attributeName)
+{
+ DescendantInvalidationSet& invalidationSet = ensureAttributeInvalidationSet(attributeName);
+ invalidationSet.setWholeSubtreeInvalid();
+}
+
+void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData)
+{
+ FeatureMetadata metadata;
+ InvalidationSetMode mode = UseSubtreeStyleChange;
+ if (m_targetedStyleRecalcEnabled)
+ mode = updateInvalidationSets(ruleData.selector());
+
+ collectFeaturesFromSelector(ruleData.selector(), metadata, mode);
+ m_metadata.add(metadata);
+
+ if (metadata.foundSiblingSelector)
+ siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
+ if (ruleData.containsUncommonAttributeSelector())
+ uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
+}
+
+DescendantInvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const AtomicString& className)
+{
+ InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(className, nullptr);
+ if (addResult.isNewEntry)
+ addResult.storedValue->value = DescendantInvalidationSet::create();
+ return *addResult.storedValue->value;
+}
+
+DescendantInvalidationSet& RuleFeatureSet::ensureAttributeInvalidationSet(const AtomicString& attributeName)
+{
+ InvalidationSetMap::AddResult addResult = m_attributeInvalidationSets.add(attributeName, nullptr);
+ if (addResult.isNewEntry)
+ addResult.storedValue->value = DescendantInvalidationSet::create();
+ return *addResult.storedValue->value;
+}
+
+DescendantInvalidationSet& RuleFeatureSet::ensureIdInvalidationSet(const AtomicString& id)
+{
+ InvalidationSetMap::AddResult addResult = m_idInvalidationSets.add(id, nullptr);
+ if (addResult.isNewEntry)
+ addResult.storedValue->value = DescendantInvalidationSet::create();
+ return *addResult.storedValue->value;
+}
+
+DescendantInvalidationSet& RuleFeatureSet::ensurePseudoInvalidationSet(CSSSelector::PseudoType pseudoType)
+{
+ PseudoTypeInvalidationSetMap::AddResult addResult = m_pseudoInvalidationSets.add(pseudoType, nullptr);
+ if (addResult.isNewEntry)
+ addResult.storedValue->value = DescendantInvalidationSet::create();
+ return *addResult.storedValue->value;
+}
+
+void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector)
+{
+ collectFeaturesFromSelector(selector, m_metadata, UseSubtreeStyleChange);
+}
+
+void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode)
+{
+ unsigned maxDirectAdjacentSelectors = 0;
+
+ for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
+ if (mode != AddFeatures) {
+ if (DescendantInvalidationSet* invalidationSet = invalidationSetForSelector(*current)) {
+ if (mode == UseSubtreeStyleChange)
+ invalidationSet->setWholeSubtreeInvalid();
+ }
+ }
+ if (current->pseudoType() == CSSSelector::PseudoFirstLine)
+ metadata.usesFirstLineRules = true;
+ if (current->isDirectAdjacentSelector()) {
+ maxDirectAdjacentSelectors++;
+ } else if (maxDirectAdjacentSelectors) {
+ if (maxDirectAdjacentSelectors > metadata.maxDirectAdjacentSelectors)
+ metadata.maxDirectAdjacentSelectors = maxDirectAdjacentSelectors;
+ maxDirectAdjacentSelectors = 0;
+ }
+ if (current->isSiblingSelector())
+ metadata.foundSiblingSelector = true;
+
+ collectFeaturesFromSelectorList(current->selectorList(), metadata, mode);
+
+ if (mode == UseLocalStyleChange && current->relation() != CSSSelector::SubSelector)
+ mode = UseSubtreeStyleChange;
}
+
+ ASSERT(!maxDirectAdjacentSelectors);
}
-void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* selectorList)
+void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* selectorList, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode)
{
if (!selectorList)
return;
- for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(selector)) {
- for (const CSSSelector* subSelector = selector; subSelector; subSelector = subSelector->tagHistory())
- collectFeaturesFromSelector(subSelector);
- }
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
+ collectFeaturesFromSelector(*selector, metadata, mode);
+}
+
+void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other)
+{
+ usesFirstLineRules = usesFirstLineRules || other.usesFirstLineRules;
+ maxDirectAdjacentSelectors = std::max(maxDirectAdjacentSelectors, other.maxDirectAdjacentSelectors);
+}
+
+void RuleFeatureSet::FeatureMetadata::clear()
+{
+ usesFirstLineRules = false;
+ foundSiblingSelector = false;
+ maxDirectAdjacentSelectors = 0;
}
void RuleFeatureSet::add(const RuleFeatureSet& other)
{
- HashSet<AtomicString>::const_iterator end = other.idsInRules.end();
- for (HashSet<AtomicString>::const_iterator it = other.idsInRules.begin(); it != end; ++it)
- idsInRules.add(*it);
- end = other.classesInRules.end();
- for (HashSet<AtomicString>::const_iterator it = other.classesInRules.begin(); it != end; ++it)
- classesInRules.add(*it);
- end = other.attrsInRules.end();
- for (HashSet<AtomicString>::const_iterator it = other.attrsInRules.begin(); it != end; ++it)
- attrsInRules.add(*it);
- siblingRules.append(other.siblingRules);
- uncommonAttributeRules.append(other.uncommonAttributeRules);
- m_usesFirstLineRules = m_usesFirstLineRules || other.m_usesFirstLineRules;
- m_maxDirectAdjacentSelectors = std::max(m_maxDirectAdjacentSelectors, other.maxDirectAdjacentSelectors());
+ for (InvalidationSetMap::const_iterator it = other.m_classInvalidationSets.begin(); it != other.m_classInvalidationSets.end(); ++it)
+ ensureClassInvalidationSet(it->key).combine(*it->value);
+ for (InvalidationSetMap::const_iterator it = other.m_attributeInvalidationSets.begin(); it != other.m_attributeInvalidationSets.end(); ++it)
+ ensureAttributeInvalidationSet(it->key).combine(*it->value);
+ for (InvalidationSetMap::const_iterator it = other.m_idInvalidationSets.begin(); it != other.m_idInvalidationSets.end(); ++it)
+ ensureIdInvalidationSet(it->key).combine(*it->value);
+ for (PseudoTypeInvalidationSetMap::const_iterator it = other.m_pseudoInvalidationSets.begin(); it != other.m_pseudoInvalidationSets.end(); ++it)
+ ensurePseudoInvalidationSet(static_cast<CSSSelector::PseudoType>(it->key)).combine(*it->value);
+
+ m_metadata.add(other.m_metadata);
+
+ siblingRules.appendVector(other.siblingRules);
+ uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
}
void RuleFeatureSet::clear()
{
- idsInRules.clear();
- classesInRules.clear();
- attrsInRules.clear();
siblingRules.clear();
uncommonAttributeRules.clear();
- m_usesFirstLineRules = false;
- m_maxDirectAdjacentSelectors = 0;
+ m_metadata.clear();
+ m_classInvalidationSets.clear();
+ m_attributeInvalidationSets.clear();
+ m_idInvalidationSets.clear();
+ // We cannot clear m_styleInvalidator here, because the style invalidator might not
+ // have been evaluated yet. If not yet, in StyleInvalidator, there exists some element
+ // who has needsStyleInvlidation but does not have any invalidation list.
+ // This makes Blink not to recalc style correctly. crbug.com/344729.
+}
+
+void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element& element)
+{
+ unsigned changedSize = changedClasses.size();
+ for (unsigned i = 0; i < changedSize; ++i) {
+ addClassToInvalidationSet(changedClasses[i], element);
+ }
+}
+
+void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element& element)
+{
+ if (!oldClasses.size()) {
+ scheduleStyleInvalidationForClassChange(newClasses, element);
+ return;
+ }
+
+ // Class vectors tend to be very short. This is faster than using a hash table.
+ BitVector remainingClassBits;
+ remainingClassBits.ensureSize(oldClasses.size());
+
+ for (unsigned i = 0; i < newClasses.size(); ++i) {
+ bool found = false;
+ for (unsigned j = 0; j < oldClasses.size(); ++j) {
+ if (newClasses[i] == oldClasses[j]) {
+ // Mark each class that is still in the newClasses so we can skip doing
+ // an n^2 search below when looking for removals. We can't break from
+ // this loop early since a class can appear more than once.
+ remainingClassBits.quickSet(j);
+ found = true;
+ }
+ }
+ // Class was added.
+ if (!found)
+ addClassToInvalidationSet(newClasses[i], element);
+ }
+
+ for (unsigned i = 0; i < oldClasses.size(); ++i) {
+ if (remainingClassBits.quickGet(i))
+ continue;
+ // Class was removed.
+ addClassToInvalidationSet(oldClasses[i], element);
+ }
+}
+
+void RuleFeatureSet::scheduleStyleInvalidationForAttributeChange(const QualifiedName& attributeName, Element& element)
+{
+
+ if (RefPtrWillBeRawPtr<DescendantInvalidationSet> invalidationSet = m_attributeInvalidationSets.get(attributeName.localName()))
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element);
+}
+
+void RuleFeatureSet::scheduleStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, Element& element)
+{
+ if (!oldId.isEmpty()) {
+ if (RefPtrWillBeRawPtr<DescendantInvalidationSet> invalidationSet = m_idInvalidationSets.get(oldId))
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element);
+ }
+ if (!newId.isEmpty()) {
+ if (RefPtrWillBeRawPtr<DescendantInvalidationSet> invalidationSet = m_idInvalidationSets.get(newId))
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element);
+ }
+}
+
+void RuleFeatureSet::scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoType pseudo, Element& element)
+{
+ if (RefPtrWillBeRawPtr<DescendantInvalidationSet> invalidationSet = m_pseudoInvalidationSets.get(pseudo))
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element);
+}
+
+void RuleFeatureSet::addClassToInvalidationSet(const AtomicString& className, Element& element)
+{
+ if (RefPtrWillBeRawPtr<DescendantInvalidationSet> invalidationSet = m_classInvalidationSets.get(className))
+ m_styleInvalidator.scheduleInvalidation(invalidationSet, element);
+}
+
+StyleInvalidator& RuleFeatureSet::styleInvalidator()
+{
+ return m_styleInvalidator;
+}
+
+void RuleFeatureSet::trace(Visitor* visitor)
+{
+ visitor->trace(siblingRules);
+ visitor->trace(uncommonAttributeRules);
+ visitor->trace(m_classInvalidationSets);
+ visitor->trace(m_attributeInvalidationSets);
+ visitor->trace(m_idInvalidationSets);
+ visitor->trace(m_pseudoInvalidationSets);
+ visitor->trace(m_styleInvalidator);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/RuleFeature.h b/chromium/third_party/WebKit/Source/core/css/RuleFeature.h
index b51863c4289..bc098d89244 100644
--- a/chromium/third_party/WebKit/Source/core/css/RuleFeature.h
+++ b/chromium/third_party/WebKit/Source/core/css/RuleFeature.h
@@ -22,76 +22,172 @@
#ifndef RuleFeature_h
#define RuleFeature_h
+#include "core/css/CSSSelector.h"
+#include "core/css/invalidation/StyleInvalidator.h"
#include "wtf/Forward.h"
#include "wtf/HashSet.h"
#include "wtf/text/AtomicStringHash.h"
namespace WebCore {
-class StyleRule;
-class CSSSelector;
class CSSSelectorList;
+class DescendantInvalidationSet;
+class Document;
+class Node;
+class QualifiedName;
+class RuleData;
+class ShadowRoot;
+class SpaceSplitString;
+class StyleRule;
struct RuleFeature {
- RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin)
- : rule(rule)
- , selectorIndex(selectorIndex)
- , hasDocumentSecurityOrigin(hasDocumentSecurityOrigin)
- {
- }
- StyleRule* rule;
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
+ RuleFeature(StyleRule* rule, unsigned selectorIndex, bool hasDocumentSecurityOrigin);
+
+ void trace(Visitor*);
+
+ RawPtrWillBeMember<StyleRule> rule;
unsigned selectorIndex;
bool hasDocumentSecurityOrigin;
};
class RuleFeatureSet {
+ DISALLOW_ALLOCATION();
public:
- RuleFeatureSet()
- : m_usesFirstLineRules(false)
- , m_maxDirectAdjacentSelectors(0)
- { }
+ RuleFeatureSet();
+ ~RuleFeatureSet();
void add(const RuleFeatureSet&);
void clear();
- void collectFeaturesFromSelector(const CSSSelector*);
+ void collectFeaturesFromSelector(const CSSSelector&);
+ void collectFeaturesFromRuleData(const RuleData&);
bool usesSiblingRules() const { return !siblingRules.isEmpty(); }
- bool usesFirstLineRules() const { return m_usesFirstLineRules; }
+ bool usesFirstLineRules() const { return m_metadata.usesFirstLineRules; }
- unsigned maxDirectAdjacentSelectors() const { return m_maxDirectAdjacentSelectors; }
- void setMaxDirectAdjacentSelectors(unsigned value) { m_maxDirectAdjacentSelectors = std::max(value, m_maxDirectAdjacentSelectors); }
+ unsigned maxDirectAdjacentSelectors() const { return m_metadata.maxDirectAdjacentSelectors; }
+ void setMaxDirectAdjacentSelectors(unsigned value) { m_metadata.maxDirectAdjacentSelectors = std::max(value, m_metadata.maxDirectAdjacentSelectors); }
inline bool hasSelectorForAttribute(const AtomicString& attributeName) const
{
ASSERT(!attributeName.isEmpty());
- return attrsInRules.contains(attributeName);
+ return m_attributeInvalidationSets.contains(attributeName);
}
inline bool hasSelectorForClass(const AtomicString& classValue) const
{
ASSERT(!classValue.isEmpty());
- return classesInRules.contains(classValue);
+ return m_classInvalidationSets.contains(classValue);
}
inline bool hasSelectorForId(const AtomicString& idValue) const
{
- ASSERT(!idValue.isEmpty());
- return idsInRules.contains(idValue);
+ return m_idInvalidationSets.contains(idValue);
}
- HashSet<AtomicString> idsInRules;
- HashSet<AtomicString> classesInRules;
- HashSet<AtomicString> attrsInRules;
- Vector<RuleFeature> siblingRules;
- Vector<RuleFeature> uncommonAttributeRules;
-private:
- void collectFeaturesFromSelectorList(const CSSSelectorList*);
+ void scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element&);
+ void scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element&);
+ void scheduleStyleInvalidationForAttributeChange(const QualifiedName& attributeName, Element&);
+ void scheduleStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, Element&);
+ void scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoType, Element&);
+
+ bool hasIdsInSelectors() const
+ {
+ return m_idInvalidationSets.size() > 0;
+ }
- bool m_usesFirstLineRules;
- unsigned m_maxDirectAdjacentSelectors;
+ // Marks the given attribute name as "appearing in a selector". Used for
+ // CSS properties such as content: ... attr(...) ...
+ // FIXME: record these internally to this class instead calls from StyleResolver to here.
+ void addContentAttr(const AtomicString& attributeName);
+
+ StyleInvalidator& styleInvalidator();
+
+ void trace(Visitor*);
+
+ WillBeHeapVector<RuleFeature> siblingRules;
+ WillBeHeapVector<RuleFeature> uncommonAttributeRules;
+
+private:
+ typedef WillBeHeapHashMap<AtomicString, RefPtrWillBeMember<DescendantInvalidationSet> > InvalidationSetMap;
+ typedef WillBeHeapHashMap<CSSSelector::PseudoType, RefPtrWillBeMember<DescendantInvalidationSet>, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > PseudoTypeInvalidationSetMap;
+
+ struct FeatureMetadata {
+ FeatureMetadata()
+ : usesFirstLineRules(false)
+ , foundSiblingSelector(false)
+ , maxDirectAdjacentSelectors(0)
+ { }
+ void add(const FeatureMetadata& other);
+ void clear();
+
+ bool usesFirstLineRules;
+ bool foundSiblingSelector;
+ unsigned maxDirectAdjacentSelectors;
+ };
+
+ enum InvalidationSetMode {
+ AddFeatures,
+ UseLocalStyleChange,
+ UseSubtreeStyleChange
+ };
+
+ static InvalidationSetMode invalidationSetModeForSelector(const CSSSelector&);
+
+ void collectFeaturesFromSelector(const CSSSelector&, FeatureMetadata&, InvalidationSetMode);
+ void collectFeaturesFromSelectorList(const CSSSelectorList*, FeatureMetadata&, InvalidationSetMode);
+
+ DescendantInvalidationSet& ensureClassInvalidationSet(const AtomicString& className);
+ DescendantInvalidationSet& ensureAttributeInvalidationSet(const AtomicString& attributeName);
+ DescendantInvalidationSet& ensureIdInvalidationSet(const AtomicString& attributeName);
+ DescendantInvalidationSet& ensurePseudoInvalidationSet(CSSSelector::PseudoType);
+ DescendantInvalidationSet* invalidationSetForSelector(const CSSSelector&);
+
+ InvalidationSetMode updateInvalidationSets(const CSSSelector&);
+
+ struct InvalidationSetFeatures {
+ InvalidationSetFeatures()
+ : customPseudoElement(false)
+ , treeBoundaryCrossing(false)
+ , wholeSubtree(false)
+ { }
+ Vector<AtomicString> classes;
+ Vector<AtomicString> attributes;
+ AtomicString id;
+ AtomicString tagName;
+ bool customPseudoElement;
+ bool treeBoundaryCrossing;
+ bool wholeSubtree;
+ };
+
+ static void extractInvalidationSetFeature(const CSSSelector&, InvalidationSetFeatures&);
+ const CSSSelector* extractInvalidationSetFeatures(const CSSSelector&, InvalidationSetFeatures&);
+ void addFeaturesToInvalidationSets(const CSSSelector&, InvalidationSetFeatures&);
+
+ void addClassToInvalidationSet(const AtomicString& className, Element&);
+
+ FeatureMetadata m_metadata;
+ InvalidationSetMap m_classInvalidationSets;
+ InvalidationSetMap m_attributeInvalidationSets;
+ InvalidationSetMap m_idInvalidationSets;
+ PseudoTypeInvalidationSetMap m_pseudoInvalidationSets;
+ bool m_targetedStyleRecalcEnabled;
+ StyleInvalidator m_styleInvalidator;
};
+
} // namespace WebCore
+namespace WTF {
+
+template <> struct VectorTraits<WebCore::RuleFeature> : VectorTraitsBase<WebCore::RuleFeature> {
+ static const bool needsDestruction = false;
+ static const bool canInitializeWithMemset = true;
+ static const bool canMoveWithMemcpy = true;
+};
+
+} // namespace WTF
+
#endif // RuleFeature_h
diff --git a/chromium/third_party/WebKit/Source/core/css/RuleSet.cpp b/chromium/third_party/WebKit/Source/core/css/RuleSet.cpp
index f7a0325f543..7e2a8f344fd 100644
--- a/chromium/third_party/WebKit/Source/core/css/RuleSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/RuleSet.cpp
@@ -29,39 +29,43 @@
#include "config.h"
#include "core/css/RuleSet.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSSelector.h"
#include "core/css/CSSSelectorList.h"
#include "core/css/SelectorChecker.h"
-#include "core/css/SelectorCheckerFastPath.h"
#include "core/css/SelectorFilter.h"
#include "core/css/StyleRuleImport.h"
#include "core/css/StyleSheetContents.h"
#include "core/html/track/TextTrackCue.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/TraceEvent.h"
+#include "platform/heap/HeapTerminatedArrayBuilder.h"
#include "platform/weborigin/SecurityOrigin.h"
+#include "wtf/TerminatedArrayBuilder.h"
+
namespace WebCore {
using namespace HTMLNames;
// -----------------------------------------------------------------
-static inline bool isSelectorMatchingHTMLBasedOnRuleHash(const CSSSelector* selector)
+static inline bool isSelectorMatchingHTMLBasedOnRuleHash(const CSSSelector& selector)
{
- ASSERT(selector);
- if (selector->m_match == CSSSelector::Tag) {
- const AtomicString& selectorNamespace = selector->tagQName().namespaceURI();
+ if (selector.match() == CSSSelector::Tag) {
+ const AtomicString& selectorNamespace = selector.tagQName().namespaceURI();
if (selectorNamespace != starAtom && selectorNamespace != xhtmlNamespaceURI)
return false;
- if (selector->relation() == CSSSelector::SubSelector)
- return isSelectorMatchingHTMLBasedOnRuleHash(selector->tagHistory());
+ if (selector.relation() == CSSSelector::SubSelector) {
+ ASSERT(selector.tagHistory());
+ return isSelectorMatchingHTMLBasedOnRuleHash(*selector.tagHistory());
+ }
return true;
}
if (SelectorChecker::isCommonPseudoClassSelector(selector))
return true;
- return selector->m_match == CSSSelector::Id || selector->m_match == CSSSelector::Class;
+ return selector.match() == CSSSelector::Id || selector.match() == CSSSelector::Class;
}
static inline bool selectorListContainsUncommonAttributeSelector(const CSSSelector* selector)
@@ -69,7 +73,7 @@ static inline bool selectorListContainsUncommonAttributeSelector(const CSSSelect
const CSSSelectorList* selectorList = selector->selectorList();
if (!selectorList)
return false;
- for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(selector)) {
+ for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) {
for (const CSSSelector* component = selector; component; component = component->tagHistory()) {
if (component->isAttributeSelector())
return true;
@@ -84,118 +88,48 @@ static inline bool isCommonAttributeSelectorAttribute(const QualifiedName& attri
return attribute == typeAttr || attribute == readonlyAttr;
}
-static inline bool containsUncommonAttributeSelector(const CSSSelector* selector)
+static inline bool containsUncommonAttributeSelector(const CSSSelector& selector)
{
- for (; selector; selector = selector->tagHistory()) {
+ const CSSSelector* current = &selector;
+ for (; current; current = current->tagHistory()) {
// Allow certain common attributes (used in the default style) in the selectors that match the current element.
- if (selector->isAttributeSelector() && !isCommonAttributeSelectorAttribute(selector->attribute()))
+ if (current->isAttributeSelector() && !isCommonAttributeSelectorAttribute(current->attribute()))
return true;
- if (selectorListContainsUncommonAttributeSelector(selector))
+ if (selectorListContainsUncommonAttributeSelector(current))
return true;
- if (selector->relation() != CSSSelector::SubSelector) {
- selector = selector->tagHistory();
+ if (current->relation() != CSSSelector::SubSelector) {
+ current = current->tagHistory();
break;
}
}
- for (; selector; selector = selector->tagHistory()) {
- if (selector->isAttributeSelector())
+ for (; current; current = current->tagHistory()) {
+ if (current->isAttributeSelector())
return true;
- if (selectorListContainsUncommonAttributeSelector(selector))
+ if (selectorListContainsUncommonAttributeSelector(current))
return true;
}
return false;
}
-static inline PropertyWhitelistType determinePropertyWhitelistType(const AddRuleFlags addRuleFlags, const CSSSelector* selector)
+static inline PropertyWhitelistType determinePropertyWhitelistType(const AddRuleFlags addRuleFlags, const CSSSelector& selector)
{
- if (addRuleFlags & RuleIsInRegionRule)
- return PropertyWhitelistRegion;
- for (const CSSSelector* component = selector; component; component = component->tagHistory()) {
- if (component->pseudoType() == CSSSelector::PseudoCue || (component->m_match == CSSSelector::PseudoElement && component->value() == TextTrackCue::cueShadowPseudoId()))
+ for (const CSSSelector* component = &selector; component; component = component->tagHistory()) {
+ if (component->pseudoType() == CSSSelector::PseudoCue || (component->match() == CSSSelector::PseudoElement && component->value() == TextTrackCue::cueShadowPseudoId()))
return PropertyWhitelistCue;
+ if (component->pseudoType() == CSSSelector::PseudoFirstLetter)
+ return PropertyWhitelistFirstLetter;
}
return PropertyWhitelistNone;
}
-namespace {
-
-// FIXME: Should we move this class to WTF?
-template<typename T>
-class TerminatedArrayBuilder {
-public:
- explicit TerminatedArrayBuilder(PassOwnPtr<T> array)
- : m_array(array)
- , m_count(0)
- , m_capacity(0)
- {
- if (!m_array)
- return;
- for (T* item = m_array.get(); !item->isLastInArray(); ++item)
- ++m_count;
- ++m_count; // To count the last item itself.
- m_capacity = m_count;
- }
-
- void grow(size_t count)
- {
- ASSERT(count);
- if (!m_array) {
- ASSERT(!m_count);
- ASSERT(!m_capacity);
- m_capacity = count;
- m_array = adoptPtr(static_cast<T*>(fastMalloc(m_capacity * sizeof(T))));
- return;
- }
- m_capacity += count;
- m_array = adoptPtr(static_cast<T*>(fastRealloc(m_array.leakPtr(), m_capacity * sizeof(T))));
- m_array.get()[m_count - 1].setLastInArray(false);
- }
-
- void append(const T& item)
- {
- RELEASE_ASSERT(m_count < m_capacity);
- ASSERT(!item.isLastInArray());
- m_array.get()[m_count++] = item;
- }
-
- PassOwnPtr<T> release()
- {
- RELEASE_ASSERT(m_count == m_capacity);
- if (m_array)
- m_array.get()[m_count - 1].setLastInArray(true);
- assertValid();
- return m_array.release();
- }
-
-private:
-#ifndef NDEBUG
- void assertValid()
- {
- for (size_t i = 0; i < m_count; ++i) {
- bool isLastInArray = (i + 1 == m_count);
- ASSERT(m_array.get()[i].isLastInArray() == isLastInArray);
- }
- }
-#else
- void assertValid() { }
-#endif
-
- OwnPtr<T> m_array;
- size_t m_count;
- size_t m_capacity;
-};
-
-}
-
RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, AddRuleFlags addRuleFlags)
: m_rule(rule)
, m_selectorIndex(selectorIndex)
, m_isLastInArray(false)
, m_position(position)
- , m_hasFastCheckableSelector((addRuleFlags & RuleCanUseFastCheckSelector) && SelectorCheckerFastPath::canUse(selector()))
- , m_specificity(selector()->specificity())
- , m_hasMultipartSelector(!!selector()->tagHistory())
+ , m_specificity(selector().specificity())
+ , m_hasMultipartSelector(!!selector().tagHistory())
, m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash(isSelectorMatchingHTMLBasedOnRuleHash(selector()))
, m_containsUncommonAttributeSelector(WebCore::containsUncommonAttributeSelector(selector()))
, m_linkMatchType(SelectorChecker::determineLinkMatchType(selector()))
@@ -207,66 +141,78 @@ RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, A
SelectorFilter::collectIdentifierHashes(selector(), m_descendantSelectorIdentifierHashes, maximumIdentifierCount);
}
-static void collectFeaturesFromRuleData(RuleFeatureSet& features, const RuleData& ruleData)
+void RuleSet::addToRuleSet(const AtomicString& key, PendingRuleMap& map, const RuleData& ruleData)
{
- bool foundSiblingSelector = false;
- unsigned maxDirectAdjacentSelectors = 0;
- for (const CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) {
- features.collectFeaturesFromSelector(selector);
-
- if (const CSSSelectorList* selectorList = selector->selectorList()) {
- for (const CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
- // FIXME: Shouldn't this be checking subSelector->isSiblingSelector()?
- if (!foundSiblingSelector && selector->isSiblingSelector())
- foundSiblingSelector = true;
- if (subSelector->isDirectAdjacentSelector())
- maxDirectAdjacentSelectors++;
- features.collectFeaturesFromSelector(subSelector);
- }
- } else {
- if (!foundSiblingSelector && selector->isSiblingSelector())
- foundSiblingSelector = true;
- if (selector->isDirectAdjacentSelector())
- maxDirectAdjacentSelectors++;
- }
- }
- features.setMaxDirectAdjacentSelectors(maxDirectAdjacentSelectors);
- if (foundSiblingSelector)
- features.siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
- if (ruleData.containsUncommonAttributeSelector())
- features.uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
+ OwnPtrWillBeMember<WillBeHeapLinkedStack<RuleData> >& rules = map.add(key, nullptr).storedValue->value;
+ if (!rules)
+ rules = adoptPtrWillBeNoop(new WillBeHeapLinkedStack<RuleData>);
+ rules->push(ruleData);
}
-void RuleSet::addToRuleSet(StringImpl* key, PendingRuleMap& map, const RuleData& ruleData)
+static void extractValuesforSelector(const CSSSelector* selector, AtomicString& id, AtomicString& className, AtomicString& customPseudoElementName, AtomicString& tagName)
{
- if (!key)
- return;
- OwnPtr<LinkedStack<RuleData> >& rules = map.add(key, nullptr).iterator->value;
- if (!rules)
- rules = adoptPtr(new LinkedStack<RuleData>);
- rules->push(ruleData);
+ switch (selector->match()) {
+ case CSSSelector::Id:
+ id = selector->value();
+ break;
+ case CSSSelector::Class:
+ className = selector->value();
+ break;
+ case CSSSelector::Tag:
+ if (selector->tagQName().localName() != starAtom)
+ tagName = selector->tagQName().localName();
+ break;
+ default:
+ break;
+ }
+ if (selector->isCustomPseudoElement())
+ customPseudoElementName = selector->value();
}
-bool RuleSet::findBestRuleSetAndAdd(const CSSSelector* component, RuleData& ruleData)
+bool RuleSet::findBestRuleSetAndAdd(const CSSSelector& component, RuleData& ruleData)
{
- if (component->m_match == CSSSelector::Id) {
- addToRuleSet(component->value().impl(), ensurePendingRules()->idRules, ruleData);
+ AtomicString id;
+ AtomicString className;
+ AtomicString customPseudoElementName;
+ AtomicString tagName;
+
+#ifndef NDEBUG
+ m_allRules.append(ruleData);
+#endif
+
+ const CSSSelector* it = &component;
+ for (; it && it->relation() == CSSSelector::SubSelector; it = it->tagHistory()) {
+ extractValuesforSelector(it, id, className, customPseudoElementName, tagName);
+ }
+ // FIXME: this null check should not be necessary. See crbug.com/358475
+ if (it)
+ extractValuesforSelector(it, id, className, customPseudoElementName, tagName);
+
+ // Prefer rule sets in order of most likely to apply infrequently.
+ if (!id.isEmpty()) {
+ addToRuleSet(id, ensurePendingRules()->idRules, ruleData);
return true;
}
- if (component->m_match == CSSSelector::Class) {
- addToRuleSet(component->value().impl(), ensurePendingRules()->classRules, ruleData);
+ if (!className.isEmpty()) {
+ addToRuleSet(className, ensurePendingRules()->classRules, ruleData);
return true;
}
- if (component->isCustomPseudoElement()) {
- addToRuleSet(component->value().impl(), ensurePendingRules()->shadowPseudoElementRules, ruleData);
+ if (!customPseudoElementName.isEmpty()) {
+ // Custom pseudos come before ids and classes in the order of tagHistory, and have a relation of
+ // ShadowPseudo between them. Therefore we should never be a situation where extractValuesforSelector
+ // finsd id and className in addition to custom pseudo.
+ ASSERT(id.isEmpty() && className.isEmpty());
+ addToRuleSet(customPseudoElementName, ensurePendingRules()->shadowPseudoElementRules, ruleData);
return true;
}
- if (component->pseudoType() == CSSSelector::PseudoCue) {
+
+ if (component.pseudoType() == CSSSelector::PseudoCue) {
m_cuePseudoRules.append(ruleData);
return true;
}
+
if (SelectorChecker::isCommonPseudoClassSelector(component)) {
- switch (component->pseudoType()) {
+ switch (component.pseudoType()) {
case CSSSelector::PseudoLink:
case CSSSelector::PseudoVisited:
case CSSSelector::PseudoAnyLink:
@@ -281,25 +227,18 @@ bool RuleSet::findBestRuleSetAndAdd(const CSSSelector* component, RuleData& rule
}
}
- if (component->m_match == CSSSelector::Tag) {
- if (component->tagQName().localName() != starAtom) {
- // If this is part of a subselector chain, recurse ahead to find a narrower set (ID/class.)
- if (component->relation() == CSSSelector::SubSelector
- && (component->tagHistory()->m_match == CSSSelector::Class || component->tagHistory()->m_match == CSSSelector::Id || SelectorChecker::isCommonPseudoClassSelector(component->tagHistory()))
- && findBestRuleSetAndAdd(component->tagHistory(), ruleData))
- return true;
-
- addToRuleSet(component->tagQName().localName().impl(), ensurePendingRules()->tagRules, ruleData);
- return true;
- }
+ if (!tagName.isEmpty()) {
+ addToRuleSet(tagName, ensurePendingRules()->tagRules, ruleData);
+ return true;
}
+
return false;
}
void RuleSet::addRule(StyleRule* rule, unsigned selectorIndex, AddRuleFlags addRuleFlags)
{
RuleData ruleData(rule, selectorIndex, m_ruleCount++, addRuleFlags);
- collectFeaturesFromRuleData(m_features, ruleData);
+ m_features.collectFeaturesFromRuleData(ruleData);
if (!findBestRuleSetAndAdd(ruleData.selector(), ruleData)) {
// If we didn't find a specialized map to stick it in, file under universal rules.
@@ -331,32 +270,7 @@ void RuleSet::addKeyframesRule(StyleRuleKeyframes* rule)
m_keyframesRules.append(rule);
}
-void RuleSet::addRegionRule(StyleRuleRegion* regionRule, bool hasDocumentSecurityOrigin)
-{
- ensurePendingRules(); // So that m_regionSelectorsAndRuleSets.shrinkToFit() gets called.
- OwnPtr<RuleSet> regionRuleSet = RuleSet::create();
- // The region rule set should take into account the position inside the parent rule set.
- // Otherwise, the rules inside region block might be incorrectly positioned before other similar rules from
- // the stylesheet that contains the region block.
- regionRuleSet->m_ruleCount = m_ruleCount;
-
- // Collect the region rules into a rule set
- // FIXME: Should this add other types of rules? (i.e. use addChildRules() directly?)
- const Vector<RefPtr<StyleRuleBase> >& childRules = regionRule->childRules();
- AddRuleFlags addRuleFlags = hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState;
- addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleIsInRegionRule | RuleCanUseFastCheckSelector);
- for (unsigned i = 0; i < childRules.size(); ++i) {
- StyleRuleBase* regionStylingRule = childRules[i].get();
- if (regionStylingRule->isStyleRule())
- regionRuleSet->addStyleRule(toStyleRule(regionStylingRule), addRuleFlags);
- }
- // Update the "global" rule count so that proper order is maintained
- m_ruleCount = regionRuleSet->m_ruleCount;
-
- m_regionSelectorsAndRuleSets.append(RuleSetSelectorPair(regionRule->selectorList().first(), regionRuleSet.release()));
-}
-
-void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase> >& rules, const MediaQueryEvaluator& medium, AddRuleFlags addRuleFlags)
+void RuleSet::addChildRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules, const MediaQueryEvaluator& medium, AddRuleFlags addRuleFlags)
{
for (unsigned i = 0; i < rules.size(); ++i) {
StyleRuleBase* rule = rules[i].get();
@@ -366,7 +280,7 @@ void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase> >& rules, const M
const CSSSelectorList& selectorList = styleRule->selectorList();
for (size_t selectorIndex = 0; selectorIndex != kNotFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) {
- if (selectorList.hasCombinatorCrossingTreeBoundaryAt(selectorIndex)) {
+ if (selectorList.selectorCrossesTreeScopes(selectorIndex)) {
m_treeBoundaryCrossingRules.append(MinimalRuleData(styleRule, selectorIndex, addRuleFlags));
} else if (selectorList.hasShadowDistributedAt(selectorIndex)) {
m_shadowDistributedRules.append(MinimalRuleData(styleRule, selectorIndex, addRuleFlags));
@@ -384,8 +298,6 @@ void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase> >& rules, const M
addFontFaceRule(toStyleRuleFontFace(rule));
} else if (rule->isKeyframesRule()) {
addKeyframesRule(toStyleRuleKeyframes(rule));
- } else if (rule->isRegionRule()) {
- addRegionRule(toStyleRuleRegion(rule), addRuleFlags & RuleHasDocumentSecurityOrigin);
} else if (rule->isViewportRule()) {
addViewportRule(toStyleRuleViewport(rule));
} else if (rule->isSupportsRule() && toStyleRuleSupports(rule)->conditionIsSupported()) {
@@ -396,10 +308,12 @@ void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase> >& rules, const M
void RuleSet::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvaluator& medium, AddRuleFlags addRuleFlags)
{
+ TRACE_EVENT0("webkit", "RuleSet::addRulesFromSheet");
+
ASSERT(sheet);
addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleCanUseFastCheckSelector);
- const Vector<RefPtr<StyleRuleImport> >& importRules = sheet->importRules();
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> >& importRules = sheet->importRules();
for (unsigned i = 0; i < importRules.size(); ++i) {
StyleRuleImport* importRule = importRules[i].get();
if (importRule->styleSheet() && (!importRule->mediaQueries() || medium.eval(importRule->mediaQueries(), &m_viewportDependentMediaQueryResults)))
@@ -419,10 +333,10 @@ void RuleSet::compactPendingRules(PendingRuleMap& pendingMap, CompactRuleMap& co
{
PendingRuleMap::iterator end = pendingMap.end();
for (PendingRuleMap::iterator it = pendingMap.begin(); it != end; ++it) {
- OwnPtr<LinkedStack<RuleData> > pendingRules = it->value.release();
- CompactRuleMap::iterator compactRules = compactMap.add(it->key, nullptr).iterator;
+ OwnPtrWillBeRawPtr<WillBeHeapLinkedStack<RuleData> > pendingRules = it->value.release();
+ CompactRuleMap::ValueType* compactRules = compactMap.add(it->key, nullptr).storedValue;
- TerminatedArrayBuilder<RuleData> builder(compactRules->value.release());
+ WillBeHeapTerminatedArrayBuilder<RuleData> builder(compactRules->value.release());
builder.grow(pendingRules->size());
while (!pendingRules->isEmpty()) {
builder.append(pendingRules->peek());
@@ -436,7 +350,7 @@ void RuleSet::compactPendingRules(PendingRuleMap& pendingMap, CompactRuleMap& co
void RuleSet::compactRules()
{
ASSERT(m_pendingRules);
- OwnPtr<PendingRuleMaps> pendingRules = m_pendingRules.release();
+ OwnPtrWillBeRawPtr<PendingRuleMaps> pendingRules = m_pendingRules.release();
compactPendingRules(pendingRules->idRules, m_idRules);
compactPendingRules(pendingRules->classRules, m_classRules);
compactPendingRules(pendingRules->tagRules, m_tagRules);
@@ -453,4 +367,56 @@ void RuleSet::compactRules()
m_shadowDistributedRules.shrinkToFit();
}
+void MinimalRuleData::trace(Visitor* visitor)
+{
+ visitor->trace(m_rule);
+}
+
+void RuleData::trace(Visitor* visitor)
+{
+ visitor->trace(m_rule);
+}
+
+void RuleSet::PendingRuleMaps::trace(Visitor* visitor)
+{
+ visitor->trace(idRules);
+ visitor->trace(classRules);
+ visitor->trace(tagRules);
+ visitor->trace(shadowPseudoElementRules);
+}
+
+void RuleSet::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_idRules);
+ visitor->trace(m_classRules);
+ visitor->trace(m_tagRules);
+ visitor->trace(m_shadowPseudoElementRules);
+ visitor->trace(m_linkPseudoClassRules);
+ visitor->trace(m_cuePseudoRules);
+ visitor->trace(m_focusPseudoClassRules);
+ visitor->trace(m_universalRules);
+ visitor->trace(m_features);
+ visitor->trace(m_pageRules);
+ visitor->trace(m_viewportRules);
+ visitor->trace(m_fontFaceRules);
+ visitor->trace(m_keyframesRules);
+ visitor->trace(m_treeBoundaryCrossingRules);
+ visitor->trace(m_shadowDistributedRules);
+ visitor->trace(m_viewportDependentMediaQueryResults);
+ visitor->trace(m_pendingRules);
+#ifndef NDEBUG
+ visitor->trace(m_allRules);
+#endif
+#endif
+}
+
+#ifndef NDEBUG
+void RuleSet::show()
+{
+ for (WillBeHeapVector<RuleData>::const_iterator it = m_allRules.begin(); it != m_allRules.end(); ++it)
+ it->selector().show();
+}
+#endif
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/RuleSet.h b/chromium/third_party/WebKit/Source/core/css/RuleSet.h
index d8249a3edb9..e7538f58100 100644
--- a/chromium/third_party/WebKit/Source/core/css/RuleSet.h
+++ b/chromium/third_party/WebKit/Source/core/css/RuleSet.h
@@ -27,9 +27,12 @@
#include "core/css/RuleFeature.h"
#include "core/css/StyleRule.h"
#include "core/css/resolver/MediaQueryResult.h"
+#include "platform/heap/HeapLinkedStack.h"
+#include "platform/heap/HeapTerminatedArray.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/LinkedStack.h"
+#include "wtf/TerminatedArray.h"
namespace WebCore {
@@ -37,21 +40,21 @@ enum AddRuleFlags {
RuleHasNoSpecialState = 0,
RuleHasDocumentSecurityOrigin = 1,
RuleCanUseFastCheckSelector = 1 << 1,
- RuleIsInRegionRule = 1 << 2,
};
enum PropertyWhitelistType {
PropertyWhitelistNone = 0,
- PropertyWhitelistRegion,
- PropertyWhitelistCue
+ PropertyWhitelistCue,
+ PropertyWhitelistFirstLetter,
};
class CSSSelector;
class MediaQueryEvaluator;
-class StyleRuleRegion;
class StyleSheetContents;
-struct MinimalRuleData {
+class MinimalRuleData {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
MinimalRuleData(StyleRule* rule, unsigned selectorIndex, AddRuleFlags flags)
: m_rule(rule)
, m_selectorIndex(selectorIndex)
@@ -59,25 +62,26 @@ struct MinimalRuleData {
{
}
- StyleRule* m_rule;
+ void trace(Visitor*);
+
+ RawPtrWillBeMember<StyleRule> m_rule;
unsigned m_selectorIndex;
AddRuleFlags m_flags;
};
class RuleData {
- WTF_MAKE_FAST_ALLOCATED;
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
RuleData(StyleRule*, unsigned selectorIndex, unsigned position, AddRuleFlags);
unsigned position() const { return m_position; }
StyleRule* rule() const { return m_rule; }
- const CSSSelector* selector() const { return m_rule->selectorList().selectorAt(m_selectorIndex); }
+ const CSSSelector& selector() const { return m_rule->selectorList().selectorAt(m_selectorIndex); }
unsigned selectorIndex() const { return m_selectorIndex; }
bool isLastInArray() const { return m_isLastInArray; }
void setLastInArray(bool flag) { m_isLastInArray = flag; }
- bool hasFastCheckableSelector() const { return m_hasFastCheckableSelector; }
bool hasMultipartSelector() const { return m_hasMultipartSelector; }
bool hasRightmostSelectorMatchingHTMLBasedOnRuleHash() const { return m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash; }
bool containsUncommonAttributeSelector() const { return m_containsUncommonAttributeSelector; }
@@ -89,14 +93,15 @@ public:
static const unsigned maximumIdentifierCount = 4;
const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
+ void trace(Visitor*);
+
private:
- StyleRule* m_rule;
+ RawPtrWillBeMember<StyleRule> m_rule;
unsigned m_selectorIndex : 12;
unsigned m_isLastInArray : 1; // We store an array of RuleData objects in a primitive array.
// This number was picked fairly arbitrarily. We can probably lower it if we need to.
// Some simple testing showed <100,000 RuleData's on large sites.
unsigned m_position : 18;
- unsigned m_hasFastCheckableSelector : 1;
unsigned m_specificity : 24;
unsigned m_hasMultipartSelector : 1;
unsigned m_hasRightmostSelectorMatchingHTMLBasedOnRuleHash : 1;
@@ -117,10 +122,11 @@ struct SameSizeAsRuleData {
COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small);
-class RuleSet {
- WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED;
+class RuleSet : public NoBaseWillBeGarbageCollectedFinalized<RuleSet> {
+ WTF_MAKE_NONCOPYABLE(RuleSet);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<RuleSet> create() { return adoptPtr(new RuleSet); }
+ static PassOwnPtrWillBeRawPtr<RuleSet> create() { return adoptPtrWillBeNoop(new RuleSet); }
void addRulesFromSheet(StyleSheetContents*, const MediaQueryEvaluator&, AddRuleFlags = RuleHasNoSpecialState);
void addStyleRule(StyleRule*, AddRuleFlags);
@@ -128,20 +134,20 @@ public:
const RuleFeatureSet& features() const { return m_features; }
- const RuleData* idRules(StringImpl* key) const { ASSERT(!m_pendingRules); return m_idRules.get(key); }
- const RuleData* classRules(StringImpl* key) const { ASSERT(!m_pendingRules); return m_classRules.get(key); }
- const RuleData* tagRules(StringImpl* key) const { ASSERT(!m_pendingRules); return m_tagRules.get(key); }
- const RuleData* shadowPseudoElementRules(StringImpl* key) const { ASSERT(!m_pendingRules); return m_shadowPseudoElementRules.get(key); }
- const Vector<RuleData>* linkPseudoClassRules() const { ASSERT(!m_pendingRules); return &m_linkPseudoClassRules; }
- const Vector<RuleData>* cuePseudoRules() const { ASSERT(!m_pendingRules); return &m_cuePseudoRules; }
- const Vector<RuleData>* focusPseudoClassRules() const { ASSERT(!m_pendingRules); return &m_focusPseudoClassRules; }
- const Vector<RuleData>* universalRules() const { ASSERT(!m_pendingRules); return &m_universalRules; }
- const Vector<StyleRulePage*>& pageRules() const { ASSERT(!m_pendingRules); return m_pageRules; }
- const Vector<StyleRuleViewport*>& viewportRules() const { ASSERT(!m_pendingRules); return m_viewportRules; }
- const Vector<StyleRuleFontFace*>& fontFaceRules() const { return m_fontFaceRules; }
- const Vector<StyleRuleKeyframes*>& keyframesRules() const { return m_keyframesRules; }
- const Vector<MinimalRuleData>& treeBoundaryCrossingRules() const { return m_treeBoundaryCrossingRules; }
- const Vector<MinimalRuleData>& shadowDistributedRules() const { return m_shadowDistributedRules; }
+ const WillBeHeapTerminatedArray<RuleData>* idRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_idRules.get(key); }
+ const WillBeHeapTerminatedArray<RuleData>* classRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_classRules.get(key); }
+ const WillBeHeapTerminatedArray<RuleData>* tagRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_tagRules.get(key); }
+ const WillBeHeapTerminatedArray<RuleData>* shadowPseudoElementRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_shadowPseudoElementRules.get(key); }
+ const WillBeHeapVector<RuleData>* linkPseudoClassRules() const { ASSERT(!m_pendingRules); return &m_linkPseudoClassRules; }
+ const WillBeHeapVector<RuleData>* cuePseudoRules() const { ASSERT(!m_pendingRules); return &m_cuePseudoRules; }
+ const WillBeHeapVector<RuleData>* focusPseudoClassRules() const { ASSERT(!m_pendingRules); return &m_focusPseudoClassRules; }
+ const WillBeHeapVector<RuleData>* universalRules() const { ASSERT(!m_pendingRules); return &m_universalRules; }
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& pageRules() const { ASSERT(!m_pendingRules); return m_pageRules; }
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleViewport> >& viewportRules() const { ASSERT(!m_pendingRules); return m_viewportRules; }
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> >& fontFaceRules() const { return m_fontFaceRules; }
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> >& keyframesRules() const { return m_keyframesRules; }
+ const WillBeHeapVector<MinimalRuleData>& treeBoundaryCrossingRules() const { return m_treeBoundaryCrossingRules; }
+ const WillBeHeapVector<MinimalRuleData>& shadowDistributedRules() const { return m_shadowDistributedRules; }
const MediaQueryResultList& viewportDependentMediaQueryResults() const { return m_viewportDependentMediaQueryResults; }
unsigned ruleCount() const { return m_ruleCount; }
@@ -153,49 +159,52 @@ public:
compactRules();
}
- struct RuleSetSelectorPair {
- RuleSetSelectorPair(const CSSSelector* selector, PassOwnPtr<RuleSet> ruleSet) : selector(selector), ruleSet(ruleSet) { }
- RuleSetSelectorPair(const RuleSetSelectorPair& rs) : selector(rs.selector), ruleSet(const_cast<RuleSetSelectorPair*>(&rs)->ruleSet.release()) { }
-
- const CSSSelector* selector;
- OwnPtr<RuleSet> ruleSet;
- };
+#ifndef NDEBUG
+ void show();
+#endif
- Vector<RuleSetSelectorPair> m_regionSelectorsAndRuleSets;
+ void trace(Visitor*);
private:
- typedef HashMap<StringImpl*, OwnPtr<LinkedStack<RuleData> > > PendingRuleMap;
- typedef HashMap<StringImpl*, OwnPtr<RuleData> > CompactRuleMap;
+ typedef WillBeHeapHashMap<AtomicString, OwnPtrWillBeMember<WillBeHeapLinkedStack<RuleData> > > PendingRuleMap;
+ typedef WillBeHeapHashMap<AtomicString, OwnPtrWillBeMember<WillBeHeapTerminatedArray<RuleData> > > CompactRuleMap;
RuleSet()
: m_ruleCount(0)
{
}
- void addToRuleSet(StringImpl* key, PendingRuleMap&, const RuleData&);
+ void addToRuleSet(const AtomicString& key, PendingRuleMap&, const RuleData&);
void addPageRule(StyleRulePage*);
void addViewportRule(StyleRuleViewport*);
void addFontFaceRule(StyleRuleFontFace*);
void addKeyframesRule(StyleRuleKeyframes*);
- void addRegionRule(StyleRuleRegion*, bool hasDocumentSecurityOrigin);
- void addChildRules(const Vector<RefPtr<StyleRuleBase> >&, const MediaQueryEvaluator& medium, AddRuleFlags);
- bool findBestRuleSetAndAdd(const CSSSelector*, RuleData&);
+ void addChildRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >&, const MediaQueryEvaluator& medium, AddRuleFlags);
+ bool findBestRuleSetAndAdd(const CSSSelector&, RuleData&);
void compactRules();
static void compactPendingRules(PendingRuleMap&, CompactRuleMap&);
- struct PendingRuleMaps {
+ class PendingRuleMaps : public NoBaseWillBeGarbageCollected<PendingRuleMaps> {
+ public:
+ static PassOwnPtrWillBeRawPtr<PendingRuleMaps> create() { return adoptPtrWillBeNoop(new PendingRuleMaps); }
+
PendingRuleMap idRules;
PendingRuleMap classRules;
PendingRuleMap tagRules;
PendingRuleMap shadowPseudoElementRules;
+
+ void trace(Visitor*);
+
+ private:
+ PendingRuleMaps() { }
};
PendingRuleMaps* ensurePendingRules()
{
if (!m_pendingRules)
- m_pendingRules = adoptPtr(new PendingRuleMaps);
+ m_pendingRules = PendingRuleMaps::create();
return m_pendingRules.get();
}
@@ -203,24 +212,31 @@ private:
CompactRuleMap m_classRules;
CompactRuleMap m_tagRules;
CompactRuleMap m_shadowPseudoElementRules;
- Vector<RuleData> m_linkPseudoClassRules;
- Vector<RuleData> m_cuePseudoRules;
- Vector<RuleData> m_focusPseudoClassRules;
- Vector<RuleData> m_universalRules;
+ WillBeHeapVector<RuleData> m_linkPseudoClassRules;
+ WillBeHeapVector<RuleData> m_cuePseudoRules;
+ WillBeHeapVector<RuleData> m_focusPseudoClassRules;
+ WillBeHeapVector<RuleData> m_universalRules;
RuleFeatureSet m_features;
- Vector<StyleRulePage*> m_pageRules;
- Vector<StyleRuleViewport*> m_viewportRules;
- Vector<StyleRuleFontFace*> m_fontFaceRules;
- Vector<StyleRuleKeyframes*> m_keyframesRules;
- Vector<MinimalRuleData> m_treeBoundaryCrossingRules;
- Vector<MinimalRuleData> m_shadowDistributedRules;
+ WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> > m_pageRules;
+ WillBeHeapVector<RawPtrWillBeMember<StyleRuleViewport> > m_viewportRules;
+ WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> > m_fontFaceRules;
+ WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> > m_keyframesRules;
+ WillBeHeapVector<MinimalRuleData> m_treeBoundaryCrossingRules;
+ WillBeHeapVector<MinimalRuleData> m_shadowDistributedRules;
MediaQueryResultList m_viewportDependentMediaQueryResults;
unsigned m_ruleCount;
- OwnPtr<PendingRuleMaps> m_pendingRules;
+ OwnPtrWillBeMember<PendingRuleMaps> m_pendingRules;
+
+#ifndef NDEBUG
+ WillBeHeapVector<RuleData> m_allRules;
+#endif
};
} // namespace WebCore
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::RuleData);
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::MinimalRuleData);
+
#endif // RuleSet_h
diff --git a/chromium/third_party/WebKit/Source/core/css/RuleSetTest.cpp b/chromium/third_party/WebKit/Source/core/css/RuleSetTest.cpp
new file mode 100644
index 00000000000..8fd5ec63bba
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/RuleSetTest.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/css/CSSTestHelper.h"
+#include "core/css/RuleSet.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+TEST(RuleSetTest, findBestRuleSetAndAdd_CustomPseudoElements)
+{
+ CSSTestHelper helper;
+
+ helper.addCSSRules("summary::-webkit-details-marker { }");
+ RuleSet& ruleSet = helper.ruleSet();
+ AtomicString str("-webkit-details-marker");
+ const TerminatedArray<RuleData>* rules = ruleSet.shadowPseudoElementRules(str);
+ ASSERT_EQ(1u, rules->size());
+ ASSERT_EQ(str, rules->at(0).selector().value());
+}
+
+TEST(RuleSetTest, findBestRuleSetAndAdd_Id)
+{
+ CSSTestHelper helper;
+
+ helper.addCSSRules("#id { }");
+ RuleSet& ruleSet = helper.ruleSet();
+ AtomicString str("id");
+ const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+ ASSERT_EQ(1u, rules->size());
+ ASSERT_EQ(str, rules->at(0).selector().value());
+}
+
+TEST(RuleSetTest, findBestRuleSetAndAdd_NthChild)
+{
+ CSSTestHelper helper;
+
+ helper.addCSSRules("div:nth-child(2) { }");
+ RuleSet& ruleSet = helper.ruleSet();
+ AtomicString str("div");
+ const TerminatedArray<RuleData>* rules = ruleSet.tagRules(str);
+ ASSERT_EQ(1u, rules->size());
+ ASSERT_EQ(str, rules->at(0).selector().tagQName().localName());
+}
+
+TEST(RuleSetTest, findBestRuleSetAndAdd_ClassThenId)
+{
+ CSSTestHelper helper;
+
+ helper.addCSSRules(".class#id { }");
+ RuleSet& ruleSet = helper.ruleSet();
+ AtomicString str("id");
+ // id is prefered over class even if class preceeds it in the selector.
+ const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+ ASSERT_EQ(1u, rules->size());
+ AtomicString classStr("class");
+ ASSERT_EQ(classStr, rules->at(0).selector().value());
+}
+
+TEST(RuleSetTest, findBestRuleSetAndAdd_IdThenClass)
+{
+ CSSTestHelper helper;
+
+ helper.addCSSRules("#id.class { }");
+ RuleSet& ruleSet = helper.ruleSet();
+ AtomicString str("id");
+ const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+ ASSERT_EQ(1u, rules->size());
+ ASSERT_EQ(str, rules->at(0).selector().value());
+}
+
+TEST(RuleSetTest, findBestRuleSetAndAdd_AttrThenId)
+{
+ CSSTestHelper helper;
+
+ helper.addCSSRules("[attr]#id { }");
+ RuleSet& ruleSet = helper.ruleSet();
+ AtomicString str("id");
+ const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+ ASSERT_EQ(1u, rules->size());
+ AtomicString attrStr("attr");
+ ASSERT_EQ(attrStr, rules->at(0).selector().attribute().localName());
+}
+
+TEST(RuleSetTest, findBestRuleSetAndAdd_TagThenAttrThenId)
+{
+ CSSTestHelper helper;
+
+ helper.addCSSRules("div[attr]#id { }");
+ RuleSet& ruleSet = helper.ruleSet();
+ AtomicString str("id");
+ const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+ ASSERT_EQ(1u, rules->size());
+ AtomicString tagStr("div");
+ ASSERT_EQ(tagStr, rules->at(0).selector().tagQName().localName());
+}
+
+TEST(RuleSetTest, findBestRuleSetAndAdd_DivWithContent)
+{
+ CSSTestHelper helper;
+
+ helper.addCSSRules("div::content { }");
+ RuleSet& ruleSet = helper.ruleSet();
+ AtomicString str("div");
+ const TerminatedArray<RuleData>* rules = ruleSet.tagRules(str);
+ ASSERT_EQ(1u, rules->size());
+ AtomicString valueStr("content");
+ ASSERT_EQ(valueStr, rules->at(0).selector().value());
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp b/chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp
index 7e0d728e2b8..dd9796bfc9d 100644
--- a/chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp
@@ -30,12 +30,12 @@
#include "config.h"
#include "core/css/RuntimeCSSEnabled.h"
-#include "RuntimeEnabledFeatures.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "wtf/BitArray.h"
namespace WebCore {
-// FIXME: We should use a real BitVector class instead!
-typedef Vector<bool> BoolVector;
+typedef BitArray<numCSSProperties> CSSPropertySwitches;
static void setCSSPropertiesEnabled(CSSPropertyID* properties, size_t length, bool featureFlag)
{
@@ -45,15 +45,6 @@ static void setCSSPropertiesEnabled(CSSPropertyID* properties, size_t length, bo
static void setPropertySwitchesFromRuntimeFeatures()
{
- CSSPropertyID regionProperites[] = {
- CSSPropertyWebkitFlowInto,
- CSSPropertyWebkitFlowFrom,
- CSSPropertyWebkitRegionFragment,
- CSSPropertyWebkitRegionBreakAfter,
- CSSPropertyWebkitRegionBreakBefore,
- CSSPropertyWebkitRegionBreakInside
- };
- setCSSPropertiesEnabled(regionProperites, WTF_ARRAY_LENGTH(regionProperites), RuntimeEnabledFeatures::cssRegionsEnabled());
CSSPropertyID exclusionProperties[] = {
CSSPropertyWebkitWrapFlow,
CSSPropertyWebkitWrapThrough,
@@ -61,9 +52,7 @@ static void setPropertySwitchesFromRuntimeFeatures()
setCSSPropertiesEnabled(exclusionProperties, WTF_ARRAY_LENGTH(exclusionProperties), RuntimeEnabledFeatures::cssExclusionsEnabled());
CSSPropertyID shapeProperties[] = {
CSSPropertyShapeMargin,
- CSSPropertyShapePadding,
CSSPropertyShapeImageThreshold,
- CSSPropertyShapeInside,
CSSPropertyShapeOutside,
};
setCSSPropertiesEnabled(shapeProperties, WTF_ARRAY_LENGTH(shapeProperties), RuntimeEnabledFeatures::cssShapesEnabled());
@@ -82,8 +71,8 @@ static void setPropertySwitchesFromRuntimeFeatures()
CSSPropertyID cssGridLayoutProperties[] = {
CSSPropertyGridAutoColumns,
CSSPropertyGridAutoRows,
- CSSPropertyGridDefinitionColumns,
- CSSPropertyGridDefinitionRows,
+ CSSPropertyGridTemplateColumns,
+ CSSPropertyGridTemplateRows,
CSSPropertyGridColumnStart,
CSSPropertyGridColumnEnd,
CSSPropertyGridRowStart,
@@ -92,7 +81,10 @@ static void setPropertySwitchesFromRuntimeFeatures()
CSSPropertyGridRow,
CSSPropertyGridArea,
CSSPropertyGridAutoFlow,
- CSSPropertyGridTemplate
+ CSSPropertyGridTemplateAreas,
+ CSSPropertyGridTemplate,
+ CSSPropertyGrid,
+ CSSPropertyJustifySelf
};
setCSSPropertiesEnabled(cssGridLayoutProperties, WTF_ARRAY_LENGTH(cssGridLayoutProperties), RuntimeEnabledFeatures::cssGridLayoutEnabled());
CSSPropertyID cssObjectFitPositionProperties[] = {
@@ -114,26 +106,34 @@ static void setPropertySwitchesFromRuntimeFeatures()
};
setCSSPropertiesEnabled(animationProperties, WTF_ARRAY_LENGTH(animationProperties), RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
- RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyBackgroundBlendMode, RuntimeEnabledFeatures::cssCompositingEnabled());
+ CSSPropertyID transformProperties[] = {
+ CSSPropertyBackfaceVisibility,
+ CSSPropertyPerspective,
+ CSSPropertyPerspectiveOrigin,
+ CSSPropertyTransform,
+ CSSPropertyTransformOrigin,
+ CSSPropertyTransformStyle
+ };
+ setCSSPropertiesEnabled(transformProperties, WTF_ARRAY_LENGTH(transformProperties), RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
+
RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyMixBlendMode, RuntimeEnabledFeatures::cssCompositingEnabled());
RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyIsolation, RuntimeEnabledFeatures::cssCompositingEnabled());
RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyTouchAction, RuntimeEnabledFeatures::cssTouchActionEnabled());
- RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyPaintOrder, RuntimeEnabledFeatures::svgPaintOrderEnabled());
- RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyVariable, RuntimeEnabledFeatures::cssVariablesEnabled());
+ RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyTouchActionDelay, RuntimeEnabledFeatures::cssTouchActionDelayEnabled());
RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyMaskSourceType, RuntimeEnabledFeatures::cssMaskSourceTypeEnabled());
RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyColumnFill, RuntimeEnabledFeatures::regionBasedColumnsEnabled());
+ RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyScrollBehavior, RuntimeEnabledFeatures::cssomSmoothScrollEnabled());
+ RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyWillChange, RuntimeEnabledFeatures::cssWillChangeEnabled());
// InternalCallback is an implementation detail, rather than an experimental feature, and should never be exposed to the web.
RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyInternalCallback, false);
}
-static BoolVector& propertySwitches()
+static CSSPropertySwitches& propertySwitches()
{
- static BoolVector* switches = 0;
+ static CSSPropertySwitches* switches = 0;
if (!switches) {
- switches = new BoolVector;
- // Accomodate CSSPropertyIDs that fall outside the firstCSSProperty, lastCSSProperty range (eg. CSSPropertyVariable).
- switches->fill(true, lastCSSProperty + 1);
+ switches = new CSSPropertySwitches(true); // All bits sets to 1.
setPropertySwitchesFromRuntimeFeatures();
}
return *switches;
@@ -141,9 +141,9 @@ static BoolVector& propertySwitches()
size_t indexForProperty(CSSPropertyID propertyId)
{
- RELEASE_ASSERT(propertyId >= 0 && propertyId <= lastCSSProperty);
- ASSERT(propertyId != CSSPropertyInvalid);
- return static_cast<size_t>(propertyId);
+ RELEASE_ASSERT(propertyId >= firstCSSProperty && propertyId <= lastCSSProperty);
+ // Values all start at 0. BitArray ASSERTS will catch if we're ever wrong.
+ return static_cast<size_t>(propertyId - firstCSSProperty);
}
bool RuntimeCSSEnabled::isCSSPropertyEnabled(CSSPropertyID propertyId)
@@ -153,12 +153,16 @@ bool RuntimeCSSEnabled::isCSSPropertyEnabled(CSSPropertyID propertyId)
if (isInternalProperty(propertyId))
return false;
- return propertySwitches()[indexForProperty(propertyId)];
+ return propertySwitches().get(indexForProperty(propertyId));
}
void RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyID propertyId, bool enable)
{
- propertySwitches()[indexForProperty(propertyId)] = enable;
+ size_t propertyIndex = indexForProperty(propertyId);
+ if (enable)
+ propertySwitches().set(propertyIndex);
+ else
+ propertySwitches().clear(propertyIndex);
}
void RuntimeCSSEnabled::filterEnabledCSSPropertiesIntoVector(const CSSPropertyID* properties, size_t propertyCount, Vector<CSSPropertyID>& outVector)
diff --git a/chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.h b/chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.h
index 493d3a52356..bb7900f1c21 100644
--- a/chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.h
+++ b/chromium/third_party/WebKit/Source/core/css/RuntimeCSSEnabled.h
@@ -30,7 +30,7 @@
#ifndef RuntimeCSSEnabled_h
#define RuntimeCSSEnabled_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "wtf/Vector.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp b/chromium/third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp
index c972f873786..584b67705a6 100644
--- a/chromium/third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp
@@ -22,7 +22,7 @@
#include "core/css/CSSComputedStyleDeclaration.h"
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/dom/Document.h"
#include "core/rendering/style/RenderStyle.h"
@@ -30,7 +30,7 @@
namespace WebCore {
-static PassRefPtr<CSSPrimitiveValue> glyphOrientationToCSSPrimitiveValue(EGlyphOrientation orientation)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> glyphOrientationToCSSPrimitiveValue(EGlyphOrientation orientation)
{
switch (orientation) {
case GO_0DEG:
@@ -42,26 +42,29 @@ static PassRefPtr<CSSPrimitiveValue> glyphOrientationToCSSPrimitiveValue(EGlyphO
case GO_270DEG:
return CSSPrimitiveValue::create(270.0f, CSSPrimitiveValue::CSS_DEG);
default:
- return 0;
+ return nullptr;
}
}
-static PassRefPtr<CSSValue> strokeDashArrayToCSSValueList(const Vector<SVGLength>& dashes)
+static PassRefPtrWillBeRawPtr<CSSValue> strokeDashArrayToCSSValueList(PassRefPtr<SVGLengthList> passDashes)
{
- if (dashes.isEmpty())
+ RefPtr<SVGLengthList> dashes = passDashes;
+
+ if (dashes->isEmpty())
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- const Vector<SVGLength>::const_iterator end = dashes.end();
- for (Vector<SVGLength>::const_iterator it = dashes.begin(); it != end; ++it)
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ SVGLengthList::ConstIterator it = dashes->begin();
+ SVGLengthList::ConstIterator itEnd = dashes->end();
+ for (; it != itEnd; ++it)
list->append(SVGLength::toCSSPrimitiveValue(*it));
return list.release();
}
-static PassRefPtr<CSSValue> paintOrderToCSSValueList(EPaintOrder paintorder)
+static PassRefPtrWillBeRawPtr<CSSValue> paintOrderToCSSValueList(EPaintOrder paintorder)
{
- RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
do {
EPaintOrderType paintOrderType = (EPaintOrderType)(paintorder & ((1 << kPaintOrderBitwidth) - 1));
switch (paintOrderType) {
@@ -80,19 +83,24 @@ static PassRefPtr<CSSValue> paintOrderToCSSValueList(EPaintOrder paintorder)
return list.release();
}
-PassRefPtr<SVGPaint> CSSComputedStyleDeclaration::adjustSVGPaintForCurrentColor(PassRefPtr<SVGPaint> newPaint, RenderStyle& style) const
+PassRefPtrWillBeRawPtr<SVGPaint> CSSComputedStyleDeclaration::adjustSVGPaintForCurrentColor(PassRefPtrWillBeRawPtr<SVGPaint> newPaint, RenderStyle& style) const
{
- RefPtr<SVGPaint> paint = newPaint;
+ RefPtrWillBeRawPtr<SVGPaint> paint = newPaint;
if (paint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR || paint->paintType() == SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR)
paint->setColor(style.color());
return paint.release();
}
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
+static inline String serializeAsFragmentIdentifier(const AtomicString& resource)
+{
+ return "#" + resource;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
{
Node* node = m_node.get();
if (!node)
- return 0;
+ return nullptr;
// Make sure our layout is up to date before we allow a query on these attributes.
if (updateLayout)
@@ -100,11 +108,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSProp
RenderStyle* style = node->computedStyle();
if (!style)
- return 0;
+ return nullptr;
const SVGRenderStyle* svgStyle = style->svgStyle();
if (!svgStyle)
- return 0;
+ return nullptr;
switch (propertyID) {
case CSSPropertyClipRule:
@@ -143,15 +151,15 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSProp
return CSSPrimitiveValue::create(svgStyle->writingMode());
case CSSPropertyClipPath:
if (!svgStyle->clipperResource().isEmpty())
- return CSSPrimitiveValue::create(svgStyle->clipperResource(), CSSPrimitiveValue::CSS_URI);
+ return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle->clipperResource()), CSSPrimitiveValue::CSS_URI);
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
case CSSPropertyMask:
if (!svgStyle->maskerResource().isEmpty())
- return CSSPrimitiveValue::create(svgStyle->maskerResource(), CSSPrimitiveValue::CSS_URI);
+ return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle->maskerResource()), CSSPrimitiveValue::CSS_URI);
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
case CSSPropertyFilter:
if (!svgStyle->filterResource().isEmpty())
- return CSSPrimitiveValue::create(svgStyle->filterResource(), CSSPrimitiveValue::CSS_URI);
+ return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle->filterResource()), CSSPrimitiveValue::CSS_URI);
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
case CSSPropertyFloodColor:
return currentColorOrValidColor(*style, svgStyle->floodColor());
@@ -161,19 +169,17 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSProp
return currentColorOrValidColor(*style, svgStyle->stopColor());
case CSSPropertyFill:
return adjustSVGPaintForCurrentColor(SVGPaint::create(svgStyle->fillPaintType(), svgStyle->fillPaintUri(), svgStyle->fillPaintColor()), *style);
- case CSSPropertyKerning:
- return SVGLength::toCSSPrimitiveValue(svgStyle->kerning());
case CSSPropertyMarkerEnd:
if (!svgStyle->markerEndResource().isEmpty())
- return CSSPrimitiveValue::create(svgStyle->markerEndResource(), CSSPrimitiveValue::CSS_URI);
+ return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle->markerEndResource()), CSSPrimitiveValue::CSS_URI);
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
case CSSPropertyMarkerMid:
if (!svgStyle->markerMidResource().isEmpty())
- return CSSPrimitiveValue::create(svgStyle->markerMidResource(), CSSPrimitiveValue::CSS_URI);
+ return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle->markerMidResource()), CSSPrimitiveValue::CSS_URI);
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
case CSSPropertyMarkerStart:
if (!svgStyle->markerStartResource().isEmpty())
- return CSSPrimitiveValue::create(svgStyle->markerStartResource(), CSSPrimitiveValue::CSS_URI);
+ return CSSPrimitiveValue::create(serializeAsFragmentIdentifier(svgStyle->markerStartResource()), CSSPrimitiveValue::CSS_URI);
return CSSPrimitiveValue::createIdentifier(CSSValueNone);
case CSSPropertyStroke:
return adjustSVGPaintForCurrentColor(SVGPaint::create(svgStyle->strokePaintType(), svgStyle->strokePaintUri(), svgStyle->strokePaintColor()), *style);
@@ -195,20 +201,20 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSProp
return SVGLength::toCSSPrimitiveValue(svgStyle->baselineShiftValue());
}
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
case CSSPropertyBufferedRendering:
return CSSPrimitiveValue::create(svgStyle->bufferedRendering());
case CSSPropertyGlyphOrientationHorizontal:
return glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationHorizontal());
case CSSPropertyGlyphOrientationVertical: {
- if (RefPtr<CSSPrimitiveValue> value = glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationVertical()))
+ if (RefPtrWillBeRawPtr<CSSPrimitiveValue> value = glyphOrientationToCSSPrimitiveValue(svgStyle->glyphOrientationVertical()))
return value.release();
if (svgStyle->glyphOrientationVertical() == GO_AUTO)
return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
- return 0;
+ return nullptr;
}
case CSSPropertyPaintOrder:
return paintOrderToCSSValueList(svgStyle->paintOrder());
@@ -218,7 +224,6 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSProp
return CSSPrimitiveValue::create(svgStyle->maskType());
case CSSPropertyMarker:
case CSSPropertyEnableBackground:
- case CSSPropertyColorProfile:
// the above properties are not yet implemented in the engine
break;
default:
@@ -227,7 +232,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSProp
ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propertyID);
}
WTF_LOG_ERROR("unimplemented propertyID: %d", propertyID);
- return 0;
+ return nullptr;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/SVGCSSParser.cpp b/chromium/third_party/WebKit/Source/core/css/SVGCSSParser.cpp
deleted file mode 100644
index 8c07b148933..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/SVGCSSParser.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- Copyright (C) 2008 Eric Seidel <eric@webkit.org>
- Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005, 2007, 2010 Rob Buis <buis@kde.org>
- Copyright (C) 2005, 2006 Apple Computer, Inc.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-#include "config.h"
-
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/CSSParser.h"
-#include "core/css/CSSValueList.h"
-#include "core/rendering/RenderTheme.h"
-#include "core/svg/SVGPaint.h"
-
-using namespace std;
-
-namespace WebCore {
-
-static bool isSystemColor(int id)
-{
- return (id >= CSSValueActiveborder && id <= CSSValueWindowtext) || id == CSSValueMenu;
-}
-
-bool CSSParser::parseSVGValue(CSSPropertyID propId, bool important)
-{
- CSSParserValue* value = m_valueList->current();
- if (!value)
- return false;
-
- CSSValueID id = value->id;
-
- bool valid_primitive = false;
- RefPtr<CSSValue> parsedValue;
-
- switch (propId) {
- /* The comment to the right defines all valid value of these
- * properties as defined in SVG 1.1, Appendix N. Property index */
- case CSSPropertyAlignmentBaseline:
- // auto | baseline | before-edge | text-before-edge | middle |
- // central | after-edge | text-after-edge | ideographic | alphabetic |
- // hanging | mathematical | inherit
- if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle ||
- (id >= CSSValueBeforeEdge && id <= CSSValueMathematical))
- valid_primitive = true;
- break;
-
- case CSSPropertyBaselineShift:
- // baseline | super | sub | <percentage> | <length> | inherit
- if (id == CSSValueBaseline || id == CSSValueSub ||
- id >= CSSValueSuper)
- valid_primitive = true;
- else
- valid_primitive = validUnit(value, FLength | FPercent, SVGAttributeMode);
- break;
-
- case CSSPropertyDominantBaseline:
- // auto | use-script | no-change | reset-size | ideographic |
- // alphabetic | hanging | mathematical | central | middle |
- // text-after-edge | text-before-edge | inherit
- if (id == CSSValueAuto || id == CSSValueMiddle ||
- (id >= CSSValueUseScript && id <= CSSValueResetSize) ||
- (id >= CSSValueCentral && id <= CSSValueMathematical))
- valid_primitive = true;
- break;
-
- case CSSPropertyEnableBackground:
- // accumulate | new [x] [y] [width] [height] | inherit
- if (id == CSSValueAccumulate) // TODO : new
- valid_primitive = true;
- break;
-
- case CSSPropertyMarkerStart:
- case CSSPropertyMarkerMid:
- case CSSPropertyMarkerEnd:
- case CSSPropertyMask:
- if (id == CSSValueNone)
- valid_primitive = true;
- else if (value->unit == CSSPrimitiveValue::CSS_URI) {
- parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI);
- if (parsedValue)
- m_valueList->next();
- }
- break;
-
- case CSSPropertyClipRule: // nonzero | evenodd | inherit
- case CSSPropertyFillRule:
- if (id == CSSValueNonzero || id == CSSValueEvenodd)
- valid_primitive = true;
- break;
-
- case CSSPropertyStrokeMiterlimit: // <miterlimit> | inherit
- valid_primitive = validUnit(value, FNumber | FNonNeg, SVGAttributeMode);
- break;
-
- case CSSPropertyStrokeLinejoin: // miter | round | bevel | inherit
- if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel)
- valid_primitive = true;
- break;
-
- case CSSPropertyStrokeLinecap: // butt | round | square | inherit
- if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare)
- valid_primitive = true;
- break;
-
- case CSSPropertyStrokeOpacity: // <opacity-value> | inherit
- case CSSPropertyFillOpacity:
- case CSSPropertyStopOpacity:
- case CSSPropertyFloodOpacity:
- valid_primitive = (!id && validUnit(value, FNumber | FPercent, SVGAttributeMode));
- break;
-
- case CSSPropertyShapeRendering:
- // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
- if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
- id == CSSValueCrispedges || id == CSSValueGeometricprecision)
- valid_primitive = true;
- break;
-
- case CSSPropertyImageRendering: // auto | optimizeSpeed |
- case CSSPropertyColorRendering: // optimizeQuality | inherit
- if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
- id == CSSValueOptimizequality)
- valid_primitive = true;
- break;
-
- case CSSPropertyBufferedRendering: // auto | dynamic | static
- if (id == CSSValueAuto || id == CSSValueDynamic || id == CSSValueStatic)
- valid_primitive = true;
- break;
-
- case CSSPropertyColorProfile: // auto | sRGB | <name> | <uri> inherit
- if (id == CSSValueAuto || id == CSSValueSrgb)
- valid_primitive = true;
- break;
-
- case CSSPropertyColorInterpolation: // auto | sRGB | linearRGB | inherit
- case CSSPropertyColorInterpolationFilters:
- if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb)
- valid_primitive = true;
- break;
-
- /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
- * correctly and allows optimization in applyRule(..)
- */
-
- case CSSPropertyTextAnchor: // start | middle | end | inherit
- if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd)
- valid_primitive = true;
- break;
-
- case CSSPropertyGlyphOrientationVertical: // auto | <angle> | inherit
- if (id == CSSValueAuto) {
- valid_primitive = true;
- break;
- }
- /* fallthrough intentional */
- case CSSPropertyGlyphOrientationHorizontal: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit
- if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) {
- parsedValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_DEG);
-
- if (parsedValue)
- m_valueList->next();
- }
- break;
-
- case CSSPropertyFill: // <paint> | inherit
- case CSSPropertyStroke: // <paint> | inherit
- {
- if (id == CSSValueNone)
- parsedValue = SVGPaint::createNone();
- else if (id == CSSValueCurrentcolor)
- parsedValue = SVGPaint::createCurrentColor();
- else if (isSystemColor(id))
- parsedValue = SVGPaint::createColor(RenderTheme::theme().systemColor(id));
- else if (value->unit == CSSPrimitiveValue::CSS_URI) {
- RGBA32 c = Color::transparent;
- if (m_valueList->next()) {
- if (parseColorFromValue(m_valueList->current(), c))
- parsedValue = SVGPaint::createURIAndColor(value->string, c);
- else if (m_valueList->current()->id == CSSValueNone)
- parsedValue = SVGPaint::createURIAndNone(value->string);
- }
- if (!parsedValue)
- parsedValue = SVGPaint::createURI(value->string);
- } else
- parsedValue = parseSVGPaint();
-
- if (parsedValue)
- m_valueList->next();
- }
- break;
-
- case CSSPropertyStopColor: // TODO : icccolor
- case CSSPropertyFloodColor:
- case CSSPropertyLightingColor:
- if (isSystemColor(id))
- parsedValue = SVGColor::createFromColor(RenderTheme::theme().systemColor(id));
- else if ((id >= CSSValueAqua && id <= CSSValueTransparent) ||
- (id >= CSSValueAliceblue && id <= CSSValueYellowgreen) || id == CSSValueGrey)
- parsedValue = SVGColor::createFromString(value->string);
- else if (id == CSSValueCurrentcolor)
- parsedValue = SVGColor::createCurrentColor();
- else // TODO : svgcolor (iccColor)
- parsedValue = parseSVGColor();
-
- if (parsedValue)
- m_valueList->next();
-
- break;
-
- case CSSPropertyPaintOrder:
- if (!RuntimeEnabledFeatures::svgPaintOrderEnabled())
- return false;
-
- if (m_valueList->size() == 1 && id == CSSValueNormal)
- valid_primitive = true;
- else if ((parsedValue = parsePaintOrder()))
- m_valueList->next();
- break;
-
- case CSSPropertyVectorEffect: // none | non-scaling-stroke | inherit
- if (id == CSSValueNone || id == CSSValueNonScalingStroke)
- valid_primitive = true;
- break;
-
- case CSSPropertyWritingMode:
- // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
- if (id == CSSValueLrTb || id == CSSValueRlTb || id == CSSValueTbRl || id == CSSValueLr || id == CSSValueRl || id == CSSValueTb)
- valid_primitive = true;
- break;
-
- case CSSPropertyStrokeWidth: // <length> | inherit
- case CSSPropertyStrokeDashoffset:
- valid_primitive = validUnit(value, FLength | FPercent, SVGAttributeMode);
- break;
- case CSSPropertyStrokeDasharray: // none | <dasharray> | inherit
- if (id == CSSValueNone)
- valid_primitive = true;
- else
- parsedValue = parseSVGStrokeDasharray();
-
- break;
-
- case CSSPropertyKerning: // auto | normal | <length> | inherit
- if (id == CSSValueAuto || id == CSSValueNormal)
- valid_primitive = true;
- else
- valid_primitive = validUnit(value, FLength, SVGAttributeMode);
- break;
-
- case CSSPropertyClipPath: // <uri> | none | inherit
- case CSSPropertyFilter:
- if (id == CSSValueNone)
- valid_primitive = true;
- else if (value->unit == CSSPrimitiveValue::CSS_URI) {
- parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
- if (parsedValue)
- m_valueList->next();
- }
- break;
- case CSSPropertyMaskType: // luminance | alpha | inherit
- if (id == CSSValueLuminance || id == CSSValueAlpha)
- valid_primitive = true;
- break;
-
- /* shorthand properties */
- case CSSPropertyMarker:
- {
- ShorthandScope scope(this, propId);
- CSSParser::ImplicitScope implicitScope(this, PropertyImplicit);
- if (!parseValue(CSSPropertyMarkerStart, important))
- return false;
- if (m_valueList->current()) {
- rollbackLastProperties(1);
- return false;
- }
- CSSValue* value = m_parsedProperties.last().value();
- addProperty(CSSPropertyMarkerMid, value, important);
- addProperty(CSSPropertyMarkerEnd, value, important);
- return true;
- }
- default:
- // If you crash here, it's because you added a css property and are not handling it
- // in either this switch statement or the one in CSSParser::parseValue
- ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
- return false;
- }
-
- if (valid_primitive) {
- if (id != 0)
- parsedValue = CSSPrimitiveValue::createIdentifier(id);
- else if (value->unit == CSSPrimitiveValue::CSS_STRING)
- parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
- else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
- parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
- else if (value->unit >= CSSParserValue::Q_EMS)
- parsedValue = CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
- if (isCalculation(value)) {
- // FIXME calc() http://webkit.org/b/16662 : actually create a CSSPrimitiveValue here, ie
- // parsedValue = CSSPrimitiveValue::create(m_parsedCalculation.release());
- m_parsedCalculation.release();
- parsedValue = 0;
- }
- m_valueList->next();
- }
- if (!parsedValue || (m_valueList->current() && !inShorthand()))
- return false;
-
- addProperty(propId, parsedValue.release(), important);
- return true;
-}
-
-PassRefPtr<CSSValue> CSSParser::parseSVGStrokeDasharray()
-{
- RefPtr<CSSValueList> ret = CSSValueList::createCommaSeparated();
- CSSParserValue* value = m_valueList->current();
- bool valid_primitive = true;
- while (value) {
- valid_primitive = validUnit(value, FLength | FPercent | FNonNeg, SVGAttributeMode);
- if (!valid_primitive)
- break;
- if (value->id != 0)
- ret->append(CSSPrimitiveValue::createIdentifier(value->id));
- else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
- ret->append(CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
- value = m_valueList->next();
- if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
- value = m_valueList->next();
- }
- if (!valid_primitive)
- return 0;
- return ret.release();
-}
-
-PassRefPtr<CSSValue> CSSParser::parseSVGPaint()
-{
- RGBA32 c = Color::transparent;
- if (!parseColorFromValue(m_valueList->current(), c))
- return SVGPaint::createUnknown();
- return SVGPaint::createColor(Color(c));
-}
-
-PassRefPtr<CSSValue> CSSParser::parseSVGColor()
-{
- RGBA32 c = Color::transparent;
- if (!parseColorFromValue(m_valueList->current(), c))
- return 0;
- return SVGColor::createFromColor(Color(c));
-}
-
-// normal | [ fill || stroke || markers ]
-PassRefPtr<CSSValue> CSSParser::parsePaintOrder() const
-{
- if (m_valueList->size() > 3)
- return 0;
-
- CSSParserValue* value = m_valueList->current();
- if (!value)
- return 0;
-
- RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
-
- // The default paint-order is: Fill, Stroke, Markers.
- bool seenFill = false,
- seenStroke = false,
- seenMarkers = false;
-
- do {
- switch (value->id) {
- case CSSValueNormal:
- // normal inside [fill || stroke || markers] not valid
- return 0;
- case CSSValueFill:
- if (seenFill)
- return 0;
-
- seenFill = true;
- break;
- case CSSValueStroke:
- if (seenStroke)
- return 0;
-
- seenStroke = true;
- break;
- case CSSValueMarkers:
- if (seenMarkers)
- return 0;
-
- seenMarkers = true;
- break;
- default:
- return 0;
- }
-
- parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id));
- } while ((value = m_valueList->next()));
-
- // fill out the rest of the paint order
- if (!seenFill)
- parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
- if (!seenStroke)
- parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
- if (!seenMarkers)
- parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
-
- return parsedValues.release();
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in b/chromium/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in
index 1cf28711f0f..98fb81438de 100644
--- a/chromium/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in
+++ b/chromium/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in
@@ -18,7 +18,6 @@ stop-opacity
// pointer-events
color-interpolation
color-interpolation-filters
-color-profile
color-rendering
fill
fill-opacity
@@ -45,7 +44,6 @@ baseline-shift
dominant-baseline
glyph-orientation-horizontal
glyph-orientation-vertical
-kerning
text-anchor
vector-effect
writing-mode
diff --git a/chromium/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in b/chromium/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in
index ccfad3ca78f..b4260b76325 100644
--- a/chromium/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in
+++ b/chromium/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in
@@ -259,7 +259,6 @@ reset-size
// CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL
// CSS_PROP_GLYPH_ORIENTATION_VERTICAL
-// CSS_PROP_KERNING
// CSS_PROP_TEXT_ANCHOR
// start
// middle
diff --git a/chromium/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/chromium/third_party/WebKit/Source/core/css/SelectorChecker.cpp
index 15474cedd1d..3c6755a57fc 100644
--- a/chromium/third_party/WebKit/Source/core/css/SelectorChecker.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -28,27 +28,26 @@
#include "config.h"
#include "core/css/SelectorChecker.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSSelectorList.h"
#include "core/css/SiblingTraversalStrategies.h"
#include "core/dom/Document.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/FrameSelection.h"
-#include "core/html/HTMLAnchorElement.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/html/HTMLInputElement.h"
-#include "core/html/HTMLOptGroupElement.h"
#include "core/html/HTMLOptionElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/track/vtt/VTTElement.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/style/RenderStyle.h"
@@ -66,32 +65,39 @@ SelectorChecker::SelectorChecker(Document& document, Mode mode)
{
}
-static bool matchesCustomPseudoElement(const Element* element, const CSSSelector* selector)
+static bool matchesCustomPseudoElement(const Element* element, const CSSSelector& selector)
{
ShadowRoot* root = element->containingShadowRoot();
- if (!root)
+ if (!root || root->type() != ShadowRoot::UserAgentShadowRoot)
return false;
- const AtomicString& pseudoId = selector->pseudoType() == CSSSelector::PseudoWebKitCustomElement ? element->shadowPseudoId() : element->pseudo();
- if (pseudoId != selector->value())
- return false;
- if (selector->pseudoType() == CSSSelector::PseudoWebKitCustomElement && root->type() != ShadowRoot::UserAgentShadowRoot)
+ if (element->shadowPseudoId() != selector.value())
return false;
+
return true;
}
-Element* SelectorChecker::parentElement(const SelectorCheckingContext& context) const
+Element* SelectorChecker::parentElement(const SelectorCheckingContext& context, bool allowToCrossBoundary) const
{
// CrossesBoundary means we don't care any context.scope. So we can walk up from a shadow root to its shadow host.
- if ((context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) == SelectorChecker::CrossesBoundary)
+ if (allowToCrossBoundary)
+ return context.element->parentOrShadowHostElement();
+
+ // If context.scope is a shadow root, we should walk up to its shadow host.
+ if ((context.behaviorAtBoundary & SelectorChecker::ScopeIsShadowRoot) && context.scope == context.element->containingShadowRoot())
return context.element->parentOrShadowHostElement();
- // If context.scope is not a shadow host, we cannot walk up from a shadow root to its shadow host.
- if (!(context.behaviorAtBoundary & SelectorChecker::ScopeIsShadowHost))
+ if ((context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) != SelectorChecker::StaysWithinTreeScope)
return context.element->parentElement();
- // If behaviorAtBoundary is StaysWithInTreeScope, we cannot walk up from a shadow root to its shadow host.
- return (context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) != SelectorChecker::StaysWithinTreeScope ? context.element->parentOrShadowHostElement() : context.element->parentElement();
+ // If context.scope is some element in some shadow tree and querySelector initialized the context,
+ // e.g. shadowRoot.querySelector(':host *'),
+ // (a) context.element has the same treescope as context.scope, need to walk up to its shadow host.
+ // (b) Otherwise, should not walk up from a shadow root to a shadow host.
+ if (context.scope && context.scope->treeScope() == context.element->treeScope())
+ return context.element->parentOrShadowHostElement();
+
+ return context.element->parentElement();
}
bool SelectorChecker::scopeContainsLastMatchedElement(const SelectorCheckingContext& context) const
@@ -100,25 +106,21 @@ bool SelectorChecker::scopeContainsLastMatchedElement(const SelectorCheckingCont
return true;
ASSERT(context.scope);
- // If behaviorAtBoundary is not ScopeIsShadowHost, we can use "contains".
- if (!(context.behaviorAtBoundary & SelectorChecker::ScopeIsShadowHost))
- return context.scope->contains(context.element);
-
- // If a given element is scope, i.e. shadow host, matches.
- if (context.element == context.scope)
+ if (context.scope->treeScope() == context.element->treeScope())
return true;
- ShadowRoot* root = context.element->containingShadowRoot();
- if (!root)
- return false;
-
- // If a host of the containing shadow root is scope, matches.
- return root->host() == context.scope;
+ // Because Blink treats a shadow host's TreeScope as a separate one from its descendent shadow roots,
+ // if the last matched element is a shadow host, the condition above isn't met, even though it
+ // should be.
+ return context.element == context.scope->shadowHost() && (!context.previousElement || context.previousElement->isInDescendantTreeOf(context.element));
}
static inline bool nextSelectorExceedsScope(const SelectorChecker::SelectorCheckingContext& context)
{
- return context.element == context.scope && (context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) != SelectorChecker::StaysWithinTreeScope;
+ if (context.scope && context.scope->isInShadowTree())
+ return context.element == context.scope->shadowHost();
+
+ return false;
}
// Recursive check of selectors and combinators
@@ -135,13 +137,16 @@ SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext& con
if (!checkOne(context, siblingTraversalStrategy, &specificity))
return SelectorFailsLocally;
- if (context.selector->m_match == CSSSelector::PseudoElement) {
+ if (context.selector->match() == CSSSelector::PseudoElement) {
if (context.selector->isCustomPseudoElement()) {
- if (!matchesCustomPseudoElement(context.element, context.selector))
+ if (!matchesCustomPseudoElement(context.element, *context.selector))
return SelectorFailsLocally;
} else if (context.selector->isContentPseudoElement()) {
if (!context.element->isInShadowTree() || !context.element->isInsertionPoint())
return SelectorFailsLocally;
+ } else if (context.selector->isShadowPseudoElement()) {
+ if (!context.element->isInShadowTree() || !context.previousElement)
+ return SelectorFailsCompletely;
} else {
if ((!context.elementStyle && m_mode == ResolvingStyle) || m_mode == QueryingRules)
return SelectorFailsLocally;
@@ -155,8 +160,7 @@ SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext& con
}
// Prepare next selector
- const CSSSelector* historySelector = context.selector->tagHistory();
- if (!historySelector) {
+ if (context.selector->isLastInTagHistory()) {
if (scopeContainsLastMatchedElement(context)) {
if (result)
result->specificity += specificity;
@@ -199,6 +203,11 @@ static inline SelectorChecker::SelectorCheckingContext prepareNextContextForRela
return nextContext;
}
+static inline bool isAuthorShadowRoot(const Node* node)
+{
+ return node && node->isShadowRoot() && toShadowRoot(node)->type() == ShadowRoot::AuthorShadowRoot;
+}
+
template<typename SiblingTraversalStrategy>
SelectorChecker::Match SelectorChecker::matchForSubSelector(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const
{
@@ -212,17 +221,31 @@ SelectorChecker::Match SelectorChecker::matchForSubSelector(const SelectorChecki
nextContext.hasSelectionPseudo = dynamicPseudo == SELECTION;
if ((context.elementStyle || m_mode == CollectingCSSRules || m_mode == CollectingStyleRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO
&& !nextContext.hasSelectionPseudo
- && !(nextContext.hasScrollbarPseudo && nextContext.selector->m_match == CSSSelector::PseudoClass))
+ && !(nextContext.hasScrollbarPseudo && nextContext.selector->match() == CSSSelector::PseudoClass))
return SelectorFailsCompletely;
nextContext.isSubSelector = true;
return match(nextContext, siblingTraversalStrategy, result);
}
+static bool selectorMatchesShadowRoot(const CSSSelector* selector)
+{
+ return selector && selector->isShadowPseudoElement();
+}
+
+template<typename SiblingTraversalStrategy>
+SelectorChecker::Match SelectorChecker::matchForPseudoShadow(const ContainerNode* node, const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const
+{
+ if (!isAuthorShadowRoot(node))
+ return SelectorFailsCompletely;
+ return match(context, siblingTraversalStrategy, result);
+}
+
template<typename SiblingTraversalStrategy>
SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const
{
SelectorCheckingContext nextContext = prepareNextContextForRelation(context);
+ nextContext.previousElement = context.element;
CSSSelector::Relation relation = context.selector->relation();
@@ -243,6 +266,10 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
}
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
+
+ if (selectorMatchesShadowRoot(nextContext.selector))
+ return matchForPseudoShadow(context.element->containingShadowRoot(), nextContext, siblingTraversalStrategy, result);
+
for (nextContext.element = parentElement(context); nextContext.element; nextContext.element = parentElement(nextContext)) {
Match match = this->match(nextContext, siblingTraversalStrategy, result);
if (match == SelectorMatches || match == SelectorFailsCompletely)
@@ -256,20 +283,27 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
if (context.selector->relationIsAffectedByPseudoContent())
return matchForShadowDistributed(context.element, siblingTraversalStrategy, nextContext, result);
+ nextContext.isSubSelector = false;
+ nextContext.elementStyle = 0;
+
+ if (selectorMatchesShadowRoot(nextContext.selector))
+ return matchForPseudoShadow(context.element->parentNode(), nextContext, siblingTraversalStrategy, result);
+
nextContext.element = parentElement(context);
if (!nextContext.element)
return SelectorFailsCompletely;
-
- nextContext.isSubSelector = false;
- nextContext.elementStyle = 0;
return match(nextContext, siblingTraversalStrategy, result);
}
case CSSSelector::DirectAdjacent:
+ // Shadow roots can't have sibling elements
+ if (selectorMatchesShadowRoot(nextContext.selector))
+ return SelectorFailsCompletely;
+
if (m_mode == ResolvingStyle) {
- if (Element* parent = parentElement(context))
+ if (ContainerNode* parent = context.element->parentElementOrShadowRoot())
parent->setChildrenAffectedByDirectAdjacentRules();
}
- nextContext.element = context.element->previousElementSibling();
+ nextContext.element = ElementTraversal::previousSibling(*context.element);
if (!nextContext.element)
return SelectorFailsAllSiblings;
nextContext.isSubSelector = false;
@@ -277,14 +311,18 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
return match(nextContext, siblingTraversalStrategy, result);
case CSSSelector::IndirectAdjacent:
+ // Shadow roots can't have sibling elements
+ if (selectorMatchesShadowRoot(nextContext.selector))
+ return SelectorFailsCompletely;
+
if (m_mode == ResolvingStyle) {
- if (Element* parent = parentElement(context))
- parent->setChildrenAffectedByForwardPositionalRules();
+ if (ContainerNode* parent = context.element->parentElementOrShadowRoot())
+ parent->setChildrenAffectedByIndirectAdjacentRules();
}
- nextContext.element = context.element->previousElementSibling();
+ nextContext.element = ElementTraversal::previousSibling(*context.element);
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
- for (; nextContext.element; nextContext.element = nextContext.element->previousElementSibling()) {
+ for (; nextContext.element; nextContext.element = ElementTraversal::previousSibling(*nextContext.element)) {
Match match = this->match(nextContext, siblingTraversalStrategy, result);
if (match == SelectorMatches || match == SelectorFailsAllSiblings || match == SelectorFailsCompletely)
return match;
@@ -292,10 +330,9 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
return SelectorFailsAllSiblings;
case CSSSelector::ShadowPseudo:
- case CSSSelector::ChildTree:
{
// If we're in the same tree-scope as the scoping element, then following a shadow descendant combinator would escape that and thus the scope.
- if (context.scope && context.scope->treeScope() == context.element->treeScope() && (context.behaviorAtBoundary & BoundaryBehaviorMask) != StaysWithinTreeScope)
+ if (context.scope && context.scope->shadowHost() && context.scope->shadowHost()->treeScope() == context.element->treeScope() && (context.behaviorAtBoundary & BoundaryBehaviorMask) != StaysWithinTreeScope)
return SelectorFailsCompletely;
Element* shadowHost = context.element->shadowHost();
@@ -307,11 +344,11 @@ SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingC
return this->match(nextContext, siblingTraversalStrategy, result);
}
- case CSSSelector::DescendantTree:
+ case CSSSelector::ShadowDeep:
{
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
- for (nextContext.element = parentElement(context); nextContext.element; nextContext.element = parentElement(nextContext)) {
+ for (nextContext.element = parentElement(context, true); nextContext.element; nextContext.element = parentElement(nextContext, true)) {
Match match = this->match(nextContext, siblingTraversalStrategy, result);
if (match == SelectorMatches || match == SelectorFailsCompletely)
return match;
@@ -333,7 +370,7 @@ template<typename SiblingTraversalStrategy>
SelectorChecker::Match SelectorChecker::matchForShadowDistributed(const Element* element, const SiblingTraversalStrategy& siblingTraversalStrategy, SelectorCheckingContext& nextContext, MatchResult* result) const
{
ASSERT(element);
- Vector<InsertionPoint*, 8> insertionPoints;
+ WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
const ContainerNode* scope = nextContext.scope;
BehaviorAtBoundary behaviorAtBoundary = nextContext.behaviorAtBoundary;
@@ -342,32 +379,44 @@ SelectorChecker::Match SelectorChecker::matchForShadowDistributed(const Element*
for (size_t i = 0; i < insertionPoints.size(); ++i) {
nextContext.element = insertionPoints[i];
- // If a given scope is a shadow host of an insertion point but behaviorAtBoundary doesn't have ScopeIsShadowHost,
+ // If a given scope is a shadow host of an insertion point but behaviorAtBoundary doesn't have ScopeIsShadowRoot,
// we need to update behaviorAtBoundary to make selectors like ":host > ::content" work correctly.
- if (scope == insertionPoints[i]->containingShadowRoot()->shadowHost() && !(behaviorAtBoundary & ScopeIsShadowHost))
- nextContext.behaviorAtBoundary = static_cast<BehaviorAtBoundary>(behaviorAtBoundary | ScopeIsShadowHost);
- else
+ if (m_mode == SharingRules) {
+ nextContext.behaviorAtBoundary = static_cast<BehaviorAtBoundary>(behaviorAtBoundary | ScopeIsShadowRoot);
+ nextContext.scope = insertionPoints[i]->containingShadowRoot();
+ } else if (scope == insertionPoints[i]->containingShadowRoot() && !(behaviorAtBoundary & ScopeIsShadowRoot)) {
+ nextContext.behaviorAtBoundary = static_cast<BehaviorAtBoundary>(behaviorAtBoundary | ScopeIsShadowRoot);
+ } else {
nextContext.behaviorAtBoundary = behaviorAtBoundary;
+ }
nextContext.isSubSelector = false;
nextContext.elementStyle = 0;
if (match(nextContext, siblingTraversalStrategy, result) == SelectorMatches)
return SelectorMatches;
}
- return SelectorFailsCompletely;
+ return SelectorFailsLocally;
}
-static inline bool containsHTMLSpace(const AtomicString& string)
+template<typename CharType>
+static inline bool containsHTMLSpaceTemplate(const CharType* string, unsigned length)
{
- for (unsigned i = 0; i < string.length(); i++)
- if (isHTMLSpace<UChar>(string[i]))
+ for (unsigned i = 0; i < length; ++i)
+ if (isHTMLSpace<CharType>(string[i]))
return true;
return false;
}
-static bool attributeValueMatches(const Attribute* attributeItem, CSSSelector::Match match, const AtomicString& selectorValue, bool caseSensitive)
+static inline bool containsHTMLSpace(const AtomicString& string)
+{
+ if (LIKELY(string.is8Bit()))
+ return containsHTMLSpaceTemplate<LChar>(string.characters8(), string.length());
+ return containsHTMLSpaceTemplate<UChar>(string.characters16(), string.length());
+}
+
+static bool attributeValueMatches(const Attribute& attributeItem, CSSSelector::Match match, const AtomicString& selectorValue, bool caseSensitive)
{
- const AtomicString& value = attributeItem->value();
+ const AtomicString& value = attributeItem.value();
if (value.isNull())
return false;
@@ -441,18 +490,28 @@ static bool anyAttributeMatches(Element& element, CSSSelector::Match match, cons
return false;
const AtomicString& selectorValue = selector.value();
- // Case sensitivity for attribute matching is looser than hasAttribute or
- // Element::shouldIgnoreAttributeCase() for now. Unclear if that's correct.
- bool caseSensitive = !element.document().isHTMLDocument() || HTMLDocument::isCaseSensitiveAttribute(selectorAttr);
- for (size_t i = 0; i < element.attributeCount(); ++i) {
- const Attribute* attributeItem = element.attributeItem(i);
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ const Attribute& attributeItem = *it;
- if (!attributeItem->matches(selectorAttr))
+ if (!attributeItem.matches(selectorAttr))
continue;
- if (attributeValueMatches(attributeItem, match, selectorValue, caseSensitive))
+ if (attributeValueMatches(attributeItem, match, selectorValue, true))
return true;
+
+ // Case sensitivity for attribute matching is looser than hasAttribute or
+ // Element::shouldIgnoreAttributeCase() for now. Unclear if that's correct.
+ bool caseSensitive = !element.document().isHTMLDocument() || HTMLDocument::isCaseSensitiveAttribute(selectorAttr);
+
+ // If case-insensitive, re-check, and count if result differs.
+ // See http://code.google.com/p/chromium/issues/detail?id=327060
+ if (!caseSensitive && attributeValueMatches(attributeItem, match, selectorValue, false)) {
+ UseCounter::count(element.document(), UseCounter::CaseInsensitiveAttrSelectorMatch);
+ return true;
+ }
}
return false;
@@ -463,33 +522,35 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
{
ASSERT(context.element);
Element& element = *context.element;
- const CSSSelector* const & selector = context.selector;
- ASSERT(selector);
+ ASSERT(context.selector);
+ const CSSSelector& selector = *context.selector;
+
bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.behaviorAtBoundary, context.scope);
- if (selector->m_match == CSSSelector::Tag)
- return SelectorChecker::tagMatches(element, selector->tagQName(), elementIsHostInItsShadowTree ? MatchingHostInItsShadowTree : MatchingElement);
+ // Only :host and :ancestor should match the host: http://drafts.csswg.org/css-scoping/#host-element
+ if (elementIsHostInItsShadowTree && !selector.isHostPseudoClass()
+ && !(context.behaviorAtBoundary & TreatShadowHostAsNormalScope))
+ return false;
- if (selector->m_match == CSSSelector::Class)
- return element.hasClass() && element.classNames().contains(selector->value()) && !elementIsHostInItsShadowTree;
+ if (selector.match() == CSSSelector::Tag)
+ return SelectorChecker::tagMatches(element, selector.tagQName());
- if (selector->m_match == CSSSelector::Id)
- return element.hasID() && element.idForStyleResolution() == selector->value() && !elementIsHostInItsShadowTree;
+ if (selector.match() == CSSSelector::Class)
+ return element.hasClass() && element.classNames().contains(selector.value());
- if (selector->isAttributeSelector()) {
- if (elementIsHostInItsShadowTree)
- return false;
- if (!anyAttributeMatches(element, static_cast<CSSSelector::Match>(selector->m_match), *selector))
- return false;
- }
+ if (selector.match() == CSSSelector::Id)
+ return element.hasID() && element.idForStyleResolution() == selector.value();
+
+ if (selector.isAttributeSelector())
+ return anyAttributeMatches(element, selector.match(), selector);
- if (selector->m_match == CSSSelector::PseudoClass) {
+ if (selector.match() == CSSSelector::PseudoClass) {
// Handle :not up front.
- if (selector->pseudoType() == CSSSelector::PseudoNot) {
+ if (selector.pseudoType() == CSSSelector::PseudoNot) {
SelectorCheckingContext subContext(context);
subContext.isSubSelector = true;
- ASSERT(selector->selectorList());
- for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = subContext.selector->tagHistory()) {
+ ASSERT(selector.selectorList());
+ for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = subContext.selector->tagHistory()) {
// :not cannot nest. I don't really know why this is a
// restriction in CSS3, but it is, so let's honor it.
// the parser enforces that this never occurs
@@ -497,6 +558,10 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
// We select between :visited and :link when applying. We don't know which one applied (or not) yet.
if (subContext.selector->pseudoType() == CSSSelector::PseudoVisited || (subContext.selector->pseudoType() == CSSSelector::PseudoLink && subContext.visitedMatchType == VisitedMatchEnabled))
return true;
+ // context.scope is not available if m_mode == SharingRules.
+ // We cannot determine whether :host or :scope matches a given element or not.
+ if (m_mode == SharingRules && (subContext.selector->isHostPseudoClass() || subContext.selector->pseudoType() == CSSSelector::PseudoScope))
+ return true;
if (!checkOne(subContext, DOMSiblingTraversalStrategy()))
return true;
}
@@ -505,12 +570,12 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
// (since there are no elements involved).
return checkScrollbarPseudoClass(context, &element.document(), selector);
} else if (context.hasSelectionPseudo) {
- if (selector->pseudoType() == CSSSelector::PseudoWindowInactive)
+ if (selector.pseudoType() == CSSSelector::PseudoWindowInactive)
return !element.document().page()->focusController().isActive();
}
// Normal element pseudo class checking.
- switch (selector->pseudoType()) {
+ switch (selector.pseudoType()) {
// Pseudo classes:
case CSSSelector::PseudoNot:
break; // Already handled up above.
@@ -541,8 +606,8 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
}
case CSSSelector::PseudoFirstChild:
// first-child matches the first child that is an element
- if (Element* parent = element.parentElement()) {
- bool result = siblingTraversalStrategy.isFirstChild(&element);
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
+ bool result = siblingTraversalStrategy.isFirstChild(element);
if (m_mode == ResolvingStyle) {
RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
parent->setChildrenAffectedByFirstChildRules();
@@ -554,8 +619,8 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
break;
case CSSSelector::PseudoFirstOfType:
// first-of-type matches the first element of its type
- if (Element* parent = element.parentElement()) {
- bool result = siblingTraversalStrategy.isFirstOfType(&element, element.tagQName());
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
+ bool result = siblingTraversalStrategy.isFirstOfType(element, element.tagQName());
if (m_mode == ResolvingStyle)
parent->setChildrenAffectedByForwardPositionalRules();
return result;
@@ -563,8 +628,8 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
break;
case CSSSelector::PseudoLastChild:
// last-child matches the last child that is an element
- if (Element* parent = element.parentElement()) {
- bool result = parent->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(&element);
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
+ bool result = parent->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element);
if (m_mode == ResolvingStyle) {
RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
parent->setChildrenAffectedByLastChildRules();
@@ -576,18 +641,18 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
break;
case CSSSelector::PseudoLastOfType:
// last-of-type matches the last element of its type
- if (Element* parent = element.parentElement()) {
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
if (m_mode == ResolvingStyle)
parent->setChildrenAffectedByBackwardPositionalRules();
if (!parent->isFinishedParsingChildren())
return false;
- return siblingTraversalStrategy.isLastOfType(&element, element.tagQName());
+ return siblingTraversalStrategy.isLastOfType(element, element.tagQName());
}
break;
case CSSSelector::PseudoOnlyChild:
- if (Element* parent = element.parentElement()) {
- bool firstChild = siblingTraversalStrategy.isFirstChild(&element);
- bool onlyChild = firstChild && parent->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(&element);
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
+ bool firstChild = siblingTraversalStrategy.isFirstChild(element);
+ bool onlyChild = firstChild && parent->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element);
if (m_mode == ResolvingStyle) {
RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
parent->setChildrenAffectedByFirstChildRules();
@@ -602,69 +667,68 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
break;
case CSSSelector::PseudoOnlyOfType:
// FIXME: This selector is very slow.
- if (Element* parent = element.parentElement()) {
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
if (m_mode == ResolvingStyle) {
parent->setChildrenAffectedByForwardPositionalRules();
parent->setChildrenAffectedByBackwardPositionalRules();
}
if (!parent->isFinishedParsingChildren())
return false;
- return siblingTraversalStrategy.isFirstOfType(&element, element.tagQName()) && siblingTraversalStrategy.isLastOfType(&element, element.tagQName());
+ return siblingTraversalStrategy.isFirstOfType(element, element.tagQName()) && siblingTraversalStrategy.isLastOfType(element, element.tagQName());
}
break;
case CSSSelector::PseudoNthChild:
- if (!selector->parseNth())
+ if (!selector.parseNth())
break;
- if (Element* parent = element.parentElement()) {
- int count = 1 + siblingTraversalStrategy.countElementsBefore(&element);
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
+ int count = 1 + siblingTraversalStrategy.countElementsBefore(element);
if (m_mode == ResolvingStyle) {
RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
- element.setChildIndex(count);
if (childStyle)
childStyle->setUnique();
parent->setChildrenAffectedByForwardPositionalRules();
}
- if (selector->matchNth(count))
+ if (selector.matchNth(count))
return true;
}
break;
case CSSSelector::PseudoNthOfType:
- if (!selector->parseNth())
+ if (!selector.parseNth())
break;
- if (Element* parent = element.parentElement()) {
- int count = 1 + siblingTraversalStrategy.countElementsOfTypeBefore(&element, element.tagQName());
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
+ int count = 1 + siblingTraversalStrategy.countElementsOfTypeBefore(element, element.tagQName());
if (m_mode == ResolvingStyle)
parent->setChildrenAffectedByForwardPositionalRules();
- if (selector->matchNth(count))
+ if (selector.matchNth(count))
return true;
}
break;
case CSSSelector::PseudoNthLastChild:
- if (!selector->parseNth())
+ if (!selector.parseNth())
break;
- if (Element* parent = element.parentElement()) {
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
if (m_mode == ResolvingStyle)
parent->setChildrenAffectedByBackwardPositionalRules();
if (!parent->isFinishedParsingChildren())
return false;
- int count = 1 + siblingTraversalStrategy.countElementsAfter(&element);
- if (selector->matchNth(count))
+ int count = 1 + siblingTraversalStrategy.countElementsAfter(element);
+ if (selector.matchNth(count))
return true;
}
break;
case CSSSelector::PseudoNthLastOfType:
- if (!selector->parseNth())
+ if (!selector.parseNth())
break;
- if (Element* parent = element.parentElement()) {
+ if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
if (m_mode == ResolvingStyle)
parent->setChildrenAffectedByBackwardPositionalRules();
if (!parent->isFinishedParsingChildren())
return false;
- int count = 1 + siblingTraversalStrategy.countElementsOfTypeAfter(&element, element.tagQName());
- if (selector->matchNth(count))
+ int count = 1 + siblingTraversalStrategy.countElementsOfTypeAfter(element, element.tagQName());
+ if (selector.matchNth(count))
return true;
}
break;
@@ -676,8 +740,8 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
{
SelectorCheckingContext subContext(context);
subContext.isSubSelector = true;
- ASSERT(selector->selectorList());
- for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) {
+ ASSERT(selector.selectorList());
+ for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
if (match(subContext, siblingTraversalStrategy) == SelectorMatches)
return true;
}
@@ -699,7 +763,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
if (context.elementStyle)
context.elementStyle->setAffectedByDrag();
else
- element.setChildrenAffectedByDrag();
+ element.setChildrenOrSiblingsAffectedByDrag();
}
if (element.renderer() && element.renderer()->isDragging())
return true;
@@ -709,18 +773,18 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
if (context.elementStyle)
context.elementStyle->setAffectedByFocus();
else
- element.setChildrenAffectedByFocus();
+ element.setChildrenOrSiblingsAffectedByFocus();
}
return matchesFocusPseudoClass(element);
case CSSSelector::PseudoHover:
// If we're in quirks mode, then hover should never match anchors with no
// href and *:hover should not match anything. This is important for sites like wsj.com.
- if (m_strictParsing || context.isSubSelector || (selector->m_match == CSSSelector::Tag && selector->tagQName() != anyQName() && !isHTMLAnchorElement(element)) || element.isLink()) {
+ if (m_strictParsing || context.isSubSelector || element.isLink()) {
if (m_mode == ResolvingStyle) {
if (context.elementStyle)
context.elementStyle->setAffectedByHover();
else
- element.setChildrenAffectedByHover();
+ element.setChildrenOrSiblingsAffectedByHover();
}
if (element.hovered() || InspectorInstrumentation::forcePseudoState(&element, CSSSelector::PseudoHover))
return true;
@@ -729,19 +793,19 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
case CSSSelector::PseudoActive:
// If we're in quirks mode, then :active should never match anchors with no
// href and *:active should not match anything.
- if (m_strictParsing || context.isSubSelector || (selector->m_match == CSSSelector::Tag && selector->tagQName() != anyQName() && !isHTMLAnchorElement(element)) || element.isLink()) {
+ if (m_strictParsing || context.isSubSelector || element.isLink()) {
if (m_mode == ResolvingStyle) {
if (context.elementStyle)
context.elementStyle->setAffectedByActive();
else
- element.setChildrenAffectedByActive();
+ element.setChildrenOrSiblingsAffectedByActive();
}
if (element.active() || InspectorInstrumentation::forcePseudoState(&element, CSSSelector::PseudoActive))
return true;
}
break;
case CSSSelector::PseudoEnabled:
- if (element.isFormControlElement() || element.hasTagName(optionTag) || isHTMLOptGroupElement(element))
+ if (element.isFormControlElement() || isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
return !element.isDisabledFormControl();
break;
case CSSSelector::PseudoFullPageMedia:
@@ -750,7 +814,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
case CSSSelector::PseudoDefault:
return element.isDefaultButtonForForm();
case CSSSelector::PseudoDisabled:
- if (element.isFormControlElement() || element.hasTagName(optionTag) || isHTMLOptGroupElement(element))
+ if (element.isFormControlElement() || isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
return element.isDisabledFormControl();
break;
case CSSSelector::PseudoReadOnly:
@@ -769,7 +833,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
return element.willValidate() && !element.isValidFormControlElement();
case CSSSelector::PseudoChecked:
{
- if (element.hasTagName(inputTag)) {
+ if (isHTMLInputElement(element)) {
HTMLInputElement& inputElement = toHTMLInputElement(element);
// Even though WinIE allows checked and indeterminate to
// co-exist, the CSS selector spec says that you can't be
@@ -778,7 +842,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
// test for matching the pseudo.
if (inputElement.shouldAppearChecked() && !inputElement.shouldAppearIndeterminate())
return true;
- } else if (element.hasTagName(optionTag) && toHTMLOptionElement(element).selected())
+ } else if (isHTMLOptionElement(element) && toHTMLOptionElement(element).selected())
return true;
break;
}
@@ -795,7 +859,7 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
value = toVTTElement(element).language();
else
value = element.computeInheritedLanguage();
- const AtomicString& argument = selector->argument();
+ const AtomicString& argument = selector.argument();
if (value.isEmpty() || !value.startsWith(argument, false))
break;
if (value.length() != argument.length() && value[argument.length()] != '-')
@@ -807,9 +871,9 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
// element is an element in the document, the 'full-screen' pseudoclass applies to
// that element. Also, an <iframe>, <object> or <embed> element whose child browsing
// context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.
- if (element.isFrameElementBase() && element.containsFullScreenElement())
+ if (isHTMLFrameElementBase(element) && element.containsFullScreenElement())
return true;
- if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&element.document())) {
+ if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(element.document())) {
if (!fullscreen->webkitIsFullScreen())
return false;
return element == fullscreen->webkitCurrentFullScreenElement();
@@ -820,13 +884,9 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
case CSSSelector::PseudoFullScreenDocument:
// While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies
// to all elements of that Document.
- if (!FullscreenElementStack::isFullScreen(&element.document()))
+ if (!FullscreenElementStack::isFullScreen(element.document()))
return false;
return true;
- case CSSSelector::PseudoSeamlessDocument:
- // While a document is rendered in a seamless iframe, the 'seamless-document' pseudoclass applies
- // to all elements of that Document.
- return element.document().shouldDisplaySeamlesslyWithParent();
case CSSSelector::PseudoInRange:
element.document().setContainsValidityStyleRules();
return element.isInRange();
@@ -840,7 +900,9 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
case CSSSelector::PseudoScope:
{
- const Node* contextualReferenceNode = !context.scope || (context.behaviorAtBoundary & BoundaryBehaviorMask) == CrossesBoundary ? element.document().documentElement() : context.scope;
+ if (m_mode == SharingRules)
+ return true;
+ const Node* contextualReferenceNode = !context.scope ? element.document().documentElement() : context.scope;
if (element == contextualReferenceNode)
return true;
break;
@@ -852,14 +914,20 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
break;
case CSSSelector::PseudoHost:
+ case CSSSelector::PseudoHostContext:
{
+ if (m_mode == SharingRules)
+ return true;
// :host only matches a shadow host when :host is in a shadow tree of the shadow host.
- if (!context.scope || !(context.behaviorAtBoundary & ScopeIsShadowHost) || context.scope != element)
+ if (!context.scope)
+ return false;
+ const ContainerNode* shadowHost = context.scope->shadowHost();
+ if (!shadowHost || shadowHost != element)
return false;
ASSERT(element.shadow());
// For empty parameter case, i.e. just :host or :host().
- if (!selector->selectorList()) // Use *'s specificity. So just 0.
+ if (!selector.selectorList()) // Use *'s specificity. So just 0.
return true;
SelectorCheckingContext subContext(context);
@@ -869,22 +937,30 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
unsigned maxSpecificity = 0;
// If one of simple selectors matches an element, returns SelectorMatches. Just "OR".
- for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) {
+ for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
subContext.behaviorAtBoundary = ScopeIsShadowHostInPseudoHostParameter;
subContext.scope = context.scope;
// Use NodeRenderingTraversal to traverse a composed ancestor list of a given element.
- for (Element* nextElement = &element; nextElement; nextElement = NodeRenderingTraversal::parentElement(nextElement)) {
+ Element* nextElement = &element;
+ SelectorCheckingContext hostContext(subContext);
+ do {
MatchResult subResult;
- subContext.element = nextElement;
- if (match(subContext, siblingTraversalStrategy, &subResult) == SelectorMatches) {
+ hostContext.element = nextElement;
+ if (match(hostContext, siblingTraversalStrategy, &subResult) == SelectorMatches) {
matched = true;
// Consider div:host(div:host(div:host(div:host...))).
- maxSpecificity = std::max(maxSpecificity, subContext.selector->specificity() + subResult.specificity);
+ maxSpecificity = std::max(maxSpecificity, hostContext.selector->specificity() + subResult.specificity);
break;
}
- subContext.behaviorAtBoundary = CrossesBoundary;
- subContext.scope = 0;
- }
+ hostContext.behaviorAtBoundary = DoesNotCrossBoundary;
+ hostContext.scope = 0;
+
+ if (selector.pseudoType() == CSSSelector::PseudoHost)
+ break;
+
+ hostContext.elementStyle = 0;
+ nextElement = NodeRenderingTraversal::parentElement(nextElement);
+ } while (nextElement);
}
if (matched) {
if (specificity)
@@ -913,14 +989,14 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
break;
}
return false;
- }
- else if (selector->m_match == CSSSelector::PseudoElement && selector->pseudoType() == CSSSelector::PseudoCue) {
+ } else if (selector.match() == CSSSelector::PseudoElement && selector.pseudoType() == CSSSelector::PseudoCue) {
SelectorCheckingContext subContext(context);
subContext.isSubSelector = true;
subContext.behaviorAtBoundary = StaysWithinTreeScope;
- const CSSSelector* const & selector = context.selector;
- for (subContext.selector = selector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(subContext.selector)) {
+ const CSSSelector* contextSelector = context.selector;
+ ASSERT(contextSelector);
+ for (subContext.selector = contextSelector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
if (match(subContext, siblingTraversalStrategy) == SelectorMatches)
return true;
}
@@ -930,21 +1006,21 @@ bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const Sib
return true;
}
-bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& context, Document* document, const CSSSelector* selector) const
+bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& context, Document* document, const CSSSelector& selector) const
{
RenderScrollbar* scrollbar = context.scrollbar;
ScrollbarPart part = context.scrollbarPart;
// FIXME: This is a temporary hack for resizers and scrollbar corners. Eventually :window-inactive should become a real
// pseudo class and just apply to everything.
- if (selector->pseudoType() == CSSSelector::PseudoWindowInactive)
+ if (selector.pseudoType() == CSSSelector::PseudoWindowInactive)
return !document->page()->focusController().isActive();
if (!scrollbar)
return false;
- ASSERT(selector->m_match == CSSSelector::PseudoClass);
- switch (selector->pseudoType()) {
+ ASSERT(selector.match() == CSSSelector::PseudoClass);
+ switch (selector.pseudoType()) {
case CSSSelector::PseudoEnabled:
return scrollbar->enabled();
case CSSSelector::PseudoDisabled:
@@ -1011,19 +1087,19 @@ bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& c
}
}
-unsigned SelectorChecker::determineLinkMatchType(const CSSSelector* selector)
+unsigned SelectorChecker::determineLinkMatchType(const CSSSelector& selector)
{
unsigned linkMatchType = MatchAll;
// Statically determine if this selector will match a link in visited, unvisited or any state, or never.
// :visited never matches other elements than the innermost link element.
- for (; selector; selector = selector->tagHistory()) {
- switch (selector->pseudoType()) {
+ for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
+ switch (current->pseudoType()) {
case CSSSelector::PseudoNot:
{
// :not(:visited) is equivalent to :link. Parser enforces that :not can't nest.
- ASSERT(selector->selectorList());
- for (const CSSSelector* subSelector = selector->selectorList()->first(); subSelector; subSelector = subSelector->tagHistory()) {
+ ASSERT(current->selectorList());
+ for (const CSSSelector* subSelector = current->selectorList()->first(); subSelector; subSelector = subSelector->tagHistory()) {
CSSSelector::PseudoType subType = subSelector->pseudoType();
if (subType == CSSSelector::PseudoVisited)
linkMatchType &= ~SelectorChecker::MatchVisited;
@@ -1042,7 +1118,7 @@ unsigned SelectorChecker::determineLinkMatchType(const CSSSelector* selector)
// We don't support :link and :visited inside :-webkit-any.
break;
}
- CSSSelector::Relation relation = selector->relation();
+ CSSSelector::Relation relation = current->relation();
if (relation == CSSSelector::SubSelector)
continue;
if (relation != CSSSelector::Descendant && relation != CSSSelector::Child)
diff --git a/chromium/third_party/WebKit/Source/core/css/SelectorChecker.h b/chromium/third_party/WebKit/Source/core/css/SelectorChecker.h
index 13d7d7dc1fc..55fddb9b942 100644
--- a/chromium/third_party/WebKit/Source/core/css/SelectorChecker.h
+++ b/chromium/third_party/WebKit/Source/core/css/SelectorChecker.h
@@ -49,26 +49,22 @@ public:
explicit SelectorChecker(Document&, Mode);
enum BehaviorAtBoundary {
DoesNotCrossBoundary = 0,
- CrossesBoundary = 1,
+ // FIXME: refactor to remove BoundaryBehavior (i.e. DoesNotCrossBoundary and StaysWithinTreeScope).
StaysWithinTreeScope = 2,
BoundaryBehaviorMask = 3, // 2bit for boundary behavior
ScopeContainsLastMatchedElement = 4,
- ScopeIsShadowHost = 8,
+ ScopeIsShadowRoot = 8,
TreatShadowHostAsNormalScope = 16,
- ScopeIsShadowHostInPseudoHostParameter = CrossesBoundary | ScopeIsShadowHost | TreatShadowHostAsNormalScope
- };
-
- enum MatchingTagType {
- MatchingElement = 0,
- MatchingHostInItsShadowTree
+ ScopeIsShadowHostInPseudoHostParameter = ScopeIsShadowRoot | TreatShadowHostAsNormalScope
};
struct SelectorCheckingContext {
// Initial selector constructor
- SelectorCheckingContext(const CSSSelector* selector, Element* element, VisitedMatchType visitedMatchType)
- : selector(selector)
+ SelectorCheckingContext(const CSSSelector& selector, Element* element, VisitedMatchType visitedMatchType)
+ : selector(&selector)
, element(element)
+ , previousElement(0)
, scope(0)
, visitedMatchType(visitedMatchType)
, pseudoId(NOPSEUDO)
@@ -83,6 +79,7 @@ public:
const CSSSelector* selector;
Element* element;
+ Element* previousElement;
const ContainerNode* scope;
VisitedMatchType visitedMatchType;
PseudoId pseudoId;
@@ -114,13 +111,13 @@ public:
Mode mode() const { return m_mode; }
- static bool tagMatches(const Element&, const QualifiedName&, MatchingTagType = MatchingElement);
- static bool isCommonPseudoClassSelector(const CSSSelector*);
+ static bool tagMatches(const Element&, const QualifiedName&);
+ static bool isCommonPseudoClassSelector(const CSSSelector&);
static bool matchesFocusPseudoClass(const Element&);
static bool checkExactAttribute(const Element&, const QualifiedName& selectorAttributeName, const StringImpl* value);
enum LinkMatchMask { MatchLink = 1, MatchVisited = 2, MatchAll = MatchLink | MatchVisited };
- static unsigned determineLinkMatchType(const CSSSelector*);
+ static unsigned determineLinkMatchType(const CSSSelector&);
static bool isHostInItsShadowTree(const Element&, BehaviorAtBoundary, const ContainerNode* scope);
@@ -131,9 +128,11 @@ private:
Match matchForRelation(const SelectorCheckingContext&, const SiblingTraversalStrategy&, MatchResult*) const;
template<typename SiblingTraversalStrategy>
Match matchForShadowDistributed(const Element*, const SiblingTraversalStrategy&, SelectorCheckingContext& nextContext, MatchResult* = 0) const;
+ template<typename SiblingTraversalStrategy>
+ Match matchForPseudoShadow(const ContainerNode*, const SelectorCheckingContext&, const SiblingTraversalStrategy&, MatchResult*) const;
- bool checkScrollbarPseudoClass(const SelectorCheckingContext&, Document*, const CSSSelector*) const;
- Element* parentElement(const SelectorCheckingContext&) const;
+ bool checkScrollbarPseudoClass(const SelectorCheckingContext&, Document*, const CSSSelector&) const;
+ Element* parentElement(const SelectorCheckingContext&, bool allowToCrossBoundary = false) const;
bool scopeContainsLastMatchedElement(const SelectorCheckingContext&) const;
static bool isFrameFocused(const Element&);
@@ -143,23 +142,23 @@ private:
Mode m_mode;
};
-inline bool SelectorChecker::isCommonPseudoClassSelector(const CSSSelector* selector)
+inline bool SelectorChecker::isCommonPseudoClassSelector(const CSSSelector& selector)
{
- if (selector->m_match != CSSSelector::PseudoClass)
+ if (selector.match() != CSSSelector::PseudoClass)
return false;
- CSSSelector::PseudoType pseudoType = selector->pseudoType();
+ CSSSelector::PseudoType pseudoType = selector.pseudoType();
return pseudoType == CSSSelector::PseudoLink
|| pseudoType == CSSSelector::PseudoAnyLink
|| pseudoType == CSSSelector::PseudoVisited
|| pseudoType == CSSSelector::PseudoFocus;
}
-inline bool SelectorChecker::tagMatches(const Element& element, const QualifiedName& tagQName, MatchingTagType matchingTagType)
+inline bool SelectorChecker::tagMatches(const Element& element, const QualifiedName& tagQName)
{
if (tagQName == anyQName())
return true;
const AtomicString& localName = tagQName.localName();
- if (localName != starAtom && (localName != element.localName() || matchingTagType == MatchingHostInItsShadowTree))
+ if (localName != starAtom && localName != element.localName())
return false;
const AtomicString& namespaceURI = tagQName.namespaceURI();
return namespaceURI == starAtom || namespaceURI == element.namespaceURI();
@@ -169,10 +168,10 @@ inline bool SelectorChecker::checkExactAttribute(const Element& element, const Q
{
if (!element.hasAttributesWithoutUpdate())
return false;
- unsigned size = element.attributeCount();
- for (unsigned i = 0; i < size; ++i) {
- const Attribute* attribute = element.attributeItem(i);
- if (attribute->matches(selectorAttributeName) && (!value || attribute->value().impl() == value))
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->matches(selectorAttributeName) && (!value || it->value().impl() == value))
return true;
}
return false;
@@ -180,7 +179,7 @@ inline bool SelectorChecker::checkExactAttribute(const Element& element, const Q
inline bool SelectorChecker::isHostInItsShadowTree(const Element& element, BehaviorAtBoundary behaviorAtBoundary, const ContainerNode* scope)
{
- return (behaviorAtBoundary & (ScopeIsShadowHost | TreatShadowHostAsNormalScope)) == ScopeIsShadowHost && scope == element;
+ return scope && scope->isInShadowTree() && scope->shadowHost() == element;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp b/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp
deleted file mode 100644
index 557f0438a56..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
- * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
- * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/css/SelectorCheckerFastPath.h"
-
-#include "HTMLNames.h"
-#include "core/dom/Element.h"
-#include "core/html/HTMLDocument.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-namespace {
-
-template <bool checkValue(const Element&, const CSSSelector*)>
-inline bool fastCheckSingleSelector(const CSSSelector*& selector, const Element*& element, const CSSSelector*& topChildOrSubselector, const Element*& topChildOrSubselectorMatchElement)
-{
- for (; element; element = element->parentElement()) {
- if (checkValue(*element, selector)) {
- if (selector->relation() == CSSSelector::Descendant)
- topChildOrSubselector = 0;
- else if (!topChildOrSubselector) {
- ASSERT(selector->relation() == CSSSelector::Child || selector->relation() == CSSSelector::SubSelector);
- topChildOrSubselector = selector;
- topChildOrSubselectorMatchElement = element;
- }
- if (selector->relation() != CSSSelector::SubSelector)
- element = element->parentElement();
- selector = selector->tagHistory();
- return true;
- }
- if (topChildOrSubselector) {
- // Child or subselector check failed.
- // If the match element is null, topChildOrSubselector was also the very topmost selector and had to match
- // the original element we were checking.
- if (!topChildOrSubselectorMatchElement)
- return false;
- // There may be other matches down the ancestor chain.
- // Rewind to the topmost child or subselector and the element it matched, continue checking ancestors.
- selector = topChildOrSubselector;
- element = topChildOrSubselectorMatchElement->parentElement();
- topChildOrSubselector = 0;
- return true;
- }
- }
- return false;
-}
-
-inline bool checkClassValue(const Element& element, const CSSSelector* selector)
-{
- return element.hasClass() && element.classNames().contains(selector->value());
-}
-
-inline bool checkIDValue(const Element& element, const CSSSelector* selector)
-{
- return element.hasID() && element.idForStyleResolution() == selector->value();
-}
-
-inline bool checkExactAttributeValue(const Element& element, const CSSSelector* selector)
-{
- return SelectorChecker::checkExactAttribute(element, selector->attribute(), selector->value().impl());
-}
-
-inline bool checkTagValue(const Element& element, const CSSSelector* selector)
-{
- return SelectorChecker::tagMatches(element, selector->tagQName());
-}
-
-}
-
-SelectorCheckerFastPath::SelectorCheckerFastPath(const CSSSelector* selector, const Element& element)
- : m_selector(selector)
- , m_element(element)
-{
-}
-
-bool SelectorCheckerFastPath::matchesRightmostSelector(SelectorChecker::VisitedMatchType visitedMatchType) const
-{
- ASSERT(SelectorCheckerFastPath::canUse(m_selector));
-
- switch (m_selector->m_match) {
- case CSSSelector::Tag:
- return checkTagValue(m_element, m_selector);
- case CSSSelector::Class:
- return checkClassValue(m_element, m_selector);
- case CSSSelector::Id:
- return checkIDValue(m_element, m_selector);
- case CSSSelector::Exact:
- case CSSSelector::Set:
- return checkExactAttributeValue(m_element, m_selector);
- case CSSSelector::PseudoClass:
- return commonPseudoClassSelectorMatches(visitedMatchType);
- default:
- ASSERT_NOT_REACHED();
- }
- return false;
-}
-
-bool SelectorCheckerFastPath::matches() const
-{
- ASSERT(matchesRightmostSelector(SelectorChecker::VisitedMatchEnabled));
- const CSSSelector* selector = m_selector;
- const Element* element = &m_element;
-
- const CSSSelector* topChildOrSubselector = 0;
- const Element* topChildOrSubselectorMatchElement = 0;
- if (selector->relation() == CSSSelector::Child || selector->relation() == CSSSelector::SubSelector)
- topChildOrSubselector = selector;
-
- if (selector->relation() != CSSSelector::SubSelector)
- element = element->parentElement();
-
- selector = selector->tagHistory();
-
- // We know this compound selector has descendant, child and subselector combinators only and all components are simple.
- while (selector) {
- switch (selector->m_match) {
- case CSSSelector::Class:
- if (!fastCheckSingleSelector<checkClassValue>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement))
- return false;
- break;
- case CSSSelector::Id:
- if (!fastCheckSingleSelector<checkIDValue>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement))
- return false;
- break;
- case CSSSelector::Tag:
- if (!fastCheckSingleSelector<checkTagValue>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement))
- return false;
- break;
- case CSSSelector::Set:
- case CSSSelector::Exact:
- if (!fastCheckSingleSelector<checkExactAttributeValue>(selector, element, topChildOrSubselector, topChildOrSubselectorMatchElement))
- return false;
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
- return true;
-}
-
-static inline bool isFastCheckableRelation(CSSSelector::Relation relation)
-{
- return relation == CSSSelector::Descendant || relation == CSSSelector::Child || relation == CSSSelector::SubSelector;
-}
-
-static inline bool isFastCheckableMatch(const CSSSelector* selector)
-{
- if (selector->m_match == CSSSelector::Set) {
- // Style attribute is generated lazily but the fast path doesn't trigger it.
- // Disallow them here rather than making the fast path more branchy.
- return selector->attribute() != styleAttr;
- }
- if (selector->m_match == CSSSelector::Exact)
- return selector->attribute() != styleAttr && HTMLDocument::isCaseSensitiveAttribute(selector->attribute());
- return selector->m_match == CSSSelector::Tag || selector->m_match == CSSSelector::Id || selector->m_match == CSSSelector::Class;
-}
-
-static inline bool isFastCheckableRightmostSelector(const CSSSelector* selector)
-{
- if (!isFastCheckableRelation(selector->relation()))
- return false;
- return isFastCheckableMatch(selector) || SelectorChecker::isCommonPseudoClassSelector(selector);
-}
-
-bool SelectorCheckerFastPath::canUse(const CSSSelector* selector)
-{
- if (!isFastCheckableRightmostSelector(selector))
- return false;
- for (selector = selector->tagHistory(); selector; selector = selector->tagHistory()) {
- if (!isFastCheckableRelation(selector->relation()))
- return false;
- if (!isFastCheckableMatch(selector))
- return false;
- }
- return true;
-}
-
-bool SelectorCheckerFastPath::commonPseudoClassSelectorMatches(SelectorChecker::VisitedMatchType visitedMatchType) const
-{
- ASSERT(SelectorChecker::isCommonPseudoClassSelector(m_selector));
- switch (m_selector->pseudoType()) {
- case CSSSelector::PseudoLink:
- case CSSSelector::PseudoAnyLink:
- return m_element.isLink();
- case CSSSelector::PseudoVisited:
- return m_element.isLink() && visitedMatchType == SelectorChecker::VisitedMatchEnabled;
- case CSSSelector::PseudoFocus:
- return SelectorChecker::matchesFocusPseudoClass(m_element);
- default:
- ASSERT_NOT_REACHED();
- }
- return true;
-}
-
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.h b/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.h
deleted file mode 100644
index 1a37b9ac35a..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/SelectorCheckerFastPath.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
- * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
- * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SelectorCheckerFastPath_h
-#define SelectorCheckerFastPath_h
-
-#include "core/css/CSSSelector.h"
-#include "core/css/SelectorChecker.h"
-
-namespace WebCore {
-
-class SelectorCheckerFastPath {
-public:
- SelectorCheckerFastPath(const CSSSelector*, const Element&);
-
- bool matches() const;
- bool matchesRightmostSelector(SelectorChecker::VisitedMatchType) const;
- bool matchesRightmostAttributeSelector() const;
-
- static bool canUse(const CSSSelector*);
-
-private:
- bool commonPseudoClassSelectorMatches(SelectorChecker::VisitedMatchType) const;
-
- const CSSSelector* m_selector;
- const Element& m_element;
-};
-
-inline bool SelectorCheckerFastPath::matchesRightmostAttributeSelector() const
-{
- if (m_selector->m_match == CSSSelector::Exact || m_selector->m_match == CSSSelector::Set)
- return SelectorChecker::checkExactAttribute(m_element, m_selector->attribute(), m_selector->value().impl());
- ASSERT(!m_selector->isAttributeSelector());
- return true;
-}
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/SelectorFilter.cpp b/chromium/third_party/WebKit/Source/core/css/SelectorFilter.cpp
index 50d13de6b48..c0c6a97a16a 100644
--- a/chromium/third_party/WebKit/Source/core/css/SelectorFilter.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/SelectorFilter.cpp
@@ -108,45 +108,44 @@ void SelectorFilter::pushParent(Element& parent)
pushParentStackFrame(parent);
}
-static inline void collectDescendantSelectorIdentifierHashes(const CSSSelector* selector, unsigned*& hash)
+static inline void collectDescendantSelectorIdentifierHashes(const CSSSelector& selector, unsigned*& hash)
{
- switch (selector->m_match) {
+ switch (selector.match()) {
case CSSSelector::Id:
- if (!selector->value().isEmpty())
- (*hash++) = selector->value().impl()->existingHash() * IdAttributeSalt;
+ if (!selector.value().isEmpty())
+ (*hash++) = selector.value().impl()->existingHash() * IdAttributeSalt;
break;
case CSSSelector::Class:
- if (!selector->value().isEmpty())
- (*hash++) = selector->value().impl()->existingHash() * ClassAttributeSalt;
+ if (!selector.value().isEmpty())
+ (*hash++) = selector.value().impl()->existingHash() * ClassAttributeSalt;
break;
case CSSSelector::Tag:
- if (selector->tagQName().localName() != starAtom)
- (*hash++) = selector->tagQName().localName().impl()->existingHash() * TagNameSalt;
+ if (selector.tagQName().localName() != starAtom)
+ (*hash++) = selector.tagQName().localName().impl()->existingHash() * TagNameSalt;
break;
default:
break;
}
}
-void SelectorFilter::collectIdentifierHashes(const CSSSelector* selector, unsigned* identifierHashes, unsigned maximumIdentifierCount)
+void SelectorFilter::collectIdentifierHashes(const CSSSelector& selector, unsigned* identifierHashes, unsigned maximumIdentifierCount)
{
unsigned* hash = identifierHashes;
unsigned* end = identifierHashes + maximumIdentifierCount;
- CSSSelector::Relation relation = selector->relation();
- bool relationIsAffectedByPseudoContent = selector->relationIsAffectedByPseudoContent();
+ CSSSelector::Relation relation = selector.relation();
+ bool relationIsAffectedByPseudoContent = selector.relationIsAffectedByPseudoContent();
// Skip the topmost selector. It is handled quickly by the rule hashes.
bool skipOverSubselectors = true;
- for (selector = selector->tagHistory(); selector; selector = selector->tagHistory()) {
+ for (const CSSSelector* current = selector.tagHistory(); current; current = current->tagHistory()) {
// Only collect identifiers that match ancestors.
switch (relation) {
case CSSSelector::SubSelector:
if (!skipOverSubselectors)
- collectDescendantSelectorIdentifierHashes(selector, hash);
+ collectDescendantSelectorIdentifierHashes(*current, hash);
break;
case CSSSelector::DirectAdjacent:
case CSSSelector::IndirectAdjacent:
- case CSSSelector::ShadowPseudo:
skipOverSubselectors = true;
break;
case CSSSelector::Descendant:
@@ -157,16 +156,16 @@ void SelectorFilter::collectIdentifierHashes(const CSSSelector* selector, unsign
return;
}
// Fall through.
- case CSSSelector::ChildTree:
- case CSSSelector::DescendantTree:
+ case CSSSelector::ShadowPseudo:
+ case CSSSelector::ShadowDeep:
skipOverSubselectors = false;
- collectDescendantSelectorIdentifierHashes(selector, hash);
+ collectDescendantSelectorIdentifierHashes(*current, hash);
break;
}
if (hash == end)
return;
- relation = selector->relation();
- relationIsAffectedByPseudoContent = selector->relationIsAffectedByPseudoContent();
+ relation = current->relation();
+ relationIsAffectedByPseudoContent = current->relationIsAffectedByPseudoContent();
}
*hash = 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/css/SelectorFilter.h b/chromium/third_party/WebKit/Source/core/css/SelectorFilter.h
index 905edb6dd30..8a2e85280c1 100644
--- a/chromium/third_party/WebKit/Source/core/css/SelectorFilter.h
+++ b/chromium/third_party/WebKit/Source/core/css/SelectorFilter.h
@@ -50,7 +50,7 @@ public:
template <unsigned maximumIdentifierCount>
inline bool fastRejectSelector(const unsigned* identifierHashes) const;
- static void collectIdentifierHashes(const CSSSelector*, unsigned* identifierHashes, unsigned maximumIdentifierCount);
+ static void collectIdentifierHashes(const CSSSelector&, unsigned* identifierHashes, unsigned maximumIdentifierCount);
private:
struct ParentStackFrame {
diff --git a/chromium/third_party/WebKit/Source/core/css/SiblingTraversalStrategies.h b/chromium/third_party/WebKit/Source/core/css/SiblingTraversalStrategies.h
index b082fa6df0e..dce3c41af18 100644
--- a/chromium/third_party/WebKit/Source/core/css/SiblingTraversalStrategies.h
+++ b/chromium/third_party/WebKit/Source/core/css/SiblingTraversalStrategies.h
@@ -30,63 +30,64 @@
#define SiblingTraversalStrategies_h
#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
#include "core/rendering/style/RenderStyle.h"
namespace WebCore {
struct DOMSiblingTraversalStrategy {
- bool isFirstChild(Element*) const;
- bool isLastChild(Element*) const;
- bool isFirstOfType(Element*, const QualifiedName&) const;
- bool isLastOfType(Element*, const QualifiedName&) const;
-
- int countElementsBefore(Element*) const;
- int countElementsAfter(Element*) const;
- int countElementsOfTypeBefore(Element*, const QualifiedName&) const;
- int countElementsOfTypeAfter(Element*, const QualifiedName&) const;
+ bool isFirstChild(Element&) const;
+ bool isLastChild(Element&) const;
+ bool isFirstOfType(Element&, const QualifiedName&) const;
+ bool isLastOfType(Element&, const QualifiedName&) const;
+
+ int countElementsBefore(Element&) const;
+ int countElementsAfter(Element&) const;
+ int countElementsOfTypeBefore(Element&, const QualifiedName&) const;
+ int countElementsOfTypeAfter(Element&, const QualifiedName&) const;
};
-inline bool DOMSiblingTraversalStrategy::isFirstChild(Element* element) const
+inline bool DOMSiblingTraversalStrategy::isFirstChild(Element& element) const
{
- return !element->previousElementSibling();
+ return !ElementTraversal::previousSibling(element);
}
-inline bool DOMSiblingTraversalStrategy::isLastChild(Element* element) const
+inline bool DOMSiblingTraversalStrategy::isLastChild(Element& element) const
{
- return !element->nextElementSibling();
+ return !ElementTraversal::nextSibling(element);
}
-inline bool DOMSiblingTraversalStrategy::isFirstOfType(Element* element, const QualifiedName& type) const
+inline bool DOMSiblingTraversalStrategy::isFirstOfType(Element& element, const QualifiedName& type) const
{
- for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) {
+ for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
if (sibling->hasTagName(type))
return false;
}
return true;
}
-inline bool DOMSiblingTraversalStrategy::isLastOfType(Element* element, const QualifiedName& type) const
+inline bool DOMSiblingTraversalStrategy::isLastOfType(Element& element, const QualifiedName& type) const
{
- for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) {
+ for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {
if (sibling->hasTagName(type))
return false;
}
return true;
}
-inline int DOMSiblingTraversalStrategy::countElementsBefore(Element* element) const
+inline int DOMSiblingTraversalStrategy::countElementsBefore(Element& element) const
{
int count = 0;
- for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling())
+ for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling))
count++;
return count;
}
-inline int DOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element* element, const QualifiedName& type) const
+inline int DOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element& element, const QualifiedName& type) const
{
int count = 0;
- for (const Element* sibling = element->previousElementSibling(); sibling; sibling = sibling->previousElementSibling()) {
+ for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
if (sibling->hasTagName(type))
++count;
}
@@ -94,19 +95,19 @@ inline int DOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element* eleme
return count;
}
-inline int DOMSiblingTraversalStrategy::countElementsAfter(Element* element) const
+inline int DOMSiblingTraversalStrategy::countElementsAfter(Element& element) const
{
int count = 0;
- for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling())
+ for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling))
++count;
return count;
}
-inline int DOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element* element, const QualifiedName& type) const
+inline int DOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element& element, const QualifiedName& type) const
{
int count = 0;
- for (const Element* sibling = element->nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) {
+ for (const Element* sibling = ElementTraversal::nextSibling(element); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {
if (sibling->hasTagName(type))
++count;
}
@@ -114,29 +115,31 @@ inline int DOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element* elemen
return count;
}
-struct ShadowDOMSiblingTraversalStrategy {
- ShadowDOMSiblingTraversalStrategy(const Vector<Node*, 32>& siblings, int nth)
+class ShadowDOMSiblingTraversalStrategy FINAL {
+ STACK_ALLOCATED();
+public:
+ ShadowDOMSiblingTraversalStrategy(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth)
: m_siblings(siblings)
, m_nth(nth)
{
}
- bool isFirstChild(Element*) const;
- bool isLastChild(Element*) const;
- bool isFirstOfType(Element*, const QualifiedName&) const;
- bool isLastOfType(Element*, const QualifiedName&) const;
+ bool isFirstChild(Element&) const;
+ bool isLastChild(Element&) const;
+ bool isFirstOfType(Element&, const QualifiedName&) const;
+ bool isLastOfType(Element&, const QualifiedName&) const;
- int countElementsBefore(Element*) const;
- int countElementsAfter(Element*) const;
- int countElementsOfTypeBefore(Element*, const QualifiedName&) const;
- int countElementsOfTypeAfter(Element*, const QualifiedName&) const;
+ int countElementsBefore(Element&) const;
+ int countElementsAfter(Element&) const;
+ int countElementsOfTypeBefore(Element&, const QualifiedName&) const;
+ int countElementsOfTypeAfter(Element&, const QualifiedName&) const;
private:
- const Vector<Node*, 32>& m_siblings;
+ const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& m_siblings;
int m_nth;
};
-inline bool ShadowDOMSiblingTraversalStrategy::isFirstChild(Element* element) const
+inline bool ShadowDOMSiblingTraversalStrategy::isFirstChild(Element& element) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
@@ -148,7 +151,7 @@ inline bool ShadowDOMSiblingTraversalStrategy::isFirstChild(Element* element) co
return true;
}
-inline bool ShadowDOMSiblingTraversalStrategy::isLastChild(Element* element) const
+inline bool ShadowDOMSiblingTraversalStrategy::isLastChild(Element& element) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
@@ -160,7 +163,7 @@ inline bool ShadowDOMSiblingTraversalStrategy::isLastChild(Element* element) con
return true;
}
-inline bool ShadowDOMSiblingTraversalStrategy::isFirstOfType(Element* element, const QualifiedName& type) const
+inline bool ShadowDOMSiblingTraversalStrategy::isFirstOfType(Element& element, const QualifiedName& type) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
@@ -172,7 +175,7 @@ inline bool ShadowDOMSiblingTraversalStrategy::isFirstOfType(Element* element, c
return true;
}
-inline bool ShadowDOMSiblingTraversalStrategy::isLastOfType(Element* element, const QualifiedName& type) const
+inline bool ShadowDOMSiblingTraversalStrategy::isLastOfType(Element& element, const QualifiedName& type) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
@@ -184,7 +187,7 @@ inline bool ShadowDOMSiblingTraversalStrategy::isLastOfType(Element* element, co
return true;
}
-inline int ShadowDOMSiblingTraversalStrategy::countElementsBefore(Element* element) const
+inline int ShadowDOMSiblingTraversalStrategy::countElementsBefore(Element& element) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
@@ -197,7 +200,7 @@ inline int ShadowDOMSiblingTraversalStrategy::countElementsBefore(Element* eleme
return count;
}
-inline int ShadowDOMSiblingTraversalStrategy::countElementsAfter(Element* element) const
+inline int ShadowDOMSiblingTraversalStrategy::countElementsAfter(Element& element) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
@@ -210,7 +213,7 @@ inline int ShadowDOMSiblingTraversalStrategy::countElementsAfter(Element* elemen
return count;
}
-inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element* element, const QualifiedName& type) const
+inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element& element, const QualifiedName& type) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
@@ -223,7 +226,7 @@ inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeBefore(Element*
return count;
}
-inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element* element, const QualifiedName& type) const
+inline int ShadowDOMSiblingTraversalStrategy::countElementsOfTypeAfter(Element& element, const QualifiedName& type) const
{
ASSERT(element == toElement(m_siblings[m_nth]));
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleColor.h b/chromium/third_party/WebKit/Source/core/css/StyleColor.h
index 1f58584f9a9..3c26609cb20 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleColor.h
+++ b/chromium/third_party/WebKit/Source/core/css/StyleColor.h
@@ -32,79 +32,30 @@
#define StyleColor_h
#include "platform/graphics/Color.h"
-#include "wtf/FastAllocBase.h"
namespace WebCore {
class StyleColor {
- WTF_MAKE_FAST_ALLOCATED;
public:
- StyleColor()
- : m_color()
- , m_valid(false)
- , m_currentColor(false) { }
- StyleColor(Color color)
- : m_color(color)
- , m_valid(true)
- , m_currentColor(false) { }
- StyleColor(RGBA32 color, bool valid = true, bool currentColor = false)
- : m_color(color)
- , m_valid(valid)
- , m_currentColor(currentColor) { }
- StyleColor(int r, int g, int b)
- : m_color(Color(r, g, b))
- , m_valid(true)
- , m_currentColor(false) { }
- StyleColor(int r, int g, int b, int a)
- : m_color(Color(r, g, b, a))
- , m_valid(true)
- , m_currentColor(false) { }
- StyleColor(const StyleColor& other)
- : m_color(other.m_color)
- , m_valid(other.m_valid)
- , m_currentColor(other.m_currentColor) { }
+ StyleColor(Color color) : m_color(color), m_currentColor(false) { }
+ static StyleColor currentColor() { return StyleColor(); }
- Color color() const { return m_color; }
- bool isValid() const { return m_valid; }
bool isCurrentColor() const { return m_currentColor; }
- bool hasAlpha() const { return m_color.hasAlpha(); }
+ Color color() const { ASSERT(!isCurrentColor()); return m_color; }
- void setRGB(int r, int g, int b)
- {
- m_color.setRGB(r, g, b);
- m_valid = true;
- m_currentColor = false;
- }
-
- RGBA32 rgb() const { return m_color.rgb(); } // Preserve the alpha.
- int red() const { return m_color.red(); }
- int green() const { return m_color.green(); }
- int blue() const { return m_color.blue(); }
- int alpha() const { return m_color.alpha(); }
-
- static const StyleColor invalid()
- {
- return StyleColor(false, false);
- }
- static const StyleColor currentColor()
- {
- return StyleColor(true, true);
- }
+ Color resolve(Color currentColor) const { return m_currentColor ? currentColor : m_color; }
private:
- StyleColor(bool invalid, bool currentColor)
- : m_color()
- , m_valid(invalid)
- , m_currentColor(currentColor) { }
-
+ StyleColor() : m_currentColor(true) { }
Color m_color;
- bool m_valid;
bool m_currentColor;
};
inline bool operator==(const StyleColor& a, const StyleColor& b)
{
- return a.rgb() == b.rgb() && a.isValid() == b.isValid() && a.isCurrentColor() == b.isCurrentColor();
+ if (a.isCurrentColor() || b.isCurrentColor())
+ return a.isCurrentColor() && b.isCurrentColor();
+ return a.color() == b.color();
}
inline bool operator!=(const StyleColor& a, const StyleColor& b)
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleInvalidationAnalysis.cpp b/chromium/third_party/WebKit/Source/core/css/StyleInvalidationAnalysis.cpp
deleted file mode 100644
index 440e17fe346..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/StyleInvalidationAnalysis.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/css/StyleInvalidationAnalysis.h"
-
-#include "core/css/CSSSelectorList.h"
-#include "core/css/StyleRuleImport.h"
-#include "core/css/StyleSheetContents.h"
-#include "core/dom/ContainerNode.h"
-#include "core/dom/Document.h"
-#include "core/dom/ElementTraversal.h"
-#include "core/dom/shadow/ShadowRoot.h"
-#include "core/html/HTMLStyleElement.h"
-
-namespace WebCore {
-
-StyleInvalidationAnalysis::StyleInvalidationAnalysis(const Vector<StyleSheetContents*>& sheets)
- : m_dirtiesAllStyle(false)
-{
- for (unsigned i = 0; i < sheets.size() && !m_dirtiesAllStyle; ++i)
- analyzeStyleSheet(sheets[i]);
-}
-
-static bool determineSelectorScopes(const CSSSelectorList& selectorList, HashSet<StringImpl*>& idScopes, HashSet<StringImpl*>& classScopes)
-{
- for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
- const CSSSelector* scopeSelector = 0;
- // This picks the widest scope, not the narrowest, to minimize the number of found scopes.
- for (const CSSSelector* current = selector; current; current = current->tagHistory()) {
- // Prefer ids over classes.
- if (current->m_match == CSSSelector::Id)
- scopeSelector = current;
- else if (current->m_match == CSSSelector::Class && (!scopeSelector || scopeSelector->m_match != CSSSelector::Id))
- scopeSelector = current;
- CSSSelector::Relation relation = current->relation();
- if (relation != CSSSelector::Descendant && relation != CSSSelector::Child && relation != CSSSelector::SubSelector)
- break;
- }
- if (!scopeSelector)
- return false;
- ASSERT(scopeSelector->m_match == CSSSelector::Class || scopeSelector->m_match == CSSSelector::Id);
- if (scopeSelector->m_match == CSSSelector::Id)
- idScopes.add(scopeSelector->value().impl());
- else
- classScopes.add(scopeSelector->value().impl());
- }
- return true;
-}
-
-static bool hasDistributedRule(StyleSheetContents* styleSheetContents)
-{
- const Vector<RefPtr<StyleRuleBase> >& rules = styleSheetContents->childRules();
- for (unsigned i = 0; i < rules.size(); i++) {
- const StyleRuleBase* rule = rules[i].get();
- if (!rule->isStyleRule())
- continue;
-
- const StyleRule* styleRule = toStyleRule(rule);
- const CSSSelectorList& selectorList = styleRule->selectorList();
- for (size_t selectorIndex = 0; selectorIndex != kNotFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) {
- if (selectorList.hasShadowDistributedAt(selectorIndex))
- return true;
- }
- }
- return false;
-}
-
-static Node* determineScopingNodeForStyleScoped(HTMLStyleElement* ownerElement, StyleSheetContents* styleSheetContents)
-{
- ASSERT(ownerElement && ownerElement->isRegisteredAsScoped());
-
- if (ownerElement->isInShadowTree()) {
- if (hasDistributedRule(styleSheetContents)) {
- ContainerNode* scope = ownerElement;
- do {
- scope = scope->containingShadowRoot()->shadowHost();
- } while (scope->isInShadowTree());
-
- return scope;
- }
- if (ownerElement->isRegisteredAsScoped())
- return ownerElement->containingShadowRoot()->shadowHost();
- }
-
- return ownerElement->isRegisteredInShadowRoot() ? ownerElement->containingShadowRoot()->shadowHost() : ownerElement->parentNode();
-}
-
-static bool ruleAdditionMightRequireDocumentStyleRecalc(StyleRuleBase* rule)
-{
- // This funciton is conservative. We only return false when we know that
- // the added @rule can't require style recalcs.
- switch (rule->type()) {
- case StyleRule::Import: // Whatever we import should do its own analysis, we don't need to invalidate the document here!
- case StyleRule::Keyframes: // Keyframes never cause style invalidations and are handled during sheet insertion.
- case StyleRule::Page: // Page rules apply only during printing, we force a full-recalc before printing.
- return false;
-
- case StyleRule::Media: // If the media rule doesn't apply, we could avoid recalc.
- case StyleRule::FontFace: // If the fonts aren't in use, we could avoid recalc.
- case StyleRule::Supports: // If we evaluated the supports-clause we could avoid recalc.
- case StyleRule::Viewport: // If the viewport doesn't match, we could avoid recalcing.
- // FIXME: Unclear if any of the rest need to cause style recalc:
- case StyleRule::Region:
- case StyleRule::Filter:
- return true;
-
- // These should all be impossible to reach:
- case StyleRule::Unknown:
- case StyleRule::Charset:
- case StyleRule::Keyframe:
- case StyleRule::Style:
- break;
- }
- ASSERT_NOT_REACHED();
- return true;
-}
-
-void StyleInvalidationAnalysis::analyzeStyleSheet(StyleSheetContents* styleSheetContents)
-{
- ASSERT(!styleSheetContents->isLoading());
-
- // See if all rules on the sheet are scoped to some specific ids or classes.
- // Then test if we actually have any of those in the tree at the moment.
- const Vector<RefPtr<StyleRuleImport> >& importRules = styleSheetContents->importRules();
- for (unsigned i = 0; i < importRules.size(); ++i) {
- if (!importRules[i]->styleSheet())
- continue;
- analyzeStyleSheet(importRules[i]->styleSheet());
- if (m_dirtiesAllStyle)
- return;
- }
- if (styleSheetContents->hasSingleOwnerNode()) {
- Node* ownerNode = styleSheetContents->singleOwnerNode();
- if (ownerNode && ownerNode->hasTagName(HTMLNames::styleTag) && toHTMLStyleElement(ownerNode)->isRegisteredAsScoped()) {
- m_scopingNodes.append(determineScopingNodeForStyleScoped(toHTMLStyleElement(ownerNode), styleSheetContents));
- return;
- }
- }
-
- const Vector<RefPtr<StyleRuleBase> >& rules = styleSheetContents->childRules();
- for (unsigned i = 0; i < rules.size(); i++) {
- StyleRuleBase* rule = rules[i].get();
- if (!rule->isStyleRule()) {
- if (ruleAdditionMightRequireDocumentStyleRecalc(rule)) {
- m_dirtiesAllStyle = true;
- return;
- }
- continue;
- }
- StyleRule* styleRule = toStyleRule(rule);
- if (!determineSelectorScopes(styleRule->selectorList(), m_idScopes, m_classScopes)) {
- m_dirtiesAllStyle = true;
- return;
- }
- }
-}
-
-static bool elementMatchesSelectorScopes(const Element* element, const HashSet<StringImpl*>& idScopes, const HashSet<StringImpl*>& classScopes)
-{
- if (!idScopes.isEmpty() && element->hasID() && idScopes.contains(element->idForStyleResolution().impl()))
- return true;
- if (classScopes.isEmpty() || !element->hasClass())
- return false;
- const SpaceSplitString& classNames = element->classNames();
- for (unsigned i = 0; i < classNames.size(); ++i) {
- if (classScopes.contains(classNames[i].impl()))
- return true;
- }
- return false;
-}
-
-void StyleInvalidationAnalysis::invalidateStyle(Document& document)
-{
- ASSERT(!m_dirtiesAllStyle);
-
- if (!m_scopingNodes.isEmpty()) {
- for (unsigned i = 0; i < m_scopingNodes.size(); ++i)
- m_scopingNodes.at(i)->setNeedsStyleRecalc();
- }
-
- if (m_idScopes.isEmpty() && m_classScopes.isEmpty())
- return;
- Element* element = ElementTraversal::firstWithin(document);
- while (element) {
- if (elementMatchesSelectorScopes(element, m_idScopes, m_classScopes)) {
- element->setNeedsStyleRecalc();
- // The whole subtree is now invalidated, we can skip to the next sibling.
- element = ElementTraversal::nextSkippingChildren(*element);
- continue;
- }
- element = ElementTraversal::next(*element);
- }
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleInvalidationAnalysis.h b/chromium/third_party/WebKit/Source/core/css/StyleInvalidationAnalysis.h
deleted file mode 100644
index 79cf3d87bda..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/StyleInvalidationAnalysis.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef StyleInvalidationAnalysis_h
-#define StyleInvalidationAnalysis_h
-
-#include "wtf/HashSet.h"
-#include "wtf/Vector.h"
-#include "wtf/text/StringImpl.h"
-
-namespace WebCore {
-
-class Document;
-class Node;
-class StyleSheetContents;
-
-class StyleInvalidationAnalysis {
-public:
- StyleInvalidationAnalysis(const Vector<StyleSheetContents*>&);
-
- bool dirtiesAllStyle() const { return m_dirtiesAllStyle; }
- void invalidateStyle(Document&);
-
-private:
-
- void analyzeStyleSheet(StyleSheetContents*);
-
- bool m_dirtiesAllStyle;
- HashSet<StringImpl*> m_idScopes;
- HashSet<StringImpl*> m_classScopes;
- Vector<Node*, 8> m_scopingNodes;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleMedia.cpp b/chromium/third_party/WebKit/Source/core/css/StyleMedia.cpp
index 791ef27328f..c18d26c592c 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleMedia.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/StyleMedia.cpp
@@ -28,14 +28,13 @@
#include "core/css/MediaList.h"
#include "core/css/MediaQueryEvaluator.h"
-#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-StyleMedia::StyleMedia(Frame* frame)
+StyleMedia::StyleMedia(LocalFrame* frame)
: DOMWindowProperty(frame)
{
}
@@ -60,14 +59,11 @@ bool StyleMedia::matchMedium(const String& query) const
if (!documentElement)
return false;
- StyleResolver& styleResolver = document->ensureStyleResolver();
- RefPtr<RenderStyle> rootStyle = styleResolver.styleForElement(documentElement, 0 /*defaultParent*/, DisallowStyleSharing, MatchOnlyUserAgentRules);
-
- RefPtr<MediaQuerySet> media = MediaQuerySet::create();
+ RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create();
if (!media->set(query))
return false;
- MediaQueryEvaluator screenEval(type(), m_frame, rootStyle.get());
+ MediaQueryEvaluator screenEval(type(), m_frame);
return screenEval.eval(media.get());
}
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleMedia.h b/chromium/third_party/WebKit/Source/core/css/StyleMedia.h
index e2cd69be117..c08bd104930 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleMedia.h
+++ b/chromium/third_party/WebKit/Source/core/css/StyleMedia.h
@@ -28,22 +28,25 @@
#define StyleMedia_h
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
-class StyleMedia : public RefCounted<StyleMedia>, public DOMWindowProperty {
+class StyleMedia : public RefCountedWillBeGarbageCollectedFinalized<StyleMedia>, public DOMWindowProperty {
public:
- static PassRefPtr<StyleMedia> create(Frame* frame) { return adoptRef(new StyleMedia(frame));}
+ static PassRefPtrWillBeRawPtr<StyleMedia> create(LocalFrame* frame) { return adoptRefWillBeNoop(new StyleMedia(frame));}
AtomicString type() const;
bool matchMedium(const String&) const;
+ void trace(Visitor*) { }
+
private:
- explicit StyleMedia(Frame*);
+ explicit StyleMedia(LocalFrame*);
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleMedia.idl b/chromium/third_party/WebKit/Source/core/css/StyleMedia.idl
index 370eee8f913..b897eb0690b 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleMedia.idl
+++ b/chromium/third_party/WebKit/Source/core/css/StyleMedia.idl
@@ -25,7 +25,8 @@
*/
[
- NoInterfaceObject
+ NoInterfaceObject,
+ WillBeGarbageCollected
] interface StyleMedia {
readonly attribute DOMString type;
boolean matchMedium([Default=Undefined] optional DOMString mediaquery);
diff --git a/chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp b/chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
index 825781430ab..4d00705a09c 100644
--- a/chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.cpp
@@ -23,14 +23,12 @@
#include "config.h"
#include "core/css/StylePropertySerializer.h"
-#include "CSSValueKeywords.h"
-#include "StylePropertyShorthand.h"
+#include "core/CSSValueKeywords.h"
+#include "core/StylePropertyShorthand.h"
#include "core/css/RuntimeCSSEnabled.h"
#include "wtf/BitArray.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
static bool isInitialOrInherit(const String& value)
@@ -45,14 +43,23 @@ StylePropertySerializer::StylePropertySerializer(const StylePropertySet& propert
{
}
-String StylePropertySerializer::asText() const
+String StylePropertySerializer::getPropertyText(CSSPropertyID propertyID, const String& value, bool isImportant, bool isNotFirstDecl) const
{
StringBuilder result;
+ if (isNotFirstDecl)
+ result.append(' ');
+ result.append(getPropertyName(propertyID));
+ result.appendLiteral(": ");
+ result.append(value);
+ if (isImportant)
+ result.appendLiteral(" !important");
+ result.append(';');
+ return result.toString();
+}
- int positionXPropertyIndex = -1;
- int positionYPropertyIndex = -1;
- int repeatXPropertyIndex = -1;
- int repeatYPropertyIndex = -1;
+String StylePropertySerializer::asText() const
+{
+ StringBuilder result;
BitArray<numCSSProperties> shorthandPropertyUsed;
BitArray<numCSSProperties> shorthandPropertyAppeared;
@@ -69,22 +76,17 @@ String StylePropertySerializer::asText() const
String value;
switch (propertyID) {
- case CSSPropertyVariable:
- if (numDecls++)
- result.append(' ');
- result.append(property.cssText());
- continue;
+ case CSSPropertyBackgroundAttachment:
+ case CSSPropertyBackgroundClip:
+ case CSSPropertyBackgroundColor:
+ case CSSPropertyBackgroundImage:
+ case CSSPropertyBackgroundOrigin:
case CSSPropertyBackgroundPositionX:
- positionXPropertyIndex = n;
- continue;
case CSSPropertyBackgroundPositionY:
- positionYPropertyIndex = n;
- continue;
+ case CSSPropertyBackgroundSize:
case CSSPropertyBackgroundRepeatX:
- repeatXPropertyIndex = n;
- continue;
case CSSPropertyBackgroundRepeatY:
- repeatYPropertyIndex = n;
+ shorthandPropertyAppeared.set(CSSPropertyBackground - firstCSSProperty);
continue;
case CSSPropertyContent:
if (property.value()->isValueList())
@@ -229,80 +231,11 @@ String StylePropertySerializer::asText() const
if (value == "initial" && !CSSProperty::isInheritedProperty(propertyID))
continue;
- if (numDecls++)
- result.append(' ');
- result.append(getPropertyName(propertyID));
- result.appendLiteral(": ");
- result.append(value);
- if (property.isImportant())
- result.appendLiteral(" !important");
- result.append(';');
- }
-
- // FIXME: This is a not-so-nice way to turn x/y positions into single background-position in output.
- // It is required because background-position-x/y are non-standard properties and WebKit generated output
- // would not work in Firefox (<rdar://problem/5143183>)
- // It would be a better solution if background-position was CSS_PAIR.
- if (positionXPropertyIndex != -1 && positionYPropertyIndex != -1 && m_propertySet.propertyAt(positionXPropertyIndex).isImportant() == m_propertySet.propertyAt(positionYPropertyIndex).isImportant()) {
- StylePropertySet::PropertyReference positionXProperty = m_propertySet.propertyAt(positionXPropertyIndex);
- StylePropertySet::PropertyReference positionYProperty = m_propertySet.propertyAt(positionYPropertyIndex);
-
- if (numDecls++)
- result.append(' ');
- result.appendLiteral("background-position: ");
- if (positionXProperty.value()->isValueList() || positionYProperty.value()->isValueList())
- result.append(getLayeredShorthandValue(backgroundPositionShorthand()));
- else {
- result.append(positionXProperty.value()->cssText());
- result.append(' ');
- result.append(positionYProperty.value()->cssText());
- }
- if (positionXProperty.isImportant())
- result.appendLiteral(" !important");
- result.append(';');
- } else {
- if (positionXPropertyIndex != -1) {
- if (numDecls++)
- result.append(' ');
- result.append(m_propertySet.propertyAt(positionXPropertyIndex).cssText());
- }
- if (positionYPropertyIndex != -1) {
- if (numDecls++)
- result.append(' ');
- result.append(m_propertySet.propertyAt(positionYPropertyIndex).cssText());
- }
+ result.append(getPropertyText(propertyID, value, property.isImportant(), numDecls++));
}
- // FIXME: We need to do the same for background-repeat.
- if (repeatXPropertyIndex != -1 && repeatYPropertyIndex != -1 && m_propertySet.propertyAt(repeatXPropertyIndex).isImportant() == m_propertySet.propertyAt(repeatYPropertyIndex).isImportant()) {
- StylePropertySet::PropertyReference repeatXProperty = m_propertySet.propertyAt(repeatXPropertyIndex);
- StylePropertySet::PropertyReference repeatYProperty = m_propertySet.propertyAt(repeatYPropertyIndex);
-
- if (numDecls++)
- result.append(' ');
- result.appendLiteral("background-repeat: ");
- if (repeatXProperty.value()->isValueList() || repeatYProperty.value()->isValueList())
- result.append(getLayeredShorthandValue(backgroundRepeatShorthand()));
- else {
- result.append(repeatXProperty.value()->cssText());
- result.append(' ');
- result.append(repeatYProperty.value()->cssText());
- }
- if (repeatXProperty.isImportant())
- result.appendLiteral(" !important");
- result.append(';');
- } else {
- if (repeatXPropertyIndex != -1) {
- if (numDecls++)
- result.append(' ');
- result.append(m_propertySet.propertyAt(repeatXPropertyIndex).cssText());
- }
- if (repeatYPropertyIndex != -1) {
- if (numDecls++)
- result.append(' ');
- result.append(m_propertySet.propertyAt(repeatYPropertyIndex).cssText());
- }
- }
+ if (shorthandPropertyAppeared.get(CSSPropertyBackground - firstCSSProperty))
+ appendBackgroundPropertyAsText(result, numDecls);
ASSERT(!numDecls ^ !result.isEmpty());
return result.toString();
@@ -319,7 +252,7 @@ String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
case CSSPropertyBackgroundPosition:
return getLayeredShorthandValue(backgroundPositionShorthand());
case CSSPropertyBackgroundRepeat:
- return getLayeredShorthandValue(backgroundRepeatShorthand());
+ return backgroundRepeatPropertyValue();
case CSSPropertyBackground:
return getLayeredShorthandValue(backgroundShorthand());
case CSSPropertyBorder:
@@ -378,6 +311,7 @@ String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
return getShorthandValue(webkitTextEmphasisShorthand());
case CSSPropertyWebkitTextStroke:
return getShorthandValue(webkitTextStrokeShorthand());
+ case CSSPropertyTransformOrigin:
case CSSPropertyWebkitTransformOrigin:
return getShorthandValue(webkitTransformOriginShorthand());
case CSSPropertyWebkitTransition:
@@ -385,7 +319,7 @@ String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
case CSSPropertyWebkitAnimation:
return getLayeredShorthandValue(webkitAnimationShorthand());
case CSSPropertyMarker: {
- RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyMarkerStart);
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyMarkerStart);
if (value)
return value->cssText();
return String();
@@ -399,8 +333,8 @@ String StylePropertySerializer::getPropertyValue(CSSPropertyID propertyID) const
String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand& shorthand) const
{
- RefPtr<CSSValue> horizontalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[0]);
- RefPtr<CSSValue> verticalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[1]);
+ RefPtrWillBeRawPtr<CSSValue> horizontalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[0]);
+ RefPtrWillBeRawPtr<CSSValue> verticalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[1]);
// While standard border-spacing property does not allow specifying border-spacing-vertical without
// specifying border-spacing-horizontal <http://www.w3.org/TR/CSS21/tables.html#separated-borders>,
@@ -539,7 +473,7 @@ String StylePropertySerializer::getLayeredShorthandValue(const StylePropertyShor
const unsigned size = shorthand.length();
// Begin by collecting the properties into an array.
- Vector< RefPtr<CSSValue> > values(size);
+ WillBeHeapVector<RefPtrWillBeMember<CSSValue> > values(size);
size_t numLayers = 0;
for (unsigned i = 0; i < size; ++i) {
@@ -547,9 +481,10 @@ String StylePropertySerializer::getLayeredShorthandValue(const StylePropertyShor
if (values[i]) {
if (values[i]->isBaseValueList()) {
CSSValueList* valueList = toCSSValueList(values[i].get());
- numLayers = max(valueList->length(), numLayers);
- } else
- numLayers = max<size_t>(1U, numLayers);
+ numLayers = std::max(valueList->length(), numLayers);
+ } else {
+ numLayers = std::max<size_t>(1U, numLayers);
+ }
}
}
@@ -565,7 +500,7 @@ String StylePropertySerializer::getLayeredShorthandValue(const StylePropertyShor
bool useSingleWordShorthand = false;
bool foundPositionYCSSProperty = false;
for (unsigned j = 0; j < size; j++) {
- RefPtr<CSSValue> value;
+ RefPtrWillBeRawPtr<CSSValue> value = nullptr;
if (values[j]) {
if (values[j]->isBaseValueList())
value = toCSSValueList(values[j].get())->item(i);
@@ -575,9 +510,11 @@ String StylePropertySerializer::getLayeredShorthandValue(const StylePropertyShor
// Color only belongs in the last layer.
if (shorthand.properties()[j] == CSSPropertyBackgroundColor) {
if (i != numLayers - 1)
- value = 0;
- } else if (i) // Other singletons only belong in the first layer.
- value = 0;
+ value = nullptr;
+ } else if (i) {
+ // Other singletons only belong in the first layer.
+ value = nullptr;
+ }
}
}
@@ -590,8 +527,8 @@ String StylePropertySerializer::getLayeredShorthandValue(const StylePropertyShor
// BUG 49055: make sure the value was not reset in the layer check just above.
if ((j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyBackgroundRepeatY && value)
|| (j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyWebkitMaskRepeatY && value)) {
- RefPtr<CSSValue> yValue;
- RefPtr<CSSValue> nextValue = values[j + 1];
+ RefPtrWillBeRawPtr<CSSValue> yValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> nextValue = values[j + 1];
if (nextValue->isValueList())
yValue = toCSSValueList(nextValue.get())->itemWithoutBoundsCheck(i);
else
@@ -687,7 +624,7 @@ String StylePropertySerializer::getShorthandValue(const StylePropertyShorthand&
StringBuilder result;
for (unsigned i = 0; i < shorthand.length(); ++i) {
if (!m_propertySet.isPropertyImplicit(shorthand.properties()[i])) {
- RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
if (!value)
return String();
String valueText = value->cssText();
@@ -716,7 +653,7 @@ String StylePropertySerializer::getCommonValue(const StylePropertyShorthand& sho
String res;
bool lastPropertyWasImportant = false;
for (unsigned i = 0; i < shorthand.length(); ++i) {
- RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
// FIXME: CSSInitialValue::cssText should generate the right value.
if (!value)
return String();
@@ -764,4 +701,172 @@ String StylePropertySerializer::borderPropertyValue(CommonValueMode valueMode) c
return result.isEmpty() ? String() : result.toString();
}
+static void appendBackgroundRepeatValue(StringBuilder& builder, const CSSValue& repeatXCSSValue, const CSSValue& repeatYCSSValue)
+{
+ // FIXME: Ensure initial values do not appear in CSS_VALUE_LISTS.
+ DEFINE_STATIC_REF_WILL_BE_PERSISTENT(CSSPrimitiveValue, initialRepeatValue, (CSSPrimitiveValue::create(CSSValueRepeat)));
+ const CSSPrimitiveValue& repeatX = repeatXCSSValue.isInitialValue() ? *initialRepeatValue : toCSSPrimitiveValue(repeatXCSSValue);
+ const CSSPrimitiveValue& repeatY = repeatYCSSValue.isInitialValue() ? *initialRepeatValue : toCSSPrimitiveValue(repeatYCSSValue);
+ CSSValueID repeatXValueId = repeatX.getValueID();
+ CSSValueID repeatYValueId = repeatY.getValueID();
+ if (repeatXValueId == repeatYValueId) {
+ builder.append(repeatX.cssText());
+ } else if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueRepeat) {
+ builder.append("repeat-y");
+ } else if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoRepeat) {
+ builder.append("repeat-x");
+ } else {
+ builder.append(repeatX.cssText());
+ builder.append(" ");
+ builder.append(repeatY.cssText());
+ }
+}
+
+String StylePropertySerializer::backgroundRepeatPropertyValue() const
+{
+ RefPtrWillBeRawPtr<CSSValue> repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatX);
+ RefPtrWillBeRawPtr<CSSValue> repeatY = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatY);
+ if (!repeatX || !repeatY)
+ return String();
+ if (m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX) != m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatY))
+ return String();
+ if (repeatX->cssValueType() == repeatY->cssValueType()
+ && (repeatX->cssValueType() == CSSValue::CSS_INITIAL || repeatX->cssValueType() == CSSValue::CSS_INHERIT)) {
+ return repeatX->cssText();
+ }
+
+ RefPtrWillBeRawPtr<CSSValueList> repeatXList;
+ if (repeatX->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) {
+ repeatXList = CSSValueList::createCommaSeparated();
+ repeatXList->append(repeatX);
+ } else if (repeatX->cssValueType() == CSSValue::CSS_VALUE_LIST) {
+ repeatXList = toCSSValueList(repeatX.get());
+ } else {
+ return String();
+ }
+
+ RefPtrWillBeRawPtr<CSSValueList> repeatYList;
+ if (repeatY->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE) {
+ repeatYList = CSSValueList::createCommaSeparated();
+ repeatYList->append(repeatY);
+ } else if (repeatY->cssValueType() == CSSValue::CSS_VALUE_LIST) {
+ repeatYList = toCSSValueList(repeatY.get());
+ } else {
+ return String();
+ }
+
+ size_t shorthandLength = lowestCommonMultiple(repeatXList->length(), repeatYList->length());
+ StringBuilder builder;
+ for (size_t i = 0; i < shorthandLength; ++i) {
+ if (i)
+ builder.append(", ");
+ appendBackgroundRepeatValue(builder,
+ *repeatXList->item(i % repeatXList->length()),
+ *repeatYList->item(i % repeatYList->length()));
+ }
+ return builder.toString();
+}
+
+void StylePropertySerializer::appendBackgroundPropertyAsText(StringBuilder& result, unsigned& numDecls) const
+{
+ if (isPropertyShorthandAvailable(backgroundShorthand())) {
+ String backgroundValue = getPropertyValue(CSSPropertyBackground);
+ bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundImage);
+ result.append(getPropertyText(CSSPropertyBackground, backgroundValue, isImportant, numDecls++));
+ return;
+ }
+ if (shorthandHasOnlyInitialOrInheritedValue(backgroundShorthand())) {
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundImage);
+ bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundImage);
+ result.append(getPropertyText(CSSPropertyBackground, value->cssText(), isImportant, numDecls++));
+ return;
+ }
+
+ // backgroundShorthandProperty without layered shorhand properties
+ const CSSPropertyID backgroundPropertyIds[] = {
+ CSSPropertyBackgroundImage,
+ CSSPropertyBackgroundAttachment,
+ CSSPropertyBackgroundColor,
+ CSSPropertyBackgroundSize,
+ CSSPropertyBackgroundOrigin,
+ CSSPropertyBackgroundClip
+ };
+
+ for (unsigned i = 0; i < WTF_ARRAY_LENGTH(backgroundPropertyIds); ++i) {
+ CSSPropertyID propertyID = backgroundPropertyIds[i];
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(propertyID);
+ if (!value)
+ continue;
+ result.append(getPropertyText(propertyID, value->cssText(), m_propertySet.propertyIsImportant(propertyID), numDecls++));
+ }
+
+ // FIXME: This is a not-so-nice way to turn x/y positions into single background-position in output.
+ // It is required because background-position-x/y are non-standard properties and WebKit generated output
+ // would not work in Firefox (<rdar://problem/5143183>)
+ // It would be a better solution if background-position was CSS_PAIR.
+ if (shorthandHasOnlyInitialOrInheritedValue(backgroundPositionShorthand())) {
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionX);
+ bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
+ result.append(getPropertyText(CSSPropertyBackgroundPosition, value->cssText(), isImportant, numDecls++));
+ } else if (isPropertyShorthandAvailable(backgroundPositionShorthand())) {
+ String positionValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundPosition);
+ bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
+ if (!positionValue.isNull())
+ result.append(getPropertyText(CSSPropertyBackgroundPosition, positionValue, isImportant, numDecls++));
+ } else {
+ // should check background-position-x or background-position-y.
+ if (RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionX)) {
+ if (!value->isImplicitInitialValue()) {
+ bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
+ result.append(getPropertyText(CSSPropertyBackgroundPositionX, value->cssText(), isImportant, numDecls++));
+ }
+ }
+ if (RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionY)) {
+ if (!value->isImplicitInitialValue()) {
+ bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionY);
+ result.append(getPropertyText(CSSPropertyBackgroundPositionY, value->cssText(), isImportant, numDecls++));
+ }
+ }
+ }
+
+ String repeatValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundRepeat);
+ if (!repeatValue.isNull())
+ result.append(getPropertyText(CSSPropertyBackgroundRepeat, repeatValue, m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX), numDecls++));
+}
+
+bool StylePropertySerializer::isPropertyShorthandAvailable(const StylePropertyShorthand& shorthand) const
+{
+ ASSERT(shorthand.length() > 0);
+
+ bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[0]);
+ for (unsigned i = 0; i < shorthand.length(); ++i) {
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
+ if (!value || (value->isInitialValue() && !value->isImplicitInitialValue()) || value->isInheritedValue())
+ return false;
+ if (isImportant != m_propertySet.propertyIsImportant(shorthand.properties()[i]))
+ return false;
+ }
+ return true;
+}
+
+bool StylePropertySerializer::shorthandHasOnlyInitialOrInheritedValue(const StylePropertyShorthand& shorthand) const
+{
+ ASSERT(shorthand.length() > 0);
+ bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[0]);
+ bool isInitialValue = true;
+ bool isInheritedValue = true;
+ for (unsigned i = 0; i < shorthand.length(); ++i) {
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
+ if (!value)
+ return false;
+ if (!value->isInitialValue())
+ isInitialValue = false;
+ if (!value->isInheritedValue())
+ isInheritedValue = false;
+ if (isImportant != m_propertySet.propertyIsImportant(shorthand.properties()[i]))
+ return false;
+ }
+ return isInitialValue || isInheritedValue;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.h b/chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.h
index 55d1027b5bd..ed9bc6ab478 100644
--- a/chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.h
+++ b/chromium/third_party/WebKit/Source/core/css/StylePropertySerializer.h
@@ -45,6 +45,11 @@ private:
String getShorthandValue(const StylePropertyShorthand&) const;
String fontValue() const;
void appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result, String& value) const;
+ String backgroundRepeatPropertyValue() const;
+ String getPropertyText(CSSPropertyID, const String& value, bool isImportant, bool isNotFirstDecl) const;
+ bool isPropertyShorthandAvailable(const StylePropertyShorthand&) const;
+ bool shorthandHasOnlyInitialOrInheritedValue(const StylePropertyShorthand&) const;
+ void appendBackgroundPropertyAsText(StringBuilder& result, unsigned& numDecls) const;
const StylePropertySet& m_propertySet;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/StylePropertySet.cpp b/chromium/third_party/WebKit/Source/core/css/StylePropertySet.cpp
index c7e0ae63811..2581c01e911 100644
--- a/chromium/third_party/WebKit/Source/core/css/StylePropertySet.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/StylePropertySet.cpp
@@ -23,14 +23,14 @@
#include "config.h"
#include "core/css/StylePropertySet.h"
-#include "RuntimeEnabledFeatures.h"
-#include "StylePropertyShorthand.h"
-#include "core/css/CSSParser.h"
+#include "core/StylePropertyShorthand.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSValuePool.h"
-#include "core/css/CSSVariableValue.h"
#include "core/css/RuntimeCSSEnabled.h"
#include "core/css/StylePropertySerializer.h"
#include "core/css/StyleSheetContents.h"
+#include "core/frame/UseCounter.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/text/StringBuilder.h"
#ifndef NDEBUG
@@ -38,8 +38,6 @@
#include <stdio.h>
#endif
-using namespace std;
-
namespace WebCore {
static size_t sizeForImmutableStylePropertySetWithPropertyCount(unsigned count)
@@ -50,8 +48,12 @@ static size_t sizeForImmutableStylePropertySetWithPropertyCount(unsigned count)
PassRefPtr<ImmutableStylePropertySet> ImmutableStylePropertySet::create(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode)
{
ASSERT(count <= MaxArraySize);
+#if ENABLE(OILPAN)
+ void* slot = Heap::allocate<StylePropertySet>(sizeForImmutableStylePropertySetWithPropertyCount(count));
+#else
void* slot = WTF::fastMalloc(sizeForImmutableStylePropertySetWithPropertyCount(count));
- return adoptRef(new (slot) ImmutableStylePropertySet(properties, count, cssParserMode));
+#endif // ENABLE(OILPAN)
+ return adoptRefWillBeRefCountedGarbageCollected(new (slot) ImmutableStylePropertySet(properties, count, cssParserMode));
}
PassRefPtr<ImmutableStylePropertySet> StylePropertySet::immutableCopyIfNeeded() const
@@ -79,19 +81,47 @@ ImmutableStylePropertySet::ImmutableStylePropertySet(const CSSProperty* properti
: StylePropertySet(cssParserMode, length)
{
StylePropertyMetadata* metadataArray = const_cast<StylePropertyMetadata*>(this->metadataArray());
- CSSValue** valueArray = const_cast<CSSValue**>(this->valueArray());
+ RawPtrWillBeMember<CSSValue>* valueArray = const_cast<RawPtrWillBeMember<CSSValue>*>(this->valueArray());
for (unsigned i = 0; i < m_arraySize; ++i) {
metadataArray[i] = properties[i].metadata();
valueArray[i] = properties[i].value();
+#if !ENABLE(OILPAN)
valueArray[i]->ref();
+#endif
}
}
ImmutableStylePropertySet::~ImmutableStylePropertySet()
{
- CSSValue** valueArray = const_cast<CSSValue**>(this->valueArray());
+#if !ENABLE(OILPAN)
+ RawPtrWillBeMember<CSSValue>* valueArray = const_cast<RawPtrWillBeMember<CSSValue>*>(this->valueArray());
for (unsigned i = 0; i < m_arraySize; ++i)
valueArray[i]->deref();
+#endif
+}
+
+int ImmutableStylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
+{
+ // Convert here propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
+ // the compiler converting it to an int multiple times in the loop.
+ uint16_t id = static_cast<uint16_t>(propertyID);
+ for (int n = m_arraySize - 1 ; n >= 0; --n) {
+ if (metadataArray()[n].m_propertyID == id) {
+ // Only enabled or internal properties should be part of the style.
+ ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID));
+ return n;
+ }
+ }
+
+ return -1;
+}
+
+void ImmutableStylePropertySet::traceAfterDispatch(Visitor* visitor)
+{
+ const RawPtrWillBeMember<CSSValue>* values = valueArray();
+ for (unsigned i = 0; i < m_arraySize; i++)
+ visitor->trace(values[i]);
+ StylePropertySet::traceAfterDispatch(visitor);
}
MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other)
@@ -108,40 +138,38 @@ MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other)
String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const
{
- RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID);
if (value)
return value->cssText();
return StylePropertySerializer(*this).getPropertyValue(propertyID);
}
-PassRefPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSPropertyID propertyID) const
+PassRefPtrWillBeRawPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSPropertyID propertyID) const
{
int foundPropertyIndex = findPropertyIndex(propertyID);
if (foundPropertyIndex == -1)
- return 0;
+ return nullptr;
return propertyAt(foundPropertyIndex).value();
}
-unsigned StylePropertySet::variableCount() const
+void StylePropertySet::trace(Visitor* visitor)
{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- unsigned count = 0;
- for (unsigned i = 0; i < propertyCount(); ++i) {
- if (propertyAt(i).id() == CSSPropertyVariable)
- count++;
- }
- return count;
+ if (m_isMutable)
+ toMutableStylePropertySet(this)->traceAfterDispatch(visitor);
+ else
+ toImmutableStylePropertySet(this)->traceAfterDispatch(visitor);
}
-String StylePropertySet::variableValue(const AtomicString& name) const
+#if ENABLE(OILPAN)
+void StylePropertySet::finalizeGarbageCollectedObject()
{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- size_t index = findVariableIndex(name);
- if (index == kNotFound)
- return String();
- return toCSSVariableValue(propertyAt(index).value())->value();
+ if (m_isMutable)
+ toMutableStylePropertySet(this)->~MutableStylePropertySet();
+ else
+ toImmutableStylePropertySet(this)->~ImmutableStylePropertySet();
}
+#endif
bool MutableStylePropertySet::removeShorthandProperty(CSSPropertyID propertyID)
{
@@ -237,10 +265,10 @@ bool MutableStylePropertySet::setProperty(CSSPropertyID propertyID, const String
// When replacing an existing property value, this moves the property to the end of the list.
// Firefox preserves the position, and MSIE moves the property to the beginning.
- return CSSParser::parseValue(this, propertyID, value, important, cssParserMode(), contextStyleSheet);
+ return BisonCSSParser::parseValue(this, propertyID, value, important, cssParserMode(), contextStyleSheet);
}
-void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue> prpValue, bool important)
+void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtrWillBeRawPtr<CSSValue> prpValue, bool important)
{
StylePropertyShorthand shorthand = shorthandForProperty(propertyID);
if (!shorthand.length()) {
@@ -250,7 +278,7 @@ void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtr<C
removePropertiesInSet(shorthand.properties(), shorthand.length());
- RefPtr<CSSValue> value = prpValue;
+ RefPtrWillBeRawPtr<CSSValue> value = prpValue;
for (unsigned i = 0; i < shorthand.length(); ++i)
m_propertyVector.append(CSSProperty(shorthand.properties()[i], value, important));
}
@@ -279,28 +307,6 @@ unsigned getIndexInShorthandVectorForPrefixingVariant(const CSSProperty& propert
return indexOfShorthandForLonghand(prefixedShorthand, shorthands);
}
-bool MutableStylePropertySet::setVariableValue(const AtomicString& name, const String& value, bool important)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- if (value.isEmpty())
- return removeVariable(name);
-
- size_t index = findVariableIndex(name);
- if (index != kNotFound) {
- const CSSValue* cssValue = m_propertyVector.at(index).value();
- if (toCSSVariableValue(cssValue)->value() == value)
- return false;
- }
-
- CSSProperty property(CSSPropertyVariable, CSSVariableValue::create(name, value), important);
- if (index == kNotFound) {
- m_propertyVector.append(property);
- return true;
- }
- m_propertyVector.at(index) = property;
- return false;
-}
-
void MutableStylePropertySet::appendPrefixingVariantProperty(const CSSProperty& property)
{
m_propertyVector.append(property);
@@ -335,17 +341,17 @@ void MutableStylePropertySet::parseDeclaration(const String& styleDeclaration, S
{
m_propertyVector.clear();
- CSSParserContext context(cssParserMode());
+ CSSParserContext context(cssParserMode(), UseCounter::getFrom(contextStyleSheet));
if (contextStyleSheet) {
context = contextStyleSheet->parserContext();
context.setMode(cssParserMode());
}
- CSSParser parser(context, UseCounter::getFrom(contextStyleSheet));
+ BisonCSSParser parser(context);
parser.parseDeclaration(this, styleDeclaration, 0, contextStyleSheet);
}
-void MutableStylePropertySet::addParsedProperties(const Vector<CSSProperty, 256>& properties)
+void MutableStylePropertySet::addParsedProperties(const WillBeHeapVector<CSSProperty, 256>& properties)
{
m_propertyVector.reserveCapacity(m_propertyVector.size() + properties.size());
for (unsigned i = 0; i < properties.size(); ++i)
@@ -364,11 +370,6 @@ String StylePropertySet::asText() const
return StylePropertySerializer(*this).asText();
}
-bool StylePropertySet::hasCSSOMWrapper() const
-{
- return m_isMutable && toMutableStylePropertySet(this)->m_cssomWrapper;
-}
-
void MutableStylePropertySet::mergeAndOverrideOnConflict(const StylePropertySet* other)
{
unsigned size = other->propertyCount();
@@ -382,13 +383,6 @@ void MutableStylePropertySet::mergeAndOverrideOnConflict(const StylePropertySet*
}
}
-void StylePropertySet::addSubresourceStyleURLs(ListHashSet<KURL>& urls, StyleSheetContents* contextStyleSheet) const
-{
- unsigned size = propertyCount();
- for (unsigned i = 0; i < size; ++i)
- propertyAt(i).value()->addSubresourceStyleURLs(urls, contextStyleSheet);
-}
-
bool StylePropertySet::hasFailedOrCanceledSubresources() const
{
unsigned size = propertyCount();
@@ -417,9 +411,6 @@ static const CSSPropertyID staticBlockProperties[] = {
CSSPropertyPageBreakAfter,
CSSPropertyPageBreakBefore,
CSSPropertyPageBreakInside,
- CSSPropertyWebkitRegionBreakAfter,
- CSSPropertyWebkitRegionBreakBefore,
- CSSPropertyWebkitRegionBreakInside,
CSSPropertyTextAlign,
CSSPropertyTextAlignLast,
CSSPropertyTextIndent,
@@ -440,7 +431,7 @@ void MutableStylePropertySet::clear()
m_propertyVector.clear();
}
-PassRefPtr<MutableStylePropertySet> StylePropertySet::copyBlockProperties() const
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> StylePropertySet::copyBlockProperties() const
{
return copyPropertiesInSet(blockProperties());
}
@@ -450,59 +441,35 @@ void MutableStylePropertySet::removeBlockProperties()
removePropertiesInSet(blockProperties().data(), blockProperties().size());
}
+inline bool containsId(const CSSPropertyID* set, unsigned length, CSSPropertyID id)
+{
+ for (unsigned i = 0; i < length; ++i) {
+ if (set[i] == id)
+ return true;
+ }
+ return false;
+}
+
bool MutableStylePropertySet::removePropertiesInSet(const CSSPropertyID* set, unsigned length)
{
if (m_propertyVector.isEmpty())
return false;
- // FIXME: This is always used with static sets and in that case constructing the hash repeatedly is pretty pointless.
- HashSet<CSSPropertyID> toRemove;
- for (unsigned i = 0; i < length; ++i)
- toRemove.add(set[i]);
-
- Vector<CSSProperty> newProperties;
+ WillBeHeapVector<CSSProperty> newProperties;
newProperties.reserveInitialCapacity(m_propertyVector.size());
- unsigned size = m_propertyVector.size();
- for (unsigned n = 0; n < size; ++n) {
- const CSSProperty& property = m_propertyVector.at(n);
+ unsigned initialSize = m_propertyVector.size();
+ const CSSProperty* properties = m_propertyVector.data();
+ for (unsigned n = 0; n < initialSize; ++n) {
+ const CSSProperty& property = properties[n];
// Not quite sure if the isImportant test is needed but it matches the existing behavior.
- if (!property.isImportant()) {
- if (toRemove.contains(property.id()))
- continue;
- }
+ if (!property.isImportant() && containsId(set, length, property.id()))
+ continue;
newProperties.append(property);
}
- bool changed = newProperties.size() != m_propertyVector.size();
m_propertyVector = newProperties;
- return changed;
-}
-
-int StylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
-{
- // Convert here propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
- // the compiler converting it to an int multiple times in the loop.
- uint16_t id = static_cast<uint16_t>(propertyID);
- for (int n = propertyCount() - 1 ; n >= 0; --n) {
- if (id == propertyAt(n).propertyMetadata().m_propertyID) {
- // Only enabled or internal properties should be part of the style.
- ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID));
- return n;
- }
- }
- return -1;
-}
-
-size_t StylePropertySet::findVariableIndex(const AtomicString& name) const
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- for (int i = propertyCount() - 1; i >= 0; --i) {
- const PropertyReference& property = propertyAt(i);
- if (property.id() == CSSPropertyVariable && toCSSVariableValue(property.value())->name() == name)
- return i;
- }
- return kNotFound;
+ return initialSize != m_propertyVector.size();
}
CSSProperty* MutableStylePropertySet::findCSSPropertyWithID(CSSPropertyID propertyID)
@@ -549,116 +516,58 @@ void MutableStylePropertySet::removeEquivalentProperties(const CSSStyleDeclarati
removeProperty(propertiesToRemove[i]);
}
-bool MutableStylePropertySet::removeVariable(const AtomicString& name)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- size_t index = findVariableIndex(name);
- if (index == kNotFound)
- return false;
- m_propertyVector.remove(index);
- return true;
-}
-
-bool MutableStylePropertySet::clearVariables()
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- CSSPropertyID variablesId = CSSPropertyVariable;
- return removePropertiesInSet(&variablesId, 1);
-}
-
-PassRefPtr<MutableStylePropertySet::VariablesIterator> MutableStylePropertySet::VariablesIterator::create(MutableStylePropertySet* propertySet)
-{
- ASSERT(RuntimeEnabledFeatures::cssVariablesEnabled());
- const size_t propertyCount = propertySet->propertyCount();
- size_t variableCount = 0;
- Vector<AtomicString> remainingNames(propertyCount);
- for (int i = propertyCount; i--; ) {
- const PropertyReference& property = propertySet->propertyAt(i);
- if (property.id() == CSSPropertyVariable)
- remainingNames[variableCount++] = toCSSVariableValue(property.value())->name();
- }
- remainingNames.shrink(variableCount);
-
- RefPtr<VariablesIterator> iterator = adoptRef(new VariablesIterator(propertySet));
- // FIXME: Make use of the Vector move constructor when rvalues are supported on all platforms.
- iterator->takeRemainingNames(remainingNames);
- return iterator.release();
-}
-
-void MutableStylePropertySet::VariablesIterator::addedVariable(const AtomicString& name)
-{
- ASSERT(!m_remainingNames.contains(name));
- ASSERT(!m_newNames.contains(name));
- m_newNames.append(name);
-}
-
-void MutableStylePropertySet::VariablesIterator::removedVariable(const AtomicString& name)
-{
- size_t index = m_remainingNames.find(name);
- if (index != kNotFound)
- m_remainingNames.remove(index);
- index = m_newNames.find(name);
- if (index != kNotFound)
- m_newNames.remove(index);
-}
-
-void MutableStylePropertySet::VariablesIterator::clearedVariables()
-{
- m_remainingNames.clear();
- m_newNames.clear();
-}
-
-void MutableStylePropertySet::VariablesIterator::advance()
-{
- if (!atEnd())
- m_remainingNames.removeLast();
- if (!m_newNames.isEmpty()) {
- m_remainingNames.appendVector(m_newNames);
- m_newNames.clear();
- }
-}
-
-PassRefPtr<MutableStylePropertySet> StylePropertySet::mutableCopy() const
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> StylePropertySet::mutableCopy() const
{
- return adoptRef(new MutableStylePropertySet(*this));
+ return adoptRefWillBeRefCountedGarbageCollected(new MutableStylePropertySet(*this));
}
-PassRefPtr<MutableStylePropertySet> StylePropertySet::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> StylePropertySet::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
{
- Vector<CSSProperty, 256> list;
+ WillBeHeapVector<CSSProperty, 256> list;
list.reserveInitialCapacity(properties.size());
for (unsigned i = 0; i < properties.size(); ++i) {
- RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
+ RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
if (value)
list.append(CSSProperty(properties[i], value.release(), false));
}
return MutableStylePropertySet::create(list.data(), list.size());
}
-PropertySetCSSStyleDeclaration* MutableStylePropertySet::cssStyleDeclaration()
-{
- return m_cssomWrapper.get();
-}
-
CSSStyleDeclaration* MutableStylePropertySet::ensureCSSStyleDeclaration()
{
+ // FIXME: get rid of this weirdness of a CSSStyleDeclaration inside of a
+ // style property set.
if (m_cssomWrapper) {
ASSERT(!static_cast<CSSStyleDeclaration*>(m_cssomWrapper.get())->parentRule());
ASSERT(!m_cssomWrapper->parentElement());
return m_cssomWrapper.get();
}
- m_cssomWrapper = adoptPtr(new PropertySetCSSStyleDeclaration(this));
+ m_cssomWrapper = adoptPtrWillBeNoop(new PropertySetCSSStyleDeclaration(*this));
return m_cssomWrapper.get();
}
-CSSStyleDeclaration* MutableStylePropertySet::ensureInlineCSSStyleDeclaration(Element* parentElement)
+int MutableStylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
{
- if (m_cssomWrapper) {
- ASSERT(m_cssomWrapper->parentElement() == parentElement);
- return m_cssomWrapper.get();
+ // Convert here propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
+ // the compiler converting it to an int multiple times in the loop.
+ uint16_t id = static_cast<uint16_t>(propertyID);
+ const CSSProperty* properties = m_propertyVector.data();
+ for (int n = m_propertyVector.size() - 1 ; n >= 0; --n) {
+ if (properties[n].metadata().m_propertyID == id) {
+ // Only enabled or internal properties should be part of the style.
+ ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID));
+ return n;
+ }
}
- m_cssomWrapper = adoptPtr(new InlineCSSStyleDeclaration(this, parentElement));
- return m_cssomWrapper.get();
+
+ return -1;
+}
+
+void MutableStylePropertySet::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_cssomWrapper);
+ visitor->trace(m_propertyVector);
+ StylePropertySet::traceAfterDispatch(visitor);
}
unsigned StylePropertySet::averageSizeInBytes()
@@ -668,7 +577,7 @@ unsigned StylePropertySet::averageSizeInBytes()
}
// See the function above if you need to update this.
-struct SameSizeAsStylePropertySet : public RefCounted<SameSizeAsStylePropertySet> {
+struct SameSizeAsStylePropertySet : public RefCountedWillBeRefCountedGarbageCollected<SameSizeAsStylePropertySet> {
unsigned bitfield;
};
COMPILE_ASSERT(sizeof(StylePropertySet) == sizeof(SameSizeAsStylePropertySet), style_property_set_should_stay_small);
@@ -680,23 +589,18 @@ void StylePropertySet::showStyle()
}
#endif
-PassRefPtr<MutableStylePropertySet> MutableStylePropertySet::create(CSSParserMode cssParserMode)
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> MutableStylePropertySet::create(CSSParserMode cssParserMode)
{
- return adoptRef(new MutableStylePropertySet(cssParserMode));
+ return adoptRefWillBeRefCountedGarbageCollected(new MutableStylePropertySet(cssParserMode));
}
-PassRefPtr<MutableStylePropertySet> MutableStylePropertySet::create(const CSSProperty* properties, unsigned count)
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> MutableStylePropertySet::create(const CSSProperty* properties, unsigned count)
{
- return adoptRef(new MutableStylePropertySet(properties, count));
+ return adoptRefWillBeRefCountedGarbageCollected(new MutableStylePropertySet(properties, count));
}
String StylePropertySet::PropertyReference::cssName() const
{
- if (id() == CSSPropertyVariable) {
- if (!propertyValue()->isVariableValue())
- return emptyString(); // Should not happen, but if it does, avoid a bad cast.
- return "var-" + toCSSVariableValue(propertyValue())->name();
- }
return getPropertyNameString(id());
}
diff --git a/chromium/third_party/WebKit/Source/core/css/StylePropertySet.h b/chromium/third_party/WebKit/Source/core/css/StylePropertySet.h
index 1003f3b93e5..3e1a42786e0 100644
--- a/chromium/third_party/WebKit/Source/core/css/StylePropertySet.h
+++ b/chromium/third_party/WebKit/Source/core/css/StylePropertySet.h
@@ -21,11 +21,10 @@
#ifndef StylePropertySet_h
#define StylePropertySet_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/css/CSSParserMode.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSProperty.h"
-#include "core/css/CSSVariablesIterator.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
#include "wtf/ListHashSet.h"
#include "wtf/Vector.h"
@@ -42,12 +41,20 @@ class MutableStylePropertySet;
class StylePropertyShorthand;
class StyleSheetContents;
-class StylePropertySet : public RefCounted<StylePropertySet> {
+class StylePropertySet : public RefCountedWillBeRefCountedGarbageCollected<StylePropertySet> {
friend class PropertyReference;
public:
+
+#if ENABLE(OILPAN)
+ // When oilpan is enabled override the finalize method to dispatch to the subclasses'
+ // destructor. This can be removed once the MutableStylePropertySet's OwnPtr is moved
+ // to the heap.
+ void finalizeGarbageCollectedObject();
+#else
// Override RefCounted's deref() to ensure operator delete is called on
// the appropriate subclass type.
void deref();
+#endif
class PropertyReference {
public:
@@ -87,32 +94,26 @@ public:
bool isEmpty() const;
PropertyReference propertyAt(unsigned index) const { return PropertyReference(*this, index); }
int findPropertyIndex(CSSPropertyID) const;
- size_t findVariableIndex(const AtomicString& name) const;
- PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
+ PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
String getPropertyValue(CSSPropertyID) const;
- unsigned variableCount() const;
- String variableValue(const AtomicString& name) const;
bool propertyIsImportant(CSSPropertyID) const;
CSSPropertyID getPropertyShorthand(CSSPropertyID) const;
bool isPropertyImplicit(CSSPropertyID) const;
- PassRefPtr<MutableStylePropertySet> copyBlockProperties() const;
+ PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyBlockProperties() const;
CSSParserMode cssParserMode() const { return static_cast<CSSParserMode>(m_cssParserMode); }
- void addSubresourceStyleURLs(ListHashSet<KURL>&, StyleSheetContents* contextStyleSheet) const;
-
- PassRefPtr<MutableStylePropertySet> mutableCopy() const;
+ PassRefPtrWillBeRawPtr<MutableStylePropertySet> mutableCopy() const;
PassRefPtr<ImmutableStylePropertySet> immutableCopyIfNeeded() const;
- PassRefPtr<MutableStylePropertySet> copyPropertiesInSet(const Vector<CSSPropertyID>&) const;
+ PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyPropertiesInSet(const Vector<CSSPropertyID>&) const;
String asText() const;
bool isMutable() const { return m_isMutable; }
- bool hasCSSOMWrapper() const;
bool hasFailedOrCanceledSubresources() const;
@@ -124,6 +125,9 @@ public:
bool propertyMatches(CSSPropertyID, const CSSValue*) const;
+ void trace(Visitor*);
+ void traceAfterDispatch(Visitor*) { }
+
protected:
enum { MaxArraySize = (1 << 28) - 1 };
@@ -154,8 +158,16 @@ public:
unsigned propertyCount() const { return m_arraySize; }
- const CSSValue** valueArray() const;
+ const RawPtrWillBeMember<CSSValue>* valueArray() const;
const StylePropertyMetadata* metadataArray() const;
+ int findPropertyIndex(CSSPropertyID) const;
+
+ void traceAfterDispatch(Visitor*);
+
+ void* operator new(std::size_t, void* location)
+ {
+ return location;
+ }
void* m_storage;
@@ -163,14 +175,14 @@ private:
ImmutableStylePropertySet(const CSSProperty*, unsigned count, CSSParserMode);
};
-inline const CSSValue** ImmutableStylePropertySet::valueArray() const
+inline const RawPtrWillBeMember<CSSValue>* ImmutableStylePropertySet::valueArray() const
{
- return reinterpret_cast<const CSSValue**>(const_cast<const void**>(&(this->m_storage)));
+ return reinterpret_cast<const RawPtrWillBeMember<CSSValue>*>(const_cast<const void**>(&(this->m_storage)));
}
inline const StylePropertyMetadata* ImmutableStylePropertySet::metadataArray() const
{
- return reinterpret_cast<const StylePropertyMetadata*>(&reinterpret_cast<const char*>(&(this->m_storage))[m_arraySize * sizeof(CSSValue*)]);
+ return reinterpret_cast<const StylePropertyMetadata*>(&reinterpret_cast<const char*>(&(this->m_storage))[m_arraySize * sizeof(RawPtrWillBeMember<CSSValue>)]);
}
DEFINE_TYPE_CASTS(ImmutableStylePropertySet, StylePropertySet, set, !set->isMutable(), !set.isMutable());
@@ -183,18 +195,17 @@ inline ImmutableStylePropertySet* toImmutableStylePropertySet(const RefPtr<Style
class MutableStylePropertySet : public StylePropertySet {
public:
~MutableStylePropertySet() { }
- static PassRefPtr<MutableStylePropertySet> create(CSSParserMode = HTMLQuirksMode);
- static PassRefPtr<MutableStylePropertySet> create(const CSSProperty* properties, unsigned count);
+ static PassRefPtrWillBeRawPtr<MutableStylePropertySet> create(CSSParserMode = HTMLQuirksMode);
+ static PassRefPtrWillBeRawPtr<MutableStylePropertySet> create(const CSSProperty* properties, unsigned count);
unsigned propertyCount() const { return m_propertyVector.size(); }
- PropertySetCSSStyleDeclaration* cssStyleDeclaration();
- void addParsedProperties(const Vector<CSSProperty, 256>&);
+ void addParsedProperties(const WillBeHeapVector<CSSProperty, 256>&);
void addParsedProperty(const CSSProperty&);
// These expand shorthand properties into multiple properties.
bool setProperty(CSSPropertyID, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
- void setProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important = false);
+ void setProperty(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>, bool important = false);
// These do not. FIXME: This is too messy, we can do better.
bool setProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
@@ -202,7 +213,6 @@ public:
void appendPrefixingVariantProperty(const CSSProperty&);
void setPrefixingVariantProperty(const CSSProperty&);
void setProperty(const CSSProperty&, CSSProperty* slot = 0);
- bool setVariableValue(const AtomicString& name, const String& value, bool important = false);
bool removeProperty(CSSPropertyID, String* returnText = 0);
void removePrefixedOrUnprefixedProperty(CSSPropertyID);
@@ -210,10 +220,6 @@ public:
bool removePropertiesInSet(const CSSPropertyID* set, unsigned length);
void removeEquivalentProperties(const StylePropertySet*);
void removeEquivalentProperties(const CSSStyleDeclaration*);
- bool removeVariable(const AtomicString& name);
- bool clearVariables();
-
- PassRefPtr<CSSVariablesIterator> variablesIterator() { return VariablesIterator::create(this); }
void mergeAndOverrideOnConflict(const StylePropertySet*);
@@ -221,40 +227,22 @@ public:
void parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet);
CSSStyleDeclaration* ensureCSSStyleDeclaration();
- CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(Element* parentElement);
+ int findPropertyIndex(CSSPropertyID) const;
- Vector<CSSProperty, 4> m_propertyVector;
+ void traceAfterDispatch(Visitor*);
private:
- class VariablesIterator : public CSSVariablesIterator {
- public:
- virtual ~VariablesIterator() { }
- static PassRefPtr<VariablesIterator> create(MutableStylePropertySet*);
- private:
- explicit VariablesIterator(MutableStylePropertySet* propertySet) : m_propertySet(propertySet) { }
- void takeRemainingNames(Vector<AtomicString>& remainingNames) { m_remainingNames.swap(remainingNames); }
- virtual void advance() OVERRIDE;
- virtual bool atEnd() const OVERRIDE { return m_remainingNames.isEmpty(); }
- virtual AtomicString name() const OVERRIDE { return m_remainingNames.last(); }
- virtual String value() const OVERRIDE { return m_propertySet->variableValue(name()); }
- virtual void addedVariable(const AtomicString& name) OVERRIDE;
- virtual void removedVariable(const AtomicString& name) OVERRIDE;
- virtual void clearedVariables() OVERRIDE;
-
- RefPtr<MutableStylePropertySet> m_propertySet;
- Vector<AtomicString> m_remainingNames;
- Vector<AtomicString> m_newNames;
- };
-
explicit MutableStylePropertySet(CSSParserMode);
explicit MutableStylePropertySet(const StylePropertySet&);
MutableStylePropertySet(const CSSProperty* properties, unsigned count);
bool removeShorthandProperty(CSSPropertyID);
CSSProperty* findCSSPropertyWithID(CSSPropertyID);
- OwnPtr<PropertySetCSSStyleDeclaration> m_cssomWrapper;
+ OwnPtrWillBeMember<PropertySetCSSStyleDeclaration> m_cssomWrapper;
friend class StylePropertySet;
+
+ WillBeHeapVector<CSSProperty, 4> m_propertyVector;
};
DEFINE_TYPE_CASTS(MutableStylePropertySet, StylePropertySet, set, set->isMutable(), set.isMutable());
@@ -290,6 +278,7 @@ inline bool StylePropertySet::isEmpty() const
return !propertyCount();
}
+#if !ENABLE(OILPAN)
inline void StylePropertySet::deref()
{
if (!derefBase())
@@ -300,6 +289,14 @@ inline void StylePropertySet::deref()
else
delete toImmutableStylePropertySet(this);
}
+#endif // !ENABLE(OILPAN)
+
+inline int StylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
+{
+ if (m_isMutable)
+ return toMutableStylePropertySet(this)->findPropertyIndex(propertyID);
+ return toImmutableStylePropertySet(this)->findPropertyIndex(propertyID);
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/StylePropertyShorthandCustom.cpp b/chromium/third_party/WebKit/Source/core/css/StylePropertyShorthandCustom.cpp
index b157746c8b9..9284ca7e8bb 100644
--- a/chromium/third_party/WebKit/Source/core/css/StylePropertyShorthandCustom.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/StylePropertyShorthandCustom.cpp
@@ -20,7 +20,7 @@
*/
#include "config.h"
-#include "StylePropertyShorthand.h"
+#include "core/StylePropertyShorthand.h"
namespace WebCore {
@@ -86,6 +86,31 @@ const StylePropertyShorthand& webkitAnimationShorthandForParsing()
return webkitAnimationLonghandsForParsing;
}
+// Similar to animations, we have property after timing-function and delay after duration
+const StylePropertyShorthand& transitionShorthandForParsing()
+{
+ static const CSSPropertyID transitionProperties[] = {
+ CSSPropertyTransitionDuration,
+ CSSPropertyTransitionTimingFunction,
+ CSSPropertyTransitionDelay,
+ CSSPropertyTransitionProperty
+ };
+ DEFINE_STATIC_LOCAL(StylePropertyShorthand, transitionLonghands, (CSSPropertyTransition, transitionProperties, WTF_ARRAY_LENGTH(transitionProperties)));
+ return transitionLonghands;
+}
+
+const StylePropertyShorthand& webkitTransitionShorthandForParsing()
+{
+ static const CSSPropertyID webkitTransitionProperties[] = {
+ CSSPropertyWebkitTransitionDuration,
+ CSSPropertyWebkitTransitionTimingFunction,
+ CSSPropertyWebkitTransitionDelay,
+ CSSPropertyWebkitTransitionProperty
+ };
+ DEFINE_STATIC_LOCAL(StylePropertyShorthand, webkitTransitionLonghands, (CSSPropertyWebkitTransition, webkitTransitionProperties, WTF_ARRAY_LENGTH(webkitTransitionProperties)));
+ return webkitTransitionLonghands;
+}
+
// Returns an empty list if the property is not a shorthand, otherwise the list of longhands for parsing.
const StylePropertyShorthand& parsingShorthandForProperty(CSSPropertyID propertyID)
{
@@ -96,6 +121,10 @@ const StylePropertyShorthand& parsingShorthandForProperty(CSSPropertyID property
return borderShorthandForParsing();
case CSSPropertyWebkitAnimation:
return webkitAnimationShorthandForParsing();
+ case CSSPropertyTransition:
+ return transitionShorthandForParsing();
+ case CSSPropertyWebkitTransition:
+ return webkitTransitionShorthandForParsing();
default:
return shorthandForProperty(propertyID);
}
@@ -113,6 +142,22 @@ bool isExpandedShorthand(CSSPropertyID id)
return shorthandForProperty(id).length();
}
+bool isExpandedShorthandForAll(CSSPropertyID propertyId)
+{
+ // FIXME: isExpandedShorthand says "font" is not an expanded shorthand,
+ // but font is expanded to font-family, font-size, and so on.
+ // StylePropertySerializer::asText should not generate css text like
+ // "font: initial; font-family: initial;...". To avoid this, we need to
+ // treat "font" as an expanded shorthand.
+ // And while applying "all" property, we cannot apply "font" property
+ // directly. This causes ASSERT crash, because StyleBuilder assume that
+ // all given properties are not expanded shorthands.
+ // "marker" has the same issue.
+ if (propertyId == CSSPropertyMarker || propertyId == CSSPropertyFont)
+ return true;
+ return shorthandForProperty(propertyId).length();
+}
+
unsigned indexOfShorthandForLonghand(CSSPropertyID shorthandID, const Vector<StylePropertyShorthand, 4>& shorthands)
{
for (unsigned i = 0; i < shorthands.size(); ++i) {
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleRule.cpp b/chromium/third_party/WebKit/Source/core/css/StyleRule.cpp
index 299f7a2300d..7735706796f 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/StyleRule.cpp
@@ -22,14 +22,12 @@
#include "config.h"
#include "core/css/StyleRule.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/css/CSSFilterRule.h"
#include "core/css/CSSFontFaceRule.h"
#include "core/css/CSSImportRule.h"
#include "core/css/CSSKeyframesRule.h"
#include "core/css/CSSMediaRule.h"
#include "core/css/CSSPageRule.h"
-#include "core/css/CSSRegionRule.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/CSSSupportsRule.h"
#include "core/css/CSSViewportRule.h"
@@ -38,22 +36,100 @@
namespace WebCore {
-struct SameSizeAsStyleRuleBase : public WTF::RefCountedBase {
+struct SameSizeAsStyleRuleBase : public RefCountedWillBeRefCountedGarbageCollected<SameSizeAsStyleRuleBase> {
unsigned bitfields;
};
COMPILE_ASSERT(sizeof(StyleRuleBase) <= sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
-PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
+PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
{
return createCSSOMWrapper(parentSheet, 0);
}
-PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const
+PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const
{
return createCSSOMWrapper(0, parentRule);
}
+void StyleRuleBase::trace(Visitor* visitor)
+{
+ switch (type()) {
+ case Style:
+ toStyleRule(this)->traceAfterDispatch(visitor);
+ return;
+ case Page:
+ toStyleRulePage(this)->traceAfterDispatch(visitor);
+ return;
+ case FontFace:
+ toStyleRuleFontFace(this)->traceAfterDispatch(visitor);
+ return;
+ case Media:
+ toStyleRuleMedia(this)->traceAfterDispatch(visitor);
+ return;
+ case Supports:
+ toStyleRuleSupports(this)->traceAfterDispatch(visitor);
+ return;
+ case Import:
+ toStyleRuleImport(this)->traceAfterDispatch(visitor);
+ return;
+ case Keyframes:
+ toStyleRuleKeyframes(this)->traceAfterDispatch(visitor);
+ return;
+ case Viewport:
+ toStyleRuleViewport(this)->traceAfterDispatch(visitor);
+ return;
+ case Filter:
+ toStyleRuleFilter(this)->traceAfterDispatch(visitor);
+ return;
+ case Unknown:
+ case Charset:
+ case Keyframe:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ASSERT_NOT_REACHED();
+}
+
+void StyleRuleBase::finalizeGarbageCollectedObject()
+{
+ switch (type()) {
+ case Style:
+ toStyleRule(this)->~StyleRule();
+ return;
+ case Page:
+ toStyleRulePage(this)->~StyleRulePage();
+ return;
+ case FontFace:
+ toStyleRuleFontFace(this)->~StyleRuleFontFace();
+ return;
+ case Media:
+ toStyleRuleMedia(this)->~StyleRuleMedia();
+ return;
+ case Supports:
+ toStyleRuleSupports(this)->~StyleRuleSupports();
+ return;
+ case Import:
+ toStyleRuleImport(this)->~StyleRuleImport();
+ return;
+ case Keyframes:
+ toStyleRuleKeyframes(this)->~StyleRuleKeyframes();
+ return;
+ case Viewport:
+ toStyleRuleViewport(this)->~StyleRuleViewport();
+ return;
+ case Filter:
+ toStyleRuleFilter(this)->~StyleRuleFilter();
+ return;
+ case Unknown:
+ case Charset:
+ case Keyframe:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ASSERT_NOT_REACHED();
+}
+
void StyleRuleBase::destroy()
{
switch (type()) {
@@ -72,9 +148,6 @@ void StyleRuleBase::destroy()
case Supports:
delete toStyleRuleSupports(this);
return;
- case Region:
- delete toStyleRuleRegion(this);
- return;
case Import:
delete toStyleRuleImport(this);
return;
@@ -96,7 +169,7 @@ void StyleRuleBase::destroy()
ASSERT_NOT_REACHED();
}
-PassRefPtr<StyleRuleBase> StyleRuleBase::copy() const
+PassRefPtrWillBeRawPtr<StyleRuleBase> StyleRuleBase::copy() const
{
switch (type()) {
case Style:
@@ -109,12 +182,10 @@ PassRefPtr<StyleRuleBase> StyleRuleBase::copy() const
return toStyleRuleMedia(this)->copy();
case Supports:
return toStyleRuleSupports(this)->copy();
- case Region:
- return toStyleRuleRegion(this)->copy();
case Import:
// FIXME: Copy import rules.
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
case Keyframes:
return toStyleRuleKeyframes(this)->copy();
case Viewport:
@@ -125,15 +196,15 @@ PassRefPtr<StyleRuleBase> StyleRuleBase::copy() const
case Charset:
case Keyframe:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
-PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const
+PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const
{
- RefPtr<CSSRule> rule;
+ RefPtrWillBeRawPtr<CSSRule> rule = nullptr;
StyleRuleBase* self = const_cast<StyleRuleBase*>(this);
switch (type()) {
case Style:
@@ -151,9 +222,6 @@ PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet
case Supports:
rule = CSSSupportsRule::create(toStyleRuleSupports(self), parentSheet);
break;
- case Region:
- rule = CSSRegionRule::create(toStyleRuleRegion(self), parentSheet);
- break;
case Import:
rule = CSSImportRule::create(toStyleRuleImport(self), parentSheet);
break;
@@ -170,7 +238,7 @@ PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet
case Charset:
case Keyframe:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
if (parentRule)
rule->setParentRule(parentRule);
@@ -198,11 +266,11 @@ StyleRule::~StyleRule()
{
}
-MutableStylePropertySet* StyleRule::mutableProperties()
+MutableStylePropertySet& StyleRule::mutableProperties()
{
if (!m_properties->isMutable())
m_properties = m_properties->mutableCopy();
- return toMutableStylePropertySet(m_properties);
+ return *toMutableStylePropertySet(m_properties);
}
void StyleRule::setProperties(PassRefPtr<StylePropertySet> properties)
@@ -226,11 +294,11 @@ StyleRulePage::~StyleRulePage()
{
}
-MutableStylePropertySet* StyleRulePage::mutableProperties()
+MutableStylePropertySet& StyleRulePage::mutableProperties()
{
if (!m_properties->isMutable())
m_properties = m_properties->mutableCopy();
- return toMutableStylePropertySet(m_properties);
+ return *toMutableStylePropertySet(m_properties);
}
void StyleRulePage::setProperties(PassRefPtr<StylePropertySet> properties)
@@ -253,11 +321,11 @@ StyleRuleFontFace::~StyleRuleFontFace()
{
}
-MutableStylePropertySet* StyleRuleFontFace::mutableProperties()
+MutableStylePropertySet& StyleRuleFontFace::mutableProperties()
{
if (!m_properties->isMutable())
m_properties = m_properties->mutableCopy();
- return toMutableStylePropertySet(m_properties);
+ return *toMutableStylePropertySet(m_properties);
}
void StyleRuleFontFace::setProperties(PassRefPtr<StylePropertySet> properties)
@@ -265,7 +333,7 @@ void StyleRuleFontFace::setProperties(PassRefPtr<StylePropertySet> properties)
m_properties = properties;
}
-StyleRuleGroup::StyleRuleGroup(Type type, Vector<RefPtr<StyleRuleBase> >& adoptRule)
+StyleRuleGroup::StyleRuleGroup(Type type, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRule)
: StyleRuleBase(type)
{
m_childRules.swap(adoptRule);
@@ -279,7 +347,7 @@ StyleRuleGroup::StyleRuleGroup(const StyleRuleGroup& o)
m_childRules[i] = o.m_childRules[i]->copy();
}
-void StyleRuleGroup::wrapperInsertRule(unsigned index, PassRefPtr<StyleRuleBase> rule)
+void StyleRuleGroup::wrapperInsertRule(unsigned index, PassRefPtrWillBeRawPtr<StyleRuleBase> rule)
{
m_childRules.insert(index, rule);
}
@@ -289,7 +357,13 @@ void StyleRuleGroup::wrapperRemoveRule(unsigned index)
m_childRules.remove(index);
}
-StyleRuleMedia::StyleRuleMedia(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase> >& adoptRules)
+void StyleRuleGroup::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_childRules);
+ StyleRuleBase::traceAfterDispatch(visitor);
+}
+
+StyleRuleMedia::StyleRuleMedia(PassRefPtrWillBeRawPtr<MediaQuerySet> media, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
: StyleRuleGroup(Media, adoptRules)
, m_mediaQueries(media)
{
@@ -302,7 +376,13 @@ StyleRuleMedia::StyleRuleMedia(const StyleRuleMedia& o)
m_mediaQueries = o.m_mediaQueries->copy();
}
-StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase> >& adoptRules)
+void StyleRuleMedia::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_mediaQueries);
+ StyleRuleGroup::traceAfterDispatch(visitor);
+}
+
+StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
: StyleRuleGroup(Supports, adoptRules)
, m_conditionText(conditionText)
, m_conditionIsSupported(conditionIsSupported)
@@ -316,20 +396,6 @@ StyleRuleSupports::StyleRuleSupports(const StyleRuleSupports& o)
{
}
-StyleRuleRegion::StyleRuleRegion(Vector<OwnPtr<CSSParserSelector> >* selectors, Vector<RefPtr<StyleRuleBase> >& adoptRules)
- : StyleRuleGroup(Region, adoptRules)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
- m_selectorList.adoptSelectorVector(*selectors);
-}
-
-StyleRuleRegion::StyleRuleRegion(const StyleRuleRegion& o)
- : StyleRuleGroup(o)
- , m_selectorList(o.m_selectorList)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
-}
-
StyleRuleViewport::StyleRuleViewport()
: StyleRuleBase(Viewport)
{
@@ -345,11 +411,11 @@ StyleRuleViewport::~StyleRuleViewport()
{
}
-MutableStylePropertySet* StyleRuleViewport::mutableProperties()
+MutableStylePropertySet& StyleRuleViewport::mutableProperties()
{
if (!m_properties->isMutable())
m_properties = m_properties->mutableCopy();
- return toMutableStylePropertySet(m_properties);
+ return *toMutableStylePropertySet(m_properties);
}
void StyleRuleViewport::setProperties(PassRefPtr<StylePropertySet> properties)
@@ -374,11 +440,11 @@ StyleRuleFilter::~StyleRuleFilter()
{
}
-MutableStylePropertySet* StyleRuleFilter::mutableProperties()
+MutableStylePropertySet& StyleRuleFilter::mutableProperties()
{
if (!m_properties->isMutable())
m_properties = m_properties->mutableCopy();
- return toMutableStylePropertySet(m_properties);
+ return *toMutableStylePropertySet(m_properties);
}
void StyleRuleFilter::setProperties(PassRefPtr<StylePropertySet> properties)
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleRule.h b/chromium/third_party/WebKit/Source/core/css/StyleRule.h
index e1216ebeedd..ab0853d7844 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleRule.h
+++ b/chromium/third_party/WebKit/Source/core/css/StyleRule.h
@@ -24,6 +24,7 @@
#include "core/css/CSSSelectorList.h"
#include "core/css/MediaList.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
@@ -34,8 +35,8 @@ class CSSStyleSheet;
class MutableStylePropertySet;
class StylePropertySet;
-class StyleRuleBase : public WTF::RefCountedBase {
- WTF_MAKE_FAST_ALLOCATED;
+class StyleRuleBase : public RefCountedWillBeGarbageCollectedFinalized<StyleRuleBase> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
enum Type {
Unknown, // Not used.
@@ -49,7 +50,6 @@ public:
Keyframe, // Not used. These are internally non-rule StyleKeyframe objects.
Supports = 12,
Viewport = 15,
- Region = 16,
Filter = 17
};
@@ -61,213 +61,216 @@ public:
bool isMediaRule() const { return type() == Media; }
bool isPageRule() const { return type() == Page; }
bool isStyleRule() const { return type() == Style; }
- bool isRegionRule() const { return type() == Region; }
bool isSupportsRule() const { return type() == Supports; }
bool isViewportRule() const { return type() == Viewport; }
bool isImportRule() const { return type() == Import; }
bool isFilterRule() const { return type() == Filter; }
- PassRefPtr<StyleRuleBase> copy() const;
+ PassRefPtrWillBeRawPtr<StyleRuleBase> copy() const;
+#if !ENABLE(OILPAN)
void deref()
{
if (derefBase())
destroy();
}
+#endif // !ENABLE(OILPAN)
// FIXME: There shouldn't be any need for the null parent version.
- PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = 0) const;
- PassRefPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const;
+ PassRefPtrWillBeRawPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = 0) const;
+ PassRefPtrWillBeRawPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const;
+
+ void trace(Visitor*);
+ void traceAfterDispatch(Visitor*) { };
+ void finalizeGarbageCollectedObject();
protected:
StyleRuleBase(Type type) : m_type(type) { }
- StyleRuleBase(const StyleRuleBase& o) : WTF::RefCountedBase(), m_type(o.m_type) { }
+ StyleRuleBase(const StyleRuleBase& o) : m_type(o.m_type) { }
~StyleRuleBase() { }
private:
void destroy();
- PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
+ PassRefPtrWillBeRawPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
unsigned m_type : 5;
};
class StyleRule : public StyleRuleBase {
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<StyleRule> create() { return adoptRef(new StyleRule()); }
+ static PassRefPtrWillBeRawPtr<StyleRule> create() { return adoptRefWillBeNoop(new StyleRule()); }
~StyleRule();
const CSSSelectorList& selectorList() const { return m_selectorList; }
- const StylePropertySet* properties() const { return m_properties.get(); }
- MutableStylePropertySet* mutableProperties();
+ const StylePropertySet& properties() const { return *m_properties; }
+ MutableStylePropertySet& mutableProperties();
void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); }
void setProperties(PassRefPtr<StylePropertySet>);
- PassRefPtr<StyleRule> copy() const { return adoptRef(new StyleRule(*this)); }
+ PassRefPtrWillBeRawPtr<StyleRule> copy() const { return adoptRefWillBeNoop(new StyleRule(*this)); }
static unsigned averageSizeInBytes();
+ void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
+
private:
StyleRule();
StyleRule(const StyleRule&);
- RefPtr<StylePropertySet> m_properties;
+ RefPtr<StylePropertySet> m_properties; // Cannot be null.
CSSSelectorList m_selectorList;
};
class StyleRuleFontFace : public StyleRuleBase {
public:
- static PassRefPtr<StyleRuleFontFace> create() { return adoptRef(new StyleRuleFontFace); }
+ static PassRefPtrWillBeRawPtr<StyleRuleFontFace> create() { return adoptRefWillBeNoop(new StyleRuleFontFace); }
~StyleRuleFontFace();
- const StylePropertySet* properties() const { return m_properties.get(); }
- MutableStylePropertySet* mutableProperties();
+ const StylePropertySet& properties() const { return *m_properties; }
+ MutableStylePropertySet& mutableProperties();
void setProperties(PassRefPtr<StylePropertySet>);
- PassRefPtr<StyleRuleFontFace> copy() const { return adoptRef(new StyleRuleFontFace(*this)); }
+ PassRefPtrWillBeRawPtr<StyleRuleFontFace> copy() const { return adoptRefWillBeNoop(new StyleRuleFontFace(*this)); }
+
+ void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
private:
StyleRuleFontFace();
StyleRuleFontFace(const StyleRuleFontFace&);
- RefPtr<StylePropertySet> m_properties;
+ RefPtr<StylePropertySet> m_properties; // Cannot be null.
};
class StyleRulePage : public StyleRuleBase {
public:
- static PassRefPtr<StyleRulePage> create() { return adoptRef(new StyleRulePage); }
+ static PassRefPtrWillBeRawPtr<StyleRulePage> create() { return adoptRefWillBeNoop(new StyleRulePage); }
~StyleRulePage();
const CSSSelector* selector() const { return m_selectorList.first(); }
- const StylePropertySet* properties() const { return m_properties.get(); }
- MutableStylePropertySet* mutableProperties();
+ const StylePropertySet& properties() const { return *m_properties; }
+ MutableStylePropertySet& mutableProperties();
void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); }
void setProperties(PassRefPtr<StylePropertySet>);
- PassRefPtr<StyleRulePage> copy() const { return adoptRef(new StyleRulePage(*this)); }
+ PassRefPtrWillBeRawPtr<StyleRulePage> copy() const { return adoptRefWillBeNoop(new StyleRulePage(*this)); }
+
+ void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
private:
StyleRulePage();
StyleRulePage(const StyleRulePage&);
- RefPtr<StylePropertySet> m_properties;
+ RefPtr<StylePropertySet> m_properties; // Cannot be null.
CSSSelectorList m_selectorList;
};
class StyleRuleGroup : public StyleRuleBase {
public:
- const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& childRules() const { return m_childRules; }
- void wrapperInsertRule(unsigned, PassRefPtr<StyleRuleBase>);
+ void wrapperInsertRule(unsigned, PassRefPtrWillBeRawPtr<StyleRuleBase>);
void wrapperRemoveRule(unsigned);
+ void traceAfterDispatch(Visitor*);
+
protected:
- StyleRuleGroup(Type, Vector<RefPtr<StyleRuleBase> >& adoptRule);
+ StyleRuleGroup(Type, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRule);
StyleRuleGroup(const StyleRuleGroup&);
private:
- Vector<RefPtr<StyleRuleBase> > m_childRules;
+ WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_childRules;
};
class StyleRuleMedia : public StyleRuleGroup {
public:
- static PassRefPtr<StyleRuleMedia> create(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase> >& adoptRules)
+ static PassRefPtrWillBeRawPtr<StyleRuleMedia> create(PassRefPtrWillBeRawPtr<MediaQuerySet> media, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
{
- return adoptRef(new StyleRuleMedia(media, adoptRules));
+ return adoptRefWillBeNoop(new StyleRuleMedia(media, adoptRules));
}
MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
- PassRefPtr<StyleRuleMedia> copy() const { return adoptRef(new StyleRuleMedia(*this)); }
+ PassRefPtrWillBeRawPtr<StyleRuleMedia> copy() const { return adoptRefWillBeNoop(new StyleRuleMedia(*this)); }
+
+ void traceAfterDispatch(Visitor*);
private:
- StyleRuleMedia(PassRefPtr<MediaQuerySet>, Vector<RefPtr<StyleRuleBase> >& adoptRules);
+ StyleRuleMedia(PassRefPtrWillBeRawPtr<MediaQuerySet>, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules);
StyleRuleMedia(const StyleRuleMedia&);
- RefPtr<MediaQuerySet> m_mediaQueries;
+ RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
};
class StyleRuleSupports : public StyleRuleGroup {
public:
- static PassRefPtr<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase> >& adoptRules)
+ static PassRefPtrWillBeRawPtr<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
{
- return adoptRef(new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules));
+ return adoptRefWillBeNoop(new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules));
}
String conditionText() const { return m_conditionText; }
bool conditionIsSupported() const { return m_conditionIsSupported; }
- PassRefPtr<StyleRuleSupports> copy() const { return adoptRef(new StyleRuleSupports(*this)); }
+ PassRefPtrWillBeRawPtr<StyleRuleSupports> copy() const { return adoptRefWillBeNoop(new StyleRuleSupports(*this)); }
+
+ void traceAfterDispatch(Visitor* visitor) { StyleRuleGroup::traceAfterDispatch(visitor); }
private:
- StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase> >& adoptRules);
+ StyleRuleSupports(const String& conditionText, bool conditionIsSupported, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules);
StyleRuleSupports(const StyleRuleSupports&);
String m_conditionText;
bool m_conditionIsSupported;
};
-class StyleRuleRegion : public StyleRuleGroup {
-public:
- static PassRefPtr<StyleRuleRegion> create(Vector<OwnPtr<CSSParserSelector> >* selectors, Vector<RefPtr<StyleRuleBase> >& adoptRules)
- {
- return adoptRef(new StyleRuleRegion(selectors, adoptRules));
- }
-
- const CSSSelectorList& selectorList() const { return m_selectorList; }
-
- PassRefPtr<StyleRuleRegion> copy() const { return adoptRef(new StyleRuleRegion(*this)); }
-
-private:
- StyleRuleRegion(Vector<OwnPtr<CSSParserSelector> >*, Vector<RefPtr<StyleRuleBase> >& adoptRules);
- StyleRuleRegion(const StyleRuleRegion&);
-
- CSSSelectorList m_selectorList;
-};
-
class StyleRuleViewport : public StyleRuleBase {
public:
- static PassRefPtr<StyleRuleViewport> create() { return adoptRef(new StyleRuleViewport); }
+ static PassRefPtrWillBeRawPtr<StyleRuleViewport> create() { return adoptRefWillBeNoop(new StyleRuleViewport); }
~StyleRuleViewport();
- const StylePropertySet* properties() const { return m_properties.get(); }
- MutableStylePropertySet* mutableProperties();
+ const StylePropertySet& properties() const { return *m_properties; }
+ MutableStylePropertySet& mutableProperties();
void setProperties(PassRefPtr<StylePropertySet>);
- PassRefPtr<StyleRuleViewport> copy() const { return adoptRef(new StyleRuleViewport(*this)); }
+ PassRefPtrWillBeRawPtr<StyleRuleViewport> copy() const { return adoptRefWillBeNoop(new StyleRuleViewport(*this)); }
+
+ void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
private:
StyleRuleViewport();
StyleRuleViewport(const StyleRuleViewport&);
- RefPtr<StylePropertySet> m_properties;
+ RefPtr<StylePropertySet> m_properties; // Cannot be null
};
class StyleRuleFilter : public StyleRuleBase {
public:
- static PassRefPtr<StyleRuleFilter> create(const String& filterName) { return adoptRef(new StyleRuleFilter(filterName)); }
+ static PassRefPtrWillBeRawPtr<StyleRuleFilter> create(const String& filterName) { return adoptRefWillBeNoop(new StyleRuleFilter(filterName)); }
~StyleRuleFilter();
const String& filterName() const { return m_filterName; }
- const StylePropertySet* properties() const { return m_properties.get(); }
- MutableStylePropertySet* mutableProperties();
+ const StylePropertySet& properties() const { return *m_properties; }
+ MutableStylePropertySet& mutableProperties();
void setProperties(PassRefPtr<StylePropertySet>);
- PassRefPtr<StyleRuleFilter> copy() const { return adoptRef(new StyleRuleFilter(*this)); }
+ PassRefPtrWillBeRawPtr<StyleRuleFilter> copy() const { return adoptRefWillBeNoop(new StyleRuleFilter(*this)); }
+
+ void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
private:
StyleRuleFilter(const String&);
@@ -285,7 +288,6 @@ DEFINE_STYLE_RULE_TYPE_CASTS(FontFace);
DEFINE_STYLE_RULE_TYPE_CASTS(Page);
DEFINE_STYLE_RULE_TYPE_CASTS(Media);
DEFINE_STYLE_RULE_TYPE_CASTS(Supports);
-DEFINE_STYLE_RULE_TYPE_CASTS(Region);
DEFINE_STYLE_RULE_TYPE_CASTS(Viewport);
DEFINE_STYLE_RULE_TYPE_CASTS(Filter);
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp b/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp
index aff60cb9ecd..13fd117ca58 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "core/css/StyleRuleImport.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/Document.h"
#include "core/fetch/CSSStyleSheetResource.h"
@@ -31,14 +31,14 @@
namespace WebCore {
-PassRefPtr<StyleRuleImport> StyleRuleImport::create(const String& href, PassRefPtr<MediaQuerySet> media)
+PassRefPtrWillBeRawPtr<StyleRuleImport> StyleRuleImport::create(const String& href, PassRefPtrWillBeRawPtr<MediaQuerySet> media)
{
- return adoptRef(new StyleRuleImport(href, media));
+ return adoptRefWillBeNoop(new StyleRuleImport(href, media));
}
-StyleRuleImport::StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet> media)
+StyleRuleImport::StyleRuleImport(const String& href, PassRefPtrWillBeRawPtr<MediaQuerySet> media)
: StyleRuleBase(Import)
- , m_parentStyleSheet(0)
+ , m_parentStyleSheet(nullptr)
, m_styleSheetClient(this)
, m_strHref(href)
, m_mediaQueries(media)
@@ -51,25 +51,38 @@ StyleRuleImport::StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet> m
StyleRuleImport::~StyleRuleImport()
{
+#if !ENABLE(OILPAN)
if (m_styleSheet)
m_styleSheet->clearOwnerRule();
+#endif
if (m_resource)
m_resource->removeClient(&m_styleSheetClient);
}
+void StyleRuleImport::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_parentStyleSheet);
+ visitor->trace(m_mediaQueries);
+ visitor->trace(m_styleSheet);
+ StyleRuleBase::traceAfterDispatch(visitor);
+}
+
void StyleRuleImport::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* cachedStyleSheet)
{
if (m_styleSheet)
m_styleSheet->clearOwnerRule();
- CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : HTMLStandardMode;
+ CSSParserContext context = m_parentStyleSheet ? m_parentStyleSheet->parserContext() : strictCSSParserContext();
context.setCharset(charset);
- if (!baseURL.isNull())
+ Document* document = m_parentStyleSheet ? m_parentStyleSheet->singleOwnerDocument() : 0;
+ if (!baseURL.isNull()) {
context.setBaseURL(baseURL);
+ if (document)
+ context.setReferrer(Referrer(baseURL.strippedForUseAsReferrer(), document->referrerPolicy()));
+ }
m_styleSheet = StyleSheetContents::create(this, href, context);
- Document* document = m_parentStyleSheet ? m_parentStyleSheet->singleOwnerDocument() : 0;
m_styleSheet->parseAuthorStyleSheet(cachedStyleSheet, document ? document->securityOrigin() : 0);
m_loading = false;
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.h b/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.h
index 8af664e2438..e67f7120a0c 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.h
+++ b/chromium/third_party/WebKit/Source/core/css/StyleRuleImport.h
@@ -25,6 +25,7 @@
#include "core/css/StyleRule.h"
#include "core/fetch/ResourcePtr.h"
#include "core/fetch/StyleSheetResourceClient.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -33,15 +34,15 @@ class MediaQuerySet;
class StyleSheetContents;
class StyleRuleImport : public StyleRuleBase {
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<StyleRuleImport> create(const String& href, PassRefPtr<MediaQuerySet>);
+ static PassRefPtrWillBeRawPtr<StyleRuleImport> create(const String& href, PassRefPtrWillBeRawPtr<MediaQuerySet>);
~StyleRuleImport();
StyleSheetContents* parentStyleSheet() const { return m_parentStyleSheet; }
void setParentStyleSheet(StyleSheetContents* sheet) { ASSERT(sheet); m_parentStyleSheet = sheet; }
- void clearParentStyleSheet() { m_parentStyleSheet = 0; }
+ void clearParentStyleSheet() { m_parentStyleSheet = nullptr; }
String href() const { return m_strHref; }
StyleSheetContents* styleSheet() const { return m_styleSheet.get(); }
@@ -51,14 +52,17 @@ public:
void requestStyleSheet();
+ void traceAfterDispatch(Visitor*);
+
private:
+ // FIXME: inherit from StyleSheetResourceClient directly to eliminate raw back pointer, as there are no space savings in this.
// NOTE: We put the StyleSheetResourceClient in a member instead of inheriting from it
// to avoid adding a vptr to StyleRuleImport.
- class ImportedStyleSheetClient : public StyleSheetResourceClient {
+ class ImportedStyleSheetClient FINAL : public StyleSheetResourceClient {
public:
ImportedStyleSheetClient(StyleRuleImport* ownerRule) : m_ownerRule(ownerRule) { }
virtual ~ImportedStyleSheetClient() { }
- virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* sheet)
+ virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* sheet) OVERRIDE
{
m_ownerRule->setCSSStyleSheet(href, baseURL, charset, sheet);
}
@@ -69,14 +73,14 @@ private:
void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*);
friend class ImportedStyleSheetClient;
- StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet>);
+ StyleRuleImport(const String& href, PassRefPtrWillBeRawPtr<MediaQuerySet>);
- StyleSheetContents* m_parentStyleSheet;
+ RawPtrWillBeMember<StyleSheetContents> m_parentStyleSheet;
ImportedStyleSheetClient m_styleSheetClient;
String m_strHref;
- RefPtr<MediaQuerySet> m_mediaQueries;
- RefPtr<StyleSheetContents> m_styleSheet;
+ RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
+ RefPtrWillBeMember<StyleSheetContents> m_styleSheet;
ResourcePtr<CSSStyleSheetResource> m_resource;
bool m_loading;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleSheet.h b/chromium/third_party/WebKit/Source/core/css/StyleSheet.h
index 2207b5a006c..136fa1d4ba9 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleSheet.h
+++ b/chromium/third_party/WebKit/Source/core/css/StyleSheet.h
@@ -22,6 +22,7 @@
#define StyleSheet_h
#include "core/css/CSSParserMode.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
@@ -33,7 +34,7 @@ class MediaList;
class Node;
class StyleSheet;
-class StyleSheet : public RefCounted<StyleSheet> {
+class StyleSheet : public RefCountedWillBeGarbageCollectedFinalized<StyleSheet> {
public:
virtual ~StyleSheet();
@@ -51,6 +52,8 @@ public:
virtual KURL baseURL() const = 0;
virtual bool isLoading() const = 0;
virtual bool isCSSStyleSheet() const { return false; }
+
+ virtual void trace(Visitor*) { }
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleSheet.idl b/chromium/third_party/WebKit/Source/core/css/StyleSheet.idl
index e3e13b37b1d..ed83f144757 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleSheet.idl
+++ b/chromium/third_party/WebKit/Source/core/css/StyleSheet.idl
@@ -21,7 +21,8 @@
// Introduced in DOM Level 2:
[
Custom=Wrap,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
+ WillBeGarbageCollected
] interface StyleSheet {
[TreatReturnedNullStringAs=Null] readonly attribute DOMString type;
attribute boolean disabled;
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.cpp b/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
index fa7b022da58..2b3da24942a 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
@@ -21,16 +21,17 @@
#include "config.h"
#include "core/css/StyleSheetContents.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/MediaList.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRule.h"
#include "core/css/StyleRuleImport.h"
-#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Document.h"
#include "core/dom/Node.h"
#include "core/dom/StyleEngine.h"
#include "core/fetch/CSSStyleSheetResource.h"
+#include "core/frame/UseCounter.h"
#include "platform/TraceEvent.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/Deque.h"
@@ -44,7 +45,7 @@ unsigned StyleSheetContents::estimatedSizeInBytes() const
// The assumption is that nearly all of of them are atomic and would exist anyway.
unsigned size = sizeof(*this);
- // FIXME: This ignores the children of media and region rules.
+ // FIXME: This ignores the children of media rules.
// Most rules are StyleRules.
size += ruleCount() * StyleRule::averageSizeInBytes();
@@ -58,32 +59,33 @@ unsigned StyleSheetContents::estimatedSizeInBytes() const
StyleSheetContents::StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
: m_ownerRule(ownerRule)
, m_originalURL(originalURL)
- , m_loadCompleted(false)
, m_hasSyntacticallyValidCSSHeader(true)
, m_didLoadErrorOccur(false)
, m_usesRemUnits(false)
, m_isMutable(false)
, m_isInMemoryCache(false)
, m_hasFontFaceRule(false)
+ , m_hasMediaQueries(false)
+ , m_hasSingleOwnerDocument(true)
, m_parserContext(context)
{
}
StyleSheetContents::StyleSheetContents(const StyleSheetContents& o)
- : RefCounted<StyleSheetContents>()
- , m_ownerRule(0)
+ : m_ownerRule(nullptr)
, m_originalURL(o.m_originalURL)
, m_encodingFromCharsetRule(o.m_encodingFromCharsetRule)
, m_importRules(o.m_importRules.size())
, m_childRules(o.m_childRules.size())
, m_namespaces(o.m_namespaces)
- , m_loadCompleted(true)
, m_hasSyntacticallyValidCSSHeader(o.m_hasSyntacticallyValidCSSHeader)
, m_didLoadErrorOccur(false)
, m_usesRemUnits(o.m_usesRemUnits)
, m_isMutable(false)
, m_isInMemoryCache(false)
, m_hasFontFaceRule(o.m_hasFontFaceRule)
+ , m_hasMediaQueries(o.m_hasMediaQueries)
+ , m_hasSingleOwnerDocument(true)
, m_parserContext(o.m_parserContext)
{
ASSERT(o.isCacheable());
@@ -97,11 +99,25 @@ StyleSheetContents::StyleSheetContents(const StyleSheetContents& o)
StyleSheetContents::~StyleSheetContents()
{
+#if !ENABLE(OILPAN)
clearRules();
+#endif
+}
+
+void StyleSheetContents::setHasSyntacticallyValidCSSHeader(bool isValidCss)
+{
+ if (!isValidCss) {
+ if (Document* document = clientSingleOwnerDocument())
+ removeSheetFromCache(document);
+ }
+ m_hasSyntacticallyValidCSSHeader = isValidCss;
}
bool StyleSheetContents::isCacheable() const
{
+ // This would require dealing with multiple clients for load callbacks.
+ if (!loadCompleted())
+ return false;
// FIXME: StyleSheets with media queries can't be cached because their RuleSet
// is processed differently based off the media queries, which might resolve
// differently depending on the context of the parent CSSStyleSheet (e.g.
@@ -115,9 +131,6 @@ bool StyleSheetContents::isCacheable() const
// FIXME: Support cached stylesheets in import rules.
if (m_ownerRule)
return false;
- // This would require dealing with multiple clients for load callbacks.
- if (!m_loadCompleted)
- return false;
if (m_didLoadErrorOccur)
return false;
// It is not the original sheet anymore.
@@ -130,7 +143,7 @@ bool StyleSheetContents::isCacheable() const
return true;
}
-void StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule)
+void StyleSheetContents::parserAppendRule(PassRefPtrWillBeRawPtr<StyleRuleBase> rule)
{
ASSERT(!rule->isCharsetRule());
if (rule->isImportRule()) {
@@ -210,7 +223,7 @@ void StyleSheetContents::parserSetEncodingFromCharsetRule(const String& encoding
m_encodingFromCharsetRule = encoding;
}
-bool StyleSheetContents::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsigned index)
+bool StyleSheetContents::wrapperInsertRule(PassRefPtrWillBeRawPtr<StyleRuleBase> rule, unsigned index)
{
ASSERT(m_isMutable);
ASSERT_WITH_SECURITY_IMPLICATION(index <= ruleCount());
@@ -251,6 +264,8 @@ bool StyleSheetContents::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsig
childVectorIndex -= m_importRules.size();
+ if (rule->isFontFaceRule())
+ setHasFontFaceRule(true);
m_childRules.insert(childVectorIndex, rule);
return true;
}
@@ -270,11 +285,15 @@ void StyleSheetContents::wrapperDeleteRule(unsigned index)
}
if (childVectorIndex < m_importRules.size()) {
m_importRules[childVectorIndex]->clearParentStyleSheet();
+ if (m_importRules[childVectorIndex]->isFontFaceRule())
+ notifyRemoveFontFaceRule(toStyleRuleFontFace(m_importRules[childVectorIndex].get()));
m_importRules.remove(childVectorIndex);
return;
}
childVectorIndex -= m_importRules.size();
+ if (m_childRules[childVectorIndex]->isFontFaceRule())
+ notifyRemoveFontFaceRule(toStyleRuleFontFace(m_childRules[childVectorIndex].get()));
m_childRules.remove(childVectorIndex);
}
@@ -285,7 +304,7 @@ void StyleSheetContents::parserAddNamespace(const AtomicString& prefix, const At
PrefixNamespaceURIMap::AddResult result = m_namespaces.add(prefix, uri);
if (result.isNewEntry)
return;
- result.iterator->value = uri;
+ result.storedValue->value = uri;
}
const AtomicString& StyleSheetContents::determineNamespace(const AtomicString& prefix)
@@ -307,7 +326,8 @@ void StyleSheetContents::parseAuthorStyleSheet(const CSSStyleSheetResource* cach
bool hasValidMIMEType = false;
String sheetText = cachedStyleSheet->sheetText(enforceMIMEType, &hasValidMIMEType);
- CSSParser p(parserContext(), UseCounter::getFrom(this));
+ CSSParserContext context(parserContext(), UseCounter::getFrom(this));
+ BisonCSSParser p(context);
p.parseSheet(this, sheetText, TextPosition::minimumPosition(), 0, true);
// If we're loading a stylesheet cross-origin, and the MIME type is not standard, require the CSS
@@ -329,7 +349,8 @@ bool StyleSheetContents::parseString(const String& sheetText)
bool StyleSheetContents::parseStringAtPosition(const String& sheetText, const TextPosition& startPosition, bool createdByParser)
{
- CSSParser p(parserContext(), UseCounter::getFrom(this));
+ CSSParserContext context(parserContext(), UseCounter::getFrom(this));
+ BisonCSSParser p(context);
p.parseSheet(this, sheetText, startPosition, 0, createdByParser);
return true;
@@ -344,6 +365,16 @@ bool StyleSheetContents::isLoading() const
return false;
}
+bool StyleSheetContents::loadCompleted() const
+{
+ StyleSheetContents* parentSheet = parentStyleSheet();
+ if (parentSheet)
+ return parentSheet->loadCompleted();
+
+ StyleSheetContents* root = rootStyleSheet();
+ return root->m_loadingClients.isEmpty();
+}
+
void StyleSheetContents::checkLoaded()
{
if (isLoading())
@@ -352,22 +383,39 @@ void StyleSheetContents::checkLoaded()
// Avoid |this| being deleted by scripts that run via
// ScriptableDocumentParser::executeScriptsWaitingForResources().
// See https://bugs.webkit.org/show_bug.cgi?id=95106
- RefPtr<StyleSheetContents> protect(this);
+ RefPtrWillBeRawPtr<StyleSheetContents> protect(this);
StyleSheetContents* parentSheet = parentStyleSheet();
if (parentSheet) {
parentSheet->checkLoaded();
- m_loadCompleted = true;
return;
}
- RefPtr<Node> ownerNode = singleOwnerNode();
- if (!ownerNode) {
- m_loadCompleted = true;
+
+ StyleSheetContents* root = rootStyleSheet();
+ if (root->m_loadingClients.isEmpty())
return;
+
+ // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via
+ // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also protect
+ // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoaded|
+ // method.
+ //
+ // When a sheet is loaded it is moved from the set of loading clients
+ // to the set of completed clients. We therefore need the copy in order to
+ // not modify the set while iterating it.
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > loadingClients;
+ copyToVector(m_loadingClients, loadingClients);
+
+ for (unsigned i = 0; i < loadingClients.size(); ++i) {
+ if (loadingClients[i]->loadCompleted())
+ continue;
+
+ // sheetLoaded might be invoked after its owner node is removed from document.
+ if (RefPtrWillBeRawPtr<Node> ownerNode = loadingClients[i]->ownerNode()) {
+ if (loadingClients[i]->sheetLoaded())
+ ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
+ }
}
- m_loadCompleted = ownerNode->sheetLoaded();
- if (m_loadCompleted)
- ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
}
void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet)
@@ -382,8 +430,18 @@ void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet)
void StyleSheetContents::startLoadingDynamicSheet()
{
- if (Node* owner = singleOwnerNode())
- owner->startLoadingDynamicSheet();
+ StyleSheetContents* root = rootStyleSheet();
+ for (ClientsIterator it = root->m_loadingClients.begin(); it != root->m_loadingClients.end(); ++it)
+ (*it)->startLoadingDynamicSheet();
+ // Copy the completed clients to a vector for iteration.
+ // startLoadingDynamicSheet will move the style sheet from the
+ // completed state to the loading state which modifies the set of
+ // completed clients. We therefore need the copy in order to not
+ // modify the set of completed clients while iterating it.
+ WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> > completedClients;
+ copyToVector(root->m_completedClients, completedClients);
+ for (unsigned i = 0; i < completedClients.size(); ++i)
+ completedClients[i]->startLoadingDynamicSheet();
}
StyleSheetContents* StyleSheetContents::rootStyleSheet() const
@@ -396,78 +454,48 @@ StyleSheetContents* StyleSheetContents::rootStyleSheet() const
bool StyleSheetContents::hasSingleOwnerNode() const
{
- StyleSheetContents* root = rootStyleSheet();
- if (root->m_clients.isEmpty())
- return false;
- return root->m_clients.size() == 1;
+ return rootStyleSheet()->hasOneClient();
}
Node* StyleSheetContents::singleOwnerNode() const
{
StyleSheetContents* root = rootStyleSheet();
- if (root->m_clients.isEmpty())
+ if (!root->hasOneClient())
return 0;
- ASSERT(root->m_clients.size() == 1);
- return root->m_clients[0]->ownerNode();
+ if (root->m_loadingClients.size())
+ return (*root->m_loadingClients.begin())->ownerNode();
+ return (*root->m_completedClients.begin())->ownerNode();
}
Document* StyleSheetContents::singleOwnerDocument() const
{
- Node* ownerNode = singleOwnerNode();
- return ownerNode ? &ownerNode->document() : 0;
+ StyleSheetContents* root = rootStyleSheet();
+ return root->clientSingleOwnerDocument();
}
KURL StyleSheetContents::completeURL(const String& url) const
{
- return CSSParser::completeURL(m_parserContext, url);
+ // FIXME: This is only OK when we have a singleOwnerNode, right?
+ return m_parserContext.completeURL(url);
}
-void StyleSheetContents::addSubresourceStyleURLs(ListHashSet<KURL>& urls)
-{
- Deque<StyleSheetContents*> styleSheetQueue;
- styleSheetQueue.append(this);
-
- while (!styleSheetQueue.isEmpty()) {
- StyleSheetContents* styleSheet = styleSheetQueue.takeFirst();
-
- for (unsigned i = 0; i < styleSheet->m_importRules.size(); ++i) {
- StyleRuleImport* importRule = styleSheet->m_importRules[i].get();
- if (importRule->styleSheet()) {
- styleSheetQueue.append(importRule->styleSheet());
- addSubresourceURL(urls, importRule->styleSheet()->baseURL());
- }
- }
- for (unsigned i = 0; i < styleSheet->m_childRules.size(); ++i) {
- StyleRuleBase* rule = styleSheet->m_childRules[i].get();
- if (rule->isStyleRule())
- toStyleRule(rule)->properties()->addSubresourceStyleURLs(urls, this);
- else if (rule->isFontFaceRule())
- toStyleRuleFontFace(rule)->properties()->addSubresourceStyleURLs(urls, this);
- }
- }
-}
-
-static bool childRulesHaveFailedOrCanceledSubresources(const Vector<RefPtr<StyleRuleBase> >& rules)
+static bool childRulesHaveFailedOrCanceledSubresources(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules)
{
for (unsigned i = 0; i < rules.size(); ++i) {
const StyleRuleBase* rule = rules[i].get();
switch (rule->type()) {
case StyleRuleBase::Style:
- if (toStyleRule(rule)->properties()->hasFailedOrCanceledSubresources())
+ if (toStyleRule(rule)->properties().hasFailedOrCanceledSubresources())
return true;
break;
case StyleRuleBase::FontFace:
- if (toStyleRuleFontFace(rule)->properties()->hasFailedOrCanceledSubresources())
+ if (toStyleRuleFontFace(rule)->properties().hasFailedOrCanceledSubresources())
return true;
break;
case StyleRuleBase::Media:
if (childRulesHaveFailedOrCanceledSubresources(toStyleRuleMedia(rule)->childRules()))
return true;
break;
- case StyleRuleBase::Region:
- if (childRulesHaveFailedOrCanceledSubresources(toStyleRuleRegion(rule)->childRules()))
- return true;
- break;
case StyleRuleBase::Import:
ASSERT_NOT_REACHED();
case StyleRuleBase::Page:
@@ -490,6 +518,16 @@ bool StyleSheetContents::hasFailedOrCanceledSubresources() const
return childRulesHaveFailedOrCanceledSubresources(m_childRules);
}
+Document* StyleSheetContents::clientSingleOwnerDocument() const
+{
+ if (!m_hasSingleOwnerDocument || clientSize() <= 0)
+ return 0;
+
+ if (m_loadingClients.size())
+ return (*m_loadingClients.begin())->ownerDocument();
+ return (*m_completedClients.begin())->ownerDocument();
+}
+
StyleSheetContents* StyleSheetContents::parentStyleSheet() const
{
return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0;
@@ -497,15 +535,55 @@ StyleSheetContents* StyleSheetContents::parentStyleSheet() const
void StyleSheetContents::registerClient(CSSStyleSheet* sheet)
{
- ASSERT(!m_clients.contains(sheet));
- m_clients.append(sheet);
+ ASSERT(!m_loadingClients.contains(sheet) && !m_completedClients.contains(sheet));
+
+ // InspectorCSSAgent::buildObjectForRule creates CSSStyleSheet without any owner node.
+ if (!sheet->ownerDocument())
+ return;
+
+ if (Document* document = clientSingleOwnerDocument()) {
+ if (sheet->ownerDocument() != document)
+ m_hasSingleOwnerDocument = false;
+ }
+ m_loadingClients.add(sheet);
}
void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet)
{
- size_t position = m_clients.find(sheet);
- ASSERT(position != kNotFound);
- m_clients.remove(position);
+ m_loadingClients.remove(sheet);
+ m_completedClients.remove(sheet);
+
+ if (!sheet->ownerDocument() || !m_loadingClients.isEmpty() || !m_completedClients.isEmpty())
+ return;
+
+ if (m_hasSingleOwnerDocument)
+ removeSheetFromCache(sheet->ownerDocument());
+ m_hasSingleOwnerDocument = true;
+}
+
+void StyleSheetContents::clientLoadCompleted(CSSStyleSheet* sheet)
+{
+ ASSERT(m_loadingClients.contains(sheet) || !sheet->ownerDocument());
+ m_loadingClients.remove(sheet);
+ // In m_ownerNode->sheetLoaded, the CSSStyleSheet might be detached.
+ // (i.e. clearOwnerNode was invoked.)
+ // In this case, we don't need to add the stylesheet to completed clients.
+ if (!sheet->ownerDocument())
+ return;
+ m_completedClients.add(sheet);
+}
+
+void StyleSheetContents::clientLoadStarted(CSSStyleSheet* sheet)
+{
+ ASSERT(m_completedClients.contains(sheet));
+ m_completedClients.remove(sheet);
+ m_loadingClients.add(sheet);
+}
+
+void StyleSheetContents::removeSheetFromCache(Document* document)
+{
+ ASSERT(document);
+ document->styleEngine()->removeSheet(this);
}
void StyleSheetContents::addedToMemoryCache()
@@ -537,6 +615,14 @@ RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad
return *m_ruleSet.get();
}
+static void clearResolvers(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >& clients)
+{
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) {
+ if (Document* document = (*it)->ownerDocument())
+ document->styleEngine()->clearResolver();
+ }
+}
+
void StyleSheetContents::clearRuleSet()
{
if (StyleSheetContents* parentSheet = parentStyleSheet())
@@ -550,12 +636,61 @@ void StyleSheetContents::clearRuleSet()
// Clearing the ruleSet means we need to recreate the styleResolver data structures.
// See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet.
- for (size_t i = 0; i < m_clients.size(); ++i) {
- if (Document* document = m_clients[i]->ownerDocument())
- document->styleEngine()->clearResolver();
- }
+ clearResolvers(m_loadingClients);
+ clearResolvers(m_completedClients);
m_ruleSet.clear();
}
+static void removeFontFaceRules(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >& clients, const StyleRuleFontFace* fontFaceRule)
+{
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) {
+ if (Node* ownerNode = (*it)->ownerNode())
+ ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule));
+ }
+}
+
+void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontFaceRule)
+{
+ StyleSheetContents* root = rootStyleSheet();
+ removeFontFaceRules(root->m_loadingClients, fontFaceRule);
+ removeFontFaceRules(root->m_completedClients, fontFaceRule);
+}
+
+static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
+{
+ for (unsigned i = 0; i < rules.size(); ++i) {
+ StyleRuleBase* rule = rules[i].get();
+
+ if (rule->isFontFaceRule()) {
+ fontFaceRules.append(toStyleRuleFontFace(rule));
+ } else if (rule->isMediaRule()) {
+ StyleRuleMedia* mediaRule = toStyleRuleMedia(rule);
+ // We cannot know whether the media rule matches or not, but
+ // for safety, remove @font-face in the media rule (if exists).
+ findFontFaceRulesFromRules(mediaRule->childRules(), fontFaceRules);
+ }
+ }
+}
+
+void StyleSheetContents::findFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
+{
+ for (unsigned i = 0; i < m_importRules.size(); ++i) {
+ if (!m_importRules[i]->styleSheet())
+ continue;
+ m_importRules[i]->styleSheet()->findFontFaceRules(fontFaceRules);
+ }
+
+ findFontFaceRulesFromRules(childRules(), fontFaceRules);
+}
+
+void StyleSheetContents::trace(Visitor* visitor)
+{
+ visitor->trace(m_ownerRule);
+ visitor->trace(m_importRules);
+ visitor->trace(m_childRules);
+ visitor->trace(m_loadingClients);
+ visitor->trace(m_completedClients);
+ visitor->trace(m_ruleSet);
+}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h b/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h
index 7d59d80ef93..7dca729d02b 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h
+++ b/chromium/third_party/WebKit/Source/core/css/StyleSheetContents.h
@@ -23,6 +23,7 @@
#include "core/css/CSSParserMode.h"
#include "core/css/RuleSet.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/HashMap.h"
#include "wtf/ListHashSet.h"
@@ -41,21 +42,22 @@ class Document;
class Node;
class SecurityOrigin;
class StyleRuleBase;
+class StyleRuleFontFace;
class StyleRuleImport;
-class StyleSheetContents : public RefCounted<StyleSheetContents> {
+class StyleSheetContents : public RefCountedWillBeGarbageCollectedFinalized<StyleSheetContents> {
public:
- static PassRefPtr<StyleSheetContents> create(const CSSParserContext& context = CSSParserContext(HTMLStandardMode))
+ static PassRefPtrWillBeRawPtr<StyleSheetContents> create(const CSSParserContext& context)
{
- return adoptRef(new StyleSheetContents(0, String(), context));
+ return adoptRefWillBeNoop(new StyleSheetContents(0, String(), context));
}
- static PassRefPtr<StyleSheetContents> create(const String& originalURL, const CSSParserContext& context)
+ static PassRefPtrWillBeRawPtr<StyleSheetContents> create(const String& originalURL, const CSSParserContext& context)
{
- return adoptRef(new StyleSheetContents(0, originalURL, context));
+ return adoptRefWillBeNoop(new StyleSheetContents(0, originalURL, context));
}
- static PassRefPtr<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
+ static PassRefPtrWillBeRawPtr<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
{
- return adoptRef(new StyleSheetContents(ownerRule, originalURL, context));
+ return adoptRefWillBeNoop(new StyleSheetContents(ownerRule, originalURL, context));
}
~StyleSheetContents();
@@ -82,20 +84,20 @@ public:
const String& charset() const { return m_parserContext.charset(); }
- bool loadCompleted() const { return m_loadCompleted; }
+ bool loadCompleted() const;
bool hasFailedOrCanceledSubresources() const;
KURL completeURL(const String& url) const;
- void addSubresourceStyleURLs(ListHashSet<KURL>&);
- void setHasSyntacticallyValidCSSHeader(bool b) { m_hasSyntacticallyValidCSSHeader = b; }
+ void setHasSyntacticallyValidCSSHeader(bool isValidCss);
bool hasSyntacticallyValidCSSHeader() const { return m_hasSyntacticallyValidCSSHeader; }
void setHasFontFaceRule(bool b) { m_hasFontFaceRule = b; }
bool hasFontFaceRule() const { return m_hasFontFaceRule; }
+ void findFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules);
void parserAddNamespace(const AtomicString& prefix, const AtomicString& uri);
- void parserAppendRule(PassRefPtr<StyleRuleBase>);
+ void parserAppendRule(PassRefPtrWillBeRawPtr<StyleRuleBase>);
void parserSetEncodingFromCharsetRule(const String& encoding);
void parserSetUsesRemUnits(bool b) { m_usesRemUnits = b; }
@@ -104,14 +106,14 @@ public:
bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); }
String encodingFromCharsetRule() const { return m_encodingFromCharsetRule; }
// Rules other than @charset and @import.
- const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
- const Vector<RefPtr<StyleRuleImport> >& importRules() const { return m_importRules; }
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& childRules() const { return m_childRules; }
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> >& importRules() const { return m_importRules; }
void notifyLoadedSheet(const CSSStyleSheetResource*);
StyleSheetContents* parentStyleSheet() const;
StyleRuleImport* ownerRule() const { return m_ownerRule; }
- void clearOwnerRule() { m_ownerRule = 0; }
+ void clearOwnerRule() { m_ownerRule = nullptr; }
// Note that href is the URL that started the redirect chain that led to
// this style sheet. This property probably isn't useful for much except
@@ -126,47 +128,60 @@ public:
unsigned estimatedSizeInBytes() const;
- bool wrapperInsertRule(PassRefPtr<StyleRuleBase>, unsigned index);
+ bool wrapperInsertRule(PassRefPtrWillBeRawPtr<StyleRuleBase>, unsigned index);
void wrapperDeleteRule(unsigned index);
- PassRefPtr<StyleSheetContents> copy() const { return adoptRef(new StyleSheetContents(*this)); }
+ PassRefPtrWillBeRawPtr<StyleSheetContents> copy() const
+ {
+ return adoptRefWillBeNoop(new StyleSheetContents(*this));
+ }
void registerClient(CSSStyleSheet*);
void unregisterClient(CSSStyleSheet*);
- bool hasOneClient() { return m_clients.size() == 1; }
+ size_t clientSize() const { return m_loadingClients.size() + m_completedClients.size(); }
+ bool hasOneClient() { return clientSize() == 1; }
+ void clientLoadCompleted(CSSStyleSheet*);
+ void clientLoadStarted(CSSStyleSheet*);
bool isMutable() const { return m_isMutable; }
void setMutable() { m_isMutable = true; }
+ void removeSheetFromCache(Document*);
+
bool isInMemoryCache() const { return m_isInMemoryCache; }
void addedToMemoryCache();
void removedFromMemoryCache();
void setHasMediaQueries();
- bool hasMediaQueries() { return m_hasMediaQueries; }
+ bool hasMediaQueries() const { return m_hasMediaQueries; }
+
+ bool didLoadErrorOccur() const { return m_didLoadErrorOccur; }
void shrinkToFit();
RuleSet& ruleSet() { ASSERT(m_ruleSet); return *m_ruleSet.get(); }
RuleSet& ensureRuleSet(const MediaQueryEvaluator&, AddRuleFlags);
void clearRuleSet();
+ void trace(Visitor*);
+
private:
StyleSheetContents(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext&);
StyleSheetContents(const StyleSheetContents&);
+ void notifyRemoveFontFaceRule(const StyleRuleFontFace*);
+ Document* clientSingleOwnerDocument() const;
void clearCharsetRule();
- StyleRuleImport* m_ownerRule;
+ RawPtrWillBeMember<StyleRuleImport> m_ownerRule;
String m_originalURL;
String m_encodingFromCharsetRule;
- Vector<RefPtr<StyleRuleImport> > m_importRules;
- Vector<RefPtr<StyleRuleBase> > m_childRules;
+ WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> > m_importRules;
+ WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_childRules;
typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap;
PrefixNamespaceURIMap m_namespaces;
- bool m_loadCompleted : 1;
bool m_hasSyntacticallyValidCSSHeader : 1;
bool m_didLoadErrorOccur : 1;
bool m_usesRemUnits : 1;
@@ -174,11 +189,15 @@ private:
bool m_isInMemoryCache : 1;
bool m_hasFontFaceRule : 1;
bool m_hasMediaQueries : 1;
+ bool m_hasSingleOwnerDocument : 1;
CSSParserContext m_parserContext;
- Vector<CSSStyleSheet*> m_clients;
- OwnPtr<RuleSet> m_ruleSet;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> > m_loadingClients;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> > m_completedClients;
+ typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator ClientsIterator;
+
+ OwnPtrWillBeMember<RuleSet> m_ruleSet;
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleSheetList.cpp b/chromium/third_party/WebKit/Source/core/css/StyleSheetList.cpp
index 10f5905ba4e..80714e52a8c 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleSheetList.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/StyleSheetList.cpp
@@ -21,7 +21,7 @@
#include "config.h"
#include "core/css/StyleSheetList.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/StyleEngine.h"
#include "core/html/HTMLStyleElement.h"
@@ -40,18 +40,22 @@ StyleSheetList::~StyleSheetList()
{
}
-inline const Vector<RefPtr<StyleSheet> >& StyleSheetList::styleSheets()
+inline const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& StyleSheetList::styleSheets()
{
+#if !ENABLE(OILPAN)
if (!m_treeScope)
return m_detachedStyleSheets;
+#endif
return document()->styleEngine()->styleSheetsForStyleSheetList(*m_treeScope);
}
+#if !ENABLE(OILPAN)
void StyleSheetList::detachFromDocument()
{
m_detachedStyleSheets = document()->styleEngine()->styleSheetsForStyleSheetList(*m_treeScope);
- m_treeScope = 0;
+ m_treeScope = nullptr;
}
+#endif
unsigned StyleSheetList::length()
{
@@ -60,14 +64,16 @@ unsigned StyleSheetList::length()
StyleSheet* StyleSheetList::item(unsigned index)
{
- const Vector<RefPtr<StyleSheet> >& sheets = styleSheets();
+ const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheets = styleSheets();
return index < sheets.size() ? sheets[index].get() : 0;
}
HTMLStyleElement* StyleSheetList::getNamedItem(const AtomicString& name) const
{
+#if !ENABLE(OILPAN)
if (!m_treeScope)
return 0;
+#endif
// IE also supports retrieving a stylesheet by name, using the name/id of the <style> tag
// (this is consistent with all the other collections)
@@ -76,9 +82,7 @@ HTMLStyleElement* StyleSheetList::getNamedItem(const AtomicString& name) const
// But unicity of stylesheet ids is good practice anyway ;)
// FIXME: We should figure out if we should change this or fix the spec.
Element* element = m_treeScope->getElementById(name);
- if (element && element->hasTagName(styleTag))
- return toHTMLStyleElement(element);
- return 0;
+ return isHTMLStyleElement(element) ? toHTMLStyleElement(element) : 0;
}
CSSStyleSheet* StyleSheetList::anonymousNamedGetter(const AtomicString& name)
@@ -89,4 +93,9 @@ CSSStyleSheet* StyleSheetList::anonymousNamedGetter(const AtomicString& name)
return item->sheet();
}
+void StyleSheetList::trace(Visitor* visitor)
+{
+ visitor->trace(m_treeScope);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleSheetList.h b/chromium/third_party/WebKit/Source/core/css/StyleSheetList.h
index c9c15404729..f842183b75d 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleSheetList.h
+++ b/chromium/third_party/WebKit/Source/core/css/StyleSheetList.h
@@ -33,9 +33,9 @@ namespace WebCore {
class HTMLStyleElement;
class StyleSheet;
-class StyleSheetList : public RefCounted<StyleSheetList> {
+class StyleSheetList : public RefCountedWillBeGarbageCollectedFinalized<StyleSheetList> {
public:
- static PassRefPtr<StyleSheetList> create(TreeScope* treeScope) { return adoptRef(new StyleSheetList(treeScope)); }
+ static PassRefPtrWillBeRawPtr<StyleSheetList> create(TreeScope* treeScope) { return adoptRefWillBeNoop(new StyleSheetList(treeScope)); }
~StyleSheetList();
unsigned length();
@@ -43,17 +43,24 @@ public:
HTMLStyleElement* getNamedItem(const AtomicString&) const;
- Document* document() { return m_treeScope->documentScope(); }
+ Document* document() { return m_treeScope ? &m_treeScope->document() : 0; }
+#if !ENABLE(OILPAN)
void detachFromDocument();
+#endif
+
CSSStyleSheet* anonymousNamedGetter(const AtomicString&);
+ void trace(Visitor*);
+
private:
StyleSheetList(TreeScope*);
- const Vector<RefPtr<StyleSheet> >& styleSheets();
+ const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheets();
- TreeScope* m_treeScope;
+ RawPtrWillBeMember<TreeScope> m_treeScope;
+#if !ENABLE(OILPAN)
Vector<RefPtr<StyleSheet> > m_detachedStyleSheets;
+#endif
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/StyleSheetList.idl b/chromium/third_party/WebKit/Source/core/css/StyleSheetList.idl
index 7341728216d..3da2d91e544 100644
--- a/chromium/third_party/WebKit/Source/core/css/StyleSheetList.idl
+++ b/chromium/third_party/WebKit/Source/core/css/StyleSheetList.idl
@@ -20,10 +20,10 @@
// Introduced in DOM Level 2:
[
- GenerateVisitDOMWrapper=document,
+ SetWrapperReferenceFrom=document,
+ WillBeGarbageCollected
] interface StyleSheetList {
- readonly attribute unsigned long length;
- getter StyleSheet item(unsigned long index);
- [ImplementedAs=anonymousNamedGetter, NotEnumerable] getter CSSStyleSheet (DOMString name);
+ readonly attribute unsigned long length;
+ getter StyleSheet item(unsigned long index);
+ [NotEnumerable] getter CSSStyleSheet (DOMString name);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp b/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp
index 30a5604c412..4d3b123d3bc 100644
--- a/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.cpp
@@ -29,20 +29,68 @@
#include "config.h"
#include "core/css/TreeBoundaryCrossingRules.h"
+#include "core/css/ElementRuleCollector.h"
#include "core/css/RuleFeature.h"
#include "core/dom/StyleEngine.h"
+#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
-void TreeBoundaryCrossingRules::addRule(StyleRule* rule, size_t selectorIndex, ContainerNode* scopingNode, AddRuleFlags addRuleFlags)
+static void addRules(RuleSet* ruleSet, const WillBeHeapVector<MinimalRuleData>& rules)
{
- if (m_treeBoundaryCrossingRuleSetMap.contains(scopingNode)) {
- m_treeBoundaryCrossingRuleSetMap.get(scopingNode)->addRule(rule, selectorIndex, addRuleFlags);
- } else {
- OwnPtr<RuleSet> ruleSetForScope = RuleSet::create();
- ruleSetForScope->addRule(rule, selectorIndex, addRuleFlags);
- m_treeBoundaryCrossingRuleSetMap.add(scopingNode, ruleSetForScope.release());
- m_scopingNodes.add(scopingNode);
+ for (unsigned i = 0; i < rules.size(); ++i) {
+ const MinimalRuleData& info = rules[i];
+ ruleSet->addRule(info.m_rule, info.m_selectorIndex, info.m_flags);
+ }
+}
+
+void TreeBoundaryCrossingRules::addTreeBoundaryCrossingRules(const RuleSet& authorRules, ContainerNode& scopingNode, CSSStyleSheet* parentStyleSheet)
+{
+ if (authorRules.treeBoundaryCrossingRules().isEmpty() && (scopingNode.isDocumentNode() || authorRules.shadowDistributedRules().isEmpty()))
+ return;
+ OwnPtrWillBeRawPtr<RuleSet> ruleSetForScope = RuleSet::create();
+ addRules(ruleSetForScope.get(), authorRules.treeBoundaryCrossingRules());
+ if (!scopingNode.isDocumentNode())
+ addRules(ruleSetForScope.get(), authorRules.shadowDistributedRules());
+
+ if (!m_treeBoundaryCrossingRuleSetMap.contains(&scopingNode)) {
+ m_treeBoundaryCrossingRuleSetMap.add(&scopingNode, adoptPtrWillBeNoop(new CSSStyleSheetRuleSubSet()));
+ m_scopingNodes.add(&scopingNode);
+ }
+ CSSStyleSheetRuleSubSet* ruleSubSet = m_treeBoundaryCrossingRuleSetMap.get(&scopingNode);
+ ruleSubSet->append(std::make_pair(parentStyleSheet, ruleSetForScope.release()));
+}
+
+void TreeBoundaryCrossingRules::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
+{
+ if (m_treeBoundaryCrossingRuleSetMap.isEmpty())
+ return;
+
+ RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
+
+ // When comparing rules declared in outer treescopes, outer's rules win.
+ CascadeOrder outerCascadeOrder = size() + size();
+ // When comparing rules declared in inner treescopes, inner's rules win.
+ CascadeOrder innerCascadeOrder = size();
+
+ for (DocumentOrderedList::iterator it = m_scopingNodes.begin(); it != m_scopingNodes.end(); ++it) {
+ const ContainerNode* scopingNode = toContainerNode(*it);
+ CSSStyleSheetRuleSubSet* ruleSubSet = m_treeBoundaryCrossingRuleSetMap.get(scopingNode);
+ unsigned boundaryBehavior = SelectorChecker::ScopeContainsLastMatchedElement;
+ bool isInnerTreeScope = element->treeScope().isInclusiveAncestorOf(scopingNode->treeScope());
+
+ // If a given scoping node is a shadow root, we should use ScopeIsShadowRoot.
+ if (scopingNode && scopingNode->isShadowRoot())
+ boundaryBehavior |= SelectorChecker::ScopeIsShadowRoot;
+
+ CascadeOrder cascadeOrder = isInnerTreeScope ? innerCascadeOrder : outerCascadeOrder;
+ for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != ruleSubSet->end(); ++it) {
+ CSSStyleSheet* parentStyleSheet = it->first;
+ RuleSet* ruleSet = it->second.get();
+ collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode, parentStyleSheet), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder);
+ }
+ ++innerCascadeOrder;
+ --outerCascadeOrder;
}
}
@@ -52,12 +100,16 @@ void TreeBoundaryCrossingRules::reset(const ContainerNode* scopingNode)
m_scopingNodes.remove(scopingNode);
}
+void TreeBoundaryCrossingRules::collectFeaturesFromRuleSubSet(CSSStyleSheetRuleSubSet* ruleSubSet, RuleFeatureSet& features)
+{
+ for (CSSStyleSheetRuleSubSet::iterator it = ruleSubSet->begin(); it != ruleSubSet->end(); ++it)
+ features.add(it->second->features());
+}
+
void TreeBoundaryCrossingRules::collectFeaturesTo(RuleFeatureSet& features)
{
- for (TreeBoundaryCrossingRuleSetMap::iterator::Values it = m_treeBoundaryCrossingRuleSetMap.values().begin(); it != m_treeBoundaryCrossingRuleSetMap.values().end(); ++it) {
- RuleSet* ruleSet = it->get();
- features.add(ruleSet->features());
- }
+ for (TreeBoundaryCrossingRuleSetMap::iterator::Values it = m_treeBoundaryCrossingRuleSetMap.values().begin(); it != m_treeBoundaryCrossingRuleSetMap.values().end(); ++it)
+ collectFeaturesFromRuleSubSet(it->get(), features);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.h b/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.h
index bba30ed9dcf..64c2970e4c3 100644
--- a/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.h
+++ b/chromium/third_party/WebKit/Source/core/css/TreeBoundaryCrossingRules.h
@@ -32,24 +32,29 @@
namespace WebCore {
+class CSSStyleSheet;
class ContainerNode;
+class ElementRuleCollector;
class RuleFeatureSet;
class TreeBoundaryCrossingRules {
+ DISALLOW_ALLOCATION();
public:
- void addRule(StyleRule*, size_t selectorIndex, ContainerNode* scopingNode, AddRuleFlags);
- void clear() { m_treeBoundaryCrossingRuleSetMap.clear(); }
+ void addTreeBoundaryCrossingRules(const RuleSet&, ContainerNode& scope, CSSStyleSheet*);
+
void reset(const ContainerNode* scopingNode);
- bool isEmpty() const { return m_treeBoundaryCrossingRuleSetMap.isEmpty(); }
void collectFeaturesTo(RuleFeatureSet&);
+ void collectTreeBoundaryCrossingRules(Element*, ElementRuleCollector&, bool includeEmptyRules);
- DocumentOrderedList::iterator begin() { return m_scopingNodes.begin(); }
- DocumentOrderedList::iterator end() { return m_scopingNodes.end(); }
- RuleSet* ruleSetScopedBy(const ContainerNode* scopingNode) { return m_treeBoundaryCrossingRuleSetMap.get(scopingNode); }
+ void trace(Visitor* visitor) { visitor->trace(m_treeBoundaryCrossingRuleSetMap); }
private:
+ size_t size() const { return m_scopingNodes.size(); }
+ typedef WillBeHeapVector<std::pair<CSSStyleSheet*, OwnPtrWillBeMember<RuleSet> > > CSSStyleSheetRuleSubSet;
+ void collectFeaturesFromRuleSubSet(CSSStyleSheetRuleSubSet*, RuleFeatureSet&);
+
DocumentOrderedList m_scopingNodes;
- typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > TreeBoundaryCrossingRuleSetMap;
+ typedef WillBeHeapHashMap<const ContainerNode*, OwnPtrWillBeMember<CSSStyleSheetRuleSubSet> > TreeBoundaryCrossingRuleSetMap;
TreeBoundaryCrossingRuleSetMap m_treeBoundaryCrossingRuleSetMap;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/WebKitCSSFilterValue.idl b/chromium/third_party/WebKit/Source/core/css/WebKitCSSFilterValue.idl
index db2fb1d931d..8c346d2d612 100644
--- a/chromium/third_party/WebKit/Source/core/css/WebKitCSSFilterValue.idl
+++ b/chromium/third_party/WebKit/Source/core/css/WebKitCSSFilterValue.idl
@@ -25,7 +25,7 @@
[
DoNotCheckConstants,
- ImplementedAs=CSSFilterValue
+ ImplementedAs=CSSFilterValue,
] interface WebKitCSSFilterValue : CSSValueList {
// OperationTypes
@@ -41,8 +41,7 @@
const unsigned short CSS_FILTER_CONTRAST = 9;
const unsigned short CSS_FILTER_BLUR = 10;
const unsigned short CSS_FILTER_DROP_SHADOW = 11;
- const unsigned short CSS_FILTER_CUSTOM = 12;
readonly attribute unsigned short operationType;
- [ImplementedAs=item] getter CSSValue(unsigned long index);
+ [ImplementedAs=item] getter CSSValue (unsigned long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/css/WebKitCSSMatrix.idl b/chromium/third_party/WebKit/Source/core/css/WebKitCSSMatrix.idl
index 0016fcfdc80..08ee79783c5 100644
--- a/chromium/third_party/WebKit/Source/core/css/WebKitCSSMatrix.idl
+++ b/chromium/third_party/WebKit/Source/core/css/WebKitCSSMatrix.idl
@@ -25,9 +25,10 @@
// Introduced in DOM Level ?:
[
- Constructor([Default=NullString] optional DOMString cssValue),
+ Constructor(optional DOMString cssValue = null),
ImplementedAs=CSSMatrix,
- RaisesException=Constructor
+ RaisesException=Constructor,
+ WillBeGarbageCollected
] interface WebKitCSSMatrix {
// These attributes are simple aliases for certain elements of the 4x4 matrix
diff --git a/chromium/third_party/WebKit/Source/core/css/WebKitCSSMixFunctionValue.idl b/chromium/third_party/WebKit/Source/core/css/WebKitCSSMixFunctionValue.idl
deleted file mode 100644
index 57f3125d6df..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/WebKitCSSMixFunctionValue.idl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
- ImplementedAs=CSSMixFunctionValue
-] interface WebKitCSSMixFunctionValue : CSSValueList {
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/css/WebKitCSSRegionRule.idl b/chromium/third_party/WebKit/Source/core/css/WebKitCSSRegionRule.idl
deleted file mode 100644
index 68113448048..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/WebKitCSSRegionRule.idl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
- RuntimeEnabled=CSSRegions,
- ImplementedAs=CSSRegionRule
-] interface WebKitCSSRegionRule : CSSRule {
- readonly attribute CSSRuleList cssRules;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/css/WebKitCSSTransformValue.idl b/chromium/third_party/WebKit/Source/core/css/WebKitCSSTransformValue.idl
index 836bcc6dc2d..a17e482d4c6 100644
--- a/chromium/third_party/WebKit/Source/core/css/WebKitCSSTransformValue.idl
+++ b/chromium/third_party/WebKit/Source/core/css/WebKitCSSTransformValue.idl
@@ -28,7 +28,7 @@
[
DoNotCheckConstants,
- ImplementedAs=CSSTransformValue
+ ImplementedAs=CSSTransformValue,
] interface WebKitCSSTransformValue : CSSValueList {
// OperationTypes
@@ -56,6 +56,6 @@
const unsigned short CSS_MATRIX3D = 21;
readonly attribute unsigned short operationType;
- [ImplementedAs=item] getter CSSValue(unsigned long index);
+ [ImplementedAs=item] getter CSSValue (unsigned long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/css/fullscreen.css b/chromium/third_party/WebKit/Source/core/css/fullscreen.css
index 7ecffc6ffa2..337265b9e42 100644
--- a/chromium/third_party/WebKit/Source/core/css/fullscreen.css
+++ b/chromium/third_party/WebKit/Source/core/css/fullscreen.css
@@ -31,6 +31,7 @@ video:-webkit-full-screen, audio:-webkit-full-screen {
width: 100% !important;
flex: 1 !important;
display: block !important;
+ -webkit-transform: none !important;
}
img:-webkit-full-screen {
diff --git a/chromium/third_party/WebKit/Source/core/css/html.css b/chromium/third_party/WebKit/Source/core/css/html.css
index fdacec72bdf..52aa586e5c8 100644
--- a/chromium/third_party/WebKit/Source/core/css/html.css
+++ b/chromium/third_party/WebKit/Source/core/css/html.css
@@ -59,10 +59,6 @@ body {
margin: 8px
}
-body:-webkit-seamless-document {
- margin: 0px
-}
-
body:-webkit-full-page-media {
background-color: rgb(0, 0, 0)
}
@@ -394,11 +390,11 @@ button {
}
/* Form controls don't go vertical. */
-input, textarea, keygen, select, button, isindex, meter, progress {
+input, textarea, keygen, select, button, meter, progress {
-webkit-writing-mode: horizontal-tb !important;
}
-input, textarea, keygen, select, button, isindex {
+input, textarea, keygen, select, button {
margin: 0__qem;
font: -webkit-small-control;
color: initial;
@@ -416,7 +412,7 @@ input[type="hidden"] {
display: none
}
-input, input[type="password"], input[type="search"], isindex {
+input, input[type="password"], input[type="search"] {
-webkit-appearance: textfield;
padding: 1px;
background-color: white;
@@ -577,8 +573,8 @@ input[type="datetime-local"]::-webkit-inner-spin-button,
input[type="month"]::-webkit-inner-spin-button,
input[type="time"]::-webkit-inner-spin-button,
input[type="week"]::-webkit-inner-spin-button {
- display: inline-block;
- position: static;
+ /* FIXME: Remove height. */
+ height: 1.5em;
-webkit-margin-start: 2px;
}
@@ -589,7 +585,9 @@ input[type="month"],
input[type="time"],
input[type="week"] {
align-items: center;
- -webkit-appearance: menulist-button;
+ -webkit-appearance: menulist;
+ background-color: ButtonFace;
+ border: 1px solid #a9a9a9;
display: -webkit-inline-flex;
overflow: hidden;
width: 10em;
@@ -603,15 +601,10 @@ input::-webkit-date-and-time-value {
input::-webkit-inner-spin-button {
-webkit-appearance: inner-spin-button;
- display: block;
- position: relative;
+ display: inline-block;
cursor: default;
- /* This height property is ignored for input type "number" and others which
- * use RenderTextControlSingleLine as renderer which sets height of spin
- * button in layout(). */
- height: 1.5em;
- vertical-align: top;
flex: none;
+ align-self: stretch;
-webkit-user-select: none;
-webkit-user-modify: read-only !important;
opacity: 0;
@@ -623,18 +616,6 @@ input:enabled:read-write:-webkit-any(:focus,:hover)::-webkit-inner-spin-button {
pointer-events: auto;
}
-#if defined(ENABLE_INPUT_SPEECH) && ENABLE_INPUT_SPEECH
-input::-webkit-input-speech-button {
- -webkit-appearance: -webkit-input-speech-button;
- display: block;
- vertical-align: top;
- flex: none;
- -webkit-user-modify: read-only !important;
- -webkit-align-self: flex-start;
- margin: auto 0;
-}
-#endif
-
keygen, select {
border-radius: 5px;
}
@@ -664,7 +645,7 @@ textarea {
pointer-events: none !important;
}
-input::-webkit-input-placeholder, isindex::-webkit-input-placeholder {
+input::-webkit-input-placeholder {
white-space: pre;
word-wrap: normal;
overflow: hidden;
@@ -688,7 +669,7 @@ input[type="file"] {
text-align: start !important;
}
-input:-webkit-autofill, textarea:-webkit-autofill {
+input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {
background-color: #FAFFBD !important;
background-image:none !important;
color: #000000 !important;
@@ -773,6 +754,10 @@ input[type="button"]:active:disabled, input[type="submit"]:active:disabled, inpu
border-style: outset
}
+datalist {
+ display: none
+}
+
area, param {
display: none
}
@@ -791,6 +776,10 @@ input[type="color"] {
-webkit-appearance: square-button;
width: 44px;
height: 23px;
+ background-color: ButtonFace;
+ /* Same as native_theme_base. */
+ border: 1px #a9a9a9 solid;
+ padding: 1px 2px;
}
input[type="color"]::-webkit-color-swatch-wrapper {
@@ -809,6 +798,21 @@ input[type="color"]::-webkit-color-swatch {
-webkit-user-modify: read-only !important;
}
+input[type="color"][list] {
+ -webkit-appearance: menulist;
+ width: 88px;
+ height: 23px
+}
+
+input[type="color"][list]::-webkit-color-swatch-wrapper {
+ padding-left: 8px;
+ padding-right: 24px;
+}
+
+input[type="color"][list]::-webkit-color-swatch {
+ border-color: #000000;
+}
+
input::-webkit-calendar-picker-indicator {
display: inline-block;
width: 0.66em;
@@ -912,7 +916,7 @@ meter::-webkit-meter-inner-element {
}
meter::-webkit-meter-bar {
- background: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#ddd), color-stop(0.20, #eee), color-stop(0.45, #ccc), color-stop(0.55, #ccc));
+ background: linear-gradient(to bottom, #ddd, #eee 20%, #ccc 45%, #ccc 55%, #ddd);
height: 100%;
width: 100%;
-webkit-user-modify: read-only !important;
@@ -920,21 +924,21 @@ meter::-webkit-meter-bar {
}
meter::-webkit-meter-optimum-value {
- background: -webkit-gradient(linear, left top, left bottom, from(#ad7), to(#ad7), color-stop(0.20, #cea), color-stop(0.45, #7a3), color-stop(0.55, #7a3));
+ background: linear-gradient(to bottom, #ad7, #cea 20%, #7a3 45%, #7a3 55%, #ad7);
height: 100%;
-webkit-user-modify: read-only !important;
box-sizing: border-box;
}
meter::-webkit-meter-suboptimum-value {
- background: -webkit-gradient(linear, left top, left bottom, from(#fe7), to(#fe7), color-stop(0.20, #ffc), color-stop(0.45, #db3), color-stop(0.55, #db3));
+ background: linear-gradient(to bottom, #fe7, #ffc 20%, #db3 45%, #db3 55%, #fe7);
height: 100%;
-webkit-user-modify: read-only !important;
box-sizing: border-box;
}
meter::-webkit-meter-even-less-good-value {
- background: -webkit-gradient(linear, left top, left bottom, from(#f77), to(#f77), color-stop(0.20, #fcc), color-stop(0.45, #d44), color-stop(0.55, #d44));
+ background: linear-gradient(to bottom, #f77, #fcc 20%, #d44 45%, #d44 55%, #f77);
height: 100%;
-webkit-user-modify: read-only !important;
box-sizing: border-box;
@@ -1046,7 +1050,7 @@ applet:focus, embed:focus, iframe:focus, object:focus {
outline: none
}
-input:focus, textarea:focus, isindex:focus, keygen:focus, select:focus {
+input:focus, textarea:focus, keygen:focus, select:focus {
outline-offset: -2px
}
@@ -1108,14 +1112,10 @@ frameset {
border-color: inherit
}
-iframe:not([seamless]) {
+iframe {
border: 2px inset
}
-iframe[seamless] {
- display: block
-}
-
details {
display: block
}
@@ -1128,7 +1128,7 @@ summary::-webkit-details-marker {
display: inline-block;
width: 0.66em;
height: 0.66em;
- margin-right: 0.4em;
+ -webkit-margin-end: 0.4em;
}
template {
diff --git a/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSet.cpp b/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSet.cpp
new file mode 100644
index 00000000000..6f1be3b13bf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSet.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/css/invalidation/DescendantInvalidationSet.h"
+
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Element.h"
+
+namespace WebCore {
+
+DescendantInvalidationSet::DescendantInvalidationSet()
+ : m_allDescendantsMightBeInvalid(false)
+ , m_customPseudoInvalid(false)
+ , m_treeBoundaryCrossing(false)
+{
+}
+
+bool DescendantInvalidationSet::invalidatesElement(Element& element) const
+{
+ if (m_allDescendantsMightBeInvalid)
+ return true;
+
+ if (m_tagNames && m_tagNames->contains(element.tagQName().localName()))
+ return true;
+
+ if (element.hasID() && m_ids && m_ids->contains(element.idForStyleResolution()))
+ return true;
+
+ if (element.hasClass() && m_classes) {
+ const SpaceSplitString& classNames = element.classNames();
+ for (WillBeHeapHashSet<AtomicString>::const_iterator it = m_classes->begin(); it != m_classes->end(); ++it) {
+ if (classNames.contains(*it))
+ return true;
+ }
+ }
+
+ if (element.hasAttributes() && m_attributes) {
+ for (WillBeHeapHashSet<AtomicString>::const_iterator it = m_attributes->begin(); it != m_attributes->end(); ++it) {
+ if (element.hasAttribute(*it))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void DescendantInvalidationSet::combine(const DescendantInvalidationSet& other)
+{
+ // No longer bother combining data structures, since the whole subtree is deemed invalid.
+ if (wholeSubtreeInvalid())
+ return;
+
+ if (other.wholeSubtreeInvalid()) {
+ setWholeSubtreeInvalid();
+ return;
+ }
+
+ if (other.customPseudoInvalid())
+ setCustomPseudoInvalid();
+
+ if (other.treeBoundaryCrossing())
+ setTreeBoundaryCrossing();
+
+ if (other.m_classes) {
+ WillBeHeapHashSet<AtomicString>::const_iterator end = other.m_classes->end();
+ for (WillBeHeapHashSet<AtomicString>::const_iterator it = other.m_classes->begin(); it != end; ++it)
+ addClass(*it);
+ }
+
+ if (other.m_ids) {
+ WillBeHeapHashSet<AtomicString>::const_iterator end = other.m_ids->end();
+ for (WillBeHeapHashSet<AtomicString>::const_iterator it = other.m_ids->begin(); it != end; ++it)
+ addId(*it);
+ }
+
+ if (other.m_tagNames) {
+ WillBeHeapHashSet<AtomicString>::const_iterator end = other.m_tagNames->end();
+ for (WillBeHeapHashSet<AtomicString>::const_iterator it = other.m_tagNames->begin(); it != end; ++it)
+ addTagName(*it);
+ }
+
+ if (other.m_attributes) {
+ WillBeHeapHashSet<AtomicString>::const_iterator end = other.m_attributes->end();
+ for (WillBeHeapHashSet<AtomicString>::const_iterator it = other.m_attributes->begin(); it != end; ++it)
+ addAttribute(*it);
+ }
+}
+
+WillBeHeapHashSet<AtomicString>& DescendantInvalidationSet::ensureClassSet()
+{
+ if (!m_classes)
+ m_classes = adoptPtrWillBeNoop(new WillBeHeapHashSet<AtomicString>);
+ return *m_classes;
+}
+
+WillBeHeapHashSet<AtomicString>& DescendantInvalidationSet::ensureIdSet()
+{
+ if (!m_ids)
+ m_ids = adoptPtrWillBeNoop(new WillBeHeapHashSet<AtomicString>);
+ return *m_ids;
+}
+
+WillBeHeapHashSet<AtomicString>& DescendantInvalidationSet::ensureTagNameSet()
+{
+ if (!m_tagNames)
+ m_tagNames = adoptPtrWillBeNoop(new WillBeHeapHashSet<AtomicString>);
+ return *m_tagNames;
+}
+
+WillBeHeapHashSet<AtomicString>& DescendantInvalidationSet::ensureAttributeSet()
+{
+ if (!m_attributes)
+ m_attributes = adoptPtrWillBeNoop(new WillBeHeapHashSet<AtomicString>);
+ return *m_attributes;
+}
+
+void DescendantInvalidationSet::addClass(const AtomicString& className)
+{
+ if (wholeSubtreeInvalid())
+ return;
+ ensureClassSet().add(className);
+}
+
+void DescendantInvalidationSet::addId(const AtomicString& id)
+{
+ if (wholeSubtreeInvalid())
+ return;
+ ensureIdSet().add(id);
+}
+
+void DescendantInvalidationSet::addTagName(const AtomicString& tagName)
+{
+ if (wholeSubtreeInvalid())
+ return;
+ ensureTagNameSet().add(tagName);
+}
+
+void DescendantInvalidationSet::addAttribute(const AtomicString& attribute)
+{
+ if (wholeSubtreeInvalid())
+ return;
+ ensureAttributeSet().add(attribute);
+}
+
+void DescendantInvalidationSet::setWholeSubtreeInvalid()
+{
+ if (m_allDescendantsMightBeInvalid)
+ return;
+
+ m_allDescendantsMightBeInvalid = true;
+ m_treeBoundaryCrossing = false;
+ m_classes = nullptr;
+ m_ids = nullptr;
+ m_tagNames = nullptr;
+ m_attributes = nullptr;
+}
+
+void DescendantInvalidationSet::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_classes);
+ visitor->trace(m_ids);
+ visitor->trace(m_tagNames);
+ visitor->trace(m_attributes);
+#endif
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSet.h b/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSet.h
new file mode 100644
index 00000000000..b86c93b03c6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSet.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DescendantInvalidationSet_h
+#define DescendantInvalidationSet_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/HashSet.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/AtomicStringHash.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+class Element;
+
+// Tracks data to determine which elements of a DOM subtree need to have style
+// recalculated.
+class DescendantInvalidationSet FINAL : public RefCountedWillBeGarbageCollected<DescendantInvalidationSet> {
+public:
+ static PassRefPtrWillBeRawPtr<DescendantInvalidationSet> create()
+ {
+ return adoptRefWillBeNoop(new DescendantInvalidationSet);
+ }
+
+ bool invalidatesElement(Element&) const;
+
+ void combine(const DescendantInvalidationSet& other);
+
+ void addClass(const AtomicString& className);
+ void addId(const AtomicString& id);
+ void addTagName(const AtomicString& tagName);
+ void addAttribute(const AtomicString& attributeLocalName);
+
+ void setWholeSubtreeInvalid();
+ bool wholeSubtreeInvalid() const { return m_allDescendantsMightBeInvalid; }
+
+ void setTreeBoundaryCrossing() { m_treeBoundaryCrossing = true; }
+ bool treeBoundaryCrossing() const { return m_treeBoundaryCrossing; }
+
+ void setCustomPseudoInvalid() { m_customPseudoInvalid = true; }
+ bool customPseudoInvalid() const { return m_customPseudoInvalid; }
+
+ bool isEmpty() const { return !m_classes && !m_ids && !m_tagNames && !m_attributes; }
+
+ void trace(Visitor*);
+
+private:
+ DescendantInvalidationSet();
+
+ WillBeHeapHashSet<AtomicString>& ensureClassSet();
+ WillBeHeapHashSet<AtomicString>& ensureIdSet();
+ WillBeHeapHashSet<AtomicString>& ensureTagNameSet();
+ WillBeHeapHashSet<AtomicString>& ensureAttributeSet();
+
+ // FIXME: optimize this if it becomes a memory issue.
+ OwnPtrWillBeMember<WillBeHeapHashSet<AtomicString> > m_classes;
+ OwnPtrWillBeMember<WillBeHeapHashSet<AtomicString> > m_ids;
+ OwnPtrWillBeMember<WillBeHeapHashSet<AtomicString> > m_tagNames;
+ OwnPtrWillBeMember<WillBeHeapHashSet<AtomicString> > m_attributes;
+
+ // If true, all descendants might be invalidated, so a full subtree recalc is required.
+ unsigned m_allDescendantsMightBeInvalid : 1;
+
+ // If true, all descendants which are custom pseudo elements must be invalidated.
+ unsigned m_customPseudoInvalid : 1;
+
+ // If true, the invalidation must traverse into ShadowRoots with this set.
+ unsigned m_treeBoundaryCrossing : 1;
+};
+
+} // namespace WebCore
+
+#endif // DescendantInvalidationSet_h
diff --git a/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSetTest.cpp b/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSetTest.cpp
new file mode 100644
index 00000000000..3732ebf405e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/invalidation/DescendantInvalidationSetTest.cpp
@@ -0,0 +1,64 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/invalidation/DescendantInvalidationSet.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+// Once we setWholeSubtreeInvalid, we should not keep the HashSets.
+TEST(DescendantInvalidationSetTest, SubtreeInvalid_AddBefore)
+{
+ RefPtrWillBeRawPtr<DescendantInvalidationSet> set = DescendantInvalidationSet::create();
+ set->addClass("a");
+ set->setWholeSubtreeInvalid();
+
+ ASSERT_TRUE(set->isEmpty());
+}
+
+// Don't (re)create HashSets if we've already setWholeSubtreeInvalid.
+TEST(DescendantInvalidationSetTest, SubtreeInvalid_AddAfter)
+{
+ RefPtrWillBeRawPtr<DescendantInvalidationSet> set = DescendantInvalidationSet::create();
+ set->setWholeSubtreeInvalid();
+ set->addTagName("a");
+
+ ASSERT_TRUE(set->isEmpty());
+}
+
+// No need to keep the HashSets when combining with a wholeSubtreeInvalid set.
+TEST(DescendantInvalidationSetTest, SubtreeInvalid_Combine_1)
+{
+ RefPtrWillBeRawPtr<DescendantInvalidationSet> set1 = DescendantInvalidationSet::create();
+ RefPtrWillBeRawPtr<DescendantInvalidationSet> set2 = DescendantInvalidationSet::create();
+
+ set1->addId("a");
+ set2->setWholeSubtreeInvalid();
+
+ set1->combine(*set2);
+
+ ASSERT_TRUE(set1->wholeSubtreeInvalid());
+ ASSERT_TRUE(set1->isEmpty());
+}
+
+// No need to add HashSets from combining set when we already have wholeSubtreeInvalid.
+TEST(DescendantInvalidationSetTest, SubtreeInvalid_Combine_2)
+{
+ RefPtrWillBeRawPtr<DescendantInvalidationSet> set1 = DescendantInvalidationSet::create();
+ RefPtrWillBeRawPtr<DescendantInvalidationSet> set2 = DescendantInvalidationSet::create();
+
+ set1->setWholeSubtreeInvalid();
+ set2->addAttribute("a");
+
+ set1->combine(*set2);
+
+ ASSERT_TRUE(set1->wholeSubtreeInvalid());
+ ASSERT_TRUE(set1->isEmpty());
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp b/chromium/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
new file mode 100644
index 00000000000..3874c2b93e6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
@@ -0,0 +1,167 @@
+
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/css/invalidation/StyleInvalidator.h"
+
+#include "core/css/invalidation/DescendantInvalidationSet.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/rendering/RenderObject.h"
+
+namespace WebCore {
+
+void StyleInvalidator::invalidate(Document& document)
+{
+ if (Element* documentElement = document.documentElement())
+ invalidate(*documentElement);
+ document.clearChildNeedsStyleInvalidation();
+ document.clearNeedsStyleInvalidation();
+ clearPendingInvalidations();
+}
+
+void StyleInvalidator::scheduleInvalidation(PassRefPtrWillBeRawPtr<DescendantInvalidationSet> invalidationSet, Element& element)
+{
+ ASSERT(element.inActiveDocument());
+ ASSERT(element.styleChangeType() < SubtreeStyleChange);
+ InvalidationList& list = ensurePendingInvalidationList(element);
+ // If we're already going to invalidate the whole subtree we don't need to store any new sets.
+ if (!list.isEmpty() && list.last()->wholeSubtreeInvalid())
+ return;
+ // If this set would invalidate the whole subtree we can discard all existing sets.
+ if (invalidationSet->wholeSubtreeInvalid())
+ list.clear();
+ list.append(invalidationSet);
+ element.setNeedsStyleInvalidation();
+}
+
+StyleInvalidator::InvalidationList& StyleInvalidator::ensurePendingInvalidationList(Element& element)
+{
+ PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(&element, nullptr);
+ if (addResult.isNewEntry)
+ addResult.storedValue->value = adoptPtrWillBeNoop(new InvalidationList);
+ return *addResult.storedValue->value;
+}
+
+void StyleInvalidator::clearInvalidation(Node& node)
+{
+ if (node.isElementNode() && node.needsStyleInvalidation())
+ m_pendingInvalidationMap.remove(toElement(&node));
+}
+
+void StyleInvalidator::clearPendingInvalidations()
+{
+ m_pendingInvalidationMap.clear();
+}
+
+StyleInvalidator::StyleInvalidator()
+{
+}
+
+StyleInvalidator::~StyleInvalidator()
+{
+}
+
+void StyleInvalidator::RecursionData::pushInvalidationSet(const DescendantInvalidationSet& invalidationSet)
+{
+ ASSERT(!m_wholeSubtreeInvalid);
+ if (invalidationSet.treeBoundaryCrossing())
+ m_treeBoundaryCrossing = true;
+ if (invalidationSet.wholeSubtreeInvalid()) {
+ m_wholeSubtreeInvalid = true;
+ return;
+ }
+ m_invalidationSets.append(&invalidationSet);
+ m_invalidateCustomPseudo = invalidationSet.customPseudoInvalid();
+}
+
+bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSets(Element& element)
+{
+ ASSERT(!m_wholeSubtreeInvalid);
+
+ if (m_invalidateCustomPseudo && element.shadowPseudoId() != nullAtom)
+ return true;
+
+ for (InvalidationSets::iterator it = m_invalidationSets.begin(); it != m_invalidationSets.end(); ++it) {
+ if ((*it)->invalidatesElement(element))
+ return true;
+ }
+
+ return false;
+}
+
+bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element& element)
+{
+ if (element.styleChangeType() >= SubtreeStyleChange || m_recursionData.wholeSubtreeInvalid()) {
+ m_recursionData.setWholeSubtreeInvalid();
+ return false;
+ }
+ if (element.needsStyleInvalidation()) {
+ if (InvalidationList* invalidationList = m_pendingInvalidationMap.get(&element)) {
+ for (InvalidationList::const_iterator it = invalidationList->begin(); it != invalidationList->end(); ++it)
+ m_recursionData.pushInvalidationSet(**it);
+ // FIXME: It's really only necessary to clone the render style for this element, not full style recalc.
+ return true;
+ }
+ }
+ return m_recursionData.matchesCurrentInvalidationSets(element);
+}
+
+bool StyleInvalidator::invalidateChildren(Element& element)
+{
+ bool someChildrenNeedStyleRecalc = false;
+ for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->olderShadowRoot()) {
+ if (!m_recursionData.treeBoundaryCrossing() && !root->childNeedsStyleInvalidation() && !root->needsStyleInvalidation())
+ continue;
+ for (Element* child = ElementTraversal::firstChild(*root); child; child = ElementTraversal::nextSibling(*child)) {
+ bool childRecalced = invalidate(*child);
+ someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
+ }
+ root->clearChildNeedsStyleInvalidation();
+ root->clearNeedsStyleInvalidation();
+ }
+ for (Element* child = ElementTraversal::firstChild(element); child; child = ElementTraversal::nextSibling(*child)) {
+ bool childRecalced = invalidate(*child);
+ someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
+ }
+ return someChildrenNeedStyleRecalc;
+}
+
+bool StyleInvalidator::invalidate(Element& element)
+{
+ RecursionCheckpoint checkpoint(&m_recursionData);
+
+ bool thisElementNeedsStyleRecalc = checkInvalidationSetsAgainstElement(element);
+
+ bool someChildrenNeedStyleRecalc = false;
+ if (m_recursionData.hasInvalidationSets() || element.childNeedsStyleInvalidation())
+ someChildrenNeedStyleRecalc = invalidateChildren(element);
+
+ if (thisElementNeedsStyleRecalc) {
+ element.setNeedsStyleRecalc(m_recursionData.wholeSubtreeInvalid() ? SubtreeStyleChange : LocalStyleChange);
+ } else if (m_recursionData.hasInvalidationSets() && someChildrenNeedStyleRecalc) {
+ // Clone the RenderStyle in order to preserve correct style sharing, if possible. Otherwise recalc style.
+ if (RenderObject* renderer = element.renderer())
+ renderer->setStyleInternal(RenderStyle::clone(renderer->style()));
+ else
+ element.setNeedsStyleRecalc(LocalStyleChange);
+ }
+
+ element.clearChildNeedsStyleInvalidation();
+ element.clearNeedsStyleInvalidation();
+
+ return thisElementNeedsStyleRecalc;
+}
+
+void StyleInvalidator::trace(Visitor* visitor)
+{
+ visitor->trace(m_pendingInvalidationMap);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h b/chromium/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
new file mode 100644
index 00000000000..275c6c8c8e6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
@@ -0,0 +1,96 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StyleInvalidator_h
+#define StyleInvalidator_h
+
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class DescendantInvalidationSet;
+class Document;
+class Element;
+
+class StyleInvalidator {
+ DISALLOW_ALLOCATION();
+public:
+ StyleInvalidator();
+ ~StyleInvalidator();
+ void invalidate(Document&);
+ void scheduleInvalidation(PassRefPtrWillBeRawPtr<DescendantInvalidationSet>, Element&);
+
+ // Clears all style invalidation state for the passed node.
+ void clearInvalidation(Node&);
+
+ void clearPendingInvalidations();
+
+ void trace(Visitor*);
+
+private:
+ bool invalidate(Element&);
+ bool invalidateChildren(Element&);
+
+ bool checkInvalidationSetsAgainstElement(Element&);
+
+ struct RecursionData {
+ RecursionData()
+ : m_invalidateCustomPseudo(false)
+ , m_wholeSubtreeInvalid(false)
+ , m_treeBoundaryCrossing(false)
+ { }
+
+ void pushInvalidationSet(const DescendantInvalidationSet&);
+ bool matchesCurrentInvalidationSets(Element&);
+ bool hasInvalidationSets() const { return !wholeSubtreeInvalid() && m_invalidationSets.size(); }
+
+ bool wholeSubtreeInvalid() const { return m_wholeSubtreeInvalid; }
+ void setWholeSubtreeInvalid() { m_wholeSubtreeInvalid = true; }
+
+ bool treeBoundaryCrossing() const { return m_treeBoundaryCrossing; }
+
+ typedef Vector<const DescendantInvalidationSet*, 16> InvalidationSets;
+ InvalidationSets m_invalidationSets;
+ bool m_invalidateCustomPseudo;
+ bool m_wholeSubtreeInvalid;
+ bool m_treeBoundaryCrossing;
+ };
+
+ class RecursionCheckpoint {
+ public:
+ RecursionCheckpoint(RecursionData* data)
+ : m_prevInvalidationSetsSize(data->m_invalidationSets.size())
+ , m_prevInvalidateCustomPseudo(data->m_invalidateCustomPseudo)
+ , m_prevWholeSubtreeInvalid(data->m_wholeSubtreeInvalid)
+ , m_treeBoundaryCrossing(data->m_treeBoundaryCrossing)
+ , m_data(data)
+ { }
+ ~RecursionCheckpoint()
+ {
+ m_data->m_invalidationSets.remove(m_prevInvalidationSetsSize, m_data->m_invalidationSets.size() - m_prevInvalidationSetsSize);
+ m_data->m_invalidateCustomPseudo = m_prevInvalidateCustomPseudo;
+ m_data->m_wholeSubtreeInvalid = m_prevWholeSubtreeInvalid;
+ m_data->m_treeBoundaryCrossing = m_treeBoundaryCrossing;
+ }
+
+ private:
+ int m_prevInvalidationSetsSize;
+ bool m_prevInvalidateCustomPseudo;
+ bool m_prevWholeSubtreeInvalid;
+ bool m_treeBoundaryCrossing;
+ RecursionData* m_data;
+ };
+
+ typedef WillBeHeapVector<RefPtrWillBeMember<DescendantInvalidationSet> > InvalidationList;
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<Element>, OwnPtrWillBeMember<InvalidationList> > PendingInvalidationMap;
+
+ InvalidationList& ensurePendingInvalidationList(Element&);
+
+ PendingInvalidationMap m_pendingInvalidationMap;
+ RecursionData m_recursionData;
+};
+
+} // namespace WebCore
+
+#endif // StyleInvalidator_h
diff --git a/chromium/third_party/WebKit/Source/core/css/invalidation/StyleSheetInvalidationAnalysis.cpp b/chromium/third_party/WebKit/Source/core/css/invalidation/StyleSheetInvalidationAnalysis.cpp
new file mode 100644
index 00000000000..bb9854b4762
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/invalidation/StyleSheetInvalidationAnalysis.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/css/invalidation/StyleSheetInvalidationAnalysis.h"
+
+#include "core/css/CSSSelectorList.h"
+#include "core/css/StyleRuleImport.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/dom/ContainerNode.h"
+#include "core/dom/Document.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLStyleElement.h"
+
+namespace WebCore {
+
+StyleSheetInvalidationAnalysis::StyleSheetInvalidationAnalysis(const WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& sheets)
+ : m_dirtiesAllStyle(false)
+{
+ for (unsigned i = 0; i < sheets.size() && !m_dirtiesAllStyle; ++i)
+ analyzeStyleSheet(sheets[i]);
+}
+
+static bool determineSelectorScopes(const CSSSelectorList& selectorList, HashSet<StringImpl*>& idScopes, HashSet<StringImpl*>& classScopes)
+{
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) {
+ const CSSSelector* scopeSelector = 0;
+ // This picks the widest scope, not the narrowest, to minimize the number of found scopes.
+ for (const CSSSelector* current = selector; current; current = current->tagHistory()) {
+ // Prefer ids over classes.
+ if (current->match() == CSSSelector::Id)
+ scopeSelector = current;
+ else if (current->match() == CSSSelector::Class && (!scopeSelector || scopeSelector->match() != CSSSelector::Id))
+ scopeSelector = current;
+ CSSSelector::Relation relation = current->relation();
+ // FIXME: it would be better to use setNeedsStyleRecalc for all shadow hosts matching
+ // scopeSelector. Currently requests full style recalc.
+ if (relation == CSSSelector::ShadowDeep || relation == CSSSelector::ShadowPseudo)
+ return false;
+ if (relation != CSSSelector::Descendant && relation != CSSSelector::Child && relation != CSSSelector::SubSelector)
+ break;
+ }
+ if (!scopeSelector)
+ return false;
+ ASSERT(scopeSelector->match() == CSSSelector::Class || scopeSelector->match() == CSSSelector::Id);
+ if (scopeSelector->match() == CSSSelector::Id)
+ idScopes.add(scopeSelector->value().impl());
+ else
+ classScopes.add(scopeSelector->value().impl());
+ }
+ return true;
+}
+
+static bool hasDistributedRule(StyleSheetContents* styleSheetContents)
+{
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules = styleSheetContents->childRules();
+ for (unsigned i = 0; i < rules.size(); i++) {
+ const StyleRuleBase* rule = rules[i].get();
+ if (!rule->isStyleRule())
+ continue;
+
+ const StyleRule* styleRule = toStyleRule(rule);
+ const CSSSelectorList& selectorList = styleRule->selectorList();
+ for (size_t selectorIndex = 0; selectorIndex != kNotFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex)) {
+ if (selectorList.hasShadowDistributedAt(selectorIndex))
+ return true;
+ }
+ }
+ return false;
+}
+
+static Node* determineScopingNodeForStyleInShadow(HTMLStyleElement* ownerElement, StyleSheetContents* styleSheetContents)
+{
+ ASSERT(ownerElement && ownerElement->isInShadowTree());
+
+ if (hasDistributedRule(styleSheetContents)) {
+ ContainerNode* scope = ownerElement;
+ do {
+ scope = scope->containingShadowRoot()->shadowHost();
+ } while (scope->isInShadowTree());
+ return scope;
+ }
+
+ return ownerElement->containingShadowRoot()->shadowHost();
+}
+
+static bool ruleAdditionMightRequireDocumentStyleRecalc(StyleRuleBase* rule)
+{
+ // This funciton is conservative. We only return false when we know that
+ // the added @rule can't require style recalcs.
+ switch (rule->type()) {
+ case StyleRule::Import: // Whatever we import should do its own analysis, we don't need to invalidate the document here!
+ case StyleRule::Keyframes: // Keyframes never cause style invalidations and are handled during sheet insertion.
+ case StyleRule::Page: // Page rules apply only during printing, we force a full-recalc before printing.
+ return false;
+
+ case StyleRule::Media: // If the media rule doesn't apply, we could avoid recalc.
+ case StyleRule::FontFace: // If the fonts aren't in use, we could avoid recalc.
+ case StyleRule::Supports: // If we evaluated the supports-clause we could avoid recalc.
+ case StyleRule::Viewport: // If the viewport doesn't match, we could avoid recalcing.
+ // FIXME: Unclear if any of the rest need to cause style recalc:
+ case StyleRule::Filter:
+ return true;
+
+ // These should all be impossible to reach:
+ case StyleRule::Unknown:
+ case StyleRule::Charset:
+ case StyleRule::Keyframe:
+ case StyleRule::Style:
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return true;
+}
+
+void StyleSheetInvalidationAnalysis::analyzeStyleSheet(StyleSheetContents* styleSheetContents)
+{
+ ASSERT(!styleSheetContents->isLoading());
+
+ // See if all rules on the sheet are scoped to some specific ids or classes.
+ // Then test if we actually have any of those in the tree at the moment.
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> >& importRules = styleSheetContents->importRules();
+ for (unsigned i = 0; i < importRules.size(); ++i) {
+ if (!importRules[i]->styleSheet())
+ continue;
+ analyzeStyleSheet(importRules[i]->styleSheet());
+ if (m_dirtiesAllStyle)
+ return;
+ }
+ if (styleSheetContents->hasSingleOwnerNode()) {
+ Node* ownerNode = styleSheetContents->singleOwnerNode();
+ if (isHTMLStyleElement(ownerNode) && toHTMLStyleElement(*ownerNode).isInShadowTree()) {
+ m_scopingNodes.append(determineScopingNodeForStyleInShadow(toHTMLStyleElement(ownerNode), styleSheetContents));
+ return;
+ }
+ }
+
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules = styleSheetContents->childRules();
+ for (unsigned i = 0; i < rules.size(); i++) {
+ StyleRuleBase* rule = rules[i].get();
+ if (!rule->isStyleRule()) {
+ if (ruleAdditionMightRequireDocumentStyleRecalc(rule)) {
+ m_dirtiesAllStyle = true;
+ return;
+ }
+ continue;
+ }
+ StyleRule* styleRule = toStyleRule(rule);
+ if (!determineSelectorScopes(styleRule->selectorList(), m_idScopes, m_classScopes)) {
+ m_dirtiesAllStyle = true;
+ return;
+ }
+ }
+}
+
+static bool elementMatchesSelectorScopes(const Element* element, const HashSet<StringImpl*>& idScopes, const HashSet<StringImpl*>& classScopes)
+{
+ if (!idScopes.isEmpty() && element->hasID() && idScopes.contains(element->idForStyleResolution().impl()))
+ return true;
+ if (classScopes.isEmpty() || !element->hasClass())
+ return false;
+ const SpaceSplitString& classNames = element->classNames();
+ for (unsigned i = 0; i < classNames.size(); ++i) {
+ if (classScopes.contains(classNames[i].impl()))
+ return true;
+ }
+ return false;
+}
+
+void StyleSheetInvalidationAnalysis::invalidateStyle(Document& document)
+{
+ ASSERT(!m_dirtiesAllStyle);
+
+ if (!m_scopingNodes.isEmpty()) {
+ for (unsigned i = 0; i < m_scopingNodes.size(); ++i)
+ m_scopingNodes.at(i)->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+
+ if (m_idScopes.isEmpty() && m_classScopes.isEmpty())
+ return;
+ Element* element = ElementTraversal::firstWithin(document);
+ while (element) {
+ if (elementMatchesSelectorScopes(element, m_idScopes, m_classScopes)) {
+ element->setNeedsStyleRecalc(SubtreeStyleChange);
+ // The whole subtree is now invalidated, we can skip to the next sibling.
+ element = ElementTraversal::nextSkippingChildren(*element);
+ continue;
+ }
+ element = ElementTraversal::next(*element);
+ }
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/invalidation/StyleSheetInvalidationAnalysis.h b/chromium/third_party/WebKit/Source/core/css/invalidation/StyleSheetInvalidationAnalysis.h
new file mode 100644
index 00000000000..9b74a3eef53
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/invalidation/StyleSheetInvalidationAnalysis.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StyleSheetInvalidationAnalysis_h
+#define StyleSheetInvalidationAnalysis_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/HashSet.h"
+#include "wtf/Vector.h"
+#include "wtf/text/StringImpl.h"
+
+namespace WebCore {
+
+class Document;
+class Node;
+class StyleSheetContents;
+
+class StyleSheetInvalidationAnalysis {
+public:
+ StyleSheetInvalidationAnalysis(const WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >&);
+
+ bool dirtiesAllStyle() const { return m_dirtiesAllStyle; }
+ void invalidateStyle(Document&);
+
+private:
+
+ void analyzeStyleSheet(StyleSheetContents*);
+
+ bool m_dirtiesAllStyle;
+ HashSet<StringImpl*> m_idScopes;
+ HashSet<StringImpl*> m_classScopes;
+ Vector<Node*, 8> m_scopingNodes;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/make-css-file-arrays.pl b/chromium/third_party/WebKit/Source/core/css/make-css-file-arrays.pl
index 66eb7dfb0e4..d111cb30576 100755
--- a/chromium/third_party/WebKit/Source/core/css/make-css-file-arrays.pl
+++ b/chromium/third_party/WebKit/Source/core/css/make-css-file-arrays.pl
@@ -34,8 +34,10 @@ shift;
my $out = $ARGV[0];
shift;
-open HEADER, ">", $header or die;
-open OUT, ">", $out or die;
+$header =~ s|\\|/|g;
+$out =~ s|\\|/|g;
+open HEADER, ">", $header or die "$!\n";
+open OUT, ">", $out or die "$!\n";
print HEADER "namespace WebCore {\n";
print OUT "namespace WebCore {\n";
diff --git a/chromium/third_party/WebKit/Source/core/css/mathml.css b/chromium/third_party/WebKit/Source/core/css/mathml.css
new file mode 100644
index 00000000000..cef10e3f7b0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/mathml.css
@@ -0,0 +1,49 @@
+/*
+ * The default style sheet used to render MathML.
+ *
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+@namespace "http://www.w3.org/1998/Math/MathML";
+
+/* By default, we only display the MathML formulas without any formatting other than the one specified by the display attribute. */
+math {
+ display: inline;
+}
+
+math[display="block"] {
+ display: block;
+ text-align: center;
+}
+
+/* We hide the PresentationExpression constructions that are children of a <semantics> element.
+ http://www.w3.org/TR/MathML/appendixa.html#parsing_PresentationExpression */
+semantics > mi, semantics > mn, semantics > mo, semantics > mtext, semantics > mspace, semantics > ms, semantics > maligngroup, semantics > malignmark, semantics > mrow, semantics > mfrac, semantics > msqrt, semantics > mroot, semantics > mstyle, semantics > merror, semantics > mpadded, semantics > mphantom, semantics > mfenced, semantics > menclose, semantics > msub, semantics > msup, semantics > msubsup, semantics > munder, semantics > mover, semantics > munderover, semantics > mmultiscripts, semantics > mtable, semantics > mstack, semantics > mlongdiv, semantics > maction {
+ display: none;
+}
+
+/* However, we display all the annotations. */
+annotation, annotation-xml {
+ display: inline-block;
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/mediaControls.css b/chromium/third_party/WebKit/Source/core/css/mediaControls.css
index a2efc1d2bc1..d3b5536e4a4 100644
--- a/chromium/third_party/WebKit/Source/core/css/mediaControls.css
+++ b/chromium/third_party/WebKit/Source/core/css/mediaControls.css
@@ -115,10 +115,40 @@ audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-bu
color: inherit;
}
-audio::-webkit-media-controls-overlay-play-button, video::-webkit-media-controls-overlay-play-button {
+audio::-webkit-media-controls-overlay-enclosure {
display: none;
}
+video::-webkit-media-controls-overlay-enclosure {
+ display: flex;
+ position: relative;
+ flex-direction: column;
+ justify-content: flex-end;
+ align-items: center;
+ flex: 1 1;
+ width: 100%;
+ max-width: 800px;
+ text-indent: 0;
+ box-sizing: border-box;
+ overflow: hidden;
+}
+
+video::-webkit-media-controls-overlay-play-button {
+ -webkit-appearance: media-overlay-play-button;
+ display: flex;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-left: -40px;
+ margin-top: -40px;
+ border: none;
+ box-sizing: border-box;
+ background-color: transparent;
+ width: 80px;
+ height: 80px;
+ padding: 0;
+}
+
audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
-webkit-appearance: media-play-button;
display: flex;
@@ -231,26 +261,6 @@ input[type="range"]::-webkit-media-slider-thumb {
margin-right: -7px;
}
-audio::-webkit-media-controls-seek-back-button, video::-webkit-media-controls-seek-back-button {
- -webkit-appearance: media-seek-back-button;
- display: flex;
- width: 16px;
- height: 16px;
- background-color: initial;
- border: initial;
- color: inherit;
-}
-
-audio::-webkit-media-controls-seek-forward-button, video::-webkit-media-controls-seek-forward-button {
- -webkit-appearance: media-seek-forward-button;
- display: flex;
- width: 16px;
- height: 16px;
- background-color: initial;
- border: initial;
- color: inherit;
-}
-
audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-fullscreen-button {
-webkit-appearance: media-enter-fullscreen-button;
display: flex;
@@ -267,20 +277,6 @@ audio::-webkit-media-controls-fullscreen-button, video::-webkit-media-controls-f
color: inherit;
}
-audio::-webkit-media-controls-rewind-button, video::-webkit-media-controls-rewind-button {
- display: none;
- background-color: initial;
- border: initial;
- color: inherit;
-}
-
-audio::-webkit-media-controls-return-to-realtime-button, video::-webkit-media-controls-return-to-realtime-button {
- display: none;
- background-color: initial;
- border: initial;
- color: inherit;
-}
-
audio::-webkit-media-controls-toggle-closed-captions-button {
display: none;
}
@@ -301,14 +297,6 @@ video::-webkit-media-controls-toggle-closed-captions-button {
color: inherit;
}
-audio::-webkit-media-controls-volume-slider-mute-button, video::-webkit-media-controls-volume-slider-mute-button {
- -webkit-appearance: media-volume-slider-mute-button;
- display: none;
- background-color: initial;
- border: initial;
- color: inherit;
-}
-
audio::-webkit-media-controls-fullscreen-volume-slider, video::-webkit-media-controls-fullscreen-volume-slider {
display: none;
}
diff --git a/chromium/third_party/WebKit/Source/core/css/mediaControlsAndroid.css b/chromium/third_party/WebKit/Source/core/css/mediaControlsAndroid.css
index 35a0bb4435e..107d18106b7 100644
--- a/chromium/third_party/WebKit/Source/core/css/mediaControlsAndroid.css
+++ b/chromium/third_party/WebKit/Source/core/css/mediaControlsAndroid.css
@@ -38,24 +38,6 @@ video::-webkit-media-controls-enclosure {
height: 40px;
}
-audio::-webkit-media-controls-overlay-enclosure {
- display: none;
-}
-
-video::-webkit-media-controls-overlay-enclosure {
- display: flex;
- position: relative;
- flex-direction: column;
- justify-content: flex-end;
- align-items: center;
- flex: 1 1;
- width: 100%;
- max-width: 800px;
- text-indent: 0;
- box-sizing: border-box;
- overflow: hidden;
-}
-
audio::-webkit-media-controls-panel, video::-webkit-media-controls-panel {
height: 35px;
}
@@ -64,22 +46,6 @@ audio::-webkit-media-controls-mute-button, video::-webkit-media-controls-mute-bu
display: none;
}
-video::-webkit-media-controls-overlay-play-button {
- -webkit-appearance: media-overlay-play-button;
- display: flex;
- position: absolute;
- top: 50%;
- left: 50%;
- margin-left: -40px;
- margin-top: -40px;
- border: none;
- box-sizing: border-box;
- background-color: transparent;
- width: 80px;
- height: 80px;
- padding: 0;
-}
-
audio::-webkit-media-controls-play-button, video::-webkit-media-controls-play-button {
width: 35px;
height: 35px;
diff --git a/chromium/third_party/WebKit/Source/core/css/navigationTransitions.css b/chromium/third_party/WebKit/Source/core/css/navigationTransitions.css
new file mode 100644
index 00000000000..4ae2f81d390
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/navigationTransitions.css
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+body {
+ animation-duration: 300ms;
+ transition-duration: 300ms;
+
+ /* Prevent user interaction. */
+ pointer-events: none !important;
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParser-in.cpp b/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParser-in.cpp
new file mode 100644
index 00000000000..4b366c75d11
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParser-in.cpp
@@ -0,0 +1,2119 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/css/parser/BisonCSSParser.h"
+
+#include "core/CSSValueKeywords.h"
+#include "core/StylePropertyShorthand.h"
+#include "core/css/CSSArrayFunctionValue.h"
+#include "core/css/CSSAspectRatioValue.h"
+#include "core/css/CSSBasicShapes.h"
+#include "core/css/CSSBorderImage.h"
+#include "core/css/CSSCanvasValue.h"
+#include "core/css/CSSCrossfadeValue.h"
+#include "core/css/CSSCursorImageValue.h"
+#include "core/css/CSSFontFaceSrcValue.h"
+#include "core/css/CSSFontFeatureValue.h"
+#include "core/css/CSSFunctionValue.h"
+#include "core/css/CSSGradientValue.h"
+#include "core/css/CSSGridLineNamesValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
+#include "core/css/CSSImageSetValue.h"
+#include "core/css/CSSImageValue.h"
+#include "core/css/CSSInheritedValue.h"
+#include "core/css/CSSInitialValue.h"
+#include "core/css/CSSKeyframeRule.h"
+#include "core/css/CSSKeyframesRule.h"
+#include "core/css/CSSLineBoxContainValue.h"
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSPropertySourceData.h"
+#include "core/css/CSSReflectValue.h"
+#include "core/css/CSSSelector.h"
+#include "core/css/CSSShadowValue.h"
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/CSSTimingFunctionValue.h"
+#include "core/css/CSSTransformValue.h"
+#include "core/css/CSSUnicodeRangeValue.h"
+#include "core/css/CSSValueList.h"
+#include "core/css/CSSValuePool.h"
+#include "core/css/Counter.h"
+#include "core/css/HashTools.h"
+#include "core/css/MediaList.h"
+#include "core/css/MediaQueryExp.h"
+#include "core/css/Pair.h"
+#include "core/css/Rect.h"
+#include "core/css/StylePropertySet.h"
+#include "core/css/StyleRule.h"
+#include "core/css/StyleRuleImport.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/css/parser/CSSParserIdioms.h"
+#include "core/dom/Document.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/Settings.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/rendering/RenderTheme.h"
+#include "platform/FloatConversion.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "wtf/BitArray.h"
+#include "wtf/HexNumber.h"
+#include "wtf/text/StringBuffer.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/StringImpl.h"
+#include "wtf/text/TextEncoding.h"
+#include <limits.h>
+
+#define YYDEBUG 0
+
+#if YYDEBUG > 0
+extern int cssyydebug;
+#endif
+
+int cssyyparse(WebCore::BisonCSSParser*);
+
+using namespace WTF;
+
+namespace WebCore {
+
+static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
+
+BisonCSSParser::BisonCSSParser(const CSSParserContext& context)
+ : m_context(context)
+ , m_important(false)
+ , m_id(CSSPropertyInvalid)
+ , m_styleSheet(nullptr)
+ , m_supportsCondition(false)
+ , m_selectorListForParseSelector(0)
+ , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
+ , m_hadSyntacticallyValidCSSRule(false)
+ , m_logErrors(false)
+ , m_ignoreErrors(false)
+ , m_defaultNamespace(starAtom)
+ , m_observer(0)
+ , m_source(0)
+ , m_ruleHeaderType(CSSRuleSourceData::UNKNOWN_RULE)
+ , m_allowImportRules(true)
+ , m_allowNamespaceDeclarations(true)
+ , m_inViewport(false)
+ , m_tokenizer(*this)
+{
+#if YYDEBUG > 0
+ cssyydebug = 1;
+#endif
+}
+
+BisonCSSParser::~BisonCSSParser()
+{
+ clearProperties();
+
+ deleteAllValues(m_floatingSelectors);
+ deleteAllValues(m_floatingSelectorVectors);
+ deleteAllValues(m_floatingValueLists);
+ deleteAllValues(m_floatingFunctions);
+}
+
+void BisonCSSParser::setupParser(const char* prefix, unsigned prefixLength, const String& string, const char* suffix, unsigned suffixLength)
+{
+ m_tokenizer.setupTokenizer(prefix, prefixLength, string, suffix, suffixLength);
+ m_ruleHasHeader = true;
+}
+
+void BisonCSSParser::parseSheet(StyleSheetContents* sheet, const String& string, const TextPosition& startPosition, CSSParserObserver* observer, bool logErrors)
+{
+ setStyleSheet(sheet);
+ m_defaultNamespace = starAtom; // Reset the default namespace.
+ TemporaryChange<CSSParserObserver*> scopedObsever(m_observer, observer);
+ m_logErrors = logErrors && sheet->singleOwnerDocument() && !sheet->baseURL().isEmpty() && sheet->singleOwnerDocument()->frameHost();
+ m_ignoreErrors = false;
+ m_tokenizer.m_lineNumber = 0;
+ m_startPosition = startPosition;
+ m_source = &string;
+ m_tokenizer.m_internal = false;
+ setupParser("", string, "");
+ cssyyparse(this);
+ sheet->shrinkToFit();
+ m_source = 0;
+ m_rule = nullptr;
+ m_lineEndings.clear();
+ m_ignoreErrors = false;
+ m_logErrors = false;
+ m_tokenizer.m_internal = true;
+}
+
+PassRefPtrWillBeRawPtr<StyleRuleBase> BisonCSSParser::parseRule(StyleSheetContents* sheet, const String& string)
+{
+ setStyleSheet(sheet);
+ m_allowNamespaceDeclarations = false;
+ setupParser("@-internal-rule ", string, "");
+ cssyyparse(this);
+ return m_rule.release();
+}
+
+PassRefPtrWillBeRawPtr<StyleKeyframe> BisonCSSParser::parseKeyframeRule(StyleSheetContents* sheet, const String& string)
+{
+ setStyleSheet(sheet);
+ setupParser("@-internal-keyframe-rule ", string, "");
+ cssyyparse(this);
+ return m_keyframe.release();
+}
+
+PassOwnPtr<Vector<double> > BisonCSSParser::parseKeyframeKeyList(const String& string)
+{
+ setupParser("@-internal-keyframe-key-list ", string, "");
+ cssyyparse(this);
+ ASSERT(m_valueList);
+ return StyleKeyframe::createKeyList(m_valueList.get());
+}
+
+bool BisonCSSParser::parseSupportsCondition(const String& string)
+{
+ m_supportsCondition = false;
+ setupParser("@-internal-supports-condition ", string, "");
+ cssyyparse(this);
+ return m_supportsCondition;
+}
+
+static inline bool isColorPropertyID(CSSPropertyID propertyId)
+{
+ switch (propertyId) {
+ case CSSPropertyColor:
+ case CSSPropertyBackgroundColor:
+ case CSSPropertyBorderBottomColor:
+ case CSSPropertyBorderLeftColor:
+ case CSSPropertyBorderRightColor:
+ case CSSPropertyBorderTopColor:
+ case CSSPropertyOutlineColor:
+ case CSSPropertyTextLineThroughColor:
+ case CSSPropertyTextOverlineColor:
+ case CSSPropertyTextUnderlineColor:
+ case CSSPropertyWebkitBorderAfterColor:
+ case CSSPropertyWebkitBorderBeforeColor:
+ case CSSPropertyWebkitBorderEndColor:
+ case CSSPropertyWebkitBorderStartColor:
+ case CSSPropertyWebkitColumnRuleColor:
+ case CSSPropertyWebkitTextEmphasisColor:
+ case CSSPropertyWebkitTextFillColor:
+ case CSSPropertyWebkitTextStrokeColor:
+ return true;
+ case CSSPropertyTextDecorationColor:
+ return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
+ default:
+ return false;
+ }
+}
+
+static bool parseColorValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
+{
+ ASSERT(!string.isEmpty());
+ bool quirksMode = isQuirksModeBehavior(cssParserMode);
+ if (!isColorPropertyID(propertyId))
+ return false;
+ CSSParserString cssString;
+ cssString.init(string);
+ CSSValueID valueID = cssValueKeywordID(cssString);
+ bool validPrimitive = false;
+ if (valueID == CSSValueWebkitText) {
+ validPrimitive = true;
+ } else if (valueID == CSSValueCurrentcolor) {
+ validPrimitive = true;
+ } else if ((valueID >= CSSValueAqua && valueID <= CSSValueWindowtext) || valueID == CSSValueMenu
+ || (quirksMode && valueID >= CSSValueWebkitFocusRingColor && valueID < CSSValueWebkitText)) {
+ validPrimitive = true;
+ }
+
+ if (validPrimitive) {
+ RefPtrWillBeRawPtr<CSSValue> value = cssValuePool().createIdentifierValue(valueID);
+ declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
+ return true;
+ }
+ RGBA32 color;
+ if (!CSSPropertyParser::fastParseColor(color, string, !quirksMode && string[0] != '#'))
+ return false;
+ RefPtrWillBeRawPtr<CSSValue> value = cssValuePool().createColorValue(color);
+ declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
+ return true;
+}
+
+static inline bool isSimpleLengthPropertyID(CSSPropertyID propertyId, bool& acceptsNegativeNumbers)
+{
+ switch (propertyId) {
+ case CSSPropertyFontSize:
+ case CSSPropertyHeight:
+ case CSSPropertyWidth:
+ case CSSPropertyMinHeight:
+ case CSSPropertyMinWidth:
+ case CSSPropertyPaddingBottom:
+ case CSSPropertyPaddingLeft:
+ case CSSPropertyPaddingRight:
+ case CSSPropertyPaddingTop:
+ case CSSPropertyWebkitLogicalWidth:
+ case CSSPropertyWebkitLogicalHeight:
+ case CSSPropertyWebkitMinLogicalWidth:
+ case CSSPropertyWebkitMinLogicalHeight:
+ case CSSPropertyWebkitPaddingAfter:
+ case CSSPropertyWebkitPaddingBefore:
+ case CSSPropertyWebkitPaddingEnd:
+ case CSSPropertyWebkitPaddingStart:
+ acceptsNegativeNumbers = false;
+ return true;
+ case CSSPropertyShapeMargin:
+ acceptsNegativeNumbers = false;
+ return RuntimeEnabledFeatures::cssShapesEnabled();
+ case CSSPropertyBottom:
+ case CSSPropertyLeft:
+ case CSSPropertyMarginBottom:
+ case CSSPropertyMarginLeft:
+ case CSSPropertyMarginRight:
+ case CSSPropertyMarginTop:
+ case CSSPropertyRight:
+ case CSSPropertyTop:
+ case CSSPropertyWebkitMarginAfter:
+ case CSSPropertyWebkitMarginBefore:
+ case CSSPropertyWebkitMarginEnd:
+ case CSSPropertyWebkitMarginStart:
+ acceptsNegativeNumbers = true;
+ return true;
+ default:
+ return false;
+ }
+}
+
+template <typename CharacterType>
+static inline bool parseSimpleLength(const CharacterType* characters, unsigned length, CSSPrimitiveValue::UnitType& unit, double& number)
+{
+ if (length > 2 && (characters[length - 2] | 0x20) == 'p' && (characters[length - 1] | 0x20) == 'x') {
+ length -= 2;
+ unit = CSSPrimitiveValue::CSS_PX;
+ } else if (length > 1 && characters[length - 1] == '%') {
+ length -= 1;
+ unit = CSSPrimitiveValue::CSS_PERCENTAGE;
+ }
+
+ // We rely on charactersToDouble for validation as well. The function
+ // will set "ok" to "false" if the entire passed-in character range does
+ // not represent a double.
+ bool ok;
+ number = charactersToDouble(characters, length, &ok);
+ return ok;
+}
+
+static bool parseSimpleLengthValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, CSSParserMode cssParserMode)
+{
+ ASSERT(!string.isEmpty());
+ bool acceptsNegativeNumbers = false;
+
+ // In @viewport, width and height are shorthands, not simple length values.
+ if (isCSSViewportParsingEnabledForMode(cssParserMode) || !isSimpleLengthPropertyID(propertyId, acceptsNegativeNumbers))
+ return false;
+
+ unsigned length = string.length();
+ double number;
+ CSSPrimitiveValue::UnitType unit = CSSPrimitiveValue::CSS_NUMBER;
+
+ if (string.is8Bit()) {
+ if (!parseSimpleLength(string.characters8(), length, unit, number))
+ return false;
+ } else {
+ if (!parseSimpleLength(string.characters16(), length, unit, number))
+ return false;
+ }
+
+ if (unit == CSSPrimitiveValue::CSS_NUMBER) {
+ bool quirksMode = isQuirksModeBehavior(cssParserMode);
+ if (number && !quirksMode)
+ return false;
+ unit = CSSPrimitiveValue::CSS_PX;
+ }
+ if (number < 0 && !acceptsNegativeNumbers)
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValue> value = cssValuePool().createValue(number, unit);
+ declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
+ return true;
+}
+
+bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, CSSValueID valueID, const CSSParserContext& parserContext)
+{
+ if (valueID == CSSValueInvalid)
+ return false;
+
+ switch (propertyId) {
+ case CSSPropertyBackgroundRepeatX: // repeat | no-repeat
+ case CSSPropertyBackgroundRepeatY: // repeat | no-repeat
+ return valueID == CSSValueRepeat || valueID == CSSValueNoRepeat;
+ case CSSPropertyBorderCollapse: // collapse | separate
+ return valueID == CSSValueCollapse || valueID == CSSValueSeparate;
+ case CSSPropertyBorderTopStyle: // <border-style>
+ case CSSPropertyBorderRightStyle: // Defined as: none | hidden | dotted | dashed |
+ case CSSPropertyBorderBottomStyle: // solid | double | groove | ridge | inset | outset
+ case CSSPropertyBorderLeftStyle:
+ case CSSPropertyWebkitBorderAfterStyle:
+ case CSSPropertyWebkitBorderBeforeStyle:
+ case CSSPropertyWebkitBorderEndStyle:
+ case CSSPropertyWebkitBorderStartStyle:
+ case CSSPropertyWebkitColumnRuleStyle:
+ return valueID >= CSSValueNone && valueID <= CSSValueDouble;
+ case CSSPropertyBoxSizing:
+ return valueID == CSSValueBorderBox || valueID == CSSValueContentBox;
+ case CSSPropertyCaptionSide: // top | bottom | left | right
+ return valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueTop || valueID == CSSValueBottom;
+ case CSSPropertyClear: // none | left | right | both
+ return valueID == CSSValueNone || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueBoth;
+ case CSSPropertyDirection: // ltr | rtl
+ return valueID == CSSValueLtr || valueID == CSSValueRtl;
+ case CSSPropertyDisplay:
+ // inline | block | list-item | inline-block | table |
+ // inline-table | table-row-group | table-header-group | table-footer-group | table-row |
+ // table-column-group | table-column | table-cell | table-caption | -webkit-box | -webkit-inline-box | none
+ // flex | inline-flex | -webkit-flex | -webkit-inline-flex | grid | inline-grid | lazy-block
+ return (valueID >= CSSValueInline && valueID <= CSSValueInlineFlex) || valueID == CSSValueWebkitFlex || valueID == CSSValueWebkitInlineFlex || valueID == CSSValueNone
+ || (RuntimeEnabledFeatures::cssGridLayoutEnabled() && (valueID == CSSValueGrid || valueID == CSSValueInlineGrid));
+ case CSSPropertyEmptyCells: // show | hide
+ return valueID == CSSValueShow || valueID == CSSValueHide;
+ case CSSPropertyFloat: // left | right | none | center (for buggy CSS, maps to none)
+ return valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueNone || valueID == CSSValueCenter;
+ case CSSPropertyFontStyle: // normal | italic | oblique
+ return valueID == CSSValueNormal || valueID == CSSValueItalic || valueID == CSSValueOblique;
+ case CSSPropertyImageRendering: // auto | optimizeContrast
+ return valueID == CSSValueAuto || valueID == CSSValueWebkitOptimizeContrast;
+ case CSSPropertyIsolation: // auto | isolate
+ return RuntimeEnabledFeatures::cssCompositingEnabled()
+ && (valueID == CSSValueAuto || valueID == CSSValueIsolate);
+ case CSSPropertyListStylePosition: // inside | outside
+ return valueID == CSSValueInside || valueID == CSSValueOutside;
+ case CSSPropertyListStyleType:
+ // See section CSS_PROP_LIST_STYLE_TYPE of file CSSValueKeywords.in
+ // for the list of supported list-style-types.
+ return (valueID >= CSSValueDisc && valueID <= CSSValueKatakanaIroha) || valueID == CSSValueNone;
+ case CSSPropertyObjectFit:
+ return RuntimeEnabledFeatures::objectFitPositionEnabled()
+ && (valueID == CSSValueFill || valueID == CSSValueContain || valueID == CSSValueCover || valueID == CSSValueNone || valueID == CSSValueScaleDown);
+ case CSSPropertyOutlineStyle: // (<border-style> except hidden) | auto
+ return valueID == CSSValueAuto || valueID == CSSValueNone || (valueID >= CSSValueInset && valueID <= CSSValueDouble);
+ case CSSPropertyOverflowWrap: // normal | break-word
+ case CSSPropertyWordWrap:
+ return valueID == CSSValueNormal || valueID == CSSValueBreakWord;
+ case CSSPropertyOverflowX: // visible | hidden | scroll | auto | overlay
+ return valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay;
+ case CSSPropertyOverflowY: // visible | hidden | scroll | auto | overlay | -webkit-paged-x | -webkit-paged-y
+ return valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueScroll || valueID == CSSValueAuto || valueID == CSSValueOverlay || valueID == CSSValueWebkitPagedX || valueID == CSSValueWebkitPagedY;
+ case CSSPropertyPageBreakAfter: // auto | always | avoid | left | right
+ case CSSPropertyPageBreakBefore:
+ case CSSPropertyWebkitColumnBreakAfter:
+ case CSSPropertyWebkitColumnBreakBefore:
+ return valueID == CSSValueAuto || valueID == CSSValueAlways || valueID == CSSValueAvoid || valueID == CSSValueLeft || valueID == CSSValueRight;
+ case CSSPropertyPageBreakInside: // avoid | auto
+ case CSSPropertyWebkitColumnBreakInside:
+ return valueID == CSSValueAuto || valueID == CSSValueAvoid;
+ case CSSPropertyPointerEvents:
+ // none | visiblePainted | visibleFill | visibleStroke | visible |
+ // painted | fill | stroke | auto | all | bounding-box
+ return valueID == CSSValueVisible || valueID == CSSValueNone || valueID == CSSValueAll || valueID == CSSValueAuto || (valueID >= CSSValueVisiblepainted && valueID <= CSSValueBoundingBox);
+ case CSSPropertyPosition: // static | relative | absolute | fixed | sticky
+ return valueID == CSSValueStatic || valueID == CSSValueRelative || valueID == CSSValueAbsolute || valueID == CSSValueFixed
+ || (RuntimeEnabledFeatures::cssStickyPositionEnabled() && valueID == CSSValueSticky);
+ case CSSPropertyResize: // none | both | horizontal | vertical | auto
+ return valueID == CSSValueNone || valueID == CSSValueBoth || valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueAuto;
+ case CSSPropertyScrollBehavior: // instant | smooth
+ return RuntimeEnabledFeatures::cssomSmoothScrollEnabled()
+ && (valueID == CSSValueInstant || valueID == CSSValueSmooth);
+ case CSSPropertySpeak: // none | normal | spell-out | digits | literal-punctuation | no-punctuation
+ return valueID == CSSValueNone || valueID == CSSValueNormal || valueID == CSSValueSpellOut || valueID == CSSValueDigits || valueID == CSSValueLiteralPunctuation || valueID == CSSValueNoPunctuation;
+ case CSSPropertyTableLayout: // auto | fixed
+ return valueID == CSSValueAuto || valueID == CSSValueFixed;
+ case CSSPropertyTextAlignLast:
+ // auto | start | end | left | right | center | justify
+ return RuntimeEnabledFeatures::css3TextEnabled()
+ && ((valueID >= CSSValueLeft && valueID <= CSSValueJustify) || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueAuto);
+ case CSSPropertyTextJustify:
+ // auto | none | inter-word | distribute
+ return RuntimeEnabledFeatures::css3TextEnabled()
+ && (valueID == CSSValueInterWord || valueID == CSSValueDistribute || valueID == CSSValueAuto || valueID == CSSValueNone);
+ case CSSPropertyTextLineThroughMode:
+ case CSSPropertyTextOverlineMode:
+ case CSSPropertyTextUnderlineMode:
+ return valueID == CSSValueContinuous || valueID == CSSValueSkipWhiteSpace;
+ case CSSPropertyTextLineThroughStyle:
+ case CSSPropertyTextOverlineStyle:
+ case CSSPropertyTextUnderlineStyle:
+ return valueID == CSSValueNone || valueID == CSSValueSolid || valueID == CSSValueDouble || valueID == CSSValueDashed || valueID == CSSValueDotDash || valueID == CSSValueDotDotDash || valueID == CSSValueWave;
+ case CSSPropertyTextOverflow: // clip | ellipsis
+ return valueID == CSSValueClip || valueID == CSSValueEllipsis;
+ case CSSPropertyTextRendering: // auto | optimizeSpeed | optimizeLegibility | geometricPrecision
+ return valueID == CSSValueAuto || valueID == CSSValueOptimizespeed || valueID == CSSValueOptimizelegibility || valueID == CSSValueGeometricprecision;
+ case CSSPropertyTextTransform: // capitalize | uppercase | lowercase | none
+ return (valueID >= CSSValueCapitalize && valueID <= CSSValueLowercase) || valueID == CSSValueNone;
+ case CSSPropertyTouchActionDelay: // none | script
+ return RuntimeEnabledFeatures::cssTouchActionDelayEnabled()
+ && (valueID == CSSValueScript || valueID == CSSValueNone);
+ case CSSPropertyVisibility: // visible | hidden | collapse
+ return valueID == CSSValueVisible || valueID == CSSValueHidden || valueID == CSSValueCollapse;
+ case CSSPropertyWebkitAppearance:
+ return (valueID >= CSSValueCheckbox && valueID <= CSSValueTextarea) || valueID == CSSValueNone;
+ case CSSPropertyBackfaceVisibility:
+ case CSSPropertyWebkitBackfaceVisibility:
+ return valueID == CSSValueVisible || valueID == CSSValueHidden;
+ case CSSPropertyMixBlendMode:
+ return RuntimeEnabledFeatures::cssCompositingEnabled()
+ && (valueID == CSSValueNormal || valueID == CSSValueMultiply || valueID == CSSValueScreen || valueID == CSSValueOverlay
+ || valueID == CSSValueDarken || valueID == CSSValueLighten || valueID == CSSValueColorDodge || valueID == CSSValueColorBurn
+ || valueID == CSSValueHardLight || valueID == CSSValueSoftLight || valueID == CSSValueDifference || valueID == CSSValueExclusion
+ || valueID == CSSValueHue || valueID == CSSValueSaturation || valueID == CSSValueColor || valueID == CSSValueLuminosity);
+ case CSSPropertyWebkitBorderFit:
+ return valueID == CSSValueBorder || valueID == CSSValueLines;
+ case CSSPropertyWebkitBoxAlign:
+ return valueID == CSSValueStretch || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline;
+ case CSSPropertyWebkitBoxDecorationBreak:
+ return valueID == CSSValueClone || valueID == CSSValueSlice;
+ case CSSPropertyWebkitBoxDirection:
+ return valueID == CSSValueNormal || valueID == CSSValueReverse;
+ case CSSPropertyWebkitBoxLines:
+ return valueID == CSSValueSingle || valueID == CSSValueMultiple;
+ case CSSPropertyWebkitBoxOrient:
+ return valueID == CSSValueHorizontal || valueID == CSSValueVertical || valueID == CSSValueInlineAxis || valueID == CSSValueBlockAxis;
+ case CSSPropertyWebkitBoxPack:
+ return valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueCenter || valueID == CSSValueJustify;
+ case CSSPropertyInternalCallback:
+ // This property is only injected programmatically, not parsed from stylesheets.
+ return false;
+ case CSSPropertyColumnFill:
+ return RuntimeEnabledFeatures::regionBasedColumnsEnabled()
+ && (valueID == CSSValueAuto || valueID == CSSValueBalance);
+ case CSSPropertyAlignContent:
+ // FIXME: Per CSS alignment, this property should accept an optional <overflow-position>. We should share this parsing code with 'justify-self'.
+ return valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround || valueID == CSSValueStretch;
+ case CSSPropertyAlignItems:
+ // FIXME: Per CSS alignment, this property should accept the same arguments as 'justify-self' so we should share its parsing code.
+ return valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch;
+ case CSSPropertyAlignSelf:
+ // FIXME: Per CSS alignment, this property should accept the same arguments as 'justify-self' so we should share its parsing code.
+ return valueID == CSSValueAuto || valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueBaseline || valueID == CSSValueStretch;
+ case CSSPropertyFlexDirection:
+ return valueID == CSSValueRow || valueID == CSSValueRowReverse || valueID == CSSValueColumn || valueID == CSSValueColumnReverse;
+ case CSSPropertyFlexWrap:
+ return valueID == CSSValueNowrap || valueID == CSSValueWrap || valueID == CSSValueWrapReverse;
+ case CSSPropertyJustifyContent:
+ // FIXME: Per CSS alignment, this property should accept an optional <overflow-position>. We should share this parsing code with 'justify-self'.
+ return valueID == CSSValueFlexStart || valueID == CSSValueFlexEnd || valueID == CSSValueCenter || valueID == CSSValueSpaceBetween || valueID == CSSValueSpaceAround;
+ case CSSPropertyFontKerning:
+ return valueID == CSSValueAuto || valueID == CSSValueNormal || valueID == CSSValueNone;
+ case CSSPropertyWebkitFontSmoothing:
+ return valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueAntialiased || valueID == CSSValueSubpixelAntialiased;
+ case CSSPropertyGridAutoFlow:
+ return RuntimeEnabledFeatures::cssGridLayoutEnabled()
+ && (valueID == CSSValueNone || valueID == CSSValueRow || valueID == CSSValueColumn);
+ case CSSPropertyWebkitLineBreak: // auto | loose | normal | strict | after-white-space
+ return valueID == CSSValueAuto || valueID == CSSValueLoose || valueID == CSSValueNormal || valueID == CSSValueStrict || valueID == CSSValueAfterWhiteSpace;
+ case CSSPropertyWebkitMarginAfterCollapse:
+ case CSSPropertyWebkitMarginBeforeCollapse:
+ case CSSPropertyWebkitMarginBottomCollapse:
+ case CSSPropertyWebkitMarginTopCollapse:
+ return valueID == CSSValueCollapse || valueID == CSSValueSeparate || valueID == CSSValueDiscard;
+ case CSSPropertyInternalMarqueeDirection:
+ return valueID == CSSValueForwards || valueID == CSSValueBackwards || valueID == CSSValueAhead || valueID == CSSValueReverse || valueID == CSSValueLeft || valueID == CSSValueRight || valueID == CSSValueDown
+ || valueID == CSSValueUp || valueID == CSSValueAuto;
+ case CSSPropertyInternalMarqueeStyle:
+ return valueID == CSSValueNone || valueID == CSSValueSlide || valueID == CSSValueScroll || valueID == CSSValueAlternate;
+ case CSSPropertyWebkitPrintColorAdjust:
+ return valueID == CSSValueExact || valueID == CSSValueEconomy;
+ case CSSPropertyWebkitRtlOrdering:
+ return valueID == CSSValueLogical || valueID == CSSValueVisual;
+ case CSSPropertyWebkitRubyPosition:
+ return valueID == CSSValueBefore || valueID == CSSValueAfter;
+ case CSSPropertyWebkitTextCombine:
+ return valueID == CSSValueNone || valueID == CSSValueHorizontal;
+ case CSSPropertyWebkitTextEmphasisPosition:
+ return valueID == CSSValueOver || valueID == CSSValueUnder;
+ case CSSPropertyWebkitTextSecurity: // disc | circle | square | none
+ return valueID == CSSValueDisc || valueID == CSSValueCircle || valueID == CSSValueSquare || valueID == CSSValueNone;
+ case CSSPropertyTransformStyle:
+ case CSSPropertyWebkitTransformStyle:
+ return valueID == CSSValueFlat || valueID == CSSValuePreserve3d;
+ case CSSPropertyWebkitUserDrag: // auto | none | element
+ return valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueElement;
+ case CSSPropertyWebkitUserModify: // read-only | read-write
+ return valueID == CSSValueReadOnly || valueID == CSSValueReadWrite || valueID == CSSValueReadWritePlaintextOnly;
+ case CSSPropertyWebkitUserSelect: // auto | none | text | all
+ return valueID == CSSValueAuto || valueID == CSSValueNone || valueID == CSSValueText || valueID == CSSValueAll;
+ case CSSPropertyWebkitWrapFlow:
+ return RuntimeEnabledFeatures::cssExclusionsEnabled()
+ && (valueID == CSSValueAuto || valueID == CSSValueBoth || valueID == CSSValueStart || valueID == CSSValueEnd || valueID == CSSValueMaximum || valueID == CSSValueClear);
+ case CSSPropertyWebkitWrapThrough:
+ return RuntimeEnabledFeatures::cssExclusionsEnabled()
+ && (valueID == CSSValueWrap || valueID == CSSValueNone);
+ case CSSPropertyWebkitWritingMode:
+ return valueID >= CSSValueHorizontalTb && valueID <= CSSValueHorizontalBt;
+ case CSSPropertyWhiteSpace: // normal | pre | nowrap
+ return valueID == CSSValueNormal || valueID == CSSValuePre || valueID == CSSValuePreWrap || valueID == CSSValuePreLine || valueID == CSSValueNowrap;
+ case CSSPropertyWordBreak: // normal | break-all | break-word (this is a custom extension)
+ return valueID == CSSValueNormal || valueID == CSSValueBreakAll || valueID == CSSValueBreakWord;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ return false;
+}
+
+bool isKeywordPropertyID(CSSPropertyID propertyId)
+{
+ switch (propertyId) {
+ case CSSPropertyMixBlendMode:
+ case CSSPropertyIsolation:
+ case CSSPropertyBackgroundRepeatX:
+ case CSSPropertyBackgroundRepeatY:
+ case CSSPropertyBorderBottomStyle:
+ case CSSPropertyBorderCollapse:
+ case CSSPropertyBorderLeftStyle:
+ case CSSPropertyBorderRightStyle:
+ case CSSPropertyBorderTopStyle:
+ case CSSPropertyBoxSizing:
+ case CSSPropertyCaptionSide:
+ case CSSPropertyClear:
+ case CSSPropertyDirection:
+ case CSSPropertyDisplay:
+ case CSSPropertyEmptyCells:
+ case CSSPropertyFloat:
+ case CSSPropertyFontStyle:
+ case CSSPropertyImageRendering:
+ case CSSPropertyListStylePosition:
+ case CSSPropertyListStyleType:
+ case CSSPropertyObjectFit:
+ case CSSPropertyOutlineStyle:
+ case CSSPropertyOverflowWrap:
+ case CSSPropertyOverflowX:
+ case CSSPropertyOverflowY:
+ case CSSPropertyPageBreakAfter:
+ case CSSPropertyPageBreakBefore:
+ case CSSPropertyPageBreakInside:
+ case CSSPropertyPointerEvents:
+ case CSSPropertyPosition:
+ case CSSPropertyResize:
+ case CSSPropertyScrollBehavior:
+ case CSSPropertySpeak:
+ case CSSPropertyTableLayout:
+ case CSSPropertyTextAlignLast:
+ case CSSPropertyTextJustify:
+ case CSSPropertyTextLineThroughMode:
+ case CSSPropertyTextLineThroughStyle:
+ case CSSPropertyTextOverflow:
+ case CSSPropertyTextOverlineMode:
+ case CSSPropertyTextOverlineStyle:
+ case CSSPropertyTextRendering:
+ case CSSPropertyTextTransform:
+ case CSSPropertyTextUnderlineMode:
+ case CSSPropertyTextUnderlineStyle:
+ case CSSPropertyTouchActionDelay:
+ case CSSPropertyVisibility:
+ case CSSPropertyWebkitAppearance:
+ case CSSPropertyBackfaceVisibility:
+ case CSSPropertyWebkitBackfaceVisibility:
+ case CSSPropertyWebkitBorderAfterStyle:
+ case CSSPropertyWebkitBorderBeforeStyle:
+ case CSSPropertyWebkitBorderEndStyle:
+ case CSSPropertyWebkitBorderFit:
+ case CSSPropertyWebkitBorderStartStyle:
+ case CSSPropertyWebkitBoxAlign:
+ case CSSPropertyWebkitBoxDecorationBreak:
+ case CSSPropertyWebkitBoxDirection:
+ case CSSPropertyWebkitBoxLines:
+ case CSSPropertyWebkitBoxOrient:
+ case CSSPropertyWebkitBoxPack:
+ case CSSPropertyInternalCallback:
+ case CSSPropertyWebkitColumnBreakAfter:
+ case CSSPropertyWebkitColumnBreakBefore:
+ case CSSPropertyWebkitColumnBreakInside:
+ case CSSPropertyColumnFill:
+ case CSSPropertyWebkitColumnRuleStyle:
+ case CSSPropertyAlignContent:
+ case CSSPropertyFlexDirection:
+ case CSSPropertyFlexWrap:
+ case CSSPropertyJustifyContent:
+ case CSSPropertyFontKerning:
+ case CSSPropertyWebkitFontSmoothing:
+ case CSSPropertyGridAutoFlow:
+ case CSSPropertyWebkitLineBreak:
+ case CSSPropertyWebkitMarginAfterCollapse:
+ case CSSPropertyWebkitMarginBeforeCollapse:
+ case CSSPropertyWebkitMarginBottomCollapse:
+ case CSSPropertyWebkitMarginTopCollapse:
+ case CSSPropertyInternalMarqueeDirection:
+ case CSSPropertyInternalMarqueeStyle:
+ case CSSPropertyWebkitPrintColorAdjust:
+ case CSSPropertyWebkitRtlOrdering:
+ case CSSPropertyWebkitRubyPosition:
+ case CSSPropertyWebkitTextCombine:
+ case CSSPropertyWebkitTextEmphasisPosition:
+ case CSSPropertyWebkitTextSecurity:
+ case CSSPropertyTransformStyle:
+ case CSSPropertyWebkitTransformStyle:
+ case CSSPropertyWebkitUserDrag:
+ case CSSPropertyWebkitUserModify:
+ case CSSPropertyWebkitUserSelect:
+ case CSSPropertyWebkitWrapFlow:
+ case CSSPropertyWebkitWrapThrough:
+ case CSSPropertyWebkitWritingMode:
+ case CSSPropertyWhiteSpace:
+ case CSSPropertyWordBreak:
+ case CSSPropertyWordWrap:
+ return true;
+ case CSSPropertyAlignItems:
+ case CSSPropertyAlignSelf:
+ return !RuntimeEnabledFeatures::cssGridLayoutEnabled();
+ default:
+ return false;
+ }
+}
+
+static bool parseKeywordValue(MutableStylePropertySet* declaration, CSSPropertyID propertyId, const String& string, bool important, const CSSParserContext& parserContext)
+{
+ ASSERT(!string.isEmpty());
+
+ if (!isKeywordPropertyID(propertyId)) {
+ // All properties accept the values of "initial" and "inherit".
+ String lowerCaseString = string.lower();
+ if (lowerCaseString != "initial" && lowerCaseString != "inherit")
+ return false;
+
+ // Parse initial/inherit shorthands using the BisonCSSParser.
+ if (shorthandForProperty(propertyId).length())
+ return false;
+ }
+
+ CSSParserString cssString;
+ cssString.init(string);
+ CSSValueID valueID = cssValueKeywordID(cssString);
+
+ if (!valueID)
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValue> value = nullptr;
+ if (valueID == CSSValueInherit)
+ value = cssValuePool().createInheritedValue();
+ else if (valueID == CSSValueInitial)
+ value = cssValuePool().createExplicitInitialValue();
+ else if (isValidKeywordPropertyAndValue(propertyId, valueID, parserContext))
+ value = cssValuePool().createIdentifierValue(valueID);
+ else
+ return false;
+
+ declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
+ return true;
+}
+
+template <typename CharType>
+static bool parseTransformTranslateArguments(CharType*& pos, CharType* end, unsigned expectedCount, CSSTransformValue* transformValue)
+{
+ while (expectedCount) {
+ size_t delimiter = WTF::find(pos, end - pos, expectedCount == 1 ? ')' : ',');
+ if (delimiter == kNotFound)
+ return false;
+ unsigned argumentLength = static_cast<unsigned>(delimiter);
+ CSSPrimitiveValue::UnitType unit = CSSPrimitiveValue::CSS_NUMBER;
+ double number;
+ if (!parseSimpleLength(pos, argumentLength, unit, number))
+ return false;
+ if (unit != CSSPrimitiveValue::CSS_PX && (number || unit != CSSPrimitiveValue::CSS_NUMBER))
+ return false;
+ transformValue->append(cssValuePool().createValue(number, CSSPrimitiveValue::CSS_PX));
+ pos += argumentLength + 1;
+ --expectedCount;
+ }
+ return true;
+}
+
+template <typename CharType>
+static bool parseTransformNumberArguments(CharType*& pos, CharType* end, unsigned expectedCount, CSSTransformValue* transformValue)
+{
+ while (expectedCount) {
+ size_t delimiter = WTF::find(pos, end - pos, expectedCount == 1 ? ')' : ',');
+ if (delimiter == kNotFound)
+ return false;
+ unsigned argumentLength = static_cast<unsigned>(delimiter);
+ bool ok;
+ double number = charactersToDouble(pos, argumentLength, &ok);
+ if (!ok)
+ return false;
+ transformValue->append(cssValuePool().createValue(number, CSSPrimitiveValue::CSS_NUMBER));
+ pos += argumentLength + 1;
+ --expectedCount;
+ }
+ return true;
+}
+
+template <typename CharType>
+static PassRefPtrWillBeRawPtr<CSSTransformValue> parseSimpleTransformValue(CharType*& pos, CharType* end)
+{
+ static const int shortestValidTransformStringLength = 12;
+
+ if (end - pos < shortestValidTransformStringLength)
+ return nullptr;
+
+ const bool isTranslate = toASCIILower(pos[0]) == 't'
+ && toASCIILower(pos[1]) == 'r'
+ && toASCIILower(pos[2]) == 'a'
+ && toASCIILower(pos[3]) == 'n'
+ && toASCIILower(pos[4]) == 's'
+ && toASCIILower(pos[5]) == 'l'
+ && toASCIILower(pos[6]) == 'a'
+ && toASCIILower(pos[7]) == 't'
+ && toASCIILower(pos[8]) == 'e';
+
+ if (isTranslate) {
+ CSSTransformValue::TransformOperationType transformType;
+ unsigned expectedArgumentCount = 1;
+ unsigned argumentStart = 11;
+ CharType c9 = toASCIILower(pos[9]);
+ if (c9 == 'x' && pos[10] == '(') {
+ transformType = CSSTransformValue::TranslateXTransformOperation;
+ } else if (c9 == 'y' && pos[10] == '(') {
+ transformType = CSSTransformValue::TranslateYTransformOperation;
+ } else if (c9 == 'z' && pos[10] == '(') {
+ transformType = CSSTransformValue::TranslateZTransformOperation;
+ } else if (c9 == '(') {
+ transformType = CSSTransformValue::TranslateTransformOperation;
+ expectedArgumentCount = 2;
+ argumentStart = 10;
+ } else if (c9 == '3' && toASCIILower(pos[10]) == 'd' && pos[11] == '(') {
+ transformType = CSSTransformValue::Translate3DTransformOperation;
+ expectedArgumentCount = 3;
+ argumentStart = 12;
+ } else {
+ return nullptr;
+ }
+ pos += argumentStart;
+ RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(transformType);
+ if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, transformValue.get()))
+ return nullptr;
+ return transformValue.release();
+ }
+
+ const bool isMatrix3d = toASCIILower(pos[0]) == 'm'
+ && toASCIILower(pos[1]) == 'a'
+ && toASCIILower(pos[2]) == 't'
+ && toASCIILower(pos[3]) == 'r'
+ && toASCIILower(pos[4]) == 'i'
+ && toASCIILower(pos[5]) == 'x'
+ && pos[6] == '3'
+ && toASCIILower(pos[7]) == 'd'
+ && pos[8] == '(';
+
+ if (isMatrix3d) {
+ pos += 9;
+ RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(CSSTransformValue::Matrix3DTransformOperation);
+ if (!parseTransformNumberArguments(pos, end, 16, transformValue.get()))
+ return nullptr;
+ return transformValue.release();
+ }
+
+ const bool isScale3d = toASCIILower(pos[0]) == 's'
+ && toASCIILower(pos[1]) == 'c'
+ && toASCIILower(pos[2]) == 'a'
+ && toASCIILower(pos[3]) == 'l'
+ && toASCIILower(pos[4]) == 'e'
+ && pos[5] == '3'
+ && toASCIILower(pos[6]) == 'd'
+ && pos[7] == '(';
+
+ if (isScale3d) {
+ pos += 8;
+ RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(CSSTransformValue::Scale3DTransformOperation);
+ if (!parseTransformNumberArguments(pos, end, 3, transformValue.get()))
+ return nullptr;
+ return transformValue.release();
+ }
+
+ return nullptr;
+}
+
+template <typename CharType>
+static PassRefPtrWillBeRawPtr<CSSValueList> parseSimpleTransformList(CharType*& pos, CharType* end)
+{
+ RefPtrWillBeRawPtr<CSSValueList> transformList = nullptr;
+ while (pos < end) {
+ while (pos < end && isCSSSpace(*pos))
+ ++pos;
+ RefPtrWillBeRawPtr<CSSTransformValue> transformValue = parseSimpleTransformValue(pos, end);
+ if (!transformValue)
+ return nullptr;
+ if (!transformList)
+ transformList = CSSValueList::createSpaceSeparated();
+ transformList->append(transformValue.release());
+ if (pos < end) {
+ if (isCSSSpace(*pos))
+ return nullptr;
+ }
+ }
+ return transformList.release();
+}
+
+static bool parseSimpleTransform(MutableStylePropertySet* properties, CSSPropertyID propertyID, const String& string, bool important)
+{
+ if (propertyID != CSSPropertyTransform && propertyID != CSSPropertyWebkitTransform)
+ return false;
+ if (string.isEmpty())
+ return false;
+ RefPtrWillBeRawPtr<CSSValueList> transformList = nullptr;
+ if (string.is8Bit()) {
+ const LChar* pos = string.characters8();
+ const LChar* end = pos + string.length();
+ transformList = parseSimpleTransformList(pos, end);
+ if (!transformList)
+ return false;
+ } else {
+ const UChar* pos = string.characters16();
+ const UChar* end = pos + string.length();
+ transformList = parseSimpleTransformList(pos, end);
+ if (!transformList)
+ return false;
+ }
+ properties->addParsedProperty(CSSProperty(propertyID, transformList.release(), important));
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValueList> BisonCSSParser::parseFontFaceValue(const AtomicString& string)
+{
+ if (string.isEmpty())
+ return nullptr;
+ RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
+ if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, HTMLQuirksMode, 0))
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSValue> fontFamily = dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily);
+ if (!fontFamily->isValueList())
+ return nullptr;
+
+ return toCSSValueList(dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily).get());
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> BisonCSSParser::parseAnimationTimingFunctionValue(const String& string)
+{
+ if (string.isEmpty())
+ return nullptr;
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ if (!parseValue(style.get(), CSSPropertyTransitionTimingFunction, string, false, HTMLStandardMode, 0))
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(CSSPropertyTransitionTimingFunction);
+ if (!value || value->isInitialValue() || value->isInheritedValue())
+ return nullptr;
+ CSSValueList* valueList = toCSSValueList(value.get());
+ if (valueList->length() > 1)
+ return nullptr;
+ return valueList->item(0);
+}
+
+bool BisonCSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, const Document& document)
+{
+ ASSERT(!string.isEmpty());
+
+ CSSParserContext context(document, UseCounter::getFrom(&document));
+
+ if (parseSimpleLengthValue(declaration, propertyID, string, important, context.mode()))
+ return true;
+ if (parseColorValue(declaration, propertyID, string, important, context.mode()))
+ return true;
+ if (parseKeywordValue(declaration, propertyID, string, important, context))
+ return true;
+
+ BisonCSSParser parser(context);
+ return parser.parseValue(declaration, propertyID, string, important, static_cast<StyleSheetContents*>(0));
+}
+
+bool BisonCSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, CSSParserMode cssParserMode, StyleSheetContents* contextStyleSheet)
+{
+ ASSERT(!string.isEmpty());
+ if (parseSimpleLengthValue(declaration, propertyID, string, important, cssParserMode))
+ return true;
+ if (parseColorValue(declaration, propertyID, string, important, cssParserMode))
+ return true;
+
+ CSSParserContext context(cssParserMode, 0);
+ if (contextStyleSheet) {
+ context = contextStyleSheet->parserContext();
+ context.setMode(cssParserMode);
+ }
+
+ if (parseKeywordValue(declaration, propertyID, string, important, context))
+ return true;
+ if (parseSimpleTransform(declaration, propertyID, string, important))
+ return true;
+
+ BisonCSSParser parser(context);
+ return parser.parseValue(declaration, propertyID, string, important, contextStyleSheet);
+}
+
+bool BisonCSSParser::parseValue(MutableStylePropertySet* declaration, CSSPropertyID propertyID, const String& string, bool important, StyleSheetContents* contextStyleSheet)
+{
+ // FIXME: Check RuntimeCSSEnabled::isPropertyEnabled or isValueEnabledForProperty.
+
+ if (m_context.useCounter())
+ m_context.useCounter()->count(m_context, propertyID);
+
+ setStyleSheet(contextStyleSheet);
+
+ setupParser("@-internal-value ", string, "");
+
+ m_id = propertyID;
+ m_important = important;
+
+ {
+ StyleDeclarationScope scope(this, declaration);
+ cssyyparse(this);
+ }
+
+ m_rule = nullptr;
+ m_id = CSSPropertyInvalid;
+
+ bool ok = false;
+ if (!m_parsedProperties.isEmpty()) {
+ ok = true;
+ declaration->addParsedProperties(m_parsedProperties);
+ clearProperties();
+ }
+
+ return ok;
+}
+
+// The color will only be changed when string contains a valid CSS color, so callers
+// can set it to a default color and ignore the boolean result.
+bool BisonCSSParser::parseColor(RGBA32& color, const String& string, bool strict)
+{
+ // First try creating a color specified by name, rgba(), rgb() or "#" syntax.
+ if (CSSPropertyParser::fastParseColor(color, string, strict))
+ return true;
+
+ BisonCSSParser parser(strictCSSParserContext());
+
+ // In case the fast-path parser didn't understand the color, try the full parser.
+ if (!parser.parseColor(string))
+ return false;
+
+ CSSValue* value = parser.m_parsedProperties.first().value();
+ if (!value->isPrimitiveValue())
+ return false;
+
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (!primitiveValue->isRGBColor())
+ return false;
+
+ color = primitiveValue->getRGBA32Value();
+ return true;
+}
+
+bool BisonCSSParser::parseColor(const String& string)
+{
+ setupParser("@-internal-decls color:", string, "");
+ cssyyparse(this);
+ m_rule = nullptr;
+
+ return !m_parsedProperties.isEmpty() && m_parsedProperties.first().id() == CSSPropertyColor;
+}
+
+bool BisonCSSParser::parseSystemColor(RGBA32& color, const String& string)
+{
+ CSSParserString cssColor;
+ cssColor.init(string);
+ CSSValueID id = cssValueKeywordID(cssColor);
+ if (!CSSPropertyParser::isSystemColor(id))
+ return false;
+
+ Color parsedColor = RenderTheme::theme().systemColor(id);
+ color = parsedColor.rgb();
+ return true;
+}
+
+void BisonCSSParser::parseSelector(const String& string, CSSSelectorList& selectorList)
+{
+ m_selectorListForParseSelector = &selectorList;
+
+ setupParser("@-internal-selector ", string, "");
+
+ cssyyparse(this);
+
+ m_selectorListForParseSelector = 0;
+}
+
+PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::parseInlineStyleDeclaration(const String& string, Element* element)
+{
+ Document& document = element->document();
+ CSSParserContext context = CSSParserContext(document.elementSheet().contents()->parserContext(), UseCounter::getFrom(&document));
+ context.setMode((element->isHTMLElement() && !document.inQuirksMode()) ? HTMLStandardMode : HTMLQuirksMode);
+ return BisonCSSParser(context).parseDeclaration(string, document.elementSheet().contents());
+}
+
+PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::parseDeclaration(const String& string, StyleSheetContents* contextStyleSheet)
+{
+ setStyleSheet(contextStyleSheet);
+
+ setupParser("@-internal-decls ", string, "");
+ cssyyparse(this);
+ m_rule = nullptr;
+
+ RefPtr<ImmutableStylePropertySet> style = createStylePropertySet();
+ clearProperties();
+ return style.release();
+}
+
+
+bool BisonCSSParser::parseDeclaration(MutableStylePropertySet* declaration, const String& string, CSSParserObserver* observer, StyleSheetContents* contextStyleSheet)
+{
+ setStyleSheet(contextStyleSheet);
+
+ TemporaryChange<CSSParserObserver*> scopedObsever(m_observer, observer);
+
+ setupParser("@-internal-decls ", string, "");
+ if (m_observer) {
+ m_observer->startRuleHeader(CSSRuleSourceData::STYLE_RULE, 0);
+ m_observer->endRuleHeader(1);
+ m_observer->startRuleBody(0);
+ }
+
+ {
+ StyleDeclarationScope scope(this, declaration);
+ cssyyparse(this);
+ }
+
+ m_rule = nullptr;
+
+ bool ok = false;
+ if (!m_parsedProperties.isEmpty()) {
+ ok = true;
+ declaration->addParsedProperties(m_parsedProperties);
+ clearProperties();
+ }
+
+ if (m_observer)
+ m_observer->endRuleBody(string.length(), false);
+
+ return ok;
+}
+
+PassRefPtrWillBeRawPtr<MediaQuerySet> BisonCSSParser::parseMediaQueryList(const String& string)
+{
+ ASSERT(!m_mediaList);
+
+ // can't use { because tokenizer state switches from mediaquery to initial state when it sees { token.
+ // instead insert one " " (which is caught by maybe_space in CSSGrammar.y)
+ setupParser("@-internal-medialist ", string, "");
+ cssyyparse(this);
+
+ ASSERT(m_mediaList);
+ return m_mediaList.release();
+}
+
+static inline void filterProperties(bool important, const WillBeHeapVector<CSSProperty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties)
+{
+ // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
+ for (int i = input.size() - 1; i >= 0; --i) {
+ const CSSProperty& property = input[i];
+ if (property.isImportant() != important)
+ continue;
+ const unsigned propertyIDIndex = property.id() - firstCSSProperty;
+ if (seenProperties.get(propertyIDIndex))
+ continue;
+ seenProperties.set(propertyIDIndex);
+ output[--unusedEntries] = property;
+ }
+}
+
+PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::createStylePropertySet()
+{
+ BitArray<numCSSProperties> seenProperties;
+ size_t unusedEntries = m_parsedProperties.size();
+ WillBeHeapVector<CSSProperty, 256> results(unusedEntries);
+
+ // Important properties have higher priority, so add them first. Duplicate definitions can then be ignored when found.
+ filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties);
+ filterProperties(false, m_parsedProperties, results, unusedEntries, seenProperties);
+ if (unusedEntries)
+ results.remove(0, unusedEntries);
+
+ CSSParserMode mode = inViewport() ? CSSViewportRuleMode : m_context.mode();
+
+ return ImmutableStylePropertySet::create(results.data(), results.size(), mode);
+}
+
+void BisonCSSParser::rollbackLastProperties(int num)
+{
+ ASSERT(num >= 0);
+ ASSERT(m_parsedProperties.size() >= static_cast<unsigned>(num));
+ m_parsedProperties.shrink(m_parsedProperties.size() - num);
+}
+
+void BisonCSSParser::clearProperties()
+{
+ m_parsedProperties.clear();
+ m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
+}
+
+void BisonCSSParser::setCurrentProperty(CSSPropertyID propId)
+{
+ m_id = propId;
+}
+
+bool BisonCSSParser::parseValue(CSSPropertyID propId, bool important)
+{
+ CSSPropertyParser parser(m_valueList, m_context, m_inViewport, m_important, m_parsedProperties, m_ruleHeaderType);
+ return parser.parseValue(propId, important);
+}
+
+
+class TransformOperationInfo {
+public:
+ TransformOperationInfo(const CSSParserString& name)
+ : m_type(CSSTransformValue::UnknownTransformOperation)
+ , m_argCount(1)
+ , m_allowSingleArgument(false)
+ , m_unit(CSSPropertyParser::FUnknown)
+ {
+ const UChar* characters;
+ unsigned nameLength = name.length();
+
+ const unsigned longestNameLength = 12;
+ UChar characterBuffer[longestNameLength];
+ if (name.is8Bit()) {
+ unsigned length = std::min(longestNameLength, nameLength);
+ const LChar* characters8 = name.characters8();
+ for (unsigned i = 0; i < length; ++i)
+ characterBuffer[i] = characters8[i];
+ characters = characterBuffer;
+ } else
+ characters = name.characters16();
+
+ SWITCH(characters, nameLength) {
+ CASE("skew(") {
+ m_unit = CSSPropertyParser::FAngle;
+ m_type = CSSTransformValue::SkewTransformOperation;
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ CASE("scale(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::ScaleTransformOperation;
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ CASE("skewx(") {
+ m_unit = CSSPropertyParser::FAngle;
+ m_type = CSSTransformValue::SkewXTransformOperation;
+ }
+ CASE("skewy(") {
+ m_unit = CSSPropertyParser::FAngle;
+ m_type = CSSTransformValue::SkewYTransformOperation;
+ }
+ CASE("matrix(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::MatrixTransformOperation;
+ m_argCount = 11;
+ }
+ CASE("rotate(") {
+ m_unit = CSSPropertyParser::FAngle;
+ m_type = CSSTransformValue::RotateTransformOperation;
+ }
+ CASE("scalex(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::ScaleXTransformOperation;
+ }
+ CASE("scaley(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::ScaleYTransformOperation;
+ }
+ CASE("scalez(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::ScaleZTransformOperation;
+ }
+ CASE("scale3d(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::Scale3DTransformOperation;
+ m_argCount = 5;
+ }
+ CASE("rotatex(") {
+ m_unit = CSSPropertyParser::FAngle;
+ m_type = CSSTransformValue::RotateXTransformOperation;
+ }
+ CASE("rotatey(") {
+ m_unit = CSSPropertyParser::FAngle;
+ m_type = CSSTransformValue::RotateYTransformOperation;
+ }
+ CASE("rotatez(") {
+ m_unit = CSSPropertyParser::FAngle;
+ m_type = CSSTransformValue::RotateZTransformOperation;
+ }
+ CASE("matrix3d(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::Matrix3DTransformOperation;
+ m_argCount = 31;
+ }
+ CASE("rotate3d(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::Rotate3DTransformOperation;
+ m_argCount = 7;
+ }
+ CASE("translate(") {
+ m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
+ m_type = CSSTransformValue::TranslateTransformOperation;
+ m_allowSingleArgument = true;
+ m_argCount = 3;
+ }
+ CASE("translatex(") {
+ m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
+ m_type = CSSTransformValue::TranslateXTransformOperation;
+ }
+ CASE("translatey(") {
+ m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
+ m_type = CSSTransformValue::TranslateYTransformOperation;
+ }
+ CASE("translatez(") {
+ m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
+ m_type = CSSTransformValue::TranslateZTransformOperation;
+ }
+ CASE("perspective(") {
+ m_unit = CSSPropertyParser::FNumber;
+ m_type = CSSTransformValue::PerspectiveTransformOperation;
+ }
+ CASE("translate3d(") {
+ m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
+ m_type = CSSTransformValue::Translate3DTransformOperation;
+ m_argCount = 5;
+ }
+ }
+ }
+
+ CSSTransformValue::TransformOperationType type() const { return m_type; }
+ unsigned argCount() const { return m_argCount; }
+ CSSPropertyParser::Units unit() const { return m_unit; }
+
+ bool unknown() const { return m_type == CSSTransformValue::UnknownTransformOperation; }
+ bool hasCorrectArgCount(unsigned argCount) { return m_argCount == argCount || (m_allowSingleArgument && argCount == 1); }
+
+private:
+ CSSTransformValue::TransformOperationType m_type;
+ unsigned m_argCount;
+ bool m_allowSingleArgument;
+ CSSPropertyParser::Units m_unit;
+};
+
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform(CSSPropertyID propId)
+{
+ if (!m_valueList)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+ RefPtrWillBeRawPtr<CSSValue> parsedTransformValue = parseTransformValue(propId, value);
+ if (!parsedTransformValue)
+ return nullptr;
+
+ list->append(parsedTransformValue.release());
+ }
+
+ return list.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSPropertyID propId, CSSParserValue *value)
+{
+ if (value->unit != CSSParserValue::Function || !value->function)
+ return nullptr;
+
+ // Every primitive requires at least one argument.
+ CSSParserValueList* args = value->function->args.get();
+ if (!args)
+ return nullptr;
+
+ // See if the specified primitive is one we understand.
+ TransformOperationInfo info(value->function->name);
+ if (info.unknown())
+ return nullptr;
+
+ if (!info.hasCorrectArgCount(args->size()))
+ return nullptr;
+
+ // The transform is a list of functional primitives that specify transform operations.
+ // We collect a list of CSSTransformValues, where each value specifies a single operation.
+
+ // Create the new CSSTransformValue for this operation and add it to our list.
+ RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(info.type());
+
+ // Snag our values.
+ CSSParserValue* a = args->current();
+ unsigned argNumber = 0;
+ while (a) {
+ CSSPropertyParser::Units unit = info.unit();
+
+ if (info.type() == CSSTransformValue::Rotate3DTransformOperation && argNumber == 3) {
+ // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
+ if (!validUnit(a, FAngle, HTMLStandardMode))
+ return nullptr;
+ } else if (info.type() == CSSTransformValue::Translate3DTransformOperation && argNumber == 2) {
+ // 3rd param of translate3d() cannot be a percentage
+ if (!validUnit(a, FLength, HTMLStandardMode))
+ return nullptr;
+ } else if (info.type() == CSSTransformValue::TranslateZTransformOperation && !argNumber) {
+ // 1st param of translateZ() cannot be a percentage
+ if (!validUnit(a, FLength, HTMLStandardMode))
+ return nullptr;
+ } else if (info.type() == CSSTransformValue::PerspectiveTransformOperation && !argNumber) {
+ // 1st param of perspective() must be a non-negative number (deprecated) or length.
+ if ((propId == CSSPropertyWebkitTransform && !validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
+ || (propId == CSSPropertyTransform && !validUnit(a, FLength | FNonNeg, HTMLStandardMode)))
+ return nullptr;
+ } else if (!validUnit(a, unit, HTMLStandardMode)) {
+ return nullptr;
+ }
+
+ // Add the value to the current transform operation.
+ transformValue->append(createPrimitiveNumericValue(a));
+
+ a = args->next();
+ if (!a)
+ break;
+ if (a->unit != CSSParserValue::Operator || a->iValue != ',')
+ return nullptr;
+ a = args->next();
+
+ argNumber++;
+ }
+
+ return transformValue.release();
+}
+
+void BisonCSSParser::ensureLineEndings()
+{
+ if (!m_lineEndings)
+ m_lineEndings = lineEndings(*m_source);
+}
+
+CSSParserSelector* BisonCSSParser::createFloatingSelectorWithTagName(const QualifiedName& tagQName)
+{
+ CSSParserSelector* selector = new CSSParserSelector(tagQName);
+ m_floatingSelectors.append(selector);
+ return selector;
+}
+
+CSSParserSelector* BisonCSSParser::createFloatingSelector()
+{
+ CSSParserSelector* selector = new CSSParserSelector;
+ m_floatingSelectors.append(selector);
+ return selector;
+}
+
+PassOwnPtr<CSSParserSelector> BisonCSSParser::sinkFloatingSelector(CSSParserSelector* selector)
+{
+ if (selector) {
+ size_t index = m_floatingSelectors.reverseFind(selector);
+ ASSERT(index != kNotFound);
+ m_floatingSelectors.remove(index);
+ }
+ return adoptPtr(selector);
+}
+
+Vector<OwnPtr<CSSParserSelector> >* BisonCSSParser::createFloatingSelectorVector()
+{
+ Vector<OwnPtr<CSSParserSelector> >* selectorVector = new Vector<OwnPtr<CSSParserSelector> >;
+ m_floatingSelectorVectors.append(selectorVector);
+ return selectorVector;
+}
+
+PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > BisonCSSParser::sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >* selectorVector)
+{
+ if (selectorVector) {
+ size_t index = m_floatingSelectorVectors.reverseFind(selectorVector);
+ ASSERT(index != kNotFound);
+ m_floatingSelectorVectors.remove(index);
+ }
+ return adoptPtr(selectorVector);
+}
+
+CSSParserValueList* BisonCSSParser::createFloatingValueList()
+{
+ CSSParserValueList* list = new CSSParserValueList;
+ m_floatingValueLists.append(list);
+ return list;
+}
+
+PassOwnPtr<CSSParserValueList> BisonCSSParser::sinkFloatingValueList(CSSParserValueList* list)
+{
+ if (list) {
+ size_t index = m_floatingValueLists.reverseFind(list);
+ ASSERT(index != kNotFound);
+ m_floatingValueLists.remove(index);
+ }
+ return adoptPtr(list);
+}
+
+CSSParserFunction* BisonCSSParser::createFloatingFunction()
+{
+ CSSParserFunction* function = new CSSParserFunction;
+ m_floatingFunctions.append(function);
+ return function;
+}
+
+CSSParserFunction* BisonCSSParser::createFloatingFunction(const CSSParserString& name, PassOwnPtr<CSSParserValueList> args)
+{
+ CSSParserFunction* function = createFloatingFunction();
+ function->name = name;
+ function->args = args;
+ return function;
+}
+
+PassOwnPtr<CSSParserFunction> BisonCSSParser::sinkFloatingFunction(CSSParserFunction* function)
+{
+ if (function) {
+ size_t index = m_floatingFunctions.reverseFind(function);
+ ASSERT(index != kNotFound);
+ m_floatingFunctions.remove(index);
+ }
+ return adoptPtr(function);
+}
+
+CSSParserValue& BisonCSSParser::sinkFloatingValue(CSSParserValue& value)
+{
+ if (value.unit == CSSParserValue::Function) {
+ size_t index = m_floatingFunctions.reverseFind(value.function);
+ ASSERT(index != kNotFound);
+ m_floatingFunctions.remove(index);
+ }
+ return value;
+}
+
+MediaQueryExp* BisonCSSParser::createFloatingMediaQueryExp(const AtomicString& mediaFeature, CSSParserValueList* values)
+{
+ m_floatingMediaQueryExp = MediaQueryExp::createIfValid(mediaFeature, values);
+ return m_floatingMediaQueryExp.get();
+}
+
+PassOwnPtrWillBeRawPtr<MediaQueryExp> BisonCSSParser::sinkFloatingMediaQueryExp(MediaQueryExp* expression)
+{
+ ASSERT_UNUSED(expression, expression == m_floatingMediaQueryExp);
+ return m_floatingMediaQueryExp.release();
+}
+
+WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* BisonCSSParser::createFloatingMediaQueryExpList()
+{
+ m_floatingMediaQueryExpList = adoptPtrWillBeNoop(new WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >);
+ return m_floatingMediaQueryExpList.get();
+}
+
+PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > BisonCSSParser::sinkFloatingMediaQueryExpList(WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* list)
+{
+ ASSERT_UNUSED(list, list == m_floatingMediaQueryExpList);
+ return m_floatingMediaQueryExpList.release();
+}
+
+MediaQuery* BisonCSSParser::createFloatingMediaQuery(MediaQuery::Restrictor restrictor, const AtomicString& mediaType, PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > expressions)
+{
+ m_floatingMediaQuery = adoptPtrWillBeNoop(new MediaQuery(restrictor, mediaType, expressions));
+ return m_floatingMediaQuery.get();
+}
+
+MediaQuery* BisonCSSParser::createFloatingMediaQuery(PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > expressions)
+{
+ return createFloatingMediaQuery(MediaQuery::None, AtomicString("all", AtomicString::ConstructFromLiteral), expressions);
+}
+
+MediaQuery* BisonCSSParser::createFloatingNotAllQuery()
+{
+ return createFloatingMediaQuery(MediaQuery::Not, AtomicString("all", AtomicString::ConstructFromLiteral), sinkFloatingMediaQueryExpList(createFloatingMediaQueryExpList()));
+}
+
+PassOwnPtrWillBeRawPtr<MediaQuery> BisonCSSParser::sinkFloatingMediaQuery(MediaQuery* query)
+{
+ ASSERT_UNUSED(query, query == m_floatingMediaQuery);
+ return m_floatingMediaQuery.release();
+}
+
+WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* BisonCSSParser::createFloatingKeyframeVector()
+{
+ m_floatingKeyframeVector = adoptPtrWillBeNoop(new WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >());
+ return m_floatingKeyframeVector.get();
+}
+
+PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > BisonCSSParser::sinkFloatingKeyframeVector(WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* keyframeVector)
+{
+ ASSERT_UNUSED(keyframeVector, m_floatingKeyframeVector == keyframeVector);
+ return m_floatingKeyframeVector.release();
+}
+
+MediaQuerySet* BisonCSSParser::createMediaQuerySet()
+{
+ RefPtrWillBeRawPtr<MediaQuerySet> queries = MediaQuerySet::create();
+ MediaQuerySet* result = queries.get();
+ m_parsedMediaQuerySets.append(queries.release());
+ return result;
+}
+
+StyleRuleBase* BisonCSSParser::createImportRule(const CSSParserString& url, MediaQuerySet* media)
+{
+ if (!media || !m_allowImportRules)
+ return 0;
+ RefPtrWillBeRawPtr<StyleRuleImport> rule = StyleRuleImport::create(url, media);
+ StyleRuleImport* result = rule.get();
+ m_parsedRules.append(rule.release());
+ return result;
+}
+
+StyleRuleBase* BisonCSSParser::createMediaRule(MediaQuerySet* media, RuleList* rules)
+{
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+ RefPtrWillBeRawPtr<StyleRuleMedia> rule = nullptr;
+ if (rules) {
+ rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create().get(), *rules);
+ } else {
+ RuleList emptyRules;
+ rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create().get(), emptyRules);
+ }
+ StyleRuleMedia* result = rule.get();
+ m_parsedRules.append(rule.release());
+ return result;
+}
+
+StyleRuleBase* BisonCSSParser::createSupportsRule(bool conditionIsSupported, RuleList* rules)
+{
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+
+ RefPtrWillBeRawPtr<CSSRuleSourceData> data = popSupportsRuleData();
+ RefPtrWillBeRawPtr<StyleRuleSupports> rule = nullptr;
+ String conditionText;
+ unsigned conditionOffset = data->ruleHeaderRange.start + 9;
+ unsigned conditionLength = data->ruleHeaderRange.length() - 9;
+
+ if (m_tokenizer.is8BitSource())
+ conditionText = String(m_tokenizer.m_dataStart8.get() + conditionOffset, conditionLength).stripWhiteSpace();
+ else
+ conditionText = String(m_tokenizer.m_dataStart16.get() + conditionOffset, conditionLength).stripWhiteSpace();
+
+ if (rules) {
+ rule = StyleRuleSupports::create(conditionText, conditionIsSupported, *rules);
+ } else {
+ RuleList emptyRules;
+ rule = StyleRuleSupports::create(conditionText, conditionIsSupported, emptyRules);
+ }
+
+ StyleRuleSupports* result = rule.get();
+ m_parsedRules.append(rule.release());
+
+ return result;
+}
+
+void BisonCSSParser::markSupportsRuleHeaderStart()
+{
+ if (!m_supportsRuleDataStack)
+ m_supportsRuleDataStack = adoptPtrWillBeNoop(new RuleSourceDataList());
+
+ RefPtrWillBeRawPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(CSSRuleSourceData::SUPPORTS_RULE);
+ data->ruleHeaderRange.start = m_tokenizer.tokenStartOffset();
+ m_supportsRuleDataStack->append(data);
+}
+
+void BisonCSSParser::markSupportsRuleHeaderEnd()
+{
+ ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty());
+
+ if (m_tokenizer.is8BitSource())
+ m_supportsRuleDataStack->last()->ruleHeaderRange.end = m_tokenizer.tokenStart<LChar>() - m_tokenizer.m_dataStart8.get();
+ else
+ m_supportsRuleDataStack->last()->ruleHeaderRange.end = m_tokenizer.tokenStart<UChar>() - m_tokenizer.m_dataStart16.get();
+}
+
+PassRefPtrWillBeRawPtr<CSSRuleSourceData> BisonCSSParser::popSupportsRuleData()
+{
+ ASSERT(m_supportsRuleDataStack && !m_supportsRuleDataStack->isEmpty());
+ RefPtrWillBeRawPtr<CSSRuleSourceData> data = m_supportsRuleDataStack->last();
+ m_supportsRuleDataStack->removeLast();
+ return data.release();
+}
+
+BisonCSSParser::RuleList* BisonCSSParser::createRuleList()
+{
+ OwnPtrWillBeRawPtr<RuleList> list = adoptPtrWillBeNoop(new RuleList);
+ RuleList* listPtr = list.get();
+
+ m_parsedRuleLists.append(list.release());
+ return listPtr;
+}
+
+BisonCSSParser::RuleList* BisonCSSParser::appendRule(RuleList* ruleList, StyleRuleBase* rule)
+{
+ if (rule) {
+ if (!ruleList)
+ ruleList = createRuleList();
+ ruleList->append(rule);
+ }
+ return ruleList;
+}
+
+template <typename CharacterType>
+ALWAYS_INLINE static void makeLower(const CharacterType* input, CharacterType* output, unsigned length)
+{
+ // FIXME: If we need Unicode lowercasing here, then we probably want the real kind
+ // that can potentially change the length of the string rather than the character
+ // by character kind. If we don't need Unicode lowercasing, it would be good to
+ // simplify this function.
+
+ if (charactersAreAllASCII(input, length)) {
+ // Fast case for all-ASCII.
+ for (unsigned i = 0; i < length; i++)
+ output[i] = toASCIILower(input[i]);
+ } else {
+ for (unsigned i = 0; i < length; i++)
+ output[i] = Unicode::toLower(input[i]);
+ }
+}
+
+void BisonCSSParser::tokenToLowerCase(CSSParserString& token)
+{
+ // Since it's our internal token, we know that we created it out
+ // of our writable work buffers. Therefore the const_cast is just
+ // ugly and not a potential crash.
+ size_t length = token.length();
+ if (token.is8Bit()) {
+ makeLower(token.characters8(), const_cast<LChar*>(token.characters8()), length);
+ } else {
+ makeLower(token.characters16(), const_cast<UChar*>(token.characters16()), length);
+ }
+}
+
+void BisonCSSParser::endInvalidRuleHeader()
+{
+ if (m_ruleHeaderType == CSSRuleSourceData::UNKNOWN_RULE)
+ return;
+
+ CSSParserLocation location;
+ location.lineNumber = m_tokenizer.m_lineNumber;
+ location.offset = m_ruleHeaderStartOffset;
+ if (m_tokenizer.is8BitSource())
+ location.token.init(m_tokenizer.m_dataStart8.get() + m_ruleHeaderStartOffset, 0);
+ else
+ location.token.init(m_tokenizer.m_dataStart16.get() + m_ruleHeaderStartOffset, 0);
+
+ reportError(location, m_ruleHeaderType == CSSRuleSourceData::STYLE_RULE ? InvalidSelectorCSSError : InvalidRuleCSSError);
+
+ endRuleHeader();
+}
+
+void BisonCSSParser::reportError(const CSSParserLocation&, CSSParserError)
+{
+ // FIXME: error reporting temporatily disabled.
+}
+
+bool BisonCSSParser::isLoggingErrors()
+{
+ return m_logErrors && !m_ignoreErrors;
+}
+
+void BisonCSSParser::logError(const String& message, const CSSParserLocation& location)
+{
+ unsigned lineNumberInStyleSheet;
+ unsigned columnNumber = 0;
+ if (InspectorInstrumentation::hasFrontends()) {
+ ensureLineEndings();
+ TextPosition tokenPosition = TextPosition::fromOffsetAndLineEndings(location.offset, *m_lineEndings);
+ lineNumberInStyleSheet = tokenPosition.m_line.zeroBasedInt();
+ columnNumber = (lineNumberInStyleSheet ? 0 : m_startPosition.m_column.zeroBasedInt()) + tokenPosition.m_column.zeroBasedInt();
+ } else {
+ lineNumberInStyleSheet = location.lineNumber;
+ }
+ FrameConsole& console = m_styleSheet->singleOwnerDocument()->frame()->console();
+ console.addMessage(CSSMessageSource, WarningMessageLevel, message, m_styleSheet->baseURL().string(), lineNumberInStyleSheet + m_startPosition.m_line.zeroBasedInt() + 1, columnNumber + 1);
+}
+
+StyleRuleKeyframes* BisonCSSParser::createKeyframesRule(const String& name, PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > popKeyframes, bool isPrefixed)
+{
+ OwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > keyframes = popKeyframes;
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+ RefPtrWillBeRawPtr<StyleRuleKeyframes> rule = StyleRuleKeyframes::create();
+ for (size_t i = 0; i < keyframes->size(); ++i)
+ rule->parserAppendKeyframe(keyframes->at(i));
+ rule->setName(name);
+ rule->setVendorPrefixed(isPrefixed);
+ StyleRuleKeyframes* rulePtr = rule.get();
+ m_parsedRules.append(rule.release());
+ return rulePtr;
+}
+
+static void recordSelectorStats(const CSSParserContext& context, const CSSSelectorList& selectorList)
+{
+ if (!context.useCounter())
+ return;
+
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) {
+ for (const CSSSelector* current = selector; current ; current = current->tagHistory()) {
+ UseCounter::Feature feature = UseCounter::NumberOfFeatures;
+ switch (current->pseudoType()) {
+ case CSSSelector::PseudoUnresolved:
+ feature = UseCounter::CSSSelectorPseudoUnresolved;
+ break;
+ case CSSSelector::PseudoShadow:
+ feature = UseCounter::CSSSelectorPseudoShadow;
+ break;
+ case CSSSelector::PseudoContent:
+ feature = UseCounter::CSSSelectorPseudoContent;
+ break;
+ case CSSSelector::PseudoHost:
+ feature = UseCounter::CSSSelectorPseudoHost;
+ break;
+ case CSSSelector::PseudoHostContext:
+ feature = UseCounter::CSSSelectorPseudoHostContext;
+ break;
+ default:
+ break;
+ }
+ if (feature != UseCounter::NumberOfFeatures)
+ context.useCounter()->count(feature);
+ if (current->relation() == CSSSelector::ShadowDeep)
+ context.useCounter()->count(UseCounter::CSSDeepCombinator);
+ if (current->selectorList())
+ recordSelectorStats(context, *current->selectorList());
+ }
+ }
+}
+
+StyleRuleBase* BisonCSSParser::createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors)
+{
+ StyleRule* result = 0;
+ if (selectors) {
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+ RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create();
+ rule->parserAdoptSelectorVector(*selectors);
+ rule->setProperties(createStylePropertySet());
+ result = rule.get();
+ m_parsedRules.append(rule.release());
+ recordSelectorStats(m_context, result->selectorList());
+ }
+ clearProperties();
+ return result;
+}
+
+StyleRuleBase* BisonCSSParser::createFontFaceRule()
+{
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+ for (unsigned i = 0; i < m_parsedProperties.size(); ++i) {
+ CSSProperty& property = m_parsedProperties[i];
+ if (property.id() == CSSPropertyFontVariant && property.value()->isPrimitiveValue())
+ property.wrapValueInCommaSeparatedList();
+ else if (property.id() == CSSPropertyFontFamily && (!property.value()->isValueList() || toCSSValueList(property.value())->length() != 1)) {
+ // Unlike font-family property, font-family descriptor in @font-face rule
+ // has to be a value list with exactly one family name. It cannot have a
+ // have 'initial' value and cannot 'inherit' from parent.
+ // See http://dev.w3.org/csswg/css3-fonts/#font-family-desc
+ clearProperties();
+ return 0;
+ }
+ }
+ RefPtrWillBeRawPtr<StyleRuleFontFace> rule = StyleRuleFontFace::create();
+ rule->setProperties(createStylePropertySet());
+ clearProperties();
+ StyleRuleFontFace* result = rule.get();
+ m_parsedRules.append(rule.release());
+ if (m_styleSheet)
+ m_styleSheet->setHasFontFaceRule(true);
+ return result;
+}
+
+void BisonCSSParser::addNamespace(const AtomicString& prefix, const AtomicString& uri)
+{
+ if (!m_styleSheet || !m_allowNamespaceDeclarations)
+ return;
+ m_allowImportRules = false;
+ m_styleSheet->parserAddNamespace(prefix, uri);
+ if (prefix.isEmpty() && !uri.isNull())
+ m_defaultNamespace = uri;
+}
+
+QualifiedName BisonCSSParser::determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName)
+{
+ if (!m_styleSheet)
+ return QualifiedName(prefix, localName, m_defaultNamespace);
+ return QualifiedName(prefix, localName, m_styleSheet->determineNamespace(prefix));
+}
+
+CSSParserSelector* BisonCSSParser::rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector* specifiers)
+{
+ if (m_defaultNamespace != starAtom || specifiers->crossesTreeScopes())
+ return rewriteSpecifiersWithElementName(nullAtom, starAtom, specifiers, /*tagIsForNamespaceRule*/true);
+ return specifiers;
+}
+
+CSSParserSelector* BisonCSSParser::rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule)
+{
+ AtomicString determinedNamespace = namespacePrefix != nullAtom && m_styleSheet ? m_styleSheet->determineNamespace(namespacePrefix) : m_defaultNamespace;
+ QualifiedName tag(namespacePrefix, elementName, determinedNamespace);
+
+ if (specifiers->crossesTreeScopes())
+ return rewriteSpecifiersWithElementNameForCustomPseudoElement(tag, elementName, specifiers, tagIsForNamespaceRule);
+
+ if (specifiers->isContentPseudoElement())
+ return rewriteSpecifiersWithElementNameForContentPseudoElement(tag, elementName, specifiers, tagIsForNamespaceRule);
+
+ // *:host never matches, so we can't discard the * otherwise we can't tell the
+ // difference between *:host and just :host.
+ if (tag == anyQName() && !specifiers->hasHostPseudoSelector())
+ return specifiers;
+ if (specifiers->pseudoType() != CSSSelector::PseudoCue)
+ specifiers->prependTagSelector(tag, tagIsForNamespaceRule);
+ return specifiers;
+}
+
+CSSParserSelector* BisonCSSParser::rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule)
+{
+ if (m_context.useCounter() && specifiers->pseudoType() == CSSSelector::PseudoUserAgentCustomElement)
+ m_context.useCounter()->count(UseCounter::CSSPseudoElementUserAgentCustomPseudo);
+
+ CSSParserSelector* lastShadowPseudo = specifiers;
+ CSSParserSelector* history = specifiers;
+ while (history->tagHistory()) {
+ history = history->tagHistory();
+ if (history->crossesTreeScopes() || history->hasShadowPseudo())
+ lastShadowPseudo = history;
+ }
+
+ if (lastShadowPseudo->tagHistory()) {
+ if (tag != anyQName())
+ lastShadowPseudo->tagHistory()->prependTagSelector(tag, tagIsForNamespaceRule);
+ return specifiers;
+ }
+
+ // For shadow-ID pseudo-elements to be correctly matched, the ShadowPseudo combinator has to be used.
+ // We therefore create a new Selector with that combinator here in any case, even if matching any (host) element in any namespace (i.e. '*').
+ OwnPtr<CSSParserSelector> elementNameSelector = adoptPtr(new CSSParserSelector(tag));
+ lastShadowPseudo->setTagHistory(elementNameSelector.release());
+ lastShadowPseudo->setRelation(CSSSelector::ShadowPseudo);
+ return specifiers;
+}
+
+CSSParserSelector* BisonCSSParser::rewriteSpecifiersWithElementNameForContentPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule)
+{
+ CSSParserSelector* last = specifiers;
+ CSSParserSelector* history = specifiers;
+ while (history->tagHistory()) {
+ history = history->tagHistory();
+ if (history->isContentPseudoElement() || history->relationIsAffectedByPseudoContent())
+ last = history;
+ }
+
+ if (last->tagHistory()) {
+ if (tag != anyQName())
+ last->tagHistory()->prependTagSelector(tag, tagIsForNamespaceRule);
+ return specifiers;
+ }
+
+ // For shadow-ID pseudo-elements to be correctly matched, the ShadowPseudo combinator has to be used.
+ // We therefore create a new Selector with that combinator here in any case, even if matching any (host) element in any namespace (i.e. '*').
+ OwnPtr<CSSParserSelector> elementNameSelector = adoptPtr(new CSSParserSelector(tag));
+ last->setTagHistory(elementNameSelector.release());
+ last->setRelation(CSSSelector::SubSelector);
+ return specifiers;
+}
+
+CSSParserSelector* BisonCSSParser::rewriteSpecifiers(CSSParserSelector* specifiers, CSSParserSelector* newSpecifier)
+{
+ if (newSpecifier->crossesTreeScopes()) {
+ // Unknown pseudo element always goes at the top of selector chain.
+ newSpecifier->appendTagHistory(CSSSelector::ShadowPseudo, sinkFloatingSelector(specifiers));
+ return newSpecifier;
+ }
+ if (newSpecifier->isContentPseudoElement()) {
+ newSpecifier->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(specifiers));
+ return newSpecifier;
+ }
+ if (specifiers->crossesTreeScopes()) {
+ // Specifiers for unknown pseudo element go right behind it in the chain.
+ specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::ShadowPseudo);
+ return specifiers;
+ }
+ if (specifiers->isContentPseudoElement()) {
+ specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::SubSelector);
+ return specifiers;
+ }
+ specifiers->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier));
+ return specifiers;
+}
+
+StyleRuleBase* BisonCSSParser::createPageRule(PassOwnPtr<CSSParserSelector> pageSelector)
+{
+ // FIXME: Margin at-rules are ignored.
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+ StyleRulePage* pageRule = 0;
+ if (pageSelector) {
+ RefPtrWillBeRawPtr<StyleRulePage> rule = StyleRulePage::create();
+ Vector<OwnPtr<CSSParserSelector> > selectorVector;
+ selectorVector.append(pageSelector);
+ rule->parserAdoptSelectorVector(selectorVector);
+ rule->setProperties(createStylePropertySet());
+ pageRule = rule.get();
+ m_parsedRules.append(rule.release());
+ }
+ clearProperties();
+ return pageRule;
+}
+
+StyleRuleBase* BisonCSSParser::createMarginAtRule(CSSSelector::MarginBoxType /* marginBox */)
+{
+ // FIXME: Implement margin at-rule here, using:
+ // - marginBox: margin box
+ // - m_parsedProperties: properties at [m_numParsedPropertiesBeforeMarginBox, m_parsedProperties.size()] are for this at-rule.
+ // Don't forget to also update the action for page symbol in CSSGrammar.y such that margin at-rule data is cleared if page_selector is invalid.
+
+ endDeclarationsForMarginBox();
+ return 0; // until this method is implemented.
+}
+
+void BisonCSSParser::startDeclarationsForMarginBox()
+{
+ m_numParsedPropertiesBeforeMarginBox = m_parsedProperties.size();
+}
+
+void BisonCSSParser::endDeclarationsForMarginBox()
+{
+ rollbackLastProperties(m_parsedProperties.size() - m_numParsedPropertiesBeforeMarginBox);
+ m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
+}
+
+StyleKeyframe* BisonCSSParser::createKeyframe(CSSParserValueList* keys)
+{
+ OwnPtr<Vector<double> > keyVector = StyleKeyframe::createKeyList(keys);
+ if (keyVector->isEmpty())
+ return 0;
+
+ RefPtrWillBeRawPtr<StyleKeyframe> keyframe = StyleKeyframe::create();
+ keyframe->setKeys(keyVector.release());
+ keyframe->setProperties(createStylePropertySet());
+
+ clearProperties();
+
+ StyleKeyframe* keyframePtr = keyframe.get();
+ m_parsedKeyframes.append(keyframe.release());
+ return keyframePtr;
+}
+
+void BisonCSSParser::invalidBlockHit()
+{
+ if (m_styleSheet && !m_hadSyntacticallyValidCSSRule)
+ m_styleSheet->setHasSyntacticallyValidCSSHeader(false);
+}
+
+void BisonCSSParser::startRule()
+{
+ if (!m_observer)
+ return;
+
+ ASSERT(m_ruleHasHeader);
+ m_ruleHasHeader = false;
+}
+
+void BisonCSSParser::endRule(bool valid)
+{
+ if (!m_observer)
+ return;
+
+ if (m_ruleHasHeader)
+ m_observer->endRuleBody(m_tokenizer.safeUserStringTokenOffset(), !valid);
+ m_ruleHasHeader = true;
+}
+
+void BisonCSSParser::startRuleHeader(CSSRuleSourceData::Type ruleType)
+{
+ resumeErrorLogging();
+ m_ruleHeaderType = ruleType;
+ m_ruleHeaderStartOffset = m_tokenizer.safeUserStringTokenOffset();
+ m_ruleHeaderStartLineNumber = m_tokenizer.m_tokenStartLineNumber;
+ if (m_observer) {
+ ASSERT(!m_ruleHasHeader);
+ m_observer->startRuleHeader(ruleType, m_ruleHeaderStartOffset);
+ m_ruleHasHeader = true;
+ }
+}
+
+void BisonCSSParser::endRuleHeader()
+{
+ ASSERT(m_ruleHeaderType != CSSRuleSourceData::UNKNOWN_RULE);
+ m_ruleHeaderType = CSSRuleSourceData::UNKNOWN_RULE;
+ if (m_observer) {
+ ASSERT(m_ruleHasHeader);
+ m_observer->endRuleHeader(m_tokenizer.safeUserStringTokenOffset());
+ }
+}
+
+void BisonCSSParser::startSelector()
+{
+ if (m_observer)
+ m_observer->startSelector(m_tokenizer.safeUserStringTokenOffset());
+}
+
+void BisonCSSParser::endSelector()
+{
+ if (m_observer)
+ m_observer->endSelector(m_tokenizer.safeUserStringTokenOffset());
+}
+
+void BisonCSSParser::startRuleBody()
+{
+ if (m_observer)
+ m_observer->startRuleBody(m_tokenizer.safeUserStringTokenOffset());
+}
+
+void BisonCSSParser::startProperty()
+{
+ resumeErrorLogging();
+ if (m_observer)
+ m_observer->startProperty(m_tokenizer.safeUserStringTokenOffset());
+}
+
+void BisonCSSParser::endProperty(bool isImportantFound, bool isPropertyParsed, CSSParserError errorType)
+{
+ m_id = CSSPropertyInvalid;
+ if (m_observer)
+ m_observer->endProperty(isImportantFound, isPropertyParsed, m_tokenizer.safeUserStringTokenOffset(), errorType);
+}
+
+void BisonCSSParser::startEndUnknownRule()
+{
+ if (m_observer)
+ m_observer->startEndUnknownRule();
+}
+
+StyleRuleBase* BisonCSSParser::createViewportRule()
+{
+ // Allow @viewport rules from UA stylesheets even if the feature is disabled.
+ if (!RuntimeEnabledFeatures::cssViewportEnabled() && !isUASheetBehavior(m_context.mode()))
+ return 0;
+
+ m_allowImportRules = m_allowNamespaceDeclarations = false;
+
+ RefPtrWillBeRawPtr<StyleRuleViewport> rule = StyleRuleViewport::create();
+
+ rule->setProperties(createStylePropertySet());
+ clearProperties();
+
+ StyleRuleViewport* result = rule.get();
+ m_parsedRules.append(rule.release());
+
+ return result;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParser.h b/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParser.h
new file mode 100644
index 00000000000..e4447416394
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParser.h
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 - 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef BisonCSSParser_h
+#define BisonCSSParser_h
+
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/css/CSSCalculationValue.h"
+#include "core/css/CSSFilterValue.h"
+#include "core/css/CSSGradientValue.h"
+#include "core/css/CSSParserMode.h"
+#include "core/css/CSSParserValues.h"
+#include "core/css/CSSProperty.h"
+#include "core/css/CSSPropertySourceData.h"
+#include "core/css/CSSSelector.h"
+#include "core/css/CSSTokenizer.h"
+#include "core/css/MediaQuery.h"
+#include "core/css/StylePropertySet.h"
+#include "core/css/parser/CSSParserObserver.h"
+#include "core/css/parser/CSSPropertyParser.h"
+#include "platform/graphics/Color.h"
+#include "wtf/HashSet.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/AtomicString.h"
+#include "wtf/text/TextPosition.h"
+
+namespace WebCore {
+
+class AnimationParseContext;
+class CSSArrayFunctionValue;
+class CSSBorderImageSliceValue;
+class CSSPrimitiveValue;
+class CSSSelectorList;
+class CSSValue;
+class CSSValueList;
+class CSSBasicShape;
+class CSSBasicShapeInset;
+class Document;
+class Element;
+class ImmutableStylePropertySet;
+class MediaQueryExp;
+class MediaQuerySet;
+class MutableStylePropertySet;
+class StyleKeyframe;
+class StylePropertyShorthand;
+class StyleRuleBase;
+class StyleRuleKeyframes;
+class StyleKeyframe;
+class StyleSheetContents;
+class UseCounter;
+
+// FIXME: This class is shared with CSSTokenizer so should we rename it to CSSSourceLocation?
+struct CSSParserLocation {
+ unsigned offset;
+ unsigned lineNumber;
+ CSSParserString token;
+};
+
+class BisonCSSParser {
+ STACK_ALLOCATED();
+ friend inline int cssyylex(void*, BisonCSSParser*);
+public:
+ explicit BisonCSSParser(const CSSParserContext&);
+ ~BisonCSSParser();
+
+ void rollbackLastProperties(int num);
+ void setCurrentProperty(CSSPropertyID);
+
+ void parseSheet(StyleSheetContents*, const String&, const TextPosition& startPosition = TextPosition::minimumPosition(), CSSParserObserver* = 0, bool = false);
+ PassRefPtrWillBeRawPtr<StyleRuleBase> parseRule(StyleSheetContents*, const String&);
+ PassRefPtrWillBeRawPtr<StyleKeyframe> parseKeyframeRule(StyleSheetContents*, const String&);
+ bool parseSupportsCondition(const String&);
+ static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetContents*);
+ static bool parseColor(RGBA32& color, const String&, bool strict = false);
+ static bool parseSystemColor(RGBA32& color, const String&);
+ static PassRefPtrWillBeRawPtr<CSSValueList> parseFontFaceValue(const AtomicString&);
+ static PassRefPtrWillBeRawPtr<CSSValue> parseAnimationTimingFunctionValue(const String&);
+ bool parseDeclaration(MutableStylePropertySet*, const String&, CSSParserObserver*, StyleSheetContents* contextStyleSheet);
+ static PassRefPtr<ImmutableStylePropertySet> parseInlineStyleDeclaration(const String&, Element*);
+ PassRefPtrWillBeRawPtr<MediaQuerySet> parseMediaQueryList(const String&);
+ PassOwnPtr<Vector<double> > parseKeyframeKeyList(const String&);
+
+ static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, const Document&);
+
+ bool parseValue(CSSPropertyID, bool important);
+ void parseSelector(const String&, CSSSelectorList&);
+
+ CSSParserSelector* createFloatingSelector();
+ CSSParserSelector* createFloatingSelectorWithTagName(const QualifiedName&);
+ PassOwnPtr<CSSParserSelector> sinkFloatingSelector(CSSParserSelector*);
+
+ Vector<OwnPtr<CSSParserSelector> >* createFloatingSelectorVector();
+ PassOwnPtr<Vector<OwnPtr<CSSParserSelector> > > sinkFloatingSelectorVector(Vector<OwnPtr<CSSParserSelector> >*);
+
+ CSSParserValueList* createFloatingValueList();
+ PassOwnPtr<CSSParserValueList> sinkFloatingValueList(CSSParserValueList*);
+
+ CSSParserFunction* createFloatingFunction();
+ CSSParserFunction* createFloatingFunction(const CSSParserString& name, PassOwnPtr<CSSParserValueList> args);
+ PassOwnPtr<CSSParserFunction> sinkFloatingFunction(CSSParserFunction*);
+
+ CSSParserValue& sinkFloatingValue(CSSParserValue&);
+
+ MediaQuerySet* createMediaQuerySet();
+ StyleRuleBase* createImportRule(const CSSParserString&, MediaQuerySet*);
+ StyleKeyframe* createKeyframe(CSSParserValueList*);
+ StyleRuleKeyframes* createKeyframesRule(const String&, PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > >, bool isPrefixed);
+
+ typedef WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > RuleList;
+ StyleRuleBase* createMediaRule(MediaQuerySet*, RuleList*);
+ RuleList* createRuleList();
+ RuleList* appendRule(RuleList*, StyleRuleBase*);
+ StyleRuleBase* createStyleRule(Vector<OwnPtr<CSSParserSelector> >* selectors);
+ StyleRuleBase* createFontFaceRule();
+ StyleRuleBase* createPageRule(PassOwnPtr<CSSParserSelector> pageSelector);
+ StyleRuleBase* createMarginAtRule(CSSSelector::MarginBoxType);
+ StyleRuleBase* createSupportsRule(bool conditionIsSupported, RuleList*);
+ void markSupportsRuleHeaderStart();
+ void markSupportsRuleHeaderEnd();
+ PassRefPtrWillBeRawPtr<CSSRuleSourceData> popSupportsRuleData();
+ StyleRuleBase* createHostRule(RuleList* rules);
+
+ void startDeclarationsForMarginBox();
+ void endDeclarationsForMarginBox();
+
+ MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
+ PassOwnPtrWillBeRawPtr<MediaQueryExp> sinkFloatingMediaQueryExp(MediaQueryExp*);
+ WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* createFloatingMediaQueryExpList();
+ PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > sinkFloatingMediaQueryExpList(WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >*);
+ MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const AtomicString&, PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > >);
+ MediaQuery* createFloatingMediaQuery(PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > >);
+ MediaQuery* createFloatingNotAllQuery();
+ PassOwnPtrWillBeRawPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
+
+ WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >* createFloatingKeyframeVector();
+ PassOwnPtrWillBeRawPtr<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > sinkFloatingKeyframeVector(WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> >*);
+
+ void addNamespace(const AtomicString& prefix, const AtomicString& uri);
+ QualifiedName determineNameInNamespace(const AtomicString& prefix, const AtomicString& localName);
+
+ CSSParserSelector* rewriteSpecifiersWithElementName(const AtomicString& namespacePrefix, const AtomicString& elementName, CSSParserSelector*, bool isNamespacePlaceholder = false);
+ CSSParserSelector* rewriteSpecifiersWithElementNameForCustomPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule);
+ CSSParserSelector* rewriteSpecifiersWithElementNameForContentPseudoElement(const QualifiedName& tag, const AtomicString& elementName, CSSParserSelector* specifiers, bool tagIsForNamespaceRule);
+ CSSParserSelector* rewriteSpecifiersWithNamespaceIfNeeded(CSSParserSelector*);
+ CSSParserSelector* rewriteSpecifiers(CSSParserSelector*, CSSParserSelector*);
+ CSSParserSelector* rewriteSpecifiersForShadowDistributed(CSSParserSelector* specifiers, CSSParserSelector* distributedPseudoElementSelector);
+
+ void invalidBlockHit();
+
+ Vector<OwnPtr<CSSParserSelector> >* reusableSelectorVector() { return &m_reusableSelectorVector; }
+
+ void clearProperties();
+
+ PassRefPtr<ImmutableStylePropertySet> createStylePropertySet();
+
+ CSSParserContext m_context;
+
+ bool m_important;
+ CSSPropertyID m_id;
+ RawPtrWillBeMember<StyleSheetContents> m_styleSheet;
+ RefPtrWillBeMember<StyleRuleBase> m_rule;
+ RefPtrWillBeMember<StyleKeyframe> m_keyframe;
+ RefPtrWillBeMember<MediaQuerySet> m_mediaList;
+ OwnPtr<CSSParserValueList> m_valueList;
+ bool m_supportsCondition;
+
+ WillBeHeapVector<CSSProperty, 256> m_parsedProperties;
+ CSSSelectorList* m_selectorListForParseSelector;
+
+ unsigned m_numParsedPropertiesBeforeMarginBox;
+
+ bool m_hadSyntacticallyValidCSSRule;
+ bool m_logErrors;
+ bool m_ignoreErrors;
+
+ AtomicString m_defaultNamespace;
+
+ // tokenizer methods and data
+ CSSParserObserver* m_observer;
+
+ // Local functions which just call into CSSParserObserver if non-null.
+ void startRule();
+ void endRule(bool valid);
+ void startRuleHeader(CSSRuleSourceData::Type);
+ void endRuleHeader();
+ void startSelector();
+ void endSelector();
+ void startRuleBody();
+ void startProperty();
+ void endProperty(bool isImportantFound, bool isPropertyParsed, CSSParserError = NoCSSError);
+ void startEndUnknownRule();
+
+ void endInvalidRuleHeader();
+ void reportError(const CSSParserLocation&, CSSParserError = GeneralCSSError);
+ void resumeErrorLogging() { m_ignoreErrors = false; }
+ void setLocationLabel(const CSSParserLocation& location) { m_locationLabel = location; }
+ const CSSParserLocation& lastLocationLabel() const { return m_locationLabel; }
+
+ void tokenToLowerCase(CSSParserString& token);
+
+ void markViewportRuleBodyStart() { m_inViewport = true; }
+ void markViewportRuleBodyEnd() { m_inViewport = false; }
+ StyleRuleBase* createViewportRule();
+
+ CSSParserLocation currentLocation() { return m_tokenizer.currentLocation(); }
+
+private:
+ class StyleDeclarationScope {
+ STACK_ALLOCATED();
+ WTF_MAKE_NONCOPYABLE(StyleDeclarationScope);
+ public:
+ StyleDeclarationScope(BisonCSSParser* parser, const StylePropertySet* declaration)
+ : m_parser(parser)
+ , m_mode(declaration->cssParserMode())
+ {
+ if (isCSSViewportParsingEnabledForMode(m_mode)) {
+ ASSERT(!m_parser->inViewport());
+ m_parser->markViewportRuleBodyStart();
+ }
+ }
+
+ ~StyleDeclarationScope()
+ {
+ if (isCSSViewportParsingEnabledForMode(m_mode))
+ m_parser->markViewportRuleBodyEnd();
+ }
+
+ private:
+ BisonCSSParser* m_parser;
+ CSSParserMode m_mode;
+ };
+
+ inline void ensureLineEndings();
+
+ void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
+
+ bool inViewport() const { return m_inViewport; }
+
+ void recheckAtKeyword(const UChar* str, int len);
+
+ template<unsigned prefixLength, unsigned suffixLength>
+ inline void setupParser(const char (&prefix)[prefixLength], const String& string, const char (&suffix)[suffixLength])
+ {
+ setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
+ }
+ void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
+
+ bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, StyleSheetContents* contextStyleSheet);
+ PassRefPtr<ImmutableStylePropertySet> parseDeclaration(const String&, StyleSheetContents* contextStyleSheet);
+
+ bool parseColor(const String&);
+
+ const String* m_source;
+ TextPosition m_startPosition;
+ CSSRuleSourceData::Type m_ruleHeaderType;
+ unsigned m_ruleHeaderStartOffset;
+ int m_ruleHeaderStartLineNumber;
+ OwnPtr<Vector<unsigned> > m_lineEndings;
+
+ bool m_ruleHasHeader;
+
+ bool m_allowImportRules;
+ bool m_allowNamespaceDeclarations;
+
+ bool m_inViewport;
+
+ CSSParserLocation m_locationLabel;
+
+ WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_parsedRules;
+ WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > m_parsedKeyframes;
+ WillBeHeapVector<RefPtrWillBeMember<MediaQuerySet> > m_parsedMediaQuerySets;
+ WillBeHeapVector<OwnPtrWillBeMember<RuleList> > m_parsedRuleLists;
+ Vector<CSSParserSelector*> m_floatingSelectors;
+ Vector<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors;
+ Vector<CSSParserValueList*> m_floatingValueLists;
+ Vector<CSSParserFunction*> m_floatingFunctions;
+
+ OwnPtrWillBeMember<MediaQuery> m_floatingMediaQuery;
+ OwnPtrWillBeMember<MediaQueryExp> m_floatingMediaQueryExp;
+ OwnPtrWillBeMember<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > m_floatingMediaQueryExpList;
+
+ OwnPtrWillBeMember<WillBeHeapVector<RefPtrWillBeMember<StyleKeyframe> > > m_floatingKeyframeVector;
+
+ Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
+
+ OwnPtrWillBeMember<RuleSourceDataList> m_supportsRuleDataStack;
+
+ bool isLoggingErrors();
+ void logError(const String& message, const CSSParserLocation&);
+
+ CSSTokenizer m_tokenizer;
+
+ friend class TransformOperationInfo;
+ friend class FilterOperationInfo;
+};
+
+inline int cssyylex(void* yylval, BisonCSSParser* parser)
+{
+ return parser->m_tokenizer.lex(yylval);
+}
+
+bool isValidNthToken(const CSSParserString&);
+
+} // namespace WebCore
+
+#endif // BisonCSSParser_h
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParserTest.cpp b/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParserTest.cpp
new file mode 100644
index 00000000000..f2e2f36e11f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/BisonCSSParserTest.cpp
@@ -0,0 +1,67 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/BisonCSSParser.h"
+
+#include "core/css/CSSTimingFunctionValue.h"
+#include "platform/animation/TimingFunction.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+TEST(BisonCSSParserTest, ParseAnimationTimingFunctionValue)
+{
+ RefPtrWillBeRawPtr<CSSValue> timingFunctionValue;
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("ease");
+ EXPECT_EQ(CSSValueEase, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("linear");
+ EXPECT_EQ(CSSValueLinear, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("ease-in");
+ EXPECT_EQ(CSSValueEaseIn, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("ease-out");
+ EXPECT_EQ(CSSValueEaseOut, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("ease-in-out");
+ EXPECT_EQ(CSSValueEaseInOut, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("step-start");
+ EXPECT_EQ(CSSValueStepStart, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("step-middle");
+ EXPECT_EQ(CSSValueStepMiddle, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("step-end");
+ EXPECT_EQ(CSSValueStepEnd, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3, start)");
+ EXPECT_TRUE(CSSStepsTimingFunctionValue::create(3, StepsTimingFunction::StepAtStart)->equals(toCSSStepsTimingFunctionValue(*timingFunctionValue.get())));
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3, middle)");
+ EXPECT_TRUE(CSSStepsTimingFunctionValue::create(3, StepsTimingFunction::StepAtMiddle)->equals(toCSSStepsTimingFunctionValue(*timingFunctionValue.get())));
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3, end)");
+ EXPECT_TRUE(CSSStepsTimingFunctionValue::create(3, StepsTimingFunction::StepAtEnd)->equals(toCSSStepsTimingFunctionValue(*timingFunctionValue.get())));
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3, nowhere)");
+ EXPECT_EQ(0, timingFunctionValue.get());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(-3, end)");
+ EXPECT_EQ(0, timingFunctionValue.get());
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3)");
+ EXPECT_TRUE(CSSStepsTimingFunctionValue::create(3, StepsTimingFunction::StepAtEnd)->equals(toCSSStepsTimingFunctionValue(*timingFunctionValue.get())));
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("cubic-bezier(0.1, 5, 0.23, 0)");
+ EXPECT_TRUE(CSSCubicBezierTimingFunctionValue::create(0.1, 5, 0.23, 0)->equals(toCSSCubicBezierTimingFunctionValue(*timingFunctionValue.get())));
+
+ timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("cubic-bezier(0.1, 0, 4, 0.4)");
+ EXPECT_EQ(0, timingFunctionValue.get());
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/CSSParserIdioms.h b/chromium/third_party/WebKit/Source/core/css/parser/CSSParserIdioms.h
new file mode 100644
index 00000000000..4217d0a4368
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/CSSParserIdioms.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CSSParserIdioms_h
+#define CSSParserIdioms_h
+
+#include "wtf/unicode/Unicode.h"
+
+namespace WebCore {
+
+// Space characters as defined by the CSS specification.
+// http://www.w3.org/TR/css3-syntax/#whitespace
+inline bool isCSSSpace(UChar c)
+{
+ return c == ' ' || c == '\t' || c == '\n';
+}
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/CSSParserObserver.h b/chromium/third_party/WebKit/Source/core/css/parser/CSSParserObserver.h
new file mode 100644
index 00000000000..c6711a4eab2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/CSSParserObserver.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 - 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CSSParserObserver_h
+#define CSSParserObserver_h
+
+#include "core/css/CSSPropertySourceData.h"
+
+namespace WebCore {
+
+// FIXME: Although the parser produces these, they're all ignored!
+enum CSSParserError {
+ NoCSSError,
+ PropertyDeclarationCSSError,
+ InvalidPropertyValueCSSError,
+ InvalidPropertyCSSError,
+ InvalidSelectorCSSError,
+ InvalidSupportsConditionCSSError,
+ InvalidRuleCSSError,
+ InvalidMediaQueryCSSError,
+ InvalidKeyframeSelectorCSSError,
+ InvalidSelectorPseudoCSSError,
+ UnterminatedCommentCSSError,
+ GeneralCSSError
+};
+
+// FIXME: What are these actually used for? There is probably
+// a better way for the parser to communicate this information
+// to the Inspector.
+
+// This only implemented by StyleSheetHandler in InspectorStyleSheet.cpp.
+class CSSParserObserver {
+ STACK_ALLOCATED();
+public:
+ virtual void startRuleHeader(CSSRuleSourceData::Type, unsigned offset) = 0;
+ virtual void endRuleHeader(unsigned offset) = 0;
+ virtual void startSelector(unsigned offset) = 0;
+ virtual void endSelector(unsigned offset) = 0;
+ virtual void startRuleBody(unsigned offset) = 0;
+ virtual void endRuleBody(unsigned offset, bool error) = 0;
+ virtual void startEndUnknownRule() = 0;
+ virtual void startProperty(unsigned offset) = 0;
+ virtual void endProperty(bool isImportant, bool isParsed, unsigned offset, CSSParserError) = 0;
+ virtual void startComment(unsigned offset) = 0;
+ virtual void endComment(unsigned offset) = 0;
+};
+
+} // namespace WebCore
+
+#endif // CSSParserObserver_h
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/chromium/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
new file mode 100644
index 00000000000..5431a1a06c4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -0,0 +1,8435 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/css/parser/CSSPropertyParser.h"
+
+// FIXME: Way too many!
+#include "core/CSSValueKeywords.h"
+#include "core/StylePropertyShorthand.h"
+#include "core/css/CSSArrayFunctionValue.h"
+#include "core/css/CSSAspectRatioValue.h"
+#include "core/css/CSSBasicShapes.h"
+#include "core/css/CSSBorderImage.h"
+#include "core/css/CSSCanvasValue.h"
+#include "core/css/CSSCrossfadeValue.h"
+#include "core/css/CSSCursorImageValue.h"
+#include "core/css/CSSFontFaceSrcValue.h"
+#include "core/css/CSSFontFeatureValue.h"
+#include "core/css/CSSFunctionValue.h"
+#include "core/css/CSSGradientValue.h"
+#include "core/css/CSSGridLineNamesValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
+#include "core/css/CSSImageSetValue.h"
+#include "core/css/CSSImageValue.h"
+#include "core/css/CSSInheritedValue.h"
+#include "core/css/CSSInitialValue.h"
+#include "core/css/CSSKeyframeRule.h"
+#include "core/css/CSSKeyframesRule.h"
+#include "core/css/CSSLineBoxContainValue.h"
+#include "core/css/CSSParserValues.h"
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSPropertySourceData.h"
+#include "core/css/CSSReflectValue.h"
+#include "core/css/CSSSVGDocumentValue.h"
+#include "core/css/CSSSelector.h"
+#include "core/css/CSSShadowValue.h"
+#include "core/css/CSSTimingFunctionValue.h"
+#include "core/css/CSSTransformValue.h"
+#include "core/css/CSSUnicodeRangeValue.h"
+#include "core/css/CSSValueList.h"
+#include "core/css/CSSValuePool.h"
+#include "core/css/Counter.h"
+#include "core/css/HashTools.h"
+#include "core/css/Pair.h"
+#include "core/css/Rect.h"
+#include "core/css/RuntimeCSSEnabled.h"
+#include "core/css/parser/CSSParserIdioms.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/rendering/RenderTheme.h"
+#include "core/svg/SVGPaint.h"
+#include "platform/FloatConversion.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "wtf/BitArray.h"
+#include "wtf/HexNumber.h"
+#include "wtf/text/StringBuffer.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/StringImpl.h"
+#include "wtf/text/TextEncoding.h"
+#include <limits.h>
+
+namespace WebCore {
+
+static const double MAX_SCALE = 1000000;
+static const unsigned minRepetitions = 10000;
+
+template <unsigned N>
+static bool equal(const CSSParserString& a, const char (&b)[N])
+{
+ unsigned length = N - 1; // Ignore the trailing null character
+ if (a.length() != length)
+ return false;
+
+ return a.is8Bit() ? WTF::equal(a.characters8(), reinterpret_cast<const LChar*>(b), length) : WTF::equal(a.characters16(), reinterpret_cast<const LChar*>(b), length);
+}
+
+template <unsigned N>
+static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N])
+{
+ unsigned length = N - 1; // Ignore the trailing null character
+ if (a.length() != length)
+ return false;
+
+ return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF::equalIgnoringCase(b, a.characters16(), length);
+}
+
+template <unsigned N>
+static bool equalIgnoringCase(CSSParserValue* value, const char (&b)[N])
+{
+ ASSERT(value->unit == CSSPrimitiveValue::CSS_IDENT || value->unit == CSSPrimitiveValue::CSS_STRING);
+ return equalIgnoringCase(value->string, b);
+}
+
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveValuePair(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> first, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> second, Pair::IdenticalValuesPolicy identicalValuesPolicy = Pair::DropIdenticalValues)
+{
+ return cssValuePool().createValue(Pair::create(first, second, identicalValuesPolicy));
+}
+
+CSSPropertyParser::CSSPropertyParser(OwnPtr<CSSParserValueList>& valueList,
+ const CSSParserContext& context, bool inViewport, bool savedImportant,
+ WillBeHeapVector<CSSProperty, 256>& parsedProperties,
+ CSSRuleSourceData::Type ruleType)
+ : m_valueList(valueList)
+ , m_context(context)
+ , m_inViewport(inViewport)
+ , m_important(savedImportant) // See comment in header, should be removed.
+ , m_parsedProperties(parsedProperties)
+ , m_ruleType(ruleType)
+ , m_inParseShorthand(0)
+ , m_currentShorthand(CSSPropertyInvalid)
+ , m_implicitShorthand(false)
+{
+}
+
+CSSPropertyParser::~CSSPropertyParser()
+{
+}
+
+void CSSPropertyParser::addPropertyWithPrefixingVariant(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue> value, bool important, bool implicit)
+{
+ RefPtrWillBeRawPtr<CSSValue> val = value.get();
+ addProperty(propId, value, important, implicit);
+
+ CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(propId);
+ if (prefixingVariant == propId)
+ return;
+
+ if (m_currentShorthand) {
+ // We can't use ShorthandScope here as we can already be inside one (e.g we are parsing CSSTransition).
+ m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
+ addProperty(prefixingVariant, val.release(), important, implicit);
+ m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
+ } else {
+ addProperty(prefixingVariant, val.release(), important, implicit);
+ }
+}
+
+void CSSPropertyParser::addProperty(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue> value, bool important, bool implicit)
+{
+ // This property doesn't belong to a shorthand.
+ if (!m_currentShorthand) {
+ m_parsedProperties.append(CSSProperty(propId, value, important, false, CSSPropertyInvalid, m_implicitShorthand || implicit));
+ return;
+ }
+
+ Vector<StylePropertyShorthand, 4> shorthands;
+ getMatchingShorthandsForLonghand(propId, &shorthands);
+ // The longhand does not belong to multiple shorthands.
+ if (shorthands.size() == 1)
+ m_parsedProperties.append(CSSProperty(propId, value, important, true, CSSPropertyInvalid, m_implicitShorthand || implicit));
+ else
+ m_parsedProperties.append(CSSProperty(propId, value, important, true, indexOfShorthandForLonghand(m_currentShorthand, shorthands), m_implicitShorthand || implicit));
+}
+
+void CSSPropertyParser::rollbackLastProperties(int num)
+{
+ ASSERT(num >= 0);
+ ASSERT(m_parsedProperties.size() >= static_cast<unsigned>(num));
+ m_parsedProperties.shrink(m_parsedProperties.size() - num);
+}
+
+KURL CSSPropertyParser::completeURL(const String& url) const
+{
+ return m_context.completeURL(url);
+}
+
+bool CSSPropertyParser::validCalculationUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc)
+{
+ bool mustBeNonNegative = unitflags & FNonNeg;
+
+ if (!parseCalculation(value, mustBeNonNegative ? ValueRangeNonNegative : ValueRangeAll))
+ return false;
+
+ bool b = false;
+ switch (m_parsedCalculation->category()) {
+ case CalcLength:
+ b = (unitflags & FLength);
+ break;
+ case CalcPercent:
+ b = (unitflags & FPercent);
+ if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
+ b = false;
+ break;
+ case CalcNumber:
+ b = (unitflags & FNumber);
+ if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt())
+ b = true;
+ if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
+ b = false;
+ break;
+ case CalcPercentLength:
+ b = (unitflags & FPercent) && (unitflags & FLength);
+ break;
+ case CalcPercentNumber:
+ b = (unitflags & FPercent) && (unitflags & FNumber);
+ break;
+ case CalcOther:
+ break;
+ }
+ if (!b || releaseCalc == ReleaseParsedCalcValue)
+ m_parsedCalculation.release();
+ return b;
+}
+
+inline bool CSSPropertyParser::shouldAcceptUnitLessValues(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode)
+{
+ // Quirks mode and presentation attributes accept unit less values.
+ return (unitflags & (FLength | FAngle | FTime)) && (!value->fValue || isUnitLessLengthParsingEnabledForMode(cssParserMode));
+}
+
+bool CSSPropertyParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode, ReleaseParsedCalcValueCondition releaseCalc)
+{
+ if (isCalculation(value))
+ return validCalculationUnit(value, unitflags, releaseCalc);
+
+ bool b = false;
+ switch (value->unit) {
+ case CSSPrimitiveValue::CSS_NUMBER:
+ b = (unitflags & FNumber);
+ if (!b && shouldAcceptUnitLessValues(value, unitflags, cssParserMode)) {
+ value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX :
+ ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
+ b = true;
+ }
+ if (!b && (unitflags & FInteger) && value->isInt)
+ b = true;
+ if (!b && (unitflags & FPositiveInteger) && value->isInt && value->fValue > 0)
+ b = true;
+ break;
+ case CSSPrimitiveValue::CSS_PERCENTAGE:
+ b = (unitflags & FPercent);
+ break;
+ case CSSParserValue::Q_EMS:
+ case CSSPrimitiveValue::CSS_EMS:
+ case CSSPrimitiveValue::CSS_REMS:
+ case CSSPrimitiveValue::CSS_CHS:
+ case CSSPrimitiveValue::CSS_EXS:
+ case CSSPrimitiveValue::CSS_PX:
+ case CSSPrimitiveValue::CSS_CM:
+ case CSSPrimitiveValue::CSS_MM:
+ case CSSPrimitiveValue::CSS_IN:
+ case CSSPrimitiveValue::CSS_PT:
+ case CSSPrimitiveValue::CSS_PC:
+ case CSSPrimitiveValue::CSS_VW:
+ case CSSPrimitiveValue::CSS_VH:
+ case CSSPrimitiveValue::CSS_VMIN:
+ case CSSPrimitiveValue::CSS_VMAX:
+ b = (unitflags & FLength);
+ break;
+ case CSSPrimitiveValue::CSS_MS:
+ case CSSPrimitiveValue::CSS_S:
+ b = (unitflags & FTime);
+ break;
+ case CSSPrimitiveValue::CSS_DEG:
+ case CSSPrimitiveValue::CSS_RAD:
+ case CSSPrimitiveValue::CSS_GRAD:
+ case CSSPrimitiveValue::CSS_TURN:
+ b = (unitflags & FAngle);
+ break;
+ case CSSPrimitiveValue::CSS_DPPX:
+ case CSSPrimitiveValue::CSS_DPI:
+ case CSSPrimitiveValue::CSS_DPCM:
+ b = (unitflags & FResolution);
+ break;
+ case CSSPrimitiveValue::CSS_HZ:
+ case CSSPrimitiveValue::CSS_KHZ:
+ case CSSPrimitiveValue::CSS_DIMENSION:
+ default:
+ break;
+ }
+ if (b && unitflags & FNonNeg && value->fValue < 0)
+ b = false;
+ return b;
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::createPrimitiveNumericValue(CSSParserValue* value)
+{
+ if (m_parsedCalculation) {
+ ASSERT(isCalculation(value));
+ return CSSPrimitiveValue::create(m_parsedCalculation.release());
+ }
+
+ ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
+ || (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)
+ || (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM));
+ return cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitType>(value->unit));
+}
+
+inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::createPrimitiveStringValue(CSSParserValue* value)
+{
+ ASSERT(value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT);
+ return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING);
+}
+
+inline PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::createCSSImageValueWithReferrer(const String& rawValue, const KURL& url)
+{
+ RefPtrWillBeRawPtr<CSSValue> imageValue = CSSImageValue::create(rawValue, url);
+ toCSSImageValue(imageValue.get())->setReferrer(m_context.referrer());
+ return imageValue;
+}
+
+static inline bool isComma(CSSParserValue* value)
+{
+ return value && value->unit == CSSParserValue::Operator && value->iValue == ',';
+}
+
+static inline bool isForwardSlashOperator(CSSParserValue* value)
+{
+ ASSERT(value);
+ return value->unit == CSSParserValue::Operator && value->iValue == '/';
+}
+
+static bool isGeneratedImageValue(CSSParserValue* val)
+{
+ if (val->unit != CSSParserValue::Function)
+ return false;
+
+ return equalIgnoringCase(val->function->name, "-webkit-gradient(")
+ || equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")
+ || equalIgnoringCase(val->function->name, "linear-gradient(")
+ || equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")
+ || equalIgnoringCase(val->function->name, "repeating-linear-gradient(")
+ || equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")
+ || equalIgnoringCase(val->function->name, "radial-gradient(")
+ || equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")
+ || equalIgnoringCase(val->function->name, "repeating-radial-gradient(")
+ || equalIgnoringCase(val->function->name, "-webkit-canvas(")
+ || equalIgnoringCase(val->function->name, "-webkit-cross-fade(");
+}
+
+bool CSSPropertyParser::validWidthOrHeight(CSSParserValue* value)
+{
+ int id = value->id;
+ if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic || id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent || id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent)
+ return true;
+ return !id && validUnit(value, FLength | FPercent | FNonNeg);
+}
+
+inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseValidPrimitive(CSSValueID identifier, CSSParserValue* value)
+{
+ if (identifier)
+ return cssValuePool().createIdentifierValue(identifier);
+ if (value->unit == CSSPrimitiveValue::CSS_STRING)
+ return createPrimitiveStringValue(value);
+ if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ return createPrimitiveNumericValue(value);
+ if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
+ return createPrimitiveNumericValue(value);
+ if (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)
+ return createPrimitiveNumericValue(value);
+ if (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM)
+ return createPrimitiveNumericValue(value);
+ if (value->unit >= CSSParserValue::Q_EMS)
+ return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
+ if (isCalculation(value))
+ return CSSPrimitiveValue::create(m_parsedCalculation.release());
+
+ return nullptr;
+}
+
+void CSSPropertyParser::addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue> prpValue, bool important)
+{
+ const StylePropertyShorthand& shorthand = shorthandForProperty(propId);
+ unsigned shorthandLength = shorthand.length();
+ if (!shorthandLength) {
+ addPropertyWithPrefixingVariant(propId, prpValue, important);
+ return;
+ }
+
+ RefPtrWillBeRawPtr<CSSValue> value = prpValue;
+ ShorthandScope scope(this, propId);
+ const CSSPropertyID* longhands = shorthand.properties();
+ for (unsigned i = 0; i < shorthandLength; ++i)
+ addPropertyWithPrefixingVariant(longhands[i], value, important);
+}
+
+bool CSSPropertyParser::parseValue(CSSPropertyID propId, bool important)
+{
+ if (!isInternalPropertyAndValueParsingEnabledForMode(m_context.mode()) && isInternalProperty(propId))
+ return false;
+
+ // We don't count the UA style sheet in our statistics.
+ if (m_context.useCounter())
+ m_context.useCounter()->count(m_context, propId);
+
+ if (!m_valueList)
+ return false;
+
+ CSSParserValue* value = m_valueList->current();
+
+ if (!value)
+ return false;
+
+ if (inViewport()) {
+ // Allow @viewport rules from UA stylesheets even if the feature is disabled.
+ if (!RuntimeEnabledFeatures::cssViewportEnabled() && !isUASheetBehavior(m_context.mode()))
+ return false;
+
+ return parseViewportProperty(propId, important);
+ }
+
+ // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function.
+ // FIXME: This is to avoid having to pass parsedCalc to all validUnit callers.
+ ASSERT(!m_parsedCalculation);
+
+ CSSValueID id = value->id;
+
+ int num = inShorthand() ? 1 : m_valueList->size();
+
+ if (id == CSSValueInherit) {
+ if (num != 1)
+ return false;
+ addExpandedPropertyForValue(propId, cssValuePool().createInheritedValue(), important);
+ return true;
+ }
+ else if (id == CSSValueInitial) {
+ if (num != 1)
+ return false;
+ addExpandedPropertyForValue(propId, cssValuePool().createExplicitInitialValue(), important);
+ return true;
+ }
+
+ if (isKeywordPropertyID(propId)) {
+ if (!isValidKeywordPropertyAndValue(propId, id, m_context))
+ return false;
+ if (m_valueList->next() && !inShorthand())
+ return false;
+ addProperty(propId, cssValuePool().createIdentifierValue(id), important);
+ return true;
+ }
+
+ bool validPrimitive = false;
+ RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr;
+
+ switch (propId) {
+ case CSSPropertySize: // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
+ return parseSize(propId, important);
+
+ case CSSPropertyQuotes: // [<string> <string>]+ | none | inherit
+ if (id)
+ validPrimitive = true;
+ else
+ return parseQuotes(propId, important);
+ break;
+ case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | isolate | isolate-override | plaintext | inherit
+ if (id == CSSValueNormal
+ || id == CSSValueEmbed
+ || id == CSSValueBidiOverride
+ || id == CSSValueWebkitIsolate
+ || id == CSSValueWebkitIsolateOverride
+ || id == CSSValueWebkitPlaintext)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyContent: // [ <string> | <uri> | <counter> | attr(X) | open-quote |
+ // close-quote | no-open-quote | no-close-quote ]+ | inherit
+ return parseContent(propId, important);
+
+ case CSSPropertyClip: // <shape> | auto | inherit
+ if (id == CSSValueAuto)
+ validPrimitive = true;
+ else if (value->unit == CSSParserValue::Function)
+ return parseClipShape(propId, important);
+ break;
+
+ /* Start of supported CSS properties with validation. This is needed for parseShorthand to work
+ * correctly and allows optimization in WebCore::applyRule(..)
+ */
+ case CSSPropertyOverflow: {
+ ShorthandScope scope(this, propId);
+ if (num != 1 || !parseValue(CSSPropertyOverflowY, important))
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValue> overflowXValue = nullptr;
+
+ // FIXME: -webkit-paged-x or -webkit-paged-y only apply to overflow-y. If this value has been
+ // set using the shorthand, then for now overflow-x will default to auto, but once we implement
+ // pagination controls, it should default to hidden. If the overflow-y value is anything but
+ // paged-x or paged-y, then overflow-x and overflow-y should have the same value.
+ if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY)
+ overflowXValue = cssValuePool().createIdentifierValue(CSSValueAuto);
+ else
+ overflowXValue = m_parsedProperties.last().value();
+ addProperty(CSSPropertyOverflowX, overflowXValue.release(), important);
+ return true;
+ }
+
+ case CSSPropertyTextAlign:
+ // left | right | center | justify | -webkit-left | -webkit-right | -webkit-center | -webkit-match-parent
+ // | start | end | <string> | inherit | -webkit-auto (converted to start)
+ if ((id >= CSSValueWebkitAuto && id <= CSSValueWebkitMatchParent) || id == CSSValueStart || id == CSSValueEnd
+ || value->unit == CSSPrimitiveValue::CSS_STRING)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyFontWeight: { // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
+ if (m_valueList->size() != 1)
+ return false;
+ return parseFontWeight(important);
+ }
+ case CSSPropertyBorderSpacing: {
+ if (num == 1) {
+ ShorthandScope scope(this, CSSPropertyBorderSpacing);
+ if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important))
+ return false;
+ CSSValue* value = m_parsedProperties.last().value();
+ addProperty(CSSPropertyWebkitBorderVerticalSpacing, value, important);
+ return true;
+ }
+ else if (num == 2) {
+ ShorthandScope scope(this, CSSPropertyBorderSpacing);
+ if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important) || !parseValue(CSSPropertyWebkitBorderVerticalSpacing, important))
+ return false;
+ return true;
+ }
+ return false;
+ }
+ case CSSPropertyWebkitBorderHorizontalSpacing:
+ case CSSPropertyWebkitBorderVerticalSpacing:
+ validPrimitive = validUnit(value, FLength | FNonNeg);
+ break;
+ case CSSPropertyOutlineColor: // <color> | invert | inherit
+ // Outline color has "invert" as additional keyword.
+ // Also, we want to allow the special focus color even in HTML Standard parsing mode.
+ if (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor) {
+ validPrimitive = true;
+ break;
+ }
+ /* nobreak */
+ case CSSPropertyBackgroundColor: // <color> | inherit
+ case CSSPropertyBorderTopColor: // <color> | inherit
+ case CSSPropertyBorderRightColor:
+ case CSSPropertyBorderBottomColor:
+ case CSSPropertyBorderLeftColor:
+ case CSSPropertyWebkitBorderStartColor:
+ case CSSPropertyWebkitBorderEndColor:
+ case CSSPropertyWebkitBorderBeforeColor:
+ case CSSPropertyWebkitBorderAfterColor:
+ case CSSPropertyColor: // <color> | inherit
+ case CSSPropertyTextDecorationColor: // CSS3 text decoration colors
+ case CSSPropertyTextLineThroughColor:
+ case CSSPropertyTextUnderlineColor:
+ case CSSPropertyTextOverlineColor:
+ case CSSPropertyWebkitColumnRuleColor:
+ case CSSPropertyWebkitTextEmphasisColor:
+ case CSSPropertyWebkitTextFillColor:
+ case CSSPropertyWebkitTextStrokeColor:
+ if (propId == CSSPropertyTextDecorationColor
+ && !RuntimeEnabledFeatures::css3TextDecorationsEnabled())
+ return false;
+
+ if ((id >= CSSValueAqua && id <= CSSValueWebkitText) || id == CSSValueMenu) {
+ validPrimitive = isValueAllowedInMode(id, m_context.mode());
+ } else {
+ parsedValue = parseColor();
+ if (parsedValue)
+ m_valueList->next();
+ }
+ break;
+
+ case CSSPropertyCursor: {
+ // Grammar defined by CSS3 UI and modified by CSS4 images:
+ // [ [<image> [<x> <y>]?,]*
+ // [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
+ // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize |
+ // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help |
+ // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed | all-scroll |
+ // zoom-in | zoom-out | -webkit-grab | -webkit-grabbing | -webkit-zoom-in | -webkit-zoom-out ] ] | inherit
+ RefPtrWillBeRawPtr<CSSValueList> list = nullptr;
+ while (value) {
+ RefPtrWillBeRawPtr<CSSValue> image = nullptr;
+ if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ String uri = value->string;
+ if (!uri.isNull())
+ image = createCSSImageValueWithReferrer(uri, completeURL(uri));
+ } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) {
+ image = parseImageSet(m_valueList.get());
+ if (!image)
+ break;
+ } else
+ break;
+
+ Vector<int> coords;
+ value = m_valueList->next();
+ while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+ coords.append(int(value->fValue));
+ value = m_valueList->next();
+ }
+ bool hasHotSpot = false;
+ IntPoint hotSpot(-1, -1);
+ int nrcoords = coords.size();
+ if (nrcoords > 0 && nrcoords != 2)
+ return false;
+ if (nrcoords == 2) {
+ hasHotSpot = true;
+ hotSpot = IntPoint(coords[0], coords[1]);
+ }
+
+ if (!list)
+ list = CSSValueList::createCommaSeparated();
+
+ if (image)
+ list->append(CSSCursorImageValue::create(image, hasHotSpot, hotSpot));
+
+ if (!value || !(value->unit == CSSParserValue::Operator && value->iValue == ','))
+ return false;
+ value = m_valueList->next(); // comma
+ }
+ if (value && m_context.useCounter()) {
+ if (value->id == CSSValueWebkitZoomIn)
+ m_context.useCounter()->count(UseCounter::PrefixedCursorZoomIn);
+ else if (value->id == CSSValueWebkitZoomOut)
+ m_context.useCounter()->count(UseCounter::PrefixedCursorZoomOut);
+ }
+ if (list) {
+ if (!value)
+ return false;
+ if (inQuirksMode() && value->id == CSSValueHand) // MSIE 5 compatibility :/
+ list->append(cssValuePool().createIdentifierValue(CSSValuePointer));
+ else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitZoomOut) || value->id == CSSValueCopy || value->id == CSSValueNone)
+ list->append(cssValuePool().createIdentifierValue(value->id));
+ m_valueList->next();
+ parsedValue = list.release();
+ break;
+ } else if (value) {
+ id = value->id;
+ if (inQuirksMode() && value->id == CSSValueHand) { // MSIE 5 compatibility :/
+ id = CSSValuePointer;
+ validPrimitive = true;
+ } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitZoomOut) || value->id == CSSValueCopy || value->id == CSSValueNone)
+ validPrimitive = true;
+ } else {
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ break;
+ }
+
+ case CSSPropertyBackgroundBlendMode:
+ case CSSPropertyBackgroundAttachment:
+ case CSSPropertyBackgroundClip:
+ case CSSPropertyWebkitBackgroundClip:
+ case CSSPropertyWebkitBackgroundComposite:
+ case CSSPropertyBackgroundImage:
+ case CSSPropertyBackgroundOrigin:
+ case CSSPropertyMaskSourceType:
+ case CSSPropertyWebkitBackgroundOrigin:
+ case CSSPropertyBackgroundPosition:
+ case CSSPropertyBackgroundPositionX:
+ case CSSPropertyBackgroundPositionY:
+ case CSSPropertyBackgroundSize:
+ case CSSPropertyWebkitBackgroundSize:
+ case CSSPropertyBackgroundRepeat:
+ case CSSPropertyBackgroundRepeatX:
+ case CSSPropertyBackgroundRepeatY:
+ case CSSPropertyWebkitMaskClip:
+ case CSSPropertyWebkitMaskComposite:
+ case CSSPropertyWebkitMaskImage:
+ case CSSPropertyWebkitMaskOrigin:
+ case CSSPropertyWebkitMaskPosition:
+ case CSSPropertyWebkitMaskPositionX:
+ case CSSPropertyWebkitMaskPositionY:
+ case CSSPropertyWebkitMaskSize:
+ case CSSPropertyWebkitMaskRepeat:
+ case CSSPropertyWebkitMaskRepeatX:
+ case CSSPropertyWebkitMaskRepeatY:
+ {
+ RefPtrWillBeRawPtr<CSSValue> val1 = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> val2 = nullptr;
+ CSSPropertyID propId1, propId2;
+ bool result = false;
+ if (parseFillProperty(propId, propId1, propId2, val1, val2)) {
+ if (propId == CSSPropertyBackgroundPosition ||
+ propId == CSSPropertyBackgroundRepeat ||
+ propId == CSSPropertyWebkitMaskPosition ||
+ propId == CSSPropertyWebkitMaskRepeat) {
+ ShorthandScope scope(this, propId);
+ addProperty(propId1, val1.release(), important);
+ if (val2)
+ addProperty(propId2, val2.release(), important);
+ } else {
+ addProperty(propId1, val1.release(), important);
+ if (val2)
+ addProperty(propId2, val2.release(), important);
+ }
+ result = true;
+ }
+ m_implicitShorthand = false;
+ return result;
+ }
+ case CSSPropertyObjectPosition:
+ return RuntimeEnabledFeatures::objectFitPositionEnabled() && parseObjectPosition(important);
+ case CSSPropertyListStyleImage: // <uri> | none | inherit
+ case CSSPropertyBorderImageSource:
+ case CSSPropertyWebkitMaskBoxImageSource:
+ if (id == CSSValueNone) {
+ parsedValue = cssValuePool().createIdentifierValue(CSSValueNone);
+ m_valueList->next();
+ } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ parsedValue = createCSSImageValueWithReferrer(value->string, completeURL(value->string));
+ m_valueList->next();
+ } else if (isGeneratedImageValue(value)) {
+ if (parseGeneratedImage(m_valueList.get(), parsedValue))
+ m_valueList->next();
+ else
+ return false;
+ }
+ else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) {
+ parsedValue = parseImageSet(m_valueList.get());
+ if (!parsedValue)
+ return false;
+ m_valueList->next();
+ }
+ break;
+
+ case CSSPropertyWebkitTextStrokeWidth:
+ case CSSPropertyOutlineWidth: // <border-width> | inherit
+ case CSSPropertyBorderTopWidth: //// <border-width> | inherit
+ case CSSPropertyBorderRightWidth: // Which is defined as
+ case CSSPropertyBorderBottomWidth: // thin | medium | thick | <length>
+ case CSSPropertyBorderLeftWidth:
+ case CSSPropertyWebkitBorderStartWidth:
+ case CSSPropertyWebkitBorderEndWidth:
+ case CSSPropertyWebkitBorderBeforeWidth:
+ case CSSPropertyWebkitBorderAfterWidth:
+ case CSSPropertyWebkitColumnRuleWidth:
+ if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FLength | FNonNeg);
+ break;
+
+ case CSSPropertyLetterSpacing: // normal | <length> | inherit
+ case CSSPropertyWordSpacing: // normal | <length> | inherit
+ if (id == CSSValueNormal)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FLength);
+ break;
+
+ case CSSPropertyTextIndent:
+ parsedValue = parseTextIndent();
+ break;
+
+ case CSSPropertyPaddingTop: //// <padding-width> | inherit
+ case CSSPropertyPaddingRight: // Which is defined as
+ case CSSPropertyPaddingBottom: // <length> | <percentage>
+ case CSSPropertyPaddingLeft: ////
+ case CSSPropertyWebkitPaddingStart:
+ case CSSPropertyWebkitPaddingEnd:
+ case CSSPropertyWebkitPaddingBefore:
+ case CSSPropertyWebkitPaddingAfter:
+ validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+ break;
+
+ case CSSPropertyMaxWidth:
+ case CSSPropertyWebkitMaxLogicalWidth:
+ case CSSPropertyMaxHeight:
+ case CSSPropertyWebkitMaxLogicalHeight:
+ validPrimitive = (id == CSSValueNone || validWidthOrHeight(value));
+ break;
+
+ case CSSPropertyMinWidth:
+ case CSSPropertyWebkitMinLogicalWidth:
+ case CSSPropertyMinHeight:
+ case CSSPropertyWebkitMinLogicalHeight:
+ validPrimitive = validWidthOrHeight(value);
+ break;
+
+ case CSSPropertyWidth:
+ case CSSPropertyWebkitLogicalWidth:
+ case CSSPropertyHeight:
+ case CSSPropertyWebkitLogicalHeight:
+ validPrimitive = (id == CSSValueAuto || validWidthOrHeight(value));
+ break;
+
+ case CSSPropertyFontSize:
+ return parseFontSize(important);
+
+ case CSSPropertyFontVariant: // normal | small-caps | inherit
+ return parseFontVariant(important);
+
+ case CSSPropertyVerticalAlign:
+ // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
+ // <percentage> | <length> | inherit
+
+ if (id >= CSSValueBaseline && id <= CSSValueWebkitBaselineMiddle)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FLength | FPercent));
+ break;
+
+ case CSSPropertyBottom: // <length> | <percentage> | auto | inherit
+ case CSSPropertyLeft: // <length> | <percentage> | auto | inherit
+ case CSSPropertyRight: // <length> | <percentage> | auto | inherit
+ case CSSPropertyTop: // <length> | <percentage> | auto | inherit
+ case CSSPropertyMarginTop: //// <margin-width> | inherit
+ case CSSPropertyMarginRight: // Which is defined as
+ case CSSPropertyMarginBottom: // <length> | <percentage> | auto | inherit
+ case CSSPropertyMarginLeft: ////
+ case CSSPropertyWebkitMarginStart:
+ case CSSPropertyWebkitMarginEnd:
+ case CSSPropertyWebkitMarginBefore:
+ case CSSPropertyWebkitMarginAfter:
+ if (id == CSSValueAuto)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FLength | FPercent));
+ break;
+
+ case CSSPropertyOrphans: // <integer> | inherit | auto (We've added support for auto for backwards compatibility)
+ case CSSPropertyWidows: // <integer> | inherit | auto (Ditto)
+ if (id == CSSValueAuto)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FPositiveInteger, HTMLQuirksMode));
+ break;
+
+ case CSSPropertyZIndex: // auto | <integer> | inherit
+ if (id == CSSValueAuto)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FInteger, HTMLQuirksMode));
+ break;
+
+ case CSSPropertyLineHeight:
+ return parseLineHeight(important);
+ case CSSPropertyCounterIncrement: // [ <identifier> <integer>? ]+ | none | inherit
+ if (id != CSSValueNone)
+ return parseCounter(propId, 1, important);
+ validPrimitive = true;
+ break;
+ case CSSPropertyCounterReset: // [ <identifier> <integer>? ]+ | none | inherit
+ if (id != CSSValueNone)
+ return parseCounter(propId, 0, important);
+ validPrimitive = true;
+ break;
+ case CSSPropertyFontFamily:
+ // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit
+ {
+ parsedValue = parseFontFamily();
+ break;
+ }
+
+ case CSSPropertyTextDecoration:
+ // Fall through 'text-decoration-line' parsing if CSS 3 Text Decoration
+ // is disabled to match CSS 2.1 rules for parsing 'text-decoration'.
+ if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) {
+ // [ <text-decoration-line> || <text-decoration-style> || <text-decoration-color> ] | inherit
+ return parseShorthand(CSSPropertyTextDecoration, textDecorationShorthand(), important);
+ }
+ case CSSPropertyWebkitTextDecorationsInEffect:
+ case CSSPropertyTextDecorationLine:
+ // none | [ underline || overline || line-through || blink ] | inherit
+ return parseTextDecoration(propId, important);
+
+ case CSSPropertyTextDecorationStyle:
+ // solid | double | dotted | dashed | wavy
+ if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()
+ && (id == CSSValueSolid || id == CSSValueDouble || id == CSSValueDotted || id == CSSValueDashed || id == CSSValueWavy))
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyTextUnderlinePosition:
+ // auto | under | inherit
+ if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
+ return parseTextUnderlinePosition(important);
+ return false;
+
+ case CSSPropertyZoom: // normal | reset | document | <number> | <percentage> | inherit
+ if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode));
+ break;
+
+ case CSSPropertySrc: // Only used within @font-face and @-webkit-filter, so cannot use inherit | initial or be !important. This is a list of urls or local references.
+ return parseFontFaceSrc();
+
+ case CSSPropertyUnicodeRange:
+ return parseFontFaceUnicodeRange();
+
+ /* CSS3 properties */
+
+ case CSSPropertyBorderImage:
+ case CSSPropertyWebkitMaskBoxImage:
+ return parseBorderImageShorthand(propId, important);
+ case CSSPropertyWebkitBorderImage: {
+ if (RefPtrWillBeRawPtr<CSSValue> result = parseBorderImage(propId)) {
+ addProperty(propId, result, important);
+ return true;
+ }
+ return false;
+ }
+
+ case CSSPropertyBorderImageOutset:
+ case CSSPropertyWebkitMaskBoxImageOutset: {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = nullptr;
+ if (parseBorderImageOutset(result)) {
+ addProperty(propId, result, important);
+ return true;
+ }
+ break;
+ }
+ case CSSPropertyBorderImageRepeat:
+ case CSSPropertyWebkitMaskBoxImageRepeat: {
+ RefPtrWillBeRawPtr<CSSValue> result = nullptr;
+ if (parseBorderImageRepeat(result)) {
+ addProperty(propId, result, important);
+ return true;
+ }
+ break;
+ }
+ case CSSPropertyBorderImageSlice:
+ case CSSPropertyWebkitMaskBoxImageSlice: {
+ RefPtrWillBeRawPtr<CSSBorderImageSliceValue> result = nullptr;
+ if (parseBorderImageSlice(propId, result)) {
+ addProperty(propId, result, important);
+ return true;
+ }
+ break;
+ }
+ case CSSPropertyBorderImageWidth:
+ case CSSPropertyWebkitMaskBoxImageWidth: {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = nullptr;
+ if (parseBorderImageWidth(result)) {
+ addProperty(propId, result, important);
+ return true;
+ }
+ break;
+ }
+ case CSSPropertyBorderTopRightRadius:
+ case CSSPropertyBorderTopLeftRadius:
+ case CSSPropertyBorderBottomLeftRadius:
+ case CSSPropertyBorderBottomRightRadius: {
+ if (num != 1 && num != 2)
+ return false;
+ validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
+ if (!validPrimitive)
+ return false;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1 = createPrimitiveNumericValue(value);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2 = nullptr;
+ if (num == 2) {
+ value = m_valueList->next();
+ validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
+ if (!validPrimitive)
+ return false;
+ parsedValue2 = createPrimitiveNumericValue(value);
+ } else
+ parsedValue2 = parsedValue1;
+
+ addProperty(propId, createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release()), important);
+ return true;
+ }
+ case CSSPropertyTabSize:
+ validPrimitive = validUnit(value, FInteger | FNonNeg);
+ break;
+ case CSSPropertyWebkitAspectRatio:
+ return parseAspectRatio(important);
+ case CSSPropertyBorderRadius:
+ case CSSPropertyWebkitBorderRadius:
+ return parseBorderRadius(propId, important);
+ case CSSPropertyOutlineOffset:
+ validPrimitive = validUnit(value, FLength);
+ break;
+ case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
+ case CSSPropertyBoxShadow:
+ case CSSPropertyWebkitBoxShadow:
+ if (id == CSSValueNone)
+ validPrimitive = true;
+ else {
+ RefPtrWillBeRawPtr<CSSValueList> shadowValueList = parseShadow(m_valueList.get(), propId);
+ if (shadowValueList) {
+ addProperty(propId, shadowValueList.release(), important);
+ m_valueList->next();
+ return true;
+ }
+ return false;
+ }
+ break;
+ case CSSPropertyWebkitBoxReflect:
+ if (id == CSSValueNone)
+ validPrimitive = true;
+ else
+ return parseReflect(propId, important);
+ break;
+ case CSSPropertyOpacity:
+ validPrimitive = validUnit(value, FNumber);
+ break;
+ case CSSPropertyWebkitBoxFlex:
+ validPrimitive = validUnit(value, FNumber);
+ break;
+ case CSSPropertyWebkitBoxFlexGroup:
+ validPrimitive = validUnit(value, FInteger | FNonNeg, HTMLStandardMode);
+ break;
+ case CSSPropertyWebkitBoxOrdinalGroup:
+ validPrimitive = validUnit(value, FInteger | FNonNeg, HTMLStandardMode) && value->fValue;
+ break;
+ case CSSPropertyWebkitFilter:
+ if (id == CSSValueNone)
+ validPrimitive = true;
+ else {
+ RefPtrWillBeRawPtr<CSSValue> val = parseFilter();
+ if (val) {
+ addProperty(propId, val, important);
+ return true;
+ }
+ return false;
+ }
+ break;
+ case CSSPropertyFlex: {
+ ShorthandScope scope(this, propId);
+ if (id == CSSValueNone) {
+ addProperty(CSSPropertyFlexGrow, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
+ addProperty(CSSPropertyFlexShrink, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
+ addProperty(CSSPropertyFlexBasis, cssValuePool().createIdentifierValue(CSSValueAuto), important);
+ return true;
+ }
+ return parseFlex(m_valueList.get(), important);
+ }
+ case CSSPropertyFlexBasis:
+ // FIXME: Support intrinsic dimensions too.
+ if (id == CSSValueAuto)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+ break;
+ case CSSPropertyFlexGrow:
+ case CSSPropertyFlexShrink:
+ validPrimitive = validUnit(value, FNumber | FNonNeg);
+ break;
+ case CSSPropertyOrder:
+ validPrimitive = validUnit(value, FInteger, HTMLStandardMode);
+ break;
+ case CSSPropertyInternalMarqueeIncrement:
+ if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FLength | FPercent);
+ break;
+ case CSSPropertyInternalMarqueeRepetition:
+ if (id == CSSValueInfinite)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FInteger | FNonNeg);
+ break;
+ case CSSPropertyInternalMarqueeSpeed:
+ if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FTime | FInteger | FNonNeg);
+ break;
+ case CSSPropertyTransform:
+ case CSSPropertyWebkitTransform:
+ if (id == CSSValueNone)
+ validPrimitive = true;
+ else {
+ RefPtrWillBeRawPtr<CSSValue> transformValue = parseTransform(propId);
+ if (transformValue) {
+ addProperty(propId, transformValue.release(), important);
+ return true;
+ }
+ return false;
+ }
+ break;
+ case CSSPropertyTransformOrigin: {
+ RefPtrWillBeRawPtr<CSSValueList> list = parseTransformOrigin();
+ if (!list)
+ return false;
+ // These values are added to match gecko serialization.
+ if (list->length() == 1)
+ list->append(cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+ if (list->length() == 2)
+ list->append(cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX));
+ addProperty(propId, list.release(), important);
+ return true;
+ }
+ case CSSPropertyWebkitTransformOrigin:
+ case CSSPropertyWebkitTransformOriginX:
+ case CSSPropertyWebkitTransformOriginY:
+ case CSSPropertyWebkitTransformOriginZ: {
+ RefPtrWillBeRawPtr<CSSValue> val1 = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> val2 = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> val3 = nullptr;
+ CSSPropertyID propId1, propId2, propId3;
+ if (parseWebkitTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
+ addProperty(propId1, val1.release(), important);
+ if (val2)
+ addProperty(propId2, val2.release(), important);
+ if (val3)
+ addProperty(propId3, val3.release(), important);
+ return true;
+ }
+ return false;
+ }
+ case CSSPropertyPerspective:
+ if (id == CSSValueNone) {
+ validPrimitive = true;
+ } else if (validUnit(value, FLength | FNonNeg)) {
+ addProperty(propId, createPrimitiveNumericValue(value), important);
+ return true;
+ }
+ break;
+ case CSSPropertyWebkitPerspective:
+ if (id == CSSValueNone) {
+ validPrimitive = true;
+ } else if (validUnit(value, FNumber | FLength | FNonNeg)) {
+ // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
+ addProperty(propId, createPrimitiveNumericValue(value), important);
+ return true;
+ }
+ break;
+ case CSSPropertyPerspectiveOrigin: {
+ RefPtrWillBeRawPtr<CSSValueList> list = parseTransformOrigin();
+ if (!list || list->length() == 3)
+ return false;
+ // This values are added to match gecko serialization.
+ if (list->length() == 1)
+ list->append(cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+ addProperty(propId, list.release(), important);
+ return true;
+ }
+ case CSSPropertyWebkitPerspectiveOrigin:
+ case CSSPropertyWebkitPerspectiveOriginX:
+ case CSSPropertyWebkitPerspectiveOriginY: {
+ RefPtrWillBeRawPtr<CSSValue> val1 = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> val2 = nullptr;
+ CSSPropertyID propId1, propId2;
+ if (parseWebkitPerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
+ addProperty(propId1, val1.release(), important);
+ if (val2)
+ addProperty(propId2, val2.release(), important);
+ return true;
+ }
+ return false;
+ }
+ case CSSPropertyAnimationDelay:
+ case CSSPropertyAnimationDirection:
+ case CSSPropertyAnimationDuration:
+ case CSSPropertyAnimationFillMode:
+ case CSSPropertyAnimationName:
+ case CSSPropertyAnimationPlayState:
+ case CSSPropertyAnimationIterationCount:
+ case CSSPropertyAnimationTimingFunction:
+ if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
+ break;
+ case CSSPropertyWebkitAnimationDelay:
+ case CSSPropertyWebkitAnimationDirection:
+ case CSSPropertyWebkitAnimationDuration:
+ case CSSPropertyWebkitAnimationFillMode:
+ case CSSPropertyWebkitAnimationName:
+ case CSSPropertyWebkitAnimationPlayState:
+ case CSSPropertyWebkitAnimationIterationCount:
+ case CSSPropertyWebkitAnimationTimingFunction:
+ case CSSPropertyTransitionDelay:
+ case CSSPropertyTransitionDuration:
+ case CSSPropertyTransitionTimingFunction:
+ case CSSPropertyTransitionProperty:
+ case CSSPropertyWebkitTransitionDelay:
+ case CSSPropertyWebkitTransitionDuration:
+ case CSSPropertyWebkitTransitionTimingFunction:
+ case CSSPropertyWebkitTransitionProperty: {
+ if (RefPtrWillBeRawPtr<CSSValueList> val = parseAnimationPropertyList(propId)) {
+ addPropertyWithPrefixingVariant(propId, val.release(), important);
+ return true;
+ }
+ return false;
+ }
+
+ case CSSPropertyJustifySelf:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+
+ return parseItemPositionOverflowPosition(propId, important);
+ case CSSPropertyGridAutoColumns:
+ case CSSPropertyGridAutoRows:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ parsedValue = parseGridTrackSize(*m_valueList);
+ break;
+
+ case CSSPropertyGridTemplateColumns:
+ case CSSPropertyGridTemplateRows:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ parsedValue = parseGridTrackList(important);
+ break;
+
+ case CSSPropertyGridColumnEnd:
+ case CSSPropertyGridColumnStart:
+ case CSSPropertyGridRowEnd:
+ case CSSPropertyGridRowStart:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ parsedValue = parseGridPosition();
+ break;
+
+ case CSSPropertyGridColumn:
+ case CSSPropertyGridRow:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ return parseGridItemPositionShorthand(propId, important);
+
+ case CSSPropertyGridArea:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ return parseGridAreaShorthand(important);
+
+ case CSSPropertyGridTemplateAreas:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ parsedValue = parseGridTemplateAreas();
+ break;
+
+ case CSSPropertyGridTemplate:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ return parseGridTemplateShorthand(important);
+
+ case CSSPropertyGrid:
+ if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+ return false;
+ return parseGridShorthand(important);
+
+ case CSSPropertyWebkitMarginCollapse: {
+ if (num == 1) {
+ ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
+ if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important))
+ return false;
+ CSSValue* value = m_parsedProperties.last().value();
+ addProperty(webkitMarginCollapseShorthand().properties()[1], value, important);
+ return true;
+ }
+ else if (num == 2) {
+ ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
+ if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important) || !parseValue(webkitMarginCollapseShorthand().properties()[1], important))
+ return false;
+ return true;
+ }
+ return false;
+ }
+ case CSSPropertyTextLineThroughWidth:
+ case CSSPropertyTextOverlineWidth:
+ case CSSPropertyTextUnderlineWidth:
+ if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueThin ||
+ id == CSSValueMedium || id == CSSValueThick)
+ validPrimitive = true;
+ else
+ validPrimitive = !id && validUnit(value, FNumber | FLength | FPercent);
+ break;
+ case CSSPropertyWebkitColumnCount:
+ parsedValue = parseColumnCount();
+ break;
+ case CSSPropertyWebkitColumnGap: // normal | <length>
+ if (id == CSSValueNormal)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FLength | FNonNeg);
+ break;
+ case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property)
+ if (id == CSSValueAll || id == CSSValueNone)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FNumber | FNonNeg) && value->fValue == 1;
+ break;
+ case CSSPropertyWebkitColumnWidth: // auto | <length>
+ parsedValue = parseColumnWidth();
+ break;
+ case CSSPropertyWillChange:
+ if (!RuntimeEnabledFeatures::cssWillChangeEnabled())
+ return false;
+ return parseWillChange(important);
+ // End of CSS3 properties
+
+ // Apple specific properties. These will never be standardized and are purely to
+ // support custom WebKit-based Apple applications.
+ case CSSPropertyWebkitLineClamp:
+ // When specifying number of lines, don't allow 0 as a valid value
+ // When specifying either type of unit, require non-negative integers
+ validPrimitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, HTMLQuirksMode));
+ break;
+
+ case CSSPropertyWebkitFontSizeDelta: // <length>
+ validPrimitive = validUnit(value, FLength);
+ break;
+
+ case CSSPropertyWebkitHighlight:
+ if (id == CSSValueNone || value->unit == CSSPrimitiveValue::CSS_STRING)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyWebkitHyphenateCharacter:
+ if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyWebkitLocale:
+ if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
+ validPrimitive = true;
+ break;
+
+ // End Apple-specific properties
+
+ case CSSPropertyWebkitAppRegion:
+ if (id >= CSSValueDrag && id <= CSSValueNoDrag)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyWebkitTapHighlightColor:
+ if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu
+ || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) {
+ validPrimitive = true;
+ } else {
+ parsedValue = parseColor();
+ if (parsedValue)
+ m_valueList->next();
+ }
+ break;
+
+ /* shorthand properties */
+ case CSSPropertyBackground: {
+ // Position must come before color in this array because a plain old "0" is a legal color
+ // in quirks mode but it's usually the X coordinate of a position.
+ const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat,
+ CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin,
+ CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundSize };
+ return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
+ }
+ case CSSPropertyWebkitMask: {
+ const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat,
+ CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip, CSSPropertyWebkitMaskSize };
+ return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
+ }
+ case CSSPropertyBorder:
+ // [ 'border-width' || 'border-style' || <color> ] | inherit
+ {
+ if (parseShorthand(propId, parsingShorthandForProperty(CSSPropertyBorder), important)) {
+ // The CSS3 Borders and Backgrounds specification says that border also resets border-image. It's as
+ // though a value of none was specified for the image.
+ addExpandedPropertyForValue(CSSPropertyBorderImage, cssValuePool().createImplicitInitialValue(), important);
+ return true;
+ }
+ return false;
+ }
+ case CSSPropertyBorderTop:
+ // [ 'border-top-width' || 'border-style' || <color> ] | inherit
+ return parseShorthand(propId, borderTopShorthand(), important);
+ case CSSPropertyBorderRight:
+ // [ 'border-right-width' || 'border-style' || <color> ] | inherit
+ return parseShorthand(propId, borderRightShorthand(), important);
+ case CSSPropertyBorderBottom:
+ // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit
+ return parseShorthand(propId, borderBottomShorthand(), important);
+ case CSSPropertyBorderLeft:
+ // [ 'border-left-width' || 'border-style' || <color> ] | inherit
+ return parseShorthand(propId, borderLeftShorthand(), important);
+ case CSSPropertyWebkitBorderStart:
+ return parseShorthand(propId, webkitBorderStartShorthand(), important);
+ case CSSPropertyWebkitBorderEnd:
+ return parseShorthand(propId, webkitBorderEndShorthand(), important);
+ case CSSPropertyWebkitBorderBefore:
+ return parseShorthand(propId, webkitBorderBeforeShorthand(), important);
+ case CSSPropertyWebkitBorderAfter:
+ return parseShorthand(propId, webkitBorderAfterShorthand(), important);
+ case CSSPropertyOutline:
+ // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
+ return parseShorthand(propId, outlineShorthand(), important);
+ case CSSPropertyBorderColor:
+ // <color>{1,4} | inherit
+ return parse4Values(propId, borderColorShorthand().properties(), important);
+ case CSSPropertyBorderWidth:
+ // <border-width>{1,4} | inherit
+ return parse4Values(propId, borderWidthShorthand().properties(), important);
+ case CSSPropertyBorderStyle:
+ // <border-style>{1,4} | inherit
+ return parse4Values(propId, borderStyleShorthand().properties(), important);
+ case CSSPropertyMargin:
+ // <margin-width>{1,4} | inherit
+ return parse4Values(propId, marginShorthand().properties(), important);
+ case CSSPropertyPadding:
+ // <padding-width>{1,4} | inherit
+ return parse4Values(propId, paddingShorthand().properties(), important);
+ case CSSPropertyFlexFlow:
+ return parseShorthand(propId, flexFlowShorthand(), important);
+ case CSSPropertyFont:
+ // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
+ // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
+ if (id >= CSSValueCaption && id <= CSSValueStatusBar)
+ validPrimitive = true;
+ else
+ return parseFont(important);
+ break;
+ case CSSPropertyListStyle:
+ return parseShorthand(propId, listStyleShorthand(), important);
+ case CSSPropertyWebkitColumns:
+ return parseColumnsShorthand(important);
+ case CSSPropertyWebkitColumnRule:
+ return parseShorthand(propId, webkitColumnRuleShorthand(), important);
+ case CSSPropertyWebkitTextStroke:
+ return parseShorthand(propId, webkitTextStrokeShorthand(), important);
+ case CSSPropertyAnimation:
+ if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
+ break;
+ case CSSPropertyWebkitAnimation:
+ return parseAnimationShorthand(propId, important);
+ case CSSPropertyTransition:
+ case CSSPropertyWebkitTransition:
+ return parseTransitionShorthand(propId, important);
+ case CSSPropertyInvalid:
+ return false;
+ case CSSPropertyPage:
+ return parsePage(propId, important);
+ case CSSPropertyFontStretch:
+ return false;
+ // CSS Text Layout Module Level 3: Vertical writing support
+ case CSSPropertyWebkitTextEmphasis:
+ return parseShorthand(propId, webkitTextEmphasisShorthand(), important);
+
+ case CSSPropertyWebkitTextEmphasisStyle:
+ return parseTextEmphasisStyle(important);
+
+ case CSSPropertyWebkitTextOrientation:
+ // FIXME: For now just support sideways, sideways-right, upright and vertical-right.
+ if (id == CSSValueSideways || id == CSSValueSidewaysRight || id == CSSValueVerticalRight || id == CSSValueUpright)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyWebkitLineBoxContain:
+ if (id == CSSValueNone)
+ validPrimitive = true;
+ else
+ return parseLineBoxContain(important);
+ break;
+ case CSSPropertyWebkitFontFeatureSettings:
+ if (id == CSSValueNormal)
+ validPrimitive = true;
+ else
+ return parseFontFeatureSettings(important);
+ break;
+
+ case CSSPropertyFontVariantLigatures:
+ if (id == CSSValueNormal)
+ validPrimitive = true;
+ else
+ return parseFontVariantLigatures(important);
+ break;
+ case CSSPropertyWebkitClipPath:
+ if (id == CSSValueNone) {
+ validPrimitive = true;
+ } else if (value->unit == CSSParserValue::Function) {
+ parsedValue = parseBasicShape();
+ } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI);
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+ }
+ break;
+ case CSSPropertyShapeOutside:
+ parsedValue = parseShapeProperty(propId);
+ break;
+ case CSSPropertyShapeMargin:
+ validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FLength | FPercent | FNonNeg));
+ break;
+ case CSSPropertyShapeImageThreshold:
+ validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FNumber));
+ break;
+
+ case CSSPropertyTouchAction:
+ // auto | none | [pan-x || pan-y] | manipulation
+ return parseTouchAction(important);
+
+ case CSSPropertyAlignSelf:
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+ return parseItemPositionOverflowPosition(propId, important);
+
+ case CSSPropertyAlignItems:
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+ return parseItemPositionOverflowPosition(propId, important);
+
+ case CSSPropertyBorderBottomStyle:
+ case CSSPropertyBorderCollapse:
+ case CSSPropertyBorderLeftStyle:
+ case CSSPropertyBorderRightStyle:
+ case CSSPropertyBorderTopStyle:
+ case CSSPropertyBoxSizing:
+ case CSSPropertyCaptionSide:
+ case CSSPropertyClear:
+ case CSSPropertyDirection:
+ case CSSPropertyDisplay:
+ case CSSPropertyEmptyCells:
+ case CSSPropertyFloat:
+ case CSSPropertyFontStyle:
+ case CSSPropertyImageRendering:
+ case CSSPropertyListStylePosition:
+ case CSSPropertyListStyleType:
+ case CSSPropertyObjectFit:
+ case CSSPropertyOutlineStyle:
+ case CSSPropertyOverflowWrap:
+ case CSSPropertyOverflowX:
+ case CSSPropertyOverflowY:
+ case CSSPropertyPageBreakAfter:
+ case CSSPropertyPageBreakBefore:
+ case CSSPropertyPageBreakInside:
+ case CSSPropertyPointerEvents:
+ case CSSPropertyPosition:
+ case CSSPropertyResize:
+ case CSSPropertySpeak:
+ case CSSPropertyTableLayout:
+ case CSSPropertyTextAlignLast:
+ case CSSPropertyTextJustify:
+ case CSSPropertyTextLineThroughMode:
+ case CSSPropertyTextLineThroughStyle:
+ case CSSPropertyTextOverflow:
+ case CSSPropertyTextOverlineMode:
+ case CSSPropertyTextOverlineStyle:
+ case CSSPropertyTextRendering:
+ case CSSPropertyTextTransform:
+ case CSSPropertyTextUnderlineMode:
+ case CSSPropertyTextUnderlineStyle:
+ case CSSPropertyTouchActionDelay:
+ case CSSPropertyVisibility:
+ case CSSPropertyWebkitAppearance:
+ case CSSPropertyBackfaceVisibility:
+ case CSSPropertyWebkitBackfaceVisibility:
+ case CSSPropertyWebkitBorderAfterStyle:
+ case CSSPropertyWebkitBorderBeforeStyle:
+ case CSSPropertyWebkitBorderEndStyle:
+ case CSSPropertyWebkitBorderFit:
+ case CSSPropertyWebkitBorderStartStyle:
+ case CSSPropertyWebkitBoxAlign:
+ case CSSPropertyWebkitBoxDecorationBreak:
+ case CSSPropertyWebkitBoxDirection:
+ case CSSPropertyWebkitBoxLines:
+ case CSSPropertyWebkitBoxOrient:
+ case CSSPropertyWebkitBoxPack:
+ case CSSPropertyInternalCallback:
+ case CSSPropertyWebkitColumnBreakAfter:
+ case CSSPropertyWebkitColumnBreakBefore:
+ case CSSPropertyWebkitColumnBreakInside:
+ case CSSPropertyColumnFill:
+ case CSSPropertyWebkitColumnRuleStyle:
+ case CSSPropertyAlignContent:
+ case CSSPropertyFlexDirection:
+ case CSSPropertyFlexWrap:
+ case CSSPropertyJustifyContent:
+ case CSSPropertyFontKerning:
+ case CSSPropertyWebkitFontSmoothing:
+ case CSSPropertyGridAutoFlow:
+ case CSSPropertyWebkitLineBreak:
+ case CSSPropertyWebkitMarginAfterCollapse:
+ case CSSPropertyWebkitMarginBeforeCollapse:
+ case CSSPropertyWebkitMarginBottomCollapse:
+ case CSSPropertyWebkitMarginTopCollapse:
+ case CSSPropertyInternalMarqueeDirection:
+ case CSSPropertyInternalMarqueeStyle:
+ case CSSPropertyWebkitPrintColorAdjust:
+ case CSSPropertyWebkitRtlOrdering:
+ case CSSPropertyWebkitRubyPosition:
+ case CSSPropertyWebkitTextCombine:
+ case CSSPropertyWebkitTextEmphasisPosition:
+ case CSSPropertyWebkitTextSecurity:
+ case CSSPropertyTransformStyle:
+ case CSSPropertyWebkitTransformStyle:
+ case CSSPropertyWebkitUserDrag:
+ case CSSPropertyWebkitUserModify:
+ case CSSPropertyWebkitUserSelect:
+ case CSSPropertyWebkitWrapFlow:
+ case CSSPropertyWebkitWrapThrough:
+ case CSSPropertyWebkitWritingMode:
+ case CSSPropertyWhiteSpace:
+ case CSSPropertyWordBreak:
+ case CSSPropertyWordWrap:
+ case CSSPropertyMixBlendMode:
+ case CSSPropertyIsolation:
+ // These properties should be handled before in isValidKeywordPropertyAndValue().
+ ASSERT_NOT_REACHED();
+ return false;
+ // Properties below are validated inside parseViewportProperty, because we
+ // check for parser state. We need to invalidate if someone adds them outside
+ // a @viewport rule.
+ case CSSPropertyMaxZoom:
+ case CSSPropertyMinZoom:
+ case CSSPropertyOrientation:
+ case CSSPropertyUserZoom:
+ validPrimitive = false;
+ break;
+
+ case CSSPropertyAll:
+ if (id == CSSValueInitial || id == CSSValueInherit || id == CSSValueUnset) {
+ validPrimitive = true;
+ break;
+ }
+ return false;
+
+ default:
+ return parseSVGValue(propId, important);
+ }
+
+ if (validPrimitive) {
+ parsedValue = parseValidPrimitive(id, value);
+ m_valueList->next();
+ }
+ ASSERT(!m_parsedCalculation);
+ if (parsedValue) {
+ if (!m_valueList->current() || inShorthand()) {
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+ }
+ }
+ return false;
+}
+
+void CSSPropertyParser::addFillValue(RefPtrWillBeRawPtr<CSSValue>& lval, PassRefPtrWillBeRawPtr<CSSValue> rval)
+{
+ if (lval) {
+ if (lval->isBaseValueList())
+ toCSSValueList(lval.get())->append(rval);
+ else {
+ PassRefPtrWillBeRawPtr<CSSValue> oldlVal(lval.release());
+ PassRefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ list->append(oldlVal);
+ list->append(rval);
+ lval = list;
+ }
+ }
+ else
+ lval = rval;
+}
+
+static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtrWillBeRawPtr<CSSValue>& cssValue)
+{
+ if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox
+ || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) {
+ cssValue = cssValuePool().createIdentifierValue(parserValue->id);
+ return true;
+ }
+ return false;
+}
+
+const int cMaxFillProperties = 9;
+
+bool CSSPropertyParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* properties, int numProperties, bool important)
+{
+ ASSERT(numProperties <= cMaxFillProperties);
+ if (numProperties > cMaxFillProperties)
+ return false;
+
+ ShorthandScope scope(this, propId);
+
+ bool parsedProperty[cMaxFillProperties] = { false };
+ RefPtrWillBeRawPtr<CSSValue> values[cMaxFillProperties];
+#if ENABLE(OILPAN)
+ // Zero initialize the array of raw pointers.
+ memset(&values, 0, sizeof(values));
+#endif
+ RefPtrWillBeRawPtr<CSSValue> clipValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> positionYValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> repeatYValue = nullptr;
+ bool foundClip = false;
+ int i;
+ bool foundPositionCSSProperty = false;
+
+ while (m_valueList->current()) {
+ CSSParserValue* val = m_valueList->current();
+ if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
+ // We hit the end. Fill in all remaining values with the initial value.
+ m_valueList->next();
+ for (i = 0; i < numProperties; ++i) {
+ if (properties[i] == CSSPropertyBackgroundColor && parsedProperty[i])
+ // Color is not allowed except as the last item in a list for backgrounds.
+ // Reject the entire property.
+ return false;
+
+ if (!parsedProperty[i] && properties[i] != CSSPropertyBackgroundColor) {
+ addFillValue(values[i], cssValuePool().createImplicitInitialValue());
+ if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+ addFillValue(positionYValue, cssValuePool().createImplicitInitialValue());
+ if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+ addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue());
+ if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) && !parsedProperty[i]) {
+ // If background-origin wasn't present, then reset background-clip also.
+ addFillValue(clipValue, cssValuePool().createImplicitInitialValue());
+ }
+ }
+ parsedProperty[i] = false;
+ }
+ if (!m_valueList->current())
+ break;
+ }
+
+ bool sizeCSSPropertyExpected = false;
+ if (isForwardSlashOperator(val) && foundPositionCSSProperty) {
+ sizeCSSPropertyExpected = true;
+ m_valueList->next();
+ }
+
+ foundPositionCSSProperty = false;
+ bool found = false;
+ for (i = 0; !found && i < numProperties; ++i) {
+
+ if (sizeCSSPropertyExpected && (properties[i] != CSSPropertyBackgroundSize && properties[i] != CSSPropertyWebkitMaskSize))
+ continue;
+ if (!sizeCSSPropertyExpected && (properties[i] == CSSPropertyBackgroundSize || properties[i] == CSSPropertyWebkitMaskSize))
+ continue;
+
+ if (!parsedProperty[i]) {
+ RefPtrWillBeRawPtr<CSSValue> val1 = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> val2 = nullptr;
+ CSSPropertyID propId1, propId2;
+ CSSParserValue* parserValue = m_valueList->current();
+ // parseFillProperty() may modify m_implicitShorthand, so we MUST reset it
+ // before EACH return below.
+ if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) {
+ parsedProperty[i] = found = true;
+ addFillValue(values[i], val1.release());
+ if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+ addFillValue(positionYValue, val2.release());
+ if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+ addFillValue(repeatYValue, val2.release());
+ if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
+ // Reparse the value as a clip, and see if we succeed.
+ if (parseBackgroundClip(parserValue, val1))
+ addFillValue(clipValue, val1.release()); // The property parsed successfully.
+ else
+ addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
+ }
+ if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) {
+ // Update clipValue
+ addFillValue(clipValue, val1.release());
+ foundClip = true;
+ }
+ if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+ foundPositionCSSProperty = true;
+ }
+ }
+ }
+
+ // if we didn't find at least one match, this is an
+ // invalid shorthand and we have to ignore it
+ if (!found) {
+ m_implicitShorthand = false;
+ return false;
+ }
+ }
+
+ // Now add all of the properties we found.
+ for (i = 0; i < numProperties; i++) {
+ // Fill in any remaining properties with the initial value.
+ if (!parsedProperty[i]) {
+ addFillValue(values[i], cssValuePool().createImplicitInitialValue());
+ if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+ addFillValue(positionYValue, cssValuePool().createImplicitInitialValue());
+ if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+ addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue());
+ if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
+ // If background-origin wasn't present, then reset background-clip also.
+ addFillValue(clipValue, cssValuePool().createImplicitInitialValue());
+ }
+ }
+ if (properties[i] == CSSPropertyBackgroundPosition) {
+ addProperty(CSSPropertyBackgroundPositionX, values[i].release(), important);
+ // it's OK to call positionYValue.release() since we only see CSSPropertyBackgroundPosition once
+ addProperty(CSSPropertyBackgroundPositionY, positionYValue.release(), important);
+ } else if (properties[i] == CSSPropertyWebkitMaskPosition) {
+ addProperty(CSSPropertyWebkitMaskPositionX, values[i].release(), important);
+ // it's OK to call positionYValue.release() since we only see CSSPropertyWebkitMaskPosition once
+ addProperty(CSSPropertyWebkitMaskPositionY, positionYValue.release(), important);
+ } else if (properties[i] == CSSPropertyBackgroundRepeat) {
+ addProperty(CSSPropertyBackgroundRepeatX, values[i].release(), important);
+ // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
+ addProperty(CSSPropertyBackgroundRepeatY, repeatYValue.release(), important);
+ } else if (properties[i] == CSSPropertyWebkitMaskRepeat) {
+ addProperty(CSSPropertyWebkitMaskRepeatX, values[i].release(), important);
+ // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
+ addProperty(CSSPropertyWebkitMaskRepeatY, repeatYValue.release(), important);
+ } else if ((properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) && !foundClip)
+ // Value is already set while updating origin
+ continue;
+ else if (properties[i] == CSSPropertyBackgroundSize && !parsedProperty[i] && m_context.useLegacyBackgroundSizeShorthandBehavior())
+ continue;
+ else
+ addProperty(properties[i], values[i].release(), important);
+
+ // Add in clip values when we hit the corresponding origin property.
+ if (properties[i] == CSSPropertyBackgroundOrigin && !foundClip)
+ addProperty(CSSPropertyBackgroundClip, clipValue.release(), important);
+ else if (properties[i] == CSSPropertyWebkitMaskOrigin && !foundClip)
+ addProperty(CSSPropertyWebkitMaskClip, clipValue.release(), important);
+ }
+
+ m_implicitShorthand = false;
+ return true;
+}
+
+static bool isValidTransitionPropertyList(CSSValueList* value)
+{
+ if (value->length() < 2)
+ return true;
+ for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
+ // FIXME: Shorthand parsing shouldn't add initial to the list since it won't round-trip
+ if (i.value()->isInitialValue())
+ continue;
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value());
+ if (primitiveValue->isValueID() && primitiveValue->getValueID() == CSSValueNone)
+ return false;
+ }
+ return true;
+}
+
+bool CSSPropertyParser::parseAnimationShorthand(CSSPropertyID propId, bool important)
+{
+ const StylePropertyShorthand& animationProperties = parsingShorthandForProperty(propId);
+ const unsigned numProperties = 8;
+
+ // The list of properties in the shorthand should be the same
+ // length as the list with animation name in last position, even though they are
+ // in a different order.
+ ASSERT(numProperties == animationProperties.length());
+ ASSERT(numProperties == shorthandForProperty(propId).length());
+
+ ShorthandScope scope(this, propId);
+
+ bool parsedProperty[numProperties] = { false };
+ RefPtrWillBeRawPtr<CSSValueList> values[numProperties];
+ for (size_t i = 0; i < numProperties; ++i)
+ values[i] = CSSValueList::createCommaSeparated();
+
+ while (m_valueList->current()) {
+ CSSParserValue* val = m_valueList->current();
+ if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
+ // We hit the end. Fill in all remaining values with the initial value.
+ m_valueList->next();
+ for (size_t i = 0; i < numProperties; ++i) {
+ if (!parsedProperty[i])
+ values[i]->append(cssValuePool().createImplicitInitialValue());
+ parsedProperty[i] = false;
+ }
+ if (!m_valueList->current())
+ break;
+ }
+
+ bool found = false;
+ for (size_t i = 0; i < numProperties; ++i) {
+ if (parsedProperty[i])
+ continue;
+ if (RefPtrWillBeRawPtr<CSSValue> val = parseAnimationProperty(animationProperties.properties()[i])) {
+ parsedProperty[i] = found = true;
+ values[i]->append(val.release());
+ break;
+ }
+ }
+
+ // if we didn't find at least one match, this is an
+ // invalid shorthand and we have to ignore it
+ if (!found)
+ return false;
+ }
+
+ for (size_t i = 0; i < numProperties; ++i) {
+ // If we didn't find the property, set an intial value.
+ if (!parsedProperty[i])
+ values[i]->append(cssValuePool().createImplicitInitialValue());
+
+ if (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
+ addPropertyWithPrefixingVariant(animationProperties.properties()[i], values[i].release(), important);
+ else
+ addProperty(animationProperties.properties()[i], values[i].release(), important);
+ }
+
+ return true;
+}
+
+bool CSSPropertyParser::parseTransitionShorthand(CSSPropertyID propId, bool important)
+{
+ const unsigned numProperties = 4;
+ const StylePropertyShorthand& shorthand = parsingShorthandForProperty(propId);
+ ASSERT(numProperties == shorthand.length());
+
+ ShorthandScope scope(this, propId);
+
+ bool parsedProperty[numProperties] = { false };
+ RefPtrWillBeRawPtr<CSSValueList> values[numProperties];
+ for (size_t i = 0; i < numProperties; ++i)
+ values[i] = CSSValueList::createCommaSeparated();
+
+ while (m_valueList->current()) {
+ CSSParserValue* val = m_valueList->current();
+ if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
+ // We hit the end. Fill in all remaining values with the initial value.
+ m_valueList->next();
+ for (size_t i = 0; i < numProperties; ++i) {
+ if (!parsedProperty[i])
+ values[i]->append(cssValuePool().createImplicitInitialValue());
+ parsedProperty[i] = false;
+ }
+ if (!m_valueList->current())
+ break;
+ }
+
+ bool found = false;
+ for (size_t i = 0; i < numProperties; ++i) {
+ if (parsedProperty[i])
+ continue;
+ if (RefPtrWillBeRawPtr<CSSValue> val = parseAnimationProperty(shorthand.properties()[i])) {
+ parsedProperty[i] = found = true;
+ values[i]->append(val.release());
+ break;
+ }
+ }
+
+ // if we didn't find at least one match, this is an
+ // invalid shorthand and we have to ignore it
+ if (!found)
+ return false;
+ }
+
+ ASSERT(shorthand.properties()[3] == CSSPropertyTransitionProperty || shorthand.properties()[3] == CSSPropertyWebkitTransitionProperty);
+ if (!isValidTransitionPropertyList(values[3].get()))
+ return false;
+
+ // Fill in any remaining properties with the initial value and add
+ for (size_t i = 0; i < numProperties; ++i) {
+ if (!parsedProperty[i])
+ values[i]->append(cssValuePool().createImplicitInitialValue());
+ addPropertyWithPrefixingVariant(shorthand.properties()[i], values[i].release(), important);
+ }
+
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseColumnWidth()
+{
+ CSSParserValue* value = m_valueList->current();
+ // Always parse lengths in strict mode here, since it would be ambiguous otherwise when used in
+ // the 'columns' shorthand property.
+ if (value->id == CSSValueAuto
+ || (validUnit(value, FLength | FNonNeg, HTMLStandardMode) && value->fValue)) {
+ RefPtrWillBeRawPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
+ m_valueList->next();
+ return parsedValue;
+ }
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseColumnCount()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (value->id == CSSValueAuto
+ || (!value->id && validUnit(value, FPositiveInteger, HTMLQuirksMode))) {
+ RefPtrWillBeRawPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
+ m_valueList->next();
+ return parsedValue;
+ }
+ return nullptr;
+}
+
+bool CSSPropertyParser::parseColumnsShorthand(bool important)
+{
+ RefPtrWillBeRawPtr<CSSValue> columnWidth = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> columnCount = nullptr;
+ bool hasPendingExplicitAuto = false;
+
+ for (unsigned propertiesParsed = 0; CSSParserValue* value = m_valueList->current(); propertiesParsed++) {
+ if (propertiesParsed >= 2)
+ return false; // Too many values for this shorthand. Invalid declaration.
+ if (!propertiesParsed && value->id == CSSValueAuto) {
+ // 'auto' is a valid value for any of the two longhands, and at this point we
+ // don't know which one(s) it is meant for. We need to see if there are other
+ // values first.
+ m_valueList->next();
+ hasPendingExplicitAuto = true;
+ } else {
+ if (!columnWidth) {
+ if ((columnWidth = parseColumnWidth()))
+ continue;
+ }
+ if (!columnCount) {
+ if ((columnCount = parseColumnCount()))
+ continue;
+ }
+ // If we didn't find at least one match, this is an
+ // invalid shorthand and we have to ignore it.
+ return false;
+ }
+ }
+ if (hasPendingExplicitAuto) {
+ // Time to assign the previously skipped 'auto' value to a property. If both properties are
+ // unassigned at this point (i.e. 'columns:auto'), it doesn't matter that much which one we
+ // set (although it does make a slight difference to web-inspector). The one we don't set
+ // here will get an implicit 'auto' value further down.
+ if (!columnWidth) {
+ columnWidth = cssValuePool().createIdentifierValue(CSSValueAuto);
+ } else {
+ ASSERT(!columnCount);
+ columnCount = cssValuePool().createIdentifierValue(CSSValueAuto);
+ }
+ }
+ ASSERT(columnCount || columnWidth);
+
+ // Any unassigned property at this point will become implicit 'auto'.
+ if (columnWidth)
+ addProperty(CSSPropertyWebkitColumnWidth, columnWidth, important);
+ else
+ addProperty(CSSPropertyWebkitColumnWidth, cssValuePool().createIdentifierValue(CSSValueAuto), important, true /* implicit */);
+ if (columnCount)
+ addProperty(CSSPropertyWebkitColumnCount, columnCount, important);
+ else
+ addProperty(CSSPropertyWebkitColumnCount, cssValuePool().createIdentifierValue(CSSValueAuto), important, true /* implicit */);
+ return true;
+}
+
+bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthand& shorthand, bool important)
+{
+ // We try to match as many properties as possible
+ // We set up an array of booleans to mark which property has been found,
+ // and we try to search for properties until it makes no longer any sense.
+ ShorthandScope scope(this, propId);
+
+ bool found = false;
+ unsigned propertiesParsed = 0;
+ bool propertyFound[6] = { false, false, false, false, false, false }; // 6 is enough size.
+
+ while (m_valueList->current()) {
+ found = false;
+ for (unsigned propIndex = 0; !found && propIndex < shorthand.length(); ++propIndex) {
+ if (!propertyFound[propIndex] && parseValue(shorthand.properties()[propIndex], important)) {
+ propertyFound[propIndex] = found = true;
+ propertiesParsed++;
+ }
+ }
+
+ // if we didn't find at least one match, this is an
+ // invalid shorthand and we have to ignore it
+ if (!found)
+ return false;
+ }
+
+ if (propertiesParsed == shorthand.length())
+ return true;
+
+ // Fill in any remaining properties with the initial value.
+ ImplicitScope implicitScope(this, PropertyImplicit);
+ const StylePropertyShorthand* const* const propertiesForInitialization = shorthand.propertiesForInitialization();
+ for (unsigned i = 0; i < shorthand.length(); ++i) {
+ if (propertyFound[i])
+ continue;
+
+ if (propertiesForInitialization) {
+ const StylePropertyShorthand& initProperties = *(propertiesForInitialization[i]);
+ for (unsigned propIndex = 0; propIndex < initProperties.length(); ++propIndex)
+ addProperty(initProperties.properties()[propIndex], cssValuePool().createImplicitInitialValue(), important);
+ } else
+ addProperty(shorthand.properties()[i], cssValuePool().createImplicitInitialValue(), important);
+ }
+
+ return true;
+}
+
+bool CSSPropertyParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properties, bool important)
+{
+ /* From the CSS 2 specs, 8.3
+ * If there is only one value, it applies to all sides. If there are two values, the top and
+ * bottom margins are set to the first value and the right and left margins are set to the second.
+ * If there are three values, the top is set to the first value, the left and right are set to the
+ * second, and the bottom is set to the third. If there are four values, they apply to the top,
+ * right, bottom, and left, respectively.
+ */
+
+ int num = inShorthand() ? 1 : m_valueList->size();
+
+ ShorthandScope scope(this, propId);
+
+ // the order is top, right, bottom, left
+ switch (num) {
+ case 1: {
+ if (!parseValue(properties[0], important))
+ return false;
+ CSSValue* value = m_parsedProperties.last().value();
+ ImplicitScope implicitScope(this, PropertyImplicit);
+ addProperty(properties[1], value, important);
+ addProperty(properties[2], value, important);
+ addProperty(properties[3], value, important);
+ break;
+ }
+ case 2: {
+ if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
+ return false;
+ CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+ ImplicitScope implicitScope(this, PropertyImplicit);
+ addProperty(properties[2], value, important);
+ value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+ addProperty(properties[3], value, important);
+ break;
+ }
+ case 3: {
+ if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important))
+ return false;
+ CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+ ImplicitScope implicitScope(this, PropertyImplicit);
+ addProperty(properties[3], value, important);
+ break;
+ }
+ case 4: {
+ if (!parseValue(properties[0], important) || !parseValue(properties[1], important) ||
+ !parseValue(properties[2], important) || !parseValue(properties[3], important))
+ return false;
+ break;
+ }
+ default: {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// auto | <identifier>
+bool CSSPropertyParser::parsePage(CSSPropertyID propId, bool important)
+{
+ ASSERT(propId == CSSPropertyPage);
+
+ if (m_valueList->size() != 1)
+ return false;
+
+ CSSParserValue* value = m_valueList->current();
+ if (!value)
+ return false;
+
+ if (value->id == CSSValueAuto) {
+ addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
+ return true;
+ } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) {
+ addProperty(propId, createPrimitiveStringValue(value), important);
+ return true;
+ }
+ return false;
+}
+
+// <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
+bool CSSPropertyParser::parseSize(CSSPropertyID propId, bool important)
+{
+ ASSERT(propId == CSSPropertySize);
+
+ if (m_valueList->size() > 2)
+ return false;
+
+ CSSParserValue* value = m_valueList->current();
+ if (!value)
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
+
+ // First parameter.
+ SizeParameterType paramType = parseSizeParameter(parsedValues.get(), value, None);
+ if (paramType == None)
+ return false;
+
+ // Second parameter, if any.
+ value = m_valueList->next();
+ if (value) {
+ paramType = parseSizeParameter(parsedValues.get(), value, paramType);
+ if (paramType == None)
+ return false;
+ }
+
+ addProperty(propId, parsedValues.release(), important);
+ return true;
+}
+
+CSSPropertyParser::SizeParameterType CSSPropertyParser::parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType)
+{
+ switch (value->id) {
+ case CSSValueAuto:
+ if (prevParamType == None) {
+ parsedValues->append(cssValuePool().createIdentifierValue(value->id));
+ return Auto;
+ }
+ return None;
+ case CSSValueLandscape:
+ case CSSValuePortrait:
+ if (prevParamType == None || prevParamType == PageSize) {
+ parsedValues->append(cssValuePool().createIdentifierValue(value->id));
+ return Orientation;
+ }
+ return None;
+ case CSSValueA3:
+ case CSSValueA4:
+ case CSSValueA5:
+ case CSSValueB4:
+ case CSSValueB5:
+ case CSSValueLedger:
+ case CSSValueLegal:
+ case CSSValueLetter:
+ if (prevParamType == None || prevParamType == Orientation) {
+ // Normalize to Page Size then Orientation order by prepending.
+ // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (StyleResolver::applyPageSizeProperty).
+ parsedValues->prepend(cssValuePool().createIdentifierValue(value->id));
+ return PageSize;
+ }
+ return None;
+ case 0:
+ if (validUnit(value, FLength | FNonNeg) && (prevParamType == None || prevParamType == Length)) {
+ parsedValues->append(createPrimitiveNumericValue(value));
+ return Length;
+ }
+ return None;
+ default:
+ return None;
+ }
+}
+
+// [ <string> <string> ]+ | inherit | none
+// inherit and none are handled in parseValue.
+bool CSSPropertyParser::parseQuotes(CSSPropertyID propId, bool important)
+{
+ RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+ while (CSSParserValue* val = m_valueList->current()) {
+ RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr;
+ if (val->unit == CSSPrimitiveValue::CSS_STRING)
+ parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
+ else
+ break;
+ values->append(parsedValue.release());
+ m_valueList->next();
+ }
+ if (values->length()) {
+ addProperty(propId, values.release(), important);
+ m_valueList->next();
+ return true;
+ }
+ return false;
+}
+
+// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
+// in CSS 2.1 this got somewhat reduced:
+// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
+bool CSSPropertyParser::parseContent(CSSPropertyID propId, bool important)
+{
+ RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+
+ while (CSSParserValue* val = m_valueList->current()) {
+ RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr;
+ if (val->unit == CSSPrimitiveValue::CSS_URI) {
+ // url
+ parsedValue = createCSSImageValueWithReferrer(val->string, completeURL(val->string));
+ } else if (val->unit == CSSParserValue::Function) {
+ // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...)
+ CSSParserValueList* args = val->function->args.get();
+ if (!args)
+ return false;
+ if (equalIgnoringCase(val->function->name, "attr(")) {
+ parsedValue = parseAttr(args);
+ if (!parsedValue)
+ return false;
+ } else if (equalIgnoringCase(val->function->name, "counter(")) {
+ parsedValue = parseCounterContent(args, false);
+ if (!parsedValue)
+ return false;
+ } else if (equalIgnoringCase(val->function->name, "counters(")) {
+ parsedValue = parseCounterContent(args, true);
+ if (!parsedValue)
+ return false;
+ } else if (equalIgnoringCase(val->function->name, "-webkit-image-set(")) {
+ parsedValue = parseImageSet(m_valueList.get());
+ if (!parsedValue)
+ return false;
+ } else if (isGeneratedImageValue(val)) {
+ if (!parseGeneratedImage(m_valueList.get(), parsedValue))
+ return false;
+ } else
+ return false;
+ } else if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
+ // open-quote
+ // close-quote
+ // no-open-quote
+ // no-close-quote
+ // inherit
+ // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503).
+ // none
+ // normal
+ switch (val->id) {
+ case CSSValueOpenQuote:
+ case CSSValueCloseQuote:
+ case CSSValueNoOpenQuote:
+ case CSSValueNoCloseQuote:
+ case CSSValueNone:
+ case CSSValueNormal:
+ parsedValue = cssValuePool().createIdentifierValue(val->id);
+ default:
+ break;
+ }
+ } else if (val->unit == CSSPrimitiveValue::CSS_STRING) {
+ parsedValue = createPrimitiveStringValue(val);
+ }
+ if (!parsedValue)
+ break;
+ values->append(parsedValue.release());
+ m_valueList->next();
+ }
+
+ if (values->length()) {
+ addProperty(propId, values.release(), important);
+ m_valueList->next();
+ return true;
+ }
+
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAttr(CSSParserValueList* args)
+{
+ if (args->size() != 1)
+ return nullptr;
+
+ CSSParserValue* a = args->current();
+
+ if (a->unit != CSSPrimitiveValue::CSS_IDENT)
+ return nullptr;
+
+ String attrName = a->string;
+ // CSS allows identifiers with "-" at the start, like "-webkit-mask-image".
+ // But HTML attribute names can't have those characters, and we should not
+ // even parse them inside attr().
+ if (attrName[0] == '-')
+ return nullptr;
+
+ if (m_context.isHTMLDocument())
+ attrName = attrName.lower();
+
+ return cssValuePool().createValue(attrName, CSSPrimitiveValue::CSS_ATTR);
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseBackgroundColor()
+{
+ CSSValueID id = m_valueList->current()->id;
+ if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor ||
+ (id >= CSSValueGrey && id < CSSValueWebkitText && inQuirksMode()))
+ return cssValuePool().createIdentifierValue(id);
+ return parseColor();
+}
+
+bool CSSPropertyParser::parseFillImage(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value)
+{
+ if (valueList->current()->id == CSSValueNone) {
+ value = cssValuePool().createIdentifierValue(CSSValueNone);
+ return true;
+ }
+ if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) {
+ value = createCSSImageValueWithReferrer(valueList->current()->string, completeURL(valueList->current()->string));
+ return true;
+ }
+
+ if (isGeneratedImageValue(valueList->current()))
+ return parseGeneratedImage(valueList, value);
+
+ if (valueList->current()->unit == CSSParserValue::Function && equalIgnoringCase(valueList->current()->function->name, "-webkit-image-set(")) {
+ value = parseImageSet(m_valueList.get());
+ if (value)
+ return true;
+ }
+
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseFillPositionX(CSSParserValueList* valueList)
+{
+ int id = valueList->current()->id;
+ if (id == CSSValueLeft || id == CSSValueRight || id == CSSValueCenter) {
+ int percent = 0;
+ if (id == CSSValueRight)
+ percent = 100;
+ else if (id == CSSValueCenter)
+ percent = 50;
+ return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
+ if (validUnit(valueList->current(), FPercent | FLength))
+ return createPrimitiveNumericValue(valueList->current());
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseFillPositionY(CSSParserValueList* valueList)
+{
+ int id = valueList->current()->id;
+ if (id == CSSValueTop || id == CSSValueBottom || id == CSSValueCenter) {
+ int percent = 0;
+ if (id == CSSValueBottom)
+ percent = 100;
+ else if (id == CSSValueCenter)
+ percent = 50;
+ return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
+ if (validUnit(valueList->current(), FPercent | FLength))
+ return createPrimitiveNumericValue(valueList->current());
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseFillPositionComponent(CSSParserValueList* valueList, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode parsingMode)
+{
+ CSSValueID id = valueList->current()->id;
+ if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) {
+ int percent = 0;
+ if (id == CSSValueLeft || id == CSSValueRight) {
+ if (cumulativeFlags & XFillPosition)
+ return nullptr;
+ cumulativeFlags |= XFillPosition;
+ individualFlag = XFillPosition;
+ if (id == CSSValueRight)
+ percent = 100;
+ }
+ else if (id == CSSValueTop || id == CSSValueBottom) {
+ if (cumulativeFlags & YFillPosition)
+ return nullptr;
+ cumulativeFlags |= YFillPosition;
+ individualFlag = YFillPosition;
+ if (id == CSSValueBottom)
+ percent = 100;
+ } else if (id == CSSValueCenter) {
+ // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
+ percent = 50;
+ cumulativeFlags |= AmbiguousFillPosition;
+ individualFlag = AmbiguousFillPosition;
+ }
+
+ if (parsingMode == ResolveValuesAsKeyword)
+ return cssValuePool().createIdentifierValue(id);
+
+ return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
+ if (validUnit(valueList->current(), FPercent | FLength)) {
+ if (!cumulativeFlags) {
+ cumulativeFlags |= XFillPosition;
+ individualFlag = XFillPosition;
+ } else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) {
+ cumulativeFlags |= YFillPosition;
+ individualFlag = YFillPosition;
+ } else {
+ if (m_parsedCalculation)
+ m_parsedCalculation.release();
+ return nullptr;
+ }
+ return createPrimitiveNumericValue(valueList->current());
+ }
+ return nullptr;
+}
+
+static bool isValueConflictingWithCurrentEdge(int value1, int value2)
+{
+ if ((value1 == CSSValueLeft || value1 == CSSValueRight) && (value2 == CSSValueLeft || value2 == CSSValueRight))
+ return true;
+
+ if ((value1 == CSSValueTop || value1 == CSSValueBottom) && (value2 == CSSValueTop || value2 == CSSValueBottom))
+ return true;
+
+ return false;
+}
+
+static bool isFillPositionKeyword(CSSValueID value)
+{
+ return value == CSSValueLeft || value == CSSValueTop || value == CSSValueBottom || value == CSSValueRight || value == CSSValueCenter;
+}
+
+void CSSPropertyParser::parse4ValuesFillPosition(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2)
+{
+ // [ left | right ] [ <percentage] | <length> ] && [ top | bottom ] [ <percentage> | <length> ]
+ // In the case of 4 values <position> requires the second value to be a length or a percentage.
+ if (isFillPositionKeyword(parsedValue2->getValueID()))
+ return;
+
+ unsigned cumulativeFlags = 0;
+ FillPositionFlag value3Flag = InvalidFillPosition;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
+ if (!value3)
+ return;
+
+ CSSValueID ident1 = parsedValue1->getValueID();
+ CSSValueID ident3 = value3->getValueID();
+
+ if (ident1 == CSSValueCenter)
+ return;
+
+ if (!isFillPositionKeyword(ident3) || ident3 == CSSValueCenter)
+ return;
+
+ // We need to check if the values are not conflicting, e.g. they are not on the same edge. It is
+ // needed as the second call to parseFillPositionComponent was on purpose not checking it. In the
+ // case of two values top 20px is invalid but in the case of 4 values it becomes valid.
+ if (isValueConflictingWithCurrentEdge(ident1, ident3))
+ return;
+
+ valueList->next();
+
+ cumulativeFlags = 0;
+ FillPositionFlag value4Flag = InvalidFillPosition;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> value4 = parseFillPositionComponent(valueList, cumulativeFlags, value4Flag, ResolveValuesAsKeyword);
+ if (!value4)
+ return;
+
+ // 4th value must be a length or a percentage.
+ if (isFillPositionKeyword(value4->getValueID()))
+ return;
+
+ value1 = createPrimitiveValuePair(parsedValue1, parsedValue2);
+ value2 = createPrimitiveValuePair(value3, value4);
+
+ if (ident1 == CSSValueTop || ident1 == CSSValueBottom)
+ value1.swap(value2);
+
+ valueList->next();
+}
+void CSSPropertyParser::parse3ValuesFillPosition(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2)
+{
+ unsigned cumulativeFlags = 0;
+ FillPositionFlag value3Flag = InvalidFillPosition;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
+
+ // value3 is not an expected value, we return.
+ if (!value3)
+ return;
+
+ valueList->next();
+
+ bool swapNeeded = false;
+ CSSValueID ident1 = parsedValue1->getValueID();
+ CSSValueID ident2 = parsedValue2->getValueID();
+ CSSValueID ident3 = value3->getValueID();
+
+ CSSValueID firstPositionKeyword;
+ CSSValueID secondPositionKeyword;
+
+ if (ident1 == CSSValueCenter) {
+ // <position> requires the first 'center' to be followed by a keyword.
+ if (!isFillPositionKeyword(ident2))
+ return;
+
+ // If 'center' is the first keyword then the last one needs to be a length.
+ if (isFillPositionKeyword(ident3))
+ return;
+
+ firstPositionKeyword = CSSValueLeft;
+ if (ident2 == CSSValueLeft || ident2 == CSSValueRight) {
+ firstPositionKeyword = CSSValueTop;
+ swapNeeded = true;
+ }
+ value1 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(firstPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+ value2 = createPrimitiveValuePair(parsedValue2, value3);
+ } else if (ident3 == CSSValueCenter) {
+ if (isFillPositionKeyword(ident2))
+ return;
+
+ secondPositionKeyword = CSSValueTop;
+ if (ident1 == CSSValueTop || ident1 == CSSValueBottom) {
+ secondPositionKeyword = CSSValueLeft;
+ swapNeeded = true;
+ }
+ value1 = createPrimitiveValuePair(parsedValue1, parsedValue2);
+ value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+ } else {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> firstPositionValue = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> secondPositionValue = nullptr;
+
+ if (isFillPositionKeyword(ident2)) {
+ // To match CSS grammar, we should only accept: [ center | left | right | bottom | top ] [ left | right | top | bottom ] [ <percentage> | <length> ].
+ ASSERT(ident2 != CSSValueCenter);
+
+ if (isFillPositionKeyword(ident3))
+ return;
+
+ secondPositionValue = value3;
+ secondPositionKeyword = ident2;
+ firstPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
+ } else {
+ // Per CSS, we should only accept: [ right | left | top | bottom ] [ <percentage> | <length> ] [ center | left | right | bottom | top ].
+ if (!isFillPositionKeyword(ident3))
+ return;
+
+ firstPositionValue = parsedValue2;
+ secondPositionKeyword = ident3;
+ secondPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
+ }
+
+ if (isValueConflictingWithCurrentEdge(ident1, secondPositionKeyword))
+ return;
+
+ value1 = createPrimitiveValuePair(parsedValue1, firstPositionValue);
+ value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), secondPositionValue);
+ }
+
+ if (ident1 == CSSValueTop || ident1 == CSSValueBottom || swapNeeded)
+ value1.swap(value2);
+
+#ifndef NDEBUG
+ CSSPrimitiveValue* first = toCSSPrimitiveValue(value1.get());
+ CSSPrimitiveValue* second = toCSSPrimitiveValue(value2.get());
+ ident1 = first->getPairValue()->first()->getValueID();
+ ident2 = second->getPairValue()->first()->getValueID();
+ ASSERT(ident1 == CSSValueLeft || ident1 == CSSValueRight);
+ ASSERT(ident2 == CSSValueBottom || ident2 == CSSValueTop);
+#endif
+}
+
+inline bool CSSPropertyParser::isPotentialPositionValue(CSSParserValue* value)
+{
+ return isFillPositionKeyword(value->id) || validUnit(value, FPercent | FLength, ReleaseParsedCalcValue);
+}
+
+void CSSPropertyParser::parseFillPosition(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2)
+{
+ unsigned numberOfValues = 0;
+ for (unsigned i = valueList->currentIndex(); i < valueList->size(); ++i, ++numberOfValues) {
+ CSSParserValue* current = valueList->valueAt(i);
+ if (isComma(current) || !current || isForwardSlashOperator(current) || !isPotentialPositionValue(current))
+ break;
+ }
+
+ if (numberOfValues > 4)
+ return;
+
+ // If we are parsing two values, we can safely call the CSS 2.1 parsing function and return.
+ if (numberOfValues <= 2) {
+ parse2ValuesFillPosition(valueList, value1, value2);
+ return;
+ }
+
+ ASSERT(numberOfValues > 2 && numberOfValues <= 4);
+
+ CSSParserValue* value = valueList->current();
+
+ // <position> requires the first value to be a background keyword.
+ if (!isFillPositionKeyword(value->id))
+ return;
+
+ // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
+ unsigned cumulativeFlags = 0;
+ FillPositionFlag value1Flag = InvalidFillPosition;
+ FillPositionFlag value2Flag = InvalidFillPosition;
+ value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag, ResolveValuesAsKeyword);
+ if (!value1)
+ return;
+
+ valueList->next();
+
+ // In case we are parsing more than two values, relax the check inside of parseFillPositionComponent. top 20px is
+ // a valid start for <position>.
+ cumulativeFlags = AmbiguousFillPosition;
+ value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag, ResolveValuesAsKeyword);
+ if (value2)
+ valueList->next();
+ else {
+ value1.clear();
+ return;
+ }
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1 = toCSSPrimitiveValue(value1.get());
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2 = toCSSPrimitiveValue(value2.get());
+
+ value1.clear();
+ value2.clear();
+
+ // Per CSS3 syntax, <position> can't have 'center' as its second keyword as we have more arguments to follow.
+ if (parsedValue2->getValueID() == CSSValueCenter)
+ return;
+
+ if (numberOfValues == 3)
+ parse3ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release());
+ else
+ parse4ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release());
+}
+
+void CSSPropertyParser::parse2ValuesFillPosition(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2)
+{
+ // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
+ unsigned cumulativeFlags = 0;
+ FillPositionFlag value1Flag = InvalidFillPosition;
+ FillPositionFlag value2Flag = InvalidFillPosition;
+ value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag);
+ if (!value1)
+ return;
+
+ // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
+ // can assume that any other values belong to the rest of the shorthand). If we're not parsing a shorthand, though, the
+ // value was explicitly specified for our property.
+ CSSParserValue* value = valueList->next();
+
+ // First check for the comma. If so, we are finished parsing this value or value pair.
+ if (isComma(value))
+ value = 0;
+
+ if (value) {
+ value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag);
+ if (value2)
+ valueList->next();
+ else {
+ if (!inShorthand()) {
+ value1.clear();
+ return;
+ }
+ }
+ }
+
+ if (!value2)
+ // Only one value was specified. If that value was not a keyword, then it sets the x position, and the y position
+ // is simply 50%. This is our default.
+ // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
+ // For left/right/center, the default of 50% in the y is still correct.
+ value2 = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+
+ if (value1Flag == YFillPosition || value2Flag == XFillPosition)
+ value1.swap(value2);
+}
+
+void CSSPropertyParser::parseFillRepeat(RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2)
+{
+ CSSValueID id = m_valueList->current()->id;
+ if (id == CSSValueRepeatX) {
+ m_implicitShorthand = true;
+ value1 = cssValuePool().createIdentifierValue(CSSValueRepeat);
+ value2 = cssValuePool().createIdentifierValue(CSSValueNoRepeat);
+ m_valueList->next();
+ return;
+ }
+ if (id == CSSValueRepeatY) {
+ m_implicitShorthand = true;
+ value1 = cssValuePool().createIdentifierValue(CSSValueNoRepeat);
+ value2 = cssValuePool().createIdentifierValue(CSSValueRepeat);
+ m_valueList->next();
+ return;
+ }
+ if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
+ value1 = cssValuePool().createIdentifierValue(id);
+ else {
+ value1 = nullptr;
+ return;
+ }
+
+ CSSParserValue* value = m_valueList->next();
+
+ // Parse the second value if one is available
+ if (value && !isComma(value)) {
+ id = value->id;
+ if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) {
+ value2 = cssValuePool().createIdentifierValue(id);
+ m_valueList->next();
+ return;
+ }
+ }
+
+ // If only one value was specified, value2 is the same as value1.
+ m_implicitShorthand = true;
+ value2 = cssValuePool().createIdentifierValue(toCSSPrimitiveValue(value1.get())->getValueID());
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseFillSize(CSSPropertyID propId, bool& allowComma)
+{
+ allowComma = true;
+ CSSParserValue* value = m_valueList->current();
+
+ if (value->id == CSSValueContain || value->id == CSSValueCover)
+ return cssValuePool().createIdentifierValue(value->id);
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1 = nullptr;
+
+ if (value->id == CSSValueAuto)
+ parsedValue1 = cssValuePool().createIdentifierValue(CSSValueAuto);
+ else {
+ if (!validUnit(value, FLength | FPercent))
+ return nullptr;
+ parsedValue1 = createPrimitiveNumericValue(value);
+ }
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2 = nullptr;
+ if ((value = m_valueList->next())) {
+ if (value->unit == CSSParserValue::Operator && value->iValue == ',')
+ allowComma = false;
+ else if (value->id != CSSValueAuto) {
+ if (!validUnit(value, FLength | FPercent)) {
+ if (!inShorthand())
+ return nullptr;
+ // We need to rewind the value list, so that when it is advanced we'll end up back at this value.
+ m_valueList->previous();
+ } else
+ parsedValue2 = createPrimitiveNumericValue(value);
+ }
+ } else if (!parsedValue2 && propId == CSSPropertyWebkitBackgroundSize) {
+ // For backwards compatibility we set the second value to the first if it is omitted.
+ // We only need to do this for -webkit-background-size. It should be safe to let masks match
+ // the real property.
+ parsedValue2 = parsedValue1;
+ }
+
+ if (!parsedValue2)
+ return parsedValue1;
+
+ Pair::IdenticalValuesPolicy policy = propId == CSSPropertyWebkitBackgroundSize ?
+ Pair::DropIdenticalValues : Pair::KeepIdenticalValues;
+
+ return createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release(), policy);
+}
+
+bool CSSPropertyParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2,
+ RefPtrWillBeRawPtr<CSSValue>& retValue1, RefPtrWillBeRawPtr<CSSValue>& retValue2)
+{
+ RefPtrWillBeRawPtr<CSSValueList> values = nullptr;
+ RefPtrWillBeRawPtr<CSSValueList> values2 = nullptr;
+ CSSParserValue* val;
+ RefPtrWillBeRawPtr<CSSValue> value = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> value2 = nullptr;
+
+ bool allowComma = false;
+
+ retValue1 = retValue2 = nullptr;
+ propId1 = propId;
+ propId2 = propId;
+ if (propId == CSSPropertyBackgroundPosition) {
+ propId1 = CSSPropertyBackgroundPositionX;
+ propId2 = CSSPropertyBackgroundPositionY;
+ } else if (propId == CSSPropertyWebkitMaskPosition) {
+ propId1 = CSSPropertyWebkitMaskPositionX;
+ propId2 = CSSPropertyWebkitMaskPositionY;
+ } else if (propId == CSSPropertyBackgroundRepeat) {
+ propId1 = CSSPropertyBackgroundRepeatX;
+ propId2 = CSSPropertyBackgroundRepeatY;
+ } else if (propId == CSSPropertyWebkitMaskRepeat) {
+ propId1 = CSSPropertyWebkitMaskRepeatX;
+ propId2 = CSSPropertyWebkitMaskRepeatY;
+ }
+
+ while ((val = m_valueList->current())) {
+ RefPtrWillBeRawPtr<CSSValue> currValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> currValue2 = nullptr;
+
+ if (allowComma) {
+ if (!isComma(val))
+ return false;
+ m_valueList->next();
+ allowComma = false;
+ } else {
+ allowComma = true;
+ switch (propId) {
+ case CSSPropertyBackgroundColor:
+ currValue = parseBackgroundColor();
+ if (currValue)
+ m_valueList->next();
+ break;
+ case CSSPropertyBackgroundAttachment:
+ if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) {
+ currValue = cssValuePool().createIdentifierValue(val->id);
+ m_valueList->next();
+ }
+ break;
+ case CSSPropertyBackgroundImage:
+ case CSSPropertyWebkitMaskImage:
+ if (parseFillImage(m_valueList.get(), currValue))
+ m_valueList->next();
+ break;
+ case CSSPropertyWebkitBackgroundClip:
+ case CSSPropertyWebkitBackgroundOrigin:
+ case CSSPropertyWebkitMaskClip:
+ case CSSPropertyWebkitMaskOrigin:
+ // The first three values here are deprecated and do not apply to the version of the property that has
+ // the -webkit- prefix removed.
+ if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent ||
+ val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox ||
+ ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) &&
+ (val->id == CSSValueText || val->id == CSSValueWebkitText))) {
+ currValue = cssValuePool().createIdentifierValue(val->id);
+ m_valueList->next();
+ }
+ break;
+ case CSSPropertyBackgroundClip:
+ if (parseBackgroundClip(val, currValue))
+ m_valueList->next();
+ break;
+ case CSSPropertyBackgroundOrigin:
+ if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) {
+ currValue = cssValuePool().createIdentifierValue(val->id);
+ m_valueList->next();
+ }
+ break;
+ case CSSPropertyBackgroundPosition:
+ case CSSPropertyWebkitMaskPosition:
+ parseFillPosition(m_valueList.get(), currValue, currValue2);
+ // parseFillPosition advances the m_valueList pointer.
+ break;
+ case CSSPropertyBackgroundPositionX:
+ case CSSPropertyWebkitMaskPositionX: {
+ currValue = parseFillPositionX(m_valueList.get());
+ if (currValue)
+ m_valueList->next();
+ break;
+ }
+ case CSSPropertyBackgroundPositionY:
+ case CSSPropertyWebkitMaskPositionY: {
+ currValue = parseFillPositionY(m_valueList.get());
+ if (currValue)
+ m_valueList->next();
+ break;
+ }
+ case CSSPropertyWebkitBackgroundComposite:
+ case CSSPropertyWebkitMaskComposite:
+ if (val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) {
+ currValue = cssValuePool().createIdentifierValue(val->id);
+ m_valueList->next();
+ }
+ break;
+ case CSSPropertyBackgroundBlendMode:
+ if (val->id == CSSValueNormal || val->id == CSSValueMultiply
+ || val->id == CSSValueScreen || val->id == CSSValueOverlay || val->id == CSSValueDarken
+ || val->id == CSSValueLighten || val->id == CSSValueColorDodge || val->id == CSSValueColorBurn
+ || val->id == CSSValueHardLight || val->id == CSSValueSoftLight || val->id == CSSValueDifference
+ || val->id == CSSValueExclusion || val->id == CSSValueHue || val->id == CSSValueSaturation
+ || val->id == CSSValueColor || val->id == CSSValueLuminosity) {
+ currValue = cssValuePool().createIdentifierValue(val->id);
+ m_valueList->next();
+ }
+ break;
+ case CSSPropertyBackgroundRepeat:
+ case CSSPropertyWebkitMaskRepeat:
+ parseFillRepeat(currValue, currValue2);
+ // parseFillRepeat advances the m_valueList pointer
+ break;
+ case CSSPropertyBackgroundSize:
+ case CSSPropertyWebkitBackgroundSize:
+ case CSSPropertyWebkitMaskSize: {
+ currValue = parseFillSize(propId, allowComma);
+ if (currValue)
+ m_valueList->next();
+ break;
+ }
+ case CSSPropertyMaskSourceType: {
+ if (RuntimeEnabledFeatures::cssMaskSourceTypeEnabled()) {
+ if (val->id == CSSValueAuto || val->id == CSSValueAlpha || val->id == CSSValueLuminance) {
+ currValue = cssValuePool().createIdentifierValue(val->id);
+ m_valueList->next();
+ } else {
+ currValue = nullptr;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if (!currValue)
+ return false;
+
+ if (value && !values) {
+ values = CSSValueList::createCommaSeparated();
+ values->append(value.release());
+ }
+
+ if (value2 && !values2) {
+ values2 = CSSValueList::createCommaSeparated();
+ values2->append(value2.release());
+ }
+
+ if (values)
+ values->append(currValue.release());
+ else
+ value = currValue.release();
+ if (currValue2) {
+ if (values2)
+ values2->append(currValue2.release());
+ else
+ value2 = currValue2.release();
+ }
+ }
+
+ // When parsing any fill shorthand property, we let it handle building up the lists for all
+ // properties.
+ if (inShorthand())
+ break;
+ }
+
+ if (values && values->length()) {
+ retValue1 = values.release();
+ if (values2 && values2->length())
+ retValue2 = values2.release();
+ return true;
+ }
+ if (value) {
+ retValue1 = value.release();
+ retValue2 = value2.release();
+ return true;
+ }
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationDelay()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (validUnit(value, FTime))
+ return createPrimitiveNumericValue(value);
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationDirection()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (value->id == CSSValueNormal || value->id == CSSValueAlternate || value->id == CSSValueReverse || value->id == CSSValueAlternateReverse)
+ return cssValuePool().createIdentifierValue(value->id);
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationDuration()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (validUnit(value, FTime | FNonNeg))
+ return createPrimitiveNumericValue(value);
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationFillMode()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth)
+ return cssValuePool().createIdentifierValue(value->id);
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationIterationCount()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (value->id == CSSValueInfinite)
+ return cssValuePool().createIdentifierValue(value->id);
+ if (validUnit(value, FNumber | FNonNeg))
+ return createPrimitiveNumericValue(value);
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationName()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) {
+ if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value, "none"))) {
+ return cssValuePool().createIdentifierValue(CSSValueNone);
+ } else {
+ return createPrimitiveStringValue(value);
+ }
+ }
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationPlayState()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (value->id == CSSValueRunning || value->id == CSSValuePaused)
+ return cssValuePool().createIdentifierValue(value->id);
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationProperty()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (value->unit != CSSPrimitiveValue::CSS_IDENT)
+ return nullptr;
+ // Since all is valid css property keyword, cssPropertyID for all
+ // returns non-null value. We need to check "all" before
+ // cssPropertyID check.
+ if (equalIgnoringCase(value, "all"))
+ return cssValuePool().createIdentifierValue(CSSValueAll);
+ CSSPropertyID result = cssPropertyID(value->string);
+ if (result && RuntimeCSSEnabled::isCSSPropertyEnabled(result))
+ return cssValuePool().createIdentifierValue(result);
+ if (equalIgnoringCase(value, "none"))
+ return cssValuePool().createIdentifierValue(CSSValueNone);
+ if (equalIgnoringCase(value, "inherit") || equalIgnoringCase(value, "initial"))
+ return nullptr;
+ return createPrimitiveStringValue(value);
+}
+
+bool CSSPropertyParser::parseWebkitTransformOriginShorthand(RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2, RefPtrWillBeRawPtr<CSSValue>& value3)
+{
+ parse2ValuesFillPosition(m_valueList.get(), value1, value2);
+
+ // now get z
+ if (m_valueList->current()) {
+ if (validUnit(m_valueList->current(), FLength)) {
+ value3 = createPrimitiveNumericValue(m_valueList->current());
+ m_valueList->next();
+ return true;
+ }
+ return false;
+ }
+ value3 = cssValuePool().createImplicitInitialValue();
+ return true;
+}
+
+bool CSSPropertyParser::parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result)
+{
+ CSSParserValue* v = args->current();
+ if (!validUnit(v, FNumber))
+ return false;
+ result = v->fValue;
+ v = args->next();
+ if (!v)
+ // The last number in the function has no comma after it, so we're done.
+ return true;
+ if (!isComma(v))
+ return false;
+ args->next();
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationTimingFunction()
+{
+ CSSParserValue* value = m_valueList->current();
+ if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut
+ || value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd
+ || (value->id == CSSValueStepMiddle && RuntimeEnabledFeatures::webAnimationsElementAnimateEnabled()))
+ return cssValuePool().createIdentifierValue(value->id);
+
+ // We must be a function.
+ if (value->unit != CSSParserValue::Function)
+ return nullptr;
+
+ CSSParserValueList* args = value->function->args.get();
+
+ if (equalIgnoringCase(value->function->name, "steps(")) {
+ // For steps, 1 or 2 params must be specified (comma-separated)
+ if (!args || (args->size() != 1 && args->size() != 3))
+ return nullptr;
+
+ // There are two values.
+ int numSteps;
+ StepsTimingFunction::StepAtPosition stepAtPosition = StepsTimingFunction::StepAtEnd;
+
+ CSSParserValue* v = args->current();
+ if (!validUnit(v, FInteger))
+ return nullptr;
+ numSteps = clampToInteger(v->fValue);
+ if (numSteps < 1)
+ return nullptr;
+ v = args->next();
+
+ if (v) {
+ // There is a comma so we need to parse the second value
+ if (!isComma(v))
+ return nullptr;
+ v = args->next();
+ switch (v->id) {
+ case CSSValueMiddle:
+ if (!RuntimeEnabledFeatures::webAnimationsAPIEnabled())
+ return nullptr;
+ stepAtPosition = StepsTimingFunction::StepAtMiddle;
+ break;
+ case CSSValueStart:
+ stepAtPosition = StepsTimingFunction::StepAtStart;
+ break;
+ case CSSValueEnd:
+ stepAtPosition = StepsTimingFunction::StepAtEnd;
+ break;
+ default:
+ return nullptr;
+ }
+ }
+
+ return CSSStepsTimingFunctionValue::create(numSteps, stepAtPosition);
+ }
+
+ if (equalIgnoringCase(value->function->name, "cubic-bezier(")) {
+ // For cubic bezier, 4 values must be specified.
+ if (!args || args->size() != 7)
+ return nullptr;
+
+ // There are two points specified. The x values must be between 0 and 1 but the y values can exceed this range.
+ double x1, y1, x2, y2;
+
+ if (!parseCubicBezierTimingFunctionValue(args, x1))
+ return nullptr;
+ if (x1 < 0 || x1 > 1)
+ return nullptr;
+ if (!parseCubicBezierTimingFunctionValue(args, y1))
+ return nullptr;
+ if (!parseCubicBezierTimingFunctionValue(args, x2))
+ return nullptr;
+ if (x2 < 0 || x2 > 1)
+ return nullptr;
+ if (!parseCubicBezierTimingFunctionValue(args, y2))
+ return nullptr;
+
+ return CSSCubicBezierTimingFunctionValue::create(x1, y1, x2, y2);
+ }
+
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationProperty(CSSPropertyID propId)
+{
+ RefPtrWillBeRawPtr<CSSValue> value = nullptr;
+ switch (propId) {
+ case CSSPropertyAnimationDelay:
+ case CSSPropertyWebkitAnimationDelay:
+ case CSSPropertyTransitionDelay:
+ case CSSPropertyWebkitTransitionDelay:
+ value = parseAnimationDelay();
+ break;
+ case CSSPropertyAnimationDirection:
+ case CSSPropertyWebkitAnimationDirection:
+ value = parseAnimationDirection();
+ break;
+ case CSSPropertyAnimationDuration:
+ case CSSPropertyWebkitAnimationDuration:
+ case CSSPropertyTransitionDuration:
+ case CSSPropertyWebkitTransitionDuration:
+ value = parseAnimationDuration();
+ break;
+ case CSSPropertyAnimationFillMode:
+ case CSSPropertyWebkitAnimationFillMode:
+ value = parseAnimationFillMode();
+ break;
+ case CSSPropertyAnimationIterationCount:
+ case CSSPropertyWebkitAnimationIterationCount:
+ value = parseAnimationIterationCount();
+ break;
+ case CSSPropertyAnimationName:
+ case CSSPropertyWebkitAnimationName:
+ value = parseAnimationName();
+ break;
+ case CSSPropertyAnimationPlayState:
+ case CSSPropertyWebkitAnimationPlayState:
+ value = parseAnimationPlayState();
+ break;
+ case CSSPropertyTransitionProperty:
+ case CSSPropertyWebkitTransitionProperty:
+ value = parseAnimationProperty();
+ break;
+ case CSSPropertyAnimationTimingFunction:
+ case CSSPropertyWebkitAnimationTimingFunction:
+ case CSSPropertyTransitionTimingFunction:
+ case CSSPropertyWebkitTransitionTimingFunction:
+ value = parseAnimationTimingFunction();
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return nullptr;
+ }
+
+ if (value)
+ m_valueList->next();
+ return value.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseAnimationPropertyList(CSSPropertyID propId)
+{
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ while (m_valueList->current()) {
+ RefPtrWillBeRawPtr<CSSValue> value = parseAnimationProperty(propId);
+ if (!value)
+ return nullptr;
+ list->append(value.release());
+ if (CSSParserValue* parserValue = m_valueList->current()) {
+ if (!isComma(parserValue))
+ return nullptr;
+ m_valueList->next();
+ ASSERT(m_valueList->current());
+ }
+ }
+ if ((propId == CSSPropertyTransitionProperty || propId == CSSPropertyWebkitTransitionProperty) && !isValidTransitionPropertyList(list.get()))
+ return nullptr;
+ ASSERT(list->length());
+ return list.release();
+}
+
+static inline bool isCSSWideKeyword(CSSParserValue& value)
+{
+ return value.id == CSSValueInitial || value.id == CSSValueInherit || value.id == CSSValueDefault;
+}
+
+static inline bool isValidCustomIdentForGridPositions(CSSParserValue& value)
+{
+ // FIXME: we need a more general solution for <custom-ident> in all properties.
+ return value.unit == CSSPrimitiveValue::CSS_IDENT && value.id != CSSValueSpan && value.id != CSSValueAuto && !isCSSWideKeyword(value);
+}
+
+// The function parses [ <integer> || <custom-ident> ] in <grid-line> (which can be stand alone or with 'span').
+bool CSSPropertyParser::parseIntegerOrCustomIdentFromGridPosition(RefPtrWillBeRawPtr<CSSPrimitiveValue>& numericValue, RefPtrWillBeRawPtr<CSSPrimitiveValue>& gridLineName)
+{
+ CSSParserValue* value = m_valueList->current();
+ if (validUnit(value, FInteger) && value->fValue) {
+ numericValue = createPrimitiveNumericValue(value);
+ value = m_valueList->next();
+ if (value && isValidCustomIdentForGridPositions(*value)) {
+ gridLineName = createPrimitiveStringValue(m_valueList->current());
+ m_valueList->next();
+ }
+ return true;
+ }
+
+ if (isValidCustomIdentForGridPositions(*value)) {
+ gridLineName = createPrimitiveStringValue(m_valueList->current());
+ value = m_valueList->next();
+ if (value && validUnit(value, FInteger) && value->fValue) {
+ numericValue = createPrimitiveNumericValue(value);
+ m_valueList->next();
+ }
+ return true;
+ }
+
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridPosition()
+{
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+ CSSParserValue* value = m_valueList->current();
+ if (value->id == CSSValueAuto) {
+ m_valueList->next();
+ return cssValuePool().createIdentifierValue(CSSValueAuto);
+ }
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> numericValue = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> gridLineName = nullptr;
+ bool hasSeenSpanKeyword = false;
+
+ if (parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName)) {
+ value = m_valueList->current();
+ if (value && value->id == CSSValueSpan) {
+ hasSeenSpanKeyword = true;
+ m_valueList->next();
+ }
+ } else if (value->id == CSSValueSpan) {
+ hasSeenSpanKeyword = true;
+ if (CSSParserValue* nextValue = m_valueList->next()) {
+ if (!isForwardSlashOperator(nextValue) && !parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName))
+ return nullptr;
+ }
+ }
+
+ // Check that we have consumed all the value list. For shorthands, the parser will pass
+ // the whole value list (including the opposite position).
+ if (m_valueList->current() && !isForwardSlashOperator(m_valueList->current()))
+ return nullptr;
+
+ // If we didn't parse anything, this is not a valid grid position.
+ if (!hasSeenSpanKeyword && !gridLineName && !numericValue)
+ return nullptr;
+
+ // Negative numbers are not allowed for span (but are for <integer>).
+ if (hasSeenSpanKeyword && numericValue && numericValue->getIntValue() < 0)
+ return nullptr;
+
+ // For the <custom-ident> case.
+ if (gridLineName && !numericValue && !hasSeenSpanKeyword)
+ return cssValuePool().createValue(gridLineName->getStringValue(), CSSPrimitiveValue::CSS_STRING);
+
+ RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
+ if (hasSeenSpanKeyword)
+ values->append(cssValuePool().createIdentifierValue(CSSValueSpan));
+ if (numericValue)
+ values->append(numericValue.release());
+ if (gridLineName)
+ values->append(gridLineName.release());
+ ASSERT(values->length());
+ return values.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> gridMissingGridPositionValue(CSSValue* value)
+{
+ if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->isString())
+ return value;
+
+ return cssValuePool().createIdentifierValue(CSSValueAuto);
+}
+
+bool CSSPropertyParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool important)
+{
+ ShorthandScope scope(this, shorthandId);
+ const StylePropertyShorthand& shorthand = shorthandForProperty(shorthandId);
+ ASSERT(shorthand.length() == 2);
+
+ RefPtrWillBeRawPtr<CSSValue> startValue = parseGridPosition();
+ if (!startValue)
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValue> endValue = nullptr;
+ if (m_valueList->current()) {
+ if (!isForwardSlashOperator(m_valueList->current()))
+ return false;
+
+ if (!m_valueList->next())
+ return false;
+
+ endValue = parseGridPosition();
+ if (!endValue || m_valueList->current())
+ return false;
+ } else {
+ endValue = gridMissingGridPositionValue(startValue.get());
+ }
+
+ addProperty(shorthand.properties()[0], startValue, important);
+ addProperty(shorthand.properties()[1], endValue, important);
+ return true;
+}
+
+bool CSSPropertyParser::parseGridTemplateRowsAndAreas(PassRefPtrWillBeRawPtr<CSSValue> templateColumns, bool important)
+{
+ NamedGridAreaMap gridAreaMap;
+ size_t rowCount = 0;
+ size_t columnCount = 0;
+ bool trailingIdentWasAdded = false;
+ RefPtrWillBeRawPtr<CSSValueList> templateRows = CSSValueList::createSpaceSeparated();
+
+ // At least template-areas strings must be defined.
+ if (!m_valueList->current())
+ return false;
+
+ while (m_valueList->current()) {
+ // Handle leading <custom-ident>*.
+ if (m_valueList->current()->unit == CSSParserValue::ValueList) {
+ if (trailingIdentWasAdded) {
+ // A row's trailing ident must be concatenated with the next row's leading one.
+ parseGridLineNames(*m_valueList, *templateRows, static_cast<CSSGridLineNamesValue*>(templateRows->item(templateRows->length() - 1)));
+ } else {
+ parseGridLineNames(*m_valueList, *templateRows);
+ }
+ }
+
+ // Handle a template-area's row.
+ if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
+ return false;
+ ++rowCount;
+
+ // Handle template-rows's track-size.
+ if (m_valueList->current() && m_valueList->current()->unit != CSSParserValue::ValueList && m_valueList->current()->unit != CSSPrimitiveValue::CSS_STRING) {
+ RefPtrWillBeRawPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
+ if (!value)
+ return false;
+ templateRows->append(value);
+ } else {
+ templateRows->append(cssValuePool().createIdentifierValue(CSSValueAuto));
+ }
+
+ // This will handle the trailing/leading <custom-ident>* in the grammar.
+ trailingIdentWasAdded = false;
+ if (m_valueList->current() && m_valueList->current()->unit == CSSParserValue::ValueList) {
+ parseGridLineNames(*m_valueList, *templateRows);
+ trailingIdentWasAdded = true;
+ }
+ }
+
+ // [<track-list> /]?
+ if (templateColumns)
+ addProperty(CSSPropertyGridTemplateColumns, templateColumns, important);
+ else
+ addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentifierValue(CSSValueNone), important);
+
+ // [<line-names>? <string> [<track-size> <line-names>]? ]+
+ RefPtrWillBeRawPtr<CSSValue> templateAreas = CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
+ addProperty(CSSPropertyGridTemplateAreas, templateAreas.release(), important);
+ addProperty(CSSPropertyGridTemplateRows, templateRows.release(), important);
+
+
+ return true;
+}
+
+
+bool CSSPropertyParser::parseGridTemplateShorthand(bool important)
+{
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+ ShorthandScope scope(this, CSSPropertyGridTemplate);
+ ASSERT(gridTemplateShorthand().length() == 3);
+
+ // At least "none" must be defined.
+ if (!m_valueList->current())
+ return false;
+
+ bool firstValueIsNone = m_valueList->current()->id == CSSValueNone;
+
+ // 1- 'none' case.
+ if (firstValueIsNone && !m_valueList->next()) {
+ addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ addProperty(CSSPropertyGridTemplateRows, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ return true;
+ }
+
+ unsigned index = 0;
+ RefPtrWillBeRawPtr<CSSValue> columnsValue = nullptr;
+ if (firstValueIsNone) {
+ columnsValue = cssValuePool().createIdentifierValue(CSSValueNone);
+ } else {
+ columnsValue = parseGridTrackList(important);
+ }
+
+ // 2- <grid-template-columns> / <grid-template-columns> syntax.
+ if (columnsValue) {
+ if (!(m_valueList->current() && isForwardSlashOperator(m_valueList->current()) && m_valueList->next()))
+ return false;
+ index = m_valueList->currentIndex();
+ if (RefPtrWillBeRawPtr<CSSValue> rowsValue = parseGridTrackList(important)) {
+ if (m_valueList->current())
+ return false;
+ addProperty(CSSPropertyGridTemplateColumns, columnsValue, important);
+ addProperty(CSSPropertyGridTemplateRows, rowsValue, important);
+ addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ return true;
+ }
+ }
+
+
+ // 3- [<track-list> /]? [<line-names>? <string> [<track-size> <line-names>]? ]+ syntax.
+ // The template-columns <track-list> can't be 'none'.
+ if (firstValueIsNone)
+ return false;
+ // It requires to rewind parsing due to previous syntax failures.
+ m_valueList->setCurrentIndex(index);
+ return parseGridTemplateRowsAndAreas(columnsValue, important);
+}
+
+bool CSSPropertyParser::parseGridShorthand(bool important)
+{
+ ShorthandScope scope(this, CSSPropertyGrid);
+ ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 4);
+
+ // 1- <grid-template>
+ if (parseGridTemplateShorthand(important)) {
+ // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
+ // The sub-properties not specified are set to their initial value, as normal for shorthands.
+ addProperty(CSSPropertyGridAutoFlow, cssValuePool().createImplicitInitialValue(), important);
+ addProperty(CSSPropertyGridAutoColumns, cssValuePool().createImplicitInitialValue(), important);
+ addProperty(CSSPropertyGridAutoRows, cssValuePool().createImplicitInitialValue(), important);
+ return true;
+ }
+
+ // Need to rewind parsing to explore the alternative syntax of this shorthand.
+ m_valueList->setCurrentIndex(0);
+
+ // 2- <grid-auto-flow> [ <grid-auto-columns> [ / <grid-auto-rows> ]? ]
+ CSSValueID id = m_valueList->current()->id;
+ if (id != CSSValueRow && id != CSSValueColumn && id != CSSValueNone)
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValue> autoFlowValue = cssValuePool().createIdentifierValue(id);
+ RefPtrWillBeRawPtr<CSSValue> autoColumnsValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> autoRowsValue = nullptr;
+
+ if (m_valueList->next()) {
+ autoColumnsValue = parseGridTrackSize(*m_valueList);
+ if (!autoColumnsValue)
+ return false;
+ if (m_valueList->current()) {
+ if (!isForwardSlashOperator(m_valueList->current()) || !m_valueList->next())
+ return false;
+ autoRowsValue = parseGridTrackSize(*m_valueList);
+ if (!autoRowsValue)
+ return false;
+ }
+ if (m_valueList->current())
+ return false;
+ } else {
+ // Other omitted values are set to their initial values.
+ autoColumnsValue = cssValuePool().createImplicitInitialValue();
+ autoRowsValue = cssValuePool().createImplicitInitialValue();
+ }
+
+ // if <grid-auto-rows> value is omitted, it is set to the value specified for grid-auto-columns.
+ if (!autoRowsValue)
+ autoRowsValue = autoColumnsValue;
+
+ addProperty(CSSPropertyGridAutoFlow, autoFlowValue, important);
+ addProperty(CSSPropertyGridAutoColumns, autoColumnsValue, important);
+ addProperty(CSSPropertyGridAutoRows, autoRowsValue, important);
+
+ // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
+ // The sub-properties not specified are set to their initial value, as normal for shorthands.
+ addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createImplicitInitialValue(), important);
+ addProperty(CSSPropertyGridTemplateRows, cssValuePool().createImplicitInitialValue(), important);
+ addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createImplicitInitialValue(), important);
+
+ return true;
+}
+
+bool CSSPropertyParser::parseGridAreaShorthand(bool important)
+{
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+ ShorthandScope scope(this, CSSPropertyGridArea);
+ const StylePropertyShorthand& shorthand = gridAreaShorthand();
+ ASSERT_UNUSED(shorthand, shorthand.length() == 4);
+
+ RefPtrWillBeRawPtr<CSSValue> rowStartValue = parseGridPosition();
+ if (!rowStartValue)
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValue> columnStartValue = nullptr;
+ if (!parseSingleGridAreaLonghand(columnStartValue))
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValue> rowEndValue = nullptr;
+ if (!parseSingleGridAreaLonghand(rowEndValue))
+ return false;
+
+ RefPtrWillBeRawPtr<CSSValue> columnEndValue = nullptr;
+ if (!parseSingleGridAreaLonghand(columnEndValue))
+ return false;
+
+ if (!columnStartValue)
+ columnStartValue = gridMissingGridPositionValue(rowStartValue.get());
+
+ if (!rowEndValue)
+ rowEndValue = gridMissingGridPositionValue(rowStartValue.get());
+
+ if (!columnEndValue)
+ columnEndValue = gridMissingGridPositionValue(columnStartValue.get());
+
+ addProperty(CSSPropertyGridRowStart, rowStartValue, important);
+ addProperty(CSSPropertyGridColumnStart, columnStartValue, important);
+ addProperty(CSSPropertyGridRowEnd, rowEndValue, important);
+ addProperty(CSSPropertyGridColumnEnd, columnEndValue, important);
+ return true;
+}
+
+bool CSSPropertyParser::parseSingleGridAreaLonghand(RefPtrWillBeRawPtr<CSSValue>& property)
+{
+ if (!m_valueList->current())
+ return true;
+
+ if (!isForwardSlashOperator(m_valueList->current()))
+ return false;
+
+ if (!m_valueList->next())
+ return false;
+
+ property = parseGridPosition();
+ return true;
+}
+
+void CSSPropertyParser::parseGridLineNames(CSSParserValueList& inputList, CSSValueList& valueList, CSSGridLineNamesValue* previousNamedAreaTrailingLineNames)
+{
+ ASSERT(inputList.current() && inputList.current()->unit == CSSParserValue::ValueList);
+
+ CSSParserValueList* identList = inputList.current()->valueList;
+ if (!identList->size()) {
+ inputList.next();
+ return;
+ }
+
+ // Need to ensure the identList is at the heading index, since the parserList might have been rewound.
+ identList->setCurrentIndex(0);
+
+ RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = previousNamedAreaTrailingLineNames;
+ if (!lineNames)
+ lineNames = CSSGridLineNamesValue::create();
+ while (CSSParserValue* identValue = identList->current()) {
+ ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> lineName = createPrimitiveStringValue(identValue);
+ lineNames->append(lineName.release());
+ identList->next();
+ }
+ if (!previousNamedAreaTrailingLineNames)
+ valueList.append(lineNames.release());
+
+ inputList.next();
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridTrackList(bool important)
+{
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+ CSSParserValue* value = m_valueList->current();
+ if (value->id == CSSValueNone) {
+ m_valueList->next();
+ return cssValuePool().createIdentifierValue(CSSValueNone);
+ }
+
+ RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
+ // Handle leading <ident>*.
+ value = m_valueList->current();
+ if (value && value->unit == CSSParserValue::ValueList)
+ parseGridLineNames(*m_valueList, *values);
+
+ bool seenTrackSizeOrRepeatFunction = false;
+ while (CSSParserValue* currentValue = m_valueList->current()) {
+ if (isForwardSlashOperator(currentValue))
+ break;
+ if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "repeat(")) {
+ if (!parseGridTrackRepeatFunction(*values))
+ return nullptr;
+ seenTrackSizeOrRepeatFunction = true;
+ } else {
+ RefPtrWillBeRawPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
+ if (!value)
+ return nullptr;
+ values->append(value);
+ seenTrackSizeOrRepeatFunction = true;
+ }
+ // This will handle the trailing <ident>* in the grammar.
+ value = m_valueList->current();
+ if (value && value->unit == CSSParserValue::ValueList)
+ parseGridLineNames(*m_valueList, *values);
+ }
+
+ // We should have found a <track-size> or else it is not a valid <track-list>
+ if (!seenTrackSizeOrRepeatFunction)
+ return nullptr;
+
+ return values;
+}
+
+bool CSSPropertyParser::parseGridTrackRepeatFunction(CSSValueList& list)
+{
+ CSSParserValueList* arguments = m_valueList->current()->function->args.get();
+ if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1)))
+ return false;
+
+ ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0);
+ size_t repetitions = arguments->valueAt(0)->fValue;
+ // Clamp repetitions at minRepetitions.
+ // http://www.w3.org/TR/css-grid-1/#repeat-notation
+ if (repetitions > minRepetitions)
+ repetitions = minRepetitions;
+ RefPtrWillBeRawPtr<CSSValueList> repeatedValues = CSSValueList::createSpaceSeparated();
+ arguments->next(); // Skip the repetition count.
+ arguments->next(); // Skip the comma.
+
+ // Handle leading <ident>*.
+ CSSParserValue* currentValue = arguments->current();
+ if (currentValue && currentValue->unit == CSSParserValue::ValueList)
+ parseGridLineNames(*arguments, *repeatedValues);
+
+ while (arguments->current()) {
+ RefPtrWillBeRawPtr<CSSValue> trackSize = parseGridTrackSize(*arguments);
+ if (!trackSize)
+ return false;
+
+ repeatedValues->append(trackSize);
+
+ // This takes care of any trailing <ident>* in the grammar.
+ currentValue = arguments->current();
+ if (currentValue && currentValue->unit == CSSParserValue::ValueList)
+ parseGridLineNames(*arguments, *repeatedValues);
+ }
+
+ for (size_t i = 0; i < repetitions; ++i) {
+ for (size_t j = 0; j < repeatedValues->length(); ++j)
+ list.append(repeatedValues->itemWithoutBoundsCheck(j));
+ }
+
+ // parseGridTrackSize iterated over the repeat arguments, move to the next value.
+ m_valueList->next();
+ return true;
+}
+
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridTrackSize(CSSParserValueList& inputList)
+{
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+ CSSParserValue* currentValue = inputList.current();
+ inputList.next();
+
+ if (currentValue->id == CSSValueAuto)
+ return cssValuePool().createIdentifierValue(CSSValueAuto);
+
+ if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "minmax(")) {
+ // The spec defines the following grammar: minmax( <track-breadth> , <track-breadth> )
+ CSSParserValueList* arguments = currentValue->function->args.get();
+ if (!arguments || arguments->size() != 3 || !isComma(arguments->valueAt(1)))
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> minTrackBreadth = parseGridBreadth(arguments->valueAt(0));
+ if (!minTrackBreadth)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> maxTrackBreadth = parseGridBreadth(arguments->valueAt(2));
+ if (!maxTrackBreadth)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSValueList> parsedArguments = CSSValueList::createCommaSeparated();
+ parsedArguments->append(minTrackBreadth);
+ parsedArguments->append(maxTrackBreadth);
+ return CSSFunctionValue::create("minmax(", parsedArguments);
+ }
+
+ return parseGridBreadth(currentValue);
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseGridBreadth(CSSParserValue* currentValue)
+{
+ if (currentValue->id == CSSValueMinContent || currentValue->id == CSSValueMaxContent)
+ return cssValuePool().createIdentifierValue(currentValue->id);
+
+ if (currentValue->unit == CSSPrimitiveValue::CSS_FR) {
+ double flexValue = currentValue->fValue;
+
+ // Fractional unit is a non-negative dimension.
+ if (flexValue <= 0)
+ return nullptr;
+
+ return cssValuePool().createValue(flexValue, CSSPrimitiveValue::CSS_FR);
+ }
+
+ if (!validUnit(currentValue, FNonNeg | FLength | FPercent))
+ return nullptr;
+
+ return createPrimitiveNumericValue(currentValue);
+}
+
+bool CSSPropertyParser::parseGridTemplateAreasRow(NamedGridAreaMap& gridAreaMap, const size_t rowCount, size_t& columnCount)
+{
+ CSSParserValue* currentValue = m_valueList->current();
+ if (!currentValue || currentValue->unit != CSSPrimitiveValue::CSS_STRING)
+ return false;
+
+ String gridRowNames = currentValue->string;
+ if (!gridRowNames.length())
+ return false;
+
+ Vector<String> columnNames;
+ gridRowNames.split(' ', columnNames);
+
+ if (!columnCount) {
+ columnCount = columnNames.size();
+ ASSERT(columnCount);
+ } else if (columnCount != columnNames.size()) {
+ // The declaration is invalid is all the rows don't have the number of columns.
+ return false;
+ }
+
+ for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
+ const String& gridAreaName = columnNames[currentCol];
+
+ // Unamed areas are always valid (we consider them to be 1x1).
+ if (gridAreaName == ".")
+ continue;
+
+ // We handle several grid areas with the same name at once to simplify the validation code.
+ size_t lookAheadCol;
+ for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++lookAheadCol) {
+ if (columnNames[lookAheadCol + 1] != gridAreaName)
+ break;
+ }
+
+ NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
+ if (gridAreaIt == gridAreaMap.end()) {
+ gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentCol, lookAheadCol)));
+ } else {
+ GridCoordinate& gridCoordinate = gridAreaIt->value;
+
+ // The following checks test that the grid area is a single filled-in rectangle.
+ // 1. The new row is adjacent to the previously parsed row.
+ if (rowCount != gridCoordinate.rows.resolvedFinalPosition.next().toInt())
+ return false;
+
+ // 2. The new area starts at the same position as the previously parsed area.
+ if (currentCol != gridCoordinate.columns.resolvedInitialPosition.toInt())
+ return false;
+
+ // 3. The new area ends at the same position as the previously parsed area.
+ if (lookAheadCol != gridCoordinate.columns.resolvedFinalPosition.toInt())
+ return false;
+
+ ++gridCoordinate.rows.resolvedFinalPosition;
+ }
+ currentCol = lookAheadCol;
+ }
+
+ m_valueList->next();
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridTemplateAreas()
+{
+ NamedGridAreaMap gridAreaMap;
+ size_t rowCount = 0;
+ size_t columnCount = 0;
+
+ while (m_valueList->current()) {
+ if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
+ return nullptr;
+ ++rowCount;
+ }
+
+ if (!rowCount || !columnCount)
+ return nullptr;
+
+ return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseCounterContent(CSSParserValueList* args, bool counters)
+{
+ unsigned numArgs = args->size();
+ if (counters && numArgs != 3 && numArgs != 5)
+ return nullptr;
+ if (!counters && numArgs != 1 && numArgs != 3)
+ return nullptr;
+
+ CSSParserValue* i = args->current();
+ if (i->unit != CSSPrimitiveValue::CSS_IDENT)
+ return nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> identifier = createPrimitiveStringValue(i);
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> separator = nullptr;
+ if (!counters)
+ separator = cssValuePool().createValue(String(), CSSPrimitiveValue::CSS_STRING);
+ else {
+ i = args->next();
+ if (i->unit != CSSParserValue::Operator || i->iValue != ',')
+ return nullptr;
+
+ i = args->next();
+ if (i->unit != CSSPrimitiveValue::CSS_STRING)
+ return nullptr;
+
+ separator = createPrimitiveStringValue(i);
+ }
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> listStyle = nullptr;
+ i = args->next();
+ if (!i) // Make the list style default decimal
+ listStyle = cssValuePool().createIdentifierValue(CSSValueDecimal);
+ else {
+ if (i->unit != CSSParserValue::Operator || i->iValue != ',')
+ return nullptr;
+
+ i = args->next();
+ if (i->unit != CSSPrimitiveValue::CSS_IDENT)
+ return nullptr;
+
+ CSSValueID listStyleID = CSSValueInvalid;
+ if (i->id == CSSValueNone || (i->id >= CSSValueDisc && i->id <= CSSValueKatakanaIroha))
+ listStyleID = i->id;
+ else
+ return nullptr;
+
+ listStyle = cssValuePool().createIdentifierValue(listStyleID);
+ }
+
+ return cssValuePool().createValue(Counter::create(identifier.release(), listStyle.release(), separator.release()));
+}
+
+bool CSSPropertyParser::parseClipShape(CSSPropertyID propId, bool important)
+{
+ CSSParserValue* value = m_valueList->current();
+ CSSParserValueList* args = value->function->args.get();
+
+ if (!equalIgnoringCase(value->function->name, "rect(") || !args)
+ return false;
+
+ // rect(t, r, b, l) || rect(t r b l)
+ if (args->size() != 4 && args->size() != 7)
+ return false;
+ RefPtrWillBeRawPtr<Rect> rect = Rect::create();
+ bool valid = true;
+ int i = 0;
+ CSSParserValue* a = args->current();
+ while (a) {
+ valid = a->id == CSSValueAuto || validUnit(a, FLength);
+ if (!valid)
+ break;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ?
+ cssValuePool().createIdentifierValue(CSSValueAuto) :
+ createPrimitiveNumericValue(a);
+ if (i == 0)
+ rect->setTop(length);
+ else if (i == 1)
+ rect->setRight(length);
+ else if (i == 2)
+ rect->setBottom(length);
+ else
+ rect->setLeft(length);
+ a = args->next();
+ if (a && args->size() == 7) {
+ if (a->unit == CSSParserValue::Operator && a->iValue == ',') {
+ a = args->next();
+ } else {
+ valid = false;
+ break;
+ }
+ }
+ i++;
+ }
+ if (valid) {
+ addProperty(propId, cssValuePool().createValue(rect.release()), important);
+ m_valueList->next();
+ return true;
+ }
+ return false;
+}
+
+static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4])
+{
+ if (radii[3])
+ return;
+ if (!radii[2]) {
+ if (!radii[1])
+ radii[1] = radii[0];
+ radii[2] = radii[0];
+ }
+ radii[3] = radii[1];
+}
+
+// FIXME: This should be refactored with CSSParser::parseBorderRadius.
+// CSSParser::parseBorderRadius contains support for some legacy radius construction.
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseInsetRoundedCorners(PassRefPtrWillBeRawPtr<CSSBasicShapeInset> shape, CSSParserValueList* args)
+{
+ CSSParserValue* argument = args->next();
+
+ if (!argument)
+ return nullptr;
+
+ Vector<CSSParserValue*> radiusArguments;
+ while (argument) {
+ radiusArguments.append(argument);
+ argument = args->next();
+ }
+
+ unsigned num = radiusArguments.size();
+ if (!num || num > 9)
+ return nullptr;
+
+ // FIXME: Refactor completeBorderRadii and the array
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[2][4];
+#if ENABLE(OILPAN)
+ // Zero initialize the array of raw pointers.
+ memset(&radii, 0, sizeof(radii));
+#endif
+
+ unsigned indexAfterSlash = 0;
+ for (unsigned i = 0; i < num; ++i) {
+ CSSParserValue* value = radiusArguments.at(i);
+ if (value->unit == CSSParserValue::Operator) {
+ if (value->iValue != '/')
+ return nullptr;
+
+ if (!i || indexAfterSlash || i + 1 == num)
+ return nullptr;
+
+ indexAfterSlash = i + 1;
+ completeBorderRadii(radii[0]);
+ continue;
+ }
+
+ if (i - indexAfterSlash >= 4)
+ return nullptr;
+
+ if (!validUnit(value, FLength | FPercent | FNonNeg))
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value);
+
+ if (!indexAfterSlash)
+ radii[0][i] = radius;
+ else
+ radii[1][i - indexAfterSlash] = radius.release();
+ }
+
+ if (!indexAfterSlash) {
+ completeBorderRadii(radii[0]);
+ for (unsigned i = 0; i < 4; ++i)
+ radii[1][i] = radii[0][i];
+ } else {
+ completeBorderRadii(radii[1]);
+ }
+ shape->setTopLeftRadius(createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()));
+ shape->setTopRightRadius(createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()));
+ shape->setBottomRightRadius(createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()));
+ shape->setBottomLeftRadius(createPrimitiveValuePair(radii[0][3].release(), radii[1][3].release()));
+
+ return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapeInset(CSSParserValueList* args)
+{
+ ASSERT(args);
+
+ RefPtrWillBeRawPtr<CSSBasicShapeInset> shape = CSSBasicShapeInset::create();
+
+ CSSParserValue* argument = args->current();
+ WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> > widthArguments;
+ bool hasRoundedInset = false;
+
+ while (argument) {
+ if (argument->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(argument->string, "round")) {
+ hasRoundedInset = true;
+ break;
+ }
+
+ Units unitFlags = FLength | FPercent;
+ if (!validUnit(argument, unitFlags) || widthArguments.size() > 4)
+ return nullptr;
+
+ widthArguments.append(createPrimitiveNumericValue(argument));
+ argument = args->next();
+ }
+
+ switch (widthArguments.size()) {
+ case 1: {
+ shape->updateShapeSize1Value(widthArguments[0].get());
+ break;
+ }
+ case 2: {
+ shape->updateShapeSize2Values(widthArguments[0].get(), widthArguments[1].get());
+ break;
+ }
+ case 3: {
+ shape->updateShapeSize3Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get());
+ break;
+ }
+ case 4: {
+ shape->updateShapeSize4Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get(), widthArguments[3].get());
+ break;
+ }
+ default:
+ return nullptr;
+ }
+
+ if (hasRoundedInset)
+ return parseInsetRoundedCorners(shape, args);
+ return shape;
+}
+
+static bool isItemPositionKeyword(CSSValueID id)
+{
+ return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
+ || id == CSSValueSelfStart || id == CSSValueSelfEnd || id == CSSValueFlexStart
+ || id == CSSValueFlexEnd || id == CSSValueLeft || id == CSSValueRight;
+}
+
+bool CSSPropertyParser::parseItemPositionOverflowPosition(CSSPropertyID propId, bool important)
+{
+ // auto | baseline | stretch | [<item-position> && <overflow-position>? ]
+ // <item-position> = center | start | end | self-start | self-end | flex-start | flex-end | left | right;
+ // <overflow-position> = true | safe
+
+ CSSParserValue* value = m_valueList->current();
+
+ if (value->id == CSSValueAuto || value->id == CSSValueBaseline || value->id == CSSValueStretch) {
+ if (m_valueList->next())
+ return false;
+
+ addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
+ return true;
+ }
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> position = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> overflowAlignmentKeyword = nullptr;
+ if (isItemPositionKeyword(value->id)) {
+ position = cssValuePool().createIdentifierValue(value->id);
+ value = m_valueList->next();
+ if (value) {
+ if (value->id == CSSValueTrue || value->id == CSSValueSafe)
+ overflowAlignmentKeyword = cssValuePool().createIdentifierValue(value->id);
+ else
+ return false;
+ }
+ } else if (value->id == CSSValueTrue || value->id == CSSValueSafe) {
+ overflowAlignmentKeyword = cssValuePool().createIdentifierValue(value->id);
+ value = m_valueList->next();
+ if (value && isItemPositionKeyword(value->id))
+ position = cssValuePool().createIdentifierValue(value->id);
+ else
+ return false;
+ } else {
+ return false;
+ }
+
+ if (m_valueList->next())
+ return false;
+
+ ASSERT(position);
+ if (overflowAlignmentKeyword)
+ addProperty(propId, createPrimitiveValuePair(position, overflowAlignmentKeyword), important);
+ else
+ addProperty(propId, position.release(), important);
+
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseShapeRadius(CSSParserValue* value)
+{
+ if (value->id == CSSValueClosestSide || value->id == CSSValueFarthestSide)
+ return cssValuePool().createIdentifierValue(value->id);
+
+ if (!validUnit(value, FLength | FPercent | FNonNeg))
+ return nullptr;
+
+ return createPrimitiveNumericValue(value);
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapeCircle(CSSParserValueList* args)
+{
+ ASSERT(args);
+
+ // circle(radius)
+ // circle(radius at <position>)
+ // circle(at <position>)
+ // where position defines centerX and centerY using a CSS <position> data type.
+ RefPtrWillBeRawPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create();
+
+ for (CSSParserValue* argument = args->current(); argument; argument = args->next()) {
+ // The call to parseFillPosition below should consume all of the
+ // arguments except the first two. Thus, and index greater than one
+ // indicates an invalid production.
+ if (args->currentIndex() > 1)
+ return nullptr;
+
+ if (!args->currentIndex() && argument->id != CSSValueAt) {
+ if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) {
+ shape->setRadius(radius);
+ continue;
+ }
+
+ return nullptr;
+ }
+
+ if (argument->id == CSSValueAt && args->next()) {
+ RefPtrWillBeRawPtr<CSSValue> centerX = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> centerY = nullptr;
+ parseFillPosition(args, centerX, centerY);
+ if (centerX && centerY && !args->current()) {
+ ASSERT(centerX->isPrimitiveValue());
+ ASSERT(centerY->isPrimitiveValue());
+ shape->setCenterX(toCSSPrimitiveValue(centerX.get()));
+ shape->setCenterY(toCSSPrimitiveValue(centerY.get()));
+ } else {
+ return nullptr;
+ }
+ } else {
+ return nullptr;
+ }
+ }
+
+ return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapeEllipse(CSSParserValueList* args)
+{
+ ASSERT(args);
+
+ // ellipse(radiusX)
+ // ellipse(radiusX at <position>)
+ // ellipse(radiusX radiusY)
+ // ellipse(radiusX radiusY at <position>)
+ // ellipse(at <position>)
+ // where position defines centerX and centerY using a CSS <position> data type.
+ RefPtrWillBeRawPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create();
+
+ for (CSSParserValue* argument = args->current(); argument; argument = args->next()) {
+ // The call to parseFillPosition below should consume all of the
+ // arguments except the first three. Thus, an index greater than two
+ // indicates an invalid production.
+ if (args->currentIndex() > 2)
+ return nullptr;
+
+ if (args->currentIndex() < 2 && argument->id != CSSValueAt) {
+ if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) {
+ if (!shape->radiusX())
+ shape->setRadiusX(radius);
+ else
+ shape->setRadiusY(radius);
+ continue;
+ }
+
+ return nullptr;
+ }
+
+ if (argument->id != CSSValueAt || !args->next()) // expecting ellipse(.. at <position>)
+ return nullptr;
+ RefPtrWillBeRawPtr<CSSValue> centerX = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> centerY = nullptr;
+ parseFillPosition(args, centerX, centerY);
+ if (!centerX || !centerY || args->current())
+ return nullptr;
+
+ ASSERT(centerX->isPrimitiveValue());
+ ASSERT(centerY->isPrimitiveValue());
+ shape->setCenterX(toCSSPrimitiveValue(centerX.get()));
+ shape->setCenterY(toCSSPrimitiveValue(centerY.get()));
+ }
+
+ return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapePolygon(CSSParserValueList* args)
+{
+ ASSERT(args);
+
+ unsigned size = args->size();
+ if (!size)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSBasicShapePolygon> shape = CSSBasicShapePolygon::create();
+
+ CSSParserValue* argument = args->current();
+ if (argument->id == CSSValueEvenodd || argument->id == CSSValueNonzero) {
+ shape->setWindRule(argument->id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO);
+
+ if (!isComma(args->next()))
+ return nullptr;
+
+ argument = args->next();
+ size -= 2;
+ }
+
+ // <length> <length>, ... <length> <length> -> each pair has 3 elements except the last one
+ if (!size || (size % 3) - 2)
+ return nullptr;
+
+ CSSParserValue* argumentX = argument;
+ while (argumentX) {
+
+ if (!validUnit(argumentX, FLength | FPercent))
+ return nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> xLength = createPrimitiveNumericValue(argumentX);
+
+ CSSParserValue* argumentY = args->next();
+ if (!argumentY || !validUnit(argumentY, FLength | FPercent))
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> yLength = createPrimitiveNumericValue(argumentY);
+
+ shape->appendPoint(xLength.release(), yLength.release());
+
+ CSSParserValue* commaOrNull = args->next();
+ if (!commaOrNull)
+ argumentX = 0;
+ else if (!isComma(commaOrNull))
+ return nullptr;
+ else
+ argumentX = args->next();
+ }
+
+ return shape;
+}
+
+static bool isBoxValue(CSSValueID valueId)
+{
+ switch (valueId) {
+ case CSSValueContentBox:
+ case CSSValuePaddingBox:
+ case CSSValueBorderBox:
+ case CSSValueMarginBox:
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseShapeProperty(CSSPropertyID propId)
+{
+ if (!RuntimeEnabledFeatures::cssShapesEnabled())
+ return nullptr;
+
+ CSSParserValue* value = m_valueList->current();
+ CSSValueID valueId = value->id;
+
+ if (valueId == CSSValueNone) {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> keywordValue = parseValidPrimitive(valueId, value);
+ m_valueList->next();
+ return keywordValue.release();
+ }
+
+ RefPtrWillBeRawPtr<CSSValue> imageValue = nullptr;
+ if (valueId != CSSValueNone && parseFillImage(m_valueList.get(), imageValue)) {
+ m_valueList->next();
+ return imageValue.release();
+ }
+
+ return parseBasicShapeAndOrBox();
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseBasicShapeAndOrBox()
+{
+ CSSParserValue* value = m_valueList->current();
+
+ bool shapeFound = false;
+ bool boxFound = false;
+ CSSValueID valueId;
+
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ for (unsigned i = 0; i < 2; ++i) {
+ if (!value)
+ break;
+ valueId = value->id;
+ if (value->unit == CSSParserValue::Function && !shapeFound) {
+ // parseBasicShape already asks for the next value list item.
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue = parseBasicShape();
+ if (!shapeValue)
+ return nullptr;
+ list->append(shapeValue.release());
+ shapeFound = true;
+ } else if (isBoxValue(valueId) && !boxFound) {
+ list->append(parseValidPrimitive(valueId, value));
+ boxFound = true;
+ m_valueList->next();
+ } else {
+ return nullptr;
+ }
+
+ value = m_valueList->current();
+ }
+
+ if (m_valueList->current())
+ return nullptr;
+ return list.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseBasicShape()
+{
+ CSSParserValue* value = m_valueList->current();
+ ASSERT(value->unit == CSSParserValue::Function);
+ CSSParserValueList* args = value->function->args.get();
+
+ if (!args)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSBasicShape> shape = nullptr;
+ if (equalIgnoringCase(value->function->name, "circle("))
+ shape = parseBasicShapeCircle(args);
+ else if (equalIgnoringCase(value->function->name, "ellipse("))
+ shape = parseBasicShapeEllipse(args);
+ else if (equalIgnoringCase(value->function->name, "polygon("))
+ shape = parseBasicShapePolygon(args);
+ else if (equalIgnoringCase(value->function->name, "inset("))
+ shape = parseBasicShapeInset(args);
+
+ if (!shape)
+ return nullptr;
+
+ m_valueList->next();
+
+ return cssValuePool().createValue(shape.release());
+}
+
+// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family'
+bool CSSPropertyParser::parseFont(bool important)
+{
+ // Let's check if there is an inherit or initial somewhere in the shorthand.
+ for (unsigned i = 0; i < m_valueList->size(); ++i) {
+ if (m_valueList->valueAt(i)->id == CSSValueInherit || m_valueList->valueAt(i)->id == CSSValueInitial)
+ return false;
+ }
+
+ ShorthandScope scope(this, CSSPropertyFont);
+ // Optional font-style, font-variant and font-weight.
+ bool fontStyleParsed = false;
+ bool fontVariantParsed = false;
+ bool fontWeightParsed = false;
+ CSSParserValue* value;
+ while ((value = m_valueList->current())) {
+ if (!fontStyleParsed && isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value->id, m_context)) {
+ addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(value->id), important);
+ fontStyleParsed = true;
+ } else if (!fontVariantParsed && (value->id == CSSValueNormal || value->id == CSSValueSmallCaps)) {
+ // Font variant in the shorthand is particular, it only accepts normal or small-caps.
+ addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(value->id), important);
+ fontVariantParsed = true;
+ } else if (!fontWeightParsed && parseFontWeight(important))
+ fontWeightParsed = true;
+ else
+ break;
+ m_valueList->next();
+ }
+
+ if (!value)
+ return false;
+
+ if (!fontStyleParsed)
+ addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
+ if (!fontVariantParsed)
+ addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
+ if (!fontWeightParsed)
+ addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
+
+ // Now a font size _must_ come.
+ // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
+ if (!parseFontSize(important))
+ return false;
+
+ value = m_valueList->current();
+ if (!value)
+ return false;
+
+ if (isForwardSlashOperator(value)) {
+ // The line-height property.
+ value = m_valueList->next();
+ if (!value)
+ return false;
+ if (!parseLineHeight(important))
+ return false;
+ } else
+ addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
+
+ // Font family must come now.
+ RefPtrWillBeRawPtr<CSSValue> parsedFamilyValue = parseFontFamily();
+ if (!parsedFamilyValue)
+ return false;
+
+ addProperty(CSSPropertyFontFamily, parsedFamilyValue.release(), important);
+
+ // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires that
+ // "font-stretch", "font-size-adjust", and "font-kerning" be reset to their initial values
+ // but we don't seem to support them at the moment. They should also be added here once implemented.
+ if (m_valueList->current())
+ return false;
+
+ return true;
+}
+
+class FontFamilyValueBuilder {
+ DISALLOW_ALLOCATION();
+public:
+ FontFamilyValueBuilder(CSSValueList* list)
+ : m_list(list)
+ {
+ }
+
+ void add(const CSSParserString& string)
+ {
+ if (!m_builder.isEmpty())
+ m_builder.append(' ');
+
+ if (string.is8Bit()) {
+ m_builder.append(string.characters8(), string.length());
+ return;
+ }
+
+ m_builder.append(string.characters16(), string.length());
+ }
+
+ void commit()
+ {
+ if (m_builder.isEmpty())
+ return;
+ m_list->append(cssValuePool().createFontFamilyValue(m_builder.toString()));
+ m_builder.clear();
+ }
+
+private:
+ StringBuilder m_builder;
+ CSSValueList* m_list;
+};
+
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseFontFamily()
+{
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ CSSParserValue* value = m_valueList->current();
+
+ FontFamilyValueBuilder familyBuilder(list.get());
+ bool inFamily = false;
+
+ while (value) {
+ CSSParserValue* nextValue = m_valueList->next();
+ bool nextValBreaksFont = !nextValue ||
+ (nextValue->unit == CSSParserValue::Operator && nextValue->iValue == ',');
+ bool nextValIsFontName = nextValue &&
+ ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitBody) ||
+ (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT));
+
+ if (isCSSWideKeyword(*value) && !inFamily) {
+ if (nextValBreaksFont)
+ value = m_valueList->next();
+ else if (nextValIsFontName)
+ value = nextValue;
+ continue;
+ }
+
+ if (value->id >= CSSValueSerif && value->id <= CSSValueWebkitBody) {
+ if (inFamily)
+ familyBuilder.add(value->string);
+ else if (nextValBreaksFont || !nextValIsFontName)
+ list->append(cssValuePool().createIdentifierValue(value->id));
+ else {
+ familyBuilder.commit();
+ familyBuilder.add(value->string);
+ inFamily = true;
+ }
+ } else if (value->unit == CSSPrimitiveValue::CSS_STRING) {
+ // Strings never share in a family name.
+ inFamily = false;
+ familyBuilder.commit();
+ list->append(cssValuePool().createFontFamilyValue(value->string));
+ } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) {
+ if (inFamily)
+ familyBuilder.add(value->string);
+ else if (nextValBreaksFont || !nextValIsFontName)
+ list->append(cssValuePool().createFontFamilyValue(value->string));
+ else {
+ familyBuilder.commit();
+ familyBuilder.add(value->string);
+ inFamily = true;
+ }
+ } else {
+ break;
+ }
+
+ if (!nextValue)
+ break;
+
+ if (nextValBreaksFont) {
+ value = m_valueList->next();
+ familyBuilder.commit();
+ inFamily = false;
+ }
+ else if (nextValIsFontName)
+ value = nextValue;
+ else
+ break;
+ }
+ familyBuilder.commit();
+
+ if (!list->length())
+ list = nullptr;
+ return list.release();
+}
+
+bool CSSPropertyParser::parseLineHeight(bool important)
+{
+ CSSParserValue* value = m_valueList->current();
+ CSSValueID id = value->id;
+ bool validPrimitive = false;
+ // normal | <number> | <length> | <percentage> | inherit
+ if (id == CSSValueNormal)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FNumber | FLength | FPercent | FNonNeg));
+ if (validPrimitive && (!m_valueList->next() || inShorthand()))
+ addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, value), important);
+ return validPrimitive;
+}
+
+bool CSSPropertyParser::parseFontSize(bool important)
+{
+ CSSParserValue* value = m_valueList->current();
+ CSSValueID id = value->id;
+ bool validPrimitive = false;
+ // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
+ if (id >= CSSValueXxSmall && id <= CSSValueLarger)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
+ if (validPrimitive && (!m_valueList->next() || inShorthand()))
+ addProperty(CSSPropertyFontSize, parseValidPrimitive(id, value), important);
+ return validPrimitive;
+}
+
+bool CSSPropertyParser::parseFontVariant(bool important)
+{
+ RefPtrWillBeRawPtr<CSSValueList> values = nullptr;
+ if (m_valueList->size() > 1)
+ values = CSSValueList::createCommaSeparated();
+ CSSParserValue* val;
+ bool expectComma = false;
+ while ((val = m_valueList->current())) {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue = nullptr;
+ if (!expectComma) {
+ expectComma = true;
+ if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps)
+ parsedValue = cssValuePool().createIdentifierValue(val->id);
+ else if (val->id == CSSValueAll && !values) {
+ // FIXME: CSSPropertyParser::parseFontVariant() implements
+ // the old css3 draft:
+ // http://www.w3.org/TR/2002/WD-css3-webfonts-20020802/#font-variant
+ // 'all' is only allowed in @font-face and with no other values. Make a value list to
+ // indicate that we are in the @font-face case.
+ values = CSSValueList::createCommaSeparated();
+ parsedValue = cssValuePool().createIdentifierValue(val->id);
+ }
+ } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
+ expectComma = false;
+ m_valueList->next();
+ continue;
+ }
+
+ if (!parsedValue)
+ return false;
+
+ m_valueList->next();
+
+ if (values)
+ values->append(parsedValue.release());
+ else {
+ addProperty(CSSPropertyFontVariant, parsedValue.release(), important);
+ return true;
+ }
+ }
+
+ if (values && values->length()) {
+ if (m_ruleType != CSSRuleSourceData::FONT_FACE_RULE)
+ return false;
+ addProperty(CSSPropertyFontVariant, values.release(), important);
+ return true;
+ }
+
+ return false;
+}
+
+bool CSSPropertyParser::parseFontWeight(bool important)
+{
+ CSSParserValue* value = m_valueList->current();
+ if ((value->id >= CSSValueNormal) && (value->id <= CSSValue900)) {
+ addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(value->id), important);
+ return true;
+ }
+ if (validUnit(value, FInteger | FNonNeg, HTMLQuirksMode)) {
+ int weight = static_cast<int>(value->fValue);
+ if (!(weight % 100) && weight >= 100 && weight <= 900) {
+ addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue100 + weight / 100 - 1)), important);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CSSPropertyParser::parseFontFaceSrcURI(CSSValueList* valueList)
+{
+ RefPtrWillBeRawPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create(completeURL(m_valueList->current()->string)));
+ uriValue->setReferrer(m_context.referrer());
+
+ CSSParserValue* value = m_valueList->next();
+ if (!value) {
+ valueList->append(uriValue.release());
+ return true;
+ }
+ if (value->unit == CSSParserValue::Operator && value->iValue == ',') {
+ m_valueList->next();
+ valueList->append(uriValue.release());
+ return true;
+ }
+
+ if (value->unit != CSSParserValue::Function || !equalIgnoringCase(value->function->name, "format("))
+ return false;
+
+ // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20111004/ says that format() contains a comma-separated list of strings,
+ // but CSSFontFaceSrcValue stores only one format. Allowing one format for now.
+ CSSParserValueList* args = value->function->args.get();
+ if (!args || args->size() != 1 || (args->current()->unit != CSSPrimitiveValue::CSS_STRING && args->current()->unit != CSSPrimitiveValue::CSS_IDENT))
+ return false;
+ uriValue->setFormat(args->current()->string);
+ valueList->append(uriValue.release());
+ value = m_valueList->next();
+ if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
+ m_valueList->next();
+ return true;
+}
+
+bool CSSPropertyParser::parseFontFaceSrcLocal(CSSValueList* valueList)
+{
+ CSSParserValueList* args = m_valueList->current()->function->args.get();
+ if (!args || !args->size())
+ return false;
+
+ if (args->size() == 1 && args->current()->unit == CSSPrimitiveValue::CSS_STRING)
+ valueList->append(CSSFontFaceSrcValue::createLocal(args->current()->string));
+ else if (args->current()->unit == CSSPrimitiveValue::CSS_IDENT) {
+ StringBuilder builder;
+ for (CSSParserValue* localValue = args->current(); localValue; localValue = args->next()) {
+ if (localValue->unit != CSSPrimitiveValue::CSS_IDENT)
+ return false;
+ if (!builder.isEmpty())
+ builder.append(' ');
+ builder.append(localValue->string);
+ }
+ valueList->append(CSSFontFaceSrcValue::createLocal(builder.toString()));
+ } else
+ return false;
+
+ if (CSSParserValue* value = m_valueList->next()) {
+ if (value->unit == CSSParserValue::Operator && value->iValue == ',')
+ m_valueList->next();
+ }
+ return true;
+}
+
+bool CSSPropertyParser::parseFontFaceSrc()
+{
+ RefPtrWillBeRawPtr<CSSValueList> values(CSSValueList::createCommaSeparated());
+
+ while (CSSParserValue* value = m_valueList->current()) {
+ if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ if (!parseFontFaceSrcURI(values.get()))
+ return false;
+ } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "local(")) {
+ if (!parseFontFaceSrcLocal(values.get()))
+ return false;
+ } else
+ return false;
+ }
+ if (!values->length())
+ return false;
+
+ addProperty(CSSPropertySrc, values.release(), m_important);
+ m_valueList->next();
+ return true;
+}
+
+bool CSSPropertyParser::parseFontFaceUnicodeRange()
+{
+ RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+ bool failed = false;
+ bool operatorExpected = false;
+ for (; m_valueList->current(); m_valueList->next(), operatorExpected = !operatorExpected) {
+ if (operatorExpected) {
+ if (m_valueList->current()->unit == CSSParserValue::Operator && m_valueList->current()->iValue == ',')
+ continue;
+ failed = true;
+ break;
+ }
+ if (m_valueList->current()->unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
+ failed = true;
+ break;
+ }
+
+ String rangeString = m_valueList->current()->string;
+ UChar32 from = 0;
+ UChar32 to = 0;
+ unsigned length = rangeString.length();
+
+ if (length < 3) {
+ failed = true;
+ break;
+ }
+
+ unsigned i = 2;
+ while (i < length) {
+ UChar c = rangeString[i];
+ if (c == '-' || c == '?')
+ break;
+ from *= 16;
+ if (c >= '0' && c <= '9')
+ from += c - '0';
+ else if (c >= 'A' && c <= 'F')
+ from += 10 + c - 'A';
+ else if (c >= 'a' && c <= 'f')
+ from += 10 + c - 'a';
+ else {
+ failed = true;
+ break;
+ }
+ i++;
+ }
+ if (failed)
+ break;
+
+ if (i == length)
+ to = from;
+ else if (rangeString[i] == '?') {
+ unsigned span = 1;
+ while (i < length && rangeString[i] == '?') {
+ span *= 16;
+ from *= 16;
+ i++;
+ }
+ if (i < length)
+ failed = true;
+ to = from + span - 1;
+ } else {
+ if (length < i + 2) {
+ failed = true;
+ break;
+ }
+ i++;
+ while (i < length) {
+ UChar c = rangeString[i];
+ to *= 16;
+ if (c >= '0' && c <= '9')
+ to += c - '0';
+ else if (c >= 'A' && c <= 'F')
+ to += 10 + c - 'A';
+ else if (c >= 'a' && c <= 'f')
+ to += 10 + c - 'a';
+ else {
+ failed = true;
+ break;
+ }
+ i++;
+ }
+ if (failed)
+ break;
+ }
+ if (from <= to)
+ values->append(CSSUnicodeRangeValue::create(from, to));
+ }
+ if (failed || !values->length())
+ return false;
+ addProperty(CSSPropertyUnicodeRange, values.release(), m_important);
+ return true;
+}
+
+// Returns the number of characters which form a valid double
+// and are terminated by the given terminator character
+template <typename CharacterType>
+static int checkForValidDouble(const CharacterType* string, const CharacterType* end, const char terminator)
+{
+ int length = end - string;
+ if (length < 1)
+ return 0;
+
+ bool decimalMarkSeen = false;
+ int processedLength = 0;
+
+ for (int i = 0; i < length; ++i) {
+ if (string[i] == terminator) {
+ processedLength = i;
+ break;
+ }
+ if (!isASCIIDigit(string[i])) {
+ if (!decimalMarkSeen && string[i] == '.')
+ decimalMarkSeen = true;
+ else
+ return 0;
+ }
+ }
+
+ if (decimalMarkSeen && processedLength == 1)
+ return 0;
+
+ return processedLength;
+}
+
+// Returns the number of characters consumed for parsing a valid double
+// terminated by the given terminator character
+template <typename CharacterType>
+static int parseDouble(const CharacterType* string, const CharacterType* end, const char terminator, double& value)
+{
+ int length = checkForValidDouble(string, end, terminator);
+ if (!length)
+ return 0;
+
+ int position = 0;
+ double localValue = 0;
+
+ // The consumed characters here are guaranteed to be
+ // ASCII digits with or without a decimal mark
+ for (; position < length; ++position) {
+ if (string[position] == '.')
+ break;
+ localValue = localValue * 10 + string[position] - '0';
+ }
+
+ if (++position == length) {
+ value = localValue;
+ return length;
+ }
+
+ double fraction = 0;
+ double scale = 1;
+
+ while (position < length && scale < MAX_SCALE) {
+ fraction = fraction * 10 + string[position++] - '0';
+ scale *= 10;
+ }
+
+ value = localValue + fraction / scale;
+ return length;
+}
+
+template <typename CharacterType>
+static bool parseColorIntOrPercentage(const CharacterType*& string, const CharacterType* end, const char terminator, CSSPrimitiveValue::UnitType& expect, int& value)
+{
+ const CharacterType* current = string;
+ double localValue = 0;
+ bool negative = false;
+ while (current != end && isHTMLSpace<CharacterType>(*current))
+ current++;
+ if (current != end && *current == '-') {
+ negative = true;
+ current++;
+ }
+ if (current == end || !isASCIIDigit(*current))
+ return false;
+ while (current != end && isASCIIDigit(*current)) {
+ double newValue = localValue * 10 + *current++ - '0';
+ if (newValue >= 255) {
+ // Clamp values at 255.
+ localValue = 255;
+ while (current != end && isASCIIDigit(*current))
+ ++current;
+ break;
+ }
+ localValue = newValue;
+ }
+
+ if (current == end)
+ return false;
+
+ if (expect == CSSPrimitiveValue::CSS_NUMBER && (*current == '.' || *current == '%'))
+ return false;
+
+ if (*current == '.') {
+ // We already parsed the integral part, try to parse
+ // the fraction part of the percentage value.
+ double percentage = 0;
+ int numCharactersParsed = parseDouble(current, end, '%', percentage);
+ if (!numCharactersParsed)
+ return false;
+ current += numCharactersParsed;
+ if (*current != '%')
+ return false;
+ localValue += percentage;
+ }
+
+ if (expect == CSSPrimitiveValue::CSS_PERCENTAGE && *current != '%')
+ return false;
+
+ if (*current == '%') {
+ expect = CSSPrimitiveValue::CSS_PERCENTAGE;
+ localValue = localValue / 100.0 * 256.0;
+ // Clamp values at 255 for percentages over 100%
+ if (localValue > 255)
+ localValue = 255;
+ current++;
+ } else
+ expect = CSSPrimitiveValue::CSS_NUMBER;
+
+ while (current != end && isHTMLSpace<CharacterType>(*current))
+ current++;
+ if (current == end || *current++ != terminator)
+ return false;
+ // Clamp negative values at zero.
+ value = negative ? 0 : static_cast<int>(localValue);
+ string = current;
+ return true;
+}
+
+template <typename CharacterType>
+static inline bool isTenthAlpha(const CharacterType* string, const int length)
+{
+ // "0.X"
+ if (length == 3 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2]))
+ return true;
+
+ // ".X"
+ if (length == 2 && string[0] == '.' && isASCIIDigit(string[1]))
+ return true;
+
+ return false;
+}
+
+template <typename CharacterType>
+static inline bool parseAlphaValue(const CharacterType*& string, const CharacterType* end, const char terminator, int& value)
+{
+ while (string != end && isHTMLSpace<CharacterType>(*string))
+ string++;
+
+ bool negative = false;
+
+ if (string != end && *string == '-') {
+ negative = true;
+ string++;
+ }
+
+ value = 0;
+
+ int length = end - string;
+ if (length < 2)
+ return false;
+
+ if (string[length - 1] != terminator || !isASCIIDigit(string[length - 2]))
+ return false;
+
+ if (string[0] != '0' && string[0] != '1' && string[0] != '.') {
+ if (checkForValidDouble(string, end, terminator)) {
+ value = negative ? 0 : 255;
+ string = end;
+ return true;
+ }
+ return false;
+ }
+
+ if (length == 2 && string[0] != '.') {
+ value = !negative && string[0] == '1' ? 255 : 0;
+ string = end;
+ return true;
+ }
+
+ if (isTenthAlpha(string, length - 1)) {
+ static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 };
+ value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
+ string = end;
+ return true;
+ }
+
+ double alpha = 0;
+ if (!parseDouble(string, end, terminator, alpha))
+ return false;
+ value = negative ? 0 : static_cast<int>(alpha * nextafter(256.0, 0.0));
+ string = end;
+ return true;
+}
+
+template <typename CharacterType>
+static inline bool mightBeRGBA(const CharacterType* characters, unsigned length)
+{
+ if (length < 5)
+ return false;
+ return characters[4] == '('
+ && isASCIIAlphaCaselessEqual(characters[0], 'r')
+ && isASCIIAlphaCaselessEqual(characters[1], 'g')
+ && isASCIIAlphaCaselessEqual(characters[2], 'b')
+ && isASCIIAlphaCaselessEqual(characters[3], 'a');
+}
+
+template <typename CharacterType>
+static inline bool mightBeRGB(const CharacterType* characters, unsigned length)
+{
+ if (length < 4)
+ return false;
+ return characters[3] == '('
+ && isASCIIAlphaCaselessEqual(characters[0], 'r')
+ && isASCIIAlphaCaselessEqual(characters[1], 'g')
+ && isASCIIAlphaCaselessEqual(characters[2], 'b');
+}
+
+template <typename CharacterType>
+static inline bool fastParseColorInternal(RGBA32& rgb, const CharacterType* characters, unsigned length , bool strict)
+{
+ CSSPrimitiveValue::UnitType expect = CSSPrimitiveValue::CSS_UNKNOWN;
+
+ if (length >= 4 && characters[0] == '#')
+ return Color::parseHexColor(characters + 1, length - 1, rgb);
+
+ if (!strict && length >= 3) {
+ if (Color::parseHexColor(characters, length, rgb))
+ return true;
+ }
+
+ // Try rgba() syntax.
+ if (mightBeRGBA(characters, length)) {
+ const CharacterType* current = characters + 5;
+ const CharacterType* end = characters + length;
+ int red;
+ int green;
+ int blue;
+ int alpha;
+
+ if (!parseColorIntOrPercentage(current, end, ',', expect, red))
+ return false;
+ if (!parseColorIntOrPercentage(current, end, ',', expect, green))
+ return false;
+ if (!parseColorIntOrPercentage(current, end, ',', expect, blue))
+ return false;
+ if (!parseAlphaValue(current, end, ')', alpha))
+ return false;
+ if (current != end)
+ return false;
+ rgb = makeRGBA(red, green, blue, alpha);
+ return true;
+ }
+
+ // Try rgb() syntax.
+ if (mightBeRGB(characters, length)) {
+ const CharacterType* current = characters + 4;
+ const CharacterType* end = characters + length;
+ int red;
+ int green;
+ int blue;
+ if (!parseColorIntOrPercentage(current, end, ',', expect, red))
+ return false;
+ if (!parseColorIntOrPercentage(current, end, ',', expect, green))
+ return false;
+ if (!parseColorIntOrPercentage(current, end, ')', expect, blue))
+ return false;
+ if (current != end)
+ return false;
+ rgb = makeRGB(red, green, blue);
+ return true;
+ }
+
+ return false;
+}
+
+template<typename StringType>
+bool CSSPropertyParser::fastParseColor(RGBA32& rgb, const StringType& name, bool strict)
+{
+ unsigned length = name.length();
+ bool parseResult;
+
+ if (!length)
+ return false;
+
+ if (name.is8Bit())
+ parseResult = fastParseColorInternal(rgb, name.characters8(), length, strict);
+ else
+ parseResult = fastParseColorInternal(rgb, name.characters16(), length, strict);
+
+ if (parseResult)
+ return true;
+
+ // Try named colors.
+ Color tc;
+ if (!tc.setNamedColor(name))
+ return false;
+ rgb = tc.rgb();
+ return true;
+}
+
+template bool CSSPropertyParser::fastParseColor(RGBA32&, const String&, bool strict);
+
+inline double CSSPropertyParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc)
+{
+ const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue;
+ if (releaseCalc == ReleaseParsedCalcValue)
+ m_parsedCalculation.release();
+ return result;
+}
+
+bool CSSPropertyParser::isCalculation(CSSParserValue* value)
+{
+ return (value->unit == CSSParserValue::Function)
+ && (equalIgnoringCase(value->function->name, "calc(")
+ || equalIgnoringCase(value->function->name, "-webkit-calc(")
+ || equalIgnoringCase(value->function->name, "-webkit-min(")
+ || equalIgnoringCase(value->function->name, "-webkit-max("));
+}
+
+inline int CSSPropertyParser::colorIntFromValue(CSSParserValue* v)
+{
+ bool isPercent;
+
+ if (m_parsedCalculation)
+ isPercent = m_parsedCalculation->category() == CalcPercent;
+ else
+ isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE;
+
+ const double value = parsedDouble(v, ReleaseParsedCalcValue);
+
+ if (value <= 0.0)
+ return 0;
+
+ if (isPercent) {
+ if (value >= 100.0)
+ return 255;
+ return static_cast<int>(value * 256.0 / 100.0);
+ }
+
+ if (value >= 255.0)
+ return 255;
+
+ return static_cast<int>(value);
+}
+
+bool CSSPropertyParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha)
+{
+ CSSParserValueList* args = value->function->args.get();
+ CSSParserValue* v = args->current();
+ Units unitType = FUnknown;
+ // Get the first value and its type
+ if (validUnit(v, FInteger, HTMLStandardMode))
+ unitType = FInteger;
+ else if (validUnit(v, FPercent, HTMLStandardMode))
+ unitType = FPercent;
+ else
+ return false;
+
+ colorArray[0] = colorIntFromValue(v);
+ for (int i = 1; i < 3; i++) {
+ v = args->next();
+ if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+ return false;
+ v = args->next();
+ if (!validUnit(v, unitType, HTMLStandardMode))
+ return false;
+ colorArray[i] = colorIntFromValue(v);
+ }
+ if (parseAlpha) {
+ v = args->next();
+ if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+ return false;
+ v = args->next();
+ if (!validUnit(v, FNumber, HTMLStandardMode))
+ return false;
+ const double value = parsedDouble(v, ReleaseParsedCalcValue);
+ // Convert the floating pointer number of alpha to an integer in the range [0, 256),
+ // with an equal distribution across all 256 values.
+ colorArray[3] = static_cast<int>(std::max(0.0, std::min(1.0, value)) * nextafter(256.0, 0.0));
+ }
+ return true;
+}
+
+// The CSS3 specification defines the format of a HSL color as
+// hsl(<number>, <percent>, <percent>)
+// and with alpha, the format is
+// hsla(<number>, <percent>, <percent>, <number>)
+// The first value, HUE, is in an angle with a value between 0 and 360
+bool CSSPropertyParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bool parseAlpha)
+{
+ CSSParserValueList* args = value->function->args.get();
+ CSSParserValue* v = args->current();
+ // Get the first value
+ if (!validUnit(v, FNumber, HTMLStandardMode))
+ return false;
+ // normalize the Hue value and change it to be between 0 and 1.0
+ colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0;
+ for (int i = 1; i < 3; i++) {
+ v = args->next();
+ if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+ return false;
+ v = args->next();
+ if (!validUnit(v, FPercent, HTMLStandardMode))
+ return false;
+ colorArray[i] = std::max(0.0, std::min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0
+ }
+ if (parseAlpha) {
+ v = args->next();
+ if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+ return false;
+ v = args->next();
+ if (!validUnit(v, FNumber, HTMLStandardMode))
+ return false;
+ colorArray[3] = std::max(0.0, std::min(1.0, parsedDouble(v, ReleaseParsedCalcValue)));
+ }
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseColor(CSSParserValue* value)
+{
+ RGBA32 c = Color::transparent;
+ if (!parseColorFromValue(value ? value : m_valueList->current(), c))
+ return nullptr;
+ return cssValuePool().createColorValue(c);
+}
+
+bool CSSPropertyParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
+{
+ if (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_NUMBER
+ && value->fValue >= 0. && value->fValue < 1000000.) {
+ String str = String::format("%06d", static_cast<int>((value->fValue+.5)));
+ // FIXME: This should be strict parsing for SVG as well.
+ if (!fastParseColor(c, str, !inQuirksMode()))
+ return false;
+ } else if (value->unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR ||
+ value->unit == CSSPrimitiveValue::CSS_IDENT ||
+ (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) {
+ if (!fastParseColor(c, value->string, !inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_IDENT))
+ return false;
+ } else if (value->unit == CSSParserValue::Function &&
+ value->function->args != 0 &&
+ value->function->args->size() == 5 /* rgb + two commas */ &&
+ equalIgnoringCase(value->function->name, "rgb(")) {
+ int colorValues[3];
+ if (!parseColorParameters(value, colorValues, false))
+ return false;
+ c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
+ } else {
+ if (value->unit == CSSParserValue::Function &&
+ value->function->args != 0 &&
+ value->function->args->size() == 7 /* rgba + three commas */ &&
+ equalIgnoringCase(value->function->name, "rgba(")) {
+ int colorValues[4];
+ if (!parseColorParameters(value, colorValues, true))
+ return false;
+ c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
+ } else if (value->unit == CSSParserValue::Function &&
+ value->function->args != 0 &&
+ value->function->args->size() == 5 /* hsl + two commas */ &&
+ equalIgnoringCase(value->function->name, "hsl(")) {
+ double colorValues[3];
+ if (!parseHSLParameters(value, colorValues, false))
+ return false;
+ c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
+ } else if (value->unit == CSSParserValue::Function &&
+ value->function->args != 0 &&
+ value->function->args->size() == 7 /* hsla + three commas */ &&
+ equalIgnoringCase(value->function->name, "hsla(")) {
+ double colorValues[4];
+ if (!parseHSLParameters(value, colorValues, true))
+ return false;
+ c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
+ } else
+ return false;
+ }
+
+ return true;
+}
+
+// This class tracks parsing state for shadow values. If it goes out of scope (e.g., due to an early return)
+// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
+class ShadowParseContext {
+ STACK_ALLOCATED();
+public:
+ ShadowParseContext(CSSPropertyID prop, CSSPropertyParser* parser)
+ : property(prop)
+ , m_parser(parser)
+ , allowX(true)
+ , allowY(false)
+ , allowBlur(false)
+ , allowSpread(false)
+ , allowColor(true)
+ , allowStyle(prop == CSSPropertyWebkitBoxShadow || prop == CSSPropertyBoxShadow)
+ , allowBreak(true)
+ {
+ }
+
+ bool allowLength() { return allowX || allowY || allowBlur || allowSpread; }
+
+ void commitValue()
+ {
+ // Handle the ,, case gracefully by doing nothing.
+ if (x || y || blur || spread || color || style) {
+ if (!values)
+ values = CSSValueList::createCommaSeparated();
+
+ // Construct the current shadow value and add it to the list.
+ values->append(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
+ }
+
+ // Now reset for the next shadow value.
+ x = nullptr;
+ y = nullptr;
+ blur = nullptr;
+ spread = nullptr;
+ style = nullptr;
+ color = nullptr;
+
+ allowX = true;
+ allowColor = true;
+ allowBreak = true;
+ allowY = false;
+ allowBlur = false;
+ allowSpread = false;
+ allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+ }
+
+ void commitLength(CSSParserValue* v)
+ {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
+
+ if (allowX) {
+ x = val.release();
+ allowX = false;
+ allowY = true;
+ allowColor = false;
+ allowStyle = false;
+ allowBreak = false;
+ } else if (allowY) {
+ y = val.release();
+ allowY = false;
+ allowBlur = true;
+ allowColor = true;
+ allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+ allowBreak = true;
+ } else if (allowBlur) {
+ blur = val.release();
+ allowBlur = false;
+ allowSpread = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+ } else if (allowSpread) {
+ spread = val.release();
+ allowSpread = false;
+ }
+ }
+
+ void commitColor(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val)
+ {
+ color = val;
+ allowColor = false;
+ if (allowX) {
+ allowStyle = false;
+ allowBreak = false;
+ } else {
+ allowBlur = false;
+ allowSpread = false;
+ allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+ }
+ }
+
+ void commitStyle(CSSParserValue* v)
+ {
+ style = cssValuePool().createIdentifierValue(v->id);
+ allowStyle = false;
+ if (allowX)
+ allowBreak = false;
+ else {
+ allowBlur = false;
+ allowSpread = false;
+ allowColor = false;
+ }
+ }
+
+ CSSPropertyID property;
+ CSSPropertyParser* m_parser;
+
+ RefPtrWillBeMember<CSSValueList> values;
+ RefPtrWillBeMember<CSSPrimitiveValue> x;
+ RefPtrWillBeMember<CSSPrimitiveValue> y;
+ RefPtrWillBeMember<CSSPrimitiveValue> blur;
+ RefPtrWillBeMember<CSSPrimitiveValue> spread;
+ RefPtrWillBeMember<CSSPrimitiveValue> style;
+ RefPtrWillBeMember<CSSPrimitiveValue> color;
+
+ bool allowX;
+ bool allowY;
+ bool allowBlur;
+ bool allowSpread;
+ bool allowColor;
+ bool allowStyle; // inset or not.
+ bool allowBreak;
+};
+
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseShadow(CSSParserValueList* valueList, CSSPropertyID propId)
+{
+ ShadowParseContext context(propId, this);
+ CSSParserValue* val;
+ while ((val = valueList->current())) {
+ // Check for a comma break first.
+ if (val->unit == CSSParserValue::Operator) {
+ if (val->iValue != ',' || !context.allowBreak) {
+ // Other operators aren't legal or we aren't done with the current shadow
+ // value. Treat as invalid.
+ return nullptr;
+ }
+ // The value is good. Commit it.
+ context.commitValue();
+ } else if (validUnit(val, FLength, HTMLStandardMode)) {
+ // We required a length and didn't get one. Invalid.
+ if (!context.allowLength())
+ return nullptr;
+
+ // Blur radius must be non-negative.
+ if (context.allowBlur && !validUnit(val, FLength | FNonNeg, HTMLStandardMode))
+ return nullptr;
+
+ // A length is allowed here. Construct the value and add it.
+ context.commitLength(val);
+ } else if (val->id == CSSValueInset) {
+ if (!context.allowStyle)
+ return nullptr;
+
+ context.commitStyle(val);
+ } else {
+ // The only other type of value that's ok is a color value.
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedColor = nullptr;
+ bool isColor = ((val->id >= CSSValueAqua && val->id <= CSSValueWindowtext) || val->id == CSSValueMenu
+ || (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && inQuirksMode())
+ || val->id == CSSValueCurrentcolor);
+ if (isColor) {
+ if (!context.allowColor)
+ return nullptr;
+ parsedColor = cssValuePool().createIdentifierValue(val->id);
+ }
+
+ if (!parsedColor)
+ // It's not built-in. Try to parse it as a color.
+ parsedColor = parseColor(val);
+
+ if (!parsedColor || !context.allowColor)
+ return nullptr; // This value is not a color or length and is invalid or
+ // it is a color, but a color isn't allowed at this point.
+
+ context.commitColor(parsedColor.release());
+ }
+
+ valueList->next();
+ }
+
+ if (context.allowBreak) {
+ context.commitValue();
+ if (context.values && context.values->length())
+ return context.values.release();
+ }
+
+ return nullptr;
+}
+
+bool CSSPropertyParser::parseReflect(CSSPropertyID propId, bool important)
+{
+ // box-reflect: <direction> <offset> <mask>
+
+ // Direction comes first.
+ CSSParserValue* val = m_valueList->current();
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> direction = nullptr;
+ switch (val->id) {
+ case CSSValueAbove:
+ case CSSValueBelow:
+ case CSSValueLeft:
+ case CSSValueRight:
+ direction = cssValuePool().createIdentifierValue(val->id);
+ break;
+ default:
+ return false;
+ }
+
+ // The offset comes next.
+ val = m_valueList->next();
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> offset = nullptr;
+ if (!val)
+ offset = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
+ else {
+ if (!validUnit(val, FLength | FPercent))
+ return false;
+ offset = createPrimitiveNumericValue(val);
+ }
+
+ // Now for the mask.
+ RefPtrWillBeRawPtr<CSSValue> mask = nullptr;
+ val = m_valueList->next();
+ if (val) {
+ mask = parseBorderImage(propId);
+ if (!mask)
+ return false;
+ }
+
+ RefPtrWillBeRawPtr<CSSReflectValue> reflectValue = CSSReflectValue::create(direction.release(), offset.release(), mask.release());
+ addProperty(propId, reflectValue.release(), important);
+ m_valueList->next();
+ return true;
+}
+
+bool CSSPropertyParser::parseFlex(CSSParserValueList* args, bool important)
+{
+ if (!args || !args->size() || args->size() > 3)
+ return false;
+ static const double unsetValue = -1;
+ double flexGrow = unsetValue;
+ double flexShrink = unsetValue;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> flexBasis = nullptr;
+
+ while (CSSParserValue* arg = args->current()) {
+ if (validUnit(arg, FNumber | FNonNeg)) {
+ if (flexGrow == unsetValue)
+ flexGrow = arg->fValue;
+ else if (flexShrink == unsetValue)
+ flexShrink = arg->fValue;
+ else if (!arg->fValue) {
+ // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set.
+ flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
+ } else {
+ // We only allow 3 numbers without units if the last value is 0. E.g., flex:1 1 1 is invalid.
+ return false;
+ }
+ } else if (!flexBasis && (arg->id == CSSValueAuto || validUnit(arg, FLength | FPercent | FNonNeg)))
+ flexBasis = parseValidPrimitive(arg->id, arg);
+ else {
+ // Not a valid arg for flex.
+ return false;
+ }
+ args->next();
+ }
+
+ if (flexGrow == unsetValue)
+ flexGrow = 1;
+ if (flexShrink == unsetValue)
+ flexShrink = 1;
+ if (!flexBasis)
+ flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
+
+ addProperty(CSSPropertyFlexGrow, cssValuePool().createValue(clampToFloat(flexGrow), CSSPrimitiveValue::CSS_NUMBER), important);
+ addProperty(CSSPropertyFlexShrink, cssValuePool().createValue(clampToFloat(flexShrink), CSSPrimitiveValue::CSS_NUMBER), important);
+ addProperty(CSSPropertyFlexBasis, flexBasis, important);
+ return true;
+}
+
+bool CSSPropertyParser::parseObjectPosition(bool important)
+{
+ RefPtrWillBeRawPtr<CSSValue> xValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> yValue = nullptr;
+ parseFillPosition(m_valueList.get(), xValue, yValue);
+ if (!xValue || !yValue)
+ return false;
+ addProperty(
+ CSSPropertyObjectPosition,
+ createPrimitiveValuePair(toCSSPrimitiveValue(xValue.get()), toCSSPrimitiveValue(yValue.get()), Pair::KeepIdenticalValues),
+ important);
+ return true;
+}
+
+class BorderImageParseContext {
+ STACK_ALLOCATED();
+public:
+ BorderImageParseContext()
+ : m_canAdvance(false)
+ , m_allowCommit(true)
+ , m_allowImage(true)
+ , m_allowImageSlice(true)
+ , m_allowRepeat(true)
+ , m_allowForwardSlashOperator(false)
+ , m_requireWidth(false)
+ , m_requireOutset(false)
+ {}
+
+ bool canAdvance() const { return m_canAdvance; }
+ void setCanAdvance(bool canAdvance) { m_canAdvance = canAdvance; }
+
+ bool allowCommit() const { return m_allowCommit; }
+ bool allowImage() const { return m_allowImage; }
+ bool allowImageSlice() const { return m_allowImageSlice; }
+ bool allowRepeat() const { return m_allowRepeat; }
+ bool allowForwardSlashOperator() const { return m_allowForwardSlashOperator; }
+
+ bool requireWidth() const { return m_requireWidth; }
+ bool requireOutset() const { return m_requireOutset; }
+
+ void commitImage(PassRefPtrWillBeRawPtr<CSSValue> image)
+ {
+ m_image = image;
+ m_canAdvance = true;
+ m_allowCommit = true;
+ m_allowImage = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+ m_allowImageSlice = !m_imageSlice;
+ m_allowRepeat = !m_repeat;
+ }
+ void commitImageSlice(PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> slice)
+ {
+ m_imageSlice = slice;
+ m_canAdvance = true;
+ m_allowCommit = m_allowForwardSlashOperator = true;
+ m_allowImageSlice = m_requireWidth = m_requireOutset = false;
+ m_allowImage = !m_image;
+ m_allowRepeat = !m_repeat;
+ }
+ void commitForwardSlashOperator()
+ {
+ m_canAdvance = true;
+ m_allowCommit = m_allowImage = m_allowImageSlice = m_allowRepeat = m_allowForwardSlashOperator = false;
+ if (!m_borderSlice) {
+ m_requireWidth = true;
+ m_requireOutset = false;
+ } else {
+ m_requireOutset = true;
+ m_requireWidth = false;
+ }
+ }
+ void commitBorderWidth(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> slice)
+ {
+ m_borderSlice = slice;
+ m_canAdvance = true;
+ m_allowCommit = m_allowForwardSlashOperator = true;
+ m_allowImageSlice = m_requireWidth = m_requireOutset = false;
+ m_allowImage = !m_image;
+ m_allowRepeat = !m_repeat;
+ }
+ void commitBorderOutset(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> outset)
+ {
+ m_outset = outset;
+ m_canAdvance = true;
+ m_allowCommit = true;
+ m_allowImageSlice = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+ m_allowImage = !m_image;
+ m_allowRepeat = !m_repeat;
+ }
+ void commitRepeat(PassRefPtrWillBeRawPtr<CSSValue> repeat)
+ {
+ m_repeat = repeat;
+ m_canAdvance = true;
+ m_allowCommit = true;
+ m_allowRepeat = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+ m_allowImageSlice = !m_imageSlice;
+ m_allowImage = !m_image;
+ }
+
+ PassRefPtrWillBeRawPtr<CSSValue> commitCSSValue()
+ {
+ return createBorderImageValue(m_image, m_imageSlice.get(), m_borderSlice.get(), m_outset.get(), m_repeat.get());
+ }
+
+ void commitMaskBoxImage(CSSPropertyParser* parser, bool important)
+ {
+ commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageSource, parser, m_image, important);
+ commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageSlice, parser, m_imageSlice.get(), important);
+ commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageWidth, parser, m_borderSlice.get(), important);
+ commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageOutset, parser, m_outset.get(), important);
+ commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageRepeat, parser, m_repeat.get(), important);
+ }
+
+ void commitBorderImage(CSSPropertyParser* parser, bool important)
+ {
+ commitBorderImageProperty(CSSPropertyBorderImageSource, parser, m_image, important);
+ commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice.get(), important);
+ commitBorderImageProperty(CSSPropertyBorderImageWidth, parser, m_borderSlice.get(), important);
+ commitBorderImageProperty(CSSPropertyBorderImageOutset, parser, m_outset.get(), important);
+ commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, m_repeat, important);
+ }
+
+ void commitBorderImageProperty(CSSPropertyID propId, CSSPropertyParser* parser, PassRefPtrWillBeRawPtr<CSSValue> value, bool important)
+ {
+ if (value)
+ parser->addProperty(propId, value, important);
+ else
+ parser->addProperty(propId, cssValuePool().createImplicitInitialValue(), important, true);
+ }
+
+ static bool buildFromParser(CSSPropertyParser&, CSSPropertyID, BorderImageParseContext&);
+
+ bool m_canAdvance;
+
+ bool m_allowCommit;
+ bool m_allowImage;
+ bool m_allowImageSlice;
+ bool m_allowRepeat;
+ bool m_allowForwardSlashOperator;
+
+ bool m_requireWidth;
+ bool m_requireOutset;
+
+ RefPtrWillBeMember<CSSValue> m_image;
+ RefPtrWillBeMember<CSSBorderImageSliceValue> m_imageSlice;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_borderSlice;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_outset;
+
+ RefPtrWillBeMember<CSSValue> m_repeat;
+};
+
+bool BorderImageParseContext::buildFromParser(CSSPropertyParser& parser, CSSPropertyID propId, BorderImageParseContext& context)
+{
+ CSSPropertyParser::ShorthandScope scope(&parser, propId);
+ while (CSSParserValue* val = parser.m_valueList->current()) {
+ context.setCanAdvance(false);
+
+ if (!context.canAdvance() && context.allowForwardSlashOperator() && isForwardSlashOperator(val))
+ context.commitForwardSlashOperator();
+
+ if (!context.canAdvance() && context.allowImage()) {
+ if (val->unit == CSSPrimitiveValue::CSS_URI) {
+ context.commitImage(parser.createCSSImageValueWithReferrer(val->string, parser.m_context.completeURL(val->string)));
+ } else if (isGeneratedImageValue(val)) {
+ RefPtrWillBeRawPtr<CSSValue> value = nullptr;
+ if (parser.parseGeneratedImage(parser.m_valueList.get(), value))
+ context.commitImage(value.release());
+ else
+ return false;
+ } else if (val->unit == CSSParserValue::Function && equalIgnoringCase(val->function->name, "-webkit-image-set(")) {
+ RefPtrWillBeRawPtr<CSSValue> value = parser.parseImageSet(parser.m_valueList.get());
+ if (value)
+ context.commitImage(value.release());
+ else
+ return false;
+ } else if (val->id == CSSValueNone)
+ context.commitImage(cssValuePool().createIdentifierValue(CSSValueNone));
+ }
+
+ if (!context.canAdvance() && context.allowImageSlice()) {
+ RefPtrWillBeRawPtr<CSSBorderImageSliceValue> imageSlice = nullptr;
+ if (parser.parseBorderImageSlice(propId, imageSlice))
+ context.commitImageSlice(imageSlice.release());
+ }
+
+ if (!context.canAdvance() && context.allowRepeat()) {
+ RefPtrWillBeRawPtr<CSSValue> repeat = nullptr;
+ if (parser.parseBorderImageRepeat(repeat))
+ context.commitRepeat(repeat.release());
+ }
+
+ if (!context.canAdvance() && context.requireWidth()) {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> borderSlice = nullptr;
+ if (parser.parseBorderImageWidth(borderSlice))
+ context.commitBorderWidth(borderSlice.release());
+ }
+
+ if (!context.canAdvance() && context.requireOutset()) {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> borderOutset = nullptr;
+ if (parser.parseBorderImageOutset(borderOutset))
+ context.commitBorderOutset(borderOutset.release());
+ }
+
+ if (!context.canAdvance())
+ return false;
+
+ parser.m_valueList->next();
+ }
+
+ return context.allowCommit();
+}
+
+bool CSSPropertyParser::parseBorderImageShorthand(CSSPropertyID propId, bool important)
+{
+ BorderImageParseContext context;
+ if (BorderImageParseContext::buildFromParser(*this, propId, context)) {
+ switch (propId) {
+ case CSSPropertyWebkitMaskBoxImage:
+ context.commitMaskBoxImage(this, important);
+ return true;
+ case CSSPropertyBorderImage:
+ context.commitBorderImage(this, important);
+ return true;
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+ }
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseBorderImage(CSSPropertyID propId)
+{
+ BorderImageParseContext context;
+ if (BorderImageParseContext::buildFromParser(*this, propId, context)) {
+ return context.commitCSSValue();
+ }
+ return nullptr;
+}
+
+static bool isBorderImageRepeatKeyword(int id)
+{
+ return id == CSSValueStretch || id == CSSValueRepeat || id == CSSValueSpace || id == CSSValueRound;
+}
+
+bool CSSPropertyParser::parseBorderImageRepeat(RefPtrWillBeRawPtr<CSSValue>& result)
+{
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> firstValue = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> secondValue = nullptr;
+ CSSParserValue* val = m_valueList->current();
+ if (!val)
+ return false;
+ if (isBorderImageRepeatKeyword(val->id))
+ firstValue = cssValuePool().createIdentifierValue(val->id);
+ else
+ return false;
+
+ val = m_valueList->next();
+ if (val) {
+ if (isBorderImageRepeatKeyword(val->id))
+ secondValue = cssValuePool().createIdentifierValue(val->id);
+ else if (!inShorthand()) {
+ // If we're not parsing a shorthand then we are invalid.
+ return false;
+ } else {
+ // We need to rewind the value list, so that when its advanced we'll
+ // end up back at this value.
+ m_valueList->previous();
+ secondValue = firstValue;
+ }
+ } else
+ secondValue = firstValue;
+
+ result = createPrimitiveValuePair(firstValue, secondValue);
+ return true;
+}
+
+class BorderImageSliceParseContext {
+ STACK_ALLOCATED();
+public:
+ BorderImageSliceParseContext(CSSPropertyParser* parser)
+ : m_parser(parser)
+ , m_allowNumber(true)
+ , m_allowFill(true)
+ , m_allowFinalCommit(false)
+ , m_fill(false)
+ { }
+
+ bool allowNumber() const { return m_allowNumber; }
+ bool allowFill() const { return m_allowFill; }
+ bool allowFinalCommit() const { return m_allowFinalCommit; }
+ CSSPrimitiveValue* top() const { return m_top.get(); }
+
+ void commitNumber(CSSParserValue* v)
+ {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
+ if (!m_top)
+ m_top = val;
+ else if (!m_right)
+ m_right = val;
+ else if (!m_bottom)
+ m_bottom = val;
+ else {
+ ASSERT(!m_left);
+ m_left = val;
+ }
+
+ m_allowNumber = !m_left;
+ m_allowFinalCommit = true;
+ }
+
+ void commitFill() { m_fill = true; m_allowFill = false; m_allowNumber = !m_top; }
+
+ PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> commitBorderImageSlice()
+ {
+ // We need to clone and repeat values for any omissions.
+ ASSERT(m_top);
+ if (!m_right) {
+ m_right = m_top;
+ m_bottom = m_top;
+ m_left = m_top;
+ }
+ if (!m_bottom) {
+ m_bottom = m_top;
+ m_left = m_right;
+ }
+ if (!m_left)
+ m_left = m_right;
+
+ // Now build a rect value to hold all four of our primitive values.
+ RefPtrWillBeRawPtr<Quad> quad = Quad::create();
+ quad->setTop(m_top);
+ quad->setRight(m_right);
+ quad->setBottom(m_bottom);
+ quad->setLeft(m_left);
+
+ // Make our new border image value now.
+ return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), m_fill);
+ }
+
+private:
+ CSSPropertyParser* m_parser;
+
+ bool m_allowNumber;
+ bool m_allowFill;
+ bool m_allowFinalCommit;
+
+ RefPtrWillBeMember<CSSPrimitiveValue> m_top;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_right;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_bottom;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_left;
+
+ bool m_fill;
+};
+
+bool CSSPropertyParser::parseBorderImageSlice(CSSPropertyID propId, RefPtrWillBeRawPtr<CSSBorderImageSliceValue>& result)
+{
+ BorderImageSliceParseContext context(this);
+ CSSParserValue* val;
+ while ((val = m_valueList->current())) {
+ // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
+ if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, HTMLStandardMode)) {
+ context.commitNumber(val);
+ } else if (context.allowFill() && val->id == CSSValueFill)
+ context.commitFill();
+ else if (!inShorthand()) {
+ // If we're not parsing a shorthand then we are invalid.
+ return false;
+ } else {
+ if (context.allowFinalCommit()) {
+ // We're going to successfully parse, but we don't want to consume this token.
+ m_valueList->previous();
+ }
+ break;
+ }
+ m_valueList->next();
+ }
+
+ if (context.allowFinalCommit()) {
+ // FIXME: For backwards compatibility, -webkit-border-image, -webkit-mask-box-image and -webkit-box-reflect have to do a fill by default.
+ // FIXME: What do we do with -webkit-box-reflect and -webkit-mask-box-image? Probably just have to leave them filling...
+ if (propId == CSSPropertyWebkitBorderImage || propId == CSSPropertyWebkitMaskBoxImage || propId == CSSPropertyWebkitBoxReflect)
+ context.commitFill();
+
+ // Need to fully commit as a single value.
+ result = context.commitBorderImageSlice();
+ return true;
+ }
+
+ return false;
+}
+
+class BorderImageQuadParseContext {
+ STACK_ALLOCATED();
+public:
+ BorderImageQuadParseContext(CSSPropertyParser* parser)
+ : m_parser(parser)
+ , m_allowNumber(true)
+ , m_allowFinalCommit(false)
+ { }
+
+ bool allowNumber() const { return m_allowNumber; }
+ bool allowFinalCommit() const { return m_allowFinalCommit; }
+ CSSPrimitiveValue* top() const { return m_top.get(); }
+
+ void commitNumber(CSSParserValue* v)
+ {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> val = nullptr;
+ if (v->id == CSSValueAuto)
+ val = cssValuePool().createIdentifierValue(v->id);
+ else
+ val = m_parser->createPrimitiveNumericValue(v);
+
+ if (!m_top)
+ m_top = val;
+ else if (!m_right)
+ m_right = val;
+ else if (!m_bottom)
+ m_bottom = val;
+ else {
+ ASSERT(!m_left);
+ m_left = val;
+ }
+
+ m_allowNumber = !m_left;
+ m_allowFinalCommit = true;
+ }
+
+ void setTop(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_top = val; }
+
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> commitBorderImageQuad()
+ {
+ // We need to clone and repeat values for any omissions.
+ ASSERT(m_top);
+ if (!m_right) {
+ m_right = m_top;
+ m_bottom = m_top;
+ m_left = m_top;
+ }
+ if (!m_bottom) {
+ m_bottom = m_top;
+ m_left = m_right;
+ }
+ if (!m_left)
+ m_left = m_right;
+
+ // Now build a quad value to hold all four of our primitive values.
+ RefPtrWillBeRawPtr<Quad> quad = Quad::create();
+ quad->setTop(m_top);
+ quad->setRight(m_right);
+ quad->setBottom(m_bottom);
+ quad->setLeft(m_left);
+
+ // Make our new value now.
+ return cssValuePool().createValue(quad.release());
+ }
+
+private:
+ CSSPropertyParser* m_parser;
+
+ bool m_allowNumber;
+ bool m_allowFinalCommit;
+
+ RefPtrWillBeMember<CSSPrimitiveValue> m_top;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_right;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_bottom;
+ RefPtrWillBeMember<CSSPrimitiveValue> m_left;
+};
+
+bool CSSPropertyParser::parseBorderImageQuad(Units validUnits, RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
+{
+ BorderImageQuadParseContext context(this);
+ CSSParserValue* val;
+ while ((val = m_valueList->current())) {
+ if (context.allowNumber() && (validUnit(val, validUnits, HTMLStandardMode) || val->id == CSSValueAuto)) {
+ context.commitNumber(val);
+ } else if (!inShorthand()) {
+ // If we're not parsing a shorthand then we are invalid.
+ return false;
+ } else {
+ if (context.allowFinalCommit())
+ m_valueList->previous(); // The shorthand loop will advance back to this point.
+ break;
+ }
+ m_valueList->next();
+ }
+
+ if (context.allowFinalCommit()) {
+ // Need to fully commit as a single value.
+ result = context.commitBorderImageQuad();
+ return true;
+ }
+ return false;
+}
+
+bool CSSPropertyParser::parseBorderImageWidth(RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
+{
+ return parseBorderImageQuad(FLength | FNumber | FNonNeg | FPercent, result);
+}
+
+bool CSSPropertyParser::parseBorderImageOutset(RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
+{
+ return parseBorderImageQuad(FLength | FNumber | FNonNeg, result);
+}
+
+bool CSSPropertyParser::parseBorderRadius(CSSPropertyID propId, bool important)
+{
+ unsigned num = m_valueList->size();
+ if (num > 9)
+ return false;
+
+ ShorthandScope scope(this, propId);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[2][4];
+#if ENABLE(OILPAN)
+ // Zero initialize the array of raw pointers.
+ memset(&radii, 0, sizeof(radii));
+#endif
+
+ unsigned indexAfterSlash = 0;
+ for (unsigned i = 0; i < num; ++i) {
+ CSSParserValue* value = m_valueList->valueAt(i);
+ if (value->unit == CSSParserValue::Operator) {
+ if (value->iValue != '/')
+ return false;
+
+ if (!i || indexAfterSlash || i + 1 == num || num > i + 5)
+ return false;
+
+ indexAfterSlash = i + 1;
+ completeBorderRadii(radii[0]);
+ continue;
+ }
+
+ if (i - indexAfterSlash >= 4)
+ return false;
+
+ if (!validUnit(value, FLength | FPercent | FNonNeg))
+ return false;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value);
+
+ if (!indexAfterSlash) {
+ radii[0][i] = radius;
+
+ // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
+ if (num == 2 && propId == CSSPropertyWebkitBorderRadius) {
+ indexAfterSlash = 1;
+ completeBorderRadii(radii[0]);
+ }
+ } else
+ radii[1][i - indexAfterSlash] = radius.release();
+ }
+
+ if (!indexAfterSlash) {
+ completeBorderRadii(radii[0]);
+ for (unsigned i = 0; i < 4; ++i)
+ radii[1][i] = radii[0][i];
+ } else
+ completeBorderRadii(radii[1]);
+
+ ImplicitScope implicitScope(this, PropertyImplicit);
+ addProperty(CSSPropertyBorderTopLeftRadius, createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()), important);
+ addProperty(CSSPropertyBorderTopRightRadius, createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()), important);
+ addProperty(CSSPropertyBorderBottomRightRadius, createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()), important);
+ addProperty(CSSPropertyBorderBottomLeftRadius, createPrimitiveValuePair(radii[0][3].release(), radii[1][3].release()), important);
+ return true;
+}
+
+bool CSSPropertyParser::parseAspectRatio(bool important)
+{
+ unsigned num = m_valueList->size();
+ if (num == 1 && m_valueList->valueAt(0)->id == CSSValueNone) {
+ addProperty(CSSPropertyWebkitAspectRatio, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ return true;
+ }
+
+ if (num != 3)
+ return false;
+
+ CSSParserValue* lvalue = m_valueList->valueAt(0);
+ CSSParserValue* op = m_valueList->valueAt(1);
+ CSSParserValue* rvalue = m_valueList->valueAt(2);
+
+ if (!isForwardSlashOperator(op))
+ return false;
+
+ if (!validUnit(lvalue, FNumber | FNonNeg) || !validUnit(rvalue, FNumber | FNonNeg))
+ return false;
+
+ if (!lvalue->fValue || !rvalue->fValue)
+ return false;
+
+ addProperty(CSSPropertyWebkitAspectRatio, CSSAspectRatioValue::create(narrowPrecisionToFloat(lvalue->fValue), narrowPrecisionToFloat(rvalue->fValue)), important);
+
+ return true;
+}
+
+bool CSSPropertyParser::parseCounter(CSSPropertyID propId, int defaultValue, bool important)
+{
+ enum { ID, VAL } state = ID;
+
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> counterName = nullptr;
+
+ while (true) {
+ CSSParserValue* val = m_valueList->current();
+ switch (state) {
+ case ID:
+ if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
+ counterName = createPrimitiveStringValue(val);
+ state = VAL;
+ m_valueList->next();
+ continue;
+ }
+ break;
+ case VAL: {
+ int i = defaultValue;
+ if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) {
+ i = clampToInteger(val->fValue);
+ m_valueList->next();
+ }
+
+ list->append(createPrimitiveValuePair(counterName.release(),
+ cssValuePool().createValue(i, CSSPrimitiveValue::CSS_NUMBER)));
+ state = ID;
+ continue;
+ }
+ }
+ break;
+ }
+
+ if (list->length() > 0) {
+ addProperty(propId, list.release(), important);
+ return true;
+ }
+
+ return false;
+}
+
+// This should go away once we drop support for -webkit-gradient
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal)
+{
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> result = nullptr;
+ if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
+ if ((equalIgnoringCase(a, "left") && horizontal)
+ || (equalIgnoringCase(a, "top") && !horizontal))
+ result = cssValuePool().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
+ else if ((equalIgnoringCase(a, "right") && horizontal)
+ || (equalIgnoringCase(a, "bottom") && !horizontal))
+ result = cssValuePool().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
+ else if (equalIgnoringCase(a, "center"))
+ result = cssValuePool().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
+ } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE) {
+ result = cssValuePool().createValue(a->fValue, static_cast<CSSPrimitiveValue::UnitType>(a->unit));
+ }
+ return result;
+}
+
+bool parseDeprecatedGradientColorStop(CSSPropertyParser* p, CSSParserValue* a, CSSGradientColorStop& stop)
+{
+ if (a->unit != CSSParserValue::Function)
+ return false;
+
+ if (!equalIgnoringCase(a->function->name, "from(") &&
+ !equalIgnoringCase(a->function->name, "to(") &&
+ !equalIgnoringCase(a->function->name, "color-stop("))
+ return false;
+
+ CSSParserValueList* args = a->function->args.get();
+ if (!args)
+ return false;
+
+ if (equalIgnoringCase(a->function->name, "from(")
+ || equalIgnoringCase(a->function->name, "to(")) {
+ // The "from" and "to" stops expect 1 argument.
+ if (args->size() != 1)
+ return false;
+
+ if (equalIgnoringCase(a->function->name, "from("))
+ stop.m_position = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
+ else
+ stop.m_position = cssValuePool().createValue(1, CSSPrimitiveValue::CSS_NUMBER);
+
+ CSSValueID id = args->current()->id;
+ if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
+ stop.m_color = cssValuePool().createIdentifierValue(id);
+ else
+ stop.m_color = p->parseColor(args->current());
+ if (!stop.m_color)
+ return false;
+ }
+
+ // The "color-stop" function expects 3 arguments.
+ if (equalIgnoringCase(a->function->name, "color-stop(")) {
+ if (args->size() != 3)
+ return false;
+
+ CSSParserValue* stopArg = args->current();
+ if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+ stop.m_position = cssValuePool().createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
+ else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER)
+ stop.m_position = cssValuePool().createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
+ else
+ return false;
+
+ stopArg = args->next();
+ if (stopArg->unit != CSSParserValue::Operator || stopArg->iValue != ',')
+ return false;
+
+ stopArg = args->next();
+ CSSValueID id = stopArg->id;
+ if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
+ stop.m_color = cssValuePool().createIdentifierValue(id);
+ else
+ stop.m_color = p->parseColor(stopArg);
+ if (!stop.m_color)
+ return false;
+ }
+
+ return true;
+}
+
+bool CSSPropertyParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient)
+{
+ // Walk the arguments.
+ CSSParserValueList* args = valueList->current()->function->args.get();
+ if (!args || args->size() == 0)
+ return false;
+
+ // The first argument is the gradient type. It is an identifier.
+ CSSGradientType gradientType;
+ CSSParserValue* a = args->current();
+ if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
+ return false;
+ if (equalIgnoringCase(a, "linear"))
+ gradientType = CSSDeprecatedLinearGradient;
+ else if (equalIgnoringCase(a, "radial"))
+ gradientType = CSSDeprecatedRadialGradient;
+ else
+ return false;
+
+ RefPtrWillBeRawPtr<CSSGradientValue> result = nullptr;
+ switch (gradientType) {
+ case CSSDeprecatedLinearGradient:
+ result = CSSLinearGradientValue::create(NonRepeating, gradientType);
+ break;
+ case CSSDeprecatedRadialGradient:
+ result = CSSRadialGradientValue::create(NonRepeating, gradientType);
+ break;
+ default:
+ // The rest of the gradient types shouldn't appear here.
+ ASSERT_NOT_REACHED();
+ }
+
+ // Comma.
+ a = args->next();
+ if (!isComma(a))
+ return false;
+
+ // Next comes the starting point for the gradient as an x y pair. There is no
+ // comma between the x and the y values.
+ // First X. It can be left, right, number or percent.
+ a = args->next();
+ if (!a)
+ return false;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true);
+ if (!point)
+ return false;
+ result->setFirstX(point.release());
+
+ // First Y. It can be top, bottom, number or percent.
+ a = args->next();
+ if (!a)
+ return false;
+ point = parseDeprecatedGradientPoint(a, false);
+ if (!point)
+ return false;
+ result->setFirstY(point.release());
+
+ // Comma after the first point.
+ a = args->next();
+ if (!isComma(a))
+ return false;
+
+ // For radial gradients only, we now expect a numeric radius.
+ if (gradientType == CSSDeprecatedRadialGradient) {
+ a = args->next();
+ if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
+ return false;
+ toCSSRadialGradientValue(result.get())->setFirstRadius(createPrimitiveNumericValue(a));
+
+ // Comma after the first radius.
+ a = args->next();
+ if (!isComma(a))
+ return false;
+ }
+
+ // Next is the ending point for the gradient as an x, y pair.
+ // Second X. It can be left, right, number or percent.
+ a = args->next();
+ if (!a)
+ return false;
+ point = parseDeprecatedGradientPoint(a, true);
+ if (!point)
+ return false;
+ result->setSecondX(point.release());
+
+ // Second Y. It can be top, bottom, number or percent.
+ a = args->next();
+ if (!a)
+ return false;
+ point = parseDeprecatedGradientPoint(a, false);
+ if (!point)
+ return false;
+ result->setSecondY(point.release());
+
+ // For radial gradients only, we now expect the second radius.
+ if (gradientType == CSSDeprecatedRadialGradient) {
+ // Comma after the second point.
+ a = args->next();
+ if (!isComma(a))
+ return false;
+
+ a = args->next();
+ if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
+ return false;
+ toCSSRadialGradientValue(result.get())->setSecondRadius(createPrimitiveNumericValue(a));
+ }
+
+ // We now will accept any number of stops (0 or more).
+ a = args->next();
+ while (a) {
+ // Look for the comma before the next stop.
+ if (!isComma(a))
+ return false;
+
+ // Now examine the stop itself.
+ a = args->next();
+ if (!a)
+ return false;
+
+ // The function name needs to be one of "from", "to", or "color-stop."
+ CSSGradientColorStop stop;
+ if (!parseDeprecatedGradientColorStop(this, a, stop))
+ return false;
+ result->addStop(stop);
+
+ // Advance
+ a = args->next();
+ }
+
+ gradient = result.release();
+ return true;
+}
+
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal)
+{
+ if (a->unit != CSSPrimitiveValue::CSS_IDENT)
+ return nullptr;
+
+ switch (a->id) {
+ case CSSValueLeft:
+ case CSSValueRight:
+ isHorizontal = true;
+ break;
+ case CSSValueTop:
+ case CSSValueBottom:
+ isHorizontal = false;
+ break;
+ default:
+ return nullptr;
+ }
+ return cssValuePool().createIdentifierValue(a->id);
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSPropertyParser* p, CSSParserValue* value)
+{
+ CSSValueID id = value->id;
+ if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor)
+ return cssValuePool().createIdentifierValue(id);
+
+ return p->parseColor(value);
+}
+
+bool CSSPropertyParser::parseDeprecatedLinearGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
+{
+ RefPtrWillBeRawPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSPrefixedLinearGradient);
+
+ // Walk the arguments.
+ CSSParserValueList* args = valueList->current()->function->args.get();
+ if (!args || !args->size())
+ return false;
+
+ CSSParserValue* a = args->current();
+ if (!a)
+ return false;
+
+ bool expectComma = false;
+ // Look for angle.
+ if (validUnit(a, FAngle, HTMLStandardMode)) {
+ result->setAngle(createPrimitiveNumericValue(a));
+
+ args->next();
+ expectComma = true;
+ } else {
+ // Look one or two optional keywords that indicate a side or corner.
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> startX = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> startY = nullptr;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> location = nullptr;
+ bool isHorizontal = false;
+ if ((location = valueFromSideKeyword(a, isHorizontal))) {
+ if (isHorizontal)
+ startX = location;
+ else
+ startY = location;
+
+ if ((a = args->next())) {
+ if ((location = valueFromSideKeyword(a, isHorizontal))) {
+ if (isHorizontal) {
+ if (startX)
+ return false;
+ startX = location;
+ } else {
+ if (startY)
+ return false;
+ startY = location;
+ }
+
+ args->next();
+ }
+ }
+
+ expectComma = true;
+ }
+
+ if (!startX && !startY)
+ startY = cssValuePool().createIdentifierValue(CSSValueTop);
+
+ result->setFirstX(startX.release());
+ result->setFirstY(startY.release());
+ }
+
+ if (!parseGradientColorStops(args, result.get(), expectComma))
+ return false;
+
+ if (!result->stopCount())
+ return false;
+
+ gradient = result.release();
+ return true;
+}
+
+bool CSSPropertyParser::parseDeprecatedRadialGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
+{
+ RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient);
+
+ // Walk the arguments.
+ CSSParserValueList* args = valueList->current()->function->args.get();
+ if (!args || !args->size())
+ return false;
+
+ CSSParserValue* a = args->current();
+ if (!a)
+ return false;
+
+ bool expectComma = false;
+
+ // Optional background-position
+ RefPtrWillBeRawPtr<CSSValue> centerX = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> centerY = nullptr;
+ // parse2ValuesFillPosition advances the args next pointer.
+ parse2ValuesFillPosition(args, centerX, centerY);
+ a = args->current();
+ if (!a)
+ return false;
+
+ if (centerX || centerY) {
+ // Comma
+ if (!isComma(a))
+ return false;
+
+ a = args->next();
+ if (!a)
+ return false;
+ }
+
+ result->setFirstX(toCSSPrimitiveValue(centerX.get()));
+ result->setSecondX(toCSSPrimitiveValue(centerX.get()));
+ // CSS3 radial gradients always share the same start and end point.
+ result->setFirstY(toCSSPrimitiveValue(centerY.get()));
+ result->setSecondY(toCSSPrimitiveValue(centerY.get()));
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeValue = nullptr;
+
+ // Optional shape and/or size in any order.
+ for (int i = 0; i < 2; ++i) {
+ if (a->unit != CSSPrimitiveValue::CSS_IDENT)
+ break;
+
+ bool foundValue = false;
+ switch (a->id) {
+ case CSSValueCircle:
+ case CSSValueEllipse:
+ shapeValue = cssValuePool().createIdentifierValue(a->id);
+ foundValue = true;
+ break;
+ case CSSValueClosestSide:
+ case CSSValueClosestCorner:
+ case CSSValueFarthestSide:
+ case CSSValueFarthestCorner:
+ case CSSValueContain:
+ case CSSValueCover:
+ sizeValue = cssValuePool().createIdentifierValue(a->id);
+ foundValue = true;
+ break;
+ default:
+ break;
+ }
+
+ if (foundValue) {
+ a = args->next();
+ if (!a)
+ return false;
+
+ expectComma = true;
+ }
+ }
+
+ result->setShape(shapeValue);
+ result->setSizingBehavior(sizeValue);
+
+ // Or, two lengths or percentages
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize = nullptr;
+
+ if (!shapeValue && !sizeValue) {
+ if (validUnit(a, FLength | FPercent)) {
+ horizontalSize = createPrimitiveNumericValue(a);
+ a = args->next();
+ if (!a)
+ return false;
+
+ expectComma = true;
+ }
+
+ if (validUnit(a, FLength | FPercent)) {
+ verticalSize = createPrimitiveNumericValue(a);
+
+ a = args->next();
+ if (!a)
+ return false;
+ expectComma = true;
+ }
+ }
+
+ // Must have neither or both.
+ if (!horizontalSize != !verticalSize)
+ return false;
+
+ result->setEndHorizontalSize(horizontalSize);
+ result->setEndVerticalSize(verticalSize);
+
+ if (!parseGradientColorStops(args, result.get(), expectComma))
+ return false;
+
+ gradient = result.release();
+ return true;
+}
+
+bool CSSPropertyParser::parseLinearGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
+{
+ RefPtrWillBeRawPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSLinearGradient);
+
+ CSSParserValueList* args = valueList->current()->function->args.get();
+ if (!args || !args->size())
+ return false;
+
+ CSSParserValue* a = args->current();
+ if (!a)
+ return false;
+
+ bool expectComma = false;
+ // Look for angle.
+ if (validUnit(a, FAngle, HTMLStandardMode)) {
+ result->setAngle(createPrimitiveNumericValue(a));
+
+ args->next();
+ expectComma = true;
+ } else if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "to")) {
+ // to [ [left | right] || [top | bottom] ]
+ a = args->next();
+ if (!a)
+ return false;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> endX = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> endY = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> location = nullptr;
+ bool isHorizontal = false;
+
+ location = valueFromSideKeyword(a, isHorizontal);
+ if (!location)
+ return false;
+
+ if (isHorizontal)
+ endX = location;
+ else
+ endY = location;
+
+ a = args->next();
+ if (!a)
+ return false;
+
+ location = valueFromSideKeyword(a, isHorizontal);
+ if (location) {
+ if (isHorizontal) {
+ if (endX)
+ return false;
+ endX = location;
+ } else {
+ if (endY)
+ return false;
+ endY = location;
+ }
+
+ args->next();
+ }
+
+ expectComma = true;
+ result->setFirstX(endX.release());
+ result->setFirstY(endY.release());
+ }
+
+ if (!parseGradientColorStops(args, result.get(), expectComma))
+ return false;
+
+ if (!result->stopCount())
+ return false;
+
+ gradient = result.release();
+ return true;
+}
+
+bool CSSPropertyParser::parseRadialGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
+{
+ RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient);
+
+ CSSParserValueList* args = valueList->current()->function->args.get();
+ if (!args || !args->size())
+ return false;
+
+ CSSParserValue* a = args->current();
+ if (!a)
+ return false;
+
+ bool expectComma = false;
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeValue = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize = nullptr;
+
+ // First part of grammar, the size/shape clause:
+ // [ circle || <length> ] |
+ // [ ellipse || [ <length> | <percentage> ]{2} ] |
+ // [ [ circle | ellipse] || <size-keyword> ]
+ for (int i = 0; i < 3; ++i) {
+ if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
+ bool badIdent = false;
+ switch (a->id) {
+ case CSSValueCircle:
+ case CSSValueEllipse:
+ if (shapeValue)
+ return false;
+ shapeValue = cssValuePool().createIdentifierValue(a->id);
+ break;
+ case CSSValueClosestSide:
+ case CSSValueClosestCorner:
+ case CSSValueFarthestSide:
+ case CSSValueFarthestCorner:
+ if (sizeValue || horizontalSize)
+ return false;
+ sizeValue = cssValuePool().createIdentifierValue(a->id);
+ break;
+ default:
+ badIdent = true;
+ }
+
+ if (badIdent)
+ break;
+
+ a = args->next();
+ if (!a)
+ return false;
+ } else if (validUnit(a, FLength | FPercent)) {
+
+ if (sizeValue || horizontalSize)
+ return false;
+ horizontalSize = createPrimitiveNumericValue(a);
+
+ a = args->next();
+ if (!a)
+ return false;
+
+ if (validUnit(a, FLength | FPercent)) {
+ verticalSize = createPrimitiveNumericValue(a);
+ ++i;
+ a = args->next();
+ if (!a)
+ return false;
+ }
+ } else
+ break;
+ }
+
+ // You can specify size as a keyword or a length/percentage, not both.
+ if (sizeValue && horizontalSize)
+ return false;
+ // Circles must have 0 or 1 lengths.
+ if (shapeValue && shapeValue->getValueID() == CSSValueCircle && verticalSize)
+ return false;
+ // Ellipses must have 0 or 2 length/percentages.
+ if (shapeValue && shapeValue->getValueID() == CSSValueEllipse && horizontalSize && !verticalSize)
+ return false;
+ // If there's only one size, it must be a length.
+ if (!verticalSize && horizontalSize && horizontalSize->isPercentage())
+ return false;
+
+ result->setShape(shapeValue);
+ result->setSizingBehavior(sizeValue);
+ result->setEndHorizontalSize(horizontalSize);
+ result->setEndVerticalSize(verticalSize);
+
+ // Second part of grammar, the center-position clause:
+ // at <position>
+ RefPtrWillBeRawPtr<CSSValue> centerX = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> centerY = nullptr;
+ if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "at")) {
+ a = args->next();
+ if (!a)
+ return false;
+
+ parseFillPosition(args, centerX, centerY);
+ if (!(centerX && centerY))
+ return false;
+
+ a = args->current();
+ if (!a)
+ return false;
+ result->setFirstX(toCSSPrimitiveValue(centerX.get()));
+ result->setFirstY(toCSSPrimitiveValue(centerY.get()));
+ // Right now, CSS radial gradients have the same start and end centers.
+ result->setSecondX(toCSSPrimitiveValue(centerX.get()));
+ result->setSecondY(toCSSPrimitiveValue(centerY.get()));
+ }
+
+ if (shapeValue || sizeValue || horizontalSize || centerX || centerY)
+ expectComma = true;
+
+ if (!parseGradientColorStops(args, result.get(), expectComma))
+ return false;
+
+ gradient = result.release();
+ return true;
+}
+
+bool CSSPropertyParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradientValue* gradient, bool expectComma)
+{
+ CSSParserValue* a = valueList->current();
+
+ // Now look for color stops.
+ while (a) {
+ // Look for the comma before the next stop.
+ if (expectComma) {
+ if (!isComma(a))
+ return false;
+
+ a = valueList->next();
+ if (!a)
+ return false;
+ }
+
+ // <color-stop> = <color> [ <percentage> | <length> ]?
+ CSSGradientColorStop stop;
+ stop.m_color = parseGradientColorOrKeyword(this, a);
+ if (!stop.m_color)
+ return false;
+
+ a = valueList->next();
+ if (a) {
+ if (validUnit(a, FLength | FPercent)) {
+ stop.m_position = createPrimitiveNumericValue(a);
+ a = valueList->next();
+ }
+ }
+
+ gradient->addStop(stop);
+ expectComma = true;
+ }
+
+ // Must have 2 or more stops to be valid.
+ return gradient->stopCount() >= 2;
+}
+
+bool CSSPropertyParser::parseGeneratedImage(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value)
+{
+ CSSParserValue* val = valueList->current();
+
+ if (val->unit != CSSParserValue::Function)
+ return false;
+
+ if (equalIgnoringCase(val->function->name, "-webkit-gradient(")) {
+ // FIXME: This should send a deprecation message.
+ if (m_context.useCounter())
+ m_context.useCounter()->count(UseCounter::DeprecatedWebKitGradient);
+ return parseDeprecatedGradient(valueList, value);
+ }
+
+ if (equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")) {
+ // FIXME: This should send a deprecation message.
+ if (m_context.useCounter())
+ m_context.useCounter()->count(UseCounter::DeprecatedWebKitLinearGradient);
+ return parseDeprecatedLinearGradient(valueList, value, NonRepeating);
+ }
+
+ if (equalIgnoringCase(val->function->name, "linear-gradient("))
+ return parseLinearGradient(valueList, value, NonRepeating);
+
+ if (equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")) {
+ // FIXME: This should send a deprecation message.
+ if (m_context.useCounter())
+ m_context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLinearGradient);
+ return parseDeprecatedLinearGradient(valueList, value, Repeating);
+ }
+
+ if (equalIgnoringCase(val->function->name, "repeating-linear-gradient("))
+ return parseLinearGradient(valueList, value, Repeating);
+
+ if (equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")) {
+ // FIXME: This should send a deprecation message.
+ if (m_context.useCounter())
+ m_context.useCounter()->count(UseCounter::DeprecatedWebKitRadialGradient);
+ return parseDeprecatedRadialGradient(valueList, value, NonRepeating);
+ }
+
+ if (equalIgnoringCase(val->function->name, "radial-gradient("))
+ return parseRadialGradient(valueList, value, NonRepeating);
+
+ if (equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")) {
+ if (m_context.useCounter())
+ m_context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingRadialGradient);
+ return parseDeprecatedRadialGradient(valueList, value, Repeating);
+ }
+
+ if (equalIgnoringCase(val->function->name, "repeating-radial-gradient("))
+ return parseRadialGradient(valueList, value, Repeating);
+
+ if (equalIgnoringCase(val->function->name, "-webkit-canvas("))
+ return parseCanvas(valueList, value);
+
+ if (equalIgnoringCase(val->function->name, "-webkit-cross-fade("))
+ return parseCrossfade(valueList, value);
+
+ return false;
+}
+
+bool CSSPropertyParser::parseCrossfade(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& crossfade)
+{
+ // Walk the arguments.
+ CSSParserValueList* args = valueList->current()->function->args.get();
+ if (!args || args->size() != 5)
+ return false;
+ CSSParserValue* a = args->current();
+ RefPtrWillBeRawPtr<CSSValue> fromImageValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> toImageValue = nullptr;
+
+ // The first argument is the "from" image. It is a fill image.
+ if (!a || !parseFillImage(args, fromImageValue))
+ return false;
+ a = args->next();
+
+ // Skip a comma
+ if (!isComma(a))
+ return false;
+ a = args->next();
+
+ // The second argument is the "to" image. It is a fill image.
+ if (!a || !parseFillImage(args, toImageValue))
+ return false;
+ a = args->next();
+
+ // Skip a comma
+ if (!isComma(a))
+ return false;
+ a = args->next();
+
+ // The third argument is the crossfade value. It is a percentage or a fractional number.
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> percentage = nullptr;
+ if (!a)
+ return false;
+
+ if (a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+ percentage = cssValuePool().createValue(clampTo<double>(a->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
+ else if (a->unit == CSSPrimitiveValue::CSS_NUMBER)
+ percentage = cssValuePool().createValue(clampTo<double>(a->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
+ else
+ return false;
+
+ RefPtrWillBeRawPtr<CSSCrossfadeValue> result = CSSCrossfadeValue::create(fromImageValue, toImageValue);
+ result->setPercentage(percentage);
+
+ crossfade = result;
+
+ return true;
+}
+
+bool CSSPropertyParser::parseCanvas(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& canvas)
+{
+ // Walk the arguments.
+ CSSParserValueList* args = valueList->current()->function->args.get();
+ if (!args || args->size() != 1)
+ return false;
+
+ // The first argument is the canvas name. It is an identifier.
+ CSSParserValue* value = args->current();
+ if (!value || value->unit != CSSPrimitiveValue::CSS_IDENT)
+ return false;
+
+ canvas = CSSCanvasValue::create(value->string);
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseImageSet(CSSParserValueList* valueList)
+{
+ CSSParserValue* function = valueList->current();
+
+ if (function->unit != CSSParserValue::Function)
+ return nullptr;
+
+ CSSParserValueList* functionArgs = valueList->current()->function->args.get();
+ if (!functionArgs || !functionArgs->size() || !functionArgs->current())
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create();
+
+ CSSParserValue* arg = functionArgs->current();
+ while (arg) {
+ if (arg->unit != CSSPrimitiveValue::CSS_URI)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSValue> image = createCSSImageValueWithReferrer(arg->string, completeURL(arg->string));
+ imageSet->append(image);
+
+ arg = functionArgs->next();
+ if (!arg || arg->unit != CSSPrimitiveValue::CSS_DIMENSION)
+ return nullptr;
+
+ double imageScaleFactor = 0;
+ const String& string = arg->string;
+ unsigned length = string.length();
+ if (!length)
+ return nullptr;
+ if (string.is8Bit()) {
+ const LChar* start = string.characters8();
+ parseDouble(start, start + length, 'x', imageScaleFactor);
+ } else {
+ const UChar* start = string.characters16();
+ parseDouble(start, start + length, 'x', imageScaleFactor);
+ }
+ if (imageScaleFactor <= 0)
+ return nullptr;
+ imageSet->append(cssValuePool().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER));
+
+ // If there are no more arguments, we're done.
+ arg = functionArgs->next();
+ if (!arg)
+ break;
+
+ // If there are more arguments, they should be after a comma.
+ if (!isComma(arg))
+ return nullptr;
+
+ // Skip the comma and move on to the next argument.
+ arg = functionArgs->next();
+ }
+
+ return imageSet.release();
+}
+
+bool CSSPropertyParser::parseWillChange(bool important)
+{
+ ASSERT(RuntimeEnabledFeatures::cssWillChangeEnabled());
+
+ RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+ if (m_valueList->current()->id == CSSValueAuto) {
+ if (m_valueList->next())
+ return false;
+ }
+
+ CSSParserValue* currentValue;
+ bool expectComma = false;
+
+ // Every comma-separated list of CSS_IDENTs is a valid will-change value,
+ // unless the list includes an explicitly disallowed CSS_IDENT.
+ while ((currentValue = m_valueList->current())) {
+ if (expectComma) {
+ if (!isComma(currentValue))
+ return false;
+ expectComma = false;
+ m_valueList->next();
+ continue;
+ }
+
+ if (currentValue->unit != CSSPrimitiveValue::CSS_IDENT)
+ return false;
+
+ CSSPropertyID property = cssPropertyID(currentValue->string);
+ if (property && RuntimeCSSEnabled::isCSSPropertyEnabled(property)) {
+ // Now "all" is used by both CSSValue and CSSPropertyValue.
+ // Need to return false when currentValue is CSSPropertyAll.
+ if (property == CSSPropertyWillChange || property == CSSPropertyAll)
+ return false;
+ values->append(cssValuePool().createIdentifierValue(property));
+ } else {
+ switch (currentValue->id) {
+ case CSSValueNone:
+ case CSSValueAll:
+ case CSSValueAuto:
+ case CSSValueDefault:
+ case CSSValueInitial:
+ case CSSValueInherit:
+ return false;
+ case CSSValueContents:
+ case CSSValueScrollPosition:
+ values->append(cssValuePool().createIdentifierValue(currentValue->id));
+ break;
+ default:
+ break;
+ }
+ }
+ expectComma = true;
+ m_valueList->next();
+ }
+
+ addProperty(CSSPropertyWillChange, values.release(), important);
+ return true;
+}
+
+static void filterInfoForName(const CSSParserString& name, CSSFilterValue::FilterOperationType& filterType, unsigned& maximumArgumentCount)
+{
+ if (equalIgnoringCase(name, "grayscale("))
+ filterType = CSSFilterValue::GrayscaleFilterOperation;
+ else if (equalIgnoringCase(name, "sepia("))
+ filterType = CSSFilterValue::SepiaFilterOperation;
+ else if (equalIgnoringCase(name, "saturate("))
+ filterType = CSSFilterValue::SaturateFilterOperation;
+ else if (equalIgnoringCase(name, "hue-rotate("))
+ filterType = CSSFilterValue::HueRotateFilterOperation;
+ else if (equalIgnoringCase(name, "invert("))
+ filterType = CSSFilterValue::InvertFilterOperation;
+ else if (equalIgnoringCase(name, "opacity("))
+ filterType = CSSFilterValue::OpacityFilterOperation;
+ else if (equalIgnoringCase(name, "brightness("))
+ filterType = CSSFilterValue::BrightnessFilterOperation;
+ else if (equalIgnoringCase(name, "contrast("))
+ filterType = CSSFilterValue::ContrastFilterOperation;
+ else if (equalIgnoringCase(name, "blur("))
+ filterType = CSSFilterValue::BlurFilterOperation;
+ else if (equalIgnoringCase(name, "drop-shadow(")) {
+ filterType = CSSFilterValue::DropShadowFilterOperation;
+ maximumArgumentCount = 4; // x-offset, y-offset, blur-radius, color -- spread and inset style not allowed.
+ }
+}
+
+PassRefPtrWillBeRawPtr<CSSFilterValue> CSSPropertyParser::parseBuiltinFilterArguments(CSSParserValueList* args, CSSFilterValue::FilterOperationType filterType)
+{
+ RefPtrWillBeRawPtr<CSSFilterValue> filterValue = CSSFilterValue::create(filterType);
+ ASSERT(args);
+
+ switch (filterType) {
+ case CSSFilterValue::GrayscaleFilterOperation:
+ case CSSFilterValue::SepiaFilterOperation:
+ case CSSFilterValue::SaturateFilterOperation:
+ case CSSFilterValue::InvertFilterOperation:
+ case CSSFilterValue::OpacityFilterOperation:
+ case CSSFilterValue::ContrastFilterOperation: {
+ // One optional argument, 0-1 or 0%-100%, if missing use 100%.
+ if (args->size() > 1)
+ return nullptr;
+
+ if (args->size()) {
+ CSSParserValue* value = args->current();
+ if (!validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode))
+ return nullptr;
+
+ double amount = value->fValue;
+
+ // Saturate and Contrast allow values over 100%.
+ if (filterType != CSSFilterValue::SaturateFilterOperation
+ && filterType != CSSFilterValue::ContrastFilterOperation) {
+ double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
+ if (amount > maxAllowed)
+ return nullptr;
+ }
+
+ filterValue->append(cssValuePool().createValue(amount, static_cast<CSSPrimitiveValue::UnitType>(value->unit)));
+ }
+ break;
+ }
+ case CSSFilterValue::BrightnessFilterOperation: {
+ // One optional argument, if missing use 100%.
+ if (args->size() > 1)
+ return nullptr;
+
+ if (args->size()) {
+ CSSParserValue* value = args->current();
+ if (!validUnit(value, FNumber | FPercent, HTMLStandardMode))
+ return nullptr;
+
+ filterValue->append(cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitType>(value->unit)));
+ }
+ break;
+ }
+ case CSSFilterValue::HueRotateFilterOperation: {
+ // hue-rotate() takes one optional angle.
+ if (args->size() > 1)
+ return nullptr;
+
+ if (args->size()) {
+ CSSParserValue* argument = args->current();
+ if (!validUnit(argument, FAngle, HTMLStandardMode))
+ return nullptr;
+
+ filterValue->append(createPrimitiveNumericValue(argument));
+ }
+ break;
+ }
+ case CSSFilterValue::BlurFilterOperation: {
+ // Blur takes a single length. Zero parameters are allowed.
+ if (args->size() > 1)
+ return nullptr;
+
+ if (args->size()) {
+ CSSParserValue* argument = args->current();
+ if (!validUnit(argument, FLength | FNonNeg, HTMLStandardMode))
+ return nullptr;
+
+ filterValue->append(createPrimitiveNumericValue(argument));
+ }
+ break;
+ }
+ case CSSFilterValue::DropShadowFilterOperation: {
+ // drop-shadow() takes a single shadow.
+ RefPtrWillBeRawPtr<CSSValueList> shadowValueList = parseShadow(args, CSSPropertyWebkitFilter);
+ if (!shadowValueList || shadowValueList->length() != 1)
+ return nullptr;
+
+ filterValue->append((shadowValueList.release())->itemWithoutBoundsCheck(0));
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ return filterValue.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseFilter()
+{
+ if (!m_valueList)
+ return nullptr;
+
+ // The filter is a list of functional primitives that specify individual operations.
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+ if (value->unit != CSSPrimitiveValue::CSS_URI && (value->unit != CSSParserValue::Function || !value->function))
+ return nullptr;
+
+ CSSFilterValue::FilterOperationType filterType = CSSFilterValue::UnknownFilterOperation;
+
+ // See if the specified primitive is one we understand.
+ if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ RefPtrWillBeRawPtr<CSSFilterValue> referenceFilterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
+ list->append(referenceFilterValue);
+ referenceFilterValue->append(CSSSVGDocumentValue::create(value->string));
+ } else {
+ const CSSParserString name = value->function->name;
+ unsigned maximumArgumentCount = 1;
+
+ filterInfoForName(name, filterType, maximumArgumentCount);
+
+ if (filterType == CSSFilterValue::UnknownFilterOperation)
+ return nullptr;
+
+ CSSParserValueList* args = value->function->args.get();
+ if (!args)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSFilterValue> filterValue = parseBuiltinFilterArguments(args, filterType);
+ if (!filterValue)
+ return nullptr;
+
+ list->append(filterValue);
+ }
+ }
+
+ return list.release();
+}
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransformOrigin()
+{
+ CSSParserValue* value = m_valueList->current();
+ CSSValueID id = value->id;
+ RefPtrWillBeRawPtr<CSSValue> xValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> yValue = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> zValue = nullptr;
+ if (id == CSSValueLeft || id == CSSValueRight) {
+ xValue = cssValuePool().createIdentifierValue(id);
+ } else if (id == CSSValueTop || id == CSSValueBottom) {
+ yValue = cssValuePool().createIdentifierValue(id);
+ } else if (id == CSSValueCenter) {
+ // Unresolved as to whether this is X or Y.
+ } else if (validUnit(value, FPercent | FLength)) {
+ xValue = createPrimitiveNumericValue(value);
+ } else {
+ return nullptr;
+ }
+
+ if ((value = m_valueList->next())) {
+ id = value->id;
+ if (!xValue && (id == CSSValueLeft || id == CSSValueRight)) {
+ xValue = cssValuePool().createIdentifierValue(id);
+ } else if (!yValue && (id == CSSValueTop || id == CSSValueBottom)) {
+ yValue = cssValuePool().createIdentifierValue(id);
+ } else if (id == CSSValueCenter) {
+ // Resolved below.
+ } else if (!yValue && validUnit(value, FPercent | FLength)) {
+ yValue = createPrimitiveNumericValue(value);
+ } else {
+ return nullptr;
+ }
+
+ // If X or Y have not been resolved, they must be center.
+ if (!xValue)
+ xValue = cssValuePool().createIdentifierValue(CSSValueCenter);
+ if (!yValue)
+ yValue = cssValuePool().createIdentifierValue(CSSValueCenter);
+
+ if ((value = m_valueList->next())) {
+ if (!validUnit(value, FLength))
+ return nullptr;
+ zValue = createPrimitiveNumericValue(value);
+
+ if ((value = m_valueList->next()))
+ return nullptr;
+ }
+ } else if (!xValue) {
+ if (yValue) {
+ xValue = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+ } else {
+ xValue = cssValuePool().createIdentifierValue(CSSValueCenter);
+ }
+ }
+
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ list->append(xValue.release());
+ if (yValue)
+ list->append(yValue.release());
+ if (zValue)
+ list->append(zValue.release());
+ return list.release();
+}
+
+bool CSSPropertyParser::parseWebkitTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtrWillBeRawPtr<CSSValue>& value, RefPtrWillBeRawPtr<CSSValue>& value2, RefPtrWillBeRawPtr<CSSValue>& value3)
+{
+ propId1 = propId;
+ propId2 = propId;
+ propId3 = propId;
+ if (propId == CSSPropertyWebkitTransformOrigin) {
+ propId1 = CSSPropertyWebkitTransformOriginX;
+ propId2 = CSSPropertyWebkitTransformOriginY;
+ propId3 = CSSPropertyWebkitTransformOriginZ;
+ }
+
+ switch (propId) {
+ case CSSPropertyWebkitTransformOrigin:
+ if (!parseWebkitTransformOriginShorthand(value, value2, value3))
+ return false;
+ // parseWebkitTransformOriginShorthand advances the m_valueList pointer
+ break;
+ case CSSPropertyWebkitTransformOriginX: {
+ value = parseFillPositionX(m_valueList.get());
+ if (value)
+ m_valueList->next();
+ break;
+ }
+ case CSSPropertyWebkitTransformOriginY: {
+ value = parseFillPositionY(m_valueList.get());
+ if (value)
+ m_valueList->next();
+ break;
+ }
+ case CSSPropertyWebkitTransformOriginZ: {
+ if (validUnit(m_valueList->current(), FLength))
+ value = createPrimitiveNumericValue(m_valueList->current());
+ if (value)
+ m_valueList->next();
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ return value;
+}
+
+bool CSSPropertyParser::parseWebkitPerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>& value, RefPtrWillBeRawPtr<CSSValue>& value2)
+{
+ propId1 = propId;
+ propId2 = propId;
+ if (propId == CSSPropertyWebkitPerspectiveOrigin) {
+ propId1 = CSSPropertyWebkitPerspectiveOriginX;
+ propId2 = CSSPropertyWebkitPerspectiveOriginY;
+ }
+
+ switch (propId) {
+ case CSSPropertyWebkitPerspectiveOrigin:
+ if (m_valueList->size() > 2)
+ return false;
+ parse2ValuesFillPosition(m_valueList.get(), value, value2);
+ break;
+ case CSSPropertyWebkitPerspectiveOriginX: {
+ value = parseFillPositionX(m_valueList.get());
+ if (value)
+ m_valueList->next();
+ break;
+ }
+ case CSSPropertyWebkitPerspectiveOriginY: {
+ value = parseFillPositionY(m_valueList.get());
+ if (value)
+ m_valueList->next();
+ break;
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ return false;
+ }
+
+ return value;
+}
+
+bool CSSPropertyParser::parseTouchAction(bool important)
+{
+ if (!RuntimeEnabledFeatures::cssTouchActionEnabled())
+ return false;
+
+ CSSParserValue* value = m_valueList->current();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ if (m_valueList->size() == 1 && value && (value->id == CSSValueAuto || value->id == CSSValueNone || value->id == CSSValueManipulation)) {
+ list->append(cssValuePool().createIdentifierValue(value->id));
+ addProperty(CSSPropertyTouchAction, list.release(), important);
+ m_valueList->next();
+ return true;
+ }
+
+ bool isValid = true;
+ while (isValid && value) {
+ switch (value->id) {
+ case CSSValuePanX:
+ case CSSValuePanY: {
+ RefPtrWillBeRawPtr<CSSValue> panValue = cssValuePool().createIdentifierValue(value->id);
+ if (list->hasValue(panValue.get())) {
+ isValid = false;
+ break;
+ }
+ list->append(panValue.release());
+ break;
+ }
+ default:
+ isValid = false;
+ break;
+ }
+ if (isValid)
+ value = m_valueList->next();
+ }
+
+ if (list->length() && isValid) {
+ addProperty(CSSPropertyTouchAction, list.release(), important);
+ return true;
+ }
+
+ return false;
+}
+
+void CSSPropertyParser::addTextDecorationProperty(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue> value, bool important)
+{
+ // The text-decoration-line property takes priority over text-decoration, unless the latter has important priority set.
+ if (propId == CSSPropertyTextDecoration && !important && !inShorthand()) {
+ for (unsigned i = 0; i < m_parsedProperties.size(); ++i) {
+ if (m_parsedProperties[i].id() == CSSPropertyTextDecorationLine)
+ return;
+ }
+ }
+ addProperty(propId, value, important);
+}
+
+bool CSSPropertyParser::parseTextDecoration(CSSPropertyID propId, bool important)
+{
+ if (propId == CSSPropertyTextDecorationLine
+ && !RuntimeEnabledFeatures::css3TextDecorationsEnabled())
+ return false;
+
+ CSSParserValue* value = m_valueList->current();
+ if (value && value->id == CSSValueNone) {
+ addTextDecorationProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ m_valueList->next();
+ return true;
+ }
+
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ bool isValid = true;
+ while (isValid && value) {
+ switch (value->id) {
+ case CSSValueUnderline:
+ case CSSValueOverline:
+ case CSSValueLineThrough:
+ case CSSValueBlink:
+ list->append(cssValuePool().createIdentifierValue(value->id));
+ break;
+ default:
+ isValid = false;
+ break;
+ }
+ if (isValid)
+ value = m_valueList->next();
+ }
+
+ // Values are either valid or in shorthand scope.
+ if (list->length() && (isValid || inShorthand())) {
+ addTextDecorationProperty(propId, list.release(), important);
+ return true;
+ }
+
+ return false;
+}
+
+bool CSSPropertyParser::parseTextUnderlinePosition(bool important)
+{
+ // The text-underline-position property has syntax "auto | [ under || [ left | right ] ]".
+ // However, values 'left' and 'right' are not implemented yet, so we will parse syntax
+ // "auto | under" for now.
+ CSSParserValue* value = m_valueList->current();
+ switch (value->id) {
+ case CSSValueAuto:
+ case CSSValueUnder:
+ if (m_valueList->next())
+ return false;
+ addProperty(CSSPropertyTextUnderlinePosition, cssValuePool().createIdentifierValue(value->id), important);
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool CSSPropertyParser::parseTextEmphasisStyle(bool important)
+{
+ unsigned valueListSize = m_valueList->size();
+
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> fill = nullptr;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> shape = nullptr;
+
+ for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+ if (value->unit == CSSPrimitiveValue::CSS_STRING) {
+ if (fill || shape || (valueListSize != 1 && !inShorthand()))
+ return false;
+ addProperty(CSSPropertyWebkitTextEmphasisStyle, createPrimitiveStringValue(value), important);
+ m_valueList->next();
+ return true;
+ }
+
+ if (value->id == CSSValueNone) {
+ if (fill || shape || (valueListSize != 1 && !inShorthand()))
+ return false;
+ addProperty(CSSPropertyWebkitTextEmphasisStyle, cssValuePool().createIdentifierValue(CSSValueNone), important);
+ m_valueList->next();
+ return true;
+ }
+
+ if (value->id == CSSValueOpen || value->id == CSSValueFilled) {
+ if (fill)
+ return false;
+ fill = cssValuePool().createIdentifierValue(value->id);
+ } else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) {
+ if (shape)
+ return false;
+ shape = cssValuePool().createIdentifierValue(value->id);
+ } else if (!inShorthand())
+ return false;
+ else
+ break;
+ }
+
+ if (fill && shape) {
+ RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
+ parsedValues->append(fill.release());
+ parsedValues->append(shape.release());
+ addProperty(CSSPropertyWebkitTextEmphasisStyle, parsedValues.release(), important);
+ return true;
+ }
+ if (fill) {
+ addProperty(CSSPropertyWebkitTextEmphasisStyle, fill.release(), important);
+ return true;
+ }
+ if (shape) {
+ addProperty(CSSPropertyWebkitTextEmphasisStyle, shape.release(), important);
+ return true;
+ }
+
+ return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTextIndent()
+{
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+
+ bool hasLengthOrPercentage = false;
+ bool hasEachLine = false;
+ bool hasHanging = false;
+
+ for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+ // <length> | <percentage> | inherit when RuntimeEnabledFeatures::css3TextEnabled() returns false
+ if (!hasLengthOrPercentage && validUnit(value, FLength | FPercent)) {
+ list->append(createPrimitiveNumericValue(value));
+ hasLengthOrPercentage = true;
+ continue;
+ }
+
+ // [ <length> | <percentage> ] && hanging? && each-line? | inherit
+ // when RuntimeEnabledFeatures::css3TextEnabled() returns true
+ if (RuntimeEnabledFeatures::css3TextEnabled()) {
+ if (!hasEachLine && value->id == CSSValueEachLine) {
+ list->append(cssValuePool().createIdentifierValue(CSSValueEachLine));
+ hasEachLine = true;
+ continue;
+ }
+ if (!hasHanging && value->id == CSSValueHanging) {
+ list->append(cssValuePool().createIdentifierValue(CSSValueHanging));
+ hasHanging = true;
+ continue;
+ }
+ }
+ return nullptr;
+ }
+
+ if (!hasLengthOrPercentage)
+ return nullptr;
+
+ return list.release();
+}
+
+bool CSSPropertyParser::parseLineBoxContain(bool important)
+{
+ LineBoxContain lineBoxContain = LineBoxContainNone;
+
+ for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+ if (value->id == CSSValueBlock) {
+ if (lineBoxContain & LineBoxContainBlock)
+ return false;
+ lineBoxContain |= LineBoxContainBlock;
+ } else if (value->id == CSSValueInline) {
+ if (lineBoxContain & LineBoxContainInline)
+ return false;
+ lineBoxContain |= LineBoxContainInline;
+ } else if (value->id == CSSValueFont) {
+ if (lineBoxContain & LineBoxContainFont)
+ return false;
+ lineBoxContain |= LineBoxContainFont;
+ } else if (value->id == CSSValueGlyphs) {
+ if (lineBoxContain & LineBoxContainGlyphs)
+ return false;
+ lineBoxContain |= LineBoxContainGlyphs;
+ } else if (value->id == CSSValueReplaced) {
+ if (lineBoxContain & LineBoxContainReplaced)
+ return false;
+ lineBoxContain |= LineBoxContainReplaced;
+ } else if (value->id == CSSValueInlineBox) {
+ if (lineBoxContain & LineBoxContainInlineBox)
+ return false;
+ lineBoxContain |= LineBoxContainInlineBox;
+ } else
+ return false;
+ }
+
+ if (!lineBoxContain)
+ return false;
+
+ addProperty(CSSPropertyWebkitLineBoxContain, CSSLineBoxContainValue::create(lineBoxContain), important);
+ return true;
+}
+
+bool CSSPropertyParser::parseFontFeatureTag(CSSValueList* settings)
+{
+ // Feature tag name consists of 4-letter characters.
+ static const unsigned tagNameLength = 4;
+
+ CSSParserValue* value = m_valueList->current();
+ // Feature tag name comes first
+ if (value->unit != CSSPrimitiveValue::CSS_STRING)
+ return false;
+ if (value->string.length() != tagNameLength)
+ return false;
+ for (unsigned i = 0; i < tagNameLength; ++i) {
+ // Limits the range of characters to 0x20-0x7E, following the tag name rules defiend in the OpenType specification.
+ UChar character = value->string[i];
+ if (character < 0x20 || character > 0x7E)
+ return false;
+ }
+
+ AtomicString tag = value->string;
+ int tagValue = 1;
+ // Feature tag values could follow: <integer> | on | off
+ value = m_valueList->next();
+ if (value) {
+ if (value->unit == CSSPrimitiveValue::CSS_NUMBER && value->isInt && value->fValue >= 0) {
+ tagValue = clampToInteger(value->fValue);
+ if (tagValue < 0)
+ return false;
+ m_valueList->next();
+ } else if (value->id == CSSValueOn || value->id == CSSValueOff) {
+ tagValue = value->id == CSSValueOn;
+ m_valueList->next();
+ }
+ }
+ settings->append(CSSFontFeatureValue::create(tag, tagValue));
+ return true;
+}
+
+bool CSSPropertyParser::parseFontFeatureSettings(bool important)
+{
+ if (m_valueList->size() == 1 && m_valueList->current()->id == CSSValueNormal) {
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> normalValue = cssValuePool().createIdentifierValue(CSSValueNormal);
+ m_valueList->next();
+ addProperty(CSSPropertyWebkitFontFeatureSettings, normalValue.release(), important);
+ return true;
+ }
+
+ RefPtrWillBeRawPtr<CSSValueList> settings = CSSValueList::createCommaSeparated();
+ for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+ if (!parseFontFeatureTag(settings.get()))
+ return false;
+
+ // If the list isn't parsed fully, the current value should be comma.
+ value = m_valueList->current();
+ if (value && !isComma(value))
+ return false;
+ }
+ if (settings->length()) {
+ addProperty(CSSPropertyWebkitFontFeatureSettings, settings.release(), important);
+ return true;
+ }
+ return false;
+}
+
+bool CSSPropertyParser::parseFontVariantLigatures(bool important)
+{
+ RefPtrWillBeRawPtr<CSSValueList> ligatureValues = CSSValueList::createSpaceSeparated();
+ bool sawCommonLigaturesValue = false;
+ bool sawDiscretionaryLigaturesValue = false;
+ bool sawHistoricalLigaturesValue = false;
+ bool sawContextualLigaturesValue = false;
+
+ for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+ if (value->unit != CSSPrimitiveValue::CSS_IDENT)
+ return false;
+
+ switch (value->id) {
+ case CSSValueNoCommonLigatures:
+ case CSSValueCommonLigatures:
+ if (sawCommonLigaturesValue)
+ return false;
+ sawCommonLigaturesValue = true;
+ ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
+ break;
+ case CSSValueNoDiscretionaryLigatures:
+ case CSSValueDiscretionaryLigatures:
+ if (sawDiscretionaryLigaturesValue)
+ return false;
+ sawDiscretionaryLigaturesValue = true;
+ ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
+ break;
+ case CSSValueNoHistoricalLigatures:
+ case CSSValueHistoricalLigatures:
+ if (sawHistoricalLigaturesValue)
+ return false;
+ sawHistoricalLigaturesValue = true;
+ ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
+ break;
+ case CSSValueNoContextual:
+ case CSSValueContextual:
+ if (sawContextualLigaturesValue)
+ return false;
+ sawContextualLigaturesValue = true;
+ ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
+ break;
+ default:
+ return false;
+ }
+ }
+
+ if (!ligatureValues->length())
+ return false;
+
+ addProperty(CSSPropertyFontVariantLigatures, ligatureValues.release(), important);
+ return true;
+}
+
+bool CSSPropertyParser::parseCalculation(CSSParserValue* value, ValueRange range)
+{
+ ASSERT(isCalculation(value));
+
+ CSSParserValueList* args = value->function->args.get();
+ if (!args || !args->size())
+ return false;
+
+ ASSERT(!m_parsedCalculation);
+ m_parsedCalculation = CSSCalcValue::create(value->function->name, args, range);
+
+ if (!m_parsedCalculation)
+ return false;
+
+ return true;
+}
+
+bool CSSPropertyParser::parseViewportProperty(CSSPropertyID propId, bool important)
+{
+ ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_context.mode()));
+
+ CSSParserValue* value = m_valueList->current();
+ if (!value)
+ return false;
+
+ CSSValueID id = value->id;
+ bool validPrimitive = false;
+
+ switch (propId) {
+ case CSSPropertyMinWidth: // auto | extend-to-zoom | <length> | <percentage>
+ case CSSPropertyMaxWidth:
+ case CSSPropertyMinHeight:
+ case CSSPropertyMaxHeight:
+ if (id == CSSValueAuto || id == CSSValueInternalExtendToZoom)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+ break;
+ case CSSPropertyWidth: // shorthand
+ return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
+ case CSSPropertyHeight:
+ return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
+ case CSSPropertyMinZoom: // auto | <number> | <percentage>
+ case CSSPropertyMaxZoom:
+ case CSSPropertyZoom:
+ if (id == CSSValueAuto)
+ validPrimitive = true;
+ else
+ validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg));
+ break;
+ case CSSPropertyUserZoom: // zoom | fixed
+ if (id == CSSValueZoom || id == CSSValueFixed)
+ validPrimitive = true;
+ break;
+ case CSSPropertyOrientation: // auto | portrait | landscape
+ if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
+ validPrimitive = true;
+ default:
+ break;
+ }
+
+ RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr;
+ if (validPrimitive) {
+ parsedValue = parseValidPrimitive(id, value);
+ m_valueList->next();
+ }
+
+ if (parsedValue) {
+ if (!m_valueList->current() || inShorthand()) {
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool CSSPropertyParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
+{
+ ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_context.mode()));
+ unsigned numValues = m_valueList->size();
+
+ if (numValues > 2)
+ return false;
+
+ ShorthandScope scope(this, propId);
+
+ if (!parseViewportProperty(first, important))
+ return false;
+
+ // If just one value is supplied, the second value
+ // is implicitly initialized with the first value.
+ if (numValues == 1)
+ m_valueList->previous();
+
+ return parseViewportProperty(second, important);
+}
+
+template <typename CharacterType>
+static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned length)
+{
+ char buffer[maxCSSPropertyNameLength + 1]; // 1 for null character
+
+ for (unsigned i = 0; i != length; ++i) {
+ CharacterType c = propertyName[i];
+ if (c == 0 || c >= 0x7F)
+ return CSSPropertyInvalid; // illegal character
+ buffer[i] = toASCIILower(c);
+ }
+ buffer[length] = '\0';
+
+ const char* name = buffer;
+ const Property* hashTableEntry = findProperty(name, length);
+ return hashTableEntry ? static_cast<CSSPropertyID>(hashTableEntry->id) : CSSPropertyInvalid;
+}
+
+CSSPropertyID cssPropertyID(const String& string)
+{
+ unsigned length = string.length();
+
+ if (!length)
+ return CSSPropertyInvalid;
+ if (length > maxCSSPropertyNameLength)
+ return CSSPropertyInvalid;
+
+ return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
+}
+
+CSSPropertyID cssPropertyID(const CSSParserString& string)
+{
+ unsigned length = string.length();
+
+ if (!length)
+ return CSSPropertyInvalid;
+ if (length > maxCSSPropertyNameLength)
+ return CSSPropertyInvalid;
+
+ return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
+}
+
+template <typename CharacterType>
+static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned length)
+{
+ char buffer[maxCSSValueKeywordLength + 1]; // 1 for null character
+
+ for (unsigned i = 0; i != length; ++i) {
+ CharacterType c = valueKeyword[i];
+ if (c == 0 || c >= 0x7F)
+ return CSSValueInvalid; // illegal character
+ buffer[i] = WTF::toASCIILower(c);
+ }
+ buffer[length] = '\0';
+
+ const Value* hashTableEntry = findValue(buffer, length);
+ return hashTableEntry ? static_cast<CSSValueID>(hashTableEntry->id) : CSSValueInvalid;
+}
+
+CSSValueID cssValueKeywordID(const CSSParserString& string)
+{
+ unsigned length = string.length();
+ if (!length)
+ return CSSValueInvalid;
+ if (length > maxCSSValueKeywordLength)
+ return CSSValueInvalid;
+
+ return string.is8Bit() ? cssValueKeywordID(string.characters8(), length) : cssValueKeywordID(string.characters16(), length);
+}
+
+bool isValidNthToken(const CSSParserString& token)
+{
+ // The tokenizer checks for the construct of an+b.
+ // However, since the {ident} rule precedes the {nth} rule, some of those
+ // tokens are identified as string literal. Furthermore we need to accept
+ // "odd" and "even" which does not match to an+b.
+ return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even")
+ || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
+}
+
+bool CSSPropertyParser::isSystemColor(int id)
+{
+ return (id >= CSSValueActiveborder && id <= CSSValueWindowtext) || id == CSSValueMenu;
+}
+
+bool CSSPropertyParser::parseSVGValue(CSSPropertyID propId, bool important)
+{
+ CSSParserValue* value = m_valueList->current();
+ if (!value)
+ return false;
+
+ CSSValueID id = value->id;
+
+ bool validPrimitive = false;
+ RefPtrWillBeRawPtr<CSSValue> parsedValue = nullptr;
+
+ switch (propId) {
+ /* The comment to the right defines all valid value of these
+ * properties as defined in SVG 1.1, Appendix N. Property index */
+ case CSSPropertyAlignmentBaseline:
+ // auto | baseline | before-edge | text-before-edge | middle |
+ // central | after-edge | text-after-edge | ideographic | alphabetic |
+ // hanging | mathematical | inherit
+ if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle
+ || (id >= CSSValueBeforeEdge && id <= CSSValueMathematical))
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyBaselineShift:
+ // baseline | super | sub | <percentage> | <length> | inherit
+ if (id == CSSValueBaseline || id == CSSValueSub
+ || id >= CSSValueSuper)
+ validPrimitive = true;
+ else
+ validPrimitive = validUnit(value, FLength | FPercent, SVGAttributeMode);
+ break;
+
+ case CSSPropertyDominantBaseline:
+ // auto | use-script | no-change | reset-size | ideographic |
+ // alphabetic | hanging | mathematical | central | middle |
+ // text-after-edge | text-before-edge | inherit
+ if (id == CSSValueAuto || id == CSSValueMiddle
+ || (id >= CSSValueUseScript && id <= CSSValueResetSize)
+ || (id >= CSSValueCentral && id <= CSSValueMathematical))
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyEnableBackground:
+ // accumulate | new [x] [y] [width] [height] | inherit
+ if (id == CSSValueAccumulate) // TODO : new
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyMarkerStart:
+ case CSSPropertyMarkerMid:
+ case CSSPropertyMarkerEnd:
+ case CSSPropertyMask:
+ if (id == CSSValueNone) {
+ validPrimitive = true;
+ } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI);
+ if (parsedValue)
+ m_valueList->next();
+ }
+ break;
+
+ case CSSPropertyClipRule: // nonzero | evenodd | inherit
+ case CSSPropertyFillRule:
+ if (id == CSSValueNonzero || id == CSSValueEvenodd)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyStrokeMiterlimit: // <miterlimit> | inherit
+ validPrimitive = validUnit(value, FNumber | FNonNeg, SVGAttributeMode);
+ break;
+
+ case CSSPropertyStrokeLinejoin: // miter | round | bevel | inherit
+ if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyStrokeLinecap: // butt | round | square | inherit
+ if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyStrokeOpacity: // <opacity-value> | inherit
+ case CSSPropertyFillOpacity:
+ case CSSPropertyStopOpacity:
+ case CSSPropertyFloodOpacity:
+ validPrimitive = (!id && validUnit(value, FNumber | FPercent, SVGAttributeMode));
+ break;
+
+ case CSSPropertyShapeRendering:
+ // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
+ if (id == CSSValueAuto || id == CSSValueOptimizespeed
+ || id == CSSValueCrispedges || id == CSSValueGeometricprecision)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyImageRendering: // auto | optimizeSpeed |
+ case CSSPropertyColorRendering: // optimizeQuality | inherit
+ if (id == CSSValueAuto || id == CSSValueOptimizespeed
+ || id == CSSValueOptimizequality)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyBufferedRendering: // auto | dynamic | static
+ if (id == CSSValueAuto || id == CSSValueDynamic || id == CSSValueStatic)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyColorInterpolation: // auto | sRGB | linearRGB | inherit
+ case CSSPropertyColorInterpolationFilters:
+ if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb)
+ validPrimitive = true;
+ break;
+
+ /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
+ * correctly and allows optimization in applyRule(..)
+ */
+
+ case CSSPropertyTextAnchor: // start | middle | end | inherit
+ if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyGlyphOrientationVertical: // auto | <angle> | inherit
+ if (id == CSSValueAuto) {
+ validPrimitive = true;
+ break;
+ }
+ /* fallthrough intentional */
+ case CSSPropertyGlyphOrientationHorizontal: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit
+ if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+ parsedValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_DEG);
+
+ if (parsedValue)
+ m_valueList->next();
+ }
+ break;
+
+ case CSSPropertyFill: // <paint> | inherit
+ case CSSPropertyStroke: // <paint> | inherit
+ {
+ if (id == CSSValueNone) {
+ parsedValue = SVGPaint::createNone();
+ } else if (id == CSSValueCurrentcolor) {
+ parsedValue = SVGPaint::createCurrentColor();
+ } else if (isSystemColor(id)) {
+ parsedValue = SVGPaint::createColor(RenderTheme::theme().systemColor(id));
+ } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ RGBA32 c = Color::transparent;
+ if (m_valueList->next()) {
+ if (parseColorFromValue(m_valueList->current(), c))
+ parsedValue = SVGPaint::createURIAndColor(value->string, c);
+ else if (m_valueList->current()->id == CSSValueNone)
+ parsedValue = SVGPaint::createURIAndNone(value->string);
+ else if (m_valueList->current()->id == CSSValueCurrentcolor)
+ parsedValue = SVGPaint::createURIAndCurrentColor(value->string);
+ }
+ if (!parsedValue)
+ parsedValue = SVGPaint::createURI(value->string);
+ } else {
+ parsedValue = parseSVGPaint();
+ }
+
+ if (parsedValue)
+ m_valueList->next();
+ }
+ break;
+
+ case CSSPropertyStopColor: // TODO : icccolor
+ case CSSPropertyFloodColor:
+ case CSSPropertyLightingColor:
+ if (isSystemColor(id)) {
+ parsedValue = cssValuePool().createColorValue(RenderTheme::theme().systemColor(id).rgb());
+ } else if ((id >= CSSValueAqua && id <= CSSValueTransparent)
+ || (id >= CSSValueAliceblue && id <= CSSValueYellowgreen) || id == CSSValueGrey) {
+ StyleColor styleColor = SVGPaint::colorFromRGBColorString(value->string);
+ ASSERT(!styleColor.isCurrentColor());
+ parsedValue = cssValuePool().createColorValue(styleColor.color().rgb());
+ } else if (id == CSSValueCurrentcolor) {
+ parsedValue = cssValuePool().createIdentifierValue(id);
+ } else { // TODO : svgcolor (iccColor)
+ parsedValue = parseColor();
+ }
+
+ if (parsedValue)
+ m_valueList->next();
+
+ break;
+
+ case CSSPropertyPaintOrder:
+ if (m_valueList->size() == 1 && id == CSSValueNormal)
+ validPrimitive = true;
+ else if ((parsedValue = parsePaintOrder()))
+ m_valueList->next();
+ break;
+
+ case CSSPropertyVectorEffect: // none | non-scaling-stroke | inherit
+ if (id == CSSValueNone || id == CSSValueNonScalingStroke)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyWritingMode:
+ // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
+ if (id == CSSValueLrTb || id == CSSValueRlTb || id == CSSValueTbRl || id == CSSValueLr || id == CSSValueRl || id == CSSValueTb)
+ validPrimitive = true;
+ break;
+
+ case CSSPropertyStrokeWidth: // <length> | inherit
+ case CSSPropertyStrokeDashoffset:
+ validPrimitive = validUnit(value, FLength | FPercent, SVGAttributeMode);
+ break;
+ case CSSPropertyStrokeDasharray: // none | <dasharray> | inherit
+ if (id == CSSValueNone)
+ validPrimitive = true;
+ else
+ parsedValue = parseSVGStrokeDasharray();
+
+ break;
+
+ case CSSPropertyClipPath: // <uri> | none | inherit
+ case CSSPropertyFilter:
+ if (id == CSSValueNone) {
+ validPrimitive = true;
+ } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+ parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitType) value->unit);
+ if (parsedValue)
+ m_valueList->next();
+ }
+ break;
+ case CSSPropertyMaskType: // luminance | alpha | inherit
+ if (id == CSSValueLuminance || id == CSSValueAlpha)
+ validPrimitive = true;
+ break;
+
+ /* shorthand properties */
+ case CSSPropertyMarker: {
+ ShorthandScope scope(this, propId);
+ CSSPropertyParser::ImplicitScope implicitScope(this, PropertyImplicit);
+ if (!parseValue(CSSPropertyMarkerStart, important))
+ return false;
+ if (m_valueList->current()) {
+ rollbackLastProperties(1);
+ return false;
+ }
+ CSSValue* value = m_parsedProperties.last().value();
+ addProperty(CSSPropertyMarkerMid, value, important);
+ addProperty(CSSPropertyMarkerEnd, value, important);
+ return true;
+ }
+ default:
+ // If you crash here, it's because you added a css property and are not handling it
+ // in either this switch statement or the one in CSSPropertyParser::parseValue
+ ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
+ return false;
+ }
+
+ if (validPrimitive) {
+ if (id)
+ parsedValue = CSSPrimitiveValue::createIdentifier(id);
+ else if (value->unit == CSSPrimitiveValue::CSS_STRING)
+ parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitType) value->unit);
+ else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitType) value->unit);
+ else if (value->unit >= CSSParserValue::Q_EMS)
+ parsedValue = CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
+ if (isCalculation(value)) {
+ // FIXME calc() http://webkit.org/b/16662 : actually create a CSSPrimitiveValue here, ie
+ // parsedValue = CSSPrimitiveValue::create(m_parsedCalculation.release());
+ m_parsedCalculation.release();
+ parsedValue = nullptr;
+ }
+ m_valueList->next();
+ }
+ if (!parsedValue || (m_valueList->current() && !inShorthand()))
+ return false;
+
+ addProperty(propId, parsedValue.release(), important);
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSVGStrokeDasharray()
+{
+ RefPtrWillBeRawPtr<CSSValueList> ret = CSSValueList::createCommaSeparated();
+ CSSParserValue* value = m_valueList->current();
+ bool validPrimitive = true;
+ while (value) {
+ validPrimitive = validUnit(value, FLength | FPercent | FNonNeg, SVGAttributeMode);
+ if (!validPrimitive)
+ break;
+ if (value->id)
+ ret->append(CSSPrimitiveValue::createIdentifier(value->id));
+ else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+ ret->append(CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitType) value->unit));
+ value = m_valueList->next();
+ if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
+ value = m_valueList->next();
+ }
+ if (!validPrimitive)
+ return nullptr;
+ return ret.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSVGPaint()
+{
+ RGBA32 c = Color::transparent;
+ if (!parseColorFromValue(m_valueList->current(), c))
+ return SVGPaint::createUnknown();
+ return SVGPaint::createColor(Color(c));
+}
+
+// normal | [ fill || stroke || markers ]
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parsePaintOrder() const
+{
+ if (m_valueList->size() > 3)
+ return nullptr;
+
+ CSSParserValue* value = m_valueList->current();
+ if (!value)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
+
+ // The default paint-order is: Fill, Stroke, Markers.
+ bool seenFill = false, seenStroke = false, seenMarkers = false;
+
+ do {
+ switch (value->id) {
+ case CSSValueNormal:
+ // normal inside [fill || stroke || markers] not valid
+ return nullptr;
+ case CSSValueFill:
+ if (seenFill)
+ return nullptr;
+
+ seenFill = true;
+ break;
+ case CSSValueStroke:
+ if (seenStroke)
+ return nullptr;
+
+ seenStroke = true;
+ break;
+ case CSSValueMarkers:
+ if (seenMarkers)
+ return nullptr;
+
+ seenMarkers = true;
+ break;
+ default:
+ return nullptr;
+ }
+
+ parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id));
+ } while ((value = m_valueList->next()));
+
+ // fill out the rest of the paint order
+ if (!seenFill)
+ parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
+ if (!seenStroke)
+ parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
+ if (!seenMarkers)
+ parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
+
+ return parsedValues.release();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h b/chromium/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
new file mode 100644
index 00000000000..1fc76568cee
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.h
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 - 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CSSPropertyParser_h
+#define CSSPropertyParser_h
+
+// FIXME: Way too many.
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/css/CSSCalculationValue.h"
+#include "core/css/CSSFilterValue.h"
+#include "core/css/CSSGradientValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
+#include "core/css/CSSParserMode.h"
+#include "core/css/CSSParserValues.h"
+#include "core/css/CSSProperty.h"
+#include "core/css/CSSPropertySourceData.h"
+#include "core/css/CSSSelector.h"
+#include "platform/graphics/Color.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+// FIXME: Many of these may not be used.
+class CSSArrayFunctionValue;
+class CSSBorderImageSliceValue;
+class CSSPrimitiveValue;
+class CSSSelectorList;
+class CSSValue;
+class CSSValueList;
+class CSSBasicShape;
+class CSSBasicShapeInset;
+class CSSGridLineNamesValue;
+class Document;
+class Element;
+class ImmutableStylePropertySet;
+class StyleKeyframe;
+class StylePropertyShorthand;
+class StyleKeyframe;
+class UseCounter;
+
+// Inputs: PropertyID, isImportant bool, CSSParserValueList.
+// Outputs: Vector of CSSProperties
+
+class CSSPropertyParser {
+ STACK_ALLOCATED();
+public:
+ CSSPropertyParser(OwnPtr<CSSParserValueList>&,
+ const CSSParserContext&, bool inViewport, bool savedImportant,
+ WillBeHeapVector<CSSProperty, 256>&, CSSRuleSourceData::Type);
+ ~CSSPropertyParser();
+
+ // FIXME: Should this be on a separate ColorParser object?
+ template<typename StringType>
+ static bool fastParseColor(RGBA32&, const StringType&, bool strict);
+
+ bool parseValue(CSSPropertyID, bool important);
+
+ static bool isSystemColor(int id);
+
+private:
+ bool inShorthand() const { return m_inParseShorthand; }
+ bool inQuirksMode() const { return isQuirksModeBehavior(m_context.mode()); }
+
+ bool inViewport() const { return m_inViewport; }
+ bool parseViewportProperty(CSSPropertyID propId, bool important);
+ bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
+
+ KURL completeURL(const String& url) const;
+
+ void addPropertyWithPrefixingVariant(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>, bool important, bool implicit = false);
+ void addProperty(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>, bool important, bool implicit = false);
+ void rollbackLastProperties(int num);
+ bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
+ void addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue>, bool);
+
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseValidPrimitive(CSSValueID ident, CSSParserValue*);
+
+ bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&, bool important);
+ bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important);
+ bool parseContent(CSSPropertyID, bool important);
+ bool parseQuotes(CSSPropertyID, bool important);
+
+ PassRefPtrWillBeRawPtr<CSSValue> parseAttr(CSSParserValueList* args);
+
+ PassRefPtrWillBeRawPtr<CSSValue> parseBackgroundColor();
+
+ bool parseFillImage(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+
+ enum FillPositionFlag { InvalidFillPosition = 0, AmbiguousFillPosition = 1, XFillPosition = 2, YFillPosition = 4 };
+ enum FillPositionParsingMode { ResolveValuesAsPercent = 0, ResolveValuesAsKeyword = 1 };
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseFillPositionComponent(CSSParserValueList*, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode = ResolveValuesAsPercent);
+ PassRefPtrWillBeRawPtr<CSSValue> parseFillPositionX(CSSParserValueList*);
+ PassRefPtrWillBeRawPtr<CSSValue> parseFillPositionY(CSSParserValueList*);
+ void parse2ValuesFillPosition(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ bool isPotentialPositionValue(CSSParserValue*);
+ void parseFillPosition(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ void parse3ValuesFillPosition(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>);
+ void parse4ValuesFillPosition(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>);
+
+ void parseFillRepeat(RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ PassRefPtrWillBeRawPtr<CSSValue> parseFillSize(CSSPropertyID, bool &allowComma);
+
+ bool parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important);
+
+ void addFillValue(RefPtrWillBeRawPtr<CSSValue>& lval, PassRefPtrWillBeRawPtr<CSSValue> rval);
+
+ void addAnimationValue(RefPtrWillBeRawPtr<CSSValue>& lval, PassRefPtrWillBeRawPtr<CSSValue> rval);
+
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationDelay();
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationDirection();
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationDuration();
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationFillMode();
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationIterationCount();
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationName();
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationPlayState();
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationProperty();
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationTimingFunction();
+
+ bool parseWebkitTransformOriginShorthand(RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result);
+ PassRefPtrWillBeRawPtr<CSSValue> parseAnimationProperty(CSSPropertyID);
+ PassRefPtrWillBeRawPtr<CSSValueList> parseAnimationPropertyList(CSSPropertyID);
+ bool parseTransitionShorthand(CSSPropertyID, bool important);
+ bool parseAnimationShorthand(CSSPropertyID, bool important);
+
+ PassRefPtrWillBeRawPtr<CSSValue> parseColumnWidth();
+ PassRefPtrWillBeRawPtr<CSSValue> parseColumnCount();
+ bool parseColumnsShorthand(bool important);
+
+ PassRefPtrWillBeRawPtr<CSSValue> parseGridPosition();
+ bool parseIntegerOrCustomIdentFromGridPosition(RefPtrWillBeRawPtr<CSSPrimitiveValue>& numericValue, RefPtrWillBeRawPtr<CSSPrimitiveValue>& gridLineName);
+ bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
+ bool parseGridTemplateRowsAndAreas(PassRefPtrWillBeRawPtr<CSSValue>, bool important);
+ bool parseGridTemplateShorthand(bool important);
+ bool parseGridShorthand(bool important);
+ bool parseGridAreaShorthand(bool important);
+ bool parseSingleGridAreaLonghand(RefPtrWillBeRawPtr<CSSValue>&);
+ PassRefPtrWillBeRawPtr<CSSValue> parseGridTrackList(bool important);
+ bool parseGridTrackRepeatFunction(CSSValueList&);
+ PassRefPtrWillBeRawPtr<CSSValue> parseGridTrackSize(CSSParserValueList& inputList);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGridBreadth(CSSParserValue*);
+ bool parseGridTemplateAreasRow(NamedGridAreaMap&, const size_t, size_t&);
+ PassRefPtrWillBeRawPtr<CSSValue> parseGridTemplateAreas();
+ void parseGridLineNames(CSSParserValueList&, CSSValueList&, CSSGridLineNamesValue* = 0);
+
+ bool parseClipShape(CSSPropertyID, bool important);
+
+ bool parseItemPositionOverflowPosition(CSSPropertyID, bool important);
+
+ PassRefPtrWillBeRawPtr<CSSValue> parseShapeProperty(CSSPropertyID propId);
+ PassRefPtrWillBeRawPtr<CSSValue> parseBasicShapeAndOrBox();
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseBasicShape();
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseShapeRadius(CSSParserValue*);
+
+ PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapeCircle(CSSParserValueList* args);
+ PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapeEllipse(CSSParserValueList* args);
+ PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapePolygon(CSSParserValueList* args);
+ PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapeInset(CSSParserValueList* args);
+
+ bool parseFont(bool important);
+ PassRefPtrWillBeRawPtr<CSSValueList> parseFontFamily();
+
+ bool parseCounter(CSSPropertyID, int defaultValue, bool important);
+ PassRefPtrWillBeRawPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters);
+
+ bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha);
+ bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0);
+ bool parseColorFromValue(CSSParserValue*, RGBA32&);
+
+ bool parseLineHeight(bool important);
+ bool parseFontSize(bool important);
+ bool parseFontVariant(bool important);
+ bool parseFontWeight(bool important);
+ bool parseFontFaceSrc();
+ bool parseFontFaceUnicodeRange();
+
+ bool parseSVGValue(CSSPropertyID propId, bool important);
+ PassRefPtrWillBeRawPtr<CSSValue> parseSVGPaint();
+ PassRefPtrWillBeRawPtr<CSSValue> parseSVGStrokeDasharray();
+
+ PassRefPtrWillBeRawPtr<CSSValue> parsePaintOrder() const;
+
+ // CSS3 Parsing Routines (for properties specific to CSS3)
+ PassRefPtrWillBeRawPtr<CSSValueList> parseShadow(CSSParserValueList*, CSSPropertyID);
+ bool parseBorderImageShorthand(CSSPropertyID, bool important);
+ PassRefPtrWillBeRawPtr<CSSValue> parseBorderImage(CSSPropertyID);
+ bool parseBorderImageRepeat(RefPtrWillBeRawPtr<CSSValue>&);
+ bool parseBorderImageSlice(CSSPropertyID, RefPtrWillBeRawPtr<CSSBorderImageSliceValue>&);
+ bool parseBorderImageWidth(RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
+ bool parseBorderImageOutset(RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
+ bool parseBorderRadius(CSSPropertyID, bool important);
+
+ bool parseAspectRatio(bool important);
+
+ bool parseReflect(CSSPropertyID, bool important);
+
+ bool parseFlex(CSSParserValueList* args, bool important);
+
+ bool parseObjectPosition(bool important);
+
+ // Image generators
+ bool parseCanvas(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+
+ bool parseDeprecatedGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+ bool parseDeprecatedLinearGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, CSSGradientRepeat repeating);
+ bool parseDeprecatedRadialGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, CSSGradientRepeat repeating);
+ bool parseLinearGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, CSSGradientRepeat repeating);
+ bool parseRadialGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, CSSGradientRepeat repeating);
+ bool parseGradientColorStops(CSSParserValueList*, CSSGradientValue*, bool expectComma);
+
+ bool parseCrossfade(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+
+ PassRefPtrWillBeRawPtr<CSSValue> parseImageSet(CSSParserValueList*);
+
+ bool parseWillChange(bool important);
+
+ PassRefPtrWillBeRawPtr<CSSValueList> parseFilter();
+ PassRefPtrWillBeRawPtr<CSSFilterValue> parseBuiltinFilterArguments(CSSParserValueList*, CSSFilterValue::FilterOperationType);
+
+ PassRefPtrWillBeRawPtr<CSSValueList> parseTransformOrigin();
+ PassRefPtrWillBeRawPtr<CSSValueList> parseTransform(CSSPropertyID);
+ PassRefPtrWillBeRawPtr<CSSValue> parseTransformValue(CSSPropertyID, CSSParserValue*);
+ bool parseWebkitTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+ bool parseWebkitPerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+
+ bool parseTextEmphasisStyle(bool important);
+
+ bool parseTouchAction(bool important);
+
+ void addTextDecorationProperty(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>, bool important);
+ bool parseTextDecoration(CSSPropertyID propId, bool important);
+ bool parseTextUnderlinePosition(bool important);
+
+ PassRefPtrWillBeRawPtr<CSSValue> parseTextIndent();
+
+ bool parseLineBoxContain(bool important);
+ bool parseCalculation(CSSParserValue*, ValueRange);
+
+ bool parseFontFeatureTag(CSSValueList*);
+ bool parseFontFeatureSettings(bool important);
+
+ bool parseFontVariantLigatures(bool important);
+
+ bool parseGeneratedImage(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
+ PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
+
+ PassRefPtrWillBeRawPtr<CSSValue> createCSSImageValueWithReferrer(const String& rawValue, const KURL&);
+
+ bool validWidthOrHeight(CSSParserValue*);
+
+ PassRefPtrWillBeRawPtr<CSSBasicShape> parseInsetRoundedCorners(PassRefPtrWillBeRawPtr<CSSBasicShapeInset>, CSSParserValueList*);
+
+ enum SizeParameterType {
+ None,
+ Auto,
+ Length,
+ PageSize,
+ Orientation,
+ };
+
+ bool parsePage(CSSPropertyID propId, bool important);
+ bool parseSize(CSSPropertyID propId, bool important);
+ SizeParameterType parseSizeParameter(CSSValueList* parsedValues, CSSParserValue*, SizeParameterType prevParamType);
+
+ bool parseFontFaceSrcURI(CSSValueList*);
+ bool parseFontFaceSrcLocal(CSSValueList*);
+
+ enum PropertyType {
+ PropertyExplicit,
+ PropertyImplicit
+ };
+
+ class ImplicitScope {
+ STACK_ALLOCATED();
+ WTF_MAKE_NONCOPYABLE(ImplicitScope);
+ public:
+ ImplicitScope(CSSPropertyParser* parser, PropertyType propertyType)
+ : m_parser(parser)
+ {
+ m_parser->m_implicitShorthand = propertyType == CSSPropertyParser::PropertyImplicit;
+ }
+
+ ~ImplicitScope()
+ {
+ m_parser->m_implicitShorthand = false;
+ }
+
+ private:
+ CSSPropertyParser* m_parser;
+ };
+
+ class ShorthandScope {
+ STACK_ALLOCATED();
+ public:
+ ShorthandScope(CSSPropertyParser* parser, CSSPropertyID propId) : m_parser(parser)
+ {
+ if (!(m_parser->m_inParseShorthand++))
+ m_parser->m_currentShorthand = propId;
+ }
+ ~ShorthandScope()
+ {
+ if (!(--m_parser->m_inParseShorthand))
+ m_parser->m_currentShorthand = CSSPropertyInvalid;
+ }
+
+ private:
+ CSSPropertyParser* m_parser;
+ };
+
+ enum ReleaseParsedCalcValueCondition {
+ ReleaseParsedCalcValue,
+ DoNotReleaseParsedCalcValue
+ };
+
+ enum Units {
+ FUnknown = 0x0000,
+ FInteger = 0x0001,
+ FNumber = 0x0002, // Real Numbers
+ FPercent = 0x0004,
+ FLength = 0x0008,
+ FAngle = 0x0010,
+ FTime = 0x0020,
+ FFrequency = 0x0040,
+ FPositiveInteger = 0x0080,
+ FRelative = 0x0100,
+ FResolution = 0x0200,
+ FNonNeg = 0x0400
+ };
+
+ friend inline Units operator|(Units a, Units b)
+ {
+ return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
+ }
+
+ bool validCalculationUnit(CSSParserValue*, Units, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
+
+ bool shouldAcceptUnitLessValues(CSSParserValue*, Units, CSSParserMode);
+
+ inline bool validUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue) { return validUnit(value, unitflags, m_context.mode(), releaseCalc); }
+ bool validUnit(CSSParserValue*, Units, CSSParserMode, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
+
+ bool parseBorderImageQuad(Units, RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
+ int colorIntFromValue(CSSParserValue*);
+ double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
+ bool isCalculation(CSSParserValue*);
+
+private:
+ // Inputs:
+ // FIXME: This should not be an OwnPtr&, many callers will need to be changed.
+ const OwnPtr<CSSParserValueList>& m_valueList;
+ const CSSParserContext& m_context;
+ const bool m_inViewport;
+ const bool m_important; // FIXME: This is only used by font-face-src and unicode-range and undoubtably wrong!
+
+ // Outputs:
+ WillBeHeapVector<CSSProperty, 256>& m_parsedProperties;
+ CSSRuleSourceData::Type m_ruleType;
+
+ // Locals during parsing:
+ int m_inParseShorthand;
+ CSSPropertyID m_currentShorthand;
+ bool m_implicitShorthand;
+ RefPtrWillBeMember<CSSCalcValue> m_parsedCalculation;
+
+ // FIXME: There is probably a small set of APIs we could expose for these
+ // classes w/o needing to make them friends.
+ friend class ShadowParseContext;
+ friend class BorderImageParseContext;
+ friend class BorderImageSliceParseContext;
+ friend class BorderImageQuadParseContext;
+ friend class TransformOperationInfo;
+ friend bool parseDeprecatedGradientColorStop(CSSPropertyParser*, CSSParserValue*, CSSGradientColorStop&);
+ friend PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSPropertyParser*, CSSParserValue*);
+};
+
+CSSPropertyID cssPropertyID(const CSSParserString&);
+CSSPropertyID cssPropertyID(const String&);
+CSSValueID cssValueKeywordID(const CSSParserString&);
+
+bool isKeywordPropertyID(CSSPropertyID);
+bool isValidKeywordPropertyAndValue(CSSPropertyID, CSSValueID, const CSSParserContext&);
+
+} // namespace WebCore
+
+#endif // CSSPropertyParser_h
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaConditionTest.cpp b/chromium/third_party/WebKit/Source/core/css/parser/MediaConditionTest.cpp
new file mode 100644
index 00000000000..46985d38ad2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaConditionTest.cpp
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/css/MediaList.h"
+#include "core/css/MediaQuery.h"
+#include "core/css/parser/MediaQueryParser.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/text/StringBuilder.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+typedef struct {
+ const char* input;
+ const char* output;
+} TestCase;
+
+TEST(MediaConditionParserTest, Basic)
+{
+ // The first string represents the input string.
+ // The second string represents the output string, if present.
+ // Otherwise, the output string is identical to the first string.
+ TestCase testCases[] = {
+ {"screen", "not all"},
+ {"screen and (color)", "not all"},
+ {"all and (min-width:500px)", "not all"},
+ {"(min-width:500px)", "(min-width: 500px)"},
+ {"screen and (color), projection and (color)", "not all"},
+ {"(min-width: -100px)", "not all"},
+ {"(min-width: 100px) and print", "not all"},
+ {"(min-width: 100px) and (max-width: 900px)", "(max-width: 900px) and (min-width: 100px)"},
+ {"(min-width: [100px) and (max-width: 900px)", "not all"},
+ {0, 0} // Do not remove the terminator line.
+ };
+
+ for (unsigned i = 0; testCases[i].input; ++i) {
+ Vector<MediaQueryToken> tokens;
+ MediaQueryTokenizer::tokenize(testCases[i].input, tokens);
+ MediaQueryTokenIterator endToken;
+ // Stop the input once we hit a comma token
+ for (endToken = tokens.begin(); endToken != tokens.end() && endToken->type() != CommaToken; ++endToken) { }
+ RefPtrWillBeRawPtr<MediaQuerySet> mediaConditionQuerySet = MediaQueryParser::parseMediaCondition(tokens.begin(), endToken);
+ ASSERT_EQ(mediaConditionQuerySet->queryVector().size(), (unsigned)1);
+ String queryText = mediaConditionQuerySet->queryVector()[0]->cssText();
+ ASSERT_STREQ(testCases[i].output, queryText.ascii().data());
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryBlockWatcher.cpp b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryBlockWatcher.cpp
new file mode 100644
index 00000000000..fdceea230d0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryBlockWatcher.cpp
@@ -0,0 +1,28 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryBlockWatcher.h"
+
+#include "core/css/parser/MediaQueryToken.h"
+
+namespace WebCore {
+
+MediaQueryBlockWatcher::MediaQueryBlockWatcher()
+ : m_blockLevel(0)
+{
+}
+
+void MediaQueryBlockWatcher::handleToken(const MediaQueryToken& token)
+{
+ if (token.blockType() == MediaQueryToken::BlockStart) {
+ ++m_blockLevel;
+ } else if (token.blockType() == MediaQueryToken::BlockEnd) {
+ ASSERT(m_blockLevel);
+ --m_blockLevel;
+ }
+}
+
+} // namespace
+
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryBlockWatcher.h b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryBlockWatcher.h
new file mode 100644
index 00000000000..73937c06653
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryBlockWatcher.h
@@ -0,0 +1,25 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryBlockWatcher_h
+#define MediaQueryBlockWatcher_h
+
+namespace WebCore {
+
+class MediaQueryToken;
+
+class MediaQueryBlockWatcher {
+public:
+
+ MediaQueryBlockWatcher();
+ void handleToken(const MediaQueryToken&);
+ unsigned blockLevel() const { return m_blockLevel; }
+
+private:
+ unsigned m_blockLevel;
+};
+
+} // namespace
+
+#endif // MediaQueryBlockWatcher_h
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp
new file mode 100644
index 00000000000..a5adeb551a4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp
@@ -0,0 +1,66 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryInputStream.h"
+
+#include "core/html/parser/InputStreamPreprocessor.h"
+
+namespace WebCore {
+
+MediaQueryInputStream::MediaQueryInputStream(String input)
+ : m_offset(0)
+ , m_string(input)
+{
+}
+
+UChar MediaQueryInputStream::peek(unsigned lookaheadOffset)
+{
+ ASSERT((m_offset + lookaheadOffset) <= maxLength());
+ if ((m_offset + lookaheadOffset) >= m_string.length())
+ return kEndOfFileMarker;
+ return m_string[m_offset + lookaheadOffset];
+}
+
+void MediaQueryInputStream::advance(unsigned offset)
+{
+ ASSERT(m_offset + offset <= maxLength());
+ m_offset += offset;
+}
+
+void MediaQueryInputStream::pushBack(UChar cc)
+{
+ --m_offset;
+ ASSERT(nextInputChar() == cc);
+}
+
+unsigned long long MediaQueryInputStream::getUInt(unsigned start, unsigned end)
+{
+ ASSERT(start <= end && ((m_offset + end) <= m_string.length()));
+ bool isResultOK = false;
+ unsigned long long result = 0;
+ if (start < end) {
+ if (m_string.is8Bit())
+ result = charactersToUInt64Strict(m_string.characters8() + m_offset + start, end - start, &isResultOK);
+ else
+ result = charactersToUInt64Strict(m_string.characters16() + m_offset + start, end - start, &isResultOK);
+ }
+ return isResultOK ? result : 0;
+}
+
+double MediaQueryInputStream::getDouble(unsigned start, unsigned end)
+{
+ ASSERT(start <= end && ((m_offset + end) <= m_string.length()));
+ bool isResultOK = false;
+ double result = 0.0;
+ if (start < end) {
+ if (m_string.is8Bit())
+ result = charactersToDouble(m_string.characters8() + m_offset + start, end - start, &isResultOK);
+ else
+ result = charactersToDouble(m_string.characters16() + m_offset + start, end - start, &isResultOK);
+ }
+ return isResultOK ? result : 0.0;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.h b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.h
new file mode 100644
index 00000000000..24018d095bd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.h
@@ -0,0 +1,57 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryInputStream_h
+#define MediaQueryInputStream_h
+
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class MediaQueryInputStream {
+ WTF_MAKE_NONCOPYABLE(MediaQueryInputStream);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ MediaQueryInputStream(String input);
+
+ UChar peek(unsigned);
+ inline UChar nextInputChar()
+ {
+ return peek(0);
+ }
+
+ void advance(unsigned = 1);
+ void pushBack(UChar);
+
+ inline size_t maxLength()
+ {
+ return m_string.length() + 1;
+ }
+
+ inline size_t leftChars()
+ {
+ return m_string.length() - m_offset;
+
+ }
+
+ unsigned long long getUInt(unsigned start, unsigned end);
+ double getDouble(unsigned start, unsigned end);
+
+ template<bool characterPredicate(UChar)>
+ unsigned skipWhilePredicate(unsigned offset)
+ {
+ while ((m_offset + offset) < m_string.length() && characterPredicate(m_string[m_offset + offset]))
+ ++offset;
+ return offset;
+ }
+
+private:
+ size_t m_offset;
+ String m_string;
+};
+
+} // namespace WebCore
+
+#endif // MediaQueryInputStream_h
+
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp
new file mode 100644
index 00000000000..63b720cfe4b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp
@@ -0,0 +1,265 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryParser.h"
+
+#include "core/MediaTypeNames.h"
+#include "core/css/parser/CSSPropertyParser.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQueryParser::parseMediaQuerySet(const String& queryString)
+{
+ // FIXME: Replace the MediaQueryTokenizer with a generic CSSTokenizer, once there is one,
+ // or better yet, replace the MediaQueryParser with a generic thread-safe CSS parser.
+ Vector<MediaQueryToken> tokens;
+ MediaQueryTokenizer::tokenize(queryString, tokens);
+ return MediaQueryParser(MediaQuerySetParser).parseImpl(tokens.begin(), tokens.end());
+}
+
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQueryParser::parseMediaCondition(MediaQueryTokenIterator token, MediaQueryTokenIterator endToken)
+{
+ return MediaQueryParser(MediaConditionParser).parseImpl(token, endToken);
+}
+
+const MediaQueryParser::State MediaQueryParser::ReadRestrictor = &MediaQueryParser::readRestrictor;
+const MediaQueryParser::State MediaQueryParser::ReadMediaType = &MediaQueryParser::readMediaType;
+const MediaQueryParser::State MediaQueryParser::ReadAnd = &MediaQueryParser::readAnd;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureStart = &MediaQueryParser::readFeatureStart;
+const MediaQueryParser::State MediaQueryParser::ReadFeature = &MediaQueryParser::readFeature;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureColon = &MediaQueryParser::readFeatureColon;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureValue = &MediaQueryParser::readFeatureValue;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureEnd = &MediaQueryParser::readFeatureEnd;
+const MediaQueryParser::State MediaQueryParser::SkipUntilComma = &MediaQueryParser::skipUntilComma;
+const MediaQueryParser::State MediaQueryParser::SkipUntilBlockEnd = &MediaQueryParser::skipUntilBlockEnd;
+const MediaQueryParser::State MediaQueryParser::Done = &MediaQueryParser::done;
+
+MediaQueryParser::MediaQueryParser(ParserType parserType)
+ : m_parserType(parserType)
+ , m_querySet(MediaQuerySet::create())
+{
+ if (parserType == MediaQuerySetParser)
+ m_state = &MediaQueryParser::readRestrictor;
+ else // MediaConditionParser
+ m_state = &MediaQueryParser::readFeatureStart;
+}
+
+MediaQueryParser::~MediaQueryParser() { };
+
+void MediaQueryParser::setStateAndRestrict(State state, MediaQuery::Restrictor restrictor)
+{
+ m_mediaQueryData.setRestrictor(restrictor);
+ m_state = state;
+}
+
+// State machine member functions start here
+void MediaQueryParser::readRestrictor(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ readMediaType(type, token);
+}
+
+void MediaQueryParser::readMediaType(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if (type == LeftParenthesisToken) {
+ m_state = ReadFeature;
+ } else if (type == IdentToken) {
+ if (m_state == ReadRestrictor && equalIgnoringCase(token.value(), "not")) {
+ setStateAndRestrict(ReadMediaType, MediaQuery::Not);
+ } else if (m_state == ReadRestrictor && equalIgnoringCase(token.value(), "only")) {
+ setStateAndRestrict(ReadMediaType, MediaQuery::Only);
+ } else {
+ m_mediaQueryData.setMediaType(token.value());
+ m_state = ReadAnd;
+ }
+ } else if (type == EOFToken && (!m_querySet->queryVector().size() || m_state != ReadRestrictor)) {
+ m_state = Done;
+ } else {
+ m_state = SkipUntilComma;
+ if (type == CommaToken)
+ skipUntilComma(type, token);
+ }
+}
+
+void MediaQueryParser::readAnd(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if (type == IdentToken && equalIgnoringCase(token.value(), "and")) {
+ m_state = ReadFeatureStart;
+ } else if (type == CommaToken && m_parserType != MediaConditionParser) {
+ m_querySet->addMediaQuery(m_mediaQueryData.takeMediaQuery());
+ m_state = ReadRestrictor;
+ } else if (type == EOFToken) {
+ m_state = Done;
+ } else {
+ m_state = SkipUntilComma;
+ }
+}
+
+void MediaQueryParser::readFeatureStart(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if (type == LeftParenthesisToken)
+ m_state = ReadFeature;
+ else
+ m_state = SkipUntilComma;
+}
+
+void MediaQueryParser::readFeature(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if (type == IdentToken) {
+ m_mediaQueryData.setMediaFeature(token.value());
+ m_state = ReadFeatureColon;
+ } else {
+ m_state = SkipUntilComma;
+ }
+}
+
+void MediaQueryParser::readFeatureColon(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if (type == ColonToken)
+ m_state = ReadFeatureValue;
+ else if (type == RightParenthesisToken || type == EOFToken)
+ readFeatureEnd(type, token);
+ else
+ m_state = SkipUntilBlockEnd;
+}
+
+void MediaQueryParser::readFeatureValue(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if (type == DimensionToken && token.unitType() == CSSPrimitiveValue::CSS_UNKNOWN) {
+ m_state = SkipUntilComma;
+ } else {
+ m_mediaQueryData.addParserValue(type, token);
+ m_state = ReadFeatureEnd;
+ }
+}
+
+void MediaQueryParser::readFeatureEnd(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if (type == RightParenthesisToken || type == EOFToken) {
+ if (m_mediaQueryData.addExpression())
+ m_state = ReadAnd;
+ else
+ m_state = SkipUntilComma;
+ } else if (type == DelimiterToken && token.delimiter() == '/') {
+ m_mediaQueryData.addParserValue(type, token);
+ m_state = ReadFeatureValue;
+ } else {
+ m_state = SkipUntilBlockEnd;
+ }
+}
+
+void MediaQueryParser::skipUntilComma(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if ((type == CommaToken && !m_blockWatcher.blockLevel()) || type == EOFToken) {
+ m_state = ReadRestrictor;
+ m_mediaQueryData.clear();
+ m_querySet->addMediaQuery(MediaQuery::createNotAll());
+ }
+}
+
+void MediaQueryParser::skipUntilBlockEnd(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ if (token.blockType() == MediaQueryToken::BlockEnd && !m_blockWatcher.blockLevel())
+ m_state = SkipUntilComma;
+}
+
+void MediaQueryParser::done(MediaQueryTokenType type, const MediaQueryToken& token) { }
+
+void MediaQueryParser::handleBlocks(const MediaQueryToken& token)
+{
+ if (token.blockType() == MediaQueryToken::BlockStart
+ && (token.type() != LeftParenthesisToken || m_blockWatcher.blockLevel()))
+ m_state = SkipUntilBlockEnd;
+}
+
+void MediaQueryParser::processToken(const MediaQueryToken& token)
+{
+ MediaQueryTokenType type = token.type();
+
+ handleBlocks(token);
+ m_blockWatcher.handleToken(token);
+
+ // Call the function that handles current state
+ if (type != WhitespaceToken && type != CommentToken)
+ ((this)->*(m_state))(type, token);
+}
+
+// The state machine loop
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQueryParser::parseImpl(MediaQueryTokenIterator token, MediaQueryTokenIterator endToken)
+{
+ for (; token != endToken; ++token)
+ processToken(*token);
+
+ if (m_state != ReadAnd && m_state != ReadRestrictor && m_state != Done && (m_parserType != MediaConditionParser || m_state != ReadFeatureStart))
+ m_querySet->addMediaQuery(MediaQuery::createNotAll());
+ else if (m_mediaQueryData.currentMediaQueryChanged())
+ m_querySet->addMediaQuery(m_mediaQueryData.takeMediaQuery());
+
+ return m_querySet;
+}
+
+MediaQueryData::MediaQueryData()
+ : m_restrictor(MediaQuery::None)
+ , m_mediaType(MediaTypeNames::all)
+ , m_expressions(adoptPtrWillBeNoop(new ExpressionHeapVector))
+ , m_mediaTypeSet(false)
+{
+}
+
+void MediaQueryData::clear()
+{
+ m_restrictor = MediaQuery::None;
+ m_mediaType = MediaTypeNames::all;
+ m_mediaTypeSet = false;
+ m_mediaFeature = String();
+ m_valueList.destroyAndClear();
+ m_expressions = adoptPtrWillBeNoop(new ExpressionHeapVector);
+}
+
+PassOwnPtrWillBeRawPtr<MediaQuery> MediaQueryData::takeMediaQuery()
+{
+ OwnPtrWillBeRawPtr<MediaQuery> mediaQuery = adoptPtrWillBeNoop(new MediaQuery(m_restrictor, m_mediaType, m_expressions.release()));
+ clear();
+ return mediaQuery.release();
+}
+
+bool MediaQueryData::addExpression()
+{
+ OwnPtrWillBeRawPtr<MediaQueryExp> expression = MediaQueryExp::createIfValid(m_mediaFeature, &m_valueList);
+ bool isValid = !!expression;
+ m_expressions->append(expression.release());
+ m_valueList.destroyAndClear();
+ return isValid;
+}
+
+void MediaQueryData::addParserValue(MediaQueryTokenType type, const MediaQueryToken& token)
+{
+ CSSParserValue value;
+ if (type == NumberToken || type == PercentageToken || type == DimensionToken) {
+ value.setFromNumber(token.numericValue(), token.unitType());
+ value.isInt = (token.numericValueType() == IntegerValueType);
+ } else if (type == DelimiterToken) {
+ value.unit = CSSParserValue::Operator;
+ value.iValue = token.delimiter();
+ value.id = CSSValueInvalid;
+ value.isInt = false;
+ } else {
+ CSSParserFunction* function = new CSSParserFunction;
+ function->name.init(token.value());
+ value.setFromFunction(function);
+ CSSParserString tokenValue;
+ tokenValue.init(token.value());
+ value.id = cssValueKeywordID(tokenValue);
+ }
+ m_valueList.addValue(value);
+}
+
+void MediaQueryData::setMediaType(const String& mediaType)
+{
+ m_mediaType = mediaType;
+ m_mediaTypeSet = true;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h
new file mode 100644
index 00000000000..84609982f3c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryParser.h
@@ -0,0 +1,107 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryParser_h
+#define MediaQueryParser_h
+
+#include "core/css/CSSParserValues.h"
+#include "core/css/MediaList.h"
+#include "core/css/MediaQuery.h"
+#include "core/css/MediaQueryExp.h"
+#include "core/css/parser/MediaQueryBlockWatcher.h"
+#include "core/css/parser/MediaQueryToken.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class MediaQuerySet;
+
+class MediaQueryData {
+ STACK_ALLOCATED();
+private:
+ MediaQuery::Restrictor m_restrictor;
+ String m_mediaType;
+ OwnPtrWillBeMember<ExpressionHeapVector> m_expressions;
+ String m_mediaFeature;
+ CSSParserValueList m_valueList;
+ bool m_mediaTypeSet;
+
+public:
+ MediaQueryData();
+ void clear();
+ bool addExpression();
+ void addParserValue(MediaQueryTokenType, const MediaQueryToken&);
+ void setMediaType(const String&);
+ PassOwnPtrWillBeRawPtr<MediaQuery> takeMediaQuery();
+
+ inline bool currentMediaQueryChanged() const
+ {
+ return (m_restrictor != MediaQuery::None || m_mediaTypeSet || m_expressions->size() > 0);
+ }
+
+ inline void setRestrictor(MediaQuery::Restrictor restrictor) { m_restrictor = restrictor; }
+
+ inline void setMediaFeature(const String& str) { m_mediaFeature = str; }
+};
+
+class MediaQueryParser {
+ STACK_ALLOCATED();
+public:
+ static PassRefPtrWillBeRawPtr<MediaQuerySet> parseMediaQuerySet(const String&);
+ static PassRefPtrWillBeRawPtr<MediaQuerySet> parseMediaCondition(MediaQueryTokenIterator, MediaQueryTokenIterator endToken);
+
+private:
+ enum ParserType {
+ MediaQuerySetParser,
+ MediaConditionParser,
+ };
+
+ MediaQueryParser(ParserType);
+ virtual ~MediaQueryParser();
+
+ PassRefPtrWillBeRawPtr<MediaQuerySet> parseImpl(MediaQueryTokenIterator, MediaQueryTokenIterator endToken);
+
+ void processToken(const MediaQueryToken&);
+
+ void readRestrictor(MediaQueryTokenType, const MediaQueryToken&);
+ void readMediaType(MediaQueryTokenType, const MediaQueryToken&);
+ void readAnd(MediaQueryTokenType, const MediaQueryToken&);
+ void readFeatureStart(MediaQueryTokenType, const MediaQueryToken&);
+ void readFeature(MediaQueryTokenType, const MediaQueryToken&);
+ void readFeatureColon(MediaQueryTokenType, const MediaQueryToken&);
+ void readFeatureValue(MediaQueryTokenType, const MediaQueryToken&);
+ void readFeatureEnd(MediaQueryTokenType, const MediaQueryToken&);
+ void skipUntilComma(MediaQueryTokenType, const MediaQueryToken&);
+ void skipUntilBlockEnd(MediaQueryTokenType, const MediaQueryToken&);
+ void done(MediaQueryTokenType, const MediaQueryToken&);
+
+ typedef void (MediaQueryParser::*State)(MediaQueryTokenType, const MediaQueryToken&);
+
+ void setStateAndRestrict(State, MediaQuery::Restrictor);
+ void handleBlocks(const MediaQueryToken&);
+
+ State m_state;
+ ParserType m_parserType;
+ MediaQueryData m_mediaQueryData;
+ RefPtrWillBeMember<MediaQuerySet> m_querySet;
+ MediaQueryBlockWatcher m_blockWatcher;
+
+ const static State ReadRestrictor;
+ const static State ReadMediaType;
+ const static State ReadAnd;
+ const static State ReadFeatureStart;
+ const static State ReadFeature;
+ const static State ReadFeatureColon;
+ const static State ReadFeatureValue;
+ const static State ReadFeatureEnd;
+ const static State SkipUntilComma;
+ const static State SkipUntilBlockEnd;
+ const static State Done;
+
+};
+
+} // namespace WebCore
+
+#endif // MediaQueryParser_h
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp
new file mode 100644
index 00000000000..fb6bcb39d05
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp
@@ -0,0 +1,129 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryToken.h"
+
+#include "wtf/HashMap.h"
+#include "wtf/text/StringHash.h"
+#include <limits.h>
+
+namespace WebCore {
+
+
+MediaQueryToken::MediaQueryToken(MediaQueryTokenType type, BlockType blockType)
+ : m_type(type)
+ , m_delimiter(0)
+ , m_numericValue(0)
+ , m_unit(CSSPrimitiveValue::CSS_UNKNOWN)
+ , m_blockType(blockType)
+{
+}
+
+// Just a helper used for Delimiter tokens.
+MediaQueryToken::MediaQueryToken(MediaQueryTokenType type, UChar c)
+ : m_type(type)
+ , m_delimiter(c)
+ , m_numericValue(0)
+ , m_unit(CSSPrimitiveValue::CSS_UNKNOWN)
+ , m_blockType(NotBlock)
+{
+ ASSERT(m_type == DelimiterToken);
+}
+
+MediaQueryToken::MediaQueryToken(MediaQueryTokenType type, String value, BlockType blockType)
+ : m_type(type)
+ , m_value(value)
+ , m_delimiter(0)
+ , m_numericValue(0)
+ , m_unit(CSSPrimitiveValue::CSS_UNKNOWN)
+ , m_blockType(blockType)
+{
+}
+
+MediaQueryToken::MediaQueryToken(MediaQueryTokenType type, double numericValue, NumericValueType numericValueType)
+ : m_type(type)
+ , m_delimiter(0)
+ , m_numericValueType(numericValueType)
+ , m_numericValue(numericValue)
+ , m_unit(CSSPrimitiveValue::CSS_NUMBER)
+ , m_blockType(NotBlock)
+{
+ ASSERT(type == NumberToken);
+}
+
+void MediaQueryToken::convertToDimensionWithUnit(String unit)
+{
+ ASSERT(m_type == NumberToken);
+ m_type = DimensionToken;
+ m_unit = CSSPrimitiveValue::fromName(unit);
+}
+
+void MediaQueryToken::convertToPercentage()
+{
+ ASSERT(m_type == NumberToken);
+ m_type = PercentageToken;
+ m_unit = CSSPrimitiveValue::CSS_PERCENTAGE;
+}
+
+// This function is used only for testing
+// FIXME - This doesn't cover all possible Token types, but it's enough for current testing.
+String MediaQueryToken::textForUnitTests() const
+{
+ char buffer[std::numeric_limits<float>::digits];
+ if (!m_value.isNull())
+ return m_value;
+ if (m_type == LeftParenthesisToken)
+ return String("(");
+ if (m_type == RightParenthesisToken)
+ return String(")");
+ if (m_type == ColonToken)
+ return String(":");
+ if (m_type == WhitespaceToken)
+ return String(" ");
+
+ if (m_delimiter) {
+ sprintf(buffer, "'%c'", m_delimiter);
+ return String(buffer, strlen(buffer));
+ }
+ if (m_numericValue) {
+ static const unsigned maxUnitBufferLength = 6;
+ char unitBuffer[maxUnitBufferLength] = {0};
+ if (m_unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+ sprintf(unitBuffer, "%s", "%");
+ else if (m_unit == CSSPrimitiveValue::CSS_PX)
+ sprintf(unitBuffer, "%s", "px");
+ else if (m_unit == CSSPrimitiveValue::CSS_EMS)
+ sprintf(unitBuffer, "%s", "em");
+ else if (m_unit != CSSPrimitiveValue::CSS_NUMBER)
+ sprintf(unitBuffer, "%s", "other");
+ if (m_numericValueType == IntegerValueType)
+ sprintf(buffer, "%d%s", static_cast<int>(m_numericValue), unitBuffer);
+ else
+ sprintf(buffer, "%f%s", m_numericValue, unitBuffer);
+
+ return String(buffer, strlen(buffer));
+ }
+ return String();
+}
+
+UChar MediaQueryToken::delimiter() const
+{
+ ASSERT(m_type == DelimiterToken);
+ return m_delimiter;
+}
+
+NumericValueType MediaQueryToken::numericValueType() const
+{
+ ASSERT(m_type == NumberToken || m_type == PercentageToken || m_type == DimensionToken);
+ return m_numericValueType;
+}
+
+double MediaQueryToken::numericValue() const
+{
+ ASSERT(m_type == NumberToken || m_type == PercentageToken || m_type == DimensionToken);
+ return m_numericValue;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryToken.h b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryToken.h
new file mode 100644
index 00000000000..5e602e8cbf6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryToken.h
@@ -0,0 +1,88 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryToken_h
+#define MediaQueryToken_h
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+enum MediaQueryTokenType {
+ IdentToken = 0,
+ FunctionToken,
+ DelimiterToken,
+ NumberToken,
+ PercentageToken,
+ DimensionToken,
+ WhitespaceToken,
+ ColonToken,
+ SemicolonToken,
+ CommaToken,
+ LeftParenthesisToken,
+ RightParenthesisToken,
+ LeftBracketToken,
+ RightBracketToken,
+ LeftBraceToken,
+ RightBraceToken,
+ StringToken,
+ BadStringToken,
+ EOFToken,
+ CommentToken,
+};
+
+enum NumericValueType {
+ IntegerValueType,
+ NumberValueType,
+};
+
+class MediaQueryToken {
+public:
+ enum BlockType {
+ NotBlock,
+ BlockStart,
+ BlockEnd,
+ };
+
+ MediaQueryToken(MediaQueryTokenType, BlockType = NotBlock);
+ MediaQueryToken(MediaQueryTokenType, String value, BlockType = NotBlock);
+
+ MediaQueryToken(MediaQueryTokenType, UChar); // for DelimiterToken
+ MediaQueryToken(MediaQueryTokenType, double, NumericValueType); // for NumberToken
+
+ // Converts NumberToken to DimensionToken.
+ void convertToDimensionWithUnit(String);
+
+ // Converts NumberToken to PercentageToken.
+ void convertToPercentage();
+
+ MediaQueryTokenType type() const { return m_type; }
+ String value() const { return m_value; }
+ String textForUnitTests() const;
+
+ UChar delimiter() const;
+ NumericValueType numericValueType() const;
+ double numericValue() const;
+ BlockType blockType() const { return m_blockType; }
+ CSSPrimitiveValue::UnitType unitType() const { return m_unit; }
+
+private:
+ MediaQueryTokenType m_type;
+ String m_value;
+
+ UChar m_delimiter; // Could be rolled into m_value?
+
+ NumericValueType m_numericValueType;
+ double m_numericValue;
+ CSSPrimitiveValue::UnitType m_unit;
+
+ BlockType m_blockType;
+};
+
+typedef Vector<MediaQueryToken>::iterator MediaQueryTokenIterator;
+
+} // namespace
+
+#endif // MediaQueryToken_h
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp
new file mode 100644
index 00000000000..1e0b467f4f9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp
@@ -0,0 +1,527 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+
+namespace WebCore {
+#include "core/MediaQueryTokenizerCodepoints.cpp"
+}
+
+#include "core/css/parser/MediaQueryInputStream.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+#include "wtf/unicode/CharacterNames.h"
+
+namespace WebCore {
+
+// http://dev.w3.org/csswg/css-syntax/#name-start-code-point
+static bool isNameStart(UChar c)
+{
+ if (isASCIIAlpha(c))
+ return true;
+ if (c == '_')
+ return true;
+ return !isASCII(c);
+}
+
+// http://dev.w3.org/csswg/css-syntax/#name-code-point
+static bool isNameChar(UChar c)
+{
+ return isNameStart(c) || isASCIIDigit(c) || c == '-';
+}
+
+// http://dev.w3.org/csswg/css-syntax/#check-if-two-code-points-are-a-valid-escape
+static bool twoCharsAreValidEscape(UChar first, UChar second)
+{
+ return ((first == '\\') && (second != '\n') && (second != kEndOfFileMarker));
+}
+
+MediaQueryTokenizer::MediaQueryTokenizer(MediaQueryInputStream& inputStream)
+ : m_input(inputStream)
+{
+}
+
+void MediaQueryTokenizer::reconsume(UChar c)
+{
+ m_input.pushBack(c);
+}
+
+UChar MediaQueryTokenizer::consume()
+{
+ UChar current = m_input.nextInputChar();
+ m_input.advance();
+ return current;
+}
+
+void MediaQueryTokenizer::consume(unsigned offset)
+{
+ m_input.advance(offset);
+}
+
+MediaQueryToken MediaQueryTokenizer::whiteSpace(UChar cc)
+{
+ // CSS Tokenization is currently lossy, but we could record
+ // the exact whitespace instead of discarding it here.
+ consumeUntilNonWhitespace();
+ return MediaQueryToken(WhitespaceToken);
+}
+
+static bool popIfBlockMatches(Vector<MediaQueryTokenType>& blockStack, MediaQueryTokenType type)
+{
+ if (!blockStack.isEmpty() && blockStack.last() == type) {
+ blockStack.removeLast();
+ return true;
+ }
+ return false;
+}
+
+MediaQueryToken MediaQueryTokenizer::blockStart(MediaQueryTokenType type)
+{
+ m_blockStack.append(type);
+ return MediaQueryToken(type, MediaQueryToken::BlockStart);
+}
+
+MediaQueryToken MediaQueryTokenizer::blockStart(MediaQueryTokenType blockType, MediaQueryTokenType type, String name)
+{
+ m_blockStack.append(blockType);
+ return MediaQueryToken(type, name, MediaQueryToken::BlockStart);
+}
+
+MediaQueryToken MediaQueryTokenizer::blockEnd(MediaQueryTokenType type, MediaQueryTokenType startType)
+{
+ if (popIfBlockMatches(m_blockStack, startType))
+ return MediaQueryToken(type, MediaQueryToken::BlockEnd);
+ return MediaQueryToken(type);
+}
+
+MediaQueryToken MediaQueryTokenizer::leftParenthesis(UChar cc)
+{
+ return blockStart(LeftParenthesisToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::rightParenthesis(UChar cc)
+{
+ return blockEnd(RightParenthesisToken, LeftParenthesisToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::leftBracket(UChar cc)
+{
+ return blockStart(LeftBracketToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::rightBracket(UChar cc)
+{
+ return blockEnd(RightBracketToken, LeftBracketToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::leftBrace(UChar cc)
+{
+ return blockStart(LeftBraceToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::rightBrace(UChar cc)
+{
+ return blockEnd(RightBraceToken, LeftBraceToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::plusOrFullStop(UChar cc)
+{
+ if (nextCharsAreNumber(cc)) {
+ reconsume(cc);
+ return consumeNumericToken();
+ }
+ return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::asterisk(UChar cc)
+{
+ return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::comma(UChar cc)
+{
+ return MediaQueryToken(CommaToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::hyphenMinus(UChar cc)
+{
+ if (nextCharsAreNumber(cc)) {
+ reconsume(cc);
+ return consumeNumericToken();
+ }
+ if (nextCharsAreIdentifier(cc)) {
+ reconsume(cc);
+ return consumeIdentLikeToken();
+ }
+ return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::solidus(UChar cc)
+{
+ if (consumeIfNext('*')) {
+ // We're intentionally deviating from the spec here, by creating tokens for CSS comments.
+ return consumeUntilCommentEndFound()? MediaQueryToken(CommentToken): MediaQueryToken(EOFToken);
+ }
+
+ return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::colon(UChar cc)
+{
+ return MediaQueryToken(ColonToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::semiColon(UChar cc)
+{
+ return MediaQueryToken(SemicolonToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::reverseSolidus(UChar cc)
+{
+ if (twoCharsAreValidEscape(cc, m_input.nextInputChar())) {
+ reconsume(cc);
+ return consumeIdentLikeToken();
+ }
+ return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::asciiDigit(UChar cc)
+{
+ reconsume(cc);
+ return consumeNumericToken();
+}
+
+MediaQueryToken MediaQueryTokenizer::nameStart(UChar cc)
+{
+ reconsume(cc);
+ return consumeIdentLikeToken();
+}
+
+MediaQueryToken MediaQueryTokenizer::stringStart(UChar cc)
+{
+ return consumeStringTokenUntil(cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::endOfFile(UChar cc)
+{
+ return MediaQueryToken(EOFToken);
+}
+
+void MediaQueryTokenizer::tokenize(String string, Vector<MediaQueryToken>& outTokens)
+{
+ // According to the spec, we should perform preprocessing here.
+ // See: http://dev.w3.org/csswg/css-syntax/#input-preprocessing
+ //
+ // However, we can skip this step since:
+ // * We're using HTML spaces (which accept \r and \f as a valid white space)
+ // * Do not count white spaces
+ // * consumeEscape replaces NULLs for replacement characters
+
+ if (string.isEmpty())
+ return;
+
+ MediaQueryInputStream input(string);
+ MediaQueryTokenizer tokenizer(input);
+ while (true) {
+ MediaQueryToken token = tokenizer.nextToken();
+ outTokens.append(token);
+ if (token.type() == EOFToken)
+ return;
+ }
+}
+
+MediaQueryToken MediaQueryTokenizer::nextToken()
+{
+ // Unlike the HTMLTokenizer, the CSS Syntax spec is written
+ // as a stateless, (fixed-size) look-ahead tokenizer.
+ // We could move to the stateful model and instead create
+ // states for all the "next 3 codepoints are X" cases.
+ // State-machine tokenizers are easier to write to handle
+ // incremental tokenization of partial sources.
+ // However, for now we follow the spec exactly.
+ UChar cc = consume();
+ CodePoint codePointFunc = 0;
+
+ if (isASCII(cc)) {
+ ASSERT_WITH_SECURITY_IMPLICATION(cc < codePointsNumber);
+ codePointFunc = codePoints[cc];
+ } else {
+ codePointFunc = &MediaQueryTokenizer::nameStart;
+ }
+
+ if (codePointFunc)
+ return ((this)->*(codePointFunc))(cc);
+ return MediaQueryToken(DelimiterToken, cc);
+}
+
+static int getSign(MediaQueryInputStream& input, unsigned& offset)
+{
+ int sign = 1;
+ if (input.nextInputChar() == '+') {
+ ++offset;
+ } else if (input.peek(offset) == '-') {
+ sign = -1;
+ ++offset;
+ }
+ return sign;
+}
+
+static unsigned long long getInteger(MediaQueryInputStream& input, unsigned& offset)
+{
+ unsigned intStartPos = offset;
+ offset = input.skipWhilePredicate<isASCIIDigit>(offset);
+ unsigned intEndPos = offset;
+ return input.getUInt(intStartPos, intEndPos);
+}
+
+static double getFraction(MediaQueryInputStream& input, unsigned& offset, unsigned& digitsNumber)
+{
+ unsigned fractionStartPos = 0;
+ unsigned fractionEndPos = 0;
+ if (input.peek(offset) == '.' && isASCIIDigit(input.peek(++offset))) {
+ fractionStartPos = offset - 1;
+ offset = input.skipWhilePredicate<isASCIIDigit>(offset);
+ fractionEndPos = offset;
+ }
+ digitsNumber = fractionEndPos- fractionStartPos;
+ return input.getDouble(fractionStartPos, fractionEndPos);
+}
+
+static unsigned long long getExponent(MediaQueryInputStream& input, unsigned& offset, int& sign)
+{
+ unsigned exponentStartPos = 0;
+ unsigned exponentEndPos = 0;
+ if ((input.peek(offset) == 'E' || input.peek(offset) == 'e')) {
+ int offsetBeforeExponent = offset;
+ ++offset;
+ if (input.peek(offset) == '+') {
+ ++offset;
+ } else if (input.peek(offset) =='-') {
+ sign = -1;
+ ++offset;
+ }
+ exponentStartPos = offset;
+ offset = input.skipWhilePredicate<isASCIIDigit>(offset);
+ exponentEndPos = offset;
+ if (exponentEndPos == exponentStartPos)
+ offset = offsetBeforeExponent;
+ }
+ return input.getUInt(exponentStartPos, exponentEndPos);
+}
+
+// This method merges the following spec sections for efficiency
+// http://www.w3.org/TR/css3-syntax/#consume-a-number
+// http://www.w3.org/TR/css3-syntax/#convert-a-string-to-a-number
+MediaQueryToken MediaQueryTokenizer::consumeNumber()
+{
+ ASSERT(nextCharsAreNumber());
+ NumericValueType type = IntegerValueType;
+ double value = 0;
+ unsigned offset = 0;
+ int exponentSign = 1;
+ unsigned fractionDigits;
+ int sign = getSign(m_input, offset);
+ unsigned long long integerPart = getInteger(m_input, offset);
+ double fractionPart = getFraction(m_input, offset, fractionDigits);
+ unsigned long long exponentPart = getExponent(m_input, offset, exponentSign);
+ double exponent = pow(10, (float)exponentSign * (double)exponentPart);
+ value = (double)sign * ((double)integerPart + fractionPart) * exponent;
+
+ m_input.advance(offset);
+ if (fractionDigits > 0)
+ type = NumberValueType;
+
+ return MediaQueryToken(NumberToken, value, type);
+}
+
+// http://www.w3.org/TR/css3-syntax/#consume-a-numeric-token
+MediaQueryToken MediaQueryTokenizer::consumeNumericToken()
+{
+ MediaQueryToken token = consumeNumber();
+ if (nextCharsAreIdentifier())
+ token.convertToDimensionWithUnit(consumeName());
+ else if (consumeIfNext('%'))
+ token.convertToPercentage();
+ return token;
+}
+
+// http://www.w3.org/TR/css3-syntax/#consume-an-ident-like-token
+MediaQueryToken MediaQueryTokenizer::consumeIdentLikeToken()
+{
+ String name = consumeName();
+ if (consumeIfNext('(')) {
+ return blockStart(LeftParenthesisToken, FunctionToken, name);
+ }
+ return MediaQueryToken(IdentToken, name);
+}
+
+static bool isNewLine(UChar cc)
+{
+ // We check \r and \f here, since we have no preprocessing stage
+ return (cc == '\r' || cc == '\n' || cc == '\f');
+}
+
+// http://dev.w3.org/csswg/css-syntax/#consume-a-string-token
+MediaQueryToken MediaQueryTokenizer::consumeStringTokenUntil(UChar endingCodePoint)
+{
+ StringBuilder output;
+ while (true) {
+ UChar cc = consume();
+ if (cc == endingCodePoint || cc == kEndOfFileMarker) {
+ // The "reconsume" here deviates from the spec, but is required to avoid consuming past the EOF
+ if (cc == kEndOfFileMarker)
+ reconsume(cc);
+ return MediaQueryToken(StringToken, output.toString());
+ }
+ if (isNewLine(cc)) {
+ reconsume(cc);
+ return MediaQueryToken(BadStringToken);
+ }
+ if (cc == '\\') {
+ if (m_input.nextInputChar() == kEndOfFileMarker)
+ continue;
+ if (isNewLine(m_input.nextInputChar()))
+ consume();
+ else
+ output.append(consumeEscape());
+ } else {
+ output.append(cc);
+ }
+ }
+}
+
+void MediaQueryTokenizer::consumeUntilNonWhitespace()
+{
+ // Using HTML space here rather than CSS space since we don't do preprocessing
+ while (isHTMLSpace<UChar>(m_input.nextInputChar()))
+ consume();
+}
+
+bool MediaQueryTokenizer::consumeUntilCommentEndFound()
+{
+ UChar c = consume();
+ while (true) {
+ if (c == kEndOfFileMarker)
+ return false;
+ if (c != '*') {
+ c = consume();
+ continue;
+ }
+ c = consume();
+ if (c == '/')
+ break;
+ }
+ return true;
+}
+
+bool MediaQueryTokenizer::consumeIfNext(UChar character)
+{
+ if (m_input.nextInputChar() == character) {
+ consume();
+ return true;
+ }
+ return false;
+}
+
+// http://www.w3.org/TR/css3-syntax/#consume-a-name
+String MediaQueryTokenizer::consumeName()
+{
+ // FIXME: Is this as efficient as it can be?
+ // The possibility of escape chars mandates a copy AFAICT.
+ StringBuilder result;
+ while (true) {
+ UChar cc = consume();
+ if (isNameChar(cc)) {
+ result.append(cc);
+ continue;
+ }
+ if (twoCharsAreValidEscape(cc, m_input.nextInputChar())) {
+ result.append(consumeEscape());
+ continue;
+ }
+ reconsume(cc);
+ return result.toString();
+ }
+}
+
+// http://dev.w3.org/csswg/css-syntax/#consume-an-escaped-code-point
+UChar MediaQueryTokenizer::consumeEscape()
+{
+ UChar cc = consume();
+ ASSERT(cc != '\n');
+ if (isASCIIHexDigit(cc)) {
+ unsigned consumedHexDigits = 1;
+ StringBuilder hexChars;
+ hexChars.append(cc);
+ while (consumedHexDigits < 6 && isASCIIHexDigit(m_input.nextInputChar())) {
+ cc = consume();
+ hexChars.append(cc);
+ consumedHexDigits++;
+ };
+ bool ok = false;
+ UChar codePoint = hexChars.toString().toUIntStrict(&ok, 16);
+ if (!ok)
+ return WTF::Unicode::replacementCharacter;
+ return codePoint;
+ }
+
+ // Replaces NULLs with replacement characters, since we do not perform preprocessing
+ if (cc == kEndOfFileMarker)
+ return WTF::Unicode::replacementCharacter;
+ return cc;
+}
+
+bool MediaQueryTokenizer::nextTwoCharsAreValidEscape()
+{
+ if (m_input.leftChars() < 1)
+ return false;
+ return twoCharsAreValidEscape(m_input.nextInputChar(), m_input.peek(1));
+}
+
+// http://www.w3.org/TR/css3-syntax/#starts-with-a-number
+bool MediaQueryTokenizer::nextCharsAreNumber(UChar first)
+{
+ UChar second = m_input.nextInputChar();
+ if (isASCIIDigit(first))
+ return true;
+ if (first == '+' || first == '-')
+ return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input.peek(1))));
+ if (first =='.')
+ return (isASCIIDigit(second));
+ return false;
+}
+
+bool MediaQueryTokenizer::nextCharsAreNumber()
+{
+ UChar first = consume();
+ bool areNumber = nextCharsAreNumber(first);
+ reconsume(first);
+ return areNumber;
+}
+
+// http://www.w3.org/TR/css3-syntax/#would-start-an-identifier
+bool MediaQueryTokenizer::nextCharsAreIdentifier(UChar first)
+{
+ UChar second = m_input.nextInputChar();
+ if (isNameStart(first) || twoCharsAreValidEscape(first, second))
+ return true;
+
+ if (first == '-') {
+ if (isNameStart(m_input.nextInputChar()))
+ return true;
+ return nextTwoCharsAreValidEscape();
+ }
+
+ return false;
+}
+
+bool MediaQueryTokenizer::nextCharsAreIdentifier()
+{
+ UChar first = consume();
+ bool areIdentifier = nextCharsAreIdentifier(first);
+ reconsume(first);
+ return areIdentifier;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.h b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.h
new file mode 100644
index 00000000000..c59a96d299a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.h
@@ -0,0 +1,85 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryTokenizer_h
+#define MediaQueryTokenizer_h
+
+#include "core/css/parser/MediaQueryToken.h"
+#include "core/html/parser/InputStreamPreprocessor.h"
+#include "wtf/text/WTFString.h"
+
+#include <climits>
+
+namespace WebCore {
+
+class MediaQueryInputStream;
+
+class MediaQueryTokenizer {
+ WTF_MAKE_NONCOPYABLE(MediaQueryTokenizer);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static void tokenize(String, Vector<MediaQueryToken>&);
+private:
+ MediaQueryTokenizer(MediaQueryInputStream&);
+
+ MediaQueryToken nextToken();
+
+ UChar consume();
+ void consume(unsigned);
+ void reconsume(UChar);
+
+ MediaQueryToken consumeNumericToken();
+ MediaQueryToken consumeIdentLikeToken();
+ MediaQueryToken consumeNumber();
+ MediaQueryToken consumeStringTokenUntil(UChar);
+
+ void consumeUntilNonWhitespace();
+ bool consumeUntilCommentEndFound();
+
+ bool consumeIfNext(UChar);
+ String consumeName();
+ UChar consumeEscape();
+
+ bool nextTwoCharsAreValidEscape();
+ bool nextCharsAreNumber(UChar);
+ bool nextCharsAreNumber();
+ bool nextCharsAreIdentifier(UChar);
+ bool nextCharsAreIdentifier();
+ MediaQueryToken blockStart(MediaQueryTokenType);
+ MediaQueryToken blockStart(MediaQueryTokenType blockType, MediaQueryTokenType, String);
+ MediaQueryToken blockEnd(MediaQueryTokenType, MediaQueryTokenType startType);
+
+ typedef MediaQueryToken (MediaQueryTokenizer::*CodePoint)(UChar);
+
+ static const CodePoint codePoints[];
+ Vector<MediaQueryTokenType> m_blockStack;
+
+ MediaQueryToken whiteSpace(UChar);
+ MediaQueryToken leftParenthesis(UChar);
+ MediaQueryToken rightParenthesis(UChar);
+ MediaQueryToken leftBracket(UChar);
+ MediaQueryToken rightBracket(UChar);
+ MediaQueryToken leftBrace(UChar);
+ MediaQueryToken rightBrace(UChar);
+ MediaQueryToken plusOrFullStop(UChar);
+ MediaQueryToken comma(UChar);
+ MediaQueryToken hyphenMinus(UChar);
+ MediaQueryToken asterisk(UChar);
+ MediaQueryToken solidus(UChar);
+ MediaQueryToken colon(UChar);
+ MediaQueryToken semiColon(UChar);
+ MediaQueryToken reverseSolidus(UChar);
+ MediaQueryToken asciiDigit(UChar);
+ MediaQueryToken nameStart(UChar);
+ MediaQueryToken stringStart(UChar);
+ MediaQueryToken endOfFile(UChar);
+
+ MediaQueryInputStream& m_input;
+};
+
+
+
+} // namespace WebCore
+
+#endif // MediaQueryTokenizer_h
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizerTest.cpp b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizerTest.cpp
new file mode 100644
index 00000000000..c611dc435c2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/MediaQueryTokenizerTest.cpp
@@ -0,0 +1,173 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+
+#include "core/css/parser/MediaQueryBlockWatcher.h"
+#include "wtf/PassOwnPtr.h"
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+typedef struct {
+ const char* input;
+ const char* output;
+} TestCase;
+
+typedef struct {
+ const char* input;
+ const unsigned maxLevel;
+ const unsigned finalLevel;
+} BlockTestCase;
+
+TEST(MediaQueryTokenizerTest, Basic)
+{
+ TestCase testCases[] = {
+ { "(max-width: 50px)", "(max-width: 50px)" },
+ { "(max-width: 1e+2px)", "(max-width: 100px)" },
+ { "(max-width: 1e2px)", "(max-width: 100px)" },
+ { "(max-width: 1000e-1px)", "(max-width: 100px)" },
+ { "(max-width: 50\\70\\78)", "(max-width: 50px)" },
+ { "(max-width: /* comment */50px)", "(max-width: 50px)" },
+ { "(max-width: /** *commen*t */60px)", "(max-width: 60px)" },
+ { "(max-width: /** *commen*t **/70px)", "(max-width: 70px)" },
+ { "(max-width: /** *commen*t **//**/80px)", "(max-width: 80px)" },
+ { "(max-width: /*/ **/90px)", "(max-width: 90px)" },
+ { "(max-width: /*/ **/*100px)", "(max-width: '*'100px)" },
+ { "(max-width: 110px/*)", "(max-width: 110px" },
+ { "(max-width: 120px)/*", "(max-width: 120px)" },
+ { "(max-width: 130px)/**", "(max-width: 130px)" },
+ { "(max-width: /***/140px)/**/", "(max-width: 140px)" },
+ { "(max-width: '40px')", "(max-width: 40px)" },
+ { "(max-width: '40px", "(max-width: 40px" },
+ { "(max-width: '40px\n", "(max-width: " },
+ { "(max-width: '40px\\", "(max-width: 40px" },
+ { "(max-width: '40px\\\n", "(max-width: 40px" },
+ { "(max-width: '40px\\\n')", "(max-width: 40px)" },
+ { "(max-width: '40\\70\\78')", "(max-width: 40px)" },
+ { "(max-width: '40\\\npx')", "(max-width: 40px)" },
+ { "(max-aspect-ratio: 5)", "(max-aspect-ratio: 5)" },
+ { "(max-aspect-ratio: +5)", "(max-aspect-ratio: 5)" },
+ { "(max-aspect-ratio: -5)", "(max-aspect-ratio: -5)" },
+ { "(max-aspect-ratio: -+5)", "(max-aspect-ratio: '-'5)" },
+ { "(max-aspect-ratio: +-5)", "(max-aspect-ratio: '+'-5)" },
+ { "(max-aspect-ratio: +bla5)", "(max-aspect-ratio: '+'bla5)" },
+ { "(max-aspect-ratio: +5bla)", "(max-aspect-ratio: 5other)" },
+ { "(max-aspect-ratio: -bla)", "(max-aspect-ratio: -bla)" },
+ { "(max-aspect-ratio: --bla)", "(max-aspect-ratio: '-'-bla)" },
+ { 0, 0 } // Do not remove the terminator line.
+ };
+
+ for (int i = 0; testCases[i].input; ++i) {
+ Vector<MediaQueryToken> tokens;
+ MediaQueryTokenizer::tokenize(testCases[i].input, tokens);
+ StringBuilder output;
+ for (size_t j = 0; j < tokens.size(); ++j)
+ output.append(tokens[j].textForUnitTests());
+ ASSERT_STREQ(testCases[i].output, output.toString().ascii().data());
+ }
+}
+
+TEST(MediaQueryTokenizerBlockTest, Basic)
+{
+ BlockTestCase testCases[] = {
+ {"(max-width: 800px()), (max-width: 800px)", 2, 0},
+ {"(max-width: 900px(()), (max-width: 900px)", 3, 1},
+ {"(max-width: 600px(())))), (max-width: 600px)", 3, 0},
+ {"(max-width: 500px(((((((((())))), (max-width: 500px)", 11, 6},
+ {"(max-width: 800px[]), (max-width: 800px)", 2, 0},
+ {"(max-width: 900px[[]), (max-width: 900px)", 3, 2},
+ {"(max-width: 600px[[]]]]), (max-width: 600px)", 3, 0},
+ {"(max-width: 500px[[[[[[[[[[]]]]), (max-width: 500px)", 11, 7},
+ {"(max-width: 800px{}), (max-width: 800px)", 2, 0},
+ {"(max-width: 900px{{}), (max-width: 900px)", 3, 2},
+ {"(max-width: 600px{{}}}}), (max-width: 600px)", 3, 0},
+ {"(max-width: 500px{{{{{{{{{{}}}}), (max-width: 500px)", 11, 7},
+ {"[(), (max-width: 400px)", 2, 1},
+ {"[{}, (max-width: 500px)", 2, 1},
+ {"[{]}], (max-width: 900px)", 2, 0},
+ {"[{[]{}{{{}}}}], (max-width: 900px)", 5, 0},
+ {"[{[}], (max-width: 900px)", 3, 2},
+ {"[({)}], (max-width: 900px)", 3, 2},
+ {"[]((), (max-width: 900px)", 2, 1},
+ {"((), (max-width: 900px)", 2, 1},
+ {"(foo(), (max-width: 900px)", 2, 1},
+ {"[](()), (max-width: 900px)", 2, 0},
+ {"all an[isdfs bla())(i())]icalc(i)(()), (max-width: 400px)", 3, 0},
+ {"all an[isdfs bla())(]icalc(i)(()), (max-width: 500px)", 4, 2},
+ {"all an[isdfs bla())(]icalc(i)(())), (max-width: 600px)", 4, 1},
+ {"all an[isdfs bla())(]icalc(i)(()))], (max-width: 800px)", 4, 0},
+ {0, 0, 0} // Do not remove the terminator line.
+ };
+ for (int i = 0; testCases[i].input; ++i) {
+ Vector<MediaQueryToken> tokens;
+ MediaQueryTokenizer::tokenize(testCases[i].input, tokens);
+ MediaQueryBlockWatcher blockWatcher;
+
+ unsigned maxLevel = 0;
+ unsigned level = 0;
+ for (size_t j = 0; j < tokens.size(); ++j) {
+ blockWatcher.handleToken(tokens[j]);
+ level = blockWatcher.blockLevel();
+ maxLevel = std::max(level, maxLevel);
+ }
+ ASSERT_EQ(testCases[i].maxLevel, maxLevel);
+ ASSERT_EQ(testCases[i].finalLevel, level);
+ }
+}
+
+void testToken(UChar c, MediaQueryTokenType tokenType)
+{
+ Vector<MediaQueryToken> tokens;
+ StringBuilder input;
+ input.append(c);
+ MediaQueryTokenizer::tokenize(input.toString(), tokens);
+ ASSERT_EQ(tokens[0].type(), tokenType);
+}
+
+TEST(MediaQueryTokenizerCodepointsTest, Basic)
+{
+ for (UChar c = 0; c <= 1000; ++c) {
+ if (isASCIIDigit(c))
+ testToken(c, NumberToken);
+ else if (isASCIIAlpha(c))
+ testToken(c, IdentToken);
+ else if (c == '_')
+ testToken(c, IdentToken);
+ else if (c == '\r' || c == ' ' || c == '\n' || c == '\t' || c == '\f')
+ testToken(c, WhitespaceToken);
+ else if (c == '(')
+ testToken(c, LeftParenthesisToken);
+ else if (c == ')')
+ testToken(c, RightParenthesisToken);
+ else if (c == '[')
+ testToken(c, LeftBracketToken);
+ else if (c == ']')
+ testToken(c, RightBracketToken);
+ else if (c == '{')
+ testToken(c, LeftBraceToken);
+ else if (c == '}')
+ testToken(c, RightBraceToken);
+ else if (c == '.' || c == '+' || c == '-' || c == '/' || c == '\\')
+ testToken(c, DelimiterToken);
+ else if (c == '\'' || c == '"')
+ testToken(c, StringToken);
+ else if (c == ',')
+ testToken(c, CommaToken);
+ else if (c == ':')
+ testToken(c, ColonToken);
+ else if (c == ';')
+ testToken(c, SemicolonToken);
+ else if (!c)
+ testToken(c, EOFToken);
+ else if (c > SCHAR_MAX)
+ testToken(c, IdentToken);
+ else
+ testToken(c, DelimiterToken);
+ }
+ testToken(USHRT_MAX, IdentToken);
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.cpp b/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.cpp
new file mode 100644
index 00000000000..15f5590fa19
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.cpp
@@ -0,0 +1,141 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/SizesAttributeParser.h"
+
+#include "core/MediaTypeNames.h"
+#include "core/css/MediaQueryEvaluator.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+#include "core/css/parser/SizesCalcParser.h"
+
+namespace WebCore {
+
+unsigned SizesAttributeParser::findEffectiveSize(const String& attribute, PassRefPtr<MediaValues> mediaValues)
+{
+ Vector<MediaQueryToken> tokens;
+ SizesAttributeParser parser(mediaValues);
+
+ MediaQueryTokenizer::tokenize(attribute, tokens);
+ if (!parser.parse(tokens))
+ return parser.effectiveSizeDefaultValue();
+ return parser.effectiveSize();
+}
+
+bool SizesAttributeParser::calculateLengthInPixels(MediaQueryTokenIterator startToken, MediaQueryTokenIterator endToken, unsigned& result)
+{
+ if (startToken == endToken)
+ return false;
+ MediaQueryTokenType type = startToken->type();
+ if (type == DimensionToken) {
+ int length;
+ if (!CSSPrimitiveValue::isLength(startToken->unitType()))
+ return false;
+ if ((m_mediaValues->computeLength(startToken->numericValue(), startToken->unitType(), length)) && (length > 0)) {
+ result = (unsigned)length;
+ return true;
+ }
+ } else if (type == FunctionToken) {
+ return SizesCalcParser::parse(startToken, endToken, m_mediaValues, result);
+ } else if (type == NumberToken && !startToken->numericValue()) {
+ result = 0;
+ return true;
+ }
+
+ return false;
+}
+
+static void reverseSkipIrrelevantTokens(MediaQueryTokenIterator& token, MediaQueryTokenIterator startToken)
+{
+ MediaQueryTokenIterator endToken = token;
+ while (token != startToken && (token->type() == WhitespaceToken || token->type() == CommentToken || token->type() == EOFToken))
+ --token;
+ if (token != endToken)
+ ++token;
+}
+
+static void reverseSkipUntilComponentStart(MediaQueryTokenIterator& token, MediaQueryTokenIterator startToken)
+{
+ if (token == startToken)
+ return;
+ --token;
+ if (token->blockType() != MediaQueryToken::BlockEnd)
+ return;
+ unsigned blockLevel = 0;
+ while (token != startToken) {
+ if (token->blockType() == MediaQueryToken::BlockEnd) {
+ ++blockLevel;
+ } else if (token->blockType() == MediaQueryToken::BlockStart) {
+ --blockLevel;
+ if (!blockLevel)
+ break;
+ }
+
+ --token;
+ }
+}
+
+bool SizesAttributeParser::mediaConditionMatches(PassRefPtrWillBeRawPtr<MediaQuerySet> mediaCondition)
+{
+ // A Media Condition cannot have a media type other then screen.
+ MediaQueryEvaluator mediaQueryEvaluator(MediaTypeNames::screen, *m_mediaValues);
+ return mediaQueryEvaluator.eval(mediaCondition.get());
+}
+
+bool SizesAttributeParser::parseMediaConditionAndLength(MediaQueryTokenIterator startToken, MediaQueryTokenIterator endToken)
+{
+ MediaQueryTokenIterator lengthTokenStart;
+ MediaQueryTokenIterator lengthTokenEnd;
+
+ reverseSkipIrrelevantTokens(endToken, startToken);
+ lengthTokenEnd = endToken;
+ reverseSkipUntilComponentStart(endToken, startToken);
+ lengthTokenStart = endToken;
+ unsigned length;
+ if (!calculateLengthInPixels(lengthTokenStart, lengthTokenEnd, length))
+ return false;
+ RefPtrWillBeRawPtr<MediaQuerySet> mediaCondition = MediaQueryParser::parseMediaCondition(startToken, endToken);
+ if (mediaCondition && mediaConditionMatches(mediaCondition)) {
+ m_length = length;
+ m_lengthWasSet = true;
+ return true;
+ }
+ return false;
+}
+
+bool SizesAttributeParser::parse(Vector<MediaQueryToken>& tokens)
+{
+ if (tokens.isEmpty())
+ return false;
+ MediaQueryTokenIterator startToken = tokens.begin();
+ MediaQueryTokenIterator endToken;
+ // Split on a comma token, and send the result tokens to be parsed as (media-condition, length) pairs
+ for (MediaQueryTokenIterator token = tokens.begin(); token != tokens.end(); ++token) {
+ if (token->type() == CommaToken) {
+ endToken = token;
+ if (parseMediaConditionAndLength(startToken, endToken))
+ return true;
+ startToken = token;
+ ++startToken;
+ }
+ }
+ endToken = tokens.end();
+ return parseMediaConditionAndLength(startToken, --endToken);
+}
+
+unsigned SizesAttributeParser::effectiveSize()
+{
+ if (m_lengthWasSet)
+ return m_length;
+ return effectiveSizeDefaultValue();
+}
+
+unsigned SizesAttributeParser::effectiveSizeDefaultValue()
+{
+ // Returning the equivalent of "100%"
+ return m_mediaValues->viewportWidth();
+}
+
+} // namespace
+
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.h b/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.h
new file mode 100644
index 00000000000..3c7bc4ee260
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParser.h
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SizesAttributeParser_h
+#define SizesAttributeParser_h
+
+#include "core/css/MediaValues.h"
+#include "core/css/parser/MediaQueryParser.h"
+#include "platform/heap/Handle.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class SizesAttributeParser {
+ STACK_ALLOCATED();
+public:
+ static unsigned findEffectiveSize(const String& attribute, PassRefPtr<MediaValues>);
+
+private:
+ SizesAttributeParser(PassRefPtr<MediaValues> mediaValues)
+ : m_mediaValues(mediaValues)
+ , m_length(0)
+ , m_lengthWasSet(false)
+ {
+ }
+
+ bool parse(Vector<MediaQueryToken>& tokens);
+ bool parseMediaConditionAndLength(MediaQueryTokenIterator startToken, MediaQueryTokenIterator endToken);
+ unsigned effectiveSize();
+ bool calculateLengthInPixels(MediaQueryTokenIterator startToken, MediaQueryTokenIterator endToken, unsigned& result);
+ bool mediaConditionMatches(PassRefPtrWillBeRawPtr<MediaQuerySet> mediaCondition);
+ unsigned effectiveSizeDefaultValue();
+
+ RefPtrWillBeMember<MediaQuerySet> m_mediaCondition;
+ RefPtr<MediaValues> m_mediaValues;
+ unsigned m_length;
+ bool m_lengthWasSet;
+};
+
+} // namespace
+
+#endif
+
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParserTest.cpp b/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParserTest.cpp
new file mode 100644
index 00000000000..0cc866c2acf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/SizesAttributeParserTest.cpp
@@ -0,0 +1,82 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/SizesAttributeParser.h"
+
+#include "core/css/MediaValuesCached.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+typedef struct {
+ const char* input;
+ const int output;
+} TestCase;
+
+TEST(SizesAttributeParserTest, Basic)
+{
+ TestCase testCases[] = {
+ {"screen", 500},
+ {"(min-width:500px)", 500},
+ {"(min-width:500px) 200px", 200},
+ {"(min-width:500px) 50vw", 250},
+ {"(min-width:500px) 200px, 400px", 200},
+ {"400px, (min-width:500px) 200px", 400},
+ {"(min-width:5000px) 200px, 400px", 400},
+ {"(blalbadfsdf) 200px, 400px", 400},
+ {"0", 0},
+ {"-0", 0},
+ {"1", 500},
+ {"300px, 400px", 300},
+ {"(min-width:5000px) 200px, (min-width:500px) 400px", 400},
+ {"", 500},
+ {" ", 500},
+ {" /**/ ", 500},
+ {" /**/ 300px", 300},
+ {"300px /**/ ", 300},
+ {" /**/ (min-width:500px) /**/ 300px", 300},
+ {"-100px, 200px", 200},
+ {"-50vw, 20vw", 100},
+ {"50asdf, 200px", 200},
+ {"asdf, 200px", 200},
+ {"(max-width: 3000px) 200w, 400w", 500},
+ {",, , /**/ ,200px", 200},
+ {"50vw", 250},
+ {"calc(40vw*2)", 400},
+ {"(min-width:5000px) calc(5000px/10), (min-width:500px) calc(1200px/3)", 400},
+ {"(min-width:500px) calc(1200/3)", 500},
+ {"(min-width:500px) calc(1200px/(0px*14))", 500},
+ {"(max-width: 3000px) 200px, 400px", 200},
+ {"(max-width: 3000px) 20em, 40em", 320},
+ {"(max-width: 3000px) 0, 40em", 0},
+ {"(max-width: 3000px) 50vw, 40em", 250},
+ {0, 0} // Do not remove the terminator line.
+ };
+
+ MediaValuesCached::MediaValuesCachedData data;
+ data.viewportWidth = 500;
+ data.viewportHeight = 500;
+ data.deviceWidth = 500;
+ data.deviceHeight = 500;
+ data.devicePixelRatio = 2.0;
+ data.colorBitsPerComponent = 24;
+ data.monochromeBitsPerComponent = 0;
+ data.pointer = MediaValues::MousePointer;
+ data.defaultFontSize = 16;
+ data.threeDEnabled = true;
+ data.scanMediaType = false;
+ data.screenMediaType = true;
+ data.printMediaType = false;
+ data.strictMode = true;
+ RefPtr<MediaValues> mediaValues = MediaValuesCached::create(data);
+
+ for (unsigned i = 0; testCases[i].input; ++i) {
+ int effectiveSize = SizesAttributeParser::findEffectiveSize(testCases[i].input, mediaValues);
+ ASSERT_EQ(testCases[i].output, effectiveSize);
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParser.cpp b/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParser.cpp
new file mode 100644
index 00000000000..f99688bb609
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParser.cpp
@@ -0,0 +1,214 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/SizesCalcParser.h"
+
+#include "core/css/MediaValues.h"
+#include "core/css/parser/MediaQueryToken.h"
+
+namespace WebCore {
+
+bool SizesCalcParser::parse(MediaQueryTokenIterator start, MediaQueryTokenIterator end, PassRefPtr<MediaValues> mediaValues, unsigned& result)
+{
+ SizesCalcParser parser(mediaValues);
+ if (!parser.calcToReversePolishNotation(start, end))
+ return false;
+ return parser.calculate(result);
+}
+
+static bool operatorPriority(UChar cc, bool& highPriority)
+{
+ if (cc == '+' || cc == '-')
+ highPriority = false;
+ else if (cc == '*' || cc == '/')
+ highPriority = true;
+ else
+ return false;
+ return true;
+}
+
+bool SizesCalcParser::handleOperator(Vector<MediaQueryToken>& stack, const MediaQueryToken& token)
+{
+ // If the token is an operator, o1, then:
+ // while there is an operator token, o2, at the top of the stack, and
+ // either o1 is left-associative and its precedence is equal to that of o2,
+ // or o1 has precedence less than that of o2,
+ // pop o2 off the stack, onto the output queue;
+ // push o1 onto the stack.
+ bool stackOperatorPriority;
+ bool incomingOperatorPriority;
+
+ if (!operatorPriority(token.delimiter(), incomingOperatorPriority))
+ return false;
+ if (!stack.isEmpty() && stack.last().type() == DelimiterToken) {
+ if (!operatorPriority(stack.last().delimiter(), stackOperatorPriority))
+ return false;
+ if (!incomingOperatorPriority || stackOperatorPriority) {
+ appendOperator(stack.last());
+ stack.removeLast();
+ }
+ }
+ stack.append(token);
+ return true;
+}
+
+void SizesCalcParser::appendNumber(const MediaQueryToken& token)
+{
+ SizesCalcValue value;
+ value.value = token.numericValue();
+ m_valueList.append(value);
+}
+
+bool SizesCalcParser::appendLength(const MediaQueryToken& token)
+{
+ SizesCalcValue value;
+ double result = 0;
+ if (!m_mediaValues->computeLength(token.numericValue(), token.unitType(), result))
+ return false;
+ value.value = result;
+ value.isLength = true;
+ m_valueList.append(value);
+ return true;
+}
+
+void SizesCalcParser::appendOperator(const MediaQueryToken& token)
+{
+ SizesCalcValue value;
+ value.operation = token.delimiter();
+ m_valueList.append(value);
+}
+
+bool SizesCalcParser::calcToReversePolishNotation(MediaQueryTokenIterator start, MediaQueryTokenIterator end)
+{
+ // This method implements the shunting yard algorithm, to turn the calc syntax into a reverse polish notation.
+ // http://en.wikipedia.org/wiki/Shunting-yard_algorithm
+
+ Vector<MediaQueryToken> stack;
+ for (MediaQueryTokenIterator it = start; it != end; ++it) {
+ MediaQueryTokenType type = it->type();
+ switch (type) {
+ case NumberToken:
+ appendNumber(*it);
+ break;
+ case DimensionToken:
+ if (!CSSPrimitiveValue::isLength(it->unitType()) || !appendLength(*it))
+ return false;
+ break;
+ case DelimiterToken:
+ if (!handleOperator(stack, *it))
+ return false;
+ break;
+ case FunctionToken:
+ if (it->value() != "calc")
+ return false;
+ // "calc(" is the same as "("
+ case LeftParenthesisToken:
+ // If the token is a left parenthesis, then push it onto the stack.
+ stack.append(*it);
+ break;
+ case RightParenthesisToken:
+ // If the token is a right parenthesis:
+ // Until the token at the top of the stack is a left parenthesis, pop operators off the stack onto the output queue.
+ while (!stack.isEmpty() && stack.last().type() != LeftParenthesisToken && stack.last().type() != FunctionToken) {
+ appendOperator(stack.last());
+ stack.removeLast();
+ }
+ // If the stack runs out without finding a left parenthesis, then there are mismatched parentheses.
+ if (stack.isEmpty())
+ return false;
+ // Pop the left parenthesis from the stack, but not onto the output queue.
+ stack.removeLast();
+ break;
+ case CommentToken:
+ case WhitespaceToken:
+ case EOFToken:
+ break;
+ case PercentageToken:
+ case IdentToken:
+ case CommaToken:
+ case ColonToken:
+ case SemicolonToken:
+ case LeftBraceToken:
+ case LeftBracketToken:
+ case RightBraceToken:
+ case RightBracketToken:
+ case StringToken:
+ case BadStringToken:
+ return false;
+ }
+ }
+
+ // When there are no more tokens to read:
+ // While there are still operator tokens in the stack:
+ while (!stack.isEmpty()) {
+ // If the operator token on the top of the stack is a parenthesis, then there are mismatched parentheses.
+ MediaQueryTokenType type = stack.last().type();
+ if (type == LeftParenthesisToken || type == FunctionToken)
+ return false;
+ // Pop the operator onto the output queue.
+ appendOperator(stack.last());
+ stack.removeLast();
+ }
+ return true;
+}
+
+static bool operateOnStack(Vector<SizesCalcValue>& stack, UChar operation)
+{
+ if (stack.size() < 2)
+ return false;
+ SizesCalcValue rightOperand = stack.last();
+ stack.removeLast();
+ SizesCalcValue leftOperand = stack.last();
+ stack.removeLast();
+ bool isLength;
+ switch (operation) {
+ case '+':
+ if (rightOperand.isLength != leftOperand.isLength)
+ return false;
+ isLength = (rightOperand.isLength && leftOperand.isLength);
+ stack.append(SizesCalcValue(leftOperand.value + rightOperand.value, isLength));
+ break;
+ case '-':
+ if (rightOperand.isLength != leftOperand.isLength)
+ return false;
+ isLength = (rightOperand.isLength && leftOperand.isLength);
+ stack.append(SizesCalcValue(leftOperand.value - rightOperand.value, isLength));
+ break;
+ case '*':
+ if (rightOperand.isLength && leftOperand.isLength)
+ return false;
+ isLength = (rightOperand.isLength || leftOperand.isLength);
+ stack.append(SizesCalcValue(leftOperand.value * rightOperand.value, isLength));
+ break;
+ case '/':
+ if (rightOperand.isLength || rightOperand.value == 0)
+ return false;
+ stack.append(SizesCalcValue(leftOperand.value / rightOperand.value, leftOperand.isLength));
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool SizesCalcParser::calculate(unsigned& result)
+{
+ Vector<SizesCalcValue> stack;
+ for (Vector<SizesCalcValue>::iterator it = m_valueList.begin(); it != m_valueList.end(); ++it) {
+ if (it->operation == 0) {
+ stack.append(*it);
+ } else {
+ if (!operateOnStack(stack, it->operation))
+ return false;
+ }
+ }
+ if (stack.size() == 1 && stack.last().isLength) {
+ result = clampTo<unsigned>(stack.last().value);
+ return true;
+ }
+ return false;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParser.h b/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParser.h
new file mode 100644
index 00000000000..4e040c6cee6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParser.h
@@ -0,0 +1,59 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SizesCalcParser_h
+#define SizesCalcParser_h
+
+#include "core/css/MediaValues.h"
+#include "core/css/parser/MediaQueryToken.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+struct SizesCalcValue {
+ double value;
+ bool isLength;
+ UChar operation;
+
+ SizesCalcValue()
+ : value(0)
+ , isLength(false)
+ , operation(0)
+ {
+ }
+
+ SizesCalcValue(double numericValue, bool length)
+ : value(numericValue)
+ , isLength(length)
+ , operation(0)
+ {
+ }
+};
+
+class SizesCalcParser {
+
+public:
+ static bool parse(MediaQueryTokenIterator start, MediaQueryTokenIterator end, PassRefPtr<MediaValues>, unsigned& result);
+
+private:
+ SizesCalcParser(PassRefPtr<MediaValues> mediaValues)
+ : m_mediaValues(mediaValues)
+ {
+ }
+
+ bool calcToReversePolishNotation(MediaQueryTokenIterator start, MediaQueryTokenIterator end);
+ bool calculate(unsigned& result);
+ void appendNumber(const MediaQueryToken&);
+ bool appendLength(const MediaQueryToken&);
+ bool handleOperator(Vector<MediaQueryToken>& stack, const MediaQueryToken&);
+ void appendOperator(const MediaQueryToken&);
+
+ Vector<SizesCalcValue> m_valueList;
+ RefPtr<MediaValues> m_mediaValues;
+};
+
+} // namespace WebCore
+
+#endif // SizesCalcParser_h
+
diff --git a/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParserTest.cpp b/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParserTest.cpp
new file mode 100644
index 00000000000..67a6f4d92c2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/parser/SizesCalcParserTest.cpp
@@ -0,0 +1,136 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/SizesCalcParser.h"
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/MediaValuesCached.h"
+#include "core/css/StylePropertySet.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+struct TestCase {
+ const char* input;
+ const unsigned output;
+ const bool valid;
+ const bool dontRunInCSSCalc;
+};
+
+static void initLengthArray(CSSLengthArray& lengthArray)
+{
+ lengthArray.resize(CSSPrimitiveValue::LengthUnitTypeCount);
+ for (size_t i = 0; i < CSSPrimitiveValue::LengthUnitTypeCount; ++i)
+ lengthArray.at(i) = 0;
+}
+
+static void verifyCSSCalc(String text, double value, bool valid, unsigned fontSize, unsigned viewportWidth, unsigned viewportHeight)
+{
+ CSSLengthArray lengthArray;
+ initLengthArray(lengthArray);
+ RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
+ propertySet->setProperty(CSSPropertyLeft, text);
+ RefPtrWillBeRawPtr<CSSValue> cssValue = propertySet->getPropertyCSSValue(CSSPropertyLeft);
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(cssValue.get());
+ if (primitiveValue)
+ primitiveValue->accumulateLengthArray(lengthArray);
+ else
+ ASSERT_EQ(valid, false);
+ int length = lengthArray.at(CSSPrimitiveValue::UnitTypePixels);
+ length += lengthArray.at(CSSPrimitiveValue::UnitTypeFontSize) * fontSize;
+ length += lengthArray.at(CSSPrimitiveValue::UnitTypeViewportWidth) * viewportWidth / 100.0;
+ length += lengthArray.at(CSSPrimitiveValue::UnitTypeViewportHeight) * viewportHeight / 100.0;
+ ASSERT_EQ(value, length);
+}
+
+
+TEST(SizesCalcParserTest, Basic)
+{
+ TestCase testCases[] = {
+ {"calc(500px + 10em)", 660, true, false},
+ {"calc(500px + 2 * 10em)", 820, true, false},
+ {"calc(500px + 2*10em)", 820, true, false},
+ {"calc(500px + 0.5*10em)", 580, true, false},
+ {"calc(500px + (0.5*10em + 13px))", 593, true, false},
+ {"calc(100vw + (0.5*10em + 13px))", 593, true, false},
+ {"calc(100vh + (0.5*10em + 13px))", 736, true, false},
+ {"calc(100vh + calc(0.5*10em + 13px))", 736, true, true}, // CSSCalculationValue does not parse internal "calc(".
+ {"calc(100vh + (50%*10em + 13px))", 0, false, false},
+ {"calc(50em+13px)", 0, false, false},
+ {"calc(50em-13px)", 0, false, false},
+ {"calc(500px + 10)", 0, false, false},
+ {"calc(500 + 10)", 0, false, false},
+ {"calc(500px + 10s)", 0, false, true}, // This test ASSERTs in CSSCalculationValue.
+ {"calc(500px + 1cm)", 537, true, false},
+ {"calc(500px - 10s)", 0, false, true}, // This test ASSERTs in CSSCalculationValue.
+ {"calc(500px - 1cm)", 462, true, false},
+ {"calc(50px*10)", 500, true, false},
+ {"calc(50px*10px)", 0, false, false},
+ {"calc(50px/10px)", 0, false, false},
+ {"calc(500px/10)", 50, true, false},
+ {"calc(500/10)", 0, false, false},
+ {"calc(500px/0.5)", 1000, true, false},
+ {"calc(500px/.5)", 1000, true, false},
+ {"calc(500/0)", 0, false, false},
+ {"calc(500px/0)", 0, false, false},
+ {"calc(-500px/10)", 0, true, true}, // CSSCalculationValue does not clamp negative values to 0.
+ {"calc(((4) * ((10px))))", 40, true, false},
+ {"calc(50px / 0)", 0, false, false},
+ {"calc(50px / (10 + 10))", 2, true, false},
+ {"calc(50px / (10 - 10))", 0, false, false},
+ {"calc(50px / (10 * 10))", 0, true, false},
+ {"calc(50px / (10 / 10))", 50, true, false},
+ {"calc(200px*)", 0, false, false},
+ {"calc(+ +200px)", 0, false, false},
+ {"calc()", 0, false, false},
+ {"calc(100px + + +100px)", 0, false, false},
+ {"calc(200px 200px)", 0, false, false},
+ {"calc(100px * * 2)", 0, false, false},
+ {"calc(100px @ 2)", 0, false, false},
+ {"calc(1 flim 2)", 0, false, false},
+ {"calc(100px @ 2)", 0, false, false},
+ {"calc(1 flim 2)", 0, false, false},
+ {"calc(1 flim (2))", 0, false, false},
+ {0, 0, true, false} // Do not remove the terminator line.
+ };
+
+
+ MediaValuesCached::MediaValuesCachedData data;
+ data.viewportWidth = 500;
+ data.viewportHeight = 643;
+ data.deviceWidth = 500;
+ data.deviceHeight = 643;
+ data.devicePixelRatio = 2.0;
+ data.colorBitsPerComponent = 24;
+ data.monochromeBitsPerComponent = 0;
+ data.pointer = MediaValues::MousePointer;
+ data.defaultFontSize = 16;
+ data.threeDEnabled = true;
+ data.scanMediaType = false;
+ data.screenMediaType = true;
+ data.printMediaType = false;
+ data.strictMode = true;
+ RefPtr<MediaValues> mediaValues = MediaValuesCached::create(data);
+
+ for (unsigned i = 0; testCases[i].input; ++i) {
+ Vector<MediaQueryToken> tokens;
+ MediaQueryTokenizer::tokenize(testCases[i].input, tokens);
+ unsigned output;
+ bool valid = SizesCalcParser::parse(tokens.begin(), tokens.end(), mediaValues, output);
+ ASSERT_EQ(testCases[i].valid, valid);
+ if (valid)
+ ASSERT_EQ(testCases[i].output, output);
+ }
+
+ for (unsigned i = 0; testCases[i].input; ++i) {
+ if (testCases[i].dontRunInCSSCalc)
+ continue;
+ verifyCSSCalc(testCases[i].input, testCases[i].output, testCases[i].valid, data.defaultFontSize, data.viewportWidth, data.viewportHeight);
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp
index dbfd63b8bb6..89d6cc3d0bd 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.cpp
@@ -40,6 +40,7 @@
#include "core/animation/AnimatableLengthBox.h"
#include "core/animation/AnimatableLengthBoxAndBool.h"
#include "core/animation/AnimatableLengthPoint.h"
+#include "core/animation/AnimatableLengthPoint3D.h"
#include "core/animation/AnimatableLengthSize.h"
#include "core/animation/AnimatableRepeatable.h"
#include "core/animation/AnimatableSVGLength.h"
@@ -63,11 +64,11 @@ namespace WebCore {
namespace {
-Length animatableValueToLength(const AnimatableValue* value, const StyleResolverState& state, NumberRange range = AllValues)
+Length animatableValueToLength(const AnimatableValue* value, const StyleResolverState& state, ValueRange range = ValueRangeAll)
{
if (value->isLength())
- return toAnimatableLength(value)->toLength(state.cssToLengthConversionData(), range);
- RefPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
+ return toAnimatableLength(value)->length(state.style()->effectiveZoom(), range);
+ RefPtrWillBeRawPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
CSSPrimitiveValue* cssPrimitiveValue = toCSSPrimitiveValue(cssValue.get());
return cssPrimitiveValue->convertToLength<AnyConversion>(state.cssToLengthConversionData());
}
@@ -75,10 +76,10 @@ Length animatableValueToLength(const AnimatableValue* value, const StyleResolver
BorderImageLength animatableValueToBorderImageLength(const AnimatableValue* value, const StyleResolverState& state)
{
if (value->isLength())
- return BorderImageLength(toAnimatableLength(value)->toLength(state.cssToLengthConversionData(), NonNegativeValues));
+ return BorderImageLength(toAnimatableLength(value)->length(state.style()->effectiveZoom(), ValueRangeNonNegative));
if (value->isDouble())
return BorderImageLength(clampTo<double>(toAnimatableDouble(value)->toDouble(), 0));
- RefPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
+ RefPtrWillBeRawPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
CSSPrimitiveValue* cssPrimitiveValue = toCSSPrimitiveValue(cssValue.get());
return BorderImageLength(cssPrimitiveValue->convertToLength<AnyConversion>(state.cssToLengthConversionData()));
}
@@ -89,7 +90,7 @@ template<typename T> T animatableValueRoundClampTo(const AnimatableValue* value,
return clampTo<T>(round(toAnimatableDouble(value)->toDouble()), min, max);
}
-LengthBox animatableValueToLengthBox(const AnimatableValue* value, const StyleResolverState& state, NumberRange range = AllValues)
+LengthBox animatableValueToLengthBox(const AnimatableValue* value, const StyleResolverState& state, ValueRange range = ValueRangeAll)
{
const AnimatableLengthBox* animatableLengthBox = toAnimatableLengthBox(value);
return LengthBox(
@@ -109,7 +110,7 @@ BorderImageLengthBox animatableValueToBorderImageLengthBox(const AnimatableValue
animatableValueToBorderImageLength(animatableLengthBox->left(), state));
}
-LengthPoint animatableValueToLengthPoint(const AnimatableValue* value, const StyleResolverState& state, NumberRange range = AllValues)
+LengthPoint animatableValueToLengthPoint(const AnimatableValue* value, const StyleResolverState& state, ValueRange range = ValueRangeAll)
{
const AnimatableLengthPoint* animatableLengthPoint = toAnimatableLengthPoint(value);
return LengthPoint(
@@ -117,7 +118,7 @@ LengthPoint animatableValueToLengthPoint(const AnimatableValue* value, const Sty
animatableValueToLength(animatableLengthPoint->y(), state, range));
}
-LengthSize animatableValueToLengthSize(const AnimatableValue* value, const StyleResolverState& state, NumberRange range)
+LengthSize animatableValueToLengthSize(const AnimatableValue* value, const StyleResolverState& state, ValueRange range)
{
const AnimatableLengthSize* animatableLengthSize = toAnimatableLengthSize(value);
return LengthSize(
@@ -129,23 +130,23 @@ template <CSSPropertyID property>
void setFillSize(FillLayer* fillLayer, const AnimatableValue* value, const StyleResolverState& state)
{
if (value->isLengthSize())
- fillLayer->setSize(FillSize(SizeLength, animatableValueToLengthSize(value, state, NonNegativeValues)));
+ fillLayer->setSize(FillSize(SizeLength, animatableValueToLengthSize(value, state, ValueRangeNonNegative)));
else
state.styleMap().mapFillSize(property, fillLayer, toAnimatableUnknown(value)->toCSSValue().get());
}
-SVGLength animatableValueToNonNegativeSVGLength(const AnimatableValue* value)
+PassRefPtr<SVGLength> animatableValueToNonNegativeSVGLength(const AnimatableValue* value)
{
- SVGLength length = toAnimatableSVGLength(value)->toSVGLength();
- if (length.valueInSpecifiedUnits() < 0)
- length.setValueInSpecifiedUnits(0);
- return length;
+ RefPtr<SVGLength> length = toAnimatableSVGLength(value)->toSVGLength();
+ if (length->valueInSpecifiedUnits() < 0)
+ length->setValueInSpecifiedUnits(0);
+ return length.release();
}
template <CSSPropertyID property>
void setOnFillLayers(FillLayer* fillLayer, const AnimatableValue* value, StyleResolverState& state)
{
- const Vector<RefPtr<AnimatableValue> >& values = toAnimatableRepeatable(value)->values();
+ const WillBeHeapVector<RefPtrWillBeMember<AnimatableValue> >& values = toAnimatableRepeatable(value)->values();
ASSERT(!values.isEmpty());
FillLayer* prev = 0;
for (size_t i = 0; i < values.size(); ++i) {
@@ -174,10 +175,10 @@ void setOnFillLayers(FillLayer* fillLayer, const AnimatableValue* value, StyleRe
case CSSPropertyBackgroundImage:
case CSSPropertyWebkitMaskImage:
if (layerValue->isImage()) {
- fillLayer->setImage(toAnimatableImage(layerValue)->toStyleImage());
+ fillLayer->setImage(state.styleImage(property, toAnimatableImage(layerValue)->toCSSValue()));
} else {
ASSERT(toAnimatableUnknown(layerValue)->toCSSValueID() == CSSValueNone);
- fillLayer->setImage(0);
+ fillLayer->setImage(nullptr);
}
break;
case CSSPropertyBackgroundPositionX:
@@ -225,11 +226,33 @@ void setOnFillLayers(FillLayer* fillLayer, const AnimatableValue* value, StyleRe
}
}
+FontWeight animatableValueToFontWeight(const AnimatableValue* value)
+{
+ int index = round(toAnimatableDouble(value)->toDouble() / 100) - 1;
+
+ static const FontWeight weights[] = {
+ FontWeight100,
+ FontWeight200,
+ FontWeight300,
+ FontWeight400,
+ FontWeight500,
+ FontWeight600,
+ FontWeight700,
+ FontWeight800,
+ FontWeight900
+ };
+
+ index = clampTo<int>(index, 0, WTF_ARRAY_LENGTH(weights) - 1);
+
+ return weights[index];
+}
+
} // namespace
// FIXME: Generate this function.
void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverState& state, const AnimatableValue* value)
{
+ ASSERT(CSSAnimations::isAnimatableProperty(property));
if (value->isUnknown()) {
StyleBuilder::applyProperty(property, state, toAnimatableUnknown(value)->toCSSValue().get());
return;
@@ -260,10 +283,10 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setVisitedLinkBorderBottomColor(toAnimatableColor(value)->visitedLinkColor());
return;
case CSSPropertyBorderBottomLeftRadius:
- style->setBorderBottomLeftRadius(animatableValueToLengthSize(value, state, NonNegativeValues));
+ style->setBorderBottomLeftRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
return;
case CSSPropertyBorderBottomRightRadius:
- style->setBorderBottomRightRadius(animatableValueToLengthSize(value, state, NonNegativeValues));
+ style->setBorderBottomRightRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
return;
case CSSPropertyBorderBottomWidth:
style->setBorderBottomWidth(animatableValueRoundClampTo<unsigned>(value));
@@ -272,10 +295,10 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setBorderImageOutset(animatableValueToBorderImageLengthBox(value, state));
return;
case CSSPropertyBorderImageSlice:
- style->setBorderImageSlices(animatableValueToLengthBox(value, state, NonNegativeValues));
+ style->setBorderImageSlices(animatableValueToLengthBox(value, state, ValueRangeNonNegative));
return;
case CSSPropertyBorderImageSource:
- style->setBorderImageSource(toAnimatableImage(value)->toStyleImage());
+ style->setBorderImageSource(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
return;
case CSSPropertyBorderImageWidth:
style->setBorderImageWidth(animatableValueToBorderImageLengthBox(value, state));
@@ -299,10 +322,10 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setVisitedLinkBorderTopColor(toAnimatableColor(value)->visitedLinkColor());
return;
case CSSPropertyBorderTopLeftRadius:
- style->setBorderTopLeftRadius(animatableValueToLengthSize(value, state, NonNegativeValues));
+ style->setBorderTopLeftRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
return;
case CSSPropertyBorderTopRightRadius:
- style->setBorderTopRightRadius(animatableValueToLengthSize(value, state, NonNegativeValues));
+ style->setBorderTopRightRadius(animatableValueToLengthSize(value, state, ValueRangeNonNegative));
return;
case CSSPropertyBorderTopWidth:
style->setBorderTopWidth(animatableValueRoundClampTo<unsigned>(value));
@@ -323,13 +346,13 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setVisitedLinkColor(toAnimatableColor(value)->visitedLinkColor());
return;
case CSSPropertyFillOpacity:
- // Avoiding a value of 1 forces a layer to be created.
- style->setFillOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, nextafterf(1, 0)));
+ style->setFillOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
return;
case CSSPropertyFill:
{
const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
- style->accessSVGStyle()->setFillPaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri());
+ style->accessSVGStyle()->setFillPaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri(), true, false);
+ style->accessSVGStyle()->setFillPaint(svgPaint->visitedLinkPaintType(), svgPaint->visitedLinkColor(), svgPaint->visitedLinkURI(), false, true);
}
return;
case CSSPropertyFlexGrow:
@@ -339,7 +362,7 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setFlexShrink(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
return;
case CSSPropertyFlexBasis:
- style->setFlexBasis(animatableValueToLength(value, state, NonNegativeValues));
+ style->setFlexBasis(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyFloodColor:
style->setFloodColor(toAnimatableColor(value)->color());
@@ -350,11 +373,11 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
case CSSPropertyFontSize:
style->setFontSize(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
return;
- case CSSPropertyHeight:
- style->setHeight(animatableValueToLength(value, state, NonNegativeValues));
+ case CSSPropertyFontWeight:
+ style->setFontWeight(animatableValueToFontWeight(value));
return;
- case CSSPropertyKerning:
- style->setKerning(toAnimatableSVGLength(value)->toSVGLength());
+ case CSSPropertyHeight:
+ style->setHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyLeft:
style->setLeft(animatableValueToLength(value, state));
@@ -364,12 +387,12 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
return;
case CSSPropertyLineHeight:
if (value->isLength())
- style->setLineHeight(animatableValueToLength(value, state, NonNegativeValues));
+ style->setLineHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
else
style->setLineHeight(Length(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0), Percent));
return;
case CSSPropertyListStyleImage:
- style->setListStyleImage(toAnimatableImage(value)->toStyleImage());
+ style->setListStyleImage(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
return;
case CSSPropertyLetterSpacing:
style->setLetterSpacing(clampTo<float>(toAnimatableDouble(value)->toDouble()));
@@ -387,16 +410,16 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setMarginTop(animatableValueToLength(value, state));
return;
case CSSPropertyMaxHeight:
- style->setMaxHeight(animatableValueToLength(value, state, NonNegativeValues));
+ style->setMaxHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyMaxWidth:
- style->setMaxWidth(animatableValueToLength(value, state, NonNegativeValues));
+ style->setMaxWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyMinHeight:
- style->setMinHeight(animatableValueToLength(value, state, NonNegativeValues));
+ style->setMinHeight(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyMinWidth:
- style->setMinWidth(animatableValueToLength(value, state, NonNegativeValues));
+ style->setMinWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyObjectPosition:
style->setObjectPosition(animatableValueToLengthPoint(value, state));
@@ -419,16 +442,16 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setOutlineWidth(animatableValueRoundClampTo<unsigned short>(value));
return;
case CSSPropertyPaddingBottom:
- style->setPaddingBottom(animatableValueToLength(value, state, NonNegativeValues));
+ style->setPaddingBottom(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyPaddingLeft:
- style->setPaddingLeft(animatableValueToLength(value, state, NonNegativeValues));
+ style->setPaddingLeft(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyPaddingRight:
- style->setPaddingRight(animatableValueToLength(value, state, NonNegativeValues));
+ style->setPaddingRight(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyPaddingTop:
- style->setPaddingTop(animatableValueToLength(value, state, NonNegativeValues));
+ style->setPaddingTop(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyRight:
style->setRight(animatableValueToLength(value, state));
@@ -443,7 +466,7 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setStopOpacity(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
return;
case CSSPropertyStrokeDasharray:
- style->setStrokeDashArray(toAnimatableStrokeDasharrayList(value)->toSVGLengthVector());
+ style->setStrokeDashArray(toAnimatableStrokeDasharrayList(value)->toSVGLengthList());
return;
case CSSPropertyStrokeDashoffset:
style->setStrokeDashOffset(toAnimatableSVGLength(value)->toSVGLength());
@@ -457,7 +480,8 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
case CSSPropertyStroke:
{
const AnimatableSVGPaint* svgPaint = toAnimatableSVGPaint(value);
- style->accessSVGStyle()->setStrokePaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri());
+ style->accessSVGStyle()->setStrokePaint(svgPaint->paintType(), svgPaint->color(), svgPaint->uri(), true, false);
+ style->accessSVGStyle()->setStrokePaint(svgPaint->visitedLinkPaintType(), svgPaint->visitedLinkColor(), svgPaint->visitedLinkURI(), false, true);
}
return;
case CSSPropertyTextDecorationColor:
@@ -508,11 +532,11 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setMaskBoxImageOutset(animatableValueToBorderImageLengthBox(value, state));
return;
case CSSPropertyWebkitMaskBoxImageSlice:
- style->setMaskBoxImageSlices(animatableValueToLengthBox(toAnimatableLengthBoxAndBool(value)->box(), state, NonNegativeValues));
+ style->setMaskBoxImageSlices(animatableValueToLengthBox(toAnimatableLengthBoxAndBool(value)->box(), state, ValueRangeNonNegative));
style->setMaskBoxImageSlicesFill(toAnimatableLengthBoxAndBool(value)->flag());
return;
case CSSPropertyWebkitMaskBoxImageSource:
- style->setMaskBoxImageSource(toAnimatableImage(value)->toStyleImage());
+ style->setMaskBoxImageSource(state.styleImage(property, toAnimatableImage(value)->toCSSValue()));
return;
case CSSPropertyWebkitMaskBoxImageWidth:
style->setMaskBoxImageWidth(animatableValueToBorderImageLengthBox(value, state));
@@ -529,23 +553,29 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
case CSSPropertyWebkitMaskSize:
setOnFillLayers<CSSPropertyWebkitMaskSize>(style->accessMaskLayers(), value, state);
return;
- case CSSPropertyWebkitPerspective:
+ case CSSPropertyPerspective:
style->setPerspective(clampTo<float>(toAnimatableDouble(value)->toDouble()));
return;
+ case CSSPropertyPerspectiveOrigin: {
+ ASSERT(RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
+ const AnimatableLengthPoint* animatableLengthPoint = toAnimatableLengthPoint(value);
+ style->setPerspectiveOriginX(animatableValueToLength(animatableLengthPoint->x(), state));
+ style->setPerspectiveOriginY(animatableValueToLength(animatableLengthPoint->y(), state));
+ return;
+ }
case CSSPropertyWebkitPerspectiveOriginX:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setPerspectiveOriginX(animatableValueToLength(value, state));
return;
case CSSPropertyWebkitPerspectiveOriginY:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setPerspectiveOriginY(animatableValueToLength(value, state));
return;
- case CSSPropertyShapeInside:
- style->setShapeInside(toAnimatableShapeValue(value)->shapeValue());
- return;
case CSSPropertyShapeOutside:
style->setShapeOutside(toAnimatableShapeValue(value)->shapeValue());
return;
case CSSPropertyShapeMargin:
- style->setShapeMargin(animatableValueToLength(value, state, NonNegativeValues));
+ style->setShapeMargin(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyShapeImageThreshold:
style->setShapeImageThreshold(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0, 1));
@@ -554,31 +584,44 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setTextStrokeColor(toAnimatableColor(value)->color());
style->setVisitedLinkTextStrokeColor(toAnimatableColor(value)->visitedLinkColor());
return;
- case CSSPropertyWebkitTransform: {
+ case CSSPropertyTransform: {
const TransformOperations& operations = toAnimatableTransform(value)->transformOperations();
- // FIXME: Using identity matrix here when the transform list is empty
- // forces a layer to be created in the presence of a transform animation.
+ // FIXME: This normalization (handling of 'none') should be performed at input in AnimatableValueFactory.
style->setTransform(operations.size() ? operations : TransformOperations(true));
return;
}
+ case CSSPropertyTransformOrigin: {
+ ASSERT(RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
+ const AnimatableLengthPoint3D* animatableLengthPoint3D = toAnimatableLengthPoint3D(value);
+ style->setTransformOriginX(animatableValueToLength(animatableLengthPoint3D->x(), state));
+ style->setTransformOriginY(animatableValueToLength(animatableLengthPoint3D->y(), state));
+ style->setTransformOriginZ(clampTo<float>(toAnimatableDouble(animatableLengthPoint3D->z())->toDouble()));
+ return;
+ }
case CSSPropertyWebkitTransformOriginX:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setTransformOriginX(animatableValueToLength(value, state));
return;
case CSSPropertyWebkitTransformOriginY:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setTransformOriginY(animatableValueToLength(value, state));
return;
case CSSPropertyWebkitTransformOriginZ:
+ ASSERT(!RuntimeEnabledFeatures::cssTransformsUnprefixedEnabled());
style->setTransformOriginZ(toAnimatableDouble(value)->toDouble());
return;
case CSSPropertyWidows:
style->setWidows(animatableValueRoundClampTo<unsigned short>(value, 1));
return;
case CSSPropertyWidth:
- style->setWidth(animatableValueToLength(value, state, NonNegativeValues));
+ style->setWidth(animatableValueToLength(value, state, ValueRangeNonNegative));
return;
case CSSPropertyWordSpacing:
style->setWordSpacing(clampTo<float>(toAnimatableDouble(value)->toDouble()));
return;
+ case CSSPropertyVerticalAlign:
+ style->setVerticalAlignLength(animatableValueToLength(value, state));
+ return;
case CSSPropertyVisibility:
style->setVisibility(toAnimatableVisibility(value)->visibility());
return;
@@ -589,7 +632,6 @@ void AnimatedStyleBuilder::applyProperty(CSSPropertyID property, StyleResolverSt
style->setZoom(clampTo<float>(toAnimatableDouble(value)->toDouble(), std::numeric_limits<float>::denorm_min()));
return;
default:
- ASSERT_WITH_MESSAGE(!CSSAnimations::isAnimatableProperty(property), "Web Animations not yet implemented: Unable to apply AnimatableValue to RenderStyle: %s", getPropertyNameString(property).utf8().data());
ASSERT_NOT_REACHED();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.h b/chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.h
index 3f91a145a4c..1139c524326 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/AnimatedStyleBuilder.h
@@ -31,7 +31,7 @@
#ifndef AnimatedStyleBuilder_h
#define AnimatedStyleBuilder_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
index 9eeec75b2c7..465a89e1bbf 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.cpp
@@ -28,7 +28,8 @@
#include "config.h"
#include "core/css/resolver/CSSToStyleMap.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
+#include "core/animation/css/CSSAnimationData.h"
#include "core/css/CSSBorderImageSliceValue.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSPrimitiveValueMappings.h"
@@ -36,7 +37,6 @@
#include "core/css/Pair.h"
#include "core/css/Rect.h"
#include "core/css/resolver/StyleResolverState.h"
-#include "core/platform/animation/CSSAnimationData.h"
#include "core/rendering/style/BorderImageLengthBox.h"
#include "core/rendering/style/FillLayer.h"
@@ -47,14 +47,9 @@ const CSSToLengthConversionData& CSSToStyleMap::cssToLengthConversionData() cons
return m_state.cssToLengthConversionData();
}
-bool CSSToStyleMap::useSVGZoomRules() const
-{
- return m_state.useSVGZoomRules();
-}
-
PassRefPtr<StyleImage> CSSToStyleMap::styleImage(CSSPropertyID propertyId, CSSValue* value)
{
- return m_elementStyleResources.styleImage(m_state.document().textLinkColors(), m_state.style()->color(), propertyId, value);
+ return m_elementStyleResources.styleImage(m_state.document(), m_state.document().textLinkColors(), m_state.style()->color(), propertyId, value);
}
void CSSToStyleMap::mapFillAttachment(CSSPropertyID, FillLayer* layer, CSSValue* value) const
@@ -215,9 +210,6 @@ void CSSToStyleMap::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* value
secondLength = Length();
}
- if (firstLength.isUndefined() || secondLength.isUndefined())
- return;
-
b.setWidth(firstLength);
b.setHeight(secondLength);
layer->setSizeLength(b);
@@ -241,7 +233,6 @@ void CSSToStyleMap::mapFillXPosition(CSSPropertyID propertyID, FillLayer* layer,
}
Length length = primitiveValue->convertToLength<FixedConversion | PercentConversion>(cssToLengthConversionData());
- ASSERT(!length.isUndefined());
layer->setXPosition(length);
if (pair)
@@ -266,7 +257,6 @@ void CSSToStyleMap::mapFillYPosition(CSSPropertyID propertyID, FillLayer* layer,
}
Length length = primitiveValue->convertToLength<FixedConversion | PercentConversion>(cssToLengthConversionData());
- ASSERT(!length.isUndefined());
layer->setYPosition(length);
if (pair)
@@ -300,207 +290,150 @@ void CSSToStyleMap::mapFillMaskSourceType(CSSPropertyID, FillLayer* layer, CSSVa
layer->setMaskSourceType(type);
}
-void CSSToStyleMap::mapAnimationDelay(CSSAnimationData* animation, CSSValue* value) const
+double CSSToStyleMap::mapAnimationDelay(CSSValue* value)
{
- if (value->isInitialValue()) {
- animation->setDelay(CSSAnimationData::initialAnimationDelay());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
- animation->setDelay(toCSSPrimitiveValue(value)->computeTime<double, CSSPrimitiveValue::Seconds>());
+ if (value->isInitialValue())
+ return CSSTimingData::initialDelay();
+ return toCSSPrimitiveValue(value)->computeTime<double, CSSPrimitiveValue::Seconds>();
}
-void CSSToStyleMap::mapAnimationDirection(CSSAnimationData* layer, CSSValue* value) const
+Timing::PlaybackDirection CSSToStyleMap::mapAnimationDirection(CSSValue* value)
{
- if (value->isInitialValue()) {
- layer->setDirection(CSSAnimationData::initialAnimationDirection());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
+ if (value->isInitialValue())
+ return CSSAnimationData::initialDirection();
switch (toCSSPrimitiveValue(value)->getValueID()) {
case CSSValueNormal:
- layer->setDirection(CSSAnimationData::AnimationDirectionNormal);
- break;
+ return Timing::PlaybackDirectionNormal;
case CSSValueAlternate:
- layer->setDirection(CSSAnimationData::AnimationDirectionAlternate);
- break;
+ return Timing::PlaybackDirectionAlternate;
case CSSValueReverse:
- layer->setDirection(CSSAnimationData::AnimationDirectionReverse);
- break;
+ return Timing::PlaybackDirectionReverse;
case CSSValueAlternateReverse:
- layer->setDirection(CSSAnimationData::AnimationDirectionAlternateReverse);
- break;
+ return Timing::PlaybackDirectionAlternateReverse;
default:
- break;
+ ASSERT_NOT_REACHED();
+ return CSSAnimationData::initialDirection();
}
}
-void CSSToStyleMap::mapAnimationDuration(CSSAnimationData* animation, CSSValue* value) const
+double CSSToStyleMap::mapAnimationDuration(CSSValue* value)
{
- if (value->isInitialValue()) {
- animation->setDuration(CSSAnimationData::initialAnimationDuration());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- animation->setDuration(primitiveValue->computeTime<double, CSSPrimitiveValue::Seconds>());
+ if (value->isInitialValue())
+ return CSSTimingData::initialDuration();
+ return toCSSPrimitiveValue(value)->computeTime<double, CSSPrimitiveValue::Seconds>();
}
-void CSSToStyleMap::mapAnimationFillMode(CSSAnimationData* layer, CSSValue* value) const
+Timing::FillMode CSSToStyleMap::mapAnimationFillMode(CSSValue* value)
{
- if (value->isInitialValue()) {
- layer->setFillMode(CSSAnimationData::initialAnimationFillMode());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
+ if (value->isInitialValue())
+ return CSSAnimationData::initialFillMode();
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- switch (primitiveValue->getValueID()) {
+ switch (toCSSPrimitiveValue(value)->getValueID()) {
case CSSValueNone:
- layer->setFillMode(AnimationFillModeNone);
- break;
+ return Timing::FillModeNone;
case CSSValueForwards:
- layer->setFillMode(AnimationFillModeForwards);
- break;
+ return Timing::FillModeForwards;
case CSSValueBackwards:
- layer->setFillMode(AnimationFillModeBackwards);
- break;
+ return Timing::FillModeBackwards;
case CSSValueBoth:
- layer->setFillMode(AnimationFillModeBoth);
- break;
+ return Timing::FillModeBoth;
default:
- break;
+ ASSERT_NOT_REACHED();
+ return CSSAnimationData::initialFillMode();
}
}
-void CSSToStyleMap::mapAnimationIterationCount(CSSAnimationData* animation, CSSValue* value) const
+double CSSToStyleMap::mapAnimationIterationCount(CSSValue* value)
{
- if (value->isInitialValue()) {
- animation->setIterationCount(CSSAnimationData::initialAnimationIterationCount());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
+ if (value->isInitialValue())
+ return CSSAnimationData::initialIterationCount();
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
if (primitiveValue->getValueID() == CSSValueInfinite)
- animation->setIterationCount(CSSAnimationData::IterationCountInfinite);
- else
- animation->setIterationCount(primitiveValue->getFloatValue());
+ return std::numeric_limits<double>::infinity();
+ return primitiveValue->getFloatValue();
}
-void CSSToStyleMap::mapAnimationName(CSSAnimationData* layer, CSSValue* value) const
+AtomicString CSSToStyleMap::mapAnimationName(CSSValue* value)
{
- if (value->isInitialValue()) {
- layer->setName(CSSAnimationData::initialAnimationName());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
+ if (value->isInitialValue())
+ return CSSAnimationData::initialName();
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
if (primitiveValue->getValueID() == CSSValueNone)
- layer->setIsNoneAnimation(true);
- else
- layer->setName(AtomicString(primitiveValue->getStringValue()));
+ return CSSAnimationData::initialName();
+ return AtomicString(primitiveValue->getStringValue());
}
-void CSSToStyleMap::mapAnimationPlayState(CSSAnimationData* layer, CSSValue* value) const
+EAnimPlayState CSSToStyleMap::mapAnimationPlayState(CSSValue* value)
{
- if (value->isInitialValue()) {
- layer->setPlayState(CSSAnimationData::initialAnimationPlayState());
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- EAnimPlayState playState = (primitiveValue->getValueID() == CSSValuePaused) ? AnimPlayStatePaused : AnimPlayStatePlaying;
- layer->setPlayState(playState);
+ if (value->isInitialValue())
+ return CSSAnimationData::initialPlayState();
+ if (toCSSPrimitiveValue(value)->getValueID() == CSSValuePaused)
+ return AnimPlayStatePaused;
+ ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueRunning);
+ return AnimPlayStatePlaying;
}
-void CSSToStyleMap::mapAnimationProperty(CSSAnimationData* animation, CSSValue* value) const
+CSSTransitionData::TransitionProperty CSSToStyleMap::mapAnimationProperty(CSSValue* value)
{
- if (value->isInitialValue()) {
- animation->setAnimationMode(CSSAnimationData::AnimateAll);
- animation->setProperty(CSSPropertyInvalid);
- return;
- }
-
- if (!value->isPrimitiveValue())
- return;
-
+ if (value->isInitialValue())
+ return CSSTransitionData::initialProperty();
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (primitiveValue->getValueID() == CSSValueAll) {
- animation->setAnimationMode(CSSAnimationData::AnimateAll);
- animation->setProperty(CSSPropertyInvalid);
- } else if (primitiveValue->getValueID() == CSSValueNone) {
- animation->setAnimationMode(CSSAnimationData::AnimateNone);
- animation->setProperty(CSSPropertyInvalid);
- } else {
- animation->setAnimationMode(CSSAnimationData::AnimateSingleProperty);
- animation->setProperty(primitiveValue->getPropertyID());
- }
+ if (primitiveValue->isString())
+ return CSSTransitionData::TransitionProperty(primitiveValue->getStringValue());
+ if (primitiveValue->getValueID() == CSSValueAll)
+ return CSSTransitionData::TransitionProperty(CSSTransitionData::TransitionAll);
+ if (primitiveValue->getValueID() == CSSValueNone)
+ return CSSTransitionData::TransitionProperty(CSSTransitionData::TransitionNone);
+ return CSSTransitionData::TransitionProperty(primitiveValue->getPropertyID());
}
-void CSSToStyleMap::mapAnimationTimingFunction(CSSAnimationData* animation, CSSValue* value) const
+PassRefPtr<TimingFunction> CSSToStyleMap::mapAnimationTimingFunction(CSSValue* value, bool allowStepMiddle)
{
- if (value->isInitialValue()) {
- animation->setTimingFunction(CSSAnimationData::initialAnimationTimingFunction());
- return;
- }
+ // FIXME: We should probably only call into this function with a valid
+ // single timing function value which isn't initial or inherit. We can
+ // currently get into here with initial since the parser expands unset
+ // properties in shorthands to initial.
if (value->isPrimitiveValue()) {
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
switch (primitiveValue->getValueID()) {
case CSSValueLinear:
- animation->setTimingFunction(LinearTimingFunction::create());
- break;
+ return LinearTimingFunction::shared();
case CSSValueEase:
- animation->setTimingFunction(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease));
- break;
+ return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
case CSSValueEaseIn:
- animation->setTimingFunction(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
- break;
+ return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
case CSSValueEaseOut:
- animation->setTimingFunction(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut));
- break;
+ return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
case CSSValueEaseInOut:
- animation->setTimingFunction(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut));
- break;
+ return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
case CSSValueStepStart:
- animation->setTimingFunction(StepsTimingFunction::preset(StepsTimingFunction::Start));
- break;
+ return StepsTimingFunction::preset(StepsTimingFunction::Start);
+ case CSSValueStepMiddle:
+ if (allowStepMiddle)
+ return StepsTimingFunction::preset(StepsTimingFunction::Middle);
+ return CSSTimingData::initialTimingFunction();
case CSSValueStepEnd:
- animation->setTimingFunction(StepsTimingFunction::preset(StepsTimingFunction::End));
- break;
+ return StepsTimingFunction::preset(StepsTimingFunction::End);
default:
- break;
+ ASSERT_NOT_REACHED();
+ return CSSTimingData::initialTimingFunction();
}
- return;
}
if (value->isCubicBezierTimingFunctionValue()) {
CSSCubicBezierTimingFunctionValue* cubicTimingFunction = toCSSCubicBezierTimingFunctionValue(value);
- animation->setTimingFunction(CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2()));
- } else if (value->isStepsTimingFunctionValue()) {
- CSSStepsTimingFunctionValue* stepsTimingFunction = toCSSStepsTimingFunctionValue(value);
- animation->setTimingFunction(StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart()));
+ return CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2());
}
+
+ if (value->isInitialValue())
+ return CSSTimingData::initialTimingFunction();
+
+ CSSStepsTimingFunctionValue* stepsTimingFunction = toCSSStepsTimingFunctionValue(value);
+ if (stepsTimingFunction->stepAtPosition() == StepsTimingFunction::StepAtMiddle && !allowStepMiddle)
+ return CSSTimingData::initialTimingFunction();
+ return StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtPosition());
}
void CSSToStyleMap::mapNinePieceImage(RenderStyle* mutableStyle, CSSPropertyID property, CSSValue* value, NinePieceImage& image)
@@ -611,16 +544,14 @@ BorderImageLengthBox CSSToStyleMap::mapNinePieceImageQuad(CSSValue* value) const
if (!value || !value->isPrimitiveValue())
return BorderImageLengthBox(Length(Auto));
- float zoom = useSVGZoomRules() ? 1.0f : cssToLengthConversionData().zoom();
Quad* slices = toCSSPrimitiveValue(value)->getQuadValue();
// Set up a border image length box to represent our image slices.
- const CSSToLengthConversionData& conversionData = cssToLengthConversionData().copyWithAdjustedZoom(zoom);
return BorderImageLengthBox(
- toBorderImageLength(*slices->top(), conversionData),
- toBorderImageLength(*slices->right(), conversionData),
- toBorderImageLength(*slices->bottom(), conversionData),
- toBorderImageLength(*slices->left(), conversionData));
+ toBorderImageLength(*slices->top(), cssToLengthConversionData()),
+ toBorderImageLength(*slices->right(), cssToLengthConversionData()),
+ toBorderImageLength(*slices->bottom(), cssToLengthConversionData()),
+ toBorderImageLength(*slices->left(), cssToLengthConversionData()));
}
void CSSToStyleMap::mapNinePieceImageRepeat(CSSValue* value, NinePieceImage& image) const
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.h b/chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.h
index b994b6f0a78..e539064f8ba 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/CSSToStyleMap.h
@@ -22,14 +22,17 @@
#ifndef CSSToStyleMap_h
#define CSSToStyleMap_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/animation/Timing.h"
+#include "core/animation/css/CSSTransitionData.h"
#include "core/css/resolver/ElementStyleResources.h"
+#include "core/rendering/style/RenderStyleConstants.h"
+#include "platform/animation/TimingFunction.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
class FillLayer;
-class CSSAnimationData;
class CSSToLengthConversionData;
class CSSValue;
class RenderStyle;
@@ -43,10 +46,10 @@ class BorderImageLengthBox;
// CSSValue objects into their RenderStyle equivalents.
class CSSToStyleMap {
+ STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(CSSToStyleMap);
public:
CSSToStyleMap(const StyleResolverState& state, ElementStyleResources& elementStyleResources) : m_state(state), m_elementStyleResources(elementStyleResources) { }
-
void mapFillAttachment(CSSPropertyID, FillLayer*, CSSValue*) const;
void mapFillClip(CSSPropertyID, FillLayer*, CSSValue*) const;
void mapFillComposite(CSSPropertyID, FillLayer*, CSSValue*) const;
@@ -60,15 +63,15 @@ public:
void mapFillYPosition(CSSPropertyID, FillLayer*, CSSValue*) const;
void mapFillMaskSourceType(CSSPropertyID, FillLayer*, CSSValue*);
- void mapAnimationDelay(CSSAnimationData*, CSSValue*) const;
- void mapAnimationDirection(CSSAnimationData*, CSSValue*) const;
- void mapAnimationDuration(CSSAnimationData*, CSSValue*) const;
- void mapAnimationFillMode(CSSAnimationData*, CSSValue*) const;
- void mapAnimationIterationCount(CSSAnimationData*, CSSValue*) const;
- void mapAnimationName(CSSAnimationData*, CSSValue*) const;
- void mapAnimationPlayState(CSSAnimationData*, CSSValue*) const;
- void mapAnimationProperty(CSSAnimationData*, CSSValue*) const;
- void mapAnimationTimingFunction(CSSAnimationData*, CSSValue*) const;
+ static double mapAnimationDelay(CSSValue*);
+ static Timing::PlaybackDirection mapAnimationDirection(CSSValue*);
+ static double mapAnimationDuration(CSSValue*);
+ static Timing::FillMode mapAnimationFillMode(CSSValue*);
+ static double mapAnimationIterationCount(CSSValue*);
+ static AtomicString mapAnimationName(CSSValue*);
+ static EAnimPlayState mapAnimationPlayState(CSSValue*);
+ static CSSTransitionData::TransitionProperty mapAnimationProperty(CSSValue*);
+ static PassRefPtr<TimingFunction> mapAnimationTimingFunction(CSSValue*, bool allowStepMiddle = false);
void mapNinePieceImage(RenderStyle* mutableStyle, CSSPropertyID, CSSValue*, NinePieceImage&);
void mapNinePieceImageSlice(CSSValue*, NinePieceImage&) const;
@@ -77,7 +80,6 @@ public:
private:
const CSSToLengthConversionData& cssToLengthConversionData() const;
- bool useSVGZoomRules() const;
PassRefPtr<StyleImage> styleImage(CSSPropertyID, CSSValue*);
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.cpp
index 75a1ab10f17..9d952b4363e 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.cpp
@@ -33,12 +33,10 @@ ElementResolveContext::ElementResolveContext(Element& element)
: m_element(&element)
, m_elementLinkState(element.document().visitedLinkState().determineLinkState(element))
, m_distributedToInsertionPoint(false)
- , m_resetStyleInheritance(false)
{
NodeRenderingTraversal::ParentDetails parentDetails;
m_parentNode = NodeRenderingTraversal::parent(&element, &parentDetails);
m_distributedToInsertionPoint = parentDetails.insertionPoint();
- m_resetStyleInheritance = parentDetails.resetStyleInheritance();
const Document& document = element.document();
Node* documentElement = document.documentElement();
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.h b/chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.h
index f255e897425..f6c77bdbfc9 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ElementResolveContext.h
@@ -34,14 +34,14 @@ class RenderStyle;
// ElementResolveContext is immutable and serves as an input to the style resolve process.
class ElementResolveContext {
+ STACK_ALLOCATED();
public:
ElementResolveContext()
- : m_element(0)
- , m_parentNode(0)
+ : m_element(nullptr)
+ , m_parentNode(nullptr)
, m_rootElementStyle(0)
, m_elementLinkState(NotInsideLink)
, m_distributedToInsertionPoint(false)
- , m_resetStyleInheritance(false)
{
}
@@ -52,15 +52,13 @@ public:
const RenderStyle* rootElementStyle() const { return m_rootElementStyle; }
EInsideLink elementLinkState() const { return m_elementLinkState; }
bool distributedToInsertionPoint() const { return m_distributedToInsertionPoint; }
- bool resetStyleInheritance() const { return m_resetStyleInheritance; }
private:
- Element* m_element;
- ContainerNode* m_parentNode;
+ RawPtrWillBeMember<Element> m_element;
+ RawPtrWillBeMember<ContainerNode> m_parentNode;
RenderStyle* m_rootElementStyle;
EInsideLink m_elementLinkState;
bool m_distributedToInsertionPoint;
- bool m_resetStyleInheritance;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp
index d8b081743c9..60643ae2a8e 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.cpp
@@ -33,15 +33,14 @@
namespace WebCore {
ElementStyleResources::ElementStyleResources()
- : m_hasNewCustomFilterProgram(false)
- , m_deviceScaleFactor(1)
+ : m_deviceScaleFactor(1)
{
}
-PassRefPtr<StyleImage> ElementStyleResources::styleImage(const TextLinkColors& textLinkColors, Color currentColor, CSSPropertyID property, CSSValue* value)
+PassRefPtr<StyleImage> ElementStyleResources::styleImage(Document& document, const TextLinkColors& textLinkColors, Color currentColor, CSSPropertyID property, CSSValue* value)
{
if (value->isImageValue())
- return cachedOrPendingFromValue(property, toCSSImageValue(value));
+ return cachedOrPendingFromValue(document, property, toCSSImageValue(value));
if (value->isImageGeneratorValue()) {
if (value->isGradientValue())
@@ -55,7 +54,7 @@ PassRefPtr<StyleImage> ElementStyleResources::styleImage(const TextLinkColors& t
if (value->isCursorImageValue())
return cursorOrPendingFromValue(property, toCSSCursorImageValue(value));
- return 0;
+ return nullptr;
}
PassRefPtr<StyleImage> ElementStyleResources::generatedOrPendingFromValue(CSSPropertyID property, CSSImageGeneratorValue* value)
@@ -75,11 +74,15 @@ PassRefPtr<StyleImage> ElementStyleResources::setOrPendingFromValue(CSSPropertyI
return image.release();
}
-PassRefPtr<StyleImage> ElementStyleResources::cachedOrPendingFromValue(CSSPropertyID property, CSSImageValue* value)
+PassRefPtr<StyleImage> ElementStyleResources::cachedOrPendingFromValue(Document& document, CSSPropertyID property, CSSImageValue* value)
{
RefPtr<StyleImage> image = value->cachedOrPendingImage();
- if (image && image->isPendingImage())
- m_pendingImageProperties.set(property, value);
+ if (image) {
+ if (image->isPendingImage())
+ m_pendingImageProperties.set(property, value);
+ else
+ value->restoreCachedResourceIfNeeded(document);
+ }
return image.release();
}
@@ -91,6 +94,16 @@ PassRefPtr<StyleImage> ElementStyleResources::cursorOrPendingFromValue(CSSProper
return image.release();
}
+void ElementStyleResources::clearPendingImageProperties()
+{
+ m_pendingImageProperties.clear();
+}
+
+void ElementStyleResources::clearPendingSVGDocuments()
+{
+ m_pendingSVGDocuments.clear();
+}
+
void ElementStyleResources::addPendingSVGDocument(FilterOperation* filterOperation, CSSSVGDocumentValue* cssSVGDocumentValue)
{
m_pendingSVGDocuments.set(filterOperation, cssSVGDocumentValue);
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.h b/chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.h
index 354b022fe28..5d86c7d50f8 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ElementStyleResources.h
@@ -23,8 +23,9 @@
#ifndef ElementStyleResources_h
#define ElementStyleResources_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "platform/graphics/Color.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
@@ -40,28 +41,29 @@ class FilterOperation;
class StyleImage;
class TextLinkColors;
-typedef HashMap<FilterOperation*, RefPtr<CSSSVGDocumentValue> > PendingSVGDocumentMap;
-typedef HashMap<CSSPropertyID, RefPtr<CSSValue> > PendingImagePropertyMap;
+typedef WillBeHeapHashMap<FilterOperation*, RefPtrWillBeMember<CSSSVGDocumentValue> > PendingSVGDocumentMap;
+typedef WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<CSSValue> > PendingImagePropertyMap;
// Holds information about resources, requested by stylesheets.
// Lifetime: per-element style resolve.
class ElementStyleResources {
+STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(ElementStyleResources);
public:
ElementStyleResources();
- PassRefPtr<StyleImage> styleImage(const TextLinkColors&, Color currentColor, CSSPropertyID, CSSValue*);
+ PassRefPtr<StyleImage> styleImage(Document&, const TextLinkColors&, Color currentColor, CSSPropertyID, CSSValue*);
PassRefPtr<StyleImage> generatedOrPendingFromValue(CSSPropertyID, CSSImageGeneratorValue*);
- PassRefPtr<StyleImage> cachedOrPendingFromValue(CSSPropertyID, CSSImageValue*);
+ PassRefPtr<StyleImage> cachedOrPendingFromValue(Document&, CSSPropertyID, CSSImageValue*);
PassRefPtr<StyleImage> setOrPendingFromValue(CSSPropertyID, CSSImageSetValue*);
PassRefPtr<StyleImage> cursorOrPendingFromValue(CSSPropertyID, CSSCursorImageValue*);
const PendingImagePropertyMap& pendingImageProperties() const { return m_pendingImageProperties; }
const PendingSVGDocumentMap& pendingSVGDocuments() const { return m_pendingSVGDocuments; }
- void setHasNewCustomFilterProgram(bool hasNewCustomFilterProgram) { m_hasNewCustomFilterProgram = hasNewCustomFilterProgram; }
- bool hasNewCustomFilterProgram() const { return m_hasNewCustomFilterProgram; }
+ void clearPendingImageProperties();
+ void clearPendingSVGDocuments();
float deviceScaleFactor() const { return m_deviceScaleFactor; }
void setDeviceScaleFactor(float deviceScaleFactor) { m_deviceScaleFactor = deviceScaleFactor; }
@@ -71,7 +73,6 @@ public:
private:
PendingImagePropertyMap m_pendingImageProperties;
PendingSVGDocumentMap m_pendingSVGDocuments;
- bool m_hasNewCustomFilterProgram;
float m_deviceScaleFactor;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp
index 37706e6818d..fdb2e957ab4 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.cpp
@@ -30,23 +30,12 @@
#include "core/css/resolver/FilterOperationResolver.h"
#include "core/css/CSSFilterValue.h"
-#include "core/css/CSSMixFunctionValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSPrimitiveValueMappings.h"
-#include "core/css/CSSShaderValue.h"
#include "core/css/CSSShadowValue.h"
#include "core/css/resolver/TransformBuilder.h"
-#include "core/rendering/style/StyleCustomFilterProgram.h"
-#include "core/rendering/style/StyleShader.h"
#include "core/rendering/svg/ReferenceFilterBuilder.h"
#include "core/svg/SVGURIReference.h"
-#include "platform/graphics/filters/custom/CustomFilterArrayParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterConstants.h"
-#include "platform/graphics/filters/custom/CustomFilterNumberParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterOperation.h"
-#include "platform/graphics/filters/custom/CustomFilterParameter.h"
-#include "platform/graphics/filters/custom/CustomFilterProgramInfo.h"
-#include "platform/graphics/filters/custom/CustomFilterTransformParameter.h"
namespace WebCore {
@@ -75,277 +64,12 @@ static FilterOperation::OperationType filterOperationForType(CSSFilterValue::Fil
return FilterOperation::BLUR;
case CSSFilterValue::DropShadowFilterOperation:
return FilterOperation::DROP_SHADOW;
- case CSSFilterValue::CustomFilterOperation:
- return FilterOperation::CUSTOM;
case CSSFilterValue::UnknownFilterOperation:
return FilterOperation::NONE;
}
return FilterOperation::NONE;
}
-static StyleShader* styleShader(CSSValue* value)
-{
- if (value->isShaderValue())
- return toCSSShaderValue(value)->cachedOrPendingShader();
- return 0;
-}
-
-static PassRefPtr<CustomFilterParameter> parseCustomFilterArrayParameter(const String& name, CSSValueList* values)
-{
- RefPtr<CustomFilterArrayParameter> arrayParameter = CustomFilterArrayParameter::create(name);
- for (unsigned i = 0, length = values->length(); i < length; ++i) {
- CSSValue* value = values->itemWithoutBoundsCheck(i);
- if (!value->isPrimitiveValue())
- return 0;
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
- return 0;
- arrayParameter->addValue(primitiveValue->getDoubleValue());
- }
- return arrayParameter.release();
-}
-
-static PassRefPtr<CustomFilterParameter> parseCustomFilterNumberParameter(const String& name, CSSValueList* values)
-{
- RefPtr<CustomFilterNumberParameter> numberParameter = CustomFilterNumberParameter::create(name);
- for (unsigned i = 0; i < values->length(); ++i) {
- CSSValue* value = values->itemWithoutBoundsCheck(i);
- if (!value->isPrimitiveValue())
- return 0;
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_NUMBER)
- return 0;
- numberParameter->addValue(primitiveValue->getDoubleValue());
- }
- return numberParameter.release();
-}
-
-static PassRefPtr<CustomFilterParameter> parseCustomFilterTransformParameter(const String& name, CSSValueList* values, StyleResolverState& state)
-{
- RefPtr<CustomFilterTransformParameter> transformParameter = CustomFilterTransformParameter::create(name);
- TransformOperations operations;
- TransformBuilder::createTransformOperations(values, state.cssToLengthConversionData(), operations);
- transformParameter->setOperations(operations);
- return transformParameter.release();
-}
-
-static PassRefPtr<CustomFilterParameter> parseCustomFilterParameter(const String& name, CSSValue* parameterValue, StyleResolverState& state)
-{
- // FIXME: Implement other parameters types parsing.
- // booleans: https://bugs.webkit.org/show_bug.cgi?id=76438
- // textures: https://bugs.webkit.org/show_bug.cgi?id=71442
- // mat2, mat3, mat4: https://bugs.webkit.org/show_bug.cgi?id=71444
- // Number parameters are wrapped inside a CSSValueList and all
- // the other functions values inherit from CSSValueList.
- if (!parameterValue->isValueList())
- return 0;
-
- CSSValueList* values = toCSSValueList(parameterValue);
- if (!values->length())
- return 0;
-
- if (parameterValue->isArrayFunctionValue())
- return parseCustomFilterArrayParameter(name, values);
-
- // If the first value of the list is a transform function,
- // then we could safely assume that all the remaining items
- // are transforms. parseCustomFilterTransformParameter will
- // return 0 if that assumption is incorrect.
- if (values->itemWithoutBoundsCheck(0)->isTransformValue())
- return parseCustomFilterTransformParameter(name, values, state);
-
- // We can have only arrays of booleans or numbers, so use the first value to choose between those two.
- // We need up to 4 values (all booleans or all numbers).
- if (!values->itemWithoutBoundsCheck(0)->isPrimitiveValue() || values->length() > 4)
- return 0;
-
- CSSPrimitiveValue* firstPrimitiveValue = toCSSPrimitiveValue(values->itemWithoutBoundsCheck(0));
- if (firstPrimitiveValue->primitiveType() == CSSPrimitiveValue::CSS_NUMBER)
- return parseCustomFilterNumberParameter(name, values);
-
- // FIXME: Implement the boolean array parameter here.
- // https://bugs.webkit.org/show_bug.cgi?id=76438
-
- return 0;
-}
-
-static bool parseCustomFilterParameterList(CSSValue* parametersValue, CustomFilterParameterList& parameterList, StyleResolverState& state)
-{
- HashSet<String> knownParameterNames;
- CSSValueListIterator parameterIterator(parametersValue);
- for (; parameterIterator.hasMore(); parameterIterator.advance()) {
- if (!parameterIterator.value()->isValueList())
- return false;
- CSSValueListIterator iterator(parameterIterator.value());
- if (!iterator.isPrimitiveValue())
- return false;
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value());
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_STRING)
- return false;
-
- String name = primitiveValue->getStringValue();
- // Do not allow duplicate parameter names.
- if (!knownParameterNames.add(name).isNewEntry)
- return false;
-
- iterator.advance();
-
- if (!iterator.hasMore())
- return false;
-
- RefPtr<CustomFilterParameter> parameter = parseCustomFilterParameter(name, iterator.value(), state);
- if (!parameter)
- return false;
- parameterList.append(parameter.release());
- }
-
- // Make sure we sort the parameters before passing them down to the CustomFilterOperation.
- parameterList.sortParametersByName();
-
- return true;
-}
-
-static PassRefPtr<CustomFilterOperation> createCustomFilterOperationWithAtRuleReferenceSyntax(CSSFilterValue*)
-{
- // FIXME: Implement style resolution for the custom filter at-rule reference syntax.
- return 0;
-}
-
-static PassRefPtr<CustomFilterProgram> createCustomFilterProgram(CSSShaderValue* vertexShader, CSSShaderValue* fragmentShader,
- CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType,
- StyleResolverState& state)
-{
- ResourceFetcher* fetcher = state.document().fetcher();
- KURL vertexShaderURL = vertexShader ? vertexShader->completeURL(fetcher) : KURL();
- KURL fragmentShaderURL = fragmentShader ? fragmentShader->completeURL(fetcher) : KURL();
- // We re-resolve the custom filter style after the shaders are loaded.
- // We always create a StyleCustomFilterProgram here, and later replace it with a program from the StyleCustomFilterProgramCache, if available.
- StyleShader* styleVertexShader = vertexShader ? styleShader(vertexShader) : 0;
- StyleShader* styleFragmentShader = fragmentShader ? styleShader(fragmentShader) : 0;
- RefPtr<StyleCustomFilterProgram> program = StyleCustomFilterProgram::create(vertexShaderURL, styleVertexShader,
- fragmentShaderURL, styleFragmentShader, programType, mixSettings, meshType);
- state.elementStyleResources().setHasNewCustomFilterProgram(true);
- return program.release();
-}
-
-static PassRefPtr<CustomFilterOperation> createCustomFilterOperationWithInlineSyntax(CSSFilterValue* filterValue, StyleResolverState& state)
-{
- CSSValue* shadersValue = filterValue->itemWithoutBoundsCheck(0);
- ASSERT_WITH_SECURITY_IMPLICATION(shadersValue->isValueList());
- CSSValueList* shadersList = toCSSValueList(shadersValue);
-
- unsigned shadersListLength = shadersList->length();
- ASSERT(shadersListLength);
-
- CSSShaderValue* vertexShader = 0;
- CSSShaderValue* fragmentShader = 0;
-
- if (shadersList->itemWithoutBoundsCheck(0)->isShaderValue())
- vertexShader = toCSSShaderValue(shadersList->itemWithoutBoundsCheck(0));
-
- CustomFilterProgramType programType = ProgramTypeBlendsElementTexture;
- CustomFilterProgramMixSettings mixSettings;
-
- if (shadersListLength > 1) {
- CSSValue* fragmentShaderOrMixFunction = shadersList->itemWithoutBoundsCheck(1);
- if (fragmentShaderOrMixFunction->isMixFunctionValue()) {
- CSSMixFunctionValue* mixFunction = toCSSMixFunctionValue(fragmentShaderOrMixFunction);
- CSSValueListIterator iterator(mixFunction);
-
- ASSERT(mixFunction->length());
- if (iterator.value()->isShaderValue())
- fragmentShader = toCSSShaderValue(iterator.value());
-
- iterator.advance();
-
- ASSERT(mixFunction->length() <= 3);
- while (iterator.hasMore()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value());
- if (CSSParser::isBlendMode(primitiveValue->getValueID()))
- mixSettings.blendMode = *primitiveValue;
- else if (CSSParser::isCompositeOperator(primitiveValue->getValueID()))
- mixSettings.compositeOperator = *primitiveValue;
- else
- ASSERT_NOT_REACHED();
- iterator.advance();
- }
- } else {
- programType = ProgramTypeNoElementTexture;
- if (fragmentShaderOrMixFunction->isShaderValue())
- fragmentShader = toCSSShaderValue(fragmentShaderOrMixFunction);
- }
- }
-
- if (!vertexShader && !fragmentShader)
- return 0;
-
- unsigned meshRows = 1;
- unsigned meshColumns = 1;
- CustomFilterMeshType meshType = MeshTypeAttached;
-
- CSSValue* parametersValue = 0;
-
- if (filterValue->length() > 1) {
- CSSValueListIterator iterator(filterValue->itemWithoutBoundsCheck(1));
-
- // The second value might be the mesh box or the list of parameters:
- // If it starts with a number or any of the mesh-box identifiers it is
- // the mesh-box list, if not it means it is the parameters list.
-
- if (iterator.hasMore() && iterator.isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value());
- if (primitiveValue->isNumber()) {
- // If only one integer value is specified, it will set both
- // the rows and the columns.
- meshColumns = meshRows = primitiveValue->getIntValue();
- iterator.advance();
-
- // Try to match another number for the rows.
- if (iterator.hasMore() && iterator.isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value());
- if (primitiveValue->isNumber()) {
- meshRows = primitiveValue->getIntValue();
- iterator.advance();
- }
- }
- }
- }
-
- if (iterator.hasMore() && iterator.isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(iterator.value());
- if (primitiveValue->getValueID() == CSSValueDetached) {
- meshType = MeshTypeDetached;
- iterator.advance();
- }
- }
-
- if (!iterator.index()) {
- // If no value was consumed from the mesh value, then it is just a parameter list, meaning that we end up
- // having just two CSSListValues: list of shaders and list of parameters.
- ASSERT(filterValue->length() == 2);
- parametersValue = filterValue->itemWithoutBoundsCheck(1);
- }
- }
-
- if (filterValue->length() > 2 && !parametersValue)
- parametersValue = filterValue->itemWithoutBoundsCheck(2);
-
- CustomFilterParameterList parameterList;
- if (parametersValue && !parseCustomFilterParameterList(parametersValue, parameterList, state))
- return 0;
-
- RefPtr<CustomFilterProgram> program = createCustomFilterProgram(vertexShader, fragmentShader, programType, mixSettings, meshType, state);
- return CustomFilterOperation::create(program.release(), parameterList, meshRows, meshColumns, meshType);
-}
-
-static PassRefPtr<CustomFilterOperation> createCustomFilterOperation(CSSFilterValue* filterValue, StyleResolverState& state)
-{
- ASSERT(filterValue->length());
- bool isAtRuleReferenceSyntax = filterValue->itemWithoutBoundsCheck(0)->isPrimitiveValue();
- return isAtRuleReferenceSyntax ? createCustomFilterOperationWithAtRuleReferenceSyntax(filterValue) : createCustomFilterOperationWithInlineSyntax(filterValue, state);
-}
-
-
bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CSSToLengthConversionData& unadjustedConversionData, FilterOperations& outOperations, StyleResolverState& state)
{
ASSERT(outOperations.isEmpty());
@@ -362,7 +86,11 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
if (!inValue->isValueList())
return false;
+#ifdef BLINK_SCALE_FILTERS_AT_RECORD_TIME
float zoomFactor = unadjustedConversionData.zoom() * state.elementStyleResources().deviceScaleFactor();
+#else
+ float zoomFactor = unadjustedConversionData.zoom();
+#endif
const CSSToLengthConversionData& conversionData = unadjustedConversionData.copyWithAdjustedZoom(zoomFactor);
FilterOperations operations;
for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) {
@@ -373,19 +101,6 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
CSSFilterValue* filterValue = toCSSFilterValue(i.value());
FilterOperation::OperationType operationType = filterOperationForType(filterValue->operationType());
- if (operationType == FilterOperation::VALIDATED_CUSTOM) {
- // ValidatedCustomFilterOperation is not supposed to end up in the RenderStyle.
- ASSERT_NOT_REACHED();
- continue;
- }
- if (operationType == FilterOperation::CUSTOM) {
- RefPtr<CustomFilterOperation> operation = createCustomFilterOperation(filterValue, state);
- if (!operation)
- return false;
-
- operations.operations().append(operation);
- continue;
- }
if (operationType == FilterOperation::REFERENCE) {
if (filterValue->length() != 1)
continue;
@@ -397,7 +112,7 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
CSSSVGDocumentValue* svgDocumentValue = toCSSSVGDocumentValue(argument);
KURL url = state.document().completeURL(svgDocumentValue->url());
- RefPtr<ReferenceFilterOperation> operation = ReferenceFilterOperation::create(svgDocumentValue->url(), url.fragmentIdentifier());
+ RefPtr<ReferenceFilterOperation> operation = ReferenceFilterOperation::create(svgDocumentValue->url(), AtomicString(url.fragmentIdentifier()));
if (SVGURIReference::isExternalURIReference(svgDocumentValue->url(), state.document())) {
if (!svgDocumentValue->loadRequested())
state.elementStyleResources().addPendingSVGDocument(operation.get(), svgDocumentValue);
@@ -463,9 +178,6 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
Length stdDeviation = Length(0, Fixed);
if (filterValue->length() >= 1)
stdDeviation = firstValue->convertToLength<FixedConversion | PercentConversion>(conversionData);
- if (stdDeviation.isUndefined())
- return false;
-
operations.operations().append(BlurFilterOperation::create(stdDeviation));
break;
}
@@ -480,11 +192,11 @@ bool FilterOperationResolver::createFilterOperations(CSSValue* inValue, const CS
CSSShadowValue* item = toCSSShadowValue(cssValue);
IntPoint location(item->x->computeLength<int>(conversionData), item->y->computeLength<int>(conversionData));
int blur = item->blur ? item->blur->computeLength<int>(conversionData) : 0;
- Color shadowColor;
+ Color shadowColor = Color::transparent;
if (item->color)
shadowColor = state.document().textLinkColors().colorFromPrimitiveValue(item->color.get(), state.style()->color());
- operations.operations().append(DropShadowFilterOperation::create(location, blur, shadowColor.isValid() ? shadowColor : Color::transparent));
+ operations.operations().append(DropShadowFilterOperation::create(location, blur, shadowColor));
break;
}
case CSSFilterValue::UnknownFilterOperation:
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.h b/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.h
index 4475ce31d63..494e0d98612 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/FilterOperationResolver.h
@@ -24,6 +24,7 @@
#include "core/css/resolver/StyleResolverState.h"
#include "platform/graphics/filters/FilterOperations.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -31,8 +32,7 @@ class CSSToLengthConversionData;
class CSSValue;
class FilterOperationResolver {
-private:
- FilterOperationResolver();
+ STATIC_ONLY(FilterOperationResolver);
public:
static bool createFilterOperations(CSSValue* inValue, const CSSToLengthConversionData&, FilterOperations& outOperations, StyleResolverState&);
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp
index 57eba497510..9de7131f88c 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.cpp
@@ -27,10 +27,11 @@
#include "core/css/CSSFontFeatureValue.h"
#include "core/css/CSSToLengthConversionData.h"
#include "core/css/FontSize.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
+#include "platform/fonts/FontDescription.h"
#include "platform/text/LocaleToScriptMapping.h"
namespace WebCore {
@@ -61,23 +62,35 @@ private:
FontBuilder::FontBuilder()
: m_document(0)
- , m_useSVGZoomRules(false)
+ , m_fontSizehasViewportUnits(false)
+ , m_style(0)
, m_fontDirty(false)
{
}
-void FontBuilder::initForStyleResolve(const Document& document, RenderStyle* style, bool useSVGZoomRules)
+void FontBuilder::initForStyleResolve(const Document& document, RenderStyle* style)
{
- // All documents need to be in a frame (and thus have access to Settings)
- // for style-resolution to make sense.
- // Unfortunately SVG Animations currently violate this: crbug.com/260966
- // ASSERT(m_document->frame());
+ ASSERT(document.frame());
m_document = &document;
- m_useSVGZoomRules = useSVGZoomRules;
m_style = style;
m_fontDirty = false;
}
+inline static void setFontFamilyToStandard(FontDescription& fontDescription, const Document* document)
+{
+ if (!document || !document->settings())
+ return;
+
+ fontDescription.setGenericFamily(FontDescription::StandardFamily);
+ const AtomicString& standardFontFamily = document->settings()->genericFontFamilySettings().standard();
+ if (standardFontFamily.isEmpty())
+ return;
+
+ fontDescription.firstFamily().setFamily(standardFontFamily);
+ // FIXME: Why is this needed here?
+ fontDescription.firstFamily().appendFamily(nullptr);
+}
+
void FontBuilder::setInitial(float effectiveZoom)
{
ASSERT(m_document && m_document->settings());
@@ -87,13 +100,7 @@ void FontBuilder::setInitial(float effectiveZoom)
FontDescriptionChangeScope scope(this);
scope.reset();
- scope.fontDescription().setGenericFamily(FontDescription::StandardFamily);
- scope.fontDescription().setUsePrinterFont(m_document->printing());
- const AtomicString& standardFontFamily = m_document->settings()->genericFontFamilySettings().standard();
- if (!standardFontFamily.isEmpty()) {
- scope.fontDescription().firstFamily().setFamily(standardFontFamily);
- scope.fontDescription().firstFamily().appendFamily(0);
- }
+ setFontFamilyToStandard(scope.fontDescription(), m_document);
scope.fontDescription().setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
setSize(scope.fontDescription(), effectiveZoom, FontSize::fontSizeForKeyword(m_document, CSSValueMedium, false));
}
@@ -126,25 +133,17 @@ void FontBuilder::fromSystemFont(CSSValueID valueId, float effectiveZoom)
ASSERT(settings); // If we're doing style resolution, this document should always be in a frame and thus have settings
if (!settings)
return;
- fontDescription.setUsePrinterFont(m_document->printing());
// Handle the zoom factor.
fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, effectiveZoom, fontDescription.specifiedSize()));
scope.set(fontDescription);
}
-void FontBuilder::setFontFamilyInitial(float effectiveZoom)
+void FontBuilder::setFontFamilyInitial()
{
FontDescriptionChangeScope scope(this);
- FontDescription initialDesc = FontDescription();
-
- // We need to adjust the size to account for the generic family change from monospace to non-monospace.
- if (scope.fontDescription().keywordSize() && scope.fontDescription().useFixedDefaultSize())
- setSize(scope.fontDescription(), effectiveZoom, FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, false));
- scope.fontDescription().setGenericFamily(initialDesc.genericFamily());
- if (!initialDesc.firstFamily().familyIsEmpty())
- scope.fontDescription().setFamily(initialDesc.firstFamily());
+ setFontFamilyToStandard(scope.fontDescription(), m_document);
}
void FontBuilder::setFontFamilyInherit(const FontDescription& parentFontDescription)
@@ -153,11 +152,10 @@ void FontBuilder::setFontFamilyInherit(const FontDescription& parentFontDescript
scope.fontDescription().setGenericFamily(parentFontDescription.genericFamily());
scope.fontDescription().setFamily(parentFontDescription.family());
- scope.fontDescription().setIsSpecifiedFont(parentFontDescription.isSpecifiedFont());
}
// FIXME: I am not convinced FontBuilder needs to know anything about CSSValues.
-void FontBuilder::setFontFamilyValue(CSSValue* value, float effectiveZoom)
+void FontBuilder::setFontFamilyValue(CSSValue* value)
{
FontDescriptionChangeScope scope(this);
@@ -218,9 +216,8 @@ void FontBuilder::setFontFamilyValue(CSSValue* value, float effectiveZoom)
if (!currFamily) {
// Filling in the first family.
firstFamily.setFamily(face);
- firstFamily.appendFamily(0); // Remove any inherited family-fallback list.
+ firstFamily.appendFamily(nullptr); // Remove any inherited family-fallback list.
currFamily = &firstFamily;
- scope.fontDescription().setIsSpecifiedFont(scope.fontDescription().genericFamily() == FontDescription::NoFamily);
} else {
RefPtr<SharedFontFamily> newFamily = SharedFontFamily::create();
newFamily->setFamily(face);
@@ -236,10 +233,10 @@ void FontBuilder::setFontFamilyValue(CSSValue* value, float effectiveZoom)
return;
if (scope.fontDescription().keywordSize() && scope.fontDescription().useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize)
- setSize(scope.fontDescription(), effectiveZoom, FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, !oldFamilyUsedFixedDefaultSize));
+ scope.fontDescription().setSpecifiedSize(FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, !oldFamilyUsedFixedDefaultSize));
}
-void FontBuilder::setFontSizeInitial(float effectiveZoom)
+void FontBuilder::setFontSizeInitial()
{
FontDescriptionChangeScope scope(this);
@@ -249,10 +246,10 @@ void FontBuilder::setFontSizeInitial(float effectiveZoom)
return;
scope.fontDescription().setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
- setSize(scope.fontDescription(), effectiveZoom, size);
+ scope.fontDescription().setSpecifiedSize(size);
}
-void FontBuilder::setFontSizeInherit(const FontDescription& parentFontDescription, float effectiveZoom)
+void FontBuilder::setFontSizeInherit(const FontDescription& parentFontDescription)
{
FontDescriptionChangeScope scope(this);
@@ -262,7 +259,7 @@ void FontBuilder::setFontSizeInherit(const FontDescription& parentFontDescriptio
return;
scope.fontDescription().setKeywordSize(parentFontDescription.keywordSize());
- setSize(scope.fontDescription(), effectiveZoom, size);
+ scope.fontDescription().setSpecifiedSize(size);
}
// FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large)
@@ -278,7 +275,7 @@ static float smallerFontSize(float size)
}
// FIXME: Have to pass RenderStyles here for calc/computed values. This shouldn't be neecessary.
-void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, const RenderStyle* rootElementStyle, float effectiveZoom)
+void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, const RenderStyle* rootElementStyle)
{
if (!value->isPrimitiveValue())
return;
@@ -324,16 +321,22 @@ void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, co
scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize && (valueID == CSSValueLarger || valueID == CSSValueSmaller));
} else {
scope.fontDescription().setIsAbsoluteSize(parentIsAbsoluteSize || !(primitiveValue->isPercentage() || primitiveValue->isFontRelativeLength()));
- if (primitiveValue->isLength())
- size = primitiveValue->computeLength<float>(CSSToLengthConversionData(parentStyle, rootElementStyle, 1.0, true));
- else if (primitiveValue->isPercentage())
+ if (primitiveValue->isPercentage()) {
size = (primitiveValue->getFloatValue() * parentSize) / 100.0f;
- else if (primitiveValue->isCalculatedPercentageWithLength())
- size = primitiveValue->cssCalcValue()->toCalcValue(CSSToLengthConversionData(parentStyle, rootElementStyle, 1.0f))->evaluate(parentSize);
- else if (primitiveValue->isViewportPercentageLength())
- size = valueForLength(primitiveValue->viewportPercentageLength(), 0, m_document->renderView());
- else
- return;
+ } else {
+ // If we have viewport units the conversion will mark the parent style as having viewport units.
+ bool parentHasViewportUnits = parentStyle->hasViewportUnits();
+ parentStyle->setHasViewportUnits(false);
+ CSSToLengthConversionData conversionData(parentStyle, rootElementStyle, m_document->renderView(), 1.0f, true);
+ if (primitiveValue->isLength())
+ size = primitiveValue->computeLength<float>(conversionData);
+ else if (primitiveValue->isCalculatedPercentageWithLength())
+ size = primitiveValue->cssCalcValue()->toCalcValue(conversionData)->evaluate(parentSize);
+ else
+ ASSERT_NOT_REACHED();
+ m_fontSizehasViewportUnits = parentStyle->hasViewportUnits();
+ parentStyle->setHasViewportUnits(parentHasViewportUnits);
+ }
}
if (size < 0)
@@ -343,7 +346,8 @@ void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, co
// Cap font size here to make sure that doesn't happen.
size = std::min(maximumAllowedFontSize, size);
- setSize(scope.fontDescription(), effectiveZoom, size);
+
+ scope.fontDescription().setSpecifiedSize(size);
}
void FontBuilder::setWeight(FontWeight fontWeight)
@@ -374,6 +378,7 @@ void FontBuilder::setFontVariantLigaturesInitial()
scope.fontDescription().setCommonLigaturesState(FontDescription::NormalLigaturesState);
scope.fontDescription().setDiscretionaryLigaturesState(FontDescription::NormalLigaturesState);
scope.fontDescription().setHistoricalLigaturesState(FontDescription::NormalLigaturesState);
+ scope.fontDescription().setContextualLigaturesState(FontDescription::NormalLigaturesState);
}
void FontBuilder::setFontVariantLigaturesInherit(const FontDescription& parentFontDescription)
@@ -383,6 +388,7 @@ void FontBuilder::setFontVariantLigaturesInherit(const FontDescription& parentFo
scope.fontDescription().setCommonLigaturesState(parentFontDescription.commonLigaturesState());
scope.fontDescription().setDiscretionaryLigaturesState(parentFontDescription.discretionaryLigaturesState());
scope.fontDescription().setHistoricalLigaturesState(parentFontDescription.historicalLigaturesState());
+ scope.fontDescription().setContextualLigaturesState(parentFontDescription.historicalLigaturesState());
}
void FontBuilder::setFontVariantLigaturesValue(CSSValue* value)
@@ -392,6 +398,7 @@ void FontBuilder::setFontVariantLigaturesValue(CSSValue* value)
FontDescription::LigaturesState commonLigaturesState = FontDescription::NormalLigaturesState;
FontDescription::LigaturesState discretionaryLigaturesState = FontDescription::NormalLigaturesState;
FontDescription::LigaturesState historicalLigaturesState = FontDescription::NormalLigaturesState;
+ FontDescription::LigaturesState contextualLigaturesState = FontDescription::NormalLigaturesState;
if (value->isValueList()) {
CSSValueList* valueList = toCSSValueList(value);
@@ -419,6 +426,12 @@ void FontBuilder::setFontVariantLigaturesValue(CSSValue* value)
case CSSValueHistoricalLigatures:
historicalLigaturesState = FontDescription::EnabledLigaturesState;
break;
+ case CSSValueNoContextual:
+ contextualLigaturesState = FontDescription::DisabledLigaturesState;
+ break;
+ case CSSValueContextual:
+ contextualLigaturesState = FontDescription::EnabledLigaturesState;
+ break;
default:
ASSERT_NOT_REACHED();
break;
@@ -426,7 +439,7 @@ void FontBuilder::setFontVariantLigaturesValue(CSSValue* value)
}
}
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
else {
ASSERT_WITH_SECURITY_IMPLICATION(value->isPrimitiveValue());
ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal);
@@ -436,34 +449,36 @@ void FontBuilder::setFontVariantLigaturesValue(CSSValue* value)
scope.fontDescription().setCommonLigaturesState(commonLigaturesState);
scope.fontDescription().setDiscretionaryLigaturesState(discretionaryLigaturesState);
scope.fontDescription().setHistoricalLigaturesState(historicalLigaturesState);
+ scope.fontDescription().setContextualLigaturesState(contextualLigaturesState);
}
void FontBuilder::setScript(const String& locale)
{
FontDescriptionChangeScope scope(this);
+ scope.fontDescription().setLocale(locale);
scope.fontDescription().setScript(localeToScriptCodeForFontSelection(locale));
}
-void FontBuilder::setItalic(FontItalic italic)
+void FontBuilder::setStyle(FontStyle italic)
{
FontDescriptionChangeScope scope(this);
- scope.fontDescription().setItalic(italic);
+ scope.fontDescription().setStyle(italic);
}
-void FontBuilder::setSmallCaps(FontSmallCaps smallCaps)
+void FontBuilder::setVariant(FontVariant smallCaps)
{
FontDescriptionChangeScope scope(this);
- scope.fontDescription().setSmallCaps(smallCaps);
+ scope.fontDescription().setVariant(smallCaps);
}
-void FontBuilder::setTextRenderingMode(TextRenderingMode textRenderingMode)
+void FontBuilder::setTextRendering(TextRenderingMode textRenderingMode)
{
FontDescriptionChangeScope scope(this);
- scope.fontDescription().setTextRenderingMode(textRenderingMode);
+ scope.fontDescription().setTextRendering(textRenderingMode);
}
void FontBuilder::setKerning(FontDescription::Kerning kerning)
@@ -513,13 +528,10 @@ void FontBuilder::setSize(FontDescription& fontDescription, float effectiveZoom,
float FontBuilder::getComputedSizeFromSpecifiedSize(FontDescription& fontDescription, float effectiveZoom, float specifiedSize)
{
- float zoomFactor = 1.0f;
- if (!m_useSVGZoomRules) {
- zoomFactor = effectiveZoom;
- // FIXME: Why is this here!!!!?!
- if (Frame* frame = m_document->frame())
- zoomFactor *= frame->textZoomFactor();
- }
+ float zoomFactor = effectiveZoom;
+ // FIXME: Why is this here!!!!?!
+ if (LocalFrame* frame = m_document->frame())
+ zoomFactor *= frame->textZoomFactor();
return FontSize::getComputedSizeFromSpecifiedSize(m_document, zoomFactor, fontDescription.isAbsoluteSize(), specifiedSize);
}
@@ -614,48 +626,36 @@ void FontBuilder::checkForGenericFamilyChange(RenderStyle* style, const RenderSt
setSize(scope.fontDescription(), style->effectiveZoom(), size);
}
-void FontBuilder::checkForZoomChange(RenderStyle* style, const RenderStyle* parentStyle)
+void FontBuilder::updateComputedSize(RenderStyle* style, const RenderStyle* parentStyle)
{
FontDescriptionChangeScope scope(this);
- if (style->effectiveZoom() == parentStyle->effectiveZoom())
- return;
-
- setSize(scope.fontDescription(), style->effectiveZoom(), scope.fontDescription().specifiedSize());
+ scope.fontDescription().setComputedSize(getComputedSizeFromSpecifiedSize(scope.fontDescription(), style->effectiveZoom(), scope.fontDescription().specifiedSize()));
}
// FIXME: style param should come first
-void FontBuilder::createFont(PassRefPtr<FontSelector> fontSelector, const RenderStyle* parentStyle, RenderStyle* style)
+void FontBuilder::createFont(PassRefPtrWillBeRawPtr<FontSelector> fontSelector, const RenderStyle* parentStyle, RenderStyle* style)
{
if (!m_fontDirty)
return;
+ updateComputedSize(style, parentStyle);
checkForGenericFamilyChange(style, parentStyle);
- checkForZoomChange(style, parentStyle);
checkForOrientationChange(style);
style->font().update(fontSelector);
m_fontDirty = false;
}
-void FontBuilder::createFontForDocument(PassRefPtr<FontSelector> fontSelector, RenderStyle* documentStyle)
+void FontBuilder::createFontForDocument(PassRefPtrWillBeRawPtr<FontSelector> fontSelector, RenderStyle* documentStyle)
{
FontDescription fontDescription = FontDescription();
fontDescription.setScript(localeToScriptCodeForFontSelection(documentStyle->locale()));
- if (Settings* settings = m_document->settings()) {
- fontDescription.setUsePrinterFont(m_document->printing());
- const AtomicString& standardFont = settings->genericFontFamilySettings().standard(fontDescription.script());
- if (!standardFont.isEmpty()) {
- fontDescription.setGenericFamily(FontDescription::StandardFamily);
- fontDescription.firstFamily().setFamily(standardFont);
- fontDescription.firstFamily().appendFamily(0);
- }
- fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
- int size = FontSize::fontSizeForKeyword(m_document, CSSValueMedium, false);
- fontDescription.setSpecifiedSize(size);
- fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, documentStyle->effectiveZoom(), size));
- } else {
- fontDescription.setUsePrinterFont(m_document->printing());
- }
+
+ setFontFamilyToStandard(fontDescription, m_document);
+ fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
+ int size = FontSize::fontSizeForKeyword(m_document, CSSValueMedium, false);
+ fontDescription.setSpecifiedSize(size);
+ fontDescription.setComputedSize(getComputedSizeFromSpecifiedSize(fontDescription, documentStyle->effectiveZoom(), size));
FontOrientation fontOrientation;
NonCJKGlyphOrientation glyphOrientation;
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.h b/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.h
index b573b5159fd..2a611a01b1c 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilder.h
@@ -23,9 +23,10 @@
#ifndef FontBuilder_h
#define FontBuilder_h
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "platform/fonts/FontDescription.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
@@ -42,7 +43,7 @@ public:
FontBuilder();
// FIXME: The name is probably wrong, but matches StyleResolverState callsite for consistency.
- void initForStyleResolve(const Document&, RenderStyle*, bool useSVGZoomRules);
+ void initForStyleResolve(const Document&, RenderStyle*);
void setInitial(float effectiveZoom);
@@ -51,13 +52,13 @@ public:
void inheritFrom(const FontDescription&);
void fromSystemFont(CSSValueID, float effectiveZoom);
- void setFontFamilyInitial(float effectiveZoom);
+ void setFontFamilyInitial();
void setFontFamilyInherit(const FontDescription&);
- void setFontFamilyValue(CSSValue*, float effectiveZoom);
+ void setFontFamilyValue(CSSValue*);
- void setFontSizeInitial(float effectiveZoom);
- void setFontSizeInherit(const FontDescription&, float effectiveZoom);
- void setFontSizeValue(CSSValue*, RenderStyle* parentStyle, const RenderStyle* rootElementStyle, float effectiveZoom);
+ void setFontSizeInitial();
+ void setFontSizeInherit(const FontDescription&);
+ void setFontSizeValue(CSSValue*, RenderStyle* parentStyle, const RenderStyle* rootElementStyle);
void setWeight(FontWeight);
void setWeightBolder();
@@ -71,24 +72,34 @@ public:
void setFeatureSettingsValue(CSSValue*);
void setScript(const String& locale);
- void setItalic(FontItalic);
- void setSmallCaps(FontSmallCaps);
- void setTextRenderingMode(TextRenderingMode);
+ void setStyle(FontStyle);
+ void setVariant(FontVariant);
+ void setTextRendering(TextRenderingMode);
void setKerning(FontDescription::Kerning);
void setFontSmoothing(FontSmoothingMode);
// FIXME: These need to just vend a Font object eventually.
- void createFont(PassRefPtr<FontSelector>, const RenderStyle* parentStyle, RenderStyle*);
+ void createFont(PassRefPtrWillBeRawPtr<FontSelector>, const RenderStyle* parentStyle, RenderStyle*);
// FIXME: This is nearly static, should either made fully static or decomposed into
// FontBuilder calls at the callsite.
- void createFontForDocument(PassRefPtr<FontSelector>, RenderStyle*);
+ void createFontForDocument(PassRefPtrWillBeRawPtr<FontSelector>, RenderStyle*);
+
+ bool fontSizeHasViewportUnits() { return m_fontSizehasViewportUnits; }
// FIXME: These should not be necessary eventually.
void setFontDirty(bool fontDirty) { m_fontDirty = fontDirty; }
// FIXME: This is only used by an ASSERT in StyleResolver. Remove?
bool fontDirty() const { return m_fontDirty; }
+ static FontDescription::GenericFamilyType initialGenericFamily() { return FontDescription::NoFamily; }
+ static TextRenderingMode initialTextRendering() { return AutoTextRendering; }
+ static FontVariant initialVariant() { return FontVariantNormal; }
+ static FontStyle initialStyle() { return FontStyleNormal; }
+ static FontDescription::Kerning initialKerning() { return FontDescription::AutoKerning; }
+ static FontSmoothingMode initialFontSmoothing() { return AutoSmoothing; }
+
friend class FontDescriptionChangeScope;
+
private:
// FIXME: "size" arg should be first for consistency with other similar functions.
@@ -96,12 +107,12 @@ private:
void checkForOrientationChange(RenderStyle*);
// This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
void checkForGenericFamilyChange(RenderStyle*, const RenderStyle* parentStyle);
- void checkForZoomChange(RenderStyle*, const RenderStyle* parentStyle);
+ void updateComputedSize(RenderStyle*, const RenderStyle* parentStyle);
float getComputedSizeFromSpecifiedSize(FontDescription&, float effectiveZoom, float specifiedSize);
const Document* m_document;
- bool m_useSVGZoomRules;
+ bool m_fontSizehasViewportUnits;
// FIXME: This member is here on a short-term lease. The plan is to remove
// any notion of RenderStyle from here, allowing FontBuilder to build Font objects
// directly, rather than as a byproduct of calling RenderStyle::setFontDescription.
@@ -115,6 +126,8 @@ private:
// is changed, FontBuilder tracks the need to update
// style->font() with this bool.
bool m_fontDirty;
+
+ friend class FontBuilderTest;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilderTest.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilderTest.cpp
new file mode 100644
index 00000000000..231dc93627a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/FontBuilderTest.cpp
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/resolver/FontBuilder.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class FontBuilderTest : public ::testing::Test {
+protected:
+ RenderStyle* getStyle(const FontBuilder& builder)
+ {
+ return builder.m_style;
+ }
+};
+
+TEST_F(FontBuilderTest, StylePointerInitialisation)
+{
+ FontBuilder builder;
+ EXPECT_EQ(0, getStyle(builder));
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/MatchRequest.h b/chromium/third_party/WebKit/Source/core/css/resolver/MatchRequest.h
index df0207f4038..04c587eb623 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/MatchRequest.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/MatchRequest.h
@@ -23,6 +23,7 @@
#ifndef MatchRequest_h
#define MatchRequest_h
+#include "core/css/CSSStyleSheet.h"
#include "core/css/RuleSet.h"
namespace WebCore {
@@ -30,11 +31,13 @@ namespace WebCore {
class ContainerNode;
class MatchRequest {
+ STACK_ALLOCATED();
public:
- MatchRequest(RuleSet* ruleSet, bool includeEmptyRules = false, const ContainerNode* scope = 0, bool elementApplyAuthorStyles = true, unsigned styleSheetIndex = 0)
+ MatchRequest(RuleSet* ruleSet, bool includeEmptyRules = false, const ContainerNode* scope = 0, const CSSStyleSheet* cssSheet = 0, bool elementApplyAuthorStyles = true, unsigned styleSheetIndex = 0)
: ruleSet(ruleSet)
, includeEmptyRules(includeEmptyRules)
, scope(scope)
+ , styleSheet(cssSheet)
, elementApplyAuthorStyles(elementApplyAuthorStyles)
, styleSheetIndex(styleSheetIndex)
{
@@ -43,9 +46,10 @@ public:
ruleSet->compactRulesIfNeeded();
}
- const RuleSet* ruleSet;
+ RawPtrWillBeMember<const RuleSet> ruleSet;
const bool includeEmptyRules;
- const ContainerNode* scope;
+ RawPtrWillBeMember<const ContainerNode> scope;
+ RawPtrWillBeMember<const CSSStyleSheet> styleSheet;
const bool elementApplyAuthorStyles;
const unsigned styleSheetIndex;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/MatchResult.h b/chromium/third_party/WebKit/Source/core/css/resolver/MatchResult.h
index bbcae30bdb5..25d9b91900a 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/MatchResult.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/MatchResult.h
@@ -67,10 +67,12 @@ struct MatchedProperties {
};
};
-struct MatchResult {
+class MatchResult {
+ STACK_ALLOCATED();
+public:
MatchResult() : isCacheable(true) { }
Vector<MatchedProperties, 64> matchedProperties;
- Vector<StyleRule*, 64> matchedRules;
+ WillBeHeapVector<RawPtrWillBeMember<StyleRule>, 64> matchedRules;
MatchRanges ranges;
bool isCacheable;
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp
index d3c222a1f1e..469fa3c9c2f 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.cpp
@@ -37,7 +37,7 @@ namespace WebCore {
void CachedMatchedProperties::set(const RenderStyle* style, const RenderStyle* parentStyle, const MatchResult& matchResult)
{
- matchedProperties.append(matchResult.matchedProperties);
+ matchedProperties.appendVector(matchResult.matchedProperties);
ranges = matchResult.ranges;
// Note that we don't cache the original RenderStyle instance. It may be further modified.
@@ -49,8 +49,8 @@ void CachedMatchedProperties::set(const RenderStyle* style, const RenderStyle* p
void CachedMatchedProperties::clear()
{
matchedProperties.clear();
- renderStyle = 0;
- parentRenderStyle = 0;
+ renderStyle = nullptr;
+ parentRenderStyle = nullptr;
}
MatchedPropertiesCache::MatchedPropertiesCache()
@@ -89,15 +89,15 @@ void MatchedPropertiesCache::add(const RenderStyle* style, const RenderStyle* pa
if (++m_additionsSinceLastSweep >= maxAdditionsBetweenSweeps
&& !m_sweepTimer.isActive()) {
static const unsigned sweepTimeInSeconds = 60;
- m_sweepTimer.startOneShot(sweepTimeInSeconds);
+ m_sweepTimer.startOneShot(sweepTimeInSeconds, FROM_HERE);
}
ASSERT(hash);
Cache::AddResult addResult = m_cache.add(hash, nullptr);
if (addResult.isNewEntry)
- addResult.iterator->value = adoptPtr(new CachedMatchedProperties);
+ addResult.storedValue->value = adoptPtr(new CachedMatchedProperties);
- CachedMatchedProperties* cacheItem = addResult.iterator->value.get();
+ CachedMatchedProperties* cacheItem = addResult.storedValue->value.get();
if (!addResult.isNewEntry)
cacheItem->clear();
@@ -109,6 +109,17 @@ void MatchedPropertiesCache::clear()
m_cache.clear();
}
+void MatchedPropertiesCache::clearViewportDependent()
+{
+ Vector<unsigned, 16> toRemove;
+ for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it) {
+ CachedMatchedProperties* cacheItem = it->value.get();
+ if (cacheItem->renderStyle->hasViewportUnits())
+ toRemove.append(it->key);
+ }
+ m_cache.removeAll(toRemove);
+}
+
void MatchedPropertiesCache::sweep(Timer<MatchedPropertiesCache>*)
{
// Look for cache entries containing a style declaration with a single ref and remove them.
@@ -127,9 +138,7 @@ void MatchedPropertiesCache::sweep(Timer<MatchedPropertiesCache>*)
}
}
}
- for (size_t i = 0; i < toRemove.size(); ++i)
- m_cache.remove(toRemove[i]);
-
+ m_cache.removeAll(toRemove);
m_additionsSinceLastSweep = 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h b/chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h
index 2e5297d5acd..d86bf01f856 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/MatchedPropertiesCache.h
@@ -54,6 +54,7 @@ public:
void add(const RenderStyle*, const RenderStyle* parentStyle, unsigned hash, const MatchResult&);
void clear();
+ void clearViewportDependent();
static bool isCacheable(const Element*, const RenderStyle*, const RenderStyle* parentStyle);
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h b/chromium/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h
index 1dc00f42dc3..86adebd50d4 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/MediaQueryResult.h
@@ -29,16 +29,38 @@
namespace WebCore {
-class MediaQueryResult : public RefCounted<MediaQueryResult> {
- WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
+class MediaQueryResult : public RefCountedWillBeGarbageCollectedFinalized<MediaQueryResult> {
+ WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
MediaQueryResult(const MediaQueryExp& expr, bool result)
+#if ENABLE(OILPAN)
+ : m_expression(&expr)
+#else
: m_expression(expr)
+#endif
, m_result(result)
{
}
+ void trace(Visitor* visitor) { visitor->trace(m_expression); }
+
+ const MediaQueryExp* expression() const
+ {
+#if ENABLE(OILPAN)
+ return m_expression;
+#else
+ return &m_expression;
+#endif
+ }
+
+ bool result() const { return m_result; }
+
+private:
+#if ENABLE(OILPAN)
+ Member<const MediaQueryExp> m_expression;
+#else
MediaQueryExp m_expression;
+#endif
bool m_result;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp
index 706f5d827ab..7aea947d29f 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "core/css/resolver/ScopedStyleResolver.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/PageRuleCollector.h"
#include "core/css/RuleFeature.h"
@@ -49,38 +49,35 @@ ContainerNode* ScopedStyleResolver::scopingNodeFor(Document& document, const CSS
Document* sheetDocument = sheet->ownerDocument();
if (!sheetDocument)
return 0;
- Node* ownerNode = sheet->ownerNode();
- if (!ownerNode || !isHTMLStyleElement(ownerNode))
- return &document;
- HTMLStyleElement* styleElement = toHTMLStyleElement(ownerNode);
- if (!styleElement->scoped()) {
- if (styleElement->isInShadowTree())
- return styleElement->containingShadowRoot();
+ Node* ownerNode = sheet->ownerNode();
+ if (!isHTMLStyleElement(ownerNode))
return &document;
- }
- ContainerNode* parent = styleElement->parentNode();
- if (!parent)
- return 0;
-
- return (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0;
+ HTMLStyleElement& styleElement = toHTMLStyleElement(*ownerNode);
+ if (styleElement.isInShadowTree())
+ return styleElement.containingShadowRoot();
+ return &document;
}
-void ScopedStyleResolver::addRulesFromSheet(StyleSheetContents* sheet, const MediaQueryEvaluator& medium, StyleResolver* resolver)
+void ScopedStyleResolver::addRulesFromSheet(CSSStyleSheet* cssSheet, const MediaQueryEvaluator& medium, StyleResolver* resolver)
{
- m_authorStyleSheets.append(sheet);
+ m_authorStyleSheets.append(cssSheet);
+ StyleSheetContents* sheet = cssSheet->contents();
AddRuleFlags addRuleFlags = resolver->document().securityOrigin()->canRequest(sheet->baseURL()) ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState;
const RuleSet& ruleSet = sheet->ensureRuleSet(medium, addRuleFlags);
resolver->addMediaQueryResults(ruleSet.viewportDependentMediaQueryResults());
- resolver->processScopedRules(ruleSet, sheet->baseURL(), &m_scopingNode);
+ resolver->processScopedRules(ruleSet, cssSheet, m_scopingNode);
}
-void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features)
+void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents)
{
- for (size_t i = 0; i < m_authorStyleSheets.size(); ++i)
- features.add(m_authorStyleSheets[i]->ruleSet().features());
+ for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) {
+ StyleSheetContents* contents = m_authorStyleSheets[i]->contents();
+ if (contents->hasOneClient() || visitedSharedStyleSheetContents.add(contents).isNewEntry)
+ features.add(contents->ruleSet().features());
+ }
}
void ScopedStyleResolver::resetAuthorStyle()
@@ -89,19 +86,6 @@ void ScopedStyleResolver::resetAuthorStyle()
m_keyframesRuleMap.clear();
}
-bool ScopedStyleResolver::checkRegionStyle(Element* regionElement)
-{
- for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) {
- const RuleSet& ruleSet = m_authorStyleSheets[i]->ruleSet();
- for (unsigned i = 0; i < ruleSet.m_regionSelectorsAndRuleSets.size(); ++i) {
- ASSERT(ruleSet.m_regionSelectorsAndRuleSets.at(i).ruleSet.get());
- if (checkRegionSelector(ruleSet.m_regionSelectorsAndRuleSets.at(i).selector, regionElement))
- return true;
- }
- }
- return false;
-}
-
const StyleRuleKeyframes* ScopedStyleResolver::keyframeStylesForAnimation(const StringImpl* animationName)
{
if (m_keyframesRuleMap.isEmpty())
@@ -114,7 +98,7 @@ const StyleRuleKeyframes* ScopedStyleResolver::keyframeStylesForAnimation(const
return it->value.get();
}
-void ScopedStyleResolver::addKeyframeStyle(PassRefPtr<StyleRuleKeyframes> rule)
+void ScopedStyleResolver::addKeyframeStyle(PassRefPtrWillBeRawPtr<StyleRuleKeyframes> rule)
{
AtomicString s(rule->name());
if (rule->isVendorPrefixed()) {
@@ -136,16 +120,13 @@ void ScopedStyleResolver::collectMatchingAuthorRules(ElementRuleCollector& colle
if (!applyAuthorStyles)
behaviorAtBoundary |= SelectorChecker::ScopeContainsLastMatchedElement;
- if (m_scopingNode.isShadowRoot()) {
- scopingNode = toShadowRoot(m_scopingNode).host();
- behaviorAtBoundary |= SelectorChecker::ScopeIsShadowHost;
- }
+ if (m_scopingNode.isShadowRoot())
+ behaviorAtBoundary |= SelectorChecker::ScopeIsShadowRoot;
RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) {
- MatchRequest matchRequest(&m_authorStyleSheets[i]->ruleSet(), includeEmptyRules, scopingNode, applyAuthorStyles, i);
+ MatchRequest matchRequest(&m_authorStyleSheets[i]->contents()->ruleSet(), includeEmptyRules, scopingNode, m_authorStyleSheets[i], applyAuthorStyles, i);
collector.collectMatchingRules(matchRequest, ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(behaviorAtBoundary), cascadeScope, cascadeOrder);
- collector.collectMatchingRulesForRegion(matchRequest, ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(behaviorAtBoundary), cascadeScope, cascadeOrder);
}
}
@@ -154,7 +135,7 @@ void ScopedStyleResolver::matchPageRules(PageRuleCollector& collector)
// Only consider the global author RuleSet for @page rules, as per the HTML5 spec.
ASSERT(m_scopingNode.isDocumentNode());
for (size_t i = 0; i < m_authorStyleSheets.size(); ++i)
- collector.matchPageRules(&m_authorStyleSheets[i]->ruleSet());
+ collector.matchPageRules(&m_authorStyleSheets[i]->contents()->ruleSet());
}
void ScopedStyleResolver::collectViewportRulesTo(StyleResolver* resolver) const
@@ -162,7 +143,7 @@ void ScopedStyleResolver::collectViewportRulesTo(StyleResolver* resolver) const
if (!m_scopingNode.isDocumentNode())
return;
for (size_t i = 0; i < m_authorStyleSheets.size(); ++i)
- resolver->viewportStyleResolver()->collectViewportRules(&m_authorStyleSheets[i]->ruleSet(), ViewportStyleResolver::AuthorOrigin);
+ resolver->viewportStyleResolver()->collectViewportRules(&m_authorStyleSheets[i]->contents()->ruleSet(), ViewportStyleResolver::AuthorOrigin);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h b/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h
index 7aa1a1a18dd..64e7b7df54a 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleResolver.h
@@ -31,6 +31,7 @@
#include "core/css/RuleSet.h"
#include "core/dom/ContainerNode.h"
#include "wtf/HashMap.h"
+#include "wtf/HashSet.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
@@ -38,7 +39,6 @@ namespace WebCore {
class MediaQueryEvaluator;
class PageRuleCollector;
-class ShadowRoot;
class StyleSheetContents;
// This class selects a RenderStyle for a given element based on a collection of stylesheets.
@@ -55,28 +55,25 @@ public:
ScopedStyleResolver* parent() { return m_parent; }
public:
- bool checkRegionStyle(Element*);
const StyleRuleKeyframes* keyframeStylesForAnimation(const StringImpl* animationName);
- void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
+ void addKeyframeStyle(PassRefPtrWillBeRawPtr<StyleRuleKeyframes>);
void collectMatchingAuthorRules(ElementRuleCollector&, bool includeEmptyRules, bool applyAuthorStyles, CascadeScope, CascadeOrder = ignoreCascadeOrder);
void matchPageRules(PageRuleCollector&);
- void addRulesFromSheet(StyleSheetContents*, const MediaQueryEvaluator&, StyleResolver*);
- void collectFeaturesTo(RuleFeatureSet&);
+ void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, StyleResolver*);
+ void collectFeaturesTo(RuleFeatureSet&, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents);
void resetAuthorStyle();
void collectViewportRulesTo(StyleResolver*) const;
private:
explicit ScopedStyleResolver(ContainerNode& scopingNode) : m_scopingNode(scopingNode), m_parent(0) { }
- RuleSet* ensureAuthorStyle();
-
ContainerNode& m_scopingNode;
ScopedStyleResolver* m_parent;
- Vector<StyleSheetContents*> m_authorStyleSheets;
+ WillBePersistentHeapVector<RawPtrWillBeMember<CSSStyleSheet> > m_authorStyleSheets;
- typedef HashMap<const StringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap;
+ typedef WillBePersistentHeapHashMap<const StringImpl*, RefPtrWillBeMember<StyleRuleKeyframes> > KeyframesRuleMap;
KeyframesRuleMap m_keyframesRuleMap;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleTree.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleTree.cpp
index 729faf15e8f..3b27951217e 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleTree.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ScopedStyleTree.cpp
@@ -34,6 +34,8 @@
namespace WebCore {
+class StyleSheetContents;
+
ScopedStyleResolver* ScopedStyleTree::ensureScopedStyleResolver(ContainerNode& scopingNode)
{
bool isNewEntry;
@@ -45,8 +47,7 @@ ScopedStyleResolver* ScopedStyleTree::ensureScopedStyleResolver(ContainerNode& s
ScopedStyleResolver* ScopedStyleTree::scopedStyleResolverFor(const ContainerNode& scopingNode)
{
- if (!scopingNode.hasScopedHTMLStyleChild()
- && !isShadowHost(&scopingNode)
+ if (!isShadowHost(&scopingNode)
&& !scopingNode.isDocumentNode()
&& !scopingNode.isShadowRoot())
return 0;
@@ -58,12 +59,12 @@ ScopedStyleResolver* ScopedStyleTree::addScopedStyleResolver(ContainerNode& scop
HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::AddResult addResult = m_authorStyles.add(&scopingNode, nullptr);
if (addResult.isNewEntry) {
- addResult.iterator->value = ScopedStyleResolver::create(scopingNode);
+ addResult.storedValue->value = ScopedStyleResolver::create(scopingNode);
if (scopingNode.isDocumentNode())
- m_scopedResolverForDocument = addResult.iterator->value.get();
+ m_scopedResolverForDocument = addResult.storedValue->value.get();
}
isNewEntry = addResult.isNewEntry;
- return addResult.iterator->value.get();
+ return addResult.storedValue->value.get();
}
void ScopedStyleTree::setupScopedStylesTree(ScopedStyleResolver* target)
@@ -123,12 +124,10 @@ void ScopedStyleTree::collectScopedResolversForHostedShadowTrees(const Element*
// Adding scoped resolver for active shadow roots for shadow host styling.
for (ShadowRoot* shadowRoot = shadow->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
- if (shadowRoot->hasScopedHTMLStyleChild()) {
+ if (shadowRoot->numberOfStyles() > 0) {
if (ScopedStyleResolver* resolver = scopedStyleResolverFor(*shadowRoot))
resolvers.append(resolver);
}
- if (!shadowRoot->containsShadowElements())
- break;
}
}
@@ -138,6 +137,10 @@ void ScopedStyleTree::resolveScopedKeyframesRules(const Element* element, Vector
TreeScope& treeScope = element->treeScope();
bool applyAuthorStyles = treeScope.applyAuthorStyles();
+ // Add resolvers for shadow roots hosted by the given element.
+ collectScopedResolversForHostedShadowTrees(element, resolvers);
+
+ // Add resolvers while walking up DOM tree from the given element.
for (ScopedStyleResolver* scopedResolver = scopedResolverFor(element); scopedResolver; scopedResolver = scopedResolver->parent()) {
if (scopedResolver->treeScope() == treeScope || (applyAuthorStyles && scopedResolver->treeScope() == document))
resolvers.append(scopedResolver);
@@ -187,8 +190,9 @@ void ScopedStyleTree::popStyleCache(const ContainerNode& scopingNode)
void ScopedStyleTree::collectFeaturesTo(RuleFeatureSet& features)
{
+ HashSet<const StyleSheetContents*> visitedSharedStyleSheetContents;
for (HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator it = m_authorStyles.begin(); it != m_authorStyles.end(); ++it)
- it->value->collectFeaturesTo(features);
+ it->value->collectFeaturesTo(features, visitedSharedStyleSheetContents);
}
inline void ScopedStyleTree::reparentNodes(const ScopedStyleResolver* oldParent, ScopedStyleResolver* newParent)
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
index 92890d6c3af..4589e71bf6f 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.cpp
@@ -29,8 +29,8 @@
#include "config.h"
#include "core/css/resolver/SharedStyleFinder.h"
-#include "HTMLNames.h"
-#include "XMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/XMLNames.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/css/resolver/StyleResolverStats.h"
#include "core/dom/ContainerNode.h"
@@ -42,9 +42,11 @@
#include "core/dom/QualifiedName.h"
#include "core/dom/SpaceSplitString.h"
#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/InsertionPoint.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLOptGroupElement.h"
+#include "core/html/HTMLOptionElement.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/svg/SVGElement.h"
#include "wtf/HashSet.h"
@@ -56,7 +58,7 @@ using namespace HTMLNames;
bool SharedStyleFinder::canShareStyleWithControl(Element& candidate) const
{
- if (!candidate.hasTagName(inputTag) || !element().hasTagName(inputTag))
+ if (!isHTMLInputElement(candidate) || !isHTMLInputElement(element()))
return false;
HTMLInputElement& candidateInput = toHTMLInputElement(candidate);
@@ -100,7 +102,7 @@ bool SharedStyleFinder::classNamesAffectedByRules(const SpaceSplitString& classN
{
unsigned count = classNames.size();
for (unsigned i = 0; i < count; ++i) {
- if (m_features.classesInRules.contains(classNames[i]))
+ if (m_features.hasSelectorForClass(classNames[i]))
return true;
}
return false;
@@ -121,7 +123,7 @@ bool SharedStyleFinder::sharingCandidateHasIdenticalStyleAffectingAttributes(Ele
if (element().fastGetAttribute(langAttr) != candidate.fastGetAttribute(langAttr))
return false;
- // These two checks must be here since RuleSet has a specail case to allow style sharing between elements
+ // These two checks must be here since RuleSet has a special case to allow style sharing between elements
// with type and readonly attributes whereas other attribute selectors prevent sharing.
if (typeAttributeValue(element()) != typeAttributeValue(candidate))
return false;
@@ -149,11 +151,46 @@ bool SharedStyleFinder::sharingCandidateHasIdenticalStyleAffectingAttributes(Ele
// FIXME: Consider removing this, it's unlikely we'll have so many progress elements
// that sharing the style makes sense. Instead we should just not support style sharing
// for them.
- if (element().hasTagName(progressTag)) {
+ if (isHTMLProgressElement(element())) {
if (element().shouldAppearIndeterminate() != candidate.shouldAppearIndeterminate())
return false;
}
+ if (isHTMLOptGroupElement(element()) || isHTMLOptionElement(element())) {
+ if (element().isDisabledFormControl() != candidate.isDisabledFormControl())
+ return false;
+ if (isHTMLOptionElement(element()) && toHTMLOptionElement(element()).selected() != toHTMLOptionElement(candidate).selected())
+ return false;
+ }
+
+ return true;
+}
+
+bool SharedStyleFinder::sharingCandidateCanShareHostStyles(Element& candidate) const
+{
+ const ElementShadow* elementShadow = element().shadow();
+ const ElementShadow* candidateShadow = candidate.shadow();
+
+ if (!elementShadow && !candidateShadow)
+ return true;
+
+ if (static_cast<bool>(elementShadow) != static_cast<bool>(candidateShadow))
+ return false;
+
+ return elementShadow->hasSameStyles(candidateShadow);
+}
+
+bool SharedStyleFinder::sharingCandidateDistributedToSameInsertionPoint(Element& candidate) const
+{
+ WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints, candidateInsertionPoints;
+ collectDestinationInsertionPoints(element(), insertionPoints);
+ collectDestinationInsertionPoints(candidate, candidateInsertionPoints);
+ if (insertionPoints.size() != candidateInsertionPoints.size())
+ return false;
+ for (size_t i = 0; i < insertionPoints.size(); ++i) {
+ if (insertionPoints[i] != candidateInsertionPoints[i])
+ return false;
+ }
return true;
}
@@ -161,7 +198,7 @@ bool SharedStyleFinder::canShareStyleWithElement(Element& candidate) const
{
if (element() == candidate)
return false;
- Element* parent = candidate.parentElement();
+ Element* parent = candidate.parentOrShadowHostElement();
RenderStyle* style = candidate.renderStyle();
if (!style)
return false;
@@ -169,7 +206,7 @@ bool SharedStyleFinder::canShareStyleWithElement(Element& candidate) const
return false;
if (!parent)
return false;
- if (element().parentElement()->renderStyle() != parent->renderStyle())
+ if (element().parentOrShadowHostElement()->renderStyle() != parent->renderStyle())
return false;
if (candidate.tagQName() != element().tagQName())
return false;
@@ -181,26 +218,20 @@ bool SharedStyleFinder::canShareStyleWithElement(Element& candidate) const
return false;
if (candidate.isLink() != element().isLink())
return false;
- if (candidate.hovered() != element().hovered())
- return false;
- if (candidate.active() != element().active())
- return false;
- if (candidate.focused() != element().focused())
- return false;
if (candidate.shadowPseudoId() != element().shadowPseudoId())
return false;
- if (candidate == document().cssTarget())
- return false;
if (!sharingCandidateHasIdenticalStyleAffectingAttributes(candidate))
return false;
if (candidate.additionalPresentationAttributeStyle() != element().additionalPresentationAttributeStyle())
return false;
- if (candidate.hasID() && m_features.idsInRules.contains(candidate.idForStyleResolution()))
+ if (candidate.hasID() && m_features.hasSelectorForId(candidate.idForStyleResolution()))
return false;
- if (candidate.hasScopedHTMLStyleChild())
+ if (!sharingCandidateCanShareHostStyles(candidate))
+ return false;
+ if (!sharingCandidateDistributedToSameInsertionPoint(candidate))
+ return false;
+ if (candidate.isInTopLayer() != element().isInTopLayer())
return false;
- if (candidate.shadow() && candidate.shadow()->containsActiveStyles())
- return 0;
bool isControl = candidate.isFormControlElement();
@@ -220,16 +251,14 @@ bool SharedStyleFinder::canShareStyleWithElement(Element& candidate) const
if (candidate.isUnresolvedCustomElement() != element().isUnresolvedCustomElement())
return false;
- if (element().parentElement() != parent) {
+ if (element().parentOrShadowHostElement() != parent) {
if (!parent->isStyledElement())
return false;
- if (parent->hasScopedHTMLStyleChild())
- return false;
if (parent->inlineStyle())
return false;
if (parent->isSVGElement() && toSVGElement(parent)->animatedSMILStyleProperties())
return false;
- if (parent->hasID() && m_features.idsInRules.contains(parent->idForStyleResolution()))
+ if (parent->hasID() && m_features.hasSelectorForId(parent->idForStyleResolution()))
return false;
if (!parent->childrenSupportStyleSharing())
return false;
@@ -304,7 +333,7 @@ RenderStyle* SharedStyleFinder::findSharedStyle()
}
// Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
- if (!element().parentElement()->childrenSupportStyleSharing()) {
+ if (!element().parentElementOrShadowRoot()->childrenSupportStyleSharing()) {
INCREMENT_STYLE_STATS_COUNTER(m_styleResolver, sharedStyleRejectedByParent);
return 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.h b/chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.h
index e65c5c07cd0..5af9a95711f 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/SharedStyleFinder.h
@@ -36,6 +36,7 @@ class SpaceSplitString;
class StyleResolver;
class SharedStyleFinder {
+ STACK_ALLOCATED();
public:
// RuleSets are passed non-const as the act of matching against them can cause them
// to be compacted. :(
@@ -63,6 +64,8 @@ private:
bool canShareStyleWithElement(Element& candidate) const;
bool canShareStyleWithControl(Element& candidate) const;
bool sharingCandidateHasIdenticalStyleAffectingAttributes(Element& candidate) const;
+ bool sharingCandidateCanShareHostStyles(Element& candidate) const;
+ bool sharingCandidateDistributedToSameInsertionPoint(Element& candidate) const;
bool matchesRuleSet(RuleSet*);
Element& element() const { return *m_context.element(); }
@@ -70,8 +73,8 @@ private:
bool m_elementAffectedByClassRules;
const RuleFeatureSet& m_features;
- RuleSet* m_siblingRuleSet;
- RuleSet* m_uncommonAttributeRuleSet;
+ RawPtrWillBeMember<RuleSet> m_siblingRuleSet;
+ RawPtrWillBeMember<RuleSet> m_uncommonAttributeRuleSet;
StyleResolver& m_styleResolver;
const ElementResolveContext& m_context;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
index 4b1fe76c082..060f53f8eb0 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.cpp
@@ -29,24 +29,26 @@
#include "config.h"
#include "core/css/resolver/StyleAdjuster.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
-#include "core/html/HTMLHtmlElement.h"
+#include "core/dom/NodeRenderStyle.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/html/HTMLInputElement.h"
-#include "core/html/HTMLTableElement.h"
+#include "core/html/HTMLPlugInElement.h"
+#include "core/html/HTMLTableCellElement.h"
#include "core/html/HTMLTextAreaElement.h"
#include "core/frame/FrameView.h"
#include "core/frame/Settings.h"
-#include "core/rendering/Pagination.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/style/GridPosition.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/RenderStyleConstants.h"
+#include "core/svg/SVGSVGElement.h"
#include "platform/Length.h"
+#include "platform/transforms/TransformOperations.h"
#include "wtf/Assertions.h"
namespace WebCore {
@@ -161,63 +163,44 @@ static bool parentStyleForcesZIndexToCreateStackingContext(const RenderStyle* pa
return isDisplayFlexibleBox(parentStyle->display()) || isDisplayGridBox(parentStyle->display());
}
-void StyleAdjuster::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e)
+static bool hasWillChangeThatCreatesStackingContext(const RenderStyle* style)
{
- ASSERT(parentStyle);
-
- // Cache our original display.
- style->setOriginalDisplay(style->display());
-
- if (style->display() != NONE) {
- // If we have a <td> that specifies a float property, in quirks mode we just drop the float
- // property.
- // Sites also commonly use display:inline/block on <td>s and <table>s. In quirks mode we force
- // these tags to retain their display types.
- if (m_useQuirksModeStyles && e) {
- if (e->hasTagName(tdTag)) {
- style->setDisplay(TABLE_CELL);
- style->setFloating(NoFloat);
- } else if (isHTMLTableElement(e)) {
- style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
- }
- }
-
- if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) {
- if (style->whiteSpace() == KHTML_NOWRAP) {
- // Figure out if we are really nowrapping or if we should just
- // use normal instead. If the width of the cell is fixed, then
- // we don't actually use NOWRAP.
- if (style->width().isFixed())
- style->setWhiteSpace(NORMAL);
- else
- style->setWhiteSpace(NOWRAP);
- }
- }
-
- // Tables never support the -webkit-* values for text-align and will reset back to the default.
- if (e && isHTMLTableElement(e) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
- style->setTextAlign(TASTART);
-
- // Frames and framesets never honor position:relative or position:absolute. This is necessary to
- // fix a crash where a site tries to position these objects. They also never honor display.
- if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
- style->setPosition(StaticPosition);
- style->setDisplay(BLOCK);
- }
-
- // Ruby text does not support float or position. This might change with evolution of the specification.
- if (e && e->hasTagName(rtTag)) {
- style->setPosition(StaticPosition);
- style->setFloating(NoFloat);
+ for (size_t i = 0; i < style->willChangeProperties().size(); ++i) {
+ switch (style->willChangeProperties()[i]) {
+ case CSSPropertyOpacity:
+ case CSSPropertyTransform:
+ case CSSPropertyWebkitTransform:
+ case CSSPropertyTransformStyle:
+ case CSSPropertyWebkitTransformStyle:
+ case CSSPropertyPerspective:
+ case CSSPropertyWebkitPerspective:
+ case CSSPropertyWebkitMask:
+ case CSSPropertyWebkitMaskBoxImage:
+ case CSSPropertyWebkitClipPath:
+ case CSSPropertyWebkitBoxReflect:
+ case CSSPropertyWebkitFilter:
+ case CSSPropertyZIndex:
+ case CSSPropertyPosition:
+ return true;
+ case CSSPropertyMixBlendMode:
+ case CSSPropertyIsolation:
+ if (RuntimeEnabledFeatures::cssCompositingEnabled())
+ return true;
+ break;
+ default:
+ break;
}
+ }
+ return false;
+}
- // FIXME: We shouldn't be overriding start/-webkit-auto like this. Do it in html.css instead.
- // Table headers with a text-align of -webkit-auto will change the text-align to center.
- if (e && e->hasTagName(thTag) && style->textAlign() == TASTART)
- style->setTextAlign(CENTER);
+void StyleAdjuster::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e, const CachedUAStyle* cachedUAStyle)
+{
+ ASSERT(parentStyle);
- if (e && e->hasTagName(legendTag))
- style->setDisplay(BLOCK);
+ if (style->display() != NONE) {
+ if (e)
+ adjustStyleForTagName(style, parentStyle, *e);
// Per the spec, position 'static' and 'relative' in the top layer compute to 'absolute'.
if (isInTopLayer(e, style) && (style->position() == StaticPosition || style->position() == RelativePosition))
@@ -227,36 +210,7 @@ void StyleAdjuster::adjustRenderStyle(RenderStyle* style, RenderStyle* parentSty
if (style->hasOutOfFlowPosition() || style->isFloating() || (e && e->document().documentElement() == e))
style->setDisplay(equivalentBlockDisplay(style->display(), style->isFloating(), !m_useQuirksModeStyles));
- // FIXME: Don't support this mutation for pseudo styles like first-letter or first-line, since it's not completely
- // clear how that should work.
- if (style->display() == INLINE && style->styleType() == NOPSEUDO && style->writingMode() != parentStyle->writingMode())
- style->setDisplay(INLINE_BLOCK);
-
- // After performing the display mutation, check table rows. We do not honor position:relative or position:sticky on
- // table rows or cells. This has been established for position:relative in CSS2.1 (and caused a crash in containingBlock()
- // on some sites).
- if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP
- || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW)
- && style->hasInFlowPosition())
- style->setPosition(StaticPosition);
-
- // writing-mode does not apply to table row groups, table column groups, table rows, and table columns.
- // FIXME: Table cells should be allowed to be perpendicular or flipped with respect to the table, though.
- if (style->display() == TABLE_COLUMN || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_FOOTER_GROUP
- || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_ROW_GROUP
- || style->display() == TABLE_CELL)
- style->setWritingMode(parentStyle->writingMode());
-
- // FIXME: Since we don't support block-flow on flexible boxes yet, disallow setting
- // of block-flow to anything other than TopToBottomWritingMode.
- // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support.
- if (style->writingMode() != TopToBottomWritingMode && (style->display() == BOX || style->display() == INLINE_BOX))
- style->setWritingMode(TopToBottomWritingMode);
-
- if (isDisplayFlexibleBox(parentStyle->display()) || isDisplayGridBox(parentStyle->display())) {
- style->setFloating(NoFloat);
- style->setDisplay(equivalentBlockDisplay(style->display(), style->isFloating(), !m_useQuirksModeStyles));
- }
+ adjustStyleForDisplay(style, parentStyle);
}
// Make sure our z-index value is only applied if the object is positioned.
@@ -276,80 +230,36 @@ void StyleAdjuster::adjustRenderStyle(RenderStyle* style, RenderStyle* parentSty
|| style->hasBlendMode()
|| style->hasIsolation()
|| style->position() == StickyPosition
- || (style->position() == FixedPosition && e && e->document().settings() && e->document().settings()->fixedPositionCreatesStackingContext())
+ || style->position() == FixedPosition
|| isInTopLayer(e, style)
- || style->hasFlowFrom()
- ))
+ || hasWillChangeThatCreatesStackingContext(style)))
style->setZIndex(0);
- // Textarea considers overflow visible as auto.
- if (e && isHTMLTextAreaElement(e)) {
- style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
- style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
- }
-
- // For now, <marquee> requires an overflow clip to work properly.
- if (e && e->hasTagName(marqueeTag)) {
- style->setOverflowX(OHIDDEN);
- style->setOverflowY(OHIDDEN);
+ // will-change:transform should result in the same rendering behavior as having a transform,
+ // including the creation of a containing block for fixed position descendants.
+ if (!style->hasTransform() && (style->willChangeProperties().contains(CSSPropertyWebkitTransform) || style->willChangeProperties().contains(CSSPropertyTransform))) {
+ bool makeIdentity = true;
+ style->setTransform(TransformOperations(makeIdentity));
}
if (doesNotInheritTextDecoration(style, e))
- style->setTextDecorationsInEffect(style->textDecoration());
- else
- style->addToTextDecorationsInEffect(style->textDecoration());
+ style->clearAppliedTextDecorations();
- // If either overflow value is not visible, change to auto.
- if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE) {
- // FIXME: Once we implement pagination controls, overflow-x should default to hidden
- // if overflow-y is set to -webkit-paged-x or -webkit-page-y. For now, we'll let it
- // default to auto so we can at least scroll through the pages.
- style->setOverflowX(OAUTO);
- } else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE) {
- style->setOverflowY(OAUTO);
- }
+ style->applyTextDecorations();
- // Call setStylesForPaginationMode() if a pagination mode is set for any non-root elements. If these
- // styles are specified on a root element, then they will be incorporated in
- // StyleAdjuster::styleForDocument().
- if ((style->overflowY() == OPAGEDX || style->overflowY() == OPAGEDY) && !(e && (isHTMLHtmlElement(e) || e->hasTagName(bodyTag))))
- Pagination::setStylesForPaginationMode(WebCore::paginationModeForRenderStyle(style), style);
-
- // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
- // FIXME: Eventually table sections will support auto and scroll.
- if (style->display() == TABLE || style->display() == INLINE_TABLE
- || style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
- if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN)
- style->setOverflowX(OVISIBLE);
- if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN)
- style->setOverflowY(OVISIBLE);
- }
-
- // Menulists should have visible overflow
- if (style->appearance() == MenulistPart) {
- style->setOverflowX(OVISIBLE);
- style->setOverflowY(OVISIBLE);
- }
+ if (style->overflowX() != OVISIBLE || style->overflowY() != OVISIBLE)
+ adjustOverflow(style);
// Cull out any useless layers and also repeat patterns into additional layers.
style->adjustBackgroundLayers();
style->adjustMaskLayers();
- // Important: Intrinsic margins get added to controls before the theme has adjusted the style, since the theme will
- // alter fonts and heights/widths.
- if (e && e->isFormControlElement() && style->fontSize() >= 11) {
- // Don't apply intrinsic margins to image buttons. The designer knows how big the images are,
- // so we have to treat all image buttons as though they were explicitly sized.
- if (!e->hasTagName(inputTag) || !toHTMLInputElement(e)->isImageButton())
- addIntrinsicMargins(style);
- }
-
// Let the theme also have a crack at adjusting the style.
if (style->hasAppearance())
- RenderTheme::theme().adjustStyle(style, e, m_cachedUAStyle);
+ RenderTheme::theme().adjustStyle(style, e, cachedUAStyle);
- // If we have first-letter pseudo style, do not share this style.
- if (style->hasPseudoStyle(FIRST_LETTER))
+ // If we have first-letter pseudo style, transitions, or animations, do not share this style.
+ if (style->hasPseudoStyle(FIRST_LETTER) || style->transitions() || style->animations())
style->setUnique();
// FIXME: when dropping the -webkit prefix on transform-style, we should also have opacity < 1 cause flattening.
@@ -358,68 +268,186 @@ void StyleAdjuster::adjustRenderStyle(RenderStyle* style, RenderStyle* parentSty
|| style->hasFilter()))
style->setTransformStyle3D(TransformStyle3DFlat);
- // Seamless iframes behave like blocks. Map their display to inline-block when marked inline.
- if (e && e->hasTagName(iframeTag) && style->display() == INLINE && toHTMLIFrameElement(e)->shouldDisplaySeamlessly())
- style->setDisplay(INLINE_BLOCK);
-
- adjustGridItemPosition(style, parentStyle);
-
if (e && e->isSVGElement()) {
- // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
- if (style->overflowY() == OSCROLL)
- style->setOverflowY(OHIDDEN);
- else if (style->overflowY() == OAUTO)
- style->setOverflowY(OVISIBLE);
-
- if (style->overflowX() == OSCROLL)
- style->setOverflowX(OHIDDEN);
- else if (style->overflowX() == OAUTO)
- style->setOverflowX(OVISIBLE);
-
// Only the root <svg> element in an SVG document fragment tree honors css position
- if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
+ if (!(isSVGSVGElement(*e) && e->parentNode() && !e->parentNode()->isSVGElement()))
style->setPosition(RenderStyle::initialPosition());
- // RenderSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should
- // not be scaled again.
- if (e->hasTagName(SVGNames::foreignObjectTag))
- style->setEffectiveZoom(RenderStyle::initialZoom());
-
// SVG text layout code expects us to be a block-level style element.
- if ((e->hasTagName(SVGNames::foreignObjectTag) || e->hasTagName(SVGNames::textTag)) && style->isDisplayInlineType())
+ if ((isSVGForeignObjectElement(*e) || isSVGTextElement(*e)) && style->isDisplayInlineType())
style->setDisplay(BLOCK);
}
+
+ if (e && e->renderStyle() && e->renderStyle()->textAutosizingMultiplier() != 1) {
+ // Preserve the text autosizing multiplier on style recalc.
+ // (The autosizer will update it during layout if it needs to be changed.)
+ style->setTextAutosizingMultiplier(e->renderStyle()->textAutosizingMultiplier());
+ style->setUnique();
+ }
+}
+
+void StyleAdjuster::adjustStyleForTagName(RenderStyle* style, RenderStyle* parentStyle, Element& element)
+{
+ // <div> and <span> are the most common elements on the web, we skip all the work for them.
+ if (isHTMLDivElement(element) || isHTMLSpanElement(element))
+ return;
+
+ if (isHTMLTableCellElement(element)) {
+ // If we have a <td> that specifies a float property, in quirks mode we just drop the float property.
+ // FIXME: Why is this only <td> and not <th>?
+ if (element.hasTagName(tdTag) && m_useQuirksModeStyles) {
+ style->setDisplay(TABLE_CELL);
+ style->setFloating(NoFloat);
+ }
+ // FIXME: We shouldn't be overriding start/-webkit-auto like this. Do it in html.css instead.
+ // Table headers with a text-align of -webkit-auto will change the text-align to center.
+ if (element.hasTagName(thTag) && style->textAlign() == TASTART)
+ style->setTextAlign(CENTER);
+ if (style->whiteSpace() == KHTML_NOWRAP) {
+ // Figure out if we are really nowrapping or if we should just
+ // use normal instead. If the width of the cell is fixed, then
+ // we don't actually use NOWRAP.
+ if (style->width().isFixed())
+ style->setWhiteSpace(NORMAL);
+ else
+ style->setWhiteSpace(NOWRAP);
+ }
+ return;
+ }
+
+ if (isHTMLTableElement(element)) {
+ // Sites commonly use display:inline/block on <td>s and <table>s. In quirks mode we force
+ // these tags to retain their display types.
+ if (m_useQuirksModeStyles)
+ style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
+ // Tables never support the -webkit-* values for text-align and will reset back to the default.
+ if (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT)
+ style->setTextAlign(TASTART);
+ return;
+ }
+
+ if (isHTMLFrameElement(element) || isHTMLFrameSetElement(element)) {
+ // Frames and framesets never honor position:relative or position:absolute. This is necessary to
+ // fix a crash where a site tries to position these objects. They also never honor display.
+ style->setPosition(StaticPosition);
+ style->setDisplay(BLOCK);
+ return;
+ }
+
+ if (isHTMLRTElement(element)) {
+ // Ruby text does not support float or position. This might change with evolution of the specification.
+ style->setPosition(StaticPosition);
+ style->setFloating(NoFloat);
+ return;
+ }
+
+ if (isHTMLLegendElement(element)) {
+ style->setDisplay(BLOCK);
+ return;
+ }
+
+ if (isHTMLMarqueeElement(element)) {
+ // For now, <marquee> requires an overflow clip to work properly.
+ style->setOverflowX(OHIDDEN);
+ style->setOverflowY(OHIDDEN);
+ return;
+ }
+
+ if (element.isFormControlElement()) {
+ if (isHTMLTextAreaElement(element)) {
+ // Textarea considers overflow visible as auto.
+ style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
+ style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
+ }
+
+ // Important: Intrinsic margins get added to controls before the theme has adjusted the style,
+ // since the theme will alter fonts and heights/widths.
+ //
+ // Don't apply intrinsic margins to image buttons. The designer knows how big the images are,
+ // so we have to treat all image buttons as though they were explicitly sized.
+ if (style->fontSize() >= 11 && (!isHTMLInputElement(element) || !toHTMLInputElement(element).isImageButton()))
+ addIntrinsicMargins(style);
+ return;
+ }
+
+ if (isHTMLPlugInElement(element)) {
+ style->setRequiresAcceleratedCompositingForExternalReasons(toHTMLPlugInElement(element).shouldAccelerate());
+ return;
+ }
}
-void StyleAdjuster::adjustGridItemPosition(RenderStyle* style, RenderStyle* parentStyle) const
+void StyleAdjuster::adjustOverflow(RenderStyle* style)
{
- const GridPosition& columnStartPosition = style->gridColumnStart();
- const GridPosition& columnEndPosition = style->gridColumnEnd();
- const GridPosition& rowStartPosition = style->gridRowStart();
- const GridPosition& rowEndPosition = style->gridRowEnd();
-
- // If opposing grid-placement properties both specify a grid span, they both compute to ‘auto’.
- if (columnStartPosition.isSpan() && columnEndPosition.isSpan()) {
- style->setGridColumnStart(GridPosition());
- style->setGridColumnEnd(GridPosition());
+ ASSERT(style->overflowX() != OVISIBLE || style->overflowY() != OVISIBLE);
+
+ // If either overflow value is not visible, change to auto.
+ if (style->overflowX() == OVISIBLE && style->overflowY() != OVISIBLE) {
+ // FIXME: Once we implement pagination controls, overflow-x should default to hidden
+ // if overflow-y is set to -webkit-paged-x or -webkit-page-y. For now, we'll let it
+ // default to auto so we can at least scroll through the pages.
+ style->setOverflowX(OAUTO);
+ } else if (style->overflowY() == OVISIBLE && style->overflowX() != OVISIBLE) {
+ style->setOverflowY(OAUTO);
}
- if (rowStartPosition.isSpan() && rowEndPosition.isSpan()) {
- style->setGridRowStart(GridPosition());
- style->setGridRowEnd(GridPosition());
+ // Table rows, sections and the table itself will support overflow:hidden and will ignore scroll/auto.
+ // FIXME: Eventually table sections will support auto and scroll.
+ if (style->display() == TABLE || style->display() == INLINE_TABLE
+ || style->display() == TABLE_ROW_GROUP || style->display() == TABLE_ROW) {
+ if (style->overflowX() != OVISIBLE && style->overflowX() != OHIDDEN)
+ style->setOverflowX(OVISIBLE);
+ if (style->overflowY() != OVISIBLE && style->overflowY() != OHIDDEN)
+ style->setOverflowY(OVISIBLE);
}
- // Unknown named grid area compute to 'auto'.
- const NamedGridAreaMap& map = parentStyle->namedGridArea();
+ // Menulists should have visible overflow
+ if (style->appearance() == MenulistPart) {
+ style->setOverflowX(OVISIBLE);
+ style->setOverflowY(OVISIBLE);
+ }
+}
-#define CLEAR_UNKNOWN_NAMED_AREA(prop, Prop) \
- if (prop.isNamedGridArea() && !map.contains(prop.namedGridLine())) \
- style->setGrid##Prop(GridPosition());
+void StyleAdjuster::adjustStyleForDisplay(RenderStyle* style, RenderStyle* parentStyle)
+{
+ if (style->display() == BLOCK && !style->isFloating())
+ return;
+
+ // FIXME: Don't support this mutation for pseudo styles like first-letter or first-line, since it's not completely
+ // clear how that should work.
+ if (style->display() == INLINE && style->styleType() == NOPSEUDO && style->writingMode() != parentStyle->writingMode())
+ style->setDisplay(INLINE_BLOCK);
- CLEAR_UNKNOWN_NAMED_AREA(columnStartPosition, ColumnStart);
- CLEAR_UNKNOWN_NAMED_AREA(columnEndPosition, ColumnEnd);
- CLEAR_UNKNOWN_NAMED_AREA(rowStartPosition, RowStart);
- CLEAR_UNKNOWN_NAMED_AREA(rowEndPosition, RowEnd);
+ // After performing the display mutation, check table rows. We do not honor position: relative table rows or cells.
+ // This has been established for position: relative in CSS2.1 (and caused a crash in containingBlock()
+ // on some sites).
+ if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP
+ || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW)
+ && style->position() == RelativePosition)
+ style->setPosition(StaticPosition);
+
+ // Cannot support position: sticky for table columns and column groups because current code is only doing
+ // background painting through columns / column groups
+ if ((style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_COLUMN)
+ && style->position() == StickyPosition)
+ style->setPosition(StaticPosition);
+
+ // writing-mode does not apply to table row groups, table column groups, table rows, and table columns.
+ // FIXME: Table cells should be allowed to be perpendicular or flipped with respect to the table, though.
+ if (style->display() == TABLE_COLUMN || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_FOOTER_GROUP
+ || style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW || style->display() == TABLE_ROW_GROUP
+ || style->display() == TABLE_CELL)
+ style->setWritingMode(parentStyle->writingMode());
+
+ // FIXME: Since we don't support block-flow on flexible boxes yet, disallow setting
+ // of block-flow to anything other than TopToBottomWritingMode.
+ // https://bugs.webkit.org/show_bug.cgi?id=46418 - Flexible box support.
+ if (style->writingMode() != TopToBottomWritingMode && (style->display() == BOX || style->display() == INLINE_BOX))
+ style->setWritingMode(TopToBottomWritingMode);
+
+ if (isDisplayFlexibleBox(parentStyle->display()) || isDisplayGridBox(parentStyle->display())) {
+ style->setFloating(NoFloat);
+ style->setDisplay(equivalentBlockDisplay(style->display(), style->isFloating(), !m_useQuirksModeStyles));
+ }
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.h b/chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.h
index 96e5927bc37..b83ff9b0648 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleAdjuster.h
@@ -22,6 +22,8 @@
#ifndef StyleAdjuster_h
#define StyleAdjuster_h
+#include "platform/heap/Handle.h"
+
namespace WebCore {
class CachedUAStyle;
@@ -32,18 +34,19 @@ class RenderStyle;
// and the web expects that we expose "adjusted" values when
// for those property/element pairs.
class StyleAdjuster {
+ STACK_ALLOCATED();
public:
- StyleAdjuster(const CachedUAStyle& cachedUAStyle, bool useQuirksModeStyles)
- : m_cachedUAStyle(cachedUAStyle)
- , m_useQuirksModeStyles(useQuirksModeStyles)
+ StyleAdjuster(bool useQuirksModeStyles)
+ : m_useQuirksModeStyles(useQuirksModeStyles)
{ }
- void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*);
+ void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*, const CachedUAStyle*);
private:
- void adjustGridItemPosition(RenderStyle*, RenderStyle*) const;
+ void adjustStyleForDisplay(RenderStyle* styleToAdjust, RenderStyle* parentStyle);
+ void adjustStyleForTagName(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element&);
+ void adjustOverflow(RenderStyle* styleToAdjust);
- const CachedUAStyle& m_cachedUAStyle;
bool m_useQuirksModeStyles;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilder.h b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilder.h
index 82214e7980b..f3557a2044c 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilder.h
@@ -31,7 +31,8 @@
#ifndef StyleBuilder_h
#define StyleBuilder_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -41,16 +42,12 @@ class RenderStyle;
class StyleResolverState;
class StyleBuilder {
+ STATIC_ONLY(StyleBuilder);
public:
static void applyProperty(CSSPropertyID, StyleResolverState&, CSSValue*);
- // This function contains the gigantic old switch-statement of properties inherited from
- // StyleResolver. Each property should be migrated over to a new StyleBuilder templated
- // function and removed from this code. Once they're all moved, this function can die.
- static void oldApplyProperty(CSSPropertyID, StyleResolverState&, CSSValue*, bool isInitial, bool isInherit);
-
private:
- static bool applyProperty(CSSPropertyID, StyleResolverState&, CSSValue*, bool isInitial, bool isInherit);
+ static void applyProperty(CSSPropertyID, StyleResolverState&, CSSValue*, bool isInitial, bool isInherit);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
index d3ffb158dce..fe94e10930e 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.cpp
@@ -27,26 +27,210 @@
#include "config.h"
#include "core/css/resolver/StyleBuilderConverter.h"
+#include "core/css/CSSFunctionValue.h"
+#include "core/css/CSSGridLineNamesValue.h"
#include "core/css/CSSPrimitiveValueMappings.h"
+#include "core/css/CSSReflectValue.h"
#include "core/css/CSSShadowValue.h"
#include "core/css/Pair.h"
#include "core/svg/SVGURIReference.h"
namespace WebCore {
-String StyleBuilderConverter::convertFragmentIdentifier(StyleResolverState& state, CSSValue* value)
+namespace {
+
+static GridLength convertGridTrackBreadth(const StyleResolverState& state, CSSPrimitiveValue* primitiveValue)
+{
+ if (primitiveValue->getValueID() == CSSValueMinContent)
+ return Length(MinContent);
+
+ if (primitiveValue->getValueID() == CSSValueMaxContent)
+ return Length(MaxContent);
+
+ // Fractional unit.
+ if (primitiveValue->isFlex())
+ return GridLength(primitiveValue->getDoubleValue());
+
+ return primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
+}
+
+} // namespace
+
+PassRefPtr<StyleReflection> StyleBuilderConverter::convertBoxReflect(StyleResolverState& state, CSSValue* value)
+{
+ if (value->isPrimitiveValue()) {
+ ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
+ return RenderStyle::initialBoxReflect();
+ }
+
+ CSSReflectValue* reflectValue = toCSSReflectValue(value);
+ RefPtr<StyleReflection> reflection = StyleReflection::create();
+ reflection->setDirection(*reflectValue->direction());
+ if (reflectValue->offset())
+ reflection->setOffset(reflectValue->offset()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()));
+ NinePieceImage mask;
+ mask.setMaskDefaults();
+ state.styleMap().mapNinePieceImage(state.style(), CSSPropertyWebkitBoxReflect, reflectValue->mask(), mask);
+ reflection->setMask(mask);
+
+ return reflection.release();
+}
+
+AtomicString StyleBuilderConverter::convertFragmentIdentifier(StyleResolverState& state, CSSValue* value)
{
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
if (primitiveValue->isURI())
- return SVGURIReference::fragmentIdentifierFromIRIString(primitiveValue->getStringValue(), state.document());
- return String();
+ return SVGURIReference::fragmentIdentifierFromIRIString(primitiveValue->getStringValue(), state.element()->treeScope());
+ return nullAtom;
+}
+
+EGlyphOrientation StyleBuilderConverter::convertGlyphOrientation(StyleResolverState&, CSSValue* value)
+{
+ if (!value->isPrimitiveValue())
+ return GO_0DEG;
+
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_DEG)
+ return GO_0DEG;
+
+ float angle = fabsf(fmodf(primitiveValue->getFloatValue(), 360.0f));
+
+ if (angle <= 45.0f || angle > 315.0f)
+ return GO_0DEG;
+ if (angle > 45.0f && angle <= 135.0f)
+ return GO_90DEG;
+ if (angle > 135.0f && angle <= 225.0f)
+ return GO_180DEG;
+ return GO_270DEG;
+}
+
+GridPosition StyleBuilderConverter::convertGridPosition(StyleResolverState&, CSSValue* value)
+{
+ // We accept the specification's grammar:
+ // 'auto' | [ <integer> || <custom-ident> ] | [ span && [ <integer> || <custom-ident> ] ] | <custom-ident>
+
+ GridPosition position;
+
+ if (value->isPrimitiveValue()) {
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ // We translate <custom-ident> to <string> during parsing as it
+ // makes handling it more simple.
+ if (primitiveValue->isString()) {
+ position.setNamedGridArea(primitiveValue->getStringValue());
+ return position;
+ }
+
+ ASSERT(primitiveValue->getValueID() == CSSValueAuto);
+ return position;
+ }
+
+ CSSValueList* values = toCSSValueList(value);
+ ASSERT(values->length());
+
+ bool isSpanPosition = false;
+ // The specification makes the <integer> optional, in which case it default to '1'.
+ int gridLineNumber = 1;
+ String gridLineName;
+
+ CSSValueListIterator it = values;
+ CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value());
+ if (currentValue->getValueID() == CSSValueSpan) {
+ isSpanPosition = true;
+ it.advance();
+ currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
+ }
+
+ if (currentValue && currentValue->isNumber()) {
+ gridLineNumber = currentValue->getIntValue();
+ it.advance();
+ currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
+ }
+
+ if (currentValue && currentValue->isString()) {
+ gridLineName = currentValue->getStringValue();
+ it.advance();
+ }
+
+ ASSERT(!it.hasMore());
+ if (isSpanPosition)
+ position.setSpanPosition(gridLineNumber, gridLineName);
+ else
+ position.setExplicitPosition(gridLineNumber, gridLineName);
+
+ return position;
+}
+
+GridTrackSize StyleBuilderConverter::convertGridTrackSize(StyleResolverState& state, CSSValue* value)
+{
+ if (value->isPrimitiveValue())
+ return GridTrackSize(convertGridTrackBreadth(state, toCSSPrimitiveValue(value)));
+
+ CSSFunctionValue* minmaxFunction = toCSSFunctionValue(value);
+ CSSValueList* arguments = minmaxFunction->arguments();
+ ASSERT_WITH_SECURITY_IMPLICATION(arguments->length() == 2);
+ GridLength minTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(0))));
+ GridLength maxTrackBreadth(convertGridTrackBreadth(state, toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(1))));
+ return GridTrackSize(minTrackBreadth, maxTrackBreadth);
+}
+
+bool StyleBuilderConverter::convertGridTrackList(CSSValue* value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, StyleResolverState& state)
+{
+ // Handle 'none'.
+ if (value->isPrimitiveValue()) {
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ return primitiveValue->getValueID() == CSSValueNone;
+ }
+
+ if (!value->isValueList())
+ return false;
+
+ size_t currentNamedGridLine = 0;
+ for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
+ CSSValue* currValue = i.value();
+ if (currValue->isGridLineNamesValue()) {
+ CSSGridLineNamesValue* lineNamesValue = toCSSGridLineNamesValue(currValue);
+ for (CSSValueListIterator j = lineNamesValue; j.hasMore(); j.advance()) {
+ String namedGridLine = toCSSPrimitiveValue(j.value())->getStringValue();
+ NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>());
+ result.storedValue->value.append(currentNamedGridLine);
+ OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>());
+ orderedInsertionResult.storedValue->value.append(namedGridLine);
+ }
+ continue;
+ }
+
+ ++currentNamedGridLine;
+ trackSizes.append(convertGridTrackSize(state, currValue));
+ }
+
+ // The parser should have rejected any <track-list> without any <track-size> as
+ // this is not conformant to the syntax.
+ ASSERT(!trackSizes.isEmpty());
+ return true;
+}
+
+void StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(const NamedGridAreaMap& namedGridAreas, NamedGridLinesMap& namedGridLines, GridTrackSizingDirection direction)
+{
+ NamedGridAreaMap::const_iterator end = namedGridAreas.end();
+ for (NamedGridAreaMap::const_iterator it = namedGridAreas.begin(); it != end; ++it) {
+ GridSpan areaSpan = direction == ForRows ? it->value.rows : it->value.columns;
+ {
+ NamedGridLinesMap::AddResult startResult = namedGridLines.add(it->key + "-start", Vector<size_t>());
+ startResult.storedValue->value.append(areaSpan.resolvedInitialPosition.toInt());
+ std::sort(startResult.storedValue->value.begin(), startResult.storedValue->value.end());
+ }
+ {
+ NamedGridLinesMap::AddResult endResult = namedGridLines.add(it->key + "-end", Vector<size_t>());
+ endResult.storedValue->value.append(areaSpan.resolvedFinalPosition.toInt() + 1);
+ std::sort(endResult.storedValue->value.begin(), endResult.storedValue->value.end());
+ }
+ }
}
Length StyleBuilderConverter::convertLength(StyleResolverState& state, CSSValue* value)
{
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
- ASSERT(!result.isUndefined());
result.setQuirk(primitiveValue->isQuirkValue());
return result;
}
@@ -55,7 +239,6 @@ Length StyleBuilderConverter::convertLengthOrAuto(StyleResolverState& state, CSS
{
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
Length result = primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
- ASSERT(!result.isUndefined());
result.setQuirk(primitiveValue->isQuirkValue());
return result;
}
@@ -103,6 +286,16 @@ LengthPoint StyleBuilderConverter::convertLengthPoint(StyleResolverState& state,
return LengthPoint(x, y);
}
+LineBoxContain StyleBuilderConverter::convertLineBoxContain(StyleResolverState&, CSSValue* value)
+{
+ if (value->isPrimitiveValue()) {
+ ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
+ return LineBoxContainNone;
+ }
+
+ return toCSSLineBoxContainValue(value)->value();
+}
+
float StyleBuilderConverter::convertNumberOrPercentage(StyleResolverState& state, CSSValue* value)
{
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
@@ -112,6 +305,59 @@ float StyleBuilderConverter::convertNumberOrPercentage(StyleResolverState& state
return primitiveValue->getFloatValue() / 100.0f;
}
+EPaintOrder StyleBuilderConverter::convertPaintOrder(StyleResolverState&, CSSValue* cssPaintOrder)
+{
+ if (cssPaintOrder->isValueList()) {
+ int paintOrder = 0;
+ CSSValueListInspector iter(cssPaintOrder);
+ for (size_t i = 0; i < iter.length(); i++) {
+ CSSPrimitiveValue* value = toCSSPrimitiveValue(iter.item(i));
+
+ EPaintOrderType paintOrderType = PT_NONE;
+ switch (value->getValueID()) {
+ case CSSValueFill:
+ paintOrderType = PT_FILL;
+ break;
+ case CSSValueStroke:
+ paintOrderType = PT_STROKE;
+ break;
+ case CSSValueMarkers:
+ paintOrderType = PT_MARKERS;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+
+ paintOrder |= (paintOrderType << kPaintOrderBitwidth*i);
+ }
+ return (EPaintOrder)paintOrder;
+ }
+
+ return PO_NORMAL;
+}
+
+PassRefPtr<QuotesData> StyleBuilderConverter::convertQuotes(StyleResolverState&, CSSValue* value)
+{
+ if (value->isValueList()) {
+ CSSValueList* list = toCSSValueList(value);
+ RefPtr<QuotesData> quotes = QuotesData::create();
+ for (size_t i = 0; i < list->length(); i += 2) {
+ CSSValue* first = list->itemWithoutBoundsCheck(i);
+ // item() returns null if out of bounds so this is safe.
+ CSSValue* second = list->item(i + 1);
+ if (!second)
+ continue;
+ String startQuote = toCSSPrimitiveValue(first)->getStringValue();
+ String endQuote = toCSSPrimitiveValue(second)->getStringValue();
+ quotes->addPair(std::make_pair(startQuote, endQuote));
+ }
+ return quotes.release();
+ }
+ // FIXME: We should assert we're a primitive value with valueID = CSSValueNone
+ return QuotesData::create();
+}
+
LengthSize StyleBuilderConverter::convertRadius(StyleResolverState& state, CSSValue* value)
{
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
@@ -138,20 +384,17 @@ PassRefPtr<ShadowList> StyleBuilderConverter::convertShadow(StyleResolverState&
ShadowDataVector shadows;
for (size_t i = 0; i < shadowCount; ++i) {
const CSSShadowValue* item = toCSSShadowValue(valueList->item(i));
- int x = item->x->computeLength<int>(state.cssToLengthConversionData());
- int y = item->y->computeLength<int>(state.cssToLengthConversionData());
- int blur = item->blur ? item->blur->computeLength<int>(state.cssToLengthConversionData()) : 0;
- int spread = item->spread ? item->spread->computeLength<int>(state.cssToLengthConversionData()) : 0;
+ float x = item->x->computeLength<float>(state.cssToLengthConversionData());
+ float y = item->y->computeLength<float>(state.cssToLengthConversionData());
+ float blur = item->blur ? item->blur->computeLength<float>(state.cssToLengthConversionData()) : 0;
+ float spread = item->spread ? item->spread->computeLength<float>(state.cssToLengthConversionData()) : 0;
ShadowStyle shadowStyle = item->style && item->style->getValueID() == CSSValueInset ? Inset : Normal;
Color color;
if (item->color)
color = state.document().textLinkColors().colorFromPrimitiveValue(item->color.get(), state.style()->color());
else
color = state.style()->color();
-
- if (!color.isValid())
- color = Color::transparent;
- shadows.append(ShadowData(IntPoint(x, y), blur, spread, shadowStyle, color));
+ shadows.append(ShadowData(FloatPoint(x, y), blur, spread, shadowStyle, color));
}
return ShadowList::adopt(shadows);
}
@@ -161,14 +404,53 @@ float StyleBuilderConverter::convertSpacing(StyleResolverState& state, CSSValue*
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
if (primitiveValue->getValueID() == CSSValueNormal)
return 0;
- if (state.useSVGZoomRules())
- return primitiveValue->computeLength<float>(state.cssToLengthConversionData().copyWithAdjustedZoom(1));
return primitiveValue->computeLength<float>(state.cssToLengthConversionData());
}
-SVGLength StyleBuilderConverter::convertSVGLength(StyleResolverState&, CSSValue* value)
+PassRefPtr<SVGLengthList> StyleBuilderConverter::convertStrokeDasharray(StyleResolverState&, CSSValue* value)
+{
+ if (!value->isValueList()) {
+ return SVGRenderStyle::initialStrokeDashArray();
+ }
+
+ CSSValueList* dashes = toCSSValueList(value);
+
+ RefPtr<SVGLengthList> array = SVGLengthList::create();
+ size_t length = dashes->length();
+ for (size_t i = 0; i < length; ++i) {
+ CSSValue* currValue = dashes->itemWithoutBoundsCheck(i);
+ if (!currValue->isPrimitiveValue())
+ continue;
+
+ CSSPrimitiveValue* dash = toCSSPrimitiveValue(dashes->itemWithoutBoundsCheck(i));
+ array->append(SVGLength::fromCSSPrimitiveValue(dash));
+ }
+
+ return array.release();
+}
+
+Color StyleBuilderConverter::convertSVGColor(StyleResolverState& state, CSSValue* value)
+{
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (primitiveValue->isRGBColor())
+ return primitiveValue->getRGBA32Value();
+ ASSERT(primitiveValue->getValueID() == CSSValueCurrentcolor);
+ return state.style()->color();
+}
+
+PassRefPtr<SVGLength> StyleBuilderConverter::convertSVGLength(StyleResolverState&, CSSValue* value)
{
return SVGLength::fromCSSPrimitiveValue(toCSSPrimitiveValue(value));
}
+float StyleBuilderConverter::convertTextStrokeWidth(StyleResolverState& state, CSSValue* value)
+{
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (primitiveValue->getValueID()) {
+ float multiplier = convertLineWidth<float>(state, value);
+ return CSSPrimitiveValue::create(multiplier / 48, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(state.cssToLengthConversionData());
+ }
+ return primitiveValue->computeLength<float>(state.cssToLengthConversionData());
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
index 12f03ecfdcc..e2f92ccea97 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderConverter.h
@@ -30,7 +30,9 @@
#include "core/css/CSSValue.h"
#include "core/css/resolver/StyleResolverState.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/style/QuotesData.h"
#include "core/rendering/style/ShadowList.h"
+#include "core/rendering/style/StyleReflection.h"
#include "core/svg/SVGLength.h"
#include "platform/LengthSize.h"
@@ -40,20 +42,33 @@ namespace WebCore {
class StyleBuilderConverter {
public:
- static String convertFragmentIdentifier(StyleResolverState&, CSSValue*);
+ static PassRefPtr<StyleReflection> convertBoxReflect(StyleResolverState&, CSSValue*);
+ static AtomicString convertFragmentIdentifier(StyleResolverState&, CSSValue*);
template <typename T> static T convertComputedLength(StyleResolverState&, CSSValue*);
+ static EGlyphOrientation convertGlyphOrientation(StyleResolverState&, CSSValue*);
+ static GridPosition convertGridPosition(StyleResolverState&, CSSValue*);
+ static GridTrackSize convertGridTrackSize(StyleResolverState&, CSSValue*);
template <typename T> static T convertLineWidth(StyleResolverState&, CSSValue*);
static Length convertLength(StyleResolverState&, CSSValue*);
static Length convertLengthOrAuto(StyleResolverState&, CSSValue*);
static Length convertLengthSizing(StyleResolverState&, CSSValue*);
static Length convertLengthMaxSizing(StyleResolverState&, CSSValue*);
static LengthPoint convertLengthPoint(StyleResolverState&, CSSValue*);
+ static LineBoxContain convertLineBoxContain(StyleResolverState&, CSSValue*);
static float convertNumberOrPercentage(StyleResolverState&, CSSValue*);
+ static PassRefPtr<QuotesData> convertQuotes(StyleResolverState&, CSSValue*);
static LengthSize convertRadius(StyleResolverState&, CSSValue*);
+ static EPaintOrder convertPaintOrder(StyleResolverState&, CSSValue*);
static PassRefPtr<ShadowList> convertShadow(StyleResolverState&, CSSValue*);
static float convertSpacing(StyleResolverState&, CSSValue*);
template <CSSValueID IdForNone> static AtomicString convertString(StyleResolverState&, CSSValue*);
- static SVGLength convertSVGLength(StyleResolverState&, CSSValue*);
+ static PassRefPtr<SVGLengthList> convertStrokeDasharray(StyleResolverState&, CSSValue*);
+ static Color convertSVGColor(StyleResolverState&, CSSValue*);
+ static PassRefPtr<SVGLength> convertSVGLength(StyleResolverState&, CSSValue*);
+ static float convertTextStrokeWidth(StyleResolverState&, CSSValue*);
+
+ static bool convertGridTrackList(CSSValue*, Vector<GridTrackSize>&, NamedGridLinesMap&, OrderedNamedGridLines&, StyleResolverState&);
+ static void createImplicitNamedGridLinesFromGridArea(const NamedGridAreaMap&, NamedGridLinesMap&, GridTrackSizingDirection);
};
template <typename T>
@@ -73,8 +88,6 @@ T StyleBuilderConverter::convertLineWidth(StyleResolverState& state, CSSValue* v
return 3;
if (valueID == CSSValueThick)
return 5;
- if (primitiveValue->isViewportPercentageLength())
- return intValueForLength(primitiveValue->viewportPercentageLength(), 0, state.document().renderView());
if (valueID == CSSValueInvalid) {
// Any original result that was >= 1 should not be allowed to fall below 1.
// This keeps border lines from vanishing.
@@ -96,7 +109,7 @@ AtomicString StyleBuilderConverter::convertString(StyleResolverState&, CSSValue*
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
if (primitiveValue->getValueID() == IdForNone)
return nullAtom;
- return primitiveValue->getStringValue();
+ return AtomicString(primitiveValue->getStringValue());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
index 8f239d8cb64..c9e9af60fb0 100755..100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -37,28 +37,25 @@
*/
#include "config.h"
-#include "StyleBuilderFunctions.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "StylePropertyShorthand.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/StyleBuilderFunctions.h"
+#include "core/StylePropertyShorthand.h"
#include "core/css/BasicShapeFunctions.h"
#include "core/css/CSSAspectRatioValue.h"
#include "core/css/CSSCursorImageValue.h"
#include "core/css/CSSFontValue.h"
-#include "core/css/CSSFunctionValue.h"
#include "core/css/CSSGradientValue.h"
-#include "core/css/CSSGridLineNamesValue.h"
-#include "core/css/CSSGridTemplateValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
#include "core/css/CSSHelper.h"
#include "core/css/CSSImageSetValue.h"
#include "core/css/CSSLineBoxContainValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSProperty.h"
-#include "core/css/CSSReflectValue.h"
-#include "core/css/CSSVariableValue.h"
#include "core/css/Counter.h"
+#include "core/css/Pair.h"
#include "core/css/Rect.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRule.h"
@@ -67,18 +64,14 @@
#include "core/css/resolver/FontBuilder.h"
#include "core/css/resolver/StyleBuilder.h"
#include "core/css/resolver/TransformBuilder.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/rendering/style/CounterContent.h"
-#include "core/rendering/style/CursorList.h"
#include "core/rendering/style/QuotesData.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "core/rendering/style/SVGRenderStyle.h"
-#include "core/rendering/style/SVGRenderStyleDefs.h"
#include "core/rendering/style/StyleGeneratedImage.h"
-#include "core/svg/SVGColor.h"
-#include "core/svg/SVGPaint.h"
#include "platform/fonts/FontDescription.h"
#include "wtf/MathExtras.h"
#include "wtf/StdLibExtras.h"
@@ -86,6 +79,58 @@
namespace WebCore {
+namespace {
+
+static inline bool isValidVisitedLinkProperty(CSSPropertyID id)
+{
+ switch (id) {
+ case CSSPropertyBackgroundColor:
+ case CSSPropertyBorderLeftColor:
+ case CSSPropertyBorderRightColor:
+ case CSSPropertyBorderTopColor:
+ case CSSPropertyBorderBottomColor:
+ case CSSPropertyColor:
+ case CSSPropertyFill:
+ case CSSPropertyOutlineColor:
+ case CSSPropertyStroke:
+ case CSSPropertyTextDecorationColor:
+ case CSSPropertyWebkitColumnRuleColor:
+ case CSSPropertyWebkitTextEmphasisColor:
+ case CSSPropertyWebkitTextFillColor:
+ case CSSPropertyWebkitTextStrokeColor:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace
+
+void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value)
+{
+ ASSERT_WITH_MESSAGE(!isExpandedShorthand(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
+
+ bool isInherit = state.parentNode() && value->isInheritedValue();
+ bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue());
+
+ ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
+ ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle())
+
+ if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
+ // Limit the properties that can be applied to only the ones honored by :visited.
+ return;
+ }
+
+ CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0;
+ if (primitiveValue && primitiveValue->getValueID() == CSSValueCurrentcolor)
+ state.style()->setHasCurrentColor();
+
+ if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(id))
+ state.parentStyle()->setHasExplicitlyInheritedProperties();
+
+ StyleBuilder::applyProperty(id, state, value, isInitial, isInherit);
+}
+
static Length clipConvertToLength(StyleResolverState& state, CSSPrimitiveValue* value)
{
return value->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
@@ -108,22 +153,54 @@ void StyleBuilderFunctions::applyInheritCSSPropertyClip(StyleResolverState& stat
void StyleBuilderFunctions::applyValueCSSPropertyClip(StyleResolverState& state, CSSValue* value)
{
- if (!value->isPrimitiveValue())
- return;
-
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (Rect* rect = primitiveValue->getRectValue()) {
- Length top = clipConvertToLength(state, rect->top());
- Length right = clipConvertToLength(state, rect->right());
- Length bottom = clipConvertToLength(state, rect->bottom());
- Length left = clipConvertToLength(state, rect->left());
- state.style()->setClip(top, right, bottom, left);
- state.style()->setHasClip(true);
- } else if (primitiveValue->getValueID() == CSSValueAuto) {
+ if (primitiveValue->getValueID() == CSSValueAuto) {
state.style()->setClip(Length(), Length(), Length(), Length());
state.style()->setHasClip(false);
+ return;
+ }
+
+ Rect* rect = primitiveValue->getRectValue();
+ Length top = clipConvertToLength(state, rect->top());
+ Length right = clipConvertToLength(state, rect->right());
+ Length bottom = clipConvertToLength(state, rect->bottom());
+ Length left = clipConvertToLength(state, rect->left());
+ state.style()->setClip(top, right, bottom, left);
+ state.style()->setHasClip(true);
+}
+
+void StyleBuilderFunctions::applyInitialCSSPropertyColor(StyleResolverState& state)
+{
+ Color color = RenderStyle::initialColor();
+ if (state.applyPropertyToRegularStyle())
+ state.style()->setColor(color);
+ if (state.applyPropertyToVisitedLinkStyle())
+ state.style()->setVisitedLinkColor(color);
+}
+
+void StyleBuilderFunctions::applyInheritCSSPropertyColor(StyleResolverState& state)
+{
+ Color color = state.parentStyle()->color();
+ if (state.applyPropertyToRegularStyle())
+ state.style()->setColor(color);
+ if (state.applyPropertyToVisitedLinkStyle())
+ state.style()->setVisitedLinkColor(color);
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyColor(StyleResolverState& state, CSSValue* value)
+{
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ // As per the spec, 'color: currentColor' is treated as 'color: inherit'
+ if (primitiveValue->getValueID() == CSSValueCurrentcolor) {
+ applyInheritCSSPropertyColor(state);
+ return;
}
+
+ if (state.applyPropertyToRegularStyle())
+ state.style()->setColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color()));
+ if (state.applyPropertyToVisitedLinkStyle())
+ state.style()->setVisitedLinkColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color(), true));
}
void StyleBuilderFunctions::applyInitialCSSPropertyCursor(StyleResolverState& state)
@@ -152,16 +229,12 @@ void StyleBuilderFunctions::applyValueCSSPropertyCursor(StyleResolverState& stat
if (image->updateIfSVGCursorIsUsed(state.element())) // Elements with SVG cursors are not allowed to share style.
state.style()->setUnique();
state.style()->addCursor(state.styleImage(CSSPropertyCursor, image), image->hotSpot());
- } else if (item->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(item);
- if (primitiveValue->isValueID())
- state.style()->setCursor(*primitiveValue);
+ } else {
+ state.style()->setCursor(*toCSSPrimitiveValue(item));
}
}
- } else if (value->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (primitiveValue->isValueID() && state.style()->cursor() != ECursor(*primitiveValue))
- state.style()->setCursor(*primitiveValue);
+ } else {
+ state.style()->setCursor(*toCSSPrimitiveValue(value));
}
}
@@ -190,20 +263,15 @@ void StyleBuilderFunctions::applyInheritCSSPropertyDisplay(StyleResolverState& s
void StyleBuilderFunctions::applyValueCSSPropertyDisplay(StyleResolverState& state, CSSValue* value)
{
- if (!value->isPrimitiveValue())
- return;
-
EDisplay display = *toCSSPrimitiveValue(value);
-
if (!isValidDisplayValue(state, display))
return;
-
state.style()->setDisplay(display);
}
void StyleBuilderFunctions::applyInitialCSSPropertyFontFamily(StyleResolverState& state)
{
- state.fontBuilder().setFontFamilyInitial(state.style()->effectiveZoom());
+ state.fontBuilder().setFontFamilyInitial();
}
void StyleBuilderFunctions::applyInheritCSSPropertyFontFamily(StyleResolverState& state)
@@ -213,22 +281,22 @@ void StyleBuilderFunctions::applyInheritCSSPropertyFontFamily(StyleResolverState
void StyleBuilderFunctions::applyValueCSSPropertyFontFamily(StyleResolverState& state, CSSValue* value)
{
- state.fontBuilder().setFontFamilyValue(value, state.style()->effectiveZoom());
+ state.fontBuilder().setFontFamilyValue(value);
}
void StyleBuilderFunctions::applyInitialCSSPropertyFontSize(StyleResolverState& state)
{
- state.fontBuilder().setFontSizeInitial(state.style()->effectiveZoom());
+ state.fontBuilder().setFontSizeInitial();
}
void StyleBuilderFunctions::applyInheritCSSPropertyFontSize(StyleResolverState& state)
{
- state.fontBuilder().setFontSizeInherit(state.parentFontDescription(), state.style()->effectiveZoom());
+ state.fontBuilder().setFontSizeInherit(state.parentFontDescription());
}
void StyleBuilderFunctions::applyValueCSSPropertyFontSize(StyleResolverState& state, CSSValue* value)
{
- state.fontBuilder().setFontSizeValue(value, state.parentStyle(), state.rootElementStyle(), state.style()->effectiveZoom());
+ state.fontBuilder().setFontSizeValue(value, state.parentStyle(), state.rootElementStyle());
}
void StyleBuilderFunctions::applyInitialCSSPropertyFontWeight(StyleResolverState& state)
@@ -243,17 +311,17 @@ void StyleBuilderFunctions::applyInheritCSSPropertyFontWeight(StyleResolverState
void StyleBuilderFunctions::applyValueCSSPropertyFontWeight(StyleResolverState& state, CSSValue* value)
{
- if (!value->isPrimitiveValue())
- return;
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
switch (primitiveValue->getValueID()) {
case CSSValueInvalid:
ASSERT_NOT_REACHED();
break;
case CSSValueBolder:
+ state.fontBuilder().setWeight(state.parentStyle()->fontDescription().weight());
state.fontBuilder().setWeightBolder();
break;
case CSSValueLighter:
+ state.fontBuilder().setWeight(state.parentStyle()->fontDescription().weight());
state.fontBuilder().setWeightLighter();
break;
default:
@@ -261,11 +329,53 @@ void StyleBuilderFunctions::applyValueCSSPropertyFontWeight(StyleResolverState&
}
}
-void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState& state, CSSValue* value)
+void StyleBuilderFunctions::applyValueCSSPropertyGlyphOrientationVertical(StyleResolverState& state, CSSValue* value)
{
- if (!value->isPrimitiveValue())
+ if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueAuto)
+ state.style()->accessSVGStyle()->setGlyphOrientationVertical(GO_AUTO);
+ else
+ state.style()->accessSVGStyle()->setGlyphOrientationVertical(StyleBuilderConverter::convertGlyphOrientation(state, value));
+}
+
+void StyleBuilderFunctions::applyInitialCSSPropertyGridTemplateAreas(StyleResolverState& state)
+{
+ state.style()->setNamedGridArea(RenderStyle::initialNamedGridArea());
+ state.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount());
+ state.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount());
+}
+
+void StyleBuilderFunctions::applyInheritCSSPropertyGridTemplateAreas(StyleResolverState& state)
+{
+ state.style()->setNamedGridArea(state.parentStyle()->namedGridArea());
+ state.style()->setNamedGridAreaRowCount(state.parentStyle()->namedGridAreaRowCount());
+ state.style()->setNamedGridAreaColumnCount(state.parentStyle()->namedGridAreaColumnCount());
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyGridTemplateAreas(StyleResolverState& state, CSSValue* value)
+{
+ if (value->isPrimitiveValue()) {
+ // FIXME: Shouldn't we clear the grid-area values
+ ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
return;
+ }
+ CSSGridTemplateAreasValue* gridTemplateAreasValue = toCSSGridTemplateAreasValue(value);
+ const NamedGridAreaMap& newNamedGridAreas = gridTemplateAreasValue->gridAreaMap();
+
+ NamedGridLinesMap namedGridColumnLines = state.style()->namedGridColumnLines();
+ NamedGridLinesMap namedGridRowLines = state.style()->namedGridRowLines();
+ StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridColumnLines, ForColumns);
+ StyleBuilderConverter::createImplicitNamedGridLinesFromGridArea(newNamedGridAreas, namedGridRowLines, ForRows);
+ state.style()->setNamedGridColumnLines(namedGridColumnLines);
+ state.style()->setNamedGridRowLines(namedGridRowLines);
+
+ state.style()->setNamedGridArea(newNamedGridAreas);
+ state.style()->setNamedGridAreaRowCount(gridTemplateAreasValue->rowCount());
+ state.style()->setNamedGridAreaColumnCount(gridTemplateAreasValue->columnCount());
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState& state, CSSValue* value)
+{
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
Length lineHeight;
@@ -273,18 +383,16 @@ void StyleBuilderFunctions::applyValueCSSPropertyLineHeight(StyleResolverState&
lineHeight = RenderStyle::initialLineHeight();
} else if (primitiveValue->isLength()) {
float multiplier = state.style()->effectiveZoom();
- if (Frame* frame = state.document().frame())
+ if (LocalFrame* frame = state.document().frame())
multiplier *= frame->textZoomFactor();
lineHeight = primitiveValue->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier));
} else if (primitiveValue->isPercentage()) {
lineHeight = Length((state.style()->computedFontSize() * primitiveValue->getIntValue()) / 100.0, Fixed);
} else if (primitiveValue->isNumber()) {
lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
- } else if (primitiveValue->isViewportPercentageLength()) {
- lineHeight = primitiveValue->viewportPercentageLength();
} else if (primitiveValue->isCalculated()) {
double multiplier = state.style()->effectiveZoom();
- if (Frame* frame = state.document().frame())
+ if (LocalFrame* frame = state.document().frame())
multiplier *= frame->textZoomFactor();
Length zoomedLength = Length(primitiveValue->cssCalcValue()->toCalcValue(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier)));
lineHeight = Length(valueForLength(zoomedLength, state.style()->fontSize()), Fixed);
@@ -320,20 +428,13 @@ void StyleBuilderFunctions::applyValueCSSPropertyOutlineStyle(StyleResolverState
void StyleBuilderFunctions::applyValueCSSPropertyResize(StyleResolverState& state, CSSValue* value)
{
- if (!value->isPrimitiveValue())
- return;
-
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
EResize r = RESIZE_NONE;
- switch (primitiveValue->getValueID()) {
- case 0:
- return;
- case CSSValueAuto:
+ if (primitiveValue->getValueID() == CSSValueAuto) {
if (Settings* settings = state.document().settings())
r = settings->textAreasAreResizable() ? RESIZE_BOTH : RESIZE_NONE;
- break;
- default:
+ } else {
r = *primitiveValue;
}
state.style()->setResize(r);
@@ -439,7 +540,7 @@ void StyleBuilderFunctions::applyValueCSSPropertySize(StyleResolverState& state,
height = second->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(1.0));
} else {
// <page-size> <orientation>
- // The value order is guaranteed. See CSSParser::parseSizeParameter.
+ // The value order is guaranteed. See BisonCSSParser::parseSizeParameter.
if (!getPageSizeFromName(first, second, width, height))
return;
}
@@ -519,12 +620,14 @@ void StyleBuilderFunctions::applyInheritCSSPropertyTextIndent(StyleResolverState
{
state.style()->setTextIndent(state.parentStyle()->textIndent());
state.style()->setTextIndentLine(state.parentStyle()->textIndentLine());
+ state.style()->setTextIndentType(state.parentStyle()->textIndentType());
}
void StyleBuilderFunctions::applyInitialCSSPropertyTextIndent(StyleResolverState& state)
{
state.style()->setTextIndent(RenderStyle::initialTextIndent());
state.style()->setTextIndentLine(RenderStyle::initialTextIndentLine());
+ state.style()->setTextIndentType(RenderStyle::initialTextIndentType());
}
void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState& state, CSSValue* value)
@@ -532,23 +635,155 @@ void StyleBuilderFunctions::applyValueCSSPropertyTextIndent(StyleResolverState&
if (!value->isValueList())
return;
- // [ <length> | <percentage> ] each-line
- // The order is guaranteed. See CSSParser::parseTextIndent.
- // The second value, each-line is handled only when css3TextEnabled() returns true.
+ Length lengthOrPercentageValue;
+ TextIndentLine textIndentLineValue = RenderStyle::initialTextIndentLine();
+ TextIndentType textIndentTypeValue = RenderStyle::initialTextIndentType();
+
+ for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value());
+ if (!primitiveValue->getValueID())
+ lengthOrPercentageValue = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
+ else if (primitiveValue->getValueID() == CSSValueEachLine)
+ textIndentLineValue = TextIndentEachLine;
+ else if (primitiveValue->getValueID() == CSSValueHanging)
+ textIndentTypeValue = TextIndentHanging;
+ else
+ ASSERT_NOT_REACHED();
+ }
- CSSValueList* valueList = toCSSValueList(value);
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(valueList->itemWithoutBoundsCheck(0));
- Length lengthOrPercentageValue = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
- ASSERT(!lengthOrPercentageValue.isUndefined());
state.style()->setTextIndent(lengthOrPercentageValue);
+ state.style()->setTextIndentLine(textIndentLineValue);
+ state.style()->setTextIndentType(textIndentTypeValue);
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyTransform(StyleResolverState& state, CSSValue* value)
+{
+ TransformOperations operations;
+ TransformBuilder::createTransformOperations(value, state.cssToLengthConversionData(), operations);
+ state.style()->setTransform(operations);
+}
+
+void StyleBuilderFunctions::applyInitialCSSPropertyTransformOrigin(StyleResolverState& state)
+{
+ applyInitialCSSPropertyWebkitTransformOriginX(state);
+ applyInitialCSSPropertyWebkitTransformOriginY(state);
+ applyInitialCSSPropertyWebkitTransformOriginZ(state);
+}
+
+void StyleBuilderFunctions::applyInheritCSSPropertyTransformOrigin(StyleResolverState& state)
+{
+ applyInheritCSSPropertyWebkitTransformOriginX(state);
+ applyInheritCSSPropertyWebkitTransformOriginY(state);
+ applyInheritCSSPropertyWebkitTransformOriginZ(state);
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyTransformOrigin(StyleResolverState& state, CSSValue* value)
+{
+ CSSValueList* list = toCSSValueList(value);
+ ASSERT(list->length() == 3);
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
+ if (primitiveValue->isValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueLeft:
+ state.style()->setTransformOriginX(Length(0, Percent));
+ break;
+ case CSSValueRight:
+ state.style()->setTransformOriginX(Length(100, Percent));
+ break;
+ case CSSValueCenter:
+ state.style()->setTransformOriginX(Length(50, Percent));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ state.style()->setTransformOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
+ }
+
+ primitiveValue = toCSSPrimitiveValue(list->item(1));
+ if (primitiveValue->isValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueTop:
+ state.style()->setTransformOriginY(Length(0, Percent));
+ break;
+ case CSSValueBottom:
+ state.style()->setTransformOriginY(Length(100, Percent));
+ break;
+ case CSSValueCenter:
+ state.style()->setTransformOriginY(Length(50, Percent));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ state.style()->setTransformOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
+ }
+
+ primitiveValue = toCSSPrimitiveValue(list->item(2));
+ state.style()->setTransformOriginZ(StyleBuilderConverter::convertComputedLength<float>(state, primitiveValue));
+}
+
+void StyleBuilderFunctions::applyInitialCSSPropertyPerspectiveOrigin(StyleResolverState& state)
+{
+ applyInitialCSSPropertyWebkitPerspectiveOriginX(state);
+ applyInitialCSSPropertyWebkitPerspectiveOriginY(state);
+}
- ASSERT(valueList->length() <= 2);
- CSSPrimitiveValue* eachLineValue = toCSSPrimitiveValue(valueList->item(1));
- if (eachLineValue) {
- ASSERT(eachLineValue->getValueID() == CSSValueEachLine);
- state.style()->setTextIndentLine(TextIndentEachLine);
- } else
- state.style()->setTextIndentLine(TextIndentFirstLine);
+void StyleBuilderFunctions::applyInheritCSSPropertyPerspectiveOrigin(StyleResolverState& state)
+{
+ applyInheritCSSPropertyWebkitPerspectiveOriginX(state);
+ applyInheritCSSPropertyWebkitPerspectiveOriginY(state);
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyPerspectiveOrigin(StyleResolverState& state, CSSValue* value)
+{
+ CSSValueList* list = toCSSValueList(value);
+ ASSERT(list->length() == 2);
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(list->item(0));
+ if (primitiveValue->isValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueLeft:
+ state.style()->setPerspectiveOriginX(Length(0, Percent));
+ break;
+ case CSSValueRight:
+ state.style()->setPerspectiveOriginX(Length(100, Percent));
+ break;
+ case CSSValueCenter:
+ state.style()->setPerspectiveOriginX(Length(50, Percent));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ state.style()->setPerspectiveOriginX(StyleBuilderConverter::convertLength(state, primitiveValue));
+ }
+
+ primitiveValue = toCSSPrimitiveValue(list->item(1));
+ if (primitiveValue->isValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueTop:
+ state.style()->setPerspectiveOriginY(Length(0, Percent));
+ break;
+ case CSSValueBottom:
+ state.style()->setPerspectiveOriginY(Length(100, Percent));
+ break;
+ case CSSValueCenter:
+ state.style()->setPerspectiveOriginY(Length(50, Percent));
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ } else {
+ state.style()->setPerspectiveOriginY(StyleBuilderConverter::convertLength(state, primitiveValue));
+ }
+}
+
+void StyleBuilderFunctions::applyInheritCSSPropertyVerticalAlign(StyleResolverState& state)
+{
+ EVerticalAlign verticalAlign = state.parentStyle()->verticalAlign();
+ state.style()->setVerticalAlign(verticalAlign);
+ if (verticalAlign == LENGTH)
+ state.style()->setVerticalAlignLength(state.parentStyle()->verticalAlignLength());
}
void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverState& state, CSSValue* value)
@@ -558,8 +793,10 @@ void StyleBuilderFunctions::applyValueCSSPropertyVerticalAlign(StyleResolverStat
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- if (primitiveValue->getValueID())
- return state.style()->setVerticalAlign(*primitiveValue);
+ if (primitiveValue->getValueID()) {
+ state.style()->setVerticalAlign(*primitiveValue);
+ return;
+ }
state.style()->setVerticalAlignLength(primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()));
}
@@ -657,29 +894,36 @@ void StyleBuilderFunctions::applyValueCSSPropertyWebkitClipPath(StyleResolverSta
if (value->isPrimitiveValue()) {
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
if (primitiveValue->getValueID() == CSSValueNone) {
- state.style()->setClipPath(0);
+ state.style()->setClipPath(nullptr);
} else if (primitiveValue->isShape()) {
state.style()->setClipPath(ShapeClipPathOperation::create(basicShapeForValue(state, primitiveValue->getShapeValue())));
} else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_URI) {
String cssURLValue = primitiveValue->getStringValue();
KURL url = state.document().completeURL(cssURLValue);
// FIXME: It doesn't work with forward or external SVG references (see https://bugs.webkit.org/show_bug.cgi?id=90405)
- state.style()->setClipPath(ReferenceClipPathOperation::create(cssURLValue, url.fragmentIdentifier()));
+ state.style()->setClipPath(ReferenceClipPathOperation::create(cssURLValue, AtomicString(url.fragmentIdentifier())));
}
}
}
-void StyleBuilderFunctions::applyInitialCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state)
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitFilter(StyleResolverState& state, CSSValue* value)
+{
+ FilterOperations operations;
+ if (FilterOperationResolver::createFilterOperations(value, state.cssToLengthConversionData(), operations, state))
+ state.style()->setFilter(operations);
+}
+
+void StyleBuilderFunctions::applyInitialCSSPropertyFontVariantLigatures(StyleResolverState& state)
{
state.fontBuilder().setFontVariantLigaturesInitial();
}
-void StyleBuilderFunctions::applyInheritCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state)
+void StyleBuilderFunctions::applyInheritCSSPropertyFontVariantLigatures(StyleResolverState& state)
{
state.fontBuilder().setFontVariantLigaturesInherit(state.parentFontDescription());
}
-void StyleBuilderFunctions::applyValueCSSPropertyWebkitFontVariantLigatures(StyleResolverState& state, CSSValue* value)
+void StyleBuilderFunctions::applyValueCSSPropertyFontVariantLigatures(StyleResolverState& state, CSSValue* value)
{
state.fontBuilder().setFontVariantLigaturesValue(value);
}
@@ -705,9 +949,8 @@ void StyleBuilderFunctions::applyValueCSSPropertyInternalMarqueeIncrement(StyleR
break;
}
} else {
- Length marqueeLength = primitiveValue ? primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()) : Length(Undefined);
- if (!marqueeLength.isUndefined())
- state.style()->setMarqueeIncrement(marqueeLength);
+ Length marqueeLength = primitiveValue->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData());
+ state.style()->setMarqueeIncrement(marqueeLength);
}
}
@@ -757,6 +1000,14 @@ void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspectiveOrigin(StyleRe
ASSERT_NOT_REACHED();
}
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitTapHighlightColor(StyleResolverState& state, CSSValue* value)
+{
+ if (!value->isPrimitiveValue())
+ return;
+ Color color = state.document().textLinkColors().colorFromPrimitiveValue(toCSSPrimitiveValue(value), state.style()->color());
+ state.style()->setTapHighlightColor(color);
+}
+
void StyleBuilderFunctions::applyInitialCSSPropertyWebkitTextEmphasisStyle(StyleResolverState& state)
{
state.style()->setTextEmphasisFill(RenderStyle::initialTextEmphasisFill());
@@ -833,1355 +1084,310 @@ void StyleBuilderFunctions::applyValueCSSPropertyTextUnderlinePosition(StyleReso
state.style()->setTextUnderlinePosition(static_cast<TextUnderlinePosition>(t));
}
-// Everything below this line is from the old StyleResolver::applyProperty
-// and eventually needs to move into new StyleBuilderFunctions calls intead.
-
-#define HANDLE_INHERIT(prop, Prop) \
-if (isInherit) { \
- state.style()->set##Prop(state.parentStyle()->prop()); \
- return; \
-}
-
-#define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
-HANDLE_INHERIT(prop, Prop) \
-if (isInitial) { \
- state.style()->set##Prop(RenderStyle::initial##Prop()); \
- return; \
-}
-
-#define HANDLE_SVG_INHERIT(prop, Prop) \
-if (isInherit) { \
- state.style()->accessSVGStyle()->set##Prop(state.parentStyle()->svgStyle()->prop()); \
- return; \
+void StyleBuilderFunctions::applyInitialCSSPropertyWillChange(StyleResolverState& state)
+{
+ state.style()->setWillChangeContents(false);
+ state.style()->setWillChangeScrollPosition(false);
+ state.style()->setWillChangeProperties(Vector<CSSPropertyID>());
+ state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents());
}
-#define HANDLE_SVG_INHERIT_AND_INITIAL(prop, Prop) \
-HANDLE_SVG_INHERIT(prop, Prop) \
-if (isInitial) { \
- state.style()->accessSVGStyle()->set##Prop(SVGRenderStyle::initial##Prop()); \
- return; \
+void StyleBuilderFunctions::applyInheritCSSPropertyWillChange(StyleResolverState& state)
+{
+ state.style()->setWillChangeContents(state.parentStyle()->willChangeContents());
+ state.style()->setWillChangeScrollPosition(state.parentStyle()->willChangeScrollPosition());
+ state.style()->setWillChangeProperties(state.parentStyle()->willChangeProperties());
+ state.style()->setSubtreeWillChangeContents(state.parentStyle()->subtreeWillChangeContents());
}
-static bool createGridTrackBreadth(CSSPrimitiveValue* primitiveValue, const StyleResolverState& state, GridLength& workingLength)
+void StyleBuilderFunctions::applyValueCSSPropertyWillChange(StyleResolverState& state, CSSValue* value)
{
- if (primitiveValue->getValueID() == CSSValueMinContent) {
- workingLength = Length(MinContent);
- return true;
- }
+ ASSERT(value->isValueList());
+ bool willChangeContents = false;
+ bool willChangeScrollPosition = false;
+ Vector<CSSPropertyID> willChangeProperties;
- if (primitiveValue->getValueID() == CSSValueMaxContent) {
- workingLength = Length(MaxContent);
- return true;
- }
-
- if (primitiveValue->isFlex()) {
- // Fractional unit.
- workingLength.setFlex(primitiveValue->getDoubleValue());
- return true;
+ for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value());
+ if (CSSPropertyID propertyID = primitiveValue->getPropertyID())
+ willChangeProperties.append(propertyID);
+ else if (primitiveValue->getValueID() == CSSValueContents)
+ willChangeContents = true;
+ else if (primitiveValue->getValueID() == CSSValueScrollPosition)
+ willChangeScrollPosition = true;
+ else
+ ASSERT_NOT_REACHED();
}
-
- workingLength = primitiveValue->convertToLength<FixedConversion | PercentConversion | AutoConversion>(state.cssToLengthConversionData());
- if (workingLength.length().isUndefined())
- return false;
-
- if (primitiveValue->isLength())
- workingLength.length().setQuirk(primitiveValue->isQuirkValue());
-
- return true;
+ state.style()->setWillChangeContents(willChangeContents);
+ state.style()->setWillChangeScrollPosition(willChangeScrollPosition);
+ state.style()->setWillChangeProperties(willChangeProperties);
+ state.style()->setSubtreeWillChangeContents(willChangeContents || state.parentStyle()->subtreeWillChangeContents());
}
-static bool createGridTrackSize(CSSValue* value, GridTrackSize& trackSize, const StyleResolverState& state)
+void StyleBuilderFunctions::applyInitialCSSPropertyContent(StyleResolverState& state)
{
- if (value->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- GridLength workingLength;
- if (!createGridTrackBreadth(primitiveValue, state, workingLength))
- return false;
-
- trackSize.setLength(workingLength);
- return true;
- }
-
- CSSFunctionValue* minmaxFunction = toCSSFunctionValue(value);
- CSSValueList* arguments = minmaxFunction->arguments();
- ASSERT_WITH_SECURITY_IMPLICATION(arguments->length() == 2);
- GridLength minTrackBreadth;
- GridLength maxTrackBreadth;
- if (!createGridTrackBreadth(toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(0)), state, minTrackBreadth) || !createGridTrackBreadth(toCSSPrimitiveValue(arguments->itemWithoutBoundsCheck(1)), state, maxTrackBreadth))
- return false;
+ state.style()->clearContent();
+}
- trackSize.setMinMax(minTrackBreadth, maxTrackBreadth);
- return true;
+void StyleBuilderFunctions::applyInheritCSSPropertyContent(StyleResolverState&)
+{
+ // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
+ // note is a reminder that eventually "inherit" needs to be supported.
}
-static bool createGridTrackList(CSSValue* value, Vector<GridTrackSize>& trackSizes, NamedGridLinesMap& namedGridLines, OrderedNamedGridLines& orderedNamedGridLines, const StyleResolverState& state)
+void StyleBuilderFunctions::applyValueCSSPropertyContent(StyleResolverState& state, CSSValue* value)
{
- // Handle 'none'.
- if (value->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- return primitiveValue->getValueID() == CSSValueNone;
- }
+ // list of string, uri, counter, attr, i
if (!value->isValueList())
- return false;
+ return;
- size_t currentNamedGridLine = 0;
+ bool didSet = false;
for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
- CSSValue* currValue = i.value();
- if (currValue->isGridLineNamesValue()) {
- CSSGridLineNamesValue* lineNamesValue = toCSSGridLineNamesValue(currValue);
- for (CSSValueListIterator j = lineNamesValue; j.hasMore(); j.advance()) {
- String namedGridLine = toCSSPrimitiveValue(j.value())->getStringValue();
- NamedGridLinesMap::AddResult result = namedGridLines.add(namedGridLine, Vector<size_t>());
- result.iterator->value.append(currentNamedGridLine);
- OrderedNamedGridLines::AddResult orderedInsertionResult = orderedNamedGridLines.add(currentNamedGridLine, Vector<String>());
- orderedInsertionResult.iterator->value.append(namedGridLine);
- }
- continue;
+ CSSValue* item = i.value();
+ if (item->isImageGeneratorValue()) {
+ if (item->isGradientValue())
+ state.style()->setContent(StyleGeneratedImage::create(toCSSGradientValue(item)->gradientWithStylesResolved(state.document().textLinkColors(), state.style()->color()).get()), didSet);
+ else
+ state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item)), didSet);
+ didSet = true;
+ } else if (item->isImageSetValue()) {
+ state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item)), didSet);
+ didSet = true;
}
- ++currentNamedGridLine;
- GridTrackSize trackSize;
- if (!createGridTrackSize(currValue, trackSize, state))
- return false;
-
- trackSizes.append(trackSize);
- }
-
- // The parser should have rejected any <track-list> without any <track-size> as
- // this is not conformant to the syntax.
- ASSERT(!trackSizes.isEmpty());
- return true;
-}
-
-static bool createGridPosition(CSSValue* value, GridPosition& position)
-{
- // We accept the specification's grammar:
- // 'auto' | [ <integer> || <string> ] | [ span && [ <integer> || string ] ] | <ident>
-
- if (value->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- // We translate <ident> to <string> during parsing as it
- // makes handling it more simple.
- if (primitiveValue->isString()) {
- position.setNamedGridArea(primitiveValue->getStringValue());
- return true;
+ if (item->isImageValue()) {
+ state.style()->setContent(state.elementStyleResources().cachedOrPendingFromValue(state.document(), CSSPropertyContent, toCSSImageValue(item)), didSet);
+ didSet = true;
+ continue;
}
- ASSERT(primitiveValue->getValueID() == CSSValueAuto);
- return true;
- }
-
- CSSValueList* values = toCSSValueList(value);
- ASSERT(values->length());
-
- bool isSpanPosition = false;
- // The specification makes the <integer> optional, in which case it default to '1'.
- int gridLineNumber = 1;
- String gridLineName;
-
- CSSValueListIterator it = values;
- CSSPrimitiveValue* currentValue = toCSSPrimitiveValue(it.value());
- if (currentValue->getValueID() == CSSValueSpan) {
- isSpanPosition = true;
- it.advance();
- currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
- }
-
- if (currentValue && currentValue->isNumber()) {
- gridLineNumber = currentValue->getIntValue();
- it.advance();
- currentValue = it.hasMore() ? toCSSPrimitiveValue(it.value()) : 0;
- }
-
- if (currentValue && currentValue->isString()) {
- gridLineName = currentValue->getStringValue();
- it.advance();
- }
-
- ASSERT(!it.hasMore());
- if (isSpanPosition)
- position.setSpanPosition(gridLineNumber, gridLineName);
- else
- position.setExplicitPosition(gridLineNumber, gridLineName);
-
- return true;
-}
-
-static bool degreeToGlyphOrientation(CSSPrimitiveValue* primitiveValue, EGlyphOrientation& orientation)
-{
- if (!primitiveValue)
- return false;
-
- if (primitiveValue->primitiveType() != CSSPrimitiveValue::CSS_DEG)
- return false;
-
- float angle = fabsf(fmodf(primitiveValue->getFloatValue(), 360.0f));
-
- if (angle <= 45.0f || angle > 315.0f) {
- orientation = GO_0DEG;
- return true;
- }
- if (angle > 45.0f && angle <= 135.0f) {
- orientation = GO_90DEG;
- return true;
- }
- if (angle > 135.0f && angle <= 225.0f) {
- orientation = GO_180DEG;
- return true;
- }
- orientation = GO_270DEG;
- return true;
-}
-
-static Color colorFromSVGColorCSSValue(SVGColor* svgColor, const Color& fgColor)
-{
- Color color;
- if (svgColor->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
- color = fgColor;
- else
- color = svgColor->color();
- return color;
-}
+ if (!item->isPrimitiveValue())
+ continue;
-static EPaintOrder paintOrderFlattened(CSSValue* cssPaintOrder)
-{
- if (cssPaintOrder->isValueList()) {
- int paintOrder = 0;
- CSSValueListInspector iter(cssPaintOrder);
- for (size_t i = 0; i < iter.length(); i++) {
- CSSPrimitiveValue* value = toCSSPrimitiveValue(iter.item(i));
+ CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item);
- EPaintOrderType paintOrderType = PT_NONE;
- switch (value->getValueID()) {
- case CSSValueFill:
- paintOrderType = PT_FILL;
+ if (contentValue->isString()) {
+ state.style()->setContent(contentValue->getStringValue().impl(), didSet);
+ didSet = true;
+ } else if (contentValue->isAttr()) {
+ // FIXME: Can a namespace be specified for an attr(foo)?
+ if (state.style()->styleType() == NOPSEUDO)
+ state.style()->setUnique();
+ else
+ state.parentStyle()->setUnique();
+ QualifiedName attr(nullAtom, AtomicString(contentValue->getStringValue()), nullAtom);
+ const AtomicString& value = state.element()->getAttribute(attr);
+ state.style()->setContent(value.isNull() ? emptyString() : value.string(), didSet);
+ didSet = true;
+ // register the fact that the attribute value affects the style
+ state.contentAttrValues().append(attr.localName());
+ } else if (contentValue->isCounter()) {
+ Counter* counterValue = contentValue->getCounterValue();
+ EListStyleType listStyleType = NoneListStyle;
+ CSSValueID listStyleIdent = counterValue->listStyleIdent();
+ if (listStyleIdent != CSSValueNone)
+ listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
+ OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(AtomicString(counterValue->identifier()), listStyleType, AtomicString(counterValue->separator())));
+ state.style()->setContent(counter.release(), didSet);
+ didSet = true;
+ } else {
+ switch (contentValue->getValueID()) {
+ case CSSValueOpenQuote:
+ state.style()->setContent(OPEN_QUOTE, didSet);
+ didSet = true;
break;
- case CSSValueStroke:
- paintOrderType = PT_STROKE;
+ case CSSValueCloseQuote:
+ state.style()->setContent(CLOSE_QUOTE, didSet);
+ didSet = true;
break;
- case CSSValueMarkers:
- paintOrderType = PT_MARKERS;
+ case CSSValueNoOpenQuote:
+ state.style()->setContent(NO_OPEN_QUOTE, didSet);
+ didSet = true;
break;
- default:
- ASSERT_NOT_REACHED();
+ case CSSValueNoCloseQuote:
+ state.style()->setContent(NO_CLOSE_QUOTE, didSet);
+ didSet = true;
break;
+ default:
+ // normal and none do not have any effect.
+ { }
}
-
- paintOrder |= (paintOrderType << kPaintOrderBitwidth*i);
}
- return (EPaintOrder)paintOrder;
}
-
- return PO_NORMAL;
+ if (!didSet)
+ state.style()->clearContent();
}
-static inline bool isValidVisitedLinkProperty(CSSPropertyID id)
+void StyleBuilderFunctions::applyInitialCSSPropertyFont(StyleResolverState&)
{
- switch (id) {
- case CSSPropertyBackgroundColor:
- case CSSPropertyBorderLeftColor:
- case CSSPropertyBorderRightColor:
- case CSSPropertyBorderTopColor:
- case CSSPropertyBorderBottomColor:
- case CSSPropertyColor:
- case CSSPropertyFill:
- case CSSPropertyOutlineColor:
- case CSSPropertyStroke:
- case CSSPropertyTextDecorationColor:
- case CSSPropertyWebkitColumnRuleColor:
- case CSSPropertyWebkitTextEmphasisColor:
- case CSSPropertyWebkitTextFillColor:
- case CSSPropertyWebkitTextStrokeColor:
- return true;
- default:
- break;
- }
-
- return false;
+ ASSERT_NOT_REACHED();
}
-static bool hasVariableReference(CSSValue* value)
+void StyleBuilderFunctions::applyInheritCSSPropertyFont(StyleResolverState&)
{
- if (value->isPrimitiveValue()) {
- CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
- return primitiveValue->hasVariableReference();
- }
-
- if (value->isCalcValue())
- return toCSSCalcValue(value)->hasVariableReference();
-
- if (value->isReflectValue()) {
- CSSReflectValue* reflectValue = toCSSReflectValue(value);
- CSSPrimitiveValue* direction = reflectValue->direction();
- CSSPrimitiveValue* offset = reflectValue->offset();
- CSSValue* mask = reflectValue->mask();
- return (direction && hasVariableReference(direction)) || (offset && hasVariableReference(offset)) || (mask && hasVariableReference(mask));
- }
-
- for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
- if (hasVariableReference(i.value()))
- return true;
- }
-
- return false;
+ ASSERT_NOT_REACHED();
}
-// FIXME: Resolving variables should be factored better. Maybe a resover-style class?
-static void resolveVariables(StyleResolverState& state, CSSPropertyID id, CSSValue* value, Vector<std::pair<CSSPropertyID, String> >& knownExpressions)
+void StyleBuilderFunctions::applyValueCSSPropertyFont(StyleResolverState& state, CSSValue* value)
{
- std::pair<CSSPropertyID, String> expression(id, value->serializeResolvingVariables(*state.style()->variables()));
-
- if (knownExpressions.contains(expression))
- return; // cycle detected.
-
- knownExpressions.append(expression);
-
- // FIXME: It would be faster not to re-parse from strings, but for now CSS property validation lives inside the parser so we do it there.
- RefPtr<MutableStylePropertySet> resultSet = MutableStylePropertySet::create();
- if (!CSSParser::parseValue(resultSet.get(), id, expression.second, false, state.document()))
- return; // expression failed to parse.
-
- for (unsigned i = 0; i < resultSet->propertyCount(); i++) {
- StylePropertySet::PropertyReference property = resultSet->propertyAt(i);
- if (property.id() != CSSPropertyVariable && hasVariableReference(property.value())) {
- resolveVariables(state, property.id(), property.value(), knownExpressions);
- } else {
- StyleBuilder::applyProperty(property.id(), state, property.value());
- // All properties become dependent on their parent style when they use variables.
- state.style()->setHasExplicitlyInheritedProperties();
- }
- }
+ // Only System Font identifiers should come through this method
+ // all other values should have been handled when the shorthand
+ // was expanded by the parser.
+ // FIXME: System Font identifiers should not hijack this
+ // short-hand CSSProperty like this (crbug.com/353932)
+ state.style()->setLineHeight(RenderStyle::initialLineHeight());
+ state.setLineHeightValue(0);
+ state.fontBuilder().fromSystemFont(toCSSPrimitiveValue(value)->getValueID(), state.style()->effectiveZoom());
}
-void StyleBuilder::applyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value)
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitLocale(StyleResolverState& state, CSSValue* value)
{
- if (RuntimeEnabledFeatures::cssVariablesEnabled() && id != CSSPropertyVariable && hasVariableReference(value)) {
- Vector<std::pair<CSSPropertyID, String> > knownExpressions;
- resolveVariables(state, id, value, knownExpressions);
- return;
- }
-
- // CSS variables don't resolve shorthands at parsing time, so this should be *after* handling variables.
- ASSERT_WITH_MESSAGE(!isExpandedShorthand(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
-
- bool isInherit = state.parentNode() && value->isInheritedValue();
- bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue());
-
- ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
- ASSERT(!isInherit || (state.parentNode() && state.parentStyle())); // isInherit -> (state.parentNode() && state.parentStyle())
-
- if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
- // Limit the properties that can be applied to only the ones honored by :visited.
- return;
- }
-
- CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0;
- if (primitiveValue && primitiveValue->getValueID() == CSSValueCurrentcolor)
- state.style()->setHasCurrentColor();
-
- if (isInherit && !state.parentStyle()->hasExplicitlyInheritedProperties() && !CSSProperty::isInheritedProperty(id))
- state.parentStyle()->setHasExplicitlyInheritedProperties();
-
- if (id == CSSPropertyVariable) {
- ASSERT_WITH_SECURITY_IMPLICATION(value->isVariableValue());
- CSSVariableValue* variable = toCSSVariableValue(value);
- ASSERT(!variable->name().isEmpty());
- ASSERT(!variable->value().isEmpty());
- state.style()->setVariable(variable->name(), variable->value());
- return;
- }
-
- if (StyleBuilder::applyProperty(id, state, value, isInitial, isInherit))
+ if (!value->isPrimitiveValue())
return;
-
- // Fall back to the old switch statement, which is now in StyleBuilderCustom.cpp
- StyleBuilder::oldApplyProperty(id, state, value, isInitial, isInherit);
+ const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (primitiveValue->getValueID() == CSSValueAuto)
+ state.style()->setLocale(nullAtom);
+ else
+ state.style()->setLocale(AtomicString(primitiveValue->getStringValue()));
+ state.fontBuilder().setScript(state.style()->locale());
}
-
-void StyleBuilder::oldApplyProperty(CSSPropertyID id, StyleResolverState& state, CSSValue* value, bool isInitial, bool isInherit)
+void StyleBuilderFunctions::applyInitialCSSPropertyWebkitAppRegion(StyleResolverState&)
{
- CSSPrimitiveValue* primitiveValue = value->isPrimitiveValue() ? toCSSPrimitiveValue(value) : 0;
-
- // What follows is a list that maps the CSS properties into their corresponding front-end
- // RenderStyle values.
- switch (id) {
- case CSSPropertyContent:
- // list of string, uri, counter, attr, i
- {
- // FIXME: In CSS3, it will be possible to inherit content. In CSS2 it is not. This
- // note is a reminder that eventually "inherit" needs to be supported.
-
- if (isInitial) {
- state.style()->clearContent();
- return;
- }
+}
- if (!value->isValueList())
- return;
+void StyleBuilderFunctions::applyInheritCSSPropertyWebkitAppRegion(StyleResolverState&)
+{
+}
- bool didSet = false;
- for (CSSValueListIterator i = value; i.hasMore(); i.advance()) {
- CSSValue* item = i.value();
- if (item->isImageGeneratorValue()) {
- if (item->isGradientValue())
- state.style()->setContent(StyleGeneratedImage::create(toCSSGradientValue(item)->gradientWithStylesResolved(state.document().textLinkColors(), state.style()->color()).get()), didSet);
- else
- state.style()->setContent(StyleGeneratedImage::create(toCSSImageGeneratorValue(item)), didSet);
- didSet = true;
- } else if (item->isImageSetValue()) {
- state.style()->setContent(state.elementStyleResources().setOrPendingFromValue(CSSPropertyContent, toCSSImageSetValue(item)), didSet);
- didSet = true;
- }
-
- if (item->isImageValue()) {
- state.style()->setContent(state.elementStyleResources().cachedOrPendingFromValue(CSSPropertyContent, toCSSImageValue(item)), didSet);
- didSet = true;
- continue;
- }
-
- if (!item->isPrimitiveValue())
- continue;
-
- CSSPrimitiveValue* contentValue = toCSSPrimitiveValue(item);
-
- if (contentValue->isString()) {
- state.style()->setContent(contentValue->getStringValue().impl(), didSet);
- didSet = true;
- } else if (contentValue->isAttr()) {
- // FIXME: Can a namespace be specified for an attr(foo)?
- if (state.style()->styleType() == NOPSEUDO)
- state.style()->setUnique();
- else
- state.parentStyle()->setUnique();
- QualifiedName attr(nullAtom, AtomicString(contentValue->getStringValue()), nullAtom);
- const AtomicString& value = state.element()->getAttribute(attr);
- state.style()->setContent(value.isNull() ? emptyString() : value.string(), didSet);
- didSet = true;
- // register the fact that the attribute value affects the style
- state.contentAttrValues().append(attr.localName());
- } else if (contentValue->isCounter()) {
- Counter* counterValue = contentValue->getCounterValue();
- EListStyleType listStyleType = NoneListStyle;
- CSSValueID listStyleIdent = counterValue->listStyleIdent();
- if (listStyleIdent != CSSValueNone)
- listStyleType = static_cast<EListStyleType>(listStyleIdent - CSSValueDisc);
- OwnPtr<CounterContent> counter = adoptPtr(new CounterContent(AtomicString(counterValue->identifier()), listStyleType, AtomicString(counterValue->separator())));
- state.style()->setContent(counter.release(), didSet);
- didSet = true;
- } else {
- switch (contentValue->getValueID()) {
- case CSSValueOpenQuote:
- state.style()->setContent(OPEN_QUOTE, didSet);
- didSet = true;
- break;
- case CSSValueCloseQuote:
- state.style()->setContent(CLOSE_QUOTE, didSet);
- didSet = true;
- break;
- case CSSValueNoOpenQuote:
- state.style()->setContent(NO_OPEN_QUOTE, didSet);
- didSet = true;
- break;
- case CSSValueNoCloseQuote:
- state.style()->setContent(NO_CLOSE_QUOTE, didSet);
- didSet = true;
- break;
- default:
- // normal and none do not have any effect.
- { }
- }
- }
- }
- if (!didSet)
- state.style()->clearContent();
- return;
- }
- case CSSPropertyQuotes:
- HANDLE_INHERIT_AND_INITIAL(quotes, Quotes);
- if (value->isValueList()) {
- CSSValueList* list = toCSSValueList(value);
- RefPtr<QuotesData> quotes = QuotesData::create();
- for (size_t i = 0; i < list->length(); i += 2) {
- CSSValue* first = list->itemWithoutBoundsCheck(i);
- // item() returns null if out of bounds so this is safe.
- CSSValue* second = list->item(i + 1);
- if (!second)
- continue;
- String startQuote = toCSSPrimitiveValue(first)->getStringValue();
- String endQuote = toCSSPrimitiveValue(second)->getStringValue();
- quotes->addPair(std::make_pair(startQuote, endQuote));
- }
- state.style()->setQuotes(quotes);
- return;
- }
- if (primitiveValue) {
- if (primitiveValue->getValueID() == CSSValueNone)
- state.style()->setQuotes(QuotesData::create());
- }
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitAppRegion(StyleResolverState& state, CSSValue* value)
+{
+ if (!value->isPrimitiveValue())
return;
- // Shorthand properties.
- case CSSPropertyFont:
- // Only System Font identifiers should come through this method
- // all other values should have been handled when the shorthand
- // was expanded by the parser.
- // FIXME: System Font identifiers should not hijack this
- // short-hand CSSProperty like this.
- ASSERT(!isInitial);
- ASSERT(!isInherit);
- ASSERT(primitiveValue);
- state.style()->setLineHeight(RenderStyle::initialLineHeight());
- state.setLineHeightValue(0);
- state.fontBuilder().fromSystemFont(primitiveValue->getValueID(), state.style()->effectiveZoom());
+ const CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (!primitiveValue->getValueID())
return;
- case CSSPropertyAnimation:
- case CSSPropertyBackground:
- case CSSPropertyBackgroundPosition:
- case CSSPropertyBackgroundRepeat:
- case CSSPropertyBorder:
- case CSSPropertyBorderBottom:
- case CSSPropertyBorderColor:
- case CSSPropertyBorderImage:
- case CSSPropertyBorderLeft:
- case CSSPropertyBorderRadius:
- case CSSPropertyBorderRight:
- case CSSPropertyBorderSpacing:
- case CSSPropertyBorderStyle:
- case CSSPropertyBorderTop:
- case CSSPropertyBorderWidth:
- case CSSPropertyListStyle:
- case CSSPropertyMargin:
- case CSSPropertyObjectPosition:
- case CSSPropertyOutline:
- case CSSPropertyOverflow:
- case CSSPropertyPadding:
- case CSSPropertyTransition:
- case CSSPropertyWebkitAnimation:
- case CSSPropertyWebkitBorderAfter:
- case CSSPropertyWebkitBorderBefore:
- case CSSPropertyWebkitBorderEnd:
- case CSSPropertyWebkitBorderStart:
- case CSSPropertyWebkitBorderRadius:
- case CSSPropertyWebkitColumns:
- case CSSPropertyWebkitColumnRule:
- case CSSPropertyFlex:
- case CSSPropertyFlexFlow:
- case CSSPropertyGridColumn:
- case CSSPropertyGridRow:
- case CSSPropertyGridArea:
- case CSSPropertyWebkitMarginCollapse:
- case CSSPropertyWebkitMask:
- case CSSPropertyWebkitMaskPosition:
- case CSSPropertyWebkitMaskRepeat:
- case CSSPropertyWebkitTextEmphasis:
- case CSSPropertyWebkitTextStroke:
- case CSSPropertyWebkitTransition:
- case CSSPropertyWebkitTransformOrigin:
- ASSERT(isExpandedShorthand(id));
- ASSERT_NOT_REACHED();
- break;
+ state.style()->setDraggableRegionMode(primitiveValue->getValueID() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag);
+ state.document().setHasAnnotatedRegions(true);
+}
- // CSS3 Properties
- case CSSPropertyWebkitBoxReflect: {
- HANDLE_INHERIT_AND_INITIAL(boxReflect, BoxReflect)
- if (primitiveValue) {
- state.style()->setBoxReflect(RenderStyle::initialBoxReflect());
- return;
- }
+void StyleBuilderFunctions::applyInitialCSSPropertyWebkitPerspective(StyleResolverState& state)
+{
+ applyInitialCSSPropertyPerspective(state);
+}
- if (!value->isReflectValue())
- return;
+void StyleBuilderFunctions::applyInheritCSSPropertyWebkitPerspective(StyleResolverState& state)
+{
+ applyInheritCSSPropertyPerspective(state);
+}
- CSSReflectValue* reflectValue = toCSSReflectValue(value);
- RefPtr<StyleReflection> reflection = StyleReflection::create();
- reflection->setDirection(*reflectValue->direction());
- if (reflectValue->offset())
- reflection->setOffset(reflectValue->offset()->convertToLength<FixedConversion | PercentConversion>(state.cssToLengthConversionData()));
- NinePieceImage mask;
- mask.setMaskDefaults();
- state.styleMap().mapNinePieceImage(state.style(), id, reflectValue->mask(), mask);
- reflection->setMask(mask);
-
- state.style()->setBoxReflect(reflection.release());
- return;
- }
- case CSSPropertySrc: // Only used in @font-face rules.
- return;
- case CSSPropertyUnicodeRange: // Only used in @font-face rules.
- return;
- case CSSPropertyWebkitLocale: {
- HANDLE_INHERIT_AND_INITIAL(locale, Locale);
- if (!primitiveValue)
- return;
- if (primitiveValue->getValueID() == CSSValueAuto)
- state.style()->setLocale(nullAtom);
- else
- state.style()->setLocale(AtomicString(primitiveValue->getStringValue()));
- state.fontBuilder().setScript(state.style()->locale());
- return;
- }
- case CSSPropertyWebkitAppRegion: {
- if (!primitiveValue || !primitiveValue->getValueID())
- return;
- state.style()->setDraggableRegionMode(primitiveValue->getValueID() == CSSValueDrag ? DraggableRegionDrag : DraggableRegionNoDrag);
- state.document().setHasAnnotatedRegions(true);
- return;
- }
- case CSSPropertyWebkitTextStrokeWidth: {
- HANDLE_INHERIT_AND_INITIAL(textStrokeWidth, TextStrokeWidth)
- float width = 0;
- switch (primitiveValue->getValueID()) {
- case CSSValueThin:
- case CSSValueMedium:
- case CSSValueThick: {
- double result = 1.0 / 48;
- if (primitiveValue->getValueID() == CSSValueMedium)
- result *= 3;
- else if (primitiveValue->getValueID() == CSSValueThick)
- result *= 5;
- width = CSSPrimitiveValue::create(result, CSSPrimitiveValue::CSS_EMS)->computeLength<float>(state.cssToLengthConversionData());
- break;
- }
- default:
- width = primitiveValue->computeLength<float>(state.cssToLengthConversionData());
- break;
- }
- state.style()->setTextStrokeWidth(width);
- return;
- }
- case CSSPropertyWebkitTransform: {
- HANDLE_INHERIT_AND_INITIAL(transform, Transform);
- TransformOperations operations;
- TransformBuilder::createTransformOperations(value, state.cssToLengthConversionData(), operations);
- state.style()->setTransform(operations);
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitPerspective(StyleResolverState& state, CSSValue* value)
+{
+ if (!value->isPrimitiveValue())
return;
- }
- case CSSPropertyWebkitPerspective: {
- HANDLE_INHERIT_AND_INITIAL(perspective, Perspective)
-
- if (!primitiveValue)
- return;
-
- if (primitiveValue->getValueID() == CSSValueNone) {
- state.style()->setPerspective(0);
- return;
- }
-
- float perspectiveValue;
- if (primitiveValue->isLength()) {
- perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData());
- } else if (primitiveValue->isNumber()) {
- // For backward compatibility, treat valueless numbers as px.
- perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.cssToLengthConversionData());
- } else {
- return;
- }
-
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (primitiveValue->isNumber()) {
+ float perspectiveValue = CSSPrimitiveValue::create(primitiveValue->getDoubleValue(), CSSPrimitiveValue::CSS_PX)->computeLength<float>(state.cssToLengthConversionData());
if (perspectiveValue >= 0.0f)
state.style()->setPerspective(perspectiveValue);
- return;
+ } else {
+ applyValueCSSPropertyPerspective(state, value);
}
- case CSSPropertyWebkitTapHighlightColor: {
- HANDLE_INHERIT_AND_INITIAL(tapHighlightColor, TapHighlightColor);
- if (!primitiveValue)
- break;
+}
- Color col = state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color());
- state.style()->setTapHighlightColor(col);
- return;
- }
- case CSSPropertyInternalCallback: {
- if (isInherit || isInitial)
- return;
- if (primitiveValue && primitiveValue->getValueID() == CSSValueInternalPresence) {
- state.style()->addCallbackSelector(state.currentRule()->selectorList().selectorsText());
- return;
- }
- break;
- }
- case CSSPropertyInvalid:
- return;
- // Directional properties are resolved by resolveDirectionAwareProperty() before the switch.
- case CSSPropertyWebkitBorderEndColor:
- case CSSPropertyWebkitBorderEndStyle:
- case CSSPropertyWebkitBorderEndWidth:
- case CSSPropertyWebkitBorderStartColor:
- case CSSPropertyWebkitBorderStartStyle:
- case CSSPropertyWebkitBorderStartWidth:
- case CSSPropertyWebkitBorderBeforeColor:
- case CSSPropertyWebkitBorderBeforeStyle:
- case CSSPropertyWebkitBorderBeforeWidth:
- case CSSPropertyWebkitBorderAfterColor:
- case CSSPropertyWebkitBorderAfterStyle:
- case CSSPropertyWebkitBorderAfterWidth:
- case CSSPropertyWebkitMarginEnd:
- case CSSPropertyWebkitMarginStart:
- case CSSPropertyWebkitMarginBefore:
- case CSSPropertyWebkitMarginAfter:
- case CSSPropertyWebkitMarginBeforeCollapse:
- case CSSPropertyWebkitMarginTopCollapse:
- case CSSPropertyWebkitMarginAfterCollapse:
- case CSSPropertyWebkitMarginBottomCollapse:
- case CSSPropertyWebkitPaddingEnd:
- case CSSPropertyWebkitPaddingStart:
- case CSSPropertyWebkitPaddingBefore:
- case CSSPropertyWebkitPaddingAfter:
- case CSSPropertyWebkitLogicalWidth:
- case CSSPropertyWebkitLogicalHeight:
- case CSSPropertyWebkitMinLogicalWidth:
- case CSSPropertyWebkitMinLogicalHeight:
- case CSSPropertyWebkitMaxLogicalWidth:
- case CSSPropertyWebkitMaxLogicalHeight:
- {
- CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, state.style()->direction(), state.style()->writingMode());
- ASSERT(newId != id);
- return applyProperty(newId, state, value);
- }
- case CSSPropertyFontStretch:
- case CSSPropertyPage:
- case CSSPropertyTextLineThroughColor:
- case CSSPropertyTextLineThroughMode:
- case CSSPropertyTextLineThroughStyle:
- case CSSPropertyTextLineThroughWidth:
- case CSSPropertyTextOverlineColor:
- case CSSPropertyTextOverlineMode:
- case CSSPropertyTextOverlineStyle:
- case CSSPropertyTextOverlineWidth:
- case CSSPropertyTextUnderlineColor:
- case CSSPropertyTextUnderlineMode:
- case CSSPropertyTextUnderlineStyle:
- case CSSPropertyTextUnderlineWidth:
- case CSSPropertyWebkitFontSizeDelta:
- case CSSPropertyWebkitTextDecorationsInEffect:
+void StyleBuilderFunctions::applyValueCSSPropertyPerspective(StyleResolverState& state, CSSValue* value)
+{
+ if (!value->isPrimitiveValue())
return;
-
- // CSS Text Layout Module Level 3: Vertical writing support
- case CSSPropertyWebkitWritingMode: {
- HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode);
-
- if (primitiveValue)
- state.setWritingMode(*primitiveValue);
-
- // FIXME: It is not ok to modify document state while applying style.
- if (state.element() && state.element() == state.document().documentElement())
- state.document().setWritingModeSetOnDocumentElement(true);
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (primitiveValue->getValueID() == CSSValueNone) {
+ state.style()->setPerspective(0);
return;
}
- case CSSPropertyWebkitTextOrientation: {
- HANDLE_INHERIT_AND_INITIAL(textOrientation, TextOrientation);
-
- if (primitiveValue)
- state.setTextOrientation(*primitiveValue);
-
+ if (!primitiveValue->isLength())
return;
- }
-
- case CSSPropertyWebkitLineBoxContain: {
- HANDLE_INHERIT_AND_INITIAL(lineBoxContain, LineBoxContain)
- if (primitiveValue && primitiveValue->getValueID() == CSSValueNone) {
- state.style()->setLineBoxContain(LineBoxContainNone);
- return;
- }
-
- if (!value->isLineBoxContainValue())
- return;
+ float perspectiveValue = primitiveValue->computeLength<float>(state.cssToLengthConversionData());
+ if (perspectiveValue >= 0.0f)
+ state.style()->setPerspective(perspectiveValue);
+}
- state.style()->setLineBoxContain(toCSSLineBoxContainValue(value)->value());
- return;
- }
+void StyleBuilderFunctions::applyInitialCSSPropertyInternalCallback(StyleResolverState& state)
+{
+}
- // CSS Fonts Module Level 3
- case CSSPropertyWebkitFontFeatureSettings: {
- if (primitiveValue && primitiveValue->getValueID() == CSSValueNormal) {
- state.fontBuilder().setFeatureSettingsNormal();
- return;
- }
+void StyleBuilderFunctions::applyInheritCSSPropertyInternalCallback(StyleResolverState& state)
+{
+}
- if (!value->isValueList())
- return;
+void StyleBuilderFunctions::applyValueCSSPropertyInternalCallback(StyleResolverState& state, CSSValue* value)
+{
+ if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueInternalPresence)
+ state.style()->addCallbackSelector(state.currentRule()->selectorList().selectorsText());
+}
- state.fontBuilder().setFeatureSettingsValue(value);
- return;
- }
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitWritingMode(StyleResolverState& state, CSSValue* value)
+{
+ if (value->isPrimitiveValue())
+ state.setWritingMode(*toCSSPrimitiveValue(value));
- case CSSPropertyWebkitFilter: {
- HANDLE_INHERIT_AND_INITIAL(filter, Filter);
- FilterOperations operations;
- if (FilterOperationResolver::createFilterOperations(value, state.cssToLengthConversionData(), operations, state))
- state.style()->setFilter(operations);
- return;
- }
- case CSSPropertyGridAutoColumns: {
- HANDLE_INHERIT_AND_INITIAL(gridAutoColumns, GridAutoColumns);
- GridTrackSize trackSize;
- if (!createGridTrackSize(value, trackSize, state))
- return;
- state.style()->setGridAutoColumns(trackSize);
- return;
- }
- case CSSPropertyGridAutoRows: {
- HANDLE_INHERIT_AND_INITIAL(gridAutoRows, GridAutoRows);
- GridTrackSize trackSize;
- if (!createGridTrackSize(value, trackSize, state))
- return;
- state.style()->setGridAutoRows(trackSize);
- return;
- }
- case CSSPropertyGridDefinitionColumns: {
- if (isInherit) {
- state.style()->setGridDefinitionColumns(state.parentStyle()->gridDefinitionColumns());
- state.style()->setNamedGridColumnLines(state.parentStyle()->namedGridColumnLines());
- state.style()->setOrderedNamedGridColumnLines(state.parentStyle()->orderedNamedGridColumnLines());
- return;
- }
- if (isInitial) {
- state.style()->setGridDefinitionColumns(RenderStyle::initialGridDefinitionColumns());
- state.style()->setNamedGridColumnLines(RenderStyle::initialNamedGridColumnLines());
- state.style()->setOrderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines());
- return;
- }
+ // FIXME: It is not ok to modify document state while applying style.
+ if (state.element() && state.element() == state.document().documentElement())
+ state.document().setWritingModeSetOnDocumentElement(true);
+}
- Vector<GridTrackSize> trackSizes;
- NamedGridLinesMap namedGridLines;
- OrderedNamedGridLines orderedNamedGridLines;
- if (!createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, state))
- return;
- state.style()->setGridDefinitionColumns(trackSizes);
- state.style()->setNamedGridColumnLines(namedGridLines);
- state.style()->setOrderedNamedGridColumnLines(orderedNamedGridLines);
- return;
- }
- case CSSPropertyGridDefinitionRows: {
- if (isInherit) {
- state.style()->setGridDefinitionRows(state.parentStyle()->gridDefinitionRows());
- state.style()->setNamedGridRowLines(state.parentStyle()->namedGridRowLines());
- state.style()->setOrderedNamedGridRowLines(state.parentStyle()->orderedNamedGridRowLines());
- return;
- }
- if (isInitial) {
- state.style()->setGridDefinitionRows(RenderStyle::initialGridDefinitionRows());
- state.style()->setNamedGridRowLines(RenderStyle::initialNamedGridRowLines());
- state.style()->setOrderedNamedGridRowLines(RenderStyle::initialOrderedNamedGridRowLines());
- return;
- }
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitTextOrientation(StyleResolverState& state, CSSValue* value)
+{
+ if (value->isPrimitiveValue())
+ state.setTextOrientation(*toCSSPrimitiveValue(value));
+}
- Vector<GridTrackSize> trackSizes;
- NamedGridLinesMap namedGridLines;
- OrderedNamedGridLines orderedNamedGridLines;
- if (!createGridTrackList(value, trackSizes, namedGridLines, orderedNamedGridLines, state))
- return;
- state.style()->setGridDefinitionRows(trackSizes);
- state.style()->setNamedGridRowLines(namedGridLines);
- state.style()->setOrderedNamedGridRowLines(orderedNamedGridLines);
- return;
- }
+// FIXME: We should handle initial and inherit for font-feature-settings
+void StyleBuilderFunctions::applyInitialCSSPropertyWebkitFontFeatureSettings(StyleResolverState& state)
+{
+}
- case CSSPropertyGridColumnStart: {
- HANDLE_INHERIT_AND_INITIAL(gridColumnStart, GridColumnStart);
- GridPosition startPosition;
- if (!createGridPosition(value, startPosition))
- return;
- state.style()->setGridColumnStart(startPosition);
- return;
- }
- case CSSPropertyGridColumnEnd: {
- HANDLE_INHERIT_AND_INITIAL(gridColumnEnd, GridColumnEnd);
- GridPosition endPosition;
- if (!createGridPosition(value, endPosition))
- return;
- state.style()->setGridColumnEnd(endPosition);
- return;
- }
+void StyleBuilderFunctions::applyInheritCSSPropertyWebkitFontFeatureSettings(StyleResolverState& state)
+{
+}
- case CSSPropertyGridRowStart: {
- HANDLE_INHERIT_AND_INITIAL(gridRowStart, GridRowStart);
- GridPosition beforePosition;
- if (!createGridPosition(value, beforePosition))
- return;
- state.style()->setGridRowStart(beforePosition);
- return;
- }
- case CSSPropertyGridRowEnd: {
- HANDLE_INHERIT_AND_INITIAL(gridRowEnd, GridRowEnd);
- GridPosition afterPosition;
- if (!createGridPosition(value, afterPosition))
- return;
- state.style()->setGridRowEnd(afterPosition);
+void StyleBuilderFunctions::applyValueCSSPropertyWebkitFontFeatureSettings(StyleResolverState& state, CSSValue* value)
+{
+ if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->getValueID() == CSSValueNormal) {
+ state.fontBuilder().setFeatureSettingsNormal();
return;
}
- case CSSPropertyGridTemplate: {
- if (isInherit) {
- state.style()->setNamedGridArea(state.parentStyle()->namedGridArea());
- state.style()->setNamedGridAreaRowCount(state.parentStyle()->namedGridAreaRowCount());
- state.style()->setNamedGridAreaColumnCount(state.parentStyle()->namedGridAreaColumnCount());
- return;
- }
- if (isInitial) {
- state.style()->setNamedGridArea(RenderStyle::initialNamedGridArea());
- state.style()->setNamedGridAreaRowCount(RenderStyle::initialNamedGridAreaCount());
- state.style()->setNamedGridAreaColumnCount(RenderStyle::initialNamedGridAreaCount());
- return;
- }
-
- if (value->isPrimitiveValue()) {
- ASSERT(toCSSPrimitiveValue(value)->getValueID() == CSSValueNone);
- return;
- }
+ if (value->isValueList())
+ state.fontBuilder().setFeatureSettingsValue(value);
+}
- CSSGridTemplateValue* gridTemplateValue = toCSSGridTemplateValue(value);
- state.style()->setNamedGridArea(gridTemplateValue->gridAreaMap());
- state.style()->setNamedGridAreaRowCount(gridTemplateValue->rowCount());
- state.style()->setNamedGridAreaColumnCount(gridTemplateValue->columnCount());
- return;
- }
- // These properties are aliased and we already applied the property on the prefixed version.
- case CSSPropertyAnimationDelay:
- case CSSPropertyAnimationDirection:
- case CSSPropertyAnimationDuration:
- case CSSPropertyAnimationFillMode:
- case CSSPropertyAnimationIterationCount:
- case CSSPropertyAnimationName:
- case CSSPropertyAnimationPlayState:
- case CSSPropertyAnimationTimingFunction:
- case CSSPropertyTransitionDelay:
- case CSSPropertyTransitionDuration:
- case CSSPropertyTransitionProperty:
- case CSSPropertyTransitionTimingFunction:
- return;
- // These properties are implemented in StyleBuilder::applyProperty.
- case CSSPropertyBackgroundAttachment:
- case CSSPropertyBackgroundBlendMode:
- case CSSPropertyBackgroundClip:
- case CSSPropertyBackgroundColor:
- case CSSPropertyBackgroundImage:
- case CSSPropertyBackgroundOrigin:
- case CSSPropertyBackgroundPositionX:
- case CSSPropertyBackgroundPositionY:
- case CSSPropertyBackgroundRepeatX:
- case CSSPropertyBackgroundRepeatY:
- case CSSPropertyBackgroundSize:
- case CSSPropertyBorderBottomColor:
- case CSSPropertyBorderBottomLeftRadius:
- case CSSPropertyBorderBottomRightRadius:
- case CSSPropertyBorderBottomStyle:
- case CSSPropertyBorderBottomWidth:
- case CSSPropertyBorderCollapse:
- case CSSPropertyBorderImageOutset:
- case CSSPropertyBorderImageRepeat:
- case CSSPropertyBorderImageSlice:
- case CSSPropertyBorderImageSource:
- case CSSPropertyBorderImageWidth:
- case CSSPropertyBorderLeftColor:
- case CSSPropertyBorderLeftStyle:
- case CSSPropertyBorderLeftWidth:
- case CSSPropertyBorderRightColor:
- case CSSPropertyBorderRightStyle:
- case CSSPropertyBorderRightWidth:
- case CSSPropertyBorderTopColor:
- case CSSPropertyBorderTopLeftRadius:
- case CSSPropertyBorderTopRightRadius:
- case CSSPropertyBorderTopStyle:
- case CSSPropertyBorderTopWidth:
- case CSSPropertyBottom:
- case CSSPropertyBoxShadow:
- case CSSPropertyBoxSizing:
- case CSSPropertyCaptionSide:
- case CSSPropertyClear:
- case CSSPropertyClip:
- case CSSPropertyColor:
- case CSSPropertyCounterIncrement:
- case CSSPropertyCounterReset:
- case CSSPropertyCursor:
- case CSSPropertyDirection:
- case CSSPropertyDisplay:
- case CSSPropertyEmptyCells:
- case CSSPropertyFloat:
- case CSSPropertyFontKerning:
- case CSSPropertyFontSize:
- case CSSPropertyFontStyle:
- case CSSPropertyFontVariant:
- case CSSPropertyFontWeight:
- case CSSPropertyHeight:
- case CSSPropertyImageRendering:
- case CSSPropertyIsolation:
- case CSSPropertyLeft:
- case CSSPropertyLetterSpacing:
- case CSSPropertyLineHeight:
- case CSSPropertyListStyleImage:
- case CSSPropertyListStylePosition:
- case CSSPropertyListStyleType:
- case CSSPropertyMarginBottom:
- case CSSPropertyMarginLeft:
- case CSSPropertyMarginRight:
- case CSSPropertyMarginTop:
- case CSSPropertyMaxHeight:
- case CSSPropertyMaxWidth:
- case CSSPropertyMinHeight:
- case CSSPropertyMixBlendMode:
- case CSSPropertyMinWidth:
- case CSSPropertyObjectFit:
- case CSSPropertyOpacity:
- case CSSPropertyOrphans:
- case CSSPropertyOutlineColor:
- case CSSPropertyOutlineOffset:
- case CSSPropertyOutlineStyle:
- case CSSPropertyOutlineWidth:
- case CSSPropertyOverflowWrap:
- case CSSPropertyOverflowX:
- case CSSPropertyOverflowY:
- case CSSPropertyPaddingBottom:
- case CSSPropertyPaddingLeft:
- case CSSPropertyPaddingRight:
- case CSSPropertyPaddingTop:
- case CSSPropertyPageBreakAfter:
- case CSSPropertyPageBreakBefore:
- case CSSPropertyPageBreakInside:
- case CSSPropertyPointerEvents:
- case CSSPropertyPosition:
- case CSSPropertyResize:
- case CSSPropertyRight:
- case CSSPropertySize:
- case CSSPropertySpeak:
- case CSSPropertyTabSize:
- case CSSPropertyTableLayout:
- case CSSPropertyTextAlign:
- case CSSPropertyTextAlignLast:
- case CSSPropertyTextDecoration:
- case CSSPropertyTextDecorationLine:
- case CSSPropertyTextDecorationStyle:
- case CSSPropertyTextDecorationColor:
- case CSSPropertyTextIndent:
- case CSSPropertyTextJustify:
- case CSSPropertyTextOverflow:
- case CSSPropertyTextRendering:
- case CSSPropertyTextShadow:
- case CSSPropertyTextTransform:
- case CSSPropertyTop:
- case CSSPropertyTouchAction:
- case CSSPropertyTouchActionDelay:
- case CSSPropertyUnicodeBidi:
- case CSSPropertyVariable:
- case CSSPropertyVerticalAlign:
- case CSSPropertyVisibility:
- case CSSPropertyWebkitAnimationDelay:
- case CSSPropertyWebkitAnimationDirection:
- case CSSPropertyWebkitAnimationDuration:
- case CSSPropertyWebkitAnimationFillMode:
- case CSSPropertyWebkitAnimationIterationCount:
- case CSSPropertyWebkitAnimationName:
- case CSSPropertyWebkitAnimationPlayState:
- case CSSPropertyWebkitAnimationTimingFunction:
- case CSSPropertyWebkitAppearance:
- case CSSPropertyWebkitAspectRatio:
- case CSSPropertyWebkitBackfaceVisibility:
- case CSSPropertyWebkitBackgroundClip:
- case CSSPropertyWebkitBackgroundComposite:
- case CSSPropertyWebkitBackgroundOrigin:
- case CSSPropertyWebkitBackgroundSize:
- case CSSPropertyWebkitBorderFit:
- case CSSPropertyWebkitBorderHorizontalSpacing:
- case CSSPropertyWebkitBorderImage:
- case CSSPropertyWebkitBorderVerticalSpacing:
- case CSSPropertyWebkitBoxAlign:
- case CSSPropertyWebkitBoxDecorationBreak:
- case CSSPropertyWebkitBoxDirection:
- case CSSPropertyWebkitBoxFlex:
- case CSSPropertyWebkitBoxFlexGroup:
- case CSSPropertyWebkitBoxLines:
- case CSSPropertyWebkitBoxOrdinalGroup:
- case CSSPropertyWebkitBoxOrient:
- case CSSPropertyWebkitBoxPack:
- case CSSPropertyWebkitBoxShadow:
- case CSSPropertyWebkitColumnAxis:
- case CSSPropertyWebkitColumnBreakAfter:
- case CSSPropertyWebkitColumnBreakBefore:
- case CSSPropertyWebkitColumnBreakInside:
- case CSSPropertyWebkitColumnCount:
- case CSSPropertyColumnFill:
- case CSSPropertyWebkitColumnGap:
- case CSSPropertyWebkitColumnProgression:
- case CSSPropertyWebkitColumnRuleColor:
- case CSSPropertyWebkitColumnRuleStyle:
- case CSSPropertyWebkitColumnRuleWidth:
- case CSSPropertyWebkitColumnSpan:
- case CSSPropertyWebkitColumnWidth:
- case CSSPropertyAlignContent:
- case CSSPropertyAlignItems:
- case CSSPropertyAlignSelf:
- case CSSPropertyFlexBasis:
- case CSSPropertyFlexDirection:
- case CSSPropertyFlexGrow:
- case CSSPropertyFlexShrink:
- case CSSPropertyFlexWrap:
- case CSSPropertyJustifyContent:
- case CSSPropertyOrder:
- case CSSPropertyWebkitFlowFrom:
- case CSSPropertyWebkitFlowInto:
- case CSSPropertyWebkitFontSmoothing:
- case CSSPropertyWebkitFontVariantLigatures:
- case CSSPropertyWebkitHighlight:
- case CSSPropertyWebkitHyphenateCharacter:
- case CSSPropertyWebkitLineAlign:
- case CSSPropertyWebkitLineBreak:
- case CSSPropertyWebkitLineClamp:
- case CSSPropertyWebkitLineGrid:
- case CSSPropertyWebkitLineSnap:
- case CSSPropertyInternalMarqueeDirection:
- case CSSPropertyInternalMarqueeIncrement:
- case CSSPropertyInternalMarqueeRepetition:
- case CSSPropertyInternalMarqueeSpeed:
- case CSSPropertyInternalMarqueeStyle:
- case CSSPropertyWebkitMaskBoxImage:
- case CSSPropertyWebkitMaskBoxImageOutset:
- case CSSPropertyWebkitMaskBoxImageRepeat:
- case CSSPropertyWebkitMaskBoxImageSlice:
- case CSSPropertyWebkitMaskBoxImageSource:
- case CSSPropertyWebkitMaskBoxImageWidth:
- case CSSPropertyWebkitMaskClip:
- case CSSPropertyWebkitMaskComposite:
- case CSSPropertyWebkitMaskImage:
- case CSSPropertyWebkitMaskOrigin:
- case CSSPropertyWebkitMaskPositionX:
- case CSSPropertyWebkitMaskPositionY:
- case CSSPropertyWebkitMaskRepeatX:
- case CSSPropertyWebkitMaskRepeatY:
- case CSSPropertyWebkitMaskSize:
- case CSSPropertyWebkitPerspectiveOrigin:
- case CSSPropertyWebkitPerspectiveOriginX:
- case CSSPropertyWebkitPerspectiveOriginY:
- case CSSPropertyWebkitPrintColorAdjust:
- case CSSPropertyWebkitRegionBreakAfter:
- case CSSPropertyWebkitRegionBreakBefore:
- case CSSPropertyWebkitRegionBreakInside:
- case CSSPropertyWebkitRegionFragment:
- case CSSPropertyWebkitRtlOrdering:
- case CSSPropertyWebkitRubyPosition:
- case CSSPropertyWebkitTextCombine:
- case CSSPropertyTextUnderlinePosition:
- case CSSPropertyWebkitTextEmphasisColor:
- case CSSPropertyWebkitTextEmphasisPosition:
- case CSSPropertyWebkitTextEmphasisStyle:
- case CSSPropertyWebkitTextFillColor:
- case CSSPropertyWebkitTextSecurity:
- case CSSPropertyWebkitTextStrokeColor:
- case CSSPropertyWebkitTransformOriginX:
- case CSSPropertyWebkitTransformOriginY:
- case CSSPropertyWebkitTransformOriginZ:
- case CSSPropertyWebkitTransformStyle:
- case CSSPropertyWebkitTransitionDelay:
- case CSSPropertyWebkitTransitionDuration:
- case CSSPropertyWebkitTransitionProperty:
- case CSSPropertyWebkitTransitionTimingFunction:
- case CSSPropertyWebkitUserDrag:
- case CSSPropertyWebkitUserModify:
- case CSSPropertyWebkitUserSelect:
- case CSSPropertyWebkitClipPath:
- case CSSPropertyWebkitWrapFlow:
- case CSSPropertyShapeMargin:
- case CSSPropertyShapePadding:
- case CSSPropertyShapeImageThreshold:
- case CSSPropertyWebkitWrapThrough:
- case CSSPropertyShapeInside:
- case CSSPropertyShapeOutside:
- case CSSPropertyWhiteSpace:
- case CSSPropertyWidows:
- case CSSPropertyWidth:
- case CSSPropertyWordBreak:
- case CSSPropertyWordSpacing:
- case CSSPropertyWordWrap:
- case CSSPropertyZIndex:
- case CSSPropertyZoom:
- case CSSPropertyFontFamily:
- case CSSPropertyGridAutoFlow:
- case CSSPropertyMarker:
- case CSSPropertyAlignmentBaseline:
- case CSSPropertyBufferedRendering:
- case CSSPropertyClipRule:
- case CSSPropertyColorInterpolation:
- case CSSPropertyColorInterpolationFilters:
- case CSSPropertyColorRendering:
- case CSSPropertyDominantBaseline:
- case CSSPropertyFillRule:
- case CSSPropertyMaskSourceType:
- case CSSPropertyMaskType:
- case CSSPropertyShapeRendering:
- case CSSPropertyStrokeLinecap:
- case CSSPropertyStrokeLinejoin:
- case CSSPropertyTextAnchor:
- case CSSPropertyVectorEffect:
- case CSSPropertyWritingMode:
- case CSSPropertyClipPath:
- case CSSPropertyFillOpacity:
- case CSSPropertyFilter:
- case CSSPropertyFloodOpacity:
- case CSSPropertyKerning:
- case CSSPropertyMarkerEnd:
- case CSSPropertyMarkerMid:
- case CSSPropertyMarkerStart:
- case CSSPropertyMask:
- case CSSPropertyStopOpacity:
- case CSSPropertyStrokeDashoffset:
- case CSSPropertyStrokeMiterlimit:
- case CSSPropertyStrokeOpacity:
- case CSSPropertyStrokeWidth:
- ASSERT_NOT_REACHED();
- return;
- // Only used in @viewport rules
- case CSSPropertyMaxZoom:
- case CSSPropertyMinZoom:
- case CSSPropertyOrientation:
- case CSSPropertyUserZoom:
+void StyleBuilderFunctions::applyValueCSSPropertyBaselineShift(StyleResolverState& state, CSSValue* value)
+{
+ if (!value->isPrimitiveValue())
return;
- case CSSPropertyBaselineShift:
- {
- HANDLE_SVG_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
- if (!primitiveValue)
+ SVGRenderStyle* svgStyle = state.style()->accessSVGStyle();
+ CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
+ if (primitiveValue->getValueID()) {
+ switch (primitiveValue->getValueID()) {
+ case CSSValueBaseline:
+ svgStyle->setBaselineShift(BS_BASELINE);
break;
-
- SVGRenderStyle* svgStyle = state.style()->accessSVGStyle();
- if (primitiveValue->getValueID()) {
- switch (primitiveValue->getValueID()) {
- case CSSValueBaseline:
- svgStyle->setBaselineShift(BS_BASELINE);
- break;
- case CSSValueSub:
- svgStyle->setBaselineShift(BS_SUB);
- break;
- case CSSValueSuper:
- svgStyle->setBaselineShift(BS_SUPER);
- break;
- default:
- break;
- }
- } else {
- svgStyle->setBaselineShift(BS_LENGTH);
- svgStyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
- }
-
- break;
- }
- case CSSPropertyColorProfile:
- {
- // Not implemented.
- break;
- }
- // end of ident only properties
- case CSSPropertyFill:
- {
- SVGRenderStyle* svgStyle = state.style()->accessSVGStyle();
- if (isInherit) {
- const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle();
- svgStyle->setFillPaint(svgParentStyle->fillPaintType(), svgParentStyle->fillPaintColor(), svgParentStyle->fillPaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
- return;
- }
- if (isInitial) {
- svgStyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
- return;
- }
- if (value->isSVGPaint()) {
- SVGPaint* svgPaint = toSVGPaint(value);
- svgStyle->setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
- }
- break;
- }
- case CSSPropertyStroke:
- {
- SVGRenderStyle* svgStyle = state.style()->accessSVGStyle();
- if (isInherit) {
- const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle();
- svgStyle->setStrokePaint(svgParentStyle->strokePaintType(), svgParentStyle->strokePaintColor(), svgParentStyle->strokePaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
- return;
- }
- if (isInitial) {
- svgStyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
- return;
- }
- if (value->isSVGPaint()) {
- SVGPaint* svgPaint = toSVGPaint(value);
- svgStyle->setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
- }
- break;
- }
- case CSSPropertyStrokeDasharray:
- {
- HANDLE_SVG_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
- if (!value->isValueList()) {
- state.style()->accessSVGStyle()->setStrokeDashArray(SVGRenderStyle::initialStrokeDashArray());
+ case CSSValueSub:
+ svgStyle->setBaselineShift(BS_SUB);
break;
- }
-
- CSSValueList* dashes = toCSSValueList(value);
-
- Vector<SVGLength> array;
- size_t length = dashes->length();
- for (size_t i = 0; i < length; ++i) {
- CSSValue* currValue = dashes->itemWithoutBoundsCheck(i);
- if (!currValue->isPrimitiveValue())
- continue;
-
- CSSPrimitiveValue* dash = toCSSPrimitiveValue(dashes->itemWithoutBoundsCheck(i));
- array.append(SVGLength::fromCSSPrimitiveValue(dash));
- }
-
- state.style()->accessSVGStyle()->setStrokeDashArray(array);
- break;
- }
- case CSSPropertyStopColor:
- {
- HANDLE_SVG_INHERIT_AND_INITIAL(stopColor, StopColor);
- if (value->isSVGColor())
- state.style()->accessSVGStyle()->setStopColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
- break;
- }
- case CSSPropertyLightingColor:
- {
- HANDLE_SVG_INHERIT_AND_INITIAL(lightingColor, LightingColor);
- if (value->isSVGColor())
- state.style()->accessSVGStyle()->setLightingColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
- break;
- }
- case CSSPropertyFloodColor:
- {
- HANDLE_SVG_INHERIT_AND_INITIAL(floodColor, FloodColor);
- if (value->isSVGColor())
- state.style()->accessSVGStyle()->setFloodColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
- break;
- }
- case CSSPropertyGlyphOrientationHorizontal:
- {
- HANDLE_SVG_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal)
- EGlyphOrientation orientation;
- if (degreeToGlyphOrientation(primitiveValue, orientation))
- state.style()->accessSVGStyle()->setGlyphOrientationHorizontal(orientation);
- break;
- }
- case CSSPropertyPaintOrder: {
- HANDLE_SVG_INHERIT_AND_INITIAL(paintOrder, PaintOrder)
- if (value->isValueList())
- state.style()->accessSVGStyle()->setPaintOrder(paintOrderFlattened(value));
- break;
- }
- case CSSPropertyGlyphOrientationVertical:
- {
- HANDLE_SVG_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical)
- if (primitiveValue->getValueID() == CSSValueAuto) {
- state.style()->accessSVGStyle()->setGlyphOrientationVertical(GO_AUTO);
+ case CSSValueSuper:
+ svgStyle->setBaselineShift(BS_SUPER);
+ break;
+ default:
break;
}
- EGlyphOrientation orientation;
- if (degreeToGlyphOrientation(primitiveValue, orientation))
- state.style()->accessSVGStyle()->setGlyphOrientationVertical(orientation);
- break;
- }
- case CSSPropertyEnableBackground:
- // Silently ignoring this property for now
- // http://bugs.webkit.org/show_bug.cgi?id=6022
- break;
+ } else {
+ svgStyle->setBaselineShift(BS_LENGTH);
+ svgStyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
index bc5cbdab5db..28b0cc9254b 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.cpp
@@ -29,41 +29,42 @@
#include "config.h"
#include "core/css/resolver/StyleResolver.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "StylePropertyShorthand.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
+#include "core/StylePropertyShorthand.h"
#include "core/animation/ActiveAnimations.h"
-#include "core/animation/AnimatableLength.h"
#include "core/animation/AnimatableValue.h"
#include "core/animation/Animation.h"
-#include "core/animation/DocumentTimeline.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/animation/css/CSSAnimatableValueFactory.h"
#include "core/animation/css/CSSAnimations.h"
+#include "core/animation/interpolation/StyleInterpolation.h"
#include "core/css/CSSCalculationValue.h"
#include "core/css/CSSDefaultStyleSheets.h"
-#include "core/css/CSSFontFace.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSKeyframeRule.h"
#include "core/css/CSSKeyframesRule.h"
-#include "core/css/CSSParser.h"
#include "core/css/CSSReflectValue.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSSelector.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/CSSValueList.h"
-#include "core/css/CSSVariableValue.h"
+#include "core/css/CSSValuePool.h"
#include "core/css/ElementRuleCollector.h"
+#include "core/css/FontFace.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/PageRuleCollector.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRuleImport.h"
#include "core/css/StyleSheetContents.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/AnimatedStyleBuilder.h"
#include "core/css/resolver/MatchResult.h"
#include "core/css/resolver/MediaQueryResult.h"
#include "core/css/resolver/SharedStyleFinder.h"
#include "core/css/resolver/StyleAdjuster.h"
+#include "core/css/resolver/StyleResolverParentScope.h"
+#include "core/css/resolver/StyleResolverState.h"
#include "core/css/resolver/StyleResolverStats.h"
#include "core/css/resolver/ViewportStyleResolver.h"
#include "core/dom/CSSSelectorWatch.h"
@@ -72,20 +73,18 @@
#include "core/dom/Text.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/style/KeyframeList.h"
-#include "core/rendering/style/StyleCustomFilterProgramCache.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGFontFaceElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/StdLibExtras.h"
-using namespace std;
-
namespace {
using namespace WebCore;
@@ -94,8 +93,8 @@ void setAnimationUpdateIfNeeded(StyleResolverState& state, Element& element)
{
// If any changes to CSS Animations were detected, stash the update away for application after the
// render object is updated if we're in the appropriate scope.
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled() && state.animationUpdate())
- element.ensureActiveAnimations()->cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
+ if (state.animationUpdate())
+ element.ensureActiveAnimations().cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
}
} // namespace
@@ -124,9 +123,9 @@ static StylePropertySet* rightToLeftDeclaration()
static void addFontFaceRule(Document* document, CSSFontSelector* cssFontSelector, const StyleRuleFontFace* fontFaceRule)
{
- RefPtr<CSSFontFace> cssFontFace = CSSFontFace::createFromStyleRule(document, fontFaceRule);
- if (cssFontFace)
- cssFontSelector->addFontFaceRule(fontFaceRule, cssFontFace);
+ RefPtrWillBeRawPtr<FontFace> fontFace = FontFace::create(document, fontFaceRule);
+ if (fontFace)
+ cssFontSelector->fontFaceCache()->add(cssFontSelector, fontFaceRule, fontFace);
}
StyleResolver::StyleResolver(Document& document)
@@ -134,46 +133,31 @@ StyleResolver::StyleResolver(Document& document)
, m_viewportStyleResolver(ViewportStyleResolver::create(&document))
, m_needCollectFeatures(false)
, m_styleResourceLoader(document.fetcher())
+ , m_styleSharingDepth(0)
, m_styleResolverStatsSequence(0)
, m_accessCount(0)
{
- // FIXME: Why do this here instead of as part of resolving style on the root?
- CSSDefaultStyleSheets::loadDefaultStylesheetIfNecessary();
-
- // Construct document root element default style. This is needed
- // to evaluate media queries that contain relative constraints, like "screen and (max-width: 10em)"
- // This is here instead of constructor because when constructor is run,
- // Document doesn't have documentElement.
- // NOTE: This assumes that element that gets passed to the styleForElement call
- // is always from the document that owns the StyleResolver.
FrameView* view = document.view();
if (view)
- m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType()));
+ m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), &view->frame()));
else
m_medium = adoptPtr(new MediaQueryEvaluator("all"));
- Element* root = document.documentElement();
- if (root)
- m_rootDefaultStyle = styleForElement(root, 0, DisallowStyleSharing, MatchOnlyUserAgentRules);
-
- if (m_rootDefaultStyle && view)
- m_medium = adoptPtr(new MediaQueryEvaluator(view->mediaType(), &view->frame(), m_rootDefaultStyle.get()));
-
m_styleTree.clear();
initWatchedSelectorRules(CSSSelectorWatch::from(document).watchedCallbackSelectors());
#if ENABLE(SVG_FONTS)
if (document.svgExtensions()) {
- const HashSet<SVGFontFaceElement*>& svgFontFaceElements = document.svgExtensions()->svgFontFaceElements();
- HashSet<SVGFontFaceElement*>::const_iterator end = svgFontFaceElements.end();
- for (HashSet<SVGFontFaceElement*>::const_iterator it = svgFontFaceElements.begin(); it != end; ++it)
+ const WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >& svgFontFaceElements = document.svgExtensions()->svgFontFaceElements();
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >::const_iterator end = svgFontFaceElements.end();
+ for (WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >::const_iterator it = svgFontFaceElements.begin(); it != end; ++it)
addFontFaceRule(&document, document.styleEngine()->fontSelector(), (*it)->fontFaceRule());
}
#endif
}
-void StyleResolver::initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& watchedSelectors)
+void StyleResolver::initWatchedSelectorRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedSelectors)
{
if (!watchedSelectors.size())
return;
@@ -182,14 +166,14 @@ void StyleResolver::initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& w
m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState);
}
-void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
{
unsigned size = styleSheets.size();
for (unsigned i = firstNew; i < size; ++i)
m_pendingStyleSheets.add(styleSheets[i].get());
}
-void StyleResolver::removePendingAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::removePendingAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
{
for (unsigned i = 0; i < styleSheets.size(); ++i)
m_pendingStyleSheets.remove(styleSheets[i].get());
@@ -202,33 +186,31 @@ void StyleResolver::appendCSSStyleSheet(CSSStyleSheet* cssSheet)
if (cssSheet->mediaQueries() && !m_medium->eval(cssSheet->mediaQueries(), &m_viewportDependentMediaQueryResults))
return;
- StyleSheetContents* sheet = cssSheet->contents();
ContainerNode* scopingNode = ScopedStyleResolver::scopingNodeFor(document(), cssSheet);
if (!scopingNode)
return;
ScopedStyleResolver* resolver = ensureScopedStyleResolver(scopingNode);
ASSERT(resolver);
- resolver->addRulesFromSheet(sheet, *m_medium, this);
- m_inspectorCSSOMWrappers.collectFromStyleSheetIfNeeded(cssSheet);
+ resolver->addRulesFromSheet(cssSheet, *m_medium, this);
}
void StyleResolver::appendPendingAuthorStyleSheets()
{
setBuildScopedStyleTreeInDocumentOrder(false);
- for (ListHashSet<CSSStyleSheet*, 16>::iterator it = m_pendingStyleSheets.begin(); it != m_pendingStyleSheets.end(); ++it)
+ for (WillBeHeapListHashSet<RawPtrWillBeMember<CSSStyleSheet>, 16>::iterator it = m_pendingStyleSheets.begin(); it != m_pendingStyleSheets.end(); ++it)
appendCSSStyleSheet(*it);
m_pendingStyleSheets.clear();
finishAppendAuthorStyleSheets();
}
-void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::appendAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
{
// This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
// needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated.
unsigned size = styleSheets.size();
- for (unsigned i = firstNew; i < size; ++i)
+ for (unsigned i = 0; i < size; ++i)
appendCSSStyleSheet(styleSheets[i].get());
}
@@ -236,8 +218,8 @@ void StyleResolver::finishAppendAuthorStyleSheets()
{
collectFeatures();
- if (document().renderer() && document().renderer()->style())
- document().renderer()->style()->font().update(document().styleEngine()->fontSelector());
+ if (document().renderView() && document().renderView()->style())
+ document().renderView()->style()->font().update(document().styleEngine()->fontSelector());
collectViewportRules();
@@ -253,43 +235,31 @@ void StyleResolver::resetRuleFeatures()
m_needCollectFeatures = true;
}
-void StyleResolver::addTreeBoundaryCrossingRules(const Vector<MinimalRuleData>& rules, ContainerNode* scope)
+void StyleResolver::processScopedRules(const RuleSet& authorRules, CSSStyleSheet* parentStyleSheet, ContainerNode& scope)
{
- for (unsigned i = 0; i < rules.size(); ++i) {
- const MinimalRuleData& info = rules[i];
- m_treeBoundaryCrossingRules.addRule(info.m_rule, info.m_selectorIndex, scope, info.m_flags);
- }
-}
-
-void StyleResolver::processScopedRules(const RuleSet& authorRules, const KURL& sheetBaseURL, ContainerNode* scope)
-{
- const Vector<StyleRuleKeyframes*> keyframesRules = authorRules.keyframesRules();
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> > keyframesRules = authorRules.keyframesRules();
for (unsigned i = 0; i < keyframesRules.size(); ++i)
- ensureScopedStyleResolver(scope)->addKeyframeStyle(keyframesRules[i]);
+ ensureScopedStyleResolver(&scope)->addKeyframeStyle(keyframesRules[i]);
- addTreeBoundaryCrossingRules(authorRules.treeBoundaryCrossingRules(), scope);
+ m_treeBoundaryCrossingRules.addTreeBoundaryCrossingRules(authorRules, scope, parentStyleSheet);
// FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
- if (!scope || scope->isDocumentNode()) {
- const Vector<StyleRuleFontFace*> fontFaceRules = authorRules.fontFaceRules();
+ if (scope.isDocumentNode()) {
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> > fontFaceRules = authorRules.fontFaceRules();
for (unsigned i = 0; i < fontFaceRules.size(); ++i)
addFontFaceRule(&m_document, document().styleEngine()->fontSelector(), fontFaceRules[i]);
if (fontFaceRules.size())
invalidateMatchedPropertiesCache();
- } else {
- addTreeBoundaryCrossingRules(authorRules.shadowDistributedRules(), scope);
}
}
void StyleResolver::resetAuthorStyle(const ContainerNode* scopingNode)
{
- // FIXME: When chanking scoped attribute, scopingNode's hasScopedHTMLStyleChild has been already modified.
- // So we cannot use hasScopedHTMLStyleChild flag here.
ScopedStyleResolver* resolver = scopingNode ? m_styleTree.lookupScopedStyleResolverFor(scopingNode) : m_styleTree.scopedStyleResolverForDocument();
if (!resolver)
return;
- treeBoundaryCrossingRules().reset(scopingNode);
+ m_treeBoundaryCrossingRules.reset(scopingNode);
resolver->resetAuthorStyle();
resetRuleFeatures();
@@ -299,12 +269,12 @@ void StyleResolver::resetAuthorStyle(const ContainerNode* scopingNode)
m_styleTree.remove(scopingNode);
}
-static PassOwnPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
+static PassOwnPtrWillBeRawPtr<RuleSet> makeRuleSet(const WillBeHeapVector<RuleFeature>& rules)
{
size_t size = rules.size();
if (!size)
return nullptr;
- OwnPtr<RuleSet> ruleSet = RuleSet::create();
+ OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
for (size_t i = 0; i < size; ++i)
ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
return ruleSet.release();
@@ -316,11 +286,15 @@ void StyleResolver::collectFeatures()
// Collect all ids and rules using sibling selectors (:first-child and similar)
// in the current set of stylesheets. Style sharing code uses this information to reject
// sharing candidates.
- if (CSSDefaultStyleSheets::defaultStyle)
- m_features.add(CSSDefaultStyleSheets::defaultStyle->features());
+ CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
+ if (defaultStyleSheets.defaultStyle())
+ m_features.add(defaultStyleSheets.defaultStyle()->features());
if (document().isViewSource())
- m_features.add(CSSDefaultStyleSheets::viewSourceStyle()->features());
+ m_features.add(defaultStyleSheets.defaultViewSourceStyle()->features());
+
+ if (document().isTransitionDocument())
+ m_features.add(defaultStyleSheets.defaultTransitionStyle()->features());
if (m_watchedSelectorsRules)
m_features.add(m_watchedSelectorsRules->features());
@@ -336,7 +310,7 @@ void StyleResolver::collectFeatures()
bool StyleResolver::hasRulesForId(const AtomicString& id) const
{
- return m_features.idsInRules.contains(id);
+ return m_features.hasSelectorForId(id);
}
void StyleResolver::addToStyleSharingList(Element& element)
@@ -346,20 +320,29 @@ void StyleResolver::addToStyleSharingList(Element& element)
if (!document().inStyleRecalc())
return;
INCREMENT_STYLE_STATS_COUNTER(*this, sharedStyleCandidates);
- if (m_styleSharingList.size() >= styleSharingListSize)
- m_styleSharingList.remove(--m_styleSharingList.end());
- m_styleSharingList.prepend(&element);
+ StyleSharingList& list = styleSharingList();
+ if (list.size() >= styleSharingListSize)
+ list.remove(--list.end());
+ list.prepend(&element);
}
-void StyleResolver::clearStyleSharingList()
+StyleSharingList& StyleResolver::styleSharingList()
{
- m_styleSharingList.clear();
+ m_styleSharingLists.resize(styleSharingMaxDepth);
+
+ // We never put things at depth 0 into the list since that's only the <html> element
+ // and it has no siblings or cousins to share with.
+ unsigned depth = std::max(std::min(m_styleSharingDepth, styleSharingMaxDepth), 1u) - 1u;
+ ASSERT(depth >= 0);
+
+ if (!m_styleSharingLists[depth])
+ m_styleSharingLists[depth] = adoptPtr(new StyleSharingList);
+ return *m_styleSharingLists[depth];
}
-void StyleResolver::fontsNeedUpdate(FontSelector* fontSelector)
+void StyleResolver::clearStyleSharingList()
{
- invalidateMatchedPropertiesCache();
- m_document.setNeedsStyleRecalc();
+ m_styleSharingLists.resize(0);
}
void StyleResolver::pushParentElement(Element& parent)
@@ -403,39 +386,11 @@ void StyleResolver::popParentShadowRoot(const ShadowRoot& shadowRoot)
StyleResolver::~StyleResolver()
{
- m_viewportStyleResolver->clearDocument();
-}
-
-inline void StyleResolver::collectTreeBoundaryCrossingRules(Element* element, ElementRuleCollector& collector, bool includeEmptyRules)
-{
- if (m_treeBoundaryCrossingRules.isEmpty())
- return;
-
- RuleRange ruleRange = collector.matchedResult().ranges.authorRuleRange();
-
- CascadeOrder cascadeOrder = 0;
-
- DocumentOrderedList::iterator it = m_treeBoundaryCrossingRules.end();
- while (it != m_treeBoundaryCrossingRules.begin()) {
- --it;
- const ContainerNode* scopingNode = toContainerNode(*it);
- RuleSet* ruleSet = m_treeBoundaryCrossingRules.ruleSetScopedBy(scopingNode);
- unsigned boundaryBehavior = SelectorChecker::CrossesBoundary | SelectorChecker::ScopeContainsLastMatchedElement;
-
- // If a given scoping node is a shadow root and a given element is in a descendant tree of tree hosted by
- // the scoping node's shadow host, we should use ScopeIsShadowHost.
- if (scopingNode && scopingNode->isShadowRoot()) {
- if (element->isInDescendantTreeOf(toShadowRoot(scopingNode)->host()))
- boundaryBehavior |= SelectorChecker::ScopeIsShadowHost;
- scopingNode = toShadowRoot(scopingNode)->host();
- }
- collector.collectMatchingRules(MatchRequest(ruleSet, includeEmptyRules, scopingNode), ruleRange, static_cast<SelectorChecker::BehaviorAtBoundary>(boundaryBehavior), ignoreCascadeScope, cascadeOrder++);
- }
}
static inline bool applyAuthorStylesOf(const Element* element)
{
- return element->treeScope().applyAuthorStyles() || (element->shadow() && element->shadow()->applyAuthorStyles());
+ return element->treeScope().applyAuthorStyles();
}
void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleCollector& collector, bool includeEmptyRules, Vector<ScopedStyleResolver*, 8>& resolvers, Vector<ScopedStyleResolver*, 8>& resolversInShadowTree)
@@ -456,7 +411,7 @@ void StyleResolver::matchAuthorRulesForShadowHost(Element* element, ElementRuleC
for (unsigned i = 0; i < resolvers.size(); ++i)
resolvers.at(i)->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, --cascadeOrder);
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
+ m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
collector.sortAndTransferMatchedRules();
}
@@ -468,7 +423,7 @@ void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col
bool applyAuthorStyles = applyAuthorStylesOf(element);
if (m_styleTree.hasOnlyScopedResolverForDocument()) {
m_styleTree.scopedStyleResolverForDocument()->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, ignoreCascadeScope);
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
+ m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
collector.sortAndTransferMatchedRules();
return;
}
@@ -494,7 +449,7 @@ void StyleResolver::matchAuthorRules(Element* element, ElementRuleCollector& col
resolver->collectMatchingAuthorRules(collector, includeEmptyRules, applyAuthorStyles, cascadeScope++, resolver->treeScope() == element->treeScope() && resolver->scopingNode().isShadowRoot() ? 0 : cascadeOrder);
}
- collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
+ m_treeBoundaryCrossingRules.collectTreeBoundaryCrossingRules(element, collector, includeEmptyRules);
collector.sortAndTransferMatchedRules();
}
@@ -509,7 +464,6 @@ void StyleResolver::matchWatchSelectorRules(ElementRuleCollector& collector)
MatchRequest matchRequest(m_watchedSelectorsRules.get());
RuleRange ruleRange = collector.matchedResult().ranges.userRuleRange();
collector.collectMatchingRules(matchRequest, ruleRange);
- collector.collectMatchingRulesForRegion(matchRequest, ruleRange);
collector.sortAndTransferMatchedRules();
}
@@ -518,17 +472,21 @@ void StyleResolver::matchUARules(ElementRuleCollector& collector)
{
collector.setMatchingUARules(true);
+ CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
RuleSet* userAgentStyleSheet = m_medium->mediaTypeMatchSpecific("print")
- ? CSSDefaultStyleSheets::defaultPrintStyle : CSSDefaultStyleSheets::defaultStyle;
+ ? defaultStyleSheets.defaultPrintStyle() : defaultStyleSheets.defaultStyle();
matchUARules(collector, userAgentStyleSheet);
// In quirks mode, we match rules from the quirks user agent sheet.
if (document().inQuirksMode())
- matchUARules(collector, CSSDefaultStyleSheets::defaultQuirksStyle);
+ matchUARules(collector, defaultStyleSheets.defaultQuirksStyle());
// If document uses view source styles (in view source mode or in xml viewer mode), then we match rules from the view source style sheet.
if (document().isViewSource())
- matchUARules(collector, CSSDefaultStyleSheets::viewSourceStyle());
+ matchUARules(collector, defaultStyleSheets.defaultViewSourceStyle());
+
+ if (document().isTransitionDocument())
+ matchUARules(collector, defaultStyleSheets.defaultTransitionStyle());
collector.setMatchingUARules(false);
@@ -582,33 +540,20 @@ void StyleResolver::matchAllRules(StyleResolverState& state, ElementRuleCollecto
}
}
-PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document, CSSFontSelector* fontSelector)
+PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document)
{
- const Frame* frame = document.frame();
+ const LocalFrame* frame = document.frame();
- // HTML5 states that seamless iframes should replace default CSS values
- // with values inherited from the containing iframe element. However,
- // some values (such as the case of designMode = "on") still need to
- // be set by this "document style".
RefPtr<RenderStyle> documentStyle = RenderStyle::create();
- bool seamlessWithParent = document.shouldDisplaySeamlesslyWithParent();
- if (seamlessWithParent) {
- RenderStyle* iframeStyle = document.seamlessParentIFrame()->renderStyle();
- if (iframeStyle)
- documentStyle->inheritFrom(iframeStyle);
- }
-
- // FIXME: It's not clear which values below we want to override in the seamless case!
documentStyle->setDisplay(BLOCK);
- if (!seamlessWithParent) {
- documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : LogicalOrder);
- documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() : 1);
- documentStyle->setLocale(document.contentLanguage());
- }
- // This overrides any -webkit-user-modify inherited from the parent iframe.
+ documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : LogicalOrder);
+ documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() : 1);
+ documentStyle->setLocale(document.contentLanguage());
+ documentStyle->setZIndex(0);
documentStyle->setUserModify(document.inDesignMode() ? READ_WRITE : READ_ONLY);
- document.setStyleDependentState(documentStyle.get());
+ document.setupFontBuilder(documentStyle.get());
+
return documentStyle.release();
}
@@ -631,11 +576,24 @@ static inline void resetDirectionAndWritingModeOnDocument(Document& document)
static void addContentAttrValuesToFeatures(const Vector<AtomicString>& contentAttrValues, RuleFeatureSet& features)
{
for (size_t i = 0; i < contentAttrValues.size(); ++i)
- features.attrsInRules.add(contentAttrValues[i]);
+ features.addContentAttr(contentAttrValues[i]);
+}
+
+void StyleResolver::adjustRenderStyle(StyleResolverState& state, Element* element)
+{
+ StyleAdjuster adjuster(m_document.inQuirksMode());
+ adjuster.adjustRenderStyle(state.style(), state.parentStyle(), element, state.cachedUAStyle());
+}
+
+// Start loading resources referenced by this style.
+void StyleResolver::loadPendingResources(StyleResolverState& state)
+{
+ m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
+ document().styleEngine()->fontSelector()->fontLoader()->loadPendingFonts();
}
PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderStyle* defaultParent, StyleSharingBehavior sharingBehavior,
- RuleMatchingBehavior matchingBehavior, RenderRegion* regionForStyling)
+ RuleMatchingBehavior matchingBehavior)
{
ASSERT(document().frame());
ASSERT(documentSettings());
@@ -644,23 +602,26 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
// Once an element has a renderer, we don't try to destroy it, since otherwise the renderer
// will vanish if a style recalc happens during loading.
- if (sharingBehavior == AllowStyleSharing && !element->document().haveStylesheetsLoaded() && !element->renderer()) {
+ if (sharingBehavior == AllowStyleSharing && !document().isRenderingReady() && !element->renderer()) {
if (!s_styleNotYetAvailable) {
s_styleNotYetAvailable = RenderStyle::create().leakRef();
s_styleNotYetAvailable->setDisplay(NONE);
s_styleNotYetAvailable->font().update(document().styleEngine()->fontSelector());
}
- element->document().setHasNodesWithPlaceholderStyle();
+
+ document().setHasNodesWithPlaceholderStyle();
return s_styleNotYetAvailable;
}
didAccess();
+ StyleResolverParentScope::ensureParentStackIsPushed();
+
if (element == document().documentElement())
resetDirectionAndWritingModeOnDocument(document());
- StyleResolverState state(document(), element, defaultParent, regionForStyling);
+ StyleResolverState state(document(), element, defaultParent);
- if (sharingBehavior == AllowStyleSharing && !state.distributedToInsertionPoint() && state.parentStyle()) {
+ if (sharingBehavior == AllowStyleSharing && state.parentStyle()) {
SharedStyleFinder styleFinder(state.elementContext(), m_features, m_siblingRuleSet.get(), m_uncommonAttributeRuleSet.get(), *this);
if (RefPtr<RenderStyle> sharedStyle = styleFinder.findSharedStyle())
return sharedStyle.release();
@@ -682,7 +643,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
}
}
- state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
if (element->isLink()) {
state.style()->setIsLink(true);
@@ -696,41 +657,40 @@ PassRefPtr<RenderStyle> StyleResolver::styleForElement(Element* element, RenderS
}
bool needsCollection = false;
- CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(element, needsCollection);
- if (needsCollection) {
+ CSSDefaultStyleSheets::instance().ensureDefaultStyleSheetsForElement(element, needsCollection);
+ if (needsCollection)
collectFeatures();
- m_inspectorCSSOMWrappers.reset();
- }
{
ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
- collector.setRegionForStyling(regionForStyling);
- if (matchingBehavior == MatchOnlyUserAgentRules)
- matchUARules(collector);
- else
- matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludingSMIL);
+ matchAllRules(state, collector, matchingBehavior != MatchAllRulesExcludingSMIL);
applyMatchedProperties(state, collector.matchedResult());
addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
}
- {
- StyleAdjuster adjuster(state.cachedUAStyle(), m_document.inQuirksMode());
- adjuster.adjustRenderStyle(state.style(), state.parentStyle(), element);
- }
+
+ // Cache our original display.
+ state.style()->setOriginalDisplay(state.style()->display());
+
+ adjustRenderStyle(state, element);
// FIXME: The CSSWG wants to specify that the effects of animations are applied before
// important rules, but this currently happens here as we require adjustment to have happened
// before deciding which properties to transition.
- applyAnimatedProperties(state, element);
+ if (applyAnimatedProperties(state, element))
+ adjustRenderStyle(state, element);
// FIXME: Shouldn't this be on RenderBody::styleDidChange?
- if (element->hasTagName(bodyTag))
+ if (isHTMLBodyElement(*element))
document().textLinkColors().setTextColor(state.style()->color());
setAnimationUpdateIfNeeded(state, *element);
+ if (state.style()->hasViewportUnits())
+ document().setHasViewportUnits();
+
// Now return the style.
return state.takeStyle();
}
@@ -746,8 +706,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* element, const
StyleResolverState state(document(), element, parentStyle);
MatchResult result;
- if (keyframe->properties())
- result.addMatchedProperties(keyframe->properties());
+ result.addMatchedProperties(&keyframe->properties());
ASSERT(!state.style());
@@ -755,28 +714,15 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* element, const
state.setStyle(RenderStyle::clone(&elementStyle));
state.setLineHeightValue(0);
- // Make sure that the CSSAnimationData for the animation to which this
- // keyframe belongs is first in the list. This makes sure that if the
- // animation-timing-function property is set for this keyframe, it will be
- // applied to the correct CSSAnimationData object. Note that objects other
- // than the first in the list are ignored when reading the timing function
- // value. See KeyframeValue::timingFunction().
- CSSAnimationDataList* animations = state.style()->accessAnimations();
- ASSERT(animations && !animations->isEmpty());
- while (animations->animation(0)->name() != animationName)
- animations->remove(0);
- ASSERT(!animations->isEmpty() && animations->animation(0)->name() == animationName);
-
- state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
// We don't need to bother with !important. Since there is only ever one
// decl, there's nothing to override. So just add the first properties.
+ // We also don't need to bother with animation properties since the only
+ // relevant one is animation-timing-function and we special-case that in
+ // CSSAnimations.cpp
bool inheritedOnly = false;
- if (keyframe->properties()) {
- // FIXME: Can't keyframes contain variables?
- applyMatchedProperties<AnimationProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
- applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
- }
+ applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
// If our font got dirtied, go ahead and update it now.
updateFont(state);
@@ -786,124 +732,73 @@ PassRefPtr<RenderStyle> StyleResolver::styleForKeyframe(Element* element, const
StyleBuilder::applyProperty(CSSPropertyLineHeight, state, state.lineHeightValue());
// Now do rest of the properties.
- if (keyframe->properties())
- applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
+ applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
// If our font got dirtied by one of the non-essential font props,
// go ahead and update it a second time.
updateFont(state);
- // Start loading resources referenced by this style.
- m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
- document().styleEngine()->fontSelector()->loadPendingFonts();
+ loadPendingResources(state);
didAccess();
return state.takeStyle();
}
-void StyleResolver::keyframeStylesForAnimation(Element* e, const RenderStyle& elementStyle, KeyframeList& list)
-{
- ASSERT(!RuntimeEnabledFeatures::webAnimationsCSSEnabled());
- list.clear();
-
- // Get the keyframesRule for this name
- if (!e || list.animationName().isEmpty())
- return;
-
- ASSERT(!hasPendingAuthorStyleSheets());
- const StyleRuleKeyframes* keyframesRule = CSSAnimations::matchScopedKeyframesRule(this, e, list.animationName().impl());
- if (!keyframesRule)
- return;
-
- // Construct and populate the style for each keyframe
- const AtomicString& name = list.animationName();
- const Vector<RefPtr<StyleKeyframe> >& keyframes = keyframesRule->keyframes();
- for (unsigned i = 0; i < keyframes.size(); ++i) {
- // Apply the declaration to the style. This is a simplified version of the logic in styleForElement
- const StyleKeyframe* keyframe = keyframes[i].get();
-
- KeyframeValue keyframeValue(0, 0);
- keyframeValue.setStyle(styleForKeyframe(e, elementStyle, 0, keyframe, name));
- keyframeValue.addProperties(keyframe->properties());
-
- // Add this keyframe style to all the indicated key times
- const Vector<double>& keys = keyframe->keys();
- for (size_t keyIndex = 0; keyIndex < keys.size(); ++keyIndex) {
- keyframeValue.setKey(keys[keyIndex]);
- list.insert(keyframeValue);
- }
- }
-
- // If the 0% keyframe is missing, create it (but only if there is at least one other keyframe)
- int initialListSize = list.size();
- if (initialListSize > 0 && list[0].key()) {
- static StyleKeyframe* zeroPercentKeyframe;
- if (!zeroPercentKeyframe) {
- zeroPercentKeyframe = StyleKeyframe::create().leakRef();
- zeroPercentKeyframe->setKeyText("0%");
- }
- KeyframeValue keyframeValue(0, 0);
- keyframeValue.setStyle(styleForKeyframe(e, elementStyle, 0, zeroPercentKeyframe, name));
- keyframeValue.addProperties(zeroPercentKeyframe->properties());
- list.insert(keyframeValue);
- }
-
- // If the 100% keyframe is missing, create it (but only if there is at least one other keyframe)
- if (initialListSize > 0 && (list[list.size() - 1].key() != 1)) {
- static StyleKeyframe* hundredPercentKeyframe;
- if (!hundredPercentKeyframe) {
- hundredPercentKeyframe = StyleKeyframe::create().leakRef();
- hundredPercentKeyframe->setKeyText("100%");
- }
- KeyframeValue keyframeValue(1, 0);
- keyframeValue.setStyle(styleForKeyframe(e, elementStyle, 0, hundredPercentKeyframe, name));
- keyframeValue.addProperties(hundredPercentKeyframe->properties());
- list.insert(keyframeValue);
- }
-}
-
// This function is used by the WebAnimations JavaScript API method animate().
// FIXME: Remove this when animate() switches away from resolution-dependent parsing.
-PassRefPtr<KeyframeAnimationEffect> StyleResolver::createKeyframeAnimationEffect(Element& element, const Vector<RefPtr<MutableStylePropertySet> >& propertySetVector, KeyframeAnimationEffect::KeyframeVector& keyframes)
+PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot(Element& element, CSSPropertyID property, CSSValue& value)
{
- ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
- ASSERT(propertySetVector.size() == keyframes.size());
-
+ RefPtr<RenderStyle> style;
+ if (element.renderStyle())
+ style = RenderStyle::clone(element.renderStyle());
+ else
+ style = RenderStyle::create();
StyleResolverState state(element.document(), &element);
- state.setStyle(RenderStyle::create());
+ state.setStyle(style);
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
+ return createAnimatableValueSnapshot(state, property, value);
+}
- for (unsigned i = 0; i < propertySetVector.size(); ++i) {
- for (unsigned j = 0; j < propertySetVector[i]->propertyCount(); ++j) {
- CSSPropertyID id = propertySetVector[i]->propertyAt(j).id();
- StyleBuilder::applyProperty(id, state, propertySetVector[i]->getPropertyCSSValue(id).get());
- keyframes[i]->setPropertyValue(id, CSSAnimatableValueFactory::create(id, *state.style()).get());
- }
- }
- return KeyframeAnimationEffect::create(keyframes);
+PassRefPtrWillBeRawPtr<AnimatableValue> StyleResolver::createAnimatableValueSnapshot(StyleResolverState& state, CSSPropertyID property, CSSValue& value)
+{
+ StyleBuilder::applyProperty(property, state, &value);
+ return CSSAnimatableValueFactory::create(property, *state.style());
}
-PassRefPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& element, PseudoId pseudoId)
+PassRefPtrWillBeRawPtr<PseudoElement> StyleResolver::createPseudoElementIfNeeded(Element& parent, PseudoId pseudoId)
{
- RenderObject* renderer = element.renderer();
- if (!renderer)
- return 0;
+ RenderObject* parentRenderer = parent.renderer();
+ if (!parentRenderer)
+ return nullptr;
+
+ if (pseudoId < FIRST_INTERNAL_PSEUDOID && !parentRenderer->style()->hasPseudoStyle(pseudoId))
+ return nullptr;
- if (pseudoId < FIRST_INTERNAL_PSEUDOID && !renderer->style()->hasPseudoStyle(pseudoId))
- return 0;
+ if (pseudoId == BACKDROP && !parent.isInTopLayer())
+ return nullptr;
+
+ if (!parentRenderer->canHaveGeneratedChildren())
+ return nullptr;
- RenderStyle* parentStyle = renderer->style();
- StyleResolverState state(document(), &element, parentStyle);
- if (!pseudoStyleForElementInternal(element, pseudoId, parentStyle, state))
- return 0;
+ RenderStyle* parentStyle = parentRenderer->style();
+ if (RenderStyle* cachedStyle = parentStyle->getCachedPseudoStyle(pseudoId)) {
+ if (!pseudoElementRendererIsNeeded(cachedStyle))
+ return nullptr;
+ return PseudoElement::create(&parent, pseudoId);
+ }
+
+ StyleResolverState state(document(), &parent, parentStyle);
+ if (!pseudoStyleForElementInternal(parent, pseudoId, parentStyle, state))
+ return nullptr;
RefPtr<RenderStyle> style = state.takeStyle();
ASSERT(style);
+ parentStyle->addCachedPseudoStyle(style);
- if (!element.needsPseudoElement(pseudoId, *style))
- return 0;
+ if (!pseudoElementRendererIsNeeded(style.get()))
+ return nullptr;
- renderer->style()->addCachedPseudoStyle(style.release());
- RefPtr<PseudoElement> pseudo = PseudoElement::create(&element, pseudoId);
+ RefPtrWillBeRawPtr<PseudoElement> pseudo = PseudoElement::create(&parent, pseudoId);
setAnimationUpdateIfNeeded(state, *pseudo);
if (ActiveAnimations* activeAnimations = pseudo->activeAnimations())
@@ -917,6 +812,8 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo
ASSERT(documentSettings());
ASSERT(pseudoStyleRequest.pseudoId != FIRST_LINE_INHERITED);
+ StyleResolverParentScope::ensureParentStackIsPushed();
+
if (pseudoStyleRequest.allowsInheritance(state.parentStyle())) {
state.setStyle(RenderStyle::create());
state.style()->inheritFrom(state.parentStyle());
@@ -925,7 +822,7 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo
state.setParentStyle(RenderStyle::clone(state.style()));
}
- state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
// Since we don't use pseudo-elements in any of our quirk/print
// user agent rules, don't waste time walking those rules.
@@ -947,20 +844,25 @@ bool StyleResolver::pseudoStyleForElementInternal(Element& element, const Pseudo
addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
}
- {
- StyleAdjuster adjuster(state.cachedUAStyle(), m_document.inQuirksMode());
- // FIXME: Passing 0 as the Element* introduces a lot of complexity
- // in the adjustRenderStyle code.
- adjuster.adjustRenderStyle(state.style(), state.parentStyle(), 0);
- }
+
+ // Cache our original display.
+ state.style()->setOriginalDisplay(state.style()->display());
+
+ // FIXME: Passing 0 as the Element* introduces a lot of complexity
+ // in the adjustRenderStyle code.
+ adjustRenderStyle(state, 0);
// FIXME: The CSSWG wants to specify that the effects of animations are applied before
// important rules, but this currently happens here as we require adjustment to have happened
// before deciding which properties to transition.
- applyAnimatedProperties(state, element.pseudoElement(pseudoStyleRequest.pseudoId));
+ if (applyAnimatedProperties(state, element.pseudoElement(pseudoStyleRequest.pseudoId)))
+ adjustRenderStyle(state, 0);
didAccess();
+ if (state.style()->hasViewportUnits())
+ document().setHasViewportUnits();
+
return true;
}
@@ -968,11 +870,11 @@ PassRefPtr<RenderStyle> StyleResolver::pseudoStyleForElement(Element* element, c
{
ASSERT(parentStyle);
if (!element)
- return 0;
+ return nullptr;
StyleResolverState state(document(), element, parentStyle);
if (!pseudoStyleForElementInternal(*element, pseudoStyleRequest, parentStyle, state))
- return 0;
+ return nullptr;
if (PseudoElement* pseudoElement = element->pseudoElement(pseudoStyleRequest.pseudoId))
setAnimationUpdateIfNeeded(state, *pseudoElement);
@@ -992,11 +894,11 @@ PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
ASSERT(rootElementStyle);
state.style()->inheritFrom(rootElementStyle);
- state.fontBuilder().initForStyleResolve(state.document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(state.document(), state.style());
PageRuleCollector collector(rootElementStyle, pageIndex);
- collector.matchPageRules(CSSDefaultStyleSheets::defaultPrintStyle);
+ collector.matchPageRules(CSSDefaultStyleSheets::instance().defaultPrintStyle());
if (ScopedStyleResolver* scopedResolver = m_styleTree.scopedStyleResolverForDocument())
scopedResolver->matchPageRules(collector);
@@ -1005,7 +907,6 @@ PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
bool inheritedOnly = false;
MatchResult& result = collector.matchedResult();
- applyMatchedProperties<VariableDefinitions>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
// If our font got dirtied, go ahead and update it now.
@@ -1019,9 +920,7 @@ PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
addContentAttrValuesToFeatures(state.contentAttrValues(), m_features);
- // Start loading resources referenced by this style.
- m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
- document().styleEngine()->fontSelector()->loadPendingFonts();
+ loadPendingResources(state);
didAccess();
@@ -1031,13 +930,14 @@ PassRefPtr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
void StyleResolver::collectViewportRules()
{
- viewportStyleResolver()->collectViewportRules(CSSDefaultStyleSheets::defaultStyle, ViewportStyleResolver::UserAgentOrigin);
+ CSSDefaultStyleSheets& defaultStyleSheets = CSSDefaultStyleSheets::instance();
+ viewportStyleResolver()->collectViewportRules(defaultStyleSheets.defaultStyle(), ViewportStyleResolver::UserAgentOrigin);
if (!InspectorInstrumentation::applyViewportStyleOverride(&document(), this))
- viewportStyleResolver()->collectViewportRules(CSSDefaultStyleSheets::defaultViewportStyle, ViewportStyleResolver::UserAgentOrigin);
+ viewportStyleResolver()->collectViewportRules(defaultStyleSheets.defaultViewportStyle(), ViewportStyleResolver::UserAgentOrigin);
if (document().isMobileDocument())
- viewportStyleResolver()->collectViewportRules(CSSDefaultStyleSheets::xhtmlMobileProfileStyle(), ViewportStyleResolver::UserAgentOrigin);
+ viewportStyleResolver()->collectViewportRules(defaultStyleSheets.defaultXHTMLMobileProfileStyle(), ViewportStyleResolver::UserAgentOrigin);
if (ScopedStyleResolver* scopedResolver = m_styleTree.scopedStyleResolverForDocument())
scopedResolver->collectViewportRulesTo(this);
@@ -1049,7 +949,7 @@ PassRefPtr<RenderStyle> StyleResolver::defaultStyleForElement()
{
StyleResolverState state(document(), 0);
state.setStyle(RenderStyle::create());
- state.fontBuilder().initForStyleResolve(document(), state.style(), state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(document(), state.style());
state.style()->setLineHeight(RenderStyle::initialLineHeight());
state.setLineHeightValue(0);
state.fontBuilder().setInitial(state.style()->effectiveZoom());
@@ -1063,28 +963,19 @@ PassRefPtr<RenderStyle> StyleResolver::styleForText(Text* textNode)
NodeRenderingTraversal::ParentDetails parentDetails;
Node* parentNode = NodeRenderingTraversal::parent(textNode, &parentDetails);
- if (!parentNode || !parentNode->renderStyle() || parentDetails.resetStyleInheritance())
+ if (!parentNode || !parentNode->renderStyle())
return defaultStyleForElement();
return parentNode->renderStyle();
}
-bool StyleResolver::checkRegionStyle(Element* regionElement)
-{
- // FIXME (BUG 72472): We don't add @-webkit-region rules of scoped style sheets for the moment,
- // so all region rules are global by default. Verify whether that can stand or needs changing.
- if (ScopedStyleResolver* scopedResolver = m_styleTree.scopedStyleResolverForDocument()) {
- if (scopedResolver->checkRegionStyle(regionElement))
- return true;
- }
- return false;
-}
-
void StyleResolver::updateFont(StyleResolverState& state)
{
state.fontBuilder().createFont(document().styleEngine()->fontSelector(), state.parentStyle(), state.style());
+ if (state.fontBuilder().fontSizeHasViewportUnits())
+ state.style()->setHasViewportUnits();
}
-PassRefPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element, unsigned rulesToInclude)
{
ASSERT(element);
StyleResolverState state(document(), element);
@@ -1094,19 +985,19 @@ PassRefPtr<StyleRuleList> StyleResolver::styleRulesForElement(Element* element,
return collector.matchedStyleRuleList();
}
-PassRefPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude, ShouldIncludeStyleSheetInCSSOMWrapper includeDocument)
+PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude)
{
ASSERT(element);
StyleResolverState state(document(), element);
- ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style(), includeDocument);
+ ElementRuleCollector collector(state.elementContext(), m_selectorFilter, state.style());
collector.setMode(SelectorChecker::CollectingCSSRules);
collectPseudoRulesForElement(element, collector, pseudoId, rulesToInclude);
return collector.matchedCSSRuleList();
}
-PassRefPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude, ShouldIncludeStyleSheetInCSSOMWrapper includeDocument)
+PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude)
{
- return pseudoCSSRulesForElement(element, NOPSEUDO, rulesToInclude, includeDocument);
+ return pseudoCSSRulesForElement(element, NOPSEUDO, rulesToInclude);
}
void StyleResolver::collectPseudoRulesForElement(Element* element, ElementRuleCollector& collector, PseudoId pseudoId, unsigned rulesToInclude)
@@ -1125,11 +1016,8 @@ void StyleResolver::collectPseudoRulesForElement(Element* element, ElementRuleCo
// -------------------------------------------------------------------------------------
// this is mostly boring stuff on how to apply a certain rule to the renderstyle...
-void StyleResolver::applyAnimatedProperties(StyleResolverState& state, Element* animatingElement)
+bool StyleResolver::applyAnimatedProperties(StyleResolverState& state, Element* animatingElement)
{
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- return;
-
const Element* element = state.element();
ASSERT(element);
@@ -1139,61 +1027,45 @@ void StyleResolver::applyAnimatedProperties(StyleResolverState& state, Element*
ASSERT(animatingElement == element || !animatingElement || animatingElement->parentOrShadowHostElement() == element);
if (!(animatingElement && animatingElement->hasActiveAnimations())
- && !(state.style()->transitions() && !state.style()->transitions()->isEmpty())
- && !(state.style()->animations() && !state.style()->animations()->isEmpty()))
- return;
+ && !state.style()->transitions() && !state.style()->animations())
+ return false;
state.setAnimationUpdate(CSSAnimations::calculateUpdate(animatingElement, *element, *state.style(), state.parentStyle(), this));
if (!state.animationUpdate())
- return;
+ return false;
+
+ const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForAnimations = state.animationUpdate()->activeInterpolationsForAnimations();
+ const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolationsForTransitions = state.animationUpdate()->activeInterpolationsForTransitions();
+ applyAnimatedProperties<HighPriorityProperties>(state, activeInterpolationsForAnimations);
+ applyAnimatedProperties<HighPriorityProperties>(state, activeInterpolationsForTransitions);
+
+ updateFont(state);
+
+ applyAnimatedProperties<LowPriorityProperties>(state, activeInterpolationsForAnimations);
+ applyAnimatedProperties<LowPriorityProperties>(state, activeInterpolationsForTransitions);
+
+ // Start loading resources used by animations.
+ loadPendingResources(state);
- const AnimationEffect::CompositableValueMap& compositableValuesForAnimations = state.animationUpdate()->compositableValuesForAnimations();
- const AnimationEffect::CompositableValueMap& compositableValuesForTransitions = state.animationUpdate()->compositableValuesForTransitions();
- applyAnimatedProperties<HighPriorityProperties>(state, compositableValuesForAnimations);
- applyAnimatedProperties<HighPriorityProperties>(state, compositableValuesForTransitions);
- applyAnimatedProperties<LowPriorityProperties>(state, compositableValuesForAnimations);
- applyAnimatedProperties<LowPriorityProperties>(state, compositableValuesForTransitions);
+ ASSERT(!state.fontBuilder().fontDirty());
- // If the animations/transitions change opacity or transform, we need to update
- // the style to impose the stacking rules. Note that this is also
- // done in StyleResolver::adjustRenderStyle().
- RenderStyle* style = state.style();
- if (style->hasAutoZIndex() && (style->opacity() < 1.0f || style->hasTransform()))
- style->setZIndex(0);
+ return true;
}
template <StyleResolver::StyleApplicationPass pass>
-void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const AnimationEffect::CompositableValueMap& compositableValues)
+void StyleResolver::applyAnimatedProperties(StyleResolverState& state, const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >& activeInterpolations)
{
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
- ASSERT(pass != VariableDefinitions);
ASSERT(pass != AnimationProperties);
- for (AnimationEffect::CompositableValueMap::const_iterator iter = compositableValues.begin(); iter != compositableValues.end(); ++iter) {
+ for (WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >::const_iterator iter = activeInterpolations.begin(); iter != activeInterpolations.end(); ++iter) {
CSSPropertyID property = iter->key;
if (!isPropertyForPass<pass>(property))
continue;
- ASSERT_WITH_MESSAGE(!iter->value->dependsOnUnderlyingValue(), "Web Animations not yet implemented: An interface for compositing onto the underlying value.");
- RefPtr<AnimatableValue> animatableValue = iter->value->compositeOnto(0);
- AnimatedStyleBuilder::applyProperty(property, state, animatableValue.get());
+ const StyleInterpolation* interpolation = toStyleInterpolation(iter->value.get());
+ interpolation->apply(state);
}
}
-// http://dev.w3.org/csswg/css3-regions/#the-at-region-style-rule
-// FIXME: add incremental support for other region styling properties.
-static inline bool isValidRegionStyleProperty(CSSPropertyID id)
-{
- switch (id) {
- case CSSPropertyBackgroundColor:
- case CSSPropertyColor:
- return true;
- default:
- break;
- }
-
- return false;
-}
-
static inline bool isValidCueStyleProperty(CSSPropertyID id)
{
switch (id) {
@@ -1242,36 +1114,237 @@ static inline bool isValidCueStyleProperty(CSSPropertyID id)
return false;
}
+static inline bool isValidFirstLetterStyleProperty(CSSPropertyID id)
+{
+ switch (id) {
+ // Valid ::first-letter properties listed in spec:
+ // http://www.w3.org/TR/css3-selectors/#application-in-css
+ case CSSPropertyBackgroundAttachment:
+ case CSSPropertyBackgroundBlendMode:
+ case CSSPropertyBackgroundClip:
+ case CSSPropertyBackgroundColor:
+ case CSSPropertyBackgroundImage:
+ case CSSPropertyBackgroundOrigin:
+ case CSSPropertyBackgroundPosition:
+ case CSSPropertyBackgroundPositionX:
+ case CSSPropertyBackgroundPositionY:
+ case CSSPropertyBackgroundRepeat:
+ case CSSPropertyBackgroundRepeatX:
+ case CSSPropertyBackgroundRepeatY:
+ case CSSPropertyBackgroundSize:
+ case CSSPropertyBorderBottomColor:
+ case CSSPropertyBorderBottomLeftRadius:
+ case CSSPropertyBorderBottomRightRadius:
+ case CSSPropertyBorderBottomStyle:
+ case CSSPropertyBorderBottomWidth:
+ case CSSPropertyBorderImageOutset:
+ case CSSPropertyBorderImageRepeat:
+ case CSSPropertyBorderImageSlice:
+ case CSSPropertyBorderImageSource:
+ case CSSPropertyBorderImageWidth:
+ case CSSPropertyBorderLeftColor:
+ case CSSPropertyBorderLeftStyle:
+ case CSSPropertyBorderLeftWidth:
+ case CSSPropertyBorderRightColor:
+ case CSSPropertyBorderRightStyle:
+ case CSSPropertyBorderRightWidth:
+ case CSSPropertyBorderTopColor:
+ case CSSPropertyBorderTopLeftRadius:
+ case CSSPropertyBorderTopRightRadius:
+ case CSSPropertyBorderTopStyle:
+ case CSSPropertyBorderTopWidth:
+ case CSSPropertyColor:
+ case CSSPropertyFloat:
+ case CSSPropertyFont:
+ case CSSPropertyFontFamily:
+ case CSSPropertyFontKerning:
+ case CSSPropertyFontSize:
+ case CSSPropertyFontStretch:
+ case CSSPropertyFontStyle:
+ case CSSPropertyFontVariant:
+ case CSSPropertyFontVariantLigatures:
+ case CSSPropertyFontWeight:
+ case CSSPropertyLetterSpacing:
+ case CSSPropertyLineHeight:
+ case CSSPropertyMarginBottom:
+ case CSSPropertyMarginLeft:
+ case CSSPropertyMarginRight:
+ case CSSPropertyMarginTop:
+ case CSSPropertyPaddingBottom:
+ case CSSPropertyPaddingLeft:
+ case CSSPropertyPaddingRight:
+ case CSSPropertyPaddingTop:
+ case CSSPropertyTextTransform:
+ case CSSPropertyVerticalAlign:
+ case CSSPropertyWebkitBackgroundClip:
+ case CSSPropertyWebkitBackgroundComposite:
+ case CSSPropertyWebkitBackgroundOrigin:
+ case CSSPropertyWebkitBackgroundSize:
+ case CSSPropertyWebkitBorderAfter:
+ case CSSPropertyWebkitBorderAfterColor:
+ case CSSPropertyWebkitBorderAfterStyle:
+ case CSSPropertyWebkitBorderAfterWidth:
+ case CSSPropertyWebkitBorderBefore:
+ case CSSPropertyWebkitBorderBeforeColor:
+ case CSSPropertyWebkitBorderBeforeStyle:
+ case CSSPropertyWebkitBorderBeforeWidth:
+ case CSSPropertyWebkitBorderEnd:
+ case CSSPropertyWebkitBorderEndColor:
+ case CSSPropertyWebkitBorderEndStyle:
+ case CSSPropertyWebkitBorderEndWidth:
+ case CSSPropertyWebkitBorderFit:
+ case CSSPropertyWebkitBorderHorizontalSpacing:
+ case CSSPropertyWebkitBorderImage:
+ case CSSPropertyWebkitBorderRadius:
+ case CSSPropertyWebkitBorderStart:
+ case CSSPropertyWebkitBorderStartColor:
+ case CSSPropertyWebkitBorderStartStyle:
+ case CSSPropertyWebkitBorderStartWidth:
+ case CSSPropertyWebkitBorderVerticalSpacing:
+ case CSSPropertyWebkitFontSmoothing:
+ case CSSPropertyWebkitMarginAfter:
+ case CSSPropertyWebkitMarginAfterCollapse:
+ case CSSPropertyWebkitMarginBefore:
+ case CSSPropertyWebkitMarginBeforeCollapse:
+ case CSSPropertyWebkitMarginBottomCollapse:
+ case CSSPropertyWebkitMarginCollapse:
+ case CSSPropertyWebkitMarginEnd:
+ case CSSPropertyWebkitMarginStart:
+ case CSSPropertyWebkitMarginTopCollapse:
+ case CSSPropertyWordSpacing:
+ return true;
+ case CSSPropertyTextDecorationColor:
+ case CSSPropertyTextDecorationLine:
+ case CSSPropertyTextDecorationStyle:
+ return RuntimeEnabledFeatures::css3TextDecorationsEnabled();
+
+ // text-shadow added in text decoration spec:
+ // http://www.w3.org/TR/css-text-decor-3/#text-shadow-property
+ case CSSPropertyTextShadow:
+ // box-shadox added in CSS3 backgrounds spec:
+ // http://www.w3.org/TR/css3-background/#placement
+ case CSSPropertyBoxShadow:
+ case CSSPropertyWebkitBoxShadow:
+ // Properties that we currently support outside of spec.
+ case CSSPropertyWebkitLineBoxContain:
+ case CSSPropertyVisibility:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+// FIXME: Consider refactoring to create a new class which owns the following
+// first/last/range properties.
+// This method returns the first CSSPropertyId of properties which generate
+// animations. All animation properties are obtained by using
+// firstCSSPropertyId<AnimationProperties> and
+// lastCSSPropertyId<AnimationProperties>.
+// c.f. //src/third_party/WebKit/Source/core/css/CSSPropertyNames.in.
+template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::AnimationProperties>()
+{
+ COMPILE_ASSERT(firstCSSProperty == CSSPropertyDisplay, CSS_first_animation_property_should_be_first_property);
+ return CSSPropertyDisplay;
+}
+
+// This method returns the first CSSPropertyId of properties which generate
+// animations.
+template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::AnimationProperties>()
+{
+ COMPILE_ASSERT(CSSPropertyTransitionTimingFunction == CSSPropertyColor - 1, CSS_transition_timing_is_last_animation_property);
+ return CSSPropertyTransitionTimingFunction;
+}
+
+// This method returns the first CSSPropertyId of high priority properties.
+// Other properties can depend on high priority properties. For example,
+// border-color property with currentColor value depends on color property.
+// All high priority properties are obtained by using
+// firstCSSPropertyId<HighPriorityProperties> and
+// lastCSSPropertyId<HighPriorityProperties>.
+template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::HighPriorityProperties>()
+{
+ COMPILE_ASSERT(CSSPropertyTransitionTimingFunction + 1 == CSSPropertyColor, CSS_color_is_first_high_priority_property);
+ return CSSPropertyColor;
+}
+
+// This method returns the last CSSPropertyId of high priority properties.
+template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::HighPriorityProperties>()
+{
+ COMPILE_ASSERT(CSSPropertyLineHeight == CSSPropertyColor + 17, CSS_line_height_is_end_of_high_prioity_property_range);
+ COMPILE_ASSERT(CSSPropertyZoom == CSSPropertyLineHeight - 1, CSS_zoom_is_before_line_height);
+ return CSSPropertyLineHeight;
+}
+
+// This method returns the first CSSPropertyId of remaining properties,
+// i.e. low priority properties. No properties depend on low priority
+// properties. So we don't need to resolve such properties quickly.
+// All low priority properties are obtained by using
+// firstCSSPropertyId<LowPriorityProperties> and
+// lastCSSPropertyId<LowPriorityProperties>.
+template<> CSSPropertyID StyleResolver::firstCSSPropertyId<StyleResolver::LowPriorityProperties>()
+{
+ COMPILE_ASSERT(CSSPropertyBackground == CSSPropertyLineHeight + 1, CSS_background_is_first_low_priority_property);
+ return CSSPropertyBackground;
+}
+
+// This method returns the last CSSPropertyId of low priority properties.
+template<> CSSPropertyID StyleResolver::lastCSSPropertyId<StyleResolver::LowPriorityProperties>()
+{
+ return static_cast<CSSPropertyID>(lastCSSProperty);
+}
+
template <StyleResolver::StyleApplicationPass pass>
bool StyleResolver::isPropertyForPass(CSSPropertyID property)
{
- COMPILE_ASSERT(CSSPropertyVariable < firstCSSProperty, CSS_variable_is_before_first_property);
- const CSSPropertyID firstAnimationProperty = CSSPropertyDisplay;
- const CSSPropertyID lastAnimationProperty = CSSPropertyTransitionTimingFunction;
- COMPILE_ASSERT(firstCSSProperty == firstAnimationProperty, CSS_first_animation_property_should_be_first_property);
- const CSSPropertyID firstHighPriorityProperty = CSSPropertyColor;
- const CSSPropertyID lastHighPriorityProperty = CSSPropertyLineHeight;
- COMPILE_ASSERT(lastAnimationProperty + 1 == firstHighPriorityProperty, CSS_color_is_first_high_priority_property);
- COMPILE_ASSERT(CSSPropertyLineHeight == firstHighPriorityProperty + 17, CSS_line_height_is_end_of_high_prioity_property_range);
- COMPILE_ASSERT(CSSPropertyZoom == lastHighPriorityProperty - 1, CSS_zoom_is_before_line_height);
- switch (pass) {
- case VariableDefinitions:
- return property == CSSPropertyVariable;
- case AnimationProperties:
- return property >= firstAnimationProperty && property <= lastAnimationProperty;
- case HighPriorityProperties:
- return property >= firstHighPriorityProperty && property <= lastHighPriorityProperty;
- case LowPriorityProperties:
- return property > lastHighPriorityProperty;
+ return firstCSSPropertyId<pass>() <= property && property <= lastCSSPropertyId<pass>();
+}
+
+// This method expands all shorthand property to longhand properties
+// considering StyleApplicationPass, and apply each expanded longhand property.
+// For example, if StyleApplicationPass is AnimationProperties, all shorthand
+// is expaneded to display, -webkit-animation, -webkit-animation-delay, ...,
+// transition-timing-function. So each property's value will be applied
+// according to all's value (initial, inherit or unset).
+template <StyleResolver::StyleApplicationPass pass>
+void StyleResolver::applyAllProperty(StyleResolverState& state, CSSValue* allValue)
+{
+ bool isUnsetValue = !allValue->isInitialValue() && !allValue->isInheritedValue();
+ unsigned startCSSProperty = firstCSSPropertyId<pass>();
+ unsigned endCSSProperty = lastCSSPropertyId<pass>();
+
+ for (unsigned i = startCSSProperty; i <= endCSSProperty; ++i) {
+ CSSPropertyID propertyId = static_cast<CSSPropertyID>(i);
+
+ // StyleBuilder does not allow any expanded shorthands.
+ if (isExpandedShorthandForAll(propertyId))
+ continue;
+
+ // all shorthand spec says:
+ // The all property is a shorthand that resets all CSS properties
+ // except direction and unicode-bidi.
+ // c.f. http://dev.w3.org/csswg/css-cascade/#all-shorthand
+ // We skip applyProperty when a given property is unicode-bidi or
+ // direction.
+ if (!CSSProperty::isAffectedByAllProperty(propertyId))
+ continue;
+
+ CSSValue* value;
+ if (!isUnsetValue) {
+ value = allValue;
+ } else {
+ if (CSSProperty::isInheritedProperty(propertyId))
+ value = cssValuePool().createInheritedValue().get();
+ else
+ value = cssValuePool().createExplicitInitialValue().get();
+ }
+ StyleBuilder::applyProperty(propertyId, state, value);
}
- ASSERT_NOT_REACHED();
- return false;
}
template <StyleResolver::StyleApplicationPass pass>
void StyleResolver::applyProperties(StyleResolverState& state, const StylePropertySet* properties, StyleRule* rule, bool isImportant, bool inheritedOnly, PropertyWhitelistType propertyWhitelistType)
{
- ASSERT((propertyWhitelistType != PropertyWhitelistRegion) || state.regionForStyling());
state.setCurrentRule(rule);
unsigned propertyCount = properties->propertyCount();
@@ -1279,6 +1352,13 @@ void StyleResolver::applyProperties(StyleResolverState& state, const StyleProper
StylePropertySet::PropertyReference current = properties->propertyAt(i);
if (isImportant != current.isImportant())
continue;
+
+ CSSPropertyID property = current.id();
+ if (property == CSSPropertyAll) {
+ applyAllProperty<pass>(state, current.value());
+ continue;
+ }
+
if (inheritedOnly && !current.isInherited()) {
// If the property value is explicitly inherited, we need to apply further non-inherited properties
// as they might override the value inherited here. For this reason we don't allow declarations with
@@ -1286,12 +1366,11 @@ void StyleResolver::applyProperties(StyleResolverState& state, const StyleProper
ASSERT(!current.value()->isInheritedValue());
continue;
}
- CSSPropertyID property = current.id();
- if (propertyWhitelistType == PropertyWhitelistRegion && !isValidRegionStyleProperty(property))
- continue;
if (propertyWhitelistType == PropertyWhitelistCue && !isValidCueStyleProperty(property))
continue;
+ if (propertyWhitelistType == PropertyWhitelistFirstLetter && !isValidFirstLetterStyleProperty(property))
+ continue;
if (!isPropertyForPass<pass>(property))
continue;
if (pass == HighPriorityProperties && property == CSSPropertyLineHeight)
@@ -1337,6 +1416,12 @@ void StyleResolver::invalidateMatchedPropertiesCache()
m_matchedPropertiesCache.clear();
}
+void StyleResolver::notifyResizeForViewportUnits()
+{
+ collectViewportRules();
+ m_matchedPropertiesCache.clearViewportDependent();
+}
+
void StyleResolver::applyMatchedProperties(StyleResolverState& state, const MatchResult& matchResult)
{
const Element* element = state.element();
@@ -1355,7 +1440,8 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
// style declarations. We then only need to apply the inherited properties, if any, as their values can depend on the
// element context. This is fast and saves memory by reusing the style data structures.
state.style()->copyNonInheritedFrom(cachedMatchedProperties->renderStyle.get());
- if (state.parentStyle()->inheritedDataShared(cachedMatchedProperties->parentRenderStyle.get()) && !isAtShadowBoundary(element)) {
+ if (state.parentStyle()->inheritedDataShared(cachedMatchedProperties->parentRenderStyle.get()) && !isAtShadowBoundary(element)
+ && (!state.distributedToInsertionPoint() || state.style()->userModify() == READ_ONLY)) {
INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheInheritedHit);
EInsideLink linkStatus = state.style()->insideLink();
@@ -1370,24 +1456,12 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
applyInheritedOnly = true;
}
- // First apply all variable definitions, as they may be used during application of later properties.
- applyMatchedProperties<VariableDefinitions>(state, matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
- applyMatchedProperties<VariableDefinitions>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
- applyMatchedProperties<VariableDefinitions>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
- applyMatchedProperties<VariableDefinitions>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
-
// Apply animation properties in order to apply animation results and trigger transitions below.
applyMatchedProperties<AnimationProperties>(state, matchResult, false, 0, matchResult.matchedProperties.size() - 1, applyInheritedOnly);
applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstAuthorRule, matchResult.ranges.lastAuthorRule, applyInheritedOnly);
applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
applyMatchedProperties<AnimationProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
- // Match transition-property / animation-name length by trimming and
- // lengthening other transition / animation property lists
- // FIXME: This is wrong because we shouldn't affect the computed values
- state.style()->adjustAnimations();
- state.style()->adjustTransitions();
-
// Now we have all of the matched rules in the appropriate order. Walk the rules and apply
// high-priority properties first, i.e., those properties that other properties depend on.
// The order is (1) high-priority not important, (2) high-priority important, (3) normal not important
@@ -1398,6 +1472,17 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
applyMatchedProperties<HighPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
+ if (UNLIKELY(isSVGForeignObjectElement(element))) {
+ // RenderSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should not be scaled again.
+ //
+ // FIXME: The following hijacks the zoom property for foreignObject so that children of foreignObject get the
+ // correct font-size in case of zooming. 'zoom' is part of HighPriorityProperties, along with other font-related
+ // properties used as input to the FontBuilder, so resetting it here may cause the FontBuilder to recompute the
+ // font used as inheritable font for foreignObject content. If we want to support zoom on foreignObject we'll
+ // need to find another way of handling the SVG zoom model.
+ state.setEffectiveZoom(RenderStyle::initialZoom());
+ }
+
if (cachedMatchedProperties && cachedMatchedProperties->renderStyle->effectiveZoom() != state.style()->effectiveZoom()) {
state.fontBuilder().setFontDirty(true);
applyInheritedOnly = false;
@@ -1426,9 +1511,7 @@ void StyleResolver::applyMatchedProperties(StyleResolverState& state, const Matc
applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUserRule, matchResult.ranges.lastUserRule, applyInheritedOnly);
applyMatchedProperties<LowPriorityProperties>(state, matchResult, true, matchResult.ranges.firstUARule, matchResult.ranges.lastUARule, applyInheritedOnly);
- // Start loading resources referenced by this style.
- m_styleResourceLoader.loadPendingResources(state.style(), state.elementStyleResources());
- document().styleEngine()->fontSelector()->loadPendingFonts();
+ loadPendingResources(state);
if (!cachedMatchedProperties && cacheHash && MatchedPropertiesCache::isCacheable(element, state.style(), state.parentStyle())) {
INCREMENT_STYLE_STATS_COUNTER(*this, matchedPropertyCacheAdded);
@@ -1476,7 +1559,7 @@ void StyleResolver::applyPropertiesToStyle(const CSSPropertyValue* properties, s
StyleResolverState state(document(), document().documentElement(), style);
state.setStyle(style);
- state.fontBuilder().initForStyleResolve(document(), style, state.useSVGZoomRules());
+ state.fontBuilder().initForStyleResolve(document(), style);
for (size_t i = 0; i < count; ++i) {
if (properties[i].value) {
@@ -1502,13 +1585,26 @@ void StyleResolver::addMediaQueryResults(const MediaQueryResultList& list)
m_viewportDependentMediaQueryResults.append(list[i]);
}
-bool StyleResolver::affectedByViewportChange() const
+bool StyleResolver::mediaQueryAffectedByViewportChange() const
{
for (unsigned i = 0; i < m_viewportDependentMediaQueryResults.size(); ++i) {
- if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expression) != m_viewportDependentMediaQueryResults[i]->m_result)
+ if (m_medium->eval(m_viewportDependentMediaQueryResults[i]->expression()) != m_viewportDependentMediaQueryResults[i]->result())
return true;
}
return false;
}
+void StyleResolver::trace(Visitor* visitor)
+{
+ visitor->trace(m_keyframesRuleMap);
+ visitor->trace(m_viewportDependentMediaQueryResults);
+ visitor->trace(m_viewportStyleResolver);
+ visitor->trace(m_features);
+ visitor->trace(m_siblingRuleSet);
+ visitor->trace(m_uncommonAttributeRuleSet);
+ visitor->trace(m_watchedSelectorsRules);
+ visitor->trace(m_treeBoundaryCrossingRules);
+ visitor->trace(m_pendingStyleSheets);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.h b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.h
index f1dae0b2381..1ab53b349d0 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolver.h
@@ -22,8 +22,6 @@
#ifndef StyleResolver_h
#define StyleResolver_h
-#include "core/animation/KeyframeAnimationEffect.h"
-#include "core/css/InspectorCSSOMWrappers.h"
#include "core/css/PseudoStyleRequest.h"
#include "core/css/RuleFeature.h"
#include "core/css/RuleSet.h"
@@ -35,9 +33,8 @@
#include "core/css/resolver/ScopedStyleResolver.h"
#include "core/css/resolver/ScopedStyleTree.h"
#include "core/css/resolver/StyleBuilder.h"
-#include "core/css/resolver/StyleResolverIncludes.h"
-#include "core/css/resolver/StyleResolverState.h"
#include "core/css/resolver/StyleResourceLoader.h"
+#include "platform/heap/Handle.h"
#include "wtf/Deque.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
@@ -47,6 +44,8 @@
namespace WebCore {
+class AnimatableValue;
+class AnimationTimeline;
class CSSAnimationUpdate;
class CSSFontSelector;
class CSSRuleList;
@@ -55,14 +54,13 @@ class CSSStyleSheet;
class CSSValue;
class ContainerNode;
class Document;
-class DocumentTimeline;
class Element;
class ElementRuleCollector;
+class Interpolation;
class KeyframeList;
class KeyframeValue;
class MediaQueryEvaluator;
class MediaQueryResult;
-class RenderRegion;
class RuleData;
class Settings;
class StyleKeyframe;
@@ -73,40 +71,39 @@ class StyleRuleKeyframes;
class StyleRulePage;
class ViewportStyleResolver;
-struct MatchResult;
+class MatchResult;
enum StyleSharingBehavior {
AllowStyleSharing,
DisallowStyleSharing,
};
-// MatchOnlyUserAgentRules is used in media queries, where relative units
-// are interpreted according to the document root element style, and styled only
-// from the User Agent Stylesheet rules.
enum RuleMatchingBehavior {
MatchAllRules,
- MatchAllRulesExcludingSMIL,
- MatchOnlyUserAgentRules,
+ MatchAllRulesExcludingSMIL
};
-const unsigned styleSharingListSize = 40;
+const unsigned styleSharingListSize = 15;
+const unsigned styleSharingMaxDepth = 32;
typedef WTF::Deque<Element*, styleSharingListSize> StyleSharingList;
struct CSSPropertyValue {
+ STACK_ALLOCATED();
+public:
CSSPropertyValue(CSSPropertyID property, CSSValue* value)
: property(property), value(value) { }
// Stores value=propertySet.getPropertyCSSValue(id).get().
CSSPropertyValue(CSSPropertyID, const StylePropertySet&);
CSSPropertyID property;
- CSSValue* value;
+ RawPtrWillBeMember<CSSValue> value;
};
// This class selects a RenderStyle for a given element based on a collection of stylesheets.
-class StyleResolver : public FontSelectorClient {
- WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED;
+class StyleResolver FINAL : public NoBaseWillBeGarbageCollectedFinalized<StyleResolver> {
+ WTF_MAKE_NONCOPYABLE(StyleResolver); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
explicit StyleResolver(Document&);
- ~StyleResolver();
+ virtual ~StyleResolver();
// FIXME: StyleResolver should not be keeping tree-walk state.
// These should move to some global tree-walk state, or should be contained in a
@@ -118,13 +115,11 @@ public:
void popParentShadowRoot(const ShadowRoot&);
PassRefPtr<RenderStyle> styleForElement(Element*, RenderStyle* parentStyle = 0, StyleSharingBehavior = AllowStyleSharing,
- RuleMatchingBehavior = MatchAllRules, RenderRegion* regionForStyling = 0);
+ RuleMatchingBehavior = MatchAllRules);
- // FIXME: keyframeStylesForAnimation is only used in the legacy animations implementation
- // and should be removed when that is replaced by Web Animations.
- void keyframeStylesForAnimation(Element*, const RenderStyle&, KeyframeList&);
PassRefPtr<RenderStyle> styleForKeyframe(Element*, const RenderStyle&, RenderStyle* parentStyle, const StyleKeyframe*, const AtomicString& animationName);
- static PassRefPtr<KeyframeAnimationEffect> createKeyframeAnimationEffect(Element&, const Vector<RefPtr<MutableStylePropertySet> >&, KeyframeAnimationEffect::KeyframeVector&);
+ static PassRefPtrWillBeRawPtr<AnimatableValue> createAnimatableValueSnapshot(Element&, CSSPropertyID, CSSValue&);
+ static PassRefPtrWillBeRawPtr<AnimatableValue> createAnimatableValueSnapshot(StyleResolverState&, CSSPropertyID, CSSValue&);
PassRefPtr<RenderStyle> pseudoStyleForElement(Element*, const PseudoStyleRequest&, RenderStyle* parentStyle);
@@ -132,7 +127,7 @@ public:
PassRefPtr<RenderStyle> defaultStyleForElement();
PassRefPtr<RenderStyle> styleForText(Text*);
- static PassRefPtr<RenderStyle> styleForDocument(Document&, CSSFontSelector* = 0);
+ static PassRefPtr<RenderStyle> styleForDocument(Document&);
// FIXME: This only has 5 callers and should be removed. Callers should be explicit about
// their dependency on Document* instead of grabbing one through StyleResolver.
@@ -140,15 +135,14 @@ public:
// FIXME: It could be better to call appendAuthorStyleSheets() directly after we factor StyleResolver further.
// https://bugs.webkit.org/show_bug.cgi?id=108890
- void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >&);
+ void appendAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
void resetAuthorStyle(const ContainerNode*);
void finishAppendAuthorStyleSheets();
- TreeBoundaryCrossingRules& treeBoundaryCrossingRules() { return m_treeBoundaryCrossingRules; }
- void processScopedRules(const RuleSet& authorRules, const KURL&, ContainerNode* scope = 0);
+ void processScopedRules(const RuleSet& authorRules, CSSStyleSheet*, ContainerNode& scope);
- void lazyAppendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >&);
- void removePendingAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&);
+ void lazyAppendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
+ void removePendingAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
void appendPendingAuthorStyleSheets();
bool hasPendingAuthorStyleSheets() const { return m_pendingStyleSheets.size() > 0 || m_needCollectFeatures; }
@@ -179,9 +173,9 @@ public:
AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
AllCSSRules = AllButEmptyCSSRules | EmptyCSSRules,
};
- PassRefPtr<CSSRuleList> cssRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules, ShouldIncludeStyleSheetInCSSOMWrapper = IncludeStyleSheetInCSSOMWrapper);
- PassRefPtr<CSSRuleList> pseudoCSSRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules, ShouldIncludeStyleSheetInCSSOMWrapper = IncludeStyleSheetInCSSOMWrapper);
- PassRefPtr<StyleRuleList> styleRulesForElement(Element*, unsigned rulesToInclude);
+ PassRefPtrWillBeRawPtr<CSSRuleList> cssRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
+ PassRefPtrWillBeRawPtr<CSSRuleList> pseudoCSSRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
+ PassRefPtrWillBeRawPtr<StyleRuleList> styleRulesForElement(Element*, unsigned rulesToInclude);
// |properties| is an array with |count| elements.
void applyPropertiesToStyle(const CSSPropertyValue* properties, size_t count, RenderStyle*);
@@ -191,28 +185,29 @@ public:
void addMediaQueryResults(const MediaQueryResultList&);
MediaQueryResultList* viewportDependentMediaQueryResults() { return &m_viewportDependentMediaQueryResults; }
bool hasViewportDependentMediaQueries() const { return !m_viewportDependentMediaQueryResults.isEmpty(); }
- bool affectedByViewportChange() const;
-
- // FIXME: Regions should not require special logic in StyleResolver.
- bool checkRegionStyle(Element* regionElement);
+ bool mediaQueryAffectedByViewportChange() const;
// FIXME: Rename to reflect the purpose, like didChangeFontSize or something.
void invalidateMatchedPropertiesCache();
+ void notifyResizeForViewportUnits();
+
// Exposed for RenderStyle::isStyleAvilable().
static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
- // FIXME: StyleResolver should not have this member or method.
- InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; }
-
- const RuleFeatureSet& ensureRuleFeatureSet()
+ RuleFeatureSet& ensureUpdatedRuleFeatureSet()
{
if (hasPendingAuthorStyleSheets())
appendPendingAuthorStyleSheets();
return m_features;
}
- StyleSharingList& styleSharingList() { return m_styleSharingList; }
+ RuleFeatureSet& ruleFeatureSet()
+ {
+ return m_features;
+ }
+
+ StyleSharingList& styleSharingList();
bool hasRulesForId(const AtomicString&) const;
@@ -229,20 +224,22 @@ public:
unsigned accessCount() const { return m_accessCount; }
void didAccess() { ++m_accessCount; }
- PassRefPtr<PseudoElement> createPseudoElementIfNeeded(Element&, PseudoId);
+ void increaseStyleSharingDepth() { ++m_styleSharingDepth; }
+ void decreaseStyleSharingDepth() { --m_styleSharingDepth; }
-private:
- // FontSelectorClient implementation.
- virtual void fontsNeedUpdate(FontSelector*);
+ PassRefPtrWillBeRawPtr<PseudoElement> createPseudoElementIfNeeded(Element& parent, PseudoId);
-private:
- void initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& watchedSelectors);
+ void trace(Visitor*);
- void addTreeBoundaryCrossingRules(const Vector<MinimalRuleData>&, ContainerNode* scope);
+private:
+ void initWatchedSelectorRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedSelectors);
// FIXME: This should probably go away, folded into FontBuilder.
void updateFont(StyleResolverState&);
+ void loadPendingResources(StyleResolverState&);
+ void adjustRenderStyle(StyleResolverState&, Element*);
+
void appendCSSStyleSheet(CSSStyleSheet*);
void collectPseudoRulesForElement(Element*, ElementRuleCollector&, PseudoId, unsigned rulesToInclude);
@@ -254,30 +251,35 @@ private:
// FIXME: watched selectors should be implemented using injected author stylesheets: http://crbug.com/316960
void matchWatchSelectorRules(ElementRuleCollector&);
void collectFeatures();
- void collectTreeBoundaryCrossingRules(Element*, ElementRuleCollector&, bool includeEmptyRules);
void resetRuleFeatures();
bool fastRejectSelector(const RuleData&) const;
void applyMatchedProperties(StyleResolverState&, const MatchResult&);
- void applyAnimatedProperties(StyleResolverState&, Element* animatingElement);
+ bool applyAnimatedProperties(StyleResolverState&, Element* animatingElement);
enum StyleApplicationPass {
- VariableDefinitions,
AnimationProperties,
HighPriorityProperties,
LowPriorityProperties
};
template <StyleResolver::StyleApplicationPass pass>
+ static inline CSSPropertyID firstCSSPropertyId();
+ template <StyleResolver::StyleApplicationPass pass>
+ static inline CSSPropertyID lastCSSPropertyId();
+ template <StyleResolver::StyleApplicationPass pass>
static inline bool isPropertyForPass(CSSPropertyID);
template <StyleApplicationPass pass>
void applyMatchedProperties(StyleResolverState&, const MatchResult&, bool important, int startIndex, int endIndex, bool inheritedOnly);
template <StyleApplicationPass pass>
void applyProperties(StyleResolverState&, const StylePropertySet* properties, StyleRule*, bool isImportant, bool inheritedOnly, PropertyWhitelistType = PropertyWhitelistNone);
template <StyleApplicationPass pass>
- void applyAnimatedProperties(StyleResolverState&, const AnimationEffect::CompositableValueMap&);
+ void applyAnimatedProperties(StyleResolverState&, const WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> >&);
+ template <StyleResolver::StyleApplicationPass pass>
+ void applyAllProperty(StyleResolverState&, CSSValue*);
+
void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
- void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName);
+ void matchPageRulesForList(WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& matchedRules, const WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >&, bool isLeftPage, bool isFirstPage, const String& pageName);
void collectViewportRules();
Settings* documentSettings() { return m_document.settings(); }
@@ -289,7 +291,7 @@ private:
bool pseudoStyleForElementInternal(Element&, const PseudoStyleRequest&, RenderStyle* parentStyle, StyleResolverState&);
// FIXME: This likely belongs on RuleSet.
- typedef HashMap<StringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap;
+ typedef WillBeHeapHashMap<StringImpl*, RefPtrWillBeMember<StyleRuleKeyframes> > KeyframesRuleMap;
KeyframesRuleMap m_keyframesRuleMap;
static RenderStyle* s_styleNotYetAvailable;
@@ -301,56 +303,40 @@ private:
OwnPtr<MediaQueryEvaluator> m_medium;
MediaQueryResultList m_viewportDependentMediaQueryResults;
- RefPtr<RenderStyle> m_rootDefaultStyle;
-
Document& m_document;
SelectorFilter m_selectorFilter;
- RefPtr<ViewportStyleResolver> m_viewportStyleResolver;
+ OwnPtrWillBeMember<ViewportStyleResolver> m_viewportStyleResolver;
- ListHashSet<CSSStyleSheet*, 16> m_pendingStyleSheets;
+ WillBeHeapListHashSet<RawPtrWillBeMember<CSSStyleSheet>, 16> m_pendingStyleSheets;
ScopedStyleTree m_styleTree;
- // FIXME: The entire logic of collecting features on StyleResolver, as well astransferring them
+ // FIXME: The entire logic of collecting features on StyleResolver, as well as transferring them
// between various parts of machinery smells wrong. This needs to be better somehow.
RuleFeatureSet m_features;
- OwnPtr<RuleSet> m_siblingRuleSet;
- OwnPtr<RuleSet> m_uncommonAttributeRuleSet;
+ OwnPtrWillBeMember<RuleSet> m_siblingRuleSet;
+ OwnPtrWillBeMember<RuleSet> m_uncommonAttributeRuleSet;
// FIXME: watched selectors should be implemented using injected author stylesheets: http://crbug.com/316960
- OwnPtr<RuleSet> m_watchedSelectorsRules;
+ OwnPtrWillBeMember<RuleSet> m_watchedSelectorsRules;
TreeBoundaryCrossingRules m_treeBoundaryCrossingRules;
bool m_needCollectFeatures;
- InspectorCSSOMWrappers m_inspectorCSSOMWrappers;
-
StyleResourceLoader m_styleResourceLoader;
- StyleSharingList m_styleSharingList;
+ unsigned m_styleSharingDepth;
+ Vector<OwnPtr<StyleSharingList>, styleSharingMaxDepth> m_styleSharingLists;
OwnPtr<StyleResolverStats> m_styleResolverStats;
OwnPtr<StyleResolverStats> m_styleResolverStatsTotals;
unsigned m_styleResolverStatsSequence;
+ // Use only for Internals::updateStyleAndReturnAffectedElementCount.
unsigned m_accessCount;
};
-inline bool checkRegionSelector(const CSSSelector* regionSelector, Element* regionElement)
-{
- if (!regionSelector || !regionElement)
- return false;
-
- SelectorChecker selectorChecker(regionElement->document(), SelectorChecker::QueryingRules);
- for (const CSSSelector* s = regionSelector; s; s = CSSSelectorList::next(s)) {
- SelectorChecker::SelectorCheckingContext selectorCheckingContext(s, regionElement, SelectorChecker::VisitedMatchDisabled);
- if (selectorChecker.match(selectorCheckingContext, DOMSiblingTraversalStrategy()) == SelectorChecker::SelectorMatches)
- return true;
- }
- return false;
-}
-
} // namespace WebCore
#endif // StyleResolver_h
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverIncludes.h b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverIncludes.h
deleted file mode 100644
index 380c1eb1d57..00000000000
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverIncludes.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef StyleResolverIncludes_h
-#define StyleResolverIncludes_h
-
-namespace WebCore {
-
-enum ShouldIncludeStyleSheetInCSSOMWrapper {
- IncludeStyleSheetInCSSOMWrapper,
- DoNotIncludeStyleSheetInCSSOMWrapper,
-};
-
-}
-
-#endif // StyleResolverIncludes_h
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverParentScope.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverParentScope.cpp
new file mode 100644
index 00000000000..bde3a362aed
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverParentScope.cpp
@@ -0,0 +1,13 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/css/resolver/StyleResolverParentScope.h"
+
+namespace WebCore {
+
+StyleResolverParentScope* StyleResolverParentScope::s_currentScope = 0;
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverParentScope.h b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverParentScope.h
new file mode 100644
index 00000000000..87ca21cee91
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverParentScope.h
@@ -0,0 +1,78 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StyleResolverParentScope_h
+#define StyleResolverParentScope_h
+
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Element.h"
+#include "core/dom/shadow/ShadowRoot.h"
+
+namespace WebCore {
+
+// Maintains the parent element stack (and bloom filter) inside recalcStyle.
+class StyleResolverParentScope FINAL {
+public:
+ explicit StyleResolverParentScope(Node& parent);
+ ~StyleResolverParentScope();
+
+ static void ensureParentStackIsPushed();
+
+private:
+ void pushParentIfNeeded();
+
+ Node& m_parent;
+ bool m_pushed;
+ StyleResolverParentScope* m_previous;
+ StyleResolver& m_resolver;
+
+ static StyleResolverParentScope* s_currentScope;
+};
+
+inline StyleResolverParentScope::StyleResolverParentScope(Node& parent)
+ : m_parent(parent)
+ , m_pushed(false)
+ , m_previous(s_currentScope)
+ , m_resolver(*m_parent.document().styleResolver())
+{
+ ASSERT(m_parent.document().inStyleRecalc());
+ ASSERT(parent.isElementNode() || parent.isShadowRoot());
+ s_currentScope = this;
+ m_resolver.increaseStyleSharingDepth();
+}
+
+inline StyleResolverParentScope::~StyleResolverParentScope()
+{
+ s_currentScope = m_previous;
+ m_resolver.decreaseStyleSharingDepth();
+ if (!m_pushed)
+ return;
+ if (m_parent.isElementNode())
+ m_resolver.popParentElement(toElement(m_parent));
+ else
+ m_resolver.popParentShadowRoot(toShadowRoot(m_parent));
+}
+
+inline void StyleResolverParentScope::ensureParentStackIsPushed()
+{
+ if (s_currentScope)
+ s_currentScope->pushParentIfNeeded();
+}
+
+inline void StyleResolverParentScope::pushParentIfNeeded()
+{
+ if (m_pushed)
+ return;
+ if (m_previous)
+ m_previous->pushParentIfNeeded();
+ if (m_parent.isElementNode())
+ m_resolver.pushParentElement(toElement(m_parent));
+ else
+ m_resolver.pushParentShadowRoot(toShadowRoot(m_parent));
+ m_pushed = true;
+}
+
+} // namespace WebCore
+
+#endif // StyleResolverParentScope_h
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp
index 6df80021ba5..f0efa4a7d8a 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.cpp
@@ -22,33 +22,48 @@
#include "config.h"
#include "core/css/resolver/StyleResolverState.h"
+#include "core/animation/css/CSSAnimations.h"
#include "core/dom/Node.h"
#include "core/dom/NodeRenderStyle.h"
-#include "core/page/Page.h"
+#include "core/frame/FrameHost.h"
namespace WebCore {
-StyleResolverState::StyleResolverState(Document& document, Element* element, RenderStyle* parentStyle, RenderRegion* regionForStyling)
+StyleResolverState::StyleResolverState(Document& document, Element* element, RenderStyle* parentStyle)
: m_elementContext(element ? ElementResolveContext(*element) : ElementResolveContext())
, m_document(document)
- , m_style(0)
- , m_cssToLengthConversionData(0, rootElementStyle())
+ , m_style(nullptr)
+ , m_cssToLengthConversionData(0, rootElementStyle(), document.renderView())
, m_parentStyle(parentStyle)
- , m_regionForStyling(regionForStyling)
, m_applyPropertyToRegularStyle(true)
, m_applyPropertyToVisitedLinkStyle(false)
- , m_lineHeightValue(0)
+ , m_lineHeightValue(nullptr)
, m_styleMap(*this, m_elementStyleResources)
- , m_currentRule(0)
+ , m_currentRule(nullptr)
{
- if (m_elementContext.resetStyleInheritance())
- m_parentStyle = 0;
- else if (!parentStyle && m_elementContext.parentNode())
+ if (!parentStyle && m_elementContext.parentNode())
m_parentStyle = m_elementContext.parentNode()->renderStyle();
- // FIXME: How can we not have a page here?
- if (Page* page = document.page())
- m_elementStyleResources.setDeviceScaleFactor(page->deviceScaleFactor());
+ // FIXME: Animation unitests will start animations on non-active documents!
+ // http://crbug.com/330095
+ // ASSERT(document.isActive());
+ if (!document.isActive())
+ return;
+ m_elementStyleResources.setDeviceScaleFactor(document.frameHost()->deviceScaleFactor());
+}
+
+StyleResolverState::~StyleResolverState()
+{
+}
+
+void StyleResolverState::setAnimationUpdate(PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> update)
+{
+ m_animationUpdate = update;
+}
+
+PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> StyleResolverState::takeAnimationUpdate()
+{
+ return m_animationUpdate.release();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h
index 18095bd28dd..2a723ba471b 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResolverState.h
@@ -22,9 +22,8 @@
#ifndef StyleResolverState_h
#define StyleResolverState_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
-#include "core/animation/css/CSSAnimations.h"
#include "core/css/CSSSVGDocumentValue.h"
#include "core/css/CSSToLengthConversionData.h"
#include "core/css/resolver/CSSToStyleMap.h"
@@ -38,14 +37,16 @@
namespace WebCore {
+class CSSAnimationUpdate;
class FontDescription;
-class RenderRegion;
class StyleRule;
class StyleResolverState {
-WTF_MAKE_NONCOPYABLE(StyleResolverState);
+ STACK_ALLOCATED();
+ WTF_MAKE_NONCOPYABLE(StyleResolverState);
public:
- StyleResolverState(Document&, Element*, RenderStyle* parentStyle = 0, RenderRegion* regionForStyling = 0);
+ StyleResolverState(Document&, Element*, RenderStyle* parentStyle = 0);
+ ~StyleResolverState();
// In FontFaceSet and CanvasRenderingContext2D, we don't have an element to grab the document from.
// This is why we have to store the document separately.
@@ -66,16 +67,14 @@ public:
const CSSToLengthConversionData& cssToLengthConversionData() const { return m_cssToLengthConversionData; }
- void setAnimationUpdate(PassOwnPtr<CSSAnimationUpdate> update) { m_animationUpdate = update; }
+ void setAnimationUpdate(PassOwnPtrWillBeRawPtr<CSSAnimationUpdate>);
const CSSAnimationUpdate* animationUpdate() { return m_animationUpdate.get(); }
- PassOwnPtr<CSSAnimationUpdate> takeAnimationUpdate() { return m_animationUpdate.release(); }
+ PassOwnPtrWillBeRawPtr<CSSAnimationUpdate> takeAnimationUpdate();
void setParentStyle(PassRefPtr<RenderStyle> parentStyle) { m_parentStyle = parentStyle; }
const RenderStyle* parentStyle() const { return m_parentStyle.get(); }
RenderStyle* parentStyle() { return m_parentStyle.get(); }
- const RenderRegion* regionForStyling() const { return m_regionForStyling; }
-
void setCurrentRule(StyleRule* currentRule) { m_currentRule = currentRule; }
const StyleRule* currentRule() const { return m_currentRule; }
@@ -95,8 +94,20 @@ public:
void setLineHeightValue(CSSValue* value) { m_lineHeightValue = value; }
CSSValue* lineHeightValue() { return m_lineHeightValue; }
- void cacheUserAgentBorderAndBackground() { m_cachedUAStyle = CachedUAStyle(style()); }
- const CachedUAStyle& cachedUAStyle() const { return m_cachedUAStyle; }
+ void cacheUserAgentBorderAndBackground()
+ {
+ // RenderTheme only needs the cached style if it has an appearance,
+ // and constructing it is expensive so we avoid it if possible.
+ if (!style()->hasAppearance())
+ return;
+
+ m_cachedUAStyle = CachedUAStyle::create(style());
+ }
+
+ const CachedUAStyle* cachedUAStyle() const
+ {
+ return m_cachedUAStyle.get();
+ }
ElementStyleResources& elementStyleResources() { return m_elementStyleResources; }
const CSSToStyleMap& styleMap() const { return m_styleMap; }
@@ -107,7 +118,7 @@ public:
// sites are extremely verbose.
PassRefPtr<StyleImage> styleImage(CSSPropertyID propertyId, CSSValue* value)
{
- return m_elementStyleResources.styleImage(document().textLinkColors(), style()->color(), propertyId, value);
+ return m_elementStyleResources.styleImage(document(), document().textLinkColors(), style()->color(), propertyId, value);
}
FontBuilder& fontBuilder() { return m_fontBuilder; }
@@ -122,19 +133,7 @@ public:
void setWritingMode(WritingMode writingMode) { m_fontBuilder.didChangeFontParameters(m_style->setWritingMode(writingMode)); }
void setTextOrientation(TextOrientation textOrientation) { m_fontBuilder.didChangeFontParameters(m_style->setTextOrientation(textOrientation)); }
- // SVG handles zooming in a different way compared to CSS. The whole document is scaled instead
- // of each individual length value in the render style / tree. CSSPrimitiveValue::computeLength*()
- // multiplies each resolved length with the zoom multiplier - so for SVG we need to disable that.
- // Though all CSS values that can be applied to outermost <svg> elements (width/height/border/padding...)
- // need to respect the scaling. RenderBox (the parent class of RenderSVGRoot) grabs values like
- // width/height/border/padding/... from the RenderStyle -> for SVG these values would never scale,
- // if we'd pass a 1.0 zoom factor everyhwere. So we only pass a zoom factor of 1.0 for specific
- // properties that are NOT allowed to scale within a zoomed SVG document (letter/word-spacing/font-size).
- bool useSVGZoomRules() const { return element() && element()->isSVGElement(); }
-
private:
- friend class StyleResolveScope;
-
ElementResolveContext m_elementContext;
Document& m_document;
@@ -147,21 +146,16 @@ private:
// so we keep it separate from m_elementContext.
RefPtr<RenderStyle> m_parentStyle;
- OwnPtr<CSSAnimationUpdate> m_animationUpdate;
-
- // Required to ASSERT in applyProperties.
- // FIXME: Regions should not need special state on StyleResolverState
- // no other @rule does.
- RenderRegion* m_regionForStyling;
+ OwnPtrWillBeMember<CSSAnimationUpdate> m_animationUpdate;
bool m_applyPropertyToRegularStyle;
bool m_applyPropertyToVisitedLinkStyle;
- CSSValue* m_lineHeightValue;
+ RawPtrWillBeMember<CSSValue> m_lineHeightValue;
FontBuilder m_fontBuilder;
- CachedUAStyle m_cachedUAStyle;
+ OwnPtr<CachedUAStyle> m_cachedUAStyle;
ElementStyleResources m_elementStyleResources;
// CSSToStyleMap is a pure-logic class and only contains
@@ -169,7 +163,7 @@ private:
CSSToStyleMap m_styleMap;
Vector<AtomicString> m_contentAttrValues;
- StyleRule* m_currentRule;
+ RawPtrWillBeMember<StyleRule> m_currentRule;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.cpp
index 04405c340a7..9025bf04f78 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.cpp
@@ -23,37 +23,29 @@
#include "config.h"
#include "core/css/resolver/StyleResourceLoader.h"
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/css/CSSCursorImageValue.h"
#include "core/css/CSSImageValue.h"
#include "core/css/CSSSVGDocumentValue.h"
-#include "core/css/CSSShaderValue.h"
#include "core/css/resolver/ElementStyleResources.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/rendering/style/ContentData.h"
-#include "core/rendering/style/CursorList.h"
#include "core/rendering/style/FillLayer.h"
#include "core/rendering/style/RenderStyle.h"
-#include "core/rendering/style/StyleCustomFilterProgram.h"
-#include "core/rendering/style/StyleCustomFilterProgramCache.h"
#include "core/rendering/style/StyleFetchedImage.h"
#include "core/rendering/style/StyleFetchedImageSet.h"
-#include "core/rendering/style/StyleFetchedShader.h"
#include "core/rendering/style/StyleGeneratedImage.h"
#include "core/rendering/style/StylePendingImage.h"
-#include "core/rendering/style/StylePendingShader.h"
#include "core/rendering/svg/ReferenceFilterBuilder.h"
-#include "platform/graphics/filters/custom/CustomFilterOperation.h"
namespace WebCore {
StyleResourceLoader::StyleResourceLoader(ResourceFetcher* fetcher)
- : m_customFilterProgramCache(StyleCustomFilterProgramCache::create())
- , m_fetcher(fetcher)
+ : m_fetcher(fetcher)
{
}
-void StyleResourceLoader::loadPendingSVGDocuments(RenderStyle* renderStyle, const ElementStyleResources& elementStyleResources)
+void StyleResourceLoader::loadPendingSVGDocuments(RenderStyle* renderStyle, ElementStyleResources& elementStyleResources)
{
if (!renderStyle->hasFilter() || elementStyleResources.pendingSVGDocuments().isEmpty())
return;
@@ -75,35 +67,37 @@ void StyleResourceLoader::loadPendingSVGDocuments(RenderStyle* renderStyle, cons
ReferenceFilterBuilder::setDocumentResourceReference(referenceFilter, adoptPtr(new DocumentResourceReference(resource)));
}
}
+
+ elementStyleResources.clearPendingSVGDocuments();
}
-PassRefPtr<StyleImage> StyleResourceLoader::loadPendingImage(StylePendingImage* pendingImage, float deviceScaleFactor)
+static PassRefPtr<StyleImage> doLoadPendingImage(ResourceFetcher* fetcher, StylePendingImage* pendingImage, float deviceScaleFactor, const ResourceLoaderOptions& options)
{
- if (pendingImage->cssImageValue()) {
- CSSImageValue* imageValue = pendingImage->cssImageValue();
- return imageValue->cachedImage(m_fetcher);
- }
+ if (CSSImageValue* imageValue = pendingImage->cssImageValue())
+ return imageValue->cachedImage(fetcher, options);
- if (pendingImage->cssImageGeneratorValue()) {
- CSSImageGeneratorValue* imageGeneratorValue = pendingImage->cssImageGeneratorValue();
- imageGeneratorValue->loadSubimages(m_fetcher);
+ if (CSSImageGeneratorValue* imageGeneratorValue
+ = pendingImage->cssImageGeneratorValue()) {
+ imageGeneratorValue->loadSubimages(fetcher);
return StyleGeneratedImage::create(imageGeneratorValue);
}
- if (pendingImage->cssCursorImageValue()) {
- CSSCursorImageValue* cursorImageValue = pendingImage->cssCursorImageValue();
- return cursorImageValue->cachedImage(m_fetcher, deviceScaleFactor);
- }
+ if (CSSCursorImageValue* cursorImageValue
+ = pendingImage->cssCursorImageValue())
+ return cursorImageValue->cachedImage(fetcher, deviceScaleFactor);
- if (pendingImage->cssImageSetValue()) {
- CSSImageSetValue* imageSetValue = pendingImage->cssImageSetValue();
- return imageSetValue->cachedImageSet(m_fetcher, deviceScaleFactor);
- }
+ if (CSSImageSetValue* imageSetValue = pendingImage->cssImageSetValue())
+ return imageSetValue->cachedImageSet(fetcher, deviceScaleFactor, options);
+
+ return nullptr;
+}
- return 0;
+PassRefPtr<StyleImage> StyleResourceLoader::loadPendingImage(StylePendingImage* pendingImage, float deviceScaleFactor)
+{
+ return doLoadPendingImage(m_fetcher, pendingImage, deviceScaleFactor, ResourceFetcher::defaultResourceOptions());
}
-void StyleResourceLoader::loadPendingShapeImage(RenderStyle* renderStyle, ShapeValue* shapeValue)
+void StyleResourceLoader::loadPendingShapeImage(RenderStyle* renderStyle, ShapeValue* shapeValue, float deviceScaleFactor)
{
if (!shapeValue)
return;
@@ -112,16 +106,15 @@ void StyleResourceLoader::loadPendingShapeImage(RenderStyle* renderStyle, ShapeV
if (!image || !image->isPendingImage())
return;
- StylePendingImage* pendingImage = toStylePendingImage(image);
- CSSImageValue* cssImageValue = pendingImage->cssImageValue();
-
ResourceLoaderOptions options = ResourceFetcher::defaultResourceOptions();
options.allowCredentials = DoNotAllowStoredCredentials;
+ options.credentialsRequested = ClientDidNotRequestCredentials;
+ options.corsEnabled = IsCORSEnabled;
- shapeValue->setImage(cssImageValue->cachedImage(m_fetcher, options, PotentiallyCORSEnabled));
+ shapeValue->setImage(doLoadPendingImage(m_fetcher, toStylePendingImage(image), deviceScaleFactor, options));
}
-void StyleResourceLoader::loadPendingImages(RenderStyle* style, const ElementStyleResources& elementStyleResources)
+void StyleResourceLoader::loadPendingImages(RenderStyle* style, ElementStyleResources& elementStyleResources)
{
if (elementStyleResources.pendingImageProperties().isEmpty())
return;
@@ -195,51 +188,15 @@ void StyleResourceLoader::loadPendingImages(RenderStyle* style, const ElementSty
}
break;
}
- case CSSPropertyShapeInside:
- loadPendingShapeImage(style, style->shapeInside());
- break;
case CSSPropertyShapeOutside:
- loadPendingShapeImage(style, style->shapeOutside());
+ loadPendingShapeImage(style, style->shapeOutside(), elementStyleResources.deviceScaleFactor());
break;
default:
ASSERT_NOT_REACHED();
}
}
-}
-void StyleResourceLoader::loadPendingShaders(RenderStyle* style, const ElementStyleResources& elementStyleResources)
-{
- if (!style->hasFilter() || !elementStyleResources.hasNewCustomFilterProgram())
- return;
-
- Vector<RefPtr<FilterOperation> >& filterOperations = style->mutableFilter().operations();
- for (unsigned i = 0; i < filterOperations.size(); ++i) {
- RefPtr<FilterOperation> filterOperation = filterOperations.at(i);
- if (filterOperation->type() == FilterOperation::CUSTOM) {
- CustomFilterOperation* customFilter = toCustomFilterOperation(filterOperation.get());
- ASSERT(customFilter->program());
- StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customFilter->program());
- // Note that the StylePendingShaders could be already resolved to StyleFetchedShaders. That's because the rule was matched before.
- // However, the StyleCustomFilterProgram that was initially created could have been removed from the cache in the meanwhile,
- // meaning that we get a new StyleCustomFilterProgram here that is not yet in the cache, but already has loaded StyleShaders.
- if (!program->hasPendingShaders() && program->inCache())
- continue;
- RefPtr<StyleCustomFilterProgram> styleProgram = m_customFilterProgramCache->lookup(program);
- if (styleProgram.get()) {
- customFilter->setProgram(styleProgram.release());
- } else {
- if (program->vertexShader() && program->vertexShader()->isPendingShader()) {
- CSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->vertexShader())->cssShaderValue();
- program->setVertexShader(shaderValue->resource(m_fetcher));
- }
- if (program->fragmentShader() && program->fragmentShader()->isPendingShader()) {
- CSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->fragmentShader())->cssShaderValue();
- program->setFragmentShader(shaderValue->resource(m_fetcher));
- }
- m_customFilterProgramCache->add(program);
- }
- }
- }
+ elementStyleResources.clearPendingImageProperties();
}
void StyleResourceLoader::loadPendingResources(RenderStyle* renderStyle, ElementStyleResources& elementStyleResources)
@@ -247,9 +204,6 @@ void StyleResourceLoader::loadPendingResources(RenderStyle* renderStyle, Element
// Start loading images referenced by this style.
loadPendingImages(renderStyle, elementStyleResources);
- // Start loading the shaders referenced by this style.
- loadPendingShaders(renderStyle, elementStyleResources);
-
// Start loading the SVG Documents referenced by this style.
loadPendingSVGDocuments(renderStyle, elementStyleResources);
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.h b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.h
index 4b33efeea47..8d3eff19ec0 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/StyleResourceLoader.h
@@ -29,34 +29,29 @@
namespace WebCore {
class ElementStyleResources;
-class ResourceFetcher;
class RenderStyle;
+class ResourceFetcher;
class ShapeValue;
class StyleImage;
class StylePendingImage;
-class StyleCustomFilterProgramCache;
// Manages loading of resources, requested by the stylesheets.
-// Expects the same lifetime as StyleResolver, because:
-// 1) it expects ResourceFetcher to never change, and
-// 2) it also holds the StyleCustomFilterProgramCache.
+// Expects the same lifetime as StyleResolver, because
+// it expects ResourceFetcher to never change.
class StyleResourceLoader {
WTF_MAKE_NONCOPYABLE(StyleResourceLoader);
public:
explicit StyleResourceLoader(ResourceFetcher*);
void loadPendingResources(RenderStyle*, ElementStyleResources&);
- StyleCustomFilterProgramCache* customFilterProgramCache() const { return m_customFilterProgramCache.get(); }
private:
- void loadPendingSVGDocuments(RenderStyle*, const ElementStyleResources&);
- void loadPendingShaders(RenderStyle*, const ElementStyleResources&);
+ void loadPendingSVGDocuments(RenderStyle*, ElementStyleResources&);
PassRefPtr<StyleImage> loadPendingImage(StylePendingImage*, float deviceScaleFactor);
- void loadPendingImages(RenderStyle*, const ElementStyleResources&);
- void loadPendingShapeImage(RenderStyle*, ShapeValue*);
+ void loadPendingImages(RenderStyle*, ElementStyleResources&);
+ void loadPendingShapeImage(RenderStyle*, ShapeValue*, float deviceScaleFactor);
- OwnPtr<StyleCustomFilterProgramCache> m_customFilterProgramCache;
ResourceFetcher* m_fetcher;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.cpp
index 3779a01f6a5..b111c0b7844 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.cpp
@@ -32,6 +32,7 @@
#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSTransformValue.h"
#include "core/rendering/style/RenderStyle.h"
+#include "platform/heap/Handle.h"
#include "platform/transforms/Matrix3DTransformOperation.h"
#include "platform/transforms/MatrixTransformOperation.h"
#include "platform/transforms/PerspectiveTransformOperation.h"
@@ -43,17 +44,10 @@
namespace WebCore {
-TransformBuilder::TransformBuilder()
-{
-}
-
-TransformBuilder::~TransformBuilder()
-{
-}
-
static Length convertToFloatLength(CSSPrimitiveValue* primitiveValue, const CSSToLengthConversionData& conversionData)
{
- return primitiveValue ? primitiveValue->convertToLength<FixedConversion | PercentConversion>(conversionData) : Length(Undefined);
+ ASSERT(primitiveValue);
+ return primitiveValue->convertToLength<FixedConversion | PercentConversion>(conversionData);
}
static TransformOperation::OperationType getTransformOperationType(CSSTransformValue::TransformOperationType type)
@@ -180,19 +174,16 @@ bool TransformBuilder::createTransformOperations(CSSValue* inValue, const CSSToL
}
}
- if (tx.isUndefined() || ty.isUndefined())
- return false;
-
- operations.operations().append(TranslateTransformOperation::create(tx, ty, Length(0, Fixed), getTransformOperationType(transformValue->operationType())));
+ operations.operations().append(TranslateTransformOperation::create(tx, ty, 0, getTransformOperationType(transformValue->operationType())));
break;
}
case CSSTransformValue::TranslateZTransformOperation:
case CSSTransformValue::Translate3DTransformOperation: {
Length tx = Length(0, Fixed);
Length ty = Length(0, Fixed);
- Length tz = Length(0, Fixed);
+ double tz = 0;
if (transformValue->operationType() == CSSTransformValue::TranslateZTransformOperation)
- tz = convertToFloatLength(firstValue, conversionData);
+ tz = firstValue->computeLength<double>(conversionData);
else if (transformValue->operationType() == CSSTransformValue::TranslateYTransformOperation)
ty = convertToFloatLength(firstValue, conversionData);
else {
@@ -200,7 +191,7 @@ bool TransformBuilder::createTransformOperations(CSSValue* inValue, const CSSToL
if (transformValue->operationType() != CSSTransformValue::TranslateXTransformOperation) {
if (transformValue->length() > 2) {
CSSPrimitiveValue* thirdValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(2));
- tz = convertToFloatLength(thirdValue, conversionData);
+ tz = thirdValue->computeLength<double>(conversionData);
}
if (transformValue->length() > 1) {
CSSPrimitiveValue* secondValue = toCSSPrimitiveValue(transformValue->itemWithoutBoundsCheck(1));
@@ -209,9 +200,6 @@ bool TransformBuilder::createTransformOperations(CSSValue* inValue, const CSSToL
}
}
- if (tx.isUndefined() || ty.isUndefined() || tz.isUndefined())
- return false;
-
operations.operations().append(TranslateTransformOperation::create(tx, ty, tz, getTransformOperationType(transformValue->operationType())));
break;
}
@@ -305,18 +293,17 @@ bool TransformBuilder::createTransformOperations(CSSValue* inValue, const CSSToL
break;
}
case CSSTransformValue::PerspectiveTransformOperation: {
- Length p = Length(0, Fixed);
+ double p;
if (firstValue->isLength())
- p = convertToFloatLength(firstValue, conversionData);
+ p = firstValue->computeLength<double>(conversionData);
else {
// This is a quirk that should go away when 3d transforms are finalized.
double val = firstValue->getDoubleValue();
- p = val >= 0 ? Length(clampToPositiveInteger(val), Fixed) : Length(Undefined);
+ if (val < 0)
+ return false;
+ p = clampToPositiveInteger(val);
}
- if (p.isUndefined())
- return false;
-
operations.operations().append(PerspectiveTransformOperation::create(p));
break;
}
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.h b/chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.h
index a3ac2e0b0f5..94fc5a5b946 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/TransformBuilder.h
@@ -31,6 +31,7 @@
#ifndef TransformBuilder_h
#define TransformBuilder_h
+#include "platform/heap/Handle.h"
#include "platform/transforms/TransformOperations.h"
#include "wtf/Noncopyable.h"
@@ -40,11 +41,8 @@ class CSSToLengthConversionData;
class CSSValue;
class TransformBuilder {
- WTF_MAKE_NONCOPYABLE(TransformBuilder); WTF_MAKE_FAST_ALLOCATED;
+ STATIC_ONLY(TransformBuilder);
public:
- TransformBuilder();
- ~TransformBuilder();
-
static bool createTransformOperations(CSSValue* inValue, const CSSToLengthConversionData&, TransformOperations& outOperations);
};
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp b/chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
index 61894a2458a..a8c3be72ed1 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.cpp
@@ -30,41 +30,41 @@
#include "config.h"
#include "core/css/resolver/ViewportStyleResolver.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
+#include "core/css/CSSPrimitiveValueMappings.h"
#include "core/css/CSSToLengthConversionData.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRule.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/ViewportDescription.h"
+#include "core/frame/FrameView.h"
namespace WebCore {
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ViewportStyleResolver);
+
ViewportStyleResolver::ViewportStyleResolver(Document* document)
- : m_document(document),
- m_hasAuthorStyle(false)
+ : m_document(document)
+ , m_hasAuthorStyle(false)
{
ASSERT(m_document);
}
-ViewportStyleResolver::~ViewportStyleResolver()
-{
-}
-
void ViewportStyleResolver::collectViewportRules(RuleSet* rules, Origin origin)
{
rules->compactRulesIfNeeded();
- const Vector<StyleRuleViewport*>& viewportRules = rules->viewportRules();
+ const WillBeHeapVector<RawPtrWillBeMember<StyleRuleViewport> >& viewportRules = rules->viewportRules();
for (size_t i = 0; i < viewportRules.size(); ++i)
addViewportRule(viewportRules[i], origin);
}
void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule, Origin origin)
{
- StylePropertySet* propertySet = viewportRule->mutableProperties();
+ StylePropertySet& propertySet = viewportRule->mutableProperties();
- unsigned propertyCount = propertySet->propertyCount();
+ unsigned propertyCount = propertySet.propertyCount();
if (!propertyCount)
return;
@@ -72,19 +72,14 @@ void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule, Ori
m_hasAuthorStyle = true;
if (!m_propertySet) {
- m_propertySet = propertySet->mutableCopy();
+ m_propertySet = propertySet.mutableCopy();
return;
}
// We cannot use mergeAndOverrideOnConflict() here because it doesn't
// respect the !important declaration (but addParsedProperty() does).
for (unsigned i = 0; i < propertyCount; ++i)
- m_propertySet->addParsedProperty(propertySet->propertyAt(i).toCSSProperty());
-}
-
-void ViewportStyleResolver::clearDocument()
-{
- m_document = 0;
+ m_propertySet->addParsedProperty(propertySet.propertyAt(i).toCSSProperty());
}
void ViewportStyleResolver::resolve()
@@ -92,10 +87,8 @@ void ViewportStyleResolver::resolve()
if (!m_document)
return;
- if (!m_propertySet || (!m_hasAuthorStyle && m_document->hasLegacyViewportTag())) {
- ASSERT(!m_hasAuthorStyle);
- m_propertySet = 0;
- m_document->setViewportDescription(ViewportDescription());
+ if (!m_propertySet) {
+ m_document->setViewportDescription(ViewportDescription(ViewportDescription::UserAgentStyleSheet));
return;
}
@@ -113,7 +106,7 @@ void ViewportStyleResolver::resolve()
m_document->setViewportDescription(description);
- m_propertySet = 0;
+ m_propertySet = nullptr;
m_hasAuthorStyle = false;
}
@@ -127,7 +120,7 @@ float ViewportStyleResolver::viewportArgumentValue(CSSPropertyID id) const
if (id == CSSPropertyUserZoom)
defaultValue = 1;
- RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
if (!value || !value->isPrimitiveValue())
return defaultValue;
@@ -177,31 +170,36 @@ Length ViewportStyleResolver::viewportLengthValue(CSSPropertyID id) const
|| id == CSSPropertyMaxWidth
|| id == CSSPropertyMinWidth);
- RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
+ RefPtrWillBeRawPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
if (!value || !value->isPrimitiveValue())
return Length(); // auto
CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value.get());
- if (primitiveValue->isLength())
- return primitiveValue->computeLength<Length>(CSSToLengthConversionData(m_document->renderStyle(), m_document->renderStyle(), 1.0f));
+ if (primitiveValue->getValueID() == CSSValueInternalExtendToZoom)
+ return Length(ExtendToZoom);
- if (primitiveValue->isViewportPercentageLength())
- return primitiveValue->viewportPercentageLength();
+ RenderStyle* documentStyle = m_document->renderStyle();
- if (primitiveValue->isPercentage())
- return Length(primitiveValue->getFloatValue(), Percent);
+ // If we have viewport units the conversion will mark the document style as having viewport units.
+ bool documentStyleHasViewportUnits = documentStyle->hasViewportUnits();
+ documentStyle->setHasViewportUnits(false);
- switch (primitiveValue->getValueID()) {
- case CSSValueInternalExtendToZoom:
- return Length(ExtendToZoom);
- case CSSValueAuto:
- return Length();
- default:
- // Unrecognized keyword.
- ASSERT_NOT_REACHED();
- return Length(0, Fixed);
- }
+ FrameView* view = m_document->view();
+ float width = view ? view->width() : 0;
+ float height = view ? view->height() : 0;
+
+ Length result = primitiveValue->convertToLength<AnyConversion>(CSSToLengthConversionData(documentStyle, documentStyle, width, height, 1.0f));
+ if (documentStyle->hasViewportUnits())
+ m_document->setHasViewportUnits();
+ documentStyle->setHasViewportUnits(documentStyleHasViewportUnits);
+
+ return result;
+}
+
+void ViewportStyleResolver::trace(Visitor* visitor)
+{
+ visitor->trace(m_propertySet);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h b/chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h
index 30b663f2b18..604a9890b97 100644
--- a/chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h
+++ b/chromium/third_party/WebKit/Source/core/css/resolver/ViewportStyleResolver.h
@@ -30,7 +30,7 @@
#ifndef ViewportStyleResolver_h
#define ViewportStyleResolver_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/css/RuleSet.h"
#include "platform/Length.h"
#include "wtf/RefCounted.h"
@@ -42,22 +42,22 @@ class Document;
class MutableStylePropertySet;
class StyleRuleViewport;
-class ViewportStyleResolver : public RefCounted<ViewportStyleResolver> {
+class ViewportStyleResolver : public NoBaseWillBeGarbageCollected<ViewportStyleResolver> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ViewportStyleResolver);
public:
- static PassRefPtr<ViewportStyleResolver> create(Document* document)
+ static PassOwnPtrWillBeRawPtr<ViewportStyleResolver> create(Document* document)
{
- return adoptRef(new ViewportStyleResolver(document));
+ return adoptPtrWillBeNoop(new ViewportStyleResolver(document));
}
- ~ViewportStyleResolver();
-
enum Origin { UserAgentOrigin, AuthorOrigin };
void collectViewportRules(RuleSet*, Origin);
- void clearDocument();
void resolve();
+ void trace(Visitor*);
+
private:
explicit ViewportStyleResolver(Document*);
@@ -67,7 +67,7 @@ private:
Length viewportLengthValue(CSSPropertyID) const;
Document* m_document;
- RefPtr<MutableStylePropertySet> m_propertySet;
+ RefPtrWillBeMember<MutableStylePropertySet> m_propertySet;
bool m_hasAuthorStyle;
};
diff --git a/chromium/third_party/WebKit/Source/core/css/svg.css b/chromium/third_party/WebKit/Source/core/css/svg.css
index 3975ab42872..6151d17c5d2 100644
--- a/chromium/third_party/WebKit/Source/core/css/svg.css
+++ b/chromium/third_party/WebKit/Source/core/css/svg.css
@@ -47,14 +47,23 @@ svg:not(:root), symbol, image, marker, pattern, foreignObject {
overflow: hidden
}
+svg:root {
+ width: 100%;
+ height: 100%
+}
+
text, foreignObject {
display: block
}
-text, tspan, textPath {
+text {
white-space: nowrap
}
+tspan, textPath {
+ white-space: inherit
+}
+
/* states */
:focus {
diff --git a/chromium/third_party/WebKit/Source/core/css/themeChromium.css b/chromium/third_party/WebKit/Source/core/css/themeChromium.css
index 0a413e1efde..6094c1dd04e 100644
--- a/chromium/third_party/WebKit/Source/core/css/themeChromium.css
+++ b/chromium/third_party/WebKit/Source/core/css/themeChromium.css
@@ -30,7 +30,7 @@
/* These styles override other user-agent styles for Chromium. */
-input:disabled, isindex:disabled, textarea:disabled {
+input:disabled, textarea:disabled {
color: #545454; /* Color::light() for #000000. See RenderTextControl.cpp:disabledTextColor */
}
diff --git a/chromium/third_party/WebKit/Source/core/css/themeChromiumAndroid.css b/chromium/third_party/WebKit/Source/core/css/themeChromiumAndroid.css
index be5488fc854..3ff3183058b 100644
--- a/chromium/third_party/WebKit/Source/core/css/themeChromiumAndroid.css
+++ b/chromium/third_party/WebKit/Source/core/css/themeChromiumAndroid.css
@@ -35,7 +35,22 @@ select[multiple],
select[size][multiple] {
-webkit-appearance: menulist;
align-items: center;
- border: 1px solid;
+ background-color: ButtonFace;
+ border: 1px solid #a9a9a9;
border-radius: initial;
white-space: pre;
}
+
+input[type="date"]:disabled,
+input[type="datetime-local"]:disabled,
+input[type="month"]:disabled,
+input[type="time"]:disabled,
+input[type="week"]:disabled,
+input[type="date"]:read-only,
+input[type="datetime-local"]:read-only,
+input[type="month"]:read-only,
+input[type="time"]:read-only,
+input[type="week"]:read-only {
+ background-color: ButtonFace;
+ color: GrayText;
+} \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/core/css/themeMac.css b/chromium/third_party/WebKit/Source/core/css/themeMac.css
new file mode 100644
index 00000000000..64950d72c65
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/css/themeMac.css
@@ -0,0 +1,20 @@
+/* Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+select, input[type="color"][list] {
+ background-color: #f8f8f8;
+ border: 1px solid #a6a6a6;
+}
+
+select[size],
+select[multiple],
+select[size][multiple] {
+ background: white;
+ border: 1px inset gray;
+}
+
+input::-webkit-inner-spin-button {
+ align-self: center;
+}
diff --git a/chromium/third_party/WebKit/Source/core/css/themeWin.css b/chromium/third_party/WebKit/Source/core/css/themeWin.css
index 3c727d33b66..09b348a35a7 100644
--- a/chromium/third_party/WebKit/Source/core/css/themeWin.css
+++ b/chromium/third_party/WebKit/Source/core/css/themeWin.css
@@ -33,7 +33,6 @@
making our form elements match Firefox's. */
input:not([type]),
-input[type="color"],
input[type="email"],
input[type="number"],
input[type="password"],
diff --git a/chromium/third_party/WebKit/Source/core/css/view-source.css b/chromium/third_party/WebKit/Source/core/css/view-source.css
index daebdbf4f67..6c2077c647c 100644
--- a/chromium/third_party/WebKit/Source/core/css/view-source.css
+++ b/chromium/third_party/WebKit/Source/core/css/view-source.css
@@ -82,6 +82,11 @@ tbody:last-child .webkit-line-content:empty:before {
padding: 0 5px !important;
}
+.webkit-highlight {
+ background-color: rgb(100%, 42%, 42%);
+ border: 2px solid rgb(100%, 31%, 31%);
+}
+
.webkit-html-tag {
/* Keep this in sync with inspector.css (.webkit-html-tag) */
color: rgb(136, 18, 128);
diff --git a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp
index be52d0f70fd..78e88e8c6e6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.cpp
@@ -34,7 +34,7 @@ namespace WebCore {
ActiveDOMObject::ActiveDOMObject(ExecutionContext* executionContext)
: ContextLifecycleObserver(executionContext, ActiveDOMObjectType)
, m_pendingActivityCount(0)
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
, m_suspendIfNeededCalled(false)
#endif
{
@@ -58,7 +58,7 @@ ActiveDOMObject::~ActiveDOMObject()
void ActiveDOMObject::suspendIfNeeded()
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
ASSERT(!m_suspendIfNeededCalled);
m_suspendIfNeededCalled = true;
#endif
@@ -83,4 +83,21 @@ void ActiveDOMObject::stop()
{
}
+void ActiveDOMObject::didMoveToNewExecutionContext(ExecutionContext* context)
+{
+ observeContext(context);
+
+ if (context->activeDOMObjectsAreStopped()) {
+ stop();
+ return;
+ }
+
+ if (context->activeDOMObjectsAreSuspended()) {
+ suspend();
+ return;
+ }
+
+ resume();
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h
index 1157363cb3b..e35637c4d4c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObject.h
@@ -29,7 +29,6 @@
#include "core/dom/ContextLifecycleObserver.h"
#include "wtf/Assertions.h"
-#include "wtf/Forward.h"
namespace WebCore {
@@ -40,7 +39,7 @@ public:
// suspendIfNeeded() should be called exactly once after object construction to synchronize
// the suspend state with that in ExecutionContext.
void suspendIfNeeded();
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool suspendIfNeededCalled() const { return m_suspendIfNeededCalled; }
#endif
@@ -57,6 +56,8 @@ public:
virtual void resume();
virtual void stop();
+ void didMoveToNewExecutionContext(ExecutionContext*);
+
protected:
virtual ~ActiveDOMObject();
@@ -76,7 +77,7 @@ protected:
private:
unsigned m_pendingActivityCount;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool m_suspendIfNeededCalled;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObjectTest.cpp b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObjectTest.cpp
new file mode 100644
index 00000000000..9be6d8335f6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ActiveDOMObjectTest.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/Document.h"
+
+#include "core/testing/DummyPageHolder.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class MockActiveDOMObject : public ActiveDOMObject {
+public:
+ MockActiveDOMObject(ExecutionContext* context) : ActiveDOMObject(context) { }
+
+ MOCK_METHOD0(suspend, void());
+ MOCK_METHOD0(resume, void());
+ MOCK_METHOD0(stop, void());
+};
+
+class ActiveDOMObjectTest : public ::testing::Test {
+protected:
+ ActiveDOMObjectTest();
+
+ Document& srcDocument() const { return m_srcPageHolder->document(); }
+ Document& destDocument() const { return m_destPageHolder->document(); }
+ MockActiveDOMObject& activeDOMObject() { return m_activeDOMObject; }
+
+private:
+ OwnPtr<DummyPageHolder> m_srcPageHolder;
+ OwnPtr<DummyPageHolder> m_destPageHolder;
+ MockActiveDOMObject m_activeDOMObject;
+};
+
+ActiveDOMObjectTest::ActiveDOMObjectTest()
+ : m_srcPageHolder(DummyPageHolder::create(IntSize(800, 600)))
+ , m_destPageHolder(DummyPageHolder::create(IntSize(800, 600)))
+ , m_activeDOMObject(&m_srcPageHolder->document())
+{
+ m_activeDOMObject.suspendIfNeeded();
+}
+
+TEST_F(ActiveDOMObjectTest, NewContextObserved)
+{
+ unsigned initialSrcCount = srcDocument().activeDOMObjectCount();
+ unsigned initialDestCount = destDocument().activeDOMObjectCount();
+
+ EXPECT_CALL(activeDOMObject(), resume());
+ activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+
+ EXPECT_EQ(initialSrcCount - 1, srcDocument().activeDOMObjectCount());
+ EXPECT_EQ(initialDestCount + 1, destDocument().activeDOMObjectCount());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToActiveDocument)
+{
+ EXPECT_CALL(activeDOMObject(), resume());
+ activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToSuspendedDocument)
+{
+ destDocument().suspendScheduledTasks();
+
+ EXPECT_CALL(activeDOMObject(), suspend());
+ activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToStoppedDocument)
+{
+ destDocument().detach();
+
+ EXPECT_CALL(activeDOMObject(), stop());
+ activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+} // unnamed namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/Attr.cpp b/chromium/third_party/WebKit/Source/core/dom/Attr.cpp
index b67b2818f65..802bc19f555 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Attr.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Attr.cpp
@@ -23,11 +23,10 @@
#include "config.h"
#include "core/dom/Attr.h"
-#include "XMLNSNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
-#include "core/dom/ExceptionCode.h"
#include "core/dom/Text.h"
#include "core/events/ScopedEventQueue.h"
#include "core/frame/UseCounter.h"
@@ -49,24 +48,24 @@ Attr::Attr(Element& element, const QualifiedName& name)
Attr::Attr(Document& document, const QualifiedName& name, const AtomicString& standaloneValue)
: ContainerNode(&document)
- , m_element(0)
+ , m_element(nullptr)
, m_name(name)
- , m_standaloneValue(standaloneValue)
+ , m_standaloneValueOrAttachedLocalName(standaloneValue)
, m_ignoreChildrenChanged(0)
{
ScriptWrappable::init(this);
}
-PassRefPtr<Attr> Attr::create(Element& element, const QualifiedName& name)
+PassRefPtrWillBeRawPtr<Attr> Attr::create(Element& element, const QualifiedName& name)
{
- RefPtr<Attr> attr = adoptRef(new Attr(element, name));
+ RefPtrWillBeRawPtr<Attr> attr = adoptRefWillBeNoop(new Attr(element, name));
attr->createTextChild();
return attr.release();
}
-PassRefPtr<Attr> Attr::create(Document& document, const QualifiedName& name, const AtomicString& value)
+PassRefPtrWillBeRawPtr<Attr> Attr::create(Document& document, const QualifiedName& name, const AtomicString& value)
{
- RefPtr<Attr> attr = adoptRef(new Attr(document, name, value));
+ RefPtrWillBeRawPtr<Attr> attr = adoptRefWillBeNoop(new Attr(document, name, value));
attr->createTextChild();
return attr.release();
}
@@ -75,11 +74,26 @@ Attr::~Attr()
{
}
+const QualifiedName Attr::qualifiedName() const
+{
+ if (m_element && !m_standaloneValueOrAttachedLocalName.isNull()) {
+ // In the unlikely case the Element attribute has a local name
+ // that differs by case, construct the qualified name based on
+ // it. This is the qualified name that must be used when
+ // looking up the attribute on the element.
+ return QualifiedName(m_name.prefix(), m_standaloneValueOrAttachedLocalName, m_name.namespaceURI());
+ }
+
+ return m_name;
+}
+
void Attr::createTextChild()
{
+#if !ENABLE(OILPAN)
ASSERT(refCount());
+#endif
if (!value().isEmpty()) {
- RefPtr<Text> textNode = document().createTextNode(value().string());
+ RefPtrWillBeRawPtr<Text> textNode = document().createTextNode(value().string());
// This does everything appendChild() would do in this situation (assuming m_ignoreChildrenChanged was set),
// but much more efficiently.
@@ -90,31 +104,6 @@ void Attr::createTextChild()
}
}
-void Attr::setPrefix(const AtomicString& prefix, ExceptionState& exceptionState)
-{
- UseCounter::count(document(), UseCounter::AttributeSetPrefix);
-
- checkSetPrefix(prefix, exceptionState);
- if (exceptionState.hadException())
- return;
-
- if (prefix == xmlnsAtom && namespaceURI() != XMLNSNames::xmlnsNamespaceURI) {
- exceptionState.throwDOMException(NamespaceError, "The prefix '" + xmlnsAtom + "' may not be used on the namespace '" + namespaceURI() + "'.");
- return;
- }
-
- if (this->qualifiedName() == xmlnsAtom) {
- exceptionState.throwDOMException(NamespaceError, "The prefix '" + prefix + "' may not be used as a namespace prefix for attributes whose qualified name is '" + xmlnsAtom + "'.");
- return;
- }
-
- const AtomicString& newPrefix = prefix.isEmpty() ? nullAtom : prefix;
-
- if (m_element)
- elementAttribute().setPrefix(newPrefix);
- m_name.setPrefix(newPrefix);
-}
-
void Attr::setValue(const AtomicString& value)
{
EventQueueScope scope;
@@ -123,14 +112,15 @@ void Attr::setValue(const AtomicString& value)
if (m_element)
elementAttribute().setValue(value);
else
- m_standaloneValue = value;
+ m_standaloneValueOrAttachedLocalName = value;
createTextChild();
m_ignoreChildrenChanged--;
- invalidateNodeListCachesInAncestors(&m_name, m_element);
+ QualifiedName name = qualifiedName();
+ invalidateNodeListCachesInAncestors(&name, m_element);
}
-void Attr::setValue(const AtomicString& value, ExceptionState&)
+void Attr::setValueInternal(const AtomicString& value)
{
if (m_element)
m_element->willModifyAttribute(qualifiedName(), this->value(), value);
@@ -141,14 +131,30 @@ void Attr::setValue(const AtomicString& value, ExceptionState&)
m_element->didModifyAttribute(qualifiedName(), value);
}
+const AtomicString& Attr::valueForBindings() const
+{
+ UseCounter::count(document(), UseCounter::AttrGetValue);
+ return value();
+}
+
+void Attr::setValueForBindings(const AtomicString& value)
+{
+ UseCounter::count(document(), UseCounter::AttrSetValue);
+ if (m_element)
+ UseCounter::count(document(), UseCounter::AttrSetValueWithElement);
+ setValueInternal(value);
+}
+
void Attr::setNodeValue(const String& v)
{
- setValue(v, IGNORE_EXCEPTION);
+ // Attr uses AtomicString type for its value to save memory as there
+ // is duplication among Elements' attributes values.
+ setValueInternal(AtomicString(v));
}
-PassRefPtr<Node> Attr::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> Attr::cloneNode(bool /*deep*/)
{
- RefPtr<Attr> clone = adoptRef(new Attr(document(), qualifiedName(), value()));
+ RefPtrWillBeRawPtr<Attr> clone = adoptRefWillBeNoop(new Attr(document(), m_name, value()));
cloneChildNodes(clone.get());
return clone.release();
}
@@ -164,7 +170,8 @@ void Attr::childrenChanged(bool, Node*, Node*, int)
if (m_ignoreChildrenChanged > 0)
return;
- invalidateNodeListCachesInAncestors(&qualifiedName(), m_element);
+ QualifiedName name = qualifiedName();
+ invalidateNodeListCachesInAncestors(&name, m_element);
StringBuilder valueBuilder;
for (Node *n = firstChild(); n; n = n->nextSibling()) {
@@ -179,44 +186,44 @@ void Attr::childrenChanged(bool, Node*, Node*, int)
if (m_element)
elementAttribute().setValue(newValue);
else
- m_standaloneValue = newValue;
+ m_standaloneValueOrAttachedLocalName = newValue;
if (m_element)
m_element->attributeChanged(qualifiedName(), newValue);
}
-bool Attr::isId() const
-{
- return qualifiedName().matches(document().idAttributeName());
-}
-
const AtomicString& Attr::value() const
{
if (m_element)
return m_element->getAttribute(qualifiedName());
- return m_standaloneValue;
+ return m_standaloneValueOrAttachedLocalName;
}
Attribute& Attr::elementAttribute()
{
ASSERT(m_element);
ASSERT(m_element->elementData());
- return *m_element->ensureUniqueElementData()->getAttributeItem(qualifiedName());
+ return *m_element->ensureUniqueElementData().findAttributeByName(qualifiedName());
}
void Attr::detachFromElementWithValue(const AtomicString& value)
{
ASSERT(m_element);
- ASSERT(m_standaloneValue.isNull());
- m_standaloneValue = value;
- m_element = 0;
+ m_standaloneValueOrAttachedLocalName = value;
+ m_element = nullptr;
}
-void Attr::attachToElement(Element* element)
+void Attr::attachToElement(Element* element, const AtomicString& attachedLocalName)
{
ASSERT(!m_element);
m_element = element;
- m_standaloneValue = nullAtom;
+ m_standaloneValueOrAttachedLocalName = attachedLocalName;
+}
+
+void Attr::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ ContainerNode::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/Attr.h b/chromium/third_party/WebKit/Source/core/dom/Attr.h
index 40d812b3997..b6b2b4d362c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Attr.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Attr.h
@@ -30,9 +30,7 @@
namespace WebCore {
-class CSSStyleDeclaration;
class ExceptionState;
-class MutableStylePropertySet;
// Attr can have Text children
// therefore it has to be a fullblown Node. The plan
@@ -42,30 +40,30 @@ class MutableStylePropertySet;
class Attr FINAL : public ContainerNode {
public:
- static PassRefPtr<Attr> create(Element&, const QualifiedName&);
- static PassRefPtr<Attr> create(Document&, const QualifiedName&, const AtomicString& value);
+ static PassRefPtrWillBeRawPtr<Attr> create(Element&, const QualifiedName&);
+ static PassRefPtrWillBeRawPtr<Attr> create(Document&, const QualifiedName&, const AtomicString& value);
virtual ~Attr();
- String name() const { return qualifiedName().toString(); }
+ String name() const { return m_name.toString(); }
bool specified() const { return true; }
Element* ownerElement() const { return m_element; }
const AtomicString& value() const;
- void setValue(const AtomicString&, ExceptionState&);
void setValue(const AtomicString&);
- const QualifiedName& qualifiedName() const { return m_name; }
+ const AtomicString& valueForBindings() const;
+ void setValueForBindings(const AtomicString&);
- bool isId() const;
+ const QualifiedName qualifiedName() const;
- void attachToElement(Element*);
+ void attachToElement(Element*, const AtomicString&);
void detachFromElementWithValue(const AtomicString&);
virtual const AtomicString& localName() const OVERRIDE { return m_name.localName(); }
virtual const AtomicString& namespaceURI() const OVERRIDE { return m_name.namespaceURI(); }
- virtual const AtomicString& prefix() const OVERRIDE { return m_name.prefix(); }
+ const AtomicString& prefix() const { return m_name.prefix(); }
- virtual void setPrefix(const AtomicString&, ExceptionState&) OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
private:
Attr(Element&, const QualifiedName&);
@@ -73,25 +71,31 @@ private:
void createTextChild();
+ void setValueInternal(const AtomicString&);
+
virtual String nodeName() const OVERRIDE { return name(); }
virtual NodeType nodeType() const OVERRIDE { return ATTRIBUTE_NODE; }
virtual String nodeValue() const OVERRIDE { return value(); }
- virtual void setNodeValue(const String&);
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
+ virtual void setNodeValue(const String&) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
- virtual bool isAttributeNode() const { return true; }
- virtual bool childTypeAllowed(NodeType) const;
+ virtual bool isAttributeNode() const OVERRIDE { return true; }
+ virtual bool childTypeAllowed(NodeType) const OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
Attribute& elementAttribute();
// Attr wraps either an element/name, or a name/value pair (when it's a standalone Node.)
// Note that m_name is always set, but m_element/m_standaloneValue may be null.
- Element* m_element;
+ RawPtrWillBeMember<Element> m_element;
QualifiedName m_name;
- AtomicString m_standaloneValue;
+ // Holds the value if it is a standalone Node, or the local name of the
+ // attribute it is attached to on an Element. The latter may (letter case)
+ // differ from m_name's local name. As these two modes are non-overlapping,
+ // use a single field.
+ AtomicString m_standaloneValueOrAttachedLocalName;
unsigned m_ignoreChildrenChanged;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Attr.idl b/chromium/third_party/WebKit/Source/core/dom/Attr.idl
index 00d9205a929..9c1fb6c82a5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Attr.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Attr.idl
@@ -26,20 +26,18 @@ interface Attr : Node {
[MeasureAs=AttributeSpecified] readonly attribute boolean specified;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, RaisesException=Setter, CustomElementCallbacks] attribute DOMString value;
+ [ImplementedAs=valueForBindings, TreatReturnedNullStringAs=Null, TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString value;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, DeprecateAs=AttrNodeValue, ImplementedAs=valueForBindings] attribute DOMString nodeValue;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, DeprecateAs=AttrTextContent, ImplementedAs=valueForBindings] attribute DOMString textContent;
// DOM Level 2
- [MeasureAs=AttributeOwnerElement] readonly attribute Element ownerElement;
-
- // DOM Level 3
-
- [MeasureAs=AttributeIsId] readonly attribute boolean isId;
+ [DeprecateAs=AttributeOwnerElement] readonly attribute Element ownerElement;
// DOM 4
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, RaisesException=Setter] attribute DOMString prefix;
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString namespaceURI;
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString localName;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString prefix;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString namespaceURI;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString localName;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp b/chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp
index ec61f0995a0..5ae5bbf8ee4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/CDATASection.cpp
@@ -32,9 +32,9 @@ inline CDATASection::CDATASection(Document& document, const String& data)
ScriptWrappable::init(this);
}
-PassRefPtr<CDATASection> CDATASection::create(Document& document, const String& data)
+PassRefPtrWillBeRawPtr<CDATASection> CDATASection::create(Document& document, const String& data)
{
- return adoptRef(new CDATASection(document, data));
+ return adoptRefWillBeNoop(new CDATASection(document, data));
}
String CDATASection::nodeName() const
@@ -47,12 +47,7 @@ Node::NodeType CDATASection::nodeType() const
return CDATA_SECTION_NODE;
}
-bool CDATASection::childTypeAllowed(NodeType) const
-{
- return false;
-}
-
-PassRefPtr<Text> CDATASection::cloneWithData(const String& data)
+PassRefPtrWillBeRawPtr<Text> CDATASection::cloneWithData(const String& data)
{
return create(document(), data);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/CDATASection.h b/chromium/third_party/WebKit/Source/core/dom/CDATASection.h
index 338866f02ec..6efcfcc147d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CDATASection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/CDATASection.h
@@ -29,15 +29,14 @@ namespace WebCore {
class CDATASection FINAL : public Text {
public:
- static PassRefPtr<CDATASection> create(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<CDATASection> create(Document&, const String&);
private:
CDATASection(Document&, const String&);
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual bool childTypeAllowed(NodeType) const;
- virtual PassRefPtr<Text> cloneWithData(const String&) OVERRIDE;
+ virtual String nodeName() const OVERRIDE;
+ virtual NodeType nodeType() const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Text> cloneWithData(const String&) OVERRIDE;
};
DEFINE_NODE_TYPE_CASTS(CDATASection, nodeType() == Node::CDATA_SECTION_NODE);
diff --git a/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp b/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp
index 074d6b2ee81..123c036df47 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.cpp
@@ -31,13 +31,13 @@
#include "config.h"
#include "core/dom/CSSSelectorWatch.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSSelectorList.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
#include "core/rendering/style/StyleRareNonInheritedData.h"
namespace WebCore {
@@ -54,10 +54,10 @@ CSSSelectorWatch::CSSSelectorWatch(Document& document)
CSSSelectorWatch& CSSSelectorWatch::from(Document& document)
{
- CSSSelectorWatch* watch = static_cast<CSSSelectorWatch*>(DocumentSupplement::from(&document, kSupplementName));
+ CSSSelectorWatch* watch = static_cast<CSSSelectorWatch*>(DocumentSupplement::from(document, kSupplementName));
if (!watch) {
watch = new CSSSelectorWatch(document);
- DocumentSupplement::provideTo(&document, kSupplementName, adoptPtr(watch));
+ DocumentSupplement::provideTo(document, kSupplementName, adoptPtrWillBeNoop(watch));
}
return *watch;
}
@@ -69,7 +69,7 @@ void CSSSelectorWatch::callbackSelectorChangeTimerFired(Timer<CSSSelectorWatch>*
if (m_timerExpirations < 1) {
m_timerExpirations++;
- m_callbackSelectorChangeTimer.startOneShot(0);
+ m_callbackSelectorChangeTimer.startOneShot(0, FROM_HERE);
return;
}
if (m_document.frame()) {
@@ -125,13 +125,13 @@ void CSSSelectorWatch::updateSelectorMatches(const Vector<String>& removedSelect
} else {
m_timerExpirations = 0;
if (!m_callbackSelectorChangeTimer.isActive())
- m_callbackSelectorChangeTimer.startOneShot(0);
+ m_callbackSelectorChangeTimer.startOneShot(0, FROM_HERE);
}
}
static bool allCompound(const CSSSelectorList& selectorList)
{
- for (const CSSSelector* selector = selectorList.first(); selector; selector = selectorList.next(selector)) {
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = selectorList.next(*selector)) {
if (!selector->isCompound())
return false;
}
@@ -141,8 +141,7 @@ static bool allCompound(const CSSSelectorList& selectorList)
void CSSSelectorWatch::watchCSSSelectors(const Vector<String>& selectors)
{
m_watchedCallbackSelectors.clear();
- CSSParserContext context(UASheetMode);
- CSSParser parser(context);
+ BisonCSSParser parser(CSSParserContext(UASheetMode, 0));
const CSSProperty callbackProperty(CSSPropertyInternalCallback, CSSPrimitiveValue::createIdentifier(CSSValueInternalPresence));
const RefPtr<StylePropertySet> callbackPropertySet = ImmutableStylePropertySet::create(&callbackProperty, 1, UASheetMode);
@@ -157,7 +156,7 @@ void CSSSelectorWatch::watchCSSSelectors(const Vector<String>& selectors)
if (!allCompound(selectorList))
continue;
- RefPtr<StyleRule> rule = StyleRule::create();
+ RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create();
rule->wrapperAdoptSelectorList(selectorList);
rule->setProperties(callbackPropertySet);
m_watchedCallbackSelectors.append(rule.release());
@@ -165,4 +164,10 @@ void CSSSelectorWatch::watchCSSSelectors(const Vector<String>& selectors)
m_document.changedSelectorWatch();
}
+void CSSSelectorWatch::trace(Visitor* visitor)
+{
+ visitor->trace(m_watchedCallbackSelectors);
+ DocumentSupplement::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h b/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
index e1cbbed5608..35756c7a24b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
+++ b/chromium/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
@@ -43,24 +43,27 @@
namespace WebCore {
-class CSSSelectorWatch : public DocumentSupplement {
+class CSSSelectorWatch FINAL : public NoBaseWillBeGarbageCollectedFinalized<CSSSelectorWatch>, public DocumentSupplement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(CSSSelectorWatch);
public:
virtual ~CSSSelectorWatch() { }
static CSSSelectorWatch& from(Document&);
void watchCSSSelectors(const Vector<String>& selectors);
- const Vector<RefPtr<StyleRule> >& watchedCallbackSelectors() const { return m_watchedCallbackSelectors; }
+ const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedCallbackSelectors() const { return m_watchedCallbackSelectors; }
void updateSelectorMatches(const Vector<String>& removedSelectors, const Vector<String>& addedSelectors);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- CSSSelectorWatch(Document&);
+ explicit CSSSelectorWatch(Document&);
void callbackSelectorChangeTimerFired(Timer<CSSSelectorWatch>*);
Document& m_document;
- Vector<RefPtr<StyleRule> > m_watchedCallbackSelectors;
+ WillBeHeapVector<RefPtrWillBeMember<StyleRule> > m_watchedCallbackSelectors;
// Maps a CSS selector string with a -webkit-callback property to the number
// of matching RenderStyle objects in this document.
diff --git a/chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp b/chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp
index d0344f255cd..fce49e276d4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/CharacterData.cpp
@@ -31,10 +31,8 @@
#include "core/dom/Text.h"
#include "core/editing/FrameSelection.h"
#include "core/events/MutationEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/inspector/InspectorInstrumentation.h"
-
-using namespace std;
+#include "wtf/CheckedArithmetic.h"
namespace WebCore {
@@ -49,7 +47,7 @@ void CharacterData::setData(const String& data)
if (m_data == nonNullData)
return;
- RefPtr<CharacterData> protect = this;
+ RefPtrWillBeRawPtr<CharacterData> protect(this);
unsigned oldLength = length();
@@ -70,7 +68,7 @@ String CharacterData::substringData(unsigned offset, unsigned count, ExceptionSt
void CharacterData::parserAppendData(const String& string)
{
unsigned oldLength = m_data.length();
- m_data.append(string);
+ m_data = m_data + string;
ASSERT(!renderer() || isTextNode());
if (isTextNode())
@@ -106,45 +104,49 @@ void CharacterData::insertData(unsigned offset, const String& data, ExceptionSta
document().didInsertText(this, offset, data.length());
}
-void CharacterData::deleteData(unsigned offset, unsigned count, ExceptionState& exceptionState, RecalcStyleBehavior recalcStyleBehavior)
+static bool validateOffsetCount(unsigned offset, unsigned count, unsigned length, unsigned& realCount, ExceptionState& exceptionState)
{
- if (offset > length()) {
- exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is greater than the node's length (" + String::number(length()) + ").");
- return;
+ if (offset > length) {
+ exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is greater than the node's length (" + String::number(length) + ").");
+ return false;
}
- unsigned realCount;
- if (offset + count > length())
- realCount = length() - offset;
+ Checked<unsigned, RecordOverflow> offsetCount = offset;
+ offsetCount += count;
+
+ if (offsetCount.hasOverflowed() || offset + count > length)
+ realCount = length - offset;
else
realCount = count;
+ return true;
+}
+
+void CharacterData::deleteData(unsigned offset, unsigned count, ExceptionState& exceptionState, RecalcStyleBehavior recalcStyleBehavior)
+{
+ unsigned realCount = 0;
+ if (!validateOffsetCount(offset, count, length(), realCount, exceptionState))
+ return;
+
String newStr = m_data;
newStr.remove(offset, realCount);
- setDataAndUpdate(newStr, offset, count, 0, recalcStyleBehavior);
+ setDataAndUpdate(newStr, offset, realCount, 0, recalcStyleBehavior);
document().didRemoveText(this, offset, realCount);
}
void CharacterData::replaceData(unsigned offset, unsigned count, const String& data, ExceptionState& exceptionState)
{
- if (offset > length()) {
- exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is greater than the node's length (" + String::number(length()) + ").");
+ unsigned realCount = 0;
+ if (!validateOffsetCount(offset, count, length(), realCount, exceptionState))
return;
- }
-
- unsigned realCount;
- if (offset + count > length())
- realCount = length() - offset;
- else
- realCount = count;
String newStr = m_data;
newStr.remove(offset, realCount);
newStr.insert(data, offset);
- setDataAndUpdate(newStr, offset, count, data.length());
+ setDataAndUpdate(newStr, offset, realCount, data.length());
// update the markers for spell checking and grammar checking
document().didRemoveText(this, offset, realCount);
@@ -176,7 +178,7 @@ void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfRep
toText(this)->updateTextRenderer(offsetOfReplacedData, oldLength, recalcStyleBehavior);
if (nodeType() == PROCESSING_INSTRUCTION_NODE)
- toProcessingInstruction(this)->checkStyleSheet();
+ toProcessingInstruction(this)->didAttributeChanged();
if (document().frame())
document().frame()->selection().didUpdateCharacterData(this, offsetOfReplacedData, oldLength, newLength);
@@ -187,7 +189,7 @@ void CharacterData::setDataAndUpdate(const String& newData, unsigned offsetOfRep
void CharacterData::didModifyData(const String& oldData)
{
- if (OwnPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this))
+ if (OwnPtrWillBeRawPtr<MutationObserverInterestGroup> mutationRecipients = MutationObserverInterestGroup::createForCharacterDataMutation(*this))
mutationRecipients->enqueueMutationRecord(MutationRecord::createCharacterData(this, oldData));
if (parentNode())
@@ -195,7 +197,7 @@ void CharacterData::didModifyData(const String& oldData)
if (!isInShadowTree()) {
if (document().hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
- dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMCharacterDataModified, true, 0, oldData, m_data));
+ dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMCharacterDataModified, true, nullptr, oldData, m_data));
dispatchSubtreeModifiedEvent();
}
InspectorInstrumentation::characterDataModified(this);
diff --git a/chromium/third_party/WebKit/Source/core/dom/CharacterData.h b/chromium/third_party/WebKit/Source/core/dom/CharacterData.h
index 11636228cc7..a89eccdf833 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CharacterData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/CharacterData.h
@@ -33,7 +33,7 @@ class ExceptionState;
class CharacterData : public Node {
public:
void atomize();
- String data() const { return m_data; }
+ const String& data() const { return m_data; }
void setData(const String&);
unsigned length() const { return m_data.length(); }
String substringData(unsigned offset, unsigned count, ExceptionState&);
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp b/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp
new file mode 100644
index 00000000000..555da1cd3b9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.cpp
@@ -0,0 +1,106 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/ChildFrameDisconnector.h"
+
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "wtf/Assertions.h"
+
+namespace WebCore {
+
+#ifndef NDEBUG
+static unsigned checkConnectedSubframeCountIsConsistent(Node&);
+#endif
+
+void ChildFrameDisconnector::disconnect(DisconnectPolicy policy)
+{
+#ifndef NDEBUG
+ checkConnectedSubframeCountIsConsistent(m_root);
+#endif
+
+ if (!m_root.connectedSubframeCount())
+ return;
+
+ if (policy == RootAndDescendants) {
+ collectFrameOwners(m_root);
+ } else {
+ for (Node* child = m_root.firstChild(); child; child = child->nextSibling())
+ collectFrameOwners(*child);
+ }
+
+ disconnectCollectedFrameOwners();
+}
+
+void ChildFrameDisconnector::collectFrameOwners(Node& root)
+{
+ if (!root.connectedSubframeCount())
+ return;
+
+ if (root.isHTMLElement() && root.isFrameOwnerElement())
+ m_frameOwners.append(&toHTMLFrameOwnerElement(root));
+
+ for (Node* child = root.firstChild(); child; child = child->nextSibling())
+ collectFrameOwners(*child);
+
+ ElementShadow* shadow = root.isElementNode() ? toElement(root).shadow() : 0;
+ if (shadow)
+ collectFrameOwners(*shadow);
+}
+
+void ChildFrameDisconnector::disconnectCollectedFrameOwners()
+{
+ // Must disable frame loading in the subtree so an unload handler cannot
+ // insert more frames and create loaded frames in detached subtrees.
+ SubframeLoadingDisabler disabler(m_root);
+
+ for (unsigned i = 0; i < m_frameOwners.size(); ++i) {
+ HTMLFrameOwnerElement* owner = m_frameOwners[i].get();
+ // Don't need to traverse up the tree for the first owner since no
+ // script could have moved it.
+ if (!i || m_root.containsIncludingShadowDOM(owner))
+ owner->disconnectContentFrame();
+ }
+}
+
+void ChildFrameDisconnector::collectFrameOwners(ElementShadow& shadow)
+{
+ for (ShadowRoot* root = shadow.youngestShadowRoot(); root; root = root->olderShadowRoot())
+ collectFrameOwners(*root);
+}
+
+#ifndef NDEBUG
+static unsigned checkConnectedSubframeCountIsConsistent(Node& node)
+{
+ unsigned count = 0;
+
+ if (node.isElementNode()) {
+ if (node.isFrameOwnerElement() && toHTMLFrameOwnerElement(node).contentFrame())
+ count++;
+
+ if (ElementShadow* shadow = toElement(node).shadow()) {
+ for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
+ count += checkConnectedSubframeCountIsConsistent(*root);
+ }
+ }
+
+ for (Node* child = node.firstChild(); child; child = child->nextSibling())
+ count += checkConnectedSubframeCountIsConsistent(*child);
+
+ // If we undercount there's possibly a security bug since we'd leave frames
+ // in subtrees outside the document.
+ ASSERT(node.connectedSubframeCount() >= count);
+
+ // If we overcount it's safe, but not optimal because it means we'll traverse
+ // through the document in ChildFrameDisconnector looking for frames that have
+ // already been disconnected.
+ ASSERT(node.connectedSubframeCount() == count);
+
+ return count;
+}
+#endif
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.h b/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.h
new file mode 100644
index 00000000000..d77e9086f64
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildFrameDisconnector.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ChildFrameDisconnector_h
+#define ChildFrameDisconnector_h
+
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class ElementShadow;
+class HTMLFrameOwnerElement;
+class Node;
+
+class ChildFrameDisconnector {
+ STACK_ALLOCATED();
+public:
+ enum DisconnectPolicy {
+ RootAndDescendants,
+ DescendantsOnly
+ };
+
+ explicit ChildFrameDisconnector(Node& root)
+ : m_root(root)
+ {
+ }
+
+ void disconnect(DisconnectPolicy = RootAndDescendants);
+
+private:
+ void collectFrameOwners(Node&);
+ void collectFrameOwners(ElementShadow&);
+ void disconnectCollectedFrameOwners();
+
+ WillBeHeapVector<RefPtrWillBeMember<HTMLFrameOwnerElement>, 10> m_frameOwners;
+ Node& m_root;
+};
+
+} // namespace WebCore
+
+#endif // ChildFrameDisconnector_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp b/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp
index 1d00364cac5..73593055290 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.cpp
@@ -39,36 +39,47 @@
namespace WebCore {
-typedef HashMap<Node*, ChildListMutationAccumulator*> AccumulatorMap;
+// The accumulator map is used to make sure that there is only one mutation
+// accumulator for a given node even if there are multiple ChildListMutationScopes
+// on the stack. The map is always empty when there are no ChildListMutationScopes
+// on the stack.
+typedef WillBeHeapHashMap<RawPtrWillBeMember<Node>, RawPtrWillBeMember<ChildListMutationAccumulator> > AccumulatorMap;
+
static AccumulatorMap& accumulatorMap()
{
- DEFINE_STATIC_LOCAL(AccumulatorMap, map, ());
- return map;
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<AccumulatorMap>, map, (adoptPtrWillBeNoop(new AccumulatorMap())));
+ return *map;
}
-ChildListMutationAccumulator::ChildListMutationAccumulator(PassRefPtr<Node> target, PassOwnPtr<MutationObserverInterestGroup> observers)
+ChildListMutationAccumulator::ChildListMutationAccumulator(PassRefPtrWillBeRawPtr<Node> target, PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> observers)
: m_target(target)
- , m_lastAdded(0)
+ , m_lastAdded(nullptr)
, m_observers(observers)
+ , m_mutationScopes(0)
{
}
-ChildListMutationAccumulator::~ChildListMutationAccumulator()
+void ChildListMutationAccumulator::leaveMutationScope()
{
- if (!isEmpty())
- enqueueMutationRecord();
- accumulatorMap().remove(m_target.get());
+ ASSERT(m_mutationScopes > 0);
+ if (!--m_mutationScopes) {
+ if (!isEmpty())
+ enqueueMutationRecord();
+ accumulatorMap().remove(m_target.get());
+ }
}
-PassRefPtr<ChildListMutationAccumulator> ChildListMutationAccumulator::getOrCreate(Node& target)
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ChildListMutationAccumulator);
+
+PassRefPtrWillBeRawPtr<ChildListMutationAccumulator> ChildListMutationAccumulator::getOrCreate(Node& target)
{
- AccumulatorMap::AddResult result = accumulatorMap().add(&target, 0);
- RefPtr<ChildListMutationAccumulator> accumulator;
+ AccumulatorMap::AddResult result = accumulatorMap().add(&target, nullptr);
+ RefPtrWillBeRawPtr<ChildListMutationAccumulator> accumulator;
if (!result.isNewEntry)
- accumulator = result.iterator->value;
+ accumulator = result.storedValue->value;
else {
- accumulator = adoptRef(new ChildListMutationAccumulator(PassRefPtr<Node>(target), MutationObserverInterestGroup::createForChildListMutation(target)));
- result.iterator->value = accumulator.get();
+ accumulator = adoptRefWillBeNoop(new ChildListMutationAccumulator(PassRefPtrWillBeRawPtr<Node>(target), MutationObserverInterestGroup::createForChildListMutation(target)));
+ result.storedValue->value = accumulator.get();
}
return accumulator.release();
}
@@ -78,11 +89,11 @@ inline bool ChildListMutationAccumulator::isAddedNodeInOrder(Node* child)
return isEmpty() || (m_lastAdded == child->previousSibling() && m_nextSibling == child->nextSibling());
}
-void ChildListMutationAccumulator::childAdded(PassRefPtr<Node> prpChild)
+void ChildListMutationAccumulator::childAdded(PassRefPtrWillBeRawPtr<Node> prpChild)
{
ASSERT(hasObservers());
- RefPtr<Node> child = prpChild;
+ RefPtrWillBeRawPtr<Node> child = prpChild;
if (!isAddedNodeInOrder(child.get()))
enqueueMutationRecord();
@@ -101,11 +112,11 @@ inline bool ChildListMutationAccumulator::isRemovedNodeInOrder(Node* child)
return isEmpty() || m_nextSibling == child;
}
-void ChildListMutationAccumulator::willRemoveChild(PassRefPtr<Node> prpChild)
+void ChildListMutationAccumulator::willRemoveChild(PassRefPtrWillBeRawPtr<Node> prpChild)
{
ASSERT(hasObservers());
- RefPtr<Node> child = prpChild;
+ RefPtrWillBeRawPtr<Node> child = prpChild;
if (!m_addedNodes.isEmpty() || !isRemovedNodeInOrder(child.get()))
enqueueMutationRecord();
@@ -125,11 +136,11 @@ void ChildListMutationAccumulator::enqueueMutationRecord()
ASSERT(hasObservers());
ASSERT(!isEmpty());
- RefPtr<NodeList> addedNodes = StaticNodeList::adopt(m_addedNodes);
- RefPtr<NodeList> removedNodes = StaticNodeList::adopt(m_removedNodes);
- RefPtr<MutationRecord> record = MutationRecord::createChildList(m_target, addedNodes.release(), removedNodes.release(), m_previousSibling.release(), m_nextSibling.release());
+ RefPtrWillBeRawPtr<StaticNodeList> addedNodes = StaticNodeList::adopt(m_addedNodes);
+ RefPtrWillBeRawPtr<StaticNodeList> removedNodes = StaticNodeList::adopt(m_removedNodes);
+ RefPtrWillBeRawPtr<MutationRecord> record = MutationRecord::createChildList(m_target, addedNodes.release(), removedNodes.release(), m_previousSibling.release(), m_nextSibling.release());
m_observers->enqueueMutationRecord(record.release());
- m_lastAdded = 0;
+ m_lastAdded = nullptr;
ASSERT(isEmpty());
}
@@ -146,4 +157,15 @@ bool ChildListMutationAccumulator::isEmpty()
return result;
}
+void ChildListMutationAccumulator::trace(Visitor* visitor)
+{
+ visitor->trace(m_target);
+ visitor->trace(m_removedNodes);
+ visitor->trace(m_addedNodes);
+ visitor->trace(m_previousSibling);
+ visitor->trace(m_nextSibling);
+ visitor->trace(m_lastAdded);
+ visitor->trace(m_observers);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h b/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h
index d847d826a6d..b232335f4d0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildListMutationScope.h
@@ -34,6 +34,7 @@
#include "core/dom/Document.h"
#include "core/dom/MutationObserver.h"
#include "core/dom/Node.h"
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
#include "wtf/RefCounted.h"
@@ -43,58 +44,85 @@ namespace WebCore {
class MutationObserverInterestGroup;
// ChildListMutationAccumulator is not meant to be used directly; ChildListMutationScope is the public interface.
-class ChildListMutationAccumulator : public RefCounted<ChildListMutationAccumulator> {
+//
+// One ChildListMutationAccumulator for a given Node is shared between all the
+// active ChildListMutationScopes for that Node. Once the last ChildListMutationScope
+// is destructed the accumulator enqueues a mutation record for the recorded
+// mutations and the accumulator can be garbage collected.
+class ChildListMutationAccumulator FINAL : public RefCountedWillBeGarbageCollected<ChildListMutationAccumulator> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ChildListMutationAccumulator);
public:
- static PassRefPtr<ChildListMutationAccumulator> getOrCreate(Node&);
- ~ChildListMutationAccumulator();
+ static PassRefPtrWillBeRawPtr<ChildListMutationAccumulator> getOrCreate(Node&);
- void childAdded(PassRefPtr<Node>);
- void willRemoveChild(PassRefPtr<Node>);
+ void childAdded(PassRefPtrWillBeRawPtr<Node>);
+ void willRemoveChild(PassRefPtrWillBeRawPtr<Node>);
bool hasObservers() const { return m_observers; }
+ // Register and unregister mutation scopes that are using this mutation
+ // accumulator.
+ void enterMutationScope() { m_mutationScopes++; }
+ void leaveMutationScope();
+
+ void trace(Visitor*);
+
private:
- ChildListMutationAccumulator(PassRefPtr<Node>, PassOwnPtr<MutationObserverInterestGroup>);
+ ChildListMutationAccumulator(PassRefPtrWillBeRawPtr<Node>, PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup>);
void enqueueMutationRecord();
bool isEmpty();
bool isAddedNodeInOrder(Node*);
bool isRemovedNodeInOrder(Node*);
- RefPtr<Node> m_target;
+ RefPtrWillBeMember<Node> m_target;
+
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_removedNodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_addedNodes;
+ RefPtrWillBeMember<Node> m_previousSibling;
+ RefPtrWillBeMember<Node> m_nextSibling;
+ RawPtrWillBeMember<Node> m_lastAdded;
- Vector<RefPtr<Node> > m_removedNodes;
- Vector<RefPtr<Node> > m_addedNodes;
- RefPtr<Node> m_previousSibling;
- RefPtr<Node> m_nextSibling;
- Node* m_lastAdded;
+ OwnPtrWillBeMember<MutationObserverInterestGroup> m_observers;
- OwnPtr<MutationObserverInterestGroup> m_observers;
+ unsigned m_mutationScopes;
};
-class ChildListMutationScope {
+class ChildListMutationScope FINAL {
WTF_MAKE_NONCOPYABLE(ChildListMutationScope);
+ STACK_ALLOCATED();
public:
explicit ChildListMutationScope(Node& target)
{
- if (target.document().hasMutationObserversOfType(MutationObserver::ChildList))
+ if (target.document().hasMutationObserversOfType(MutationObserver::ChildList)) {
m_accumulator = ChildListMutationAccumulator::getOrCreate(target);
+ // Register another user of the accumulator.
+ m_accumulator->enterMutationScope();
+ }
+ }
+
+ ~ChildListMutationScope()
+ {
+ if (m_accumulator) {
+ // Unregister a user of the accumulator. If this is the last user
+ // the accumulator will enqueue a mutation record for the mutations.
+ m_accumulator->leaveMutationScope();
+ }
}
void childAdded(Node& child)
{
if (m_accumulator && m_accumulator->hasObservers())
- m_accumulator->childAdded(PassRefPtr<Node>(child));
+ m_accumulator->childAdded(&child);
}
void willRemoveChild(Node& child)
{
if (m_accumulator && m_accumulator->hasObservers())
- m_accumulator->willRemoveChild(PassRefPtr<Node>(child));
+ m_accumulator->willRemoveChild(&child);
}
private:
- RefPtr<ChildListMutationAccumulator> m_accumulator;
+ RefPtrWillBeMember<ChildListMutationAccumulator> m_accumulator;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildNode.h b/chromium/third_party/WebKit/Source/core/dom/ChildNode.h
new file mode 100644
index 00000000000..19bcc5a602f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildNode.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ChildNode_h
+#define ChildNode_h
+
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/Node.h"
+
+namespace WebCore {
+
+class ChildNode {
+public:
+ static Element* previousElementSibling(Node& node)
+ {
+ return ElementTraversal::previousSibling(node);
+ }
+
+ static Element* nextElementSibling(Node& node)
+ {
+ return ElementTraversal::nextSibling(node);
+ }
+
+ static void remove(Node& node, ExceptionState& exceptionState)
+ {
+ return node.remove(exceptionState);
+ }
+};
+
+} // namespace WebCore
+
+#endif // ChildNode_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildNode.idl b/chromium/third_party/WebKit/Source/core/dom/ChildNode.idl
index 21441f63506..38ccf66bd57 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildNode.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildNode.idl
@@ -20,12 +20,13 @@
* Boston, MA 02110-1301, USA.
*/
+// http://dom.spec.whatwg.org/#interface-childnode
+
[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface ChildNode {
[PerWorldBindings] readonly attribute Element previousElementSibling;
[PerWorldBindings] readonly attribute Element nextElementSibling;
[RaisesException, CustomElementCallbacks] void remove();
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp
index 4144c04cbe5..c1a895cb932 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.cpp
@@ -1,8 +1,9 @@
-/**
+/*
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,21 +29,50 @@
namespace WebCore {
-ChildNodeList::ChildNodeList(PassRefPtr<Node> node)
- : LiveNodeList(node, ChildNodeListType, DoNotInvalidateOnAttributeChanges)
+ChildNodeList::ChildNodeList(ContainerNode& parent)
+ : m_parent(parent)
{
}
+Node* ChildNodeList::virtualOwnerNode() const
+{
+ return &ownerNode();
+}
+
ChildNodeList::~ChildNodeList()
{
- ownerNode()->nodeLists()->removeChildNodeList(this);
+#if !ENABLE(OILPAN)
+ m_parent->nodeLists()->removeChildNodeList(this);
+#endif
+}
+
+Node* ChildNodeList::traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset) const
+{
+ ASSERT(currentOffset < offset);
+ Node* next = &currentNode;
+ while ((next = next->nextSibling())) {
+ if (++currentOffset == offset)
+ return next;
+ }
+ return 0;
+}
+
+Node* ChildNodeList::traverseBackwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset) const
+{
+ ASSERT(currentOffset > offset);
+ Node* previous = &currentNode;
+ while ((previous = previous->previousSibling())) {
+ if (--currentOffset == offset)
+ return previous;
+ }
+ return 0;
}
-bool ChildNodeList::nodeMatches(Element* testNode) const
+void ChildNodeList::trace(Visitor* visitor)
{
- // This function will be called only by LiveNodeList::namedItem,
- // for an element that was located with getElementById.
- return testNode->parentNode() == rootNode();
+ visitor->trace(m_parent);
+ visitor->trace(m_collectionIndexCache);
+ NodeList::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h b/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h
index 46f5beab4b1..d3a871246cd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ChildNodeList.h
@@ -3,6 +3,7 @@
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,26 +25,52 @@
#ifndef ChildNodeList_h
#define ChildNodeList_h
-#include "core/dom/LiveNodeList.h"
+#include "core/dom/NodeList.h"
+#include "core/html/CollectionIndexCache.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
-class ChildNodeList FINAL : public LiveNodeList {
+class ChildNodeList FINAL : public NodeList {
public:
- static PassRefPtr<ChildNodeList> create(PassRefPtr<Node> rootNode)
+ static PassRefPtrWillBeRawPtr<ChildNodeList> create(ContainerNode& rootNode)
{
- return adoptRef(new ChildNodeList(rootNode));
+ return adoptRefWillBeNoop(new ChildNodeList(rootNode));
}
virtual ~ChildNodeList();
-protected:
- explicit ChildNodeList(PassRefPtr<Node> rootNode);
+ // DOM API.
+ virtual unsigned length() const OVERRIDE { return m_collectionIndexCache.nodeCount(*this); }
+ virtual Node* item(unsigned index) const OVERRIDE { return m_collectionIndexCache.nodeAt(*this, index); }
- virtual bool nodeMatches(Element*) const OVERRIDE;
+ // Non-DOM API.
+ void invalidateCache() { m_collectionIndexCache.invalidate(); }
+ ContainerNode& ownerNode() const { return *m_parent; }
+
+ ContainerNode& rootNode() const { return ownerNode(); }
+
+ // CollectionIndexCache API.
+ bool canTraverseBackward() const { return true; }
+ Node* traverseToFirstElement() const { return rootNode().firstChild(); }
+ Node* traverseToLastElement() const { return rootNode().lastChild(); }
+ Node* traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset) const;
+ Node* traverseBackwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset) const;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit ChildNodeList(ContainerNode& rootNode);
+
+ virtual bool isChildNodeList() const OVERRIDE { return true; }
+ virtual Node* virtualOwnerNode() const OVERRIDE;
+
+ RefPtrWillBeMember<ContainerNode> m_parent;
+ mutable CollectionIndexCache<ChildNodeList, Node> m_collectionIndexCache;
};
+DEFINE_TYPE_CASTS(ChildNodeList, NodeList, nodeList, nodeList->isChildNodeList(), nodeList.isChildNodeList());
+
} // namespace WebCore
#endif // ChildNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClassCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/ClassCollection.cpp
new file mode 100644
index 00000000000..04e2bdcb920
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ClassCollection.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 David Smith (catfish.man@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/ClassCollection.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/NodeRareData.h"
+
+namespace WebCore {
+
+ClassCollection::ClassCollection(ContainerNode& rootNode, const AtomicString& classNames)
+ : HTMLCollection(rootNode, ClassCollectionType, DoesNotOverrideItemAfter)
+ , m_classNames(classNames, document().inQuirksMode())
+ , m_originalClassNames(classNames)
+{
+}
+
+ClassCollection::~ClassCollection()
+{
+#if !ENABLE(OILPAN)
+ ownerNode().nodeLists()->removeCache(this, ClassCollectionType, m_originalClassNames);
+#endif
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClassCollection.h b/chromium/third_party/WebKit/Source/core/dom/ClassCollection.h
new file mode 100644
index 00000000000..d9ddd3b3e17
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ClassCollection.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 David Smith (catfish.man@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ClassCollection_h
+#define ClassCollection_h
+
+#include "core/dom/Element.h"
+#include "core/dom/SpaceSplitString.h"
+#include "core/html/HTMLCollection.h"
+
+namespace WebCore {
+
+class ClassCollection FINAL : public HTMLCollection {
+public:
+ // classNames argument is an AtomicString because it is common for Elements to share the same class names.
+ // It is also used to construct a SpaceSplitString (m_classNames) and its constructor requires an AtomicString.
+ static PassRefPtrWillBeRawPtr<ClassCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& classNames)
+ {
+ ASSERT_UNUSED(type, type == ClassCollectionType);
+ return adoptRefWillBeNoop(new ClassCollection(rootNode, classNames));
+ }
+
+ virtual ~ClassCollection();
+
+ bool elementMatches(const Element&) const;
+
+private:
+ ClassCollection(ContainerNode& rootNode, const AtomicString& classNames);
+
+ SpaceSplitString m_classNames;
+ AtomicString m_originalClassNames;
+};
+
+DEFINE_TYPE_CASTS(ClassCollection, LiveNodeListBase, collection, collection->type() == ClassCollectionType, collection.type() == ClassCollectionType);
+
+inline bool ClassCollection::elementMatches(const Element& testElement) const
+{
+ if (!testElement.hasClass())
+ return false;
+ if (!m_classNames.size())
+ return false;
+ // FIXME: DOM4 allows getElementsByClassName to return non StyledElement.
+ // https://bugs.webkit.org/show_bug.cgi?id=94718
+ if (!testElement.isStyledElement())
+ return false;
+ return testElement.classNames().containsAll(m_classNames);
+}
+
+} // namespace WebCore
+
+#endif // ClassCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.cpp
deleted file mode 100644
index 8b362182679..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2007 David Smith (catfish.man@gmail.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/ClassNodeList.h"
-
-#include "core/dom/Document.h"
-#include "core/dom/NodeRareData.h"
-
-namespace WebCore {
-
-ClassNodeList::ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames)
- : LiveNodeList(rootNode, ClassNodeListType, InvalidateOnClassAttrChange)
- , m_classNames(classNames, document().inQuirksMode())
- , m_originalClassNames(classNames)
-{
-}
-
-ClassNodeList::~ClassNodeList()
-{
- ownerNode()->nodeLists()->removeCacheWithName(this, ClassNodeListType, m_originalClassNames);
-}
-
-bool ClassNodeList::nodeMatches(Element* testNode) const
-{
- return nodeMatchesInlined(testNode);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.h b/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.h
deleted file mode 100644
index 2e08ea81928..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/ClassNodeList.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 David Smith (catfish.man@gmail.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ClassNodeList_h
-#define ClassNodeList_h
-
-#include "core/dom/Element.h"
-#include "core/dom/LiveNodeList.h"
-#include "core/dom/Node.h"
-#include "core/dom/SpaceSplitString.h"
-
-namespace WebCore {
-
-class ClassNodeList FINAL : public LiveNodeList {
-public:
- static PassRefPtr<ClassNodeList> create(PassRefPtr<Node> rootNode, const String& classNames)
- {
- return adoptRef(new ClassNodeList(rootNode, classNames));
- }
-
- virtual ~ClassNodeList();
-
- bool nodeMatchesInlined(Element*) const;
-
-private:
- ClassNodeList(PassRefPtr<Node> rootNode, const String& classNames);
-
- virtual bool nodeMatches(Element*) const OVERRIDE;
-
- SpaceSplitString m_classNames;
- String m_originalClassNames;
-};
-
-inline bool ClassNodeList::nodeMatchesInlined(Element* testNode) const
-{
- if (!testNode->hasClass())
- return false;
- if (!m_classNames.size())
- return false;
- // FIXME: DOM4 allows getElementsByClassName to return non StyledElement.
- // https://bugs.webkit.org/show_bug.cgi?id=94718
- if (!testNode->isStyledElement())
- return false;
- return testNode->classNames().containsAll(m_classNames);
-}
-
-} // namespace WebCore
-
-#endif // ClassNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRect.h b/chromium/third_party/WebKit/Source/core/dom/ClientRect.h
index 3ef3b24f3b4..2fdaeab14dd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRect.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRect.h
@@ -29,33 +29,45 @@
#include "bindings/v8/ScriptWrappable.h"
#include "platform/geometry/FloatRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
- class IntRect;
+class IntRect;
- class ClientRect : public ScriptWrappable, public RefCounted<ClientRect> {
- public:
- static PassRefPtr<ClientRect> create() { return adoptRef(new ClientRect); }
- static PassRefPtr<ClientRect> create(const IntRect& rect) { return adoptRef(new ClientRect(rect)); }
- static PassRefPtr<ClientRect> create(const FloatRect& rect) { return adoptRef(new ClientRect(rect)); }
+class ClientRect FINAL : public RefCountedWillBeGarbageCollectedFinalized<ClientRect>, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<ClientRect> create()
+ {
+ return adoptRefWillBeNoop(new ClientRect);
+ }
+ static PassRefPtrWillBeRawPtr<ClientRect> create(const IntRect& rect)
+ {
+ return adoptRefWillBeNoop(new ClientRect(rect));
+ }
+ static PassRefPtrWillBeRawPtr<ClientRect> create(const FloatRect& rect)
+ {
+ return adoptRefWillBeNoop(new ClientRect(rect));
+ }
- float top() const { return m_rect.y(); }
- float right() const { return m_rect.maxX(); }
- float bottom() const { return m_rect.maxY(); }
- float left() const { return m_rect.x(); }
- float width() const { return m_rect.width(); }
- float height() const { return m_rect.height(); }
+ float top() const { return m_rect.y(); }
+ float right() const { return m_rect.maxX(); }
+ float bottom() const { return m_rect.maxY(); }
+ float left() const { return m_rect.x(); }
+ float width() const { return m_rect.width(); }
+ float height() const { return m_rect.height(); }
- private:
- ClientRect();
- explicit ClientRect(const IntRect&);
- explicit ClientRect(const FloatRect&);
+ void trace(Visitor*) { }
- FloatRect m_rect;
- };
+private:
+ ClientRect();
+ explicit ClientRect(const IntRect&);
+ explicit ClientRect(const FloatRect&);
+
+ FloatRect m_rect;
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRect.idl b/chromium/third_party/WebKit/Source/core/dom/ClientRect.idl
index ffdcfdddeb3..4fae5d7f938 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRect.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRect.idl
@@ -25,6 +25,7 @@
*/
[
+ WillBeGarbageCollected,
] interface ClientRect {
readonly attribute float top;
readonly attribute float right;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp
index c7d054c1594..78288826534 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.cpp
@@ -64,4 +64,9 @@ ClientRect* ClientRectList::item(unsigned index)
return m_list[index].get();
}
+void ClientRectList::trace(Visitor* visitor)
+{
+ visitor->trace(m_list);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.h b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.h
index 0639714f74e..789ca22c712 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.h
@@ -29,6 +29,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "platform/geometry/FloatQuad.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -37,20 +38,28 @@ namespace WebCore {
class ClientRect;
-class ClientRectList : public RefCounted<ClientRectList>, public ScriptWrappable {
+class ClientRectList FINAL : public RefCountedWillBeGarbageCollectedFinalized<ClientRectList>, public ScriptWrappable {
public:
- static PassRefPtr<ClientRectList> create() { return adoptRef(new ClientRectList); }
- static PassRefPtr<ClientRectList> create(const Vector<FloatQuad>& quads) { return adoptRef(new ClientRectList(quads)); }
+ static PassRefPtrWillBeRawPtr<ClientRectList> create()
+ {
+ return adoptRefWillBeNoop(new ClientRectList);
+ }
+ static PassRefPtrWillBeRawPtr<ClientRectList> create(const Vector<FloatQuad>& quads)
+ {
+ return adoptRefWillBeNoop(new ClientRectList(quads));
+ }
~ClientRectList();
unsigned length() const;
ClientRect* item(unsigned index);
+ void trace(Visitor*);
+
private:
ClientRectList();
explicit ClientRectList(const Vector<FloatQuad>&);
- Vector<RefPtr<ClientRect> > m_list;
+ WillBeHeapVector<RefPtrWillBeMember<ClientRect> > m_list;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl
index 7f6b1988c79..bf1454225c6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/ClientRectList.idl
@@ -25,6 +25,7 @@
*/
[
+ WillBeGarbageCollected,
] interface ClientRectList {
readonly attribute unsigned long length;
getter ClientRect item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/dom/Clipboard.cpp b/chromium/third_party/WebKit/Source/core/dom/Clipboard.cpp
deleted file mode 100644
index 4a16d84f8ef..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Clipboard.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/Clipboard.h"
-
-#include "HTMLNames.h"
-#include "core/dom/DataTransferItem.h"
-#include "core/dom/DataTransferItemList.h"
-#include "core/editing/markup.h"
-#include "core/fetch/ImageResource.h"
-#include "core/fileapi/FileList.h"
-#include "core/html/HTMLImageElement.h"
-#include "core/frame/Frame.h"
-#include "core/platform/DragImage.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
-#include "core/rendering/RenderImage.h"
-#include "core/rendering/RenderObject.h"
-#include "platform/MIMETypeRegistry.h"
-#include "platform/clipboard/ClipboardMimeTypes.h"
-#include "platform/clipboard/ClipboardUtilities.h"
-
-namespace WebCore {
-
-// These "conversion" methods are called by both WebCore and WebKit, and never make sense to JS, so we don't
-// worry about security for these. They don't allow access to the pasteboard anyway.
-static DragOperation dragOpFromIEOp(const String& op)
-{
- // yep, it's really just this fixed set
- if (op == "uninitialized")
- return DragOperationEvery;
- if (op == "none")
- return DragOperationNone;
- if (op == "copy")
- return DragOperationCopy;
- if (op == "link")
- return DragOperationLink;
- if (op == "move")
- return (DragOperation)(DragOperationGeneric | DragOperationMove);
- if (op == "copyLink")
- return (DragOperation)(DragOperationCopy | DragOperationLink);
- if (op == "copyMove")
- return (DragOperation)(DragOperationCopy | DragOperationGeneric | DragOperationMove);
- if (op == "linkMove")
- return (DragOperation)(DragOperationLink | DragOperationGeneric | DragOperationMove);
- if (op == "all")
- return DragOperationEvery;
- return DragOperationPrivate; // really a marker for "no conversion"
-}
-
-static String IEOpFromDragOp(DragOperation op)
-{
- bool moveSet = !!((DragOperationGeneric | DragOperationMove) & op);
-
- if ((moveSet && (op & DragOperationCopy) && (op & DragOperationLink))
- || (op == DragOperationEvery))
- return "all";
- if (moveSet && (op & DragOperationCopy))
- return "copyMove";
- if (moveSet && (op & DragOperationLink))
- return "linkMove";
- if ((op & DragOperationCopy) && (op & DragOperationLink))
- return "copyLink";
- if (moveSet)
- return "move";
- if (op & DragOperationCopy)
- return "copy";
- if (op & DragOperationLink)
- return "link";
- return "none";
-}
-
-// We provide the IE clipboard types (URL and Text), and the clipboard types specified in the WHATWG Web Applications 1.0 draft
-// see http://www.whatwg.org/specs/web-apps/current-work/ Section 6.3.5.3
-static String normalizeType(const String& type, bool* convertToURL = 0)
-{
- String cleanType = type.stripWhiteSpace().lower();
- if (cleanType == mimeTypeText || cleanType.startsWith(mimeTypeTextPlainEtc))
- return mimeTypeTextPlain;
- if (cleanType == mimeTypeURL) {
- if (convertToURL)
- *convertToURL = true;
- return mimeTypeTextURIList;
- }
- return cleanType;
-}
-
-PassRefPtr<Clipboard> Clipboard::create(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtr<ChromiumDataObject> dataObject)
-{
- return adoptRef(new Clipboard(type, policy , dataObject));
-}
-
-Clipboard::~Clipboard()
-{
-}
-
-void Clipboard::setDropEffect(const String &effect)
-{
- if (!isForDragAndDrop())
- return;
-
- // The attribute must ignore any attempts to set it to a value other than none, copy, link, and move.
- if (effect != "none" && effect != "copy" && effect != "link" && effect != "move")
- return;
-
- // FIXME: The spec actually allows this in all circumstances, even though there's no point in
- // setting the drop effect when this condition is not true.
- if (canReadTypes())
- m_dropEffect = effect;
-}
-
-void Clipboard::setEffectAllowed(const String &effect)
-{
- if (!isForDragAndDrop())
- return;
-
- if (dragOpFromIEOp(effect) == DragOperationPrivate) {
- // This means that there was no conversion, and the effectAllowed that
- // we are passed isn't a valid effectAllowed, so we should ignore it,
- // and not set m_effectAllowed.
-
- // The attribute must ignore any attempts to set it to a value other than
- // none, copy, copyLink, copyMove, link, linkMove, move, all, and uninitialized.
- return;
- }
-
-
- if (canWriteData())
- m_effectAllowed = effect;
-}
-
-void Clipboard::clearData(const String& type)
-{
- if (!canWriteData())
- return;
-
- if (type.isNull())
- m_dataObject->clearAll();
- else
- m_dataObject->clearData(normalizeType(type));
-}
-
-String Clipboard::getData(const String& type) const
-{
- if (!canReadData())
- return String();
-
- bool convertToURL = false;
- String data = m_dataObject->getData(normalizeType(type, &convertToURL));
- if (!convertToURL)
- return data;
- return convertURIListToURL(data);
-}
-
-bool Clipboard::setData(const String& type, const String& data)
-{
- if (!canWriteData())
- return false;
-
- return m_dataObject->setData(normalizeType(type), data);
-}
-
-// extensions beyond IE's API
-Vector<String> Clipboard::types() const
-{
- Vector<String> types;
- if (!canReadTypes())
- return types;
-
- ListHashSet<String> typesSet = m_dataObject->types();
- types.appendRange(typesSet.begin(), typesSet.end());
- return types;
-}
-
-PassRefPtr<FileList> Clipboard::files() const
-{
- RefPtr<FileList> files = FileList::create();
- if (!canReadData())
- return files.release();
-
- for (size_t i = 0; i < m_dataObject->length(); ++i) {
- if (m_dataObject->item(i)->kind() == ChromiumDataObjectItem::FileKind) {
- RefPtr<Blob> blob = m_dataObject->item(i)->getAsFile();
- if (blob && blob->isFile())
- files->append(toFile(blob.get()));
- }
- }
-
- return files.release();
-}
-
-void Clipboard::setDragImage(Element* image, int x, int y, ExceptionState& exceptionState)
-{
- if (!isForDragAndDrop())
- return;
-
- if (!image) {
- exceptionState.throwTypeError("setDragImage: Invalid first argument");
- return;
- }
- IntPoint location(x, y);
- if (image->hasTagName(HTMLNames::imgTag) && !image->inDocument())
- setDragImageResource(toHTMLImageElement(image)->cachedImage(), location);
- else
- setDragImageElement(image, location);
-}
-
-void Clipboard::setDragImageResource(ImageResource* img, const IntPoint& loc)
-{
- setDragImage(img, 0, loc);
-}
-
-void Clipboard::setDragImageElement(Node* node, const IntPoint& loc)
-{
- setDragImage(0, node, loc);
-}
-
-PassOwnPtr<DragImage> Clipboard::createDragImage(IntPoint& loc, Frame* frame) const
-{
- if (m_dragImageElement) {
- loc = m_dragLoc;
- return frame->nodeImage(m_dragImageElement.get());
- }
- if (m_dragImage) {
- loc = m_dragLoc;
- return DragImage::create(m_dragImage->image());
- }
- return nullptr;
-}
-
-static ImageResource* getImageResource(Element* element)
-{
- // Attempt to pull ImageResource from element
- ASSERT(element);
- RenderObject* renderer = element->renderer();
- if (!renderer || !renderer->isImage())
- return 0;
-
- RenderImage* image = toRenderImage(renderer);
- if (image->cachedImage() && !image->cachedImage()->errorOccurred())
- return image->cachedImage();
-
- return 0;
-}
-
-static void writeImageToDataObject(ChromiumDataObject* dataObject, Element* element, const KURL& url)
-{
- // Shove image data into a DataObject for use as a file
- ImageResource* cachedImage = getImageResource(element);
- if (!cachedImage || !cachedImage->imageForRenderer(element->renderer()) || !cachedImage->isLoaded())
- return;
-
- SharedBuffer* imageBuffer = cachedImage->imageForRenderer(element->renderer())->data();
- if (!imageBuffer || !imageBuffer->size())
- return;
-
- String imageExtension = cachedImage->image()->filenameExtension();
- ASSERT(!imageExtension.isEmpty());
-
- // Determine the filename for the file contents of the image.
- String filename = cachedImage->response().suggestedFilename();
- if (filename.isEmpty())
- filename = url.lastPathComponent();
-
- String fileExtension;
- if (filename.isEmpty()) {
- filename = element->getAttribute(HTMLNames::altAttr);
- } else {
- // Strip any existing extension. Assume that alt text is usually not a filename.
- int extensionIndex = filename.reverseFind('.');
- if (extensionIndex != -1) {
- fileExtension = filename.substring(extensionIndex + 1);
- filename.truncate(extensionIndex);
- }
- }
-
- if (!fileExtension.isEmpty() && fileExtension != imageExtension) {
- String imageMimeType = MIMETypeRegistry::getMIMETypeForExtension(imageExtension);
- ASSERT(imageMimeType.startsWith("image/"));
- // Use the file extension only if it has imageMimeType: it's untrustworthy otherwise.
- if (imageMimeType == MIMETypeRegistry::getMIMETypeForExtension(fileExtension))
- imageExtension = fileExtension;
- }
-
- imageExtension = "." + imageExtension;
- validateFilename(filename, imageExtension);
-
- dataObject->addSharedBuffer(filename + imageExtension, imageBuffer);
-}
-
-void Clipboard::declareAndWriteDragImage(Element* element, const KURL& url, const String& title)
-{
- if (!m_dataObject)
- return;
-
- m_dataObject->setURLAndTitle(url, title);
-
- // Write the bytes in the image to the file format.
- writeImageToDataObject(m_dataObject.get(), element, url);
-
- // Put img tag on the clipboard referencing the image
- m_dataObject->setData(mimeTypeTextHTML, createMarkup(element, IncludeNode, 0, ResolveAllURLs));
-}
-
-void Clipboard::writeURL(const KURL& url, const String& title)
-{
- if (!m_dataObject)
- return;
- ASSERT(!url.isEmpty());
-
- m_dataObject->setURLAndTitle(url, title);
-
- // The URL can also be used as plain text.
- m_dataObject->setData(mimeTypeTextPlain, url.string());
-
- // The URL can also be used as an HTML fragment.
- m_dataObject->setHTMLAndBaseURL(urlToMarkup(url, title), url);
-}
-
-void Clipboard::writeRange(Range* selectedRange, Frame* frame)
-{
- ASSERT(selectedRange);
- if (!m_dataObject)
- return;
-
- m_dataObject->setHTMLAndBaseURL(createMarkup(selectedRange, 0, AnnotateForInterchange, false, ResolveNonLocalURLs), frame->document()->url());
-
- String str = frame->selectedTextForClipboard();
-#if OS(WIN)
- replaceNewlinesWithWindowsStyleNewlines(str);
-#endif
- replaceNBSPWithSpace(str);
- m_dataObject->setData(mimeTypeTextPlain, str);
-}
-
-void Clipboard::writePlainText(const String& text)
-{
- if (!m_dataObject)
- return;
-
- String str = text;
-#if OS(WIN)
- replaceNewlinesWithWindowsStyleNewlines(str);
-#endif
- replaceNBSPWithSpace(str);
-
- m_dataObject->setData(mimeTypeTextPlain, str);
-}
-
-bool Clipboard::hasData()
-{
- ASSERT(isForDragAndDrop());
-
- return m_dataObject->length() > 0;
-}
-
-void Clipboard::setAccessPolicy(ClipboardAccessPolicy policy)
-{
- // once you go numb, can never go back
- ASSERT(m_policy != ClipboardNumb || policy == ClipboardNumb);
- m_policy = policy;
-}
-
-bool Clipboard::canReadTypes() const
-{
- return m_policy == ClipboardReadable || m_policy == ClipboardTypesReadable || m_policy == ClipboardWritable;
-}
-
-bool Clipboard::canReadData() const
-{
- return m_policy == ClipboardReadable || m_policy == ClipboardWritable;
-}
-
-bool Clipboard::canWriteData() const
-{
- return m_policy == ClipboardWritable;
-}
-
-bool Clipboard::canSetDragImage() const
-{
- return m_policy == ClipboardImageWritable || m_policy == ClipboardWritable;
-}
-
-DragOperation Clipboard::sourceOperation() const
-{
- DragOperation op = dragOpFromIEOp(m_effectAllowed);
- ASSERT(op != DragOperationPrivate);
- return op;
-}
-
-DragOperation Clipboard::destinationOperation() const
-{
- DragOperation op = dragOpFromIEOp(m_dropEffect);
- ASSERT(op == DragOperationCopy || op == DragOperationNone || op == DragOperationLink || op == (DragOperation)(DragOperationGeneric | DragOperationMove) || op == DragOperationEvery);
- return op;
-}
-
-void Clipboard::setSourceOperation(DragOperation op)
-{
- ASSERT_ARG(op, op != DragOperationPrivate);
- m_effectAllowed = IEOpFromDragOp(op);
-}
-
-void Clipboard::setDestinationOperation(DragOperation op)
-{
- ASSERT_ARG(op, op == DragOperationCopy || op == DragOperationNone || op == DragOperationLink || op == DragOperationGeneric || op == DragOperationMove || op == (DragOperation)(DragOperationGeneric | DragOperationMove));
- m_dropEffect = IEOpFromDragOp(op);
-}
-
-bool Clipboard::hasDropZoneType(const String& keyword)
-{
- if (keyword.startsWith("file:"))
- return hasFileOfType(keyword.substring(5));
-
- if (keyword.startsWith("string:"))
- return hasStringOfType(keyword.substring(7));
-
- return false;
-}
-
-PassRefPtr<DataTransferItemList> Clipboard::items()
-{
- // FIXME: According to the spec, we are supposed to return the same collection of items each
- // time. We now return a wrapper that always wraps the *same* set of items, so JS shouldn't be
- // able to tell, but we probably still want to fix this.
- return DataTransferItemList::create(this, m_dataObject);
-}
-
-PassRefPtr<ChromiumDataObject> Clipboard::dataObject() const
-{
- return m_dataObject;
-}
-
-Clipboard::Clipboard(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtr<ChromiumDataObject> dataObject)
- : m_policy(policy)
- , m_dropEffect("uninitialized")
- , m_effectAllowed("uninitialized")
- , m_clipboardType(type)
- , m_dataObject(dataObject)
-{
- ScriptWrappable::init(this);
-}
-
-void Clipboard::setDragImage(ImageResource* image, Node* node, const IntPoint& loc)
-{
- if (!canSetDragImage())
- return;
-
- m_dragImage = image;
- m_dragLoc = loc;
- m_dragImageElement = node;
-}
-
-bool Clipboard::hasFileOfType(const String& type) const
-{
- if (!canReadTypes())
- return false;
-
- RefPtr<FileList> fileList = files();
- if (fileList->isEmpty())
- return false;
-
- for (unsigned f = 0; f < fileList->length(); f++) {
- if (equalIgnoringCase(fileList->item(f)->type(), type))
- return true;
- }
- return false;
-}
-
-bool Clipboard::hasStringOfType(const String& type) const
-{
- if (!canReadTypes())
- return false;
-
- return types().contains(type);
-}
-
-DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation)
-{
- if (dragOperation == "copy")
- return DragOperationCopy;
- if (dragOperation == "move")
- return DragOperationMove;
- if (dragOperation == "link")
- return DragOperationLink;
- return DragOperationNone;
-}
-
-String convertDragOperationToDropZoneOperation(DragOperation operation)
-{
- switch (operation) {
- case DragOperationCopy:
- return String("copy");
- case DragOperationMove:
- return String("move");
- case DragOperationLink:
- return String("link");
- default:
- return String("copy");
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Clipboard.h b/chromium/third_party/WebKit/Source/core/dom/Clipboard.h
deleted file mode 100644
index dfe22710e76..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Clipboard.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
- * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Clipboard_h
-#define Clipboard_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/dom/ClipboardAccessPolicy.h"
-#include "core/fetch/ResourcePtr.h"
-#include "core/page/DragActions.h"
-#include "platform/geometry/IntPoint.h"
-#include "wtf/Forward.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class ChromiumDataObject;
-class DataTransferItemList;
-class DragImage;
-class Element;
-class ExceptionState;
-class FileList;
-class Frame;
-class ImageResource;
-class Node;
-class Range;
-
-// State available during IE's events for drag and drop and copy/paste
-class Clipboard : public RefCounted<Clipboard>, public ScriptWrappable {
-public:
- // Whether this clipboard is serving a drag-drop or copy-paste request.
- enum ClipboardType {
- CopyAndPaste,
- DragAndDrop,
- };
-
- static PassRefPtr<Clipboard> create(ClipboardType, ClipboardAccessPolicy, PassRefPtr<ChromiumDataObject>);
- ~Clipboard();
-
- bool isForCopyAndPaste() const { return m_clipboardType == CopyAndPaste; }
- bool isForDragAndDrop() const { return m_clipboardType == DragAndDrop; }
-
- String dropEffect() const { return dropEffectIsUninitialized() ? "none" : m_dropEffect; }
- void setDropEffect(const String&);
- bool dropEffectIsUninitialized() const { return m_dropEffect == "uninitialized"; }
- String effectAllowed() const { return m_effectAllowed; }
- void setEffectAllowed(const String&);
-
- void clearData(const String& type = String());
- String getData(const String& type) const;
- bool setData(const String& type, const String& data);
-
- // extensions beyond IE's API
- Vector<String> types() const;
- PassRefPtr<FileList> files() const;
-
- IntPoint dragLocation() const { return m_dragLoc; }
- void setDragImage(Element*, int x, int y, ExceptionState&);
- ImageResource* dragImageResource() const { return m_dragImage.get(); }
- void setDragImageResource(ImageResource*, const IntPoint&);
- Node* dragImageElement() const { return m_dragImageElement.get(); }
- void setDragImageElement(Node*, const IntPoint&);
-
- PassOwnPtr<DragImage> createDragImage(IntPoint& dragLocation, Frame*) const;
- void declareAndWriteDragImage(Element*, const KURL&, const String& title);
- void writeURL(const KURL&, const String&);
- void writeRange(Range*, Frame*);
- void writePlainText(const String&);
-
- bool hasData();
-
- void setAccessPolicy(ClipboardAccessPolicy);
- bool canReadTypes() const;
- bool canReadData() const;
- bool canWriteData() const;
- // Note that the spec doesn't actually allow drag image modification outside the dragstart
- // event. This capability is maintained for backwards compatiblity for ports that have
- // supported this in the past. On many ports, attempting to set a drag image outside the
- // dragstart operation is a no-op anyway.
- bool canSetDragImage() const;
-
- DragOperation sourceOperation() const;
- DragOperation destinationOperation() const;
- void setSourceOperation(DragOperation);
- void setDestinationOperation(DragOperation);
-
- bool hasDropZoneType(const String&);
-
- PassRefPtr<DataTransferItemList> items();
-
- PassRefPtr<ChromiumDataObject> dataObject() const;
-
-private:
- Clipboard(ClipboardType, ClipboardAccessPolicy, PassRefPtr<ChromiumDataObject>);
-
- void setDragImage(ImageResource*, Node*, const IntPoint&);
-
- bool hasFileOfType(const String&) const;
- bool hasStringOfType(const String&) const;
-
- // Instead of using this member directly, prefer to use the can*() methods above.
- ClipboardAccessPolicy m_policy;
- String m_dropEffect;
- String m_effectAllowed;
- ClipboardType m_clipboardType;
- RefPtr<ChromiumDataObject> m_dataObject;
-
- IntPoint m_dragLoc;
- ResourcePtr<ImageResource> m_dragImage;
- RefPtr<Node> m_dragImageElement;
-};
-
-DragOperation convertDropZoneOperationToDragOperation(const String& dragOperation);
-String convertDragOperationToDropZoneOperation(DragOperation);
-
-} // namespace WebCore
-
-#endif // Clipboard_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/Clipboard.idl b/chromium/third_party/WebKit/Source/core/dom/Clipboard.idl
deleted file mode 100644
index 695f70d4866..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Clipboard.idl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
-] interface Clipboard {
- [TreatReturnedNullStringAs=Undefined] attribute DOMString dropEffect;
- [TreatReturnedNullStringAs=Undefined] attribute DOMString effectAllowed;
- readonly attribute DOMString[] types;
- readonly attribute FileList files;
-
- void clearData(optional DOMString type);
- DOMString getData(DOMString type);
- boolean setData(DOMString type, DOMString data);
- [RaisesException] void setDragImage(Element image, long x, long y);
-
- readonly attribute DataTransferItemList items;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/Comment.cpp b/chromium/third_party/WebKit/Source/core/dom/Comment.cpp
index 90fb91b2ab8..03c5e98a70b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Comment.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Comment.cpp
@@ -32,9 +32,9 @@ inline Comment::Comment(Document& document, const String& text)
ScriptWrappable::init(this);
}
-PassRefPtr<Comment> Comment::create(Document& document, const String& text)
+PassRefPtrWillBeRawPtr<Comment> Comment::create(Document& document, const String& text)
{
- return adoptRef(new Comment(document, text));
+ return adoptRefWillBeNoop(new Comment(document, text));
}
String Comment::nodeName() const
@@ -47,14 +47,9 @@ Node::NodeType Comment::nodeType() const
return COMMENT_NODE;
}
-PassRefPtr<Node> Comment::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> Comment::cloneNode(bool /*deep*/)
{
return create(document(), data());
}
-bool Comment::childTypeAllowed(NodeType) const
-{
- return false;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Comment.h b/chromium/third_party/WebKit/Source/core/dom/Comment.h
index b0625f4be12..fc68b5264ef 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Comment.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Comment.h
@@ -31,15 +31,14 @@ class ExecutionContext;
class Comment FINAL : public CharacterData {
public:
- static PassRefPtr<Comment> create(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<Comment> create(Document&, const String&);
private:
Comment(Document&, const String&);
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
- virtual bool childTypeAllowed(NodeType) const;
+ virtual String nodeName() const OVERRIDE;
+ virtual NodeType nodeType() const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
};
DEFINE_NODE_TYPE_CASTS(Comment, nodeType() == Node::COMMENT_NODE);
diff --git a/chromium/third_party/WebKit/Source/core/dom/Comment.idl b/chromium/third_party/WebKit/Source/core/dom/Comment.idl
index 0297e953064..3af73b24d5b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Comment.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Comment.idl
@@ -18,7 +18,7 @@
*/
[
- Constructor([Default=NullString] optional DOMString data),
+ Constructor(optional DOMString data = null),
ConstructorCallWith=Document,
] interface Comment : CharacterData {
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp
index ba1ac83c663..18da27a211a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -24,33 +24,41 @@
#include "core/dom/ContainerNode.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ChildFrameDisconnector.h"
#include "core/dom/ChildListMutationScope.h"
+#include "core/dom/ClassCollection.h"
#include "core/dom/ContainerNodeAlgorithms.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/FullscreenElementStack.h"
+#include "core/dom/NameNodeList.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeChildRemovalTracker.h"
#include "core/dom/NodeRareData.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/NodeTraversal.h"
+#include "core/dom/ScriptForbiddenScope.h"
+#include "core/dom/SelectorQuery.h"
+#include "core/dom/StaticNodeList.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/MutationEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/html/HTMLCollection.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/html/RadioNodeList.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
-#include "core/rendering/RenderWidget.h"
-
-using namespace std;
namespace WebCore {
+using namespace HTMLNames;
+
static void dispatchChildInsertionEvents(Node&);
static void dispatchChildRemovalEvents(Node&);
-ChildNodesLazySnapshot* ChildNodesLazySnapshot::latestSnapshot = 0;
-
#ifndef NDEBUG
unsigned NoEventDispatchAssertion::s_count = 0;
#endif
@@ -67,19 +75,18 @@ static void collectChildrenAndRemoveFromOldParent(Node& node, NodeVector& nodes,
toContainerNode(node).removeChildren();
}
+#if !ENABLE(OILPAN)
void ContainerNode::removeDetachedChildren()
{
- if (connectedSubframeCount()) {
- for (Node* child = firstChild(); child; child = child->nextSibling())
- child->updateAncestorConnectedSubframeCountForRemoval();
- }
+ ASSERT(!connectedSubframeCount());
ASSERT(needsAttach());
removeDetachedChildrenInContainer<Node, ContainerNode>(*this);
}
+#endif
void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
{
- while (RefPtr<Node> child = oldParent.firstChild()) {
+ while (RefPtrWillBeRawPtr<Node> child = oldParent.firstChild()) {
oldParent.parserRemoveChild(*child);
treeScope().adoptIfNeeded(*child);
parserAppendChild(child.get());
@@ -88,8 +95,11 @@ void ContainerNode::parserTakeAllChildrenFrom(ContainerNode& oldParent)
ContainerNode::~ContainerNode()
{
+ ASSERT(needsAttach());
+#if !ENABLE(OILPAN)
willBeDeletedFromDocument();
removeDetachedChildren();
+#endif
}
bool ContainerNode::isChildTypeAllowed(const Node& child) const
@@ -97,7 +107,7 @@ bool ContainerNode::isChildTypeAllowed(const Node& child) const
if (!child.isDocumentFragment())
return childTypeAllowed(child.nodeType());
- for (Node* node = child.firstChild(); node; node = node->nextSibling()) {
+ for (Node* node = toDocumentFragment(child).firstChild(); node; node = node->nextSibling()) {
if (!childTypeAllowed(node->nodeType()))
return false;
}
@@ -106,7 +116,7 @@ bool ContainerNode::isChildTypeAllowed(const Node& child) const
bool ContainerNode::containsConsideringHostElements(const Node& newChild) const
{
- if (isInShadowTree() || document() == document().templateDocument())
+ if (isInShadowTree() || document().isTemplateDocument())
return newChild.containsIncludingHostElements(*this);
return newChild.contains(this);
}
@@ -165,13 +175,15 @@ bool ContainerNode::checkAcceptChildGuaranteedNodeTypes(const Node& newChild, Ex
return true;
}
-void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
+void ContainerNode::insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
{
+#if !ENABLE(OILPAN)
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
ASSERT(refCount() || parentOrShadowHostNode());
+#endif
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
// insertBefore(node, 0) is equivalent to appendChild(node)
if (!refChild) {
@@ -193,7 +205,7 @@ void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
if (refChild->previousSibling() == newChild || refChild == newChild) // nothing to do
return;
- RefPtr<Node> next = refChild;
+ RefPtrWillBeRawPtr<Node> next = refChild;
NodeVector targets;
collectChildrenAndRemoveFromOldParent(*newChild, targets, exceptionState);
@@ -235,6 +247,7 @@ void ContainerNode::insertBefore(PassRefPtr<Node> newChild, Node* refChild, Exce
void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
{
NoEventDispatchAssertion assertNoEventDispatch;
+ ScriptForbiddenScope forbidScript;
ASSERT(!newChild.parentNode()); // Use insertBefore if you need to handle reparenting (and want DOM mutation events).
ASSERT(!newChild.nextSibling());
@@ -245,11 +258,11 @@ void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
ASSERT(m_lastChild != prev);
nextChild.setPreviousSibling(&newChild);
if (prev) {
- ASSERT(m_firstChild != nextChild);
+ ASSERT(firstChild() != nextChild);
ASSERT(prev->nextSibling() == nextChild);
prev->setNextSibling(&newChild);
} else {
- ASSERT(m_firstChild == nextChild);
+ ASSERT(firstChild() == nextChild);
m_firstChild = &newChild;
}
newChild.setParentOrShadowHostNode(this);
@@ -257,14 +270,28 @@ void ContainerNode::insertBeforeCommon(Node& nextChild, Node& newChild)
newChild.setNextSibling(&nextChild);
}
-void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChild)
+void ContainerNode::appendChildCommon(Node& child)
+{
+ child.setParentOrShadowHostNode(this);
+
+ if (m_lastChild) {
+ child.setPreviousSibling(m_lastChild);
+ m_lastChild->setNextSibling(&child);
+ } else {
+ setFirstChild(&child);
+ }
+
+ setLastChild(&child);
+}
+
+void ContainerNode::parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node& nextChild)
{
ASSERT(newChild);
ASSERT(nextChild.parentNode() == this);
ASSERT(!newChild->isDocumentFragment());
- ASSERT(!hasTagName(HTMLNames::templateTag));
+ ASSERT(!isHTMLTemplateElement(this));
- if (nextChild.previousSibling() == newChild || nextChild == newChild) // nothing to do
+ if (nextChild.previousSibling() == newChild || &nextChild == newChild) // nothing to do
return;
if (document() != newChild->document())
@@ -278,16 +305,18 @@ void ContainerNode::parserInsertBefore(PassRefPtr<Node> newChild, Node& nextChil
childrenChanged(true, newChild->previousSibling(), &nextChild, 1);
- ChildNodeInsertionNotifier(*this).notify(*newChild);
+ notifyNodeInserted(*newChild);
}
-void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
+void ContainerNode::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
{
+#if !ENABLE(OILPAN)
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
ASSERT(refCount() || parentOrShadowHostNode());
+#endif
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
if (oldChild == newChild) // nothing to do
return;
@@ -309,10 +338,11 @@ void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
ChildListMutationScope mutation(*this);
- RefPtr<Node> next = oldChild->nextSibling();
+ RefPtrWillBeRawPtr<Node> next = oldChild->nextSibling();
// Remove the node we're replacing
- RefPtr<Node> removedChild = oldChild;
+ RefPtrWillBeRawPtr<Node> protectRemovedChild = oldChild;
+ ASSERT_UNUSED(protectRemovedChild, protectRemovedChild);
removeChild(oldChild, exceptionState);
if (exceptionState.hadException())
return;
@@ -357,7 +387,7 @@ void ContainerNode::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, Exce
if (next)
insertBeforeCommon(*next, child);
else
- appendChildToContainer(child, *this);
+ appendChildCommon(child);
}
updateTreeAfterInsertion(child);
@@ -382,7 +412,7 @@ void ContainerNode::willRemoveChildren()
getChildNodes(*this, children);
ChildListMutationScope mutation(*this);
- for (NodeVector::const_iterator it = children.begin(); it != children.end(); it++) {
+ for (NodeVector::const_iterator it = children.begin(); it != children.end(); ++it) {
ASSERT(*it);
Node& child = **it;
mutation.willRemoveChild(child);
@@ -398,25 +428,37 @@ void ContainerNode::disconnectDescendantFrames()
ChildFrameDisconnector(*this).disconnect();
}
+void ContainerNode::trace(Visitor* visitor)
+{
+ visitor->trace(m_firstChild);
+ visitor->trace(m_lastChild);
+ Node::trace(visitor);
+}
+
void ContainerNode::removeChild(Node* oldChild, ExceptionState& exceptionState)
{
+#if !ENABLE(OILPAN)
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
ASSERT(refCount() || parentOrShadowHostNode());
+#endif
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
// NotFoundError: Raised if oldChild is not a child of this node.
- if (!oldChild || oldChild->parentNode() != this) {
+ // FIXME: We should never really get PseudoElements in here, but editing will sometimes
+ // attempt to remove them still. We should fix that and enable this ASSERT.
+ // ASSERT(!oldChild->isPseudoElement())
+ if (!oldChild || oldChild->parentNode() != this || oldChild->isPseudoElement()) {
exceptionState.throwDOMException(NotFoundError, "The node to be removed is not a child of this node.");
return;
}
- RefPtr<Node> child = oldChild;
+ RefPtrWillBeRawPtr<Node> child = oldChild;
document().removeFocusedElementOfSubtree(child.get());
- if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document()))
+ if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
fullscreen->removeFullScreenElementOfSubtree(child.get());
// Events fired when blurring currently focused node might have moved this
@@ -435,13 +477,13 @@ void ContainerNode::removeChild(Node* oldChild, ExceptionState& exceptionState)
}
{
- RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+ HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
Node* prev = child->previousSibling();
Node* next = child->nextSibling();
removeBetween(prev, next, *child);
childrenChanged(false, prev, next, -1);
- ChildNodeRemovalNotifier(*this).notify(*child);
+ notifyNodeRemoved(*child);
}
dispatchSubtreeModifiedEvent();
}
@@ -459,9 +501,9 @@ void ContainerNode::removeBetween(Node* previousChild, Node* nextChild, Node& ol
nextChild->setPreviousSibling(previousChild);
if (previousChild)
previousChild->setNextSibling(nextChild);
- if (m_firstChild == oldChild)
+ if (m_firstChild == &oldChild)
m_firstChild = nextChild;
- if (m_lastChild == oldChild)
+ if (m_lastChild == &oldChild)
m_lastChild = previousChild;
oldChild.setPreviousSibling(0);
@@ -487,7 +529,7 @@ void ContainerNode::parserRemoveChild(Node& oldChild)
removeBetween(prev, next, oldChild);
childrenChanged(true, prev, next, -1);
- ChildNodeRemovalNotifier(*this).notify(oldChild);
+ notifyNodeRemoved(oldChild);
}
// this differs from other remove functions because it forcibly removes all the children,
@@ -498,9 +540,9 @@ void ContainerNode::removeChildren()
return;
// The container node can be removed from event handlers.
- RefPtr<ContainerNode> protect(this);
+ RefPtrWillBeRawPtr<ContainerNode> protect(this);
- if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document()))
+ if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
fullscreen->removeFullScreenElementOfSubtree(this, true);
// Do any prep work needed before actually starting to detach
@@ -519,16 +561,16 @@ void ContainerNode::removeChildren()
document().removeFocusedElementOfSubtree(this, true);
// Removing a node from a selection can cause widget updates.
- document().nodeChildrenWillBeRemoved(this);
+ document().nodeChildrenWillBeRemoved(*this);
}
NodeVector removedChildren;
{
- RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+ HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
{
NoEventDispatchAssertion assertNoEventDispatch;
- removedChildren.reserveInitialCapacity(childNodeCount());
+ removedChildren.reserveInitialCapacity(countChildren());
while (m_firstChild) {
removedChildren.append(m_firstChild);
removeBetween(0, m_firstChild->nextSibling(), *m_firstChild);
@@ -538,19 +580,21 @@ void ContainerNode::removeChildren()
childrenChanged(false, 0, 0, -static_cast<int>(removedChildren.size()));
for (size_t i = 0; i < removedChildren.size(); ++i)
- ChildNodeRemovalNotifier(*this).notify(*removedChildren[i]);
+ notifyNodeRemoved(*removedChildren[i]);
}
dispatchSubtreeModifiedEvent();
}
-void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& exceptionState)
+void ContainerNode::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& exceptionState)
{
- RefPtr<ContainerNode> protect(this);
+ RefPtrWillBeRawPtr<ContainerNode> protect(this);
+#if !ENABLE(OILPAN)
// Check that this node is not "floating".
// If it is, it can be deleted as a side effect of sending mutation events.
ASSERT(refCount() || parentOrShadowHostNode());
+#endif
// Make sure adding the new child is ok
if (!checkAcceptChild(newChild.get(), 0, exceptionState))
@@ -586,12 +630,12 @@ void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& excep
if (child.parentNode())
break;
- treeScope().adoptIfNeeded(child);
-
- // Append child to the end of the list
{
NoEventDispatchAssertion assertNoEventDispatch;
- appendChildToContainer(child, *this);
+ ScriptForbiddenScope forbidScript;
+
+ treeScope().adoptIfNeeded(child);
+ appendChildCommon(child);
}
updateTreeAfterInsertion(child);
@@ -600,30 +644,86 @@ void ContainerNode::appendChild(PassRefPtr<Node> newChild, ExceptionState& excep
dispatchSubtreeModifiedEvent();
}
-void ContainerNode::parserAppendChild(PassRefPtr<Node> newChild)
+void ContainerNode::parserAppendChild(PassRefPtrWillBeRawPtr<Node> newChild)
{
ASSERT(newChild);
ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
ASSERT(!newChild->isDocumentFragment());
- ASSERT(!hasTagName(HTMLNames::templateTag));
+ ASSERT(!isHTMLTemplateElement(this));
if (document() != newChild->document())
document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
Node* last = m_lastChild;
+
{
NoEventDispatchAssertion assertNoEventDispatch;
- // FIXME: This method should take a PassRefPtr.
- appendChildToContainer(*newChild, *this);
+ ScriptForbiddenScope forbidScript;
+
treeScope().adoptIfNeeded(*newChild);
+ appendChildCommon(*newChild);
+ newChild->updateAncestorConnectedSubframeCountForInsertion();
+ ChildListMutationScope(*this).childAdded(*newChild);
}
- newChild->updateAncestorConnectedSubframeCountForInsertion();
+ childrenChanged(true, last, 0, 1);
+ notifyNodeInserted(*newChild);
+}
- ChildListMutationScope(*this).childAdded(*newChild);
+void ContainerNode::notifyNodeInserted(Node& root)
+{
+ ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
- childrenChanged(true, last, 0, 1);
- ChildNodeInsertionNotifier(*this).notify(*newChild);
+ InspectorInstrumentation::didInsertDOMNode(&root);
+
+ RefPtrWillBeRawPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protectNode(root);
+
+ NodeVector postInsertionNotificationTargets;
+ notifyNodeInsertedInternal(root, postInsertionNotificationTargets);
+
+ for (size_t i = 0; i < postInsertionNotificationTargets.size(); ++i) {
+ Node* targetNode = postInsertionNotificationTargets[i].get();
+ if (targetNode->inDocument())
+ targetNode->didNotifySubtreeInsertionsToDocument();
+ }
+}
+
+void ContainerNode::notifyNodeInsertedInternal(Node& root, NodeVector& postInsertionNotificationTargets)
+{
+ NoEventDispatchAssertion assertNoEventDispatch;
+ ScriptForbiddenScope forbidScript;
+
+ for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
+ // As an optimization we don't notify leaf nodes when when inserting
+ // into detached subtrees.
+ if (!inDocument() && !node->isContainerNode())
+ continue;
+ if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node->insertedInto(this))
+ postInsertionNotificationTargets.append(node);
+ for (ShadowRoot* shadowRoot = node->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
+ notifyNodeInsertedInternal(*shadowRoot, postInsertionNotificationTargets);
+ }
+}
+
+void ContainerNode::notifyNodeRemoved(Node& root)
+{
+ ScriptForbiddenScope forbidScript;
+ NoEventDispatchAssertion assertNoEventDispatch;
+
+ Document& document = root.document();
+ for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
+ // As an optimization we skip notifying Text nodes and other leaf nodes
+ // of removal when they're not in the Document tree since the virtual
+ // call to removedFrom is not needed.
+ if (!node->inDocument() && !node->isContainerNode())
+ continue;
+ if (document.cssTarget() == node)
+ document.setCSSTarget(nullptr);
+ node->removedFrom(this);
+ for (ShadowRoot* shadowRoot = node->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
+ notifyNodeRemoved(*shadowRoot);
+ }
}
void ContainerNode::attach(const AttachContext& context)
@@ -646,7 +746,7 @@ void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int chil
if (!changedByParser && childCountDelta)
document().updateRangesAfterChildrenChanged(this);
invalidateNodeListCachesInAncestors();
- if (childCountDelta > 0 && inActiveDocument()) {
+ if (childCountDelta > 0 && !childNeedsStyleRecalc()) {
setChildNeedsStyleRecalc();
markAncestorsWithChildNeedsStyleRecalc();
}
@@ -666,7 +766,6 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
return false;
// What is this code really trying to do?
RenderObject* o = renderer();
- RenderObject* p = o;
if (!o->isInline() || o->isReplaced()) {
point = o->localToAbsolute(FloatPoint(), UseTransforms);
@@ -675,9 +774,9 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
// find the next text/image child, to get a position
while (o) {
- p = o;
- if (o->firstChild()) {
- o = o->firstChild();
+ RenderObject* p = o;
+ if (RenderObject* oFirstChild = o->slowFirstChild()) {
+ o = oFirstChild;
} else if (o->nextSibling()) {
o = o->nextSibling();
} else {
@@ -703,7 +802,7 @@ bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const
} else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
point = FloatPoint();
if (o->isText() && toRenderText(o)->firstTextBox()) {
- point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root()->lineTop());
+ point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root().lineTop().toFloat());
} else if (o->isBox()) {
RenderBox* box = toRenderBox(o);
point.moveBy(box->location());
@@ -736,8 +835,8 @@ bool ContainerNode::getLowerRightCorner(FloatPoint& point) const
// find the last text/image child, to get a position
while (o) {
- if (o->lastChild()) {
- o = o->lastChild();
+ if (RenderObject* oLastChild = o->slowLastChild()) {
+ o = oLastChild;
} else if (o->previousSibling()) {
o = o->previousSibling();
} else {
@@ -800,12 +899,18 @@ void ContainerNode::focusStateChanged()
// renderer we can just ignore the state change.
if (!renderer())
return;
- // FIXME: This could probably setNeedsStyleRecalc(LocalStyleChange) in the affectedByFocus case
- // and only setNeedsStyleRecalc(SubtreeStyleChange) in the childrenAffectedByFocus case.
- if (renderStyle()->affectedByFocus() || (isElementNode() && toElement(this)->childrenAffectedByFocus()))
- setNeedsStyleRecalc();
+
+ if (styleChangeType() < SubtreeStyleChange) {
+ if (renderStyle()->affectedByFocus() && renderStyle()->hasPseudoStyle(FIRST_LETTER))
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFocus())
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoFocus, *toElement(this));
+ else if (renderStyle()->affectedByFocus())
+ setNeedsStyleRecalc(LocalStyleChange);
+ }
+
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), FocusState);
+ RenderTheme::theme().stateChanged(renderer(), FocusControlState);
}
void ContainerNode::setFocus(bool received)
@@ -816,9 +921,15 @@ void ContainerNode::setFocus(bool received)
Node::setFocus(received);
focusStateChanged();
+
+ if (renderer() || received)
+ return;
+
// If :focus sets display: none, we lose focus but still need to recalc our style.
- if (!renderer() && !received)
- setNeedsStyleRecalc();
+ if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByFocus() && styleChangeType() < SubtreeStyleChange)
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoFocus, *toElement(this));
+ else
+ setNeedsStyleRecalc(LocalStyleChange);
}
void ContainerNode::setActive(bool down)
@@ -830,10 +941,17 @@ void ContainerNode::setActive(bool down)
// FIXME: Why does this not need to handle the display: none transition like :hover does?
if (renderer()) {
- if (renderStyle()->affectedByActive() || (isElementNode() && toElement(this)->childrenAffectedByActive()))
- setNeedsStyleRecalc();
+ if (styleChangeType() < SubtreeStyleChange) {
+ if (renderStyle()->affectedByActive() && renderStyle()->hasPseudoStyle(FIRST_LETTER))
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByActive())
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoActive, *toElement(this));
+ else if (renderStyle()->affectedByActive())
+ setNeedsStyleRecalc(LocalStyleChange);
+ }
+
if (renderStyle()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), PressedState);
+ RenderTheme::theme().stateChanged(renderer(), PressedControlState);
}
}
@@ -846,49 +964,34 @@ void ContainerNode::setHovered(bool over)
// If :hover sets display: none we lose our hover but still need to recalc our style.
if (!renderer()) {
- if (!over)
- setNeedsStyleRecalc();
+ if (over)
+ return;
+ if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHover() && styleChangeType() < SubtreeStyleChange)
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoHover, *toElement(this));
+ else
+ setNeedsStyleRecalc(LocalStyleChange);
return;
}
- if (renderer()) {
- if (renderStyle()->affectedByHover() || (isElementNode() && toElement(this)->childrenAffectedByHover()))
- setNeedsStyleRecalc();
- if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), HoverState);
+ if (styleChangeType() < SubtreeStyleChange) {
+ if (renderStyle()->affectedByHover() && renderStyle()->hasPseudoStyle(FIRST_LETTER))
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ else if (isElementNode() && toElement(this)->childrenOrSiblingsAffectedByHover())
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForPseudoChange(CSSSelector::PseudoHover, *toElement(this));
+ else if (renderStyle()->affectedByHover())
+ setNeedsStyleRecalc(LocalStyleChange);
}
-}
-
-PassRefPtr<HTMLCollection> ContainerNode::children()
-{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, NodeChildren);
-}
-
-Element* ContainerNode::firstElementChild() const
-{
- return ElementTraversal::firstWithin(*this);
-}
-Element* ContainerNode::lastElementChild() const
-{
- Node* n = lastChild();
- while (n && !n->isElementNode())
- n = n->previousSibling();
- return toElement(n);
+ if (renderer()->style()->hasAppearance())
+ RenderTheme::theme().stateChanged(renderer(), HoverControlState);
}
-unsigned ContainerNode::childElementCount() const
+PassRefPtrWillBeRawPtr<HTMLCollection> ContainerNode::children()
{
- unsigned count = 0;
- Node* n = firstChild();
- while (n) {
- count += n->isElementNode();
- n = n->nextSibling();
- }
- return count;
+ return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, NodeChildren);
}
-unsigned ContainerNode::childNodeCount() const
+unsigned ContainerNode::countChildren() const
{
unsigned count = 0;
Node *n;
@@ -897,7 +1000,7 @@ unsigned ContainerNode::childNodeCount() const
return count;
}
-Node *ContainerNode::childNode(unsigned index) const
+Node* ContainerNode::traverseToChildAt(unsigned index) const
{
unsigned i;
Node *n = firstChild();
@@ -906,6 +1009,33 @@ Node *ContainerNode::childNode(unsigned index) const
return n;
}
+PassRefPtrWillBeRawPtr<Element> ContainerNode::querySelector(const AtomicString& selectors, ExceptionState& exceptionState)
+{
+ if (selectors.isEmpty()) {
+ exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
+ return nullptr;
+ }
+
+ SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
+ if (!selectorQuery)
+ return nullptr;
+ return selectorQuery->queryFirst(*this);
+}
+
+PassRefPtrWillBeRawPtr<StaticNodeList> ContainerNode::querySelectorAll(const AtomicString& selectors, ExceptionState& exceptionState)
+{
+ if (selectors.isEmpty()) {
+ exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
+ return nullptr;
+ }
+
+ SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
+ if (!selectorQuery)
+ return nullptr;
+
+ return selectorQuery->queryAll(*this);
+}
+
static void dispatchChildInsertionEvents(Node& child)
{
if (child.isInShadowTree())
@@ -913,8 +1043,8 @@ static void dispatchChildInsertionEvents(Node& child)
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
- RefPtr<Node> c(child);
- RefPtr<Document> document(child.document());
+ RefPtrWillBeRawPtr<Node> c(child);
+ RefPtrWillBeRawPtr<Document> document(child.document());
if (c->parentNode() && document->hasListenerType(Document::DOMNODEINSERTED_LISTENER))
c->dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMNodeInserted, true, c->parentNode()));
@@ -937,8 +1067,8 @@ static void dispatchChildRemovalEvents(Node& child)
InspectorInstrumentation::willRemoveDOMNode(&child);
- RefPtr<Node> c(child);
- RefPtr<Document> document(child.document());
+ RefPtrWillBeRawPtr<Node> c(child);
+ RefPtrWillBeRawPtr<Document> document(child.document());
// dispatch pre-removal mutation events
if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER)) {
@@ -956,18 +1086,196 @@ static void dispatchChildRemovalEvents(Node& child)
void ContainerNode::updateTreeAfterInsertion(Node& child)
{
+#if !ENABLE(OILPAN)
ASSERT(refCount());
ASSERT(child.refCount());
+#endif
ChildListMutationScope(*this).childAdded(child);
childrenChanged(false, child.previousSibling(), child.nextSibling(), 1);
- ChildNodeInsertionNotifier(*this).notify(child);
+ notifyNodeInserted(child);
dispatchChildInsertionEvents(child);
}
+bool ContainerNode::hasRestyleFlagInternal(DynamicRestyleFlags mask) const
+{
+ return rareData()->hasRestyleFlag(mask);
+}
+
+bool ContainerNode::hasRestyleFlagsInternal() const
+{
+ return rareData()->hasRestyleFlags();
+}
+
+void ContainerNode::setRestyleFlag(DynamicRestyleFlags mask)
+{
+ ASSERT(isElementNode() || isShadowRoot());
+ ensureRareData().setRestyleFlag(mask);
+}
+
+void ContainerNode::checkForChildrenAdjacentRuleChanges()
+{
+ bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
+ bool hasIndirectAdjacentRules = childrenAffectedByIndirectAdjacentRules();
+
+ if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
+ return;
+
+ unsigned forceCheckOfNextElementCount = 0;
+ bool forceCheckOfAnyElementSibling = false;
+ Document& document = this->document();
+
+ for (Element* child = ElementTraversal::firstChild(*this); child; child = ElementTraversal::nextSibling(*child)) {
+ bool childRulesChanged = child->needsStyleRecalc() && child->styleChangeType() >= SubtreeStyleChange;
+
+ if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
+ child->setNeedsStyleRecalc(SubtreeStyleChange);
+
+ if (childRulesChanged && hasDirectAdjacentRules)
+ forceCheckOfNextElementCount = document.styleEngine()->maxDirectAdjacentSelectors();
+ else if (forceCheckOfNextElementCount)
+ --forceCheckOfNextElementCount;
+
+ forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
+ }
+}
+
+void ContainerNode::checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta)
+{
+ if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || styleChangeType() >= SubtreeStyleChange)
+ return;
+
+ if (needsStyleRecalc() && childrenAffectedByPositionalRules())
+ return;
+
+ // Forward positional selectors include nth-child, nth-of-type, first-of-type and only-of-type.
+ // The indirect adjacent selector is the ~ selector.
+ // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
+ // We have to invalidate everything following the insertion point in the forward and indirect adjacent case,
+ // and everything before the insertion point in the backward case.
+ // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
+ // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
+ // here. recalcStyle will then force a walk of the children when it sees that this has happened.
+ if (((childrenAffectedByForwardPositionalRules() || childrenAffectedByIndirectAdjacentRules()) && afterChange)
+ || (childrenAffectedByBackwardPositionalRules() && beforeChange)) {
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ return;
+ }
+
+ // :first-child. In the parser callback case, we don't have to check anything, since we were right the first time.
+ // In the DOM case, we only need to do something if |afterChange| is not 0.
+ // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
+ if (childrenAffectedByFirstChildRules() && afterChange) {
+ // Find our new first child.
+ Element* newFirstChild = ElementTraversal::firstWithin(*this);
+ RenderStyle* newFirstChildStyle = newFirstChild ? newFirstChild->renderStyle() : 0;
+
+ // Find the first element node following |afterChange|
+ Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : ElementTraversal::nextSibling(*afterChange);
+ RenderStyle* firstElementAfterInsertionStyle = firstElementAfterInsertion ? firstElementAfterInsertion->renderStyle() : 0;
+
+ // This is the insert/append case.
+ if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertionStyle && firstElementAfterInsertionStyle->firstChildState())
+ firstElementAfterInsertion->setNeedsStyleRecalc(SubtreeStyleChange);
+
+ // We also have to handle node removal.
+ if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChildStyle || !newFirstChildStyle->firstChildState()))
+ newFirstChild->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+
+ // :last-child. In the parser callback case, we don't have to check anything, since we were right the first time.
+ // In the DOM case, we only need to do something if |afterChange| is not 0.
+ if (childrenAffectedByLastChildRules() && beforeChange) {
+ // Find our new last child.
+ Node* newLastChild = ElementTraversal::lastChild(*this);
+ RenderStyle* newLastChildStyle = newLastChild ? newLastChild->renderStyle() : 0;
+
+ // Find the last element node going backwards from |beforeChange|
+ Node* lastElementBeforeInsertion = beforeChange->isElementNode() ? beforeChange : ElementTraversal::previousSibling(*beforeChange);
+ RenderStyle* lastElementBeforeInsertionStyle = lastElementBeforeInsertion ? lastElementBeforeInsertion->renderStyle() : 0;
+
+ if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertionStyle && lastElementBeforeInsertionStyle->lastChildState())
+ lastElementBeforeInsertion->setNeedsStyleRecalc(SubtreeStyleChange);
+
+ // We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
+ // to match now.
+ if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChildStyle->lastChildState()))
+ newLastChild->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+
+ // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element
+ // that could be affected by this DOM change.
+ if (childrenAffectedByDirectAdjacentRules() && afterChange) {
+ if (Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : ElementTraversal::nextSibling(*afterChange))
+ firstElementAfterInsertion->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+}
+
+PassRefPtrWillBeRawPtr<TagCollection> ContainerNode::getElementsByTagName(const AtomicString& localName)
+{
+ if (localName.isNull())
+ return nullptr;
+
+ if (document().isHTMLDocument())
+ return ensureRareData().ensureNodeLists().addCache<HTMLTagCollection>(*this, HTMLTagCollectionType, localName);
+ return ensureRareData().ensureNodeLists().addCache<TagCollection>(*this, TagCollectionType, localName);
+}
+
+PassRefPtrWillBeRawPtr<TagCollection> ContainerNode::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
+{
+ if (localName.isNull())
+ return nullptr;
+
+ if (namespaceURI == starAtom)
+ return getElementsByTagName(localName);
+
+ return ensureRareData().ensureNodeLists().addCache(*this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
+}
+
+// Takes an AtomicString in argument because it is common for elements to share the same name attribute.
+// Therefore, the NameNodeList factory function expects an AtomicString type.
+PassRefPtrWillBeRawPtr<NameNodeList> ContainerNode::getElementsByName(const AtomicString& elementName)
+{
+ return ensureRareData().ensureNodeLists().addCache<NameNodeList>(*this, NameNodeListType, elementName);
+}
+
+// Takes an AtomicString in argument because it is common for elements to share the same set of class names.
+// Therefore, the ClassNodeList factory function expects an AtomicString type.
+PassRefPtrWillBeRawPtr<ClassCollection> ContainerNode::getElementsByClassName(const AtomicString& classNames)
+{
+ return ensureRareData().ensureNodeLists().addCache<ClassCollection>(*this, ClassCollectionType, classNames);
+}
+
+PassRefPtrWillBeRawPtr<RadioNodeList> ContainerNode::radioNodeList(const AtomicString& name, bool onlyMatchImgElements)
+{
+ ASSERT(isHTMLFormElement(this) || isHTMLFieldSetElement(this));
+ CollectionType type = onlyMatchImgElements ? RadioImgNodeListType : RadioNodeListType;
+ return ensureRareData().ensureNodeLists().addCache<RadioNodeList>(*this, type, name);
+}
+
+Element* ContainerNode::getElementById(const AtomicString& id) const
+{
+ if (isInTreeScope()) {
+ // Fast path if we are in a tree scope: call getElementById() on tree scope
+ // and check if the matching element is in our subtree.
+ Element* element = treeScope().getElementById(id);
+ if (!element)
+ return 0;
+ if (element->isDescendantOf(this))
+ return element;
+ }
+
+ // Fall back to traversing our subtree. In case of duplicate ids, the first element found will be returned.
+ for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element, this)) {
+ if (element->getIdAttribute() == id)
+ return element;
+ }
+ return 0;
+}
+
#ifndef NDEBUG
bool childAttachedAllowedWhenAttachingChildren(ContainerNode* node)
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.h b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.h
index d64d78275f9..4df98d42119 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContainerNode.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ContainerNode.h
@@ -31,82 +31,76 @@
namespace WebCore {
+class ClassCollection;
class ExceptionState;
class FloatPoint;
class HTMLCollection;
+class StaticNodeList;
+class TagCollection;
namespace Private {
template<class GenericNode, class GenericNodeContainer>
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
}
-class NoEventDispatchAssertion {
-public:
- NoEventDispatchAssertion()
- {
-#ifndef NDEBUG
- if (!isMainThread())
- return;
- s_count++;
-#endif
- }
-
- ~NoEventDispatchAssertion()
- {
-#ifndef NDEBUG
- if (!isMainThread())
- return;
- ASSERT(s_count);
- s_count--;
-#endif
- }
-
-#ifndef NDEBUG
- static bool isEventDispatchForbidden()
- {
- if (!isMainThread())
- return false;
- return s_count;
- }
-#endif
-
-private:
-#ifndef NDEBUG
- static unsigned s_count;
-#endif
+enum DynamicRestyleFlags {
+ ChildrenOrSiblingsAffectedByFocus = 1 << 0,
+ ChildrenOrSiblingsAffectedByHover = 1 << 1,
+ ChildrenOrSiblingsAffectedByActive = 1 << 2,
+ ChildrenOrSiblingsAffectedByDrag = 1 << 3,
+ ChildrenAffectedByFirstChildRules = 1 << 4,
+ ChildrenAffectedByLastChildRules = 1 << 5,
+ ChildrenAffectedByDirectAdjacentRules = 1 << 6,
+ ChildrenAffectedByIndirectAdjacentRules = 1 << 7,
+ ChildrenAffectedByForwardPositionalRules = 1 << 8,
+ ChildrenAffectedByBackwardPositionalRules = 1 << 9,
+
+ NumberOfDynamicRestyleFlags = 10,
};
+// This constant controls how much buffer is initially allocated
+// for a Node Vector that is used to store child Nodes of a given Node.
+// FIXME: Optimize the value.
+const int initialNodeVectorSize = 11;
+typedef WillBeHeapVector<RefPtrWillBeMember<Node>, initialNodeVectorSize> NodeVector;
+
class ContainerNode : public Node {
public:
virtual ~ContainerNode();
Node* firstChild() const { return m_firstChild; }
Node* lastChild() const { return m_lastChild; }
- bool hasChildNodes() const { return m_firstChild; }
+ bool hasChildren() const { return m_firstChild; }
bool hasOneChild() const { return m_firstChild && !m_firstChild->nextSibling(); }
bool hasOneTextChild() const { return hasOneChild() && m_firstChild->isTextNode(); }
+ bool hasChildCount(unsigned) const;
- // ParentNode interface API
- PassRefPtr<HTMLCollection> children();
- Element* firstElementChild() const;
- Element* lastElementChild() const;
- unsigned childElementCount() const;
+ PassRefPtrWillBeRawPtr<HTMLCollection> children();
- unsigned childNodeCount() const;
- Node* childNode(unsigned index) const;
+ unsigned countChildren() const;
+ Node* traverseToChildAt(unsigned index) const;
- void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
- void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ PassRefPtrWillBeRawPtr<Element> querySelector(const AtomicString& selectors, ExceptionState&);
+ PassRefPtrWillBeRawPtr<StaticNodeList> querySelectorAll(const AtomicString& selectors, ExceptionState&);
+
+ void insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
void removeChild(Node* child, ExceptionState& = ASSERT_NO_EXCEPTION);
- void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+
+ Element* getElementById(const AtomicString& id) const;
+ PassRefPtrWillBeRawPtr<TagCollection> getElementsByTagName(const AtomicString&);
+ PassRefPtrWillBeRawPtr<TagCollection> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName);
+ PassRefPtrWillBeRawPtr<NameNodeList> getElementsByName(const AtomicString& elementName);
+ PassRefPtrWillBeRawPtr<ClassCollection> getElementsByClassName(const AtomicString& classNames);
+ PassRefPtrWillBeRawPtr<RadioNodeList> radioNodeList(const AtomicString&, bool onlyMatchImgElements = false);
// These methods are only used during parsing.
// They don't send DOM mutation events or handle reparenting.
- // However, arbitrary code may be run by beforeload handlers.
- void parserAppendChild(PassRefPtr<Node>);
+ void parserAppendChild(PassRefPtrWillBeRawPtr<Node>);
void parserRemoveChild(Node&);
- void parserInsertBefore(PassRefPtr<Node> newChild, Node& refChild);
+ void parserInsertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node& refChild);
void parserTakeAllChildrenFrom(ContainerNode&);
void removeChildren();
@@ -115,12 +109,51 @@ public:
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual LayoutRect boundingBox() const OVERRIDE;
+ virtual LayoutRect boundingBox() const OVERRIDE FINAL;
virtual void setFocus(bool) OVERRIDE;
void focusStateChanged();
virtual void setActive(bool = true) OVERRIDE;
virtual void setHovered(bool = true) OVERRIDE;
+ bool childrenOrSiblingsAffectedByFocus() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByFocus); }
+ void setChildrenOrSiblingsAffectedByFocus() { setRestyleFlag(ChildrenOrSiblingsAffectedByFocus); }
+
+ bool childrenOrSiblingsAffectedByHover() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByHover); }
+ void setChildrenOrSiblingsAffectedByHover() { setRestyleFlag(ChildrenOrSiblingsAffectedByHover); }
+
+ bool childrenOrSiblingsAffectedByActive() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByActive); }
+ void setChildrenOrSiblingsAffectedByActive() { setRestyleFlag(ChildrenOrSiblingsAffectedByActive); }
+
+ bool childrenOrSiblingsAffectedByDrag() const { return hasRestyleFlag(ChildrenOrSiblingsAffectedByDrag); }
+ void setChildrenOrSiblingsAffectedByDrag() { setRestyleFlag(ChildrenOrSiblingsAffectedByDrag); }
+
+ bool childrenAffectedByPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByForwardPositionalRules) || hasRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
+
+ bool childrenAffectedByFirstChildRules() const { return hasRestyleFlag(ChildrenAffectedByFirstChildRules); }
+ void setChildrenAffectedByFirstChildRules() { setRestyleFlag(ChildrenAffectedByFirstChildRules); }
+
+ bool childrenAffectedByLastChildRules() const { return hasRestyleFlag(ChildrenAffectedByLastChildRules); }
+ void setChildrenAffectedByLastChildRules() { setRestyleFlag(ChildrenAffectedByLastChildRules); }
+
+ bool childrenAffectedByDirectAdjacentRules() const { return hasRestyleFlag(ChildrenAffectedByDirectAdjacentRules); }
+ void setChildrenAffectedByDirectAdjacentRules() { setRestyleFlag(ChildrenAffectedByDirectAdjacentRules); }
+
+ bool childrenAffectedByIndirectAdjacentRules() const { return hasRestyleFlag(ChildrenAffectedByIndirectAdjacentRules); }
+ void setChildrenAffectedByIndirectAdjacentRules() { setRestyleFlag(ChildrenAffectedByIndirectAdjacentRules); }
+
+ bool childrenAffectedByForwardPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByForwardPositionalRules); }
+ void setChildrenAffectedByForwardPositionalRules() { setRestyleFlag(ChildrenAffectedByForwardPositionalRules); }
+
+ bool childrenAffectedByBackwardPositionalRules() const { return hasRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
+ void setChildrenAffectedByBackwardPositionalRules() { setRestyleFlag(ChildrenAffectedByBackwardPositionalRules); }
+
+ // FIXME: These methods should all be renamed to something better than "check",
+ // since it's not clear that they alter the style bits of siblings and children.
+ void checkForChildrenAdjacentRuleChanges();
+ void checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta);
+
+ bool childrenSupportStyleSharing() const { return !hasRestyleFlags(); }
+
// -----------------------------------------------------------------------------
// Notification of document structure changes (see core/dom/Node.h for more notification methods)
@@ -130,28 +163,40 @@ public:
void disconnectDescendantFrames();
- virtual bool childShouldCreateRenderer(const Node& child) const { return true; }
+ virtual void trace(Visitor*) OVERRIDE;
+
+ void notifyNodeInserted(Node&);
+ void notifyNodeRemoved(Node&);
protected:
ContainerNode(TreeScope*, ConstructionType = CreateContainer);
template<class GenericNode, class GenericNodeContainer>
- friend void appendChildToContainer(GenericNode& child, GenericNodeContainer&);
-
- template<class GenericNode, class GenericNodeContainer>
friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
+#if !ENABLE(OILPAN)
void removeDetachedChildren();
+#endif
+
void setFirstChild(Node* child) { m_firstChild = child; }
void setLastChild(Node* child) { m_lastChild = child; }
private:
void removeBetween(Node* previousChild, Node* nextChild, Node& oldChild);
void insertBeforeCommon(Node& nextChild, Node& oldChild);
+ void appendChildCommon(Node& child);
void updateTreeAfterInsertion(Node& child);
void willRemoveChildren();
void willRemoveChild(Node& child);
+ void notifyNodeInsertedInternal(Node&, NodeVector& postInsertionNotificationTargets);
+
+ bool hasRestyleFlag(DynamicRestyleFlags mask) const { return hasRareData() && hasRestyleFlagInternal(mask); }
+ bool hasRestyleFlags() const { return hasRareData() && hasRestyleFlagsInternal(); }
+ void setRestyleFlag(DynamicRestyleFlags);
+ bool hasRestyleFlagInternal(DynamicRestyleFlags) const;
+ bool hasRestyleFlagsInternal() const;
+
inline bool checkAcceptChildGuaranteedNodeTypes(const Node& newChild, ExceptionState&) const;
inline bool checkAcceptChild(const Node* newChild, const Node* oldChild, ExceptionState&) const;
inline bool containsConsideringHostElements(const Node&) const;
@@ -163,8 +208,8 @@ private:
bool getUpperLeftCorner(FloatPoint&) const;
bool getLowerRightCorner(FloatPoint&) const;
- Node* m_firstChild;
- Node* m_lastChild;
+ RawPtrWillBeMember<Node> m_firstChild;
+ RawPtrWillBeMember<Node> m_lastChild;
};
#ifndef NDEBUG
@@ -173,10 +218,20 @@ bool childAttachedAllowedWhenAttachingChildren(ContainerNode*);
DEFINE_NODE_TYPE_CASTS(ContainerNode, isContainerNode());
+inline bool ContainerNode::hasChildCount(unsigned count) const
+{
+ Node* child = m_firstChild;
+ while (count && child) {
+ child = child->nextSibling();
+ --count;
+ }
+ return !count && !child;
+}
+
inline ContainerNode::ContainerNode(TreeScope* treeScope, ConstructionType type)
: Node(treeScope, type)
- , m_firstChild(0)
- , m_lastChild(0)
+ , m_firstChild(nullptr)
+ , m_lastChild(nullptr)
{
}
@@ -201,18 +256,18 @@ inline void ContainerNode::detachChildren(const AttachContext& context)
child->detach(childrenContext);
}
-inline unsigned Node::childNodeCount() const
+inline unsigned Node::countChildren() const
{
if (!isContainerNode())
return 0;
- return toContainerNode(this)->childNodeCount();
+ return toContainerNode(this)->countChildren();
}
-inline Node* Node::childNode(unsigned index) const
+inline Node* Node::traverseToChildAt(unsigned index) const
{
if (!isContainerNode())
return 0;
- return toContainerNode(this)->childNode(index);
+ return toContainerNode(this)->traverseToChildAt(index);
}
inline Node* Node::firstChild() const
@@ -229,20 +284,26 @@ inline Node* Node::lastChild() const
return toContainerNode(this)->lastChild();
}
-inline Node* Node::highestAncestor() const
+inline Node& Node::highestAncestorOrSelf() const
{
Node* node = const_cast<Node*>(this);
Node* highest = node;
for (; node; node = node->parentNode())
highest = node;
- return highest;
+ return *highest;
}
-// This constant controls how much buffer is initially allocated
-// for a Node Vector that is used to store child Nodes of a given Node.
-// FIXME: Optimize the value.
-const int initialNodeVectorSize = 11;
-typedef Vector<RefPtr<Node>, initialNodeVectorSize> NodeVector;
+inline ContainerNode* Node::parentElementOrShadowRoot() const
+{
+ ContainerNode* parent = parentNode();
+ return parent && (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0;
+}
+
+inline ContainerNode* Node::parentElementOrDocumentFragment() const
+{
+ ContainerNode* parent = parentNode();
+ return parent && (parent->isElementNode() || parent->isDocumentFragment()) ? parent : 0;
+}
inline void getChildNodes(Node& node, NodeVector& nodes)
{
@@ -251,71 +312,6 @@ inline void getChildNodes(Node& node, NodeVector& nodes)
nodes.append(child);
}
-class ChildNodesLazySnapshot {
- WTF_MAKE_NONCOPYABLE(ChildNodesLazySnapshot);
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit ChildNodesLazySnapshot(Node& parentNode)
- : m_currentNode(parentNode.firstChild())
- , m_currentIndex(0)
- {
- m_nextSnapshot = latestSnapshot;
- latestSnapshot = this;
- }
-
- ~ChildNodesLazySnapshot()
- {
- latestSnapshot = m_nextSnapshot;
- }
-
- // Returns 0 if there is no next Node.
- PassRefPtr<Node> nextNode()
- {
- if (LIKELY(!hasSnapshot())) {
- RefPtr<Node> node = m_currentNode;
- if (node)
- m_currentNode = node->nextSibling();
- return node.release();
- }
- Vector<RefPtr<Node> >& nodeVector = *m_childNodes;
- if (m_currentIndex >= nodeVector.size())
- return 0;
- return nodeVector[m_currentIndex++];
- }
-
- void takeSnapshot()
- {
- if (hasSnapshot())
- return;
- m_childNodes = adoptPtr(new Vector<RefPtr<Node> >());
- Node* node = m_currentNode.get();
- while (node) {
- m_childNodes->append(node);
- node = node->nextSibling();
- }
- }
-
- ChildNodesLazySnapshot* nextSnapshot() { return m_nextSnapshot; }
- bool hasSnapshot() { return !!m_childNodes.get(); }
-
- static void takeChildNodesLazySnapshot()
- {
- ChildNodesLazySnapshot* snapshot = latestSnapshot;
- while (snapshot && !snapshot->hasSnapshot()) {
- snapshot->takeSnapshot();
- snapshot = snapshot->nextSnapshot();
- }
- }
-
-private:
- static ChildNodesLazySnapshot* latestSnapshot;
-
- RefPtr<Node> m_currentNode;
- unsigned m_currentIndex;
- OwnPtr<Vector<RefPtr<Node> > > m_childNodes; // Lazily instantiated.
- ChildNodesLazySnapshot* m_nextSnapshot;
-};
-
} // namespace WebCore
#endif // ContainerNode_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.cpp b/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.cpp
deleted file mode 100644
index 4c55b46355d..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/dom/ContainerNodeAlgorithms.h"
-
-#include "core/dom/Element.h"
-#include "core/dom/shadow/ElementShadow.h"
-#include "core/dom/shadow/ShadowRoot.h"
-
-namespace WebCore {
-
-class ShadowRootVector : public Vector<RefPtr<ShadowRoot> > {
-public:
- explicit ShadowRootVector(ElementShadow* tree)
- {
- for (ShadowRoot* root = tree->youngestShadowRoot(); root; root = root->olderShadowRoot())
- append(root);
- }
-};
-
-void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoDocument(ContainerNode& node)
-{
- ChildNodesLazySnapshot snapshot(node);
- while (RefPtr<Node> child = snapshot.nextNode()) {
- // If we have been removed from the document during this loop, then
- // we don't want to tell the rest of our children that they've been
- // inserted into the document because they haven't.
- if (node.inDocument() && child->parentNode() == node)
- notifyNodeInsertedIntoDocument(*child);
- }
-
- if (!node.isElementNode())
- return;
-
- if (ElementShadow* shadow = toElement(node).shadow()) {
- ShadowRootVector roots(shadow);
- for (size_t i = 0; i < roots.size(); ++i) {
- if (node.inDocument() && roots[i]->host() == node)
- notifyNodeInsertedIntoDocument(*roots[i]);
- }
- }
-}
-
-void ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree(ContainerNode& node)
-{
- for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
- if (child->isContainerNode())
- notifyNodeInsertedIntoTree(toContainerNode(*child));
- }
-
- for (ShadowRoot* root = node.youngestShadowRoot(); root; root = root->olderShadowRoot())
- notifyNodeInsertedIntoTree(*root);
-}
-
-void ChildNodeRemovalNotifier::notifyDescendantRemovedFromDocument(ContainerNode& node)
-{
- ChildNodesLazySnapshot snapshot(node);
- while (RefPtr<Node> child = snapshot.nextNode()) {
- // If we have been added to the document during this loop, then we
- // don't want to tell the rest of our children that they've been
- // removed from the document because they haven't.
- if (!node.inDocument() && child->parentNode() == node)
- notifyNodeRemovedFromDocument(*child);
- }
-
- if (!node.isElementNode())
- return;
-
- if (node.document().cssTarget() == node)
- node.document().setCSSTarget(0);
-
- if (ElementShadow* shadow = toElement(node).shadow()) {
- ShadowRootVector roots(shadow);
- for (size_t i = 0; i < roots.size(); ++i) {
- if (!node.inDocument() && roots[i]->host() == node)
- notifyNodeRemovedFromDocument(*roots[i]);
- }
- }
-}
-
-void ChildNodeRemovalNotifier::notifyDescendantRemovedFromTree(ContainerNode& node)
-{
- for (Node* child = node.firstChild(); child; child = child->nextSibling()) {
- if (child->isContainerNode())
- notifyNodeRemovedFromTree(toContainerNode(*child));
- }
-
- if (!node.isElementNode())
- return;
-
- if (ElementShadow* shadow = toElement(node).shadow()) {
- ShadowRootVector roots(shadow);
- for (size_t i = 0; i < roots.size(); ++i)
- notifyNodeRemovedFromTree(*roots[i]);
- }
-}
-
-void ChildFrameDisconnector::collectFrameOwners(ElementShadow& shadow)
-{
- for (ShadowRoot* root = shadow.youngestShadowRoot(); root; root = root->olderShadowRoot())
- collectFrameOwners(*root);
-}
-
-#ifndef NDEBUG
-unsigned assertConnectedSubrameCountIsConsistent(Node& node)
-{
- unsigned count = 0;
-
- if (node.isElementNode()) {
- if (node.isFrameOwnerElement() && toHTMLFrameOwnerElement(node).contentFrame())
- count++;
-
- if (ElementShadow* shadow = toElement(node).shadow()) {
- for (ShadowRoot* root = shadow->youngestShadowRoot(); root; root = root->olderShadowRoot())
- count += assertConnectedSubrameCountIsConsistent(*root);
- }
- }
-
- for (Node* child = node.firstChild(); child; child = child->nextSibling())
- count += assertConnectedSubrameCountIsConsistent(*child);
-
- // If we undercount there's possibly a security bug since we'd leave frames
- // in subtrees outside the document.
- ASSERT(node.connectedSubframeCount() >= count);
-
- // If we overcount it's safe, but not optimal because it means we'll traverse
- // through the document in ChildFrameDisconnector looking for frames that have
- // already been disconnected.
- ASSERT(node.connectedSubframeCount() == count);
-
- return count;
-}
-#endif
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h b/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h
index b863c252f2f..67691aade58 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ContainerNodeAlgorithms.h
@@ -23,49 +23,10 @@
#define ContainerNodeAlgorithms_h
#include "core/dom/Document.h"
-#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/inspector/InspectorInstrumentation.h"
#include "wtf/Assertions.h"
namespace WebCore {
-class ChildNodeInsertionNotifier {
-public:
- explicit ChildNodeInsertionNotifier(ContainerNode& insertionPoint)
- : m_insertionPoint(insertionPoint)
- {
- }
-
- void notify(Node&);
-
-private:
- void notifyDescendantInsertedIntoDocument(ContainerNode&);
- void notifyDescendantInsertedIntoTree(ContainerNode&);
- void notifyNodeInsertedIntoDocument(Node&);
- void notifyNodeInsertedIntoTree(ContainerNode&);
-
- ContainerNode& m_insertionPoint;
- Vector< RefPtr<Node> > m_postInsertionNotificationTargets;
-};
-
-class ChildNodeRemovalNotifier {
-public:
- explicit ChildNodeRemovalNotifier(ContainerNode& insertionPoint)
- : m_insertionPoint(insertionPoint)
- {
- }
-
- void notify(Node&);
-
-private:
- void notifyDescendantRemovedFromDocument(ContainerNode&);
- void notifyDescendantRemovedFromTree(ContainerNode&);
- void notifyNodeRemovedFromDocument(Node&);
- void notifyNodeRemovedFromTree(ContainerNode&);
-
- ContainerNode& m_insertionPoint;
-};
-
namespace Private {
template<class GenericNode, class GenericNodeContainer>
@@ -73,6 +34,7 @@ namespace Private {
}
+#if !ENABLE(OILPAN)
// Helper functions for TreeShared-derived classes, which have a 'Node' style interface
// This applies to 'ContainerNode' and 'SVGElementInstance'
template<class GenericNode, class GenericNodeContainer>
@@ -96,62 +58,17 @@ inline void removeDetachedChildrenInContainer(GenericNodeContainer& container)
if (next == 0)
tail = 0;
- if (n->hasChildNodes())
+ if (n->hasChildren())
Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer&>(*n));
delete n;
}
}
-
-template<class GenericNode, class GenericNodeContainer>
-inline void appendChildToContainer(GenericNode& child, GenericNodeContainer& container)
-{
- child.setParentOrShadowHostNode(&container);
-
- GenericNode* lastChild = container.lastChild();
- if (lastChild) {
- child.setPreviousSibling(lastChild);
- lastChild->setNextSibling(&child);
- } else {
- container.setFirstChild(&child);
- }
-
- container.setLastChild(&child);
-}
+#endif
// Helper methods for removeDetachedChildrenInContainer, hidden from WebCore namespace
namespace Private {
- template<class GenericNode, class GenericNodeContainer, bool dispatchRemovalNotification>
- struct NodeRemovalDispatcher {
- static void dispatch(GenericNode&, GenericNodeContainer&)
- {
- // no-op, by default
- }
- };
-
- template<class GenericNode, class GenericNodeContainer>
- struct NodeRemovalDispatcher<GenericNode, GenericNodeContainer, true> {
- static void dispatch(GenericNode& node, GenericNodeContainer& container)
- {
- // Clean up any TreeScope to a removed tree.
- if (Document* containerDocument = container.ownerDocument())
- containerDocument->adoptIfNeeded(node);
- if (node.inDocument())
- ChildNodeRemovalNotifier(container).notify(node);
- }
- };
-
- template<class GenericNode>
- struct ShouldDispatchRemovalNotification {
- static const bool value = false;
- };
-
- template<>
- struct ShouldDispatchRemovalNotification<Node> {
- static const bool value = true;
- };
-
template<class GenericNode, class GenericNodeContainer>
void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer& container)
{
@@ -180,8 +97,10 @@ namespace Private {
tail = n;
} else {
- RefPtr<GenericNode> protect(n); // removedFromDocument may remove remove all references to this node.
- NodeRemovalDispatcher<GenericNode, GenericNodeContainer, ShouldDispatchRemovalNotification<GenericNode>::value>::dispatch(*n, container);
+ RefPtrWillBeRawPtr<GenericNode> protect(n); // removedFromDocument may remove all references to this node.
+ container.document().adoptIfNeeded(*n);
+ if (n->inDocument())
+ container.notifyNodeRemoved(*n);
}
}
@@ -190,151 +109,6 @@ namespace Private {
} // namespace Private
-inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoDocument(Node& node)
-{
- ASSERT(m_insertionPoint.inDocument());
- RefPtr<Node> protect(node);
- if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto(&m_insertionPoint))
- m_postInsertionNotificationTargets.append(&node);
- if (node.isContainerNode())
- notifyDescendantInsertedIntoDocument(toContainerNode(node));
-}
-
-inline void ChildNodeInsertionNotifier::notifyNodeInsertedIntoTree(ContainerNode& node)
-{
- NoEventDispatchAssertion assertNoEventDispatch;
- ASSERT(!m_insertionPoint.inDocument());
-
- if (Node::InsertionShouldCallDidNotifySubtreeInsertions == node.insertedInto(&m_insertionPoint))
- m_postInsertionNotificationTargets.append(&node);
- notifyDescendantInsertedIntoTree(node);
-}
-
-inline void ChildNodeInsertionNotifier::notify(Node& node)
-{
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- InspectorInstrumentation::didInsertDOMNode(&node);
-
- RefPtr<Document> protectDocument(node.document());
- RefPtr<Node> protectNode(node);
-
- if (m_insertionPoint.inDocument())
- notifyNodeInsertedIntoDocument(node);
- else if (node.isContainerNode())
- notifyNodeInsertedIntoTree(toContainerNode(node));
-
- for (size_t i = 0; i < m_postInsertionNotificationTargets.size(); ++i) {
- Node* targetNode = m_postInsertionNotificationTargets[i].get();
- if (targetNode->inDocument())
- targetNode->didNotifySubtreeInsertionsToDocument();
- }
-}
-
-inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromDocument(Node& node)
-{
- ASSERT(m_insertionPoint.inDocument());
- node.removedFrom(&m_insertionPoint);
-
- if (node.isContainerNode())
- notifyDescendantRemovedFromDocument(toContainerNode(node));
-}
-
-inline void ChildNodeRemovalNotifier::notifyNodeRemovedFromTree(ContainerNode& node)
-{
- NoEventDispatchAssertion assertNoEventDispatch;
- ASSERT(!m_insertionPoint.inDocument());
-
- node.removedFrom(&m_insertionPoint);
- notifyDescendantRemovedFromTree(node);
-}
-
-inline void ChildNodeRemovalNotifier::notify(Node& node)
-{
- if (node.inDocument()) {
- notifyNodeRemovedFromDocument(node);
- node.document().notifyRemovePendingSheetIfNeeded();
- } else if (node.isContainerNode())
- notifyNodeRemovedFromTree(toContainerNode(node));
-}
-
-class ChildFrameDisconnector {
-public:
- enum DisconnectPolicy {
- RootAndDescendants,
- DescendantsOnly
- };
-
- explicit ChildFrameDisconnector(Node& root)
- : m_root(root)
- {
- }
-
- void disconnect(DisconnectPolicy = RootAndDescendants);
-
-private:
- void collectFrameOwners(Node& root);
- void collectFrameOwners(ElementShadow&);
- void disconnectCollectedFrameOwners();
-
- Vector<RefPtr<HTMLFrameOwnerElement>, 10> m_frameOwners;
- Node& m_root;
-};
-
-#ifndef NDEBUG
-unsigned assertConnectedSubrameCountIsConsistent(Node&);
-#endif
-
-inline void ChildFrameDisconnector::collectFrameOwners(Node& root)
-{
- if (!root.connectedSubframeCount())
- return;
-
- if (root.isHTMLElement() && root.isFrameOwnerElement())
- m_frameOwners.append(&toHTMLFrameOwnerElement(root));
-
- for (Node* child = root.firstChild(); child; child = child->nextSibling())
- collectFrameOwners(*child);
-
- ElementShadow* shadow = root.isElementNode() ? toElement(root).shadow() : 0;
- if (shadow)
- collectFrameOwners(*shadow);
-}
-
-inline void ChildFrameDisconnector::disconnectCollectedFrameOwners()
-{
- // Must disable frame loading in the subtree so an unload handler cannot
- // insert more frames and create loaded frames in detached subtrees.
- SubframeLoadingDisabler disabler(m_root);
-
- for (unsigned i = 0; i < m_frameOwners.size(); ++i) {
- HTMLFrameOwnerElement* owner = m_frameOwners[i].get();
- // Don't need to traverse up the tree for the first owner since no
- // script could have moved it.
- if (!i || m_root.containsIncludingShadowDOM(owner))
- owner->disconnectContentFrame();
- }
-}
-
-inline void ChildFrameDisconnector::disconnect(DisconnectPolicy policy)
-{
-#ifndef NDEBUG
- assertConnectedSubrameCountIsConsistent(m_root);
-#endif
-
- if (!m_root.connectedSubframeCount())
- return;
-
- if (policy == RootAndDescendants)
- collectFrameOwners(m_root);
- else {
- for (Node* child = m_root.firstChild(); child; child = child->nextSibling())
- collectFrameOwners(*child);
- }
-
- disconnectCollectedFrameOwners();
-}
-
} // namespace WebCore
#endif // ContainerNodeAlgorithms_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp b/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp
index 980dde13bfb..2e17b30dace 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.cpp
@@ -27,16 +27,15 @@
#include "config.h"
#include "core/dom/ContextFeatures.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/dom/Document.h"
#include "core/page/Page.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-ContextFeaturesClient* ContextFeaturesClient::empty()
+PassOwnPtr<ContextFeaturesClient> ContextFeaturesClient::empty()
{
- DEFINE_STATIC_LOCAL(ContextFeaturesClient, empty, ());
- return &empty;
+ return adoptPtr(new ContextFeaturesClient());
}
const char* ContextFeatures::supplementName()
@@ -46,7 +45,11 @@ const char* ContextFeatures::supplementName()
ContextFeatures* ContextFeatures::defaultSwitch()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<ContextFeatures>, instance, (ContextFeatures::create(ContextFeaturesClient::empty())));
+#else
DEFINE_STATIC_REF(ContextFeatures, instance, (ContextFeatures::create(ContextFeaturesClient::empty())));
+#endif
return instance;
}
@@ -54,21 +57,14 @@ bool ContextFeatures::dialogElementEnabled(Document* document)
{
if (!document)
return RuntimeEnabledFeatures::dialogElementEnabled();
- return document->contextFeatures()->isEnabled(document, DialogElement, RuntimeEnabledFeatures::dialogElementEnabled());
-}
-
-bool ContextFeatures::styleScopedEnabled(Document* document)
-{
- if (!document)
- return RuntimeEnabledFeatures::styleScopedEnabled();
- return document->contextFeatures()->isEnabled(document, StyleScoped, RuntimeEnabledFeatures::styleScopedEnabled());
+ return document->contextFeatures().isEnabled(document, DialogElement, RuntimeEnabledFeatures::dialogElementEnabled());
}
bool ContextFeatures::pagePopupEnabled(Document* document)
{
if (!document)
return false;
- return document->contextFeatures()->isEnabled(document, PagePopup, false);
+ return document->contextFeatures().isEnabled(document, PagePopup, false);
}
bool ContextFeatures::mutationEventsEnabled(Document* document)
@@ -76,25 +72,25 @@ bool ContextFeatures::mutationEventsEnabled(Document* document)
ASSERT(document);
if (!document)
return true;
- return document->contextFeatures()->isEnabled(document, MutationEvents, true);
+ return document->contextFeatures().isEnabled(document, MutationEvents, true);
}
bool ContextFeatures::pushStateEnabled(Document* document)
{
- return document->contextFeatures()->isEnabled(document, PushState, true);
+ return document->contextFeatures().isEnabled(document, PushState, true);
}
-void provideContextFeaturesTo(Page* page, ContextFeaturesClient* client)
+void provideContextFeaturesTo(Page& page, PassOwnPtr<ContextFeaturesClient> client)
{
- RefCountedSupplement<Page, ContextFeatures>::provideTo(page, ContextFeatures::supplementName(), ContextFeatures::create(client));
+ ContextFeatures::SupplementType::provideTo(page, ContextFeatures::supplementName(), ContextFeatures::create(client));
}
-void provideContextFeaturesToDocumentFrom(Document* document, Page* page)
+void provideContextFeaturesToDocumentFrom(Document& document, Page& page)
{
- ContextFeatures* provided = static_cast<ContextFeatures*>(RefCountedSupplement<Page, ContextFeatures>::from(page, ContextFeatures::supplementName()));
+ ContextFeatures* provided = static_cast<ContextFeatures*>(ContextFeatures::SupplementType::from(page, ContextFeatures::supplementName()));
if (!provided)
return;
- document->setContextFeatures(provided);
+ document.setContextFeatures(*provided);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h b/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h
index 109b781ff09..ab479ab90dd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ContextFeatures.h
@@ -35,11 +35,18 @@ class ContextFeaturesClient;
class Document;
class Page;
+#if ENABLE(OILPAN)
+class ContextFeatures FINAL : public GarbageCollectedFinalized<ContextFeatures>, public HeapSupplement<Page> {
+ USING_GARBAGE_COLLECTED_MIXIN(ContextFeatures);
+public:
+ typedef HeapSupplement<Page> SupplementType;
+#else
class ContextFeatures : public RefCountedSupplement<Page, ContextFeatures> {
public:
+ typedef RefCountedSupplement<Page, ContextFeatures> SupplementType;
+#endif
enum FeatureType {
DialogElement = 0,
- StyleScoped,
PagePopup,
MutationEvents,
PushState,
@@ -48,10 +55,9 @@ public:
static const char* supplementName();
static ContextFeatures* defaultSwitch();
- static PassRefPtr<ContextFeatures> create(ContextFeaturesClient*);
+ static PassRefPtrWillBeRawPtr<ContextFeatures> create(PassOwnPtr<ContextFeaturesClient>);
static bool dialogElementEnabled(Document*);
- static bool styleScopedEnabled(Document*);
static bool pagePopupEnabled(Document*);
static bool mutationEventsEnabled(Document*);
static bool pushStateEnabled(Document*);
@@ -59,38 +65,34 @@ public:
bool isEnabled(Document*, FeatureType, bool) const;
void urlDidChange(Document*);
+#if ENABLE(OILPAN)
+ virtual void trace(Visitor* visitor) OVERRIDE { HeapSupplement<Page>::trace(visitor); }
+#endif
+
private:
- explicit ContextFeatures(ContextFeaturesClient* client)
+ explicit ContextFeatures(PassOwnPtr<ContextFeaturesClient> client)
: m_client(client)
{ }
- virtual void hostDestroyed() OVERRIDE;
-
- ContextFeaturesClient* m_client;
+ OwnPtr<ContextFeaturesClient> m_client;
};
-inline void ContextFeatures::hostDestroyed()
-{
- m_client = 0;
-}
-
-
class ContextFeaturesClient {
WTF_MAKE_FAST_ALLOCATED;
public:
- static ContextFeaturesClient* empty();
+ static PassOwnPtr<ContextFeaturesClient> empty();
virtual ~ContextFeaturesClient() { }
virtual bool isEnabled(Document*, ContextFeatures::FeatureType, bool defaultValue) { return defaultValue; }
virtual void urlDidChange(Document*) { }
};
-void provideContextFeaturesTo(Page*, ContextFeaturesClient*);
-void provideContextFeaturesToDocumentFrom(Document*, Page*);
+void provideContextFeaturesTo(Page&, PassOwnPtr<ContextFeaturesClient>);
+void provideContextFeaturesToDocumentFrom(Document&, Page&);
-inline PassRefPtr<ContextFeatures> ContextFeatures::create(ContextFeaturesClient* client)
+inline PassRefPtrWillBeRawPtr<ContextFeatures> ContextFeatures::create(PassOwnPtr<ContextFeaturesClient> client)
{
- return adoptRef(new ContextFeatures(client));
+ return adoptRefWillBeNoop(new ContextFeatures(client));
}
inline bool ContextFeatures::isEnabled(Document* document, FeatureType type, bool defaultValue) const
diff --git a/chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp b/chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
index 048978c7354..af9f97ca291 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ContextLifecycleNotifier.cpp
@@ -59,7 +59,6 @@ void ContextLifecycleNotifier::removeObserver(ContextLifecycleNotifier::Observer
RELEASE_ASSERT(m_iterating != IteratingOverContextObservers);
if (observer->observerType() == Observer::ActiveDOMObjectType) {
- RELEASE_ASSERT(m_iterating != IteratingOverActiveDOMObjects);
m_activeDOMObjects.remove(static_cast<ActiveDOMObject*>(observer));
}
}
@@ -67,44 +66,61 @@ void ContextLifecycleNotifier::removeObserver(ContextLifecycleNotifier::Observer
void ContextLifecycleNotifier::notifyResumingActiveDOMObjects()
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverActiveDOMObjects);
- ActiveDOMObjectSet::iterator activeObjectsEnd = m_activeDOMObjects.end();
- for (ActiveDOMObjectSet::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
- ASSERT((*iter)->executionContext() == context());
- ASSERT((*iter)->suspendIfNeededCalled());
- (*iter)->resume();
+ Vector<ActiveDOMObject*> snapshotOfActiveDOMObjects;
+ copyToVector(m_activeDOMObjects, snapshotOfActiveDOMObjects);
+ for (Vector<ActiveDOMObject*>::iterator iter = snapshotOfActiveDOMObjects.begin(); iter != snapshotOfActiveDOMObjects.end(); iter++) {
+ // FIXME: Oilpan: At the moment, it's possible that the ActiveDOMObject is destructed
+ // during the iteration. Once we move ActiveDOMObject to the heap and
+ // make m_activeDOMObjects a HeapHashSet<WeakMember<ActiveDOMObject>>,
+ // it's no longer possible that ActiveDOMObject is destructed during the iteration,
+ // so we can remove the hack (i.e., we can just iterate m_activeDOMObjects without
+ // taking a snapshot). For more details, see https://codereview.chromium.org/247253002/.
+ if (m_activeDOMObjects.contains(*iter)) {
+ ASSERT((*iter)->executionContext() == context());
+ ASSERT((*iter)->suspendIfNeededCalled());
+ (*iter)->resume();
+ }
}
}
void ContextLifecycleNotifier::notifySuspendingActiveDOMObjects()
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverActiveDOMObjects);
- ActiveDOMObjectSet::iterator activeObjectsEnd = m_activeDOMObjects.end();
- for (ActiveDOMObjectSet::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
- ASSERT((*iter)->executionContext() == context());
- ASSERT((*iter)->suspendIfNeededCalled());
- (*iter)->suspend();
+ Vector<ActiveDOMObject*> snapshotOfActiveDOMObjects;
+ copyToVector(m_activeDOMObjects, snapshotOfActiveDOMObjects);
+ for (Vector<ActiveDOMObject*>::iterator iter = snapshotOfActiveDOMObjects.begin(); iter != snapshotOfActiveDOMObjects.end(); iter++) {
+ // It's possible that the ActiveDOMObject is already destructed.
+ // See a FIXME above.
+ if (m_activeDOMObjects.contains(*iter)) {
+ ASSERT((*iter)->executionContext() == context());
+ ASSERT((*iter)->suspendIfNeededCalled());
+ (*iter)->suspend();
+ }
}
}
void ContextLifecycleNotifier::notifyStoppingActiveDOMObjects()
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverActiveDOMObjects);
- ActiveDOMObjectSet::iterator activeObjectsEnd = m_activeDOMObjects.end();
- for (ActiveDOMObjectSet::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
- ASSERT((*iter)->executionContext() == context());
- ASSERT((*iter)->suspendIfNeededCalled());
- (*iter)->stop();
+ Vector<ActiveDOMObject*> snapshotOfActiveDOMObjects;
+ copyToVector(m_activeDOMObjects, snapshotOfActiveDOMObjects);
+ for (Vector<ActiveDOMObject*>::iterator iter = snapshotOfActiveDOMObjects.begin(); iter != snapshotOfActiveDOMObjects.end(); iter++) {
+ // It's possible that the ActiveDOMObject is already destructed.
+ // See a FIXME above.
+ if (m_activeDOMObjects.contains(*iter)) {
+ ASSERT((*iter)->executionContext() == context());
+ ASSERT((*iter)->suspendIfNeededCalled());
+ (*iter)->stop();
+ }
}
}
bool ContextLifecycleNotifier::hasPendingActivity() const
{
- ActiveDOMObjectSet::const_iterator activeObjectsEnd = activeDOMObjects().end();
- for (ActiveDOMObjectSet::const_iterator iter = activeDOMObjects().begin(); iter != activeObjectsEnd; ++iter) {
+ for (ActiveDOMObjectSet::const_iterator iter = m_activeDOMObjects.begin(); iter != m_activeDOMObjects.end(); ++iter) {
if ((*iter)->hasPendingActivity())
return true;
}
-
return false;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h b/chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h
index 9902ebdcefd..d341205b62b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h
+++ b/chromium/third_party/WebKit/Source/core/dom/CrossThreadTask.h
@@ -57,8 +57,14 @@ template<typename T> struct CrossThreadTaskTraits<PassOwnPtr<T> > {
typedef PassOwnPtr<T> ParamType;
};
+// FIXME: Oilpan: Using a RawPtr is not safe.
+// We need to move ExecutionContextTask to the heap and make this a Member.
+template<typename T> struct CrossThreadTaskTraits<RawPtr<T> > {
+ typedef RawPtr<T> ParamType;
+};
+
template<typename P1, typename MP1>
-class CrossThreadTask1 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask1 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1);
typedef CrossThreadTask1<P1, MP1> CrossThreadTask;
@@ -87,7 +93,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2>
-class CrossThreadTask2 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask2 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2);
typedef CrossThreadTask2<P1, MP1, P2, MP2> CrossThreadTask;
@@ -119,7 +125,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3>
-class CrossThreadTask3 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask3 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3);
typedef CrossThreadTask3<P1, MP1, P2, MP2, P3, MP3> CrossThreadTask;
@@ -154,7 +160,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4>
-class CrossThreadTask4 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask4 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4);
typedef CrossThreadTask4<P1, MP1, P2, MP2, P3, MP3, P4, MP4> CrossThreadTask;
@@ -192,7 +198,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5>
-class CrossThreadTask5 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask5 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5);
typedef CrossThreadTask5<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5> CrossThreadTask;
@@ -233,7 +239,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6>
-class CrossThreadTask6 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask6 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6);
typedef CrossThreadTask6<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6> CrossThreadTask;
@@ -277,7 +283,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7>
-class CrossThreadTask7 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask7 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7);
typedef CrossThreadTask7<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6, P7, MP7> CrossThreadTask;
@@ -324,7 +330,7 @@ private:
};
template<typename P1, typename MP1, typename P2, typename MP2, typename P3, typename MP3, typename P4, typename MP4, typename P5, typename MP5, typename P6, typename MP6, typename P7, typename MP7, typename P8, typename MP8>
-class CrossThreadTask8 : public ExecutionContextTask {
+class GC_PLUGIN_IGNORE("crbug.com/378192") CrossThreadTask8 : public ExecutionContextTask {
public:
typedef void (*Method)(ExecutionContext*, MP1, MP2, MP3, MP4, MP5, MP6, MP7, MP8);
typedef CrossThreadTask8<P1, MP1, P2, MP2, P3, MP3, P4, MP4, P5, MP5, P6, MP6, P7, MP7, P8, MP8> CrossThreadTask;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMError.h b/chromium/third_party/WebKit/Source/core/dom/DOMError.h
index a66d0e2175f..845c23063b0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMError.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMError.h
@@ -29,36 +29,39 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/DOMException.h"
#include "core/dom/ExceptionCode.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class DOMError : public RefCounted<DOMError>, public ScriptWrappable {
+class DOMError : public RefCountedWillBeGarbageCollectedFinalized<DOMError>, public ScriptWrappable {
public:
- static PassRefPtr<DOMError> create(const String& name)
+ static PassRefPtrWillBeRawPtr<DOMError> create(const String& name)
{
- return adoptRef(new DOMError(name));
+ return adoptRefWillBeNoop(new DOMError(name));
}
- static PassRefPtr<DOMError> create(const String& name, const String& message)
+ static PassRefPtrWillBeRawPtr<DOMError> create(const String& name, const String& message)
{
- return adoptRef(new DOMError(name, message));
+ return adoptRefWillBeNoop(new DOMError(name, message));
}
- static PassRefPtr<DOMError> create(ExceptionCode ec)
+ static PassRefPtrWillBeRawPtr<DOMError> create(ExceptionCode ec)
{
- return adoptRef(new DOMError(DOMException::getErrorName(ec), DOMException::getErrorMessage(ec)));
+ return adoptRefWillBeNoop(new DOMError(DOMException::getErrorName(ec), DOMException::getErrorMessage(ec)));
}
- static PassRefPtr<DOMError> create(ExceptionCode ec, const String& message)
+ static PassRefPtrWillBeRawPtr<DOMError> create(ExceptionCode ec, const String& message)
{
- return adoptRef(new DOMError(DOMException::getErrorName(ec), message));
+ return adoptRefWillBeNoop(new DOMError(DOMException::getErrorName(ec), message));
}
const String& name() const { return m_name; }
const String& message() const { return m_message; }
+ void trace(Visitor*) { }
+
protected:
explicit DOMError(const String& name);
DOMError(const String& name, const String& message);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMError.idl b/chromium/third_party/WebKit/Source/core/dom/DOMError.idl
index b2ea60f4821..aba4e7a6c51 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMError.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMError.idl
@@ -26,7 +26,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
[
- NoInterfaceObject
+ Constructor(DOMString name, optional DOMString message = null),
+ WillBeGarbageCollected
] interface DOMError {
readonly attribute DOMString name;
readonly attribute DOMString message;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMException.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMException.cpp
index ebb5b209f6c..06128d40a3d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMException.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMException.cpp
@@ -29,7 +29,7 @@
#include "config.h"
#include "core/dom/DOMException.h"
-#include "ExceptionCode.h"
+#include "core/dom/ExceptionCode.h"
namespace WebCore {
@@ -76,6 +76,9 @@ static const struct CoreException {
// SQL
{ "DatabaseError", "The operation failed for some reason related to the database.", 0 },
+
+ // Web Crypto
+ { "OperationError", "The operation failed for an operation-specific reason", 0 },
};
static const CoreException* getErrorEntry(ExceptionCode ec)
@@ -96,11 +99,11 @@ DOMException::DOMException(unsigned short code, const String& name, const String
ScriptWrappable::init(this);
}
-PassRefPtr<DOMException> DOMException::create(ExceptionCode ec, const String& sanitizedMessage, const String& unsanitizedMessage)
+PassRefPtrWillBeRawPtr<DOMException> DOMException::create(ExceptionCode ec, const String& sanitizedMessage, const String& unsanitizedMessage)
{
const CoreException* entry = getErrorEntry(ec);
ASSERT(entry);
- return adoptRef(new DOMException(entry->code,
+ return adoptRefWillBeNoop(new DOMException(entry->code,
entry->name ? entry->name : "Error",
sanitizedMessage.isNull() ? String(entry->message) : sanitizedMessage,
unsanitizedMessage));
@@ -136,12 +139,4 @@ String DOMException::getErrorMessage(ExceptionCode ec)
return entry->message;
}
-unsigned short DOMException::getLegacyErrorCode(ExceptionCode ec)
-{
- const CoreException* entry = getErrorEntry(ec);
- ASSERT(entry);
-
- return (entry && entry->code) ? entry->code : 0;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMException.h b/chromium/third_party/WebKit/Source/core/dom/DOMException.h
index 825cf50338c..221a312337c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMException.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMException.h
@@ -30,6 +30,7 @@
#define DOMException_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -38,9 +39,9 @@ namespace WebCore {
typedef int ExceptionCode;
-class DOMException : public RefCounted<DOMException>, public ScriptWrappable {
+class DOMException FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMException>, public ScriptWrappable {
public:
- static PassRefPtr<DOMException> create(ExceptionCode, const String& sanitizedMessage = String(), const String& unsanitizedMessage = String());
+ static PassRefPtrWillBeRawPtr<DOMException> create(ExceptionCode, const String& sanitizedMessage = String(), const String& unsanitizedMessage = String());
unsigned short code() const { return m_code; }
String name() const { return m_name; }
@@ -55,7 +56,8 @@ public:
static String getErrorName(ExceptionCode);
static String getErrorMessage(ExceptionCode);
- static unsigned short getLegacyErrorCode(ExceptionCode);
+
+ void trace(Visitor*) { }
private:
DOMException(unsigned short m_code, const String& name, const String& sanitizedMessage, const String& unsanitizedMessage);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMException.idl b/chromium/third_party/WebKit/Source/core/dom/DOMException.idl
index 68d04bf4782..44423509cbc 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMException.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMException.idl
@@ -27,7 +27,8 @@
*/
[
- DoNotCheckConstants
+ DoNotCheckConstants,
+ WillBeGarbageCollected,
] exception DOMException {
readonly attribute unsigned short code;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
index ff898a52dea..0a66b556589 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.cpp
@@ -25,9 +25,9 @@
#include "config.h"
#include "core/dom/DOMImplementation.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/MediaList.h"
#include "core/css/StyleSheetContents.h"
@@ -36,7 +36,10 @@
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/XMLDocument.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/HTMLViewSourceDocument.h"
@@ -45,9 +48,7 @@
#include "core/html/PluginDocument.h"
#include "core/html/TextDocument.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
-#include "core/svg/SVGDocument.h"
#include "platform/ContentType.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/graphics/Image.h"
@@ -132,7 +133,7 @@ static bool isSupportedSVG11Feature(const String& feature, const String& version
addString(svgFeatures, "GraphicsAttribute");
addString(svgFeatures, "BaseGraphicsAttribute");
addString(svgFeatures, "Marker");
-// addString(svgFeatures, "ColorProfile"); // requires color-profile, bug 6037
+// addString(svgFeatures, "ColorProfile");
addString(svgFeatures, "Gradient");
addString(svgFeatures, "Pattern");
addString(svgFeatures, "Clip");
@@ -146,7 +147,6 @@ static bool isSupportedSVG11Feature(const String& feature, const String& version
addString(svgFeatures, "Cursor");
addString(svgFeatures, "Hyperlinking");
addString(svgFeatures, "XlinkAttribute");
- addString(svgFeatures, "ExternalResourcesRequired");
addString(svgFeatures, "View");
addString(svgFeatures, "Script");
addString(svgFeatures, "Animation");
@@ -178,42 +178,46 @@ bool DOMImplementation::hasFeature(const String& feature, const String& version)
return true;
}
-PassRefPtr<DocumentType> DOMImplementation::createDocumentType(const AtomicString& qualifiedName,
+bool DOMImplementation::hasFeatureForBindings(const String& feature, const String& version)
+{
+ if (!hasFeature(feature, version)) {
+ UseCounter::count(m_document, UseCounter::DOMImplementationHasFeatureReturnFalse);
+ return false;
+ }
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<DocumentType> DOMImplementation::createDocumentType(const AtomicString& qualifiedName,
const String& publicId, const String& systemId, ExceptionState& exceptionState)
{
AtomicString prefix, localName;
if (!Document::parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
- return 0;
+ return nullptr;
- return DocumentType::create(&m_document, qualifiedName, publicId, systemId);
+ return DocumentType::create(m_document, qualifiedName, publicId, systemId);
}
-DOMImplementation* DOMImplementation::getInterface(const String& /*feature*/)
-{
- return 0;
-}
-
-PassRefPtr<Document> DOMImplementation::createDocument(const AtomicString& namespaceURI,
+PassRefPtrWillBeRawPtr<XMLDocument> DOMImplementation::createDocument(const AtomicString& namespaceURI,
const AtomicString& qualifiedName, DocumentType* doctype, ExceptionState& exceptionState)
{
- RefPtr<Document> doc;
- DocumentInit init = DocumentInit::fromContext(m_document.contextDocument());
+ RefPtrWillBeRawPtr<XMLDocument> doc = nullptr;
+ DocumentInit init = DocumentInit::fromContext(document().contextDocument());
if (namespaceURI == SVGNames::svgNamespaceURI) {
- doc = SVGDocument::create(init);
+ doc = XMLDocument::createSVG(init);
} else if (namespaceURI == HTMLNames::xhtmlNamespaceURI) {
- doc = Document::createXHTML(init.withRegistrationContext(m_document.registrationContext()));
+ doc = XMLDocument::createXHTML(init.withRegistrationContext(document().registrationContext()));
} else {
- doc = Document::create(init);
+ doc = XMLDocument::create(init);
}
- doc->setSecurityOrigin(m_document.securityOrigin()->isolatedCopy());
- doc->setContextFeatures(m_document.contextFeatures());
+ doc->setSecurityOrigin(document().securityOrigin()->isolatedCopy());
+ doc->setContextFeatures(document().contextFeatures());
- RefPtr<Node> documentElement;
+ RefPtrWillBeRawPtr<Node> documentElement = nullptr;
if (!qualifiedName.isEmpty()) {
documentElement = doc->createElementNS(namespaceURI, qualifiedName, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
}
if (doctype)
@@ -224,33 +228,21 @@ PassRefPtr<Document> DOMImplementation::createDocument(const AtomicString& names
return doc.release();
}
-PassRefPtr<CSSStyleSheet> DOMImplementation::createCSSStyleSheet(const String&, const String& media)
-{
- // FIXME: Title should be set.
- // FIXME: Media could have wrong syntax, in which case we should generate an exception.
- RefPtr<CSSStyleSheet> sheet = CSSStyleSheet::create(StyleSheetContents::create());
- sheet->setMediaQueries(MediaQuerySet::create(media));
- return sheet;
-}
-
bool DOMImplementation::isXMLMIMEType(const String& mimeType)
{
- if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
+ if (equalIgnoringCase(mimeType, "text/xml")
+ || equalIgnoringCase(mimeType, "application/xml")
+ || equalIgnoringCase(mimeType, "text/xsl"))
return true;
- // Per RFCs 3023 and 2045 a mime type is of the form:
+ // Per RFCs 3023 and 2045, an XML MIME type is of the form:
// ^[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]+/[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]+\+xml$
int length = mimeType.length();
if (length < 7)
return false;
- if (mimeType[0] == '/' ||
- mimeType[length - 5] == '/' ||
- mimeType[length - 4] != '+' ||
- mimeType[length - 3] != 'x' ||
- mimeType[length - 2] != 'm' ||
- mimeType[length - 1] != 'l')
+ if (mimeType[0] == '/' || mimeType[length - 5] == '/' || !mimeType.endsWith("+xml", false))
return false;
bool hasSlash = false;
@@ -294,37 +286,58 @@ bool DOMImplementation::isXMLMIMEType(const String& mimeType)
return true;
}
-bool DOMImplementation::isTextMIMEType(const String& mimeType)
+bool DOMImplementation::isJSONMIMEType(const String& mimeType)
{
- if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType)
- || mimeType == "application/json" // Render JSON as text/plain.
- || (mimeType.startsWith("text/") && mimeType != "text/html"
- && mimeType != "text/xml" && mimeType != "text/xsl"))
+ if (mimeType.startsWith("application/json", false))
return true;
-
+ if (mimeType.startsWith("application/", false)) {
+ size_t subtype = mimeType.find("+json", 12, false);
+ if (subtype != kNotFound) {
+ // Just check that a parameter wasn't matched.
+ size_t parameterMarker = mimeType.find(";");
+ if (parameterMarker == kNotFound) {
+ unsigned endSubtype = static_cast<unsigned>(subtype) + 5;
+ return endSubtype == mimeType.length() || isASCIISpace(mimeType[endSubtype]);
+ }
+ return parameterMarker > subtype;
+ }
+ }
return false;
}
-PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title)
+static bool isTextPlainType(const String& mimeType)
+{
+ return mimeType.startsWith("text/", false)
+ && !(equalIgnoringCase(mimeType, "text/html")
+ || equalIgnoringCase(mimeType, "text/xml")
+ || equalIgnoringCase(mimeType, "text/xsl"));
+}
+
+bool DOMImplementation::isTextMIMEType(const String& mimeType)
{
- DocumentInit init = DocumentInit::fromContext(m_document.contextDocument())
- .withRegistrationContext(m_document.registrationContext());
- RefPtr<HTMLDocument> d = HTMLDocument::create(init);
+ return MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || isJSONMIMEType(mimeType) || isTextPlainType(mimeType);
+}
+
+PassRefPtrWillBeRawPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title)
+{
+ DocumentInit init = DocumentInit::fromContext(document().contextDocument())
+ .withRegistrationContext(document().registrationContext());
+ RefPtrWillBeRawPtr<HTMLDocument> d = HTMLDocument::create(init);
d->open();
d->write("<!doctype html><html><body></body></html>");
if (!title.isNull())
d->setTitle(title);
- d->setSecurityOrigin(m_document.securityOrigin()->isolatedCopy());
- d->setContextFeatures(m_document.contextFeatures());
+ d->setSecurityOrigin(document().securityOrigin()->isolatedCopy());
+ d->setContextFeatures(document().contextFeatures());
return d.release();
}
-PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame* frame, const KURL& url, bool inViewSourceMode)
+PassRefPtrWillBeRawPtr<Document> DOMImplementation::createDocument(const String& type, LocalFrame* frame, const KURL& url, bool inViewSourceMode)
{
return createDocument(type, DocumentInit(url, frame), inViewSourceMode);
}
-PassRefPtr<Document> DOMImplementation::createDocument(const String& type, const DocumentInit& init, bool inViewSourceMode)
+PassRefPtrWillBeRawPtr<Document> DOMImplementation::createDocument(const String& type, const DocumentInit& init, bool inViewSourceMode)
{
if (inViewSourceMode)
return HTMLViewSourceDocument::create(init, type);
@@ -333,7 +346,7 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& type, const
if (type == "text/html")
return HTMLDocument::create(init);
if (type == "application/xhtml+xml")
- return Document::createXHTML(init);
+ return XMLDocument::createXHTML(init);
PluginData* pluginData = 0;
if (init.frame() && init.frame()->page() && init.frame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
@@ -358,11 +371,16 @@ PassRefPtr<Document> DOMImplementation::createDocument(const String& type, const
if (isTextMIMEType(type))
return TextDocument::create(init);
if (type == "image/svg+xml")
- return SVGDocument::create(init);
+ return XMLDocument::createSVG(init);
if (isXMLMIMEType(type))
- return Document::create(init);
+ return XMLDocument::create(init);
return HTMLDocument::create(init);
}
+void DOMImplementation::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h
index b710d2ad22c..47a6c3212ad 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.h
@@ -25,7 +25,6 @@
#define DOMImplementation_h
#include "core/dom/Document.h"
-#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
@@ -35,43 +34,48 @@ class Document;
class DocumentInit;
class DocumentType;
class ExceptionState;
-class Frame;
+class LocalFrame;
class HTMLDocument;
class KURL;
+class XMLDocument;
-class DOMImplementation : public ScriptWrappable {
- WTF_MAKE_FAST_ALLOCATED;
+class DOMImplementation FINAL : public NoBaseWillBeGarbageCollectedFinalized<DOMImplementation>, public ScriptWrappable {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<DOMImplementation> create(Document& document) { return adoptPtr(new DOMImplementation(document)); }
-
- void ref() { m_document.ref(); }
- void deref() { m_document.deref(); }
- Document* document() { return &m_document; }
+ static PassOwnPtrWillBeRawPtr<DOMImplementation> create(Document& document)
+ {
+ return adoptPtrWillBeNoop(new DOMImplementation(document));
+ }
+
+#if !ENABLE(OILPAN)
+ void ref() { m_document->ref(); }
+ void deref() { m_document->deref(); }
+#endif
+ Document& document() const { return *m_document; }
// DOM methods & attributes for DOMImplementation
static bool hasFeature(const String& feature, const String& version);
- PassRefPtr<DocumentType> createDocumentType(const AtomicString& qualifiedName, const String& publicId, const String& systemId, ExceptionState&);
- PassRefPtr<Document> createDocument(const AtomicString& namespaceURI, const AtomicString& qualifiedName, DocumentType*, ExceptionState&);
-
- DOMImplementation* getInterface(const String& feature);
-
- // From the DOMImplementationCSS interface
- static PassRefPtr<CSSStyleSheet> createCSSStyleSheet(const String& title, const String& media);
+ bool hasFeatureForBindings(const String& feature, const String& version);
+ PassRefPtrWillBeRawPtr<DocumentType> createDocumentType(const AtomicString& qualifiedName, const String& publicId, const String& systemId, ExceptionState&);
+ PassRefPtrWillBeRawPtr<XMLDocument> createDocument(const AtomicString& namespaceURI, const AtomicString& qualifiedName, DocumentType*, ExceptionState&);
// From the HTMLDOMImplementation interface
- PassRefPtr<HTMLDocument> createHTMLDocument(const String& title);
+ PassRefPtrWillBeRawPtr<HTMLDocument> createHTMLDocument(const String& title);
// Other methods (not part of DOM)
- static PassRefPtr<Document> createDocument(const String& MIMEType, Frame*, const KURL&, bool inViewSourceMode);
- static PassRefPtr<Document> createDocument(const String& type, const DocumentInit&, bool inViewSourceMode);
+ static PassRefPtrWillBeRawPtr<Document> createDocument(const String& mimeType, LocalFrame*, const KURL&, bool inViewSourceMode);
+ static PassRefPtrWillBeRawPtr<Document> createDocument(const String& mimeType, const DocumentInit&, bool inViewSourceMode);
+
+ static bool isXMLMIMEType(const String&);
+ static bool isTextMIMEType(const String&);
+ static bool isJSONMIMEType(const String&);
- static bool isXMLMIMEType(const String& MIMEType);
- static bool isTextMIMEType(const String& MIMEType);
+ void trace(Visitor*);
private:
explicit DOMImplementation(Document&);
- Document& m_document;
+ RawPtrWillBeMember<Document> m_document;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl
index 7630c5e5fbd..472d1b0998f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMImplementation.idl
@@ -19,11 +19,13 @@
*/
[
- GenerateVisitDOMWrapper=document,
+ SetWrapperReferenceFrom=document,
+ WillBeGarbageCollected,
] interface DOMImplementation {
// DOM Level 1
+ [ImplementedAs=hasFeatureForBindings, MeasureAs=DOMImplementationHasFeature]
boolean hasFeature(DOMString feature, [TreatNullAs=NullString] DOMString version);
// DOM Level 2
@@ -31,17 +33,11 @@
[RaisesException] DocumentType createDocumentType(DOMString qualifiedName,
DOMString publicId,
DOMString systemId);
- [RaisesException] Document createDocument([TreatNullAs=NullString] DOMString namespaceURI,
- [TreatNullAs=NullString] DOMString qualifiedName,
- [Default=Undefined] optional DocumentType doctype);
-
- // DOMImplementationCSS interface from DOM Level 2 CSS
-
- [MeasureAs=DOMImplementationCreateCSSStyleSheet]
- CSSStyleSheet createCSSStyleSheet([Default=Undefined] optional DOMString title,
- [Default=Undefined] optional DOMString media);
+ [RaisesException] XMLDocument createDocument([TreatNullAs=NullString] DOMString namespaceURI,
+ [TreatNullAs=NullString] DOMString qualifiedName,
+ [Default=Undefined] optional DocumentType doctype);
// HTMLDOMImplementation interface from DOM Level 2 HTML
- HTMLDocument createHTMLDocument([Default=NullString] optional DOMString title);
+ HTMLDocument createHTMLDocument(optional DOMString title = null);
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMImplementationTest.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMImplementationTest.cpp
new file mode 100644
index 00000000000..73b2f8d1dc0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMImplementationTest.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/DOMImplementation.h"
+
+#include "wtf/text/WTFString.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+TEST(DOMImplementationTest, TextMIMEType)
+{
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("text/plain"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("text/javascript"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("TEXT/JavaScript"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/jSON"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json;foo=2"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json "));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/+json"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/x-javascript-like+json;a=2;c=4"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/javascript"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("Application/Javascript"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/x-custom+json;b=3"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/x-custom+json"));
+ // Outside of RFC-2045 grammar, but robustly accept/allow.
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/x-what+json;"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json;"));
+ EXPECT_TRUE(DOMImplementation::isTextMIMEType("application/json "));
+
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("application/x-custom;a=a+json"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("application/x-custom;a=a+json ;"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("application/x-custom+jsonsoup"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("application/x-custom+jsonsoup "));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("text/html"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("text/xml"));
+ EXPECT_FALSE(DOMImplementation::isTextMIMEType("text/xsl"));
+}
+
+TEST(DOMImplementationTest, TextXMLType)
+{
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("text/xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("Text/xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("tEXt/XML"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/XML"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/x-tra+xML"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/xslt+xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/rdf+Xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("image/svg+xml"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("text/xsl"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("text/XSL"));
+ EXPECT_TRUE(DOMImplementation::isXMLMIMEType("application/x+xml"));
+
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom;a=a+xml"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom;a=a+xml ;"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom+xml2"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom+xml2 "));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-custom+exml"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("text/html"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/xml;"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/xml "));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-what+xml;"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/x-tra+xML;a=2"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/+xML"));
+ EXPECT_FALSE(DOMImplementation::isXMLMIMEType("application/+xml"));
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.cpp
deleted file mode 100644
index 9fbf981ff46..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#include "config.h"
-#include "core/dom/DOMNamedFlowCollection.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/dom/NamedFlow.h"
-#include "wtf/text/StringHash.h"
-
-namespace WebCore {
-
-DOMNamedFlowCollection::DOMNamedFlowCollection(const Vector<NamedFlow*>& namedFlows)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
- ScriptWrappable::init(this);
- for (Vector<NamedFlow*>::const_iterator it = namedFlows.begin(); it != namedFlows.end(); ++it)
- m_namedFlows.add(*it);
-}
-
-unsigned long DOMNamedFlowCollection::length() const
-{
- return m_namedFlows.size();
-}
-
-PassRefPtr<NamedFlow> DOMNamedFlowCollection::item(unsigned long index) const
-{
- if (index >= static_cast<unsigned long>(m_namedFlows.size()))
- return 0;
- DOMNamedFlowSet::const_iterator it = m_namedFlows.begin();
- for (unsigned long i = 0; i < index; ++i)
- ++it;
- return *it;
-}
-
-PassRefPtr<NamedFlow> DOMNamedFlowCollection::namedItem(const AtomicString& name) const
-{
- DOMNamedFlowSet::const_iterator it = m_namedFlows.find<DOMNamedFlowHashTranslator, String>(name);
- if (it != m_namedFlows.end())
- return *it;
- return 0;
-}
-
-bool DOMNamedFlowCollection::hasNamedItem(const AtomicString& name) const
-{
- return namedItem(name);
-}
-
-// The HashFunctions object used by the HashSet to compare between RefPtr<NamedFlows>.
-// It is safe to set safeToCompareToEmptyOrDeleted because the HashSet will never contain null pointers or deleted values.
-struct DOMNamedFlowCollection::DOMNamedFlowHashFunctions {
- static unsigned hash(PassRefPtr<NamedFlow> key) { return DefaultHash<String>::Hash::hash(key->name()); }
- static bool equal(PassRefPtr<NamedFlow> a, PassRefPtr<NamedFlow> b) { return a->name() == b->name(); }
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-
-// The HashTranslator is used to lookup a RefPtr<NamedFlow> in the set using a name.
-struct DOMNamedFlowCollection::DOMNamedFlowHashTranslator {
- static unsigned hash(const String& key) { return DefaultHash<String>::Hash::hash(key); }
- static bool equal(PassRefPtr<NamedFlow> a, const String& b) { return a->name() == b; }
-};
-} // namespace WebCore
-
-
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.h b/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.h
deleted file mode 100644
index c7e6a6c20af..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DOMNamedFlowCollection.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef DOMNamedFlowCollection_h
-#define DOMNamedFlowCollection_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/dom/NamedFlowCollection.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class Document;
-class NamedFlow;
-
-class DOMNamedFlowCollection : public ScriptWrappable, public RefCounted<DOMNamedFlowCollection> {
-public:
- static PassRefPtr<DOMNamedFlowCollection> create(const Vector<NamedFlow*>& namedFlows)
- {
- return adoptRef(new DOMNamedFlowCollection(namedFlows));
- }
-
- unsigned long length() const;
- PassRefPtr<NamedFlow> item(unsigned long index) const;
- PassRefPtr<NamedFlow> namedItem(const AtomicString& name) const;
-
- bool hasNamedItem(const AtomicString& name) const;
-
-private:
- struct DOMNamedFlowHashFunctions;
- struct DOMNamedFlowHashTranslator;
-
- typedef ListHashSet<RefPtr<NamedFlow>, 1, DOMNamedFlowHashFunctions> DOMNamedFlowSet;
- explicit DOMNamedFlowCollection(const Vector<NamedFlow*>&);
- DOMNamedFlowSet m_namedFlows;
-};
-
-} // namespace WebCore
-#endif
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp
index 2d69533d6b3..07098c9d5e3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.cpp
@@ -58,9 +58,9 @@ void DOMSettableTokenList::add(const Vector<String>& tokens, ExceptionState& exc
for (size_t i = 0; i < tokens.size(); ++i) {
if (m_tokens.isNull())
- m_tokens.set(tokens[i], false);
+ m_tokens.set(AtomicString(tokens[i]), false);
else
- m_tokens.add(tokens[i]);
+ m_tokens.add(AtomicString(tokens[i]));
}
}
@@ -77,7 +77,7 @@ void DOMSettableTokenList::remove(const Vector<String>& tokens, ExceptionState&
{
DOMTokenList::remove(tokens, exceptionState);
for (size_t i = 0; i < tokens.size(); ++i)
- m_tokens.remove(tokens[i]);
+ m_tokens.remove(AtomicString(tokens[i]));
}
void DOMSettableTokenList::removeInternal(const AtomicString& token)
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h
index 234b505f785..bba9691d7a6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.h
@@ -27,6 +27,7 @@
#include "core/dom/DOMTokenList.h"
#include "core/dom/SpaceSplitString.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/text/AtomicString.h"
@@ -34,17 +35,24 @@ namespace WebCore {
class ExceptionState;
-class DOMSettableTokenList : public DOMTokenList, public RefCounted<DOMSettableTokenList> {
- WTF_MAKE_FAST_ALLOCATED;
+class DOMSettableTokenList FINAL
+ : public DOMTokenList
+#if !ENABLE(OILPAN)
+ , public RefCounted<DOMSettableTokenList>
+#endif
+ {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<DOMSettableTokenList> create()
+ static PassRefPtrWillBeRawPtr<DOMSettableTokenList> create()
{
- return adoptRef(new DOMSettableTokenList());
+ return adoptRefWillBeNoop(new DOMSettableTokenList());
}
virtual ~DOMSettableTokenList();
+#if !ENABLE(OILPAN)
virtual void ref() OVERRIDE { RefCounted<DOMSettableTokenList>::ref(); }
virtual void deref() OVERRIDE { RefCounted<DOMSettableTokenList>::deref(); }
+#endif
virtual unsigned length() const OVERRIDE { return m_tokens.size(); }
virtual const AtomicString item(unsigned index) const OVERRIDE;
@@ -52,7 +60,7 @@ public:
virtual void add(const Vector<String>&, ExceptionState&) OVERRIDE;
virtual void remove(const Vector<String>&, ExceptionState&) OVERRIDE;
- virtual AtomicString value() const OVERRIDE { return m_value; }
+ virtual const AtomicString& value() const OVERRIDE { return m_value; }
virtual void setValue(const AtomicString&) OVERRIDE;
const SpaceSplitString& tokens() const { return m_tokens; }
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl
index 18142d0e751..e02dd6950ac 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMSettableTokenList.idl
@@ -23,7 +23,7 @@
*/
interface DOMSettableTokenList : DOMTokenList {
- [TreatReturnedNullStringAs=Null, ImplementedAs=item] getter DOMString(unsigned long index);
+ [TreatReturnedNullStringAs=Null, ImplementedAs=item] getter DOMString (unsigned long index);
attribute DOMString value;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMStringList.h b/chromium/third_party/WebKit/Source/core/dom/DOMStringList.h
index 44de3447398..dd605cd3b56 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMStringList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMStringList.h
@@ -27,6 +27,7 @@
#define DOMStringList_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -36,11 +37,11 @@ namespace WebCore {
// FIXME: Some consumers of this class may benefit from lazily fetching items rather
// than creating the list statically as is currently the only option.
-class DOMStringList : public ScriptWrappable, public RefCounted<DOMStringList> {
+class DOMStringList FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMStringList>, public ScriptWrappable {
public:
- static PassRefPtr<DOMStringList> create()
+ static PassRefPtrWillBeRawPtr<DOMStringList> create()
{
- return adoptRef(new DOMStringList());
+ return adoptRefWillBeNoop(new DOMStringList());
}
bool isEmpty() const { return m_strings.isEmpty(); }
@@ -55,6 +56,8 @@ public:
operator const Vector<String>&() const { return m_strings; }
+ void trace(Visitor*) { }
+
private:
DOMStringList()
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl b/chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl
index 1c75bcb8d7c..8a570878796 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMStringList.idl
@@ -24,9 +24,9 @@
*/
[
+ WillBeGarbageCollected,
] interface DOMStringList {
readonly attribute unsigned long length;
[TreatReturnedNullStringAs=Null] getter DOMString item([Default=Undefined] optional unsigned long index);
- boolean contains([Default=Undefined] optional DOMString string);
+ [MeasureAs=DOMStringListContains] boolean contains([Default=Undefined] optional DOMString string);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h b/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h
index 22ce97497f1..83095794734 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.h
@@ -28,6 +28,8 @@
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptWrappable.h"
+#include "bindings/v8/V8Binding.h"
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
@@ -36,36 +38,31 @@ namespace WebCore {
class Element;
-class DOMStringMap : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(DOMStringMap); WTF_MAKE_FAST_ALLOCATED;
+class DOMStringMap : public NoBaseWillBeGarbageCollectedFinalized<DOMStringMap>, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(DOMStringMap);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
virtual ~DOMStringMap();
+#if !ENABLE(OILPAN)
virtual void ref() = 0;
virtual void deref() = 0;
+#endif
virtual void getNames(Vector<String>&) = 0;
virtual String item(const String& name) = 0;
virtual bool contains(const String& name) = 0;
virtual void setItem(const String& name, const String& value, ExceptionState&) = 0;
- virtual void deleteItem(const String& name, ExceptionState&) = 0;
+ virtual bool deleteItem(const String& name) = 0;
bool anonymousNamedSetter(const String& name, const String& value, ExceptionState& exceptionState)
{
setItem(name, value, exceptionState);
return true;
}
- bool anonymousNamedDeleter(const AtomicString& name, ExceptionState&)
+ DeleteResult anonymousNamedDeleter(const AtomicString& name)
{
- // FIXME: Remove ExceptionState parameter.
-
- TrackExceptionState exceptionState;
- deleteItem(name, exceptionState);
- bool result = !exceptionState.hadException();
- // DOMStringMap deleter should ignore exception.
- // Behavior of Firefox and Opera are same.
- // delete document.body.dataset["-foo"] // false instead of DOM Exception 12
- // LayoutTests/fast/dom/HTMLSelectElement/select-selectedIndex-multiple.html
- return result;
+ bool knownProperty = deleteItem(name);
+ return knownProperty ? DeleteSuccess : DeleteUnknownProperty;
}
void namedPropertyEnumerator(Vector<String>& names, ExceptionState&)
{
@@ -81,13 +78,15 @@ public:
{
return anonymousNamedSetter(String::number(index), value, exceptionState);
}
- bool anonymousIndexedDeleter(uint32_t index, ExceptionState& exceptionState)
+ DeleteResult anonymousIndexedDeleter(uint32_t index)
{
- return anonymousNamedDeleter(AtomicString::number(index), exceptionState);
+ return anonymousNamedDeleter(AtomicString::number(index));
}
virtual Element* element() = 0;
+ virtual void trace(Visitor*) { }
+
protected:
DOMStringMap()
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl b/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl
index fcbbf899d42..c8c7d15fc17 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMStringMap.idl
@@ -24,13 +24,15 @@
*/
[
- GenerateVisitDOMWrapper=element,
+ OverrideBuiltins,
+ SetWrapperReferenceFrom=element,
+ WillBeGarbageCollected,
] interface DOMStringMap {
- [ImplementedAs=anonymousIndexedGetter, NotEnumerable] getter DOMString (unsigned long index);
- [ImplementedAs=anonymousIndexedSetter, RaisesException, NotEnumerable] setter DOMString (unsigned long index, DOMString value);
- [ImplementedAs=anonymousIndexedDeleter, RaisesException, NotEnumerable] deleter boolean (unsigned long index);
- [ImplementedAs=item, OverrideBuiltins] getter DOMString (DOMString name);
- [ImplementedAs=anonymousNamedSetter, RaisesException, OverrideBuiltins] setter DOMString (DOMString name, DOMString value);
- [ImplementedAs=anonymousNamedDeleter, RaisesException] deleter boolean (DOMString name);
-};
+ [NotEnumerable] getter DOMString (unsigned long index);
+ [RaisesException] setter DOMString (unsigned long index, DOMString value);
+ deleter boolean (unsigned long index);
+ [ImplementedAs=item] getter DOMString (DOMString name);
+ [RaisesException] setter DOMString (DOMString name, DOMString value);
+ deleter boolean (DOMString name);
+};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
index 41255b2b170..d4aa1a50605 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.cpp
@@ -32,7 +32,7 @@
namespace WebCore {
-bool DOMTokenList::validateToken(const AtomicString& token, ExceptionState& exceptionState)
+bool DOMTokenList::validateToken(const String& token, ExceptionState& exceptionState)
{
if (token.isEmpty()) {
exceptionState.throwDOMException(SyntaxError, "The token provided must not be empty.");
@@ -74,6 +74,8 @@ void DOMTokenList::add(const AtomicString& token, ExceptionState& exceptionState
add(tokens, exceptionState);
}
+// Optimally, this should take a Vector<AtomicString> const ref in argument but the
+// bindings generator does not handle that.
void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionState)
{
Vector<String> filteredTokens;
@@ -81,7 +83,7 @@ void DOMTokenList::add(const Vector<String>& tokens, ExceptionState& exceptionSt
for (size_t i = 0; i < tokens.size(); ++i) {
if (!validateToken(tokens[i], exceptionState))
return;
- if (containsInternal(tokens[i]))
+ if (containsInternal(AtomicString(tokens[i])))
continue;
if (filteredTokens.contains(tokens[i]))
continue;
@@ -101,6 +103,8 @@ void DOMTokenList::remove(const AtomicString& token, ExceptionState& exceptionSt
remove(tokens, exceptionState);
}
+// Optimally, this should take a Vector<AtomicString> const ref in argument but the
+// bindings generator does not handle that.
void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptionState)
{
if (!validateTokens(tokens, exceptionState))
@@ -110,7 +114,7 @@ void DOMTokenList::remove(const Vector<String>& tokens, ExceptionState& exceptio
// through the string character by character.
bool found = false;
for (size_t i = 0; i < tokens.size(); ++i) {
- if (containsInternal(tokens[i])) {
+ if (containsInternal(AtomicString(tokens[i]))) {
found = true;
break;
}
@@ -161,14 +165,16 @@ void DOMTokenList::removeInternal(const AtomicString& token)
setValue(removeToken(value(), token));
}
-String DOMTokenList::addToken(const AtomicString& input, const AtomicString& token)
+AtomicString DOMTokenList::addToken(const AtomicString& input, const AtomicString& token)
{
Vector<String> tokens;
tokens.append(token.string());
return addTokens(input, tokens);
}
-String DOMTokenList::addTokens(const AtomicString& input, const Vector<String>& tokens)
+// This returns an AtomicString because it is always passed as argument to setValue() and setValue()
+// takes an AtomicString in argument.
+AtomicString DOMTokenList::addTokens(const AtomicString& input, const Vector<String>& tokens)
{
bool needsSpace = false;
@@ -185,17 +191,19 @@ String DOMTokenList::addTokens(const AtomicString& input, const Vector<String>&
needsSpace = true;
}
- return builder.toString();
+ return builder.toAtomicString();
}
-String DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token)
+AtomicString DOMTokenList::removeToken(const AtomicString& input, const AtomicString& token)
{
Vector<String> tokens;
tokens.append(token.string());
return removeTokens(input, tokens);
}
-String DOMTokenList::removeTokens(const AtomicString& input, const Vector<String>& tokens)
+// This returns an AtomicString because it is always passed as argument to setValue() and setValue()
+// takes an AtomicString in argument.
+AtomicString DOMTokenList::removeTokens(const AtomicString& input, const Vector<String>& tokens)
{
// Algorithm defined at http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#remove-a-token-from-a-string
// New spec is at http://dom.spec.whatwg.org/#remove-a-token-from-a-string
@@ -238,7 +246,7 @@ String DOMTokenList::removeTokens(const AtomicString& input, const Vector<String
}
}
- return output.toString();
+ return output.toAtomicString();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h
index d758214d09a..1ab1b7c2a5d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.h
@@ -26,6 +26,7 @@
#define DOMTokenList_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Vector.h"
#include "wtf/text/AtomicString.h"
@@ -34,17 +35,20 @@ namespace WebCore {
class Element;
class ExceptionState;
-class DOMTokenList : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(DOMTokenList); WTF_MAKE_FAST_ALLOCATED;
+class DOMTokenList : public NoBaseWillBeGarbageCollectedFinalized<DOMTokenList>, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(DOMTokenList);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
DOMTokenList()
{
ScriptWrappable::init(this);
}
- virtual ~DOMTokenList() { };
+ virtual ~DOMTokenList() { }
+#if !ENABLE(OILPAN)
virtual void ref() = 0;
virtual void deref() = 0;
+#endif
virtual unsigned length() const = 0;
virtual const AtomicString item(unsigned index) const = 0;
@@ -57,24 +61,26 @@ public:
bool toggle(const AtomicString&, ExceptionState&);
bool toggle(const AtomicString&, bool force, ExceptionState&);
- AtomicString toString() const { return value(); }
+ const AtomicString& toString() const { return value(); }
virtual Element* element() { return 0; }
+ virtual void trace(Visitor*) { }
+
protected:
- virtual AtomicString value() const = 0;
+ virtual const AtomicString& value() const = 0;
virtual void setValue(const AtomicString&) = 0;
virtual void addInternal(const AtomicString&);
virtual bool containsInternal(const AtomicString&) const = 0;
virtual void removeInternal(const AtomicString&);
- static bool validateToken(const AtomicString&, ExceptionState&);
+ static bool validateToken(const String&, ExceptionState&);
static bool validateTokens(const Vector<String>&, ExceptionState&);
- static String addToken(const AtomicString&, const AtomicString&);
- static String addTokens(const AtomicString&, const Vector<String>&);
- static String removeToken(const AtomicString&, const AtomicString&);
- static String removeTokens(const AtomicString&, const Vector<String>&);
+ static AtomicString addToken(const AtomicString&, const AtomicString&);
+ static AtomicString addTokens(const AtomicString&, const Vector<String>&);
+ static AtomicString removeToken(const AtomicString&, const AtomicString&);
+ static AtomicString removeTokens(const AtomicString&, const Vector<String>&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl
index 9830b7ec93d..98d51cff129 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMTokenList.idl
@@ -23,7 +23,8 @@
*/
[
- GenerateVisitDOMWrapper=element,
+ SetWrapperReferenceFrom=element,
+ WillBeGarbageCollected,
] interface DOMTokenList {
readonly attribute unsigned long length;
[TreatReturnedNullStringAs=Null] getter DOMString item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp
index 8881223f724..feba9b94942 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURL.cpp
@@ -63,20 +63,24 @@ void DOMURL::setInput(const String& value)
}
}
-String DOMURL::createObjectURL(ExecutionContext* executionContext, Blob* blob)
+String DOMURL::createObjectURL(ExecutionContext* executionContext, Blob* blob, ExceptionState& exceptionState)
{
if (!executionContext || !blob)
return String();
- return createPublicURL(executionContext, blob);
+ if (blob->hasBeenClosed()) {
+ exceptionState.throwDOMException(InvalidStateError, String(blob->isFile() ? "File" : "Blob") + " has been closed.");
+ return String();
+ }
+ return createPublicURL(executionContext, blob, blob->uuid());
}
-String DOMURL::createPublicURL(ExecutionContext* executionContext, URLRegistrable* registrable)
+String DOMURL::createPublicURL(ExecutionContext* executionContext, URLRegistrable* registrable, const String& uuid)
{
KURL publicURL = BlobURL::createPublicURL(executionContext->securityOrigin());
if (publicURL.isEmpty())
return String();
- executionContext->publicURLManager().registerURL(executionContext->securityOrigin(), publicURL, registrable);
+ executionContext->publicURLManager().registerURL(executionContext->securityOrigin(), publicURL, registrable, uuid);
return publicURL.string();
}
@@ -91,4 +95,12 @@ void DOMURL::revokeObjectURL(ExecutionContext* executionContext, const String& u
executionContext->publicURLManager().revoke(url);
}
+void DOMURL::revokeObjectUUID(ExecutionContext* executionContext, const String& uuid)
+{
+ if (!executionContext)
+ return;
+
+ executionContext->publicURLManager().revoke(uuid);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURL.h b/chromium/third_party/WebKit/Source/core/dom/DOMURL.h
index 2b112f7d966..534cae2d23e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURL.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURL.h
@@ -29,11 +29,9 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/DOMURLUtils.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -42,27 +40,27 @@ class ExceptionState;
class ExecutionContext;
class URLRegistrable;
-class DOMURL FINAL : public ScriptWrappable, public DOMURLUtils, public RefCounted<DOMURL> {
-
+class DOMURL FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMURL>, public ScriptWrappable, public DOMURLUtils {
public:
- static PassRefPtr<DOMURL> create(const String& url, ExceptionState& exceptionState)
+ static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, ExceptionState& exceptionState)
{
- return adoptRef(new DOMURL(url, blankURL(), exceptionState));
+ return adoptRefWillBeNoop(new DOMURL(url, blankURL(), exceptionState));
}
- static PassRefPtr<DOMURL> create(const String& url, const String& base, ExceptionState& exceptionState)
+ static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, const String& base, ExceptionState& exceptionState)
{
- return adoptRef(new DOMURL(url, KURL(KURL(), base), exceptionState));
+ return adoptRefWillBeNoop(new DOMURL(url, KURL(KURL(), base), exceptionState));
}
- static PassRefPtr<DOMURL> create(const String& url, PassRefPtr<DOMURL> base, ExceptionState& exceptionState)
+ static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, PassRefPtrWillBeRawPtr<DOMURL> base, ExceptionState& exceptionState)
{
ASSERT(base);
- return adoptRef(new DOMURL(url, base->m_url, exceptionState));
+ return adoptRefWillBeNoop(new DOMURL(url, base->m_url, exceptionState));
}
- static String createObjectURL(ExecutionContext*, Blob*);
+ static String createObjectURL(ExecutionContext*, Blob*, ExceptionState&);
static void revokeObjectURL(ExecutionContext*, const String&);
- static String createPublicURL(ExecutionContext*, URLRegistrable*);
+ static String createPublicURL(ExecutionContext*, URLRegistrable*, const String& uuid = String());
+ static void revokeObjectUUID(ExecutionContext*, const String&);
virtual KURL url() const OVERRIDE { return m_url; }
virtual void setURL(const KURL& url) OVERRIDE { m_url = url; }
@@ -70,6 +68,8 @@ public:
virtual String input() const OVERRIDE { return m_input; }
virtual void setInput(const String&) OVERRIDE;
+ void trace(Visitor*) { }
+
private:
DOMURL(const String& url, const KURL& base, ExceptionState&);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp
index 7e1fa195c5a..ead850c3511 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.cpp
@@ -31,55 +31,55 @@
namespace WebCore {
-void DOMURLUtils::setHref(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHref(const String& value)
{
- impl->setInput(value);
+ setInput(value);
}
-void DOMURLUtils::setProtocol(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setProtocol(const String& value)
{
- KURL url = impl->url();
- if (url.isNull())
+ KURL kurl = url();
+ if (kurl.isNull())
return;
- url.setProtocol(value);
- impl->setURL(url);
+ kurl.setProtocol(value);
+ setURL(kurl);
}
-void DOMURLUtils::setUsername(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setUsername(const String& value)
{
- KURL url = impl->url();
- if (url.isNull())
+ KURL kurl = url();
+ if (kurl.isNull())
return;
- url.setUser(value);
- impl->setURL(url);
+ kurl.setUser(value);
+ setURL(kurl);
}
-void DOMURLUtils::setPassword(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPassword(const String& value)
{
- KURL url = impl->url();
- if (url.isNull())
+ KURL kurl = url();
+ if (kurl.isNull())
return;
- url.setPass(value);
- impl->setURL(url);
+ kurl.setPass(value);
+ setURL(kurl);
}
-void DOMURLUtils::setHost(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHost(const String& value)
{
if (value.isEmpty())
return;
- KURL url = impl->url();
- if (!url.canSetHostOrPort())
+ KURL kurl = url();
+ if (!kurl.canSetHostOrPort())
return;
- url.setHostAndPort(value);
- impl->setURL(url);
+ kurl.setHostAndPort(value);
+ setURL(kurl);
}
-void DOMURLUtils::setHostname(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHostname(const String& value)
{
- KURL url = impl->url();
- if (!url.canSetHostOrPort())
+ KURL kurl = url();
+ if (!kurl.canSetHostOrPort())
return;
// Before setting new value:
@@ -92,51 +92,51 @@ void DOMURLUtils::setHostname(DOMURLUtils* impl, const String& value)
if (i == hostLength)
return;
- url.setHost(value.substring(i));
+ kurl.setHost(value.substring(i));
- impl->setURL(url);
+ setURL(kurl);
}
-void DOMURLUtils::setPort(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPort(const String& value)
{
- KURL url = impl->url();
- if (!url.canSetHostOrPort())
+ KURL kurl = url();
+ if (!kurl.canSetHostOrPort())
return;
- url.setPort(value);
- impl->setURL(url);
+ kurl.setPort(value);
+ setURL(kurl);
}
-void DOMURLUtils::setPathname(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPathname(const String& value)
{
- KURL url = impl->url();
- if (!url.canSetPathname())
+ KURL kurl = url();
+ if (!kurl.canSetPathname())
return;
- url.setPath(value);
- impl->setURL(url);
+ kurl.setPath(value);
+ setURL(kurl);
}
-void DOMURLUtils::setSearch(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setSearch(const String& value)
{
- KURL url = impl->url();
- if (!url.isValid())
+ KURL kurl = url();
+ if (!kurl.isValid())
return;
- url.setQuery(value);
- impl->setURL(url);
+ kurl.setQuery(value);
+ setURL(kurl);
}
-void DOMURLUtils::setHash(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHash(const String& value)
{
- KURL url = impl->url();
- if (url.isNull())
+ KURL kurl = url();
+ if (kurl.isNull())
return;
if (value[0] == '#')
- url.setFragmentIdentifier(value.substring(1));
+ kurl.setFragmentIdentifier(value.substring(1));
else
- url.setFragmentIdentifier(value);
+ kurl.setFragmentIdentifier(value);
- impl->setURL(url);
+ setURL(kurl);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h
index 1987ecd7205..945a4bc4590 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtils.h
@@ -29,7 +29,6 @@
#include "core/dom/DOMURLUtilsReadOnly.h"
#include "wtf/Forward.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -41,17 +40,17 @@ public:
virtual void setInput(const String&) = 0;
virtual ~DOMURLUtils() { };
- static void setHref(DOMURLUtils*, const String&);
-
- static void setProtocol(DOMURLUtils*, const String&);
- static void setUsername(DOMURLUtils*, const String&);
- static void setPassword(DOMURLUtils*, const String&);
- static void setHost(DOMURLUtils*, const String&);
- static void setHostname(DOMURLUtils*, const String&);
- static void setPort(DOMURLUtils*, const String&);
- static void setPathname(DOMURLUtils*, const String&);
- static void setSearch(DOMURLUtils*, const String&);
- static void setHash(DOMURLUtils*, const String&);
+ void setHref(const String&);
+
+ void setProtocol(const String&);
+ void setUsername(const String&);
+ void setPassword(const String&);
+ void setHost(const String&);
+ void setHostname(const String&);
+ void setPort(const String&);
+ void setPathname(const String&);
+ void setSearch(const String&);
+ void setHash(const String&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp
index 15b1268115a..368eae66207 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.cpp
@@ -32,47 +32,47 @@
namespace WebCore {
-String DOMURLUtilsReadOnly::href(DOMURLUtilsReadOnly* impl)
+String DOMURLUtilsReadOnly::href()
{
- const KURL& url = impl->url();
- if (url.isNull())
- return impl->input();
- return url.string();
+ const KURL& kurl = url();
+ if (kurl.isNull())
+ return input();
+ return kurl.string();
}
-String DOMURLUtilsReadOnly::origin(const KURL& url)
+String DOMURLUtilsReadOnly::origin(const KURL& kurl)
{
- if (url.isNull())
+ if (kurl.isNull())
return "";
- return SecurityOrigin::create(url)->toString();
+ return SecurityOrigin::create(kurl)->toString();
}
-String DOMURLUtilsReadOnly::host(const KURL& url)
+String DOMURLUtilsReadOnly::host(const KURL& kurl)
{
- if (url.hostEnd() == url.pathStart())
- return url.host();
- if (isDefaultPortForProtocol(url.port(), url.protocol()))
- return url.host();
- return url.host() + ":" + String::number(url.port());
+ if (kurl.hostEnd() == kurl.pathStart())
+ return kurl.host();
+ if (isDefaultPortForProtocol(kurl.port(), kurl.protocol()))
+ return kurl.host();
+ return kurl.host() + ":" + String::number(kurl.port());
}
-String DOMURLUtilsReadOnly::port(const KURL& url)
+String DOMURLUtilsReadOnly::port(const KURL& kurl)
{
- if (url.hasPort())
- return String::number(url.port());
+ if (kurl.hasPort())
+ return String::number(kurl.port());
return emptyString();
}
-String DOMURLUtilsReadOnly::search(const KURL& url)
+String DOMURLUtilsReadOnly::search(const KURL& kurl)
{
- String query = url.query();
+ String query = kurl.query();
return query.isEmpty() ? emptyString() : "?" + query;
}
-String DOMURLUtilsReadOnly::hash(const KURL& url)
+String DOMURLUtilsReadOnly::hash(const KURL& kurl)
{
- String fragmentIdentifier = url.fragmentIdentifier();
+ String fragmentIdentifier = kurl.fragmentIdentifier();
if (fragmentIdentifier.isEmpty())
return emptyString();
return AtomicString(String("#" + fragmentIdentifier));
diff --git a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h
index 36d60851e3e..33b92076c5a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DOMURLUtilsReadOnly.h
@@ -29,7 +29,6 @@
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -39,37 +38,37 @@ public:
virtual String input() const = 0;
virtual ~DOMURLUtilsReadOnly() { };
- static String href(DOMURLUtilsReadOnly*);
+ String href();
static String origin(const KURL&);
- static String origin(DOMURLUtilsReadOnly* impl) { return origin(impl->url()); }
+ String origin() { return origin(url()); }
static String protocol(const KURL& url) { return url.protocol() + ":"; }
- static String protocol(DOMURLUtilsReadOnly* impl) { return protocol(impl->url()); }
+ String protocol() { return protocol(url()); }
static String username(const KURL& url) { return url.user(); }
- static String username(DOMURLUtilsReadOnly* impl) { return username(impl->url()); }
+ String username() { return username(url()); }
static String password(const KURL& url) { return url.pass(); }
- static String password(DOMURLUtilsReadOnly* impl) { return password(impl->url()); }
+ String password() { return password(url()); }
static String host(const KURL&);
- static String host(DOMURLUtilsReadOnly* impl) { return host(impl->url()); }
+ String host() { return host(url()); }
static String hostname(const KURL& url) { return url.host(); }
- static String hostname(DOMURLUtilsReadOnly* impl) { return hostname(impl->url()); }
+ String hostname() { return hostname(url()); }
static String port(const KURL&);
- static String port(DOMURLUtilsReadOnly* impl) { return port(impl->url()); }
+ String port() { return port(url()); }
static String pathname(const KURL& url) { return url.path(); }
- static String pathname(DOMURLUtilsReadOnly* impl) { return pathname(impl->url()); }
+ String pathname() { return pathname(url()); }
static String search(const KURL&);
- static String search(DOMURLUtilsReadOnly* impl) { return search(impl->url()); }
+ String search() { return search(url()); }
static String hash(const KURL&);
- static String hash(DOMURLUtilsReadOnly* impl) { return hash(impl->url()); }
+ String hash() { return hash(url()); }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.cpp b/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.cpp
deleted file mode 100644
index aef76486648..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/DataTransferItem.h"
-
-#include "bindings/v8/V8Binding.h"
-#include "core/dom/Clipboard.h"
-#include "core/dom/StringCallback.h"
-#include "core/platform/chromium/ChromiumDataObjectItem.h"
-#include "wtf/StdLibExtras.h"
-
-namespace WebCore {
-
-PassRefPtr<DataTransferItem> DataTransferItem::create(PassRefPtr<Clipboard> clipboard, PassRefPtr<ChromiumDataObjectItem> item)
-{
- return adoptRef(new DataTransferItem(clipboard, item));
-}
-
-DataTransferItem::~DataTransferItem()
-{
-}
-
-String DataTransferItem::kind() const
-{
- DEFINE_STATIC_LOCAL(const String, kindString, ("string"));
- DEFINE_STATIC_LOCAL(const String, kindFile, ("file"));
- if (!m_clipboard->canReadTypes())
- return String();
- switch (m_item->kind()) {
- case ChromiumDataObjectItem::StringKind:
- return kindString;
- case ChromiumDataObjectItem::FileKind:
- return kindFile;
- }
- ASSERT_NOT_REACHED();
- return String();
-}
-
-String DataTransferItem::type() const
-{
- if (!m_clipboard->canReadTypes())
- return String();
- return m_item->type();
-}
-
-void DataTransferItem::getAsString(ExecutionContext* context, PassOwnPtr<StringCallback> callback) const
-{
- if (!m_clipboard->canReadData())
- return;
-
- m_item->getAsString(callback, context);
-}
-
-PassRefPtr<Blob> DataTransferItem::getAsFile() const
-{
- if (!m_clipboard->canReadData())
- return 0;
-
- return m_item->getAsFile();
-}
-
-DataTransferItem::DataTransferItem(PassRefPtr<Clipboard> clipboard, PassRefPtr<ChromiumDataObjectItem> item)
- : m_clipboard(clipboard)
- , m_item(item)
-{
- ScriptWrappable::init(this);
-}
-
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.h b/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.h
deleted file mode 100644
index b7e200cec9f..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DataTransferItem_h
-#define DataTransferItem_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/Forward.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class Blob;
-class ChromiumDataObjectItem;
-class Clipboard;
-class File;
-class StringCallback;
-class ExecutionContext;
-
-class DataTransferItem : public RefCounted<DataTransferItem>, public ScriptWrappable {
-public:
- static PassRefPtr<DataTransferItem> create(PassRefPtr<Clipboard>, PassRefPtr<ChromiumDataObjectItem>);
- ~DataTransferItem();
-
- String kind() const;
- String type() const;
-
- void getAsString(ExecutionContext*, PassOwnPtr<StringCallback>) const;
- PassRefPtr<Blob> getAsFile() const;
-
- Clipboard* clipboard() { return m_clipboard.get(); }
- ChromiumDataObjectItem* dataObjectItem() { return m_item.get(); }
-
-private:
- DataTransferItem(PassRefPtr<Clipboard>, PassRefPtr<ChromiumDataObjectItem>);
-
- RefPtr<Clipboard> m_clipboard;
- RefPtr<ChromiumDataObjectItem> m_item;
-};
-
-} // namespace WebCore
-
-#endif // DataTransferItem_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.idl b/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.idl
deleted file mode 100644
index 849965218fc..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItem.idl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject
-] interface DataTransferItem {
- readonly attribute DOMString kind;
- readonly attribute DOMString type;
-
- [CallWith=ExecutionContext] void getAsString(StringCallback? callback);
- Blob getAsFile();
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.cpp b/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.cpp
deleted file mode 100644
index 8facacb9096..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/DataTransferItemList.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/Clipboard.h"
-#include "core/dom/DataTransferItem.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
-
-namespace WebCore {
-
-PassRefPtr<DataTransferItemList> DataTransferItemList::create(PassRefPtr<Clipboard> clipboard, PassRefPtr<ChromiumDataObject> list)
-{
- return adoptRef(new DataTransferItemList(clipboard, list));
-}
-
-DataTransferItemList::~DataTransferItemList()
-{
-}
-
-size_t DataTransferItemList::length() const
-{
- if (!m_clipboard->canReadTypes())
- return 0;
- return m_dataObject->length();
-}
-
-PassRefPtr<DataTransferItem> DataTransferItemList::item(unsigned long index)
-{
- if (!m_clipboard->canReadTypes())
- return 0;
- RefPtr<ChromiumDataObjectItem> item = m_dataObject->item(index);
- if (!item)
- return 0;
-
- return DataTransferItem::create(m_clipboard, item);
-}
-
-void DataTransferItemList::deleteItem(unsigned long index, ExceptionState& exceptionState)
-{
- if (!m_clipboard->canWriteData()) {
- exceptionState.throwDOMException(InvalidStateError, "The list is not writable.");
- return;
- }
- m_dataObject->deleteItem(index);
-}
-
-void DataTransferItemList::clear()
-{
- if (!m_clipboard->canWriteData())
- return;
- m_dataObject->clearAll();
-}
-
-PassRefPtr<DataTransferItem> DataTransferItemList::add(const String& data, const String& type, ExceptionState& exceptionState)
-{
- if (!m_clipboard->canWriteData())
- return 0;
- RefPtr<ChromiumDataObjectItem> item = m_dataObject->add(data, type);
- if (!item) {
- exceptionState.throwDOMException(NotSupportedError, "An item already exists for type '" + type + "'.");
- return 0;
- }
- return DataTransferItem::create(m_clipboard, item);
-}
-
-PassRefPtr<DataTransferItem> DataTransferItemList::add(PassRefPtr<File> file)
-{
- if (!m_clipboard->canWriteData())
- return 0;
- RefPtr<ChromiumDataObjectItem> item = m_dataObject->add(file);
- if (!item)
- return 0;
- return DataTransferItem::create(m_clipboard, item);
-}
-
-DataTransferItemList::DataTransferItemList(PassRefPtr<Clipboard> clipboard, PassRefPtr<ChromiumDataObject> dataObject)
- : m_clipboard(clipboard)
- , m_dataObject(dataObject)
-{
- ScriptWrappable::init(this);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.h b/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.h
deleted file mode 100644
index f296c7b001a..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DataTransferItemList_h
-#define DataTransferItemList_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/Forward.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class ChromiumDataObject;
-class Clipboard;
-class DataTransferItem;
-class File;
-
-class ExceptionState;
-
-class DataTransferItemList : public RefCounted<DataTransferItemList>, public ScriptWrappable {
-public:
- static PassRefPtr<DataTransferItemList> create(PassRefPtr<Clipboard>, PassRefPtr<ChromiumDataObject>);
- ~DataTransferItemList();
-
- size_t length() const;
- PassRefPtr<DataTransferItem> item(unsigned long index);
- void deleteItem(unsigned long index, ExceptionState&);
- void clear();
- PassRefPtr<DataTransferItem> add(const String& data, const String& type, ExceptionState&);
- PassRefPtr<DataTransferItem> add(PassRefPtr<File>);
-
-private:
- DataTransferItemList(PassRefPtr<Clipboard>, PassRefPtr<ChromiumDataObject>);
-
- RefPtr<Clipboard> m_clipboard;
- RefPtr<ChromiumDataObject> m_dataObject;
-};
-
-} // namespace WebCore
-
-#endif // DataTransferItemList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.idl b/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.idl
deleted file mode 100644
index 0babe031c24..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DataTransferItemList.idl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-interface DataTransferItemList {
- readonly attribute long length;
- [ImplementedAs=item] getter DataTransferItem (unsigned long index);
-
- [RaisesException, ImplementedAs=deleteItem] void remove(unsigned long index);
- void clear();
- DataTransferItem add(File? file);
- [RaisesException] DataTransferItem add(DOMString data, DOMString type);
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp b/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp
index 921531948ca..7db1bf2b2c4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "core/dom/DatasetDOMStringMap.h"
-#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "core/dom/Attribute.h"
#include "core/dom/Element.h"
@@ -71,14 +70,9 @@ static String convertAttributeNameToPropertyName(const String& name)
return stringBuilder.toString();
}
-static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
+template<typename CharType1, typename CharType2>
+static bool propertyNameMatchesAttributeName(const CharType1* propertyName, const CharType2* attributeName, unsigned propertyLength, unsigned attributeLength)
{
- if (!attributeName.startsWith("data-"))
- return false;
-
- unsigned propertyLength = propertyName.length();
- unsigned attributeLength = attributeName.length();
-
unsigned a = 5;
unsigned p = 0;
bool wordBoundary = false;
@@ -97,6 +91,25 @@ static bool propertyNameMatchesAttributeName(const String& propertyName, const S
return (a == attributeLength && p == propertyLength);
}
+static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
+{
+ if (!attributeName.startsWith("data-"))
+ return false;
+
+ unsigned propertyLength = propertyName.length();
+ unsigned attributeLength = attributeName.length();
+
+ if (propertyName.is8Bit()) {
+ if (attributeName.is8Bit())
+ return propertyNameMatchesAttributeName(propertyName.characters8(), attributeName.characters8(), propertyLength, attributeLength);
+ return propertyNameMatchesAttributeName(propertyName.characters8(), attributeName.characters16(), propertyLength, attributeLength);
+ }
+
+ if (attributeName.is8Bit())
+ return propertyNameMatchesAttributeName(propertyName.characters16(), attributeName.characters8(), propertyLength, attributeLength);
+ return propertyNameMatchesAttributeName(propertyName.characters16(), attributeName.characters16(), propertyLength, attributeLength);
+}
+
static bool isValidPropertyName(const String& name)
{
unsigned length = name.length();
@@ -107,7 +120,9 @@ static bool isValidPropertyName(const String& name)
return true;
}
-static String convertPropertyNameToAttributeName(const String& name)
+// This returns an AtomicString because attribute names are always stored
+// as AtomicString types in Element (see setAttribute()).
+static AtomicString convertPropertyNameToAttributeName(const String& name)
{
StringBuilder builder;
builder.append("data-");
@@ -122,9 +137,10 @@ static String convertPropertyNameToAttributeName(const String& name)
builder.append(character);
}
- return builder.toString();
+ return builder.toAtomicString();
}
+#if !ENABLE(OILPAN)
void DatasetDOMStringMap::ref()
{
m_element->ref();
@@ -134,17 +150,18 @@ void DatasetDOMStringMap::deref()
{
m_element->deref();
}
+#endif
void DatasetDOMStringMap::getNames(Vector<String>& names)
{
if (!m_element->hasAttributes())
return;
- unsigned length = m_element->attributeCount();
- for (unsigned i = 0; i < length; i++) {
- const Attribute* attribute = m_element->attributeItem(i);
- if (isValidAttributeName(attribute->localName()))
- names.append(convertAttributeNameToPropertyName(attribute->localName()));
+ AttributeCollection attributes = m_element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (isValidAttributeName(it->localName()))
+ names.append(convertAttributeNameToPropertyName(it->localName()));
}
}
@@ -153,11 +170,11 @@ String DatasetDOMStringMap::item(const String& name)
if (!m_element->hasAttributes())
return String();
- unsigned length = m_element->attributeCount();
- for (unsigned i = 0; i < length; i++) {
- const Attribute* attribute = m_element->attributeItem(i);
- if (propertyNameMatchesAttributeName(name, attribute->localName()))
- return attribute->value();
+ AttributeCollection attributes = m_element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (propertyNameMatchesAttributeName(name, it->localName()))
+ return it->value();
}
return String();
@@ -168,34 +185,41 @@ bool DatasetDOMStringMap::contains(const String& name)
if (!m_element->hasAttributes())
return false;
- unsigned length = m_element->attributeCount();
- for (unsigned i = 0; i < length; i++) {
- const Attribute* attribute = m_element->attributeItem(i);
- if (propertyNameMatchesAttributeName(name, attribute->localName()))
+ AttributeCollection attributes = m_element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (propertyNameMatchesAttributeName(name, it->localName()))
return true;
}
-
return false;
}
void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionState& exceptionState)
{
if (!isValidPropertyName(name)) {
- exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet(name, "DOMStringMap", "'" + name + "' is not a valid property name."));
+ exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a valid property name.");
return;
}
- m_element->setAttribute(convertPropertyNameToAttributeName(name), value, exceptionState);
+ m_element->setAttribute(convertPropertyNameToAttributeName(name), AtomicString(value), exceptionState);
}
-void DatasetDOMStringMap::deleteItem(const String& name, ExceptionState& exceptionState)
+bool DatasetDOMStringMap::deleteItem(const String& name)
{
- if (!isValidPropertyName(name)) {
- exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToDelete(name, "DOMStringMap", "'" + name + "' is not a valid property name."));
- return;
+ if (isValidPropertyName(name)) {
+ AtomicString attributeName = convertPropertyNameToAttributeName(name);
+ if (m_element->hasAttribute(attributeName)) {
+ m_element->removeAttribute(attributeName);
+ return true;
+ }
}
+ return false;
+}
- m_element->removeAttribute(convertPropertyNameToAttributeName(name));
+void DatasetDOMStringMap::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ DOMStringMap::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h b/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h
index 9bbd1d09abc..dc31f536ce8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DatasetDOMStringMap.h
@@ -34,23 +34,27 @@ namespace WebCore {
class Element;
class ExceptionState;
-class DatasetDOMStringMap : public DOMStringMap {
+class DatasetDOMStringMap FINAL : public DOMStringMap {
public:
- static PassOwnPtr<DatasetDOMStringMap> create(Element* element)
+ static PassOwnPtrWillBeRawPtr<DatasetDOMStringMap> create(Element* element)
{
- return adoptPtr(new DatasetDOMStringMap(element));
+ return adoptPtrWillBeNoop(new DatasetDOMStringMap(element));
}
- virtual void ref();
- virtual void deref();
+#if !ENABLE(OILPAN)
+ virtual void ref() OVERRIDE;
+ virtual void deref() OVERRIDE;
+#endif
- virtual void getNames(Vector<String>&);
- virtual String item(const String& name);
- virtual bool contains(const String& name);
- virtual void setItem(const String& name, const String& value, ExceptionState&);
- virtual void deleteItem(const String& name, ExceptionState&);
+ virtual void getNames(Vector<String>&) OVERRIDE;
+ virtual String item(const String& name) OVERRIDE;
+ virtual bool contains(const String& name) OVERRIDE;
+ virtual void setItem(const String& name, const String& value, ExceptionState&) OVERRIDE;
+ virtual bool deleteItem(const String& name) OVERRIDE;
- virtual Element* element() { return m_element; }
+ virtual Element* element() OVERRIDE { return m_element; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit DatasetDOMStringMap(Element* element)
@@ -58,7 +62,7 @@ private:
{
}
- Element* m_element;
+ RawPtrWillBeMember<Element> m_element;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp
index 7f3c01f23d8..06d32a47d17 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.cpp
@@ -28,13 +28,13 @@
#include "core/dom/Document.h"
#include "core/dom/DocumentEncodingData.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
namespace WebCore {
-DecodedDataDocumentParser::DecodedDataDocumentParser(Document* document)
- : DocumentParser(document)
- , m_hasAppendedData(false)
+DecodedDataDocumentParser::DecodedDataDocumentParser(Document& document)
+ : DocumentParser(&document)
+ , m_needsDecoder(true)
{
}
@@ -44,6 +44,10 @@ DecodedDataDocumentParser::~DecodedDataDocumentParser()
void DecodedDataDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
{
+ // If the decoder is explicitly unset rather than having ownership
+ // transferred away by takeDecoder(), we need to make sure it's recreated
+ // next time data is appended.
+ m_needsDecoder = !decoder;
m_decoder = decoder;
}
@@ -52,9 +56,9 @@ TextResourceDecoder* DecodedDataDocumentParser::decoder()
return m_decoder.get();
}
-void DecodedDataDocumentParser::setHasAppendedData()
+PassOwnPtr<TextResourceDecoder> DecodedDataDocumentParser::takeDecoder()
{
- m_hasAppendedData = true;
+ return m_decoder.release();
}
void DecodedDataDocumentParser::appendBytes(const char* data, size_t length)
@@ -91,22 +95,10 @@ void DecodedDataDocumentParser::flush()
void DecodedDataDocumentParser::updateDocument(String& decodedData)
{
- DocumentEncodingData encodingData;
- encodingData.encoding = m_decoder->encoding();
- encodingData.wasDetectedHeuristically = m_decoder->encodingWasDetectedHeuristically();
- encodingData.sawDecodingError = m_decoder->sawError();
- document()->setEncodingData(encodingData);
+ document()->setEncodingData(DocumentEncodingData(*m_decoder.get()));
- if (decodedData.isEmpty())
- return;
-
- append(decodedData.releaseImpl());
- // FIXME: Should be removed as part of https://code.google.com/p/chromium/issues/detail?id=319643
- if (!m_hasAppendedData) {
- m_hasAppendedData = true;
- if (m_decoder->encoding().usesVisualOrdering())
- document()->setVisuallyOrdered();
- }
+ if (!decodedData.isEmpty())
+ append(decodedData.releaseImpl());
}
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h b/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h
index 453147d0ecd..a557399fbd4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DecodedDataDocumentParser.h
@@ -28,7 +28,6 @@
#include "core/dom/DocumentParser.h"
#include "wtf/OwnPtr.h"
-#include "wtf/RefPtr.h"
namespace WebCore {
class TextResourceDecoder;
@@ -42,13 +41,14 @@ public:
// The below functions are used by DocumentWriter (the loader).
virtual void appendBytes(const char* bytes, size_t length) OVERRIDE;
virtual void flush() OVERRIDE;
- virtual bool needsDecoder() const OVERRIDE { return !m_decoder; }
+ virtual bool needsDecoder() const OVERRIDE FINAL { return m_needsDecoder; }
virtual void setDecoder(PassOwnPtr<TextResourceDecoder>) OVERRIDE;
- virtual TextResourceDecoder* decoder() OVERRIDE;
- virtual void setHasAppendedData() OVERRIDE;
+ virtual TextResourceDecoder* decoder() OVERRIDE FINAL;
+
+ PassOwnPtr<TextResourceDecoder> takeDecoder();
protected:
- explicit DecodedDataDocumentParser(Document*);
+ explicit DecodedDataDocumentParser(Document&);
virtual ~DecodedDataDocumentParser();
private:
@@ -57,7 +57,7 @@ private:
void updateDocument(String& decodedData);
- bool m_hasAppendedData;
+ bool m_needsDecoder;
OwnPtr<TextResourceDecoder> m_decoder;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Document.cpp b/chromium/third_party/WebKit/Source/core/dom/Document.cpp
index d1b53da3212..fe9c3b06248 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Document.cpp
@@ -28,25 +28,21 @@
#include "config.h"
#include "core/dom/Document.h"
-#include "HTMLElementFactory.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGElementFactory.h"
-#include "SVGNames.h"
-#include "XMLNSNames.h"
-#include "XMLNames.h"
#include "bindings/v8/CustomElementConstructorBuilder.h"
#include "bindings/v8/Dictionary.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptController.h"
+#include "core/HTMLElementFactory.h"
+#include "core/HTMLNames.h"
+#include "core/SVGElementFactory.h"
+#include "core/SVGNames.h"
+#include "core/XMLNSNames.h"
+#include "core/XMLNames.h"
#include "core/accessibility/AXObjectCache.h"
-#include "core/animation/AnimationClock.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/animation/DocumentAnimations.h"
-#include "core/animation/DocumentTimeline.h"
-#include "core/animation/css/TransitionTimeline.h"
-#include "core/css/CSSDefaultStyleSheets.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSStyleDeclaration.h"
#include "core/css/CSSStyleSheet.h"
@@ -54,6 +50,8 @@
#include "core/css/StylePropertySet.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/StyleSheetList.h"
+#include "core/css/invalidation/StyleInvalidator.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/FontBuilder.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/css/resolver/StyleResolverStats.h"
@@ -63,19 +61,19 @@
#include "core/dom/Comment.h"
#include "core/dom/ContextFeatures.h"
#include "core/dom/DOMImplementation.h"
-#include "core/dom/DOMNamedFlowCollection.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentLifecycleNotifier.h"
#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/DocumentMarkerController.h"
-#include "core/dom/DocumentSharedObjectPool.h"
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
+#include "core/dom/ElementDataCache.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContextTask.h"
#include "core/dom/MainThreadTaskRunner.h"
-#include "core/dom/NamedFlowCollection.h"
+#include "core/dom/MutationObserver.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeChildRemovalTracker.h"
#include "core/dom/NodeFilter.h"
#include "core/dom/NodeIterator.h"
@@ -84,9 +82,9 @@
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/NodeWithIndex.h"
-#include "core/dom/PostAttachCallbacks.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/RequestAnimationFrameCallback.h"
+#include "core/dom/ScriptForbiddenScope.h"
#include "core/dom/ScriptRunner.h"
#include "core/dom/ScriptedAnimationController.h"
#include "core/dom/SelectorQuery.h"
@@ -95,6 +93,7 @@
#include "core/dom/TransformSource.h"
#include "core/dom/TreeWalker.h"
#include "core/dom/VisitedLinkState.h"
+#include "core/dom/XMLDocument.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
@@ -108,18 +107,19 @@
#include "core/events/HashChangeEvent.h"
#include "core/events/PageTransitionEvent.h"
#include "core/events/ScopedEventQueue.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
#include "core/frame/History.h"
-#include "core/frame/animation/AnimationController.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/DocumentNameCollection.h"
#include "core/html/HTMLAllCollection.h"
#include "core/html/HTMLAnchorElement.h"
+#include "core/html/HTMLBaseElement.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDialogElement.h"
@@ -128,20 +128,28 @@
#include "core/html/HTMLHeadElement.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLImport.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLLinkElement.h"
-#include "core/html/HTMLNameCollection.h"
+#include "core/html/HTMLMetaElement.h"
#include "core/html/HTMLScriptElement.h"
#include "core/html/HTMLStyleElement.h"
+#include "core/html/HTMLTemplateElement.h"
#include "core/html/HTMLTitleElement.h"
#include "core/html/PluginDocument.h"
+#include "core/html/WindowNameCollection.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+#include "core/html/canvas/CanvasRenderingContext2D.h"
+#include "core/html/canvas/WebGLRenderingContext.h"
#include "core/html/forms/FormController.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportsController.h"
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/NestingLevelIncrementer.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorCounters.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/inspector/ScriptCallStack.h"
#include "core/loader/CookieJar.h"
#include "core/loader/DocumentLoader.h"
@@ -152,26 +160,28 @@
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
#include "core/page/EventHandler.h"
+#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
#include "core/page/MouseEventWithHitTestResults.h"
#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
#include "core/page/PointerLockController.h"
-#include "core/frame/Settings.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderView.h"
-#include "core/rendering/RenderWidget.h"
#include "core/rendering/TextAutosizer.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGFontFaceElement.h"
-#include "core/svg/SVGStyleElement.h"
+#include "core/svg/SVGUseElement.h"
+#include "core/workers/SharedWorkerRepositoryClient.h"
#include "core/xml/XSLTProcessor.h"
#include "core/xml/parser/XMLDocumentParser.h"
#include "platform/DateComponents.h"
#include "platform/Language.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
#include "platform/network/HTTPParsers.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "platform/text/PlatformLocale.h"
@@ -179,6 +189,7 @@
#include "platform/weborigin/OriginAccessEntry.h"
#include "platform/weborigin/SchemeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/Platform.h"
#include "wtf/CurrentTime.h"
#include "wtf/HashFunctions.h"
#include "wtf/MainThread.h"
@@ -187,7 +198,6 @@
#include "wtf/text/StringBuffer.h"
#include "wtf/text/TextEncodingRegistry.h"
-using namespace std;
using namespace WTF;
using namespace Unicode;
@@ -285,7 +295,7 @@ static bool shouldInheritSecurityOriginFromOwner(const KURL& url)
// Note: We generalize this to all "blank" URLs and invalid URLs because we
// treat all of these URLs as about:blank.
//
- return url.isEmpty() || url.isBlankURL();
+ return url.isEmpty() || url.protocolIsAbout();
}
static Widget* widgetForElement(const Element& focusedElement)
@@ -303,7 +313,7 @@ static bool acceptsEditingFocus(const Element& element)
return element.document().frame() && element.rootEditableElement();
}
-static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame* targetFrame)
+static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, const Frame* targetFrame)
{
// targetFrame can be 0 when we're trying to navigate a top-level frame
// that has a 0 opener.
@@ -311,8 +321,13 @@ static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame*
return false;
const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal();
- for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
- Document* ancestorDocument = ancestorFrame->document();
+ for (const Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
+ // FIXME: SecurityOrigins need to be refactored to work with out-of-process iframes.
+ // For now we prevent navigation between cross-process frames.
+ if (!ancestorFrame->isLocalFrame())
+ return false;
+
+ Document* ancestorDocument = toLocalFrame(ancestorFrame)->document();
// FIXME: Should be an ASSERT? Frames should alway have documents.
if (!ancestorDocument)
return true;
@@ -331,7 +346,7 @@ static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame*
return false;
}
-static void printNavigationErrorMessage(const Frame& frame, const KURL& activeURL, const char* reason)
+static void printNavigationErrorMessage(const LocalFrame& frame, const KURL& activeURL, const char* reason)
{
String message = "Unsafe JavaScript attempt to initiate navigation for frame with URL '" + frame.document()->url().string() + "' from frame with URL '" + activeURL.string() + "'. " + reason + "\n";
@@ -341,46 +356,76 @@ static void printNavigationErrorMessage(const Frame& frame, const KURL& activeUR
uint64_t Document::s_globalTreeVersion = 0;
-// This class should be passed only to Document::postTask.
-class CheckFocusedElementTask FINAL : public ExecutionContextTask {
+// This class doesn't work with non-Document ExecutionContext.
+class AutofocusTask FINAL : public ExecutionContextTask {
public:
- static PassOwnPtr<CheckFocusedElementTask> create()
+ static PassOwnPtr<AutofocusTask> create()
{
- return adoptPtr(new CheckFocusedElementTask());
+ return adoptPtr(new AutofocusTask());
}
- virtual ~CheckFocusedElementTask() { }
+ virtual ~AutofocusTask() { }
private:
- CheckFocusedElementTask() { }
+ AutofocusTask() { }
virtual void performTask(ExecutionContext* context) OVERRIDE
{
- ASSERT(context->isDocument());
Document* document = toDocument(context);
- document->didRunCheckFocusedElementTask();
- Element* element = document->focusedElement();
- if (!element)
- return;
- if (document->childNeedsStyleRecalc()) {
- document->setNeedsFocusedElementCheck();
- return;
+ if (RefPtrWillBeRawPtr<Element> element = document->autofocusElement()) {
+ document->setAutofocusElement(0);
+ element->focus();
}
- if (element->renderer() && element->renderer()->needsLayout())
- return;
- if (!element->isFocusable())
- document->setFocusedElement(0);
}
};
+DocumentVisibilityObserver::DocumentVisibilityObserver(Document& document)
+ : m_document(nullptr)
+{
+ registerObserver(document);
+}
+
+DocumentVisibilityObserver::~DocumentVisibilityObserver()
+{
+#if !ENABLE(OILPAN)
+ unregisterObserver();
+#endif
+}
+
+void DocumentVisibilityObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+}
+
+void DocumentVisibilityObserver::unregisterObserver()
+{
+ if (m_document) {
+ m_document->unregisterVisibilityObserver(this);
+ m_document = nullptr;
+ }
+}
+
+void DocumentVisibilityObserver::registerObserver(Document& document)
+{
+ ASSERT(!m_document);
+ m_document = &document;
+ if (m_document)
+ m_document->registerVisibilityObserver(this);
+}
+
+void DocumentVisibilityObserver::setObservedDocument(Document& document)
+{
+ unregisterObserver();
+ registerObserver(document);
+}
+
Document::Document(const DocumentInit& initializer, DocumentClassFlags documentClasses)
: ContainerNode(0, CreateDocument)
- , TreeScope(this)
+ , TreeScope(*this)
, m_hasNodesWithPlaceholderStyle(false)
- , m_needsNotifyRemoveAllPendingStylesheet(false)
, m_evaluateMediaQueriesOnStyleRecalc(false)
, m_pendingSheetLayout(NoLayoutWithPendingSheets)
, m_frame(initializer.frame())
, m_domWindow(m_frame ? m_frame->domWindow() : 0)
- , m_import(initializer.import())
+ , m_importsController(initializer.importsController())
, m_activeParserCount(0)
, m_contextFeatures(ContextFeatures::defaultSwitch())
, m_wellFormed(false)
@@ -388,28 +433,27 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
, m_paginatedForScreen(false)
, m_compatibilityMode(NoQuirksMode)
, m_compatibilityModeLocked(false)
- , m_didPostCheckFocusedElementTask(false)
+ , m_executeScriptsWaitingForResourcesTimer(this, &Document::executeScriptsWaitingForResourcesTimerFired)
+ , m_hasAutofocused(false)
+ , m_clearFocusedElementTimer(this, &Document::clearFocusedElementTimerFired)
, m_domTreeVersion(++s_globalTreeVersion)
, m_listenerTypes(0)
, m_mutationObserverTypes(0)
, m_visitedLinkState(VisitedLinkState::create(*this))
, m_visuallyOrdered(false)
, m_readyState(Complete)
- , m_bParsing(false)
- , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
- , m_inStyleRecalc(false)
+ , m_isParsing(false)
, m_gotoAnchorNeededAfterStylesheetsLoad(false)
, m_containsValidityStyleRules(false)
, m_updateFocusAppearanceRestoresSelection(false)
, m_containsPlugins(false)
, m_ignoreDestructiveWriteCount(0)
, m_titleSetExplicitly(false)
- , m_markers(adoptPtr(new DocumentMarkerController))
+ , m_markers(adoptPtrWillBeNoop(new DocumentMarkerController))
, m_updateFocusAppearanceTimer(this, &Document::updateFocusAppearanceTimerFired)
- , m_cssTarget(0)
+ , m_cssTarget(nullptr)
, m_loadEventProgress(LoadEventNotRun)
, m_startTime(currentTime())
- , m_overMinimumLayoutThreshold(false)
, m_scriptRunner(ScriptRunner::create(this))
, m_xmlVersion("1.0")
, m_xmlStandalone(StandaloneUnspecified)
@@ -423,39 +467,42 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
, m_sawElementsInKnownNamespaces(false)
, m_isSrcdocDocument(false)
, m_isMobileDocument(false)
- , m_mayDisplaySeamlesslyWithParent(false)
+ , m_isTransitionDocument(false)
, m_renderView(0)
+#if !ENABLE(OILPAN)
, m_weakFactory(this)
+#endif
, m_contextDocument(initializer.contextDocument())
- , m_idAttributeName(idAttr)
, m_hasFullscreenElementStack(false)
, m_loadEventDelayCount(0)
, m_loadEventDelayTimer(this, &Document::loadEventDelayTimerFired)
+ , m_pluginLoadingTimer(this, &Document::pluginLoadingTimerFired)
+ , m_didSetReferrerPolicy(false)
, m_referrerPolicy(ReferrerPolicyDefault)
, m_directionSetOnDocumentElement(false)
, m_writingModeSetOnDocumentElement(false)
, m_writeRecursionIsTooDeep(false)
, m_writeRecursionDepth(0)
- , m_lastHandledUserGestureTimestamp(0)
, m_taskRunner(MainThreadTaskRunner::create(this))
, m_registrationContext(initializer.registrationContext(this))
- , m_sharedObjectPoolClearTimer(this, &Document::sharedObjectPoolClearTimerFired)
+ , m_elementDataCacheClearTimer(this, &Document::elementDataCacheClearTimerFired)
#ifndef NDEBUG
, m_didDispatchViewportPropertiesChanged(false)
#endif
- , m_animationClock(AnimationClock::create())
- , m_timeline(DocumentTimeline::create(this))
- , m_transitionTimeline(TransitionTimeline::create(this))
- , m_templateDocumentHost(0)
+ , m_timeline(AnimationTimeline::create(this))
+ , m_templateDocumentHost(nullptr)
, m_didAssociateFormControlsTimer(this, &Document::didAssociateFormControlsTimerFired)
+ , m_hasViewportUnits(false)
+ , m_styleRecalcElementCounter(0)
{
setClient(this);
ScriptWrappable::init(this);
if (m_frame) {
- provideContextFeaturesToDocumentFrom(this, m_frame->page());
+ ASSERT(m_frame->page());
+ provideContextFeaturesToDocumentFrom(*this, *m_frame->page());
- m_fetcher = m_frame->loader().activeDocumentLoader()->fetcher();
+ m_fetcher = m_frame->loader().documentLoader()->fetcher();
}
if (!m_fetcher)
@@ -473,12 +520,14 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
initSecurityContext(initializer);
initDNSPrefetch();
- for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
+#if !ENABLE(OILPAN)
+ for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); ++i)
m_nodeListCounts[i] = 0;
+#endif
InspectorCounters::incrementCounter(InspectorCounters::DocumentCounter);
- m_lifecyle.advanceTo(DocumentLifecycle::Inactive);
+ m_lifecycle.advanceTo(DocumentLifecycle::Inactive);
// Since CSSFontSelector requires Document::m_fetcher and StyleEngine owns
// CSSFontSelector, need to initialize m_styleEngine after initializing
@@ -489,19 +538,26 @@ Document::Document(const DocumentInit& initializer, DocumentClassFlags documentC
Document::~Document()
{
ASSERT(!renderView());
+ ASSERT(!parentTreeScope());
+#if !ENABLE(OILPAN)
ASSERT(m_ranges.isEmpty());
- ASSERT(!m_parentTreeScope);
ASSERT(!hasGuardRefCount());
+ // With Oilpan, either the document outlives the visibility observers
+ // or the visibility observers and the document die in the same GC round.
+ // When they die in the same GC round, the list of visibility observers
+ // will not be empty on Document destruction.
+ ASSERT(m_visibilityObservers.isEmpty());
if (m_templateDocument)
- m_templateDocument->setTemplateDocumentHost(0); // balanced in templateDocument().
-
- if (Document* ownerDocument = this->ownerDocument())
- ownerDocument->didRemoveEventTargetNode(this);
+ m_templateDocument->m_templateDocumentHost = nullptr; // balanced in ensureTemplateDocument().
m_scriptRunner.clear();
- removeAllEventListeners();
+ // FIXME: Oilpan: Not removing event listeners here also means that we do
+ // not notify the inspector instrumentation that the event listeners are
+ // gone. The Document and all the nodes in the document are gone, so maybe
+ // that is OK?
+ removeAllEventListenersRecursively();
// Currently we believe that Document can never outlive the parser.
// Although the Document may be replaced synchronously, DocumentParsers
@@ -511,19 +567,25 @@ Document::~Document()
// if the DocumentParser outlives the Document it won't cause badness.
ASSERT(!m_parser || m_parser->refCount() == 1);
detachParser();
+#endif
if (this == topDocument())
clearAXObjectCache();
+#if !ENABLE(OILPAN)
if (m_styleSheetList)
m_styleSheetList->detachFromDocument();
- if (m_import) {
- m_import->wasDetachedFromDocument();
- m_import = 0;
+ if (m_importsController) {
+ m_importsController->wasDetachedFrom(*this);
+ m_importsController = nullptr;
}
- m_styleEngine.clear(); // We need to destory CSSFontSelector before destroying m_fetcher.
+ m_timeline->detachFromDocument();
+
+ // We need to destroy CSSFontSelector before destroying m_fetcher.
+ if (m_styleEngine)
+ m_styleEngine->detachFromDocument();
if (m_elemSheet)
m_elemSheet->clearOwnerNode();
@@ -531,7 +593,7 @@ Document::~Document()
// It's possible for multiple Documents to end up referencing the same ResourceFetcher (e.g., SVGImages
// load the initial empty document and the SVGDocument with the same DocumentLoader).
if (m_fetcher->document() == this)
- m_fetcher->setDocument(0);
+ m_fetcher->setDocument(nullptr);
m_fetcher.clear();
// We must call clearRareData() here since a Document class inherits TreeScope
@@ -539,28 +601,30 @@ Document::~Document()
if (hasRareData())
clearRareData();
- ASSERT(!m_listsInvalidatedAtDocument.size());
+ ASSERT(m_listsInvalidatedAtDocument.isEmpty());
- for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); i++)
+ for (unsigned i = 0; i < WTF_ARRAY_LENGTH(m_nodeListCounts); ++i)
ASSERT(!m_nodeListCounts[i]);
+#endif
- clearDocumentScope();
setClient(0);
InspectorCounters::decrementCounter(InspectorCounters::DocumentCounter);
}
+#if !ENABLE(OILPAN)
void Document::dispose()
{
ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
+
// We must make sure not to be retaining any of our children through
// these extra pointers or we will create a reference cycle.
- m_docType = 0;
- m_focusedElement = 0;
- m_hoverNode = 0;
- m_activeElement = 0;
- m_titleElement = 0;
- m_documentElement = 0;
+ m_docType = nullptr;
+ m_focusedElement = nullptr;
+ m_hoverNode = nullptr;
+ m_activeHoverElement = nullptr;
+ m_titleElement = nullptr;
+ m_documentElement = nullptr;
m_contextFeatures = ContextFeatures::defaultSwitch();
m_userActionElements.documentDidRemoveLastRef();
m_associatedFormControls.clear();
@@ -569,15 +633,17 @@ void Document::dispose()
m_registrationContext.clear();
- if (m_import) {
- m_import->wasDetachedFromDocument();
- m_import = 0;
+ if (m_importsController) {
+ m_importsController->wasDetachedFrom(*this);
+ m_importsController = nullptr;
}
// removeDetachedChildren() doesn't always unregister IDs,
// so tear down scope information upfront to avoid having stale references in the map.
destroyTreeScopeData();
+
removeDetachedChildren();
+
// removeDetachedChildren() can access FormController.
m_formController.clear();
@@ -591,11 +657,12 @@ void Document::dispose()
m_scriptedAnimationController.clear();
if (svgExtensions())
- accessSVGExtensions()->pauseAnimations();
+ accessSVGExtensions().pauseAnimations();
- m_lifecyle.advanceTo(DocumentLifecycle::Disposed);
+ m_lifecycle.advanceTo(DocumentLifecycle::Disposed);
lifecycleNotifier().notifyDocumentWasDisposed();
}
+#endif
SelectorQueryCache& Document::selectorQueryCache()
{
@@ -613,6 +680,7 @@ MediaQueryMatcher& Document::mediaQueryMatcher()
void Document::mediaQueryAffectingValueChanged()
{
+ m_evaluateMediaQueriesOnStyleRecalc = true;
styleEngine()->clearMediaQueryRuleSetStyleSheets();
}
@@ -634,7 +702,7 @@ String Document::compatMode() const
return inQuirksMode() ? "BackCompat" : "CSS1Compat";
}
-void Document::setDoctype(PassRefPtr<DocumentType> docType)
+void Document::setDoctype(PassRefPtrWillBeRawPtr<DocumentType> docType)
{
// This should never be called more than once.
ASSERT(!m_docType || !docType);
@@ -648,16 +716,16 @@ void Document::setDoctype(PassRefPtr<DocumentType> docType)
clearStyleResolver();
}
-DOMImplementation* Document::implementation()
+DOMImplementation& Document::implementation()
{
if (!m_implementation)
m_implementation = DOMImplementation::create(*this);
- return m_implementation.get();
+ return *m_implementation;
}
-bool Document::hasManifest() const
+bool Document::hasAppCacheManifest() const
{
- return documentElement() && isHTMLHtmlElement(documentElement()) && documentElement()->hasAttribute(manifestAttr);
+ return isHTMLHtmlElement(documentElement()) && documentElement()->hasAttribute(manifestAttr);
}
Location* Document::location() const
@@ -665,280 +733,319 @@ Location* Document::location() const
if (!frame())
return 0;
- return domWindow()->location();
+ return &domWindow()->location();
}
void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
-
- Element* newDocumentElement = ElementTraversal::firstWithin(*this);
- if (newDocumentElement == m_documentElement)
- return;
- m_documentElement = newDocumentElement;
- // The root style used for media query matching depends on the document element.
- clearStyleResolver();
+ m_documentElement = ElementTraversal::firstWithin(*this);
}
-PassRefPtr<Element> Document::createElement(const AtomicString& name, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& name, ExceptionState& exceptionState)
{
if (!isValidName(name)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
- return 0;
+ exceptionState.throwDOMException(InvalidCharacterError, "The tag name provided ('" + name + "') is not a valid name.");
+ return nullptr;
}
if (isXHTMLDocument() || isHTMLDocument())
- return HTMLElementFactory::createHTMLElement(isHTMLDocument() ? name.lower() : name, document(), 0, false);
+ return HTMLElementFactory::createHTMLElement(isHTMLDocument() ? name.lower() : name, *this, 0, false);
- return createElement(QualifiedName(nullAtom, name, nullAtom), false);
+ return Element::create(QualifiedName(nullAtom, name, nullAtom), this);
}
-PassRefPtr<Element> Document::createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Element> Document::createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState& exceptionState)
{
if (!isValidName(localName)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
- return 0;
+ exceptionState.throwDOMException(InvalidCharacterError, "The tag name provided ('" + localName + "') is not a valid name.");
+ return nullptr;
}
- RefPtr<Element> element;
+ RefPtrWillBeRawPtr<Element> element;
- if (RuntimeEnabledFeatures::customElementsEnabled() && CustomElement::isValidName(localName) && registrationContext())
+ if (CustomElement::isValidName(localName) && registrationContext()) {
element = registrationContext()->createCustomTagElement(*this, QualifiedName(nullAtom, localName, xhtmlNamespaceURI));
- else
+ } else {
element = createElement(localName, exceptionState);
+ if (exceptionState.hadException())
+ return nullptr;
+ }
- if (RuntimeEnabledFeatures::customElementsEnabled() && !typeExtension.isNull() && !typeExtension.isEmpty())
+ if (!typeExtension.isEmpty())
CustomElementRegistrationContext::setIsAttributeAndTypeExtension(element.get(), typeExtension);
- return element;
+ return element.release();
}
-PassRefPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState& exceptionState)
+static inline QualifiedName createQualifiedName(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
{
AtomicString prefix, localName;
- if (!parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
- return 0;
+ if (!Document::parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
+ return QualifiedName::null();
QualifiedName qName(prefix, localName, namespaceURI);
- if (!hasValidNamespaceForElements(qName)) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
- return 0;
+ if (!Document::hasValidNamespaceForElements(qName)) {
+ exceptionState.throwDOMException(NamespaceError, "The namespace URI provided ('" + namespaceURI + "') is not valid for the qualified name provided ('" + qualifiedName + "').");
+ return QualifiedName::null();
}
- RefPtr<Element> element;
+ return qName;
+}
+
+PassRefPtrWillBeRawPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
+{
+ QualifiedName qName(createQualifiedName(namespaceURI, qualifiedName, exceptionState));
+ if (qName == QualifiedName::null())
+ return nullptr;
+
+ return createElement(qName, false);
+}
+
+PassRefPtrWillBeRawPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState& exceptionState)
+{
+ QualifiedName qName(createQualifiedName(namespaceURI, qualifiedName, exceptionState));
+ if (qName == QualifiedName::null())
+ return nullptr;
+
+ RefPtrWillBeRawPtr<Element> element;
if (CustomElement::isValidName(qName.localName()) && registrationContext())
element = registrationContext()->createCustomTagElement(*this, qName);
else
- element = createElementNS(namespaceURI, qualifiedName, exceptionState);
+ element = createElement(qName, false);
- if (!typeExtension.isNull() && !typeExtension.isEmpty())
+ if (!typeExtension.isEmpty())
CustomElementRegistrationContext::setIsAttributeAndTypeExtension(element.get(), typeExtension);
- return element;
+ return element.release();
}
-ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, ExceptionState& exceptionState)
+ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const AtomicString& name, ExceptionState& exceptionState)
{
- return registerElement(state, name, Dictionary(), exceptionState);
+ return registerElement(scriptState, name, Dictionary(), exceptionState);
}
-ScriptValue Document::registerElement(WebCore::ScriptState* state, const AtomicString& name, const Dictionary& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
+ScriptValue Document::registerElement(WebCore::ScriptState* scriptState, const AtomicString& name, const Dictionary& options, ExceptionState& exceptionState, CustomElement::NameSet validNames)
{
if (!registrationContext()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "No element registration context is available.");
return ScriptValue();
}
- CustomElementConstructorBuilder constructorBuilder(state, &options);
+ CustomElementConstructorBuilder constructorBuilder(scriptState, &options);
registrationContext()->registerElement(this, &constructorBuilder, name, validNames, exceptionState);
return constructorBuilder.bindingsReturnValue();
}
-void Document::setImport(HTMLImport* import)
+void Document::setImportsController(HTMLImportsController* controller)
{
- ASSERT(!m_import || !import);
- m_import = import;
+ ASSERT(!m_importsController || !controller);
+ m_importsController = controller;
}
-void Document::didLoadAllImports()
+HTMLImportLoader* Document::importLoader() const
{
- executeScriptsWaitingForResourcesIfNeeded();
+ if (!m_importsController)
+ return 0;
+ return m_importsController->loaderFor(*this);
}
bool Document::haveImportsLoaded() const
{
- return !m_import || !m_import->isBlocked();
+ if (!m_importsController)
+ return true;
+ return !m_importsController->shouldBlockScriptExecution(*this);
+}
+
+LocalDOMWindow* Document::executingWindow()
+{
+ if (LocalDOMWindow* owningWindow = domWindow())
+ return owningWindow;
+ if (HTMLImportsController* import = this->importsController())
+ return import->master()->domWindow();
+ return 0;
+}
+
+LocalFrame* Document::executingFrame()
+{
+ LocalDOMWindow* window = executingWindow();
+ if (!window)
+ return 0;
+ return window->frame();
}
-PassRefPtr<DocumentFragment> Document::createDocumentFragment()
+PassRefPtrWillBeRawPtr<DocumentFragment> Document::createDocumentFragment()
{
- return DocumentFragment::create(document());
+ return DocumentFragment::create(*this);
}
-PassRefPtr<Text> Document::createTextNode(const String& data)
+PassRefPtrWillBeRawPtr<Text> Document::createTextNode(const String& data)
{
return Text::create(*this, data);
}
-PassRefPtr<Comment> Document::createComment(const String& data)
+PassRefPtrWillBeRawPtr<Comment> Document::createComment(const String& data)
{
return Comment::create(*this, data);
}
-PassRefPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<CDATASection> Document::createCDATASection(const String& data, ExceptionState& exceptionState)
{
if (isHTMLDocument()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, "This operation is not supported for HTML documents.");
+ return nullptr;
}
if (data.contains("]]>")) {
exceptionState.throwDOMException(InvalidCharacterError, "String cannot contain ']]>' since that is the end delimiter of a CData section.");
- return 0;
+ return nullptr;
}
return CDATASection::create(*this, data);
}
-PassRefPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ProcessingInstruction> Document::createProcessingInstruction(const String& target, const String& data, ExceptionState& exceptionState)
{
if (!isValidName(target)) {
exceptionState.throwDOMException(InvalidCharacterError, "The target provided ('" + target + "') is not a valid name.");
- return 0;
+ return nullptr;
}
if (data.contains("?>")) {
exceptionState.throwDOMException(InvalidCharacterError, "The data provided ('" + data + "') contains '?>'.");
- return 0;
+ return nullptr;
}
return ProcessingInstruction::create(*this, target, data);
}
-PassRefPtr<Text> Document::createEditingTextNode(const String& text)
+PassRefPtrWillBeRawPtr<Text> Document::createEditingTextNode(const String& text)
{
return Text::createEditingText(*this, text);
}
-PassRefPtr<CSSStyleDeclaration> Document::createCSSStyleDeclaration()
+bool Document::importContainerNodeChildren(ContainerNode* oldContainerNode, PassRefPtrWillBeRawPtr<ContainerNode> newContainerNode, ExceptionState& exceptionState)
+{
+ for (Node* oldChild = oldContainerNode->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
+ RefPtrWillBeRawPtr<Node> newChild = importNode(oldChild, true, exceptionState);
+ if (exceptionState.hadException())
+ return false;
+ newContainerNode->appendChild(newChild.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+ }
+
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, ExceptionState& ec)
{
- return MutableStylePropertySet::create()->ensureCSSStyleDeclaration();
+ UseCounter::countDeprecation(this, UseCounter::DocumentImportNodeOptionalArgument);
+ return importNode(importedNode, true, ec);
}
-PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& exceptionState)
{
if (!importedNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
switch (importedNode->nodeType()) {
case TEXT_NODE:
return createTextNode(importedNode->nodeValue());
case CDATA_SECTION_NODE:
- return createCDATASection(importedNode->nodeValue(), exceptionState);
+ return CDATASection::create(*this, importedNode->nodeValue());
case PROCESSING_INSTRUCTION_NODE:
return createProcessingInstruction(importedNode->nodeName(), importedNode->nodeValue(), exceptionState);
case COMMENT_NODE:
return createComment(importedNode->nodeValue());
+ case DOCUMENT_TYPE_NODE: {
+ DocumentType* doctype = toDocumentType(importedNode);
+ return DocumentType::create(this, doctype->name(), doctype->publicId(), doctype->systemId());
+ }
case ELEMENT_NODE: {
Element* oldElement = toElement(importedNode);
// FIXME: The following check might be unnecessary. Is it possible that
// oldElement has mismatched prefix/namespace?
if (!hasValidNamespaceForElements(oldElement->tagQName())) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
- return 0;
+ exceptionState.throwDOMException(NamespaceError, "The imported node has an invalid namespace.");
+ return nullptr;
}
- RefPtr<Element> newElement = createElement(oldElement->tagQName(), false);
+ RefPtrWillBeRawPtr<Element> newElement = createElement(oldElement->tagQName(), false);
newElement->cloneDataFromElement(*oldElement);
if (deep) {
- for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
- RefPtr<Node> newChild = importNode(oldChild, true, exceptionState);
- if (exceptionState.hadException())
- return 0;
- newElement->appendChild(newChild.release(), exceptionState);
- if (exceptionState.hadException())
- return 0;
- }
+ if (!importContainerNodeChildren(oldElement, newElement, exceptionState))
+ return nullptr;
+ if (isHTMLTemplateElement(*oldElement)
+ && !importContainerNodeChildren(toHTMLTemplateElement(oldElement)->content(), toHTMLTemplateElement(newElement)->content(), exceptionState))
+ return nullptr;
}
return newElement.release();
}
case ATTRIBUTE_NODE:
- return Attr::create(*this, QualifiedName(nullAtom, toAttr(importedNode)->name(), nullAtom), toAttr(importedNode)->value());
+ return Attr::create(*this, QualifiedName(nullAtom, AtomicString(toAttr(importedNode)->name()), nullAtom), toAttr(importedNode)->value());
case DOCUMENT_FRAGMENT_NODE: {
if (importedNode->isShadowRoot()) {
// ShadowRoot nodes should not be explicitly importable.
// Either they are imported along with their host node, or created implicitly.
- break;
+ exceptionState.throwDOMException(NotSupportedError, "The node provided is a shadow root, which may not be imported.");
+ return nullptr;
}
DocumentFragment* oldFragment = toDocumentFragment(importedNode);
- RefPtr<DocumentFragment> newFragment = createDocumentFragment();
- if (deep) {
- for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
- RefPtr<Node> newChild = importNode(oldChild, true, exceptionState);
- if (exceptionState.hadException())
- return 0;
- newFragment->appendChild(newChild.release(), exceptionState);
- if (exceptionState.hadException())
- return 0;
- }
- }
+ RefPtrWillBeRawPtr<DocumentFragment> newFragment = createDocumentFragment();
+ if (deep && !importContainerNodeChildren(oldFragment, newFragment, exceptionState))
+ return nullptr;
return newFragment.release();
}
- case ENTITY_NODE:
- case NOTATION_NODE:
- // FIXME: It should be possible to import these node types, however in DOM3 the DocumentType is readonly, so there isn't much sense in doing that.
- // Ability to add these imported nodes to a DocumentType will be considered for addition to a future release of the DOM.
case DOCUMENT_NODE:
- case DOCUMENT_TYPE_NODE:
- case XPATH_NAMESPACE_NODE:
- break;
+ exceptionState.throwDOMException(NotSupportedError, "The node provided is a document, which may not be imported.");
+ return nullptr;
}
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+
+ ASSERT_NOT_REACHED();
+ return nullptr;
}
-PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> Document::adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState& exceptionState)
{
if (!source) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
EventQueueScope scope;
switch (source->nodeType()) {
- case ENTITY_NODE:
- case NOTATION_NODE:
case DOCUMENT_NODE:
case DOCUMENT_TYPE_NODE:
- case XPATH_NAMESPACE_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, "The node provided is of type '" + source->nodeName() + "', which may not be adopted.");
+ return nullptr;
case ATTRIBUTE_NODE: {
Attr* attr = toAttr(source.get());
- if (attr->ownerElement())
- attr->ownerElement()->removeAttributeNode(attr, exceptionState);
+ if (RefPtrWillBeRawPtr<Element> ownerElement = attr->ownerElement())
+ ownerElement->removeAttributeNode(attr, exceptionState);
break;
}
default:
if (source->isShadowRoot()) {
// ShadowRoot cannot disconnect itself from the host node.
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
- return 0;
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided is a shadow root, which may not be adopted.");
+ return nullptr;
}
if (source->isFrameOwnerElement()) {
HTMLFrameOwnerElement* frameOwnerElement = toHTMLFrameOwnerElement(source.get());
- if (frame() && frame()->tree().isDescendantOf(frameOwnerElement->contentFrame())) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
- return 0;
+ // FIXME(kenrb): the downcast can be removed when the FrameTree supports RemoteFrames.
+ if (frame() && frame()->tree().isDescendantOf(toLocalFrameTemporary(frameOwnerElement->contentFrame()))) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided is a frame which contains this document.");
+ return nullptr;
}
}
if (source->parentNode()) {
source->parentNode()->removeChild(source.get(), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
}
}
@@ -958,39 +1065,32 @@ bool Document::hasValidNamespaceForElements(const QualifiedName& qName)
// Required by DOM Level 3 Core and unspecified by DOM Level 2 Core:
// http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-DocCrElNS
- // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar")
- if ((qName.prefix() == xmlnsAtom && qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI) || (qName.prefix() != xmlnsAtom && qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI))
- return false;
-
- return true;
+ // createElementNS("http://www.w3.org/2000/xmlns/", "foo:bar"), createElementNS(null, "xmlns:bar"), createElementNS(null, "xmlns")
+ if (qName.prefix() == xmlnsAtom || (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom))
+ return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
+ return qName.namespaceURI() != XMLNSNames::xmlnsNamespaceURI;
}
bool Document::hasValidNamespaceForAttributes(const QualifiedName& qName)
{
- // Spec: DOM Level 2 Core: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-ElSetAttrNS
- if (qName.prefix().isEmpty() && qName.localName() == xmlnsAtom) {
- // Note: The case of an "xmlns" qualified name with a namespace of
- // xmlnsNamespaceURI is specifically allowed (See <http://www.w3.org/2000/xmlns/>).
- return qName.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
- }
return hasValidNamespaceForElements(qName);
}
// FIXME: This should really be in a possible ElementFactory class
-PassRefPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
+PassRefPtrWillBeRawPtr<Element> Document::createElement(const QualifiedName& qName, bool createdByParser)
{
- RefPtr<Element> e;
+ RefPtrWillBeRawPtr<Element> e = nullptr;
// FIXME: Use registered namespaces and look up in a hash to find the right factory.
if (qName.namespaceURI() == xhtmlNamespaceURI)
- e = HTMLElementFactory::createHTMLElement(qName.localName(), document(), 0, createdByParser);
+ e = HTMLElementFactory::createHTMLElement(qName.localName(), *this, 0, createdByParser);
else if (qName.namespaceURI() == SVGNames::svgNamespaceURI)
- e = SVGElementFactory::createSVGElement(qName.localName(), document(), createdByParser);
+ e = SVGElementFactory::createSVGElement(qName.localName(), *this, createdByParser);
if (e)
m_sawElementsInKnownNamespaces = true;
else
- e = Element::create(qName, &document());
+ e = Element::create(qName, this);
if (e->prefix() != qName.prefix())
e->setTagNameForCreateElementNS(qName);
@@ -1005,39 +1105,6 @@ bool Document::regionBasedColumnsEnabled() const
return settings() && settings()->regionBasedColumnsEnabled();
}
-PassRefPtr<DOMNamedFlowCollection> Document::webkitGetNamedFlows()
-{
- if (!RuntimeEnabledFeatures::cssRegionsEnabled() || !renderView())
- return 0;
-
- updateStyleIfNeeded();
-
- return namedFlows()->createCSSOMSnapshot();
-}
-
-NamedFlowCollection* Document::namedFlows()
-{
- if (!m_namedFlows)
- m_namedFlows = NamedFlowCollection::create(this);
-
- return m_namedFlows.get();
-}
-
-PassRefPtr<Element> Document::createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
-{
- AtomicString prefix, localName;
- if (!parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
- return 0;
-
- QualifiedName qName(prefix, localName, namespaceURI);
- if (!hasValidNamespaceForElements(qName)) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
- return 0;
- }
-
- return createElement(qName, false);
-}
-
String Document::readyState() const
{
DEFINE_STATIC_LOCAL(const String, loading, ("loading"));
@@ -1066,8 +1133,6 @@ void Document::setReadyState(ReadyState readyState)
case Loading:
if (!m_documentTiming.domLoading) {
m_documentTiming.domLoading = monotonicallyIncreasingTime();
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- m_timeline->setZeroTime(m_documentTiming.domLoading);
}
break;
case Interactive:
@@ -1106,6 +1171,7 @@ String Document::defaultCharset() const
void Document::setCharset(const String& charset)
{
+ UseCounter::count(*this, UseCounter::DocumentSetCharset);
if (DocumentLoader* documentLoader = loader())
documentLoader->setUserChosenEncoding(charset);
WTF::TextEncoding encoding(charset);
@@ -1113,7 +1179,7 @@ void Document::setCharset(const String& charset)
if (!encoding.isValid())
return;
DocumentEncodingData newEncodingData = m_encodingData;
- newEncodingData.encoding = encoding;
+ newEncodingData.setEncoding(encoding);
setEncodingData(newEncodingData);
}
@@ -1124,18 +1190,13 @@ void Document::setContentLanguage(const AtomicString& language)
m_contentLanguage = language;
// Document's style depends on the content language.
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
void Document::setXMLVersion(const String& version, ExceptionState& exceptionState)
{
- if (!implementation()->hasFeature("XML", String())) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
-
if (!XMLDocumentParser::supportsXMLVersion(version)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "This document does not support the XML version '" + version + "'.");
return;
}
@@ -1144,11 +1205,6 @@ void Document::setXMLVersion(const String& version, ExceptionState& exceptionSta
void Document::setXMLStandalone(bool standalone, ExceptionState& exceptionState)
{
- if (!implementation()->hasFeature("XML", String())) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
-
m_xmlStandalone = standalone ? Standalone : NotStandalone;
}
@@ -1171,10 +1227,13 @@ void Document::setContent(const String& content)
String Document::suggestedMIMEType() const
{
- if (isXHTMLDocument())
- return "application/xhtml+xml";
- if (isSVGDocument())
- return "image/svg+xml";
+ if (isXMLDocument()) {
+ if (isXHTMLDocument())
+ return "application/xhtml+xml";
+ if (isSVGDocument())
+ return "image/svg+xml";
+ return "application/xml";
+ }
if (xmlStandalone())
return "text/xml";
if (isHTMLDocument())
@@ -1185,6 +1244,26 @@ String Document::suggestedMIMEType() const
return String();
}
+void Document::setMimeType(const AtomicString& mimeType)
+{
+ m_mimeType = mimeType;
+}
+
+AtomicString Document::contentType() const
+{
+ if (!m_mimeType.isEmpty())
+ return m_mimeType;
+
+ if (DocumentLoader* documentLoader = loader())
+ return documentLoader->mimeType();
+
+ String mimeType = suggestedMIMEType();
+ if (!mimeType.isEmpty())
+ return AtomicString(mimeType);
+
+ return AtomicString("application/xml");
+}
+
Element* Document::elementFromPoint(int x, int y) const
{
if (!renderView())
@@ -1193,14 +1272,14 @@ Element* Document::elementFromPoint(int x, int y) const
return TreeScope::elementFromPoint(x, y);
}
-PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
+PassRefPtrWillBeRawPtr<Range> Document::caretRangeFromPoint(int x, int y)
{
if (!renderView())
- return 0;
- LayoutPoint localPoint;
- RenderObject* renderer = rendererFromPoint(this, x, y, &localPoint);
+ return nullptr;
+ HitTestResult result = hitTestInDocument(this, x, y);
+ RenderObject* renderer = result.renderer();
if (!renderer)
- return 0;
+ return nullptr;
Node* node = renderer->node();
Node* shadowAncestorNode = ancestorInThisScope(node);
@@ -1210,9 +1289,9 @@ PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
return Range::create(*this, container, offset, container, offset);
}
- PositionWithAffinity positionWithAffinity = renderer->positionForPoint(localPoint);
+ PositionWithAffinity positionWithAffinity = renderer->positionForPoint(result.localPoint());
if (positionWithAffinity.position().isNull())
- return 0;
+ return nullptr;
Position rangeCompliantPosition = positionWithAffinity.position().parentAnchoredEquivalent();
return Range::create(*this, rangeCompliantPosition, rangeCompliantPosition);
@@ -1299,18 +1378,18 @@ void Document::setTitle(const String& title)
// Title set by JavaScript -- overrides any title elements.
m_titleSetExplicitly = true;
if (!isHTMLDocument() && !isXHTMLDocument())
- m_titleElement = 0;
+ m_titleElement = nullptr;
else if (!m_titleElement) {
if (HTMLElement* headElement = head()) {
- m_titleElement = createElement(titleTag, false);
- headElement->appendChild(m_titleElement);
+ m_titleElement = HTMLTitleElement::create(*this);
+ headElement->appendChild(m_titleElement.get());
}
}
- updateTitle(title);
-
- if (m_titleElement && isHTMLTitleElement(m_titleElement.get()))
+ if (isHTMLTitleElement(m_titleElement))
toHTMLTitleElement(m_titleElement)->setText(title);
+ else
+ updateTitle(title);
}
void Document::setTitleElement(const String& title, Element* titleElement)
@@ -1330,25 +1409,35 @@ void Document::removeTitle(Element* titleElement)
if (m_titleElement != titleElement)
return;
- m_titleElement = 0;
+ m_titleElement = nullptr;
m_titleSetExplicitly = false;
// FIXME: This is broken for SVG.
// Update title based on first title element in the head, if one exists.
if (HTMLElement* headElement = head()) {
- for (Element* element = headElement->firstElementChild(); element; element = element->nextElementSibling()) {
- if (!isHTMLTitleElement(element))
- continue;
- HTMLTitleElement* title = toHTMLTitleElement(element);
+ if (HTMLTitleElement* title = Traversal<HTMLTitleElement>::firstChild(*headElement))
setTitleElement(title->text(), title);
- break;
- }
}
if (!m_titleElement)
updateTitle(String());
}
+const AtomicString& Document::dir()
+{
+ Element* rootElement = documentElement();
+ if (isHTMLHtmlElement(rootElement))
+ return toHTMLHtmlElement(rootElement)->dir();
+ return nullAtom;
+}
+
+void Document::setDir(const AtomicString& value)
+{
+ Element* rootElement = documentElement();
+ if (isHTMLHtmlElement(rootElement))
+ toHTMLHtmlElement(rootElement)->setDir(value);
+}
+
PageVisibilityState Document::pageVisibilityState() const
{
// The visibility of the document is inherited from the visibility of the
@@ -1370,18 +1459,28 @@ bool Document::hidden() const
return pageVisibilityState() != PageVisibilityStateVisible;
}
-void Document::dispatchVisibilityStateChangeEvent()
+void Document::didChangeVisibilityState()
{
dispatchEvent(Event::create(EventTypeNames::visibilitychange));
// Also send out the deprecated version until it can be removed.
dispatchEvent(Event::create(EventTypeNames::webkitvisibilitychange));
+
+ PageVisibilityState state = pageVisibilityState();
+ DocumentVisibilityObserverSet::const_iterator observerEnd = m_visibilityObservers.end();
+ for (DocumentVisibilityObserverSet::const_iterator it = m_visibilityObservers.begin(); it != observerEnd; ++it)
+ (*it)->didChangeVisibilityState(state);
+}
+
+void Document::registerVisibilityObserver(DocumentVisibilityObserver* observer)
+{
+ ASSERT(!m_visibilityObservers.contains(observer));
+ m_visibilityObservers.add(observer);
}
-DOMSecurityPolicy* Document::securityPolicy()
+void Document::unregisterVisibilityObserver(DocumentVisibilityObserver* observer)
{
- if (!m_domSecurityPolicy)
- m_domSecurityPolicy = DOMSecurityPolicy::create(this);
- return m_domSecurityPolicy.get();
+ ASSERT(m_visibilityObservers.contains(observer));
+ m_visibilityObservers.remove(observer);
}
String Document::nodeName() const
@@ -1394,17 +1493,20 @@ Node::NodeType Document::nodeType() const
return DOCUMENT_NODE;
}
-FormController* Document::formController()
+FormController& Document::formController()
{
- if (!m_formController)
+ if (!m_formController) {
m_formController = FormController::create();
- return m_formController.get();
+ if (m_frame && m_frame->loader().currentItem() && m_frame->loader().currentItem()->isCurrentDocument(this))
+ m_frame->loader().currentItem()->setDocumentState(m_formController->formElementsState());
+ }
+ return *m_formController;
}
-Vector<String> Document::formElementsState() const
+DocumentState* Document::formElementsState() const
{
if (!m_formController)
- return Vector<String>();
+ return 0;
return m_formController->formElementsState();
}
@@ -1412,7 +1514,7 @@ void Document::setStateForNewFormElements(const Vector<String>& stateVector)
{
if (!stateVector.size() && !m_formController)
return;
- formController()->setStateForNewFormElements(stateVector);
+ formController().setStateForNewFormElements(stateVector);
}
FrameView* Document::view() const
@@ -1425,124 +1527,174 @@ Page* Document::page() const
return m_frame ? m_frame->page() : 0;
}
+FrameHost* Document::frameHost() const
+{
+ return m_frame ? m_frame->host() : 0;
+}
+
Settings* Document::settings() const
{
return m_frame ? m_frame->settings() : 0;
}
-PassRefPtr<Range> Document::createRange()
+PassRefPtrWillBeRawPtr<Range> Document::createRange()
{
return Range::create(*this);
}
-PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, ExceptionState& exceptionState)
{
// FIXME: Probably this should be handled within the bindings layer and TypeError should be thrown.
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
- return NodeIterator::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
+ return NodeIterator::create(root, NodeFilter::SHOW_ALL, nullptr);
}
-PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
// FIXME: It might be a good idea to emit a warning if |whatToShow| contains a bit that is not defined in
// NodeFilter.
- return NodeIterator::create(root, whatToShow, PassRefPtr<NodeFilter>());
+ return NodeIterator::create(root, whatToShow, nullptr);
}
-PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
// FIXME: Ditto.
return NodeIterator::create(root, whatToShow, filter);
}
-PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
- return TreeWalker::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
+ return TreeWalker::create(root, NodeFilter::SHOW_ALL, nullptr);
}
-PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
- return TreeWalker::create(root, whatToShow, PassRefPtr<NodeFilter>());
+ return TreeWalker::create(root, whatToShow, nullptr);
}
-PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter, ExceptionState& exceptionState)
{
if (!root) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
return TreeWalker::create(root, whatToShow, filter);
}
-void Document::scheduleStyleRecalc()
+bool Document::needsRenderTreeUpdate() const
{
- if (shouldDisplaySeamlesslyWithParent()) {
- // When we're seamless, our parent document manages our style recalcs.
- ownerElement()->setNeedsStyleRecalc();
- ownerElement()->document().scheduleStyleRecalc();
- return;
- }
-
- if (m_styleRecalcTimer.isActive())
- return;
-
- ASSERT(needsStyleRecalc() || childNeedsStyleRecalc() || childNeedsDistributionRecalc());
-
- m_styleRecalcTimer.startOneShot(0);
-
- InspectorInstrumentation::didScheduleStyleRecalculation(this);
+ if (!isActive() || !view())
+ return false;
+ if (needsFullRenderTreeUpdate())
+ return true;
+ if (childNeedsStyleRecalc())
+ return true;
+ if (childNeedsStyleInvalidation())
+ return true;
+ return false;
}
-void Document::unscheduleStyleRecalc()
+bool Document::needsFullRenderTreeUpdate() const
{
- ASSERT(!isActive() || (!needsStyleRecalc() && !childNeedsStyleRecalc()));
- m_styleRecalcTimer.stop();
+ if (!isActive() || !view())
+ return false;
+ if (!m_useElementsNeedingUpdate.isEmpty())
+ return true;
+ if (!m_layerUpdateSVGFilterElements.isEmpty())
+ return true;
+ if (needsStyleRecalc())
+ return true;
+ if (needsStyleInvalidation())
+ return true;
+ // FIXME: The childNeedsDistributionRecalc bit means either self or children, we should fix that.
+ if (childNeedsDistributionRecalc())
+ return true;
+ if (DocumentAnimations::needsOutdatedAnimationPlayerUpdate(*this))
+ return true;
+ return false;
}
-bool Document::hasPendingStyleRecalc() const
+bool Document::shouldScheduleRenderTreeUpdate() const
{
- return m_styleRecalcTimer.isActive() && !m_inStyleRecalc;
+ if (!isActive())
+ return false;
+ if (inStyleRecalc())
+ return false;
+ // InPreLayout will recalc style itself. There's no reason to schedule another recalc.
+ if (m_lifecycle.state() == DocumentLifecycle::InPreLayout)
+ return false;
+ if (!shouldScheduleLayout())
+ return false;
+ return true;
}
-bool Document::hasPendingForcedStyleRecalc() const
+void Document::scheduleRenderTreeUpdate()
{
- return hasPendingStyleRecalc() && styleChangeType() >= SubtreeStyleChange;
+ ASSERT(!hasPendingStyleRecalc());
+ ASSERT(shouldScheduleRenderTreeUpdate());
+ ASSERT(needsRenderTreeUpdate());
+
+ page()->animator().scheduleVisualUpdate();
+ m_lifecycle.ensureStateAtMost(DocumentLifecycle::VisualUpdatePending);
+
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ScheduleStyleRecalculation", "frame", frame());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didScheduleStyleRecalculation(this);
}
-void Document::styleRecalcTimerFired(Timer<Document>*)
+bool Document::hasPendingForcedStyleRecalc() const
{
- updateStyleIfNeeded();
+ return hasPendingStyleRecalc() && !inStyleRecalc() && styleChangeType() >= SubtreeStyleChange;
}
void Document::updateDistributionIfNeeded()
{
+ ScriptForbiddenScope forbidScript;
+
if (!childNeedsDistributionRecalc())
return;
- TRACE_EVENT0("webkit", "Document::recalcDistribution");
+ TRACE_EVENT0("webkit", "Document::updateDistributionIfNeeded");
recalcDistribution();
}
+void Document::updateStyleInvalidationIfNeeded()
+{
+ ScriptForbiddenScope forbidScript;
+
+ if (!isActive())
+ return;
+ if (!childNeedsStyleInvalidation())
+ return;
+ TRACE_EVENT0("webkit", "Document::updateStyleInvalidationIfNeeded");
+ ASSERT(styleResolver());
+
+ styleResolver()->ruleFeatureSet().styleInvalidator().invalidate(*this);
+}
+
void Document::updateDistributionForNodeIfNeeded(Node* node)
{
+ ScriptForbiddenScope forbidScript;
+
if (node->inDocument()) {
updateDistributionIfNeeded();
return;
@@ -1556,23 +1708,11 @@ void Document::updateDistributionForNodeIfNeeded(Node* node)
root->recalcDistribution();
}
-void Document::setStyleDependentState(RenderStyle* documentStyle)
+void Document::setupFontBuilder(RenderStyle* documentStyle)
{
- const Pagination& pagination = view()->pagination();
- if (pagination.mode != Pagination::Unpaginated) {
- Pagination::setStylesForPaginationMode(pagination.mode, documentStyle);
- documentStyle->setColumnGap(pagination.gap);
- if (renderView()->hasColumns())
- renderView()->updateColumnInfoFromStyle(documentStyle);
- }
-
- // Seamless iframes want to inherit their font from their parent iframe, so early return before setting the font.
- if (shouldDisplaySeamlesslyWithParent())
- return;
-
FontBuilder fontBuilder;
- fontBuilder.initForStyleResolve(*this, documentStyle, isSVGDocument());
- RefPtr<CSSFontSelector> selector = m_styleEngine->fontSelector();
+ fontBuilder.initForStyleResolve(*this, documentStyle);
+ RefPtrWillBeRawPtr<CSSFontSelector> selector = m_styleEngine->fontSelector();
fontBuilder.createFontForDocument(selector, documentStyle);
}
@@ -1587,10 +1727,11 @@ void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change)
WritingMode rootWritingMode = documentElementStyle->writingMode();
TextDirection rootDirection = documentElementStyle->direction();
- HTMLElement* body = this->body();
+ HTMLElement* body = this->body();
+ RefPtr<RenderStyle> bodyStyle;
if (body) {
- RefPtr<RenderStyle> bodyStyle = body->renderStyle();
+ bodyStyle = body->renderStyle();
if (!bodyStyle || body->needsStyleRecalc() || documentElement()->needsStyleRecalc() || change == Force)
bodyStyle = ensureStyleResolver().styleForElement(body, documentElementStyle.get());
if (!writingModeSetOnDocumentElement())
@@ -1599,157 +1740,217 @@ void Document::inheritHtmlAndBodyElementStyles(StyleRecalcChange change)
rootDirection = bodyStyle->direction();
}
+ RefPtr<RenderStyle> overflowStyle;
+ if (Element* element = viewportDefiningElement(documentElementStyle.get())) {
+ if (element == body) {
+ overflowStyle = bodyStyle;
+ } else {
+ ASSERT(element == documentElement());
+ overflowStyle = documentElementStyle;
+ }
+ }
+
+ // Resolved rem units are stored in the matched properties cache so we need to make sure to
+ // invalidate the cache if the documentElement needed to reattach or the font size changed
+ // and then trigger a full document recalc. We also need to clear it here since the
+ // call to styleForElement on the body above can cache bad values for rem units if the
+ // documentElement's style was dirty. We could keep track of which elements depend on
+ // rem units like we do for viewport styles, but we assume root font size changes are
+ // rare and just invalidate the cache for now.
+ if (styleEngine()->usesRemUnits() && (documentElement()->needsAttach() || documentElement()->computedStyle()->fontSize() != documentElementStyle->fontSize())) {
+ ensureStyleResolver().invalidateMatchedPropertiesCache();
+ documentElement()->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+
+ EOverflow overflowX = OAUTO;
+ EOverflow overflowY = OAUTO;
+ float columnGap = 0;
+ if (overflowStyle) {
+ overflowX = overflowStyle->overflowX();
+ overflowY = overflowStyle->overflowY();
+ // Visible overflow on the viewport is meaningless, and the spec says to treat it as 'auto':
+ if (overflowX == OVISIBLE)
+ overflowX = OAUTO;
+ if (overflowY == OVISIBLE)
+ overflowY = OAUTO;
+ // Column-gap is (ab)used by the current paged overflow implementation (in lack of other
+ // ways to specify gaps between pages), so we have to propagate it too.
+ columnGap = overflowStyle->columnGap();
+ }
+
RefPtr<RenderStyle> documentStyle = renderView()->style();
- if (documentStyle->writingMode() != rootWritingMode || documentStyle->direction() != rootDirection) {
+ if (documentStyle->writingMode() != rootWritingMode
+ || documentStyle->direction() != rootDirection
+ || documentStyle->overflowX() != overflowX
+ || documentStyle->overflowY() != overflowY
+ || documentStyle->columnGap() != columnGap) {
RefPtr<RenderStyle> newStyle = RenderStyle::clone(documentStyle.get());
newStyle->setWritingMode(rootWritingMode);
newStyle->setDirection(rootDirection);
+ newStyle->setColumnGap(columnGap);
+ newStyle->setOverflowX(overflowX);
+ newStyle->setOverflowY(overflowY);
renderView()->setStyle(newStyle);
- setStyleDependentState(newStyle.get());
+ setupFontBuilder(newStyle.get());
}
if (body) {
if (RenderStyle* style = body->renderStyle()) {
if (style->direction() != rootDirection || style->writingMode() != rootWritingMode)
- body->setNeedsStyleRecalc();
+ body->setNeedsStyleRecalc(SubtreeStyleChange);
}
}
if (RenderStyle* style = documentElement()->renderStyle()) {
if (style->direction() != rootDirection || style->writingMode() != rootWritingMode)
- documentElement()->setNeedsStyleRecalc();
+ documentElement()->setNeedsStyleRecalc(SubtreeStyleChange);
}
}
-void Document::recalcStyle(StyleRecalcChange change)
+void Document::updateRenderTree(StyleRecalcChange change)
{
- // we should not enter style recalc while painting
- RELEASE_ASSERT(!view() || !view()->isPainting());
+ ASSERT(isMainThread());
- // FIXME: We should never enter here without a FrameView or with an inactive document.
- if (!isActive() || !view())
+ if (change != Force && !needsRenderTreeUpdate())
return;
- if (m_inStyleRecalc)
+ if (inStyleRecalc())
return;
- TRACE_EVENT0("webkit", "Document::recalcStyle");
- TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "RecalcStyle");
+ // Entering here from inside layout or paint would be catastrophic since recalcStyle can
+ // tear down the render tree or (unfortunately) run script. Kill the whole renderer if
+ // someone managed to get into here from inside layout or paint.
+ RELEASE_ASSERT(!view()->isInPerformLayout());
+ RELEASE_ASSERT(!view()->isPainting());
- updateDistributionIfNeeded();
+ // Script can run below in WidgetUpdates, so protect the LocalFrame.
+ RefPtr<LocalFrame> protect(m_frame);
+
+ TRACE_EVENT0("webkit", "Document::updateRenderTree");
+ TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "UpdateRenderTree");
+ m_styleRecalcElementCounter = 0;
+ TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RecalculateStyles", "frame", frame());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRecalculateStyle(this);
- if (m_evaluateMediaQueriesOnStyleRecalc) {
- m_evaluateMediaQueriesOnStyleRecalc = false;
- evaluateMediaQueryList();
- }
+ DocumentAnimations::updateOutdatedAnimationPlayersIfNeeded(*this);
+
+ // FIXME: This executes media query listeners which runs script, instead the script
+ // should run at raf timing in ScriptedAnimationController just like resize events.
+ evaluateMediaQueryListIfNeeded();
+
+ updateUseShadowTreesIfNeeded();
+ updateDistributionIfNeeded();
+ updateStyleInvalidationIfNeeded();
- // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
- // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
- // before setting the DOMWindow on the Frame, or the SecurityOrigin on the document. The attach, in turn
+ // FIXME: We should update style on our ancestor chain before proceeding
+ // however doing so currently causes several tests to crash, as LocalFrame::setDocument calls Document::attach
+ // before setting the LocalDOMWindow on the LocalFrame, or the SecurityOrigin on the document. The attach, in turn
// resolves style (here) and then when we resolve style on the parent chain, we may end up
// re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
// hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
- if (m_styleEngine->needsUpdateActiveStylesheetsOnStyleRecalc())
- m_styleEngine->updateActiveStyleSheets(FullStyleUpdate);
-
if (m_elemSheet && m_elemSheet->contents()->usesRemUnits())
m_styleEngine->setUsesRemUnit(true);
- {
- PostAttachCallbacks::SuspendScope suspendPostAttachCallbacks;
- RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
- FrameView::DeferredRepaintScope deferRepaints(*view());
- TemporaryChange<bool> changeInStyleRecalc(m_inStyleRecalc, true);
-
- if (styleChangeType() >= SubtreeStyleChange)
- change = Force;
-
- // FIXME: Cannot access the ensureStyleResolver() before calling styleForDocument below because
- // apparently the StyleResolver's constructor has side effects. We should fix it.
- // See printing/setPrinting.html, printing/width-overflow.html though they only fail on
- // mac when accessing the resolver by what appears to be a viewport size difference.
-
- if (change == Force || (change >= Inherit && shouldDisplaySeamlesslyWithParent())) {
- m_hasNodesWithPlaceholderStyle = false;
- RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*this, m_styleEngine->fontSelector());
- StyleRecalcChange localChange = RenderStyle::compare(documentStyle.get(), renderView()->style());
- if (localChange != NoChange)
- renderView()->setStyle(documentStyle.release());
- }
+ updateStyle(change);
- clearNeedsStyleRecalc();
+ // As a result of the style recalculation, the currently hovered element might have been
+ // detached (for example, by setting display:none in the :hover style), schedule another mouseMove event
+ // to check if any other elements ended up under the mouse pointer due to re-layout.
+ if (hoverNode() && !hoverNode()->renderer() && frame())
+ frame()->eventHandler().dispatchFakeMouseMoveEventSoon();
- // Uncomment to enable printing of statistics about style sharing and the matched property cache.
- // Optionally pass StyleResolver::ReportSlowStats to print numbers that require crawling the
- // entire DOM (where collecting them is very slow).
- // FIXME: Expose this as a runtime flag.
- // ensureStyleResolver().enableStats(/*StyleResolver::ReportSlowStats*/);
+ if (m_focusedElement && !m_focusedElement->isFocusable())
+ clearFocusedElementSoon();
- if (StyleResolverStats* stats = ensureStyleResolver().stats())
- stats->reset();
+#if ENABLE(SVG_FONTS)
+ if (svgExtensions())
+ accessSVGExtensions().removePendingSVGFontFaceElementsForRemoval();
+#endif
- if (Element* documentElement = this->documentElement()) {
- inheritHtmlAndBodyElementStyles(change);
- if (shouldRecalcStyle(change, documentElement))
- documentElement->recalcStyle(change);
- }
+ ASSERT(!m_timeline->hasOutdatedAnimationPlayer());
- ensureStyleResolver().printStats();
+ TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RecalculateStyles", "elementCount", m_styleRecalcElementCounter);
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didRecalculateStyle(cookie, m_styleRecalcElementCounter);
+}
- view()->updateCompositingLayersAfterStyleChange();
+void Document::updateStyle(StyleRecalcChange change)
+{
+ TRACE_EVENT0("webkit", "Document::updateStyle");
- clearChildNeedsStyleRecalc();
- unscheduleStyleRecalc();
+ ScriptForbiddenScope forbidScript;
+ HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
+ m_lifecycle.advanceTo(DocumentLifecycle::InStyleRecalc);
- // FIXME: SVG <use> element can schedule a recalc in the middle of an already running one.
- // See StyleEngine::updateActiveStyleSheets.
- if (m_styleEngine->needsUpdateActiveStylesheetsOnStyleRecalc())
- setNeedsStyleRecalc();
+ if (styleChangeType() >= SubtreeStyleChange)
+ change = Force;
- if (m_styleEngine->hasResolver()) {
- // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
- StyleResolver& resolver = m_styleEngine->ensureResolver();
- m_styleEngine->resetCSSFeatureFlags(resolver.ensureRuleFeatureSet());
- resolver.clearStyleSharingList();
- }
+ // FIXME: Cannot access the ensureStyleResolver() before calling styleForDocument below because
+ // apparently the StyleResolver's constructor has side effects. We should fix it.
+ // See printing/setPrinting.html, printing/width-overflow.html though they only fail on
+ // mac when accessing the resolver by what appears to be a viewport size difference.
+
+ if (change == Force) {
+ m_hasNodesWithPlaceholderStyle = false;
+ RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*this);
+ StyleRecalcChange localChange = RenderStyle::stylePropagationDiff(documentStyle.get(), renderView()->style());
+ if (localChange != NoChange)
+ renderView()->setStyle(documentStyle.release());
}
- InspectorInstrumentation::didRecalculateStyle(cookie);
+ clearNeedsStyleRecalc();
- // As a result of the style recalculation, the currently hovered element might have been
- // detached (for example, by setting display:none in the :hover style), schedule another mouseMove event
- // to check if any other elements ended up under the mouse pointer due to re-layout.
- if (hoverNode() && !hoverNode()->renderer() && frame())
- frame()->eventHandler().dispatchFakeMouseMoveEventSoon();
-}
+ // Uncomment to enable printing of statistics about style sharing and the matched property cache.
+ // Optionally pass StyleResolver::ReportSlowStats to print numbers that require crawling the
+ // entire DOM (where collecting them is very slow).
+ // FIXME: Expose this as a runtime flag.
+ // ensureStyleResolver().enableStats(/*StyleResolver::ReportSlowStats*/);
-void Document::updateStyleIfNeeded()
-{
- ASSERT(isMainThread());
- ASSERT(!view() || (!view()->isInLayout() && !view()->isPainting()));
+ if (StyleResolverStats* stats = ensureStyleResolver().stats())
+ stats->reset();
- if (!needsStyleRecalc() && !childNeedsStyleRecalc() && !childNeedsDistributionRecalc())
- return;
+ if (Element* documentElement = this->documentElement()) {
+ inheritHtmlAndBodyElementStyles(change);
+ dirtyElementsForLayerUpdate();
+ if (documentElement->shouldCallRecalcStyle(change))
+ documentElement->recalcStyle(change);
+ while (dirtyElementsForLayerUpdate())
+ documentElement->recalcStyle(NoChange);
+ }
+
+ ensureStyleResolver().printStats();
+
+ view()->recalcOverflowAfterStyleChange();
+ renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+
+ clearChildNeedsStyleRecalc();
+
+ if (m_styleEngine->hasResolver()) {
+ // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
+ StyleResolver& resolver = m_styleEngine->ensureResolver();
+ m_styleEngine->resetCSSFeatureFlags(resolver.ensureUpdatedRuleFeatureSet());
+ resolver.clearStyleSharingList();
+ }
- RefPtr<Frame> holder(m_frame);
- AnimationUpdateBlock animationUpdateBlock(m_frame ? &m_frame->animation() : 0);
- recalcStyle(NoChange);
- DocumentAnimations::serviceAfterStyleRecalc(*this);
+ ASSERT(!needsStyleRecalc());
+ ASSERT(!childNeedsStyleRecalc());
+ ASSERT(inStyleRecalc());
+ m_lifecycle.advanceTo(DocumentLifecycle::StyleClean);
}
-void Document::updateStyleForNodeIfNeeded(Node* node)
+void Document::updateRenderTreeForNodeIfNeeded(Node* node)
{
- if (!hasPendingForcedStyleRecalc() && !childNeedsStyleRecalc() && !needsStyleRecalc())
- return;
+ bool needsRecalc = needsFullRenderTreeUpdate();
- bool needsStyleRecalc = hasPendingForcedStyleRecalc();
- for (Node* ancestor = node; ancestor && !needsStyleRecalc; ancestor = ancestor->parentOrShadowHostNode())
- needsStyleRecalc = ancestor->needsStyleRecalc();
- if (needsStyleRecalc)
- updateStyleIfNeeded();
+ for (const Node* ancestor = node; ancestor && !needsRecalc; ancestor = NodeRenderingTraversal::parent(ancestor))
+ needsRecalc = ancestor->needsStyleRecalc() || ancestor->needsStyleInvalidation();
+
+ if (needsRecalc)
+ updateRenderTreeIfNeeded();
}
void Document::updateLayout()
@@ -1757,7 +1958,7 @@ void Document::updateLayout()
ASSERT(isMainThread());
RefPtr<FrameView> frameView = view();
- if (frameView && frameView->isInLayout()) {
+ if (frameView && frameView->isInPerformLayout()) {
// View layout should not be re-entrant.
ASSERT_NOT_REACHED();
return;
@@ -1766,51 +1967,36 @@ void Document::updateLayout()
if (Element* oe = ownerElement())
oe->document().updateLayout();
- updateStyleIfNeeded();
+ updateRenderTreeIfNeeded();
- // Only do a layout if changes have occurred that make it necessary.
- if (isActive() && frameView && renderView() && (frameView->layoutPending() || renderView()->needsLayout()))
- frameView->layout();
+ if (!isActive())
+ return;
- if (isActive() && frameView)
- frameView->partialLayout().reset();
+ if (frameView->needsLayout())
+ frameView->layout();
- setNeedsFocusedElementCheck();
+ if (lifecycle().state() < DocumentLifecycle::LayoutClean)
+ lifecycle().advanceTo(DocumentLifecycle::LayoutClean);
}
void Document::setNeedsFocusedElementCheck()
{
- // FIXME: Using a Task doesn't look a good idea.
- if (!m_focusedElement || m_didPostCheckFocusedElementTask)
- return;
- m_taskRunner->postTask(CheckFocusedElementTask::create());
- m_didPostCheckFocusedElementTask = true;
+ setNeedsStyleRecalc(LocalStyleChange);
}
-void Document::recalcStyleForLayoutIgnoringPendingStylesheets()
+void Document::clearFocusedElementSoon()
{
- ASSERT(m_styleEngine->ignoringPendingStylesheets());
+ if (!m_clearFocusedElementTimer.isActive())
+ m_clearFocusedElementTimer.startOneShot(0, FROM_HERE);
+}
- if (!m_styleEngine->hasPendingSheets())
- return;
+void Document::clearFocusedElementTimerFired(Timer<Document>*)
+{
+ updateRenderTreeIfNeeded();
+ m_clearFocusedElementTimer.stop();
- // FIXME: We are willing to attempt to suppress painting with outdated style info only once.
- // Our assumption is that it would be dangerous to try to stop it a second time, after page
- // content has already been loaded and displayed with accurate style information. (Our
- // suppression involves blanking the whole page at the moment. If it were more refined, we
- // might be able to do something better.) It's worth noting though that this entire method
- // is a hack, since what we really want to do is suspend JS instead of doing a layout with
- // inaccurate information.
- HTMLElement* bodyElement = body();
- if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
- m_pendingSheetLayout = DidLayoutWithPendingSheets;
- styleResolverChanged(RecalcStyleImmediately);
- } else if (m_hasNodesWithPlaceholderStyle) {
- // If new nodes have been added or style recalc has been done with style sheets still
- // pending, some nodes may not have had their real style calculated yet. Normally this
- // gets cleaned when style sheets arrive but here we need up-to-date style immediately.
- recalcStyle(Force);
- }
+ if (m_focusedElement && !m_focusedElement->isFocusable())
+ m_focusedElement->blur();
}
// FIXME: This is a bad idea and needs to be removed eventually.
@@ -1822,42 +2008,31 @@ void Document::recalcStyleForLayoutIgnoringPendingStylesheets()
void Document::updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasks runPostLayoutTasks)
{
StyleEngine::IgnoringPendingStylesheet ignoring(m_styleEngine.get());
- recalcStyleForLayoutIgnoringPendingStylesheets();
- updateLayout();
- if (runPostLayoutTasks == RunPostLayoutTasksSynchronously && view())
- view()->flushAnyPendingPostLayoutTasks();
-}
-
-void Document::partialUpdateLayoutIgnorePendingStylesheets(Node* stopLayoutAtNode)
-{
- // Non-overlay scrollbars can cause a second layout that is dependent
- // on a first layout. This is disabled for partial layout for now.
- if (!RuntimeEnabledFeatures::partialLayoutEnabled() || !ScrollbarTheme::theme()->usesOverlayScrollbars()) {
- updateLayoutIgnorePendingStylesheets();
- return;
- }
- StyleEngine::IgnoringPendingStylesheet ignoring(m_styleEngine.get());
- recalcStyleForLayoutIgnoringPendingStylesheets();
-
- if (stopLayoutAtNode) {
- RenderObject* renderer = stopLayoutAtNode->renderer();
- bool canPartialLayout = renderer;
- while (renderer) {
- if (!renderer->supportsPartialLayout()) {
- canPartialLayout = false;
- break;
- }
- renderer = renderer->parent();
+ if (m_styleEngine->hasPendingSheets()) {
+ // FIXME: We are willing to attempt to suppress painting with outdated style info only once.
+ // Our assumption is that it would be dangerous to try to stop it a second time, after page
+ // content has already been loaded and displayed with accurate style information. (Our
+ // suppression involves blanking the whole page at the moment. If it were more refined, we
+ // might be able to do something better.) It's worth noting though that this entire method
+ // is a hack, since what we really want to do is suspend JS instead of doing a layout with
+ // inaccurate information.
+ HTMLElement* bodyElement = body();
+ if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
+ m_pendingSheetLayout = DidLayoutWithPendingSheets;
+ styleResolverChanged();
+ } else if (m_hasNodesWithPlaceholderStyle) {
+ // If new nodes have been added or style recalc has been done with style sheets still
+ // pending, some nodes may not have had their real style calculated yet. Normally this
+ // gets cleaned when style sheets arrive but here we need up-to-date style immediately.
+ updateRenderTree(Force);
}
- if (canPartialLayout && view())
- view()->partialLayout().setStopAtRenderer(stopLayoutAtNode->renderer());
}
updateLayout();
- if (view())
- view()->partialLayout().reset();
+ if (runPostLayoutTasks == RunPostLayoutTasksSynchronously && view())
+ view()->flushAnyPendingPostLayoutTasks();
}
PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
@@ -1880,7 +2055,6 @@ bool Document::isPageBoxVisible(int pageIndex)
void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int& marginTop, int& marginRight, int& marginBottom, int& marginLeft)
{
RefPtr<RenderStyle> style = styleForPage(pageIndex);
- RenderView* view = renderView();
int width = pageSize.width();
int height = pageSize.height();
@@ -1899,8 +2073,8 @@ void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int&
LengthSize size = style->pageSize();
ASSERT(size.width().isFixed());
ASSERT(size.height().isFixed());
- width = valueForLength(size.width(), 0, view);
- height = valueForLength(size.height(), 0, view);
+ width = valueForLength(size.width(), 0);
+ height = valueForLength(size.height(), 0);
break;
}
default:
@@ -1910,10 +2084,10 @@ void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int&
// The percentage is calculated with respect to the width even for margin top and bottom.
// http://www.w3.org/TR/CSS2/box.html#margin-properties
- marginTop = style->marginTop().isAuto() ? marginTop : intValueForLength(style->marginTop(), width, view);
- marginRight = style->marginRight().isAuto() ? marginRight : intValueForLength(style->marginRight(), width, view);
- marginBottom = style->marginBottom().isAuto() ? marginBottom : intValueForLength(style->marginBottom(), width, view);
- marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width, view);
+ marginTop = style->marginTop().isAuto() ? marginTop : intValueForLength(style->marginTop(), width);
+ marginRight = style->marginRight().isAuto() ? marginRight : intValueForLength(style->marginRight(), width);
+ marginBottom = style->marginBottom().isAuto() ? marginBottom : intValueForLength(style->marginBottom(), width);
+ marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width);
}
void Document::setIsViewSource(bool isViewSource)
@@ -1926,6 +2100,58 @@ void Document::setIsViewSource(bool isViewSource)
didUpdateSecurityOrigin();
}
+bool Document::dirtyElementsForLayerUpdate()
+{
+ if (m_layerUpdateSVGFilterElements.isEmpty())
+ return false;
+
+ for (WillBeHeapHashSet<RawPtrWillBeMember<Element> >::iterator it = m_layerUpdateSVGFilterElements.begin(), end = m_layerUpdateSVGFilterElements.end(); it != end; ++it)
+ (*it)->setNeedsStyleRecalc(LocalStyleChange);
+ m_layerUpdateSVGFilterElements.clear();
+ return true;
+}
+
+void Document::scheduleSVGFilterLayerUpdateHack(Element& element)
+{
+ if (element.styleChangeType() == NeedsReattachStyleChange)
+ return;
+ element.setSVGFilterNeedsLayerUpdate();
+ m_layerUpdateSVGFilterElements.add(&element);
+ scheduleRenderTreeUpdateIfNeeded();
+}
+
+void Document::unscheduleSVGFilterLayerUpdateHack(Element& element)
+{
+ element.clearSVGFilterNeedsLayerUpdate();
+ m_layerUpdateSVGFilterElements.remove(&element);
+}
+
+void Document::scheduleUseShadowTreeUpdate(SVGUseElement& element)
+{
+ m_useElementsNeedingUpdate.add(&element);
+ scheduleRenderTreeUpdateIfNeeded();
+}
+
+void Document::unscheduleUseShadowTreeUpdate(SVGUseElement& element)
+{
+ m_useElementsNeedingUpdate.remove(&element);
+}
+
+void Document::updateUseShadowTreesIfNeeded()
+{
+ ScriptForbiddenScope forbidScript;
+
+ if (m_useElementsNeedingUpdate.isEmpty())
+ return;
+
+ WillBeHeapVector<RawPtrWillBeMember<SVGUseElement> > elements;
+ copyToVector(m_useElementsNeedingUpdate, elements);
+ m_useElementsNeedingUpdate.clear();
+
+ for (WillBeHeapVector<RawPtrWillBeMember<SVGUseElement> >::iterator it = elements.begin(), end = elements.end(); it != end; ++it)
+ (*it)->buildPendingResource();
+}
+
StyleResolver* Document::styleResolver() const
{
return m_styleEngine->resolver();
@@ -1943,7 +2169,7 @@ void Document::clearStyleResolver()
void Document::attach(const AttachContext& context)
{
- ASSERT(m_lifecyle.state() == DocumentLifecycle::Inactive);
+ ASSERT(m_lifecycle.state() == DocumentLifecycle::Inactive);
ASSERT(!m_axObjectCache || this != topDocument());
m_renderView = new RenderView(this);
@@ -1951,22 +2177,28 @@ void Document::attach(const AttachContext& context)
m_renderView->setIsInWindow(true);
m_renderView->setStyle(StyleResolver::styleForDocument(*this));
- view()->updateCompositingLayersAfterStyleChange();
-
- m_styleEngine->didAttach();
+ m_renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
ContainerNode::attach(context);
- m_lifecyle.advanceTo(DocumentLifecycle::Active);
+ // FastTextAutosizer can't update render view info while the Document is detached, so update now in case anything changed.
+ if (FastTextAutosizer* textAutosizer = fastTextAutosizer())
+ textAutosizer->updatePageInfo();
+
+ m_lifecycle.advanceTo(DocumentLifecycle::StyleClean);
}
void Document::detach(const AttachContext& context)
{
ASSERT(isActive());
- m_lifecyle.advanceTo(DocumentLifecycle::Stopping);
+ m_lifecycle.advanceTo(DocumentLifecycle::Stopping);
if (page())
page()->documentDetached(this);
+ InspectorInstrumentation::documentDetached(this);
+
+ if (m_frame->loader().client()->sharedWorkerRepositoryClient())
+ m_frame->loader().client()->sharedWorkerRepositoryClient()->documentDetached(this);
if (this == topDocument())
clearAXObjectCache();
@@ -1979,16 +2211,14 @@ void Document::detach(const AttachContext& context)
m_scriptedAnimationController.clear();
if (svgExtensions())
- accessSVGExtensions()->pauseAnimations();
+ accessSVGExtensions().pauseAnimations();
- // FIXME: This shouldn't be needed once DOMWindow becomes ExecutionContext.
+ // FIXME: This shouldn't be needed once LocalDOMWindow becomes ExecutionContext.
if (m_domWindow)
m_domWindow->clearEventQueue();
- RenderView* renderView = m_renderView;
-
- if (renderView)
- renderView->setIsInWindow(false);
+ if (m_renderView)
+ m_renderView->setIsInWindow(false);
if (m_frame) {
FrameView* view = m_frame->view();
@@ -1996,28 +2226,20 @@ void Document::detach(const AttachContext& context)
view->detachCustomScrollbars();
}
- // Indicate destruction mode by setting the renderer to null.
- // FIXME: Don't do this and use m_lifecycle.state() == Stopping instead.
- setRenderer(0);
- m_renderView = 0;
-
- m_hoverNode = 0;
- m_focusedElement = 0;
- m_activeElement = 0;
+ m_hoverNode = nullptr;
+ m_focusedElement = nullptr;
+ m_activeHoverElement = nullptr;
+ m_autofocusElement = nullptr;
+ m_renderView = 0;
ContainerNode::detach(context);
- unscheduleStyleRecalc();
-
m_styleEngine->didDetach();
- if (renderView)
- renderView->destroy();
-
- if (m_touchEventTargets && m_touchEventTargets->size() && parentDocument())
- parentDocument()->didRemoveEventTargetNode(this);
+ if (Document* parentDoc = parentDocument())
+ parentDoc->didClearTouchEventHandlers(this);
- // This is required, as our Frame might delete itself as soon as it detaches
+ // This is required, as our LocalFrame might delete itself as soon as it detaches
// us. However, this violates Node::detach() semantics, as it's never
// possible to re-attach. Eventually Document::detach() should be renamed,
// or this setting of the frame to 0 could be made explicit in each of the
@@ -2028,7 +2250,18 @@ void Document::detach(const AttachContext& context)
m_mediaQueryMatcher->documentDestroyed();
lifecycleNotifier().notifyDocumentWasDetached();
- m_lifecyle.advanceTo(DocumentLifecycle::Stopped);
+ m_lifecycle.advanceTo(DocumentLifecycle::Stopped);
+#if ENABLE(OILPAN)
+ // This mirrors the clearing of the document object's touch
+ // handlers that happens when the LocalDOMWindow is destructed in a
+ // non-Oilpan setting (LocalDOMWindow::removeAllEventListeners()),
+ // except that it is now done during detach instead.
+ didClearTouchEventHandlers(this);
+
+ // Done with the window, explicitly clear to hasten its
+ // destruction.
+ clearDOMWindow();
+#endif
}
void Document::prepareForDestruction()
@@ -2040,19 +2273,17 @@ void Document::prepareForDestruction()
if (!isActive())
return;
- if (DOMWindow* window = this->domWindow())
+ if (LocalDOMWindow* window = this->domWindow())
window->willDetachDocumentFromFrame();
detach();
}
void Document::removeAllEventListeners()
{
- EventTarget::removeAllEventListeners();
+ ContainerNode::removeAllEventListeners();
- if (DOMWindow* domWindow = this->domWindow())
+ if (LocalDOMWindow* domWindow = this->domWindow())
domWindow->removeAllEventListeners();
- for (Node* node = firstChild(); node; node = NodeTraversal::next(*node))
- node->removeAllEventListeners();
}
void Document::clearAXObjectCache()
@@ -2070,10 +2301,10 @@ AXObjectCache* Document::existingAXObjectCache() const
// If the renderer is gone then we are in the process of destruction.
// This method will be called before m_frame = 0.
- if (!topDocument()->renderView())
+ if (!topDocument().renderView())
return 0;
- return topDocument()->m_axObjectCache.get();
+ return topDocument().m_axObjectCache.get();
}
AXObjectCache* Document::axObjectCache() const
@@ -2085,43 +2316,33 @@ AXObjectCache* Document::axObjectCache() const
// document. This is because we need to be able to get from any WebCoreAXObject
// to any other WebCoreAXObject on the same page. Using a single cache allows
// lookups across nested webareas (i.e. multiple documents).
- Document* topDocument = this->topDocument();
+ Document& topDocument = this->topDocument();
// If the document has already been detached, do not make a new axObjectCache.
- if (!topDocument->renderView())
+ if (!topDocument.renderView())
return 0;
ASSERT(topDocument == this || !m_axObjectCache);
- if (!topDocument->m_axObjectCache)
- topDocument->m_axObjectCache = adoptPtr(new AXObjectCache(topDocument));
- return topDocument->m_axObjectCache.get();
+ if (!topDocument.m_axObjectCache)
+ topDocument.m_axObjectCache = adoptPtr(new AXObjectCache(topDocument));
+ return topDocument.m_axObjectCache.get();
}
-void Document::setVisuallyOrdered()
-{
- m_visuallyOrdered = true;
- // FIXME: How is possible to not have a renderer here?
- if (renderView())
- renderView()->style()->setRTLOrdering(VisualOrder);
- setNeedsStyleRecalc();
-}
-
-PassRefPtr<DocumentParser> Document::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> Document::createParser()
{
if (isHTMLDocument()) {
- bool reportErrors = InspectorInstrumentation::collectingHTMLParseErrors(this->page());
- return HTMLDocumentParser::create(toHTMLDocument(this), reportErrors);
+ bool reportErrors = InspectorInstrumentation::collectingHTMLParseErrors(page());
+ return HTMLDocumentParser::create(toHTMLDocument(*this), reportErrors);
}
// FIXME: this should probably pass the frame instead
- return XMLDocumentParser::create(this, view());
+ return XMLDocumentParser::create(*this, view());
}
bool Document::isFrameSet() const
{
if (!isHTMLDocument())
return false;
- HTMLElement* bodyElement = body();
- return bodyElement && bodyElement->hasTagName(framesetTag);
+ return isHTMLFrameSetElement(body());
}
ScriptableDocumentParser* Document::scriptableDocumentParser() const
@@ -2129,8 +2350,13 @@ ScriptableDocumentParser* Document::scriptableDocumentParser() const
return parser() ? parser()->asScriptableDocumentParser() : 0;
}
-void Document::open(Document* ownerDocument)
+void Document::open(Document* ownerDocument, ExceptionState& exceptionState)
{
+ if (importLoader()) {
+ exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support open().");
+ return;
+ }
+
if (ownerDocument) {
setURL(ownerDocument->url());
m_cookieURL = ownerDocument->cookieURL();
@@ -2153,7 +2379,7 @@ void Document::open(Document* ownerDocument)
m_frame->loader().stopAllLoaders();
}
- removeAllEventListeners();
+ removeAllEventListenersRecursively();
implicitOpen();
if (ScriptableDocumentParser* parser = scriptableDocumentParser())
parser->setWasCreatedByScript(true);
@@ -2185,7 +2411,7 @@ void Document::cancelParsing()
explicitClose();
}
-PassRefPtr<DocumentParser> Document::implicitOpen()
+PassRefPtrWillBeRawPtr<DocumentParser> Document::implicitOpen()
{
cancelParsing();
@@ -2194,12 +2420,6 @@ PassRefPtr<DocumentParser> Document::implicitOpen()
setCompatibilityMode(NoQuirksMode);
- // Documents rendered seamlessly should start out requiring a stylesheet
- // collection update in order to ensure they inherit all the relevant data
- // from their parent.
- if (shouldDisplaySeamlesslyWithParent())
- styleResolverChanged(RecalcStyleDeferred);
-
m_parser = createParser();
setParsing(true);
setReadyState(Loading);
@@ -2212,25 +2432,29 @@ HTMLElement* Document::body() const
if (!documentElement())
return 0;
- for (Node* child = documentElement()->firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(framesetTag) || child->hasTagName(bodyTag))
- return toHTMLElement(child);
+ for (HTMLElement* child = Traversal<HTMLElement>::firstWithin(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ if (isHTMLFrameSetElement(*child) || isHTMLBodyElement(*child))
+ return child;
}
return 0;
}
-void Document::setBody(PassRefPtr<HTMLElement> prpNewBody, ExceptionState& exceptionState)
+void Document::setBody(PassRefPtrWillBeRawPtr<HTMLElement> prpNewBody, ExceptionState& exceptionState)
{
- RefPtr<HTMLElement> newBody = prpNewBody;
+ RefPtrWillBeRawPtr<HTMLElement> newBody = prpNewBody;
- if (!newBody || !documentElement()) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ if (!newBody) {
+ exceptionState.throwDOMException(HierarchyRequestError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLElement"));
+ return;
+ }
+ if (!documentElement()) {
+ exceptionState.throwDOMException(HierarchyRequestError, "No document element exists.");
return;
}
- if (!newBody->hasTagName(bodyTag) && !newBody->hasTagName(framesetTag)) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ if (!isHTMLBodyElement(*newBody) && !isHTMLFrameSetElement(*newBody)) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The new body element is of type '" + newBody->tagName() + "'. It must be either a 'BODY' or 'FRAMESET' element.");
return;
}
@@ -2244,24 +2468,47 @@ void Document::setBody(PassRefPtr<HTMLElement> prpNewBody, ExceptionState& excep
documentElement()->appendChild(newBody.release(), exceptionState);
}
-HTMLHeadElement* Document::head()
+HTMLHeadElement* Document::head() const
{
Node* de = documentElement();
if (!de)
return 0;
- for (Node* node = de->firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(headTag))
- return toHTMLHeadElement(node);
+ return Traversal<HTMLHeadElement>::firstChild(*de);
+}
+
+Element* Document::viewportDefiningElement(RenderStyle* rootStyle) const
+{
+ // If a BODY element sets non-visible overflow, it is to be propagated to the viewport, as long
+ // as the following conditions are all met:
+ // (1) The root element is HTML.
+ // (2) It is the primary BODY element (we only assert for this, expecting callers to behave).
+ // (3) The root element has visible overflow.
+ // Otherwise it's the root element's properties that are to be propagated.
+ Element* rootElement = documentElement();
+ Element* bodyElement = body();
+ if (!rootElement)
+ return 0;
+ if (!rootStyle) {
+ rootStyle = rootElement->renderStyle();
+ if (!rootStyle)
+ return 0;
}
- return 0;
+ if (bodyElement && rootStyle->isOverflowVisible() && isHTMLHtmlElement(*rootElement))
+ return bodyElement;
+ return rootElement;
}
-void Document::close()
+void Document::close(ExceptionState& exceptionState)
{
// FIXME: We should follow the specification more closely:
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-close
+ if (importLoader()) {
+ exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support close().");
+ return;
+ }
+
if (!scriptableDocumentParser() || !scriptableDocumentParser()->wasCreatedByScript() || !scriptableDocumentParser()->isParsing())
return;
@@ -2270,7 +2517,7 @@ void Document::close()
void Document::explicitClose()
{
- if (RefPtr<DocumentParser> parser = m_parser)
+ if (RefPtrWillBeRawPtr<DocumentParser> parser = m_parser)
parser->finish();
if (!m_frame) {
@@ -2298,9 +2545,9 @@ void Document::implicitClose()
if (!doload)
return;
- // The call to dispatchWindowLoadEvent can detach the DOMWindow and cause it (and its
+ // The call to dispatchWindowLoadEvent can detach the LocalDOMWindow and cause it (and its
// attached Document) to be destroyed.
- RefPtr<DOMWindow> protectedWindow(this->domWindow());
+ RefPtrWillBeRawPtr<LocalDOMWindow> protectedWindow(this->domWindow());
m_loadEventProgress = LoadEventInProgress;
@@ -2312,7 +2559,6 @@ void Document::implicitClose()
detachParser();
if (frame() && frame()->script().canExecuteScripts(NotAboutToExecuteScript)) {
- ImageLoader::dispatchPendingBeforeLoadEvents();
ImageLoader::dispatchPendingLoadEvents();
ImageLoader::dispatchPendingErrorEvents();
@@ -2324,10 +2570,9 @@ void Document::implicitClose()
// those two functions repeatedly and don't save them on the stack.
// To align the HTML load event and the SVGLoad event for the outermost <svg> element, fire it from
- // here, instead of doing it from SVGElement::finishedParsingChildren (if externalResourcesRequired="false",
- // which is the default, for ='true' its fired at a later time, once all external resources finished loading).
+ // here, instead of doing it from SVGElement::finishedParsingChildren.
if (svgExtensions())
- accessSVGExtensions()->dispatchSVGLoadEventToOutermostSVGElements();
+ accessSVGExtensions().dispatchSVGLoadEventToOutermostSVGElements();
if (protectedWindow)
protectedWindow->documentWasClosed();
@@ -2350,16 +2595,14 @@ void Document::implicitClose()
// Just bail out. Before or during the onload we were shifted to another page.
// The old i-Bench suite does this. When this happens don't bother painting or laying out.
m_loadEventProgress = LoadEventCompleted;
- view()->unscheduleRelayout();
return;
}
// We used to force a synchronous display and flush here. This really isn't
// necessary and can in fact be actively harmful if pages are loading at a rate of > 60fps
// (if your platform is syncing flushes and limiting them to 60fps).
- m_overMinimumLayoutThreshold = true;
if (!ownerElement() || (ownerElement()->renderer() && !ownerElement()->renderer()->needsLayout())) {
- updateStyleIfNeeded();
+ updateRenderTreeIfNeeded();
// Always do a layout after loading if needed.
if (view() && renderView() && (!renderView()->firstChild() || renderView()->needsLayout()))
@@ -2386,7 +2629,7 @@ void Document::implicitClose()
}
if (svgExtensions())
- accessSVGExtensions()->startAnimations();
+ accessSVGExtensions().startAnimations();
}
bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigation)
@@ -2397,9 +2640,9 @@ bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigatio
if (!body())
return true;
- RefPtr<Document> protect(this);
+ RefPtrWillBeRawPtr<Document> protect(this);
- RefPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
+ RefPtrWillBeRawPtr<BeforeUnloadEvent> beforeUnloadEvent = BeforeUnloadEvent::create();
m_loadEventProgress = BeforeUnloadEventInProgress;
m_domWindow->dispatchEvent(beforeUnloadEvent.get(), this);
m_loadEventProgress = BeforeUnloadEventCompleted;
@@ -2423,17 +2666,17 @@ bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigatio
void Document::dispatchUnloadEvents()
{
- RefPtr<Document> protect(this);
+ RefPtrWillBeRawPtr<Document> protect(this);
if (m_parser)
m_parser->stopParsing();
if (m_loadEventProgress >= LoadEventTried && m_loadEventProgress <= UnloadEventInProgress) {
Element* currentFocusedElement = focusedElement();
- if (currentFocusedElement && currentFocusedElement->hasTagName(inputTag))
- toHTMLInputElement(currentFocusedElement)->endEditing();
+ if (isHTMLInputElement(currentFocusedElement))
+ toHTMLInputElement(*currentFocusedElement).endEditing();
if (m_loadEventProgress < PageHideInProgress) {
m_loadEventProgress = PageHideInProgress;
- if (DOMWindow* window = domWindow())
+ if (LocalDOMWindow* window = domWindow())
window->dispatchEvent(PageTransitionEvent::create(EventTypeNames::pagehide, false), this);
if (!m_frame)
return;
@@ -2443,7 +2686,7 @@ void Document::dispatchUnloadEvents()
// time into freed memory.
RefPtr<DocumentLoader> documentLoader = m_frame->loader().provisionalDocumentLoader();
m_loadEventProgress = UnloadEventInProgress;
- RefPtr<Event> unloadEvent(Event::create(EventTypeNames::unload));
+ RefPtrWillBeRawPtr<Event> unloadEvent(Event::create(EventTypeNames::unload));
if (documentLoader && !documentLoader->timing()->unloadEventStart() && !documentLoader->timing()->unloadEventEnd()) {
DocumentLoadTiming* timing = documentLoader->timing();
ASSERT(timing->navigationStart());
@@ -2464,7 +2707,7 @@ void Document::dispatchUnloadEvents()
bool keepEventListeners = m_frame->loader().stateMachine()->isDisplayingInitialEmptyDocument() && m_frame->loader().provisionalDocumentLoader()
&& isSecureTransitionTo(m_frame->loader().provisionalDocumentLoader()->url());
if (!keepEventListeners)
- removeAllEventListeners();
+ removeAllEventListenersRecursively();
}
Document::PageDismissalType Document::pageDismissalEventBeingDispatched() const
@@ -2480,42 +2723,29 @@ Document::PageDismissalType Document::pageDismissalEventBeingDispatched() const
void Document::setParsing(bool b)
{
- m_bParsing = b;
-
- if (m_bParsing && !m_sharedObjectPool)
- m_sharedObjectPool = DocumentSharedObjectPool::create();
+ m_isParsing = b;
- if (!m_bParsing && view())
- view()->scheduleRelayout();
+ if (m_isParsing && !m_elementDataCache)
+ m_elementDataCache = ElementDataCache::create();
}
-bool Document::shouldScheduleLayout()
+bool Document::shouldScheduleLayout() const
{
// This function will only be called when FrameView thinks a layout is needed.
// This enforces a couple extra rules.
//
// (a) Only schedule a layout once the stylesheets are loaded.
// (b) Only schedule layout once we have a body element.
+ if (!isActive())
+ return false;
- return (haveStylesheetsLoaded() && body())
- || (documentElement() && !isHTMLHtmlElement(documentElement()));
-}
-
-bool Document::shouldParserYieldAgressivelyBeforeScriptExecution()
-{
- return view() && view()->layoutPending() && !minimumLayoutDelay();
-}
-
-int Document::minimumLayoutDelay()
-{
- if (m_overMinimumLayoutThreshold)
- return 0;
+ if (isRenderingReady() && body())
+ return true;
- int elapsed = elapsedTime();
- m_overMinimumLayoutThreshold = elapsed > cLayoutScheduleThreshold;
+ if (documentElement() && !isHTMLHtmlElement(*documentElement()))
+ return true;
- // We'll want to schedule the timer to fire at the minimum layout threshold.
- return max(0, cLayoutScheduleThreshold - elapsed);
+ return false;
}
int Document::elapsedTime() const
@@ -2523,8 +2753,13 @@ int Document::elapsedTime() const
return static_cast<int>((currentTime() - m_startTime) * 1000);
}
-void Document::write(const SegmentedString& text, Document* ownerDocument)
+void Document::write(const SegmentedString& text, Document* ownerDocument, ExceptionState& exceptionState)
{
+ if (importLoader()) {
+ exceptionState.throwDOMException(InvalidStateError, "Imported document doesn't support write().");
+ return;
+ }
+
NestingLevelIncrementer nestingLevelIncrementer(m_writeRecursionDepth);
m_writeRecursionIsTooDeep = (m_writeRecursionDepth > 1) && m_writeRecursionIsTooDeep;
@@ -2534,8 +2769,11 @@ void Document::write(const SegmentedString& text, Document* ownerDocument)
return;
bool hasInsertionPoint = m_parser && m_parser->hasInsertionPoint();
- if (!hasInsertionPoint && m_ignoreDestructiveWriteCount)
+
+ if (!hasInsertionPoint && m_ignoreDestructiveWriteCount) {
+ addConsoleMessage(JSMessageSource, WarningMessageLevel, ExceptionMessages::failedToExecute("write", "Document", "It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened."));
return;
+ }
if (!hasInsertionPoint)
open(ownerDocument);
@@ -2544,14 +2782,16 @@ void Document::write(const SegmentedString& text, Document* ownerDocument)
m_parser->insert(text);
}
-void Document::write(const String& text, Document* ownerDocument)
+void Document::write(const String& text, Document* ownerDocument, ExceptionState& exceptionState)
{
- write(SegmentedString(text), ownerDocument);
+ write(SegmentedString(text), ownerDocument, exceptionState);
}
-void Document::writeln(const String& text, Document* ownerDocument)
+void Document::writeln(const String& text, Document* ownerDocument, ExceptionState& exceptionState)
{
- write(text, ownerDocument);
+ write(text, ownerDocument, exceptionState);
+ if (exceptionState.hadException())
+ return;
write("\n", ownerDocument);
}
@@ -2578,7 +2818,7 @@ EventTarget* Document::errorEventTarget()
return domWindow();
}
-void Document::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+void Document::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
{
internalAddMessage(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, callStack, 0);
}
@@ -2590,9 +2830,8 @@ void Document::setURL(const KURL& url)
return;
m_url = newURL;
- m_documentURI = m_url.string();
updateBaseURL();
- contextFeatures()->urlDidChange(this);
+ contextFeatures().urlDidChange(this);
}
void Document::updateBaseURL()
@@ -2600,18 +2839,14 @@ void Document::updateBaseURL()
KURL oldBaseURL = m_baseURL;
// DOM 3 Core: When the Document supports the feature "HTML" [DOM Level 2 HTML], the base URI is computed using
// first the value of the href attribute of the HTML BASE element if any, and the value of the documentURI attribute
- // from the Document interface otherwise.
+ // from the Document interface otherwise (which we store, preparsed, in m_url).
if (!m_baseElementURL.isEmpty())
m_baseURL = m_baseElementURL;
else if (!m_baseURLOverride.isEmpty())
m_baseURL = m_baseURLOverride;
- else {
- // The documentURI attribute is read-only from JavaScript, but writable from Objective C, so we need to retain
- // this fallback behavior. We use a null base URL, since the documentURI attribute is an arbitrary string
- // and DOM 3 Core does not specify how it should be resolved.
- // FIXME: Now that we don't support Objective-C this can probably be removed.
- m_baseURL = KURL(ParsedURLString, documentURI());
- }
+ else
+ m_baseURL = m_url;
+
selectorQueryCache().invalidate();
if (!m_baseURL.isValid())
@@ -2629,10 +2864,8 @@ void Document::updateBaseURL()
if (!equalIgnoringFragmentIdentifier(oldBaseURL, m_baseURL)) {
// Base URL change changes any relative visited links.
// FIXME: There are other URLs in the tree that would need to be re-evaluated on dynamic base URL change. Style should be invalidated too.
- for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element)) {
- if (isHTMLAnchorElement(element))
- toHTMLAnchorElement(element)->invalidateCachedVisitedLinkHash();
- }
+ for (HTMLAnchorElement* anchor = Traversal<HTMLAnchorElement>::firstWithin(*this); anchor; anchor = Traversal<HTMLAnchorElement>::next(*anchor))
+ anchor->invalidateCachedVisitedLinkHash();
}
}
@@ -2647,21 +2880,19 @@ void Document::processBaseElement()
// Find the first href attribute in a base element and the first target attribute in a base element.
const AtomicString* href = 0;
const AtomicString* target = 0;
- for (Element* element = ElementTraversal::firstWithin(*this); element && (!href || !target); element = ElementTraversal::next(*element)) {
- if (element->hasTagName(baseTag)) {
- if (!href) {
- const AtomicString& value = element->fastGetAttribute(hrefAttr);
- if (!value.isNull())
- href = &value;
- }
- if (!target) {
- const AtomicString& value = element->fastGetAttribute(targetAttr);
- if (!value.isNull())
- target = &value;
- }
- if (contentSecurityPolicy()->isActive())
- UseCounter::count(*this, UseCounter::ContentSecurityPolicyWithBaseElement);
+ for (HTMLBaseElement* base = Traversal<HTMLBaseElement>::firstWithin(*this); base && (!href || !target); base = Traversal<HTMLBaseElement>::next(*base)) {
+ if (!href) {
+ const AtomicString& value = base->fastGetAttribute(hrefAttr);
+ if (!value.isNull())
+ href = &value;
+ }
+ if (!target) {
+ const AtomicString& value = base->fastGetAttribute(targetAttr);
+ if (!value.isNull())
+ target = &value;
}
+ if (contentSecurityPolicy()->isActive())
+ UseCounter::count(*this, UseCounter::ContentSecurityPolicyWithBaseElement);
}
// FIXME: Since this doesn't share code with completeURL it may not handle encodings correctly.
@@ -2692,30 +2923,24 @@ void Document::disableEval(const String& errorMessage)
frame()->script().disableEval(errorMessage);
}
-bool Document::canNavigate(Frame* targetFrame)
+bool Document::canNavigate(const Frame& targetFrame)
{
if (!m_frame)
return false;
- // FIXME: We shouldn't call this function without a target frame, but
- // fast/forms/submit-to-blank-multiple-times.html depends on this function
- // returning true when supplied with a 0 targetFrame.
- if (!targetFrame)
- return true;
-
// Frame-busting is generally allowed, but blocked for sandboxed frames lacking the 'allow-top-navigation' flag.
if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top())
return true;
if (isSandboxed(SandboxNavigation)) {
- if (targetFrame->tree().isDescendantOf(m_frame))
+ if (targetFrame.tree().isDescendantOf(m_frame))
return true;
const char* reason = "The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors.";
if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top())
reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set.";
- printNavigationErrorMessage(*targetFrame, url(), reason);
+ printNavigationErrorMessage(toLocalFrameTemporary(targetFrame), url(), reason);
return false;
}
@@ -2729,7 +2954,7 @@ bool Document::canNavigate(Frame* targetFrame)
//
// See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for
// historical information about this security check.
- if (canAccessAncestor(origin, targetFrame))
+ if (canAccessAncestor(origin, &targetFrame))
return true;
// Top-level frames are easier to navigate than other frames because they
@@ -2743,100 +2968,112 @@ bool Document::canNavigate(Frame* targetFrame)
// some way related to the frame being navigate (e.g., by the "opener"
// and/or "parent" relation). Requiring some sort of relation prevents a
// document from navigating arbitrary, unrelated top-level frames.
- if (!targetFrame->tree().parent()) {
+ if (!targetFrame.tree().parent()) {
if (targetFrame == m_frame->loader().opener())
return true;
- if (canAccessAncestor(origin, targetFrame->loader().opener()))
+ // FIXME: We don't have access to RemoteFrame's opener yet.
+ if (targetFrame.isLocalFrame() && canAccessAncestor(origin, toLocalFrame(targetFrame).loader().opener()))
return true;
}
- printNavigationErrorMessage(*targetFrame, url(), "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.");
+ printNavigationErrorMessage(toLocalFrameTemporary(targetFrame), url(), "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.");
return false;
}
-Frame* Document::findUnsafeParentScrollPropagationBoundary()
+LocalFrame* Document::findUnsafeParentScrollPropagationBoundary()
{
- Frame* currentFrame = m_frame;
+ LocalFrame* currentFrame = m_frame;
Frame* ancestorFrame = currentFrame->tree().parent();
while (ancestorFrame) {
- if (!ancestorFrame->document()->securityOrigin()->canAccess(securityOrigin()))
+ // FIXME: We don't yet have access to a RemoteFrame's security origin.
+ if (!ancestorFrame->isLocalFrame())
return currentFrame;
- currentFrame = ancestorFrame;
+ if (!toLocalFrame(ancestorFrame)->document()->securityOrigin()->canAccess(securityOrigin()))
+ return currentFrame;
+ currentFrame = toLocalFrame(ancestorFrame);
ancestorFrame = ancestorFrame->tree().parent();
}
return 0;
}
-
-void Document::seamlessParentUpdatedStylesheets()
+void Document::didLoadAllImports()
{
- m_styleEngine->didModifySeamlessParentStyleSheet();
- styleResolverChanged(RecalcStyleImmediately);
+ if (!haveStylesheetsLoaded())
+ return;
+ if (!importLoader())
+ styleResolverMayHaveChanged();
+ didLoadAllScriptBlockingResources();
}
void Document::didRemoveAllPendingStylesheet()
{
- m_needsNotifyRemoveAllPendingStylesheet = false;
+ styleResolverMayHaveChanged();
+
+ // Only imports on master documents can trigger rendering.
+ if (HTMLImportLoader* import = importLoader())
+ import->didRemoveAllPendingStylesheet();
+ if (!haveImportsLoaded())
+ return;
+ didLoadAllScriptBlockingResources();
+}
- styleResolverChanged(RecalcStyleDeferred, AnalyzedStyleUpdate);
- executeScriptsWaitingForResourcesIfNeeded();
+void Document::didLoadAllScriptBlockingResources()
+{
+ m_executeScriptsWaitingForResourcesTimer.startOneShot(0, FROM_HERE);
if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
view()->scrollToFragment(m_url);
}
-void Document::executeScriptsWaitingForResourcesIfNeeded()
+void Document::executeScriptsWaitingForResourcesTimerFired(Timer<Document>*)
{
- if (!haveStylesheetsAndImportsLoaded())
+ if (!isRenderingReady())
return;
if (ScriptableDocumentParser* parser = scriptableDocumentParser())
parser->executeScriptsWaitingForResources();
}
-
-CSSStyleSheet* Document::elementSheet()
+CSSStyleSheet& Document::elementSheet()
{
if (!m_elemSheet)
m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
- return m_elemSheet.get();
+ return *m_elemSheet;
}
-void Document::processHttpEquiv(const AtomicString& equiv, const AtomicString& content)
+void Document::processHttpEquiv(const AtomicString& equiv, const AtomicString& content, bool inDocumentHeadElement)
{
ASSERT(!equiv.isNull() && !content.isNull());
- if (equalIgnoringCase(equiv, "default-style"))
+ if (equalIgnoringCase(equiv, "default-style")) {
processHttpEquivDefaultStyle(content);
- else if (equalIgnoringCase(equiv, "refresh"))
+ } else if (equalIgnoringCase(equiv, "refresh")) {
processHttpEquivRefresh(content);
- else if (equalIgnoringCase(equiv, "set-cookie"))
+ } else if (equalIgnoringCase(equiv, "set-cookie")) {
processHttpEquivSetCookie(content);
- else if (equalIgnoringCase(equiv, "content-language"))
+ } else if (equalIgnoringCase(equiv, "content-language")) {
setContentLanguage(content);
- else if (equalIgnoringCase(equiv, "x-dns-prefetch-control"))
+ } else if (equalIgnoringCase(equiv, "x-dns-prefetch-control")) {
parseDNSPrefetchControlHeader(content);
- else if (equalIgnoringCase(equiv, "x-frame-options"))
+ } else if (equalIgnoringCase(equiv, "x-frame-options")) {
processHttpEquivXFrameOptions(content);
- else if (equalIgnoringCase(equiv, "content-security-policy")
- || equalIgnoringCase(equiv, "content-security-policy-report-only")
- || equalIgnoringCase(equiv, "x-webkit-csp")
- || equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
- processHttpEquivContentSecurityPolicy(equiv, content);
+ } else if (equalIgnoringCase(equiv, "content-security-policy") || equalIgnoringCase(equiv, "content-security-policy-report-only")) {
+ if (inDocumentHeadElement)
+ processHttpEquivContentSecurityPolicy(equiv, content);
+ else
+ contentSecurityPolicy()->reportMetaOutsideHead(content);
+ }
}
void Document::processHttpEquivContentSecurityPolicy(const AtomicString& equiv, const AtomicString& content)
{
+ if (importLoader())
+ return;
if (equalIgnoringCase(equiv, "content-security-policy"))
- contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Enforce);
+ contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceMeta);
else if (equalIgnoringCase(equiv, "content-security-policy-report-only"))
- contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Report);
- // FIXME: Remove deprecation messages after the next release branch.
- else if (equalIgnoringCase(equiv, "x-webkit-csp"))
- UseCounter::countDeprecation(this, UseCounter::PrefixedContentSecurityPolicy);
- else if (equalIgnoringCase(equiv, "x-webkit-csp-report-only"))
- UseCounter::countDeprecation(this, UseCounter::PrefixedContentSecurityPolicyReportOnly);
+ contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderTypeReport, ContentSecurityPolicyHeaderSourceMeta);
else
ASSERT_NOT_REACHED();
}
@@ -2851,7 +3088,7 @@ void Document::processHttpEquivDefaultStyle(const AtomicString& content)
// -dwh
m_styleEngine->setSelectedStylesheetSetName(content);
m_styleEngine->setPreferredStylesheetSetName(content);
- styleResolverChanged(RecalcStyleDeferred);
+ styleResolverChanged();
}
void Document::processHttpEquivRefresh(const AtomicString& content)
@@ -2899,7 +3136,7 @@ void Document::processHttpEquivSetCookie(const AtomicString& content)
void Document::processHttpEquivXFrameOptions(const AtomicString& content)
{
- Frame* frame = this->frame();
+ LocalFrame* frame = this->frame();
if (!frame)
return;
@@ -2911,7 +3148,7 @@ void Document::processHttpEquivXFrameOptions(const AtomicString& content)
// Stopping the loader isn't enough, as we're already parsing the document; to honor the header's
// intent, we must navigate away from the possibly partially-rendered document to a location that
// doesn't inherit the parent's SecurityOrigin.
- frame->navigationScheduler().scheduleLocationChange(this, SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+ frame->navigationScheduler().scheduleLocationChange(this, SecurityOrigin::urlWithUniqueSecurityOrigin(), Referrer());
addConsoleMessageWithRequestIdentifier(SecurityMessageSource, ErrorMessageLevel, message, requestIdentifier);
}
}
@@ -2923,6 +3160,10 @@ bool Document::shouldMergeWithLegacyDescription(ViewportDescription::Type origin
void Document::setViewportDescription(const ViewportDescription& viewportDescription)
{
+ // The UA-defined min-width is used by the processing of legacy meta tags.
+ if (!viewportDescription.isSpecifiedByAuthor())
+ m_viewportDefaultMinWidth = viewportDescription.minWidth;
+
if (viewportDescription.isLegacyViewportType()) {
if (settings() && !settings()->viewportMetaEnabled())
return;
@@ -2952,7 +3193,7 @@ void Document::updateViewportDescription()
#ifndef NDEBUG
m_didDispatchViewportPropertiesChanged = true;
#endif
- page()->chrome().dispatchViewportPropertiesDidChange(m_viewportDescription);
+ frameHost()->chrome().dispatchViewportPropertiesDidChange(m_viewportDescription);
}
}
@@ -2960,14 +3201,28 @@ void Document::processReferrerPolicy(const String& policy)
{
ASSERT(!policy.isNull());
- m_referrerPolicy = ReferrerPolicyDefault;
+ if (equalIgnoringCase(policy, "never")) {
+ setReferrerPolicy(ReferrerPolicyNever);
+ } else if (equalIgnoringCase(policy, "always")) {
+ setReferrerPolicy(ReferrerPolicyAlways);
+ } else if (equalIgnoringCase(policy, "origin")) {
+ setReferrerPolicy(ReferrerPolicyOrigin);
+ } else if (equalIgnoringCase(policy, "default")) {
+ setReferrerPolicy(ReferrerPolicyDefault);
+ } else {
+ addConsoleMessage(RenderingMessageSource, ErrorMessageLevel, "Failed to set referrer policy: The value '" + policy + "' is not one of 'always', 'default', 'never', or 'origin'. Defaulting to 'never'.");
+ setReferrerPolicy(ReferrerPolicyNever);
+ }
+}
+
+void Document::setReferrerPolicy(ReferrerPolicy referrerPolicy)
+{
+ // FIXME: Can we adopt the CSP referrer policy merge algorithm? Or does the web rely on being able to modify the referrer policy in-flight?
+ if (m_didSetReferrerPolicy)
+ UseCounter::count(this, UseCounter::ResetReferrerPolicy);
+ m_didSetReferrerPolicy = true;
- if (equalIgnoringCase(policy, "never"))
- m_referrerPolicy = ReferrerPolicyNever;
- else if (equalIgnoringCase(policy, "always"))
- m_referrerPolicy = ReferrerPolicyAlways;
- else if (equalIgnoringCase(policy, "origin"))
- m_referrerPolicy = ReferrerPolicyOrigin;
+ m_referrerPolicy = referrerPolicy;
}
String Document::outgoingReferrer()
@@ -2975,9 +3230,10 @@ String Document::outgoingReferrer()
// See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources
// for why we walk the parent chain for srcdoc documents.
Document* referrerDocument = this;
- if (Frame* frame = m_frame) {
+ if (LocalFrame* frame = m_frame) {
while (frame->document()->isSrcdocDocument()) {
- frame = frame->tree().parent();
+ // Srcdoc documents must be local within the containing frame.
+ frame = toLocalFrame(frame->tree().parent());
// Srcdoc documents cannot be top-level documents, by definition,
// because they need to be contained in iframes with the srcdoc.
ASSERT(frame);
@@ -3022,10 +3278,7 @@ bool Document::childTypeAllowed(NodeType type) const
case CDATA_SECTION_NODE:
case DOCUMENT_FRAGMENT_NODE:
case DOCUMENT_NODE:
- case ENTITY_NODE:
- case NOTATION_NODE:
case TEXT_NODE:
- case XPATH_NAMESPACE_NODE:
return false;
case COMMENT_NODE:
case PROCESSING_INSTRUCTION_NODE:
@@ -3069,17 +3322,14 @@ bool Document::canReplaceChild(const Node& newChild, const Node& oldChild) const
}
// Then, see how many doctypes and elements might be added by the new child.
- if (newChild.nodeType() == DOCUMENT_FRAGMENT_NODE) {
- for (Node* c = newChild.firstChild(); c; c = c->nextSibling()) {
+ if (newChild.isDocumentFragment()) {
+ for (Node* c = toDocumentFragment(newChild).firstChild(); c; c = c->nextSibling()) {
switch (c->nodeType()) {
case ATTRIBUTE_NODE:
case CDATA_SECTION_NODE:
case DOCUMENT_FRAGMENT_NODE:
case DOCUMENT_NODE:
- case ENTITY_NODE:
- case NOTATION_NODE:
case TEXT_NODE:
- case XPATH_NAMESPACE_NODE:
return false;
case COMMENT_NODE:
case PROCESSING_INSTRUCTION_NODE:
@@ -3098,10 +3348,7 @@ bool Document::canReplaceChild(const Node& newChild, const Node& oldChild) const
case CDATA_SECTION_NODE:
case DOCUMENT_FRAGMENT_NODE:
case DOCUMENT_NODE:
- case ENTITY_NODE:
- case NOTATION_NODE:
case TEXT_NODE:
- case XPATH_NAMESPACE_NODE:
return false;
case COMMENT_NODE:
case PROCESSING_INSTRUCTION_NODE:
@@ -3121,20 +3368,23 @@ bool Document::canReplaceChild(const Node& newChild, const Node& oldChild) const
return true;
}
-PassRefPtr<Node> Document::cloneNode(bool deep)
+PassRefPtrWillBeRawPtr<Node> Document::cloneNode(bool deep)
{
- RefPtr<Document> clone = cloneDocumentWithoutChildren();
+ RefPtrWillBeRawPtr<Document> clone = cloneDocumentWithoutChildren();
clone->cloneDataFromDocument(*this);
if (deep)
cloneChildNodes(clone.get());
return clone.release();
}
-PassRefPtr<Document> Document::cloneDocumentWithoutChildren()
+PassRefPtrWillBeRawPtr<Document> Document::cloneDocumentWithoutChildren()
{
DocumentInit init(url());
- if (isXHTMLDocument())
- return createXHTML(init.withRegistrationContext(registrationContext()));
+ if (isXMLDocument()) {
+ if (isXHTMLDocument())
+ return XMLDocument::createXHTML(init.withRegistrationContext(registrationContext()));
+ return XMLDocument::create(init);
+ }
return create(init);
}
@@ -3144,6 +3394,7 @@ void Document::cloneDataFromDocument(const Document& other)
setEncodingData(other.m_encodingData);
setContextFeatures(other.contextFeatures());
setSecurityOrigin(other.securityOrigin()->isolatedCopy());
+ setMimeType(other.contentType());
}
StyleSheetList* Document::styleSheets()
@@ -3166,7 +3417,15 @@ String Document::selectedStylesheetSet() const
void Document::setSelectedStylesheetSet(const String& aString)
{
m_styleEngine->setSelectedStylesheetSetName(aString);
- styleResolverChanged(RecalcStyleDeferred);
+ styleResolverChanged();
+}
+
+void Document::evaluateMediaQueryListIfNeeded()
+{
+ if (!m_evaluateMediaQueriesOnStyleRecalc)
+ return;
+ evaluateMediaQueryList();
+ m_evaluateMediaQueriesOnStyleRecalc = false;
}
void Document::evaluateMediaQueryList()
@@ -3175,60 +3434,49 @@ void Document::evaluateMediaQueryList()
m_mediaQueryMatcher->styleResolverChanged();
}
-void Document::styleResolverChanged(RecalcStyleTime updateTime, StyleResolverUpdateMode updateMode)
+void Document::notifyResizeForViewportUnits()
+{
+ if (!hasViewportUnits())
+ return;
+ ensureStyleResolver().notifyResizeForViewportUnits();
+ setNeedsStyleRecalcForViewportUnits();
+}
+
+void Document::styleResolverChanged(StyleResolverUpdateMode updateMode)
{
// styleResolverChanged() can be invoked during Document destruction.
// We just skip that case.
if (!m_styleEngine)
return;
- StyleResolverChange change = m_styleEngine->resolverChanged(updateTime, updateMode);
- if (change.needsRepaint()) {
+ m_styleEngine->resolverChanged(updateMode);
+
+ if (didLayoutWithPendingStylesheets() && !m_styleEngine->hasPendingSheets()) {
// We need to manually repaint because we avoid doing all repaints in layout or style
// recalc while sheets are still loading to avoid FOUC.
m_pendingSheetLayout = IgnoreLayoutWithPendingSheets;
renderView()->repaintViewAndCompositedLayers();
}
-
- if (!change.needsStyleRecalc())
- return;
-
- m_evaluateMediaQueriesOnStyleRecalc = true;
- setNeedsStyleRecalc();
-
- if (updateTime == RecalcStyleImmediately)
- updateStyleIfNeeded();
}
-void Document::notifySeamlessChildDocumentsOfStylesheetUpdate() const
+void Document::styleResolverMayHaveChanged()
{
- // If we're not in a frame yet any potential child documents won't have a StyleResolver to update.
- if (!frame())
- return;
-
- // Seamless child frames are expected to notify their seamless children recursively, so we only do direct children.
- for (Frame* child = frame()->tree().firstChild(); child; child = child->tree().nextSibling()) {
- Document* childDocument = child->document();
- if (childDocument->shouldDisplaySeamlesslyWithParent()) {
- ASSERT(childDocument->seamlessParentIFrame()->document() == this);
- childDocument->seamlessParentUpdatedStylesheets();
- }
- }
+ styleResolverChanged(hasNodesWithPlaceholderStyle() ? FullStyleUpdate : AnalyzedStyleUpdate);
}
-void Document::setHoverNode(PassRefPtr<Node> newHoverNode)
+void Document::setHoverNode(PassRefPtrWillBeRawPtr<Node> newHoverNode)
{
m_hoverNode = newHoverNode;
}
-void Document::setActiveElement(PassRefPtr<Element> newActiveElement)
+void Document::setActiveHoverElement(PassRefPtrWillBeRawPtr<Element> newActiveElement)
{
if (!newActiveElement) {
- m_activeElement.clear();
+ m_activeHoverElement.clear();
return;
}
- m_activeElement = newActiveElement;
+ m_activeHoverElement = newActiveElement;
}
void Document::removeFocusedElementOfSubtree(Node* node, bool amongChildrenOnly)
@@ -3241,7 +3489,7 @@ void Document::removeFocusedElementOfSubtree(Node* node, bool amongChildrenOnly)
return;
bool contains = node->containsIncludingShadowDOM(m_focusedElement.get());
if (contains && (m_focusedElement != node || !amongChildrenOnly))
- setFocusedElement(0);
+ setFocusedElement(nullptr);
}
void Document::hoveredNodeDetached(Node* node)
@@ -3268,17 +3516,17 @@ void Document::hoveredNodeDetached(Node* node)
void Document::activeChainNodeDetached(Node* node)
{
- if (!m_activeElement)
+ if (!m_activeHoverElement)
return;
- if (node != m_activeElement && (!m_activeElement->isTextNode() || node != NodeRenderingTraversal::parent(m_activeElement.get())))
+ if (node != m_activeHoverElement && (!m_activeHoverElement->isTextNode() || node != NodeRenderingTraversal::parent(m_activeHoverElement.get())))
return;
Node* activeNode = NodeRenderingTraversal::parent(node);
while (activeNode && activeNode->isElementNode() && !activeNode->renderer())
activeNode = NodeRenderingTraversal::parent(activeNode);
- m_activeElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0;
+ m_activeHoverElement = activeNode && activeNode->isElementNode() ? toElement(activeNode) : 0;
}
const Vector<AnnotatedRegionValue>& Document::annotatedRegions() const
@@ -3292,9 +3540,11 @@ void Document::setAnnotatedRegions(const Vector<AnnotatedRegionValue>& regions)
setAnnotatedRegionsDirty(false);
}
-bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, FocusDirection direction)
+bool Document::setFocusedElement(PassRefPtrWillBeRawPtr<Element> prpNewFocusedElement, FocusType type)
{
- RefPtr<Element> newFocusedElement = prpNewFocusedElement;
+ m_clearFocusedElementTimer.stop();
+
+ RefPtrWillBeRawPtr<Element> newFocusedElement = prpNewFocusedElement;
// Make sure newFocusedNode is actually in this document
if (newFocusedElement && (newFocusedElement->document() != this))
@@ -3307,8 +3557,8 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
return true;
bool focusChangeBlocked = false;
- RefPtr<Element> oldFocusedElement = m_focusedElement;
- m_focusedElement = 0;
+ RefPtrWillBeRawPtr<Element> oldFocusedElement = m_focusedElement;
+ m_focusedElement = nullptr;
// Remove focus from the existing focus node (if any)
if (oldFocusedElement) {
@@ -3319,28 +3569,27 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
oldFocusedElement->setFocus(false);
- // Dispatch a change event for text fields or textareas that have been edited
- if (oldFocusedElement->wasChangedSinceLastFormControlChangeEvent())
- oldFocusedElement->dispatchFormControlChangeEvent();
-
// Dispatch the blur event and let the node do any other blur related activities (important for text fields)
- oldFocusedElement->dispatchBlurEvent(newFocusedElement.get());
-
- if (m_focusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- newFocusedElement = 0;
- }
+ // If page lost focus, blur event will have already been dispatched
+ if (page() && (page()->focusController().isFocused())) {
+ oldFocusedElement->dispatchBlurEvent(newFocusedElement.get());
+
+ if (m_focusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ newFocusedElement = nullptr;
+ }
- oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, newFocusedElement.get()); // DOM level 3 name for the bubbling blur event.
- // FIXME: We should remove firing DOMFocusOutEvent event when we are sure no content depends
- // on it, probably when <rdar://problem/8503958> is resolved.
- oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, newFocusedElement.get()); // DOM level 2 name for compatibility.
+ oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, newFocusedElement.get()); // DOM level 3 name for the bubbling blur event.
+ // FIXME: We should remove firing DOMFocusOutEvent event when we are sure no content depends
+ // on it, probably when <rdar://problem/8503958> is resolved.
+ oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, newFocusedElement.get()); // DOM level 2 name for compatibility.
- if (m_focusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- newFocusedElement = 0;
+ if (m_focusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ newFocusedElement = nullptr;
+ }
}
if (view()) {
@@ -3362,31 +3611,36 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
m_focusedElement = newFocusedElement;
// Dispatch the focus event and let the node do any other focus related activities (important for text fields)
- m_focusedElement->dispatchFocusEvent(oldFocusedElement.get(), direction);
+ // If page lost focus, event will be dispatched on page focus, don't duplicate
+ if (page() && (page()->focusController().isFocused())) {
+ m_focusedElement->dispatchFocusEvent(oldFocusedElement.get(), type);
- if (m_focusedElement != newFocusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- goto SetFocusedElementDone;
- }
- m_focusedElement->dispatchFocusInEvent(EventTypeNames::focusin, oldFocusedElement.get()); // DOM level 3 bubbling focus event.
+ if (m_focusedElement != newFocusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ goto SetFocusedElementDone;
+ }
- if (m_focusedElement != newFocusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- goto SetFocusedElementDone;
- }
+ m_focusedElement->dispatchFocusInEvent(EventTypeNames::focusin, oldFocusedElement.get()); // DOM level 3 bubbling focus event.
- // FIXME: We should remove firing DOMFocusInEvent event when we are sure no content depends
- // on it, probably when <rdar://problem/8503958> is m.
- m_focusedElement->dispatchFocusInEvent(EventTypeNames::DOMFocusIn, oldFocusedElement.get()); // DOM level 2 for compatibility.
+ if (m_focusedElement != newFocusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ goto SetFocusedElementDone;
+ }
- if (m_focusedElement != newFocusedElement) {
- // handler shifted focus
- focusChangeBlocked = true;
- goto SetFocusedElementDone;
+ // FIXME: We should remove firing DOMFocusInEvent event when we are sure no content depends
+ // on it, probably when <rdar://problem/8503958> is m.
+ m_focusedElement->dispatchFocusInEvent(EventTypeNames::DOMFocusIn, oldFocusedElement.get()); // DOM level 2 for compatibility.
+
+ if (m_focusedElement != newFocusedElement) {
+ // handler shifted focus
+ focusChangeBlocked = true;
+ goto SetFocusedElementDone;
+ }
}
+
m_focusedElement->setFocus(true);
if (m_focusedElement->isRootEditableElement())
@@ -3417,45 +3671,70 @@ bool Document::setFocusedElement(PassRefPtr<Element> prpNewFocusedElement, Focus
cache->handleFocusedUIElementChanged(oldFocusedElement.get(), newFocusedElement.get());
}
- if (!focusChangeBlocked && page())
- page()->chrome().focusedNodeChanged(m_focusedElement.get());
+ if (!focusChangeBlocked && frameHost())
+ frameHost()->chrome().focusedNodeChanged(m_focusedElement.get());
SetFocusedElementDone:
- updateStyleIfNeeded();
- if (Frame* frame = this->frame())
+ updateRenderTreeIfNeeded();
+ if (LocalFrame* frame = this->frame())
frame->selection().didChangeFocus();
return !focusChangeBlocked;
}
-void Document::setCSSTarget(Element* n)
+void Document::setCSSTarget(Element* newTarget)
{
if (m_cssTarget)
m_cssTarget->didAffectSelector(AffectedSelectorTarget);
- m_cssTarget = n;
- if (n)
- n->didAffectSelector(AffectedSelectorTarget);
+ m_cssTarget = newTarget;
+ if (m_cssTarget)
+ m_cssTarget->didAffectSelector(AffectedSelectorTarget);
}
-void Document::registerNodeList(LiveNodeListBase* list)
+void Document::registerNodeList(const LiveNodeListBase* list)
{
- if (list->hasIdNameCache())
- m_nodeListCounts[InvalidateOnIdNameAttrChange]++;
+#if ENABLE(OILPAN)
+ m_nodeLists[list->invalidationType()].add(list);
+#else
m_nodeListCounts[list->invalidationType()]++;
+#endif
if (list->isRootedAtDocument())
m_listsInvalidatedAtDocument.add(list);
}
-void Document::unregisterNodeList(LiveNodeListBase* list)
+void Document::unregisterNodeList(const LiveNodeListBase* list)
{
- if (list->hasIdNameCache())
- m_nodeListCounts[InvalidateOnIdNameAttrChange]--;
+#if ENABLE(OILPAN)
+ ASSERT(m_nodeLists[list->invalidationType()].contains(list));
+ m_nodeLists[list->invalidationType()].remove(list);
+#else
m_nodeListCounts[list->invalidationType()]--;
+#endif
if (list->isRootedAtDocument()) {
ASSERT(m_listsInvalidatedAtDocument.contains(list));
m_listsInvalidatedAtDocument.remove(list);
}
}
+void Document::registerNodeListWithIdNameCache(const LiveNodeListBase* list)
+{
+#if ENABLE(OILPAN)
+ m_nodeLists[InvalidateOnIdNameAttrChange].add(list);
+#else
+ m_nodeListCounts[InvalidateOnIdNameAttrChange]++;
+#endif
+}
+
+void Document::unregisterNodeListWithIdNameCache(const LiveNodeListBase* list)
+{
+#if ENABLE(OILPAN)
+ ASSERT(m_nodeLists[InvalidateOnIdNameAttrChange].contains(list));
+ m_nodeLists[InvalidateOnIdNameAttrChange].remove(list);
+#else
+ ASSERT(m_nodeListCounts[InvalidateOnIdNameAttrChange] > 0);
+ m_nodeListCounts[InvalidateOnIdNameAttrChange]--;
+#endif
+}
+
void Document::attachNodeIterator(NodeIterator* ni)
{
m_nodeIterators.add(ni);
@@ -3468,14 +3747,14 @@ void Document::detachNodeIterator(NodeIterator* ni)
m_nodeIterators.remove(ni);
}
-void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
+void Document::moveNodeIteratorsToNewDocument(Node& node, Document& newDocument)
{
- HashSet<NodeIterator*> nodeIteratorsList = m_nodeIterators;
- HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
- for (HashSet<NodeIterator*>::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> > nodeIteratorsList = m_nodeIterators;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator nodeIteratorsEnd = nodeIteratorsList.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator it = nodeIteratorsList.begin(); it != nodeIteratorsEnd; ++it) {
if ((*it)->root() == node) {
detachNodeIterator(*it);
- newDocument->attachNodeIterator(*it);
+ newDocument.attachNodeIterator(*it);
}
}
}
@@ -3483,29 +3762,40 @@ void Document::moveNodeIteratorsToNewDocument(Node* node, Document* newDocument)
void Document::updateRangesAfterChildrenChanged(ContainerNode* container)
{
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->nodeChildrenChanged(container);
}
}
-void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
+void Document::updateRangesAfterNodeMovedToAnotherDocument(const Node& node)
+{
+ ASSERT(node.document() != this);
+ if (m_ranges.isEmpty())
+ return;
+ AttachedRangeSet ranges = m_ranges;
+ AttachedRangeSet::const_iterator end = ranges.end();
+ for (AttachedRangeSet::const_iterator it = ranges.begin(); it != end; ++it)
+ (*it)->updateOwnerDocumentIfNeeded();
+}
+
+void Document::nodeChildrenWillBeRemoved(ContainerNode& container)
{
NoEventDispatchAssertion assertNoEventDispatch;
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->nodeChildrenWillBeRemoved(container);
}
- HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
- for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
- for (Node* n = container->firstChild(); n; n = n->nextSibling())
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
+ for (Node* n = container.firstChild(); n; n = n->nextSibling())
(*it)->nodeWillBeRemoved(*n);
}
- if (Frame* frame = this->frame()) {
- for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
+ if (LocalFrame* frame = this->frame()) {
+ for (Node* n = container.firstChild(); n; n = n->nextSibling()) {
frame->eventHandler().nodeWillBeRemoved(*n);
frame->selection().nodeWillBeRemoved(*n);
frame->page()->dragCaretController().nodeWillBeRemoved(*n);
@@ -3515,17 +3805,17 @@ void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
void Document::nodeWillBeRemoved(Node& n)
{
- HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
- for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> >::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it)
(*it)->nodeWillBeRemoved(n);
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator rangesEnd = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
+ AttachedRangeSet::const_iterator rangesEnd = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != rangesEnd; ++it)
(*it)->nodeWillBeRemoved(n);
}
- if (Frame* frame = this->frame()) {
+ if (LocalFrame* frame = this->frame()) {
frame->eventHandler().nodeWillBeRemoved(n);
frame->selection().nodeWillBeRemoved(n);
frame->page()->dragCaretController().nodeWillBeRemoved(n);
@@ -3535,8 +3825,8 @@ void Document::nodeWillBeRemoved(Node& n)
void Document::didInsertText(Node* text, unsigned offset, unsigned length)
{
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->didInsertText(text, offset, length);
}
@@ -3547,8 +3837,8 @@ void Document::didInsertText(Node* text, unsigned offset, unsigned length)
void Document::didRemoveText(Node* text, unsigned offset, unsigned length)
{
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->didRemoveText(text, offset, length);
}
@@ -3557,49 +3847,49 @@ void Document::didRemoveText(Node* text, unsigned offset, unsigned length)
m_markers->shiftMarkers(text, offset + length, 0 - length);
}
-void Document::didMergeTextNodes(Text* oldNode, unsigned offset)
+void Document::didMergeTextNodes(Text& oldNode, unsigned offset)
{
if (!m_ranges.isEmpty()) {
NodeWithIndex oldNodeWithIndex(oldNode);
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->didMergeTextNodes(oldNodeWithIndex, offset);
}
if (m_frame)
- m_frame->selection().didMergeTextNodes(*oldNode, offset);
+ m_frame->selection().didMergeTextNodes(oldNode, offset);
// FIXME: This should update markers for spelling and grammar checking.
}
-void Document::didSplitTextNode(Text* oldNode)
+void Document::didSplitTextNode(Text& oldNode)
{
if (!m_ranges.isEmpty()) {
- HashSet<Range*>::const_iterator end = m_ranges.end();
- for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+ AttachedRangeSet::const_iterator end = m_ranges.end();
+ for (AttachedRangeSet::const_iterator it = m_ranges.begin(); it != end; ++it)
(*it)->didSplitTextNode(oldNode);
}
if (m_frame)
- m_frame->selection().didSplitTextNode(*oldNode);
+ m_frame->selection().didSplitTextNode(oldNode);
// FIXME: This should update markers for spelling and grammar checking.
}
-void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld)
+void Document::setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
{
- DOMWindow* domWindow = this->domWindow();
+ LocalDOMWindow* domWindow = this->domWindow();
if (!domWindow)
return;
- domWindow->setAttributeEventListener(eventType, listener, isolatedWorld);
+ domWindow->setAttributeEventListener(eventType, listener);
}
-EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld)
+EventListener* Document::getWindowAttributeEventListener(const AtomicString& eventType)
{
- DOMWindow* domWindow = this->domWindow();
+ LocalDOMWindow* domWindow = this->domWindow();
if (!domWindow)
return 0;
- return domWindow->getAttributeEventListener(eventType, isolatedWorld);
+ return domWindow->getAttributeEventListener(eventType);
}
EventQueue* Document::eventQueue() const
@@ -3609,7 +3899,7 @@ EventQueue* Document::eventQueue() const
return m_domWindow->eventQueue();
}
-void Document::enqueueAnimationFrameEvent(PassRefPtr<Event> event)
+void Document::enqueueAnimationFrameEvent(PassRefPtrWillBeRawPtr<Event> event)
{
ensureScriptedAnimationController().enqueueEvent(event);
}
@@ -3617,26 +3907,40 @@ void Document::enqueueAnimationFrameEvent(PassRefPtr<Event> event)
void Document::enqueueScrollEventForNode(Node* target)
{
// Per the W3C CSSOM View Module only scroll events fired at the document should bubble.
- RefPtr<Event> scrollEvent = target->isDocumentNode() ? Event::createBubble(EventTypeNames::scroll) : Event::create(EventTypeNames::scroll);
+ RefPtrWillBeRawPtr<Event> scrollEvent = target->isDocumentNode() ? Event::createBubble(EventTypeNames::scroll) : Event::create(EventTypeNames::scroll);
scrollEvent->setTarget(target);
ensureScriptedAnimationController().enqueuePerFrameEvent(scrollEvent.release());
}
void Document::enqueueResizeEvent()
{
- RefPtr<Event> event = Event::create(EventTypeNames::resize);
+ RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::resize);
event->setTarget(domWindow());
ensureScriptedAnimationController().enqueuePerFrameEvent(event.release());
}
-PassRefPtr<Event> Document::createEvent(const String& eventType, ExceptionState& exceptionState)
+Document::EventFactorySet& Document::eventFactories()
{
- RefPtr<Event> event = EventFactory::create(eventType);
- if (event)
- return event.release();
+ DEFINE_STATIC_LOCAL(EventFactorySet, s_eventFactory, ());
+ return s_eventFactory;
+}
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+void Document::registerEventFactory(PassOwnPtr<EventFactoryBase> eventFactory)
+{
+ ASSERT(!eventFactories().contains(eventFactory.get()));
+ eventFactories().add(eventFactory);
+}
+
+PassRefPtrWillBeRawPtr<Event> Document::createEvent(const String& eventType, ExceptionState& exceptionState)
+{
+ RefPtrWillBeRawPtr<Event> event = nullptr;
+ for (EventFactorySet::const_iterator it = eventFactories().begin(); it != eventFactories().end(); ++it) {
+ event = (*it)->create(eventType);
+ if (event)
+ return event.release();
+ }
+ exceptionState.throwDOMException(NotSupportedError, "The provided event type ('" + eventType + "') is invalid.");
+ return nullptr;
}
void Document::addMutationEventListenerTypeIfEnabled(ListenerType listenerType)
@@ -3666,7 +3970,7 @@ void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
UseCounter::count(*this, UseCounter::DOMCharacterDataModifiedEvent);
addMutationEventListenerTypeIfEnabled(DOMCHARACTERDATAMODIFIED_LISTENER);
} else if (eventType == EventTypeNames::overflowchanged) {
- UseCounter::count(*this, UseCounter::OverflowChangedEvent);
+ UseCounter::countDeprecation(*this, UseCounter::OverflowChangedEvent);
addListenerType(OVERFLOWCHANGED_LISTENER);
} else if (eventType == EventTypeNames::webkitAnimationStart || (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && eventType == EventTypeNames::animationstart)) {
addListenerType(ANIMATIONSTART_LISTENER);
@@ -3676,17 +3980,8 @@ void Document::addListenerTypeIfNeeded(const AtomicString& eventType)
addListenerType(ANIMATIONITERATION_LISTENER);
} else if (eventType == EventTypeNames::webkitTransitionEnd || eventType == EventTypeNames::transitionend) {
addListenerType(TRANSITIONEND_LISTENER);
- } else if (eventType == EventTypeNames::beforeload) {
- if (m_frame && m_frame->script().shouldBypassMainWorldContentSecurityPolicy()) {
- UseCounter::count(*this, UseCounter::BeforeLoadEventInIsolatedWorld);
- } else {
- UseCounter::count(*this, UseCounter::BeforeLoadEvent);
- }
- addListenerType(BEFORELOAD_LISTENER);
} else if (eventType == EventTypeNames::scroll) {
addListenerType(SCROLL_LISTENER);
- } else if (eventType == EventTypeNames::DOMFocusIn || eventType == EventTypeNames::DOMFocusOut) {
- UseCounter::count(*this, UseCounter::DOMFocusInOutEvent);
}
}
@@ -3699,7 +3994,8 @@ HTMLFrameOwnerElement* Document::ownerElement() const
{
if (!frame())
return 0;
- return frame()->ownerElement();
+ // FIXME: This probably breaks the attempts to layout after a load is finished in implicitClose(), and probably tons of other things...
+ return frame()->deprecatedLocalOwner();
}
String Document::cookie(ExceptionState& exceptionState) const
@@ -3798,7 +4094,7 @@ void Document::setDomain(const String& newDomain, ExceptionState& exceptionState
securityOrigin()->setDomainFromDOM(newDomain);
if (m_frame)
- m_frame->script().updateSecurityOrigin();
+ m_frame->script().updateSecurityOrigin(securityOrigin());
}
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-lastmodified
@@ -3825,7 +4121,7 @@ String Document::lastModified() const
const KURL& Document::firstPartyForCookies() const
{
- return topDocument()->url();
+ return topDocument().url();
}
static bool isValidNameNonASCII(const LChar* characters, unsigned length)
@@ -3910,7 +4206,7 @@ static bool parseQualifiedNameInternal(const AtomicString& qualifiedName, const
U16_NEXT(characters, i, length, c)
if (c == ':') {
if (sawColon) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
+ exceptionState.throwDOMException(NamespaceError, "The qualified name provided ('" + qualifiedName + "') contains multiple colons.");
return false; // multiple colons: not allowed
}
nameStart = true;
@@ -3918,13 +4214,25 @@ static bool parseQualifiedNameInternal(const AtomicString& qualifiedName, const
colonPos = i - 1;
} else if (nameStart) {
if (!isValidNameStart(c)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ StringBuilder message;
+ message.appendLiteral("The qualified name provided ('");
+ message.append(qualifiedName);
+ message.appendLiteral("') contains the invalid name-start character '");
+ message.append(c);
+ message.appendLiteral("'.");
+ exceptionState.throwDOMException(InvalidCharacterError, message.toString());
return false;
}
nameStart = false;
} else {
if (!isValidNamePart(c)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ StringBuilder message;
+ message.appendLiteral("The qualified name provided ('");
+ message.append(qualifiedName);
+ message.appendLiteral("') contains the invalid character '");
+ message.append(c);
+ message.appendLiteral("'.");
+ exceptionState.throwDOMException(InvalidCharacterError, message.toString());
return false;
}
}
@@ -3936,7 +4244,7 @@ static bool parseQualifiedNameInternal(const AtomicString& qualifiedName, const
} else {
prefix = AtomicString(characters, colonPos);
if (prefix.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
+ exceptionState.throwDOMException(NamespaceError, "The qualified name provided ('" + qualifiedName + "') has an empty namespace prefix.");
return false;
}
int prefixStart = colonPos + 1;
@@ -3944,7 +4252,7 @@ static bool parseQualifiedNameInternal(const AtomicString& qualifiedName, const
}
if (localName.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
+ exceptionState.throwDOMException(NamespaceError, "The qualified name provided ('" + qualifiedName + "') has an empty local name.");
return false;
}
@@ -3956,7 +4264,7 @@ bool Document::parseQualifiedName(const AtomicString& qualifiedName, AtomicStrin
unsigned length = qualifiedName.length();
if (!length) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ exceptionState.throwDOMException(InvalidCharacterError, "The qualified name provided is empty.");
return false;
}
@@ -3974,29 +4282,50 @@ void Document::setEncodingData(const DocumentEncodingData& newData)
// document's title so that the user doesn't see an incorrectly decoded title
// in the title bar.
if (m_titleElement
- && encoding() != newData.encoding
- && !m_titleElement->firstElementChild()
+ && encoding() != newData.encoding()
+ && !ElementTraversal::firstWithin(*m_titleElement)
&& encoding() == Latin1Encoding()
&& m_titleElement->textContent().containsOnlyLatin1()) {
CString originalBytes = m_titleElement->textContent().latin1();
- OwnPtr<TextCodec> codec = newTextCodec(newData.encoding);
- String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), true);
+ OwnPtr<TextCodec> codec = newTextCodec(newData.encoding());
+ String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), DataEOF);
m_titleElement->setTextContent(correctlyDecodedTitle);
}
m_encodingData = newData;
+
+ // FIXME: Should be removed as part of https://code.google.com/p/chromium/issues/detail?id=319643
+ bool shouldUseVisualOrdering = m_encodingData.encoding().usesVisualOrdering();
+ if (shouldUseVisualOrdering != m_visuallyOrdered) {
+ m_visuallyOrdered = shouldUseVisualOrdering;
+ // FIXME: How is possible to not have a renderer here?
+ if (renderView())
+ renderView()->style()->setRTLOrdering(m_visuallyOrdered ? VisualOrder : LogicalOrder);
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ }
+}
+
+KURL Document::completeURL(const String& url) const
+{
+ return completeURLWithOverride(url, m_baseURL);
}
-KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
+KURL Document::completeURLWithOverride(const String& url, const KURL& baseURLOverride) const
{
// Always return a null URL when passed a null string.
// FIXME: Should we change the KURL constructor to have this behavior?
// See also [CSS]StyleSheet::completeURL(const String&)
if (url.isNull())
return KURL();
+ // This logic is deliberately spread over many statements in an attempt to track down http://crbug.com/312410.
const KURL* baseURLFromParent = 0;
- if (baseURLOverride.isEmpty() || baseURLOverride == blankURL()) {
+ bool shouldUseParentBaseURL = baseURLOverride.isEmpty();
+ if (!shouldUseParentBaseURL) {
+ const KURL& aboutBlankURL = blankURL();
+ shouldUseParentBaseURL = (baseURLOverride == aboutBlankURL);
+ }
+ if (shouldUseParentBaseURL) {
if (Document* parent = parentDocument())
baseURLFromParent = &parent->baseURL();
}
@@ -4006,26 +4335,39 @@ KURL Document::completeURL(const String& url, const KURL& baseURLOverride) const
return KURL(baseURL, url, encoding());
}
-KURL Document::completeURL(const String& url) const
-{
- return completeURL(url, m_baseURL);
-}
-
// Support for Javascript execCommand, and related methods
static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
{
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
if (!frame || frame->document() != document)
return Editor::Command();
- document->updateStyleIfNeeded();
+ document->updateRenderTreeIfNeeded();
return frame->editor().command(commandName, userInterface ? CommandFromDOMWithUserInterface : CommandFromDOM);
}
bool Document::execCommand(const String& commandName, bool userInterface, const String& value)
{
- return command(this, commandName, userInterface).execute(value);
+ // We don't allow recusrive |execCommand()| to protect against attack code.
+ // Recursive call of |execCommand()| could be happened by moving iframe
+ // with script triggered by insertion, e.g. <iframe src="javascript:...">
+ // <iframe onload="...">. This usage is valid as of the specification
+ // although, it isn't common use case, rather it is used as attack code.
+ static bool inExecCommand = false;
+ if (inExecCommand) {
+ String message = "We don't execute document.execCommand() this time, because it is called recursively.";
+ addConsoleMessage(JSMessageSource, WarningMessageLevel, message);
+ return false;
+ }
+ TemporaryChange<bool> executeScope(inExecCommand, true);
+
+ // Postpone DOM mutation events, which can execute scripts and change
+ // DOM tree against implementation assumption.
+ EventQueueScope eventQueueScope;
+ Editor::Command editorCommand = command(this, commandName, userInterface);
+ blink::Platform::current()->histogramSparse("WebCore.Document.execCommand", editorCommand.idForHistogram());
+ return editorCommand.execute(value);
}
bool Document::queryCommandEnabled(const String& commandName)
@@ -4069,11 +4411,7 @@ KURL Document::openSearchDescriptionURL()
if (!head())
return KURL();
- RefPtr<HTMLCollection> children = head()->children();
- for (unsigned i = 0; Node* child = children->item(i); i++) {
- if (!child->hasTagName(linkTag))
- continue;
- HTMLLinkElement* linkElement = toHTMLLinkElement(child);
+ for (HTMLLinkElement* linkElement = Traversal<HTMLLinkElement>::firstChild(*head()); linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
if (!equalIgnoringCase(linkElement->type(), openSearchMIMEType) || !equalIgnoringCase(linkElement->rel(), openSearchRelation))
continue;
if (linkElement->href().isEmpty())
@@ -4084,7 +4422,7 @@ KURL Document::openSearchDescriptionURL()
return KURL();
}
-void Document::pushCurrentScript(PassRefPtr<HTMLScriptElement> newCurrentScript)
+void Document::pushCurrentScript(PassRefPtrWillBeRawPtr<HTMLScriptElement> newCurrentScript)
{
ASSERT(newCurrentScript);
m_currentScriptStack.append(newCurrentScript);
@@ -4100,7 +4438,7 @@ void Document::applyXSLTransform(ProcessingInstruction* pi)
{
ASSERT(!pi->isLoading());
UseCounter::count(*this, UseCounter::XSLProcessingInstruction);
- RefPtr<XSLTProcessor> processor = XSLTProcessor::create();
+ RefPtrWillBeRawPtr<XSLTProcessor> processor = XSLTProcessor::create();
processor->setXSLStyleSheet(toXSLStyleSheet(pi->sheet()));
String resultMIMEType;
String newSource;
@@ -4108,7 +4446,7 @@ void Document::applyXSLTransform(ProcessingInstruction* pi)
if (!processor->transformToString(this, resultMIMEType, newSource, resultEncoding))
return;
// FIXME: If the transform failed we should probably report an error (like Mozilla does).
- Frame* ownerFrame = frame();
+ LocalFrame* ownerFrame = frame();
processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, ownerFrame);
InspectorInstrumentation::frameDocumentUpdated(ownerFrame);
}
@@ -4121,8 +4459,13 @@ void Document::setTransformSource(PassOwnPtr<TransformSource> source)
void Document::setDesignMode(InheritedBool value)
{
m_designMode = value;
- for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree().traverseNext(m_frame))
- frame->document()->setNeedsStyleRecalc();
+ for (Frame* frame = m_frame; frame; frame = frame->tree().traverseNext(m_frame)) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (!toLocalFrame(frame)->document())
+ break;
+ toLocalFrame(frame)->document()->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
}
Document::InheritedBool Document::getDesignMode() const
@@ -4139,54 +4482,79 @@ bool Document::inDesignMode() const
return false;
}
+String Document::designMode() const
+{
+ return inDesignMode() ? "on" : "off";
+}
+
+void Document::setDesignMode(const String& value)
+{
+ InheritedBool mode;
+ if (equalIgnoringCase(value, "on"))
+ mode = on;
+ else if (equalIgnoringCase(value, "off"))
+ mode = off;
+ else
+ mode = inherit;
+ setDesignMode(mode);
+}
+
Document* Document::parentDocument() const
{
if (!m_frame)
return 0;
Frame* parent = m_frame->tree().parent();
- if (!parent)
+ if (!parent || !parent->isLocalFrame())
return 0;
- return parent->document();
+ return toLocalFrame(parent)->document();
}
-Document* Document::topDocument() const
+Document& Document::topDocument() const
{
+ // FIXME: Not clear what topDocument() should do in the OOPI case--should it return the topmost
+ // available Document, or something else?
Document* doc = const_cast<Document*>(this);
Element* element;
while ((element = doc->ownerElement()))
doc = &element->document();
- return doc;
+ ASSERT(doc);
+ return *doc;
}
-WeakPtr<Document> Document::contextDocument()
+WeakPtrWillBeRawPtr<Document> Document::contextDocument()
{
if (m_contextDocument)
return m_contextDocument;
- if (m_frame)
+ if (m_frame) {
+#if ENABLE(OILPAN)
+ return this;
+#else
return m_weakFactory.createWeakPtr();
- return WeakPtr<Document>(0);
+#endif
+ }
+ return WeakPtrWillBeRawPtr<Document>(nullptr);
}
-PassRefPtr<Attr> Document::createAttribute(const AtomicString& name, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Attr> Document::createAttribute(const AtomicString& name, ExceptionState& exceptionState)
{
return createAttributeNS(nullAtom, name, exceptionState, true);
}
-PassRefPtr<Attr> Document::createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState, bool shouldIgnoreNamespaceChecks)
+PassRefPtrWillBeRawPtr<Attr> Document::createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState, bool shouldIgnoreNamespaceChecks)
{
AtomicString prefix, localName;
if (!parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
- return 0;
+ return nullptr;
QualifiedName qName(prefix, localName, namespaceURI);
if (!shouldIgnoreNamespaceChecks && !hasValidNamespaceForAttributes(qName)) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
- return 0;
+ exceptionState.throwDOMException(NamespaceError, "The namespace URI provided ('" + namespaceURI + "') is not valid for the qualified name provided ('" + qualifiedName + "').");
+ return nullptr;
}
- return Attr::create(*this, qName, emptyString());
+ return Attr::create(*this, qName, emptyAtom);
}
const SVGDocumentExtensions* Document::svgExtensions()
@@ -4194,77 +4562,77 @@ const SVGDocumentExtensions* Document::svgExtensions()
return m_svgExtensions.get();
}
-SVGDocumentExtensions* Document::accessSVGExtensions()
+SVGDocumentExtensions& Document::accessSVGExtensions()
{
if (!m_svgExtensions)
- m_svgExtensions = adoptPtr(new SVGDocumentExtensions(this));
- return m_svgExtensions.get();
+ m_svgExtensions = adoptPtrWillBeNoop(new SVGDocumentExtensions(this));
+ return *m_svgExtensions;
}
bool Document::hasSVGRootNode() const
{
- return documentElement() && documentElement()->hasTagName(SVGNames::svgTag);
+ return isSVGSVGElement(documentElement());
}
-PassRefPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, type);
+ return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
}
-PassRefPtr<HTMLCollection> Document::images()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::images()
{
return ensureCachedCollection(DocImages);
}
-PassRefPtr<HTMLCollection> Document::applets()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::applets()
{
return ensureCachedCollection(DocApplets);
}
-PassRefPtr<HTMLCollection> Document::embeds()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::embeds()
{
return ensureCachedCollection(DocEmbeds);
}
-PassRefPtr<HTMLCollection> Document::scripts()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::scripts()
{
return ensureCachedCollection(DocScripts);
}
-PassRefPtr<HTMLCollection> Document::links()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::links()
{
return ensureCachedCollection(DocLinks);
}
-PassRefPtr<HTMLCollection> Document::forms()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::forms()
{
return ensureCachedCollection(DocForms);
}
-PassRefPtr<HTMLCollection> Document::anchors()
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::anchors()
{
return ensureCachedCollection(DocAnchors);
}
-PassRefPtr<HTMLCollection> Document::allForBinding()
+PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::allForBinding()
{
UseCounter::count(*this, UseCounter::DocumentAll);
return all();
}
-PassRefPtr<HTMLCollection> Document::all()
+PassRefPtrWillBeRawPtr<HTMLAllCollection> Document::all()
{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLAllCollection>(this, DocAll);
+ return ensureRareData().ensureNodeLists().addCache<HTMLAllCollection>(*this, DocAll);
}
-PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLNameCollection>(this, WindowNamedItems, name);
+ return ensureRareData().ensureNodeLists().addCache<WindowNameCollection>(*this, WindowNamedItems, name);
}
-PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
+PassRefPtrWillBeRawPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLNameCollection>(this, DocumentNamedItems, name);
+ return ensureRareData().ensureNodeLists().addCache<DocumentNameCollection>(*this, DocumentNamedItems, name);
}
void Document::finishedParsing()
@@ -4278,12 +4646,26 @@ void Document::finishedParsing()
if (!m_documentTiming.domContentLoadedEventEnd)
m_documentTiming.domContentLoadedEventEnd = monotonicallyIncreasingTime();
+ if (frame() && frame()->isMainFrame()) {
+ // Reset the text autosizing multipliers on main frame when DOM is loaded.
+ // This is to allow for a fresh text autosizing pass when the page layout
+ // changes significantly in the end.
+ if (TextAutosizer* textAutosizer = this->textAutosizer())
+ textAutosizer->recalculateMultipliers();
+ }
+
// The loader's finishedParsing() method may invoke script that causes this object to
// be dereferenced (when this document is in an iframe and the onload causes the iframe's src to change).
// Keep it alive until we are done.
- RefPtr<Document> protect(this);
+ RefPtrWillBeRawPtr<Document> protect(this);
+
+ if (RefPtr<LocalFrame> f = frame()) {
+ // Don't update the render tree if we haven't requested the main resource yet to avoid
+ // adding extra latency. Note that the first render tree update can be expensive since it
+ // triggers the parsing of the default stylesheets which are compiled-in.
+ const bool mainResourceWasAlreadyRequested =
+ m_frame->loader().stateMachine()->committedFirstRealDocumentLoad();
- if (RefPtr<Frame> f = frame()) {
// FrameLoader::finishedParsing() might end up calling Document::implicitClose() if all
// resource loads are complete. HTMLObjectElements can start loading their resources from
// post attach callbacks triggered by recalcStyle(). This means if we parse out an <object>
@@ -4291,30 +4673,32 @@ void Document::finishedParsing()
// started the resource load and might fire the window load event too early. To avoid this
// we force the styles to be up to date before calling FrameLoader::finishedParsing().
// See https://bugs.webkit.org/show_bug.cgi?id=36864 starting around comment 35.
- updateStyleIfNeeded();
+ if (mainResourceWasAlreadyRequested)
+ updateRenderTreeIfNeeded();
f->loader().finishedParsing();
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "MarkDOMContent", "data", InspectorMarkLoadEvent::data(f.get()));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::domContentLoadedEventFired(f.get());
}
- // Schedule dropping of the DocumentSharedObjectPool. We keep it alive for a while after parsing finishes
+ // Schedule dropping of the ElementDataCache. We keep it alive for a while after parsing finishes
// so that dynamically inserted content can also benefit from sharing optimizations.
- // Note that we don't refresh the timer on pool access since that could lead to huge caches being kept
+ // Note that we don't refresh the timer on cache access since that could lead to huge caches being kept
// alive indefinitely by something innocuous like JS setting .innerHTML repeatedly on a timer.
- static const int timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds = 10;
- m_sharedObjectPoolClearTimer.startOneShot(timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds);
+ m_elementDataCacheClearTimer.startOneShot(10, FROM_HERE);
// Parser should have picked up all preloads by now
m_fetcher->clearPreloads();
- if (m_import)
- m_import->didFinishParsing();
+ if (HTMLImportLoader* import = importLoader())
+ import->didFinishParsing();
}
-void Document::sharedObjectPoolClearTimerFired(Timer<Document>*)
+void Document::elementDataCacheClearTimerFired(Timer<Document>*)
{
- m_sharedObjectPool.clear();
+ m_elementDataCache.clear();
}
Vector<IconURL> Document::iconURLs(int iconTypesMask)
@@ -4325,21 +4709,13 @@ Vector<IconURL> Document::iconURLs(int iconTypesMask)
Vector<IconURL> secondaryIcons;
// Start from the last child node so that icons seen later take precedence as required by the spec.
- RefPtr<HTMLCollection> children = head() ? head()->children() : 0;
- unsigned length = children ? children->length() : 0;
- for (unsigned i = 0; i < length; i++) {
- Node* child = children->item(i);
- if (!child->hasTagName(linkTag))
- continue;
- HTMLLinkElement* linkElement = toHTMLLinkElement(child);
+ for (HTMLLinkElement* linkElement = head() ? Traversal<HTMLLinkElement>::firstChild(*head()) : 0; linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
if (!(linkElement->iconType() & iconTypesMask))
continue;
if (linkElement->href().isEmpty())
continue;
-#if !ENABLE(TOUCH_ICON_LOADING)
- if (linkElement->iconType() != Favicon)
+ if (!RuntimeEnabledFeatures::touchIconLoadingEnabled() && linkElement->iconType() != Favicon)
continue;
-#endif
IconURL newURL(linkElement->href(), linkElement->iconSizes(), linkElement->type(), linkElement->iconType());
if (linkElement->iconType() == Favicon) {
@@ -4374,6 +4750,35 @@ Vector<IconURL> Document::iconURLs(int iconTypesMask)
return iconURLs;
}
+Color Document::themeColor() const
+{
+ if (!RuntimeEnabledFeatures::themeColorEnabled())
+ return Color();
+
+ for (HTMLMetaElement* metaElement = head() ? Traversal<HTMLMetaElement>::firstChild(*head()) : 0; metaElement; metaElement = Traversal<HTMLMetaElement>::nextSibling(*metaElement)) {
+ RGBA32 rgb;
+ if (equalIgnoringCase(metaElement->name(), "theme-color") && BisonCSSParser::parseColor(rgb, metaElement->content().string().stripWhiteSpace(), true))
+ return Color(rgb);
+ }
+ return Color();
+}
+
+HTMLLinkElement* Document::linkManifest() const
+{
+ HTMLHeadElement* head = this->head();
+ if (!head)
+ return 0;
+
+ // The first link element with a manifest rel must be used. Others are ignored.
+ for (HTMLLinkElement* linkElement = Traversal<HTMLLinkElement>::firstChild(*head); linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
+ if (!linkElement->relAttribute().isManifest())
+ continue;
+ return linkElement;
+ }
+
+ return 0;
+}
+
void Document::setUseSecureKeyboardEntryWhenActive(bool usesSecureKeyboard)
{
if (m_useSecureKeyboardEntryWhenActive == usesSecureKeyboard)
@@ -4390,7 +4795,14 @@ bool Document::useSecureKeyboardEntryWhenActive() const
void Document::initSecurityContext()
{
- initSecurityContext(DocumentInit(m_url, m_frame, contextDocument(), m_import));
+ initSecurityContext(DocumentInit(m_url, m_frame, contextDocument(), m_importsController));
+}
+
+static PassRefPtr<ContentSecurityPolicy> contentSecurityPolicyFor(Document* document)
+{
+ if (document->importsController())
+ return document->importsController()->master()->contentSecurityPolicy();
+ return ContentSecurityPolicy::create(document);
}
void Document::initSecurityContext(const DocumentInit& initializer)
@@ -4414,7 +4826,7 @@ void Document::initSecurityContext(const DocumentInit& initializer)
m_cookieURL = m_url;
enforceSandboxFlags(initializer.sandboxFlags());
setSecurityOrigin(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url));
- setContentSecurityPolicy(ContentSecurityPolicy::create(this));
+ setContentSecurityPolicy(contentSecurityPolicyFor(this));
if (Settings* settings = initializer.settings()) {
if (!settings->webSecurityEnabled()) {
@@ -4439,10 +4851,6 @@ void Document::initSecurityContext(const DocumentInit& initializer)
setBaseURLOverride(initializer.parentBaseURL());
}
- // FIXME: What happens if we inherit the security origin? This check may need to be later.
- // <iframe seamless src="about:blank"> likely won't work as-is.
- m_mayDisplaySeamlesslyWithParent = initializer.isSeamlessAllowedFor(this);
-
if (!shouldInheritSecurityOriginFromOwner(m_url))
return;
@@ -4472,8 +4880,8 @@ void Document::initSecurityContext(const DocumentInit& initializer)
void Document::initContentSecurityPolicy(const ContentSecurityPolicyResponseHeaders& headers)
{
- if (m_frame && m_frame->tree().parent() && (shouldInheritSecurityOriginFromOwner(m_url) || isPluginDocument()))
- contentSecurityPolicy()->copyStateFrom(m_frame->tree().parent()->document()->contentSecurityPolicy());
+ if (m_frame && m_frame->tree().parent() && m_frame->tree().parent()->isLocalFrame() && (shouldInheritSecurityOriginFromOwner(m_url) || isPluginDocument()))
+ contentSecurityPolicy()->copyStateFrom(toLocalFrame(m_frame->tree().parent())->document()->contentSecurityPolicy());
contentSecurityPolicy()->didReceiveHeaders(headers);
}
@@ -4486,9 +4894,10 @@ bool Document::allowInlineEventHandlers(Node* node, EventListener* listener, con
// http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handler-attributes
// Also, if the listening node came from other document, which happens on context-less event dispatching,
// we also need to ask the owner document of the node.
- if (!m_frame)
+ LocalFrame* frame = executingFrame();
+ if (!frame)
return false;
- if (!m_frame->script().canExecuteScripts(NotAboutToExecuteScript))
+ if (!frame->script().canExecuteScripts(NotAboutToExecuteScript))
return false;
if (node && node->document() != this && !node->document().allowInlineEventHandlers(node, listener, contextURL, contextLine))
return false;
@@ -4501,11 +4910,12 @@ bool Document::allowExecutingScripts(Node* node)
// FIXME: Eventually we'd like to evaluate scripts which are inserted into a
// viewless document but this'll do for now.
// See http://bugs.webkit.org/show_bug.cgi?id=5727
- if (!frame() && !import())
+ LocalFrame* frame = executingFrame();
+ if (!frame)
return false;
- if (!node->document().frame() && !node->document().import())
+ if (!node->document().executingFrame())
return false;
- if (!contextDocument().get()->frame()->script().canExecuteScripts(AboutToExecuteScript))
+ if (!frame->script().canExecuteScripts(AboutToExecuteScript))
return false;
return true;
}
@@ -4520,7 +4930,7 @@ void Document::didUpdateSecurityOrigin()
{
if (!m_frame)
return;
- m_frame->script().updateSecurityOrigin();
+ m_frame->script().updateSecurityOrigin(securityOrigin());
}
bool Document::isContextThread() const
@@ -4532,7 +4942,7 @@ void Document::updateFocusAppearanceSoon(bool restorePreviousSelection)
{
m_updateFocusAppearanceRestoresSelection = restorePreviousSelection;
if (!m_updateFocusAppearanceTimer.isActive())
- m_updateFocusAppearanceTimer.startOneShot(0);
+ m_updateFocusAppearanceTimer.startOneShot(0, FROM_HERE);
}
void Document::cancelFocusAppearanceUpdate()
@@ -4563,23 +4973,31 @@ void Document::detachRange(Range* range)
m_ranges.remove(range);
}
-CanvasRenderingContext* Document::getCSSCanvasContext(const String& type, const String& name, int width, int height)
+void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, bool& is2d, RefPtrWillBeRawPtr<CanvasRenderingContext2D>& context2d, bool& is3d, RefPtrWillBeRawPtr<WebGLRenderingContext>& context3d)
{
- HTMLCanvasElement* element = getCSSCanvasElement(name);
- if (!element)
- return 0;
- element->setSize(IntSize(width, height));
- return element->getContext(type);
+ HTMLCanvasElement& element = getCSSCanvasElement(name);
+ element.setSize(IntSize(width, height));
+ CanvasRenderingContext* context = element.getContext(type);
+ if (!context)
+ return;
+
+ if (context->is2d()) {
+ is2d = true;
+ context2d = toCanvasRenderingContext2D(context);
+ } else if (context->is3d()) {
+ is3d = true;
+ context3d = toWebGLRenderingContext(context);
+ }
}
-HTMLCanvasElement* Document::getCSSCanvasElement(const String& name)
+HTMLCanvasElement& Document::getCSSCanvasElement(const String& name)
{
- RefPtr<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, 0).iterator->value;
+ RefPtrWillBeMember<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, nullptr).storedValue->value;
if (!element) {
element = HTMLCanvasElement::create(*this);
element->setAccelerationDisabled(true);
}
- return element.get();
+ return *element;
}
void Document::initDNSPrefetch()
@@ -4612,23 +5030,23 @@ void Document::reportBlockedScriptExecutionToInspector(const String& directiveTe
InspectorInstrumentation::scriptExecutionBlockedByCSP(this, directiveText);
}
-void Document::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* state)
+void Document::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* scriptState)
{
- internalAddMessage(source, level, message, sourceURL, lineNumber, 0, state);
+ internalAddMessage(source, level, message, sourceURL, lineNumber, nullptr, scriptState);
}
-void Document::internalAddMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack> callStack, ScriptState* state)
+void Document::internalAddMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, ScriptState* scriptState)
{
if (!isContextThread()) {
m_taskRunner->postTask(AddConsoleMessageTask::create(source, level, message));
return;
}
- Page* page = this->page();
- if (!page)
+
+ if (!m_frame)
return;
String messageURL = sourceURL;
- if (!state && sourceURL.isNull() && !lineNumber) {
+ if (!scriptState && sourceURL.isNull() && !lineNumber) {
messageURL = url().string();
if (parsing() && !isInDocumentWrite() && scriptableDocumentParser()) {
ScriptableDocumentParser* parser = scriptableDocumentParser();
@@ -4636,7 +5054,7 @@ void Document::internalAddMessage(MessageSource source, MessageLevel level, cons
lineNumber = parser->lineNumber().oneBasedInt();
}
}
- page->console().addMessage(source, level, message, messageURL, lineNumber, 0, callStack, state, 0);
+ m_frame->console().addMessage(source, level, message, messageURL, lineNumber, 0, callStack, scriptState, 0);
}
void Document::addConsoleMessageWithRequestIdentifier(MessageSource source, MessageLevel level, const String& message, unsigned long requestIdentifier)
@@ -4646,11 +5064,11 @@ void Document::addConsoleMessageWithRequestIdentifier(MessageSource source, Mess
return;
}
- if (Page* page = this->page())
- page->console().addMessage(source, level, message, String(), 0, 0, 0, 0, requestIdentifier);
+ if (m_frame)
+ m_frame->console().addMessage(source, level, message, String(), 0, 0, nullptr, 0, requestIdentifier);
}
-// FIXME(crbug.com/305497): This should be removed after ExecutionContext-DOMWindow migration.
+// FIXME(crbug.com/305497): This should be removed after ExecutionContext-LocalDOMWindow migration.
void Document::postTask(PassOwnPtr<ExecutionContextTask> task)
{
m_taskRunner->postTask(task);
@@ -4674,10 +5092,12 @@ void Document::tasksWereResumed()
m_parser->resumeScheduledTasks();
if (m_scriptedAnimationController)
m_scriptedAnimationController->resume();
+
+ MutationObserver::resumeSuspendedObservers();
}
// FIXME: suspendScheduledTasks(), resumeScheduledTasks(), tasksNeedSuspension()
-// should be moved to DOMWindow once it inherits ExecutionContext
+// should be moved to LocalDOMWindow once it inherits ExecutionContext
void Document::suspendScheduledTasks()
{
ExecutionContext::suspendScheduledTasks();
@@ -4729,7 +5149,7 @@ HTMLDialogElement* Document::activeModalDialog() const
return toHTMLDialogElement(m_topLayerElements.last().get());
}
-void Document::webkitExitPointerLock()
+void Document::exitPointerLock()
{
if (!page())
return;
@@ -4740,7 +5160,7 @@ void Document::webkitExitPointerLock()
page()->pointerLockController().requestPointerUnlock();
}
-Element* Document::webkitPointerLockElement() const
+Element* Document::pointerLockElement() const
{
if (!page() || page()->pointerLockController().lockPending())
return 0;
@@ -4756,16 +5176,51 @@ void Document::decrementLoadEventDelayCount()
ASSERT(m_loadEventDelayCount);
--m_loadEventDelayCount;
- if (frame() && !m_loadEventDelayCount && !m_loadEventDelayTimer.isActive())
- m_loadEventDelayTimer.startOneShot(0);
+ if (!m_loadEventDelayCount)
+ checkLoadEventSoon();
+}
+
+void Document::checkLoadEventSoon()
+{
+ if (frame() && !m_loadEventDelayTimer.isActive())
+ m_loadEventDelayTimer.startOneShot(0, FROM_HERE);
+}
+
+bool Document::isDelayingLoadEvent()
+{
+#if ENABLE(OILPAN)
+ // Always delay load events until after garbage collection.
+ // This way we don't have to explicitly delay load events via
+ // incrementLoadEventDelayCount and decrementLoadEventDelayCount in
+ // Node destructors.
+ if (ThreadState::current()->isSweepInProgress()) {
+ if (!m_loadEventDelayCount)
+ checkLoadEventSoon();
+ return true;
+ }
+#endif
+ return m_loadEventDelayCount;
}
+
void Document::loadEventDelayTimerFired(Timer<Document>*)
{
if (frame())
frame()->loader().checkCompleted();
}
+void Document::loadPluginsSoon()
+{
+ // FIXME: Remove this timer once we don't need to compute layout to load plugins.
+ if (!m_pluginLoadingTimer.isActive())
+ m_pluginLoadingTimer.startOneShot(0, FROM_HERE);
+}
+
+void Document::pluginLoadingTimerFired(Timer<Document>*)
+{
+ updateLayout();
+}
+
ScriptedAnimationController& Document::ensureScriptedAnimationController()
{
if (!m_scriptedAnimationController) {
@@ -4796,96 +5251,112 @@ void Document::serviceScriptedAnimations(double monotonicAnimationStartTime)
m_scriptedAnimationController->serviceScriptedAnimations(monotonicAnimationStartTime);
}
-PassRefPtr<Touch> Document::createTouch(DOMWindow* window, EventTarget* target, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const
-{
+PassRefPtrWillBeRawPtr<Touch> Document::createTouch(LocalDOMWindow* window, EventTarget* target, int identifier, double pageX, double pageY, double screenX, double screenY, double radiusX, double radiusY, float rotationAngle, float force) const
+{
+ // Match behavior from when these types were integers, and avoid surprises from someone explicitly
+ // passing Infinity/NaN.
+ if (!std::isfinite(pageX))
+ pageX = 0;
+ if (!std::isfinite(pageY))
+ pageY = 0;
+ if (!std::isfinite(screenX))
+ screenX = 0;
+ if (!std::isfinite(screenY))
+ screenY = 0;
+ if (!std::isfinite(radiusX))
+ radiusX = 0;
+ if (!std::isfinite(radiusY))
+ radiusY = 0;
+ if (!std::isfinite(rotationAngle))
+ rotationAngle = 0;
+ if (!std::isfinite(force))
+ force = 0;
+
// FIXME: It's not clear from the documentation at
// http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html
// when this method should throw and nor is it by inspection of iOS behavior. It would be nice to verify any cases where it throws under iOS
// and implement them here. See https://bugs.webkit.org/show_bug.cgi?id=47819
- Frame* frame = window ? window->frame() : this->frame();
- return Touch::create(frame, target, identifier, screenX, screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force);
+ LocalFrame* frame = window ? window->frame() : this->frame();
+ return Touch::create(frame, target, identifier, FloatPoint(screenX, screenY), FloatPoint(pageX, pageY), FloatSize(radiusX, radiusY), rotationAngle, force);
}
-PassRefPtr<TouchList> Document::createTouchList(Vector<RefPtr<Touch> >& touches) const
+PassRefPtrWillBeRawPtr<TouchList> Document::createTouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches) const
{
return TouchList::create(touches);
}
void Document::didAddTouchEventHandler(Node* handler)
{
+ // The node should either be in this document, or be the Document node of a child
+ // of this document.
+ ASSERT(&handler->document() == this
+ || (handler->isDocumentNode() && toDocument(handler)->parentDocument() == this));
if (!m_touchEventTargets.get())
m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
- m_touchEventTargets->add(handler);
- if (Document* parent = parentDocument()) {
- parent->didAddTouchEventHandler(this);
+ bool isFirstHandler = m_touchEventTargets->isEmpty();
+
+ if (!m_touchEventTargets->add(handler).isNewEntry) {
+ // Just incremented refcount, no real change.
+ // If this is a child document node, then the count should never go above 1.
+ ASSERT(!handler->isDocumentNode() || &handler->document() == this);
return;
}
- if (Page* page = this->page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange(this);
- if (m_touchEventTargets->size() == 1)
- page->chrome().client().needTouchEvents(true);
+
+ if (isFirstHandler) {
+ if (Document* parent = parentDocument()) {
+ parent->didAddTouchEventHandler(this);
+ } else {
+ // This is the first touch handler on the whole page.
+ if (FrameHost* frameHost = this->frameHost())
+ frameHost->chrome().client().needTouchEvents(true);
+ }
+ }
+
+ // When we're all done with all frames, ensure touch hit rects are marked as dirty.
+ if (!handler->isDocumentNode() || handler == this) {
+ if (Page* page = this->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ scrollingCoordinator->touchEventTargetRectsDidChange();
+ }
}
}
-void Document::didRemoveTouchEventHandler(Node* handler)
+void Document::didRemoveTouchEventHandler(Node* handler, bool clearAll)
{
+ // Note that we can't assert that |handler| is in this document because it might be in
+ // the process of moving out of it.
+ ASSERT(clearAll || m_touchEventTargets->contains(handler));
if (!m_touchEventTargets.get())
return;
- ASSERT(m_touchEventTargets->contains(handler));
- m_touchEventTargets->remove(handler);
- if (Document* parent = parentDocument()) {
- parent->didRemoveTouchEventHandler(this);
- return;
- }
- Page* page = this->page();
- if (!page)
- return;
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange(this);
- if (m_touchEventTargets->size())
- return;
- for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document() && frame->document()->hasTouchEventHandlers())
+ if (clearAll) {
+ if (!m_touchEventTargets->contains(handler))
+ return;
+ m_touchEventTargets->removeAll(handler);
+ } else {
+ if (!m_touchEventTargets->remove(handler))
+ // Just decremented refcount, no real update.
return;
}
- page->chrome().client().needTouchEvents(false);
-}
-void Document::didRemoveEventTargetNode(Node* handler)
-{
- if (m_touchEventTargets && !m_touchEventTargets->isEmpty()) {
- if (handler == this)
- m_touchEventTargets->clear();
- else
- m_touchEventTargets->removeAll(handler);
- if (m_touchEventTargets->isEmpty() && parentDocument())
- parentDocument()->didRemoveEventTargetNode(this);
+ if (m_touchEventTargets->isEmpty()) {
+ if (Document* parent = parentDocument()) {
+ // This was the last handler in this document, update the parent document too.
+ parent->didRemoveTouchEventHandler(this, clearAll);
+ } else {
+ // We just removed the last touch handler on the whole page.
+ if (FrameHost* frameHost = this->frameHost())
+ frameHost->chrome().client().needTouchEvents(false);
+ }
}
-}
-
-void Document::resetLastHandledUserGestureTimestamp()
-{
- m_lastHandledUserGestureTimestamp = currentTime();
-}
-
-HTMLIFrameElement* Document::seamlessParentIFrame() const
-{
- if (!shouldDisplaySeamlesslyWithParent())
- return 0;
-
- return toHTMLIFrameElement(this->ownerElement());
-}
-bool Document::shouldDisplaySeamlesslyWithParent() const
-{
- if (!RuntimeEnabledFeatures::seamlessIFramesEnabled())
- return false;
- HTMLFrameOwnerElement* ownerElement = this->ownerElement();
- if (!ownerElement)
- return false;
- return m_mayDisplaySeamlesslyWithParent && ownerElement->hasTagName(iframeTag) && ownerElement->fastHasAttribute(seamlessAttr);
+ // When we're all done with all frames, ensure touch hit rects are marked as dirty.
+ if (!handler->isDocumentNode() || handler == this) {
+ if (Page* page = this->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ scrollingCoordinator->touchEventTargetRectsDidChange();
+ }
+ }
}
DocumentLoader* Document::loader() const
@@ -4907,7 +5378,7 @@ IntSize Document::initialViewportSize() const
{
if (!view())
return IntSize();
- return view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
+ return view()->unscaledVisibleContentSize(IncludeScrollbars);
}
Node* eventTargetNodeForDocument(Document* doc)
@@ -4933,7 +5404,7 @@ void Document::adjustFloatQuadsForScrollAndAbsoluteZoom(Vector<FloatQuad>& quads
LayoutRect visibleContentRect = view()->visibleContentRect();
for (size_t i = 0; i < quads.size(); ++i) {
- quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
+ quads[i].move(-FloatSize(visibleContentRect.x().toFloat(), visibleContentRect.y().toFloat()));
adjustFloatQuadForAbsoluteZoom(quads[i], renderer);
}
}
@@ -4944,7 +5415,7 @@ void Document::adjustFloatRectForScrollAndAbsoluteZoom(FloatRect& rect, RenderOb
return;
LayoutRect visibleContentRect = view()->visibleContentRect();
- rect.move(-visibleContentRect.x(), -visibleContentRect.y());
+ rect.move(-FloatSize(visibleContentRect.x().toFloat(), visibleContentRect.y().toFloat()));
adjustFloatRectForAbsoluteZoom(rect, renderer);
}
@@ -4961,13 +5432,12 @@ void Document::decrementActiveParserCount()
// FIXME: This should always be enabled, but it seems to cause
// http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1
// see http://webkit.org/b/110554 and http://webkit.org/b/110401
- loader()->checkLoadComplete();
frame()->loader().checkLoadComplete();
}
-void Document::setContextFeatures(PassRefPtr<ContextFeatures> features)
+void Document::setContextFeatures(ContextFeatures& features)
{
- m_contextFeatures = features;
+ m_contextFeatures = PassRefPtrWillBeRawPtr<ContextFeatures>(features);
}
static RenderObject* nearestCommonHoverAncestor(RenderObject* obj1, RenderObject* obj2)
@@ -4998,7 +5468,7 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
innerElementInDocument = innerElementInDocument->document().ownerElement();
}
- Element* oldActiveElement = activeElement();
+ Element* oldActiveElement = activeHoverElement();
if (oldActiveElement && !request.active()) {
// We are clearing the :active chain because the mouse has been released.
for (RenderObject* curr = oldActiveElement->renderer(); curr; curr = curr->parent()) {
@@ -5008,10 +5478,10 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
m_userActionElements.setInActiveChain(curr->node(), false);
}
}
- setActiveElement(0);
+ setActiveHoverElement(nullptr);
} else {
Element* newActiveElement = innerElementInDocument;
- if (!oldActiveElement && newActiveElement && request.active() && !request.touchMove()) {
+ if (!oldActiveElement && newActiveElement && !newActiveElement->isDisabledFormControl() && request.active() && !request.touchMove()) {
// We are setting the :active chain and freezing it. If future moves happen, they
// will need to reference this chain.
for (RenderObject* curr = newActiveElement->renderer(); curr; curr = curr->parent()) {
@@ -5019,19 +5489,19 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
m_userActionElements.setInActiveChain(curr->node(), true);
}
- setActiveElement(newActiveElement);
+ setActiveHoverElement(newActiveElement);
}
}
// If the mouse has just been pressed, set :active on the chain. Those (and only those)
// nodes should remain :active until the mouse is released.
- bool allowActiveChanges = !oldActiveElement && activeElement();
+ bool allowActiveChanges = !oldActiveElement && activeHoverElement();
// If the mouse is down and if this is a mouse move event, we want to restrict changes in
// :hover/:active to only apply to elements that are in the :active chain that we froze
// at the time the mouse went down.
bool mustBeInActiveChain = request.active() && request.move();
- RefPtr<Node> oldHoverNode = hoverNode();
+ RefPtrWillBeRawPtr<Node> oldHoverNode = hoverNode();
// Check to see if the hovered node has changed.
// If it hasn't, we do not need to do anything.
@@ -5048,10 +5518,10 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
// Locate the common ancestor render object for the two renderers.
RenderObject* ancestor = nearestCommonHoverAncestor(oldHoverObj, newHoverObj);
- RefPtr<Node> ancestorNode(ancestor ? ancestor->node() : 0);
+ RefPtrWillBeRawPtr<Node> ancestorNode(ancestor ? ancestor->node() : 0);
- Vector<RefPtr<Node>, 32> nodesToRemoveFromChain;
- Vector<RefPtr<Node>, 32> nodesToAddToChain;
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 32> nodesToRemoveFromChain;
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 32> nodesToAddToChain;
if (oldHoverObj != newHoverObj) {
// If the old hovered node is not nil but it's renderer is, it was probably detached as part of the :hover style
@@ -5125,8 +5595,6 @@ void Document::updateHoverActiveState(const HitTestRequest& request, Element* in
nodesToAddToChain[i]->dispatchMouseEvent(*event, EventTypeNames::mouseenter, 0, oldHoverNode.get());
}
}
-
- updateStyleIfNeeded();
}
bool Document::haveStylesheetsLoaded() const
@@ -5141,23 +5609,26 @@ Locale& Document::getCachedLocale(const AtomicString& locale)
return Locale::defaultLocale();
LocaleIdentifierToLocaleMap::AddResult result = m_localeCache.add(localeKey, nullptr);
if (result.isNewEntry)
- result.iterator->value = Locale::create(localeKey);
- return *(result.iterator->value);
+ result.storedValue->value = Locale::create(localeKey);
+ return *(result.storedValue->value);
}
Document& Document::ensureTemplateDocument()
{
- if (const Document* document = templateDocument())
- return *const_cast<Document*>(document);
+ if (isTemplateDocument())
+ return *this;
+
+ if (m_templateDocument)
+ return *m_templateDocument;
if (isHTMLDocument()) {
- DocumentInit init = DocumentInit::fromContext(contextDocument(), blankURL());
+ DocumentInit init = DocumentInit::fromContext(contextDocument(), blankURL()).withNewRegistrationContext();
m_templateDocument = HTMLDocument::create(init);
} else {
m_templateDocument = Document::create(DocumentInit(blankURL()));
}
- m_templateDocument->setTemplateDocumentHost(this); // balanced in dtor.
+ m_templateDocument->m_templateDocumentHost = this; // balanced in dtor.
return *m_templateDocument.get();
}
@@ -5168,7 +5639,7 @@ void Document::didAssociateFormControl(Element* element)
return;
m_associatedFormControls.add(element);
if (!m_didAssociateFormControlsTimer.isActive())
- m_didAssociateFormControlsTimer.startOneShot(0);
+ m_didAssociateFormControlsTimer.startOneShot(0, FROM_HERE);
}
void Document::didAssociateFormControlsTimerFired(Timer<Document>* timer)
@@ -5177,7 +5648,7 @@ void Document::didAssociateFormControlsTimerFired(Timer<Document>* timer)
if (!frame() || !frame()->page())
return;
- Vector<RefPtr<Element> > associatedFormControls;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > associatedFormControls;
copyToVector(m_associatedFormControls, associatedFormControls);
frame()->page()->chrome().client().didAssociateFormControls(associatedFormControls);
@@ -5199,24 +5670,24 @@ DocumentLifecycleNotifier& Document::lifecycleNotifier()
return static_cast<DocumentLifecycleNotifier&>(LifecycleContext<Document>::lifecycleNotifier());
}
-void Document::removedStyleSheet(StyleSheet* sheet, RecalcStyleTime when, StyleResolverUpdateMode updateMode)
+void Document::removedStyleSheet(StyleSheet* sheet, StyleResolverUpdateMode updateMode)
{
// If we're in document teardown, then we don't need this notification of our sheet's removal.
// styleResolverChanged() is needed even when the document is inactive so that
// imported docuements (which is inactive) notifies the change to the master document.
if (isActive())
styleEngine()->modifiedStyleSheet(sheet);
- styleResolverChanged(when, updateMode);
+ styleResolverChanged(updateMode);
}
-void Document::modifiedStyleSheet(StyleSheet* sheet, RecalcStyleTime when, StyleResolverUpdateMode updateMode)
+void Document::modifiedStyleSheet(StyleSheet* sheet, StyleResolverUpdateMode updateMode)
{
// If we're in document teardown, then we don't need this notification of our sheet's removal.
// styleResolverChanged() is needed even when the document is inactive so that
// imported docuements (which is inactive) notifies the change to the master document.
if (isActive())
styleEngine()->modifiedStyleSheet(sheet);
- styleResolverChanged(when, updateMode);
+ styleResolverChanged(updateMode);
}
TextAutosizer* Document::textAutosizer()
@@ -5233,4 +5704,170 @@ FastTextAutosizer* Document::fastTextAutosizer()
return m_fastTextAutosizer.get();
}
+void Document::setAutofocusElement(Element* element)
+{
+ if (!element) {
+ m_autofocusElement = nullptr;
+ return;
+ }
+ if (m_hasAutofocused)
+ return;
+ m_hasAutofocused = true;
+ ASSERT(!m_autofocusElement);
+ m_autofocusElement = element;
+ m_taskRunner->postTask(AutofocusTask::create());
+}
+
+Element* Document::activeElement() const
+{
+ if (Element* element = treeScope().adjustedFocusedElement())
+ return element;
+ return body();
+}
+
+bool Document::hasFocus() const
+{
+ Page* page = this->page();
+ if (!page)
+ return false;
+ if (!page->focusController().isActive() || !page->focusController().isFocused())
+ return false;
+ Frame* focusedFrame = page->focusController().focusedFrame();
+ if (focusedFrame && focusedFrame->isLocalFrame()) {
+ if (toLocalFrame(focusedFrame)->tree().isDescendantOf(frame()))
+ return true;
+ }
+ return false;
+}
+
+#if ENABLE(OILPAN)
+template<unsigned type>
+bool shouldInvalidateNodeListCachesForAttr(const HeapHashSet<WeakMember<const LiveNodeListBase> > nodeLists[], const QualifiedName& attrName)
+{
+ if (!nodeLists[type].isEmpty() && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
+ return true;
+ return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeLists, attrName);
+}
+
+template<>
+bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const HeapHashSet<WeakMember<const LiveNodeListBase> >[], const QualifiedName&)
+{
+ return false;
+}
+#else
+template<unsigned type>
+bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName)
+{
+ if (nodeListCounts[type] && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
+ return true;
+ return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName);
+}
+
+template<>
+bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&)
+{
+ return false;
+}
+#endif
+
+bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const
+{
+ if (attrName) {
+#if ENABLE(OILPAN)
+ return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeLists, *attrName);
+#else
+ return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListCounts, *attrName);
+#endif
+ }
+
+ for (int type = 0; type < numNodeListInvalidationTypes; ++type) {
+#if ENABLE(OILPAN)
+ if (!m_nodeLists[type].isEmpty())
+#else
+ if (m_nodeListCounts[type])
+#endif
+ return true;
+ }
+
+ return false;
+}
+
+void Document::invalidateNodeListCaches(const QualifiedName* attrName)
+{
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<const LiveNodeListBase> >::const_iterator end = m_listsInvalidatedAtDocument.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<const LiveNodeListBase> >::const_iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it)
+ (*it)->invalidateCacheForAttribute(attrName);
+}
+
+void Document::clearWeakMembers(Visitor* visitor)
+{
+ if (m_axObjectCache)
+ m_axObjectCache->clearWeakMembers(visitor);
+
+ // FIXME: Oilpan: Use a weak counted set instead.
+ if (m_touchEventTargets) {
+ Vector<Node*> deadNodes;
+ for (TouchEventTargetSet::iterator it = m_touchEventTargets->begin(); it != m_touchEventTargets->end(); ++it) {
+ if (!visitor->isAlive(it->key))
+ deadNodes.append(it->key);
+ }
+ for (unsigned i = 0; i < deadNodes.size(); ++i)
+ didClearTouchEventHandlers(deadNodes[i]);
+ }
+}
+
+void Document::trace(Visitor* visitor)
+{
+ visitor->trace(m_importsController);
+ visitor->trace(m_docType);
+ visitor->trace(m_implementation);
+ visitor->trace(m_autofocusElement);
+ visitor->trace(m_focusedElement);
+ visitor->trace(m_hoverNode);
+ visitor->trace(m_activeHoverElement);
+ visitor->trace(m_documentElement);
+ visitor->trace(m_titleElement);
+ visitor->trace(m_markers);
+ visitor->trace(m_cssTarget);
+ visitor->trace(m_currentScriptStack);
+ visitor->trace(m_scriptRunner);
+ visitor->trace(m_transformSourceDocument);
+ visitor->trace(m_listsInvalidatedAtDocument);
+#if ENABLE(OILPAN)
+ for (int i = 0; i < numNodeListInvalidationTypes; ++i)
+ visitor->trace(m_nodeLists[i]);
+#endif
+ visitor->trace(m_cssCanvasElements);
+ visitor->trace(m_topLayerElements);
+ visitor->trace(m_elemSheet);
+ visitor->trace(m_nodeIterators);
+ visitor->trace(m_ranges);
+ visitor->trace(m_styleEngine);
+ visitor->trace(m_formController);
+ visitor->trace(m_domWindow);
+ visitor->trace(m_fetcher);
+ visitor->trace(m_parser);
+ visitor->trace(m_contextFeatures);
+ visitor->trace(m_styleSheetList);
+ visitor->trace(m_mediaQueryMatcher);
+ visitor->trace(m_scriptedAnimationController);
+ visitor->trace(m_registrationContext);
+ visitor->trace(m_associatedFormControls);
+ visitor->trace(m_useElementsNeedingUpdate);
+ visitor->trace(m_layerUpdateSVGFilterElements);
+ visitor->trace(m_templateDocument);
+ visitor->trace(m_templateDocumentHost);
+ visitor->trace(m_visibilityObservers);
+ visitor->trace(m_userActionElements);
+ visitor->trace(m_svgExtensions);
+ visitor->trace(m_timeline);
+ visitor->trace(m_compositorPendingAnimations);
+ visitor->trace(m_contextDocument);
+ visitor->registerWeakMembers<Document, &Document::clearWeakMembers>(this);
+ DocumentSupplementable::trace(visitor);
+ TreeScope::trace(visitor);
+ ContainerNode::trace(visitor);
+ ExecutionContext::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Document.h b/chromium/third_party/WebKit/Source/core/dom/Document.h
index cc23012b679..a8f6f8050f5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Document.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Document.h
@@ -28,10 +28,11 @@
#ifndef Document_h
#define Document_h
+#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptValue.h"
-#include "core/animation/css/CSSPendingAnimations.h"
+#include "core/animation/AnimationClock.h"
+#include "core/animation/CompositorPendingAnimations.h"
#include "core/dom/ContainerNode.h"
-#include "core/dom/DOMTimeStamp.h"
#include "core/dom/DocumentEncodingData.h"
#include "core/dom/DocumentInit.h"
#include "core/dom/DocumentLifecycle.h"
@@ -47,10 +48,13 @@
#include "core/dom/ViewportDescription.h"
#include "core/dom/custom/CustomElement.h"
#include "core/html/CollectionType.h"
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
#include "core/page/PageVisibilityState.h"
#include "core/rendering/HitTestRequest.h"
+#include "platform/Length.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
+#include "platform/weborigin/KURL.h"
#include "platform/weborigin/ReferrerPolicy.h"
#include "wtf/HashSet.h"
#include "wtf/OwnPtr.h"
@@ -61,14 +65,13 @@
namespace WebCore {
class AXObjectCache;
-class AnimationClock;
class Attr;
class CDATASection;
class CSSFontSelector;
class CSSStyleDeclaration;
class CSSStyleSheet;
class CSSStyleSheetResource;
-class CanvasRenderingContext;
+class CanvasRenderingContext2D;
class CharacterData;
class Chrome;
class Comment;
@@ -76,11 +79,8 @@ class ContentSecurityPolicyResponseHeaders;
class ContextFeatures;
class CustomElementRegistrationContext;
class DOMImplementation;
-class DOMNamedFlowCollection;
-class DOMSecurityPolicy;
class DOMSelection;
-class DOMWindow;
-class DOMWrapperWorld;
+class LocalDOMWindow;
class Database;
class DatabaseThread;
class DocumentFragment;
@@ -89,19 +89,22 @@ class DocumentLifecycleObserver;
class DocumentLoader;
class DocumentMarkerController;
class DocumentParser;
-class DocumentSharedObjectPool;
-class DocumentTimeline;
+class DocumentState;
+class AnimationTimeline;
class DocumentType;
class Element;
+class ElementDataCache;
class Event;
+class EventFactoryBase;
class EventListener;
class ExceptionState;
-class MainThreadTaskRunner;
class FastTextAutosizer;
class FloatQuad;
class FloatRect;
+class FontFaceSet;
class FormController;
class Frame;
+class FrameHost;
class FrameView;
class HTMLAllCollection;
class HTMLCanvasElement;
@@ -113,6 +116,9 @@ class HTMLFrameOwnerElement;
class HTMLHeadElement;
class HTMLIFrameElement;
class HTMLImport;
+class HTMLImportLoader;
+class HTMLImportsController;
+class HTMLLinkElement;
class HTMLMapElement;
class HTMLNameCollection;
class HTMLScriptElement;
@@ -124,11 +130,12 @@ class LayoutPoint;
class LayoutRect;
class LiveNodeListBase;
class Locale;
+class LocalFrame;
class Location;
+class MainThreadTaskRunner;
class MediaQueryList;
class MediaQueryMatcher;
class MouseEventWithHitTestResults;
-class NamedFlowCollection;
class NodeFilter;
class NodeIterator;
class Page;
@@ -140,6 +147,7 @@ class RenderView;
class RequestAnimationFrameCallback;
class ResourceFetcher;
class SVGDocumentExtensions;
+class SVGUseElement;
class ScriptElementData;
class ScriptResource;
class ScriptRunner;
@@ -162,19 +170,13 @@ class TouchList;
class TransformSource;
class TreeWalker;
class VisitedLinkState;
+class WebGLRenderingContext;
class XMLHttpRequest;
struct AnnotatedRegionValue;
-class FontFaceSet;
-
typedef int ExceptionCode;
-enum RecalcStyleTime {
- RecalcStyleImmediately, // synchronous
- RecalcStyleDeferred // asynchronous
-};
-
enum StyleResolverUpdateMode {
// Discards the StyleResolver and rebuilds it.
FullStyleUpdate,
@@ -190,7 +192,6 @@ enum NodeListInvalidationType {
InvalidateOnForAttrChange,
InvalidateForFormControls,
InvalidateOnHRefAttrChange,
- InvalidateOnItemAttrChange,
InvalidateOnAnyAttrChange,
};
const int numNodeListInvalidationTypes = InvalidateOnAnyAttrChange + 1;
@@ -205,20 +206,42 @@ enum DocumentClass {
PluginDocumentClass = 1 << 3,
MediaDocumentClass = 1 << 4,
SVGDocumentClass = 1 << 5,
+ XMLDocumentClass = 1 << 6,
};
typedef unsigned char DocumentClassFlags;
+class Document;
+
+class DocumentVisibilityObserver : public WillBeGarbageCollectedMixin {
+public:
+ DocumentVisibilityObserver(Document&);
+ virtual ~DocumentVisibilityObserver();
+
+ virtual void didChangeVisibilityState(PageVisibilityState) = 0;
+
+ // Classes that inherit Node and DocumentVisibilityObserver must have a
+ // virtual override of Node::didMoveToNewDocument that calls
+ // DocumentVisibilityObserver::setDocument
+ void setObservedDocument(Document&);
+
+protected:
+ void trace(Visitor*);
+
+private:
+ void registerObserver(Document&);
+ void unregisterObserver();
+
+ RawPtrWillBeMember<Document> m_document;
+};
+
class Document : public ContainerNode, public TreeScope, public SecurityContext, public ExecutionContext, public ExecutionContextClient
, public DocumentSupplementable, public LifecycleContext<Document> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Document);
public:
- static PassRefPtr<Document> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<Document> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new Document(initializer));
- }
- static PassRefPtr<Document> createXHTML(const DocumentInit& initializer = DocumentInit())
- {
- return adoptRef(new Document(initializer, XHTMLDocumentClass));
+ return adoptRefWillBeNoop(new Document(initializer));
}
virtual ~Document();
@@ -226,16 +249,23 @@ public:
void mediaQueryAffectingValueChanged();
+#if !ENABLE(OILPAN)
using ContainerNode::ref;
using ContainerNode::deref;
+#endif
using SecurityContext::securityOrigin;
using SecurityContext::contentSecurityPolicy;
using ExecutionContextClient::addConsoleMessage;
+ using TreeScope::getElementById;
- virtual bool canContainRangeEndPoint() const { return true; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return true; }
SelectorQueryCache& selectorQueryCache();
+ // Focus Management.
+ Element* activeElement() const;
+ bool hasFocus() const;
+
// DOM methods & attributes for Document
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
@@ -244,6 +274,8 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(copy);
DEFINE_ATTRIBUTE_EVENT_LISTENER(cut);
DEFINE_ATTRIBUTE_EVENT_LISTENER(paste);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(pointerlockerror);
DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
DEFINE_ATTRIBUTE_EVENT_LISTENER(securitypolicyviolation);
@@ -263,66 +295,51 @@ public:
bool shouldOverrideLegacyDescription(ViewportDescription::Type);
void setViewportDescription(const ViewportDescription&);
const ViewportDescription& viewportDescription() const { return m_viewportDescription; }
+ Length viewportDefaultMinWidth() const { return m_viewportDefaultMinWidth; }
+
#ifndef NDEBUG
bool didDispatchViewportPropertiesChanged() const { return m_didDispatchViewportPropertiesChanged; }
#endif
bool hasLegacyViewportTag() const { return m_legacyViewportDescription.isLegacyViewportType(); }
- void setReferrerPolicy(ReferrerPolicy referrerPolicy) { m_referrerPolicy = referrerPolicy; }
+ void setReferrerPolicy(ReferrerPolicy);
ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
String outgoingReferrer();
String outgoingOrigin() const;
- void setDoctype(PassRefPtr<DocumentType>);
+ void setDoctype(PassRefPtrWillBeRawPtr<DocumentType>);
DocumentType* doctype() const { return m_docType.get(); }
- DOMImplementation* implementation();
+ DOMImplementation& implementation();
Element* documentElement() const
{
return m_documentElement.get();
}
- bool hasManifest() const;
+ // Returns whether the Document has an AppCache manifest.
+ bool hasAppCacheManifest() const;
Location* location() const;
- PassRefPtr<Element> createElement(const AtomicString& name, ExceptionState&);
- PassRefPtr<DocumentFragment> createDocumentFragment();
- PassRefPtr<Text> createTextNode(const String& data);
- PassRefPtr<Comment> createComment(const String& data);
- PassRefPtr<CDATASection> createCDATASection(const String& data, ExceptionState&);
- PassRefPtr<ProcessingInstruction> createProcessingInstruction(const String& target, const String& data, ExceptionState&);
- PassRefPtr<Attr> createAttribute(const AtomicString& name, ExceptionState&);
- PassRefPtr<Attr> createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&, bool shouldIgnoreNamespaceChecks = false);
- PassRefPtr<Node> importNode(Node* importedNode, ExceptionState& ec) { return importNode(importedNode, true, ec); }
- PassRefPtr<Node> importNode(Node* importedNode, bool deep, ExceptionState&);
- PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&);
- PassRefPtr<Element> createElement(const QualifiedName&, bool createdByParser);
-
- PassRefPtr<DOMNamedFlowCollection> webkitGetNamedFlows();
-
- NamedFlowCollection* namedFlows();
+ PassRefPtrWillBeRawPtr<Element> createElement(const AtomicString& name, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> createDocumentFragment();
+ PassRefPtrWillBeRawPtr<Text> createTextNode(const String& data);
+ PassRefPtrWillBeRawPtr<Comment> createComment(const String& data);
+ PassRefPtrWillBeRawPtr<CDATASection> createCDATASection(const String& data, ExceptionState&);
+ PassRefPtrWillBeRawPtr<ProcessingInstruction> createProcessingInstruction(const String& target, const String& data, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> createAttribute(const AtomicString& name, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> createAttributeNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&, bool shouldIgnoreNamespaceChecks = false);
+ PassRefPtrWillBeRawPtr<Node> importNode(Node* importedNode, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> importNode(Node* importedNode, bool deep, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Element> createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Element> createElement(const QualifiedName&, bool createdByParser);
bool regionBasedColumnsEnabled() const;
- /**
- * Retrieve all nodes that intersect a rect in the window's document, until it is fully enclosed by
- * the boundaries of a node.
- *
- * @param centerX x reference for the rectangle in CSS pixels
- * @param centerY y reference for the rectangle in CSS pixels
- * @param topPadding How much to expand the top of the rectangle
- * @param rightPadding How much to expand the right of the rectangle
- * @param bottomPadding How much to expand the bottom of the rectangle
- * @param leftPadding How much to expand the left of the rectangle
- */
- PassRefPtr<NodeList> nodesFromRect(int centerX, int centerY,
- unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding,
- HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent) const;
Element* elementFromPoint(int x, int y) const;
- PassRefPtr<Range> caretRangeFromPoint(int x, int y);
+ PassRefPtrWillBeRawPtr<Range> caretRangeFromPoint(int x, int y);
String readyState() const;
@@ -339,6 +356,8 @@ public:
void setContent(const String&);
String suggestedMIMEType() const;
+ void setMimeType(const AtomicString&);
+ AtomicString contentType() const; // DOM 4 document.contentType
const AtomicString& contentLanguage() const { return m_contentLanguage; }
void setContentLanguage(const AtomicString&);
@@ -355,33 +374,30 @@ public:
void setXMLStandalone(bool, ExceptionState&);
void setHasXMLDeclaration(bool hasXMLDeclaration) { m_hasXMLDeclaration = hasXMLDeclaration ? 1 : 0; }
- String documentURI() const { return m_documentURI; }
-
- virtual KURL baseURI() const;
+ virtual KURL baseURI() const OVERRIDE FINAL;
String visibilityState() const;
bool hidden() const;
- void dispatchVisibilityStateChangeEvent();
-
- DOMSecurityPolicy* securityPolicy();
+ void didChangeVisibilityState();
- PassRefPtr<Node> adoptNode(PassRefPtr<Node> source, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState&);
- PassRefPtr<HTMLCollection> images();
- PassRefPtr<HTMLCollection> embeds();
- PassRefPtr<HTMLCollection> applets();
- PassRefPtr<HTMLCollection> links();
- PassRefPtr<HTMLCollection> forms();
- PassRefPtr<HTMLCollection> anchors();
- PassRefPtr<HTMLCollection> scripts();
- PassRefPtr<HTMLCollection> allForBinding();
- PassRefPtr<HTMLCollection> all();
+ PassRefPtrWillBeRawPtr<HTMLCollection> images();
+ PassRefPtrWillBeRawPtr<HTMLCollection> embeds();
+ PassRefPtrWillBeRawPtr<HTMLCollection> applets();
+ PassRefPtrWillBeRawPtr<HTMLCollection> links();
+ PassRefPtrWillBeRawPtr<HTMLCollection> forms();
+ PassRefPtrWillBeRawPtr<HTMLCollection> anchors();
+ PassRefPtrWillBeRawPtr<HTMLCollection> scripts();
+ PassRefPtrWillBeRawPtr<HTMLAllCollection> allForBinding();
+ PassRefPtrWillBeRawPtr<HTMLAllCollection> all();
- PassRefPtr<HTMLCollection> windowNamedItems(const AtomicString& name);
- PassRefPtr<HTMLCollection> documentNamedItems(const AtomicString& name);
+ PassRefPtrWillBeRawPtr<HTMLCollection> windowNamedItems(const AtomicString& name);
+ PassRefPtrWillBeRawPtr<HTMLCollection> documentNamedItems(const AtomicString& name);
bool isHTMLDocument() const { return m_documentClasses & HTMLDocumentClass; }
bool isXHTMLDocument() const { return m_documentClasses & XHTMLDocumentClass; }
+ bool isXMLDocument() const { return m_documentClasses & XMLDocumentClass; }
bool isImageDocument() const { return m_documentClasses & ImageDocumentClass; }
bool isSVGDocument() const { return m_documentClasses & SVGDocumentClass; }
bool isPluginDocument() const { return m_documentClasses & PluginDocumentClass; }
@@ -394,6 +410,9 @@ public:
bool isSrcdocDocument() const { return m_isSrcdocDocument; }
bool isMobileDocument() const { return m_isMobileDocument; }
+ bool isTransitionDocument() const { return m_isTransitionDocument; }
+ void setIsTransitionDocument() { m_isTransitionDocument = true; }
+
StyleResolver* styleResolver() const;
StyleResolver& ensureStyleResolver() const;
@@ -402,10 +421,8 @@ public:
bool sawElementsInKnownNamespaces() const { return m_sawElementsInKnownNamespaces; }
- void notifyRemovePendingSheetIfNeeded();
-
- bool haveStylesheetsLoaded() const;
- bool haveStylesheetsAndImportsLoaded() const { return haveImportsLoaded() && haveStylesheetsLoaded(); }
+ bool isRenderingReady() const { return haveImportsLoaded() && haveStylesheetsLoaded(); }
+ bool isScriptExecutionReady() const { return isRenderingReady(); }
// This is a DOM function.
StyleSheetList* styleSheets();
@@ -416,55 +433,61 @@ public:
void setGotoAnchorNeededAfterStylesheetsLoad(bool b) { m_gotoAnchorNeededAfterStylesheetsLoad = b; }
// Called when one or more stylesheets in the document may have been added, removed, or changed.
- void styleResolverChanged(RecalcStyleTime, StyleResolverUpdateMode = FullStyleUpdate);
+ void styleResolverChanged(StyleResolverUpdateMode = FullStyleUpdate);
+ void styleResolverMayHaveChanged();
// FIXME: Switch all callers of styleResolverChanged to these or better ones and then make them
// do something smarter.
- void removedStyleSheet(StyleSheet*, RecalcStyleTime when = RecalcStyleDeferred, StyleResolverUpdateMode = FullStyleUpdate);
- void addedStyleSheet(StyleSheet*, RecalcStyleTime when = RecalcStyleDeferred) { styleResolverChanged(when); }
- void modifiedStyleSheet(StyleSheet*, RecalcStyleTime when = RecalcStyleDeferred, StyleResolverUpdateMode = FullStyleUpdate);
- void changedSelectorWatch() { styleResolverChanged(RecalcStyleDeferred); }
+ void removedStyleSheet(StyleSheet*, StyleResolverUpdateMode = FullStyleUpdate);
+ void addedStyleSheet(StyleSheet*) { styleResolverChanged(); }
+ void modifiedStyleSheet(StyleSheet*, StyleResolverUpdateMode = FullStyleUpdate);
+ void changedSelectorWatch() { styleResolverChanged(); }
+
+ void scheduleUseShadowTreeUpdate(SVGUseElement&);
+ void unscheduleUseShadowTreeUpdate(SVGUseElement&);
+
+ // FIXME: SVG filters should change to store the filter on the RenderStyle
+ // instead of the RenderObject so we can get rid of this hack.
+ void scheduleSVGFilterLayerUpdateHack(Element&);
+ void unscheduleSVGFilterLayerUpdateHack(Element&);
void evaluateMediaQueryList();
- // Never returns 0.
- FormController* formController();
- Vector<String> formElementsState() const;
+ FormController& formController();
+ DocumentState* formElementsState() const;
void setStateForNewFormElements(const Vector<String>&);
FrameView* view() const; // can be null
- Frame* frame() const { return m_frame; } // can be null
+ LocalFrame* frame() const { return m_frame; } // can be null
+ FrameHost* frameHost() const; // can be null
Page* page() const; // can be null
Settings* settings() const; // can be null
float devicePixelRatio() const;
- PassRefPtr<Range> createRange();
+ PassRefPtrWillBeRawPtr<Range> createRange();
- PassRefPtr<NodeIterator> createNodeIterator(Node* root, ExceptionState&);
- PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, ExceptionState&);
- PassRefPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter>, ExceptionState&);
+ PassRefPtrWillBeRawPtr<NodeIterator> createNodeIterator(Node* root, ExceptionState&);
+ PassRefPtrWillBeRawPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, ExceptionState&);
+ PassRefPtrWillBeRawPtr<NodeIterator> createNodeIterator(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>, ExceptionState&);
- PassRefPtr<TreeWalker> createTreeWalker(Node* root, ExceptionState&);
- PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, ExceptionState&);
- PassRefPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter>, ExceptionState&);
+ PassRefPtrWillBeRawPtr<TreeWalker> createTreeWalker(Node* root, ExceptionState&);
+ PassRefPtrWillBeRawPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, ExceptionState&);
+ PassRefPtrWillBeRawPtr<TreeWalker> createTreeWalker(Node* root, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>, ExceptionState&);
// Special support for editing
- PassRefPtr<CSSStyleDeclaration> createCSSStyleDeclaration();
- PassRefPtr<Text> createEditingTextNode(const String&);
+ PassRefPtrWillBeRawPtr<Text> createEditingTextNode(const String&);
- void setStyleDependentState(RenderStyle* documentStyle);
- void inheritHtmlAndBodyElementStyles(StyleRecalcChange);
- void recalcStyle(StyleRecalcChange);
- void updateStyleIfNeeded();
- void updateStyleForNodeIfNeeded(Node*);
+ void setupFontBuilder(RenderStyle* documentStyle);
+
+ void updateRenderTreeIfNeeded() { updateRenderTree(NoChange); }
+ void updateRenderTreeForNodeIfNeeded(Node*);
void updateLayout();
enum RunPostLayoutTasks {
RunPostLayoutTasksAsyhnchronously,
RunPostLayoutTasksSynchronously,
};
void updateLayoutIgnorePendingStylesheets(RunPostLayoutTasks = RunPostLayoutTasksAsyhnchronously);
- void partialUpdateLayoutIgnorePendingStylesheets(Node*);
PassRefPtr<RenderStyle> styleForElementIgnoringPendingStylesheets(Element*);
PassRefPtr<RenderStyle> styleForPage(int pageIndex);
@@ -485,6 +508,9 @@ public:
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
void prepareForDestruction();
+ // If you have a Document, use renderView() instead which is faster.
+ void renderer() const WTF_DELETED_FUNCTION;
+
RenderView* renderView() const { return m_renderView; }
AXObjectCache* existingAXObjectCache() const;
@@ -492,16 +518,15 @@ public:
void clearAXObjectCache();
// to get visually ordered hebrew and arabic pages right
- void setVisuallyOrdered();
bool visuallyOrdered() const { return m_visuallyOrdered; }
DocumentLoader* loader() const;
- void open(Document* ownerDocument = 0);
- PassRefPtr<DocumentParser> implicitOpen();
+ void open(Document* ownerDocument = 0, ExceptionState& = ASSERT_NO_EXCEPTION);
+ PassRefPtrWillBeRawPtr<DocumentParser> implicitOpen();
// close() is the DOM API document.close()
- void close();
+ void close(ExceptionState& = ASSERT_NO_EXCEPTION);
// In some situations (see the code), we ignore document.close().
// explicitClose() bypass these checks and actually tries to close the
// input stream.
@@ -522,9 +547,9 @@ public:
void cancelParsing();
- void write(const SegmentedString& text, Document* ownerDocument = 0);
- void write(const String& text, Document* ownerDocument = 0);
- void writeln(const String& text, Document* ownerDocument = 0);
+ void write(const SegmentedString& text, Document* ownerDocument = 0, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void write(const String& text, Document* ownerDocument = 0, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void writeln(const String& text, Document* ownerDocument = 0, ExceptionState& = ASSERT_NO_EXCEPTION);
bool wellFormed() const { return m_wellFormed; }
@@ -537,21 +562,21 @@ public:
void setBaseURLOverride(const KURL&);
const KURL& baseURLOverride() const { return m_baseURLOverride; }
const KURL& baseElementURL() const { return m_baseElementURL; }
- const String& baseTarget() const { return m_baseTarget; }
+ const AtomicString& baseTarget() const { return m_baseTarget; }
void processBaseElement();
KURL completeURL(const String&) const;
- KURL completeURL(const String&, const KURL& baseURLOverride) const;
+ KURL completeURLWithOverride(const String&, const KURL& baseURLOverride) const;
- virtual String userAgent(const KURL&) const;
- virtual void disableEval(const String& errorMessage);
+ virtual String userAgent(const KURL&) const OVERRIDE FINAL;
+ virtual void disableEval(const String& errorMessage) OVERRIDE FINAL;
- bool canNavigate(Frame* targetFrame);
- Frame* findUnsafeParentScrollPropagationBoundary();
+ bool canNavigate(const Frame& targetFrame);
+ LocalFrame* findUnsafeParentScrollPropagationBoundary();
- CSSStyleSheet* elementSheet();
+ CSSStyleSheet& elementSheet();
- virtual PassRefPtr<DocumentParser> createParser();
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser();
DocumentParser* parser() const { return m_parser.get(); }
ScriptableDocumentParser* scriptableDocumentParser() const;
@@ -566,7 +591,6 @@ public:
enum CompatibilityMode { QuirksMode, LimitedQuirksMode, NoQuirksMode };
void setCompatibilityMode(CompatibilityMode m);
- void lockCompatibilityMode() { m_compatibilityModeLocked = true; }
CompatibilityMode compatibilityMode() const { return m_compatibilityMode; }
String compatMode() const;
@@ -584,11 +608,9 @@ public:
bool isLoadCompleted();
void setParsing(bool);
- bool parsing() const { return m_bParsing; }
- int minimumLayoutDelay();
+ bool parsing() const { return m_isParsing; }
- bool shouldScheduleLayout();
- bool shouldParserYieldAgressivelyBeforeScriptExecution();
+ bool shouldScheduleLayout() const;
int elapsedTime() const;
TextLinkColors& textLinkColors() { return m_textLinkColors; }
@@ -604,18 +626,16 @@ public:
String selectedStylesheetSet() const;
void setSelectedStylesheetSet(const String&);
- bool setFocusedElement(PassRefPtr<Element>, FocusDirection = FocusDirectionNone);
+ bool setFocusedElement(PassRefPtrWillBeRawPtr<Element>, FocusType = FocusTypeNone);
Element* focusedElement() const { return m_focusedElement.get(); }
UserActionElementSet& userActionElements() { return m_userActionElements; }
const UserActionElementSet& userActionElements() const { return m_userActionElements; }
void setNeedsFocusedElementCheck();
- void didRunCheckFocusedElementTask() { m_didPostCheckFocusedElementTask = false; }
+ void setAutofocusElement(Element*);
+ Element* autofocusElement() const { return m_autofocusElement.get(); }
- void setHoverNode(PassRefPtr<Node>);
- Node* hoverNode() const { return m_hoverNode.get(); }
-
- void setActiveElement(PassRefPtr<Element>);
- Element* activeElement() const { return m_activeElement.get(); }
+ void setActiveHoverElement(PassRefPtrWillBeRawPtr<Element>);
+ Element* activeHoverElement() const { return m_activeHoverElement.get(); }
void removeFocusedElementOfSubtree(Node*, bool amongChildrenOnly = false);
void hoveredNodeDetached(Node*);
@@ -627,44 +647,45 @@ public:
void setCSSTarget(Element*);
Element* cssTarget() const { return m_cssTarget; }
- void scheduleStyleRecalc();
- void unscheduleStyleRecalc();
- bool hasPendingStyleRecalc() const;
+ void scheduleRenderTreeUpdateIfNeeded();
bool hasPendingForcedStyleRecalc() const;
- void styleRecalcTimerFired(Timer<Document>*);
- void registerNodeList(LiveNodeListBase*);
- void unregisterNodeList(LiveNodeListBase*);
+ void registerNodeList(const LiveNodeListBase*);
+ void unregisterNodeList(const LiveNodeListBase*);
+ void registerNodeListWithIdNameCache(const LiveNodeListBase*);
+ void unregisterNodeListWithIdNameCache(const LiveNodeListBase*);
bool shouldInvalidateNodeListCaches(const QualifiedName* attrName = 0) const;
void invalidateNodeListCaches(const QualifiedName* attrName);
void attachNodeIterator(NodeIterator*);
void detachNodeIterator(NodeIterator*);
- void moveNodeIteratorsToNewDocument(Node*, Document*);
+ void moveNodeIteratorsToNewDocument(Node&, Document&);
void attachRange(Range*);
void detachRange(Range*);
void updateRangesAfterChildrenChanged(ContainerNode*);
+ void updateRangesAfterNodeMovedToAnotherDocument(const Node&);
// nodeChildrenWillBeRemoved is used when removing all node children at once.
- void nodeChildrenWillBeRemoved(ContainerNode*);
+ void nodeChildrenWillBeRemoved(ContainerNode&);
// nodeWillBeRemoved is only safe when removing one node at a time.
void nodeWillBeRemoved(Node&);
bool canReplaceChild(const Node& newChild, const Node& oldChild) const;
void didInsertText(Node*, unsigned offset, unsigned length);
void didRemoveText(Node*, unsigned offset, unsigned length);
- void didMergeTextNodes(Text* oldNode, unsigned offset);
- void didSplitTextNode(Text* oldNode);
+ void didMergeTextNodes(Text& oldNode, unsigned offset);
+ void didSplitTextNode(Text& oldNode);
- void clearDOMWindow() { m_domWindow = 0; }
- DOMWindow* domWindow() const { return m_domWindow; }
+ void clearDOMWindow() { m_domWindow = nullptr; }
+ LocalDOMWindow* domWindow() const { return m_domWindow; }
- // Helper functions for forwarding DOMWindow event related tasks to the DOMWindow if it exists.
- void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, DOMWrapperWorld* isolatedWorld = 0);
- EventListener* getWindowAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
+ // Helper functions for forwarding LocalDOMWindow event related tasks to the LocalDOMWindow if it exists.
+ void setWindowAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
+ EventListener* getWindowAttributeEventListener(const AtomicString& eventType);
- PassRefPtr<Event> createEvent(const String& eventType, ExceptionState&);
+ static void registerEventFactory(PassOwnPtr<EventFactoryBase>);
+ static PassRefPtrWillBeRawPtr<Event> createEvent(const String& eventType, ExceptionState&);
// keep track of what types of event listeners are registered, so we don't
// dispatch events unnecessarily
@@ -680,9 +701,8 @@ public:
ANIMATIONSTART_LISTENER = 1 << 8,
ANIMATIONITERATION_LISTENER = 1 << 9,
TRANSITIONEND_LISTENER = 1 << 10,
- BEFORELOAD_LISTENER = 1 << 11,
SCROLL_LISTENER = 1 << 12
- // 3 bits remaining
+ // 4 bits remaining
};
bool hasListenerType(ListenerType listenerType) const { return (m_listenerTypes & listenerType); }
@@ -705,9 +725,9 @@ public:
*
* @param equiv The http header name (value of the meta tag's "equiv" attribute)
* @param content The header value (value of the meta tag's "content" attribute)
+ * @param inDocumentHeadElement Is the element in the document's <head> element?
*/
- void processHttpEquiv(const AtomicString& equiv, const AtomicString& content);
- void processViewport(const String& features, ViewportDescription::Type origin);
+ void processHttpEquiv(const AtomicString& equiv, const AtomicString& content, bool inDocumentHeadElement);
void updateViewportDescription();
void processReferrerPolicy(const String& policy);
@@ -715,9 +735,6 @@ public:
// Returns 0 if this is the top level document.
HTMLFrameOwnerElement* ownerElement() const;
- HTMLIFrameElement* seamlessParentIFrame() const;
- bool shouldDisplaySeamlesslyWithParent() const;
-
String title() const { return m_title; }
void setTitle(const String&);
@@ -725,6 +742,9 @@ public:
void setTitleElement(const String& title, Element* titleElement);
void removeTitle(Element* titleElement);
+ const AtomicString& dir();
+ void setDir(const AtomicString&);
+
String cookie(ExceptionState&) const;
void setCookie(const String&, ExceptionState&);
@@ -765,11 +785,17 @@ public:
static bool hasValidNamespaceForAttributes(const QualifiedName&);
HTMLElement* body() const;
- void setBody(PassRefPtr<HTMLElement>, ExceptionState&);
+ void setBody(PassRefPtrWillBeRawPtr<HTMLElement>, ExceptionState&);
+
+ HTMLHeadElement* head() const;
- HTMLHeadElement* head();
+ // Decide which element is to define the viewport's overflow policy. If |rootStyle| is set, use
+ // that as the style for the root element, rather than obtaining it on our own. The reason for
+ // this is that style may not have been associated with the elements yet - in which case it may
+ // have been calculated on the fly (without associating it with the actual element) somewhere.
+ Element* viewportDefiningElement(RenderStyle* rootStyle = 0) const;
- DocumentMarkerController* markers() const { return m_markers.get(); }
+ DocumentMarkerController& markers() const { return *m_markers; }
bool directionSetOnDocumentElement() const { return m_directionSetOnDocumentElement; }
bool writingModeSetOnDocumentElement() const { return m_writingModeSetOnDocumentElement; }
@@ -790,36 +816,45 @@ public:
void setDesignMode(InheritedBool value);
InheritedBool getDesignMode() const;
bool inDesignMode() const;
+ String designMode() const;
+ void setDesignMode(const String&);
Document* parentDocument() const;
- Document* topDocument() const;
- WeakPtr<Document> contextDocument();
+ Document& topDocument() const;
+ WeakPtrWillBeRawPtr<Document> contextDocument();
ScriptRunner* scriptRunner() { return m_scriptRunner.get(); }
HTMLScriptElement* currentScript() const { return !m_currentScriptStack.isEmpty() ? m_currentScriptStack.last().get() : 0; }
- void pushCurrentScript(PassRefPtr<HTMLScriptElement>);
+ void pushCurrentScript(PassRefPtrWillBeRawPtr<HTMLScriptElement>);
void popCurrentScript();
void applyXSLTransform(ProcessingInstruction* pi);
- PassRefPtr<Document> transformSourceDocument() { return m_transformSourceDocument; }
+ PassRefPtrWillBeRawPtr<Document> transformSourceDocument() { return m_transformSourceDocument; }
void setTransformSourceDocument(Document* doc) { m_transformSourceDocument = doc; }
void setTransformSource(PassOwnPtr<TransformSource>);
TransformSource* transformSource() const { return m_transformSource.get(); }
- void incDOMTreeVersion() { m_domTreeVersion = ++s_globalTreeVersion; }
+ void incDOMTreeVersion() { ASSERT(m_lifecycle.stateAllowsTreeMutations()); m_domTreeVersion = ++s_globalTreeVersion; }
uint64_t domTreeVersion() const { return m_domTreeVersion; }
enum PendingSheetLayout { NoLayoutWithPendingSheets, DidLayoutWithPendingSheets, IgnoreLayoutWithPendingSheets };
bool didLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == DidLayoutWithPendingSheets; }
+ bool ignoreLayoutWithPendingStylesheets() const { return m_pendingSheetLayout == IgnoreLayoutWithPendingSheets; }
bool hasNodesWithPlaceholderStyle() const { return m_hasNodesWithPlaceholderStyle; }
void setHasNodesWithPlaceholderStyle() { m_hasNodesWithPlaceholderStyle = true; }
Vector<IconURL> iconURLs(int iconTypesMask);
+ Color themeColor() const;
+
+ // Returns the HTMLLinkElement currently in use for the Web Manifest.
+ // Returns null if there is no such element.
+ HTMLLinkElement* linkManifest() const;
+
void setUseSecureKeyboardEntryWhenActive(bool);
bool useSecureKeyboardEntryWhenActive() const;
@@ -827,28 +862,28 @@ public:
void cancelFocusAppearanceUpdate();
// Extension for manipulating canvas drawing contexts for use in CSS
- CanvasRenderingContext* getCSSCanvasContext(const String& type, const String& name, int width, int height);
- HTMLCanvasElement* getCSSCanvasElement(const String& name);
+ void getCSSCanvasContext(const String& type, const String& name, int width, int height, bool&, RefPtrWillBeRawPtr<CanvasRenderingContext2D>&, bool&, RefPtrWillBeRawPtr<WebGLRenderingContext>&);
+ HTMLCanvasElement& getCSSCanvasElement(const String& name);
bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
void parseDNSPrefetchControlHeader(const String&);
- // FIXME(crbug.com/305497): This should be removed once DOMWindow is an ExecutionContext.
+ // FIXME(crbug.com/305497): This should be removed once LocalDOMWindow is an ExecutionContext.
virtual void postTask(PassOwnPtr<ExecutionContextTask>) OVERRIDE; // Executes the task on context's thread asynchronously.
- virtual void tasksWereSuspended() OVERRIDE;
- virtual void tasksWereResumed() OVERRIDE;
- virtual void suspendScheduledTasks() OVERRIDE;
- virtual void resumeScheduledTasks() OVERRIDE;
- virtual bool tasksNeedSuspension() OVERRIDE;
+ virtual void tasksWereSuspended() OVERRIDE FINAL;
+ virtual void tasksWereResumed() OVERRIDE FINAL;
+ virtual void suspendScheduledTasks() OVERRIDE FINAL;
+ virtual void resumeScheduledTasks() OVERRIDE FINAL;
+ virtual bool tasksNeedSuspension() OVERRIDE FINAL;
void finishedParsing();
void setEncodingData(const DocumentEncodingData& newData);
- const WTF::TextEncoding& encoding() const { return m_encodingData.encoding; }
+ const WTF::TextEncoding& encoding() const { return m_encodingData.encoding(); }
- bool encodingWasDetectedHeuristically() const { return m_encodingData.wasDetectedHeuristically; }
- bool sawDecodingError() const { return m_encodingData.sawDecodingError; }
+ bool encodingWasDetectedHeuristically() const { return m_encodingData.wasDetectedHeuristically(); }
+ bool sawDecodingError() const { return m_encodingData.sawDecodingError(); }
void setAnnotatedRegionsDirty(bool f) { m_annotatedRegionsDirty = f; }
bool annotatedRegionsDirty() const { return m_annotatedRegionsDirty; }
@@ -857,10 +892,10 @@ public:
const Vector<AnnotatedRegionValue>& annotatedRegions() const;
void setAnnotatedRegions(const Vector<AnnotatedRegionValue>&);
- virtual void removeAllEventListeners();
+ virtual void removeAllEventListeners() OVERRIDE FINAL;
const SVGDocumentExtensions* svgExtensions();
- SVGDocumentExtensions* accessSVGExtensions();
+ SVGDocumentExtensions& accessSVGExtensions();
void initSecurityContext();
void initSecurityContext(const DocumentInit&);
@@ -885,56 +920,60 @@ public:
bool loadEventStillNeeded() const { return m_loadEventProgress == LoadEventNotRun; }
bool processingLoadEvent() const { return m_loadEventProgress == LoadEventInProgress; }
bool loadEventFinished() const { return m_loadEventProgress >= LoadEventCompleted; }
+ bool unloadStarted() const { return m_loadEventProgress >= PageHideInProgress; }
void setContainsPlugins() { m_containsPlugins = true; }
bool containsPlugins() const { return m_containsPlugins; }
- virtual bool isContextThread() const;
- virtual bool isJSExecutionForbidden() const { return false; }
+ virtual bool isContextThread() const OVERRIDE FINAL;
+ virtual bool isJSExecutionForbidden() const OVERRIDE FINAL { return false; }
bool containsValidityStyleRules() const { return m_containsValidityStyleRules; }
void setContainsValidityStyleRules() { m_containsValidityStyleRules = true; }
void enqueueResizeEvent();
void enqueueScrollEventForNode(Node*);
- void enqueueAnimationFrameEvent(PassRefPtr<Event>);
-
- const QualifiedName& idAttributeName() const { return m_idAttributeName; }
+ void enqueueAnimationFrameEvent(PassRefPtrWillBeRawPtr<Event>);
bool hasFullscreenElementStack() const { return m_hasFullscreenElementStack; }
void setHasFullscreenElementStack() { m_hasFullscreenElementStack = true; }
- void webkitExitPointerLock();
- Element* webkitPointerLockElement() const;
+ void exitPointerLock();
+ Element* pointerLockElement() const;
// Used to allow element that loads data without going through a FrameLoader to delay the 'load' event.
void incrementLoadEventDelayCount() { ++m_loadEventDelayCount; }
void decrementLoadEventDelayCount();
- bool isDelayingLoadEvent() const { return m_loadEventDelayCount; }
+ void checkLoadEventSoon();
+ bool isDelayingLoadEvent();
+ void loadPluginsSoon();
- PassRefPtr<Touch> createTouch(DOMWindow*, EventTarget*, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const;
- PassRefPtr<TouchList> createTouchList(Vector<RefPtr<Touch> >&) const;
+ PassRefPtrWillBeRawPtr<Touch> createTouch(LocalDOMWindow*, EventTarget*, int identifier, double pageX, double pageY, double screenX, double screenY, double radiusX, double radiusY, float rotationAngle, float force) const;
+ PassRefPtrWillBeRawPtr<TouchList> createTouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >&) const;
- const DocumentTiming* timing() const { return &m_documentTiming; }
+ const DocumentTiming& timing() const { return m_documentTiming; }
int requestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback>);
void cancelAnimationFrame(int id);
void serviceScriptedAnimations(double monotonicAnimationStartTime);
- virtual EventTarget* errorEventTarget();
- virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>);
+ virtual EventTarget* errorEventTarget() OVERRIDE FINAL;
+ virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>) OVERRIDE FINAL;
void initDNSPrefetch();
- double lastHandledUserGestureTimestamp() const { return m_lastHandledUserGestureTimestamp; }
- void resetLastHandledUserGestureTimestamp();
-
bool hasTouchEventHandlers() const { return (m_touchEventTargets.get()) ? m_touchEventTargets->size() : false; }
+ // Called when a single touch event handler has been added or removed for a node.
+ // The Node should always be in this Document, except for child Documents which report
+ // themselves to their parent exactly once if they have any touch handlers.
+ // Handlers added/removed from the LocalDOMWindow are reported as the Document.
void didAddTouchEventHandler(Node*);
- void didRemoveTouchEventHandler(Node*);
+ void didRemoveTouchEventHandler(Node* handler) { didRemoveTouchEventHandler(handler, false); }
- void didRemoveEventTargetNode(Node*);
+ // Called whenever all touch event handlers have been removed for a node (such as when the
+ // node itself is being removed from the document).
+ void didClearTouchEventHandlers(Node* handler) { didRemoveTouchEventHandler(handler, true); }
const TouchEventTargetSet* touchEventTargets() const { return m_touchEventTargets.get(); }
@@ -947,14 +986,16 @@ public:
TextAutosizer* textAutosizer();
FastTextAutosizer* fastTextAutosizer();
- PassRefPtr<Element> createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState&);
- PassRefPtr<Element> createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Element> createElement(const AtomicString& localName, const AtomicString& typeExtension, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Element> createElementNS(const AtomicString& namespaceURI, const AtomicString& qualifiedName, const AtomicString& typeExtension, ExceptionState&);
ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, ExceptionState&);
ScriptValue registerElement(WebCore::ScriptState*, const AtomicString& name, const Dictionary& options, ExceptionState&, CustomElement::NameSet validNames = CustomElement::StandardNames);
CustomElementRegistrationContext* registrationContext() { return m_registrationContext.get(); }
- void setImport(HTMLImport*);
- HTMLImport* import() const { return m_import; }
+ void setImportsController(HTMLImportsController*);
+ HTMLImportsController* importsController() const { return m_importsController; }
+ HTMLImportLoader* importLoader() const;
+
bool haveImportsLoaded() const;
void didLoadAllImports();
@@ -966,46 +1007,46 @@ public:
void incrementActiveParserCount() { ++m_activeParserCount; }
void decrementActiveParserCount();
- void setContextFeatures(PassRefPtr<ContextFeatures>);
- ContextFeatures* contextFeatures() const { return m_contextFeatures.get(); }
+ void setContextFeatures(ContextFeatures&);
+ ContextFeatures& contextFeatures() const { return *m_contextFeatures; }
- DocumentSharedObjectPool* sharedObjectPool() { return m_sharedObjectPool.get(); }
+ ElementDataCache* elementDataCache() { return m_elementDataCache.get(); }
+ void didLoadAllScriptBlockingResources();
void didRemoveAllPendingStylesheet();
- void setNeedsNotifyRemoveAllPendingStylesheet() { m_needsNotifyRemoveAllPendingStylesheet = true; }
void clearStyleResolver();
- void notifySeamlessChildDocumentsOfStylesheetUpdate() const;
- bool inStyleRecalc() { return m_inStyleRecalc; }
+ bool inStyleRecalc() const { return m_lifecycle.state() == DocumentLifecycle::InStyleRecalc; }
// Return a Locale for the default locale if the argument is null or empty.
Locale& getCachedLocale(const AtomicString& locale = nullAtom);
- AnimationClock& animationClock() { return *m_animationClock; }
- DocumentTimeline* timeline() const { return m_timeline.get(); }
- DocumentTimeline* transitionTimeline() const { return m_transitionTimeline.get(); }
- CSSPendingAnimations& cssPendingAnimations() { return m_cssPendingAnimations; }
+ AnimationClock& animationClock() { return m_animationClock; }
+ AnimationTimeline& timeline() const { return *m_timeline; }
+ CompositorPendingAnimations& compositorPendingAnimations() { return m_compositorPendingAnimations; }
void addToTopLayer(Element*, const Element* before = 0);
void removeFromTopLayer(Element*);
- const Vector<RefPtr<Element> >& topLayerElements() const { return m_topLayerElements; }
+ const WillBeHeapVector<RefPtrWillBeMember<Element> >& topLayerElements() const { return m_topLayerElements; }
HTMLDialogElement* activeModalDialog() const;
- const Document* templateDocument() const;
+ // A non-null m_templateDocumentHost implies that |this| was created by ensureTemplateDocument().
+ bool isTemplateDocument() const { return !!m_templateDocumentHost; }
Document& ensureTemplateDocument();
- void setTemplateDocumentHost(Document* templateDocumentHost) { m_templateDocumentHost = templateDocumentHost; }
Document* templateDocumentHost() { return m_templateDocumentHost; }
void didAssociateFormControl(Element*);
void addConsoleMessageWithRequestIdentifier(MessageSource, MessageLevel, const String& message, unsigned long requestIdentifier);
- virtual DOMWindow* executingWindow() OVERRIDE { return domWindow(); }
- virtual void userEventWasHandled() OVERRIDE { resetLastHandledUserGestureTimestamp(); }
+ virtual LocalDOMWindow* executingWindow() OVERRIDE FINAL;
+ LocalFrame* executingFrame();
DocumentLifecycleNotifier& lifecycleNotifier();
- bool isActive() const { return m_lifecyle.state() == DocumentLifecycle::Active; }
- bool isStopped() const { return m_lifecyle.state() == DocumentLifecycle::Stopped; }
+ DocumentLifecycle& lifecycle() { return m_lifecycle; }
+ bool isActive() const { return m_lifecycle.isActive(); }
+ bool isStopped() const { return m_lifecycle.state() == DocumentLifecycle::Stopped; }
+ bool isDisposed() const { return m_lifecycle.state() == DocumentLifecycle::Disposed; }
enum HttpRefreshType {
HttpRefreshFromHeader,
@@ -1016,71 +1057,106 @@ public:
void updateSecurityOrigin(PassRefPtr<SecurityOrigin>);
PassOwnPtr<LifecycleNotifier<Document> > createLifecycleNotifier();
+ void setHasViewportUnits() { m_hasViewportUnits = true; }
+ bool hasViewportUnits() const { return m_hasViewportUnits; }
+ void notifyResizeForViewportUnits();
+
+ void registerVisibilityObserver(DocumentVisibilityObserver*);
+ void unregisterVisibilityObserver(DocumentVisibilityObserver*);
+
+ void updateStyleInvalidationIfNeeded();
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ bool hasSVGFilterElementsRequiringLayerUpdate() const { return m_layerUpdateSVGFilterElements.size(); }
+ void didRecalculateStyleForElement() { ++m_styleRecalcElementCounter; }
+
protected:
Document(const DocumentInit&, DocumentClassFlags = DefaultDocumentClass);
- virtual void didUpdateSecurityOrigin() OVERRIDE;
+ virtual void didUpdateSecurityOrigin() OVERRIDE FINAL;
void clearXMLVersion() { m_xmlVersion = String(); }
+#if !ENABLE(OILPAN)
virtual void dispose() OVERRIDE;
+#endif
+
+ virtual PassRefPtrWillBeRawPtr<Document> cloneDocumentWithoutChildren();
- virtual PassRefPtr<Document> cloneDocumentWithoutChildren();
+ bool importContainerNodeChildren(ContainerNode* oldContainerNode, PassRefPtrWillBeRawPtr<ContainerNode> newContainerNode, ExceptionState&);
+ void lockCompatibilityMode() { m_compatibilityModeLocked = true; }
private:
friend class Node;
friend class IgnoreDestructiveWriteCountIncrementer;
ScriptedAnimationController& ensureScriptedAnimationController();
- virtual SecurityContext& securityContext() OVERRIDE { return *this; }
- virtual EventQueue* eventQueue() const FINAL;
+ virtual SecurityContext& securityContext() OVERRIDE FINAL { return *this; }
+ virtual EventQueue* eventQueue() const OVERRIDE FINAL;
+
+ // FIXME: Rename the StyleRecalc state to RenderTreeUpdate.
+ bool hasPendingStyleRecalc() const { return m_lifecycle.state() == DocumentLifecycle::VisualUpdatePending; }
+
+ bool shouldScheduleRenderTreeUpdate() const;
+ void scheduleRenderTreeUpdate();
+ bool needsFullRenderTreeUpdate() const;
+ bool needsRenderTreeUpdate() const;
+
+ void inheritHtmlAndBodyElementStyles(StyleRecalcChange);
+
+ bool dirtyElementsForLayerUpdate();
void updateDistributionIfNeeded();
+ void updateUseShadowTreesIfNeeded();
+ void evaluateMediaQueryListIfNeeded();
+
+ void updateRenderTree(StyleRecalcChange);
+ void updateStyle(StyleRecalcChange);
void detachParser();
- virtual bool isDocument() const OVERRIDE { return true; }
+ void clearWeakMembers(Visitor*);
+
+ virtual bool isDocument() const OVERRIDE FINAL { return true; }
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual bool childTypeAllowed(NodeType) const;
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
+ virtual String nodeName() const OVERRIDE FINAL;
+ virtual NodeType nodeType() const OVERRIDE FINAL;
+ virtual bool childTypeAllowed(NodeType) const OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE FINAL;
void cloneDataFromDocument(const Document&);
- virtual void refExecutionContext() { ref(); }
- virtual void derefExecutionContext() { deref(); }
+#if !ENABLE(OILPAN)
+ virtual void refExecutionContext() OVERRIDE FINAL { ref(); }
+ virtual void derefExecutionContext() OVERRIDE FINAL { deref(); }
+#endif
- virtual const KURL& virtualURL() const; // Same as url(), but needed for ExecutionContext to implement it without a performance loss for direct calls.
- virtual KURL virtualCompleteURL(const String&) const; // Same as completeURL() for the same reason as above.
+ virtual const KURL& virtualURL() const OVERRIDE FINAL; // Same as url(), but needed for ExecutionContext to implement it without a performance loss for direct calls.
+ virtual KURL virtualCompleteURL(const String&) const OVERRIDE FINAL; // Same as completeURL() for the same reason as above.
- virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) OVERRIDE;
- virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState*);
- void internalAddMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack>, ScriptState*);
+ virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) OVERRIDE FINAL;
+ virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState*) OVERRIDE FINAL;
+ void internalAddMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>, ScriptState*);
- virtual double timerAlignmentInterval() const;
+ virtual double timerAlignmentInterval() const OVERRIDE FINAL;
void updateTitle(const String&);
void updateFocusAppearanceTimerFired(Timer<Document>*);
void updateBaseURL();
- void executeScriptsWaitingForResourcesIfNeeded();
-
- void seamlessParentUpdatedStylesheets();
-
- void recalcStyleForLayoutIgnoringPendingStylesheets();
-
- PassRefPtr<NodeList> handleZeroPadding(const HitTestRequest&, HitTestResult&) const;
+ void executeScriptsWaitingForResourcesTimerFired(Timer<Document>*);
void loadEventDelayTimerFired(Timer<Document>*);
+ void pluginLoadingTimerFired(Timer<Document>*);
PageVisibilityState pageVisibilityState() const;
- PassRefPtr<HTMLCollection> ensureCachedCollection(CollectionType);
+ PassRefPtrWillBeRawPtr<HTMLCollection> ensureCachedCollection(CollectionType);
- // Note that dispatching a window load event may cause the DOMWindow to be detached from
- // the Frame, so callers should take a reference to the DOMWindow (which owns us) to
+ // Note that dispatching a window load event may cause the LocalDOMWindow to be detached from
+ // the LocalFrame, so callers should take a reference to the LocalDOMWindow (which owns us) to
// prevent the Document from getting blown away from underneath them.
void dispatchWindowLoadEvent();
@@ -1088,7 +1164,9 @@ private:
void addMutationEventListenerTypeIfEnabled(ListenerType);
void didAssociateFormControlsTimerFired(Timer<Document>*);
- void styleResolverThrowawayTimerFired(Timer<Document>*);
+
+ void clearFocusedElementSoon();
+ void clearFocusedElementTimerFired(Timer<Document>*);
void processHttpEquivDefaultStyle(const AtomicString& content);
void processHttpEquivRefresh(const AtomicString& content);
@@ -1096,10 +1174,19 @@ private:
void processHttpEquivXFrameOptions(const AtomicString& content);
void processHttpEquivContentSecurityPolicy(const AtomicString& equiv, const AtomicString& content);
- DocumentLifecycle m_lifecyle;
+ void didRemoveTouchEventHandler(Node*, bool clearAll);
+
+ bool haveStylesheetsLoaded() const;
+
+ void setHoverNode(PassRefPtrWillBeRawPtr<Node>);
+ Node* hoverNode() const { return m_hoverNode.get(); }
+
+ typedef HashSet<OwnPtr<EventFactoryBase> > EventFactorySet;
+ static EventFactorySet& eventFactories();
+
+ DocumentLifecycle m_lifecycle;
bool m_hasNodesWithPlaceholderStyle;
- bool m_needsNotifyRemoveAllPendingStylesheet;
bool m_evaluateMediaQueriesOnStyleRecalc;
// If we do ignore the pending stylesheet count, then we need to add a boolean
@@ -1107,14 +1194,17 @@ private:
// do eventually load.
PendingSheetLayout m_pendingSheetLayout;
- Frame* m_frame;
- DOMWindow* m_domWindow;
- HTMLImport* m_import;
+ LocalFrame* m_frame;
+ RawPtrWillBeMember<LocalDOMWindow> m_domWindow;
+ // FIXME: oilpan: when we get rid of the transition types change the
+ // HTMLImportsController to not be a DocumentSupplement since it is
+ // redundant with oilpan.
+ RawPtrWillBeMember<HTMLImportsController> m_importsController;
- RefPtr<ResourceFetcher> m_fetcher;
- RefPtr<DocumentParser> m_parser;
+ RefPtrWillBeMember<ResourceFetcher> m_fetcher;
+ RefPtrWillBeMember<DocumentParser> m_parser;
unsigned m_activeParserCount;
- RefPtr<ContextFeatures> m_contextFeatures;
+ RefPtrWillBeMember<ContextFeatures> m_contextFeatures;
bool m_wellFormed;
@@ -1125,19 +1215,15 @@ private:
KURL m_baseElementURL; // The URL set by the <base> element.
KURL m_cookieURL; // The URL to use for cookie access.
- // Document.documentURI:
- // Although URL-like, Document.documentURI can actually be set to any
- // string by content. Document.documentURI affects m_baseURL unless the
- // document contains a <base> element, in which case the <base> element
- // takes precedence.
- String m_documentURI;
+ AtomicString m_baseTarget;
- String m_baseTarget;
+ // Mime-type of the document in case it was cloned or created by XHR.
+ AtomicString m_mimeType;
- RefPtr<DocumentType> m_docType;
- OwnPtr<DOMImplementation> m_implementation;
+ RefPtrWillBeMember<DocumentType> m_docType;
+ OwnPtrWillBeMember<DOMImplementation> m_implementation;
- RefPtr<CSSStyleSheet> m_elemSheet;
+ RefPtrWillBeMember<CSSStyleSheet> m_elemSheet;
bool m_printing;
bool m_paginatedForScreen;
@@ -1145,38 +1231,39 @@ private:
CompatibilityMode m_compatibilityMode;
bool m_compatibilityModeLocked; // This is cheaper than making setCompatibilityMode virtual.
- bool m_didPostCheckFocusedElementTask;
- RefPtr<Element> m_focusedElement;
- RefPtr<Node> m_hoverNode;
- RefPtr<Element> m_activeElement;
- RefPtr<Element> m_documentElement;
+ Timer<Document> m_executeScriptsWaitingForResourcesTimer;
+
+ bool m_hasAutofocused;
+ Timer<Document> m_clearFocusedElementTimer;
+ RefPtrWillBeMember<Element> m_autofocusElement;
+ RefPtrWillBeMember<Element> m_focusedElement;
+ RefPtrWillBeMember<Node> m_hoverNode;
+ RefPtrWillBeMember<Element> m_activeHoverElement;
+ RefPtrWillBeMember<Element> m_documentElement;
UserActionElementSet m_userActionElements;
uint64_t m_domTreeVersion;
static uint64_t s_globalTreeVersion;
- HashSet<NodeIterator*> m_nodeIterators;
- HashSet<Range*> m_ranges;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<NodeIterator> > m_nodeIterators;
+ typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<Range> > AttachedRangeSet;
+ AttachedRangeSet m_ranges;
unsigned short m_listenerTypes;
MutationObserverOptions m_mutationObserverTypes;
- OwnPtr<StyleEngine> m_styleEngine;
- RefPtr<StyleSheetList> m_styleSheetList;
+ OwnPtrWillBeMember<StyleEngine> m_styleEngine;
+ RefPtrWillBeMember<StyleSheetList> m_styleSheetList;
- OwnPtr<FormController> m_formController;
+ OwnPtrWillBeMember<FormController> m_formController;
TextLinkColors m_textLinkColors;
const OwnPtr<VisitedLinkState> m_visitedLinkState;
- bool m_loadingSheet;
bool m_visuallyOrdered;
ReadyState m_readyState;
- bool m_bParsing;
-
- Timer<Document> m_styleRecalcTimer;
- bool m_inStyleRecalc;
+ bool m_isParsing;
bool m_gotoAnchorNeededAfterStylesheetsLoad;
bool m_isDNSPrefetchEnabled;
@@ -1191,26 +1278,25 @@ private:
String m_title;
String m_rawTitle;
bool m_titleSetExplicitly;
- RefPtr<Element> m_titleElement;
+ RefPtrWillBeMember<Element> m_titleElement;
OwnPtr<AXObjectCache> m_axObjectCache;
- OwnPtr<DocumentMarkerController> m_markers;
+ OwnPtrWillBeMember<DocumentMarkerController> m_markers;
Timer<Document> m_updateFocusAppearanceTimer;
- Element* m_cssTarget;
+ RawPtrWillBeMember<Element> m_cssTarget;
LoadEventProgress m_loadEventProgress;
double m_startTime;
- bool m_overMinimumLayoutThreshold;
- OwnPtr<ScriptRunner> m_scriptRunner;
+ OwnPtrWillBeMember<ScriptRunner> m_scriptRunner;
- Vector<RefPtr<HTMLScriptElement> > m_currentScriptStack;
+ WillBeHeapVector<RefPtrWillBeMember<HTMLScriptElement> > m_currentScriptStack;
OwnPtr<TransformSource> m_transformSource;
- RefPtr<Document> m_transformSourceDocument;
+ RefPtrWillBeMember<Document> m_transformSourceDocument;
String m_xmlEncoding;
String m_xmlVersion;
@@ -1223,16 +1309,24 @@ private:
InheritedBool m_designMode;
- HashSet<LiveNodeListBase*> m_listsInvalidatedAtDocument;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<const LiveNodeListBase> > m_listsInvalidatedAtDocument;
+#if ENABLE(OILPAN)
+ // Oilpan keeps track of all registered NodeLists.
+ //
+ // FIXME: Oilpan: improve - only need to know if a NodeList
+ // is currently alive or not for the different types.
+ HeapHashSet<WeakMember<const LiveNodeListBase> > m_nodeLists[numNodeListInvalidationTypes];
+#else
unsigned m_nodeListCounts[numNodeListInvalidationTypes];
+#endif
- OwnPtr<SVGDocumentExtensions> m_svgExtensions;
+ OwnPtrWillBeMember<SVGDocumentExtensions> m_svgExtensions;
Vector<AnnotatedRegionValue> m_annotatedRegions;
bool m_hasAnnotatedRegions;
bool m_annotatedRegionsDirty;
- HashMap<String, RefPtr<HTMLCanvasElement> > m_cssCanvasElements;
+ WillBeHeapHashMap<String, RefPtrWillBeMember<HTMLCanvasElement> > m_cssCanvasElements;
OwnPtr<SelectorQueryCache> m_selectorQueryCache;
@@ -1244,55 +1338,50 @@ private:
bool m_sawElementsInKnownNamespaces;
bool m_isSrcdocDocument;
bool m_isMobileDocument;
- // Set in Document::initSecurityContext() at Document creation, per:
- // http://www.whatwg.org/specs/web-apps/current-work/#attr-iframe-seamless
- bool m_mayDisplaySeamlesslyWithParent;
+ bool m_isTransitionDocument;
RenderView* m_renderView;
+#if !ENABLE(OILPAN)
WeakPtrFactory<Document> m_weakFactory;
- WeakPtr<Document> m_contextDocument;
-
- QualifiedName m_idAttributeName;
+#endif
+ WeakPtrWillBeWeakMember<Document> m_contextDocument;
bool m_hasFullscreenElementStack; // For early return in FullscreenElementStack::fromIfExists()
- Vector<RefPtr<Element> > m_topLayerElements;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > m_topLayerElements;
int m_loadEventDelayCount;
Timer<Document> m_loadEventDelayTimer;
+ Timer<Document> m_pluginLoadingTimer;
ViewportDescription m_viewportDescription;
ViewportDescription m_legacyViewportDescription;
+ Length m_viewportDefaultMinWidth;
+ bool m_didSetReferrerPolicy;
ReferrerPolicy m_referrerPolicy;
bool m_directionSetOnDocumentElement;
bool m_writingModeSetOnDocumentElement;
DocumentTiming m_documentTiming;
- RefPtr<MediaQueryMatcher> m_mediaQueryMatcher;
+ RefPtrWillBeMember<MediaQueryMatcher> m_mediaQueryMatcher;
bool m_writeRecursionIsTooDeep;
unsigned m_writeRecursionDepth;
OwnPtr<TouchEventTargetSet> m_touchEventTargets;
- double m_lastHandledUserGestureTimestamp;
-
- RefPtr<ScriptedAnimationController> m_scriptedAnimationController;
+ RefPtrWillBeMember<ScriptedAnimationController> m_scriptedAnimationController;
OwnPtr<MainThreadTaskRunner> m_taskRunner;
OwnPtr<TextAutosizer> m_textAutosizer;
OwnPtr<FastTextAutosizer> m_fastTextAutosizer;
- RefPtr<CustomElementRegistrationContext> m_registrationContext;
-
- RefPtr<NamedFlowCollection> m_namedFlows;
+ RefPtrWillBeMember<CustomElementRegistrationContext> m_registrationContext;
- RefPtr<DOMSecurityPolicy> m_domSecurityPolicy;
+ void elementDataCacheClearTimerFired(Timer<Document>*);
+ Timer<Document> m_elementDataCacheClearTimer;
- void sharedObjectPoolClearTimerFired(Timer<Document>*);
- Timer<Document> m_sharedObjectPoolClearTimer;
-
- OwnPtr<DocumentSharedObjectPool> m_sharedObjectPool;
+ OwnPtr<ElementDataCache> m_elementDataCache;
#ifndef NDEBUG
bool m_didDispatchViewportPropertiesChanged;
@@ -1301,32 +1390,29 @@ private:
typedef HashMap<AtomicString, OwnPtr<Locale> > LocaleIdentifierToLocaleMap;
LocaleIdentifierToLocaleMap m_localeCache;
- OwnPtr<AnimationClock> m_animationClock;
- RefPtr<DocumentTimeline> m_timeline;
- RefPtr<DocumentTimeline> m_transitionTimeline;
- CSSPendingAnimations m_cssPendingAnimations;
+ AnimationClock m_animationClock;
+ RefPtrWillBeMember<AnimationTimeline> m_timeline;
+ CompositorPendingAnimations m_compositorPendingAnimations;
- RefPtr<Document> m_templateDocument;
- Document* m_templateDocumentHost; // Manually managed weakref (backpointer from m_templateDocument).
+ RefPtrWillBeMember<Document> m_templateDocument;
+ // With Oilpan the templateDocument and the templateDocumentHost
+ // live and die together. Without Oilpan, the templateDocumentHost
+ // is a manually managed backpointer from m_templateDocument.
+ RawPtrWillBeMember<Document> m_templateDocumentHost;
Timer<Document> m_didAssociateFormControlsTimer;
- HashSet<RefPtr<Element> > m_associatedFormControls;
-};
+ WillBeHeapHashSet<RefPtrWillBeMember<Element> > m_associatedFormControls;
-inline void Document::notifyRemovePendingSheetIfNeeded()
-{
- if (m_needsNotifyRemoveAllPendingStylesheet)
- didRemoveAllPendingStylesheet();
-}
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGUseElement> > m_useElementsNeedingUpdate;
+ WillBeHeapHashSet<RawPtrWillBeMember<Element> > m_layerUpdateSVGFilterElements;
-inline const Document* Document::templateDocument() const
-{
- // If DOCUMENT does not have a browsing context, Let TEMPLATE CONTENTS OWNER be DOCUMENT and abort these steps.
- if (!m_frame)
- return this;
+ bool m_hasViewportUnits;
- return m_templateDocument.get();
-}
+ typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<DocumentVisibilityObserver> > DocumentVisibilityObserverSet;
+ DocumentVisibilityObserverSet m_visibilityObservers;
+
+ int m_styleRecalcElementCounter;
+};
inline bool Document::shouldOverrideLegacyDescription(ViewportDescription::Type origin)
{
@@ -1336,18 +1422,17 @@ inline bool Document::shouldOverrideLegacyDescription(ViewportDescription::Type
return origin >= m_legacyViewportDescription.type;
}
-inline Document* toDocument(ExecutionContext* executionContext)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!executionContext || executionContext->isDocument());
- return static_cast<Document*>(executionContext);
-}
-
-inline const Document* toDocument(const ExecutionContext* executionContext)
+inline void Document::scheduleRenderTreeUpdateIfNeeded()
{
- ASSERT_WITH_SECURITY_IMPLICATION(!executionContext || executionContext->isDocument());
- return static_cast<const Document*>(executionContext);
+ // Inline early out to avoid the function calls below.
+ if (hasPendingStyleRecalc())
+ return;
+ if (shouldScheduleRenderTreeUpdate() && needsRenderTreeUpdate())
+ scheduleRenderTreeUpdate();
}
+DEFINE_TYPE_CASTS(Document, ExecutionContextClient, client, client->isDocument(), client.isDocument());
+DEFINE_TYPE_CASTS(Document, ExecutionContext, context, context->isDocument(), context.isDocument());
DEFINE_NODE_TYPE_CASTS(Document, isDocumentNode());
#define DEFINE_DOCUMENT_TYPE_CASTS(thisType) \
@@ -1365,7 +1450,7 @@ inline bool operator!=(const Document* a, const Document& b) { return !(a == b);
inline bool Node::isDocumentNode() const
{
- return this == documentInternal();
+ return this == document();
}
Node* eventTargetNodeForDocument(Document*);
diff --git a/chromium/third_party/WebKit/Source/core/dom/Document.idl b/chromium/third_party/WebKit/Source/core/dom/Document.idl
index 366966261f7..c0b3801f4d3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Document.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Document.idl
@@ -20,8 +20,10 @@
callback CustomElementConstructor = Element ();
+typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext;
+
[
- SpecialWrapFor=HTMLDocument|SVGDocument
+ SpecialWrapFor=HTMLDocument|XMLDocument
] interface Document : Node {
// DOM Level 1 Core
@@ -29,22 +31,22 @@ callback CustomElementConstructor = Element ();
readonly attribute DOMImplementation implementation;
readonly attribute Element documentElement;
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Element createElement(DOMString tagName);
+ [CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Element createElement(DOMString tagName);
DocumentFragment createDocumentFragment();
- [PerWorldBindings] Text createTextNode(DOMString data);
+ Text createTextNode(DOMString data);
Comment createComment(DOMString data);
[RaisesException, MeasureAs=DocumentCreateCDATASection] CDATASection createCDATASection([Default=Undefined] optional DOMString data); // Removed from DOM4.
[RaisesException] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
[RaisesException, MeasureAs=DocumentCreateAttribute] Attr createAttribute([Default=Undefined] optional DOMString name); // Removed from DOM4.
- [PerWorldBindings] NodeList getElementsByTagName(DOMString localName);
+ HTMLCollection getElementsByTagName(DOMString localName);
// Introduced in DOM Level 2:
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node importNode(Node node, optional boolean deep);
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName);
- [RaisesException, MeasureAs=DocumentCreateAttributeNS] Attr createAttributeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
+ [CustomElementCallbacks, LogActivity, RaisesException] Node importNode(Node node, optional boolean deep);
+ [CustomElementCallbacks, LogActivity, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName);
+ [RaisesException, DeprecateAs=DocumentCreateAttributeNS] Attr createAttributeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
[TreatNullAs=NullString,Default=Undefined] optional DOMString qualifiedName); // Removed from DOM4.
- NodeList getElementsByTagNameNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
+ HTMLCollection getElementsByTagNameNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
[PerWorldBindings] Element getElementById(DOMString elementId);
// DOM Level 3 Core
@@ -57,7 +59,7 @@ callback CustomElementConstructor = Element ();
[RaisesException, CustomElementCallbacks] Node adoptNode(Node node);
- [TreatReturnedNullStringAs=Null] readonly attribute DOMString documentURI;
+ [TreatReturnedNullStringAs=Null, ImplementedAs=url] readonly attribute DOMString documentURI;
// DOM Level 2 Events (DocumentEvents interface)
@@ -78,7 +80,7 @@ callback CustomElementConstructor = Element ();
// DOM Level 2 Abstract Views (DocumentView interface)
- [ImplementedAs=domWindow] readonly attribute Window defaultView;
+ [ImplementedAs=executingWindow] readonly attribute Window defaultView;
// DOM Level 2 Style (DocumentStyle interface)
@@ -89,6 +91,9 @@ callback CustomElementConstructor = Element ();
CSSStyleDeclaration getOverrideStyle([Default=Undefined] optional Element element,
[Default=Undefined] optional DOMString pseudoElement);
+ // DOM 4
+ readonly attribute DOMString contentType;
+
// Common extensions
[CustomElementCallbacks]
boolean execCommand([Default=Undefined] optional DOMString command,
@@ -102,7 +107,8 @@ callback CustomElementConstructor = Element ();
DOMString queryCommandValue([Default=Undefined] optional DOMString command);
// Moved down from HTMLDocument
-
+ [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString dir;
+ [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString designMode;
[TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString title;
readonly attribute DOMString referrer;
[TreatNullAs=NullString, RaisesException=Setter] attribute DOMString domain;
@@ -110,27 +116,31 @@ callback CustomElementConstructor = Element ();
[TreatNullAs=NullString, RaisesException] attribute DOMString cookie;
- [RaisesException=Setter, CustomElementCallbacks] attribute HTMLElement body;
+ [RaisesException=Setter, CustomElementCallbacks, PerWorldBindings] attribute HTMLElement body;
readonly attribute HTMLHeadElement head;
readonly attribute HTMLCollection images;
readonly attribute HTMLCollection applets;
+ readonly attribute HTMLCollection embeds;
+ [ImplementedAs=embeds] readonly attribute HTMLCollection plugins;
readonly attribute HTMLCollection links;
readonly attribute HTMLCollection forms;
+ readonly attribute HTMLCollection scripts;
readonly attribute HTMLCollection anchors;
readonly attribute DOMString lastModified;
[PerWorldBindings] NodeList getElementsByName([Default=Undefined] optional DOMString elementName);
- [PerWorldBindings, ActivityLogging=ForIsolatedWorlds, PutForwards=href] readonly attribute Location location;
+ [LogActivity, PutForwards=href] readonly attribute Location location;
// IE extensions
[MeasureAs=DocumentCharset, TreatReturnedNullStringAs=Undefined, TreatNullAs=NullString] attribute DOMString charset;
- [MeasureAs=DocumentCharset, TreatReturnedNullStringAs=Undefined] readonly attribute DOMString defaultCharset;
+ [MeasureAs=DocumentDefaultCharset, TreatReturnedNullStringAs=Undefined] readonly attribute DOMString defaultCharset;
[TreatReturnedNullStringAs=Undefined] readonly attribute DOMString readyState;
Element elementFromPoint([Default=Undefined] optional long x,
[Default=Undefined] optional long y);
+ [MeasureAs=DocumentCaretRangeFromPoint]
Range caretRangeFromPoint([Default=Undefined] optional long x,
[Default=Undefined] optional long y);
@@ -141,23 +151,21 @@ callback CustomElementConstructor = Element ();
// WebKit extensions
[TreatReturnedNullStringAs=Null] readonly attribute DOMString preferredStylesheetSet;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectedStylesheetSet;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectedStylesheetSet;
- CanvasRenderingContext getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
+ [MeasureAs=DocumentGetCSSCanvasContext] RenderingContext getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
// HTML 5
- NodeList getElementsByClassName(DOMString classNames);
+ HTMLCollection getElementsByClassName(DOMString classNames);
+ readonly attribute Element activeElement;
+ boolean hasFocus();
readonly attribute DOMString compatMode;
- // NodeSelector - Selector API
- [RaisesException] Element querySelector(DOMString selectors);
- [RaisesException] NodeList querySelectorAll(DOMString selectors);
-
- void webkitExitPointerLock();
- readonly attribute Element webkitPointerLockElement;
-
- [RuntimeEnabled=CSSRegions] WebKitNamedFlowCollection webkitGetNamedFlows();
+ [MeasureAs=DocumentExitPointerLock] void exitPointerLock();
+ [MeasureAs=DocumentPointerLockElement] readonly attribute Element pointerLockElement;
+ [MeasureAs=PrefixedDocumentExitPointerLock, ImplementedAs=exitPointerLock] void webkitExitPointerLock();
+ [MeasureAs=PrefixedDocumentPointerLockElement, ImplementedAs=pointerLockElement] readonly attribute Element webkitPointerLockElement;
// Event handler attributes
attribute EventHandler onbeforecopy;
@@ -166,6 +174,8 @@ callback CustomElementConstructor = Element ();
attribute EventHandler oncopy;
attribute EventHandler oncut;
attribute EventHandler onpaste;
+ attribute EventHandler onpointerlockchange;
+ attribute EventHandler onpointerlockerror;
attribute EventHandler onreadystatechange;
attribute EventHandler onsearch;
[RuntimeEnabled=ExperimentalContentSecurityPolicyFeatures] attribute EventHandler onsecuritypolicyviolation;
@@ -179,24 +189,24 @@ callback CustomElementConstructor = Element ();
attribute EventHandler onwebkitfullscreenerror;
attribute EventHandler onwebkitpointerlockchange;
attribute EventHandler onwebkitpointerlockerror;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onwheel;
+ [LogActivity=SetterOnly] attribute EventHandler onwheel;
[RuntimeEnabled=Touch] Touch createTouch([Default=Undefined] optional Window window,
[Default=Undefined] optional EventTarget target,
[Default=Undefined] optional long identifier,
- [Default=Undefined] optional long pageX,
- [Default=Undefined] optional long pageY,
- [Default=Undefined] optional long screenX,
- [Default=Undefined] optional long screenY,
- [Default=Undefined] optional long webkitRadiusX,
- [Default=Undefined] optional long webkitRadiusY,
+ [Default=Undefined] optional double pageX,
+ [Default=Undefined] optional double pageY,
+ [Default=Undefined] optional double screenX,
+ [Default=Undefined] optional double screenY,
+ [Default=Undefined] optional double webkitRadiusX,
+ [Default=Undefined] optional double webkitRadiusY,
[Default=Undefined] optional float webkitRotationAngle,
[Default=Undefined] optional float webkitForce);
[RuntimeEnabled=Touch] TouchList createTouchList(Touch... touches);
- [RuntimeEnabled=CustomElements, CallWith=ScriptState, CustomElementCallbacks, RaisesException] CustomElementConstructor registerElement(DOMString name, optional Dictionary options);
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Element createElement(DOMString localName, [TreatNullAs=NullString] DOMString typeExtension);
- [CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName,
+ [CallWith=ScriptState, CustomElementCallbacks, RaisesException, MeasureAs=DocumentRegisterElement] CustomElementConstructor registerElement(DOMString name, optional Dictionary options);
+ [CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Element createElement(DOMString localName, [TreatNullAs=NullString] DOMString typeExtension);
+ [CustomElementCallbacks, LogActivity, RaisesException] Element createElementNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName,
[TreatNullAs=NullString] DOMString typeExtension);
// Page visibility API.
@@ -209,9 +219,6 @@ callback CustomElementConstructor = Element ();
[MeasureAs=PrefixedPageVisibility, ImplementedAs=visibilityState] readonly attribute DOMString webkitVisibilityState;
[MeasureAs=PrefixedPageVisibility, ImplementedAs=hidden] readonly attribute boolean webkitHidden;
- // Security Policy API: http://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#script-interfaces
- [RuntimeEnabled=ExperimentalContentSecurityPolicyFeatures] readonly attribute SecurityPolicy securityPolicy;
-
readonly attribute HTMLScriptElement currentScript;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.cpp
new file mode 100644
index 00000000000..23d69f5ceb4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/DocumentEncodingData.h"
+
+#include "core/html/parser/TextResourceDecoder.h"
+
+namespace WebCore {
+
+DocumentEncodingData::DocumentEncodingData()
+ : m_wasDetectedHeuristically(false)
+ , m_sawDecodingError(false)
+{
+}
+
+DocumentEncodingData::DocumentEncodingData(const TextResourceDecoder& decoder)
+{
+ m_encoding = decoder.encoding();
+ m_wasDetectedHeuristically = decoder.encodingWasDetectedHeuristically();
+ m_sawDecodingError = decoder.sawError();
+}
+
+void DocumentEncodingData::setEncoding(const WTF::TextEncoding& encoding)
+{
+ m_encoding = encoding;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h b/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h
index 5a696afdd17..2016aa531ae 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentEncodingData.h
@@ -34,19 +34,31 @@
#include "wtf/text/TextEncoding.h"
namespace WebCore {
+class TextResourceDecoder;
-struct DocumentEncodingData {
- DocumentEncodingData()
- : wasDetectedHeuristically(false)
- , sawDecodingError(false)
- {
- }
+class DocumentEncodingData {
+public:
+ DocumentEncodingData();
+ explicit DocumentEncodingData(const TextResourceDecoder&);
- WTF::TextEncoding encoding;
- bool wasDetectedHeuristically;
- bool sawDecodingError;
+ const WTF::TextEncoding& encoding() const { return m_encoding; }
+ void setEncoding(const WTF::TextEncoding&);
+ bool wasDetectedHeuristically() const { return m_wasDetectedHeuristically; }
+ bool sawDecodingError() const { return m_sawDecodingError; }
+
+private:
+ WTF::TextEncoding m_encoding;
+ bool m_wasDetectedHeuristically;
+ bool m_sawDecodingError;
};
+inline bool operator!=(const DocumentEncodingData& a, const DocumentEncodingData& b)
+{
+ return a.encoding() != b.encoding()
+ || a.wasDetectedHeuristically() != b.wasDetectedHeuristically()
+ || a.sawDecodingError() != b.sawDecodingError();
+}
+
} // namespace WebCore
#endif // DocumentEncodingData_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
index 141d571fe3f..a88cbf8a5de 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
@@ -35,9 +35,9 @@ DocumentFragment::DocumentFragment(Document* document, ConstructionType construc
ScriptWrappable::init(this);
}
-PassRefPtr<DocumentFragment> DocumentFragment::create(Document& document)
+PassRefPtrWillBeRawPtr<DocumentFragment> DocumentFragment::create(Document& document)
{
- return adoptRef(new DocumentFragment(&document, Node::CreateDocumentFragment));
+ return adoptRefWillBeNoop(new DocumentFragment(&document, Node::CreateDocumentFragment));
}
String DocumentFragment::nodeName() const
@@ -64,9 +64,9 @@ bool DocumentFragment::childTypeAllowed(NodeType type) const
}
}
-PassRefPtr<Node> DocumentFragment::cloneNode(bool deep)
+PassRefPtrWillBeRawPtr<Node> DocumentFragment::cloneNode(bool deep)
{
- RefPtr<DocumentFragment> clone = create(document());
+ RefPtrWillBeRawPtr<DocumentFragment> clone = create(document());
if (deep)
cloneChildNodes(clone.get());
return clone.release();
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h
index 4730abcd065..a4292d41c1a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.h
@@ -33,25 +33,25 @@ class ExecutionContext;
class DocumentFragment : public ContainerNode {
public:
- static PassRefPtr<DocumentFragment> create(Document&);
+ static PassRefPtrWillBeRawPtr<DocumentFragment> create(Document&);
void parseHTML(const String&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
bool parseXML(const String&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
- virtual bool canContainRangeEndPoint() const { return true; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return true; }
virtual bool isTemplateContent() const { return false; }
protected:
DocumentFragment(Document*, ConstructionType = CreateContainer);
- virtual String nodeName() const;
+ virtual String nodeName() const OVERRIDE FINAL;
private:
- virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
- virtual bool childTypeAllowed(NodeType) const;
+ virtual NodeType nodeType() const OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
+ virtual bool childTypeAllowed(NodeType) const OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(DocumentFragment, nodeType() == Node::DOCUMENT_FRAGMENT_NODE);
+DEFINE_NODE_TYPE_CASTS(DocumentFragment, isDocumentFragment());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl
index 4f1ecf98231..005032a254e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFragment.idl
@@ -21,9 +21,8 @@
Constructor,
ConstructorCallWith=Document,
] interface DocumentFragment : Node {
- // NodeSelector - Selector API
- [RaisesException] Element querySelector(DOMString selectors);
- [RaisesException] NodeList querySelectorAll(DOMString selectors);
+ // NonElementParentNode API.
+ Element getElementById(DOMString elementId);
};
DocumentFragment implements ParentNode;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp
index 407e55d3082..b1f88cdb3ce 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.cpp
@@ -30,47 +30,47 @@
namespace WebCore {
-bool DocumentFullscreen::webkitIsFullScreen(Document* document)
+bool DocumentFullscreen::webkitIsFullScreen(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->webkitIsFullScreen();
return false;
}
-bool DocumentFullscreen::webkitFullScreenKeyboardInputAllowed(Document* document)
+bool DocumentFullscreen::webkitFullScreenKeyboardInputAllowed(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->webkitFullScreenKeyboardInputAllowed();
return false;
}
-Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document* document)
+Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->webkitCurrentFullScreenElement();
return 0;
}
-void DocumentFullscreen::webkitCancelFullScreen(Document* document)
+void DocumentFullscreen::webkitCancelFullScreen(Document& document)
{
- FullscreenElementStack::from(document)->webkitCancelFullScreen();
+ FullscreenElementStack::from(document).webkitCancelFullScreen();
}
-bool DocumentFullscreen::webkitFullscreenEnabled(Document* document)
+bool DocumentFullscreen::webkitFullscreenEnabled(Document& document)
{
return FullscreenElementStack::webkitFullscreenEnabled(document);
}
-Element* DocumentFullscreen::webkitFullscreenElement(Document* document)
+Element* DocumentFullscreen::webkitFullscreenElement(Document& document)
{
if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
return fullscreen->webkitFullscreenElement();
return 0;
}
-void DocumentFullscreen::webkitExitFullscreen(Document* document)
+void DocumentFullscreen::webkitExitFullscreen(Document& document)
{
- FullscreenElementStack::from(document)->webkitExitFullscreen();
+ FullscreenElementStack::from(document).webkitExitFullscreen();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h
index ff5338da300..01a5ac96cf6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.h
@@ -33,14 +33,14 @@ class Element;
class DocumentFullscreen {
public:
- static bool webkitIsFullScreen(Document*);
- static bool webkitFullScreenKeyboardInputAllowed(Document*);
- static Element* webkitCurrentFullScreenElement(Document*);
- static void webkitCancelFullScreen(Document*);
+ static bool webkitIsFullScreen(Document&);
+ static bool webkitFullScreenKeyboardInputAllowed(Document&);
+ static Element* webkitCurrentFullScreenElement(Document&);
+ static void webkitCancelFullScreen(Document&);
- static bool webkitFullscreenEnabled(Document*);
- static Element* webkitFullscreenElement(Document*);
- static void webkitExitFullscreen(Document*);
+ static bool webkitFullscreenEnabled(Document&);
+ static Element* webkitFullscreenElement(Document&);
+ static void webkitExitFullscreen(Document&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl
index 561ad8018b4..65c6f80058a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentFullscreen.idl
@@ -18,15 +18,16 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
partial interface Document {
// Mozilla version
- [RuntimeEnabled=Fullscreen] readonly attribute boolean webkitIsFullScreen;
- [RuntimeEnabled=Fullscreen] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
- [RuntimeEnabled=Fullscreen] readonly attribute Element webkitCurrentFullScreenElement;
- [RuntimeEnabled=Fullscreen] void webkitCancelFullScreen();
+ [MeasureAs=PrefixedDocumentIsFullscreen] readonly attribute boolean webkitIsFullScreen;
+ [MeasureAs=PrefixedDocumentFullScreenKeyboardInputAllowed] readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
+ [MeasureAs=PrefixedDocumentCurrentFullScreenElement] readonly attribute Element webkitCurrentFullScreenElement;
+ [MeasureAs=PrefixedDocumentCancelFullScreen] void webkitCancelFullScreen();
// W3C version
- [RuntimeEnabled=Fullscreen] readonly attribute boolean webkitFullscreenEnabled;
- [RuntimeEnabled=Fullscreen] readonly attribute Element webkitFullscreenElement;
- [RuntimeEnabled=Fullscreen] void webkitExitFullscreen();
+ [MeasureAs=PrefixedDocumentFullscreenEnabled] readonly attribute boolean webkitFullscreenEnabled;
+ [MeasureAs=PrefixedDocumentFullscreenElement] readonly attribute Element webkitFullscreenElement;
+ [MeasureAs=PrefixedDocumentExitFullscreen] void webkitExitFullscreen();
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp
index 90b4dd996f1..a71dc74a634 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentInit.cpp
@@ -28,27 +28,28 @@
#include "config.h"
#include "core/dom/DocumentInit.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/dom/Document.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/html/HTMLImportsController.h"
-#include "core/frame/Frame.h"
+#include "core/html/imports/HTMLImportsController.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-static Document* parentDocument(Frame* frame)
+// FIXME: Broken with OOPI.
+static Document* parentDocument(LocalFrame* frame)
{
if (!frame)
return 0;
- Element* ownerElement = frame->ownerElement();
+ Element* ownerElement = frame->deprecatedLocalOwner();
if (!ownerElement)
return 0;
return &ownerElement->document();
}
-static Document* ownerDocument(Frame* frame)
+static Document* ownerDocument(LocalFrame* frame)
{
if (!frame)
return 0;
@@ -56,18 +57,19 @@ static Document* ownerDocument(Frame* frame)
Frame* ownerFrame = frame->tree().parent();
if (!ownerFrame)
ownerFrame = frame->loader().opener();
- if (!ownerFrame)
+ if (!ownerFrame || !ownerFrame->isLocalFrame())
return 0;
- return ownerFrame->document();
+ return toLocalFrame(ownerFrame)->document();
}
-DocumentInit::DocumentInit(const KURL& url, Frame* frame, WeakPtr<Document> contextDocument, HTMLImport* import)
+DocumentInit::DocumentInit(const KURL& url, LocalFrame* frame, WeakPtrWillBeRawPtr<Document> contextDocument, HTMLImportsController* importsController)
: m_url(url)
, m_frame(frame)
, m_parent(parentDocument(frame))
, m_owner(ownerDocument(frame))
, m_contextDocument(contextDocument)
- , m_import(import)
+ , m_importsController(importsController)
+ , m_createNewRegistrationContext(false)
{
}
@@ -77,8 +79,9 @@ DocumentInit::DocumentInit(const DocumentInit& other)
, m_parent(other.m_parent)
, m_owner(other.m_owner)
, m_contextDocument(other.m_contextDocument)
- , m_import(other.m_import)
+ , m_importsController(other.m_importsController)
, m_registrationContext(other.m_registrationContext)
+ , m_createNewRegistrationContext(other.m_createNewRegistrationContext)
{
}
@@ -88,8 +91,8 @@ DocumentInit::~DocumentInit()
bool DocumentInit::shouldSetURL() const
{
- Frame* frame = frameForSecurityContext();
- return (frame && frame->ownerElement()) || !m_url.isEmpty();
+ LocalFrame* frame = frameForSecurityContext();
+ return (frame && frame->owner()) || !m_url.isEmpty();
}
bool DocumentInit::shouldTreatURLAsSrcdocDocument() const
@@ -97,25 +100,12 @@ bool DocumentInit::shouldTreatURLAsSrcdocDocument() const
return m_parent && m_frame->loader().shouldTreatURLAsSrcdocDocument(m_url);
}
-bool DocumentInit::isSeamlessAllowedFor(Document* child) const
-{
- if (!m_parent)
- return false;
- if (m_parent->isSandboxed(SandboxSeamlessIframes))
- return false;
- if (child->isSrcdocDocument())
- return true;
- if (m_parent->securityOrigin()->canAccess(child->securityOrigin()))
- return true;
- return m_parent->securityOrigin()->canRequest(child->url());
-}
-
-Frame* DocumentInit::frameForSecurityContext() const
+LocalFrame* DocumentInit::frameForSecurityContext() const
{
if (m_frame)
return m_frame;
- if (m_import)
- return m_import->frame();
+ if (m_importsController)
+ return m_importsController->master()->frame();
return 0;
}
@@ -138,31 +128,35 @@ KURL DocumentInit::parentBaseURL() const
DocumentInit& DocumentInit::withRegistrationContext(CustomElementRegistrationContext* registrationContext)
{
- ASSERT(!m_registrationContext);
+ ASSERT(!m_createNewRegistrationContext && !m_registrationContext);
m_registrationContext = registrationContext;
return *this;
}
-PassRefPtr<CustomElementRegistrationContext> DocumentInit::registrationContext(Document* document) const
+DocumentInit& DocumentInit::withNewRegistrationContext()
{
- if (!RuntimeEnabledFeatures::customElementsEnabled() && !RuntimeEnabledFeatures::embedderCustomElementsEnabled())
- return 0;
+ ASSERT(!m_createNewRegistrationContext && !m_registrationContext);
+ m_createNewRegistrationContext = true;
+ return *this;
+}
+PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> DocumentInit::registrationContext(Document* document) const
+{
if (!document->isHTMLDocument() && !document->isXHTMLDocument())
- return 0;
+ return nullptr;
- if (m_registrationContext)
- return m_registrationContext.get();
+ if (m_createNewRegistrationContext)
+ return CustomElementRegistrationContext::create();
- return CustomElementRegistrationContext::create();
+ return m_registrationContext.get();
}
-WeakPtr<Document> DocumentInit::contextDocument() const
+WeakPtrWillBeRawPtr<Document> DocumentInit::contextDocument() const
{
return m_contextDocument;
}
-DocumentInit DocumentInit::fromContext(WeakPtr<Document> contextDocument, const KURL& url)
+DocumentInit DocumentInit::fromContext(WeakPtrWillBeRawPtr<Document> contextDocument, const KURL& url)
{
return DocumentInit(url, 0, contextDocument, 0);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentInit.h b/chromium/third_party/WebKit/Source/core/dom/DocumentInit.h
index 911d14f4620..3458f02678e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentInit.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentInit.h
@@ -30,6 +30,7 @@
#include "core/dom/SandboxFlags.h"
#include "core/dom/SecurityContext.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -39,19 +40,20 @@ namespace WebCore {
class CustomElementRegistrationContext;
class Document;
-class Frame;
-class HTMLImport;
+class LocalFrame;
+class HTMLImportsController;
class Settings;
-class DocumentInit {
+class DocumentInit FINAL {
+ STACK_ALLOCATED();
public:
- explicit DocumentInit(const KURL& = KURL(), Frame* = 0, WeakPtr<Document> = WeakPtr<Document>(), HTMLImport* = 0);
+ explicit DocumentInit(const KURL& = KURL(), LocalFrame* = 0, WeakPtrWillBeRawPtr<Document> = nullptr, HTMLImportsController* = 0);
DocumentInit(const DocumentInit&);
~DocumentInit();
const KURL& url() const { return m_url; }
- Frame* frame() const { return m_frame; }
- HTMLImport* import() const { return m_import; }
+ LocalFrame* frame() const { return m_frame; }
+ HTMLImportsController* importsController() const { return m_importsController; }
bool hasSecurityContext() const { return frameForSecurityContext(); }
bool shouldTreatURLAsSrcdocDocument() const;
@@ -62,26 +64,27 @@ public:
Document* parent() const { return m_parent.get(); }
Document* owner() const { return m_owner.get(); }
KURL parentBaseURL() const;
- Frame* ownerFrame() const;
+ LocalFrame* ownerFrame() const;
Settings* settings() const;
DocumentInit& withRegistrationContext(CustomElementRegistrationContext*);
+ DocumentInit& withNewRegistrationContext();
+ PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> registrationContext(Document*) const;
+ WeakPtrWillBeRawPtr<Document> contextDocument() const;
- PassRefPtr<CustomElementRegistrationContext> registrationContext(Document*) const;
- WeakPtr<Document> contextDocument() const;
-
- static DocumentInit fromContext(WeakPtr<Document> contextDocument, const KURL& = KURL());
+ static DocumentInit fromContext(WeakPtrWillBeRawPtr<Document> contextDocument, const KURL& = KURL());
private:
- Frame* frameForSecurityContext() const;
+ LocalFrame* frameForSecurityContext() const;
KURL m_url;
- Frame* m_frame;
- RefPtr<Document> m_parent;
- RefPtr<Document> m_owner;
- WeakPtr<Document> m_contextDocument;
- HTMLImport* m_import;
- RefPtr<CustomElementRegistrationContext> m_registrationContext;
+ LocalFrame* m_frame;
+ RefPtrWillBeMember<Document> m_parent;
+ RefPtrWillBeMember<Document> m_owner;
+ WeakPtrWillBeMember<Document> m_contextDocument;
+ RawPtrWillBeMember<HTMLImportsController> m_importsController;
+ RefPtrWillBeMember<CustomElementRegistrationContext> m_registrationContext;
+ bool m_createNewRegistrationContext;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp
index 157548f32b0..c7e2615062a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.cpp
@@ -35,8 +35,35 @@
namespace WebCore {
+static DocumentLifecycle::DeprecatedTransition* s_deprecatedTransitionStack = 0;
+
+DocumentLifecycle::Scope::Scope(DocumentLifecycle& lifecycle, State finalState)
+ : m_lifecycle(lifecycle)
+ , m_finalState(finalState)
+{
+}
+
+DocumentLifecycle::Scope::~Scope()
+{
+ m_lifecycle.advanceTo(m_finalState);
+}
+
+DocumentLifecycle::DeprecatedTransition::DeprecatedTransition(State from, State to)
+ : m_previous(s_deprecatedTransitionStack)
+ , m_from(from)
+ , m_to(to)
+{
+ s_deprecatedTransitionStack = this;
+}
+
+DocumentLifecycle::DeprecatedTransition::~DeprecatedTransition()
+{
+ s_deprecatedTransitionStack = m_previous;
+}
+
DocumentLifecycle::DocumentLifecycle()
: m_state(Uninitialized)
+ , m_detachCount(0)
{
}
@@ -44,11 +71,96 @@ DocumentLifecycle::~DocumentLifecycle()
{
}
+#if ASSERT_ENABLED
+
+bool DocumentLifecycle::canAdvanceTo(State state) const
+{
+ if (state > m_state)
+ return true;
+ if (m_state == Disposed) {
+ // FIXME: We can dispose a document multiple times. This seems wrong.
+ // See https://code.google.com/p/chromium/issues/detail?id=301668.
+ return state == Disposed;
+ }
+ if (m_state == StyleClean) {
+ // We can synchronously recalc style.
+ if (state == InStyleRecalc)
+ return true;
+ // We can synchronously perform layout.
+ if (state == InPreLayout)
+ return true;
+ if (state == InPerformLayout)
+ return true;
+ // We can redundant arrive in the style clean state.
+ if (state == StyleClean)
+ return true;
+ return false;
+ }
+ if (m_state == InPreLayout) {
+ if (state == InStyleRecalc)
+ return true;
+ if (state == StyleClean)
+ return true;
+ if (state == InPreLayout)
+ return true;
+ return false;
+ }
+ if (m_state == AfterPerformLayout) {
+ // We can synchronously recompute layout in AfterPerformLayout.
+ // FIXME: Ideally, we would unnest this recursion into a loop.
+ return state == InPreLayout;
+ }
+ if (m_state == LayoutClean) {
+ // We can synchronously recalc style.
+ if (state == InStyleRecalc)
+ return true;
+ // We can synchronously perform layout.
+ if (state == InPreLayout)
+ return true;
+ if (state == InPerformLayout)
+ return true;
+ // We can redundant arrive in the layout clean state. This situation
+ // can happen when we call layout recursively and we unwind the stack.
+ if (state == LayoutClean)
+ return true;
+ if (state == StyleClean)
+ return true;
+ return false;
+ }
+ if (m_state == CompositingClean) {
+ if (state == InStyleRecalc)
+ return true;
+ if (state == InPreLayout)
+ return true;
+ if (state == InCompositingUpdate)
+ return true;
+ return false;
+ }
+ return false;
+}
+
+bool DocumentLifecycle::canRewindTo(State state) const
+{
+ // This transition is bogus, but we've whitelisted it anyway.
+ if (s_deprecatedTransitionStack && m_state == s_deprecatedTransitionStack->from() && state == s_deprecatedTransitionStack->to())
+ return true;
+ return m_state == StyleClean || m_state == AfterPerformLayout || m_state == LayoutClean || m_state == CompositingClean;
+}
+
+#endif
+
void DocumentLifecycle::advanceTo(State state)
{
- // FIXME: We can dispose a document multiple times. This seems wrong.
- // See https://code.google.com/p/chromium/issues/detail?id=301668.
- ASSERT(state > m_state || (state == Disposed && m_state == Disposed));
+ ASSERT(canAdvanceTo(state));
+ m_state = state;
+}
+
+void DocumentLifecycle::ensureStateAtMost(State state)
+{
+ ASSERT(state == VisualUpdatePending || state == StyleClean || state == LayoutClean);
+ if (m_state <= state)
+ return;
+ ASSERT(canRewindTo(state));
m_state = state;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h
index c3f919635e8..449ed15b533 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycle.h
@@ -31,6 +31,7 @@
#ifndef DocumentLifecycle_h
#define DocumentLifecycle_h
+#include "wtf/Assertions.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
@@ -41,23 +42,130 @@ public:
enum State {
Uninitialized,
Inactive,
- Active,
+
+ // When the document is active, it traverses these states.
+
+ VisualUpdatePending,
+
+ InStyleRecalc,
+ StyleClean,
+
+ InPreLayout,
+ InPerformLayout,
+ AfterPerformLayout,
+ LayoutClean,
+
+ InCompositingUpdate,
+ CompositingClean,
+
+ // Once the document starts shuting down, we cannot return
+ // to the style/layout/rendering states.
Stopping,
Stopped,
Disposed,
};
+ class Scope {
+ WTF_MAKE_NONCOPYABLE(Scope);
+ public:
+ Scope(DocumentLifecycle&, State finalState);
+ ~Scope();
+
+ void setFinalState(State finalState) { m_finalState = finalState; }
+
+ private:
+ DocumentLifecycle& m_lifecycle;
+ State m_finalState;
+ };
+
+ class DeprecatedTransition {
+ WTF_MAKE_NONCOPYABLE(DeprecatedTransition);
+ public:
+ DeprecatedTransition(State from, State to);
+ ~DeprecatedTransition();
+
+ State from() const { return m_from; }
+ State to() const { return m_to; }
+
+ private:
+ DeprecatedTransition* m_previous;
+ State m_from;
+ State m_to;
+ };
+
+ class DetachScope {
+ WTF_MAKE_NONCOPYABLE(DetachScope);
+ public:
+ explicit DetachScope(DocumentLifecycle& documentLifecycle)
+ : m_documentLifecycle(documentLifecycle)
+ {
+ m_documentLifecycle.incrementDetachCount();
+ }
+
+ ~DetachScope()
+ {
+ m_documentLifecycle.decrementDetachCount();
+ }
+
+ private:
+ DocumentLifecycle& m_documentLifecycle;
+ };
+
DocumentLifecycle();
~DocumentLifecycle();
+ bool isActive() const { return m_state > Inactive && m_state < Stopping; }
State state() const { return m_state; }
+ bool stateAllowsTreeMutations() const;
+ bool stateAllowsRenderTreeMutations() const;
+ bool stateAllowsDetach() const;
+
void advanceTo(State);
+ void ensureStateAtMost(State);
+
+ void incrementDetachCount() { m_detachCount++; }
+ void decrementDetachCount()
+ {
+ ASSERT(m_detachCount > 0);
+ m_detachCount--;
+ }
private:
+#if ASSERT_ENABLED
+ bool canAdvanceTo(State) const;
+ bool canRewindTo(State) const;
+#endif
+
State m_state;
+ int m_detachCount;
};
+inline bool DocumentLifecycle::stateAllowsTreeMutations() const
+{
+ // FIXME: We should not allow mutations in InPreLayout or AfterPerformLayout either,
+ // but we need to fix MediaList listeners and plugins first.
+ return m_state != InStyleRecalc
+ && m_state != InPerformLayout
+ && m_state != InCompositingUpdate;
+}
+
+inline bool DocumentLifecycle::stateAllowsRenderTreeMutations() const
+{
+ return m_detachCount || m_state == InStyleRecalc;
+}
+
+inline bool DocumentLifecycle::stateAllowsDetach() const
+{
+ return m_state == VisualUpdatePending
+ || m_state == InStyleRecalc
+ || m_state == StyleClean
+ || m_state == InPreLayout
+ || m_state == LayoutClean
+ || m_state == CompositingClean
+ || m_state == Stopping;
+}
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h
index 07888bd1b74..7e7b062f768 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleNotifier.h
@@ -39,10 +39,12 @@ public:
static PassOwnPtr<DocumentLifecycleNotifier> create(Document*);
void notifyDocumentWasDetached();
+#if !ENABLE(OILPAN)
void notifyDocumentWasDisposed();
+#endif
- virtual void addObserver(Observer*) OVERRIDE;
- virtual void removeObserver(Observer*) OVERRIDE;
+ virtual void addObserver(Observer*) OVERRIDE FINAL;
+ virtual void removeObserver(Observer*) OVERRIDE FINAL;
private:
explicit DocumentLifecycleNotifier(Document*);
@@ -63,12 +65,14 @@ inline void DocumentLifecycleNotifier::notifyDocumentWasDetached()
(*i)->documentWasDetached();
}
+#if !ENABLE(OILPAN)
inline void DocumentLifecycleNotifier::notifyDocumentWasDisposed()
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverDocumentObservers);
for (DocumentObserverSet::iterator i = m_documentObservers.begin(); i != m_documentObservers.end(); ++i)
(*i)->documentWasDisposed();
}
+#endif
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h
index 47233c51a72..02d18a1d26e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentLifecycleObserver.h
@@ -40,7 +40,9 @@ public:
explicit DocumentLifecycleObserver(Document*);
virtual ~DocumentLifecycleObserver();
virtual void documentWasDetached() { }
+#if !ENABLE(OILPAN)
virtual void documentWasDisposed() { }
+#endif
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp
index 12b903937f6..a37e522286a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.cpp
@@ -37,12 +37,12 @@ DocumentMarkerDetails::~DocumentMarkerDetails()
{
}
-class DocumentMarkerDescription : public DocumentMarkerDetails {
+class DocumentMarkerDescription FINAL : public DocumentMarkerDetails {
public:
static PassRefPtr<DocumentMarkerDescription> create(const String&);
const String& description() const { return m_description; }
- virtual bool isDescription() const { return true; }
+ virtual bool isDescription() const OVERRIDE { return true; }
private:
DocumentMarkerDescription(const String& description)
@@ -66,12 +66,12 @@ inline DocumentMarkerDescription* toDocumentMarkerDescription(DocumentMarkerDeta
}
-class DocumentMarkerTextMatch : public DocumentMarkerDetails {
+class DocumentMarkerTextMatch FINAL : public DocumentMarkerDetails {
public:
static PassRefPtr<DocumentMarkerTextMatch> instanceFor(bool);
bool activeMatch() const { return m_match; }
- virtual bool isTextMatch() const { return true; }
+ virtual bool isTextMatch() const OVERRIDE { return true; }
private:
explicit DocumentMarkerTextMatch(bool match)
@@ -117,7 +117,7 @@ DocumentMarker::DocumentMarker(MarkerType type, unsigned startOffset, unsigned e
: m_type(type)
, m_startOffset(startOffset)
, m_endOffset(endOffset)
- , m_details(description.isEmpty() ? 0 : DocumentMarkerDescription::create(description))
+ , m_details(description.isEmpty() ? nullptr : DocumentMarkerDescription::create(description))
, m_hash(0)
{
}
@@ -126,7 +126,7 @@ DocumentMarker::DocumentMarker(MarkerType type, unsigned startOffset, unsigned e
: m_type(type)
, m_startOffset(startOffset)
, m_endOffset(endOffset)
- , m_details(description.isEmpty() ? 0 : DocumentMarkerDescription::create(description))
+ , m_details(description.isEmpty() ? nullptr : DocumentMarkerDescription::create(description))
, m_hash(hash)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h b/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h
index ded6b9d1c79..bed144af853 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarker.h
@@ -23,9 +23,7 @@
#ifndef DocumentMarker_h
#define DocumentMarker_h
-#include "wtf/Forward.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
+#include "wtf/VectorTraits.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -152,4 +150,11 @@ public:
} // namespace WebCore
+namespace WTF {
+
+template<>
+struct VectorTraits<WebCore::DocumentMarker> : SimpleClassVectorTraits<WebCore::DocumentMarker> { };
+
+} // namespace WTF
+
#endif // DocumentMarker_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp
index ef4fa8220e6..c115627d87f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.cpp
@@ -71,9 +71,7 @@ DocumentMarkerController::DocumentMarkerController()
{
}
-DocumentMarkerController::~DocumentMarkerController()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentMarkerController);
void DocumentMarkerController::clear()
{
@@ -85,7 +83,7 @@ void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerTyp
{
// Use a TextIterator to visit the potentially multiple nodes the range covers.
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset(), description, hash));
}
}
@@ -94,7 +92,7 @@ void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerTyp
{
// Use a TextIterator to visit the potentially multiple nodes the range covers.
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset(), description));
}
}
@@ -103,28 +101,17 @@ void DocumentMarkerController::addMarker(Range* range, DocumentMarker::MarkerTyp
{
// Use a TextIterator to visit the potentially multiple nodes the range covers.
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
addMarker(textPiece->startContainer(), DocumentMarker(type, textPiece->startOffset(), textPiece->endOffset()));
}
}
-void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, unsigned length, DocumentMarker::MarkerType type)
-{
- addMarker(node, DocumentMarker(type, startOffset, startOffset + length));
-}
-
-void DocumentMarkerController::addMarkerToNode(Node* node, unsigned startOffset, unsigned length, DocumentMarker::MarkerType type, PassRefPtr<DocumentMarkerDetails> details)
-{
- addMarker(node, DocumentMarker(type, startOffset, startOffset + length, details));
-}
-
-
void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activeMatch)
{
// Use a TextIterator to visit the potentially multiple nodes the range covers.
for (TextIterator markedText(range); !markedText.atEnd(); markedText.advance()) {
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
unsigned startOffset = textPiece->startOffset();
unsigned endOffset = textPiece->endOffset();
addMarker(textPiece->startContainer(), DocumentMarker(startOffset, endOffset, activeMatch));
@@ -134,7 +121,7 @@ void DocumentMarkerController::addTextMatchMarker(const Range* range, bool activ
// the whole purpose of tickmarks on the scrollbar is to show where
// matches off-screen are (that haven't been painted yet).
Node* node = textPiece->startContainer();
- Vector<DocumentMarker*> markers = markersFor(node);
+ WillBeHeapVector<DocumentMarker*> markers = markersFor(node);
toRenderedDocumentMarker(markers[markers.size() - 1])->setRenderedRect(range->boundingBox());
}
}
@@ -152,7 +139,7 @@ void DocumentMarkerController::removeMarkers(Range* range, DocumentMarker::Marke
return;
ASSERT(!m_markers.isEmpty());
- RefPtr<Range> textPiece = markedText.range();
+ RefPtrWillBeRawPtr<Range> textPiece = markedText.range();
int startOffset = textPiece->startOffset();
int endOffset = textPiece->endOffset();
removeMarkers(textPiece->startContainer(), startOffset, endOffset - startOffset, markerTypes, shouldRemovePartiallyOverlappingMarker);
@@ -200,18 +187,18 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa
m_possiblyExistingMarkerTypes.add(newMarker.type());
- OwnPtr<MarkerLists>& markers = m_markers.add(node, nullptr).iterator->value;
+ OwnPtrWillBeMember<MarkerLists>& markers = m_markers.add(node, nullptr).storedValue->value;
if (!markers) {
- markers = adoptPtr(new MarkerLists);
+ markers = adoptPtrWillBeNoop(new MarkerLists);
markers->grow(DocumentMarker::MarkerTypeIndexesCount);
}
DocumentMarker::MarkerTypeIndex markerListIndex = MarkerTypeToMarkerIndex(newMarker.type());
if (!markers->at(markerListIndex)) {
- markers->insert(markerListIndex, adoptPtr(new MarkerList));
+ markers->insert(markerListIndex, adoptPtrWillBeNoop(new MarkerList));
}
- OwnPtr<MarkerList>& list = markers->at(markerListIndex);
+ OwnPtrWillBeMember<MarkerList>& list = markers->at(markerListIndex);
if (list->isEmpty() || list->last().endOffset() < newMarker.startOffset()) {
list->append(RenderedDocumentMarker(newMarker));
} else {
@@ -226,7 +213,7 @@ void DocumentMarkerController::addMarker(Node* node, const DocumentMarker& newMa
// repaint the affected node
if (node->renderer())
- node->renderer()->repaint();
+ node->renderer()->paintInvalidationForWholeRenderer();
}
void DocumentMarkerController::mergeOverlapping(MarkerList* list, DocumentMarker& toInsert)
@@ -260,7 +247,7 @@ void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset,
bool docDirty = false;
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list)
continue;
@@ -287,7 +274,7 @@ void DocumentMarkerController::copyMarkers(Node* srcNode, unsigned startOffset,
// repaint the affected node
if (docDirty && dstNode->renderer())
- dstNode->renderer()->repaint();
+ dstNode->renderer()->paintInvalidationForWholeRenderer();
}
void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, int length, DocumentMarker::MarkerTypes markerTypes, RemovePartiallyOverlappingMarkerOrNot shouldRemovePartiallyOverlappingMarker)
@@ -306,7 +293,7 @@ void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, i
bool docDirty = false;
size_t emptyListsCount = 0;
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty()) {
if (list.get() && list->isEmpty())
list.clear();
@@ -368,7 +355,7 @@ void DocumentMarkerController::removeMarkers(Node* node, unsigned startOffset, i
// repaint the affected node
if (docDirty && node->renderer())
- node->renderer()->repaint();
+ node->renderer()->paintInvalidationForWholeRenderer();
}
DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoint& point, DocumentMarker::MarkerType markerType)
@@ -382,7 +369,7 @@ DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoin
for (MarkerMap::iterator nodeIterator = m_markers.begin(); nodeIterator != end; ++nodeIterator) {
// inner loop; process each marker in this node
MarkerLists* markers = nodeIterator->value.get();
- OwnPtr<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(markerType)];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(markerType)];
unsigned markerCount = list.get() ? list->size() : 0;
for (unsigned markerIndex = 0; markerIndex < markerCount; ++markerIndex) {
RenderedDocumentMarker& marker = list->at(markerIndex);
@@ -395,16 +382,16 @@ DocumentMarker* DocumentMarkerController::markerContainingPoint(const LayoutPoin
return 0;
}
-Vector<DocumentMarker*> DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes)
+WillBeHeapVector<DocumentMarker*> DocumentMarkerController::markersFor(Node* node, DocumentMarker::MarkerTypes markerTypes)
{
- Vector<DocumentMarker*> result;
+ WillBeHeapVector<DocumentMarker*> result;
MarkerLists* markers = m_markers.get(node);
if (!markers)
return result;
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty() || !markerTypes.contains(list->begin()->type()))
continue;
@@ -416,13 +403,13 @@ Vector<DocumentMarker*> DocumentMarkerController::markersFor(Node* node, Documen
return result;
}
-Vector<DocumentMarker*> DocumentMarkerController::markers()
+WillBeHeapVector<DocumentMarker*> DocumentMarkerController::markers()
{
- Vector<DocumentMarker*> result;
+ WillBeHeapVector<DocumentMarker*> result;
for (MarkerMap::iterator i = m_markers.begin(); i != m_markers.end(); ++i) {
MarkerLists* markers = i->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
for (size_t j = 0; list.get() && j < list->size(); ++j)
result.append(&(list->at(j)));
}
@@ -431,12 +418,12 @@ Vector<DocumentMarker*> DocumentMarkerController::markers()
return result;
}
-Vector<DocumentMarker*> DocumentMarkerController::markersInRange(Range* range, DocumentMarker::MarkerTypes markerTypes)
+WillBeHeapVector<DocumentMarker*> DocumentMarkerController::markersInRange(Range* range, DocumentMarker::MarkerTypes markerTypes)
{
if (!possiblyHasMarkers(markerTypes))
- return Vector<DocumentMarker*>();
+ return WillBeHeapVector<DocumentMarker*>();
- Vector<DocumentMarker*> foundMarkers;
+ WillBeHeapVector<DocumentMarker*> foundMarkers;
Node* startContainer = range->startContainer();
ASSERT(startContainer);
@@ -445,9 +432,9 @@ Vector<DocumentMarker*> DocumentMarkerController::markersInRange(Range* range, D
Node* pastLastNode = range->pastLastNode();
for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
- Vector<DocumentMarker*> markers = markersFor(node);
- Vector<DocumentMarker*>::const_iterator end = markers.end();
- for (Vector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) {
+ WillBeHeapVector<DocumentMarker*> markers = markersFor(node);
+ WillBeHeapVector<DocumentMarker*>::const_iterator end = markers.end();
+ for (WillBeHeapVector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) {
DocumentMarker* marker = *it;
if (!markerTypes.contains(marker->type()))
continue;
@@ -475,7 +462,7 @@ Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker
// inner loop; process each marker in this node
MarkerLists* markers = nodeIterator->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty() || list->begin()->type() != markerType)
continue;
for (unsigned markerIndex = 0; markerIndex < list->size(); ++markerIndex) {
@@ -492,6 +479,11 @@ Vector<IntRect> DocumentMarkerController::renderedRectsForMarkers(DocumentMarker
return result;
}
+void DocumentMarkerController::trace(Visitor* visitor)
+{
+ visitor->trace(m_markers);
+}
+
void DocumentMarkerController::removeMarkers(Node* node, DocumentMarker::MarkerTypes markerTypes)
{
if (!possiblyHasMarkers(markerTypes))
@@ -534,7 +526,7 @@ void DocumentMarkerController::removeMarkersFromList(MarkerMap::iterator iterato
MarkerLists* markers = iterator->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty()) {
if (list.get() && list->isEmpty())
list.clear();
@@ -554,7 +546,7 @@ void DocumentMarkerController::removeMarkersFromList(MarkerMap::iterator iterato
if (needsRepainting) {
if (RenderObject* renderer = iterator->key->renderer())
- renderer->repaint();
+ renderer->paintInvalidationForWholeRenderer();
}
if (nodeCanBeRemoved) {
@@ -578,13 +570,13 @@ void DocumentMarkerController::repaintMarkers(DocumentMarker::MarkerTypes marker
// inner loop: process each marker in the current node
MarkerLists* markers = i->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list || list->isEmpty() || !markerTypes.contains(list->begin()->type()))
continue;
// cause the node to be redrawn
if (RenderObject* renderer = node->renderer()) {
- renderer->repaint();
+ renderer->paintInvalidationForWholeRenderer();
break;
}
}
@@ -600,7 +592,7 @@ void DocumentMarkerController::invalidateRenderedRectsForMarkersInRect(const Lay
// inner loop: process each rect in the current node
MarkerLists* markers = i->value.get();
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
for (size_t markerIndex = 0; list.get() && markerIndex < list->size(); ++markerIndex)
list->at(markerIndex).invalidate(r);
}
@@ -619,7 +611,7 @@ void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, in
bool docDirty = false;
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
if (!list)
continue;
MarkerList::iterator startPos = std::lower_bound(list->begin(), list->end(), startOffset, startsAfter);
@@ -635,7 +627,7 @@ void DocumentMarkerController::shiftMarkers(Node* node, unsigned startOffset, in
// repaint the affected node
if (docDirty && node->renderer())
- node->renderer()->repaint();
+ node->renderer()->paintInvalidationForWholeRenderer();
}
void DocumentMarkerController::setMarkersActive(Range* range, bool active)
@@ -663,7 +655,7 @@ void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset
return;
bool docDirty = false;
- OwnPtr<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(DocumentMarker::TextMatch)];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[MarkerTypeToMarkerIndex(DocumentMarker::TextMatch)];
if (!list)
return;
MarkerList::iterator startPos = std::upper_bound(list->begin(), list->end(), startOffset, endsBefore);
@@ -679,7 +671,7 @@ void DocumentMarkerController::setMarkersActive(Node* node, unsigned startOffset
// repaint the affected node
if (docDirty && node->renderer())
- node->renderer()->repaint();
+ node->renderer()->paintInvalidationForWholeRenderer();
}
bool DocumentMarkerController::hasMarkers(Range* range, DocumentMarker::MarkerTypes markerTypes)
@@ -695,9 +687,9 @@ bool DocumentMarkerController::hasMarkers(Range* range, DocumentMarker::MarkerTy
Node* pastLastNode = range->pastLastNode();
for (Node* node = range->firstNode(); node != pastLastNode; node = NodeTraversal::next(*node)) {
- Vector<DocumentMarker*> markers = markersFor(node);
- Vector<DocumentMarker*>::const_iterator end = markers.end();
- for (Vector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) {
+ WillBeHeapVector<DocumentMarker*> markers = markersFor(node);
+ WillBeHeapVector<DocumentMarker*>::const_iterator end = markers.end();
+ for (WillBeHeapVector<DocumentMarker*>::const_iterator it = markers.begin(); it != end; ++it) {
DocumentMarker* marker = *it;
if (!markerTypes.contains(marker->type()))
continue;
@@ -721,7 +713,7 @@ void DocumentMarkerController::showMarkers() const
fprintf(stderr, "%p", node);
MarkerLists* markers = m_markers.get(node);
for (size_t markerListIndex = 0; markerListIndex < DocumentMarker::MarkerTypeIndexesCount; ++markerListIndex) {
- OwnPtr<MarkerList>& list = (*markers)[markerListIndex];
+ OwnPtrWillBeMember<MarkerList>& list = (*markers)[markerListIndex];
for (unsigned markerIndex = 0; list.get() && markerIndex < list->size(); ++markerIndex) {
const DocumentMarker& marker = list->at(markerIndex);
fprintf(stderr, " %d:[%d:%d](%d)", marker.type(), marker.startOffset(), marker.endOffset(), marker.activeMatch());
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h
index a3b023f7d4c..01093354ce1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerController.h
@@ -29,6 +29,7 @@
#include "core/dom/DocumentMarker.h"
#include "platform/geometry/IntRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
@@ -41,19 +42,17 @@ class Node;
class Range;
class RenderedDocumentMarker;
-class DocumentMarkerController {
- WTF_MAKE_NONCOPYABLE(DocumentMarkerController); WTF_MAKE_FAST_ALLOCATED;
+class DocumentMarkerController FINAL : public NoBaseWillBeGarbageCollected<DocumentMarkerController> {
+ WTF_MAKE_NONCOPYABLE(DocumentMarkerController); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentMarkerController);
public:
DocumentMarkerController();
- ~DocumentMarkerController();
void clear();
void addMarker(Range*, DocumentMarker::MarkerType);
void addMarker(Range*, DocumentMarker::MarkerType, const String& description);
void addMarker(Range*, DocumentMarker::MarkerType, const String& description, uint32_t hash);
- void addMarkerToNode(Node*, unsigned startOffset, unsigned length, DocumentMarker::MarkerType);
- void addMarkerToNode(Node*, unsigned startOffset, unsigned length, DocumentMarker::MarkerType, PassRefPtr<DocumentMarkerDetails>);
void addTextMatchMarker(const Range*, bool activeMatch);
void copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta);
@@ -76,11 +75,13 @@ public:
void setMarkersActive(Node*, unsigned startOffset, unsigned endOffset, bool);
DocumentMarker* markerContainingPoint(const LayoutPoint&, DocumentMarker::MarkerType);
- Vector<DocumentMarker*> markersFor(Node*, DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
- Vector<DocumentMarker*> markersInRange(Range*, DocumentMarker::MarkerTypes);
- Vector<DocumentMarker*> markers();
+ WillBeHeapVector<DocumentMarker*> markersFor(Node*, DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers());
+ WillBeHeapVector<DocumentMarker*> markersInRange(Range*, DocumentMarker::MarkerTypes);
+ WillBeHeapVector<DocumentMarker*> markers();
Vector<IntRect> renderedRectsForMarkers(DocumentMarker::MarkerType);
+ void trace(Visitor*);
+
#ifndef NDEBUG
void showMarkers() const;
#endif
@@ -88,9 +89,9 @@ public:
private:
void addMarker(Node*, const DocumentMarker&);
- typedef Vector<RenderedDocumentMarker> MarkerList;
- typedef Vector<OwnPtr<MarkerList>, DocumentMarker::MarkerTypeIndexesCount> MarkerLists;
- typedef HashMap<const Node*, OwnPtr<MarkerLists> > MarkerMap;
+ typedef WillBeHeapVector<RenderedDocumentMarker> MarkerList;
+ typedef WillBeHeapVector<OwnPtrWillBeMember<MarkerList>, DocumentMarker::MarkerTypeIndexesCount> MarkerLists;
+ typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<const Node>, OwnPtrWillBeMember<MarkerLists> > MarkerMap;
void mergeOverlapping(MarkerList*, DocumentMarker&);
bool possiblyHasMarkers(DocumentMarker::MarkerTypes);
void removeMarkersFromList(MarkerMap::iterator, DocumentMarker::MarkerTypes);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp
index f7132ed5527..62a4d58cdd5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentMarkerControllerTest.cpp
@@ -51,10 +51,10 @@ protected:
virtual void SetUp() OVERRIDE;
Document& document() const { return *m_document; }
- DocumentMarkerController& markerController() const { return *m_document->markers(); }
+ DocumentMarkerController& markerController() const { return m_document->markers(); }
- PassRefPtr<Text> createTextNode(const char*);
- void markNodeContents(PassRefPtr<Node>);
+ PassRefPtrWillBeRawPtr<Text> createTextNode(const char*);
+ void markNodeContents(PassRefPtrWillBeRawPtr<Node>);
void setBodyInnerHTML(const char*);
private:
@@ -69,17 +69,17 @@ void DocumentMarkerControllerTest::SetUp()
ASSERT(m_document);
}
-PassRefPtr<Text> DocumentMarkerControllerTest::createTextNode(const char* textContents)
+PassRefPtrWillBeRawPtr<Text> DocumentMarkerControllerTest::createTextNode(const char* textContents)
{
return document().createTextNode(String::fromUTF8(textContents));
}
-void DocumentMarkerControllerTest::markNodeContents(PassRefPtr<Node> node)
+void DocumentMarkerControllerTest::markNodeContents(PassRefPtrWillBeRawPtr<Node> node)
{
// Force renderers to be created; TextIterator, which is used in
// DocumentMarkerControllerTest::addMarker(), needs them.
document().updateLayout();
- RefPtr<Range> range = rangeOfContents(node.get());
+ RefPtrWillBeRawPtr<Range> range = rangeOfContents(node.get());
markerController().addMarker(range.get(), DocumentMarker::Spelling);
}
@@ -88,28 +88,45 @@ void DocumentMarkerControllerTest::setBodyInnerHTML(const char* bodyContent)
document().body()->setInnerHTML(String::fromUTF8(bodyContent), ASSERT_NO_EXCEPTION);
}
+TEST_F(DocumentMarkerControllerTest, DidMoveToNewDocument)
+{
+ setBodyInnerHTML("<b><i>foo</i></b>");
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ markNodeContents(parent.get());
+ EXPECT_EQ(1u, markerController().markers().size());
+ RefPtrWillBePersistent<Document> anotherDocument = Document::create();
+ anotherDocument->adoptNode(parent.get(), ASSERT_NO_EXCEPTION);
+
+ // No more reference to marked node.
+ Heap::collectAllGarbage();
+ EXPECT_EQ(0u, markerController().markers().size());
+ EXPECT_EQ(0u, anotherDocument->markers().markers().size());
+}
+
TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByNormalize)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
parent->appendChild(createTextNode("bar").get());
markNodeContents(parent.get());
EXPECT_EQ(2u, markerController().markers().size());
parent->normalize();
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(1u, markerController().markers().size());
}
TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveChildren)
{
setBodyInnerHTML("<b><i>foo</i></b>");
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent.get());
EXPECT_EQ(1u, markerController().markers().size());
parent->removeChildren();
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -117,12 +134,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedByRemoveMarked)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent);
EXPECT_EQ(1u, markerController().markers().size());
parent->removeChild(parent->firstChild());
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -130,12 +148,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveAncestor)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent);
EXPECT_EQ(1u, markerController().markers().size());
parent->parentNode()->parentNode()->removeChild(parent->parentNode());
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -143,12 +162,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByRemoveParent)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent);
EXPECT_EQ(1u, markerController().markers().size());
parent->parentNode()->removeChild(parent.get());
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -156,12 +176,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedMarkedByReplaceChild)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent.get());
EXPECT_EQ(1u, markerController().markers().size());
parent->replaceChild(createTextNode("bar").get(), parent->firstChild());
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
@@ -169,12 +190,13 @@ TEST_F(DocumentMarkerControllerTest, NodeWillBeRemovedBySetInnerHTML)
{
setBodyInnerHTML("<b><i>foo</i></b>");
{
- RefPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
+ RefPtrWillBeRawPtr<Element> parent = toElement(document().body()->firstChild()->firstChild());
markNodeContents(parent);
EXPECT_EQ(1u, markerController().markers().size());
setBodyInnerHTML("");
}
// No more reference to marked node.
+ Heap::collectAllGarbage();
EXPECT_EQ(0u, markerController().markers().size());
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h
index 133a34df77f..37b43850ba3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedList.h
@@ -45,6 +45,7 @@ public:
void remove(const Node*);
bool isEmpty() const { return m_nodes.isEmpty(); }
void clear() { m_nodes.clear(); }
+ size_t size() const { return m_nodes.size(); }
typedef ListHashSet<Node*, 32>::iterator iterator;
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
index 494d266768f..b75d1823a0c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.cpp
@@ -31,41 +31,34 @@
#include "config.h"
#include "core/dom/DocumentOrderedMap.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/TreeScope.h"
-#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLMapElement.h"
namespace WebCore {
using namespace HTMLNames;
-inline bool keyMatchesId(StringImpl* key, Element* element)
+inline bool keyMatchesId(StringImpl* key, Element& element)
{
- return element->getIdAttribute().impl() == key;
+ return element.getIdAttribute().impl() == key;
}
-inline bool keyMatchesMapName(StringImpl* key, Element* element)
+inline bool keyMatchesMapName(StringImpl* key, Element& element)
{
- return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().impl() == key;
+ return isHTMLMapElement(element) && toHTMLMapElement(element).getName().impl() == key;
}
-inline bool keyMatchesLowercasedMapName(StringImpl* key, Element* element)
+inline bool keyMatchesLowercasedMapName(StringImpl* key, Element& element)
{
- return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().lower().impl() == key;
+ return isHTMLMapElement(element) && toHTMLMapElement(element).getName().lower().impl() == key;
}
-inline bool keyMatchesLabelForAttribute(StringImpl* key, Element* element)
+inline bool keyMatchesLabelForAttribute(StringImpl* key, Element& element)
{
- return isHTMLLabelElement(element) && element->getAttribute(forAttr).impl() == key;
-}
-
-void DocumentOrderedMap::clear()
-{
- m_map.clear();
- m_duplicateCounts.clear();
+ return isHTMLLabelElement(element) && element.getAttribute(forAttr).impl() == key;
}
void DocumentOrderedMap::add(StringImpl* key, Element* element)
@@ -73,29 +66,15 @@ void DocumentOrderedMap::add(StringImpl* key, Element* element)
ASSERT(key);
ASSERT(element);
- if (!m_duplicateCounts.contains(key)) {
- // Fast path. The key is not already in m_duplicateCounts, so we assume that it's
- // also not already in m_map and try to add it. If that add succeeds, we're done.
- Map::AddResult addResult = m_map.add(key, element);
- if (addResult.isNewEntry)
- return;
-
- // The add failed, so this key was already cached in m_map.
- // There are multiple elements with this key. Remove the m_map
- // cache for this key so get searches for it next time it is called.
- m_map.remove(addResult.iterator);
- m_duplicateCounts.add(key);
- } else {
- // There are multiple elements with this key. Remove the m_map
- // cache for this key so get will search for it next time it is called.
- Map::iterator cachedItem = m_map.find(key);
- if (cachedItem != m_map.end()) {
- m_map.remove(cachedItem);
- m_duplicateCounts.add(key);
- }
- }
+ Map::AddResult addResult = m_map.add(key, adoptPtr(new MapEntry(element)));
+ if (addResult.isNewEntry)
+ return;
- m_duplicateCounts.add(key);
+ OwnPtr<MapEntry>& entry = addResult.storedValue->value;
+ ASSERT(entry->count);
+ entry->element = 0;
+ entry->count++;
+ entry->orderedList.clear();
}
void DocumentOrderedMap::remove(StringImpl* key, Element* element)
@@ -103,36 +82,47 @@ void DocumentOrderedMap::remove(StringImpl* key, Element* element)
ASSERT(key);
ASSERT(element);
- Map::iterator cachedItem = m_map.find(key);
- if (cachedItem != m_map.end() && cachedItem->value == element)
- m_map.remove(cachedItem);
- else
- m_duplicateCounts.remove(key);
+ Map::iterator it = m_map.find(key);
+ if (it == m_map.end())
+ return;
+
+ OwnPtr<MapEntry>& entry = it->value;
+ ASSERT(entry->count);
+ if (entry->count == 1) {
+ ASSERT(!entry->element || entry->element == element);
+ m_map.remove(it);
+ } else {
+ if (entry->element == element) {
+ ASSERT(entry->orderedList.isEmpty() || entry->orderedList.first() == element);
+ entry->element = entry->orderedList.size() > 1 ? entry->orderedList[1] : 0;
+ }
+ entry->count--;
+ entry->orderedList.clear();
+ }
}
-template<bool keyMatches(StringImpl*, Element*)>
+template<bool keyMatches(StringImpl*, Element&)>
inline Element* DocumentOrderedMap::get(StringImpl* key, const TreeScope* scope) const
{
ASSERT(key);
ASSERT(scope);
- Element* element = m_map.get(key);
- if (element)
- return element;
+ MapEntry* entry = m_map.get(key);
+ if (!entry)
+ return 0;
- if (m_duplicateCounts.contains(key)) {
- // We know there's at least one node that matches; iterate to find the first one.
- ASSERT(scope->rootNode());
- for (element = ElementTraversal::firstWithin(*scope->rootNode()); element; element = ElementTraversal::next(*element)) {
- if (!keyMatches(key, element))
- continue;
- m_duplicateCounts.remove(key);
- m_map.set(key, element);
- return element;
- }
- ASSERT_NOT_REACHED();
- }
+ ASSERT(entry->count);
+ if (entry->element)
+ return entry->element;
+ // We know there's at least one node that matches; iterate to find the first one.
+ for (Element* element = ElementTraversal::firstWithin(scope->rootNode()); element; element = ElementTraversal::next(*element)) {
+ if (!keyMatches(key, *element))
+ continue;
+ entry->element = element;
+ return element;
+ }
+ ASSERT_NOT_REACHED();
return 0;
}
@@ -141,6 +131,34 @@ Element* DocumentOrderedMap::getElementById(StringImpl* key, const TreeScope* sc
return get<keyMatchesId>(key, scope);
}
+const Vector<Element*>& DocumentOrderedMap::getAllElementsById(StringImpl* key, const TreeScope* scope) const
+{
+ ASSERT(key);
+ ASSERT(scope);
+ DEFINE_STATIC_LOCAL(Vector<Element*>, emptyVector, ());
+
+ Map::iterator it = m_map.find(key);
+ if (it == m_map.end())
+ return emptyVector;
+
+ OwnPtr<MapEntry>& entry = it->value;
+ ASSERT(entry->count);
+
+ if (entry->orderedList.isEmpty()) {
+ entry->orderedList.reserveCapacity(entry->count);
+ for (Element* element = entry->element ? entry->element : ElementTraversal::firstWithin(scope->rootNode()); entry->orderedList.size() < entry->count; element = ElementTraversal::next(*element)) {
+ ASSERT(element);
+ if (!keyMatchesId(key, *element))
+ continue;
+ entry->orderedList.uncheckedAppend(element);
+ }
+ if (!entry->element)
+ entry->element = entry->orderedList.first();
+ }
+
+ return entry->orderedList;
+}
+
Element* DocumentOrderedMap::getElementByMapName(StringImpl* key, const TreeScope* scope) const
{
return get<keyMatchesMapName>(key, scope);
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
index b6fc8e07e0d..e5158ee1715 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentOrderedMap.h
@@ -31,7 +31,7 @@
#ifndef DocumentOrderedMap_h
#define DocumentOrderedMap_h
-#include "wtf/HashCountedSet.h"
+#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/text/StringImpl.h"
@@ -44,38 +44,44 @@ class DocumentOrderedMap {
public:
void add(StringImpl*, Element*);
void remove(StringImpl*, Element*);
- void clear();
bool contains(StringImpl*) const;
bool containsMultiple(StringImpl*) const;
// concrete instantiations of the get<>() method template
Element* getElementById(StringImpl*, const TreeScope*) const;
+ const Vector<Element*>& getAllElementsById(StringImpl*, const TreeScope*) const;
Element* getElementByMapName(StringImpl*, const TreeScope*) const;
Element* getElementByLowercasedMapName(StringImpl*, const TreeScope*) const;
Element* getElementByLabelForAttribute(StringImpl*, const TreeScope*) const;
- void checkConsistency() const;
-
private:
- template<bool keyMatches(StringImpl*, Element*)> Element* get(StringImpl*, const TreeScope*) const;
+ template<bool keyMatches(StringImpl*, Element&)> Element* get(StringImpl*, const TreeScope*) const;
+
+ struct MapEntry {
+ explicit MapEntry(Element* firstElement)
+ : element(firstElement)
+ , count(1)
+ { }
+
+ Element* element;
+ unsigned count;
+ Vector<Element*> orderedList;
+ };
- typedef HashMap<StringImpl*, Element*> Map;
+ typedef HashMap<StringImpl*, OwnPtr<MapEntry> > Map;
- // We maintain the invariant that m_duplicateCounts is the count of all elements with a given key
- // excluding the one referenced in m_map, if any. This means it one less than the total count
- // when the first node with a given key is cached, otherwise the same as the total count.
mutable Map m_map;
- mutable HashCountedSet<StringImpl*> m_duplicateCounts;
};
inline bool DocumentOrderedMap::contains(StringImpl* id) const
{
- return m_map.contains(id) || m_duplicateCounts.contains(id);
+ return m_map.contains(id);
}
inline bool DocumentOrderedMap::containsMultiple(StringImpl* id) const
{
- return m_duplicateCounts.contains(id);
+ Map::const_iterator it = m_map.find(id);
+ return it != m_map.end() && it->value->count > 1;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp
index ac2ffa99a21..2fef5ff92c0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentParser.cpp
@@ -25,8 +25,9 @@
#include "config.h"
#include "core/dom/DocumentParser.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/dom/Document.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "wtf/Assertions.h"
namespace WebCore {
@@ -41,10 +42,17 @@ DocumentParser::DocumentParser(Document* document)
DocumentParser::~DocumentParser()
{
+#if !ENABLE(OILPAN)
// Document is expected to call detach() before releasing its ref.
// This ASSERT is slightly awkward for parsers with a fragment case
// as there is no Document to release the ref.
ASSERT(!m_document);
+#endif
+}
+
+void DocumentParser::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
}
void DocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder>)
@@ -76,7 +84,7 @@ void DocumentParser::stopParsing()
void DocumentParser::detach()
{
m_state = DetachedState;
- m_document = 0;
+ m_document = nullptr;
}
void DocumentParser::suspendScheduledTasks()
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentParser.h b/chromium/third_party/WebKit/Source/core/dom/DocumentParser.h
index c0b502ae36b..c8ed45f5f20 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentParser.h
@@ -24,9 +24,9 @@
#ifndef DocumentParser_h
#define DocumentParser_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
namespace WebCore {
@@ -36,9 +36,10 @@ class SegmentedString;
class ScriptableDocumentParser;
class TextResourceDecoder;
-class DocumentParser : public RefCounted<DocumentParser> {
+class DocumentParser : public RefCountedWillBeGarbageCollectedFinalized<DocumentParser> {
public:
virtual ~DocumentParser();
+ virtual void trace(Visitor*);
virtual ScriptableDocumentParser* asScriptableDocumentParser() { return 0; }
@@ -97,6 +98,7 @@ public:
// callstacks, but not produce any more nodes.
// It is impossible for the parser to touch the rest of WebCore after
// detach is called.
+ // Oilpan: We don't need to call detach when a Document is destructed.
virtual void detach();
void setDocumentWasLoadedAsPartOfNavigation() { m_documentWasLoadedAsPartOfNavigation = true; }
@@ -121,7 +123,7 @@ private:
// Every DocumentParser needs a pointer back to the document.
// m_document will be 0 after the parser is stopped.
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.cpp
deleted file mode 100644
index 985f04cdde9..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "config.h"
-#include "core/dom/DocumentSharedObjectPool.h"
-
-#include "core/dom/Element.h"
-
-namespace WebCore {
-
-class ShareableElementDataCacheKey {
-public:
- ShareableElementDataCacheKey(const Attribute* attributes, unsigned attributeCount)
- : m_attributes(attributes)
- , m_attributeCount(attributeCount)
- { }
-
- bool operator!=(const ShareableElementDataCacheKey& other) const
- {
- if (m_attributeCount != other.m_attributeCount)
- return true;
- return memcmp(m_attributes, other.m_attributes, sizeof(Attribute) * m_attributeCount);
- }
-
- unsigned hash() const
- {
- return StringHasher::hashMemory(m_attributes, m_attributeCount * sizeof(Attribute));
- }
-
-private:
- const Attribute* m_attributes;
- unsigned m_attributeCount;
-};
-
-class ShareableElementDataCacheEntry {
-public:
- ShareableElementDataCacheEntry(const ShareableElementDataCacheKey& k, PassRefPtr<ShareableElementData> v)
- : key(k)
- , value(v)
- { }
-
- ShareableElementDataCacheKey key;
- RefPtr<ShareableElementData> value;
-};
-
-PassRefPtr<ShareableElementData> DocumentSharedObjectPool::cachedShareableElementDataWithAttributes(const Vector<Attribute>& attributes)
-{
- ASSERT(!attributes.isEmpty());
-
- ShareableElementDataCacheKey cacheKey(attributes.data(), attributes.size());
- unsigned cacheHash = cacheKey.hash();
-
- ShareableElementDataCache::iterator cacheIterator = m_shareableElementDataCache.add(cacheHash, nullptr).iterator;
- if (cacheIterator->value && cacheIterator->value->key != cacheKey)
- cacheHash = 0;
-
- RefPtr<ShareableElementData> elementData;
- if (cacheHash && cacheIterator->value)
- elementData = cacheIterator->value->value;
- else
- elementData = ShareableElementData::createWithAttributes(attributes);
-
- if (!cacheHash || cacheIterator->value)
- return elementData.release();
-
- cacheIterator->value = adoptPtr(new ShareableElementDataCacheEntry(ShareableElementDataCacheKey(elementData->m_attributeArray, elementData->length()), elementData));
-
- return elementData.release();
-}
-
-DocumentSharedObjectPool::DocumentSharedObjectPool()
-{
-}
-
-DocumentSharedObjectPool::~DocumentSharedObjectPool()
-{
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.h b/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.h
deleted file mode 100644
index 2f827db60a0..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentSharedObjectPool.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef DocumentSharedObjectPool_h
-#define DocumentSharedObjectPool_h
-
-#include "wtf/HashMap.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/text/StringHash.h"
-
-namespace WebCore {
-
-class Attribute;
-class ShareableElementData;
-class ShareableElementDataCacheEntry;
-
-class DocumentSharedObjectPool {
-public:
- static PassOwnPtr<DocumentSharedObjectPool> create() { return adoptPtr(new DocumentSharedObjectPool); }
- ~DocumentSharedObjectPool();
-
- PassRefPtr<ShareableElementData> cachedShareableElementDataWithAttributes(const Vector<Attribute>&);
-
-private:
- DocumentSharedObjectPool();
-
- typedef HashMap<unsigned, OwnPtr<ShareableElementDataCacheEntry>, AlreadyHashed> ShareableElementDataCache;
- ShareableElementDataCache m_shareableElementDataCache;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp
index 94421382571..cd55b40c5ee 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -27,166 +27,105 @@
#include "config.h"
#include "core/dom/DocumentStyleSheetCollection.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
-#include "core/css/CSSStyleSheet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
-#include "core/dom/Element.h"
+#include "core/dom/DocumentStyleSheetCollector.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/StyleEngine.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLLinkElement.h"
-#include "core/html/HTMLStyleElement.h"
-#include "core/frame/Settings.h"
-#include "core/svg/SVGStyleElement.h"
+#include "core/dom/StyleSheetCandidate.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-using namespace HTMLNames;
-
DocumentStyleSheetCollection::DocumentStyleSheetCollection(TreeScope& treeScope)
- : StyleSheetCollection(treeScope)
+ : TreeScopeStyleSheetCollection(treeScope)
{
- ASSERT(treeScope.rootNode() == treeScope.rootNode()->document());
+ ASSERT(treeScope.rootNode() == treeScope.rootNode().document());
}
-void DocumentStyleSheetCollection::collectStyleSheetsFromCandidates(StyleEngine* engine, StyleSheetCollectionBase& collection, DocumentStyleSheetCollection::CollectFor collectFor)
+void DocumentStyleSheetCollection::collectStyleSheetsFromCandidates(StyleEngine* engine, DocumentStyleSheetCollector& collector)
{
DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
Node* n = *it;
- StyleSheet* sheet = 0;
- CSSStyleSheet* activeSheet = 0;
- if (n->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && !document()->isHTMLDocument()) {
- // Processing instruction (XML documents only).
- // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
- ProcessingInstruction* pi = toProcessingInstruction(n);
- // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
- if (RuntimeEnabledFeatures::xsltEnabled() && pi->isXSL() && !document()->transformSourceDocument()) {
- // Don't apply XSL transforms until loading is finished.
- if (!document()->parsing() && !pi->isLoading())
- document()->applyXSLTransform(pi);
- return;
- }
- sheet = pi->sheet();
- if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
- activeSheet = toCSSStyleSheet(sheet);
- } else if ((n->isHTMLElement() && (n->hasTagName(linkTag) || n->hasTagName(styleTag))) || (n->isSVGElement() && n->hasTagName(SVGNames::styleTag))) {
- Element* e = toElement(n);
- AtomicString title = e->getAttribute(titleAttr);
- bool enabledViaScript = false;
- if (e->hasLocalName(linkTag)) {
- // <LINK> element
- HTMLLinkElement* linkElement = toHTMLLinkElement(n);
- enabledViaScript = linkElement->isEnabledViaScript();
- if (!linkElement->isDisabled() && linkElement->styleSheetIsLoading()) {
- // it is loading but we should still decide which style sheet set to use
- if (!enabledViaScript && !title.isEmpty() && engine->preferredStylesheetSetName().isEmpty()) {
- const AtomicString& rel = e->getAttribute(relAttr);
- if (!rel.contains("alternate")) {
- engine->setPreferredStylesheetSetName(title);
- engine->setSelectedStylesheetSetName(title);
- }
- }
-
- continue;
- }
- sheet = linkElement->sheet();
- if (!sheet)
- title = nullAtom;
- } else if (n->isSVGElement() && n->hasTagName(SVGNames::styleTag)) {
- sheet = toSVGStyleElement(n)->sheet();
- } else {
- sheet = toHTMLStyleElement(n)->sheet();
- }
-
- if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
- activeSheet = toCSSStyleSheet(sheet);
-
- // Check to see if this sheet belongs to a styleset
- // (thus making it PREFERRED or ALTERNATE rather than
- // PERSISTENT).
- AtomicString rel = e->getAttribute(relAttr);
- if (!enabledViaScript && sheet && !title.isEmpty()) {
- // Yes, we have a title.
- if (engine->preferredStylesheetSetName().isEmpty()) {
- // No preferred set has been established. If
- // we are NOT an alternate sheet, then establish
- // us as the preferred set. Otherwise, just ignore
- // this sheet.
- if (e->hasLocalName(styleTag) || !rel.contains("alternate")) {
- engine->setPreferredStylesheetSetName(title);
- engine->setSelectedStylesheetSetName(title);
- }
- }
- if (title != engine->preferredStylesheetSetName())
- activeSheet = 0;
- }
-
- if (rel.contains("alternate") && title.isEmpty())
- activeSheet = 0;
+ StyleSheetCandidate candidate(*n);
+
+ ASSERT(!candidate.isXSL());
+ if (candidate.isImport()) {
+ Document* document = candidate.importedDocument();
+ if (!document)
+ continue;
+ if (collector.hasVisited(document))
+ continue;
+ collector.willVisit(document);
+ document->styleEngine()->updateStyleSheetsInImport(collector);
+ continue;
}
- if (sheet && collectFor == CollectForList)
- collection.appendSheetForList(sheet);
- if (activeSheet)
- collection.appendActiveStyleSheet(activeSheet);
- }
-}
+ if (candidate.isEnabledAndLoading()) {
+ // it is loading but we should still decide which style sheet set to use
+ if (candidate.hasPreferrableName(engine->preferredStylesheetSetName()))
+ engine->selectStylesheetSetName(candidate.title());
+ continue;
+ }
-static void collectActiveCSSStyleSheetsFromSeamlessParents(StyleSheetCollectionBase& collection, Document* document)
-{
- HTMLIFrameElement* seamlessParentIFrame = document->seamlessParentIFrame();
- if (!seamlessParentIFrame)
- return;
- collection.appendActiveStyleSheets(seamlessParentIFrame->document().styleEngine()->activeAuthorStyleSheets());
+ StyleSheet* sheet = candidate.sheet();
+ if (!sheet)
+ continue;
+
+ if (candidate.hasPreferrableName(engine->preferredStylesheetSetName()))
+ engine->selectStylesheetSetName(candidate.title());
+ collector.appendSheetForList(sheet);
+ if (candidate.canBeActivated(engine->preferredStylesheetSetName()))
+ collector.appendActiveStyleSheet(toCSSStyleSheet(sheet));
+ }
}
-void DocumentStyleSheetCollection::collectStyleSheets(StyleEngine* engine, StyleSheetCollectionBase& collection, DocumentStyleSheetCollection::CollectFor colletFor)
+void DocumentStyleSheetCollection::collectStyleSheets(StyleEngine* engine, DocumentStyleSheetCollector& collector)
{
- ASSERT(document()->styleEngine() == engine);
- collection.appendActiveStyleSheets(engine->injectedAuthorStyleSheets());
- collection.appendActiveStyleSheets(engine->documentAuthorStyleSheets());
- collectActiveCSSStyleSheetsFromSeamlessParents(collection, document());
- collectStyleSheetsFromCandidates(engine, collection, colletFor);
+ ASSERT(document().styleEngine() == engine);
+ collector.appendActiveStyleSheets(engine->injectedAuthorStyleSheets());
+ collector.appendActiveStyleSheets(engine->documentAuthorStyleSheets());
+ collectStyleSheetsFromCandidates(engine, collector);
}
-bool DocumentStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
+void DocumentStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
{
- StyleSheetCollectionBase collection;
- engine->collectDocumentActiveStyleSheets(collection);
+ StyleSheetCollection collection;
+ ActiveDocumentStyleSheetCollector collector(collection);
+ collectStyleSheets(engine, collector);
StyleSheetChange change;
analyzeStyleSheetChange(updateMode, collection, change);
if (change.styleResolverUpdateType == Reconstruct) {
engine->clearMasterResolver();
- engine->resetFontSelector();
+ // FIMXE: The following depends on whether StyleRuleFontFace was modified or not.
+ // No need to always-clear font cache.
+ engine->clearFontCache();
} else if (StyleResolver* styleResolver = engine->resolver()) {
// FIXME: We might have already had styles in child treescope. In this case, we cannot use buildScopedStyleTreeInDocumentOrder.
// Need to change "false" to some valid condition.
styleResolver->setBuildScopedStyleTreeInDocumentOrder(false);
if (change.styleResolverUpdateType != Additive) {
- ASSERT(change.styleResolverUpdateType == Reset || change.styleResolverUpdateType == ResetStyleResolverAndFontSelector);
+ ASSERT(change.styleResolverUpdateType == Reset);
resetAllRuleSetsInTreeScope(styleResolver);
- if (change.styleResolverUpdateType == ResetStyleResolverAndFontSelector)
- engine->resetFontSelector();
+ engine->removeFontFaceRules(change.fontFaceRulesToRemove);
styleResolver->removePendingAuthorStyleSheets(m_activeAuthorStyleSheets);
styleResolver->lazyAppendAuthorStyleSheets(0, collection.activeAuthorStyleSheets());
} else {
styleResolver->lazyAppendAuthorStyleSheets(m_activeAuthorStyleSheets.size(), collection.activeAuthorStyleSheets());
}
- } else if (change.styleResolverUpdateType == ResetStyleResolverAndFontSelector) {
- engine->resetFontSelector();
}
+ if (change.requiresFullStyleRecalc)
+ document().setNeedsStyleRecalc(SubtreeStyleChange);
+
m_scopingNodesForStyleScoped.didRemoveScopingNodes();
+
collection.swap(*this);
- updateUsesRemUnits();
- return change.requiresFullStyleRecalc;
+ updateUsesRemUnits();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h
index 9920ad8a848..84de5f865ca 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollection.h
@@ -28,31 +28,30 @@
#ifndef DocumentStyleSheetCollection_h
#define DocumentStyleSheetCollection_h
-#include "core/dom/StyleSheetCollection.h"
+#include "core/dom/TreeScopeStyleSheetCollection.h"
namespace WebCore {
-class CSSStyleSheet;
-class StyleSheet;
-class StyleSheetCollection;
+class DocumentStyleSheetCollector;
class StyleEngine;
class TreeScope;
-class DocumentStyleSheetCollection FINAL : public StyleSheetCollection {
- WTF_MAKE_NONCOPYABLE(DocumentStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
+class DocumentStyleSheetCollection FINAL : public TreeScopeStyleSheetCollection {
+ WTF_MAKE_NONCOPYABLE(DocumentStyleSheetCollection);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
explicit DocumentStyleSheetCollection(TreeScope&);
- enum CollectFor {
- CollectForList,
- DontCollectForList
- };
+ void updateActiveStyleSheets(StyleEngine*, StyleResolverUpdateMode);
+ void collectStyleSheets(StyleEngine*, DocumentStyleSheetCollector&);
- bool updateActiveStyleSheets(StyleEngine*, StyleResolverUpdateMode);
- void collectStyleSheets(StyleEngine*, StyleSheetCollectionBase&, CollectFor);
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ TreeScopeStyleSheetCollection::trace(visitor);
+ }
private:
- void collectStyleSheetsFromCandidates(StyleEngine*, StyleSheetCollectionBase&, CollectFor);
+ void collectStyleSheetsFromCandidates(StyleEngine*, DocumentStyleSheetCollector&);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.cpp
new file mode 100644
index 00000000000..47818b9392d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/DocumentStyleSheetCollector.h"
+
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/StyleSheet.h"
+#include "core/dom/DocumentStyleSheetCollection.h"
+
+namespace WebCore {
+
+DocumentStyleSheetCollector::DocumentStyleSheetCollector(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetsForList, WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeList, WillBeHeapHashSet<RawPtrWillBeMember<Document> >& visitedDocuments)
+ : m_styleSheetsForStyleSheetList(sheetsForList)
+ , m_activeAuthorStyleSheets(activeList)
+ , m_visitedDocuments(visitedDocuments)
+{
+}
+
+DocumentStyleSheetCollector::~DocumentStyleSheetCollector()
+{
+}
+
+void DocumentStyleSheetCollector::appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
+{
+ m_activeAuthorStyleSheets.appendVector(sheets);
+}
+
+void DocumentStyleSheetCollector::appendActiveStyleSheet(CSSStyleSheet* sheet)
+{
+ m_activeAuthorStyleSheets.append(sheet);
+}
+
+void DocumentStyleSheetCollector::appendSheetForList(StyleSheet* sheet)
+{
+ m_styleSheetsForStyleSheetList.append(sheet);
+}
+
+ActiveDocumentStyleSheetCollector::ActiveDocumentStyleSheetCollector(StyleSheetCollection& collection)
+ : DocumentStyleSheetCollector(collection.m_styleSheetsForStyleSheetList, collection.m_activeAuthorStyleSheets, m_visitedDocuments)
+{
+}
+
+ImportedDocumentStyleSheetCollector::ImportedDocumentStyleSheetCollector(DocumentStyleSheetCollector& collector, WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetForList)
+ : DocumentStyleSheetCollector(sheetForList, collector.m_activeAuthorStyleSheets, collector.m_visitedDocuments)
+{
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h
new file mode 100644
index 00000000000..fd74c839162
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DocumentStyleSheetCollector_h
+#define DocumentStyleSheetCollector_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/HashSet.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CSSStyleSheet;
+class Document;
+class StyleSheet;
+class StyleSheetCollection;
+
+class DocumentStyleSheetCollector {
+ // This class contains references to two on-heap collections, therefore
+ // it's unhealthy to have it anywhere but on the stack, where stack
+ // scanning will keep them alive.
+ STACK_ALLOCATED();
+public:
+ friend class ImportedDocumentStyleSheetCollector;
+
+ DocumentStyleSheetCollector(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetsForList, WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeList, WillBeHeapHashSet<RawPtrWillBeMember<Document> >&);
+ ~DocumentStyleSheetCollector();
+
+ void appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
+ void appendActiveStyleSheet(CSSStyleSheet*);
+ void appendSheetForList(StyleSheet*);
+
+ bool hasVisited(Document* document) const { return m_visitedDocuments.contains(document); }
+ void willVisit(Document* document) { m_visitedDocuments.add(document); }
+
+private:
+ WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& m_styleSheetsForStyleSheetList;
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& m_activeAuthorStyleSheets;
+ WillBeHeapHashSet<RawPtrWillBeMember<Document> >& m_visitedDocuments;
+};
+
+class ActiveDocumentStyleSheetCollector FINAL : public DocumentStyleSheetCollector {
+public:
+ ActiveDocumentStyleSheetCollector(StyleSheetCollection&);
+private:
+ WillBeHeapHashSet<RawPtrWillBeMember<Document> > m_visitedDocuments;
+};
+
+class ImportedDocumentStyleSheetCollector FINAL : public DocumentStyleSheetCollector {
+public:
+ ImportedDocumentStyleSheetCollector(DocumentStyleSheetCollector&, WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >&);
+};
+
+} // namespace WebCore
+
+#endif // DocumentStyleSheetCollector_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h b/chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h
index 9b5e7790af0..0156646cbbe 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentSupplementable.h
@@ -34,8 +34,8 @@ namespace WebCore {
class Document;
-typedef Supplementable<Document> DocumentSupplementable;
-typedef Supplement<Document> DocumentSupplement;
+typedef WillBeHeapSupplementable<Document> DocumentSupplementable;
+typedef WillBeHeapSupplement<Document> DocumentSupplement;
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentTest.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentTest.cpp
new file mode 100644
index 00000000000..5867805f548
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentTest.cpp
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/Document.h"
+
+#include "core/html/HTMLHeadElement.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class DocumentTest : public ::testing::Test {
+protected:
+ virtual void SetUp() OVERRIDE;
+
+ Document& document() const { return m_dummyPageHolder->document(); }
+ Page& page() const { return m_dummyPageHolder->page(); }
+
+private:
+ OwnPtr<DummyPageHolder> m_dummyPageHolder;
+};
+
+void DocumentTest::SetUp()
+{
+ m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+}
+
+class MockDocumentVisibilityObserver
+ : public NoBaseWillBeGarbageCollectedFinalized<MockDocumentVisibilityObserver>
+ , public DocumentVisibilityObserver {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MockDocumentVisibilityObserver);
+public:
+ static PassOwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> create(Document& document)
+ {
+ return adoptPtrWillBeNoop(new MockDocumentVisibilityObserver(document));
+ }
+
+ virtual void trace(Visitor*) { }
+
+ MOCK_METHOD1(didChangeVisibilityState, void(PageVisibilityState));
+
+private:
+ MockDocumentVisibilityObserver(Document& document) : DocumentVisibilityObserver(document) { }
+};
+
+TEST_F(DocumentTest, VisibilityOberver)
+{
+ page().setVisibilityState(PageVisibilityStateVisible, true); // initial state
+ OwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> observer1 = MockDocumentVisibilityObserver::create(document());
+
+ {
+ OwnPtrWillBeRawPtr<MockDocumentVisibilityObserver> observer2 = MockDocumentVisibilityObserver::create(document());
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ page().setVisibilityState(PageVisibilityStateHidden, false);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ page().setVisibilityState(PageVisibilityStateHidden, false);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(1);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ OwnPtr<DummyPageHolder> alternatePage = DummyPageHolder::create(IntSize(800, 600));
+ Document& alternateDocument = alternatePage->document();
+ observer2->setObservedDocument(alternateDocument);
+ page().setVisibilityState(PageVisibilityStateVisible, false);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateHidden)).Times(1);
+ EXPECT_CALL(*observer2, didChangeVisibilityState(PageVisibilityStateVisible)).Times(0);
+ observer2->setObservedDocument(document());
+ page().setVisibilityState(PageVisibilityStateHidden, false);
+ ::testing::Mock::VerifyAndClearExpectations(observer1.get());
+ ::testing::Mock::VerifyAndClearExpectations(observer2.get());
+ }
+
+ // observer2 destroyed
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateHidden)).Times(0);
+ EXPECT_CALL(*observer1, didChangeVisibilityState(PageVisibilityStateVisible)).Times(1);
+ page().setVisibilityState(PageVisibilityStateVisible, false);
+}
+
+// This test checks that Documunt::linkManifest() returns a value conform to the specification.
+TEST_F(DocumentTest, LinkManifest)
+{
+ // Test the default result.
+ EXPECT_EQ(0, document().linkManifest());
+
+ // Check that we use the first manifest with <link rel=manifest>
+ RefPtrWillBeRawPtr<HTMLLinkElement> link = HTMLLinkElement::create(document(), false);
+ link->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "foo.json");
+ document().head()->appendChild(link);
+ EXPECT_EQ(link, document().linkManifest());
+
+ RefPtrWillBeRawPtr<HTMLLinkElement> link2 = HTMLLinkElement::create(document(), false);
+ link2->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
+ link2->setAttribute(WebCore::HTMLNames::hrefAttr, "bar.json");
+ document().head()->insertBefore(link2, link.get());
+ EXPECT_EQ(link2, document().linkManifest());
+ document().head()->appendChild(link2);
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Check that crazy URLs are accepted.
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "http:foo.json");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Check that empty URLs are accepted.
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Check that URLs from different origins are accepted.
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://example.org/manifest.json");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://foo.example.org/manifest.json");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::hrefAttr, "http://foo.bar/manifest.json");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // More than one token in @rel is accepted.
+ link->setAttribute(WebCore::HTMLNames::relAttr, "foo bar manifest");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Such as spaces around the token.
+ link->setAttribute(WebCore::HTMLNames::relAttr, " manifest ");
+ EXPECT_EQ(link, document().linkManifest());
+
+ // Check that rel=manifest actually matters.
+ link->setAttribute(WebCore::HTMLNames::relAttr, "");
+ EXPECT_EQ(link2, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::relAttr, "manifest");
+
+ // Check that link outside of the <head> are ignored.
+ document().head()->removeChild(link.get(), ASSERT_NO_EXCEPTION);
+ document().head()->removeChild(link2.get(), ASSERT_NO_EXCEPTION);
+ EXPECT_EQ(0, document().linkManifest());
+ document().body()->appendChild(link);
+ EXPECT_EQ(0, document().linkManifest());
+ document().head()->appendChild(link);
+ document().head()->appendChild(link2);
+
+ // Check that some attribute values do not have an effect.
+ link->setAttribute(WebCore::HTMLNames::crossoriginAttr, "use-credentials");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::hreflangAttr, "klingon");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::typeAttr, "image/gif");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::sizesAttr, "16x16");
+ EXPECT_EQ(link, document().linkManifest());
+ link->setAttribute(WebCore::HTMLNames::mediaAttr, "print");
+ EXPECT_EQ(link, document().linkManifest());
+}
+
+} // unnamed namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp b/chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp
index 7c392a7035f..1859a617a7c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentType.cpp
@@ -52,7 +52,7 @@ Node::NodeType DocumentType::nodeType() const
return DOCUMENT_TYPE_NODE;
}
-PassRefPtr<Node> DocumentType::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> DocumentType::cloneNode(bool /*deep*/)
{
return create(&document(), m_name, m_publicId, m_systemId);
}
@@ -71,7 +71,7 @@ Node::InsertionNotificationRequest DocumentType::insertedInto(ContainerNode* ins
void DocumentType::removedFrom(ContainerNode* insertionPoint)
{
- document().setDoctype(0);
+ document().setDoctype(nullptr);
Node::removedFrom(insertionPoint);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentType.h b/chromium/third_party/WebKit/Source/core/dom/DocumentType.h
index 6aa51fe4194..4976f299a4b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentType.h
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentType.h
@@ -32,20 +32,14 @@ class NamedNodeMap;
class DocumentType FINAL : public Node {
public:
- static PassRefPtr<DocumentType> create(Document* document, const String& name, const String& publicId, const String& systemId)
+ static PassRefPtrWillBeRawPtr<DocumentType> create(Document* document, const String& name, const String& publicId, const String& systemId)
{
- return adoptRef(new DocumentType(document, name, publicId, systemId));
+ return adoptRefWillBeNoop(new DocumentType(document, name, publicId, systemId));
}
- // FIXME: These wre removed from DOM4, we should add a UseCounter and see if
- // we can remove them since they never worked anyway.
- NamedNodeMap* entities() const { return 0; }
- NamedNodeMap* notations() const { return 0; }
-
const String& name() const { return m_name; }
const String& publicId() const { return m_publicId; }
const String& systemId() const { return m_systemId; }
- const String& internalSubset() const { return m_subset; }
private:
DocumentType(Document*, const String& name, const String& publicId, const String& systemId);
@@ -53,7 +47,7 @@ private:
virtual KURL baseURI() const OVERRIDE;
virtual String nodeName() const OVERRIDE;
virtual NodeType nodeType() const OVERRIDE;
- virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
@@ -61,10 +55,9 @@ private:
String m_name;
String m_publicId;
String m_systemId;
- String m_subset;
};
-DEFINE_NODE_TYPE_CASTS(DocumentType, nodeType() == Node::DOCUMENT_TYPE_NODE);
+DEFINE_NODE_TYPE_CASTS(DocumentType, isDocumentTypeNode());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/DocumentType.idl b/chromium/third_party/WebKit/Source/core/dom/DocumentType.idl
index 510240a1362..680352bc1b6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/DocumentType.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/DocumentType.idl
@@ -22,14 +22,11 @@ interface DocumentType : Node {
// DOM Level 1
readonly attribute DOMString name;
- [MeasureAs=DocumentTypeEntities] readonly attribute NamedNodeMap entities; // Removed from DOM4.
- [MeasureAs=DocumentTypeNotations] readonly attribute NamedNodeMap notations; // Removed from DOM4.
// DOM Level 2
- [TreatReturnedNullStringAs=Null] readonly attribute DOMString publicId;
- [TreatReturnedNullStringAs=Null] readonly attribute DOMString systemId;
- [TreatReturnedNullStringAs=Null, MeasureAs=DocumentTypeInternalSubset] readonly attribute DOMString internalSubset; // Removed from DOM4.
+ readonly attribute DOMString publicId;
+ readonly attribute DOMString systemId;
};
DocumentType implements ChildNode;
diff --git a/chromium/third_party/WebKit/Source/core/dom/Element.cpp b/chromium/third_party/WebKit/Source/core/dom/Element.cpp
index 8be9f406e93..a75add2f8ed 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Element.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Element.cpp
@@ -26,37 +26,41 @@
#include "config.h"
#include "core/dom/Element.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
-#include "XMLNames.h"
+#include "bindings/v8/Dictionary.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/CSSValueKeywords.h"
+#include "core/SVGNames.h"
+#include "core/XMLNames.h"
#include "core/accessibility/AXObjectCache.h"
-#include "core/animation/DocumentTimeline.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/animation/css/CSSAnimations.h"
-#include "core/css/CSSParser.h"
+#include "core/css/CSSImageValue.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/CSSValuePool.h"
#include "core/css/PropertySetCSSStyleDeclaration.h"
#include "core/css/StylePropertySet.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/resolver/StyleResolver.h"
+#include "core/css/resolver/StyleResolverParentScope.h"
#include "core/dom/Attr.h"
#include "core/dom/CSSSelectorWatch.h"
#include "core/dom/ClientRect.h"
#include "core/dom/ClientRectList.h"
#include "core/dom/DatasetDOMStringMap.h"
-#include "core/dom/DocumentSharedObjectPool.h"
+#include "core/dom/ElementDataCache.h"
#include "core/dom/ElementRareData.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/MutationObserverInterestGroup.h"
#include "core/dom/MutationRecord.h"
#include "core/dom/NamedNodeMap.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeRenderStyle.h"
-#include "core/dom/NodeRenderingContext.h"
-#include "core/dom/PostAttachCallbacks.h"
#include "core/dom/PresentationAttributeStyle.h"
#include "core/dom/PseudoElement.h"
+#include "core/dom/RenderTreeBuilder.h"
#include "core/dom/ScriptableDocumentParser.h"
#include "core/dom/SelectorQuery.h"
#include "core/dom/Text.h"
@@ -70,14 +74,17 @@
#include "core/editing/markup.h"
#include "core/events/EventDispatcher.h"
#include "core/events/FocusEvent.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/ClassList.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLFormControlsCollection.h"
+#include "core/html/HTMLFrameElementBase.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLOptionsCollection.h"
@@ -88,15 +95,17 @@
#include "core/page/FocusController.h"
#include "core/page/Page.h"
#include "core/page/PointerLockController.h"
-#include "core/rendering/FlowThreadController.h"
-#include "core/rendering/RenderNamedFlowFragment.h"
+#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
-#include "core/rendering/RenderWidget.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/scroll/ScrollableArea.h"
#include "wtf/BitVector.h"
#include "wtf/HashFunctions.h"
#include "wtf/text/CString.h"
+#include "wtf/text/StringBuilder.h"
#include "wtf/text/TextPosition.h"
namespace WebCore {
@@ -104,76 +113,7 @@ namespace WebCore {
using namespace HTMLNames;
using namespace XMLNames;
-class StyleResolverParentPusher {
-public:
- explicit StyleResolverParentPusher(Element& parent)
- : m_parent(parent)
- , m_pushedStyleResolver(0)
- {
- }
- void push()
- {
- if (m_pushedStyleResolver)
- return;
- m_pushedStyleResolver = &m_parent.document().ensureStyleResolver();
- m_pushedStyleResolver->pushParentElement(m_parent);
- }
- ~StyleResolverParentPusher()
- {
-
- if (!m_pushedStyleResolver)
- return;
-
- // This tells us that our pushed style selector is in a bad state,
- // so we should just bail out in that scenario.
- ASSERT(m_pushedStyleResolver == m_parent.document().styleResolver());
- if (m_pushedStyleResolver != m_parent.document().styleResolver())
- return;
-
- m_pushedStyleResolver->popParentElement(m_parent);
- }
-
-private:
- Element& m_parent;
- StyleResolver* m_pushedStyleResolver;
-};
-
-typedef Vector<RefPtr<Attr> > AttrNodeList;
-typedef HashMap<Element*, OwnPtr<AttrNodeList> > AttrNodeListMap;
-
-static AttrNodeListMap& attrNodeListMap()
-{
- DEFINE_STATIC_LOCAL(AttrNodeListMap, map, ());
- return map;
-}
-
-static AttrNodeList* attrNodeListForElement(Element* element)
-{
- if (!element->hasSyntheticAttrChildNodes())
- return 0;
- ASSERT(attrNodeListMap().contains(element));
- return attrNodeListMap().get(element);
-}
-
-static AttrNodeList& ensureAttrNodeListForElement(Element* element)
-{
- if (element->hasSyntheticAttrChildNodes()) {
- ASSERT(attrNodeListMap().contains(element));
- return *attrNodeListMap().get(element);
- }
- ASSERT(!attrNodeListMap().contains(element));
- element->setHasSyntheticAttrChildNodes(true);
- AttrNodeListMap::AddResult result = attrNodeListMap().add(element, adoptPtr(new AttrNodeList));
- return *result.iterator->value;
-}
-
-static void removeAttrNodeListForElement(Element* element)
-{
- ASSERT(element->hasSyntheticAttrChildNodes());
- ASSERT(attrNodeListMap().contains(element));
- attrNodeListMap().remove(element);
- element->setHasSyntheticAttrChildNodes(false);
-}
+typedef WillBeHeapVector<RefPtrWillBeMember<Attr> > AttrNodeList;
static Attr* findAttrNodeInList(const AttrNodeList& attrNodeList, const QualifiedName& name)
{
@@ -185,33 +125,25 @@ static Attr* findAttrNodeInList(const AttrNodeList& attrNodeList, const Qualifie
return 0;
}
-PassRefPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
+PassRefPtrWillBeRawPtr<Element> Element::create(const QualifiedName& tagName, Document* document)
{
- return adoptRef(new Element(tagName, document, CreateElement));
+ return adoptRefWillBeNoop(new Element(tagName, document, CreateElement));
}
-Element::~Element()
+Element::Element(const QualifiedName& tagName, Document* document, ConstructionType type)
+ : ContainerNode(document, type)
+ , m_tagName(tagName)
{
- // When the document is not destroyed, an element that was part of a named flow
- // content nodes should have been removed from the content nodes collection
- // and the inNamedFlow flag reset.
- ASSERT(!document().renderView() || !inNamedFlow());
-
- if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper())
- cssomWrapper->clearParentElement();
+ ScriptWrappable::init(this);
+}
- if (hasRareData()) {
- ElementRareData* data = elementRareData();
- data->setPseudoElement(BEFORE, 0);
- data->setPseudoElement(AFTER, 0);
- data->setPseudoElement(BACKDROP, 0);
- data->clearShadow();
+Element::~Element()
+{
+ ASSERT(needsAttach());
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
- if (ActiveAnimations* activeAnimations = data->activeAnimations())
- activeAnimations->cssAnimations().cancel();
- }
- }
+#if !ENABLE(OILPAN)
+ if (hasRareData())
+ elementRareData()->clearShadow();
if (isCustomElement())
CustomElement::wasDestroyed(this);
@@ -219,10 +151,16 @@ Element::~Element()
if (hasSyntheticAttrChildNodes())
detachAllAttrNodesFromElement();
+ // With Oilpan, either the Element has been removed from the Document
+ // or the Document is dead as well. If the Element has been removed from
+ // the Document the element has already been removed from the pending
+ // resources. If the document is also dead, there is no need to remove
+ // the element from the pending resources.
if (hasPendingResources()) {
- document().accessSVGExtensions()->removeElementFromPendingResources(this);
+ document().accessSVGExtensions().removeElementFromPendingResources(this);
ASSERT(!hasPendingResources());
}
+#endif
}
inline ElementRareData* Element::elementRareData() const
@@ -236,6 +174,25 @@ inline ElementRareData& Element::ensureElementRareData()
return static_cast<ElementRareData&>(ensureRareData());
}
+bool Element::hasElementFlagInternal(ElementFlags mask) const
+{
+ return elementRareData()->hasElementFlag(mask);
+}
+
+void Element::setElementFlag(ElementFlags mask, bool value)
+{
+ if (!hasRareData() && !value)
+ return;
+ ensureElementRareData().setElementFlag(mask, value);
+}
+
+void Element::clearElementFlag(ElementFlags mask)
+{
+ if (!hasRareData())
+ return;
+ elementRareData()->clearElementFlag(mask);
+}
+
void Element::clearTabIndexExplicitlyIfNeeded()
{
if (hasRareData())
@@ -247,9 +204,9 @@ void Element::setTabIndexExplicitly(short tabIndex)
ensureElementRareData().setTabIndexExplicitly(tabIndex);
}
-bool Element::supportsFocus() const
+void Element::setTabIndex(int value)
{
- return hasRareData() && elementRareData()->tabIndexSetExplicitly();
+ setIntegralAttribute(tabindexAttr, value);
}
short Element::tabIndex() const
@@ -272,9 +229,7 @@ bool Element::rendererIsFocusable() const
// FIXME: These asserts should be in Node::isFocusable, but there are some
// callsites like Document::setFocusedElement that would currently fail on
// them. See crbug.com/251163
- if (renderer()) {
- ASSERT(!renderer()->needsLayout());
- } else {
+ if (!renderer()) {
// We can't just use needsStyleRecalc() because if the node is in a
// display:none tree it might say it needs style recalc but the whole
// document is actually up to date.
@@ -289,21 +244,21 @@ bool Element::rendererIsFocusable() const
return true;
}
-PassRefPtr<Node> Element::cloneNode(bool deep)
+PassRefPtrWillBeRawPtr<Node> Element::cloneNode(bool deep)
{
return deep ? cloneElementWithChildren() : cloneElementWithoutChildren();
}
-PassRefPtr<Element> Element::cloneElementWithChildren()
+PassRefPtrWillBeRawPtr<Element> Element::cloneElementWithChildren()
{
- RefPtr<Element> clone = cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> clone = cloneElementWithoutChildren();
cloneChildNodes(clone.get());
return clone.release();
}
-PassRefPtr<Element> Element::cloneElementWithoutChildren()
+PassRefPtrWillBeRawPtr<Element> Element::cloneElementWithoutChildren()
{
- RefPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
+ RefPtrWillBeRawPtr<Element> clone = cloneElementWithoutAttributesAndChildren();
// This will catch HTML elements in the wrong namespace that are not correctly copied.
// This is a sanity check as HTML overloads some of the DOM methods.
ASSERT(isHTMLElement() == clone->isHTMLElement());
@@ -312,20 +267,20 @@ PassRefPtr<Element> Element::cloneElementWithoutChildren()
return clone.release();
}
-PassRefPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
+PassRefPtrWillBeRawPtr<Element> Element::cloneElementWithoutAttributesAndChildren()
{
return document().createElement(tagQName(), false);
}
-PassRefPtr<Attr> Element::detachAttribute(size_t index)
+PassRefPtrWillBeRawPtr<Attr> Element::detachAttribute(size_t index)
{
ASSERT(elementData());
- const Attribute* attribute = elementData()->attributeItem(index);
- RefPtr<Attr> attrNode = attrIfExists(attribute->name());
+ const Attribute& attribute = elementData()->attributeAt(index);
+ RefPtrWillBeRawPtr<Attr> attrNode = attrIfExists(attribute.name());
if (attrNode)
detachAttrNodeAtIndex(attrNode.get(), index);
else {
- attrNode = Attr::create(document(), attribute->name(), attribute->value());
+ attrNode = Attr::create(document(), attribute.name(), attribute.value());
removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
}
return attrNode.release();
@@ -336,10 +291,9 @@ void Element::detachAttrNodeAtIndex(Attr* attr, size_t index)
ASSERT(attr);
ASSERT(elementData());
- const Attribute* attribute = elementData()->attributeItem(index);
- ASSERT(attribute);
- ASSERT(attribute->name() == attr->qualifiedName());
- detachAttrNodeFromElementWithValue(attr, attribute->value());
+ const Attribute& attribute = elementData()->attributeAt(index);
+ ASSERT(attribute.name() == attr->qualifiedName());
+ detachAttrNodeFromElementWithValue(attr, attribute.value());
removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
}
@@ -348,7 +302,7 @@ void Element::removeAttribute(const QualifiedName& name)
if (!elementData())
return;
- size_t index = elementData()->getAttributeItemIndex(name);
+ size_t index = elementData()->findAttributeIndexByName(name);
if (index == kNotFound)
return;
@@ -363,7 +317,7 @@ void Element::setBooleanAttribute(const QualifiedName& name, bool value)
removeAttribute(name);
}
-NamedNodeMap* Element::attributes() const
+NamedNodeMap* Element::attributesForBindings() const
{
ElementRareData& rareData = const_cast<Element*>(this)->ensureElementRareData();
if (NamedNodeMap* attributeMap = rareData.attributeMap())
@@ -380,19 +334,16 @@ ActiveAnimations* Element::activeAnimations() const
return 0;
}
-ActiveAnimations* Element::ensureActiveAnimations()
+ActiveAnimations& Element::ensureActiveAnimations()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.activeAnimations())
- rareData.setActiveAnimations(adoptPtr(new ActiveAnimations()));
- return rareData.activeAnimations();
+ rareData.setActiveAnimations(adoptPtrWillBeNoop(new ActiveAnimations()));
+ return *rareData.activeAnimations();
}
bool Element::hasActiveAnimations() const
{
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- return false;
-
if (!hasRareData())
return false;
@@ -414,6 +365,9 @@ void Element::synchronizeAllAttributes() const
{
if (!elementData())
return;
+ // NOTE: anyAttributeMatches in SelectorChecker.cpp
+ // currently assumes that all lazy attributes have a null namespace.
+ // If that ever changes we'll need to fix that code.
if (elementData()->m_styleAttributeIsDirty) {
ASSERT(isStyledElement());
synchronizeStyleAttributeInternal();
@@ -435,6 +389,8 @@ inline void Element::synchronizeAttribute(const QualifiedName& name) const
}
if (UNLIKELY(elementData()->m_animatedSVGAttributesAreDirty)) {
ASSERT(isSVGElement());
+ // See comment in the AtomicString version of synchronizeAttribute()
+ // also.
toSVGElement(this)->synchronizeAnimatedSVGAttribute(name);
}
}
@@ -452,6 +408,16 @@ void Element::synchronizeAttribute(const AtomicString& localName) const
}
if (elementData()->m_animatedSVGAttributesAreDirty) {
// We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well.
+
+ // FIXME: this code is called regardless of whether name is an
+ // animated SVG Attribute. It would seem we should only call this method
+ // if SVGElement::isAnimatableAttribute is true, but the list of
+ // animatable attributes in isAnimatableAttribute does not suffice to
+ // pass all layout tests. Also, m_animatedSVGAttributesAreDirty stays
+ // dirty unless synchronizeAnimatedSVGAttribute is called with
+ // anyQName(). This means that even if Element::synchronizeAttribute()
+ // is called on all attributes, m_animatedSVGAttributesAreDirty remains
+ // true.
toSVGElement(this)->synchronizeAnimatedSVGAttribute(QualifiedName(nullAtom, localName, nullAtom));
}
}
@@ -461,11 +427,16 @@ const AtomicString& Element::getAttribute(const QualifiedName& name) const
if (!elementData())
return nullAtom;
synchronizeAttribute(name);
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = findAttributeByName(name))
return attribute->value();
return nullAtom;
}
+bool Element::shouldIgnoreAttributeCase() const
+{
+ return isHTMLElement() && document().isHTMLDocument();
+}
+
void Element::scrollIntoView(bool alignToTop)
{
document().updateLayoutIgnorePendingStylesheets();
@@ -546,40 +517,33 @@ static float localZoomForRenderer(RenderObject& renderer)
return zoomFactor;
}
-static int adjustForLocalZoom(LayoutUnit value, RenderObject& renderer)
+static double adjustForLocalZoom(LayoutUnit value, RenderObject& renderer)
{
float zoomFactor = localZoomForRenderer(renderer);
if (zoomFactor == 1)
- return value;
- return lroundf(value / zoomFactor);
+ return value.toDouble();
+ return value.toDouble() / zoomFactor;
}
int Element::offsetLeft()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
- return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), *renderer);
+ return lroundf(adjustForLocalZoom(renderer->offsetLeft(), *renderer));
return 0;
}
int Element::offsetTop()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
- return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), *renderer);
+ return lroundf(adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), *renderer));
return 0;
}
int Element::offsetWidth()
{
- document().updateStyleForNodeIfNeeded(this);
-
- if (RenderBox* renderer = renderBox()) {
- if (renderer->canDetermineWidthWithoutLayout())
- return adjustLayoutUnitForAbsoluteZoom(renderer->fixedOffsetWidth(), *renderer).round();
- }
-
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), *renderer).round();
return 0;
@@ -587,13 +551,13 @@ int Element::offsetWidth()
int Element::offsetHeight()
{
- document().partialUpdateLayoutIgnorePendingStylesheets(this);
+ document().updateLayoutIgnorePendingStylesheets();
if (RenderBoxModelObject* renderer = renderBoxModelObject())
return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), *renderer).round();
return 0;
}
-Element* Element::bindingsOffsetParent()
+Element* Element::offsetParentForBindings()
{
Element* element = offsetParent();
if (!element || !element->isInShadowTree())
@@ -614,7 +578,7 @@ int Element::clientLeft()
document().updateLayoutIgnorePendingStylesheets();
if (RenderBox* renderer = renderBox())
- return adjustForAbsoluteZoom(roundToInt(renderer->clientLeft()), renderer);
+ return adjustLayoutUnitForAbsoluteZoom(roundToInt(renderer->clientLeft()), *renderer);
return 0;
}
@@ -623,7 +587,7 @@ int Element::clientTop()
document().updateLayoutIgnorePendingStylesheets();
if (RenderBox* renderer = renderBox())
- return adjustForAbsoluteZoom(roundToInt(renderer->clientTop()), renderer);
+ return adjustLayoutUnitForAbsoluteZoom(roundToInt(renderer->clientTop()), *renderer);
return 0;
}
@@ -638,7 +602,7 @@ int Element::clientWidth()
|| (inQuirksMode && isHTMLElement() && document().body() == this)) {
if (FrameView* view = document().view()) {
if (RenderView* renderView = document().renderView())
- return adjustForAbsoluteZoom(view->layoutSize().width(), renderView);
+ return adjustLayoutUnitForAbsoluteZoom(view->layoutSize().width(), *renderView);
}
}
@@ -659,7 +623,7 @@ int Element::clientHeight()
|| (inQuirksMode && isHTMLElement() && document().body() == this)) {
if (FrameView* view = document().view()) {
if (RenderView* renderView = document().renderView())
- return adjustForAbsoluteZoom(view->layoutSize().height(), renderView);
+ return adjustLayoutUnitForAbsoluteZoom(view->layoutSize().height(), *renderView);
}
}
@@ -674,7 +638,7 @@ int Element::scrollLeft()
if (document().documentElement() != this) {
if (RenderBox* rend = renderBox())
- return adjustForAbsoluteZoom(rend->scrollLeft(), rend);
+ return adjustDoubleForAbsoluteZoom(rend->scrollLeft(), *rend);
return 0;
}
@@ -684,7 +648,7 @@ int Element::scrollLeft()
if (FrameView* view = document().view()) {
if (RenderView* renderView = document().renderView())
- return adjustForAbsoluteZoom(view->scrollX(), renderView);
+ return adjustDoubleForAbsoluteZoom(view->scrollX(), *renderView);
}
}
@@ -697,7 +661,7 @@ int Element::scrollTop()
if (document().documentElement() != this) {
if (RenderBox* rend = renderBox())
- return adjustForAbsoluteZoom(rend->scrollTop(), rend);
+ return adjustLayoutUnitForAbsoluteZoom(rend->scrollTop(), *rend);
return 0;
}
@@ -707,7 +671,7 @@ int Element::scrollTop()
if (FrameView* view = document().view()) {
if (RenderView* renderView = document().renderView())
- return adjustForAbsoluteZoom(view->scrollY(), renderView);
+ return adjustDoubleForAbsoluteZoom(view->scrollY(), *renderView);
}
}
@@ -720,7 +684,7 @@ void Element::setScrollLeft(int newLeft)
if (document().documentElement() != this) {
if (RenderBox* rend = renderBox())
- rend->setScrollLeft(static_cast<int>(newLeft * rend->style()->effectiveZoom()));
+ rend->setScrollLeft(LayoutUnit::fromFloatRound(newLeft * rend->style()->effectiveZoom()));
return;
}
@@ -728,15 +692,36 @@ void Element::setScrollLeft(int newLeft)
if (document().inQuirksMode())
return;
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
FrameView* view = frame->view();
if (!view)
return;
- view->setScrollPosition(IntPoint(static_cast<int>(newLeft * frame->pageZoomFactor()), view->scrollY()));
+ view->setScrollPosition(IntPoint(roundf(newLeft * frame->pageZoomFactor()), view->scrollY()));
+ }
+}
+
+void Element::setScrollLeft(const Dictionary& scrollOptionsHorizontal, ExceptionState& exceptionState)
+{
+ String scrollBehaviorString;
+ ScrollBehavior scrollBehavior = ScrollBehaviorAuto;
+ if (scrollOptionsHorizontal.get("behavior", scrollBehaviorString)) {
+ if (!ScrollableArea::scrollBehaviorFromString(scrollBehaviorString, scrollBehavior)) {
+ exceptionState.throwTypeError("The ScrollBehavior provided is invalid.");
+ return;
+ }
+ }
+
+ int position;
+ if (!scrollOptionsHorizontal.get("x", position)) {
+ exceptionState.throwTypeError("ScrollOptionsHorizontal must include an 'x' member.");
+ return;
}
+
+ // FIXME: Use scrollBehavior to decide whether to scroll smoothly or instantly.
+ setScrollLeft(position);
}
void Element::setScrollTop(int newTop)
@@ -745,7 +730,7 @@ void Element::setScrollTop(int newTop)
if (document().documentElement() != this) {
if (RenderBox* rend = renderBox())
- rend->setScrollTop(static_cast<int>(newTop * rend->style()->effectiveZoom()));
+ rend->setScrollTop(LayoutUnit::fromFloatRound(newTop * rend->style()->effectiveZoom()));
return;
}
@@ -753,22 +738,43 @@ void Element::setScrollTop(int newTop)
if (document().inQuirksMode())
return;
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
FrameView* view = frame->view();
if (!view)
return;
- view->setScrollPosition(IntPoint(view->scrollX(), static_cast<int>(newTop * frame->pageZoomFactor())));
+ view->setScrollPosition(IntPoint(view->scrollX(), roundf(newTop * frame->pageZoomFactor())));
}
}
+void Element::setScrollTop(const Dictionary& scrollOptionsVertical, ExceptionState& exceptionState)
+{
+ String scrollBehaviorString;
+ ScrollBehavior scrollBehavior = ScrollBehaviorAuto;
+ if (scrollOptionsVertical.get("behavior", scrollBehaviorString)) {
+ if (!ScrollableArea::scrollBehaviorFromString(scrollBehaviorString, scrollBehavior)) {
+ exceptionState.throwTypeError("The ScrollBehavior provided is invalid.");
+ return;
+ }
+ }
+
+ int position;
+ if (!scrollOptionsVertical.get("y", position)) {
+ exceptionState.throwTypeError("ScrollOptionsVertical must include a 'y' member.");
+ return;
+ }
+
+ // FIXME: Use scrollBehavior to decide whether to scroll smoothly or instantly.
+ setScrollTop(position);
+}
+
int Element::scrollWidth()
{
document().updateLayoutIgnorePendingStylesheets();
if (RenderBox* rend = renderBox())
- return adjustForAbsoluteZoom(rend->scrollWidth(), rend);
+ return adjustLayoutUnitForAbsoluteZoom(rend->scrollWidth(), *rend).toDouble();
return 0;
}
@@ -776,7 +782,7 @@ int Element::scrollHeight()
{
document().updateLayoutIgnorePendingStylesheets();
if (RenderBox* rend = renderBox())
- return adjustForAbsoluteZoom(rend->scrollHeight(), rend);
+ return adjustLayoutUnitForAbsoluteZoom(rend->scrollHeight(), *rend).toDouble();
return 0;
}
@@ -812,7 +818,7 @@ IntRect Element::boundsInRootViewSpace()
return result;
}
-PassRefPtr<ClientRectList> Element::getClientRects()
+PassRefPtrWillBeRawPtr<ClientRectList> Element::getClientRects()
{
document().updateLayoutIgnorePendingStylesheets();
@@ -829,7 +835,7 @@ PassRefPtr<ClientRectList> Element::getClientRects()
return ClientRectList::create(quads);
}
-PassRefPtr<ClientRect> Element::getBoundingClientRect()
+PassRefPtrWillBeRawPtr<ClientRect> Element::getBoundingClientRect()
{
document().updateLayoutIgnorePendingStylesheets();
@@ -871,7 +877,7 @@ const AtomicString& Element::getAttribute(const AtomicString& localName) const
if (!elementData())
return nullAtom;
synchronizeAttribute(localName);
- if (const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase()))
+ if (const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase()))
return attribute->value();
return nullAtom;
}
@@ -884,28 +890,28 @@ const AtomicString& Element::getAttributeNS(const AtomicString& namespaceURI, co
void Element::setAttribute(const AtomicString& localName, const AtomicString& value, ExceptionState& exceptionState)
{
if (!Document::isValidName(localName)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidCharacterError);
+ exceptionState.throwDOMException(InvalidCharacterError, "'" + localName + "' is not a valid attribute name.");
return;
}
synchronizeAttribute(localName);
const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase() ? localName.lower() : localName;
- size_t index = elementData() ? elementData()->getAttributeItemIndex(caseAdjustedLocalName, false) : kNotFound;
- const QualifiedName& qName = index != kNotFound ? attributeItem(index)->name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
+ size_t index = elementData() ? elementData()->findAttributeIndexByName(caseAdjustedLocalName, false) : kNotFound;
+ const QualifiedName& qName = index != kNotFound ? attributeAt(index).name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
}
void Element::setAttribute(const QualifiedName& name, const AtomicString& value)
{
synchronizeAttribute(name);
- size_t index = elementData() ? elementData()->getAttributeItemIndex(name) : kNotFound;
+ size_t index = elementData() ? elementData()->findAttributeIndexByName(name) : kNotFound;
setAttributeInternal(index, name, value, NotInSynchronizationOfLazyAttribute);
}
void Element::setSynchronizedLazyAttribute(const QualifiedName& name, const AtomicString& value)
{
- size_t index = elementData() ? elementData()->getAttributeItemIndex(name) : kNotFound;
+ size_t index = elementData() ? elementData()->findAttributeIndexByName(name) : kNotFound;
setAttributeInternal(index, name, value, InSynchronizationOfLazyAttribute);
}
@@ -918,24 +924,24 @@ ALWAYS_INLINE void Element::setAttributeInternal(size_t index, const QualifiedNa
}
if (index == kNotFound) {
- addAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
+ appendAttributeInternal(name, newValue, inSynchronizationOfLazyAttribute);
return;
}
- const Attribute* existingAttribute = attributeItem(index);
- QualifiedName existingAttributeName = existingAttribute->name();
+ const Attribute& existingAttribute = attributeAt(index);
+ QualifiedName existingAttributeName = existingAttribute.name();
if (!inSynchronizationOfLazyAttribute)
- willModifyAttribute(existingAttributeName, existingAttribute->value(), newValue);
+ willModifyAttribute(existingAttributeName, existingAttribute.value(), newValue);
- if (newValue != existingAttribute->value()) {
+ if (newValue != existingAttribute.value()) {
// If there is an Attr node hooked to this attribute, the Attr::setValue() call below
// will write into the ElementData.
// FIXME: Refactor this so it makes some sense.
- if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(existingAttributeName))
+ if (RefPtrWillBeRawPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? nullptr : attrIfExists(existingAttributeName))
attrNode->setValue(newValue);
else
- ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
+ ensureUniqueElementData().attributeAt(index).setValue(newValue);
}
if (!inSynchronizationOfLazyAttribute)
@@ -949,16 +955,6 @@ static inline AtomicString makeIdForStyleResolution(const AtomicString& value, b
return value;
}
-static bool checkNeedsStyleInvalidationForIdChange(const AtomicString& oldId, const AtomicString& newId, const RuleFeatureSet& features)
-{
- ASSERT(newId != oldId);
- if (!oldId.isEmpty() && features.hasSelectorForId(oldId))
- return true;
- if (!newId.isEmpty() && features.hasSelectorForId(newId))
- return true;
- return false;
-}
-
void Element::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
{
if (ElementShadow* parentElementShadow = shadowWhereNodeCanBeDistributed(*this)) {
@@ -972,7 +968,6 @@ void Element::attributeChanged(const QualifiedName& name, const AtomicString& ne
StyleResolver* styleResolver = document().styleResolver();
bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
- bool shouldInvalidateStyle = false;
if (isStyledElement() && name == styleAttr) {
styleAttributeChanged(newValue, reason);
@@ -986,28 +981,35 @@ void Element::attributeChanged(const QualifiedName& name, const AtomicString& ne
AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
if (newId != oldId) {
elementData()->setIdForStyleResolution(newId);
- shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver->ensureRuleFeatureSet());
+ if (testShouldInvalidateStyle)
+ styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForIdChange(oldId, newId, *this);
}
} else if (name == classAttr) {
classAttributeChanged(newValue);
} else if (name == HTMLNames::nameAttr) {
setHasName(!newValue.isNull());
- } else if (name == HTMLNames::pseudoAttr) {
- shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
}
invalidateNodeListCachesInAncestors(&name, this);
// If there is currently no StyleResolver, we can't be sure that this attribute change won't affect style.
- shouldInvalidateStyle |= !styleResolver;
-
- if (shouldInvalidateStyle)
- setNeedsStyleRecalc();
+ if (!styleResolver)
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (AXObjectCache* cache = document().existingAXObjectCache())
cache->handleAttributeChanged(name, this);
}
+bool Element::hasLegalLinkAttribute(const QualifiedName&) const
+{
+ return false;
+}
+
+const QualifiedName& Element::subResourceAttributeName() const
+{
+ return QualifiedName::null();
+}
+
inline void Element::attributeChangedFromParserOrByCloning(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason reason)
{
if (name == isAttr)
@@ -1042,77 +1044,28 @@ static inline bool classStringHasClassName(const AtomicString& newClassString)
return classStringHasClassName(newClassString.characters16(), length);
}
-template<typename Checker>
-static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker)
-{
- unsigned changedSize = changedClasses.size();
- for (unsigned i = 0; i < changedSize; ++i) {
- if (checker.hasSelectorForClass(changedClasses[i]))
- return true;
- }
- return false;
-}
-
-template<typename Checker>
-static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const Checker& checker)
-{
- if (!oldClasses.size())
- return checkSelectorForClassChange(newClasses, checker);
-
- // Class vectors tend to be very short. This is faster than using a hash table.
- BitVector remainingClassBits;
- remainingClassBits.ensureSize(oldClasses.size());
-
- for (unsigned i = 0; i < newClasses.size(); ++i) {
- bool found = false;
- for (unsigned j = 0; j < oldClasses.size(); ++j) {
- if (newClasses[i] == oldClasses[j]) {
- // Mark each class that is still in the newClasses so we can skip doing
- // an n^2 search below when looking for removals. We can't break from
- // this loop early since a class can appear more than once.
- remainingClassBits.quickSet(j);
- found = true;
- }
- }
- // Class was added.
- if (!found && checker.hasSelectorForClass(newClasses[i]))
- return true;
- }
-
- for (unsigned i = 0; i < oldClasses.size(); ++i) {
- if (remainingClassBits.quickGet(i))
- continue;
- // Class was removed.
- if (checker.hasSelectorForClass(oldClasses[i]))
- return true;
- }
-
- return false;
-}
-
void Element::classAttributeChanged(const AtomicString& newClassString)
{
StyleResolver* styleResolver = document().styleResolver();
bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
- bool shouldInvalidateStyle = false;
+ ASSERT(elementData());
if (classStringHasClassName(newClassString)) {
const bool shouldFoldCase = document().inQuirksMode();
const SpaceSplitString oldClasses = elementData()->classNames();
elementData()->setClass(newClassString, shouldFoldCase);
const SpaceSplitString& newClasses = elementData()->classNames();
- shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, styleResolver->ensureRuleFeatureSet());
+ if (testShouldInvalidateStyle)
+ styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, newClasses, *this);
} else {
const SpaceSplitString& oldClasses = elementData()->classNames();
- shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, styleResolver->ensureRuleFeatureSet());
+ if (testShouldInvalidateStyle)
+ styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, *this);
elementData()->clearClass();
}
if (hasRareData())
elementRareData()->clearClassListValueForQuirksMode();
-
- if (shouldInvalidateStyle)
- setNeedsStyleRecalc();
}
bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* elementShadow, const QualifiedName& name, const AtomicString& newValue)
@@ -1137,11 +1090,11 @@ bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* el
const bool shouldFoldCase = document().inQuirksMode();
const SpaceSplitString& oldClasses = elementData()->classNames();
const SpaceSplitString newClasses(newClassString, shouldFoldCase);
- if (checkSelectorForClassChange(oldClasses, newClasses, featureSet))
+ if (featureSet.checkSelectorsForClassChange(oldClasses, newClasses))
return true;
} else {
const SpaceSplitString& oldClasses = elementData()->classNames();
- if (checkSelectorForClassChange(oldClasses, featureSet))
+ if (featureSet.checkSelectorsForClassChange(oldClasses))
return true;
}
}
@@ -1190,8 +1143,8 @@ void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
if (attributeVector.isEmpty())
return;
- if (document().sharedObjectPool())
- m_elementData = document().sharedObjectPool()->cachedShareableElementDataWithAttributes(attributeVector);
+ if (document().elementDataCache())
+ m_elementData = document().elementDataCache()->cachedShareableElementDataWithAttributes(attributeVector);
else
m_elementData = ShareableElementData::createWithAttributes(attributeVector);
@@ -1203,7 +1156,7 @@ void Element::parserSetAttributes(const Vector<Attribute>& attributeVector)
bool Element::hasAttributes() const
{
synchronizeAllAttributes();
- return elementData() && elementData()->length();
+ return elementData() && elementData()->hasAttributes();
}
bool Element::hasEquivalentAttributes(const Element* other) const
@@ -1224,23 +1177,57 @@ String Element::nodeName() const
return m_tagName.toString();
}
-String Element::nodeNamePreservingCase() const
-{
- return m_tagName.toString();
-}
-
void Element::setPrefix(const AtomicString& prefix, ExceptionState& exceptionState)
{
- checkSetPrefix(prefix, exceptionState);
+ UseCounter::countDeprecation(document(), UseCounter::ElementSetPrefix);
+
+ if (!prefix.isEmpty() && !Document::isValidName(prefix)) {
+ exceptionState.throwDOMException(InvalidCharacterError, "The prefix '" + prefix + "' is not a valid name.");
+ return;
+ }
+
+ // FIXME: Raise NamespaceError if prefix is malformed per the Namespaces in XML specification.
+
+ const AtomicString& nodeNamespaceURI = namespaceURI();
+ if (nodeNamespaceURI.isEmpty() && !prefix.isEmpty()) {
+ exceptionState.throwDOMException(NamespaceError, "No namespace is set, so a namespace prefix may not be set.");
+ return;
+ }
+
+ if (prefix == xmlAtom && nodeNamespaceURI != XMLNames::xmlNamespaceURI) {
+ exceptionState.throwDOMException(NamespaceError, "The prefix '" + xmlAtom + "' may not be set on namespace '" + nodeNamespaceURI + "'.");
+ return;
+ }
+
if (exceptionState.hadException())
return;
m_tagName.setPrefix(prefix.isEmpty() ? AtomicString() : prefix);
}
+const AtomicString& Element::locateNamespacePrefix(const AtomicString& namespaceToLocate) const
+{
+ if (!prefix().isNull() && namespaceURI() == namespaceToLocate)
+ return prefix();
+
+ if (hasAttributes()) {
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->prefix() == xmlnsAtom && it->value() == namespaceToLocate)
+ return it->localName();
+ }
+ }
+
+ if (Element* parent = parentElement())
+ return parent->locateNamespacePrefix(namespaceToLocate);
+
+ return nullAtom;
+}
+
KURL Element::baseURI() const
{
- const AtomicString& baseAttribute = getAttribute(baseAttr);
+ const AtomicString& baseAttribute = fastGetAttribute(baseAttr);
KURL base(KURL(), baseAttribute);
if (!base.protocol().isEmpty())
return base;
@@ -1303,7 +1290,7 @@ Node::InsertionNotificationRequest Element::insertedInto(ContainerNode* insertio
if (!nameValue.isNull())
updateName(nullAtom, nameValue);
- if (hasTagName(labelTag)) {
+ if (isHTMLLabelElement(*this)) {
if (scope.shouldCacheLabelsByForAttribute())
updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
}
@@ -1337,7 +1324,7 @@ void Element::removedFrom(ContainerNode* insertionPoint)
if (!nameValue.isNull())
updateName(nameValue, nullAtom);
- if (hasTagName(labelTag)) {
+ if (isHTMLLabelElement(*this)) {
TreeScope& treeScope = insertionPoint->treeScope();
if (treeScope.shouldCacheLabelsByForAttribute())
updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
@@ -1347,7 +1334,7 @@ void Element::removedFrom(ContainerNode* insertionPoint)
ContainerNode::removedFrom(insertionPoint);
if (wasInDocument) {
if (hasPendingResources())
- document().accessSVGExtensions()->removeElementFromPendingResources(this);
+ document().accessSVGExtensions().removeElementFromPendingResources(this);
if (isUpgradedCustomElement())
CustomElement::didLeaveDocument(this, insertionPoint->document());
@@ -1355,101 +1342,85 @@ void Element::removedFrom(ContainerNode* insertionPoint)
document().removeFromTopLayer(this);
+ clearElementFlag(IsInCanvasSubtree);
+
if (hasRareData())
- elementRareData()->setIsInCanvasSubtree(false);
+ elementRareData()->clearRestyleFlags();
}
void Element::attach(const AttachContext& context)
{
ASSERT(document().inStyleRecalc());
- StyleResolverParentPusher parentPusher(*this);
-
// We've already been through detach when doing an attach, but we might
// need to clear any state that's been added since then.
if (hasRareData() && styleChangeType() == NeedsReattachStyleChange) {
ElementRareData* data = elementRareData();
data->clearComputedStyle();
- data->resetDynamicRestyleObservations();
// Only clear the style state if we're not going to reuse the style from recalcStyle.
if (!context.resolvedStyle)
data->resetStyleState();
}
- NodeRenderingContext(this, context.resolvedStyle).createRendererForElementIfNeeded();
+ RenderTreeBuilder(this, context.resolvedStyle).createRendererForElementIfNeeded();
addCallbackSelectors();
+ StyleResolverParentScope parentScope(*this);
+
createPseudoElementIfNeeded(BEFORE);
// When a shadow root exists, it does the work of attaching the children.
- if (ElementShadow* shadow = this->shadow()) {
- parentPusher.push();
+ if (ElementShadow* shadow = this->shadow())
shadow->attach(context);
- } else if (firstChild()) {
- parentPusher.push();
- }
ContainerNode::attach(context);
createPseudoElementIfNeeded(AFTER);
createPseudoElementIfNeeded(BACKDROP);
- if (hasRareData()) {
- ElementRareData* data = elementRareData();
- if (data->needsFocusAppearanceUpdateSoonAfterAttach()) {
- if (isFocusable() && document().focusedElement() == this)
- document().updateFocusAppearanceSoon(false /* don't restore selection */);
- data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
- }
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled() && !renderer()) {
- if (ActiveAnimations* activeAnimations = data->activeAnimations())
- activeAnimations->cssAnimations().cancel();
+ if (hasRareData() && !renderer()) {
+ if (ActiveAnimations* activeAnimations = elementRareData()->activeAnimations()) {
+ activeAnimations->cssAnimations().cancel();
+ activeAnimations->setAnimationStyleChange(false);
}
}
-
- InspectorInstrumentation::didRecalculateStyleForElement(this);
-}
-
-void Element::unregisterNamedFlowContentNode()
-{
- if (RuntimeEnabledFeatures::cssRegionsEnabled() && inNamedFlow() && document().renderView())
- document().renderView()->flowThreadController()->unregisterNamedFlowContentNode(this);
}
void Element::detach(const AttachContext& context)
{
- RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
- unregisterNamedFlowContentNode();
+ HTMLFrameOwnerElement::UpdateSuspendScope suspendWidgetHierarchyUpdates;
cancelFocusAppearanceUpdate();
removeCallbackSelectors();
+ if (svgFilterNeedsLayerUpdate())
+ document().unscheduleSVGFilterLayerUpdateHack(*this);
if (hasRareData()) {
ElementRareData* data = elementRareData();
- data->setPseudoElement(BEFORE, 0);
- data->setPseudoElement(AFTER, 0);
- data->setPseudoElement(BACKDROP, 0);
- data->setIsInsideRegion(false);
+ data->clearPseudoElements();
// attach() will perform the below steps for us when inside recalcStyle.
if (!document().inStyleRecalc()) {
data->resetStyleState();
data->clearComputedStyle();
- data->resetDynamicRestyleObservations();
}
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
- if (ActiveAnimations* activeAnimations = data->activeAnimations()) {
- if (context.performingReattach) {
- // FIXME: restart compositor animations rather than pull back to the main thread
- activeAnimations->cancelAnimationOnCompositor();
- } else {
- activeAnimations->cssAnimations().cancel();
- }
+ if (ActiveAnimations* activeAnimations = data->activeAnimations()) {
+ if (context.performingReattach) {
+ // FIXME: We call detach from within style recalc, so compositingState is not up to date.
+ // https://code.google.com/p/chromium/issues/detail?id=339847
+ DisableCompositingQueryAsserts disabler;
+
+ // FIXME: restart compositor animations rather than pull back to the main thread
+ activeAnimations->cancelAnimationOnCompositor();
+ } else {
+ activeAnimations->cssAnimations().cancel();
+ activeAnimations->setAnimationStyleChange(false);
}
}
+
+ if (ElementShadow* shadow = data->shadow())
+ shadow->detach(context);
}
- if (ElementShadow* shadow = this->shadow())
- shadow->detach(context);
ContainerNode::detach(context);
}
@@ -1483,7 +1454,7 @@ bool Element::pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderS
// FIXME: We should do an actual diff to determine whether a repaint vs. layout
// is needed, but for now just assume a layout will be required. The diff code
// in RenderObject::setStyle would need to be factored out so that it could be reused.
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
return true;
}
@@ -1506,12 +1477,15 @@ PassRefPtr<RenderStyle> Element::styleForRenderer()
style = customStyleForRenderer();
if (!style)
style = originalStyleForRenderer();
+ ASSERT(style);
// styleForElement() might add active animations so we need to get it again.
- if (ActiveAnimations* activeAnimations = this->activeAnimations())
+ if (ActiveAnimations* activeAnimations = this->activeAnimations()) {
activeAnimations->cssAnimations().maybeApplyPendingUpdate(this);
+ activeAnimations->updateAnimationFlags(*style);
+ }
- ASSERT(style);
+ document().didRecalculateStyleForElement();
return style.release();
}
@@ -1546,9 +1520,10 @@ void Element::recalcStyle(StyleRecalcChange change, Text* nextTextSibling)
}
// If we reattached we don't need to recalc the style of our descendants anymore.
- if ((change >= Inherit && change < Reattach) || childNeedsStyleRecalc())
+ if ((change >= UpdatePseudoElements && change < Reattach) || childNeedsStyleRecalc()) {
recalcChildStyle(change);
- clearChildNeedsStyleRecalc();
+ clearChildNeedsStyleRecalc();
+ }
if (hasCustomStyleCallbacks())
didRecalcStyle(change);
@@ -1566,27 +1541,28 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change)
RefPtr<RenderStyle> oldStyle = renderStyle();
RefPtr<RenderStyle> newStyle = styleForRenderer();
- StyleRecalcChange localChange = RenderStyle::compare(oldStyle.get(), newStyle.get());
+ StyleRecalcChange localChange = RenderStyle::stylePropagationDiff(oldStyle.get(), newStyle.get());
ASSERT(newStyle);
if (localChange == Reattach) {
AttachContext reattachContext;
reattachContext.resolvedStyle = newStyle.get();
+ bool rendererWillChange = needsAttach() || renderer();
reattach(reattachContext);
- return Reattach;
+ if (rendererWillChange || renderer())
+ return Reattach;
+ return ReattachNoRenderer;
}
ASSERT(oldStyle);
- InspectorInstrumentation::didRecalculateStyleForElement(this);
-
if (localChange != NoChange)
updateCallbackSelectors(oldStyle.get(), newStyle.get());
if (RenderObject* renderer = this->renderer()) {
- if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || shouldNotifyRendererWithIdenticalStyles()) {
- renderer->setAnimatableStyle(newStyle.get());
+ if (localChange != NoChange || pseudoStyleCacheIsInvalid(oldStyle.get(), newStyle.get()) || svgFilterNeedsLayerUpdate()) {
+ renderer->setStyle(newStyle.get());
} else {
// Although no change occurred, we use the new style so that the cousin style sharing code won't get
// fooled into believing this style is the same.
@@ -1596,98 +1572,63 @@ StyleRecalcChange Element::recalcOwnStyle(StyleRecalcChange change)
}
}
- // If "rem" units are used anywhere in the document, and if the document element's font size changes, then go ahead and force font updating
- // all the way down the tree. This is simpler than having to maintain a cache of objects (and such font size changes should be rare anyway).
- if (document().styleEngine()->usesRemUnits() && document().documentElement() == this && oldStyle->fontSize() != newStyle->fontSize()) {
- // Cached RenderStyles may depend on the re units.
- document().ensureStyleResolver().invalidateMatchedPropertiesCache();
- return Force;
- }
-
if (styleChangeType() >= SubtreeStyleChange)
return Force;
- return max(localChange, change);
+ if (change > Inherit || localChange > Inherit)
+ return max(localChange, change);
+
+ if (localChange < Inherit && (oldStyle->hasPseudoElementStyle() || newStyle->hasPseudoElementStyle()))
+ return UpdatePseudoElements;
+
+ return localChange;
}
void Element::recalcChildStyle(StyleRecalcChange change)
{
ASSERT(document().inStyleRecalc());
- ASSERT(change >= Inherit || childNeedsStyleRecalc());
+ ASSERT(change >= UpdatePseudoElements || childNeedsStyleRecalc());
ASSERT(!needsStyleRecalc());
- StyleResolverParentPusher parentPusher(*this);
+ StyleResolverParentScope parentScope(*this);
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
- if (shouldRecalcStyle(change, root)) {
- parentPusher.push();
- root->recalcStyle(change);
+ updatePseudoElement(BEFORE, change);
+
+ if (change > UpdatePseudoElements || childNeedsStyleRecalc()) {
+ for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
+ if (root->shouldCallRecalcStyle(change))
+ root->recalcStyle(change);
}
}
- if (shouldRecalcStyle(change, this))
- updatePseudoElement(BEFORE, change);
-
if (change < Force && hasRareData() && childNeedsStyleRecalc())
checkForChildrenAdjacentRuleChanges();
- // This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid
- // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last
- // child and work our way back means in the common case, we'll find the insertion point in O(1) time.
- // See crbug.com/288225
- StyleResolver& styleResolver = document().ensureStyleResolver();
- Text* lastTextNode = 0;
- for (Node* child = lastChild(); child; child = child->previousSibling()) {
- if (child->isTextNode()) {
- toText(child)->recalcTextStyle(change, lastTextNode);
- lastTextNode = toText(child);
- } else if (child->isElementNode()) {
- Element* element = toElement(child);
- if (shouldRecalcStyle(change, element)) {
- parentPusher.push();
- element->recalcStyle(change, lastTextNode);
- } else if (element->supportsStyleSharing()) {
- styleResolver.addToStyleSharingList(*element);
+ if (change > UpdatePseudoElements || childNeedsStyleRecalc()) {
+ // This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid
+ // a potentially n^2 loop to find the insertion point while resolving style. Having us start from the last
+ // child and work our way back means in the common case, we'll find the insertion point in O(1) time.
+ // See crbug.com/288225
+ StyleResolver& styleResolver = document().ensureStyleResolver();
+ Text* lastTextNode = 0;
+ for (Node* child = lastChild(); child; child = child->previousSibling()) {
+ if (child->isTextNode()) {
+ toText(child)->recalcTextStyle(change, lastTextNode);
+ lastTextNode = toText(child);
+ } else if (child->isElementNode()) {
+ Element* element = toElement(child);
+ if (element->shouldCallRecalcStyle(change))
+ element->recalcStyle(change, lastTextNode);
+ else if (element->supportsStyleSharing())
+ styleResolver.addToStyleSharingList(*element);
+ if (element->renderer())
+ lastTextNode = 0;
}
- if (element->renderer())
- lastTextNode = 0;
}
}
- if (shouldRecalcStyle(change, this)) {
- updatePseudoElement(AFTER, change);
- updatePseudoElement(BACKDROP, change);
- }
-}
-
-void Element::checkForChildrenAdjacentRuleChanges()
-{
- bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
- bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
-
- if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
- return;
-
- unsigned forceCheckOfNextElementCount = 0;
- bool forceCheckOfAnyElementSibling = false;
-
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->isElementNode())
- continue;
- Element* element = toElement(child);
- bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() >= SubtreeStyleChange;
-
- if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
- element->setNeedsStyleRecalc();
-
- if (forceCheckOfNextElementCount)
- forceCheckOfNextElementCount--;
-
- if (childRulesChanged && hasDirectAdjacentRules)
- forceCheckOfNextElementCount = document().styleEngine()->maxDirectAdjacentSelectors();
-
- forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
- }
+ updatePseudoElement(AFTER, change);
+ updatePseudoElement(BACKDROP, change);
}
void Element::updateCallbackSelectors(RenderStyle* oldStyle, RenderStyle* newStyle)
@@ -1723,42 +1664,70 @@ ElementShadow& Element::ensureShadow()
void Element::didAffectSelector(AffectedSelectorMask mask)
{
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (ElementShadow* elementShadow = shadowWhereNodeCanBeDistributed(*this))
elementShadow->didAffectSelector(mask);
}
void Element::setAnimationStyleChange(bool animationStyleChange)
{
+ if (animationStyleChange && document().inStyleRecalc())
+ return;
if (ActiveAnimations* activeAnimations = elementRareData()->activeAnimations())
activeAnimations->setAnimationStyleChange(animationStyleChange);
}
void Element::setNeedsAnimationStyleRecalc()
{
- bool recalcPending = styleChangeType() != NoStyleChange;
- setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
+ if (styleChangeType() != NoStyleChange)
+ return;
- if (!recalcPending)
- setAnimationStyleChange(true);
+ setNeedsStyleRecalc(LocalStyleChange);
+ setAnimationStyleChange(true);
+}
+
+void Element::setNeedsCompositingUpdate()
+{
+ if (!document().isActive())
+ return;
+ RenderBoxModelObject* renderer = renderBoxModelObject();
+ if (!renderer)
+ return;
+ if (!renderer->hasLayer())
+ return;
+ renderer->layer()->setNeedsCompositingInputsUpdate();
+ document().renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
}
-PassRefPtr<ShadowRoot> Element::createShadowRoot(ExceptionState& exceptionState)
+void Element::setCustomElementDefinition(PassRefPtr<CustomElementDefinition> definition)
+{
+ if (!hasRareData() && !definition)
+ return;
+ ASSERT(!customElementDefinition());
+ ensureElementRareData().setCustomElementDefinition(definition);
+}
+
+CustomElementDefinition* Element::customElementDefinition() const
+{
+ if (hasRareData())
+ return elementRareData()->customElementDefinition();
+ return 0;
+}
+
+PassRefPtrWillBeRawPtr<ShadowRoot> Element::createShadowRoot(ExceptionState& exceptionState)
{
if (alwaysCreateUserAgentShadowRoot())
ensureUserAgentShadowRoot();
- if (RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
- return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
-
- // Since some elements recreates shadow root dynamically, multiple shadow
- // subtrees won't work well in that element. Until they are fixed, we disable
- // adding author shadow root for them.
- if (!areAuthorShadowsAllowed()) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
- return 0;
+ // Some elements make assumptions about what kind of renderers they allow
+ // as children so we can't allow author shadows on them for now. An override
+ // flag is provided for testing how author shadows interact on these elements.
+ if (!areAuthorShadowsAllowed() && !RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled()) {
+ exceptionState.throwDOMException(HierarchyRequestError, "Author-created shadow roots are disabled for this element.");
+ return nullptr;
}
- return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
+
+ return PassRefPtrWillBeRawPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
}
ShadowRoot* Element::shadowRoot() const
@@ -1772,10 +1741,6 @@ ShadowRoot* Element::shadowRoot() const
return 0;
}
-void Element::didAddShadowRoot(ShadowRoot&)
-{
-}
-
ShadowRoot* Element::userAgentShadowRoot() const
{
if (ElementShadow* elementShadow = shadow()) {
@@ -1812,117 +1777,34 @@ bool Element::childTypeAllowed(NodeType type) const
return false;
}
-void Element::checkForEmptyStyleChange(RenderStyle* style)
+void Element::checkForEmptyStyleChange()
{
- if (!style && !styleAffectedByEmpty())
- return;
-
- if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildNodes())))
- setNeedsStyleRecalc();
-}
-
-void Element::checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta)
-{
- if (!inActiveDocument() || document().hasPendingForcedStyleRecalc() || styleChangeType() >= SubtreeStyleChange)
- return;
-
RenderStyle* style = renderStyle();
- // :empty selector.
- checkForEmptyStyleChange(style);
-
- if (!style || (needsStyleRecalc() && childrenAffectedByPositionalRules()))
- return;
-
- // Forward positional selectors include the ~ selector, nth-child, nth-of-type, first-of-type and only-of-type.
- // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
- // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
- // backward case.
- // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to.
- // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids
- // here. recalcStyle will then force a walk of the children when it sees that this has happened.
- if ((childrenAffectedByForwardPositionalRules() && afterChange) || (childrenAffectedByBackwardPositionalRules() && beforeChange)) {
- setNeedsStyleRecalc();
+ if (!style && !styleAffectedByEmpty())
return;
- }
-
- // :first-child. In the parser callback case, we don't have to check anything, since we were right the first time.
- // In the DOM case, we only need to do something if |afterChange| is not 0.
- // |afterChange| is 0 in the parser case, so it works out that we'll skip this block.
- if (childrenAffectedByFirstChildRules() && afterChange) {
- // Find our new first child.
- Node* newFirstChild = firstElementChild();
- RenderStyle* newFirstChildStyle = newFirstChild ? newFirstChild->renderStyle() : 0;
-
- // Find the first element node following |afterChange|
- Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : afterChange->nextElementSibling();
- RenderStyle* firstElementAfterInsertionStyle = firstElementAfterInsertion ? firstElementAfterInsertion->renderStyle() : 0;
-
- // This is the insert/append case.
- if (newFirstChild != firstElementAfterInsertion && firstElementAfterInsertionStyle && firstElementAfterInsertionStyle->firstChildState())
- firstElementAfterInsertion->setNeedsStyleRecalc();
-
- // We also have to handle node removal.
- if (childCountDelta < 0 && newFirstChild == firstElementAfterInsertion && newFirstChild && (!newFirstChildStyle || !newFirstChildStyle->firstChildState()))
- newFirstChild->setNeedsStyleRecalc();
- }
-
- // :last-child. In the parser callback case, we don't have to check anything, since we were right the first time.
- // In the DOM case, we only need to do something if |afterChange| is not 0.
- if (childrenAffectedByLastChildRules() && beforeChange) {
- // Find our new last child.
- Node* newLastChild = lastElementChild();
- RenderStyle* newLastChildStyle = newLastChild ? newLastChild->renderStyle() : 0;
- // Find the last element node going backwards from |beforeChange|
- Node* lastElementBeforeInsertion = beforeChange->isElementNode() ? beforeChange : beforeChange->previousElementSibling();
- RenderStyle* lastElementBeforeInsertionStyle = lastElementBeforeInsertion ? lastElementBeforeInsertion->renderStyle() : 0;
-
- if (newLastChild != lastElementBeforeInsertion && lastElementBeforeInsertionStyle && lastElementBeforeInsertionStyle->lastChildState())
- lastElementBeforeInsertion->setNeedsStyleRecalc();
-
- // We also have to handle node removal. The parser callback case is similar to node removal as well in that we need to change the last child
- // to match now.
- if ((childCountDelta < 0 || finishedParsingCallback) && newLastChild == lastElementBeforeInsertion && newLastChild && (!newLastChildStyle || !newLastChildStyle->lastChildState()))
- newLastChild->setNeedsStyleRecalc();
- }
-
- // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element
- // that could be affected by this DOM change.
- if (childrenAffectedByDirectAdjacentRules() && afterChange) {
- if (Node* firstElementAfterInsertion = afterChange->isElementNode() ? afterChange : afterChange->nextElementSibling())
- firstElementAfterInsertion->setNeedsStyleRecalc();
- }
+ if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildren())))
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
void Element::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (changedByParser)
- checkForEmptyStyleChange(renderStyle());
- else
+
+ checkForEmptyStyleChange();
+ if (!changedByParser)
checkForSiblingStyleChanges(false, beforeChange, afterChange, childCountDelta);
if (ElementShadow* shadow = this->shadow())
shadow->setNeedsDistributionRecalc();
}
-void Element::removeAllEventListeners()
-{
- ContainerNode::removeAllEventListeners();
- if (ElementShadow* shadow = this->shadow())
- shadow->removeAllEventListeners();
-}
-
-void Element::beginParsingChildren()
-{
- clearIsParsingChildrenFinished();
-}
-
void Element::finishParsingChildren()
{
- setIsParsingChildrenFinished();
- checkForSiblingStyleChanges(this, lastChild(), 0, 0);
+ setIsFinishedParsingChildren(true);
+ checkForEmptyStyleChange();
+ checkForSiblingStyleChanges(true, lastChild(), 0, 0);
}
#ifndef NDEBUG
@@ -1953,81 +1835,127 @@ void Element::formatForDebugger(char* buffer, unsigned length) const
}
#endif
-const Vector<RefPtr<Attr> >& Element::attrNodeList()
+WillBeHeapVector<RefPtrWillBeMember<Attr> >* Element::attrNodeList()
+{
+ return hasRareData() ? elementRareData()->attrNodeList() : 0;
+}
+
+WillBeHeapVector<RefPtrWillBeMember<Attr> >& Element::ensureAttrNodeList()
+{
+ setHasSyntheticAttrChildNodes(true);
+ return ensureElementRareData().ensureAttrNodeList();
+}
+
+void Element::removeAttrNodeList()
{
ASSERT(hasSyntheticAttrChildNodes());
- return *attrNodeListForElement(this);
+ if (hasRareData())
+ elementRareData()->removeAttrNodeList();
+ setHasSyntheticAttrChildNodes(false);
}
-PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionState& exceptionState)
{
if (!attrNode) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Attr"));
+ return nullptr;
}
- RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
+ RefPtrWillBeRawPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
if (oldAttrNode.get() == attrNode)
return attrNode; // This Attr is already attached to the element.
// InUseAttributeError: Raised if node is an Attr that is already an attribute of another Element object.
// The DOM user must explicitly clone Attr nodes to re-use them in other elements.
if (attrNode->ownerElement()) {
- exceptionState.throwUninformativeAndGenericDOMException(InUseAttributeError);
- return 0;
+ exceptionState.throwDOMException(InUseAttributeError, "The node provided is an attribute node that is already an attribute of another Element; attribute nodes must be explicitly cloned.");
+ return nullptr;
}
synchronizeAllAttributes();
- UniqueElementData* elementData = ensureUniqueElementData();
+ UniqueElementData& elementData = ensureUniqueElementData();
- size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
+ size_t index = elementData.findAttributeIndexByName(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
+ AtomicString localName;
if (index != kNotFound) {
- if (oldAttrNode)
- detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->attributeItem(index)->value());
- else
- oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData->attributeItem(index)->value());
+ const Attribute& attr = elementData.attributeAt(index);
+
+ // If the name of the ElementData attribute doesn't
+ // (case-sensitively) match that of the Attr node, record it
+ // on the Attr so that it can correctly resolve the value on
+ // the Element.
+ if (!attr.name().matches(attrNode->qualifiedName()))
+ localName = attr.localName();
+
+ if (oldAttrNode) {
+ detachAttrNodeFromElementWithValue(oldAttrNode.get(), attr.value());
+ } else {
+ // FIXME: using attrNode's name rather than the
+ // Attribute's for the replaced Attr is compatible with
+ // all but Gecko (and, arguably, the DOM Level1 spec text.)
+ // Consider switching.
+ oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), attr.value());
+ }
}
setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
- attrNode->attachToElement(this);
+ attrNode->attachToElement(this, localName);
treeScope().adoptIfNeeded(*attrNode);
- ensureAttrNodeListForElement(this).append(attrNode);
+ ensureAttrNodeList().append(attrNode);
return oldAttrNode.release();
}
-PassRefPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Attr> Element::setAttributeNodeNS(Attr* attr, ExceptionState& exceptionState)
{
return setAttributeNode(attr, exceptionState);
}
-PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionState& exceptionState)
{
if (!attr) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Attr"));
+ return nullptr;
}
if (attr->ownerElement() != this) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "The node provided is owned by another element.");
+ return nullptr;
}
ASSERT(document() == attr->document());
synchronizeAttribute(attr->qualifiedName());
- size_t index = elementData()->getAttrIndex(attr);
+ size_t index = elementData()->findAttrNodeIndex(attr);
if (index == kNotFound) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "The attribute was not found on this element.");
+ return nullptr;
}
- RefPtr<Attr> guard(attr);
+ RefPtrWillBeRawPtr<Attr> guard(attr);
detachAttrNodeAtIndex(attr, index);
return guard.release();
}
+void Element::parseAttribute(const QualifiedName& name, const AtomicString& value)
+{
+ if (name == tabindexAttr) {
+ int tabindex = 0;
+ if (value.isEmpty()) {
+ clearTabIndexExplicitlyIfNeeded();
+ if (treeScope().adjustedFocusedElement() == this) {
+ // We might want to call blur(), but it's dangerous to dispatch
+ // events here.
+ document().setNeedsFocusedElementCheck();
+ }
+ } else if (parseHTMLInteger(value, tabindex)) {
+ // Clamp tabindex to the range of 'short' to match Firefox's behavior.
+ setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), std::min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
+ }
+ }
+}
+
bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespaceURI, const AtomicString& qualifiedName, ExceptionState& exceptionState)
{
AtomicString prefix, localName;
@@ -2038,7 +1966,7 @@ bool Element::parseAttributeName(QualifiedName& out, const AtomicString& namespa
QualifiedName qName(prefix, localName, namespaceURI);
if (!Document::hasValidNamespaceForAttributes(qName)) {
- exceptionState.throwUninformativeAndGenericDOMException(NamespaceError);
+ exceptionState.throwDOMException(NamespaceError, "'" + namespaceURI + "' is an invalid namespace for attributes.");
return false;
}
@@ -2058,30 +1986,30 @@ void Element::removeAttributeInternal(size_t index, SynchronizationOfLazyAttribu
{
ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
- UniqueElementData* elementData = ensureUniqueElementData();
+ UniqueElementData& elementData = ensureUniqueElementData();
- QualifiedName name = elementData->attributeItem(index)->name();
- AtomicString valueBeingRemoved = elementData->attributeItem(index)->value();
+ QualifiedName name = elementData.attributeAt(index).name();
+ AtomicString valueBeingRemoved = elementData.attributeAt(index).value();
if (!inSynchronizationOfLazyAttribute) {
if (!valueBeingRemoved.isNull())
willModifyAttribute(name, valueBeingRemoved, nullAtom);
}
- if (RefPtr<Attr> attrNode = attrIfExists(name))
- detachAttrNodeFromElementWithValue(attrNode.get(), elementData->attributeItem(index)->value());
+ if (RefPtrWillBeRawPtr<Attr> attrNode = attrIfExists(name))
+ detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeAt(index).value());
- elementData->removeAttribute(index);
+ elementData.removeAttributeAt(index);
if (!inSynchronizationOfLazyAttribute)
didRemoveAttribute(name);
}
-void Element::addAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
+void Element::appendAttributeInternal(const QualifiedName& name, const AtomicString& value, SynchronizationOfLazyAttribute inSynchronizationOfLazyAttribute)
{
if (!inSynchronizationOfLazyAttribute)
willModifyAttribute(name, nullAtom, value);
- ensureUniqueElementData()->addAttribute(name, value);
+ ensureUniqueElementData().appendAttribute(name, value);
if (!inSynchronizationOfLazyAttribute)
didAddAttribute(name, value);
}
@@ -2092,7 +2020,7 @@ void Element::removeAttribute(const AtomicString& name)
return;
AtomicString localName = shouldIgnoreAttributeCase() ? name.lower() : name;
- size_t index = elementData()->getAttributeItemIndex(localName, false);
+ size_t index = elementData()->findAttributeIndexByName(localName, false);
if (index == kNotFound) {
if (UNLIKELY(localName == styleAttr) && elementData()->m_styleAttributeIsDirty && isStyledElement())
removeAllInlineStyleProperties();
@@ -2107,26 +2035,26 @@ void Element::removeAttributeNS(const AtomicString& namespaceURI, const AtomicSt
removeAttribute(QualifiedName(nullAtom, localName, namespaceURI));
}
-PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
+PassRefPtrWillBeRawPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
{
if (!elementData())
- return 0;
+ return nullptr;
synchronizeAttribute(localName);
- const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase());
+ const Attribute* attribute = elementData()->findAttributeByName(localName, shouldIgnoreAttributeCase());
if (!attribute)
- return 0;
+ return nullptr;
return ensureAttr(attribute->name());
}
-PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
+PassRefPtrWillBeRawPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
{
if (!elementData())
- return 0;
+ return nullptr;
QualifiedName qName(nullAtom, localName, namespaceURI);
synchronizeAttribute(qName);
- const Attribute* attribute = elementData()->getAttributeItem(qName);
+ const Attribute* attribute = elementData()->findAttributeByName(qName);
if (!attribute)
- return 0;
+ return nullptr;
return ensureAttr(attribute->name());
}
@@ -2135,7 +2063,7 @@ bool Element::hasAttribute(const AtomicString& localName) const
if (!elementData())
return false;
synchronizeAttribute(localName);
- return elementData()->getAttributeItem(shouldIgnoreAttributeCase() ? localName.lower() : localName, false);
+ return elementData()->findAttributeByName(shouldIgnoreAttributeCase() ? localName.lower() : localName, false);
}
bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName) const
@@ -2144,47 +2072,32 @@ bool Element::hasAttributeNS(const AtomicString& namespaceURI, const AtomicStrin
return false;
QualifiedName qName(nullAtom, localName, namespaceURI);
synchronizeAttribute(qName);
- return elementData()->getAttributeItem(qName);
+ return elementData()->findAttributeByName(qName);
}
-void Element::focus(bool restorePreviousSelection, FocusDirection direction)
+void Element::focus(bool restorePreviousSelection, FocusType type)
{
if (!inDocument())
return;
- Document& doc = document();
- if (doc.focusedElement() == this)
+ if (document().focusedElement() == this)
return;
- // If the stylesheets have already been loaded we can reliably check isFocusable.
- // If not, we continue and set the focused node on the focus controller below so
- // that it can be updated soon after attach.
- if (doc.haveStylesheetsLoaded()) {
- doc.updateLayoutIgnorePendingStylesheets();
- if (!isFocusable())
- return;
- }
+ if (!document().isActive())
+ return;
- if (!supportsFocus())
+ document().updateLayoutIgnorePendingStylesheets();
+ if (!isFocusable())
return;
- RefPtr<Node> protect;
- if (Page* page = doc.page()) {
- // Focus and change event handlers can cause us to lose our last ref.
- // If a focus event handler changes the focus to a different node it
- // does not make sense to continue and update appearence.
- protect = this;
- if (!page->focusController().setFocusedElement(this, doc.frame(), direction))
- return;
- }
+ RefPtrWillBeRawPtr<Node> protect(this);
+ if (!document().page()->focusController().setFocusedElement(this, document().frame(), type))
+ return;
// Setting the focused node above might have invalidated the layout due to scripts.
- doc.updateLayoutIgnorePendingStylesheets();
-
- if (!isFocusable()) {
- ensureElementRareData().setNeedsFocusAppearanceUpdateSoonAfterAttach(true);
+ document().updateLayoutIgnorePendingStylesheets();
+ if (!isFocusable())
return;
- }
cancelFocusAppearanceUpdate();
updateFocusAppearance(restorePreviousSelection);
@@ -2193,7 +2106,8 @@ void Element::focus(bool restorePreviousSelection, FocusDirection direction)
void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
{
if (isRootEditableElement()) {
- Frame* frame = document().frame();
+ // Taking the ownership since setSelection() may release the last reference to |frame|.
+ RefPtr<LocalFrame> frame(document().frame());
if (!frame)
return;
@@ -2203,7 +2117,9 @@ void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
// FIXME: We should restore the previous selection if there is one.
VisibleSelection newSelection = VisibleSelection(firstPositionInOrBeforeNode(this), DOWNSTREAM);
- frame->selection().setSelection(newSelection);
+ // Passing DoNotSetFocus as this function is called after FocusController::setFocusedElement()
+ // and we don't want to change the focus to a new Element.
+ frame->selection().setSelection(newSelection, FrameSelection::DoNotSetFocus);
frame->selection().revealSelection();
} else if (renderer() && !renderer()->isWidget())
renderer()->scrollRectToVisible(boundingBox());
@@ -2217,10 +2133,37 @@ void Element::blur()
if (doc.page())
doc.page()->focusController().setFocusedElement(0, doc.frame());
else
- doc.setFocusedElement(0);
+ doc.setFocusedElement(nullptr);
}
}
+bool Element::supportsFocus() const
+{
+ // FIXME: supportsFocus() can be called when layout is not up to date.
+ // Logic that deals with the renderer should be moved to rendererIsFocusable().
+ // But supportsFocus must return true when the element is editable, or else
+ // it won't be focusable. Furthermore, supportsFocus cannot just return true
+ // always or else tabIndex() will change for all HTML elements.
+ return hasElementFlag(TabIndexWasSetExplicitly) || (rendererIsEditable() && parentNode() && !parentNode()->rendererIsEditable())
+ || supportsSpatialNavigationFocus();
+}
+
+bool Element::supportsSpatialNavigationFocus() const
+{
+ // This function checks whether the element satisfies the extended criteria
+ // for the element to be focusable, introduced by spatial navigation feature,
+ // i.e. checks if click or keyboard event handler is specified.
+ // This is the way to make it possible to navigate to (focus) elements
+ // which web designer meant for being active (made them respond to click events).
+
+ if (!document().settings() || !document().settings()->spatialNavigationEnabled())
+ return false;
+ return hasEventListeners(EventTypeNames::click)
+ || hasEventListeners(EventTypeNames::keydown)
+ || hasEventListeners(EventTypeNames::keypress)
+ || hasEventListeners(EventTypeNames::keyup);
+}
+
bool Element::isFocusable() const
{
return inDocument() && supportsFocus() && !isInert() && rendererIsFocusable();
@@ -2236,15 +2179,15 @@ bool Element::isMouseFocusable() const
return isFocusable();
}
-void Element::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection)
+void Element::dispatchFocusEvent(Element* oldFocusedElement, FocusType)
{
- RefPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::focus, false, false, document().domWindow(), 0, oldFocusedElement);
+ RefPtrWillBeRawPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::focus, false, false, document().domWindow(), 0, oldFocusedElement);
EventDispatcher::dispatchEvent(this, FocusEventDispatchMediator::create(event.release()));
}
void Element::dispatchBlurEvent(Element* newFocusedElement)
{
- RefPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::blur, false, false, document().domWindow(), 0, newFocusedElement);
+ RefPtrWillBeRawPtr<FocusEvent> event = FocusEvent::create(EventTypeNames::blur, false, false, document().domWindow(), 0, newFocusedElement);
EventDispatcher::dispatchEvent(this, BlurEventDispatchMediator::create(event.release()));
}
@@ -2274,9 +2217,9 @@ String Element::outerHTML() const
void Element::setInnerHTML(const String& html, ExceptionState& exceptionState)
{
- if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", exceptionState)) {
+ if (RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", exceptionState)) {
ContainerNode* container = this;
- if (hasTagName(templateTag))
+ if (isHTMLTemplateElement(*this))
container = toHTMLTemplateElement(this)->content();
replaceChildrenWithFragment(container, fragment.release(), exceptionState);
}
@@ -2285,20 +2228,25 @@ void Element::setInnerHTML(const String& html, ExceptionState& exceptionState)
void Element::setOuterHTML(const String& html, ExceptionState& exceptionState)
{
Node* p = parentNode();
- if (!p || !p->isElementNode()) {
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
+ if (!p) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "This element has no parent node.");
+ return;
+ }
+ if (!p->isElementNode()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "This element's parent is of type '" + p->nodeName() + "', which is not an element node.");
return;
}
- RefPtr<Element> parent = toElement(p);
- RefPtr<Node> prev = previousSibling();
- RefPtr<Node> next = nextSibling();
- RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, "outerHTML", exceptionState);
+ RefPtrWillBeRawPtr<Element> parent = toElement(p);
+ RefPtrWillBeRawPtr<Node> prev = previousSibling();
+ RefPtrWillBeRawPtr<Node> next = nextSibling();
+
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, parent.get(), AllowScriptingContent, "outerHTML", exceptionState);
if (exceptionState.hadException())
return;
parent->replaceChild(fragment.release(), this, exceptionState);
- RefPtr<Node> node = next ? next->previousSibling() : 0;
+ RefPtrWillBeRawPtr<Node> node = next ? next->previousSibling() : 0;
if (!exceptionState.hadException() && node && node->isTextNode())
mergeWithNextTextNode(node.release(), exceptionState);
@@ -2357,13 +2305,30 @@ static Element* contextElementForInsertion(const String& where, Element* element
return 0;
}
+Element* Element::insertAdjacentElement(const String& where, Element* newChild, ExceptionState& exceptionState)
+{
+ if (!newChild) {
+ // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative.
+ exceptionState.throwTypeError("The node provided is null.");
+ return 0;
+ }
+
+ Node* returnValue = insertAdjacent(where, newChild, exceptionState);
+ return toElement(returnValue);
+}
+
+void Element::insertAdjacentText(const String& where, const String& text, ExceptionState& exceptionState)
+{
+ insertAdjacent(where, document().createTextNode(text).get(), exceptionState);
+}
+
void Element::insertAdjacentHTML(const String& where, const String& markup, ExceptionState& exceptionState)
{
- RefPtr<Element> contextElement = contextElementForInsertion(where, this, exceptionState);
+ RefPtrWillBeRawPtr<Element> contextElement = contextElementForInsertion(where, this, exceptionState);
if (!contextElement)
return;
- RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, contextElement.get(), AllowScriptingContent, "insertAdjacentHTML", exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, contextElement.get(), AllowScriptingContent, "insertAdjacentHTML", exceptionState);
if (!fragment)
return;
insertAdjacent(where, fragment.get(), exceptionState);
@@ -2430,15 +2395,19 @@ String Element::textFromChildren()
return content.toString();
}
-// pseudo is used via shadowPseudoId.
-const AtomicString& Element::pseudo() const
+const AtomicString& Element::shadowPseudoId() const
{
- return getAttribute(pseudoAttr);
+ if (ShadowRoot* root = containingShadowRoot()) {
+ if (root->type() == ShadowRoot::UserAgentShadowRoot)
+ return fastGetAttribute(pseudoAttr);
+ }
+ return nullAtom;
}
-void Element::setPseudo(const AtomicString& value)
+void Element::setShadowPseudoId(const AtomicString& id)
{
- setAttribute(pseudoAttr, value);
+ ASSERT(CSSSelector::parsePseudoType(id) == CSSSelector::PseudoWebKitCustomElement || CSSSelector::parsePseudoType(id) == CSSSelector::PseudoUserAgentCustomElement);
+ setAttribute(pseudoAttr, id);
}
bool Element::isInDescendantTreeOf(const Element* shadowHost) const
@@ -2495,178 +2464,6 @@ RenderStyle* Element::computedStyle(PseudoId pseudoElementSpecifier)
return pseudoElementSpecifier ? rareData.computedStyle()->getCachedPseudoStyle(pseudoElementSpecifier) : rareData.computedStyle();
}
-void Element::setStyleAffectedByEmpty()
-{
- ensureElementRareData().setStyleAffectedByEmpty(true);
-}
-
-void Element::setChildrenAffectedByFocus()
-{
- ensureElementRareData().setChildrenAffectedByFocus(true);
-}
-
-void Element::setChildrenAffectedByHover()
-{
- ensureElementRareData().setChildrenAffectedByHover(true);
-}
-
-void Element::setChildrenAffectedByActive()
-{
- ensureElementRareData().setChildrenAffectedByActive(true);
-}
-
-void Element::setChildrenAffectedByDrag()
-{
- ensureElementRareData().setChildrenAffectedByDrag(true);
-}
-
-void Element::setChildrenAffectedByFirstChildRules()
-{
- ensureElementRareData().setChildrenAffectedByFirstChildRules(true);
-}
-
-void Element::setChildrenAffectedByLastChildRules()
-{
- ensureElementRareData().setChildrenAffectedByLastChildRules(true);
-}
-
-void Element::setChildrenAffectedByDirectAdjacentRules()
-{
- ensureElementRareData().setChildrenAffectedByDirectAdjacentRules(true);
-}
-
-void Element::setChildrenAffectedByForwardPositionalRules()
-{
- ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
-}
-
-void Element::setChildrenAffectedByBackwardPositionalRules()
-{
- ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
-}
-
-void Element::setChildIndex(unsigned index)
-{
- ElementRareData& rareData = ensureElementRareData();
- if (RenderStyle* style = renderStyle())
- style->setUnique();
- rareData.setChildIndex(index);
-}
-
-bool Element::childrenSupportStyleSharing() const
-{
- if (!hasRareData())
- return true;
- return !rareDataChildrenAffectedByFocus()
- && !rareDataChildrenAffectedByHover()
- && !rareDataChildrenAffectedByActive()
- && !rareDataChildrenAffectedByDrag()
- && !rareDataChildrenAffectedByFirstChildRules()
- && !rareDataChildrenAffectedByLastChildRules()
- && !rareDataChildrenAffectedByDirectAdjacentRules()
- && !rareDataChildrenAffectedByForwardPositionalRules()
- && !rareDataChildrenAffectedByBackwardPositionalRules();
-}
-
-bool Element::rareDataStyleAffectedByEmpty() const
-{
- ASSERT(hasRareData());
- return elementRareData()->styleAffectedByEmpty();
-}
-
-bool Element::rareDataChildrenAffectedByFocus() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByFocus();
-}
-
-bool Element::rareDataChildrenAffectedByHover() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByHover();
-}
-
-bool Element::rareDataChildrenAffectedByActive() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByActive();
-}
-
-bool Element::rareDataChildrenAffectedByDrag() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByDrag();
-}
-
-bool Element::rareDataChildrenAffectedByFirstChildRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByFirstChildRules();
-}
-
-bool Element::rareDataChildrenAffectedByLastChildRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByLastChildRules();
-}
-
-bool Element::rareDataChildrenAffectedByDirectAdjacentRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByDirectAdjacentRules();
-}
-
-bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByForwardPositionalRules();
-}
-
-bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childrenAffectedByBackwardPositionalRules();
-}
-
-unsigned Element::rareDataChildIndex() const
-{
- ASSERT(hasRareData());
- return elementRareData()->childIndex();
-}
-
-void Element::setIsInCanvasSubtree(bool isInCanvasSubtree)
-{
- ensureElementRareData().setIsInCanvasSubtree(isInCanvasSubtree);
-}
-
-bool Element::isInCanvasSubtree() const
-{
- return hasRareData() && elementRareData()->isInCanvasSubtree();
-}
-
-void Element::setIsInsideRegion(bool value)
-{
- if (value == isInsideRegion())
- return;
-
- ensureElementRareData().setIsInsideRegion(value);
-}
-
-bool Element::isInsideRegion() const
-{
- return hasRareData() ? elementRareData()->isInsideRegion() : false;
-}
-
-void Element::setRegionOversetState(RegionOversetState state)
-{
- ensureElementRareData().setRegionOversetState(state);
-}
-
-RegionOversetState Element::regionOversetState() const
-{
- return hasRareData() ? elementRareData()->regionOversetState() : RegionUndefined;
-}
-
AtomicString Element::computeInheritedLanguage() const
{
const Node* n = this;
@@ -2676,9 +2473,9 @@ AtomicString Element::computeInheritedLanguage() const
if (n->isElementNode()) {
if (const ElementData* elementData = toElement(n)->elementData()) {
// Spec: xml:lang takes precedence -- http://www.w3.org/TR/xhtml1/#C_7
- if (const Attribute* attribute = elementData->getAttributeItem(XMLNames::langAttr))
+ if (const Attribute* attribute = elementData->findAttributeByName(XMLNames::langAttr))
value = attribute->value();
- else if (const Attribute* attribute = elementData->getAttributeItem(HTMLNames::langAttr))
+ else if (const Attribute* attribute = elementData->findAttributeByName(HTMLNames::langAttr))
value = attribute->value();
}
} else if (n->isDocumentNode()) {
@@ -2699,8 +2496,6 @@ Locale& Element::locale() const
void Element::cancelFocusAppearanceUpdate()
{
- if (hasRareData())
- elementRareData()->setNeedsFocusAppearanceUpdateSoonAfterAttach(false);
if (document().focusedElement() == this)
document().cancelFocusAppearanceUpdate();
}
@@ -2709,16 +2504,20 @@ void Element::normalizeAttributes()
{
if (!hasAttributes())
return;
+ // attributeCount() cannot be cached before the loop because the attributes
+ // list is altered while iterating.
for (unsigned i = 0; i < attributeCount(); ++i) {
- if (RefPtr<Attr> attr = attrIfExists(attributeItem(i)->name()))
+ if (RefPtrWillBeRawPtr<Attr> attr = attrIfExists(attributeAt(i).name()))
attr->normalize();
}
}
void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change)
{
+ ASSERT(!needsStyleRecalc());
PseudoElement* element = pseudoElement(pseudoId);
- if (element && (needsStyleRecalc() || shouldRecalcStyle(change, element))) {
+ if (element && (change == UpdatePseudoElements || element->shouldCallRecalcStyle(change))) {
+
// Need to clear the cached style if the PseudoElement wants a recalc so it
// computes a new style.
if (element->needsStyleRecalc())
@@ -2727,27 +2526,17 @@ void Element::updatePseudoElement(PseudoId pseudoId, StyleRecalcChange change)
// PseudoElement styles hang off their parent element's style so if we needed
// a style recalc we should Force one on the pseudo.
// FIXME: We should figure out the right text sibling to pass.
- element->recalcStyle(needsStyleRecalc() ? Force : change);
+ element->recalcStyle(change == UpdatePseudoElements ? Force : change);
// Wait until our parent is not displayed or pseudoElementRendererIsNeeded
// is false, otherwise we could continously create and destroy PseudoElements
// when RenderObject::isChildAllowed on our parent returns false for the
// PseudoElement's renderer for each style recalc.
if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
- elementRareData()->setPseudoElement(pseudoId, 0);
- } else if (change >= Inherit || needsStyleRecalc())
+ elementRareData()->setPseudoElement(pseudoId, nullptr);
+ } else if (change >= UpdatePseudoElements) {
createPseudoElementIfNeeded(pseudoId);
-}
-
-bool Element::needsPseudoElement(PseudoId pseudoId, const RenderStyle& style) const
-{
- if (pseudoId == BACKDROP && !isInTopLayer())
- return false;
- if (!renderer() || !pseudoElementRendererIsNeeded(&style))
- return false;
- if (!renderer()->canHaveGeneratedChildren())
- return false;
- return true;
+ }
}
void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
@@ -2755,7 +2544,9 @@ void Element::createPseudoElementIfNeeded(PseudoId pseudoId)
if (isPseudoElement())
return;
- RefPtr<PseudoElement> element = document().ensureStyleResolver().createPseudoElementIfNeeded(*this, pseudoId);
+ // Document::ensureStyleResolver is not inlined and shows up on profiles, avoid it here.
+ StyleEngine* engine = document().styleEngine();
+ RefPtrWillBeRawPtr<PseudoElement> element = engine->ensureResolver().createPseudoElementIfNeeded(*this, pseudoId);
if (!element)
return;
@@ -2781,40 +2572,35 @@ RenderObject* Element::pseudoElementRenderer(PseudoId pseudoId) const
return 0;
}
-bool Element::webkitMatchesSelector(const String& selector, ExceptionState& exceptionState)
+bool Element::matches(const String& selectors, ExceptionState& exceptionState)
{
- if (selector.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return false;
- }
-
- SelectorQuery* selectorQuery = document().selectorQueryCache().add(selector, document(), exceptionState);
+ SelectorQuery* selectorQuery = document().selectorQueryCache().add(AtomicString(selectors), document(), exceptionState);
if (!selectorQuery)
return false;
return selectorQuery->matches(*this);
}
-DOMTokenList* Element::classList()
+DOMTokenList& Element::classList()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.classList())
rareData.setClassList(ClassList::create(this));
- return rareData.classList();
+ return *rareData.classList();
}
-DOMStringMap* Element::dataset()
+DOMStringMap& Element::dataset()
{
ElementRareData& rareData = ensureElementRareData();
if (!rareData.dataset())
rareData.setDataset(DatasetDOMStringMap::create(this));
- return rareData.dataset();
+ return *rareData.dataset();
}
KURL Element::getURLAttribute(const QualifiedName& name) const
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
if (elementData()) {
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = findAttributeByName(name))
ASSERT(isURLAttribute(*attribute));
}
#endif
@@ -2823,9 +2609,9 @@ KURL Element::getURLAttribute(const QualifiedName& name) const
KURL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
if (elementData()) {
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = findAttributeByName(name))
ASSERT(isURLAttribute(*attribute));
}
#endif
@@ -2870,33 +2656,19 @@ void Element::setFloatingPointAttribute(const QualifiedName& attributeName, doub
setAttribute(attributeName, AtomicString::number(value));
}
-bool Element::childShouldCreateRenderer(const Node& child) const
-{
- // Only create renderers for SVG elements whose parents are SVG elements, or for proper <svg xmlns="svgNS"> subdocuments.
- if (child.isSVGElement())
- return child.hasTagName(SVGNames::svgTag) || isSVGElement();
-
- return ContainerNode::childShouldCreateRenderer(child);
-}
-
void Element::webkitRequestFullscreen()
{
- FullscreenElementStack::from(&document())->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
+ FullscreenElementStack::from(document()).requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
}
void Element::webkitRequestFullScreen(unsigned short flags)
{
- FullscreenElementStack::from(&document())->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
-}
-
-bool Element::containsFullScreenElement() const
-{
- return hasRareData() && elementRareData()->containsFullScreenElement();
+ FullscreenElementStack::from(document()).requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
}
void Element::setContainsFullScreenElement(bool flag)
{
- ensureElementRareData().setContainsFullScreenElement(flag);
+ setElementFlag(ContainsFullScreenElement, flag);
setNeedsStyleRecalc(SubtreeStyleChange);
}
@@ -2913,16 +2685,11 @@ void Element::setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(boo
element->setContainsFullScreenElement(flag);
}
-bool Element::isInTopLayer() const
-{
- return hasRareData() && elementRareData()->isInTopLayer();
-}
-
void Element::setIsInTopLayer(bool inTopLayer)
{
if (isInTopLayer() == inTopLayer)
return;
- ensureElementRareData().setIsInTopLayer(inTopLayer);
+ setElementFlag(IsInTopLayer, inTopLayer);
// We must ensure a reattach occurs so the renderer is inserted in the correct sibling order under RenderView according to its
// top layer position, or in its usual place if not in the top layer.
@@ -2935,9 +2702,15 @@ void Element::webkitRequestPointerLock()
document().page()->pointerLockController().requestPointerLock(this);
}
+void Element::requestPointerLock()
+{
+ if (document().page())
+ document().page()->pointerLockController().requestPointerLock(this);
+}
+
SpellcheckAttributeState Element::spellcheckAttributeState() const
{
- const AtomicString& value = getAttribute(HTMLNames::spellcheckAttr);
+ const AtomicString& value = fastGetAttribute(spellcheckAttr);
if (value == nullAtom)
return SpellcheckAttributeDefault;
if (equalIgnoringCase(value, "true") || equalIgnoringCase(value, ""))
@@ -2964,79 +2737,6 @@ bool Element::isSpellCheckingEnabled() const
return true;
}
-RenderRegion* Element::renderRegion() const
-{
- if (renderer() && renderer()->isRenderNamedFlowFragmentContainer())
- return toRenderBlockFlow(renderer())->renderNamedFlowFragment();
-
- return 0;
-}
-
-bool Element::shouldMoveToFlowThread(RenderStyle* styleToUse) const
-{
- ASSERT(styleToUse);
-
- if (FullscreenElementStack::isActiveFullScreenElement(this))
- return false;
-
- if (isInShadowTree())
- return false;
-
- if (styleToUse->flowThread().isEmpty())
- return false;
-
- return !isRegisteredWithNamedFlow();
-}
-
-const AtomicString& Element::webkitRegionOverset() const
-{
- DEFINE_STATIC_LOCAL(AtomicString, undefinedState, ("undefined", AtomicString::ConstructFromLiteral));
- if (!RuntimeEnabledFeatures::cssRegionsEnabled())
- return undefinedState;
-
- document().updateLayoutIgnorePendingStylesheets();
-
- if (!renderRegion())
- return undefinedState;
-
- switch (renderRegion()->regionOversetState()) {
- case RegionFit: {
- DEFINE_STATIC_LOCAL(AtomicString, fitState, ("fit", AtomicString::ConstructFromLiteral));
- return fitState;
- }
- case RegionEmpty: {
- DEFINE_STATIC_LOCAL(AtomicString, emptyState, ("empty", AtomicString::ConstructFromLiteral));
- return emptyState;
- }
- case RegionOverset: {
- DEFINE_STATIC_LOCAL(AtomicString, overflowState, ("overset", AtomicString::ConstructFromLiteral));
- return overflowState;
- }
- case RegionUndefined:
- return undefinedState;
- }
-
- ASSERT_NOT_REACHED();
- return undefinedState;
-}
-
-Vector<RefPtr<Range> > Element::webkitGetRegionFlowRanges() const
-{
- Vector<RefPtr<Range> > rangeObjects;
- if (!RuntimeEnabledFeatures::cssRegionsEnabled())
- return rangeObjects;
-
- document().updateLayoutIgnorePendingStylesheets();
-
- if (renderer() && renderer()->isRenderNamedFlowFragmentContainer()) {
- RenderNamedFlowFragment* region = toRenderBlockFlow(renderer())->renderNamedFlowFragment();
- if (region->isValid())
- region->getRanges(rangeObjects);
- }
-
- return rangeObjects;
-}
-
#ifndef NDEBUG
bool Element::fastAttributeLookupAllowed(const QualifiedName& name) const
{
@@ -3096,7 +2796,7 @@ inline void Element::updateId(TreeScope& scope, const AtomicString& oldId, const
void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
{
- ASSERT(hasTagName(labelTag));
+ ASSERT(isHTMLLabelElement(this));
if (!inDocument())
return;
@@ -3110,32 +2810,27 @@ void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeV
scope.addLabel(newForAttributeValue, toHTMLLabelElement(this));
}
-static bool hasSelectorForAttribute(Document* document, const AtomicString& localName)
-{
- return document->ensureStyleResolver().ensureRuleFeatureSet().hasSelectorForAttribute(localName);
-}
-
void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
{
- if (isIdAttributeName(name))
+ if (isIdAttributeName(name)) {
updateId(oldValue, newValue);
- else if (name == HTMLNames::nameAttr)
+ } else if (name == HTMLNames::nameAttr) {
updateName(oldValue, newValue);
- else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
+ } else if (name == HTMLNames::forAttr && isHTMLLabelElement(*this)) {
TreeScope& scope = treeScope();
if (scope.shouldCacheLabelsByForAttribute())
updateLabel(scope, oldValue, newValue);
}
if (oldValue != newValue) {
- if (inActiveDocument() && hasSelectorForAttribute(&document(), name.localName()))
- setNeedsStyleRecalc();
+ if (inActiveDocument() && document().styleResolver() && styleChangeType() < SubtreeStyleChange)
+ document().ensureStyleResolver().ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForAttributeChange(name, *this);
if (isUpgradedCustomElement())
CustomElement::attributeDidChange(this, name.localName(), oldValue, newValue);
}
- if (OwnPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
+ if (OwnPtrWillBeRawPtr<MutationObserverInterestGroup> recipients = MutationObserverInterestGroup::createForAttributesMutation(*this, name))
recipients->enqueueMutationRecord(MutationRecord::createAttributes(this, name, oldValue));
InspectorInstrumentation::willModifyDOMAttr(this, oldValue, newValue);
@@ -3162,6 +2857,33 @@ void Element::didRemoveAttribute(const QualifiedName& name)
dispatchSubtreeModifiedEvent();
}
+static bool needsURLResolutionForInlineStyle(const Element& element, const Document& oldDocument, const Document& newDocument)
+{
+ if (oldDocument == newDocument)
+ return false;
+ if (oldDocument.baseURL() == newDocument.baseURL())
+ return false;
+ const StylePropertySet* style = element.inlineStyle();
+ if (!style)
+ return false;
+ for (unsigned i = 0; i < style->propertyCount(); ++i) {
+ // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCursorImageValue, etc.
+ if (style->propertyAt(i).value()->isImageValue())
+ return true;
+ }
+ return false;
+}
+
+static void reResolveURLsInInlineStyle(const Document& document, MutableStylePropertySet& style)
+{
+ for (unsigned i = 0; i < style.propertyCount(); ++i) {
+ StylePropertySet::PropertyReference property = style.propertyAt(i);
+ // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCursorImageValue, etc.
+ if (property.value()->isImageValue())
+ toCSSImageValue(property.value())->reResolveURL(document);
+ }
+}
+
void Element::didMoveToNewDocument(Document& oldDocument)
{
Node::didMoveToNewDocument(oldDocument);
@@ -3175,6 +2897,9 @@ void Element::didMoveToNewDocument(Document& oldDocument)
if (hasClass())
setAttribute(HTMLNames::classAttr, getClassAttribute());
}
+
+ if (needsURLResolutionForInlineStyle(*this, oldDocument, document()))
+ reResolveURLsInInlineStyle(document(), ensureMutableInlineStyle());
}
void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
@@ -3201,43 +2926,32 @@ void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const
toHTMLDocument(document()).addExtraNamedItem(newId);
}
-PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
+PassRefPtrWillBeRawPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type)
{
if (HTMLCollection* collection = cachedHTMLCollection(type))
return collection;
- RefPtr<HTMLCollection> collection;
if (type == TableRows) {
- ASSERT(hasTagName(tableTag));
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTableRowsCollection>(this, type);
+ ASSERT(isHTMLTableElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLTableRowsCollection>(*this, type);
} else if (type == SelectOptions) {
- ASSERT(hasTagName(selectTag));
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLOptionsCollection>(this, type);
+ ASSERT(isHTMLSelectElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLOptionsCollection>(*this, type);
} else if (type == FormControls) {
- ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLFormControlsCollection>(this, type);
+ ASSERT(isHTMLFormElement(this) || isHTMLFieldSetElement(this));
+ return ensureRareData().ensureNodeLists().addCache<HTMLFormControlsCollection>(*this, type);
}
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLCollection>(this, type);
-}
-
-static void scheduleLayerUpdateCallback(Node* node)
-{
- // Notify the renderer even is the styles are identical since it may need to
- // create or destroy a RenderLayer.
- node->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
+ return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
}
-void Element::scheduleLayerUpdate()
+void Element::scheduleSVGFilterLayerUpdateHack()
{
- if (document().inStyleRecalc())
- PostAttachCallbacks::queueCallback(scheduleLayerUpdateCallback, this);
- else
- scheduleLayerUpdateCallback(this);
+ document().scheduleSVGFilterLayerUpdateHack(*this);
}
HTMLCollection* Element::cachedHTMLCollection(CollectionType type)
{
- return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0;
+ return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cached<HTMLCollection>(type) : 0;
}
IntSize Element::savedLayerScrollOffset() const
@@ -3252,17 +2966,17 @@ void Element::setSavedLayerScrollOffset(const IntSize& size)
ensureElementRareData().setSavedLayerScrollOffset(size);
}
-PassRefPtr<Attr> Element::attrIfExists(const QualifiedName& name)
+PassRefPtrWillBeRawPtr<Attr> Element::attrIfExists(const QualifiedName& name)
{
- if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
+ if (AttrNodeList* attrNodeList = this->attrNodeList())
return findAttrNodeInList(*attrNodeList, name);
- return 0;
+ return nullptr;
}
-PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
+PassRefPtrWillBeRawPtr<Attr> Element::ensureAttr(const QualifiedName& name)
{
- AttrNodeList& attrNodeList = ensureAttrNodeListForElement(this);
- RefPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
+ AttrNodeList& attrNodeList = ensureAttrNodeList();
+ RefPtrWillBeRawPtr<Attr> attrNode = findAttrNodeInList(attrNodeList, name);
if (!attrNode) {
attrNode = Attr::create(*this, name);
treeScope().adoptIfNeeded(*attrNode);
@@ -3276,12 +2990,12 @@ void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicStr
ASSERT(hasSyntheticAttrChildNodes());
attrNode->detachFromElementWithValue(value);
- AttrNodeList* attrNodeList = attrNodeListForElement(this);
- for (unsigned i = 0; i < attrNodeList->size(); ++i) {
- if (attrNodeList->at(i)->qualifiedName() == attrNode->qualifiedName()) {
- attrNodeList->remove(i);
- if (attrNodeList->isEmpty())
- removeAttrNodeListForElement(this);
+ AttrNodeList* list = attrNodeList();
+ for (unsigned i = 0; i < list->size(); ++i) {
+ if (list->at(i)->qualifiedName() == attrNode->qualifiedName()) {
+ list->remove(i);
+ if (list->isEmpty())
+ removeAttrNodeList();
return;
}
}
@@ -3290,16 +3004,17 @@ void Element::detachAttrNodeFromElementWithValue(Attr* attrNode, const AtomicStr
void Element::detachAllAttrNodesFromElement()
{
- AttrNodeList* attrNodeList = attrNodeListForElement(this);
- ASSERT(attrNodeList);
+ AttrNodeList* list = this->attrNodeList();
+ ASSERT(list);
- for (unsigned i = 0; i < attributeCount(); ++i) {
- const Attribute* attribute = attributeItem(i);
- if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute->name()))
- attrNode->detachFromElementWithValue(attribute->value());
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (RefPtrWillBeRawPtr<Attr> attrNode = findAttrNodeInList(*list, it->name()))
+ attrNode->detachFromElementWithValue(it->value());
}
- removeAttrNodeListForElement(this);
+ removeAttrNodeList();
}
void Element::willRecalcStyle(StyleRecalcChange)
@@ -3316,7 +3031,7 @@ void Element::didRecalcStyle(StyleRecalcChange)
PassRefPtr<RenderStyle> Element::customStyleForRenderer()
{
ASSERT(hasCustomStyleCallbacks());
- return 0;
+ return nullptr;
}
void Element::cloneAttributesFromElement(const Element& other)
@@ -3349,23 +3064,21 @@ void Element::cloneAttributesFromElement(const Element& other)
ownerDocumentsHaveDifferentCaseSensitivity = other.document().inQuirksMode() != document().inQuirksMode();
// If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements.
- // We can only do this if there is no CSSOM wrapper for other's inline style, and there are no presentation attributes,
- // and sharing the data won't result in different case sensitivity of class or id.
+ // We can only do this if there are no presentation attributes and sharing the data won't result in different case sensitivity of class or id.
if (other.m_elementData->isUnique()
&& !ownerDocumentsHaveDifferentCaseSensitivity
- && !other.m_elementData->presentationAttributeStyle()
- && (!other.m_elementData->inlineStyle() || !other.m_elementData->inlineStyle()->hasCSSOMWrapper()))
+ && !other.m_elementData->presentationAttributeStyle())
const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
- if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity)
+ if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity && !needsURLResolutionForInlineStyle(other, other.document(), document()))
m_elementData = other.m_elementData;
else
m_elementData = other.m_elementData->makeUniqueCopy();
- for (unsigned i = 0; i < m_elementData->length(); ++i) {
- const Attribute* attribute = const_cast<const ElementData*>(m_elementData.get())->attributeItem(i);
- attributeChangedFromParserOrByCloning(attribute->name(), attribute->value(), ModifiedByCloning);
- }
+ AttributeCollection attributes = m_elementData->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it)
+ attributeChangedFromParserOrByCloning(it->name(), it->value(), ModifiedByCloning);
}
void Element::cloneDataFromElement(const Element& other)
@@ -3384,7 +3097,7 @@ void Element::createUniqueElementData()
}
}
-InputMethodContext* Element::inputMethodContext()
+InputMethodContext& Element::inputMethodContext()
{
return ensureElementRareData().ensureInputMethodContext(toHTMLElement(this));
}
@@ -3394,58 +3107,42 @@ bool Element::hasInputMethodContext() const
return hasRareData() && elementRareData()->hasInputMethodContext();
}
-bool Element::hasPendingResources() const
-{
- return hasRareData() && elementRareData()->hasPendingResources();
-}
-
-void Element::setHasPendingResources()
-{
- ensureElementRareData().setHasPendingResources(true);
-}
-
-void Element::clearHasPendingResources()
-{
- ensureElementRareData().setHasPendingResources(false);
-}
-
void Element::synchronizeStyleAttributeInternal() const
{
ASSERT(isStyledElement());
ASSERT(elementData());
ASSERT(elementData()->m_styleAttributeIsDirty);
elementData()->m_styleAttributeIsDirty = false;
- if (const StylePropertySet* inlineStyle = this->inlineStyle())
- const_cast<Element*>(this)->setSynchronizedLazyAttribute(styleAttr, inlineStyle->asText());
+ const StylePropertySet* inlineStyle = this->inlineStyle();
+ const_cast<Element*>(this)->setSynchronizedLazyAttribute(styleAttr,
+ inlineStyle ? AtomicString(inlineStyle->asText()) : nullAtom);
}
CSSStyleDeclaration* Element::style()
{
if (!isStyledElement())
return 0;
- return ensureMutableInlineStyle()->ensureInlineCSSStyleDeclaration(this);
+ return &ensureElementRareData().ensureInlineCSSStyleDeclaration(this);
}
-MutableStylePropertySet* Element::ensureMutableInlineStyle()
+MutableStylePropertySet& Element::ensureMutableInlineStyle()
{
ASSERT(isStyledElement());
- RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData()->m_inlineStyle;
+ RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData().m_inlineStyle;
if (!inlineStyle) {
CSSParserMode mode = (!isHTMLElement() || document().inQuirksMode()) ? HTMLQuirksMode : HTMLStandardMode;
inlineStyle = MutableStylePropertySet::create(mode);
} else if (!inlineStyle->isMutable()) {
inlineStyle = inlineStyle->mutableCopy();
}
- return toMutableStylePropertySet(inlineStyle);
+ return *toMutableStylePropertySet(inlineStyle);
}
-PropertySetCSSStyleDeclaration* Element::inlineStyleCSSOMWrapper()
+void Element::clearMutableInlineStyleIfEmpty()
{
- if (!inlineStyle() || !inlineStyle()->hasCSSOMWrapper())
- return 0;
- PropertySetCSSStyleDeclaration* cssomWrapper = ensureMutableInlineStyle()->cssStyleDeclaration();
- ASSERT(cssomWrapper && cssomWrapper->parentElement() == this);
- return cssomWrapper;
+ if (ensureMutableInlineStyle().isEmpty()) {
+ ensureUniqueElementData().m_inlineStyle.clear();
+ }
}
inline void Element::setInlineStyleFromString(const AtomicString& newStyleString)
@@ -3463,10 +3160,10 @@ inline void Element::setInlineStyleFromString(const AtomicString& newStyleString
inlineStyle.clear();
if (!inlineStyle) {
- inlineStyle = CSSParser::parseInlineStyleDeclaration(newStyleString, this);
+ inlineStyle = BisonCSSParser::parseInlineStyleDeclaration(newStyleString, this);
} else {
ASSERT(inlineStyle->isMutable());
- static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet()->contents());
+ static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet().contents());
}
}
@@ -3478,9 +3175,7 @@ void Element::styleAttributeChanged(const AtomicString& newStyleString, Attribut
startLineNumber = document().scriptableDocumentParser()->lineNumber();
if (newStyleString.isNull()) {
- if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper())
- cssomWrapper->clearParentElement();
- ensureUniqueElementData()->m_inlineStyle.clear();
+ ensureUniqueElementData().m_inlineStyle.clear();
} else if (modificationReason == ModifiedByCloning || document().contentSecurityPolicy()->allowInlineStyle(document().url(), startLineNumber)) {
setInlineStyleFromString(newStyleString);
}
@@ -3503,7 +3198,7 @@ void Element::inlineStyleChanged()
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSValueID identifier, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
inlineStyleChanged();
return true;
}
@@ -3511,15 +3206,15 @@ bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSValueID identi
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSPropertyID identifier, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
inlineStyleChanged();
return true;
}
-bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important)
+bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitType unit, bool important)
{
ASSERT(isStyledElement());
- ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createValue(value, unit), important);
+ ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createValue(value, unit), important);
inlineStyleChanged();
return true;
}
@@ -3527,7 +3222,7 @@ bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSS
bool Element::setInlineStyleProperty(CSSPropertyID propertyID, const String& value, bool important)
{
ASSERT(isStyledElement());
- bool changes = ensureMutableInlineStyle()->setProperty(propertyID, value, important, document().elementSheet()->contents());
+ bool changes = ensureMutableInlineStyle().setProperty(propertyID, value, important, document().elementSheet().contents());
if (changes)
inlineStyleChanged();
return changes;
@@ -3538,7 +3233,7 @@ bool Element::removeInlineStyleProperty(CSSPropertyID propertyID)
ASSERT(isStyledElement());
if (!inlineStyle())
return false;
- bool changes = ensureMutableInlineStyle()->removeProperty(propertyID);
+ bool changes = ensureMutableInlineStyle().removeProperty(propertyID);
if (changes)
inlineStyleChanged();
return changes;
@@ -3547,25 +3242,19 @@ bool Element::removeInlineStyleProperty(CSSPropertyID propertyID)
void Element::removeAllInlineStyleProperties()
{
ASSERT(isStyledElement());
- if (!inlineStyle() || inlineStyle()->isEmpty())
+ if (!inlineStyle())
return;
- ensureMutableInlineStyle()->clear();
+ ensureMutableInlineStyle().clear();
inlineStyleChanged();
}
-void Element::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- ASSERT(isStyledElement());
- if (const StylePropertySet* inlineStyle = elementData() ? elementData()->inlineStyle() : 0)
- inlineStyle->addSubresourceStyleURLs(urls, document().elementSheet()->contents());
-}
-
void Element::updatePresentationAttributeStyle()
{
+ synchronizeAllAttributes();
// ShareableElementData doesn't store presentation attribute style, so make sure we have a UniqueElementData.
- UniqueElementData* elementData = ensureUniqueElementData();
- elementData->m_presentationAttributeStyleIsDirty = false;
- elementData->m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
+ UniqueElementData& elementData = ensureUniqueElementData();
+ elementData.m_presentationAttributeStyleIsDirty = false;
+ elementData.m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
}
void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, CSSValueID identifier)
@@ -3574,7 +3263,7 @@ void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* s
style->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier));
}
-void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit)
+void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitType unit)
{
ASSERT(isStyledElement());
style->setProperty(propertyID, cssValuePool().createValue(value, unit));
@@ -3588,7 +3277,7 @@ void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* s
bool Element::supportsStyleSharing() const
{
- if (!isStyledElement() || !parentElement())
+ if (!isStyledElement() || !parentOrShadowHostElement())
return false;
// If the element has inline style it is probably unique.
if (inlineStyle())
@@ -3598,17 +3287,12 @@ bool Element::supportsStyleSharing() const
// Ids stop style sharing if they show up in the stylesheets.
if (hasID() && document().ensureStyleResolver().hasRulesForId(idForStyleResolution()))
return false;
- // Active and hovered elements always make a chain towards the document node
- // and no siblings or cousins will have the same state.
- if (hovered())
- return false;
- if (active())
- return false;
- if (focused())
+ // :active and :hover elements always make a chain towards the document node
+ // and no siblings or cousins will have the same state. There's also only one
+ // :focus element per scope so we don't need to attempt to share.
+ if (isUserActionElement())
return false;
- if (!parentElement()->childrenSupportStyleSharing())
- return false;
- if (hasScopedHTMLStyleChild())
+ if (!parentOrShadowHostElement()->childrenSupportStyleSharing())
return false;
if (this == document().cssTarget())
return false;
@@ -3616,26 +3300,26 @@ bool Element::supportsStyleSharing() const
return false;
if (hasActiveAnimations())
return false;
- if (shadow() && shadow()->containsActiveStyles())
- return false;
// Turn off style sharing for elements that can gain layers for reasons outside of the style system.
// See comments in RenderObject::setStyle().
// FIXME: Why does gaining a layer from outside the style system require disabling sharing?
- if (hasTagName(iframeTag)
- || hasTagName(frameTag)
- || hasTagName(embedTag)
- || hasTagName(objectTag)
- || hasTagName(appletTag)
- || hasTagName(canvasTag))
- return false;
- // FIXME: We should share style for option and optgroup whenever possible.
- // Before doing so, we need to resolve issues in HTMLSelectElement::recalcListItems
- // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cgi?id=88405
- if (hasTagName(optionTag) || hasTagName(optgroupTag))
+ if (isHTMLFrameElementBase(*this)
+ || isHTMLEmbedElement(*this)
+ || isHTMLObjectElement(*this)
+ || isHTMLAppletElement(*this)
+ || isHTMLCanvasElement(*this))
return false;
if (FullscreenElementStack::isActiveFullScreenElement(this))
return false;
return true;
}
+void Element::trace(Visitor* visitor)
+{
+ if (hasRareData())
+ visitor->trace(elementRareData());
+
+ ContainerNode::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Element.h b/chromium/third_party/WebKit/Source/core/dom/Element.h
index 370d7d6a5ed..b3972e8a490 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Element.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Element.h
@@ -25,16 +25,16 @@
#ifndef Element_h
#define Element_h
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/dom/Attribute.h"
-#include "core/dom/Document.h"
+#include "core/dom/ContainerNode.h"
#include "core/dom/ElementData.h"
#include "core/dom/SpaceSplitString.h"
#include "core/html/CollectionType.h"
-#include "core/page/FocusDirection.h"
-#include "core/rendering/RegionOversetState.h"
+#include "core/page/FocusType.h"
+#include "platform/heap/Handle.h"
#include "platform/scroll/ScrollTypes.h"
namespace WebCore {
@@ -42,10 +42,13 @@ namespace WebCore {
class ActiveAnimations;
class Attr;
class Attribute;
+class CSSStyleDeclaration;
class ClientRect;
class ClientRectList;
+class CustomElementDefinition;
class DOMStringMap;
class DOMTokenList;
+class Document;
class ElementRareData;
class ElementShadow;
class ExceptionState;
@@ -56,7 +59,6 @@ class Locale;
class MutableStylePropertySet;
class PropertySetCSSStyleDeclaration;
class PseudoElement;
-class RenderRegion;
class ShadowRoot;
class StylePropertySet;
@@ -77,9 +79,20 @@ enum SpellcheckAttributeState {
SpellcheckAttributeDefault
};
+enum ElementFlags {
+ TabIndexWasSetExplicitly = 1 << 0,
+ StyleAffectedByEmpty = 1 << 1,
+ IsInCanvasSubtree = 1 << 2,
+ ContainsFullScreenElement = 1 << 3,
+ IsInTopLayer = 1 << 4,
+ HasPendingResources = 1 << 5,
+
+ NumberOfElementFlags = 6, // Required size of bitfield used to store the flags.
+};
+
class Element : public ContainerNode {
public:
- static PassRefPtr<Element> create(const QualifiedName&, Document*);
+ static PassRefPtrWillBeRawPtr<Element> create(const QualifiedName&, Document*);
virtual ~Element();
DEFINE_ATTRIBUTE_EVENT_LISTENER(beforecopy);
@@ -100,8 +113,11 @@ public:
bool hasAttribute(const QualifiedName&) const;
const AtomicString& getAttribute(const QualifiedName&) const;
+
+ // Passing nullAtom as the second parameter removes the attribute when calling either of these set methods.
void setAttribute(const QualifiedName&, const AtomicString& value);
void setSynchronizedLazyAttribute(const QualifiedName&, const AtomicString& value);
+
void removeAttribute(const QualifiedName&);
// Typed getters and setters for language bindings.
@@ -153,12 +169,14 @@ public:
const AtomicString& idForStyleResolution() const;
// Internal methods that assume the existence of attribute storage, one should use hasAttributes()
- // before calling them.
+ // before calling them. This is not a trivial getter and its return value should be cached for
+ // performance.
+ AttributeCollection attributes() const { return elementData()->attributes(); }
size_t attributeCount() const;
- const Attribute* attributeItem(unsigned index) const;
- const Attribute* getAttributeItem(const QualifiedName&) const;
- size_t getAttributeItemIndex(const QualifiedName& name) const { return elementData()->getAttributeItemIndex(name); }
- size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->getAttributeItemIndex(name, shouldIgnoreAttributeCase); }
+ const Attribute& attributeAt(unsigned index) const;
+ const Attribute* findAttributeByName(const QualifiedName&) const;
+ size_t findAttributeIndexByName(const QualifiedName& name) const { return elementData()->findAttributeIndexByName(name); }
+ size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->findAttributeIndexByName(name, shouldIgnoreAttributeCase); }
void scrollIntoView(bool alignToTop = true);
void scrollIntoViewIfNeeded(bool centerIfNeeded = true);
@@ -172,8 +190,8 @@ public:
int offsetHeight();
// FIXME: Replace uses of offsetParent in the platform with calls
- // to the render layer and merge bindingsOffsetParent and offsetParent.
- Element* bindingsOffsetParent();
+ // to the render layer and merge offsetParentForBindings and offsetParent.
+ Element* offsetParentForBindings();
Element* offsetParent();
int clientLeft();
@@ -183,14 +201,16 @@ public:
virtual int scrollLeft();
virtual int scrollTop();
virtual void setScrollLeft(int);
+ virtual void setScrollLeft(const Dictionary& scrollOptionsHorizontal, ExceptionState&);
virtual void setScrollTop(int);
+ virtual void setScrollTop(const Dictionary& scrollOptionsVertical, ExceptionState&);
virtual int scrollWidth();
virtual int scrollHeight();
IntRect boundsInRootViewSpace();
- PassRefPtr<ClientRectList> getClientRects();
- PassRefPtr<ClientRect> getBoundingClientRect();
+ PassRefPtrWillBeRawPtr<ClientRectList> getClientRects();
+ PassRefPtrWillBeRawPtr<ClientRect> getBoundingClientRect();
// Returns the absolute bounding box translated into screen coordinates:
IntRect screenRect() const;
@@ -200,18 +220,18 @@ public:
void removeAttribute(const AtomicString& name);
void removeAttributeNS(const AtomicString& namespaceURI, const AtomicString& localName);
- PassRefPtr<Attr> detachAttribute(size_t index);
+ PassRefPtrWillBeRawPtr<Attr> detachAttribute(size_t index);
- PassRefPtr<Attr> getAttributeNode(const AtomicString& name);
- PassRefPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
- PassRefPtr<Attr> setAttributeNode(Attr*, ExceptionState&);
- PassRefPtr<Attr> setAttributeNodeNS(Attr*, ExceptionState&);
- PassRefPtr<Attr> removeAttributeNode(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> getAttributeNode(const AtomicString& name);
+ PassRefPtrWillBeRawPtr<Attr> getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName);
+ PassRefPtrWillBeRawPtr<Attr> setAttributeNode(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> setAttributeNodeNS(Attr*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Attr> removeAttributeNode(Attr*, ExceptionState&);
- PassRefPtr<Attr> attrIfExists(const QualifiedName&);
- PassRefPtr<Attr> ensureAttr(const QualifiedName&);
+ PassRefPtrWillBeRawPtr<Attr> attrIfExists(const QualifiedName&);
+ PassRefPtrWillBeRawPtr<Attr> ensureAttr(const QualifiedName&);
- const Vector<RefPtr<Attr> >& attrNodeList();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodeList();
CSSStyleDeclaration* style();
@@ -226,21 +246,22 @@ public:
bool hasLocalName(const AtomicString& other) const { return m_tagName.localName() == other; }
bool hasLocalName(const QualifiedName& other) const { return m_tagName.localName() == other.localName(); }
- virtual const AtomicString& localName() const OVERRIDE { return m_tagName.localName(); }
- virtual const AtomicString& prefix() const OVERRIDE { return m_tagName.prefix(); }
- virtual const AtomicString& namespaceURI() const OVERRIDE { return m_tagName.namespaceURI(); }
+ virtual const AtomicString& localName() const OVERRIDE FINAL { return m_tagName.localName(); }
+ const AtomicString& prefix() const { return m_tagName.prefix(); }
+ virtual const AtomicString& namespaceURI() const OVERRIDE FINAL { return m_tagName.namespaceURI(); }
+
+ const AtomicString& locateNamespacePrefix(const AtomicString& namespaceURI) const;
virtual KURL baseURI() const OVERRIDE FINAL;
- virtual String nodeName() const;
+ virtual String nodeName() const OVERRIDE;
- PassRefPtr<Element> cloneElementWithChildren();
- PassRefPtr<Element> cloneElementWithoutChildren();
+ PassRefPtrWillBeRawPtr<Element> cloneElementWithChildren();
+ PassRefPtrWillBeRawPtr<Element> cloneElementWithoutChildren();
- void scheduleLayerUpdate();
+ void scheduleSVGFilterLayerUpdateHack();
void normalizeAttributes();
- String nodeNamePreservingCase() const;
void setBooleanAttribute(const QualifiedName& name, bool);
@@ -251,7 +272,7 @@ public:
bool setInlineStyleProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
bool setInlineStyleProperty(CSSPropertyID, CSSPropertyID identifier, bool important = false);
- bool setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitTypes, bool important = false);
+ bool setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitType, bool important = false);
bool setInlineStyleProperty(CSSPropertyID, const String& value, bool important = false);
bool removeInlineStyleProperty(CSSPropertyID);
void removeAllInlineStyleProperties();
@@ -263,7 +284,7 @@ public:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) { }
// For exposing to DOM only.
- NamedNodeMap* attributes() const;
+ NamedNodeMap* attributesForBindings() const;
enum AttributeModificationReason {
ModifiedDirectly,
@@ -272,7 +293,10 @@ public:
// This method is called whenever an attribute is added, changed or removed.
virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly);
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) { }
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&);
+
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const;
+ virtual const QualifiedName& subResourceAttributeName() const;
// Only called by the parser immediately after element construction.
void parserSetAttributes(const Vector<Attribute>&);
@@ -281,7 +305,7 @@ public:
void stripScriptingAttributes(Vector<Attribute>&) const;
const ElementData* elementData() const { return m_elementData.get(); }
- UniqueElementData* ensureUniqueElementData();
+ UniqueElementData& ensureUniqueElementData();
void synchronizeAllAttributes() const;
@@ -304,63 +328,35 @@ public:
void setAnimationStyleChange(bool);
void setNeedsAnimationStyleRecalc();
+ void setNeedsCompositingUpdate();
+
bool supportsStyleSharing() const;
ElementShadow* shadow() const;
ElementShadow& ensureShadow();
- PassRefPtr<ShadowRoot> createShadowRoot(ExceptionState&);
+ PassRefPtrWillBeRawPtr<ShadowRoot> createShadowRoot(ExceptionState&);
ShadowRoot* shadowRoot() const;
ShadowRoot* youngestShadowRoot() const;
bool hasAuthorShadowRoot() const { return shadowRoot(); }
- virtual void didAddShadowRoot(ShadowRoot&);
ShadowRoot* userAgentShadowRoot() const;
ShadowRoot& ensureUserAgentShadowRoot();
- const AtomicString& shadowPseudoId() const;
+ virtual void willAddFirstAuthorShadowRoot() { }
+
bool isInDescendantTreeOf(const Element* shadowHost) const;
RenderStyle* computedStyle(PseudoId = NOPSEUDO);
// Methods for indicating the style is affected by dynamic updates (e.g., children changing, our position changing in our sibling list, etc.)
- bool styleAffectedByEmpty() const { return hasRareData() && rareDataStyleAffectedByEmpty(); }
- bool childrenAffectedByFocus() const { return hasRareData() && rareDataChildrenAffectedByFocus(); }
- bool childrenAffectedByHover() const { return hasRareData() && rareDataChildrenAffectedByHover(); }
- bool childrenAffectedByActive() const { return hasRareData() && rareDataChildrenAffectedByActive(); }
- bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); }
- bool childrenAffectedByPositionalRules() const { return hasRareData() && (rareDataChildrenAffectedByForwardPositionalRules() || rareDataChildrenAffectedByBackwardPositionalRules()); }
- bool childrenAffectedByFirstChildRules() const { return hasRareData() && rareDataChildrenAffectedByFirstChildRules(); }
- bool childrenAffectedByLastChildRules() const { return hasRareData() && rareDataChildrenAffectedByLastChildRules(); }
- bool childrenAffectedByDirectAdjacentRules() const { return hasRareData() && rareDataChildrenAffectedByDirectAdjacentRules(); }
- bool childrenAffectedByForwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByForwardPositionalRules(); }
- bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); }
- unsigned childIndex() const { return hasRareData() ? rareDataChildIndex() : 0; }
-
- bool childrenSupportStyleSharing() const;
-
- void setStyleAffectedByEmpty();
- void setChildrenAffectedByFocus();
- void setChildrenAffectedByHover();
- void setChildrenAffectedByActive();
- void setChildrenAffectedByDrag();
- void setChildrenAffectedByFirstChildRules();
- void setChildrenAffectedByLastChildRules();
- void setChildrenAffectedByDirectAdjacentRules();
- void setChildrenAffectedByForwardPositionalRules();
- void setChildrenAffectedByBackwardPositionalRules();
- void setChildIndex(unsigned);
-
- void setIsInCanvasSubtree(bool);
- bool isInCanvasSubtree() const;
+ bool styleAffectedByEmpty() const { return hasElementFlag(StyleAffectedByEmpty); }
+ void setStyleAffectedByEmpty() { setElementFlag(StyleAffectedByEmpty); }
+
+ void setIsInCanvasSubtree(bool value) { setElementFlag(IsInCanvasSubtree, value); }
+ bool isInCanvasSubtree() const { return hasElementFlag(IsInCanvasSubtree); }
bool isUpgradedCustomElement() { return customElementState() == Upgraded; }
bool isUnresolvedCustomElement() { return customElementState() == WaitingForUpgrade; }
- void setIsInsideRegion(bool);
- bool isInsideRegion() const;
-
- void setRegionOversetState(RegionOversetState);
- RegionOversetState regionOversetState() const;
-
AtomicString computeInheritedLanguage() const;
Locale& locale() const;
@@ -373,10 +369,9 @@ public:
KURL getNonEmptyURLAttribute(const QualifiedName&) const;
virtual const AtomicString imageSourceURL() const;
- virtual String target() const { return String(); }
virtual Image* imageContents() { return 0; }
- virtual void focus(bool restorePreviousSelection = true, FocusDirection = FocusDirectionNone);
+ virtual void focus(bool restorePreviousSelection = true, FocusType = FocusTypeNone);
virtual void updateFocusAppearance(bool restorePreviousSelection);
virtual void blur();
// Whether this element can receive focus at all. Most elements are not
@@ -388,7 +383,7 @@ public:
bool isFocusable() const;
virtual bool isKeyboardFocusable() const;
virtual bool isMouseFocusable() const;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection);
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType);
virtual void dispatchBlurEvent(Element* newFocusedElement);
void dispatchFocusInEvent(const AtomicString& eventType, Element* oldFocusedElement);
void dispatchFocusOutEvent(const AtomicString& eventType, Element* newFocusedElement);
@@ -399,14 +394,17 @@ public:
String outerHTML() const;
void setInnerHTML(const String&, ExceptionState&);
void setOuterHTML(const String&, ExceptionState&);
+
+ Element* insertAdjacentElement(const String& where, Element* newChild, ExceptionState&);
+ void insertAdjacentText(const String& where, const String& text, ExceptionState&);
void insertAdjacentHTML(const String& where, const String& html, ExceptionState&);
String textFromChildren();
virtual String title() const { return String(); }
- virtual const AtomicString& pseudo() const;
- void setPseudo(const AtomicString&);
+ virtual const AtomicString& shadowPseudoId() const;
+ void setShadowPseudoId(const AtomicString&);
LayoutSize minimumSizeForResizing() const;
void setMinimumSizeForResizing(const LayoutSize&);
@@ -414,27 +412,28 @@ public:
virtual void didBecomeFullscreenElement() { }
virtual void willStopBeingFullscreenElement() { }
- bool isFinishedParsingChildren() const { return isParsingChildrenFinished(); }
+ // Called by the parser when this element's close tag is reached,
+ // signaling that all child tags have been parsed and added.
+ // This is needed for <applet> and <object> elements, which can't lay themselves out
+ // until they know all of their nested <param>s. [Radar 3603191, 4040848].
+ // Also used for script elements and some SVG elements for similar purposes,
+ // but making parsing a special case in this respect should be avoided if possible.
virtual void finishParsingChildren();
- virtual void beginParsingChildren() OVERRIDE FINAL;
+
+ void beginParsingChildren() { setIsFinishedParsingChildren(false); }
PseudoElement* pseudoElement(PseudoId) const;
RenderObject* pseudoElementRenderer(PseudoId) const;
virtual bool matchesReadOnlyPseudoClass() const { return false; }
virtual bool matchesReadWritePseudoClass() const { return false; }
- bool webkitMatchesSelector(const String& selectors, ExceptionState&);
+ bool matches(const String& selectors, ExceptionState&);
virtual bool shouldAppearIndeterminate() const { return false; }
- DOMTokenList* classList();
+ DOMTokenList& classList();
- DOMStringMap* dataset();
+ DOMStringMap& dataset();
- virtual bool isMediaElement() const { return false; }
-
-#if ENABLE(INPUT_SPEECH)
- virtual bool isInputFieldSpeechButtonElement() const { return false; }
-#endif
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
virtual bool isDateTimeEditElement() const { return false; }
virtual bool isDateTimeFieldElement() const { return false; }
@@ -451,59 +450,46 @@ public:
virtual bool isValidFormControlElement() { return false; }
virtual bool isInRange() const { return false; }
virtual bool isOutOfRange() const { return false; }
- virtual bool isFrameElementBase() const { return false; }
- virtual bool isPasswordGeneratorButtonElement() const { return false; }
virtual bool isClearButtonElement() const { return false; }
- virtual bool canContainRangeEndPoint() const { return true; }
-
- virtual const AtomicString& formControlType() const { return nullAtom; }
-
- // FIXME: Only HTMLInputElement uses these, they don't need to be virtual.
- virtual bool wasChangedSinceLastFormControlChangeEvent() const { return false; }
- virtual void setChangedSinceLastFormControlChangeEvent(bool) { }
- virtual void dispatchFormControlChangeEvent() { }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return true; }
// Used for disabled form elements; if true, prevents mouse events from being dispatched
// to event listeners, and prevents DOMActivate events from being sent at all.
virtual bool isDisabledFormControl() const { return false; }
- virtual bool shouldBeReparentedUnderRenderView(const RenderStyle*) const { return isInTopLayer(); }
-
- virtual bool childShouldCreateRenderer(const Node& child) const;
- bool hasPendingResources() const;
- void setHasPendingResources();
- void clearHasPendingResources();
+ bool hasPendingResources() const { return hasElementFlag(HasPendingResources); }
+ void setHasPendingResources() { setElementFlag(HasPendingResources); }
+ void clearHasPendingResources() { clearElementFlag(HasPendingResources); }
virtual void buildPendingResource() { };
+ void setCustomElementDefinition(PassRefPtr<CustomElementDefinition>);
+ CustomElementDefinition* customElementDefinition() const;
+
enum {
ALLOW_KEYBOARD_INPUT = 1 << 0,
LEGACY_MOZILLA_REQUEST = 1 << 1,
};
void webkitRequestFullScreen(unsigned short flags);
- bool containsFullScreenElement() const;
+ bool containsFullScreenElement() const { return hasElementFlag(ContainsFullScreenElement); }
void setContainsFullScreenElement(bool);
void setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(bool);
// W3C API
void webkitRequestFullscreen();
- bool isInTopLayer() const;
+ bool isInTopLayer() const { return hasElementFlag(IsInTopLayer); }
void setIsInTopLayer(bool);
void webkitRequestPointerLock();
+ void requestPointerLock();
bool isSpellCheckingEnabled() const;
- // FIXME: public for NodeRenderingContext, we shouldn't expose this though.
+ // FIXME: public for RenderTreeBuilder, we shouldn't expose this though.
PassRefPtr<RenderStyle> styleForRenderer();
- RenderRegion* renderRegion() const;
- virtual bool shouldMoveToFlowThread(RenderStyle*) const;
- const AtomicString& webkitRegionOverset() const;
- Vector<RefPtr<Range> > webkitGetRegionFlowRanges() const;
-
bool hasID() const;
bool hasClass() const;
const SpaceSplitString& classNames() const;
@@ -512,36 +498,34 @@ public:
void setSavedLayerScrollOffset(const IntSize&);
ActiveAnimations* activeAnimations() const;
- ActiveAnimations* ensureActiveAnimations();
+ ActiveAnimations& ensureActiveAnimations();
bool hasActiveAnimations() const;
- InputMethodContext* inputMethodContext();
+ InputMethodContext& inputMethodContext();
bool hasInputMethodContext() const;
- virtual void setPrefix(const AtomicString&, ExceptionState&) OVERRIDE FINAL;
+ void setPrefix(const AtomicString&, ExceptionState&);
void synchronizeAttribute(const AtomicString& localName) const;
- bool needsPseudoElement(PseudoId, const RenderStyle&) const;
+ MutableStylePropertySet& ensureMutableInlineStyle();
+ void clearMutableInlineStyleIfEmpty();
+
+ void setTabIndex(int);
+ virtual short tabIndex() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
protected:
- Element(const QualifiedName& tagName, Document* document, ConstructionType type)
- : ContainerNode(document, type)
- , m_tagName(tagName)
- {
- ScriptWrappable::init(this);
- }
+ Element(const QualifiedName& tagName, Document*, ConstructionType);
void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, CSSValueID identifier);
- void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, double value, CSSPrimitiveValue::UnitTypes);
+ void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, double value, CSSPrimitiveValue::UnitType);
void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, const String& value);
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void removeAllEventListeners() OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange);
virtual void didRecalcStyle(StyleRecalcChange);
@@ -550,16 +534,17 @@ protected:
virtual bool shouldRegisterAsNamedItem() const { return false; }
virtual bool shouldRegisterAsExtraNamedItem() const { return false; }
+ virtual bool supportsSpatialNavigationFocus() const;
+
void clearTabIndexExplicitlyIfNeeded();
void setTabIndexExplicitly(short);
- virtual short tabIndex() const OVERRIDE;
// Subclasses may override this method to affect focusability. Unlike
// supportsFocus, this method must be called on an up-to-date layout, so it
// may use the renderer to reason about focusability. This method cannot be
// moved to RenderObject because some focusable nodes don't have renderers,
// e.g., HTMLOptionElement.
virtual bool rendererIsFocusable() const;
- PassRefPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
+ PassRefPtrWillBeRawPtr<HTMLCollection> ensureCachedHTMLCollection(CollectionType);
HTMLCollection* cachedHTMLCollection(CollectionType);
// classAttributeChanged() exists to share code between
@@ -572,6 +557,11 @@ protected:
Node* insertAdjacent(const String& where, Node* newChild, ExceptionState&);
private:
+ bool hasElementFlag(ElementFlags mask) const { return hasRareData() && hasElementFlagInternal(mask); }
+ void setElementFlag(ElementFlags, bool value = true);
+ void clearElementFlag(ElementFlags);
+ bool hasElementFlagInternal(ElementFlags) const;
+
void styleAttributeChanged(const AtomicString& newStyleString, AttributeModificationReason);
void updatePresentationAttributeStyle();
@@ -579,16 +569,11 @@ private:
void inlineStyleChanged();
PropertySetCSSStyleDeclaration* inlineStyleCSSOMWrapper();
void setInlineStyleFromString(const AtomicString&);
- MutableStylePropertySet* ensureMutableInlineStyle();
StyleRecalcChange recalcOwnStyle(StyleRecalcChange);
void recalcChildStyle(StyleRecalcChange);
- // FIXME: These methods should all be renamed to something better than "check",
- // since it's not clear that they alter the style bits of siblings and children.
- void checkForChildrenAdjacentRuleChanges();
- void checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta);
- inline void checkForEmptyStyleChange(RenderStyle*);
+ inline void checkForEmptyStyleChange();
void updatePseudoElement(PseudoId, StyleRecalcChange);
@@ -622,19 +607,19 @@ private:
virtual bool childTypeAllowed(NodeType) const OVERRIDE FINAL;
void setAttributeInternal(size_t index, const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
- void addAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
+ void appendAttributeInternal(const QualifiedName&, const AtomicString& value, SynchronizationOfLazyAttribute);
void removeAttributeInternal(size_t index, SynchronizationOfLazyAttribute);
void attributeChangedFromParserOrByCloning(const QualifiedName&, const AtomicString&, AttributeModificationReason);
#ifndef NDEBUG
- virtual void formatForDebugger(char* buffer, unsigned length) const;
+ virtual void formatForDebugger(char* buffer, unsigned length) const OVERRIDE;
#endif
bool pseudoStyleCacheIsInvalid(const RenderStyle* currentStyle, RenderStyle* newStyle);
void cancelFocusAppearanceUpdate();
- virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return computedStyle(pseudoElementSpecifier); }
+ virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) OVERRIDE { return computedStyle(pseudoElementSpecifier); }
inline void updateCallbackSelectors(RenderStyle* oldStyle, RenderStyle* newStyle);
inline void removeCallbackSelectors();
@@ -642,29 +627,16 @@ private:
// cloneNode is private so that non-virtual cloneElementWithChildren and cloneElementWithoutChildren
// are used instead.
- virtual PassRefPtr<Node> cloneNode(bool deep) OVERRIDE;
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren();
QualifiedName m_tagName;
- bool rareDataStyleAffectedByEmpty() const;
- bool rareDataChildrenAffectedByFocus() const;
- bool rareDataChildrenAffectedByHover() const;
- bool rareDataChildrenAffectedByActive() const;
- bool rareDataChildrenAffectedByDrag() const;
- bool rareDataChildrenAffectedByFirstChildRules() const;
- bool rareDataChildrenAffectedByLastChildRules() const;
- bool rareDataChildrenAffectedByDirectAdjacentRules() const;
- bool rareDataChildrenAffectedByForwardPositionalRules() const;
- bool rareDataChildrenAffectedByBackwardPositionalRules() const;
- unsigned rareDataChildIndex() const;
SpellcheckAttributeState spellcheckAttributeState() const;
void updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
void updateExtraNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName);
- void unregisterNamedFlowContentNode();
-
void createUniqueElementData();
bool shouldInvalidateDistributionWhenAttributeChanged(ElementShadow*, const QualifiedName&, const AtomicString&);
@@ -672,6 +644,8 @@ private:
ElementRareData* elementRareData() const;
ElementRareData& ensureElementRareData();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >& ensureAttrNodeList();
+ void removeAttrNodeList();
void detachAllAttrNodesFromElement();
void detachAttrNodeFromElementWithValue(Attr*, const AtomicString& value);
void detachAttrNodeAtIndex(Attr*, size_t index);
@@ -682,6 +656,32 @@ private:
};
DEFINE_NODE_TYPE_CASTS(Element, isElementNode());
+template <typename T> bool isElementOfType(const Element&);
+template <typename T> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const T>(toElement(node)); }
+template <> inline bool isElementOfType<const Element>(const Element&) { return true; }
+
+// Type casting.
+template<typename T> inline T& toElement(Node& node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
+ return static_cast<T&>(node);
+}
+template<typename T> inline T* toElement(Node* node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
+ return static_cast<T*>(node);
+}
+template<typename T> inline const T& toElement(const Node& node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
+ return static_cast<const T&>(node);
+}
+template<typename T> inline const T* toElement(const Node* node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
+ return static_cast<const T*>(node);
+}
+template<typename T, typename U> inline T* toElement(const RefPtr<U>& node) { return toElement<T>(node.get()); }
inline bool isDisabledFormControl(const Node* node)
{
@@ -699,33 +699,17 @@ inline Element* Node::parentElement() const
return parent && parent->isElementNode() ? toElement(parent) : 0;
}
-inline Element* Node::previousElementSibling() const
-{
- Node* n = previousSibling();
- while (n && !n->isElementNode())
- n = n->previousSibling();
- return toElement(n);
-}
-
-inline Element* Node::nextElementSibling() const
-{
- Node* n = nextSibling();
- while (n && !n->isElementNode())
- n = n->nextSibling();
- return toElement(n);
-}
-
inline bool Element::fastHasAttribute(const QualifiedName& name) const
{
ASSERT(fastAttributeLookupAllowed(name));
- return elementData() && getAttributeItem(name);
+ return elementData() && findAttributeByName(name);
}
inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name) const
{
ASSERT(fastAttributeLookupAllowed(name));
if (elementData()) {
- if (const Attribute* attribute = getAttributeItem(name))
+ if (const Attribute* attribute = findAttributeByName(name))
return attribute->value();
}
return nullAtom;
@@ -733,7 +717,7 @@ inline const AtomicString& Element::fastGetAttribute(const QualifiedName& name)
inline bool Element::hasAttributesWithoutUpdate() const
{
- return elementData() && !elementData()->isEmpty();
+ return elementData() && elementData()->hasAttributes();
}
inline const AtomicString& Element::idForStyleResolution() const
@@ -742,23 +726,18 @@ inline const AtomicString& Element::idForStyleResolution() const
return elementData()->idForStyleResolution();
}
-inline const AtomicString& Element::shadowPseudoId() const
-{
- return pseudo();
-}
-
inline bool Element::isIdAttributeName(const QualifiedName& attributeName) const
{
// FIXME: This check is probably not correct for the case where the document has an id attribute
// with a non-null namespace, because it will return false, a false negative, if the prefixes
// don't match but the local name and namespace both do. However, since this has been like this
// for a while and the code paths may be hot, we'll have to measure performance if we fix it.
- return attributeName == document().idAttributeName();
+ return attributeName == HTMLNames::idAttr;
}
inline const AtomicString& Element::getIdAttribute() const
{
- return hasID() ? fastGetAttribute(document().idAttributeName()) : nullAtom;
+ return hasID() ? fastGetAttribute(HTMLNames::idAttr) : nullAtom;
}
inline const AtomicString& Element::getNameAttribute() const
@@ -775,14 +754,9 @@ inline const AtomicString& Element::getClassAttribute() const
return fastGetAttribute(HTMLNames::classAttr);
}
-inline bool Element::shouldIgnoreAttributeCase() const
-{
- return isHTMLElement() && document().isHTMLDocument();
-}
-
inline void Element::setIdAttribute(const AtomicString& value)
{
- setAttribute(document().idAttributeName(), value);
+ setAttribute(HTMLNames::idAttr, value);
}
inline const SpaceSplitString& Element::classNames() const
@@ -795,19 +769,19 @@ inline const SpaceSplitString& Element::classNames() const
inline size_t Element::attributeCount() const
{
ASSERT(elementData());
- return elementData()->length();
+ return elementData()->attributeCount();
}
-inline const Attribute* Element::attributeItem(unsigned index) const
+inline const Attribute& Element::attributeAt(unsigned index) const
{
ASSERT(elementData());
- return elementData()->attributeItem(index);
+ return elementData()->attributeAt(index);
}
-inline const Attribute* Element::getAttributeItem(const QualifiedName& name) const
+inline const Attribute* Element::findAttributeByName(const QualifiedName& name) const
{
ASSERT(elementData());
- return elementData()->getAttributeItem(name);
+ return elementData()->findAttributeByName(name);
}
inline bool Element::hasID() const
@@ -820,11 +794,11 @@ inline bool Element::hasClass() const
return elementData() && elementData()->hasClass();
}
-inline UniqueElementData* Element::ensureUniqueElementData()
+inline UniqueElementData& Element::ensureUniqueElementData()
{
if (!elementData() || !elementData()->isUnique())
createUniqueElementData();
- return static_cast<UniqueElementData*>(m_elementData.get());
+ return static_cast<UniqueElementData&>(*m_elementData);
}
// Put here to make them inline.
@@ -840,6 +814,8 @@ inline bool Node::hasClass() const
inline Node::InsertionNotificationRequest Node::insertedInto(ContainerNode* insertionPoint)
{
+ ASSERT(!childNeedsStyleInvalidation());
+ ASSERT(!needsStyleInvalidation());
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
setFlag(InDocumentFlag);
@@ -855,7 +831,7 @@ inline void Node::removedFrom(ContainerNode* insertionPoint)
ASSERT(insertionPoint->inDocument() || isContainerNode());
if (insertionPoint->inDocument())
clearFlag(InDocumentFlag);
- if (isInShadowTree() && !treeScope().rootNode()->isShadowRoot())
+ if (isInShadowTree() && !treeScope().rootNode().isShadowRoot())
clearFlag(IsInShadowTreeFlag);
}
@@ -894,6 +870,24 @@ inline bool isShadowHost(const Element* element)
return element && element->shadow();
}
+// These macros do the same as their NODE equivalents but additionally provide a template specialization
+// for isElementOfType<>() so that the Traversal<> API works for these Element types.
+#define DEFINE_ELEMENT_TYPE_CASTS(thisType, predicate) \
+ template <> inline bool isElementOfType<const thisType>(const Element& element) { return element.predicate; } \
+ DEFINE_NODE_TYPE_CASTS(thisType, predicate)
+
+#define DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
+ template <> inline bool isElementOfType<const thisType>(const Element& element) { return is##thisType(element); } \
+ DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType)
+
+#define DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(T) \
+ static PassRefPtrWillBeRawPtr<T> create(const QualifiedName&, Document&)
+#define DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(T) \
+ PassRefPtrWillBeRawPtr<T> T::create(const QualifiedName& tagName, Document& document) \
+ { \
+ return adoptRefWillBeNoop(new T(tagName, document)); \
+ }
+
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Element.idl b/chromium/third_party/WebKit/Source/core/dom/Element.idl
index ac5003883ee..b4f745d34bf 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Element.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Element.idl
@@ -19,33 +19,33 @@
*/
[
- SpecialWrapFor=HTMLElement|SVGElement
+ SpecialWrapFor=HTMLElement|SVGElement,
] interface Element : Node {
// DOM Level 1 Core
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString tagName;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString tagName;
[TreatReturnedNullStringAs=Null] DOMString getAttribute(DOMString name);
[RaisesException, CustomElementCallbacks] void setAttribute(DOMString name, DOMString value);
[CustomElementCallbacks] void removeAttribute(DOMString name);
[MeasureAs=ElementGetAttributeNode] Attr getAttributeNode([Default=Undefined] optional DOMString name); // Removed from DOM4.
- [RaisesException, CustomElementCallbacks, MeasureAs=ElementSetAttributeNode] Attr setAttributeNode([Default=Undefined, StrictTypeChecking] optional Attr newAttr); // Removed from DOM4.
- [RaisesException, CustomElementCallbacks, MeasureAs=ElementRemoveAttributeNode] Attr removeAttributeNode([Default=Undefined, StrictTypeChecking] optional Attr oldAttr); // Removed from DOM4.
- [PerWorldBindings] NodeList getElementsByTagName(DOMString name);
+ [RaisesException, CustomElementCallbacks, MeasureAs=ElementSetAttributeNode] Attr setAttributeNode([Default=Undefined, TypeChecking=Nullable] optional Attr newAttr); // Removed from DOM4.
+ [RaisesException, CustomElementCallbacks, MeasureAs=ElementRemoveAttributeNode] Attr removeAttributeNode([Default=Undefined, TypeChecking=Nullable] optional Attr oldAttr); // Removed from DOM4.
+ HTMLCollection getElementsByTagName(DOMString name);
- [PerWorldBindings] readonly attribute NamedNodeMap attributes;
+ [PerWorldBindings, ImplementedAs=attributesForBindings] readonly attribute NamedNodeMap attributes;
[MeasureAs=HasAttributes] boolean hasAttributes();
// DOM Level 2 Core
- DOMString getAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
+ [TreatReturnedNullStringAs=Null] DOMString getAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
[RaisesException, CustomElementCallbacks] void setAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString qualifiedName, DOMString value);
[CustomElementCallbacks] void removeAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
- NodeList getElementsByTagNameNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
- [MeasureAs=ElementGetAttributeNodeNS] Attr getAttributeNodeNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
+ HTMLCollection getElementsByTagNameNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
+ [MeasureAs=ElementGetAttributeNodeNS] Attr getAttributeNodeNS([TreatNullAs=NullString, Default=Undefined] optional DOMString namespaceURI,
[Default=Undefined] optional DOMString localName); // Removed from DOM4.
- [RaisesException, CustomElementCallbacks, MeasureAs=ElementSetAttributeNodeNS] Attr setAttributeNodeNS([Default=Undefined, StrictTypeChecking] optional Attr newAttr); // Removed from DOM4.
+ [RaisesException, CustomElementCallbacks, DeprecateAs=ElementSetAttributeNodeNS] Attr setAttributeNodeNS([Default=Undefined, TypeChecking=Nullable] optional Attr newAttr); // Removed from DOM4.
boolean hasAttribute(DOMString name);
boolean hasAttributeNS([TreatNullAs=NullString] DOMString namespaceURI, DOMString localName);
@@ -53,25 +53,32 @@
// DOM4
[Reflect] attribute DOMString id;
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString namespaceURI;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, RaisesException=Setter] attribute DOMString prefix;
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString localName;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString namespaceURI;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, RaisesException=Setter] attribute DOMString prefix;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString localName;
+
+ [RaisesException] boolean matches(DOMString selectors);
// Common extensions
- [PerWorldBindings] readonly attribute long offsetLeft;
- [PerWorldBindings] readonly attribute long offsetTop;
- [PerWorldBindings] readonly attribute long offsetWidth;
- [PerWorldBindings] readonly attribute long offsetHeight;
- [ImplementedAs=bindingsOffsetParent, PerWorldBindings] readonly attribute Element offsetParent;
- [PerWorldBindings] readonly attribute long clientLeft;
- [PerWorldBindings] readonly attribute long clientTop;
- [PerWorldBindings] readonly attribute long clientWidth;
- [PerWorldBindings] readonly attribute long clientHeight;
- [PerWorldBindings] attribute long scrollLeft;
- [PerWorldBindings] attribute long scrollTop;
- [PerWorldBindings] readonly attribute long scrollWidth;
- [PerWorldBindings] readonly attribute long scrollHeight;
+ readonly attribute long offsetLeft;
+ readonly attribute long offsetTop;
+ readonly attribute long offsetWidth;
+ readonly attribute long offsetHeight;
+ [ImplementedAs=offsetParentForBindings, PerWorldBindings] readonly attribute Element offsetParent;
+ readonly attribute long clientLeft;
+ readonly attribute long clientTop;
+ readonly attribute long clientWidth;
+ readonly attribute long clientHeight;
+
+ // FIXME: should be:
+ // attribute (Dictionary or double) scrollLeft;
+ // attribute (Dictionary or double) scrollTop;
+ // http://crbug.com/240176
+ [Custom=Setter] attribute long scrollLeft;
+ [Custom=Setter] attribute long scrollTop;
+ readonly attribute long scrollWidth;
+ readonly attribute long scrollHeight;
void focus();
void blur();
@@ -79,38 +86,31 @@
// WebKit extensions
- void scrollIntoViewIfNeeded(optional boolean centerIfNeeded);
- void scrollByLines([Default=Undefined] optional long lines);
- void scrollByPages([Default=Undefined] optional long pages);
+ [MeasureAs=ElementScrollIntoViewIfNeeded] void scrollIntoViewIfNeeded(optional boolean centerIfNeeded);
+ [MeasureAs=ElementScrollByLines] void scrollByLines([Default=Undefined] optional long lines);
+ [MeasureAs=ElementScrollByPages] void scrollByPages([Default=Undefined] optional long pages);
// HTML 5
- NodeList getElementsByClassName(DOMString classNames);
- [TreatNullAs=NullString, CustomElementCallbacks, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds, RaisesException=Setter] attribute DOMString innerHTML;
+ HTMLCollection getElementsByClassName(DOMString classNames);
+ [TreatNullAs=NullString, CustomElementCallbacks, PerWorldBindings, LogActivity=SetterOnly, RaisesException=Setter] attribute DOMString innerHTML;
[TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter] attribute DOMString outerHTML;
- [CustomElementCallbacks, RaisesException] void insertAdjacentHTML(DOMString where, DOMString html);
- [Reflect=class, PerWorldBindings] attribute DOMString className;
+ [RaisesException, CustomElementCallbacks, MeasureAs=InsertAdjacentElement] Element insertAdjacentElement(DOMString where, Element element);
+ [RaisesException, MeasureAs=InsertAdjacentText] void insertAdjacentText(DOMString where, DOMString text);
+ [CustomElementCallbacks, RaisesException, MeasureAs=InsertAdjacentHTML] void insertAdjacentHTML(DOMString where, DOMString html);
+
+ [Reflect=class] attribute DOMString className;
[PerWorldBindings] readonly attribute DOMTokenList classList;
[PerWorldBindings] readonly attribute DOMStringMap dataset;
- // NodeSelector - Selector API
- [RaisesException] Element querySelector(DOMString selectors);
- [RaisesException] NodeList querySelectorAll(DOMString selectors);
-
// WebKit extension
- [RaisesException, MeasureAs=ElementPrefixedMatchesSelector] boolean webkitMatchesSelector([Default=Undefined] optional DOMString selectors);
+ [RaisesException, ImplementedAs=matches, MeasureAs=ElementPrefixedMatchesSelector] boolean webkitMatchesSelector(DOMString selectors);
// Shadow DOM API
- [RuntimeEnabled=ShadowDOM, Reflect, TreatNullAs=NullString, PerWorldBindings] attribute DOMString pseudo;
- [RuntimeEnabled=ShadowDOM, RaisesException] ShadowRoot createShadowRoot();
- [RuntimeEnabled=ShadowDOM, PerWorldBindings] readonly attribute ShadowRoot shadowRoot;
- [RuntimeEnabled=ShadowDOM, PerWorldBindings] NodeList getDestinationInsertionPoints();
-
- // To-be-deprecated prefixed Shadow DOM API
- [Reflect=pseudo, TreatNullAs=NullString, ImplementedAs=pseudo, PerWorldBindings, MeasureAs=ShadowDOMPrefixedPseudo] attribute DOMString webkitPseudo;
- [ImplementedAs=createShadowRoot, RaisesException, MeasureAs=ShadowDOMPrefixedCreateShadowRoot] ShadowRoot webkitCreateShadowRoot();
- [ImplementedAs=shadowRoot, PerWorldBindings, MeasureAs=ShadowDOMPrefixedShadowRoot] readonly attribute ShadowRoot webkitShadowRoot;
+ [RaisesException, MeasureAs=ElementCreateShadowRoot] ShadowRoot createShadowRoot();
+ [PerWorldBindings] readonly attribute ShadowRoot shadowRoot;
+ NodeList getDestinationInsertionPoints();
// CSSOM View Module API
ClientRectList getClientRects();
@@ -118,16 +118,13 @@
// Mozilla version
const unsigned short ALLOW_KEYBOARD_INPUT = 1;
- [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=ForAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
+ [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
// W3C version
- [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=ForAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen();
-
- void webkitRequestPointerLock();
+ [LogActivity, LogAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen();
- // CSS Regions API
- [RuntimeEnabled=CSSRegions, PerWorldBindings] readonly attribute DOMString webkitRegionOverset;
- [RuntimeEnabled=CSSRegions] sequence<Range> webkitGetRegionFlowRanges();
+ [MeasureAs=PrefixedElementRequestPointerLock] void webkitRequestPointerLock();
+ [MeasureAs=ElementRequestPointerLock] void requestPointerLock();
// Event handler attributes
attribute EventHandler onbeforecopy;
@@ -144,7 +141,7 @@
[RuntimeEnabled=Touch] attribute EventHandler ontouchstart;
attribute EventHandler onwebkitfullscreenchange;
attribute EventHandler onwebkitfullscreenerror;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onwheel;
+ [LogActivity=SetterOnly] attribute EventHandler onwheel;
};
Element implements ParentNode;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementData.cpp b/chromium/third_party/WebKit/Source/core/dom/ElementData.cpp
index 2ce4aa0413a..77428a688ea 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementData.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementData.cpp
@@ -70,7 +70,7 @@ ElementData::ElementData(unsigned arraySize)
ElementData::ElementData(const ElementData& other, bool isUnique)
: m_isUnique(isUnique)
- , m_arraySize(isUnique ? 0 : other.length())
+ , m_arraySize(isUnique ? 0 : other.attributeCount())
, m_presentationAttributeStyleIsDirty(other.m_presentationAttributeStyleIsDirty)
, m_styleAttributeIsDirty(other.m_styleAttributeIsDirty)
, m_animatedSVGAttributesAreDirty(other.m_animatedSVGAttributesAreDirty)
@@ -98,48 +98,52 @@ PassRefPtr<UniqueElementData> ElementData::makeUniqueCopy() const
bool ElementData::isEquivalent(const ElementData* other) const
{
if (!other)
- return isEmpty();
+ return !hasAttributes();
- unsigned len = length();
- if (len != other->length())
+ AttributeCollection attributes = this->attributes();
+ if (attributes.size() != other->attributeCount())
return false;
- for (unsigned i = 0; i < len; i++) {
- const Attribute* attribute = attributeItem(i);
- const Attribute* otherAttr = other->getAttributeItem(attribute->name());
- if (!otherAttr || attribute->value() != otherAttr->value())
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ const Attribute* otherAttr = other->findAttributeByName(it->name());
+ if (!otherAttr || it->value() != otherAttr->value())
return false;
}
-
return true;
}
-size_t ElementData::getAttrIndex(Attr* attr) const
+size_t ElementData::findAttrNodeIndex(Attr* attr) const
{
// This relies on the fact that Attr's QualifiedName == the Attribute's name.
- for (unsigned i = 0; i < length(); ++i) {
- if (attributeItem(i)->name() == attr->qualifiedName())
- return i;
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ unsigned index = 0;
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
+ if (it->name() == attr->qualifiedName())
+ return index;
}
return kNotFound;
}
-size_t ElementData::getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+size_t ElementData::findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
// Continue to checking case-insensitively and/or full namespaced names if necessary:
- for (unsigned i = 0; i < length(); ++i) {
- const Attribute* attribute = attributeItem(i);
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ unsigned index = 0;
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
// FIXME: Why check the prefix? Namespace is all that should matter
// and all HTML/SVG attributes have a null namespace!
- if (!attribute->name().hasPrefix()) {
- if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute->localName()))
- return i;
+ if (!it->name().hasPrefix()) {
+ if (shouldIgnoreAttributeCase && equalIgnoringCase(name, it->localName()))
+ return index;
} else {
// FIXME: Would be faster to do this comparison without calling toString, which
// generates a temporary string by concatenation. But this branch is only reached
// if the attribute name has a prefix, which is rare in HTML.
- if (equalPossiblyIgnoringCase(name, attribute->name().toString(), shouldIgnoreAttributeCase))
- return i;
+ if (equalPossiblyIgnoringCase(name, it->name().toString(), shouldIgnoreAttributeCase))
+ return index;
}
}
return kNotFound;
@@ -164,7 +168,6 @@ ShareableElementData::ShareableElementData(const UniqueElementData& other)
ASSERT(!other.m_presentationAttributeStyle);
if (other.m_inlineStyle) {
- ASSERT(!other.m_inlineStyle->hasCSSOMWrapper());
m_inlineStyle = other.m_inlineStyle->immutableCopyIfNeeded();
}
@@ -187,7 +190,7 @@ UniqueElementData::UniqueElementData(const UniqueElementData& other)
, m_presentationAttributeStyle(other.m_presentationAttributeStyle)
, m_attributeVector(other.m_attributeVector)
{
- m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
+ m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : nullptr;
}
UniqueElementData::UniqueElementData(const ShareableElementData& other)
@@ -197,8 +200,9 @@ UniqueElementData::UniqueElementData(const ShareableElementData& other)
ASSERT(!other.m_inlineStyle || !other.m_inlineStyle->isMutable());
m_inlineStyle = other.m_inlineStyle;
- m_attributeVector.reserveCapacity(other.length());
- for (unsigned i = 0; i < other.length(); ++i)
+ unsigned length = other.attributeCount();
+ m_attributeVector.reserveCapacity(length);
+ for (unsigned i = 0; i < length; ++i)
m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
}
@@ -213,9 +217,10 @@ PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const
return adoptRef(new (slot) ShareableElementData(*this));
}
-Attribute* UniqueElementData::getAttributeItem(const QualifiedName& name)
+Attribute* UniqueElementData::findAttributeByName(const QualifiedName& name)
{
- for (unsigned i = 0; i < length(); ++i) {
+ unsigned length = m_attributeVector.size();
+ for (unsigned i = 0; i < length; ++i) {
if (m_attributeVector.at(i).name().matches(name))
return &m_attributeVector.at(i);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementData.h b/chromium/third_party/WebKit/Source/core/dom/ElementData.h
index 2426667d6c2..0a8cc6202a0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementData.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -42,6 +43,27 @@ class ShareableElementData;
class StylePropertySet;
class UniqueElementData;
+class AttributeCollection {
+public:
+ typedef const Attribute* const_iterator;
+
+ AttributeCollection(const Attribute* array, unsigned size)
+ : m_array(array)
+ , m_size(size)
+ { }
+
+ const_iterator begin() const { return m_array; }
+ const_iterator end() const { return m_array + m_size; }
+
+ unsigned size() const { return m_size; }
+
+private:
+ const Attribute* m_array;
+ unsigned m_size;
+};
+
+// ElementData represents very common, but not necessarily unique to an element,
+// data such as attributes, inline style, and parsed class names and ids.
class ElementData : public RefCounted<ElementData> {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -60,14 +82,17 @@ public:
const StylePropertySet* presentationAttributeStyle() const;
- size_t length() const;
- bool isEmpty() const { return !length(); }
+ // This is not a trivial getter and its return value should be cached for performance.
+ size_t attributeCount() const;
+ bool hasAttributes() const { return !!attributeCount(); }
+
+ AttributeCollection attributes() const;
- const Attribute* attributeItem(unsigned index) const;
- const Attribute* getAttributeItem(const QualifiedName&) const;
- size_t getAttributeItemIndex(const QualifiedName&, bool shouldIgnoreCase = false) const;
- size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
- size_t getAttrIndex(Attr*) const;
+ const Attribute& attributeAt(unsigned index) const;
+ const Attribute* findAttributeByName(const QualifiedName&) const;
+ size_t findAttributeIndexByName(const QualifiedName&, bool shouldIgnoreCase = false) const;
+ size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ size_t findAttrNodeIndex(Attr*) const;
bool hasID() const { return !m_idForStyleResolution.isNull(); }
bool hasClass() const { return !m_classNames.isNull(); }
@@ -81,6 +106,7 @@ protected:
explicit ElementData(unsigned arraySize);
ElementData(const ElementData&, bool isUnique);
+ // Keep the type in a bitfield instead of using virtual destructors to avoid adding a vtable.
unsigned m_isUnique : 1;
unsigned m_arraySize : 28;
mutable unsigned m_presentationAttributeStyleIsDirty : 1;
@@ -100,8 +126,8 @@ private:
void destroy();
const Attribute* attributeBase() const;
- const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
- size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ const Attribute* findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
+ size_t findAttributeIndexByNameSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
PassRefPtr<UniqueElementData> makeUniqueCopy() const;
};
@@ -111,7 +137,11 @@ private:
#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
#endif
-class ShareableElementData : public ElementData {
+// SharableElementData is managed by ElementDataCache and is produced by
+// the parser during page load for elements that have identical attributes. This
+// is a memory optimization since it's very common for many elements to have
+// duplicate sets of attributes (ex. the same classes).
+class ShareableElementData FINAL : public ElementData {
public:
static PassRefPtr<ShareableElementData> createWithAttributes(const Vector<Attribute>&);
@@ -126,22 +156,32 @@ public:
#pragma warning(pop)
#endif
-class UniqueElementData : public ElementData {
+// UniqueElementData is created when an element needs to mutate its attributes
+// or gains presentation attribute style (ex. width="10"). It does not need to
+// be created to fill in values in the ElementData that are derived from
+// attributes. For example populating the m_inlineStyle from the style attribute
+// doesn't require a UniqueElementData as all elements with the same style
+// attribute will have the same inline style.
+class UniqueElementData FINAL : public ElementData {
public:
static PassRefPtr<UniqueElementData> create();
PassRefPtr<ShareableElementData> makeShareableCopy() const;
// These functions do no error/duplicate checking.
- void addAttribute(const QualifiedName&, const AtomicString&);
- void removeAttribute(size_t index);
+ void appendAttribute(const QualifiedName&, const AtomicString&);
+ void removeAttributeAt(size_t index);
- Attribute* attributeItem(unsigned index);
- Attribute* getAttributeItem(const QualifiedName&);
+ Attribute& attributeAt(unsigned index);
+ Attribute* findAttributeByName(const QualifiedName&);
UniqueElementData();
explicit UniqueElementData(const ShareableElementData&);
explicit UniqueElementData(const UniqueElementData&);
+ // FIXME: We might want to support sharing element data for elements with
+ // presentation attribute style. Lots of table cells likely have the same
+ // attributes. Most modern pages don't use presentation attributes though
+ // so this might not make sense.
mutable RefPtr<StylePropertySet> m_presentationAttributeStyle;
Vector<Attribute, 4> m_attributeVector;
};
@@ -153,7 +193,7 @@ inline void ElementData::deref()
destroy();
}
-inline size_t ElementData::length() const
+inline size_t ElementData::attributeCount() const
{
if (isUnique())
return static_cast<const UniqueElementData*>(this)->m_attributeVector.size();
@@ -167,11 +207,11 @@ inline const StylePropertySet* ElementData::presentationAttributeStyle() const
return static_cast<const UniqueElementData*>(this)->m_presentationAttributeStyle.get();
}
-inline const Attribute* ElementData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+inline const Attribute* ElementData::findAttributeByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
- size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
+ size_t index = findAttributeIndexByName(name, shouldIgnoreAttributeCase);
if (index != kNotFound)
- return attributeItem(index);
+ return &attributeAt(index);
return 0;
}
@@ -182,76 +222,84 @@ inline const Attribute* ElementData::attributeBase() const
return static_cast<const ShareableElementData*>(this)->m_attributeArray;
}
-inline size_t ElementData::getAttributeItemIndex(const QualifiedName& name, bool shouldIgnoreCase) const
+inline size_t ElementData::findAttributeIndexByName(const QualifiedName& name, bool shouldIgnoreCase) const
{
- const Attribute* begin = attributeBase();
- // Cache length for performance as ElementData::length() contains a conditional branch.
- unsigned len = length();
- for (unsigned i = 0; i < len; ++i) {
- const Attribute& attribute = begin[i];
- if (attribute.name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
- return i;
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ unsigned index = 0;
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
+ if (it->name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
+ return index;
}
return kNotFound;
}
// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
// can tune the behavior (hasAttribute is case sensitive whereas getAttribute is not).
-inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
+inline size_t ElementData::findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreAttributeCase) const
{
- // Cache length for performance as ElementData::length() contains a conditional branch.
- unsigned len = length();
bool doSlowCheck = shouldIgnoreAttributeCase;
// Optimize for the case where the attribute exists and its name exactly matches.
- const Attribute* begin = attributeBase();
- for (unsigned i = 0; i < len; ++i) {
- const Attribute& attribute = begin[i];
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ unsigned index = 0;
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it, ++index) {
// FIXME: Why check the prefix? Namespaces should be all that matter.
// Most attributes (all of HTML and CSS) have no namespace.
- if (!attribute.name().hasPrefix()) {
- if (name == attribute.localName())
- return i;
+ if (!it->name().hasPrefix()) {
+ if (name == it->localName())
+ return index;
} else {
doSlowCheck = true;
}
}
if (doSlowCheck)
- return getAttributeItemIndexSlowCase(name, shouldIgnoreAttributeCase);
+ return findAttributeIndexByNameSlowCase(name, shouldIgnoreAttributeCase);
return kNotFound;
}
-inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name) const
+inline AttributeCollection ElementData::attributes() const
+{
+ if (isUnique()) {
+ const Vector<Attribute, 4>& attributeVector = static_cast<const UniqueElementData*>(this)->m_attributeVector;
+ return AttributeCollection(attributeVector.data(), attributeVector.size());
+ }
+ return AttributeCollection(static_cast<const ShareableElementData*>(this)->m_attributeArray, m_arraySize);
+}
+
+inline const Attribute* ElementData::findAttributeByName(const QualifiedName& name) const
{
- const Attribute* begin = attributeBase();
- for (unsigned i = 0; i < length(); ++i) {
- const Attribute& attribute = begin[i];
- if (attribute.name().matches(name))
- return &attribute;
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->name().matches(name))
+ return it;
}
return 0;
}
-inline const Attribute* ElementData::attributeItem(unsigned index) const
+inline const Attribute& ElementData::attributeAt(unsigned index) const
{
- RELEASE_ASSERT(index < length());
- return attributeBase() + index;
+ RELEASE_ASSERT(index < attributeCount());
+ ASSERT(attributeBase() + index);
+ return *(attributeBase() + index);
}
-inline void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
+inline void UniqueElementData::appendAttribute(const QualifiedName& attributeName, const AtomicString& value)
{
m_attributeVector.append(Attribute(attributeName, value));
}
-inline void UniqueElementData::removeAttribute(size_t index)
+inline void UniqueElementData::removeAttributeAt(size_t index)
{
m_attributeVector.remove(index);
}
-inline Attribute* UniqueElementData::attributeItem(unsigned index)
+inline Attribute& UniqueElementData::attributeAt(unsigned index)
{
- return &m_attributeVector.at(index);
+ return m_attributeVector.at(index);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.cpp b/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.cpp
new file mode 100644
index 00000000000..9d0cbdad6c2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "core/dom/ElementDataCache.h"
+
+#include "core/dom/ElementData.h"
+
+namespace WebCore {
+
+inline unsigned attributeHash(const Vector<Attribute>& attributes)
+{
+ return StringHasher::hashMemory(attributes.data(), attributes.size() * sizeof(Attribute));
+}
+
+inline bool hasSameAttributes(const Vector<Attribute>& attributes, ShareableElementData& elementData)
+{
+ if (attributes.size() != elementData.attributeCount())
+ return false;
+ return !memcmp(attributes.data(), elementData.m_attributeArray, attributes.size() * sizeof(Attribute));
+}
+
+PassRefPtr<ShareableElementData> ElementDataCache::cachedShareableElementDataWithAttributes(const Vector<Attribute>& attributes)
+{
+ ASSERT(!attributes.isEmpty());
+
+ ShareableElementDataCache::ValueType* it = m_shareableElementDataCache.add(attributeHash(attributes), nullptr).storedValue;
+
+ // FIXME: This prevents sharing when there's a hash collision.
+ if (it->value && !hasSameAttributes(attributes, *it->value))
+ return ShareableElementData::createWithAttributes(attributes);
+
+ if (!it->value)
+ it->value = ShareableElementData::createWithAttributes(attributes);
+
+ return it->value.get();
+}
+
+ElementDataCache::ElementDataCache()
+{
+}
+
+ElementDataCache::~ElementDataCache()
+{
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.h b/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.h
new file mode 100644
index 00000000000..d275f1edd37
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementDataCache.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef ElementDataCache_h
+#define ElementDataCache_h
+
+#include "wtf/HashMap.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+class Attribute;
+class ShareableElementData;
+class ShareableElementDataCacheEntry;
+
+class ElementDataCache {
+public:
+ static PassOwnPtr<ElementDataCache> create() { return adoptPtr(new ElementDataCache); }
+ ~ElementDataCache();
+
+ PassRefPtr<ShareableElementData> cachedShareableElementDataWithAttributes(const Vector<Attribute>&);
+
+private:
+ ElementDataCache();
+
+ typedef HashMap<unsigned, RefPtr<ShareableElementData>, AlreadyHashed> ShareableElementDataCache;
+ ShareableElementDataCache m_shareableElementDataCache;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp b/chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp
index ef6d2c26fb7..30888559606 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementRareData.cpp
@@ -31,20 +31,49 @@
#include "config.h"
#include "core/dom/ElementRareData.h"
-#include "core/rendering/RegionOversetState.h"
#include "core/rendering/style/RenderStyle.h"
namespace WebCore {
struct SameSizeAsElementRareData : NodeRareData {
short indices[2];
- unsigned bitfields;
- RegionOversetState regionOversetState;
LayoutSize sizeForResizing;
IntSize scrollOffset;
- void* pointers[10];
+ void* pointers[13];
};
+CSSStyleDeclaration& ElementRareData::ensureInlineCSSStyleDeclaration(Element* ownerElement)
+{
+ if (!m_cssomWrapper)
+ m_cssomWrapper = adoptPtrWillBeNoop(new InlineCSSStyleDeclaration(ownerElement));
+ return *m_cssomWrapper;
+}
+
+WillBeHeapVector<RefPtrWillBeMember<Attr> >& ElementRareData::ensureAttrNodeList()
+{
+ if (!m_attrNodeList)
+ m_attrNodeList = adoptPtrWillBeNoop(new WillBeHeapVector<RefPtrWillBeMember<Attr> >());
+ return *m_attrNodeList;
+}
+
+void ElementRareData::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_dataset);
+ visitor->trace(m_classList);
+ visitor->trace(m_shadow);
+ visitor->trace(m_attributeMap);
+#if ENABLE(OILPAN)
+ visitor->trace(m_attrNodeList);
+#endif
+ visitor->trace(m_inputMethodContext);
+ visitor->trace(m_activeAnimations);
+ visitor->trace(m_cssomWrapper);
+ visitor->trace(m_generatedBefore);
+ visitor->trace(m_generatedAfter);
+ visitor->trace(m_backdrop);
+ NodeRareData::traceAfterDispatch(visitor);
+}
+
COMPILE_ASSERT(sizeof(ElementRareData) == sizeof(SameSizeAsElementRareData), ElementRareDataShouldStaySmall);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementRareData.h b/chromium/third_party/WebKit/Source/core/dom/ElementRareData.h
index a1879973aa5..ff28414a606 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementRareData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementRareData.h
@@ -23,14 +23,17 @@
#define ElementRareData_h
#include "core/animation/ActiveAnimations.h"
+#include "core/dom/Attr.h"
#include "core/dom/DatasetDOMStringMap.h"
#include "core/dom/NamedNodeMap.h"
#include "core/dom/NodeRareData.h"
#include "core/dom/PseudoElement.h"
+#include "core/dom/custom/CustomElementDefinition.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/html/ClassList.h"
#include "core/html/ime/InputMethodContext.h"
#include "core/rendering/style/StyleInheritedData.h"
+#include "platform/heap/Handle.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
@@ -39,63 +42,33 @@ class HTMLElement;
class ElementRareData : public NodeRareData {
public:
- static PassOwnPtr<ElementRareData> create(RenderObject* renderer) { return adoptPtr(new ElementRareData(renderer)); }
+ static ElementRareData* create(RenderObject* renderer)
+ {
+ return new ElementRareData(renderer);
+ }
~ElementRareData();
- void setPseudoElement(PseudoId, PassRefPtr<PseudoElement>);
+ void setPseudoElement(PseudoId, PassRefPtrWillBeRawPtr<PseudoElement>);
PseudoElement* pseudoElement(PseudoId) const;
void resetStyleState();
- void resetDynamicRestyleObservations();
-
- short tabIndex() const { return m_tabIndex; }
- void setTabIndexExplicitly(short index) { m_tabIndex = index; m_tabIndexWasSetExplicitly = true; }
- bool tabIndexSetExplicitly() const { return m_tabIndexWasSetExplicitly; }
- void clearTabIndexExplicitly() { m_tabIndex = 0; m_tabIndexWasSetExplicitly = false; }
-
- bool needsFocusAppearanceUpdateSoonAfterAttach() const { return m_needsFocusAppearanceUpdateSoonAfterAttach; }
- void setNeedsFocusAppearanceUpdateSoonAfterAttach(bool needs) { m_needsFocusAppearanceUpdateSoonAfterAttach = needs; }
-
- bool styleAffectedByEmpty() const { return m_styleAffectedByEmpty; }
- void setStyleAffectedByEmpty(bool value) { m_styleAffectedByEmpty = value; }
-
- bool isInCanvasSubtree() const { return m_isInCanvasSubtree; }
- void setIsInCanvasSubtree(bool value) { m_isInCanvasSubtree = value; }
-
- bool isInsideRegion() const { return m_isInsideRegion; }
- void setIsInsideRegion(bool value) { m_isInsideRegion = value; }
-
- RegionOversetState regionOversetState() const { return m_regionOversetState; }
- void setRegionOversetState(RegionOversetState state) { m_regionOversetState = state; }
-
- bool containsFullScreenElement() { return m_containsFullScreenElement; }
- void setContainsFullScreenElement(bool value) { m_containsFullScreenElement = value; }
-
- bool isInTopLayer() const { return m_isInTopLayer; }
- void setIsInTopLayer(bool value) { m_isInTopLayer = value; }
-
- bool childrenAffectedByFocus() const { return m_childrenAffectedByFocus; }
- void setChildrenAffectedByFocus(bool value) { m_childrenAffectedByFocus = value; }
- bool childrenAffectedByHover() const { return m_childrenAffectedByHover; }
- void setChildrenAffectedByHover(bool value) { m_childrenAffectedByHover = value; }
- bool childrenAffectedByActive() const { return m_childrenAffectedByActive; }
- void setChildrenAffectedByActive(bool value) { m_childrenAffectedByActive = value; }
- bool childrenAffectedByDrag() const { return m_childrenAffectedByDrag; }
- void setChildrenAffectedByDrag(bool value) { m_childrenAffectedByDrag = value; }
-
- bool childrenAffectedByFirstChildRules() const { return m_childrenAffectedByFirstChildRules; }
- void setChildrenAffectedByFirstChildRules(bool value) { m_childrenAffectedByFirstChildRules = value; }
- bool childrenAffectedByLastChildRules() const { return m_childrenAffectedByLastChildRules; }
- void setChildrenAffectedByLastChildRules(bool value) { m_childrenAffectedByLastChildRules = value; }
- bool childrenAffectedByDirectAdjacentRules() const { return m_childrenAffectedByDirectAdjacentRules; }
- void setChildrenAffectedByDirectAdjacentRules(bool value) { m_childrenAffectedByDirectAdjacentRules = value; }
- bool childrenAffectedByForwardPositionalRules() const { return m_childrenAffectedByForwardPositionalRules; }
- void setChildrenAffectedByForwardPositionalRules(bool value) { m_childrenAffectedByForwardPositionalRules = value; }
- bool childrenAffectedByBackwardPositionalRules() const { return m_childrenAffectedByBackwardPositionalRules; }
- void setChildrenAffectedByBackwardPositionalRules(bool value) { m_childrenAffectedByBackwardPositionalRules = value; }
- unsigned childIndex() const { return m_childIndex; }
- void setChildIndex(unsigned index) { m_childIndex = index; }
+
+ short tabIndex() const { return m_tabindex; }
+
+ void setTabIndexExplicitly(short index)
+ {
+ m_tabindex = index;
+ setElementFlag(TabIndexWasSetExplicitly, true);
+ }
+
+ void clearTabIndexExplicitly()
+ {
+ m_tabindex = 0;
+ clearElementFlag(TabIndexWasSetExplicitly);
+ }
+
+ CSSStyleDeclaration& ensureInlineCSSStyleDeclaration(Element* ownerElement);
void clearShadow() { m_shadow = nullptr; }
ElementShadow* shadow() const { return m_shadow.get(); }
@@ -107,14 +80,14 @@ public:
}
NamedNodeMap* attributeMap() const { return m_attributeMap.get(); }
- void setAttributeMap(PassOwnPtr<NamedNodeMap> attributeMap) { m_attributeMap = attributeMap; }
+ void setAttributeMap(PassOwnPtrWillBeRawPtr<NamedNodeMap> attributeMap) { m_attributeMap = attributeMap; }
RenderStyle* computedStyle() const { return m_computedStyle.get(); }
void setComputedStyle(PassRefPtr<RenderStyle> computedStyle) { m_computedStyle = computedStyle; }
- void clearComputedStyle() { m_computedStyle = 0; }
+ void clearComputedStyle() { m_computedStyle = nullptr; }
ClassList* classList() const { return m_classList.get(); }
- void setClassList(PassOwnPtr<ClassList> classList) { m_classList = classList; }
+ void setClassList(PassOwnPtrWillBeRawPtr<ClassList> classList) { m_classList = classList; }
void clearClassListValueForQuirksMode()
{
if (!m_classList)
@@ -123,7 +96,7 @@ public:
}
DatasetDOMStringMap* dataset() const { return m_dataset.get(); }
- void setDataset(PassOwnPtr<DatasetDOMStringMap> dataset) { m_dataset = dataset; }
+ void setDataset(PassOwnPtrWillBeRawPtr<DatasetDOMStringMap> dataset) { m_dataset = dataset; }
LayoutSize minimumSizeForResizing() const { return m_minimumSizeForResizing; }
void setMinimumSizeForResizing(LayoutSize size) { m_minimumSizeForResizing = size; }
@@ -132,66 +105,54 @@ public:
void setSavedLayerScrollOffset(IntSize size) { m_savedLayerScrollOffset = size; }
ActiveAnimations* activeAnimations() { return m_activeAnimations.get(); }
- void setActiveAnimations(PassOwnPtr<ActiveAnimations> activeAnimations)
+ void setActiveAnimations(PassOwnPtrWillBeRawPtr<ActiveAnimations> activeAnimations)
{
m_activeAnimations = activeAnimations;
}
- bool hasPendingResources() const { return m_hasPendingResources; }
- void setHasPendingResources(bool has) { m_hasPendingResources = has; }
-
bool hasInputMethodContext() const { return m_inputMethodContext; }
- InputMethodContext* ensureInputMethodContext(HTMLElement* element)
+ InputMethodContext& ensureInputMethodContext(HTMLElement* element)
{
if (!m_inputMethodContext)
m_inputMethodContext = InputMethodContext::create(element);
- return m_inputMethodContext.get();
+ return *m_inputMethodContext;
}
bool hasPseudoElements() const;
+ void clearPseudoElements();
+
+ void setCustomElementDefinition(PassRefPtr<CustomElementDefinition> definition) { m_customElementDefinition = definition; }
+ CustomElementDefinition* customElementDefinition() const { return m_customElementDefinition.get(); }
+
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >& ensureAttrNodeList();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >* attrNodeList() { return m_attrNodeList.get(); }
+ void removeAttrNodeList() { m_attrNodeList.clear(); }
+
+ void traceAfterDispatch(Visitor*);
private:
- short m_tabIndex;
- unsigned short m_childIndex;
- unsigned m_tabIndexWasSetExplicitly : 1;
- unsigned m_needsFocusAppearanceUpdateSoonAfterAttach : 1;
- unsigned m_styleAffectedByEmpty : 1;
- unsigned m_isInCanvasSubtree : 1;
- unsigned m_containsFullScreenElement : 1;
- unsigned m_isInTopLayer : 1;
- unsigned m_hasPendingResources : 1;
- unsigned m_childrenAffectedByFocus : 1;
- unsigned m_childrenAffectedByHover : 1;
- unsigned m_childrenAffectedByActive : 1;
- unsigned m_childrenAffectedByDrag : 1;
- // Bits for dynamic child matching.
- // We optimize for :first-child and :last-child. The other positional child selectors like nth-child or
- // *-child-of-type, we will just give up and re-evaluate whenever children change at all.
- unsigned m_childrenAffectedByFirstChildRules : 1;
- unsigned m_childrenAffectedByLastChildRules : 1;
- unsigned m_childrenAffectedByDirectAdjacentRules : 1;
- unsigned m_childrenAffectedByForwardPositionalRules : 1;
- unsigned m_childrenAffectedByBackwardPositionalRules : 1;
-
- unsigned m_isInsideRegion : 1;
- RegionOversetState m_regionOversetState;
+ short m_tabindex;
LayoutSize m_minimumSizeForResizing;
IntSize m_savedLayerScrollOffset;
- RefPtr<RenderStyle> m_computedStyle;
- OwnPtr<DatasetDOMStringMap> m_dataset;
- OwnPtr<ClassList> m_classList;
- OwnPtr<ElementShadow> m_shadow;
- OwnPtr<NamedNodeMap> m_attributeMap;
- OwnPtr<InputMethodContext> m_inputMethodContext;
- OwnPtr<ActiveAnimations> m_activeAnimations;
+ OwnPtrWillBeMember<DatasetDOMStringMap> m_dataset;
+ OwnPtrWillBeMember<ClassList> m_classList;
+ OwnPtrWillBeMember<ElementShadow> m_shadow;
+ OwnPtrWillBeMember<NamedNodeMap> m_attributeMap;
+ OwnPtrWillBeMember<WillBeHeapVector<RefPtrWillBeMember<Attr> > > m_attrNodeList;
+ OwnPtrWillBeMember<InputMethodContext> m_inputMethodContext;
+ OwnPtrWillBeMember<ActiveAnimations> m_activeAnimations;
+ OwnPtrWillBeMember<InlineCSSStyleDeclaration> m_cssomWrapper;
- RefPtr<PseudoElement> m_generatedBefore;
- RefPtr<PseudoElement> m_generatedAfter;
- RefPtr<PseudoElement> m_backdrop;
+ RefPtr<RenderStyle> m_computedStyle;
+ RefPtr<CustomElementDefinition> m_customElementDefinition;
+
+ RefPtrWillBeMember<PseudoElement> m_generatedBefore;
+ RefPtrWillBeMember<PseudoElement> m_generatedAfter;
+ RefPtrWillBeMember<PseudoElement> m_backdrop;
- ElementRareData(RenderObject*);
+ explicit ElementRareData(RenderObject*);
};
inline IntSize defaultMinimumSizeForResizing()
@@ -201,33 +162,17 @@ inline IntSize defaultMinimumSizeForResizing()
inline ElementRareData::ElementRareData(RenderObject* renderer)
: NodeRareData(renderer)
- , m_tabIndex(0)
- , m_childIndex(0)
- , m_tabIndexWasSetExplicitly(false)
- , m_needsFocusAppearanceUpdateSoonAfterAttach(false)
- , m_styleAffectedByEmpty(false)
- , m_isInCanvasSubtree(false)
- , m_containsFullScreenElement(false)
- , m_isInTopLayer(false)
- , m_hasPendingResources(false)
- , m_childrenAffectedByFocus(false)
- , m_childrenAffectedByHover(false)
- , m_childrenAffectedByActive(false)
- , m_childrenAffectedByDrag(false)
- , m_childrenAffectedByFirstChildRules(false)
- , m_childrenAffectedByLastChildRules(false)
- , m_childrenAffectedByDirectAdjacentRules(false)
- , m_childrenAffectedByForwardPositionalRules(false)
- , m_childrenAffectedByBackwardPositionalRules(false)
- , m_isInsideRegion(false)
- , m_regionOversetState(RegionUndefined)
+ , m_tabindex(0)
, m_minimumSizeForResizing(defaultMinimumSizeForResizing())
{
+ m_isElementRareData = true;
}
inline ElementRareData::~ElementRareData()
{
+#if !ENABLE(OILPAN)
ASSERT(!m_shadow);
+#endif
ASSERT(!m_generatedBefore);
ASSERT(!m_generatedAfter);
ASSERT(!m_backdrop);
@@ -238,7 +183,14 @@ inline bool ElementRareData::hasPseudoElements() const
return m_generatedBefore || m_generatedAfter || m_backdrop;
}
-inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
+inline void ElementRareData::clearPseudoElements()
+{
+ setPseudoElement(BEFORE, nullptr);
+ setPseudoElement(AFTER, nullptr);
+ setPseudoElement(BACKDROP, nullptr);
+}
+
+inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtrWillBeRawPtr<PseudoElement> element)
{
switch (pseudoId) {
case BEFORE:
@@ -277,21 +229,7 @@ inline PseudoElement* ElementRareData::pseudoElement(PseudoId pseudoId) const
inline void ElementRareData::resetStyleState()
{
- setStyleAffectedByEmpty(false);
- setChildIndex(0);
-}
-
-inline void ElementRareData::resetDynamicRestyleObservations()
-{
- setChildrenAffectedByFocus(false);
- setChildrenAffectedByHover(false);
- setChildrenAffectedByActive(false);
- setChildrenAffectedByDrag(false);
- setChildrenAffectedByFirstChildRules(false);
- setChildrenAffectedByLastChildRules(false);
- setChildrenAffectedByDirectAdjacentRules(false);
- setChildrenAffectedByForwardPositionalRules(false);
- setChildrenAffectedByBackwardPositionalRules(false);
+ clearElementFlag(StyleAffectedByEmpty);
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h b/chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h
index 274725d57ee..e8241820b5e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ElementTraversal.h
@@ -2,8 +2,9 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,122 +31,313 @@
namespace WebCore {
-namespace ElementTraversal {
+template <class ElementType>
+class Traversal {
+public:
+ // First or last ElementType child of the node.
+ static ElementType* firstChild(const ContainerNode& current) { return firstChildTemplate(current); }
+ static ElementType* firstChild(const Node& current) { return firstChildTemplate(current); }
+ static ElementType* lastChild(const ContainerNode& current) { return lastChildTemplate(current); }
+ static ElementType* lastChild(const Node& current) { return lastChildTemplate(current); }
-// First element child of the node.
-Element* firstWithin(const Node&);
-Element* firstWithin(const ContainerNode&);
+ // First ElementType ancestor of the node.
+ static ElementType* firstAncestor(const Node& current);
+ static ElementType* firstAncestorOrSelf(Node& current) { return firstAncestorOrSelfTemplate(current); }
+ static ElementType* firstAncestorOrSelf(Element& current) { return firstAncestorOrSelfTemplate(current); }
-// Pre-order traversal skipping non-element nodes.
-Element* next(const Node&);
-Element* next(const Node&, const Node* stayWithin);
-Element* next(const ContainerNode&);
-Element* next(const ContainerNode&, const Node* stayWithin);
+ // First or last ElementType descendant of the node.
+ // For Elements firstWithin() is always the same as firstChild().
+ static ElementType* firstWithin(const ContainerNode& current) { return firstWithinTemplate(current); }
+ static ElementType* firstWithin(const Node& current) { return firstWithinTemplate(current); }
+ static ElementType* lastWithin(const ContainerNode& current) { return lastWithinTemplate(current); }
+ static ElementType* lastWithin(const Node& current) { return lastWithinTemplate(current); }
-// Like next, but skips children.
-Element* nextSkippingChildren(const Node&);
-Element* nextSkippingChildren(const Node&, const Node* stayWithin);
-Element* nextSkippingChildren(const ContainerNode&);
-Element* nextSkippingChildren(const ContainerNode&, const Node* stayWithin);
+ // Pre-order traversal skipping non-element nodes.
+ static ElementType* next(const ContainerNode& current) { return nextTemplate(current); }
+ static ElementType* next(const Node& current) { return nextTemplate(current); }
+ static ElementType* next(const ContainerNode& current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
+ static ElementType* next(const Node& current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
+ static ElementType* previous(const ContainerNode& current) { return previousTemplate(current); }
+ static ElementType* previous(const Node& current) { return previousTemplate(current); }
+ static ElementType* previous(const ContainerNode& current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
+ static ElementType* previous(const Node& current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
-// Pre-order traversal including the pseudo-elements.
-Element* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Element* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Element* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
+ // Like next, but skips children.
+ static ElementType* nextSkippingChildren(const ContainerNode& current) { return nextSkippingChildrenTemplate(current); }
+ static ElementType* nextSkippingChildren(const Node& current) { return nextSkippingChildrenTemplate(current); }
+ static ElementType* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
+ static ElementType* nextSkippingChildren(const Node& current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
-// Utility function to traverse only the element and pseudo-element siblings of a node.
-Element* pseudoAwarePreviousSibling(const Node&);
+ // Pre-order traversal including the pseudo-elements.
+ static ElementType* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
+ static ElementType* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
+ static ElementType* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
+ // Utility function to traverse only the element and pseudo-element siblings of a node.
+ static ElementType* pseudoAwarePreviousSibling(const Node&);
+
+ // Previous / Next sibling.
+ static ElementType* previousSibling(const Node&);
+ static ElementType* nextSibling(const Node&);
+
+private:
+ template <class NodeType>
+ static ElementType* firstChildTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* lastChildTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* firstAncestorOrSelfTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* firstWithinTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* lastWithinTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* nextTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* nextTemplate(NodeType&, const Node* stayWithin);
+ template <class NodeType>
+ static ElementType* previousTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* previousTemplate(NodeType&, const Node* stayWithin);
+ template <class NodeType>
+ static ElementType* nextSkippingChildrenTemplate(NodeType&);
+ template <class NodeType>
+ static ElementType* nextSkippingChildrenTemplate(NodeType&, const Node* stayWithin);
+};
+
+typedef Traversal<Element> ElementTraversal;
+
+// Specialized for pure Element to exploit the fact that Elements parent is always either another Element or the root.
+template <>
template <class NodeType>
-inline Element* firstElementWithinTemplate(NodeType& current)
+inline Element* Traversal<Element>::firstWithinTemplate(NodeType& current)
{
- // Except for the root containers, only elements can have element children.
- Node* node = current.firstChild();
+ return firstChildTemplate(current);
+}
+
+template <>
+template <class NodeType>
+inline Element* Traversal<Element>::lastWithinTemplate(NodeType& current)
+{
+ Node* node = NodeTraversal::lastWithin(current);
while (node && !node->isElementNode())
- node = node->nextSibling();
+ node = NodeTraversal::previous(*node, &current);
return toElement(node);
}
-inline Element* firstWithin(const ContainerNode& current) { return firstElementWithinTemplate(current); }
-inline Element* firstWithin(const Node& current) { return firstElementWithinTemplate(current); }
+template <>
template <class NodeType>
-inline Element* traverseNextElementTemplate(NodeType& current)
+inline Element* Traversal<Element>::nextTemplate(NodeType& current)
{
Node* node = NodeTraversal::next(current);
while (node && !node->isElementNode())
node = NodeTraversal::nextSkippingChildren(*node);
return toElement(node);
}
-inline Element* next(const ContainerNode& current) { return traverseNextElementTemplate(current); }
-inline Element* next(const Node& current) { return traverseNextElementTemplate(current); }
+template <>
template <class NodeType>
-inline Element* traverseNextElementTemplate(NodeType& current, const Node* stayWithin)
+inline Element* Traversal<Element>::nextTemplate(NodeType& current, const Node* stayWithin)
{
Node* node = NodeTraversal::next(current, stayWithin);
while (node && !node->isElementNode())
node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
return toElement(node);
}
-inline Element* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextElementTemplate(current, stayWithin); }
-inline Element* next(const Node& current, const Node* stayWithin) { return traverseNextElementTemplate(current, stayWithin); }
+template <>
template <class NodeType>
-inline Element* traverseNextElementSkippingChildrenTemplate(NodeType& current)
+inline Element* Traversal<Element>::previousTemplate(NodeType& current)
{
- Node* node = NodeTraversal::nextSkippingChildren(current);
+ Node* node = NodeTraversal::previous(current);
while (node && !node->isElementNode())
- node = NodeTraversal::nextSkippingChildren(*node);
+ node = NodeTraversal::previous(*node);
return toElement(node);
}
-inline Element* nextSkippingChildren(const ContainerNode& current) { return traverseNextElementSkippingChildrenTemplate(current); }
-inline Element* nextSkippingChildren(const Node& current) { return traverseNextElementSkippingChildrenTemplate(current); }
+template <>
template <class NodeType>
-inline Element* traverseNextElementSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
+inline Element* Traversal<Element>::previousTemplate(NodeType& current, const Node* stayWithin)
{
- Node* node = NodeTraversal::nextSkippingChildren(current, stayWithin);
+ Node* node = NodeTraversal::previous(current, stayWithin);
while (node && !node->isElementNode())
- node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
+ node = NodeTraversal::previous(*node, stayWithin);
return toElement(node);
}
-inline Element* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextElementSkippingChildrenTemplate(current, stayWithin); }
-inline Element* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextElementSkippingChildrenTemplate(current, stayWithin); }
-inline Element* previousIncludingPseudo(const Node& current, const Node* stayWithin)
+// Generic versions.
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::firstChildTemplate(NodeType& current)
+{
+ Node* node = current.firstChild();
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = node->nextSibling();
+ return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::firstAncestor(const Node& current)
+{
+ ContainerNode* ancestor = current.parentNode();
+ while (ancestor && !isElementOfType<const ElementType>(*ancestor))
+ ancestor = ancestor->parentNode();
+ return toElement<ElementType>(ancestor);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::firstAncestorOrSelfTemplate(NodeType& current)
+{
+ if (isElementOfType<const ElementType>(current))
+ return &toElement<ElementType>(current);
+ return firstAncestor(current);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::lastChildTemplate(NodeType& current)
+{
+ Node* node = current.lastChild();
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = node->previousSibling();
+ return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::firstWithinTemplate(NodeType& current)
+{
+ Element* element = Traversal<Element>::firstWithin(current);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::next(*element, &current);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::lastWithinTemplate(NodeType& current)
+{
+ Element* element = Traversal<Element>::lastWithin(current);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::previous(element, &current);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextTemplate(NodeType& current)
+{
+ Element* element = Traversal<Element>::next(current);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::next(*element);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextTemplate(NodeType& current, const Node* stayWithin)
+{
+ Element* element = Traversal<Element>::next(current, stayWithin);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::next(*element, stayWithin);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::previousTemplate(NodeType& current)
+{
+ Element* element = Traversal<Element>::previous(current);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::previous(*element);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::previousTemplate(NodeType& current, const Node* stayWithin)
+{
+ Element* element = Traversal<Element>::previous(current, stayWithin);
+ while (element && !isElementOfType<const ElementType>(*element))
+ element = Traversal<Element>::previous(*element, stayWithin);
+ return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(NodeType& current)
+{
+ Node* node = NodeTraversal::nextSkippingChildren(current);
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = NodeTraversal::nextSkippingChildren(*node);
+ return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
+{
+ Node* node = NodeTraversal::nextSkippingChildren(current, stayWithin);
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
+ return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::previousIncludingPseudo(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::previousIncludingPseudo(current, stayWithin);
- while (node && !node->isElementNode())
+ while (node && !isElementOfType<const ElementType>(*node))
node = NodeTraversal::previousIncludingPseudo(*node, stayWithin);
- return toElement(node);
+ return toElement<ElementType>(node);
}
-inline Element* nextIncludingPseudo(const Node& current, const Node* stayWithin)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextIncludingPseudo(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::nextIncludingPseudo(current, stayWithin);
- while (node && !node->isElementNode())
+ while (node && !isElementOfType<const ElementType>(*node))
node = NodeTraversal::nextIncludingPseudo(*node, stayWithin);
- return toElement(node);
+ return toElement<ElementType>(node);
}
-inline Element* nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
{
Node* node = NodeTraversal::nextIncludingPseudoSkippingChildren(current, stayWithin);
- while (node && !node->isElementNode())
+ while (node && !isElementOfType<const ElementType>(*node))
node = NodeTraversal::nextIncludingPseudoSkippingChildren(*node, stayWithin);
- return toElement(node);
+ return toElement<ElementType>(node);
}
-inline Element* pseudoAwarePreviousSibling(const Node& current)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::pseudoAwarePreviousSibling(const Node& current)
{
Node* node = current.pseudoAwarePreviousSibling();
- while (node && !node->isElementNode())
+ while (node && !isElementOfType<const ElementType>(*node))
node = node->pseudoAwarePreviousSibling();
- return toElement(node);
+ return toElement<ElementType>(node);
}
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::previousSibling(const Node& current)
+{
+ Node* node = current.previousSibling();
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = node->previousSibling();
+ return toElement<ElementType>(node);
}
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextSibling(const Node& current)
+{
+ Node* node = current.nextSibling();
+ while (node && !isElementOfType<const ElementType>(*node))
+ node = node->nextSibling();
+ return toElement<ElementType>(node);
}
+} // namespace WebCore
+
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.cpp
new file mode 100644
index 00000000000..9a453d8fcfd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/EmptyNodeList.h"
+
+#include "core/dom/Node.h"
+#include "core/dom/NodeRareData.h"
+
+namespace WebCore {
+
+EmptyNodeList::~EmptyNodeList()
+{
+#if !ENABLE(OILPAN)
+ m_owner->nodeLists()->removeEmptyChildNodeList(this);
+#endif
+}
+
+Node* EmptyNodeList::virtualOwnerNode() const
+{
+ return &ownerNode();
+}
+
+void EmptyNodeList::trace(Visitor* visitor)
+{
+ visitor->trace(m_owner);
+ NodeList::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.h b/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.h
new file mode 100644
index 00000000000..0857148db08
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/EmptyNodeList.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EmptyNodeList_h
+#define EmptyNodeList_h
+
+#include "core/dom/NodeList.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class EmptyNodeList FINAL : public NodeList {
+public:
+ static PassRefPtrWillBeRawPtr<EmptyNodeList> create(Node& rootNode)
+ {
+ return adoptRefWillBeNoop(new EmptyNodeList(rootNode));
+ }
+ virtual ~EmptyNodeList();
+
+ Node& ownerNode() const { return *m_owner; }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit EmptyNodeList(Node& rootNode) : m_owner(rootNode) { }
+
+ virtual unsigned length() const OVERRIDE { return 0; }
+ virtual Node* item(unsigned) const OVERRIDE { return 0; }
+
+ virtual bool isEmptyNodeList() const OVERRIDE { return true; }
+ virtual Node* virtualOwnerNode() const OVERRIDE;
+
+ RefPtrWillBeMember<Node> m_owner;
+};
+
+DEFINE_TYPE_CASTS(EmptyNodeList, NodeList, nodeList, nodeList->isEmptyNodeList(), nodeList.isEmptyNodeList());
+
+} // namespace WebCore
+
+#endif // EmptyNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/Entity.h b/chromium/third_party/WebKit/Source/core/dom/Entity.h
deleted file mode 100644
index e1a7a002513..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Entity.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2000 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Entity_h
-#define Entity_h
-
-#include "core/dom/ContainerNode.h"
-
-namespace WebCore {
-
-class Entity : public ContainerNode {
-private:
- Entity(); // Left unimplemented on purpose.
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Entity.idl b/chromium/third_party/WebKit/Source/core/dom/Entity.idl
deleted file mode 100644
index 151572f4f26..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Entity.idl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-// FIXME: Remove Entity interface. We never create Entity objects. We have this
-// interface to provide window.Entity.
-interface Entity : Node {
- // We don't need to provide any attributes.
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h b/chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h
index 4dc428a5a83..be3bf07856a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ExceptionCode.h
@@ -78,6 +78,9 @@ namespace WebCore {
// SQL
SQLDatabaseError, // Naming conflict with DatabaseError class.
+ // Web Crypto
+ OperationError,
+
// WebIDL exception types, handled by the binding layer.
// FIXME: Add GeneralError, EvalError, etc. when implemented in the bindings.
TypeError,
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp b/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
index 1f62b74cfef..c8a61b7898f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
@@ -41,10 +41,10 @@
namespace WebCore {
-class ExecutionContext::PendingException {
+class ExecutionContext::PendingException : public NoBaseWillBeGarbageCollectedFinalized<ExecutionContext::PendingException> {
WTF_MAKE_NONCOPYABLE(PendingException);
public:
- PendingException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, PassRefPtr<ScriptCallStack> callStack)
+ PendingException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
: m_errorMessage(errorMessage)
, m_lineNumber(lineNumber)
, m_columnNumber(columnNumber)
@@ -52,11 +52,15 @@ public:
, m_callStack(callStack)
{
}
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_callStack);
+ }
String m_errorMessage;
int m_lineNumber;
int m_columnNumber;
String m_sourceURL;
- RefPtr<ScriptCallStack> m_callStack;
+ RefPtrWillBeMember<ScriptCallStack> m_callStack;
};
ExecutionContext::ExecutionContext()
@@ -96,6 +100,11 @@ void ExecutionContext::stopActiveDOMObjects()
lifecycleNotifier().notifyStoppingActiveDOMObjects();
}
+unsigned ExecutionContext::activeDOMObjectCount()
+{
+ return lifecycleNotifier().activeDOMObjects().size();
+}
+
void ExecutionContext::suspendScheduledTasks()
{
suspendActiveDOMObjects();
@@ -123,13 +132,13 @@ bool ExecutionContext::shouldSanitizeScriptError(const String& sourceURL, Access
return !(securityOrigin()->canRequest(completeURL(sourceURL)) || corsStatus == SharableCrossOrigin);
}
-void ExecutionContext::reportException(PassRefPtr<ErrorEvent> event, PassRefPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
+void ExecutionContext::reportException(PassRefPtrWillBeRawPtr<ErrorEvent> event, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, AccessControlStatus corsStatus)
{
- RefPtr<ErrorEvent> errorEvent = event;
+ RefPtrWillBeRawPtr<ErrorEvent> errorEvent = event;
if (m_inDispatchErrorEvent) {
if (!m_pendingExceptions)
- m_pendingExceptions = adoptPtr(new Vector<OwnPtr<PendingException> >());
- m_pendingExceptions->append(adoptPtr(new PendingException(errorEvent->messageForConsole(), errorEvent->lineno(), errorEvent->colno(), errorEvent->filename(), callStack)));
+ m_pendingExceptions = adoptPtrWillBeNoop(new WillBeHeapVector<OwnPtrWillBeMember<PendingException> >());
+ m_pendingExceptions->append(adoptPtrWillBeNoop(new PendingException(errorEvent->messageForConsole(), errorEvent->lineno(), errorEvent->colno(), errorEvent->filename(), callStack)));
return;
}
@@ -155,14 +164,14 @@ void ExecutionContext::addConsoleMessage(MessageSource source, MessageLevel leve
m_client->addMessage(source, level, message, sourceURL, lineNumber, 0);
}
-void ExecutionContext::addConsoleMessage(MessageSource source, MessageLevel level, const String& message, ScriptState* state)
+void ExecutionContext::addConsoleMessage(MessageSource source, MessageLevel level, const String& message, ScriptState* scriptState)
{
if (!m_client)
return;
- m_client->addMessage(source, level, message, String(), 0, state);
+ m_client->addMessage(source, level, message, String(), 0, scriptState);
}
-bool ExecutionContext::dispatchErrorEvent(PassRefPtr<ErrorEvent> event, AccessControlStatus corsStatus)
+bool ExecutionContext::dispatchErrorEvent(PassRefPtrWillBeRawPtr<ErrorEvent> event, AccessControlStatus corsStatus)
{
if (!m_client)
return false;
@@ -170,7 +179,7 @@ bool ExecutionContext::dispatchErrorEvent(PassRefPtr<ErrorEvent> event, AccessCo
if (!target)
return false;
- RefPtr<ErrorEvent> errorEvent = event;
+ RefPtrWillBeRawPtr<ErrorEvent> errorEvent = event;
if (shouldSanitizeScriptError(errorEvent->filename(), corsStatus))
errorEvent = ErrorEvent::createSanitizedError(errorEvent->world());
@@ -199,7 +208,7 @@ int ExecutionContext::installNewTimeout(PassOwnPtr<ScheduledAction> action, int
}
TimeoutMap::AddResult result = m_timeouts.add(timeoutID, DOMTimer::create(this, action, timeout, singleShot, timeoutID));
ASSERT(result.isNewEntry);
- DOMTimer* timer = result.iterator->value.get();
+ DOMTimer* timer = result.storedValue->value.get();
timer->suspendIfNeeded();
@@ -245,7 +254,7 @@ const KURL& ExecutionContext::url() const
return emptyURL;
}
- return m_client->virtualURL();
+ return virtualURL();
}
KURL ExecutionContext::completeURL(const String& url) const
@@ -256,14 +265,7 @@ KURL ExecutionContext::completeURL(const String& url) const
return emptyURL;
}
- return m_client->virtualCompleteURL(url);
-}
-
-void ExecutionContext::userEventWasHandled()
-{
- if (!m_client)
- return;
- m_client->userEventWasHandled();
+ return virtualCompleteURL(url);
}
void ExecutionContext::disableEval(const String& errorMessage)
@@ -273,7 +275,7 @@ void ExecutionContext::disableEval(const String& errorMessage)
return m_client->disableEval(errorMessage);
}
-DOMWindow* ExecutionContext::executingWindow() const
+LocalDOMWindow* ExecutionContext::executingWindow() const
{
RELEASE_ASSERT(m_client);
return m_client->executingWindow();
@@ -334,4 +336,12 @@ void ExecutionContext::enforceSandboxFlags(SandboxFlags mask)
}
}
+void ExecutionContext::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_pendingExceptions);
+#endif
+ Supplementable<WebCore::ExecutionContext>::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h b/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h
index 3fb01bb79f8..863b18b56f2 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ExecutionContext.h
@@ -37,6 +37,8 @@
#include "core/frame/ConsoleTypes.h"
#include "core/frame/DOMTimer.h"
#include "platform/LifecycleContext.h"
+#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Functional.h"
#include "wtf/OwnPtr.h"
@@ -49,23 +51,24 @@ class OrdinalNumber;
namespace WebCore {
class ContextLifecycleNotifier;
-class DOMWindow;
+class LocalDOMWindow;
class EventListener;
class EventQueue;
class EventTarget;
class ExecutionContextTask;
+class ScriptState;
class PublicURLManager;
class SecurityOrigin;
class ScriptCallStack;
-class ScriptState;
-class ExecutionContext : public LifecycleContext<ExecutionContext> {
+class ExecutionContext
+ : public WillBeGarbageCollectedMixin
+ , public LifecycleContext<ExecutionContext>
+ , public Supplementable<ExecutionContext> {
public:
- ExecutionContext();
- virtual ~ExecutionContext();
+ virtual void trace(Visitor*);
// Delegating to ExecutionContextClient
- void setClient(ExecutionContextClient* client) { m_client = client; }
bool isDocument() const { return m_client && m_client->isDocument(); }
bool isWorkerGlobalScope() const { return m_client && m_client->isWorkerGlobalScope(); }
bool isJSExecutionForbidden() { return m_client && m_client->isJSExecutionForbidden(); }
@@ -73,16 +76,21 @@ public:
ContentSecurityPolicy* contentSecurityPolicy() const;
const KURL& url() const;
KURL completeURL(const String& url) const;
- void userEventWasHandled();
void disableEval(const String& errorMessage);
- DOMWindow* executingWindow() const;
+ LocalDOMWindow* executingWindow() const;
String userAgent(const KURL&) const;
void postTask(PassOwnPtr<ExecutionContextTask>);
void postTask(const Closure&);
double timerAlignmentInterval() const;
+ virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) = 0;
+
+ virtual SecurityContext& securityContext() = 0;
+ KURL contextURL() const { return virtualURL(); }
+ KURL contextCompleteURL(const String& url) const { return virtualCompleteURL(url); }
+
bool shouldSanitizeScriptError(const String& sourceURL, AccessControlStatus);
- void reportException(PassRefPtr<ErrorEvent>, PassRefPtr<ScriptCallStack>, AccessControlStatus);
+ void reportException(PassRefPtrWillBeRawPtr<ErrorEvent>, PassRefPtrWillBeRawPtr<ScriptCallStack>, AccessControlStatus);
void addConsoleMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber);
void addConsoleMessage(MessageSource, MessageLevel, const String& message, ScriptState* = 0);
@@ -95,6 +103,7 @@ public:
void suspendActiveDOMObjects();
void resumeActiveDOMObjects();
void stopActiveDOMObjects();
+ unsigned activeDOMObjectCount();
virtual void suspendScheduledTasks();
virtual void resumeScheduledTasks();
@@ -106,9 +115,10 @@ public:
// Called after the construction of an ActiveDOMObject to synchronize suspend state.
void suspendActiveDOMObjectIfNeeded(ActiveDOMObject*);
-
+#if !ENABLE(OILPAN)
void ref() { refExecutionContext(); }
void deref() { derefExecutionContext(); }
+#endif
// Gets the next id in a circular sequence from 1 to 2^31-1.
int circularSequentialID();
@@ -124,16 +134,25 @@ public:
virtual EventQueue* eventQueue() const = 0;
protected:
+ ExecutionContext();
+ virtual ~ExecutionContext();
+
+ void setClient(ExecutionContextClient* client) { m_client = client; }
+
+ virtual const KURL& virtualURL() const = 0;
+ virtual KURL virtualCompleteURL(const String&) const = 0;
ContextLifecycleNotifier& lifecycleNotifier();
private:
friend class DOMTimer; // For installNewTimeout() and removeTimeoutByID() below.
- bool dispatchErrorEvent(PassRefPtr<ErrorEvent>, AccessControlStatus);
+ bool dispatchErrorEvent(PassRefPtrWillBeRawPtr<ErrorEvent>, AccessControlStatus);
+#if !ENABLE(OILPAN)
virtual void refExecutionContext() = 0;
virtual void derefExecutionContext() = 0;
+#endif
// LifecycleContext implementation.
// Implementation details for DOMTimer. No other classes should call these functions.
@@ -149,7 +168,7 @@ private:
bool m_inDispatchErrorEvent;
class PendingException;
- OwnPtr<Vector<OwnPtr<PendingException> > > m_pendingExceptions;
+ OwnPtrWillBeMember<WillBeHeapVector<OwnPtrWillBeMember<PendingException> > > m_pendingExceptions;
bool m_activeDOMObjectsAreSuspended;
bool m_activeDOMObjectsAreStopped;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h
index 4293c744c09..1964752a75c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextClient.h
@@ -29,14 +29,13 @@
#include "core/frame/ConsoleTypes.h"
#include "platform/LifecycleNotifier.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class EventQueue;
class EventTarget;
class ExecutionContextTask;
@@ -53,17 +52,13 @@ public:
virtual bool isDocument() const { return false; }
virtual bool isWorkerGlobalScope() const { return false; }
virtual bool isJSExecutionForbidden() const = 0;
- virtual DOMWindow* executingWindow() { return 0; }
- virtual void userEventWasHandled() { }
+ virtual LocalDOMWindow* executingWindow() { return 0; }
virtual String userAgent(const KURL&) const = 0;
virtual void disableEval(const String& errorMessage) = 0;
virtual SecurityContext& securityContext() = 0;
- virtual const KURL& virtualURL() const = 0;
- virtual KURL virtualCompleteURL(const String&) const = 0;
virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState*) = 0;
- virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) = 0;
virtual EventTarget* errorEventTarget() = 0;
- virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) = 0;
+ virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>) = 0;
virtual double timerAlignmentInterval() const = 0;
virtual void didUpdateSecurityOrigin() = 0;
@@ -72,8 +67,6 @@ public:
void addConsoleMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber) { addMessage(source, level, message, sourceURL, lineNumber, 0); }
void addConsoleMessage(MessageSource source, MessageLevel level, const String& message, ScriptState* state = 0) { addMessage(source, level, message, String(), 0, state); }
- KURL contextURL() const { return virtualURL(); }
- KURL contextCompleteURL(const String& url) const { return virtualCompleteURL(url); }
protected:
virtual ~ExecutionContextClient() { }
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp
deleted file mode 100644
index 124a5ac4aac..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ExecutionContextTask_h
-#define ExecutionContextTask_h
-
-#include "config.h"
-#include "core/dom/ExecutionContextTask.h"
-
-namespace WebCore {
-
-
-} // namespace
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
index 9d07d75d6a9..dbc98d3b69b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ExecutionContextTask.h
@@ -47,7 +47,7 @@ public:
virtual bool isCleanupTask() const { return false; }
};
-class CallClosureTask : public ExecutionContextTask {
+class CallClosureTask FINAL : public ExecutionContextTask {
public:
static PassOwnPtr<CallClosureTask> create(const Closure& closure)
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp b/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp
index f6daf0e6631..b5363bc682b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp
@@ -28,15 +28,15 @@
#include "config.h"
#include "core/dom/FullscreenElementStack.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderFullScreen.h"
#include "platform/UserGestureIndicator.h"
@@ -44,13 +44,18 @@ namespace WebCore {
using namespace HTMLNames;
-static bool isAttributeOnAllOwners(const WebCore::QualifiedName& attribute, const WebCore::QualifiedName& prefixedAttribute, const HTMLFrameOwnerElement* owner)
+static bool fullscreenIsAllowedForAllOwners(const Document& document)
{
+ const HTMLFrameOwnerElement* owner = document.ownerElement();
if (!owner)
return true;
do {
- if (!(owner->hasAttribute(attribute) || owner->hasAttribute(prefixedAttribute)))
- return false;
+ if (!owner->hasAttribute(allowfullscreenAttr)) {
+ if (owner->hasAttribute(webkitallowfullscreenAttr))
+ UseCounter::count(document, UseCounter::PrefixedAllowFullscreenAttribute);
+ else
+ return false;
+ }
} while ((owner = owner->document().ownerElement()));
return true;
}
@@ -60,50 +65,50 @@ const char* FullscreenElementStack::supplementName()
return "FullscreenElementStack";
}
-FullscreenElementStack* FullscreenElementStack::from(Document* document)
+FullscreenElementStack& FullscreenElementStack::from(Document& document)
{
FullscreenElementStack* fullscreen = fromIfExists(document);
if (!fullscreen) {
fullscreen = new FullscreenElementStack(document);
- DocumentSupplement::provideTo(document, supplementName(), adoptPtr(fullscreen));
+ DocumentSupplement::provideTo(document, supplementName(), adoptPtrWillBeNoop(fullscreen));
}
- return fullscreen;
+ return *fullscreen;
}
-FullscreenElementStack* FullscreenElementStack::fromIfExistsSlow(Document* document)
+FullscreenElementStack* FullscreenElementStack::fromIfExistsSlow(Document& document)
{
return static_cast<FullscreenElementStack*>(DocumentSupplement::from(document, supplementName()));
}
-Element* FullscreenElementStack::fullscreenElementFrom(Document* document)
+Element* FullscreenElementStack::fullscreenElementFrom(Document& document)
{
if (FullscreenElementStack* found = fromIfExists(document))
return found->webkitFullscreenElement();
return 0;
}
-Element* FullscreenElementStack::currentFullScreenElementFrom(Document* document)
+Element* FullscreenElementStack::currentFullScreenElementFrom(Document& document)
{
if (FullscreenElementStack* found = fromIfExists(document))
return found->webkitCurrentFullScreenElement();
return 0;
}
-bool FullscreenElementStack::isFullScreen(Document* document)
+bool FullscreenElementStack::isFullScreen(Document& document)
{
if (FullscreenElementStack* found = fromIfExists(document))
return found->webkitIsFullScreen();
return false;
}
-FullscreenElementStack::FullscreenElementStack(Document* document)
- : DocumentLifecycleObserver(document)
+FullscreenElementStack::FullscreenElementStack(Document& document)
+ : DocumentLifecycleObserver(&document)
, m_areKeysEnabledInFullScreen(false)
, m_fullScreenRenderer(0)
, m_fullScreenChangeDelayTimer(this, &FullscreenElementStack::fullScreenChangeDelayTimerFired)
{
- document->setHasFullscreenElementStack();
+ document.setHasFullscreenElementStack();
}
FullscreenElementStack::~FullscreenElementStack()
@@ -122,22 +127,36 @@ void FullscreenElementStack::documentWasDetached()
if (m_fullScreenRenderer)
setFullScreenRenderer(0);
+
+#if ENABLE(OILPAN)
+ m_fullScreenElement = nullptr;
+ m_fullScreenElementStack.clear();
+#endif
+
}
+#if !ENABLE(OILPAN)
void FullscreenElementStack::documentWasDisposed()
{
- m_fullScreenElement = 0;
+ // NOTE: the context dispose phase is not supported in oilpan. Please
+ // consider using the detach phase instead.
+ m_fullScreenElement = nullptr;
m_fullScreenElementStack.clear();
}
+#endif
bool FullscreenElementStack::fullScreenIsAllowedForElement(Element* element) const
{
ASSERT(element);
- return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, element->document().ownerElement());
+ return fullscreenIsAllowedForAllOwners(element->document());
}
void FullscreenElementStack::requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType)
{
+ // Ignore this request if the document is not in a live frame.
+ if (!document()->isActive())
+ return;
+
// The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI> has different requirements
// for full screen mode, and do not have the concept of a full screen element stack.
bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST);
@@ -171,7 +190,10 @@ void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
// A descendant browsing context's document has a non-empty fullscreen element stack.
bool descendentHasNonEmptyStack = false;
for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
- if (fullscreenElementFrom(descendant->document())) {
+ if (!descendant->isLocalFrame())
+ continue;
+ ASSERT(toLocalFrame(descendant)->document());
+ if (fullscreenElementFrom(*toLocalFrame(descendant)->document())) {
descendentHasNonEmptyStack = true;
break;
}
@@ -183,13 +205,10 @@ void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
// An algorithm is allowed to show a pop-up if, in the task in which the algorithm is running, either:
// - an activation behavior is currently being processed whose click event was trusted, or
// - the event listener for a trusted click event is being handled.
- // FIXME: Does this need to null-check settings()?
- if (!UserGestureIndicator::processingUserGesture() && (!element->isMediaElement() || document()->settings()->mediaFullscreenRequiresUserGesture()))
+ if (!UserGestureIndicator::processingUserGesture())
break;
// There is a previously-established user preference, security risk, or platform limitation.
- if (!document()->settings() || !document()->settings()->fullScreenEnabled())
- break;
// 2. Let doc be element's node document. (i.e. "this")
Document* currentDoc = document();
@@ -217,19 +236,19 @@ void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
// stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
// set to true on the document.
if (!followingDoc) {
- from(currentDoc)->pushFullscreenElementStack(element);
+ from(*currentDoc).pushFullscreenElementStack(element);
addDocumentToFullScreenChangeEventQueue(currentDoc);
continue;
}
// 3. Otherwise, if document's fullscreen element stack is either empty or its top element
// is not following document's browsing context container,
- Element* topElement = fullscreenElementFrom(currentDoc);
+ Element* topElement = fullscreenElementFrom(*currentDoc);
if (!topElement || topElement != followingDoc->ownerElement()) {
// ...push following document's browsing context container on document's fullscreen element
// stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
// set to true on document.
- from(currentDoc)->pushFullscreenElementStack(followingDoc->ownerElement());
+ from(*currentDoc).pushFullscreenElementStack(followingDoc->ownerElement());
addDocumentToFullScreenChangeEventQueue(currentDoc);
continue;
}
@@ -240,14 +259,14 @@ void FullscreenElementStack::requestFullScreenForElement(Element* element, unsig
// 5. Return, and run the remaining steps asynchronously.
// 6. Optionally, perform some animation.
m_areKeysEnabledInFullScreen = flags & Element::ALLOW_KEYBOARD_INPUT;
- document()->page()->chrome().client().enterFullScreenForElement(element);
+ document()->frameHost()->chrome().client().enterFullScreenForElement(element);
// 7. Optionally, display a message indicating how the user can exit displaying the context object fullscreen.
return;
} while (0);
m_fullScreenErrorEventTargetQueue.append(element ? element : document()->documentElement());
- m_fullScreenChangeDelayTimer.startOneShot(0);
+ m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
}
void FullscreenElementStack::webkitCancelFullScreen()
@@ -261,11 +280,11 @@ void FullscreenElementStack::webkitCancelFullScreen()
// To achieve that aim, remove all the elements from the top document's stack except for the first before
// calling webkitExitFullscreen():
- Vector<RefPtr<Element> > replacementFullscreenElementStack;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > replacementFullscreenElementStack;
replacementFullscreenElementStack.append(fullscreenElementFrom(document()->topDocument()));
- FullscreenElementStack* topFullscreenElementStack = from(document()->topDocument());
- topFullscreenElementStack->m_fullScreenElementStack.swap(replacementFullscreenElementStack);
- topFullscreenElementStack->webkitExitFullscreen();
+ FullscreenElementStack& topFullscreenElementStack = from(document()->topDocument());
+ topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscreenElementStack);
+ topFullscreenElementStack.webkitExitFullscreen();
}
void FullscreenElementStack::webkitExitFullscreen()
@@ -274,6 +293,8 @@ void FullscreenElementStack::webkitExitFullscreen()
// 1. Let doc be the context object. (i.e. "this")
Document* currentDoc = document();
+ if (!currentDoc->isActive())
+ return;
// 2. If doc's fullscreen element stack is empty, terminate these steps.
if (m_fullScreenElementStack.isEmpty())
@@ -282,16 +303,20 @@ void FullscreenElementStack::webkitExitFullscreen()
// 3. Let descendants be all the doc's descendant browsing context's documents with a non-empty fullscreen
// element stack (if any), ordered so that the child of the doc is last and the document furthest
// away from the doc is first.
- Deque<RefPtr<Document> > descendants;
- for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
- if (fullscreenElementFrom(descendant->document()))
- descendants.prepend(descendant->document());
+ WillBeHeapDeque<RefPtrWillBeMember<Document> > descendants;
+ for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
+ if (!descendant->isLocalFrame())
+ continue;
+ ASSERT(toLocalFrame(descendant)->document());
+ if (fullscreenElementFrom(*toLocalFrame(descendant)->document()))
+ descendants.prepend(toLocalFrame(descendant)->document());
}
// 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
// task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
- for (Deque<RefPtr<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
- from(i->get())->clearFullscreenElementStack();
+ for (WillBeHeapDeque<RefPtrWillBeMember<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
+ ASSERT(*i);
+ from(**i).clearFullscreenElementStack();
addDocumentToFullScreenChangeEventQueue(i->get());
}
@@ -299,11 +324,11 @@ void FullscreenElementStack::webkitExitFullscreen()
Element* newTop = 0;
while (currentDoc) {
// 1. Pop the top element of doc's fullscreen element stack.
- from(currentDoc)->popFullscreenElementStack();
+ from(*currentDoc).popFullscreenElementStack();
// If doc's fullscreen element stack is non-empty and the element now at the top is either
// not in a document or its node document is not doc, repeat this substep.
- newTop = fullscreenElementFrom(currentDoc);
+ newTop = fullscreenElementFrom(*currentDoc);
if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
continue;
@@ -325,43 +350,40 @@ void FullscreenElementStack::webkitExitFullscreen()
// 6. Return, and run the remaining steps asynchronously.
// 7. Optionally, perform some animation.
- if (!document()->page())
+ FrameHost* host = document()->frameHost();
+
+ // Speculative fix for engaget.com/videos per crbug.com/336239.
+ // FIXME: This check is wrong. We ASSERT(document->isActive()) above
+ // so this should be redundant and should be removed!
+ if (!host)
return;
// Only exit out of full screen window mode if there are no remaining elements in the
// full screen stack.
if (!newTop) {
- document()->page()->chrome().client().exitFullScreenForElement(m_fullScreenElement.get());
+ host->chrome().client().exitFullScreenForElement(m_fullScreenElement.get());
return;
}
// Otherwise, notify the chrome of the new full screen element.
- document()->page()->chrome().client().enterFullScreenForElement(newTop);
+ host->chrome().client().enterFullScreenForElement(newTop);
}
-bool FullscreenElementStack::webkitFullscreenEnabled(Document* document)
+bool FullscreenElementStack::webkitFullscreenEnabled(Document& document)
{
// 4. The fullscreenEnabled attribute must return true if the context object and all ancestor
// browsing context's documents have their fullscreen enabled flag set, or false otherwise.
// Top-level browsing contexts are implied to have their allowFullScreen attribute set.
- return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, document->ownerElement());
-
+ return fullscreenIsAllowedForAllOwners(document);
}
void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* element)
{
- if (!document()->isActive())
- return;
-
ASSERT(element);
-
- // Protect against being called after the document has been removed from the page.
- if (!document()->settings())
+ if (!document()->isActive())
return;
- ASSERT(document()->settings()->fullScreenEnabled());
-
if (m_fullScreenRenderer)
m_fullScreenRenderer->unwrapRenderer();
@@ -383,7 +405,9 @@ void FullscreenElementStack::webkitWillEnterFullScreenForElement(Element* elemen
m_fullScreenElement->setContainsFullScreenElementOnAncestorsCrossingFrameBoundaries(true);
- document()->recalcStyle(Force);
+ // FIXME: This should not call updateStyleIfNeeded.
+ document()->setNeedsStyleRecalc(SubtreeStyleChange);
+ document()->updateRenderTreeIfNeeded();
}
void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*)
@@ -396,7 +420,7 @@ void FullscreenElementStack::webkitDidEnterFullScreenForElement(Element*)
m_fullScreenElement->didBecomeFullscreenElement();
- m_fullScreenChangeDelayTimer.startOneShot(0);
+ m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
}
void FullscreenElementStack::webkitWillExitFullScreenForElement(Element*)
@@ -425,16 +449,17 @@ void FullscreenElementStack::webkitDidExitFullScreenForElement(Element*)
if (m_fullScreenRenderer)
m_fullScreenRenderer->unwrapRenderer();
- m_fullScreenElement = 0;
- document()->setNeedsStyleRecalc();
+ m_fullScreenElement = nullptr;
+ document()->setNeedsStyleRecalc(SubtreeStyleChange);
// When webkitCancelFullScreen is called, we call webkitExitFullScreen on the topDocument(). That
// means that the events will be queued there. So if we have no events here, start the timer on
// the exiting document.
Document* exitingDocument = document();
if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTargetQueue.isEmpty())
- exitingDocument = document()->topDocument();
- from(exitingDocument)->m_fullScreenChangeDelayTimer.startOneShot(0);
+ exitingDocument = &document()->topDocument();
+ ASSERT(exitingDocument);
+ from(*exitingDocument).m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
}
void FullscreenElementStack::setFullScreenRenderer(RenderFullScreen* renderer)
@@ -466,14 +491,14 @@ void FullscreenElementStack::fullScreenChangeDelayTimerFired(Timer<FullscreenEle
// Since we dispatch events in this function, it's possible that the
// document will be detached and GC'd. We protect it here to make sure we
// can finish the function successfully.
- RefPtr<Document> protectDocument(document());
- Deque<RefPtr<Node> > changeQueue;
+ RefPtrWillBeRawPtr<Document> protectDocument(document());
+ WillBeHeapDeque<RefPtrWillBeMember<Node> > changeQueue;
m_fullScreenChangeEventTargetQueue.swap(changeQueue);
- Deque<RefPtr<Node> > errorQueue;
+ WillBeHeapDeque<RefPtrWillBeMember<Node> > errorQueue;
m_fullScreenErrorEventTargetQueue.swap(errorQueue);
while (!changeQueue.isEmpty()) {
- RefPtr<Node> node = changeQueue.takeFirst();
+ RefPtrWillBeRawPtr<Node> node = changeQueue.takeFirst();
if (!node)
node = document()->documentElement();
// The dispatchEvent below may have blown away our documentElement.
@@ -489,7 +514,7 @@ void FullscreenElementStack::fullScreenChangeDelayTimerFired(Timer<FullscreenEle
}
while (!errorQueue.isEmpty()) {
- RefPtr<Node> node = errorQueue.takeFirst();
+ RefPtrWillBeRawPtr<Node> node = errorQueue.takeFirst();
if (!node)
node = document()->documentElement();
// The dispatchEvent below may have blown away our documentElement.
@@ -553,7 +578,7 @@ void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d
ASSERT(doc);
Node* target = 0;
- if (FullscreenElementStack* fullscreen = fromIfExists(doc)) {
+ if (FullscreenElementStack* fullscreen = fromIfExists(*doc)) {
target = fullscreen->webkitFullscreenElement();
if (!target)
target = fullscreen->webkitCurrentFullScreenElement();
@@ -564,4 +589,13 @@ void FullscreenElementStack::addDocumentToFullScreenChangeEventQueue(Document* d
m_fullScreenChangeEventTargetQueue.append(target);
}
+void FullscreenElementStack::trace(Visitor* visitor)
+{
+ visitor->trace(m_fullScreenElement);
+ visitor->trace(m_fullScreenElementStack);
+ visitor->trace(m_fullScreenChangeEventTargetQueue);
+ visitor->trace(m_fullScreenErrorEventTargetQueue);
+ DocumentSupplement::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h b/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h
index 4211a8387da..852812a70d4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h
+++ b/chromium/third_party/WebKit/Source/core/dom/FullscreenElementStack.h
@@ -28,6 +28,7 @@
#ifndef FullscreenElementStack_h
#define FullscreenElementStack_h
+#include "core/dom/Document.h"
#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/Element.h"
#include "platform/Supplementable.h"
@@ -39,24 +40,22 @@
namespace WebCore {
-class Document;
-class Element;
-class Node;
class RenderFullScreen;
class RenderStyle;
-class ExecutionContext;
-class FullscreenElementStack
- : public DocumentSupplement
+class FullscreenElementStack FINAL
+ : public NoBaseWillBeGarbageCollectedFinalized<FullscreenElementStack>
+ , public DocumentSupplement
, public DocumentLifecycleObserver {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FullscreenElementStack);
public:
virtual ~FullscreenElementStack();
static const char* supplementName();
- static FullscreenElementStack* from(Document*);
- static FullscreenElementStack* fromIfExists(Document*);
- static Element* fullscreenElementFrom(Document*);
- static Element* currentFullScreenElementFrom(Document*);
- static bool isFullScreen(Document*);
+ static FullscreenElementStack& from(Document&);
+ static FullscreenElementStack* fromIfExists(Document&);
+ static Element* fullscreenElementFrom(Document&);
+ static Element* currentFullScreenElementFrom(Document&);
+ static bool isFullScreen(Document&);
static bool isActiveFullScreenElement(const Element*);
enum FullScreenCheckType {
@@ -86,7 +85,7 @@ public:
void removeFullScreenElementOfSubtree(Node*, bool amongChildrenOnly = false);
// W3C API
- static bool webkitFullscreenEnabled(Document*);
+ static bool webkitFullscreenEnabled(Document&);
Element* webkitFullscreenElement() const { return !m_fullScreenElementStack.isEmpty() ? m_fullScreenElementStack.last().get() : 0; }
void webkitExitFullscreen();
@@ -95,38 +94,42 @@ public:
Element* webkitCurrentFullScreenElement() const { return m_fullScreenElement.get(); }
virtual void documentWasDetached() OVERRIDE;
+#if !ENABLE(OILPAN)
virtual void documentWasDisposed() OVERRIDE;
+#endif
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- static FullscreenElementStack* fromIfExistsSlow(Document*);
+ static FullscreenElementStack* fromIfExistsSlow(Document&);
- explicit FullscreenElementStack(Document*);
+ explicit FullscreenElementStack(Document&);
Document* document();
void fullScreenChangeDelayTimerFired(Timer<FullscreenElementStack>*);
bool m_areKeysEnabledInFullScreen;
- RefPtr<Element> m_fullScreenElement;
- Vector<RefPtr<Element> > m_fullScreenElementStack;
+ RefPtrWillBeMember<Element> m_fullScreenElement;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > m_fullScreenElementStack;
RenderFullScreen* m_fullScreenRenderer;
Timer<FullscreenElementStack> m_fullScreenChangeDelayTimer;
- Deque<RefPtr<Node> > m_fullScreenChangeEventTargetQueue;
- Deque<RefPtr<Node> > m_fullScreenErrorEventTargetQueue;
+ WillBeHeapDeque<RefPtrWillBeMember<Node> > m_fullScreenChangeEventTargetQueue;
+ WillBeHeapDeque<RefPtrWillBeMember<Node> > m_fullScreenErrorEventTargetQueue;
LayoutRect m_savedPlaceholderFrameRect;
RefPtr<RenderStyle> m_savedPlaceholderRenderStyle;
};
inline bool FullscreenElementStack::isActiveFullScreenElement(const Element* element)
{
- FullscreenElementStack* controller = fromIfExists(&element->document());
+ FullscreenElementStack* controller = fromIfExists(element->document());
if (!controller)
return false;
return controller->webkitIsFullScreen() && controller->webkitCurrentFullScreenElement() == element;
}
-inline FullscreenElementStack* FullscreenElementStack::fromIfExists(Document* document)
+inline FullscreenElementStack* FullscreenElementStack::fromIfExists(Document& document)
{
- if (!document->hasFullscreenElementStack())
+ if (!document.hasFullscreenElementStack())
return 0;
return fromIfExistsSlow(document);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h b/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h
index 8da83b9add9..933d14f8fb8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h
+++ b/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.h
@@ -36,6 +36,8 @@ namespace WebCore {
namespace GlobalEventHandlers {
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(abort);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(autocomplete);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(autocompleteerror);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(blur);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(cancel);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(canplay);
@@ -81,6 +83,7 @@ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(playing);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(progress);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(ratechange);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(reset);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(resize);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(scroll);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeked);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(seeking);
@@ -90,6 +93,7 @@ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(stalled);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(submit);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(suspend);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(timeupdate);
+DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(toggle);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(volumechange);
DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(waiting);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl b/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
index 880038222f2..c835461307d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/GlobalEventHandlers.idl
@@ -27,56 +27,62 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/#globaleventhandlers
+
[
- NoInterfaceObject
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface GlobalEventHandlers {
attribute EventHandler onabort;
+ [RuntimeEnabled=RequestAutocomplete] attribute EventHandler onautocomplete;
+ [RuntimeEnabled=RequestAutocomplete] attribute EventHandler onautocompleteerror;
attribute EventHandler onblur;
attribute EventHandler oncancel;
attribute EventHandler oncanplay;
attribute EventHandler oncanplaythrough;
attribute EventHandler onchange;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onclick;
+ [LogActivity=SetterOnly] attribute EventHandler onclick;
attribute EventHandler onclose;
attribute EventHandler oncontextmenu;
attribute EventHandler oncuechange;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondblclick;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondrag;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragend;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragenter;
- //[PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragexit;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragleave;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragover;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondragstart;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler ondrop;
+ [LogActivity=SetterOnly] attribute EventHandler ondblclick;
+ [LogActivity=SetterOnly] attribute EventHandler ondrag;
+ [LogActivity=SetterOnly] attribute EventHandler ondragend;
+ [LogActivity=SetterOnly] attribute EventHandler ondragenter;
+ //[LogActivity=SetterOnly] attribute EventHandler ondragexit;
+ [LogActivity=SetterOnly] attribute EventHandler ondragleave;
+ [LogActivity=SetterOnly] attribute EventHandler ondragover;
+ [LogActivity=SetterOnly] attribute EventHandler ondragstart;
+ [LogActivity=SetterOnly] attribute EventHandler ondrop;
attribute EventHandler ondurationchange;
attribute EventHandler onemptied;
attribute EventHandler onended;
attribute EventHandler onerror;
attribute EventHandler onfocus;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler oninput;
+ [LogActivity=SetterOnly] attribute EventHandler oninput;
attribute EventHandler oninvalid;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onkeydown;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onkeypress;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onkeyup;
+ [LogActivity=SetterOnly] attribute EventHandler onkeydown;
+ [LogActivity=SetterOnly] attribute EventHandler onkeypress;
+ [LogActivity=SetterOnly] attribute EventHandler onkeyup;
attribute EventHandler onload;
attribute EventHandler onloadeddata;
attribute EventHandler onloadedmetadata;
attribute EventHandler onloadstart;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmousedown;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseenter;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseleave;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmousemove;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseout;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseover;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmouseup;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onmousewheel;
+ [LogActivity=SetterOnly] attribute EventHandler onmousedown;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseenter;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseleave;
+ [LogActivity=SetterOnly] attribute EventHandler onmousemove;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseout;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseover;
+ [LogActivity=SetterOnly] attribute EventHandler onmouseup;
+ [LogActivity=SetterOnly] attribute EventHandler onmousewheel;
attribute EventHandler onpause;
attribute EventHandler onplay;
attribute EventHandler onplaying;
attribute EventHandler onprogress;
attribute EventHandler onratechange;
attribute EventHandler onreset;
+ attribute EventHandler onresize;
attribute EventHandler onscroll;
attribute EventHandler onseeked;
attribute EventHandler onseeking;
@@ -87,6 +93,7 @@
attribute EventHandler onsubmit;
attribute EventHandler onsuspend;
attribute EventHandler ontimeupdate;
+ attribute EventHandler ontoggle;
attribute EventHandler onvolumechange;
attribute EventHandler onwaiting;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/IconURL.cpp b/chromium/third_party/WebKit/Source/core/dom/IconURL.cpp
index 248835b507e..b427d1a81eb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IconURL.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/IconURL.cpp
@@ -44,7 +44,7 @@ IconURL IconURL::defaultFavicon(const KURL& documentURL)
url.setPort(documentURL.port());
url.setPath("/favicon.ico");
- IconURL result(url, emptyString(), emptyString(), Favicon);
+ IconURL result(url, Vector<IntSize>(), emptyString(), Favicon);
result.m_isDefaultIcon = true;
return result;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/IconURL.h b/chromium/third_party/WebKit/Source/core/dom/IconURL.h
index adec2a7a8fd..4a6fa233342 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IconURL.h
+++ b/chromium/third_party/WebKit/Source/core/dom/IconURL.h
@@ -31,16 +31,11 @@
#ifndef IconURL_h
#define IconURL_h
+#include "platform/geometry/IntSize.h"
#include "platform/weborigin/KURL.h"
namespace WebCore {
-#if ENABLE(TOUCH_ICON_LOADING)
-#define ICON_COUNT 3
-#else
-#define ICON_COUNT 1
-#endif
-
enum IconType {
InvalidIcon = 0,
Favicon = 1,
@@ -50,7 +45,7 @@ enum IconType {
struct IconURL {
IconType m_iconType;
- String m_sizes;
+ Vector<IntSize> m_sizes;
String m_mimeType;
KURL m_iconURL;
bool m_isDefaultIcon;
@@ -61,7 +56,7 @@ struct IconURL {
{
}
- IconURL(const KURL& url, const String& sizes, const String& mimeType, IconType type)
+ IconURL(const KURL& url, const Vector<IntSize>& sizes, const String& mimeType, IconType type)
: m_iconType(type)
, m_sizes(sizes)
, m_mimeType(mimeType)
@@ -75,8 +70,6 @@ struct IconURL {
bool operator==(const IconURL&, const IconURL&);
-typedef Vector<IconURL, ICON_COUNT> IconURLs;
-
}
#endif // IconURL_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp
index 69579955c75..c821d7803c7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.cpp
@@ -30,17 +30,30 @@
namespace WebCore {
-IdTargetObserver::IdTargetObserver(IdTargetObserverRegistry& registry, const AtomicString& id)
- : m_registry(&registry)
+IdTargetObserver::IdTargetObserver(IdTargetObserverRegistry& observerRegistry, const AtomicString& id)
+ : m_registry(&observerRegistry)
, m_id(id)
{
- m_registry->addObserver(m_id, this);
+ registry().addObserver(m_id, this);
}
IdTargetObserver::~IdTargetObserver()
{
- if (m_registry)
- m_registry->removeObserver(m_id, this);
+#if !ENABLE(OILPAN)
+ registry().removeObserver(m_id, this);
+#endif
+}
+
+void IdTargetObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_registry);
+}
+
+void IdTargetObserver::unregister()
+{
+#if ENABLE(OILPAN)
+ registry().removeObserver(m_id, this);
+#endif
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h
index e76b8a5dbf0..71ee604cde4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h
+++ b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserver.h
@@ -26,22 +26,27 @@
#ifndef IdTargetObserver_h
#define IdTargetObserver_h
+#include "platform/heap/Handle.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
class IdTargetObserverRegistry;
-class IdTargetObserver {
+class IdTargetObserver : public NoBaseWillBeGarbageCollectedFinalized<IdTargetObserver> {
public:
virtual ~IdTargetObserver();
+ virtual void trace(Visitor*);
virtual void idTargetChanged() = 0;
+ virtual void unregister();
protected:
IdTargetObserver(IdTargetObserverRegistry&, const AtomicString& id);
private:
- IdTargetObserverRegistry* m_registry;
+ IdTargetObserverRegistry& registry() { return *m_registry; }
+
+ RawPtrWillBeMember<IdTargetObserverRegistry> m_registry;
AtomicString m_id;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp
index 19d297ad5e7..36e7f60c868 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp
@@ -30,9 +30,15 @@
namespace WebCore {
-PassOwnPtr<IdTargetObserverRegistry> IdTargetObserverRegistry::create()
+PassOwnPtrWillBeRawPtr<IdTargetObserverRegistry> IdTargetObserverRegistry::create()
{
- return adoptPtr(new IdTargetObserverRegistry());
+ return adoptPtrWillBeNoop(new IdTargetObserverRegistry());
+}
+
+void IdTargetObserverRegistry::trace(Visitor* visitor)
+{
+ visitor->trace(m_registry);
+ visitor->trace(m_notifyingObserversInSet);
}
void IdTargetObserverRegistry::addObserver(const AtomicString& id, IdTargetObserver* observer)
@@ -42,9 +48,9 @@ void IdTargetObserverRegistry::addObserver(const AtomicString& id, IdTargetObser
IdToObserverSetMap::AddResult result = m_registry.add(id.impl(), nullptr);
if (result.isNewEntry)
- result.iterator->value = adoptPtr(new ObserverSet());
+ result.storedValue->value = adoptPtrWillBeNoop(new ObserverSet());
- result.iterator->value->add(observer);
+ result.storedValue->value->add(observer);
}
void IdTargetObserverRegistry::removeObserver(const AtomicString& id, IdTargetObserver* observer)
@@ -69,9 +75,9 @@ void IdTargetObserverRegistry::notifyObserversInternal(const AtomicString& id)
if (!m_notifyingObserversInSet)
return;
- Vector<IdTargetObserver*> copy;
+ WillBeHeapVector<RawPtrWillBeMember<IdTargetObserver> > copy;
copyToVector(*m_notifyingObserversInSet, copy);
- for (Vector<IdTargetObserver*>::const_iterator it = copy.begin(); it != copy.end(); ++it) {
+ for (WillBeHeapVector<RawPtrWillBeMember<IdTargetObserver> >::const_iterator it = copy.begin(); it != copy.end(); ++it) {
if (m_notifyingObserversInSet->contains(*it))
(*it)->idTargetChanged();
}
@@ -79,7 +85,15 @@ void IdTargetObserverRegistry::notifyObserversInternal(const AtomicString& id)
if (m_notifyingObserversInSet->isEmpty())
m_registry.remove(id.impl());
- m_notifyingObserversInSet = 0;
+ m_notifyingObserversInSet = nullptr;
+}
+
+bool IdTargetObserverRegistry::hasObservers(const AtomicString& id) const
+{
+ if (id.isEmpty() || m_registry.isEmpty())
+ return false;
+ ObserverSet* set = m_registry.get(id.impl());
+ return set && !set->isEmpty();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h
index 4af563a853c..2036b30e6a4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h
+++ b/chromium/third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.h
@@ -26,33 +26,36 @@
#ifndef IdTargetObserverRegistry_h
#define IdTargetObserverRegistry_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
-#include "wtf/PassOwnPtr.h"
#include "wtf/text/StringHash.h"
namespace WebCore {
class IdTargetObserver;
-class IdTargetObserverRegistry {
- WTF_MAKE_FAST_ALLOCATED;
+class IdTargetObserverRegistry FINAL : public NoBaseWillBeGarbageCollectedFinalized<IdTargetObserverRegistry> {
+ WTF_MAKE_NONCOPYABLE(IdTargetObserverRegistry);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
friend class IdTargetObserver;
public:
- static PassOwnPtr<IdTargetObserverRegistry> create();
+ static PassOwnPtrWillBeRawPtr<IdTargetObserverRegistry> create();
+ void trace(Visitor*);
void notifyObservers(const AtomicString& id);
+ bool hasObservers(const AtomicString& id) const;
private:
- IdTargetObserverRegistry() : m_notifyingObserversInSet(0) { }
+ IdTargetObserverRegistry() : m_notifyingObserversInSet(nullptr) { }
void addObserver(const AtomicString& id, IdTargetObserver*);
void removeObserver(const AtomicString& id, IdTargetObserver*);
void notifyObserversInternal(const AtomicString& id);
- typedef HashSet<IdTargetObserver*> ObserverSet;
- typedef HashMap<StringImpl*, OwnPtr<ObserverSet> > IdToObserverSetMap;
+ typedef WillBeHeapHashSet<RawPtrWillBeMember<IdTargetObserver> > ObserverSet;
+ typedef WillBeHeapHashMap<StringImpl*, OwnPtrWillBeMember<ObserverSet> > IdToObserverSetMap;
IdToObserverSetMap m_registry;
- ObserverSet* m_notifyingObserversInSet;
+ RawPtrWillBeMember<ObserverSet> m_notifyingObserversInSet;
};
inline void IdTargetObserverRegistry::notifyObservers(const AtomicString& id)
diff --git a/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp b/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp
new file mode 100644
index 00000000000..36fc264d0a6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.cpp
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/IncrementLoadEventDelayCount.h"
+
+#include "core/dom/Document.h"
+
+namespace WebCore {
+
+IncrementLoadEventDelayCount::IncrementLoadEventDelayCount(Document& document)
+ : m_document(&document)
+{
+ document.incrementLoadEventDelayCount();
+}
+
+IncrementLoadEventDelayCount::~IncrementLoadEventDelayCount()
+{
+ m_document->decrementLoadEventDelayCount();
+}
+
+void IncrementLoadEventDelayCount::documentChanged(Document& newDocument)
+{
+ newDocument.incrementLoadEventDelayCount();
+ m_document->decrementLoadEventDelayCount();
+ m_document = &newDocument;
+}
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h b/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
new file mode 100644
index 00000000000..b90b5201ee2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IncrementLoadEventDelayCount_h
+#define IncrementLoadEventDelayCount_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class Document;
+
+// A helper class that will increment a document's loadEventDelayCount on
+// contruction and decrement it on destruction (semantics similar to RefPtr).
+class IncrementLoadEventDelayCount {
+ WTF_MAKE_NONCOPYABLE(IncrementLoadEventDelayCount);
+
+public:
+ IncrementLoadEventDelayCount(Document&);
+ ~IncrementLoadEventDelayCount();
+
+ // Increments the new document's count and decrements the old count.
+ void documentChanged(Document& newDocument);
+
+private:
+ RefPtrWillBePersistent<Document> m_document;
+};
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp
index 5343cb9520f..a577323050d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.cpp
@@ -23,72 +23,48 @@
#include "config.h"
#include "core/dom/LiveNodeList.h"
-#include "core/dom/Element.h"
-#include "core/html/HTMLCollection.h"
-
namespace WebCore {
-Node& LiveNodeListBase::rootNode() const
+static inline bool isMatchingElement(const LiveNodeList& nodeList, const Element& element)
{
- if (isRootedAtDocument() && m_ownerNode->inDocument())
- return m_ownerNode->document();
- return *m_ownerNode;
+ return nodeList.elementMatches(element);
}
-ContainerNode* LiveNodeListBase::rootContainerNode() const
+Node* LiveNodeList::virtualOwnerNode() const
{
- Node& rootNode = this->rootNode();
- if (!rootNode.isContainerNode())
- return 0;
- return toContainerNode(&rootNode);
+ return &ownerNode();
}
-void LiveNodeListBase::invalidateCache() const
+void LiveNodeList::invalidateCache(Document*) const
{
- m_cachedItem = 0;
- m_isLengthCacheValid = false;
- m_isItemCacheValid = false;
- m_isNameCacheValid = false;
- m_isItemRefElementsCacheValid = false;
- if (isNodeList(type()))
- return;
-
- const HTMLCollection* cacheBase = static_cast<const HTMLCollection*>(this);
- cacheBase->m_idCache.clear();
- cacheBase->m_nameCache.clear();
- cacheBase->m_cachedElementsArrayOffset = 0;
+ m_collectionIndexCache.invalidate();
}
-void LiveNodeListBase::invalidateIdNameCacheMaps() const
+Element* LiveNodeList::traverseToFirstElement() const
{
- ASSERT(hasIdNameCache());
- const HTMLCollection* cacheBase = static_cast<const HTMLCollection*>(this);
- cacheBase->m_idCache.clear();
- cacheBase->m_nameCache.clear();
+ return firstMatchingElement(*this);
}
-Node* LiveNodeList::namedItem(const AtomicString& elementId) const
+Element* LiveNodeList::traverseToLastElement() const
{
- Node& rootNode = this->rootNode();
+ return lastMatchingElement(*this);
+}
- if (rootNode.inDocument()) {
- Element* element = rootNode.treeScope().getElementById(elementId);
- if (element && nodeMatches(element) && element->isDescendantOf(&rootNode))
- return element;
- if (!element)
- return 0;
- // In the case of multiple nodes with the same name, just fall through.
- }
+Element* LiveNodeList::traverseForwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset) const
+{
+ return traverseMatchingElementsForwardToOffset(*this, offset, currentNode, currentOffset);
+}
- unsigned length = this->length();
- for (unsigned i = 0; i < length; i++) {
- Node* node = item(i);
- // FIXME: This should probably be using getIdAttribute instead of idForStyleResolution.
- if (node->hasID() && toElement(node)->idForStyleResolution() == elementId)
- return node;
- }
+Element* LiveNodeList::traverseBackwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset) const
+{
+ return traverseMatchingElementsBackwardToOffset(*this, offset, currentNode, currentOffset);
+}
- return 0;
+void LiveNodeList::trace(Visitor* visitor)
+{
+ visitor->trace(m_collectionIndexCache);
+ LiveNodeListBase::trace(visitor);
+ NodeList::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h b/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h
index 2145b245f9e..ca2da3aedd1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/LiveNodeList.h
@@ -24,182 +24,55 @@
#ifndef LiveNodeList_h
#define LiveNodeList_h
-#include "HTMLNames.h"
-#include "core/dom/Document.h"
+#include "core/dom/LiveNodeListBase.h"
#include "core/dom/NodeList.h"
+#include "core/html/CollectionIndexCache.h"
#include "core/html/CollectionType.h"
-#include "wtf/Forward.h"
-#include "wtf/RefPtr.h"
+#include "platform/heap/Handle.h"
+#include "wtf/PassRefPtr.h"
namespace WebCore {
class Element;
-enum NodeListRootType {
- NodeListIsRootedAtNode,
- NodeListIsRootedAtDocument,
- NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr,
-};
-
-class LiveNodeListBase : public NodeList {
+class LiveNodeList : public NodeList, public LiveNodeListBase {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(LiveNodeList);
public:
- enum ItemAfterOverrideType {
- OverridesItemAfter,
- DoesNotOverrideItemAfter,
- };
-
- LiveNodeListBase(Node* ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType,
- bool shouldOnlyIncludeDirectChildren, CollectionType collectionType, ItemAfterOverrideType itemAfterOverrideType)
- : m_ownerNode(ownerNode)
- , m_cachedItem(0)
- , m_isLengthCacheValid(false)
- , m_isItemCacheValid(false)
- , m_rootType(rootType)
- , m_invalidationType(invalidationType)
- , m_shouldOnlyIncludeDirectChildren(shouldOnlyIncludeDirectChildren)
- , m_isNameCacheValid(false)
- , m_collectionType(collectionType)
- , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter)
- , m_isItemRefElementsCacheValid(false)
- {
- ASSERT(m_rootType == static_cast<unsigned>(rootType));
- ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
- ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
- ASSERT(!m_overridesItemAfter || !isNodeList(collectionType));
-
- if (collectionType != ChildNodeListType)
- document().registerNodeList(this);
- }
-
- virtual ~LiveNodeListBase()
- {
- if (type() != ChildNodeListType)
- document().unregisterNodeList(this);
- }
-
- // DOM API
- virtual unsigned length() const OVERRIDE;
- virtual Node* item(unsigned offset) const OVERRIDE;
-
- ALWAYS_INLINE bool hasIdNameCache() const { return !isNodeList(type()); }
- ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument || m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr; }
- ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }
- ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); }
- Node* ownerNode() const { return m_ownerNode.get(); }
- ALWAYS_INLINE void invalidateCache(const QualifiedName* attrName) const
- {
- if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
- invalidateCache();
- else if (hasIdNameCache() && (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr))
- invalidateIdNameCacheMaps();
- }
- void invalidateCache() const;
- void invalidateIdNameCacheMaps() const;
-
- static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
-
-protected:
- Document& document() const { return m_ownerNode->document(); }
- Node& rootNode() const;
- ContainerNode* rootContainerNode() const;
- bool overridesItemAfter() const { return m_overridesItemAfter; }
-
- ALWAYS_INLINE bool isItemCacheValid() const { return m_isItemCacheValid; }
- ALWAYS_INLINE Node* cachedItem() const { return m_cachedItem; }
- ALWAYS_INLINE unsigned cachedItemOffset() const { return m_cachedItemOffset; }
-
- ALWAYS_INLINE bool isLengthCacheValid() const { return m_isLengthCacheValid; }
- ALWAYS_INLINE unsigned cachedLength() const { return m_cachedLength; }
- ALWAYS_INLINE void setLengthCache(unsigned length) const
- {
- m_cachedLength = length;
- m_isLengthCacheValid = true;
- }
- ALWAYS_INLINE void setItemCache(Node* item, unsigned offset) const
- {
- ASSERT(item);
- m_cachedItem = item;
- m_cachedItemOffset = offset;
- m_isItemCacheValid = true;
- }
- void setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const;
-
- ALWAYS_INLINE bool isItemRefElementsCacheValid() const { return m_isItemRefElementsCacheValid; }
- ALWAYS_INLINE void setItemRefElementsCacheValid() const { m_isItemRefElementsCacheValid = true; }
-
- ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); }
-
- bool hasNameCache() const { return m_isNameCacheValid; }
- void setHasNameCache() const { m_isNameCacheValid = true; }
-
- bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDirectChildren; }
+ LiveNodeList(ContainerNode& ownerNode, CollectionType collectionType, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode)
+ : LiveNodeListBase(ownerNode, rootType, invalidationType, collectionType) { }
-private:
- Node* itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode* root) const;
- Node* traverseChildNodeListForwardToOffset(unsigned offset, Node* currentNode, unsigned& currentOffset) const;
- Element* traverseLiveNodeListFirstElement(ContainerNode& root) const;
- Element* traverseLiveNodeListForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, ContainerNode* root) const;
- bool isLastItemCloserThanLastOrCachedItem(unsigned offset) const;
- bool isFirstItemCloserThanCachedItem(unsigned offset) const;
- Node* iterateForPreviousNode(Node* current) const;
- Node* itemBefore(Node* previousItem) const;
-
- RefPtr<Node> m_ownerNode;
- mutable Node* m_cachedItem;
- mutable unsigned m_cachedLength;
- mutable unsigned m_cachedItemOffset;
- mutable unsigned m_isLengthCacheValid : 1;
- mutable unsigned m_isItemCacheValid : 1;
- const unsigned m_rootType : 2;
- const unsigned m_invalidationType : 4;
- const unsigned m_shouldOnlyIncludeDirectChildren : 1;
-
- // From HTMLCollection
- mutable unsigned m_isNameCacheValid : 1;
- const unsigned m_collectionType : 5;
- const unsigned m_overridesItemAfter : 1;
- mutable unsigned m_isItemRefElementsCacheValid : 1;
-};
+ virtual unsigned length() const OVERRIDE FINAL { return m_collectionIndexCache.nodeCount(*this); }
+ virtual Element* item(unsigned offset) const OVERRIDE FINAL { return m_collectionIndexCache.nodeAt(*this, offset); }
+ virtual bool elementMatches(const Element&) const = 0;
-ALWAYS_INLINE bool LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType type, const QualifiedName& attrName)
-{
- switch (type) {
- case InvalidateOnClassAttrChange:
- return attrName == HTMLNames::classAttr;
- case InvalidateOnNameAttrChange:
- return attrName == HTMLNames::nameAttr;
- case InvalidateOnIdNameAttrChange:
- return attrName == HTMLNames::idAttr || attrName == HTMLNames::nameAttr;
- case InvalidateOnForAttrChange:
- return attrName == HTMLNames::forAttr;
- case InvalidateForFormControls:
- return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr
- || attrName == HTMLNames::formAttr || attrName == HTMLNames::typeAttr;
- case InvalidateOnHRefAttrChange:
- return attrName == HTMLNames::hrefAttr;
- case InvalidateOnItemAttrChange:
- case DoNotInvalidateOnAttributeChanges:
- return false;
- case InvalidateOnAnyAttrChange:
- return true;
- }
- return false;
-}
+ virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE FINAL;
+ void invalidateCacheForAttribute(const QualifiedName*) const;
-class LiveNodeList : public LiveNodeListBase {
-public:
- LiveNodeList(PassRefPtr<Node> ownerNode, CollectionType collectionType, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode)
- : LiveNodeListBase(ownerNode.get(), rootType, invalidationType, collectionType == ChildNodeListType,
- collectionType, DoesNotOverrideItemAfter)
- { }
+ bool shouldOnlyIncludeDirectChildren() const { return false; }
- virtual Node* namedItem(const AtomicString&) const OVERRIDE;
- virtual bool nodeMatches(Element*) const = 0;
+ // Collection IndexCache API.
+ bool canTraverseBackward() const { return true; }
+ Element* traverseToFirstElement() const;
+ Element* traverseToLastElement() const;
+ Element* traverseForwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset) const;
+ Element* traverseBackwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset) const;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- virtual bool isLiveNodeList() const OVERRIDE { return true; }
+ virtual Node* virtualOwnerNode() const OVERRIDE FINAL;
+
+ mutable CollectionIndexCache<LiveNodeList, Element> m_collectionIndexCache;
};
+DEFINE_TYPE_CASTS(LiveNodeList, LiveNodeListBase, list, isLiveNodeListType(list->type()), isLiveNodeListType(list.type()));
+
+inline void LiveNodeList::invalidateCacheForAttribute(const QualifiedName* attrName) const
+{
+ if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
+ invalidateCache();
+}
+
} // namespace WebCore
#endif // LiveNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp b/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp
new file mode 100644
index 00000000000..bfcea21151d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/LiveNodeListBase.h"
+
+#include "core/dom/LiveNodeList.h"
+#include "core/html/HTMLCollection.h"
+
+namespace WebCore {
+
+void LiveNodeListBase::invalidateCacheForAttribute(const QualifiedName* attrName) const
+{
+ if (isLiveNodeListType(type()))
+ toLiveNodeList(this)->invalidateCacheForAttribute(attrName);
+ else
+ toHTMLCollection(this)->invalidateCacheForAttribute(attrName);
+}
+
+ContainerNode& LiveNodeListBase::rootNode() const
+{
+ if (isRootedAtDocument() && m_ownerNode->inDocument())
+ return m_ownerNode->document();
+ return *m_ownerNode;
+}
+
+void LiveNodeListBase::didMoveToDocument(Document& oldDocument, Document& newDocument)
+{
+ invalidateCache(&oldDocument);
+ oldDocument.unregisterNodeList(this);
+ newDocument.registerNodeList(this);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.h b/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.h
new file mode 100644
index 00000000000..f301ad89d77
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/LiveNodeListBase.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LiveNodeListBase_h
+#define LiveNodeListBase_h
+
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/NodeTraversal.h"
+#include "core/html/CollectionType.h"
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+enum NodeListRootType {
+ NodeListIsRootedAtNode,
+ NodeListIsRootedAtDocument
+};
+
+class LiveNodeListBase : public WillBeGarbageCollectedMixin {
+public:
+ LiveNodeListBase(ContainerNode& ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType,
+ CollectionType collectionType)
+ : m_ownerNode(ownerNode)
+ , m_rootType(rootType)
+ , m_invalidationType(invalidationType)
+ , m_collectionType(collectionType)
+ {
+ ASSERT(m_rootType == static_cast<unsigned>(rootType));
+ ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
+ ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
+
+ document().registerNodeList(this);
+ }
+
+ virtual ~LiveNodeListBase()
+ {
+#if !ENABLE(OILPAN)
+ document().unregisterNodeList(this);
+#endif
+ }
+
+ ContainerNode& rootNode() const;
+
+ void didMoveToDocument(Document& oldDocument, Document& newDocument);
+ ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument; }
+ ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }
+ ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); }
+ ContainerNode& ownerNode() const { return *m_ownerNode; }
+
+ virtual void invalidateCache(Document* oldDocument = 0) const = 0;
+ void invalidateCacheForAttribute(const QualifiedName*) const;
+
+ static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
+
+protected:
+ Document& document() const { return m_ownerNode->document(); }
+
+ ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); }
+
+ template <class NodeListType>
+ static Element* firstMatchingElement(const NodeListType&);
+ template <class NodeListType>
+ static Element* lastMatchingElement(const NodeListType&);
+ template <class NodeListType>
+ static Element* nextMatchingElement(const NodeListType&, Element& current);
+ template <class NodeListType>
+ static Element* previousMatchingElement(const NodeListType&, Element& current);
+ template <class NodeListType>
+ static Element* traverseMatchingElementsForwardToOffset(const NodeListType&, unsigned offset, Element& currentElement, unsigned& currentOffset);
+ template <class NodeListType>
+ static Element* traverseMatchingElementsBackwardToOffset(const NodeListType&, unsigned offset, Element& currentElement, unsigned& currentOffset);
+
+ void trace(Visitor* visitor) { visitor->trace(m_ownerNode); }
+
+private:
+ RefPtrWillBeMember<ContainerNode> m_ownerNode; // Cannot be null.
+ const unsigned m_rootType : 1;
+ const unsigned m_invalidationType : 4;
+ const unsigned m_collectionType : 5;
+};
+
+ALWAYS_INLINE bool LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType type, const QualifiedName& attrName)
+{
+ switch (type) {
+ case InvalidateOnClassAttrChange:
+ return attrName == HTMLNames::classAttr;
+ case InvalidateOnNameAttrChange:
+ return attrName == HTMLNames::nameAttr;
+ case InvalidateOnIdNameAttrChange:
+ return attrName == HTMLNames::idAttr || attrName == HTMLNames::nameAttr;
+ case InvalidateOnForAttrChange:
+ return attrName == HTMLNames::forAttr;
+ case InvalidateForFormControls:
+ return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr
+ || attrName == HTMLNames::formAttr || attrName == HTMLNames::typeAttr;
+ case InvalidateOnHRefAttrChange:
+ return attrName == HTMLNames::hrefAttr;
+ case DoNotInvalidateOnAttributeChanges:
+ return false;
+ case InvalidateOnAnyAttrChange:
+ return true;
+ }
+ return false;
+}
+
+template <typename NodeListType>
+Element* LiveNodeListBase::lastMatchingElement(const NodeListType& nodeList)
+{
+ ContainerNode& root = nodeList.rootNode();
+ Element* element = ElementTraversal::lastWithin(root);
+ while (element && !isMatchingElement(nodeList, *element))
+ element = ElementTraversal::previous(*element, &root);
+ return element;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::firstMatchingElement(const NodeListType& nodeList)
+{
+ ContainerNode& root = nodeList.rootNode();
+ Element* element = ElementTraversal::firstWithin(root);
+ while (element && !isMatchingElement(nodeList, *element))
+ element = ElementTraversal::next(*element, &root);
+ return element;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::nextMatchingElement(const NodeListType& nodeList, Element& current)
+{
+ ContainerNode& root = nodeList.rootNode();
+ Element* next = &current;
+ do {
+ next = ElementTraversal::next(*next, &root);
+ } while (next && !isMatchingElement(nodeList, *next));
+ return next;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::previousMatchingElement(const NodeListType& nodeList, Element& current)
+{
+ ContainerNode& root = nodeList.rootNode();
+ Element* previous = &current;
+ do {
+ previous = ElementTraversal::previous(*previous, &root);
+ } while (previous && !isMatchingElement(nodeList, *previous));
+ return previous;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::traverseMatchingElementsForwardToOffset(const NodeListType& nodeList, unsigned offset, Element& currentElement, unsigned& currentOffset)
+{
+ ASSERT(currentOffset < offset);
+ Element* next = &currentElement;
+ while ((next = nextMatchingElement(nodeList, *next))) {
+ if (++currentOffset == offset)
+ return next;
+ }
+ return 0;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::traverseMatchingElementsBackwardToOffset(const NodeListType& nodeList, unsigned offset, Element& currentElement, unsigned& currentOffset)
+{
+ ASSERT(currentOffset > offset);
+ Element* previous = &currentElement;
+ while ((previous = previousMatchingElement(nodeList, *previous))) {
+ if (--currentOffset == offset)
+ return previous;
+ }
+ return 0;
+}
+
+} // namespace WebCore
+
+#endif // LiveNodeListBase_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp b/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp
index 976d971ce66..d8b53106188 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp
@@ -99,7 +99,7 @@ void MainThreadTaskRunner::resume()
{
ASSERT(m_suspended);
if (!m_pendingTasks.isEmpty())
- m_pendingTasksTimer.startOneShot(0);
+ m_pendingTasksTimer.startOneShot(0, FROM_HERE);
m_suspended = false;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp b/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp
index ca1779947a4..56e05f9940d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MainThreadTaskRunnerTest.cpp
@@ -28,50 +28,19 @@
#include "config.h"
#include "core/dom/MainThreadTaskRunner.h"
-#include "core/dom/ExecutionContext.h"
#include "core/dom/ExecutionContextTask.h"
-#include "core/events/EventQueue.h"
+#include "core/testing/NullExecutionContext.h"
#include "core/testing/UnitTestHelpers.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
#include <gtest/gtest.h>
using namespace WebCore;
namespace {
-class NullEventQueue : public EventQueue {
-public:
- NullEventQueue() { }
- virtual ~NullEventQueue() { }
- virtual bool enqueueEvent(PassRefPtr<Event>) OVERRIDE { return true; }
- virtual bool cancelEvent(Event*) OVERRIDE { return true; }
- virtual void close() OVERRIDE { }
-};
-
-class NullExecutionContext : public ExecutionContext, public RefCounted<NullExecutionContext> {
-public:
- using RefCounted<NullExecutionContext>::ref;
- using RefCounted<NullExecutionContext>::deref;
-
- virtual void refExecutionContext() OVERRIDE { ref(); }
- virtual void derefExecutionContext() OVERRIDE { deref(); }
- virtual EventQueue* eventQueue() const OVERRIDE { return m_queue.get(); }
- virtual bool tasksNeedSuspension() { return m_tasksNeedSuspension; }
-
- void setTasksNeedSuspention(bool flag) { m_tasksNeedSuspension = flag; }
-
- NullExecutionContext();
-
-private:
- bool m_tasksNeedSuspension;
- OwnPtr<EventQueue> m_queue;
-};
-
-NullExecutionContext::NullExecutionContext()
- : m_tasksNeedSuspension(false)
- , m_queue(adoptPtr(new NullEventQueue()))
-{
-}
-
class MarkingBooleanTask FINAL : public ExecutionContextTask {
public:
static PassOwnPtr<MarkingBooleanTask> create(bool* toBeMarked)
@@ -95,7 +64,7 @@ private:
TEST(MainThreadTaskRunnerTest, PostTask)
{
- RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
+ RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
@@ -107,17 +76,17 @@ TEST(MainThreadTaskRunnerTest, PostTask)
TEST(MainThreadTaskRunnerTest, SuspendTask)
{
- RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
+ RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
- context->setTasksNeedSuspention(true);
+ context->setTasksNeedSuspension(true);
runner->postTask(MarkingBooleanTask::create(&isMarked));
runner->suspend();
WebCore::testing::runPendingTasks();
EXPECT_FALSE(isMarked);
- context->setTasksNeedSuspention(false);
+ context->setTasksNeedSuspension(false);
runner->resume();
WebCore::testing::runPendingTasks();
EXPECT_TRUE(isMarked);
@@ -125,11 +94,11 @@ TEST(MainThreadTaskRunnerTest, SuspendTask)
TEST(MainThreadTaskRunnerTest, RemoveRunner)
{
- RefPtr<NullExecutionContext> context = adoptRef(new NullExecutionContext());
+ RefPtrWillBeRawPtr<NullExecutionContext> context = adoptRefWillBeNoop(new NullExecutionContext());
OwnPtr<MainThreadTaskRunner> runner = MainThreadTaskRunner::create(context.get());
bool isMarked = false;
- context->setTasksNeedSuspention(true);
+ context->setTasksNeedSuspension(true);
runner->postTask(MarkingBooleanTask::create(&isMarked));
runner.clear();
WebCore::testing::runPendingTasks();
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp
index 20a493d97c8..0131a3b6581 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.cpp
@@ -35,17 +35,14 @@ namespace WebCore {
static void createChannel(MessagePort* port1, MessagePort* port2)
{
- // Create proxies for each endpoint.
- OwnPtr<blink::WebMessagePortChannel> channel1 = adoptPtr(blink::Platform::current()->createMessagePortChannel());
- OwnPtr<blink::WebMessagePortChannel> channel2 = adoptPtr(blink::Platform::current()->createMessagePortChannel());
-
- // Entangle the two endpoints.
- channel1->entangle(channel2.get());
- channel2->entangle(channel1.get());
+ blink::WebMessagePortChannel* channel1;
+ blink::WebMessagePortChannel* channel2;
+ blink::Platform::current()->createMessageChannel(&channel1, &channel2);
+ ASSERT(channel1 && channel2);
// Now entangle the proxies with the appropriate local ports.
- port1->entangle(channel2.release());
- port2->entangle(channel1.release());
+ port1->entangle(adoptPtr(channel2));
+ port2->entangle(adoptPtr(channel1));
}
MessageChannel::MessageChannel(ExecutionContext* context)
@@ -60,4 +57,10 @@ MessageChannel::~MessageChannel()
{
}
+void MessageChannel::trace(Visitor* visitor)
+{
+ visitor->trace(m_port1);
+ visitor->trace(m_port2);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.h b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.h
index 5b1dc49a04f..750c601e5fc 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.h
@@ -28,6 +28,7 @@
#define MessageChannel_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -37,19 +38,24 @@ namespace WebCore {
class MessagePort;
class ExecutionContext;
-class MessageChannel : public RefCounted<MessageChannel>, public ScriptWrappable {
+class MessageChannel FINAL : public RefCountedWillBeGarbageCollectedFinalized<MessageChannel>, public ScriptWrappable {
public:
- static PassRefPtr<MessageChannel> create(ExecutionContext* context) { return adoptRef(new MessageChannel(context)); }
+ static PassRefPtrWillBeRawPtr<MessageChannel> create(ExecutionContext* context)
+ {
+ return adoptRefWillBeNoop(new MessageChannel(context));
+ }
~MessageChannel();
MessagePort* port1() const { return m_port1.get(); }
MessagePort* port2() const { return m_port2.get(); }
+ void trace(Visitor*);
+
private:
explicit MessageChannel(ExecutionContext*);
- RefPtr<MessagePort> m_port1;
- RefPtr<MessagePort> m_port2;
+ RefPtrWillBeMember<MessagePort> m_port1;
+ RefPtrWillBeMember<MessagePort> m_port2;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl
index fbd8babde20..3a1123c78d1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/MessageChannel.idl
@@ -26,7 +26,8 @@
[
CustomConstructor,
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker,
+ WillBeGarbageCollected
] interface MessageChannel {
readonly attribute MessagePort port1;
readonly attribute MessagePort port2;
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp b/chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp
index 887bfc9bad7..1426ddbb838 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MessagePort.cpp
@@ -34,8 +34,7 @@
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/events/MessageEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/workers/WorkerGlobalScope.h"
#include "public/platform/WebString.h"
#include "wtf/Functional.h"
@@ -43,9 +42,9 @@
namespace WebCore {
-PassRefPtr<MessagePort> MessagePort::create(ExecutionContext& executionContext)
+PassRefPtrWillBeRawPtr<MessagePort> MessagePort::create(ExecutionContext& executionContext)
{
- RefPtr<MessagePort> port = adoptRef(new MessagePort(executionContext));
+ RefPtrWillBeRawPtr<MessagePort> port = adoptRefWillBeRefCountedGarbageCollected(new MessagePort(executionContext));
port->suspendIfNeeded();
return port.release();
}
@@ -74,10 +73,10 @@ void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, const M
OwnPtr<MessagePortChannelArray> channels;
// Make sure we aren't connected to any of the passed-in ports.
if (ports) {
- for (unsigned int i = 0; i < ports->size(); ++i) {
+ for (unsigned i = 0; i < ports->size(); ++i) {
MessagePort* dataPort = (*ports)[i].get();
if (dataPort == this) {
- exceptionState.throwDOMException(DataCloneError, "Item #" + String::number(i) + " in the array of ports contains the source port.");
+ exceptionState.throwDOMException(DataCloneError, "Port at index " + String::number(i) + " contains the source port.");
return;
}
}
@@ -87,13 +86,33 @@ void MessagePort::postMessage(PassRefPtr<SerializedScriptValue> message, const M
}
blink::WebString messageString = message->toWireString();
- blink::WebMessagePortChannelArray* webChannels = 0;
+ OwnPtr<blink::WebMessagePortChannelArray> webChannels = toWebMessagePortChannelArray(channels.release());
+ m_entangledChannel->postMessage(messageString, webChannels.leakPtr());
+}
+
+// static
+PassOwnPtr<blink::WebMessagePortChannelArray> MessagePort::toWebMessagePortChannelArray(PassOwnPtr<MessagePortChannelArray> channels)
+{
+ OwnPtr<blink::WebMessagePortChannelArray> webChannels;
if (channels && channels->size()) {
- webChannels = new blink::WebMessagePortChannelArray(channels->size());
+ webChannels = adoptPtr(new blink::WebMessagePortChannelArray(channels->size()));
for (size_t i = 0; i < channels->size(); ++i)
(*webChannels)[i] = (*channels)[i].leakPtr();
}
- m_entangledChannel->postMessage(messageString, webChannels);
+ return webChannels.release();
+}
+
+// static
+PassOwnPtr<MessagePortArray> MessagePort::toMessagePortArray(ExecutionContext* context, const blink::WebMessagePortChannelArray& webChannels)
+{
+ OwnPtr<MessagePortArray> ports;
+ if (!webChannels.isEmpty()) {
+ OwnPtr<MessagePortChannelArray> channels = adoptPtr(new MessagePortChannelArray(webChannels.size()));
+ for (size_t i = 0; i < webChannels.size(); ++i)
+ (*channels)[i] = adoptPtr(webChannels[i]);
+ ports = MessagePort::entanglePorts(*context, channels.release());
+ }
+ return ports.release();
}
PassOwnPtr<blink::WebMessagePortChannel> MessagePort::disentangle()
@@ -178,7 +197,7 @@ void MessagePort::dispatchMessages()
return;
OwnPtr<MessagePortArray> ports = MessagePort::entanglePorts(*executionContext(), channels.release());
- RefPtr<Event> evt = MessageEvent::create(ports.release(), message.release());
+ RefPtrWillBeRawPtr<Event> evt = MessageEvent::create(ports.release(), message.release());
dispatchEvent(evt.release(), ASSERT_NO_EXCEPTION);
}
@@ -210,7 +229,7 @@ PassOwnPtr<MessagePortChannelArray> MessagePort::disentanglePorts(const MessageP
type = "already neutered";
else
type = "a duplicate";
- exceptionState.throwDOMException(DataCloneError, "Item #" + String::number(i) + " in the array of ports is " + type + ".");
+ exceptionState.throwDOMException(DataCloneError, "Port at index " + String::number(i) + " is " + type + ".");
return nullptr;
}
portSet.add(port);
@@ -229,7 +248,7 @@ PassOwnPtr<MessagePortArray> MessagePort::entanglePorts(ExecutionContext& contex
return nullptr;
OwnPtr<MessagePortArray> portArray = adoptPtr(new MessagePortArray(channels->size()));
- for (unsigned int i = 0; i < channels->size(); ++i) {
+ for (unsigned i = 0; i < channels->size(); ++i) {
RefPtr<MessagePort> port = MessagePort::create(context);
port->entangle((*channels)[i].release());
(*portArray)[i] = port.release();
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessagePort.h b/chromium/third_party/WebKit/Source/core/dom/MessagePort.h
index c5f78eac9ee..648f574979a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessagePort.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MessagePort.h
@@ -45,7 +45,7 @@ namespace WebCore {
class Event;
class ExceptionState;
-class Frame;
+class LocalFrame;
class MessagePort;
class ExecutionContext;
class SerializedScriptValue;
@@ -56,14 +56,15 @@ typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
// Not to be confused with blink::WebMessagePortChannelArray; this one uses Vector and OwnPtr instead of WebVector and raw pointers.
typedef Vector<OwnPtr<blink::WebMessagePortChannel>, 1> MessagePortChannelArray;
-class MessagePort : public RefCounted<MessagePort>
+class MessagePort FINAL : public RefCountedWillBeRefCountedGarbageCollected<MessagePort>
, public ActiveDOMObject
, public EventTargetWithInlineData
, public ScriptWrappable
, public blink::WebMessagePortChannelClient {
REFCOUNTED_EVENT_TARGET(MessagePort);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MessagePort);
public:
- static PassRefPtr<MessagePort> create(ExecutionContext&);
+ static PassRefPtrWillBeRawPtr<MessagePort> create(ExecutionContext&);
virtual ~MessagePort();
void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, ExceptionState&);
@@ -74,6 +75,9 @@ public:
void entangle(PassOwnPtr<blink::WebMessagePortChannel>);
PassOwnPtr<blink::WebMessagePortChannel> disentangle();
+ static PassOwnPtr<blink::WebMessagePortChannelArray> toWebMessagePortChannelArray(PassOwnPtr<MessagePortChannelArray>);
+ static PassOwnPtr<MessagePortArray> toMessagePortArray(ExecutionContext*, const blink::WebMessagePortChannelArray&);
+
// Returns 0 if there is an exception, or if the passed-in array is 0/empty.
static PassOwnPtr<MessagePortChannelArray> disentanglePorts(const MessagePortArray*, ExceptionState&);
@@ -84,18 +88,18 @@ public:
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ExecutionContext* executionContext() const OVERRIDE { return ActiveDOMObject::executionContext(); }
- MessagePort* toMessagePort() OVERRIDE { return this; }
+ virtual MessagePort* toMessagePort() OVERRIDE { return this; }
// ActiveDOMObject implementation.
virtual bool hasPendingActivity() const OVERRIDE;
virtual void stop() OVERRIDE { close(); }
- void setOnmessage(PassRefPtr<EventListener> listener, DOMWrapperWorld* world)
+ void setOnmessage(PassRefPtr<EventListener> listener)
{
- setAttributeEventListener(EventTypeNames::message, listener, world);
+ setAttributeEventListener(EventTypeNames::message, listener);
start();
}
- EventListener* onmessage(DOMWrapperWorld* world) { return getAttributeEventListener(EventTypeNames::message, world); }
+ EventListener* onmessage() { return getAttributeEventListener(EventTypeNames::message); }
// A port starts out its life entangled, and remains entangled until it is closed or is cloned.
bool isEntangled() const { return !m_closed && !isNeutered(); }
diff --git a/chromium/third_party/WebKit/Source/core/dom/MessagePort.idl b/chromium/third_party/WebKit/Source/core/dom/MessagePort.idl
index 17ae44910fe..f834df6318a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MessagePort.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/MessagePort.idl
@@ -26,9 +26,10 @@
*/
[
- ActiveDOMObject
+ ActiveDOMObject,
+ WillBeGarbageCollected
] interface MessagePort : EventTarget {
- [Custom, RaisesException] void postMessage(any message, optional Array messagePorts);
+ [Custom, RaisesException] void postMessage(any message, optional MessagePort[] messagePorts);
void start();
void close();
diff --git a/chromium/third_party/WebKit/Source/core/dom/Microtask.cpp b/chromium/third_party/WebKit/Source/core/dom/Microtask.cpp
index 27cd2178f46..c732cdcaaaf 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Microtask.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Microtask.cpp
@@ -31,26 +31,41 @@
#include "config.h"
#include "core/dom/Microtask.h"
-#include "core/dom/MutationObserver.h"
-#include "core/dom/custom/CustomElementCallbackDispatcher.h"
+#include "bindings/v8/V8PerIsolateData.h"
+#include "platform/Task.h"
+#include "public/platform/WebThread.h"
#include "wtf/Vector.h"
+#include <v8.h>
namespace WebCore {
void Microtask::performCheckpoint()
{
- static bool performingCheckpoint = false;
- if (performingCheckpoint)
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ V8PerIsolateData* isolateData = V8PerIsolateData::from(isolate);
+ ASSERT(isolateData);
+ if (isolateData->recursionLevel() || isolateData->performingMicrotaskCheckpoint())
return;
- performingCheckpoint = true;
+ isolateData->setPerformingMicrotaskCheckpoint(true);
+ isolate->RunMicrotasks();
+ isolateData->setPerformingMicrotaskCheckpoint(false);
+}
- bool anyWorkDone;
- do {
- MutationObserver::deliverAllMutations();
- anyWorkDone = CustomElementCallbackDispatcher::instance().dispatch();
- } while (anyWorkDone);
+static void microtaskFunctionCallback(void* data)
+{
+ OwnPtr<blink::WebThread::Task> task = adoptPtr(static_cast<blink::WebThread::Task*>(data));
+ task->run();
+}
- performingCheckpoint = false;
+void Microtask::enqueueMicrotask(PassOwnPtr<blink::WebThread::Task> callback)
+{
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ isolate->EnqueueMicrotask(&microtaskFunctionCallback, callback.leakPtr());
+}
+
+void Microtask::enqueueMicrotask(const Closure& callback)
+{
+ enqueueMicrotask(adoptPtr(new Task(callback)));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Microtask.h b/chromium/third_party/WebKit/Source/core/dom/Microtask.h
index 27f72cbec01..5bea815d0a9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Microtask.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Microtask.h
@@ -31,11 +31,17 @@
#ifndef Microtask_h
#define Microtask_h
+#include "public/platform/WebThread.h"
+#include "wtf/Functional.h"
+#include "wtf/PassOwnPtr.h"
+
namespace WebCore {
class Microtask {
public:
static void performCheckpoint();
+ static void enqueueMicrotask(PassOwnPtr<blink::WebThread::Task>);
+ static void enqueueMicrotask(const Closure&);
private:
explicit Microtask();
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationCallback.h b/chromium/third_party/WebKit/Source/core/dom/MutationCallback.h
index 88f230bb35d..9445becca81 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationCallback.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationCallback.h
@@ -31,6 +31,7 @@
#ifndef MutationCallback_h
#define MutationCallback_h
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
@@ -43,7 +44,7 @@ class MutationCallback {
public:
virtual ~MutationCallback() { }
- virtual void call(const Vector<RefPtr<MutationRecord> >&, MutationObserver*) = 0;
+ virtual void call(const WillBeHeapVector<RefPtrWillBeMember<MutationRecord> >&, MutationObserver*) = 0;
virtual ExecutionContext* executionContext() const = 0;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp
index 06e610a33f4..e36a1a7b243 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.cpp
@@ -36,10 +36,12 @@
#include "bindings/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/Microtask.h"
#include "core/dom/MutationCallback.h"
#include "core/dom/MutationObserverRegistration.h"
#include "core/dom/MutationRecord.h"
#include "core/dom/Node.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "wtf/MainThread.h"
namespace WebCore {
@@ -47,16 +49,16 @@ namespace WebCore {
static unsigned s_observerPriority = 0;
struct MutationObserver::ObserverLessThan {
- bool operator()(const RefPtr<MutationObserver>& lhs, const RefPtr<MutationObserver>& rhs)
+ bool operator()(const RefPtrWillBeMember<MutationObserver>& lhs, const RefPtrWillBeMember<MutationObserver>& rhs)
{
return lhs->m_priority < rhs->m_priority;
}
};
-PassRefPtr<MutationObserver> MutationObserver::create(PassOwnPtr<MutationCallback> callback)
+PassRefPtrWillBeRawPtr<MutationObserver> MutationObserver::create(PassOwnPtr<MutationCallback> callback)
{
ASSERT(isMainThread());
- return adoptRef(new MutationObserver(callback));
+ return adoptRefWillBeNoop(new MutationObserver(callback));
}
MutationObserver::MutationObserver(PassOwnPtr<MutationCallback> callback)
@@ -68,7 +70,11 @@ MutationObserver::MutationObserver(PassOwnPtr<MutationCallback> callback)
MutationObserver::~MutationObserver()
{
+#if !ENABLE(OILPAN)
ASSERT(m_registrations.isEmpty());
+#endif
+ if (!m_records.isEmpty())
+ InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionContext(), this);
}
void MutationObserver::observe(Node* node, const Dictionary& optionsDictionary, ExceptionState& exceptionState)
@@ -115,40 +121,43 @@ void MutationObserver::observe(Node* node, const Dictionary& optionsDictionary,
if (!(options & Attributes)) {
if (options & AttributeOldValue) {
- exceptionState.throwDOMException(TypeError, "The options object may only set 'attributeOldValue' to true when 'attributes' is true or not present.");
+ exceptionState.throwTypeError("The options object may only set 'attributeOldValue' to true when 'attributes' is true or not present.");
return;
}
if (options & AttributeFilter) {
- exceptionState.throwDOMException(TypeError, "The options object may only set 'attributeFilter' when 'attributes' is true or not present.");
+ exceptionState.throwTypeError("The options object may only set 'attributeFilter' when 'attributes' is true or not present.");
return;
}
}
if (!((options & CharacterData) || !(options & CharacterDataOldValue))) {
- exceptionState.throwDOMException(TypeError, "The options object may only set 'characterDataOldValue' to true when 'characterData' is true or not present.");
+ exceptionState.throwTypeError("The options object may only set 'characterDataOldValue' to true when 'characterData' is true or not present.");
return;
}
if (!(options & (Attributes | CharacterData | ChildList))) {
- exceptionState.throwDOMException(TypeError, "The options object must set at least one of 'attributes', 'characterData', or 'childList' to true.");
+ exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true.");
return;
}
- node->registerMutationObserver(this, options, attributeFilter);
+ node->registerMutationObserver(*this, options, attributeFilter);
}
-Vector<RefPtr<MutationRecord> > MutationObserver::takeRecords()
+MutationRecordVector MutationObserver::takeRecords()
{
- Vector<RefPtr<MutationRecord> > records;
+ MutationRecordVector records;
records.swap(m_records);
+ InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionContext(), this);
return records;
}
void MutationObserver::disconnect()
{
m_records.clear();
- HashSet<MutationObserverRegistration*> registrations(m_registrations);
- for (HashSet<MutationObserverRegistration*>::iterator iter = registrations.begin(); iter != registrations.end(); ++iter)
+ InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionContext(), this);
+ MutationObserverRegistrationSet registrations(m_registrations);
+ for (MutationObserverRegistrationSet::iterator iter = registrations.begin(); iter != registrations.end(); ++iter)
(*iter)->unregister();
+ ASSERT(m_registrations.isEmpty());
}
void MutationObserver::observationStarted(MutationObserverRegistration* registration)
@@ -163,37 +172,54 @@ void MutationObserver::observationEnded(MutationObserverRegistration* registrati
m_registrations.remove(registration);
}
-typedef HashSet<RefPtr<MutationObserver> > MutationObserverSet;
-
static MutationObserverSet& activeMutationObservers()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, activeObservers, (new MutationObserverSet()));
+ return *activeObservers;
+#else
DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ());
return activeObservers;
+#endif
}
static MutationObserverSet& suspendedMutationObservers()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, suspendedObservers, (new MutationObserverSet()));
+ return *suspendedObservers;
+#else
DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ());
return suspendedObservers;
+#endif
}
-void MutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation)
+static void activateObserver(PassRefPtrWillBeRawPtr<MutationObserver> observer)
+{
+ if (activeMutationObservers().isEmpty())
+ Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutations));
+
+ activeMutationObservers().add(observer);
+}
+
+void MutationObserver::enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationRecord> mutation)
{
ASSERT(isMainThread());
m_records.append(mutation);
- activeMutationObservers().add(this);
+ activateObserver(this);
+ InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionContext(), this);
}
void MutationObserver::setHasTransientRegistration()
{
ASSERT(isMainThread());
- activeMutationObservers().add(this);
+ activateObserver(this);
}
HashSet<Node*> MutationObserver::getObservedNodes() const
{
HashSet<Node*> observedNodes;
- for (HashSet<MutationObserverRegistration*>::const_iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter)
+ for (MutationObserverRegistrationSet::const_iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter)
(*iter)->addRegistrationNodesToSet(observedNodes);
return observedNodes;
}
@@ -209,8 +235,8 @@ void MutationObserver::deliver()
// Calling clearTransientRegistrations() can modify m_registrations, so it's necessary
// to make a copy of the transient registrations before operating on them.
- Vector<MutationObserverRegistration*, 1> transientRegistrations;
- for (HashSet<MutationObserverRegistration*>::iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter) {
+ WillBeHeapVector<RawPtrWillBeMember<MutationObserverRegistration>, 1> transientRegistrations;
+ for (MutationObserverRegistrationSet::iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter) {
if ((*iter)->hasTransientRegistrations())
transientRegistrations.append(*iter);
}
@@ -220,46 +246,49 @@ void MutationObserver::deliver()
if (m_records.isEmpty())
return;
- Vector<RefPtr<MutationRecord> > records;
+ MutationRecordVector records;
records.swap(m_records);
+ InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionContext(), this);
m_callback->call(records, this);
+ InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionContext());
}
-void MutationObserver::deliverAllMutations()
+void MutationObserver::resumeSuspendedObservers()
{
ASSERT(isMainThread());
- static bool deliveryInProgress = false;
- if (deliveryInProgress)
+ if (suspendedMutationObservers().isEmpty())
return;
- deliveryInProgress = true;
-
- if (!suspendedMutationObservers().isEmpty()) {
- Vector<RefPtr<MutationObserver> > suspended;
- copyToVector(suspendedMutationObservers(), suspended);
- for (size_t i = 0; i < suspended.size(); ++i) {
- if (!suspended[i]->canDeliver())
- continue;
+ MutationObserverVector suspended;
+ copyToVector(suspendedMutationObservers(), suspended);
+ for (size_t i = 0; i < suspended.size(); ++i) {
+ if (suspended[i]->canDeliver()) {
suspendedMutationObservers().remove(suspended[i]);
- activeMutationObservers().add(suspended[i]);
+ activateObserver(suspended[i]);
}
}
+}
- while (!activeMutationObservers().isEmpty()) {
- Vector<RefPtr<MutationObserver> > observers;
- copyToVector(activeMutationObservers(), observers);
- activeMutationObservers().clear();
- std::sort(observers.begin(), observers.end(), ObserverLessThan());
- for (size_t i = 0; i < observers.size(); ++i) {
- if (observers[i]->canDeliver())
- observers[i]->deliver();
- else
- suspendedMutationObservers().add(observers[i]);
- }
+void MutationObserver::deliverMutations()
+{
+ ASSERT(isMainThread());
+ MutationObserverVector observers;
+ copyToVector(activeMutationObservers(), observers);
+ activeMutationObservers().clear();
+ std::sort(observers.begin(), observers.end(), ObserverLessThan());
+ for (size_t i = 0; i < observers.size(); ++i) {
+ if (observers[i]->canDeliver())
+ observers[i]->deliver();
+ else
+ suspendedMutationObservers().add(observers[i]);
}
+}
- deliveryInProgress = false;
+void MutationObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_records);
+ visitor->trace(m_registrations);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.h b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.h
index 062d01edfe1..5036587d3bd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.h
@@ -32,7 +32,9 @@
#define MutationObserver_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -43,6 +45,7 @@ namespace WebCore {
class Dictionary;
class ExceptionState;
class MutationCallback;
+class MutationObserver;
class MutationObserverRegistration;
class MutationRecord;
class Node;
@@ -50,7 +53,12 @@ class Node;
typedef unsigned char MutationObserverOptions;
typedef unsigned char MutationRecordDeliveryOptions;
-class MutationObserver : public RefCounted<MutationObserver>, public ScriptWrappable {
+typedef WillBeHeapHashSet<RefPtrWillBeMember<MutationObserver> > MutationObserverSet;
+typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> > MutationObserverRegistrationSet;
+typedef WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > MutationObserverVector;
+typedef WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > MutationRecordVector;
+
+class MutationObserver FINAL : public RefCountedWillBeGarbageCollectedFinalized<MutationObserver>, public ScriptWrappable {
public:
enum MutationType {
ChildList = 1 << 0,
@@ -70,22 +78,25 @@ public:
CharacterDataOldValue = 1 << 6,
};
- static PassRefPtr<MutationObserver> create(PassOwnPtr<MutationCallback>);
- static void deliverAllMutations();
+ static PassRefPtrWillBeRawPtr<MutationObserver> create(PassOwnPtr<MutationCallback>);
+ static void resumeSuspendedObservers();
+ static void deliverMutations();
~MutationObserver();
void observe(Node*, const Dictionary&, ExceptionState&);
- Vector<RefPtr<MutationRecord> > takeRecords();
+ WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > takeRecords();
void disconnect();
void observationStarted(MutationObserverRegistration*);
void observationEnded(MutationObserverRegistration*);
- void enqueueMutationRecord(PassRefPtr<MutationRecord>);
+ void enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationRecord>);
void setHasTransientRegistration();
bool canDeliver();
HashSet<Node*> getObservedNodes() const;
+ void trace(Visitor*);
+
private:
struct ObserverLessThan;
@@ -93,8 +104,8 @@ private:
void deliver();
OwnPtr<MutationCallback> m_callback;
- Vector<RefPtr<MutationRecord> > m_records;
- HashSet<MutationObserverRegistration*> m_registrations;
+ MutationRecordVector m_records;
+ MutationObserverRegistrationSet m_registrations;
unsigned m_priority;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl
index d16bb4fd3e2..2c6d142f8f8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserver.idl
@@ -30,6 +30,8 @@
[
CustomConstructor(MutationCallback callback),
+ Custom=VisitDOMWrapper,
+ WillBeGarbageCollected,
] interface MutationObserver {
[RaisesException] void observe(Node target, Dictionary options);
sequence<MutationRecord> takeRecords();
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp b/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp
index e9e839ba0be..3d48535d5ff 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.cpp
@@ -36,18 +36,18 @@
namespace WebCore {
-PassOwnPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node& target, MutationObserver::MutationType type, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName)
+PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> MutationObserverInterestGroup::createIfNeeded(Node& target, MutationObserver::MutationType type, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName)
{
ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
- HashMap<MutationObserver*, MutationRecordDeliveryOptions> observers;
+ WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions> observers;
target.getRegisteredMutationObserversOfType(observers, type, attributeName);
if (observers.isEmpty())
return nullptr;
- return adoptPtr(new MutationObserverInterestGroup(observers, oldValueFlag));
+ return adoptPtrWillBeNoop(new MutationObserverInterestGroup(observers, oldValueFlag));
}
-MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag)
+MutationObserverInterestGroup::MutationObserverInterestGroup(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag)
: m_oldValueFlag(oldValueFlag)
{
ASSERT(!observers.isEmpty());
@@ -56,18 +56,18 @@ MutationObserverInterestGroup::MutationObserverInterestGroup(HashMap<MutationObs
bool MutationObserverInterestGroup::isOldValueRequested()
{
- for (HashMap<MutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
+ for (WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
if (hasOldValue(iter->value))
return true;
}
return false;
}
-void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRecord> prpMutation)
+void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationRecord> prpMutation)
{
- RefPtr<MutationRecord> mutation = prpMutation;
- RefPtr<MutationRecord> mutationWithNullOldValue;
- for (HashMap<MutationObserver*, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
+ RefPtrWillBeRawPtr<MutationRecord> mutation = prpMutation;
+ RefPtrWillBeRawPtr<MutationRecord> mutationWithNullOldValue = nullptr;
+ for (WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>::iterator iter = m_observers.begin(); iter != m_observers.end(); ++iter) {
MutationObserver* observer = iter->key;
if (hasOldValue(iter->value)) {
observer->enqueueMutationRecord(mutation);
@@ -83,4 +83,9 @@ void MutationObserverInterestGroup::enqueueMutationRecord(PassRefPtr<MutationRec
}
}
+void MutationObserverInterestGroup::trace(Visitor* visitor)
+{
+ visitor->trace(m_observers);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h b/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h
index b149afcf935..9df7498930b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserverInterestGroup.h
@@ -35,14 +35,15 @@
#include "core/dom/MutationObserver.h"
#include "core/dom/Node.h"
#include "core/dom/QualifiedName.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
-class MutationObserverInterestGroup {
+class MutationObserverInterestGroup FINAL : public NoBaseWillBeGarbageCollectedFinalized<MutationObserverInterestGroup> {
public:
- static PassOwnPtr<MutationObserverInterestGroup> createForChildListMutation(Node& target)
+ static PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> createForChildListMutation(Node& target)
{
if (!target.document().hasMutationObserversOfType(MutationObserver::ChildList))
return nullptr;
@@ -51,7 +52,7 @@ public:
return createIfNeeded(target, MutationObserver::ChildList, oldValueFlag);
}
- static PassOwnPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node& target)
+ static PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> createForCharacterDataMutation(Node& target)
{
if (!target.document().hasMutationObserversOfType(MutationObserver::CharacterData))
return nullptr;
@@ -59,7 +60,7 @@ public:
return createIfNeeded(target, MutationObserver::CharacterData, MutationObserver::CharacterDataOldValue);
}
- static PassOwnPtr<MutationObserverInterestGroup> createForAttributesMutation(Node& target, const QualifiedName& attributeName)
+ static PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> createForAttributesMutation(Node& target, const QualifiedName& attributeName)
{
if (!target.document().hasMutationObserversOfType(MutationObserver::Attributes))
return nullptr;
@@ -68,15 +69,17 @@ public:
}
bool isOldValueRequested();
- void enqueueMutationRecord(PassRefPtr<MutationRecord>);
+ void enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationRecord>);
+
+ void trace(Visitor*);
private:
- static PassOwnPtr<MutationObserverInterestGroup> createIfNeeded(Node& target, MutationObserver::MutationType, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName = 0);
- MutationObserverInterestGroup(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
+ static PassOwnPtrWillBeRawPtr<MutationObserverInterestGroup> createIfNeeded(Node& target, MutationObserver::MutationType, MutationRecordDeliveryOptions oldValueFlag, const QualifiedName* attributeName = 0);
+ MutationObserverInterestGroup(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, MutationRecordDeliveryOptions oldValueFlag);
bool hasOldValue(MutationRecordDeliveryOptions options) { return options & m_oldValueFlag; }
- HashMap<MutationObserver*, MutationRecordDeliveryOptions> m_observers;
+ WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions> m_observers;
MutationRecordDeliveryOptions m_oldValueFlag;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp b/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp
index 1ece4d1cbdc..5421360f707 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.cpp
@@ -37,12 +37,12 @@
namespace WebCore {
-PassOwnPtr<MutationObserverRegistration> MutationObserverRegistration::create(PassRefPtr<MutationObserver> observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+PassOwnPtrWillBeRawPtr<MutationObserverRegistration> MutationObserverRegistration::create(MutationObserver& observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
{
- return adoptPtr(new MutationObserverRegistration(observer, registrationNode, options, attributeFilter));
+ return adoptPtrWillBeNoop(new MutationObserverRegistration(observer, registrationNode, options, attributeFilter));
}
-MutationObserverRegistration::MutationObserverRegistration(PassRefPtr<MutationObserver> observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+MutationObserverRegistration::MutationObserverRegistration(MutationObserver& observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
: m_observer(observer)
, m_registrationNode(registrationNode)
, m_options(options)
@@ -53,8 +53,16 @@ MutationObserverRegistration::MutationObserverRegistration(PassRefPtr<MutationOb
MutationObserverRegistration::~MutationObserverRegistration()
{
+#if !ENABLE(OILPAN)
+ dispose();
+#endif
+}
+
+void MutationObserverRegistration::dispose()
+{
clearTransientRegistrations();
m_observer->observationEnded(this);
+ m_observer.clear();
}
void MutationObserverRegistration::resetObservation(MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
@@ -64,21 +72,22 @@ void MutationObserverRegistration::resetObservation(MutationObserverOptions opti
m_attributeFilter = attributeFilter;
}
-void MutationObserverRegistration::observedSubtreeNodeWillDetach(Node* node)
+void MutationObserverRegistration::observedSubtreeNodeWillDetach(Node& node)
{
if (!isSubtree())
return;
- node->registerTransientMutationObserver(this);
+ node.registerTransientMutationObserver(this);
m_observer->setHasTransientRegistration();
if (!m_transientRegistrationNodes) {
- m_transientRegistrationNodes = adoptPtr(new NodeHashSet);
+ m_transientRegistrationNodes = adoptPtrWillBeNoop(new NodeHashSet);
+ ASSERT(m_registrationNode);
ASSERT(!m_registrationNodeKeepAlive);
- m_registrationNodeKeepAlive = m_registrationNode; // Balanced in clearTransientRegistrations.
+ m_registrationNodeKeepAlive = PassRefPtrWillBeRawPtr<Node>(m_registrationNode.get()); // Balanced in clearTransientRegistrations.
}
- m_transientRegistrationNodes->add(node);
+ m_transientRegistrationNodes->add(&node);
}
void MutationObserverRegistration::clearTransientRegistrations()
@@ -94,22 +103,23 @@ void MutationObserverRegistration::clearTransientRegistrations()
m_transientRegistrationNodes.clear();
ASSERT(m_registrationNodeKeepAlive);
- m_registrationNodeKeepAlive = 0; // Balanced in observeSubtreeNodeWillDetach.
+ m_registrationNodeKeepAlive = nullptr; // Balanced in observeSubtreeNodeWillDetach.
}
void MutationObserverRegistration::unregister()
{
+ ASSERT(m_registrationNode);
m_registrationNode->unregisterMutationObserver(this);
// The above line will cause this object to be deleted, so don't do any more in this function.
}
-bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, MutationObserver::MutationType type, const QualifiedName* attributeName) const
+bool MutationObserverRegistration::shouldReceiveMutationFrom(Node& node, MutationObserver::MutationType type, const QualifiedName* attributeName) const
{
ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
if (!(m_options & type))
return false;
- if (m_registrationNode != node && !isSubtree())
+ if (m_registrationNode != &node && !isSubtree())
return false;
if (type != MutationObserver::Attributes || !(m_options & MutationObserver::AttributeFilter))
@@ -123,11 +133,22 @@ bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, Mutatio
void MutationObserverRegistration::addRegistrationNodesToSet(HashSet<Node*>& nodes) const
{
- nodes.add(m_registrationNode);
+ ASSERT(m_registrationNode);
+ nodes.add(m_registrationNode.get());
if (!m_transientRegistrationNodes)
return;
for (NodeHashSet::const_iterator iter = m_transientRegistrationNodes->begin(); iter != m_transientRegistrationNodes->end(); ++iter)
nodes.add(iter->get());
}
+void MutationObserverRegistration::trace(Visitor* visitor)
+{
+ visitor->trace(m_observer);
+ visitor->trace(m_registrationNode);
+ visitor->trace(m_registrationNodeKeepAlive);
+#if ENABLE(OILPAN)
+ visitor->trace(m_transientRegistrationNodes);
+#endif
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h b/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h
index 7c0fb527839..386a65aa230 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationObserverRegistration.h
@@ -32,6 +32,7 @@
#define MutationObserverRegistration_h
#include "core/dom/MutationObserver.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/AtomicStringHash.h"
@@ -40,34 +41,38 @@ namespace WebCore {
class QualifiedName;
-class MutationObserverRegistration {
+class MutationObserverRegistration FINAL : public NoBaseWillBeGarbageCollectedFinalized<MutationObserverRegistration> {
public:
- static PassOwnPtr<MutationObserverRegistration> create(PassRefPtr<MutationObserver>, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+ static PassOwnPtrWillBeRawPtr<MutationObserverRegistration> create(MutationObserver&, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
~MutationObserverRegistration();
void resetObservation(MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
- void observedSubtreeNodeWillDetach(Node*);
+ void observedSubtreeNodeWillDetach(Node&);
void clearTransientRegistrations();
bool hasTransientRegistrations() const { return m_transientRegistrationNodes && !m_transientRegistrationNodes->isEmpty(); }
void unregister();
- bool shouldReceiveMutationFrom(Node*, MutationObserver::MutationType, const QualifiedName* attributeName) const;
+ bool shouldReceiveMutationFrom(Node&, MutationObserver::MutationType, const QualifiedName* attributeName) const;
bool isSubtree() const { return m_options & MutationObserver::Subtree; }
- MutationObserver* observer() const { return m_observer.get(); }
+ MutationObserver& observer() const { return *m_observer; }
MutationRecordDeliveryOptions deliveryOptions() const { return m_options & (MutationObserver::AttributeOldValue | MutationObserver::CharacterDataOldValue); }
MutationObserverOptions mutationTypes() const { return m_options & MutationObserver::AllMutationTypes; }
void addRegistrationNodesToSet(HashSet<Node*>&) const;
+ void trace(Visitor*);
+
+ void dispose();
+
private:
- MutationObserverRegistration(PassRefPtr<MutationObserver>, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+ MutationObserverRegistration(MutationObserver&, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
- RefPtr<MutationObserver> m_observer;
- Node* m_registrationNode;
- RefPtr<Node> m_registrationNodeKeepAlive;
- typedef HashSet<RefPtr<Node> > NodeHashSet;
- OwnPtr<NodeHashSet> m_transientRegistrationNodes;
+ RefPtrWillBeMember<MutationObserver> m_observer;
+ RawPtrWillBeWeakMember<Node> m_registrationNode;
+ RefPtrWillBeMember<Node> m_registrationNodeKeepAlive;
+ typedef WillBeHeapHashSet<RefPtrWillBeMember<Node> > NodeHashSet;
+ OwnPtrWillBeMember<NodeHashSet> m_transientRegistrationNodes;
MutationObserverOptions m_options;
HashSet<AtomicString> m_attributeFilter;
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp
index 77c6f393073..4d81e614d67 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.cpp
@@ -44,7 +44,7 @@ namespace {
class ChildListRecord : public MutationRecord {
public:
- ChildListRecord(PassRefPtr<Node> target, PassRefPtr<NodeList> added, PassRefPtr<NodeList> removed, PassRefPtr<Node> previousSibling, PassRefPtr<Node> nextSibling)
+ ChildListRecord(PassRefPtrWillBeRawPtr<Node> target, PassRefPtrWillBeRawPtr<StaticNodeList> added, PassRefPtrWillBeRawPtr<StaticNodeList> removed, PassRefPtrWillBeRawPtr<Node> previousSibling, PassRefPtrWillBeRawPtr<Node> nextSibling)
: m_target(target)
, m_addedNodes(added)
, m_removedNodes(removed)
@@ -53,51 +53,69 @@ public:
{
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_target);
+ visitor->trace(m_addedNodes);
+ visitor->trace(m_removedNodes);
+ visitor->trace(m_previousSibling);
+ visitor->trace(m_nextSibling);
+ MutationRecord::trace(visitor);
+ }
+
private:
virtual const AtomicString& type() OVERRIDE;
virtual Node* target() OVERRIDE { return m_target.get(); }
- virtual NodeList* addedNodes() OVERRIDE { return m_addedNodes.get(); }
- virtual NodeList* removedNodes() OVERRIDE { return m_removedNodes.get(); }
+ virtual StaticNodeList* addedNodes() OVERRIDE { return m_addedNodes.get(); }
+ virtual StaticNodeList* removedNodes() OVERRIDE { return m_removedNodes.get(); }
virtual Node* previousSibling() OVERRIDE { return m_previousSibling.get(); }
virtual Node* nextSibling() OVERRIDE { return m_nextSibling.get(); }
- RefPtr<Node> m_target;
- RefPtr<NodeList> m_addedNodes;
- RefPtr<NodeList> m_removedNodes;
- RefPtr<Node> m_previousSibling;
- RefPtr<Node> m_nextSibling;
+ RefPtrWillBeMember<Node> m_target;
+ RefPtrWillBeMember<StaticNodeList> m_addedNodes;
+ RefPtrWillBeMember<StaticNodeList> m_removedNodes;
+ RefPtrWillBeMember<Node> m_previousSibling;
+ RefPtrWillBeMember<Node> m_nextSibling;
};
class RecordWithEmptyNodeLists : public MutationRecord {
public:
- RecordWithEmptyNodeLists(PassRefPtr<Node> target, const String& oldValue)
+ RecordWithEmptyNodeLists(PassRefPtrWillBeRawPtr<Node> target, const String& oldValue)
: m_target(target)
, m_oldValue(oldValue)
{
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_target);
+ visitor->trace(m_addedNodes);
+ visitor->trace(m_removedNodes);
+ MutationRecord::trace(visitor);
+ }
+
private:
virtual Node* target() OVERRIDE { return m_target.get(); }
virtual String oldValue() OVERRIDE { return m_oldValue; }
- virtual NodeList* addedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_addedNodes); }
- virtual NodeList* removedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_removedNodes); }
+ virtual StaticNodeList* addedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_addedNodes); }
+ virtual StaticNodeList* removedNodes() OVERRIDE { return lazilyInitializeEmptyNodeList(m_removedNodes); }
- static NodeList* lazilyInitializeEmptyNodeList(RefPtr<NodeList>& nodeList)
+ static StaticNodeList* lazilyInitializeEmptyNodeList(RefPtrWillBeMember<StaticNodeList>& nodeList)
{
if (!nodeList)
nodeList = StaticNodeList::createEmpty();
return nodeList.get();
}
- RefPtr<Node> m_target;
+ RefPtrWillBeMember<Node> m_target;
String m_oldValue;
- RefPtr<NodeList> m_addedNodes;
- RefPtr<NodeList> m_removedNodes;
+ RefPtrWillBeMember<StaticNodeList> m_addedNodes;
+ RefPtrWillBeMember<StaticNodeList> m_removedNodes;
};
class AttributesRecord : public RecordWithEmptyNodeLists {
public:
- AttributesRecord(PassRefPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
+ AttributesRecord(PassRefPtrWillBeRawPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
: RecordWithEmptyNodeLists(target, oldValue)
, m_attributeName(name.localName())
, m_attributeNamespace(name.namespaceURI())
@@ -115,7 +133,7 @@ private:
class CharacterDataRecord : public RecordWithEmptyNodeLists {
public:
- CharacterDataRecord(PassRefPtr<Node> target, const String& oldValue)
+ CharacterDataRecord(PassRefPtrWillBeRawPtr<Node> target, const String& oldValue)
: RecordWithEmptyNodeLists(target, oldValue)
{
}
@@ -126,16 +144,22 @@ private:
class MutationRecordWithNullOldValue : public MutationRecord {
public:
- MutationRecordWithNullOldValue(PassRefPtr<MutationRecord> record)
+ MutationRecordWithNullOldValue(PassRefPtrWillBeRawPtr<MutationRecord> record)
: m_record(record)
{
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_record);
+ MutationRecord::trace(visitor);
+ }
+
private:
virtual const AtomicString& type() OVERRIDE { return m_record->type(); }
virtual Node* target() OVERRIDE { return m_record->target(); }
- virtual NodeList* addedNodes() OVERRIDE { return m_record->addedNodes(); }
- virtual NodeList* removedNodes() OVERRIDE { return m_record->removedNodes(); }
+ virtual StaticNodeList* addedNodes() OVERRIDE { return m_record->addedNodes(); }
+ virtual StaticNodeList* removedNodes() OVERRIDE { return m_record->removedNodes(); }
virtual Node* previousSibling() OVERRIDE { return m_record->previousSibling(); }
virtual Node* nextSibling() OVERRIDE { return m_record->nextSibling(); }
virtual const AtomicString& attributeName() OVERRIDE { return m_record->attributeName(); }
@@ -143,7 +167,7 @@ private:
virtual String oldValue() OVERRIDE { return String(); }
- RefPtr<MutationRecord> m_record;
+ RefPtrWillBeMember<MutationRecord> m_record;
};
const AtomicString& ChildListRecord::type()
@@ -166,24 +190,24 @@ const AtomicString& CharacterDataRecord::type()
} // namespace
-PassRefPtr<MutationRecord> MutationRecord::createChildList(PassRefPtr<Node> target, PassRefPtr<NodeList> added, PassRefPtr<NodeList> removed, PassRefPtr<Node> previousSibling, PassRefPtr<Node> nextSibling)
+PassRefPtrWillBeRawPtr<MutationRecord> MutationRecord::createChildList(PassRefPtrWillBeRawPtr<Node> target, PassRefPtrWillBeRawPtr<StaticNodeList> added, PassRefPtrWillBeRawPtr<StaticNodeList> removed, PassRefPtrWillBeRawPtr<Node> previousSibling, PassRefPtrWillBeRawPtr<Node> nextSibling)
{
- return adoptRef(new ChildListRecord(target, added, removed, previousSibling, nextSibling));
+ return adoptRefWillBeNoop(new ChildListRecord(target, added, removed, previousSibling, nextSibling));
}
-PassRefPtr<MutationRecord> MutationRecord::createAttributes(PassRefPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
+PassRefPtrWillBeRawPtr<MutationRecord> MutationRecord::createAttributes(PassRefPtrWillBeRawPtr<Node> target, const QualifiedName& name, const AtomicString& oldValue)
{
- return adoptRef(new AttributesRecord(target, name, oldValue));
+ return adoptRefWillBeNoop(new AttributesRecord(target, name, oldValue));
}
-PassRefPtr<MutationRecord> MutationRecord::createCharacterData(PassRefPtr<Node> target, const String& oldValue)
+PassRefPtrWillBeRawPtr<MutationRecord> MutationRecord::createCharacterData(PassRefPtrWillBeRawPtr<Node> target, const String& oldValue)
{
- return adoptRef(new CharacterDataRecord(target, oldValue));
+ return adoptRefWillBeNoop(new CharacterDataRecord(target, oldValue));
}
-PassRefPtr<MutationRecord> MutationRecord::createWithNullOldValue(PassRefPtr<MutationRecord> record)
+PassRefPtrWillBeRawPtr<MutationRecord> MutationRecord::createWithNullOldValue(PassRefPtrWillBeRawPtr<MutationRecord> record)
{
- return adoptRef(new MutationRecordWithNullOldValue(record));
+ return adoptRefWillBeNoop(new MutationRecordWithNullOldValue(record));
}
MutationRecord::~MutationRecord()
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.h b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.h
index 2c9812e0e05..de7cb5b3fcc 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.h
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.h
@@ -32,6 +32,7 @@
#define MutationRecord_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -39,15 +40,15 @@
namespace WebCore {
class Node;
-class NodeList;
class QualifiedName;
+class StaticNodeList;
-class MutationRecord : public RefCounted<MutationRecord>, public ScriptWrappable {
+class MutationRecord : public RefCountedWillBeGarbageCollectedFinalized<MutationRecord>, public ScriptWrappable {
public:
- static PassRefPtr<MutationRecord> createChildList(PassRefPtr<Node> target, PassRefPtr<NodeList> added, PassRefPtr<NodeList> removed, PassRefPtr<Node> previousSibling, PassRefPtr<Node> nextSibling);
- static PassRefPtr<MutationRecord> createAttributes(PassRefPtr<Node> target, const QualifiedName&, const AtomicString& oldValue);
- static PassRefPtr<MutationRecord> createCharacterData(PassRefPtr<Node> target, const String& oldValue);
- static PassRefPtr<MutationRecord> createWithNullOldValue(PassRefPtr<MutationRecord>);
+ static PassRefPtrWillBeRawPtr<MutationRecord> createChildList(PassRefPtrWillBeRawPtr<Node> target, PassRefPtrWillBeRawPtr<StaticNodeList> added, PassRefPtrWillBeRawPtr<StaticNodeList> removed, PassRefPtrWillBeRawPtr<Node> previousSibling, PassRefPtrWillBeRawPtr<Node> nextSibling);
+ static PassRefPtrWillBeRawPtr<MutationRecord> createAttributes(PassRefPtrWillBeRawPtr<Node> target, const QualifiedName&, const AtomicString& oldValue);
+ static PassRefPtrWillBeRawPtr<MutationRecord> createCharacterData(PassRefPtrWillBeRawPtr<Node> target, const String& oldValue);
+ static PassRefPtrWillBeRawPtr<MutationRecord> createWithNullOldValue(PassRefPtrWillBeRawPtr<MutationRecord>);
MutationRecord()
{
@@ -59,8 +60,8 @@ public:
virtual const AtomicString& type() = 0;
virtual Node* target() = 0;
- virtual NodeList* addedNodes() = 0;
- virtual NodeList* removedNodes() = 0;
+ virtual StaticNodeList* addedNodes() = 0;
+ virtual StaticNodeList* removedNodes() = 0;
virtual Node* previousSibling() { return 0; }
virtual Node* nextSibling() { return 0; }
@@ -68,6 +69,9 @@ public:
virtual const AtomicString& attributeNamespace() { return nullAtom; }
virtual String oldValue() { return String(); }
+
+ virtual void trace(Visitor*) { }
+
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl
index c3ef6164eb8..daecf1d0c37 100644
--- a/chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/MutationRecord.idl
@@ -29,6 +29,7 @@
*/
[
+ WillBeGarbageCollected,
] interface MutationRecord {
readonly attribute DOMString type;
readonly attribute Node target;
diff --git a/chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp
index 69634c9f48a..cd844cac8fe 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NameNodeList.cpp
@@ -31,7 +31,7 @@ namespace WebCore {
using namespace HTMLNames;
-NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name)
+NameNodeList::NameNodeList(ContainerNode& rootNode, const AtomicString& name)
: LiveNodeList(rootNode, NameNodeListType, InvalidateOnNameAttrChange)
, m_name(name)
{
@@ -39,12 +39,14 @@ NameNodeList::NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name)
NameNodeList::~NameNodeList()
{
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, NameNodeListType, m_name);
+#if !ENABLE(OILPAN)
+ ownerNode().nodeLists()->removeCache(this, NameNodeListType, m_name);
+#endif
}
-bool NameNodeList::nodeMatches(Element* testNode) const
+bool NameNodeList::elementMatches(const Element& element) const
{
- return testNode->getNameAttribute() == m_name;
+ return element.getNameAttribute() == m_name;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NameNodeList.h b/chromium/third_party/WebKit/Source/core/dom/NameNodeList.h
index 5a595d8d9a3..55f313c5904 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NameNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NameNodeList.h
@@ -26,25 +26,24 @@
#include "core/dom/LiveNodeList.h"
#include "wtf/Forward.h"
-#include "wtf/text/AtomicString.h"
namespace WebCore {
// NodeList which lists all Nodes in a Element with a given "name" attribute
class NameNodeList FINAL : public LiveNodeList {
public:
- static PassRefPtr<NameNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& name)
+ static PassRefPtrWillBeRawPtr<NameNodeList> create(ContainerNode& rootNode, CollectionType type, const AtomicString& name)
{
ASSERT_UNUSED(type, type == NameNodeListType);
- return adoptRef(new NameNodeList(rootNode, name));
+ return adoptRefWillBeNoop(new NameNodeList(rootNode, name));
}
virtual ~NameNodeList();
private:
- NameNodeList(PassRefPtr<Node> rootNode, const AtomicString& name);
+ NameNodeList(ContainerNode& rootNode, const AtomicString& name);
- virtual bool nodeMatches(Element*) const OVERRIDE;
+ virtual bool elementMatches(const Element&) const OVERRIDE;
AtomicString m_name;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedFlow.cpp b/chromium/third_party/WebKit/Source/core/dom/NamedFlow.cpp
deleted file mode 100644
index 04f1c08d1f7..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NamedFlow.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/NamedFlow.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/dom/NamedFlowCollection.h"
-#include "core/dom/StaticNodeList.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/events/UIEvent.h"
-#include "core/rendering/RenderNamedFlowFragment.h"
-#include "core/rendering/RenderNamedFlowThread.h"
-
-namespace WebCore {
-
-NamedFlow::NamedFlow(PassRefPtr<NamedFlowCollection> manager, const AtomicString& flowThreadName)
- : m_flowThreadName(flowThreadName)
- , m_flowManager(manager)
- , m_parentFlowThread(0)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
- ScriptWrappable::init(this);
-}
-
-NamedFlow::~NamedFlow()
-{
- // The named flow is not "strong" referenced from anywhere at this time so it shouldn't be reused if the named flow is recreated.
- m_flowManager->discardNamedFlow(this);
-}
-
-PassRefPtr<NamedFlow> NamedFlow::create(PassRefPtr<NamedFlowCollection> manager, const AtomicString& flowThreadName)
-{
- return adoptRef(new NamedFlow(manager, flowThreadName));
-}
-
-const AtomicString& NamedFlow::name() const
-{
- return m_flowThreadName;
-}
-
-bool NamedFlow::overset() const
-{
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- // The renderer may be destroyed or created after the style update.
- // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
- return m_parentFlowThread ? m_parentFlowThread->overset() : true;
-}
-
-static inline bool inFlowThread(RenderObject* renderer, RenderNamedFlowThread* flowThread)
-{
- if (!renderer)
- return false;
- RenderFlowThread* currentFlowThread = renderer->flowThreadContainingBlock();
- if (flowThread == currentFlowThread)
- return true;
- if (renderer->flowThreadState() != RenderObject::InsideInFlowThread)
- return false;
-
- // An in-flow flow thread can be nested inside an out-of-flow one, so we have to recur up to check.
- return inFlowThread(currentFlowThread->containingBlock(), flowThread);
-}
-
-int NamedFlow::firstEmptyRegionIndex() const
-{
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- if (!m_parentFlowThread)
- return -1;
-
- const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
- if (regionList.isEmpty())
- return -1;
-
- int countNonPseudoRegions = -1;
- RenderRegionList::const_iterator iter = regionList.begin();
- for (int index = 0; iter != regionList.end(); ++index, ++iter) {
- const RenderNamedFlowFragment* renderRegion = toRenderNamedFlowFragment(*iter);
- // FIXME: Pseudo-elements are not included in the list.
- // They will be included when we will properly support the Region interface
- // http://dev.w3.org/csswg/css-regions/#the-region-interface
- if (!renderRegion->isElementBasedRegion())
- continue;
- countNonPseudoRegions++;
- if (renderRegion->regionOversetState() == RegionEmpty)
- return countNonPseudoRegions;
- }
- return -1;
-}
-
-PassRefPtr<NodeList> NamedFlow::getRegionsByContent(Node* contentNode)
-{
- Vector<RefPtr<Node> > regionNodes;
-
- if (!contentNode)
- return StaticNodeList::adopt(regionNodes);
-
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- // The renderer may be destroyed or created after the style update.
- // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
- if (!m_parentFlowThread)
- return StaticNodeList::adopt(regionNodes);
-
- if (inFlowThread(contentNode->renderer(), m_parentFlowThread)) {
- const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
- for (RenderRegionList::const_iterator iter = regionList.begin(); iter != regionList.end(); ++iter) {
- const RenderNamedFlowFragment* renderRegion = toRenderNamedFlowFragment(*iter);
- // They will be included when we will properly support the Region interface
- // http://dev.w3.org/csswg/css-regions/#the-region-interface
- if (!renderRegion->isElementBasedRegion())
- continue;
- if (m_parentFlowThread->objectInFlowRegion(contentNode->renderer(), renderRegion))
- regionNodes.append(renderRegion->nodeForRegion());
- }
- }
-
- return StaticNodeList::adopt(regionNodes);
-}
-
-PassRefPtr<NodeList> NamedFlow::getRegions()
-{
- Vector<RefPtr<Node> > regionNodes;
-
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- // The renderer may be destroyed or created after the style update.
- // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
- if (!m_parentFlowThread)
- return StaticNodeList::adopt(regionNodes);
-
- const RenderRegionList& regionList = m_parentFlowThread->renderRegionList();
- for (RenderRegionList::const_iterator iter = regionList.begin(); iter != regionList.end(); ++iter) {
- const RenderNamedFlowFragment* renderRegion = toRenderNamedFlowFragment(*iter);
- // They will be included when we will properly support the Region interface
- // http://dev.w3.org/csswg/css-regions/#the-region-interface
- if (!renderRegion->isElementBasedRegion())
- continue;
- regionNodes.append(renderRegion->nodeForRegion());
- }
-
- return StaticNodeList::adopt(regionNodes);
-}
-
-PassRefPtr<NodeList> NamedFlow::getContent()
-{
- Vector<RefPtr<Node> > contentNodes;
-
- if (m_flowManager->document())
- m_flowManager->document()->updateLayoutIgnorePendingStylesheets();
-
- // The renderer may be destroyed or created after the style update.
- // Because this is called from JS, where the wrapper keeps a reference to the NamedFlow, no guard is necessary.
- if (!m_parentFlowThread)
- return StaticNodeList::adopt(contentNodes);
-
- const NamedFlowContentNodes& contentNodesList = m_parentFlowThread->contentNodes();
- for (NamedFlowContentNodes::const_iterator it = contentNodesList.begin(); it != contentNodesList.end(); ++it) {
- Node* node = *it;
- ASSERT(node->computedStyle()->flowThread() == m_parentFlowThread->flowThreadName());
- contentNodes.append(node);
- }
-
- return StaticNodeList::adopt(contentNodes);
-}
-
-void NamedFlow::setRenderer(RenderNamedFlowThread* parentFlowThread)
-{
- // The named flow can either go from a no_renderer->renderer or renderer->no_renderer state; anything else could indicate a bug.
- ASSERT((!m_parentFlowThread && parentFlowThread) || (m_parentFlowThread && !parentFlowThread));
-
- // If parentFlowThread is 0, the flow thread will move in the "NULL" state.
- m_parentFlowThread = parentFlowThread;
-}
-
-void NamedFlow::dispatchRegionLayoutUpdateEvent()
-{
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- // If the flow is in the "NULL" state the event should not be dispatched any more.
- if (flowState() == FlowStateNull)
- return;
-
- RefPtr<Event> event = UIEvent::create(EventTypeNames::webkitregionlayoutupdate, false, false, m_flowManager->document()->domWindow(), 0);
-
- dispatchEvent(event);
-}
-
-void NamedFlow::dispatchRegionOversetChangeEvent()
-{
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- // If the flow is in the "NULL" state the event should not be dispatched any more.
- if (flowState() == FlowStateNull)
- return;
-
- RefPtr<Event> event = UIEvent::create(EventTypeNames::webkitregionoversetchange, false, false, m_flowManager->document()->domWindow(), 0);
-
- dispatchEvent(event);
-}
-
-const AtomicString& NamedFlow::interfaceName() const
-{
- return EventTargetNames::NamedFlow;
-}
-
-ExecutionContext* NamedFlow::executionContext() const
-{
- return m_flowManager->document();
-}
-
-Node* NamedFlow::ownerNode() const
-{
- return m_flowManager->document();
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedFlow.h b/chromium/third_party/WebKit/Source/core/dom/NamedFlow.h
deleted file mode 100644
index 75f2bd5765a..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NamedFlow.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef NamedFlow_h
-#define NamedFlow_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/events/EventTarget.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-class Document;
-class NamedFlowCollection;
-class Node;
-class NodeList;
-class RenderNamedFlowThread;
-class ExecutionContext;
-
-class NamedFlow : public RefCounted<NamedFlow>, public ScriptWrappable, public EventTargetWithInlineData {
- REFCOUNTED_EVENT_TARGET(NamedFlow);
-public:
- static PassRefPtr<NamedFlow> create(PassRefPtr<NamedFlowCollection> manager, const AtomicString& flowThreadName);
-
- ~NamedFlow();
-
- const AtomicString& name() const;
- bool overset() const;
- int firstEmptyRegionIndex() const;
- PassRefPtr<NodeList> getRegionsByContent(Node*);
- PassRefPtr<NodeList> getRegions();
- PassRefPtr<NodeList> getContent();
-
- virtual const AtomicString& interfaceName() const OVERRIDE;
- virtual ExecutionContext* executionContext() const OVERRIDE;
-
- // This function is called from the JS binding code to determine if the NamedFlow object is reachable or not.
- // If the object has listeners, the object should only be discarded if the parent Document is not reachable.
- Node* ownerNode() const;
-
- void setRenderer(RenderNamedFlowThread* parentFlowThread);
-
- enum FlowState {
- FlowStateCreated,
- FlowStateNull
- };
-
- FlowState flowState() const { return m_parentFlowThread ? FlowStateCreated : FlowStateNull; }
-
- void dispatchRegionLayoutUpdateEvent();
- void dispatchRegionOversetChangeEvent();
-
-private:
- NamedFlow(PassRefPtr<NamedFlowCollection>, const AtomicString&);
-
- // The name of the flow thread as specified in CSS.
- AtomicString m_flowThreadName;
-
- RefPtr<NamedFlowCollection> m_flowManager;
- RenderNamedFlowThread* m_parentFlowThread;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.cpp
deleted file mode 100644
index 2b48c7be3d1..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/NamedFlowCollection.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/dom/DOMNamedFlowCollection.h"
-#include "core/dom/Document.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "wtf/text/StringHash.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-NamedFlowCollection::NamedFlowCollection(Document* document)
- : DocumentLifecycleObserver(document)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
-}
-
-Vector<RefPtr<NamedFlow> > NamedFlowCollection::namedFlows()
-{
- Vector<RefPtr<NamedFlow> > namedFlows;
-
- for (NamedFlowSet::iterator it = m_namedFlows.begin(); it != m_namedFlows.end(); ++it) {
- if ((*it)->flowState() == NamedFlow::FlowStateNull)
- continue;
-
- namedFlows.append(RefPtr<NamedFlow>(*it));
- }
-
- return namedFlows;
-}
-
-NamedFlow* NamedFlowCollection::flowByName(const String& flowName)
-{
- NamedFlowSet::iterator it = m_namedFlows.find<NamedFlowHashTranslator>(flowName);
- if (it == m_namedFlows.end() || (*it)->flowState() == NamedFlow::FlowStateNull)
- return 0;
-
- return *it;
-}
-
-PassRefPtr<NamedFlow> NamedFlowCollection::ensureFlowWithName(const String& flowName)
-{
- NamedFlowSet::iterator it = m_namedFlows.find<NamedFlowHashTranslator>(flowName);
- if (it != m_namedFlows.end()) {
- NamedFlow* namedFlow = *it;
- ASSERT(namedFlow->flowState() == NamedFlow::FlowStateNull);
-
- return namedFlow;
- }
-
- RefPtr<NamedFlow> newFlow = NamedFlow::create(this, flowName);
- m_namedFlows.add(newFlow.get());
-
- InspectorInstrumentation::didCreateNamedFlow(document(), newFlow.get());
-
- return newFlow.release();
-}
-
-void NamedFlowCollection::discardNamedFlow(NamedFlow* namedFlow)
-{
- // The document is not valid anymore so the collection will be destroyed anyway.
- if (!document())
- return;
-
- ASSERT(namedFlow->flowState() == NamedFlow::FlowStateNull);
- ASSERT(m_namedFlows.contains(namedFlow));
-
- InspectorInstrumentation::willRemoveNamedFlow(document(), namedFlow);
-
- m_namedFlows.remove(namedFlow);
-}
-
-Document* NamedFlowCollection::document() const
-{
- return lifecycleContext();
-}
-
-PassRefPtr<DOMNamedFlowCollection> NamedFlowCollection::createCSSOMSnapshot()
-{
- Vector<NamedFlow*> createdFlows;
- for (NamedFlowSet::iterator it = m_namedFlows.begin(); it != m_namedFlows.end(); ++it)
- if ((*it)->flowState() == NamedFlow::FlowStateCreated)
- createdFlows.append(*it);
- return DOMNamedFlowCollection::create(createdFlows);
-}
-
-// The HashFunctions object used by the HashSet to compare between NamedFlows.
-// It is safe to set safeToCompareToEmptyOrDeleted because the HashSet will never contain null pointers or deleted values.
-struct NamedFlowCollection::NamedFlowHashFunctions {
- static unsigned hash(NamedFlow* key) { return DefaultHash<String>::Hash::hash(key->name()); }
- static bool equal(NamedFlow* a, NamedFlow* b) { return a->name() == b->name(); }
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-
-// The HashTranslator is used to lookup a NamedFlow in the set using a name.
-struct NamedFlowCollection::NamedFlowHashTranslator {
- static unsigned hash(const String& key) { return DefaultHash<String>::Hash::hash(key); }
- static bool equal(NamedFlow* a, const String& b) { return a->name() == b; }
-};
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.h b/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.h
deleted file mode 100644
index f9c4b9cb446..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NamedFlowCollection.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef NamedFlowCollection_h
-#define NamedFlowCollection_h
-
-#include "core/dom/DocumentLifecycleObserver.h"
-#include "core/dom/NamedFlow.h"
-#include "wtf/Forward.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class Document;
-class DOMNamedFlowCollection;
-
-class NamedFlowCollection : public RefCounted<NamedFlowCollection>, public DocumentLifecycleObserver {
-public:
- static PassRefPtr<NamedFlowCollection> create(Document* doc) { return adoptRef(new NamedFlowCollection(doc)); }
-
- Vector<RefPtr<NamedFlow> > namedFlows();
- NamedFlow* flowByName(const String&);
- PassRefPtr<NamedFlow> ensureFlowWithName(const String&);
-
- void discardNamedFlow(NamedFlow*);
-
- Document* document() const;
-
- virtual ~NamedFlowCollection() { }
-
- PassRefPtr<DOMNamedFlowCollection> createCSSOMSnapshot();
-
-private:
- struct NamedFlowHashFunctions;
- struct NamedFlowHashTranslator;
-
- typedef ListHashSet<NamedFlow*, 1, NamedFlowHashFunctions> NamedFlowSet;
-
- explicit NamedFlowCollection(Document*);
-
- NamedFlowSet m_namedFlows;
-};
-
-} // namespace WebCore
-
-#endif // NamedFlowCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp
index 2265972d656..09808b8895f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.cpp
@@ -35,6 +35,7 @@ namespace WebCore {
using namespace HTMLNames;
+#if !ENABLE(OILPAN)
void NamedNodeMap::ref()
{
m_element->ref();
@@ -44,63 +45,64 @@ void NamedNodeMap::deref()
{
m_element->deref();
}
+#endif
-PassRefPtr<Node> NamedNodeMap::getNamedItem(const AtomicString& name) const
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::getNamedItem(const AtomicString& name) const
{
return m_element->getAttributeNode(name);
}
-PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const
{
return m_element->getAttributeNodeNS(namespaceURI, localName);
}
-PassRefPtr<Node> NamedNodeMap::removeNamedItem(const AtomicString& name, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::removeNamedItem(const AtomicString& name, ExceptionState& exceptionState)
{
- size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(name, m_element->shouldIgnoreAttributeCase()) : kNotFound;
+ size_t index = m_element->hasAttributes() ? m_element->findAttributeIndexByName(name, m_element->shouldIgnoreAttributeCase()) : kNotFound;
if (index == kNotFound) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "No item with name '" + name + "' was found.");
+ return nullptr;
}
return m_element->detachAttribute(index);
}
-PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState& exceptionState)
{
- size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(QualifiedName(nullAtom, localName, namespaceURI)) : kNotFound;
+ size_t index = m_element->hasAttributes() ? m_element->findAttributeIndexByName(QualifiedName(nullAtom, localName, namespaceURI)) : kNotFound;
if (index == kNotFound) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "No item with name '" + namespaceURI + "::" + localName + "' was found.");
+ return nullptr;
}
return m_element->detachAttribute(index);
}
-PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return 0;
+ exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
+ return nullptr;
}
// Not mentioned in spec: throw a HIERARCHY_REQUEST_ERROR if the user passes in a non-attribute node
if (!node->isAttributeNode()) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
- return 0;
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided is not an attribute node.");
+ return nullptr;
}
return m_element->setAttributeNode(toAttr(node), exceptionState);
}
-PassRefPtr<Node> NamedNodeMap::setNamedItemNS(Node* node, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::setNamedItemNS(Node* node, ExceptionState& exceptionState)
{
return setNamedItem(node, exceptionState);
}
-PassRefPtr<Node> NamedNodeMap::item(unsigned index) const
+PassRefPtrWillBeRawPtr<Node> NamedNodeMap::item(unsigned index) const
{
if (index >= length())
- return 0;
- return m_element->ensureAttr(m_element->attributeItem(index)->name());
+ return nullptr;
+ return m_element->ensureAttr(m_element->attributeAt(index).name());
}
size_t NamedNodeMap::length() const
@@ -110,4 +112,9 @@ size_t NamedNodeMap::length() const
return m_element->attributeCount();
}
+void NamedNodeMap::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h
index f01102c9957..b1e569323e5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.h
@@ -26,6 +26,7 @@
#define NamedNodeMap_h
#include "bindings/v8/ScriptWrappable.h"
+#include "core/dom/Element.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/AtomicString.h"
@@ -33,47 +34,50 @@
namespace WebCore {
class Node;
-class Element;
class ExceptionState;
-class NamedNodeMap : public ScriptWrappable {
- WTF_MAKE_FAST_ALLOCATED;
+class NamedNodeMap FINAL : public NoBaseWillBeGarbageCollectedFinalized<NamedNodeMap>, public ScriptWrappable {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
friend class Element;
public:
- static PassOwnPtr<NamedNodeMap> create(Element* element)
+ static PassOwnPtrWillBeRawPtr<NamedNodeMap> create(Element* element)
{
- return adoptPtr(new NamedNodeMap(element));
+ return adoptPtrWillBeNoop(new NamedNodeMap(element));
}
+#if !ENABLE(OILPAN)
void ref();
void deref();
+#endif
// Public DOM interface.
- PassRefPtr<Node> getNamedItem(const AtomicString&) const;
- PassRefPtr<Node> removeNamedItem(const AtomicString& name, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> getNamedItem(const AtomicString&) const;
+ PassRefPtrWillBeRawPtr<Node> removeNamedItem(const AtomicString& name, ExceptionState&);
- PassRefPtr<Node> getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
- PassRefPtr<Node> removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const;
+ PassRefPtrWillBeRawPtr<Node> removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState&);
- PassRefPtr<Node> setNamedItem(Node*, ExceptionState&);
- PassRefPtr<Node> setNamedItemNS(Node*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> setNamedItem(Node*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> setNamedItemNS(Node*, ExceptionState&);
- PassRefPtr<Node> item(unsigned index) const;
+ PassRefPtrWillBeRawPtr<Node> item(unsigned index) const;
size_t length() const;
Element* element() const { return m_element; }
+ void trace(Visitor*);
+
private:
explicit NamedNodeMap(Element* element)
: m_element(element)
{
- // Only supports NamedNodeMaps with Element associated, DocumentType.entities and DocumentType.notations are not supported yet.
+ // Only supports NamedNodeMaps with Element associated.
ASSERT(m_element);
ScriptWrappable::init(this);
}
- Element* m_element;
+ RawPtrWillBeMember<Element> m_element;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl
index 0f51574fdd1..7de6a6f8454 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodeMap.idl
@@ -19,31 +19,31 @@
*/
[
- GenerateVisitDOMWrapper=element,
+ SetWrapperReferenceFrom=element,
+ WillBeGarbageCollected,
] interface NamedNodeMap {
- Node getNamedItem([Default=Undefined] optional DOMString name);
+ [MeasureAs=NamedNodeMapGetNamedItem] Node getNamedItem([Default=Undefined] optional DOMString name);
[NotEnumerable, ImplementedAs=getNamedItem] getter Node ([Default=Undefined] optional DOMString name);
- [RaisesException, CustomElementCallbacks] Node setNamedItem([Default=Undefined] optional Node node);
+ [RaisesException, CustomElementCallbacks, MeasureAs=NamedNodeMapSetNamedItem] Node setNamedItem([Default=Undefined] optional Node node);
- [RaisesException, CustomElementCallbacks] Node removeNamedItem([Default=Undefined] optional DOMString name);
+ [RaisesException, CustomElementCallbacks, MeasureAs=NamedNodeMapRemoveNamedItem] Node removeNamedItem([Default=Undefined] optional DOMString name);
- getter Node item([Default=Undefined] optional unsigned long index);
+ [MeasureAs=NamedNodeMapItem] getter Node item([Default=Undefined] optional unsigned long index);
readonly attribute unsigned long length;
// Introduced in DOM Level 2:
- // FIXME: the implementation does take an exceptioncode parameter.
- /*[RaisesException]*/ Node getNamedItemNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
- [Default=Undefined] optional DOMString localName);
+ [MeasureAs=NamedNodeMapGetNamedItemNS] Node getNamedItemNS([TreatNullAs=NullString, Default=Undefined] optional DOMString namespaceURI,
+ [Default=Undefined] optional DOMString localName);
- [RaisesException, CustomElementCallbacks] Node setNamedItemNS([Default=Undefined] optional Node node);
+ [RaisesException, CustomElementCallbacks, MeasureAs=NamedNodeMapSetNamedItemNS] Node setNamedItemNS([Default=Undefined] optional Node node);
- [RaisesException, CustomElementCallbacks] Node removeNamedItemNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
- [Default=Undefined] optional DOMString localName);
+ [RaisesException, CustomElementCallbacks, MeasureAs=NamedNodeMapRemoveNamedItemNS] Node removeNamedItemNS([TreatNullAs=NullString, Default=Undefined] optional DOMString namespaceURI,
+ [Default=Undefined] optional DOMString localName);
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp
index fb6b772693b..85727582353 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.cpp
@@ -34,21 +34,17 @@
namespace WebCore {
-Node* NamedNodesCollection::item(unsigned index) const
+Element* NamedNodesCollection::item(unsigned index) const
{
if (index < m_nodes.size())
return m_nodes[index].get();
return 0;
}
-Node* NamedNodesCollection::namedItem(const AtomicString& id) const
+void NamedNodesCollection::trace(Visitor* visitor)
{
- for (unsigned i = 0; i < m_nodes.size(); ++i) {
- Node* node = m_nodes[i].get();
- if (node->hasID() && toElement(node)->getIdAttribute() == id)
- return node;
- }
- return 0;
+ visitor->trace(m_nodes);
+ NodeList::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h b/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h
index b202bcf238f..d30a2ad05b6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NamedNodesCollection.h
@@ -31,7 +31,7 @@
#ifndef NamedNodesCollection_h
#define NamedNodesCollection_h
-#include "core/dom/Node.h"
+#include "core/dom/Element.h"
#include "core/dom/NodeList.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -41,20 +41,21 @@ namespace WebCore {
class NamedNodesCollection FINAL : public NodeList {
public:
- static PassRefPtr<NodeList> create(const Vector<RefPtr<Node> >& nodes)
+ static PassRefPtrWillBeRawPtr<NodeList> create(const WillBeHeapVector<RefPtrWillBeMember<Element> >& nodes)
{
- return adoptRef(new NamedNodesCollection(nodes));
+ return adoptRefWillBeNoop(new NamedNodesCollection(nodes));
}
virtual unsigned length() const OVERRIDE { return m_nodes.size(); }
- virtual Node* item(unsigned) const OVERRIDE;
- virtual Node* namedItem(const AtomicString&) const OVERRIDE;
+ virtual Element* item(unsigned) const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- explicit NamedNodesCollection(const Vector<RefPtr<Node> >& nodes)
+ explicit NamedNodesCollection(const WillBeHeapVector<RefPtrWillBeMember<Element> > nodes)
: m_nodes(nodes) { }
- Vector<RefPtr<Node> > m_nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > m_nodes;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NoEventDispatchAssertion.h b/chromium/third_party/WebKit/Source/core/dom/NoEventDispatchAssertion.h
new file mode 100644
index 00000000000..a495212c275
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/NoEventDispatchAssertion.h
@@ -0,0 +1,76 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NoEventDispatchAssertion_h
+#define NoEventDispatchAssertion_h
+
+#include "wtf/MainThread.h"
+#include "wtf/TemporaryChange.h"
+
+namespace WebCore {
+
+#ifndef NDEBUG
+
+class NoEventDispatchAssertion {
+public:
+ NoEventDispatchAssertion()
+ {
+ if (!isMainThread())
+ return;
+ ++s_count;
+ }
+
+ ~NoEventDispatchAssertion()
+ {
+ if (!isMainThread())
+ return;
+ ASSERT(s_count);
+ --s_count;
+ }
+
+ static bool isEventDispatchForbidden()
+ {
+ if (!isMainThread())
+ return false;
+ return s_count;
+ }
+
+ // It's safe to dispatch events in SVGImage since there can't be any script
+ // listeners.
+ class AllowSVGImageEvents {
+ public:
+ AllowSVGImageEvents()
+ : m_change(s_count, 0)
+ {
+ }
+
+ ~AllowSVGImageEvents()
+ {
+ ASSERT(!s_count);
+ }
+
+ TemporaryChange<unsigned> m_change;
+ };
+
+private:
+ static unsigned s_count;
+};
+
+#else
+
+class NoEventDispatchAssertion {
+public:
+ NoEventDispatchAssertion() { }
+
+ class AllowSVGImageEvents {
+ public:
+ AllowSVGImageEvents() { }
+ };
+};
+
+#endif // NDEBUG
+
+} // namespace WebCore
+
+#endif // NoEventDispatchAssertion_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/Node.cpp b/chromium/third_party/WebKit/Source/core/dom/Node.cpp
index abea9efac4e..6dcd3c17be8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Node.cpp
@@ -25,16 +25,15 @@
#include "config.h"
#include "core/dom/Node.h"
-#include "HTMLNames.h"
-#include "XMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptCallStackFactory.h"
+#include "core/HTMLNames.h"
+#include "core/XMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Attr.h"
#include "core/dom/Attribute.h"
#include "core/dom/ChildListMutationScope.h"
#include "core/dom/ChildNodeList.h"
-#include "core/dom/ClassNodeList.h"
#include "core/dom/DOMImplementation.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
@@ -42,25 +41,26 @@
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
#include "core/dom/ElementRareData.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/LiveNodeList.h"
-#include "core/dom/NameNodeList.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeRareData.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/Range.h"
-#include "core/dom/SelectorQuery.h"
-#include "core/dom/TagNodeList.h"
+#include "core/dom/StaticNodeList.h"
#include "core/dom/TemplateContentDocumentFragment.h"
#include "core/dom/Text.h"
#include "core/dom/TreeScopeAdopter.h"
#include "core/dom/UserActionElementSet.h"
-#include "core/dom/WheelController.h"
+#include "core/dom/WeakNodeMap.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/htmlediting.h"
-#include "core/events/BeforeLoadEvent.h"
+#include "core/editing/markup.h"
#include "core/events/Event.h"
#include "core/events/EventDispatchMediator.h"
#include "core/events/EventDispatcher.h"
@@ -70,24 +70,25 @@
#include "core/events/MouseEvent.h"
#include "core/events/MutationEvent.h"
#include "core/events/TextEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/TouchEvent.h"
#include "core/events/UIEvent.h"
#include "core/events/WheelEvent.h"
+#include "core/frame/EventHandlerRegistry.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLDialogElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLStyleElement.h"
-#include "core/html/RadioNodeList.h"
#include "core/page/ContextMenuController.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/RenderBox.h"
#include "core/svg/graphics/SVGImage.h"
#include "platform/Partitions.h"
+#include "platform/TraceEvent.h"
+#include "platform/TracedValue.h"
#include "wtf/HashSet.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCountedLeakCounter.h"
@@ -95,12 +96,11 @@
#include "wtf/text/CString.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
+#if !ENABLE(OILPAN)
void* Node::operator new(size_t size)
{
ASSERT(isMainThread());
@@ -112,14 +112,14 @@ void Node::operator delete(void* ptr)
ASSERT(isMainThread());
partitionFree(ptr);
}
+#endif
-bool Node::isSupported(const String& feature, const String& version)
+#if DUMP_NODE_STATISTICS
+static HashSet<Node*>& liveNodeSet()
{
- return DOMImplementation::hasFeature(feature, version);
+ DEFINE_STATIC_LOCAL(HashSet<Node*>, s_liveNodeSet, ());
+ return s_liveNodeSet;
}
-
-#if DUMP_NODE_STATISTICS
-static HashSet<Node*> liveNodeSet;
#endif
void Node::dumpStatistics()
@@ -132,24 +132,20 @@ void Node::dumpStatistics()
size_t textNodes = 0;
size_t cdataNodes = 0;
size_t commentNodes = 0;
- size_t entityNodes = 0;
size_t piNodes = 0;
size_t documentNodes = 0;
size_t docTypeNodes = 0;
size_t fragmentNodes = 0;
- size_t notationNodes = 0;
- size_t xpathNSNodes = 0;
size_t shadowRootNodes = 0;
HashMap<String, size_t> perTagCount;
size_t attributes = 0;
- size_t attributesWithAttr = 0;
size_t elementsWithAttributeStorage = 0;
size_t elementsWithRareData = 0;
size_t elementsWithNamedNodeMap = 0;
- for (HashSet<Node*>::iterator it = liveNodeSet.begin(); it != liveNodeSet.end(); ++it) {
+ for (HashSet<Node*>::iterator it = liveNodeSet().begin(); it != liveNodeSet().end(); ++it) {
Node* node = *it;
if (node->hasRareData()) {
@@ -169,16 +165,11 @@ void Node::dumpStatistics()
Element* element = toElement(node);
HashMap<String, size_t>::AddResult result = perTagCount.add(element->tagName(), 1);
if (!result.isNewEntry)
- result.iterator->value++;
+ result.storedValue->value++;
- if (ElementData* elementData = element->elementData()) {
+ if (const ElementData* elementData = element->elementData()) {
attributes += elementData->length();
++elementsWithAttributeStorage;
- for (unsigned i = 0; i < elementData->length(); ++i) {
- Attribute* attr = elementData->attributeItem(i);
- if (attr->attr())
- ++attributesWithAttr;
- }
}
break;
}
@@ -198,10 +189,6 @@ void Node::dumpStatistics()
++commentNodes;
break;
}
- case ENTITY_NODE: {
- ++entityNodes;
- break;
- }
case PROCESSING_INSTRUCTION_NODE: {
++piNodes;
break;
@@ -221,18 +208,10 @@ void Node::dumpStatistics()
++fragmentNodes;
break;
}
- case NOTATION_NODE: {
- ++notationNodes;
- break;
- }
- case XPATH_NAMESPACE_NODE: {
- ++xpathNSNodes;
- break;
- }
}
}
- printf("Number of Nodes: %d\n\n", liveNodeSet.size());
+ printf("Number of Nodes: %d\n\n", liveNodeSet().size());
printf("Number of Nodes with RareData: %zu\n\n", nodesWithRareData);
printf("NodeType distribution:\n");
@@ -241,13 +220,10 @@ void Node::dumpStatistics()
printf(" Number of Text nodes: %zu\n", textNodes);
printf(" Number of CDATASection nodes: %zu\n", cdataNodes);
printf(" Number of Comment nodes: %zu\n", commentNodes);
- printf(" Number of Entity nodes: %zu\n", entityNodes);
printf(" Number of ProcessingInstruction nodes: %zu\n", piNodes);
printf(" Number of Document nodes: %zu\n", documentNodes);
printf(" Number of DocumentType nodes: %zu\n", docTypeNodes);
printf(" Number of DocumentFragment nodes: %zu\n", fragmentNodes);
- printf(" Number of Notation nodes: %zu\n", notationNodes);
- printf(" Number of XPathNS nodes: %zu\n", xpathNSNodes);
printf(" Number of ShadowRoot nodes: %zu\n", shadowRootNodes);
printf("Element tag name distibution:\n");
@@ -256,7 +232,6 @@ void Node::dumpStatistics()
printf("Attributes:\n");
printf(" Number of Attributes (non-Node and Node): %zu [%zu]\n", attributes, sizeof(Attribute));
- printf(" Number of Attributes with an Attr: %zu\n", attributesWithAttr);
printf(" Number of Elements with attribute storage: %zu [%zu]\n", elementsWithAttributeStorage, sizeof(ElementData));
printf(" Number of Elements with RareData: %zu\n", elementsWithRareData);
printf(" Number of Elements with NamedNodeMap: %zu [%zu]\n", elementsWithNamedNodeMap, sizeof(NamedNodeMap));
@@ -272,8 +247,28 @@ void Node::trackForDebugging()
#endif
#if DUMP_NODE_STATISTICS
- liveNodeSet.add(this);
+ liveNodeSet().add(this);
+#endif
+}
+
+Node::Node(TreeScope* treeScope, ConstructionType type)
+ : m_nodeFlags(type)
+ , m_parentOrShadowHostNode(nullptr)
+ , m_treeScope(treeScope)
+ , m_previous(nullptr)
+ , m_next(nullptr)
+{
+ ASSERT(m_treeScope || type == CreateDocument || type == CreateShadowRoot);
+ ScriptWrappable::init(this);
+#if !ENABLE(OILPAN)
+ if (m_treeScope)
+ m_treeScope->guardRef();
+#endif
+
+#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
+ trackForDebugging();
#endif
+ InspectorCounters::incrementCounter(InspectorCounters::NodeCounter);
}
Node::~Node()
@@ -283,9 +278,10 @@ Node::~Node()
#endif
#if DUMP_NODE_STATISTICS
- liveNodeSet.remove(this);
+ liveNodeSet().remove(this);
#endif
+#if !ENABLE(OILPAN)
if (hasRareData())
clearRareData();
@@ -301,10 +297,20 @@ Node::~Node()
if (m_treeScope)
m_treeScope->guardDeref();
+#else
+ // With Oilpan, the rare data finalizer also asserts for
+ // this condition (we cannot directly access it here.)
+ RELEASE_ASSERT(hasRareData() || !renderer());
+#endif
InspectorCounters::decrementCounter(InspectorCounters::NodeCounter);
+
+ if (getFlag(HasWeakReferencesFlag))
+ WeakNodeMap::notifyNodeDestroyed(this);
}
+#if !ENABLE(OILPAN)
+// With Oilpan all of this is handled with weak processing of the document.
void Node::willBeDeletedFromDocument()
{
if (!isTreeScopeInitialized())
@@ -313,15 +319,18 @@ void Node::willBeDeletedFromDocument()
Document& document = this->document();
if (hasEventTargetData()) {
- document.didRemoveEventTargetNode(this);
clearEventTargetData();
+ document.didClearTouchEventHandlers(this);
+ if (document.frameHost())
+ document.frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers(*this);
}
if (AXObjectCache* cache = document.existingAXObjectCache())
cache->remove(this);
- document.markers()->removeMarkers(this);
+ document.markers().removeMarkers(this);
}
+#endif
NodeRareData* Node::rareData() const
{
@@ -334,18 +343,18 @@ NodeRareData& Node::ensureRareData()
if (hasRareData())
return *rareData();
- NodeRareData* data;
if (isElementNode())
- data = ElementRareData::create(m_data.m_renderer).leakPtr();
+ m_data.m_rareData = ElementRareData::create(m_data.m_renderer);
else
- data = NodeRareData::create(m_data.m_renderer).leakPtr();
- ASSERT(data);
+ m_data.m_rareData = NodeRareData::create(m_data.m_renderer);
+
+ ASSERT(m_data.m_rareData);
- m_data.m_rareData = data;
setFlag(HasRareDataFlag);
- return *data;
+ return *rareData();
}
+#if !ENABLE(OILPAN)
void Node::clearRareData()
{
ASSERT(hasRareData());
@@ -359,6 +368,7 @@ void Node::clearRareData()
m_data.m_renderer = renderer;
clearFlag(HasRareDataFlag);
}
+#endif
Node* Node::toNode()
{
@@ -380,12 +390,14 @@ void Node::setNodeValue(const String&)
// By default, setting nodeValue has no effect.
}
-PassRefPtr<NodeList> Node::childNodes()
+PassRefPtrWillBeRawPtr<NodeList> Node::childNodes()
{
- return ensureRareData().ensureNodeLists().ensureChildNodeList(this);
+ if (isContainerNode())
+ return ensureRareData().ensureNodeLists().ensureChildNodeList(toContainerNode(*this));
+ return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(*this);
}
-Node& Node::lastDescendant() const
+Node& Node::lastDescendantOrSelf() const
{
Node* n = const_cast<Node*>(this);
while (n && n->lastChild())
@@ -450,7 +462,7 @@ Node* Node::pseudoAwareLastChild() const
return lastChild();
}
-void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
+void Node::insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& exceptionState)
{
if (isContainerNode())
toContainerNode(this)->insertBefore(newChild, refChild, exceptionState);
@@ -458,7 +470,7 @@ void Node::insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionStat
exceptionState.throwDOMException(HierarchyRequestError, "This node type does not support this method.");
}
-void Node::replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
+void Node::replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& exceptionState)
{
if (isContainerNode())
toContainerNode(this)->replaceChild(newChild, oldChild, exceptionState);
@@ -474,7 +486,7 @@ void Node::removeChild(Node* oldChild, ExceptionState& exceptionState)
exceptionState.throwDOMException(NotFoundError, "This node type does not support this method.");
}
-void Node::appendChild(PassRefPtr<Node> newChild, ExceptionState& exceptionState)
+void Node::appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& exceptionState)
{
if (isContainerNode())
toContainerNode(this)->appendChild(newChild, exceptionState);
@@ -493,38 +505,23 @@ void Node::normalize()
// Go through the subtree beneath us, normalizing all nodes. This means that
// any two adjacent text nodes are merged and any empty text nodes are removed.
- RefPtr<Node> node = this;
+ RefPtrWillBeRawPtr<Node> node = this;
while (Node* firstChild = node->firstChild())
node = firstChild;
while (node) {
- NodeType type = node->nodeType();
- if (type == ELEMENT_NODE)
+ if (node->isElementNode())
toElement(node)->normalizeAttributes();
if (node == this)
break;
- if (type == TEXT_NODE)
+ if (node->nodeType() == TEXT_NODE)
node = toText(node)->mergeNextSiblingNodesIfPossible();
else
node = NodeTraversal::nextPostOrder(*node);
}
}
-const AtomicString& Node::prefix() const
-{
- // For nodes other than elements and attributes, the prefix is always null
- return nullAtom;
-}
-
-void Node::setPrefix(const AtomicString& /*prefix*/, ExceptionState& exceptionState)
-{
- // The spec says that for nodes other than elements and attributes, prefix is always null.
- // It does not say what to do when the user tries to set the prefix on another type of
- // node, however Mozilla throws a NamespaceError exception.
- exceptionState.throwDOMException(NamespaceError, "Prefixes are only supported on element and attribute nodes.");
-}
-
const AtomicString& Node::localName() const
{
return nullAtom;
@@ -537,13 +534,13 @@ const AtomicString& Node::namespaceURI() const
bool Node::isContentEditable(UserSelectAllTreatment treatment)
{
- document().updateStyleIfNeeded();
+ document().updateRenderTreeIfNeeded();
return rendererIsEditable(Editable, treatment);
}
bool Node::isContentRichlyEditable()
{
- document().updateStyleIfNeeded();
+ document().updateRenderTreeIfNeeded();
return rendererIsEditable(RichlyEditable, UserSelectAllIsAlwaysNonEditable);
}
@@ -677,47 +674,32 @@ void Node::setIsLink(bool isLink)
setFlag(isLink && !SVGImage::isInSVGImage(toElement(this)), IsLinkFlag);
}
-void Node::markAncestorsWithChildNeedsDistributionRecalc()
+void Node::setNeedsStyleInvalidation()
{
- for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode())
- node->setChildNeedsDistributionRecalc();
- if (document().childNeedsDistributionRecalc())
- document().scheduleStyleRecalc();
+ setFlag(NeedsStyleInvalidationFlag);
+ markAncestorsWithChildNeedsStyleInvalidation();
}
-namespace {
-
-unsigned styledSubtreeSize(const Node*);
-
-unsigned styledSubtreeSizeIgnoringSelfAndShadowRoots(const Node* rootNode)
+void Node::markAncestorsWithChildNeedsStyleInvalidation()
{
- unsigned nodeCount = 0;
- for (Node* child = rootNode->firstChild(); child; child = child->nextSibling())
- nodeCount += styledSubtreeSize(child);
- return nodeCount;
+ for (Node* node = parentOrShadowHostNode(); node && !node->childNeedsStyleInvalidation(); node = node->parentOrShadowHostNode())
+ node->setChildNeedsStyleInvalidation();
+ document().scheduleRenderTreeUpdateIfNeeded();
}
-unsigned styledSubtreeSize(const Node* rootNode)
+void Node::markAncestorsWithChildNeedsDistributionRecalc()
{
- if (rootNode->isTextNode())
- return 1;
- if (!rootNode->isElementNode())
- return 0;
-
- // FIXME: We should use a shadow-tree aware node-iterator when such exists.
- unsigned nodeCount = 1 + styledSubtreeSizeIgnoringSelfAndShadowRoots(rootNode);
-
- // ShadowRoots don't have style (so don't count them), but their children might.
- for (ShadowRoot* shadowRoot = rootNode->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot())
- nodeCount += styledSubtreeSizeIgnoringSelfAndShadowRoots(shadowRoot);
-
- return nodeCount;
+ for (Node* node = this; node && !node->childNeedsDistributionRecalc(); node = node->parentOrShadowHostNode())
+ node->setChildNeedsDistributionRecalc();
+ document().scheduleRenderTreeUpdateIfNeeded();
}
+namespace {
+
PassRefPtr<JSONArray> jsStackAsJSONArray()
{
RefPtr<JSONArray> jsonArray = JSONArray::create();
- RefPtr<ScriptCallStack> stack = createScriptCallStack(10);
+ RefPtrWillBeRawPtr<ScriptCallStack> stack = createScriptCallStack(10);
if (!stack)
return jsonArray.release();
for (size_t i = 0; i < stack->size(); i++)
@@ -736,16 +718,30 @@ PassRefPtr<JSONObject> jsonObjectForStyleInvalidation(unsigned nodeCount, const
} // anonymous namespace'd functions supporting traceStyleChange
+unsigned Node::styledSubtreeSize() const
+{
+ unsigned nodeCount = 0;
+
+ for (const Node* node = this; node; node = NodeTraversal::next(*node, this)) {
+ if (node->isTextNode() || node->isElementNode())
+ nodeCount++;
+ for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
+ nodeCount += root->styledSubtreeSize();
+ }
+
+ return nodeCount;
+}
+
void Node::traceStyleChange(StyleChangeType changeType)
{
static const unsigned kMinLoggedSize = 100;
- unsigned nodeCount = styledSubtreeSize(this);
+ unsigned nodeCount = styledSubtreeSize();
if (nodeCount < kMinLoggedSize)
return;
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("style.debug"),
"Node::setNeedsStyleRecalc",
- "data", jsonObjectForStyleInvalidation(nodeCount, this)->toJSONString().ascii()
+ "data", TracedValue::fromJSONValue(jsonObjectForStyleInvalidation(nodeCount, this))
);
}
@@ -767,20 +763,15 @@ void Node::markAncestorsWithChildNeedsStyleRecalc()
{
for (ContainerNode* p = parentOrShadowHostNode(); p && !p->childNeedsStyleRecalc(); p = p->parentOrShadowHostNode())
p->setChildNeedsStyleRecalc();
-
- if (document().needsStyleRecalc() || document().childNeedsStyleRecalc())
- document().scheduleStyleRecalc();
+ document().scheduleRenderTreeUpdateIfNeeded();
}
-void Node::setNeedsStyleRecalc(StyleChangeType changeType, StyleChangeSource source)
+void Node::setNeedsStyleRecalc(StyleChangeType changeType)
{
ASSERT(changeType != NoStyleChange);
if (!inActiveDocument())
return;
- if (source == StyleChangeFromRenderer)
- setFlag(NotifyRendererWithIdenticalStyles);
-
StyleChangeType existingChangeType = styleChangeType();
if (changeType > existingChangeType) {
setStyleChange(changeType);
@@ -798,7 +789,8 @@ void Node::setNeedsStyleRecalc(StyleChangeType changeType, StyleChangeSource sou
void Node::clearNeedsStyleRecalc()
{
m_nodeFlags &= ~StyleChangeMask;
- clearFlag(NotifyRendererWithIdenticalStyles);
+
+ clearSVGFilterNeedsLayerUpdate();
if (isElementNode() && hasRareData())
toElement(*this).setAnimationStyleChange(false);
@@ -823,7 +815,7 @@ bool Node::shouldHaveFocusAppearance() const
bool Node::isInert() const
{
const HTMLDialogElement* dialog = document().activeModalDialog();
- if (dialog && !containsIncludingShadowDOM(dialog) && !dialog->containsIncludingShadowDOM(this))
+ if (dialog && this != document() && !NodeRenderingTraversal::contains(dialog, this))
return true;
return document().ownerElement() && document().ownerElement()->isInert();
}
@@ -837,40 +829,6 @@ unsigned Node::nodeIndex() const
return count;
}
-template<unsigned type>
-bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName)
-{
- if (nodeListCounts[type] && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
- return true;
- return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName);
-}
-
-template<>
-bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&)
-{
- return false;
-}
-
-bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const
-{
- if (attrName)
- return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListCounts, *attrName);
-
- for (int type = 0; type < numNodeListInvalidationTypes; type++) {
- if (m_nodeListCounts[type])
- return true;
- }
-
- return false;
-}
-
-void Document::invalidateNodeListCaches(const QualifiedName* attrName)
-{
- HashSet<LiveNodeListBase*>::iterator end = m_listsInvalidatedAtDocument.end();
- for (HashSet<LiveNodeListBase*>::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it)
- (*it)->invalidateCache(attrName);
-}
-
void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, Element* attributeOwnerElement)
{
if (hasRareData() && (!attrName || isAttributeNode())) {
@@ -888,11 +846,8 @@ void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, El
document().invalidateNodeListCaches(attrName);
for (Node* node = this; node; node = node->parentNode()) {
- if (!node->hasRareData())
- continue;
- NodeRareData* data = node->rareData();
- if (data->nodeLists())
- data->nodeLists()->invalidateCaches(attrName);
+ if (NodeListsNodeData* lists = node->nodeLists())
+ lists->invalidateCaches(attrName);
}
}
@@ -906,35 +861,10 @@ void Node::clearNodeLists()
rareData()->clearNodeLists();
}
-void Node::checkSetPrefix(const AtomicString& prefix, ExceptionState& exceptionState)
-{
- // Perform error checking as required by spec for setting Node.prefix. Used by
- // Element::setPrefix() and Attr::setPrefix()
-
- if (!prefix.isEmpty() && !Document::isValidName(prefix)) {
- exceptionState.throwDOMException(InvalidCharacterError, "The prefix '" + prefix + "' is not a valid name.");
- return;
- }
-
- // FIXME: Raise NamespaceError if prefix is malformed per the Namespaces in XML specification.
-
- const AtomicString& nodeNamespaceURI = namespaceURI();
- if (nodeNamespaceURI.isEmpty() && !prefix.isEmpty()) {
- exceptionState.throwDOMException(NamespaceError, "No namespace is set, so a namespace prefix may not be set.");
- return;
- }
-
- if (prefix == xmlAtom && nodeNamespaceURI != XMLNames::xmlNamespaceURI) {
- exceptionState.throwDOMException(NamespaceError, "The prefix '" + xmlAtom + "' may not be set on namespace '" + nodeNamespaceURI + "'.");
- return;
- }
- // Attribute-specific checks are in Attr::setPrefix().
-}
-
bool Node::isDescendantOf(const Node *other) const
{
// Return true if other is an ancestor of this, otherwise false
- if (!other || !other->hasChildNodes() || inDocument() != other->inDocument())
+ if (!other || !other->hasChildren() || inDocument() != other->inDocument())
return false;
if (other->treeScope() != treeScope())
return false;
@@ -968,7 +898,7 @@ bool Node::containsIncludingShadowDOM(const Node* node) const
if (inDocument() != node->inDocument())
return false;
- bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildNodes();
+ bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildren();
bool hasShadow = isElementNode() && toElement(this)->shadow();
if (!hasChildren && !hasShadow)
return false;
@@ -1051,10 +981,8 @@ void Node::attach(const AttachContext&)
clearNeedsStyleRecalc();
- if (Document* doc = documentInternal()) {
- if (AXObjectCache* cache = doc->axObjectCache())
- cache->updateCacheAfterNodeIsAttached(this);
- }
+ if (AXObjectCache* cache = document().axObjectCache())
+ cache->updateCacheAfterNodeIsAttached(this);
}
#ifndef NDEBUG
@@ -1068,6 +996,9 @@ bool Node::inDetach() const
void Node::detach(const AttachContext& context)
{
+ ASSERT(document().lifecycle().stateAllowsDetach());
+ DocumentLifecycle::DetachScope willDetach(document().lifecycle());
+
#ifndef NDEBUG
ASSERT(!detachingNode);
detachingNode = this;
@@ -1093,6 +1024,11 @@ void Node::detach(const AttachContext& context)
setStyleChange(NeedsReattachStyleChange);
setChildNeedsStyleRecalc();
+ if (StyleResolver* resolver = document().styleResolver())
+ resolver->ruleFeatureSet().styleInvalidator().clearInvalidation(*this);
+ clearChildNeedsStyleInvalidation();
+ clearNeedsStyleInvalidation();
+
#ifndef NDEBUG
detachingNode = 0;
#endif
@@ -1102,12 +1038,12 @@ void Node::reattachWhitespaceSiblings(Text* start)
{
for (Node* sibling = start; sibling; sibling = sibling->nextSibling()) {
if (sibling->isTextNode() && toText(sibling)->containsOnlyWhitespace()) {
- bool hadRenderer = sibling->hasRenderer();
+ bool hadRenderer = !!sibling->renderer();
sibling->reattach();
// If the reattach didn't toggle the visibility of the whitespace we don't
// need to continue reattaching siblings since they won't toggle visibility
// either.
- if (hadRenderer == sibling->hasRenderer())
+ if (hadRenderer == !!sibling->renderer())
return;
} else if (sibling->renderer()) {
return;
@@ -1196,11 +1132,6 @@ bool Node::canStartSelection() const
return parentOrShadowHostNode() ? parentOrShadowHostNode()->canStartSelection() : true;
}
-bool Node::isRegisteredWithNamedFlow() const
-{
- return document().renderView()->flowThreadController()->isContentNodeRegisteredWithAnyNamedFlow(this);
-}
-
Element* Node::shadowHost() const
{
if (ShadowRoot* root = containingShadowRoot())
@@ -1218,8 +1149,8 @@ Node* Node::deprecatedShadowAncestorNode() const
ShadowRoot* Node::containingShadowRoot() const
{
- Node* root = treeScope().rootNode();
- return root && root->isShadowRoot() ? toShadowRoot(root) : 0;
+ Node& root = treeScope().rootNode();
+ return root.isShadowRoot() ? toShadowRoot(&root) : 0;
}
Node* Node::nonBoundaryShadowTreeRootNode()
@@ -1280,7 +1211,7 @@ Element *Node::enclosingBlockFlowElement() const
n = n->parentNode();
if (!n)
break;
- if (n->isBlockFlowElement() || n->hasTagName(bodyTag))
+ if (n->isBlockFlowElement() || isHTMLBodyElement(*n))
return toElement(n);
}
return 0;
@@ -1289,7 +1220,7 @@ Element *Node::enclosingBlockFlowElement() const
bool Node::isRootEditableElement() const
{
return rendererIsEditable() && isElementNode() && (!parentNode() || !parentNode()->rendererIsEditable()
- || !parentNode()->isElementNode() || hasTagName(bodyTag));
+ || !parentNode()->isElementNode() || isHTMLBodyElement((*this)));
}
Element* Node::rootEditableElement(EditableType editableType) const
@@ -1308,7 +1239,7 @@ Element* Node::rootEditableElement() const
for (Node* n = const_cast<Node*>(this); n && n->rendererIsEditable(); n = n->parentNode()) {
if (n->isElementNode())
result = toElement(n);
- if (n->hasTagName(bodyTag))
+ if (isHTMLBodyElement(*n))
break;
}
return result;
@@ -1321,69 +1252,6 @@ bool Node::inSameContainingBlockFlowElement(Node *n)
// FIXME: End of obviously misplaced HTML editing functions. Try to move these out of Node.
-PassRefPtr<NodeList> Node::getElementsByTagName(const AtomicString& localName)
-{
- if (localName.isNull())
- return 0;
-
- if (document().isHTMLDocument())
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<HTMLTagNodeList>(this, HTMLTagNodeListType, localName);
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<TagNodeList>(this, TagNodeListType, localName);
-}
-
-PassRefPtr<NodeList> Node::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
-{
- if (localName.isNull())
- return 0;
-
- if (namespaceURI == starAtom)
- return getElementsByTagName(localName);
-
- return ensureRareData().ensureNodeLists().addCacheWithQualifiedName(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
-}
-
-PassRefPtr<NodeList> Node::getElementsByName(const String& elementName)
-{
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<NameNodeList>(this, NameNodeListType, elementName);
-}
-
-PassRefPtr<NodeList> Node::getElementsByClassName(const String& classNames)
-{
- return ensureRareData().ensureNodeLists().addCacheWithName<ClassNodeList>(this, ClassNodeListType, classNames);
-}
-
-PassRefPtr<RadioNodeList> Node::radioNodeList(const AtomicString& name)
-{
- ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<RadioNodeList>(this, RadioNodeListType, name);
-}
-
-PassRefPtr<Element> Node::querySelector(const AtomicString& selectors, ExceptionState& exceptionState)
-{
- if (selectors.isEmpty()) {
- exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
- return 0;
- }
-
- SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
- if (!selectorQuery)
- return 0;
- return selectorQuery->queryFirst(*this);
-}
-
-PassRefPtr<NodeList> Node::querySelectorAll(const AtomicString& selectors, ExceptionState& exceptionState)
-{
- if (selectors.isEmpty()) {
- exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
- return 0;
- }
-
- SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
- if (!selectorQuery)
- return 0;
- return selectorQuery->queryAll(*this);
-}
-
Document* Node::ownerDocument() const
{
Document* doc = &document();
@@ -1413,9 +1281,6 @@ bool Node::isEqualNode(Node* other) const
if (namespaceURI() != other->namespaceURI())
return false;
- if (prefix() != other->prefix())
- return false;
-
if (nodeValue() != other->nodeValue())
return false;
@@ -1436,7 +1301,7 @@ bool Node::isEqualNode(Node* other) const
if (otherChild)
return false;
- if (nodeType == DOCUMENT_TYPE_NODE) {
+ if (isDocumentTypeNode()) {
const DocumentType* documentTypeThis = toDocumentType(this);
const DocumentType* documentTypeOther = toDocumentType(other);
@@ -1445,11 +1310,6 @@ bool Node::isEqualNode(Node* other) const
if (documentTypeThis->systemId() != documentTypeOther->systemId())
return false;
-
- if (documentTypeThis->internalSubset() != documentTypeOther->internalSubset())
- return false;
-
- // FIXME: We don't compare entities or notations because currently both are always empty.
}
return true;
@@ -1461,22 +1321,22 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
switch (nodeType()) {
case ELEMENT_NODE: {
- const Element* elem = toElement(this);
-
- if (elem->prefix().isNull())
- return elem->namespaceURI() == namespaceURI;
+ const Element& element = toElement(*this);
- if (elem->hasAttributes()) {
- for (unsigned i = 0; i < elem->attributeCount(); i++) {
- const Attribute* attr = elem->attributeItem(i);
+ if (element.prefix().isNull())
+ return element.namespaceURI() == namespaceURI;
- if (attr->localName() == xmlnsAtom)
- return attr->value() == namespaceURI;
+ if (element.hasAttributes()) {
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->localName() == xmlnsAtom)
+ return it->value() == namespaceURI;
}
}
- if (Element* ancestor = ancestorElement())
- return ancestor->isDefaultNamespace(namespaceURI);
+ if (Element* parent = parentElement())
+ return parent->isDefaultNamespace(namespaceURI);
return false;
}
@@ -1484,8 +1344,6 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
if (Element* de = toDocument(this)->documentElement())
return de->isDefaultNamespace(namespaceURI);
return false;
- case ENTITY_NODE:
- case NOTATION_NODE:
case DOCUMENT_TYPE_NODE:
case DOCUMENT_FRAGMENT_NODE:
return false;
@@ -1496,8 +1354,8 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
return false;
}
default:
- if (Element* ancestor = ancestorElement())
- return ancestor->isDefaultNamespace(namespaceURI);
+ if (Element* parent = parentElement())
+ return parent->isDefaultNamespace(namespaceURI);
return false;
}
}
@@ -1505,34 +1363,37 @@ bool Node::isDefaultNamespace(const AtomicString& namespaceURIMaybeEmpty) const
const AtomicString& Node::lookupPrefix(const AtomicString& namespaceURI) const
{
// Implemented according to
- // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespacePrefixAlgo
+ // http://dom.spec.whatwg.org/#dom-node-lookupprefix
- if (namespaceURI.isEmpty())
+ if (namespaceURI.isEmpty() || namespaceURI.isNull())
return nullAtom;
+ const Element* context;
+
switch (nodeType()) {
case ELEMENT_NODE:
- return lookupNamespacePrefix(namespaceURI, toElement(this));
+ context = toElement(this);
+ break;
case DOCUMENT_NODE:
- if (Element* de = toDocument(this)->documentElement())
- return de->lookupPrefix(namespaceURI);
- return nullAtom;
- case ENTITY_NODE:
- case NOTATION_NODE:
+ context = toDocument(this)->documentElement();
+ break;
case DOCUMENT_FRAGMENT_NODE:
case DOCUMENT_TYPE_NODE:
- return nullAtom;
- case ATTRIBUTE_NODE: {
- const Attr *attr = toAttr(this);
- if (attr->ownerElement())
- return attr->ownerElement()->lookupPrefix(namespaceURI);
- return nullAtom;
- }
+ context = 0;
+ break;
+ // FIXME: Remove this when Attr no longer extends Node (CR305105)
+ case ATTRIBUTE_NODE:
+ context = toAttr(this)->ownerElement();
+ break;
default:
- if (Element* ancestor = ancestorElement())
- return ancestor->lookupPrefix(namespaceURI);
- return nullAtom;
+ context = parentElement();
+ break;
}
+
+ if (!context)
+ return nullAtom;
+
+ return context->locateNamespacePrefix(namespaceURI);
}
const AtomicString& Node::lookupNamespaceURI(const String& prefix) const
@@ -1545,38 +1406,35 @@ const AtomicString& Node::lookupNamespaceURI(const String& prefix) const
switch (nodeType()) {
case ELEMENT_NODE: {
- const Element *elem = toElement(this);
-
- if (!elem->namespaceURI().isNull() && elem->prefix() == prefix)
- return elem->namespaceURI();
-
- if (elem->hasAttributes()) {
- for (unsigned i = 0; i < elem->attributeCount(); i++) {
- const Attribute* attr = elem->attributeItem(i);
-
- if (attr->prefix() == xmlnsAtom && attr->localName() == prefix) {
- if (!attr->value().isEmpty())
- return attr->value();
-
+ const Element& element = toElement(*this);
+
+ if (!element.namespaceURI().isNull() && element.prefix() == prefix)
+ return element.namespaceURI();
+
+ if (element.hasAttributes()) {
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->prefix() == xmlnsAtom && it->localName() == prefix) {
+ if (!it->value().isEmpty())
+ return it->value();
return nullAtom;
- } else if (attr->localName() == xmlnsAtom && prefix.isNull()) {
- if (!attr->value().isEmpty())
- return attr->value();
-
+ }
+ if (it->localName() == xmlnsAtom && prefix.isNull()) {
+ if (!it->value().isEmpty())
+ return it->value();
return nullAtom;
}
}
}
- if (Element* ancestor = ancestorElement())
- return ancestor->lookupNamespaceURI(prefix);
+ if (Element* parent = parentElement())
+ return parent->lookupNamespaceURI(prefix);
return nullAtom;
}
case DOCUMENT_NODE:
if (Element* de = toDocument(this)->documentElement())
return de->lookupNamespaceURI(prefix);
return nullAtom;
- case ENTITY_NODE:
- case NOTATION_NODE:
case DOCUMENT_TYPE_NODE:
case DOCUMENT_FRAGMENT_NODE:
return nullAtom;
@@ -1588,37 +1446,12 @@ const AtomicString& Node::lookupNamespaceURI(const String& prefix) const
return nullAtom;
}
default:
- if (Element* ancestor = ancestorElement())
- return ancestor->lookupNamespaceURI(prefix);
+ if (Element* parent = parentElement())
+ return parent->lookupNamespaceURI(prefix);
return nullAtom;
}
}
-const AtomicString& Node::lookupNamespacePrefix(const AtomicString& _namespaceURI, const Element* originalElement) const
-{
- if (_namespaceURI.isNull())
- return nullAtom;
-
- if (originalElement->lookupNamespaceURI(prefix()) == _namespaceURI)
- return prefix();
-
- ASSERT(isElementNode());
- const Element* thisElement = toElement(this);
- if (thisElement->hasAttributes()) {
- for (unsigned i = 0; i < thisElement->attributeCount(); i++) {
- const Attribute* attr = thisElement->attributeItem(i);
-
- if (attr->prefix() == xmlnsAtom && attr->value() == _namespaceURI
- && originalElement->lookupNamespaceURI(attr->localName()) == _namespaceURI)
- return attr->localName();
- }
- }
-
- if (Element* ancestor = ancestorElement())
- return ancestor->lookupNamespacePrefix(_namespaceURI, originalElement);
- return nullAtom;
-}
-
static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool& isNullString, StringBuilder& content)
{
switch (node->nodeType()) {
@@ -1635,18 +1468,18 @@ static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool&
break;
case Node::ELEMENT_NODE:
- if (node->hasTagName(brTag) && convertBRsToNewlines) {
+ if (isHTMLBRElement(*node) && convertBRsToNewlines) {
isNullString = false;
content.append('\n');
break;
}
// Fall through.
case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
isNullString = false;
- for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
- if (child->nodeType() == Node::COMMENT_NODE || child->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
+ for (Node* child = toContainerNode(node)->firstChild(); child; child = child->nextSibling()) {
+ Node::NodeType childNodeType = child->nodeType();
+ if (childNodeType == Node::COMMENT_NODE || childNodeType == Node::PROCESSING_INSTRUCTION_NODE)
continue;
appendTextContent(child, convertBRsToNewlines, isNullString, content);
}
@@ -1654,8 +1487,6 @@ static void appendTextContent(const Node* node, bool convertBRsToNewlines, bool&
case Node::DOCUMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
- case Node::NOTATION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
}
}
@@ -1679,35 +1510,28 @@ void Node::setTextContent(const String& text)
return;
case ELEMENT_NODE:
case ATTRIBUTE_NODE:
- case ENTITY_NODE:
case DOCUMENT_FRAGMENT_NODE: {
- RefPtr<ContainerNode> container = toContainerNode(this);
+ // FIXME: Merge this logic into replaceChildrenWithText.
+ RefPtrWillBeRawPtr<ContainerNode> container = toContainerNode(this);
+ // No need to do anything if the text is identical.
+ if (container->hasOneTextChild() && toText(container->firstChild())->data() == text)
+ return;
ChildListMutationScope mutation(*this);
container->removeChildren();
+ // Note: This API will not insert empty text nodes:
+ // http://dom.spec.whatwg.org/#dom-node-textcontent
if (!text.isEmpty())
container->appendChild(document().createTextNode(text), ASSERT_NO_EXCEPTION);
return;
}
case DOCUMENT_NODE:
case DOCUMENT_TYPE_NODE:
- case NOTATION_NODE:
- case XPATH_NAMESPACE_NODE:
// Do nothing.
return;
}
ASSERT_NOT_REACHED();
}
-Element* Node::ancestorElement() const
-{
- // In theory, there can be EntityReference nodes between elements, but this is currently not supported.
- for (ContainerNode* n = parentNode(); n; n = n->parentNode()) {
- if (n->isElementNode())
- return toElement(n);
- }
- return 0;
-}
-
bool Node::offsetInCharacters() const
{
return false;
@@ -1751,17 +1575,17 @@ unsigned short Node::compareDocumentPositionInternal(const Node* otherNode, Shad
// We are comparing two attributes on the same node. Crawl our attribute map and see which one we hit first.
const Element* owner1 = attr1->ownerElement();
owner1->synchronizeAllAttributes();
- unsigned length = owner1->attributeCount();
- for (unsigned i = 0; i < length; ++i) {
+ AttributeCollection attributes = owner1->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
// If neither of the two determining nodes is a child node and nodeType is the same for both determining nodes, then an
// implementation-dependent order between the determining nodes is returned. This order is stable as long as no nodes of
// the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
// when comparing two attributes of the same element, and inserting or removing additional attributes might change
// the order between existing attributes.
- const Attribute* attribute = owner1->attributeItem(i);
- if (attr1->qualifiedName() == attribute->name())
+ if (attr1->qualifiedName() == it->name())
return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
- if (attr2->qualifiedName() == attribute->name())
+ if (attr2->qualifiedName() == it->name())
return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
}
@@ -1796,7 +1620,7 @@ unsigned short Node::compareDocumentPositionInternal(const Node* otherNode, Shad
unsigned connection = start1->treeScope() != start2->treeScope() ? DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC : 0;
// Walk the two chains backwards and look for the first difference.
- for (unsigned i = min(index1, index2); i; --i) {
+ for (unsigned i = std::min(index1, index2); i; --i) {
const Node* child1 = chain1[--index1];
const Node* child2 = chain2[--index2];
if (child1 != child2) {
@@ -1848,8 +1672,7 @@ FloatPoint Node::convertToPage(const FloatPoint& p) const
return renderer()->localToAbsolute(p, UseTransforms);
// Otherwise go up the tree looking for a renderer
- Element *parent = ancestorElement();
- if (parent)
+ if (Element* parent = parentElement())
return parent->convertToPage(p);
// No parent - no conversion needed
@@ -1863,8 +1686,7 @@ FloatPoint Node::convertFromPage(const FloatPoint& p) const
return renderer()->absoluteToLocal(p, UseTransforms);
// Otherwise go up the tree looking for a renderer
- Element *parent = ancestorElement();
- if (parent)
+ if (Element* parent = parentElement())
return parent->convertFromPage(p);
// No parent - no conversion needed
@@ -1907,7 +1729,9 @@ static void appendAttributeDesc(const Node* node, StringBuilder& stringBuilder,
return;
stringBuilder.append(attrDesc);
+ stringBuilder.append("=\"");
stringBuilder.append(attr);
+ stringBuilder.append("\"");
}
void Node::showNode(const char* prefix) const
@@ -1921,8 +1745,9 @@ void Node::showNode(const char* prefix) const
fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data());
} else {
StringBuilder attrs;
- appendAttributeDesc(this, attrs, classAttr, " CLASS=");
- appendAttributeDesc(this, attrs, styleAttr, " STYLE=");
+ appendAttributeDesc(this, attrs, idAttr, " ID");
+ appendAttributeDesc(this, attrs, classAttr, " CLASS");
+ appendAttributeDesc(this, attrs, styleAttr, " STYLE");
fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.toString().utf8().data());
}
}
@@ -1963,11 +1788,12 @@ void Node::showNodePathForThis() const
if (previous->nodeName() == node->nodeName())
++count;
if (hasIdAttr)
- fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.string().utf8().data(), count);
+ fprintf(stderr, "[@id=\"%s\" and position()=%d]", idattr.utf8().data(), count);
else
fprintf(stderr, "[%d]", count);
- } else if (hasIdAttr)
- fprintf(stderr, "[@id=\"%s\"]", idattr.string().utf8().data());
+ } else if (hasIdAttr) {
+ fprintf(stderr, "[@id=\"%s\"]", idattr.utf8().data());
+ }
break;
}
case TEXT_NODE:
@@ -2010,7 +1836,7 @@ void Node::showTreeAndMark(const Node* markedNode1, const char* markedLabel1, co
{
const Node* rootNode;
const Node* node = this;
- while (node->parentOrShadowHostNode() && !node->hasTagName(bodyTag))
+ while (node->parentOrShadowHostNode() && !isHTMLBodyElement(*node))
node = node->parentOrShadowHostNode();
rootNode = node;
@@ -2036,7 +1862,7 @@ static ContainerNode* parentOrShadowHostOrFrameOwner(const Node* node)
{
ContainerNode* parent = node->parentOrShadowHostNode();
if (!parent && node->document().frame())
- parent = node->document().frame()->ownerElement();
+ parent = node->document().frame()->deprecatedLocalOwner();
return parent;
}
@@ -2071,31 +1897,13 @@ void Node::showTreeForThisAcrossFrame() const
// --------
-void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName)
-{
- NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
- for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it)
- it->value->invalidateCache(attrName);
-
- NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end();
- for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it)
- it->value->invalidateCache(attrName);
-
- if (attrName)
- return;
-
- TagNodeListCacheNS::iterator tagCacheEnd = m_tagNodeListCacheNS.end();
- for (TagNodeListCacheNS::iterator it = m_tagNodeListCacheNS.begin(); it != tagCacheEnd; ++it)
- it->value->invalidateCache();
-}
-
Node* Node::enclosingLinkEventParentOrSelf()
{
- for (Node* node = this; node; node = node->parentOrShadowHostNode()) {
+ for (Node* node = this; node; node = NodeRenderingTraversal::parent(node)) {
// For imagemaps, the enclosing link node is the associated area element not the image itself.
// So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true
// for them.
- if (node->isLink() && !node->hasTagName(imgTag))
+ if (node->isLink() && !isHTMLImageElement(*node))
return node;
}
@@ -2130,19 +1938,8 @@ void Node::didMoveToNewDocument(Document& oldDocument)
cache->remove(this);
}
- const EventListenerVector& mousewheelListeners = getEventListeners(EventTypeNames::mousewheel);
- WheelController* oldController = WheelController::from(&oldDocument);
- WheelController* newController = WheelController::from(&document());
- for (size_t i = 0; i < mousewheelListeners.size(); ++i) {
- oldController->didRemoveWheelEventHandler(&oldDocument);
- newController->didAddWheelEventHandler(&document());
- }
-
- const EventListenerVector& wheelListeners = getEventListeners(EventTypeNames::wheel);
- for (size_t i = 0; i < wheelListeners.size(); ++i) {
- oldController->didRemoveWheelEventHandler(&oldDocument);
- newController->didAddWheelEventHandler(&document());
- }
+ oldDocument.markers().removeMarkers(this);
+ oldDocument.updateRangesAfterNodeMovedToAnotherDocument(*this);
if (const TouchEventTargetSet* touchHandlers = oldDocument.touchEventTargets()) {
while (touchHandlers->contains(this)) {
@@ -2150,15 +1947,21 @@ void Node::didMoveToNewDocument(Document& oldDocument)
document().didAddTouchEventHandler(this);
}
}
+ if (oldDocument.frameHost() != document().frameHost()) {
+ if (oldDocument.frameHost())
+ oldDocument.frameHost()->eventHandlerRegistry().didMoveOutOfFrameHost(*this);
+ if (document().frameHost())
+ document().frameHost()->eventHandlerRegistry().didMoveIntoFrameHost(*this);
+ }
- if (Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
+ if (WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = mutationObserverRegistry()) {
for (size_t i = 0; i < registry->size(); ++i) {
document().addMutationObserverTypes(registry->at(i)->mutationTypes());
}
}
- if (HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry()) {
- for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
+ if (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = transientMutationObserverRegistry()) {
+ for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter) {
document().addMutationObserverTypes((*iter)->mutationTypes());
}
}
@@ -2171,10 +1974,10 @@ static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eve
Document& document = targetNode->document();
document.addListenerTypeIfNeeded(eventType);
- if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel)
- WheelController::from(&document)->didAddWheelEventHandler(&document);
- else if (isTouchEventType(eventType))
+ if (isTouchEventType(eventType))
document.didAddTouchEventHandler(targetNode);
+ if (document.frameHost())
+ document.frameHost()->eventHandlerRegistry().didAddEventHandler(*targetNode, eventType);
return true;
}
@@ -2192,10 +1995,10 @@ static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString&
// FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
// listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
Document& document = targetNode->document();
- if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel)
- WheelController::from(&document)->didAddWheelEventHandler(&document);
- else if (isTouchEventType(eventType))
+ if (isTouchEventType(eventType))
document.didRemoveTouchEventHandler(targetNode);
+ if (document.frameHost())
+ document.frameHost()->eventHandlerRegistry().didRemoveEventHandler(*targetNode, eventType);
return true;
}
@@ -2205,12 +2008,34 @@ bool Node::removeEventListener(const AtomicString& eventType, EventListener* lis
return tryRemoveEventListener(this, eventType, listener, useCapture);
}
-typedef HashMap<Node*, OwnPtr<EventTargetData> > EventTargetDataMap;
+void Node::removeAllEventListeners()
+{
+ if (hasEventListeners() && document().frameHost())
+ document().frameHost()->eventHandlerRegistry().didRemoveAllEventHandlers(*this);
+ EventTarget::removeAllEventListeners();
+ document().didClearTouchEventHandlers(this);
+}
+
+void Node::removeAllEventListenersRecursively()
+{
+ for (Node* node = this; node; node = NodeTraversal::next(*node)) {
+ node->removeAllEventListeners();
+ for (ShadowRoot* root = node->youngestShadowRoot(); root; root = root->olderShadowRoot())
+ root->removeAllEventListenersRecursively();
+ }
+}
+
+typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Node>, OwnPtr<EventTargetData> > EventTargetDataMap;
static EventTargetDataMap& eventTargetDataMap()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<EventTargetDataMap>, map, (new EventTargetDataMap()));
+ return *map;
+#else
DEFINE_STATIC_LOCAL(EventTargetDataMap, map, ());
return map;
+#endif
}
EventTargetData* Node::eventTargetData()
@@ -2228,12 +2053,14 @@ EventTargetData& Node::ensureEventTargetData()
return *data;
}
+#if !ENABLE(OILPAN)
void Node::clearEventTargetData()
{
eventTargetDataMap().remove(this);
}
+#endif
-Vector<OwnPtr<MutationObserverRegistration> >* Node::mutationObserverRegistry()
+WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* Node::mutationObserverRegistry()
{
if (!hasRareData())
return 0;
@@ -2243,7 +2070,7 @@ Vector<OwnPtr<MutationObserverRegistration> >* Node::mutationObserverRegistry()
return &data->registry;
}
-HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry()
+WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* Node::transientMutationObserverRegistry()
{
if (!hasRareData())
return 0;
@@ -2254,7 +2081,7 @@ HashSet<MutationObserverRegistration*>* Node::transientMutationObserverRegistry(
}
template<typename Registry>
-static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, Registry* registry, Node* target, MutationObserver::MutationType type, const QualifiedName* attributeName)
+static inline void collectMatchingObserversForMutation(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, Registry* registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName)
{
if (!registry)
return;
@@ -2262,30 +2089,30 @@ static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*
const MutationObserverRegistration& registration = **iter;
if (registration.shouldReceiveMutationFrom(target, type, attributeName)) {
MutationRecordDeliveryOptions deliveryOptions = registration.deliveryOptions();
- HashMap<MutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(registration.observer(), deliveryOptions);
+ WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>::AddResult result = observers.add(&registration.observer(), deliveryOptions);
if (!result.isNewEntry)
- result.iterator->value |= deliveryOptions;
+ result.storedValue->value |= deliveryOptions;
}
}
}
-void Node::getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName)
+void Node::getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName)
{
ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
- collectMatchingObserversForMutation(observers, mutationObserverRegistry(), this, type, attributeName);
- collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), this, type, attributeName);
+ collectMatchingObserversForMutation(observers, mutationObserverRegistry(), *this, type, attributeName);
+ collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), *this, type, attributeName);
for (Node* node = parentNode(); node; node = node->parentNode()) {
- collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), this, type, attributeName);
- collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), this, type, attributeName);
+ collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), *this, type, attributeName);
+ collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), *this, type, attributeName);
}
}
-void Node::registerMutationObserver(MutationObserver* observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+void Node::registerMutationObserver(MutationObserver& observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
{
MutationObserverRegistration* registration = 0;
- Vector<OwnPtr<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry;
+ WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry;
for (size_t i = 0; i < registry.size(); ++i) {
- if (registry[i]->observer() == observer) {
+ if (&registry[i]->observer() == &observer) {
registration = registry[i].get();
registration->resetObservation(options, attributeFilter);
}
@@ -2301,7 +2128,7 @@ void Node::registerMutationObserver(MutationObserver* observer, MutationObserver
void Node::unregisterMutationObserver(MutationObserverRegistration* registration)
{
- Vector<OwnPtr<MutationObserverRegistration> >* registry = mutationObserverRegistry();
+ WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = mutationObserverRegistry();
ASSERT(registry);
if (!registry)
return;
@@ -2314,7 +2141,12 @@ void Node::unregisterMutationObserver(MutationObserverRegistration* registration
// Deleting the registration may cause this node to be derefed, so we must make sure the Vector operation completes
// before that, in case |this| is destroyed (see MutationObserverRegistration::m_registrationNodeKeepAlive).
// FIXME: Simplify the registration/transient registration logic to make this understandable by humans.
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
+#if ENABLE(OILPAN)
+ // The explicit dispose() is needed to have the registration
+ // object unregister itself promptly.
+ registration->dispose();
+#endif
registry->remove(index);
}
@@ -2325,7 +2157,7 @@ void Node::registerTransientMutationObserver(MutationObserverRegistration* regis
void Node::unregisterTransientMutationObserver(MutationObserverRegistration* registration)
{
- HashSet<MutationObserverRegistration*>* transientRegistry = transientMutationObserverRegistry();
+ WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = transientMutationObserverRegistry();
ASSERT(transientRegistry);
if (!transientRegistry)
return;
@@ -2340,15 +2172,15 @@ void Node::notifyMutationObserversNodeWillDetach()
return;
for (Node* node = parentNode(); node; node = node->parentNode()) {
- if (Vector<OwnPtr<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) {
+ if (WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) {
const size_t size = registry->size();
for (size_t i = 0; i < size; ++i)
- registry->at(i)->observedSubtreeNodeWillDetach(this);
+ registry->at(i)->observedSubtreeNodeWillDetach(*this);
}
- if (HashSet<MutationObserverRegistration*>* transientRegistry = node->transientMutationObserverRegistry()) {
- for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter)
- (*iter)->observedSubtreeNodeWillDetach(this);
+ if (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientRegistry = node->transientMutationObserverRegistry()) {
+ for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter)
+ (*iter)->observedSubtreeNodeWillDetach(*this);
}
}
}
@@ -2364,17 +2196,17 @@ void Node::handleLocalEvents(Event* event)
fireEventListeners(event);
}
-void Node::dispatchScopedEvent(PassRefPtr<Event> event)
+void Node::dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event> event)
{
dispatchScopedEventDispatchMediator(EventDispatchMediator::create(event));
}
-void Node::dispatchScopedEventDispatchMediator(PassRefPtr<EventDispatchMediator> eventDispatchMediator)
+void Node::dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator> eventDispatchMediator)
{
EventDispatcher::dispatchScopedEvent(this, eventDispatchMediator);
}
-bool Node::dispatchEvent(PassRefPtr<Event> event)
+bool Node::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
if (event->isMouseEvent())
return EventDispatcher::dispatchEvent(this, MouseEventDispatchMediator::create(static_pointer_cast<MouseEvent>(event), MouseEventDispatchMediator::SyntheticMouseEvent));
@@ -2396,10 +2228,10 @@ void Node::dispatchSubtreeModifiedEvent()
dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMSubtreeModified, true));
}
-bool Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent)
+bool Node::dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent)
{
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
- RefPtr<UIEvent> event = UIEvent::create(EventTypeNames::DOMActivate, true, true, document().domWindow(), detail);
+ RefPtrWillBeRawPtr<UIEvent> event = UIEvent::create(EventTypeNames::DOMActivate, true, true, document().domWindow(), detail);
event->setUnderlyingEvent(underlyingEvent);
dispatchScopedEvent(event);
return event->defaultHandled();
@@ -2418,13 +2250,13 @@ bool Node::dispatchMouseEvent(const PlatformMouseEvent& event, const AtomicStrin
bool Node::dispatchGestureEvent(const PlatformGestureEvent& event)
{
- RefPtr<GestureEvent> gestureEvent = GestureEvent::create(document().domWindow(), event);
+ RefPtrWillBeRawPtr<GestureEvent> gestureEvent = GestureEvent::create(document().domWindow(), event);
if (!gestureEvent.get())
return false;
return EventDispatcher::dispatchEvent(this, GestureEventDispatchMediator::create(gestureEvent));
}
-bool Node::dispatchTouchEvent(PassRefPtr<TouchEvent> event)
+bool Node::dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent> event)
{
return EventDispatcher::dispatchEvent(this, TouchEventDispatchMediator::create(event));
}
@@ -2434,27 +2266,11 @@ void Node::dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEve
EventDispatcher::dispatchSimulatedClick(this, underlyingEvent, eventOptions);
}
-bool Node::dispatchBeforeLoadEvent(const String& sourceURL)
-{
- if (!document().hasListenerType(Document::BEFORELOAD_LISTENER))
- return true;
-
- RefPtr<Node> protector(this);
- RefPtr<BeforeLoadEvent> beforeLoadEvent = BeforeLoadEvent::create(sourceURL);
- dispatchEvent(beforeLoadEvent.get());
- return !beforeLoadEvent->defaultPrevented();
-}
-
bool Node::dispatchWheelEvent(const PlatformWheelEvent& event)
{
return EventDispatcher::dispatchEvent(this, WheelEventDispatchMediator::create(event, document().domWindow()));
}
-void Node::dispatchChangeEvent()
-{
- dispatchScopedEvent(Event::createBubble(EventTypeNames::change));
-}
-
void Node::dispatchInputEvent()
{
dispatchScopedEvent(Event::createBubble(EventTypeNames::input));
@@ -2467,7 +2283,7 @@ void Node::defaultEventHandler(Event* event)
const AtomicString& eventType = event->type();
if (eventType == EventTypeNames::keydown || eventType == EventTypeNames::keypress) {
if (event->isKeyboardEvent()) {
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().defaultKeyboardEventHandler(toKeyboardEvent(event));
}
} else if (eventType == EventTypeNames::click) {
@@ -2479,7 +2295,7 @@ void Node::defaultEventHandler(Event* event)
page->contextMenuController().handleContextMenuEvent(event);
} else if (eventType == EventTypeNames::textInput) {
if (event->hasInterface(EventNames::TextEvent)) {
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().defaultTextInputEventHandler(toTextEvent(event));
}
#if OS(WIN)
@@ -2494,7 +2310,7 @@ void Node::defaultEventHandler(Event* event)
renderer = renderer->parent();
if (renderer) {
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().startPanScrolling(renderer);
}
}
@@ -2509,7 +2325,7 @@ void Node::defaultEventHandler(Event* event)
startNode = startNode->parentOrShadowHostNode();
if (startNode && startNode->renderer()) {
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().defaultWheelEventHandler(startNode, wheelEvent);
}
} else if (event->type() == EventTypeNames::webkitEditableContentChanged) {
@@ -2542,6 +2358,7 @@ bool Node::willRespondToTouchEvents()
return hasEventListeners(EventTypeNames::touchstart) || hasEventListeners(EventTypeNames::touchmove) || hasEventListeners(EventTypeNames::touchcancel) || hasEventListeners(EventTypeNames::touchend);
}
+#if !ENABLE(OILPAN)
// This is here for inlining
inline void TreeScope::removedLastRefToScope()
{
@@ -2553,14 +2370,14 @@ inline void TreeScope::removedLastRefToScope()
// extra self-only ref.
guardRef();
dispose();
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
// We need to do this right now since guardDeref() can delete this.
- rootNode()->m_inRemovedLastRefFunction = false;
+ rootNode().m_inRemovedLastRefFunction = false;
#endif
guardDeref();
} else {
-#if !ASSERT_DISABLED
- rootNode()->m_inRemovedLastRefFunction = false;
+#if ASSERT_ENABLED
+ rootNode().m_inRemovedLastRefFunction = false;
#endif
#if SECURITY_ASSERT_ENABLED
beginDeletion();
@@ -2586,6 +2403,7 @@ void Node::removedLastRef()
#endif
delete this;
}
+#endif
unsigned Node::connectedSubframeCount() const
{
@@ -2625,12 +2443,12 @@ void Node::updateAncestorConnectedSubframeCountForInsertion() const
node->incrementConnectedSubframeCount(count);
}
-PassRefPtr<NodeList> Node::getDestinationInsertionPoints()
+PassRefPtrWillBeRawPtr<StaticNodeList> Node::getDestinationInsertionPoints()
{
document().updateDistributionForNodeIfNeeded(this);
- Vector<InsertionPoint*, 8> insertionPoints;
+ WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
collectDestinationInsertionPoints(*this, insertionPoints);
- Vector<RefPtr<Node> > filteredInsertionPoints;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > filteredInsertionPoints;
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* insertionPoint = insertionPoints[i];
ASSERT(insertionPoint->containingShadowRoot());
@@ -2640,28 +2458,6 @@ PassRefPtr<NodeList> Node::getDestinationInsertionPoints()
return StaticNodeList::adopt(filteredInsertionPoints);
}
-void Node::registerScopedHTMLStyleChild()
-{
- setHasScopedHTMLStyleChild(true);
-}
-
-void Node::unregisterScopedHTMLStyleChild()
-{
- ASSERT(hasScopedHTMLStyleChild());
- setHasScopedHTMLStyleChild(numberOfScopedHTMLStyleChildren());
-}
-
-size_t Node::numberOfScopedHTMLStyleChildren() const
-{
- size_t count = 0;
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(HTMLNames::styleTag) && toHTMLStyleElement(child)->isRegisteredAsScoped())
- count++;
- }
-
- return count;
-}
-
void Node::setFocus(bool flag)
{
document().userActionElements().setFocused(this, flag);
@@ -2720,17 +2516,56 @@ void Node::setCustomElementState(CustomElementState newState)
}
ASSERT(isHTMLElement() || isSVGElement());
- setFlag(CustomElement);
- setFlag(newState == Upgraded, CustomElementUpgraded);
+ setFlag(CustomElementFlag);
+ setFlag(newState == Upgraded, CustomElementUpgradedFlag);
if (oldState == NotCustomElement || newState == Upgraded)
- setNeedsStyleRecalc(); // :unresolved has changed
+ setNeedsStyleRecalc(SubtreeStyleChange); // :unresolved has changed
+}
+
+void Node::trace(Visitor* visitor)
+{
+ visitor->trace(m_parentOrShadowHostNode);
+ visitor->trace(m_previous);
+ visitor->trace(m_next);
+ if (hasRareData())
+ visitor->trace(rareData());
+ visitor->trace(m_treeScope);
+ EventTarget::trace(visitor);
+}
+
+unsigned Node::lengthOfContents() const
+{
+ // This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
+ switch (nodeType()) {
+ case Node::TEXT_NODE:
+ case Node::CDATA_SECTION_NODE:
+ case Node::COMMENT_NODE:
+ return toCharacterData(this)->length();
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ return toProcessingInstruction(this)->data().length();
+ case Node::ELEMENT_NODE:
+ case Node::ATTRIBUTE_NODE:
+ case Node::DOCUMENT_NODE:
+ case Node::DOCUMENT_FRAGMENT_NODE:
+ return toContainerNode(this)->countChildren();
+ case Node::DOCUMENT_TYPE_NODE:
+ return 0;
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
}
} // namespace WebCore
#ifndef NDEBUG
+void showNode(const WebCore::Node* node)
+{
+ if (node)
+ node->showNode("");
+}
+
void showTree(const WebCore::Node* node)
{
if (node)
diff --git a/chromium/third_party/WebKit/Source/core/dom/Node.h b/chromium/third_party/WebKit/Source/core/dom/Node.h
index 36235187f71..61858541de3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Node.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Node.h
@@ -36,10 +36,9 @@
#include "core/inspector/InspectorCounters.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "platform/geometry/LayoutRect.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURLHash.h"
#include "wtf/Forward.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/text/AtomicString.h"
// This needs to be here because Document.h also depends on it.
#define DUMP_NODE_STATISTICS 0
@@ -47,28 +46,27 @@
namespace WebCore {
class Attribute;
-class ClassNodeList;
+class ClassCollection;
class ContainerNode;
class DOMSettableTokenList;
class Document;
class Element;
class Event;
-class EventContext;
class EventDispatchMediator;
class EventListener;
class ExceptionState;
class FloatPoint;
-class Frame;
+class LocalFrame;
class HTMLInputElement;
class IntRect;
class KeyboardEvent;
class NSResolver;
class NameNodeList;
class NamedNodeMap;
+class NodeEventContext;
class NodeList;
class NodeListsNodeData;
class NodeRareData;
-class NodeRenderingContext;
class PlatformGestureEvent;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
@@ -81,11 +79,13 @@ class RenderBoxModelObject;
class RenderObject;
class RenderStyle;
class ShadowRoot;
-class TagNodeList;
+class StaticNodeList;
+class TagCollection;
class Text;
class TouchEvent;
+class WeakNodeMap;
-const int nodeStyleChangeShift = 14;
+const int nodeStyleChangeShift = 19;
enum StyleChangeType {
NoStyleChange = 0,
@@ -94,13 +94,6 @@ enum StyleChangeType {
NeedsReattachStyleChange = 3 << nodeStyleChangeShift,
};
-// If the style change is from the renderer then we'll call setStyle on the
-// renderer even if the style computed from CSS is identical.
-enum StyleChangeSource {
- StyleChangeFromCSS,
- StyleChangeFromRenderer
-};
-
class NodeRareDataBase {
public:
RenderObject* renderer() const { return m_renderer; }
@@ -115,34 +108,43 @@ private:
RenderObject* m_renderer;
};
-class Node : public EventTarget, public ScriptWrappable, public TreeShared<Node> {
+#if ENABLE(OILPAN)
+#define NODE_BASE_CLASSES public GarbageCollectedFinalized<Node>, public EventTarget, public ScriptWrappable
+#else
+// TreeShared should be the last to pack TreeShared::m_refCount and
+// Node::m_nodeFlags on 64bit platforms.
+#define NODE_BASE_CLASSES public EventTarget, public ScriptWrappable, public TreeShared<Node>
+#endif
+
+class Node : NODE_BASE_CLASSES {
friend class Document;
friend class TreeScope;
friend class TreeScopeAdopter;
- DEFINE_EVENT_TARGET_REFCOUNTING(TreeShared<Node>);
+ DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(TreeShared<Node>);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Node);
public:
enum NodeType {
ELEMENT_NODE = 1,
ATTRIBUTE_NODE = 2,
TEXT_NODE = 3,
CDATA_SECTION_NODE = 4,
- ENTITY_NODE = 6,
PROCESSING_INSTRUCTION_NODE = 7,
COMMENT_NODE = 8,
DOCUMENT_NODE = 9,
DOCUMENT_TYPE_NODE = 10,
DOCUMENT_FRAGMENT_NODE = 11,
- NOTATION_NODE = 12,
- XPATH_NAMESPACE_NODE = 13,
};
- // EntityReference nodes are deprecated and impossible to create in WebKit.
- // We want Node.ENTITY_REFERNCE_NODE to exist in JS and this enum, makes the bindings
+ // Entity, EntityReference, Notation, and XPathNamespace nodes are impossible to create in Blink.
+ // But for compatibility reasons we want these enum values exist in JS, and this enum makes the bindings
// generation not complain about ENTITY_REFERENCE_NODE being missing from the implementation
// while not requiring all switch(NodeType) blocks to include this deprecated constant.
enum DeprecatedNodeType {
- ENTITY_REFERENCE_NODE = 5
+ ENTITY_REFERENCE_NODE = 5,
+ ENTITY_NODE = 6,
+ NOTATION_NODE = 12,
+ XPATH_NAMESPACE_NODE = 13,
};
enum DocumentPosition {
@@ -155,12 +157,13 @@ public:
DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20,
};
+#if !ENABLE(OILPAN)
// All Nodes are placed in their own heap partition for security.
// See http://crbug.com/246860 for detail.
void* operator new(size_t);
void operator delete(void*);
+#endif
- static bool isSupported(const String& feature, const String& version);
static void dumpStatistics();
virtual ~Node();
@@ -174,15 +177,14 @@ public:
virtual NodeType nodeType() const = 0;
ContainerNode* parentNode() const;
Element* parentElement() const;
+ ContainerNode* parentElementOrShadowRoot() const;
+ ContainerNode* parentElementOrDocumentFragment() const;
Node* previousSibling() const { return m_previous; }
Node* nextSibling() const { return m_next; }
- PassRefPtr<NodeList> childNodes();
+ PassRefPtrWillBeRawPtr<NodeList> childNodes();
Node* firstChild() const;
Node* lastChild() const;
- // ChildNode interface API
- Element* previousElementSibling() const;
- Element* nextElementSibling() const;
void remove(ExceptionState&);
Node* pseudoAwareNextSibling() const;
@@ -194,17 +196,15 @@ public:
// These should all actually return a node, but this is only important for language bindings,
// which will already know and hold a ref on the right node to return.
- void insertBefore(PassRefPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
- void replaceChild(PassRefPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void insertBefore(PassRefPtrWillBeRawPtr<Node> newChild, Node* refChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void replaceChild(PassRefPtrWillBeRawPtr<Node> newChild, Node* oldChild, ExceptionState& = ASSERT_NO_EXCEPTION);
void removeChild(Node* child, ExceptionState&);
- void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void appendChild(PassRefPtrWillBeRawPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
- bool hasChildNodes() const { return firstChild(); }
- virtual PassRefPtr<Node> cloneNode(bool deep = false) = 0;
+ bool hasChildren() const { return firstChild(); }
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = false) = 0;
virtual const AtomicString& localName() const;
virtual const AtomicString& namespaceURI() const;
- virtual const AtomicString& prefix() const;
- virtual void setPrefix(const AtomicString&, ExceptionState&);
void normalize();
bool isSameNode(Node* other) const { return this == other; }
@@ -212,12 +212,11 @@ public:
bool isDefaultNamespace(const AtomicString& namespaceURI) const;
const AtomicString& lookupPrefix(const AtomicString& namespaceURI) const;
const AtomicString& lookupNamespaceURI(const String& prefix) const;
- const AtomicString& lookupNamespacePrefix(const AtomicString& namespaceURI, const Element* originalElement) const;
String textContent(bool convertBRsToNewlines = false) const;
void setTextContent(const String&);
- Node& lastDescendant() const;
+ Node& lastDescendantOrSelf() const;
// Other methods (not part of DOM)
@@ -232,7 +231,7 @@ public:
bool isAfterPseudoElement() const { return pseudoId() == AFTER; }
PseudoId pseudoId() const { return (isElementNode() && hasCustomStyleCallbacks()) ? customPseudoId() : NOPSEUDO; }
- bool isCustomElement() const { return getFlag(CustomElement); }
+ bool isCustomElement() const { return getFlag(CustomElementFlag); }
enum CustomElementState {
NotCustomElement = 0,
WaitingForUpgrade = 1 << 0,
@@ -241,7 +240,7 @@ public:
CustomElementState customElementState() const
{
return isCustomElement()
- ? (getFlag(CustomElementUpgraded) ? Upgraded : WaitingForUpgrade)
+ ? (getFlag(CustomElementUpgradedFlag) ? Upgraded : WaitingForUpgrade)
: NotCustomElement;
}
void setCustomElementState(CustomElementState newState);
@@ -252,7 +251,6 @@ public:
virtual bool isAttributeNode() const { return false; }
virtual bool isCharacterDataNode() const { return false; }
virtual bool isFrameOwnerElement() const { return false; }
- virtual bool isPluginElement() const { return false; }
// StyledElements allow inline style (style="border: 1px"), presentational attributes (ex. color),
// class names (ex. class="foo bar") and other non-basic styling features. They and also control
@@ -265,16 +263,13 @@ public:
bool isStyledElement() const { return isHTMLElement() || isSVGElement(); }
bool isDocumentNode() const;
- bool isTreeScope() const { return treeScope().rootNode() == this; }
+ bool isTreeScope() const { return &treeScope().rootNode() == this; }
bool isDocumentFragment() const { return getFlag(IsDocumentFragmentFlag); }
bool isShadowRoot() const { return isDocumentFragment() && isTreeScope(); }
bool isInsertionPoint() const { return getFlag(IsInsertionPointFlag); }
- bool inNamedFlow() const { return getFlag(InNamedFlowFlag); }
bool hasCustomStyleCallbacks() const { return getFlag(HasCustomStyleCallbacksFlag); }
- bool isRegisteredWithNamedFlow() const;
-
bool hasSyntheticAttrChildNodes() const { return getFlag(HasSyntheticAttrChildNodesFlag); }
void setHasSyntheticAttrChildNodes(bool flag) { setFlag(flag, HasSyntheticAttrChildNodesFlag); }
@@ -293,7 +288,7 @@ public:
ContainerNode* parentOrShadowHostNode() const;
Element* parentOrShadowHostElement() const;
void setParentOrShadowHostNode(ContainerNode*);
- Node* highestAncestor() const;
+ Node& highestAncestorOrSelf() const;
// Knows about all kinds of hosts.
ContainerNode* parentOrShadowHostOrTemplateHostNode() const;
@@ -340,15 +335,6 @@ public:
bool inSameContainingBlockFlowElement(Node*);
- // Called by the parser when this element's close tag is reached,
- // signaling that all child tags have been parsed and added.
- // This is needed for <applet> and <object> elements, which can't lay themselves out
- // until they know all of their nested <param>s. [Radar 3603191, 4040848].
- // Also used for script elements and some SVG elements for similar purposes,
- // but making parsing a special case in this respect should be avoided if possible.
- virtual void finishParsingChildren() { }
- virtual void beginParsingChildren() { }
-
// For <link> and <style> elements.
virtual bool sheetLoaded() { return true; }
virtual void notifyLoadedSheetAndAllCriticalSubresources(bool /* error loading subresource */) { }
@@ -358,8 +344,8 @@ public:
bool hasID() const;
bool hasClass() const;
- bool isUserActionElement() const { return getFlag(IsUserActionElement); }
- void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElement); }
+ bool isUserActionElement() const { return getFlag(IsUserActionElementFlag); }
+ void setUserActionElement(bool flag) { setFlag(flag, IsUserActionElementFlag); }
bool active() const { return isUserActionElement() && isUserActionElementActive(); }
bool inActiveChain() const { return isUserActionElement() && isUserActionElementInActiveChain(); }
@@ -377,31 +363,36 @@ public:
void setChildNeedsStyleRecalc() { setFlag(ChildNeedsStyleRecalcFlag); }
void clearChildNeedsStyleRecalc() { clearFlag(ChildNeedsStyleRecalcFlag); }
- void setNeedsStyleRecalc(StyleChangeType = SubtreeStyleChange, StyleChangeSource = StyleChangeFromCSS);
+ void setNeedsStyleRecalc(StyleChangeType);
void clearNeedsStyleRecalc();
- bool childNeedsDistributionRecalc() const { return getFlag(ChildNeedsDistributionRecalc); }
- void setChildNeedsDistributionRecalc() { setFlag(ChildNeedsDistributionRecalc); }
- void clearChildNeedsDistributionRecalc() { clearFlag(ChildNeedsDistributionRecalc); }
+ bool childNeedsDistributionRecalc() const { return getFlag(ChildNeedsDistributionRecalcFlag); }
+ void setChildNeedsDistributionRecalc() { setFlag(ChildNeedsDistributionRecalcFlag); }
+ void clearChildNeedsDistributionRecalc() { clearFlag(ChildNeedsDistributionRecalcFlag); }
void markAncestorsWithChildNeedsDistributionRecalc();
+ bool childNeedsStyleInvalidation() const { return getFlag(ChildNeedsStyleInvalidationFlag); }
+ void setChildNeedsStyleInvalidation() { setFlag(ChildNeedsStyleInvalidationFlag); }
+ void clearChildNeedsStyleInvalidation() { clearFlag(ChildNeedsStyleInvalidationFlag); }
+ void markAncestorsWithChildNeedsStyleInvalidation();
+ bool needsStyleInvalidation() const { return getFlag(NeedsStyleInvalidationFlag); }
+ void clearNeedsStyleInvalidation() { clearFlag(NeedsStyleInvalidationFlag); }
+ void setNeedsStyleInvalidation();
+
void recalcDistribution();
- bool shouldNotifyRendererWithIdenticalStyles() const { return getFlag(NotifyRendererWithIdenticalStyles); }
+ bool svgFilterNeedsLayerUpdate() const { return getFlag(SVGFilterNeedsLayerUpdateFlag); }
+ void setSVGFilterNeedsLayerUpdate() { setFlag(SVGFilterNeedsLayerUpdateFlag); }
+ void clearSVGFilterNeedsLayerUpdate() { clearFlag(SVGFilterNeedsLayerUpdateFlag); }
void setIsLink(bool f);
- void setInNamedFlow() { setFlag(InNamedFlowFlag); }
- void clearInNamedFlow() { clearFlag(InNamedFlowFlag); }
-
- bool hasScopedHTMLStyleChild() const { return getFlag(HasScopedHTMLStyleChildFlag); }
- void setHasScopedHTMLStyleChild(bool flag) { setFlag(flag, HasScopedHTMLStyleChildFlag); }
-
bool hasEventTargetData() const { return getFlag(HasEventTargetDataFlag); }
void setHasEventTargetData(bool flag) { setFlag(flag, HasEventTargetDataFlag); }
bool isV8CollectableDuringMinorGC() const { return getFlag(V8CollectableDuringMinorGCFlag); }
- void setV8CollectableDuringMinorGC(bool flag) { setFlag(flag, V8CollectableDuringMinorGCFlag); }
+ void markV8CollectableDuringMinorGC() { setFlag(true, V8CollectableDuringMinorGCFlag); }
+ void clearV8CollectableDuringMinorGC() { setFlag(false, V8CollectableDuringMinorGCFlag); }
virtual void setFocus(bool flag);
virtual void setActive(bool flag = true);
@@ -466,9 +457,7 @@ public:
// Returns the document associated with this node. A Document node returns itself.
Document& document() const
{
- ASSERT(this);
- ASSERT(documentInternal());
- return *documentInternal();
+ return treeScope().document();
}
TreeScope& treeScope() const
@@ -483,7 +472,6 @@ public:
// node tree, false otherwise.
bool inDocument() const
{
- ASSERT(documentInternal() || !getFlag(InDocumentFlag));
return getFlag(InDocumentFlag);
}
bool isInShadowTree() const { return getFlag(IsInShadowTreeFlag); }
@@ -491,19 +479,15 @@ public:
bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; }
virtual bool childTypeAllowed(NodeType) const { return false; }
- unsigned childNodeCount() const;
- Node* childNode(unsigned index) const;
+ unsigned countChildren() const;
+ Node* traverseToChildAt(unsigned index) const;
- void checkSetPrefix(const AtomicString& prefix, ExceptionState&);
bool isDescendantOf(const Node*) const;
bool contains(const Node*) const;
bool containsIncludingShadowDOM(const Node*) const;
bool containsIncludingHostElements(const Node&) const;
Node* commonAncestor(const Node&, Node* (*parent)(const Node&));
- // FIXME: Remove this when crbug.com/265716 cleans up contains semantics.
- bool bindingsContains(const Node* node) const { return containsIncludingShadowDOM(node); }
-
// Used to determine whether range offsets use characters or node indices.
virtual bool offsetInCharacters() const;
// Number of DOM 16-bit units contained in node. Note that rendered text length can be different - e.g. because of
@@ -530,7 +514,6 @@ public:
else
m_data.m_renderer = renderer;
}
- bool hasRenderer() const { return renderer(); }
// Use these two methods with caution.
RenderBox* renderBox() const;
@@ -559,6 +542,9 @@ public:
void reattach(const AttachContext& = AttachContext());
void lazyReattachIfAttached();
+ // Returns true if recalcStyle should be called on the object, if there is such a method (on Document and Element).
+ bool shouldCallRecalcStyle(StyleRecalcChange);
+
// Wrapper for nodes that don't have a renderer, but still cache the style (like HTMLOptionElement).
RenderStyle* renderStyle() const;
RenderStyle* parentRenderStyle() const;
@@ -579,7 +565,7 @@ public:
//
// There are another callback named didNotifySubtreeInsertionsToDocument(), which is called after all the descendant is notified,
// if this node was inserted into the document tree. Only a few subclasses actually need this. To utilize this, the node should
- // return InsertionShouldCallDidNotifySubtreeInsertions from insrtedInto().
+ // return InsertionShouldCallDidNotifySubtreeInsertions from insertedInto().
//
enum InsertionNotificationRequest {
InsertionDone,
@@ -612,19 +598,10 @@ public:
NodeListsNodeData* nodeLists();
void clearNodeLists();
- PassRefPtr<NodeList> getElementsByTagName(const AtomicString&);
- PassRefPtr<NodeList> getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName);
- PassRefPtr<NodeList> getElementsByName(const String& elementName);
- PassRefPtr<NodeList> getElementsByClassName(const String& classNames);
- PassRefPtr<RadioNodeList> radioNodeList(const AtomicString&);
-
virtual bool willRespondToMouseMoveEvents();
virtual bool willRespondToMouseClickEvents();
virtual bool willRespondToTouchEvents();
- PassRefPtr<Element> querySelector(const AtomicString& selectors, ExceptionState&);
- PassRefPtr<NodeList> querySelectorAll(const AtomicString& selectors, ExceptionState&);
-
unsigned short compareDocumentPosition(const Node*) const;
enum ShadowTreesTreatment {
@@ -634,13 +611,15 @@ public:
unsigned short compareDocumentPositionInternal(const Node*, ShadowTreesTreatment) const;
- virtual Node* toNode();
+ virtual Node* toNode() OVERRIDE FINAL;
virtual const AtomicString& interfaceName() const OVERRIDE;
- virtual ExecutionContext* executionContext() const OVERRIDE;
+ virtual ExecutionContext* executionContext() const OVERRIDE FINAL;
- virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE;
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture = false) OVERRIDE;
+ virtual void removeAllEventListeners() OVERRIDE;
+ void removeAllEventListenersRecursively();
// Handlers to do/undo actions on the target node before an event is dispatched to it and after the event
// has been dispatched. The data pointer is handed back by the preDispatch and passed to postDispatch.
@@ -648,27 +627,25 @@ public:
virtual void postDispatchEventHandler(Event*, void* /*dataFromPreDispatch*/) { }
using EventTarget::dispatchEvent;
- virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
+ virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
- void dispatchScopedEvent(PassRefPtr<Event>);
- void dispatchScopedEventDispatchMediator(PassRefPtr<EventDispatchMediator>);
+ void dispatchScopedEvent(PassRefPtrWillBeRawPtr<Event>);
+ void dispatchScopedEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator>);
virtual void handleLocalEvents(Event*);
void dispatchSubtreeModifiedEvent();
- bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
+ bool dispatchDOMActivateEvent(int detail, PassRefPtrWillBeRawPtr<Event> underlyingEvent);
bool dispatchKeyEvent(const PlatformKeyboardEvent&);
bool dispatchWheelEvent(const PlatformWheelEvent&);
bool dispatchMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType, int clickCount = 0, Node* relatedTarget = 0);
bool dispatchGestureEvent(const PlatformGestureEvent&);
- bool dispatchTouchEvent(PassRefPtr<TouchEvent>);
+ bool dispatchTouchEvent(PassRefPtrWillBeRawPtr<TouchEvent>);
void dispatchSimulatedClick(Event* underlyingEvent, SimulatedClickMouseEventOptions = SendNoEvents);
- virtual bool dispatchBeforeLoadEvent(const String& sourceURL);
- virtual void dispatchChangeEvent();
- virtual void dispatchInputEvent();
+ void dispatchInputEvent();
// Perform the default action for an event.
virtual void defaultEventHandler(Event*);
@@ -677,80 +654,89 @@ public:
virtual EventTargetData* eventTargetData() OVERRIDE;
virtual EventTargetData& ensureEventTargetData() OVERRIDE;
- void getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
- void registerMutationObserver(MutationObserver*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+ void getRegisteredMutationObserversOfType(WillBeHeapHashMap<RawPtrWillBeMember<MutationObserver>, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
+ void registerMutationObserver(MutationObserver&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
void unregisterMutationObserver(MutationObserverRegistration*);
void registerTransientMutationObserver(MutationObserverRegistration*);
void unregisterTransientMutationObserver(MutationObserverRegistration*);
void notifyMutationObserversNodeWillDetach();
- virtual void registerScopedHTMLStyleChild();
- virtual void unregisterScopedHTMLStyleChild();
- size_t numberOfScopedHTMLStyleChildren() const;
-
unsigned connectedSubframeCount() const;
void incrementConnectedSubframeCount(unsigned amount = 1);
void decrementConnectedSubframeCount(unsigned amount = 1);
void updateAncestorConnectedSubframeCountForRemoval() const;
void updateAncestorConnectedSubframeCountForInsertion() const;
- PassRefPtr<NodeList> getDestinationInsertionPoints();
+ PassRefPtrWillBeRawPtr<StaticNodeList> getDestinationInsertionPoints();
void setAlreadySpellChecked(bool flag) { setFlag(flag, AlreadySpellCheckedFlag); }
bool isAlreadySpellChecked() { return getFlag(AlreadySpellCheckedFlag); }
+ bool isFinishedParsingChildren() const { return getFlag(IsFinishedParsingChildrenFlag); }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ unsigned lengthOfContents() const;
+
private:
enum NodeFlags {
- IsTextFlag = 1,
- IsContainerFlag = 1 << 1,
- IsElementFlag = 1 << 2,
- IsHTMLFlag = 1 << 3,
- IsSVGFlag = 1 << 4,
-
- ChildNeedsDistributionRecalc = 1 << 5,
- ChildNeedsStyleRecalcFlag = 1 << 6,
- InDocumentFlag = 1 << 7,
+ HasRareDataFlag = 1,
+
+ // Node type flags. These never change once created.
+ IsTextFlag = 1 << 1,
+ IsContainerFlag = 1 << 2,
+ IsElementFlag = 1 << 3,
+ IsHTMLFlag = 1 << 4,
+ IsSVGFlag = 1 << 5,
+ IsDocumentFragmentFlag = 1 << 6,
+ IsInsertionPointFlag = 1 << 7,
+
+ // Changes based on if the element should be treated like a link,
+ // ex. When setting the href attribute on an <a>.
IsLinkFlag = 1 << 8,
- IsUserActionElement = 1 << 9,
- HasRareDataFlag = 1 << 10,
- IsDocumentFragmentFlag = 1 << 11,
-
- // These bits are used by derived classes, pulled up here so they can
- // be stored in the same memory word as the Node bits above.
- IsParsingChildrenFinishedFlag = 1 << 12, // Element
- HasSVGRareDataFlag = 1 << 13, // SVGElement
- StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
+ // Changes based on :hover, :active and :focus state.
+ IsUserActionElementFlag = 1 << 9,
- SelfOrAncestorHasDirAutoFlag = 1 << 16,
+ // Tree state flags. These change when the element is added/removed
+ // from a DOM tree.
+ InDocumentFlag = 1 << 10,
+ IsInShadowTreeFlag = 1 << 11,
- HasNameOrIsEditingTextFlag = 1 << 17,
+ // Set by the parser when the children are done parsing.
+ IsFinishedParsingChildrenFlag = 1 << 12,
- InNamedFlowFlag = 1 << 18,
- HasSyntheticAttrChildNodesFlag = 1 << 19,
- HasCustomStyleCallbacksFlag = 1 << 20,
- HasScopedHTMLStyleChildFlag = 1 << 21,
- HasEventTargetDataFlag = 1 << 22,
- V8CollectableDuringMinorGCFlag = 1 << 23,
- IsInsertionPointFlag = 1 << 24,
- IsInShadowTreeFlag = 1 << 25,
+ // Flags related to recalcStyle.
+ SVGFilterNeedsLayerUpdateFlag = 1 << 13,
+ HasCustomStyleCallbacksFlag = 1 << 14,
+ ChildNeedsStyleInvalidationFlag = 1 << 15,
+ NeedsStyleInvalidationFlag = 1 << 16,
+ ChildNeedsDistributionRecalcFlag = 1 << 17,
+ ChildNeedsStyleRecalcFlag = 1 << 18,
+ StyleChangeMask = 1 << nodeStyleChangeShift | 1 << (nodeStyleChangeShift + 1),
- NotifyRendererWithIdenticalStyles = 1 << 26,
+ CustomElementFlag = 1 << 21,
+ CustomElementUpgradedFlag = 1 << 22,
- CustomElement = 1 << 27,
- CustomElementUpgraded = 1 << 28,
+ HasNameOrIsEditingTextFlag = 1 << 23,
+ HasWeakReferencesFlag = 1 << 24,
+ V8CollectableDuringMinorGCFlag = 1 << 25,
+ HasSyntheticAttrChildNodesFlag = 1 << 26,
+ HasEventTargetDataFlag = 1 << 27,
+ AlreadySpellCheckedFlag = 1 << 28,
- AlreadySpellCheckedFlag = 1 << 29,
+ // HTML dir=auto.
+ SelfOrAncestorHasDirAutoFlag = 1 << 29,
- DefaultNodeFlags = IsParsingChildrenFinishedFlag | ChildNeedsStyleRecalcFlag | NeedsReattachStyleChange
+ DefaultNodeFlags = IsFinishedParsingChildrenFlag | ChildNeedsStyleRecalcFlag | NeedsReattachStyleChange
};
- // 3 bits remaining.
+ // 2 bits remaining.
bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; }
- void setFlag(bool f, NodeFlags mask) const { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
- void setFlag(NodeFlags mask) const { m_nodeFlags |= mask; }
- void clearFlag(NodeFlags mask) const { m_nodeFlags &= ~mask; }
+ void setFlag(bool f, NodeFlags mask) { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); }
+ void setFlag(NodeFlags mask) { m_nodeFlags |= mask; }
+ void clearFlag(NodeFlags mask) { m_nodeFlags &= ~mask; }
protected:
enum ConstructionType {
@@ -767,43 +753,28 @@ protected:
CreateEditingText = CreateText | HasNameOrIsEditingTextFlag,
};
- Node(TreeScope* treeScope, ConstructionType type)
- : m_nodeFlags(type)
- , m_parentOrShadowHostNode(0)
- , m_treeScope(treeScope)
- , m_previous(0)
- , m_next(0)
- {
- ASSERT(m_treeScope || type == CreateDocument || type == CreateShadowRoot);
- ScriptWrappable::init(this);
- if (m_treeScope)
- m_treeScope->guardRef();
-
-#if !defined(NDEBUG) || (defined(DUMP_NODE_STATISTICS) && DUMP_NODE_STATISTICS)
- trackForDebugging();
-#endif
- InspectorCounters::incrementCounter(InspectorCounters::NodeCounter);
- }
+ Node(TreeScope*, ConstructionType);
virtual void didMoveToNewDocument(Document& oldDocument);
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const { }
-
static void reattachWhitespaceSiblings(Text* start);
+#if !ENABLE(OILPAN)
void willBeDeletedFromDocument();
+#endif
bool hasRareData() const { return getFlag(HasRareDataFlag); }
NodeRareData* rareData() const;
NodeRareData& ensureRareData();
+#if !ENABLE(OILPAN)
void clearRareData();
void clearEventTargetData();
+#endif
void setHasCustomStyleCallbacks() { setFlag(true, HasCustomStyleCallbacksFlag); }
- Document* documentInternal() const { return treeScope().documentScope(); }
void setTreeScope(TreeScope* scope) { m_treeScope = scope; }
// isTreeScopeInitialized() can be false
@@ -813,8 +784,11 @@ protected:
void markAncestorsWithChildNeedsStyleRecalc();
+ void setIsFinishedParsingChildren(bool value) { setFlag(value, IsFinishedParsingChildrenFlag); }
+
private:
friend class TreeShared<Node>;
+ friend class WeakNodeMap;
virtual PseudoId customPseudoId() const
{
@@ -822,7 +796,11 @@ private:
return NOPSEUDO;
}
+ unsigned styledSubtreeSize() const;
+
+#if !ENABLE(OILPAN)
void removedLastRef();
+#endif
bool hasTreeSharedParent() const { return !!parentOrShadowHostNode(); }
enum EditableLevel { Editable, RichlyEditable };
@@ -842,42 +820,24 @@ private:
virtual RenderStyle* virtualComputedStyle(PseudoId = NOPSEUDO);
- Element* ancestorElement() const;
-
void trackForDebugging();
- Vector<OwnPtr<MutationObserverRegistration> >* mutationObserverRegistry();
- HashSet<MutationObserverRegistration*>* transientMutationObserverRegistry();
+ WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> >* mutationObserverRegistry();
+ WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >* transientMutationObserverRegistry();
- mutable uint32_t m_nodeFlags;
- ContainerNode* m_parentOrShadowHostNode;
- TreeScope* m_treeScope;
- Node* m_previous;
- Node* m_next;
+ uint32_t m_nodeFlags;
+ RawPtrWillBeMember<ContainerNode> m_parentOrShadowHostNode;
+ RawPtrWillBeMember<TreeScope> m_treeScope;
+ RawPtrWillBeMember<Node> m_previous;
+ RawPtrWillBeMember<Node> m_next;
// When a node has rare data we move the renderer into the rare data.
union DataUnion {
DataUnion() : m_renderer(0) { }
RenderObject* m_renderer;
NodeRareDataBase* m_rareData;
} m_data;
-
-protected:
- bool isParsingChildrenFinished() const { return getFlag(IsParsingChildrenFinishedFlag); }
- void setIsParsingChildrenFinished() { setFlag(IsParsingChildrenFinishedFlag); }
- void clearIsParsingChildrenFinished() { clearFlag(IsParsingChildrenFinishedFlag); }
-
- bool hasSVGRareData() const { return getFlag(HasSVGRareDataFlag); }
- void setHasSVGRareData() { setFlag(HasSVGRareDataFlag); }
- void clearHasSVGRareData() { clearFlag(HasSVGRareDataFlag); }
};
-// Used in Node::addSubresourceAttributeURLs() and in addSubresourceStyleURLs()
-inline void addSubresourceURL(ListHashSet<KURL>& urls, const KURL& url)
-{
- if (!url.isNull())
- urls.add(url);
-}
-
inline void Node::setParentOrShadowHostNode(ContainerNode* parent)
{
ASSERT(isMainThread());
@@ -909,9 +869,9 @@ inline void Node::lazyReattachIfAttached()
markAncestorsWithChildNeedsStyleRecalc();
}
-inline bool shouldRecalcStyle(StyleRecalcChange change, const Node* node)
+inline bool Node::shouldCallRecalcStyle(StyleRecalcChange change)
{
- return change >= Inherit || node->childNeedsStyleRecalc() || node->needsStyleRecalc();
+ return change >= Inherit || needsStyleRecalc() || childNeedsStyleRecalc();
}
inline bool isTreeScopeRoot(const Node* node)
@@ -925,16 +885,7 @@ inline bool isTreeScopeRoot(const Node& node)
}
// Allow equality comparisons of Nodes by reference or pointer, interchangeably.
-inline bool operator==(const Node& a, const Node& b) { return &a == &b; }
-inline bool operator==(const Node& a, const Node* b) { return &a == b; }
-inline bool operator==(const Node* a, const Node& b) { return a == &b; }
-inline bool operator!=(const Node& a, const Node& b) { return !(a == b); }
-inline bool operator!=(const Node& a, const Node* b) { return !(a == b); }
-inline bool operator!=(const Node* a, const Node& b) { return !(a == b); }
-inline bool operator==(const PassRefPtr<Node>& a, const Node& b) { return a.get() == &b; }
-inline bool operator==(const Node& a, const PassRefPtr<Node>& b) { return &a == b.get(); }
-inline bool operator!=(const PassRefPtr<Node>& a, const Node& b) { return !(a == b); }
-inline bool operator!=(const Node& a, const PassRefPtr<Node>& b) { return !(a == b); }
+DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES_REFCOUNTED(Node)
#define DEFINE_NODE_TYPE_CASTS(thisType, predicate) \
@@ -946,10 +897,19 @@ inline bool operator!=(const Node& a, const PassRefPtr<Node>& b) { return !(a ==
template<typename T> inline thisType* to##thisType(const RefPtr<T>& node) { return to##thisType(node.get()); } \
DEFINE_TYPE_CASTS(thisType, Node, node, is##thisType(*node), is##thisType(node))
+#define DECLARE_NODE_FACTORY(T) \
+ static PassRefPtrWillBeRawPtr<T> create(Document&)
+#define DEFINE_NODE_FACTORY(T) \
+PassRefPtrWillBeRawPtr<T> T::create(Document& document) \
+{ \
+ return adoptRefWillBeNoop(new T(document)); \
+}
+
} // namespace WebCore
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
+void showNode(const WebCore::Node*);
void showTree(const WebCore::Node*);
void showNodePath(const WebCore::Node*);
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Node.idl b/chromium/third_party/WebKit/Source/core/dom/Node.idl
index c67bbebddf5..4536b1f0e07 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Node.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Node.idl
@@ -36,11 +36,11 @@
const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
const unsigned short NOTATION_NODE = 12;
- [PerWorldBindings] readonly attribute DOMString nodeName;
+ readonly attribute DOMString nodeName;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, CustomElementCallbacks] attribute DOMString nodeValue;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString nodeValue;
- [PerWorldBindings] readonly attribute unsigned short nodeType;
+ readonly attribute unsigned short nodeType;
[PerWorldBindings] readonly attribute Node parentNode;
[PerWorldBindings] readonly attribute NodeList childNodes;
[PerWorldBindings] readonly attribute Node firstChild;
@@ -49,28 +49,23 @@
[PerWorldBindings] readonly attribute Node nextSibling;
[PerWorldBindings] readonly attribute Document ownerDocument;
- [Custom, CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node insertBefore(Node newChild, Node refChild);
- [Custom, CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node replaceChild(Node newChild, Node oldChild);
- [Custom, CustomElementCallbacks, PerWorldBindings, RaisesException] Node removeChild(Node oldChild);
- [Custom, CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node appendChild(Node newChild);
+ [Custom, CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Node insertBefore(Node newChild, Node refChild);
+ [Custom, CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Node replaceChild(Node newChild, Node oldChild);
+ [Custom, CustomElementCallbacks, RaisesException] Node removeChild(Node oldChild);
+ [Custom, CustomElementCallbacks, PerWorldBindings, LogActivity, RaisesException] Node appendChild(Node newChild);
- boolean hasChildNodes();
- [CustomElementCallbacks, PerWorldBindings]
- Node cloneNode(optional boolean deep);
+ [ImplementedAs=hasChildren] boolean hasChildNodes();
+ [CustomElementCallbacks] Node cloneNode(optional boolean deep);
[CustomElementCallbacks] void normalize();
// Introduced in DOM Level 2:
- [MeasureAs=NodeIsSupported] boolean isSupported([Default=Undefined] optional DOMString feature,
- [TreatNullAs=NullString,Default=Undefined] optional DOMString version); // Removed in DOM4.
-
- [TreatReturnedNullStringAs=Null, PerWorldBindings, MeasureAs=NodeNamespaceURI] readonly attribute DOMString namespaceURI; // Moved to Element and Attr in DOM4.
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, RaisesException=Setter, MeasureAs=NodePrefix] attribute DOMString prefix; // Moved to Element and Attr in DOM4.
- [TreatReturnedNullStringAs=Null, PerWorldBindings, MeasureAs=NodeLocalName] readonly attribute DOMString localName; // Moved to Element and Attr in DOM4.
+ [TreatReturnedNullStringAs=Null, MeasureAs=NodeNamespaceURI] readonly attribute DOMString namespaceURI; // Moved to Element and Attr in DOM4.
+ [TreatReturnedNullStringAs=Null, MeasureAs=NodeLocalName] readonly attribute DOMString localName; // Moved to Element and Attr in DOM4.
// Introduced in DOM Level 3:
- [TreatReturnedNullStringAs=Null, PerWorldBindings] readonly attribute DOMString baseURI;
+ [TreatReturnedNullStringAs=Null] readonly attribute DOMString baseURI;
- [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, PerWorldBindings, CustomElementCallbacks] attribute DOMString textContent;
+ [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, TreatUndefinedAs=NullString, CustomElementCallbacks] attribute DOMString textContent;
[MeasureAs=NodeIsSameNode] boolean isSameNode([Default=Undefined] optional Node other); // Removed in DOM4.
boolean isEqualNode(Node other);
@@ -89,7 +84,7 @@
unsigned short compareDocumentPosition(Node other);
// Introduced in DOM4
- [ImplementedAs=bindingsContains] boolean contains(Node other);
+ boolean contains(Node other);
// IE extensions
[PerWorldBindings] readonly attribute Element parentElement;
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp
index 6fedc7a0f1e..f207378e1c7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.cpp
@@ -27,10 +27,15 @@
namespace WebCore {
-short NodeFilter::acceptNode(ScriptState* state, Node* node) const
+short NodeFilter::acceptNode(Node* node, ExceptionState& exceptionState) const
{
// cast to short silences "enumeral and non-enumeral types in return" warning
- return m_condition ? m_condition->acceptNode(state, node) : static_cast<short>(FILTER_ACCEPT);
+ return m_condition ? m_condition->acceptNode(node, exceptionState) : static_cast<short>(FILTER_ACCEPT);
+}
+
+void NodeFilter::trace(Visitor* visitor)
+{
+ visitor->trace(m_condition);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.h b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.h
index a811a1325bd..a52520e3806 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.h
@@ -27,11 +27,12 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/NodeFilterCondition.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
-class NodeFilter : public RefCounted<NodeFilter>, public ScriptWrappable {
+class NodeFilter FINAL : public RefCountedWillBeGarbageCollectedFinalized<NodeFilter>, public ScriptWrappable {
public:
/**
* The following constants are returned by the acceptNode()
@@ -65,25 +66,27 @@ public:
SHOW_NOTATION = 0x00000800
};
- static PassRefPtr<NodeFilter> create(PassRefPtr<NodeFilterCondition> condition)
+ static PassRefPtrWillBeRawPtr<NodeFilter> create(PassRefPtrWillBeRawPtr<NodeFilterCondition> condition)
{
- return adoptRef(new NodeFilter(condition));
+ return adoptRefWillBeNoop(new NodeFilter(condition));
}
- static PassRefPtr<NodeFilter> create()
+ static PassRefPtrWillBeRawPtr<NodeFilter> create()
{
- return adoptRef(new NodeFilter());
+ return adoptRefWillBeNoop(new NodeFilter());
}
- short acceptNode(ScriptState*, Node*) const;
+ short acceptNode(Node*, ExceptionState&) const;
- void setCondition(PassRefPtr<NodeFilterCondition> condition)
+ void setCondition(PassRefPtrWillBeRawPtr<NodeFilterCondition> condition)
{
m_condition = condition;
}
+ void trace(Visitor*);
+
private:
- explicit NodeFilter(PassRefPtr<NodeFilterCondition> condition) : m_condition(condition)
+ explicit NodeFilter(PassRefPtrWillBeRawPtr<NodeFilterCondition> condition) : m_condition(condition)
{
ScriptWrappable::init(this);
}
@@ -93,7 +96,7 @@ private:
ScriptWrappable::init(this);
}
- RefPtr<NodeFilterCondition> m_condition;
+ RefPtrWillBeMember<NodeFilterCondition> m_condition;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl
index 58ac22e9407..7d52e408bcd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilter.idl
@@ -19,7 +19,8 @@
*/
[
- DependentLifetime
+ DependentLifetime,
+ WillBeGarbageCollected,
] interface NodeFilter {
// Constants returned by acceptNode
const short FILTER_ACCEPT = 1;
@@ -41,7 +42,6 @@
const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x00000400;
const unsigned long SHOW_NOTATION = 0x00000800;
- [CallWith=ScriptState] short acceptNode([Default=Undefined] optional Node n);
+ [RaisesException] short acceptNode([Default=Undefined] optional Node n);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp
index aee9f8029ac..18a99b42181 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-short NodeFilterCondition::acceptNode(ScriptState*, Node*) const
+short NodeFilterCondition::acceptNode(Node*, ExceptionState&) const
{
return NodeFilter::FILTER_ACCEPT;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h b/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h
index 4c838e9e094..d1248f3b5e1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeFilterCondition.h
@@ -25,18 +25,21 @@
#ifndef NodeFilterCondition_h
#define NodeFilterCondition_h
-#include "bindings/v8/ScriptState.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
namespace WebCore {
- class Node;
+class ExceptionState;
+class Node;
- class NodeFilterCondition : public RefCounted<NodeFilterCondition> {
- public:
- virtual ~NodeFilterCondition() { }
- virtual short acceptNode(ScriptState*, Node*) const = 0;
- };
+class NodeFilterCondition : public RefCountedWillBeGarbageCollectedFinalized<NodeFilterCondition> {
+public:
+ virtual ~NodeFilterCondition() { }
+ virtual short acceptNode(Node*, ExceptionState&) const = 0;
+
+ virtual void trace(Visitor*) { }
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp
index 35c912fe65a..fd2f9737119 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.cpp
@@ -26,7 +26,6 @@
#include "core/dom/NodeIterator.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeTraversal.h"
@@ -37,7 +36,7 @@ NodeIterator::NodePointer::NodePointer()
{
}
-NodeIterator::NodePointer::NodePointer(PassRefPtr<Node> n, bool b)
+NodeIterator::NodePointer::NodePointer(PassRefPtrWillBeRawPtr<Node> n, bool b)
: node(n)
, isPointerBeforeNode(b)
{
@@ -72,10 +71,9 @@ bool NodeIterator::NodePointer::moveToPrevious(Node* root)
return node;
}
-NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
- : Traversal(rootNode, whatToShow, filter)
+NodeIterator::NodeIterator(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
+ : NodeIteratorBase(rootNode, whatToShow, filter)
, m_referenceNode(root(), true)
- , m_detached(false)
{
ScriptWrappable::init(this);
root()->document().attachNodeIterator(this);
@@ -83,26 +81,23 @@ NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassR
NodeIterator::~NodeIterator()
{
+#if !ENABLE(OILPAN)
root()->document().detachNodeIterator(this);
+#endif
}
-PassRefPtr<Node> NodeIterator::nextNode(ScriptState* state, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NodeIterator::nextNode(ExceptionState& exceptionState)
{
- if (m_detached) {
- exceptionState.throwDOMException(InvalidStateError, "The iterator is detached.");
- return 0;
- }
-
- RefPtr<Node> result;
+ RefPtrWillBeRawPtr<Node> result = nullptr;
m_candidateNode = m_referenceNode;
while (m_candidateNode.moveToNext(root())) {
// NodeIterators treat the DOM tree as a flat list of nodes.
// In other words, FILTER_REJECT does not pass over descendants
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
- RefPtr<Node> provisionalResult = m_candidateNode.node;
- bool nodeWasAccepted = acceptNode(state, provisionalResult.get()) == NodeFilter::FILTER_ACCEPT;
- if (state && state->hadException())
+ RefPtrWillBeRawPtr<Node> provisionalResult = m_candidateNode.node;
+ bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionState) == NodeFilter::FILTER_ACCEPT;
+ if (exceptionState.hadException())
break;
if (nodeWasAccepted) {
m_referenceNode = m_candidateNode;
@@ -115,23 +110,18 @@ PassRefPtr<Node> NodeIterator::nextNode(ScriptState* state, ExceptionState& exce
return result.release();
}
-PassRefPtr<Node> NodeIterator::previousNode(ScriptState* state, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> NodeIterator::previousNode(ExceptionState& exceptionState)
{
- if (m_detached) {
- exceptionState.throwDOMException(InvalidStateError, "The iterator is detached.");
- return 0;
- }
-
- RefPtr<Node> result;
+ RefPtrWillBeRawPtr<Node> result = nullptr;
m_candidateNode = m_referenceNode;
while (m_candidateNode.moveToPrevious(root())) {
// NodeIterators treat the DOM tree as a flat list of nodes.
// In other words, FILTER_REJECT does not pass over descendants
// of the rejected node. Hence, FILTER_REJECT is the same as FILTER_SKIP.
- RefPtr<Node> provisionalResult = m_candidateNode.node;
- bool nodeWasAccepted = acceptNode(state, provisionalResult.get()) == NodeFilter::FILTER_ACCEPT;
- if (state && state->hadException())
+ RefPtrWillBeRawPtr<Node> provisionalResult = m_candidateNode.node;
+ bool nodeWasAccepted = acceptNode(provisionalResult.get(), exceptionState) == NodeFilter::FILTER_ACCEPT;
+ if (exceptionState.hadException())
break;
if (nodeWasAccepted) {
m_referenceNode = m_candidateNode;
@@ -146,9 +136,7 @@ PassRefPtr<Node> NodeIterator::previousNode(ScriptState* state, ExceptionState&
void NodeIterator::detach()
{
- root()->document().detachNodeIterator(this);
- m_detached = true;
- m_referenceNode.node.clear();
+ // This is now a no-op as per the DOM specification.
}
void NodeIterator::nodeWillBeRemoved(Node& removedNode)
@@ -159,14 +147,13 @@ void NodeIterator::nodeWillBeRemoved(Node& removedNode)
void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenceNode) const
{
- ASSERT(!m_detached);
ASSERT(root()->document() == removedNode.document());
// Iterator is not affected if the removed node is the reference node and is the root.
// or if removed node is not the reference node, or the ancestor of the reference node.
if (!removedNode.isDescendantOf(root()))
return;
- bool willRemoveReferenceNode = removedNode == referenceNode.node;
+ bool willRemoveReferenceNode = removedNode == referenceNode.node.get();
bool willRemoveReferenceNodeAncestor = referenceNode.node && referenceNode.node->isDescendantOf(&removedNode);
if (!willRemoveReferenceNode && !willRemoveReferenceNodeAncestor)
return;
@@ -224,5 +211,11 @@ void NodeIterator::updateForNodeRemoval(Node& removedNode, NodePointer& referenc
}
}
+void NodeIterator::trace(Visitor* visitor)
+{
+ visitor->trace(m_referenceNode);
+ visitor->trace(m_candidateNode);
+ NodeIteratorBase::trace(visitor);
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.h b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.h
index 1f06a57c3e4..c2c5de1b05f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.h
@@ -27,7 +27,8 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/NodeFilter.h"
-#include "core/dom/Traversal.h"
+#include "core/dom/NodeIteratorBase.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -35,16 +36,18 @@ namespace WebCore {
class ExceptionState;
-class NodeIterator : public ScriptWrappable, public RefCounted<NodeIterator>, public Traversal {
+class NodeIterator FINAL : public RefCountedWillBeGarbageCollectedFinalized<NodeIterator>, public ScriptWrappable, public NodeIteratorBase {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(NodeIterator);
public:
- static PassRefPtr<NodeIterator> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
+ static PassRefPtrWillBeRawPtr<NodeIterator> create(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
{
- return adoptRef(new NodeIterator(rootNode, whatToShow, filter));
+ return adoptRefWillBeNoop(new NodeIterator(rootNode, whatToShow, filter));
}
- ~NodeIterator();
- PassRefPtr<Node> nextNode(ScriptState*, ExceptionState&);
- PassRefPtr<Node> previousNode(ScriptState*, ExceptionState&);
+ virtual ~NodeIterator();
+
+ PassRefPtrWillBeRawPtr<Node> nextNode(ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> previousNode(ExceptionState&);
void detach();
Node* referenceNode() const { return m_referenceNode.node.get(); }
@@ -53,24 +56,34 @@ public:
// This function is called before any node is removed from the document tree.
void nodeWillBeRemoved(Node&);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- NodeIterator(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
+ NodeIterator(PassRefPtrWillBeRawPtr<Node>, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>);
- struct NodePointer {
- RefPtr<Node> node;
- bool isPointerBeforeNode;
+ class NodePointer {
+ DISALLOW_ALLOCATION();
+ public:
NodePointer();
- NodePointer(PassRefPtr<Node>, bool);
+ NodePointer(PassRefPtrWillBeRawPtr<Node>, bool);
+
void clear();
bool moveToNext(Node* root);
bool moveToPrevious(Node* root);
+
+ RefPtrWillBeMember<Node> node;
+ bool isPointerBeforeNode;
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(node);
+ }
};
void updateForNodeRemoval(Node& nodeToBeRemoved, NodePointer&) const;
NodePointer m_referenceNode;
NodePointer m_candidateNode;
- bool m_detached;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl
index 9c636c4bdd6..ef46701e401 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIterator.idl
@@ -18,19 +18,19 @@
* Boston, MA 02110-1301, USA.
*/
-// Introduced in DOM Level 2:
+// Introduced in DOM Level 2
[
- SetReference(NodeFilter filter)
+ SetWrapperReferenceTo(NodeFilter filter),
+ WillBeGarbageCollected,
] interface NodeIterator {
readonly attribute Node root;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter filter;
- readonly attribute boolean expandEntityReferences;
+ [DeprecateAs=NodeIteratorExpandEntityReferences] readonly attribute boolean expandEntityReferences;
readonly attribute Node referenceNode;
readonly attribute boolean pointerBeforeReferenceNode;
- [CallWith=ScriptState, RaisesException] Node nextNode();
- [CallWith=ScriptState, RaisesException] Node previousNode();
- void detach();
+ [RaisesException] Node nextNode();
+ [RaisesException] Node previousNode();
+ [DeprecateAs=NodeIteratorDetach] void detach();
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp
new file mode 100644
index 00000000000..8899fc88dce
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
+ * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/dom/NodeIteratorBase.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/Node.h"
+#include "core/dom/NodeFilter.h"
+
+namespace WebCore {
+
+NodeIteratorBase::NodeIteratorBase(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> nodeFilter)
+ : m_root(rootNode)
+ , m_whatToShow(whatToShow)
+ , m_filter(nodeFilter)
+{
+}
+
+short NodeIteratorBase::acceptNode(Node* node, ExceptionState& exceptionState) const
+{
+ // The bit twiddling here is done to map DOM node types, which are given as integers from
+ // 1 through 14, to whatToShow bit masks.
+ if (!(((1 << (node->nodeType() - 1)) & m_whatToShow)))
+ return NodeFilter::FILTER_SKIP;
+ if (!m_filter)
+ return NodeFilter::FILTER_ACCEPT;
+ return m_filter->acceptNode(node, exceptionState);
+}
+
+void NodeIteratorBase::trace(Visitor* visitor)
+{
+ visitor->trace(m_root);
+ visitor->trace(m_filter);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.h b/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.h
new file mode 100644
index 00000000000..18cc6aeb98f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeIteratorBase.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
+ * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NodeIteratorBase_h
+#define NodeIteratorBase_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class ExceptionState;
+class Node;
+class NodeFilter;
+
+class NodeIteratorBase : public WillBeGarbageCollectedMixin {
+public:
+ virtual ~NodeIteratorBase() { }
+
+ Node* root() const { return m_root.get(); }
+ unsigned whatToShow() const { return m_whatToShow; }
+ NodeFilter* filter() const { return m_filter.get(); }
+ // |expandEntityReferences| first appeared in "DOM Level 2 Traversal and Range". However, this argument was
+ // never implemented, and, in DOM4, the function argument |expandEntityReferences| is removed from
+ // Document.createNodeIterator() and Document.createTreeWalker().
+ bool expandEntityReferences() const { return false; }
+
+ virtual void trace(Visitor*);
+
+protected:
+ NodeIteratorBase(PassRefPtrWillBeRawPtr<Node>, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>);
+ short acceptNode(Node*, ExceptionState&) const;
+
+private:
+ RefPtrWillBeMember<Node> m_root;
+ unsigned m_whatToShow;
+ RefPtrWillBeMember<NodeFilter> m_filter;
+};
+
+} // namespace WebCore
+
+#endif // NodeIteratorBase_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeList.cpp
deleted file mode 100644
index fb06c70817b..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NodeList.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/NodeList.h"
-
-#include "core/dom/Node.h"
-
-namespace WebCore {
-
-void NodeList::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<Node>& returnValue0, bool& returnValue1Enabled, unsigned& returnValue1)
-{
- // Length property cannot be overridden.
- DEFINE_STATIC_LOCAL(const AtomicString, length, ("length", AtomicString::ConstructFromLiteral));
- if (name == length) {
- returnValue1Enabled = true;
- returnValue1 = this->length();
- return;
- }
-
- Node* result = namedItem(name);
- if (!result)
- return;
-
- returnValue0Enabled = true;
- returnValue0 = result;
-}
-
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeList.h b/chromium/third_party/WebKit/Source/core/dom/NodeList.h
index 1d77043f3f8..1b1643898cb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeList.h
@@ -25,25 +25,27 @@
#define NodeList_h
#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
namespace WebCore {
class Node;
-class NodeList : public ScriptWrappable, public RefCounted<NodeList> {
+class NodeList : public RefCountedWillBeGarbageCollectedFinalized<NodeList>, public ScriptWrappable {
public:
virtual ~NodeList() { }
// DOM methods & attributes for NodeList
virtual unsigned length() const = 0;
virtual Node* item(unsigned index) const = 0;
- virtual Node* namedItem(const AtomicString&) const = 0;
// Other methods (not part of DOM)
- virtual bool isLiveNodeList() const { return false; }
- void anonymousNamedGetter(const AtomicString&, bool&, RefPtr<Node>&, bool&, unsigned&);
+ virtual bool isEmptyNodeList() const { return false; }
+ virtual bool isChildNodeList() const { return false; }
+
+ virtual Node* virtualOwnerNode() const { return 0; }
+
+ virtual void trace(Visitor*) { }
protected:
NodeList()
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeList.idl b/chromium/third_party/WebKit/Source/core/dom/NodeList.idl
index 19ccec64c87..66cc82045c8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeList.idl
@@ -19,14 +19,10 @@
*/
[
- Custom=VisitDOMWrapper,
DependentLifetime,
+ SetWrapperReferenceFrom=virtualOwnerNode,
+ WillBeGarbageCollected,
] interface NodeList {
-
getter Node item(unsigned long index);
- [ImplementedAs=anonymousNamedGetter, OverrideBuiltins, NotEnumerable] getter (Node or unsigned long) (DOMString name);
-
readonly attribute unsigned long length;
-
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp
index bbd863e8c68..e8ea37076c2 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRareData.cpp
@@ -30,14 +30,69 @@
#include "config.h"
#include "core/dom/NodeRareData.h"
+#include "core/dom/Element.h"
+#include "core/dom/ElementRareData.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
struct SameSizeAsNodeRareData {
- unsigned m_bitfields : 20;
- void* m_pointer[3];
+ void* m_pointer[2];
+ OwnPtrWillBeMember<NodeMutationObserverData> m_mutationObserverData;
+ unsigned m_bitfields;
};
COMPILE_ASSERT(sizeof(NodeRareData) == sizeof(SameSizeAsNodeRareData), NodeRareDataShouldStaySmall);
+void NodeListsNodeData::invalidateCaches(const QualifiedName* attrName)
+{
+ NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
+ for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it)
+ it->value->invalidateCacheForAttribute(attrName);
+
+ if (attrName)
+ return;
+
+ TagCollectionCacheNS::iterator tagCacheEnd = m_tagCollectionCacheNS.end();
+ for (TagCollectionCacheNS::iterator it = m_tagCollectionCacheNS.begin(); it != tagCacheEnd; ++it)
+ it->value->invalidateCache();
+}
+
+void NodeListsNodeData::trace(Visitor* visitor)
+{
+ visitor->trace(m_childNodeList);
+ visitor->trace(m_atomicNameCaches);
+ visitor->trace(m_tagCollectionCacheNS);
+}
+
+void NodeRareData::traceAfterDispatch(Visitor* visitor)
+{
+ visitor->trace(m_mutationObserverData);
+ // Do not keep empty NodeListsNodeData objects around.
+ if (m_nodeLists && m_nodeLists->isEmpty())
+ m_nodeLists.clear();
+ else
+ visitor->trace(m_nodeLists);
+}
+
+void NodeRareData::trace(Visitor* visitor)
+{
+ if (m_isElementRareData)
+ static_cast<ElementRareData*>(this)->traceAfterDispatch(visitor);
+ else
+ traceAfterDispatch(visitor);
+}
+
+void NodeRareData::finalizeGarbageCollectedObject()
+{
+ RELEASE_ASSERT(!renderer());
+ if (m_isElementRareData)
+ static_cast<ElementRareData*>(this)->~ElementRareData();
+ else
+ this->~NodeRareData();
+}
+
+// Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
+COMPILE_ASSERT(Page::maxNumberOfFrames < (1 << NodeRareData::ConnectedFrameCountBits), Frame_limit_should_fit_in_rare_data_count);
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRareData.h b/chromium/third_party/WebKit/Source/core/dom/NodeRareData.h
index 38dd440c6cb..edc3719595f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRareData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRareData.h
@@ -23,11 +23,13 @@
#define NodeRareData_h
#include "core/dom/ChildNodeList.h"
+#include "core/dom/EmptyNodeList.h"
#include "core/dom/LiveNodeList.h"
#include "core/dom/MutationObserverRegistration.h"
#include "core/dom/QualifiedName.h"
-#include "core/dom/TagNodeList.h"
+#include "core/dom/TagCollection.h"
#include "core/page/Page.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
@@ -40,102 +42,122 @@ class LabelsNodeList;
class RadioNodeList;
class TreeScope;
-class NodeListsNodeData {
- WTF_MAKE_NONCOPYABLE(NodeListsNodeData); WTF_MAKE_FAST_ALLOCATED;
+class NodeListsNodeData FINAL : public NoBaseWillBeGarbageCollectedFinalized<NodeListsNodeData> {
+ WTF_MAKE_NONCOPYABLE(NodeListsNodeData);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
void clearChildNodeListCache()
{
+ if (m_childNodeList && m_childNodeList->isChildNodeList())
+ toChildNodeList(m_childNodeList)->invalidateCache();
+ }
+
+ PassRefPtrWillBeRawPtr<ChildNodeList> ensureChildNodeList(ContainerNode& node)
+ {
if (m_childNodeList)
- m_childNodeList->invalidateCache();
+ return toChildNodeList(m_childNodeList);
+ RefPtrWillBeRawPtr<ChildNodeList> list = ChildNodeList::create(node);
+ m_childNodeList = list.get();
+ return list.release();
}
- PassRefPtr<ChildNodeList> ensureChildNodeList(Node* node)
+ PassRefPtrWillBeRawPtr<EmptyNodeList> ensureEmptyChildNodeList(Node& node)
{
if (m_childNodeList)
- return m_childNodeList;
- RefPtr<ChildNodeList> list = ChildNodeList::create(node);
+ return toEmptyNodeList(m_childNodeList);
+ RefPtrWillBeRawPtr<EmptyNodeList> list = EmptyNodeList::create(node);
m_childNodeList = list.get();
return list.release();
}
+#if !ENABLE(OILPAN)
void removeChildNodeList(ChildNodeList* list)
{
ASSERT(m_childNodeList == list);
if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
return;
- m_childNodeList = 0;
+ m_childNodeList = nullptr;
}
- template <typename StringType>
- struct NodeListCacheMapEntryHash {
- static unsigned hash(const std::pair<unsigned char, StringType>& entry)
+ void removeEmptyChildNodeList(EmptyNodeList* list)
+ {
+ ASSERT(m_childNodeList == list);
+ if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
+ return;
+ m_childNodeList = nullptr;
+ }
+#endif
+
+ struct NodeListAtomicCacheMapEntryHash {
+ static unsigned hash(const std::pair<unsigned char, StringImpl*>& entry)
{
- return DefaultHash<StringType>::Hash::hash(entry.second) + entry.first;
+ return DefaultHash<StringImpl*>::Hash::hash(entry.second) + entry.first;
}
- static bool equal(const std::pair<unsigned char, StringType>& a, const std::pair<unsigned char, StringType>& b) { return a == b; }
- static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringType>::Hash::safeToCompareToEmptyOrDeleted;
+ static bool equal(const std::pair<unsigned char, StringImpl*>& a, const std::pair<unsigned char, StringImpl*>& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = DefaultHash<StringImpl*>::Hash::safeToCompareToEmptyOrDeleted;
};
- typedef HashMap<std::pair<unsigned char, AtomicString>, LiveNodeListBase*, NodeListCacheMapEntryHash<AtomicString> > NodeListAtomicNameCacheMap;
- typedef HashMap<std::pair<unsigned char, String>, LiveNodeListBase*, NodeListCacheMapEntryHash<String> > NodeListNameCacheMap;
- typedef HashMap<QualifiedName, TagNodeList*> TagNodeListCacheNS;
+ // Oilpan: keep a weak reference to the collection objects.
+ // Explicit object unregistration in a non-Oilpan setting
+ // on object destruction is replaced by the garbage collector
+ // clearing out their weak reference.
+ typedef WillBeHeapHashMap<std::pair<unsigned char, StringImpl*>, RawPtrWillBeWeakMember<LiveNodeListBase>, NodeListAtomicCacheMapEntryHash> NodeListAtomicNameCacheMap;
+ typedef WillBeHeapHashMap<QualifiedName, RawPtrWillBeWeakMember<TagCollection> > TagCollectionCacheNS;
template<typename T>
- PassRefPtr<T> addCacheWithAtomicName(Node* node, CollectionType collectionType, const AtomicString& name)
+ PassRefPtrWillBeRawPtr<T> addCache(ContainerNode& node, CollectionType collectionType, const AtomicString& name)
{
- NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, name), 0);
- if (!result.isNewEntry)
- return static_cast<T*>(result.iterator->value);
+ NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, name), nullptr);
+ if (!result.isNewEntry) {
+#if ENABLE(OILPAN)
+ return static_cast<T*>(result.storedValue->value.get());
+#else
+ return static_cast<T*>(result.storedValue->value);
+#endif
+ }
- RefPtr<T> list = T::create(node, collectionType, name);
- result.iterator->value = list.get();
+ RefPtrWillBeRawPtr<T> list = T::create(node, collectionType, name);
+ result.storedValue->value = list.get();
return list.release();
}
- // FIXME: This function should be renamed since it doesn't have an atomic name.
template<typename T>
- PassRefPtr<T> addCacheWithAtomicName(Node* node, CollectionType collectionType)
+ PassRefPtrWillBeRawPtr<T> addCache(ContainerNode& node, CollectionType collectionType)
{
- NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, starAtom), 0);
- if (!result.isNewEntry)
- return static_cast<T*>(result.iterator->value);
+ NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, starAtom), nullptr);
+ if (!result.isNewEntry) {
+#if ENABLE(OILPAN)
+ return static_cast<T*>(result.storedValue->value.get());
+#else
+ return static_cast<T*>(result.storedValue->value);
+#endif
+ }
- RefPtr<T> list = T::create(node, collectionType);
- result.iterator->value = list.get();
+ RefPtrWillBeRawPtr<T> list = T::create(node, collectionType);
+ result.storedValue->value = list.get();
return list.release();
}
template<typename T>
- T* cacheWithAtomicName(CollectionType collectionType)
+ T* cached(CollectionType collectionType)
{
return static_cast<T*>(m_atomicNameCaches.get(namedNodeListKey(collectionType, starAtom)));
}
- template<typename T>
- PassRefPtr<T> addCacheWithName(Node* node, CollectionType collectionType, const String& name)
- {
- NodeListNameCacheMap::AddResult result = m_nameCaches.add(namedNodeListKey(collectionType, name), 0);
- if (!result.isNewEntry)
- return static_cast<T*>(result.iterator->value);
-
- RefPtr<T> list = T::create(node, name);
- result.iterator->value = list.get();
- return list.release();
- }
-
- PassRefPtr<TagNodeList> addCacheWithQualifiedName(Node* node, const AtomicString& namespaceURI, const AtomicString& localName)
+ PassRefPtrWillBeRawPtr<TagCollection> addCache(ContainerNode& node, const AtomicString& namespaceURI, const AtomicString& localName)
{
QualifiedName name(nullAtom, localName, namespaceURI);
- TagNodeListCacheNS::AddResult result = m_tagNodeListCacheNS.add(name, 0);
+ TagCollectionCacheNS::AddResult result = m_tagCollectionCacheNS.add(name, nullptr);
if (!result.isNewEntry)
- return result.iterator->value;
+ return result.storedValue->value;
- RefPtr<TagNodeList> list = TagNodeList::create(node, namespaceURI, localName);
- result.iterator->value = list.get();
+ RefPtrWillBeRawPtr<TagCollection> list = TagCollection::create(node, namespaceURI, localName);
+ result.storedValue->value = list.get();
return list.release();
}
- void removeCacheWithAtomicName(LiveNodeListBase* list, CollectionType collectionType, const AtomicString& name = starAtom)
+#if !ENABLE(OILPAN)
+ void removeCache(LiveNodeListBase* list, CollectionType collectionType, const AtomicString& name = starAtom)
{
ASSERT(list == m_atomicNameCaches.get(namedNodeListKey(collectionType, name)));
if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
@@ -143,32 +165,26 @@ public:
m_atomicNameCaches.remove(namedNodeListKey(collectionType, name));
}
- void removeCacheWithName(LiveNodeListBase* list, CollectionType collectionType, const String& name)
- {
- ASSERT(list == m_nameCaches.get(namedNodeListKey(collectionType, name)));
- if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
- return;
- m_nameCaches.remove(namedNodeListKey(collectionType, name));
- }
-
- void removeCacheWithQualifiedName(LiveNodeList* list, const AtomicString& namespaceURI, const AtomicString& localName)
+ void removeCache(LiveNodeListBase* list, const AtomicString& namespaceURI, const AtomicString& localName)
{
QualifiedName name(nullAtom, localName, namespaceURI);
- ASSERT(list == m_tagNodeListCacheNS.get(name));
+ ASSERT(list == m_tagCollectionCacheNS.get(name));
if (deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(list->ownerNode()))
return;
- m_tagNodeListCacheNS.remove(name);
+ m_tagCollectionCacheNS.remove(name);
}
+#endif
- static PassOwnPtr<NodeListsNodeData> create()
+ static PassOwnPtrWillBeRawPtr<NodeListsNodeData> create()
{
- return adoptPtr(new NodeListsNodeData);
+ return adoptPtrWillBeNoop(new NodeListsNodeData);
}
void invalidateCaches(const QualifiedName* attrName = 0);
+
bool isEmpty() const
{
- return m_atomicNameCaches.isEmpty() && m_nameCaches.isEmpty() && m_tagNodeListCacheNS.isEmpty();
+ return !m_childNodeList && m_atomicNameCaches.isEmpty() && m_tagCollectionCacheNS.isEmpty();
}
void adoptTreeScope()
@@ -176,76 +192,78 @@ public:
invalidateCaches();
}
- void adoptDocument(Document* oldDocument, Document* newDocument)
+ void adoptDocument(Document& oldDocument, Document& newDocument)
{
- invalidateCaches();
+ ASSERT(oldDocument != newDocument);
- if (oldDocument != newDocument) {
- NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
- for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) {
- LiveNodeListBase* list = it->value;
- oldDocument->unregisterNodeList(list);
- newDocument->registerNodeList(list);
- }
-
- NodeListNameCacheMap::const_iterator nameCacheEnd = m_nameCaches.end();
- for (NodeListNameCacheMap::const_iterator it = m_nameCaches.begin(); it != nameCacheEnd; ++it) {
- LiveNodeListBase* list = it->value;
- oldDocument->unregisterNodeList(list);
- newDocument->registerNodeList(list);
- }
-
- TagNodeListCacheNS::const_iterator tagEnd = m_tagNodeListCacheNS.end();
- for (TagNodeListCacheNS::const_iterator it = m_tagNodeListCacheNS.begin(); it != tagEnd; ++it) {
- LiveNodeListBase* list = it->value;
- ASSERT(!list->isRootedAtDocument());
- oldDocument->unregisterNodeList(list);
- newDocument->registerNodeList(list);
- }
+ NodeListAtomicNameCacheMap::const_iterator atomicNameCacheEnd = m_atomicNameCaches.end();
+ for (NodeListAtomicNameCacheMap::const_iterator it = m_atomicNameCaches.begin(); it != atomicNameCacheEnd; ++it) {
+ LiveNodeListBase* list = it->value;
+ list->didMoveToDocument(oldDocument, newDocument);
+ }
+
+ TagCollectionCacheNS::const_iterator tagEnd = m_tagCollectionCacheNS.end();
+ for (TagCollectionCacheNS::const_iterator it = m_tagCollectionCacheNS.begin(); it != tagEnd; ++it) {
+ LiveNodeListBase* list = it->value;
+ ASSERT(!list->isRootedAtDocument());
+ list->didMoveToDocument(oldDocument, newDocument);
}
}
+ void trace(Visitor*);
+
private:
NodeListsNodeData()
- : m_childNodeList(0)
+ : m_childNodeList(nullptr)
{ }
- std::pair<unsigned char, AtomicString> namedNodeListKey(CollectionType type, const AtomicString& name)
+ std::pair<unsigned char, StringImpl*> namedNodeListKey(CollectionType type, const AtomicString& name)
{
- return std::pair<unsigned char, AtomicString>(type, name);
+ // Holding the raw StringImpl is safe because |name| is retained by the NodeList and the NodeList
+ // is reponsible for removing itself from the cache on deletion.
+ return std::pair<unsigned char, StringImpl*>(type, name.impl());
}
- std::pair<unsigned char, String> namedNodeListKey(CollectionType type, const String& name)
- {
- return std::pair<unsigned char, String>(type, name);
- }
-
- bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node*);
+#if !ENABLE(OILPAN)
+ bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node&);
+#endif
- // FIXME: m_childNodeList should be merged into m_atomicNameCaches or at least be shared with HTMLCollection returned by Element::children
- // but it's tricky because invalidateCaches shouldn't invalidate this cache and adoptTreeScope shouldn't call registerNodeList or unregisterNodeList.
- ChildNodeList* m_childNodeList;
+ // Can be a ChildNodeList or an EmptyNodeList.
+ RawPtrWillBeWeakMember<NodeList> m_childNodeList;
NodeListAtomicNameCacheMap m_atomicNameCaches;
- NodeListNameCacheMap m_nameCaches;
- TagNodeListCacheNS m_tagNodeListCacheNS;
+ TagCollectionCacheNS m_tagCollectionCacheNS;
};
-class NodeMutationObserverData {
- WTF_MAKE_NONCOPYABLE(NodeMutationObserverData); WTF_MAKE_FAST_ALLOCATED;
+class NodeMutationObserverData FINAL : public NoBaseWillBeGarbageCollected<NodeMutationObserverData> {
+ WTF_MAKE_NONCOPYABLE(NodeMutationObserverData);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- Vector<OwnPtr<MutationObserverRegistration> > registry;
- HashSet<MutationObserverRegistration*> transientRegistry;
+ WillBeHeapVector<OwnPtrWillBeMember<MutationObserverRegistration> > registry;
+ WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> > transientRegistry;
- static PassOwnPtr<NodeMutationObserverData> create() { return adoptPtr(new NodeMutationObserverData); }
+ static PassOwnPtrWillBeRawPtr<NodeMutationObserverData> create()
+ {
+ return adoptPtrWillBeNoop(new NodeMutationObserverData);
+ }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(registry);
+ visitor->trace(transientRegistry);
+ }
private:
NodeMutationObserverData() { }
};
-class NodeRareData : public NodeRareDataBase {
- WTF_MAKE_NONCOPYABLE(NodeRareData); WTF_MAKE_FAST_ALLOCATED;
+class NodeRareData : public NoBaseWillBeGarbageCollectedFinalized<NodeRareData>, public NodeRareDataBase {
+ WTF_MAKE_NONCOPYABLE(NodeRareData);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<NodeRareData> create(RenderObject* renderer) { return adoptPtr(new NodeRareData(renderer)); }
+ static NodeRareData* create(RenderObject* renderer)
+ {
+ return new NodeRareData(renderer);
+ }
void clearNodeLists() { m_nodeLists.clear(); }
NodeListsNodeData* nodeLists() const { return m_nodeLists.get(); }
@@ -276,31 +294,54 @@ public:
m_connectedFrameCount -= amount;
}
+ bool hasElementFlag(ElementFlags mask) const { return m_elementFlags & mask; }
+ void setElementFlag(ElementFlags mask, bool value) { m_elementFlags = (m_elementFlags & ~mask) | (-(int32_t)value & mask); }
+ void clearElementFlag(ElementFlags mask) { m_elementFlags &= ~mask; }
+
+ bool hasRestyleFlag(DynamicRestyleFlags mask) const { return m_restyleFlags & mask; }
+ void setRestyleFlag(DynamicRestyleFlags mask) { m_restyleFlags |= mask; RELEASE_ASSERT(m_restyleFlags); }
+ bool hasRestyleFlags() const { return m_restyleFlags; }
+ void clearRestyleFlags() { m_restyleFlags = 0; }
+
+ enum {
+ ConnectedFrameCountBits = 10, // Must fit Page::maxNumberOfFrames.
+ };
+
+ void trace(Visitor*);
+
+ void traceAfterDispatch(Visitor*);
+ void finalizeGarbageCollectedObject();
+
protected:
- NodeRareData(RenderObject* renderer)
+ explicit NodeRareData(RenderObject* renderer)
: NodeRareDataBase(renderer)
, m_connectedFrameCount(0)
+ , m_elementFlags(0)
+ , m_restyleFlags(0)
+ , m_isElementRareData(false)
{ }
private:
- unsigned m_connectedFrameCount : 10; // Must fit Page::maxNumberOfFrames.
+ OwnPtrWillBeMember<NodeListsNodeData> m_nodeLists;
+ OwnPtrWillBeMember<NodeMutationObserverData> m_mutationObserverData;
- OwnPtr<NodeListsNodeData> m_nodeLists;
- OwnPtr<NodeMutationObserverData> m_mutationObserverData;
+ unsigned m_connectedFrameCount : ConnectedFrameCountBits;
+ unsigned m_elementFlags : NumberOfElementFlags;
+ unsigned m_restyleFlags : NumberOfDynamicRestyleFlags;
+protected:
+ unsigned m_isElementRareData : 1;
};
-inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node* ownerNode)
+#if !ENABLE(OILPAN)
+inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node& ownerNode)
{
- ASSERT(ownerNode);
- ASSERT(ownerNode->nodeLists() == this);
- if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_nameCaches.size() + m_tagNodeListCacheNS.size() != 1)
+ ASSERT(ownerNode.nodeLists() == this);
+ if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_tagCollectionCacheNS.size() != 1)
return false;
- ownerNode->clearNodeLists();
+ ownerNode.clearNodeLists();
return true;
}
-
-// Ensure the 10 bits reserved for the m_connectedFrameCount cannot overflow
-COMPILE_ASSERT(Page::maxNumberOfFrames < 1024, Frame_limit_should_fit_in_rare_data_count);
+#endif
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h b/chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h
index a9487abba62..96b9fab2c72 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRenderStyle.h
@@ -27,6 +27,7 @@
#include "core/dom/Node.h"
#include "core/dom/NodeRenderingTraversal.h"
+#include "core/html/HTMLOptGroupElement.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/style/RenderStyle.h"
@@ -34,11 +35,14 @@ namespace WebCore {
inline RenderStyle* Node::renderStyle() const
{
- // Using a ternary here confuses the Solaris Studio 12/12.1/12.2 compilers:
- // Bug is CR 6569194, "Problem with question operator binding in inline function"
if (RenderObject* renderer = this->renderer())
return renderer->style();
- return nonRendererStyle();
+ // <option> and <optgroup> can be styled even though they never get renderers,
+ // so they store their style internally and return it through nonRendererStyle().
+ // We check here explicitly to avoid the virtual call in the common case.
+ if (isHTMLOptGroupElement(*this) || isHTMLOptionElement(this))
+ return nonRendererStyle();
+ return 0;
}
inline RenderStyle* Node::parentRenderStyle() const
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.cpp
deleted file mode 100644
index 2d2b4a4e08d..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/dom/NodeRenderingContext.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/ContainerNode.h"
-#include "core/dom/FullscreenElementStack.h"
-#include "core/dom/Node.h"
-#include "core/dom/Text.h"
-#include "core/dom/shadow/InsertionPoint.h"
-#include "core/rendering/FlowThreadController.h"
-#include "core/rendering/RenderFullScreen.h"
-#include "core/rendering/RenderNamedFlowThread.h"
-#include "core/rendering/RenderObject.h"
-#include "core/rendering/RenderText.h"
-#include "core/rendering/RenderView.h"
-
-namespace WebCore {
-
-static bool isRendererReparented(const RenderObject* renderer)
-{
- if (!renderer->node()->isElementNode())
- return false;
- if (renderer->style() && !renderer->style()->flowThread().isEmpty())
- return true;
- if (toElement(renderer->node())->shouldBeReparentedUnderRenderView(renderer->style()))
- return true;
- return false;
-}
-
-RenderObject* NodeRenderingContext::nextRenderer() const
-{
- if (RenderObject* renderer = m_node->renderer())
- return renderer->nextSibling();
-
- Element* element = m_node->isElementNode() ? toElement(m_node) : 0;
- if (element && element->shouldBeReparentedUnderRenderView(m_style.get())) {
- // FIXME: Reparented renderers not in the top layer should probably be
- // ordered in DOM tree order. We don't have a good way to do that yet,
- // since NodeRenderingTraversal isn't aware of reparenting. It's safe to
- // just append for now; it doesn't disrupt the top layer rendering as
- // the layer collection in RenderLayer only requires that top layer
- // renderers are orderered correctly relative to each other.
- if (!element->isInTopLayer())
- return 0;
-
- const Vector<RefPtr<Element> >& topLayerElements = element->document().topLayerElements();
- size_t position = topLayerElements.find(element);
- ASSERT(position != kNotFound);
- for (size_t i = position + 1; i < topLayerElements.size(); ++i) {
- if (RenderObject* renderer = topLayerElements[i]->renderer())
- return renderer;
- }
- return 0;
- }
-
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer->nextRendererForNode(m_node);
-
- // Avoid an O(N^2) walk over the children when reattaching all children of a node.
- if (m_renderingParent && m_renderingParent->needsAttach())
- return 0;
-
- for (Node* sibling = NodeRenderingTraversal::nextSibling(m_node); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
- RenderObject* renderer = sibling->renderer();
- if (renderer && !isRendererReparented(renderer))
- return renderer;
- }
-
- return 0;
-}
-
-RenderObject* NodeRenderingContext::previousRenderer() const
-{
- if (RenderObject* renderer = m_node->renderer())
- return renderer->previousSibling();
-
- // FIXME: This doesn't work correctly for reparented elements that are
- // display: none. We'd need to duplicate the logic in nextRenderer, but since
- // nothing needs that yet just assert.
- ASSERT(!m_node->isElementNode() || !toElement(m_node)->shouldBeReparentedUnderRenderView(m_style.get()));
-
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer->previousRendererForNode(m_node);
-
- // FIXME: We should have the same O(N^2) avoidance as nextRenderer does
- // however, when I tried adding it, several tests failed.
- for (Node* sibling = NodeRenderingTraversal::previousSibling(m_node); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
- RenderObject* renderer = sibling->renderer();
- if (renderer && !isRendererReparented(renderer))
- return renderer;
- }
-
- return 0;
-}
-
-RenderObject* NodeRenderingContext::parentRenderer() const
-{
- if (RenderObject* renderer = m_node->renderer())
- return renderer->parent();
-
- if (m_node->isElementNode() && toElement(m_node)->shouldBeReparentedUnderRenderView(m_style.get())) {
- // The parent renderer of reparented elements is the RenderView, but only
- // if the normal parent would have had a renderer.
- // FIXME: This behavior isn't quite right as the spec for top layer
- // only talks about display: none ancestors so putting a <dialog> inside
- // an <optgroup> seems like it should still work even though this check
- // will prevent it.
- if (!m_renderingParent || !m_renderingParent->renderer())
- return 0;
- return m_node->document().renderView();
- }
-
- if (m_parentFlowRenderer)
- return m_parentFlowRenderer;
-
- return m_renderingParent ? m_renderingParent->renderer() : 0;
-}
-
-bool NodeRenderingContext::shouldCreateRenderer() const
-{
- if (!m_renderingParent)
- return false;
- RenderObject* parentRenderer = this->parentRenderer();
- if (!parentRenderer)
- return false;
- if (!parentRenderer->canHaveChildren())
- return false;
- if (!m_renderingParent->childShouldCreateRenderer(*m_node))
- return false;
- return true;
-}
-
-// Check the specific case of elements that are children of regions but are flowed into a flow thread themselves.
-bool NodeRenderingContext::elementInsideRegionNeedsRenderer()
-{
- Element* element = toElement(m_node);
- bool elementInsideRegionNeedsRenderer = false;
- RenderObject* parentRenderer = this->parentRenderer();
- if ((parentRenderer && !parentRenderer->canHaveChildren() && parentRenderer->isRenderNamedFlowFragmentContainer())
- || (!parentRenderer && element->parentElement() && element->parentElement()->isInsideRegion())) {
-
- if (!m_style)
- m_style = element->styleForRenderer();
-
- elementInsideRegionNeedsRenderer = element->shouldMoveToFlowThread(m_style.get());
-
- // Children of this element will only be allowed to be flowed into other flow-threads if display is NOT none.
- if (element->rendererIsNeeded(*m_style))
- element->setIsInsideRegion(true);
- }
-
- return elementInsideRegionNeedsRenderer;
-}
-
-void NodeRenderingContext::moveToFlowThreadIfNeeded()
-{
- if (!RuntimeEnabledFeatures::cssRegionsEnabled())
- return;
-
- Element* element = toElement(m_node);
-
- if (!element->shouldMoveToFlowThread(m_style.get()))
- return;
-
- ASSERT(m_node->document().renderView());
- FlowThreadController* flowThreadController = m_node->document().renderView()->flowThreadController();
- m_parentFlowRenderer = flowThreadController->ensureRenderFlowThreadWithName(m_style->flowThread());
- flowThreadController->registerNamedFlowContentNode(m_node, m_parentFlowRenderer);
-}
-
-void NodeRenderingContext::createRendererForElementIfNeeded()
-{
- ASSERT(!m_node->renderer());
-
- Element* element = toElement(m_node);
-
- element->setIsInsideRegion(false);
-
- if (!shouldCreateRenderer() && !elementInsideRegionNeedsRenderer())
- return;
-
- if (!m_style)
- m_style = element->styleForRenderer();
-
- moveToFlowThreadIfNeeded();
-
- if (!element->rendererIsNeeded(*m_style))
- return;
-
- RenderObject* newRenderer = element->createRenderer(m_style.get());
- if (!newRenderer)
- return;
-
- RenderObject* parentRenderer = this->parentRenderer();
-
- if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
- newRenderer->destroy();
- return;
- }
-
- // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
- // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
- newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
-
- RenderObject* nextRenderer = this->nextRenderer();
- element->setRenderer(newRenderer);
- newRenderer->setAnimatableStyle(m_style.release()); // setAnimatableStyle() can depend on renderer() already being set.
-
- if (FullscreenElementStack::isActiveFullScreenElement(element)) {
- newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &element->document());
- if (!newRenderer)
- return;
- }
-
- // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
- parentRenderer->addChild(newRenderer, nextRenderer);
-}
-
-void NodeRenderingContext::createRendererForTextIfNeeded()
-{
- ASSERT(!m_node->renderer());
-
- Text* textNode = toText(m_node);
-
- if (!shouldCreateRenderer())
- return;
-
- RenderObject* parentRenderer = this->parentRenderer();
-
- if (m_parentDetails.resetStyleInheritance())
- m_style = textNode->document().ensureStyleResolver().defaultStyleForElement();
- else
- m_style = parentRenderer->style();
-
- if (!textNode->textRendererIsNeeded(*this))
- return;
-
- RenderText* newRenderer = textNode->createTextRenderer(m_style.get());
- if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
- newRenderer->destroy();
- return;
- }
-
- // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
- // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
- newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
-
- RenderObject* nextRenderer = this->nextRenderer();
- textNode->setRenderer(newRenderer);
- // Parent takes care of the animations, no need to call setAnimatableStyle.
- newRenderer->setStyle(m_style.release());
- parentRenderer->addChild(newRenderer, nextRenderer);
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.h b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.h
deleted file mode 100644
index ac2bab3b580..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingContext.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef NodeRenderingContext_h
-#define NodeRenderingContext_h
-
-#include "core/dom/NodeRenderingTraversal.h"
-
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class ContainerNode;
-class Node;
-class RenderNamedFlowThread;
-class RenderObject;
-class RenderStyle;
-
-class NodeRenderingContext {
-public:
- explicit NodeRenderingContext(Node* node, RenderStyle* style = 0)
- : m_node(node)
- , m_renderingParent(0)
- , m_style(style)
- , m_parentFlowRenderer(0)
- {
- m_renderingParent = NodeRenderingTraversal::parent(node, &m_parentDetails);
- }
-
- void createRendererForTextIfNeeded();
- void createRendererForElementIfNeeded();
-
- Node* node() const { return m_node; }
- RenderObject* parentRenderer() const;
- RenderObject* nextRenderer() const;
- RenderObject* previousRenderer() const;
-
- const RenderStyle* style() const { return m_style.get(); }
-
-private:
- bool shouldCreateRenderer() const;
- void moveToFlowThreadIfNeeded();
- bool elementInsideRegionNeedsRenderer();
-
- Node* m_node;
- ContainerNode* m_renderingParent;
- NodeRenderingTraversal::ParentDetails m_parentDetails;
- RefPtr<RenderStyle> m_style;
- RenderNamedFlowThread* m_parentFlowRenderer;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp
index b30c66aba53..e60ef4f29d7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp
@@ -27,26 +27,31 @@
#include "config.h"
#include "core/dom/NodeRenderingTraversal.h"
+#include "core/HTMLNames.h"
#include "core/dom/PseudoElement.h"
#include "core/dom/shadow/ComposedTreeWalker.h"
+#include "core/rendering/RenderObject.h"
namespace WebCore {
namespace NodeRenderingTraversal {
+static bool isRendererReparented(const RenderObject* renderer)
+{
+ if (!renderer->node()->isElementNode())
+ return false;
+ if (toElement(renderer->node())->isInTopLayer())
+ return true;
+ return false;
+}
+
void ParentDetails::didTraverseInsertionPoint(const InsertionPoint* insertionPoint)
{
if (!m_insertionPoint) {
m_insertionPoint = insertionPoint;
- m_resetStyleInheritance = m_resetStyleInheritance || insertionPoint->resetStyleInheritance();
}
}
-void ParentDetails::didTraverseShadowRoot(const ShadowRoot* root)
-{
- m_resetStyleInheritance = m_resetStyleInheritance || root->resetStyleInheritance();
-}
-
ContainerNode* parent(const Node* node, ParentDetails* details)
{
// FIXME: We should probably ASSERT(!node->document().childNeedsDistributionRecalc()) here, but
@@ -59,6 +64,16 @@ ContainerNode* parent(const Node* node, ParentDetails* details)
return toContainerNode(walker.traverseParent(walker.get(), details));
}
+bool contains(const ContainerNode* container, const Node* node)
+{
+ while (node) {
+ if (node == container)
+ return true;
+ node = NodeRenderingTraversal::parent(node);
+ }
+ return false;
+}
+
Node* nextSibling(const Node* node)
{
ComposedTreeWalker walker(node);
@@ -97,6 +112,149 @@ Node* previousSibling(const Node* node)
return 0;
}
+static Node* lastChild(const Node* node)
+{
+ ComposedTreeWalker walker(node);
+ walker.lastChild();
+ return walker.get();
+}
+
+static Node* pseudoAwarePreviousSibling(const Node* node)
+{
+ Node* previousNode = previousSibling(node);
+ Node* parentNode = parent(node);
+
+ if (parentNode && parentNode->isElementNode() && !previousNode) {
+ if (node->isAfterPseudoElement()) {
+ if (Node* child = lastChild(parentNode))
+ return child;
+ }
+ if (!node->isBeforePseudoElement())
+ return toElement(parentNode)->pseudoElement(BEFORE);
+ }
+ return previousNode;
+}
+
+static Node* pseudoAwareLastChild(const Node* node)
+{
+ if (node->isElementNode()) {
+ const Element* currentElement = toElement(node);
+ Node* last = currentElement->pseudoElement(AFTER);
+ if (last)
+ return last;
+
+ last = lastChild(currentElement);
+ if (!last)
+ last = currentElement->pseudoElement(BEFORE);
+ return last;
+ }
+
+ return lastChild(node);
+}
+
+Node* previous(const Node* node, const Node* stayWithin)
+{
+ if (node == stayWithin)
+ return 0;
+
+ if (Node* previousNode = pseudoAwarePreviousSibling(node)) {
+ while (Node* previousLastChild = pseudoAwareLastChild(previousNode))
+ previousNode = previousLastChild;
+ return previousNode;
+ }
+ return parent(node);
+}
+
+static Node* firstChild(const Node* node)
+{
+ ComposedTreeWalker walker(node);
+ walker.firstChild();
+ return walker.get();
+}
+
+static Node* pseudoAwareNextSibling(const Node* node)
+{
+ Node* parentNode = parent(node);
+ Node* nextNode = nextSibling(node);
+
+ if (parentNode && parentNode->isElementNode() && !nextNode) {
+ if (node->isBeforePseudoElement()) {
+ if (Node* child = firstChild(parentNode))
+ return child;
+ }
+ if (!node->isAfterPseudoElement())
+ return toElement(parentNode)->pseudoElement(AFTER);
+ }
+ return nextNode;
+}
+
+static Node* pseudoAwareFirstChild(const Node* node)
+{
+ if (node->isElementNode()) {
+ const Element* currentElement = toElement(node);
+ Node* first = currentElement->pseudoElement(BEFORE);
+ if (first)
+ return first;
+ first = firstChild(currentElement);
+ if (!first)
+ first = currentElement->pseudoElement(AFTER);
+ return first;
+ }
+
+ return firstChild(node);
+}
+
+Node* next(const Node* node, const Node* stayWithin)
+{
+ if (Node* child = pseudoAwareFirstChild(node))
+ return child;
+ if (node == stayWithin)
+ return 0;
+ if (Node* nextNode = pseudoAwareNextSibling(node))
+ return nextNode;
+ for (Node* parentNode = parent(node); parentNode; parentNode = parent(parentNode)) {
+ if (parentNode == stayWithin)
+ return 0;
+ if (Node* nextNode = pseudoAwareNextSibling(parentNode))
+ return nextNode;
+ }
+ return 0;
+}
+
+RenderObject* nextSiblingRenderer(const Node* node)
+{
+ for (Node* sibling = NodeRenderingTraversal::nextSibling(node); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
+ RenderObject* renderer = sibling->renderer();
+ if (renderer && !isRendererReparented(renderer))
+ return renderer;
+ }
+ return 0;
+}
+
+RenderObject* previousSiblingRenderer(const Node* node)
+{
+ for (Node* sibling = NodeRenderingTraversal::previousSibling(node); sibling; sibling = NodeRenderingTraversal::previousSibling(sibling)) {
+ RenderObject* renderer = sibling->renderer();
+ if (renderer && !isRendererReparented(renderer))
+ return renderer;
+ }
+ return 0;
+}
+
+RenderObject* nextInTopLayer(const Element* element)
+{
+ if (!element->isInTopLayer())
+ return 0;
+ const WillBeHeapVector<RefPtrWillBeMember<Element> >& topLayerElements = element->document().topLayerElements();
+ size_t position = topLayerElements.find(element);
+ ASSERT(position != kNotFound);
+ for (size_t i = position + 1; i < topLayerElements.size(); ++i) {
+ if (RenderObject* renderer = topLayerElements[i]->renderer())
+ return renderer;
+ }
+ return 0;
+}
+
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h
index 8935ae60a45..0a0bd9c13e5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeRenderingTraversal.h
@@ -32,6 +32,7 @@
namespace WebCore {
class InsertionPoint;
+class RenderObject;
namespace NodeRenderingTraversal {
@@ -39,30 +40,31 @@ class ParentDetails {
public:
ParentDetails()
: m_insertionPoint(0)
- , m_resetStyleInheritance(false)
{ }
const InsertionPoint* insertionPoint() const { return m_insertionPoint; }
- bool resetStyleInheritance() const { return m_resetStyleInheritance; }
void didTraverseInsertionPoint(const InsertionPoint*);
- void didTraverseShadowRoot(const ShadowRoot*);
bool operator==(const ParentDetails& other)
{
- return m_insertionPoint == other.m_insertionPoint
- && m_resetStyleInheritance == other.m_resetStyleInheritance;
+ return m_insertionPoint == other.m_insertionPoint;
}
private:
const InsertionPoint* m_insertionPoint;
- bool m_resetStyleInheritance;
};
ContainerNode* parent(const Node*);
ContainerNode* parent(const Node*, ParentDetails*);
+bool contains(const ContainerNode*, const Node*);
Node* nextSibling(const Node*);
Node* previousSibling(const Node*);
+Node* previous(const Node*, const Node* stayWithin);
+Node* next(const Node*, const Node* stayWithin);
+RenderObject* nextSiblingRenderer(const Node*);
+RenderObject* previousSiblingRenderer(const Node*);
+RenderObject* nextInTopLayer(const Element*);
inline ContainerNode* parent(const Node* node)
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp b/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp
index 631a8b9c741..6ad5ecd96a8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.cpp
@@ -28,9 +28,8 @@
#include "core/dom/ContainerNode.h"
namespace WebCore {
-namespace NodeTraversal {
-Node* previousIncludingPseudo(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousIncludingPseudo(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
@@ -42,7 +41,7 @@ Node* previousIncludingPseudo(const Node& current, const Node* stayWithin)
return current.parentNode();
}
-Node* nextIncludingPseudo(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextIncludingPseudo(const Node& current, const Node* stayWithin)
{
if (Node* next = current.pseudoAwareFirstChild())
return next;
@@ -59,7 +58,7 @@ Node* nextIncludingPseudo(const Node& current, const Node* stayWithin)
return 0;
}
-Node* nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
@@ -74,7 +73,7 @@ Node* nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayW
return 0;
}
-Node* nextAncestorSibling(const Node& current)
+Node* NodeTraversal::nextAncestorSibling(const Node& current)
{
ASSERT(!current.nextSibling());
for (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
@@ -84,7 +83,7 @@ Node* nextAncestorSibling(const Node& current)
return 0;
}
-Node* nextAncestorSibling(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextAncestorSibling(const Node& current, const Node* stayWithin)
{
ASSERT(!current.nextSibling());
ASSERT(current != stayWithin);
@@ -97,20 +96,28 @@ Node* nextAncestorSibling(const Node& current, const Node* stayWithin)
return 0;
}
-Node* previous(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::lastWithin(const ContainerNode& current)
+{
+ Node* descendant = current.lastChild();
+ for (Node* child = descendant; child; child = child->lastChild())
+ descendant = child;
+ return descendant;
+}
+
+Node* NodeTraversal::previous(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
if (current.previousSibling()) {
Node* previous = current.previousSibling();
- while (previous->lastChild())
- previous = previous->lastChild();
+ while (Node* child = previous->lastChild())
+ previous = child;
return previous;
}
return current.parentNode();
}
-Node* previousSkippingChildren(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousSkippingChildren(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
@@ -125,15 +132,15 @@ Node* previousSkippingChildren(const Node& current, const Node* stayWithin)
return 0;
}
-Node* nextPostOrder(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextPostOrder(const Node& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
if (!current.nextSibling())
return current.parentNode();
Node* next = current.nextSibling();
- while (next->firstChild())
- next = next->firstChild();
+ while (Node* child = next->firstChild())
+ next = child;
return next;
}
@@ -149,10 +156,10 @@ static Node* previousAncestorSiblingPostOrder(const Node& current, const Node* s
return 0;
}
-Node* previousPostOrder(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousPostOrder(const Node& current, const Node* stayWithin)
{
- if (current.lastChild())
- return current.lastChild();
+ if (Node* lastChild = current.lastChild())
+ return lastChild;
if (current == stayWithin)
return 0;
if (current.previousSibling())
@@ -160,14 +167,4 @@ Node* previousPostOrder(const Node& current, const Node* stayWithin)
return previousAncestorSiblingPostOrder(current, stayWithin);
}
-Node* previousSkippingChildrenPostOrder(const Node& current, const Node* stayWithin)
-{
- if (current == stayWithin)
- return 0;
- if (current.previousSibling())
- return current.previousSibling();
- return previousAncestorSiblingPostOrder(current, stayWithin);
-}
-
-}
-}
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h b/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h
index 438b0c09a29..e216fa56a2f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeTraversal.h
@@ -4,6 +4,7 @@
* (C) 2001 Dirk Mueller (mueller@kde.org)
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,46 +30,57 @@
namespace WebCore {
-namespace NodeTraversal {
-
-// Does a pre-order traversal of the tree to find the next node after this one.
-// This uses the same order that tags appear in the source file. If the stayWithin
-// argument is non-null, the traversal will stop once the specified node is reached.
-// This can be used to restrict traversal to a particular sub-tree.
-Node* next(const Node&);
-Node* next(const Node&, const Node* stayWithin);
-Node* next(const ContainerNode&);
-Node* next(const ContainerNode&, const Node* stayWithin);
-
-// Like next, but skips children and starts with the next sibling.
-Node* nextSkippingChildren(const Node&);
-Node* nextSkippingChildren(const Node&, const Node* stayWithin);
-Node* nextSkippingChildren(const ContainerNode&);
-Node* nextSkippingChildren(const ContainerNode&, const Node* stayWithin);
-
-// Does a reverse pre-order traversal to find the node that comes before the current one in document order
-Node* previous(const Node&, const Node* stayWithin = 0);
-
-// Like previous, but skips children and starts with the next sibling.
-Node* previousSkippingChildren(const Node&, const Node* stayWithin = 0);
-
-// Like next, but visits parents after their children.
-Node* nextPostOrder(const Node&, const Node* stayWithin = 0);
-
-// Like previous/previousSkippingChildren, but visits parents before their children.
-Node* previousPostOrder(const Node&, const Node* stayWithin = 0);
-Node* previousSkippingChildrenPostOrder(const Node&, const Node* stayWithin = 0);
-
-// Pre-order traversal including the pseudo-elements.
-Node* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Node* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Node* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
-
-Node* nextAncestorSibling(const Node&);
-Node* nextAncestorSibling(const Node&, const Node* stayWithin);
+class NodeTraversal {
+public:
+ // Does a pre-order traversal of the tree to find the next node after this one.
+ // This uses the same order that tags appear in the source file. If the stayWithin
+ // argument is non-null, the traversal will stop once the specified node is reached.
+ // This can be used to restrict traversal to a particular sub-tree.
+ static Node* next(const Node& current) { return traverseNextTemplate(current); }
+ static Node* next(const ContainerNode& current) { return traverseNextTemplate(current); }
+ static Node* next(const Node& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
+ static Node* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
+
+ // Like next, but skips children and starts with the next sibling.
+ static Node* nextSkippingChildren(const Node& current) { return traverseNextSkippingChildrenTemplate(current); }
+ static Node* nextSkippingChildren(const ContainerNode& current) { return traverseNextSkippingChildrenTemplate(current); }
+ static Node* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
+ static Node* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
+
+ // Does a reverse pre-order traversal to find the node that comes before the current one in document order
+ static Node* lastWithin(const ContainerNode&);
+ static Node* previous(const Node&, const Node* stayWithin = 0);
+
+ // Like previous, but skips children and starts with the next sibling.
+ static Node* previousSkippingChildren(const Node&, const Node* stayWithin = 0);
+
+ // Like next, but visits parents after their children.
+ static Node* nextPostOrder(const Node&, const Node* stayWithin = 0);
+
+ // Like previous, but visits parents before their children.
+ static Node* previousPostOrder(const Node&, const Node* stayWithin = 0);
+
+ // Pre-order traversal including the pseudo-elements.
+ static Node* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
+ static Node* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
+ static Node* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
+
+ static Node* nextAncestorSibling(const Node&);
+ static Node* nextAncestorSibling(const Node&, const Node* stayWithin);
+
+private:
+ template <class NodeType>
+ static Node* traverseNextTemplate(NodeType&);
+ template <class NodeType>
+ static Node* traverseNextTemplate(NodeType&, const Node* stayWithin);
+ template <class NodeType>
+ static Node* traverseNextSkippingChildrenTemplate(NodeType&);
+ template <class NodeType>
+ static Node* traverseNextSkippingChildrenTemplate(NodeType&, const Node* stayWithin);
+};
template <class NodeType>
-inline Node* traverseNextTemplate(NodeType& current)
+inline Node* NodeTraversal::traverseNextTemplate(NodeType& current)
{
if (current.firstChild())
return current.firstChild();
@@ -76,11 +88,9 @@ inline Node* traverseNextTemplate(NodeType& current)
return current.nextSibling();
return nextAncestorSibling(current);
}
-inline Node* next(const Node& current) { return traverseNextTemplate(current); }
-inline Node* next(const ContainerNode& current) { return traverseNextTemplate(current); }
template <class NodeType>
-inline Node* traverseNextTemplate(NodeType& current, const Node* stayWithin)
+inline Node* NodeTraversal::traverseNextTemplate(NodeType& current, const Node* stayWithin)
{
if (current.firstChild())
return current.firstChild();
@@ -90,21 +100,17 @@ inline Node* traverseNextTemplate(NodeType& current, const Node* stayWithin)
return current.nextSibling();
return nextAncestorSibling(current, stayWithin);
}
-inline Node* next(const Node& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
-inline Node* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
template <class NodeType>
-inline Node* traverseNextSkippingChildrenTemplate(NodeType& current)
+inline Node* NodeTraversal::traverseNextSkippingChildrenTemplate(NodeType& current)
{
if (current.nextSibling())
return current.nextSibling();
return nextAncestorSibling(current);
}
-inline Node* nextSkippingChildren(const Node& current) { return traverseNextSkippingChildrenTemplate(current); }
-inline Node* nextSkippingChildren(const ContainerNode& current) { return traverseNextSkippingChildrenTemplate(current); }
template <class NodeType>
-inline Node* traverseNextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
+inline Node* NodeTraversal::traverseNextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
{
if (current == stayWithin)
return 0;
@@ -112,11 +118,7 @@ inline Node* traverseNextSkippingChildrenTemplate(NodeType& current, const Node*
return current.nextSibling();
return nextAncestorSibling(current, stayWithin);
}
-inline Node* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
-inline Node* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
-}
-
-}
+} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h b/chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h
index 8c75ccc8682..7efddfc8aff 100644
--- a/chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h
+++ b/chromium/third_party/WebKit/Source/core/dom/NodeWithIndex.h
@@ -34,28 +34,27 @@ namespace WebCore {
// only want to walk the child list to figure out the index once.
class NodeWithIndex {
public:
- explicit NodeWithIndex(Node* node)
+ explicit NodeWithIndex(Node& node)
: m_node(node)
- , m_haveIndex(false)
+ , m_index(-1)
{
- ASSERT(node);
}
- Node* node() const { return m_node; }
+ Node& node() const { return m_node; }
int index() const
{
- if (!m_haveIndex) {
- m_index = m_node->nodeIndex();
- m_haveIndex = true;
- }
- ASSERT(m_index == static_cast<int>(m_node->nodeIndex()));
+ if (!hasIndex())
+ m_index = m_node.nodeIndex();
+ ASSERT(hasIndex());
+ ASSERT(m_index == static_cast<int>(m_node.nodeIndex()));
return m_index;
}
private:
- Node* m_node;
- mutable bool m_haveIndex;
+ bool hasIndex() const { return m_index >= 0; }
+
+ Node& m_node;
mutable int m_index;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Notation.h b/chromium/third_party/WebKit/Source/core/dom/Notation.h
index 30401f250e4..8ac0250336e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Notation.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Notation.h
@@ -28,11 +28,7 @@ namespace WebCore {
class Notation : public ContainerNode {
private:
- Notation(TreeScope* treeScope) : ContainerNode(treeScope)
- {
- ASSERT_NOT_REACHED();
- ScriptWrappable::init(this);
- }
+ Notation(); // Left unimplemented on purpose.
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ParentNode.h b/chromium/third_party/WebKit/Source/core/dom/ParentNode.h
index 9fb949a35b0..c85feee1d7e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ParentNode.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ParentNode.h
@@ -32,29 +32,44 @@
#define ParentNode_h
#include "core/dom/ContainerNode.h"
+#include "core/dom/ElementTraversal.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class ParentNode {
public:
- static PassRefPtr<HTMLCollection> children(ContainerNode* node)
+ static PassRefPtrWillBeRawPtr<HTMLCollection> children(ContainerNode& node)
{
- return node->children();
+ return node.children();
}
- static Element* firstElementChild(ContainerNode* node)
+ static Element* firstElementChild(ContainerNode& node)
{
- return node->firstElementChild();
+ return ElementTraversal::firstChild(node);
}
- static Element* lastElementChild(ContainerNode* node)
+ static Element* lastElementChild(ContainerNode& node)
{
- return node->lastElementChild();
+ return ElementTraversal::lastChild(node);
}
- static unsigned childElementCount(ContainerNode* node)
+ static unsigned childElementCount(ContainerNode& node)
{
- return node->childElementCount();
+ unsigned count = 0;
+ for (Element* child = ElementTraversal::firstWithin(node); child; child = ElementTraversal::nextSibling(*child))
+ ++count;
+ return count;
+ }
+
+ static PassRefPtrWillBeRawPtr<Element> querySelector(ContainerNode& node, const AtomicString& selectors, ExceptionState& exceptionState)
+ {
+ return node.querySelector(selectors, exceptionState);
+ }
+
+ static PassRefPtrWillBeRawPtr<StaticNodeList> querySelectorAll(ContainerNode& node, const AtomicString& selectors, ExceptionState& exceptionState)
+ {
+ return node.querySelectorAll(selectors, exceptionState);
}
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ParentNode.idl b/chromium/third_party/WebKit/Source/core/dom/ParentNode.idl
index 8de54f83d86..dea4bfd282a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ParentNode.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/ParentNode.idl
@@ -1,9 +1,43 @@
+/*
+ * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
[
- NoInterfaceObject,
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface ParentNode {
[PerWorldBindings] readonly attribute HTMLCollection children;
[PerWorldBindings] readonly attribute Element firstElementChild;
[PerWorldBindings] readonly attribute Element lastElementChild;
- [PerWorldBindings] readonly attribute unsigned long childElementCount;
-};
+ readonly attribute unsigned long childElementCount;
+ // NodeSelector - Selector API
+ [RaisesException] Element querySelector(DOMString selectors);
+ [RaisesException] NodeList querySelectorAll(DOMString selectors);
+};
diff --git a/chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp b/chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp
index b448c8bd9bf..d29146cb708 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/PendingScript.cpp
@@ -35,7 +35,7 @@ PendingScript::~PendingScript()
{
}
-PassRefPtr<Element> PendingScript::releaseElementAndClear()
+PassRefPtrWillBeRawPtr<Element> PendingScript::releaseElementAndClear()
{
setScriptResource(0);
m_watchingForLoad = false;
@@ -52,4 +52,9 @@ void PendingScript::notifyFinished(Resource*)
{
}
+void PendingScript::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/PendingScript.h b/chromium/third_party/WebKit/Source/core/dom/PendingScript.h
index a5c5855819c..8237aa9924f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PendingScript.h
+++ b/chromium/third_party/WebKit/Source/core/dom/PendingScript.h
@@ -29,6 +29,7 @@
#include "core/fetch/ResourceClient.h"
#include "core/fetch/ResourceOwner.h"
#include "core/fetch/ScriptResource.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/text/TextPosition.h"
@@ -43,7 +44,8 @@ class ScriptResource;
// A ResourcePtr alone does not prevent the underlying Resource
// from purging its data buffer. This class holds a dummy client open for its
// lifetime in order to guarantee that the data buffer will not be purged.
-class PendingScript : public ResourceOwner<ScriptResource> {
+class PendingScript FINAL : public ResourceOwner<ScriptResource> {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
PendingScript()
: m_watchingForLoad(false)
@@ -90,15 +92,17 @@ public:
Element* element() const { return m_element.get(); }
void setElement(Element* element) { m_element = element; }
- PassRefPtr<Element> releaseElementAndClear();
+ PassRefPtrWillBeRawPtr<Element> releaseElementAndClear();
void setScriptResource(ScriptResource*);
virtual void notifyFinished(Resource*);
+ void trace(Visitor*);
+
private:
bool m_watchingForLoad;
- RefPtr<Element> m_element;
+ RefPtrWillBeMember<Element> m_element;
TextPosition m_startingPosition; // Only used for inline script tags.
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Position.cpp b/chromium/third_party/WebKit/Source/core/dom/Position.cpp
index f6d9fa115b8..dbff7aa850d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Position.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Position.cpp
@@ -26,8 +26,7 @@
#include "config.h"
#include "core/dom/Position.h"
-#include <stdio.h>
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/dom/PositionIterator.h"
#include "core/dom/Text.h"
@@ -35,18 +34,18 @@
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
-#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLTableElement.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
-#include "platform/Logging.h"
+#include "core/html/HTMLTableElement.h"
#include "core/rendering/InlineIterator.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderText.h"
+#include "platform/Logging.h"
#include "wtf/text/CString.h"
#include "wtf/unicode/CharacterNames.h"
+#include <stdio.h>
namespace WebCore {
@@ -80,7 +79,7 @@ static Node* previousRenderedEditable(Node* node)
return 0;
}
-Position::Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset offset)
+Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, LegacyEditingOffset offset)
: m_anchorNode(anchorNode)
, m_offset(offset.value())
, m_anchorType(anchorTypeForLegacyEditingPosition(m_anchorNode.get(), m_offset))
@@ -89,7 +88,7 @@ Position::Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset offset)
ASSERT(!m_anchorNode || !m_anchorNode->isPseudoElement());
}
-Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
+Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, AnchorType anchorType)
: m_anchorNode(anchorNode)
, m_offset(0)
, m_anchorType(anchorType)
@@ -102,7 +101,7 @@ Position::Position(PassRefPtr<Node> anchorNode, AnchorType anchorType)
&& (m_anchorNode->isTextNode() || editingIgnoresContent(m_anchorNode.get()))));
}
-Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorType)
+Position::Position(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset, AnchorType anchorType)
: m_anchorNode(anchorNode)
, m_offset(offset)
, m_anchorType(anchorType)
@@ -113,7 +112,7 @@ Position::Position(PassRefPtr<Node> anchorNode, int offset, AnchorType anchorTyp
ASSERT(anchorType == PositionIsOffsetInAnchor);
}
-Position::Position(PassRefPtr<Text> textNode, unsigned offset)
+Position::Position(PassRefPtrWillBeRawPtr<Text> textNode, unsigned offset)
: m_anchorNode(textNode)
, m_offset(static_cast<int>(offset))
, m_anchorType(PositionIsOffsetInAnchor)
@@ -122,7 +121,7 @@ Position::Position(PassRefPtr<Text> textNode, unsigned offset)
ASSERT(m_anchorNode);
}
-void Position::moveToPosition(PassRefPtr<Node> node, int offset)
+void Position::moveToPosition(PassRefPtrWillBeRawPtr<Node> node, int offset)
{
ASSERT(!editingIgnoresContent(node.get()));
ASSERT(anchorType() == PositionIsOffsetInAnchor || m_isLegacyEditingPosition);
@@ -211,15 +210,15 @@ Position Position::parentAnchoredEquivalent() const
// FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
- if (m_anchorNode->parentNode() && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get())))
- return positionInParentBeforeNode(m_anchorNode.get());
+ if (m_anchorNode->parentNode() && (editingIgnoresContent(m_anchorNode.get()) || isRenderedTableElement(m_anchorNode.get())))
+ return positionInParentBeforeNode(*m_anchorNode);
return Position(m_anchorNode.get(), 0, PositionIsOffsetInAnchor);
}
if (!m_anchorNode->offsetInCharacters()
- && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->childNodeCount())
- && (editingIgnoresContent(m_anchorNode.get()) || isTableElement(m_anchorNode.get()))
+ && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildren())
+ && (editingIgnoresContent(m_anchorNode.get()) || isRenderedTableElement(m_anchorNode.get()))
&& containerNode()) {
- return positionInParentAfterNode(m_anchorNode.get());
+ return positionInParentAfterNode(*m_anchorNode);
}
return Position(containerNode(), computeOffsetInContainerNode(), PositionIsOffsetInAnchor);
@@ -229,14 +228,13 @@ Node* Position::computeNodeBeforePosition() const
{
if (!m_anchorNode)
return 0;
-
switch (anchorType()) {
case PositionIsBeforeChildren:
return 0;
case PositionIsAfterChildren:
return m_anchorNode->lastChild();
case PositionIsOffsetInAnchor:
- return m_anchorNode->childNode(m_offset - 1); // -1 converts to childNode((unsigned)-1) and returns null.
+ return m_anchorNode->traverseToChildAt(m_offset - 1); // -1 converts to traverseToChildAt((unsigned)-1) and returns null.
case PositionIsBeforeAnchor:
return m_anchorNode->previousSibling();
case PositionIsAfterAnchor:
@@ -257,7 +255,7 @@ Node* Position::computeNodeAfterPosition() const
case PositionIsAfterChildren:
return 0;
case PositionIsOffsetInAnchor:
- return m_anchorNode->childNode(m_offset);
+ return m_anchorNode->traverseToChildAt(m_offset);
case PositionIsBeforeAnchor:
return m_anchorNode.get();
case PositionIsAfterAnchor:
@@ -286,11 +284,11 @@ Element* Position::element() const
return toElement(n);
}
-PassRefPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
+PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> Position::computedStyle() const
{
Element* elem = element();
if (!elem)
- return 0;
+ return nullptr;
return CSSComputedStyleDeclaration::create(elem);
}
@@ -305,7 +303,7 @@ Position Position::previous(PositionMoveType moveType) const
ASSERT(offset >= 0);
if (offset > 0) {
- if (Node* child = node->childNode(offset - 1))
+ if (Node* child = node->traverseToChildAt(offset - 1))
return lastPositionInOrAfterNode(child);
// There are two reasons child might be 0:
@@ -340,10 +338,10 @@ Position Position::next(PositionMoveType moveType) const
// FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
ASSERT(offset >= 0);
- if (Node* child = node->childNode(offset))
+ if (Node* child = node->traverseToChildAt(offset))
return firstPositionInOrBeforeNode(child);
- if (!node->hasChildNodes() && offset < lastOffsetForEditing(node)) {
+ if (!node->hasChildren() && offset < lastOffsetForEditing(node)) {
// There are two reasons child might be 0:
// 1) The node is node like a text node that is not an element, and therefore has no children.
// Going forward one character at a time is correct.
@@ -505,34 +503,6 @@ Position Position::previousCharacterPosition(EAffinity affinity) const
return *this;
}
-// return first following position rendered at a different location, or "this"
-Position Position::nextCharacterPosition(EAffinity affinity) const
-{
- if (isNull())
- return Position();
-
- Node* fromRootEditableElement = deprecatedNode()->rootEditableElement();
-
- bool atEndOfLine = isEndOfLine(VisiblePosition(*this, affinity));
- bool rendered = isCandidate();
-
- Position currentPos = *this;
- while (!currentPos.atEndOfTree()) {
- currentPos = currentPos.next();
-
- if (currentPos.deprecatedNode()->rootEditableElement() != fromRootEditableElement)
- return *this;
-
- if (atEndOfLine || !rendered) {
- if (currentPos.isCandidate())
- return currentPos;
- } else if (rendersInDifferentPosition(currentPos))
- return currentPos;
- }
-
- return *this;
-}
-
// Whether or not [node, 0] and [node, lastOffsetForEditing(node)] are their own VisiblePositions.
// If true, adjacent candidates are visually distinct.
// FIXME: Disregard nodes with renderers that have no height, as we do in isCandidate.
@@ -546,9 +516,14 @@ static bool endsOfNodeAreVisuallyDistinctPositions(Node* node)
return true;
// Don't include inline tables.
- if (isHTMLTableElement(node))
+ if (isHTMLTableElement(*node))
return false;
+ // A Marquee elements are moving so we should assume their ends are always
+ // visibily distinct.
+ if (isHTMLMarqueeElement(*node))
+ return true;
+
// There is a VisiblePosition inside an empty inline-block container.
return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && toRenderBox(node->renderer())->height() != 0 && !node->firstChild();
}
@@ -635,7 +610,7 @@ Position Position::upstream(EditingBoundaryCrossingRule rule) const
return lastVisible;
// Return position after tables and nodes which have content that can be ignored.
- if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
+ if (editingIgnoresContent(currentNode) || isRenderedTableElement(currentNode)) {
if (currentPos.atEndOfNode())
return positionAfterNode(currentNode);
continue;
@@ -736,7 +711,7 @@ Position Position::downstream(EditingBoundaryCrossingRule rule) const
// stop before going above the body, up into the head
// return the last visible streamer position
- if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode())
+ if (isHTMLBodyElement(*currentNode) && currentPos.atEndOfNode())
break;
// Do not move to a visually distinct position.
@@ -763,7 +738,7 @@ Position Position::downstream(EditingBoundaryCrossingRule rule) const
lastVisible = currentPos;
// Return position before tables and nodes which have content that can be ignored.
- if (editingIgnoresContent(currentNode) || isTableElement(currentNode)) {
+ if (editingIgnoresContent(currentNode) || isRenderedTableElement(currentNode)) {
if (currentPos.offsetInLeafNode() <= renderer->caretMinOffset())
return createLegacyEditingPosition(currentNode, renderer->caretMinOffset());
continue;
@@ -828,7 +803,7 @@ static int boundingBoxLogicalHeight(RenderObject *o, const IntRect &rect)
bool Position::hasRenderedNonAnonymousDescendantsWithHeight(RenderObject* renderer)
{
RenderObject* stop = renderer->nextInPreOrderAfterChildren();
- for (RenderObject *o = renderer->firstChild(); o && o != stop; o = o->nextInPreOrder())
+ for (RenderObject *o = renderer->slowFirstChild(); o && o != stop; o = o->nextInPreOrder())
if (o->nonPseudoNode()) {
if ((o->isText() && boundingBoxLogicalHeight(o, toRenderText(o)->linesBoundingBox()))
|| (o->isBox() && toRenderBox(o)->pixelSnappedLogicalHeight())
@@ -889,20 +864,26 @@ bool Position::isCandidate() const
if (renderer->isText())
return !nodeIsUserSelectNone(deprecatedNode()) && inRenderedText();
- if (isTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
+ if (renderer->isSVG()) {
+ // We don't consider SVG elements are contenteditable except for
+ // associated renderer returns isText() true, e.g. RenderSVGInlineText.
+ return false;
+ }
+
+ if (isRenderedTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
- if (isHTMLHtmlElement(m_anchorNode.get()))
+ if (isHTMLHtmlElement(*m_anchorNode))
return false;
if (renderer->isRenderBlockFlow()) {
- if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
+ if (toRenderBlock(renderer)->logicalHeight() || isHTMLBodyElement(*m_anchorNode)) {
if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
}
} else {
- Frame* frame = m_anchorNode->document().frame();
+ LocalFrame* frame = m_anchorNode->document().frame();
bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled();
return (caretBrowsing || m_anchorNode->rendererIsEditable()) && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
}
@@ -977,7 +958,7 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
return false;
if (deprecatedNode() == pos.deprecatedNode()) {
- if (deprecatedNode()->hasTagName(brTag))
+ if (isHTMLBRElement(*deprecatedNode()))
return false;
if (m_offset == pos.deprecatedEditingOffset())
@@ -989,10 +970,10 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
}
}
- if (deprecatedNode()->hasTagName(brTag) && pos.isCandidate())
+ if (isHTMLBRElement(*deprecatedNode()) && pos.isCandidate())
return true;
- if (pos.deprecatedNode()->hasTagName(brTag) && isCandidate())
+ if (isHTMLBRElement(*pos.deprecatedNode()) && isCandidate())
return true;
if (deprecatedNode()->enclosingBlockFlowElement() != pos.deprecatedNode()->enclosingBlockFlowElement())
@@ -1048,11 +1029,11 @@ bool Position::rendersInDifferentPosition(const Position &pos) const
// This assumes that it starts in editable content.
Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNonCollapsibleWhitespace) const
{
- ASSERT(isEditablePosition(*this));
+ ASSERT(isEditablePosition(*this, ContentIsEditable, DoNotUpdateStyle));
if (isNull())
return Position();
- if (upstream().deprecatedNode()->hasTagName(brTag))
+ if (isHTMLBRElement(*upstream().deprecatedNode()))
return Position();
Position prev = previousCharacterPosition(affinity);
@@ -1070,7 +1051,7 @@ Position Position::leadingWhitespacePosition(EAffinity affinity, bool considerNo
// This assumes that it starts in editable content.
Position Position::trailingWhitespacePosition(EAffinity, bool considerNonCollapsibleWhitespace) const
{
- ASSERT(isEditablePosition(*this));
+ ASSERT(isEditablePosition(*this, ContentIsEditable, DoNotUpdateStyle));
if (isNull())
return Position();
@@ -1091,7 +1072,7 @@ void Position::getInlineBoxAndOffset(EAffinity affinity, InlineBox*& inlineBox,
static bool isNonTextLeafChild(RenderObject* object)
{
- if (object->firstChild())
+ if (object->slowFirstChild())
return false;
if (object->isText())
return false;
@@ -1284,7 +1265,10 @@ void Position::getInlineBoxAndOffset(EAffinity affinity, TextDirection primaryDi
break;
inlineBox = prevBox;
}
- caretOffset = inlineBox->caretLeftmostOffset();
+ if (m_anchorNode->selfOrAncestorHasDirAutoAttribute())
+ caretOffset = inlineBox->bidiLevel() < level ? inlineBox->caretLeftmostOffset() : inlineBox->caretRightmostOffset();
+ else
+ caretOffset = inlineBox->caretLeftmostOffset();
} else if (nextBox->bidiLevel() > level) {
// Left edge of a "tertiary" run. Set to the right edge of that run.
while (InlineBox* tertiaryBox = inlineBox->nextLeafChildIgnoringLineBreak()) {
@@ -1310,6 +1294,10 @@ TextDirection Position::primaryDirection() const
return primaryDirection;
}
+void Position::trace(Visitor* visitor)
+{
+ visitor->trace(m_anchorNode);
+}
void Position::debugPosition(const char* msg) const
{
diff --git a/chromium/third_party/WebKit/Source/core/dom/Position.h b/chromium/third_party/WebKit/Source/core/dom/Position.h
index eea78f644ce..07ad7a195a5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Position.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Position.h
@@ -51,6 +51,7 @@ enum PositionMoveType {
};
class Position {
+ DISALLOW_ALLOCATION();
public:
enum AnchorType {
PositionIsOffsetInAnchor,
@@ -75,19 +76,19 @@ public:
private:
explicit LegacyEditingOffset(int offset) : m_offset(offset) { }
- friend Position createLegacyEditingPosition(PassRefPtr<Node>, int offset);
+ friend Position createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node>, int offset);
int m_offset;
};
- Position(PassRefPtr<Node> anchorNode, LegacyEditingOffset);
+ Position(PassRefPtrWillBeRawPtr<Node> anchorNode, LegacyEditingOffset);
// For creating before/after positions:
- Position(PassRefPtr<Node> anchorNode, AnchorType);
- Position(PassRefPtr<Text> textNode, unsigned offset);
+ Position(PassRefPtrWillBeRawPtr<Node> anchorNode, AnchorType);
+ Position(PassRefPtrWillBeRawPtr<Text> textNode, unsigned offset);
// For creating offset positions:
// FIXME: This constructor should eventually go away. See bug 63040.
- Position(PassRefPtr<Node> anchorNode, int offset, AnchorType);
+ Position(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset, AnchorType);
AnchorType anchorType() const { return static_cast<AnchorType>(m_anchorType); }
@@ -137,7 +138,7 @@ public:
// These should only be used for PositionIsOffsetInAnchor positions, unless
// the position is a legacy editing position.
- void moveToPosition(PassRefPtr<Node> anchorNode, int offset);
+ void moveToPosition(PassRefPtrWillBeRawPtr<Node> anchorNode, int offset);
void moveToOffset(int offset);
bool isNull() const { return !m_anchorNode; }
@@ -145,7 +146,7 @@ public:
bool isOrphan() const { return m_anchorNode && !m_anchorNode->inDocument(); }
Element* element() const;
- PassRefPtr<CSSComputedStyleDeclaration> computedStyle() const;
+ PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyle() const;
// Move up or down the DOM by one position.
// Offsets are computed using render text for nodes that have renderers - but note that even when
@@ -203,18 +204,18 @@ public:
void showTreeForThis() const;
#endif
+ void trace(Visitor*);
+
private:
int offsetForPositionAfterAnchor() const;
int renderedOffset() const;
-
Position previousCharacterPosition(EAffinity) const;
- Position nextCharacterPosition(EAffinity) const;
static AnchorType anchorTypeForLegacyEditingPosition(Node* anchorNode, int offset);
- RefPtr<Node> m_anchorNode;
+ RefPtrWillBeMember<Node> m_anchorNode;
// m_offset can be the offset inside m_anchorNode, or if editingIgnoresContent(m_anchorNode)
// returns true, then other places in editing will treat m_offset == 0 as "before the anchor"
// and m_offset > 0 as "after the anchor node". See parentAnchoredEquivalent for more info.
@@ -223,7 +224,7 @@ private:
bool m_isLegacyEditingPosition : 1;
};
-inline Position createLegacyEditingPosition(PassRefPtr<Node> node, int offset)
+inline Position createLegacyEditingPosition(PassRefPtrWillBeRawPtr<Node> node, int offset)
{
return Position(node, Position::LegacyEditingOffset(offset));
}
@@ -244,19 +245,19 @@ inline bool operator!=(const Position& a, const Position& b)
// These are inline to prevent ref-churn when returning a Position object.
// If we ever add a PassPosition we can make these non-inline.
-inline Position positionInParentBeforeNode(const Node* node)
+inline Position positionInParentBeforeNode(const Node& node)
{
- // FIXME: This should ASSERT(node->parentNode())
+ // FIXME: This should ASSERT(node.parentNode())
// At least one caller currently hits this ASSERT though, which indicates
// that the caller is trying to make a position relative to a disconnected node (which is likely an error)
// Specifically, editing/deleting/delete-ligature-001.html crashes with ASSERT(node->parentNode())
- return Position(node->parentNode(), node->nodeIndex(), Position::PositionIsOffsetInAnchor);
+ return Position(node.parentNode(), node.nodeIndex(), Position::PositionIsOffsetInAnchor);
}
-inline Position positionInParentAfterNode(const Node* node)
+inline Position positionInParentAfterNode(const Node& node)
{
- ASSERT(node->parentNode());
- return Position(node->parentNode(), node->nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
+ ASSERT(node.parentNode());
+ return Position(node.parentNode(), node.nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
}
// positionBeforeNode and positionAfterNode return neighbor-anchored positions, construction is O(1)
@@ -274,10 +275,10 @@ inline Position positionAfterNode(Node* anchorNode)
inline int lastOffsetInNode(Node* node)
{
- return node->offsetInCharacters() ? node->maxCharacterOffset() : static_cast<int>(node->childNodeCount());
+ return node->offsetInCharacters() ? node->maxCharacterOffset() : static_cast<int>(node->countChildren());
}
-// firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to childNodeCount()
+// firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to countChildren()
inline Position firstPositionInNode(Node* anchorNode)
{
if (anchorNode->isTextNode())
@@ -318,6 +319,7 @@ inline bool offsetIsBeforeLastNodeOffset(int offset, Node* anchorNode)
}
class PositionWithAffinity {
+ DISALLOW_ALLOCATION();
public:
PositionWithAffinity()
: m_affinity(DOWNSTREAM)
@@ -333,6 +335,11 @@ public:
EAffinity affinity() const { return m_affinity; }
const Position& position() const { return m_position; }
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_position);
+ }
+
private:
Position m_position;
EAffinity m_affinity;
diff --git a/chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp b/chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp
index f94c0aee90c..147ab5ef964 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/PositionIterator.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "core/dom/PositionIterator.h"
-#include "HTMLNames.h"
#include "core/editing/htmlediting.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/rendering/RenderBlock.h"
@@ -42,9 +41,9 @@ PositionIterator::operator Position() const
// FIXME: This check is inadaquete because any ancestor could be ignored by editing
if (editingIgnoresContent(m_nodeAfterPositionInAnchor->parentNode()))
return positionBeforeNode(m_anchorNode);
- return positionInParentBeforeNode(m_nodeAfterPositionInAnchor);
+ return positionInParentBeforeNode(*m_nodeAfterPositionInAnchor);
}
- if (m_anchorNode->hasChildNodes())
+ if (m_anchorNode->hasChildren())
return lastPositionInOrAfterNode(m_anchorNode);
return createLegacyEditingPosition(m_anchorNode, m_offsetInAnchor);
}
@@ -61,7 +60,7 @@ void PositionIterator::increment()
return;
}
- if (!m_anchorNode->hasChildNodes() && m_offsetInAnchor < lastOffsetForEditing(m_anchorNode))
+ if (!m_anchorNode->hasChildren() && m_offsetInAnchor < lastOffsetForEditing(m_anchorNode))
m_offsetInAnchor = Position::uncheckedNextOffset(m_anchorNode, m_offsetInAnchor);
else {
m_nodeAfterPositionInAnchor = m_anchorNode;
@@ -79,8 +78,8 @@ void PositionIterator::decrement()
if (m_nodeAfterPositionInAnchor) {
m_anchorNode = m_nodeAfterPositionInAnchor->previousSibling();
if (m_anchorNode) {
- m_nodeAfterPositionInAnchor = 0;
- m_offsetInAnchor = m_anchorNode->hasChildNodes() ? 0 : lastOffsetForEditing(m_anchorNode);
+ m_nodeAfterPositionInAnchor = nullptr;
+ m_offsetInAnchor = m_anchorNode->hasChildren() ? 0 : lastOffsetForEditing(m_anchorNode);
} else {
m_nodeAfterPositionInAnchor = m_nodeAfterPositionInAnchor->parentNode();
m_anchorNode = m_nodeAfterPositionInAnchor->parentNode();
@@ -89,9 +88,9 @@ void PositionIterator::decrement()
return;
}
- if (m_anchorNode->hasChildNodes()) {
+ if (m_anchorNode->hasChildren()) {
m_anchorNode = m_anchorNode->lastChild();
- m_offsetInAnchor = m_anchorNode->hasChildNodes()? 0: lastOffsetForEditing(m_anchorNode);
+ m_offsetInAnchor = m_anchorNode->hasChildren()? 0: lastOffsetForEditing(m_anchorNode);
} else {
if (m_offsetInAnchor)
m_offsetInAnchor = Position::uncheckedPreviousOffset(m_anchorNode, m_offsetInAnchor);
@@ -108,7 +107,7 @@ bool PositionIterator::atStart() const
return true;
if (m_anchorNode->parentNode())
return false;
- return (!m_anchorNode->hasChildNodes() && !m_offsetInAnchor) || (m_nodeAfterPositionInAnchor && !m_nodeAfterPositionInAnchor->previousSibling());
+ return (!m_anchorNode->hasChildren() && !m_offsetInAnchor) || (m_nodeAfterPositionInAnchor && !m_nodeAfterPositionInAnchor->previousSibling());
}
bool PositionIterator::atEnd() const
@@ -117,7 +116,7 @@ bool PositionIterator::atEnd() const
return true;
if (m_nodeAfterPositionInAnchor)
return false;
- return !m_anchorNode->parentNode() && (m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode));
+ return !m_anchorNode->parentNode() && (m_anchorNode->hasChildren() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode));
}
bool PositionIterator::atStartOfNode() const
@@ -125,7 +124,7 @@ bool PositionIterator::atStartOfNode() const
if (!m_anchorNode)
return true;
if (!m_nodeAfterPositionInAnchor)
- return !m_anchorNode->hasChildNodes() && !m_offsetInAnchor;
+ return !m_anchorNode->hasChildren() && !m_offsetInAnchor;
return !m_nodeAfterPositionInAnchor->previousSibling();
}
@@ -135,7 +134,7 @@ bool PositionIterator::atEndOfNode() const
return true;
if (m_nodeAfterPositionInAnchor)
return false;
- return m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode);
+ return m_anchorNode->hasChildren() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode);
}
bool PositionIterator::isCandidate() const
@@ -150,17 +149,33 @@ bool PositionIterator::isCandidate() const
if (renderer->style()->visibility() != VISIBLE)
return false;
- if (renderer->isBR())
- return !m_offsetInAnchor && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
-
+ if (renderer->isBR()) {
+ // For br element, the condition
+ // |(!m_anchorNode->hasChildren() || m_nodeAfterPositionInAnchor)|
+ // corresponds to the condition
+ // |m_anchorType != PositionIsAfterAnchor| in Position.isCandaite.
+ // Both conditions say this position is not in tail of the element.
+ // If conditions lose consitency, VisiblePosition::canonicalPosition
+ // will fail on |canonicalizeCandidate(previousCandidate(position))|,
+ // because previousCandidate returns a Position converted from
+ // a "Candidate" PositionIterator and cannonicalizeCandidate(Position)
+ // assumes the Position is "Candidate".
+ return !m_offsetInAnchor && (!m_anchorNode->hasChildren() || m_nodeAfterPositionInAnchor) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
+ }
if (renderer->isText())
return !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).inRenderedText();
- if (isTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
+ if (renderer->isSVG()) {
+ // We don't consider SVG elements are contenteditable except for
+ // associated renderer returns isText() true, e.g. RenderSVGInlineText.
+ return false;
+ }
+
+ if (isRenderedTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
- if (!isHTMLHtmlElement(m_anchorNode) && renderer->isRenderBlockFlow()) {
- if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
+ if (!isHTMLHtmlElement(*m_anchorNode) && renderer->isRenderBlockFlow()) {
+ if (toRenderBlock(renderer)->logicalHeight() || isHTMLBodyElement(*m_anchorNode)) {
if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).atEditingBoundary();
diff --git a/chromium/third_party/WebKit/Source/core/dom/PositionIterator.h b/chromium/third_party/WebKit/Source/core/dom/PositionIterator.h
index 6587f7eb0a5..b3bcba0a0d0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PositionIterator.h
+++ b/chromium/third_party/WebKit/Source/core/dom/PositionIterator.h
@@ -35,17 +35,18 @@ namespace WebCore {
// increment, decrement, and several predicates on the Position it is at.
// Conversion to/from Position is O(n) in the offset.
class PositionIterator {
+ STACK_ALLOCATED();
public:
PositionIterator()
- : m_anchorNode(0)
- , m_nodeAfterPositionInAnchor(0)
+ : m_anchorNode(nullptr)
+ , m_nodeAfterPositionInAnchor(nullptr)
, m_offsetInAnchor(0)
{
}
PositionIterator(const Position& pos)
: m_anchorNode(pos.anchorNode())
- , m_nodeAfterPositionInAnchor(m_anchorNode->childNode(pos.deprecatedEditingOffset()))
+ , m_nodeAfterPositionInAnchor(m_anchorNode->traverseToChildAt(pos.deprecatedEditingOffset()))
, m_offsetInAnchor(m_nodeAfterPositionInAnchor ? 0 : pos.deprecatedEditingOffset())
{
}
@@ -64,8 +65,8 @@ public:
bool isCandidate() const;
private:
- Node* m_anchorNode;
- Node* m_nodeAfterPositionInAnchor; // If this is non-null, m_nodeAfterPositionInAnchor->parentNode() == m_anchorNode;
+ RawPtrWillBeMember<Node> m_anchorNode;
+ RawPtrWillBeMember<Node> m_nodeAfterPositionInAnchor; // If this is non-null, m_nodeAfterPositionInAnchor->parentNode() == m_anchorNode;
int m_offsetInAnchor;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.cpp b/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.cpp
deleted file mode 100644
index b86239671a6..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/PostAttachCallbacks.h"
-
-#include "core/dom/Node.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-typedef std::pair<PostAttachCallbacks::Callback, RefPtr<Node> > CallbackInfo;
-typedef Vector<CallbackInfo> CallbackQueue;
-
-static size_t s_attachDepth;
-
-static CallbackQueue& callbackQueue()
-{
- DEFINE_STATIC_LOCAL(CallbackQueue, callbackQueue, ());
- return callbackQueue;
-}
-
-void PostAttachCallbacks::queueCallback(Callback callback, Node* node)
-{
- callbackQueue().append(CallbackInfo(callback, node));
-}
-
-PostAttachCallbacks::SuspendScope::SuspendScope()
-{
- ++s_attachDepth;
-}
-
-PostAttachCallbacks::SuspendScope::~SuspendScope()
-{
- if (s_attachDepth == 1) {
- // We recalculate size() each time through the loop because a callback
- // can add more callbacks to the end of the queue.
- CallbackQueue& queue = callbackQueue();
- for (size_t i = 0; i < queue.size(); ++i) {
- const CallbackInfo& info = queue[i];
- info.first(info.second.get());
- }
- queue.clear();
- }
- --s_attachDepth;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.h b/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.h
deleted file mode 100644
index 5684cb877ac..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/PostAttachCallbacks.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PostAttachCallbacks_h
-#define PostAttachCallbacks_h
-
-#include "wtf/Forward.h"
-
-namespace WebCore {
-
-class Node;
-
-class PostAttachCallbacks {
-public:
- typedef void (*Callback)(Node*);
- static void queueCallback(Callback, Node*);
-
- class SuspendScope {
- public:
- SuspendScope();
- ~SuspendScope();
- };
-private:
- PostAttachCallbacks();
-};
-
-} // namespace WebCore
-
-#endif // PostAttachCallbacks_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp b/chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
index e9ced659b29..dc2c1c95d3e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.cpp
@@ -31,10 +31,11 @@
#include "config.h"
#include "core/dom/PresentationAttributeStyle.h"
-#include "HTMLNames.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Attribute.h"
#include "core/dom/Element.h"
+#include "core/html/HTMLInputElement.h"
+#include "platform/Timer.h"
#include "wtf/HashFunctions.h"
#include "wtf/HashMap.h"
#include "wtf/text/CString.h"
@@ -87,7 +88,7 @@ public:
m_hitCount++;
if (!m_cleanTimer.isActive())
- m_cleanTimer.startOneShot(presentationAttributeCacheCleanTimeInSeconds);
+ m_cleanTimer.startOneShot(presentationAttributeCacheCleanTimeInSeconds, FROM_HERE);
}
private:
@@ -121,19 +122,19 @@ static void makePresentationAttributeCacheKey(Element& element, PresentationAttr
if (!element.isHTMLElement())
return;
// Interpretation of the size attributes on <input> depends on the type attribute.
- if (element.hasTagName(inputTag))
+ if (isHTMLInputElement(element))
return;
- unsigned size = element.attributeCount();
- for (unsigned i = 0; i < size; ++i) {
- const Attribute* attribute = element.attributeItem(i);
- if (!element.isPresentationAttribute(attribute->name()))
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (!element.isPresentationAttribute(it->name()))
continue;
- if (!attribute->namespaceURI().isNull())
+ if (!it->namespaceURI().isNull())
return;
// FIXME: Background URL may depend on the base URL and can't be shared. Disallow caching.
- if (attribute->name() == backgroundAttr)
+ if (it->name() == backgroundAttr)
return;
- result.attributesAndValues.append(std::make_pair(attribute->localName().impl(), attribute->value()));
+ result.attributesAndValues.append(std::make_pair(it->localName().impl(), it->value()));
}
if (result.attributesAndValues.isEmpty())
return;
@@ -163,29 +164,28 @@ PassRefPtr<StylePropertySet> computePresentationAttributeStyle(Element& element)
unsigned cacheHash = computePresentationAttributeCacheHash(cacheKey);
- PresentationAttributeCache::iterator cacheIterator;
+ PresentationAttributeCache::ValueType* cacheValue;
if (cacheHash) {
- cacheIterator = presentationAttributeCache().add(cacheHash, nullptr).iterator;
- if (cacheIterator->value && cacheIterator->value->key != cacheKey)
+ cacheValue = presentationAttributeCache().add(cacheHash, nullptr).storedValue;
+ if (cacheValue->value && cacheValue->value->key != cacheKey)
cacheHash = 0;
} else {
- cacheIterator = presentationAttributeCache().end();
+ cacheValue = 0;
}
RefPtr<StylePropertySet> style;
- if (cacheHash && cacheIterator->value) {
- style = cacheIterator->value->value;
+ if (cacheHash && cacheValue->value) {
+ style = cacheValue->value->value;
cacheCleaner.didHitPresentationAttributeCache();
} else {
style = MutableStylePropertySet::create(element.isSVGElement() ? SVGAttributeMode : HTMLAttributeMode);
- unsigned size = element.attributeCount();
- for (unsigned i = 0; i < size; ++i) {
- const Attribute* attribute = element.attributeItem(i);
- element.collectStyleForPresentationAttribute(attribute->name(), attribute->value(), toMutableStylePropertySet(style));
- }
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it)
+ element.collectStyleForPresentationAttribute(it->name(), it->value(), toMutableStylePropertySet(style));
}
- if (!cacheHash || cacheIterator->value)
+ if (!cacheHash || cacheValue->value)
return style.release();
OwnPtr<PresentationAttributeCacheEntry> newEntry = adoptPtr(new PresentationAttributeCacheEntry);
@@ -199,7 +199,7 @@ PassRefPtr<StylePropertySet> computePresentationAttributeStyle(Element& element)
presentationAttributeCache().clear();
presentationAttributeCache().set(cacheHash, newEntry.release());
} else {
- cacheIterator->value = newEntry.release();
+ cacheValue->value = newEntry.release();
}
return style.release();
diff --git a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
index bd1bd7b02c6..bff917dafe5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.cpp
@@ -21,7 +21,7 @@
#include "config.h"
#include "core/dom/ProcessingInstruction.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/MediaList.h"
#include "core/css/StyleSheetContents.h"
@@ -48,18 +48,27 @@ inline ProcessingInstruction::ProcessingInstruction(Document& document, const St
ScriptWrappable::init(this);
}
-PassRefPtr<ProcessingInstruction> ProcessingInstruction::create(Document& document, const String& target, const String& data)
+PassRefPtrWillBeRawPtr<ProcessingInstruction> ProcessingInstruction::create(Document& document, const String& target, const String& data)
{
- return adoptRef(new ProcessingInstruction(document, target, data));
+ return adoptRefWillBeNoop(new ProcessingInstruction(document, target, data));
}
ProcessingInstruction::~ProcessingInstruction()
{
+#if !ENABLE(OILPAN)
if (m_sheet)
m_sheet->clearOwnerNode();
- if (inDocument())
- document().styleEngine()->removeStyleSheetCandidateNode(this);
+ // FIXME: ProcessingInstruction should not be in document here.
+ // However, if we add ASSERT(!inDocument()), fast/xsl/xslt-entity.xml
+ // crashes. We need to investigate ProcessingInstruction lifetime.
+ if (inDocument()) {
+ if (m_isCSS)
+ document().styleEngine()->removeStyleSheetCandidateNode(this);
+ else if (m_isXSL)
+ document().styleEngine()->removeXSLStyleSheet(this);
+ }
+#endif
}
String ProcessingInstruction::nodeName() const
@@ -72,77 +81,88 @@ Node::NodeType ProcessingInstruction::nodeType() const
return PROCESSING_INSTRUCTION_NODE;
}
-PassRefPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> ProcessingInstruction::cloneNode(bool /*deep*/)
{
// FIXME: Is it a problem that this does not copy m_localHref?
// What about other data members?
return create(document(), m_target, m_data);
}
-void ProcessingInstruction::checkStyleSheet()
+void ProcessingInstruction::didAttributeChanged()
{
- if (m_target == "xml-stylesheet" && document().frame() && parentNode() == document()) {
- // see http://www.w3.org/TR/xml-stylesheet/
- // ### support stylesheet included in a fragment of this (or another) document
- // ### make sure this gets called when adding from javascript
- bool attrsOk;
- const HashMap<String, String> attrs = parseAttributes(m_data, attrsOk);
- if (!attrsOk)
- return;
- HashMap<String, String>::const_iterator i = attrs.find("type");
- String type;
- if (i != attrs.end())
- type = i->value;
-
- m_isCSS = type.isEmpty() || type == "text/css";
- m_isXSL = (type == "text/xml" || type == "text/xsl" || type == "application/xml" ||
- type == "application/xhtml+xml" || type == "application/rss+xml" || type == "application/atom+xml");
- if (!m_isCSS && !m_isXSL)
- return;
-
- String href = attrs.get("href");
- String alternate = attrs.get("alternate");
- m_alternate = alternate == "yes";
- m_title = attrs.get("title");
- m_media = attrs.get("media");
-
- if (m_alternate && m_title.isEmpty())
- return;
-
- if (href.length() > 1 && href[0] == '#') {
- m_localHref = href.substring(1);
- // We need to make a synthetic XSLStyleSheet that is embedded. It needs to be able
- // to kick off import/include loads that can hang off some parent sheet.
- if (m_isXSL) {
- KURL finalURL(ParsedURLString, m_localHref);
- m_sheet = XSLStyleSheet::createEmbedded(this, finalURL);
- m_loading = false;
- }
- } else {
- clearResource();
-
- String url = document().completeURL(href).string();
- if (!dispatchBeforeLoadEvent(url))
- return;
-
- ResourcePtr<StyleSheetResource> resource;
- FetchRequest request(ResourceRequest(document().completeURL(href)), FetchInitiatorTypeNames::processinginstruction);
- if (m_isXSL) {
- resource = document().fetcher()->fetchXSLStyleSheet(request);
- } else {
- String charset = attrs.get("charset");
- if (charset.isEmpty())
- charset = document().charset();
- request.setCharset(charset);
- resource = document().fetcher()->fetchCSSStyleSheet(request);
- }
-
- if (resource) {
- m_loading = true;
- document().styleEngine()->addPendingSheet();
- setResource(resource);
- }
+ ASSERT(!m_sheet);
+ ASSERT(!isLoading());
+ String href;
+ String charset;
+ if (!checkStyleSheet(href, charset))
+ return;
+ process(href, charset);
+}
+
+bool ProcessingInstruction::checkStyleSheet(String& href, String& charset)
+{
+ if (m_target != "xml-stylesheet" || !document().frame() || parentNode() != document())
+ return false;
+
+ // see http://www.w3.org/TR/xml-stylesheet/
+ // ### support stylesheet included in a fragment of this (or another) document
+ // ### make sure this gets called when adding from javascript
+ bool attrsOk;
+ const HashMap<String, String> attrs = parseAttributes(m_data, attrsOk);
+ if (!attrsOk)
+ return false;
+ HashMap<String, String>::const_iterator i = attrs.find("type");
+ String type;
+ if (i != attrs.end())
+ type = i->value;
+
+ m_isCSS = type.isEmpty() || type == "text/css";
+ m_isXSL = (type == "text/xml" || type == "text/xsl" || type == "application/xml" || type == "application/xhtml+xml" || type == "application/rss+xml" || type == "application/atom+xml");
+ if (!m_isCSS && !m_isXSL)
+ return false;
+
+ href = attrs.get("href");
+ charset = attrs.get("charset");
+ String alternate = attrs.get("alternate");
+ m_alternate = alternate == "yes";
+ m_title = attrs.get("title");
+ m_media = attrs.get("media");
+
+ return !m_alternate || !m_title.isEmpty();
+}
+
+void ProcessingInstruction::process(const String& href, const String& charset)
+{
+ if (href.length() > 1 && href[0] == '#') {
+ m_localHref = href.substring(1);
+ // We need to make a synthetic XSLStyleSheet that is embedded.
+ // It needs to be able to kick off import/include loads that
+ // can hang off some parent sheet.
+ if (m_isXSL) {
+ KURL finalURL(ParsedURLString, m_localHref);
+ m_sheet = XSLStyleSheet::createEmbedded(this, finalURL);
+ m_loading = false;
}
+ return;
+ }
+
+ clearResource();
+
+ String url = document().completeURL(href).string();
+
+ ResourcePtr<StyleSheetResource> resource;
+ FetchRequest request(ResourceRequest(document().completeURL(href)), FetchInitiatorTypeNames::processinginstruction);
+ if (m_isXSL) {
+ resource = document().fetcher()->fetchXSLStyleSheet(request);
+ } else {
+ request.setCharset(charset.isEmpty() ? document().charset() : charset);
+ resource = document().fetcher()->fetchCSSStyleSheet(request);
+ }
+
+ if (resource) {
+ m_loading = true;
+ document().styleEngine()->addPendingSheet();
+ setResource(resource);
}
}
@@ -172,11 +192,11 @@ void ProcessingInstruction::setCSSStyleSheet(const String& href, const KURL& bas
}
ASSERT(m_isCSS);
- CSSParserContext parserContext(document(), baseURL, charset);
+ CSSParserContext parserContext(document(), 0, baseURL, charset);
- RefPtr<StyleSheetContents> newSheet = StyleSheetContents::create(href, parserContext);
+ RefPtrWillBeRawPtr<StyleSheetContents> newSheet = StyleSheetContents::create(href, parserContext);
- RefPtr<CSSStyleSheet> cssSheet = CSSStyleSheet::create(newSheet, this);
+ RefPtrWillBeRawPtr<CSSStyleSheet> cssSheet = CSSStyleSheet::create(newSheet, this);
cssSheet->setDisabled(m_alternate);
cssSheet->setTitle(m_title);
cssSheet->setMediaQueries(MediaQuerySet::create(m_media));
@@ -212,7 +232,7 @@ void ProcessingInstruction::parseStyleSheet(const String& sheet)
toXSLStyleSheet(m_sheet.get())->checkLoaded();
}
-void ProcessingInstruction::setCSSStyleSheet(PassRefPtr<CSSStyleSheet> sheet)
+void ProcessingInstruction::setCSSStyleSheet(PassRefPtrWillBeRawPtr<CSSStyleSheet> sheet)
{
ASSERT(!resource());
ASSERT(!m_loading);
@@ -221,21 +241,21 @@ void ProcessingInstruction::setCSSStyleSheet(PassRefPtr<CSSStyleSheet> sheet)
sheet->setDisabled(m_alternate);
}
-void ProcessingInstruction::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- if (!sheet())
- return;
-
- addSubresourceURL(urls, sheet()->baseURL());
-}
-
Node::InsertionNotificationRequest ProcessingInstruction::insertedInto(ContainerNode* insertionPoint)
{
CharacterData::insertedInto(insertionPoint);
if (!insertionPoint->inDocument())
return InsertionDone;
- document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
- checkStyleSheet();
+
+ String href;
+ String charset;
+ bool isValid = checkStyleSheet(href, charset);
+ if (m_isCSS)
+ document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
+ else if (m_isXSL)
+ document().styleEngine()->addXSLStyleSheet(this, m_createdByParser);
+ if (isValid)
+ process(href, charset);
return InsertionDone;
}
@@ -245,14 +265,17 @@ void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint)
if (!insertionPoint->inDocument())
return;
- document().styleEngine()->removeStyleSheetCandidateNode(this);
+ if (m_isCSS)
+ document().styleEngine()->removeStyleSheetCandidateNode(this);
+ else if (m_isXSL)
+ document().styleEngine()->removeXSLStyleSheet(this);
- RefPtr<StyleSheet> removedSheet = m_sheet;
+ RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet;
if (m_sheet) {
ASSERT(m_sheet->ownerNode() == this);
m_sheet->clearOwnerNode();
- m_sheet = 0;
+ m_sheet = nullptr;
}
// If we're in document teardown, then we don't need to do any notification of our sheet's removal.
@@ -260,10 +283,10 @@ void ProcessingInstruction::removedFrom(ContainerNode* insertionPoint)
document().removedStyleSheet(removedSheet.get());
}
-void ProcessingInstruction::finishParsingChildren()
+void ProcessingInstruction::trace(Visitor* visitor)
{
- m_createdByParser = false;
- CharacterData::finishParsingChildren();
+ visitor->trace(m_sheet);
+ CharacterData::trace(visitor);
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
index 2dec480183e..60528e0e22a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ProcessingInstruction.h
@@ -34,42 +34,41 @@ class CSSStyleSheet;
class ProcessingInstruction FINAL : public CharacterData, private ResourceOwner<StyleSheetResource> {
public:
- static PassRefPtr<ProcessingInstruction> create(Document&, const String& target, const String& data);
+ static PassRefPtrWillBeRawPtr<ProcessingInstruction> create(Document&, const String& target, const String& data);
virtual ~ProcessingInstruction();
+ virtual void trace(Visitor*) OVERRIDE;
const String& target() const { return m_target; }
void setCreatedByParser(bool createdByParser) { m_createdByParser = createdByParser; }
- virtual void finishParsingChildren();
-
const String& localHref() const { return m_localHref; }
StyleSheet* sheet() const { return m_sheet.get(); }
- void setCSSStyleSheet(PassRefPtr<CSSStyleSheet>);
+ void setCSSStyleSheet(PassRefPtrWillBeRawPtr<CSSStyleSheet>);
bool isCSS() const { return m_isCSS; }
bool isXSL() const { return m_isXSL; }
+ void didAttributeChanged();
bool isLoading() const;
private:
- friend class CharacterData;
ProcessingInstruction(Document&, const String& target, const String& data);
- virtual String nodeName() const;
- virtual NodeType nodeType() const;
- virtual PassRefPtr<Node> cloneNode(bool deep = true);
+ virtual String nodeName() const OVERRIDE;
+ virtual NodeType nodeType() const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- void checkStyleSheet();
- virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*);
- virtual void setXSLStyleSheet(const String& href, const KURL& baseURL, const String& sheet);
+ bool checkStyleSheet(String& href, String& charset);
+ void process(const String& href, const String& charset);
- virtual bool sheetLoaded();
+ virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*) OVERRIDE;
+ virtual void setXSLStyleSheet(const String& href, const KURL& baseURL, const String& sheet) OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool sheetLoaded() OVERRIDE;
void parseStyleSheet(const String& sheet);
@@ -77,7 +76,7 @@ private:
String m_localHref;
String m_title;
String m_media;
- RefPtr<StyleSheet> m_sheet;
+ RefPtrWillBeMember<StyleSheet> m_sheet;
bool m_loading;
bool m_alternate;
bool m_createdByParser;
@@ -87,6 +86,11 @@ private:
DEFINE_NODE_TYPE_CASTS(ProcessingInstruction, nodeType() == Node::PROCESSING_INSTRUCTION_NODE);
+inline bool isXSLStyleSheet(const Node& node)
+{
+ return node.nodeType() == Node::PROCESSING_INSTRUCTION_NODE && toProcessingInstruction(node).isXSL();
+}
+
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/Promise.h b/chromium/third_party/WebKit/Source/core/dom/Promise.h
deleted file mode 100644
index 2c842aa4c11..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Promise.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// FIXME: This file should be deleted.
-#ifndef Promise_h
-#define Promise_h
-
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-// An empty class. This is here because a generated file use it.
-class Promise : public RefCounted<Promise> {
-};
-
-} // namespace WebCore
-
-
-#endif // Promise_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/Promise.idl b/chromium/third_party/WebKit/Source/core/dom/Promise.idl
deleted file mode 100644
index 45989d44d82..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Promise.idl
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-callback PromiseInit = void (any resolve, any reject);
-callback AnyCallback = any (optional any value);
-[
- CustomConstructor(PromiseInit init),
- GlobalContext=Window&WorkerGlobalScope,
-] interface Promise {
- [Custom] Promise then(optional AnyCallback fulfillCallback, optional AnyCallback rejectCallback);
- [Custom] Promise catch(optional AnyCallback rejectCallback);
-
- [Custom] static Promise resolve(any value);
- [Custom] static Promise reject(any value);
-
- [Custom] static Promise cast(any value);
- [Custom] static Promise race(any iterable);
- [Custom] static Promise all(any iterable);
-};
diff --git a/chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp b/chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp
index 9512d82defe..30535de0e3b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/PseudoElement.cpp
@@ -70,13 +70,15 @@ PassRefPtr<RenderStyle> PseudoElement::customStyleForRenderer()
void PseudoElement::dispose()
{
+ ASSERT(parentOrShadowHostElement());
+
InspectorInstrumentation::pseudoElementDestroyed(this);
ASSERT(!nextSibling());
ASSERT(!previousSibling());
detach();
- RefPtr<Element> parent = parentOrShadowHostElement();
+ RefPtrWillBeRawPtr<Element> parent = parentOrShadowHostElement();
setParentOrShadowHostNode(0);
removedFrom(parent.get());
}
@@ -91,8 +93,6 @@ void PseudoElement::attach(const AttachContext& context)
if (!renderer)
return;
RenderStyle* style = renderer->style();
- if (style->hasFlowFrom())
- return;
if (style->styleType() != BEFORE && style->styleType() != AFTER)
return;
ASSERT(style->contentData());
diff --git a/chromium/third_party/WebKit/Source/core/dom/PseudoElement.h b/chromium/third_party/WebKit/Source/core/dom/PseudoElement.h
index 6f109333e08..184eb9c537b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/PseudoElement.h
+++ b/chromium/third_party/WebKit/Source/core/dom/PseudoElement.h
@@ -29,25 +29,20 @@
#include "core/dom/Element.h"
#include "core/rendering/style/RenderStyle.h"
-#include "wtf/Forward.h"
namespace WebCore {
class PseudoElement FINAL : public Element {
public:
- static PassRefPtr<PseudoElement> create(Element* parent, PseudoId pseudoId)
+ static PassRefPtrWillBeRawPtr<PseudoElement> create(Element* parent, PseudoId pseudoId)
{
- return adoptRef(new PseudoElement(parent, pseudoId));
+ return adoptRefWillBeNoop(new PseudoElement(parent, pseudoId));
}
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
- // As per http://dev.w3.org/csswg/css3-regions/#flow-into, pseudo-elements such as ::first-line, ::first-letter, ::before or ::after
- // cannot be directly collected into a named flow.
- virtual bool shouldMoveToFlowThread(RenderStyle*) const OVERRIDE { return false; }
-
virtual bool canStartSelection() const OVERRIDE { return false; }
virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
@@ -68,10 +63,10 @@ const QualifiedName& pseudoElementTagName();
inline bool pseudoElementRendererIsNeeded(const RenderStyle* style)
{
- return style && style->display() != NONE && (style->styleType() == BACKDROP || style->contentData() || style->hasFlowFrom());
+ return style && style->display() != NONE && (style->styleType() == BACKDROP || style->contentData());
}
-DEFINE_NODE_TYPE_CASTS(PseudoElement, isPseudoElement());
+DEFINE_ELEMENT_TYPE_CASTS(PseudoElement, isPseudoElement());
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp b/chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp
index 1912986ead2..c447e8db0a1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/QualifiedName.cpp
@@ -25,12 +25,13 @@
#define QNAME_DEFAULT_CONSTRUCTOR
#endif
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-#include "XMLNSNames.h"
-#include "XMLNames.h"
#include "core/dom/QualifiedName.h"
+
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
+#include "core/XMLNSNames.h"
+#include "core/XMLNames.h"
#include "wtf/Assertions.h"
#include "wtf/HashSet.h"
#include "wtf/MainThread.h"
@@ -59,42 +60,39 @@ static QualifiedNameCache& qualifiedNameCache()
}
struct QNameComponentsTranslator {
- static unsigned hash(const QualifiedNameComponents& components)
+ static unsigned hash(const QualifiedNameData& data)
{
- return hashComponents(components);
+ return hashComponents(data.m_components);
}
- static bool equal(QualifiedName::QualifiedNameImpl* name, const QualifiedNameComponents& c)
+ static bool equal(QualifiedName::QualifiedNameImpl* name, const QualifiedNameData& data)
{
- return c.m_prefix == name->m_prefix.impl() && c.m_localName == name->m_localName.impl() && c.m_namespace == name->m_namespace.impl();
+ return data.m_components.m_prefix == name->m_prefix.impl()
+ && data.m_components.m_localName == name->m_localName.impl()
+ && data.m_components.m_namespace == name->m_namespace.impl();
}
- static void translate(QualifiedName::QualifiedNameImpl*& location, const QualifiedNameComponents& components, unsigned)
+ static void translate(QualifiedName::QualifiedNameImpl*& location, const QualifiedNameData& data, unsigned)
{
- location = QualifiedName::QualifiedNameImpl::create(AtomicString(components.m_prefix), AtomicString(components.m_localName), AtomicString(components.m_namespace)).leakRef();
+ const QualifiedNameComponents& components = data.m_components;
+ location = QualifiedName::QualifiedNameImpl::create(AtomicString(components.m_prefix), AtomicString(components.m_localName), AtomicString(components.m_namespace), data.m_isStatic).leakRef();
}
};
QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n)
{
- QualifiedNameComponents components = { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() };
- QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(components);
- m_impl = *addResult.iterator;
- if (!addResult.isNewEntry)
- m_impl->ref();
+ QualifiedNameData data = { { p.impl(), l.impl(), n.isEmpty() ? nullAtom.impl() : n.impl() }, false };
+ QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(data);
+ m_impl = addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.storedValue;
}
-QualifiedName::~QualifiedName()
+QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n, bool isStatic)
{
- deref();
+ QualifiedNameData data = { { p.impl(), l.impl(), n.impl() }, isStatic };
+ QualifiedNameCache::AddResult addResult = qualifiedNameCache().add<QNameComponentsTranslator>(data);
+ m_impl = addResult.isNewEntry ? adoptRef(*addResult.storedValue) : *addResult.storedValue;
}
-void QualifiedName::deref()
+QualifiedName::~QualifiedName()
{
-#ifdef QNAME_DEFAULT_CONSTRUCTOR
- if (!m_impl)
- return;
-#endif
- ASSERT(!isHashTableDeletedValue());
- m_impl->deref();
}
QualifiedName::QualifiedNameImpl::~QualifiedNameImpl()
@@ -116,12 +114,12 @@ DEFINE_GLOBAL(QualifiedName, anyName, nullAtom, starAtom, starAtom)
void QualifiedName::init()
{
ASSERT(starAtom.impl());
- new ((void*)&anyName) QualifiedName(nullAtom, starAtom, starAtom);
+ new ((void*)&anyName) QualifiedName(nullAtom, starAtom, starAtom, true );
}
-const QualifiedName& nullQName()
+const QualifiedName& QualifiedName::null()
{
- DEFINE_STATIC_LOCAL(QualifiedName, nullName, (nullAtom, nullAtom, nullAtom));
+ DEFINE_STATIC_LOCAL(QualifiedName, nullName, (nullAtom, nullAtom, nullAtom, true));
return nullName;
}
@@ -138,14 +136,14 @@ unsigned QualifiedName::QualifiedNameImpl::computeHash() const
return hashComponents(components);
}
-void createQualifiedName(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace)
+void QualifiedName::createStatic(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace)
{
- new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nameNamespace);
+ new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nameNamespace, true);
}
-void createQualifiedName(void* targetAddress, StringImpl* name)
+void QualifiedName::createStatic(void* targetAddress, StringImpl* name)
{
- new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nullAtom);
+ new (targetAddress) QualifiedName(nullAtom, AtomicString(name), nullAtom, true);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/QualifiedName.h b/chromium/third_party/WebKit/Source/core/dom/QualifiedName.h
index b42f9e45cd2..46d4ad8cd3a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/QualifiedName.h
+++ b/chromium/third_party/WebKit/Source/core/dom/QualifiedName.h
@@ -21,7 +21,6 @@
#ifndef QualifiedName_h
#define QualifiedName_h
-#include "wtf/Forward.h"
#include "wtf/HashTableDeletedValueType.h"
#include "wtf/HashTraits.h"
#include "wtf/RefCounted.h"
@@ -35,47 +34,80 @@ struct QualifiedNameComponents {
StringImpl* m_namespace;
};
+// This struct is used to pass data between QualifiedName and the QNameTranslator.
+// For hashing and equality only the QualifiedNameComponents fields are used.
+struct QualifiedNameData {
+ QualifiedNameComponents m_components;
+ bool m_isStatic;
+};
+
class QualifiedName {
WTF_MAKE_FAST_ALLOCATED;
public:
class QualifiedNameImpl : public RefCounted<QualifiedNameImpl> {
public:
- static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
+ static PassRefPtr<QualifiedNameImpl> create(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic)
{
- return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI));
+ return adoptRef(new QualifiedNameImpl(prefix, localName, namespaceURI, isStatic));
}
~QualifiedNameImpl();
unsigned computeHash() const;
- mutable unsigned m_existingHash;
+ bool hasOneRef() const
+ {
+ return m_isStatic || RefCounted<QualifiedNameImpl>::hasOneRef();
+ }
+
+ void ref()
+ {
+ if (m_isStatic)
+ return;
+ RefCounted<QualifiedNameImpl>::ref();
+ }
+
+ void deref()
+ {
+ if (m_isStatic)
+ return;
+ RefCounted<QualifiedNameImpl>::deref();
+ }
+
const AtomicString m_prefix;
const AtomicString m_localName;
const AtomicString m_namespace;
mutable AtomicString m_localNameUpper;
+ // We rely on StringHasher's hashMemory clearing out the top 8 bits when
+ // doing hashing and use one of the bits for the m_isStatic value.
+ mutable unsigned m_existingHash : 24;
+ unsigned m_isStatic : 1;
private:
- QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI)
- : m_existingHash(0)
- , m_prefix(prefix)
+ QualifiedNameImpl(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic)
+ : m_prefix(prefix)
, m_localName(localName)
, m_namespace(namespaceURI)
+ , m_existingHash(0)
+ , m_isStatic(isStatic)
+
{
ASSERT(!namespaceURI.isEmpty() || namespaceURI.isNull());
}
};
QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI);
- QualifiedName(WTF::HashTableDeletedValueType) : m_impl(hashTableDeletedValue()) { }
- bool isHashTableDeletedValue() const { return m_impl == hashTableDeletedValue(); }
~QualifiedName();
#ifdef QNAME_DEFAULT_CONSTRUCTOR
- QualifiedName() : m_impl(0) { }
+ QualifiedName() { }
#endif
- QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { ref(); }
- const QualifiedName& operator=(const QualifiedName& other) { other.ref(); deref(); m_impl = other.m_impl; return *this; }
+ QualifiedName(const QualifiedName& other) : m_impl(other.m_impl) { }
+ const QualifiedName& operator=(const QualifiedName& other) { m_impl = other.m_impl; return *this; }
+
+ // Hash table deleted values, which are only constructed and never copied or destroyed.
+ QualifiedName(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { }
+ bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); }
bool operator==(const QualifiedName& other) const { return m_impl == other.m_impl; }
bool operator!=(const QualifiedName& other) const { return !(*this == other); }
@@ -96,18 +128,22 @@ public:
String toString() const;
- QualifiedNameImpl* impl() const { return m_impl; }
+ QualifiedNameImpl* impl() const { return m_impl.get(); }
// Init routine for globals
static void init();
-private:
- void ref() const { m_impl->ref(); }
- void deref();
+ static const QualifiedName& null();
- static QualifiedNameImpl* hashTableDeletedValue() { return RefPtr<QualifiedNameImpl>::hashTableDeletedValue(); }
+ // The below methods are only for creating static global QNames that need no ref counting.
+ static void createStatic(void* targetAddress, StringImpl* name);
+ static void createStatic(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace);
- QualifiedNameImpl* m_impl;
+private:
+ // This constructor is used only to create global/static QNames that don't require any ref counting.
+ QualifiedName(const AtomicString& prefix, const AtomicString& localName, const AtomicString& namespaceURI, bool isStatic);
+
+ RefPtr<QualifiedNameImpl> m_impl;
};
#ifndef WEBCORE_QUALIFIEDNAME_HIDE_GLOBALS
@@ -115,8 +151,6 @@ extern const QualifiedName anyName;
inline const QualifiedName& anyQName() { return anyName; }
#endif
-const QualifiedName& nullQName();
-
inline bool operator==(const AtomicString& a, const QualifiedName& q) { return a == q.localName(); }
inline bool operator!=(const AtomicString& a, const QualifiedName& q) { return a != q.localName(); }
inline bool operator==(const QualifiedName& q, const AtomicString& a) { return a == q.localName(); }
@@ -143,9 +177,6 @@ struct QualifiedNameHash {
static const bool safeToCompareToEmptyOrDeleted = false;
};
-void createQualifiedName(void* targetAddress, StringImpl* name);
-void createQualifiedName(void* targetAddress, StringImpl* name, const AtomicString& nameNamespace);
-
}
namespace WTF {
@@ -158,7 +189,7 @@ namespace WTF {
template<> struct HashTraits<WebCore::QualifiedName> : SimpleClassHashTraits<WebCore::QualifiedName> {
static const bool emptyValueIsZero = false;
- static WebCore::QualifiedName emptyValue() { return WebCore::nullQName(); }
+ static WebCore::QualifiedName emptyValue() { return WebCore::QualifiedName::null(); }
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/Range.cpp b/chromium/third_party/WebKit/Source/core/dom/Range.cpp
index 5b75ea2bab4..af875e7afd1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Range.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Range.cpp
@@ -25,7 +25,6 @@
#include "config.h"
#include "core/dom/Range.h"
-#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "core/dom/ClientRect.h"
#include "core/dom/ClientRectList.h"
@@ -35,12 +34,12 @@
#include "core/dom/NodeTraversal.h"
#include "core/dom/NodeWithIndex.h"
#include "core/dom/ProcessingInstruction.h"
-#include "core/events/ScopedEventQueue.h"
#include "core/dom/Text.h"
#include "core/editing/TextIterator.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/markup.h"
+#include "core/events/ScopedEventQueue.h"
#include "core/html/HTMLElement.h"
#include "core/rendering/RenderBoxModelObject.h"
#include "core/rendering/RenderText.h"
@@ -54,7 +53,6 @@
namespace WebCore {
-using namespace std;
using namespace HTMLNames;
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, rangeCounter, ("Range"));
@@ -72,9 +70,9 @@ inline Range::Range(Document& ownerDocument)
m_ownerDocument->attachRange(this);
}
-PassRefPtr<Range> Range::create(Document& ownerDocument)
+PassRefPtrWillBeRawPtr<Range> Range::create(Document& ownerDocument)
{
- return adoptRef(new Range(ownerDocument));
+ return adoptRefWillBeNoop(new Range(ownerDocument));
}
inline Range::Range(Document& ownerDocument, Node* startContainer, int startOffset, Node* endContainer, int endOffset)
@@ -95,20 +93,22 @@ inline Range::Range(Document& ownerDocument, Node* startContainer, int startOffs
setEnd(endContainer, endOffset);
}
-PassRefPtr<Range> Range::create(Document& ownerDocument, Node* startContainer, int startOffset, Node* endContainer, int endOffset)
+PassRefPtrWillBeRawPtr<Range> Range::create(Document& ownerDocument, Node* startContainer, int startOffset, Node* endContainer, int endOffset)
{
- return adoptRef(new Range(ownerDocument, startContainer, startOffset, endContainer, endOffset));
+ return adoptRefWillBeNoop(new Range(ownerDocument, startContainer, startOffset, endContainer, endOffset));
}
-PassRefPtr<Range> Range::create(Document& ownerDocument, const Position& start, const Position& end)
+PassRefPtrWillBeRawPtr<Range> Range::create(Document& ownerDocument, const Position& start, const Position& end)
{
- return adoptRef(new Range(ownerDocument, start.containerNode(), start.computeOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode()));
+ return adoptRefWillBeNoop(new Range(ownerDocument, start.containerNode(), start.computeOffsetInContainerNode(), end.containerNode(), end.computeOffsetInContainerNode()));
}
Range::~Range()
{
+#if !ENABLE(OILPAN)
// Always detach (even if we've already detached) to fix https://bugs.webkit.org/show_bug.cgi?id=26044
m_ownerDocument->detachRange(this);
+#endif
#ifndef NDEBUG
rangeCounter.decrement();
@@ -121,58 +121,13 @@ void Range::setDocument(Document& document)
ASSERT(m_ownerDocument);
m_ownerDocument->detachRange(this);
m_ownerDocument = &document;
- m_start.setToStartOfNode(&document);
- m_end.setToStartOfNode(&document);
+ m_start.setToStartOfNode(document);
+ m_end.setToStartOfNode(document);
m_ownerDocument->attachRange(this);
}
-Node* Range::startContainer(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_start.container();
-}
-
-int Range::startOffset(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_start.offset();
-}
-
-Node* Range::endContainer(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_end.container();
-}
-
-int Range::endOffset(ExceptionState& exceptionState) const
+Node* Range::commonAncestorContainer() const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_end.offset();
-}
-
-Node* Range::commonAncestorContainer(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
return commonAncestorContainer(m_start.container(), m_end.container());
}
@@ -187,16 +142,6 @@ Node* Range::commonAncestorContainer(Node* containerA, Node* containerB)
return 0;
}
-bool Range::collapsed(ExceptionState& exceptionState) const
-{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
- return m_start == m_end;
-}
-
static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& start, const RangeBoundaryPoint& end)
{
Node* endRootContainer = end.container();
@@ -209,15 +154,10 @@ static inline bool checkForDifferentRootContainer(const RangeBoundaryPoint& star
return startRootContainer != endRootContainer || (Range::compareBoundaryPoints(start, end, ASSERT_NO_EXCEPTION) > 0);
}
-void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionState& exceptionState)
+void Range::setStart(PassRefPtrWillBeRawPtr<Node> refNode, int offset, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
return;
}
@@ -234,18 +174,13 @@ void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionState& excep
m_start.set(refNode, offset, childNode);
if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end))
- collapse(true, exceptionState);
+ collapse(true);
}
-void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& exceptionState)
+void Range::setEnd(PassRefPtrWillBeRawPtr<Node> refNode, int offset, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
return;
}
@@ -262,7 +197,7 @@ void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& excepti
m_end.set(refNode, offset, childNode);
if (didMoveDocument || checkForDifferentRootContainer(m_start, m_end))
- collapse(false, exceptionState);
+ collapse(false);
}
void Range::setStart(const Position& start, ExceptionState& exceptionState)
@@ -277,13 +212,8 @@ void Range::setEnd(const Position& end, ExceptionState& exceptionState)
setEnd(parentAnchored.containerNode(), parentAnchored.offsetInContainerNode(), exceptionState);
}
-void Range::collapse(bool toStart, ExceptionState& exceptionState)
+void Range::collapse(bool toStart)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (toStart)
m_end = m_start;
else
@@ -292,13 +222,8 @@ void Range::collapse(bool toStart, ExceptionState& exceptionState)
bool Range::isPointInRange(Node* refNode, int offset, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return false;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided was null.");
return false;
}
@@ -320,18 +245,18 @@ short Range::comparePoint(Node* refNode, int offset, ExceptionState& exceptionSt
// This method returns -1, 0 or 1 depending on if the point described by the
// refNode node and an offset within the node is before, same as, or after the range respectively.
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+ if (!refNode) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided was null.");
return 0;
}
- if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ if (!refNode->inActiveDocument()) {
+ exceptionState.throwDOMException(WrongDocumentError, "The node provided is not in an active document.");
return 0;
}
- if (!refNode->inActiveDocument() || refNode->document() != m_ownerDocument) {
- exceptionState.throwUninformativeAndGenericDOMException(WrongDocumentError);
+ if (refNode->document() != m_ownerDocument) {
+ exceptionState.throwDOMException(WrongDocumentError, "The node provided is not in this Range's Document.");
return 0;
}
@@ -361,16 +286,11 @@ Range::CompareResults Range::compareNode(Node* refNode, ExceptionState& exceptio
// before and after(surrounds), or inside the range, respectively
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
return NODE_BEFORE;
}
- if (!m_start.container() && refNode->inActiveDocument()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return NODE_BEFORE;
- }
-
- if (m_start.container() && !refNode->inActiveDocument()) {
+ if (!refNode->inActiveDocument()) {
// Firefox doesn't throw an exception for this case; it returns 0.
return NODE_BEFORE;
}
@@ -386,7 +306,7 @@ Range::CompareResults Range::compareNode(Node* refNode, ExceptionState& exceptio
if (!parentNode) {
// if the node is the top document we should return NODE_BEFORE_AND_AFTER
// but we throw to match firefox behavior
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The provided node has no parent.");
return NODE_BEFORE;
}
@@ -403,25 +323,15 @@ Range::CompareResults Range::compareNode(Node* refNode, ExceptionState& exceptio
short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, ExceptionState& exceptionState) const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
if (!sourceRange) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The source range provided was null.");
return 0;
}
- Node* thisCont = commonAncestorContainer(exceptionState);
- if (exceptionState.hadException())
- return 0;
- Node* sourceCont = sourceRange->commonAncestorContainer(exceptionState);
- if (exceptionState.hadException())
- return 0;
-
+ Node* thisCont = commonAncestorContainer();
+ Node* sourceCont = sourceRange->commonAncestorContainer();
if (thisCont->document() != sourceCont->document()) {
- exceptionState.throwUninformativeAndGenericDOMException(WrongDocumentError);
+ exceptionState.throwDOMException(WrongDocumentError, "The source range is in a different document than this range.");
return 0;
}
@@ -432,7 +342,7 @@ short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
while (sourceTop->parentNode())
sourceTop = sourceTop->parentNode();
if (thisTop != sourceTop) { // in different DocumentFragments
- exceptionState.throwUninformativeAndGenericDOMException(WrongDocumentError);
+ exceptionState.throwDOMException(WrongDocumentError, "The source range is in a different document than this range.");
return 0;
}
@@ -447,7 +357,7 @@ short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, Exc
return compareBoundaryPoints(m_start, sourceRange->m_end, exceptionState);
}
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The comparison method provided must be one of 'START_TO_START', 'START_TO_END', 'END_TO_END', or 'END_TO_START'.");
return 0;
}
@@ -513,7 +423,7 @@ short Range::compareBoundaryPoints(Node* containerA, int offsetA, Node* containe
// ### we need to do a traversal here instead
Node* commonAncestor = commonAncestorContainer(containerA, containerB);
if (!commonAncestor) {
- exceptionState.throwUninformativeAndGenericDOMException(WrongDocumentError);
+ exceptionState.throwDOMException(WrongDocumentError, "The two ranges are in separate documents.");
return 0;
}
Node* childA = containerA;
@@ -552,7 +462,7 @@ short Range::compareBoundaryPoints(const RangeBoundaryPoint& boundaryA, const Ra
bool Range::boundaryPointsValid() const
{
TrackExceptionState exceptionState;
- return m_start.container() && compareBoundaryPoints(m_start, m_end, exceptionState) <= 0 && !exceptionState.hadException();
+ return compareBoundaryPoints(m_start, m_end, exceptionState) <= 0 && !exceptionState.hadException();
}
void Range::deleteContents(ExceptionState& exceptionState)
@@ -561,21 +471,18 @@ void Range::deleteContents(ExceptionState& exceptionState)
if (exceptionState.hadException())
return;
- processContents(DELETE_CONTENTS, exceptionState);
+ {
+ EventQueueScope eventQueueScope;
+ processContents(DELETE_CONTENTS, exceptionState);
+ }
}
bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState)
{
// http://developer.mozilla.org/en/docs/DOM:range.intersectsNode
// Returns a bool if the node intersects the range.
-
- // Throw exception if the range is already detached.
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return false;
- }
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return false;
}
@@ -590,7 +497,7 @@ bool Range::intersectsNode(Node* refNode, ExceptionState& exceptionState)
if (!parentNode) {
// if the node is the top document we should return NODE_BEFORE_AND_AFTER
// but we throw to match firefox behavior
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided has no parent.");
return false;
}
@@ -640,46 +547,18 @@ static inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offs
return container;
}
-static inline unsigned lengthOfContentsInNode(Node* node)
-{
- // This switch statement must be consistent with that of Range::processContentsBetweenOffsets.
- switch (node->nodeType()) {
- case Node::TEXT_NODE:
- case Node::CDATA_SECTION_NODE:
- case Node::COMMENT_NODE:
- return toCharacterData(node)->length();
- case Node::PROCESSING_INSTRUCTION_NODE:
- return toProcessingInstruction(node)->data().length();
- case Node::ELEMENT_NODE:
- case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
- case Node::DOCUMENT_NODE:
- case Node::DOCUMENT_TYPE_NODE:
- case Node::DOCUMENT_FRAGMENT_NODE:
- case Node::NOTATION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- return node->childNodeCount();
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-PassRefPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> Range::processContents(ActionType action, ExceptionState& exceptionState)
{
- typedef Vector<RefPtr<Node> > NodeVector;
+ typedef WillBeHeapVector<RefPtrWillBeMember<Node> > NodeVector;
- RefPtr<DocumentFragment> fragment;
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = nullptr;
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS)
fragment = DocumentFragment::create(*m_ownerDocument.get());
- if (collapsed(exceptionState))
+ if (collapsed())
return fragment.release();
- if (exceptionState.hadException())
- return 0;
- RefPtr<Node> commonRoot = commonAncestorContainer(exceptionState);
- if (exceptionState.hadException())
- return 0;
+ RefPtrWillBeRawPtr<Node> commonRoot = commonAncestorContainer();
ASSERT(commonRoot);
if (m_start.container() == m_end.container()) {
@@ -692,8 +571,8 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
RangeBoundaryPoint originalEnd(m_end);
// what is the highest node that partially selects the start / end of the range?
- RefPtr<Node> partialStart = highestAncestorUnderCommonRoot(originalStart.container(), commonRoot.get());
- RefPtr<Node> partialEnd = highestAncestorUnderCommonRoot(originalEnd.container(), commonRoot.get());
+ RefPtrWillBeRawPtr<Node> partialStart = highestAncestorUnderCommonRoot(originalStart.container(), commonRoot.get());
+ RefPtrWillBeRawPtr<Node> partialEnd = highestAncestorUnderCommonRoot(originalEnd.container(), commonRoot.get());
// Start and end containers are different.
// There are three possibilities here:
@@ -715,23 +594,23 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
// Note that we are verifying that our common root hierarchy is still intact
// after any DOM mutation event, at various stages below. See webkit bug 60350.
- RefPtr<Node> leftContents;
+ RefPtrWillBeRawPtr<Node> leftContents = nullptr;
if (originalStart.container() != commonRoot && commonRoot->contains(originalStart.container())) {
- leftContents = processContentsBetweenOffsets(action, 0, originalStart.container(), originalStart.offset(), lengthOfContentsInNode(originalStart.container()), exceptionState);
+ leftContents = processContentsBetweenOffsets(action, nullptr, originalStart.container(), originalStart.offset(), originalStart.container()->lengthOfContents(), exceptionState);
leftContents = processAncestorsAndTheirSiblings(action, originalStart.container(), ProcessContentsForward, leftContents, commonRoot.get(), exceptionState);
}
- RefPtr<Node> rightContents;
+ RefPtrWillBeRawPtr<Node> rightContents = nullptr;
if (m_end.container() != commonRoot && commonRoot->contains(originalEnd.container())) {
- rightContents = processContentsBetweenOffsets(action, 0, originalEnd.container(), 0, originalEnd.offset(), exceptionState);
+ rightContents = processContentsBetweenOffsets(action, nullptr, originalEnd.container(), 0, originalEnd.offset(), exceptionState);
rightContents = processAncestorsAndTheirSiblings(action, originalEnd.container(), ProcessContentsBackward, rightContents, commonRoot.get(), exceptionState);
}
// delete all children of commonRoot between the start and end container
- RefPtr<Node> processStart = childOfCommonRootBeforeOffset(originalStart.container(), originalStart.offset(), commonRoot.get());
+ RefPtrWillBeRawPtr<Node> processStart = childOfCommonRootBeforeOffset(originalStart.container(), originalStart.offset(), commonRoot.get());
if (processStart && originalStart.container() != commonRoot) // processStart contains nodes before m_start.
processStart = processStart->nextSibling();
- RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(originalEnd.container(), originalEnd.offset(), commonRoot.get());
+ RefPtrWillBeRawPtr<Node> processEnd = childOfCommonRootBeforeOffset(originalEnd.container(), originalEnd.offset(), commonRoot.get());
// Collapse the range, making sure that the result is not within a node that was partially selected.
if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) {
@@ -745,7 +624,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), exceptionState);
}
if (exceptionState.hadException())
- return 0;
+ return nullptr;
m_end = m_start;
}
@@ -771,7 +650,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception
return fragment.release();
}
-static inline void deleteCharacterData(PassRefPtr<CharacterData> data, unsigned startOffset, unsigned endOffset, ExceptionState& exceptionState)
+static inline void deleteCharacterData(PassRefPtrWillBeRawPtr<CharacterData> data, unsigned startOffset, unsigned endOffset, ExceptionState& exceptionState)
{
if (data->length() - endOffset)
data->deleteData(endOffset, data->length() - endOffset, exceptionState);
@@ -779,21 +658,21 @@ static inline void deleteCharacterData(PassRefPtr<CharacterData> data, unsigned
data->deleteData(0, startOffset, exceptionState);
}
-PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRefPtr<DocumentFragment> fragment,
+PassRefPtrWillBeRawPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRefPtrWillBeRawPtr<DocumentFragment> fragment,
Node* container, unsigned startOffset, unsigned endOffset, ExceptionState& exceptionState)
{
ASSERT(container);
ASSERT(startOffset <= endOffset);
- // This switch statement must be consistent with that of lengthOfContentsInNode.
- RefPtr<Node> result;
+ // This switch statement must be consistent with that of Node::lengthOfContents.
+ RefPtrWillBeRawPtr<Node> result = nullptr;
switch (container->nodeType()) {
case Node::TEXT_NODE:
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
endOffset = std::min(endOffset, toCharacterData(container)->length());
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true));
+ RefPtrWillBeRawPtr<CharacterData> c = static_pointer_cast<CharacterData>(container->cloneNode(true));
deleteCharacterData(c, startOffset, endOffset, exceptionState);
if (fragment) {
result = fragment;
@@ -807,7 +686,7 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef
case Node::PROCESSING_INSTRUCTION_NODE:
endOffset = std::min(endOffset, toProcessingInstruction(container)->data().length());
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- RefPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true));
+ RefPtrWillBeRawPtr<ProcessingInstruction> c = static_pointer_cast<ProcessingInstruction>(container->cloneNode(true));
c->setData(c->data().substring(startOffset, endOffset - startOffset));
if (fragment) {
result = fragment;
@@ -824,12 +703,9 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef
break;
case Node::ELEMENT_NODE:
case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
case Node::DOCUMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
- case Node::NOTATION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
// FIXME: Should we assert that some nodes never appear here?
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
if (fragment)
@@ -839,7 +715,7 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef
}
Node* n = container->firstChild();
- Vector<RefPtr<Node> > nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > nodes;
for (unsigned i = startOffset; n && i; i--)
n = n->nextSibling();
for (unsigned i = startOffset; n && i < endOffset; i++, n = n->nextSibling())
@@ -852,7 +728,7 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef
return result.release();
}
-void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionState& exceptionState)
+void Range::processNodes(ActionType action, WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes, PassRefPtrWillBeRawPtr<Node> oldContainer, PassRefPtrWillBeRawPtr<Node> newContainer, ExceptionState& exceptionState)
{
for (unsigned i = 0; i < nodes.size(); i++) {
switch (action) {
@@ -869,20 +745,20 @@ void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRe
}
}
-PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node* container, ContentsProcessDirection direction, PassRefPtr<Node> passedClonedContainer, Node* commonRoot, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node* container, ContentsProcessDirection direction, PassRefPtrWillBeRawPtr<Node> passedClonedContainer, Node* commonRoot, ExceptionState& exceptionState)
{
- typedef Vector<RefPtr<Node> > NodeVector;
+ typedef WillBeHeapVector<RefPtrWillBeMember<Node> > NodeVector;
- RefPtr<Node> clonedContainer = passedClonedContainer;
- Vector<RefPtr<Node> > ancestors;
+ RefPtrWillBeRawPtr<Node> clonedContainer = passedClonedContainer;
+ NodeVector ancestors;
for (ContainerNode* n = container->parentNode(); n && n != commonRoot; n = n->parentNode())
ancestors.append(n);
- RefPtr<Node> firstChildInAncestorToProcess = direction == ProcessContentsForward ? container->nextSibling() : container->previousSibling();
- for (Vector<RefPtr<Node> >::const_iterator it = ancestors.begin(); it != ancestors.end(); it++) {
- RefPtr<Node> ancestor = *it;
+ RefPtrWillBeRawPtr<Node> firstChildInAncestorToProcess = direction == ProcessContentsForward ? container->nextSibling() : container->previousSibling();
+ for (NodeVector::const_iterator it = ancestors.begin(); it != ancestors.end(); ++it) {
+ RefPtrWillBeRawPtr<Node> ancestor = *it;
if (action == EXTRACT_CONTENTS || action == CLONE_CONTENTS) {
- if (RefPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // Might have been removed already during mutation event.
+ if (RefPtrWillBeRawPtr<Node> clonedAncestor = ancestor->cloneNode(false)) { // Might have been removed already during mutation event.
clonedAncestor->appendChild(clonedContainer, exceptionState);
clonedContainer = clonedAncestor;
}
@@ -898,11 +774,14 @@ PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node
child = (direction == ProcessContentsForward) ? child->nextSibling() : child->previousSibling())
nodes.append(child);
- for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); it++) {
+ for (NodeVector::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
Node* child = it->get();
switch (action) {
case DELETE_CONTENTS:
- ancestor->removeChild(child, exceptionState);
+ // Prior call of ancestor->removeChild() may cause a tree change due to DOMSubtreeModified event.
+ // Therefore, we need to make sure |ancestor| is still |child|'s parent.
+ if (ancestor == child->parentNode())
+ ancestor->removeChild(child, exceptionState);
break;
case EXTRACT_CONTENTS: // will remove child from ancestor
if (direction == ProcessContentsForward)
@@ -924,36 +803,26 @@ PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node
return clonedContainer.release();
}
-PassRefPtr<DocumentFragment> Range::extractContents(ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> Range::extractContents(ExceptionState& exceptionState)
{
checkDeleteExtract(exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
return processContents(EXTRACT_CONTENTS, exceptionState);
}
-PassRefPtr<DocumentFragment> Range::cloneContents(ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> Range::cloneContents(ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
return processContents(CLONE_CONTENTS, exceptionState);
}
-void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionState)
+void Range::insertNode(PassRefPtrWillBeRawPtr<Node> prpNewNode, ExceptionState& exceptionState)
{
- RefPtr<Node> newNode = prpNewNode;
-
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
+ RefPtrWillBeRawPtr<Node> newNode = prpNewNode;
if (!newNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -963,7 +832,7 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
// an extra one here - if a text node is going to split, it must have a parent to insert into
bool startIsText = m_start.container()->isTextNode();
if (startIsText && !m_start.container()->parentNode()) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "This operation would split a text node, but there's no parent into which to insert.");
return;
}
@@ -980,9 +849,9 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
if (newNodeType == Node::DOCUMENT_FRAGMENT_NODE && !newNode->isShadowRoot()) {
// check each child node, not the DocumentFragment itself
numNewChildren = 0;
- for (Node* c = newNode->firstChild(); c; c = c->nextSibling()) {
+ for (Node* c = toDocumentFragment(newNode)->firstChild(); c; c = c->nextSibling()) {
if (!checkAgainst->childTypeAllowed(c->nodeType())) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node to be inserted contains a '" + c->nodeName() + "' node, which may not be inserted here.");
return;
}
++numNewChildren;
@@ -990,14 +859,14 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
} else {
numNewChildren = 1;
if (!checkAgainst->childTypeAllowed(newNodeType)) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node to be inserted is a '" + newNode->nodeName() + "' node, which may not be inserted here.");
return;
}
}
for (Node* n = m_start.container(); n; n = n->parentNode()) {
if (n == newNode) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node to be inserted contains the insertion point; it may not be inserted into itself.");
return;
}
}
@@ -1005,14 +874,12 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
// InvalidNodeTypeError: Raised if newNode is an Attr, Entity, Notation, ShadowRoot or Document node.
switch (newNodeType) {
case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
case Node::DOCUMENT_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node to be inserted is a '" + newNode->nodeName() + "' node, which may not be inserted here.");
return;
default:
if (newNode->isShadowRoot()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node to be inserted is a shadow root, which may not be inserted here.");
return;
}
break;
@@ -1020,10 +887,10 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
EventQueueScope scope;
bool collapsed = m_start == m_end;
- RefPtr<Node> container;
+ RefPtrWillBeRawPtr<Node> container = nullptr;
if (startIsText) {
container = m_start.container();
- RefPtr<Text> newText = toText(container)->splitText(m_start.offset(), exceptionState);
+ RefPtrWillBeRawPtr<Text> newText = toText(container)->splitText(m_start.offset(), exceptionState);
if (exceptionState.hadException())
return;
@@ -1035,18 +902,18 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
if (collapsed)
m_end.setToBeforeChild(*newText);
} else {
- RefPtr<Node> lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->lastChild() : newNode;
+ RefPtrWillBeRawPtr<Node> lastChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? toDocumentFragment(newNode)->lastChild() : newNode.get();
if (lastChild && lastChild == m_start.childBefore()) {
// The insertion will do nothing, but we need to extend the range to include
// the inserted nodes.
- Node* firstChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? newNode->firstChild() : newNode.get();
+ Node* firstChild = (newNodeType == Node::DOCUMENT_FRAGMENT_NODE) ? toDocumentFragment(newNode)->firstChild() : newNode.get();
ASSERT(firstChild);
m_start.setToBeforeChild(*firstChild);
return;
}
container = m_start.container();
- container->insertBefore(newNode.release(), container->childNode(m_start.offset()), exceptionState);
+ container->insertBefore(newNode.release(), container->traverseToChildAt(m_start.offset()), exceptionState);
if (exceptionState.hadException())
return;
@@ -1057,22 +924,18 @@ void Range::insertNode(PassRefPtr<Node> prpNewNode, ExceptionState& exceptionSta
}
}
-String Range::toString(ExceptionState& exceptionState) const
+String Range::toString() const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return String();
- }
-
StringBuilder builder;
Node* pastLast = pastLastNode();
for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) {
- if (n->nodeType() == Node::TEXT_NODE || n->nodeType() == Node::CDATA_SECTION_NODE) {
+ Node::NodeType type = n->nodeType();
+ if (type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE) {
String data = toCharacterData(n)->data();
int length = data.length();
- int start = (n == m_start.container()) ? min(max(0, m_start.offset()), length) : 0;
- int end = (n == m_end.container()) ? min(max(start, m_end.offset()), length) : length;
+ int start = (n == m_start.container()) ? std::min(std::max(0, m_start.offset()), length) : 0;
+ int end = (n == m_end.container()) ? std::min(std::max(start, m_end.offset()), length) : length;
builder.append(data, start, end - start);
}
}
@@ -1087,79 +950,59 @@ String Range::toHTML() const
String Range::text() const
{
- if (!m_start.container())
- return String();
-
// We need to update layout, since plainText uses line boxes in the render tree.
// FIXME: As with innerText, we'd like this to work even if there are no render objects.
m_start.container()->document().updateLayout();
- return plainText(this);
+ return plainText(this, TextIteratorEmitsObjectReplacementCharacter);
}
-PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
Node* element = m_start.container()->isElementNode() ? m_start.container() : m_start.container()->parentNode();
if (!element || !element->isHTMLElement()) {
exceptionState.throwDOMException(NotSupportedError, "The range's container must be an HTML element.");
- return 0;
+ return nullptr;
}
- RefPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState);
if (!fragment)
- return 0;
+ return nullptr;
return fragment.release();
}
-void Range::detach(ExceptionState& exceptionState)
+void Range::detach()
{
- // Check first to see if we've already detached:
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
- m_ownerDocument->detachRange(this);
-
- m_start.clear();
- m_end.clear();
+ // This is now a no-op as per the DOM specification.
}
Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionState& exceptionState) const
{
switch (n->nodeType()) {
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + n->nodeName() + "'.");
return 0;
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
case Node::TEXT_NODE:
if (static_cast<unsigned>(offset) > toCharacterData(n)->length())
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is larger than or equal to the node's length (" + String::number(toCharacterData(n)->length()) + ").");
return 0;
case Node::PROCESSING_INSTRUCTION_NODE:
if (static_cast<unsigned>(offset) > toProcessingInstruction(n)->data().length())
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is larger than or equal to than the node's length (" + String::number(toProcessingInstruction(n)->data().length()) + ").");
return 0;
case Node::ATTRIBUTE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
case Node::DOCUMENT_NODE:
- case Node::ELEMENT_NODE:
- case Node::XPATH_NAMESPACE_NODE: {
+ case Node::ELEMENT_NODE: {
if (!offset)
return 0;
- Node* childBefore = n->childNode(offset - 1);
+ Node* childBefore = n->traverseToChildAt(offset - 1);
if (!childBefore)
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "There is no child at offset " + String::number(offset) + ".");
return childBefore;
}
}
@@ -1169,13 +1012,8 @@ Node* Range::checkNodeWOffset(Node* n, int offset, ExceptionState& exceptionStat
void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!n) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -1192,9 +1030,7 @@ void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
case Node::ATTRIBUTE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
case Node::DOCUMENT_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + n->nodeName() + "'.");
return;
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
@@ -1202,7 +1038,6 @@ void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
}
@@ -1219,23 +1054,15 @@ void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + n->nodeName() + "'.");
return;
}
}
-PassRefPtr<Range> Range::cloneRange(ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<Range> Range::cloneRange() const
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return 0;
- }
-
return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.offset(), m_end.container(), m_end.offset());
}
@@ -1268,13 +1095,8 @@ void Range::setEndAfter(Node* refNode, ExceptionState& exceptionState)
void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -1296,12 +1118,9 @@ void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided has an ancestor of type '" + anc->nodeName() + "'.");
return;
}
}
@@ -1313,14 +1132,11 @@ void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
case Node::ATTRIBUTE_NODE:
case Node::DOCUMENT_FRAGMENT_NODE:
case Node::DOCUMENT_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + refNode->nodeName() + "'.");
return;
}
@@ -1333,13 +1149,8 @@ void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
void Range::selectNodeContents(Node* refNode, ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
if (!refNode) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -1355,12 +1166,9 @@ void Range::selectNodeContents(Node* refNode, ExceptionState& exceptionState)
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + refNode->nodeName() + "'.");
return;
}
}
@@ -1368,21 +1176,15 @@ void Range::selectNodeContents(Node* refNode, ExceptionState& exceptionState)
if (m_ownerDocument != refNode->document())
setDocument(refNode->document());
- m_start.setToStartOfNode(refNode);
- m_end.setToEndOfNode(refNode);
+ m_start.setToStartOfNode(*refNode);
+ m_end.setToEndOfNode(*refNode);
}
-void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exceptionState)
+void Range::surroundContents(PassRefPtrWillBeRawPtr<Node> passNewParent, ExceptionState& exceptionState)
{
- RefPtr<Node> newParent = passNewParent;
-
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
-
+ RefPtrWillBeRawPtr<Node> newParent = passNewParent;
if (!newParent) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The node provided is null.");
return;
}
@@ -1393,16 +1195,13 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exc
case Node::DOCUMENT_FRAGMENT_NODE:
case Node::DOCUMENT_NODE:
case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The node provided is of type '" + newParent->nodeName() + "'.");
return;
case Node::CDATA_SECTION_NODE:
case Node::COMMENT_NODE:
case Node::ELEMENT_NODE:
case Node::PROCESSING_INSTRUCTION_NODE:
case Node::TEXT_NODE:
- case Node::XPATH_NAMESPACE_NODE:
break;
}
@@ -1414,13 +1213,19 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exc
// although this will fail below for another reason).
if (parentOfNewParent->isCharacterDataNode())
parentOfNewParent = parentOfNewParent->parentNode();
- if (!parentOfNewParent || !parentOfNewParent->childTypeAllowed(newParent->nodeType())) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+
+ if (!parentOfNewParent) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The container node is a detached character data node; no parent node is available for insertion.");
+ return;
+ }
+
+ if (!parentOfNewParent->childTypeAllowed(newParent->nodeType())) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided is of type '" + newParent->nodeName() + "', which may not be inserted here.");
return;
}
if (newParent->contains(m_start.container())) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ exceptionState.throwDOMException(HierarchyRequestError, "The node provided contains the insertion point; it may not be inserted into itself.");
return;
}
@@ -1435,7 +1240,7 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exc
if (endNonTextContainer->nodeType() == Node::TEXT_NODE)
endNonTextContainer = endNonTextContainer->parentNode();
if (startNonTextContainer != endNonTextContainer) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "The Range has partially selected a non-Text node.");
return;
}
@@ -1444,7 +1249,7 @@ void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exc
if (exceptionState.hadException())
return;
}
- RefPtr<DocumentFragment> fragment = extractContents(exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = extractContents(exceptionState);
if (exceptionState.hadException())
return;
insertNode(newParent, exceptionState);
@@ -1467,18 +1272,15 @@ void Range::setStartBefore(Node* refNode, ExceptionState& exceptionState)
void Range::checkDeleteExtract(ExceptionState& exceptionState)
{
- if (!m_start.container()) {
- exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
- return;
- }
+ ASSERT(boundaryPointsValid());
- if (!commonAncestorContainer(exceptionState) || exceptionState.hadException())
+ if (!commonAncestorContainer())
return;
Node* pastLast = pastLastNode();
for (Node* n = firstNode(); n != pastLast; n = NodeTraversal::next(*n)) {
- if (n->nodeType() == Node::DOCUMENT_TYPE_NODE) {
- exceptionState.throwUninformativeAndGenericDOMException(HierarchyRequestError);
+ if (n->isDocumentTypeNode()) {
+ exceptionState.throwDOMException(HierarchyRequestError, "The Range contains a doctype node.");
return;
}
}
@@ -1486,11 +1288,9 @@ void Range::checkDeleteExtract(ExceptionState& exceptionState)
Node* Range::firstNode() const
{
- if (!m_start.container())
- return 0;
if (m_start.container()->offsetInCharacters())
return m_start.container();
- if (Node* child = m_start.container()->childNode(m_start.offset()))
+ if (Node* child = m_start.container()->traverseToChildAt(m_start.offset()))
return child;
if (!m_start.offset())
return m_start.container();
@@ -1504,11 +1304,9 @@ ShadowRoot* Range::shadowRoot() const
Node* Range::pastLastNode() const
{
- if (!m_start.container() || !m_end.container())
- return 0;
if (m_end.container()->offsetInCharacters())
return NodeTraversal::nextSkippingChildren(*m_end.container());
- if (Node* child = m_end.container()->childNode(m_end.offset()))
+ if (Node* child = m_end.container()->traverseToChildAt(m_end.offset()))
return child;
return NodeTraversal::nextSkippingChildren(*m_end.container());
}
@@ -1527,13 +1325,9 @@ IntRect Range::boundingBox() const
void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFixedPosition* inFixed) const
{
Node* startContainer = m_start.container();
+ ASSERT(startContainer);
Node* endContainer = m_end.container();
-
- if (!startContainer || !endContainer) {
- if (inFixed)
- *inFixed = NotFixedPosition;
- return;
- }
+ ASSERT(endContainer);
bool allFixed = true;
bool someFixed = false;
@@ -1545,7 +1339,7 @@ void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFi
continue;
RenderText* renderText = toRenderText(r);
int startOffset = node == startContainer ? m_start.offset() : 0;
- int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
+ int endOffset = node == endContainer ? m_end.offset() : std::numeric_limits<int>::max();
bool isFixed = false;
renderText->absoluteRectsForRange(rects, startOffset, endOffset, useSelectionHeight, &isFixed);
allFixed &= isFixed;
@@ -1559,13 +1353,9 @@ void Range::textRects(Vector<IntRect>& rects, bool useSelectionHeight, RangeInFi
void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight, RangeInFixedPosition* inFixed) const
{
Node* startContainer = m_start.container();
+ ASSERT(startContainer);
Node* endContainer = m_end.container();
-
- if (!startContainer || !endContainer) {
- if (inFixed)
- *inFixed = NotFixedPosition;
- return;
- }
+ ASSERT(endContainer);
bool allFixed = true;
bool someFixed = false;
@@ -1577,7 +1367,7 @@ void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight, RangeIn
continue;
RenderText* renderText = toRenderText(r);
int startOffset = node == startContainer ? m_start.offset() : 0;
- int endOffset = node == endContainer ? m_end.offset() : numeric_limits<int>::max();
+ int endOffset = node == endContainer ? m_end.offset() : std::numeric_limits<int>::max();
bool isFixed = false;
renderText->absoluteQuadsForRange(quads, startOffset, endOffset, useSelectionHeight, &isFixed);
allFixed &= isFixed;
@@ -1592,24 +1382,19 @@ void Range::textQuads(Vector<FloatQuad>& quads, bool useSelectionHeight, RangeIn
void Range::formatForDebugger(char* buffer, unsigned length) const
{
StringBuilder result;
- String s;
-
- if (!m_start.container() || !m_end.container())
- result.appendLiteral("<empty>");
- else {
- const int FormatBufferSize = 1024;
- char s[FormatBufferSize];
- result.appendLiteral("from offset ");
- result.appendNumber(m_start.offset());
- result.appendLiteral(" of ");
- m_start.container()->formatForDebugger(s, FormatBufferSize);
- result.append(s);
- result.appendLiteral(" to offset ");
- result.appendNumber(m_end.offset());
- result.appendLiteral(" of ");
- m_end.container()->formatForDebugger(s, FormatBufferSize);
- result.append(s);
- }
+
+ const int FormatBufferSize = 1024;
+ char s[FormatBufferSize];
+ result.appendLiteral("from offset ");
+ result.appendNumber(m_start.offset());
+ result.appendLiteral(" of ");
+ m_start.container()->formatForDebugger(s, FormatBufferSize);
+ result.append(s);
+ result.appendLiteral(" to offset ");
+ result.appendNumber(m_end.offset());
+ result.appendLiteral(" of ");
+ m_end.container()->formatForDebugger(s, FormatBufferSize);
+ result.append(s);
strncpy(buffer, result.toString().utf8().data(), length - 1);
}
@@ -1624,32 +1409,14 @@ bool areRangesEqual(const Range* a, const Range* b)
return a->startPosition() == b->startPosition() && a->endPosition() == b->endPosition();
}
-PassRefPtr<Range> rangeOfContents(Node* node)
+PassRefPtrWillBeRawPtr<Range> rangeOfContents(Node* node)
{
ASSERT(node);
- RefPtr<Range> range = Range::create(node->document());
+ RefPtrWillBeRawPtr<Range> range = Range::create(node->document());
range->selectNodeContents(node, IGNORE_EXCEPTION);
return range.release();
}
-int Range::maxStartOffset() const
-{
- if (!m_start.container())
- return 0;
- if (!m_start.container()->offsetInCharacters())
- return m_start.container()->childNodeCount();
- return m_start.container()->maxCharacterOffset();
-}
-
-int Range::maxEndOffset() const
-{
- if (!m_end.container())
- return 0;
- if (!m_end.container()->offsetInCharacters())
- return m_end.container()->childNodeCount();
- return m_end.container()->maxCharacterOffset();
-}
-
static inline void boundaryNodeChildrenChanged(RangeBoundaryPoint& boundary, ContainerNode* container)
{
if (!boundary.childBefore())
@@ -1667,9 +1434,9 @@ void Range::nodeChildrenChanged(ContainerNode* container)
boundaryNodeChildrenChanged(m_end, container);
}
-static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode* container)
+static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode& container)
{
- for (Node* nodeToBeRemoved = container->firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
+ for (Node* nodeToBeRemoved = container.firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
if (boundary.childBefore() == nodeToBeRemoved) {
boundary.setToStartOfNode(container);
return;
@@ -1684,10 +1451,9 @@ static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundar
}
}
-void Range::nodeChildrenWillBeRemoved(ContainerNode* container)
+void Range::nodeChildrenWillBeRemoved(ContainerNode& container)
{
- ASSERT(container);
- ASSERT(container->document() == m_ownerDocument);
+ ASSERT(container.document() == m_ownerDocument);
boundaryNodeChildrenWillBeRemoved(m_start, container);
boundaryNodeChildrenWillBeRemoved(m_end, container);
}
@@ -1710,7 +1476,7 @@ static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node&
void Range::nodeWillBeRemoved(Node& node)
{
ASSERT(node.document() == m_ownerDocument);
- ASSERT(node != m_ownerDocument);
+ ASSERT(node != m_ownerDocument.get());
// FIXME: Once DOMNodeRemovedFromDocument mutation event removed, we
// should change following if-statement to ASSERT(!node->parentNode).
@@ -1759,46 +1525,58 @@ void Range::didRemoveText(Node* text, unsigned offset, unsigned length)
boundaryTextRemoved(m_end, text, offset, length);
}
-static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, NodeWithIndex& oldNode, unsigned offset)
+static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, const NodeWithIndex& oldNode, unsigned offset)
{
if (boundary.container() == oldNode.node())
- boundary.set(oldNode.node()->previousSibling(), boundary.offset() + offset, 0);
- else if (boundary.container() == oldNode.node()->parentNode() && boundary.offset() == oldNode.index())
- boundary.set(oldNode.node()->previousSibling(), offset, 0);
+ boundary.set(oldNode.node().previousSibling(), boundary.offset() + offset, 0);
+ else if (boundary.container() == oldNode.node().parentNode() && boundary.offset() == oldNode.index())
+ boundary.set(oldNode.node().previousSibling(), offset, 0);
}
-void Range::didMergeTextNodes(NodeWithIndex& oldNode, unsigned offset)
+void Range::didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset)
{
- ASSERT(oldNode.node());
- ASSERT(oldNode.node()->document() == m_ownerDocument);
- ASSERT(oldNode.node()->parentNode());
- ASSERT(oldNode.node()->isTextNode());
- ASSERT(oldNode.node()->previousSibling());
- ASSERT(oldNode.node()->previousSibling()->isTextNode());
+ ASSERT(oldNode.node().document() == m_ownerDocument);
+ ASSERT(oldNode.node().parentNode());
+ ASSERT(oldNode.node().isTextNode());
+ ASSERT(oldNode.node().previousSibling());
+ ASSERT(oldNode.node().previousSibling()->isTextNode());
boundaryTextNodesMerged(m_start, oldNode, offset);
boundaryTextNodesMerged(m_end, oldNode, offset);
}
-static inline void boundaryTextNodeSplit(RangeBoundaryPoint& boundary, Text* oldNode)
+void Range::updateOwnerDocumentIfNeeded()
{
- if (boundary.container() != oldNode)
+ ASSERT(m_start.container());
+ ASSERT(m_end.container());
+ Document& newDocument = m_start.container()->document();
+ ASSERT(newDocument == m_end.container()->document());
+ if (newDocument == m_ownerDocument)
return;
+ m_ownerDocument->detachRange(this);
+ m_ownerDocument = &newDocument;
+ m_ownerDocument->attachRange(this);
+}
+
+static inline void boundaryTextNodeSplit(RangeBoundaryPoint& boundary, Text& oldNode)
+{
+ Node* boundaryContainer = boundary.container();
unsigned boundaryOffset = boundary.offset();
- if (boundaryOffset <= oldNode->length())
- return;
- boundary.set(oldNode->nextSibling(), boundaryOffset - oldNode->length(), 0);
+ if (boundary.childBefore() == &oldNode)
+ boundary.set(boundaryContainer, boundaryOffset + 1, oldNode.nextSibling());
+ else if (boundary.container() == &oldNode && boundaryOffset > oldNode.length())
+ boundary.set(oldNode.nextSibling(), boundaryOffset - oldNode.length(), 0);
}
-void Range::didSplitTextNode(Text* oldNode)
+void Range::didSplitTextNode(Text& oldNode)
{
- ASSERT(oldNode);
- ASSERT(oldNode->document() == m_ownerDocument);
- ASSERT(oldNode->parentNode());
- ASSERT(oldNode->isTextNode());
- ASSERT(oldNode->nextSibling());
- ASSERT(oldNode->nextSibling()->isTextNode());
+ ASSERT(oldNode.document() == m_ownerDocument);
+ ASSERT(oldNode.parentNode());
+ ASSERT(oldNode.isTextNode());
+ ASSERT(oldNode.nextSibling());
+ ASSERT(oldNode.nextSibling()->isTextNode());
boundaryTextNodeSplit(m_start, oldNode);
boundaryTextNodeSplit(m_end, oldNode);
+ ASSERT(boundaryPointsValid());
}
void Range::expand(const String& unit, ExceptionState& exceptionState)
@@ -1823,11 +1601,8 @@ void Range::expand(const String& unit, ExceptionState& exceptionState)
setEnd(end.deepEquivalent().containerNode(), end.deepEquivalent().computeOffsetInContainerNode(), exceptionState);
}
-PassRefPtr<ClientRectList> Range::getClientRects() const
+PassRefPtrWillBeRawPtr<ClientRectList> Range::getClientRects() const
{
- if (!m_start.container())
- return ClientRectList::create();
-
m_ownerDocument->updateLayoutIgnorePendingStylesheets();
Vector<FloatQuad> quads;
@@ -1836,7 +1611,7 @@ PassRefPtr<ClientRectList> Range::getClientRects() const
return ClientRectList::create(quads);
}
-PassRefPtr<ClientRect> Range::getBoundingClientRect() const
+PassRefPtrWillBeRawPtr<ClientRect> Range::getBoundingClientRect() const
{
return ClientRect::create(boundingRect());
}
@@ -1861,7 +1636,7 @@ void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const
renderBoxModelObject->absoluteQuads(elementQuads);
m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(elementQuads, *renderBoxModelObject);
- quads.append(elementQuads);
+ quads.appendVector(elementQuads);
}
}
} else if (node->isTextNode()) {
@@ -1874,7 +1649,7 @@ void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const
renderText.absoluteQuadsForRange(textQuads, startOffset, endOffset);
m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(textQuads, renderText);
- quads.append(textQuads);
+ quads.appendVector(textQuads);
}
}
}
@@ -1882,9 +1657,6 @@ void Range::getBorderAndTextQuads(Vector<FloatQuad>& quads) const
FloatRect Range::boundingRect() const
{
- if (!m_start.container())
- return FloatRect();
-
m_ownerDocument->updateLayoutIgnorePendingStylesheets();
Vector<FloatQuad> quads;
@@ -1899,6 +1671,13 @@ FloatRect Range::boundingRect() const
return result;
}
+void Range::trace(Visitor* visitor)
+{
+ visitor->trace(m_ownerDocument);
+ visitor->trace(m_start);
+ visitor->trace(m_end);
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/dom/Range.h b/chromium/third_party/WebKit/Source/core/dom/Range.h
index 3a662f19cb0..bb0f7691761 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Range.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Range.h
@@ -30,9 +30,9 @@
#include "core/dom/RangeBoundaryPoint.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
namespace WebCore {
@@ -47,11 +47,11 @@ class Node;
class NodeWithIndex;
class Text;
-class Range : public RefCounted<Range>, public ScriptWrappable {
+class Range FINAL : public RefCountedWillBeGarbageCollectedFinalized<Range>, public ScriptWrappable {
public:
- static PassRefPtr<Range> create(Document&);
- static PassRefPtr<Range> create(Document&, Node* startContainer, int startOffset, Node* endContainer, int endOffset);
- static PassRefPtr<Range> create(Document&, const Position&, const Position&);
+ static PassRefPtrWillBeRawPtr<Range> create(Document&);
+ static PassRefPtrWillBeRawPtr<Range> create(Document&, Node* startContainer, int startOffset, Node* endContainer, int endOffset);
+ static PassRefPtrWillBeRawPtr<Range> create(Document&, const Position&, const Position&);
~Range();
Document& ownerDocument() const { ASSERT(m_ownerDocument); return *m_ownerDocument.get(); }
@@ -60,17 +60,13 @@ public:
Node* endContainer() const { return m_end.container(); }
int endOffset() const { return m_end.offset(); }
- Node* startContainer(ExceptionState&) const;
- int startOffset(ExceptionState&) const;
- Node* endContainer(ExceptionState&) const;
- int endOffset(ExceptionState&) const;
- bool collapsed(ExceptionState&) const;
+ bool collapsed() const { return m_start == m_end; }
- Node* commonAncestorContainer(ExceptionState&) const;
+ Node* commonAncestorContainer() const;
static Node* commonAncestorContainer(Node* containerA, Node* containerB);
- void setStart(PassRefPtr<Node> container, int offset, ExceptionState& = ASSERT_NO_EXCEPTION);
- void setEnd(PassRefPtr<Node> container, int offset, ExceptionState& = ASSERT_NO_EXCEPTION);
- void collapse(bool toStart, ExceptionState&);
+ void setStart(PassRefPtrWillBeRawPtr<Node> container, int offset, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void setEnd(PassRefPtrWillBeRawPtr<Node> container, int offset, ExceptionState& = ASSERT_NO_EXCEPTION);
+ void collapse(bool toStart);
bool isPointInRange(Node* refNode, int offset, ExceptionState&);
short comparePoint(Node* refNode, int offset, ExceptionState&) const;
enum CompareResults { NODE_BEFORE, NODE_AFTER, NODE_BEFORE_AND_AFTER, NODE_INSIDE };
@@ -82,25 +78,25 @@ public:
bool boundaryPointsValid() const;
bool intersectsNode(Node* refNode, ExceptionState&);
void deleteContents(ExceptionState&);
- PassRefPtr<DocumentFragment> extractContents(ExceptionState&);
- PassRefPtr<DocumentFragment> cloneContents(ExceptionState&);
- void insertNode(PassRefPtr<Node>, ExceptionState&);
- String toString(ExceptionState&) const;
+ PassRefPtrWillBeRawPtr<DocumentFragment> extractContents(ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> cloneContents(ExceptionState&);
+ void insertNode(PassRefPtrWillBeRawPtr<Node>, ExceptionState&);
+ String toString() const;
String toHTML() const;
String text() const;
- PassRefPtr<DocumentFragment> createContextualFragment(const String& html, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> createContextualFragment(const String& html, ExceptionState&);
- void detach(ExceptionState&);
- PassRefPtr<Range> cloneRange(ExceptionState&) const;
+ void detach();
+ PassRefPtrWillBeRawPtr<Range> cloneRange() const;
void setStartAfter(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void setEndBefore(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void setEndAfter(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void selectNode(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
void selectNodeContents(Node*, ExceptionState&);
- void surroundContents(PassRefPtr<Node>, ExceptionState&);
+ void surroundContents(PassRefPtrWillBeRawPtr<Node>, ExceptionState&);
void setStartBefore(Node*, ExceptionState& = ASSERT_NO_EXCEPTION);
const Position startPosition() const { return m_start.toPosition(); }
@@ -129,26 +125,29 @@ public:
FloatRect boundingRect() const;
void nodeChildrenChanged(ContainerNode*);
- void nodeChildrenWillBeRemoved(ContainerNode*);
+ void nodeChildrenWillBeRemoved(ContainerNode&);
void nodeWillBeRemoved(Node&);
void didInsertText(Node*, unsigned offset, unsigned length);
void didRemoveText(Node*, unsigned offset, unsigned length);
- void didMergeTextNodes(NodeWithIndex& oldNode, unsigned offset);
- void didSplitTextNode(Text* oldNode);
+ void didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset);
+ void didSplitTextNode(Text& oldNode);
+ void updateOwnerDocumentIfNeeded();
// Expand range to a unit (word or sentence or block or document) boundary.
// Please refer to https://bugs.webkit.org/show_bug.cgi?id=27632 comment #5
// for details.
void expand(const String&, ExceptionState&);
- PassRefPtr<ClientRectList> getClientRects() const;
- PassRefPtr<ClientRect> getBoundingClientRect() const;
+ PassRefPtrWillBeRawPtr<ClientRectList> getClientRects() const;
+ PassRefPtrWillBeRawPtr<ClientRect> getBoundingClientRect() const;
#ifndef NDEBUG
void formatForDebugger(char* buffer, unsigned length) const;
#endif
+ void trace(Visitor*);
+
private:
explicit Range(Document&);
Range(Document&, Node* startContainer, int startOffset, Node* endContainer, int endOffset);
@@ -158,22 +157,20 @@ private:
Node* checkNodeWOffset(Node*, int offset, ExceptionState&) const;
void checkNodeBA(Node*, ExceptionState&) const;
void checkDeleteExtract(ExceptionState&);
- int maxStartOffset() const;
- int maxEndOffset() const;
enum ActionType { DELETE_CONTENTS, EXTRACT_CONTENTS, CLONE_CONTENTS };
- PassRefPtr<DocumentFragment> processContents(ActionType, ExceptionState&);
- static PassRefPtr<Node> processContentsBetweenOffsets(ActionType, PassRefPtr<DocumentFragment>, Node*, unsigned startOffset, unsigned endOffset, ExceptionState&);
- static void processNodes(ActionType, Vector<RefPtr<Node> >&, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> processContents(ActionType, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<Node> processContentsBetweenOffsets(ActionType, PassRefPtrWillBeRawPtr<DocumentFragment>, Node*, unsigned startOffset, unsigned endOffset, ExceptionState&);
+ static void processNodes(ActionType, WillBeHeapVector<RefPtrWillBeMember<Node> >&, PassRefPtrWillBeRawPtr<Node> oldContainer, PassRefPtrWillBeRawPtr<Node> newContainer, ExceptionState&);
enum ContentsProcessDirection { ProcessContentsForward, ProcessContentsBackward };
- static PassRefPtr<Node> processAncestorsAndTheirSiblings(ActionType, Node* container, ContentsProcessDirection, PassRefPtr<Node> clonedContainer, Node* commonRoot, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<Node> processAncestorsAndTheirSiblings(ActionType, Node* container, ContentsProcessDirection, PassRefPtrWillBeRawPtr<Node> clonedContainer, Node* commonRoot, ExceptionState&);
- RefPtr<Document> m_ownerDocument; // Cannot be null.
+ RefPtrWillBeMember<Document> m_ownerDocument; // Cannot be null.
RangeBoundaryPoint m_start;
RangeBoundaryPoint m_end;
};
-PassRefPtr<Range> rangeOfContents(Node*);
+PassRefPtrWillBeRawPtr<Range> rangeOfContents(Node*);
bool areRangesEqual(const Range*, const Range*);
diff --git a/chromium/third_party/WebKit/Source/core/dom/Range.idl b/chromium/third_party/WebKit/Source/core/dom/Range.idl
index d3dd1eb2f0e..e73f6d37add 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Range.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Range.idl
@@ -22,14 +22,15 @@
[
Constructor,
ConstructorCallWith=Document,
+ WillBeGarbageCollected,
] interface Range {
- [RaisesException=Getter] readonly attribute Node startContainer;
- [RaisesException=Getter] readonly attribute long startOffset;
- [RaisesException=Getter] readonly attribute Node endContainer;
- [RaisesException=Getter] readonly attribute long endOffset;
- [RaisesException=Getter] readonly attribute boolean collapsed;
- [RaisesException=Getter] readonly attribute Node commonAncestorContainer;
+ readonly attribute Node startContainer;
+ readonly attribute long startOffset;
+ readonly attribute Node endContainer;
+ readonly attribute long endOffset;
+ readonly attribute boolean collapsed;
+ readonly attribute Node commonAncestorContainer;
[RaisesException] void setStart(Node refNode, long offset);
[RaisesException] void setEnd(Node refNode, long offset);
@@ -37,7 +38,7 @@
[RaisesException] void setStartAfter(Node refNode);
[RaisesException] void setEndBefore(Node refNode);
[RaisesException] void setEndAfter(Node refNode);
- [RaisesException] void collapse([Default=Undefined] optional boolean toStart);
+ void collapse([Default=Undefined] optional boolean toStart);
[RaisesException] void selectNode(Node refNode);
[RaisesException] void selectNodeContents(Node refNode);
@@ -54,10 +55,10 @@
[RaisesException, CustomElementCallbacks] DocumentFragment cloneContents();
[RaisesException, CustomElementCallbacks] void insertNode(Node newNode);
[RaisesException, CustomElementCallbacks] void surroundContents(Node newParent);
- [RaisesException] Range cloneRange();
- [RaisesException] DOMString toString();
+ Range cloneRange();
+ DOMString toString();
- [RaisesException] void detach();
+ [DeprecateAs=RangeDetach] void detach();
[RaisesException] boolean isPointInRange(Node refNode, long offset);
[RaisesException] short comparePoint(Node refNode, long offset);
@@ -81,7 +82,7 @@
const unsigned short NODE_BEFORE_AND_AFTER = 2;
const unsigned short NODE_INSIDE = 3;
- [RaisesException] short compareNode([Default=Undefined] optional Node refNode);
+ [RaisesException, MeasureAs=RangeCompareNode] short compareNode([Default=Undefined] optional Node refNode);
- [RaisesException] void expand([Default=Undefined] optional DOMString unit);
+ [RaisesException, MeasureAs=RangeExpand] void expand([Default=Undefined] optional DOMString unit);
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h b/chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
index 7574a89ef48..4df553bbff0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
+++ b/chromium/third_party/WebKit/Source/core/dom/RangeBoundaryPoint.h
@@ -32,8 +32,9 @@
namespace WebCore {
class RangeBoundaryPoint {
+ DISALLOW_ALLOCATION();
public:
- explicit RangeBoundaryPoint(PassRefPtr<Node> container);
+ explicit RangeBoundaryPoint(PassRefPtrWillBeRawPtr<Node> container);
explicit RangeBoundaryPoint(const RangeBoundaryPoint&);
@@ -45,29 +46,31 @@ public:
void clear();
- void set(PassRefPtr<Node> container, int offset, Node* childBefore);
+ void set(PassRefPtrWillBeRawPtr<Node> container, int offset, Node* childBefore);
void setOffset(int offset);
void setToBeforeChild(Node&);
- void setToStartOfNode(PassRefPtr<Node>);
- void setToEndOfNode(PassRefPtr<Node>);
+ void setToStartOfNode(Node&);
+ void setToEndOfNode(Node&);
void childBeforeWillBeRemoved();
void invalidateOffset() const;
void ensureOffsetIsValid() const;
+ void trace(Visitor*);
+
private:
static const int invalidOffset = -1;
- RefPtr<Node> m_containerNode;
+ RefPtrWillBeMember<Node> m_containerNode;
mutable int m_offsetInContainer;
- RefPtr<Node> m_childBeforeBoundary;
+ RefPtrWillBeMember<Node> m_childBeforeBoundary;
};
-inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
+inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtrWillBeRawPtr<Node> container)
: m_containerNode(container)
, m_offsetInContainer(0)
- , m_childBeforeBoundary(0)
+ , m_childBeforeBoundary(nullptr)
{
ASSERT(m_containerNode);
}
@@ -114,14 +117,14 @@ inline void RangeBoundaryPoint::clear()
{
m_containerNode.clear();
m_offsetInContainer = 0;
- m_childBeforeBoundary = 0;
+ m_childBeforeBoundary = nullptr;
}
-inline void RangeBoundaryPoint::set(PassRefPtr<Node> container, int offset, Node* childBefore)
+inline void RangeBoundaryPoint::set(PassRefPtrWillBeRawPtr<Node> container, int offset, Node* childBefore)
{
ASSERT(container);
ASSERT(offset >= 0);
- ASSERT(childBefore == (offset ? container->childNode(offset - 1) : 0));
+ ASSERT(childBefore == (offset ? container->traverseToChildAt(offset - 1) : 0));
m_containerNode = container;
m_offsetInContainer = offset;
m_childBeforeBoundary = childBefore;
@@ -144,21 +147,19 @@ inline void RangeBoundaryPoint::setToBeforeChild(Node& child)
m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
}
-inline void RangeBoundaryPoint::setToStartOfNode(PassRefPtr<Node> container)
+inline void RangeBoundaryPoint::setToStartOfNode(Node& container)
{
- ASSERT(container);
- m_containerNode = container;
+ m_containerNode = &container;
m_offsetInContainer = 0;
- m_childBeforeBoundary = 0;
+ m_childBeforeBoundary = nullptr;
}
-inline void RangeBoundaryPoint::setToEndOfNode(PassRefPtr<Node> container)
+inline void RangeBoundaryPoint::setToEndOfNode(Node& container)
{
- ASSERT(container);
- m_containerNode = container;
+ m_containerNode = &container;
if (m_containerNode->offsetInCharacters()) {
m_offsetInContainer = m_containerNode->maxCharacterOffset();
- m_childBeforeBoundary = 0;
+ m_childBeforeBoundary = nullptr;
} else {
m_childBeforeBoundary = m_containerNode->lastChild();
m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
@@ -180,6 +181,12 @@ inline void RangeBoundaryPoint::invalidateOffset() const
m_offsetInContainer = invalidOffset;
}
+inline void RangeBoundaryPoint::trace(Visitor* visitor)
+{
+ visitor->trace(m_containerNode);
+ visitor->trace(m_childBeforeBoundary);
+}
+
inline bool operator==(const RangeBoundaryPoint& a, const RangeBoundaryPoint& b)
{
if (a.container() != b.container())
diff --git a/chromium/third_party/WebKit/Source/core/dom/RangeTest.cpp b/chromium/third_party/WebKit/Source/core/dom/RangeTest.cpp
new file mode 100644
index 00000000000..f27f44de1ba
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/RangeTest.cpp
@@ -0,0 +1,144 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/Range.h"
+
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/Element.h"
+#include "core/dom/NodeList.h"
+#include "core/dom/Text.h"
+#include "core/html/HTMLBodyElement.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/HTMLElement.h"
+#include "core/html/HTMLHtmlElement.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Compiler.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/AtomicString.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class RangeTest : public ::testing::Test {
+protected:
+ virtual void SetUp() OVERRIDE;
+
+ HTMLDocument& document() const;
+
+private:
+ RefPtrWillBePersistent<HTMLDocument> m_document;
+};
+
+void RangeTest::SetUp()
+{
+ m_document = HTMLDocument::create();
+ RefPtrWillBeRawPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*m_document);
+ html->appendChild(HTMLBodyElement::create(*m_document));
+ m_document->appendChild(html.release());
+}
+
+HTMLDocument& RangeTest::document() const
+{
+ return *m_document;
+}
+
+TEST_F(RangeTest, SplitTextNodeRangeWithinText)
+{
+ document().body()->setInnerHTML("1234", ASSERT_NO_EXCEPTION);
+ Text* oldText = toText(document().body()->firstChild());
+
+ RefPtrWillBeRawPtr<Range> range04 = Range::create(document(), oldText, 0, oldText, 4);
+ RefPtrWillBeRawPtr<Range> range02 = Range::create(document(), oldText, 0, oldText, 2);
+ RefPtrWillBeRawPtr<Range> range22 = Range::create(document(), oldText, 2, oldText, 2);
+ RefPtrWillBeRawPtr<Range> range24 = Range::create(document(), oldText, 2, oldText, 4);
+
+ oldText->splitText(2, ASSERT_NO_EXCEPTION);
+ Text* newText = toText(oldText->nextSibling());
+
+ EXPECT_TRUE(range04->boundaryPointsValid());
+ EXPECT_EQ(oldText, range04->startContainer());
+ EXPECT_EQ(0, range04->startOffset());
+ EXPECT_EQ(newText, range04->endContainer());
+ EXPECT_EQ(2, range04->endOffset());
+
+ EXPECT_TRUE(range02->boundaryPointsValid());
+ EXPECT_EQ(oldText, range02->startContainer());
+ EXPECT_EQ(0, range02->startOffset());
+ EXPECT_EQ(oldText, range02->endContainer());
+ EXPECT_EQ(2, range02->endOffset());
+
+ // Our implementation always moves the boundary point at the separation point to the end of the original text node.
+ EXPECT_TRUE(range22->boundaryPointsValid());
+ EXPECT_EQ(oldText, range22->startContainer());
+ EXPECT_EQ(2, range22->startOffset());
+ EXPECT_EQ(oldText, range22->endContainer());
+ EXPECT_EQ(2, range22->endOffset());
+
+ EXPECT_TRUE(range24->boundaryPointsValid());
+ EXPECT_EQ(oldText, range24->startContainer());
+ EXPECT_EQ(2, range24->startOffset());
+ EXPECT_EQ(newText, range24->endContainer());
+ EXPECT_EQ(2, range24->endOffset());
+}
+
+TEST_F(RangeTest, SplitTextNodeRangeOutsideText)
+{
+ document().body()->setInnerHTML("<span id=\"outer\">0<span id=\"inner-left\">1</span>SPLITME<span id=\"inner-right\">2</span>3</span>", ASSERT_NO_EXCEPTION);
+
+ Element* outer = document().getElementById(AtomicString::fromUTF8("outer"));
+ Element* innerLeft = document().getElementById(AtomicString::fromUTF8("inner-left"));
+ Element* innerRight = document().getElementById(AtomicString::fromUTF8("inner-right"));
+ Text* oldText = toText(outer->childNodes()->item(2));
+
+ RefPtrWillBeRawPtr<Range> rangeOuterOutside = Range::create(document(), outer, 0, outer, 5);
+ RefPtrWillBeRawPtr<Range> rangeOuterInside = Range::create(document(), outer, 1, outer, 4);
+ RefPtrWillBeRawPtr<Range> rangeOuterSurroundingText = Range::create(document(), outer, 2, outer, 3);
+ RefPtrWillBeRawPtr<Range> rangeInnerLeft = Range::create(document(), innerLeft, 0, innerLeft, 1);
+ RefPtrWillBeRawPtr<Range> rangeInnerRight = Range::create(document(), innerRight, 0, innerRight, 1);
+ RefPtrWillBeRawPtr<Range> rangeFromTextToMiddleOfElement = Range::create(document(), oldText, 6, outer, 3);
+
+ oldText->splitText(3, ASSERT_NO_EXCEPTION);
+ Text* newText = toText(oldText->nextSibling());
+
+ EXPECT_TRUE(rangeOuterOutside->boundaryPointsValid());
+ EXPECT_EQ(outer, rangeOuterOutside->startContainer());
+ EXPECT_EQ(0, rangeOuterOutside->startOffset());
+ EXPECT_EQ(outer, rangeOuterOutside->endContainer());
+ EXPECT_EQ(6, rangeOuterOutside->endOffset()); // Increased by 1 since a new node is inserted.
+
+ EXPECT_TRUE(rangeOuterInside->boundaryPointsValid());
+ EXPECT_EQ(outer, rangeOuterInside->startContainer());
+ EXPECT_EQ(1, rangeOuterInside->startOffset());
+ EXPECT_EQ(outer, rangeOuterInside->endContainer());
+ EXPECT_EQ(5, rangeOuterInside->endOffset());
+
+ EXPECT_TRUE(rangeOuterSurroundingText->boundaryPointsValid());
+ EXPECT_EQ(outer, rangeOuterSurroundingText->startContainer());
+ EXPECT_EQ(2, rangeOuterSurroundingText->startOffset());
+ EXPECT_EQ(outer, rangeOuterSurroundingText->endContainer());
+ EXPECT_EQ(4, rangeOuterSurroundingText->endOffset());
+
+ EXPECT_TRUE(rangeInnerLeft->boundaryPointsValid());
+ EXPECT_EQ(innerLeft, rangeInnerLeft->startContainer());
+ EXPECT_EQ(0, rangeInnerLeft->startOffset());
+ EXPECT_EQ(innerLeft, rangeInnerLeft->endContainer());
+ EXPECT_EQ(1, rangeInnerLeft->endOffset());
+
+ EXPECT_TRUE(rangeInnerRight->boundaryPointsValid());
+ EXPECT_EQ(innerRight, rangeInnerRight->startContainer());
+ EXPECT_EQ(0, rangeInnerRight->startOffset());
+ EXPECT_EQ(innerRight, rangeInnerRight->endContainer());
+ EXPECT_EQ(1, rangeInnerRight->endOffset());
+
+ EXPECT_TRUE(rangeFromTextToMiddleOfElement->boundaryPointsValid());
+ EXPECT_EQ(newText, rangeFromTextToMiddleOfElement->startContainer());
+ EXPECT_EQ(3, rangeFromTextToMiddleOfElement->startOffset());
+ EXPECT_EQ(outer, rangeFromTextToMiddleOfElement->endContainer());
+ EXPECT_EQ(4, rangeFromTextToMiddleOfElement->endOffset());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h b/chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h
index f2adeed32f8..ade8afe00b6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/dom/RawDataDocumentParser.h
@@ -38,7 +38,7 @@ protected:
{
}
- virtual void finish()
+ virtual void finish() OVERRIDE
{
if (!isStopped())
document()->finishedParsing();
@@ -51,11 +51,11 @@ private:
appendBytes(0, 0);
}
- virtual void insert(const SegmentedString&)
+ virtual void insert(const SegmentedString&) OVERRIDE
{
}
- virtual void append(PassRefPtr<StringImpl>)
+ virtual void append(PassRefPtr<StringImpl>) OVERRIDE
{
ASSERT_NOT_REACHED();
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp b/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp
new file mode 100644
index 00000000000..974a1fa5c53
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/dom/RenderTreeBuilder.h"
+
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/FullscreenElementStack.h"
+#include "core/dom/Node.h"
+#include "core/dom/Text.h"
+#include "core/rendering/RenderFullScreen.h"
+#include "core/rendering/RenderObject.h"
+#include "core/rendering/RenderText.h"
+#include "core/rendering/RenderView.h"
+#include "core/svg/SVGElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
+
+namespace WebCore {
+
+RenderObject* RenderTreeBuilder::nextRenderer() const
+{
+ ASSERT(m_renderingParent);
+
+ Element* element = m_node->isElementNode() ? toElement(m_node) : 0;
+
+ if (element && element->isInTopLayer())
+ return NodeRenderingTraversal::nextInTopLayer(element);
+
+ // Avoid an O(N^2) walk over the children when reattaching all children of a node.
+ if (m_renderingParent->needsAttach())
+ return 0;
+
+ return NodeRenderingTraversal::nextSiblingRenderer(m_node);
+}
+
+RenderObject* RenderTreeBuilder::parentRenderer() const
+{
+ ASSERT(m_renderingParent);
+
+ Element* element = m_node->isElementNode() ? toElement(m_node) : 0;
+
+ if (element && m_renderingParent->renderer()) {
+ // FIXME: Guarding this by m_renderingParent->renderer() isn't quite right as the spec for
+ // top layer only talks about display: none ancestors so putting a <dialog> inside an
+ // <optgroup> seems like it should still work even though this check will prevent it.
+ if (element->isInTopLayer())
+ return m_node->document().renderView();
+ }
+
+ return m_renderingParent->renderer();
+}
+
+bool RenderTreeBuilder::shouldCreateRenderer() const
+{
+ if (!m_renderingParent)
+ return false;
+ if (m_node->isSVGElement()) {
+ // SVG elements only render when inside <svg>, or if the element is an <svg> itself.
+ if (!isSVGSVGElement(*m_node) && !m_renderingParent->isSVGElement())
+ return false;
+ if (!toSVGElement(m_node)->isValid())
+ return false;
+ }
+ RenderObject* parentRenderer = this->parentRenderer();
+ if (!parentRenderer)
+ return false;
+ if (!parentRenderer->canHaveChildren())
+ return false;
+ return true;
+}
+
+RenderStyle& RenderTreeBuilder::style() const
+{
+ if (!m_style)
+ m_style = toElement(m_node)->styleForRenderer();
+ return *m_style;
+}
+
+void RenderTreeBuilder::createRendererForElementIfNeeded()
+{
+ ASSERT(!m_node->renderer());
+
+ if (!shouldCreateRenderer())
+ return;
+
+ Element* element = toElement(m_node);
+ RenderStyle& style = this->style();
+
+ if (!element->rendererIsNeeded(style))
+ return;
+
+ RenderObject* newRenderer = element->createRenderer(&style);
+ if (!newRenderer)
+ return;
+
+ RenderObject* parentRenderer = this->parentRenderer();
+
+ if (!parentRenderer->isChildAllowed(newRenderer, &style)) {
+ newRenderer->destroy();
+ return;
+ }
+
+ // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
+ // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
+ newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
+
+ RenderObject* nextRenderer = this->nextRenderer();
+ element->setRenderer(newRenderer);
+ newRenderer->setStyle(&style); // setStyle() can depend on renderer() already being set.
+
+ if (FullscreenElementStack::isActiveFullScreenElement(element)) {
+ newRenderer = RenderFullScreen::wrapRenderer(newRenderer, parentRenderer, &element->document());
+ if (!newRenderer)
+ return;
+ }
+
+ // Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
+ parentRenderer->addChild(newRenderer, nextRenderer);
+}
+
+void RenderTreeBuilder::createRendererForTextIfNeeded()
+{
+ ASSERT(!m_node->renderer());
+
+ if (!shouldCreateRenderer())
+ return;
+
+ Text* textNode = toText(m_node);
+ RenderObject* parentRenderer = this->parentRenderer();
+
+ m_style = parentRenderer->style();
+
+ if (!textNode->textRendererIsNeeded(*m_style, *parentRenderer))
+ return;
+
+ RenderText* newRenderer = textNode->createTextRenderer(m_style.get());
+ if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
+ newRenderer->destroy();
+ return;
+ }
+
+ // Make sure the RenderObject already knows it is going to be added to a RenderFlowThread before we set the style
+ // for the first time. Otherwise code using inRenderFlowThread() in the styleWillChange and styleDidChange will fail.
+ newRenderer->setFlowThreadState(parentRenderer->flowThreadState());
+
+ RenderObject* nextRenderer = this->nextRenderer();
+ textNode->setRenderer(newRenderer);
+ // Parent takes care of the animations, no need to call setAnimatableStyle.
+ newRenderer->setStyle(m_style.release());
+ parentRenderer->addChild(newRenderer, nextRenderer);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.h b/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.h
new file mode 100644
index 00000000000..b92b1af8a94
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/RenderTreeBuilder.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderTreeBuilder_h
+#define RenderTreeBuilder_h
+
+#include "core/dom/Document.h"
+#include "core/dom/Node.h"
+#include "core/dom/NodeRenderingTraversal.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class ContainerNode;
+class RenderObject;
+class RenderStyle;
+
+class RenderTreeBuilder {
+ STACK_ALLOCATED();
+public:
+ RenderTreeBuilder(Node* node, RenderStyle* style)
+ : m_node(node)
+ , m_renderingParent(nullptr)
+ , m_style(style)
+ {
+ ASSERT(!node->renderer());
+ ASSERT(node->needsAttach());
+ ASSERT(node->document().inStyleRecalc());
+
+ // FIXME: We should be able to ASSERT(node->inActiveDocument()) but childrenChanged is called
+ // before ChildNodeInsertionNotifier in ContainerNode's methods and some implementations
+ // will trigger a layout inside childrenChanged.
+ // Mainly HTMLTextAreaElement::childrenChanged calls HTMLTextFormControlElement::setSelectionRange
+ // which does an updateLayoutIgnorePendingStylesheets.
+
+ m_renderingParent = NodeRenderingTraversal::parent(node, &m_parentDetails);
+ }
+
+ void createRendererForTextIfNeeded();
+ void createRendererForElementIfNeeded();
+
+private:
+ RenderObject* parentRenderer() const;
+ RenderObject* nextRenderer() const;
+ bool shouldCreateRenderer() const;
+ RenderStyle& style() const;
+
+ RawPtrWillBeMember<Node> m_node;
+ RawPtrWillBeMember<ContainerNode> m_renderingParent;
+ NodeRenderingTraversal::ParentDetails m_parentDetails;
+ mutable RefPtr<RenderStyle> m_style;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h b/chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h
index 9e6966a225f..2fd4b50bf5e 100644
--- a/chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h
+++ b/chromium/third_party/WebKit/Source/core/dom/RenderedDocumentMarker.h
@@ -62,11 +62,15 @@ inline void RenderedDocumentMarker::invalidate(const LayoutRect& r)
invalidate();
}
-inline RenderedDocumentMarker* toRenderedDocumentMarker(DocumentMarker* marker)
-{
- return static_cast<RenderedDocumentMarker*>(marker);
-}
+DEFINE_TYPE_CASTS(RenderedDocumentMarker, DocumentMarker, marker, true, true);
} // namespace
+namespace WTF {
+
+template<>
+struct VectorTraits<WebCore::RenderedDocumentMarker> : SimpleClassVectorTraits<WebCore::RenderedDocumentMarker> { };
+
+} // namespace WTF
+
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp b/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp
index 1ebd0c3fe66..8d8e01c2f79 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.cpp
@@ -65,6 +65,8 @@ SandboxFlags parseSandboxPolicy(const String& policy, String& invalidTokensError
flags &= ~SandboxPopups;
} else if (equalIgnoringCase(sandboxToken, "allow-pointer-lock")) {
flags &= ~SandboxPointerLock;
+ } else if (equalIgnoringCase(sandboxToken, "allow-orientation-lock")) {
+ flags &= ~SandboxOrientationLock;
} else {
if (numberOfTokenErrors)
tokenErrors.appendLiteral(", '");
diff --git a/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h b/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h
index fa072d1ea9e..3e980d9d610 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h
+++ b/chromium/third_party/WebKit/Source/core/dom/SandboxFlags.h
@@ -42,9 +42,9 @@ enum SandboxFlag {
SandboxTopNavigation = 1 << 5,
SandboxPopups = 1 << 6, // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=12393
SandboxAutomaticFeatures = 1 << 7,
- SandboxSeamlessIframes = 1 << 8,
- SandboxPointerLock = 1 << 9,
- SandboxDocumentDomain = 1 << 10,
+ SandboxPointerLock = 1 << 8,
+ SandboxDocumentDomain = 1 << 9,
+ SandboxOrientationLock = 1 << 10, // See https://w3c.github.io/screen-orientation/#dfn-sandboxed-orientation-lock-browsing-context-flag.
SandboxAll = -1 // Mask with all bits set to 1.
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.cpp
new file mode 100644
index 00000000000..81540dcb6f3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.cpp
@@ -0,0 +1,46 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/ScriptForbiddenScope.h"
+
+#include "wtf/Assertions.h"
+#include "wtf/MainThread.h"
+
+namespace WebCore {
+
+#if ASSERT_ENABLED
+
+static unsigned s_scriptForbiddenCount = 0;
+
+ScriptForbiddenScope::ScriptForbiddenScope()
+{
+ ASSERT(isMainThread());
+ ++s_scriptForbiddenCount;
+}
+
+ScriptForbiddenScope::~ScriptForbiddenScope()
+{
+ ASSERT(isMainThread());
+ --s_scriptForbiddenCount;
+}
+
+bool ScriptForbiddenScope::isScriptForbidden()
+{
+ return isMainThread() && s_scriptForbiddenCount;
+}
+
+ScriptForbiddenScope::AllowUserAgentScript::AllowUserAgentScript()
+ : m_change(s_scriptForbiddenCount, 0)
+{
+}
+
+ScriptForbiddenScope::AllowUserAgentScript::~AllowUserAgentScript()
+{
+ ASSERT(!s_scriptForbiddenCount);
+}
+
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.h b/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.h
new file mode 100644
index 00000000000..7425b6cb943
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptForbiddenScope.h
@@ -0,0 +1,47 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ScriptForbiddenScope_h
+#define ScriptForbiddenScope_h
+
+#include "wtf/Assertions.h"
+#include "wtf/TemporaryChange.h"
+
+namespace WebCore {
+
+#if ASSERT_ENABLED
+
+class ScriptForbiddenScope {
+public:
+ ScriptForbiddenScope();
+ ~ScriptForbiddenScope();
+
+ class AllowUserAgentScript {
+ public:
+ AllowUserAgentScript();
+ ~AllowUserAgentScript();
+ private:
+ TemporaryChange<unsigned> m_change;
+ };
+
+ static bool isScriptForbidden();
+};
+
+#else
+
+class ScriptForbiddenScope {
+public:
+ ScriptForbiddenScope() { }
+ class AllowUserAgentScript {
+ public:
+ AllowUserAgentScript() { }
+ };
+ static bool isScriptForbidden() { return false; }
+};
+
+#endif
+
+} // namespace WebCore
+
+#endif // ScriptForbiddenScope_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
index eaa0e45da91..e5b9a3be4bb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.cpp
@@ -24,10 +24,10 @@
#include "config.h"
#include "core/dom/ScriptLoader.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
#include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
@@ -38,11 +38,11 @@
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ScriptResource.h"
-#include "core/html/HTMLImport.h"
#include "core/html/HTMLScriptElement.h"
+#include "core/html/imports/HTMLImport.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/svg/SVGScriptElement.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
@@ -65,7 +65,6 @@ ScriptLoader::ScriptLoader(Element* element, bool parserInserted, bool alreadySt
, m_willExecuteWhenDocumentFinishedParsing(false)
, m_forceAsync(!parserInserted)
, m_willExecuteInOrder(false)
- , m_isPotentiallyCORSEnabled(false)
{
ASSERT(m_element);
if (parserInserted && element->document().scriptableDocumentParser() && !element->document().isInDocumentWrite())
@@ -116,7 +115,6 @@ static bool isLegacySupportedJavaScriptLanguage(const String& language)
DEFINE_STATIC_LOCAL(LanguageSet, languages, ());
if (languages.isEmpty()) {
languages.add("javascript");
- languages.add("javascript");
languages.add("javascript1.0");
languages.add("javascript1.1");
languages.add("javascript1.2");
@@ -159,7 +157,7 @@ bool ScriptLoader::isScriptTypeSupported(LegacyTypeSupport supportLegacyTypes) c
type = "text/" + language.lower();
if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type) || isLegacySupportedJavaScriptLanguage(language))
return true;
- } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace().lower()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) {
+ } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(type.stripWhiteSpace()) || (supportLegacyTypes == AllowLegacyTypeInTypeAttribute && isLegacySupportedJavaScriptLanguage(type))) {
return true;
}
@@ -227,7 +225,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
m_willBeParserExecuted = true;
} else if (client->hasSourceAttribute() && m_parserInserted && !client->asyncAttributeValue()) {
m_willBeParserExecuted = true;
- } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument.haveStylesheetsAndImportsLoaded()) {
+ } else if (!client->hasSourceAttribute() && m_parserInserted && !elementDocument.isRenderingReady()) {
m_willBeParserExecuted = true;
m_readyToBeParserExecuted = true;
} else if (client->hasSourceAttribute() && !client->asyncAttributeValue() && !m_forceAsync) {
@@ -241,8 +239,7 @@ bool ScriptLoader::prepareScript(const TextPosition& scriptStartPosition, Legacy
// Reset line numbering for nested writes.
TextPosition position = elementDocument.isInDocumentWrite() ? TextPosition() : scriptStartPosition;
KURL scriptURL = (!elementDocument.isInDocumentWrite() && m_parserInserted) ? elementDocument.url() : KURL();
- if (!executePotentiallyCrossOriginScript(ScriptSourceCode(scriptContent(), scriptURL, position)))
- return false;
+ executeScript(ScriptSourceCode(scriptContent(), scriptURL, position));
}
return true;
@@ -252,9 +249,7 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
{
ASSERT(m_element);
- RefPtr<Document> elementDocument(m_element->document());
- if (!m_element->dispatchBeforeLoadEvent(sourceUrl))
- return false;
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
if (!m_element->inDocument() || m_element->document() != elementDocument)
return false;
@@ -262,12 +257,9 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
if (!stripLeadingAndTrailingHTMLSpaces(sourceUrl).isEmpty()) {
FetchRequest request(ResourceRequest(elementDocument->completeURL(sourceUrl)), m_element->localName());
- String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
- if (!crossOriginMode.isNull()) {
- StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- request.setCrossOriginAccessControl(elementDocument->securityOrigin(), allowCredentials);
- m_isPotentiallyCORSEnabled = true;
- }
+ AtomicString crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
+ if (!crossOriginMode.isNull())
+ request.setCrossOriginAccessControl(elementDocument->securityOrigin(), crossOriginMode);
request.setCharset(scriptCharset());
bool isValidScriptNonce = elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr));
@@ -287,12 +279,14 @@ bool ScriptLoader::fetchScript(const String& sourceUrl)
bool isHTMLScriptLoader(Element* element)
{
- return element->hasTagName(HTMLNames::scriptTag);
+ ASSERT(element);
+ return isHTMLScriptElement(*element);
}
bool isSVGScriptLoader(Element* element)
{
- return element->hasTagName(SVGNames::scriptTag);
+ ASSERT(element);
+ return isSVGScriptElement(*element);
}
void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode)
@@ -302,31 +296,37 @@ void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode)
if (sourceCode.isEmpty())
return;
- RefPtr<Document> elementDocument(m_element->document());
- RefPtr<Document> contextDocument = elementDocument->contextDocument().get();
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
+ RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
if (!contextDocument)
return;
- Frame* frame = contextDocument->frame();
+ LocalFrame* frame = contextDocument->frame();
bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script().shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)) || elementDocument->contentSecurityPolicy()->allowScriptHash(sourceCode.source());
if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !elementDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url(), m_startLineNumber)))
return;
- if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosniff()) {
- contextDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_resource->url().elidedString() + "' because its MIME type ('" + m_resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
- return;
+ if (m_isExternalScript) {
+ ScriptResource* resource = m_resource ? m_resource.get() : sourceCode.resource();
+ if (resource && !resource->mimeTypeAllowedByNosniff()) {
+ contextDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->url().elidedString() + "' because its MIME type ('" + resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
+ return;
+ }
}
if (frame) {
- IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? contextDocument.get() : 0);
+ const bool isImportedScript = contextDocument != elementDocument;
+ // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block step 2.3
+ // with additional support for HTML imports.
+ IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_isExternalScript || isImportedScript ? contextDocument.get() : 0);
if (isHTMLScriptLoader(m_element))
contextDocument->pushCurrentScript(toHTMLScriptElement(m_element));
AccessControlStatus corsCheck = NotSharableCrossOrigin;
- if (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin()))
+ if (!m_isExternalScript || (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin())))
corsCheck = SharableCrossOrigin;
// Create a script from the script element node, using the script
@@ -363,24 +363,12 @@ void ScriptLoader::execute(ScriptResource* resource)
resource->removeClient(this);
}
-bool ScriptLoader::executePotentiallyCrossOriginScript(const ScriptSourceCode& sourceCode)
-{
- if (sourceCode.resource()
- && isPotentiallyCORSEnabled()
- && !m_element->document().fetcher()->canAccess(sourceCode.resource(), PotentiallyCORSEnabled)) {
- dispatchErrorEvent();
- return false;
- }
- executeScript(sourceCode);
- return true;
-}
-
void ScriptLoader::notifyFinished(Resource* resource)
{
ASSERT(!m_willBeParserExecuted);
- RefPtr<Document> elementDocument(m_element->document());
- RefPtr<Document> contextDocument = elementDocument->contextDocument().get();
+ RefPtrWillBeRawPtr<Document> elementDocument(m_element->document());
+ RefPtrWillBeRawPtr<Document> contextDocument = elementDocument->contextDocument().get();
if (!contextDocument)
return;
@@ -391,13 +379,11 @@ void ScriptLoader::notifyFinished(Resource* resource)
ASSERT_UNUSED(resource, resource == m_resource);
if (!m_resource)
return;
- CORSEnabled corsEnabled = isPotentiallyCORSEnabled() ? PotentiallyCORSEnabled : NotCORSEnabled;
- if (!elementDocument->fetcher()->canAccess(m_resource.get(), corsEnabled)) {
+ if (m_resource->errorOccurred()) {
dispatchErrorEvent();
contextDocument->scriptRunner()->notifyScriptLoadError(this, m_willExecuteInOrder ? ScriptRunner::IN_ORDER_EXECUTION : ScriptRunner::ASYNC_EXECUTION);
return;
}
-
if (m_willExecuteInOrder)
contextDocument->scriptRunner()->notifyScriptReady(this, ScriptRunner::IN_ORDER_EXECUTION);
else
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h
index 72f51972005..83acaecfe42 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptLoader.h
@@ -35,7 +35,7 @@ class ScriptLoaderClient;
class ScriptSourceCode;
-class ScriptLoader : private ResourceClient {
+class ScriptLoader FINAL : private ResourceClient {
public:
static PassOwnPtr<ScriptLoader> create(Element*, bool createdByParser, bool isEvaluated);
virtual ~ScriptLoader();
@@ -50,12 +50,6 @@ public:
void executeScript(const ScriptSourceCode&);
void execute(ScriptResource*);
- // Check if potentially cross-origin enabled script is accessible
- // prior to execution. Returns 'false' if not accessible, signalling
- // that callers must not dispatch load events as the cross-origin
- // fetch failed.
- bool executePotentiallyCrossOriginScript(const ScriptSourceCode&);
-
// XML parser calls these
void dispatchLoadEvent();
void dispatchErrorEvent();
@@ -71,7 +65,6 @@ public:
bool isParserInserted() const { return m_parserInserted; }
bool alreadyStarted() const { return m_alreadyStarted; }
bool forceAsync() const { return m_forceAsync; }
- bool isPotentiallyCORSEnabled() const { return m_isPotentiallyCORSEnabled; }
// Helper functions used by our parent classes.
void didNotifySubtreeInsertionsToDocument();
@@ -105,7 +98,6 @@ private:
bool m_willExecuteWhenDocumentFinishedParsing : 1;
bool m_forceAsync : 1;
bool m_willExecuteInOrder : 1;
- bool m_isPotentiallyCORSEnabled : 1;
String m_characterEncoding;
String m_fallbackCharacterEncoding;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
index 2fbf959c598..21798469eed 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.cpp
@@ -31,6 +31,7 @@
#include "core/dom/PendingScript.h"
#include "core/dom/ScriptLoader.h"
#include "core/fetch/ScriptResource.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -43,12 +44,6 @@ ScriptRunner::ScriptRunner(Document* document)
ScriptRunner::~ScriptRunner()
{
- for (size_t i = 0; i < m_scriptsToExecuteSoon.size(); ++i)
- m_document->decrementLoadEventDelayCount();
- for (size_t i = 0; i < m_scriptsToExecuteInOrder.size(); ++i)
- m_document->decrementLoadEventDelayCount();
- for (size_t i = 0; i < m_pendingAsyncScripts.size(); ++i)
- m_document->decrementLoadEventDelayCount();
}
void ScriptRunner::queueScriptForExecution(ScriptLoader* scriptLoader, ResourcePtr<ScriptResource> resource, ExecutionType executionType)
@@ -81,7 +76,7 @@ void ScriptRunner::suspend()
void ScriptRunner::resume()
{
if (hasPendingScripts())
- m_timer.startOneShot(0);
+ m_timer.startOneShot(0, FROM_HERE);
}
void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, ExecutionType executionType)
@@ -96,7 +91,7 @@ void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, ExecutionType e
ASSERT(!m_scriptsToExecuteInOrder.isEmpty());
break;
}
- m_timer.startOneShot(0);
+ m_timer.startOneShot(0, FROM_HERE);
}
void ScriptRunner::notifyScriptLoadError(ScriptLoader* scriptLoader, ExecutionType executionType)
@@ -118,7 +113,7 @@ void ScriptRunner::timerFired(Timer<ScriptRunner>* timer)
{
ASSERT_UNUSED(timer, timer == &m_timer);
- RefPtr<Document> protect(m_document);
+ RefPtrWillBeRawPtr<Document> protect(m_document.get());
Vector<PendingScript> scripts;
scripts.swap(m_scriptsToExecuteSoon);
@@ -132,10 +127,18 @@ void ScriptRunner::timerFired(Timer<ScriptRunner>* timer)
size_t size = scripts.size();
for (size_t i = 0; i < size; ++i) {
ScriptResource* resource = scripts[i].resource();
- RefPtr<Element> element = scripts[i].releaseElementAndClear();
+ RefPtrWillBeRawPtr<Element> element = scripts[i].releaseElementAndClear();
toScriptLoaderIfPossible(element.get())->execute(resource);
m_document->decrementLoadEventDelayCount();
}
}
+void ScriptRunner::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_scriptsToExecuteInOrder);
+ visitor->trace(m_scriptsToExecuteSoon);
+ visitor->trace(m_pendingAsyncScripts);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h b/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h
index b47139c8629..a24ca26a090 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptRunner.h
@@ -28,6 +28,7 @@
#include "core/fetch/ResourcePtr.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
@@ -40,10 +41,13 @@ class Document;
class PendingScript;
class ScriptLoader;
-class ScriptRunner {
- WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED;
+class ScriptRunner FINAL : public NoBaseWillBeGarbageCollectedFinalized<ScriptRunner> {
+ WTF_MAKE_NONCOPYABLE(ScriptRunner); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<ScriptRunner> create(Document* document) { return adoptPtr(new ScriptRunner(document)); }
+ static PassOwnPtrWillBeRawPtr<ScriptRunner> create(Document* document)
+ {
+ return adoptPtrWillBeNoop(new ScriptRunner(document));
+ }
~ScriptRunner();
enum ExecutionType { ASYNC_EXECUTION, IN_ORDER_EXECUTION };
@@ -54,12 +58,16 @@ public:
void notifyScriptReady(ScriptLoader*, ExecutionType);
void notifyScriptLoadError(ScriptLoader*, ExecutionType);
+ void trace(Visitor*);
+
private:
explicit ScriptRunner(Document*);
void timerFired(Timer<ScriptRunner>*);
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
+ // FIXME: Oilpan: consider using heap vectors and hash map here;
+ // PendingScript does have a (trivial) destructor, however.
Vector<PendingScript> m_scriptsToExecuteInOrder;
Vector<PendingScript> m_scriptsToExecuteSoon; // http://www.whatwg.org/specs/web-apps/current-work/#set-of-scripts-that-will-execute-as-soon-as-possible
HashMap<ScriptLoader*, PendingScript> m_pendingAsyncScripts;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp
index 5e8f2f39a2b..6d00efb4b66 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.cpp
@@ -31,12 +31,12 @@
namespace WebCore {
-ScriptableDocumentParser::ScriptableDocumentParser(Document* document, ParserContentPolicy parserContentPolicy)
+ScriptableDocumentParser::ScriptableDocumentParser(Document& document, ParserContentPolicy parserContentPolicy)
: DecodedDataDocumentParser(document)
, m_wasCreatedByScript(false)
, m_parserContentPolicy(parserContentPolicy)
{
- if (!pluginContentIsAllowed(m_parserContentPolicy) && (!document->settings() || document->settings()->unsafePluginPastingEnabled()))
+ if (!pluginContentIsAllowed(m_parserContentPolicy) && (!document.settings() || document.settings()->unsafePluginPastingEnabled()))
m_parserContentPolicy = allowPluginContent(m_parserContentPolicy);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h b/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h
index 18a2f93310f..f5c3867d4d9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptableDocumentParser.h
@@ -54,10 +54,10 @@ public:
ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
protected:
- explicit ScriptableDocumentParser(Document*, ParserContentPolicy = AllowScriptingContent);
+ explicit ScriptableDocumentParser(Document&, ParserContentPolicy = AllowScriptingContent);
private:
- virtual ScriptableDocumentParser* asScriptableDocumentParser() { return this; }
+ virtual ScriptableDocumentParser* asScriptableDocumentParser() OVERRIDE FINAL { return this; }
// http://www.whatwg.org/specs/web-apps/current-work/#script-created-parser
bool m_wasCreatedByScript;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp b/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
index 27a7f6b463f..3f5f9b9e410 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
@@ -29,9 +29,10 @@
#include "core/dom/Document.h"
#include "core/dom/RequestAnimationFrameCallback.h"
#include "core/events/Event.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/DocumentLoader.h"
namespace WebCore {
@@ -52,6 +53,15 @@ ScriptedAnimationController::~ScriptedAnimationController()
{
}
+void ScriptedAnimationController::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_eventQueue);
+#if ENABLE(OILPAN)
+ visitor->trace(m_perFrameEvents);
+#endif
+}
+
void ScriptedAnimationController::suspend()
{
++m_suspendCount;
@@ -74,6 +84,9 @@ ScriptedAnimationController::CallbackId ScriptedAnimationController::registerCal
m_callbacks.append(callback);
scheduleAnimationIfNeeded();
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RequestAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, id));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didRequestAnimationFrame(m_document, id);
return id;
@@ -83,6 +96,9 @@ void ScriptedAnimationController::cancelCallback(CallbackId id)
{
for (size_t i = 0; i < m_callbacks.size(); ++i) {
if (m_callbacks[i]->m_id == id) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "CancelAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, id));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didCancelAnimationFrame(m_document, id);
m_callbacks.remove(i);
return;
@@ -90,6 +106,9 @@ void ScriptedAnimationController::cancelCallback(CallbackId id)
}
for (size_t i = 0; i < m_callbacksToInvoke.size(); ++i) {
if (m_callbacksToInvoke[i]->m_id == id) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "CancelAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, id));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didCancelAnimationFrame(m_document, id);
m_callbacksToInvoke[i]->m_cancelled = true;
// will be removed at the end of executeCallbacks()
@@ -100,7 +119,7 @@ void ScriptedAnimationController::cancelCallback(CallbackId id)
void ScriptedAnimationController::dispatchEvents()
{
- Vector<RefPtr<Event> > events;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > events;
events.swap(m_eventQueue);
m_perFrameEvents.clear();
@@ -109,10 +128,12 @@ void ScriptedAnimationController::dispatchEvents()
// FIXME: we should figure out how to make dispatchEvent properly virtual to avoid
// special casting window.
// FIXME: We should not fire events for nodes that are no longer in the tree.
- if (DOMWindow* window = eventTarget->toDOMWindow())
- window->dispatchEvent(events[i], 0);
+ if (LocalDOMWindow* window = eventTarget->toDOMWindow())
+ window->dispatchEvent(events[i], nullptr);
else
eventTarget->dispatchEvent(events[i]);
+
+ InspectorInstrumentation::didRemoveEvent(eventTarget, events[i].get());
}
}
@@ -133,12 +154,15 @@ void ScriptedAnimationController::executeCallbacks(double monotonicTimeNow)
for (size_t i = 0; i < m_callbacksToInvoke.size(); ++i) {
RequestAnimationFrameCallback* callback = m_callbacksToInvoke[i].get();
if (!callback->m_cancelled) {
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FireAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, callback->m_id));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrame(m_document, callback->m_id);
if (callback->m_useLegacyTimeBase)
callback->handleEvent(legacyHighResNowMs);
else
callback->handleEvent(highResNowMs);
InspectorInstrumentation::didFireAnimationFrame(cookie);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
}
}
@@ -153,7 +177,7 @@ void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTime
if (m_suspendCount)
return;
- RefPtr<ScriptedAnimationController> protect(this);
+ RefPtrWillBeRawPtr<ScriptedAnimationController> protect(this);
dispatchEvents();
executeCallbacks(monotonicTimeNow);
@@ -161,13 +185,14 @@ void ScriptedAnimationController::serviceScriptedAnimations(double monotonicTime
scheduleAnimationIfNeeded();
}
-void ScriptedAnimationController::enqueueEvent(PassRefPtr<Event> event)
+void ScriptedAnimationController::enqueueEvent(PassRefPtrWillBeRawPtr<Event> event)
{
+ InspectorInstrumentation::didEnqueueEvent(event->target(), event.get());
m_eventQueue.append(event);
scheduleAnimationIfNeeded();
}
-void ScriptedAnimationController::enqueuePerFrameEvent(PassRefPtr<Event> event)
+void ScriptedAnimationController::enqueuePerFrameEvent(PassRefPtrWillBeRawPtr<Event> event)
{
if (!m_perFrameEvents.add(eventTargetKey(event.get())).isNewEntry)
return;
diff --git a/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h b/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
index 5f7efb887e9..c148a2f77cb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
@@ -26,6 +26,7 @@
#ifndef ScriptedAnimationController_h
#define ScriptedAnimationController_h
+#include "platform/heap/Handle.h"
#include "wtf/ListHashSet.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -39,14 +40,15 @@ class Event;
class EventTarget;
class RequestAnimationFrameCallback;
-class ScriptedAnimationController : public RefCounted<ScriptedAnimationController> {
+class ScriptedAnimationController : public RefCountedWillBeGarbageCollectedFinalized<ScriptedAnimationController> {
public:
- static PassRefPtr<ScriptedAnimationController> create(Document* document)
+ static PassRefPtrWillBeRawPtr<ScriptedAnimationController> create(Document* document)
{
- return adoptRef(new ScriptedAnimationController(document));
+ return adoptRefWillBeNoop(new ScriptedAnimationController(document));
}
~ScriptedAnimationController();
- void clearDocumentPointer() { m_document = 0; }
+ void trace(Visitor*);
+ void clearDocumentPointer() { m_document = nullptr; }
typedef int CallbackId;
@@ -54,8 +56,8 @@ public:
void cancelCallback(CallbackId);
void serviceScriptedAnimations(double monotonicTimeNow);
- void enqueueEvent(PassRefPtr<Event>);
- void enqueuePerFrameEvent(PassRefPtr<Event>);
+ void enqueueEvent(PassRefPtrWillBeRawPtr<Event>);
+ void enqueuePerFrameEvent(PassRefPtrWillBeRawPtr<Event>);
void suspend();
void resume();
@@ -72,11 +74,11 @@ private:
CallbackList m_callbacks;
CallbackList m_callbacksToInvoke; // only non-empty while inside executeCallbacks
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
CallbackId m_nextCallbackId;
int m_suspendCount;
- Vector<RefPtr<Event> > m_eventQueue;
- ListHashSet<std::pair<const EventTarget*, const StringImpl*> > m_perFrameEvents;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > m_eventQueue;
+ WillBeHeapListHashSet<std::pair<RawPtrWillBeMember<const EventTarget>, const StringImpl*> > m_perFrameEvents;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp
index d0c35303076..9767bf15540 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "core/dom/SecurityContext.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace WebCore {
@@ -47,7 +47,7 @@ void SecurityContext::setSecurityOrigin(PassRefPtr<SecurityOrigin> securityOrigi
m_haveInitializedSecurityOrigin = true;
}
-void SecurityContext::setContentSecurityPolicy(PassOwnPtr<ContentSecurityPolicy> contentSecurityPolicy)
+void SecurityContext::setContentSecurityPolicy(PassRefPtr<ContentSecurityPolicy> contentSecurityPolicy)
{
m_contentSecurityPolicy = contentSecurityPolicy;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h
index b47c6f4906c..07f62ad223a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h
+++ b/chromium/third_party/WebKit/Source/core/dom/SecurityContext.h
@@ -53,7 +53,7 @@ protected:
SecurityContext();
virtual ~SecurityContext();
- void setContentSecurityPolicy(PassOwnPtr<ContentSecurityPolicy>);
+ void setContentSecurityPolicy(PassRefPtr<ContentSecurityPolicy>);
void didFailToInitializeSecurityOrigin() { m_haveInitializedSecurityOrigin = false; }
bool haveInitializedSecurityOrigin() const { return m_haveInitializedSecurityOrigin; }
@@ -61,7 +61,7 @@ protected:
private:
bool m_haveInitializedSecurityOrigin;
RefPtr<SecurityOrigin> m_securityOrigin;
- OwnPtr<ContentSecurityPolicy> m_contentSecurityPolicy;
+ RefPtr<ContentSecurityPolicy> m_contentSecurityPolicy;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp b/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
index 5fcf2ac55a2..9ed695de994 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.cpp
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,94 +28,65 @@
#include "core/dom/SelectorQuery.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/SelectorChecker.h"
-#include "core/css/SelectorCheckerFastPath.h"
#include "core/css/SiblingTraversalStrategies.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/Node.h"
#include "core/dom/StaticNodeList.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
-class SimpleNodeList {
-public:
- virtual ~SimpleNodeList() { }
- virtual bool isEmpty() const = 0;
- virtual Node* next() = 0;
-};
-
-class SingleNodeList : public SimpleNodeList {
-public:
- explicit SingleNodeList(Node* rootNode) : m_currentNode(rootNode) { }
-
- bool isEmpty() const { return !m_currentNode; }
-
- Node* next()
+struct SingleElementSelectorQueryTrait {
+ typedef Element* OutputType;
+ static const bool shouldOnlyMatchFirstElement = true;
+ ALWAYS_INLINE static void appendElement(OutputType& output, Element& element)
{
- Node* current = m_currentNode;
- m_currentNode = 0;
- return current;
+ ASSERT(!output);
+ output = &element;
}
-
-private:
- Node* m_currentNode;
};
-class ClassRootNodeList : public SimpleNodeList {
-public:
- ClassRootNodeList(Node& rootNode, const AtomicString& className)
- : m_className(className)
- , m_rootNode(rootNode)
- , m_currentElement(nextInternal(ElementTraversal::firstWithin(m_rootNode))) { }
-
- bool isEmpty() const { return !m_currentElement; }
-
- Node* next()
+struct AllElementsSelectorQueryTrait {
+ typedef WillBeHeapVector<RefPtrWillBeMember<Node> > OutputType;
+ static const bool shouldOnlyMatchFirstElement = false;
+ ALWAYS_INLINE static void appendElement(OutputType& output, Node& element)
{
- Node* current = m_currentElement;
- ASSERT(current);
- m_currentElement = nextInternal(ElementTraversal::nextSkippingChildren(*m_currentElement, &m_rootNode));
- return current;
+ output.append(&element);
}
-
-private:
- Element* nextInternal(Element* element)
- {
- for (; element; element = ElementTraversal::next(*element, &m_rootNode)) {
- if (element->hasClass() && element->classNames().contains(m_className))
- return element;
- }
- return 0;
- }
-
- const AtomicString& m_className;
- Node& m_rootNode;
- Element* m_currentElement;
};
-class ClassElementList : public SimpleNodeList {
+enum ClassElementListBehavior { AllElements, OnlyRoots };
+
+template <ClassElementListBehavior onlyRoots>
+class ClassElementList {
+ STACK_ALLOCATED();
public:
- ClassElementList(Node& rootNode, const AtomicString& className)
+ ClassElementList(ContainerNode& rootNode, const AtomicString& className)
: m_className(className)
- , m_rootNode(rootNode)
+ , m_rootNode(&rootNode)
, m_currentElement(nextInternal(ElementTraversal::firstWithin(rootNode))) { }
bool isEmpty() const { return !m_currentElement; }
- Node* next()
+ Element* next()
{
- Node* current = m_currentElement;
+ Element* current = m_currentElement;
ASSERT(current);
- m_currentElement = nextInternal(ElementTraversal::next(*m_currentElement, &m_rootNode));
+ if (onlyRoots)
+ m_currentElement = nextInternal(ElementTraversal::nextSkippingChildren(*m_currentElement, m_rootNode));
+ else
+ m_currentElement = nextInternal(ElementTraversal::next(*m_currentElement, m_rootNode));
return current;
}
private:
Element* nextInternal(Element* element)
{
- for (; element; element = ElementTraversal::next(*element, &m_rootNode)) {
+ for (; element; element = ElementTraversal::next(*element, m_rootNode)) {
if (element->hasClass() && element->classNames().contains(m_className))
return element;
}
@@ -122,8 +94,8 @@ private:
}
const AtomicString& m_className;
- Node& m_rootNode;
- Element* m_currentElement;
+ RawPtrWillBeMember<ContainerNode> m_rootNode;
+ RawPtrWillBeMember<Element> m_currentElement;
};
void SelectorDataList::initialize(const CSSSelectorList& selectorList)
@@ -131,27 +103,26 @@ void SelectorDataList::initialize(const CSSSelectorList& selectorList)
ASSERT(m_selectors.isEmpty());
unsigned selectorCount = 0;
- for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector))
selectorCount++;
+ m_crossesTreeBoundary = false;
m_selectors.reserveInitialCapacity(selectorCount);
- for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
- m_selectors.uncheckedAppend(SelectorData(selector, SelectorCheckerFastPath::canUse(selector)));
+ unsigned index = 0;
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector), ++index) {
+ m_selectors.uncheckedAppend(selector);
+ m_crossesTreeBoundary |= selectorList.selectorCrossesTreeScopes(index);
+ }
}
-inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element& element, const Node& rootNode) const
+inline bool SelectorDataList::selectorMatches(const CSSSelector& selector, Element& element, const ContainerNode& rootNode) const
{
- if (selectorData.isFastCheckable && !element.isSVGElement()) {
- SelectorCheckerFastPath selectorCheckerFastPath(selectorData.selector, element);
- if (!selectorCheckerFastPath.matchesRightmostSelector(SelectorChecker::VisitedMatchDisabled))
- return false;
- return selectorCheckerFastPath.matches();
- }
-
SelectorChecker selectorChecker(element.document(), SelectorChecker::QueryingRules);
- SelectorChecker::SelectorCheckingContext selectorCheckingContext(selectorData.selector, &element, SelectorChecker::VisitedMatchDisabled);
+ SelectorChecker::SelectorCheckingContext selectorCheckingContext(selector, &element, SelectorChecker::VisitedMatchDisabled);
selectorCheckingContext.behaviorAtBoundary = SelectorChecker::StaysWithinTreeScope;
- selectorCheckingContext.scope = !rootNode.isDocumentNode() && rootNode.isContainerNode() ? &toContainerNode(rootNode) : 0;
+ selectorCheckingContext.scope = !rootNode.isDocumentNode() ? &rootNode : 0;
+ if (selectorCheckingContext.scope)
+ selectorCheckingContext.behaviorAtBoundary = static_cast<SelectorChecker::BehaviorAtBoundary>(SelectorChecker::StaysWithinTreeScope | SelectorChecker::ScopeContainsLastMatchedElement);
return selectorChecker.match(selectorCheckingContext, DOMSiblingTraversalStrategy()) == SelectorChecker::SelectorMatches;
}
@@ -159,65 +130,57 @@ bool SelectorDataList::matches(Element& targetElement) const
{
unsigned selectorCount = m_selectors.size();
for (unsigned i = 0; i < selectorCount; ++i) {
- if (selectorMatches(m_selectors[i], targetElement, targetElement))
+ if (selectorMatches(*m_selectors[i], targetElement, targetElement))
return true;
}
return false;
}
-PassRefPtr<NodeList> SelectorDataList::queryAll(Node& rootNode) const
+PassRefPtrWillBeRawPtr<StaticNodeList> SelectorDataList::queryAll(ContainerNode& rootNode) const
{
- Vector<RefPtr<Node> > result;
- executeQueryAll(rootNode, result);
+ WillBeHeapVector<RefPtrWillBeMember<Node> > result;
+ execute<AllElementsSelectorQueryTrait>(rootNode, result);
return StaticNodeList::adopt(result);
}
-PassRefPtr<Element> SelectorDataList::queryFirst(Node& rootNode) const
+PassRefPtrWillBeRawPtr<Element> SelectorDataList::queryFirst(ContainerNode& rootNode) const
{
- return executeQueryFirst(rootNode);
+ Element* matchedElement = 0;
+ execute<SingleElementSelectorQueryTrait>(rootNode, matchedElement);
+ return matchedElement;
}
-void SelectorDataList::collectElementsByClassName(Node& rootNode, const AtomicString& className, Vector<RefPtr<Node> >& traversalRoots) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::collectElementsByClassName(ContainerNode& rootNode, const AtomicString& className, typename SelectorQueryTrait::OutputType& output) const
{
for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- if (element->hasClass() && element->classNames().contains(className))
- traversalRoots.append(element);
- }
-}
-
-void SelectorDataList::collectElementsByTagName(Node& rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >& traversalRoots) const
-{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- if (SelectorChecker::tagMatches(*element, tagName))
- traversalRoots.append(element);
- }
-}
-
-Element* SelectorDataList::findElementByClassName(Node& rootNode, const AtomicString& className) const
-{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- if (element->hasClass() && element->classNames().contains(className))
- return element;
+ if (element->hasClass() && element->classNames().contains(className)) {
+ SelectorQueryTrait::appendElement(output, *element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
- return 0;
}
-Element* SelectorDataList::findElementByTagName(Node& rootNode, const QualifiedName& tagName) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::collectElementsByTagName(ContainerNode& rootNode, const QualifiedName& tagName, typename SelectorQueryTrait::OutputType& output) const
{
for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- if (SelectorChecker::tagMatches(*element, tagName))
- return element;
+ if (SelectorChecker::tagMatches(*element, tagName)) {
+ SelectorQueryTrait::appendElement(output, *element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
- return 0;
}
-inline bool SelectorDataList::canUseFastQuery(const Node& rootNode) const
+inline bool SelectorDataList::canUseFastQuery(const ContainerNode& rootNode) const
{
- return m_selectors.size() == 1 && rootNode.inDocument() && !rootNode.document().inQuirksMode();
+ return m_selectors.size() == 1 && !m_crossesTreeBoundary && rootNode.inDocument() && !rootNode.document().inQuirksMode();
}
-inline bool ancestorHasClassName(Node& rootNode, const AtomicString& className)
+inline bool ancestorHasClassName(ContainerNode& rootNode, const AtomicString& className)
{
if (!rootNode.isElementNode())
return false;
@@ -237,48 +200,53 @@ inline bool ancestorHasClassName(Node& rootNode, const AtomicString& className)
//
// The travseralRoots may be empty, regardless of the returned bool value, if this method finds that the selectors won't
// match any element.
-PassOwnPtr<SimpleNodeList> SelectorDataList::findTraverseRoots(Node& rootNode, bool& matchTraverseRoots) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::findTraverseRootsAndExecute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
// We need to return the matches in document order. To use id lookup while there is possiblity of multiple matches
// we would need to sort the results. For now, just traverse the document in that case.
ASSERT(m_selectors.size() == 1);
- ASSERT(m_selectors[0].selector);
bool isRightmostSelector = true;
bool startFromParent = false;
- for (const CSSSelector* selector = m_selectors[0].selector; selector; selector = selector->tagHistory()) {
- if (selector->m_match == CSSSelector::Id && !rootNode.document().containsMultipleElementsWithId(selector->value())) {
+ for (const CSSSelector* selector = m_selectors[0]; selector; selector = selector->tagHistory()) {
+ if (selector->match() == CSSSelector::Id && !rootNode.document().containsMultipleElementsWithId(selector->value())) {
Element* element = rootNode.treeScope().getElementById(selector->value());
- Node* adjustedNode = &rootNode;
+ ContainerNode* adjustedNode = &rootNode;
if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
adjustedNode = element;
else if (!element || isRightmostSelector)
adjustedNode = 0;
if (isRightmostSelector) {
- matchTraverseRoots = true;
- return adoptPtr(new SingleNodeList(adjustedNode));
+ executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adjustedNode, MatchesTraverseRoots, rootNode, output);
+ return;
}
+
if (startFromParent && adjustedNode)
adjustedNode = adjustedNode->parentNode();
- matchTraverseRoots = false;
- return adoptPtr(new SingleNodeList(adjustedNode));
+ executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], adjustedNode, DoesNotMatchTraverseRoots, rootNode, output);
+ return;
}
// If we have both CSSSelector::Id and CSSSelector::Class at the same time, we should use Id
// to find traverse root.
- if (!startFromParent && selector->m_match == CSSSelector::Class) {
+ if (!SelectorQueryTrait::shouldOnlyMatchFirstElement && !startFromParent && selector->match() == CSSSelector::Class) {
if (isRightmostSelector) {
- matchTraverseRoots = true;
- return adoptPtr(new ClassElementList(rootNode, selector->value()));
+ ClassElementList<AllElements> traverseRoots(rootNode, selector->value());
+ executeForTraverseRoots<SelectorQueryTrait>(*m_selectors[0], traverseRoots, MatchesTraverseRoots, rootNode, output);
+ return;
}
- matchTraverseRoots = false;
// Since there exists some ancestor element which has the class name, we need to see all children of rootNode.
- if (ancestorHasClassName(rootNode, selector->value()))
- return adoptPtr(new SingleNodeList(&rootNode));
+ if (ancestorHasClassName(rootNode, selector->value())) {
+ executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], &rootNode, DoesNotMatchTraverseRoots, rootNode, output);
+ return;
+ }
- return adoptPtr(new ClassRootNodeList(rootNode, selector->value()));
+ ClassElementList<OnlyRoots> traverseRoots(rootNode, selector->value());
+ executeForTraverseRoots<SelectorQueryTrait>(*m_selectors[0], traverseRoots, DoesNotMatchTraverseRoots, rootNode, output);
+ return;
}
if (selector->relation() == CSSSelector::SubSelector)
@@ -290,187 +258,223 @@ PassOwnPtr<SimpleNodeList> SelectorDataList::findTraverseRoots(Node& rootNode, b
startFromParent = false;
}
- matchTraverseRoots = false;
- return adoptPtr(new SingleNodeList(&rootNode));
+ executeForTraverseRoot<SelectorQueryTrait>(*m_selectors[0], &rootNode, DoesNotMatchTraverseRoots, rootNode, output);
}
-void SelectorDataList::executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::executeForTraverseRoot(const CSSSelector& selector, ContainerNode* traverseRoot, MatchTraverseRootState matchTraverseRoot, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
- for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- for (unsigned i = 0; i < m_selectors.size(); ++i) {
- if (selectorMatches(m_selectors[i], *element, rootNode)) {
- matchedElements.append(element);
- break;
- }
- }
- }
-}
+ if (!traverseRoot)
+ return;
-void SelectorDataList::executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const
-{
- if (!canUseFastQuery(rootNode))
- return executeSlowQueryAll(rootNode, matchedElements);
+ if (matchTraverseRoot) {
+ if (selectorMatches(selector, toElement(*traverseRoot), rootNode))
+ SelectorQueryTrait::appendElement(output, toElement(*traverseRoot));
+ return;
+ }
- ASSERT(m_selectors.size() == 1);
- ASSERT(m_selectors[0].selector);
-
- const CSSSelector* firstSelector = m_selectors[0].selector;
-
- if (!firstSelector->tagHistory()) {
- // Fast path for querySelectorAll('#id'), querySelectorAl('.foo'), and querySelectorAll('div').
- switch (firstSelector->m_match) {
- case CSSSelector::Id:
- {
- if (rootNode.document().containsMultipleElementsWithId(firstSelector->value()))
- break;
-
- // Just the same as getElementById.
- Element* element = rootNode.treeScope().getElementById(firstSelector->value());
- if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
- matchedElements.append(element);
+ for (Element* element = ElementTraversal::firstWithin(*traverseRoot); element; element = ElementTraversal::next(*element, traverseRoot)) {
+ if (selectorMatches(selector, *element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, *element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
return;
- }
- case CSSSelector::Class:
- return collectElementsByClassName(rootNode, firstSelector->value(), matchedElements);
- case CSSSelector::Tag:
- return collectElementsByTagName(rootNode, firstSelector->tagQName(), matchedElements);
- default:
- break; // If we need another fast path, add here.
}
}
+}
- bool matchTraverseRoots;
- OwnPtr<SimpleNodeList> traverseRoots = findTraverseRoots(rootNode, matchTraverseRoots);
- if (traverseRoots->isEmpty())
+template <typename SelectorQueryTrait, typename SimpleElementListType>
+void SelectorDataList::executeForTraverseRoots(const CSSSelector& selector, SimpleElementListType& traverseRoots, MatchTraverseRootState matchTraverseRoots, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
+{
+ if (traverseRoots.isEmpty())
return;
- const SelectorData& selector = m_selectors[0];
if (matchTraverseRoots) {
- while (!traverseRoots->isEmpty()) {
- Node& node = *traverseRoots->next();
- Element& element = toElement(node);
- if (selectorMatches(selector, element, rootNode))
- matchedElements.append(&element);
+ while (!traverseRoots.isEmpty()) {
+ Element& element = *traverseRoots.next();
+ if (selectorMatches(selector, element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
return;
}
- while (!traverseRoots->isEmpty()) {
- Node* traverseRoot = traverseRoots->next();
- ASSERT(traverseRoot);
- for (Element* element = ElementTraversal::firstWithin(*traverseRoot); element; element = ElementTraversal::next(*element, traverseRoot)) {
- if (selectorMatches(selector, *element, rootNode))
- matchedElements.append(element);
+ while (!traverseRoots.isEmpty()) {
+ Element& traverseRoot = *traverseRoots.next();
+ for (Element* element = ElementTraversal::firstWithin(traverseRoot); element; element = ElementTraversal::next(*element, &traverseRoot)) {
+ if (selectorMatches(selector, *element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, *element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
}
}
-// If matchTraverseRoot is true, the returned Node is the single Element that may match the selector query.
-//
-// If matchTraverseRoot is false, the returned Node is the rootNode parameter or a descendant of rootNode representing
-// the subtree for which we can limit the querySelector traversal.
-//
-// The returned Node may be 0, regardless of matchTraverseRoot, if this method finds that the selectors won't
-// match any element.
-Node* SelectorDataList::findTraverseRoot(Node& rootNode, bool& matchTraverseRoot) const
+template <typename SelectorQueryTrait>
+bool SelectorDataList::selectorListMatches(ContainerNode& rootNode, Element& element, typename SelectorQueryTrait::OutputType& output) const
{
- // We need to return the matches in document order. To use id lookup while there is possiblity of multiple matches
- // we would need to sort the results. For now, just traverse the document in that case.
- ASSERT(m_selectors.size() == 1);
- ASSERT(m_selectors[0].selector);
-
- bool matchSingleNode = true;
- bool startFromParent = false;
- for (const CSSSelector* selector = m_selectors[0].selector; selector; selector = selector->tagHistory()) {
- if (selector->m_match == CSSSelector::Id && !rootNode.document().containsMultipleElementsWithId(selector->value())) {
- Element* element = rootNode.treeScope().getElementById(selector->value());
- Node* adjustedRootNode = &rootNode;
- if (element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
- adjustedRootNode = element;
- else if (!element || matchSingleNode)
- adjustedRootNode = 0;
- if (matchSingleNode) {
- matchTraverseRoot = true;
- return adjustedRootNode;
- }
- if (startFromParent && adjustedRootNode)
- adjustedRootNode = adjustedRootNode->parentNode();
- matchTraverseRoot = false;
- return adjustedRootNode;
+ for (unsigned i = 0; i < m_selectors.size(); ++i) {
+ if (selectorMatches(*m_selectors[i], element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, element);
+ return true;
}
- if (selector->relation() == CSSSelector::SubSelector)
- continue;
- matchSingleNode = false;
- if (selector->relation() == CSSSelector::DirectAdjacent || selector->relation() == CSSSelector::IndirectAdjacent)
- startFromParent = true;
- else
- startFromParent = false;
}
- matchTraverseRoot = false;
- return &rootNode;
+ return false;
}
-Element* SelectorDataList::executeSlowQueryFirst(Node& rootNode) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::executeSlow(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
- for (unsigned i = 0; i < m_selectors.size(); ++i) {
- if (selectorMatches(m_selectors[i], *element, rootNode))
- return element;
+ if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output) && SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
+}
+
+// FIXME: Move the following helper functions, authorShadowRootOf, firstWithinTraversingShadowTree,
+// nextTraversingShadowTree to the best place, e.g. NodeTraversal.
+static ShadowRoot* authorShadowRootOf(const ContainerNode& node)
+{
+ if (!node.isElementNode() || !isShadowHost(&node))
+ return 0;
+
+ ElementShadow* shadow = toElement(node).shadow();
+ ASSERT(shadow);
+ for (ShadowRoot* shadowRoot = shadow->oldestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) {
+ if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot)
+ return shadowRoot;
+ }
+ return 0;
+}
+
+static ContainerNode* firstWithinTraversingShadowTree(const ContainerNode& rootNode)
+{
+ if (ShadowRoot* shadowRoot = authorShadowRootOf(rootNode))
+ return shadowRoot;
+ return ElementTraversal::firstWithin(rootNode);
+}
+
+static ContainerNode* nextTraversingShadowTree(const ContainerNode& node, const ContainerNode* rootNode)
+{
+ if (ShadowRoot* shadowRoot = authorShadowRootOf(node))
+ return shadowRoot;
+
+ const ContainerNode* current = &node;
+ while (current) {
+ if (Element* next = ElementTraversal::next(*current, rootNode))
+ return next;
+
+ if (!current->isInShadowTree())
+ return 0;
+
+ ShadowRoot* shadowRoot = current->containingShadowRoot();
+ if (shadowRoot == rootNode)
+ return 0;
+ if (ShadowRoot* youngerShadowRoot = shadowRoot->youngerShadowRoot()) {
+ // Should not obtain any elements in user-agent shadow root.
+ ASSERT(youngerShadowRoot->type() == ShadowRoot::AuthorShadowRoot);
+ return youngerShadowRoot;
}
+
+ current = shadowRoot->host();
+ }
+ return 0;
+}
+
+template <typename SelectorQueryTrait>
+void SelectorDataList::executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
+{
+ for (ContainerNode* node = firstWithinTraversingShadowTree(rootNode); node; node = nextTraversingShadowTree(*node, &rootNode)) {
+ if (!node->isElementNode())
+ continue;
+ Element* element = toElement(node);
+ if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output) && SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
+}
+
+const CSSSelector* SelectorDataList::selectorForIdLookup(const CSSSelector& firstSelector) const
+{
+ for (const CSSSelector* selector = &firstSelector; selector; selector = selector->tagHistory()) {
+ if (selector->match() == CSSSelector::Id)
+ return selector;
+ if (selector->relation() != CSSSelector::SubSelector)
+ break;
}
return 0;
}
-Element* SelectorDataList::executeQueryFirst(Node& rootNode) const
+template <typename SelectorQueryTrait>
+void SelectorDataList::execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
{
- if (!canUseFastQuery(rootNode))
- return executeSlowQueryFirst(rootNode);
-
-
- const CSSSelector* selector = m_selectors[0].selector;
- ASSERT(selector);
-
- if (!selector->tagHistory()) {
- // Fast path for querySelector('#id'), querySelector('.foo'), and querySelector('div').
- // Many web developers uses querySelector with these simple selectors.
- switch (selector->m_match) {
- case CSSSelector::Id:
- {
- if (rootNode.document().containsMultipleElementsWithId(selector->value()))
- break;
- Element* element = rootNode.treeScope().getElementById(selector->value());
- return element && (isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)) ? element : 0;
+ if (!canUseFastQuery(rootNode)) {
+ if (m_crossesTreeBoundary) {
+ rootNode.document().updateDistributionForNodeIfNeeded(&rootNode);
+ executeSlowTraversingShadowTree<SelectorQueryTrait>(rootNode, output);
+ } else {
+ executeSlow<SelectorQueryTrait>(rootNode, output);
+ }
+ return;
+ }
+
+ ASSERT(m_selectors.size() == 1);
+
+ const CSSSelector& selector = *m_selectors[0];
+ const CSSSelector& firstSelector = selector;
+
+ // Fast path for querySelector*('#id'), querySelector*('tag#id').
+ if (const CSSSelector* idSelector = selectorForIdLookup(firstSelector)) {
+ const AtomicString& idToMatch = idSelector->value();
+ if (rootNode.treeScope().containsMultipleElementsWithId(idToMatch)) {
+ const Vector<Element*>& elements = rootNode.treeScope().getAllElementsById(idToMatch);
+ size_t count = elements.size();
+ for (size_t i = 0; i < count; ++i) {
+ Element& element = *elements[i];
+ if (!(isTreeScopeRoot(rootNode) || element.isDescendantOf(&rootNode)))
+ continue;
+ if (selectorMatches(selector, element, rootNode)) {
+ SelectorQueryTrait::appendElement(output, element);
+ if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
+ return;
+ }
}
+ return;
+ }
+ Element* element = rootNode.treeScope().getElementById(idToMatch);
+ if (!element || !(isTreeScopeRoot(rootNode) || element->isDescendantOf(&rootNode)))
+ return;
+ if (selectorMatches(selector, *element, rootNode))
+ SelectorQueryTrait::appendElement(output, *element);
+ return;
+ }
+
+ if (!firstSelector.tagHistory()) {
+ // Fast path for querySelector*('.foo'), and querySelector*('div').
+ switch (firstSelector.match()) {
case CSSSelector::Class:
- return findElementByClassName(rootNode, selector->value());
+ collectElementsByClassName<SelectorQueryTrait>(rootNode, firstSelector.value(), output);
+ return;
case CSSSelector::Tag:
- return findElementByTagName(rootNode, selector->tagQName());
+ collectElementsByTagName<SelectorQueryTrait>(rootNode, firstSelector.tagQName(), output);
+ return;
default:
break; // If we need another fast path, add here.
}
}
- bool matchTraverseRoot;
- Node* traverseRootNode = findTraverseRoot(rootNode, matchTraverseRoot);
- if (!traverseRootNode)
- return 0;
- if (matchTraverseRoot) {
- ASSERT(m_selectors.size() == 1);
- ASSERT(traverseRootNode->isElementNode());
- Element& element = toElement(*traverseRootNode);
- return selectorMatches(m_selectors[0], element, rootNode) ? &element : 0;
- }
+ findTraverseRootsAndExecute<SelectorQueryTrait>(rootNode, output);
+}
- for (Element* element = ElementTraversal::firstWithin(*traverseRootNode); element; element = ElementTraversal::next(*element, traverseRootNode)) {
- if (selectorMatches(m_selectors[0], *element, rootNode))
- return element;
- }
- return 0;
+PassOwnPtr<SelectorQuery> SelectorQuery::adopt(CSSSelectorList& selectorList)
+{
+ return adoptPtr(new SelectorQuery(selectorList));
}
-SelectorQuery::SelectorQuery(const CSSSelectorList& selectorList)
- : m_selectorList(selectorList)
+SelectorQuery::SelectorQuery(CSSSelectorList& selectorList)
{
+ m_selectorList.adopt(selectorList);
m_selectors.initialize(m_selectorList);
}
@@ -479,12 +483,12 @@ bool SelectorQuery::matches(Element& element) const
return m_selectors.matches(element);
}
-PassRefPtr<NodeList> SelectorQuery::queryAll(Node& rootNode) const
+PassRefPtrWillBeRawPtr<StaticNodeList> SelectorQuery::queryAll(ContainerNode& rootNode) const
{
return m_selectors.queryAll(rootNode);
}
-PassRefPtr<Element> SelectorQuery::queryFirst(Node& rootNode) const
+PassRefPtrWillBeRawPtr<Element> SelectorQuery::queryFirst(ContainerNode& rootNode) const
{
return m_selectors.queryFirst(rootNode);
}
@@ -495,7 +499,7 @@ SelectorQuery* SelectorQueryCache::add(const AtomicString& selectors, const Docu
if (it != m_entries.end())
return it->value.get();
- CSSParser parser(document);
+ BisonCSSParser parser(CSSParserContext(document, 0));
CSSSelectorList selectorList;
parser.parseSelector(selectors, selectorList);
@@ -514,10 +518,7 @@ SelectorQuery* SelectorQueryCache::add(const AtomicString& selectors, const Docu
if (m_entries.size() == maximumSelectorQueryCacheSize)
m_entries.remove(m_entries.begin());
- OwnPtr<SelectorQuery> selectorQuery = adoptPtr(new SelectorQuery(selectorList));
- SelectorQuery* rawSelectorQuery = selectorQuery.get();
- m_entries.add(selectors, selectorQuery.release());
- return rawSelectorQuery;
+ return m_entries.add(selectors, SelectorQuery::adopt(selectorList)).storedValue->value.get();
}
void SelectorQueryCache::invalidate()
diff --git a/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h b/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h
index fb787ab9787..63edd158402 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h
+++ b/chromium/third_party/WebKit/Source/core/dom/SelectorQuery.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +28,7 @@
#define SelectorQuery_h
#include "core/css/CSSSelectorList.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
#include "wtf/text/AtomicStringHash.h"
@@ -34,53 +36,66 @@
namespace WebCore {
class CSSSelector;
+class ContainerNode;
class Document;
class Element;
class ExceptionState;
class Node;
-class NodeList;
class SimpleNodeList;
+class StaticNodeList;
class SpaceSplitString;
class SelectorDataList {
public:
void initialize(const CSSSelectorList&);
bool matches(Element&) const;
- PassRefPtr<NodeList> queryAll(Node& rootNode) const;
- PassRefPtr<Element> queryFirst(Node& rootNode) const;
+ PassRefPtrWillBeRawPtr<StaticNodeList> queryAll(ContainerNode& rootNode) const;
+ PassRefPtrWillBeRawPtr<Element> queryFirst(ContainerNode& rootNode) const;
private:
- struct SelectorData {
- SelectorData(const CSSSelector* selector, bool isFastCheckable) : selector(selector), isFastCheckable(isFastCheckable) { }
- const CSSSelector* selector;
- bool isFastCheckable;
- };
-
- bool canUseFastQuery(const Node& rootNode) const;
- bool selectorMatches(const SelectorData&, Element&, const Node&) const;
- void collectElementsByClassName(Node& rootNode, const AtomicString& className, Vector<RefPtr<Node> >&) const;
- Element* findElementByClassName(Node& rootNode, const AtomicString& className) const;
- void collectElementsByTagName(Node& rootNode, const QualifiedName& tagName, Vector<RefPtr<Node> >&) const;
- Element* findElementByTagName(Node& rootNode, const QualifiedName& tagName) const;
- PassOwnPtr<SimpleNodeList> findTraverseRoots(Node& rootNode, bool& matchTraverseRoots) const;
- void executeSlowQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const;
- void executeQueryAll(Node& rootNode, Vector<RefPtr<Node> >& matchedElements) const;
- Node* findTraverseRoot(Node& rootNode, bool& matchTraverseRoot) const;
- Element* executeSlowQueryFirst(Node& rootNode) const;
- Element* executeQueryFirst(Node& rootNode) const;
-
- Vector<SelectorData> m_selectors;
+ bool canUseFastQuery(const ContainerNode& rootNode) const;
+ bool selectorMatches(const CSSSelector&, Element&, const ContainerNode&) const;
+
+ template <typename SelectorQueryTrait>
+ void collectElementsByClassName(ContainerNode& rootNode, const AtomicString& className, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait>
+ void collectElementsByTagName(ContainerNode& rootNode, const QualifiedName& tagName, typename SelectorQueryTrait::OutputType&) const;
+
+ template <typename SelectorQueryTrait>
+ void findTraverseRootsAndExecute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+
+ enum MatchTraverseRootState { DoesNotMatchTraverseRoots, MatchesTraverseRoots };
+ template <typename SelectorQueryTrait>
+ void executeForTraverseRoot(const CSSSelector&, ContainerNode* traverseRoot, MatchTraverseRootState, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait, typename SimpleElementListType>
+ void executeForTraverseRoots(const CSSSelector&, SimpleElementListType& traverseRoots, MatchTraverseRootState, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+
+ template <typename SelectorQueryTrait>
+ bool selectorListMatches(ContainerNode& rootNode, Element&, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait>
+ void executeSlow(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait>
+ void executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+ template <typename SelectorQueryTrait>
+ void execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+ const CSSSelector* selectorForIdLookup(const CSSSelector&) const;
+
+ Vector<const CSSSelector*> m_selectors;
+ bool m_crossesTreeBoundary;
};
class SelectorQuery {
WTF_MAKE_NONCOPYABLE(SelectorQuery);
WTF_MAKE_FAST_ALLOCATED;
public:
- explicit SelectorQuery(const CSSSelectorList&);
+ static PassOwnPtr<SelectorQuery> adopt(CSSSelectorList&);
+
bool matches(Element&) const;
- PassRefPtr<NodeList> queryAll(Node& rootNode) const;
- PassRefPtr<Element> queryFirst(Node& rootNode) const;
+ PassRefPtrWillBeRawPtr<StaticNodeList> queryAll(ContainerNode& rootNode) const;
+ PassRefPtrWillBeRawPtr<Element> queryFirst(ContainerNode& rootNode) const;
private:
+ explicit SelectorQuery(CSSSelectorList&);
+
SelectorDataList m_selectors;
CSSSelectorList m_selectorList;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
index 4285d26c27f..1dbd6c4941d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
@@ -27,25 +27,24 @@
#include "config.h"
#include "core/dom/ShadowTreeStyleSheetCollection.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Element.h"
#include "core/dom/StyleEngine.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLStyleElement.h"
-#include "core/frame/Settings.h"
namespace WebCore {
using namespace HTMLNames;
ShadowTreeStyleSheetCollection::ShadowTreeStyleSheetCollection(ShadowRoot& shadowRoot)
- : StyleSheetCollection(shadowRoot)
+ : TreeScopeStyleSheetCollection(shadowRoot)
{
}
-void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, StyleSheetCollectionBase& collection)
+void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, StyleSheetCollection& collection)
{
DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
@@ -54,32 +53,30 @@ void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, Sty
StyleSheet* sheet = 0;
CSSStyleSheet* activeSheet = 0;
- if (!node->isHTMLElement() || !node->hasTagName(styleTag))
+ if (!isHTMLStyleElement(*node))
continue;
- Element* element = toElement(node);
- AtomicString title = element->getAttribute(titleAttr);
+ HTMLStyleElement* element = toHTMLStyleElement(node);
+ const AtomicString& title = element->fastGetAttribute(titleAttr);
bool enabledViaScript = false;
- sheet = toHTMLStyleElement(node)->sheet();
+ sheet = element->sheet();
if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
activeSheet = toCSSStyleSheet(sheet);
// FIXME: clarify how PREFERRED or ALTERNATE works in shadow trees.
// Should we set preferred/selected stylesheets name in shadow trees and
// use the name in document?
- AtomicString rel = element->getAttribute(relAttr);
if (!enabledViaScript && sheet && !title.isEmpty()) {
if (engine->preferredStylesheetSetName().isEmpty()) {
- if (element->hasLocalName(styleTag) || !rel.contains("alternate")) {
- engine->setPreferredStylesheetSetName(title);
- engine->setSelectedStylesheetSetName(title);
- }
+ engine->setPreferredStylesheetSetName(title);
+ engine->setSelectedStylesheetSetName(title);
}
if (title != engine->preferredStylesheetSetName())
activeSheet = 0;
}
+ const AtomicString& rel = element->fastGetAttribute(relAttr);
if (rel.contains("alternate") && title.isEmpty())
activeSheet = 0;
@@ -90,9 +87,9 @@ void ShadowTreeStyleSheetCollection::collectStyleSheets(StyleEngine* engine, Sty
}
}
-bool ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
+void ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine, StyleResolverUpdateMode updateMode)
{
- StyleSheetCollectionBase collection;
+ StyleSheetCollection collection;
collectStyleSheets(engine, collection);
StyleSheetChange change;
@@ -113,13 +110,11 @@ bool ShadowTreeStyleSheetCollection::updateActiveStyleSheets(StyleEngine* engine
}
}
if (change.requiresFullStyleRecalc)
- toShadowRoot(m_treeScope.rootNode())->host()->setNeedsStyleRecalc();
+ toShadowRoot(m_treeScope.rootNode()).host()->setNeedsStyleRecalc(SubtreeStyleChange);
m_scopingNodesForStyleScoped.didRemoveScopingNodes();
collection.swap(*this);
updateUsesRemUnits();
-
- return change.requiresFullStyleRecalc;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h b/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h
index b7c13cb39cc..7eaafe5e9f2 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ShadowTreeStyleSheetCollection.h
@@ -28,7 +28,7 @@
#ifndef ShadowTreeStyleSheetCollection_h
#define ShadowTreeStyleSheetCollection_h
-#include "core/dom/StyleSheetCollection.h"
+#include "core/dom/TreeScopeStyleSheetCollection.h"
namespace WebCore {
@@ -38,15 +38,21 @@ class StyleSheet;
class StyleSheetCollection;
class StyleEngine;
-class ShadowTreeStyleSheetCollection FINAL : public StyleSheetCollection {
- WTF_MAKE_NONCOPYABLE(ShadowTreeStyleSheetCollection); WTF_MAKE_FAST_ALLOCATED;
+class ShadowTreeStyleSheetCollection FINAL : public TreeScopeStyleSheetCollection {
+ WTF_MAKE_NONCOPYABLE(ShadowTreeStyleSheetCollection);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
explicit ShadowTreeStyleSheetCollection(ShadowRoot&);
- bool updateActiveStyleSheets(StyleEngine*, StyleResolverUpdateMode);
+ void updateActiveStyleSheets(StyleEngine*, StyleResolverUpdateMode);
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ TreeScopeStyleSheetCollection::trace(visitor);
+ }
private:
- void collectStyleSheets(StyleEngine*, StyleSheetCollectionBase&);
+ void collectStyleSheets(StyleEngine*, StyleSheetCollection&);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp b/chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp
index 63c3da1ef57..4bec8c0ea46 100644
--- a/chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/SpaceSplitString.cpp
@@ -164,7 +164,7 @@ void SpaceSplitString::set(const AtomicString& inputString, bool shouldFoldCase)
if (shouldFoldCase && hasNonASCIIOrUpper(string))
string = string.foldCase();
- m_data = SpaceSplitStringData::create(string);
+ m_data = SpaceSplitStringData::create(AtomicString(string));
}
SpaceSplitStringData::~SpaceSplitStringData()
@@ -175,7 +175,7 @@ SpaceSplitStringData::~SpaceSplitStringData()
PassRefPtr<SpaceSplitStringData> SpaceSplitStringData::create(const AtomicString& string)
{
- SpaceSplitStringData*& data = sharedDataMap().add(string, 0).iterator->value;
+ SpaceSplitStringData*& data = sharedDataMap().add(string, 0).storedValue->value;
if (!data) {
data = new SpaceSplitStringData(string);
return adoptRef(data);
diff --git a/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp
index 10f4b281435..b678d0488b9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.cpp
@@ -30,9 +30,23 @@
#include "core/dom/StaticNodeList.h"
#include "core/dom/Element.h"
+#include <v8.h>
namespace WebCore {
+PassRefPtrWillBeRawPtr<StaticNodeList> StaticNodeList::adopt(WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes)
+{
+ RefPtrWillBeRawPtr<StaticNodeList> nodeList = adoptRefWillBeNoop(new StaticNodeList);
+ nodeList->m_nodes.swap(nodes);
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(nodeList->AllocationSize());
+ return nodeList.release();
+}
+
+StaticNodeList::~StaticNodeList()
+{
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-AllocationSize());
+}
+
unsigned StaticNodeList::length() const
{
return m_nodes.size();
@@ -45,16 +59,10 @@ Node* StaticNodeList::item(unsigned index) const
return 0;
}
-Node* StaticNodeList::namedItem(const AtomicString& elementId) const
+void StaticNodeList::trace(Visitor* visitor)
{
- size_t length = m_nodes.size();
- for (size_t i = 0; i < length; ++i) {
- Node* node = m_nodes[i].get();
- if (node->isElementNode() && toElement(node)->getIdAttribute() == elementId)
- return node;
- }
-
- return 0;
+ visitor->trace(m_nodes);
+ NodeList::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h b/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h
index fd66b3aa957..62e22e8be77 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StaticNodeList.h
@@ -29,6 +29,7 @@
#ifndef StaticNodeList_h
#define StaticNodeList_h
+#include "core/dom/Node.h"
#include "core/dom/NodeList.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -40,24 +41,27 @@ class Node;
class StaticNodeList FINAL : public NodeList {
public:
- static PassRefPtr<StaticNodeList> adopt(Vector<RefPtr<Node> >& nodes)
- {
- RefPtr<StaticNodeList> nodeList = adoptRef(new StaticNodeList);
- nodeList->m_nodes.swap(nodes);
- return nodeList.release();
- }
+ static PassRefPtrWillBeRawPtr<StaticNodeList> adopt(WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes);
- static PassRefPtr<StaticNodeList> createEmpty()
+ static PassRefPtrWillBeRawPtr<StaticNodeList> createEmpty()
{
- return adoptRef(new StaticNodeList);
+ return adoptRefWillBeNoop(new StaticNodeList);
}
+ virtual ~StaticNodeList();
+
virtual unsigned length() const OVERRIDE;
virtual Node* item(unsigned index) const OVERRIDE;
- virtual Node* namedItem(const AtomicString&) const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- Vector<RefPtr<Node> > m_nodes;
+ ptrdiff_t AllocationSize()
+ {
+ return m_nodes.capacity() * sizeof(RefPtrWillBeMember<Node>);
+ }
+
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_nodes;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp b/chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp
index 1a1a5fc7495..1b0292092cf 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StringCallback.cpp
@@ -39,14 +39,14 @@ namespace WebCore {
namespace {
-class DispatchCallbackTask : public ExecutionContextTask {
+class DispatchCallbackTask FINAL : public ExecutionContextTask {
public:
static PassOwnPtr<DispatchCallbackTask> create(PassOwnPtr<StringCallback> callback, const String& data)
{
return adoptPtr(new DispatchCallbackTask(callback, data));
}
- virtual void performTask(ExecutionContext*)
+ virtual void performTask(ExecutionContext*) OVERRIDE
{
m_callback->handleEvent(m_data);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp
index 8233785616d..cea6ad5b960 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleElement.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "core/dom/StyleElement.h"
+#include "bindings/v8/ScriptController.h"
#include "core/css/MediaList.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/StyleSheetContents.h"
@@ -28,8 +29,10 @@
#include "core/dom/Element.h"
#include "core/dom/ScriptableDocumentParser.h"
#include "core/dom/StyleEngine.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLStyleElement.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "platform/TraceEvent.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -42,6 +45,7 @@ static bool isCSS(Element* element, const AtomicString& type)
StyleElement::StyleElement(Document* document, bool createdByParser)
: m_createdByParser(createdByParser)
, m_loading(false)
+ , m_registeredAsCandidate(false)
, m_startPosition(TextPosition::belowRangePosition())
{
if (createdByParser && document && document->scriptableDocumentParser() && !document->isInDocumentWrite())
@@ -50,13 +54,19 @@ StyleElement::StyleElement(Document* document, bool createdByParser)
StyleElement::~StyleElement()
{
+#if !ENABLE(OILPAN)
if (m_sheet)
clearSheet();
+#endif
}
void StyleElement::processStyleSheet(Document& document, Element* element)
{
+ TRACE_EVENT0("webkit", "StyleElement::processStyleSheet");
ASSERT(element);
+ ASSERT(element->inDocument());
+
+ m_registeredAsCandidate = true;
document.styleEngine()->addStyleSheetCandidateNode(element, m_createdByParser);
if (m_createdByParser)
return;
@@ -64,17 +74,26 @@ void StyleElement::processStyleSheet(Document& document, Element* element)
process(element);
}
-void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode)
+void StyleElement::removedFromDocument(Document& document, Element* element)
+{
+ removedFromDocument(document, element, 0, document);
+}
+
+void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode, TreeScope& treeScope)
{
ASSERT(element);
- document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode);
- RefPtr<StyleSheet> removedSheet = m_sheet;
+ if (m_registeredAsCandidate) {
+ document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope);
+ m_registeredAsCandidate = false;
+ }
+
+ RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet.get();
if (m_sheet)
- clearSheet();
-
- document.removedStyleSheet(removedSheet.get(), RecalcStyleDeferred, AnalyzedStyleUpdate);
+ clearSheet(element);
+ if (removedSheet)
+ document.removedStyleSheet(removedSheet.get(), AnalyzedStyleUpdate);
}
void StyleElement::clearDocumentData(Document& document, Element* element)
@@ -82,8 +101,11 @@ void StyleElement::clearDocumentData(Document& document, Element* element)
if (m_sheet)
m_sheet->clearOwnerNode();
- if (element->inDocument())
- document.styleEngine()->removeStyleSheetCandidateNode(element, isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0);
+ if (element->inDocument()) {
+ ContainerNode* scopingNode = isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() : 0;
+ TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : element->treeScope();
+ document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope);
+ }
}
void StyleElement::childrenChanged(Element* element)
@@ -109,9 +131,13 @@ void StyleElement::process(Element* element)
createSheet(element, element->textFromChildren());
}
-void StyleElement::clearSheet()
+void StyleElement::clearSheet(Element* ownerElement)
{
ASSERT(m_sheet);
+
+ if (ownerElement && m_sheet->isLoading())
+ ownerElement->document().styleEngine()->removePendingSheet(ownerElement);
+
m_sheet.release()->clearOwnerNode();
}
@@ -120,30 +146,27 @@ void StyleElement::createSheet(Element* e, const String& text)
ASSERT(e);
ASSERT(e->inDocument());
Document& document = e->document();
- if (m_sheet) {
- if (m_sheet->isLoading())
- document.styleEngine()->removePendingSheet(e);
- clearSheet();
- }
+ if (m_sheet)
+ clearSheet(e);
+
+ // Inline style added from an isolated world should bypass the main world's
+ // CSP just as an inline script would.
+ LocalFrame* frame = document.frame();
+ bool shouldBypassMainWorldContentSecurityPolicy = frame && frame->script().shouldBypassMainWorldContentSecurityPolicy();
// If type is empty or CSS, this is a CSS style sheet.
const AtomicString& type = this->type();
- bool passesContentSecurityPolicyChecks = document.contentSecurityPolicy()->allowStyleNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line);
+ bool passesContentSecurityPolicyChecks = shouldBypassMainWorldContentSecurityPolicy || document.contentSecurityPolicy()->allowStyleHash(text) || document.contentSecurityPolicy()->allowStyleNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line);
if (isCSS(e, type) && passesContentSecurityPolicyChecks) {
- RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());
+ RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());
MediaQueryEvaluator screenEval("screen", true);
MediaQueryEvaluator printEval("print", true);
if (screenEval.eval(mediaQueries.get()) || printEval.eval(mediaQueries.get())) {
- document.styleEngine()->addPendingSheet();
m_loading = true;
-
TextPosition startPosition = m_startPosition == TextPosition::belowRangePosition() ? TextPosition::minimumPosition() : m_startPosition;
- m_sheet = CSSStyleSheet::createInline(e, KURL(), startPosition, document.inputEncoding());
+ m_sheet = document.styleEngine()->createSheet(e, text, startPosition, m_createdByParser);
m_sheet->setMediaQueries(mediaQueries.release());
- m_sheet->setTitle(e->title());
- m_sheet->contents()->parseStringAtPosition(text, startPosition, m_createdByParser);
-
m_loading = false;
}
}
@@ -173,4 +196,9 @@ void StyleElement::startLoadingDynamicSheet(Document& document)
document.styleEngine()->addPendingSheet();
}
+void StyleElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_sheet);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleElement.h b/chromium/third_party/WebKit/Source/core/dom/StyleElement.h
index a26f5a52e10..4f76cad04fa 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleElement.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleElement.h
@@ -29,11 +29,13 @@ namespace WebCore {
class ContainerNode;
class Document;
class Element;
+class TreeScope;
-class StyleElement {
+class StyleElement : public WillBeGarbageCollectedMixin {
public:
StyleElement(Document*, bool createdByParser);
virtual ~StyleElement();
+ virtual void trace(Visitor*);
protected:
virtual const AtomicString& type() const = 0;
@@ -46,20 +48,22 @@ protected:
void startLoadingDynamicSheet(Document&);
void processStyleSheet(Document&, Element*);
- void removedFromDocument(Document&, Element*, ContainerNode* scopingNode = 0);
+ void removedFromDocument(Document&, Element*);
+ void removedFromDocument(Document&, Element*, ContainerNode* scopingNode, TreeScope&);
void clearDocumentData(Document&, Element*);
void childrenChanged(Element*);
void finishParsingChildren(Element*);
- RefPtr<CSSStyleSheet> m_sheet;
+ RefPtrWillBeMember<CSSStyleSheet> m_sheet;
private:
void createSheet(Element*, const String& text = String());
void process(Element*);
- void clearSheet();
+ void clearSheet(Element* ownerElement = 0);
- bool m_createdByParser;
- bool m_loading;
+ bool m_createdByParser : 1;
+ bool m_loading : 1;
+ bool m_registeredAsCandidate : 1;
TextPosition m_startPosition;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp
index 54ce1fe3368..901bed5922c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -28,25 +28,23 @@
#include "config.h"
#include "core/dom/StyleEngine.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/CSSStyleSheet.h"
-#include "core/css/StyleInvalidationAnalysis.h"
+#include "core/css/FontFaceCache.h"
#include "core/css/StyleSheetContents.h"
+#include "core/dom/DocumentStyleSheetCollector.h"
#include "core/dom/Element.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/ShadowTreeStyleSheetCollection.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLImport.h"
#include "core/html/HTMLLinkElement.h"
-#include "core/html/HTMLStyleElement.h"
+#include "core/html/imports/HTMLImportsController.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/page/InjectedStyleSheets.h"
#include "core/page/Page.h"
-#include "core/page/PageGroup.h"
#include "core/frame/Settings.h"
-#include "core/svg/SVGStyleElement.h"
#include "platform/URLPatternMatcher.h"
namespace WebCore {
@@ -54,12 +52,15 @@ namespace WebCore {
using namespace HTMLNames;
StyleEngine::StyleEngine(Document& document)
- : m_document(document)
- , m_isMaster(HTMLImport::isMaster(&document))
+ : m_document(&document)
+ , m_isMaster(!document.importsController() || document.importsController()->master() == &document)
, m_pendingStylesheets(0)
, m_injectedStyleSheetCacheValid(false)
- , m_needsUpdateActiveStylesheetsOnStyleRecalc(false)
+#if ENABLE(OILPAN)
+ , m_documentStyleSheetCollection(new DocumentStyleSheetCollection(document))
+#else
, m_documentStyleSheetCollection(document)
+#endif
, m_documentScopeDirty(true)
, m_usesSiblingRules(false)
, m_usesSiblingRulesOverride(false)
@@ -69,16 +70,25 @@ StyleEngine::StyleEngine(Document& document)
, m_maxDirectAdjacentSelectors(0)
, m_ignorePendingStylesheets(false)
, m_didCalculateResolver(false)
- , m_lastResolverAccessCount(0)
- , m_resolverThrowawayTimer(this, &StyleEngine::resolverThrowawayTimerFired)
// We don't need to create CSSFontSelector for imported document or
// HTMLTemplateElement's document, because those documents have no frame.
- , m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : 0)
+ , m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : nullptr)
+ , m_xslStyleSheet(nullptr)
{
+ if (m_fontSelector)
+ m_fontSelector->registerForInvalidationCallbacks(this);
}
StyleEngine::~StyleEngine()
{
+}
+
+#if !ENABLE(OILPAN)
+void StyleEngine::detachFromDocument()
+{
+ // Cleanup is performed eagerly when the StyleEngine is removed from the
+ // document. The StyleEngine is unreachable after this, since only the
+ // document has a reference to it.
for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i)
m_injectedAuthorStyleSheets[i]->clearOwnerNode();
for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
@@ -86,16 +96,21 @@ StyleEngine::~StyleEngine()
if (m_fontSelector) {
m_fontSelector->clearDocument();
- if (m_resolver)
- m_fontSelector->unregisterForInvalidationCallbacks(m_resolver.get());
+ m_fontSelector->unregisterForInvalidationCallbacks(this);
}
+
+ // Decrement reference counts for things we could be keeping alive.
+ m_fontSelector.clear();
+ m_resolver.clear();
+ m_styleSheetCollectionMap.clear();
}
+#endif
inline Document* StyleEngine::master()
{
if (isMaster())
- return &m_document;
- HTMLImport* import = m_document.import();
+ return m_document;
+ HTMLImportsController* import = document().importsController();
if (!import) // Document::import() can return null while executing its destructor.
return 0;
return import->master();
@@ -128,52 +143,39 @@ void StyleEngine::insertTreeScopeInDocumentOrder(TreeScopeSet& treeScopes, TreeS
treeScopes.insertBefore(followingTreeScope, treeScope);
}
-StyleSheetCollection* StyleEngine::ensureStyleSheetCollectionFor(TreeScope& treeScope)
+TreeScopeStyleSheetCollection* StyleEngine::ensureStyleSheetCollectionFor(TreeScope& treeScope)
{
if (treeScope == m_document)
- return &m_documentStyleSheetCollection;
+ return documentStyleSheetCollection();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::AddResult result = m_styleSheetCollectionMap.add(&treeScope, nullptr);
+ StyleSheetCollectionMap::AddResult result = m_styleSheetCollectionMap.add(&treeScope, nullptr);
if (result.isNewEntry)
- result.iterator->value = adoptPtr(new ShadowTreeStyleSheetCollection(toShadowRoot(treeScope)));
- return result.iterator->value.get();
+ result.storedValue->value = adoptPtrWillBeNoop(new ShadowTreeStyleSheetCollection(toShadowRoot(treeScope)));
+ return result.storedValue->value.get();
}
-StyleSheetCollection* StyleEngine::styleSheetCollectionFor(TreeScope& treeScope)
+TreeScopeStyleSheetCollection* StyleEngine::styleSheetCollectionFor(TreeScope& treeScope)
{
if (treeScope == m_document)
- return &m_documentStyleSheetCollection;
+ return documentStyleSheetCollection();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::iterator it = m_styleSheetCollectionMap.find(&treeScope);
+ StyleSheetCollectionMap::iterator it = m_styleSheetCollectionMap.find(&treeScope);
if (it == m_styleSheetCollectionMap.end())
return 0;
return it->value.get();
}
-const Vector<RefPtr<StyleSheet> >& StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope)
+const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope)
{
if (treeScope == m_document)
- return m_documentStyleSheetCollection.styleSheetsForStyleSheetList();
+ return documentStyleSheetCollection()->styleSheetsForStyleSheetList();
return ensureStyleSheetCollectionFor(treeScope)->styleSheetsForStyleSheetList();
}
-const Vector<RefPtr<CSSStyleSheet> >& StyleEngine::activeAuthorStyleSheets() const
-{
- return m_documentStyleSheetCollection.activeAuthorStyleSheets();
-}
-
-void StyleEngine::getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const
+const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& StyleEngine::activeAuthorStyleSheets() const
{
- activeAuthorStyleSheets.append(&m_documentStyleSheetCollection.activeAuthorStyleSheets());
-
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values begin = m_styleSheetCollectionMap.values().begin();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values end = m_styleSheetCollectionMap.values().end();
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> >::const_iterator::Values it = begin;
- for (; it != end; ++it) {
- const StyleSheetCollection* collection = it->get();
- activeAuthorStyleSheets.append(&collection->activeAuthorStyleSheets());
- }
+ return documentStyleSheetCollection()->activeAuthorStyleSheets();
}
void StyleEngine::combineCSSFeatureFlags(const RuleFeatureSet& features)
@@ -191,7 +193,7 @@ void StyleEngine::resetCSSFeatureFlags(const RuleFeatureSet& features)
m_maxDirectAdjacentSelectors = features.maxDirectAdjacentSelectors();
}
-const Vector<RefPtr<CSSStyleSheet> >& StyleEngine::injectedAuthorStyleSheets() const
+const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& StyleEngine::injectedAuthorStyleSheets() const
{
updateInjectedStyleSheetCache();
return m_injectedAuthorStyleSheets;
@@ -204,21 +206,20 @@ void StyleEngine::updateInjectedStyleSheetCache() const
m_injectedStyleSheetCacheValid = true;
m_injectedAuthorStyleSheets.clear();
- Page* owningPage = m_document.page();
+ Page* owningPage = document().page();
if (!owningPage)
return;
- const PageGroup& pageGroup = owningPage->group();
- const InjectedStyleSheetVector& sheets = pageGroup.injectedStyleSheets();
- for (unsigned i = 0; i < sheets.size(); ++i) {
- const InjectedStyleSheet* sheet = sheets[i].get();
- if (sheet->injectedFrames() == InjectStyleInTopFrameOnly && m_document.ownerElement())
+ const InjectedStyleSheetEntryVector& entries = InjectedStyleSheets::instance().entries();
+ for (unsigned i = 0; i < entries.size(); ++i) {
+ const InjectedStyleSheetEntry* entry = entries[i].get();
+ if (entry->injectedFrames() == InjectStyleInTopFrameOnly && document().ownerElement())
continue;
- if (!URLPatternMatcher::matchesPatterns(m_document.url(), sheet->whitelist()))
+ if (!URLPatternMatcher::matchesPatterns(document().url(), entry->whitelist()))
continue;
- RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(&m_document), KURL());
+ RefPtrWillBeRawPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(m_document, KURL());
m_injectedAuthorStyleSheets.append(groupSheet);
- groupSheet->contents()->parseString(sheet->source());
+ groupSheet->contents()->parseString(entry->source());
}
}
@@ -228,38 +229,28 @@ void StyleEngine::invalidateInjectedStyleSheetCache()
markDocumentDirty();
// FIXME: updateInjectedStyleSheetCache is called inside StyleSheetCollection::updateActiveStyleSheets
// and batch updates lots of sheets so we can't call addedStyleSheet() or removedStyleSheet().
- m_document.styleResolverChanged(RecalcStyleDeferred);
+ document().styleResolverChanged();
}
-void StyleEngine::addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet)
+void StyleEngine::addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet)
{
- m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, &m_document));
- m_document.addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
+ m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, m_document));
+ document().addedStyleSheet(m_authorStyleSheets.last().get());
markDocumentDirty();
}
void StyleEngine::addPendingSheet()
{
- master()->styleEngine()->notifyPendingStyleSheetAdded();
+ m_pendingStylesheets++;
}
// This method is called whenever a top-level stylesheet has finished loading.
-void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType notification)
+void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode)
{
- TreeScope* treeScope = isHTMLStyleElement(styleSheetCandidateNode) ? &styleSheetCandidateNode->treeScope() : &m_document;
+ ASSERT(styleSheetCandidateNode);
+ TreeScope* treeScope = isHTMLStyleElement(*styleSheetCandidateNode) ? &styleSheetCandidateNode->treeScope() : m_document.get();
markTreeScopeDirty(*treeScope);
- master()->styleEngine()->notifyPendingStyleSheetRemoved(notification);
-}
-
-void StyleEngine::notifyPendingStyleSheetAdded()
-{
- ASSERT(isMaster());
- m_pendingStylesheets++;
-}
-void StyleEngine::notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationType notification)
-{
- ASSERT(isMaster());
// Make sure we knew this sheet was pending, and that our count isn't out of sync.
ASSERT(m_pendingStylesheets > 0);
@@ -267,14 +258,9 @@ void StyleEngine::notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationT
if (m_pendingStylesheets)
return;
- if (notification == RemovePendingSheetNotifyLater) {
- m_document.setNeedsNotifyRemoveAllPendingStylesheet();
- return;
- }
-
// FIXME: We can't call addedStyleSheet or removedStyleSheet here because we don't know
// what's new. We should track that to tell the style system what changed.
- m_document.didRemoveAllPendingStylesheet();
+ document().didRemoveAllPendingStylesheet();
}
void StyleEngine::modifiedStyleSheet(StyleSheet* sheet)
@@ -286,7 +272,7 @@ void StyleEngine::modifiedStyleSheet(StyleSheet* sheet)
if (!node || !node->inDocument())
return;
- TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+ TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : *m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
markTreeScopeDirty(treeScope);
@@ -297,10 +283,10 @@ void StyleEngine::addStyleSheetCandidateNode(Node* node, bool createdByParser)
if (!node->inDocument())
return;
- TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+ TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : *m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
-
- StyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
+ ASSERT(!isXSLStyleSheet(*node));
+ TreeScopeStyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
ASSERT(collection);
collection->addStyleSheetCandidateNode(node, createdByParser);
@@ -309,12 +295,17 @@ void StyleEngine::addStyleSheetCandidateNode(Node* node, bool createdByParser)
insertTreeScopeInDocumentOrder(m_activeTreeScopes, &treeScope);
}
-void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
+void StyleEngine::removeStyleSheetCandidateNode(Node* node)
+{
+ removeStyleSheetCandidateNode(node, 0, *m_document);
+}
+
+void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode, TreeScope& treeScope)
{
- TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
+ ASSERT(!isXSLStyleSheet(*node));
- StyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
+ TreeScopeStyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
ASSERT(collection);
collection->removeStyleSheetCandidateNode(node, scopingNode);
@@ -322,17 +313,59 @@ void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopi
m_activeTreeScopes.remove(&treeScope);
}
+void StyleEngine::addXSLStyleSheet(ProcessingInstruction* node, bool createdByParser)
+{
+ if (!node->inDocument())
+ return;
+
+ ASSERT(isXSLStyleSheet(*node));
+ bool needToUpdate = false;
+ if (createdByParser || !m_xslStyleSheet) {
+ needToUpdate = !m_xslStyleSheet;
+ } else {
+ unsigned position = m_xslStyleSheet->compareDocumentPositionInternal(node, Node::TreatShadowTreesAsDisconnected);
+ needToUpdate = position & Node::DOCUMENT_POSITION_FOLLOWING;
+ }
+
+ if (!needToUpdate)
+ return;
+
+ markTreeScopeDirty(*m_document);
+ m_xslStyleSheet = node;
+}
+
+void StyleEngine::removeXSLStyleSheet(ProcessingInstruction* node)
+{
+ ASSERT(isXSLStyleSheet(*node));
+ if (m_xslStyleSheet != node)
+ return;
+
+ markTreeScopeDirty(*m_document);
+ m_xslStyleSheet = nullptr;
+}
+
void StyleEngine::modifiedStyleSheetCandidateNode(Node* node)
{
if (!node->inDocument())
return;
- TreeScope& treeScope = isHTMLStyleElement(node) ? node->treeScope() : m_document;
+ TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : *m_document;
ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
markTreeScopeDirty(treeScope);
}
-bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode)
+void StyleEngine::enableExitTransitionStylesheets()
+{
+ TreeScopeStyleSheetCollection* collection = ensureStyleSheetCollectionFor(*m_document);
+ collection->enableExitTransitionStylesheets();
+}
+
+bool StyleEngine::shouldUpdateDocumentStyleSheetCollection(StyleResolverUpdateMode updateMode) const
+{
+ return m_documentScopeDirty || updateMode == FullStyleUpdate;
+}
+
+bool StyleEngine::shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode updateMode) const
{
return !m_dirtyTreeScopes.isEmpty() || updateMode == FullStyleUpdate;
}
@@ -350,48 +383,30 @@ void StyleEngine::clearMediaQueryRuleSetOnTreeScopeStyleSheets(TreeScopeSet tree
void StyleEngine::clearMediaQueryRuleSetStyleSheets()
{
- m_documentStyleSheetCollection.clearMediaQueryRuleSetStyleSheets();
+ documentStyleSheetCollection()->clearMediaQueryRuleSetStyleSheets();
clearMediaQueryRuleSetOnTreeScopeStyleSheets(m_activeTreeScopes);
clearMediaQueryRuleSetOnTreeScopeStyleSheets(m_dirtyTreeScopes);
}
-void StyleEngine::collectDocumentActiveStyleSheets(StyleSheetCollectionBase& collection)
+void StyleEngine::updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector)
{
- ASSERT(isMaster());
-
- if (HTMLImport* rootImport = m_document.import()) {
- for (HTMLImport* import = traverseFirstPostOrder(rootImport); import; import = traverseNextPostOrder(import)) {
- Document* document = import->document();
- if (!document)
- continue;
- StyleEngine* engine = document->styleEngine();
- DocumentStyleSheetCollection::CollectFor collectFor = document == &m_document ?
- DocumentStyleSheetCollection::CollectForList : DocumentStyleSheetCollection::DontCollectForList;
- engine->m_documentStyleSheetCollection.collectStyleSheets(engine, collection, collectFor);
- }
- } else {
- m_documentStyleSheetCollection.collectStyleSheets(this, collection, DocumentStyleSheetCollection::CollectForList);
- }
+ ASSERT(!isMaster());
+ WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > sheetsForList;
+ ImportedDocumentStyleSheetCollector subcollector(parentCollector, sheetsForList);
+ documentStyleSheetCollection()->collectStyleSheets(this, subcollector);
+ documentStyleSheetCollection()->swapSheetsForSheetList(sheetsForList);
}
-bool StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
+void StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
{
ASSERT(isMaster());
+ ASSERT(!document().inStyleRecalc());
- if (m_document.inStyleRecalc()) {
- // SVG <use> element may manage to invalidate style selector in the middle of a style recalc.
- // https://bugs.webkit.org/show_bug.cgi?id=54344
- // FIXME: This should be fixed in SVG and the call site replaced by ASSERT(!m_inStyleRecalc).
- m_needsUpdateActiveStylesheetsOnStyleRecalc = true;
- return false;
-
- }
- if (!m_document.isActive())
- return false;
+ if (!document().isActive())
+ return;
- bool requiresFullStyleRecalc = false;
- if (m_documentScopeDirty || updateMode == FullStyleUpdate)
- requiresFullStyleRecalc = m_documentStyleSheetCollection.updateActiveStyleSheets(this, updateMode);
+ if (shouldUpdateDocumentStyleSheetCollection(updateMode))
+ documentStyleSheetCollection()->updateActiveStyleSheets(this, updateMode);
if (shouldUpdateShadowTreeStyleSheetCollection(updateMode)) {
TreeScopeSet treeScopes = updateMode == FullStyleUpdate ? m_activeTreeScopes : m_dirtyTreeScopes;
@@ -406,44 +421,36 @@ bool StyleEngine::updateActiveStyleSheets(StyleResolverUpdateMode updateMode)
if (!collection->hasStyleSheetCandidateNodes())
treeScopesRemoved.add(treeScope);
}
- if (!treeScopesRemoved.isEmpty())
- for (HashSet<TreeScope*>::iterator it = treeScopesRemoved.begin(); it != treeScopesRemoved.end(); ++it)
- m_activeTreeScopes.remove(*it);
+ m_activeTreeScopes.removeAll(treeScopesRemoved);
}
- m_needsUpdateActiveStylesheetsOnStyleRecalc = false;
- activeStyleSheetsUpdatedForInspector();
- m_usesRemUnits = m_documentStyleSheetCollection.usesRemUnits();
- if (m_documentScopeDirty || updateMode == FullStyleUpdate)
- m_document.notifySeamlessChildDocumentsOfStylesheetUpdate();
+ InspectorInstrumentation::activeStyleSheetsUpdated(m_document);
+ m_usesRemUnits = documentStyleSheetCollection()->usesRemUnits();
m_dirtyTreeScopes.clear();
m_documentScopeDirty = false;
-
- return requiresFullStyleRecalc;
}
-void StyleEngine::activeStyleSheetsUpdatedForInspector()
+const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > StyleEngine::activeStyleSheetsForInspector() const
{
- if (m_activeTreeScopes.isEmpty()) {
- InspectorInstrumentation::activeStyleSheetsUpdated(&m_document, m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
- return;
- }
- Vector<RefPtr<StyleSheet> > activeStyleSheets;
+ if (m_activeTreeScopes.isEmpty())
+ return documentStyleSheetCollection()->activeAuthorStyleSheets();
- activeStyleSheets.append(m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > activeStyleSheets;
- TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
- TreeScopeSet::iterator end = m_activeTreeScopes.end();
- for (TreeScopeSet::iterator it = begin; it != end; ++it) {
- if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
- activeStyleSheets.append(collection->styleSheetsForStyleSheetList());
+ activeStyleSheets.appendVector(documentStyleSheetCollection()->activeAuthorStyleSheets());
+
+ TreeScopeSet::const_iterator begin = m_activeTreeScopes.begin();
+ TreeScopeSet::const_iterator end = m_activeTreeScopes.end();
+ for (TreeScopeSet::const_iterator it = begin; it != end; ++it) {
+ if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
+ activeStyleSheets.appendVector(collection->activeAuthorStyleSheets());
}
// FIXME: Inspector needs a vector which has all active stylesheets.
// However, creating such a large vector might cause performance regression.
// Need to implement some smarter solution.
- InspectorInstrumentation::activeStyleSheetsUpdated(&m_document, activeStyleSheets);
+ return activeStyleSheets;
}
void StyleEngine::didRemoveShadowRoot(ShadowRoot* shadowRoot)
@@ -456,14 +463,14 @@ void StyleEngine::appendActiveAuthorStyleSheets()
ASSERT(isMaster());
m_resolver->setBuildScopedStyleTreeInDocumentOrder(true);
- m_resolver->appendAuthorStyleSheets(0, m_documentStyleSheetCollection.activeAuthorStyleSheets());
+ m_resolver->appendAuthorStyleSheets(documentStyleSheetCollection()->activeAuthorStyleSheets());
TreeScopeSet::iterator begin = m_activeTreeScopes.begin();
TreeScopeSet::iterator end = m_activeTreeScopes.end();
for (TreeScopeSet::iterator it = begin; it != end; ++it) {
- if (StyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it)) {
+ if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it)) {
m_resolver->setBuildScopedStyleTreeInDocumentOrder(!collection->scopingNodesForStyleScoped());
- m_resolver->appendAuthorStyleSheets(0, collection->activeAuthorStyleSheets());
+ m_resolver->appendAuthorStyleSheets(collection->activeAuthorStyleSheets());
}
}
m_resolver->finishAppendAuthorStyleSheets();
@@ -476,22 +483,19 @@ void StyleEngine::createResolver()
// which is not in a frame. Code which hits this should have checked
// Document::isActive() before calling into code which could get here.
- ASSERT(m_document.frame());
- ASSERT(m_fontSelector);
+ ASSERT(document().frame());
- m_resolver = adoptPtr(new StyleResolver(m_document));
+ m_resolver = adoptPtrWillBeNoop(new StyleResolver(*m_document));
appendActiveAuthorStyleSheets();
- m_fontSelector->registerForInvalidationCallbacks(m_resolver.get());
- combineCSSFeatureFlags(m_resolver->ensureRuleFeatureSet());
+ combineCSSFeatureFlags(m_resolver->ensureUpdatedRuleFeatureSet());
}
void StyleEngine::clearResolver()
{
- ASSERT(!m_document.inStyleRecalc());
+ ASSERT(!document().inStyleRecalc());
ASSERT(isMaster() || !m_resolver);
- ASSERT(m_fontSelector || !m_resolver);
if (m_resolver)
- m_fontSelector->unregisterForInvalidationCallbacks(m_resolver.get());
+ document().updateStyleInvalidationIfNeeded();
m_resolver.clear();
}
@@ -506,21 +510,8 @@ unsigned StyleEngine::resolverAccessCount() const
return m_resolver ? m_resolver->accessCount() : 0;
}
-void StyleEngine::resolverThrowawayTimerFired(Timer<StyleEngine>*)
-{
- if (resolverAccessCount() == m_lastResolverAccessCount)
- clearResolver();
- m_lastResolverAccessCount = resolverAccessCount();
-}
-
-void StyleEngine::didAttach()
-{
- m_resolverThrowawayTimer.startRepeating(60);
-}
-
void StyleEngine::didDetach()
{
- m_resolverThrowawayTimer.stop();
clearResolver();
}
@@ -529,53 +520,74 @@ bool StyleEngine::shouldClearResolver() const
return !m_didCalculateResolver && !haveStylesheetsLoaded();
}
-StyleResolverChange StyleEngine::resolverChanged(RecalcStyleTime time, StyleResolverUpdateMode mode)
+bool StyleEngine::shouldApplyXSLTransform() const
{
- StyleResolverChange change;
+ if (!RuntimeEnabledFeatures::xsltEnabled())
+ return false;
+ return m_xslStyleSheet && !m_document->transformSourceDocument();
+}
+void StyleEngine::resolverChanged(StyleResolverUpdateMode mode)
+{
if (!isMaster()) {
if (Document* master = this->master())
- master->styleResolverChanged(time, mode);
- return change;
+ master->styleResolverChanged(mode);
+ return;
}
// Don't bother updating, since we haven't loaded all our style info yet
// and haven't calculated the style selector for the first time.
- if (!m_document.isActive() || shouldClearResolver()) {
+ if (!document().isActive() || shouldClearResolver()) {
clearResolver();
- return change;
+ return;
}
- m_didCalculateResolver = true;
- if (m_document.didLayoutWithPendingStylesheets() && !hasPendingSheets())
- change.setNeedsRepaint();
+ if (shouldApplyXSLTransform()) {
+ // Processing instruction (XML documents only).
+ // We don't support linking to embedded CSS stylesheets, see <https://bugs.webkit.org/show_bug.cgi?id=49281> for discussion.
+ // Don't apply XSL transforms to already transformed documents -- <rdar://problem/4132806>
+ if (!m_document->parsing() && !m_xslStyleSheet->isLoading())
+ m_document->applyXSLTransform(m_xslStyleSheet.get());
+ return;
+ }
- if (updateActiveStyleSheets(mode))
- change.setNeedsStyleRecalc();
+ m_didCalculateResolver = true;
+ updateActiveStyleSheets(mode);
+}
- return change;
+void StyleEngine::clearFontCache()
+{
+ // We should not recreate FontSelector. Instead, clear fontFaceCache.
+ if (m_fontSelector)
+ m_fontSelector->fontFaceCache()->clear();
+ if (m_resolver)
+ m_resolver->invalidateMatchedPropertiesCache();
}
-void StyleEngine::resetFontSelector()
+void StyleEngine::updateGenericFontFamilySettings()
{
+ // FIXME: we should not update generic font family settings when
+ // document is inactive.
+ ASSERT(document().isActive());
+
if (!m_fontSelector)
return;
- m_fontSelector->clearDocument();
- if (m_resolver) {
- m_fontSelector->unregisterForInvalidationCallbacks(m_resolver.get());
+ m_fontSelector->updateGenericFontFamilySettings(*m_document);
+ if (m_resolver)
m_resolver->invalidateMatchedPropertiesCache();
- }
+}
- // If the document has been already detached, we don't need to recreate
- // CSSFontSelector.
- if (m_document.isActive()) {
- m_fontSelector = CSSFontSelector::create(&m_document);
- if (m_resolver)
- m_fontSelector->registerForInvalidationCallbacks(m_resolver.get());
- } else {
- m_fontSelector = 0;
- }
+void StyleEngine::removeFontFaceRules(const WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
+{
+ if (!m_fontSelector)
+ return;
+
+ FontFaceCache* cache = m_fontSelector->fontFaceCache();
+ for (unsigned i = 0; i < fontFaceRules.size(); ++i)
+ cache->remove(fontFaceRules[i]);
+ if (m_resolver)
+ m_resolver->invalidateMatchedPropertiesCache();
}
void StyleEngine::markTreeScopeDirty(TreeScope& scope)
@@ -591,8 +603,99 @@ void StyleEngine::markTreeScopeDirty(TreeScope& scope)
void StyleEngine::markDocumentDirty()
{
m_documentScopeDirty = true;
- if (!HTMLImport::isMaster(&m_document))
- m_document.import()->master()->styleEngine()->markDocumentDirty();
+ if (document().importLoader())
+ document().importsController()->master()->styleEngine()->markDocumentDirty();
+}
+
+static bool isCacheableForStyleElement(const StyleSheetContents& contents)
+{
+ // FIXME: Support copying import rules.
+ if (!contents.importRules().isEmpty())
+ return false;
+ // Until import rules are supported in cached sheets it's not possible for loading to fail.
+ ASSERT(!contents.didLoadErrorOccur());
+ // It is not the original sheet anymore.
+ if (contents.isMutable())
+ return false;
+ if (!contents.hasSyntacticallyValidCSSHeader())
+ return false;
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSStyleSheet> StyleEngine::createSheet(Element* e, const String& text, TextPosition startPosition, bool createdByParser)
+{
+ RefPtrWillBeRawPtr<CSSStyleSheet> styleSheet = nullptr;
+
+ e->document().styleEngine()->addPendingSheet();
+
+ if (!e->document().inQuirksMode()) {
+ AtomicString textContent(text);
+
+ WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<StyleSheetContents> >::AddResult result = m_textToSheetCache.add(textContent, nullptr);
+ if (result.isNewEntry || !result.storedValue->value) {
+ styleSheet = StyleEngine::parseSheet(e, text, startPosition, createdByParser);
+ if (result.isNewEntry && isCacheableForStyleElement(*styleSheet->contents())) {
+ result.storedValue->value = styleSheet->contents();
+ m_sheetToTextCache.add(styleSheet->contents(), textContent);
+ }
+ } else {
+ StyleSheetContents* contents = result.storedValue->value;
+ ASSERT(contents);
+ ASSERT(isCacheableForStyleElement(*contents));
+ ASSERT(contents->singleOwnerDocument() == e->document());
+ styleSheet = CSSStyleSheet::createInline(contents, e, startPosition);
+ }
+ } else {
+ // FIXME: currently we don't cache StyleSheetContents inQuirksMode.
+ styleSheet = StyleEngine::parseSheet(e, text, startPosition, createdByParser);
+ }
+
+ ASSERT(styleSheet);
+ styleSheet->setTitle(e->title());
+ return styleSheet;
+}
+
+PassRefPtrWillBeRawPtr<CSSStyleSheet> StyleEngine::parseSheet(Element* e, const String& text, TextPosition startPosition, bool createdByParser)
+{
+ RefPtrWillBeRawPtr<CSSStyleSheet> styleSheet = nullptr;
+ styleSheet = CSSStyleSheet::createInline(e, KURL(), startPosition, e->document().inputEncoding());
+ styleSheet->contents()->parseStringAtPosition(text, startPosition, createdByParser);
+ return styleSheet;
+}
+
+void StyleEngine::removeSheet(StyleSheetContents* contents)
+{
+ WillBeHeapHashMap<RawPtrWillBeMember<StyleSheetContents>, AtomicString>::iterator it = m_sheetToTextCache.find(contents);
+ if (it == m_sheetToTextCache.end())
+ return;
+
+ m_textToSheetCache.remove(it->value);
+ m_sheetToTextCache.remove(contents);
+}
+
+void StyleEngine::fontsNeedUpdate(CSSFontSelector*)
+{
+ if (!document().isActive())
+ return;
+
+ if (m_resolver)
+ m_resolver->invalidateMatchedPropertiesCache();
+ document().setNeedsStyleRecalc(SubtreeStyleChange);
+}
+
+void StyleEngine::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_injectedAuthorStyleSheets);
+ visitor->trace(m_authorStyleSheets);
+ visitor->trace(m_documentStyleSheetCollection);
+ visitor->trace(m_styleSheetCollectionMap);
+ visitor->trace(m_resolver);
+ visitor->trace(m_fontSelector);
+ visitor->trace(m_textToSheetCache);
+ visitor->trace(m_sheetToTextCache);
+ visitor->trace(m_xslStyleSheet);
+ CSSFontSelectorClient::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleEngine.h b/chromium/third_party/WebKit/Source/core/dom/StyleEngine.h
index e6a4c4d8f09..261b09fa9c1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleEngine.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleEngine.h
@@ -28,10 +28,12 @@
#ifndef StyleEngine_h
#define StyleEngine_h
+#include "core/css/CSSFontSelectorClient.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentOrderedList.h"
#include "core/dom/DocumentStyleSheetCollection.h"
+#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
#include "wtf/ListHashSet.h"
#include "wtf/RefPtr.h"
@@ -48,30 +50,14 @@ class Node;
class RuleFeatureSet;
class ShadowTreeStyleSheetCollection;
class StyleResolver;
+class StyleRuleFontFace;
class StyleSheet;
class StyleSheetCollection;
class StyleSheetContents;
class StyleSheetList;
-class StyleResolverChange {
-public:
- StyleResolverChange()
- : m_needsRepaint(false)
- , m_needsStyleRecalc(false)
- { }
-
- bool needsRepaint() const { return m_needsRepaint; }
- bool needsStyleRecalc() const { return m_needsStyleRecalc; }
- void setNeedsRepaint() { m_needsRepaint = true; }
- void setNeedsStyleRecalc() { m_needsStyleRecalc = true; }
-
-private:
- bool m_needsRepaint;
- bool m_needsStyleRecalc;
-};
-
-class StyleEngine {
- WTF_MAKE_FAST_ALLOCATED;
+class StyleEngine FINAL : public CSSFontSelectorClient {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
class IgnoringPendingStylesheet : public TemporaryChange<bool> {
@@ -84,42 +70,53 @@ public:
friend class IgnoringPendingStylesheet;
- static PassOwnPtr<StyleEngine> create(Document& document) { return adoptPtr(new StyleEngine(document)); }
+ static PassOwnPtrWillBeRawPtr<StyleEngine> create(Document& document) { return adoptPtrWillBeNoop(new StyleEngine(document)); }
~StyleEngine();
- const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&);
- const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
+#if !ENABLE(OILPAN)
+ void detachFromDocument();
+#endif
+
+ const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&);
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() const;
- const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
- const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
+
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > activeStyleSheetsForInspector() const;
void modifiedStyleSheet(StyleSheet*);
void addStyleSheetCandidateNode(Node*, bool createdByParser);
- void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0);
+ void removeStyleSheetCandidateNode(Node*);
+ void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode, TreeScope&);
void modifiedStyleSheetCandidateNode(Node*);
+ void enableExitTransitionStylesheets();
+ void addXSLStyleSheet(ProcessingInstruction*, bool createdByParser);
+ void removeXSLStyleSheet(ProcessingInstruction*);
void invalidateInjectedStyleSheetCache();
void updateInjectedStyleSheetCache() const;
- void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet);
-
- bool needsUpdateActiveStylesheetsOnStyleRecalc() const { return m_needsUpdateActiveStylesheetsOnStyleRecalc; }
+ void addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet);
void clearMediaQueryRuleSetStyleSheets();
- bool updateActiveStyleSheets(StyleResolverUpdateMode);
+ void updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector);
+ void updateActiveStyleSheets(StyleResolverUpdateMode);
String preferredStylesheetSetName() const { return m_preferredStylesheetSetName; }
String selectedStylesheetSetName() const { return m_selectedStylesheetSetName; }
void setPreferredStylesheetSetName(const String& name) { m_preferredStylesheetSetName = name; }
void setSelectedStylesheetSetName(const String& name) { m_selectedStylesheetSetName = name; }
+ void selectStylesheetSetName(const String& name)
+ {
+ setPreferredStylesheetSetName(name);
+ setSelectedStylesheetSetName(name);
+ }
+
void addPendingSheet();
- enum RemovePendingSheetNotificationType {
- RemovePendingSheetNotifyImmediately,
- RemovePendingSheetNotifyLater
- };
- void removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+ void removePendingSheet(Node* styleSheetCandidateNode);
bool hasPendingSheets() const { return m_pendingStylesheets > 0; }
bool haveStylesheetsLoaded() const { return !hasPendingSheets() || m_ignorePendingStylesheets; }
@@ -133,15 +130,13 @@ public:
void setUsesFirstLetterRules(bool b) { m_usesFirstLetterRules = b; }
bool usesRemUnits() const { return m_usesRemUnits; }
void setUsesRemUnit(bool b) { m_usesRemUnits = b; }
- bool hasScopedStyleSheet() { return m_documentStyleSheetCollection.scopingNodesForStyleScoped(); }
+ bool hasScopedStyleSheet() { return documentStyleSheetCollection()->scopingNodesForStyleScoped(); }
void combineCSSFeatureFlags(const RuleFeatureSet&);
void resetCSSFeatureFlags(const RuleFeatureSet&);
- void didModifySeamlessParentStyleSheet() { markDocumentDirty(); }
void didRemoveShadowRoot(ShadowRoot*);
void appendActiveAuthorStyleSheets();
- void getActiveAuthorStyleSheets(Vector<const Vector<RefPtr<CSSStyleSheet> >*>& activeAuthorStyleSheets) const;
StyleResolver* resolver() const
{
@@ -163,30 +158,41 @@ public:
void clearMasterResolver();
CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
- void resetFontSelector();
+ void removeFontFaceRules(const WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >&);
+ void clearFontCache();
+ // updateGenericFontFamilySettings is used from WebSettingsImpl.
+ void updateGenericFontFamilySettings();
- void didAttach();
void didDetach();
bool shouldClearResolver() const;
- StyleResolverChange resolverChanged(RecalcStyleTime, StyleResolverUpdateMode);
+ void resolverChanged(StyleResolverUpdateMode);
unsigned resolverAccessCount() const;
- void collectDocumentActiveStyleSheets(StyleSheetCollectionBase&);
void markDocumentDirty();
+ PassRefPtrWillBeRawPtr<CSSStyleSheet> createSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
+ void removeSheet(StyleSheetContents*);
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ // CSSFontSelectorClient implementation.
+ virtual void fontsNeedUpdate(CSSFontSelector*) OVERRIDE;
+
private:
StyleEngine(Document&);
- StyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&);
- StyleSheetCollection* styleSheetCollectionFor(TreeScope&);
- void activeStyleSheetsUpdatedForInspector();
- bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode);
- void resolverThrowawayTimerFired(Timer<StyleEngine>*);
+ TreeScopeStyleSheetCollection* ensureStyleSheetCollectionFor(TreeScope&);
+ TreeScopeStyleSheetCollection* styleSheetCollectionFor(TreeScope&);
+ bool shouldUpdateDocumentStyleSheetCollection(StyleResolverUpdateMode) const;
+ bool shouldUpdateShadowTreeStyleSheetCollection(StyleResolverUpdateMode) const;
+ bool shouldApplyXSLTransform() const;
void markTreeScopeDirty(TreeScope&);
bool isMaster() const { return m_isMaster; }
Document* master();
+ Document& document() const { return *m_document; }
typedef ListHashSet<TreeScope*, 16> TreeScopeSet;
static void insertTreeScopeInDocumentOrder(TreeScopeSet&, TreeScope*);
@@ -194,10 +200,28 @@ private:
void createResolver();
- void notifyPendingStyleSheetAdded();
- void notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationType);
+ static PassRefPtrWillBeRawPtr<CSSStyleSheet> parseSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
+
+ // FIXME: Oilpan: clean this const madness up once oilpan ships.
+ const DocumentStyleSheetCollection* documentStyleSheetCollection() const
+ {
+#if ENABLE(OILPAN)
+ return m_documentStyleSheetCollection;
+#else
+ return &m_documentStyleSheetCollection;
+#endif
+ }
- Document& m_document;
+ DocumentStyleSheetCollection* documentStyleSheetCollection()
+ {
+#if ENABLE(OILPAN)
+ return m_documentStyleSheetCollection;
+#else
+ return &m_documentStyleSheetCollection;
+#endif
+ }
+
+ RawPtrWillBeMember<Document> m_document;
bool m_isMaster;
// Track the number of currently loading top-level stylesheets needed for rendering.
@@ -206,15 +230,18 @@ private:
// elements and when it is safe to execute scripts.
int m_pendingStylesheets;
- mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets;
+ mutable WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_injectedAuthorStyleSheets;
mutable bool m_injectedStyleSheetCacheValid;
- Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets;
-
- bool m_needsUpdateActiveStylesheetsOnStyleRecalc;
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_authorStyleSheets;
+#if ENABLE(OILPAN)
+ Member<DocumentStyleSheetCollection> m_documentStyleSheetCollection;
+#else
DocumentStyleSheetCollection m_documentStyleSheetCollection;
- HashMap<TreeScope*, OwnPtr<StyleSheetCollection> > m_styleSheetCollectionMap;
+#endif
+ typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<TreeScope>, OwnPtrWillBeMember<ShadowTreeStyleSheetCollection> > StyleSheetCollectionMap;
+ StyleSheetCollectionMap m_styleSheetCollectionMap;
bool m_documentScopeDirty;
TreeScopeSet m_dirtyTreeScopes;
@@ -232,11 +259,14 @@ private:
bool m_ignorePendingStylesheets;
bool m_didCalculateResolver;
- unsigned m_lastResolverAccessCount;
- Timer<StyleEngine> m_resolverThrowawayTimer;
- OwnPtr<StyleResolver> m_resolver;
+ OwnPtrWillBeMember<StyleResolver> m_resolver;
+
+ RefPtrWillBeMember<CSSFontSelector> m_fontSelector;
+
+ WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<StyleSheetContents> > m_textToSheetCache;
+ WillBeHeapHashMap<RawPtrWillBeMember<StyleSheetContents>, AtomicString> m_sheetToTextCache;
- RefPtr<CSSFontSelector> m_fontSelector;
+ RefPtrWillBeMember<ProcessingInstruction> m_xslStyleSheet;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp
new file mode 100644
index 00000000000..23768afc886
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/StyleSheetCandidate.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/Element.h"
+#include "core/dom/ProcessingInstruction.h"
+#include "core/dom/StyleEngine.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLStyleElement.h"
+#include "core/html/imports/HTMLImport.h"
+#include "core/svg/SVGStyleElement.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+AtomicString StyleSheetCandidate::title() const
+{
+ return isElement() ? toElement(m_node).fastGetAttribute(titleAttr) : nullAtom;
+}
+
+bool StyleSheetCandidate::isXSL() const
+{
+ return !m_node.document().isHTMLDocument() && m_type == Pi && toProcessingInstruction(m_node).isXSL();
+}
+
+bool StyleSheetCandidate::isImport() const
+{
+ return m_type == HTMLLink && toHTMLLinkElement(m_node).isImport();
+}
+
+Document* StyleSheetCandidate::importedDocument() const
+{
+ ASSERT(isImport());
+ return toHTMLLinkElement(m_node).import();
+}
+
+bool StyleSheetCandidate::isAlternate() const
+{
+ if (!isElement())
+ return false;
+ return toElement(m_node).getAttribute(relAttr).contains("alternate");
+}
+
+bool StyleSheetCandidate::isEnabledViaScript() const
+{
+ return isHTMLLink() && toHTMLLinkElement(m_node).isEnabledViaScript();
+}
+
+bool StyleSheetCandidate::isEnabledAndLoading() const
+{
+ return isHTMLLink() && !toHTMLLinkElement(m_node).isDisabled() && toHTMLLinkElement(m_node).styleSheetIsLoading();
+}
+
+bool StyleSheetCandidate::hasPreferrableName(const String& currentPreferrableName) const
+{
+ ASSERT(isEnabledAndLoading() || sheet());
+ return !isEnabledViaScript() && !title().isEmpty() && !isAlternate() && currentPreferrableName.isEmpty();
+}
+
+bool StyleSheetCandidate::canBeActivated(const String& currentPreferrableName) const
+{
+ StyleSheet* sheet = this->sheet();
+ if (!sheet || sheet->disabled() || !sheet->isCSSStyleSheet())
+ return false;
+ const AtomicString& title = this->title();
+ if (!isEnabledViaScript() && !title.isEmpty() && title != currentPreferrableName)
+ return false;
+ if (isAlternate() && title.isEmpty())
+ return false;
+
+ return true;
+}
+
+StyleSheetCandidate::Type StyleSheetCandidate::typeOf(Node& node)
+{
+ if (node.nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
+ return Pi;
+
+ if (node.isHTMLElement()) {
+ if (isHTMLLinkElement(node))
+ return HTMLLink;
+ if (isHTMLStyleElement(node))
+ return HTMLStyle;
+
+ ASSERT_NOT_REACHED();
+ return HTMLStyle;
+ }
+
+ if (isSVGStyleElement(node))
+ return SVGStyle;
+
+ ASSERT_NOT_REACHED();
+ return HTMLStyle;
+}
+
+StyleSheet* StyleSheetCandidate::sheet() const
+{
+ switch (m_type) {
+ case HTMLLink:
+ return toHTMLLinkElement(m_node).sheet();
+ case HTMLStyle:
+ return toHTMLStyleElement(m_node).sheet();
+ case SVGStyle:
+ return toSVGStyleElement(m_node).sheet();
+ case Pi:
+ return toProcessingInstruction(m_node).sheet();
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h
new file mode 100644
index 00000000000..742e8621e31
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCandidate.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StyleSheetCandidate_h
+#define StyleSheetCandidate_h
+
+#include "wtf/text/AtomicString.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class Document;
+class Node;
+class StyleSheet;
+
+class StyleSheetCandidate {
+public:
+ enum Type {
+ HTMLLink,
+ HTMLStyle,
+ SVGStyle,
+ Pi
+ };
+
+ StyleSheetCandidate(Node& node)
+ : m_node(node)
+ , m_type(typeOf(node))
+ { }
+
+ bool isXSL() const;
+ bool isImport() const;
+ bool isAlternate() const;
+ bool isEnabledViaScript() const;
+ bool isEnabledAndLoading() const;
+ bool hasPreferrableName(const String& currentPreferrableName) const;
+ bool canBeActivated(const String& currentPreferrableName) const;
+
+ StyleSheet* sheet() const;
+ AtomicString title() const;
+ Document* importedDocument() const;
+
+private:
+ bool isElement() const { return m_type != Pi; }
+ bool isHTMLLink() const { return m_type == HTMLLink; }
+
+ static Type typeOf(Node&);
+
+ Node& m_node;
+ Type m_type;
+};
+
+}
+
+#endif
+
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp
index cb944d876ee..186f1a499a6 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.cpp
@@ -28,238 +28,49 @@
#include "core/dom/StyleSheetCollection.h"
#include "core/css/CSSStyleSheet.h"
-#include "core/css/StyleInvalidationAnalysis.h"
-#include "core/css/StyleRuleImport.h"
-#include "core/css/StyleSheetContents.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/Element.h"
-#include "core/dom/StyleEngine.h"
-#include "core/html/HTMLStyleElement.h"
-#include "core/frame/Settings.h"
namespace WebCore {
-StyleSheetCollectionBase::StyleSheetCollectionBase()
+StyleSheetCollection::StyleSheetCollection()
{
}
-StyleSheetCollectionBase::~StyleSheetCollectionBase()
+StyleSheetCollection::~StyleSheetCollection()
{
}
-void StyleSheetCollectionBase::swap(StyleSheetCollectionBase& other)
+void StyleSheetCollection::swap(StyleSheetCollection& other)
{
m_styleSheetsForStyleSheetList.swap(other.m_styleSheetsForStyleSheetList);
m_activeAuthorStyleSheets.swap(other.m_activeAuthorStyleSheets);
}
-void StyleSheetCollectionBase::appendActiveStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& sheets)
+void StyleSheetCollection::swapSheetsForSheetList(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheets)
{
- m_activeAuthorStyleSheets.append(sheets);
+ // Only called for collection of HTML Imports that never has active sheets.
+ ASSERT(m_activeAuthorStyleSheets.isEmpty());
+ m_styleSheetsForStyleSheetList.swap(sheets);
}
-void StyleSheetCollectionBase::appendActiveStyleSheet(CSSStyleSheet* sheet)
+void StyleSheetCollection::appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
{
- m_activeAuthorStyleSheets.append(sheet);
-}
-
-void StyleSheetCollectionBase::appendSheetForList(StyleSheet* sheet)
-{
- m_styleSheetsForStyleSheetList.append(sheet);
-}
-
-
-StyleSheetCollection::StyleSheetCollection(TreeScope& treeScope)
- : m_treeScope(treeScope)
- , m_hadActiveLoadingStylesheet(false)
- , m_usesRemUnits(false)
-{
-}
-
-void StyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool createdByParser)
-{
- if (!node->inDocument())
- return;
-
- // Until the <body> exists, we have no choice but to compare document positions,
- // since styles outside of the body and head continue to be shunted into the head
- // (and thus can shift to end up before dynamically added DOM content that is also
- // outside the body).
- if (createdByParser && document()->body())
- m_styleSheetCandidateNodes.parserAdd(node);
- else
- m_styleSheetCandidateNodes.add(node);
-
- if (!isHTMLStyleElement(node))
- return;
-
- ContainerNode* scopingNode = toHTMLStyleElement(node)->scopingNode();
- if (!isTreeScopeRoot(scopingNode))
- m_scopingNodesForStyleScoped.add(scopingNode);
-}
-
-void StyleSheetCollection::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
-{
- m_styleSheetCandidateNodes.remove(node);
-
- if (!isTreeScopeRoot(scopingNode))
- m_scopingNodesForStyleScoped.remove(scopingNode);
-}
-
-StyleSheetCollection::StyleResolverUpdateType StyleSheetCollection::compareStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, Vector<StyleSheetContents*>& addedSheets)
-{
- unsigned newStyleSheetCount = newStylesheets.size();
- unsigned oldStyleSheetCount = oldStyleSheets.size();
- ASSERT(newStyleSheetCount >= oldStyleSheetCount);
-
- if (!newStyleSheetCount)
- return Reconstruct;
-
- unsigned newIndex = 0;
- for (unsigned oldIndex = 0; oldIndex < oldStyleSheetCount; ++oldIndex) {
- while (oldStyleSheets[oldIndex] != newStylesheets[newIndex]) {
- addedSheets.append(newStylesheets[newIndex]->contents());
- if (++newIndex == newStyleSheetCount)
- return Reconstruct;
- }
- if (++newIndex == newStyleSheetCount)
- return Reconstruct;
- }
- bool hasInsertions = !addedSheets.isEmpty();
- while (newIndex < newStyleSheetCount) {
- addedSheets.append(newStylesheets[newIndex]->contents());
- ++newIndex;
- }
- // If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
- // If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
- return hasInsertions ? Reset : Additive;
-}
-
-bool StyleSheetCollection::activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets)
-{
- // StyleSheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
- bool hasActiveLoadingStylesheet = false;
- unsigned newStylesheetCount = newStyleSheets.size();
- for (unsigned i = 0; i < newStylesheetCount; ++i) {
- if (newStyleSheets[i]->isLoading())
- hasActiveLoadingStylesheet = true;
- }
- if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
- m_hadActiveLoadingStylesheet = false;
- return true;
- }
- m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
- return false;
-}
-
-static bool styleSheetContentsHasFontFaceRule(Vector<StyleSheetContents*> sheets)
-{
- for (unsigned i = 0; i < sheets.size(); ++i) {
- ASSERT(sheets[i]);
- if (sheets[i]->hasFontFaceRule())
- return true;
- }
- return false;
-}
-
-static bool cssStyleSheetHasFontFaceRule(const Vector<RefPtr<CSSStyleSheet> > sheets)
-{
- for (unsigned i = 0; i < sheets.size(); ++i) {
- ASSERT(sheets[i]);
- if (sheets[i]->contents()->hasFontFaceRule())
- return true;
- }
- return false;
+ m_activeAuthorStyleSheets.appendVector(sheets);
}
-void StyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updateMode, const StyleSheetCollectionBase& newCollection, StyleSheetChange& change)
+void StyleSheetCollection::appendActiveStyleSheet(CSSStyleSheet* sheet)
{
- if (activeLoadingStyleSheetLoaded(newCollection.activeAuthorStyleSheets()))
- return;
-
- if (updateMode != AnalyzedStyleUpdate)
- return;
-
- // Find out which stylesheets are new.
- Vector<StyleSheetContents*> addedSheets;
- if (m_activeAuthorStyleSheets.size() <= newCollection.activeAuthorStyleSheets().size()) {
- change.styleResolverUpdateType = compareStyleSheets(m_activeAuthorStyleSheets, newCollection.activeAuthorStyleSheets(), addedSheets);
- } else {
- StyleResolverUpdateType updateType = compareStyleSheets(newCollection.activeAuthorStyleSheets(), m_activeAuthorStyleSheets, addedSheets);
- if (updateType != Additive) {
- change.styleResolverUpdateType = updateType;
- } else {
- if (styleSheetContentsHasFontFaceRule(addedSheets)) {
- change.styleResolverUpdateType = ResetStyleResolverAndFontSelector;
- return;
- }
- // FIXME: since currently all stylesheets are re-added after reseting styleresolver,
- // fontSelector should be always reset. After creating RuleSet for each StyleSheetContents,
- // we can avoid appending all stylesheetcontents in reset case.
- // So we can remove "styleSheetContentsHasFontFaceRule(newSheets)".
- if (cssStyleSheetHasFontFaceRule(newCollection.activeAuthorStyleSheets()))
- change.styleResolverUpdateType = ResetStyleResolverAndFontSelector;
- else
- change.styleResolverUpdateType = Reset;
- }
- }
-
- // FIXME: If styleResolverUpdateType is Reconstruct, we should return early here since
- // we need to recalc the whole document. It's wrong to use StyleInvalidationAnalysis since
- // it only looks at the addedSheets.
-
- // No point in doing the analysis work if we're just going to recalc the whole document anyways.
- // This needs to be done after the compareStyleSheets calls above to ensure we don't throw away
- // the StyleResolver if we don't need to.
- if (document()->hasPendingForcedStyleRecalc())
- return;
-
- // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
- if (!document()->body() || document()->hasNodesWithPlaceholderStyle())
- return;
- StyleInvalidationAnalysis invalidationAnalysis(addedSheets);
- if (invalidationAnalysis.dirtiesAllStyle())
- return;
- invalidationAnalysis.invalidateStyle(*document());
- change.requiresFullStyleRecalc = false;
- return;
-}
-
-void StyleSheetCollection::clearMediaQueryRuleSetStyleSheets()
-{
- for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) {
- StyleSheetContents* contents = m_activeAuthorStyleSheets[i]->contents();
- if (contents->hasMediaQueries())
- contents->clearRuleSet();
- }
-}
-
-void StyleSheetCollection::resetAllRuleSetsInTreeScope(StyleResolver* styleResolver)
-{
- // FIXME: If many web developers use style scoped, implement reset RuleSets in per-scoping node manner.
- if (DocumentOrderedList* styleScopedScopingNodes = scopingNodesForStyleScoped()) {
- for (DocumentOrderedList::iterator it = styleScopedScopingNodes->begin(); it != styleScopedScopingNodes->end(); ++it)
- styleResolver->resetAuthorStyle(toContainerNode(*it));
- }
- if (ListHashSet<Node*, 4>* removedNodes = scopingNodesRemoved()) {
- for (ListHashSet<Node*, 4>::iterator it = removedNodes->begin(); it != removedNodes->end(); ++it)
- styleResolver->resetAuthorStyle(toContainerNode(*it));
- }
- styleResolver->resetAuthorStyle(toContainerNode(m_treeScope.rootNode()));
+ m_activeAuthorStyleSheets.append(sheet);
}
-static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets)
+void StyleSheetCollection::appendSheetForList(StyleSheet* sheet)
{
- for (unsigned i = 0; i < sheets.size(); ++i) {
- if (sheets[i]->contents()->usesRemUnits())
- return true;
- }
- return false;
+ m_styleSheetsForStyleSheetList.append(sheet);
}
-void StyleSheetCollection::updateUsesRemUnits()
+void StyleSheetCollection::trace(Visitor* visitor)
{
- m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
+ visitor->trace(m_activeAuthorStyleSheets);
+ visitor->trace(m_styleSheetsForStyleSheetList);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
index 9c9023355ab..0f23d61d4ab 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
@@ -28,104 +28,42 @@
#ifndef StyleSheetCollection_h
#define StyleSheetCollection_h
-#include "core/dom/Document.h"
-#include "core/dom/DocumentOrderedList.h"
-#include "core/dom/StyleSheetScopingNodeList.h"
-#include "core/dom/TreeScope.h"
+#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
-#include "wtf/HashMap.h"
-#include "wtf/ListHashSet.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
namespace WebCore {
-class ContainerNode;
class CSSStyleSheet;
-class StyleEngine;
-class Node;
class StyleSheet;
-class StyleSheetContents;
-class StyleSheetList;
-// FIXME: Should be in separate file and be renamed like:
-// - StyleSheetCollectionBase -> StyleSheetCollection
-// - StyleSheetCollection -> ScopeStyleSheetCollection
-//
-class StyleSheetCollectionBase {
- WTF_MAKE_NONCOPYABLE(StyleSheetCollectionBase); WTF_MAKE_FAST_ALLOCATED;
+class StyleSheetCollection : public NoBaseWillBeGarbageCollectedFinalized<StyleSheetCollection> {
+ WTF_MAKE_NONCOPYABLE(StyleSheetCollection);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- StyleSheetCollectionBase();
- ~StyleSheetCollectionBase();
+ friend class ActiveDocumentStyleSheetCollector;
+ friend class ImportedDocumentStyleSheetCollector;
- Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; }
- Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() { return m_styleSheetsForStyleSheetList; }
- const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
- const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
+ StyleSheetCollection();
+ virtual ~StyleSheetCollection();
- void swap(StyleSheetCollectionBase&);
- void appendActiveStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&);
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; }
+ WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList() { return m_styleSheetsForStyleSheetList; }
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
+ const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
+
+ void swap(StyleSheetCollection&);
+ void swapSheetsForSheetList(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >&);
+ void appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
void appendActiveStyleSheet(CSSStyleSheet*);
void appendSheetForList(StyleSheet*);
-protected:
- Vector<RefPtr<StyleSheet> > m_styleSheetsForStyleSheetList;
- Vector<RefPtr<CSSStyleSheet> > m_activeAuthorStyleSheets;
-};
-
-
-class StyleSheetCollection : public StyleSheetCollectionBase {
-public:
- void addStyleSheetCandidateNode(Node*, bool createdByParser);
- void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode);
- bool hasStyleSheetCandidateNodes() const { return !m_styleSheetCandidateNodes.isEmpty(); }
-
-
- bool usesRemUnits() const { return m_usesRemUnits; }
-
- DocumentOrderedList& styleSheetCandidateNodes() { return m_styleSheetCandidateNodes; }
- DocumentOrderedList* scopingNodesForStyleScoped() { return m_scopingNodesForStyleScoped.scopingNodes(); }
- ListHashSet<Node*, 4>* scopingNodesRemoved() { return m_scopingNodesForStyleScoped.scopingNodesRemoved(); }
-
- void clearMediaQueryRuleSetStyleSheets();
+ virtual void trace(Visitor*);
protected:
- explicit StyleSheetCollection(TreeScope&);
-
- Document* document() { return m_treeScope.documentScope(); }
-
- enum StyleResolverUpdateType {
- Reconstruct,
- Reset,
- Additive,
- ResetStyleResolverAndFontSelector
- };
-
- struct StyleSheetChange {
- StyleResolverUpdateType styleResolverUpdateType;
- bool requiresFullStyleRecalc;
-
- StyleSheetChange()
- : styleResolverUpdateType(Reconstruct)
- , requiresFullStyleRecalc(true) { }
- };
-
- void analyzeStyleSheetChange(StyleResolverUpdateMode, const StyleSheetCollectionBase&, StyleSheetChange&);
- void resetAllRuleSetsInTreeScope(StyleResolver*);
- void updateUsesRemUnits();
-
-private:
- static StyleResolverUpdateType compareStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, Vector<StyleSheetContents*>& addedSheets);
- bool activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets);
-
-protected:
- TreeScope& m_treeScope;
- bool m_hadActiveLoadingStylesheet;
- bool m_usesRemUnits;
-
- DocumentOrderedList m_styleSheetCandidateNodes;
- StyleSheetScopingNodeList m_scopingNodesForStyleScoped;
+ WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > m_styleSheetsForStyleSheetList;
+ WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_activeAuthorStyleSheets;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp
index 5d809e00904..c633957f41d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/StyleSheetScopingNodeList.cpp
@@ -53,7 +53,7 @@ void StyleSheetScopingNodeList::remove(ContainerNode* node)
return;
// If the node is still working as a scoping node, we cannot remove.
- if (node->inDocument() && node->numberOfScopedHTMLStyleChildren())
+ if (node->inDocument())
return;
m_scopingNodes->remove(node);
@@ -63,5 +63,3 @@ void StyleSheetScopingNodeList::remove(ContainerNode* node)
}
}
-
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/TagCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/TagCollection.cpp
new file mode 100644
index 00000000000..0e2bb71ff2d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TagCollection.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/TagCollection.h"
+
+#include "core/dom/NodeRareData.h"
+#include "wtf/Assertions.h"
+
+namespace WebCore {
+
+TagCollection::TagCollection(ContainerNode& rootNode, CollectionType type, const AtomicString& namespaceURI, const AtomicString& localName)
+ : HTMLCollection(rootNode, type, DoesNotOverrideItemAfter)
+ , m_namespaceURI(namespaceURI)
+ , m_localName(localName)
+{
+ ASSERT(m_namespaceURI.isNull() || !m_namespaceURI.isEmpty());
+}
+
+TagCollection::~TagCollection()
+{
+#if !ENABLE(OILPAN)
+ if (m_namespaceURI == starAtom)
+ ownerNode().nodeLists()->removeCache(this, type(), m_localName);
+ else
+ ownerNode().nodeLists()->removeCache(this, m_namespaceURI, m_localName);
+#endif
+}
+
+bool TagCollection::elementMatches(const Element& testNode) const
+{
+ // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagnamens
+ if (m_localName != starAtom && m_localName != testNode.localName())
+ return false;
+
+ return m_namespaceURI == starAtom || m_namespaceURI == testNode.namespaceURI();
+}
+
+HTMLTagCollection::HTMLTagCollection(ContainerNode& rootNode, const AtomicString& localName)
+ : TagCollection(rootNode, HTMLTagCollectionType, starAtom, localName)
+ , m_loweredLocalName(localName.lower())
+{
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TagCollection.h b/chromium/third_party/WebKit/Source/core/dom/TagCollection.h
new file mode 100644
index 00000000000..6b97db7f2a7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TagCollection.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TagCollection_h
+#define TagCollection_h
+
+#include "core/dom/Element.h"
+#include "core/html/HTMLCollection.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+// Collection that limits to a particular tag.
+class TagCollection : public HTMLCollection {
+public:
+ static PassRefPtrWillBeRawPtr<TagCollection> create(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
+ {
+ ASSERT(namespaceURI != starAtom);
+ return adoptRefWillBeNoop(new TagCollection(rootNode, TagCollectionType, namespaceURI, localName));
+ }
+
+ static PassRefPtrWillBeRawPtr<TagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& localName)
+ {
+ ASSERT_UNUSED(type, type == TagCollectionType);
+ return adoptRefWillBeNoop(new TagCollection(rootNode, TagCollectionType, starAtom, localName));
+ }
+
+ virtual ~TagCollection();
+
+ bool elementMatches(const Element&) const;
+
+protected:
+ TagCollection(ContainerNode& rootNode, CollectionType, const AtomicString& namespaceURI, const AtomicString& localName);
+
+ AtomicString m_namespaceURI;
+ AtomicString m_localName;
+};
+
+DEFINE_TYPE_CASTS(TagCollection, LiveNodeListBase, collection, collection->type() == TagCollectionType, collection.type() == TagCollectionType);
+
+class HTMLTagCollection FINAL : public TagCollection {
+public:
+ static PassRefPtrWillBeRawPtr<HTMLTagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& localName)
+ {
+ ASSERT_UNUSED(type, type == HTMLTagCollectionType);
+ return adoptRefWillBeNoop(new HTMLTagCollection(rootNode, localName));
+ }
+
+ bool elementMatches(const Element&) const;
+
+private:
+ HTMLTagCollection(ContainerNode& rootNode, const AtomicString& localName);
+
+ AtomicString m_loweredLocalName;
+};
+
+DEFINE_TYPE_CASTS(HTMLTagCollection, LiveNodeListBase, collection, collection->type() == HTMLTagCollectionType, collection.type() == HTMLTagCollectionType);
+
+inline bool HTMLTagCollection::elementMatches(const Element& testElement) const
+{
+ // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagname
+ if (m_localName != starAtom) {
+ const AtomicString& localName = testElement.isHTMLElement() ? m_loweredLocalName : m_localName;
+ if (localName != testElement.localName())
+ return false;
+ }
+ ASSERT(m_namespaceURI == starAtom);
+ return true;
+}
+
+} // namespace WebCore
+
+#endif // TagCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/TagNodeList.cpp b/chromium/third_party/WebKit/Source/core/dom/TagNodeList.cpp
deleted file mode 100644
index 39446348179..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/TagNodeList.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/dom/TagNodeList.h"
-
-#include "core/dom/NodeRareData.h"
-#include "wtf/Assertions.h"
-
-namespace WebCore {
-
-TagNodeList::TagNodeList(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& namespaceURI, const AtomicString& localName)
- : LiveNodeList(rootNode, type, DoNotInvalidateOnAttributeChanges)
- , m_namespaceURI(namespaceURI)
- , m_localName(localName)
-{
- ASSERT(m_namespaceURI.isNull() || !m_namespaceURI.isEmpty());
-}
-
-TagNodeList::~TagNodeList()
-{
- if (m_namespaceURI == starAtom)
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type(), m_localName);
- else
- ownerNode()->nodeLists()->removeCacheWithQualifiedName(this, m_namespaceURI, m_localName);
-}
-
-bool TagNodeList::nodeMatches(Element* testNode) const
-{
- // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagnamens
- if (m_localName != starAtom && m_localName != testNode->localName())
- return false;
-
- return m_namespaceURI == starAtom || m_namespaceURI == testNode->namespaceURI();
-}
-
-HTMLTagNodeList::HTMLTagNodeList(PassRefPtr<Node> rootNode, const AtomicString& localName)
- : TagNodeList(rootNode, HTMLTagNodeListType, starAtom, localName)
- , m_loweredLocalName(localName.lower())
-{
-}
-
-bool HTMLTagNodeList::nodeMatches(Element* testNode) const
-{
- return nodeMatchesInlined(testNode);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TagNodeList.h b/chromium/third_party/WebKit/Source/core/dom/TagNodeList.h
deleted file mode 100644
index 8ec41937666..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/TagNodeList.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef TagNodeList_h
-#define TagNodeList_h
-
-#include "core/dom/Element.h"
-#include "core/dom/LiveNodeList.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-// NodeList that limits to a particular tag.
-class TagNodeList : public LiveNodeList {
-public:
- static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
- {
- ASSERT(namespaceURI != starAtom);
- return adoptRef(new TagNodeList(rootNode, TagNodeListType, namespaceURI, localName));
- }
-
- static PassRefPtr<TagNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& localName)
- {
- ASSERT_UNUSED(type, type == TagNodeListType);
- return adoptRef(new TagNodeList(rootNode, TagNodeListType, starAtom, localName));
- }
-
- virtual ~TagNodeList();
-
-protected:
- TagNodeList(PassRefPtr<Node> rootNode, CollectionType, const AtomicString& namespaceURI, const AtomicString& localName);
-
- virtual bool nodeMatches(Element*) const;
-
- AtomicString m_namespaceURI;
- AtomicString m_localName;
-};
-
-class HTMLTagNodeList FINAL : public TagNodeList {
-public:
- static PassRefPtr<HTMLTagNodeList> create(PassRefPtr<Node> rootNode, CollectionType type, const AtomicString& localName)
- {
- ASSERT_UNUSED(type, type == HTMLTagNodeListType);
- return adoptRef(new HTMLTagNodeList(rootNode, localName));
- }
-
- bool nodeMatchesInlined(Element*) const;
-
-private:
- HTMLTagNodeList(PassRefPtr<Node> rootNode, const AtomicString& localName);
-
- virtual bool nodeMatches(Element*) const OVERRIDE;
-
- AtomicString m_loweredLocalName;
-};
-
-inline bool HTMLTagNodeList::nodeMatchesInlined(Element* testNode) const
-{
- // Implements http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#concept-getelementsbytagname
- if (m_localName != starAtom) {
- const AtomicString& localName = testNode->isHTMLElement() ? m_loweredLocalName : m_localName;
- if (localName != testNode->localName())
- return false;
- }
- ASSERT(m_namespaceURI == starAtom);
- return true;
-}
-
-} // namespace WebCore
-
-#endif // TagNodeList_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h b/chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h
index 380e8fa48b2..aa41655cbb8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TemplateContentDocumentFragment.h
@@ -33,13 +33,21 @@ namespace WebCore {
class TemplateContentDocumentFragment FINAL : public DocumentFragment {
public:
- static PassRefPtr<TemplateContentDocumentFragment> create(Document& document, Element* host)
+ static PassRefPtrWillBeRawPtr<TemplateContentDocumentFragment> create(Document& document, Element* host)
{
- return adoptRef(new TemplateContentDocumentFragment(document, host));
+ return adoptRefWillBeNoop(new TemplateContentDocumentFragment(document, host));
}
Element* host() const { return m_host; }
- void clearHost() { m_host = 0; }
+#if !ENABLE(OILPAN)
+ void clearHost() { m_host = nullptr; }
+#endif
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_host);
+ DocumentFragment::trace(visitor);
+ }
private:
TemplateContentDocumentFragment(Document& document, Element* host)
@@ -50,7 +58,7 @@ private:
virtual bool isTemplateContent() const OVERRIDE { return true; }
- Element* m_host;
+ RawPtrWillBeMember<Element> m_host;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Text.cpp b/chromium/third_party/WebKit/Source/core/dom/Text.cpp
index f43f6ecd0e0..34a7df18241 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Text.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Text.cpp
@@ -22,44 +22,44 @@
#include "config.h"
#include "core/dom/Text.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/SVGNames.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeRenderStyle.h"
-#include "core/dom/NodeRenderingContext.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/NodeTraversal.h"
-#include "core/events/ScopedEventQueue.h"
+#include "core/dom/RenderTreeBuilder.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/events/ScopedEventQueue.h"
#include "core/rendering/RenderCombineText.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
+#include "core/svg/SVGForeignObjectElement.h"
#include "wtf/text/CString.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
-PassRefPtr<Text> Text::create(Document& document, const String& data)
+PassRefPtrWillBeRawPtr<Text> Text::create(Document& document, const String& data)
{
- return adoptRef(new Text(document, data, CreateText));
+ return adoptRefWillBeNoop(new Text(document, data, CreateText));
}
-PassRefPtr<Text> Text::createEditingText(Document& document, const String& data)
+PassRefPtrWillBeRawPtr<Text> Text::createEditingText(Document& document, const String& data)
{
- return adoptRef(new Text(document, data, CreateEditingText));
+ return adoptRefWillBeNoop(new Text(document, data, CreateEditingText));
}
-PassRefPtr<Node> Text::mergeNextSiblingNodesIfPossible()
+PassRefPtrWillBeRawPtr<Node> Text::mergeNextSiblingNodesIfPossible()
{
- RefPtr<Node> protect(this);
+ RefPtrWillBeRawPtr<Node> protect(this);
// Remove empty text nodes.
if (!length()) {
// Care must be taken to get the next node before removing the current node.
- RefPtr<Node> nextNode(NodeTraversal::nextPostOrder(*this));
+ RefPtrWillBeRawPtr<Node> nextNode(NodeTraversal::nextPostOrder(*this));
remove(IGNORE_EXCEPTION);
return nextNode.release();
}
@@ -69,7 +69,7 @@ PassRefPtr<Node> Text::mergeNextSiblingNodesIfPossible()
if (nextSibling->nodeType() != TEXT_NODE)
break;
- RefPtr<Text> nextText = toText(nextSibling);
+ RefPtrWillBeRawPtr<Text> nextText = toText(nextSibling);
// Remove empty text nodes.
if (!nextText->length()) {
@@ -88,7 +88,7 @@ PassRefPtr<Node> Text::mergeNextSiblingNodesIfPossible()
nextText->setDataWithoutUpdate(emptyString());
nextText->updateTextRenderer(0, nextTextData.length());
- document().didMergeTextNodes(nextText.get(), offset);
+ document().didMergeTextNodes(*nextText, offset);
// Restore nextText for mutation event.
nextText->setDataWithoutUpdate(nextTextData);
@@ -102,18 +102,18 @@ PassRefPtr<Node> Text::mergeNextSiblingNodesIfPossible()
return NodeTraversal::nextPostOrder(*this);
}
-PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Text> Text::splitText(unsigned offset, ExceptionState& exceptionState)
{
// IndexSizeError: Raised if the specified offset is negative or greater than
// the number of 16-bit units in data.
if (offset > length()) {
exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is larger than the Text node's length.");
- return 0;
+ return nullptr;
}
EventQueueScope scope;
String oldStr = data();
- RefPtr<Text> newText = cloneWithData(oldStr.substring(offset));
+ RefPtrWillBeRawPtr<Text> newText = cloneWithData(oldStr.substring(offset));
setDataWithoutUpdate(oldStr.substring(0, offset));
didModifyData(oldStr);
@@ -121,13 +121,13 @@ PassRefPtr<Text> Text::splitText(unsigned offset, ExceptionState& exceptionState
if (parentNode())
parentNode()->insertBefore(newText.get(), nextSibling(), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
if (renderer())
toRenderText(renderer())->setTextWithOffset(dataImpl(), 0, oldStr.length());
if (parentNode())
- document().didSplitTextNode(this);
+ document().didSplitTextNode(*this);
return newText.release();
}
@@ -189,26 +189,26 @@ String Text::wholeText() const
return result.toString();
}
-PassRefPtr<Text> Text::replaceWholeText(const String& newText)
+PassRefPtrWillBeRawPtr<Text> Text::replaceWholeText(const String& newText)
{
// Remove all adjacent text nodes, and replace the contents of this one.
// Protect startText and endText against mutation event handlers removing the last ref
- RefPtr<Text> startText = const_cast<Text*>(earliestLogicallyAdjacentTextNode(this));
- RefPtr<Text> endText = const_cast<Text*>(latestLogicallyAdjacentTextNode(this));
+ RefPtrWillBeRawPtr<Text> startText = const_cast<Text*>(earliestLogicallyAdjacentTextNode(this));
+ RefPtrWillBeRawPtr<Text> endText = const_cast<Text*>(latestLogicallyAdjacentTextNode(this));
- RefPtr<Text> protectedThis(this); // Mutation event handlers could cause our last ref to go away
- RefPtr<ContainerNode> parent = parentNode(); // Protect against mutation handlers moving this node during traversal
- for (RefPtr<Node> n = startText; n && n != this && n->isTextNode() && n->parentNode() == parent;) {
- RefPtr<Node> nodeToRemove(n.release());
+ RefPtrWillBeRawPtr<Text> protectedThis(this); // Mutation event handlers could cause our last ref to go away
+ RefPtrWillBeRawPtr<ContainerNode> parent = parentNode(); // Protect against mutation handlers moving this node during traversal
+ for (RefPtrWillBeRawPtr<Node> n = startText; n && n != this && n->isTextNode() && n->parentNode() == parent;) {
+ RefPtrWillBeRawPtr<Node> nodeToRemove(n.release());
n = nodeToRemove->nextSibling();
parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION);
}
if (this != endText) {
Node* onePastEndText = endText->nextSibling();
- for (RefPtr<Node> n = nextSibling(); n && n != onePastEndText && n->isTextNode() && n->parentNode() == parent;) {
- RefPtr<Node> nodeToRemove(n.release());
+ for (RefPtrWillBeRawPtr<Node> n = nextSibling(); n && n != onePastEndText && n->isTextNode() && n->parentNode() == parent;) {
+ RefPtrWillBeRawPtr<Node> nodeToRemove(n.release());
n = nodeToRemove->nextSibling();
parent->removeChild(nodeToRemove.get(), IGNORE_EXCEPTION);
}
@@ -217,7 +217,7 @@ PassRefPtr<Text> Text::replaceWholeText(const String& newText)
if (newText.isEmpty()) {
if (parent && parentNode() == parent)
parent->removeChild(this, IGNORE_EXCEPTION);
- return 0;
+ return nullptr;
}
setData(newText);
@@ -234,12 +234,12 @@ Node::NodeType Text::nodeType() const
return TEXT_NODE;
}
-PassRefPtr<Node> Text::cloneNode(bool /*deep*/)
+PassRefPtrWillBeRawPtr<Node> Text::cloneNode(bool /*deep*/)
{
return cloneWithData(data());
}
-bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
+bool Text::textRendererIsNeeded(const RenderStyle& style, const RenderObject& parent)
{
if (isEditingText())
return true;
@@ -247,39 +247,38 @@ bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
if (!length())
return false;
- if (context.style()->display() == NONE)
+ if (style.display() == NONE)
return false;
if (!containsOnlyWhitespace())
return true;
- RenderObject* parent = context.parentRenderer();
- if (!parent->canHaveWhitespaceChildren())
+ if (!parent.canHaveWhitespaceChildren())
return false;
- if (context.style()->preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
+ if (style.preserveNewline()) // pre/pre-wrap/pre-line always make renderers.
return true;
- RenderObject* prev = context.previousRenderer();
+ const RenderObject* prev = NodeRenderingTraversal::previousSiblingRenderer(this);
if (prev && prev->isBR()) // <span><br/> <br/></span>
return false;
- if (parent->isRenderInline()) {
+ if (parent.isRenderInline()) {
// <span><div/> <div/></span>
if (prev && !prev->isInline())
return false;
} else {
- if (parent->isRenderBlock() && !parent->childrenInline() && (!prev || !prev->isInline()))
+ if (parent.isRenderBlock() && !parent.childrenInline() && (!prev || !prev->isInline()))
return false;
// Avoiding creation of a Renderer for the text node is a non-essential memory optimization.
// So to avoid blowing up on very wide DOMs, we limit the number of siblings to visit.
unsigned maxSiblingsToVisit = 50;
- RenderObject* first = parent->firstChild();
+ RenderObject* first = parent.slowFirstChild();
while (first && first->isFloatingOrOutOfFlowPositioned() && maxSiblingsToVisit--)
first = first->nextSibling();
- if (!first || context.nextRenderer() == first)
+ if (!first || NodeRenderingTraversal::nextSiblingRenderer(this) == first)
// Whitespace at the start of a block just goes away. Don't even
// make a render object for this text.
return false;
@@ -290,7 +289,8 @@ bool Text::textRendererIsNeeded(const NodeRenderingContext& context)
static bool isSVGText(Text* text)
{
Node* parentOrShadowHostNode = text->parentOrShadowHostNode();
- return parentOrShadowHostNode->isSVGElement() && !parentOrShadowHostNode->hasTagName(SVGNames::foreignObjectTag);
+ ASSERT(parentOrShadowHostNode);
+ return parentOrShadowHostNode->isSVGElement() && !isSVGForeignObjectElement(*parentOrShadowHostNode);
}
RenderText* Text::createTextRenderer(RenderStyle* style)
@@ -306,7 +306,7 @@ RenderText* Text::createTextRenderer(RenderStyle* style)
void Text::attach(const AttachContext& context)
{
- NodeRenderingContext(this, context.resolvedStyle).createRendererForTextIfNeeded();
+ RenderTreeBuilder(this, context.resolvedStyle).createRendererForTextIfNeeded();
CharacterData::attach(context);
}
@@ -339,22 +339,17 @@ void Text::updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfRe
if (!inActiveDocument())
return;
RenderText* textRenderer = toRenderText(renderer());
- if (!textRenderer || !textRendererIsNeeded(NodeRenderingContext(this, textRenderer->style()))) {
+ if (!textRenderer || !textRendererIsNeeded(*textRenderer->style(), *textRenderer->parent())) {
lazyReattachIfAttached();
// FIXME: Editing should be updated so this is not neccesary.
if (recalcStyleBehavior == DeprecatedRecalcStyleImmediatlelyForEditing)
- document().updateStyleIfNeeded();
+ document().updateRenderTreeIfNeeded();
return;
}
textRenderer->setTextWithOffset(dataImpl(), offsetOfReplacedData, lengthOfReplacedData);
}
-bool Text::childTypeAllowed(NodeType) const
-{
- return false;
-}
-
-PassRefPtr<Text> Text::cloneWithData(const String& data)
+PassRefPtrWillBeRawPtr<Text> Text::cloneWithData(const String& data)
{
return create(document(), data);
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/Text.h b/chromium/third_party/WebKit/Source/core/dom/Text.h
index 79540c0b399..fc387d2d75c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Text.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Text.h
@@ -35,21 +35,21 @@ class Text : public CharacterData {
public:
static const unsigned defaultLengthLimit = 1 << 16;
- static PassRefPtr<Text> create(Document&, const String&);
- static PassRefPtr<Text> createEditingText(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<Text> create(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<Text> createEditingText(Document&, const String&);
// mergeNextSiblingNodesIfPossible() merges next sibling nodes if possible
// then returns a node not merged.
- PassRefPtr<Node> mergeNextSiblingNodesIfPossible();
- PassRefPtr<Text> splitText(unsigned offset, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> mergeNextSiblingNodesIfPossible();
+ PassRefPtrWillBeRawPtr<Text> splitText(unsigned offset, ExceptionState&);
// DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1312295772
String wholeText() const;
- PassRefPtr<Text> replaceWholeText(const String&);
+ PassRefPtrWillBeRawPtr<Text> replaceWholeText(const String&);
void recalcTextStyle(StyleRecalcChange, Text* nextTextSibling);
- bool textRendererIsNeeded(const NodeRenderingContext&);
+ bool textRendererIsNeeded(const RenderStyle&, const RenderObject& parent);
RenderText* createTextRenderer(RenderStyle*);
void updateTextRenderer(unsigned offsetOfReplacedData, unsigned lengthOfReplacedData, RecalcStyleBehavior = DoNotRecalcStyle);
@@ -67,15 +67,14 @@ protected:
private:
virtual String nodeName() const OVERRIDE;
- virtual PassRefPtr<Node> cloneNode(bool deep = true) OVERRIDE FINAL;
- virtual bool childTypeAllowed(NodeType) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE FINAL;
bool needsWhitespaceRenderer();
- virtual PassRefPtr<Text> cloneWithData(const String&);
+ virtual PassRefPtrWillBeRawPtr<Text> cloneWithData(const String&);
#ifndef NDEBUG
- virtual void formatForDebugger(char* buffer, unsigned length) const;
+ virtual void formatForDebugger(char* buffer, unsigned length) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Text.idl b/chromium/third_party/WebKit/Source/core/dom/Text.idl
index 57e6dc0c8f8..2e3f84252bd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Text.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Text.idl
@@ -17,7 +17,7 @@
* Boston, MA 02110-1301, USA.
*/
[
- Constructor([Default=NullString] optional DOMString data),
+ Constructor(optional DOMString data = null),
ConstructorCallWith=Document,
Custom=Wrap,
] interface Text : CharacterData {
@@ -30,5 +30,5 @@
[MeasureAs=TextReplaceWholeText] Text replaceWholeText(DOMString content); // Removed from DOM4.
// Shadow DOM API
- [RuntimeEnabled=ShadowDOM, PerWorldBindings] NodeList getDestinationInsertionPoints();
+ NodeList getDestinationInsertionPoints();
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp b/chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp
index 42b61c7ee59..b2d5b46a09f 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TextLinkColors.cpp
@@ -54,7 +54,7 @@ void TextLinkColors::resetVisitedLinkColor()
void TextLinkColors::resetActiveLinkColor()
{
- m_activeLinkColor.setNamedColor("red");
+ m_activeLinkColor = Color(255, 0, 0);
}
static Color colorForCSSValue(CSSValueID cssValueId)
@@ -110,7 +110,8 @@ Color TextLinkColors::colorFromPrimitiveValue(const CSSPrimitiveValue* value, Co
case CSSValueWebkitActivelink:
return activeLinkColor();
case CSSValueWebkitFocusRingColor:
- return RenderTheme::focusRingColor();
+ return RenderTheme::theme().focusRingColor();
+ case CSSValueInvert: // We don't support outline-color: invert
case CSSValueCurrentcolor:
return currentColor;
default:
diff --git a/chromium/third_party/WebKit/Source/core/dom/Touch.cpp b/chromium/third_party/WebKit/Source/core/dom/Touch.cpp
index a955babbb5d..c2b5f6118f5 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Touch.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/Touch.cpp
@@ -27,63 +27,45 @@
#include "core/dom/Touch.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "platform/geometry/FloatPoint.h"
namespace WebCore {
-static int contentsX(Frame* frame)
+static FloatPoint contentsOffset(LocalFrame* frame)
{
if (!frame)
- return 0;
+ return FloatPoint();
FrameView* frameView = frame->view();
if (!frameView)
- return 0;
- return frameView->scrollX() / frame->pageZoomFactor();
+ return FloatPoint();
+ float scale = 1.0f / frame->pageZoomFactor();
+ return FloatPoint(frameView->scrollPosition()).scaledBy(scale);
}
-static int contentsY(Frame* frame)
-{
- if (!frame)
- return 0;
- FrameView* frameView = frame->view();
- if (!frameView)
- return 0;
- return frameView->scrollY() / frame->pageZoomFactor();
-}
-
-Touch::Touch(Frame* frame, EventTarget* target, unsigned identifier, int screenX, int screenY, int pageX, int pageY, int radiusX, int radiusY, float rotationAngle, float force)
+Touch::Touch(LocalFrame* frame, EventTarget* target, unsigned identifier, const FloatPoint& screenPos, const FloatPoint& pagePos, const FloatSize& radius, float rotationAngle, float force)
: m_target(target)
, m_identifier(identifier)
- , m_clientX(pageX - contentsX(frame))
- , m_clientY(pageY - contentsY(frame))
- , m_screenX(screenX)
- , m_screenY(screenY)
- , m_pageX(pageX)
- , m_pageY(pageY)
- , m_radiusX(radiusX)
- , m_radiusY(radiusY)
+ , m_clientPos(pagePos - contentsOffset(frame))
+ , m_screenPos(screenPos)
+ , m_pagePos(pagePos)
+ , m_radius(radius)
, m_rotationAngle(rotationAngle)
, m_force(force)
{
ScriptWrappable::init(this);
float scaleFactor = frame->pageZoomFactor();
- float x = pageX * scaleFactor;
- float y = pageY * scaleFactor;
- m_absoluteLocation = roundedLayoutPoint(FloatPoint(x, y));
+ m_absoluteLocation = roundedLayoutPoint(pagePos.scaledBy(scaleFactor));
}
-Touch::Touch(EventTarget* target, unsigned identifier, int clientX, int clientY, int screenX, int screenY, int pageX, int pageY, int radiusX, int radiusY, float rotationAngle, float force, LayoutPoint absoluteLocation)
+Touch::Touch(EventTarget* target, unsigned identifier, const FloatPoint& clientPos, const FloatPoint& screenPos, const FloatPoint& pagePos, const FloatSize& radius, float rotationAngle, float force, LayoutPoint absoluteLocation)
: m_target(target)
, m_identifier(identifier)
- , m_clientX(clientX)
- , m_clientY(clientY)
- , m_screenX(screenX)
- , m_screenY(screenY)
- , m_pageX(pageX)
- , m_pageY(pageY)
- , m_radiusX(radiusX)
- , m_radiusY(radiusY)
+ , m_clientPos(clientPos)
+ , m_screenPos(screenPos)
+ , m_pagePos(pagePos)
+ , m_radius(radius)
, m_rotationAngle(rotationAngle)
, m_force(force)
, m_absoluteLocation(absoluteLocation)
@@ -91,9 +73,14 @@ Touch::Touch(EventTarget* target, unsigned identifier, int clientX, int clientY,
ScriptWrappable::init(this);
}
-PassRefPtr<Touch> Touch::cloneWithNewTarget(EventTarget* eventTarget) const
+PassRefPtrWillBeRawPtr<Touch> Touch::cloneWithNewTarget(EventTarget* eventTarget) const
+{
+ return adoptRefWillBeNoop(new Touch(eventTarget, m_identifier, m_clientPos, m_screenPos, m_pagePos, m_radius, m_rotationAngle, m_force, m_absoluteLocation));
+}
+
+void Touch::trace(Visitor* visitor)
{
- return adoptRef(new Touch(eventTarget, m_identifier, m_clientX, m_clientY, m_screenX, m_screenY, m_pageX, m_pageY, m_radiusX, m_radiusY, m_rotationAngle, m_force, m_absoluteLocation));
+ visitor->trace(m_target);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Touch.h b/chromium/third_party/WebKit/Source/core/dom/Touch.h
index 220d4cf10d4..c4896bbd4f2 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Touch.h
+++ b/chromium/third_party/WebKit/Source/core/dom/Touch.h
@@ -28,61 +28,73 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/events/EventTarget.h"
+#include "platform/geometry/FloatPoint.h"
+#include "platform/geometry/FloatSize.h"
#include "platform/geometry/LayoutPoint.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
-class Touch : public RefCounted<Touch>, public ScriptWrappable {
+class Touch FINAL : public RefCountedWillBeGarbageCollectedFinalized<Touch>, public ScriptWrappable {
public:
- static PassRefPtr<Touch> create(Frame* frame, EventTarget* target,
- unsigned identifier, int screenX, int screenY, int pageX, int pageY,
- int radiusX, int radiusY, float rotationAngle, float force)
+ static PassRefPtrWillBeRawPtr<Touch> create(LocalFrame* frame, EventTarget* target,
+ unsigned identifier, const FloatPoint& screenPos, const FloatPoint& pagePos,
+ const FloatSize& radius, float rotationAngle, float force)
{
- return adoptRef(new Touch(frame, target, identifier, screenX,
- screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force));
+ return adoptRefWillBeNoop(
+ new Touch(frame, target, identifier, screenPos, pagePos, radius, rotationAngle, force));
}
+ // DOM Touch implementation
EventTarget* target() const { return m_target.get(); }
unsigned identifier() const { return m_identifier; }
- int clientX() const { return m_clientX; }
- int clientY() const { return m_clientY; }
- int screenX() const { return m_screenX; }
- int screenY() const { return m_screenY; }
- int pageX() const { return m_pageX; }
- int pageY() const { return m_pageY; }
- int webkitRadiusX() const { return m_radiusX; }
- int webkitRadiusY() const { return m_radiusY; }
+ double clientX() const { return m_clientPos.x(); }
+ double clientY() const { return m_clientPos.y(); }
+ double screenX() const { return m_screenPos.x(); }
+ double screenY() const { return m_screenPos.y(); }
+ double pageX() const { return m_pagePos.x(); }
+ double pageY() const { return m_pagePos.y(); }
+ double webkitRadiusX() const { return m_radius.width(); }
+ double webkitRadiusY() const { return m_radius.height(); }
float webkitRotationAngle() const { return m_rotationAngle; }
float webkitForce() const { return m_force; }
+
+ // Blink-internal methods
const LayoutPoint& absoluteLocation() const { return m_absoluteLocation; }
- PassRefPtr<Touch> cloneWithNewTarget(EventTarget*) const;
+ const FloatPoint& screenLocation() const { return m_screenPos; }
+ PassRefPtrWillBeRawPtr<Touch> cloneWithNewTarget(EventTarget*) const;
+
+ void trace(Visitor*);
private:
- Touch(Frame* frame, EventTarget* target, unsigned identifier,
- int screenX, int screenY, int pageX, int pageY,
- int radiusX, int radiusY, float rotationAngle, float force);
+ Touch(LocalFrame* frame, EventTarget* target, unsigned identifier,
+ const FloatPoint& screenPos, const FloatPoint& pagePos,
+ const FloatSize& radius, float rotationAngle, float force);
- Touch(EventTarget*, unsigned identifier, int clientX, int clientY,
- int screenX, int screenY, int pageX, int pageY,
- int radiusX, int radiusY, float rotationAngle, float force, LayoutPoint absoluteLocation);
+ Touch(EventTarget*, unsigned identifier, const FloatPoint& clientPos,
+ const FloatPoint& screenPos, const FloatPoint& pagePos,
+ const FloatSize& radius, float rotationAngle, float force, LayoutPoint absoluteLocation);
- RefPtr<EventTarget> m_target;
+ RefPtrWillBeMember<EventTarget> m_target;
unsigned m_identifier;
- int m_clientX;
- int m_clientY;
- int m_screenX;
- int m_screenY;
- int m_pageX;
- int m_pageY;
- int m_radiusX;
- int m_radiusY;
+ // Position relative to the viewport in CSS px.
+ FloatPoint m_clientPos;
+ // Position relative to the screen in DIPs.
+ FloatPoint m_screenPos;
+ // Position relative to the page in CSS px.
+ FloatPoint m_pagePos;
+ // Radius in CSS px.
+ FloatSize m_radius;
float m_rotationAngle;
float m_force;
+ // FIXME(rbyers): Shouldn't we be able to migrate callers to relying on screenPos, pagePos
+ // or clientPos? absoluteLocation appears to be the same as pagePos but without browser
+ // scale applied.
LayoutPoint m_absoluteLocation;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/Touch.idl b/chromium/third_party/WebKit/Source/core/dom/Touch.idl
index c748ec8e0ef..574d68441d0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/Touch.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/Touch.idl
@@ -23,17 +23,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface Touch {
- readonly attribute long clientX;
- readonly attribute long clientY;
- readonly attribute long screenX;
- readonly attribute long screenY;
- readonly attribute long pageX;
- readonly attribute long pageY;
+[
+ WillBeGarbageCollected,
+] interface Touch {
+ readonly attribute double clientX;
+ readonly attribute double clientY;
+ readonly attribute double screenX;
+ readonly attribute double screenY;
+ readonly attribute double pageX;
+ readonly attribute double pageY;
readonly attribute EventTarget target;
readonly attribute unsigned long identifier;
- readonly attribute long webkitRadiusX;
- readonly attribute long webkitRadiusY;
- readonly attribute float webkitRotationAngle;
- readonly attribute float webkitForce;
+ [MeasureAs=PrefixedTouchRadiusX] readonly attribute double webkitRadiusX;
+ [MeasureAs=PrefixedTouchRadiusY] readonly attribute double webkitRadiusY;
+ [MeasureAs=PrefixedTouchRotationAngle] readonly attribute float webkitRotationAngle;
+ [MeasureAs=PrefixedTouchForce] readonly attribute float webkitForce;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchController.cpp b/chromium/third_party/WebKit/Source/core/dom/TouchController.cpp
deleted file mode 100644
index a24bc81c166..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/TouchController.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/TouchController.h"
-
-#include "core/dom/Document.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/events/TouchEvent.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-
-namespace WebCore {
-
-TouchController::TouchController(Document* document)
- : DOMWindowLifecycleObserver(document->domWindow())
- , DocumentLifecycleObserver(document)
-{
-}
-
-TouchController::~TouchController()
-{
-}
-
-const char* TouchController::supplementName()
-{
- return "TouchController";
-}
-
-TouchController* TouchController::from(Document* document)
-{
- TouchController* controller = static_cast<TouchController*>(DocumentSupplement::from(document, supplementName()));
- if (!controller) {
- controller = new TouchController(document);
- DocumentSupplement::provideTo(document, supplementName(), adoptPtr(controller));
- }
- return controller;
-}
-
-void TouchController::didAddTouchEventHandler(Document* document, Node* handler)
-{
- if (!m_touchEventTargets)
- m_touchEventTargets = adoptPtr(new TouchEventTargetSet);
- m_touchEventTargets->add(handler);
- if (Document* parent = document->parentDocument()) {
- TouchController::from(parent)->didAddTouchEventHandler(parent, document);
- return;
- }
- if (Page* page = document->page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange(document);
- if (m_touchEventTargets->size() == 1)
- page->chrome().client().needTouchEvents(true);
- }
-}
-
-void TouchController::didRemoveTouchEventHandler(Document* document, Node* handler)
-{
- if (!m_touchEventTargets)
- return;
- ASSERT(m_touchEventTargets->contains(handler));
- m_touchEventTargets->remove(handler);
- if (Document* parent = document->parentDocument()) {
- TouchController::from(parent)->didRemoveTouchEventHandler(parent, document);
- return;
- }
-
- Page* page = document->page();
- if (!page)
- return;
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- scrollingCoordinator->touchEventTargetRectsDidChange(document);
- if (m_touchEventTargets->size())
- return;
- for (const Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document() && TouchController::from(frame->document())->hasTouchEventHandlers())
- return;
- }
- page->chrome().client().needTouchEvents(false);
-}
-
-void TouchController::didRemoveEventTargetNode(Document* document, Node* handler)
-{
- if (m_touchEventTargets && !m_touchEventTargets->isEmpty()) {
- if (handler == document)
- m_touchEventTargets->clear();
- else
- m_touchEventTargets->removeAll(handler);
- Document* parent = document->parentDocument();
- if (m_touchEventTargets->isEmpty() && parent)
- TouchController::from(parent)->didRemoveEventTargetNode(parent, document);
- }
-}
-
-void TouchController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
-{
- if (isTouchEventType(eventType)) {
- Document* document = window->document();
- didAddTouchEventHandler(document, document);
- }
-}
-
-void TouchController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
-{
- if (isTouchEventType(eventType)) {
- Document* document = window->document();
- didRemoveTouchEventHandler(document, document);
- }
-}
-
-void TouchController::didRemoveAllEventListeners(DOMWindow* window)
-{
- if (Document* document = window->document())
- didRemoveEventTargetNode(document, document);
-}
-
-void TouchController::documentWasDetached()
-{
- Document* document = static_cast<Document*>(executionContext());
- Document* parentDocument = document->parentDocument();
-
- if (parentDocument) {
- TouchController* parentController = TouchController::from(parentDocument);
- if (parentController->hasTouchEventHandlers())
- parentController->didRemoveEventTargetNode(parentDocument, document);
- }
-}
-
-void TouchController::documentBeingDestroyed()
-{
- Document* document = static_cast<Document*>(executionContext());
-
- if (Document* ownerDocument = document->ownerDocument())
- TouchController::from(ownerDocument)->didRemoveEventTargetNode(ownerDocument, document);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchController.h b/chromium/third_party/WebKit/Source/core/dom/TouchController.h
deleted file mode 100644
index 8ce5e13e4ab..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/TouchController.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-* Copyright (C) 2013 Google, Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-* * Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-* * Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef TouchController_h
-#define TouchController_h
-
-#include "core/dom/DocumentLifecycleObserver.h"
-#include "core/events/Event.h"
-#include "core/dom/Node.h"
-#include "core/frame/DOMWindowLifecycleObserver.h"
-#include "platform/Supplementable.h"
-#include "wtf/HashSet.h"
-
-namespace WebCore {
-
-typedef HashCountedSet<Node*> TouchEventTargetSet;
-
-class Document;
-class DOMWindow;
-
-class TouchController : public DocumentSupplement, public DOMWindowLifecycleObserver, public DocumentLifecycleObserver {
-
-public:
- virtual ~TouchController();
-
- static const char* supplementName();
- static TouchController* from(Document*);
-
- bool hasTouchEventHandlers() const { return m_touchEventTargets ? m_touchEventTargets->size() : false; }
-
- void didAddTouchEventHandler(Document*, Node*);
- void didRemoveTouchEventHandler(Document*, Node*);
- void didRemoveEventTargetNode(Document*, Node*);
-
- const TouchEventTargetSet* touchEventTargets() const { return m_touchEventTargets.get(); }
-
- // Inherited from DOMWindowLifecycleObserver
- virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
- virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
- virtual void didRemoveAllEventListeners(DOMWindow*) OVERRIDE;
-
- // Inherited from DocumentLifecycleObserver
- virtual void documentWasDetached() OVERRIDE;
- virtual void documentBeingDestroyed() OVERRIDE;
-
-private:
- explicit TouchController(Document*);
-
- OwnPtr<TouchEventTargetSet> m_touchEventTargets;
-};
-
-} // namespace WebCore
-
-#endif // TouchController_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchList.cpp b/chromium/third_party/WebKit/Source/core/dom/TouchList.cpp
index 3653a2eaebb..b636f20a54a 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TouchList.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TouchList.cpp
@@ -41,4 +41,9 @@ const Touch* TouchList::item(unsigned index) const
return const_cast<TouchList*>(this)->item(index);
}
+void TouchList::trace(Visitor* visitor)
+{
+ visitor->trace(m_values);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchList.h b/chromium/third_party/WebKit/Source/core/dom/TouchList.h
index 6d5f2bf2c9c..0f827589bfc 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TouchList.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TouchList.h
@@ -28,21 +28,22 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/Touch.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
namespace WebCore {
-class TouchList : public RefCounted<TouchList>, public ScriptWrappable {
+class TouchList : public RefCountedWillBeGarbageCollectedFinalized<TouchList>, public ScriptWrappable {
public:
- static PassRefPtr<TouchList> create()
+ static PassRefPtrWillBeRawPtr<TouchList> create()
{
- return adoptRef(new TouchList);
+ return adoptRefWillBeNoop(new TouchList);
}
- static PassRefPtr<TouchList> create(Vector<RefPtr<Touch> >& touches)
+ static PassRefPtrWillBeRawPtr<TouchList> create(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches)
{
- return adoptRef(new TouchList(touches));
+ return adoptRefWillBeNoop(new TouchList(touches));
}
unsigned length() const { return m_values.size(); }
@@ -50,7 +51,9 @@ public:
Touch* item(unsigned);
const Touch* item(unsigned) const;
- void append(const PassRefPtr<Touch> touch) { m_values.append(touch); }
+ void append(const PassRefPtrWillBeRawPtr<Touch> touch) { m_values.append(touch); }
+
+ void trace(Visitor*);
private:
TouchList()
@@ -58,13 +61,13 @@ private:
ScriptWrappable::init(this);
}
- TouchList(Vector<RefPtr<Touch> >& touches)
+ TouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches)
{
m_values.swap(touches);
ScriptWrappable::init(this);
}
- Vector<RefPtr<Touch> > m_values;
+ WillBeHeapVector<RefPtrWillBeMember<Touch> > m_values;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TouchList.idl b/chromium/third_party/WebKit/Source/core/dom/TouchList.idl
index 351a59cbc20..516946de775 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TouchList.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/TouchList.idl
@@ -23,7 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface TouchList {
+[
+ WillBeGarbageCollected,
+] interface TouchList {
readonly attribute unsigned long length;
getter Touch item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/dom/TransformSource.h b/chromium/third_party/WebKit/Source/core/dom/TransformSource.h
index f637ce36c52..a82c2a2e26b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TransformSource.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TransformSource.h
@@ -21,9 +21,7 @@
#define TransformSource_h
#include "wtf/FastAllocBase.h"
-#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
-#include "wtf/text/WTFString.h"
#include <libxml/tree.h>
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/dom/Traversal.cpp b/chromium/third_party/WebKit/Source/core/dom/Traversal.cpp
deleted file mode 100644
index a9262cc934d..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Traversal.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/dom/Traversal.h"
-
-#include "core/dom/Node.h"
-#include "core/dom/NodeFilter.h"
-
-namespace WebCore {
-
-Traversal::Traversal(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> nodeFilter)
- : m_root(rootNode)
- , m_whatToShow(whatToShow)
- , m_filter(nodeFilter)
-{
-}
-
-short Traversal::acceptNode(ScriptState* state, Node* node) const
-{
- // The bit twiddling here is done to map DOM node types, which are given as integers from
- // 1 through 14, to whatToShow bit masks.
- if (!(((1 << (node->nodeType() - 1)) & m_whatToShow)))
- return NodeFilter::FILTER_SKIP;
- if (!m_filter)
- return NodeFilter::FILTER_ACCEPT;
- return m_filter->acceptNode(state, node);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/Traversal.h b/chromium/third_party/WebKit/Source/core/dom/Traversal.h
deleted file mode 100644
index 58ef1524eef..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/Traversal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Traversal_h
-#define Traversal_h
-
-#include "bindings/v8/ScriptState.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
- class Node;
- class NodeFilter;
-
- class Traversal {
- public:
- Node* root() const { return m_root.get(); }
- unsigned whatToShow() const { return m_whatToShow; }
- NodeFilter* filter() const { return m_filter.get(); }
- // |expandEntityReferences| first appeared in "DOM Level 2 Traversal and Range". However, this argument was
- // never implemented, and, in DOM4, the function argument |expandEntityReferences| is removed from
- // Document.createNodeIterator() and Document.createTreeWalker().
- bool expandEntityReferences() const { return false; }
-
- protected:
- Traversal(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
- short acceptNode(ScriptState*, Node*) const;
-
- private:
- RefPtr<Node> m_root;
- unsigned m_whatToShow;
- RefPtr<NodeFilter> m_filter;
- };
-
-} // namespace WebCore
-
-#endif // Traversal_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp
index 56ad63782b7..0ffc52ba0b3 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScope.cpp
@@ -27,24 +27,25 @@
#include "config.h"
#include "core/dom/TreeScope.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/IdTargetObserverRegistry.h"
+#include "core/dom/NodeRenderStyle.h"
#include "core/dom/TreeScopeAdopter.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/EventPath.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLLabelElement.h"
#include "core/html/HTMLMapElement.h"
#include "core/page/DOMSelection.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderView.h"
@@ -52,93 +53,96 @@
namespace WebCore {
-struct SameSizeAsTreeScope {
- virtual ~SameSizeAsTreeScope();
- void* pointers[8];
- int ints[1];
-};
-
-COMPILE_ASSERT(sizeof(TreeScope) == sizeof(SameSizeAsTreeScope), treescope_should_stay_small);
-
using namespace HTMLNames;
-TreeScope::TreeScope(ContainerNode* rootNode, Document* document)
- : m_rootNode(rootNode)
- , m_documentScope(document)
- , m_parentTreeScope(document)
+TreeScope::TreeScope(ContainerNode& rootNode, Document& document)
+ : m_rootNode(&rootNode)
+ , m_document(&document)
+ , m_parentTreeScope(&document)
+#if !ENABLE(OILPAN)
, m_guardRefCount(0)
+#endif
, m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
{
- ASSERT(rootNode);
- ASSERT(document);
ASSERT(rootNode != document);
+#if !ENABLE(OILPAN)
m_parentTreeScope->guardRef();
+#endif
m_rootNode->setTreeScope(this);
}
-TreeScope::TreeScope(Document* document)
+TreeScope::TreeScope(Document& document)
: m_rootNode(document)
- , m_documentScope(document)
- , m_parentTreeScope(0)
+ , m_document(&document)
+ , m_parentTreeScope(nullptr)
+#if !ENABLE(OILPAN)
, m_guardRefCount(0)
+#endif
, m_idTargetObserverRegistry(IdTargetObserverRegistry::create())
{
- ASSERT(document);
m_rootNode->setTreeScope(this);
}
-TreeScope::TreeScope()
- : m_rootNode(0)
- , m_documentScope(0)
- , m_parentTreeScope(0)
- , m_guardRefCount(0)
-{
-}
-
TreeScope::~TreeScope()
{
+#if !ENABLE(OILPAN)
ASSERT(!m_guardRefCount);
m_rootNode->setTreeScope(0);
if (m_selection) {
m_selection->clearTreeScope();
- m_selection = 0;
+ m_selection = nullptr;
}
if (m_parentTreeScope)
m_parentTreeScope->guardDeref();
+#endif
+}
+
+TreeScope* TreeScope::olderShadowRootOrParentTreeScope() const
+{
+ if (rootNode().isShadowRoot()) {
+ if (ShadowRoot* olderShadowRoot = toShadowRoot(rootNode()).olderShadowRoot())
+ return olderShadowRoot;
+ }
+ return parentTreeScope();
+}
+
+bool TreeScope::isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(const TreeScope& scope) const
+{
+ for (const TreeScope* current = &scope; current; current = current->olderShadowRootOrParentTreeScope()) {
+ if (current == this)
+ return true;
+ }
+ return false;
}
bool TreeScope::rootNodeHasTreeSharedParent() const
{
- return rootNode()->hasTreeSharedParent();
+ return rootNode().hasTreeSharedParent();
}
+#if !ENABLE(OILPAN)
void TreeScope::destroyTreeScopeData()
{
m_elementsById.clear();
m_imageMapsByName.clear();
m_labelsByForAttribute.clear();
}
+#endif
-void TreeScope::clearDocumentScope()
-{
- ASSERT(rootNode()->isDocumentNode());
- m_documentScope = 0;
-}
-
-void TreeScope::setParentTreeScope(TreeScope* newParentScope)
+void TreeScope::setParentTreeScope(TreeScope& newParentScope)
{
// A document node cannot be re-parented.
- ASSERT(!rootNode()->isDocumentNode());
- // Every scope other than document needs a parent scope.
- ASSERT(newParentScope);
+ ASSERT(!rootNode().isDocumentNode());
- newParentScope->guardRef();
+#if !ENABLE(OILPAN)
+ newParentScope.guardRef();
if (m_parentTreeScope)
m_parentTreeScope->guardDeref();
- m_parentTreeScope = newParentScope;
- setDocumentScope(newParentScope->documentScope());
+#endif
+ m_parentTreeScope = &newParentScope;
+ setDocument(newParentScope.document());
}
Element* TreeScope::getElementById(const AtomicString& elementId) const
@@ -150,6 +154,16 @@ Element* TreeScope::getElementById(const AtomicString& elementId) const
return m_elementsById->getElementById(elementId.impl(), this);
}
+const Vector<Element*>& TreeScope::getAllElementsById(const AtomicString& elementId) const
+{
+ DEFINE_STATIC_LOCAL(Vector<Element*>, emptyVector, ());
+ if (elementId.isEmpty())
+ return emptyVector;
+ if (!m_elementsById)
+ return emptyVector;
+ return m_elementsById->getAllElementsById(elementId.impl(), this);
+}
+
void TreeScope::addElementById(const AtomicString& elementId, Element* element)
{
if (!m_elementsById)
@@ -208,44 +222,38 @@ HTMLMapElement* TreeScope::getImageMap(const String& url) const
return 0;
size_t hashPos = url.find('#');
String name = (hashPos == kNotFound ? url : url.substring(hashPos + 1)).impl();
- if (rootNode()->document().isHTMLDocument())
+ if (rootNode().document().isHTMLDocument())
return toHTMLMapElement(m_imageMapsByName->getElementByLowercasedMapName(AtomicString(name.lower()).impl(), this));
return toHTMLMapElement(m_imageMapsByName->getElementByMapName(AtomicString(name).impl(), this));
}
-RenderObject* rendererFromPoint(Document* document, int x, int y, LayoutPoint* localPoint)
+HitTestResult hitTestInDocument(const Document* document, int x, int y)
{
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
if (!frame)
- return 0;
+ return HitTestResult();
FrameView* frameView = frame->view();
if (!frameView)
- return 0;
+ return HitTestResult();
float scaleFactor = frame->pageZoomFactor();
IntPoint point = roundedIntPoint(FloatPoint(x * scaleFactor + frameView->scrollX(), y * scaleFactor + frameView->scrollY()));
if (!frameView->visibleContentRect().contains(point))
- return 0;
+ return HitTestResult();
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
HitTestResult result(point);
document->renderView()->hitTest(request, result);
-
- if (localPoint)
- *localPoint = result.localPoint();
-
- return result.renderer();
+ return result;
}
Element* TreeScope::elementFromPoint(int x, int y) const
{
- RenderObject* renderer = rendererFromPoint(&rootNode()->document(), x, y);
- if (!renderer)
- return 0;
- Node* node = renderer->node();
- if (!node)
+ HitTestResult result = hitTestInDocument(&rootNode().document(), x, y);
+ Node* node = result.innerNode();
+ if (!node || node->isDocumentNode())
return 0;
if (node->isPseudoElement() || node->isTextNode())
node = node->parentOrShadowHostNode();
@@ -276,14 +284,10 @@ HTMLLabelElement* TreeScope::labelElementForId(const AtomicString& forAttributeV
if (!m_labelsByForAttribute) {
// Populate the map on first access.
m_labelsByForAttribute = adoptPtr(new DocumentOrderedMap);
- ASSERT(rootNode());
- for (Element* element = ElementTraversal::firstWithin(*rootNode()); element; element = ElementTraversal::next(*element)) {
- if (isHTMLLabelElement(element)) {
- HTMLLabelElement* label = toHTMLLabelElement(element);
- const AtomicString& forValue = label->fastGetAttribute(forAttr);
- if (!forValue.isEmpty())
- addLabel(forValue, label);
- }
+ for (HTMLLabelElement* label = Traversal<HTMLLabelElement>::firstWithin(rootNode()); label; label = Traversal<HTMLLabelElement>::next(*label)) {
+ const AtomicString& forValue = label->fastGetAttribute(forAttr);
+ if (!forValue.isEmpty())
+ addLabel(forValue, label);
}
}
@@ -292,7 +296,7 @@ HTMLLabelElement* TreeScope::labelElementForId(const AtomicString& forAttributeV
DOMSelection* TreeScope::getSelection() const
{
- if (!rootNode()->document().frame())
+ if (!rootNode().document().frame())
return 0;
if (m_selection)
@@ -309,21 +313,17 @@ Element* TreeScope::findAnchor(const String& name)
{
if (name.isEmpty())
return 0;
- if (Element* element = getElementById(name))
+ if (Element* element = getElementById(AtomicString(name)))
return element;
- ASSERT(rootNode());
- for (Element* element = ElementTraversal::firstWithin(*rootNode()); element; element = ElementTraversal::next(*element)) {
- if (isHTMLAnchorElement(element)) {
- HTMLAnchorElement* anchor = toHTMLAnchorElement(element);
- if (rootNode()->document().inQuirksMode()) {
- // Quirks mode, case insensitive comparison of names.
- if (equalIgnoringCase(anchor->name(), name))
- return anchor;
- } else {
- // Strict mode, names need to match exactly.
- if (anchor->name() == name)
- return anchor;
- }
+ for (HTMLAnchorElement* anchor = Traversal<HTMLAnchorElement>::firstWithin(rootNode()); anchor; anchor = Traversal<HTMLAnchorElement>::next(*anchor)) {
+ if (rootNode().document().inQuirksMode()) {
+ // Quirks mode, case insensitive comparison of names.
+ if (equalIgnoringCase(anchor->name(), name))
+ return anchor;
+ } else {
+ // Strict mode, names need to match exactly.
+ if (anchor->name() == name)
+ return anchor;
}
}
return 0;
@@ -331,14 +331,16 @@ Element* TreeScope::findAnchor(const String& name)
bool TreeScope::applyAuthorStyles() const
{
- return !rootNode()->isShadowRoot() || toShadowRoot(rootNode())->applyAuthorStyles();
+ return rootNode().isDocumentNode();
}
void TreeScope::adoptIfNeeded(Node& node)
{
ASSERT(this);
ASSERT(!node.isDocumentNode());
+#if !ENABLE(OILPAN)
ASSERT_WITH_SECURITY_IMPLICATION(!node.m_deletionHasBegun);
+#endif
TreeScopeAdopter adopter(node, *this);
if (adopter.needsScopeChange())
adopter.execute();
@@ -347,15 +349,17 @@ void TreeScope::adoptIfNeeded(Node& node)
static Element* focusedFrameOwnerElement(Frame* focusedFrame, Frame* currentFrame)
{
for (; focusedFrame; focusedFrame = focusedFrame->tree().parent()) {
- if (focusedFrame->tree().parent() == currentFrame)
- return focusedFrame->ownerElement();
+ if (focusedFrame->tree().parent() == currentFrame) {
+ // FIXME: This won't work for OOPI.
+ return focusedFrame->deprecatedLocalOwner();
+ }
}
return 0;
}
Element* TreeScope::adjustedFocusedElement() const
{
- Document& document = rootNode()->document();
+ Document& document = rootNode().document();
Element* element = document.focusedElement();
if (!element && document.page())
element = focusedFrameOwnerElement(document.page()->focusController().focusedFrame(), document.frame());
@@ -398,12 +402,12 @@ unsigned short TreeScope::comparePosition(const TreeScope& otherScope) const
const TreeScope* child1 = chain1[--index1];
const TreeScope* child2 = chain2[--index2];
if (child1 != child2) {
- Node* shadowHost1 = child1->rootNode()->parentOrShadowHostNode();
- Node* shadowHost2 = child2->rootNode()->parentOrShadowHostNode();
+ Node* shadowHost1 = child1->rootNode().parentOrShadowHostNode();
+ Node* shadowHost2 = child2->rootNode().parentOrShadowHostNode();
if (shadowHost1 != shadowHost2)
return shadowHost1->compareDocumentPositionInternal(shadowHost2, Node::TreatShadowTreesAsDisconnected);
- for (const ShadowRoot* child = toShadowRoot(child2->rootNode())->olderShadowRoot(); child; child = child->olderShadowRoot())
+ for (const ShadowRoot* child = toShadowRoot(child2->rootNode()).olderShadowRoot(); child; child = child->olderShadowRoot())
if (child == child1)
return Node::DOCUMENT_POSITION_FOLLOWING;
@@ -418,6 +422,32 @@ unsigned short TreeScope::comparePosition(const TreeScope& otherScope) const
Node::DOCUMENT_POSITION_PRECEDING | Node::DOCUMENT_POSITION_CONTAINS;
}
+const TreeScope* TreeScope::commonAncestorTreeScope(const TreeScope& other) const
+{
+ Vector<const TreeScope*, 16> thisChain;
+ for (const TreeScope* tree = this; tree; tree = tree->parentTreeScope())
+ thisChain.append(tree);
+
+ Vector<const TreeScope*, 16> otherChain;
+ for (const TreeScope* tree = &other; tree; tree = tree->parentTreeScope())
+ otherChain.append(tree);
+
+ // Keep popping out the last elements of these chains until a mismatched pair is found. If |this| and |other|
+ // belong to different documents, null will be returned.
+ const TreeScope* lastAncestor = 0;
+ while (!thisChain.isEmpty() && !otherChain.isEmpty() && thisChain.last() == otherChain.last()) {
+ lastAncestor = thisChain.last();
+ thisChain.removeLast();
+ otherChain.removeLast();
+ }
+ return lastAncestor;
+}
+
+TreeScope* TreeScope::commonAncestorTreeScope(TreeScope& other)
+{
+ return const_cast<TreeScope*>(static_cast<const TreeScope&>(*this).commonAncestorTreeScope(other));
+}
+
static void listTreeScopes(Node* node, Vector<TreeScope*, 5>& treeScopes)
{
while (true) {
@@ -451,24 +481,24 @@ TreeScope* commonTreeScope(Node* nodeA, Node* nodeB)
return treeScopesA[indexA] == treeScopesB[indexB] ? treeScopesA[indexA] : 0;
}
-#if SECURITY_ASSERT_ENABLED
+#if SECURITY_ASSERT_ENABLED && !ENABLE(OILPAN)
bool TreeScope::deletionHasBegun()
{
- return rootNode() && rootNode()->m_deletionHasBegun;
+ return rootNode().m_deletionHasBegun;
}
void TreeScope::beginDeletion()
{
- rootNode()->m_deletionHasBegun = true;
+ rootNode().m_deletionHasBegun = true;
}
#endif
+#if !ENABLE(OILPAN)
int TreeScope::refCount() const
{
- if (Node* root = rootNode())
- return root->refCount();
- return 0;
+ return rootNode().refCount();
}
+#endif
bool TreeScope::isInclusiveAncestorOf(const TreeScope& scope) const
{
@@ -484,9 +514,8 @@ Element* TreeScope::getElementByAccessKey(const String& key) const
if (key.isEmpty())
return 0;
Element* result = 0;
- Node* root = rootNode();
- ASSERT(root);
- for (Element* element = ElementTraversal::firstWithin(*root); element; element = ElementTraversal::next(*element, root)) {
+ Node& root = rootNode();
+ for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(*element, &root)) {
if (equalIgnoringCase(element->fastGetAttribute(accesskeyAttr), key))
result = element;
for (ShadowRoot* shadowRoot = element->youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
@@ -497,4 +526,24 @@ Element* TreeScope::getElementByAccessKey(const String& key) const
return result;
}
+void TreeScope::setNeedsStyleRecalcForViewportUnits()
+{
+ for (Element* element = ElementTraversal::firstWithin(rootNode()); element; element = ElementTraversal::nextIncludingPseudo(*element)) {
+ for (ShadowRoot* root = element->youngestShadowRoot(); root; root = root->olderShadowRoot())
+ root->setNeedsStyleRecalcForViewportUnits();
+ RenderStyle* style = element->renderStyle();
+ if (style && style->hasViewportUnits())
+ element->setNeedsStyleRecalc(LocalStyleChange);
+ }
+}
+
+void TreeScope::trace(Visitor* visitor)
+{
+ visitor->trace(m_rootNode);
+ visitor->trace(m_document);
+ visitor->trace(m_parentTreeScope);
+ visitor->trace(m_idTargetObserverRegistry);
+ visitor->trace(m_selection);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScope.h b/chromium/third_party/WebKit/Source/core/dom/TreeScope.h
index 718d7e7fb00..79192e0d7c4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeScope.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScope.h
@@ -28,7 +28,7 @@
#define TreeScope_h
#include "core/dom/DocumentOrderedMap.h"
-#include "wtf/Forward.h"
+#include "platform/heap/Handle.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
@@ -39,6 +39,7 @@ class Document;
class Element;
class HTMLLabelElement;
class HTMLMapElement;
+class HitTestResult;
class LayoutPoint;
class IdTargetObserverRegistry;
class Node;
@@ -47,22 +48,26 @@ class RenderObject;
// A class which inherits both Node and TreeScope must call clearRareData() in its destructor
// so that the Node destructor no longer does problematic NodeList cache manipulation in
// the destructor.
-class TreeScope {
- friend class Document;
- friend class TreeScopeAdopter;
-
+class TreeScope : public WillBeGarbageCollectedMixin {
public:
TreeScope* parentTreeScope() const { return m_parentTreeScope; }
- void setParentTreeScope(TreeScope*);
+
+ TreeScope* olderShadowRootOrParentTreeScope() const;
+ bool isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(const TreeScope&) const;
Element* adjustedFocusedElement() const;
Element* getElementById(const AtomicString&) const;
+ const Vector<Element*>& getAllElementsById(const AtomicString&) const;
bool hasElementWithId(StringImpl* id) const;
bool containsMultipleElementsWithId(const AtomicString& id) const;
void addElementById(const AtomicString& elementId, Element*);
void removeElementById(const AtomicString& elementId, Element*);
- Document* documentScope() const { return m_documentScope; }
+ Document& document() const
+ {
+ ASSERT(m_document);
+ return *m_document;
+ }
Node* ancestorInThisScope(Node*) const;
@@ -92,10 +97,12 @@ public:
// Used by the basic DOM mutation methods (e.g., appendChild()).
void adoptIfNeeded(Node&);
- Node* rootNode() const { return m_rootNode; }
+ Node& rootNode() const { return *m_rootNode; }
IdTargetObserverRegistry& idTargetObserverRegistry() const { return *m_idTargetObserverRegistry.get(); }
+
+#if !ENABLE(OILPAN)
// Nodes belonging to this scope hold guard references -
// these are enough to keep the scope from being destroyed, but
// not enough to keep it from removing its children. This allows a
@@ -109,6 +116,7 @@ public:
void guardDeref()
{
+ ASSERT(m_guardRefCount > 0);
ASSERT(!deletionHasBegun());
--m_guardRefCount;
if (!m_guardRefCount && !refCount() && !rootNodeHasTreeSharedParent()) {
@@ -116,35 +124,44 @@ public:
delete this;
}
}
+#endif
void removedLastRefToScope();
bool isInclusiveAncestorOf(const TreeScope&) const;
unsigned short comparePosition(const TreeScope&) const;
+ const TreeScope* commonAncestorTreeScope(const TreeScope& other) const;
+ TreeScope* commonAncestorTreeScope(TreeScope& other);
+
Element* getElementByAccessKey(const String& key) const;
+ virtual void trace(Visitor*);
+
protected:
- TreeScope(ContainerNode*, Document*);
- TreeScope(Document*);
+ TreeScope(ContainerNode&, Document&);
+ TreeScope(Document&);
virtual ~TreeScope();
+#if !ENABLE(OILPAN)
void destroyTreeScopeData();
- void clearDocumentScope();
- void setDocumentScope(Document* document)
- {
- ASSERT(document);
- m_documentScope = document;
- }
+#endif
+
+ void setDocument(Document& document) { m_document = &document; }
+ void setParentTreeScope(TreeScope&);
+#if !ENABLE(OILPAN)
bool hasGuardRefCount() const { return m_guardRefCount; }
+#endif
-private:
- TreeScope();
+ void setNeedsStyleRecalcForViewportUnits();
+private:
virtual void dispose() { }
+#if !ENABLE(OILPAN)
int refCount() const;
+
#if SECURITY_ASSERT_ENABLED
bool deletionHasBegun();
void beginDeletion();
@@ -152,21 +169,25 @@ private:
bool deletionHasBegun() { return false; }
void beginDeletion() { }
#endif
+#endif
bool rootNodeHasTreeSharedParent() const;
- Node* m_rootNode;
- Document* m_documentScope;
- TreeScope* m_parentTreeScope;
+ RawPtrWillBeMember<Node> m_rootNode;
+ RawPtrWillBeMember<Document> m_document;
+ RawPtrWillBeMember<TreeScope> m_parentTreeScope;
+
+#if !ENABLE(OILPAN)
int m_guardRefCount;
+#endif
OwnPtr<DocumentOrderedMap> m_elementsById;
OwnPtr<DocumentOrderedMap> m_imageMapsByName;
OwnPtr<DocumentOrderedMap> m_labelsByForAttribute;
- OwnPtr<IdTargetObserverRegistry> m_idTargetObserverRegistry;
+ OwnPtrWillBeMember<IdTargetObserverRegistry> m_idTargetObserverRegistry;
- mutable RefPtr<DOMSelection> m_selection;
+ mutable RefPtrWillBeMember<DOMSelection> m_selection;
};
inline bool TreeScope::hasElementWithId(StringImpl* id) const
@@ -187,7 +208,7 @@ inline bool operator!=(const TreeScope& a, const TreeScope& b) { return !(a == b
inline bool operator!=(const TreeScope& a, const TreeScope* b) { return !(a == b); }
inline bool operator!=(const TreeScope* a, const TreeScope& b) { return !(a == b); }
-RenderObject* rendererFromPoint(Document*, int x, int y, LayoutPoint* localPoint = 0);
+HitTestResult hitTestInDocument(const Document*, int x, int y);
TreeScope* commonTreeScope(Node*, Node*);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp
index 366b4af3fa1..ecd1147ea08 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp
@@ -38,24 +38,25 @@ void TreeScopeAdopter::moveTreeToNewScope(Node& root) const
{
ASSERT(needsScopeChange());
+#if !ENABLE(OILPAN)
m_oldScope.guardRef();
+#endif
// If an element is moved from a document and then eventually back again the collection cache for
// that element may contain stale data as changes made to it will have updated the DOMTreeVersion
// of the document it was moved to. By increasing the DOMTreeVersion of the donating document here
// we ensure that the collection cache will be invalidated as needed when the element is moved back.
- Document* oldDocument = m_oldScope.documentScope();
- ASSERT(oldDocument);
- Document* newDocument = m_newScope.documentScope();
+ Document& oldDocument = m_oldScope.document();
+ Document& newDocument = m_newScope.document();
bool willMoveToNewDocument = oldDocument != newDocument;
if (willMoveToNewDocument)
- oldDocument->incDOMTreeVersion();
+ oldDocument.incDOMTreeVersion();
for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
updateTreeScope(*node);
if (willMoveToNewDocument)
- moveNodeToNewDocument(*node, *oldDocument, newDocument);
+ moveNodeToNewDocument(*node, oldDocument, newDocument);
else if (node->hasRareData()) {
NodeRareData* rareData = node->rareData();
if (rareData->nodeLists())
@@ -66,23 +67,26 @@ void TreeScopeAdopter::moveTreeToNewScope(Node& root) const
continue;
if (node->hasSyntheticAttrChildNodes()) {
- const Vector<RefPtr<Attr> >& attrs = toElement(node)->attrNodeList();
+ WillBeHeapVector<RefPtrWillBeMember<Attr> >& attrs = *toElement(node)->attrNodeList();
for (unsigned i = 0; i < attrs.size(); ++i)
moveTreeToNewScope(*attrs[i]);
}
for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot()) {
- shadow->setParentTreeScope(&m_newScope);
+ shadow->setParentTreeScope(m_newScope);
if (willMoveToNewDocument)
- moveTreeToNewDocument(*shadow, *oldDocument, newDocument);
+ moveTreeToNewDocument(*shadow, oldDocument, newDocument);
}
}
+#if !ENABLE(OILPAN)
m_oldScope.guardDeref();
+#endif
}
-void TreeScopeAdopter::moveTreeToNewDocument(Node& root, Document& oldDocument, Document* newDocument) const
+void TreeScopeAdopter::moveTreeToNewDocument(Node& root, Document& oldDocument, Document& newDocument) const
{
+ ASSERT(oldDocument != newDocument);
for (Node* node = &root; node; node = NodeTraversal::next(*node, &root)) {
moveNodeToNewDocument(*node, oldDocument, newDocument);
for (ShadowRoot* shadow = node->youngestShadowRoot(); shadow; shadow = shadow->olderShadowRoot())
@@ -106,25 +110,27 @@ inline void TreeScopeAdopter::updateTreeScope(Node& node) const
{
ASSERT(!node.isTreeScope());
ASSERT(node.treeScope() == m_oldScope);
+#if !ENABLE(OILPAN)
m_newScope.guardRef();
m_oldScope.guardDeref();
+#endif
node.setTreeScope(&m_newScope);
}
-inline void TreeScopeAdopter::moveNodeToNewDocument(Node& node, Document& oldDocument, Document* newDocument) const
+inline void TreeScopeAdopter::moveNodeToNewDocument(Node& node, Document& oldDocument, Document& newDocument) const
{
- ASSERT(!node.inDocument() || oldDocument != newDocument);
+ ASSERT(oldDocument != newDocument);
if (node.hasRareData()) {
NodeRareData* rareData = node.rareData();
if (rareData->nodeLists())
- rareData->nodeLists()->adoptDocument(&oldDocument, newDocument);
+ rareData->nodeLists()->adoptDocument(oldDocument, newDocument);
}
- oldDocument.moveNodeIteratorsToNewDocument(&node, newDocument);
+ oldDocument.moveNodeIteratorsToNewDocument(node, newDocument);
if (node.isShadowRoot())
- toShadowRoot(node).setDocumentScope(newDocument);
+ toShadowRoot(node).setDocument(newDocument);
#ifndef NDEBUG
didMoveToNewDocumentWasCalled = false;
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h b/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h
index 17742ba2553..85310ec0888 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeAdopter.h
@@ -32,6 +32,7 @@ namespace WebCore {
class TreeScope;
class TreeScopeAdopter {
+ STACK_ALLOCATED();
public:
TreeScopeAdopter(Node& toAdopt, TreeScope& newScope);
@@ -47,8 +48,8 @@ public:
private:
void updateTreeScope(Node&) const;
void moveTreeToNewScope(Node&) const;
- void moveTreeToNewDocument(Node&, Document& oldDocument, Document* newDocument) const;
- void moveNodeToNewDocument(Node&, Document& oldDocument, Document* newDocument) const;
+ void moveTreeToNewDocument(Node&, Document& oldDocument, Document& newDocument) const;
+ void moveNodeToNewDocument(Node&, Document& oldDocument, Document& newDocument) const;
Node& m_toAdopt;
TreeScope& m_newScope;
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp
new file mode 100644
index 00000000000..d6b05637f98
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/TreeScopeStyleSheetCollection.h"
+
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/StyleRuleImport.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/css/invalidation/StyleSheetInvalidationAnalysis.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Element.h"
+#include "core/dom/StyleEngine.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLStyleElement.h"
+
+namespace WebCore {
+
+TreeScopeStyleSheetCollection::TreeScopeStyleSheetCollection(TreeScope& treeScope)
+ : m_treeScope(treeScope)
+ , m_hadActiveLoadingStylesheet(false)
+ , m_usesRemUnits(false)
+{
+}
+
+void TreeScopeStyleSheetCollection::addStyleSheetCandidateNode(Node* node, bool createdByParser)
+{
+ if (!node->inDocument())
+ return;
+
+ // Until the <body> exists, we have no choice but to compare document positions,
+ // since styles outside of the body and head continue to be shunted into the head
+ // (and thus can shift to end up before dynamically added DOM content that is also
+ // outside the body).
+ if (createdByParser && document().body())
+ m_styleSheetCandidateNodes.parserAdd(node);
+ else
+ m_styleSheetCandidateNodes.add(node);
+
+ if (!isHTMLStyleElement(*node))
+ return;
+
+ ContainerNode* scopingNode = toHTMLStyleElement(*node).scopingNode();
+ if (!isTreeScopeRoot(scopingNode))
+ m_scopingNodesForStyleScoped.add(scopingNode);
+}
+
+void TreeScopeStyleSheetCollection::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
+{
+ m_styleSheetCandidateNodes.remove(node);
+
+ if (!isTreeScopeRoot(scopingNode))
+ m_scopingNodesForStyleScoped.remove(scopingNode);
+}
+
+TreeScopeStyleSheetCollection::StyleResolverUpdateType TreeScopeStyleSheetCollection::compareStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& oldStyleSheets, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStylesheets, WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& addedSheets)
+{
+ unsigned newStyleSheetCount = newStylesheets.size();
+ unsigned oldStyleSheetCount = oldStyleSheets.size();
+ ASSERT(newStyleSheetCount >= oldStyleSheetCount);
+
+ if (!newStyleSheetCount)
+ return Reconstruct;
+
+ unsigned newIndex = 0;
+ for (unsigned oldIndex = 0; oldIndex < oldStyleSheetCount; ++oldIndex) {
+ while (oldStyleSheets[oldIndex] != newStylesheets[newIndex]) {
+ addedSheets.append(newStylesheets[newIndex]->contents());
+ if (++newIndex == newStyleSheetCount)
+ return Reconstruct;
+ }
+ if (++newIndex == newStyleSheetCount)
+ return Reconstruct;
+ }
+ bool hasInsertions = !addedSheets.isEmpty();
+ while (newIndex < newStyleSheetCount) {
+ addedSheets.append(newStylesheets[newIndex]->contents());
+ ++newIndex;
+ }
+ // If all new sheets were added at the end of the list we can just add them to existing StyleResolver.
+ // If there were insertions we need to re-add all the stylesheets so rules are ordered correctly.
+ return hasInsertions ? Reset : Additive;
+}
+
+bool TreeScopeStyleSheetCollection::activeLoadingStyleSheetLoaded(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStyleSheets)
+{
+ // StyleSheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
+ bool hasActiveLoadingStylesheet = false;
+ unsigned newStylesheetCount = newStyleSheets.size();
+ for (unsigned i = 0; i < newStylesheetCount; ++i) {
+ if (newStyleSheets[i]->isLoading())
+ hasActiveLoadingStylesheet = true;
+ }
+ if (m_hadActiveLoadingStylesheet && !hasActiveLoadingStylesheet) {
+ m_hadActiveLoadingStylesheet = false;
+ return true;
+ }
+ m_hadActiveLoadingStylesheet = hasActiveLoadingStylesheet;
+ return false;
+}
+
+static bool findFontFaceRulesFromStyleSheetContents(const WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& sheets, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
+{
+ bool hasFontFaceRule = false;
+
+ for (unsigned i = 0; i < sheets.size(); ++i) {
+ ASSERT(sheets[i]);
+ if (sheets[i]->hasFontFaceRule()) {
+ // FIXME: We don't need this for styles in shadow tree.
+ sheets[i]->findFontFaceRules(fontFaceRules);
+ hasFontFaceRule = true;
+ }
+ }
+ return hasFontFaceRule;
+}
+
+void TreeScopeStyleSheetCollection::analyzeStyleSheetChange(StyleResolverUpdateMode updateMode, const StyleSheetCollection& newCollection, StyleSheetChange& change)
+{
+ if (activeLoadingStyleSheetLoaded(newCollection.activeAuthorStyleSheets()))
+ return;
+
+ if (updateMode != AnalyzedStyleUpdate)
+ return;
+
+ // Find out which stylesheets are new.
+ WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> > addedSheets;
+ if (m_activeAuthorStyleSheets.size() <= newCollection.activeAuthorStyleSheets().size()) {
+ change.styleResolverUpdateType = compareStyleSheets(m_activeAuthorStyleSheets, newCollection.activeAuthorStyleSheets(), addedSheets);
+ } else {
+ StyleResolverUpdateType updateType = compareStyleSheets(newCollection.activeAuthorStyleSheets(), m_activeAuthorStyleSheets, addedSheets);
+ if (updateType != Additive) {
+ change.styleResolverUpdateType = updateType;
+ } else {
+ change.styleResolverUpdateType = Reset;
+ // If @font-face is removed, needs full style recalc.
+ if (findFontFaceRulesFromStyleSheetContents(addedSheets, change.fontFaceRulesToRemove))
+ return;
+ }
+ }
+
+ // FIXME: If styleResolverUpdateType is Reconstruct, we should return early here since
+ // we need to recalc the whole document. It's wrong to use StyleSheetInvalidationAnalysis since
+ // it only looks at the addedSheets.
+
+ // No point in doing the analysis work if we're just going to recalc the whole document anyways.
+ // This needs to be done after the compareStyleSheets calls above to ensure we don't throw away
+ // the StyleResolver if we don't need to.
+ if (document().hasPendingForcedStyleRecalc())
+ return;
+
+ // If we are already parsing the body and so may have significant amount of elements, put some effort into trying to avoid style recalcs.
+ if (!document().body() || document().hasNodesWithPlaceholderStyle())
+ return;
+ StyleSheetInvalidationAnalysis invalidationAnalysis(addedSheets);
+ if (invalidationAnalysis.dirtiesAllStyle())
+ return;
+ invalidationAnalysis.invalidateStyle(document());
+ change.requiresFullStyleRecalc = false;
+ return;
+}
+
+void TreeScopeStyleSheetCollection::clearMediaQueryRuleSetStyleSheets()
+{
+ for (size_t i = 0; i < m_activeAuthorStyleSheets.size(); ++i) {
+ StyleSheetContents* contents = m_activeAuthorStyleSheets[i]->contents();
+ if (contents->hasMediaQueries())
+ contents->clearRuleSet();
+ }
+}
+
+void TreeScopeStyleSheetCollection::enableExitTransitionStylesheets()
+{
+ DocumentOrderedList::iterator begin = m_styleSheetCandidateNodes.begin();
+ DocumentOrderedList::iterator end = m_styleSheetCandidateNodes.end();
+ for (DocumentOrderedList::iterator it = begin; it != end; ++it) {
+ Node* node = *it;
+ if (isHTMLLinkElement(*node))
+ toHTMLLinkElement(node)->enableIfExitTransitionStyle();
+ }
+}
+
+void TreeScopeStyleSheetCollection::resetAllRuleSetsInTreeScope(StyleResolver* styleResolver)
+{
+ // FIXME: If many web developers use style scoped, implement reset RuleSets in per-scoping node manner.
+ if (DocumentOrderedList* styleScopedScopingNodes = scopingNodesForStyleScoped()) {
+ for (DocumentOrderedList::iterator it = styleScopedScopingNodes->begin(); it != styleScopedScopingNodes->end(); ++it)
+ styleResolver->resetAuthorStyle(toContainerNode(*it));
+ }
+ if (ListHashSet<Node*, 4>* removedNodes = scopingNodesRemoved()) {
+ for (ListHashSet<Node*, 4>::iterator it = removedNodes->begin(); it != removedNodes->end(); ++it)
+ styleResolver->resetAuthorStyle(toContainerNode(*it));
+ }
+ styleResolver->resetAuthorStyle(toContainerNode(&m_treeScope.rootNode()));
+}
+
+static bool styleSheetsUseRemUnits(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
+{
+ for (unsigned i = 0; i < sheets.size(); ++i) {
+ if (sheets[i]->contents()->usesRemUnits())
+ return true;
+ }
+ return false;
+}
+
+void TreeScopeStyleSheetCollection::updateUsesRemUnits()
+{
+ m_usesRemUnits = styleSheetsUseRemUnits(m_activeAuthorStyleSheets);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h b/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h
new file mode 100644
index 00000000000..2eac88f2556
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * (C) 1999 Antti Koivisto (koivisto@kde.org)
+ * (C) 2001 Dirk Mueller (mueller@kde.org)
+ * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TreeScopeStyleSheetCollection_h
+#define TreeScopeStyleSheetCollection_h
+
+#include "core/dom/Document.h"
+#include "core/dom/DocumentOrderedList.h"
+#include "core/dom/StyleSheetCollection.h"
+#include "core/dom/StyleSheetScopingNodeList.h"
+#include "core/dom/TreeScope.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/HashMap.h"
+#include "wtf/ListHashSet.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContainerNode;
+class DocumentStyleSheetCollector;
+class StyleEngine;
+class Node;
+class StyleSheetContents;
+class StyleSheetList;
+class StyleRuleFontFace;
+
+class TreeScopeStyleSheetCollection : public StyleSheetCollection {
+public:
+ void addStyleSheetCandidateNode(Node*, bool createdByParser);
+ void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode);
+ bool hasStyleSheetCandidateNodes() const { return !m_styleSheetCandidateNodes.isEmpty(); }
+
+ bool usesRemUnits() const { return m_usesRemUnits; }
+
+ DocumentOrderedList& styleSheetCandidateNodes() { return m_styleSheetCandidateNodes; }
+ DocumentOrderedList* scopingNodesForStyleScoped() { return m_scopingNodesForStyleScoped.scopingNodes(); }
+ ListHashSet<Node*, 4>* scopingNodesRemoved() { return m_scopingNodesForStyleScoped.scopingNodesRemoved(); }
+
+ void clearMediaQueryRuleSetStyleSheets();
+ void enableExitTransitionStylesheets();
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ StyleSheetCollection::trace(visitor);
+ }
+
+protected:
+ explicit TreeScopeStyleSheetCollection(TreeScope&);
+
+ Document& document() const { return m_treeScope.document(); }
+
+ enum StyleResolverUpdateType {
+ Reconstruct,
+ Reset,
+ Additive
+ };
+
+ class StyleSheetChange {
+ STACK_ALLOCATED();
+ public:
+ StyleResolverUpdateType styleResolverUpdateType;
+ bool requiresFullStyleRecalc;
+ WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> > fontFaceRulesToRemove;
+
+ StyleSheetChange()
+ : styleResolverUpdateType(Reconstruct)
+ , requiresFullStyleRecalc(true) { }
+ };
+
+ void analyzeStyleSheetChange(StyleResolverUpdateMode, const StyleSheetCollection&, StyleSheetChange&);
+ void resetAllRuleSetsInTreeScope(StyleResolver*);
+ void updateUsesRemUnits();
+
+private:
+ static StyleResolverUpdateType compareStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& oldStyleSheets, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStylesheets, WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& addedSheets);
+ bool activeLoadingStyleSheetLoaded(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStyleSheets);
+
+protected:
+ TreeScope& m_treeScope;
+ bool m_hadActiveLoadingStylesheet;
+ bool m_usesRemUnits;
+
+ DocumentOrderedList m_styleSheetCandidateNodes;
+ StyleSheetScopingNodeList m_scopingNodesForStyleScoped;
+};
+
+}
+
+#endif
+
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp
new file mode 100644
index 00000000000..8c05c0fc3cf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeScopeTest.cpp
@@ -0,0 +1,99 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/TreeScope.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+TEST(TreeScopeTest, CommonAncestorOfSameTrees)
+{
+ RefPtrWillBeRawPtr<Document> document = Document::create();
+ EXPECT_EQ(document.get(), document->commonAncestorTreeScope(*document));
+
+ RefPtrWillBeRawPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
+ document->appendChild(html, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = html->createShadowRoot(ASSERT_NO_EXCEPTION);
+ EXPECT_EQ(shadowRoot.get(), shadowRoot->commonAncestorTreeScope(*shadowRoot));
+}
+
+TEST(TreeScopeTest, CommonAncestorOfInclusiveTrees)
+{
+ // document
+ // | : Common ancestor is document.
+ // shadowRoot
+
+ RefPtrWillBeRawPtr<Document> document = Document::create();
+ RefPtrWillBeRawPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
+ document->appendChild(html, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = html->createShadowRoot(ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(document.get(), document->commonAncestorTreeScope(*shadowRoot));
+ EXPECT_EQ(document.get(), shadowRoot->commonAncestorTreeScope(*document));
+}
+
+TEST(TreeScopeTest, CommonAncestorOfSiblingTrees)
+{
+ // document
+ // / \ : Common ancestor is document.
+ // A B
+
+ RefPtrWillBeRawPtr<Document> document = Document::create();
+ RefPtrWillBeRawPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
+ document->appendChild(html, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<Element> head = document->createElement("head", nullAtom, ASSERT_NO_EXCEPTION);
+ html->appendChild(head);
+ RefPtrWillBeRawPtr<Element> body = document->createElement("body", nullAtom, ASSERT_NO_EXCEPTION);
+ html->appendChild(body);
+
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootA = head->createShadowRoot(ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootB = body->createShadowRoot(ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(document.get(), shadowRootA->commonAncestorTreeScope(*shadowRootB));
+ EXPECT_EQ(document.get(), shadowRootB->commonAncestorTreeScope(*shadowRootA));
+}
+
+TEST(TreeScopeTest, CommonAncestorOfTreesAtDifferentDepths)
+{
+ // document
+ // / \ : Common ancestor is document.
+ // Y B
+ // /
+ // A
+
+ RefPtrWillBeRawPtr<Document> document = Document::create();
+ RefPtrWillBeRawPtr<Element> html = document->createElement("html", nullAtom, ASSERT_NO_EXCEPTION);
+ document->appendChild(html, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<Element> head = document->createElement("head", nullAtom, ASSERT_NO_EXCEPTION);
+ html->appendChild(head);
+ RefPtrWillBeRawPtr<Element> body = document->createElement("body", nullAtom, ASSERT_NO_EXCEPTION);
+ html->appendChild(body);
+
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootY = head->createShadowRoot(ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootB = body->createShadowRoot(ASSERT_NO_EXCEPTION);
+
+ RefPtrWillBeRawPtr<Element> divInY = document->createElement("div", nullAtom, ASSERT_NO_EXCEPTION);
+ shadowRootY->appendChild(divInY);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRootA = divInY->createShadowRoot(ASSERT_NO_EXCEPTION);
+
+ EXPECT_EQ(document.get(), shadowRootA->commonAncestorTreeScope(*shadowRootB));
+ EXPECT_EQ(document.get(), shadowRootB->commonAncestorTreeScope(*shadowRootA));
+}
+
+TEST(TreeScopeTest, CommonAncestorOfTreesInDifferentDocuments)
+{
+ RefPtrWillBeRawPtr<Document> document1 = Document::create();
+ RefPtrWillBeRawPtr<Document> document2 = Document::create();
+ EXPECT_EQ(0, document1->commonAncestorTreeScope(*document2));
+ EXPECT_EQ(0, document2->commonAncestorTreeScope(*document1));
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeShared.h b/chromium/third_party/WebKit/Source/core/dom/TreeShared.h
index 8637dc631d0..1f22797aa42 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeShared.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeShared.h
@@ -21,6 +21,7 @@
#ifndef TreeShared_h
#define TreeShared_h
+#include "public/platform/WebPrivatePtr.h"
#include "wtf/Assertions.h"
#include "wtf/MainThread.h"
#include "wtf/Noncopyable.h"
@@ -32,14 +33,14 @@ template<typename NodeType> class TreeShared;
template<typename NodeType> void adopted(TreeShared<NodeType>*);
#endif
-template<typename NodeType> class TreeShared {
+template<typename NodeType> class TreeShared : public NoBaseWillBeGarbageCollectedFinalized<NodeType> {
WTF_MAKE_NONCOPYABLE(TreeShared);
protected:
TreeShared()
: m_refCount(1)
#if SECURITY_ASSERT_ENABLED
, m_deletionHasBegun(false)
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
, m_inRemovedLastRefFunction(false)
, m_adoptionIsRequired(true)
#endif
@@ -69,23 +70,20 @@ public:
void deref()
{
ASSERT(isMainThread());
- ASSERT(m_refCount >= 0);
+ ASSERT(m_refCount > 0);
ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
ASSERT(!m_inRemovedLastRefFunction);
ASSERT(!m_adoptionIsRequired);
NodeType* thisNode = static_cast<NodeType*>(this);
- if (--m_refCount <= 0 && !thisNode->hasTreeSharedParent()) {
-#if !ASSERT_DISABLED
+ if (!--m_refCount && !thisNode->hasTreeSharedParent()) {
+#if ASSERT_ENABLED
m_inRemovedLastRefFunction = true;
#endif
thisNode->removedLastRef();
}
}
- int refCount() const
- {
- return m_refCount;
- }
+ int refCount() const { return m_refCount; }
private:
int m_refCount;
@@ -93,7 +91,7 @@ private:
#if SECURITY_ASSERT_ENABLED
public:
bool m_deletionHasBegun;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool m_inRemovedLastRefFunction;
private:
@@ -108,8 +106,9 @@ template<typename NodeType> inline void adopted(TreeShared<NodeType>* object)
{
if (!object)
return;
+
ASSERT_WITH_SECURITY_IMPLICATION(!object->m_deletionHasBegun);
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
ASSERT(!object->m_inRemovedLastRefFunction);
object->m_adoptionIsRequired = false;
#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp
index fa099813850..dfa29d55e4d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.cpp
@@ -25,45 +25,45 @@
#include "config.h"
#include "core/dom/TreeWalker.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptState.h"
#include "core/dom/ContainerNode.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeTraversal.h"
namespace WebCore {
-TreeWalker::TreeWalker(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
- : Traversal(rootNode, whatToShow, filter)
+TreeWalker::TreeWalker(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
+ : NodeIteratorBase(rootNode, whatToShow, filter)
, m_current(root())
{
ScriptWrappable::init(this);
}
-void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionState& exceptionState)
+void TreeWalker::setCurrentNode(PassRefPtrWillBeRawPtr<Node> node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwDOMException(NotSupportedError, "The Node provided is invalid.");
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return;
}
m_current = node;
}
-inline Node* TreeWalker::setCurrent(PassRefPtr<Node> node)
+inline Node* TreeWalker::setCurrent(PassRefPtrWillBeRawPtr<Node> node)
{
m_current = node;
return m_current.get();
}
-Node* TreeWalker::parentNode(ScriptState* state)
+Node* TreeWalker::parentNode(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
while (node != root()) {
node = node->parentNode();
if (!node)
return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return setCurrent(node.release());
@@ -71,11 +71,11 @@ Node* TreeWalker::parentNode(ScriptState* state)
return 0;
}
-Node* TreeWalker::firstChild(ScriptState* state)
+Node* TreeWalker::firstChild(ExceptionState& exceptionState)
{
- for (RefPtr<Node> node = m_current->firstChild(); node; ) {
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ for (RefPtrWillBeRawPtr<Node> node = m_current->firstChild(); node; ) {
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
@@ -104,11 +104,11 @@ Node* TreeWalker::firstChild(ScriptState* state)
return 0;
}
-Node* TreeWalker::lastChild(ScriptState* state)
+Node* TreeWalker::lastChild(ExceptionState& exceptionState)
{
- for (RefPtr<Node> node = m_current->lastChild(); node; ) {
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ for (RefPtrWillBeRawPtr<Node> node = m_current->lastChild(); node; ) {
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
@@ -137,15 +137,15 @@ Node* TreeWalker::lastChild(ScriptState* state)
return 0;
}
-Node* TreeWalker::previousSibling(ScriptState* state)
+Node* TreeWalker::previousSibling(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
if (node == root())
return 0;
while (1) {
- for (RefPtr<Node> sibling = node->previousSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(state, sibling.get());
- if (state && state->hadException())
+ for (RefPtrWillBeRawPtr<Node> sibling = node->previousSibling(); sibling; ) {
+ short acceptNodeResult = acceptNode(sibling.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
@@ -166,23 +166,23 @@ Node* TreeWalker::previousSibling(ScriptState* state)
node = node->parentNode();
if (!node || node == root())
return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return 0;
}
}
-Node* TreeWalker::nextSibling(ScriptState* state)
+Node* TreeWalker::nextSibling(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
if (node == root())
return 0;
while (1) {
- for (RefPtr<Node> sibling = node->nextSibling(); sibling; ) {
- short acceptNodeResult = acceptNode(state, sibling.get());
- if (state && state->hadException())
+ for (RefPtrWillBeRawPtr<Node> sibling = node->nextSibling(); sibling; ) {
+ short acceptNodeResult = acceptNode(sibling.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
switch (acceptNodeResult) {
case NodeFilter::FILTER_ACCEPT:
@@ -203,29 +203,29 @@ Node* TreeWalker::nextSibling(ScriptState* state)
node = node->parentNode();
if (!node || node == root())
return 0;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return 0;
}
}
-Node* TreeWalker::previousNode(ScriptState* state)
+Node* TreeWalker::previousNode(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
while (node != root()) {
while (Node* previousSibling = node->previousSibling()) {
node = previousSibling;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_REJECT)
continue;
while (Node* lastChild = node->lastChild()) {
node = lastChild;
- acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_REJECT)
break;
@@ -241,8 +241,8 @@ Node* TreeWalker::previousNode(ScriptState* state)
if (!parent)
return 0;
node = parent;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return setCurrent(node.release());
@@ -250,14 +250,14 @@ Node* TreeWalker::previousNode(ScriptState* state)
return 0;
}
-Node* TreeWalker::nextNode(ScriptState* state)
+Node* TreeWalker::nextNode(ExceptionState& exceptionState)
{
- RefPtr<Node> node = m_current;
+ RefPtrWillBeRawPtr<Node> node = m_current;
Children:
while (Node* firstChild = node->firstChild()) {
node = firstChild;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return setCurrent(node.release());
@@ -266,8 +266,8 @@ Children:
}
while (Node* nextSibling = NodeTraversal::nextSkippingChildren(*node, root())) {
node = nextSibling;
- short acceptNodeResult = acceptNode(state, node.get());
- if (state && state->hadException())
+ short acceptNodeResult = acceptNode(node.get(), exceptionState);
+ if (exceptionState.hadException())
return 0;
if (acceptNodeResult == NodeFilter::FILTER_ACCEPT)
return setCurrent(node.release());
@@ -277,4 +277,10 @@ Children:
return 0;
}
+void TreeWalker::trace(Visitor* visitor)
+{
+ visitor->trace(m_current);
+ NodeIteratorBase::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.h b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.h
index 354e449289a..2980a0fce2d 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.h
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.h
@@ -27,7 +27,8 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/NodeFilter.h"
-#include "core/dom/Traversal.h"
+#include "core/dom/NodeIteratorBase.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -35,30 +36,33 @@ namespace WebCore {
class ExceptionState;
-class TreeWalker : public ScriptWrappable, public RefCounted<TreeWalker>, public Traversal {
+class TreeWalker FINAL : public RefCountedWillBeGarbageCollectedFinalized<TreeWalker>, public ScriptWrappable, public NodeIteratorBase {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TreeWalker);
public:
- static PassRefPtr<TreeWalker> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
+ static PassRefPtrWillBeRawPtr<TreeWalker> create(PassRefPtrWillBeRawPtr<Node> rootNode, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter> filter)
{
- return adoptRef(new TreeWalker(rootNode, whatToShow, filter));
+ return adoptRefWillBeNoop(new TreeWalker(rootNode, whatToShow, filter));
}
Node* currentNode() const { return m_current.get(); }
- void setCurrentNode(PassRefPtr<Node>, ExceptionState&);
+ void setCurrentNode(PassRefPtrWillBeRawPtr<Node>, ExceptionState&);
- Node* parentNode(ScriptState*);
- Node* firstChild(ScriptState*);
- Node* lastChild(ScriptState*);
- Node* previousSibling(ScriptState*);
- Node* nextSibling(ScriptState*);
- Node* previousNode(ScriptState*);
- Node* nextNode(ScriptState*);
+ Node* parentNode(ExceptionState&);
+ Node* firstChild(ExceptionState&);
+ Node* lastChild(ExceptionState&);
+ Node* previousSibling(ExceptionState&);
+ Node* nextSibling(ExceptionState&);
+ Node* previousNode(ExceptionState&);
+ Node* nextNode(ExceptionState&);
+
+ void trace(Visitor*);
private:
- TreeWalker(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
+ TreeWalker(PassRefPtrWillBeRawPtr<Node>, unsigned whatToShow, PassRefPtrWillBeRawPtr<NodeFilter>);
- Node* setCurrent(PassRefPtr<Node>);
+ Node* setCurrent(PassRefPtrWillBeRawPtr<Node>);
- RefPtr<Node> m_current;
+ RefPtrWillBeMember<Node> m_current;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl
index 6a92eb0a168..2fb6eb58a91 100644
--- a/chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/TreeWalker.idl
@@ -18,22 +18,22 @@
* Boston, MA 02110-1301, USA.
*/
-// Introduced in DOM Level 2:
+// Introduced in DOM Level 2
[
- SetReference(NodeFilter filter)
+ SetWrapperReferenceTo(NodeFilter filter),
+ WillBeGarbageCollected,
] interface TreeWalker {
readonly attribute Node root;
readonly attribute unsigned long whatToShow;
readonly attribute NodeFilter filter;
- readonly attribute boolean expandEntityReferences;
+ [DeprecateAs=TreeWalkerExpandEntityReferences] readonly attribute boolean expandEntityReferences;
[RaisesException=Setter] attribute Node currentNode;
- [CallWith=ScriptState] Node parentNode();
- [CallWith=ScriptState] Node firstChild();
- [CallWith=ScriptState] Node lastChild();
- [CallWith=ScriptState] Node previousSibling();
- [CallWith=ScriptState] Node nextSibling();
- [CallWith=ScriptState] Node previousNode();
- [CallWith=ScriptState] Node nextNode();
+ [RaisesException] Node parentNode();
+ [RaisesException] Node firstChild();
+ [RaisesException] Node lastChild();
+ [RaisesException] Node previousSibling();
+ [RaisesException] Node nextSibling();
+ [RaisesException] Node previousNode();
+ [RaisesException] Node nextNode();
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/URL.idl b/chromium/third_party/WebKit/Source/core/dom/URL.idl
index 30c96c69db2..37b80510f3c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/URL.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/URL.idl
@@ -24,17 +24,22 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://url.spec.whatwg.org/#url
+
[
- GlobalContext=Window&WorkerGlobalScope,
- RaisesException=Constructor,
Constructor(DOMString url),
- Constructor(DOMString url, URL base),
Constructor(DOMString url, DOMString base),
- ImplementedAs=DOMURL
+ Constructor(DOMString url, URL base),
+ Exposed=Window&Worker,
+ ImplementedAs=DOMURL,
+ RaisesException=Constructor,
+ WillBeGarbageCollected,
] interface URL {
- [CallWith=ExecutionContext,TreatReturnedNullStringAs=Null] static DOMString createObjectURL(Blob? blob);
+ // FIXME: should be in separate URLBlob.idl partial interface definition
+ // http://dev.w3.org/2006/webapi/FileAPI/#URL-object
+ // FIXME: should not be nullable
+ [RaisesException, CallWith=ExecutionContext, TreatReturnedNullStringAs=Null] static DOMString createObjectURL(Blob? blob);
[CallWith=ExecutionContext] static void revokeObjectURL(DOMString url);
};
-// force rebuild: crbug.com/307023
URL implements URLUtils;
diff --git a/chromium/third_party/WebKit/Source/core/dom/URLUtils.idl b/chromium/third_party/WebKit/Source/core/dom/URLUtils.idl
index 9cb7b488597..26ed382acf8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/URLUtils.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/URLUtils.idl
@@ -23,15 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://url.spec.whatwg.org/#urlutils
+
[
- NoInterfaceObject,
- ImplementedAs=DOMURLUtils
+ NoInterfaceObject, // Always used on target of 'implements'
] interface URLUtils {
- attribute DOMString href;
-
+ // FIXME: should be stringifier: http://crbug.com/306606
+ // stringifier attribute DOMString href;
+ [PerWorldBindings, LogActivity=SetterOnly, LogPreviousValue] attribute DOMString href;
[NotEnumerable, ImplementedAs=href] DOMString toString();
-
readonly attribute DOMString origin;
+
attribute DOMString protocol;
attribute DOMString username;
attribute DOMString password;
@@ -40,10 +42,7 @@
attribute DOMString port;
attribute DOMString pathname;
attribute DOMString search;
-
// Not yet implemented.
- // attribute URLQuery? query;
-
+ // attribute URLSearchParams searchParams;
attribute DOMString hash;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl b/chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl
index 0d36b46d0af..ccd26f77053 100644
--- a/chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/URLUtilsReadOnly.idl
@@ -23,13 +23,17 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://url.spec.whatwg.org/#urlutilsreadonly
+
[
- NoInterfaceObject,
- ImplementedAs=DOMURLUtilsReadOnly
+ NoInterfaceObject, // Always used on target of 'implements'
] interface URLUtilsReadOnly {
+ // FIXME: should be stringifier: http://crbug.com/306606
+ // stringifier readonly attribute DOMString href;
readonly attribute DOMString href;
-
[NotEnumerable, ImplementedAs=href] DOMString toString();
+ // Not yet implemented.
+ // readonly attribute DOMString origin;
readonly attribute DOMString protocol;
readonly attribute DOMString host;
diff --git a/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp b/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp
index 264061fd539..e59d1fa6003 100644
--- a/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.cpp
@@ -46,10 +46,12 @@ void UserActionElementSet::didDetach(Node* node)
clearFlags(toElement(node), IsActiveFlag | InActiveChainFlag | IsHoveredFlag);
}
+#if !ENABLE(OILPAN)
void UserActionElementSet::documentDidRemoveLastRef()
{
m_elements.clear();
}
+#endif
bool UserActionElementSet::hasFlags(const Node* node, unsigned flags) const
{
@@ -116,4 +118,9 @@ inline void UserActionElementSet::setFlags(Element* element, unsigned flags)
m_elements.add(element, flags);
}
+void UserActionElementSet::trace(Visitor* visitor)
+{
+ visitor->trace(m_elements);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h b/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h
index 9883262c04f..e060ef00c36 100644
--- a/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h
+++ b/chromium/third_party/WebKit/Source/core/dom/UserActionElementSet.h
@@ -27,6 +27,7 @@
#ifndef UserActionElementSet_h
#define UserActionElementSet_h
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefPtr.h"
@@ -36,10 +37,9 @@ namespace WebCore {
class Node;
class Element;
-class UserActionElementSet {
+class UserActionElementSet FINAL {
+ DISALLOW_ALLOCATION();
public:
- static PassOwnPtr<UserActionElementSet> create() { return adoptPtr(new UserActionElementSet()); }
-
bool isFocused(const Node* node) { return hasFlags(node, IsFocusedFlag); }
bool isActive(const Node* node) { return hasFlags(node, IsActiveFlag); }
bool isInActiveChain(const Node* node) { return hasFlags(node, InActiveChainFlag); }
@@ -53,7 +53,12 @@ public:
~UserActionElementSet();
void didDetach(Node*);
+
+#if !ENABLE(OILPAN)
void documentDidRemoveLastRef();
+#endif
+
+ void trace(Visitor*);
private:
enum ElementFlags {
@@ -72,7 +77,7 @@ private:
void clearFlags(Element*, unsigned);
bool hasFlags(const Element*, unsigned flags) const;
- typedef HashMap<RefPtr<Element>, unsigned> ElementFlagMap;
+ typedef WillBeHeapHashMap<RefPtrWillBeMember<Element>, unsigned> ElementFlagMap;
ElementFlagMap m_elements;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp b/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
index 77f924e623b..f6c88184eca 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.cpp
@@ -28,7 +28,13 @@
#include "config.h"
#include "core/dom/ViewportDescription.h"
-using namespace std;
+#include "core/dom/Document.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "platform/weborigin/KURL.h"
+#include "public/platform/Platform.h"
namespace WebCore {
@@ -54,27 +60,45 @@ float ViewportDescription::resolveViewportLength(const Length& length, const Flo
if (length.type() == ExtendToZoom)
return ViewportDescription::ValueExtendToZoom;
- if ((length.type() == Percent && direction == Horizontal) || length.type() == ViewportPercentageWidth)
+ if (length.type() == Percent && direction == Horizontal)
return initialViewportSize.width() * length.getFloatValue() / 100.0f;
- if ((length.type() == Percent && direction == Vertical) || length.type() == ViewportPercentageHeight)
+ if (length.type() == Percent && direction == Vertical)
return initialViewportSize.height() * length.getFloatValue() / 100.0f;
- if (length.type() == ViewportPercentageMin)
- return min(initialViewportSize.width(), initialViewportSize.height()) * length.viewportPercentageLength() / 100.0f;
+ if (length.type() == DeviceWidth)
+ return initialViewportSize.width();
- if (length.type() == ViewportPercentageMax)
- return max(initialViewportSize.width(), initialViewportSize.height()) * length.viewportPercentageLength() / 100.0f;
+ if (length.type() == DeviceHeight)
+ return initialViewportSize.height();
ASSERT_NOT_REACHED();
return ViewportDescription::ValueAuto;
}
-PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewportSize) const
+PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewportSize, Length legacyFallbackWidth) const
{
float resultWidth = ValueAuto;
- float resultMaxWidth = resolveViewportLength(maxWidth, initialViewportSize, Horizontal);
- float resultMinWidth = resolveViewportLength(minWidth, initialViewportSize, Horizontal);
+
+ Length copyMaxWidth = maxWidth;
+ Length copyMinWidth = minWidth;
+ // In case the width (used for min- and max-width) is undefined.
+ if (isLegacyViewportType() && maxWidth.isAuto()) {
+ // The width viewport META property is translated into 'width' descriptors, setting
+ // the 'min' value to 'extend-to-zoom' and the 'max' value to the intended length.
+ // In case the UA-defines a min-width, use that as length.
+ if (zoom == ViewportDescription::ValueAuto) {
+ copyMinWidth = Length(ExtendToZoom);
+ copyMaxWidth = legacyFallbackWidth;
+ } else if (maxHeight.isAuto()) {
+ copyMinWidth = Length(ExtendToZoom);
+ copyMaxWidth = Length(ExtendToZoom);
+ }
+ }
+
+ float resultMaxWidth = resolveViewportLength(copyMaxWidth, initialViewportSize, Horizontal);
+ float resultMinWidth = resolveViewportLength(copyMinWidth, initialViewportSize, Horizontal);
+
float resultHeight = ValueAuto;
float resultMaxHeight = resolveViewportLength(maxHeight, initialViewportSize, Vertical);
float resultMinHeight = resolveViewportLength(minHeight, initialViewportSize, Vertical);
@@ -82,17 +106,17 @@ PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewpo
float resultZoom = zoom;
float resultMinZoom = minZoom;
float resultMaxZoom = maxZoom;
- float resultUserZoom = userZoom;
+ bool resultUserZoom = userZoom;
// 1. Resolve min-zoom and max-zoom values.
if (resultMinZoom != ViewportDescription::ValueAuto && resultMaxZoom != ViewportDescription::ValueAuto)
- resultMaxZoom = max(resultMinZoom, resultMaxZoom);
+ resultMaxZoom = std::max(resultMinZoom, resultMaxZoom);
// 2. Constrain zoom value to the [min-zoom, max-zoom] range.
if (resultZoom != ViewportDescription::ValueAuto)
- resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, min), max);
+ resultZoom = compareIgnoringAuto(resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, std::min), std::max);
- float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, min);
+ float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, std::min);
// 3. Resolve non-"auto" lengths to pixel lengths.
if (extendZoom == ViewportDescription::ValueAuto) {
@@ -118,19 +142,19 @@ PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewpo
resultMaxHeight = extendHeight;
if (resultMinWidth == ViewportDescription::ValueExtendToZoom)
- resultMinWidth = compareIgnoringAuto(extendWidth, resultMaxWidth, max);
+ resultMinWidth = compareIgnoringAuto(extendWidth, resultMaxWidth, std::max);
if (resultMinHeight == ViewportDescription::ValueExtendToZoom)
- resultMinHeight = compareIgnoringAuto(extendHeight, resultMaxHeight, max);
+ resultMinHeight = compareIgnoringAuto(extendHeight, resultMaxHeight, std::max);
}
// 4. Resolve initial width from min/max descriptors.
if (resultMinWidth != ViewportDescription::ValueAuto || resultMaxWidth != ViewportDescription::ValueAuto)
- resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), min), max);
+ resultWidth = compareIgnoringAuto(resultMinWidth, compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(), std::min), std::max);
// 5. Resolve initial height from min/max descriptors.
if (resultMinHeight != ViewportDescription::ValueAuto || resultMaxHeight != ViewportDescription::ValueAuto)
- resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), min), max);
+ resultHeight = compareIgnoringAuto(resultMinHeight, compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(), std::min), std::max);
// 6-7. Resolve width value.
if (resultWidth == ViewportDescription::ValueAuto) {
@@ -154,7 +178,7 @@ PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewpo
resultZoom = initialViewportSize.width() / resultWidth;
if (resultHeight != ViewportDescription::ValueAuto && resultHeight > 0) {
// if 'auto', the initial-scale will be negative here and thus ignored.
- resultZoom = max<float>(resultZoom, initialViewportSize.height() / resultHeight);
+ resultZoom = std::max<float>(resultZoom, initialViewportSize.height() / resultHeight);
}
}
@@ -176,4 +200,63 @@ PageScaleConstraints ViewportDescription::resolve(const FloatSize& initialViewpo
return result;
}
+void ViewportDescription::reportMobilePageStats(const LocalFrame* mainFrame) const
+{
+#if OS(ANDROID)
+ enum ViewportUMAType {
+ NoViewportTag,
+ DeviceWidth,
+ ConstantWidth,
+ MetaWidthOther,
+ MetaHandheldFriendly,
+ MetaMobileOptimized,
+ XhtmlMobileProfile,
+ TypeCount
+ };
+
+ if (!mainFrame || !mainFrame->host() || !mainFrame->view() || !mainFrame->document())
+ return;
+
+ // Avoid chrome:// pages like the new-tab page (on Android new tab is non-http).
+ if (!mainFrame->document()->url().protocolIsInHTTPFamily())
+ return;
+
+ if (!isSpecifiedByAuthor()) {
+ if (mainFrame->document()->isMobileDocument())
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", XhtmlMobileProfile, TypeCount);
+ else
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", NoViewportTag, TypeCount);
+
+ return;
+ }
+
+ if (isMetaViewportType()) {
+ if (maxWidth.type() == WebCore::Fixed) {
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", ConstantWidth, TypeCount);
+
+ if (mainFrame->view()) {
+ // To get an idea of how "far" the viewport is from the device's ideal width, we
+ // report the zoom level that we'd need to be at for the entire page to be visible.
+ int viewportWidth = maxWidth.intValue();
+ int windowWidth = mainFrame->document()->settings()->pinchVirtualViewportEnabled()
+ ? mainFrame->host()->pinchViewport().size().width()
+ : mainFrame->view()->frameRect().width();
+ int overviewZoomPercent = 100 * windowWidth / static_cast<float>(viewportWidth);
+ blink::Platform::current()->histogramSparse("Viewport.OverviewZoom", overviewZoomPercent);
+ }
+
+ } else if (maxWidth.type() == WebCore::DeviceWidth || maxWidth.type() == WebCore::ExtendToZoom) {
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", DeviceWidth, TypeCount);
+ } else {
+ // Overflow bucket for cases we may be unaware of.
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", MetaWidthOther, TypeCount);
+ }
+ } else if (type == ViewportDescription::HandheldFriendlyMeta) {
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", MetaHandheldFriendly, TypeCount);
+ } else if (type == ViewportDescription::MobileOptimizedMeta) {
+ blink::Platform::current()->histogramEnumeration("Viewport.MetaTagType", MobileOptimizedMeta, TypeCount);
+ }
+#endif
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h b/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h
index 53eed2688f5..c5e22de890b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h
+++ b/chromium/third_party/WebKit/Source/core/dom/ViewportDescription.h
@@ -34,6 +34,9 @@
namespace WebCore {
+class KURL;
+class LocalFrame;
+
struct ViewportDescription {
enum Type {
@@ -63,14 +66,18 @@ struct ViewportDescription {
, zoom(ValueAuto)
, minZoom(ValueAuto)
, maxZoom(ValueAuto)
- , userZoom(ValueAuto)
+ , userZoom(true)
, orientation(ValueAuto)
, deprecatedTargetDensityDPI(ValueAuto)
+ , zoomIsExplicit(false)
+ , minZoomIsExplicit(false)
+ , maxZoomIsExplicit(false)
+ , userZoomIsExplicit(false)
{
}
// All arguments are in CSS units.
- PageScaleConstraints resolve(const FloatSize& initialViewportSize) const;
+ PageScaleConstraints resolve(const FloatSize& initialViewportSize, Length legacyFallbackWidth) const;
Length minWidth;
Length maxWidth;
@@ -79,10 +86,17 @@ struct ViewportDescription {
float zoom;
float minZoom;
float maxZoom;
- float userZoom;
+ bool userZoom;
float orientation;
float deprecatedTargetDensityDPI; // Only used for Android WebView
+ // Whether the computed value was explicitly specified rather than being
+ // inferred.
+ bool zoomIsExplicit;
+ bool minZoomIsExplicit;
+ bool maxZoomIsExplicit;
+ bool userZoomIsExplicit;
+
bool operator==(const ViewportDescription& other) const
{
// Used for figuring out whether to reset the viewport or not,
@@ -96,7 +110,11 @@ struct ViewportDescription {
&& maxZoom == other.maxZoom
&& userZoom == other.userZoom
&& orientation == other.orientation
- && deprecatedTargetDensityDPI == other.deprecatedTargetDensityDPI;
+ && deprecatedTargetDensityDPI == other.deprecatedTargetDensityDPI
+ && zoomIsExplicit == other.zoomIsExplicit
+ && minZoomIsExplicit == other.minZoomIsExplicit
+ && maxZoomIsExplicit == other.maxZoomIsExplicit
+ && userZoomIsExplicit == other.userZoomIsExplicit;
}
bool operator!=(const ViewportDescription& other) const
@@ -108,6 +126,10 @@ struct ViewportDescription {
bool isMetaViewportType() const { return type == ViewportMeta; }
bool isSpecifiedByAuthor() const { return type != UserAgentStyleSheet; }
+ // Reports UMA stat on whether the page is considered mobile or desktop and what kind of
+ // mobile it is. Applies only to Android, must only be called once per page load.
+ void reportMobilePageStats(const LocalFrame*) const;
+
private:
enum Direction { Horizontal, Vertical };
static float resolveViewportLength(const Length&, const FloatSize& initialViewportSize, Direction);
diff --git a/chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp b/chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp
index f715a3dfeb9..45f74a90fbd 100644
--- a/chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/VisitedLinkState.cpp
@@ -29,8 +29,8 @@
#include "config.h"
#include "core/dom/VisitedLinkState.h"
-#include "HTMLNames.h"
-#include "XLinkNames.h"
+#include "core/HTMLNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLAnchorElement.h"
#include "public/platform/Platform.h"
@@ -65,7 +65,7 @@ void VisitedLinkState::invalidateStyleForAllLinks()
return;
for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(*element)) {
if (element->isLink())
- element->setNeedsStyleRecalc();
+ element->setNeedsStyleRecalc(SubtreeStyleChange);
}
}
@@ -75,7 +75,7 @@ void VisitedLinkState::invalidateStyleForLink(LinkHash linkHash)
return;
for (Element* element = ElementTraversal::firstWithin(m_document); element; element = ElementTraversal::next(*element)) {
if (element->isLink() && linkHashForElement(*element) == linkHash)
- element->setNeedsStyleRecalc();
+ element->setNeedsStyleRecalc(SubtreeStyleChange);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.cpp b/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.cpp
new file mode 100644
index 00000000000..34296c004b7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.cpp
@@ -0,0 +1,104 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/WeakNodeMap.h"
+
+#include "core/dom/Node.h"
+
+namespace WebCore {
+
+class NodeToWeakNodeMaps {
+public:
+ bool addedToMap(Node*, WeakNodeMap*);
+ bool removedFromMap(Node*, WeakNodeMap*);
+ void nodeDestroyed(Node*);
+
+ static NodeToWeakNodeMaps& instance()
+ {
+ DEFINE_STATIC_LOCAL(NodeToWeakNodeMaps, self, ());
+ return self;
+ }
+
+private:
+ typedef Vector<WeakNodeMap*, 1> MapList;
+ typedef HashMap<Node*, OwnPtr<MapList> > NodeToMapList;
+ NodeToMapList m_nodeToMapList;
+};
+
+bool NodeToWeakNodeMaps::addedToMap(Node* node, WeakNodeMap* map)
+{
+ NodeToMapList::AddResult result = m_nodeToMapList.add(node, nullptr);
+ if (result.isNewEntry)
+ result.storedValue->value = adoptPtr(new MapList());
+ result.storedValue->value->append(map);
+ return result.isNewEntry;
+}
+
+bool NodeToWeakNodeMaps::removedFromMap(Node* node, WeakNodeMap* map)
+{
+ NodeToMapList::iterator it = m_nodeToMapList.find(node);
+ ASSERT(it != m_nodeToMapList.end());
+ MapList* mapList = it->value.get();
+ size_t position = mapList->find(map);
+ ASSERT(position != kNotFound);
+ mapList->remove(position);
+ if (mapList->size() == 0) {
+ m_nodeToMapList.remove(it);
+ return true;
+ }
+ return false;
+}
+
+void NodeToWeakNodeMaps::nodeDestroyed(Node* node)
+{
+ OwnPtr<NodeToWeakNodeMaps::MapList> maps = m_nodeToMapList.take(node);
+ for (size_t i = 0; i < maps->size(); i++)
+ (*maps)[i]->nodeDestroyed(node);
+}
+
+WeakNodeMap::~WeakNodeMap()
+{
+ NodeToWeakNodeMaps& allMaps = NodeToWeakNodeMaps::instance();
+ for (NodeToValue::iterator it = m_nodeToValue.begin(); it != m_nodeToValue.end(); ++it) {
+ Node* node = it->key;
+ if (allMaps.removedFromMap(node, this))
+ node->clearFlag(Node::HasWeakReferencesFlag);
+ }
+}
+
+void WeakNodeMap::put(Node* node, int value)
+{
+ ASSERT(!m_nodeToValue.contains(node));
+ m_nodeToValue.set(node, value);
+ m_valueToNode.set(value, node);
+
+ NodeToWeakNodeMaps& maps = NodeToWeakNodeMaps::instance();
+ if (maps.addedToMap(node, this))
+ node->setFlag(Node::HasWeakReferencesFlag);
+}
+
+int WeakNodeMap::value(Node* node)
+{
+ return m_nodeToValue.get(node);
+}
+
+Node* WeakNodeMap::node(int value)
+{
+ return m_valueToNode.get(value);
+}
+
+void WeakNodeMap::nodeDestroyed(Node* node)
+{
+ int value = m_nodeToValue.take(node);
+ ASSERT(value);
+ m_valueToNode.remove(value);
+}
+
+void WeakNodeMap::notifyNodeDestroyed(Node* node)
+{
+ NodeToWeakNodeMaps::instance().nodeDestroyed(node);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.h b/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.h
new file mode 100644
index 00000000000..44cdf59fb47
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/WeakNodeMap.h
@@ -0,0 +1,40 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WeakNodeMap_h
+#define WeakNodeMap_h
+
+#include "wtf/HashMap.h"
+
+namespace WebCore {
+
+class Node;
+class NodeToWeakNodeMaps;
+
+class WeakNodeMap {
+public:
+ ~WeakNodeMap();
+
+ void put(Node*, int value);
+ int value(Node*);
+ Node* node(int value);
+
+private:
+ // FIXME: This should not be friends with Node, we should expose a proper API and not
+ // let the map directly set flags.
+ friend class Node;
+ static void notifyNodeDestroyed(Node*);
+
+ friend class NodeToWeakNodeMaps;
+ void nodeDestroyed(Node*);
+
+ typedef HashMap<Node*, int> NodeToValue;
+ NodeToValue m_nodeToValue;
+ typedef HashMap<int, Node*> ValueToNode;
+ ValueToNode m_valueToNode;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlow.idl b/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlow.idl
deleted file mode 100644
index 800e26d9b08..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlow.idl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
- GenerateVisitDOMWrapper=ownerNode,
- ImplementedAs=NamedFlow,
- NoInterfaceObject,
- RuntimeEnabled=CSSRegions,
-] interface WebKitNamedFlow : EventTarget {
- readonly attribute DOMString name;
- readonly attribute boolean overset;
- readonly attribute long firstEmptyRegionIndex;
- NodeList getRegionsByContent(Node contentNode);
- NodeList getRegions();
- NodeList getContent();
-};
diff --git a/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlowCollection.idl b/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlowCollection.idl
deleted file mode 100644
index 4744e069746..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/WebKitNamedFlowCollection.idl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject,
- RuntimeEnabled=CSSRegions,
- ImplementedAs=DOMNamedFlowCollection
-] interface WebKitNamedFlowCollection {
- readonly attribute unsigned long length;
- getter WebKitNamedFlow item(unsigned long index);
- WebKitNamedFlow namedItem(DOMString name);
- [NotEnumerable, ImplementedAs=namedItem] getter WebKitNamedFlow (DOMString name);
-};
diff --git a/chromium/third_party/WebKit/Source/core/dom/WheelController.cpp b/chromium/third_party/WebKit/Source/core/dom/WheelController.cpp
deleted file mode 100644
index 68d5b18b2e5..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/WheelController.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/WheelController.h"
-
-#include "core/dom/Document.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/events/WheelEvent.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-
-namespace WebCore {
-
-WheelController::WheelController(Document* document)
- : DOMWindowLifecycleObserver(document->domWindow())
- , m_wheelEventHandlerCount(0)
-{
-}
-
-WheelController::~WheelController()
-{
-}
-
-const char* WheelController::supplementName()
-{
- return "WheelController";
-}
-
-WheelController* WheelController::from(Document* document)
-{
- WheelController* controller = static_cast<WheelController*>(DocumentSupplement::from(document, supplementName()));
- if (!controller) {
- controller = new WheelController(document);
- DocumentSupplement::provideTo(document, supplementName(), adoptPtr(controller));
- }
- return controller;
-}
-
-static void wheelEventHandlerCountChanged(Document* document)
-{
- Page* page = document->page();
- if (!page)
- return;
-
- ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator();
- if (!scrollingCoordinator)
- return;
-
- FrameView* frameView = document->view();
- if (!frameView)
- return;
-
- scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView);
-}
-
-void WheelController::didAddWheelEventHandler(Document* document)
-{
- ++m_wheelEventHandlerCount;
- Page* page = document->page();
- Frame* mainFrame = page ? page->mainFrame() : 0;
- if (mainFrame)
- mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
-
- wheelEventHandlerCountChanged(document);
-}
-
-void WheelController::didRemoveWheelEventHandler(Document* document)
-{
- ASSERT(m_wheelEventHandlerCount > 0);
- --m_wheelEventHandlerCount;
- Page* page = document->page();
- Frame* mainFrame = page ? page->mainFrame() : 0;
- if (mainFrame)
- mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
-
- wheelEventHandlerCountChanged(document);
-}
-
-void WheelController::didAddEventListener(DOMWindow* window, const AtomicString& eventType)
-{
- if (eventType != EventTypeNames::wheel && eventType != EventTypeNames::mousewheel)
- return;
-
- Document* document = window->document();
- didAddWheelEventHandler(document);
-}
-
-void WheelController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
-{
- if (eventType != EventTypeNames::wheel && eventType != EventTypeNames::mousewheel)
- return;
-
- Document* document = window->document();
- didRemoveWheelEventHandler(document);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/WheelController.h b/chromium/third_party/WebKit/Source/core/dom/WheelController.h
deleted file mode 100644
index 550cb09a3c0..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/WheelController.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WheelController_h
-#define WheelController_h
-
-#include "core/dom/DocumentSupplementable.h"
-#include "core/events/Event.h"
-#include "core/frame/DOMWindowLifecycleObserver.h"
-
-
-namespace WebCore {
-
-class DOMWindow;
-
-class WheelController : public DocumentSupplement, public DOMWindowLifecycleObserver {
-
-public:
- virtual ~WheelController();
-
- static const char* supplementName();
- static WheelController* from(Document*);
-
- unsigned wheelEventHandlerCount() { return m_wheelEventHandlerCount; }
-
- void didAddWheelEventHandler(Document*);
- void didRemoveWheelEventHandler(Document*);
-
- // Inherited from DOMWindowLifecycleObserver
- virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
- virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
-
-private:
- explicit WheelController(Document*);
-
- unsigned m_wheelEventHandlerCount;
-};
-
-} // namespace WebCore
-
-#endif // WheelController_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/XMLDocument.cpp b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.cpp
new file mode 100644
index 00000000000..ed0d55c5530
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/XMLDocument.h"
+
+namespace WebCore {
+
+XMLDocument::XMLDocument(const DocumentInit& initializer, DocumentClassFlags documentClasses)
+ : Document(initializer, documentClasses)
+{
+ ScriptWrappable::init(this);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/XMLDocument.h b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.h
new file mode 100644
index 00000000000..b1843440fa5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef XMLDocument_h
+#define XMLDocument_h
+
+#include "core/dom/Document.h"
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class XMLDocument FINAL : public Document {
+public:
+ static PassRefPtrWillBeRawPtr<XMLDocument> create(const DocumentInit& initializer = DocumentInit())
+ {
+ return adoptRefWillBeNoop(new XMLDocument(initializer, XMLDocumentClass));
+ }
+
+ static PassRefPtrWillBeRawPtr<XMLDocument> createXHTML(const DocumentInit& initializer = DocumentInit())
+ {
+ return adoptRefWillBeNoop(new XMLDocument(initializer, XMLDocumentClass | XHTMLDocumentClass));
+ }
+
+ static PassRefPtrWillBeRawPtr<XMLDocument> createSVG(const DocumentInit& initializer = DocumentInit())
+ {
+ return adoptRefWillBeNoop(new XMLDocument(initializer, XMLDocumentClass | SVGDocumentClass));
+ }
+
+protected:
+ XMLDocument(const DocumentInit&, DocumentClassFlags documentClasses);
+};
+
+DEFINE_DOCUMENT_TYPE_CASTS(XMLDocument);
+
+} // namespace WebCore
+
+#endif // XMLDocument_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/XMLDocument.idl b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.idl
new file mode 100644
index 00000000000..a41fb18aad2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/XMLDocument.idl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface XMLDocument : Document {
+};
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
index 0dc1683ca39..46f8b533a84 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.cpp
@@ -31,16 +31,21 @@
#include "config.h"
#include "core/dom/custom/CustomElement.h"
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
#include "core/dom/custom/CustomElementObserver.h"
+#include "core/dom/custom/CustomElementScheduler.h"
namespace WebCore {
+CustomElementMicrotaskImportStep* CustomElement::didCreateImport(HTMLImportChild* import)
+{
+ return CustomElementScheduler::scheduleImport(import);
+}
+
Vector<AtomicString>& CustomElement::embedderCustomElementNames()
{
DEFINE_STATIC_LOCAL(Vector<AtomicString>, names, ());
@@ -55,15 +60,8 @@ void CustomElement::addEmbedderCustomElementName(const AtomicString& name)
embedderCustomElementNames().append(lower);
}
-static CustomElement::NameSet enabledNameSet()
-{
- return CustomElement::NameSet((RuntimeEnabledFeatures::customElementsEnabled() ? CustomElement::StandardNames : 0) | (RuntimeEnabledFeatures::embedderCustomElementsEnabled() ? CustomElement::EmbedderNames : 0));
-}
-
bool CustomElement::isValidName(const AtomicString& name, NameSet validNames)
{
- validNames = NameSet(validNames & enabledNameSet());
-
if ((validNames & EmbedderNames) && kNotFound != embedderCustomElementNames().find(name))
return Document::isValidName(name);
@@ -71,15 +69,14 @@ bool CustomElement::isValidName(const AtomicString& name, NameSet validNames)
DEFINE_STATIC_LOCAL(Vector<AtomicString>, reservedNames, ());
if (reservedNames.isEmpty()) {
reservedNames.append(MathMLNames::annotation_xmlTag.localName());
- // In principle, "color-profile" should exist in the SVGNames
- // namespace, but we don't implement the color-profile element.
- reservedNames.append("color-profile");
+#if ENABLE(SVG_FONTS)
reservedNames.append(SVGNames::font_faceTag.localName());
reservedNames.append(SVGNames::font_face_srcTag.localName());
reservedNames.append(SVGNames::font_face_uriTag.localName());
reservedNames.append(SVGNames::font_face_formatTag.localName());
reservedNames.append(SVGNames::font_face_nameTag.localName());
reservedNames.append(SVGNames::missing_glyphTag.localName());
+#endif
}
if (kNotFound == reservedNames.find(name))
@@ -100,23 +97,16 @@ void CustomElement::define(Element* element, PassRefPtr<CustomElementDefinition>
break;
case Element::WaitingForUpgrade:
- definitions().add(element, definition);
- CustomElementCallbackScheduler::scheduleCreatedCallback(definition->callbacks(), element);
+ element->setCustomElementDefinition(definition);
+ CustomElementScheduler::scheduleCallback(definition->callbacks(), element, CustomElementLifecycleCallbacks::Created);
break;
}
}
-CustomElementDefinition* CustomElement::definitionFor(Element* element)
-{
- CustomElementDefinition* definition = definitions().get(element);
- ASSERT(definition);
- return definition;
-}
-
void CustomElement::attributeDidChange(Element* element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
{
ASSERT(element->customElementState() == Element::Upgraded);
- CustomElementCallbackScheduler::scheduleAttributeChangedCallback(definitionFor(element)->callbacks(), element, name, oldValue, newValue);
+ CustomElementScheduler::scheduleAttributeChangedCallback(element->customElementDefinition()->callbacks(), element, name, oldValue, newValue);
}
void CustomElement::didEnterDocument(Element* element, const Document& document)
@@ -124,7 +114,7 @@ void CustomElement::didEnterDocument(Element* element, const Document& document)
ASSERT(element->customElementState() == Element::Upgraded);
if (!document.domWindow())
return;
- CustomElementCallbackScheduler::scheduleAttachedCallback(definitionFor(element)->callbacks(), element);
+ CustomElementScheduler::scheduleCallback(element->customElementDefinition()->callbacks(), element, CustomElementLifecycleCallbacks::Attached);
}
void CustomElement::didLeaveDocument(Element* element, const Document& document)
@@ -132,7 +122,7 @@ void CustomElement::didLeaveDocument(Element* element, const Document& document)
ASSERT(element->customElementState() == Element::Upgraded);
if (!document.domWindow())
return;
- CustomElementCallbackScheduler::scheduleDetachedCallback(definitionFor(element)->callbacks(), element);
+ CustomElementScheduler::scheduleCallback(element->customElementDefinition()->callbacks(), element, CustomElementLifecycleCallbacks::Detached);
}
void CustomElement::wasDestroyed(Element* element)
@@ -144,23 +134,9 @@ void CustomElement::wasDestroyed(Element* element)
case Element::WaitingForUpgrade:
case Element::Upgraded:
- definitions().remove(element);
CustomElementObserver::notifyElementWasDestroyed(element);
break;
}
}
-void CustomElement::DefinitionMap::add(Element* element, PassRefPtr<CustomElementDefinition> definition)
-{
- ASSERT(definition.get());
- DefinitionMap::ElementDefinitionHashMap::AddResult result = m_definitions.add(element, definition);
- ASSERT_UNUSED(result, result.isNewEntry);
-}
-
-CustomElement::DefinitionMap& CustomElement::definitions()
-{
- DEFINE_STATIC_LOCAL(DefinitionMap, map, ());
- return map;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h
index c50bc0804e4..c9504eb7863 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElement.h
@@ -41,8 +41,10 @@
namespace WebCore {
+class CustomElementMicrotaskImportStep;
class Document;
class Element;
+class HTMLImportChild;
class CustomElement {
public:
@@ -54,15 +56,14 @@ public:
static bool isValidName(const AtomicString& name, NameSet validNames = AllNames);
static void addEmbedderCustomElementName(const AtomicString& name);
+ // API to notify of document-level changes
+ static CustomElementMicrotaskImportStep* didCreateImport(HTMLImportChild*);
+
// API for registration contexts
static void define(Element*, PassRefPtr<CustomElementDefinition>);
- // API for wrapper creation, which uses a definition as a key
- static CustomElementDefinition* definitionFor(Element*);
-
// API for Element to kick off changes
- static void didFinishParsingChildren(Element*);
static void attributeDidChange(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
static void didEnterDocument(Element*, const Document&);
static void didLeaveDocument(Element*, const Document&);
@@ -72,24 +73,6 @@ private:
CustomElement();
static Vector<AtomicString>& embedderCustomElementNames();
-
- // Maps resolved elements to their definitions
-
- class DefinitionMap {
- WTF_MAKE_NONCOPYABLE(DefinitionMap);
- public:
- DefinitionMap() { }
- ~DefinitionMap() { }
-
- void add(Element*, PassRefPtr<CustomElementDefinition>);
- void remove(Element* element) { m_definitions.remove(element); }
- CustomElementDefinition* get(Element* element) const { return m_definitions.get(element); }
-
- private:
- typedef HashMap<Element*, RefPtr<CustomElementDefinition> > ElementDefinitionHashMap;
- ElementDefinitionHashMap m_definitions;
- };
- static DefinitionMap& definitions();
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.cpp
new file mode 100644
index 00000000000..3fcf748a7fb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h"
+
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+
+namespace WebCore {
+
+void CustomElementAsyncImportMicrotaskQueue::enqueue(PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step)
+{
+ m_queue.append(step);
+}
+
+void CustomElementAsyncImportMicrotaskQueue::doDispatch()
+{
+ WillBeHeapVector<OwnPtrWillBeMember<CustomElementMicrotaskStep> > remaining;
+
+ for (unsigned i = 0; i < m_queue.size(); ++i) {
+ if (CustomElementMicrotaskStep::Processing == m_queue[i]->process())
+ remaining.append(m_queue[i].release());
+ }
+
+ m_queue.swap(remaining);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h
new file mode 100644
index 00000000000..e3845191020
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementAsyncImportMicrotaskQueue_h
+#define CustomElementAsyncImportMicrotaskQueue_h
+
+#include "core/dom/custom/CustomElementMicrotaskQueueBase.h"
+
+namespace WebCore {
+
+class CustomElementMicrotaskImportStep;
+
+class CustomElementAsyncImportMicrotaskQueue : public CustomElementMicrotaskQueueBase {
+public:
+ static PassRefPtrWillBeRawPtr<CustomElementAsyncImportMicrotaskQueue> create() { return adoptRefWillBeNoop(new CustomElementAsyncImportMicrotaskQueue()); }
+
+ void enqueue(PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep>);
+
+private:
+ CustomElementAsyncImportMicrotaskQueue() { }
+ virtual void doDispatch() OVERRIDE;
+};
+
+}
+
+#endif // CustomElementAsyncImportMicrotaskQueue_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.cpp
deleted file mode 100644
index 0e8561da12e..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/custom/CustomElementBaseElementQueue.h"
-
-#include "core/dom/custom/CustomElementCallbackDispatcher.h"
-#include "core/dom/custom/CustomElementCallbackQueue.h"
-
-namespace WebCore {
-
-void CustomElementBaseElementQueue::enqueue(CustomElementCallbackQueue* queue)
-{
- m_queue.append(queue);
-}
-
-bool CustomElementBaseElementQueue::dispatch(ElementQueue baseQueueId)
-{
- ASSERT(!m_inDispatch);
- m_inDispatch = true;
-
- bool didWork = m_queue.size();
-
- for (Vector<CustomElementCallbackQueue*>::iterator it = m_queue.begin(); it != m_queue.end(); ++it) {
- // The created callback may schedule entered document
- // callbacks.
- CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
- (*it)->processInElementQueue(baseQueueId);
- }
-
- m_queue.resize(0);
- m_inDispatch = 0;
-
- return didWork;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.h
deleted file mode 100644
index 78882aa3e0a..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementBaseElementQueue.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CustomElementBaseElementQueue_h
-#define CustomElementBaseElementQueue_h
-
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class CustomElementCallbackQueue;
-
-class CustomElementBaseElementQueue {
- WTF_MAKE_NONCOPYABLE(CustomElementBaseElementQueue);
-public:
- CustomElementBaseElementQueue() : m_inDispatch(false) { }
-
- bool isEmpty() const { return m_queue.isEmpty(); }
- void enqueue(CustomElementCallbackQueue*);
-
- typedef int ElementQueue;
- bool dispatch(ElementQueue baseQueueId);
-
-private:
- bool m_inDispatch;
- Vector<CustomElementCallbackQueue*> m_queue;
-};
-
-}
-
-#endif // CustomElementBaseElementQueue_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp
index 450af4ef301..5bd4866a076 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.cpp
@@ -32,7 +32,7 @@
#include "core/dom/custom/CustomElementCallbackDispatcher.h"
#include "core/dom/custom/CustomElementCallbackQueue.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
+#include "core/dom/custom/CustomElementScheduler.h"
#include "wtf/MainThread.h"
namespace WebCore {
@@ -48,17 +48,6 @@ CustomElementCallbackDispatcher& CustomElementCallbackDispatcher::instance()
return instance;
}
-bool CustomElementCallbackDispatcher::dispatch()
-{
- ASSERT(isMainThread());
- if (inCallbackDeliveryScope())
- return false;
-
- bool didWork = m_baseElementQueue.dispatch(baseElementQueue());
- CustomElementCallbackScheduler::clearElementCallbackQueueMap();
- return didWork;
-}
-
// Dispatches callbacks when popping the processing stack.
void CustomElementCallbackDispatcher::processElementQueueAndPop()
{
@@ -68,7 +57,7 @@ void CustomElementCallbackDispatcher::processElementQueueAndPop()
void CustomElementCallbackDispatcher::processElementQueueAndPop(size_t start, size_t end)
{
ASSERT(isMainThread());
- ElementQueue thisQueue = currentElementQueue();
+ CustomElementCallbackQueue::ElementQueueId thisQueue = currentElementQueue();
for (size_t i = start; i < end; i++) {
{
@@ -86,23 +75,21 @@ void CustomElementCallbackDispatcher::processElementQueueAndPop(size_t start, si
m_flattenedProcessingStack.resize(start);
s_elementQueueEnd = start;
- if (start == kNumSentinels && m_baseElementQueue.isEmpty())
- CustomElementCallbackScheduler::clearElementCallbackQueueMap();
+ if (s_elementQueueStart == kNumSentinels)
+ CustomElementScheduler::callbackDispatcherDidFinish();
}
void CustomElementCallbackDispatcher::enqueue(CustomElementCallbackQueue* callbackQueue)
{
+ ASSERT(inCallbackDeliveryScope());
+
if (callbackQueue->owner() == currentElementQueue())
return;
callbackQueue->setOwner(currentElementQueue());
- if (inCallbackDeliveryScope()) {
- m_flattenedProcessingStack.append(callbackQueue);
- ++s_elementQueueEnd;
- } else {
- m_baseElementQueue.enqueue(callbackQueue);
- }
+ m_flattenedProcessingStack.append(callbackQueue);
+ ++s_elementQueueEnd;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h
index 179219110c1..3e505c80600 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackDispatcher.h
@@ -31,19 +31,18 @@
#ifndef CustomElementCallbackDispatcher_h
#define CustomElementCallbackDispatcher_h
-#include "core/dom/custom/CustomElementBaseElementQueue.h"
+#include "core/dom/custom/CustomElementCallbackQueue.h"
#include "wtf/Vector.h"
namespace WebCore {
-class CustomElementCallbackQueue;
-class CustomElementCallbackScheduler;
+class CustomElementScheduler;
+// FIXME: Rename this CustomElementProcessingStack. It only handles
+// the processing stack.
class CustomElementCallbackDispatcher {
WTF_MAKE_NONCOPYABLE(CustomElementCallbackDispatcher);
public:
- static CustomElementCallbackDispatcher& instance();
-
// This is stack allocated in many DOM callbacks. Make it cheap.
class CallbackDeliveryScope {
public:
@@ -64,13 +63,11 @@ public:
size_t m_savedElementQueueStart;
};
- // Returns true if more work may have to be performed at the
- // checkpoint by this or other workers (for example, this work
- // invoked author scripts)
- bool dispatch();
+ static bool inCallbackDeliveryScope() { return s_elementQueueStart; }
protected:
- friend class CustomElementCallbackScheduler;
+ friend class CustomElementScheduler;
+ static CustomElementCallbackDispatcher& instance();
void enqueue(CustomElementCallbackQueue*);
private:
@@ -95,20 +92,11 @@ private:
// stack. A cache of instance().m_flattenedProcessingStack.size().
static size_t s_elementQueueEnd;
- static bool inCallbackDeliveryScope() { return s_elementQueueStart; }
-
- typedef int ElementQueue;
- static ElementQueue baseElementQueue() { return ElementQueue(0); }
- static ElementQueue currentElementQueue() { return ElementQueue(s_elementQueueStart); }
+ static CustomElementCallbackQueue::ElementQueueId currentElementQueue() { return CustomElementCallbackQueue::ElementQueueId(s_elementQueueStart); }
static void processElementQueueAndPop();
void processElementQueueAndPop(size_t start, size_t end);
- // The base element queue, used when no CallbackDeliveryScope is
- // active. Callbacks for elements created by the parser are
- // enqueued here.
- CustomElementBaseElementQueue m_baseElementQueue;
-
// The processing stack, flattened. Element queues lower in the
// stack appear toward the head of the vector. The first element
// is a null sentinel value.
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp
index e4fb331b654..a6e6e1b274b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.cpp
@@ -31,30 +31,12 @@
#include "config.h"
#include "core/dom/custom/CustomElementCallbackInvocation.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
+#include "core/dom/custom/CustomElementScheduler.h"
namespace WebCore {
-class CreatedInvocation : public CustomElementCallbackInvocation {
-public:
- CreatedInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
- : CustomElementCallbackInvocation(callbacks)
- {
- }
-
-private:
- virtual void dispatch(Element*) OVERRIDE;
- virtual bool isCreated() const OVERRIDE { return true; }
-};
-
-void CreatedInvocation::dispatch(Element* element)
-{
- if (element->inDocument() && element->document().domWindow())
- CustomElementCallbackScheduler::scheduleAttachedCallback(callbacks(), element);
- callbacks()->created(element);
-}
-
class AttachedDetachedInvocation : public CustomElementCallbackInvocation {
public:
AttachedDetachedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType which);
@@ -111,6 +93,25 @@ void AttributeChangedInvocation::dispatch(Element* element)
callbacks()->attributeChanged(element, m_name, m_oldValue, m_newValue);
}
+class CreatedInvocation : public CustomElementCallbackInvocation {
+public:
+ CreatedInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
+ : CustomElementCallbackInvocation(callbacks)
+ {
+ }
+
+private:
+ virtual void dispatch(Element*) OVERRIDE;
+ virtual bool isCreated() const OVERRIDE { return true; }
+};
+
+void CreatedInvocation::dispatch(Element* element)
+{
+ if (element->inDocument() && element->document().domWindow())
+ CustomElementScheduler::scheduleCallback(callbacks(), element, CustomElementLifecycleCallbacks::Attached);
+ callbacks()->created(element);
+}
+
PassOwnPtr<CustomElementCallbackInvocation> CustomElementCallbackInvocation::createInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, CustomElementLifecycleCallbacks::CallbackType which)
{
switch (which) {
@@ -120,7 +121,6 @@ PassOwnPtr<CustomElementCallbackInvocation> CustomElementCallbackInvocation::cre
case CustomElementLifecycleCallbacks::Attached:
case CustomElementLifecycleCallbacks::Detached:
return adoptPtr(new AttachedDetachedInvocation(callbacks, which));
-
default:
ASSERT_NOT_REACHED();
return PassOwnPtr<CustomElementCallbackInvocation>();
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
index 097e0918b08..615a3f4c382 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
@@ -32,6 +32,7 @@
#define CustomElementCallbackInvocation_h
#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
+#include "core/dom/custom/CustomElementProcessingStep.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -39,18 +40,12 @@
namespace WebCore {
-class Element;
-
-class CustomElementCallbackInvocation {
+class CustomElementCallbackInvocation : public CustomElementProcessingStep {
WTF_MAKE_NONCOPYABLE(CustomElementCallbackInvocation);
public:
static PassOwnPtr<CustomElementCallbackInvocation> createInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, CustomElementLifecycleCallbacks::CallbackType);
static PassOwnPtr<CustomElementCallbackInvocation> createAttributeChangedInvocation(PassRefPtr<CustomElementLifecycleCallbacks>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
- virtual ~CustomElementCallbackInvocation() { }
- virtual void dispatch(Element*) = 0;
- virtual bool isCreated() const { return false; }
-
protected:
CustomElementCallbackInvocation(PassRefPtr<CustomElementLifecycleCallbacks> callbacks)
: m_callbacks(callbacks)
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp
index 7da3b717550..d20bb901174 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.cpp
@@ -33,12 +33,12 @@
namespace WebCore {
-PassOwnPtr<CustomElementCallbackQueue> CustomElementCallbackQueue::create(PassRefPtr<Element> element)
+PassOwnPtrWillBeRawPtr<CustomElementCallbackQueue> CustomElementCallbackQueue::create(PassRefPtrWillBeRawPtr<Element> element)
{
- return adoptPtr(new CustomElementCallbackQueue(element));
+ return adoptPtrWillBeNoop(new CustomElementCallbackQueue(element));
}
-CustomElementCallbackQueue::CustomElementCallbackQueue(PassRefPtr<Element> element)
+CustomElementCallbackQueue::CustomElementCallbackQueue(PassRefPtrWillBeRawPtr<Element> element)
: m_element(element)
, m_owner(-1)
, m_index(0)
@@ -46,9 +46,10 @@ CustomElementCallbackQueue::CustomElementCallbackQueue(PassRefPtr<Element> eleme
{
}
-void CustomElementCallbackQueue::processInElementQueue(ElementQueue caller)
+bool CustomElementCallbackQueue::processInElementQueue(ElementQueueId caller)
{
ASSERT(!m_inCreatedCallback);
+ bool didWork = false;
while (m_index < m_queue.size() && owner() == caller) {
m_inCreatedCallback = m_queue[m_index]->isCreated();
@@ -58,6 +59,7 @@ void CustomElementCallbackQueue::processInElementQueue(ElementQueue caller)
// detects this recursion and cedes processing.
m_queue[m_index++]->dispatch(m_element.get());
m_inCreatedCallback = false;
+ didWork = true;
}
if (owner() == caller && m_index == m_queue.size()) {
@@ -66,6 +68,13 @@ void CustomElementCallbackQueue::processInElementQueue(ElementQueue caller)
m_queue.resize(0);
m_owner = -1;
}
+
+ return didWork;
+}
+
+void CustomElementCallbackQueue::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
index 269bfd29d4a..015f6ecc611 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
@@ -32,7 +32,9 @@
#define CustomElementCallbackQueue_h
#include "core/dom/Element.h"
-#include "core/dom/custom/CustomElementCallbackInvocation.h"
+#include "core/dom/custom/CustomElementProcessingStep.h"
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -40,14 +42,17 @@
namespace WebCore {
-class CustomElementCallbackQueue {
+// FIXME: Rename this because it contains resolution and upgrade as
+// well as callbacks.
+class CustomElementCallbackQueue : public NoBaseWillBeGarbageCollectedFinalized<CustomElementCallbackQueue> {
WTF_MAKE_NONCOPYABLE(CustomElementCallbackQueue);
public:
- static PassOwnPtr<CustomElementCallbackQueue> create(PassRefPtr<Element>);
+ static PassOwnPtrWillBeRawPtr<CustomElementCallbackQueue> create(PassRefPtrWillBeRawPtr<Element>);
- typedef int ElementQueue;
- ElementQueue owner() { return m_owner; }
- void setOwner(ElementQueue newOwner)
+ typedef int ElementQueueId;
+ ElementQueueId owner() const { return m_owner; }
+
+ void setOwner(ElementQueueId newOwner)
{
// ElementCallbackQueues only migrate towards the top of the
// processing stack.
@@ -55,16 +60,19 @@ public:
m_owner = newOwner;
}
- void append(PassOwnPtr<CustomElementCallbackInvocation> invocation) { m_queue.append(invocation); }
- void processInElementQueue(ElementQueue);
+ bool processInElementQueue(ElementQueueId);
+
+ void append(PassOwnPtr<CustomElementProcessingStep> invocation) { m_queue.append(invocation); }
bool inCreatedCallback() const { return m_inCreatedCallback; }
+ void trace(Visitor*);
+
private:
- CustomElementCallbackQueue(PassRefPtr<Element>);
+ explicit CustomElementCallbackQueue(PassRefPtrWillBeRawPtr<Element>);
- RefPtr<Element> m_element;
- Vector<OwnPtr<CustomElementCallbackInvocation> > m_queue;
- ElementQueue m_owner;
+ RefPtrWillBeMember<Element> m_element;
+ Vector<OwnPtr<CustomElementProcessingStep> > m_queue;
+ ElementQueueId m_owner;
size_t m_index;
bool m_inCreatedCallback;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.cpp
deleted file mode 100644
index fc3c90ca63d..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
-
-#include "core/dom/Element.h"
-#include "core/dom/custom/CustomElementCallbackDispatcher.h"
-#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
-
-namespace WebCore {
-
-void CustomElementCallbackScheduler::scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
-{
- if (!callbacks->hasAttributeChangedCallback())
- return;
-
- CustomElementCallbackQueue* queue = instance().schedule(element);
- queue->append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue));
-}
-
-void CustomElementCallbackScheduler::scheduleCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
-{
- if (!callbacks->hasCreatedCallback())
- return;
-
- CustomElementCallbackQueue* queue = instance().scheduleInCurrentElementQueue(element);
- queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Created));
-}
-
-void CustomElementCallbackScheduler::scheduleAttachedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
-{
- if (!callbacks->hasAttachedCallback())
- return;
-
- CustomElementCallbackQueue* queue = instance().schedule(element);
- queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Attached));
-}
-
-void CustomElementCallbackScheduler::scheduleDetachedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtr<Element> element)
-{
- if (!callbacks->hasDetachedCallback())
- return;
-
- CustomElementCallbackQueue* queue = instance().schedule(element);
- queue->append(CustomElementCallbackInvocation::createInvocation(callbacks, CustomElementLifecycleCallbacks::Detached));
-}
-
-CustomElementCallbackScheduler& CustomElementCallbackScheduler::instance()
-{
- DEFINE_STATIC_LOCAL(CustomElementCallbackScheduler, instance, ());
- return instance;
-}
-
-CustomElementCallbackQueue* CustomElementCallbackScheduler::ensureCallbackQueue(PassRefPtr<Element> element)
-{
- Element* key = element.get();
- ElementCallbackQueueMap::iterator it = m_elementCallbackQueueMap.find(key);
- if (it == m_elementCallbackQueueMap.end())
- it = m_elementCallbackQueueMap.add(key, CustomElementCallbackQueue::create(element)).iterator;
- return it->value.get();
-}
-
-void CustomElementCallbackScheduler::clearElementCallbackQueueMap()
-{
- ElementCallbackQueueMap emptyMap;
- instance().m_elementCallbackQueueMap.swap(emptyMap);
-}
-
-// Finds or creates the callback queue for element. If the
-// createdCallback has not finished running, the callback queue is not
-// moved to the top-of-stack. Otherwise like
-// scheduleInCurrentElementQueue.
-CustomElementCallbackQueue* CustomElementCallbackScheduler::schedule(PassRefPtr<Element> element)
-{
- CustomElementCallbackQueue* callbackQueue = ensureCallbackQueue(element);
- if (!callbackQueue->inCreatedCallback())
- CustomElementCallbackDispatcher::instance().enqueue(callbackQueue);
- return callbackQueue;
-}
-
-// Finds or creates the callback queue for element. If the element's
-// callback queue is scheduled in an earlier processing stack frame,
-// its owner is set to the element queue on the top of the processing
-// stack. Because callback queues are processed exhaustively, this
-// effectively moves the callback queue to the top of the stack.
-CustomElementCallbackQueue* CustomElementCallbackScheduler::scheduleInCurrentElementQueue(PassRefPtr<Element> element)
-{
- CustomElementCallbackQueue* callbackQueue = ensureCallbackQueue(element);
- CustomElementCallbackDispatcher::instance().enqueue(callbackQueue);
- return callbackQueue;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.h
deleted file mode 100644
index 741ede220bf..00000000000
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackScheduler.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CustomElementCallbackScheduler_h
-#define CustomElementCallbackScheduler_h
-
-#include "core/dom/custom/CustomElementCallbackQueue.h"
-#include "wtf/HashMap.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-class CustomElementLifecycleCallbacks;
-class Element;
-
-class CustomElementCallbackScheduler {
-public:
- static void scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
- static void scheduleCreatedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
- static void scheduleAttachedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
- static void scheduleDetachedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtr<Element>);
-
-protected:
- friend class CustomElementCallbackDispatcher;
- static void clearElementCallbackQueueMap();
-
-private:
- CustomElementCallbackScheduler() { }
-
- static CustomElementCallbackScheduler& instance();
-
- CustomElementCallbackQueue* ensureCallbackQueue(PassRefPtr<Element>);
- CustomElementCallbackQueue* schedule(PassRefPtr<Element>);
- CustomElementCallbackQueue* scheduleInCurrentElementQueue(PassRefPtr<Element>);
-
- typedef HashMap<Element*, OwnPtr<CustomElementCallbackQueue> > ElementCallbackQueueMap;
- ElementCallbackQueueMap m_elementCallbackQueueMap;
-};
-
-}
-
-#endif // CustomElementCallbackScheduler_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
index 72e4121ddbd..29b8ba6cbd1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
@@ -33,7 +33,6 @@
#include "core/dom/custom/CustomElementDescriptor.h"
#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
-#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h
index 7a3c6719bcc..5d3a36a8423 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementDescriptor.h
@@ -31,6 +31,7 @@
#ifndef CustomElementDescriptor_h
#define CustomElementDescriptor_h
+#include "platform/heap/Handle.h"
#include "wtf/HashTableDeletedValueType.h"
#include "wtf/text/AtomicString.h"
@@ -41,6 +42,7 @@ struct CustomElementDescriptorHash;
// A Custom Element descriptor is everything necessary to match a
// Custom Element instance to a definition.
class CustomElementDescriptor {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
CustomElementDescriptor(const AtomicString& type, const AtomicString& namespaceURI, const AtomicString& localName)
: m_type(type)
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp
index 331548af8b6..ddaf1fc4643 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementException.cpp
@@ -57,23 +57,23 @@ void CustomElementException::throwException(Reason reason, const AtomicString& t
return;
case ContextDestroyedCreatingCallbacks:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, preamble(type) + "The context is no longer valid.");
return;
case ContextDestroyedRegisteringDefinition:
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "The context is no longer valid.");
return;
case ExtendsIsInvalidName:
- exceptionState.throwDOMException(InvalidCharacterError, preamble(type) + "The tag name specified in 'extends' is not a valid tag name.");
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "The tag name specified in 'extends' is not a valid tag name.");
return;
case ExtendsIsCustomElementName:
- exceptionState.throwDOMException(InvalidCharacterError, preamble(type) + "The tag name specified in 'extends' is a custom element name. Use inheritance instead.");
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "The tag name specified in 'extends' is a custom element name. Use inheritance instead.");
return;
case InvalidName:
- exceptionState.throwDOMException(InvalidCharacterError, preamble(type) + "The type name is invalid.");
+ exceptionState.throwDOMException(SyntaxError, preamble(type) + "The type name is invalid.");
return;
case PrototypeInUse:
@@ -81,11 +81,11 @@ void CustomElementException::throwException(Reason reason, const AtomicString& t
return;
case PrototypeNotAnObject:
- exceptionState.throwDOMException(InvalidStateError, preamble(type) + "The prototype option is not an object.");
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "The prototype option is not an object.");
return;
case TypeAlreadyRegistered:
- exceptionState.throwDOMException(InvalidStateError, preamble(type) + "A type with that name is already registered.");
+ exceptionState.throwDOMException(NotSupportedError, preamble(type) + "A type with that name is already registered.");
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
index aa182e625d9..a713815e930 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
@@ -42,18 +42,6 @@ class CustomElementLifecycleCallbacks : public RefCounted<CustomElementLifecycle
public:
virtual ~CustomElementLifecycleCallbacks() { }
- bool hasCreatedCallback() const { return m_which & Created; }
- virtual void created(Element*) = 0;
-
- bool hasAttachedCallback() const { return m_which & Attached; }
- virtual void attached(Element*) = 0;
-
- bool hasDetachedCallback() const { return m_which & Detached; }
- virtual void detached(Element*) = 0;
-
- bool hasAttributeChangedCallback() const { return m_which & AttributeChanged; }
- virtual void attributeChanged(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) = 0;
-
enum CallbackType {
None = 0,
Created = 1 << 0,
@@ -62,6 +50,13 @@ public:
AttributeChanged = 1 << 3
};
+ bool hasCallback(CallbackType type) const { return m_which & type; }
+
+ virtual void created(Element*) = 0;
+ virtual void attached(Element*) = 0;
+ virtual void detached(Element*) = 0;
+ virtual void attributeChanged(Element*, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue) = 0;
+
protected:
CustomElementLifecycleCallbacks(CallbackType which) : m_which(which) { }
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp
new file mode 100644
index 00000000000..2adc2d15469
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp
@@ -0,0 +1,134 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
+
+#include "core/dom/Microtask.h"
+#include "core/dom/custom/CustomElementCallbackDispatcher.h"
+#include "core/dom/custom/CustomElementCallbackQueue.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+#include "core/dom/custom/CustomElementMicrotaskStepDispatcher.h"
+#include "core/dom/custom/CustomElementScheduler.h"
+#include "wtf/MainThread.h"
+
+namespace WebCore {
+
+static const CustomElementCallbackQueue::ElementQueueId kMicrotaskQueueId = 0;
+
+CustomElementMicrotaskDispatcher::CustomElementMicrotaskDispatcher()
+ : m_hasScheduledMicrotask(false)
+ , m_phase(Quiescent)
+ , m_steps(CustomElementMicrotaskStepDispatcher::create())
+{
+}
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementMicrotaskDispatcher)
+
+CustomElementMicrotaskDispatcher& CustomElementMicrotaskDispatcher::instance()
+{
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<CustomElementMicrotaskDispatcher>, instance, (adoptPtrWillBeNoop(new CustomElementMicrotaskDispatcher())));
+ return *instance;
+}
+
+void CustomElementMicrotaskDispatcher::enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep> step)
+{
+ ensureMicrotaskScheduledForMicrotaskSteps();
+ m_steps->enqueue(parentLoader, step);
+}
+
+void CustomElementMicrotaskDispatcher::enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step, bool importIsSync)
+{
+ ensureMicrotaskScheduledForMicrotaskSteps();
+ m_steps->enqueue(parentLoader, step, importIsSync);
+}
+
+void CustomElementMicrotaskDispatcher::enqueue(CustomElementCallbackQueue* queue)
+{
+ ensureMicrotaskScheduledForElementQueue();
+ queue->setOwner(kMicrotaskQueueId);
+ m_elements.append(queue);
+}
+
+void CustomElementMicrotaskDispatcher::importDidFinish(CustomElementMicrotaskImportStep* step)
+{
+ ensureMicrotaskScheduledForMicrotaskSteps();
+}
+
+void CustomElementMicrotaskDispatcher::ensureMicrotaskScheduledForMicrotaskSteps()
+{
+ ASSERT(m_phase == Quiescent || m_phase == DispatchingCallbacks);
+ ensureMicrotaskScheduled();
+}
+
+void CustomElementMicrotaskDispatcher::ensureMicrotaskScheduledForElementQueue()
+{
+ ASSERT(m_phase == Quiescent || m_phase == Resolving);
+ ensureMicrotaskScheduled();
+}
+
+void CustomElementMicrotaskDispatcher::ensureMicrotaskScheduled()
+{
+ if (!m_hasScheduledMicrotask) {
+ Microtask::enqueueMicrotask(WTF::bind(&dispatch));
+ m_hasScheduledMicrotask = true;
+ }
+}
+
+void CustomElementMicrotaskDispatcher::dispatch()
+{
+ instance().doDispatch();
+}
+
+void CustomElementMicrotaskDispatcher::doDispatch()
+{
+ ASSERT(isMainThread());
+
+ ASSERT(m_phase == Quiescent && m_hasScheduledMicrotask);
+ m_hasScheduledMicrotask = false;
+
+ // Finishing microtask work deletes all
+ // CustomElementCallbackQueues. Being in a callback delivery scope
+ // implies those queues could still be in use.
+ ASSERT_WITH_SECURITY_IMPLICATION(!CustomElementCallbackDispatcher::inCallbackDeliveryScope());
+
+ m_phase = Resolving;
+ m_steps->dispatch();
+
+ m_phase = DispatchingCallbacks;
+ for (WillBeHeapVector<RawPtrWillBeMember<CustomElementCallbackQueue> >::iterator it = m_elements.begin(); it != m_elements.end(); ++it) {
+ // Created callback may enqueue an attached callback.
+ CustomElementCallbackDispatcher::CallbackDeliveryScope scope;
+ (*it)->processInElementQueue(kMicrotaskQueueId);
+ }
+
+ m_elements.clear();
+ CustomElementScheduler::microtaskDispatcherDidFinish();
+ m_phase = Quiescent;
+}
+
+void CustomElementMicrotaskDispatcher::trace(Visitor* visitor)
+{
+ visitor->trace(m_steps);
+#if ENABLE(OILPAN)
+ visitor->trace(m_elements);
+#endif
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskDispatcher::show()
+{
+ m_steps->show(2);
+
+}
+#endif
+
+} // namespace WebCore
+
+#if !defined(NDEBUG)
+void showCEMD()
+{
+ WebCore::CustomElementMicrotaskDispatcher::instance().show();
+}
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h
new file mode 100644
index 00000000000..961074fd242
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h
@@ -0,0 +1,70 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementMicrotaskDispatcher_h
+#define CustomElementMicrotaskDispatcher_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CustomElementCallbackQueue;
+class CustomElementMicrotaskImportStep;
+class CustomElementMicrotaskStep;
+class CustomElementMicrotaskStepDispatcher;
+class HTMLImportLoader;
+
+class CustomElementMicrotaskDispatcher FINAL : public NoBaseWillBeGarbageCollected<CustomElementMicrotaskDispatcher> {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskDispatcher);
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementMicrotaskDispatcher);
+public:
+ static CustomElementMicrotaskDispatcher& instance();
+
+ void enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep>);
+ void enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep>, bool importIsSync);
+
+ void enqueue(CustomElementCallbackQueue*);
+
+
+ void importDidFinish(CustomElementMicrotaskImportStep*);
+
+ bool elementQueueIsEmpty() { return m_elements.isEmpty(); }
+
+ void trace(Visitor*);
+
+#if !defined(NDEBUG)
+ void show();
+#endif
+
+private:
+ CustomElementMicrotaskDispatcher();
+
+ void ensureMicrotaskScheduledForElementQueue();
+ void ensureMicrotaskScheduledForMicrotaskSteps();
+ void ensureMicrotaskScheduled();
+
+ static void dispatch();
+ void doDispatch();
+
+ bool m_hasScheduledMicrotask;
+ enum {
+ Quiescent,
+ Resolving,
+ DispatchingCallbacks
+ } m_phase;
+
+ RefPtrWillBeMember<CustomElementMicrotaskStepDispatcher> m_steps;
+ WillBeHeapVector<RawPtrWillBeMember<CustomElementCallbackQueue> > m_elements;
+};
+
+}
+
+#if !defined(NDEBUG)
+void showCEMD();
+#endif
+
+#endif // CustomElementMicrotaskDispatcher_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.cpp
new file mode 100644
index 00000000000..da48bb882eb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include <stdio.h>
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> CustomElementMicrotaskImportStep::create(HTMLImportChild* import)
+{
+ return adoptPtrWillBeNoop(new CustomElementMicrotaskImportStep(import));
+}
+
+CustomElementMicrotaskImportStep::CustomElementMicrotaskImportStep(HTMLImportChild* import)
+#if ENABLE(OILPAN)
+ : m_import(import)
+#else
+ : m_import(import->weakPtr())
+ , m_weakFactory(this)
+#endif
+ , m_queue(import->loader()->microtaskQueue())
+{
+}
+
+CustomElementMicrotaskImportStep::~CustomElementMicrotaskImportStep()
+{
+}
+
+void CustomElementMicrotaskImportStep::parentWasChanged()
+{
+ m_queue = CustomElementSyncMicrotaskQueue::create();
+ m_import.clear();
+}
+
+bool CustomElementMicrotaskImportStep::shouldWaitForImport() const
+{
+ return m_import && !m_import->loader()->isDone();
+}
+
+void CustomElementMicrotaskImportStep::didUpgradeAllCustomElements()
+{
+ ASSERT(m_queue);
+ if (m_import)
+ m_import->didFinishUpgradingCustomElements();
+}
+
+CustomElementMicrotaskStep::Result CustomElementMicrotaskImportStep::process()
+{
+ m_queue->dispatch();
+ if (!m_queue->isEmpty() || shouldWaitForImport())
+ return Processing;
+
+ didUpgradeAllCustomElements();
+ return FinishedProcessing;
+}
+
+void CustomElementMicrotaskImportStep::trace(Visitor* visitor)
+{
+ visitor->trace(m_import);
+ visitor->trace(m_queue);
+ CustomElementMicrotaskStep::trace(visitor);
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskImportStep::show(unsigned indent)
+{
+ fprintf(stderr, "%*sImport(wait=%d sync=%d, url=%s)\n", indent, "", shouldWaitForImport(), m_import && m_import->isSync(), m_import ? m_import->url().string().utf8().data() : "null");
+ m_queue->show(indent + 1);
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h
new file mode 100644
index 00000000000..e002356ad78
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementMicrotaskImportStep_h
+#define CustomElementMicrotaskImportStep_h
+
+#include "core/dom/custom/CustomElementMicrotaskStep.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/WeakPtr.h"
+
+namespace WebCore {
+
+class CustomElementSyncMicrotaskQueue;
+class HTMLImportChild;
+
+// Processes the Custom Elements in an HTML Import. This is a
+// composite step which processes the Custom Elements created by
+// parsing the import, and its sub-imports.
+//
+// This step blocks further Custom Element microtask processing if its
+// import isn't "ready" (finished parsing and running script.)
+class CustomElementMicrotaskImportStep : public CustomElementMicrotaskStep {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskImportStep);
+public:
+ static PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> create(HTMLImportChild*);
+ virtual ~CustomElementMicrotaskImportStep();
+
+ // API for HTML Imports
+ void parentWasChanged();
+ void importDidFinishLoading();
+#if !ENABLE(OILPAN)
+ WeakPtr<CustomElementMicrotaskImportStep> weakPtr() { return m_weakFactory.createWeakPtr(); }
+#endif
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit CustomElementMicrotaskImportStep(HTMLImportChild*);
+
+ void didUpgradeAllCustomElements();
+ bool shouldWaitForImport() const;
+
+ // CustomElementMicrotaskStep
+ virtual Result process() OVERRIDE FINAL;
+
+#if !defined(NDEBUG)
+ virtual void show(unsigned indent) OVERRIDE;
+#endif
+ WeakPtrWillBeWeakMember<HTMLImportChild> m_import;
+#if !ENABLE(OILPAN)
+ WeakPtrFactory<CustomElementMicrotaskImportStep> m_weakFactory;
+#endif
+ RefPtrWillBeMember<CustomElementSyncMicrotaskQueue> m_queue;
+};
+
+}
+
+#endif // CustomElementMicrotaskImportStep_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.cpp
new file mode 100644
index 00000000000..0495db605f8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.cpp
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskQueueBase.h"
+
+#include "core/dom/custom/CustomElementCallbackDispatcher.h"
+
+namespace WebCore {
+
+void CustomElementMicrotaskQueueBase::dispatch()
+{
+ ASSERT(!m_inDispatch);
+ m_inDispatch = true;
+ doDispatch();
+ m_inDispatch = false;
+}
+
+void CustomElementMicrotaskQueueBase::trace(Visitor* visitor)
+{
+ visitor->trace(m_queue);
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskQueueBase::show(unsigned indent)
+{
+ for (unsigned q = 0; q < m_queue.size(); ++q) {
+ if (m_queue[q])
+ m_queue[q]->show(indent);
+ else
+ fprintf(stderr, "%*snull\n", indent, "");
+ }
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h
new file mode 100644
index 00000000000..6520af12152
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementMicrotaskQueueBase_h
+#define CustomElementMicrotaskQueueBase_h
+
+#include "core/dom/custom/CustomElementMicrotaskStep.h"
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CustomElementMicrotaskQueueBase : public RefCountedWillBeGarbageCollectedFinalized<CustomElementMicrotaskQueueBase> {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskQueueBase);
+public:
+ virtual ~CustomElementMicrotaskQueueBase() { }
+
+ bool isEmpty() const { return m_queue.isEmpty(); }
+ void dispatch();
+
+ void trace(Visitor*);
+
+#if !defined(NDEBUG)
+ void show(unsigned indent);
+#endif
+
+protected:
+ CustomElementMicrotaskQueueBase() : m_inDispatch(false) { }
+ virtual void doDispatch() = 0;
+
+ WillBeHeapVector<OwnPtrWillBeMember<CustomElementMicrotaskStep> > m_queue;
+ bool m_inDispatch;
+};
+
+}
+
+#endif // CustomElementMicrotaskQueueBase_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.cpp
new file mode 100644
index 00000000000..7996219b539
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskResolutionStep.h"
+
+#include "core/dom/Element.h"
+#include "core/dom/custom/CustomElementRegistrationContext.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<CustomElementMicrotaskResolutionStep> CustomElementMicrotaskResolutionStep::create(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> context, PassRefPtrWillBeRawPtr<Element> element, const CustomElementDescriptor& descriptor)
+{
+ return adoptPtrWillBeNoop(new CustomElementMicrotaskResolutionStep(context, element, descriptor));
+}
+
+CustomElementMicrotaskResolutionStep::CustomElementMicrotaskResolutionStep(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> context, PassRefPtrWillBeRawPtr<Element> element, const CustomElementDescriptor& descriptor)
+ : m_context(context)
+ , m_element(element)
+ , m_descriptor(descriptor)
+{
+}
+
+CustomElementMicrotaskResolutionStep::~CustomElementMicrotaskResolutionStep()
+{
+}
+
+CustomElementMicrotaskStep::Result CustomElementMicrotaskResolutionStep::process()
+{
+ m_context->resolve(m_element.get(), m_descriptor);
+ return CustomElementMicrotaskStep::FinishedProcessing;
+}
+
+void CustomElementMicrotaskResolutionStep::trace(Visitor* visitor)
+{
+ visitor->trace(m_context);
+ visitor->trace(m_element);
+ CustomElementMicrotaskStep::trace(visitor);
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskResolutionStep::show(unsigned indent)
+{
+ fprintf(stderr, "%*sResolution: ", indent, "");
+ m_element->outerHTML().show();
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h
new file mode 100644
index 00000000000..c3f04874ea7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementMicrotaskResolutionStep_h
+#define CustomElementMicrotaskResolutionStep_h
+
+#include "core/dom/custom/CustomElementDescriptor.h"
+#include "core/dom/custom/CustomElementMicrotaskStep.h"
+#include "platform/heap/Handle.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class CustomElementRegistrationContext;
+class Element;
+
+class CustomElementMicrotaskResolutionStep : public CustomElementMicrotaskStep {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskResolutionStep);
+public:
+ static PassOwnPtrWillBeRawPtr<CustomElementMicrotaskResolutionStep> create(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext>, PassRefPtrWillBeRawPtr<Element>, const CustomElementDescriptor&);
+
+ virtual ~CustomElementMicrotaskResolutionStep();
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ CustomElementMicrotaskResolutionStep(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext>, PassRefPtrWillBeRawPtr<Element>, const CustomElementDescriptor&);
+
+ virtual Result process() OVERRIDE;
+
+#if !defined(NDEBUG)
+ virtual void show(unsigned indent) OVERRIDE;
+#endif
+
+ RefPtrWillBeMember<CustomElementRegistrationContext> m_context;
+ RefPtrWillBeMember<Element> m_element;
+ CustomElementDescriptor m_descriptor;
+};
+
+}
+
+#endif // CustomElementMicrotaskResolutionStep_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStep.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStep.h
new file mode 100644
index 00000000000..c4addd7f0c9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStep.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementMicrotaskStep_h
+#define CustomElementMicrotaskStep_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+
+namespace WebCore {
+
+class CustomElementMicrotaskStep : public NoBaseWillBeGarbageCollectedFinalized<CustomElementMicrotaskStep> {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskStep);
+public:
+ CustomElementMicrotaskStep() { }
+ virtual ~CustomElementMicrotaskStep() { }
+
+ enum Result {
+ Processing,
+ FinishedProcessing
+ };
+
+ virtual Result process() = 0;
+
+ virtual void trace(Visitor*) { }
+
+#if !defined(NDEBUG)
+ virtual void show(unsigned indent) = 0;
+#endif
+};
+
+}
+
+#endif // CustomElementMicrotaskStep_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.cpp
new file mode 100644
index 00000000000..bfddfe9aa7d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.cpp
@@ -0,0 +1,58 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/custom/CustomElementMicrotaskStepDispatcher.h"
+
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+#include "core/html/imports/HTMLImportLoader.h"
+
+namespace WebCore {
+
+CustomElementMicrotaskStepDispatcher::CustomElementMicrotaskStepDispatcher()
+ : m_syncQueue(CustomElementSyncMicrotaskQueue::create())
+ , m_asyncQueue(CustomElementAsyncImportMicrotaskQueue::create())
+{
+}
+
+void CustomElementMicrotaskStepDispatcher::enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep> step)
+{
+ if (parentLoader)
+ parentLoader->microtaskQueue()->enqueue(step);
+ else
+ m_syncQueue->enqueue(step);
+}
+
+void CustomElementMicrotaskStepDispatcher::enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step, bool importIsSync)
+{
+ if (importIsSync)
+ enqueue(parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep>(step));
+ else
+ m_asyncQueue->enqueue(step);
+}
+
+void CustomElementMicrotaskStepDispatcher::dispatch()
+{
+ m_syncQueue->dispatch();
+ if (m_syncQueue->isEmpty())
+ m_asyncQueue->dispatch();
+}
+
+void CustomElementMicrotaskStepDispatcher::trace(Visitor* visitor)
+{
+ visitor->trace(m_syncQueue);
+ visitor->trace(m_asyncQueue);
+}
+
+#if !defined(NDEBUG)
+void CustomElementMicrotaskStepDispatcher::show(unsigned indent)
+{
+ fprintf(stderr, "%*sSync:\n", indent, "");
+ m_syncQueue->show(indent + 1);
+ fprintf(stderr, "%*sAsync:\n", indent, "");
+ m_asyncQueue->show(indent + 1);
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.h
new file mode 100644
index 00000000000..6e715ed1b5a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskStepDispatcher.h
@@ -0,0 +1,40 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementMicrotaskStepDispatcher_h
+#define CustomElementMicrotaskStepDispatcher_h
+
+#include "core/dom/custom/CustomElementAsyncImportMicrotaskQueue.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class HTMLImportLoader;
+
+class CustomElementMicrotaskStepDispatcher : public RefCountedWillBeGarbageCollectedFinalized<CustomElementMicrotaskStepDispatcher> {
+ WTF_MAKE_NONCOPYABLE(CustomElementMicrotaskStepDispatcher);
+public:
+ static PassRefPtrWillBeRawPtr<CustomElementMicrotaskStepDispatcher> create() { return adoptRefWillBeNoop(new CustomElementMicrotaskStepDispatcher()); }
+
+ void enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep>);
+ void enqueue(HTMLImportLoader* parentLoader, PassOwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep>, bool importIsSync);
+
+ void dispatch();
+ void trace(Visitor*);
+
+#if !defined(NDEBUG)
+ void show(unsigned indent);
+#endif
+
+private:
+ CustomElementMicrotaskStepDispatcher();
+
+ RefPtrWillBeMember<CustomElementSyncMicrotaskQueue> m_syncQueue;
+ RefPtrWillBeMember<CustomElementAsyncImportMicrotaskQueue> m_asyncQueue;
+};
+
+}
+
+#endif // CustomElementMicrotaskStepDispatcher_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp
index 94247fccecc..9b537447f39 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.cpp
@@ -31,12 +31,18 @@
#include "config.h"
#include "core/dom/custom/CustomElementObserver.h"
+#include "core/dom/Element.h"
+
namespace WebCore {
-CustomElementObserver::ElementObserverMap& CustomElementObserver::elementObservers()
+// Maps elements to the observer watching them. At most one per
+// element at a time.
+typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Element>, RawPtrWillBeMember<CustomElementObserver> > ElementObserverMap;
+
+static ElementObserverMap& elementObservers()
{
- DEFINE_STATIC_LOCAL(ElementObserverMap, map, ());
- return map;
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<ElementObserverMap>, map, (adoptPtrWillBeNoop(new ElementObserverMap())));
+ return *map;
}
void CustomElementObserver::notifyElementDidFinishParsingChildren(Element* element)
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h
index ab7c57dcee8..6af62d5a6cb 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementObserver.h
@@ -31,15 +31,15 @@
#ifndef CustomElementObserver_h
#define CustomElementObserver_h
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
namespace WebCore {
class Element;
-class CustomElementObserver {
+class CustomElementObserver : public NoBaseWillBeGarbageCollectedFinalized<CustomElementObserver> {
public:
- CustomElementObserver() { }
virtual ~CustomElementObserver() { }
// API for CustomElement to kick off notifications
@@ -47,18 +47,16 @@ public:
static void notifyElementDidFinishParsingChildren(Element*);
static void notifyElementWasDestroyed(Element*);
+ virtual void trace(Visitor*) { }
+
protected:
+ CustomElementObserver() { }
+
void observe(Element*);
void unobserve(Element*);
virtual void elementDidFinishParsingChildren(Element*) = 0;
virtual void elementWasDestroyed(Element* element) { unobserve(element); }
-
-private:
- // Maps elements to the observer watching them. At most one per
- // element at a time.
- typedef HashMap<Element*, CustomElementObserver*> ElementObserverMap;
- static ElementObserverMap& elementObservers();
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementProcessingStep.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementProcessingStep.h
new file mode 100644
index 00000000000..c92451bae82
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementProcessingStep.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementProcessingStep_h
+#define CustomElementProcessingStep_h
+
+#include "wtf/Noncopyable.h"
+
+namespace WebCore {
+
+class Element;
+
+class CustomElementProcessingStep {
+ WTF_MAKE_NONCOPYABLE(CustomElementProcessingStep);
+public:
+ CustomElementProcessingStep() { }
+
+ virtual ~CustomElementProcessingStep() { }
+ virtual void dispatch(Element*) = 0;
+ virtual bool isCreated() const { return false; }
+};
+
+}
+
+#endif // CustomElementProcessingStep_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
index e248ab7cbf1..1c8898ad23c 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
@@ -31,13 +31,14 @@
#include "config.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/custom/CustomElement.h"
-#include "core/dom/custom/CustomElementCallbackScheduler.h"
#include "core/dom/custom/CustomElementDefinition.h"
+#include "core/dom/custom/CustomElementScheduler.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLUnknownElement.h"
#include "core/svg/SVGUnknownElement.h"
@@ -45,6 +46,11 @@
namespace WebCore {
+CustomElementRegistrationContext::CustomElementRegistrationContext()
+ : m_candidates(CustomElementUpgradeCandidateMap::create())
+{
+}
+
void CustomElementRegistrationContext::registerElement(Document* document, CustomElementConstructorBuilder* constructorBuilder, const AtomicString& type, CustomElement::NameSet validNames, ExceptionState& exceptionState)
{
CustomElementDefinition* definition = m_registry.registerElement(document, constructorBuilder, type, validNames, exceptionState);
@@ -53,16 +59,20 @@ void CustomElementRegistrationContext::registerElement(Document* document, Custo
return;
// Upgrade elements that were waiting for this definition.
- const CustomElementUpgradeCandidateMap::ElementSet& upgradeCandidates = m_candidates.takeUpgradeCandidatesFor(definition->descriptor());
- for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgradeCandidates.begin(); it != upgradeCandidates.end(); ++it)
- didResolveElement(definition, *it);
+ OwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap::ElementSet> upgradeCandidates = m_candidates->takeUpgradeCandidatesFor(definition->descriptor());
+
+ if (!upgradeCandidates)
+ return;
+
+ for (CustomElementUpgradeCandidateMap::ElementSet::const_iterator it = upgradeCandidates->begin(); it != upgradeCandidates->end(); ++it)
+ CustomElement::define(*it, definition);
}
-PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Document& document, const QualifiedName& tagName)
+PassRefPtrWillBeRawPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Document& document, const QualifiedName& tagName)
{
ASSERT(CustomElement::isValidName(tagName.localName()));
- RefPtr<Element> element;
+ RefPtrWillBeRawPtr<Element> element;
if (HTMLNames::xhtmlNamespaceURI == tagName.namespaceURI()) {
element = HTMLElement::create(tagName, document);
@@ -74,16 +84,16 @@ PassRefPtr<Element> CustomElementRegistrationContext::createCustomTagElement(Doc
}
element->setCustomElementState(Element::WaitingForUpgrade);
- resolve(element.get(), nullAtom);
+ resolveOrScheduleResolution(element.get(), nullAtom);
return element.release();
}
void CustomElementRegistrationContext::didGiveTypeExtension(Element* element, const AtomicString& type)
{
- resolve(element, type);
+ resolveOrScheduleResolution(element, type);
}
-void CustomElementRegistrationContext::resolve(Element* element, const AtomicString& typeExtension)
+void CustomElementRegistrationContext::resolveOrScheduleResolution(Element* element, const AtomicString& typeExtension)
{
// If an element has a custom tag name it takes precedence over
// the "is" attribute (if any).
@@ -93,27 +103,20 @@ void CustomElementRegistrationContext::resolve(Element* element, const AtomicStr
ASSERT(!type.isNull());
CustomElementDescriptor descriptor(type, element->namespaceURI(), element->localName());
- CustomElementDefinition* definition = m_registry.find(descriptor);
- if (definition)
- didResolveElement(definition, element);
- else
- didCreateUnresolvedElement(descriptor, element);
-}
-
-void CustomElementRegistrationContext::didResolveElement(CustomElementDefinition* definition, Element* element)
-{
- CustomElement::define(element, definition);
-}
-
-void CustomElementRegistrationContext::didCreateUnresolvedElement(const CustomElementDescriptor& descriptor, Element* element)
-{
ASSERT(element->customElementState() == Element::WaitingForUpgrade);
- m_candidates.add(descriptor, element);
+
+ CustomElementScheduler::resolveOrScheduleResolution(this, element, descriptor);
}
-PassRefPtr<CustomElementRegistrationContext> CustomElementRegistrationContext::create()
+void CustomElementRegistrationContext::resolve(Element* element, const CustomElementDescriptor& descriptor)
{
- return adoptRef(new CustomElementRegistrationContext());
+ CustomElementDefinition* definition = m_registry.find(descriptor);
+ if (definition) {
+ CustomElement::define(element, definition);
+ } else {
+ ASSERT(element->customElementState() == Element::WaitingForUpgrade);
+ m_candidates->add(descriptor, element);
+ }
}
void CustomElementRegistrationContext::setIsAttributeAndTypeExtension(Element* element, const AtomicString& type)
@@ -129,6 +132,10 @@ void CustomElementRegistrationContext::setTypeExtension(Element* element, const
if (!element->isHTMLElement() && !element->isSVGElement())
return;
+ CustomElementRegistrationContext* context = element->document().registrationContext();
+ if (!context)
+ return;
+
if (element->isCustomElement()) {
// This can happen if:
// 1. The element has a custom tag, which takes precedence over
@@ -141,10 +148,16 @@ void CustomElementRegistrationContext::setTypeExtension(Element* element, const
// Custom tags take precedence over type extensions
ASSERT(!CustomElement::isValidName(element->localName()));
+ if (!CustomElement::isValidName(type))
+ return;
+
element->setCustomElementState(Element::WaitingForUpgrade);
+ context->didGiveTypeExtension(element, type);
+}
- if (CustomElementRegistrationContext* context = element->document().registrationContext())
- context->didGiveTypeExtension(element, type);
+void CustomElementRegistrationContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_candidates);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
index 97dbc5fbfa7..6f8b9ff7151 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
@@ -35,7 +35,9 @@
#include "core/dom/custom/CustomElementDescriptor.h"
#include "core/dom/custom/CustomElementRegistry.h"
#include "core/dom/custom/CustomElementUpgradeCandidateMap.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/AtomicString.h"
@@ -47,34 +49,39 @@ class Document;
class Element;
class ExceptionState;
-class CustomElementRegistrationContext : public RefCounted<CustomElementRegistrationContext> {
+class CustomElementRegistrationContext FINAL : public RefCountedWillBeGarbageCollectedFinalized<CustomElementRegistrationContext> {
public:
- static PassRefPtr<CustomElementRegistrationContext> create();
+ static PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> create()
+ {
+ return adoptRefWillBeNoop(new CustomElementRegistrationContext());
+ }
~CustomElementRegistrationContext() { }
// Definitions
void registerElement(Document*, CustomElementConstructorBuilder*, const AtomicString& type, CustomElement::NameSet validNames, ExceptionState&);
- PassRefPtr<Element> createCustomTagElement(Document&, const QualifiedName&);
+ PassRefPtrWillBeRawPtr<Element> createCustomTagElement(Document&, const QualifiedName&);
static void setIsAttributeAndTypeExtension(Element*, const AtomicString& type);
static void setTypeExtension(Element*, const AtomicString& type);
+ void resolve(Element*, const CustomElementDescriptor&);
+
+ void trace(Visitor*);
+
protected:
- CustomElementRegistrationContext() { }
+ CustomElementRegistrationContext();
// Instance creation
void didGiveTypeExtension(Element*, const AtomicString& type);
private:
- void resolve(Element*, const AtomicString& typeExtension);
- void didResolveElement(CustomElementDefinition*, Element*);
- void didCreateUnresolvedElement(const CustomElementDescriptor&, Element*);
+ void resolveOrScheduleResolution(Element*, const AtomicString& typeExtension);
CustomElementRegistry m_registry;
// Element creation
- CustomElementUpgradeCandidateMap m_candidates;
+ OwnPtrWillBeMember<CustomElementUpgradeCandidateMap> m_candidates;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp
index b4bd6668dea..f5f3bf1d541 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "core/dom/custom/CustomElementRegistry.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/CustomElementConstructorBuilder.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/DocumentLifecycleObserver.h"
#include "core/dom/custom/CustomElementException.h"
#include "core/dom/custom/CustomElementRegistrationContext.h"
@@ -51,7 +51,12 @@ public:
bool registrationContextWentAway() { return m_wentAway; }
private:
+#if ENABLE(OILPAN)
+ // In oilpan we don't have the disposed phase for context lifecycle observer.
+ virtual void documentWasDetached() OVERRIDE { m_wentAway = true; }
+#else
virtual void documentWasDisposed() OVERRIDE { m_wentAway = true; }
+#endif
bool m_wentAway;
};
@@ -76,7 +81,7 @@ CustomElementDefinition* CustomElementRegistry::registerElement(Document* docume
return 0;
}
- QualifiedName tagName = nullQName();
+ QualifiedName tagName = QualifiedName::null();
if (!constructorBuilder->validateOptions(type, tagName, exceptionState))
return 0;
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.cpp
new file mode 100644
index 00000000000..0fd5203dba4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/custom/CustomElementScheduler.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/custom/CustomElementCallbackDispatcher.h"
+#include "core/dom/custom/CustomElementCallbackInvocation.h"
+#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+#include "core/dom/custom/CustomElementMicrotaskResolutionStep.h"
+#include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/html/imports/HTMLImportChild.h"
+
+namespace WebCore {
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementScheduler)
+
+void CustomElementScheduler::scheduleCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtrWillBeRawPtr<Element> element, CustomElementLifecycleCallbacks::CallbackType type)
+{
+ ASSERT(type != CustomElementLifecycleCallbacks::AttributeChanged);
+
+ if (!callbacks->hasCallback(type))
+ return;
+
+ CustomElementCallbackQueue& queue = instance().schedule(element);
+ queue.append(CustomElementCallbackInvocation::createInvocation(callbacks, type));
+}
+
+void CustomElementScheduler::scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks> callbacks, PassRefPtrWillBeRawPtr<Element> element, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue)
+{
+ if (!callbacks->hasCallback(CustomElementLifecycleCallbacks::AttributeChanged))
+ return;
+
+ CustomElementCallbackQueue& queue = instance().schedule(element);
+ queue.append(CustomElementCallbackInvocation::createAttributeChangedInvocation(callbacks, name, oldValue, newValue));
+}
+
+void CustomElementScheduler::resolveOrScheduleResolution(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext> context, PassRefPtrWillBeRawPtr<Element> element, const CustomElementDescriptor& descriptor)
+{
+ if (CustomElementCallbackDispatcher::inCallbackDeliveryScope()) {
+ context->resolve(element.get(), descriptor);
+ return;
+ }
+
+ HTMLImportLoader* loader = element->document().importLoader();
+ OwnPtrWillBeRawPtr<CustomElementMicrotaskResolutionStep> step = CustomElementMicrotaskResolutionStep::create(context, element, descriptor);
+ CustomElementMicrotaskDispatcher::instance().enqueue(loader, step.release());
+}
+
+CustomElementMicrotaskImportStep* CustomElementScheduler::scheduleImport(HTMLImportChild* import)
+{
+ ASSERT(!import->isDone());
+ ASSERT(import->parent());
+
+ // Ownership of the new step is transferred to the parent
+ // processing step, or the base queue.
+ OwnPtrWillBeRawPtr<CustomElementMicrotaskImportStep> step = CustomElementMicrotaskImportStep::create(import);
+ CustomElementMicrotaskImportStep* rawStep = step.get();
+ CustomElementMicrotaskDispatcher::instance().enqueue(import->parent()->loader(), step.release(), import->isSync());
+ return rawStep;
+}
+
+CustomElementScheduler& CustomElementScheduler::instance()
+{
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<CustomElementScheduler>, instance, (adoptPtrWillBeNoop (new CustomElementScheduler())));
+ return *instance;
+}
+
+CustomElementCallbackQueue& CustomElementScheduler::ensureCallbackQueue(PassRefPtrWillBeRawPtr<Element> element)
+{
+ ElementCallbackQueueMap::ValueType* it = m_elementCallbackQueueMap.add(element.get(), nullptr).storedValue;
+ if (!it->value)
+ it->value = CustomElementCallbackQueue::create(element);
+ return *it->value.get();
+}
+
+void CustomElementScheduler::callbackDispatcherDidFinish()
+{
+ if (CustomElementMicrotaskDispatcher::instance().elementQueueIsEmpty())
+ instance().clearElementCallbackQueueMap();
+}
+
+void CustomElementScheduler::microtaskDispatcherDidFinish()
+{
+ ASSERT(!CustomElementCallbackDispatcher::inCallbackDeliveryScope());
+ instance().clearElementCallbackQueueMap();
+}
+
+void CustomElementScheduler::clearElementCallbackQueueMap()
+{
+ ElementCallbackQueueMap emptyMap;
+ m_elementCallbackQueueMap.swap(emptyMap);
+}
+
+// Finds or creates the callback queue for element.
+CustomElementCallbackQueue& CustomElementScheduler::schedule(PassRefPtrWillBeRawPtr<Element> passElement)
+{
+ RefPtrWillBeRawPtr<Element> element(passElement);
+
+ CustomElementCallbackQueue& callbackQueue = ensureCallbackQueue(element);
+ if (callbackQueue.inCreatedCallback()) {
+ // Don't move it. Authors use the createdCallback like a
+ // constructor. By not moving it, the createdCallback
+ // completes before any other callbacks are entered for this
+ // element.
+ return callbackQueue;
+ }
+
+ if (CustomElementCallbackDispatcher::inCallbackDeliveryScope()) {
+ // The processing stack is active.
+ CustomElementCallbackDispatcher::instance().enqueue(&callbackQueue);
+ return callbackQueue;
+ }
+
+ CustomElementMicrotaskDispatcher::instance().enqueue(&callbackQueue);
+ return callbackQueue;
+}
+
+void CustomElementScheduler::trace(Visitor* visitor)
+{
+ visitor->trace(m_elementCallbackQueueMap);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h
new file mode 100644
index 00000000000..68c3dc9382f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CustomElementScheduler_h
+#define CustomElementScheduler_h
+
+#include "core/dom/custom/CustomElementCallbackQueue.h"
+#include "core/dom/custom/CustomElementLifecycleCallbacks.h"
+#include "platform/heap/Handle.h"
+#include "wtf/HashMap.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class CustomElementDescriptor;
+class CustomElementMicrotaskImportStep;
+class CustomElementRegistrationContext;
+class Element;
+class HTMLImportChild;
+
+class CustomElementScheduler FINAL : public NoBaseWillBeGarbageCollected<CustomElementScheduler> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CustomElementScheduler);
+public:
+
+ static void scheduleCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtrWillBeRawPtr<Element>, CustomElementLifecycleCallbacks::CallbackType);
+ static void scheduleAttributeChangedCallback(PassRefPtr<CustomElementLifecycleCallbacks>, PassRefPtrWillBeRawPtr<Element>, const AtomicString& name, const AtomicString& oldValue, const AtomicString& newValue);
+
+ static void resolveOrScheduleResolution(PassRefPtrWillBeRawPtr<CustomElementRegistrationContext>, PassRefPtrWillBeRawPtr<Element>, const CustomElementDescriptor&);
+ static CustomElementMicrotaskImportStep* scheduleImport(HTMLImportChild*);
+
+ static void microtaskDispatcherDidFinish();
+ static void callbackDispatcherDidFinish();
+
+ void trace(Visitor*);
+
+private:
+ CustomElementScheduler() { }
+
+ static CustomElementScheduler& instance();
+
+ CustomElementCallbackQueue& ensureCallbackQueue(PassRefPtrWillBeRawPtr<Element>);
+ CustomElementCallbackQueue& schedule(PassRefPtrWillBeRawPtr<Element>);
+
+ // FIXME: Consider moving the element's callback queue to
+ // ElementRareData. Then the scheduler can become completely
+ // static.
+ void clearElementCallbackQueueMap();
+
+ // The element -> callback queue map is populated by the scheduler
+ // and owns the lifetimes of the CustomElementCallbackQueues.
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<Element>, OwnPtrWillBeMember<CustomElementCallbackQueue> > ElementCallbackQueueMap;
+ ElementCallbackQueueMap m_elementCallbackQueueMap;
+};
+
+}
+
+#endif // CustomElementScheduler_h
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.cpp
new file mode 100644
index 00000000000..1fcd764e75d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.cpp
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+
+namespace WebCore {
+
+void CustomElementSyncMicrotaskQueue::enqueue(PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep> step)
+{
+ m_queue.append(step);
+}
+
+void CustomElementSyncMicrotaskQueue::doDispatch()
+{
+ unsigned i;
+
+ for (i = 0; i < m_queue.size(); ++i) {
+ if (CustomElementMicrotaskStep::Processing == m_queue[i]->process())
+ break;
+ }
+
+ m_queue.remove(0, i);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.h
new file mode 100644
index 00000000000..67bca95f642
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementSyncMicrotaskQueue.h
@@ -0,0 +1,25 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementSyncMicrotaskQueue_h
+#define CustomElementSyncMicrotaskQueue_h
+
+#include "core/dom/custom/CustomElementMicrotaskQueueBase.h"
+
+namespace WebCore {
+
+class CustomElementSyncMicrotaskQueue : public CustomElementMicrotaskQueueBase {
+public:
+ static PassRefPtrWillBeRawPtr<CustomElementSyncMicrotaskQueue> create() { return adoptRefWillBeNoop(new CustomElementSyncMicrotaskQueue()); }
+
+ void enqueue(PassOwnPtrWillBeRawPtr<CustomElementMicrotaskStep>);
+
+private:
+ CustomElementSyncMicrotaskQueue() { }
+ virtual void doDispatch();
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
index b7ea628bd48..998a6d5823b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.cpp
@@ -35,11 +35,20 @@
namespace WebCore {
+PassOwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap> CustomElementUpgradeCandidateMap::create()
+{
+ return adoptPtrWillBeNoop(new CustomElementUpgradeCandidateMap());
+}
+
CustomElementUpgradeCandidateMap::~CustomElementUpgradeCandidateMap()
{
+#if !ENABLE(OILPAN)
+ // With Oilpan enabled, the observer table keeps a weak reference to the
+ // element; no need for explicit removal.
UpgradeCandidateMap::const_iterator::Keys end = m_upgradeCandidates.end().keys();
for (UpgradeCandidateMap::const_iterator::Keys it = m_upgradeCandidates.begin().keys(); it != end; ++it)
unobserve(*it);
+#endif
}
void CustomElementUpgradeCandidateMap::add(const CustomElementDescriptor& descriptor, Element* element)
@@ -50,31 +59,23 @@ void CustomElementUpgradeCandidateMap::add(const CustomElementDescriptor& descri
ASSERT_UNUSED(result, result.isNewEntry);
UnresolvedDefinitionMap::iterator it = m_unresolvedDefinitions.find(descriptor);
+ ElementSet* elements;
if (it == m_unresolvedDefinitions.end())
- it = m_unresolvedDefinitions.add(descriptor, ElementSet()).iterator;
- it->value.add(element);
-}
-
-void CustomElementUpgradeCandidateMap::remove(Element* element)
-{
- unobserve(element);
- removeCommon(element);
+ elements = m_unresolvedDefinitions.add(descriptor, adoptPtrWillBeNoop(new ElementSet())).storedValue->value.get();
+ else
+ elements = it->value.get();
+ elements->add(element);
}
void CustomElementUpgradeCandidateMap::elementWasDestroyed(Element* element)
{
CustomElementObserver::elementWasDestroyed(element);
- removeCommon(element);
-}
-
-void CustomElementUpgradeCandidateMap::removeCommon(Element* element)
-{
UpgradeCandidateMap::iterator candidate = m_upgradeCandidates.find(element);
ASSERT_WITH_SECURITY_IMPLICATION(candidate != m_upgradeCandidates.end());
UnresolvedDefinitionMap::iterator elements = m_unresolvedDefinitions.find(candidate->value);
ASSERT_WITH_SECURITY_IMPLICATION(elements != m_unresolvedDefinitions.end());
- elements->value.remove(element);
+ elements->value->remove(element);
m_upgradeCandidates.remove(candidate);
}
@@ -92,19 +93,28 @@ void CustomElementUpgradeCandidateMap::moveToEnd(Element* element)
UnresolvedDefinitionMap::iterator elements = m_unresolvedDefinitions.find(candidate->value);
ASSERT_WITH_SECURITY_IMPLICATION(elements != m_unresolvedDefinitions.end());
- elements->value.appendOrMoveToLast(element);
+ elements->value->appendOrMoveToLast(element);
}
-ListHashSet<Element*> CustomElementUpgradeCandidateMap::takeUpgradeCandidatesFor(const CustomElementDescriptor& descriptor)
+PassOwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap::ElementSet> CustomElementUpgradeCandidateMap::takeUpgradeCandidatesFor(const CustomElementDescriptor& descriptor)
{
- const ListHashSet<Element*>& candidates = m_unresolvedDefinitions.take(descriptor);
+ OwnPtrWillBeRawPtr<ElementSet> candidates = m_unresolvedDefinitions.take(descriptor);
- for (ElementSet::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate) {
+ if (!candidates)
+ return nullptr;
+
+ for (ElementSet::const_iterator candidate = candidates->begin(); candidate != candidates->end(); ++candidate) {
unobserve(*candidate);
m_upgradeCandidates.remove(*candidate);
}
+ return candidates.release();
+}
- return candidates;
+void CustomElementUpgradeCandidateMap::trace(Visitor* visitor)
+{
+ visitor->trace(m_upgradeCandidates);
+ visitor->trace(m_unresolvedDefinitions);
+ CustomElementObserver::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h
index f68c50b65be..e92262eb6b9 100644
--- a/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h
+++ b/chromium/third_party/WebKit/Source/core/dom/custom/CustomElementUpgradeCandidateMap.h
@@ -35,38 +35,40 @@
#include "core/dom/custom/CustomElementDescriptorHash.h"
#include "core/dom/custom/CustomElementObserver.h"
#include "wtf/HashMap.h"
-#include "wtf/ListHashSet.h"
+#include "wtf/LinkedHashSet.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
class Element;
-class CustomElementUpgradeCandidateMap : CustomElementObserver {
+class CustomElementUpgradeCandidateMap FINAL : public CustomElementObserver {
WTF_MAKE_NONCOPYABLE(CustomElementUpgradeCandidateMap);
public:
- CustomElementUpgradeCandidateMap() { }
- ~CustomElementUpgradeCandidateMap();
+ static PassOwnPtrWillBeRawPtr<CustomElementUpgradeCandidateMap> create();
+ virtual ~CustomElementUpgradeCandidateMap();
// API for CustomElementRegistrationContext to save and take candidates
- typedef ListHashSet<Element*> ElementSet;
+ typedef WillBeHeapLinkedHashSet<RawPtrWillBeWeakMember<Element> > ElementSet;
void add(const CustomElementDescriptor&, Element*);
- void remove(Element*);
- ElementSet takeUpgradeCandidatesFor(const CustomElementDescriptor&);
+ PassOwnPtrWillBeRawPtr<ElementSet> takeUpgradeCandidatesFor(const CustomElementDescriptor&);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
+ CustomElementUpgradeCandidateMap() { }
+
virtual void elementWasDestroyed(Element*) OVERRIDE;
- void removeCommon(Element*);
virtual void elementDidFinishParsingChildren(Element*) OVERRIDE;
void moveToEnd(Element*);
- typedef HashMap<Element*, CustomElementDescriptor> UpgradeCandidateMap;
+ typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Element>, CustomElementDescriptor> UpgradeCandidateMap;
UpgradeCandidateMap m_upgradeCandidates;
- typedef HashMap<CustomElementDescriptor, ElementSet> UnresolvedDefinitionMap;
+ typedef WillBeHeapHashMap<CustomElementDescriptor, OwnPtrWillBeMember<ElementSet> > UnresolvedDefinitionMap;
UnresolvedDefinitionMap m_unresolvedDefinitions;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp
index 2a1561202fc..0ea969d8696 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.cpp
@@ -30,8 +30,7 @@
#include "core/dom/Element.h"
#include "core/dom/shadow/ElementShadow.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLShadowElement.h"
namespace WebCore {
@@ -73,7 +72,7 @@ Node* ComposedTreeWalker::traverseNode(const Node* node, TraversalDirection dire
const InsertionPoint* insertionPoint = toInsertionPoint(node);
if (Node* found = traverseDistributedNodes(direction == TraversalDirectionForward ? insertionPoint->first() : insertionPoint->last(), insertionPoint, direction))
return found;
- ASSERT(isHTMLShadowElement(node) || (isHTMLContentElement(node) && !node->hasChildNodes()));
+ ASSERT(isHTMLShadowElement(node) || (isHTMLContentElement(node) && !node->hasChildren()));
return 0;
}
@@ -140,14 +139,14 @@ Node* ComposedTreeWalker::traverseParent(const Node* node, ParentTraversalDetail
// The node is distributed. But the distribution was stopped at this insertion point.
if (shadowWhereNodeCanBeDistributed(*insertionPoint))
return 0;
- return traverseParentOrHost(insertionPoint, details);
+ return traverseParentOrHost(insertionPoint);
}
return 0;
}
- return traverseParentOrHost(node, details);
+ return traverseParentOrHost(node);
}
-inline Node* ComposedTreeWalker::traverseParentOrHost(const Node* node, ParentTraversalDetails* details) const
+inline Node* ComposedTreeWalker::traverseParentOrHost(const Node* node) const
{
Node* parent = node->parentNode();
if (!parent)
@@ -158,8 +157,6 @@ inline Node* ComposedTreeWalker::traverseParentOrHost(const Node* node, ParentTr
ASSERT(!shadowRoot->shadowInsertionPointOfYoungerShadowRoot());
if (!shadowRoot->isYoungest())
return 0;
- if (details)
- details->didTraverseShadowRoot(shadowRoot);
return shadowRoot->host();
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h
index b750e34c2a0..81cb1567d9b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ComposedTreeWalker.h
@@ -39,6 +39,7 @@ class ShadowRoot;
// FIXME: Make some functions inline to optimise the performance.
// https://bugs.webkit.org/show_bug.cgi?id=82702
class ComposedTreeWalker {
+ STACK_ALLOCATED();
public:
typedef NodeRenderingTraversal::ParentDetails ParentTraversalDetails;
@@ -49,7 +50,7 @@ public:
ComposedTreeWalker(const Node*, StartPolicy = CannotStartFromShadowBoundary);
- Node* get() const { return const_cast<Node*>(m_node); }
+ Node* get() const { return const_cast<Node*>(m_node.get()); }
void firstChild();
void lastChild();
@@ -107,9 +108,9 @@ private:
static Node* traverseBackToYoungerShadowRoot(const Node*, TraversalDirection);
- Node* traverseParentOrHost(const Node*, ParentTraversalDetails* = 0) const;
+ Node* traverseParentOrHost(const Node*) const;
- const Node* m_node;
+ RawPtrWillBeMember<const Node> m_node;
};
inline ComposedTreeWalker::ComposedTreeWalker(const Node* node, StartPolicy startPolicy)
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp
index a53ff57b81b..6b5bed5d153 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.cpp
@@ -37,7 +37,7 @@ void ContentDistribution::swap(ContentDistribution& other)
m_indices.swap(other.m_indices);
}
-void ContentDistribution::append(PassRefPtr<Node> node)
+void ContentDistribution::append(PassRefPtrWillBeRawPtr<Node> node)
{
ASSERT(node);
ASSERT(!isActiveInsertionPoint(*node));
@@ -48,7 +48,7 @@ void ContentDistribution::append(PassRefPtr<Node> node)
size_t ContentDistribution::find(const Node* node) const
{
- HashMap<const Node*, size_t>::const_iterator it = m_indices.find(node);
+ WillBeHeapHashMap<RawPtrWillBeMember<const Node>, size_t>::const_iterator it = m_indices.find(node);
if (it == m_indices.end())
return kNotFound;
@@ -71,4 +71,10 @@ Node* ContentDistribution::previousTo(const Node* node) const
return at(index - 1).get();
}
+void ContentDistribution::trace(Visitor* visitor)
+{
+ visitor->trace(m_nodes);
+ visitor->trace(m_indices);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h
index 65a221d9ea8..c3c7d707ae1 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ContentDistribution.h
@@ -32,24 +32,24 @@
#define ContentDistribution_h
#include "core/dom/Node.h"
-#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
namespace WebCore {
-class ContentDistribution {
+class ContentDistribution FINAL {
+ DISALLOW_ALLOCATION();
public:
ContentDistribution() { m_nodes.reserveInitialCapacity(32); }
- PassRefPtr<Node> first() const { return m_nodes.first(); }
- PassRefPtr<Node> last() const { return m_nodes.last(); }
- PassRefPtr<Node> at(size_t index) const { return m_nodes.at(index); }
+ PassRefPtrWillBeRawPtr<Node> first() const { return m_nodes.first(); }
+ PassRefPtrWillBeRawPtr<Node> last() const { return m_nodes.last(); }
+ PassRefPtrWillBeRawPtr<Node> at(size_t index) const { return m_nodes.at(index); }
size_t size() const { return m_nodes.size(); }
bool isEmpty() const { return m_nodes.isEmpty(); }
- void append(PassRefPtr<Node>);
+ void append(PassRefPtrWillBeRawPtr<Node>);
void clear() { m_nodes.clear(); m_indices.clear(); }
void shrinkToFit() { m_nodes.shrinkToFit(); }
@@ -60,11 +60,13 @@ public:
void swap(ContentDistribution& other);
- const Vector<RefPtr<Node> >& nodes() const { return m_nodes; }
+ const WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes() const { return m_nodes; }
+
+ void trace(Visitor*);
private:
- Vector<RefPtr<Node> > m_nodes;
- HashMap<const Node*, size_t> m_indices;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_nodes;
+ WillBeHeapHashMap<RawPtrWillBeMember<const Node>, size_t> m_indices;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
index 913bb93efc5..6e65a4962b0 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.cpp
@@ -27,16 +27,19 @@
#include "config.h"
#include "core/dom/shadow/ElementShadow.h"
+#include "core/css/StyleSheetList.h"
#include "core/dom/ContainerNodeAlgorithms.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/shadow/ContentDistribution.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLContentElement.h"
+#include "core/html/HTMLShadowElement.h"
+#include "core/inspector/InspectorInstrumentation.h"
namespace WebCore {
-class DistributionPool {
+class DistributionPool FINAL {
+ STACK_ALLOCATED();
public:
explicit DistributionPool(const ContainerNode&);
void clear();
@@ -46,7 +49,7 @@ public:
private:
void detachNonDistributedNodes();
- Vector<Node*, 32> m_nodes;
+ WillBeHeapVector<RawPtrWillBeMember<Node>, 32> m_nodes;
Vector<bool, 32> m_distributed;
};
@@ -86,7 +89,7 @@ void DistributionPool::distributeTo(InsertionPoint* insertionPoint, ElementShado
if (m_distributed[i])
continue;
- if (isHTMLContentElement(insertionPoint) && !toHTMLContentElement(insertionPoint)->canSelectNode(m_nodes, i))
+ if (isHTMLContentElement(*insertionPoint) && !toHTMLContentElement(insertionPoint)->canSelectNode(m_nodes, i))
continue;
Node* node = m_nodes[i];
@@ -120,41 +123,40 @@ inline void DistributionPool::detachNonDistributedNodes()
}
}
-PassOwnPtr<ElementShadow> ElementShadow::create()
+PassOwnPtrWillBeRawPtr<ElementShadow> ElementShadow::create()
{
- return adoptPtr(new ElementShadow());
+ return adoptPtrWillBeNoop(new ElementShadow());
}
ElementShadow::ElementShadow()
: m_needsDistributionRecalc(false)
- , m_applyAuthorStyles(false)
, m_needsSelectFeatureSet(false)
{
}
ElementShadow::~ElementShadow()
{
- removeAllShadowRoots();
+#if !ENABLE(OILPAN)
+ removeDetachedShadowRoots();
+#endif
}
ShadowRoot& ElementShadow::addShadowRoot(Element& shadowHost, ShadowRoot::ShadowRootType type)
{
- RefPtr<ShadowRoot> shadowRoot = ShadowRoot::create(&shadowHost.document(), type);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = ShadowRoot::create(shadowHost.document(), type);
+
+ if (type == ShadowRoot::AuthorShadowRoot && (!youngestShadowRoot() || youngestShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot))
+ shadowHost.willAddFirstAuthorShadowRoot();
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
root->lazyReattachIfAttached();
shadowRoot->setParentOrShadowHostNode(&shadowHost);
- shadowRoot->setParentTreeScope(&shadowHost.treeScope());
+ shadowRoot->setParentTreeScope(shadowHost.treeScope());
m_shadowRoots.push(shadowRoot.get());
- ChildNodeInsertionNotifier(shadowHost).notify(*shadowRoot);
+ shadowHost.notifyNodeInserted(*shadowRoot);
setNeedsDistributionRecalc();
- // addShadowRoot() affects apply-author-styles. However, we know that the youngest shadow root has not had any children yet.
- // The youngest shadow root's apply-author-styles is default (false). So we can just set m_applyAuthorStyles false.
- m_applyAuthorStyles = false;
-
- shadowHost.didAddShadowRoot(*shadowRoot);
InspectorInstrumentation::didPushShadowRoot(&shadowHost, shadowRoot.get());
ASSERT(m_shadowRoots.head());
@@ -162,23 +164,24 @@ ShadowRoot& ElementShadow::addShadowRoot(Element& shadowHost, ShadowRoot::Shadow
return *m_shadowRoots.head();
}
-void ElementShadow::removeAllShadowRoots()
+#if !ENABLE(OILPAN)
+void ElementShadow::removeDetachedShadowRoots()
{
// Dont protect this ref count.
Element* shadowHost = host();
ASSERT(shadowHost);
- while (RefPtr<ShadowRoot> oldRoot = m_shadowRoots.head()) {
+ while (RefPtrWillBeRawPtr<ShadowRoot> oldRoot = m_shadowRoots.head()) {
InspectorInstrumentation::willPopShadowRoot(shadowHost, oldRoot.get());
shadowHost->document().removeFocusedElementOfSubtree(oldRoot.get());
m_shadowRoots.removeHead();
oldRoot->setParentOrShadowHostNode(0);
- oldRoot->setParentTreeScope(&shadowHost->document());
+ oldRoot->setParentTreeScope(shadowHost->document());
oldRoot->setPrev(0);
oldRoot->setNext(0);
- ChildNodeRemovalNotifier(*shadowHost).notify(*oldRoot);
}
}
+#endif
void ElementShadow::attach(const Node::AttachContext& context)
{
@@ -200,14 +203,6 @@ void ElementShadow::detach(const Node::AttachContext& context)
root->detach(childrenContext);
}
-void ElementShadow::removeAllEventListeners()
-{
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
- for (Node* node = root; node; node = NodeTraversal::next(*node))
- node->removeAllEventListeners();
- }
-}
-
void ElementShadow::setNeedsDistributionRecalc()
{
if (m_needsDistributionRecalc)
@@ -217,80 +212,68 @@ void ElementShadow::setNeedsDistributionRecalc()
clearDistribution();
}
-bool ElementShadow::didAffectApplyAuthorStyles()
+bool ElementShadow::hasSameStyles(const ElementShadow* other) const
{
- bool applyAuthorStyles = resolveApplyAuthorStyles();
-
- if (m_applyAuthorStyles == applyAuthorStyles)
- return false;
+ ShadowRoot* root = youngestShadowRoot();
+ ShadowRoot* otherRoot = other->youngestShadowRoot();
+ while (root || otherRoot) {
+ if (!root || !otherRoot)
+ return false;
- m_applyAuthorStyles = applyAuthorStyles;
- return true;
-}
+ StyleSheetList* list = root->styleSheets();
+ StyleSheetList* otherList = otherRoot->styleSheets();
-bool ElementShadow::containsActiveStyles() const
-{
- for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
- if (root->hasScopedHTMLStyleChild())
- return true;
- if (!root->containsShadowElements())
+ if (list->length() != otherList->length())
return false;
- }
- return false;
-}
-bool ElementShadow::resolveApplyAuthorStyles() const
-{
- for (const ShadowRoot* shadowRoot = youngestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->olderShadowRoot()) {
- if (shadowRoot->applyAuthorStyles())
- return true;
- if (!shadowRoot->containsShadowElements())
- break;
+ for (size_t i = 0; i < list->length(); i++) {
+ if (toCSSStyleSheet(list->item(i))->contents() != toCSSStyleSheet(otherList->item(i))->contents())
+ return false;
+ }
+ root = root->olderShadowRoot();
+ otherRoot = otherRoot->olderShadowRoot();
}
- return false;
+
+ return true;
}
const InsertionPoint* ElementShadow::finalDestinationInsertionPointFor(const Node* key) const
{
+ ASSERT(key && !key->document().childNeedsDistributionRecalc());
NodeToDestinationInsertionPoints::const_iterator it = m_nodeToInsertionPoints.find(key);
return it == m_nodeToInsertionPoints.end() ? 0: it->value.last().get();
}
const DestinationInsertionPoints* ElementShadow::destinationInsertionPointsFor(const Node* key) const
{
+ ASSERT(key && !key->document().childNeedsDistributionRecalc());
NodeToDestinationInsertionPoints::const_iterator it = m_nodeToInsertionPoints.find(key);
return it == m_nodeToInsertionPoints.end() ? 0: &it->value;
}
void ElementShadow::distribute()
{
- host()->setNeedsStyleRecalc();
+ host()->setNeedsStyleRecalc(SubtreeStyleChange);
Vector<HTMLShadowElement*, 32> shadowInsertionPoints;
DistributionPool pool(*host());
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot()) {
HTMLShadowElement* shadowInsertionPoint = 0;
- const Vector<RefPtr<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints();
+ const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& insertionPoints = root->descendantInsertionPoints();
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* point = insertionPoints[i].get();
if (!point->isActive())
continue;
- if (isHTMLShadowElement(point)) {
- if (!shadowInsertionPoint)
- shadowInsertionPoint = toHTMLShadowElement(point);
+ if (isHTMLShadowElement(*point)) {
+ ASSERT(!shadowInsertionPoint);
+ shadowInsertionPoint = toHTMLShadowElement(point);
+ shadowInsertionPoints.append(shadowInsertionPoint);
} else {
pool.distributeTo(point, this);
if (ElementShadow* shadow = shadowWhereNodeCanBeDistributed(*point))
shadow->setNeedsDistributionRecalc();
}
}
- if (shadowInsertionPoint) {
- shadowInsertionPoints.append(shadowInsertionPoint);
- if (shadowInsertionPoint->hasChildNodes())
- pool.populateChildren(*shadowInsertionPoint);
- } else {
- pool.clear();
- }
}
for (size_t i = shadowInsertionPoints.size(); i > 0; --i) {
@@ -314,7 +297,7 @@ void ElementShadow::distribute()
void ElementShadow::didDistributeNode(const Node* node, InsertionPoint* insertionPoint)
{
NodeToDestinationInsertionPoints::AddResult result = m_nodeToInsertionPoints.add(node, DestinationInsertionPoints());
- result.iterator->value.append(insertionPoint);
+ result.storedValue->value.append(insertionPoint);
}
const SelectRuleFeatureSet& ElementShadow::ensureSelectFeatureSet()
@@ -337,12 +320,12 @@ void ElementShadow::collectSelectFeatureSetFrom(ShadowRoot& root)
for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(*element, &root)) {
if (ElementShadow* shadow = element->shadow())
m_selectFeatures.add(shadow->ensureSelectFeatureSet());
- if (!isHTMLContentElement(element))
+ if (!isHTMLContentElement(*element))
continue;
- const CSSSelectorList& list = toHTMLContentElement(element)->selectorList();
- for (const CSSSelector* selector = list.first(); selector; selector = CSSSelectorList::next(selector)) {
+ const CSSSelectorList& list = toHTMLContentElement(*element).selectorList();
+ for (const CSSSelector* selector = list.first(); selector; selector = CSSSelectorList::next(*selector)) {
for (const CSSSelector* component = selector; component; component = component->tagHistory())
- m_selectFeatures.collectFeaturesFromSelector(component);
+ m_selectFeatures.collectFeaturesFromSelector(*component);
}
}
}
@@ -368,7 +351,17 @@ void ElementShadow::clearDistribution()
m_nodeToInsertionPoints.clear();
for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
- root->setShadowInsertionPointOfYoungerShadowRoot(0);
+ root->setShadowInsertionPointOfYoungerShadowRoot(nullptr);
+}
+
+void ElementShadow::trace(Visitor* visitor)
+{
+ visitor->trace(m_nodeToInsertionPoints);
+ visitor->trace(m_selectFeatures);
+ // Shadow roots are linked with previous and next pointers which are traced.
+ // It is therefore enough to trace one of the shadow roots here and the
+ // rest will be traced from there.
+ visitor->trace(m_shadowRoots.head());
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
index 9017ddcafb7..870f89e2006 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
@@ -30,19 +30,19 @@
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/SelectRuleFeatureSet.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "platform/heap/Handle.h"
#include "wtf/DoublyLinkedList.h"
-#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
namespace WebCore {
-class ElementShadow {
- WTF_MAKE_NONCOPYABLE(ElementShadow); WTF_MAKE_FAST_ALLOCATED;
+class ElementShadow FINAL : public NoBaseWillBeGarbageCollectedFinalized<ElementShadow> {
+ WTF_MAKE_NONCOPYABLE(ElementShadow);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<ElementShadow> create();
+ static PassOwnPtrWillBeRawPtr<ElementShadow> create();
~ElementShadow();
Element* host() const;
@@ -52,15 +52,11 @@ public:
ShadowRoot& addShadowRoot(Element& shadowHost, ShadowRoot::ShadowRootType);
- bool applyAuthorStyles() const { return m_applyAuthorStyles; }
- bool didAffectApplyAuthorStyles();
- bool containsActiveStyles() const;
+ bool hasSameStyles(const ElementShadow*) const;
void attach(const Node::AttachContext&);
void detach(const Node::AttachContext&);
- void removeAllEventListeners();
-
void didAffectSelector(AffectedSelectorMask);
void willAffectSelector();
const SelectRuleFeatureSet& ensureSelectFeatureSet();
@@ -73,11 +69,14 @@ public:
void didDistributeNode(const Node*, InsertionPoint*);
+ void trace(Visitor*);
+
private:
ElementShadow();
- void removeAllShadowRoots();
- bool resolveApplyAuthorStyles() const;
+#if !ENABLE(OILPAN)
+ void removeDetachedShadowRoots();
+#endif
void distribute();
void clearDistribution();
@@ -88,13 +87,13 @@ private:
bool needsSelectFeatureSet() const { return m_needsSelectFeatureSet; }
void setNeedsSelectFeatureSet() { m_needsSelectFeatureSet = true; }
- typedef HashMap<const Node*, DestinationInsertionPoints> NodeToDestinationInsertionPoints;
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<const Node>, DestinationInsertionPoints> NodeToDestinationInsertionPoints;
NodeToDestinationInsertionPoints m_nodeToInsertionPoints;
SelectRuleFeatureSet m_selectFeatures;
+ // FIXME: Oilpan: add a heap-based version of DoublyLinkedList<>.
DoublyLinkedList<ShadowRoot> m_shadowRoots;
bool m_needsDistributionRecalc;
- bool m_applyAuthorStyles;
bool m_needsSelectFeatureSet;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp
index e3c5d4df9fc..e6b5b63bcf4 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.cpp
@@ -31,13 +31,11 @@
#include "config.h"
#include "core/dom/shadow/InsertionPoint.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/QualifiedName.h"
#include "core/dom/StaticNodeList.h"
#include "core/dom/shadow/ElementShadow.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
namespace WebCore {
@@ -100,7 +98,7 @@ void InsertionPoint::setDistribution(ContentDistribution& distribution)
void InsertionPoint::attach(const AttachContext& context)
{
// We need to attach the distribution here so that they're inserted in the right order
- // otherwise the n^2 protection inside NodeRenderingContext will cause them to be
+ // otherwise the n^2 protection inside RenderTreeBuilder will cause them to be
// inserted in the wrong place later. This also lets distributed nodes benefit from
// the n^2 protection.
for (size_t i = 0; i < m_distribution.size(); ++i) {
@@ -124,7 +122,7 @@ void InsertionPoint::willRecalcStyle(StyleRecalcChange change)
if (change < Inherit)
return;
for (size_t i = 0; i < m_distribution.size(); ++i)
- m_distribution.at(i)->setNeedsStyleRecalc(LocalStyleChange);
+ m_distribution.at(i)->setNeedsStyleRecalc(SubtreeStyleChange);
}
bool InsertionPoint::shouldUseFallbackElements() const
@@ -136,16 +134,9 @@ bool InsertionPoint::canBeActive() const
{
if (!isInShadowTree())
return false;
- bool foundShadowElementInAncestors = false;
- bool thisIsContentHTMLElement = isHTMLContentElement(this);
for (Node* node = parentNode(); node; node = node->parentNode()) {
- if (node->isInsertionPoint()) {
- // For HTMLContentElement, at most one HTMLShadowElement may appear in its ancestors.
- if (thisIsContentHTMLElement && isHTMLShadowElement(node) && !foundShadowElementInAncestors)
- foundShadowElementInAncestors = true;
- else
- return false;
- }
+ if (node->isInsertionPoint())
+ return false;
}
return true;
}
@@ -155,15 +146,16 @@ bool InsertionPoint::isActive() const
if (!canBeActive())
return false;
ShadowRoot* shadowRoot = containingShadowRoot();
- ASSERT(shadowRoot);
- if (!isHTMLShadowElement(this) || shadowRoot->descendantShadowElementCount() <= 1)
+ if (!shadowRoot)
+ return false;
+ if (!isHTMLShadowElement(*this) || shadowRoot->descendantShadowElementCount() <= 1)
return true;
// Slow path only when there are more than one shadow elements in a shadow tree. That should be a rare case.
- const Vector<RefPtr<InsertionPoint> >& insertionPoints = shadowRoot->descendantInsertionPoints();
+ const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& insertionPoints = shadowRoot->descendantInsertionPoints();
for (size_t i = 0; i < insertionPoints.size(); ++i) {
InsertionPoint* point = insertionPoints[i].get();
- if (isHTMLShadowElement(point))
+ if (isHTMLShadowElement(*point))
return point == this;
}
return true;
@@ -171,19 +163,19 @@ bool InsertionPoint::isActive() const
bool InsertionPoint::isShadowInsertionPoint() const
{
- return isHTMLShadowElement(this) && isActive();
+ return isHTMLShadowElement(*this) && isActive();
}
bool InsertionPoint::isContentInsertionPoint() const
{
- return isHTMLContentElement(this) && isActive();
+ return isHTMLContentElement(*this) && isActive();
}
-PassRefPtr<NodeList> InsertionPoint::getDistributedNodes()
+PassRefPtrWillBeRawPtr<StaticNodeList> InsertionPoint::getDistributedNodes()
{
document().updateDistributionForNodeIfNeeded(this);
- Vector<RefPtr<Node> > nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > nodes;
nodes.reserveInitialCapacity(m_distribution.size());
for (size_t i = 0; i < m_distribution.size(); ++i)
nodes.uncheckedAppend(m_distribution.at(i));
@@ -214,7 +206,6 @@ Node::InsertionNotificationRequest InsertionPoint::insertedInto(ContainerNode* i
if (canBeActive() && !m_registeredWithShadowRoot && insertionPoint->treeScope().rootNode() == root) {
m_registeredWithShadowRoot = true;
root->didAddInsertionPoint(this);
- rootOwner->didAffectApplyAuthorStyles();
if (canAffectSelector())
rootOwner->willAffectSelector();
}
@@ -246,7 +237,6 @@ void InsertionPoint::removedFrom(ContainerNode* insertionPoint)
m_registeredWithShadowRoot = false;
root->didRemoveInsertionPoint(this);
if (rootOwner) {
- rootOwner->didAffectApplyAuthorStyles();
if (canAffectSelector())
rootOwner->willAffectSelector();
}
@@ -255,24 +245,10 @@ void InsertionPoint::removedFrom(ContainerNode* insertionPoint)
HTMLElement::removedFrom(insertionPoint);
}
-void InsertionPoint::parseAttribute(const QualifiedName& name, const AtomicString& value)
-{
- if (name == reset_style_inheritanceAttr) {
- if (!inDocument() || !isActive())
- return;
- containingShadowRoot()->host()->setNeedsStyleRecalc();
- } else
- HTMLElement::parseAttribute(name, value);
-}
-
-bool InsertionPoint::resetStyleInheritance() const
-{
- return fastHasAttribute(reset_style_inheritanceAttr);
-}
-
-void InsertionPoint::setResetStyleInheritance(bool value)
+void InsertionPoint::trace(Visitor* visitor)
{
- setBooleanAttribute(reset_style_inheritanceAttr, value);
+ visitor->trace(m_distribution);
+ HTMLElement::trace(visitor);
}
const InsertionPoint* resolveReprojection(const Node* projectedNode)
@@ -296,7 +272,7 @@ const InsertionPoint* resolveReprojection(const Node* projectedNode)
return insertionPoint;
}
-void collectDestinationInsertionPoints(const Node& node, Vector<InsertionPoint*, 8>& results)
+void collectDestinationInsertionPoints(const Node& node, WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8>& results)
{
const Node* current = &node;
ElementShadow* lastElementShadow = 0;
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h b/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h
index 05f2ac9e070..43e0277261b 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/InsertionPoint.h
@@ -35,7 +35,6 @@
#include "core/dom/shadow/ContentDistribution.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLElement.h"
-#include "wtf/Forward.h"
namespace WebCore {
@@ -52,13 +51,10 @@ public:
bool isShadowInsertionPoint() const;
bool isContentInsertionPoint() const;
- PassRefPtr<NodeList> getDistributedNodes();
+ PassRefPtrWillBeRawPtr<StaticNodeList> getDistributedNodes();
virtual bool canAffectSelector() const { return false; }
- bool resetStyleInheritance() const;
- void setResetStyleInheritance(bool);
-
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
@@ -71,13 +67,14 @@ public:
Node* nextTo(const Node* node) const { return m_distribution.nextTo(node); }
Node* previousTo(const Node* node) const { return m_distribution.previousTo(node); }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
InsertionPoint(const QualifiedName&, Document&);
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
private:
@@ -85,9 +82,9 @@ private:
bool m_registeredWithShadowRoot;
};
-typedef Vector<RefPtr<InsertionPoint> > DestinationInsertionPoints;
+typedef WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> > DestinationInsertionPoints;
-DEFINE_NODE_TYPE_CASTS(InsertionPoint, isInsertionPoint());
+DEFINE_ELEMENT_TYPE_CASTS(InsertionPoint, isInsertionPoint());
inline bool isActiveInsertionPoint(const Node& node)
{
@@ -115,7 +112,7 @@ inline ElementShadow* shadowWhereNodeCanBeDistributed(const Node& node)
const InsertionPoint* resolveReprojection(const Node*);
-void collectDestinationInsertionPoints(const Node&, Vector<InsertionPoint*, 8>& results);
+void collectDestinationInsertionPoints(const Node&, WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8>& results);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp
index 4f6f52668ef..25757e6bc74 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.cpp
@@ -33,6 +33,8 @@
#include "core/css/CSSSelector.h"
+#include "wtf/BitVector.h"
+
namespace WebCore {
SelectRuleFeatureSet::SelectRuleFeatureSet()
@@ -52,11 +54,11 @@ void SelectRuleFeatureSet::clear()
m_featureFlags = 0;
}
-void SelectRuleFeatureSet::collectFeaturesFromSelector(const CSSSelector* selector)
+void SelectRuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector)
{
m_cssRuleFeatureSet.collectFeaturesFromSelector(selector);
- switch (selector->pseudoType()) {
+ switch (selector.pseudoType()) {
case CSSSelector::PseudoChecked:
setSelectRuleFeature(AffectedSelectorChecked);
break;
@@ -83,5 +85,53 @@ void SelectRuleFeatureSet::collectFeaturesFromSelector(const CSSSelector* select
}
}
+bool SelectRuleFeatureSet::checkSelectorsForClassChange(const SpaceSplitString& changedClasses) const
+{
+ unsigned changedSize = changedClasses.size();
+ for (unsigned i = 0; i < changedSize; ++i) {
+ if (hasSelectorForClass(changedClasses[i]))
+ return true;
+ }
+ return false;
+}
+
+bool SelectRuleFeatureSet::checkSelectorsForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses) const
+{
+ if (!oldClasses.size())
+ return checkSelectorsForClassChange(newClasses);
+
+ // Class vectors tend to be very short. This is faster than using a hash table.
+ BitVector remainingClassBits;
+ remainingClassBits.ensureSize(oldClasses.size());
+
+ for (unsigned i = 0; i < newClasses.size(); ++i) {
+ bool found = false;
+ for (unsigned j = 0; j < oldClasses.size(); ++j) {
+ if (newClasses[i] == oldClasses[j]) {
+ // Mark each class that is still in the newClasses so we can skip doing
+ // an n^2 search below when looking for removals. We can't break from
+ // this loop early since a class can appear more than once.
+ remainingClassBits.quickSet(j);
+ found = true;
+ }
+ }
+ // Class was added.
+ if (!found) {
+ if (hasSelectorForClass(newClasses[i]))
+ return true;
+ }
+ }
+
+ for (unsigned i = 0; i < oldClasses.size(); ++i) {
+ if (remainingClassBits.quickGet(i))
+ continue;
+
+ // Class was removed.
+ if (hasSelectorForClass(oldClasses[i]))
+ return true;
+ }
+ return false;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h b/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h
index 429d2777699..ad47b1b7e88 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/SelectRuleFeatureSet.h
@@ -36,13 +36,17 @@
namespace WebCore {
+class Element;
+class SpaceSplitString;
+
class SelectRuleFeatureSet {
+ DISALLOW_ALLOCATION();
public:
SelectRuleFeatureSet();
void add(const SelectRuleFeatureSet&);
void clear();
- void collectFeaturesFromSelector(const CSSSelector*);
+ void collectFeaturesFromSelector(const CSSSelector&);
bool hasSelectorForId(const AtomicString&) const;
bool hasSelectorForClass(const AtomicString&) const;
@@ -58,6 +62,11 @@ public:
bool hasSelectorFor(AffectedSelectorMask features) const { return m_featureFlags & features; }
+ bool checkSelectorsForClassChange(const SpaceSplitString& changedClasses) const;
+ bool checkSelectorsForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses) const;
+
+ void trace(Visitor* visitor) { visitor->trace(m_cssRuleFeatureSet); }
+
private:
void setSelectRuleFeature(AffectedSelectorType feature) { m_featureFlags |= feature; }
@@ -68,19 +77,19 @@ private:
inline bool SelectRuleFeatureSet::hasSelectorForId(const AtomicString& idValue) const
{
ASSERT(!idValue.isEmpty());
- return m_cssRuleFeatureSet.idsInRules.contains(idValue);
+ return m_cssRuleFeatureSet.hasSelectorForId(idValue);
}
inline bool SelectRuleFeatureSet::hasSelectorForClass(const AtomicString& classValue) const
{
ASSERT(!classValue.isEmpty());
- return m_cssRuleFeatureSet.classesInRules.contains(classValue);
+ return m_cssRuleFeatureSet.hasSelectorForClass(classValue);
}
inline bool SelectRuleFeatureSet::hasSelectorForAttribute(const AtomicString& attributeName) const
{
ASSERT(!attributeName.isEmpty());
- return m_cssRuleFeatureSet.attrsInRules.contains(attributeName);
+ return m_cssRuleFeatureSet.hasSelectorForAttribute(attributeName);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
index c9f7909eae3..60ad13145f7 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.cpp
@@ -30,6 +30,7 @@
#include "bindings/v8/ExceptionState.h"
#include "core/css/StyleSheetList.h"
#include "core/css/resolver/StyleResolver.h"
+#include "core/css/resolver/StyleResolverParentScope.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/StyleEngine.h"
#include "core/dom/Text.h"
@@ -37,6 +38,7 @@
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/ShadowRootRareData.h"
#include "core/editing/markup.h"
+#include "core/html/HTMLShadowElement.h"
#include "public/platform/Platform.h"
namespace WebCore {
@@ -48,42 +50,29 @@ struct SameSizeAsShadowRoot : public DocumentFragment, public TreeScope, public
COMPILE_ASSERT(sizeof(ShadowRoot) == sizeof(SameSizeAsShadowRoot), shadowroot_should_stay_small);
-enum ShadowRootUsageOriginType {
- ShadowRootUsageOriginWeb = 0,
- ShadowRootUsageOriginNotWeb,
- ShadowRootUsageOriginMax
-};
-
-ShadowRoot::ShadowRoot(Document* document, ShadowRootType type)
+ShadowRoot::ShadowRoot(Document& document, ShadowRootType type)
: DocumentFragment(0, CreateShadowRoot)
- , TreeScope(this, document)
- , m_prev(0)
- , m_next(0)
+ , TreeScope(*this, document)
+ , m_prev(nullptr)
+ , m_next(nullptr)
, m_numberOfStyles(0)
- , m_applyAuthorStyles(false)
- , m_resetStyleInheritance(false)
, m_type(type)
, m_registeredWithParentShadowRoot(false)
, m_descendantInsertionPointsIsValid(false)
{
- ASSERT(document);
ScriptWrappable::init(this);
-
- if (type == ShadowRoot::AuthorShadowRoot) {
- ShadowRootUsageOriginType usageType = document->url().protocolIsInHTTPFamily() ? ShadowRootUsageOriginWeb : ShadowRootUsageOriginNotWeb;
- blink::Platform::current()->histogramEnumeration("WebCore.ShadowRoot.constructor", usageType, ShadowRootUsageOriginMax);
- }
}
ShadowRoot::~ShadowRoot()
{
+#if !ENABLE(OILPAN)
ASSERT(!m_prev);
ASSERT(!m_next);
if (m_shadowRootRareData && m_shadowRootRareData->styleSheets())
m_shadowRootRareData->styleSheets()->detachFromDocument();
- documentInternal()->styleEngine()->didRemoveShadowRoot(this);
+ document().styleEngine()->didRemoveShadowRoot(this);
// We cannot let ContainerNode destructor call willBeDeletedFromDocument()
// for this ShadowRoot instance because TreeScope destructor
@@ -100,14 +89,17 @@ ShadowRoot::~ShadowRoot()
// as well as Node. See a comment on TreeScope.h for the reason.
if (hasRareData())
clearRareData();
+#endif
}
+#if !ENABLE(OILPAN)
void ShadowRoot::dispose()
{
removeDetachedChildren();
}
+#endif
-ShadowRoot* ShadowRoot::bindingsOlderShadowRoot() const
+ShadowRoot* ShadowRoot::olderShadowRootForBindings() const
{
ShadowRoot* older = olderShadowRoot();
while (older && !older->shouldExposeToBindings())
@@ -116,19 +108,10 @@ ShadowRoot* ShadowRoot::bindingsOlderShadowRoot() const
return older;
}
-bool ShadowRoot::isOldestAuthorShadowRoot() const
-{
- if (type() != AuthorShadowRoot)
- return false;
- if (ShadowRoot* older = olderShadowRoot())
- return older->type() == UserAgentShadowRoot;
- return true;
-}
-
-PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Node> ShadowRoot::cloneNode(bool, ExceptionState& exceptionState)
{
exceptionState.throwDOMException(DataCloneError, "ShadowRoot nodes are not clonable.");
- return 0;
+ return nullptr;
}
String ShadowRoot::innerHTML() const
@@ -143,35 +126,23 @@ void ShadowRoot::setInnerHTML(const String& markup, ExceptionState& exceptionSta
return;
}
- if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, "innerHTML", exceptionState))
+ if (RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, host(), AllowScriptingContent, "innerHTML", exceptionState))
replaceChildrenWithFragment(this, fragment.release(), exceptionState);
}
-bool ShadowRoot::childTypeAllowed(NodeType type) const
-{
- switch (type) {
- case ELEMENT_NODE:
- case PROCESSING_INSTRUCTION_NODE:
- case COMMENT_NODE:
- case TEXT_NODE:
- case CDATA_SECTION_NODE:
- return true;
- default:
- return false;
- }
-}
-
void ShadowRoot::recalcStyle(StyleRecalcChange change)
{
// ShadowRoot doesn't support custom callbacks.
ASSERT(!hasCustomStyleCallbacks());
- StyleResolver& styleResolver = document().ensureStyleResolver();
- styleResolver.pushParentShadowRoot(*this);
+ StyleResolverParentScope parentScope(*this);
if (styleChangeType() >= SubtreeStyleChange)
change = Force;
+ if (change < Force && hasRareData() && childNeedsStyleRecalc())
+ checkForChildrenAdjacentRuleChanges();
+
// There's no style to update so just calling recalcStyle means we're updated.
clearNeedsStyleRecalc();
@@ -182,73 +153,20 @@ void ShadowRoot::recalcStyle(StyleRecalcChange change)
toText(child)->recalcTextStyle(change, lastTextNode);
lastTextNode = toText(child);
} else if (child->isElementNode()) {
- if (shouldRecalcStyle(change, child))
+ if (child->shouldCallRecalcStyle(change))
toElement(child)->recalcStyle(change, lastTextNode);
if (child->renderer())
lastTextNode = 0;
}
}
- styleResolver.popParentShadowRoot(*this);
-
clearChildNeedsStyleRecalc();
}
-bool ShadowRoot::isActive() const
-{
- for (ShadowRoot* shadowRoot = youngerShadowRoot(); shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot())
- if (!shadowRoot->containsShadowElements())
- return false;
- return true;
-}
-
-void ShadowRoot::setApplyAuthorStyles(bool value)
-{
- if (isOrphan())
- return;
-
- if (applyAuthorStyles() == value)
- return;
-
- m_applyAuthorStyles = value;
- if (!isActive())
- return;
-
- ASSERT(host());
- ASSERT(host()->shadow());
- if (host()->shadow()->didAffectApplyAuthorStyles())
- host()->setNeedsStyleRecalc();
-
- // Since styles in shadow trees can select shadow hosts, set shadow host's needs-recalc flag true.
- // FIXME: host->setNeedsStyleRecalc() should take care of all elements in its shadow tree.
- // However, when host's recalcStyle is skipped (i.e. host's parent has no renderer),
- // no recalc style is invoked for any elements in its shadow tree.
- // This problem occurs when using getComputedStyle() API.
- // So currently host and shadow root's needsStyleRecalc flags are set to be true.
- setNeedsStyleRecalc();
-}
-
-void ShadowRoot::setResetStyleInheritance(bool value)
-{
- if (isOrphan())
- return;
-
- if (value == resetStyleInheritance())
- return;
-
- m_resetStyleInheritance = value;
- if (!isActive())
- return;
-
- setNeedsStyleRecalc();
-}
-
void ShadowRoot::attach(const AttachContext& context)
{
- StyleResolver& styleResolver = document().ensureStyleResolver();
- styleResolver.pushParentShadowRoot(*this);
+ StyleResolverParentScope parentScope(*this);
DocumentFragment::attach(context);
- styleResolver.popParentShadowRoot(*this);
}
Node::InsertionNotificationRequest ShadowRoot::insertedInto(ContainerNode* insertionPoint)
@@ -289,6 +207,9 @@ void ShadowRoot::removedFrom(ContainerNode* insertionPoint)
void ShadowRoot::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
ContainerNode::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
+
+ checkForSiblingStyleChanges(false, beforeChange, afterChange, childCountDelta);
+
if (InsertionPoint* point = shadowInsertionPointOfYoungerShadowRoot()) {
if (ShadowRoot* root = point->containingShadowRoot())
root->owner()->setNeedsDistributionRecalc();
@@ -298,14 +219,12 @@ void ShadowRoot::childrenChanged(bool changedByParser, Node* beforeChange, Node*
void ShadowRoot::registerScopedHTMLStyleChild()
{
++m_numberOfStyles;
- setHasScopedHTMLStyleChild(true);
}
void ShadowRoot::unregisterScopedHTMLStyleChild()
{
- ASSERT(hasScopedHTMLStyleChild() && m_numberOfStyles > 0);
+ ASSERT(m_numberOfStyles > 0);
--m_numberOfStyles;
- setHasScopedHTMLStyleChild(m_numberOfStyles > 0);
}
ShadowRootRareData* ShadowRoot::ensureShadowRootRareData()
@@ -313,7 +232,7 @@ ShadowRootRareData* ShadowRoot::ensureShadowRootRareData()
if (m_shadowRootRareData)
return m_shadowRootRareData.get();
- m_shadowRootRareData = adoptPtr(new ShadowRootRareData);
+ m_shadowRootRareData = adoptPtrWillBeNoop(new ShadowRootRareData);
return m_shadowRootRareData.get();
}
@@ -342,7 +261,7 @@ HTMLShadowElement* ShadowRoot::shadowInsertionPointOfYoungerShadowRoot() const
return m_shadowRootRareData ? m_shadowRootRareData->shadowInsertionPointOfYoungerShadowRoot() : 0;
}
-void ShadowRoot::setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement> shadowInsertionPoint)
+void ShadowRoot::setShadowInsertionPointOfYoungerShadowRoot(PassRefPtrWillBeRawPtr<HTMLShadowElement> shadowInsertionPoint)
{
if (!m_shadowRootRareData && !shadowInsertionPoint)
return;
@@ -385,10 +304,9 @@ void ShadowRoot::invalidateDescendantInsertionPoints()
m_shadowRootRareData->clearDescendantInsertionPoints();
}
-const Vector<RefPtr<InsertionPoint> >& ShadowRoot::descendantInsertionPoints()
+const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& ShadowRoot::descendantInsertionPoints()
{
- DEFINE_STATIC_LOCAL(const Vector<RefPtr<InsertionPoint> >, emptyList, ());
-
+ DEFINE_STATIC_LOCAL(WillBePersistentHeapVector<RefPtrWillBeMember<InsertionPoint> >, emptyList, ());
if (m_shadowRootRareData && m_descendantInsertionPointsIsValid)
return m_shadowRootRareData->descendantInsertionPoints();
@@ -397,7 +315,7 @@ const Vector<RefPtr<InsertionPoint> >& ShadowRoot::descendantInsertionPoints()
if (!containsInsertionPoints())
return emptyList;
- Vector<RefPtr<InsertionPoint> > insertionPoints;
+ WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> > insertionPoints;
for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element, this)) {
if (element->isInsertionPoint())
insertionPoints.append(toInsertionPoint(element));
@@ -416,4 +334,13 @@ StyleSheetList* ShadowRoot::styleSheets()
return m_shadowRootRareData->styleSheets();
}
+void ShadowRoot::trace(Visitor* visitor)
+{
+ visitor->trace(m_prev);
+ visitor->trace(m_next);
+ visitor->trace(m_shadowRootRareData);
+ TreeScope::trace(visitor);
+ DocumentFragment::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
index 62fd4238ad1..97d54a61074 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.h
@@ -43,6 +43,7 @@ class InsertionPoint;
class ShadowRootRareData;
class ShadowRoot FINAL : public DocumentFragment, public TreeScope, public DoublyLinkedListNode<ShadowRoot> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(ShadowRoot);
friend class WTF::DoublyLinkedListNode<ShadowRoot>;
public:
// FIXME: We will support multiple shadow subtrees, however current implementation does not work well
@@ -54,19 +55,23 @@ public:
AuthorShadowRoot
};
- static PassRefPtr<ShadowRoot> create(Document* document, ShadowRootType type)
+ static PassRefPtrWillBeRawPtr<ShadowRoot> create(Document& document, ShadowRootType type)
{
- return adoptRef(new ShadowRoot(document, type));
+ return adoptRefWillBeNoop(new ShadowRoot(document, type));
}
void recalcStyle(StyleRecalcChange);
+ // Disambiguate between Node and TreeScope hierarchies; TreeScope's implementation is simpler.
+ using TreeScope::document;
+ using TreeScope::getElementById;
+
Element* host() const { return toElement(parentOrShadowHostNode()); }
ElementShadow* owner() const { return host() ? host()->shadow() : 0; }
ShadowRoot* youngerShadowRoot() const { return prev(); }
- ShadowRoot* bindingsOlderShadowRoot() const;
+ ShadowRoot* olderShadowRootForBindings() const;
bool shouldExposeToBindings() const { return type() == AuthorShadowRoot; }
bool isYoungest() const { return !youngerShadowRoot(); }
@@ -78,8 +83,8 @@ public:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void registerScopedHTMLStyleChild() OVERRIDE;
- virtual void unregisterScopedHTMLStyleChild() OVERRIDE;
+ void registerScopedHTMLStyleChild();
+ void unregisterScopedHTMLStyleChild();
bool containsShadowElements() const;
bool containsContentElements() const;
@@ -90,41 +95,44 @@ public:
// For Internals, don't use this.
unsigned childShadowRootCount() const;
+ unsigned numberOfStyles() const { return m_numberOfStyles; }
HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const;
- void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement>);
+ void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtrWillBeRawPtr<HTMLShadowElement>);
void didAddInsertionPoint(InsertionPoint*);
void didRemoveInsertionPoint(InsertionPoint*);
- const Vector<RefPtr<InsertionPoint> >& descendantInsertionPoints();
+ const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& descendantInsertionPoints();
ShadowRootType type() const { return static_cast<ShadowRootType>(m_type); }
+ // Make protected methods from base class public here.
+ using TreeScope::setDocument;
+ using TreeScope::setParentTreeScope;
+
public:
Element* activeElement() const;
- bool applyAuthorStyles() const { return m_applyAuthorStyles; }
- void setApplyAuthorStyles(bool);
-
- bool resetStyleInheritance() const { return m_resetStyleInheritance; }
- void setResetStyleInheritance(bool);
-
ShadowRoot* olderShadowRoot() const { return next(); }
String innerHTML() const;
void setInnerHTML(const String&, ExceptionState&);
- PassRefPtr<Node> cloneNode(bool, ExceptionState&);
- PassRefPtr<Node> cloneNode(ExceptionState& exceptionState) { return cloneNode(true, exceptionState); }
+ PassRefPtrWillBeRawPtr<Node> cloneNode(bool, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Node> cloneNode(ExceptionState& exceptionState) { return cloneNode(true, exceptionState); }
StyleSheetList* styleSheets();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- ShadowRoot(Document*, ShadowRootType);
+ ShadowRoot(Document&, ShadowRootType);
virtual ~ShadowRoot();
+#if !ENABLE(OILPAN)
virtual void dispose() OVERRIDE;
- virtual bool childTypeAllowed(NodeType) const OVERRIDE;
+#endif
+
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
ShadowRootRareData* ensureShadowRootRareData();
@@ -134,18 +142,15 @@ private:
void invalidateDescendantInsertionPoints();
// ShadowRoots should never be cloned.
- virtual PassRefPtr<Node> cloneNode(bool) OVERRIDE { return 0; }
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool) OVERRIDE { return nullptr; }
// FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
bool isOrphan() const { return !host(); }
- bool isActive() const;
- ShadowRoot* m_prev;
- ShadowRoot* m_next;
- OwnPtr<ShadowRootRareData> m_shadowRootRareData;
+ RawPtrWillBeMember<ShadowRoot> m_prev;
+ RawPtrWillBeMember<ShadowRoot> m_next;
+ OwnPtrWillBeMember<ShadowRootRareData> m_shadowRootRareData;
unsigned m_numberOfStyles : 27;
- unsigned m_applyAuthorStyles : 1;
- unsigned m_resetStyleInheritance : 1;
unsigned m_type : 1;
unsigned m_registeredWithParentShadowRoot : 1;
unsigned m_descendantInsertionPointsIsValid : 1;
@@ -157,7 +162,7 @@ inline Element* ShadowRoot::activeElement() const
}
DEFINE_NODE_TYPE_CASTS(ShadowRoot, isShadowRoot());
-DEFINE_TYPE_CASTS(ShadowRoot, TreeScope, treeScope, treeScope->rootNode() && treeScope->rootNode()->isShadowRoot(), treeScope.rootNode() && treeScope.rootNode()->isShadowRoot());
+DEFINE_TYPE_CASTS(ShadowRoot, TreeScope, treeScope, treeScope->rootNode().isShadowRoot(), treeScope.rootNode().isShadowRoot());
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
index c84d177cba2..c7d26bb06b8 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRoot.idl
@@ -24,27 +24,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- NoInterfaceObject
-] interface ShadowRoot : DocumentFragment {
+interface ShadowRoot : DocumentFragment {
readonly attribute Element activeElement;
- attribute boolean applyAuthorStyles;
- attribute boolean resetStyleInheritance;
- [RuntimeEnabled=ShadowDOM, ImplementedAs=bindingsOlderShadowRoot] readonly attribute ShadowRoot olderShadowRoot;
- [TreatNullAs=NullString, CustomElementCallbacks, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds, RaisesException=Setter] attribute DOMString innerHTML;
+ [ImplementedAs=olderShadowRootForBindings] readonly attribute ShadowRoot olderShadowRoot;
+
+ [TreatNullAs=NullString, CustomElementCallbacks, LogActivity=SetterOnly, RaisesException=Setter] attribute DOMString innerHTML;
[RaisesException] Node cloneNode([Default=Undefined] optional boolean deep);
Selection getSelection();
Element getElementById([Default=Undefined] optional DOMString elementId);
- NodeList getElementsByClassName([Default=Undefined] optional DOMString className);
- NodeList getElementsByTagName([Default=Undefined] optional DOMString tagName);
- NodeList getElementsByTagNameNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
- [Default=Undefined] optional DOMString localName);
+ HTMLCollection getElementsByClassName([Default=Undefined] optional DOMString className);
+ HTMLCollection getElementsByTagName([Default=Undefined] optional DOMString tagName);
+ HTMLCollection getElementsByTagNameNS([TreatNullAs=NullString,Default=Undefined] optional DOMString namespaceURI,
+ [Default=Undefined] optional DOMString localName);
Element elementFromPoint([Default=Undefined] optional long x,
[Default=Undefined] optional long y);
- [RuntimeEnabled=ShadowDOM] readonly attribute StyleSheetList styleSheets;
- [RuntimeEnabled=ShadowDOM] readonly attribute Element host;
+ readonly attribute StyleSheetList styleSheets;
+ readonly attribute Element host;
};
diff --git a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
index dae72a7837c..abe5fbc5110 100644
--- a/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
+++ b/chromium/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
@@ -32,14 +32,12 @@
#define ShadowRootRareData_h
#include "core/dom/shadow/InsertionPoint.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
namespace WebCore {
-class ShadowRootRareData {
+class ShadowRootRareData : public NoBaseWillBeGarbageCollected<ShadowRootRareData> {
public:
ShadowRootRareData()
: m_descendantShadowElementCount(0)
@@ -49,7 +47,7 @@ public:
}
HTMLShadowElement* shadowInsertionPointOfYoungerShadowRoot() const { return m_shadowInsertionPointOfYoungerShadowRoot.get(); }
- void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtr<HTMLShadowElement> shadowInsertionPoint) { m_shadowInsertionPointOfYoungerShadowRoot = shadowInsertionPoint; }
+ void setShadowInsertionPointOfYoungerShadowRoot(PassRefPtrWillBeRawPtr<HTMLShadowElement> shadowInsertionPoint) { m_shadowInsertionPointOfYoungerShadowRoot = shadowInsertionPoint; }
void didAddInsertionPoint(InsertionPoint*);
void didRemoveInsertionPoint(InsertionPoint*);
@@ -65,27 +63,35 @@ public:
unsigned childShadowRootCount() const { return m_childShadowRootCount; }
- const Vector<RefPtr<InsertionPoint> >& descendantInsertionPoints() { return m_descendantInsertionPoints; }
- void setDescendantInsertionPoints(Vector<RefPtr<InsertionPoint> >& list) { m_descendantInsertionPoints.swap(list); }
+ const WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& descendantInsertionPoints() { return m_descendantInsertionPoints; }
+ void setDescendantInsertionPoints(WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> >& list) { m_descendantInsertionPoints.swap(list); }
void clearDescendantInsertionPoints() { m_descendantInsertionPoints.clear(); }
StyleSheetList* styleSheets() { return m_styleSheetList.get(); }
- void setStyleSheets(PassRefPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
+ void setStyleSheets(PassRefPtrWillBeRawPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_shadowInsertionPointOfYoungerShadowRoot);
+ visitor->trace(m_descendantInsertionPoints);
+ visitor->trace(m_styleSheetList);
+ }
private:
- RefPtr<HTMLShadowElement> m_shadowInsertionPointOfYoungerShadowRoot;
+ RefPtrWillBeMember<HTMLShadowElement> m_shadowInsertionPointOfYoungerShadowRoot;
unsigned m_descendantShadowElementCount;
unsigned m_descendantContentElementCount;
unsigned m_childShadowRootCount;
- Vector<RefPtr<InsertionPoint> > m_descendantInsertionPoints;
- RefPtr<StyleSheetList> m_styleSheetList;
+ WillBeHeapVector<RefPtrWillBeMember<InsertionPoint> > m_descendantInsertionPoints;
+ RefPtrWillBeMember<StyleSheetList> m_styleSheetList;
};
inline void ShadowRootRareData::didAddInsertionPoint(InsertionPoint* point)
{
- if (isHTMLShadowElement(point))
+ ASSERT(point);
+ if (isHTMLShadowElement(*point))
++m_descendantShadowElementCount;
- else if (isHTMLContentElement(point))
+ else if (isHTMLContentElement(*point))
++m_descendantContentElementCount;
else
ASSERT_NOT_REACHED();
@@ -93,9 +99,10 @@ inline void ShadowRootRareData::didAddInsertionPoint(InsertionPoint* point)
inline void ShadowRootRareData::didRemoveInsertionPoint(InsertionPoint* point)
{
- if (isHTMLShadowElement(point))
+ ASSERT(point);
+ if (isHTMLShadowElement(*point))
--m_descendantShadowElementCount;
- else if (isHTMLContentElement(point))
+ else if (isHTMLContentElement(*point))
--m_descendantContentElementCount;
else
ASSERT_NOT_REACHED();
diff --git a/chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.cpp
index 0120ec0aa95..c27886c0dd2 100644
--- a/chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-AppendNodeCommand::AppendNodeCommand(PassRefPtr<ContainerNode> parent, PassRefPtr<Node> node)
+AppendNodeCommand::AppendNodeCommand(PassRefPtrWillBeRawPtr<ContainerNode> parent, PassRefPtrWillBeRawPtr<Node> node)
: SimpleEditCommand(parent->document())
, m_parent(parent)
, m_node(node)
@@ -59,4 +59,11 @@ void AppendNodeCommand::doUnapply()
m_node->remove(IGNORE_EXCEPTION);
}
+void AppendNodeCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_parent);
+ visitor->trace(m_node);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.h b/chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.h
index 1f7a5aeb919..17a2d9d7188 100644
--- a/chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/AppendNodeCommand.h
@@ -30,21 +30,23 @@
namespace WebCore {
-class AppendNodeCommand : public SimpleEditCommand {
+class AppendNodeCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<AppendNodeCommand> create(PassRefPtr<ContainerNode> parent, PassRefPtr<Node> node)
+ static PassRefPtrWillBeRawPtr<AppendNodeCommand> create(PassRefPtrWillBeRawPtr<ContainerNode> parent, PassRefPtrWillBeRawPtr<Node> node)
{
- return adoptRef(new AppendNodeCommand(parent, node));
+ return adoptRefWillBeNoop(new AppendNodeCommand(parent, node));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- AppendNodeCommand(PassRefPtr<ContainerNode> parent, PassRefPtr<Node>);
+ AppendNodeCommand(PassRefPtrWillBeRawPtr<ContainerNode> parent, PassRefPtrWillBeRawPtr<Node>);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<ContainerNode> m_parent;
- RefPtr<Node> m_node;
+ RefPtrWillBeMember<ContainerNode> m_parent;
+ RefPtrWillBeMember<Node> m_node;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.cpp
index 7049dacad0c..abc857bdd64 100644
--- a/chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.cpp
@@ -27,8 +27,8 @@
#include "config.h"
#include "core/editing/ApplyBlockElementCommand.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/Text.h"
#include "core/editing/VisiblePosition.h"
@@ -73,17 +73,21 @@ void ApplyBlockElementCommand::doApply()
// FIXME: We paint the gap before some paragraphs that are indented with left
// margin/padding, but not others. We should make the gap painting more consistent and
// then use a left margin/padding rule here.
- if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd))
- setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(CannotCrossEditingBoundary), endingSelection().isDirectional()));
+ if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd)) {
+ VisibleSelection newSelection(visibleStart, visibleEnd.previous(CannotCrossEditingBoundary), endingSelection().isDirectional());
+ if (newSelection.isNone())
+ return;
+ setEndingSelection(newSelection);
+ }
VisibleSelection selection = selectionForParagraphIteration(endingSelection());
VisiblePosition startOfSelection = selection.visibleStart();
VisiblePosition endOfSelection = selection.visibleEnd();
ASSERT(!startOfSelection.isNull());
ASSERT(!endOfSelection.isNull());
- RefPtr<ContainerNode> startScope;
+ RefPtrWillBeRawPtr<ContainerNode> startScope = nullptr;
int startIndex = indexForVisiblePosition(startOfSelection, startScope);
- RefPtr<ContainerNode> endScope;
+ RefPtrWillBeRawPtr<ContainerNode> endScope = nullptr;
int endIndex = indexForVisiblePosition(endOfSelection, endScope);
formatSelection(startOfSelection, endOfSelection);
@@ -107,15 +111,15 @@ void ApplyBlockElementCommand::formatSelection(const VisiblePosition& startOfSel
// and there's nothing to move.
Position start = startOfSelection.deepEquivalent().downstream();
if (isAtUnsplittableElement(start)) {
- RefPtr<Element> blockquote = createBlockElement();
+ RefPtrWillBeRawPtr<Element> blockquote = createBlockElement();
insertNodeAt(blockquote, start);
- RefPtr<Element> placeholder = createBreakElement(document());
+ RefPtrWillBeRawPtr<Element> placeholder = createBreakElement(document());
appendNode(placeholder, blockquote);
setEndingSelection(VisibleSelection(positionBeforeNode(placeholder.get()), DOWNSTREAM, endingSelection().isDirectional()));
return;
}
- RefPtr<Element> blockquoteForNextIndent;
+ RefPtrWillBeRawPtr<Element> blockquoteForNextIndent = nullptr;
VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection);
VisiblePosition endOfLastParagraph = endOfParagraph(endOfSelection);
VisiblePosition endAfterSelection = endOfParagraph(endOfLastParagraph.next());
@@ -128,7 +132,7 @@ void ApplyBlockElementCommand::formatSelection(const VisiblePosition& startOfSel
atEnd = true;
rangeForParagraphSplittingTextNodesIfNeeded(endOfCurrentParagraph, start, end);
- endOfCurrentParagraph = end;
+ endOfCurrentParagraph = VisiblePosition(end);
Node* enclosingCell = enclosingNodeOfType(start, &isTableCell);
VisiblePosition endOfNextParagraph = endOfNextParagrahSplittingTextNodesIfNeeded(endOfCurrentParagraph, start, end);
@@ -138,7 +142,7 @@ void ApplyBlockElementCommand::formatSelection(const VisiblePosition& startOfSel
// Don't put the next paragraph in the blockquote we just created for this paragraph unless
// the next paragraph is in the same cell.
if (enclosingCell && enclosingCell != enclosingNodeOfType(endOfNextParagraph.deepEquivalent(), &isTableCell))
- blockquoteForNextIndent = 0;
+ blockquoteForNextIndent = nullptr;
// indentIntoBlockquote could move more than one paragraph if the paragraph
// is in a list item or a table. As a result, endAfterSelection could refer to a position
@@ -180,7 +184,7 @@ void ApplyBlockElementCommand::rangeForParagraphSplittingTextNodesIfNeeded(const
start = startOfParagraph(endOfCurrentParagraph).deepEquivalent();
end = endOfCurrentParagraph.deepEquivalent();
- document().updateStyleIfNeeded();
+ document().updateRenderTreeIfNeeded();
bool isStartAndEndOnSameNode = false;
if (RenderStyle* startStyle = renderStyleOfEnclosingTextNode(start)) {
@@ -189,7 +193,7 @@ void ApplyBlockElementCommand::rangeForParagraphSplittingTextNodesIfNeeded(const
// Avoid obtanining the start of next paragraph for start
if (startStyle->preserveNewline() && isNewLineAtPosition(start) && !isNewLineAtPosition(start.previous()) && start.offsetInContainerNode() > 0)
- start = startOfParagraph(end.previous()).deepEquivalent();
+ start = startOfParagraph(VisiblePosition(end.previous())).deepEquivalent();
// If start is in the middle of a text node, split.
if (!startStyle->collapseWhiteSpace() && start.offsetInContainerNode() > 0) {
@@ -208,7 +212,7 @@ void ApplyBlockElementCommand::rangeForParagraphSplittingTextNodesIfNeeded(const
}
}
- document().updateStyleIfNeeded();
+ document().updateRenderTreeIfNeeded();
if (RenderStyle* endStyle = renderStyleOfEnclosingTextNode(end)) {
bool isEndAndEndOfLastParagraphOnSameNode = renderStyleOfEnclosingTextNode(m_endOfLastParagraph) && end.deprecatedNode() == m_endOfLastParagraph.deprecatedNode();
@@ -223,7 +227,7 @@ void ApplyBlockElementCommand::rangeForParagraphSplittingTextNodesIfNeeded(const
// If end is in the middle of a text node, split.
if (!endStyle->collapseWhiteSpace() && end.offsetInContainerNode() && end.offsetInContainerNode() < end.containerNode()->maxCharacterOffset()) {
- RefPtr<Text> endContainer = end.containerText();
+ RefPtrWillBeRawPtr<Text> endContainer = end.containerText();
splitTextNode(endContainer, end.offsetInContainerNode());
if (isStartAndEndOnSameNode)
start = firstPositionInOrBeforeNode(endContainer->previousSibling());
@@ -246,7 +250,7 @@ VisiblePosition ApplyBlockElementCommand::endOfNextParagrahSplittingTextNodesIfN
if (!style)
return endOfNextParagraph;
- RefPtr<Text> text = position.containerText();
+ RefPtrWillBeRawPtr<Text> text = position.containerText();
if (!style->preserveNewline() || !position.offsetInContainerNode() || !isNewLineAtPosition(firstPositionInNode(text.get())))
return endOfNextParagraph;
@@ -273,15 +277,21 @@ VisiblePosition ApplyBlockElementCommand::endOfNextParagrahSplittingTextNodesIfN
m_endOfLastParagraph = Position(text.get(), m_endOfLastParagraph.offsetInContainerNode() - 1);
}
- return Position(text.get(), position.offsetInContainerNode() - 1);
+ return VisiblePosition(Position(text.get(), position.offsetInContainerNode() - 1));
}
-PassRefPtr<Element> ApplyBlockElementCommand::createBlockElement() const
+PassRefPtrWillBeRawPtr<Element> ApplyBlockElementCommand::createBlockElement() const
{
- RefPtr<Element> element = createHTMLElement(document(), m_tagName);
+ RefPtrWillBeRawPtr<Element> element = createHTMLElement(document(), m_tagName);
if (m_inlineStyle.length())
element->setAttribute(styleAttr, m_inlineStyle);
return element.release();
}
+void ApplyBlockElementCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_endOfLastParagraph);
+ CompositeEditCommand::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.h b/chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.h
index 72fdc915370..531dc1bd76b 100644
--- a/chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/ApplyBlockElementCommand.h
@@ -42,12 +42,14 @@ protected:
ApplyBlockElementCommand(Document&, const QualifiedName& tagName);
virtual void formatSelection(const VisiblePosition& startOfSelection, const VisiblePosition& endOfSelection);
- PassRefPtr<Element> createBlockElement() const;
+ PassRefPtrWillBeRawPtr<Element> createBlockElement() const;
const QualifiedName tagName() const { return m_tagName; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- virtual void doApply();
- virtual void formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtr<Element>&) = 0;
+ virtual void doApply() OVERRIDE FINAL;
+ virtual void formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtrWillBeRawPtr<Element>&) = 0;
void rangeForParagraphSplittingTextNodesIfNeeded(const VisiblePosition&, Position&, Position&);
VisiblePosition endOfNextParagrahSplittingTextNodesIfNeeded(VisiblePosition&, Position&, Position&);
diff --git a/chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.cpp
index 35fa0e67c8a..a5a5df35fac 100644
--- a/chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "core/editing/ApplyStyleCommand.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
@@ -43,8 +43,10 @@
#include "core/editing/TextIterator.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
+#include "core/frame/UseCounter.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderText.h"
+#include "platform/heap/Handle.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/StringBuilder.h"
@@ -64,7 +66,10 @@ bool isLegacyAppleStyleSpan(const Node *node)
return false;
const HTMLElement* elem = toHTMLElement(node);
- return elem->hasLocalName(spanAttr) && elem->getAttribute(classAttr) == styleSpanClassString();
+ if (!elem->hasLocalName(spanAttr) || elem->getAttribute(classAttr) != styleSpanClassString())
+ return false;
+ UseCounter::count(elem->document(), UseCounter::EditingAppleStyleSpanClass);
+ return true;
}
static bool hasNoAttributeOrOnlyStyleAttribute(const Element* element, ShouldStyleAttributeBeEmpty shouldStyleAttributeBeEmpty)
@@ -85,36 +90,34 @@ static bool hasNoAttributeOrOnlyStyleAttribute(const Element* element, ShouldSty
bool isStyleSpanOrSpanWithOnlyStyleAttribute(const Element* element)
{
- if (!element || !element->hasTagName(spanTag))
+ if (!isHTMLSpanElement(element))
return false;
return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), AllowNonEmptyStyleAttribute);
}
static inline bool isSpanWithoutAttributesOrUnstyledStyleSpan(const Node* node)
{
- if (!node || !node->isHTMLElement() || !node->hasTagName(spanTag))
+ if (!isHTMLSpanElement(node))
return false;
return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(node), StyleAttributeShouldBeEmpty);
}
bool isEmptyFontTag(const Element* element, ShouldStyleAttributeBeEmpty shouldStyleAttributeBeEmpty)
{
- if (!element || !element->hasTagName(fontTag))
+ if (!isHTMLFontElement(element))
return false;
return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), shouldStyleAttributeBeEmpty);
}
-static PassRefPtr<Element> createFontElement(Document& document)
+static PassRefPtrWillBeRawPtr<Element> createFontElement(Document& document)
{
- RefPtr<Element> fontNode = createHTMLElement(document, fontTag);
- return fontNode.release();
+ return createHTMLElement(document, fontTag);
}
-PassRefPtr<HTMLElement> createStyleSpanElement(Document& document)
+PassRefPtrWillBeRawPtr<HTMLElement> createStyleSpanElement(Document& document)
{
- RefPtr<HTMLElement> styleElement = createHTMLElement(document, spanTag);
- return styleElement.release();
+ return createHTMLElement(document, spanTag);
}
ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* style, EditAction editingAction, EPropertyLevel propertyLevel)
@@ -125,7 +128,7 @@ ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty
, m_start(endingSelection().start().downstream())
, m_end(endingSelection().end().upstream())
, m_useEndingSelection(true)
- , m_styledInlineElement(0)
+ , m_styledInlineElement(nullptr)
, m_removeOnly(false)
, m_isInlineElementToRemoveFunction(0)
{
@@ -139,13 +142,13 @@ ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty
, m_start(start)
, m_end(end)
, m_useEndingSelection(false)
- , m_styledInlineElement(0)
+ , m_styledInlineElement(nullptr)
, m_removeOnly(false)
, m_isInlineElementToRemoveFunction(0)
{
}
-ApplyStyleCommand::ApplyStyleCommand(PassRefPtr<Element> element, bool removeOnly, EditAction editingAction)
+ApplyStyleCommand::ApplyStyleCommand(PassRefPtrWillBeRawPtr<Element> element, bool removeOnly, EditAction editingAction)
: CompositeEditCommand(element->document())
, m_style(EditingStyle::create())
, m_editingAction(editingAction)
@@ -167,7 +170,7 @@ ApplyStyleCommand::ApplyStyleCommand(Document& document, const EditingStyle* sty
, m_start(endingSelection().start().downstream())
, m_end(endingSelection().end().upstream())
, m_useEndingSelection(true)
- , m_styledInlineElement(0)
+ , m_styledInlineElement(nullptr)
, m_removeOnly(true)
, m_isInlineElementToRemoveFunction(isInlineElementToRemoveFunction)
{
@@ -206,7 +209,7 @@ void ApplyStyleCommand::doApply()
switch (m_propertyLevel) {
case PropertyDefault: {
// Apply the block-centric properties of the style.
- RefPtr<EditingStyle> blockStyle = m_style->extractAndRemoveBlockProperties();
+ RefPtrWillBeRawPtr<EditingStyle> blockStyle = m_style->extractAndRemoveBlockProperties();
if (!blockStyle->isEmpty())
applyBlockStyle(blockStyle.get());
// Apply any remaining styles to the inline elements.
@@ -253,9 +256,9 @@ void ApplyStyleCommand::applyBlockStyle(EditingStyle *style)
// Save and restore the selection endpoints using their indices in the document, since
// addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints.
// Calculate start and end indices from the start of the tree that they're in.
- Node* scope = visibleStart.deepEquivalent().deprecatedNode()->highestAncestor();
- RefPtr<Range> startRange = Range::create(document(), firstPositionInNode(scope), visibleStart.deepEquivalent().parentAnchoredEquivalent());
- RefPtr<Range> endRange = Range::create(document(), firstPositionInNode(scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
+ Node& scope = visibleStart.deepEquivalent().deprecatedNode()->highestAncestorOrSelf();
+ RefPtrWillBeRawPtr<Range> startRange = Range::create(document(), firstPositionInNode(&scope), visibleStart.deepEquivalent().parentAnchoredEquivalent());
+ RefPtrWillBeRawPtr<Range> endRange = Range::create(document(), firstPositionInNode(&scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
int startIndex = TextIterator::rangeLength(startRange.get(), true);
int endIndex = TextIterator::rangeLength(endRange.get(), true);
@@ -265,9 +268,10 @@ void ApplyStyleCommand::applyBlockStyle(EditingStyle *style)
while (paragraphStart.isNotNull() && paragraphStart != beyondEnd) {
StyleChange styleChange(style, paragraphStart.deepEquivalent());
if (styleChange.cssStyle().length() || m_removeOnly) {
- RefPtr<Node> block = enclosingBlock(paragraphStart.deepEquivalent().deprecatedNode());
- if (!m_removeOnly) {
- RefPtr<Node> newBlock = moveParagraphContentsToNewBlockIfNecessary(paragraphStart.deepEquivalent());
+ RefPtrWillBeRawPtr<Node> block = enclosingBlock(paragraphStart.deepEquivalent().deprecatedNode());
+ const Position& paragraphStartToMove = paragraphStart.deepEquivalent();
+ if (!m_removeOnly && isEditablePosition(paragraphStartToMove)) {
+ RefPtrWillBeRawPtr<Element> newBlock = moveParagraphContentsToNewBlockIfNecessary(paragraphStartToMove);
if (newBlock)
block = newBlock;
}
@@ -286,13 +290,13 @@ void ApplyStyleCommand::applyBlockStyle(EditingStyle *style)
nextParagraphStart = endOfParagraph(paragraphStart).next();
}
- startRange = PlainTextRange(startIndex).createRangeForSelection(*toContainerNode(scope));
- endRange = PlainTextRange(endIndex).createRangeForSelection(*toContainerNode(scope));
+ startRange = PlainTextRange(startIndex).createRangeForSelection(toContainerNode(scope));
+ endRange = PlainTextRange(endIndex).createRangeForSelection(toContainerNode(scope));
if (startRange && endRange)
updateStartEnd(startRange->startPosition(), endRange->startPosition());
}
-static PassRefPtr<MutableStylePropertySet> copyStyleOrCreateEmpty(const StylePropertySet* style)
+static PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyStyleOrCreateEmpty(const StylePropertySet* style)
{
if (!style)
return MutableStylePropertySet::create();
@@ -349,7 +353,9 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style)
// Calculate loop end point.
// If the end node is before the start node (can only happen if the end node is
// an ancestor of the start node), we gather nodes up to the next sibling of the end node
- Node *beyondEnd;
+ Node* beyondEnd;
+ ASSERT(start.deprecatedNode());
+ ASSERT(end.deprecatedNode());
if (start.deprecatedNode()->isDescendantOf(end.deprecatedNode()))
beyondEnd = NodeTraversal::nextSkippingChildren(*end.deprecatedNode());
else
@@ -358,21 +364,30 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style)
start = start.upstream(); // Move upstream to ensure we do not add redundant spans.
Node* startNode = start.deprecatedNode();
ASSERT(startNode);
+
+ // Make sure we're not already at the end or the next NodeTraversal::next() will traverse
+ // past it.
+ if (startNode == beyondEnd)
+ return;
+
if (startNode->isTextNode() && start.deprecatedEditingOffset() >= caretMaxOffset(startNode)) // Move out of text node if range does not include its characters.
startNode = NodeTraversal::next(*startNode);
// Store away font size before making any changes to the document.
// This ensures that changes to one node won't effect another.
HashMap<Node*, float> startingFontSizes;
- for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(*node))
+ for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(*node)) {
+ ASSERT(node);
startingFontSizes.set(node, computedFontSize(node));
+ }
// These spans were added by us. If empty after font size changes, they can be removed.
- Vector<RefPtr<HTMLElement> > unstyledSpans;
+ WillBeHeapVector<RefPtrWillBeMember<HTMLElement> > unstyledSpans;
Node* lastStyledNode = 0;
for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(*node)) {
- RefPtr<HTMLElement> element;
+ ASSERT(node);
+ RefPtrWillBeRawPtr<HTMLElement> element = nullptr;
if (node->isHTMLElement()) {
// Only work on fully selected nodes.
if (!nodeFullySelected(node, start, end))
@@ -381,7 +396,7 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style)
} else if (node->isTextNode() && node->renderer() && node->parentNode() != lastStyledNode) {
// Last styled node was not parent node of this text node, but we wish to style this
// text node. To make this possible, add a style span to surround this text node.
- RefPtr<HTMLElement> span = createStyleSpanElement(document());
+ RefPtrWillBeRawPtr<HTMLElement> span = createStyleSpanElement(document());
surroundNodeRangeWithElement(node, node, span.get());
element = span.release();
} else {
@@ -390,10 +405,10 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style)
}
lastStyledNode = node;
- RefPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(element->inlineStyle());
+ RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(element->inlineStyle());
float currentFontSize = computedFontSize(node);
float desiredFontSize = max(MinimumFontSize, startingFontSizes.get(node) + style->fontSizeDelta());
- RefPtr<CSSValue> value = inlineStyle->getPropertyCSSValue(CSSPropertyFontSize);
+ RefPtrWillBeRawPtr<CSSValue> value = inlineStyle->getPropertyCSSValue(CSSPropertyFontSize);
if (value) {
element->removeInlineStyleProperty(CSSPropertyFontSize);
currentFontSize = computedFontSize(node);
@@ -414,7 +429,7 @@ void ApplyStyleCommand::applyRelativeFontStyleChange(EditingStyle* style)
removeNodePreservingChildren(unstyledSpans[i].get());
}
-static Node* dummySpanAncestorForNode(const Node* node)
+static ContainerNode* dummySpanAncestorForNode(const Node* node)
{
while (node && (!node->isElementNode() || !isStyleSpanOrSpanWithOnlyStyleAttribute(toElement(node))))
node = node->parentNode();
@@ -422,7 +437,7 @@ static Node* dummySpanAncestorForNode(const Node* node)
return node ? node->parentNode() : 0;
}
-void ApplyStyleCommand::cleanupUnstyledAppleStyleSpans(Node* dummySpanAncestor)
+void ApplyStyleCommand::cleanupUnstyledAppleStyleSpans(ContainerNode* dummySpanAncestor)
{
if (!dummySpanAncestor)
return;
@@ -478,11 +493,11 @@ HTMLElement* ApplyStyleCommand::splitAncestorsWithUnicodeBidi(Node* node, bool b
}
// Split every ancestor through highest ancestor with embedding.
- RefPtr<Node> currentNode = node;
+ RefPtrWillBeRawPtr<Node> currentNode = node;
while (currentNode) {
- RefPtr<Element> parent = toElement(currentNode->parentNode());
+ RefPtrWillBeRawPtr<Element> parent = toElement(currentNode->parentNode());
if (before ? currentNode->previousSibling() : currentNode->nextSibling())
- splitElement(parent, before ? currentNode : currentNode->nextSibling());
+ splitElement(parent, before ? currentNode.get() : currentNode->nextSibling());
if (parent == highestAncestorWithUnicodeBidi)
break;
currentNode = parent;
@@ -496,9 +511,7 @@ void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, Node* unsp
if (!block)
return;
- Node* parent = 0;
- for (Node* n = node->parentNode(); n != block && n != unsplitAncestor; n = parent) {
- parent = n->parentNode();
+ for (Node* n = node->parentNode(); n != block && n != unsplitAncestor; n = n->parentNode()) {
if (!n->isStyledElement())
continue;
@@ -516,7 +529,7 @@ void ApplyStyleCommand::removeEmbeddingUpToEnclosingBlock(Node* node, Node* unsp
// other attributes, like we (should) do with B and I elements.
removeNodeAttribute(element, dirAttr);
} else {
- RefPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(element->inlineStyle());
+ RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(element->inlineStyle());
inlineStyle->setProperty(CSSPropertyUnicodeBidi, CSSValueNormal);
inlineStyle->removeProperty(CSSPropertyDirection);
setNodeAttribute(element, styleAttr, AtomicString(inlineStyle->asText()));
@@ -538,8 +551,8 @@ static Node* highestEmbeddingAncestor(Node* startNode, Node* enclosingNode)
void ApplyStyleCommand::applyInlineStyle(EditingStyle* style)
{
- RefPtr<Node> startDummySpanAncestor = 0;
- RefPtr<Node> endDummySpanAncestor = 0;
+ RefPtrWillBeRawPtr<ContainerNode> startDummySpanAncestor = nullptr;
+ RefPtrWillBeRawPtr<ContainerNode> endDummySpanAncestor = nullptr;
// update document layout once before removing styles
// so that we avoid the expense of updating before each and every call
@@ -591,8 +604,8 @@ void ApplyStyleCommand::applyInlineStyle(EditingStyle* style)
Position removeStart = start.upstream();
WritingDirection textDirection = NaturalWritingDirection;
bool hasTextDirection = style->textDirection(textDirection);
- RefPtr<EditingStyle> styleWithoutEmbedding;
- RefPtr<EditingStyle> embeddingStyle;
+ RefPtrWillBeRawPtr<EditingStyle> styleWithoutEmbedding = nullptr;
+ RefPtrWillBeRawPtr<EditingStyle> embeddingStyle = nullptr;
if (hasTextDirection) {
// Leave alone an ancestor that provides the desired single level embedding, if there is one.
HTMLElement* startUnsplitAncestor = splitAncestorsWithUnicodeBidi(start.deprecatedNode(), true, textDirection);
@@ -603,11 +616,11 @@ void ApplyStyleCommand::applyInlineStyle(EditingStyle* style)
// Avoid removing the dir attribute and the unicode-bidi and direction properties from the unsplit ancestors.
Position embeddingRemoveStart = removeStart;
if (startUnsplitAncestor && nodeFullySelected(startUnsplitAncestor, removeStart, end))
- embeddingRemoveStart = positionInParentAfterNode(startUnsplitAncestor);
+ embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncestor);
Position embeddingRemoveEnd = end;
if (endUnsplitAncestor && nodeFullySelected(endUnsplitAncestor, removeStart, end))
- embeddingRemoveEnd = positionInParentBeforeNode(endUnsplitAncestor).downstream();
+ embeddingRemoveEnd = positionInParentBeforeNode(*endUnsplitAncestor).downstream();
if (embeddingRemoveEnd != removeStart || embeddingRemoveEnd != end) {
styleWithoutEmbedding = style->copy();
@@ -640,15 +653,15 @@ void ApplyStyleCommand::applyInlineStyle(EditingStyle* style)
// to check a computed style
document().updateLayoutIgnorePendingStylesheets();
- RefPtr<EditingStyle> styleToApply = style;
+ RefPtrWillBeRawPtr<EditingStyle> styleToApply = style;
if (hasTextDirection) {
// Avoid applying the unicode-bidi and direction properties beneath ancestors that already have them.
Node* embeddingStartNode = highestEmbeddingAncestor(start.deprecatedNode(), enclosingBlock(start.deprecatedNode()));
Node* embeddingEndNode = highestEmbeddingAncestor(end.deprecatedNode(), enclosingBlock(end.deprecatedNode()));
if (embeddingStartNode || embeddingEndNode) {
- Position embeddingApplyStart = embeddingStartNode ? positionInParentAfterNode(embeddingStartNode) : start;
- Position embeddingApplyEnd = embeddingEndNode ? positionInParentBeforeNode(embeddingEndNode) : end;
+ Position embeddingApplyStart = embeddingStartNode ? positionInParentAfterNode(*embeddingStartNode) : start;
+ Position embeddingApplyEnd = embeddingEndNode ? positionInParentBeforeNode(*embeddingEndNode) : end;
ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNull());
if (!embeddingStyle) {
@@ -686,16 +699,16 @@ void ApplyStyleCommand::fixRangeAndApplyInlineStyle(EditingStyle* style, const P
// FIXME: Callers should perform this operation on a Range that includes the br
// if they want style applied to the empty line.
- if (start == end && start.deprecatedNode()->hasTagName(brTag))
+ if (start == end && isHTMLBRElement(*start.deprecatedNode()))
pastEndNode = NodeTraversal::next(*start.deprecatedNode());
// Start from the highest fully selected ancestor so that we can modify the fully selected node.
// e.g. When applying font-size: large on <font color="blue">hello</font>, we need to include the font element in our run
// to generate <font color="blue" size="4">hello</font> instead of <font color="blue"><font size="4">hello</font></font>
- RefPtr<Range> range = Range::create(startNode->document(), start, end);
+ RefPtrWillBeRawPtr<Range> range = Range::create(startNode->document(), start, end);
Element* editableRoot = startNode->rootEditableElement();
if (startNode != editableRoot) {
- while (editableRoot && startNode->parentNode() != editableRoot && isNodeVisiblyContainedWithin(startNode->parentNode(), range.get()))
+ while (editableRoot && startNode->parentNode() != editableRoot && isNodeVisiblyContainedWithin(*startNode->parentNode(), *range))
startNode = startNode->parentNode();
}
@@ -716,7 +729,9 @@ static bool containsNonEditableRegion(Node& node)
return false;
}
-struct InlineRunToApplyStyle {
+class InlineRunToApplyStyle {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
InlineRunToApplyStyle(Node* start, Node* end, Node* pastEndNode)
: start(start)
, end(end)
@@ -730,24 +745,39 @@ struct InlineRunToApplyStyle {
return start && end && start->inDocument() && end->inDocument();
}
- RefPtr<Node> start;
- RefPtr<Node> end;
- RefPtr<Node> pastEndNode;
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(start);
+ visitor->trace(end);
+ visitor->trace(pastEndNode);
+ visitor->trace(positionForStyleComputation);
+ visitor->trace(dummyElement);
+ }
+
+ RefPtrWillBeMember<Node> start;
+ RefPtrWillBeMember<Node> end;
+ RefPtrWillBeMember<Node> pastEndNode;
Position positionForStyleComputation;
- RefPtr<Node> dummyElement;
+ RefPtrWillBeMember<Node> dummyElement;
StyleChange change;
};
-void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRefPtr<Node> startNode, PassRefPtr<Node> pastEndNode)
+} // namespace WebCore
+
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(WebCore::InlineRunToApplyStyle);
+
+namespace WebCore {
+
+void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRefPtrWillBeRawPtr<Node> startNode, PassRefPtrWillBeRawPtr<Node> pastEndNode)
{
if (m_removeOnly)
return;
document().updateLayoutIgnorePendingStylesheets();
- Vector<InlineRunToApplyStyle> runs;
- RefPtr<Node> node = startNode;
- for (RefPtr<Node> next; node && node != pastEndNode; node = next) {
+ WillBeHeapVector<InlineRunToApplyStyle> runs;
+ RefPtrWillBeRawPtr<Node> node = startNode;
+ for (RefPtrWillBeRawPtr<Node> next; node && node != pastEndNode; node = next) {
next = NodeTraversal::next(*node);
if (!node->renderer() || !node->rendererIsEditable())
@@ -764,7 +794,7 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRef
next = NodeTraversal::nextSkippingChildren(*node);
if (!style->style())
continue;
- RefPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(element->inlineStyle());
+ RefPtrWillBeRawPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(element->inlineStyle());
inlineStyle->mergeAndOverrideOnConflict(style->style());
setNodeAttribute(element, styleAttr, AtomicString(inlineStyle->asText()));
continue;
@@ -773,7 +803,7 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRef
if (isBlock(node.get()))
continue;
- if (node->childNodeCount()) {
+ if (node->hasChildren()) {
if (node->contains(pastEndNode.get()) || containsNonEditableRegion(*node) || !node->parentNode()->rendererIsEditable())
continue;
if (editingIgnoresContent(node.get())) {
@@ -786,7 +816,7 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRef
Node* runEnd = node.get();
Node* sibling = node->nextSibling();
while (sibling && sibling != pastEndNode && !sibling->contains(pastEndNode.get())
- && (!isBlock(sibling) || sibling->hasTagName(brTag))
+ && (!isBlock(sibling) || isHTMLBRElement(*sibling))
&& !containsNonEditableRegion(*sibling)) {
runEnd = sibling;
sibling = runEnd->nextSibling();
@@ -803,16 +833,19 @@ void ApplyStyleCommand::applyInlineStyleToNodeRange(EditingStyle* style, PassRef
for (size_t i = 0; i < runs.size(); i++) {
removeConflictingInlineStyleFromRun(style, runs[i].start, runs[i].end, runs[i].pastEndNode);
- runs[i].positionForStyleComputation = positionToComputeInlineStyleChange(runs[i].start, runs[i].dummyElement);
+ if (runs[i].startAndEndAreStillInDocument())
+ runs[i].positionForStyleComputation = positionToComputeInlineStyleChange(runs[i].start, runs[i].dummyElement);
}
document().updateLayoutIgnorePendingStylesheets();
- for (size_t i = 0; i < runs.size(); i++)
- runs[i].change = StyleChange(style, runs[i].positionForStyleComputation);
+ for (size_t i = 0; i < runs.size(); i++) {
+ if (runs[i].positionForStyleComputation.isNotNull())
+ runs[i].change = StyleChange(style, runs[i].positionForStyleComputation);
+ }
for (size_t i = 0; i < runs.size(); i++) {
- InlineRunToApplyStyle& run = runs[i];
+ InlineRunToApplyStyle run = runs[i];
if (run.dummyElement)
removeNode(run.dummyElement);
if (run.startAndEndAreStillInDocument())
@@ -831,7 +864,7 @@ bool ApplyStyleCommand::shouldApplyInlineStyleToRun(EditingStyle* style, Node* r
ASSERT(style && runStart);
for (Node* node = runStart; node && node != pastEndNode; node = NodeTraversal::next(*node)) {
- if (node->childNodeCount())
+ if (node->hasChildren())
continue;
// We don't consider m_isInlineElementToRemoveFunction here because we never apply style when m_isInlineElementToRemoveFunction is specified
if (!style->styleIsPresentInComputedStyleOfNode(node))
@@ -842,11 +875,11 @@ bool ApplyStyleCommand::shouldApplyInlineStyleToRun(EditingStyle* style, Node* r
return false;
}
-void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style, RefPtr<Node>& runStart, RefPtr<Node>& runEnd, PassRefPtr<Node> pastEndNode)
+void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style, RefPtrWillBeMember<Node>& runStart, RefPtrWillBeMember<Node>& runEnd, PassRefPtrWillBeRawPtr<Node> pastEndNode)
{
ASSERT(runStart && runEnd);
- RefPtr<Node> next = runStart;
- for (RefPtr<Node> node = next; node && node->inDocument() && node != pastEndNode; node = next) {
+ RefPtrWillBeRawPtr<Node> next = runStart;
+ for (RefPtrWillBeRawPtr<Node> node = next; node && node->inDocument() && node != pastEndNode; node = next) {
if (editingIgnoresContent(node.get())) {
ASSERT(!node->contains(pastEndNode.get()));
next = NodeTraversal::nextSkippingChildren(*node);
@@ -856,9 +889,9 @@ void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style,
if (!node->isHTMLElement())
continue;
- RefPtr<Node> previousSibling = node->previousSibling();
- RefPtr<Node> nextSibling = node->nextSibling();
- RefPtr<ContainerNode> parent = node->parentNode();
+ RefPtrWillBeRawPtr<Node> previousSibling = node->previousSibling();
+ RefPtrWillBeRawPtr<Node> nextSibling = node->nextSibling();
+ RefPtrWillBeRawPtr<ContainerNode> parent = node->parentNode();
removeInlineStyleFromElement(style, toHTMLElement(node), RemoveAlways);
if (!node->inDocument()) {
// FIXME: We might need to update the start and the end of current selection here but need a test.
@@ -870,7 +903,7 @@ void ApplyStyleCommand::removeConflictingInlineStyleFromRun(EditingStyle* style,
}
}
-bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, PassRefPtr<HTMLElement> element, InlineStyleRemovalMode mode, EditingStyle* extractedStyle)
+bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, PassRefPtrWillBeRawPtr<HTMLElement> element, InlineStyleRemovalMode mode, EditingStyle* extractedStyle)
{
ASSERT(element);
@@ -880,8 +913,8 @@ bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, PassRe
if (isStyledInlineElementToRemove(element.get())) {
if (mode == RemoveNone)
return true;
- ASSERT(extractedStyle);
- extractedStyle->mergeInlineStyleOfElement(element.get(), EditingStyle::OverrideValues);
+ if (extractedStyle)
+ extractedStyle->mergeInlineStyleOfElement(element.get(), EditingStyle::OverrideValues);
removeNodePreservingChildren(element);
return true;
}
@@ -901,15 +934,12 @@ bool ApplyStyleCommand::removeInlineStyleFromElement(EditingStyle* style, PassRe
return removed;
}
-void ApplyStyleCommand::replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement*& elem)
+void ApplyStyleCommand::replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement* elem)
{
if (hasNoAttributeOrOnlyStyleAttribute(elem, StyleAttributeShouldBeEmpty))
removeNodePreservingChildren(elem);
- else {
- HTMLElement* newSpanElement = replaceElementWithSpanPreservingChildrenAndAttributes(elem);
- ASSERT(newSpanElement && newSpanElement->inDocument());
- elem = newSpanElement;
- }
+ else
+ replaceElementWithSpanPreservingChildrenAndAttributes(elem);
}
bool ApplyStyleCommand::removeImplicitlyStyledElement(EditingStyle* style, HTMLElement* element, InlineStyleRemovalMode mode, EditingStyle* extractedStyle)
@@ -957,10 +987,6 @@ bool ApplyStyleCommand::removeCSSStyle(EditingStyle* style, HTMLElement* element
for (size_t i = 0; i < properties.size(); i++)
removeCSSProperty(element, properties[i]);
- // No need to serialize <foo style=""> if we just removed the last css property
- if (element->inlineStyle()->isEmpty())
- removeNodeAttribute(element, styleAttr);
-
if (isSpanWithoutAttributesOrUnstyledStyleSpan(element))
removeNodePreservingChildren(element);
@@ -991,12 +1017,12 @@ void ApplyStyleCommand::applyInlineStyleToPushDown(Node* node, EditingStyle* sty
{
ASSERT(node);
- node->document().updateStyleIfNeeded();
+ node->document().updateRenderTreeIfNeeded();
- if (!style || style->isEmpty() || !node->renderer())
+ if (!style || style->isEmpty() || !node->renderer() || isHTMLIFrameElement(*node))
return;
- RefPtr<EditingStyle> newInlineStyle = style;
+ RefPtrWillBeRawPtr<EditingStyle> newInlineStyle = style;
if (node->isHTMLElement() && toHTMLElement(node)->inlineStyle()) {
newInlineStyle = style->copy();
newInlineStyle->mergeInlineStyleOfElement(toHTMLElement(node), EditingStyle::OverrideValues);
@@ -1004,7 +1030,7 @@ void ApplyStyleCommand::applyInlineStyleToPushDown(Node* node, EditingStyle* sty
// Since addInlineStyleIfNeeded can't add styles to block-flow render objects, add style attribute instead.
// FIXME: applyInlineStyleToRange should be used here instead.
- if ((node->renderer()->isRenderBlockFlow() || node->childNodeCount()) && node->isHTMLElement()) {
+ if ((node->renderer()->isRenderBlockFlow() || node->hasChildren()) && node->isHTMLElement()) {
setNodeAttribute(toHTMLElement(node), styleAttr, AtomicString(newInlineStyle->style()->asText()));
return;
}
@@ -1025,20 +1051,20 @@ void ApplyStyleCommand::pushDownInlineStyleAroundNode(EditingStyle* style, Node*
return;
// The outer loop is traversing the tree vertically from highestAncestor to targetNode
- RefPtr<Node> current = highestAncestor;
+ RefPtrWillBeRawPtr<Node> current = highestAncestor;
// Along the way, styled elements that contain targetNode are removed and accumulated into elementsToPushDown.
// Each child of the removed element, exclusing ancestors of targetNode, is then wrapped by clones of elements in elementsToPushDown.
- Vector<RefPtr<Element> > elementsToPushDown;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > elementsToPushDown;
while (current && current != targetNode && current->contains(targetNode)) {
NodeVector currentChildren;
getChildNodes(*current, currentChildren);
- RefPtr<Element> styledElement;
+ RefPtrWillBeRawPtr<Element> styledElement = nullptr;
if (current->isStyledElement() && isStyledInlineElementToRemove(toElement(current))) {
styledElement = toElement(current);
elementsToPushDown.append(styledElement);
}
- RefPtr<EditingStyle> styleToPushDown = EditingStyle::create();
+ RefPtrWillBeRawPtr<EditingStyle> styleToPushDown = EditingStyle::create();
if (current->isHTMLElement())
removeInlineStyleFromElement(style, toHTMLElement(current), RemoveIfNeeded, styleToPushDown.get());
@@ -1050,7 +1076,7 @@ void ApplyStyleCommand::pushDownInlineStyleAroundNode(EditingStyle* style, Node*
continue;
if (!child->contains(targetNode) && elementsToPushDown.size()) {
for (size_t i = 0; i < elementsToPushDown.size(); i++) {
- RefPtr<Element> wrapper = elementsToPushDown[i]->cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> wrapper = elementsToPushDown[i]->cloneElementWithoutChildren();
wrapper->removeAttribute(styleAttr);
surroundNodeRangeWithElement(child, child, wrapper);
}
@@ -1104,9 +1130,9 @@ void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &s
Position s = start.isNull() || start.isOrphan() ? pushDownStart : start;
Position e = end.isNull() || end.isOrphan() ? pushDownEnd : end;
- RefPtr<Node> node = start.deprecatedNode();
+ RefPtrWillBeRawPtr<Node> node = start.deprecatedNode();
while (node) {
- RefPtr<Node> next;
+ RefPtrWillBeRawPtr<Node> next = nullptr;
if (editingIgnoresContent(node.get())) {
ASSERT(node == end.deprecatedNode() || !node->contains(end.deprecatedNode()));
next = NodeTraversal::nextSkippingChildren(*node);
@@ -1114,11 +1140,11 @@ void ApplyStyleCommand::removeInlineStyle(EditingStyle* style, const Position &s
next = NodeTraversal::next(*node);
}
if (node->isHTMLElement() && nodeFullySelected(node.get(), start, end)) {
- RefPtr<HTMLElement> elem = toHTMLElement(node);
- RefPtr<Node> prev = NodeTraversal::previousPostOrder(*elem);
- RefPtr<Node> next = NodeTraversal::next(*elem);
- RefPtr<EditingStyle> styleToPushDown;
- RefPtr<Node> childNode;
+ RefPtrWillBeRawPtr<HTMLElement> elem = toHTMLElement(node);
+ RefPtrWillBeRawPtr<Node> prev = NodeTraversal::previousPostOrder(*elem);
+ RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*elem);
+ RefPtrWillBeRawPtr<EditingStyle> styleToPushDown = nullptr;
+ RefPtrWillBeRawPtr<Node> childNode = nullptr;
if (isStyledInlineElementToRemove(elem.get())) {
styleToPushDown = EditingStyle::create();
childNode = elem->firstChild();
@@ -1166,17 +1192,6 @@ bool ApplyStyleCommand::nodeFullySelected(Node *node, const Position &start, con
&& comparePositions(lastPositionInOrAfterNode(node).upstream(), end) <= 0;
}
-bool ApplyStyleCommand::nodeFullyUnselected(Node *node, const Position &start, const Position &end) const
-{
- ASSERT(node);
- ASSERT(node->isElementNode());
-
- bool isFullyBeforeStart = comparePositions(lastPositionInOrAfterNode(node).upstream(), start) < 0;
- bool isFullyAfterEnd = comparePositions(firstPositionInOrBeforeNode(node), end) > 0;
-
- return isFullyBeforeStart || isFullyAfterEnd;
-}
-
void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position& end)
{
ASSERT(start.containerNode()->isTextNode());
@@ -1187,7 +1202,7 @@ void ApplyStyleCommand::splitTextAtStart(const Position& start, const Position&
else
newEnd = end;
- RefPtr<Text> text = start.containerText();
+ RefPtrWillBeRawPtr<Text> text = start.containerText();
splitTextNode(text, start.offsetInContainerNode());
updateStartEnd(firstPositionInNode(text.get()), newEnd);
}
@@ -1271,7 +1286,6 @@ bool ApplyStyleCommand::mergeStartWithPreviousIfIdentical(const Position& start,
return false;
startNode = startNode->parentNode();
- startOffset = 0;
}
if (!startNode->isElementNode())
@@ -1311,7 +1325,7 @@ bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const
endNode = end.deprecatedNode()->parentNode();
}
- if (!endNode->isElementNode() || endNode->hasTagName(brTag))
+ if (!endNode->isElementNode() || isHTMLBRElement(*endNode))
return false;
Node* nextSibling = endNode->nextSibling();
@@ -1332,19 +1346,18 @@ bool ApplyStyleCommand::mergeEndWithNextIfIdentical(const Position& start, const
return false;
}
-void ApplyStyleCommand::surroundNodeRangeWithElement(PassRefPtr<Node> passedStartNode, PassRefPtr<Node> endNode, PassRefPtr<Element> elementToInsert)
+void ApplyStyleCommand::surroundNodeRangeWithElement(PassRefPtrWillBeRawPtr<Node> passedStartNode, PassRefPtrWillBeRawPtr<Node> endNode, PassRefPtrWillBeRawPtr<Element> elementToInsert)
{
ASSERT(passedStartNode);
ASSERT(endNode);
ASSERT(elementToInsert);
- RefPtr<Node> startNode = passedStartNode;
- RefPtr<Element> element = elementToInsert;
+ RefPtrWillBeRawPtr<Node> node = passedStartNode;
+ RefPtrWillBeRawPtr<Element> element = elementToInsert;
- insertNodeBefore(element, startNode);
+ insertNodeBefore(element, node);
- RefPtr<Node> node = startNode;
while (node) {
- RefPtr<Node> next = node->nextSibling();
+ RefPtrWillBeRawPtr<Node> next = node->nextSibling();
if (node->isContentEditable(Node::UserSelectAllIsAlwaysNonEditable)) {
removeNode(node);
appendNode(node, element);
@@ -1354,8 +1367,8 @@ void ApplyStyleCommand::surroundNodeRangeWithElement(PassRefPtr<Node> passedStar
node = next;
}
- RefPtr<Node> nextSibling = element->nextSibling();
- RefPtr<Node> previousSibling = element->previousSibling();
+ RefPtrWillBeRawPtr<Node> nextSibling = element->nextSibling();
+ RefPtrWillBeRawPtr<Node> previousSibling = element->previousSibling();
if (nextSibling && nextSibling->isElementNode() && nextSibling->rendererIsEditable()
&& areIdenticalElements(element.get(), toElement(nextSibling)))
mergeIdenticalElements(element.get(), toElement(nextSibling));
@@ -1390,13 +1403,13 @@ void ApplyStyleCommand::addBlockStyle(const StyleChange& styleChange, HTMLElemen
setNodeAttribute(block, styleAttr, cssText.toAtomicString());
}
-void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtr<Node> passedStart, PassRefPtr<Node> passedEnd, EAddStyledElement addStyledElement)
+void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtrWillBeRawPtr<Node> passedStart, PassRefPtrWillBeRawPtr<Node> passedEnd, EAddStyledElement addStyledElement)
{
if (!passedStart || !passedEnd || !passedStart->inDocument() || !passedEnd->inDocument())
return;
- RefPtr<Node> start = passedStart;
- RefPtr<Node> dummyElement;
+ RefPtrWillBeRawPtr<Node> start = passedStart;
+ RefPtrWillBeMember<Node> dummyElement = nullptr;
StyleChange styleChange(style, positionToComputeInlineStyleChange(start, dummyElement));
if (dummyElement)
@@ -1405,7 +1418,7 @@ void ApplyStyleCommand::addInlineStyleIfNeeded(EditingStyle* style, PassRefPtr<N
applyInlineStyleChange(start, passedEnd, styleChange, addStyledElement);
}
-Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtr<Node> startNode, RefPtr<Node>& dummyElement)
+Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtrWillBeRawPtr<Node> startNode, RefPtrWillBeMember<Node>& dummyElement)
{
// It's okay to obtain the style at the startNode because we've removed all relevant styles from the current run.
if (!startNode->isElementNode()) {
@@ -1417,10 +1430,10 @@ Position ApplyStyleCommand::positionToComputeInlineStyleChange(PassRefPtr<Node>
return firstPositionInOrBeforeNode(startNode.get());
}
-void ApplyStyleCommand::applyInlineStyleChange(PassRefPtr<Node> passedStart, PassRefPtr<Node> passedEnd, StyleChange& styleChange, EAddStyledElement addStyledElement)
+void ApplyStyleCommand::applyInlineStyleChange(PassRefPtrWillBeRawPtr<Node> passedStart, PassRefPtrWillBeRawPtr<Node> passedEnd, StyleChange& styleChange, EAddStyledElement addStyledElement)
{
- RefPtr<Node> startNode = passedStart;
- RefPtr<Node> endNode = passedEnd;
+ RefPtrWillBeRawPtr<Node> startNode = passedStart;
+ RefPtrWillBeRawPtr<Node> endNode = passedEnd;
ASSERT(startNode->inDocument());
ASSERT(endNode->inDocument());
@@ -1428,11 +1441,14 @@ void ApplyStyleCommand::applyInlineStyleChange(PassRefPtr<Node> passedStart, Pas
HTMLElement* fontContainer = 0;
HTMLElement* styleContainer = 0;
for (Node* container = startNode.get(); container && startNode == endNode; container = container->firstChild()) {
- if (container->isHTMLElement() && container->hasTagName(fontTag))
+ if (isHTMLFontElement(*container))
fontContainer = toHTMLElement(container);
- bool styleContainerIsNotSpan = !styleContainer || !styleContainer->hasTagName(spanTag);
- if (container->isHTMLElement() && (container->hasTagName(spanTag) || (styleContainerIsNotSpan && container->childNodeCount())))
- styleContainer = toHTMLElement(container);
+ bool styleContainerIsNotSpan = !isHTMLSpanElement(styleContainer);
+ if (container->isHTMLElement()) {
+ HTMLElement* containerElement = toHTMLElement(container);
+ if (isHTMLSpanElement(*containerElement) || (styleContainerIsNotSpan && containerElement->hasChildren()))
+ styleContainer = toHTMLElement(container);
+ }
if (!container->firstChild())
break;
startNode = container->firstChild();
@@ -1449,7 +1465,7 @@ void ApplyStyleCommand::applyInlineStyleChange(PassRefPtr<Node> passedStart, Pas
if (styleChange.applyFontSize())
setNodeAttribute(fontContainer, sizeAttr, AtomicString(styleChange.fontSize()));
} else {
- RefPtr<Element> fontElement = createFontElement(document());
+ RefPtrWillBeRawPtr<Element> fontElement = createFontElement(document());
if (styleChange.applyFontColor())
fontElement->setAttribute(colorAttr, AtomicString(styleChange.fontColor()));
if (styleChange.applyFontFace())
@@ -1474,7 +1490,7 @@ void ApplyStyleCommand::applyInlineStyleChange(PassRefPtr<Node> passedStart, Pas
setNodeAttribute(styleContainer, styleAttr, AtomicString(styleChange.cssStyle()));
}
} else {
- RefPtr<Element> styleElement = createStyleSpanElement(document());
+ RefPtrWillBeRawPtr<Element> styleElement = createStyleSpanElement(document());
styleElement->setAttribute(styleAttr, AtomicString(styleChange.cssStyle()));
surroundNodeRangeWithElement(startNode, endNode, styleElement.release());
}
@@ -1506,18 +1522,18 @@ float ApplyStyleCommand::computedFontSize(Node* node)
if (!node)
return 0;
- RefPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(node);
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(node);
if (!style)
return 0;
- RefPtr<CSSPrimitiveValue> value = static_pointer_cast<CSSPrimitiveValue>(style->getPropertyCSSValue(CSSPropertyFontSize));
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> value = static_pointer_cast<CSSPrimitiveValue>(style->getPropertyCSSValue(CSSPropertyFontSize));
if (!value)
return 0;
return value->getFloatValue(CSSPrimitiveValue::CSS_PX);
}
-void ApplyStyleCommand::joinChildTextNodes(Node* node, const Position& start, const Position& end)
+void ApplyStyleCommand::joinChildTextNodes(ContainerNode* node, const Position& start, const Position& end)
{
if (!node)
return;
@@ -1525,7 +1541,7 @@ void ApplyStyleCommand::joinChildTextNodes(Node* node, const Position& start, co
Position newStart = start;
Position newEnd = end;
- Vector<RefPtr<Text> > textNodes;
+ WillBeHeapVector<RefPtrWillBeMember<Text> > textNodes;
for (Node* curr = node->firstChild(); curr; curr = curr->nextSibling()) {
if (!curr->isTextNode())
continue;
@@ -1553,4 +1569,13 @@ void ApplyStyleCommand::joinChildTextNodes(Node* node, const Position& start, co
updateStartEnd(newStart, newEnd);
}
+void ApplyStyleCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_style);
+ visitor->trace(m_start);
+ visitor->trace(m_end);
+ visitor->trace(m_styledInlineElement);
+ CompositeEditCommand::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.h b/chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.h
index 363e09e505d..435b25f510e 100644
--- a/chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/ApplyStyleCommand.h
@@ -41,46 +41,48 @@ enum ShouldIncludeTypingStyle {
IgnoreTypingStyle
};
-class ApplyStyleCommand : public CompositeEditCommand {
+class ApplyStyleCommand FINAL : public CompositeEditCommand {
public:
enum EPropertyLevel { PropertyDefault, ForceBlockProperties };
enum InlineStyleRemovalMode { RemoveIfNeeded, RemoveAlways, RemoveNone };
enum EAddStyledElement { AddStyledElement, DoNotAddStyledElement };
typedef bool (*IsInlineElementToRemoveFunction)(const Element*);
- static PassRefPtr<ApplyStyleCommand> create(Document& document, const EditingStyle* style, EditAction action = EditActionChangeAttributes, EPropertyLevel level = PropertyDefault)
+ static PassRefPtrWillBeRawPtr<ApplyStyleCommand> create(Document& document, const EditingStyle* style, EditAction action = EditActionChangeAttributes, EPropertyLevel level = PropertyDefault)
{
- return adoptRef(new ApplyStyleCommand(document, style, action, level));
+ return adoptRefWillBeNoop(new ApplyStyleCommand(document, style, action, level));
}
- static PassRefPtr<ApplyStyleCommand> create(Document& document, const EditingStyle* style, const Position& start, const Position& end, EditAction action = EditActionChangeAttributes, EPropertyLevel level = PropertyDefault)
+ static PassRefPtrWillBeRawPtr<ApplyStyleCommand> create(Document& document, const EditingStyle* style, const Position& start, const Position& end, EditAction action = EditActionChangeAttributes, EPropertyLevel level = PropertyDefault)
{
- return adoptRef(new ApplyStyleCommand(document, style, start, end, action, level));
+ return adoptRefWillBeNoop(new ApplyStyleCommand(document, style, start, end, action, level));
}
- static PassRefPtr<ApplyStyleCommand> create(PassRefPtr<Element> element, bool removeOnly = false, EditAction action = EditActionChangeAttributes)
+ static PassRefPtrWillBeRawPtr<ApplyStyleCommand> create(PassRefPtrWillBeRawPtr<Element> element, bool removeOnly = false, EditAction action = EditActionChangeAttributes)
{
- return adoptRef(new ApplyStyleCommand(element, removeOnly, action));
+ return adoptRefWillBeNoop(new ApplyStyleCommand(element, removeOnly, action));
}
- static PassRefPtr<ApplyStyleCommand> create(Document& document, const EditingStyle* style, IsInlineElementToRemoveFunction isInlineElementToRemoveFunction, EditAction action = EditActionChangeAttributes)
+ static PassRefPtrWillBeRawPtr<ApplyStyleCommand> create(Document& document, const EditingStyle* style, IsInlineElementToRemoveFunction isInlineElementToRemoveFunction, EditAction action = EditActionChangeAttributes)
{
- return adoptRef(new ApplyStyleCommand(document, style, isInlineElementToRemoveFunction, action));
+ return adoptRefWillBeNoop(new ApplyStyleCommand(document, style, isInlineElementToRemoveFunction, action));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
ApplyStyleCommand(Document&, const EditingStyle*, EditAction, EPropertyLevel);
ApplyStyleCommand(Document&, const EditingStyle*, const Position& start, const Position& end, EditAction, EPropertyLevel);
- ApplyStyleCommand(PassRefPtr<Element>, bool removeOnly, EditAction);
+ ApplyStyleCommand(PassRefPtrWillBeRawPtr<Element>, bool removeOnly, EditAction);
ApplyStyleCommand(Document&, const EditingStyle*, bool (*isInlineElementToRemove)(const Element*), EditAction);
- virtual void doApply();
- virtual EditAction editingAction() const;
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE;
// style-removal helpers
bool isStyledInlineElementToRemove(Element*) const;
bool shouldApplyInlineStyleToRun(EditingStyle*, Node* runStart, Node* pastEndNode);
- void removeConflictingInlineStyleFromRun(EditingStyle*, RefPtr<Node>& runStart, RefPtr<Node>& runEnd, PassRefPtr<Node> pastEndNode);
- bool removeInlineStyleFromElement(EditingStyle*, PassRefPtr<HTMLElement>, InlineStyleRemovalMode = RemoveIfNeeded, EditingStyle* extractedStyle = 0);
+ void removeConflictingInlineStyleFromRun(EditingStyle*, RefPtrWillBeMember<Node>& runStart, RefPtrWillBeMember<Node>& runEnd, PassRefPtrWillBeRawPtr<Node> pastEndNode);
+ bool removeInlineStyleFromElement(EditingStyle*, PassRefPtrWillBeRawPtr<HTMLElement>, InlineStyleRemovalMode = RemoveIfNeeded, EditingStyle* extractedStyle = 0);
inline bool shouldRemoveInlineStyleFromElement(EditingStyle* style, HTMLElement* element) {return removeInlineStyleFromElement(style, element, RemoveNone);}
- void replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement*&);
+ void replaceWithSpanOrRemoveIfWithoutAttributes(HTMLElement*);
bool removeImplicitlyStyledElement(EditingStyle*, HTMLElement*, InlineStyleRemovalMode, EditingStyle* extractedStyle);
bool removeCSSStyle(EditingStyle*, HTMLElement*, InlineStyleRemovalMode = RemoveIfNeeded, EditingStyle* extractedStyle = 0);
HTMLElement* highestAncestorWithConflictingInlineStyle(EditingStyle*, Node*);
@@ -88,18 +90,17 @@ private:
void pushDownInlineStyleAroundNode(EditingStyle*, Node*);
void removeInlineStyle(EditingStyle* , const Position& start, const Position& end);
bool nodeFullySelected(Node*, const Position& start, const Position& end) const;
- bool nodeFullyUnselected(Node*, const Position& start, const Position& end) const;
// style-application helpers
void applyBlockStyle(EditingStyle*);
void applyRelativeFontStyleChange(EditingStyle*);
void applyInlineStyle(EditingStyle*);
void fixRangeAndApplyInlineStyle(EditingStyle*, const Position& start, const Position& end);
- void applyInlineStyleToNodeRange(EditingStyle*, PassRefPtr<Node> startNode, PassRefPtr<Node> pastEndNode);
+ void applyInlineStyleToNodeRange(EditingStyle*, PassRefPtrWillBeRawPtr<Node> startNode, PassRefPtrWillBeRawPtr<Node> pastEndNode);
void addBlockStyle(const StyleChange&, HTMLElement*);
- void addInlineStyleIfNeeded(EditingStyle*, PassRefPtr<Node> start, PassRefPtr<Node> end, EAddStyledElement = AddStyledElement);
- Position positionToComputeInlineStyleChange(PassRefPtr<Node>, RefPtr<Node>& dummyElement);
- void applyInlineStyleChange(PassRefPtr<Node> startNode, PassRefPtr<Node> endNode, StyleChange&, EAddStyledElement);
+ void addInlineStyleIfNeeded(EditingStyle*, PassRefPtrWillBeRawPtr<Node> start, PassRefPtrWillBeRawPtr<Node> end, EAddStyledElement = AddStyledElement);
+ Position positionToComputeInlineStyleChange(PassRefPtrWillBeRawPtr<Node>, RefPtrWillBeMember<Node>& dummyElement);
+ void applyInlineStyleChange(PassRefPtrWillBeRawPtr<Node> startNode, PassRefPtrWillBeRawPtr<Node> endNode, StyleChange&, EAddStyledElement);
void splitTextAtStart(const Position& start, const Position& end);
void splitTextAtEnd(const Position& start, const Position& end);
void splitTextElementAtStart(const Position& start, const Position& end);
@@ -108,11 +109,11 @@ private:
bool isValidCaretPositionInTextNode(const Position& position);
bool mergeStartWithPreviousIfIdentical(const Position& start, const Position& end);
bool mergeEndWithNextIfIdentical(const Position& start, const Position& end);
- void cleanupUnstyledAppleStyleSpans(Node* dummySpanAncestor);
+ void cleanupUnstyledAppleStyleSpans(ContainerNode* dummySpanAncestor);
- void surroundNodeRangeWithElement(PassRefPtr<Node> start, PassRefPtr<Node> end, PassRefPtr<Element>);
+ void surroundNodeRangeWithElement(PassRefPtrWillBeRawPtr<Node> start, PassRefPtrWillBeRawPtr<Node> end, PassRefPtrWillBeRawPtr<Element>);
float computedFontSize(Node*);
- void joinChildTextNodes(Node*, const Position& start, const Position& end);
+ void joinChildTextNodes(ContainerNode*, const Position& start, const Position& end);
HTMLElement* splitAncestorsWithUnicodeBidi(Node*, bool before, WritingDirection allowedDirection);
void removeEmbeddingUpToEnclosingBlock(Node* node, Node* unsplitAncestor);
@@ -121,13 +122,13 @@ private:
Position startPosition();
Position endPosition();
- RefPtr<EditingStyle> m_style;
+ RefPtrWillBeMember<EditingStyle> m_style;
EditAction m_editingAction;
EPropertyLevel m_propertyLevel;
Position m_start;
Position m_end;
bool m_useEndingSelection;
- RefPtr<Element> m_styledInlineElement;
+ RefPtrWillBeMember<Element> m_styledInlineElement;
bool m_removeOnly;
IsInlineElementToRemoveFunction m_isInlineElementToRemoveFunction;
};
@@ -136,7 +137,7 @@ enum ShouldStyleAttributeBeEmpty { AllowNonEmptyStyleAttribute, StyleAttributeSh
bool isEmptyFontTag(const Element*, ShouldStyleAttributeBeEmpty = StyleAttributeShouldBeEmpty);
bool isLegacyAppleStyleSpan(const Node*);
bool isStyleSpanOrSpanWithOnlyStyleAttribute(const Element*);
-PassRefPtr<HTMLElement> createStyleSpanElement(Document&);
+PassRefPtrWillBeRawPtr<HTMLElement> createStyleSpanElement(Document&);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.cpp
index 73f09d90dd0..a56dec40d9e 100644
--- a/chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/editing/BreakBlockquoteCommand.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/Text.h"
#include "core/editing/VisiblePosition.h"
@@ -71,7 +71,7 @@ void BreakBlockquoteCommand::doApply()
if (!topBlockquote || !topBlockquote->parentNode() || !topBlockquote->isElementNode())
return;
- RefPtr<Element> breakNode = createBreakElement(document());
+ RefPtrWillBeRawPtr<Element> breakNode = createBreakElement(document());
bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockquote);
@@ -116,7 +116,7 @@ void BreakBlockquoteCommand::doApply()
} else if (pos.deprecatedEditingOffset() > 0)
splitTextNode(textNode, pos.deprecatedEditingOffset());
} else if (pos.deprecatedEditingOffset() > 0) {
- Node* childAtOffset = startNode->childNode(pos.deprecatedEditingOffset());
+ Node* childAtOffset = startNode->traverseToChildAt(pos.deprecatedEditingOffset());
startNode = childAtOffset ? childAtOffset : NodeTraversal::next(*startNode);
ASSERT(startNode);
}
@@ -128,27 +128,27 @@ void BreakBlockquoteCommand::doApply()
}
// Build up list of ancestors in between the start node and the top blockquote.
- Vector<RefPtr<Element> > ancestors;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > ancestors;
for (Element* node = startNode->parentElement(); node && node != topBlockquote; node = node->parentElement())
ancestors.append(node);
// Insert a clone of the top blockquote after the break.
- RefPtr<Element> clonedBlockquote = toElement(topBlockquote)->cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> clonedBlockquote = toElement(topBlockquote)->cloneElementWithoutChildren();
insertNodeAfter(clonedBlockquote.get(), breakNode.get());
// Clone startNode's ancestors into the cloned blockquote.
// On exiting this loop, clonedAncestor is the lowest ancestor
// that was cloned (i.e. the clone of either ancestors.last()
// or clonedBlockquote if ancestors is empty).
- RefPtr<Element> clonedAncestor = clonedBlockquote;
+ RefPtrWillBeRawPtr<Element> clonedAncestor = clonedBlockquote;
for (size_t i = ancestors.size(); i != 0; --i) {
- RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChildren();
// Preserve list item numbering in cloned lists.
- if (clonedChild->isElementNode() && clonedChild->hasTagName(olTag)) {
+ if (isHTMLOListElement(*clonedChild)) {
Node* listChildNode = i > 1 ? ancestors[i - 2].get() : startNode;
// The first child of the cloned list might not be a list item element,
// find the first one so that we know where to start numbering.
- while (listChildNode && !listChildNode->hasTagName(liTag))
+ while (listChildNode && !isHTMLLIElement(*listChildNode))
listChildNode = listChildNode->nextSibling();
if (listChildNode && listChildNode->renderer() && listChildNode->renderer()->isListItem())
setNodeAttribute(clonedChild, startAttr, AtomicString::number(toRenderListItem(listChildNode->renderer())->value()));
@@ -165,8 +165,8 @@ void BreakBlockquoteCommand::doApply()
// Throughout this loop, clonedParent is the clone of ancestor's parent.
// This is so we can clone ancestor's siblings and place the clones
// into the clone corresponding to the ancestor's parent.
- RefPtr<Element> ancestor;
- RefPtr<Element> clonedParent;
+ RefPtrWillBeRawPtr<Element> ancestor = nullptr;
+ RefPtrWillBeRawPtr<Element> clonedParent = nullptr;
for (ancestor = ancestors.first(), clonedParent = clonedAncestor->parentElement();
ancestor && ancestor != topBlockquote;
ancestor = ancestor->parentElement(), clonedParent = clonedParent->parentElement())
@@ -174,7 +174,7 @@ void BreakBlockquoteCommand::doApply()
// If the startNode's original parent is now empty, remove it
Node* originalParent = ancestors.first().get();
- if (!originalParent->hasChildNodes())
+ if (!originalParent->hasChildren())
removeNode(originalParent);
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.h b/chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.h
index 359777c8265..675129d3cbb 100644
--- a/chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/BreakBlockquoteCommand.h
@@ -30,16 +30,16 @@
namespace WebCore {
-class BreakBlockquoteCommand : public CompositeEditCommand {
+class BreakBlockquoteCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<BreakBlockquoteCommand> create(Document& document)
+ static PassRefPtrWillBeRawPtr<BreakBlockquoteCommand> create(Document& document)
{
- return adoptRef(new BreakBlockquoteCommand(document));
+ return adoptRefWillBeNoop(new BreakBlockquoteCommand(document));
}
private:
explicit BreakBlockquoteCommand(Document&);
- virtual void doApply();
+ virtual void doApply() OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/Caret.cpp b/chromium/third_party/WebKit/Source/core/editing/Caret.cpp
index 64f05081576..be729703f02 100644
--- a/chromium/third_party/WebKit/Source/core/editing/Caret.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/Caret.cpp
@@ -28,10 +28,11 @@
#include "core/dom/Document.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderView.h"
+#include "platform/graphics/GraphicsContext.h"
namespace WebCore {
@@ -46,9 +47,9 @@ DragCaretController::DragCaretController()
{
}
-PassOwnPtr<DragCaretController> DragCaretController::create()
+PassOwnPtrWillBeRawPtr<DragCaretController> DragCaretController::create()
{
- return adoptPtr(new DragCaretController);
+ return adoptPtrWillBeNoop(new DragCaretController);
}
bool DragCaretController::isContentRichlyEditable() const
@@ -100,6 +101,11 @@ void DragCaretController::nodeWillBeRemoved(Node& node)
clear();
}
+void DragCaretController::trace(Visitor* visitor)
+{
+ visitor->trace(m_position);
+}
+
void CaretBase::clearCaretRect()
{
m_caretLocalRect = LayoutRect();
@@ -126,7 +132,7 @@ RenderObject* CaretBase::caretRenderer(Node* node)
bool CaretBase::updateCaretRect(Document* document, const VisiblePosition& caretPosition)
{
- document->updateStyleIfNeeded();
+ document->updateRenderTreeIfNeeded();
m_caretLocalRect = LayoutRect();
m_caretRectNeedsUpdate = false;
@@ -190,7 +196,7 @@ void CaretBase::repaintCaretForLocalRect(Node* node, const LayoutRect& rect)
LayoutRect inflatedRect = rect;
inflatedRect.inflate(1);
- caretPainter->repaintRectangle(inflatedRect);
+ caretPainter->invalidatePaintRectangle(inflatedRect);
}
bool CaretBase::shouldRepaintCaret(const RenderView* view, bool isContentEditable) const
@@ -198,7 +204,7 @@ bool CaretBase::shouldRepaintCaret(const RenderView* view, bool isContentEditabl
ASSERT(view);
bool caretBrowsing = false;
if (FrameView* frameView = view->frameView()) {
- Frame& frame = frameView->frame(); // The frame where the selection started
+ LocalFrame& frame = frameView->frame(); // The frame where the selection started
caretBrowsing = frame.settings() && frame.settings()->caretBrowsingEnabled();
}
return (caretBrowsing || isContentEditable);
@@ -256,7 +262,7 @@ void CaretBase::paintCaret(Node* node, GraphicsContext* context, const LayoutPoi
context->fillRect(caret, caretColor);
}
-void DragCaretController::paintDragCaret(Frame* frame, GraphicsContext* p, const LayoutPoint& paintOffset, const LayoutRect& clipRect) const
+void DragCaretController::paintDragCaret(LocalFrame* frame, GraphicsContext* p, const LayoutPoint& paintOffset, const LayoutRect& clipRect) const
{
if (m_position.deepEquivalent().deprecatedNode()->document().frame() == frame)
paintCaret(m_position.deepEquivalent().deprecatedNode(), p, paintOffset, clipRect);
diff --git a/chromium/third_party/WebKit/Source/core/editing/Caret.h b/chromium/third_party/WebKit/Source/core/editing/Caret.h
index 18c74218038..3c3d337c766 100644
--- a/chromium/third_party/WebKit/Source/core/editing/Caret.h
+++ b/chromium/third_party/WebKit/Source/core/editing/Caret.h
@@ -33,14 +33,14 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class GraphicsContext;
class RenderObject;
class RenderView;
class CaretBase {
WTF_MAKE_NONCOPYABLE(CaretBase);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
protected:
enum CaretVisibility { Visible, Hidden };
explicit CaretBase(CaretVisibility = Hidden);
@@ -71,14 +71,14 @@ private:
CaretVisibility m_caretVisibility;
};
-class DragCaretController : private CaretBase {
+class DragCaretController FINAL : public NoBaseWillBeGarbageCollected<DragCaretController>, private CaretBase {
WTF_MAKE_NONCOPYABLE(DragCaretController);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<DragCaretController> create();
+ static PassOwnPtrWillBeRawPtr<DragCaretController> create();
RenderObject* caretRenderer() const;
- void paintDragCaret(Frame*, GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
+ void paintDragCaret(LocalFrame*, GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
bool isContentEditable() const { return m_position.rootEditableElement(); }
bool isContentRichlyEditable() const;
@@ -90,6 +90,8 @@ public:
void nodeWillBeRemoved(Node&);
+ void trace(Visitor*);
+
private:
DragCaretController();
diff --git a/chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.cpp
index 24acf2d5182..b8a6fdfec88 100644
--- a/chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.cpp
@@ -26,14 +26,14 @@
#include "config.h"
#include "core/editing/CompositeEditCommand.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentMarkerController.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/Range.h"
-#include "core/events/ScopedEventQueue.h"
#include "core/dom/Text.h"
#include "core/editing/AppendNodeCommand.h"
#include "core/editing/ApplyStyleCommand.h"
@@ -61,40 +61,22 @@
#include "core/editing/WrapContentsInDummySpanCommand.h"
#include "core/editing/htmlediting.h"
#include "core/editing/markup.h"
+#include "core/events/ScopedEventQueue.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLElement.h"
-#include "core/frame/Frame.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderBlock.h"
+#include "core/rendering/RenderListItem.h"
#include "core/rendering/RenderText.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
-namespace {
-class ReentrancyGuard {
-public:
- static bool isRecursiveCall() { return s_nestingCounter; }
-
- class Scope {
- public:
- Scope() { ++s_nestingCounter; }
- ~Scope() { --s_nestingCounter; }
- };
- friend class Scope;
-
-private:
- static int s_nestingCounter;
-};
-int ReentrancyGuard::s_nestingCounter;
-}
-
-PassRefPtr<EditCommandComposition> EditCommandComposition::create(Document* document,
+PassRefPtrWillBeRawPtr<EditCommandComposition> EditCommandComposition::create(Document* document,
const VisibleSelection& startingSelection, const VisibleSelection& endingSelection, EditAction editAction)
{
- return adoptRef(new EditCommandComposition(document, startingSelection, endingSelection, editAction));
+ return adoptRefWillBeNoop(new EditCommandComposition(document, startingSelection, endingSelection, editAction));
}
EditCommandComposition::EditCommandComposition(Document* document, const VisibleSelection& startingSelection, const VisibleSelection& endingSelection, EditAction editAction)
@@ -107,7 +89,7 @@ EditCommandComposition::EditCommandComposition(Document* document, const Visible
{
}
-bool EditCommandComposition::belongsTo(const Frame& frame) const
+bool EditCommandComposition::belongsTo(const LocalFrame& frame) const
{
ASSERT(m_document);
return m_document->frame() == &frame;
@@ -116,7 +98,7 @@ bool EditCommandComposition::belongsTo(const Frame& frame) const
void EditCommandComposition::unapply()
{
ASSERT(m_document);
- RefPtr<Frame> frame = m_document->frame();
+ RefPtr<LocalFrame> frame = m_document->frame();
ASSERT(frame);
// Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>.
@@ -136,7 +118,7 @@ void EditCommandComposition::unapply()
void EditCommandComposition::reapply()
{
ASSERT(m_document);
- RefPtr<Frame> frame = m_document->frame();
+ RefPtr<LocalFrame> frame = m_document->frame();
ASSERT(frame);
// Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>.
@@ -170,6 +152,17 @@ void EditCommandComposition::setEndingSelection(const VisibleSelection& selectio
m_endingRootEditableElement = selection.rootEditableElement();
}
+void EditCommandComposition::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_startingSelection);
+ visitor->trace(m_endingSelection);
+ visitor->trace(m_commands);
+ visitor->trace(m_startingRootEditableElement);
+ visitor->trace(m_endingRootEditableElement);
+ UndoStep::trace(visitor);
+}
+
CompositeEditCommand::CompositeEditCommand(Document& document)
: EditCommand(document)
{
@@ -182,14 +175,6 @@ CompositeEditCommand::~CompositeEditCommand()
void CompositeEditCommand::apply()
{
- // We don't allow recusrive |apply()| to protect against attack code.
- // Recursive call of |apply()| could be happened by moving iframe
- // with script triggered by insertion, e.g. <iframe src="javascript:...">
- // <iframe onload="...">. This usage is valid as of the specification
- // although, it isn't common use case, rather it is used as attack code.
- if (ReentrancyGuard::isRecursiveCall())
- return;
-
if (!endingSelection().isContentRichlyEditable()) {
switch (editingAction()) {
case EditActionTyping:
@@ -211,11 +196,10 @@ void CompositeEditCommand::apply()
// if one is necessary (like for the creation of VisiblePositions).
document().updateLayoutIgnorePendingStylesheets();
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
ASSERT(frame);
{
EventQueueScope eventQueueScope;
- ReentrancyGuard::Scope reentrancyGuardScope;
doApply();
}
@@ -236,11 +220,6 @@ EditCommandComposition* CompositeEditCommand::ensureComposition()
return command->m_composition.get();
}
-bool CompositeEditCommand::isCreateLinkCommand() const
-{
- return false;
-}
-
bool CompositeEditCommand::preservesTypingStyle() const
{
return false;
@@ -251,11 +230,6 @@ bool CompositeEditCommand::isTypingCommand() const
return false;
}
-bool CompositeEditCommand::shouldRetainAutocorrectionIndicator() const
-{
- return false;
-}
-
void CompositeEditCommand::setShouldRetainAutocorrectionIndicator(bool)
{
}
@@ -263,9 +237,9 @@ void CompositeEditCommand::setShouldRetainAutocorrectionIndicator(bool)
//
// sugary-sweet convenience functions to help create and apply edit commands in composite commands
//
-void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> prpCommand)
+void CompositeEditCommand::applyCommandToComposite(PassRefPtrWillBeRawPtr<EditCommand> prpCommand)
{
- RefPtr<EditCommand> command = prpCommand;
+ RefPtrWillBeRawPtr<EditCommand> command = prpCommand;
command->setParent(this);
command->doApply();
if (command->isSimpleEditCommand()) {
@@ -275,7 +249,7 @@ void CompositeEditCommand::applyCommandToComposite(PassRefPtr<EditCommand> prpCo
m_commands.append(command.release());
}
-void CompositeEditCommand::applyCommandToComposite(PassRefPtr<CompositeEditCommand> command, const VisibleSelection& selection)
+void CompositeEditCommand::applyCommandToComposite(PassRefPtrWillBeRawPtr<CompositeEditCommand> command, const VisibleSelection& selection)
{
command->setParent(this);
if (selection != command->endingSelection()) {
@@ -296,12 +270,12 @@ void CompositeEditCommand::applyStyle(const EditingStyle* style, const Position&
applyCommandToComposite(ApplyStyleCommand::create(document(), style, start, end, editingAction));
}
-void CompositeEditCommand::applyStyledElement(PassRefPtr<Element> element)
+void CompositeEditCommand::applyStyledElement(PassRefPtrWillBeRawPtr<Element> element)
{
applyCommandToComposite(ApplyStyleCommand::create(element, false));
}
-void CompositeEditCommand::removeStyledElement(PassRefPtr<Element> element)
+void CompositeEditCommand::removeStyledElement(PassRefPtrWillBeRawPtr<Element> element)
{
applyCommandToComposite(ApplyStyleCommand::create(element, true));
}
@@ -311,17 +285,13 @@ void CompositeEditCommand::insertParagraphSeparator(bool useDefaultParagraphElem
applyCommandToComposite(InsertParagraphSeparatorCommand::create(document(), useDefaultParagraphElement, pasteBlockqutoeIntoUnquotedArea));
}
-void CompositeEditCommand::insertLineBreak()
-{
- applyCommandToComposite(InsertLineBreakCommand::create(document()));
-}
-
bool CompositeEditCommand::isRemovableBlock(const Node* node)
{
- if (!node->hasTagName(divTag))
+ ASSERT(node);
+ if (!isHTMLDivElement(*node))
return false;
- Node* parentNode = node->parentNode();
+ ContainerNode* parentNode = node->parentNode();
if (parentNode && parentNode->firstChild() != parentNode->lastChild())
return false;
@@ -331,17 +301,17 @@ bool CompositeEditCommand::isRemovableBlock(const Node* node)
return false;
}
-void CompositeEditCommand::insertNodeBefore(PassRefPtr<Node> insertChild, PassRefPtr<Node> refChild, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+void CompositeEditCommand::insertNodeBefore(PassRefPtrWillBeRawPtr<Node> insertChild, PassRefPtrWillBeRawPtr<Node> refChild, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
- ASSERT(!refChild->hasTagName(bodyTag));
+ ASSERT(!isHTMLBodyElement(*refChild));
applyCommandToComposite(InsertNodeBeforeCommand::create(insertChild, refChild, shouldAssumeContentIsAlwaysEditable));
}
-void CompositeEditCommand::insertNodeAfter(PassRefPtr<Node> insertChild, PassRefPtr<Node> refChild)
+void CompositeEditCommand::insertNodeAfter(PassRefPtrWillBeRawPtr<Node> insertChild, PassRefPtrWillBeRawPtr<Node> refChild)
{
ASSERT(insertChild);
ASSERT(refChild);
- ASSERT(!refChild->hasTagName(bodyTag));
+ ASSERT(!isHTMLBodyElement(*refChild));
ContainerNode* parent = refChild->parentNode();
ASSERT(parent);
ASSERT(!parent->isShadowRoot());
@@ -353,9 +323,9 @@ void CompositeEditCommand::insertNodeAfter(PassRefPtr<Node> insertChild, PassRef
}
}
-void CompositeEditCommand::insertNodeAt(PassRefPtr<Node> insertChild, const Position& editingPosition)
+void CompositeEditCommand::insertNodeAt(PassRefPtrWillBeRawPtr<Node> insertChild, const Position& editingPosition)
{
- ASSERT(isEditablePosition(editingPosition));
+ ASSERT(isEditablePosition(editingPosition, ContentIsEditable, DoNotUpdateStyle));
// For editing positions like [table, 0], insert before the table,
// likewise for replaced elements, brs, etc.
Position p = editingPosition.parentAnchoredEquivalent();
@@ -383,16 +353,16 @@ void CompositeEditCommand::insertNodeAt(PassRefPtr<Node> insertChild, const Posi
insertNodeAfter(insertChild, refChild);
}
-void CompositeEditCommand::appendNode(PassRefPtr<Node> node, PassRefPtr<ContainerNode> parent)
+void CompositeEditCommand::appendNode(PassRefPtrWillBeRawPtr<Node> node, PassRefPtrWillBeRawPtr<ContainerNode> parent)
{
ASSERT(canHaveChildrenForEditing(parent.get()));
applyCommandToComposite(AppendNodeCommand::create(parent, node));
}
-void CompositeEditCommand::removeChildrenInRange(PassRefPtr<Node> node, unsigned from, unsigned to)
+void CompositeEditCommand::removeChildrenInRange(PassRefPtrWillBeRawPtr<Node> node, unsigned from, unsigned to)
{
- Vector<RefPtr<Node> > children;
- Node* child = node->childNode(from);
+ WillBeHeapVector<RefPtrWillBeMember<Node> > children;
+ Node* child = node->traverseToChildAt(from);
for (unsigned i = from; child && i < to; i++, child = child->nextSibling())
children.append(child);
@@ -401,30 +371,30 @@ void CompositeEditCommand::removeChildrenInRange(PassRefPtr<Node> node, unsigned
removeNode(children[i].release());
}
-void CompositeEditCommand::removeNode(PassRefPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+void CompositeEditCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
if (!node || !node->nonShadowBoundaryParentNode())
return;
applyCommandToComposite(RemoveNodeCommand::create(node, shouldAssumeContentIsAlwaysEditable));
}
-void CompositeEditCommand::removeNodePreservingChildren(PassRefPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+void CompositeEditCommand::removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
applyCommandToComposite(RemoveNodePreservingChildrenCommand::create(node, shouldAssumeContentIsAlwaysEditable));
}
-void CompositeEditCommand::removeNodeAndPruneAncestors(PassRefPtr<Node> node, Node* excludeNode)
+void CompositeEditCommand::removeNodeAndPruneAncestors(PassRefPtrWillBeRawPtr<Node> node, Node* excludeNode)
{
ASSERT(node.get() != excludeNode);
- RefPtr<ContainerNode> parent = node->parentNode();
+ RefPtrWillBeRawPtr<ContainerNode> parent = node->parentNode();
removeNode(node);
prune(parent.release(), excludeNode);
}
-void CompositeEditCommand::moveRemainingSiblingsToNewParent(Node* node, Node* pastLastNodeToMove, PassRefPtr<Element> prpNewParent)
+void CompositeEditCommand::moveRemainingSiblingsToNewParent(Node* node, Node* pastLastNodeToMove, PassRefPtrWillBeRawPtr<Element> prpNewParent)
{
NodeVector nodesToRemove;
- RefPtr<Element> newParent = prpNewParent;
+ RefPtrWillBeRawPtr<Element> newParent = prpNewParent;
for (; node && node != pastLastNodeToMove; node = node->nextSibling())
nodesToRemove.append(node);
@@ -435,7 +405,7 @@ void CompositeEditCommand::moveRemainingSiblingsToNewParent(Node* node, Node* pa
}
}
-void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Position& position, Node* node)
+void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Position& position, Node& node)
{
int offset = (position.anchorType() == Position::PositionIsOffsetInAnchor) ? position.offsetInContainerNode() : 0;
updatePositionForNodeRemoval(position, node);
@@ -443,12 +413,12 @@ void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Positi
position.moveToOffset(offset);
}
-HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtr<HTMLElement> node)
+HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtrWillBeRawPtr<HTMLElement> node)
{
// It would also be possible to implement all of ReplaceNodeWithSpanCommand
// as a series of existing smaller edit commands. Someone who wanted to
// reduce the number of edit commands could do so here.
- RefPtr<ReplaceNodeWithSpanCommand> command = ReplaceNodeWithSpanCommand::create(node);
+ RefPtrWillBeRawPtr<ReplaceNodeWithSpanCommand> command = ReplaceNodeWithSpanCommand::create(node);
applyCommandToComposite(command);
// Returning a raw pointer here is OK because the command is retained by
// applyCommandToComposite (thus retaining the span), and the span is also
@@ -457,26 +427,26 @@ HTMLElement* CompositeEditCommand::replaceElementWithSpanPreservingChildrenAndAt
return command->spanElement();
}
-void CompositeEditCommand::prune(PassRefPtr<Node> node, Node* excludeNode)
+void CompositeEditCommand::prune(PassRefPtrWillBeRawPtr<Node> node, Node* excludeNode)
{
- if (RefPtr<Node> highestNodeToRemove = highestNodeToRemoveInPruning(node.get(), excludeNode))
+ if (RefPtrWillBeRawPtr<Node> highestNodeToRemove = highestNodeToRemoveInPruning(node.get(), excludeNode))
removeNode(highestNodeToRemove.release());
}
-void CompositeEditCommand::splitTextNode(PassRefPtr<Text> node, unsigned offset)
+void CompositeEditCommand::splitTextNode(PassRefPtrWillBeRawPtr<Text> node, unsigned offset)
{
applyCommandToComposite(SplitTextNodeCommand::create(node, offset));
}
-void CompositeEditCommand::splitElement(PassRefPtr<Element> element, PassRefPtr<Node> atChild)
+void CompositeEditCommand::splitElement(PassRefPtrWillBeRawPtr<Element> element, PassRefPtrWillBeRawPtr<Node> atChild)
{
applyCommandToComposite(SplitElementCommand::create(element, atChild));
}
-void CompositeEditCommand::mergeIdenticalElements(PassRefPtr<Element> prpFirst, PassRefPtr<Element> prpSecond)
+void CompositeEditCommand::mergeIdenticalElements(PassRefPtrWillBeRawPtr<Element> prpFirst, PassRefPtrWillBeRawPtr<Element> prpSecond)
{
- RefPtr<Element> first = prpFirst;
- RefPtr<Element> second = prpSecond;
+ RefPtrWillBeRawPtr<Element> first = prpFirst;
+ RefPtrWillBeRawPtr<Element> second = prpSecond;
ASSERT(!first->isDescendantOf(second.get()) && second != first);
if (first->nextSibling() != second) {
removeNode(second);
@@ -485,30 +455,30 @@ void CompositeEditCommand::mergeIdenticalElements(PassRefPtr<Element> prpFirst,
applyCommandToComposite(MergeIdenticalElementsCommand::create(first, second));
}
-void CompositeEditCommand::wrapContentsInDummySpan(PassRefPtr<Element> element)
+void CompositeEditCommand::wrapContentsInDummySpan(PassRefPtrWillBeRawPtr<Element> element)
{
applyCommandToComposite(WrapContentsInDummySpanCommand::create(element));
}
-void CompositeEditCommand::splitTextNodeContainingElement(PassRefPtr<Text> text, unsigned offset)
+void CompositeEditCommand::splitTextNodeContainingElement(PassRefPtrWillBeRawPtr<Text> text, unsigned offset)
{
applyCommandToComposite(SplitTextNodeContainingElementCommand::create(text, offset));
}
-void CompositeEditCommand::insertTextIntoNode(PassRefPtr<Text> node, unsigned offset, const String& text)
+void CompositeEditCommand::insertTextIntoNode(PassRefPtrWillBeRawPtr<Text> node, unsigned offset, const String& text)
{
if (!text.isEmpty())
applyCommandToComposite(InsertIntoTextNodeCommand::create(node, offset, text));
}
-void CompositeEditCommand::deleteTextFromNode(PassRefPtr<Text> node, unsigned offset, unsigned count)
+void CompositeEditCommand::deleteTextFromNode(PassRefPtrWillBeRawPtr<Text> node, unsigned offset, unsigned count)
{
applyCommandToComposite(DeleteFromTextNodeCommand::create(node, offset, count));
}
-void CompositeEditCommand::replaceTextInNode(PassRefPtr<Text> prpNode, unsigned offset, unsigned count, const String& replacementText)
+void CompositeEditCommand::replaceTextInNode(PassRefPtrWillBeRawPtr<Text> prpNode, unsigned offset, unsigned count, const String& replacementText)
{
- RefPtr<Text> node(prpNode);
+ RefPtrWillBeRawPtr<Text> node(prpNode);
applyCommandToComposite(DeleteFromTextNodeCommand::create(node, offset, count));
if (!replacementText.isEmpty())
applyCommandToComposite(InsertIntoTextNodeCommand::create(node, offset, replacementText));
@@ -521,13 +491,13 @@ Position CompositeEditCommand::replaceSelectedTextInNode(const String& text)
if (start.containerNode() != end.containerNode() || !start.containerNode()->isTextNode() || isTabSpanTextNode(start.containerNode()))
return Position();
- RefPtr<Text> textNode = start.containerText();
+ RefPtrWillBeRawPtr<Text> textNode = start.containerText();
replaceTextInNode(textNode, start.offsetInContainerNode(), end.offsetInContainerNode() - start.offsetInContainerNode(), text);
return Position(textNode.release(), start.offsetInContainerNode() + text.length());
}
-static void copyMarkers(const Vector<DocumentMarker*>& markerPointers, Vector<DocumentMarker>& markers)
+static void copyMarkers(const WillBeHeapVector<DocumentMarker*>& markerPointers, Vector<DocumentMarker>& markers)
{
size_t arraySize = markerPointers.size();
markers.reserveCapacity(arraySize);
@@ -535,16 +505,16 @@ static void copyMarkers(const Vector<DocumentMarker*>& markerPointers, Vector<Do
markers.append(*markerPointers[i]);
}
-void CompositeEditCommand::replaceTextInNodePreservingMarkers(PassRefPtr<Text> prpNode, unsigned offset, unsigned count, const String& replacementText)
+void CompositeEditCommand::replaceTextInNodePreservingMarkers(PassRefPtrWillBeRawPtr<Text> prpNode, unsigned offset, unsigned count, const String& replacementText)
{
- RefPtr<Text> node(prpNode);
- DocumentMarkerController* markerController = document().markers();
+ RefPtrWillBeRawPtr<Text> node(prpNode);
+ DocumentMarkerController& markerController = document().markers();
Vector<DocumentMarker> markers;
- copyMarkers(markerController->markersInRange(Range::create(document(), node.get(), offset, node.get(), offset + count).get(), DocumentMarker::AllMarkers()), markers);
+ copyMarkers(markerController.markersInRange(Range::create(document(), node.get(), offset, node.get(), offset + count).get(), DocumentMarker::AllMarkers()), markers);
replaceTextInNode(node, offset, count, replacementText);
- RefPtr<Range> newRange = Range::create(document(), node.get(), offset, node.get(), offset + replacementText.length());
+ RefPtrWillBeRawPtr<Range> newRange = Range::create(document(), node.get(), offset, node.get(), offset + replacementText.length());
for (size_t i = 0; i < markers.size(); ++i)
- markerController->addMarker(newRange.get(), markers[i].type(), markers[i].description());
+ markerController.addMarker(newRange.get(), markers[i].type(), markers[i].description());
}
Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos)
@@ -560,52 +530,53 @@ Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos)
case Position::PositionIsOffsetInAnchor:
break;
case Position::PositionIsBeforeAnchor:
- return positionInParentBeforeNode(pos.anchorNode());
+ return positionInParentBeforeNode(*pos.anchorNode());
case Position::PositionIsAfterAnchor:
- return positionInParentAfterNode(pos.anchorNode());
+ return positionInParentAfterNode(*pos.anchorNode());
}
Node* tabSpan = tabSpanNode(pos.containerNode());
+ ASSERT(tabSpan);
if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode()))
- return positionInParentBeforeNode(tabSpan);
+ return positionInParentBeforeNode(*tabSpan);
if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode()))
- return positionInParentAfterNode(tabSpan);
+ return positionInParentAfterNode(*tabSpan);
splitTextNodeContainingElement(toText(pos.containerNode()), pos.offsetInContainerNode());
- return positionInParentBeforeNode(tabSpan);
+ return positionInParentBeforeNode(*tabSpan);
}
-void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtr<Node> node, const Position& pos)
+void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtrWillBeRawPtr<Node> node, const Position& pos)
{
// insert node before, after, or at split of tab span
insertNodeAt(node, positionOutsideTabSpan(pos));
}
-void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements, bool sanitizeMarkup)
+void CompositeEditCommand::deleteSelection(bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup)
{
if (endingSelection().isRange())
- applyCommandToComposite(DeleteSelectionCommand::create(document(), smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements, sanitizeMarkup));
+ applyCommandToComposite(DeleteSelectionCommand::create(document(), smartDelete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup));
}
-void CompositeEditCommand::deleteSelection(const VisibleSelection &selection, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements, bool sanitizeMarkup)
+void CompositeEditCommand::deleteSelection(const VisibleSelection &selection, bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup)
{
if (selection.isRange())
- applyCommandToComposite(DeleteSelectionCommand::create(selection, smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements, sanitizeMarkup));
+ applyCommandToComposite(DeleteSelectionCommand::create(selection, smartDelete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup));
}
-void CompositeEditCommand::removeCSSProperty(PassRefPtr<Element> element, CSSPropertyID property)
+void CompositeEditCommand::removeCSSProperty(PassRefPtrWillBeRawPtr<Element> element, CSSPropertyID property)
{
applyCommandToComposite(RemoveCSSPropertyCommand::create(document(), element, property));
}
-void CompositeEditCommand::removeNodeAttribute(PassRefPtr<Element> element, const QualifiedName& attribute)
+void CompositeEditCommand::removeNodeAttribute(PassRefPtrWillBeRawPtr<Element> element, const QualifiedName& attribute)
{
setNodeAttribute(element, attribute, AtomicString());
}
-void CompositeEditCommand::setNodeAttribute(PassRefPtr<Element> element, const QualifiedName& attribute, const AtomicString& value)
+void CompositeEditCommand::setNodeAttribute(PassRefPtrWillBeRawPtr<Element> element, const QualifiedName& attribute, const AtomicString& value)
{
applyCommandToComposite(SetNodeAttributeCommand::create(element, attribute, value));
}
@@ -661,9 +632,9 @@ void CompositeEditCommand::rebalanceWhitespaceAt(const Position& position)
rebalanceWhitespaceOnTextSubstring(toText(node), position.offsetInContainerNode(), position.offsetInContainerNode());
}
-void CompositeEditCommand::rebalanceWhitespaceOnTextSubstring(PassRefPtr<Text> prpTextNode, int startOffset, int endOffset)
+void CompositeEditCommand::rebalanceWhitespaceOnTextSubstring(PassRefPtrWillBeRawPtr<Text> prpTextNode, int startOffset, int endOffset)
{
- RefPtr<Text> textNode = prpTextNode;
+ RefPtrWillBeRawPtr<Text> textNode = prpTextNode;
String text = textNode->data();
ASSERT(!text.isEmpty());
@@ -724,7 +695,7 @@ void CompositeEditCommand::replaceCollapsibleWhitespaceWithNonBreakingSpaceIfNee
if (!isCollapsibleWhitespace(visiblePosition.characterAfter()))
return;
Position pos = visiblePosition.deepEquivalent().downstream();
- if (!pos.containerNode() || !pos.containerNode()->isTextNode() || pos.containerNode()->hasTagName(brTag))
+ if (!pos.containerNode() || !pos.containerNode()->isTextNode())
return;
replaceTextInNodePreservingMarkers(pos.containerText(), pos.offsetInContainerNode(), 1, nonBreakingSpaceString());
}
@@ -740,7 +711,7 @@ void CompositeEditCommand::rebalanceWhitespace()
rebalanceWhitespaceAt(selection.end());
}
-void CompositeEditCommand::deleteInsignificantText(PassRefPtr<Text> textNode, unsigned start, unsigned end)
+void CompositeEditCommand::deleteInsignificantText(PassRefPtrWillBeRawPtr<Text> textNode, unsigned start, unsigned end)
{
if (!textNode || start >= end)
return;
@@ -789,8 +760,7 @@ void CompositeEditCommand::deleteInsignificantText(PassRefPtr<Text> textNode, un
bool indicesIntersect = start <= gapEnd && end >= gapStart;
int gapLen = gapEnd - gapStart;
if (indicesIntersect && gapLen > 0) {
- gapStart = max(gapStart, start);
- gapEnd = min(gapEnd, end);
+ gapStart = std::max(gapStart, start);
if (str.isNull())
str = textNode->data().substring(start, end - start);
// remove text in the gap
@@ -829,7 +799,7 @@ void CompositeEditCommand::deleteInsignificantText(const Position& start, const
if (comparePositions(start, end) >= 0)
return;
- Vector<RefPtr<Text> > nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Text> > nodes;
for (Node* node = start.deprecatedNode(); node; node = NodeTraversal::next(*node)) {
if (node->isTextNode())
nodes.append(toText(node));
@@ -851,52 +821,52 @@ void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos
deleteInsignificantText(pos, end);
}
-PassRefPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRefPtr<Element> container)
+PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRefPtrWillBeRawPtr<Element> container)
{
if (!container)
- return 0;
+ return nullptr;
document().updateLayoutIgnorePendingStylesheets();
// Should assert isRenderBlockFlow || isInlineFlow when deletion improves. See 4244964.
ASSERT(container->renderer());
- RefPtr<Node> placeholder = createBlockPlaceholderElement(document());
+ RefPtrWillBeRawPtr<Node> placeholder = createBlockPlaceholderElement(document());
appendNode(placeholder, container);
return placeholder.release();
}
-PassRefPtr<Node> CompositeEditCommand::insertBlockPlaceholder(const Position& pos)
+PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::insertBlockPlaceholder(const Position& pos)
{
if (pos.isNull())
- return 0;
+ return nullptr;
// Should assert isRenderBlockFlow || isInlineFlow when deletion improves. See 4244964.
ASSERT(pos.deprecatedNode()->renderer());
- RefPtr<Node> placeholder = createBlockPlaceholderElement(document());
+ RefPtrWillBeRawPtr<Node> placeholder = createBlockPlaceholderElement(document());
insertNodeAt(placeholder, pos);
return placeholder.release();
}
-PassRefPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* container)
+PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* container)
{
if (!container)
- return 0;
+ return nullptr;
document().updateLayoutIgnorePendingStylesheets();
RenderObject* renderer = container->renderer();
if (!renderer || !renderer->isRenderBlockFlow())
- return 0;
+ return nullptr;
// append the placeholder to make sure it follows
// any unrendered blocks
RenderBlock* block = toRenderBlock(renderer);
- if (block->height() == 0 || (block->isListItem() && block->isEmpty()))
+ if (block->height() == 0 || (block->isListItem() && toRenderListItem(block)->isEmpty()))
return appendBlockPlaceholder(container);
- return 0;
+ return nullptr;
}
// Assumes that the position is at a placeholder and does the removal without much checking.
@@ -905,7 +875,7 @@ void CompositeEditCommand::removePlaceholderAt(const Position& p)
ASSERT(lineBreakExistsAtPosition(p));
// We are certain that the position is at a line break, but it may be a br or a preserved newline.
- if (p.anchorNode()->hasTagName(brTag)) {
+ if (isHTMLBRElement(*p.anchorNode())) {
removeNode(p.anchorNode());
return;
}
@@ -913,9 +883,9 @@ void CompositeEditCommand::removePlaceholderAt(const Position& p)
deleteTextFromNode(toText(p.anchorNode()), p.offsetInContainerNode(), 1);
}
-PassRefPtr<Node> CompositeEditCommand::insertNewDefaultParagraphElementAt(const Position& position)
+PassRefPtrWillBeRawPtr<Element> CompositeEditCommand::insertNewDefaultParagraphElementAt(const Position& position)
{
- RefPtr<Element> paragraphElement = createDefaultParagraphElement(document());
+ RefPtrWillBeRawPtr<Element> paragraphElement = createDefaultParagraphElement(document());
paragraphElement->appendChild(createBreakElement(document()));
insertNodeAt(paragraphElement, position);
return paragraphElement.release();
@@ -923,12 +893,9 @@ PassRefPtr<Node> CompositeEditCommand::insertNewDefaultParagraphElementAt(const
// If the paragraph is not entirely within it's own block, create one and move the paragraph into
// it, and return that block. Otherwise return 0.
-PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary(const Position& pos)
+PassRefPtrWillBeRawPtr<Element> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary(const Position& pos)
{
- if (pos.isNull())
- return 0;
-
- document().updateLayoutIgnorePendingStylesheets();
+ ASSERT(isEditablePosition(pos, ContentIsEditable, DoNotUpdateStyle));
// It's strange that this function is responsible for verifying that pos has not been invalidated
// by an earlier call to this function. The caller, applyBlockStyle, should do this.
@@ -944,7 +911,7 @@ PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessar
// If there are no VisiblePositions in the same block as pos then
// upstreamStart will be outside the paragraph
if (comparePositions(pos, upstreamStart) < 0)
- return 0;
+ return nullptr;
// Perform some checks to see if we need to perform work in this function.
if (isBlock(upstreamStart.deprecatedNode())) {
@@ -959,26 +926,33 @@ PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessar
if (!upstreamEnd.deprecatedNode()->isDescendantOf(upstreamStart.deprecatedNode())) {
// If the paragraph end is a descendant of paragraph start, then we need to run
// the rest of this function. If not, we can bail here.
- return 0;
+ return nullptr;
}
} else if (enclosingBlock(upstreamEnd.deprecatedNode()) != upstreamStart.deprecatedNode()) {
- // The visibleEnd. It must be an ancestor of the paragraph start.
+ // It should be an ancestor of the paragraph start.
// We can bail as we have a full block to work with.
- ASSERT(upstreamStart.deprecatedNode()->isDescendantOf(enclosingBlock(upstreamEnd.deprecatedNode())));
- return 0;
+ return nullptr;
} else if (isEndOfEditableOrNonEditableContent(visibleEnd)) {
// At the end of the editable region. We can bail here as well.
- return 0;
+ return nullptr;
}
}
- RefPtr<Node> newBlock = insertNewDefaultParagraphElementAt(upstreamStart);
+ if (visibleParagraphEnd.isNull())
+ return nullptr;
+
+ RefPtrWillBeRawPtr<Element> newBlock = insertNewDefaultParagraphElementAt(upstreamStart);
- bool endWasBr = visibleParagraphEnd.deepEquivalent().deprecatedNode()->hasTagName(brTag);
+ bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().deprecatedNode());
+ // Inserting default paragraph element can change visible position. We
+ // should update visible positions before use them.
+ visiblePos = VisiblePosition(pos, VP_DEFAULT_AFFINITY);
+ visibleParagraphStart = VisiblePosition(startOfParagraph(visiblePos));
+ visibleParagraphEnd = VisiblePosition(endOfParagraph(visiblePos));
moveParagraphs(visibleParagraphStart, visibleParagraphEnd, VisiblePosition(firstPositionInNode(newBlock.get())));
- if (newBlock->lastChild() && newBlock->lastChild()->hasTagName(brTag) && !endWasBr)
+ if (newBlock->lastChild() && isHTMLBRElement(*newBlock->lastChild()) && !endWasBr)
removeNode(newBlock->lastChild());
return newBlock.release();
@@ -1001,21 +975,25 @@ void CompositeEditCommand::pushAnchorElementDown(Node* anchorNode)
// Clone the paragraph between start and end under blockElement,
// preserving the hierarchy up to outerNode.
-void CompositeEditCommand::cloneParagraphUnderNewElement(Position& start, Position& end, Node* passedOuterNode, Element* blockElement)
+void CompositeEditCommand::cloneParagraphUnderNewElement(const Position& start, const Position& end, Node* passedOuterNode, Element* blockElement)
{
+ ASSERT(comparePositions(start, end) <= 0);
+ ASSERT(passedOuterNode);
+ ASSERT(blockElement);
+
// First we clone the outerNode
- RefPtr<Node> lastNode;
- RefPtr<Node> outerNode = passedOuterNode;
+ RefPtrWillBeRawPtr<Node> lastNode = nullptr;
+ RefPtrWillBeRawPtr<Node> outerNode = passedOuterNode;
if (outerNode->isRootEditableElement()) {
lastNode = blockElement;
} else {
- lastNode = outerNode->cloneNode(isTableElement(outerNode.get()));
+ lastNode = outerNode->cloneNode(isRenderedTableElement(outerNode.get()));
appendNode(lastNode, blockElement);
}
if (start.anchorNode() != outerNode && lastNode->isElementNode() && start.anchorNode()->isDescendantOf(outerNode.get())) {
- Vector<RefPtr<Node> > ancestors;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > ancestors;
// Insert each node from innerNode to outerNode (excluded) in a list.
for (Node* n = start.deprecatedNode(); n && n != outerNode; n = n->parentNode())
@@ -1025,7 +1003,7 @@ void CompositeEditCommand::cloneParagraphUnderNewElement(Position& start, Positi
for (size_t i = ancestors.size(); i != 0; --i) {
Node* item = ancestors[i - 1].get();
- RefPtr<Node> child = item->cloneNode(isTableElement(item));
+ RefPtrWillBeRawPtr<Node> child = item->cloneNode(isRenderedTableElement(item));
appendNode(child, toElement(lastNode));
lastNode = child.release();
}
@@ -1043,21 +1021,27 @@ void CompositeEditCommand::cloneParagraphUnderNewElement(Position& start, Positi
// If end is not a descendant of outerNode we need to
// find the first common ancestor to increase the scope
// of our nextSibling traversal.
- while (!end.deprecatedNode()->isDescendantOf(outerNode.get())) {
+ while (outerNode && !end.deprecatedNode()->isDescendantOf(outerNode.get())) {
outerNode = outerNode->parentNode();
}
- RefPtr<Node> startNode = start.deprecatedNode();
- for (RefPtr<Node> node = NodeTraversal::nextSkippingChildren(*startNode, outerNode.get()); node; node = NodeTraversal::nextSkippingChildren(*node, outerNode.get())) {
+ if (!outerNode)
+ return;
+
+ RefPtrWillBeRawPtr<Node> startNode = start.deprecatedNode();
+ for (RefPtrWillBeRawPtr<Node> node = NodeTraversal::nextSkippingChildren(*startNode, outerNode.get()); node; node = NodeTraversal::nextSkippingChildren(*node, outerNode.get())) {
// Move lastNode up in the tree as much as node was moved up in the
// tree by NodeTraversal::nextSkippingChildren, so that the relative depth between
// node and the original start node is maintained in the clone.
- while (startNode->parentNode() != node->parentNode()) {
+ while (startNode && lastNode && startNode->parentNode() != node->parentNode()) {
startNode = startNode->parentNode();
lastNode = lastNode->parentNode();
}
- RefPtr<Node> clonedNode = node->cloneNode(true);
+ if (!lastNode || !lastNode->parentNode())
+ return;
+
+ RefPtrWillBeRawPtr<Node> clonedNode = node->cloneNode(true);
insertNodeAfter(clonedNode, lastNode);
lastNode = clonedNode.release();
if (node == end.deprecatedNode() || end.deprecatedNode()->isDescendantOf(node.get()))
@@ -1087,7 +1071,7 @@ void CompositeEditCommand::cleanupAfterDeletion(VisiblePosition destination)
return;
// Normally deletion will leave a br as a placeholder.
- if (node->hasTagName(brTag)) {
+ if (isHTMLBRElement(*node)) {
removeNodeAndPruneAncestors(node, destinationNode);
// If the selection to move was empty and in an empty block that
@@ -1132,12 +1116,14 @@ void CompositeEditCommand::moveParagraphWithClones(const VisiblePosition& startO
// We upstream() the end and downstream() the start so that we don't include collapsed whitespace in the move.
// When we paste a fragment, spaces after the end and before the start are treated as though they were rendered.
Position start = startOfParagraphToMove.deepEquivalent().downstream();
- Position end = endOfParagraphToMove.deepEquivalent().upstream();
+ Position end = startOfParagraphToMove == endOfParagraphToMove ? start : endOfParagraphToMove.deepEquivalent().upstream();
+ if (comparePositions(start, end) > 0)
+ end = start;
cloneParagraphUnderNewElement(start, end, outerNode, blockElement);
setEndingSelection(VisibleSelection(start, end, DOWNSTREAM));
- deleteSelection(false, false, false, false);
+ deleteSelection(false, false, false);
// There are bugs in deletion when it removes a fully selected table/list.
// It expands and removes the entire table/list, but will let content
@@ -1171,7 +1157,7 @@ void CompositeEditCommand::moveParagraph(const VisiblePosition& startOfParagraph
void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagraphToMove, const VisiblePosition& endOfParagraphToMove, const VisiblePosition& destination, bool preserveSelection, bool preserveStyle, Node* constrainingAncestor)
{
- if (startOfParagraphToMove == destination)
+ if (startOfParagraphToMove == destination || startOfParagraphToMove.isNull())
return;
int startIndex = -1;
@@ -1191,13 +1177,13 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
startIndex = 0;
if (startInParagraph) {
- RefPtr<Range> startRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleStart.deepEquivalent().parentAnchoredEquivalent());
+ RefPtrWillBeRawPtr<Range> startRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleStart.deepEquivalent().parentAnchoredEquivalent());
startIndex = TextIterator::rangeLength(startRange.get(), true);
}
endIndex = 0;
if (endInParagraph) {
- RefPtr<Range> endRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
+ RefPtrWillBeRawPtr<Range> endRange = Range::create(document(), startOfParagraphToMove.deepEquivalent().parentAnchoredEquivalent(), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
endIndex = TextIterator::rangeLength(endRange.get(), true);
}
}
@@ -1214,17 +1200,17 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
// start and end can't be used directly to create a Range; they are "editing positions"
Position startRangeCompliant = start.parentAnchoredEquivalent();
Position endRangeCompliant = end.parentAnchoredEquivalent();
- RefPtr<Range> range = Range::create(document(), startRangeCompliant.deprecatedNode(), startRangeCompliant.deprecatedEditingOffset(), endRangeCompliant.deprecatedNode(), endRangeCompliant.deprecatedEditingOffset());
+ RefPtrWillBeRawPtr<Range> range = Range::create(document(), startRangeCompliant.deprecatedNode(), startRangeCompliant.deprecatedEditingOffset(), endRangeCompliant.deprecatedNode(), endRangeCompliant.deprecatedEditingOffset());
// FIXME: This is an inefficient way to preserve style on nodes in the paragraph to move. It
// shouldn't matter though, since moved paragraphs will usually be quite small.
- RefPtr<DocumentFragment> fragment = startOfParagraphToMove != endOfParagraphToMove ?
- createFragmentFromMarkup(document(), createMarkup(range.get(), 0, DoNotAnnotateForInterchange, true, DoNotResolveURLs, constrainingAncestor), "") : 0;
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = startOfParagraphToMove != endOfParagraphToMove ?
+ createFragmentFromMarkup(document(), createMarkup(range.get(), 0, DoNotAnnotateForInterchange, true, DoNotResolveURLs, constrainingAncestor), "") : nullptr;
// A non-empty paragraph's style is moved when we copy and move it. We don't move
// anything if we're given an empty paragraph, but an empty paragraph can have style
// too, <div><b><br></b></div> for example. Save it so that we can preserve it later.
- RefPtr<EditingStyle> styleInEmptyParagraph;
+ RefPtrWillBeRawPtr<EditingStyle> styleInEmptyParagraph = nullptr;
if (startOfParagraphToMove == endOfParagraphToMove && preserveStyle) {
styleInEmptyParagraph = EditingStyle::create(startOfParagraphToMove.deepEquivalent());
styleInEmptyParagraph->mergeTypingStyle(&document());
@@ -1236,7 +1222,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
setEndingSelection(VisibleSelection(start, end, DOWNSTREAM));
document().frame()->spellChecker().clearMisspellingsAndBadGrammar(endingSelection());
- deleteSelection(false, false, false, false);
+ deleteSelection(false, false, false);
ASSERT(destination.deepEquivalent().inDocument());
cleanupAfterDeletion(destination);
@@ -1258,7 +1244,7 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
document().updateLayoutIgnorePendingStylesheets();
}
- RefPtr<Range> startToDestinationRange(Range::create(document(), firstPositionInNode(document().documentElement()), destination.deepEquivalent().parentAnchoredEquivalent()));
+ RefPtrWillBeRawPtr<Range> startToDestinationRange(Range::create(document(), firstPositionInNode(document().documentElement()), destination.deepEquivalent().parentAnchoredEquivalent()));
destinationIndex = TextIterator::rangeLength(startToDestinationRange.get(), true);
setEndingSelection(VisibleSelection(destination, originalIsDirectional));
@@ -1276,40 +1262,42 @@ void CompositeEditCommand::moveParagraphs(const VisiblePosition& startOfParagrap
applyStyle(styleInEmptyParagraph.get());
if (preserveSelection && startIndex != -1) {
- // Fragment creation (using createMarkup) incorrectly uses regular
- // spaces instead of nbsps for some spaces that were rendered (11475), which
- // causes spaces to be collapsed during the move operation. This results
- // in a call to rangeFromLocationAndLength with a location past the end
- // of the document (which will return null).
- RefPtr<Range> start = PlainTextRange(destinationIndex + startIndex).createRangeForSelection(*document().documentElement());
- RefPtr<Range> end = PlainTextRange(destinationIndex + endIndex).createRangeForSelection(*document().documentElement());
- if (start && end)
- setEndingSelection(VisibleSelection(start->startPosition(), end->startPosition(), DOWNSTREAM, originalIsDirectional));
+ if (Element* documentElement = document().documentElement()) {
+ // Fragment creation (using createMarkup) incorrectly uses regular
+ // spaces instead of nbsps for some spaces that were rendered (11475), which
+ // causes spaces to be collapsed during the move operation. This results
+ // in a call to rangeFromLocationAndLength with a location past the end
+ // of the document (which will return null).
+ RefPtrWillBeRawPtr<Range> start = PlainTextRange(destinationIndex + startIndex).createRangeForSelection(*documentElement);
+ RefPtrWillBeRawPtr<Range> end = PlainTextRange(destinationIndex + endIndex).createRangeForSelection(*documentElement);
+ if (start && end)
+ setEndingSelection(VisibleSelection(start->startPosition(), end->startPosition(), DOWNSTREAM, originalIsDirectional));
+ }
}
}
// FIXME: Send an appropriate shouldDeleteRange call.
bool CompositeEditCommand::breakOutOfEmptyListItem()
{
- RefPtr<Node> emptyListItem = enclosingEmptyListItem(endingSelection().visibleStart());
+ RefPtrWillBeRawPtr<Node> emptyListItem = enclosingEmptyListItem(endingSelection().visibleStart());
if (!emptyListItem)
return false;
- RefPtr<EditingStyle> style = EditingStyle::create(endingSelection().start());
+ RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(endingSelection().start());
style->mergeTypingStyle(&document());
- RefPtr<ContainerNode> listNode = emptyListItem->parentNode();
+ RefPtrWillBeRawPtr<ContainerNode> listNode = emptyListItem->parentNode();
// FIXME: Can't we do something better when the immediate parent wasn't a list node?
if (!listNode
- || (!listNode->hasTagName(ulTag) && !listNode->hasTagName(olTag))
+ || (!isHTMLUListElement(*listNode) && !isHTMLOListElement(*listNode))
|| !listNode->rendererIsEditable()
|| listNode == emptyListItem->rootEditableElement())
return false;
- RefPtr<Element> newBlock = 0;
+ RefPtrWillBeRawPtr<Element> newBlock = nullptr;
if (ContainerNode* blockEnclosingList = listNode->parentNode()) {
- if (blockEnclosingList->hasTagName(liTag)) { // listNode is inside another list item
- if (visiblePositionAfterNode(blockEnclosingList) == visiblePositionAfterNode(listNode.get())) {
+ if (isHTMLLIElement(*blockEnclosingList)) { // listNode is inside another list item
+ if (visiblePositionAfterNode(*blockEnclosingList) == visiblePositionAfterNode(*listNode)) {
// If listNode appears at the end of the outer list item, then move listNode outside of this list item
// e.g. <ul><li>hello <ul><li><br></li></ul> </li></ul> should become <ul><li>hello</li> <ul><li><br></li></ul> </ul> after this section
// If listNode does NOT appear at the end, then we should consider it as a regular paragraph.
@@ -1319,15 +1307,15 @@ bool CompositeEditCommand::breakOutOfEmptyListItem()
newBlock = createListItemElement(document());
}
// If listNode does NOT appear at the end of the outer list item, then behave as if in a regular paragraph.
- } else if (blockEnclosingList->hasTagName(olTag) || blockEnclosingList->hasTagName(ulTag)) {
+ } else if (isHTMLOListElement(*blockEnclosingList) || isHTMLUListElement(*blockEnclosingList)) {
newBlock = createListItemElement(document());
}
}
if (!newBlock)
newBlock = createDefaultParagraphElement(document());
- RefPtr<Node> previousListNode = emptyListItem->isElementNode() ? toElement(emptyListItem)->previousElementSibling(): emptyListItem->previousSibling();
- RefPtr<Node> nextListNode = emptyListItem->isElementNode() ? toElement(emptyListItem)->nextElementSibling(): emptyListItem->nextSibling();
+ RefPtrWillBeRawPtr<Node> previousListNode = emptyListItem->isElementNode() ? ElementTraversal::previousSibling(*emptyListItem): emptyListItem->previousSibling();
+ RefPtrWillBeRawPtr<Node> nextListNode = emptyListItem->isElementNode() ? ElementTraversal::nextSibling(*emptyListItem): emptyListItem->nextSibling();
if (isListItem(nextListNode.get()) || isListElement(nextListNode.get())) {
// If emptyListItem follows another list item or nested list, split the list node.
if (isListItem(previousListNode.get()) || isListElement(previousListNode.get()))
@@ -1375,7 +1363,7 @@ bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph()
if (enclosingNodeOfType(previous.deepEquivalent(), &isMailBlockquote))
return false;
- RefPtr<Node> br = createBreakElement(document());
+ RefPtrWillBeRawPtr<Node> br = createBreakElement(document());
// We want to replace this quoted paragraph with an unquoted one, so insert a br
// to hold the caret before the highest blockquote.
insertNodeBefore(br, highestBlockquote);
@@ -1392,9 +1380,9 @@ bool CompositeEditCommand::breakOutOfEmptyMailBlockquotedParagraph()
Position caretPos(caret.deepEquivalent().downstream());
// A line break is either a br or a preserved newline.
- ASSERT(caretPos.deprecatedNode()->hasTagName(brTag) || (caretPos.deprecatedNode()->isTextNode() && caretPos.deprecatedNode()->renderer()->style()->preserveNewline()));
+ ASSERT(isHTMLBRElement(caretPos.deprecatedNode()) || (caretPos.deprecatedNode()->isTextNode() && caretPos.deprecatedNode()->renderer()->style()->preserveNewline()));
- if (caretPos.deprecatedNode()->hasTagName(brTag))
+ if (isHTMLBRElement(*caretPos.deprecatedNode()))
removeNodeAndPruneAncestors(caretPos.deprecatedNode());
else if (caretPos.deprecatedNode()->isTextNode()) {
ASSERT(caretPos.deprecatedEditingOffset() == 0);
@@ -1446,7 +1434,7 @@ Position CompositeEditCommand::positionAvoidingSpecialElementBoundary(const Posi
if (lineBreakExistsAtVisiblePosition(visiblePos) && downstream.deprecatedNode()->isDescendantOf(enclosingAnchor))
return original;
- result = positionInParentAfterNode(enclosingAnchor);
+ result = positionInParentAfterNode(*enclosingAnchor);
}
// If visually just before an anchor, insert *outside* the anchor unless it's the first
// VisiblePosition in a paragraph, to match NSTextView.
@@ -1460,7 +1448,7 @@ Position CompositeEditCommand::positionAvoidingSpecialElementBoundary(const Posi
if (!enclosingAnchor)
return original;
- result = positionInParentBeforeNode(enclosingAnchor);
+ result = positionInParentBeforeNode(*enclosingAnchor);
}
}
@@ -1472,23 +1460,25 @@ Position CompositeEditCommand::positionAvoidingSpecialElementBoundary(const Posi
// Splits the tree parent by parent until we reach the specified ancestor. We use VisiblePositions
// to determine if the split is necessary. Returns the last split node.
-PassRefPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start, Node* end, bool shouldSplitAncestor)
+PassRefPtrWillBeRawPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start, Node* end, bool shouldSplitAncestor)
{
ASSERT(start);
ASSERT(end);
ASSERT(start != end);
- RefPtr<Node> node;
if (shouldSplitAncestor && end->parentNode())
end = end->parentNode();
+ if (!start->isDescendantOf(end))
+ return end;
- RefPtr<Node> endNode = end;
- for (node = start; node && node->parentNode() != endNode; node = node->parentNode()) {
+ RefPtrWillBeRawPtr<Node> endNode = end;
+ RefPtrWillBeRawPtr<Node> node = nullptr;
+ for (node = start; node->parentNode() != endNode; node = node->parentNode()) {
if (!node->parentNode()->isElementNode())
break;
// Do not split a node when doing so introduces an empty node.
- VisiblePosition positionInParent = firstPositionInNode(node->parentNode());
- VisiblePosition positionInNode = firstPositionInOrBeforeNode(node.get());
+ VisiblePosition positionInParent(firstPositionInNode(node->parentNode()));
+ VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get()));
if (positionInParent != positionInNode)
splitElement(toElement(node->parentNode()), node);
}
@@ -1496,10 +1486,16 @@ PassRefPtr<Node> CompositeEditCommand::splitTreeToNode(Node* start, Node* end, b
return node.release();
}
-PassRefPtr<Element> createBlockPlaceholderElement(Document& document)
+PassRefPtrWillBeRawPtr<Element> createBlockPlaceholderElement(Document& document)
+{
+ return document.createElement(brTag, false);
+}
+
+void CompositeEditCommand::trace(Visitor* visitor)
{
- RefPtr<Element> breakNode = document.createElement(brTag, false);
- return breakNode.release();
+ visitor->trace(m_commands);
+ visitor->trace(m_composition);
+ EditCommand::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.h b/chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.h
index 273ed51d520..bf2eba91f79 100644
--- a/chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/CompositeEditCommand.h
@@ -26,7 +26,7 @@
#ifndef CompositeEditCommand_h
#define CompositeEditCommand_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/editing/EditCommand.h"
#include "core/editing/UndoStep.h"
#include "wtf/Vector.h"
@@ -38,14 +38,14 @@ class Element;
class HTMLElement;
class Text;
-class EditCommandComposition : public UndoStep {
+class EditCommandComposition FINAL : public UndoStep {
public:
- static PassRefPtr<EditCommandComposition> create(Document*, const VisibleSelection&, const VisibleSelection&, EditAction);
+ static PassRefPtrWillBeRawPtr<EditCommandComposition> create(Document*, const VisibleSelection&, const VisibleSelection&, EditAction);
- virtual bool belongsTo(const Frame&) const OVERRIDE;
+ virtual bool belongsTo(const LocalFrame&) const OVERRIDE;
virtual void unapply() OVERRIDE;
virtual void reapply() OVERRIDE;
- EditAction editingAction() const OVERRIDE { return m_editAction; }
+ virtual EditAction editingAction() const OVERRIDE { return m_editAction; }
void append(SimpleEditCommand*);
bool wasCreateLinkCommand() const { return m_editAction == EditActionCreateLink; }
@@ -56,15 +56,17 @@ public:
Element* startingRootEditableElement() const { return m_startingRootEditableElement.get(); }
Element* endingRootEditableElement() const { return m_endingRootEditableElement.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
EditCommandComposition(Document*, const VisibleSelection& startingSelection, const VisibleSelection& endingSelection, EditAction);
- RefPtr<Document> m_document;
+ RefPtrWillBeMember<Document> m_document;
VisibleSelection m_startingSelection;
VisibleSelection m_endingSelection;
- Vector<RefPtr<SimpleEditCommand> > m_commands;
- RefPtr<Element> m_startingRootEditableElement;
- RefPtr<Element> m_endingRootEditableElement;
+ WillBeHeapVector<RefPtrWillBeMember<SimpleEditCommand> > m_commands;
+ RefPtrWillBeMember<Element> m_startingRootEditableElement;
+ RefPtrWillBeMember<Element> m_endingRootEditableElement;
EditAction m_editAction;
};
@@ -77,77 +79,76 @@ public:
EditCommandComposition* composition() { return m_composition.get(); }
EditCommandComposition* ensureComposition();
- virtual bool isCreateLinkCommand() const;
virtual bool isTypingCommand() const;
virtual bool preservesTypingStyle() const;
- virtual bool shouldRetainAutocorrectionIndicator() const;
virtual void setShouldRetainAutocorrectionIndicator(bool);
virtual bool shouldStopCaretBlinking() const { return false; }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
explicit CompositeEditCommand(Document&);
//
// sugary-sweet convenience functions to help create and apply edit commands in composite commands
//
- void appendNode(PassRefPtr<Node>, PassRefPtr<ContainerNode> parent);
- void applyCommandToComposite(PassRefPtr<EditCommand>);
- void applyCommandToComposite(PassRefPtr<CompositeEditCommand>, const VisibleSelection&);
+ void appendNode(PassRefPtrWillBeRawPtr<Node>, PassRefPtrWillBeRawPtr<ContainerNode> parent);
+ void applyCommandToComposite(PassRefPtrWillBeRawPtr<EditCommand>);
+ void applyCommandToComposite(PassRefPtrWillBeRawPtr<CompositeEditCommand>, const VisibleSelection&);
void applyStyle(const EditingStyle*, EditAction = EditActionChangeAttributes);
void applyStyle(const EditingStyle*, const Position& start, const Position& end, EditAction = EditActionChangeAttributes);
- void applyStyledElement(PassRefPtr<Element>);
- void removeStyledElement(PassRefPtr<Element>);
- void deleteSelection(bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = true, bool sanitizeMarkup = true);
- void deleteSelection(const VisibleSelection&, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = true, bool sanitizeMarkup = true);
- virtual void deleteTextFromNode(PassRefPtr<Text>, unsigned offset, unsigned count);
+ void applyStyledElement(PassRefPtrWillBeRawPtr<Element>);
+ void removeStyledElement(PassRefPtrWillBeRawPtr<Element>);
+ void deleteSelection(bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool expandForSpecialElements = true, bool sanitizeMarkup = true);
+ void deleteSelection(const VisibleSelection&, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool expandForSpecialElements = true, bool sanitizeMarkup = true);
+ virtual void deleteTextFromNode(PassRefPtrWillBeRawPtr<Text>, unsigned offset, unsigned count);
bool isRemovableBlock(const Node*);
- void insertNodeAfter(PassRefPtr<Node>, PassRefPtr<Node> refChild);
- void insertNodeAt(PassRefPtr<Node>, const Position&);
- void insertNodeAtTabSpanPosition(PassRefPtr<Node>, const Position&);
- void insertNodeBefore(PassRefPtr<Node>, PassRefPtr<Node> refChild, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
+ void insertNodeAfter(PassRefPtrWillBeRawPtr<Node>, PassRefPtrWillBeRawPtr<Node> refChild);
+ void insertNodeAt(PassRefPtrWillBeRawPtr<Node>, const Position&);
+ void insertNodeAtTabSpanPosition(PassRefPtrWillBeRawPtr<Node>, const Position&);
+ void insertNodeBefore(PassRefPtrWillBeRawPtr<Node>, PassRefPtrWillBeRawPtr<Node> refChild, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
void insertParagraphSeparator(bool useDefaultParagraphElement = false, bool pasteBlockqutoeIntoUnquotedArea = false);
- void insertLineBreak();
- void insertTextIntoNode(PassRefPtr<Text>, unsigned offset, const String& text);
- void mergeIdenticalElements(PassRefPtr<Element>, PassRefPtr<Element>);
+ void insertTextIntoNode(PassRefPtrWillBeRawPtr<Text>, unsigned offset, const String& text);
+ void mergeIdenticalElements(PassRefPtrWillBeRawPtr<Element>, PassRefPtrWillBeRawPtr<Element>);
void rebalanceWhitespace();
void rebalanceWhitespaceAt(const Position&);
- void rebalanceWhitespaceOnTextSubstring(PassRefPtr<Text>, int startOffset, int endOffset);
+ void rebalanceWhitespaceOnTextSubstring(PassRefPtrWillBeRawPtr<Text>, int startOffset, int endOffset);
void prepareWhitespaceAtPositionForSplit(Position&);
void replaceCollapsibleWhitespaceWithNonBreakingSpaceIfNeeded(const VisiblePosition&);
bool canRebalance(const Position&) const;
bool shouldRebalanceLeadingWhitespaceFor(const String&) const;
- void removeCSSProperty(PassRefPtr<Element>, CSSPropertyID);
- void removeNodeAttribute(PassRefPtr<Element>, const QualifiedName& attribute);
- void removeChildrenInRange(PassRefPtr<Node>, unsigned from, unsigned to);
- virtual void removeNode(PassRefPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
- HTMLElement* replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtr<HTMLElement>);
- void removeNodePreservingChildren(PassRefPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
- void removeNodeAndPruneAncestors(PassRefPtr<Node>, Node* excludeNode = 0);
- void moveRemainingSiblingsToNewParent(Node*, Node* pastLastNodeToMove, PassRefPtr<Element> prpNewParent);
- void updatePositionForNodeRemovalPreservingChildren(Position&, Node*);
- void prune(PassRefPtr<Node>, Node* excludeNode = 0);
- void replaceTextInNode(PassRefPtr<Text>, unsigned offset, unsigned count, const String& replacementText);
+ void removeCSSProperty(PassRefPtrWillBeRawPtr<Element>, CSSPropertyID);
+ void removeNodeAttribute(PassRefPtrWillBeRawPtr<Element>, const QualifiedName& attribute);
+ void removeChildrenInRange(PassRefPtrWillBeRawPtr<Node>, unsigned from, unsigned to);
+ virtual void removeNode(PassRefPtrWillBeRawPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
+ HTMLElement* replaceElementWithSpanPreservingChildrenAndAttributes(PassRefPtrWillBeRawPtr<HTMLElement>);
+ void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
+ void removeNodeAndPruneAncestors(PassRefPtrWillBeRawPtr<Node>, Node* excludeNode = 0);
+ void moveRemainingSiblingsToNewParent(Node*, Node* pastLastNodeToMove, PassRefPtrWillBeRawPtr<Element> prpNewParent);
+ void updatePositionForNodeRemovalPreservingChildren(Position&, Node&);
+ void prune(PassRefPtrWillBeRawPtr<Node>, Node* excludeNode = 0);
+ void replaceTextInNode(PassRefPtrWillBeRawPtr<Text>, unsigned offset, unsigned count, const String& replacementText);
Position replaceSelectedTextInNode(const String&);
- void replaceTextInNodePreservingMarkers(PassRefPtr<Text>, unsigned offset, unsigned count, const String& replacementText);
+ void replaceTextInNodePreservingMarkers(PassRefPtrWillBeRawPtr<Text>, unsigned offset, unsigned count, const String& replacementText);
Position positionOutsideTabSpan(const Position&);
- void setNodeAttribute(PassRefPtr<Element>, const QualifiedName& attribute, const AtomicString& value);
- void splitElement(PassRefPtr<Element>, PassRefPtr<Node> atChild);
- void splitTextNode(PassRefPtr<Text>, unsigned offset);
- void splitTextNodeContainingElement(PassRefPtr<Text>, unsigned offset);
- void wrapContentsInDummySpan(PassRefPtr<Element>);
+ void setNodeAttribute(PassRefPtrWillBeRawPtr<Element>, const QualifiedName& attribute, const AtomicString& value);
+ void splitElement(PassRefPtrWillBeRawPtr<Element>, PassRefPtrWillBeRawPtr<Node> atChild);
+ void splitTextNode(PassRefPtrWillBeRawPtr<Text>, unsigned offset);
+ void splitTextNodeContainingElement(PassRefPtrWillBeRawPtr<Text>, unsigned offset);
+ void wrapContentsInDummySpan(PassRefPtrWillBeRawPtr<Element>);
- void deleteInsignificantText(PassRefPtr<Text>, unsigned start, unsigned end);
+ void deleteInsignificantText(PassRefPtrWillBeRawPtr<Text>, unsigned start, unsigned end);
void deleteInsignificantText(const Position& start, const Position& end);
void deleteInsignificantTextDownstream(const Position&);
- PassRefPtr<Node> appendBlockPlaceholder(PassRefPtr<Element>);
- PassRefPtr<Node> insertBlockPlaceholder(const Position&);
- PassRefPtr<Node> addBlockPlaceholderIfNeeded(Element*);
+ PassRefPtrWillBeRawPtr<Node> appendBlockPlaceholder(PassRefPtrWillBeRawPtr<Element>);
+ PassRefPtrWillBeRawPtr<Node> insertBlockPlaceholder(const Position&);
+ PassRefPtrWillBeRawPtr<Node> addBlockPlaceholderIfNeeded(Element*);
void removePlaceholderAt(const Position&);
- PassRefPtr<Node> insertNewDefaultParagraphElementAt(const Position&);
+ PassRefPtrWillBeRawPtr<Element> insertNewDefaultParagraphElementAt(const Position&);
- PassRefPtr<Node> moveParagraphContentsToNewBlockIfNecessary(const Position&);
+ PassRefPtrWillBeRawPtr<Element> moveParagraphContentsToNewBlockIfNecessary(const Position&);
void pushAnchorElementDown(Node*);
@@ -155,7 +156,7 @@ protected:
void moveParagraph(const VisiblePosition&, const VisiblePosition&, const VisiblePosition&, bool preserveSelection = false, bool preserveStyle = true, Node* constrainingAncestor = 0);
void moveParagraphs(const VisiblePosition&, const VisiblePosition&, const VisiblePosition&, bool preserveSelection = false, bool preserveStyle = true, Node* constrainingAncestor = 0);
void moveParagraphWithClones(const VisiblePosition& startOfParagraphToMove, const VisiblePosition& endOfParagraphToMove, Element* blockElement, Node* outerNode);
- void cloneParagraphUnderNewElement(Position& start, Position& end, Node* outerNode, Element* blockElement);
+ void cloneParagraphUnderNewElement(const Position& start, const Position& end, Node* outerNode, Element* blockElement);
void cleanupAfterDeletion(VisiblePosition destination = VisiblePosition());
bool breakOutOfEmptyListItem();
@@ -163,14 +164,14 @@ protected:
Position positionAvoidingSpecialElementBoundary(const Position&);
- PassRefPtr<Node> splitTreeToNode(Node*, Node*, bool splitAncestor = false);
+ PassRefPtrWillBeRawPtr<Node> splitTreeToNode(Node*, Node*, bool splitAncestor = false);
- Vector<RefPtr<EditCommand> > m_commands;
+ WillBeHeapVector<RefPtrWillBeMember<EditCommand> > m_commands;
private:
- bool isCompositeEditCommand() const OVERRIDE { return true; }
+ virtual bool isCompositeEditCommand() const OVERRIDE FINAL { return true; }
- RefPtr<EditCommandComposition> m_composition;
+ RefPtrWillBeMember<EditCommandComposition> m_composition;
};
DEFINE_TYPE_CASTS(CompositeEditCommand, EditCommand, command, command->isCompositeEditCommand(), command.isCompositeEditCommand());
diff --git a/chromium/third_party/WebKit/Source/core/editing/CompositionUnderline.h b/chromium/third_party/WebKit/Source/core/editing/CompositionUnderline.h
index 025ee75cbf7..54bbad2f499 100644
--- a/chromium/third_party/WebKit/Source/core/editing/CompositionUnderline.h
+++ b/chromium/third_party/WebKit/Source/core/editing/CompositionUnderline.h
@@ -32,13 +32,32 @@ namespace WebCore {
struct CompositionUnderline {
CompositionUnderline()
- : startOffset(0), endOffset(0), thick(false) { }
+ : startOffset(0)
+ , endOffset(0)
+ , color(Color::transparent)
+ , thick(false)
+ , backgroundColor(Color::transparent) { }
+
+ // FIXME(huangs): remove this constructor.
CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t)
- : startOffset(s), endOffset(e), color(c), thick(t) { }
+ : startOffset(s)
+ , endOffset(e)
+ , color(c)
+ , thick(t)
+ , backgroundColor(Color::transparent) { }
+
+ CompositionUnderline(unsigned s, unsigned e, const Color& c, bool t, const Color& bc)
+ : startOffset(s)
+ , endOffset(e)
+ , color(c)
+ , thick(t)
+ , backgroundColor(bc) { }
+
unsigned startOffset;
unsigned endOffset;
Color color;
bool thick;
+ Color backgroundColor;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilter.cpp b/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilter.cpp
new file mode 100644
index 00000000000..8817cd6bcf2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilter.cpp
@@ -0,0 +1,39 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/editing/CompositionUnderlineRangeFilter.h"
+
+namespace WebCore {
+
+CompositionUnderlineRangeFilter::CompositionUnderlineRangeFilter(const Vector<CompositionUnderline>& underlines, size_t indexLo, size_t indexHi)
+ : m_underlines(underlines)
+ , m_indexLo(indexLo)
+ , m_indexHi(indexHi)
+ , m_theEnd(this, kNotFound) { }
+
+size_t CompositionUnderlineRangeFilter::seekValidIndex(size_t index)
+{
+ if (index == kNotFound)
+ return kNotFound;
+
+ size_t numUnderlines = m_underlines.size();
+ while (index < numUnderlines) {
+ const CompositionUnderline& underline = m_underlines[index];
+
+ if (underline.endOffset <= m_indexLo) {
+ // |underline| lies before the query range: keep on looking.
+ ++index;
+ } else if (underline.startOffset <= m_indexHi) {
+ // |underline| intersects with the query range: valid, so return.
+ return index;
+ } else {
+ // |underline| is completely after the query range: bail.
+ break;
+ }
+ }
+ return kNotFound;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilter.h b/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilter.h
new file mode 100644
index 00000000000..c3093db04b4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilter.h
@@ -0,0 +1,78 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CompositionUnderlineRangeFilter_h
+#define CompositionUnderlineRangeFilter_h
+
+#include "core/editing/CompositionUnderline.h"
+#include "wtf/NotFound.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+// A visitor class to yield elements of a sorted (by startOffset) list of
+// underlines, visiting only elements that intersect with specified *inclusive*
+// range [indexLo, indexHi].
+class CompositionUnderlineRangeFilter {
+ WTF_MAKE_NONCOPYABLE(CompositionUnderlineRangeFilter);
+public:
+ class ConstIterator {
+ public:
+ ConstIterator(): m_filter(nullptr), m_index(0) { }
+ const CompositionUnderline& operator*()
+ {
+ ASSERT(m_index != kNotFound);
+ return m_filter->m_underlines[m_index];
+ }
+ ConstIterator& operator++()
+ {
+ if (m_index != kNotFound)
+ m_index = m_filter->seekValidIndex(m_index + 1);
+ return *this;
+ }
+ const CompositionUnderline* operator->()
+ {
+ ASSERT(m_index != kNotFound);
+ return &m_filter->m_underlines[m_index];
+ }
+ bool operator==(const ConstIterator& other)
+ {
+ return other.m_index == m_index && other.m_filter == m_filter;
+ }
+ bool operator!=(const ConstIterator& other) { return !operator==(other); }
+
+ private:
+ friend class CompositionUnderlineRangeFilter;
+
+ ConstIterator(CompositionUnderlineRangeFilter* filter, size_t index)
+ : m_filter(filter)
+ , m_index(index) { }
+ CompositionUnderlineRangeFilter* m_filter;
+ size_t m_index;
+ };
+
+ CompositionUnderlineRangeFilter(const Vector<CompositionUnderline>& underlines, size_t indexLo, size_t indexHi);
+
+ ConstIterator begin() { return ConstIterator(this, seekValidIndex(0)); }
+ const ConstIterator& end() { return m_theEnd; }
+
+private:
+ friend class ConstIterator;
+
+ // Returns |index| if |m_underlines[index]| intersects with range
+ // [m_indexLo, m_indexHi]. Otherwise returns the index of the next
+ // intersecting interval, or END if there are none left.
+ size_t seekValidIndex(size_t index);
+
+ // Assume that elements of |m_underlines| are sorted by |.startOffset|.
+ const Vector<CompositionUnderline>& m_underlines;
+ // The "query range" is the inclusive range [m_indexLo, m_indexHi].
+ const size_t m_indexLo;
+ const size_t m_indexHi;
+ const ConstIterator m_theEnd;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilterTest.cpp b/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilterTest.cpp
new file mode 100644
index 00000000000..ce9908bb13d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/editing/CompositionUnderlineRangeFilterTest.cpp
@@ -0,0 +1,90 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/editing/CompositionUnderlineRangeFilter.h"
+
+#include "core/editing/CompositionUnderline.h"
+#include "platform/graphics/Color.h"
+#include "wtf/Vector.h"
+#include "wtf/text/IntegerToStringConversion.h"
+#include "wtf/text/WTFString.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+// Parses test case string and populate |underlines|.
+void initUnderlines(const String& testCase, Vector<CompositionUnderline>* underlines)
+{
+ ASSERT(underlines && underlines->size() == 0U);
+ Vector<String> rangeList;
+ testCase.split("|", rangeList);
+ // Intervals are named 'A', 'B', ..., 'Z', so ensure there aren't too many.
+ ASSERT_LE(rangeList.size(), static_cast<size_t>('Z' - 'A'));
+ for (unsigned i = 0; i < rangeList.size(); ++i) {
+ String range = rangeList[i];
+ Vector<String> toks;
+ rangeList[i].split(",", toks);
+ ASSERT_EQ(2U, toks.size());
+ int startOffset = toks[0].toInt();
+ int endOffset = toks[1].toInt();
+ ASSERT_LE(startOffset, endOffset);
+ // For testing: Store i in red component of |color|, so the intervals
+ // can be distinguished.
+ underlines->append(CompositionUnderline(startOffset, endOffset, Color(i, 0, 0), false, 0));
+ }
+}
+
+// Runs the filter and encodes the result into a string, with 'A' as first
+// elemnt, 'B' as second, etc.
+String filterUnderlines(const Vector<CompositionUnderline>& underlines, int indexLo, int indexHi)
+{
+ CompositionUnderlineRangeFilter filter(underlines, indexLo, indexHi);
+ String ret = "";
+ for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begin(); it != filter.end(); ++it) {
+ int code = (*it).color.red();
+ ret.append(static_cast<char>('A' + code));
+ }
+ return ret;
+}
+
+TEST(CompositionUnderlineRangeFilterTest, Empty)
+{
+ Vector<CompositionUnderline> underlines;
+ EXPECT_EQ("", filterUnderlines(underlines, 0, 10));
+ EXPECT_EQ("", filterUnderlines(underlines, 5, 5));
+}
+
+TEST(CompositionUnderlineRangeFilterTest, Single)
+{
+ String testCase = "10,20"; // Semi-closed interval: {10, 11, ..., 19}.
+ Vector<CompositionUnderline> underlines;
+ initUnderlines(testCase, &underlines);
+ // The query intervals are all closed, e.g., [0, 9] = {0, ..., 9}.
+ EXPECT_EQ("", filterUnderlines(underlines, 0, 9));
+ EXPECT_EQ("A", filterUnderlines(underlines, 5, 10));
+ EXPECT_EQ("A", filterUnderlines(underlines, 10, 20));
+ EXPECT_EQ("A", filterUnderlines(underlines, 15, 25));
+ EXPECT_EQ("A", filterUnderlines(underlines, 19, 30));
+ EXPECT_EQ("", filterUnderlines(underlines, 20, 25));
+ EXPECT_EQ("A", filterUnderlines(underlines, 5, 25));
+}
+
+TEST(CompositionUnderlineRangeFilterTest, Multi)
+{
+ String testCase = "0,2|0,5|1,3|1,10|3,5|5,8|7,8|8,10";
+ Vector<CompositionUnderline> underlines;
+ initUnderlines(testCase, &underlines);
+ EXPECT_EQ("", filterUnderlines(underlines, 11, 11));
+ EXPECT_EQ("ABCDEFGH", filterUnderlines(underlines, 0, 9));
+ EXPECT_EQ("BDEF", filterUnderlines(underlines, 4, 5));
+ EXPECT_EQ("AB", filterUnderlines(underlines, 0, 0));
+ EXPECT_EQ("BDE", filterUnderlines(underlines, 3, 3));
+ EXPECT_EQ("DF", filterUnderlines(underlines, 5, 5));
+ EXPECT_EQ("DFG", filterUnderlines(underlines, 7, 7));
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.cpp
index 7f8adffff9f..feac186152f 100644
--- a/chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.cpp
@@ -42,16 +42,16 @@ void CreateLinkCommand::doApply()
if (endingSelection().isNone())
return;
- RefPtr<HTMLAnchorElement> anchorElement = HTMLAnchorElement::create(document());
+ RefPtrWillBeRawPtr<HTMLAnchorElement> anchorElement = HTMLAnchorElement::create(document());
anchorElement->setHref(AtomicString(m_url));
if (endingSelection().isRange())
applyStyledElement(anchorElement.get());
else {
insertNodeAt(anchorElement.get(), endingSelection().start());
- RefPtr<Text> textNode = Text::create(document(), m_url);
+ RefPtrWillBeRawPtr<Text> textNode = Text::create(document(), m_url);
appendNode(textNode.get(), anchorElement.get());
- setEndingSelection(VisibleSelection(positionInParentBeforeNode(anchorElement.get()), positionInParentAfterNode(anchorElement.get()), DOWNSTREAM, endingSelection().isDirectional()));
+ setEndingSelection(VisibleSelection(positionInParentBeforeNode(*anchorElement), positionInParentAfterNode(*anchorElement), DOWNSTREAM, endingSelection().isDirectional()));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.h b/chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.h
index af489feb7e0..0808f42a34f 100644
--- a/chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/CreateLinkCommand.h
@@ -30,20 +30,18 @@
namespace WebCore {
-class CreateLinkCommand : public CompositeEditCommand {
+class CreateLinkCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<CreateLinkCommand> create(Document& document, const String& linkURL)
+ static PassRefPtrWillBeRawPtr<CreateLinkCommand> create(Document& document, const String& linkURL)
{
- return adoptRef(new CreateLinkCommand(document, linkURL));
+ return adoptRefWillBeNoop(new CreateLinkCommand(document, linkURL));
}
- bool isCreateLinkCommand() const { return true; }
-
private:
CreateLinkCommand(Document&, const String& linkURL);
- virtual void doApply();
- virtual EditAction editingAction() const { return EditActionCreateLink; }
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE { return EditActionCreateLink; }
String m_url;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.cpp
index bbecaced675..fad7866e83e 100644
--- a/chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.cpp
@@ -33,7 +33,7 @@
namespace WebCore {
-DeleteFromTextNodeCommand::DeleteFromTextNodeCommand(PassRefPtr<Text> node, unsigned offset, unsigned count)
+DeleteFromTextNodeCommand::DeleteFromTextNodeCommand(PassRefPtrWillBeRawPtr<Text> node, unsigned offset, unsigned count)
: SimpleEditCommand(node->document())
, m_node(node)
, m_offset(offset)
@@ -69,4 +69,10 @@ void DeleteFromTextNodeCommand::doUnapply()
m_node->insertData(m_offset, m_text, IGNORE_EXCEPTION, CharacterData::DeprecatedRecalcStyleImmediatlelyForEditing);
}
+void DeleteFromTextNodeCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_node);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.h b/chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.h
index 192e8a90650..11027e25627 100644
--- a/chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/DeleteFromTextNodeCommand.h
@@ -32,20 +32,22 @@ namespace WebCore {
class Text;
-class DeleteFromTextNodeCommand : public SimpleEditCommand {
+class DeleteFromTextNodeCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<DeleteFromTextNodeCommand> create(PassRefPtr<Text> node, unsigned offset, unsigned count)
+ static PassRefPtrWillBeRawPtr<DeleteFromTextNodeCommand> create(PassRefPtrWillBeRawPtr<Text> node, unsigned offset, unsigned count)
{
- return adoptRef(new DeleteFromTextNodeCommand(node, offset, count));
+ return adoptRefWillBeNoop(new DeleteFromTextNodeCommand(node, offset, count));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- DeleteFromTextNodeCommand(PassRefPtr<Text>, unsigned offset, unsigned count);
+ DeleteFromTextNodeCommand(PassRefPtrWillBeRawPtr<Text>, unsigned offset, unsigned count);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<Text> m_node;
+ RefPtrWillBeMember<Text> m_node;
unsigned m_offset;
unsigned m_count;
String m_text;
diff --git a/chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.cpp
index ce27bb711cf..019429b337b 100644
--- a/chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/editing/DeleteSelectionCommand.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/NodeTraversal.h"
@@ -35,20 +35,14 @@
#include "core/editing/Editor.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLInputElement.h"
-#include "core/html/HTMLTableElement.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderTableCell.h"
namespace WebCore {
using namespace HTMLNames;
-static bool isTableRow(const Node* node)
-{
- return node && node->hasTagName(trTag);
-}
-
static bool isTableCellEmpty(Node* cell)
{
ASSERT(isTableCell(cell));
@@ -57,7 +51,7 @@ static bool isTableCellEmpty(Node* cell)
static bool isTableRowEmpty(Node* row)
{
- if (!isTableRow(row))
+ if (!isHTMLTableRowElement(row))
return false;
for (Node* child = row->firstChild(); child; child = child->nextSibling())
@@ -67,40 +61,38 @@ static bool isTableRowEmpty(Node* row)
return true;
}
-DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements, bool sanitizeMarkup)
+DeleteSelectionCommand::DeleteSelectionCommand(Document& document, bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup)
: CompositeEditCommand(document)
, m_hasSelectionToDelete(false)
, m_smartDelete(smartDelete)
, m_mergeBlocksAfterDelete(mergeBlocksAfterDelete)
, m_needPlaceholder(false)
- , m_replace(replace)
, m_expandForSpecialElements(expandForSpecialElements)
, m_pruneStartBlockIfNecessary(false)
, m_startsAtEmptyLine(false)
, m_sanitizeMarkup(sanitizeMarkup)
- , m_startBlock(0)
- , m_endBlock(0)
- , m_typingStyle(0)
- , m_deleteIntoBlockquoteStyle(0)
+ , m_startBlock(nullptr)
+ , m_endBlock(nullptr)
+ , m_typingStyle(nullptr)
+ , m_deleteIntoBlockquoteStyle(nullptr)
{
}
-DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements, bool sanitizeMarkup)
+DeleteSelectionCommand::DeleteSelectionCommand(const VisibleSelection& selection, bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup)
: CompositeEditCommand(*selection.start().document())
, m_hasSelectionToDelete(true)
, m_smartDelete(smartDelete)
, m_mergeBlocksAfterDelete(mergeBlocksAfterDelete)
, m_needPlaceholder(false)
- , m_replace(replace)
, m_expandForSpecialElements(expandForSpecialElements)
, m_pruneStartBlockIfNecessary(false)
, m_startsAtEmptyLine(false)
, m_sanitizeMarkup(sanitizeMarkup)
, m_selectionToDelete(selection)
- , m_startBlock(0)
- , m_endBlock(0)
- , m_typingStyle(0)
- , m_deleteIntoBlockquoteStyle(0)
+ , m_startBlock(nullptr)
+ , m_endBlock(nullptr)
+ , m_typingStyle(nullptr)
+ , m_deleteIntoBlockquoteStyle(nullptr)
{
}
@@ -114,9 +106,9 @@ void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end)
// For HRs, we'll get a position at (HR,1) when hitting delete from the beginning of the previous line, or (HR,0) when forward deleting,
// but in these cases, we want to delete it, so manually expand the selection
- if (start.deprecatedNode()->hasTagName(hrTag))
+ if (isHTMLHRElement(*start.deprecatedNode()))
start = positionBeforeNode(start.deprecatedNode());
- else if (end.deprecatedNode()->hasTagName(hrTag))
+ else if (isHTMLHRElement(*end.deprecatedNode()))
end = positionAfterNode(end.deprecatedNode());
// FIXME: This is only used so that moveParagraphs can avoid the bugs in special element expansion.
@@ -137,11 +129,11 @@ void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end)
break;
// If we're going to expand to include the startSpecialContainer, it must be fully selected.
- if (startSpecialContainer && !endSpecialContainer && comparePositions(positionInParentAfterNode(startSpecialContainer), end) > -1)
+ if (startSpecialContainer && !endSpecialContainer && comparePositions(positionInParentAfterNode(*startSpecialContainer), end) > -1)
break;
// If we're going to expand to include the endSpecialContainer, it must be fully selected.
- if (endSpecialContainer && !startSpecialContainer && comparePositions(start, positionInParentBeforeNode(endSpecialContainer)) > -1)
+ if (endSpecialContainer && !startSpecialContainer && comparePositions(start, positionInParentBeforeNode(*endSpecialContainer)) > -1)
break;
if (startSpecialContainer && startSpecialContainer->isDescendantOf(endSpecialContainer))
@@ -161,15 +153,9 @@ void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end)
void DeleteSelectionCommand::setStartingSelectionOnSmartDelete(const Position& start, const Position& end)
{
- VisiblePosition newBase;
- VisiblePosition newExtent;
- if (startingSelection().isBaseFirst()) {
- newBase = start;
- newExtent = end;
- } else {
- newBase = end;
- newExtent = start;
- }
+ bool isBaseFirst = startingSelection().isBaseFirst();
+ VisiblePosition newBase(isBaseFirst ? start : end);
+ VisiblePosition newExtent(isBaseFirst ? end : start);
setStartingSelection(VisibleSelection(newBase, newExtent, startingSelection().isDirectional()));
}
@@ -178,6 +164,10 @@ void DeleteSelectionCommand::initializePositionData()
Position start, end;
initializeStartEnd(start, end);
+ ASSERT(isEditablePosition(start, ContentIsEditable, DoNotUpdateStyle));
+ if (!isEditablePosition(end, ContentIsEditable, DoNotUpdateStyle))
+ end = lastEditablePositionBeforePositionInRoot(end, highestEditableRoot(start));
+
m_upstreamStart = start.upstream();
m_downstreamStart = start.downstream();
m_upstreamEnd = end.upstream();
@@ -186,8 +176,8 @@ void DeleteSelectionCommand::initializePositionData()
m_startRoot = editableRootForPosition(start);
m_endRoot = editableRootForPosition(end);
- m_startTableRow = enclosingNodeOfType(start, &isTableRow);
- m_endTableRow = enclosingNodeOfType(end, &isTableRow);
+ m_startTableRow = enclosingNodeOfType(start, &isHTMLTableRowElement);
+ m_endTableRow = enclosingNodeOfType(end, &isHTMLTableRowElement);
// Don't move content out of a table cell.
// If the cell is non-editable, enclosingNodeOfType won't return it by default, so
@@ -300,7 +290,7 @@ void DeleteSelectionCommand::saveTypingStyleState()
if (enclosingNodeOfType(m_selectionToDelete.start(), isMailBlockquote))
m_deleteIntoBlockquoteStyle = EditingStyle::create(m_selectionToDelete.end());
else
- m_deleteIntoBlockquoteStyle = 0;
+ m_deleteIntoBlockquoteStyle = nullptr;
}
bool DeleteSelectionCommand::handleSpecialCaseBRDelete()
@@ -314,8 +304,8 @@ bool DeleteSelectionCommand::handleSpecialCaseBRDelete()
return false;
// Check for special-case where the selection contains only a BR on a line by itself after another BR.
- bool upstreamStartIsBR = nodeAfterUpstreamStart->hasTagName(brTag);
- bool downstreamStartIsBR = nodeAfterDownstreamStart->hasTagName(brTag);
+ bool upstreamStartIsBR = isHTMLBRElement(*nodeAfterUpstreamStart);
+ bool downstreamStartIsBR = isHTMLBRElement(*nodeAfterDownstreamStart);
bool isBROnLineByItself = upstreamStartIsBR && downstreamStartIsBR && nodeAfterDownstreamStart == nodeAfterUpstreamEnd;
if (isBROnLineByItself) {
removeNode(nodeAfterDownstreamStart);
@@ -324,7 +314,7 @@ bool DeleteSelectionCommand::handleSpecialCaseBRDelete()
// FIXME: This code doesn't belong in here.
// We detect the case where the start is an empty line consisting of BR not wrapped in a block element.
- if (upstreamStartIsBR && downstreamStartIsBR && !(isStartOfBlock(positionBeforeNode(nodeAfterUpstreamStart)) && isEndOfBlock(positionAfterNode(nodeAfterUpstreamStart)))) {
+ if (upstreamStartIsBR && downstreamStartIsBR && !(isStartOfBlock(VisiblePosition(positionBeforeNode(nodeAfterUpstreamStart))) && isEndOfBlock(VisiblePosition(positionAfterNode(nodeAfterUpstreamStart))))) {
m_startsAtEmptyLine = true;
m_endingPosition = m_downstreamEnd;
}
@@ -341,7 +331,7 @@ static Position firstEditablePositionInNode(Node* node)
return next ? firstPositionInOrBeforeNode(next) : Position();
}
-void DeleteSelectionCommand::removeNode(PassRefPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+void DeleteSelectionCommand::removeNode(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
if (!node)
return;
@@ -353,9 +343,9 @@ void DeleteSelectionCommand::removeNode(PassRefPtr<Node> node, ShouldAssumeConte
if (!node->firstChild())
return;
// Search this non-editable region for editable regions to empty.
- RefPtr<Node> child = node->firstChild();
+ RefPtrWillBeRawPtr<Node> child = node->firstChild();
while (child) {
- RefPtr<Node> nextChild = child->nextSibling();
+ RefPtrWillBeRawPtr<Node> nextChild = child->nextSibling();
removeNode(child.get(), shouldAssumeContentIsAlwaysEditable);
// Bail if nextChild is no longer node's child.
if (nextChild && nextChild->parentNode() != node)
@@ -389,15 +379,21 @@ void DeleteSelectionCommand::removeNode(PassRefPtr<Node> node, ShouldAssumeConte
return;
}
- if (node == m_startBlock && !isEndOfBlock(VisiblePosition(firstPositionInNode(m_startBlock.get())).previous()))
- m_needPlaceholder = true;
- else if (node == m_endBlock && !isStartOfBlock(VisiblePosition(lastPositionInNode(m_startBlock.get())).next()))
- m_needPlaceholder = true;
+ if (node == m_startBlock) {
+ VisiblePosition previous = VisiblePosition(firstPositionInNode(m_startBlock.get())).previous();
+ if (previous.isNotNull() && !isEndOfBlock(previous))
+ m_needPlaceholder = true;
+ }
+ if (node == m_endBlock) {
+ VisiblePosition next = VisiblePosition(lastPositionInNode(m_endBlock.get())).next();
+ if (next.isNotNull() && !isStartOfBlock(next))
+ m_needPlaceholder = true;
+ }
// FIXME: Update the endpoints of the range being deleted.
- updatePositionForNodeRemoval(m_endingPosition, node.get());
- updatePositionForNodeRemoval(m_leadingWhitespace, node.get());
- updatePositionForNodeRemoval(m_trailingWhitespace, node.get());
+ updatePositionForNodeRemoval(m_endingPosition, *node);
+ updatePositionForNodeRemoval(m_leadingWhitespace, *node);
+ updatePositionForNodeRemoval(m_trailingWhitespace, *node);
CompositeEditCommand::removeNode(node, shouldAssumeContentIsAlwaysEditable);
}
@@ -413,7 +409,7 @@ static void updatePositionForTextRemoval(Node* node, int offset, int count, Posi
position.moveToOffset(offset);
}
-void DeleteSelectionCommand::deleteTextFromNode(PassRefPtr<Text> node, unsigned offset, unsigned count)
+void DeleteSelectionCommand::deleteTextFromNode(PassRefPtrWillBeRawPtr<Text> node, unsigned offset, unsigned count)
{
// FIXME: Update the endpoints of the range being deleted.
updatePositionForTextRemoval(node.get(), offset, count, m_endingPosition);
@@ -426,13 +422,13 @@ void DeleteSelectionCommand::deleteTextFromNode(PassRefPtr<Text> node, unsigned
void DeleteSelectionCommand::makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss()
{
- RefPtr<Range> range = m_selectionToDelete.toNormalizedRange();
- RefPtr<Node> node = range->firstNode();
+ RefPtrWillBeRawPtr<Range> range = m_selectionToDelete.toNormalizedRange();
+ RefPtrWillBeRawPtr<Node> node = range->firstNode();
while (node && node != range->pastLastNode()) {
- RefPtr<Node> nextNode = NodeTraversal::next(*node);
- if ((node->hasTagName(styleTag) && !(toElement(node)->hasAttribute(scopedAttr))) || node->hasTagName(linkTag)) {
+ RefPtrWillBeRawPtr<Node> nextNode = NodeTraversal::next(*node);
+ if ((isHTMLStyleElement(*node) && !(toElement(node)->hasAttribute(scopedAttr))) || isHTMLLinkElement(*node)) {
nextNode = NodeTraversal::nextSkippingChildren(*node);
- RefPtr<ContainerNode> rootEditableElement = node->rootEditableElement();
+ RefPtrWillBeRawPtr<ContainerNode> rootEditableElement = node->rootEditableElement();
if (rootEditableElement.get()) {
removeNode(node);
appendNode(node, rootEditableElement);
@@ -454,7 +450,7 @@ void DeleteSelectionCommand::handleGeneralDelete()
makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss();
// Never remove the start block unless it's a table, in which case we won't merge content in.
- if (startNode->isSameNode(m_startBlock.get()) && !startOffset && canHaveChildrenForEditing(startNode) && !isHTMLTableElement(startNode)) {
+ if (startNode->isSameNode(m_startBlock.get()) && !startOffset && canHaveChildrenForEditing(startNode) && !isHTMLTableElement(*startNode)) {
startOffset = 0;
startNode = NodeTraversal::next(*startNode);
if (!startNode)
@@ -495,7 +491,7 @@ void DeleteSelectionCommand::handleGeneralDelete()
else {
bool startNodeWasDescendantOfEndNode = m_upstreamStart.deprecatedNode()->isDescendantOf(m_downstreamEnd.deprecatedNode());
// The selection to delete spans more than one node.
- RefPtr<Node> node(startNode);
+ RefPtrWillBeRawPtr<Node> node(startNode);
if (startOffset > 0) {
if (startNode->isTextNode()) {
@@ -504,7 +500,7 @@ void DeleteSelectionCommand::handleGeneralDelete()
deleteTextFromNode(text, startOffset, text->length() - startOffset);
node = NodeTraversal::next(*node);
} else {
- node = startNode->childNode(startOffset);
+ node = startNode->traverseToChildAt(startOffset);
}
} else if (startNode == m_upstreamEnd.deprecatedNode() && startNode->isTextNode()) {
Text* text = toText(m_upstreamEnd.deprecatedNode());
@@ -515,19 +511,19 @@ void DeleteSelectionCommand::handleGeneralDelete()
while (node && node != m_downstreamEnd.deprecatedNode()) {
if (comparePositions(firstPositionInOrBeforeNode(node.get()), m_downstreamEnd) >= 0) {
// NodeTraversal::nextSkippingChildren just blew past the end position, so stop deleting
- node = 0;
+ node = nullptr;
} else if (!m_downstreamEnd.deprecatedNode()->isDescendantOf(node.get())) {
- RefPtr<Node> nextNode = NodeTraversal::nextSkippingChildren(*node);
+ RefPtrWillBeRawPtr<Node> nextNode = NodeTraversal::nextSkippingChildren(*node);
// if we just removed a node from the end container, update end position so the
// check above will work
- updatePositionForNodeRemoval(m_downstreamEnd, node.get());
+ updatePositionForNodeRemoval(m_downstreamEnd, *node);
removeNode(node.get());
node = nextNode.get();
} else {
- Node& n = node->lastDescendant();
+ Node& n = node->lastDescendantOrSelf();
if (m_downstreamEnd.deprecatedNode() == n && m_downstreamEnd.deprecatedEditingOffset() >= caretMaxOffset(&n)) {
removeNode(node.get());
- node = 0;
+ node = nullptr;
} else {
node = NodeTraversal::next(*node);
}
@@ -634,15 +630,26 @@ void DeleteSelectionCommand::mergeParagraphs()
if (mergeDestination == startOfParagraphToMove)
return;
- VisiblePosition endOfParagraphToMove = endOfParagraph(startOfParagraphToMove);
+ VisiblePosition endOfParagraphToMove = endOfParagraph(startOfParagraphToMove, CanSkipOverEditingBoundary);
if (mergeDestination == endOfParagraphToMove)
return;
+ // If the merge destination and source to be moved are both list items of different lists, merge them into single list.
+ Node* listItemInFirstParagraph = enclosingNodeOfType(m_upstreamStart, isListItem);
+ Node* listItemInSecondParagraph = enclosingNodeOfType(m_downstreamEnd, isListItem);
+ if (listItemInFirstParagraph && listItemInSecondParagraph
+ && listItemInFirstParagraph->parentElement() != listItemInSecondParagraph->parentElement()
+ && canMergeLists(listItemInFirstParagraph->parentElement(), listItemInSecondParagraph->parentElement())) {
+ mergeIdenticalElements(listItemInFirstParagraph->parentElement(), listItemInSecondParagraph->parentElement());
+ m_endingPosition = mergeDestination.deepEquivalent();
+ return;
+ }
+
// The rule for merging into an empty block is: only do so if its farther to the right.
// FIXME: Consider RTL.
if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && startOfParagraphToMove.absoluteCaretBounds().x() > mergeDestination.absoluteCaretBounds().x()) {
- if (mergeDestination.deepEquivalent().downstream().deprecatedNode()->hasTagName(brTag)) {
+ if (isHTMLBRElement(*mergeDestination.deepEquivalent().downstream().deprecatedNode())) {
removeNodeAndPruneAncestors(mergeDestination.deepEquivalent().downstream().deprecatedNode());
m_endingPosition = startOfParagraphToMove.deepEquivalent();
return;
@@ -672,7 +679,7 @@ void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows()
if (m_endTableRow && m_endTableRow->inDocument() && m_endTableRow != m_startTableRow) {
Node* row = m_endTableRow->previousSibling();
while (row && row != m_startTableRow) {
- RefPtr<Node> previousRow = row->previousSibling();
+ RefPtrWillBeRawPtr<Node> previousRow = row->previousSibling();
if (isTableRowEmpty(row))
// Use a raw removeNode, instead of DeleteSelectionCommand's, because
// that won't remove rows, it only empties them in preparation for this function.
@@ -685,7 +692,7 @@ void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows()
if (m_startTableRow && m_startTableRow->inDocument() && m_startTableRow != m_endTableRow) {
Node* row = m_startTableRow->nextSibling();
while (row && row != m_endTableRow) {
- RefPtr<Node> nextRow = row->nextSibling();
+ RefPtrWillBeRawPtr<Node> nextRow = row->nextSibling();
if (isTableRowEmpty(row))
CompositeEditCommand::removeNode(row);
row = nextRow.get();
@@ -715,17 +722,17 @@ void DeleteSelectionCommand::calculateTypingStyleAfterDelete()
// Compute the difference between the style before the delete and the style now
// after the delete has been done. Set this style on the frame, so other editing
// commands being composed with this one will work, and also cache it on the command,
- // so the Frame::appliedEditing can set it after the whole composite command
+ // so the LocalFrame::appliedEditing can set it after the whole composite command
// has completed.
// If we deleted into a blockquote, but are now no longer in a blockquote, use the alternate typing style
if (m_deleteIntoBlockquoteStyle && !enclosingNodeOfType(m_endingPosition, isMailBlockquote, CanCrossEditingBoundary))
m_typingStyle = m_deleteIntoBlockquoteStyle;
- m_deleteIntoBlockquoteStyle = 0;
+ m_deleteIntoBlockquoteStyle = nullptr;
m_typingStyle->prepareToApplyAt(m_endingPosition);
if (m_typingStyle->isEmpty())
- m_typingStyle = 0;
+ m_typingStyle = nullptr;
// This is where we've deleted all traces of a style but not a whole paragraph (that's handled above).
// In this case if we start typing, the new characters should have the same style as the just deleted ones,
// but, if we change the selection, come back and start typing that style should be lost. Also see
@@ -754,7 +761,7 @@ void DeleteSelectionCommand::removeRedundantBlocks()
while (node != rootNode) {
if (isRemovableBlock(node)) {
if (node == m_endingPosition.anchorNode())
- updatePositionForNodeRemovalPreservingChildren(m_endingPosition, node);
+ updatePositionForNodeRemovalPreservingChildren(m_endingPosition, *node);
CompositeEditCommand::removeNodePreservingChildren(node);
node = m_endingPosition.anchorNode();
@@ -829,7 +836,7 @@ void DeleteSelectionCommand::doApply()
m_needPlaceholder = hasPlaceholder && lineBreakBeforeStart && !lineBreakAtEndOfSelectionToDelete;
}
- RefPtr<Node> placeholder = m_needPlaceholder ? createBreakElement(document()).get() : 0;
+ RefPtrWillBeRawPtr<Node> placeholder = m_needPlaceholder ? createBreakElement(document()) : nullptr;
if (placeholder) {
if (m_sanitizeMarkup)
@@ -861,4 +868,26 @@ bool DeleteSelectionCommand::preservesTypingStyle() const
return m_typingStyle;
}
+void DeleteSelectionCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_selectionToDelete);
+ visitor->trace(m_upstreamStart);
+ visitor->trace(m_downstreamStart);
+ visitor->trace(m_upstreamEnd);
+ visitor->trace(m_downstreamEnd);
+ visitor->trace(m_endingPosition);
+ visitor->trace(m_leadingWhitespace);
+ visitor->trace(m_trailingWhitespace);
+ visitor->trace(m_startBlock);
+ visitor->trace(m_endBlock);
+ visitor->trace(m_typingStyle);
+ visitor->trace(m_deleteIntoBlockquoteStyle);
+ visitor->trace(m_startRoot);
+ visitor->trace(m_endRoot);
+ visitor->trace(m_startTableRow);
+ visitor->trace(m_endTableRow);
+ visitor->trace(m_temporaryPlaceholder);
+ CompositeEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.h b/chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.h
index 8234bb308b3..8bef5717c47 100644
--- a/chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/DeleteSelectionCommand.h
@@ -32,49 +32,48 @@ namespace WebCore {
class EditingStyle;
-class DeleteSelectionCommand : public CompositeEditCommand {
+class DeleteSelectionCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<DeleteSelectionCommand> create(Document& document, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = false, bool sanitizeMarkup = true)
+ static PassRefPtrWillBeRawPtr<DeleteSelectionCommand> create(Document& document, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool expandForSpecialElements = false, bool sanitizeMarkup = true)
{
- return adoptRef(new DeleteSelectionCommand(document, smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements, sanitizeMarkup));
+ return adoptRefWillBeNoop(new DeleteSelectionCommand(document, smartDelete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup));
}
- static PassRefPtr<DeleteSelectionCommand> create(const VisibleSelection& selection, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool replace = false, bool expandForSpecialElements = false, bool sanitizeMarkup = true)
+ static PassRefPtrWillBeRawPtr<DeleteSelectionCommand> create(const VisibleSelection& selection, bool smartDelete = false, bool mergeBlocksAfterDelete = true, bool expandForSpecialElements = false, bool sanitizeMarkup = true)
{
- return adoptRef(new DeleteSelectionCommand(selection, smartDelete, mergeBlocksAfterDelete, replace, expandForSpecialElements, sanitizeMarkup));
+ return adoptRefWillBeNoop(new DeleteSelectionCommand(selection, smartDelete, mergeBlocksAfterDelete, expandForSpecialElements, sanitizeMarkup));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- DeleteSelectionCommand(Document&, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements, bool santizeMarkup);
- DeleteSelectionCommand(const VisibleSelection&, bool smartDelete, bool mergeBlocksAfterDelete, bool replace, bool expandForSpecialElements, bool sanitizeMarkup);
+ DeleteSelectionCommand(Document&, bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool santizeMarkup);
+ DeleteSelectionCommand(const VisibleSelection&, bool smartDelete, bool mergeBlocksAfterDelete, bool expandForSpecialElements, bool sanitizeMarkup);
- virtual void doApply();
- virtual EditAction editingAction() const;
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE;
- virtual bool preservesTypingStyle() const;
+ virtual bool preservesTypingStyle() const OVERRIDE;
void initializeStartEnd(Position&, Position&);
void setStartingSelectionOnSmartDelete(const Position&, const Position&);
void initializePositionData();
void saveTypingStyleState();
- void insertPlaceholderForAncestorBlockContent();
bool handleSpecialCaseBRDelete();
void handleGeneralDelete();
void fixupWhitespace();
void mergeParagraphs();
void removePreviouslySelectedEmptyTableRows();
- void calculateEndingPosition();
void calculateTypingStyleAfterDelete();
void clearTransientState();
void makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss();
- virtual void removeNode(PassRefPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
- virtual void deleteTextFromNode(PassRefPtr<Text>, unsigned, unsigned);
+ virtual void removeNode(PassRefPtrWillBeRawPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable) OVERRIDE;
+ virtual void deleteTextFromNode(PassRefPtrWillBeRawPtr<Text>, unsigned, unsigned) OVERRIDE;
void removeRedundantBlocks();
bool m_hasSelectionToDelete;
bool m_smartDelete;
bool m_mergeBlocksAfterDelete;
bool m_needPlaceholder;
- bool m_replace;
bool m_expandForSpecialElements;
bool m_pruneStartBlockIfNecessary;
bool m_startsAtEmptyLine;
@@ -89,15 +88,15 @@ private:
Position m_endingPosition;
Position m_leadingWhitespace;
Position m_trailingWhitespace;
- RefPtr<Node> m_startBlock;
- RefPtr<Node> m_endBlock;
- RefPtr<EditingStyle> m_typingStyle;
- RefPtr<EditingStyle> m_deleteIntoBlockquoteStyle;
- RefPtr<Node> m_startRoot;
- RefPtr<Node> m_endRoot;
- RefPtr<Node> m_startTableRow;
- RefPtr<Node> m_endTableRow;
- RefPtr<Node> m_temporaryPlaceholder;
+ RefPtrWillBeMember<Node> m_startBlock;
+ RefPtrWillBeMember<Node> m_endBlock;
+ RefPtrWillBeMember<EditingStyle> m_typingStyle;
+ RefPtrWillBeMember<EditingStyle> m_deleteIntoBlockquoteStyle;
+ RefPtrWillBeMember<Node> m_startRoot;
+ RefPtrWillBeMember<Node> m_endRoot;
+ RefPtrWillBeMember<Node> m_startTableRow;
+ RefPtrWillBeMember<Node> m_endTableRow;
+ RefPtrWillBeMember<Node> m_temporaryPlaceholder;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/EditCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/EditCommand.cpp
index 4b318f763d8..9f4e60b06c0 100644
--- a/chromium/third_party/WebKit/Source/core/editing/EditCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/EditCommand.cpp
@@ -30,13 +30,13 @@
#include "core/dom/NodeTraversal.h"
#include "core/editing/CompositeEditCommand.h"
#include "core/editing/FrameSelection.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
EditCommand::EditCommand(Document& document)
: m_document(&document)
- , m_parent(0)
+ , m_parent(nullptr)
{
ASSERT(m_document);
ASSERT(m_document->frame());
@@ -46,7 +46,7 @@ EditCommand::EditCommand(Document& document)
EditCommand::EditCommand(Document* document, const VisibleSelection& startingSelection, const VisibleSelection& endingSelection)
: m_document(document)
- , m_parent(0)
+ , m_parent(nullptr)
{
ASSERT(m_document);
ASSERT(m_document->frame());
@@ -70,30 +70,40 @@ static inline EditCommandComposition* compositionIfPossible(EditCommand* command
return toCompositeEditCommand(command)->composition();
}
-void EditCommand::setStartingSelection(const VisibleSelection& s)
+void EditCommand::setStartingSelection(const VisibleSelection& selection)
{
- for (EditCommand* cmd = this; ; cmd = cmd->m_parent) {
- if (EditCommandComposition* composition = compositionIfPossible(cmd)) {
- ASSERT(cmd->isTopLevelCommand());
- composition->setStartingSelection(s);
+ for (EditCommand* command = this; ; command = command->m_parent) {
+ if (EditCommandComposition* composition = compositionIfPossible(command)) {
+ ASSERT(command->isTopLevelCommand());
+ composition->setStartingSelection(selection);
}
- cmd->m_startingSelection = s;
- if (!cmd->m_parent || cmd->m_parent->isFirstCommand(cmd))
+ command->m_startingSelection = selection;
+ if (!command->m_parent || command->m_parent->isFirstCommand(command))
break;
}
}
-void EditCommand::setEndingSelection(const VisibleSelection &s)
+void EditCommand::setStartingSelection(const VisiblePosition& position)
{
- for (EditCommand* cmd = this; cmd; cmd = cmd->m_parent) {
- if (EditCommandComposition* composition = compositionIfPossible(cmd)) {
- ASSERT(cmd->isTopLevelCommand());
- composition->setEndingSelection(s);
+ setStartingSelection(VisibleSelection(position));
+}
+
+void EditCommand::setEndingSelection(const VisibleSelection& selection)
+{
+ for (EditCommand* command = this; command; command = command->m_parent) {
+ if (EditCommandComposition* composition = compositionIfPossible(command)) {
+ ASSERT(command->isTopLevelCommand());
+ composition->setEndingSelection(selection);
}
- cmd->m_endingSelection = s;
+ command->m_endingSelection = selection;
}
}
+void EditCommand::setEndingSelection(const VisiblePosition& position)
+{
+ setEndingSelection(VisibleSelection(position));
+}
+
void EditCommand::setParent(CompositeEditCommand* parent)
{
ASSERT((parent && !m_parent) || (!parent && m_parent));
@@ -110,4 +120,12 @@ void SimpleEditCommand::doReapply()
doApply();
}
+void EditCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_startingSelection);
+ visitor->trace(m_endingSelection);
+ visitor->trace(m_parent);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/EditCommand.h b/chromium/third_party/WebKit/Source/core/editing/EditCommand.h
index e9dc8bea960..4b9a2ec49dd 100644
--- a/chromium/third_party/WebKit/Source/core/editing/EditCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/EditCommand.h
@@ -28,6 +28,7 @@
#include "core/editing/EditAction.h"
#include "core/editing/VisibleSelection.h"
+#include "platform/heap/Handle.h"
#ifndef NDEBUG
#include "wtf/HashSet.h"
@@ -39,7 +40,7 @@ class CompositeEditCommand;
class Document;
class Element;
-class EditCommand : public RefCounted<EditCommand> {
+class EditCommand : public RefCountedWillBeGarbageCollectedFinalized<EditCommand> {
public:
virtual ~EditCommand();
@@ -52,11 +53,12 @@ public:
virtual bool isSimpleEditCommand() const { return false; }
virtual bool isCompositeEditCommand() const { return false; }
- virtual bool isEditCommandComposition() const { return false; }
bool isTopLevelCommand() const { return !m_parent; }
virtual void doApply() = 0;
+ virtual void trace(Visitor*);
+
protected:
explicit EditCommand(Document&);
EditCommand(Document*, const VisibleSelection&, const VisibleSelection&);
@@ -64,13 +66,15 @@ protected:
Document& document() const { return *m_document.get(); }
CompositeEditCommand* parent() const { return m_parent; }
void setStartingSelection(const VisibleSelection&);
+ void setStartingSelection(const VisiblePosition&);
void setEndingSelection(const VisibleSelection&);
+ void setEndingSelection(const VisiblePosition&);
private:
- RefPtr<Document> m_document;
+ RefPtrWillBeMember<Document> m_document;
VisibleSelection m_startingSelection;
VisibleSelection m_endingSelection;
- CompositeEditCommand* m_parent;
+ RawPtrWillBeMember<CompositeEditCommand> m_parent;
};
enum ShouldAssumeContentIsAlwaysEditable {
@@ -87,7 +91,7 @@ protected:
explicit SimpleEditCommand(Document& document) : EditCommand(document) { }
private:
- virtual bool isSimpleEditCommand() const OVERRIDE { return true; }
+ virtual bool isSimpleEditCommand() const OVERRIDE FINAL { return true; }
};
DEFINE_TYPE_CASTS(SimpleEditCommand, EditCommand, command, command->isSimpleEditCommand(), command.isSimpleEditCommand());
diff --git a/chromium/third_party/WebKit/Source/core/editing/EditingBehavior.cpp b/chromium/third_party/WebKit/Source/core/editing/EditingBehavior.cpp
new file mode 100644
index 00000000000..df9d0970ef2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/editing/EditingBehavior.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2006, 2007 Apple, Inc. All rights reserved.
+ * Copyright (C) 2012 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/editing/EditingBehavior.h"
+
+#include "core/events/KeyboardEvent.h"
+#include "platform/KeyboardCodes.h"
+#include "platform/PlatformKeyboardEvent.h"
+
+namespace WebCore {
+
+//
+// The below code was adapted from the WebKit file webview.cpp
+//
+
+static const unsigned CtrlKey = 1 << 0;
+static const unsigned AltKey = 1 << 1;
+static const unsigned ShiftKey = 1 << 2;
+static const unsigned MetaKey = 1 << 3;
+#if OS(MACOSX)
+// Aliases for the generic key defintions to make kbd shortcuts definitions more
+// readable on OS X.
+static const unsigned OptionKey = AltKey;
+
+// Do not use this constant for anything but cursor movement commands. Keys
+// with cmd set have their |isSystemKey| bit set, so chances are the shortcut
+// will not be executed. Another, less important, reason is that shortcuts
+// defined in the renderer do not blink the menu item that they triggered. See
+// http://crbug.com/25856 and the bugs linked from there for details.
+static const unsigned CommandKey = MetaKey;
+#endif
+
+// Keys with special meaning. These will be delegated to the editor using
+// the execCommand() method
+struct KeyDownEntry {
+ unsigned virtualKey;
+ unsigned modifiers;
+ const char* name;
+};
+
+struct KeyPressEntry {
+ unsigned charCode;
+ unsigned modifiers;
+ const char* name;
+};
+
+// Key bindings with command key on Mac and alt key on other platforms are
+// marked as system key events and will be ignored (with the exception
+// of Command-B and Command-I) so they shouldn't be added here.
+static const KeyDownEntry keyDownEntries[] = {
+ { VKEY_LEFT, 0, "MoveLeft" },
+ { VKEY_LEFT, ShiftKey, "MoveLeftAndModifySelection" },
+#if OS(MACOSX)
+ { VKEY_LEFT, OptionKey, "MoveWordLeft" },
+ { VKEY_LEFT, OptionKey | ShiftKey,
+ "MoveWordLeftAndModifySelection" },
+#else
+ { VKEY_LEFT, CtrlKey, "MoveWordLeft" },
+ { VKEY_LEFT, CtrlKey | ShiftKey,
+ "MoveWordLeftAndModifySelection" },
+#endif
+ { VKEY_RIGHT, 0, "MoveRight" },
+ { VKEY_RIGHT, ShiftKey, "MoveRightAndModifySelection" },
+#if OS(MACOSX)
+ { VKEY_RIGHT, OptionKey, "MoveWordRight" },
+ { VKEY_RIGHT, OptionKey | ShiftKey, "MoveWordRightAndModifySelection" },
+#else
+ { VKEY_RIGHT, CtrlKey, "MoveWordRight" },
+ { VKEY_RIGHT, CtrlKey | ShiftKey, "MoveWordRightAndModifySelection" },
+#endif
+ { VKEY_UP, 0, "MoveUp" },
+ { VKEY_UP, ShiftKey, "MoveUpAndModifySelection" },
+ { VKEY_PRIOR, ShiftKey, "MovePageUpAndModifySelection" },
+ { VKEY_DOWN, 0, "MoveDown" },
+ { VKEY_DOWN, ShiftKey, "MoveDownAndModifySelection" },
+ { VKEY_NEXT, ShiftKey, "MovePageDownAndModifySelection" },
+#if !OS(MACOSX)
+ { VKEY_UP, CtrlKey, "MoveParagraphBackward" },
+ { VKEY_UP, CtrlKey | ShiftKey, "MoveParagraphBackwardAndModifySelection" },
+ { VKEY_DOWN, CtrlKey, "MoveParagraphForward" },
+ { VKEY_DOWN, CtrlKey | ShiftKey, "MoveParagraphForwardAndModifySelection" },
+ { VKEY_PRIOR, 0, "MovePageUp" },
+ { VKEY_NEXT, 0, "MovePageDown" },
+#endif
+ { VKEY_HOME, 0, "MoveToBeginningOfLine" },
+ { VKEY_HOME, ShiftKey,
+ "MoveToBeginningOfLineAndModifySelection" },
+#if OS(MACOSX)
+ { VKEY_PRIOR, OptionKey, "MovePageUp" },
+ { VKEY_NEXT, OptionKey, "MovePageDown" },
+#endif
+#if !OS(MACOSX)
+ { VKEY_HOME, CtrlKey, "MoveToBeginningOfDocument" },
+ { VKEY_HOME, CtrlKey | ShiftKey,
+ "MoveToBeginningOfDocumentAndModifySelection" },
+#endif
+ { VKEY_END, 0, "MoveToEndOfLine" },
+ { VKEY_END, ShiftKey, "MoveToEndOfLineAndModifySelection" },
+#if !OS(MACOSX)
+ { VKEY_END, CtrlKey, "MoveToEndOfDocument" },
+ { VKEY_END, CtrlKey | ShiftKey,
+ "MoveToEndOfDocumentAndModifySelection" },
+#endif
+ { VKEY_BACK, 0, "DeleteBackward" },
+ { VKEY_BACK, ShiftKey, "DeleteBackward" },
+ { VKEY_DELETE, 0, "DeleteForward" },
+#if OS(MACOSX)
+ { VKEY_BACK, OptionKey, "DeleteWordBackward" },
+ { VKEY_DELETE, OptionKey, "DeleteWordForward" },
+#else
+ { VKEY_BACK, CtrlKey, "DeleteWordBackward" },
+ { VKEY_DELETE, CtrlKey, "DeleteWordForward" },
+#endif
+#if OS(MACOSX)
+ { 'B', CommandKey, "ToggleBold" },
+ { 'I', CommandKey, "ToggleItalic" },
+#else
+ { 'B', CtrlKey, "ToggleBold" },
+ { 'I', CtrlKey, "ToggleItalic" },
+#endif
+ { 'U', CtrlKey, "ToggleUnderline" },
+ { VKEY_ESCAPE, 0, "Cancel" },
+ { VKEY_OEM_PERIOD, CtrlKey, "Cancel" },
+ { VKEY_TAB, 0, "InsertTab" },
+ { VKEY_TAB, ShiftKey, "InsertBacktab" },
+ { VKEY_RETURN, 0, "InsertNewline" },
+ { VKEY_RETURN, CtrlKey, "InsertNewline" },
+ { VKEY_RETURN, AltKey, "InsertNewline" },
+ { VKEY_RETURN, AltKey | ShiftKey, "InsertNewline" },
+ { VKEY_RETURN, ShiftKey, "InsertLineBreak" },
+ { VKEY_INSERT, CtrlKey, "Copy" },
+ { VKEY_INSERT, ShiftKey, "Paste" },
+ { VKEY_DELETE, ShiftKey, "Cut" },
+#if !OS(MACOSX)
+ // On OS X, we pipe these back to the browser, so that it can do menu item
+ // blinking.
+ { 'C', CtrlKey, "Copy" },
+ { 'V', CtrlKey, "Paste" },
+ { 'V', CtrlKey | ShiftKey, "PasteAndMatchStyle" },
+ { 'X', CtrlKey, "Cut" },
+ { 'A', CtrlKey, "SelectAll" },
+ { 'Z', CtrlKey, "Undo" },
+ { 'Z', CtrlKey | ShiftKey, "Redo" },
+ { 'Y', CtrlKey, "Redo" },
+#endif
+ { VKEY_INSERT, 0, "OverWrite" },
+};
+
+static const KeyPressEntry keyPressEntries[] = {
+ { '\t', 0, "InsertTab" },
+ { '\t', ShiftKey, "InsertBacktab" },
+ { '\r', 0, "InsertNewline" },
+ { '\r', CtrlKey, "InsertNewline" },
+ { '\r', ShiftKey, "InsertLineBreak" },
+ { '\r', AltKey, "InsertNewline" },
+ { '\r', AltKey | ShiftKey, "InsertNewline" },
+};
+
+const char* EditingBehavior::interpretKeyEvent(const KeyboardEvent& event) const
+{
+ const PlatformKeyboardEvent* keyEvent = event.keyEvent();
+ if (!keyEvent)
+ return "";
+
+ static HashMap<int, const char*>* keyDownCommandsMap = 0;
+ static HashMap<int, const char*>* keyPressCommandsMap = 0;
+
+ if (!keyDownCommandsMap) {
+ keyDownCommandsMap = new HashMap<int, const char*>;
+ keyPressCommandsMap = new HashMap<int, const char*>;
+
+ for (unsigned i = 0; i < arraysize(keyDownEntries); i++) {
+ keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
+ }
+
+ for (unsigned i = 0; i < arraysize(keyPressEntries); i++) {
+ keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
+ }
+ }
+
+ unsigned modifiers = 0;
+ if (keyEvent->shiftKey())
+ modifiers |= ShiftKey;
+ if (keyEvent->altKey())
+ modifiers |= AltKey;
+ if (keyEvent->ctrlKey())
+ modifiers |= CtrlKey;
+ if (keyEvent->metaKey())
+ modifiers |= MetaKey;
+
+ if (keyEvent->type() == PlatformEvent::RawKeyDown) {
+ int mapKey = modifiers << 16 | event.keyCode();
+ return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
+ }
+
+ int mapKey = modifiers << 16 | event.charCode();
+ return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
+}
+
+bool EditingBehavior::shouldInsertCharacter(const KeyboardEvent& event) const
+{
+ if (event.keyEvent()->text().length() != 1)
+ return true;
+
+ // On Gtk/Linux, it emits key events with ASCII text and ctrl on for ctrl-<x>.
+ // In Webkit, EditorClient::handleKeyboardEvent in
+ // WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp drop such events.
+ // On Mac, it emits key events with ASCII text and meta on for Command-<x>.
+ // These key events should not emit text insert event.
+ // Alt key would be used to insert alternative character, so we should let
+ // through. Also note that Ctrl-Alt combination equals to AltGr key which is
+ // also used to insert alternative character.
+ // http://code.google.com/p/chromium/issues/detail?id=10846
+ // Windows sets both alt and meta are on when "Alt" key pressed.
+ // http://code.google.com/p/chromium/issues/detail?id=2215
+ // Also, we should not rely on an assumption that keyboards don't
+ // send ASCII characters when pressing a control key on Windows,
+ // which may be configured to do it so by user.
+ // See also http://en.wikipedia.org/wiki/Keyboard_Layout
+ // FIXME(ukai): investigate more detail for various keyboard layout.
+ UChar ch = event.keyEvent()->text()[0U];
+
+ // Don't insert null or control characters as they can result in
+ // unexpected behaviour
+ if (ch < ' ')
+ return false;
+#if !OS(WIN)
+ // Don't insert ASCII character if ctrl w/o alt or meta is on.
+ // On Mac, we should ignore events when meta is on (Command-<x>).
+ if (ch < 0x80) {
+ if (event.keyEvent()->ctrlKey() && !event.keyEvent()->altKey())
+ return false;
+#if OS(MACOSX)
+ if (event.keyEvent()->metaKey())
+ return false;
+#endif
+ }
+#endif
+
+ return true;
+}
+} // namespace WebCore
+
diff --git a/chromium/third_party/WebKit/Source/core/editing/EditingBehavior.h b/chromium/third_party/WebKit/Source/core/editing/EditingBehavior.h
index ec1a775463c..1f92193fb8f 100644
--- a/chromium/third_party/WebKit/Source/core/editing/EditingBehavior.h
+++ b/chromium/third_party/WebKit/Source/core/editing/EditingBehavior.h
@@ -24,6 +24,7 @@
#include "core/editing/EditingBehaviorTypes.h"
namespace WebCore {
+class KeyboardEvent;
class EditingBehavior {
@@ -37,11 +38,11 @@ public:
// Create a new function for any platform difference so we can control it here.
// When extending a selection beyond the top or bottom boundary of an editable area,
- // maintain the horizontal position on Windows but extend it to the boundary of the editable
- // content on Mac.
+ // maintain the horizontal position on Windows and Android but extend it to the boundary of
+ // the editable content on Mac and Linux.
bool shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom() const
{
- return m_type != EditingWindowsBehavior && m_type != EditingAndroidBehavior && m_type != EditingUnixBehavior;
+ return m_type != EditingWindowsBehavior && m_type != EditingAndroidBehavior;
}
// On Windows, selections should always be considered as directional, regardless if it is
@@ -90,6 +91,11 @@ public:
return m_type != EditingWindowsBehavior && m_type != EditingMacBehavior;
}
+ // Convert a KeyboardEvent to a command name like "Copy", "Undo" and so on.
+ // If nothing, return empty string.
+ const char* interpretKeyEvent(const KeyboardEvent&) const;
+
+ bool shouldInsertCharacter(const KeyboardEvent&) const;
private:
EditingBehaviorType m_type;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/EditingStyle.cpp b/chromium/third_party/WebKit/Source/core/editing/EditingStyle.cpp
index 8fe59c18fdc..c0fdd1fb75b 100644
--- a/chromium/third_party/WebKit/Source/core/editing/EditingStyle.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/EditingStyle.cpp
@@ -27,10 +27,10 @@
#include "config.h"
#include "core/editing/EditingStyle.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSComputedStyleDeclaration.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/CSSValueList.h"
@@ -49,7 +49,7 @@
#include "core/editing/FrameSelection.h"
#include "core/editing/HTMLInterchange.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFontElement.h"
#include "core/rendering/style/RenderStyle.h"
@@ -122,7 +122,7 @@ static const Vector<CSSPropertyID>& inheritableEditingProperties()
}
template <class StyleDeclarationType>
-static PassRefPtr<MutableStylePropertySet> copyEditingProperties(StyleDeclarationType* style, EditingPropertiesType type = OnlyInheritableEditingProperties)
+static PassRefPtrWillBeRawPtr<MutableStylePropertySet> copyEditingProperties(StyleDeclarationType* style, EditingPropertiesType type = OnlyInheritableEditingProperties)
{
if (type == AllEditingProperties)
return style->copyPropertiesInSet(allEditingProperties());
@@ -134,45 +134,49 @@ static inline bool isEditingProperty(int id)
return allEditingProperties().contains(static_cast<CSSPropertyID>(id));
}
-static PassRefPtr<MutableStylePropertySet> editingStyleFromComputedStyle(PassRefPtr<CSSComputedStyleDeclaration> style, EditingPropertiesType type = OnlyInheritableEditingProperties)
+static PassRefPtrWillBeRawPtr<MutableStylePropertySet> editingStyleFromComputedStyle(PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style, EditingPropertiesType type = OnlyInheritableEditingProperties)
{
if (!style)
return MutableStylePropertySet::create();
return copyEditingProperties(style.get(), type);
}
-static PassRefPtr<MutableStylePropertySet> getPropertiesNotIn(StylePropertySet* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle);
+static PassRefPtrWillBeRawPtr<MutableStylePropertySet> getPropertiesNotIn(StylePropertySet* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle);
enum LegacyFontSizeMode { AlwaysUseLegacyFontSize, UseLegacyFontSizeOnlyIfPixelValuesMatch };
static int legacyFontSizeFromCSSValue(Document*, CSSPrimitiveValue*, bool shouldUseFixedFontDefaultSize, LegacyFontSizeMode);
static bool isTransparentColorValue(CSSValue*);
static bool hasTransparentBackgroundColor(CSSStyleDeclaration*);
static bool hasTransparentBackgroundColor(StylePropertySet*);
-static PassRefPtr<CSSValue> backgroundColorInEffect(Node*);
+static PassRefPtrWillBeRawPtr<CSSValue> backgroundColorInEffect(Node*);
-class HTMLElementEquivalent {
- WTF_MAKE_FAST_ALLOCATED;
+class HTMLElementEquivalent : public NoBaseWillBeGarbageCollected<HTMLElementEquivalent> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(HTMLElementEquivalent);
public:
- static PassOwnPtr<HTMLElementEquivalent> create(CSSPropertyID propertyID, CSSValueID primitiveValue, const QualifiedName& tagName)
+ static PassOwnPtrWillBeRawPtr<HTMLElementEquivalent> create(CSSPropertyID propertyID, CSSValueID primitiveValue, const QualifiedName& tagName)
{
- return adoptPtr(new HTMLElementEquivalent(propertyID, primitiveValue, tagName));
+ return adoptPtrWillBeNoop(new HTMLElementEquivalent(propertyID, primitiveValue, tagName));
}
- virtual ~HTMLElementEquivalent() { }
virtual bool matches(const Element* element) const { return !m_tagName || element->hasTagName(*m_tagName); }
virtual bool hasAttribute() const { return false; }
virtual bool propertyExistsInStyle(const StylePropertySet* style) const { return style->getPropertyCSSValue(m_propertyID); }
virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const;
virtual void addToStyle(Element*, EditingStyle*) const;
+ virtual void trace(Visitor* visitor) { visitor->trace(m_primitiveValue); }
+
protected:
HTMLElementEquivalent(CSSPropertyID);
HTMLElementEquivalent(CSSPropertyID, const QualifiedName& tagName);
HTMLElementEquivalent(CSSPropertyID, CSSValueID primitiveValue, const QualifiedName& tagName);
const CSSPropertyID m_propertyID;
- const RefPtr<CSSPrimitiveValue> m_primitiveValue;
+ const RefPtrWillBeMember<CSSPrimitiveValue> m_primitiveValue;
const QualifiedName* m_tagName; // We can store a pointer because HTML tag names are const global.
};
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(HTMLElementEquivalent);
+
HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id)
: m_propertyID(id)
, m_tagName(0)
@@ -195,7 +199,7 @@ HTMLElementEquivalent::HTMLElementEquivalent(CSSPropertyID id, CSSValueID primit
bool HTMLElementEquivalent::valueIsPresentInStyle(Element* element, StylePropertySet* style) const
{
- RefPtr<CSSValue> value = style->getPropertyCSSValue(m_propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(m_propertyID);
return matches(element) && value && value->isPrimitiveValue() && toCSSPrimitiveValue(value.get())->getValueID() == m_primitiveValue->getValueID();
}
@@ -204,14 +208,16 @@ void HTMLElementEquivalent::addToStyle(Element*, EditingStyle* style) const
style->setProperty(m_propertyID, m_primitiveValue->cssText());
}
-class HTMLTextDecorationEquivalent : public HTMLElementEquivalent {
+class HTMLTextDecorationEquivalent FINAL : public HTMLElementEquivalent {
public:
- static PassOwnPtr<HTMLElementEquivalent> create(CSSValueID primitiveValue, const QualifiedName& tagName)
+ static PassOwnPtrWillBeRawPtr<HTMLElementEquivalent> create(CSSValueID primitiveValue, const QualifiedName& tagName)
{
- return adoptPtr(new HTMLTextDecorationEquivalent(primitiveValue, tagName));
+ return adoptPtrWillBeNoop(new HTMLTextDecorationEquivalent(primitiveValue, tagName));
}
- virtual bool propertyExistsInStyle(const StylePropertySet*) const;
- virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const;
+ virtual bool propertyExistsInStyle(const StylePropertySet*) const OVERRIDE;
+ virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const OVERRIDE;
+
+ virtual void trace(Visitor* visitor) OVERRIDE { HTMLElementEquivalent::trace(visitor); }
private:
HTMLTextDecorationEquivalent(CSSValueID primitiveValue, const QualifiedName& tagName);
@@ -231,7 +237,7 @@ bool HTMLTextDecorationEquivalent::propertyExistsInStyle(const StylePropertySet*
bool HTMLTextDecorationEquivalent::valueIsPresentInStyle(Element* element, StylePropertySet* style) const
{
- RefPtr<CSSValue> styleValue = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
+ RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
if (!styleValue)
styleValue = style->getPropertyCSSValue(textDecorationPropertyForEditing());
return matches(element) && styleValue && styleValue->isValueList() && toCSSValueList(styleValue.get())->hasValue(m_primitiveValue.get());
@@ -239,22 +245,24 @@ bool HTMLTextDecorationEquivalent::valueIsPresentInStyle(Element* element, Style
class HTMLAttributeEquivalent : public HTMLElementEquivalent {
public:
- static PassOwnPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const QualifiedName& tagName, const QualifiedName& attrName)
+ static PassOwnPtrWillBeRawPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const QualifiedName& tagName, const QualifiedName& attrName)
{
- return adoptPtr(new HTMLAttributeEquivalent(propertyID, tagName, attrName));
+ return adoptPtrWillBeNoop(new HTMLAttributeEquivalent(propertyID, tagName, attrName));
}
- static PassOwnPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const QualifiedName& attrName)
+ static PassOwnPtrWillBeRawPtr<HTMLAttributeEquivalent> create(CSSPropertyID propertyID, const QualifiedName& attrName)
{
- return adoptPtr(new HTMLAttributeEquivalent(propertyID, attrName));
+ return adoptPtrWillBeNoop(new HTMLAttributeEquivalent(propertyID, attrName));
}
- bool matches(const Element* elem) const { return HTMLElementEquivalent::matches(elem) && elem->hasAttribute(m_attrName); }
- virtual bool hasAttribute() const { return true; }
- virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const;
- virtual void addToStyle(Element*, EditingStyle*) const;
- virtual PassRefPtr<CSSValue> attributeValueAsCSSValue(Element*) const;
+ virtual bool matches(const Element* elem) const OVERRIDE { return HTMLElementEquivalent::matches(elem) && elem->hasAttribute(m_attrName); }
+ virtual bool hasAttribute() const OVERRIDE { return true; }
+ virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const OVERRIDE;
+ virtual void addToStyle(Element*, EditingStyle*) const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*) const;
inline const QualifiedName& attributeName() const { return m_attrName; }
+ virtual void trace(Visitor* visitor) OVERRIDE { HTMLElementEquivalent::trace(visitor); }
+
protected:
HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& tagName, const QualifiedName& attrName);
HTMLAttributeEquivalent(CSSPropertyID, const QualifiedName& attrName);
@@ -275,37 +283,40 @@ HTMLAttributeEquivalent::HTMLAttributeEquivalent(CSSPropertyID id, const Qualifi
bool HTMLAttributeEquivalent::valueIsPresentInStyle(Element* element, StylePropertySet* style) const
{
- RefPtr<CSSValue> value = attributeValueAsCSSValue(element);
- RefPtr<CSSValue> styleValue = style->getPropertyCSSValue(m_propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element);
+ RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(m_propertyID);
return compareCSSValuePtr(value, styleValue);
}
void HTMLAttributeEquivalent::addToStyle(Element* element, EditingStyle* style) const
{
- if (RefPtr<CSSValue> value = attributeValueAsCSSValue(element))
+ if (RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element))
style->setProperty(m_propertyID, value->cssText());
}
-PassRefPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSValue(Element* element) const
+PassRefPtrWillBeRawPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSValue(Element* element) const
{
ASSERT(element);
- if (!element->hasAttribute(m_attrName))
- return 0;
+ const AtomicString& value = element->getAttribute(m_attrName);
+ if (value.isNull())
+ return nullptr;
- RefPtr<MutableStylePropertySet> dummyStyle;
+ RefPtrWillBeRawPtr<MutableStylePropertySet> dummyStyle = nullptr;
dummyStyle = MutableStylePropertySet::create();
- dummyStyle->setProperty(m_propertyID, element->getAttribute(m_attrName));
+ dummyStyle->setProperty(m_propertyID, value);
return dummyStyle->getPropertyCSSValue(m_propertyID);
}
-class HTMLFontSizeEquivalent : public HTMLAttributeEquivalent {
+class HTMLFontSizeEquivalent FINAL : public HTMLAttributeEquivalent {
public:
- static PassOwnPtr<HTMLFontSizeEquivalent> create()
+ static PassOwnPtrWillBeRawPtr<HTMLFontSizeEquivalent> create()
{
- return adoptPtr(new HTMLFontSizeEquivalent());
+ return adoptPtrWillBeNoop(new HTMLFontSizeEquivalent());
}
- virtual PassRefPtr<CSSValue> attributeValueAsCSSValue(Element*) const;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*) const OVERRIDE;
+
+ virtual void trace(Visitor* visitor) OVERRIDE { HTMLAttributeEquivalent::trace(visitor); }
private:
HTMLFontSizeEquivalent();
@@ -316,14 +327,15 @@ HTMLFontSizeEquivalent::HTMLFontSizeEquivalent()
{
}
-PassRefPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValue(Element* element) const
+PassRefPtrWillBeRawPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValue(Element* element) const
{
ASSERT(element);
- if (!element->hasAttribute(m_attrName))
- return 0;
+ const AtomicString& value = element->getAttribute(m_attrName);
+ if (value.isNull())
+ return nullptr;
CSSValueID size;
- if (!HTMLFontElement::cssValueFromFontSizeNumber(element->getAttribute(m_attrName), size))
- return 0;
+ if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
+ return nullptr;
return CSSPrimitiveValue::createIdentifier(size);
}
@@ -350,15 +362,7 @@ EditingStyle::EditingStyle(const Position& position, PropertiesToInclude propert
}
EditingStyle::EditingStyle(const StylePropertySet* style)
- : m_mutableStyle(style ? style->mutableCopy() : 0)
- , m_shouldUseFixedDefaultFontSize(false)
- , m_fontSizeDelta(NoFontDelta)
-{
- extractFontSizeDelta();
-}
-
-EditingStyle::EditingStyle(const CSSStyleDeclaration* style)
- : m_mutableStyle(style ? style->copyProperties() : 0)
+ : m_mutableStyle(style ? style->mutableCopy() : nullptr)
, m_shouldUseFixedDefaultFontSize(false)
, m_fontSizeDelta(NoFontDelta)
{
@@ -366,7 +370,7 @@ EditingStyle::EditingStyle(const CSSStyleDeclaration* style)
}
EditingStyle::EditingStyle(CSSPropertyID propertyID, const String& value)
- : m_mutableStyle(0)
+ : m_mutableStyle(nullptr)
, m_shouldUseFixedDefaultFontSize(false)
, m_fontSizeDelta(NoFontDelta)
{
@@ -387,7 +391,7 @@ static RGBA32 cssValueToRGBA(CSSValue* colorValue)
return primitiveColor->getRGBA32Value();
RGBA32 rgba = 0;
- CSSParser::parseColor(rgba, colorValue->cssText());
+ BisonCSSParser::parseColor(rgba, colorValue->cssText());
return rgba;
}
@@ -451,13 +455,13 @@ void EditingStyle::init(Node* node, PropertiesToInclude propertiesToInclude)
else if (isTabSpanNode(node))
node = node->parentNode();
- RefPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = CSSComputedStyleDeclaration::create(node);
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleAtPosition = CSSComputedStyleDeclaration::create(node);
m_mutableStyle = propertiesToInclude == AllProperties && computedStyleAtPosition ? computedStyleAtPosition->copyProperties() : editingStyleFromComputedStyle(computedStyleAtPosition);
if (propertiesToInclude == EditingPropertiesInEffect) {
- if (RefPtr<CSSValue> value = backgroundColorInEffect(node))
+ if (RefPtrWillBeRawPtr<CSSValue> value = backgroundColorInEffect(node))
m_mutableStyle->setProperty(CSSPropertyBackgroundColor, value->cssText());
- if (RefPtr<CSSValue> value = computedStyleAtPosition->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect))
+ if (RefPtrWillBeRawPtr<CSSValue> value = computedStyleAtPosition->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect))
m_mutableStyle->setProperty(CSSPropertyTextDecoration, value->cssText());
}
@@ -473,12 +477,12 @@ void EditingStyle::init(Node* node, PropertiesToInclude propertiesToInclude)
void EditingStyle::removeTextFillAndStrokeColorsIfNeeded(RenderStyle* renderStyle)
{
- // If a node's text fill color is invalid, then its children use
+ // If a node's text fill color is currentColor, then its children use
// their font-color as their text fill color (they don't
// inherit it). Likewise for stroke color.
- if (!renderStyle->textFillColor().isValid())
+ if (renderStyle->textFillColor().isCurrentColor())
m_mutableStyle->removeProperty(CSSPropertyWebkitTextFillColor);
- if (!renderStyle->textStrokeColor().isValid())
+ if (renderStyle->textStrokeColor().isCurrentColor())
m_mutableStyle->removeProperty(CSSPropertyWebkitTextStrokeColor);
}
@@ -509,7 +513,7 @@ void EditingStyle::extractFontSizeDelta()
}
// Get the adjustment amount out of the style.
- RefPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitFontSizeDelta);
+ RefPtrWillBeRawPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitFontSizeDelta);
if (!value || !value->isPrimitiveValue())
return;
@@ -534,13 +538,13 @@ bool EditingStyle::textDirection(WritingDirection& writingDirection) const
if (!m_mutableStyle)
return false;
- RefPtr<CSSValue> unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+ RefPtrWillBeRawPtr<CSSValue> unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
return false;
CSSValueID unicodeBidiValue = toCSSPrimitiveValue(unicodeBidi.get())->getValueID();
if (unicodeBidiValue == CSSValueEmbed) {
- RefPtr<CSSValue> direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
+ RefPtrWillBeRawPtr<CSSValue> direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
if (!direction || !direction->isPrimitiveValue())
return false;
@@ -557,15 +561,6 @@ bool EditingStyle::textDirection(WritingDirection& writingDirection) const
return false;
}
-void EditingStyle::setStyle(PassRefPtr<MutableStylePropertySet> style)
-{
- m_mutableStyle = style;
- // FIXME: We should be able to figure out whether or not font is fixed width for mutable style.
- // We need to check font-family is monospace as in FontDescription but we don't want to duplicate code here.
- m_shouldUseFixedDefaultFontSize = false;
- extractFontSizeDelta();
-}
-
void EditingStyle::overrideWithStyle(const StylePropertySet* style)
{
if (!style || style->isEmpty())
@@ -583,9 +578,9 @@ void EditingStyle::clear()
m_fontSizeDelta = NoFontDelta;
}
-PassRefPtr<EditingStyle> EditingStyle::copy() const
+PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::copy() const
{
- RefPtr<EditingStyle> copy = EditingStyle::create();
+ RefPtrWillBeRawPtr<EditingStyle> copy = EditingStyle::create();
if (m_mutableStyle)
copy->m_mutableStyle = m_mutableStyle->mutableCopy();
copy->m_shouldUseFixedDefaultFontSize = m_shouldUseFixedDefaultFontSize;
@@ -593,9 +588,9 @@ PassRefPtr<EditingStyle> EditingStyle::copy() const
return copy;
}
-PassRefPtr<EditingStyle> EditingStyle::extractAndRemoveBlockProperties()
+PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::extractAndRemoveBlockProperties()
{
- RefPtr<EditingStyle> blockProperties = EditingStyle::create();
+ RefPtrWillBeRawPtr<EditingStyle> blockProperties = EditingStyle::create();
if (!m_mutableStyle)
return blockProperties;
@@ -605,9 +600,9 @@ PassRefPtr<EditingStyle> EditingStyle::extractAndRemoveBlockProperties()
return blockProperties;
}
-PassRefPtr<EditingStyle> EditingStyle::extractAndRemoveTextDirection()
+PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::extractAndRemoveTextDirection()
{
- RefPtr<EditingStyle> textDirection = EditingStyle::create();
+ RefPtrWillBeRawPtr<EditingStyle> textDirection = EditingStyle::create();
textDirection->m_mutableStyle = MutableStylePropertySet::create();
textDirection->m_mutableStyle->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed, m_mutableStyle->propertyIsImportant(CSSPropertyUnicodeBidi));
textDirection->m_mutableStyle->setProperty(CSSPropertyDirection, m_mutableStyle->getPropertyValue(CSSPropertyDirection),
@@ -631,10 +626,10 @@ void EditingStyle::removeStyleAddedByNode(Node* node)
{
if (!node || !node->parentNode())
return;
- RefPtr<MutableStylePropertySet> parentStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(node->parentNode()), AllEditingProperties);
- RefPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(node), AllEditingProperties);
- nodeStyle->removeEquivalentProperties(parentStyle->ensureCSSStyleDeclaration());
- m_mutableStyle->removeEquivalentProperties(nodeStyle->ensureCSSStyleDeclaration());
+ RefPtrWillBeRawPtr<MutableStylePropertySet> parentStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(node->parentNode()), AllEditingProperties);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(node), AllEditingProperties);
+ nodeStyle->removeEquivalentProperties(parentStyle.get());
+ m_mutableStyle->removeEquivalentProperties(nodeStyle.get());
}
void EditingStyle::removeStyleConflictingWithStyleOfNode(Node* node)
@@ -642,9 +637,9 @@ void EditingStyle::removeStyleConflictingWithStyleOfNode(Node* node)
if (!node || !node->parentNode() || !m_mutableStyle)
return;
- RefPtr<MutableStylePropertySet> parentStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(node->parentNode()), AllEditingProperties);
- RefPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(node), AllEditingProperties);
- nodeStyle->removeEquivalentProperties(parentStyle->ensureCSSStyleDeclaration());
+ RefPtrWillBeRawPtr<MutableStylePropertySet> parentStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(node->parentNode()), AllEditingProperties);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> nodeStyle = editingStyleFromComputedStyle(CSSComputedStyleDeclaration::create(node), AllEditingProperties);
+ nodeStyle->removeEquivalentProperties(parentStyle.get());
unsigned propertyCount = nodeStyle->propertyCount();
for (unsigned i = 0; i < propertyCount; ++i)
@@ -656,7 +651,7 @@ void EditingStyle::collapseTextDecorationProperties()
if (!m_mutableStyle)
return;
- RefPtr<CSSValue> textDecorationsInEffect = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
+ RefPtrWillBeRawPtr<CSSValue> textDecorationsInEffect = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
if (!textDecorationsInEffect)
return;
@@ -688,7 +683,7 @@ TriState EditingStyle::triStateOfStyle(EditingStyle* style) const
TriState EditingStyle::triStateOfStyle(CSSStyleDeclaration* styleToCompare, ShouldIgnoreTextOnlyProperties shouldIgnoreTextOnlyProperties) const
{
- RefPtr<MutableStylePropertySet> difference = getPropertiesNotIn(m_mutableStyle.get(), styleToCompare);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> difference = getPropertiesNotIn(m_mutableStyle.get(), styleToCompare);
if (shouldIgnoreTextOnlyProperties == IgnoreTextOnlyProperties)
difference->removePropertiesInSet(textOnlyProperties, WTF_ARRAY_LENGTH(textOnlyProperties));
@@ -713,7 +708,7 @@ TriState EditingStyle::triStateOfStyle(const VisibleSelection& selection) const
bool nodeIsStart = true;
for (Node* node = selection.start().deprecatedNode(); node; node = NodeTraversal::next(*node)) {
if (node->renderer() && node->rendererIsEditable()) {
- RefPtr<CSSComputedStyleDeclaration> nodeStyle = CSSComputedStyleDeclaration::create(node);
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> nodeStyle = CSSComputedStyleDeclaration::create(node);
if (nodeStyle) {
TriState nodeState = triStateOfStyle(nodeStyle.get(), node->isTextNode() ? EditingStyle::DoNotIgnoreTextOnlyProperties : EditingStyle::IgnoreTextOnlyProperties);
if (nodeIsStart) {
@@ -785,10 +780,9 @@ bool EditingStyle::conflictsWithInlineStyleOfElement(Element* element, EditingSt
return conflictingProperties && !conflictingProperties->isEmpty();
}
-static const Vector<OwnPtr<HTMLElementEquivalent> >& htmlElementEquivalents()
+static const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& htmlElementEquivalents()
{
- DEFINE_STATIC_LOCAL(Vector<OwnPtr<HTMLElementEquivalent> >, HTMLElementEquivalents, ());
-
+ DEFINE_STATIC_LOCAL(WillBePersistentHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >, HTMLElementEquivalents, ());
if (!HTMLElementEquivalents.size()) {
HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontWeight, CSSValueBold, HTMLNames::bTag));
HTMLElementEquivalents.append(HTMLElementEquivalent::create(CSSPropertyFontWeight, CSSValueBold, HTMLNames::strongTag));
@@ -811,7 +805,7 @@ bool EditingStyle::conflictsWithImplicitStyleOfElement(HTMLElement* element, Edi
if (!m_mutableStyle)
return false;
- const Vector<OwnPtr<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
+ const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
for (size_t i = 0; i < HTMLElementEquivalents.size(); ++i) {
const HTMLElementEquivalent* equivalent = HTMLElementEquivalents[i].get();
if (equivalent->matches(element) && equivalent->propertyExistsInStyle(m_mutableStyle.get())
@@ -824,10 +818,9 @@ bool EditingStyle::conflictsWithImplicitStyleOfElement(HTMLElement* element, Edi
return false;
}
-static const Vector<OwnPtr<HTMLAttributeEquivalent> >& htmlAttributeEquivalents()
+static const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& htmlAttributeEquivalents()
{
- DEFINE_STATIC_LOCAL(Vector<OwnPtr<HTMLAttributeEquivalent> >, HTMLAttributeEquivalents, ());
-
+ DEFINE_STATIC_LOCAL(WillBePersistentHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >, HTMLAttributeEquivalents, ());
if (!HTMLAttributeEquivalents.size()) {
// elementIsStyledSpanOrHTMLEquivalent depends on the fact each HTMLAttriuteEquivalent matches exactly one attribute
// of exactly one element except dirAttr.
@@ -848,7 +841,7 @@ bool EditingStyle::conflictsWithImplicitStyleOfAttributes(HTMLElement* element)
if (!m_mutableStyle)
return false;
- const Vector<OwnPtr<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
+ const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
for (size_t i = 0; i < HTMLAttributeEquivalents.size(); ++i) {
if (HTMLAttributeEquivalents[i]->matches(element) && HTMLAttributeEquivalents[i]->propertyExistsInStyle(m_mutableStyle.get())
&& !HTMLAttributeEquivalents[i]->valueIsPresentInStyle(element, m_mutableStyle.get()))
@@ -867,7 +860,7 @@ bool EditingStyle::extractConflictingImplicitStyleOfAttributes(HTMLElement* elem
if (!m_mutableStyle)
return false;
- const Vector<OwnPtr<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
+ const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
bool removed = false;
for (size_t i = 0; i < HTMLAttributeEquivalents.size(); ++i) {
const HTMLAttributeEquivalent* equivalent = HTMLAttributeEquivalents[i].get();
@@ -896,11 +889,12 @@ bool EditingStyle::styleIsPresentInComputedStyleOfNode(Node* node) const
bool EditingStyle::elementIsStyledSpanOrHTMLEquivalent(const HTMLElement* element)
{
+ ASSERT(element);
bool elementIsSpanOrElementEquivalent = false;
- if (element->hasTagName(HTMLNames::spanTag))
+ if (isHTMLSpanElement(*element))
elementIsSpanOrElementEquivalent = true;
else {
- const Vector<OwnPtr<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
+ const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
size_t i;
for (i = 0; i < HTMLElementEquivalents.size(); ++i) {
if (HTMLElementEquivalents[i]->matches(element)) {
@@ -914,7 +908,7 @@ bool EditingStyle::elementIsStyledSpanOrHTMLEquivalent(const HTMLElement* elemen
return elementIsSpanOrElementEquivalent; // span, b, etc... without any attributes
unsigned matchedAttributes = 0;
- const Vector<OwnPtr<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
+ const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& HTMLAttributeEquivalents = htmlAttributeEquivalents();
for (size_t i = 0; i < HTMLAttributeEquivalents.size(); ++i) {
if (HTMLAttributeEquivalents[i]->matches(element) && HTMLAttributeEquivalents[i]->attributeName() != HTMLNames::dirAttr)
matchedAttributes++;
@@ -950,11 +944,11 @@ void EditingStyle::prepareToApplyAt(const Position& position, ShouldPreserveWrit
// ReplaceSelectionCommand::handleStyleSpans() requires that this function only removes the editing style.
// If this function was modified in the future to delete all redundant properties, then add a boolean value to indicate
// which one of editingStyleAtPosition or computedStyle is called.
- RefPtr<EditingStyle> editingStyleAtPosition = EditingStyle::create(position, EditingPropertiesInEffect);
+ RefPtrWillBeRawPtr<EditingStyle> editingStyleAtPosition = EditingStyle::create(position, EditingPropertiesInEffect);
StylePropertySet* styleAtPosition = editingStyleAtPosition->m_mutableStyle.get();
- RefPtr<CSSValue> unicodeBidi;
- RefPtr<CSSValue> direction;
+ RefPtrWillBeRawPtr<CSSValue> unicodeBidi = nullptr;
+ RefPtrWillBeRawPtr<CSSValue> direction = nullptr;
if (shouldPreserveWritingDirection == PreserveWritingDirection) {
unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
@@ -983,7 +977,7 @@ void EditingStyle::mergeTypingStyle(Document* document)
{
ASSERT(document);
- RefPtr<EditingStyle> typingStyle = document->frame()->selection().typingStyle();
+ RefPtrWillBeRawPtr<EditingStyle> typingStyle = document->frame()->selection().typingStyle();
if (!typingStyle || typingStyle == this)
return;
@@ -1016,10 +1010,10 @@ static inline bool elementMatchesAndPropertyIsNotInInlineStyleDecl(const HTMLEle
&& (mode == EditingStyle::OverrideValues || !equivalent->propertyExistsInStyle(style));
}
-static PassRefPtr<MutableStylePropertySet> extractEditingProperties(const StylePropertySet* style, EditingStyle::PropertiesToInclude propertiesToInclude)
+static PassRefPtrWillBeRawPtr<MutableStylePropertySet> extractEditingProperties(const StylePropertySet* style, EditingStyle::PropertiesToInclude propertiesToInclude)
{
if (!style)
- return 0;
+ return nullptr;
switch (propertiesToInclude) {
case EditingStyle::AllProperties:
@@ -1030,25 +1024,25 @@ static PassRefPtr<MutableStylePropertySet> extractEditingProperties(const StyleP
}
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
void EditingStyle::mergeInlineAndImplicitStyleOfElement(Element* element, CSSPropertyOverrideMode mode, PropertiesToInclude propertiesToInclude)
{
- RefPtr<EditingStyle> styleFromRules = EditingStyle::create();
+ RefPtrWillBeRawPtr<EditingStyle> styleFromRules = EditingStyle::create();
styleFromRules->mergeStyleFromRulesForSerialization(element);
styleFromRules->m_mutableStyle = extractEditingProperties(styleFromRules->m_mutableStyle.get(), propertiesToInclude);
mergeStyle(styleFromRules->m_mutableStyle.get(), mode);
mergeInlineStyleOfElement(element, mode, propertiesToInclude);
- const Vector<OwnPtr<HTMLElementEquivalent> >& elementEquivalents = htmlElementEquivalents();
+ const WillBeHeapVector<OwnPtrWillBeMember<HTMLElementEquivalent> >& elementEquivalents = htmlElementEquivalents();
for (size_t i = 0; i < elementEquivalents.size(); ++i) {
if (elementMatchesAndPropertyIsNotInInlineStyleDecl(elementEquivalents[i].get(), element, mode, m_mutableStyle.get()))
elementEquivalents[i]->addToStyle(element, this);
}
- const Vector<OwnPtr<HTMLAttributeEquivalent> >& attributeEquivalents = htmlAttributeEquivalents();
+ const WillBeHeapVector<OwnPtrWillBeMember<HTMLAttributeEquivalent> >& attributeEquivalents = htmlAttributeEquivalents();
for (size_t i = 0; i < attributeEquivalents.size(); ++i) {
if (attributeEquivalents[i]->attributeName() == HTMLNames::dirAttr)
continue; // We don't want to include directionality
@@ -1057,9 +1051,9 @@ void EditingStyle::mergeInlineAndImplicitStyleOfElement(Element* element, CSSPro
}
}
-PassRefPtr<EditingStyle> EditingStyle::wrappingStyleForSerialization(Node* context, bool shouldAnnotate)
+PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::wrappingStyleForSerialization(Node* context, bool shouldAnnotate)
{
- RefPtr<EditingStyle> wrappingStyle;
+ RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = nullptr;
if (shouldAnnotate) {
wrappingStyle = EditingStyle::create(context, EditingStyle::EditingPropertiesInEffect);
@@ -1090,14 +1084,23 @@ PassRefPtr<EditingStyle> EditingStyle::wrappingStyleForSerialization(Node* conte
static void mergeTextDecorationValues(CSSValueList* mergedValue, const CSSValueList* valueToMerge)
{
+#if ENABLE_OILPAN
+ DEFINE_STATIC_LOCAL(Persistent<CSSPrimitiveValue>, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));
+ DEFINE_STATIC_LOCAL(Persistent<CSSPrimitiveValue>, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));
+ if (valueToMerge->hasValue(underline) && !mergedValue->hasValue(underline))
+ mergedValue->append(underline.get());
+
+ if (valueToMerge->hasValue(lineThrough) && !mergedValue->hasValue(lineThrough))
+ mergedValue->append(lineThrough.get());
+#else
DEFINE_STATIC_REF(CSSPrimitiveValue, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));
DEFINE_STATIC_REF(CSSPrimitiveValue, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));
-
if (valueToMerge->hasValue(underline) && !mergedValue->hasValue(underline))
mergedValue->append(underline);
if (valueToMerge->hasValue(lineThrough) && !mergedValue->hasValue(lineThrough))
mergedValue->append(lineThrough);
+#endif
}
void EditingStyle::mergeStyle(const StylePropertySet* style, CSSPropertyOverrideMode mode)
@@ -1113,7 +1116,7 @@ void EditingStyle::mergeStyle(const StylePropertySet* style, CSSPropertyOverride
unsigned propertyCount = style->propertyCount();
for (unsigned i = 0; i < propertyCount; ++i) {
StylePropertySet::PropertyReference property = style->propertyAt(i);
- RefPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(property.id());
+ RefPtrWillBeRawPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(property.id());
// text decorations never override values
if ((property.id() == textDecorationPropertyForEditing() || property.id() == CSSPropertyWebkitTextDecorationsInEffect) && property.value()->isValueList() && value) {
@@ -1121,7 +1124,7 @@ void EditingStyle::mergeStyle(const StylePropertySet* style, CSSPropertyOverride
mergeTextDecorationValues(toCSSValueList(value.get()), toCSSValueList(property.value()));
continue;
}
- value = 0; // text-decoration: none is equivalent to not having the property
+ value = nullptr; // text-decoration: none is equivalent to not having the property
}
if (mode == OverrideValues || (mode == DoNotOverrideValues && !value))
@@ -1129,20 +1132,20 @@ void EditingStyle::mergeStyle(const StylePropertySet* style, CSSPropertyOverride
}
}
-static PassRefPtr<MutableStylePropertySet> styleFromMatchedRulesForElement(Element* element, unsigned rulesToInclude)
+static PassRefPtrWillBeRawPtr<MutableStylePropertySet> styleFromMatchedRulesForElement(Element* element, unsigned rulesToInclude)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
- RefPtr<StyleRuleList> matchedRules = element->document().ensureStyleResolver().styleRulesForElement(element, rulesToInclude);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<StyleRuleList> matchedRules = element->document().ensureStyleResolver().styleRulesForElement(element, rulesToInclude);
if (matchedRules) {
for (unsigned i = 0; i < matchedRules->m_list.size(); ++i)
- style->mergeAndOverrideOnConflict(matchedRules->m_list[i]->properties());
+ style->mergeAndOverrideOnConflict(&matchedRules->m_list[i]->properties());
}
return style.release();
}
void EditingStyle::mergeStyleFromRules(Element* element)
{
- RefPtr<MutableStylePropertySet> styleFromMatchedRules = styleFromMatchedRulesForElement(element,
+ RefPtrWillBeRawPtr<MutableStylePropertySet> styleFromMatchedRules = styleFromMatchedRulesForElement(element,
StyleResolver::AuthorCSSRules | StyleResolver::CrossOriginCSSRules);
// Styles from the inline style declaration, held in the variable "style", take precedence
// over those from matched rules.
@@ -1160,8 +1163,8 @@ void EditingStyle::mergeStyleFromRulesForSerialization(Element* element)
// The property value, if it's a percentage, may not reflect the actual computed value.
// For example: style="height: 1%; overflow: visible;" in quirksmode
// FIXME: There are others like this, see <rdar://problem/5195123> Slashdot copy/paste fidelity problem
- RefPtr<CSSComputedStyleDeclaration> computedStyleForElement = CSSComputedStyleDeclaration::create(element);
- RefPtr<MutableStylePropertySet> fromComputedStyle = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleForElement = CSSComputedStyleDeclaration::create(element);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> fromComputedStyle = MutableStylePropertySet::create();
{
unsigned propertyCount = m_mutableStyle->propertyCount();
for (unsigned i = 0; i < propertyCount; ++i) {
@@ -1170,7 +1173,7 @@ void EditingStyle::mergeStyleFromRulesForSerialization(Element* element)
if (!value->isPrimitiveValue())
continue;
if (toCSSPrimitiveValue(value)->isPercentage()) {
- if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
+ if (RefPtrWillBeRawPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
}
}
@@ -1195,12 +1198,12 @@ void EditingStyle::removeStyleFromRulesAndContext(Element* element, Node* contex
return;
// 1. Remove style from matched rules because style remain without repeating it in inline style declaration
- RefPtr<MutableStylePropertySet> styleFromMatchedRules = styleFromMatchedRulesForElement(element, StyleResolver::AllButEmptyCSSRules);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> styleFromMatchedRules = styleFromMatchedRulesForElement(element, StyleResolver::AllButEmptyCSSRules);
if (styleFromMatchedRules && !styleFromMatchedRules->isEmpty())
m_mutableStyle = getPropertiesNotIn(m_mutableStyle.get(), styleFromMatchedRules->ensureCSSStyleDeclaration());
// 2. Remove style present in context and not overriden by matched rules.
- RefPtr<EditingStyle> computedStyle = EditingStyle::create(context, EditingPropertiesInEffect);
+ RefPtrWillBeRawPtr<EditingStyle> computedStyle = EditingStyle::create(context, EditingPropertiesInEffect);
if (computedStyle->m_mutableStyle) {
if (!computedStyle->m_mutableStyle->getPropertyCSSValue(CSSPropertyBackgroundColor))
computedStyle->m_mutableStyle->setProperty(CSSPropertyBackgroundColor, CSSValueTransparent);
@@ -1239,17 +1242,17 @@ void EditingStyle::forceInline()
int EditingStyle::legacyFontSize(Document* document) const
{
- RefPtr<CSSValue> cssValue = m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize);
+ RefPtrWillBeRawPtr<CSSValue> cssValue = m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize);
if (!cssValue || !cssValue->isPrimitiveValue())
return 0;
return legacyFontSizeFromCSSValue(document, toCSSPrimitiveValue(cssValue.get()),
m_shouldUseFixedDefaultFontSize, AlwaysUseLegacyFontSize);
}
-PassRefPtr<EditingStyle> EditingStyle::styleAtSelectionStart(const VisibleSelection& selection, bool shouldUseBackgroundColorInEffect)
+PassRefPtrWillBeRawPtr<EditingStyle> EditingStyle::styleAtSelectionStart(const VisibleSelection& selection, bool shouldUseBackgroundColorInEffect)
{
if (selection.isNone())
- return 0;
+ return nullptr;
Position position = adjustedSelectionStartForStyleComputation(selection);
@@ -1263,17 +1266,17 @@ PassRefPtr<EditingStyle> EditingStyle::styleAtSelectionStart(const VisibleSelect
Element* element = position.element();
if (!element)
- return 0;
+ return nullptr;
- RefPtr<EditingStyle> style = EditingStyle::create(element, EditingStyle::AllProperties);
+ RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element, EditingStyle::AllProperties);
style->mergeTypingStyle(&element->document());
// If background color is transparent, traverse parent nodes until we hit a different value or document root
// Also, if the selection is a range, ignore the background color at the start of selection,
// and find the background color of the common ancestor.
if (shouldUseBackgroundColorInEffect && (selection.isRange() || hasTransparentBackgroundColor(style->m_mutableStyle.get()))) {
- RefPtr<Range> range(selection.toNormalizedRange());
- if (PassRefPtr<CSSValue> value = backgroundColorInEffect(range->commonAncestorContainer(IGNORE_EXCEPTION)))
+ RefPtrWillBeRawPtr<Range> range(selection.toNormalizedRange());
+ if (PassRefPtrWillBeRawPtr<CSSValue> value = backgroundColorInEffect(range->commonAncestorContainer()))
style->setProperty(CSSPropertyBackgroundColor, value->cssText());
}
@@ -1303,8 +1306,8 @@ WritingDirection EditingStyle::textDirectionForSelection(const VisibleSelection&
if (!n->isStyledElement())
continue;
- RefPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(n);
- RefPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(n);
+ RefPtrWillBeRawPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
continue;
@@ -1332,8 +1335,8 @@ WritingDirection EditingStyle::textDirectionForSelection(const VisibleSelection&
if (!node->isStyledElement())
continue;
- RefPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(node);
- RefPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(node);
+ RefPtrWillBeRawPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
continue;
@@ -1345,7 +1348,7 @@ WritingDirection EditingStyle::textDirectionForSelection(const VisibleSelection&
return NaturalWritingDirection;
ASSERT(unicodeBidiValue == CSSValueEmbed);
- RefPtr<CSSValue> direction = style->getPropertyCSSValue(CSSPropertyDirection);
+ RefPtrWillBeRawPtr<CSSValue> direction = style->getPropertyCSSValue(CSSPropertyDirection);
if (!direction || !direction->isPrimitiveValue())
continue;
@@ -1366,10 +1369,15 @@ WritingDirection EditingStyle::textDirectionForSelection(const VisibleSelection&
return foundDirection;
}
+void EditingStyle::trace(Visitor* visitor)
+{
+ visitor->trace(m_mutableStyle);
+}
+
static void reconcileTextDecorationProperties(MutableStylePropertySet* style)
{
- RefPtr<CSSValue> textDecorationsInEffect = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
- RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
+ RefPtrWillBeRawPtr<CSSValue> textDecorationsInEffect = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
+ RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
// We shouldn't have both text-decoration and -webkit-text-decorations-in-effect because that wouldn't make sense.
ASSERT(!textDecorationsInEffect || !textDecoration);
if (textDecorationsInEffect) {
@@ -1395,9 +1403,9 @@ StyleChange::StyleChange(EditingStyle* style, const Position& position)
if (!style || !style->style() || !document || !document->frame())
return;
- RefPtr<CSSComputedStyleDeclaration> computedStyle = position.computedStyle();
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyle = position.computedStyle();
// FIXME: take care of background-color in effect
- RefPtr<MutableStylePropertySet> mutableStyle = getPropertiesNotIn(style->style(), computedStyle.get());
+ RefPtrWillBeRawPtr<MutableStylePropertySet> mutableStyle = getPropertiesNotIn(style->style(), computedStyle.get());
reconcileTextDecorationProperties(mutableStyle.get());
if (!document->frame()->editor().shouldStyleWithCSS())
@@ -1422,7 +1430,6 @@ static void setTextDecorationProperty(MutableStylePropertySet* style, const CSSV
style->setProperty(propertyID, newTextDecoration->cssText(), style->propertyIsImportant(propertyID));
else {
// text-decoration: none is redundant since it does not remove any text decorations.
- ASSERT(!style->propertyIsImportant(propertyID));
style->removeProperty(propertyID);
}
}
@@ -1444,12 +1451,16 @@ void StyleChange::extractTextStyles(Document* document, MutableStylePropertySet*
// Assuming reconcileTextDecorationProperties has been called, there should not be -webkit-text-decorations-in-effect
// Furthermore, text-decoration: none has been trimmed so that text-decoration property is always a CSSValueList.
- RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
+ RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
if (textDecoration && textDecoration->isValueList()) {
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<CSSPrimitiveValue>, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));
+ DEFINE_STATIC_LOCAL(Persistent<CSSPrimitiveValue>, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));
+#else
DEFINE_STATIC_REF(CSSPrimitiveValue, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));
DEFINE_STATIC_REF(CSSPrimitiveValue, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));
-
- RefPtr<CSSValueList> newTextDecoration = toCSSValueList(textDecoration.get())->copy();
+#endif
+ RefPtrWillBeRawPtr<CSSValueList> newTextDecoration = toCSSValueList(textDecoration.get())->copy();
if (newTextDecoration->removeAll(underline))
m_applyUnderline = true;
if (newTextDecoration->removeAll(lineThrough))
@@ -1481,7 +1492,7 @@ void StyleChange::extractTextStyles(Document* document, MutableStylePropertySet*
m_applyFontFace.replaceWithLiteral('\'', "");
style->removeProperty(CSSPropertyFontFamily);
- if (RefPtr<CSSValue> fontSize = style->getPropertyCSSValue(CSSPropertyFontSize)) {
+ if (RefPtrWillBeRawPtr<CSSValue> fontSize = style->getPropertyCSSValue(CSSPropertyFontSize)) {
if (!fontSize->isPrimitiveValue())
style->removeProperty(CSSPropertyFontSize); // Can't make sense of the number. Put no font size.
else if (int legacyFontSize = legacyFontSizeFromCSSValue(document, toCSSPrimitiveValue(fontSize.get()),
@@ -1494,11 +1505,11 @@ void StyleChange::extractTextStyles(Document* document, MutableStylePropertySet*
static void diffTextDecorations(MutableStylePropertySet* style, CSSPropertyID propertID, CSSValue* refTextDecoration)
{
- RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(propertID);
+ RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(propertID);
if (!textDecoration || !textDecoration->isValueList() || !refTextDecoration || !refTextDecoration->isValueList())
return;
- RefPtr<CSSValueList> newTextDecoration = toCSSValueList(textDecoration.get())->copy();
+ RefPtrWillBeRawPtr<CSSValueList> newTextDecoration = toCSSValueList(textDecoration.get())->copy();
CSSValueList* valuesInRefTextDecoration = toCSSValueList(refTextDecoration);
for (size_t i = 0; i < valuesInRefTextDecoration->length(); i++)
@@ -1545,20 +1556,20 @@ static bool fontWeightNeedsResolving(CSSValue* fontWeight)
return value == CSSValueLighter || value == CSSValueBolder;
}
-PassRefPtr<MutableStylePropertySet> getPropertiesNotIn(StylePropertySet* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle)
+PassRefPtrWillBeRawPtr<MutableStylePropertySet> getPropertiesNotIn(StylePropertySet* styleWithRedundantProperties, CSSStyleDeclaration* baseStyle)
{
ASSERT(styleWithRedundantProperties);
ASSERT(baseStyle);
- RefPtr<MutableStylePropertySet> result = styleWithRedundantProperties->mutableCopy();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> result = styleWithRedundantProperties->mutableCopy();
result->removeEquivalentProperties(baseStyle);
- RefPtr<CSSValue> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValueInternal(CSSPropertyWebkitTextDecorationsInEffect);
+ RefPtrWillBeRawPtr<CSSValue> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValueInternal(CSSPropertyWebkitTextDecorationsInEffect);
diffTextDecorations(result.get(), textDecorationPropertyForEditing(), baseTextDecorationsInEffect.get());
diffTextDecorations(result.get(), CSSPropertyWebkitTextDecorationsInEffect, baseTextDecorationsInEffect.get());
- if (RefPtr<CSSValue> baseFontWeight = baseStyle->getPropertyCSSValueInternal(CSSPropertyFontWeight)) {
- if (RefPtr<CSSValue> fontWeight = result->getPropertyCSSValue(CSSPropertyFontWeight)) {
+ if (RefPtrWillBeRawPtr<CSSValue> baseFontWeight = baseStyle->getPropertyCSSValueInternal(CSSPropertyFontWeight)) {
+ if (RefPtrWillBeRawPtr<CSSValue> fontWeight = result->getPropertyCSSValue(CSSPropertyFontWeight)) {
if (!fontWeightNeedsResolving(fontWeight.get()) && (fontWeightIsBold(fontWeight.get()) == fontWeightIsBold(baseFontWeight.get())))
result->removeProperty(CSSPropertyFontWeight);
}
@@ -1581,7 +1592,7 @@ CSSValueID getIdentifierValue(StylePropertySet* style, CSSPropertyID propertyID)
{
if (!style)
return CSSValueInvalid;
- RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
if (!value || !value->isPrimitiveValue())
return CSSValueInvalid;
return toCSSPrimitiveValue(value.get())->getValueID();
@@ -1591,7 +1602,7 @@ CSSValueID getIdentifierValue(CSSStyleDeclaration* style, CSSPropertyID property
{
if (!style)
return CSSValueInvalid;
- RefPtr<CSSValue> value = style->getPropertyCSSValueInternal(propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValueInternal(propertyID);
if (!value || !value->isPrimitiveValue())
return CSSValueInvalid;
return toCSSPrimitiveValue(value.get())->getValueID();
@@ -1635,24 +1646,24 @@ bool isTransparentColorValue(CSSValue* cssValue)
bool hasTransparentBackgroundColor(CSSStyleDeclaration* style)
{
- RefPtr<CSSValue> cssValue = style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor);
+ RefPtrWillBeRawPtr<CSSValue> cssValue = style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor);
return isTransparentColorValue(cssValue.get());
}
bool hasTransparentBackgroundColor(StylePropertySet* style)
{
- RefPtr<CSSValue> cssValue = style->getPropertyCSSValue(CSSPropertyBackgroundColor);
+ RefPtrWillBeRawPtr<CSSValue> cssValue = style->getPropertyCSSValue(CSSPropertyBackgroundColor);
return isTransparentColorValue(cssValue.get());
}
-PassRefPtr<CSSValue> backgroundColorInEffect(Node* node)
+PassRefPtrWillBeRawPtr<CSSValue> backgroundColorInEffect(Node* node)
{
for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) {
- RefPtr<CSSComputedStyleDeclaration> ancestorStyle = CSSComputedStyleDeclaration::create(ancestor);
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> ancestorStyle = CSSComputedStyleDeclaration::create(ancestor);
if (!hasTransparentBackgroundColor(ancestorStyle.get()))
return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor);
}
- return 0;
+ return nullptr;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/EditingStyle.h b/chromium/third_party/WebKit/Source/core/editing/EditingStyle.h
index fbfa6e8f808..c9aca38f037 100644
--- a/chromium/third_party/WebKit/Source/core/editing/EditingStyle.h
+++ b/chromium/third_party/WebKit/Source/core/editing/EditingStyle.h
@@ -32,9 +32,10 @@
#ifndef EditingStyle_h
#define EditingStyle_h
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
#include "core/editing/WritingDirection.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -59,7 +60,7 @@ class RenderStyle;
class StylePropertySet;
class VisibleSelection;
-class EditingStyle : public RefCounted<EditingStyle> {
+class EditingStyle FINAL : public RefCountedWillBeGarbageCollectedFinalized<EditingStyle> {
public:
enum PropertiesToInclude { AllProperties, OnlyEditingInheritableProperties, EditingPropertiesInEffect };
@@ -67,34 +68,29 @@ public:
enum ShouldExtractMatchingStyle { ExtractMatchingStyle, DoNotExtractMatchingStyle };
static float NoFontDelta;
- static PassRefPtr<EditingStyle> create()
+ static PassRefPtrWillBeRawPtr<EditingStyle> create()
{
- return adoptRef(new EditingStyle());
+ return adoptRefWillBeNoop(new EditingStyle());
}
- static PassRefPtr<EditingStyle> create(Node* node, PropertiesToInclude propertiesToInclude = OnlyEditingInheritableProperties)
+ static PassRefPtrWillBeRawPtr<EditingStyle> create(Node* node, PropertiesToInclude propertiesToInclude = OnlyEditingInheritableProperties)
{
- return adoptRef(new EditingStyle(node, propertiesToInclude));
+ return adoptRefWillBeNoop(new EditingStyle(node, propertiesToInclude));
}
- static PassRefPtr<EditingStyle> create(const Position& position, PropertiesToInclude propertiesToInclude = OnlyEditingInheritableProperties)
+ static PassRefPtrWillBeRawPtr<EditingStyle> create(const Position& position, PropertiesToInclude propertiesToInclude = OnlyEditingInheritableProperties)
{
- return adoptRef(new EditingStyle(position, propertiesToInclude));
+ return adoptRefWillBeNoop(new EditingStyle(position, propertiesToInclude));
}
- static PassRefPtr<EditingStyle> create(const StylePropertySet* style)
+ static PassRefPtrWillBeRawPtr<EditingStyle> create(const StylePropertySet* style)
{
- return adoptRef(new EditingStyle(style));
+ return adoptRefWillBeNoop(new EditingStyle(style));
}
- static PassRefPtr<EditingStyle> create(const CSSStyleDeclaration* style)
+ static PassRefPtrWillBeRawPtr<EditingStyle> create(CSSPropertyID propertyID, const String& value)
{
- return adoptRef(new EditingStyle(style));
- }
-
- static PassRefPtr<EditingStyle> create(CSSPropertyID propertyID, const String& value)
- {
- return adoptRef(new EditingStyle(propertyID, value));
+ return adoptRefWillBeNoop(new EditingStyle(propertyID, value));
}
~EditingStyle();
@@ -102,12 +98,11 @@ public:
MutableStylePropertySet* style() { return m_mutableStyle.get(); }
bool textDirection(WritingDirection&) const;
bool isEmpty() const;
- void setStyle(PassRefPtr<MutableStylePropertySet>);
void overrideWithStyle(const StylePropertySet*);
void clear();
- PassRefPtr<EditingStyle> copy() const;
- PassRefPtr<EditingStyle> extractAndRemoveBlockProperties();
- PassRefPtr<EditingStyle> extractAndRemoveTextDirection();
+ PassRefPtrWillBeRawPtr<EditingStyle> copy() const;
+ PassRefPtrWillBeRawPtr<EditingStyle> extractAndRemoveBlockProperties();
+ PassRefPtrWillBeRawPtr<EditingStyle> extractAndRemoveTextDirection();
void removeBlockProperties();
void removeStyleAddedByNode(Node*);
void removeStyleConflictingWithStyleOfNode(Node*);
@@ -132,7 +127,7 @@ public:
void mergeTypingStyle(Document*);
enum CSSPropertyOverrideMode { OverrideValues, DoNotOverrideValues };
void mergeInlineStyleOfElement(Element*, CSSPropertyOverrideMode, PropertiesToInclude = AllProperties);
- static PassRefPtr<EditingStyle> wrappingStyleForSerialization(Node* context, bool shouldAnnotate);
+ static PassRefPtrWillBeRawPtr<EditingStyle> wrappingStyleForSerialization(Node* context, bool shouldAnnotate);
void mergeStyleFromRules(Element*);
void mergeStyleFromRulesForSerialization(Element*);
void removeStyleFromRulesAndContext(Element*, Node* context);
@@ -142,16 +137,17 @@ public:
float fontSizeDelta() const { return m_fontSizeDelta; }
bool hasFontSizeDelta() const { return m_fontSizeDelta != NoFontDelta; }
- bool shouldUseFixedDefaultFontSize() const { return m_shouldUseFixedDefaultFontSize; }
- static PassRefPtr<EditingStyle> styleAtSelectionStart(const VisibleSelection&, bool shouldUseBackgroundColorInEffect = false);
+ static PassRefPtrWillBeRawPtr<EditingStyle> styleAtSelectionStart(const VisibleSelection&, bool shouldUseBackgroundColorInEffect = false);
static WritingDirection textDirectionForSelection(const VisibleSelection&, EditingStyle* typingStyle, bool& hasNestedOrMultipleEmbeddings);
+
+ void trace(Visitor*);
+
private:
EditingStyle();
EditingStyle(Node*, PropertiesToInclude);
EditingStyle(const Position&, PropertiesToInclude);
explicit EditingStyle(const StylePropertySet*);
- explicit EditingStyle(const CSSStyleDeclaration*);
EditingStyle(CSSPropertyID, const String& value);
void init(Node*, PropertiesToInclude);
void removeTextFillAndStrokeColorsIfNeeded(RenderStyle*);
@@ -163,7 +159,7 @@ private:
void mergeInlineAndImplicitStyleOfElement(Element*, CSSPropertyOverrideMode, PropertiesToInclude);
void mergeStyle(const StylePropertySet*, CSSPropertyOverrideMode);
- RefPtr<MutableStylePropertySet> m_mutableStyle;
+ RefPtrWillBeMember<MutableStylePropertySet> m_mutableStyle;
bool m_shouldUseFixedDefaultFontSize;
float m_fontSizeDelta;
diff --git a/chromium/third_party/WebKit/Source/core/editing/Editor.cpp b/chromium/third_party/WebKit/Source/core/editing/Editor.cpp
index fcdf0cd5971..868bcf135b7 100644
--- a/chromium/third_party/WebKit/Source/core/editing/Editor.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/Editor.cpp
@@ -27,18 +27,19 @@
#include "config.h"
#include "core/editing/Editor.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/EventNames.h"
+#include "core/HTMLNames.h"
+#include "core/XLinkNames.h"
#include "core/accessibility/AXObjectCache.h"
+#include "core/clipboard/Clipboard.h"
+#include "core/clipboard/DataObject.h"
+#include "core/clipboard/Pasteboard.h"
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/css/StylePropertySet.h"
-#include "core/dom/Clipboard.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentMarkerController.h"
-#include "core/dom/NodeList.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/ParserContentPolicy.h"
#include "core/dom/Text.h"
@@ -47,7 +48,6 @@
#include "core/editing/IndentOutdentCommand.h"
#include "core/editing/InputMethodController.h"
#include "core/editing/InsertListCommand.h"
-#include "core/editing/ModifySelectionListLevel.h"
#include "core/editing/RemoveFormatCommand.h"
#include "core/editing/RenderedPosition.h"
#include "core/editing/ReplaceSelectionCommand.h"
@@ -62,9 +62,12 @@
#include "core/events/KeyboardEvent.h"
#include "core/events/ScopedEventQueue.h"
#include "core/events/TextEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
#include "core/fetch/ResourceFetcher.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLTextAreaElement.h"
@@ -73,21 +76,16 @@
#include "core/page/EditorClient.h"
#include "core/page/EventHandler.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
-#include "core/frame/Settings.h"
-#include "core/platform/Pasteboard.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderImage.h"
+#include "core/svg/SVGImageElement.h"
#include "platform/KillRing.h"
#include "platform/weborigin/KURL.h"
#include "wtf/unicode/CharacterNames.h"
namespace WebCore {
-using namespace std;
using namespace HTMLNames;
using namespace WTF;
using namespace Unicode;
@@ -116,9 +114,9 @@ VisibleSelection Editor::selectionForCommand(Event* event)
// If the target is a text control, and the current selection is outside of its shadow tree,
// then use the saved selection for that text control.
HTMLTextFormControlElement* textFormControlOfSelectionStart = enclosingTextFormControl(selection.start());
- HTMLTextFormControlElement* textFromControlOfTarget = isHTMLTextFormControlElement(event->target()->toNode()) ? toHTMLTextFormControlElement(event->target()->toNode()) : 0;
+ HTMLTextFormControlElement* textFromControlOfTarget = isHTMLTextFormControlElement(*event->target()->toNode()) ? toHTMLTextFormControlElement(event->target()->toNode()) : 0;
if (textFromControlOfTarget && (selection.start().isNull() || textFromControlOfTarget != textFormControlOfSelectionStart)) {
- if (RefPtr<Range> range = textFromControlOfTarget->selection())
+ if (RefPtrWillBeRawPtr<Range> range = textFromControlOfTarget->selection())
return VisibleSelection(range.get(), DOWNSTREAM, selection.isDirectional());
}
return selection;
@@ -225,9 +223,7 @@ static HTMLImageElement* imageElementFromImageDocument(Document* document)
return 0;
Node* node = body->firstChild();
- if (!node)
- return 0;
- if (!node->hasTagName(imgTag))
+ if (!isHTMLImageElement(node))
return 0;
return toHTMLImageElement(node);
}
@@ -261,7 +257,7 @@ bool Editor::canDeleteRange(Range* range) const
if (!startContainer->rendererIsEditable() || !endContainer->rendererIsEditable())
return false;
- if (range->collapsed(IGNORE_EXCEPTION)) {
+ if (range->collapsed()) {
VisiblePosition start(range->startPosition(), DOWNSTREAM);
VisiblePosition previous = start.previous();
// FIXME: We sometimes allow deletions at the start of editable roots, like when the caret is in an empty list item.
@@ -353,7 +349,7 @@ void Editor::pasteAsPlainText(const String& pastingText, bool smartReplace)
target->dispatchEvent(TextEvent::createForPlainTextPaste(m_frame.domWindow(), pastingText, smartReplace), IGNORE_EXCEPTION);
}
-void Editor::pasteAsFragment(PassRefPtr<DocumentFragment> pastingFragment, bool smartReplace, bool matchStyle)
+void Editor::pasteAsFragment(PassRefPtrWillBeRawPtr<DocumentFragment> pastingFragment, bool smartReplace, bool matchStyle)
{
Node* target = findEventTargetFromSelection();
if (!target)
@@ -390,8 +386,8 @@ void Editor::pasteAsPlainTextWithPasteboard(Pasteboard* pasteboard)
void Editor::pasteWithPasteboard(Pasteboard* pasteboard)
{
- RefPtr<Range> range = selectedRange();
- RefPtr<DocumentFragment> fragment;
+ RefPtrWillBeRawPtr<Range> range = selectedRange();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = nullptr;
bool chosePlainText = false;
if (pasteboard->isHTMLAvailable()) {
@@ -441,11 +437,11 @@ static void writeImageNodeToPasteboard(Pasteboard* pasteboard, Node* node, const
// FIXME: This should probably be reconciled with HitTestResult::absoluteImageURL.
AtomicString urlString;
- if (node->hasTagName(imgTag) || node->hasTagName(inputTag))
+ if (isHTMLImageElement(*node) || isHTMLInputElement(*node))
urlString = toElement(node)->getAttribute(srcAttr);
- else if (node->hasTagName(SVGNames::imageTag))
+ else if (isSVGImageElement(*node))
urlString = toElement(node)->getAttribute(XLinkNames::hrefAttr);
- else if (node->hasTagName(embedTag) || node->hasTagName(objectTag))
+ else if (isHTMLEmbedElement(*node) || isHTMLObjectElement(*node))
urlString = toElement(node)->imageSourceURL();
KURL url = urlString.isEmpty() ? KURL() : node->document().completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
@@ -460,18 +456,18 @@ bool Editor::dispatchCPPEvent(const AtomicString &eventType, ClipboardAccessPoli
if (!target)
return true;
- RefPtr<Clipboard> clipboard = Clipboard::create(
+ RefPtrWillBeRawPtr<Clipboard> clipboard = Clipboard::create(
Clipboard::CopyAndPaste,
policy,
policy == ClipboardWritable
- ? ChromiumDataObject::create()
- : ChromiumDataObject::createFromPasteboard(pasteMode));
+ ? DataObject::create()
+ : DataObject::createFromPasteboard(pasteMode));
- RefPtr<Event> evt = ClipboardEvent::create(eventType, true, true, clipboard);
+ RefPtrWillBeRawPtr<Event> evt = ClipboardEvent::create(eventType, true, true, clipboard);
target->dispatchEvent(evt, IGNORE_EXCEPTION);
bool noDefaultProcessing = evt->defaultPrevented();
if (noDefaultProcessing && policy == ClipboardWritable) {
- RefPtr<ChromiumDataObject> dataObject = clipboard->dataObject();
+ RefPtrWillBeRawPtr<DataObject> dataObject = clipboard->dataObject();
Pasteboard::generalPasteboard()->writeDataObject(dataObject.release());
}
@@ -486,7 +482,7 @@ bool Editor::canSmartReplaceWithPasteboard(Pasteboard* pasteboard)
return smartInsertDeleteEnabled() && pasteboard->canSmartReplace();
}
-void Editor::replaceSelectionWithFragment(PassRefPtr<DocumentFragment> fragment, bool selectReplacement, bool smartReplace, bool matchStyle)
+void Editor::replaceSelectionWithFragment(PassRefPtrWillBeRawPtr<DocumentFragment> fragment, bool selectReplacement, bool smartReplace, bool matchStyle)
{
if (m_frame.selection().isNone() || !m_frame.selection().isContentEditable() || !fragment)
return;
@@ -512,14 +508,14 @@ void Editor::replaceSelectionWithText(const String& text, bool selectReplacement
replaceSelectionWithFragment(createFragmentFromText(selectedRange().get(), text), selectReplacement, smartReplace, true);
}
-PassRefPtr<Range> Editor::selectedRange()
+PassRefPtrWillBeRawPtr<Range> Editor::selectedRange()
{
return m_frame.selection().toNormalizedRange();
}
bool Editor::shouldDeleteRange(Range* range) const
{
- if (!range || range->collapsed(IGNORE_EXCEPTION))
+ if (!range || range->collapsed())
return false;
return canDeleteRange(range);
@@ -527,7 +523,7 @@ bool Editor::shouldDeleteRange(Range* range) const
void Editor::notifyComponentsOnChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
{
- client().respondToChangedSelection(m_frame.selection().selectionType());
+ client().respondToChangedSelection(&m_frame, m_frame.selection().selectionType());
setStartNewKillRingSequence(true);
}
@@ -573,83 +569,6 @@ TriState Editor::selectionOrderedListState() const
return FalseTriState;
}
-PassRefPtr<Node> Editor::insertOrderedList()
-{
- if (!canEditRichly())
- return 0;
-
- ASSERT(m_frame.document());
- RefPtr<Node> newList = InsertListCommand::insertList(*m_frame.document(), InsertListCommand::OrderedList);
- revealSelectionAfterEditingOperation();
- return newList;
-}
-
-PassRefPtr<Node> Editor::insertUnorderedList()
-{
- if (!canEditRichly())
- return 0;
-
- ASSERT(m_frame.document());
- RefPtr<Node> newList = InsertListCommand::insertList(*m_frame.document(), InsertListCommand::UnorderedList);
- revealSelectionAfterEditingOperation();
- return newList;
-}
-
-bool Editor::canIncreaseSelectionListLevel()
-{
- ASSERT(m_frame.document());
- return canEditRichly() && IncreaseSelectionListLevelCommand::canIncreaseSelectionListLevel(*m_frame.document());
-}
-
-bool Editor::canDecreaseSelectionListLevel()
-{
- ASSERT(m_frame.document());
- return canEditRichly() && DecreaseSelectionListLevelCommand::canDecreaseSelectionListLevel(*m_frame.document());
-}
-
-PassRefPtr<Node> Editor::increaseSelectionListLevel()
-{
- if (!canEditRichly() || m_frame.selection().isNone())
- return 0;
-
- ASSERT(m_frame.document());
- RefPtr<Node> newList = IncreaseSelectionListLevelCommand::increaseSelectionListLevel(*m_frame.document());
- revealSelectionAfterEditingOperation();
- return newList;
-}
-
-PassRefPtr<Node> Editor::increaseSelectionListLevelOrdered()
-{
- if (!canEditRichly() || m_frame.selection().isNone())
- return 0;
-
- ASSERT(m_frame.document());
- RefPtr<Node> newList = IncreaseSelectionListLevelCommand::increaseSelectionListLevelOrdered(*m_frame.document());
- revealSelectionAfterEditingOperation();
- return newList.release();
-}
-
-PassRefPtr<Node> Editor::increaseSelectionListLevelUnordered()
-{
- if (!canEditRichly() || m_frame.selection().isNone())
- return 0;
-
- ASSERT(m_frame.document());
- RefPtr<Node> newList = IncreaseSelectionListLevelCommand::increaseSelectionListLevelUnordered(*m_frame.document());
- revealSelectionAfterEditingOperation();
- return newList.release();
-}
-
-void Editor::decreaseSelectionListLevel()
-{
- if (!canEditRichly() || m_frame.selection().isNone())
- return;
-
- ASSERT(m_frame.document());
- DecreaseSelectionListLevelCommand::decreaseSelectionListLevel(*m_frame.document());
- revealSelectionAfterEditingOperation();
-}
-
void Editor::removeFormattingAndStyle()
{
ASSERT(m_frame.document());
@@ -730,7 +649,7 @@ TriState Editor::selectionHasStyle(CSSPropertyID propertyID, const String& value
String Editor::selectionStartCSSPropertyValue(CSSPropertyID propertyID)
{
- RefPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelectionStart(m_frame.selection().selection(),
+ RefPtrWillBeRawPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelectionStart(m_frame.selection().selection(),
propertyID == CSSPropertyBackgroundColor);
if (!selectionStyle || !selectionStyle->style())
return String();
@@ -752,7 +671,7 @@ void Editor::outdent()
IndentOutdentCommand::create(*m_frame.document(), IndentOutdentCommand::Outdent)->apply();
}
-static void dispatchEditableContentChangedEvents(PassRefPtr<Element> startRoot, PassRefPtr<Element> endRoot)
+static void dispatchEditableContentChangedEvents(PassRefPtrWillBeRawPtr<Element> startRoot, PassRefPtrWillBeRawPtr<Element> endRoot)
{
if (startRoot)
startRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableContentChanged), IGNORE_EXCEPTION);
@@ -760,7 +679,7 @@ static void dispatchEditableContentChangedEvents(PassRefPtr<Element> startRoot,
endRoot->dispatchEvent(Event::create(EventTypeNames::webkitEditableContentChanged), IGNORE_EXCEPTION);
}
-void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd)
+void Editor::appliedEditing(PassRefPtrWillBeRawPtr<CompositeEditCommand> cmd)
{
EventQueueScope scope;
m_frame.document()->updateLayout();
@@ -790,7 +709,7 @@ void Editor::appliedEditing(PassRefPtr<CompositeEditCommand> cmd)
respondToChangedContents(newSelection);
}
-void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd)
+void Editor::unappliedEditing(PassRefPtrWillBeRawPtr<EditCommandComposition> cmd)
{
EventQueueScope scope;
m_frame.document()->updateLayout();
@@ -798,15 +717,17 @@ void Editor::unappliedEditing(PassRefPtr<EditCommandComposition> cmd)
dispatchEditableContentChangedEvents(cmd->startingRootEditableElement(), cmd->endingRootEditableElement());
VisibleSelection newSelection(cmd->startingSelection());
- changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle);
+ newSelection.validatePositionsIfNeeded();
+ if (newSelection.start().document() == m_frame.document() && newSelection.end().document() == m_frame.document())
+ changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle);
- m_lastEditCommand = 0;
+ m_lastEditCommand = nullptr;
if (UndoStack* undoStack = this->undoStack())
undoStack->registerRedoStep(cmd);
respondToChangedContents(newSelection);
}
-void Editor::reappliedEditing(PassRefPtr<EditCommandComposition> cmd)
+void Editor::reappliedEditing(PassRefPtrWillBeRawPtr<EditCommandComposition> cmd)
{
EventQueueScope scope;
m_frame.document()->updateLayout();
@@ -816,18 +737,18 @@ void Editor::reappliedEditing(PassRefPtr<EditCommandComposition> cmd)
VisibleSelection newSelection(cmd->endingSelection());
changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle);
- m_lastEditCommand = 0;
+ m_lastEditCommand = nullptr;
if (UndoStack* undoStack = this->undoStack())
undoStack->registerUndoStep(cmd);
respondToChangedContents(newSelection);
}
-PassOwnPtr<Editor> Editor::create(Frame& frame)
+PassOwnPtrWillBeRawPtr<Editor> Editor::create(LocalFrame& frame)
{
- return adoptPtr(new Editor(frame));
+ return adoptPtrWillBeNoop(new Editor(frame));
}
-Editor::Editor(Frame& frame)
+Editor::Editor(LocalFrame& frame)
: m_frame(frame)
, m_preventRevealSelection(0)
, m_shouldStartNewKillRingSequence(false)
@@ -864,7 +785,6 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
VisibleSelection selection = selectionForCommand(triggeringEvent);
if (!selection.isContentEditable())
return false;
- RefPtr<Range> range = selection.toNormalizedRange();
spellChecker().updateMarkersForWordsAffectedByEditing(isSpaceOrNewline(text[0]));
@@ -874,7 +794,7 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
selection = selectionForCommand(triggeringEvent);
if (selection.isContentEditable()) {
if (Node* selectionStart = selection.start().deprecatedNode()) {
- RefPtr<Document> document(selectionStart->document());
+ RefPtrWillBeRawPtr<Document> document(selectionStart->document());
// Insert the text
TypingCommand::Options options = 0;
@@ -883,9 +803,9 @@ bool Editor::insertTextWithoutSendingTextEvent(const String& text, bool selectIn
TypingCommand::insertText(*document.get(), text, selection, options, triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompositionConfirm : TypingCommand::TextCompositionNone);
// Reveal the current selection
- if (Frame* editedFrame = document->frame()) {
+ if (LocalFrame* editedFrame = document->frame()) {
if (Page* page = editedFrame->page())
- page->focusController().focusedOrMainFrame()->selection().revealSelection(ScrollAlignment::alignCenterIfNeeded);
+ toLocalFrame(page->focusController().focusedOrMainFrame())->selection().revealSelection(ScrollAlignment::alignCenterIfNeeded);
}
}
}
@@ -930,7 +850,7 @@ void Editor::cut()
return; // DHTML did the whole operation
if (!canCut())
return;
- RefPtr<Range> selection = selectedRange();
+ RefPtrWillBeRawPtr<Range> selection = selectedRange();
if (shouldDeleteRange(selection.get())) {
spellChecker().updateMarkersForWordsAffectedByEditing(true);
String plainText = m_frame.selectedTextForClipboard();
@@ -1000,6 +920,71 @@ void Editor::performDelete()
setStartNewKillRingSequence(false);
}
+static void countEditingEvent(ExecutionContext* executionContext, const Event* event, UseCounter::Feature featureOnInput, UseCounter::Feature featureOnTextArea, UseCounter::Feature featureOnContentEditable, UseCounter::Feature featureOnNonNode)
+{
+ EventTarget* eventTarget = event->target();
+ Node* node = eventTarget->toNode();
+ if (!node) {
+ UseCounter::count(executionContext, featureOnNonNode);
+ return;
+ }
+
+ if (isHTMLInputElement(node)) {
+ UseCounter::count(executionContext, featureOnInput);
+ return;
+ }
+
+ if (isHTMLTextAreaElement(node)) {
+ UseCounter::count(executionContext, featureOnTextArea);
+ return;
+ }
+
+ HTMLTextFormControlElement* control = enclosingTextFormControl(node);
+ if (isHTMLInputElement(control)) {
+ UseCounter::count(executionContext, featureOnInput);
+ return;
+ }
+
+ if (isHTMLTextAreaElement(control)) {
+ UseCounter::count(executionContext, featureOnTextArea);
+ return;
+ }
+
+ UseCounter::count(executionContext, featureOnContentEditable);
+}
+
+void Editor::countEvent(ExecutionContext* executionContext, const Event* event)
+{
+ if (!executionContext)
+ return;
+
+ if (event->type() == EventTypeNames::textInput) {
+ countEditingEvent(executionContext, event,
+ UseCounter::TextInputEventOnInput,
+ UseCounter::TextInputEventOnTextArea,
+ UseCounter::TextInputEventOnContentEditable,
+ UseCounter::TextInputEventOnNotNode);
+ return;
+ }
+
+ if (event->type() == EventTypeNames::webkitBeforeTextInserted) {
+ countEditingEvent(executionContext, event,
+ UseCounter::WebkitBeforeTextInsertedOnInput,
+ UseCounter::WebkitBeforeTextInsertedOnTextArea,
+ UseCounter::WebkitBeforeTextInsertedOnContentEditable,
+ UseCounter::WebkitBeforeTextInsertedOnNotNode);
+ return;
+ }
+
+ if (event->type() == EventTypeNames::webkitEditableContentChanged) {
+ countEditingEvent(executionContext, event,
+ UseCounter::WebkitEditableContentChangedOnInput,
+ UseCounter::WebkitEditableContentChangedOnTextArea,
+ UseCounter::WebkitEditableContentChangedOnContentEditable,
+ UseCounter::WebkitEditableContentChangedOnNotNode);
+ }
+}
+
void Editor::copyImage(const HitTestResult& result)
{
writeImageNodeToPasteboard(Pasteboard::generalPasteboard(), result.innerNonSharedNode(), result.altDisplayString());
@@ -1033,17 +1018,17 @@ void Editor::redo()
void Editor::setBaseWritingDirection(WritingDirection direction)
{
- Node* focusedElement = frame().document()->focusedElement();
- if (focusedElement && isHTMLTextFormControlElement(focusedElement)) {
+ Element* focusedElement = frame().document()->focusedElement();
+ if (isHTMLTextFormControlElement(focusedElement)) {
if (direction == NaturalWritingDirection)
return;
- toHTMLElement(focusedElement)->setAttribute(dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl");
+ focusedElement->setAttribute(dirAttr, direction == LeftToRightWritingDirection ? "ltr" : "rtl");
focusedElement->dispatchInputEvent();
- frame().document()->updateStyleIfNeeded();
+ frame().document()->updateRenderTreeIfNeeded();
return;
}
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(CSSPropertyDirection, direction == LeftToRightWritingDirection ? "ltr" : direction == RightToLeftWritingDirection ? "rtl" : "inherit", false);
applyParagraphStyleToSelection(style.get(), EditActionSetWritingDirection);
}
@@ -1074,7 +1059,7 @@ void Editor::transpose()
previous = previous.previous();
if (!inSameParagraph(next, previous))
return;
- RefPtr<Range> range = makeRange(previous, next);
+ RefPtrWillBeRawPtr<Range> range = makeRange(previous, next);
if (!range)
return;
VisibleSelection newSelection(range.get(), DOWNSTREAM);
@@ -1124,7 +1109,7 @@ void Editor::changeSelectionAfterCommand(const VisibleSelection& newSelection,
// does not call EditorClient::respondToChangedSelection(), which, on the Mac, sends selection change notifications and
// starts a new kill ring sequence, but we want to do these things (matches AppKit).
if (selectionDidNotChangeDOMPosition)
- client().respondToChangedSelection(m_frame.selection().selectionType());
+ client().respondToChangedSelection(&m_frame, m_frame.selection().selectionType());
}
IntRect Editor::firstRectForRange(Range* range) const
@@ -1143,10 +1128,10 @@ IntRect Editor::firstRectForRange(Range* range) const
if (startCaretRect.y() == endCaretRect.y()) {
// start and end are on the same line
- return IntRect(min(startCaretRect.x(), endCaretRect.x()),
+ return IntRect(std::min(startCaretRect.x(), endCaretRect.x()),
startCaretRect.y(),
abs(endCaretRect.x() - startCaretRect.x()),
- max(startCaretRect.height(), endCaretRect.height()));
+ std::max(startCaretRect.height(), endCaretRect.height()));
}
// start and end aren't on the same line, so go from start to the end of its line
@@ -1164,7 +1149,7 @@ void Editor::computeAndSetTypingStyle(StylePropertySet* style, EditAction editin
}
// Calculate the current typing style.
- RefPtr<EditingStyle> typingStyle;
+ RefPtrWillBeRawPtr<EditingStyle> typingStyle = nullptr;
if (m_frame.selection().typingStyle()) {
typingStyle = m_frame.selection().typingStyle()->copy();
typingStyle->overrideWithStyle(style);
@@ -1175,7 +1160,7 @@ void Editor::computeAndSetTypingStyle(StylePropertySet* style, EditAction editin
typingStyle->prepareToApplyAt(m_frame.selection().selection().visibleStart().deepEquivalent(), EditingStyle::PreserveWritingDirection);
// Handle block styles, substracting these from the typing style.
- RefPtr<EditingStyle> blockStyle = typingStyle->extractAndRemoveBlockProperties();
+ RefPtrWillBeRawPtr<EditingStyle> blockStyle = typingStyle->extractAndRemoveBlockProperties();
if (!blockStyle->isEmpty()) {
ASSERT(m_frame.document());
ApplyStyleCommand::create(*m_frame.document(), blockStyle.get(), editingAction)->apply();
@@ -1195,7 +1180,7 @@ bool Editor::findString(const String& target, FindOptions options)
{
VisibleSelection selection = m_frame.selection().selection();
- RefPtr<Range> resultRange = rangeOfString(target, selection.firstRange().get(), options);
+ RefPtrWillBeRawPtr<Range> resultRange = rangeOfString(target, selection.firstRange().get(), options);
if (!resultRange)
return false;
@@ -1205,11 +1190,11 @@ bool Editor::findString(const String& target, FindOptions options)
return true;
}
-PassRefPtr<Range> Editor::findStringAndScrollToVisible(const String& target, Range* previousMatch, FindOptions options)
+PassRefPtrWillBeRawPtr<Range> Editor::findStringAndScrollToVisible(const String& target, Range* previousMatch, FindOptions options)
{
- RefPtr<Range> nextMatch = rangeOfString(target, previousMatch, options);
+ RefPtrWillBeRawPtr<Range> nextMatch = rangeOfString(target, previousMatch, options);
if (!nextMatch)
- return 0;
+ return nullptr;
nextMatch->firstNode()->renderer()->scrollRectToVisible(nextMatch->boundingBox(),
ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
@@ -1217,75 +1202,76 @@ PassRefPtr<Range> Editor::findStringAndScrollToVisible(const String& target, Ran
return nextMatch.release();
}
-PassRefPtr<Range> Editor::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
+static PassRefPtrWillBeRawPtr<Range> findStringBetweenPositions(const String& target, const Position& start, const Position& end, FindOptions options)
+{
+ Position searchStart(start);
+ Position searchEnd(end);
+
+ bool forward = !(options & Backwards);
+
+ while (true) {
+ Position resultStart;
+ Position resultEnd;
+ findPlainText(searchStart, searchEnd, target, options, resultStart, resultEnd);
+ if (resultStart == resultEnd)
+ return nullptr;
+
+ RefPtrWillBeRawPtr<Range> resultRange = Range::create(*resultStart.document(), resultStart, resultEnd);
+ if (!resultRange->collapsed())
+ return resultRange.release();
+
+ // Found text spans over multiple TreeScopes. Since it's impossible to return such section as a Range,
+ // we skip this match and seek for the next occurrence.
+ // FIXME: Handle this case.
+ if (forward)
+ searchStart = resultStart.next();
+ else
+ searchEnd = resultEnd.previous();
+ }
+
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<Range> Editor::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
{
if (target.isEmpty())
- return 0;
+ return nullptr;
- // Start from an edge of the reference range, if there's a reference range that's not in shadow content. Which edge
- // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
- RefPtr<Range> searchRange(rangeOfContents(m_frame.document()));
+ // Start from an edge of the reference range. Which edge is used depends on whether we're searching forward or
+ // backward, and whether startInSelection is set.
+ Position searchStart = firstPositionInNode(m_frame.document());
+ Position searchEnd = lastPositionInNode(m_frame.document());
bool forward = !(options & Backwards);
bool startInReferenceRange = referenceRange && (options & StartInSelection);
if (referenceRange) {
if (forward)
- searchRange->setStart(startInReferenceRange ? referenceRange->startPosition() : referenceRange->endPosition());
+ searchStart = startInReferenceRange ? referenceRange->startPosition() : referenceRange->endPosition();
else
- searchRange->setEnd(startInReferenceRange ? referenceRange->endPosition() : referenceRange->startPosition());
+ searchEnd = startInReferenceRange ? referenceRange->endPosition() : referenceRange->startPosition();
}
- RefPtr<Node> shadowTreeRoot = referenceRange && referenceRange->startContainer() ? referenceRange->startContainer()->nonBoundaryShadowTreeRootNode() : 0;
- if (shadowTreeRoot) {
- if (forward)
- searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount());
- else
- searchRange->setStart(shadowTreeRoot.get(), 0);
- }
+ RefPtrWillBeRawPtr<Range> resultRange = findStringBetweenPositions(target, searchStart, searchEnd, options);
- RefPtr<Range> resultRange(findPlainText(searchRange.get(), target, options));
// If we started in the reference range and the found range exactly matches the reference range, find again.
// Build a selection with the found range to remove collapsed whitespace.
// Compare ranges instead of selection objects to ignore the way that the current selection was made.
- if (startInReferenceRange && areRangesEqual(VisibleSelection(resultRange.get()).toNormalizedRange().get(), referenceRange)) {
- searchRange = rangeOfContents(m_frame.document());
- if (forward)
- searchRange->setStart(referenceRange->endPosition());
- else
- searchRange->setEnd(referenceRange->startPosition());
-
- if (shadowTreeRoot) {
- if (forward)
- searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount());
- else
- searchRange->setStart(shadowTreeRoot.get(), 0);
- }
-
- resultRange = findPlainText(searchRange.get(), target, options);
- }
-
- // If nothing was found in the shadow tree, search in main content following the shadow tree.
- if (resultRange->collapsed(ASSERT_NO_EXCEPTION) && shadowTreeRoot) {
- searchRange = rangeOfContents(m_frame.document());
+ if (resultRange && startInReferenceRange && areRangesEqual(VisibleSelection(resultRange.get()).toNormalizedRange().get(), referenceRange)) {
if (forward)
- searchRange->setStartAfter(shadowTreeRoot->shadowHost());
+ searchStart = resultRange->endPosition();
else
- searchRange->setEndBefore(shadowTreeRoot->shadowHost());
-
- resultRange = findPlainText(searchRange.get(), target, options);
+ searchEnd = resultRange->startPosition();
+ resultRange = findStringBetweenPositions(target, searchStart, searchEnd, options);
}
- // If we didn't find anything and we're wrapping, search again in the entire document (this will
- // redundantly re-search the area already searched in some cases).
- if (resultRange->collapsed(ASSERT_NO_EXCEPTION) && options & WrapAround) {
- searchRange = rangeOfContents(m_frame.document());
- resultRange = findPlainText(searchRange.get(), target, options);
- // We used to return false here if we ended up with the same range that we started with
- // (e.g., the reference range was already the only instance of this text). But we decided that
- // this should be a success case instead, so we'll just fall through in that case.
+ if (!resultRange && options & WrapAround) {
+ searchStart = firstPositionInNode(m_frame.document());
+ searchEnd = lastPositionInNode(m_frame.document());
+ resultRange = findStringBetweenPositions(target, searchStart, searchEnd, options);
}
- return resultRange->collapsed(ASSERT_NO_EXCEPTION) ? 0 : resultRange.release();
+ return resultRange.release();
}
void Editor::setMarkedTextMatchesAreHighlighted(bool flag)
@@ -1294,7 +1280,7 @@ void Editor::setMarkedTextMatchesAreHighlighted(bool flag)
return;
m_areMarkedTextMatchesHighlighted = flag;
- m_frame.document()->markers()->repaintMarkers(DocumentMarker::TextMatch);
+ m_frame.document()->markers().repaintMarkers(DocumentMarker::TextMatch);
}
void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
@@ -1315,4 +1301,10 @@ void Editor::toggleOverwriteModeEnabled()
frame().selection().setShouldShowBlockCursor(m_overwriteModeEnabled);
}
+void Editor::trace(Visitor* visitor)
+{
+ visitor->trace(m_lastEditCommand);
+ visitor->trace(m_mark);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/Editor.h b/chromium/third_party/WebKit/Source/core/editing/Editor.h
index 15b1ba6ac30..eebeb4a0a1e 100644
--- a/chromium/third_party/WebKit/Source/core/editing/Editor.h
+++ b/chromium/third_party/WebKit/Source/core/editing/Editor.h
@@ -26,7 +26,7 @@
#ifndef Editor_h
#define Editor_h
-#include "core/dom/ClipboardAccessPolicy.h"
+#include "core/clipboard/ClipboardAccessPolicy.h"
#include "core/dom/DocumentMarker.h"
#include "core/editing/EditAction.h"
#include "core/editing/EditingBehavior.h"
@@ -37,6 +37,7 @@
#include "core/editing/WritingDirection.h"
#include "core/frame/FrameDestructionObserver.h"
#include "platform/PasteMode.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -46,7 +47,7 @@ class EditCommand;
class EditCommandComposition;
class EditorClient;
class EditorInternalCommand;
-class Frame;
+class LocalFrame;
class HTMLElement;
class HitTestResult;
class KillRing;
@@ -62,15 +63,15 @@ class UndoStack;
enum EditorCommandSource { CommandFromMenuOrKeyBinding, CommandFromDOM, CommandFromDOMWithUserInterface };
enum EditorParagraphSeparator { EditorParagraphSeparatorIsDiv, EditorParagraphSeparatorIsP };
-class Editor {
+class Editor FINAL : public NoBaseWillBeGarbageCollectedFinalized<Editor> {
WTF_MAKE_NONCOPYABLE(Editor);
public:
- static PassOwnPtr<Editor> create(Frame&);
+ static PassOwnPtrWillBeRawPtr<Editor> create(LocalFrame&);
~Editor();
EditorClient& client() const;
- Frame& frame() const { return m_frame; }
+ LocalFrame& frame() const { return m_frame; }
CompositeEditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
@@ -96,6 +97,7 @@ public:
void pasteAsPlainText();
void performDelete();
+ static void countEvent(ExecutionContext*, const Event*);
void copyImage(const HitTestResult&);
void indent();
@@ -112,14 +114,6 @@ public:
TriState selectionUnorderedListState() const;
TriState selectionOrderedListState() const;
- PassRefPtr<Node> insertOrderedList();
- PassRefPtr<Node> insertUnorderedList();
- bool canIncreaseSelectionListLevel();
- bool canDecreaseSelectionListLevel();
- PassRefPtr<Node> increaseSelectionListLevel();
- PassRefPtr<Node> increaseSelectionListLevelOrdered();
- PassRefPtr<Node> increaseSelectionListLevelUnordered();
- void decreaseSelectionListLevel();
void removeFormattingAndStyle();
@@ -133,9 +127,9 @@ public:
void applyStyleToSelection(StylePropertySet*, EditAction);
void applyParagraphStyleToSelection(StylePropertySet*, EditAction);
- void appliedEditing(PassRefPtr<CompositeEditCommand>);
- void unappliedEditing(PassRefPtr<EditCommandComposition>);
- void reappliedEditing(PassRefPtr<EditCommandComposition>);
+ void appliedEditing(PassRefPtrWillBeRawPtr<CompositeEditCommand>);
+ void unappliedEditing(PassRefPtrWillBeRawPtr<EditCommandComposition>);
+ void reappliedEditing(PassRefPtrWillBeRawPtr<EditCommandComposition>);
void setShouldStyleWithCSS(bool flag) { m_shouldStyleWithCSS = flag; }
bool shouldStyleWithCSS() const { return m_shouldStyleWithCSS; }
@@ -143,7 +137,7 @@ public:
class Command {
public:
Command();
- Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<Frame>);
+ Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<LocalFrame>);
bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
bool execute(Event* triggeringEvent) const;
@@ -156,14 +150,15 @@ public:
bool isTextInsertion() const;
+ // Returns 0 if this Command is not supported.
+ int idForHistogram() const;
private:
const EditorInternalCommand* m_command;
EditorCommandSource m_source;
- RefPtr<Frame> m_frame;
+ RefPtr<LocalFrame> m_frame;
};
Command command(const String& commandName); // Command source is CommandFromMenuOrKeyBinding.
Command command(const String& commandName, EditorCommandSource);
- static bool commandIsSupportedFromMenuOrKeyBinding(const String& commandName); // Works without a frame.
bool insertText(const String&, Event* triggeringEvent);
bool insertTextWithoutSendingTextEvent(const String&, bool selectInsertedText, TextEvent* triggeringEvent);
@@ -197,11 +192,11 @@ public:
EditingBehavior behavior() const;
- PassRefPtr<Range> selectedRange();
+ PassRefPtrWillBeRawPtr<Range> selectedRange();
void addToKillRing(Range*, bool prepend);
- void pasteAsFragment(PassRefPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
+ void pasteAsFragment(PassRefPtrWillBeRawPtr<DocumentFragment>, bool smartReplace, bool matchStyle);
void pasteAsPlainText(const String&, bool smartReplace);
Node* findEventTargetFrom(const VisibleSelection&) const;
@@ -210,7 +205,7 @@ public:
// FIXME: Switch callers over to the FindOptions version and retire this one.
bool findString(const String&, bool forward, bool caseFlag, bool wrapFlag, bool startInSelection);
- PassRefPtr<Range> findStringAndScrollToVisible(const String&, Range*, FindOptions);
+ PassRefPtrWillBeRawPtr<Range> findStringAndScrollToVisible(const String&, Range*, FindOptions);
const VisibleSelection& mark() const; // Mark, to be used as emacs uses it.
void setMark(const VisibleSelection&);
@@ -224,7 +219,7 @@ public:
bool markedTextMatchesAreHighlighted() const;
void setMarkedTextMatchesAreHighlighted(bool);
- void replaceSelectionWithFragment(PassRefPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
+ void replaceSelectionWithFragment(PassRefPtrWillBeRawPtr<DocumentFragment>, bool selectReplacement, bool smartReplace, bool matchStyle);
void replaceSelectionWithText(const String&, bool selectReplacement, bool smartReplace);
EditorParagraphSeparator defaultParagraphSeparator() const { return m_defaultParagraphSeparator; }
@@ -240,12 +235,11 @@ public:
};
friend class RevealSelectionScope;
- // Export interpretKeyEvent only for testing
- static const char* interpretKeyEvent(const WebCore::KeyboardEvent*);
+ void trace(Visitor*);
private:
- Frame& m_frame;
- RefPtr<CompositeEditCommand> m_lastEditCommand;
+ LocalFrame& m_frame;
+ RefPtrWillBeMember<CompositeEditCommand> m_lastEditCommand;
int m_preventRevealSelection;
bool m_shouldStartNewKillRingSequence;
bool m_shouldStyleWithCSS;
@@ -255,7 +249,7 @@ private:
EditorParagraphSeparator m_defaultParagraphSeparator;
bool m_overwriteModeEnabled;
- explicit Editor(Frame&);
+ explicit Editor(LocalFrame&);
bool canDeleteRange(Range*) const;
@@ -277,7 +271,7 @@ private:
Node* findEventTargetFromSelection() const;
- PassRefPtr<Range> rangeOfString(const String&, Range*, FindOptions);
+ PassRefPtrWillBeRawPtr<Range> rangeOfString(const String&, Range*, FindOptions);
SpellChecker& spellChecker() const;
diff --git a/chromium/third_party/WebKit/Source/core/editing/EditorCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/EditorCommand.cpp
index 3198fcb2ab9..ab6accac8b2 100644
--- a/chromium/third_party/WebKit/Source/core/editing/EditorCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/EditorCommand.cpp
@@ -28,15 +28,15 @@
#include "config.h"
#include "core/editing/Editor.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
+#include "core/clipboard/Pasteboard.h"
#include "core/css/CSSValueList.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/DocumentFragment.h"
-#include "core/events/Event.h"
#include "core/editing/CreateLinkCommand.h"
#include "core/editing/FormatBlockCommand.h"
#include "core/editing/IndentOutdentCommand.h"
@@ -46,20 +46,21 @@
#include "core/editing/TypingCommand.h"
#include "core/editing/UnlinkCommand.h"
#include "core/editing/markup.h"
+#include "core/events/Event.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLFontElement.h"
#include "core/html/HTMLHRElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/page/Chrome.h"
#include "core/page/EditorClient.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
-#include "core/platform/Pasteboard.h"
#include "core/rendering/RenderBox.h"
#include "platform/KillRing.h"
#include "platform/scroll/Scrollbar.h"
+#include "public/platform/Platform.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
@@ -68,11 +69,12 @@ using namespace HTMLNames;
class EditorInternalCommand {
public:
- bool (*execute)(Frame&, Event*, EditorCommandSource, const String&);
- bool (*isSupportedFromDOM)(Frame*);
- bool (*isEnabled)(Frame&, Event*, EditorCommandSource);
- TriState (*state)(Frame&, Event*);
- String (*value)(Frame&, Event*);
+ int idForUserMetrics;
+ bool (*execute)(LocalFrame&, Event*, EditorCommandSource, const String&);
+ bool (*isSupportedFromDOM)(LocalFrame*);
+ bool (*isEnabled)(LocalFrame&, Event*, EditorCommandSource);
+ TriState (*state)(LocalFrame&, Event*);
+ String (*value)(LocalFrame&, Event*);
bool isTextInsertion;
bool allowExecutionWhenDisabled;
};
@@ -88,7 +90,7 @@ static const bool doNotAllowExecutionWhenDisabled = false;
// Related to Editor::selectionForCommand.
// Certain operations continue to use the target control's selection even if the event handler
// already moved the selection outside of the text control.
-static Frame* targetFrame(Frame& frame, Event* event)
+static LocalFrame* targetFrame(LocalFrame& frame, Event* event)
{
if (!event)
return &frame;
@@ -98,7 +100,7 @@ static Frame* targetFrame(Frame& frame, Event* event)
return node->document().frame();
}
-static bool applyCommandToFrame(Frame& frame, EditorCommandSource source, EditAction action, StylePropertySet* style)
+static bool applyCommandToFrame(LocalFrame& frame, EditorCommandSource source, EditAction action, StylePropertySet* style)
{
// FIXME: We don't call shouldApplyStyle when the source is DOM; is there a good reason for that?
switch (source) {
@@ -114,16 +116,16 @@ static bool applyCommandToFrame(Frame& frame, EditorCommandSource source, EditAc
return false;
}
-static bool executeApplyStyle(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
+static bool executeApplyStyle(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(propertyID, propertyValue);
return applyCommandToFrame(frame, source, action, style.get());
}
-static bool executeApplyStyle(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, CSSValueID propertyValue)
+static bool executeApplyStyle(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, CSSValueID propertyValue)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(propertyID, propertyValue);
return applyCommandToFrame(frame, source, action, style.get());
}
@@ -131,16 +133,16 @@ static bool executeApplyStyle(Frame& frame, EditorCommandSource source, EditActi
// FIXME: executeToggleStyleInList does not handle complicated cases such as <b><u>hello</u>world</b> properly.
// This function must use Editor::selectionHasStyle to determine the current style but we cannot fix this
// until https://bugs.webkit.org/show_bug.cgi?id=27818 is resolved.
-static bool executeToggleStyleInList(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, CSSValue* value)
+static bool executeToggleStyleInList(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, CSSValue* value)
{
- RefPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelectionStart(frame.selection().selection());
+ RefPtrWillBeRawPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelectionStart(frame.selection().selection());
if (!selectionStyle || !selectionStyle->style())
return false;
- RefPtr<CSSValue> selectedCSSValue = selectionStyle->style()->getPropertyCSSValue(propertyID);
+ RefPtrWillBeRawPtr<CSSValue> selectedCSSValue = selectionStyle->style()->getPropertyCSSValue(propertyID);
String newStyle("none");
if (selectedCSSValue->isValueList()) {
- RefPtr<CSSValueList> selectedCSSValueList = toCSSValueList(selectedCSSValue.get());
+ RefPtrWillBeRawPtr<CSSValueList> selectedCSSValueList = toCSSValueList(selectedCSSValue.get());
if (!selectedCSSValueList->removeAll(value))
selectedCSSValueList->append(value);
if (selectedCSSValueList->length())
@@ -150,12 +152,12 @@ static bool executeToggleStyleInList(Frame& frame, EditorCommandSource source, E
newStyle = value->cssText();
// FIXME: We shouldn't be having to convert new style into text. We should have setPropertyCSSValue.
- RefPtr<MutableStylePropertySet> newMutableStyle = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> newMutableStyle = MutableStylePropertySet::create();
newMutableStyle->setProperty(propertyID, newStyle);
return applyCommandToFrame(frame, source, action, newMutableStyle.get());
}
-static bool executeToggleStyle(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const char* offValue, const char* onValue)
+static bool executeToggleStyle(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const char* offValue, const char* onValue)
{
// Style is considered present when
// Mac: present at the beginning of selection
@@ -167,13 +169,13 @@ static bool executeToggleStyle(Frame& frame, EditorCommandSource source, EditAct
else
styleIsPresent = frame.editor().selectionHasStyle(propertyID, onValue) == TrueTriState;
- RefPtr<EditingStyle> style = EditingStyle::create(propertyID, styleIsPresent ? offValue : onValue);
+ RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(propertyID, styleIsPresent ? offValue : onValue);
return applyCommandToFrame(frame, source, action, style->style());
}
-static bool executeApplyParagraphStyle(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
+static bool executeApplyParagraphStyle(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(propertyID, propertyValue);
// FIXME: We don't call shouldApplyStyle when the source is DOM; is there a good reason for that?
switch (source) {
@@ -189,17 +191,17 @@ static bool executeApplyParagraphStyle(Frame& frame, EditorCommandSource source,
return false;
}
-static bool executeInsertFragment(Frame& frame, PassRefPtr<DocumentFragment> fragment)
+static bool executeInsertFragment(LocalFrame& frame, PassRefPtrWillBeRawPtr<DocumentFragment> fragment)
{
ASSERT(frame.document());
ReplaceSelectionCommand::create(*frame.document(), fragment, ReplaceSelectionCommand::PreventNesting, EditActionUnspecified)->apply();
return true;
}
-static bool executeInsertNode(Frame& frame, PassRefPtr<Node> content)
+static bool executeInsertNode(LocalFrame& frame, PassRefPtrWillBeRawPtr<Node> content)
{
ASSERT(frame.document());
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(*frame.document());
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(*frame.document());
TrackExceptionState exceptionState;
fragment->appendChild(content, exceptionState);
if (exceptionState.hadException())
@@ -207,36 +209,35 @@ static bool executeInsertNode(Frame& frame, PassRefPtr<Node> content)
return executeInsertFragment(frame, fragment.release());
}
-static bool expandSelectionToGranularity(Frame& frame, TextGranularity granularity)
+static bool expandSelectionToGranularity(LocalFrame& frame, TextGranularity granularity)
{
VisibleSelection selection = frame.selection().selection();
selection.expandUsingGranularity(granularity);
- RefPtr<Range> newRange = selection.toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> newRange = selection.toNormalizedRange();
if (!newRange)
return false;
- if (newRange->collapsed(IGNORE_EXCEPTION))
+ if (newRange->collapsed())
return false;
- RefPtr<Range> oldRange = frame.selection().selection().toNormalizedRange();
EAffinity affinity = frame.selection().affinity();
- frame.selection().setSelectedRange(newRange.get(), affinity, true);
+ frame.selection().setSelectedRange(newRange.get(), affinity, FrameSelection::NonDirectional, FrameSelection::CloseTyping);
return true;
}
-static TriState stateStyle(Frame& frame, CSSPropertyID propertyID, const char* desiredValue)
+static TriState stateStyle(LocalFrame& frame, CSSPropertyID propertyID, const char* desiredValue)
{
if (frame.editor().behavior().shouldToggleStyleBasedOnStartOfSelection())
return frame.editor().selectionStartHasStyle(propertyID, desiredValue) ? TrueTriState : FalseTriState;
return frame.editor().selectionHasStyle(propertyID, desiredValue);
}
-static String valueStyle(Frame& frame, CSSPropertyID propertyID)
+static String valueStyle(LocalFrame& frame, CSSPropertyID propertyID)
{
// FIXME: Rather than retrieving the style at the start of the current selection,
// we should retrieve the style present throughout the selection for non-Mac platforms.
return frame.editor().selectionStartCSSPropertyValue(propertyID);
}
-static TriState stateTextWritingDirection(Frame& frame, WritingDirection direction)
+static TriState stateTextWritingDirection(LocalFrame& frame, WritingDirection direction)
{
bool hasNestedOrMultipleEmbeddings;
WritingDirection selectionDirection = EditingStyle::textDirectionForSelection(frame.selection().selection(),
@@ -245,7 +246,7 @@ static TriState stateTextWritingDirection(Frame& frame, WritingDirection directi
return (selectionDirection == direction && !hasNestedOrMultipleEmbeddings) ? TrueTriState : FalseTriState;
}
-static unsigned verticalScrollDistance(Frame& frame)
+static unsigned verticalScrollDistance(LocalFrame& frame)
{
Element* focusedElement = frame.document()->focusedElement();
if (!focusedElement)
@@ -262,7 +263,7 @@ static unsigned verticalScrollDistance(Frame& frame)
return static_cast<unsigned>(max(max<int>(height * ScrollableArea::minFractionToStepWhenPaging(), height - ScrollableArea::maxOverlapBetweenPages()), 1));
}
-static RefPtr<Range> unionDOMRanges(Range* a, Range* b)
+static PassRefPtrWillBeRawPtr<Range> unionDOMRanges(Range* a, Range* b)
{
Range* start = a->compareBoundaryPoints(Range::START_TO_START, b, ASSERT_NO_EXCEPTION) <= 0 ? a : b;
Range* end = a->compareBoundaryPoints(Range::END_TO_END, b, ASSERT_NO_EXCEPTION) <= 0 ? b : a;
@@ -272,18 +273,18 @@ static RefPtr<Range> unionDOMRanges(Range* a, Range* b)
// Execute command functions
-static bool executeBackColor(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeBackColor(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
{
return executeApplyStyle(frame, source, EditActionSetBackgroundColor, CSSPropertyBackgroundColor, value);
}
-static bool executeCopy(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeCopy(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().copy();
return true;
}
-static bool executeCreateLink(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeCreateLink(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
// FIXME: If userInterface is true, we should display a dialog box to let the user enter a URL.
if (value.isEmpty())
@@ -293,13 +294,13 @@ static bool executeCreateLink(Frame& frame, Event*, EditorCommandSource, const S
return true;
}
-static bool executeCut(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeCut(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().cut();
return true;
}
-static bool executeDefaultParagraphSeparator(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeDefaultParagraphSeparator(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
if (equalIgnoringCase(value, "div"))
frame.editor().setDefaultParagraphSeparator(EditorParagraphSeparatorIsDiv);
@@ -309,7 +310,7 @@ static bool executeDefaultParagraphSeparator(Frame& frame, Event*, EditorCommand
return true;
}
-static bool executeDelete(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeDelete(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
switch (source) {
case CommandFromMenuOrKeyBinding: {
@@ -329,38 +330,38 @@ static bool executeDelete(Frame& frame, Event*, EditorCommandSource source, cons
return false;
}
-static bool executeDeleteBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
return true;
}
-static bool executeDeleteBackwardByDecomposingPreviousCharacter(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteBackwardByDecomposingPreviousCharacter(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
WTF_LOG_ERROR("DeleteBackwardByDecomposingPreviousCharacter is not implemented, doing DeleteBackward instead");
frame.editor().deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
return true;
}
-static bool executeDeleteForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().deleteWithDirection(DirectionForward, CharacterGranularity, false, true);
return true;
}
-static bool executeDeleteToBeginningOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToBeginningOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().deleteWithDirection(DirectionBackward, LineBoundary, true, false);
return true;
}
-static bool executeDeleteToBeginningOfParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToBeginningOfParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().deleteWithDirection(DirectionBackward, ParagraphBoundary, true, false);
return true;
}
-static bool executeDeleteToEndOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToEndOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
// Despite its name, this command should delete the newline at the end of
// a paragraph if you are at the end of a paragraph (like DeleteToEndOfParagraph).
@@ -368,7 +369,7 @@ static bool executeDeleteToEndOfLine(Frame& frame, Event*, EditorCommandSource,
return true;
}
-static bool executeDeleteToEndOfParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToEndOfParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
// Despite its name, this command should delete the newline at the end of
// a paragraph if you are at the end of a paragraph.
@@ -376,11 +377,11 @@ static bool executeDeleteToEndOfParagraph(Frame& frame, Event*, EditorCommandSou
return true;
}
-static bool executeDeleteToMark(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<Range> mark = frame.editor().mark().toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> mark = frame.editor().mark().toNormalizedRange();
if (mark) {
- bool selected = frame.selection().setSelectedRange(unionDOMRanges(mark.get(), frame.editor().selectedRange().get()).get(), DOWNSTREAM, true);
+ bool selected = frame.selection().setSelectedRange(unionDOMRanges(mark.get(), frame.editor().selectedRange().get()).get(), DOWNSTREAM, FrameSelection::NonDirectional, FrameSelection::CloseTyping);
ASSERT(selected);
if (!selected)
return false;
@@ -390,29 +391,29 @@ static bool executeDeleteToMark(Frame& frame, Event*, EditorCommandSource, const
return true;
}
-static bool executeDeleteWordBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteWordBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().deleteWithDirection(DirectionBackward, WordGranularity, true, false);
return true;
}
-static bool executeDeleteWordForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteWordForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().deleteWithDirection(DirectionForward, WordGranularity, true, false);
return true;
}
-static bool executeFindString(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeFindString(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
return frame.editor().findString(value, true, false, true, false);
}
-static bool executeFontName(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeFontName(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
{
return executeApplyStyle(frame, source, EditActionSetFont, CSSPropertyFontFamily, value);
}
-static bool executeFontSize(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeFontSize(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
{
CSSValueID size;
if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
@@ -420,17 +421,17 @@ static bool executeFontSize(Frame& frame, Event*, EditorCommandSource source, co
return executeApplyStyle(frame, source, EditActionChangeAttributes, CSSPropertyFontSize, size);
}
-static bool executeFontSizeDelta(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeFontSizeDelta(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
{
return executeApplyStyle(frame, source, EditActionChangeAttributes, CSSPropertyWebkitFontSizeDelta, value);
}
-static bool executeForeColor(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeForeColor(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
{
return executeApplyStyle(frame, source, EditActionSetColor, CSSPropertyColor, value);
}
-static bool executeFormatBlock(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeFormatBlock(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
String tagName = value.lower();
if (tagName[0] == '<' && tagName[tagName.length() - 1] == '>')
@@ -442,12 +443,12 @@ static bool executeFormatBlock(Frame& frame, Event*, EditorCommandSource, const
QualifiedName qualifiedTagName(prefix, localName, xhtmlNamespaceURI);
ASSERT(frame.document());
- RefPtr<FormatBlockCommand> command = FormatBlockCommand::create(*frame.document(), qualifiedTagName);
+ RefPtrWillBeRawPtr<FormatBlockCommand> command = FormatBlockCommand::create(*frame.document(), qualifiedTagName);
command->apply();
return command->didApply();
}
-static bool executeForwardDelete(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeForwardDelete(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
switch (source) {
case CommandFromMenuOrKeyBinding:
@@ -466,49 +467,49 @@ static bool executeForwardDelete(Frame& frame, Event*, EditorCommandSource sourc
return false;
}
-static bool executeIgnoreSpelling(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeIgnoreSpelling(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.spellChecker().ignoreSpelling();
return true;
}
-static bool executeIndent(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeIndent(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
ASSERT(frame.document());
IndentOutdentCommand::create(*frame.document(), IndentOutdentCommand::Indent)->apply();
return true;
}
-static bool executeInsertBacktab(Frame& frame, Event* event, EditorCommandSource, const String&)
+static bool executeInsertBacktab(LocalFrame& frame, Event* event, EditorCommandSource, const String&)
{
return targetFrame(frame, event)->eventHandler().handleTextInputEvent("\t", event, TextEventInputBackTab);
}
-static bool executeInsertHorizontalRule(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertHorizontalRule(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
ASSERT(frame.document());
- RefPtr<HTMLHRElement> rule = HTMLHRElement::create(*frame.document());
+ RefPtrWillBeRawPtr<HTMLHRElement> rule = HTMLHRElement::create(*frame.document());
if (!value.isEmpty())
rule->setIdAttribute(AtomicString(value));
return executeInsertNode(frame, rule.release());
}
-static bool executeInsertHTML(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertHTML(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
ASSERT(frame.document());
return executeInsertFragment(frame, createFragmentFromMarkup(*frame.document(), value, ""));
}
-static bool executeInsertImage(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertImage(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
// FIXME: If userInterface is true, we should display a dialog box and let the user choose a local image.
ASSERT(frame.document());
- RefPtr<HTMLImageElement> image = HTMLImageElement::create(*frame.document());
+ RefPtrWillBeRawPtr<HTMLImageElement> image = HTMLImageElement::create(*frame.document());
image->setSrc(value);
return executeInsertNode(frame, image.release());
}
-static bool executeInsertLineBreak(Frame& frame, Event* event, EditorCommandSource source, const String&)
+static bool executeInsertLineBreak(LocalFrame& frame, Event* event, EditorCommandSource source, const String&)
{
switch (source) {
case CommandFromMenuOrKeyBinding:
@@ -526,145 +527,145 @@ static bool executeInsertLineBreak(Frame& frame, Event* event, EditorCommandSour
return false;
}
-static bool executeInsertNewline(Frame& frame, Event* event, EditorCommandSource, const String&)
+static bool executeInsertNewline(LocalFrame& frame, Event* event, EditorCommandSource, const String&)
{
- Frame* targetFrame = WebCore::targetFrame(frame, event);
+ LocalFrame* targetFrame = WebCore::targetFrame(frame, event);
return targetFrame->eventHandler().handleTextInputEvent("\n", event, targetFrame->editor().canEditRichly() ? TextEventInputKeyboard : TextEventInputLineBreak);
}
-static bool executeInsertNewlineInQuotedContent(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeInsertNewlineInQuotedContent(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
ASSERT(frame.document());
TypingCommand::insertParagraphSeparatorInQuotedContent(*frame.document());
return true;
}
-static bool executeInsertOrderedList(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeInsertOrderedList(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
ASSERT(frame.document());
InsertListCommand::create(*frame.document(), InsertListCommand::OrderedList)->apply();
return true;
}
-static bool executeInsertParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeInsertParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
ASSERT(frame.document());
TypingCommand::insertParagraphSeparator(*frame.document(), 0);
return true;
}
-static bool executeInsertTab(Frame& frame, Event* event, EditorCommandSource, const String&)
+static bool executeInsertTab(LocalFrame& frame, Event* event, EditorCommandSource, const String&)
{
return targetFrame(frame, event)->eventHandler().handleTextInputEvent("\t", event);
}
-static bool executeInsertText(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertText(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
ASSERT(frame.document());
TypingCommand::insertText(*frame.document(), value, 0);
return true;
}
-static bool executeInsertUnorderedList(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeInsertUnorderedList(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
ASSERT(frame.document());
InsertListCommand::create(*frame.document(), InsertListCommand::UnorderedList)->apply();
return true;
}
-static bool executeJustifyCenter(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeJustifyCenter(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeApplyParagraphStyle(frame, source, EditActionCenter, CSSPropertyTextAlign, "center");
}
-static bool executeJustifyFull(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeJustifyFull(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeApplyParagraphStyle(frame, source, EditActionJustify, CSSPropertyTextAlign, "justify");
}
-static bool executeJustifyLeft(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeJustifyLeft(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeApplyParagraphStyle(frame, source, EditActionAlignLeft, CSSPropertyTextAlign, "left");
}
-static bool executeJustifyRight(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeJustifyRight(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeApplyParagraphStyle(frame, source, EditActionAlignRight, CSSPropertyTextAlign, "right");
}
-static bool executeMakeTextWritingDirectionLeftToRight(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMakeTextWritingDirectionLeftToRight(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
style->setProperty(CSSPropertyDirection, CSSValueLtr);
frame.editor().applyStyle(style.get(), EditActionSetWritingDirection);
return true;
}
-static bool executeMakeTextWritingDirectionNatural(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMakeTextWritingDirectionNatural(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(CSSPropertyUnicodeBidi, CSSValueNormal);
frame.editor().applyStyle(style.get(), EditActionSetWritingDirection);
return true;
}
-static bool executeMakeTextWritingDirectionRightToLeft(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMakeTextWritingDirectionRightToLeft(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
style->setProperty(CSSPropertyDirection, CSSValueRtl);
frame.editor().applyStyle(style.get(), EditActionSetWritingDirection);
return true;
}
-static bool executeMoveBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
return true;
}
-static bool executeMoveBackwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveBackwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, CharacterGranularity, UserTriggered);
return true;
}
-static bool executeMoveDown(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveDown(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
return frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, LineGranularity, UserTriggered);
}
-static bool executeMoveDownAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveDownAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, LineGranularity, UserTriggered);
return true;
}
-static bool executeMoveForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity, UserTriggered);
return true;
}
-static bool executeMoveForwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveForwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity, UserTriggered);
return true;
}
-static bool executeMoveLeft(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveLeft(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
return frame.selection().modify(FrameSelection::AlterationMove, DirectionLeft, CharacterGranularity, UserTriggered);
}
-static bool executeMoveLeftAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveLeftAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, CharacterGranularity, UserTriggered);
return true;
}
-static bool executeMovePageDown(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMovePageDown(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
unsigned distance = verticalScrollDistance(frame);
if (!distance)
@@ -673,7 +674,7 @@ static bool executeMovePageDown(Frame& frame, Event*, EditorCommandSource, const
UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
}
-static bool executeMovePageDownAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMovePageDownAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
unsigned distance = verticalScrollDistance(frame);
if (!distance)
@@ -682,7 +683,7 @@ static bool executeMovePageDownAndModifySelection(Frame& frame, Event*, EditorCo
UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
}
-static bool executeMovePageUp(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMovePageUp(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
unsigned distance = verticalScrollDistance(frame);
if (!distance)
@@ -691,7 +692,7 @@ static bool executeMovePageUp(Frame& frame, Event*, EditorCommandSource, const S
UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
}
-static bool executeMovePageUpAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMovePageUpAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
unsigned distance = verticalScrollDistance(frame);
if (!distance)
@@ -700,240 +701,240 @@ static bool executeMovePageUpAndModifySelection(Frame& frame, Event*, EditorComm
UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
}
-static bool executeMoveRight(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveRight(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
return frame.selection().modify(FrameSelection::AlterationMove, DirectionRight, CharacterGranularity, UserTriggered);
}
-static bool executeMoveRightAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveRightAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, CharacterGranularity, UserTriggered);
return true;
}
-static bool executeMoveToBeginningOfDocument(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfDocument(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, DocumentBoundary, UserTriggered);
return true;
}
-static bool executeMoveToBeginningOfDocumentAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfDocumentAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, DocumentBoundary, UserTriggered);
return true;
}
-static bool executeMoveToBeginningOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, LineBoundary, UserTriggered);
return true;
}
-static bool executeMoveToBeginningOfLineAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, LineBoundary, UserTriggered);
return true;
}
-static bool executeMoveToBeginningOfParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, ParagraphBoundary, UserTriggered);
return true;
}
-static bool executeMoveToBeginningOfParagraphAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfParagraphAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, ParagraphBoundary, UserTriggered);
return true;
}
-static bool executeMoveToBeginningOfSentence(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfSentence(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, SentenceBoundary, UserTriggered);
return true;
}
-static bool executeMoveToBeginningOfSentenceAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfSentenceAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, SentenceBoundary, UserTriggered);
return true;
}
-static bool executeMoveToEndOfDocument(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfDocument(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, DocumentBoundary, UserTriggered);
return true;
}
-static bool executeMoveToEndOfDocumentAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfDocumentAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, DocumentBoundary, UserTriggered);
return true;
}
-static bool executeMoveToEndOfSentence(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfSentence(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, SentenceBoundary, UserTriggered);
return true;
}
-static bool executeMoveToEndOfSentenceAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfSentenceAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, SentenceBoundary, UserTriggered);
return true;
}
-static bool executeMoveToEndOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, LineBoundary, UserTriggered);
return true;
}
-static bool executeMoveToEndOfLineAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, LineBoundary, UserTriggered);
return true;
}
-static bool executeMoveToEndOfParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, ParagraphBoundary, UserTriggered);
return true;
}
-static bool executeMoveToEndOfParagraphAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfParagraphAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, ParagraphBoundary, UserTriggered);
return true;
}
-static bool executeMoveParagraphBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveParagraphBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, ParagraphGranularity, UserTriggered);
return true;
}
-static bool executeMoveParagraphBackwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveParagraphBackwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, ParagraphGranularity, UserTriggered);
return true;
}
-static bool executeMoveParagraphForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveParagraphForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, ParagraphGranularity, UserTriggered);
return true;
}
-static bool executeMoveParagraphForwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveParagraphForwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, ParagraphGranularity, UserTriggered);
return true;
}
-static bool executeMoveUp(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveUp(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
return frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, LineGranularity, UserTriggered);
}
-static bool executeMoveUpAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveUpAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, LineGranularity, UserTriggered);
return true;
}
-static bool executeMoveWordBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, WordGranularity, UserTriggered);
return true;
}
-static bool executeMoveWordBackwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordBackwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, WordGranularity, UserTriggered);
return true;
}
-static bool executeMoveWordForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, WordGranularity, UserTriggered);
return true;
}
-static bool executeMoveWordForwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordForwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, WordGranularity, UserTriggered);
return true;
}
-static bool executeMoveWordLeft(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordLeft(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionLeft, WordGranularity, UserTriggered);
return true;
}
-static bool executeMoveWordLeftAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordLeftAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, WordGranularity, UserTriggered);
return true;
}
-static bool executeMoveWordRight(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordRight(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionRight, WordGranularity, UserTriggered);
return true;
}
-static bool executeMoveWordRightAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordRightAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, WordGranularity, UserTriggered);
return true;
}
-static bool executeMoveToLeftEndOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToLeftEndOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionLeft, LineBoundary, UserTriggered);
return true;
}
-static bool executeMoveToLeftEndOfLineAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToLeftEndOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, LineBoundary, UserTriggered);
return true;
}
-static bool executeMoveToRightEndOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToRightEndOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationMove, DirectionRight, LineBoundary, UserTriggered);
return true;
}
-static bool executeMoveToRightEndOfLineAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToRightEndOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, LineBoundary, UserTriggered);
return true;
}
-static bool executeOutdent(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeOutdent(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
ASSERT(frame.document());
IndentOutdentCommand::create(*frame.document(), IndentOutdentCommand::Outdent)->apply();
return true;
}
-static bool executeToggleOverwrite(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeToggleOverwrite(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().toggleOverwriteModeEnabled();
return true;
}
-static bool executePaste(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executePaste(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().paste();
return true;
}
-static bool executePasteGlobalSelection(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executePasteGlobalSelection(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
if (!frame.editor().behavior().supportsGlobalSelection())
return false;
@@ -946,134 +947,134 @@ static bool executePasteGlobalSelection(Frame& frame, Event*, EditorCommandSourc
return true;
}
-static bool executePasteAndMatchStyle(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executePasteAndMatchStyle(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().pasteAsPlainText();
return true;
}
-static bool executePrint(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executePrint(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- Page* page = frame.page();
- if (!page)
+ FrameHost* host = frame.host();
+ if (!host)
return false;
- page->chrome().print(&frame);
+ host->chrome().print(&frame);
return true;
}
-static bool executeRedo(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeRedo(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().redo();
return true;
}
-static bool executeRemoveFormat(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeRemoveFormat(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().removeFormattingAndStyle();
return true;
}
-static bool executeScrollPageBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollPageBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- return frame.eventHandler().scrollRecursively(ScrollBlockDirectionBackward, ScrollByPage);
+ return frame.eventHandler().bubblingScroll(ScrollBlockDirectionBackward, ScrollByPage);
}
-static bool executeScrollPageForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollPageForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- return frame.eventHandler().scrollRecursively(ScrollBlockDirectionForward, ScrollByPage);
+ return frame.eventHandler().bubblingScroll(ScrollBlockDirectionForward, ScrollByPage);
}
-static bool executeScrollLineUp(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollLineUp(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- return frame.eventHandler().scrollRecursively(ScrollUp, ScrollByLine);
+ return frame.eventHandler().bubblingScroll(ScrollUp, ScrollByLine);
}
-static bool executeScrollLineDown(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollLineDown(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- return frame.eventHandler().scrollRecursively(ScrollDown, ScrollByLine);
+ return frame.eventHandler().bubblingScroll(ScrollDown, ScrollByLine);
}
-static bool executeScrollToBeginningOfDocument(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollToBeginningOfDocument(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- return frame.eventHandler().scrollRecursively(ScrollBlockDirectionBackward, ScrollByDocument);
+ return frame.eventHandler().bubblingScroll(ScrollBlockDirectionBackward, ScrollByDocument);
}
-static bool executeScrollToEndOfDocument(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollToEndOfDocument(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- return frame.eventHandler().scrollRecursively(ScrollBlockDirectionForward, ScrollByDocument);
+ return frame.eventHandler().bubblingScroll(ScrollBlockDirectionForward, ScrollByDocument);
}
-static bool executeSelectAll(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectAll(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().selectAll();
return true;
}
-static bool executeSelectLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
return expandSelectionToGranularity(frame, LineGranularity);
}
-static bool executeSelectParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
return expandSelectionToGranularity(frame, ParagraphGranularity);
}
-static bool executeSelectSentence(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectSentence(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
return expandSelectionToGranularity(frame, SentenceGranularity);
}
-static bool executeSelectToMark(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectToMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
- RefPtr<Range> mark = frame.editor().mark().toNormalizedRange();
- RefPtr<Range> selection = frame.editor().selectedRange();
+ RefPtrWillBeRawPtr<Range> mark = frame.editor().mark().toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> selection = frame.editor().selectedRange();
if (!mark || !selection)
return false;
- frame.selection().setSelectedRange(unionDOMRanges(mark.get(), selection.get()).get(), DOWNSTREAM, true);
+ frame.selection().setSelectedRange(unionDOMRanges(mark.get(), selection.get()).get(), DOWNSTREAM, FrameSelection::NonDirectional, FrameSelection::CloseTyping);
return true;
}
-static bool executeSelectWord(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectWord(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
return expandSelectionToGranularity(frame, WordGranularity);
}
-static bool executeSetMark(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSetMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().setMark(frame.selection().selection());
return true;
}
-static bool executeStrikethrough(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeStrikethrough(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
- RefPtr<CSSPrimitiveValue> lineThrough = CSSPrimitiveValue::createIdentifier(CSSValueLineThrough);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> lineThrough = CSSPrimitiveValue::createIdentifier(CSSValueLineThrough);
return executeToggleStyleInList(frame, source, EditActionUnderline, CSSPropertyWebkitTextDecorationsInEffect, lineThrough.get());
}
-static bool executeStyleWithCSS(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeStyleWithCSS(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
frame.editor().setShouldStyleWithCSS(!equalIgnoringCase(value, "false"));
return true;
}
-static bool executeUseCSS(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeUseCSS(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
{
frame.editor().setShouldStyleWithCSS(equalIgnoringCase(value, "false"));
return true;
}
-static bool executeSubscript(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeSubscript(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeToggleStyle(frame, source, EditActionSubscript, CSSPropertyVerticalAlign, "baseline", "sub");
}
-static bool executeSuperscript(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeSuperscript(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeToggleStyle(frame, source, EditActionSuperscript, CSSPropertyVerticalAlign, "baseline", "super");
}
-static bool executeSwapWithMark(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSwapWithMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
const VisibleSelection& mark = frame.editor().mark();
const VisibleSelection& selection = frame.selection().selection();
@@ -1084,60 +1085,60 @@ static bool executeSwapWithMark(Frame& frame, Event*, EditorCommandSource, const
return true;
}
-static bool executeToggleBold(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeToggleBold(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeToggleStyle(frame, source, EditActionBold, CSSPropertyFontWeight, "normal", "bold");
}
-static bool executeToggleItalic(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeToggleItalic(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeToggleStyle(frame, source, EditActionItalics, CSSPropertyFontStyle, "normal", "italic");
}
-static bool executeTranspose(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeTranspose(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().transpose();
return true;
}
-static bool executeUnderline(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeUnderline(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
- RefPtr<CSSPrimitiveValue> underline = CSSPrimitiveValue::createIdentifier(CSSValueUnderline);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> underline = CSSPrimitiveValue::createIdentifier(CSSValueUnderline);
return executeToggleStyleInList(frame, source, EditActionUnderline, CSSPropertyWebkitTextDecorationsInEffect, underline.get());
}
-static bool executeUndo(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeUndo(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().undo();
return true;
}
-static bool executeUnlink(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeUnlink(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
ASSERT(frame.document());
UnlinkCommand::create(*frame.document())->apply();
return true;
}
-static bool executeUnscript(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeUnscript(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
{
return executeApplyStyle(frame, source, EditActionUnscript, CSSPropertyVerticalAlign, "baseline");
}
-static bool executeUnselect(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeUnselect(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.selection().clear();
return true;
}
-static bool executeYank(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeYank(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().insertTextWithoutSendingTextEvent(frame.editor().killRing().yank(), false, 0);
frame.editor().killRing().setToYankedState();
return true;
}
-static bool executeYankAndSelect(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeYankAndSelect(LocalFrame& frame, Event*, EditorCommandSource, const String&)
{
frame.editor().insertTextWithoutSendingTextEvent(frame.editor().killRing().yank(), true, 0);
frame.editor().killRing().setToYankedState();
@@ -1146,17 +1147,17 @@ static bool executeYankAndSelect(Frame& frame, Event*, EditorCommandSource, cons
// Supported functions
-static bool supported(Frame*)
+static bool supported(LocalFrame*)
{
return true;
}
-static bool supportedFromMenuOrKeyBinding(Frame*)
+static bool supportedFromMenuOrKeyBinding(LocalFrame*)
{
return false;
}
-static bool supportedCopyCut(Frame* frame)
+static bool supportedCopyCut(LocalFrame* frame)
{
if (!frame)
return false;
@@ -1166,7 +1167,7 @@ static bool supportedCopyCut(Frame* frame)
return frame->editor().client().canCopyCut(frame, defaultValue);
}
-static bool supportedPaste(Frame* frame)
+static bool supportedPaste(LocalFrame* frame)
{
if (!frame)
return false;
@@ -1178,60 +1179,60 @@ static bool supportedPaste(Frame* frame)
// Enabled functions
-static bool enabled(Frame&, Event*, EditorCommandSource)
+static bool enabled(LocalFrame&, Event*, EditorCommandSource)
{
return true;
}
-static bool enabledVisibleSelection(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledVisibleSelection(LocalFrame& frame, Event* event, EditorCommandSource)
{
// The term "visible" here includes a caret in editable text or a range in any text.
const VisibleSelection& selection = frame.editor().selectionForCommand(event);
return (selection.isCaret() && selection.isContentEditable()) || selection.isRange();
}
-static bool caretBrowsingEnabled(Frame& frame)
+static bool caretBrowsingEnabled(LocalFrame& frame)
{
return frame.settings() && frame.settings()->caretBrowsingEnabled();
}
static EditorCommandSource dummyEditorCommandSource = static_cast<EditorCommandSource>(0);
-static bool enabledVisibleSelectionOrCaretBrowsing(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledVisibleSelectionOrCaretBrowsing(LocalFrame& frame, Event* event, EditorCommandSource)
{
// The EditorCommandSource parameter is unused in enabledVisibleSelection, so just pass a dummy variable
return caretBrowsingEnabled(frame) || enabledVisibleSelection(frame, event, dummyEditorCommandSource);
}
-static bool enabledVisibleSelectionAndMark(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledVisibleSelectionAndMark(LocalFrame& frame, Event* event, EditorCommandSource)
{
const VisibleSelection& selection = frame.editor().selectionForCommand(event);
return ((selection.isCaret() && selection.isContentEditable()) || selection.isRange())
&& frame.editor().mark().isCaretOrRange();
}
-static bool enableCaretInEditableText(Frame& frame, Event* event, EditorCommandSource)
+static bool enableCaretInEditableText(LocalFrame& frame, Event* event, EditorCommandSource)
{
const VisibleSelection& selection = frame.editor().selectionForCommand(event);
return selection.isCaret() && selection.isContentEditable();
}
-static bool enabledCopy(Frame& frame, Event*, EditorCommandSource)
+static bool enabledCopy(LocalFrame& frame, Event*, EditorCommandSource)
{
return frame.editor().canDHTMLCopy() || frame.editor().canCopy();
}
-static bool enabledCut(Frame& frame, Event*, EditorCommandSource)
+static bool enabledCut(LocalFrame& frame, Event*, EditorCommandSource)
{
return frame.editor().canDHTMLCut() || frame.editor().canCut();
}
-static bool enabledInEditableText(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledInEditableText(LocalFrame& frame, Event* event, EditorCommandSource)
{
return frame.editor().selectionForCommand(event).rootEditableElement();
}
-static bool enabledDelete(Frame& frame, Event* event, EditorCommandSource source)
+static bool enabledDelete(LocalFrame& frame, Event* event, EditorCommandSource source)
{
switch (source) {
case CommandFromMenuOrKeyBinding:
@@ -1246,142 +1247,142 @@ static bool enabledDelete(Frame& frame, Event* event, EditorCommandSource source
return false;
}
-static bool enabledInEditableTextOrCaretBrowsing(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledInEditableTextOrCaretBrowsing(LocalFrame& frame, Event* event, EditorCommandSource)
{
// The EditorCommandSource parameter is unused in enabledInEditableText, so just pass a dummy variable
return caretBrowsingEnabled(frame) || enabledInEditableText(frame, event, dummyEditorCommandSource);
}
-static bool enabledInRichlyEditableText(Frame& frame, Event*, EditorCommandSource)
+static bool enabledInRichlyEditableText(LocalFrame& frame, Event*, EditorCommandSource)
{
return frame.selection().isCaretOrRange() && frame.selection().isContentRichlyEditable() && frame.selection().rootEditableElement();
}
-static bool enabledPaste(Frame& frame, Event*, EditorCommandSource)
+static bool enabledPaste(LocalFrame& frame, Event*, EditorCommandSource)
{
return frame.editor().canPaste();
}
-static bool enabledRangeInEditableText(Frame& frame, Event*, EditorCommandSource)
+static bool enabledRangeInEditableText(LocalFrame& frame, Event*, EditorCommandSource)
{
return frame.selection().isRange() && frame.selection().isContentEditable();
}
-static bool enabledRangeInRichlyEditableText(Frame& frame, Event*, EditorCommandSource)
+static bool enabledRangeInRichlyEditableText(LocalFrame& frame, Event*, EditorCommandSource)
{
return frame.selection().isRange() && frame.selection().isContentRichlyEditable();
}
-static bool enabledRedo(Frame& frame, Event*, EditorCommandSource)
+static bool enabledRedo(LocalFrame& frame, Event*, EditorCommandSource)
{
return frame.editor().canRedo();
}
-static bool enabledUndo(Frame& frame, Event*, EditorCommandSource)
+static bool enabledUndo(LocalFrame& frame, Event*, EditorCommandSource)
{
return frame.editor().canUndo();
}
// State functions
-static TriState stateNone(Frame&, Event*)
+static TriState stateNone(LocalFrame&, Event*)
{
return FalseTriState;
}
-static TriState stateBold(Frame& frame, Event*)
+static TriState stateBold(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyFontWeight, "bold");
}
-static TriState stateItalic(Frame& frame, Event*)
+static TriState stateItalic(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyFontStyle, "italic");
}
-static TriState stateOrderedList(Frame& frame, Event*)
+static TriState stateOrderedList(LocalFrame& frame, Event*)
{
return frame.editor().selectionOrderedListState();
}
-static TriState stateStrikethrough(Frame& frame, Event*)
+static TriState stateStrikethrough(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyWebkitTextDecorationsInEffect, "line-through");
}
-static TriState stateStyleWithCSS(Frame& frame, Event*)
+static TriState stateStyleWithCSS(LocalFrame& frame, Event*)
{
return frame.editor().shouldStyleWithCSS() ? TrueTriState : FalseTriState;
}
-static TriState stateSubscript(Frame& frame, Event*)
+static TriState stateSubscript(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyVerticalAlign, "sub");
}
-static TriState stateSuperscript(Frame& frame, Event*)
+static TriState stateSuperscript(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyVerticalAlign, "super");
}
-static TriState stateTextWritingDirectionLeftToRight(Frame& frame, Event*)
+static TriState stateTextWritingDirectionLeftToRight(LocalFrame& frame, Event*)
{
return stateTextWritingDirection(frame, LeftToRightWritingDirection);
}
-static TriState stateTextWritingDirectionNatural(Frame& frame, Event*)
+static TriState stateTextWritingDirectionNatural(LocalFrame& frame, Event*)
{
return stateTextWritingDirection(frame, NaturalWritingDirection);
}
-static TriState stateTextWritingDirectionRightToLeft(Frame& frame, Event*)
+static TriState stateTextWritingDirectionRightToLeft(LocalFrame& frame, Event*)
{
return stateTextWritingDirection(frame, RightToLeftWritingDirection);
}
-static TriState stateUnderline(Frame& frame, Event*)
+static TriState stateUnderline(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyWebkitTextDecorationsInEffect, "underline");
}
-static TriState stateUnorderedList(Frame& frame, Event*)
+static TriState stateUnorderedList(LocalFrame& frame, Event*)
{
return frame.editor().selectionUnorderedListState();
}
-static TriState stateJustifyCenter(Frame& frame, Event*)
+static TriState stateJustifyCenter(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyTextAlign, "center");
}
-static TriState stateJustifyFull(Frame& frame, Event*)
+static TriState stateJustifyFull(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyTextAlign, "justify");
}
-static TriState stateJustifyLeft(Frame& frame, Event*)
+static TriState stateJustifyLeft(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyTextAlign, "left");
}
-static TriState stateJustifyRight(Frame& frame, Event*)
+static TriState stateJustifyRight(LocalFrame& frame, Event*)
{
return stateStyle(frame, CSSPropertyTextAlign, "right");
}
// Value functions
-static String valueNull(Frame&, Event*)
+static String valueNull(LocalFrame&, Event*)
{
return String();
}
-static String valueBackColor(Frame& frame, Event*)
+static String valueBackColor(LocalFrame& frame, Event*)
{
return valueStyle(frame, CSSPropertyBackgroundColor);
}
-static String valueDefaultParagraphSeparator(Frame& frame, Event*)
+static String valueDefaultParagraphSeparator(LocalFrame& frame, Event*)
{
switch (frame.editor().defaultParagraphSeparator()) {
case EditorParagraphSeparatorIsDiv:
@@ -1394,27 +1395,27 @@ static String valueDefaultParagraphSeparator(Frame& frame, Event*)
return String();
}
-static String valueFontName(Frame& frame, Event*)
+static String valueFontName(LocalFrame& frame, Event*)
{
return valueStyle(frame, CSSPropertyFontFamily);
}
-static String valueFontSize(Frame& frame, Event*)
+static String valueFontSize(LocalFrame& frame, Event*)
{
return valueStyle(frame, CSSPropertyFontSize);
}
-static String valueFontSizeDelta(Frame& frame, Event*)
+static String valueFontSizeDelta(LocalFrame& frame, Event*)
{
return valueStyle(frame, CSSPropertyWebkitFontSizeDelta);
}
-static String valueForeColor(Frame& frame, Event*)
+static String valueForeColor(LocalFrame& frame, Event*)
{
return valueStyle(frame, CSSPropertyColor);
}
-static String valueFormatBlock(Frame& frame, Event*)
+static String valueFormatBlock(LocalFrame& frame, Event*)
{
const VisibleSelection& selection = frame.selection().selection();
if (!selection.isNonOrphanedCaretOrRange() || !selection.isContentEditable())
@@ -1434,146 +1435,148 @@ struct CommandEntry {
static const CommandMap& createCommandMap()
{
+ // If you add new commands, you should assign new Id to each idForUserMetrics and update MappedEditingCommands
+ // in chrome/trunk/src/tools/metrics/histograms/histograms.xml.
static const CommandEntry commands[] = {
- { "AlignCenter", { executeJustifyCenter, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "AlignJustified", { executeJustifyFull, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "AlignLeft", { executeJustifyLeft, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "AlignRight", { executeJustifyRight, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "BackColor", { executeBackColor, supported, enabledInRichlyEditableText, stateNone, valueBackColor, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "BackwardDelete", { executeDeleteBackward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } }, // FIXME: remove BackwardDelete when Safari for Windows stops using it.
- { "Bold", { executeToggleBold, supported, enabledInRichlyEditableText, stateBold, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Copy", { executeCopy, supportedCopyCut, enabledCopy, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
- { "CreateLink", { executeCreateLink, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Cut", { executeCut, supportedCopyCut, enabledCut, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
- { "DefaultParagraphSeparator", { executeDefaultParagraphSeparator, supported, enabled, stateNone, valueDefaultParagraphSeparator, notTextInsertion, doNotAllowExecutionWhenDisabled} },
- { "Delete", { executeDelete, supported, enabledDelete, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteBackward", { executeDeleteBackward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteBackwardByDecomposingPreviousCharacter", { executeDeleteBackwardByDecomposingPreviousCharacter, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteForward", { executeDeleteForward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteToBeginningOfLine", { executeDeleteToBeginningOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteToBeginningOfParagraph", { executeDeleteToBeginningOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteToEndOfLine", { executeDeleteToEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteToEndOfParagraph", { executeDeleteToEndOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteToMark", { executeDeleteToMark, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteWordBackward", { executeDeleteWordBackward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "DeleteWordForward", { executeDeleteWordForward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "FindString", { executeFindString, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "FontName", { executeFontName, supported, enabledInEditableText, stateNone, valueFontName, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "FontSize", { executeFontSize, supported, enabledInEditableText, stateNone, valueFontSize, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "FontSizeDelta", { executeFontSizeDelta, supported, enabledInEditableText, stateNone, valueFontSizeDelta, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ForeColor", { executeForeColor, supported, enabledInRichlyEditableText, stateNone, valueForeColor, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "FormatBlock", { executeFormatBlock, supported, enabledInRichlyEditableText, stateNone, valueFormatBlock, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ForwardDelete", { executeForwardDelete, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "HiliteColor", { executeBackColor, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "IgnoreSpelling", { executeIgnoreSpelling, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Indent", { executeIndent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertBacktab", { executeInsertBacktab, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertHTML", { executeInsertHTML, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertHorizontalRule", { executeInsertHorizontalRule, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertImage", { executeInsertImage, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertLineBreak", { executeInsertLineBreak, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertNewline", { executeInsertNewline, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertNewlineInQuotedContent", { executeInsertNewlineInQuotedContent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertOrderedList", { executeInsertOrderedList, supported, enabledInRichlyEditableText, stateOrderedList, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertParagraph", { executeInsertParagraph, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertTab", { executeInsertTab, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertText", { executeInsertText, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "InsertUnorderedList", { executeInsertUnorderedList, supported, enabledInRichlyEditableText, stateUnorderedList, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Italic", { executeToggleItalic, supported, enabledInRichlyEditableText, stateItalic, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "JustifyCenter", { executeJustifyCenter, supported, enabledInRichlyEditableText, stateJustifyCenter, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "JustifyFull", { executeJustifyFull, supported, enabledInRichlyEditableText, stateJustifyFull, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "JustifyLeft", { executeJustifyLeft, supported, enabledInRichlyEditableText, stateJustifyLeft, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "JustifyNone", { executeJustifyLeft, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "JustifyRight", { executeJustifyRight, supported, enabledInRichlyEditableText, stateJustifyRight, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MakeTextWritingDirectionLeftToRight", { executeMakeTextWritingDirectionLeftToRight, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateTextWritingDirectionLeftToRight, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MakeTextWritingDirectionNatural", { executeMakeTextWritingDirectionNatural, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateTextWritingDirectionNatural, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MakeTextWritingDirectionRightToLeft", { executeMakeTextWritingDirectionRightToLeft, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateTextWritingDirectionRightToLeft, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveBackward", { executeMoveBackward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveBackwardAndModifySelection", { executeMoveBackwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveDown", { executeMoveDown, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveDownAndModifySelection", { executeMoveDownAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveForward", { executeMoveForward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveForwardAndModifySelection", { executeMoveForwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveLeft", { executeMoveLeft, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveLeftAndModifySelection", { executeMoveLeftAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MovePageDown", { executeMovePageDown, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MovePageDownAndModifySelection", { executeMovePageDownAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MovePageUp", { executeMovePageUp, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MovePageUpAndModifySelection", { executeMovePageUpAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveParagraphBackward", { executeMoveParagraphBackward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveParagraphBackwardAndModifySelection", { executeMoveParagraphBackwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveParagraphForward", { executeMoveParagraphForward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveParagraphForwardAndModifySelection", { executeMoveParagraphForwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveRight", { executeMoveRight, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveRightAndModifySelection", { executeMoveRightAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToBeginningOfDocument", { executeMoveToBeginningOfDocument, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToBeginningOfDocumentAndModifySelection", { executeMoveToBeginningOfDocumentAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToBeginningOfLine", { executeMoveToBeginningOfLine, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToBeginningOfLineAndModifySelection", { executeMoveToBeginningOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToBeginningOfParagraph", { executeMoveToBeginningOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToBeginningOfParagraphAndModifySelection", { executeMoveToBeginningOfParagraphAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToBeginningOfSentence", { executeMoveToBeginningOfSentence, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToBeginningOfSentenceAndModifySelection", { executeMoveToBeginningOfSentenceAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToEndOfDocument", { executeMoveToEndOfDocument, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToEndOfDocumentAndModifySelection", { executeMoveToEndOfDocumentAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToEndOfLine", { executeMoveToEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToEndOfLineAndModifySelection", { executeMoveToEndOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToEndOfParagraph", { executeMoveToEndOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToEndOfParagraphAndModifySelection", { executeMoveToEndOfParagraphAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToEndOfSentence", { executeMoveToEndOfSentence, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToEndOfSentenceAndModifySelection", { executeMoveToEndOfSentenceAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToLeftEndOfLine", { executeMoveToLeftEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToLeftEndOfLineAndModifySelection", { executeMoveToLeftEndOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToRightEndOfLine", { executeMoveToRightEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveToRightEndOfLineAndModifySelection", { executeMoveToRightEndOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveUp", { executeMoveUp, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveUpAndModifySelection", { executeMoveUpAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveWordBackward", { executeMoveWordBackward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveWordBackwardAndModifySelection", { executeMoveWordBackwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveWordForward", { executeMoveWordForward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveWordForwardAndModifySelection", { executeMoveWordForwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveWordLeft", { executeMoveWordLeft, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveWordLeftAndModifySelection", { executeMoveWordLeftAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveWordRight", { executeMoveWordRight, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "MoveWordRightAndModifySelection", { executeMoveWordRightAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Outdent", { executeOutdent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "OverWrite", { executeToggleOverwrite, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Paste", { executePaste, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
- { "PasteAndMatchStyle", { executePasteAndMatchStyle, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
- { "PasteGlobalSelection", { executePasteGlobalSelection, supportedFromMenuOrKeyBinding, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
- { "Print", { executePrint, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Redo", { executeRedo, supported, enabledRedo, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "RemoveFormat", { executeRemoveFormat, supported, enabledRangeInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ScrollPageBackward", { executeScrollPageBackward, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ScrollPageForward", { executeScrollPageForward, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ScrollLineUp", { executeScrollLineUp, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ScrollLineDown", { executeScrollLineDown, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ScrollToBeginningOfDocument", { executeScrollToBeginningOfDocument, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ScrollToEndOfDocument", { executeScrollToEndOfDocument, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "SelectAll", { executeSelectAll, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "SelectLine", { executeSelectLine, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "SelectParagraph", { executeSelectParagraph, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "SelectSentence", { executeSelectSentence, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "SelectToMark", { executeSelectToMark, supportedFromMenuOrKeyBinding, enabledVisibleSelectionAndMark, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "SelectWord", { executeSelectWord, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "SetMark", { executeSetMark, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Strikethrough", { executeStrikethrough, supported, enabledInRichlyEditableText, stateStrikethrough, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "StyleWithCSS", { executeStyleWithCSS, supported, enabled, stateStyleWithCSS, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Subscript", { executeSubscript, supported, enabledInRichlyEditableText, stateSubscript, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Superscript", { executeSuperscript, supported, enabledInRichlyEditableText, stateSuperscript, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "SwapWithMark", { executeSwapWithMark, supportedFromMenuOrKeyBinding, enabledVisibleSelectionAndMark, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ToggleBold", { executeToggleBold, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateBold, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ToggleItalic", { executeToggleItalic, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateItalic, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "ToggleUnderline", { executeUnderline, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateUnderline, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Transpose", { executeTranspose, supported, enableCaretInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Underline", { executeUnderline, supported, enabledInRichlyEditableText, stateUnderline, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Undo", { executeUndo, supported, enabledUndo, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Unlink", { executeUnlink, supported, enabledRangeInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Unscript", { executeUnscript, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Unselect", { executeUnselect, supported, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "UseCSS", { executeUseCSS, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "Yank", { executeYank, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
- { "YankAndSelect", { executeYankAndSelect, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "AlignCenter", {139, executeJustifyCenter, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "AlignJustified", {1, executeJustifyFull, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "AlignLeft", {2, executeJustifyLeft, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "AlignRight", {3, executeJustifyRight, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "BackColor", {4, executeBackColor, supported, enabledInRichlyEditableText, stateNone, valueBackColor, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "BackwardDelete", {5, executeDeleteBackward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } }, // FIXME: remove BackwardDelete when Safari for Windows stops using it.
+ { "Bold", {6, executeToggleBold, supported, enabledInRichlyEditableText, stateBold, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Copy", {7, executeCopy, supportedCopyCut, enabledCopy, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
+ { "CreateLink", {8, executeCreateLink, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Cut", {9, executeCut, supportedCopyCut, enabledCut, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
+ { "DefaultParagraphSeparator", {10, executeDefaultParagraphSeparator, supported, enabled, stateNone, valueDefaultParagraphSeparator, notTextInsertion, doNotAllowExecutionWhenDisabled} },
+ { "Delete", {11, executeDelete, supported, enabledDelete, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteBackward", {12, executeDeleteBackward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteBackwardByDecomposingPreviousCharacter", {13, executeDeleteBackwardByDecomposingPreviousCharacter, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteForward", {14, executeDeleteForward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteToBeginningOfLine", {15, executeDeleteToBeginningOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteToBeginningOfParagraph", {16, executeDeleteToBeginningOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteToEndOfLine", {17, executeDeleteToEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteToEndOfParagraph", {18, executeDeleteToEndOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteToMark", {19, executeDeleteToMark, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteWordBackward", {20, executeDeleteWordBackward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "DeleteWordForward", {21, executeDeleteWordForward, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "FindString", {22, executeFindString, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "FontName", {23, executeFontName, supported, enabledInEditableText, stateNone, valueFontName, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "FontSize", {24, executeFontSize, supported, enabledInEditableText, stateNone, valueFontSize, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "FontSizeDelta", {25, executeFontSizeDelta, supported, enabledInEditableText, stateNone, valueFontSizeDelta, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ForeColor", {26, executeForeColor, supported, enabledInRichlyEditableText, stateNone, valueForeColor, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "FormatBlock", {27, executeFormatBlock, supported, enabledInRichlyEditableText, stateNone, valueFormatBlock, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ForwardDelete", {28, executeForwardDelete, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "HiliteColor", {29, executeBackColor, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "IgnoreSpelling", {30, executeIgnoreSpelling, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Indent", {31, executeIndent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertBacktab", {32, executeInsertBacktab, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertHTML", {33, executeInsertHTML, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertHorizontalRule", {34, executeInsertHorizontalRule, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertImage", {35, executeInsertImage, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertLineBreak", {36, executeInsertLineBreak, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertNewline", {37, executeInsertNewline, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertNewlineInQuotedContent", {38, executeInsertNewlineInQuotedContent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertOrderedList", {39, executeInsertOrderedList, supported, enabledInRichlyEditableText, stateOrderedList, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertParagraph", {40, executeInsertParagraph, supported, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertTab", {41, executeInsertTab, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertText", {42, executeInsertText, supported, enabledInEditableText, stateNone, valueNull, isTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "InsertUnorderedList", {43, executeInsertUnorderedList, supported, enabledInRichlyEditableText, stateUnorderedList, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Italic", {44, executeToggleItalic, supported, enabledInRichlyEditableText, stateItalic, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "JustifyCenter", {45, executeJustifyCenter, supported, enabledInRichlyEditableText, stateJustifyCenter, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "JustifyFull", {46, executeJustifyFull, supported, enabledInRichlyEditableText, stateJustifyFull, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "JustifyLeft", {47, executeJustifyLeft, supported, enabledInRichlyEditableText, stateJustifyLeft, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "JustifyNone", {48, executeJustifyLeft, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "JustifyRight", {49, executeJustifyRight, supported, enabledInRichlyEditableText, stateJustifyRight, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MakeTextWritingDirectionLeftToRight", {50, executeMakeTextWritingDirectionLeftToRight, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateTextWritingDirectionLeftToRight, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MakeTextWritingDirectionNatural", {51, executeMakeTextWritingDirectionNatural, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateTextWritingDirectionNatural, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MakeTextWritingDirectionRightToLeft", {52, executeMakeTextWritingDirectionRightToLeft, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateTextWritingDirectionRightToLeft, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveBackward", {53, executeMoveBackward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveBackwardAndModifySelection", {54, executeMoveBackwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveDown", {55, executeMoveDown, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveDownAndModifySelection", {56, executeMoveDownAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveForward", {57, executeMoveForward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveForwardAndModifySelection", {58, executeMoveForwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveLeft", {59, executeMoveLeft, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveLeftAndModifySelection", {60, executeMoveLeftAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MovePageDown", {61, executeMovePageDown, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MovePageDownAndModifySelection", {62, executeMovePageDownAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MovePageUp", {63, executeMovePageUp, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MovePageUpAndModifySelection", {64, executeMovePageUpAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveParagraphBackward", {65, executeMoveParagraphBackward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveParagraphBackwardAndModifySelection", {66, executeMoveParagraphBackwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveParagraphForward", {67, executeMoveParagraphForward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveParagraphForwardAndModifySelection", {68, executeMoveParagraphForwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveRight", {69, executeMoveRight, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveRightAndModifySelection", {70, executeMoveRightAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToBeginningOfDocument", {71, executeMoveToBeginningOfDocument, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToBeginningOfDocumentAndModifySelection", {72, executeMoveToBeginningOfDocumentAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToBeginningOfLine", {73, executeMoveToBeginningOfLine, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToBeginningOfLineAndModifySelection", {74, executeMoveToBeginningOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToBeginningOfParagraph", {75, executeMoveToBeginningOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToBeginningOfParagraphAndModifySelection", {76, executeMoveToBeginningOfParagraphAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToBeginningOfSentence", {77, executeMoveToBeginningOfSentence, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToBeginningOfSentenceAndModifySelection", {78, executeMoveToBeginningOfSentenceAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToEndOfDocument", {79, executeMoveToEndOfDocument, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToEndOfDocumentAndModifySelection", {80, executeMoveToEndOfDocumentAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToEndOfLine", {81, executeMoveToEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToEndOfLineAndModifySelection", {82, executeMoveToEndOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToEndOfParagraph", {83, executeMoveToEndOfParagraph, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToEndOfParagraphAndModifySelection", {84, executeMoveToEndOfParagraphAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToEndOfSentence", {85, executeMoveToEndOfSentence, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToEndOfSentenceAndModifySelection", {86, executeMoveToEndOfSentenceAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToLeftEndOfLine", {87, executeMoveToLeftEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToLeftEndOfLineAndModifySelection", {88, executeMoveToLeftEndOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToRightEndOfLine", {89, executeMoveToRightEndOfLine, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveToRightEndOfLineAndModifySelection", {90, executeMoveToRightEndOfLineAndModifySelection, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveUp", {91, executeMoveUp, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveUpAndModifySelection", {92, executeMoveUpAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveWordBackward", {93, executeMoveWordBackward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveWordBackwardAndModifySelection", {94, executeMoveWordBackwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveWordForward", {95, executeMoveWordForward, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveWordForwardAndModifySelection", {96, executeMoveWordForwardAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveWordLeft", {97, executeMoveWordLeft, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveWordLeftAndModifySelection", {98, executeMoveWordLeftAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveWordRight", {99, executeMoveWordRight, supportedFromMenuOrKeyBinding, enabledInEditableTextOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "MoveWordRightAndModifySelection", {100, executeMoveWordRightAndModifySelection, supportedFromMenuOrKeyBinding, enabledVisibleSelectionOrCaretBrowsing, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Outdent", {101, executeOutdent, supported, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "OverWrite", {102, executeToggleOverwrite, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Paste", {103, executePaste, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
+ { "PasteAndMatchStyle", {104, executePasteAndMatchStyle, supportedPaste, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
+ { "PasteGlobalSelection", {105, executePasteGlobalSelection, supportedFromMenuOrKeyBinding, enabledPaste, stateNone, valueNull, notTextInsertion, allowExecutionWhenDisabled } },
+ { "Print", {106, executePrint, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Redo", {107, executeRedo, supported, enabledRedo, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "RemoveFormat", {108, executeRemoveFormat, supported, enabledRangeInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ScrollPageBackward", {109, executeScrollPageBackward, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ScrollPageForward", {110, executeScrollPageForward, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ScrollLineUp", {111, executeScrollLineUp, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ScrollLineDown", {112, executeScrollLineDown, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ScrollToBeginningOfDocument", {113, executeScrollToBeginningOfDocument, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ScrollToEndOfDocument", {114, executeScrollToEndOfDocument, supportedFromMenuOrKeyBinding, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "SelectAll", {115, executeSelectAll, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "SelectLine", {116, executeSelectLine, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "SelectParagraph", {117, executeSelectParagraph, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "SelectSentence", {118, executeSelectSentence, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "SelectToMark", {119, executeSelectToMark, supportedFromMenuOrKeyBinding, enabledVisibleSelectionAndMark, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "SelectWord", {120, executeSelectWord, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "SetMark", {121, executeSetMark, supportedFromMenuOrKeyBinding, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Strikethrough", {122, executeStrikethrough, supported, enabledInRichlyEditableText, stateStrikethrough, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "StyleWithCSS", {123, executeStyleWithCSS, supported, enabled, stateStyleWithCSS, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Subscript", {124, executeSubscript, supported, enabledInRichlyEditableText, stateSubscript, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Superscript", {125, executeSuperscript, supported, enabledInRichlyEditableText, stateSuperscript, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "SwapWithMark", {126, executeSwapWithMark, supportedFromMenuOrKeyBinding, enabledVisibleSelectionAndMark, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ToggleBold", {127, executeToggleBold, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateBold, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ToggleItalic", {128, executeToggleItalic, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateItalic, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "ToggleUnderline", {129, executeUnderline, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateUnderline, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Transpose", {130, executeTranspose, supported, enableCaretInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Underline", {131, executeUnderline, supported, enabledInRichlyEditableText, stateUnderline, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Undo", {132, executeUndo, supported, enabledUndo, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Unlink", {133, executeUnlink, supported, enabledRangeInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Unscript", {134, executeUnscript, supportedFromMenuOrKeyBinding, enabledInRichlyEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Unselect", {135, executeUnselect, supported, enabledVisibleSelection, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "UseCSS", {136, executeUseCSS, supported, enabled, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "Yank", {137, executeYank, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
+ { "YankAndSelect", {138, executeYankAndSelect, supportedFromMenuOrKeyBinding, enabledInEditableText, stateNone, valueNull, notTextInsertion, doNotAllowExecutionWhenDisabled } },
};
// These unsupported commands are listed here since they appear in the Microsoft
@@ -1623,10 +1626,17 @@ static const CommandMap& createCommandMap()
// Unbookmark (not supported)
CommandMap& commandMap = *new CommandMap;
-
+#if ASSERT_ENABLED
+ HashSet<int> idSet;
+#endif
for (size_t i = 0; i < WTF_ARRAY_LENGTH(commands); ++i) {
- ASSERT(!commandMap.get(commands[i].name));
- commandMap.set(commands[i].name, &commands[i].command);
+ const CommandEntry& command = commands[i];
+ ASSERT(!commandMap.get(command.name));
+ commandMap.set(command.name, &command.command);
+#if ASSERT_ENABLED
+ ASSERT(!idSet.contains(command.command.idForUserMetrics));
+ idSet.add(command.command.idForUserMetrics);
+#endif
}
return commandMap;
@@ -1648,20 +1658,15 @@ Editor::Command Editor::command(const String& commandName, EditorCommandSource s
return Command(internalCommand(commandName), source, &m_frame);
}
-bool Editor::commandIsSupportedFromMenuOrKeyBinding(const String& commandName)
-{
- return internalCommand(commandName);
-}
-
Editor::Command::Command()
: m_command(0)
{
}
-Editor::Command::Command(const EditorInternalCommand* command, EditorCommandSource source, PassRefPtr<Frame> frame)
+Editor::Command::Command(const EditorInternalCommand* command, EditorCommandSource source, PassRefPtr<LocalFrame> frame)
: m_command(command)
, m_source(source)
- , m_frame(command ? frame : 0)
+ , m_frame(command ? frame : nullptr)
{
// Use separate assertions so we can tell which bad thing happened.
if (!command)
@@ -1678,6 +1683,7 @@ bool Editor::Command::execute(const String& parameter, Event* triggeringEvent) c
return false;
}
m_frame->document()->updateLayoutIgnorePendingStylesheets();
+ blink::Platform::current()->histogramSparse("WebCore.Editing.Commands", m_command->idForUserMetrics);
return m_command->execute(*m_frame, triggeringEvent, m_source, parameter);
}
@@ -1729,4 +1735,9 @@ bool Editor::Command::isTextInsertion() const
return m_command && m_command->isTextInsertion;
}
+int Editor::Command::idForHistogram() const
+{
+ return isSupported() ? m_command->idForUserMetrics : 0;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/EditorKeyBindings.cpp b/chromium/third_party/WebKit/Source/core/editing/EditorKeyBindings.cpp
index 3bd023f4faf..ee4fea4dee5 100644
--- a/chromium/third_party/WebKit/Source/core/editing/EditorKeyBindings.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/EditorKeyBindings.cpp
@@ -28,201 +28,12 @@
#include "core/editing/Editor.h"
#include "core/events/KeyboardEvent.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/EditorClient.h"
-#include "platform/KeyboardCodes.h"
#include "platform/PlatformKeyboardEvent.h"
namespace WebCore {
-//
-// The below code was adapted from the WebKit file webview.cpp
-//
-
-static const unsigned CtrlKey = 1 << 0;
-static const unsigned AltKey = 1 << 1;
-static const unsigned ShiftKey = 1 << 2;
-static const unsigned MetaKey = 1 << 3;
-#if OS(MACOSX)
-// Aliases for the generic key defintions to make kbd shortcuts definitions more
-// readable on OS X.
-static const unsigned OptionKey = AltKey;
-
-// Do not use this constant for anything but cursor movement commands. Keys
-// with cmd set have their |isSystemKey| bit set, so chances are the shortcut
-// will not be executed. Another, less important, reason is that shortcuts
-// defined in the renderer do not blink the menu item that they triggered. See
-// http://crbug.com/25856 and the bugs linked from there for details.
-static const unsigned CommandKey = MetaKey;
-#endif
-
-// Keys with special meaning. These will be delegated to the editor using
-// the execCommand() method
-struct KeyDownEntry {
- unsigned virtualKey;
- unsigned modifiers;
- const char* name;
-};
-
-struct KeyPressEntry {
- unsigned charCode;
- unsigned modifiers;
- const char* name;
-};
-
-// Key bindings with command key on Mac and alt key on other platforms are
-// marked as system key events and will be ignored (with the exception
-// of Command-B and Command-I) so they shouldn't be added here.
-static const KeyDownEntry keyDownEntries[] = {
- { VKEY_LEFT, 0, "MoveLeft" },
- { VKEY_LEFT, ShiftKey, "MoveLeftAndModifySelection" },
-#if OS(MACOSX)
- { VKEY_LEFT, OptionKey, "MoveWordLeft" },
- { VKEY_LEFT, OptionKey | ShiftKey,
- "MoveWordLeftAndModifySelection" },
-#else
- { VKEY_LEFT, CtrlKey, "MoveWordLeft" },
- { VKEY_LEFT, CtrlKey | ShiftKey,
- "MoveWordLeftAndModifySelection" },
-#endif
- { VKEY_RIGHT, 0, "MoveRight" },
- { VKEY_RIGHT, ShiftKey, "MoveRightAndModifySelection" },
-#if OS(MACOSX)
- { VKEY_RIGHT, OptionKey, "MoveWordRight" },
- { VKEY_RIGHT, OptionKey | ShiftKey, "MoveWordRightAndModifySelection" },
-#else
- { VKEY_RIGHT, CtrlKey, "MoveWordRight" },
- { VKEY_RIGHT, CtrlKey | ShiftKey, "MoveWordRightAndModifySelection" },
-#endif
- { VKEY_UP, 0, "MoveUp" },
- { VKEY_UP, ShiftKey, "MoveUpAndModifySelection" },
- { VKEY_PRIOR, ShiftKey, "MovePageUpAndModifySelection" },
- { VKEY_DOWN, 0, "MoveDown" },
- { VKEY_DOWN, ShiftKey, "MoveDownAndModifySelection" },
- { VKEY_NEXT, ShiftKey, "MovePageDownAndModifySelection" },
-#if !OS(MACOSX)
- { VKEY_UP, CtrlKey, "MoveParagraphBackward" },
- { VKEY_UP, CtrlKey | ShiftKey, "MoveParagraphBackwardAndModifySelection" },
- { VKEY_DOWN, CtrlKey, "MoveParagraphForward" },
- { VKEY_DOWN, CtrlKey | ShiftKey, "MoveParagraphForwardAndModifySelection" },
- { VKEY_PRIOR, 0, "MovePageUp" },
- { VKEY_NEXT, 0, "MovePageDown" },
-#endif
- { VKEY_HOME, 0, "MoveToBeginningOfLine" },
- { VKEY_HOME, ShiftKey,
- "MoveToBeginningOfLineAndModifySelection" },
-#if OS(MACOSX)
- { VKEY_PRIOR, OptionKey, "MovePageUp" },
- { VKEY_NEXT, OptionKey, "MovePageDown" },
-#endif
-#if !OS(MACOSX)
- { VKEY_HOME, CtrlKey, "MoveToBeginningOfDocument" },
- { VKEY_HOME, CtrlKey | ShiftKey,
- "MoveToBeginningOfDocumentAndModifySelection" },
-#endif
- { VKEY_END, 0, "MoveToEndOfLine" },
- { VKEY_END, ShiftKey, "MoveToEndOfLineAndModifySelection" },
-#if !OS(MACOSX)
- { VKEY_END, CtrlKey, "MoveToEndOfDocument" },
- { VKEY_END, CtrlKey | ShiftKey,
- "MoveToEndOfDocumentAndModifySelection" },
-#endif
- { VKEY_BACK, 0, "DeleteBackward" },
- { VKEY_BACK, ShiftKey, "DeleteBackward" },
- { VKEY_DELETE, 0, "DeleteForward" },
-#if OS(MACOSX)
- { VKEY_BACK, OptionKey, "DeleteWordBackward" },
- { VKEY_DELETE, OptionKey, "DeleteWordForward" },
-#else
- { VKEY_BACK, CtrlKey, "DeleteWordBackward" },
- { VKEY_DELETE, CtrlKey, "DeleteWordForward" },
-#endif
-#if OS(MACOSX)
- { 'B', CommandKey, "ToggleBold" },
- { 'I', CommandKey, "ToggleItalic" },
-#else
- { 'B', CtrlKey, "ToggleBold" },
- { 'I', CtrlKey, "ToggleItalic" },
-#endif
- { 'U', CtrlKey, "ToggleUnderline" },
- { VKEY_ESCAPE, 0, "Cancel" },
- { VKEY_OEM_PERIOD, CtrlKey, "Cancel" },
- { VKEY_TAB, 0, "InsertTab" },
- { VKEY_TAB, ShiftKey, "InsertBacktab" },
- { VKEY_RETURN, 0, "InsertNewline" },
- { VKEY_RETURN, CtrlKey, "InsertNewline" },
- { VKEY_RETURN, AltKey, "InsertNewline" },
- { VKEY_RETURN, AltKey | ShiftKey, "InsertNewline" },
- { VKEY_RETURN, ShiftKey, "InsertLineBreak" },
- { VKEY_INSERT, CtrlKey, "Copy" },
- { VKEY_INSERT, ShiftKey, "Paste" },
- { VKEY_DELETE, ShiftKey, "Cut" },
-#if !OS(MACOSX)
- // On OS X, we pipe these back to the browser, so that it can do menu item
- // blinking.
- { 'C', CtrlKey, "Copy" },
- { 'V', CtrlKey, "Paste" },
- { 'V', CtrlKey | ShiftKey, "PasteAndMatchStyle" },
- { 'X', CtrlKey, "Cut" },
- { 'A', CtrlKey, "SelectAll" },
- { 'Z', CtrlKey, "Undo" },
- { 'Z', CtrlKey | ShiftKey, "Redo" },
- { 'Y', CtrlKey, "Redo" },
-#endif
- { VKEY_INSERT, 0, "OverWrite" },
-};
-
-static const KeyPressEntry keyPressEntries[] = {
- { '\t', 0, "InsertTab" },
- { '\t', ShiftKey, "InsertBacktab" },
- { '\r', 0, "InsertNewline" },
- { '\r', CtrlKey, "InsertNewline" },
- { '\r', ShiftKey, "InsertLineBreak" },
- { '\r', AltKey, "InsertNewline" },
- { '\r', AltKey | ShiftKey, "InsertNewline" },
-};
-
-const char* Editor::interpretKeyEvent(const KeyboardEvent* evt)
-{
- const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
- if (!keyEvent)
- return "";
-
- static HashMap<int, const char*>* keyDownCommandsMap = 0;
- static HashMap<int, const char*>* keyPressCommandsMap = 0;
-
- if (!keyDownCommandsMap) {
- keyDownCommandsMap = new HashMap<int, const char*>;
- keyPressCommandsMap = new HashMap<int, const char*>;
-
- for (unsigned i = 0; i < arraysize(keyDownEntries); i++) {
- keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
- }
-
- for (unsigned i = 0; i < arraysize(keyPressEntries); i++) {
- keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
- }
- }
-
- unsigned modifiers = 0;
- if (keyEvent->shiftKey())
- modifiers |= ShiftKey;
- if (keyEvent->altKey())
- modifiers |= AltKey;
- if (keyEvent->ctrlKey())
- modifiers |= CtrlKey;
- if (keyEvent->metaKey())
- modifiers |= MetaKey;
-
- if (keyEvent->type() == PlatformEvent::RawKeyDown) {
- int mapKey = modifiers << 16 | evt->keyCode();
- return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
- }
-
- int mapKey = modifiers << 16 | evt->charCode();
- return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
-}
-
bool Editor::handleEditingKeyboardEvent(KeyboardEvent* evt)
{
const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
@@ -230,7 +41,7 @@ bool Editor::handleEditingKeyboardEvent(KeyboardEvent* evt)
if (!keyEvent || keyEvent->isSystemKey())
return false;
- String commandName = interpretKeyEvent(evt);
+ String commandName = behavior().interpretKeyEvent(*evt);
Command command = this->command(commandName);
if (keyEvent->type() == PlatformEvent::RawKeyDown) {
@@ -241,57 +52,13 @@ bool Editor::handleEditingKeyboardEvent(KeyboardEvent* evt)
// (e.g. Tab that inserts a Tab character, or Enter).
if (command.isTextInsertion() || commandName.isEmpty())
return false;
- if (command.execute(evt)) {
- client().didExecuteCommand(commandName);
- return true;
- }
- return false;
+ return command.execute(evt);
}
- if (command.execute(evt)) {
- client().didExecuteCommand(commandName);
+ if (command.execute(evt))
return true;
- }
-
- // Here we need to filter key events.
- // On Gtk/Linux, it emits key events with ASCII text and ctrl on for ctrl-<x>.
- // In Webkit, EditorClient::handleKeyboardEvent in
- // WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp drop such events.
- // On Mac, it emits key events with ASCII text and meta on for Command-<x>.
- // These key events should not emit text insert event.
- // Alt key would be used to insert alternative character, so we should let
- // through. Also note that Ctrl-Alt combination equals to AltGr key which is
- // also used to insert alternative character.
- // http://code.google.com/p/chromium/issues/detail?id=10846
- // Windows sets both alt and meta are on when "Alt" key pressed.
- // http://code.google.com/p/chromium/issues/detail?id=2215
- // Also, we should not rely on an assumption that keyboards don't
- // send ASCII characters when pressing a control key on Windows,
- // which may be configured to do it so by user.
- // See also http://en.wikipedia.org/wiki/Keyboard_Layout
- // FIXME(ukai): investigate more detail for various keyboard layout.
- if (evt->keyEvent()->text().length() == 1) {
- UChar ch = evt->keyEvent()->text()[0U];
-
- // Don't insert null or control characters as they can result in
- // unexpected behaviour
- if (ch < ' ')
- return false;
-#if !OS(WIN)
- // Don't insert ASCII character if ctrl w/o alt or meta is on.
- // On Mac, we should ignore events when meta is on (Command-<x>).
- if (ch < 0x80) {
- if (evt->keyEvent()->ctrlKey() && !evt->keyEvent()->altKey())
- return false;
-#if OS(MACOSX)
- if (evt->keyEvent()->metaKey())
- return false;
-#endif
- }
-#endif
- }
- if (!canEdit())
+ if (!behavior().shouldInsertCharacter(*evt) || !canEdit())
return false;
return insertText(evt->keyEvent()->text(), evt);
diff --git a/chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.cpp
index 57b9634a83a..2cfdd38cc21 100644
--- a/chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.cpp
@@ -24,8 +24,8 @@
*/
#include "config.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/Range.h"
@@ -59,21 +59,21 @@ void FormatBlockCommand::formatSelection(const VisiblePosition& startOfSelection
m_didApply = true;
}
-void FormatBlockCommand::formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtr<Element>& blockNode)
+void FormatBlockCommand::formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtrWillBeRawPtr<Element>& blockNode)
{
- Element* refNode = enclosingBlockFlowElement(end);
+ Element* refNode = enclosingBlockFlowElement(VisiblePosition(end));
Element* root = editableRootForPosition(start);
// Root is null for elements with contenteditable=false.
if (!root || !refNode)
return;
Node* nodeToSplitTo = enclosingBlockToSplitTreeTo(start.deprecatedNode());
- RefPtr<Node> outerBlock = (start.deprecatedNode() == nodeToSplitTo) ? start.deprecatedNode() : splitTreeToNode(start.deprecatedNode(), nodeToSplitTo);
- RefPtr<Node> nodeAfterInsertionPosition = outerBlock;
- RefPtr<Range> range = Range::create(document(), start, endOfSelection);
+ RefPtrWillBeRawPtr<Node> outerBlock = (start.deprecatedNode() == nodeToSplitTo) ? start.deprecatedNode() : splitTreeToNode(start.deprecatedNode(), nodeToSplitTo).get();
+ RefPtrWillBeRawPtr<Node> nodeAfterInsertionPosition = outerBlock;
+ RefPtrWillBeRawPtr<Range> range = Range::create(document(), start, endOfSelection);
- if (isElementForFormatBlock(refNode->tagQName()) && start == startOfBlock(start)
- && (end == endOfBlock(end) || isNodeVisiblyContainedWithin(refNode, range.get()))
+ if (isElementForFormatBlock(refNode->tagQName()) && VisiblePosition(start) == startOfBlock(VisiblePosition(start))
+ && (VisiblePosition(end) == endOfBlock(VisiblePosition(end)) || isNodeVisiblyContainedWithin(*refNode, *range))
&& refNode != root && !root->isDescendantOf(refNode)) {
// Already in a block element that only contains the current paragraph
if (refNode->hasTagName(tagName()))
@@ -89,15 +89,15 @@ void FormatBlockCommand::formatRange(const Position& start, const Position& end,
}
Position lastParagraphInBlockNode = blockNode->lastChild() ? positionAfterNode(blockNode->lastChild()) : Position();
- bool wasEndOfParagraph = isEndOfParagraph(lastParagraphInBlockNode);
+ bool wasEndOfParagraph = isEndOfParagraph(VisiblePosition(lastParagraphInBlockNode));
- moveParagraphWithClones(start, end, blockNode.get(), outerBlock.get());
+ moveParagraphWithClones(VisiblePosition(start), VisiblePosition(end), blockNode.get(), outerBlock.get());
// Copy the inline style of the original block element to the newly created block-style element.
if (outerBlock.get() != nodeAfterInsertionPosition.get() && toHTMLElement(nodeAfterInsertionPosition.get())->hasAttribute(styleAttr))
blockNode->setAttribute(styleAttr, toHTMLElement(nodeAfterInsertionPosition.get())->getAttribute(styleAttr));
- if (wasEndOfParagraph && !isEndOfParagraph(lastParagraphInBlockNode) && !isStartOfParagraph(lastParagraphInBlockNode))
+ if (wasEndOfParagraph && !isEndOfParagraph(VisiblePosition(lastParagraphInBlockNode)) && !isStartOfParagraph(VisiblePosition(lastParagraphInBlockNode)))
insertBlockPlaceholder(lastParagraphInBlockNode);
}
@@ -106,7 +106,7 @@ Element* FormatBlockCommand::elementForFormatBlockCommand(Range* range)
if (!range)
return 0;
- Node* commonAncestor = range->commonAncestorContainer(IGNORE_EXCEPTION);
+ Node* commonAncestor = range->commonAncestorContainer();
while (commonAncestor && !isElementForFormatBlock(commonAncestor))
commonAncestor = commonAncestor->parentNode();
@@ -156,7 +156,7 @@ Node* enclosingBlockToSplitTreeTo(Node* startNode)
for (Node* n = startNode; n; n = n->parentNode()) {
if (!n->rendererIsEditable())
return lastBlock;
- if (isTableCell(n) || n->hasTagName(bodyTag) || !n->parentNode() || !n->parentNode()->rendererIsEditable() || isElementForFormatBlock(n))
+ if (isTableCell(n) || isHTMLBodyElement(*n) || !n->parentNode() || !n->parentNode()->rendererIsEditable() || isElementForFormatBlock(n))
return n;
if (isBlock(n))
lastBlock = n;
diff --git a/chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.h b/chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.h
index da6add691b0..65b7cb756af 100644
--- a/chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/FormatBlockCommand.h
@@ -38,14 +38,14 @@ class Position;
class Range;
class VisiblePosition;
-class FormatBlockCommand : public ApplyBlockElementCommand {
+class FormatBlockCommand FINAL : public ApplyBlockElementCommand {
public:
- static PassRefPtr<FormatBlockCommand> create(Document& document, const QualifiedName& tagName)
+ static PassRefPtrWillBeRawPtr<FormatBlockCommand> create(Document& document, const QualifiedName& tagName)
{
- return adoptRef(new FormatBlockCommand(document, tagName));
+ return adoptRefWillBeNoop(new FormatBlockCommand(document, tagName));
}
- virtual bool preservesTypingStyle() const { return true; }
+ virtual bool preservesTypingStyle() const OVERRIDE { return true; }
static Element* elementForFormatBlockCommand(Range*);
bool didApply() const { return m_didApply; }
@@ -53,9 +53,9 @@ public:
private:
FormatBlockCommand(Document&, const QualifiedName& tagName);
- void formatSelection(const VisiblePosition& startOfSelection, const VisiblePosition& endOfSelection);
- void formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtr<Element>&);
- EditAction editingAction() const { return EditActionFormatBlock; }
+ virtual void formatSelection(const VisiblePosition& startOfSelection, const VisiblePosition& endOfSelection) OVERRIDE;
+ virtual void formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtrWillBeRawPtr<Element>&) OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE { return EditActionFormatBlock; }
bool m_didApply;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/FrameSelection.cpp b/chromium/third_party/WebKit/Source/core/editing/FrameSelection.cpp
index 05a32fb61b3..e8802b27504 100644
--- a/chromium/third_party/WebKit/Source/core/editing/FrameSelection.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/FrameSelection.cpp
@@ -27,8 +27,8 @@
#include "core/editing/FrameSelection.h"
#include <stdio.h>
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/CharacterData.h"
@@ -45,7 +45,9 @@
#include "core/editing/TypingCommand.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/html/HTMLInputElement.h"
@@ -53,7 +55,6 @@
#include "core/page/EditorClient.h"
#include "core/page/EventHandler.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
#include "core/page/FrameTree.h"
#include "core/frame/FrameView.h"
#include "core/page/Page.h"
@@ -62,6 +63,7 @@
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/InlineTextBox.h"
+#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
@@ -82,14 +84,15 @@ static inline LayoutUnit NoXPosForVerticalArrowNavigation()
return LayoutUnit::min();
}
-static inline bool shouldAlwaysUseDirectionalSelection(Frame* frame)
+static inline bool shouldAlwaysUseDirectionalSelection(LocalFrame* frame)
{
return !frame || frame->editor().behavior().shouldConsiderSelectionAsDirectional();
}
-FrameSelection::FrameSelection(Frame* frame)
+FrameSelection::FrameSelection(LocalFrame* frame)
: m_frame(frame)
, m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation())
+ , m_observingVisibleSelection(false)
, m_granularity(CharacterGranularity)
, m_caretBlinkTimer(this, &FrameSelection::caretBlinkTimerFired)
, m_absCaretBoundsDirty(true)
@@ -102,6 +105,15 @@ FrameSelection::FrameSelection(Frame* frame)
m_selection.setIsDirectional(true);
}
+FrameSelection::~FrameSelection()
+{
+#if !ENABLE(OILPAN)
+ // Oilpan: No need to clear out VisibleSelection observer;
+ // it is finalized as a part object of FrameSelection.
+ stopObservingVisibleSelectionChangeIfNecessary();
+#endif
+}
+
Element* FrameSelection::rootEditableElementOrDocumentElement() const
{
Element* selectionRoot = m_selection.rootEditableElement();
@@ -115,7 +127,7 @@ Node* FrameSelection::rootEditableElementOrTreeScopeRootNode() const
return selectionRoot;
Node* node = m_selection.base().containerNode();
- return node ? node->treeScope().rootNode() : 0;
+ return node ? &node->treeScope().rootNode() : 0;
}
void FrameSelection::moveTo(const VisiblePosition &pos, EUserTriggered userTriggered, CursorAlignOnScroll align)
@@ -137,20 +149,6 @@ void FrameSelection::moveTo(const Position &pos, EAffinity affinity, EUserTrigge
setSelection(VisibleSelection(pos, affinity, m_selection.isDirectional()), options);
}
-void FrameSelection::moveTo(const Range *r, EAffinity affinity, EUserTriggered userTriggered)
-{
- SetSelectionOptions options = CloseTyping | ClearTypingStyle | userTriggered;
- VisibleSelection selection = r ? VisibleSelection(r->startPosition(), r->endPosition(), affinity) : VisibleSelection(Position(), Position(), affinity);
- setSelection(selection, options);
-}
-
-void FrameSelection::moveTo(const Position &base, const Position &extent, EAffinity affinity, EUserTriggered userTriggered)
-{
- const bool selectionHasDirection = true;
- SetSelectionOptions options = CloseTyping | ClearTypingStyle | userTriggered;
- setSelection(VisibleSelection(base, extent, affinity, selectionHasDirection), options);
-}
-
static void adjustEndpointsAtBidiBoundary(VisiblePosition& visibleBase, VisiblePosition& visibleExtent)
{
RenderedPosition base(visibleBase);
@@ -162,7 +160,7 @@ static void adjustEndpointsAtBidiBoundary(VisiblePosition& visibleBase, VisibleP
if (base.atLeftBoundaryOfBidiRun()) {
if (!extent.atRightBoundaryOfBidiRun(base.bidiLevelOnRight())
&& base.isEquivalent(extent.leftBoundaryOfBidiRun(base.bidiLevelOnRight()))) {
- visibleBase = base.positionAtLeftBoundaryOfBiDiRun();
+ visibleBase = VisiblePosition(base.positionAtLeftBoundaryOfBiDiRun());
return;
}
return;
@@ -171,19 +169,19 @@ static void adjustEndpointsAtBidiBoundary(VisiblePosition& visibleBase, VisibleP
if (base.atRightBoundaryOfBidiRun()) {
if (!extent.atLeftBoundaryOfBidiRun(base.bidiLevelOnLeft())
&& base.isEquivalent(extent.rightBoundaryOfBidiRun(base.bidiLevelOnLeft()))) {
- visibleBase = base.positionAtRightBoundaryOfBiDiRun();
+ visibleBase = VisiblePosition(base.positionAtRightBoundaryOfBiDiRun());
return;
}
return;
}
if (extent.atLeftBoundaryOfBidiRun() && extent.isEquivalent(base.leftBoundaryOfBidiRun(extent.bidiLevelOnRight()))) {
- visibleExtent = extent.positionAtLeftBoundaryOfBiDiRun();
+ visibleExtent = VisiblePosition(extent.positionAtLeftBoundaryOfBiDiRun());
return;
}
if (extent.atRightBoundaryOfBidiRun() && extent.isEquivalent(base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) {
- visibleExtent = extent.positionAtRightBoundaryOfBiDiRun();
+ visibleExtent = VisiblePosition(extent.positionAtRightBoundaryOfBiDiRun());
return;
}
}
@@ -238,7 +236,7 @@ void FrameSelection::setSelection(const VisibleSelection& newSelection, SetSelec
if (s.base().anchorNode()) {
Document& document = *s.base().document();
if (document.frame() && document.frame() != m_frame && document != m_frame->document()) {
- RefPtr<Frame> guard = document.frame();
+ RefPtr<LocalFrame> guard = document.frame();
document.frame()->selection().setSelection(s, options, align, granularity);
// It's possible that during the above set selection, this FrameSelection has been modified by
// selectFrameElementInParentIfFullySelected, but that the selection is no longer valid since
@@ -274,6 +272,9 @@ void FrameSelection::setSelection(const VisibleSelection& newSelection, SetSelec
if (!(options & DoNotUpdateAppearance)) {
m_frame->document()->updateLayoutIgnorePendingStylesheets();
+
+ // Hits in compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html
+ DisableCompositingQueryAsserts disabler;
updateAppearance();
}
@@ -335,9 +336,9 @@ void FrameSelection::respondToNodeModification(Node& node, bool baseRemoved, boo
Position start = m_selection.start();
Position end = m_selection.end();
if (startRemoved)
- updatePositionForNodeRemoval(start, &node);
+ updatePositionForNodeRemoval(start, node);
if (endRemoved)
- updatePositionForNodeRemoval(end, &node);
+ updatePositionForNodeRemoval(end, node);
if (start.isNotNull() && end.isNotNull()) {
if (m_selection.isBaseFirst())
@@ -357,7 +358,7 @@ void FrameSelection::respondToNodeModification(Node& node, bool baseRemoved, boo
m_selection.setWithoutValidation(m_selection.start(), m_selection.end());
else
m_selection.setWithoutValidation(m_selection.end(), m_selection.start());
- } else if (RefPtr<Range> range = m_selection.firstRange()) {
+ } else if (RefPtrWillBeRawPtr<Range> range = m_selection.firstRange()) {
TrackExceptionState exceptionState;
Range::CompareResults compareResult = range->compareNode(&node, exceptionState);
if (!exceptionState.hadException() && (compareResult == Range::NODE_BEFORE_AND_AFTER || compareResult == Range::NODE_INSIDE)) {
@@ -393,7 +394,7 @@ static Position updatePositionAfterAdoptingTextReplacement(const Position& posit
if (positionOffset > offset + oldLength)
positionOffset = positionOffset - oldLength + newLength;
- ASSERT(positionOffset <= node->length());
+ ASSERT_WITH_SECURITY_IMPLICATION(positionOffset <= node->length());
// CharacterNode in VisibleSelection must be Text node, because Comment
// and ProcessingInstruction node aren't visible.
return Position(toText(node), positionOffset);
@@ -470,7 +471,6 @@ void FrameSelection::updateSelectionIfNeeded(const Position& base, const Positio
return;
VisibleSelection newSelection;
newSelection.setWithoutValidation(base, extent);
- m_frame->document()->updateLayout();
setSelection(newSelection, DoNotSetFocus);
}
@@ -500,6 +500,8 @@ TextDirection FrameSelection::directionOfSelection()
void FrameSelection::didChangeFocus()
{
+ // Hits in virtual/gpu/compositedscrolling/scrollbars/scrollbar-miss-mousemove-disabled.html
+ DisableCompositingQueryAsserts disabler;
updateAppearance();
}
@@ -598,7 +600,7 @@ VisiblePosition FrameSelection::nextWordPositionForPlatform(const VisiblePositio
static void adjustPositionForUserSelectAll(VisiblePosition& pos, bool isForward)
{
if (Node* rootUserSelectAll = Position::rootUserSelectAllForNode(pos.deepEquivalent().anchorNode()))
- pos = isForward ? positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary) : positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary);
+ pos = VisiblePosition(isForward ? positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary) : positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary));
}
VisiblePosition FrameSelection::modifyExtendingRight(TextGranularity granularity)
@@ -935,18 +937,18 @@ static bool isBoundary(TextGranularity granularity)
bool FrameSelection::modify(EAlteration alter, SelectionDirection direction, TextGranularity granularity, EUserTriggered userTriggered)
{
if (userTriggered == UserTriggered) {
- FrameSelection trialFrameSelection;
- trialFrameSelection.setSelection(m_selection);
- trialFrameSelection.modify(alter, direction, granularity, NotUserTriggered);
+ OwnPtrWillBeRawPtr<FrameSelection> trialFrameSelection = FrameSelection::create();
+ trialFrameSelection->setSelection(m_selection);
+ trialFrameSelection->modify(alter, direction, granularity, NotUserTriggered);
- if (trialFrameSelection.selection().isRange() && m_selection.isCaret() && !dispatchSelectStart())
+ if (trialFrameSelection->selection().isRange() && m_selection.isCaret() && !dispatchSelectStart())
return false;
}
willBeModified(alter, direction);
bool wasRange = m_selection.isRange();
- Position originalStartPosition = m_selection.start();
+ VisiblePosition originalStartPosition = m_selection.visibleStart();
VisiblePosition position;
switch (direction) {
case DirectionRight:
@@ -1005,7 +1007,7 @@ bool FrameSelection::modify(EAlteration alter, SelectionDirection direction, Tex
VisibleSelection newSelection = m_selection;
newSelection.setExtent(position);
if (m_selection.isBaseFirst() != newSelection.isBaseFirst())
- position = m_selection.base();
+ position = m_selection.visibleBase();
}
// Standard Mac behavior when extending to a boundary is grow the selection rather than leaving the
@@ -1049,9 +1051,9 @@ bool FrameSelection::modify(EAlteration alter, unsigned verticalDistance, Vertic
return false;
if (userTriggered == UserTriggered) {
- FrameSelection trialFrameSelection;
- trialFrameSelection.setSelection(m_selection);
- trialFrameSelection.modify(alter, verticalDistance, direction, NotUserTriggered);
+ OwnPtrWillBeRawPtr<FrameSelection> trialFrameSelection = FrameSelection::create();
+ trialFrameSelection->setSelection(m_selection);
+ trialFrameSelection->modify(alter, verticalDistance, direction, NotUserTriggered);
}
willBeModified(alter, direction == DirectionUp ? DirectionBackward : DirectionForward);
@@ -1144,7 +1146,7 @@ LayoutUnit FrameSelection::lineDirectionPointForBlockDirectionNavigation(EPositi
break;
}
- Frame* frame = pos.document()->frame();
+ LocalFrame* frame = pos.document()->frame();
if (!frame)
return x;
@@ -1208,18 +1210,6 @@ void FrameSelection::setExtent(const VisiblePosition &pos, EUserTriggered userTr
setSelection(VisibleSelection(m_selection.base(), pos.deepEquivalent(), pos.affinity(), selectionHasDirection), CloseTyping | ClearTypingStyle | userTriggered);
}
-void FrameSelection::setBase(const Position &pos, EAffinity affinity, EUserTriggered userTriggered)
-{
- const bool selectionHasDirection = true;
- setSelection(VisibleSelection(pos, m_selection.extent(), affinity, selectionHasDirection), CloseTyping | ClearTypingStyle | userTriggered);
-}
-
-void FrameSelection::setExtent(const Position &pos, EAffinity affinity, EUserTriggered userTriggered)
-{
- const bool selectionHasDirection = true;
- setSelection(VisibleSelection(m_selection.base(), pos, affinity, selectionHasDirection), CloseTyping | ClearTypingStyle | userTriggered);
-}
-
RenderObject* FrameSelection::caretRenderer() const
{
return CaretBase::caretRenderer(m_selection.start().deprecatedNode());
@@ -1253,11 +1243,7 @@ bool FrameSelection::recomputeCaretRect()
if (!shouldUpdateCaretRect())
return false;
- if (!m_frame)
- return false;
-
- FrameView* v = m_frame->document()->view();
- if (!v)
+ if (!m_frame || !m_frame->document()->view())
return false;
LayoutRect oldRect = localCaretRectWithoutUpdate();
@@ -1273,9 +1259,9 @@ bool FrameSelection::recomputeCaretRect()
return false;
if (RenderView* view = m_frame->document()->renderView()) {
- Node* node = m_selection.start().deprecatedNode();
- if (m_previousCaretNode)
+ if (m_previousCaretNode && shouldRepaintCaret(view, m_previousCaretNode->isContentEditable()))
repaintCaretForLocalRect(m_previousCaretNode.get(), oldRect);
+ Node* node = m_selection.start().deprecatedNode();
m_previousCaretNode = node;
if (shouldRepaintCaret(view, isContentEditable()))
repaintCaretForLocalRect(node, newRect);
@@ -1352,8 +1338,13 @@ void FrameSelection::selectFrameElementInParentIfFullySelected()
if (!isEndOfDocument(selection().visibleEnd()))
return;
+ // FIXME: This is not yet implemented for cross-process frame relationships.
+ if (!parent->isLocalFrame())
+ return;
+
// Get to the <iframe> or <frame> (or even <object>) element in the parent frame.
- Element* ownerElement = m_frame->ownerElement();
+ // FIXME: Doesn't work for OOPI.
+ Element* ownerElement = m_frame->deprecatedLocalOwner();
if (!ownerElement)
return;
ContainerNode* ownerElementParent = ownerElement->parentNode();
@@ -1372,14 +1363,14 @@ void FrameSelection::selectFrameElementInParentIfFullySelected()
// Focus on the parent frame, and then select from before this element to after.
VisibleSelection newSelection(beforeOwnerElement, afterOwnerElement);
page->focusController().setFocusedFrame(parent);
- parent->selection().setSelection(newSelection);
+ toLocalFrame(parent)->selection().setSelection(newSelection);
}
void FrameSelection::selectAll()
{
Document* document = m_frame->document();
- if (document->focusedElement() && document->focusedElement()->hasTagName(selectTag)) {
+ if (isHTMLSelectElement(document->focusedElement())) {
HTMLSelectElement* selectElement = toHTMLSelectElement(document->focusedElement());
if (selectElement->canSelectAll()) {
selectElement->selectAll();
@@ -1387,7 +1378,7 @@ void FrameSelection::selectAll()
}
}
- RefPtr<Node> root = 0;
+ RefPtrWillBeRawPtr<Node> root = nullptr;
Node* selectStartTarget = 0;
if (isContentEditable()) {
root = highestEditableRoot(m_selection.start());
@@ -1416,32 +1407,37 @@ void FrameSelection::selectAll()
notifyRendererOfSelectionChange(UserTriggered);
}
-bool FrameSelection::setSelectedRange(Range* range, EAffinity affinity, bool closeTyping)
+bool FrameSelection::setSelectedRange(Range* range, EAffinity affinity, DirectoinalOption directional, SetSelectionOptions options)
{
if (!range || !range->startContainer() || !range->endContainer())
return false;
ASSERT(range->startContainer()->document() == range->endContainer()->document());
- m_frame->document()->updateLayoutIgnorePendingStylesheets();
-
// Non-collapsed ranges are not allowed to start at the end of a line that is wrapped,
// they start at the beginning of the next line instead
- TrackExceptionState exceptionState;
- bool collapsed = range->collapsed(exceptionState);
- if (exceptionState.hadException())
- return false;
+ m_logicalRange = nullptr;
+ stopObservingVisibleSelectionChangeIfNecessary();
+
+ VisibleSelection newSelection(range, affinity, directional == Directional);
+ setSelection(newSelection, options);
+
+ m_logicalRange = range->cloneRange();
+ startObservingVisibleSelectionChange();
- // FIXME: Can we provide extentAffinity?
- VisiblePosition visibleStart(range->startPosition(), collapsed ? affinity : DOWNSTREAM);
- VisiblePosition visibleEnd(range->endPosition(), SEL_DEFAULT_AFFINITY);
- setSelection(VisibleSelection(visibleStart, visibleEnd), ClearTypingStyle | (closeTyping ? CloseTyping : 0));
return true;
}
+PassRefPtrWillBeRawPtr<Range> FrameSelection::firstRange() const
+{
+ if (m_logicalRange)
+ return m_logicalRange->cloneRange();
+ return m_selection.firstRange();
+}
+
bool FrameSelection::isInPasswordField() const
{
HTMLTextFormControlElement* textControl = enclosingTextFormControl(start());
- return textControl && textControl->hasTagName(inputTag) && toHTMLInputElement(textControl)->isPasswordField();
+ return isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->isPasswordField();
}
void FrameSelection::notifyAccessibilityForSelectionChange()
@@ -1456,8 +1452,8 @@ void FrameSelection::focusedOrActiveStateChanged()
{
bool activeAndFocused = isFocusedAndActive();
- RefPtr<Document> document = m_frame->document();
- document->updateStyleIfNeeded();
+ RefPtrWillBeRawPtr<Document> document = m_frame->document();
+ document->updateRenderTreeIfNeeded();
// Because RenderObject::selectionBackgroundColor() and
// RenderObject::selectionForegroundColor() check if the frame is active,
@@ -1518,7 +1514,7 @@ bool FrameSelection::isFocusedAndActive() const
return m_focused && m_frame->page() && m_frame->page()->focusController().isActive();
}
-inline static bool shouldStopBlinkingDueToTypingCommand(Frame* frame)
+inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame)
{
return frame->editor().lastEditCommand() && frame->editor().lastEditCommand()->shouldStopCaretBlinking();
}
@@ -1550,7 +1546,7 @@ void FrameSelection::updateAppearance()
// already blinking in the right location.
if (shouldBlink && !m_caretBlinkTimer.isActive()) {
if (double blinkInterval = RenderTheme::theme().caretBlinkInterval())
- m_caretBlinkTimer.startRepeating(blinkInterval);
+ m_caretBlinkTimer.startRepeating(blinkInterval, FROM_HERE);
if (!m_caretPaint) {
m_caretPaint = true;
@@ -1589,7 +1585,8 @@ void FrameSelection::updateAppearance()
if (startPos.isNotNull() && endPos.isNotNull() && selection.visibleStart() != selection.visibleEnd()) {
RenderObject* startRenderer = startPos.deprecatedNode()->renderer();
RenderObject* endRenderer = endPos.deprecatedNode()->renderer();
- view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset());
+ if (startRenderer->view() == view && endRenderer->view() == view)
+ view->setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer, endPos.deprecatedEditingOffset());
}
}
@@ -1640,14 +1637,14 @@ void FrameSelection::caretBlinkTimerFired(Timer<FrameSelection>*)
void FrameSelection::notifyRendererOfSelectionChange(EUserTriggered userTriggered)
{
- m_frame->document()->updateStyleIfNeeded();
+ m_frame->document()->updateRenderTreeIfNeeded();
if (HTMLTextFormControlElement* textControl = enclosingTextFormControl(start()))
textControl->selectionChanged(userTriggered == UserTriggered);
}
// Helper function that tells whether a particular node is an element that has an entire
-// Frame and FrameView, a <frame>, <iframe>, or <object>.
+// LocalFrame and FrameView, a <frame>, <iframe>, or <object>.
static bool isFrameElement(const Node* n)
{
if (!n)
@@ -1684,20 +1681,13 @@ void FrameSelection::setFocusedNodeIfNeeded()
}
target = target->parentOrShadowHostElement();
}
- m_frame->document()->setFocusedElement(0);
+ m_frame->document()->setFocusedElement(nullptr);
}
if (caretBrowsing)
m_frame->page()->focusController().setFocusedElement(0, m_frame);
}
-PassRefPtr<MutableStylePropertySet> FrameSelection::copyTypingStyle() const
-{
- if (!m_typingStyle || !m_typingStyle->style())
- return 0;
- return m_typingStyle->style()->mutableCopy();
-}
-
static String extractSelectedText(const FrameSelection& selection, TextIteratorBehavior behavior)
{
// We remove '\0' characters because they are not visibly rendered to the user.
@@ -1718,7 +1708,7 @@ String FrameSelection::selectedTextForClipboard() const
FloatRect FrameSelection::bounds(bool clipToVisibleContent) const
{
- m_frame->document()->updateStyleIfNeeded();
+ m_frame->document()->updateRenderTreeIfNeeded();
FrameView* view = m_frame->view();
RenderView* renderView = m_frame->contentRenderer();
@@ -1730,22 +1720,26 @@ FloatRect FrameSelection::bounds(bool clipToVisibleContent) const
return clipToVisibleContent ? intersection(selectionRect, view->visibleContentRect()) : selectionRect;
}
+static inline HTMLFormElement* associatedFormElement(HTMLElement& element)
+{
+ if (isHTMLFormElement(element))
+ return &toHTMLFormElement(element);
+ return element.formOwner();
+}
+
// Scans logically forward from "start", including any child frames.
static HTMLFormElement* scanForForm(Node* start)
{
if (!start)
return 0;
- Element* element = start->isElementNode() ? toElement(start) : ElementTraversal::next(*start);
- for (; element; element = ElementTraversal::next(*element)) {
- if (element->hasTagName(formTag))
- return toHTMLFormElement(element);
- if (element->isHTMLElement()) {
- HTMLFormElement* owner = toHTMLElement(element)->formOwner();
- if (owner)
- return owner;
- }
- if (element->hasTagName(frameTag) || element->hasTagName(iframeTag)) {
- Node* childDocument = toHTMLFrameElementBase(element)->contentDocument();
+
+ HTMLElement* element = start->isHTMLElement() ? toHTMLElement(start) : Traversal<HTMLElement>::next(*start);
+ for (; element; element = Traversal<HTMLElement>::next(*element)) {
+ if (HTMLFormElement* form = associatedFormElement(*element))
+ return form;
+
+ if (isHTMLFrameElementBase(*element)) {
+ Node* childDocument = toHTMLFrameElementBase(*element).contentDocument();
if (HTMLFormElement* frameResult = scanForForm(childDocument))
return frameResult;
}
@@ -1760,17 +1754,13 @@ HTMLFormElement* FrameSelection::currentForm() const
Node* start = m_frame->document()->focusedElement();
if (!start)
start = this->start().deprecatedNode();
+ if (!start)
+ return 0;
// Try walking up the node tree to find a form element.
- Node* node;
- for (node = start; node; node = node->parentNode()) {
- if (node->hasTagName(formTag))
- return toHTMLFormElement(node);
- if (node->isHTMLElement()) {
- HTMLFormElement* owner = toHTMLElement(node)->formOwner();
- if (owner)
- return owner;
- }
+ for (HTMLElement* element = Traversal<HTMLElement>::firstAncestorOrSelf(*start); element; element = Traversal<HTMLElement>::firstAncestor(*element)) {
+ if (HTMLFormElement* form = associatedFormElement(*element))
+ return form;
}
// Try walking forward in the node tree to find a form element.
@@ -1814,10 +1804,11 @@ void FrameSelection::setSelectionFromNone()
return;
Node* node = document->documentElement();
- while (node && !node->hasTagName(bodyTag))
- node = NodeTraversal::next(*node);
- if (node)
- setSelection(VisibleSelection(firstPositionInOrBeforeNode(node), DOWNSTREAM));
+ if (!node)
+ return;
+ Node* body = isHTMLBodyElement(*node) ? node : Traversal<HTMLBodyElement>::next(*node);
+ if (body)
+ setSelection(VisibleSelection(firstPositionInOrBeforeNode(body), DOWNSTREAM));
}
bool FrameSelection::dispatchSelectStart()
@@ -1838,6 +1829,30 @@ void FrameSelection::setShouldShowBlockCursor(bool shouldShowBlockCursor)
updateAppearance();
}
+void FrameSelection::didChangeVisibleSelection()
+{
+ ASSERT(m_observingVisibleSelection);
+ // Invalidate the logical range when the underlying VisibleSelection has changed.
+ m_logicalRange = nullptr;
+ m_selection.clearChangeObserver();
+ m_observingVisibleSelection = false;
+}
+
+void FrameSelection::startObservingVisibleSelectionChange()
+{
+ ASSERT(!m_observingVisibleSelection);
+ m_selection.setChangeObserver(*this);
+ m_observingVisibleSelection = true;
+}
+
+void FrameSelection::stopObservingVisibleSelectionChangeIfNecessary()
+{
+ if (m_observingVisibleSelection) {
+ m_selection.clearChangeObserver();
+ m_observingVisibleSelection = false;
+ }
+}
+
#ifndef NDEBUG
void FrameSelection::formatForDebugger(char* buffer, unsigned length) const
@@ -1852,6 +1867,16 @@ void FrameSelection::showTreeForThis() const
#endif
+void FrameSelection::trace(Visitor* visitor)
+{
+ visitor->trace(m_selection);
+ visitor->trace(m_originalBase);
+ visitor->trace(m_logicalRange);
+ visitor->trace(m_previousCaretNode);
+ visitor->trace(m_typingStyle);
+ VisibleSelection::ChangeObserver::trace(visitor);
+}
+
}
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/editing/FrameSelection.h b/chromium/third_party/WebKit/Source/core/editing/FrameSelection.h
index 04b65990bd8..c3555ae8cbe 100644
--- a/chromium/third_party/WebKit/Source/core/editing/FrameSelection.h
+++ b/chromium/third_party/WebKit/Source/core/editing/FrameSelection.h
@@ -30,16 +30,17 @@
#include "core/editing/Caret.h"
#include "core/editing/EditingStyle.h"
#include "core/editing/VisibleSelection.h"
-#include "core/rendering/ScrollBehavior.h"
+#include "core/rendering/ScrollAlignment.h"
#include "platform/Timer.h"
#include "platform/geometry/IntRect.h"
#include "platform/geometry/LayoutRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
class CharacterData;
-class Frame;
+class LocalFrame;
class GraphicsContext;
class HTMLFormElement;
class MutableStylePropertySet;
@@ -56,10 +57,17 @@ enum RevealExtentOption {
DoNotRevealExtent
};
-class FrameSelection : private CaretBase {
+class FrameSelection FINAL : public NoBaseWillBeGarbageCollectedFinalized<FrameSelection>, public VisibleSelection::ChangeObserver, private CaretBase {
WTF_MAKE_NONCOPYABLE(FrameSelection);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FrameSelection);
public:
+ static PassOwnPtrWillBeRawPtr<FrameSelection> create(LocalFrame* frame = 0)
+ {
+ return adoptPtrWillBeNoop(new FrameSelection(frame));
+ }
+ virtual ~FrameSelection();
+
enum EAlteration { AlterationMove, AlterationExtend };
enum CursorAlignOnScroll { AlignCursorOnScrollIfNeeded,
AlignCursorOnScrollAlways };
@@ -77,7 +85,10 @@ public:
return static_cast<EUserTriggered>(options & UserTriggered);
}
- explicit FrameSelection(Frame* = 0);
+ enum DirectoinalOption {
+ NonDirectional,
+ Directional
+ };
Element* rootEditableElement() const { return m_selection.rootEditableElement(); }
Element* rootEditableElementOrDocumentElement() const;
@@ -87,16 +98,14 @@ public:
bool isContentEditable() const { return m_selection.isContentEditable(); }
bool isContentRichlyEditable() const { return m_selection.isContentRichlyEditable(); }
- void moveTo(const Range*, EAffinity, EUserTriggered = NotUserTriggered);
void moveTo(const VisiblePosition&, EUserTriggered = NotUserTriggered, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded);
void moveTo(const VisiblePosition&, const VisiblePosition&, EUserTriggered = NotUserTriggered);
void moveTo(const Position&, EAffinity, EUserTriggered = NotUserTriggered);
- void moveTo(const Position&, const Position&, EAffinity, EUserTriggered = NotUserTriggered);
const VisibleSelection& selection() const { return m_selection; }
void setSelection(const VisibleSelection&, SetSelectionOptions = CloseTyping | ClearTypingStyle, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity);
void setSelection(const VisibleSelection& selection, TextGranularity granularity) { setSelection(selection, CloseTyping | ClearTypingStyle, AlignCursorOnScrollIfNeeded, granularity); }
- bool setSelectedRange(Range*, EAffinity, bool closeTyping);
+ bool setSelectedRange(Range*, EAffinity, DirectoinalOption directional = NonDirectional, SetSelectionOptions = CloseTyping | ClearTypingStyle);
void selectAll();
void clear();
void prepareForDestruction();
@@ -120,9 +129,7 @@ public:
void setEnd(const VisiblePosition &, EUserTriggered = NotUserTriggered);
void setBase(const VisiblePosition&, EUserTriggered = NotUserTriggered);
- void setBase(const Position&, EAffinity, EUserTriggered = NotUserTriggered);
void setExtent(const VisiblePosition&, EUserTriggered = NotUserTriggered);
- void setExtent(const Position&, EAffinity, EUserTriggered = NotUserTriggered);
Position base() const { return m_selection.base(); }
Position extent() const { return m_selection.extent(); }
@@ -147,9 +154,13 @@ public:
bool isRange() const { return m_selection.isRange(); }
bool isCaretOrRange() const { return m_selection.isCaretOrRange(); }
bool isInPasswordField() const;
- bool isAll(EditingBoundaryCrossingRule rule = CannotCrossEditingBoundary) const { return m_selection.isAll(rule); }
+ bool isDirectional() const { return m_selection.isDirectional(); }
+
+ // If this FrameSelection has a logical range which is still valid, this function return its clone. Otherwise,
+ // the return value from underlying VisibleSelection's firstRange() is returned.
+ PassRefPtrWillBeRawPtr<Range> firstRange() const;
- PassRefPtr<Range> toNormalizedRange() const { return m_selection.toNormalizedRange(); }
+ PassRefPtrWillBeRawPtr<Range> toNormalizedRange() const { return m_selection.toNormalizedRange(); }
void nodeWillBeRemoved(Node&);
void didUpdateCharacterData(CharacterData*, unsigned offset, unsigned oldLength, unsigned newLength);
@@ -186,11 +197,8 @@ public:
void setFocusedNodeIfNeeded();
void notifyRendererOfSelectionChange(EUserTriggered);
- void paintDragCaret(GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
-
EditingStyle* typingStyle() const;
- PassRefPtr<MutableStylePropertySet> copyTypingStyle() const;
- void setTypingStyle(PassRefPtr<EditingStyle>);
+ void setTypingStyle(PassRefPtrWillBeRawPtr<EditingStyle>);
void clearTypingStyle();
String selectedText() const;
@@ -203,10 +211,16 @@ public:
void revealSelection(const ScrollAlignment& = ScrollAlignment::alignCenterIfNeeded, RevealExtentOption = DoNotRevealExtent);
void setSelectionFromNone();
- bool shouldShowBlockCursor() const { return m_shouldShowBlockCursor; }
void setShouldShowBlockCursor(bool);
+ // VisibleSelection::ChangeObserver interface.
+ virtual void didChangeVisibleSelection() OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
+ explicit FrameSelection(LocalFrame*);
+
enum EPositionType { START, END, BASE, EXTENT };
void respondToNodeModification(Node&, bool baseRemoved, bool extentRemoved, bool startRemoved, bool endRemoved);
@@ -244,17 +258,26 @@ private:
void updateSelectionIfNeeded(const Position& base, const Position& extent, const Position& start, const Position& end);
- Frame* m_frame;
+ void startObservingVisibleSelectionChange();
+ void stopObservingVisibleSelectionChangeIfNecessary();
+
+ LocalFrame* m_frame;
LayoutUnit m_xPosForVerticalArrowNavigation;
VisibleSelection m_selection;
+ bool m_observingVisibleSelection;
VisiblePosition m_originalBase; // Used to store base before the adjustment at bidi boundary
TextGranularity m_granularity;
- RefPtr<Node> m_previousCaretNode; // The last node which painted the caret. Retained for clearing the old caret when it moves.
+ // The range specified by the user, which may not be visually canonicalized (hence "logical").
+ // This will be invalidated if the underlying VisibleSelection changes. If that happens, this variable will
+ // become null, in which case logical positions == visible positions.
+ RefPtrWillBeMember<Range> m_logicalRange;
+
+ RefPtrWillBeMember<Node> m_previousCaretNode; // The last node which painted the caret. Retained for clearing the old caret when it moves.
- RefPtr<EditingStyle> m_typingStyle;
+ RefPtrWillBeMember<EditingStyle> m_typingStyle;
Timer<FrameSelection> m_caretBlinkTimer;
// The painted bounds of the caret in absolute coordinates
@@ -276,7 +299,7 @@ inline void FrameSelection::clearTypingStyle()
m_typingStyle.clear();
}
-inline void FrameSelection::setTypingStyle(PassRefPtr<EditingStyle> style)
+inline void FrameSelection::setTypingStyle(PassRefPtrWillBeRawPtr<EditingStyle> style)
{
m_typingStyle = style;
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.cpp b/chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.cpp
index c63d98c66c9..7b28f4b6592 100644
--- a/chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.cpp
@@ -27,17 +27,17 @@
#include "core/editing/HTMLInterchange.h"
#include "core/dom/Text.h"
-#include "core/editing/TextIterator.h"
+#include "core/editing/htmlediting.h"
#include "core/rendering/RenderObject.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/unicode/CharacterNames.h"
namespace WebCore {
-String convertHTMLTextToInterchangeFormat(const String& in, const Text* node)
+String convertHTMLTextToInterchangeFormat(const String& in, const Text& node)
{
// Assume all the text comes from node.
- if (node->renderer() && node->renderer()->style()->preserveNewline())
+ if (node.renderer() && node.renderer()->style()->preserveNewline())
return in;
const char convertedSpaceString[] = "<span class=\"" AppleConvertedSpace "\">\xA0</span>";
diff --git a/chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.h b/chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.h
index b306437bb09..a4d484c9150 100644
--- a/chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.h
+++ b/chromium/third_party/WebKit/Source/core/editing/HTMLInterchange.h
@@ -40,7 +40,7 @@ class Text;
enum EAnnotateForInterchange { DoNotAnnotateForInterchange, AnnotateForInterchange };
-String convertHTMLTextToInterchangeFormat(const String&, const Text*);
+String convertHTMLTextToInterchangeFormat(const String&, const Text&);
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.cpp
index f882fe03a5e..d1a4480a911 100644
--- a/chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.cpp
@@ -26,8 +26,9 @@
#include "config.h"
#include "core/editing/IndentOutdentCommand.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
+#include "core/dom/ElementTraversal.h"
#include "core/editing/InsertListCommand.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
@@ -40,48 +41,47 @@ using namespace HTMLNames;
static bool isListOrIndentBlockquote(const Node* node)
{
- return node && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(blockquoteTag));
+ return node && (isHTMLUListElement(*node) || isHTMLOListElement(*node) || node->hasTagName(blockquoteTag));
}
-IndentOutdentCommand::IndentOutdentCommand(Document& document, EIndentType typeOfAction, int marginInPixels)
+IndentOutdentCommand::IndentOutdentCommand(Document& document, EIndentType typeOfAction)
: ApplyBlockElementCommand(document, blockquoteTag, "margin: 0 0 0 40px; border: none; padding: 0px;")
, m_typeOfAction(typeOfAction)
- , m_marginInPixels(marginInPixels)
{
}
bool IndentOutdentCommand::tryIndentingAsListItem(const Position& start, const Position& end)
{
// If our selection is not inside a list, bail out.
- RefPtr<Node> lastNodeInSelectedParagraph = start.deprecatedNode();
- RefPtr<Element> listNode = enclosingList(lastNodeInSelectedParagraph.get());
+ RefPtrWillBeRawPtr<Node> lastNodeInSelectedParagraph = start.deprecatedNode();
+ RefPtrWillBeRawPtr<Element> listNode = enclosingList(lastNodeInSelectedParagraph.get());
if (!listNode)
return false;
// Find the block that we want to indent. If it's not a list item (e.g., a div inside a list item), we bail out.
- RefPtr<Element> selectedListItem = enclosingBlock(lastNodeInSelectedParagraph.get());
+ RefPtrWillBeRawPtr<Element> selectedListItem = enclosingBlock(lastNodeInSelectedParagraph.get());
// FIXME: we need to deal with the case where there is no li (malformed HTML)
- if (!selectedListItem->hasTagName(liTag))
+ if (!selectedListItem || !isHTMLLIElement(*selectedListItem))
return false;
// FIXME: previousElementSibling does not ignore non-rendered content like <span></span>. Should we?
- RefPtr<Element> previousList = selectedListItem->previousElementSibling();
- RefPtr<Element> nextList = selectedListItem->nextElementSibling();
+ RefPtrWillBeRawPtr<Element> previousList = ElementTraversal::previousSibling(*selectedListItem);
+ RefPtrWillBeRawPtr<Element> nextList = ElementTraversal::nextSibling(*selectedListItem);
// We should calculate visible range in list item because inserting new
// list element will change visibility of list item, e.g. :first-child
// CSS selector.
- RefPtr<Element> newList = document().createElement(listNode->tagQName(), false);
+ RefPtrWillBeRawPtr<Element> newList = document().createElement(listNode->tagQName(), false);
insertNodeBefore(newList, selectedListItem.get());
// We should clone all the children of the list item for indenting purposes. However, in case the current
// selection does not encompass all its children, we need to explicitally handle the same. The original
// list item too would require proper deletion in that case.
if (end.anchorNode() == selectedListItem.get() || end.anchorNode()->isDescendantOf(selectedListItem->lastChild())) {
- moveParagraphWithClones(start, end, newList.get(), selectedListItem.get());
+ moveParagraphWithClones(VisiblePosition(start), VisiblePosition(end), newList.get(), selectedListItem.get());
} else {
- moveParagraphWithClones(start, positionAfterNode(selectedListItem->lastChild()), newList.get(), selectedListItem.get());
+ moveParagraphWithClones(VisiblePosition(start), VisiblePosition(positionAfterNode(selectedListItem->lastChild())), newList.get(), selectedListItem.get());
removeNode(selectedListItem.get());
}
@@ -93,7 +93,7 @@ bool IndentOutdentCommand::tryIndentingAsListItem(const Position& start, const P
return true;
}
-void IndentOutdentCommand::indentIntoBlockquote(const Position& start, const Position& end, RefPtr<Element>& targetBlockquote)
+void IndentOutdentCommand::indentIntoBlockquote(const Position& start, const Position& end, RefPtrWillBeRawPtr<Element>& targetBlockquote)
{
Node* enclosingCell = enclosingNodeOfType(start, &isTableCell);
Node* nodeToSplitTo;
@@ -107,9 +107,9 @@ void IndentOutdentCommand::indentIntoBlockquote(const Position& start, const Pos
if (!nodeToSplitTo)
return;
- RefPtr<Node> outerBlock = (start.containerNode() == nodeToSplitTo) ? start.containerNode() : splitTreeToNode(start.containerNode(), nodeToSplitTo);
+ RefPtrWillBeRawPtr<Node> outerBlock = (start.containerNode() == nodeToSplitTo) ? start.containerNode() : splitTreeToNode(start.containerNode(), nodeToSplitTo).get();
- VisiblePosition startOfContents = start;
+ VisiblePosition startOfContents(start);
if (!targetBlockquote) {
// Create a new blockquote and insert it as a child of the root editable element. We accomplish
// this by splitting all parents of the current paragraph up to that point.
@@ -118,10 +118,10 @@ void IndentOutdentCommand::indentIntoBlockquote(const Position& start, const Pos
insertNodeAt(targetBlockquote, start);
else
insertNodeBefore(targetBlockquote, outerBlock);
- startOfContents = positionInParentAfterNode(targetBlockquote.get());
+ startOfContents = VisiblePosition(positionInParentAfterNode(*targetBlockquote));
}
- moveParagraphWithClones(startOfContents, end, targetBlockquote.get(), outerBlock.get());
+ moveParagraphWithClones(startOfContents, VisiblePosition(end), targetBlockquote.get(), outerBlock.get());
}
void IndentOutdentCommand::outdentParagraph()
@@ -134,11 +134,11 @@ void IndentOutdentCommand::outdentParagraph()
return;
// Use InsertListCommand to remove the selection from the list
- if (enclosingNode->hasTagName(olTag)) {
+ if (isHTMLOListElement(*enclosingNode)) {
applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::OrderedList));
return;
}
- if (enclosingNode->hasTagName(ulTag)) {
+ if (isHTMLUListElement(*enclosingNode)) {
applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::UnorderedList));
return;
}
@@ -176,18 +176,23 @@ void IndentOutdentCommand::outdentParagraph()
return;
}
- Node* enclosingBlockFlow = enclosingBlock(visibleStartOfParagraph.deepEquivalent().deprecatedNode());
- RefPtr<Node> splitBlockquoteNode = enclosingNode;
- if (enclosingBlockFlow != enclosingNode)
- splitBlockquoteNode = splitTreeToNode(enclosingBlockFlow, enclosingNode, true);
- else {
- // We split the blockquote at where we start outdenting.
- Node* highestInlineNode = highestEnclosingNodeOfType(visibleStartOfParagraph.deepEquivalent(), isInline, CannotCrossEditingBoundary, enclosingBlockFlow);
- splitElement(toElement(enclosingNode), (highestInlineNode) ? highestInlineNode : visibleStartOfParagraph.deepEquivalent().deprecatedNode());
+ RefPtrWillBeRawPtr<Node> splitBlockquoteNode = enclosingNode;
+ if (Node* enclosingBlockFlow = enclosingBlock(visibleStartOfParagraph.deepEquivalent().deprecatedNode())) {
+ if (enclosingBlockFlow != enclosingNode) {
+ splitBlockquoteNode = splitTreeToNode(enclosingBlockFlow, enclosingNode, true);
+ } else {
+ // We split the blockquote at where we start outdenting.
+ Node* highestInlineNode = highestEnclosingNodeOfType(visibleStartOfParagraph.deepEquivalent(), isInline, CannotCrossEditingBoundary, enclosingBlockFlow);
+ splitElement(toElement(enclosingNode), (highestInlineNode) ? highestInlineNode : visibleStartOfParagraph.deepEquivalent().deprecatedNode());
+ }
}
- RefPtr<Node> placeholder = createBreakElement(document());
+ VisiblePosition startOfParagraphToMove(startOfParagraph(visibleStartOfParagraph));
+ VisiblePosition endOfParagraphToMove(endOfParagraph(visibleEndOfParagraph));
+ if (startOfParagraphToMove.isNull() || endOfParagraphToMove.isNull())
+ return;
+ RefPtrWillBeRawPtr<Node> placeholder = createBreakElement(document());
insertNodeBefore(placeholder, splitBlockquoteNode);
- moveParagraph(startOfParagraph(visibleStartOfParagraph), endOfParagraph(visibleEndOfParagraph), positionBeforeNode(placeholder.get()), true);
+ moveParagraph(startOfParagraphToMove, endOfParagraphToMove, VisiblePosition(positionBeforeNode(placeholder.get())), true);
}
// FIXME: We should merge this function with ApplyBlockElementCommand::formatSelection
@@ -220,7 +225,7 @@ void IndentOutdentCommand::outdentRegion(const VisiblePosition& startOfSelection
break;
if (endOfNextParagraph.isNotNull() && !endOfNextParagraph.deepEquivalent().inDocument()) {
- endOfCurrentParagraph = endingSelection().end();
+ endOfCurrentParagraph = VisiblePosition(endingSelection().end());
endOfNextParagraph = endOfParagraph(endOfCurrentParagraph.next());
}
endOfCurrentParagraph = endOfNextParagraph;
@@ -235,10 +240,10 @@ void IndentOutdentCommand::formatSelection(const VisiblePosition& startOfSelecti
outdentRegion(startOfSelection, endOfSelection);
}
-void IndentOutdentCommand::formatRange(const Position& start, const Position& end, const Position&, RefPtr<Element>& blockquoteForNextIndent)
+void IndentOutdentCommand::formatRange(const Position& start, const Position& end, const Position&, RefPtrWillBeRawPtr<Element>& blockquoteForNextIndent)
{
if (tryIndentingAsListItem(start, end))
- blockquoteForNextIndent = 0;
+ blockquoteForNextIndent = nullptr;
else
indentIntoBlockquote(start, end, blockquoteForNextIndent);
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.h b/chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.h
index b90d8ec380a..c5d2b3b7312 100644
--- a/chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/IndentOutdentCommand.h
@@ -31,32 +31,30 @@
namespace WebCore {
-class IndentOutdentCommand : public ApplyBlockElementCommand {
+class IndentOutdentCommand FINAL : public ApplyBlockElementCommand {
public:
enum EIndentType { Indent, Outdent };
- static PassRefPtr<IndentOutdentCommand> create(Document& document, EIndentType type, int marginInPixels = 0)
+ static PassRefPtrWillBeRawPtr<IndentOutdentCommand> create(Document& document, EIndentType type)
{
- return adoptRef(new IndentOutdentCommand(document, type, marginInPixels));
+ return adoptRefWillBeNoop(new IndentOutdentCommand(document, type));
}
- virtual bool preservesTypingStyle() const { return true; }
+ virtual bool preservesTypingStyle() const OVERRIDE { return true; }
private:
- IndentOutdentCommand(Document&, EIndentType, int marginInPixels);
+ IndentOutdentCommand(Document&, EIndentType);
- virtual EditAction editingAction() const { return m_typeOfAction == Indent ? EditActionIndent : EditActionOutdent; }
+ virtual EditAction editingAction() const OVERRIDE { return m_typeOfAction == Indent ? EditActionIndent : EditActionOutdent; }
- void indentRegion(const VisiblePosition&, const VisiblePosition&);
void outdentRegion(const VisiblePosition&, const VisiblePosition&);
void outdentParagraph();
bool tryIndentingAsListItem(const Position&, const Position&);
- void indentIntoBlockquote(const Position&, const Position&, RefPtr<Element>&);
+ void indentIntoBlockquote(const Position&, const Position&, RefPtrWillBeRawPtr<Element>&);
- void formatSelection(const VisiblePosition& startOfSelection, const VisiblePosition& endOfSelection);
- void formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtr<Element>& blockquoteForNextIndent);
+ virtual void formatSelection(const VisiblePosition& startOfSelection, const VisiblePosition& endOfSelection) OVERRIDE;
+ virtual void formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtrWillBeRawPtr<Element>& blockquoteForNextIndent) OVERRIDE;
EIndentType m_typeOfAction;
- int m_marginInPixels;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/InputMethodController.cpp b/chromium/third_party/WebKit/Source/core/editing/InputMethodController.cpp
index 92eb55ab0a0..3e6b85ed89e 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InputMethodController.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/InputMethodController.cpp
@@ -34,11 +34,11 @@
#include "core/dom/Text.h"
#include "core/editing/Editor.h"
#include "core/editing/TypingCommand.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLTextAreaElement.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderObject.h"
namespace WebCore {
@@ -56,12 +56,12 @@ InputMethodController::SelectionOffsetsScope::~SelectionOffsetsScope()
// ----------------------------
-PassOwnPtr<InputMethodController> InputMethodController::create(Frame& frame)
+PassOwnPtr<InputMethodController> InputMethodController::create(LocalFrame& frame)
{
return adoptPtr(new InputMethodController(frame));
}
-InputMethodController::InputMethodController(Frame& frame)
+InputMethodController::InputMethodController(LocalFrame& frame)
: m_frame(frame)
, m_compositionStart(0)
, m_compositionEnd(0)
@@ -84,7 +84,7 @@ inline Editor& InputMethodController::editor() const
void InputMethodController::clear()
{
- m_compositionNode = 0;
+ m_compositionNode = nullptr;
m_customCompositionUnderlines.clear();
}
@@ -95,7 +95,7 @@ bool InputMethodController::insertTextForConfirmedComposition(const String& text
void InputMethodController::selectComposition() const
{
- RefPtr<Range> range = compositionRange();
+ RefPtrWillBeRawPtr<Range> range = compositionRange();
if (!range)
return;
@@ -192,7 +192,15 @@ bool InputMethodController::finishComposition(const String& text, FinishComposit
// We should send this event before sending a TextEvent as written in Section 6.2.2 and 6.2.3 of
// the DOM Event specification.
if (Element* target = m_frame.document()->focusedElement()) {
- RefPtr<CompositionEvent> event = CompositionEvent::create(EventTypeNames::compositionend, m_frame.domWindow(), text);
+ unsigned baseOffset = m_frame.selection().base().downstream().deprecatedEditingOffset();
+ Vector<CompositionUnderline> underlines;
+ for (size_t i = 0; i < m_customCompositionUnderlines.size(); ++i) {
+ CompositionUnderline underline = m_customCompositionUnderlines[i];
+ underline.startOffset -= baseOffset;
+ underline.endOffset -= baseOffset;
+ underlines.append(underline);
+ }
+ RefPtrWillBeRawPtr<CompositionEvent> event = CompositionEvent::create(EventTypeNames::compositionend, m_frame.domWindow(), text, underlines);
target->dispatchEvent(event, IGNORE_EXCEPTION);
}
@@ -203,7 +211,7 @@ bool InputMethodController::finishComposition(const String& text, FinishComposit
TypingCommand::deleteSelection(*m_frame.document(), 0);
}
- m_compositionNode = 0;
+ m_compositionNode = nullptr;
m_customCompositionUnderlines.clear();
insertTextForConfirmedComposition(text);
@@ -223,7 +231,7 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp
// Updates styles before setting selection for composition to prevent
// inserting the previous composition text into text nodes oddly.
// See https://bugs.webkit.org/show_bug.cgi?id=46868
- m_frame.document()->updateStyleIfNeeded();
+ m_frame.document()->updateRenderTreeIfNeeded();
selectComposition();
@@ -246,19 +254,19 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp
// 3. Canceling the ongoing composition.
// Send a compositionend event when function deletes the existing composition node, i.e.
// m_compositionNode != 0 && test.isEmpty().
- RefPtr<CompositionEvent> event;
+ RefPtrWillBeRawPtr<CompositionEvent> event = nullptr;
if (!hasComposition()) {
// We should send a compositionstart event only when the given text is not empty because this
// function doesn't create a composition node when the text is empty.
if (!text.isEmpty()) {
- target->dispatchEvent(CompositionEvent::create(EventTypeNames::compositionstart, m_frame.domWindow(), m_frame.selectedText()));
- event = CompositionEvent::create(EventTypeNames::compositionupdate, m_frame.domWindow(), text);
+ target->dispatchEvent(CompositionEvent::create(EventTypeNames::compositionstart, m_frame.domWindow(), m_frame.selectedText(), underlines));
+ event = CompositionEvent::create(EventTypeNames::compositionupdate, m_frame.domWindow(), text, underlines);
}
} else {
if (!text.isEmpty())
- event = CompositionEvent::create(EventTypeNames::compositionupdate, m_frame.domWindow(), text);
+ event = CompositionEvent::create(EventTypeNames::compositionupdate, m_frame.domWindow(), text, underlines);
else
- event = CompositionEvent::create(EventTypeNames::compositionend, m_frame.domWindow(), text);
+ event = CompositionEvent::create(EventTypeNames::compositionend, m_frame.domWindow(), text, underlines);
}
if (event.get())
target->dispatchEvent(event, IGNORE_EXCEPTION);
@@ -271,7 +279,7 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp
TypingCommand::deleteSelection(*m_frame.document(), TypingCommand::PreventSpellChecking);
}
- m_compositionNode = 0;
+ m_compositionNode = nullptr;
m_customCompositionUnderlines.clear();
if (!text.isEmpty()) {
@@ -297,23 +305,23 @@ void InputMethodController::setComposition(const String& text, const Vector<Comp
m_customCompositionUnderlines[i].endOffset += baseOffset;
}
if (baseNode->renderer())
- baseNode->renderer()->repaint();
+ baseNode->renderer()->paintInvalidationForWholeRenderer();
unsigned start = std::min(baseOffset + selectionStart, extentOffset);
unsigned end = std::min(std::max(start, baseOffset + selectionEnd), extentOffset);
- RefPtr<Range> selectedRange = Range::create(baseNode->document(), baseNode, start, baseNode, end);
- m_frame.selection().setSelectedRange(selectedRange.get(), DOWNSTREAM, false);
+ RefPtrWillBeRawPtr<Range> selectedRange = Range::create(baseNode->document(), baseNode, start, baseNode, end);
+ m_frame.selection().setSelectedRange(selectedRange.get(), DOWNSTREAM, FrameSelection::NonDirectional, NotUserTriggered);
}
}
}
void InputMethodController::setCompositionFromExistingText(const Vector<CompositionUnderline>& underlines, unsigned compositionStart, unsigned compositionEnd)
{
- Node* editable = m_frame.selection().rootEditableElement();
+ Element* editable = m_frame.selection().rootEditableElement();
Position base = m_frame.selection().base().downstream();
Node* baseNode = base.anchorNode();
if (editable->firstChild() == baseNode && editable->lastChild() == baseNode && baseNode->isTextNode()) {
- m_compositionNode = 0;
+ m_compositionNode = nullptr;
m_customCompositionUnderlines.clear();
if (base.anchorType() != Position::PositionIsOffsetInAnchor)
@@ -322,16 +330,17 @@ void InputMethodController::setCompositionFromExistingText(const Vector<Composit
return;
m_compositionNode = toText(baseNode);
- m_compositionStart = compositionStart;
- m_compositionEnd = compositionEnd;
+ RefPtrWillBeRawPtr<Range> range = PlainTextRange(compositionStart, compositionEnd).createRange(*editable);
+ m_compositionStart = range->startOffset();
+ m_compositionEnd = range->endOffset();
m_customCompositionUnderlines = underlines;
size_t numUnderlines = m_customCompositionUnderlines.size();
for (size_t i = 0; i < numUnderlines; ++i) {
- m_customCompositionUnderlines[i].startOffset += compositionStart;
- m_customCompositionUnderlines[i].endOffset += compositionStart;
+ m_customCompositionUnderlines[i].startOffset += m_compositionStart;
+ m_customCompositionUnderlines[i].endOffset += m_compositionStart;
}
if (baseNode->renderer())
- baseNode->renderer()->repaint();
+ baseNode->renderer()->paintInvalidationForWholeRenderer();
return;
}
@@ -341,21 +350,21 @@ void InputMethodController::setCompositionFromExistingText(const Vector<Composit
setComposition(m_frame.selectedText(), underlines, 0, 0);
}
-PassRefPtr<Range> InputMethodController::compositionRange() const
+PassRefPtrWillBeRawPtr<Range> InputMethodController::compositionRange() const
{
if (!hasComposition())
- return 0;
+ return nullptr;
unsigned length = m_compositionNode->length();
unsigned start = std::min(m_compositionStart, length);
unsigned end = std::min(std::max(start, m_compositionEnd), length);
if (start >= end)
- return 0;
+ return nullptr;
return Range::create(m_compositionNode->document(), m_compositionNode.get(), start, m_compositionNode.get(), end);
}
PlainTextRange InputMethodController::getSelectionOffsets() const
{
- RefPtr<Range> range = m_frame.selection().selection().firstRange();
+ RefPtrWillBeRawPtr<Range> range = m_frame.selection().selection().firstRange();
if (!range)
return PlainTextRange();
Node* editable = m_frame.selection().rootEditableElementOrTreeScopeRootNode();
@@ -371,11 +380,11 @@ bool InputMethodController::setSelectionOffsets(const PlainTextRange& selectionO
if (!rootEditableElement)
return false;
- RefPtr<Range> range = selectionOffsets.createRange(*rootEditableElement);
+ RefPtrWillBeRawPtr<Range> range = selectionOffsets.createRange(*rootEditableElement);
if (!range)
return false;
- return m_frame.selection().setSelectedRange(range.get(), VP_DEFAULT_AFFINITY, true);
+ return m_frame.selection().setSelectedRange(range.get(), VP_DEFAULT_AFFINITY, FrameSelection::NonDirectional, FrameSelection::CloseTyping);
}
bool InputMethodController::setEditableSelectionOffsets(const PlainTextRange& selectionOffsets)
diff --git a/chromium/third_party/WebKit/Source/core/editing/InputMethodController.h b/chromium/third_party/WebKit/Source/core/editing/InputMethodController.h
index 843cd8a8d07..946aeda4b2d 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InputMethodController.h
+++ b/chromium/third_party/WebKit/Source/core/editing/InputMethodController.h
@@ -34,7 +34,7 @@ namespace WebCore {
class Editor;
class EditorClient;
-class Frame;
+class LocalFrame;
class Range;
class Text;
@@ -46,7 +46,7 @@ public:
KeepSelection,
};
- static PassOwnPtr<InputMethodController> create(Frame&);
+ static PassOwnPtr<InputMethodController> create(LocalFrame&);
~InputMethodController();
// international text input composition
@@ -66,7 +66,7 @@ public:
// Deletes the existing composition text.
void cancelComposition();
void cancelCompositionIfSelectionIsInvalid();
- PassRefPtr<Range> compositionRange() const;
+ PassRefPtrWillBeRawPtr<Range> compositionRange() const;
// getting international text input composition state (for use by InlineTextBox)
Text* compositionNode() const { return m_compositionNode.get(); }
@@ -94,8 +94,8 @@ private:
};
friend class SelectionOffsetsScope;
- Frame& m_frame;
- RefPtr<Text> m_compositionNode;
+ LocalFrame& m_frame;
+ RefPtrWillBePersistent<Text> m_compositionNode;
// We don't use PlainTextRange which is immutable, for composition range.
unsigned m_compositionStart;
unsigned m_compositionEnd;
@@ -103,7 +103,7 @@ private:
// m_compositionNode.
Vector<CompositionUnderline> m_customCompositionUnderlines;
- explicit InputMethodController(Frame&);
+ explicit InputMethodController(LocalFrame&);
Editor& editor() const;
bool insertTextForConfirmedComposition(const String& text);
void selectComposition() const;
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.cpp
index 43790d9acbd..e515313b555 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.cpp
@@ -34,7 +34,7 @@
namespace WebCore {
-InsertIntoTextNodeCommand::InsertIntoTextNodeCommand(PassRefPtr<Text> node, unsigned offset, const String& text)
+InsertIntoTextNodeCommand::InsertIntoTextNodeCommand(PassRefPtrWillBeRawPtr<Text> node, unsigned offset, const String& text)
: SimpleEditCommand(node->document())
, m_node(node)
, m_offset(offset)
@@ -71,4 +71,10 @@ void InsertIntoTextNodeCommand::doUnapply()
m_node->deleteData(m_offset, m_text.length(), IGNORE_EXCEPTION, CharacterData::DeprecatedRecalcStyleImmediatlelyForEditing);
}
+void InsertIntoTextNodeCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_node);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.h b/chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.h
index 9764aa878d7..9796dd3525f 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertIntoTextNodeCommand.h
@@ -32,20 +32,22 @@ namespace WebCore {
class Text;
-class InsertIntoTextNodeCommand : public SimpleEditCommand {
+class InsertIntoTextNodeCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<InsertIntoTextNodeCommand> create(PassRefPtr<Text> node, unsigned offset, const String& text)
+ static PassRefPtrWillBeRawPtr<InsertIntoTextNodeCommand> create(PassRefPtrWillBeRawPtr<Text> node, unsigned offset, const String& text)
{
- return adoptRef(new InsertIntoTextNodeCommand(node, offset, text));
+ return adoptRefWillBeNoop(new InsertIntoTextNodeCommand(node, offset, text));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- InsertIntoTextNodeCommand(PassRefPtr<Text> node, unsigned offset, const String& text);
+ InsertIntoTextNodeCommand(PassRefPtrWillBeRawPtr<Text> node, unsigned offset, const String& text);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<Text> m_node;
+ RefPtrWillBeMember<Text> m_node;
unsigned m_offset;
String m_text;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.cpp
index cb4ad37a78a..bfd850e200c 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/editing/InsertLineBreakCommand.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/editing/EditingStyle.h"
@@ -34,9 +34,8 @@
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLElement.h"
-#include "core/html/HTMLTableElement.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderObject.h"
namespace WebCore {
@@ -53,30 +52,6 @@ bool InsertLineBreakCommand::preservesTypingStyle() const
return true;
}
-void InsertLineBreakCommand::insertNodeAfterPosition(Node* node, const Position& pos)
-{
- // Insert the BR after the caret position. In the case the
- // position is a block, do an append. We don't want to insert
- // the BR *after* the block.
- Element* cb = pos.deprecatedNode()->enclosingBlockFlowElement();
- if (cb == pos.deprecatedNode())
- appendNode(node, cb);
- else
- insertNodeAfter(node, pos.deprecatedNode());
-}
-
-void InsertLineBreakCommand::insertNodeBeforePosition(Node* node, const Position& pos)
-{
- // Insert the BR after the caret position. In the case the
- // position is a block, do an append. We don't want to insert
- // the BR *before* the block.
- Element* cb = pos.deprecatedNode()->enclosingBlockFlowElement();
- if (cb == pos.deprecatedNode())
- appendNode(node, cb);
- else
- insertNodeBefore(node, pos.deprecatedNode());
-}
-
// Whether we should insert a break element or a '\n'.
bool InsertLineBreakCommand::shouldUseBreakElement(const Position& insertionPos)
{
@@ -106,7 +81,7 @@ void InsertLineBreakCommand::doApply()
pos = positionOutsideTabSpan(pos);
- RefPtr<Node> nodeToInsert;
+ RefPtrWillBeRawPtr<Node> nodeToInsert = nullptr;
if (shouldUseBreakElement(pos))
nodeToInsert = createBreakElement(document());
else
@@ -115,7 +90,7 @@ void InsertLineBreakCommand::doApply()
// FIXME: Need to merge text nodes when inserting just after or before text.
if (isEndOfParagraph(caret) && !lineBreakExistsAtVisiblePosition(caret)) {
- bool needExtraLineBreak = !pos.deprecatedNode()->hasTagName(hrTag) && !isHTMLTableElement(pos.deprecatedNode());
+ bool needExtraLineBreak = !isHTMLHRElement(*pos.deprecatedNode()) && !isHTMLTableElement(*pos.deprecatedNode());
insertNodeAt(nodeToInsert.get(), pos);
@@ -128,15 +103,15 @@ void InsertLineBreakCommand::doApply()
insertNodeAt(nodeToInsert.get(), pos);
// Insert an extra br or '\n' if the just inserted one collapsed.
- if (!isStartOfParagraph(positionBeforeNode(nodeToInsert.get())))
+ if (!isStartOfParagraph(VisiblePosition(positionBeforeNode(nodeToInsert.get()))))
insertNodeBefore(nodeToInsert->cloneNode(false).get(), nodeToInsert.get());
- setEndingSelection(VisibleSelection(positionInParentAfterNode(nodeToInsert.get()), DOWNSTREAM, endingSelection().isDirectional()));
+ setEndingSelection(VisibleSelection(positionInParentAfterNode(*nodeToInsert), DOWNSTREAM, endingSelection().isDirectional()));
// If we're inserting after all of the rendered text in a text node, or into a non-text node,
// a simple insertion is sufficient.
} else if (pos.deprecatedEditingOffset() >= caretMaxOffset(pos.deprecatedNode()) || !pos.deprecatedNode()->isTextNode()) {
insertNodeAt(nodeToInsert.get(), pos);
- setEndingSelection(VisibleSelection(positionInParentAfterNode(nodeToInsert.get()), DOWNSTREAM, endingSelection().isDirectional()));
+ setEndingSelection(VisibleSelection(positionInParentAfterNode(*nodeToInsert), DOWNSTREAM, endingSelection().isDirectional()));
} else if (pos.deprecatedNode()->isTextNode()) {
// Split a text node
Text* textNode = toText(pos.deprecatedNode());
@@ -147,7 +122,7 @@ void InsertLineBreakCommand::doApply()
// Handle whitespace that occurs after the split
document().updateLayoutIgnorePendingStylesheets();
if (!endingPosition.isRenderedCharacter()) {
- Position positionBeforeTextNode(positionInParentBeforeNode(textNode));
+ Position positionBeforeTextNode(positionInParentBeforeNode(*textNode));
// Clear out all whitespace and insert one non-breaking space
deleteInsignificantTextDownstream(endingPosition);
ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace());
@@ -155,7 +130,7 @@ void InsertLineBreakCommand::doApply()
if (textNode->inDocument())
insertTextIntoNode(textNode, 0, nonBreakingSpaceString());
else {
- RefPtr<Text> nbspNode = document().createTextNode(nonBreakingSpaceString());
+ RefPtrWillBeRawPtr<Text> nbspNode = document().createTextNode(nonBreakingSpaceString());
insertNodeAt(nbspNode.get(), positionBeforeTextNode);
endingPosition = firstPositionInNode(nbspNode.get());
}
@@ -166,7 +141,7 @@ void InsertLineBreakCommand::doApply()
// Handle the case where there is a typing style.
- RefPtr<EditingStyle> typingStyle = document().frame()->selection().typingStyle();
+ RefPtrWillBeRawPtr<EditingStyle> typingStyle = document().frame()->selection().typingStyle();
if (typingStyle && !typingStyle->isEmpty()) {
// Apply the typing style to the inserted line break, so that if the selection
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.h b/chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.h
index 6eee0e0d595..1db2918320d 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertLineBreakCommand.h
@@ -30,22 +30,20 @@
namespace WebCore {
-class InsertLineBreakCommand : public CompositeEditCommand {
+class InsertLineBreakCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<InsertLineBreakCommand> create(Document& document)
+ static PassRefPtrWillBeRawPtr<InsertLineBreakCommand> create(Document& document)
{
- return adoptRef(new InsertLineBreakCommand(document));
+ return adoptRefWillBeNoop(new InsertLineBreakCommand(document));
}
private:
explicit InsertLineBreakCommand(Document&);
- virtual void doApply();
+ virtual void doApply() OVERRIDE;
- virtual bool preservesTypingStyle() const;
+ virtual bool preservesTypingStyle() const OVERRIDE;
- void insertNodeAfterPosition(Node*, const Position&);
- void insertNodeBeforePosition(Node*, const Position&);
bool shouldUseBreakElement(const Position&);
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertListCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/InsertListCommand.cpp
index aff29397f9c..0d07431ba83 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertListCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertListCommand.cpp
@@ -26,9 +26,11 @@
#include "config.h"
#include "core/editing/InsertListCommand.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
#include "core/editing/TextIterator.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
@@ -46,16 +48,9 @@ static Node* enclosingListChild(Node* node, Node* listNode)
return listChild;
}
-PassRefPtr<HTMLElement> InsertListCommand::insertList(Document& document, Type type)
-{
- RefPtr<InsertListCommand> insertCommand = create(document, type);
- insertCommand->apply();
- return insertCommand->m_listElement;
-}
-
HTMLElement* InsertListCommand::fixOrphanedListChild(Node* node)
{
- RefPtr<HTMLElement> listElement = createUnorderedListElement(document());
+ RefPtrWillBeRawPtr<HTMLElement> listElement = createUnorderedListElement(document());
insertNodeBefore(listElement, node);
removeNode(node);
appendNode(node, listElement);
@@ -63,17 +58,21 @@ HTMLElement* InsertListCommand::fixOrphanedListChild(Node* node)
return listElement.get();
}
-PassRefPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtr<HTMLElement> passedList)
+PassRefPtrWillBeRawPtr<HTMLElement> InsertListCommand::mergeWithNeighboringLists(PassRefPtrWillBeRawPtr<HTMLElement> passedList)
{
- RefPtr<HTMLElement> list = passedList;
- Element* previousList = list->previousElementSibling();
+ RefPtrWillBeRawPtr<HTMLElement> list = passedList;
+ Element* previousList = ElementTraversal::previousSibling(*list);
if (canMergeLists(previousList, list.get()))
mergeIdenticalElements(previousList, list);
- if (!list || !list->nextElementSibling() || !list->nextElementSibling()->isHTMLElement())
+ if (!list)
+ return nullptr;
+
+ Element* nextSibling = ElementTraversal::nextSibling(*list);
+ if (!nextSibling || !nextSibling->isHTMLElement())
return list.release();
- RefPtr<HTMLElement> nextList = toHTMLElement(list->nextElementSibling());
+ RefPtrWillBeRawPtr<HTMLElement> nextList = toHTMLElement(nextSibling);
if (canMergeLists(list.get(), nextList.get())) {
mergeIdenticalElements(list, nextList);
return nextList.release();
@@ -122,8 +121,11 @@ void InsertListCommand::doApply()
// FIXME: We paint the gap before some paragraphs that are indented with left
// margin/padding, but not others. We should make the gap painting more consistent and
// then use a left margin/padding rule here.
- if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOverEditingBoundary))
+ if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOverEditingBoundary)) {
setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(CannotCrossEditingBoundary), endingSelection().isDirectional()));
+ if (!endingSelection().rootEditableElement())
+ return;
+ }
const QualifiedName& listTag = (m_type == OrderedList) ? olTag : ulTag;
if (endingSelection().isRange()) {
@@ -134,13 +136,13 @@ void InsertListCommand::doApply()
VisiblePosition startOfLastParagraph = startOfParagraph(endOfSelection, CanSkipOverEditingBoundary);
if (startOfParagraph(startOfSelection, CanSkipOverEditingBoundary) != startOfLastParagraph) {
- RefPtr<ContainerNode> scope;
+ RefPtrWillBeRawPtr<ContainerNode> scope = nullptr;
int indexForEndOfSelection = indexForVisiblePosition(endOfSelection, scope);
bool forceCreateList = !selectionHasListOfType(selection, listTag);
- RefPtr<Range> currentSelection = endingSelection().firstRange();
+ RefPtrWillBeRawPtr<Range> currentSelection = endingSelection().firstRange();
VisiblePosition startOfCurrentParagraph = startOfSelection;
- while (!inSameParagraph(startOfCurrentParagraph, startOfLastParagraph, CanCrossEditingBoundary)) {
+ while (startOfCurrentParagraph.isNotNull() && !inSameParagraph(startOfCurrentParagraph, startOfLastParagraph, CanCrossEditingBoundary)) {
// doApply() may operate on and remove the last paragraph of the selection from the document
// if it's in the same list item as startOfCurrentParagraph. Return early to avoid an
// infinite loop and because there is no more work to be done.
@@ -155,7 +157,7 @@ void InsertListCommand::doApply()
// FIXME: This is an inefficient way to keep selection alive because indexForVisiblePosition walks from
// the beginning of the document to the endOfSelection everytime this code is executed.
// But not using index is hard because there are so many ways we can lose selection inside doApplyForSingleParagraph.
- doApplyForSingleParagraph(forceCreateList, listTag, currentSelection.get());
+ doApplyForSingleParagraph(forceCreateList, listTag, *currentSelection);
if (endOfSelection.isNull() || endOfSelection.isOrphan() || startOfLastParagraph.isNull() || startOfLastParagraph.isOrphan()) {
endOfSelection = visiblePositionForIndex(indexForEndOfSelection, scope.get());
// If endOfSelection is null, then some contents have been deleted from the document.
@@ -176,7 +178,7 @@ void InsertListCommand::doApply()
startOfCurrentParagraph = startOfNextParagraph(endingSelection().visibleStart());
}
setEndingSelection(endOfSelection);
- doApplyForSingleParagraph(forceCreateList, listTag, currentSelection.get());
+ doApplyForSingleParagraph(forceCreateList, listTag, *currentSelection);
// Fetch the end of the selection, for the reason mentioned above.
if (endOfSelection.isNull() || endOfSelection.isOrphan()) {
endOfSelection = visiblePositionForIndex(indexForEndOfSelection, scope.get());
@@ -188,10 +190,11 @@ void InsertListCommand::doApply()
}
}
- doApplyForSingleParagraph(false, listTag, endingSelection().firstRange().get());
+ ASSERT(endingSelection().firstRange());
+ doApplyForSingleParagraph(false, listTag, *endingSelection().firstRange());
}
-void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const QualifiedName& listTag, Range* currentSelection)
+void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const QualifiedName& listTag, Range& currentSelection)
{
// FIXME: This will produce unexpected results for a selection that starts just before a
// table and ends inside the first cell, selectionForParagraphIteration should probably
@@ -201,7 +204,7 @@ void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu
bool switchListType = false;
if (listChildNode) {
// Remove the list chlild.
- RefPtr<HTMLElement> listNode = enclosingList(listChildNode);
+ RefPtrWillBeRawPtr<HTMLElement> listNode = enclosingList(listChildNode);
if (!listNode) {
listNode = fixOrphanedListChild(listChildNode);
listNode = mergeWithNeighboringLists(listNode);
@@ -215,17 +218,17 @@ void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu
return;
// If the entire list is selected, then convert the whole list.
- if (switchListType && isNodeVisiblyContainedWithin(listNode.get(), currentSelection)) {
- bool rangeStartIsInList = visiblePositionBeforeNode(listNode.get()) == currentSelection->startPosition();
- bool rangeEndIsInList = visiblePositionAfterNode(listNode.get()) == currentSelection->endPosition();
+ if (switchListType && isNodeVisiblyContainedWithin(*listNode, currentSelection)) {
+ bool rangeStartIsInList = visiblePositionBeforeNode(*listNode) == VisiblePosition(currentSelection.startPosition());
+ bool rangeEndIsInList = visiblePositionAfterNode(*listNode) == VisiblePosition(currentSelection.endPosition());
- RefPtr<HTMLElement> newList = createHTMLElement(document(), listTag);
+ RefPtrWillBeRawPtr<HTMLElement> newList = createHTMLElement(document(), listTag);
insertNodeBefore(newList, listNode);
Node* firstChildInList = enclosingListChild(VisiblePosition(firstPositionInNode(listNode.get())).deepEquivalent().deprecatedNode(), listNode.get());
- Node* outerBlock = firstChildInList->isBlockFlowElement() ? firstChildInList : listNode.get();
+ Node* outerBlock = firstChildInList && firstChildInList->isBlockFlowElement() ? firstChildInList : listNode.get();
- moveParagraphWithClones(firstPositionInNode(listNode.get()), lastPositionInNode(listNode.get()), newList.get(), outerBlock);
+ moveParagraphWithClones(VisiblePosition(firstPositionInNode(listNode.get())), VisiblePosition(lastPositionInNode(listNode.get())), newList.get(), outerBlock);
// Manually remove listNode because moveParagraphWithClones sometimes leaves it behind in the document.
// See the bug 33668 and editing/execCommand/insert-list-orphaned-item-with-nested-lists.html.
@@ -238,9 +241,9 @@ void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const Qu
// Restore the start and the end of current selection if they started inside listNode
// because moveParagraphWithClones could have removed them.
if (rangeStartIsInList && newList)
- currentSelection->setStart(newList, 0, IGNORE_EXCEPTION);
+ currentSelection.setStart(newList, 0, IGNORE_EXCEPTION);
if (rangeEndIsInList && newList)
- currentSelection->setEnd(newList, lastOffsetInNode(newList.get()), IGNORE_EXCEPTION);
+ currentSelection.setEnd(newList, lastOffsetInNode(newList.get()), IGNORE_EXCEPTION);
setEndingSelection(VisiblePosition(firstPositionInNode(newList.get())));
@@ -260,9 +263,10 @@ void InsertListCommand::unlistifyParagraph(const VisiblePosition& originalStart,
Node* previousListChild;
VisiblePosition start;
VisiblePosition end;
- if (listChildNode->hasTagName(liTag)) {
- start = firstPositionInNode(listChildNode);
- end = lastPositionInNode(listChildNode);
+ ASSERT(listChildNode);
+ if (isHTMLLIElement(*listChildNode)) {
+ start = VisiblePosition(firstPositionInNode(listChildNode));
+ end = VisiblePosition(lastPositionInNode(listChildNode));
nextListChild = listChildNode->nextSibling();
previousListChild = listChildNode->previousSibling();
} else {
@@ -276,8 +280,8 @@ void InsertListCommand::unlistifyParagraph(const VisiblePosition& originalStart,
}
// When removing a list, we must always create a placeholder to act as a point of insertion
// for the list content being removed.
- RefPtr<Element> placeholder = createBreakElement(document());
- RefPtr<Element> nodeToInsert = placeholder;
+ RefPtrWillBeRawPtr<Element> placeholder = createBreakElement(document());
+ RefPtrWillBeRawPtr<Element> nodeToInsert = placeholder;
// If the content of the list item will be moved into another list, put it in a list item
// so that we don't create an orphaned list child.
if (enclosingList(listNode)) {
@@ -329,23 +333,23 @@ static Element* adjacentEnclosingList(const VisiblePosition& pos, const VisibleP
return listNode;
}
-PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag)
+PassRefPtrWillBeRawPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag)
{
VisiblePosition start = startOfParagraph(originalStart, CanSkipOverEditingBoundary);
VisiblePosition end = endOfParagraph(start, CanSkipOverEditingBoundary);
if (start.isNull() || end.isNull())
- return 0;
+ return nullptr;
// Check for adjoining lists.
- RefPtr<HTMLElement> listItemElement = createListItemElement(document());
- RefPtr<HTMLElement> placeholder = createBreakElement(document());
+ RefPtrWillBeRawPtr<HTMLElement> listItemElement = createListItemElement(document());
+ RefPtrWillBeRawPtr<HTMLElement> placeholder = createBreakElement(document());
appendNode(placeholder, listItemElement);
// Place list item into adjoining lists.
- Element* previousList = adjacentEnclosingList(start.deepEquivalent(), start.previous(CannotCrossEditingBoundary), listTag);
- Element* nextList = adjacentEnclosingList(start.deepEquivalent(), end.next(CannotCrossEditingBoundary), listTag);
- RefPtr<HTMLElement> listElement;
+ Element* previousList = adjacentEnclosingList(start, start.previous(CannotCrossEditingBoundary), listTag);
+ Element* nextList = adjacentEnclosingList(start, end.next(CannotCrossEditingBoundary), listTag);
+ RefPtrWillBeRawPtr<HTMLElement> listElement = nullptr;
if (previousList)
appendNode(listItemElement, previousList);
else if (nextList)
@@ -359,8 +363,8 @@ PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio
// Inserting the list into an empty paragraph that isn't held open
// by a br or a '\n', will invalidate start and end. Insert
// a placeholder and then recompute start and end.
- RefPtr<Node> placeholder = insertBlockPlaceholder(start.deepEquivalent());
- start = positionBeforeNode(placeholder.get());
+ RefPtrWillBeRawPtr<Node> placeholder = insertBlockPlaceholder(start.deepEquivalent());
+ start = VisiblePosition(positionBeforeNode(placeholder.get()));
end = start;
}
@@ -372,8 +376,8 @@ PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio
Position insertionPos(start.deepEquivalent().upstream());
// Also avoid the containing list item.
Node* listChild = enclosingListChild(insertionPos.deprecatedNode());
- if (listChild && listChild->hasTagName(liTag))
- insertionPos = positionInParentBeforeNode(listChild);
+ if (isHTMLLIElement(listChild))
+ insertionPos = positionInParentBeforeNode(*listChild);
insertNodeAt(listElement, insertionPos);
@@ -381,14 +385,16 @@ PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio
// Update the start of content, so we don't try to move the list into itself. bug 19066
// Layout is necessary since start's node's inline renderers may have been destroyed by the insertion
// The end of the content may have changed after the insertion and layout so update it as well.
- if (insertionPos == start.deepEquivalent()) {
- listElement->document().updateLayoutIgnorePendingStylesheets();
- start = startOfParagraph(originalStart, CanSkipOverEditingBoundary);
- end = endOfParagraph(start, CanSkipOverEditingBoundary);
- }
+ if (insertionPos == start.deepEquivalent())
+ start = originalStart;
}
- moveParagraph(start, end, positionBeforeNode(placeholder.get()), true);
+ // Inserting list element and list item list may change start of pargraph
+ // to move. We calculate start of paragraph again.
+ document().updateLayoutIgnorePendingStylesheets();
+ start = startOfParagraph(start, CanSkipOverEditingBoundary);
+ end = endOfParagraph(start, CanSkipOverEditingBoundary);
+ moveParagraph(start, end, VisiblePosition(positionBeforeNode(placeholder.get())), true);
if (listElement)
return mergeWithNeighboringLists(listElement);
@@ -399,4 +405,10 @@ PassRefPtr<HTMLElement> InsertListCommand::listifyParagraph(const VisiblePositio
return listElement;
}
+void InsertListCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_listElement);
+ CompositeEditCommand::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertListCommand.h b/chromium/third_party/WebKit/Source/core/editing/InsertListCommand.h
index 80933b253d2..23f1f9c13ac 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertListCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertListCommand.h
@@ -32,32 +32,33 @@ namespace WebCore {
class HTMLElement;
-class InsertListCommand : public CompositeEditCommand {
+class InsertListCommand FINAL : public CompositeEditCommand {
public:
enum Type { OrderedList, UnorderedList };
- static PassRefPtr<InsertListCommand> create(Document& document, Type listType)
+ static PassRefPtrWillBeRawPtr<InsertListCommand> create(Document& document, Type listType)
{
- return adoptRef(new InsertListCommand(document, listType));
+ return adoptRefWillBeNoop(new InsertListCommand(document, listType));
}
- static PassRefPtr<HTMLElement> insertList(Document&, Type);
+ virtual bool preservesTypingStyle() const OVERRIDE { return true; }
- virtual bool preservesTypingStyle() const { return true; }
+ virtual void trace(Visitor*) OVERRIDE;
private:
InsertListCommand(Document&, Type);
- virtual void doApply();
- virtual EditAction editingAction() const { return EditActionInsertList; }
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE { return EditActionInsertList; }
HTMLElement* fixOrphanedListChild(Node*);
bool selectionHasListOfType(const VisibleSelection& selection, const QualifiedName&);
- PassRefPtr<HTMLElement> mergeWithNeighboringLists(PassRefPtr<HTMLElement>);
- void doApplyForSingleParagraph(bool forceCreateList, const QualifiedName&, Range* currentSelection);
+ PassRefPtrWillBeRawPtr<HTMLElement> mergeWithNeighboringLists(PassRefPtrWillBeRawPtr<HTMLElement>);
+ void doApplyForSingleParagraph(bool forceCreateList, const QualifiedName&, Range& currentSelection);
void unlistifyParagraph(const VisiblePosition& originalStart, HTMLElement* listNode, Node* listChildNode);
- PassRefPtr<HTMLElement> listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag);
- RefPtr<HTMLElement> m_listElement;
+ PassRefPtrWillBeRawPtr<HTMLElement> listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag);
+
+ RefPtrWillBeMember<HTMLElement> m_listElement;
Type m_type;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.cpp
index 862d541033e..ef3628a97ae 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-InsertNodeBeforeCommand::InsertNodeBeforeCommand(PassRefPtr<Node> insertChild, PassRefPtr<Node> refChild,
+InsertNodeBeforeCommand::InsertNodeBeforeCommand(PassRefPtrWillBeRawPtr<Node> insertChild, PassRefPtrWillBeRawPtr<Node> refChild,
ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
: SimpleEditCommand(refChild->document())
, m_insertChild(insertChild)
@@ -64,4 +64,11 @@ void InsertNodeBeforeCommand::doUnapply()
m_insertChild->remove(IGNORE_EXCEPTION);
}
+void InsertNodeBeforeCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_insertChild);
+ visitor->trace(m_refChild);
+ SimpleEditCommand::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.h b/chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.h
index 6fc3b3c55b5..b5ad47e9ce3 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertNodeBeforeCommand.h
@@ -30,22 +30,24 @@
namespace WebCore {
-class InsertNodeBeforeCommand : public SimpleEditCommand {
+class InsertNodeBeforeCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<InsertNodeBeforeCommand> create(PassRefPtr<Node> childToInsert, PassRefPtr<Node> childToInsertBefore,
+ static PassRefPtrWillBeRawPtr<InsertNodeBeforeCommand> create(PassRefPtrWillBeRawPtr<Node> childToInsert, PassRefPtrWillBeRawPtr<Node> childToInsertBefore,
ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
- return adoptRef(new InsertNodeBeforeCommand(childToInsert, childToInsertBefore, shouldAssumeContentIsAlwaysEditable));
+ return adoptRefWillBeNoop(new InsertNodeBeforeCommand(childToInsert, childToInsertBefore, shouldAssumeContentIsAlwaysEditable));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- InsertNodeBeforeCommand(PassRefPtr<Node> childToInsert, PassRefPtr<Node> childToInsertBefore, ShouldAssumeContentIsAlwaysEditable);
+ InsertNodeBeforeCommand(PassRefPtrWillBeRawPtr<Node> childToInsert, PassRefPtrWillBeRawPtr<Node> childToInsertBefore, ShouldAssumeContentIsAlwaysEditable);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<Node> m_insertChild;
- RefPtr<Node> m_refChild;
+ RefPtrWillBeMember<Node> m_insertChild;
+ RefPtrWillBeMember<Node> m_refChild;
ShouldAssumeContentIsAlwaysEditable m_shouldAssumeContentIsAlwaysEditable;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.cpp
index 9ad4234a4bb..35984a35bc1 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/editing/InsertParagraphSeparatorCommand.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/Text.h"
@@ -50,7 +50,7 @@ static Element* highestVisuallyEquivalentDivBelowRoot(Element* startBlock)
Element* curBlock = startBlock;
// We don't want to return a root node (if it happens to be a div, e.g., in a document fragment) because there are no
// siblings for us to append to.
- while (!curBlock->nextSibling() && curBlock->parentElement()->hasTagName(divTag) && curBlock->parentElement()->parentElement()) {
+ while (!curBlock->nextSibling() && isHTMLDivElement(*curBlock->parentElement()) && curBlock->parentElement()->parentElement()) {
if (curBlock->parentElement()->hasAttributes())
break;
curBlock = curBlock->parentElement();
@@ -119,7 +119,7 @@ bool InsertParagraphSeparatorCommand::shouldUseDefaultParagraphElement(Node* enc
enclosingBlock->hasTagName(h5Tag);
}
-void InsertParagraphSeparatorCommand::getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, Vector<RefPtr<Element> >& ancestors)
+void InsertParagraphSeparatorCommand::getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, WillBeHeapVector<RefPtrWillBeMember<Element> >& ancestors)
{
ancestors.clear();
@@ -130,12 +130,12 @@ void InsertParagraphSeparatorCommand::getAncestorsInsideBlock(const Node* insert
}
}
-PassRefPtr<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock(const Vector<RefPtr<Element> >& ancestors, PassRefPtr<Element> blockToInsert)
+PassRefPtrWillBeRawPtr<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock(const WillBeHeapVector<RefPtrWillBeMember<Element> >& ancestors, PassRefPtrWillBeRawPtr<Element> blockToInsert)
{
// Make clones of ancestors in between the start node and the start block.
- RefPtr<Element> parent = blockToInsert;
+ RefPtrWillBeRawPtr<Element> parent = blockToInsert;
for (size_t i = ancestors.size(); i != 0; --i) {
- RefPtr<Element> child = ancestors[i - 1]->cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> child = ancestors[i - 1]->cloneElementWithoutChildren();
// It should always be okay to remove id from the cloned elements, since the originals are not deleted.
child->removeAttribute(idAttr);
appendNode(child, parent);
@@ -163,17 +163,17 @@ void InsertParagraphSeparatorCommand::doApply()
}
// FIXME: The parentAnchoredEquivalent conversion needs to be moved into enclosingBlock.
- RefPtr<Element> startBlock = enclosingBlock(insertionPosition.parentAnchoredEquivalent().containerNode());
+ RefPtrWillBeRawPtr<Element> startBlock = enclosingBlock(insertionPosition.parentAnchoredEquivalent().containerNode());
Node* listChildNode = enclosingListChild(insertionPosition.parentAnchoredEquivalent().containerNode());
- RefPtr<Element> listChild = listChildNode && listChildNode->isHTMLElement() ? toHTMLElement(listChildNode) : 0;
+ RefPtrWillBeRawPtr<Element> listChild = listChildNode && listChildNode->isHTMLElement() ? toHTMLElement(listChildNode) : 0;
Position canonicalPos = VisiblePosition(insertionPosition).deepEquivalent();
if (!startBlock
|| !startBlock->nonShadowBoundaryParentNode()
|| isTableCell(startBlock.get())
- || startBlock->hasTagName(formTag)
+ || isHTMLFormElement(*startBlock)
// FIXME: If the node is hidden, we don't have a canonical position so we will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.cgi?id=40342
|| (!canonicalPos.isNull() && isRenderedTable(canonicalPos.deprecatedNode()))
- || (!canonicalPos.isNull() && canonicalPos.deprecatedNode()->hasTagName(hrTag))) {
+ || (!canonicalPos.isNull() && isHTMLHRElement(*canonicalPos.deprecatedNode()))) {
applyCommandToComposite(InsertLineBreakCommand::create(document()));
return;
}
@@ -201,7 +201,7 @@ void InsertParagraphSeparatorCommand::doApply()
bool nestNewBlock = false;
// Create block to be inserted.
- RefPtr<Element> blockToInsert;
+ RefPtrWillBeRawPtr<Element> blockToInsert = nullptr;
if (startBlock->isRootEditableElement()) {
blockToInsert = createDefaultParagraphElement(document());
nestNewBlock = true;
@@ -219,7 +219,7 @@ void InsertParagraphSeparatorCommand::doApply()
if (isFirstInBlock && !lineBreakExistsAtVisiblePosition(visiblePos)) {
// The block is empty. Create an empty block to
// represent the paragraph that we're leaving.
- RefPtr<Element> extraBlock = createDefaultParagraphElement(document());
+ RefPtrWillBeRawPtr<Element> extraBlock = createDefaultParagraphElement(document());
appendNode(extraBlock, startBlock);
appendBlockPlaceholder(extraBlock);
}
@@ -233,14 +233,14 @@ void InsertParagraphSeparatorCommand::doApply()
}
if (listChild && listChild != startBlock) {
- RefPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
appendNode(blockToInsert, listChildToInsert.get());
insertNodeAfter(listChildToInsert.get(), listChild);
} else {
// Most of the time we want to stay at the nesting level of the startBlock (e.g., when nesting within lists). However,
// for div nodes, this can result in nested div tags that are hard to break out of.
Element* siblingNode = startBlock.get();
- if (blockToInsert->hasTagName(divTag))
+ if (isHTMLDivElement(*blockToInsert))
siblingNode = highestVisuallyEquivalentDivBelowRoot(startBlock.get());
insertNodeAfter(blockToInsert, siblingNode);
}
@@ -248,9 +248,9 @@ void InsertParagraphSeparatorCommand::doApply()
// Recreate the same structure in the new paragraph.
- Vector<RefPtr<Element> > ancestors;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > ancestors;
getAncestorsInsideBlock(positionOutsideTabSpan(insertionPosition).deprecatedNode(), startBlock.get(), ancestors);
- RefPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToInsert);
+ RefPtrWillBeRawPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToInsert);
appendBlockPlaceholder(parent);
@@ -268,7 +268,7 @@ void InsertParagraphSeparatorCommand::doApply()
if (isFirstInBlock && !nestNewBlock) {
if (listChild && listChild != startBlock) {
- RefPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
appendNode(blockToInsert, listChildToInsert.get());
insertNodeBefore(listChildToInsert.get(), listChild);
} else {
@@ -280,7 +280,7 @@ void InsertParagraphSeparatorCommand::doApply()
refNode = startBlock->firstChild();
}
else if (insertionPosition.deprecatedNode() == startBlock && nestNewBlock) {
- refNode = startBlock->childNode(insertionPosition.deprecatedEditingOffset());
+ refNode = startBlock->traverseToChildAt(insertionPosition.deprecatedEditingOffset());
ASSERT(refNode); // must be true or we'd be in the end of block case
} else
refNode = insertionPosition.deprecatedNode();
@@ -293,7 +293,7 @@ void InsertParagraphSeparatorCommand::doApply()
// Recreate the same structure in the new paragraph.
- Vector<RefPtr<Element> > ancestors;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > ancestors;
getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(positionOutsideTabSpan(insertionPosition)).deprecatedNode(), startBlock.get(), ancestors);
appendBlockPlaceholder(cloneHierarchyUnderNewBlock(ancestors, blockToInsert));
@@ -311,9 +311,9 @@ void InsertParagraphSeparatorCommand::doApply()
// it if visiblePos is at the start of a paragraph so that the
// content will move down a line.
if (isStartOfParagraph(visiblePos)) {
- RefPtr<Element> br = createBreakElement(document());
+ RefPtrWillBeRawPtr<Element> br = createBreakElement(document());
insertNodeAt(br.get(), insertionPosition);
- insertionPosition = positionInParentAfterNode(br.get());
+ insertionPosition = positionInParentAfterNode(*br);
// If the insertion point is a break element, there is nothing else
// we need to do.
if (visiblePos.deepEquivalent().anchorNode()->renderer()->isBR()) {
@@ -354,7 +354,7 @@ void InsertParagraphSeparatorCommand::doApply()
// Split at pos if in the middle of a text node.
Position positionAfterSplit;
if (insertionPosition.anchorType() == Position::PositionIsOffsetInAnchor && insertionPosition.containerNode()->isTextNode()) {
- RefPtr<Text> textNode = toText(insertionPosition.containerNode());
+ RefPtrWillBeRawPtr<Text> textNode = toText(insertionPosition.containerNode());
bool atEnd = static_cast<unsigned>(insertionPosition.offsetInContainerNode()) >= textNode->length();
if (insertionPosition.deprecatedEditingOffset() > 0 && !atEnd) {
splitTextNode(textNode, insertionPosition.offsetInContainerNode());
@@ -372,7 +372,7 @@ void InsertParagraphSeparatorCommand::doApply()
if (nestNewBlock) {
appendNode(blockToInsert.get(), startBlock);
} else if (listChild && listChild != startBlock) {
- RefPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
+ RefPtrWillBeRawPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
appendNode(blockToInsert.get(), listChildToInsert.get());
insertNodeAfter(listChildToInsert.get(), listChild);
} else {
@@ -400,7 +400,7 @@ void InsertParagraphSeparatorCommand::doApply()
splitTreeToNode(splitTo, startBlock.get());
for (n = startBlock->firstChild(); n; n = n->nextSibling()) {
- VisiblePosition beforeNodePosition = positionBeforeNode(n);
+ VisiblePosition beforeNodePosition(positionBeforeNode(n));
if (!beforeNodePosition.isNull() && comparePositions(VisiblePosition(insertionPosition), beforeNodePosition) <= 0)
break;
}
@@ -425,4 +425,11 @@ void InsertParagraphSeparatorCommand::doApply()
applyStyleAfterInsertion(startBlock.get());
}
+void InsertParagraphSeparatorCommand::trace(Visitor *visitor)
+{
+ visitor->trace(m_style);
+ CompositeEditCommand::trace(visitor);
+}
+
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.h b/chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.h
index 57f32b3292c..9eb51922ac4 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertParagraphSeparatorCommand.h
@@ -32,28 +32,30 @@ namespace WebCore {
class EditingStyle;
-class InsertParagraphSeparatorCommand : public CompositeEditCommand {
+class InsertParagraphSeparatorCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<InsertParagraphSeparatorCommand> create(Document& document, bool useDefaultParagraphElement = false, bool pasteBlockqutoeIntoUnquotedArea = false)
+ static PassRefPtrWillBeRawPtr<InsertParagraphSeparatorCommand> create(Document& document, bool useDefaultParagraphElement = false, bool pasteBlockqutoeIntoUnquotedArea = false)
{
- return adoptRef(new InsertParagraphSeparatorCommand(document, useDefaultParagraphElement, pasteBlockqutoeIntoUnquotedArea));
+ return adoptRefWillBeNoop(new InsertParagraphSeparatorCommand(document, useDefaultParagraphElement, pasteBlockqutoeIntoUnquotedArea));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
InsertParagraphSeparatorCommand(Document&, bool useDefaultParagraphElement, bool pasteBlockqutoeIntoUnquotedArea);
- virtual void doApply();
+ virtual void doApply() OVERRIDE;
void calculateStyleBeforeInsertion(const Position&);
void applyStyleAfterInsertion(Node* originalEnclosingBlock);
- void getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, Vector<RefPtr<Element> >& ancestors);
- PassRefPtr<Element> cloneHierarchyUnderNewBlock(const Vector<RefPtr<Element> >& ancestors, PassRefPtr<Element> blockToInsert);
+ void getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, WillBeHeapVector<RefPtrWillBeMember<Element> >& ancestors);
+ PassRefPtrWillBeRawPtr<Element> cloneHierarchyUnderNewBlock(const WillBeHeapVector<RefPtrWillBeMember<Element> >& ancestors, PassRefPtrWillBeRawPtr<Element> blockToInsert);
bool shouldUseDefaultParagraphElement(Node*) const;
- virtual bool preservesTypingStyle() const;
+ virtual bool preservesTypingStyle() const OVERRIDE;
- RefPtr<EditingStyle> m_style;
+ RefPtrWillBeMember<EditingStyle> m_style;
bool m_mustUseDefaultParagraphElement;
bool m_pasteBlockqutoeIntoUnquotedArea;
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.cpp
index 8a489403ed0..2dfd6d365de 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.cpp
@@ -32,7 +32,7 @@
#include "core/editing/Editor.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
@@ -44,20 +44,11 @@ InsertTextCommand::InsertTextCommand(Document& document, const String& text, boo
{
}
-InsertTextCommand::InsertTextCommand(Document& document, const String& text, PassRefPtr<TextInsertionMarkerSupplier> markerSupplier)
- : CompositeEditCommand(document)
- , m_text(text)
- , m_selectInsertedText(false)
- , m_rebalanceType(RebalanceLeadingAndTrailingWhitespaces)
- , m_markerSupplier(markerSupplier)
-{
-}
-
Position InsertTextCommand::positionInsideTextNode(const Position& p)
{
Position pos = p;
if (isTabSpanTextNode(pos.anchorNode())) {
- RefPtr<Node> textNode = document().createEditingTextNode("");
+ RefPtrWillBeRawPtr<Node> textNode = document().createEditingTextNode("");
insertNodeAtTabSpanPosition(textNode.get(), pos);
return firstPositionInNode(textNode.get());
}
@@ -65,7 +56,7 @@ Position InsertTextCommand::positionInsideTextNode(const Position& p)
// Prepare for text input by looking at the specified position.
// It may be necessary to insert a text node to receive characters.
if (!pos.containerNode()->isTextNode()) {
- RefPtr<Node> textNode = document().createEditingTextNode("");
+ RefPtrWillBeRawPtr<Node> textNode = document().createEditingTextNode("");
insertNodeAt(textNode.get(), pos);
return firstPositionInNode(textNode.get());
}
@@ -109,7 +100,7 @@ bool InsertTextCommand::performTrivialReplace(const String& text, bool selectIns
bool InsertTextCommand::performOverwrite(const String& text, bool selectInsertedText)
{
Position start = endingSelection().start();
- RefPtr<Text> textNode = start.containerText();
+ RefPtrWillBeRawPtr<Text> textNode = start.containerText();
if (!textNode)
return false;
@@ -139,12 +130,17 @@ void InsertTextCommand::doApply()
if (endingSelection().isRange()) {
if (performTrivialReplace(m_text, m_selectInsertedText))
return;
- deleteSelection(false, true, true, false, false);
+ bool endOfSelectionWasAtStartOfBlock = isStartOfBlock(endingSelection().visibleEnd());
+ deleteSelection(false, true, false, false);
// deleteSelection eventually makes a new endingSelection out of a Position. If that Position doesn't have
// a renderer (e.g. it is on a <frameset> in the DOM), the VisibleSelection cannot be canonicalized to
// anything other than NoSelection. The rest of this function requires a real endingSelection, so bail out.
if (endingSelection().isNone())
return;
+ if (endOfSelectionWasAtStartOfBlock) {
+ if (EditingStyle* typingStyle = document().frame()->selection().typingStyle())
+ typingStyle->removeBlockProperties();
+ }
} else if (document().frame()->editor().isOverwriteModeEnabled()) {
if (performOverwrite(m_text, m_selectInsertedText))
return;
@@ -173,7 +169,8 @@ void InsertTextCommand::doApply()
// It is possible for the node that contains startPosition to contain only unrendered whitespace,
// and so deleteInsignificantText could remove it. Save the position before the node in case that happens.
- Position positionBeforeStartNode(positionInParentBeforeNode(startPosition.containerNode()));
+ ASSERT(startPosition.containerNode());
+ Position positionBeforeStartNode(positionInParentBeforeNode(*startPosition.containerNode()));
deleteInsignificantText(startPosition, startPosition.downstream());
if (!startPosition.inDocument())
startPosition = positionBeforeStartNode;
@@ -197,13 +194,11 @@ void InsertTextCommand::doApply()
ASSERT(startPosition.containerNode()->isTextNode());
if (placeholder.isNotNull())
removePlaceholderAt(placeholder);
- RefPtr<Text> textNode = startPosition.containerText();
+ RefPtrWillBeRawPtr<Text> textNode = startPosition.containerText();
const unsigned offset = startPosition.offsetInContainerNode();
insertTextIntoNode(textNode, offset, m_text);
endPosition = Position(textNode, offset + m_text.length());
- if (m_markerSupplier)
- m_markerSupplier->addMarkersToTextNode(textNode.get(), offset, m_text);
if (m_rebalanceType == RebalanceLeadingAndTrailingWhitespaces) {
// The insertion may require adjusting adjacent whitespace, if it is present.
@@ -221,7 +216,7 @@ void InsertTextCommand::doApply()
setEndingSelectionWithoutValidation(startPosition, endPosition);
// Handle the case where there is a typing style.
- if (RefPtr<EditingStyle> typingStyle = document().frame()->selection().typingStyle()) {
+ if (RefPtrWillBeRawPtr<EditingStyle> typingStyle = document().frame()->selection().typingStyle()) {
typingStyle->prepareToApplyAt(endPosition, EditingStyle::PreserveWritingDirection);
if (!typingStyle->isEmpty())
applyStyle(typingStyle.get());
@@ -234,25 +229,27 @@ void InsertTextCommand::doApply()
Position InsertTextCommand::insertTab(const Position& pos)
{
Position insertPos = VisiblePosition(pos, DOWNSTREAM).deepEquivalent();
+ if (insertPos.isNull())
+ return pos;
Node* node = insertPos.containerNode();
- unsigned int offset = node->isTextNode() ? insertPos.offsetInContainerNode() : 0;
+ unsigned offset = node->isTextNode() ? insertPos.offsetInContainerNode() : 0;
// keep tabs coalesced in tab span
if (isTabSpanTextNode(node)) {
- RefPtr<Text> textNode = toText(node);
+ RefPtrWillBeRawPtr<Text> textNode = toText(node);
insertTextIntoNode(textNode, offset, "\t");
return Position(textNode.release(), offset + 1);
}
// create new tab span
- RefPtr<Element> spanNode = createTabSpanElement(document());
+ RefPtrWillBeRawPtr<Element> spanNode = createTabSpanElement(document());
// place it
if (!node->isTextNode()) {
insertNodeAt(spanNode.get(), insertPos);
} else {
- RefPtr<Text> textNode = toText(node);
+ RefPtrWillBeRawPtr<Text> textNode = toText(node);
if (offset >= textNode->length())
insertNodeAfter(spanNode, textNode.release());
else {
diff --git a/chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.h b/chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.h
index 10c8d80ea49..3c282be1d92 100644
--- a/chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/InsertTextCommand.h
@@ -30,43 +30,23 @@
namespace WebCore {
-class DocumentMarkerController;
-class Text;
-
-class TextInsertionMarkerSupplier : public RefCounted<TextInsertionMarkerSupplier> {
-public:
- virtual ~TextInsertionMarkerSupplier() { }
- virtual void addMarkersToTextNode(Text*, unsigned offsetOfInsertion, const String& textInserted) = 0;
-protected:
- TextInsertionMarkerSupplier() { }
-};
-
-class InsertTextCommand : public CompositeEditCommand {
+class InsertTextCommand FINAL : public CompositeEditCommand {
public:
enum RebalanceType {
RebalanceLeadingAndTrailingWhitespaces,
RebalanceAllWhitespaces
};
- static PassRefPtr<InsertTextCommand> create(Document& document, const String& text, bool selectInsertedText = false,
+ static PassRefPtrWillBeRawPtr<InsertTextCommand> create(Document& document, const String& text, bool selectInsertedText = false,
RebalanceType rebalanceType = RebalanceLeadingAndTrailingWhitespaces)
{
- return adoptRef(new InsertTextCommand(document, text, selectInsertedText, rebalanceType));
- }
-
- static PassRefPtr<InsertTextCommand> createWithMarkerSupplier(Document& document, const String& text, PassRefPtr<TextInsertionMarkerSupplier> markerSupplier)
- {
- return adoptRef(new InsertTextCommand(document, text, markerSupplier));
+ return adoptRefWillBeNoop(new InsertTextCommand(document, text, selectInsertedText, rebalanceType));
}
private:
-
InsertTextCommand(Document&, const String& text, bool selectInsertedText, RebalanceType);
- InsertTextCommand(Document&, const String& text, PassRefPtr<TextInsertionMarkerSupplier>);
-
- void deleteCharacter();
- virtual void doApply();
+ virtual void doApply() OVERRIDE;
Position positionInsideTextNode(const Position&);
Position insertTab(const Position&);
@@ -80,7 +60,6 @@ private:
String m_text;
bool m_selectInsertedText;
RebalanceType m_rebalanceType;
- RefPtr<TextInsertionMarkerSupplier> m_markerSupplier;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.cpp b/chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.cpp
index 9d5b975badc..c17fe56b7b1 100644
--- a/chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.cpp
@@ -27,12 +27,13 @@
#include "config.h"
#include "core/editing/MarkupAccumulator.h"
-#include "HTMLNames.h"
-#include "XLinkNames.h"
-#include "XMLNSNames.h"
-#include "XMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/XLinkNames.h"
+#include "core/XMLNSNames.h"
+#include "core/XMLNames.h"
#include "core/dom/CDATASection.h"
#include "core/dom/Comment.h"
+#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentType.h"
#include "core/dom/ProcessingInstruction.h"
@@ -46,13 +47,37 @@ namespace WebCore {
using namespace HTMLNames;
+struct EntityDescription {
+ UChar entity;
+ const CString& reference;
+ EntityMask mask;
+};
+
+template <typename CharType>
+static inline void appendCharactersReplacingEntitiesInternal(StringBuilder& result, CharType* text, unsigned length, const EntityDescription entityMaps[], unsigned entityMapsCount, EntityMask entityMask)
+{
+ unsigned positionAfterLastEntity = 0;
+ for (unsigned i = 0; i < length; ++i) {
+ for (unsigned entityIndex = 0; entityIndex < entityMapsCount; ++entityIndex) {
+ if (text[i] == entityMaps[entityIndex].entity && entityMaps[entityIndex].mask & entityMask) {
+ result.append(text + positionAfterLastEntity, i - positionAfterLastEntity);
+ const CString& replacement = entityMaps[entityIndex].reference;
+ result.append(replacement.data(), replacement.length());
+ positionAfterLastEntity = i + 1;
+ break;
+ }
+ }
+ }
+ result.append(text + positionAfterLastEntity, length - positionAfterLastEntity);
+}
+
void MarkupAccumulator::appendCharactersReplacingEntities(StringBuilder& result, const String& source, unsigned offset, unsigned length, EntityMask entityMask)
{
- DEFINE_STATIC_LOCAL(const String, ampReference, ("&amp;"));
- DEFINE_STATIC_LOCAL(const String, ltReference, ("&lt;"));
- DEFINE_STATIC_LOCAL(const String, gtReference, ("&gt;"));
- DEFINE_STATIC_LOCAL(const String, quotReference, ("&quot;"));
- DEFINE_STATIC_LOCAL(const String, nbspReference, ("&nbsp;"));
+ DEFINE_STATIC_LOCAL(const CString, ampReference, ("&amp;"));
+ DEFINE_STATIC_LOCAL(const CString, ltReference, ("&lt;"));
+ DEFINE_STATIC_LOCAL(const CString, gtReference, ("&gt;"));
+ DEFINE_STATIC_LOCAL(const CString, quotReference, ("&quot;"));
+ DEFINE_STATIC_LOCAL(const CString, nbspReference, ("&nbsp;"));
static const EntityDescription entityMaps[] = {
{ '&', ampReference, EntityAmp },
@@ -66,44 +91,17 @@ void MarkupAccumulator::appendCharactersReplacingEntities(StringBuilder& result,
return;
ASSERT(offset + length <= source.length());
-
- if (source.is8Bit()) {
- const LChar* text = source.characters8() + offset;
-
- size_t positionAfterLastEntity = 0;
- for (size_t i = 0; i < length; ++i) {
- for (size_t entityIndex = 0; entityIndex < WTF_ARRAY_LENGTH(entityMaps); ++entityIndex) {
- if (text[i] == entityMaps[entityIndex].entity && entityMaps[entityIndex].mask & entityMask) {
- result.append(text + positionAfterLastEntity, i - positionAfterLastEntity);
- result.append(entityMaps[entityIndex].reference);
- positionAfterLastEntity = i + 1;
- break;
- }
- }
- }
- result.append(text + positionAfterLastEntity, length - positionAfterLastEntity);
- } else {
- const UChar* text = source.characters16() + offset;
-
- size_t positionAfterLastEntity = 0;
- for (size_t i = 0; i < length; ++i) {
- for (size_t entityIndex = 0; entityIndex < WTF_ARRAY_LENGTH(entityMaps); ++entityIndex) {
- if (text[i] == entityMaps[entityIndex].entity && entityMaps[entityIndex].mask & entityMask) {
- result.append(text + positionAfterLastEntity, i - positionAfterLastEntity);
- result.append(entityMaps[entityIndex].reference);
- positionAfterLastEntity = i + 1;
- break;
- }
- }
- }
- result.append(text + positionAfterLastEntity, length - positionAfterLastEntity);
- }
+ if (source.is8Bit())
+ appendCharactersReplacingEntitiesInternal(result, source.characters8() + offset, length, entityMaps, WTF_ARRAY_LENGTH(entityMaps), entityMask);
+ else
+ appendCharactersReplacingEntitiesInternal(result, source.characters16() + offset, length, entityMaps, WTF_ARRAY_LENGTH(entityMaps), entityMask);
}
-MarkupAccumulator::MarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs resolveUrlsMethod, const Range* range)
+MarkupAccumulator::MarkupAccumulator(WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs resolveUrlsMethod, const Range* range, SerializationType serializationType)
: m_nodes(nodes)
, m_range(range)
, m_resolveURLsMethod(resolveUrlsMethod)
+ , m_serializationType(serializationType)
{
}
@@ -111,22 +109,25 @@ MarkupAccumulator::~MarkupAccumulator()
{
}
-String MarkupAccumulator::serializeNodes(Node* targetNode, EChildrenOnly childrenOnly)
+String MarkupAccumulator::serializeNodes(Node& targetNode, EChildrenOnly childrenOnly, Vector<QualifiedName>* tagNamesToSkip)
{
- return serializeNodes(targetNode, childrenOnly, 0);
-}
+ Namespaces* namespaces = 0;
+ Namespaces namespaceHash;
+ if (!serializeAsHTMLDocument(targetNode)) {
+ // Add pre-bound namespaces for XML fragments.
+ namespaceHash.set(xmlAtom, XMLNames::xmlNamespaceURI);
+ namespaces = &namespaceHash;
+ }
-String MarkupAccumulator::serializeNodes(Node* targetNode, EChildrenOnly childrenOnly, Vector<QualifiedName>* tagNamesToSkip)
-{
- serializeNodesWithNamespaces(targetNode, childrenOnly, 0, tagNamesToSkip);
+ serializeNodesWithNamespaces(targetNode, childrenOnly, namespaces, tagNamesToSkip);
return m_markup.toString();
}
-void MarkupAccumulator::serializeNodesWithNamespaces(Node* targetNode, EChildrenOnly childrenOnly, const Namespaces* namespaces, Vector<QualifiedName>* tagNamesToSkip)
+void MarkupAccumulator::serializeNodesWithNamespaces(Node& targetNode, EChildrenOnly childrenOnly, const Namespaces* namespaces, Vector<QualifiedName>* tagNamesToSkip)
{
if (tagNamesToSkip) {
for (size_t i = 0; i < tagNamesToSkip->size(); ++i) {
- if (targetNode->hasTagName(tagNamesToSkip->at(i)))
+ if (targetNode.hasTagName(tagNamesToSkip->at(i)))
return;
}
}
@@ -138,25 +139,25 @@ void MarkupAccumulator::serializeNodesWithNamespaces(Node* targetNode, EChildren
if (!childrenOnly)
appendStartTag(targetNode, &namespaceHash);
- if (!(targetNode->document().isHTMLDocument() && elementCannotHaveEndTag(targetNode))) {
- Node* current = targetNode->hasTagName(templateTag) ? toHTMLTemplateElement(targetNode)->content()->firstChild() : targetNode->firstChild();
+ if (!(serializeAsHTMLDocument(targetNode) && elementCannotHaveEndTag(targetNode))) {
+ Node* current = isHTMLTemplateElement(targetNode) ? toHTMLTemplateElement(targetNode).content()->firstChild() : targetNode.firstChild();
for ( ; current; current = current->nextSibling())
- serializeNodesWithNamespaces(current, IncludeNode, &namespaceHash, tagNamesToSkip);
+ serializeNodesWithNamespaces(*current, IncludeNode, &namespaceHash, tagNamesToSkip);
}
if (!childrenOnly)
appendEndTag(targetNode);
}
-String MarkupAccumulator::resolveURLIfNeeded(const Element* element, const String& urlString) const
+String MarkupAccumulator::resolveURLIfNeeded(const Element& element, const String& urlString) const
{
switch (m_resolveURLsMethod) {
case ResolveAllURLs:
- return element->document().completeURL(urlString).string();
+ return element.document().completeURL(urlString).string();
case ResolveNonLocalURLs:
- if (!element->document().url().isLocalFile())
- return element->document().completeURL(urlString).string();
+ if (!element.document().url().isLocalFile())
+ return element.document().completeURL(urlString).string();
break;
case DoNotResolveURLs:
@@ -170,14 +171,14 @@ void MarkupAccumulator::appendString(const String& string)
m_markup.append(string);
}
-void MarkupAccumulator::appendStartTag(Node* node, Namespaces* namespaces)
+void MarkupAccumulator::appendStartTag(Node& node, Namespaces* namespaces)
{
appendStartMarkup(m_markup, node, namespaces);
if (m_nodes)
- m_nodes->append(node);
+ m_nodes->append(&node);
}
-void MarkupAccumulator::appendEndTag(Node* node)
+void MarkupAccumulator::appendEndTag(const Node& node)
{
appendEndMarkup(m_markup, node);
}
@@ -201,13 +202,13 @@ void MarkupAccumulator::appendAttributeValue(StringBuilder& result, const String
documentIsHTML ? EntityMaskInHTMLAttributeValue : EntityMaskInAttributeValue);
}
-void MarkupAccumulator::appendCustomAttributes(StringBuilder&, Element*, Namespaces*)
+void MarkupAccumulator::appendCustomAttributes(StringBuilder&, const Element&, Namespaces*)
{
}
-void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, const Element* element, const Attribute& attribute)
+void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, const Element& element, const Attribute& attribute)
{
- ASSERT(element->isURLAttribute(attribute));
+ ASSERT(element.isURLAttribute(attribute));
const String resolvedURLString = resolveURLIfNeeded(element, attribute.value());
UChar quoteChar = '"';
String strippedURLString = resolvedURLString.stripWhiteSpace();
@@ -231,50 +232,35 @@ void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, con
result.append(quoteChar);
}
-void MarkupAccumulator::appendNodeValue(StringBuilder& result, const Node* node, const Range* range, EntityMask entityMask)
+bool MarkupAccumulator::shouldAddNamespaceElement(const Element& element, Namespaces& namespaces)
{
- const String str = node->nodeValue();
- unsigned length = str.length();
- unsigned start = 0;
-
- if (range) {
- if (node == range->endContainer())
- length = range->endOffset();
- if (node == range->startContainer()) {
- start = range->startOffset();
- length -= start;
+ // Don't add namespace attribute if it is already defined for this elem.
+ const AtomicString& prefix = element.prefix();
+ if (prefix.isEmpty()) {
+ if (element.hasAttribute(xmlnsAtom)) {
+ namespaces.set(emptyAtom, element.namespaceURI());
+ return false;
}
+ return true;
}
- appendCharactersReplacingEntities(result, str, start, length, entityMask);
+ return !element.hasAttribute(WTF::xmlnsWithColon + prefix);
}
-bool MarkupAccumulator::shouldAddNamespaceElement(const Element* element)
+bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute& attribute, const Element& element)
{
- // Don't add namespace attribute if it is already defined for this elem.
- const AtomicString& prefix = element->prefix();
- if (prefix.isEmpty())
- return !element->hasAttribute(xmlnsAtom);
+ // xmlns and xmlns:prefix attributes should be handled by another branch in appendAttribute.
+ ASSERT(attribute.namespaceURI() != XMLNSNames::xmlnsNamespaceURI);
- DEFINE_STATIC_LOCAL(String, xmlnsWithColon, ("xmlns:"));
- return !element->hasAttribute(xmlnsWithColon + prefix);
-}
-
-bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute& attribute, Namespaces& namespaces)
-{
- // Don't add namespace attributes twice
- if (attribute.name() == XMLNSNames::xmlnsAttr) {
- namespaces.set(emptyAtom.impl(), attribute.value().impl());
+ // Attributes are in the null namespace by default.
+ if (!attribute.namespaceURI())
return false;
- }
- QualifiedName xmlnsPrefixAttr(xmlnsAtom, attribute.localName(), XMLNSNames::xmlnsNamespaceURI);
- if (attribute.name() == xmlnsPrefixAttr) {
- namespaces.set(attribute.localName().impl(), attribute.value().impl());
- return false;
- }
+ // Attributes without a prefix will need one generated for them, and an xmlns attribute for that prefix.
+ if (!attribute.prefix())
+ return true;
- return true;
+ return !element.hasAttribute(WTF::xmlnsWithColon + attribute.prefix());
}
void MarkupAccumulator::appendNamespace(StringBuilder& result, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces& namespaces)
@@ -282,11 +268,10 @@ void MarkupAccumulator::appendNamespace(StringBuilder& result, const AtomicStrin
if (namespaceURI.isEmpty())
return;
- // Use emptyAtoms's impl() for both null and empty strings since the HashMap can't handle 0 as a key
- StringImpl* pre = prefix.isEmpty() ? emptyAtom.impl() : prefix.impl();
- StringImpl* foundNS = namespaces.get(pre);
- if (foundNS != namespaceURI.impl()) {
- namespaces.set(pre, namespaceURI.impl());
+ const AtomicString& lookupKey = (!prefix) ? emptyAtom : prefix;
+ AtomicString foundURI = namespaces.get(lookupKey);
+ if (foundURI != namespaceURI) {
+ namespaces.set(lookupKey, namespaceURI);
result.append(' ');
result.append(xmlnsAtom.string());
if (!prefix.isEmpty()) {
@@ -294,30 +279,41 @@ void MarkupAccumulator::appendNamespace(StringBuilder& result, const AtomicStrin
result.append(prefix);
}
- result.append('=');
- result.append('"');
+ result.appendLiteral("=\"");
appendAttributeValue(result, namespaceURI, false);
result.append('"');
}
}
-EntityMask MarkupAccumulator::entityMaskForText(Text* text) const
+EntityMask MarkupAccumulator::entityMaskForText(const Text& text) const
{
- if (!text->document().isHTMLDocument())
+ if (!serializeAsHTMLDocument(text))
return EntityMaskInPCDATA;
const QualifiedName* parentName = 0;
- if (text->parentElement())
- parentName = &(text->parentElement())->tagQName();
+ if (text.parentElement())
+ parentName = &(text.parentElement())->tagQName();
if (parentName && (*parentName == scriptTag || *parentName == styleTag || *parentName == xmpTag))
return EntityMaskInCDATA;
return EntityMaskInHTMLPCDATA;
}
-void MarkupAccumulator::appendText(StringBuilder& result, Text* text)
+void MarkupAccumulator::appendText(StringBuilder& result, Text& text)
{
- appendNodeValue(result, text, m_range, entityMaskForText(text));
+ const String& str = text.data();
+ unsigned length = str.length();
+ unsigned start = 0;
+
+ if (m_range) {
+ if (text == m_range->endContainer())
+ length = m_range->endOffset();
+ if (text == m_range->startContainer()) {
+ start = m_range->startOffset();
+ length -= start;
+ }
+ }
+ appendCharactersReplacingEntities(result, str, start, length, entityMaskForText(text));
}
void MarkupAccumulator::appendComment(StringBuilder& result, const String& comment)
@@ -328,21 +324,21 @@ void MarkupAccumulator::appendComment(StringBuilder& result, const String& comme
result.appendLiteral("-->");
}
-void MarkupAccumulator::appendXMLDeclaration(StringBuilder& result, const Document* document)
+void MarkupAccumulator::appendXMLDeclaration(StringBuilder& result, const Document& document)
{
- if (!document->hasXMLDeclaration())
+ if (!document.hasXMLDeclaration())
return;
result.appendLiteral("<?xml version=\"");
- result.append(document->xmlVersion());
- const String& encoding = document->xmlEncoding();
+ result.append(document.xmlVersion());
+ const String& encoding = document.xmlEncoding();
if (!encoding.isEmpty()) {
result.appendLiteral("\" encoding=\"");
result.append(encoding);
}
- if (document->xmlStandaloneStatus() != Document::StandaloneUnspecified) {
+ if (document.xmlStandaloneStatus() != Document::StandaloneUnspecified) {
result.appendLiteral("\" standalone=\"");
- if (document->xmlStandalone())
+ if (document.xmlStandalone())
result.appendLiteral("yes");
else
result.appendLiteral("no");
@@ -351,57 +347,49 @@ void MarkupAccumulator::appendXMLDeclaration(StringBuilder& result, const Docume
result.appendLiteral("\"?>");
}
-void MarkupAccumulator::appendDocumentType(StringBuilder& result, const DocumentType* n)
+void MarkupAccumulator::appendDocumentType(StringBuilder& result, const DocumentType& n)
{
- if (n->name().isEmpty())
+ if (n.name().isEmpty())
return;
result.appendLiteral("<!DOCTYPE ");
- result.append(n->name());
- if (!n->publicId().isEmpty()) {
+ result.append(n.name());
+ if (!n.publicId().isEmpty()) {
result.appendLiteral(" PUBLIC \"");
- result.append(n->publicId());
+ result.append(n.publicId());
result.append('"');
- if (!n->systemId().isEmpty()) {
- result.append(' ');
- result.append('"');
- result.append(n->systemId());
+ if (!n.systemId().isEmpty()) {
+ result.appendLiteral(" \"");
+ result.append(n.systemId());
result.append('"');
}
- } else if (!n->systemId().isEmpty()) {
+ } else if (!n.systemId().isEmpty()) {
result.appendLiteral(" SYSTEM \"");
- result.append(n->systemId());
+ result.append(n.systemId());
result.append('"');
}
- if (!n->internalSubset().isEmpty()) {
- result.append(' ');
- result.append('[');
- result.append(n->internalSubset());
- result.append(']');
- }
result.append('>');
}
void MarkupAccumulator::appendProcessingInstruction(StringBuilder& result, const String& target, const String& data)
{
// FIXME: PI data is not escaped, but XMLSerializer (and possibly other callers) this should raise an exception if it includes "?>".
- result.append('<');
- result.append('?');
+ result.appendLiteral("<?");
result.append(target);
result.append(' ');
result.append(data);
- result.append('?');
- result.append('>');
+ result.appendLiteral("?>");
}
-void MarkupAccumulator::appendElement(StringBuilder& result, Element* element, Namespaces* namespaces)
+void MarkupAccumulator::appendElement(StringBuilder& result, Element& element, Namespaces* namespaces)
{
appendOpenTag(result, element, namespaces);
- if (element->hasAttributes()) {
- unsigned length = element->attributeCount();
- for (unsigned int i = 0; i < length; i++)
- appendAttribute(result, element, *element->attributeItem(i), namespaces);
+ if (element.hasAttributes()) {
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it)
+ appendAttribute(result, element, *it, namespaces);
}
// Give an opportunity to subclasses to add their own attributes.
@@ -410,18 +398,23 @@ void MarkupAccumulator::appendElement(StringBuilder& result, Element* element, N
appendCloseTag(result, element);
}
-void MarkupAccumulator::appendOpenTag(StringBuilder& result, Element* element, Namespaces* namespaces)
+static String nodeNamePreservingCase(const Element& element)
+{
+ return element.tagQName().toString();
+}
+
+void MarkupAccumulator::appendOpenTag(StringBuilder& result, const Element& element, Namespaces* namespaces)
{
result.append('<');
- result.append(element->nodeNamePreservingCase());
- if (!element->document().isHTMLDocument() && namespaces && shouldAddNamespaceElement(element))
- appendNamespace(result, element->prefix(), element->namespaceURI(), *namespaces);
+ result.append(nodeNamePreservingCase(element));
+ if (!serializeAsHTMLDocument(element) && namespaces && shouldAddNamespaceElement(element, *namespaces))
+ appendNamespace(result, element.prefix(), element.namespaceURI(), *namespaces);
}
-void MarkupAccumulator::appendCloseTag(StringBuilder& result, Element* element)
+void MarkupAccumulator::appendCloseTag(StringBuilder& result, const Element& element)
{
if (shouldSelfClose(element)) {
- if (element->isHTMLElement())
+ if (element.isHTMLElement())
result.append(' '); // XHTML 1.0 <-> HTML compatibility.
result.append('/');
}
@@ -435,16 +428,15 @@ static inline bool attributeIsInSerializedNamespace(const Attribute& attribute)
|| attribute.namespaceURI() == XMLNSNames::xmlnsNamespaceURI;
}
-void MarkupAccumulator::appendAttribute(StringBuilder& result, Element* element, const Attribute& attribute, Namespaces* namespaces)
+void MarkupAccumulator::appendAttribute(StringBuilder& result, const Element& element, const Attribute& attribute, Namespaces* namespaces)
{
- bool documentIsHTML = element->document().isHTMLDocument();
+ bool documentIsHTML = serializeAsHTMLDocument(element);
- result.append(' ');
-
- if (documentIsHTML && !attributeIsInSerializedNamespace(attribute))
+ QualifiedName prefixedName = attribute.name();
+ if (documentIsHTML && !attributeIsInSerializedNamespace(attribute)) {
+ result.append(' ');
result.append(attribute.name().localName());
- else {
- QualifiedName prefixedName = attribute.name();
+ } else {
if (attribute.namespaceURI() == XLinkNames::xlinkNamespaceURI) {
if (!attribute.prefix())
prefixedName.setPrefix(xlinkAtom);
@@ -452,24 +444,42 @@ void MarkupAccumulator::appendAttribute(StringBuilder& result, Element* element,
if (!attribute.prefix())
prefixedName.setPrefix(xmlAtom);
} else if (attribute.namespaceURI() == XMLNSNames::xmlnsNamespaceURI) {
- if (attribute.name() != XMLNSNames::xmlnsAttr && !attribute.prefix())
+ if (!attribute.prefix() && attribute.localName() != xmlnsAtom)
prefixedName.setPrefix(xmlnsAtom);
+ if (namespaces) { // Account for the namespace attribute we're about to append.
+ const AtomicString& lookupKey = (!attribute.prefix()) ? emptyAtom : attribute.localName();
+ namespaces->set(lookupKey, attribute.value());
+ }
+ } else if (namespaces && shouldAddNamespaceAttribute(attribute, element)) {
+ if (!attribute.prefix()) {
+ // This behavior is in process of being standardized. See crbug.com/248044 and https://www.w3.org/Bugs/Public/show_bug.cgi?id=24208
+ String prefixPrefix("ns", 2);
+ for (unsigned i = attribute.namespaceURI().impl()->existingHash(); ; ++i) {
+ AtomicString newPrefix(String(prefixPrefix + String::number(i)));
+ AtomicString foundURI = namespaces->get(newPrefix);
+ if (foundURI == attribute.namespaceURI() || foundURI == nullAtom) {
+ // We already generated a prefix for this namespace.
+ prefixedName.setPrefix(newPrefix);
+ break;
+ }
+ }
+ }
+ ASSERT(prefixedName.prefix());
+ appendNamespace(result, prefixedName.prefix(), attribute.namespaceURI(), *namespaces);
}
+ result.append(' ');
result.append(prefixedName.toString());
}
result.append('=');
- if (element->isURLAttribute(attribute))
+ if (element.isURLAttribute(attribute)) {
appendQuotedURLAttributeValue(result, element, attribute);
- else {
+ } else {
result.append('"');
appendAttributeValue(result, attribute.value(), documentIsHTML);
result.append('"');
}
-
- if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces))
- appendNamespace(result, attribute.prefix(), attribute.namespaceURI(), *namespaces);
}
void MarkupAccumulator::appendCDATASection(StringBuilder& result, const String& section)
@@ -480,14 +490,14 @@ void MarkupAccumulator::appendCDATASection(StringBuilder& result, const String&
result.appendLiteral("]]>");
}
-void MarkupAccumulator::appendStartMarkup(StringBuilder& result, const Node* node, Namespaces* namespaces)
+void MarkupAccumulator::appendStartMarkup(StringBuilder& result, Node& node, Namespaces* namespaces)
{
- switch (node->nodeType()) {
+ switch (node.nodeType()) {
case Node::TEXT_NODE:
- appendText(result, toText(const_cast<Node*>(node)));
+ appendText(result, toText(node));
break;
case Node::COMMENT_NODE:
- appendComment(result, toComment(node)->data());
+ appendComment(result, toComment(node).data());
break;
case Node::DOCUMENT_NODE:
appendXMLDeclaration(result, toDocument(node));
@@ -498,18 +508,15 @@ void MarkupAccumulator::appendStartMarkup(StringBuilder& result, const Node* nod
appendDocumentType(result, toDocumentType(node));
break;
case Node::PROCESSING_INSTRUCTION_NODE:
- appendProcessingInstruction(result, toProcessingInstruction(node)->target(), toProcessingInstruction(node)->data());
+ appendProcessingInstruction(result, toProcessingInstruction(node).target(), toProcessingInstruction(node).data());
break;
case Node::ELEMENT_NODE:
- appendElement(result, toElement(const_cast<Node*>(node)), namespaces);
+ appendElement(result, toElement(node), namespaces);
break;
case Node::CDATA_SECTION_NODE:
- appendCDATASection(result, toCDATASection(node)->data());
+ appendCDATASection(result, toCDATASection(node).data());
break;
case Node::ATTRIBUTE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
ASSERT_NOT_REACHED();
break;
}
@@ -520,38 +527,44 @@ void MarkupAccumulator::appendStartMarkup(StringBuilder& result, const Node* nod
// 2. Elements w/ children never self-close because they use a separate end tag.
// 3. HTML elements which do not have a "forbidden" end tag will close with a separate end tag.
// 4. Other elements self-close.
-bool MarkupAccumulator::shouldSelfClose(const Node* node)
+bool MarkupAccumulator::shouldSelfClose(const Node& node)
{
- if (node->document().isHTMLDocument())
+ if (serializeAsHTMLDocument(node))
return false;
- if (node->hasChildNodes())
+ if (node.hasChildren())
return false;
- if (node->isHTMLElement() && !elementCannotHaveEndTag(node))
+ if (node.isHTMLElement() && !elementCannotHaveEndTag(node))
return false;
return true;
}
-bool MarkupAccumulator::elementCannotHaveEndTag(const Node* node)
+bool MarkupAccumulator::elementCannotHaveEndTag(const Node& node)
{
- if (!node->isHTMLElement())
+ if (!node.isHTMLElement())
return false;
// FIXME: ieForbidsInsertHTML may not be the right function to call here
// ieForbidsInsertHTML is used to disallow setting innerHTML/outerHTML
// or createContextualFragment. It does not necessarily align with
// which elements should be serialized w/o end tags.
- return toHTMLElement(node)->ieForbidsInsertHTML();
+ return toHTMLElement(node).ieForbidsInsertHTML();
}
-void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Node* node)
+void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Node& node)
{
- if (!node->isElementNode() || shouldSelfClose(node) || (!node->hasChildNodes() && elementCannotHaveEndTag(node)))
+ if (!node.isElementNode() || shouldSelfClose(node) || (!node.hasChildren() && elementCannotHaveEndTag(node)))
return;
- result.append('<');
- result.append('/');
- result.append(toElement(node)->nodeNamePreservingCase());
+ result.appendLiteral("</");
+ result.append(nodeNamePreservingCase(toElement(node)));
result.append('>');
}
+bool MarkupAccumulator::serializeAsHTMLDocument(const Node& node) const
+{
+ if (m_serializationType == ForcedXML)
+ return false;
+ return node.document().isHTMLDocument();
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.h b/chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.h
index a126567c964..8e25e431ef0 100644
--- a/chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.h
+++ b/chromium/third_party/WebKit/Source/core/editing/MarkupAccumulator.h
@@ -39,7 +39,7 @@ class Element;
class Node;
class Range;
-typedef HashMap<StringImpl*, StringImpl*> Namespaces;
+typedef HashMap<AtomicString, AtomicString> Namespaces;
enum EntityMask {
EntityAmp = 0x0001,
@@ -53,67 +53,68 @@ enum EntityMask {
EntityMaskInCDATA = 0,
EntityMaskInPCDATA = EntityAmp | EntityLt | EntityGt,
EntityMaskInHTMLPCDATA = EntityMaskInPCDATA | EntityNbsp,
- EntityMaskInAttributeValue = EntityAmp | EntityLt | EntityGt | EntityQuot,
- EntityMaskInHTMLAttributeValue = EntityMaskInAttributeValue | EntityNbsp,
+ EntityMaskInAttributeValue = EntityAmp | EntityQuot | EntityLt | EntityGt,
+ EntityMaskInHTMLAttributeValue = EntityAmp | EntityQuot | EntityNbsp,
};
-struct EntityDescription {
- UChar entity;
- const String& reference;
- EntityMask mask;
+enum SerializationType {
+ AsOwnerDocument,
+ ForcedXML
};
-// FIXME: Noncopyable?
class MarkupAccumulator {
+ WTF_MAKE_NONCOPYABLE(MarkupAccumulator);
+ STACK_ALLOCATED();
public:
- MarkupAccumulator(Vector<Node*>*, EAbsoluteURLs, const Range* = 0);
+ MarkupAccumulator(WillBeHeapVector<RawPtrWillBeMember<Node> >*, EAbsoluteURLs, const Range* = 0, SerializationType = AsOwnerDocument);
virtual ~MarkupAccumulator();
- String serializeNodes(Node* targetNode, EChildrenOnly);
- String serializeNodes(Node* targetNode, EChildrenOnly, Vector<QualifiedName>* tagNamesToSkip);
+ String serializeNodes(Node& targetNode, EChildrenOnly, Vector<QualifiedName>* tagNamesToSkip = 0);
static void appendComment(StringBuilder&, const String&);
static void appendCharactersReplacingEntities(StringBuilder&, const String&, unsigned, unsigned, EntityMask);
protected:
- virtual void appendString(const String&);
- void appendStartTag(Node*, Namespaces* = 0);
- virtual void appendEndTag(Node*);
+ void appendString(const String&);
+ void appendStartTag(Node&, Namespaces* = 0);
+ virtual void appendEndTag(const Node&);
static size_t totalLength(const Vector<String>&);
size_t length() const { return m_markup.length(); }
void concatenateMarkup(StringBuilder&);
void appendAttributeValue(StringBuilder&, const String&, bool);
- virtual void appendCustomAttributes(StringBuilder&, Element*, Namespaces*);
- void appendNodeValue(StringBuilder&, const Node*, const Range*, EntityMask);
- bool shouldAddNamespaceElement(const Element*);
- bool shouldAddNamespaceAttribute(const Attribute&, Namespaces&);
+ virtual void appendCustomAttributes(StringBuilder&, const Element&, Namespaces*);
+ bool shouldAddNamespaceElement(const Element&, Namespaces&);
+ bool shouldAddNamespaceAttribute(const Attribute&, const Element&);
+
void appendNamespace(StringBuilder&, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces&);
- EntityMask entityMaskForText(Text*) const;
- virtual void appendText(StringBuilder&, Text*);
- void appendXMLDeclaration(StringBuilder&, const Document*);
- void appendDocumentType(StringBuilder&, const DocumentType*);
+ EntityMask entityMaskForText(const Text&) const;
+ virtual void appendText(StringBuilder&, Text&);
+ void appendXMLDeclaration(StringBuilder&, const Document&);
+ void appendDocumentType(StringBuilder&, const DocumentType&);
void appendProcessingInstruction(StringBuilder&, const String& target, const String& data);
- virtual void appendElement(StringBuilder&, Element*, Namespaces*);
- void appendOpenTag(StringBuilder&, Element*, Namespaces*);
- void appendCloseTag(StringBuilder&, Element*);
- void appendAttribute(StringBuilder&, Element*, const Attribute&, Namespaces*);
+ virtual void appendElement(StringBuilder&, Element&, Namespaces*);
+ void appendOpenTag(StringBuilder&, const Element&, Namespaces*);
+ void appendCloseTag(StringBuilder&, const Element&);
+ void appendAttribute(StringBuilder&, const Element&, const Attribute&, Namespaces*);
void appendCDATASection(StringBuilder&, const String&);
- void appendStartMarkup(StringBuilder&, const Node*, Namespaces*);
- bool shouldSelfClose(const Node*);
- bool elementCannotHaveEndTag(const Node*);
- void appendEndMarkup(StringBuilder&, const Node*);
+ void appendStartMarkup(StringBuilder&, Node&, Namespaces*);
+ bool shouldSelfClose(const Node&);
+ bool elementCannotHaveEndTag(const Node&);
+ void appendEndMarkup(StringBuilder&, const Node&);
- Vector<Node*>* const m_nodes;
- const Range* const m_range;
+ RawPtrWillBeMember<WillBeHeapVector<RawPtrWillBeMember<Node> > > const m_nodes;
+ RawPtrWillBeMember<const Range> const m_range;
private:
- String resolveURLIfNeeded(const Element*, const String&) const;
- void appendQuotedURLAttributeValue(StringBuilder&, const Element*, const Attribute&);
- void serializeNodesWithNamespaces(Node* targetNode, EChildrenOnly, const Namespaces*, Vector<QualifiedName>* tagNamesToSkip);
+ String resolveURLIfNeeded(const Element&, const String&) const;
+ void appendQuotedURLAttributeValue(StringBuilder&, const Element&, const Attribute&);
+ void serializeNodesWithNamespaces(Node& targetNode, EChildrenOnly, const Namespaces*, Vector<QualifiedName>* tagNamesToSkip);
+ bool serializeAsHTMLDocument(const Node&) const;
StringBuilder m_markup;
const EAbsoluteURLs m_resolveURLsMethod;
+ SerializationType m_serializationType;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.cpp
index e512319ee52..abeae71208c 100644
--- a/chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.cpp
@@ -32,7 +32,7 @@
namespace WebCore {
-MergeIdenticalElementsCommand::MergeIdenticalElementsCommand(PassRefPtr<Element> first, PassRefPtr<Element> second)
+MergeIdenticalElementsCommand::MergeIdenticalElementsCommand(PassRefPtrWillBeRawPtr<Element> first, PassRefPtrWillBeRawPtr<Element> second)
: SimpleEditCommand(first->document())
, m_element1(first)
, m_element2(second)
@@ -49,7 +49,7 @@ void MergeIdenticalElementsCommand::doApply()
m_atChild = m_element2->firstChild();
- Vector<RefPtr<Node> > children;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > children;
for (Node* child = m_element1->firstChild(); child; child = child->nextSibling())
children.append(child);
@@ -65,7 +65,7 @@ void MergeIdenticalElementsCommand::doUnapply()
ASSERT(m_element1);
ASSERT(m_element2);
- RefPtr<Node> atChild = m_atChild.release();
+ RefPtrWillBeRawPtr<Node> atChild = m_atChild.release();
ContainerNode* parent = m_element2->parentNode();
if (!parent || !parent->rendererIsEditable())
@@ -77,7 +77,7 @@ void MergeIdenticalElementsCommand::doUnapply()
if (exceptionState.hadException())
return;
- Vector<RefPtr<Node> > children;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > children;
for (Node* child = m_element2->firstChild(); child && child != atChild; child = child->nextSibling())
children.append(child);
@@ -86,4 +86,12 @@ void MergeIdenticalElementsCommand::doUnapply()
m_element1->appendChild(children[i].release(), exceptionState);
}
+void MergeIdenticalElementsCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_element1);
+ visitor->trace(m_element2);
+ visitor->trace(m_atChild);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.h b/chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.h
index 42dd8a843ee..cdfa636be67 100644
--- a/chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/MergeIdenticalElementsCommand.h
@@ -30,22 +30,24 @@
namespace WebCore {
-class MergeIdenticalElementsCommand : public SimpleEditCommand {
+class MergeIdenticalElementsCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<MergeIdenticalElementsCommand> create(PassRefPtr<Element> element1, PassRefPtr<Element> element2)
+ static PassRefPtrWillBeRawPtr<MergeIdenticalElementsCommand> create(PassRefPtrWillBeRawPtr<Element> element1, PassRefPtrWillBeRawPtr<Element> element2)
{
- return adoptRef(new MergeIdenticalElementsCommand(element1, element2));
+ return adoptRefWillBeNoop(new MergeIdenticalElementsCommand(element1, element2));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- MergeIdenticalElementsCommand(PassRefPtr<Element>, PassRefPtr<Element>);
+ MergeIdenticalElementsCommand(PassRefPtrWillBeRawPtr<Element>, PassRefPtrWillBeRawPtr<Element>);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<Element> m_element1;
- RefPtr<Element> m_element2;
- RefPtr<Node> m_atChild;
+ RefPtrWillBeMember<Element> m_element1;
+ RefPtrWillBeMember<Element> m_element2;
+ RefPtrWillBeMember<Node> m_atChild;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/ModifySelectionListLevel.cpp b/chromium/third_party/WebKit/Source/core/editing/ModifySelectionListLevel.cpp
deleted file mode 100644
index e438eb25b4f..00000000000
--- a/chromium/third_party/WebKit/Source/core/editing/ModifySelectionListLevel.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/editing/ModifySelectionListLevel.h"
-
-#include "core/dom/Document.h"
-#include "core/editing/FrameSelection.h"
-#include "core/editing/htmlediting.h"
-#include "core/html/HTMLElement.h"
-#include "core/frame/Frame.h"
-#include "core/rendering/RenderObject.h"
-
-namespace WebCore {
-
-ModifySelectionListLevelCommand::ModifySelectionListLevelCommand(Document& document)
- : CompositeEditCommand(document)
-{
-}
-
-bool ModifySelectionListLevelCommand::preservesTypingStyle() const
-{
- return true;
-}
-
-// This needs to be static so it can be called by canIncreaseSelectionListLevel and canDecreaseSelectionListLevel
-static bool getStartEndListChildren(const VisibleSelection& selection, Node*& start, Node*& end)
-{
- if (selection.isNone())
- return false;
-
- // start must be in a list child
- Node* startListChild = enclosingListChild(selection.start().anchorNode());
- if (!startListChild)
- return false;
-
- // end must be in a list child
- Node* endListChild = selection.isRange() ? enclosingListChild(selection.end().anchorNode()) : startListChild;
- if (!endListChild)
- return false;
-
- // For a range selection we want the following behavior:
- // - the start and end must be within the same overall list
- // - the start must be at or above the level of the rest of the range
- // - if the end is anywhere in a sublist lower than start, the whole sublist gets moved
- // In terms of this function, this means:
- // - endListChild must start out being be a sibling of startListChild, or be in a
- // sublist of startListChild or a sibling
- // - if endListChild is in a sublist of startListChild or a sibling, it must be adjusted
- // to be the ancestor that is startListChild or its sibling
- while (startListChild->parentNode() != endListChild->parentNode()) {
- endListChild = endListChild->parentNode();
- if (!endListChild)
- return false;
- }
-
- // if the selection ends on a list item with a sublist, include the entire sublist
- if (endListChild->renderer()->isListItem()) {
- RenderObject* r = endListChild->renderer()->nextSibling();
- if (r && isListElement(r->node()))
- endListChild = r->node();
- }
-
- start = startListChild;
- end = endListChild;
- return true;
-}
-
-void ModifySelectionListLevelCommand::insertSiblingNodeRangeBefore(Node* startNode, Node* endNode, Node* refNode)
-{
- Node* node = startNode;
- while (1) {
- Node* next = node->nextSibling();
- removeNode(node);
- insertNodeBefore(node, refNode);
-
- if (node == endNode)
- break;
-
- node = next;
- }
-}
-
-void ModifySelectionListLevelCommand::insertSiblingNodeRangeAfter(Node* startNode, Node* endNode, Node* refNode)
-{
- Node* node = startNode;
- while (1) {
- Node* next = node->nextSibling();
- removeNode(node);
- insertNodeAfter(node, refNode);
-
- if (node == endNode)
- break;
-
- refNode = node;
- node = next;
- }
-}
-
-void ModifySelectionListLevelCommand::appendSiblingNodeRange(Node* startNode, Node* endNode, Element* newParent)
-{
- Node* node = startNode;
- while (1) {
- Node* next = node->nextSibling();
- removeNode(node);
- appendNode(node, newParent);
-
- if (node == endNode)
- break;
-
- node = next;
- }
-}
-
-IncreaseSelectionListLevelCommand::IncreaseSelectionListLevelCommand(Document& document, Type listType)
- : ModifySelectionListLevelCommand(document)
- , m_listType(listType)
-{
-}
-
-// This needs to be static so it can be called by canIncreaseSelectionListLevel
-static bool canIncreaseListLevel(const VisibleSelection& selection, Node*& start, Node*& end)
-{
- if (!getStartEndListChildren(selection, start, end))
- return false;
-
- // start must not be the first child (because you need a prior one
- // to increase relative to)
- if (!start->renderer()->previousSibling())
- return false;
-
- return true;
-}
-
-// For the moment, this is SPI and the only client (Mail.app) is satisfied.
-// Here are two things to re-evaluate when making into API.
-// 1. Currently, InheritedListType uses clones whereas OrderedList and
-// UnorderedList create a new list node of the specified type. That is
-// inconsistent wrt style. If that is not OK, here are some alternatives:
-// - new nodes always inherit style (probably the best choice)
-// - new nodes have always have no style
-// - new nodes of the same type inherit style
-// 2. Currently, the node we return may be either a pre-existing one or
-// a new one. Is it confusing to return the pre-existing one without
-// somehow indicating that it is not new? If so, here are some alternatives:
-// - only return the list node if we created it
-// - indicate whether the list node is new or pre-existing
-// - (silly) client specifies whether to return pre-existing list nodes
-void IncreaseSelectionListLevelCommand::doApply()
-{
- Node* startListChild;
- Node* endListChild;
- if (!canIncreaseListLevel(endingSelection(), startListChild, endListChild))
- return;
-
- Node* previousItem = startListChild->renderer()->previousSibling()->node();
- if (isListElement(previousItem)) {
- // move nodes up into preceding list
- appendSiblingNodeRange(startListChild, endListChild, toElement(previousItem));
- m_listElement = previousItem;
- } else {
- // create a sublist for the preceding element and move nodes there
- RefPtr<Element> newParent;
- switch (m_listType) {
- case InheritedListType:
- newParent = startListChild->parentElement();
- if (newParent)
- newParent = newParent->cloneElementWithoutChildren();
- break;
- case OrderedList:
- newParent = createOrderedListElement(document());
- break;
- case UnorderedList:
- newParent = createUnorderedListElement(document());
- break;
- }
- insertNodeBefore(newParent, startListChild);
- appendSiblingNodeRange(startListChild, endListChild, newParent.get());
- m_listElement = newParent.release();
- }
-}
-
-bool IncreaseSelectionListLevelCommand::canIncreaseSelectionListLevel(Document& document)
-{
- Node* startListChild;
- Node* endListChild;
- return canIncreaseListLevel(document.frame()->selection().selection(), startListChild, endListChild);
-}
-
-PassRefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevel(Document& document, Type type)
-{
- ASSERT(document.frame());
- RefPtr<IncreaseSelectionListLevelCommand> command = create(document, type);
- command->apply();
- return command->m_listElement.release();
-}
-
-PassRefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevel(Document& document)
-{
- return increaseSelectionListLevel(document, InheritedListType);
-}
-
-PassRefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevelOrdered(Document& document)
-{
- return increaseSelectionListLevel(document, OrderedList);
-}
-
-PassRefPtr<Node> IncreaseSelectionListLevelCommand::increaseSelectionListLevelUnordered(Document& document)
-{
- return increaseSelectionListLevel(document, UnorderedList);
-}
-
-DecreaseSelectionListLevelCommand::DecreaseSelectionListLevelCommand(Document& document)
- : ModifySelectionListLevelCommand(document)
-{
-}
-
-// This needs to be static so it can be called by canDecreaseSelectionListLevel
-static bool canDecreaseListLevel(const VisibleSelection& selection, Node*& start, Node*& end)
-{
- if (!getStartEndListChildren(selection, start, end))
- return false;
-
- // there must be a destination list to move the items to
- if (!isListElement(start->parentNode()->parentNode()))
- return false;
-
- return true;
-}
-
-void DecreaseSelectionListLevelCommand::doApply()
-{
- Node* startListChild;
- Node* endListChild;
- if (!canDecreaseListLevel(endingSelection(), startListChild, endListChild))
- return;
-
- Node* previousItem = startListChild->renderer()->previousSibling() ? startListChild->renderer()->previousSibling()->node() : 0;
- Node* nextItem = endListChild->renderer()->nextSibling() ? endListChild->renderer()->nextSibling()->node() : 0;
- Element* listNode = startListChild->parentElement();
-
- if (!previousItem) {
- // at start of sublist, move the child(ren) to before the sublist
- insertSiblingNodeRangeBefore(startListChild, endListChild, listNode);
- // if that was the whole sublist we moved, remove the sublist node
- if (!nextItem)
- removeNode(listNode);
- } else if (!nextItem) {
- // at end of list, move the child(ren) to after the sublist
- insertSiblingNodeRangeAfter(startListChild, endListChild, listNode);
- } else if (listNode) {
- // in the middle of list, split the list and move the children to the divide
- splitElement(listNode, startListChild);
- insertSiblingNodeRangeBefore(startListChild, endListChild, listNode);
- }
-}
-
-bool DecreaseSelectionListLevelCommand::canDecreaseSelectionListLevel(Document& document)
-{
- Node* startListChild;
- Node* endListChild;
- return canDecreaseListLevel(document.frame()->selection().selection(), startListChild, endListChild);
-}
-
-void DecreaseSelectionListLevelCommand::decreaseSelectionListLevel(Document& document)
-{
- ASSERT(document.frame());
- create(document)->apply();
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/editing/ModifySelectionListLevel.h b/chromium/third_party/WebKit/Source/core/editing/ModifySelectionListLevel.h
deleted file mode 100644
index b8707281e46..00000000000
--- a/chromium/third_party/WebKit/Source/core/editing/ModifySelectionListLevel.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ModifySelectionListLevel_h
-#define ModifySelectionListLevel_h
-
-#include "core/editing/CompositeEditCommand.h"
-
-namespace WebCore {
-
-// ModifySelectionListLevelCommand provides functions useful for both increasing and decreasing the list level.
-// It is the base class of IncreaseSelectionListLevelCommand and DecreaseSelectionListLevelCommand.
-// It is not used on its own.
-class ModifySelectionListLevelCommand : public CompositeEditCommand {
-protected:
- explicit ModifySelectionListLevelCommand(Document&);
-
- void appendSiblingNodeRange(Node* startNode, Node* endNode, Element* newParent);
- void insertSiblingNodeRangeBefore(Node* startNode, Node* endNode, Node* refNode);
- void insertSiblingNodeRangeAfter(Node* startNode, Node* endNode, Node* refNode);
-
-private:
- virtual bool preservesTypingStyle() const;
-};
-
-// IncreaseSelectionListLevelCommand moves the selected list items one level deeper.
-class IncreaseSelectionListLevelCommand : public ModifySelectionListLevelCommand {
-public:
- static bool canIncreaseSelectionListLevel(Document&);
- static PassRefPtr<Node> increaseSelectionListLevel(Document&);
- static PassRefPtr<Node> increaseSelectionListLevelOrdered(Document&);
- static PassRefPtr<Node> increaseSelectionListLevelUnordered(Document&);
-
-private:
- enum Type { InheritedListType, OrderedList, UnorderedList };
- static PassRefPtr<Node> increaseSelectionListLevel(Document&, Type);
-
- static PassRefPtr<IncreaseSelectionListLevelCommand> create(Document& document, Type type)
- {
- return adoptRef(new IncreaseSelectionListLevelCommand(document, type));
- }
-
- IncreaseSelectionListLevelCommand(Document&, Type);
-
- virtual void doApply();
-
- Type m_listType;
- RefPtr<Node> m_listElement;
-};
-
-// DecreaseSelectionListLevelCommand moves the selected list items one level shallower.
-class DecreaseSelectionListLevelCommand : public ModifySelectionListLevelCommand {
-public:
- static bool canDecreaseSelectionListLevel(Document&);
- static void decreaseSelectionListLevel(Document&);
-
-private:
- static PassRefPtr<DecreaseSelectionListLevelCommand> create(Document& document)
- {
- return adoptRef(new DecreaseSelectionListLevelCommand(document));
- }
-
- explicit DecreaseSelectionListLevelCommand(Document&);
-
- virtual void doApply();
-};
-
-} // namespace WebCore
-
-#endif // ModifySelectionListLevel_h
diff --git a/chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.cpp
index 7d45d37106b..5beeccc5665 100644
--- a/chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-MoveSelectionCommand::MoveSelectionCommand(PassRefPtr<DocumentFragment> fragment, const Position& position, bool smartInsert, bool smartDelete)
+MoveSelectionCommand::MoveSelectionCommand(PassRefPtrWillBeRawPtr<DocumentFragment> fragment, const Position& position, bool smartInsert, bool smartDelete)
: CompositeEditCommand(*position.document()), m_fragment(fragment), m_position(position), m_smartInsert(smartInsert), m_smartDelete(smartDelete)
{
ASSERT(m_fragment);
@@ -65,7 +65,7 @@ void MoveSelectionCommand::doApply()
if (!pos.inDocument())
pos = endingSelection().start();
- cleanupAfterDeletion(pos);
+ cleanupAfterDeletion(VisiblePosition(pos));
setEndingSelection(VisibleSelection(pos, endingSelection().affinity(), endingSelection().isDirectional()));
if (!pos.inDocument()) {
@@ -83,4 +83,11 @@ EditAction MoveSelectionCommand::editingAction() const
return EditActionDrag;
}
+void MoveSelectionCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_fragment);
+ visitor->trace(m_position);
+ CompositeEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.h b/chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.h
index f952d5f011b..dd55c6f7592 100644
--- a/chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/MoveSelectionCommand.h
@@ -32,20 +32,22 @@ namespace WebCore {
class DocumentFragment;
-class MoveSelectionCommand : public CompositeEditCommand {
+class MoveSelectionCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<MoveSelectionCommand> create(PassRefPtr<DocumentFragment> fragment, const Position& position, bool smartInsert = false, bool smartDelete = false)
+ static PassRefPtrWillBeRawPtr<MoveSelectionCommand> create(PassRefPtrWillBeRawPtr<DocumentFragment> fragment, const Position& position, bool smartInsert = false, bool smartDelete = false)
{
- return adoptRef(new MoveSelectionCommand(fragment, position, smartInsert, smartDelete));
+ return adoptRefWillBeNoop(new MoveSelectionCommand(fragment, position, smartInsert, smartDelete));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- MoveSelectionCommand(PassRefPtr<DocumentFragment>, const Position&, bool smartInsert, bool smartDelete);
+ MoveSelectionCommand(PassRefPtrWillBeRawPtr<DocumentFragment>, const Position&, bool smartInsert, bool smartDelete);
- virtual void doApply();
- virtual EditAction editingAction() const;
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE;
- RefPtr<DocumentFragment> m_fragment;
+ RefPtrWillBeMember<DocumentFragment> m_fragment;
Position m_position;
bool m_smartInsert;
bool m_smartDelete;
diff --git a/chromium/third_party/WebKit/Source/core/editing/PlainTextRange.cpp b/chromium/third_party/WebKit/Source/core/editing/PlainTextRange.cpp
index 82f321566d7..ff63a5ef92d 100644
--- a/chromium/third_party/WebKit/Source/core/editing/PlainTextRange.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/PlainTextRange.cpp
@@ -57,28 +57,31 @@ PlainTextRange::PlainTextRange(int start, int end)
ASSERT(start <= end);
}
-PassRefPtr<Range> PlainTextRange::createRange(const ContainerNode& scope) const
+PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRange(const ContainerNode& scope) const
{
return createRangeFor(scope, ForGeneric);
}
-PassRefPtr<Range> PlainTextRange::createRangeForSelection(const ContainerNode& scope) const
+PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRangeForSelection(const ContainerNode& scope) const
{
return createRangeFor(scope, ForSelection);
}
-PassRefPtr<Range> PlainTextRange::createRangeFor(const ContainerNode& scope, GetRangeFor getRangeFor) const
+PassRefPtrWillBeRawPtr<Range> PlainTextRange::createRangeFor(const ContainerNode& scope, GetRangeFor getRangeFor) const
{
ASSERT(isNotNull());
- RefPtr<Range> resultRange = scope.document().createRange();
+ RefPtrWillBeRawPtr<Range> resultRange = scope.document().createRange();
size_t docTextPosition = 0;
bool startRangeFound = false;
- RefPtr<Range> textRunRange;
+ RefPtrWillBeRawPtr<Range> textRunRange = nullptr;
- TextIterator it(rangeOfContents(const_cast<ContainerNode*>(&scope)).get(), getRangeFor == ForSelection ? TextIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior);
+ TextIteratorBehaviorFlags behaviorFlags = TextIteratorEmitsObjectReplacementCharacter;
+ if (getRangeFor == ForSelection)
+ behaviorFlags |= TextIteratorEmitsCharactersBetweenAllVisiblePositions;
+ TextIterator it(rangeOfContents(const_cast<ContainerNode*>(&scope)).get(), behaviorFlags);
// FIXME: the atEnd() check shouldn't be necessary, workaround for <http://bugs.webkit.org/show_bug.cgi?id=6289>.
if (!start() && !length() && it.atEnd()) {
@@ -106,7 +109,7 @@ PassRefPtr<Range> PlainTextRange::createRangeFor(const ContainerNode& scope, Get
scope.document().updateLayoutIgnorePendingStylesheets();
it.advance();
if (!it.atEnd()) {
- RefPtr<Range> range = it.range();
+ RefPtrWillBeRawPtr<Range> range = it.range();
textRunRange->setEnd(range->startContainer(), range->startOffset(), ASSERT_NO_EXCEPTION);
} else {
Position runStart = textRunRange->startPosition();
@@ -147,7 +150,7 @@ PassRefPtr<Range> PlainTextRange::createRangeFor(const ContainerNode& scope, Get
}
if (!startRangeFound)
- return 0;
+ return nullptr;
if (length() && end() > docTextPosition) { // end() is out of bounds
resultRange->setEnd(textRunRange->endContainer(), textRunRange->endOffset(), IGNORE_EXCEPTION);
@@ -171,7 +174,7 @@ PlainTextRange PlainTextRange::create(const Node& scope, const Range& range)
if (range.endContainer() != scope && !range.endContainer()->isDescendantOf(&scope))
return PlainTextRange();
- RefPtr<Range> testRange = Range::create(scope.document(), const_cast<Node*>(&scope), 0, range.startContainer(), range.startOffset());
+ RefPtrWillBeRawPtr<Range> testRange = Range::create(scope.document(), const_cast<Node*>(&scope), 0, range.startContainer(), range.startOffset());
ASSERT(testRange->startContainer() == &scope);
size_t start = TextIterator::rangeLength(testRange.get());
diff --git a/chromium/third_party/WebKit/Source/core/editing/PlainTextRange.h b/chromium/third_party/WebKit/Source/core/editing/PlainTextRange.h
index faf200a334a..d3e2617a666 100644
--- a/chromium/third_party/WebKit/Source/core/editing/PlainTextRange.h
+++ b/chromium/third_party/WebKit/Source/core/editing/PlainTextRange.h
@@ -26,6 +26,7 @@
#ifndef PlainTextRange_h
#define PlainTextRange_h
+#include "platform/heap/Handle.h"
#include "wtf/NotFound.h"
#include "wtf/PassRefPtr.h"
@@ -48,8 +49,8 @@ public:
bool isNotNull() const { return m_start != kNotFound; }
size_t length() const { ASSERT(!isNull()); return m_end - m_start; }
- PassRefPtr<Range> createRange(const ContainerNode& scope) const;
- PassRefPtr<Range> createRangeForSelection(const ContainerNode& scope) const;
+ PassRefPtrWillBeRawPtr<Range> createRange(const ContainerNode& scope) const;
+ PassRefPtrWillBeRawPtr<Range> createRangeForSelection(const ContainerNode& scope) const;
static PlainTextRange create(const Node& scope, const Range&);
@@ -57,7 +58,7 @@ private:
PlainTextRange& operator=(const PlainTextRange&) WTF_DELETED_FUNCTION;
enum GetRangeFor { ForGeneric, ForSelection };
- PassRefPtr<Range> createRangeFor(const ContainerNode& scope, GetRangeFor) const;
+ PassRefPtrWillBeRawPtr<Range> createRangeFor(const ContainerNode& scope, GetRangeFor) const;
const size_t m_start;
const size_t m_end;
diff --git a/chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.cpp
index 6daa8410d93..34126e33b82 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.cpp
@@ -34,7 +34,7 @@
namespace WebCore {
-RemoveCSSPropertyCommand::RemoveCSSPropertyCommand(Document& document, PassRefPtr<Element> element, CSSPropertyID property)
+RemoveCSSPropertyCommand::RemoveCSSPropertyCommand(Document& document, PassRefPtrWillBeRawPtr<Element> element, CSSPropertyID property)
: SimpleEditCommand(document)
, m_element(element)
, m_property(property)
@@ -50,6 +50,9 @@ RemoveCSSPropertyCommand::~RemoveCSSPropertyCommand()
void RemoveCSSPropertyCommand::doApply()
{
const StylePropertySet* style = m_element->inlineStyle();
+ if (!style)
+ return;
+
m_oldValue = style->getPropertyValue(m_property);
m_important = style->propertyIsImportant(m_property);
@@ -63,4 +66,10 @@ void RemoveCSSPropertyCommand::doUnapply()
m_element->style()->setPropertyInternal(m_property, m_oldValue, m_important, IGNORE_EXCEPTION);
}
+void RemoveCSSPropertyCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.h b/chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.h
index 85d61566055..c7fa87d6a35 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/RemoveCSSPropertyCommand.h
@@ -26,28 +26,30 @@
#ifndef RemoveCSSPropertyCommand_h
#define RemoveCSSPropertyCommand_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/editing/EditCommand.h"
namespace WebCore {
class Element;
-class RemoveCSSPropertyCommand : public SimpleEditCommand {
+class RemoveCSSPropertyCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<RemoveCSSPropertyCommand> create(Document& document, PassRefPtr<Element> element, CSSPropertyID property)
+ static PassRefPtrWillBeRawPtr<RemoveCSSPropertyCommand> create(Document& document, PassRefPtrWillBeRawPtr<Element> element, CSSPropertyID property)
{
- return adoptRef(new RemoveCSSPropertyCommand(document, element, property));
+ return adoptRefWillBeNoop(new RemoveCSSPropertyCommand(document, element, property));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- RemoveCSSPropertyCommand(Document&, PassRefPtr<Element>, CSSPropertyID);
- ~RemoveCSSPropertyCommand();
+ RemoveCSSPropertyCommand(Document&, PassRefPtrWillBeRawPtr<Element>, CSSPropertyID);
+ virtual ~RemoveCSSPropertyCommand();
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<Element> m_element;
+ RefPtrWillBeMember<Element> m_element;
CSSPropertyID m_property;
String m_oldValue;
bool m_important;
diff --git a/chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.cpp
index d36a52790d6..971c66ea2f6 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.cpp
@@ -27,14 +27,15 @@
#include "config.h"
#include "core/editing/RemoveFormatCommand.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/StylePropertySet.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/editing/ApplyStyleCommand.h"
#include "core/editing/EditingStyle.h"
#include "core/editing/FrameSelection.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
@@ -79,7 +80,7 @@ static bool isElementForRemoveFormatCommand(const Element* element)
void RemoveFormatCommand::doApply()
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame->selection().selection().isNonOrphanedCaretOrRange())
return;
@@ -87,7 +88,7 @@ void RemoveFormatCommand::doApply()
// Get the default style for this editable root, it's the style that we'll give the
// content that we're operating on.
Node* root = frame->selection().rootEditableElement();
- RefPtr<EditingStyle> defaultStyle = EditingStyle::create(root);
+ RefPtrWillBeRawPtr<EditingStyle> defaultStyle = EditingStyle::create(root);
// We want to remove everything but transparent background.
// FIXME: We shouldn't access style().
diff --git a/chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.h b/chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.h
index f6d030d9187..c32ce61691b 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/RemoveFormatCommand.h
@@ -30,18 +30,18 @@
namespace WebCore {
-class RemoveFormatCommand : public CompositeEditCommand {
+class RemoveFormatCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<RemoveFormatCommand> create(Document& document)
+ static PassRefPtrWillBeRawPtr<RemoveFormatCommand> create(Document& document)
{
- return adoptRef(new RemoveFormatCommand(document));
+ return adoptRefWillBeNoop(new RemoveFormatCommand(document));
}
private:
explicit RemoveFormatCommand(Document&);
- virtual void doApply();
- virtual EditAction editingAction() const { return EditActionUnspecified; }
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE { return EditActionUnspecified; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.cpp
index cffc8c0b8da..113b3063f25 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.cpp
@@ -32,7 +32,7 @@
namespace WebCore {
-RemoveNodeCommand::RemoveNodeCommand(PassRefPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+RemoveNodeCommand::RemoveNodeCommand(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
: SimpleEditCommand(node->document())
, m_node(node)
, m_shouldAssumeContentIsAlwaysEditable(shouldAssumeContentIsAlwaysEditable)
@@ -57,12 +57,20 @@ void RemoveNodeCommand::doApply()
void RemoveNodeCommand::doUnapply()
{
- RefPtr<ContainerNode> parent = m_parent.release();
- RefPtr<Node> refChild = m_refChild.release();
+ RefPtrWillBeRawPtr<ContainerNode> parent = m_parent.release();
+ RefPtrWillBeRawPtr<Node> refChild = m_refChild.release();
if (!parent || !parent->rendererIsEditable())
return;
parent->insertBefore(m_node.get(), refChild.get(), IGNORE_EXCEPTION);
}
+void RemoveNodeCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_node);
+ visitor->trace(m_parent);
+ visitor->trace(m_refChild);
+ SimpleEditCommand::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.h b/chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.h
index 5d15512c0c2..78aaa6ba5b1 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/RemoveNodeCommand.h
@@ -30,22 +30,24 @@
namespace WebCore {
-class RemoveNodeCommand : public SimpleEditCommand {
+class RemoveNodeCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<RemoveNodeCommand> create(PassRefPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+ static PassRefPtrWillBeRawPtr<RemoveNodeCommand> create(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
- return adoptRef(new RemoveNodeCommand(node, shouldAssumeContentIsAlwaysEditable));
+ return adoptRefWillBeNoop(new RemoveNodeCommand(node, shouldAssumeContentIsAlwaysEditable));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- explicit RemoveNodeCommand(PassRefPtr<Node>, ShouldAssumeContentIsAlwaysEditable);
+ explicit RemoveNodeCommand(PassRefPtrWillBeRawPtr<Node>, ShouldAssumeContentIsAlwaysEditable);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<Node> m_node;
- RefPtr<ContainerNode> m_parent;
- RefPtr<Node> m_refChild;
+ RefPtrWillBeMember<Node> m_node;
+ RefPtrWillBeMember<ContainerNode> m_parent;
+ RefPtrWillBeMember<Node> m_refChild;
ShouldAssumeContentIsAlwaysEditable m_shouldAssumeContentIsAlwaysEditable;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.cpp
index 977f3cc637e..e5c992114cd 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-RemoveNodePreservingChildrenCommand::RemoveNodePreservingChildrenCommand(PassRefPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+RemoveNodePreservingChildrenCommand::RemoveNodePreservingChildrenCommand(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
: CompositeEditCommand(node->document())
, m_node(node)
, m_shouldAssumeContentIsAlwaysEditable(shouldAssumeContentIsAlwaysEditable)
@@ -41,17 +41,23 @@ RemoveNodePreservingChildrenCommand::RemoveNodePreservingChildrenCommand(PassRef
void RemoveNodePreservingChildrenCommand::doApply()
{
- Vector<RefPtr<Node> > children;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > children;
for (Node* child = m_node->firstChild(); child; child = child->nextSibling())
children.append(child);
size_t size = children.size();
for (size_t i = 0; i < size; ++i) {
- RefPtr<Node> child = children[i].release();
+ RefPtrWillBeRawPtr<Node> child = children[i].release();
removeNode(child, m_shouldAssumeContentIsAlwaysEditable);
insertNodeBefore(child.release(), m_node, m_shouldAssumeContentIsAlwaysEditable);
}
removeNode(m_node, m_shouldAssumeContentIsAlwaysEditable);
}
+void RemoveNodePreservingChildrenCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_node);
+ CompositeEditCommand::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.h b/chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.h
index 6c9fdc80203..1498be24fcb 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/RemoveNodePreservingChildrenCommand.h
@@ -30,19 +30,21 @@
namespace WebCore {
-class RemoveNodePreservingChildrenCommand : public CompositeEditCommand {
+class RemoveNodePreservingChildrenCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<RemoveNodePreservingChildrenCommand> create(PassRefPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
+ static PassRefPtrWillBeRawPtr<RemoveNodePreservingChildrenCommand> create(PassRefPtrWillBeRawPtr<Node> node, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
{
- return adoptRef(new RemoveNodePreservingChildrenCommand(node, shouldAssumeContentIsAlwaysEditable));
+ return adoptRefWillBeNoop(new RemoveNodePreservingChildrenCommand(node, shouldAssumeContentIsAlwaysEditable));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- explicit RemoveNodePreservingChildrenCommand(PassRefPtr<Node>, ShouldAssumeContentIsAlwaysEditable);
+ RemoveNodePreservingChildrenCommand(PassRefPtrWillBeRawPtr<Node>, ShouldAssumeContentIsAlwaysEditable);
- virtual void doApply();
+ virtual void doApply() OVERRIDE;
- RefPtr<Node> m_node;
+ RefPtrWillBeMember<Node> m_node;
ShouldAssumeContentIsAlwaysEditable m_shouldAssumeContentIsAlwaysEditable;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/RenderedPosition.cpp b/chromium/third_party/WebKit/Source/core/editing/RenderedPosition.cpp
index a3646533789..beb15ae93a7 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RenderedPosition.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/RenderedPosition.cpp
@@ -74,7 +74,7 @@ RenderedPosition::RenderedPosition(const VisiblePosition& position)
return;
position.getInlineBoxAndOffset(m_inlineBox, m_offset);
if (m_inlineBox)
- m_renderer = m_inlineBox->renderer();
+ m_renderer = &m_inlineBox->renderer();
else
m_renderer = rendererFromPosition(position.deepEquivalent());
}
@@ -90,7 +90,7 @@ RenderedPosition::RenderedPosition(const Position& position, EAffinity affinity)
return;
position.getInlineBoxAndOffset(affinity, m_inlineBox, m_offset);
if (m_inlineBox)
- m_renderer = m_inlineBox->renderer();
+ m_renderer = &m_inlineBox->renderer();
else
m_renderer = rendererFromPosition(position);
}
@@ -137,7 +137,7 @@ RenderedPosition RenderedPosition::leftBoundaryOfBidiRun(unsigned char bidiLevel
do {
InlineBox* prev = box->prevLeafChildIgnoringLineBreak();
if (!prev || prev->bidiLevel() < bidiLevelOfRun)
- return RenderedPosition(box->renderer(), box, box->caretLeftmostOffset());
+ return RenderedPosition(&box->renderer(), box, box->caretLeftmostOffset());
box = prev;
} while (box);
@@ -154,7 +154,7 @@ RenderedPosition RenderedPosition::rightBoundaryOfBidiRun(unsigned char bidiLeve
do {
InlineBox* next = box->nextLeafChildIgnoringLineBreak();
if (!next || next->bidiLevel() < bidiLevelOfRun)
- return RenderedPosition(box->renderer(), box, box->caretRightmostOffset());
+ return RenderedPosition(&box->renderer(), box, box->caretRightmostOffset());
box = next;
} while (box);
@@ -209,7 +209,7 @@ Position RenderedPosition::positionAtLeftBoundaryOfBiDiRun() const
if (atLeftmostOffsetInBox())
return createLegacyEditingPosition(m_renderer->node(), m_offset);
- return createLegacyEditingPosition(nextLeafChild()->renderer()->node(), nextLeafChild()->caretLeftmostOffset());
+ return createLegacyEditingPosition(nextLeafChild()->renderer().node(), nextLeafChild()->caretLeftmostOffset());
}
Position RenderedPosition::positionAtRightBoundaryOfBiDiRun() const
@@ -219,7 +219,7 @@ Position RenderedPosition::positionAtRightBoundaryOfBiDiRun() const
if (atRightmostOffsetInBox())
return createLegacyEditingPosition(m_renderer->node(), m_offset);
- return createLegacyEditingPosition(prevLeafChild()->renderer()->node(), prevLeafChild()->caretRightmostOffset());
+ return createLegacyEditingPosition(prevLeafChild()->renderer().node(), prevLeafChild()->caretRightmostOffset());
}
IntRect RenderedPosition::absoluteRect(LayoutUnit* extraWidthToEndOfLine) const
diff --git a/chromium/third_party/WebKit/Source/core/editing/RenderedPosition.h b/chromium/third_party/WebKit/Source/core/editing/RenderedPosition.h
index 7cf21952631..fff2d2b5e4a 100644
--- a/chromium/third_party/WebKit/Source/core/editing/RenderedPosition.h
+++ b/chromium/third_party/WebKit/Source/core/editing/RenderedPosition.h
@@ -49,7 +49,7 @@ public:
bool isEquivalent(const RenderedPosition&) const;
bool isNull() const { return !m_renderer; }
- RootInlineBox* rootBox() { return m_inlineBox ? m_inlineBox->root() : 0; }
+ RootInlineBox* rootBox() { return m_inlineBox ? &m_inlineBox->root() : 0; }
unsigned char bidiLevelOnLeft() const;
unsigned char bidiLevelOnRight() const;
diff --git a/chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.cpp
index 477177d46ac..ff947b0c7c6 100644
--- a/chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/editing/ReplaceNodeWithSpanCommand.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/editing/htmlediting.h"
#include "core/html/HTMLElement.h"
#include "wtf/Assertions.h"
@@ -41,7 +41,7 @@ namespace WebCore {
using namespace HTMLNames;
-ReplaceNodeWithSpanCommand::ReplaceNodeWithSpanCommand(PassRefPtr<HTMLElement> element)
+ReplaceNodeWithSpanCommand::ReplaceNodeWithSpanCommand(PassRefPtrWillBeRawPtr<HTMLElement> element)
: SimpleEditCommand(element->document())
, m_elementToReplace(element)
{
@@ -51,7 +51,7 @@ ReplaceNodeWithSpanCommand::ReplaceNodeWithSpanCommand(PassRefPtr<HTMLElement> e
static void swapInNodePreservingAttributesAndChildren(HTMLElement* newNode, HTMLElement& nodeToReplace)
{
ASSERT(nodeToReplace.inDocument());
- RefPtr<ContainerNode> parentNode = nodeToReplace.parentNode();
+ RefPtrWillBeRawPtr<ContainerNode> parentNode = nodeToReplace.parentNode();
parentNode->insertBefore(newNode, &nodeToReplace);
NodeVector children;
@@ -81,4 +81,11 @@ void ReplaceNodeWithSpanCommand::doUnapply()
swapInNodePreservingAttributesAndChildren(m_elementToReplace.get(), *m_spanElement);
}
+void ReplaceNodeWithSpanCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_elementToReplace);
+ visitor->trace(m_spanElement);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.h b/chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.h
index e9e8afeaa9a..6d1f13b132b 100644
--- a/chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/ReplaceNodeWithSpanCommand.h
@@ -38,23 +38,25 @@ namespace WebCore {
class HTMLElement;
// More accurately, this is ReplaceElementWithSpanPreservingChildrenAndAttributesCommand
-class ReplaceNodeWithSpanCommand : public SimpleEditCommand {
+class ReplaceNodeWithSpanCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<ReplaceNodeWithSpanCommand> create(PassRefPtr<HTMLElement> element)
+ static PassRefPtrWillBeRawPtr<ReplaceNodeWithSpanCommand> create(PassRefPtrWillBeRawPtr<HTMLElement> element)
{
- return adoptRef(new ReplaceNodeWithSpanCommand(element));
+ return adoptRefWillBeNoop(new ReplaceNodeWithSpanCommand(element));
}
HTMLElement* spanElement() { return m_spanElement.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- explicit ReplaceNodeWithSpanCommand(PassRefPtr<HTMLElement>);
+ explicit ReplaceNodeWithSpanCommand(PassRefPtrWillBeRawPtr<HTMLElement>);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<HTMLElement> m_elementToReplace;
- RefPtr<HTMLElement> m_spanElement;
+ RefPtrWillBeMember<HTMLElement> m_elementToReplace;
+ RefPtrWillBeMember<HTMLElement> m_spanElement;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.cpp
index 16d13f62d11..aea9badf720 100644
--- a/chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.cpp
@@ -27,9 +27,9 @@
#include "config.h"
#include "core/editing/ReplaceSelectionCommand.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSStyleDeclaration.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Document.h"
@@ -47,11 +47,10 @@
#include "core/editing/htmlediting.h"
#include "core/editing/markup.h"
#include "core/events/BeforeTextInsertedEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLInputElement.h"
-#include "core/html/HTMLTitleElement.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderText.h"
#include "wtf/StdLibExtras.h"
@@ -65,8 +64,9 @@ enum EFragmentType { EmptyFragment, SingleTextNodeFragment, TreeFragment };
// --- ReplacementFragment helper class
-class ReplacementFragment {
+class ReplacementFragment FINAL {
WTF_MAKE_NONCOPYABLE(ReplacementFragment);
+ STACK_ALLOCATED();
public:
ReplacementFragment(Document*, DocumentFragment*, const VisibleSelection&);
@@ -78,19 +78,19 @@ public:
bool hasInterchangeNewlineAtStart() const { return m_hasInterchangeNewlineAtStart; }
bool hasInterchangeNewlineAtEnd() const { return m_hasInterchangeNewlineAtEnd; }
- void removeNode(PassRefPtr<Node>);
- void removeNodePreservingChildren(PassRefPtr<Node>);
+ void removeNode(PassRefPtrWillBeRawPtr<Node>);
+ void removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node>);
private:
- PassRefPtr<Element> insertFragmentForTestRendering(Node* rootEditableNode);
+ PassRefPtrWillBeRawPtr<Element> insertFragmentForTestRendering(Node* rootEditableNode);
void removeUnrenderedNodes(Node*);
void restoreAndRemoveTestRenderingNodesToFragment(Element*);
void removeInterchangeNodes(Node*);
- void insertNodeBefore(PassRefPtr<Node> node, Node* refNode);
+ void insertNodeBefore(PassRefPtrWillBeRawPtr<Node>, Node* refNode);
- RefPtr<Document> m_document;
- RefPtr<DocumentFragment> m_fragment;
+ RefPtrWillBeMember<Document> m_document;
+ RefPtrWillBeMember<DocumentFragment> m_fragment;
bool m_hasInterchangeNewlineAtStart;
bool m_hasInterchangeNewlineAtEnd;
};
@@ -98,13 +98,19 @@ private:
static bool isInterchangeNewlineNode(const Node *node)
{
DEFINE_STATIC_LOCAL(String, interchangeNewlineClassString, (AppleInterchangeNewline));
- return node && node->hasTagName(brTag) && toElement(node)->getAttribute(classAttr) == interchangeNewlineClassString;
+ if (!isHTMLBRElement(node) || toElement(node)->getAttribute(classAttr) != interchangeNewlineClassString)
+ return false;
+ UseCounter::count(node->document(), UseCounter::EditingAppleInterchangeNewline);
+ return true;
}
static bool isInterchangeConvertedSpaceSpan(const Node *node)
{
DEFINE_STATIC_LOCAL(String, convertedSpaceSpanClassString, (AppleConvertedSpace));
- return node->isHTMLElement() && toHTMLElement(node)->getAttribute(classAttr) == convertedSpaceSpanClassString;
+ if (!node->isHTMLElement() || toHTMLElement(node)->getAttribute(classAttr) != convertedSpaceSpanClassString)
+ return false;
+ UseCounter::count(node->document(), UseCounter::EditingAppleConvertedSpace);
+ return true;
}
static Position positionAvoidingPrecedingNodes(Position pos)
@@ -123,7 +129,7 @@ static Position positionAvoidingPrecedingNodes(Position pos)
break;
if (pos.containerNode()->nonShadowBoundaryParentNode())
- nextPosition = positionInParentAfterNode(pos.containerNode());
+ nextPosition = positionInParentAfterNode(*pos.containerNode());
if (nextPosition == pos
|| enclosingBlock(nextPosition.containerNode()) != enclosingBlockNode
@@ -146,7 +152,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
if (!m_fragment->firstChild())
return;
- RefPtr<Element> editableRoot = selection.rootEditableElement();
+ RefPtrWillBeRawPtr<Element> editableRoot = selection.rootEditableElement();
ASSERT(editableRoot);
if (!editableRoot)
return;
@@ -161,13 +167,13 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
return;
}
- RefPtr<Element> holder = insertFragmentForTestRendering(editableRoot.get());
+ RefPtrWillBeRawPtr<Element> holder = insertFragmentForTestRendering(editableRoot.get());
if (!holder) {
removeInterchangeNodes(m_fragment.get());
return;
}
- RefPtr<Range> range = VisibleSelection::selectionFromContentsOfNode(holder.get()).toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> range = VisibleSelection::selectionFromContentsOfNode(holder.get()).toNormalizedRange();
String text = plainText(range.get(), static_cast<TextIteratorBehavior>(TextIteratorEmitsOriginalText | TextIteratorIgnoresStyleVisibility));
removeInterchangeNodes(holder.get());
@@ -175,7 +181,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
restoreAndRemoveTestRenderingNodesToFragment(holder.get());
// Give the root a chance to change the text.
- RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
+ RefPtrWillBeRawPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
editableRoot->dispatchEvent(evt, ASSERT_NO_EXCEPTION);
if (text != evt->text() || !editableRoot->rendererIsRichlyEditable()) {
restoreAndRemoveTestRenderingNodesToFragment(holder.get());
@@ -206,19 +212,19 @@ Node *ReplacementFragment::lastChild() const
return m_fragment ? m_fragment->lastChild() : 0;
}
-void ReplacementFragment::removeNodePreservingChildren(PassRefPtr<Node> node)
+void ReplacementFragment::removeNodePreservingChildren(PassRefPtrWillBeRawPtr<Node> node)
{
if (!node)
return;
- while (RefPtr<Node> n = node->firstChild()) {
+ while (RefPtrWillBeRawPtr<Node> n = node->firstChild()) {
removeNode(n);
insertNodeBefore(n.release(), node.get());
}
removeNode(node);
}
-void ReplacementFragment::removeNode(PassRefPtr<Node> node)
+void ReplacementFragment::removeNode(PassRefPtrWillBeRawPtr<Node> node)
{
if (!node)
return;
@@ -230,7 +236,7 @@ void ReplacementFragment::removeNode(PassRefPtr<Node> node)
parent->removeChild(node.get());
}
-void ReplacementFragment::insertNodeBefore(PassRefPtr<Node> node, Node* refNode)
+void ReplacementFragment::insertNodeBefore(PassRefPtrWillBeRawPtr<Node> node, Node* refNode)
{
if (!node || !refNode)
return;
@@ -242,10 +248,10 @@ void ReplacementFragment::insertNodeBefore(PassRefPtr<Node> node, Node* refNode)
parent->insertBefore(node, refNode);
}
-PassRefPtr<Element> ReplacementFragment::insertFragmentForTestRendering(Node* rootEditableElement)
+PassRefPtrWillBeRawPtr<Element> ReplacementFragment::insertFragmentForTestRendering(Node* rootEditableElement)
{
ASSERT(m_document);
- RefPtr<Element> holder = createDefaultParagraphElement(*m_document.get());
+ RefPtrWillBeRawPtr<Element> holder = createDefaultParagraphElement(*m_document.get());
holder->appendChild(m_fragment);
rootEditableElement->appendChild(holder.get());
@@ -259,7 +265,7 @@ void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element*
if (!holder)
return;
- while (RefPtr<Node> node = holder->firstChild()) {
+ while (RefPtrWillBeRawPtr<Node> node = holder->firstChild()) {
holder->removeChild(node.get());
m_fragment->appendChild(node.get());
}
@@ -269,7 +275,7 @@ void ReplacementFragment::restoreAndRemoveTestRenderingNodesToFragment(Element*
void ReplacementFragment::removeUnrenderedNodes(Node* holder)
{
- Vector<RefPtr<Node> > unrendered;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > unrendered;
for (Node* node = holder->firstChild(); node; node = NodeTraversal::next(*node, holder))
if (!isNodeRendered(node) && !isTableStructureNode(node))
@@ -296,7 +302,7 @@ void ReplacementFragment::removeInterchangeNodes(Node* container)
}
node = node->firstChild();
}
- if (!container->hasChildNodes())
+ if (!container->hasChildren())
return;
// Interchange newlines at the "end" of the incoming fragment must be
// either the last node in the fragment or the last leaf in the fragment.
@@ -312,7 +318,7 @@ void ReplacementFragment::removeInterchangeNodes(Node* container)
node = container->firstChild();
while (node) {
- RefPtr<Node> next = NodeTraversal::next(*node);
+ RefPtrWillBeRawPtr<Node> next = NodeTraversal::next(*node);
if (isInterchangeConvertedSpaceSpan(node)) {
next = NodeTraversal::nextSkippingChildren(*node);
removeNodePreservingChildren(node);
@@ -331,33 +337,33 @@ inline void ReplaceSelectionCommand::InsertedNodes::respondToNodeInsertion(Node&
inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChildren(Node& node)
{
- if (m_firstNodeInserted == node)
+ if (m_firstNodeInserted.get() == node)
m_firstNodeInserted = NodeTraversal::next(node);
- if (m_lastNodeInserted == node)
+ if (m_lastNodeInserted.get() == node)
m_lastNodeInserted = node.lastChild() ? node.lastChild() : NodeTraversal::nextSkippingChildren(node);
}
inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node& node)
{
- if (m_firstNodeInserted == node && m_lastNodeInserted == node) {
- m_firstNodeInserted = 0;
- m_lastNodeInserted = 0;
- } else if (m_firstNodeInserted == node) {
+ if (m_firstNodeInserted.get() == node && m_lastNodeInserted.get() == node) {
+ m_firstNodeInserted = nullptr;
+ m_lastNodeInserted = nullptr;
+ } else if (m_firstNodeInserted.get() == node) {
m_firstNodeInserted = NodeTraversal::nextSkippingChildren(*m_firstNodeInserted);
- } else if (m_lastNodeInserted == node) {
+ } else if (m_lastNodeInserted.get() == node) {
m_lastNodeInserted = NodeTraversal::previousSkippingChildren(*m_lastNodeInserted);
}
}
inline void ReplaceSelectionCommand::InsertedNodes::didReplaceNode(Node& node, Node& newNode)
{
- if (m_firstNodeInserted == node)
+ if (m_firstNodeInserted.get() == node)
m_firstNodeInserted = &newNode;
- if (m_lastNodeInserted == node)
+ if (m_lastNodeInserted.get() == node)
m_lastNodeInserted = &newNode;
}
-ReplaceSelectionCommand::ReplaceSelectionCommand(Document& document, PassRefPtr<DocumentFragment> fragment, CommandOptions options, EditAction editAction)
+ReplaceSelectionCommand::ReplaceSelectionCommand(Document& document, PassRefPtrWillBeRawPtr<DocumentFragment> fragment, CommandOptions options, EditAction editAction)
: CompositeEditCommand(document)
, m_selectReplacement(options & SelectReplacement)
, m_smartReplace(options & SmartReplace)
@@ -400,7 +406,7 @@ bool ReplaceSelectionCommand::shouldMergeStart(bool selectionStartWasStartOfPara
return !selectionStartWasStartOfParagraph
&& !fragmentHasInterchangeNewlineAtStart
&& isStartOfParagraph(startOfInsertedContent)
- && !startOfInsertedContent.deepEquivalent().deprecatedNode()->hasTagName(brTag)
+ && !isHTMLBRElement(*startOfInsertedContent.deepEquivalent().deprecatedNode())
&& shouldMerge(startOfInsertedContent, prev);
}
@@ -413,13 +419,16 @@ bool ReplaceSelectionCommand::shouldMergeEnd(bool selectionEndWasEndOfParagraph)
return !selectionEndWasEndOfParagraph
&& isEndOfParagraph(endOfInsertedContent)
- && !endOfInsertedContent.deepEquivalent().deprecatedNode()->hasTagName(brTag)
+ && !isHTMLBRElement(*endOfInsertedContent.deepEquivalent().deprecatedNode())
&& shouldMerge(endOfInsertedContent, next);
}
static bool isMailPasteAsQuotationNode(const Node* node)
{
- return node && node->hasTagName(blockquoteTag) && node->isElementNode() && toElement(node)->getAttribute(classAttr) == ApplePasteAsQuotation;
+ if (!node || !node->hasTagName(blockquoteTag) || toElement(node)->getAttribute(classAttr) != ApplePasteAsQuotation)
+ return false;
+ UseCounter::count(node->document(), UseCounter::EditingApplePasteAsQuotation);
+ return true;
}
static bool isHeaderElement(const Node* a)
@@ -463,9 +472,9 @@ bool ReplaceSelectionCommand::shouldMerge(const VisiblePosition& source, const V
// a div inserted into a document with div { display:inline; }.
void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(InsertedNodes& insertedNodes)
{
- RefPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
- RefPtr<Node> next;
- for (RefPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
+ RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
+ RefPtrWillBeRawPtr<Node> next = nullptr;
+ for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
// FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
next = NodeTraversal::next(*node);
@@ -475,7 +484,7 @@ void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert
Element* element = toElement(node);
const StylePropertySet* inlineStyle = element->inlineStyle();
- RefPtr<EditingStyle> newInlineStyle = EditingStyle::create(inlineStyle);
+ RefPtrWillBeRawPtr<EditingStyle> newInlineStyle = EditingStyle::create(inlineStyle);
if (inlineStyle) {
if (element->isHTMLElement()) {
Vector<QualifiedName> attributes;
@@ -486,6 +495,7 @@ void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert
// e.g. <b style="font-weight: normal;"> is converted to <span style="font-weight: normal;">
node = replaceElementWithSpanPreservingChildrenAndAttributes(htmlElement);
element = toElement(node);
+ inlineStyle = element->inlineStyle();
insertedNodes.didReplaceNode(*htmlElement, *node);
} else if (newInlineStyle->extractConflictingImplicitStyleOfAttributes(htmlElement, EditingStyle::PreserveWritingDirection, 0, attributes,
EditingStyle::DoNotExtractMatchingStyle)) {
@@ -518,7 +528,7 @@ void ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline(Insert
}
// FIXME: Tolerate differences in id, class, and style attributes.
- if (isNonTableCellHTMLBlockElement(element) && areIdenticalElements(element, element->parentNode())
+ if (element->parentNode() && isNonTableCellHTMLBlockElement(element) && areIdenticalElements(element, element->parentNode())
&& VisiblePosition(firstPositionInNode(element->parentNode())) == VisiblePosition(firstPositionInNode(element))
&& VisiblePosition(lastPositionInNode(element->parentNode())) == VisiblePosition(lastPositionInNode(element))) {
insertedNodes.willRemoveNodePreservingChildren(*element);
@@ -610,38 +620,38 @@ static bool isProhibitedParagraphChild(const AtomicString& name)
return elements.contains(name);
}
-void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder(InsertedNodes& insertedNodes)
+void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes& insertedNodes)
{
- RefPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
- RefPtr<Node> next;
- for (RefPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
+ RefPtrWillBeRawPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
+ RefPtrWillBeRawPtr<Node> next = nullptr;
+ for (RefPtrWillBeRawPtr<Node> node = insertedNodes.firstNodeInserted(); node && node != pastEndNode; node = next) {
next = NodeTraversal::next(*node);
if (!node->isHTMLElement())
continue;
if (isProhibitedParagraphChild(toHTMLElement(node)->localName())) {
- if (HTMLElement* paragraphElement = toHTMLElement(enclosingNodeWithTag(positionInParentBeforeNode(node.get()), pTag)))
+ if (HTMLElement* paragraphElement = toHTMLElement(enclosingNodeWithTag(positionInParentBeforeNode(*node), pTag)))
moveNodeOutOfAncestor(node, paragraphElement);
}
if (isHeaderElement(node.get())) {
- if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(node.get()), isHeaderElement)))
+ if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(*node), isHeaderElement)))
moveNodeOutOfAncestor(node, headerElement);
}
}
}
-void ReplaceSelectionCommand::moveNodeOutOfAncestor(PassRefPtr<Node> prpNode, PassRefPtr<Node> prpAncestor)
+void ReplaceSelectionCommand::moveNodeOutOfAncestor(PassRefPtrWillBeRawPtr<Node> prpNode, PassRefPtrWillBeRawPtr<Node> prpAncestor)
{
- RefPtr<Node> node = prpNode;
- RefPtr<Node> ancestor = prpAncestor;
+ RefPtrWillBeRawPtr<Node> node = prpNode;
+ RefPtrWillBeRawPtr<Node> ancestor = prpAncestor;
if (!ancestor->parentNode()->rendererIsEditable())
return;
- VisiblePosition positionAtEndOfNode = lastPositionInOrAfterNode(node.get());
- VisiblePosition lastPositionInParagraph = lastPositionInNode(ancestor.get());
+ VisiblePosition positionAtEndOfNode(lastPositionInOrAfterNode(node.get()));
+ VisiblePosition lastPositionInParagraph(lastPositionInNode(ancestor.get()));
if (positionAtEndOfNode == lastPositionInParagraph) {
removeNode(node);
if (ancestor->nextSibling())
@@ -649,7 +659,7 @@ void ReplaceSelectionCommand::moveNodeOutOfAncestor(PassRefPtr<Node> prpNode, Pa
else
appendNode(node, ancestor->parentNode());
} else {
- RefPtr<Node> nodeToSplitTo = splitTreeToNode(node.get(), ancestor.get(), true);
+ RefPtrWillBeRawPtr<Node> nodeToSplitTo = splitTreeToNode(node.get(), ancestor.get(), true);
removeNode(node);
insertNodeBefore(node, nodeToSplitTo);
}
@@ -666,12 +676,12 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& ins
{
document().updateLayoutIgnorePendingStylesheets();
- Node& lastLeafInserted = insertedNodes.lastLeafInserted();
- if (lastLeafInserted.isTextNode() && !nodeHasVisibleRenderText(toText(lastLeafInserted))
- && !enclosingNodeWithTag(firstPositionInOrBeforeNode(&lastLeafInserted), selectTag)
- && !enclosingNodeWithTag(firstPositionInOrBeforeNode(&lastLeafInserted), scriptTag)) {
- insertedNodes.willRemoveNode(lastLeafInserted);
- removeNode(&lastLeafInserted);
+ Node* lastLeafInserted = insertedNodes.lastLeafInserted();
+ if (lastLeafInserted && lastLeafInserted->isTextNode() && !nodeHasVisibleRenderText(toText(*lastLeafInserted))
+ && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), selectTag)
+ && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), scriptTag)) {
+ insertedNodes.willRemoveNode(*lastLeafInserted);
+ removeNode(lastLeafInserted);
}
// We don't have to make sure that firstNodeInserted isn't inside a select or script element, because
@@ -687,23 +697,23 @@ VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const
{
// FIXME: Why is this hack here? What's special about <select> tags?
Node* enclosingSelect = enclosingNodeWithTag(m_endOfInsertedContent, selectTag);
- return enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endOfInsertedContent;
+ return VisiblePosition(enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endOfInsertedContent);
}
VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent() const
{
- return m_startOfInsertedContent;
+ return VisiblePosition(m_startOfInsertedContent);
}
static void removeHeadContents(ReplacementFragment& fragment)
{
Node* next = 0;
for (Node* node = fragment.firstChild(); node; node = next) {
- if (node->hasTagName(baseTag)
- || node->hasTagName(linkTag)
- || node->hasTagName(metaTag)
- || node->hasTagName(styleTag)
- || isHTMLTitleElement(node)) {
+ if (isHTMLBaseElement(*node)
+ || isHTMLLinkElement(*node)
+ || isHTMLMetaElement(*node)
+ || isHTMLStyleElement(*node)
+ || isHTMLTitleElement(*node)) {
next = NodeTraversal::nextSkippingChildren(*node);
fragment.removeNode(node);
} else {
@@ -729,7 +739,7 @@ static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const
return false;
Node* wrappingStyleSpan = topNode;
- RefPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create(insertionPos.parentAnchoredEquivalent());
+ RefPtrWillBeRawPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create(insertionPos.parentAnchoredEquivalent());
String styleText = styleAtInsertionPos->style()->asText();
// FIXME: This string comparison is a naive way of comparing two styles.
@@ -767,7 +777,7 @@ void ReplaceSelectionCommand::handleStyleSpans(InsertedNodes& insertedNodes)
if (!wrappingStyleSpan)
return;
- RefPtr<EditingStyle> style = EditingStyle::create(wrappingStyleSpan->inlineStyle());
+ RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(wrappingStyleSpan->inlineStyle());
ContainerNode* context = wrappingStyleSpan->parentNode();
// If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region,
@@ -820,7 +830,7 @@ void ReplaceSelectionCommand::mergeEndIfNeeded()
// Merging forward could result in deleting the destination anchor node.
// To avoid this, we add a placeholder node before the start of the paragraph.
if (endOfParagraph(startOfParagraphToMove) == destination) {
- RefPtr<Node> placeholder = createBreakElement(document());
+ RefPtrWillBeRawPtr<Node> placeholder = createBreakElement(document());
insertNodeBefore(placeholder, startOfParagraphToMove.deepEquivalent().deprecatedNode());
destination = VisiblePosition(positionBeforeNode(placeholder.get()));
}
@@ -841,7 +851,7 @@ void ReplaceSelectionCommand::mergeEndIfNeeded()
static Node* enclosingInline(Node* node)
{
while (ContainerNode* parent = node->parentNode()) {
- if (parent->isBlockFlowElement() || parent->hasTagName(bodyTag))
+ if (parent->isBlockFlowElement() || isHTMLBodyElement(*parent))
return node;
// Stop if any previous sibling is a block.
for (Node* sibling = node->previousSibling(); sibling; sibling = sibling->previousSibling()) {
@@ -866,10 +876,18 @@ static bool isInlineNodeWithStyle(const Node* node)
// one of our internal classes.
const HTMLElement* element = toHTMLElement(node);
const AtomicString& classAttributeValue = element->getAttribute(classAttr);
- if (classAttributeValue == AppleTabSpanClass
- || classAttributeValue == AppleConvertedSpace
- || classAttributeValue == ApplePasteAsQuotation)
+ if (classAttributeValue == AppleTabSpanClass) {
+ UseCounter::count(node->document(), UseCounter::EditingAppleTabSpanClass);
+ return true;
+ }
+ if (classAttributeValue == AppleConvertedSpace) {
+ UseCounter::count(node->document(), UseCounter::EditingAppleConvertedSpace);
+ return true;
+ }
+ if (classAttributeValue == ApplePasteAsQuotation) {
+ UseCounter::count(node->document(), UseCounter::EditingApplePasteAsQuotation);
return true;
+ }
return EditingStyle::elementIsStyledSpanOrHTMLEquivalent(element);
}
@@ -932,7 +950,7 @@ void ReplaceSelectionCommand::doApply()
bool mergeBlocksAfterDelete = startIsInsideMailBlockquote || isEndOfParagraph(visibleEnd) || isStartOfBlock(visibleStart);
// FIXME: We should only expand to include fully selected special elements if we are copying a
// selection and pasting it on top of itself.
- deleteSelection(false, mergeBlocksAfterDelete, true, false);
+ deleteSelection(false, mergeBlocksAfterDelete, false);
visibleStart = endingSelection().visibleStart();
if (fragment.hasInterchangeNewlineAtStart()) {
if (isEndOfParagraph(visibleStart) && !isStartOfParagraph(visibleStart)) {
@@ -972,9 +990,9 @@ void ReplaceSelectionCommand::doApply()
applyCommandToComposite(BreakBlockquoteCommand::create(document()));
// This will leave a br between the split.
Node* br = endingSelection().start().deprecatedNode();
- ASSERT(br->hasTagName(brTag));
+ ASSERT(isHTMLBRElement(br));
// Insert content between the two blockquotes, but remove the br (since it was just a placeholder).
- insertionPos = positionInParentBeforeNode(br);
+ insertionPos = positionInParentBeforeNode(*br);
removeNode(br);
}
@@ -988,12 +1006,12 @@ void ReplaceSelectionCommand::doApply()
// NOTE: This would be an incorrect usage of downstream() if downstream() were changed to mean the last position after
// p that maps to the same visible position as p (since in the case where a br is at the end of a block and collapsed
// away, there are positions after the br which map to the same visible position as [br, 0]).
- Node* endBR = insertionPos.downstream().deprecatedNode()->hasTagName(brTag) ? insertionPos.downstream().deprecatedNode() : 0;
+ Node* endBR = isHTMLBRElement(*insertionPos.downstream().deprecatedNode()) ? insertionPos.downstream().deprecatedNode() : 0;
VisiblePosition originalVisPosBeforeEndBR;
if (endBR)
originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), DOWNSTREAM).previous();
- RefPtr<Node> insertionBlock = enclosingBlock(insertionPos.deprecatedNode());
+ RefPtrWillBeRawPtr<Node> insertionBlock = enclosingBlock(insertionPos.deprecatedNode());
// Adjust insertionPos to prevent nesting.
// If the start was in a Mail blockquote, we will have already handled adjusting insertionPos above.
@@ -1001,9 +1019,9 @@ void ReplaceSelectionCommand::doApply()
ASSERT(insertionBlock != currentRoot);
VisiblePosition visibleInsertionPos(insertionPos);
if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInsertionPos) && fragment.hasInterchangeNewlineAtEnd()))
- insertionPos = positionInParentAfterNode(insertionBlock.get());
+ insertionPos = positionInParentAfterNode(*insertionBlock);
else if (isStartOfBlock(visibleInsertionPos))
- insertionPos = positionInParentBeforeNode(insertionBlock.get());
+ insertionPos = positionInParentBeforeNode(*insertionBlock);
}
// Paste at start or end of link goes outside of link.
@@ -1011,7 +1029,7 @@ void ReplaceSelectionCommand::doApply()
// FIXME: Can this wait until after the operation has been performed? There doesn't seem to be
// any work performed after this that queries or uses the typing style.
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->selection().clearTypingStyle();
removeHeadContents(fragment);
@@ -1042,13 +1060,13 @@ void ReplaceSelectionCommand::doApply()
insertionPos = firstPositionInNode(insertionPos.containerNode());
}
- if (RefPtr<Node> nodeToSplitTo = nodeToSplitToAvoidPastingIntoInlineNodesWithStyle(insertionPos)) {
+ if (RefPtrWillBeRawPtr<Node> nodeToSplitTo = nodeToSplitToAvoidPastingIntoInlineNodesWithStyle(insertionPos)) {
if (insertionPos.containerNode() != nodeToSplitTo->parentNode()) {
Node* splitStart = insertionPos.computeNodeAfterPosition();
if (!splitStart)
splitStart = insertionPos.containerNode();
nodeToSplitTo = splitTreeToNode(splitStart, nodeToSplitTo->parentNode()).get();
- insertionPos = positionInParentBeforeNode(nodeToSplitTo.get());
+ insertionPos = positionInParentBeforeNode(*nodeToSplitTo);
}
}
}
@@ -1067,9 +1085,9 @@ void ReplaceSelectionCommand::doApply()
// 6) Select the replacement if requested, and match style if requested.
InsertedNodes insertedNodes;
- RefPtr<Node> refNode = fragment.firstChild();
+ RefPtrWillBeRawPtr<Node> refNode = fragment.firstChild();
ASSERT(refNode);
- RefPtr<Node> node = refNode->nextSibling();
+ RefPtrWillBeRawPtr<Node> node = refNode->nextSibling();
fragment.removeNode(refNode);
@@ -1089,7 +1107,7 @@ void ReplaceSelectionCommand::doApply()
bool plainTextFragment = isPlainTextMarkup(refNode.get());
while (node) {
- RefPtr<Node> next = node->nextSibling();
+ RefPtrWillBeRawPtr<Node> next = node->nextSibling();
fragment.removeNode(node.get());
insertNodeAfter(node, refNode);
insertedNodes.respondToNodeInsertion(*node);
@@ -1116,17 +1134,17 @@ void ReplaceSelectionCommand::doApply()
// Scripts specified in javascript protocol may remove |insertionBlock|
// during insertion, e.g. <iframe src="javascript:...">
if (insertionBlock && !insertionBlock->inDocument())
- insertionBlock = 0;
+ insertionBlock = nullptr;
- VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(insertedNodes.firstNodeInserted());
+ VisiblePosition startOfInsertedContent(firstPositionInOrBeforeNode(insertedNodes.firstNodeInserted()));
// We inserted before the insertionBlock to prevent nesting, and the content before the insertionBlock wasn't in its own block and
// didn't have a br after it, so the inserted content ended up in the same paragraph.
- if (insertionBlock && insertionPos.deprecatedNode() == insertionBlock->parentNode() && (unsigned)insertionPos.deprecatedEditingOffset() < insertionBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
+ if (!startOfInsertedContent.isNull() && insertionBlock && insertionPos.deprecatedNode() == insertionBlock->parentNode() && (unsigned)insertionPos.deprecatedEditingOffset() < insertionBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
insertNodeAt(createBreakElement(document()).get(), startOfInsertedContent.deepEquivalent());
- if (endBR && (plainTextFragment || shouldRemoveEndBR(endBR, originalVisPosBeforeEndBR))) {
- RefPtr<Node> parent = endBR->parentNode();
+ if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosBeforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)))) {
+ RefPtrWillBeRawPtr<Node> parent = endBR->parentNode();
insertedNodes.willRemoveNode(*endBR);
removeNode(endBR);
if (Node* nodeToRemove = highestNodeToRemoveInPruning(parent.get())) {
@@ -1144,7 +1162,7 @@ void ReplaceSelectionCommand::doApply()
// Setup m_startOfInsertedContent and m_endOfInsertedContent. This should be the last two lines of code that access insertedNodes.
m_startOfInsertedContent = firstPositionInOrBeforeNode(insertedNodes.firstNodeInserted());
- m_endOfInsertedContent = lastPositionInOrAfterNode(&insertedNodes.lastLeafInserted());
+ m_endOfInsertedContent = lastPositionInOrAfterNode(insertedNodes.lastLeafInserted());
// Determine whether or not we should merge the end of inserted content with what's after it before we do
// the start merge so that the start merge doesn't effect our decision.
@@ -1193,7 +1211,7 @@ void ReplaceSelectionCommand::doApply()
setEndingSelection(endOfInsertedContent);
Node* enclosingNode = enclosingBlock(endOfInsertedContent.deepEquivalent().deprecatedNode());
if (isListItem(enclosingNode)) {
- RefPtr<Node> newListItem = createListItemElement(document());
+ RefPtrWillBeRawPtr<Node> newListItem = createListItemElement(document());
insertNodeAfter(newListItem, enclosingNode);
setEndingSelection(VisiblePosition(firstPositionInNode(newListItem.get())));
} else {
@@ -1255,7 +1273,7 @@ bool ReplaceSelectionCommand::shouldPerformSmartReplace() const
return false;
Element* textControl = enclosingTextFormControl(positionAtStartOfInsertedContent().deepEquivalent());
- if (textControl && textControl->hasTagName(inputTag) && toHTMLInputElement(textControl)->isPasswordField())
+ if (isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->isPasswordField())
return false; // Disable smart replace for password fields.
return true;
@@ -1287,7 +1305,7 @@ void ReplaceSelectionCommand::addSpacesForSmartReplace()
if (m_endOfInsertedContent.containerNode() == endNode)
m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offsetInContainerNode() + 1);
} else {
- RefPtr<Node> node = document().createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " ");
+ RefPtrWillBeRawPtr<Node> node = document().createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " ");
insertNodeAfter(node, endNode);
updateNodesInserted(node.get());
}
@@ -1311,7 +1329,7 @@ void ReplaceSelectionCommand::addSpacesForSmartReplace()
if (m_endOfInsertedContent.containerNode() == startNode && m_endOfInsertedContent.offsetInContainerNode())
m_endOfInsertedContent.moveToOffset(m_endOfInsertedContent.offsetInContainerNode() + 1);
} else {
- RefPtr<Node> node = document().createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " ");
+ RefPtrWillBeRawPtr<Node> node = document().createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " ");
// Don't updateNodesInserted. Doing so would set m_endOfInsertedContent to be the node containing the leading space,
// but m_endOfInsertedContent is supposed to mark the end of pasted content.
insertNodeBefore(node, startNode);
@@ -1355,7 +1373,7 @@ void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P
{
bool positionIsOffsetInAnchor = position.anchorType() == Position::PositionIsOffsetInAnchor;
bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.anchorType() == Position::PositionIsOffsetInAnchor;
- RefPtr<Text> text = 0;
+ RefPtrWillBeRawPtr<Text> text = nullptr;
if (positionIsOffsetInAnchor && position.containerNode() && position.containerNode()->isTextNode())
text = toText(position.containerNode());
else {
@@ -1372,36 +1390,37 @@ void ReplaceSelectionCommand::mergeTextNodesAroundPosition(Position& position, P
return;
if (text->previousSibling() && text->previousSibling()->isTextNode()) {
- RefPtr<Text> previous = toText(text->previousSibling());
+ RefPtrWillBeRawPtr<Text> previous = toText(text->previousSibling());
insertTextIntoNode(text, 0, previous->data());
if (positionIsOffsetInAnchor)
position.moveToOffset(previous->length() + position.offsetInContainerNode());
else
- updatePositionForNodeRemoval(position, previous.get());
+ updatePositionForNodeRemoval(position, *previous);
if (positionOnlyToBeUpdatedIsOffsetInAnchor) {
if (positionOnlyToBeUpdated.containerNode() == text)
positionOnlyToBeUpdated.moveToOffset(previous->length() + positionOnlyToBeUpdated.offsetInContainerNode());
else if (positionOnlyToBeUpdated.containerNode() == previous)
positionOnlyToBeUpdated.moveToPosition(text, positionOnlyToBeUpdated.offsetInContainerNode());
- } else
- updatePositionForNodeRemoval(positionOnlyToBeUpdated, previous.get());
+ } else {
+ updatePositionForNodeRemoval(positionOnlyToBeUpdated, *previous);
+ }
removeNode(previous);
}
if (text->nextSibling() && text->nextSibling()->isTextNode()) {
- RefPtr<Text> next = toText(text->nextSibling());
+ RefPtrWillBeRawPtr<Text> next = toText(text->nextSibling());
unsigned originalLength = text->length();
insertTextIntoNode(text, originalLength, next->data());
if (!positionIsOffsetInAnchor)
- updatePositionForNodeRemoval(position, next.get());
+ updatePositionForNodeRemoval(position, *next);
if (positionOnlyToBeUpdatedIsOffsetInAnchor && positionOnlyToBeUpdated.containerNode() == next)
positionOnlyToBeUpdated.moveToPosition(text, originalLength + positionOnlyToBeUpdated.offsetInContainerNode());
else
- updatePositionForNodeRemoval(positionOnlyToBeUpdated, next.get());
+ updatePositionForNodeRemoval(positionOnlyToBeUpdated, *next);
removeNode(next);
}
@@ -1414,15 +1433,15 @@ EditAction ReplaceSelectionCommand::editingAction() const
// If the user is inserting a list into an existing list, instead of nesting the list,
// we put the list items into the existing list.
-Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtr<HTMLElement> prpListElement, Node* insertionBlock, const Position& insertPos, InsertedNodes& insertedNodes)
+Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtrWillBeRawPtr<HTMLElement> prpListElement, Node* insertionBlock, const Position& insertPos, InsertedNodes& insertedNodes)
{
- RefPtr<HTMLElement> listElement = prpListElement;
+ RefPtrWillBeRawPtr<HTMLElement> listElement = prpListElement;
- while (listElement->hasChildNodes() && isListElement(listElement->firstChild()) && listElement->childNodeCount() == 1)
+ while (listElement->hasChildren() && isListElement(listElement->firstChild()) && listElement->hasOneChild())
listElement = toHTMLElement(listElement->firstChild());
- bool isStart = isStartOfParagraph(insertPos);
- bool isEnd = isEndOfParagraph(insertPos);
+ bool isStart = isStartOfParagraph(VisiblePosition(insertPos));
+ bool isEnd = isEndOfParagraph(VisiblePosition(insertPos));
bool isMiddle = !isStart && !isEnd;
Node* lastNode = insertionBlock;
@@ -1435,7 +1454,7 @@ Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtr<HTMLElement> prpList
splitTreeToNode(insertPos.deprecatedNode(), lastNode, true);
}
- while (RefPtr<Node> listItem = listElement->firstChild()) {
+ while (RefPtrWillBeRawPtr<Node> listItem = listElement->firstChild()) {
listElement->removeChild(listItem.get(), ASSERT_NO_EXCEPTION);
if (isStart || isMiddle) {
insertNodeBefore(listItem, lastNode);
@@ -1447,8 +1466,10 @@ Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtr<HTMLElement> prpList
} else
ASSERT_NOT_REACHED();
}
- if (isStart || isMiddle)
- lastNode = lastNode->previousSibling();
+ if (isStart || isMiddle) {
+ if (Node* node = lastNode->previousSibling())
+ return node;
+ }
return lastNode;
}
@@ -1460,7 +1481,7 @@ void ReplaceSelectionCommand::updateNodesInserted(Node *node)
if (m_startOfInsertedContent.isNull())
m_startOfInsertedContent = firstPositionInOrBeforeNode(node);
- m_endOfInsertedContent = lastPositionInOrAfterNode(&node->lastDescendant());
+ m_endOfInsertedContent = lastPositionInOrAfterNode(&node->lastDescendantOrSelf());
}
// During simple pastes, where we're just pasting a text node into a run of text, we insert the text node
@@ -1480,7 +1501,7 @@ bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& f
if (nodeToSplitToAvoidPastingIntoInlineNodesWithStyle(endingSelection().start()))
return false;
- RefPtr<Node> nodeAfterInsertionPos = endingSelection().end().downstream().anchorNode();
+ RefPtrWillBeRawPtr<Node> nodeAfterInsertionPos = endingSelection().end().downstream().anchorNode();
Text* textNode = toText(fragment.firstChild());
// Our fragment creation code handles tabs, spaces, and newlines, so we don't have to worry about those here.
@@ -1489,8 +1510,8 @@ bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& f
if (end.isNull())
return false;
- if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && nodeAfterInsertionPos->hasTagName(brTag)
- && shouldRemoveEndBR(nodeAfterInsertionPos.get(), positionBeforeNode(nodeAfterInsertionPos.get())))
+ if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBRElement(*nodeAfterInsertionPos)
+ && shouldRemoveEndBR(nodeAfterInsertionPos.get(), VisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get()))))
removeNodeAndPruneAncestors(nodeAfterInsertionPos.get());
VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, end);
@@ -1500,4 +1521,13 @@ bool ReplaceSelectionCommand::performTrivialReplace(const ReplacementFragment& f
return true;
}
+void ReplaceSelectionCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_startOfInsertedContent);
+ visitor->trace(m_endOfInsertedContent);
+ visitor->trace(m_insertionStyle);
+ visitor->trace(m_documentFragment);
+ CompositeEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.h b/chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.h
index ee3879b2258..a45675295c7 100644
--- a/chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/ReplaceSelectionCommand.h
@@ -34,7 +34,7 @@ namespace WebCore {
class DocumentFragment;
class ReplacementFragment;
-class ReplaceSelectionCommand : public CompositeEditCommand {
+class ReplaceSelectionCommand FINAL : public CompositeEditCommand {
public:
enum CommandOption {
SelectReplacement = 1 << 0,
@@ -47,18 +47,21 @@ public:
typedef unsigned CommandOptions;
- static PassRefPtr<ReplaceSelectionCommand> create(Document& document, PassRefPtr<DocumentFragment> fragment, CommandOptions options, EditAction action = EditActionPaste)
+ static PassRefPtrWillBeRawPtr<ReplaceSelectionCommand> create(Document& document, PassRefPtrWillBeRawPtr<DocumentFragment> fragment, CommandOptions options, EditAction action = EditActionPaste)
{
- return adoptRef(new ReplaceSelectionCommand(document, fragment, options, action));
+ return adoptRefWillBeNoop(new ReplaceSelectionCommand(document, fragment, options, action));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- ReplaceSelectionCommand(Document&, PassRefPtr<DocumentFragment>, CommandOptions, EditAction);
+ ReplaceSelectionCommand(Document&, PassRefPtrWillBeRawPtr<DocumentFragment>, CommandOptions, EditAction);
- virtual void doApply();
- virtual EditAction editingAction() const;
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE;
class InsertedNodes {
+ STACK_ALLOCATED();
public:
void respondToNodeInsertion(Node&);
void willRemoveNodePreservingChildren(Node&);
@@ -66,15 +69,15 @@ private:
void didReplaceNode(Node&, Node& newNode);
Node* firstNodeInserted() const { return m_firstNodeInserted.get(); }
- Node& lastLeafInserted() const { ASSERT(m_lastNodeInserted); return m_lastNodeInserted->lastDescendant(); }
- Node* pastLastLeaf() const { return m_lastNodeInserted ? NodeTraversal::next(lastLeafInserted()) : 0; }
+ Node* lastLeafInserted() const { return m_lastNodeInserted ? &m_lastNodeInserted->lastDescendantOrSelf() : 0; }
+ Node* pastLastLeaf() const { return m_lastNodeInserted ? NodeTraversal::next(m_lastNodeInserted->lastDescendantOrSelf()) : 0; }
private:
- RefPtr<Node> m_firstNodeInserted;
- RefPtr<Node> m_lastNodeInserted;
+ RefPtrWillBeMember<Node> m_firstNodeInserted;
+ RefPtrWillBeMember<Node> m_lastNodeInserted;
};
- Node* insertAsListItems(PassRefPtr<HTMLElement> listElement, Node* insertionNode, const Position&, InsertedNodes&);
+ Node* insertAsListItems(PassRefPtrWillBeRawPtr<HTMLElement> listElement, Node* insertionNode, const Position&, InsertedNodes&);
void updateNodesInserted(Node*);
bool shouldRemoveEndBR(Node*, const VisiblePosition&);
@@ -88,10 +91,9 @@ private:
void removeUnrenderedTextNodesAtEnds(InsertedNodes&);
void removeRedundantStylesAndKeepStyleSpanInline(InsertedNodes&);
- void makeInsertedContentRoundTrippableWithHTMLTreeBuilder(InsertedNodes&);
- void moveNodeOutOfAncestor(PassRefPtr<Node>, PassRefPtr<Node> ancestor);
+ void makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes&);
+ void moveNodeOutOfAncestor(PassRefPtrWillBeRawPtr<Node>, PassRefPtrWillBeRawPtr<Node> ancestor);
void handleStyleSpans(InsertedNodes&);
- void handlePasteAsQuotationNode();
VisiblePosition positionAtStartOfInsertedContent() const;
VisiblePosition positionAtEndOfInsertedContent() const;
@@ -105,11 +107,11 @@ private:
Position m_startOfInsertedContent;
Position m_endOfInsertedContent;
- RefPtr<EditingStyle> m_insertionStyle;
+ RefPtrWillBeMember<EditingStyle> m_insertionStyle;
bool m_selectReplacement;
bool m_smartReplace;
bool m_matchStyle;
- RefPtr<DocumentFragment> m_documentFragment;
+ RefPtrWillBeMember<DocumentFragment> m_documentFragment;
bool m_preventNesting;
bool m_movingParagraph;
EditAction m_editAction;
diff --git a/chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.cpp
index 2d4b7ee8f9d..54e7b23b64f 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-SetNodeAttributeCommand::SetNodeAttributeCommand(PassRefPtr<Element> element,
+SetNodeAttributeCommand::SetNodeAttributeCommand(PassRefPtrWillBeRawPtr<Element> element,
const QualifiedName& attribute, const AtomicString& value)
: SimpleEditCommand(element->document())
, m_element(element)
@@ -53,4 +53,10 @@ void SetNodeAttributeCommand::doUnapply()
m_oldValue = nullAtom;
}
+void SetNodeAttributeCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.h b/chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.h
index 5716b61dadc..3b4395a0013 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/SetNodeAttributeCommand.h
@@ -31,20 +31,22 @@
namespace WebCore {
-class SetNodeAttributeCommand : public SimpleEditCommand {
+class SetNodeAttributeCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<SetNodeAttributeCommand> create(PassRefPtr<Element> element, const QualifiedName& attribute, const AtomicString& value)
+ static PassRefPtrWillBeRawPtr<SetNodeAttributeCommand> create(PassRefPtrWillBeRawPtr<Element> element, const QualifiedName& attribute, const AtomicString& value)
{
- return adoptRef(new SetNodeAttributeCommand(element, attribute, value));
+ return adoptRefWillBeNoop(new SetNodeAttributeCommand(element, attribute, value));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- SetNodeAttributeCommand(PassRefPtr<Element>, const QualifiedName& attribute, const AtomicString& value);
+ SetNodeAttributeCommand(PassRefPtrWillBeRawPtr<Element>, const QualifiedName& attribute, const AtomicString& value);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
- RefPtr<Element> m_element;
+ RefPtrWillBeMember<Element> m_element;
QualifiedName m_attribute;
AtomicString m_value;
AtomicString m_oldValue;
diff --git a/chromium/third_party/WebKit/Source/core/editing/SetSelectionCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/SetSelectionCommand.cpp
deleted file mode 100644
index dff5416d17f..00000000000
--- a/chromium/third_party/WebKit/Source/core/editing/SetSelectionCommand.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/editing/SetSelectionCommand.h"
-
-#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
-
-namespace WebCore {
-
-SetSelectionCommand::SetSelectionCommand(const VisibleSelection& selection, FrameSelection::SetSelectionOptions options)
- : SimpleEditCommand(*selection.base().document())
- , m_options(options)
- , m_selectionToSet(selection)
-{
-}
-
-void SetSelectionCommand::doApply()
-{
- FrameSelection& selection = document().frame()->selection();
- selection.setSelection(m_selectionToSet, m_options);
- setEndingSelection(m_selectionToSet);
-}
-
-void SetSelectionCommand::doUnapply()
-{
- FrameSelection& selection = document().frame()->selection();
- selection.setSelection(startingSelection(), m_options);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SetSelectionCommand.h b/chromium/third_party/WebKit/Source/core/editing/SetSelectionCommand.h
deleted file mode 100644
index b4f09afea2f..00000000000
--- a/chromium/third_party/WebKit/Source/core/editing/SetSelectionCommand.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SetSelectionCommand_h
-#define SetSelectionCommand_h
-
-#include "core/editing/EditCommand.h"
-#include "core/editing/FrameSelection.h"
-
-namespace WebCore {
-
-class SetSelectionCommand : public SimpleEditCommand {
-public:
- static PassRefPtr<SetSelectionCommand> create(const VisibleSelection& selection, FrameSelection::SetSelectionOptions options)
- {
- return adoptRef(new SetSelectionCommand(selection, options));
- }
-
-private:
- SetSelectionCommand(const VisibleSelection&, FrameSelection::SetSelectionOptions);
-
- virtual void doApply() OVERRIDE;
- virtual void doUnapply() OVERRIDE;
-
- FrameSelection::SetSelectionOptions m_options;
- VisibleSelection m_selectionToSet;
-};
-
-} // namespace WebCore
-
-#endif // SetSelectionCommand_h
diff --git a/chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.cpp
index 8d13312d1e5..089d3290aba 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.cpp
@@ -42,7 +42,7 @@ SimplifyMarkupCommand::SimplifyMarkupCommand(Document& document, Node* firstNode
void SimplifyMarkupCommand::doApply()
{
Node* rootNode = m_firstNode->parentNode();
- Vector<RefPtr<Node> > nodesToRemove;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > nodesToRemove;
// Walk through the inserted nodes, to see if there are elements that could be removed
// without affecting the style. The goal is to produce leaner markup even when starting
@@ -77,7 +77,7 @@ void SimplifyMarkupCommand::doApply()
}
unsigned context;
- if (currentNode->renderStyle()->diff(startingStyle, context) == StyleDifferenceEqual)
+ if (currentNode->renderStyle()->visualInvalidationDiff(*startingStyle, context).hasNoChange() && !context)
topNodeWithStartingStyle = currentNode;
}
@@ -98,7 +98,7 @@ void SimplifyMarkupCommand::doApply()
}
}
-int SimplifyMarkupCommand::pruneSubsequentAncestorsToRemove(Vector<RefPtr<Node> >& nodesToRemove, size_t startNodeIndex)
+int SimplifyMarkupCommand::pruneSubsequentAncestorsToRemove(WillBeHeapVector<RefPtrWillBeMember<Node> >& nodesToRemove, size_t startNodeIndex)
{
size_t pastLastNodeToRemove = startNodeIndex + 1;
for (; pastLastNodeToRemove < nodesToRemove.size(); ++pastLastNodeToRemove) {
@@ -108,7 +108,7 @@ int SimplifyMarkupCommand::pruneSubsequentAncestorsToRemove(Vector<RefPtr<Node>
}
Node* highestAncestorToRemove = nodesToRemove[pastLastNodeToRemove - 1].get();
- RefPtr<ContainerNode> parent = highestAncestorToRemove->parentNode();
+ RefPtrWillBeRawPtr<ContainerNode> parent = highestAncestorToRemove->parentNode();
if (!parent) // Parent has already been removed.
return -1;
@@ -122,4 +122,11 @@ int SimplifyMarkupCommand::pruneSubsequentAncestorsToRemove(Vector<RefPtr<Node>
return pastLastNodeToRemove - startNodeIndex - 1;
}
+void SimplifyMarkupCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_firstNode);
+ visitor->trace(m_nodeAfterLast);
+ CompositeEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.h b/chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.h
index 3da2a622078..24659f3b845 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/SimplifyMarkupCommand.h
@@ -30,21 +30,23 @@
namespace WebCore {
-class SimplifyMarkupCommand : public CompositeEditCommand {
+class SimplifyMarkupCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<SimplifyMarkupCommand> create(Document& document, Node* firstNode, Node* nodeAfterLast)
+ static PassRefPtrWillBeRawPtr<SimplifyMarkupCommand> create(Document& document, Node* firstNode, Node* nodeAfterLast)
{
- return adoptRef(new SimplifyMarkupCommand(document, firstNode, nodeAfterLast));
+ return adoptRefWillBeNoop(new SimplifyMarkupCommand(document, firstNode, nodeAfterLast));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
SimplifyMarkupCommand(Document&, Node* firstNode, Node* nodeAfterLast);
- virtual void doApply();
- int pruneSubsequentAncestorsToRemove(Vector<RefPtr<Node> >& nodesToRemove, size_t startNodeIndex);
+ virtual void doApply() OVERRIDE;
+ int pruneSubsequentAncestorsToRemove(WillBeHeapVector<RefPtrWillBeMember<Node> >& nodesToRemove, size_t startNodeIndex);
- RefPtr<Node> m_firstNode;
- RefPtr<Node> m_nodeAfterLast;
+ RefPtrWillBeMember<Node> m_firstNode;
+ RefPtrWillBeMember<Node> m_nodeAfterLast;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.cpp b/chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.cpp
index 104f446b569..2d43474cb53 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.cpp
@@ -30,15 +30,15 @@
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/Node.h"
#include "core/editing/SpellChecker.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "platform/text/TextCheckerClient.h"
namespace WebCore {
SpellCheckRequest::SpellCheckRequest(
- PassRefPtr<Range> checkingRange,
- PassRefPtr<Range> paragraphRange,
+ PassRefPtrWillBeRawPtr<Range> checkingRange,
+ PassRefPtrWillBeRawPtr<Range> paragraphRange,
const String& text,
TextCheckingTypeMask mask,
TextCheckingProcessType processType,
@@ -59,7 +59,7 @@ SpellCheckRequest::~SpellCheckRequest()
}
// static
-PassRefPtr<SpellCheckRequest> SpellCheckRequest::create(TextCheckingTypeMask textCheckingOptions, TextCheckingProcessType processType, PassRefPtr<Range> checkingRange, PassRefPtr<Range> paragraphRange, int requestNumber)
+PassRefPtr<SpellCheckRequest> SpellCheckRequest::create(TextCheckingTypeMask textCheckingOptions, TextCheckingProcessType processType, PassRefPtrWillBeRawPtr<Range> checkingRange, PassRefPtrWillBeRawPtr<Range> paragraphRange, int requestNumber)
{
ASSERT(checkingRange);
ASSERT(paragraphRange);
@@ -68,7 +68,7 @@ PassRefPtr<SpellCheckRequest> SpellCheckRequest::create(TextCheckingTypeMask tex
if (!text.length())
return PassRefPtr<SpellCheckRequest>();
- const Vector<DocumentMarker*>& markers = checkingRange->ownerDocument().markers()->markersInRange(checkingRange.get(), DocumentMarker::SpellCheckClientMarkers());
+ const WillBeHeapVector<DocumentMarker*>& markers = checkingRange->ownerDocument().markers().markersInRange(checkingRange.get(), DocumentMarker::SpellCheckClientMarkers());
Vector<uint32_t> hashes(markers.size());
Vector<unsigned> offsets(markers.size());
for (size_t i = 0; i < markers.size(); i++) {
@@ -115,7 +115,7 @@ void SpellCheckRequest::requesterDestroyed()
m_requester = 0;
}
-SpellCheckRequester::SpellCheckRequester(Frame& frame)
+SpellCheckRequester::SpellCheckRequester(LocalFrame& frame)
: m_frame(frame)
, m_lastRequestSequence(0)
, m_lastProcessedSequence(0)
@@ -240,7 +240,7 @@ void SpellCheckRequester::didCheck(int sequence, const Vector<TextCheckingResult
m_processingRequest.clear();
if (!m_requestQueue.isEmpty())
- m_timerToProcessQueuedRequest.startOneShot(0);
+ m_timerToProcessQueuedRequest.startOneShot(0, FROM_HERE);
}
void SpellCheckRequester::didCheckSucceed(int sequence, const Vector<TextCheckingResult>& results)
@@ -252,7 +252,7 @@ void SpellCheckRequester::didCheckSucceed(int sequence, const Vector<TextCheckin
markers.remove(DocumentMarker::Spelling);
if (!requestData.maskContains(TextCheckingTypeGrammar))
markers.remove(DocumentMarker::Grammar);
- m_frame.document()->markers()->removeMarkers(m_processingRequest->checkingRange().get(), markers);
+ m_frame.document()->markers().removeMarkers(m_processingRequest->checkingRange().get(), markers);
}
didCheck(sequence, results);
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.h b/chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.h
index 6eefe8f2583..bd05790b077 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.h
+++ b/chromium/third_party/WebKit/Source/core/editing/SpellCheckRequester.h
@@ -38,23 +38,22 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class Node;
class SpellCheckRequester;
class TextCheckerClient;
-class SpellCheckRequest : public TextCheckingRequest {
+class SpellCheckRequest FINAL : public TextCheckingRequest {
public:
- static PassRefPtr<SpellCheckRequest> create(TextCheckingTypeMask, TextCheckingProcessType, PassRefPtr<Range> checkingRange, PassRefPtr<Range> paragraphRange, int requestNumber = 0);
+ static PassRefPtr<SpellCheckRequest> create(TextCheckingTypeMask, TextCheckingProcessType, PassRefPtrWillBeRawPtr<Range> checkingRange, PassRefPtrWillBeRawPtr<Range> paragraphRange, int requestNumber = 0);
virtual ~SpellCheckRequest();
- PassRefPtr<Range> checkingRange() const { return m_checkingRange; }
- PassRefPtr<Range> paragraphRange() const { return m_paragraphRange; }
- PassRefPtr<Element> rootEditableElement() const { return m_rootEditableElement; }
+ PassRefPtrWillBeRawPtr<Range> checkingRange() const { return m_checkingRange; }
+ PassRefPtrWillBeRawPtr<Range> paragraphRange() const { return m_paragraphRange; }
+ PassRefPtrWillBeRawPtr<Element> rootEditableElement() const { return m_rootEditableElement; }
void setCheckerAndSequence(SpellCheckRequester*, int sequence);
void requesterDestroyed();
- bool isStarted() const { return m_requester; }
virtual const TextCheckingRequestData& data() const OVERRIDE;
virtual void didSucceed(const Vector<TextCheckingResult>&) OVERRIDE;
@@ -63,12 +62,12 @@ public:
int requestNumber() const { return m_requestNumber; }
private:
- SpellCheckRequest(PassRefPtr<Range> checkingRange, PassRefPtr<Range> paragraphRange, const String&, TextCheckingTypeMask, TextCheckingProcessType, const Vector<uint32_t>& documentMarkersInRange, const Vector<unsigned>& documentMarkerOffsets, int requestNumber);
+ SpellCheckRequest(PassRefPtrWillBeRawPtr<Range> checkingRange, PassRefPtrWillBeRawPtr<Range> paragraphRange, const String&, TextCheckingTypeMask, TextCheckingProcessType, const Vector<uint32_t>& documentMarkersInRange, const Vector<unsigned>& documentMarkerOffsets, int requestNumber);
SpellCheckRequester* m_requester;
- RefPtr<Range> m_checkingRange;
- RefPtr<Range> m_paragraphRange;
- RefPtr<Element> m_rootEditableElement;
+ RefPtrWillBePersistent<Range> m_checkingRange;
+ RefPtrWillBePersistent<Range> m_paragraphRange;
+ RefPtrWillBePersistent<Element> m_rootEditableElement;
TextCheckingRequestData m_requestData;
int m_requestNumber;
};
@@ -78,7 +77,7 @@ class SpellCheckRequester {
public:
friend class SpellCheckRequest;
- explicit SpellCheckRequester(Frame&);
+ explicit SpellCheckRequester(LocalFrame&);
~SpellCheckRequester();
bool isAsynchronousEnabled() const;
@@ -109,7 +108,7 @@ private:
void didCheckCancel(int sequence);
void didCheck(int sequence, const Vector<TextCheckingResult>&);
- Frame& m_frame;
+ LocalFrame& m_frame;
int m_lastRequestSequence;
int m_lastProcessedSequence;
diff --git a/chromium/third_party/WebKit/Source/core/editing/SpellChecker.cpp b/chromium/third_party/WebKit/Source/core/editing/SpellChecker.cpp
index a3c129d74a0..3253554d87a 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SpellChecker.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/SpellChecker.cpp
@@ -27,7 +27,7 @@
#include "config.h"
#include "core/editing/SpellChecker.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/Element.h"
@@ -37,7 +37,7 @@
#include "core/editing/TextCheckingHelper.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLInputElement.h"
#include "core/loader/EmptyClients.h"
#include "core/page/Page.h"
@@ -55,12 +55,12 @@ namespace {
bool isSelectionInTextField(const VisibleSelection& selection)
{
HTMLTextFormControlElement* textControl = enclosingTextFormControl(selection.start());
- return textControl && textControl->hasTagName(inputTag) && toHTMLInputElement(textControl)->isTextField();
+ return isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->isTextField();
}
} // namespace
-PassOwnPtr<SpellChecker> SpellChecker::create(Frame& frame)
+PassOwnPtr<SpellChecker> SpellChecker::create(LocalFrame& frame)
{
return adoptPtr(new SpellChecker(frame));
}
@@ -83,7 +83,7 @@ TextCheckerClient& SpellChecker::textChecker() const
return spellCheckerClient().textChecker();
}
-SpellChecker::SpellChecker(Frame& frame)
+SpellChecker::SpellChecker(LocalFrame& frame)
: m_frame(frame)
, m_spellCheckRequester(adoptPtr(new SpellCheckRequester(frame)))
{
@@ -103,8 +103,10 @@ void SpellChecker::toggleContinuousSpellChecking()
spellCheckerClient().toggleContinuousSpellChecking();
if (isContinuousSpellCheckingEnabled())
return;
- for (Frame* frame = m_frame.page()->mainFrame(); frame && frame->document(); frame = frame->tree().traverseNext()) {
- for (Node* node = frame->document()->rootNode(); node; node = NodeTraversal::next(*node)) {
+ for (Frame* frame = m_frame.page()->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ for (Node* node = &toLocalFrame(frame)->document()->rootNode(); node; node = NodeTraversal::next(*node)) {
node->setAlreadySpellChecked(false);
}
}
@@ -120,15 +122,15 @@ void SpellChecker::didBeginEditing(Element* element)
if (isContinuousSpellCheckingEnabled() && unifiedTextCheckerEnabled()) {
bool isTextField = false;
HTMLTextFormControlElement* enclosingHTMLTextFormControlElement = 0;
- if (!isHTMLTextFormControlElement(element))
+ if (!isHTMLTextFormControlElement(*element))
enclosingHTMLTextFormControlElement = enclosingTextFormControl(firstPositionInNode(element));
element = enclosingHTMLTextFormControlElement ? enclosingHTMLTextFormControlElement : element;
Element* parent = element;
- if (isHTMLTextFormControlElement(element)) {
+ if (isHTMLTextFormControlElement(*element)) {
HTMLTextFormControlElement* textControl = toHTMLTextFormControlElement(element);
parent = textControl;
- element = textControl->innerTextElement();
- isTextField = textControl->hasTagName(inputTag) && toHTMLInputElement(textControl)->isTextField();
+ element = textControl->innerEditorElement();
+ isTextField = isHTMLInputElement(*textControl) && toHTMLInputElement(*textControl).isTextField();
}
if (isTextField || !parent->isAlreadySpellChecked()) {
@@ -143,8 +145,8 @@ void SpellChecker::didBeginEditing(Element* element)
void SpellChecker::ignoreSpelling()
{
- if (RefPtr<Range> selectedRange = m_frame.selection().toNormalizedRange())
- m_frame.document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
+ if (RefPtrWillBeRawPtr<Range> selectedRange = m_frame.selection().toNormalizedRange())
+ m_frame.document()->markers().removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
}
void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
@@ -155,7 +157,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
// Start at the end of the selection, search to edge of document. Starting at the selection end makes
// repeated "check spelling" commands work.
VisibleSelection selection(m_frame.selection().selection());
- RefPtr<Range> spellingSearchRange(rangeOfContents(m_frame.document()));
+ RefPtrWillBeRawPtr<Range> spellingSearchRange(rangeOfContents(m_frame.document()));
bool startedWithSelection = false;
if (selection.start().deprecatedNode()) {
@@ -178,7 +180,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
// when spell checking the whole document before sending the message.
// In that case the document might not be editable, but there are editable pockets that need to be spell checked.
- position = firstEditablePositionAfterPositionInRoot(position, m_frame.document()->documentElement()).deepEquivalent();
+ position = firstEditableVisiblePositionAfterPositionInRoot(position, m_frame.document()->documentElement()).deepEquivalent();
if (position.isNull())
return;
@@ -201,7 +203,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
// else we were already at the start of the editable node
}
- if (spellingSearchRange->collapsed(IGNORE_EXCEPTION))
+ if (spellingSearchRange->collapsed())
return; // nothing to search in
// We go to the end of our first range instead of the start of it, just to be sure
@@ -213,16 +215,16 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
int misspellingOffset = 0;
GrammarDetail grammarDetail;
int grammarPhraseOffset = 0;
- RefPtr<Range> grammarSearchRange;
+ RefPtrWillBeRawPtr<Range> grammarSearchRange = nullptr;
String badGrammarPhrase;
String misspelledWord;
bool isSpelling = true;
int foundOffset = 0;
String foundItem;
- RefPtr<Range> firstMisspellingRange;
+ RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr;
if (unifiedTextCheckerEnabled()) {
- grammarSearchRange = spellingSearchRange->cloneRange(IGNORE_EXCEPTION);
+ grammarSearchRange = spellingSearchRange->cloneRange();
foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchRange).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail);
if (isSpelling) {
misspelledWord = foundItem;
@@ -233,7 +235,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
}
} else {
misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchRange).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange);
- grammarSearchRange = spellingSearchRange->cloneRange(IGNORE_EXCEPTION);
+ grammarSearchRange = spellingSearchRange->cloneRange();
if (!misspelledWord.isEmpty()) {
// Stop looking at start of next misspelled word
CharacterIterator chars(grammarSearchRange.get());
@@ -253,7 +255,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
spellingSearchRange->setEnd(searchEndNodeAfterWrap, searchEndOffsetAfterWrap, IGNORE_EXCEPTION);
if (unifiedTextCheckerEnabled()) {
- grammarSearchRange = spellingSearchRange->cloneRange(IGNORE_EXCEPTION);
+ grammarSearchRange = spellingSearchRange->cloneRange();
foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchRange).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, foundOffset, grammarDetail);
if (isSpelling) {
misspelledWord = foundItem;
@@ -264,7 +266,7 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
}
} else {
misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchRange).findFirstMisspelling(misspellingOffset, false, firstMisspellingRange);
- grammarSearchRange = spellingSearchRange->cloneRange(IGNORE_EXCEPTION);
+ grammarSearchRange = spellingSearchRange->cloneRange();
if (!misspelledWord.isEmpty()) {
// Stop looking at start of next misspelled word
CharacterIterator chars(grammarSearchRange.get());
@@ -286,54 +288,24 @@ void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
ASSERT(grammarDetail.location != -1 && grammarDetail.length > 0);
// FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph
- RefPtr<Range> badGrammarRange = TextIterator::subrange(grammarSearchRange.get(), grammarPhraseOffset + grammarDetail.location, grammarDetail.length);
+ RefPtrWillBeRawPtr<Range> badGrammarRange = TextIterator::subrange(grammarSearchRange.get(), grammarPhraseOffset + grammarDetail.location, grammarDetail.length);
m_frame.selection().setSelection(VisibleSelection(badGrammarRange.get(), SEL_DEFAULT_AFFINITY));
m_frame.selection().revealSelection();
- m_frame.document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
+ m_frame.document()->markers().addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
} else if (!misspelledWord.isEmpty()) {
// We found a misspelling, but not any earlier bad grammar. Select the misspelling, update the spelling panel, and store
// a marker so we draw the red squiggle later.
- RefPtr<Range> misspellingRange = TextIterator::subrange(spellingSearchRange.get(), misspellingOffset, misspelledWord.length());
+ RefPtrWillBeRawPtr<Range> misspellingRange = TextIterator::subrange(spellingSearchRange.get(), misspellingOffset, misspelledWord.length());
m_frame.selection().setSelection(VisibleSelection(misspellingRange.get(), DOWNSTREAM));
m_frame.selection().revealSelection();
spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord);
- m_frame.document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
+ m_frame.document()->markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling);
}
}
-String SpellChecker::misspelledWordAtCaretOrRange(Node* clickedNode) const
-{
- if (!isContinuousSpellCheckingEnabled() || !clickedNode || !isSpellCheckingEnabledFor(clickedNode))
- return String();
-
- VisibleSelection selection = m_frame.selection().selection();
- if (!selection.isContentEditable() || selection.isNone())
- return String();
-
- VisibleSelection wordSelection(selection.base());
- wordSelection.expandUsingGranularity(WordGranularity);
- RefPtr<Range> wordRange = wordSelection.toNormalizedRange();
-
- // In compliance with GTK+ applications, additionally allow to provide suggestions when the current
- // selection exactly match the word selection.
- if (selection.isRange() && !areRangesEqual(wordRange.get(), selection.toNormalizedRange().get()))
- return String();
-
- String word = wordRange->text();
- if (word.isEmpty())
- return String();
-
- int wordLength = word.length();
- int misspellingLocation = -1;
- int misspellingLength = 0;
- textChecker().checkSpellingOfString(word, &misspellingLocation, &misspellingLength);
-
- return misspellingLength == wordLength ? word : String();
-}
-
void SpellChecker::showSpellingGuessPanel()
{
if (spellCheckerClient().spellingUIIsShowing()) {
@@ -347,9 +319,9 @@ void SpellChecker::showSpellingGuessPanel()
void SpellChecker::clearMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
{
- RefPtr<Range> selectedRange = movingSelection.toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> selectedRange = movingSelection.toNormalizedRange();
if (selectedRange)
- m_frame.document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::MisspellingMarkers());
+ m_frame.document()->markers().removeMarkers(selectedRange.get(), DocumentMarker::MisspellingMarkers());
}
void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
@@ -385,7 +357,7 @@ void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
return;
// Check spelling of one word
- RefPtr<Range> misspellingRange;
+ RefPtrWillBeRawPtr<Range> misspellingRange = nullptr;
markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)), misspellingRange);
// Autocorrect the misspelled word.
@@ -406,7 +378,7 @@ void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
m_frame.editor().replaceSelectionWithText(autocorrectedString, false, false);
// Reset the charet one character further.
- m_frame.selection().moveTo(m_frame.selection().end());
+ m_frame.selection().moveTo(m_frame.selection().selection().visibleEnd());
m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
}
@@ -417,7 +389,7 @@ void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wordStart)));
}
-void SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling, RefPtr<Range>& firstMisspellingRange)
+void SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selection, bool checkSpelling, RefPtrWillBeRawPtr<Range>& firstMisspellingRange)
{
// This function is called with a selection already expanded to word boundaries.
// Might be nice to assert that here.
@@ -427,7 +399,7 @@ void SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selectio
if (!isContinuousSpellCheckingEnabled())
return;
- RefPtr<Range> searchRange(selection.toNormalizedRange());
+ RefPtrWillBeRawPtr<Range> searchRange(selection.toNormalizedRange());
if (!searchRange)
return;
@@ -461,14 +433,14 @@ bool SpellChecker::isSpellCheckingEnabledInFocusedNode() const
return isSpellCheckingEnabledFor(m_frame.selection().start().deprecatedNode());
}
-void SpellChecker::markMisspellings(const VisibleSelection& selection, RefPtr<Range>& firstMisspellingRange)
+void SpellChecker::markMisspellings(const VisibleSelection& selection, RefPtrWillBeRawPtr<Range>& firstMisspellingRange)
{
markMisspellingsOrBadGrammar(selection, true, firstMisspellingRange);
}
void SpellChecker::markBadGrammar(const VisibleSelection& selection)
{
- RefPtr<Range> firstMisspellingRange;
+ RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr;
markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange);
}
@@ -501,7 +473,7 @@ void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node)
{
if (!node)
return;
- RefPtr<Range> rangeToCheck = Range::create(*m_frame.document(), firstPositionInNode(node), lastPositionInNode(node));
+ RefPtrWillBeRawPtr<Range> rangeToCheck = Range::create(*m_frame.document(), firstPositionInNode(node), lastPositionInNode(node));
TextCheckingParagraph textToCheck(rangeToCheck, rangeToCheck);
bool asynchronous = true;
chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextCheckingTypeSpelling | TextCheckingTypeGrammar), textToCheck, asynchronous);
@@ -520,7 +492,7 @@ void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
end = std::max(start, end);
const int kNumChunksToCheck = asynchronous ? (end - start + kChunkSize - 1) / (kChunkSize) : 1;
int currentChunkStart = start;
- RefPtr<Range> checkRange = fullParagraphToCheck.checkingRange();
+ RefPtrWillBeRawPtr<Range> checkRange = fullParagraphToCheck.checkingRange();
if (kNumChunksToCheck == 1 && asynchronous) {
markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange.get(), checkRange.get(), asynchronous, 0);
return;
@@ -528,8 +500,8 @@ void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
for (int iter = 0; iter < kNumChunksToCheck; ++iter) {
checkRange = fullParagraphToCheck.subrange(currentChunkStart, kChunkSize);
- setStart(checkRange.get(), startOfSentence(checkRange->startPosition()));
- setEnd(checkRange.get(), endOfSentence(checkRange->endPosition()));
+ setStart(checkRange.get(), startOfSentence(VisiblePosition(checkRange->startPosition())));
+ setEnd(checkRange.get(), endOfSentence(VisiblePosition(checkRange->endPosition())));
int checkingLength = 0;
markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange.get(), checkRange.get(), asynchronous, iter, &checkingLength);
@@ -598,22 +570,22 @@ void SpellChecker::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, cons
// "wouldn'" as misspelled right after apostrophe is typed.
if (shouldMarkSpelling && result->decoration == TextDecorationTypeSpelling && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) {
ASSERT(resultLength > 0 && resultLocation >= 0);
- RefPtr<Range> misspellingRange = paragraph.subrange(resultLocation, resultLength);
- misspellingRange->startContainer()->document().markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling, result->replacement, result->hash);
+ RefPtrWillBeRawPtr<Range> misspellingRange = paragraph.subrange(resultLocation, resultLength);
+ misspellingRange->startContainer()->document().markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling, result->replacement, result->hash);
} else if (shouldMarkGrammar && result->decoration == TextDecorationTypeGrammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) {
ASSERT(resultLength > 0 && resultLocation >= 0);
for (unsigned j = 0; j < result->details.size(); j++) {
const GrammarDetail* detail = &result->details[j];
ASSERT(detail->length > 0 && detail->location >= 0);
if (paragraph.checkingRangeCovers(resultLocation + detail->location, detail->length)) {
- RefPtr<Range> badGrammarRange = paragraph.subrange(resultLocation + detail->location, detail->length);
- badGrammarRange->startContainer()->document().markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription, result->hash);
+ RefPtrWillBeRawPtr<Range> badGrammarRange = paragraph.subrange(resultLocation + detail->location, detail->length);
+ badGrammarRange->startContainer()->document().markers().addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription, result->hash);
}
}
} else if (result->decoration == TextDecorationTypeInvisibleSpellcheck && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset) {
ASSERT(resultLength > 0 && resultLocation >= 0);
- RefPtr<Range> invisibleSpellcheckRange = paragraph.subrange(resultLocation, resultLength);
- invisibleSpellcheckRange->startContainer()->document().markers()->addMarker(invisibleSpellcheckRange.get(), DocumentMarker::InvisibleSpellcheck, result->replacement, result->hash);
+ RefPtrWillBeRawPtr<Range> invisibleSpellcheckRange = paragraph.subrange(resultLocation, resultLength);
+ invisibleSpellcheckRange->startContainer()->document().markers().addMarker(invisibleSpellcheckRange.get(), DocumentMarker::InvisibleSpellcheck, result->replacement, result->hash);
}
}
@@ -622,13 +594,13 @@ void SpellChecker::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, cons
// Restore the caret position if we have made any replacements
extendedParagraph.expandRangeToNextEnd();
if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffset <= extendedParagraph.rangeLength()) {
- RefPtr<Range> selectionRange = extendedParagraph.subrange(0, selectionOffset);
+ RefPtrWillBeRawPtr<Range> selectionRange = extendedParagraph.subrange(0, selectionOffset);
m_frame.selection().moveTo(selectionRange->endPosition(), DOWNSTREAM);
if (adjustSelectionForParagraphBoundaries)
m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
} else {
// If this fails for any reason, the fallback is to go one position beyond the last replacement
- m_frame.selection().moveTo(m_frame.selection().end());
+ m_frame.selection().moveTo(m_frame.selection().selection().visibleEnd());
m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
}
}
@@ -648,7 +620,7 @@ void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection& spellin
return;
}
- RefPtr<Range> firstMisspellingRange;
+ RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr;
markMisspellings(spellingSelection, firstMisspellingRange);
if (markGrammar)
markBadGrammar(grammarSelection);
@@ -669,8 +641,8 @@ void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSele
// Of course, if current selection is a range, we potentially will edit two words that fall on the boundaries of
// selection, and remove words between the selection boundaries.
//
- VisiblePosition startOfSelection = m_frame.selection().selection().start();
- VisiblePosition endOfSelection = m_frame.selection().selection().end();
+ VisiblePosition startOfSelection = m_frame.selection().selection().visibleStart();
+ VisiblePosition endOfSelection = m_frame.selection().selection().visibleEnd();
if (startOfSelection.isNull())
return;
// First word is the word that ends after or on the start of selection.
@@ -719,9 +691,9 @@ void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSele
// of marker that contains the word in question, and remove marker on that whole range.
Document* document = m_frame.document();
ASSERT(document);
- RefPtr<Range> wordRange = Range::create(*document, startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent());
+ RefPtrWillBeRawPtr<Range> wordRange = Range::create(*document, startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent());
- document->markers()->removeMarkers(wordRange.get(), DocumentMarker::MisspellingMarkers(), DocumentMarkerController::RemovePartiallyOverlappingMarker);
+ document->markers().removeMarkers(wordRange.get(), DocumentMarker::MisspellingMarkers(), DocumentMarkerController::RemovePartiallyOverlappingMarker);
}
void SpellChecker::didEndEditingOnTextField(Element* e)
@@ -730,12 +702,12 @@ void SpellChecker::didEndEditingOnTextField(Element* e)
// Prevent new ones from appearing too.
m_spellCheckRequester->cancelCheck();
HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlElement(e);
- HTMLElement* innerText = textFormControlElement->innerTextElement();
+ HTMLElement* innerEditor = textFormControlElement->innerEditorElement();
DocumentMarker::MarkerTypes markerTypes(DocumentMarker::Spelling);
if (isGrammarCheckingEnabled() || unifiedTextCheckerEnabled())
markerTypes.add(DocumentMarker::Grammar);
- for (Node* node = innerText; node; node = NodeTraversal::next(*node, innerText)) {
- m_frame.document()->markers()->removeMarkers(node, markerTypes);
+ for (Node* node = innerEditor; node; node = NodeTraversal::next(*node, innerEditor)) {
+ m_frame.document()->markers().removeMarkers(node, markerTypes);
}
}
@@ -770,20 +742,20 @@ void SpellChecker::respondToChangedSelection(const VisibleSelection& oldSelectio
}
if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)) {
- if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange())
- m_frame.document()->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
+ if (RefPtrWillBeRawPtr<Range> wordRange = newAdjacentWords.toNormalizedRange())
+ m_frame.document()->markers().removeMarkers(wordRange.get(), DocumentMarker::Spelling);
}
if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeGrammar)) {
- if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
- m_frame.document()->markers()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
+ if (RefPtrWillBeRawPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
+ m_frame.document()->markers().removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
}
}
// When continuous spell checking is off, existing markers disappear after the selection changes.
if (!isContinuousSpellCheckingEnabled)
- m_frame.document()->markers()->removeMarkers(DocumentMarker::Spelling);
+ m_frame.document()->markers().removeMarkers(DocumentMarker::Spelling);
if (!isContinuousGrammarCheckingEnabled)
- m_frame.document()->markers()->removeMarkers(DocumentMarker::Grammar);
+ m_frame.document()->markers().removeMarkers(DocumentMarker::Grammar);
}
void SpellChecker::spellCheckAfterBlur()
@@ -840,7 +812,7 @@ bool SpellChecker::selectionStartHasMarkerFor(DocumentMarker::MarkerType markerT
unsigned startOffset = static_cast<unsigned>(from);
unsigned endOffset = static_cast<unsigned>(from + length);
- Vector<DocumentMarker*> markers = m_frame.document()->markers()->markersFor(node);
+ WillBeHeapVector<DocumentMarker*> markers = m_frame.document()->markers().markersFor(node);
for (size_t i = 0; i < markers.size(); ++i) {
DocumentMarker* marker = markers[i];
if (marker->startOffset() <= startOffset && endOffset <= marker->endOffset() && marker->type() == markerType)
@@ -876,7 +848,7 @@ void SpellChecker::cancelCheck()
void SpellChecker::requestTextChecking(const Element& element)
{
- RefPtr<Range> rangeToCheck = rangeOfContents(const_cast<Element*>(&element));
+ RefPtrWillBeRawPtr<Range> rangeToCheck = rangeOfContents(const_cast<Element*>(&element));
m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextCheckingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToCheck, rangeToCheck));
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/SpellChecker.h b/chromium/third_party/WebKit/Source/core/editing/SpellChecker.h
index 009cca135a7..7b5811e90b5 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SpellChecker.h
+++ b/chromium/third_party/WebKit/Source/core/editing/SpellChecker.h
@@ -26,7 +26,7 @@
#ifndef SpellChecker_h
#define SpellChecker_h
-#include "core/dom/ClipboardAccessPolicy.h"
+#include "core/clipboard/ClipboardAccessPolicy.h"
#include "core/dom/DocumentMarker.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/VisibleSelection.h"
@@ -34,7 +34,7 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class SpellCheckerClient;
class SpellCheckRequest;
class SpellCheckRequester;
@@ -45,7 +45,7 @@ struct TextCheckingResult;
class SpellChecker {
WTF_MAKE_NONCOPYABLE(SpellChecker);
public:
- static PassOwnPtr<SpellChecker> create(Frame&);
+ static PassOwnPtr<SpellChecker> create(LocalFrame&);
~SpellChecker();
@@ -56,11 +56,10 @@ public:
void toggleContinuousSpellChecking();
bool isGrammarCheckingEnabled();
void ignoreSpelling();
- String misspelledWordAtCaretOrRange(Node* clickedNode) const;
bool isSpellCheckingEnabledInFocusedNode() const;
bool isSpellCheckingEnabledFor(Node*) const;
void markMisspellingsAfterTypingToWord(const VisiblePosition &wordStart, const VisibleSelection& selectionAfterTyping);
- void markMisspellings(const VisibleSelection&, RefPtr<Range>& firstMisspellingRange);
+ void markMisspellings(const VisibleSelection&, RefPtrWillBeRawPtr<Range>& firstMisspellingRange);
void markBadGrammar(const VisibleSelection&);
void markMisspellingsAndBadGrammar(const VisibleSelection& spellingSelection, bool markGrammar, const VisibleSelection& grammarSelection);
void markAndReplaceFor(PassRefPtr<SpellCheckRequest>, const Vector<TextCheckingResult>&);
@@ -85,12 +84,12 @@ public:
SpellCheckRequester& spellCheckRequester() const { return *m_spellCheckRequester; }
private:
- Frame& m_frame;
+ LocalFrame& m_frame;
const OwnPtr<SpellCheckRequester> m_spellCheckRequester;
- explicit SpellChecker(Frame&);
+ explicit SpellChecker(LocalFrame&);
- void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
+ void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtrWillBeRawPtr<Range>& firstMisspellingRange);
TextCheckingTypeMask resolveTextCheckingTypeMask(TextCheckingTypeMask);
bool unifiedTextCheckerEnabled() const;
diff --git a/chromium/third_party/WebKit/Source/core/editing/SpellingCorrectionCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/SpellingCorrectionCommand.cpp
deleted file mode 100644
index cc73001b77c..00000000000
--- a/chromium/third_party/WebKit/Source/core/editing/SpellingCorrectionCommand.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/editing/SpellingCorrectionCommand.h"
-
-#include "core/dom/Document.h"
-#include "core/editing/InsertTextCommand.h"
-#include "core/editing/SetSelectionCommand.h"
-#include "core/editing/TextIterator.h"
-#include "core/frame/Frame.h"
-
-namespace WebCore {
-
-SpellingCorrectionCommand::SpellingCorrectionCommand(PassRefPtr<Range> rangeToBeCorrected, const String& correction)
- : CompositeEditCommand(rangeToBeCorrected->startContainer()->document())
- , m_rangeToBeCorrected(rangeToBeCorrected)
- , m_selectionToBeCorrected(m_rangeToBeCorrected.get())
- , m_correction(correction)
-{
-}
-
-void SpellingCorrectionCommand::doApply()
-{
- m_corrected = plainText(m_rangeToBeCorrected.get());
- if (!m_corrected.length())
- return;
-
- applyCommandToComposite(SetSelectionCommand::create(m_selectionToBeCorrected, FrameSelection::SpellCorrectionTriggered | FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle));
- applyCommandToComposite(InsertTextCommand::create(document(), m_correction));
-}
-
-bool SpellingCorrectionCommand::shouldRetainAutocorrectionIndicator() const
-{
- return true;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SpellingCorrectionCommand.h b/chromium/third_party/WebKit/Source/core/editing/SpellingCorrectionCommand.h
deleted file mode 100644
index ae4d15e37ce..00000000000
--- a/chromium/third_party/WebKit/Source/core/editing/SpellingCorrectionCommand.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SpellingCorrectionCommand_h
-#define SpellingCorrectionCommand_h
-
-#include "core/dom/Range.h"
-#include "core/editing/CompositeEditCommand.h"
-
-namespace WebCore {
-
-class SpellingCorrectionCommand : public CompositeEditCommand {
-public:
- static PassRefPtr<SpellingCorrectionCommand> create(PassRefPtr<Range> rangeToBeCorrected, const String& correction)
- {
- return adoptRef(new SpellingCorrectionCommand(rangeToBeCorrected, correction));
- }
-private:
- SpellingCorrectionCommand(PassRefPtr<Range> rangeToBeCorrected, const String& correction);
- virtual void doApply();
- virtual bool shouldRetainAutocorrectionIndicator() const;
-
- RefPtr<Range> m_rangeToBeCorrected;
- VisibleSelection m_selectionToBeCorrected;
- String m_corrected;
- String m_correction;
-};
-
-} // namespace WebCore
-
-#endif // SpellingCorrectionCommand_h
diff --git a/chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.cpp
index 128c37097ed..dbd0357ecb3 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.cpp
@@ -26,15 +26,15 @@
#include "config.h"
#include "core/editing/SplitElementCommand.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "wtf/Assertions.h"
namespace WebCore {
-SplitElementCommand::SplitElementCommand(PassRefPtr<Element> element, PassRefPtr<Node> atChild)
+SplitElementCommand::SplitElementCommand(PassRefPtrWillBeRawPtr<Element> element, PassRefPtrWillBeRawPtr<Node> atChild)
: SimpleEditCommand(element->document())
, m_element2(element)
, m_atChild(atChild)
@@ -49,7 +49,7 @@ void SplitElementCommand::executeApply()
if (m_atChild->parentNode() != m_element2)
return;
- Vector<RefPtr<Node> > children;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > children;
for (Node* node = m_element2->firstChild(); node != m_atChild; node = node->nextSibling())
children.append(node);
@@ -82,19 +82,20 @@ void SplitElementCommand::doUnapply()
if (!m_element1 || !m_element1->rendererIsEditable() || !m_element2->rendererIsEditable())
return;
- Vector<RefPtr<Node> > children;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > children;
for (Node* node = m_element1->firstChild(); node; node = node->nextSibling())
children.append(node);
- RefPtr<Node> refChild = m_element2->firstChild();
+ RefPtrWillBeRawPtr<Node> refChild = m_element2->firstChild();
size_t size = children.size();
for (size_t i = 0; i < size; ++i)
m_element2->insertBefore(children[i].get(), refChild.get(), IGNORE_EXCEPTION);
// Recover the id attribute of the original element.
- if (m_element1->hasAttribute(HTMLNames::idAttr))
- m_element2->setAttribute(HTMLNames::idAttr, m_element1->getAttribute(HTMLNames::idAttr));
+ const AtomicString& id = m_element1->getAttribute(HTMLNames::idAttr);
+ if (!id.isNull())
+ m_element2->setAttribute(HTMLNames::idAttr, id);
m_element1->remove(IGNORE_EXCEPTION);
}
@@ -107,4 +108,12 @@ void SplitElementCommand::doReapply()
executeApply();
}
+void SplitElementCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_element1);
+ visitor->trace(m_element2);
+ visitor->trace(m_atChild);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.h b/chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.h
index a87b5a20984..228753d1858 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/SplitElementCommand.h
@@ -30,24 +30,26 @@
namespace WebCore {
-class SplitElementCommand : public SimpleEditCommand {
+class SplitElementCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<SplitElementCommand> create(PassRefPtr<Element> element, PassRefPtr<Node> splitPointChild)
+ static PassRefPtrWillBeRawPtr<SplitElementCommand> create(PassRefPtrWillBeRawPtr<Element> element, PassRefPtrWillBeRawPtr<Node> splitPointChild)
{
- return adoptRef(new SplitElementCommand(element, splitPointChild));
+ return adoptRefWillBeNoop(new SplitElementCommand(element, splitPointChild));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- SplitElementCommand(PassRefPtr<Element>, PassRefPtr<Node> splitPointChild);
+ SplitElementCommand(PassRefPtrWillBeRawPtr<Element>, PassRefPtrWillBeRawPtr<Node> splitPointChild);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
virtual void doReapply() OVERRIDE;
void executeApply();
- RefPtr<Element> m_element1;
- RefPtr<Element> m_element2;
- RefPtr<Node> m_atChild;
+ RefPtrWillBeMember<Element> m_element1;
+ RefPtrWillBeMember<Element> m_element2;
+ RefPtrWillBeMember<Node> m_atChild;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.cpp
index 34086598049..e4a3bd2ceca 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.cpp
@@ -35,7 +35,7 @@
namespace WebCore {
-SplitTextNodeCommand::SplitTextNodeCommand(PassRefPtr<Text> text, int offset)
+SplitTextNodeCommand::SplitTextNodeCommand(PassRefPtrWillBeRawPtr<Text> text, int offset)
: SimpleEditCommand(text->document())
, m_text2(text)
, m_offset(offset)
@@ -62,7 +62,7 @@ void SplitTextNodeCommand::doApply()
m_text1 = Text::create(document(), prefixText);
ASSERT(m_text1);
- document().markers()->copyMarkers(m_text2.get(), 0, m_offset, m_text1.get(), 0);
+ document().markers().copyMarkers(m_text2.get(), 0, m_offset, m_text1.get(), 0);
insertText1AndTrimText2();
}
@@ -78,7 +78,7 @@ void SplitTextNodeCommand::doUnapply()
m_text2->insertData(0, prefixText, ASSERT_NO_EXCEPTION, CharacterData::DeprecatedRecalcStyleImmediatlelyForEditing);
- document().markers()->copyMarkers(m_text1.get(), 0, prefixText.length(), m_text2.get(), 0);
+ document().markers().copyMarkers(m_text1.get(), 0, prefixText.length(), m_text2.get(), 0);
m_text1->remove(ASSERT_NO_EXCEPTION);
}
@@ -103,4 +103,11 @@ void SplitTextNodeCommand::insertText1AndTrimText2()
m_text2->deleteData(0, m_offset, exceptionState, CharacterData::DeprecatedRecalcStyleImmediatlelyForEditing);
}
+void SplitTextNodeCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_text1);
+ visitor->trace(m_text2);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.h b/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.h
index 27e0cb414ad..bef56eb2069 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeCommand.h
@@ -32,23 +32,25 @@ namespace WebCore {
class Text;
-class SplitTextNodeCommand : public SimpleEditCommand {
+class SplitTextNodeCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<SplitTextNodeCommand> create(PassRefPtr<Text> node, int offset)
+ static PassRefPtrWillBeRawPtr<SplitTextNodeCommand> create(PassRefPtrWillBeRawPtr<Text> node, int offset)
{
- return adoptRef(new SplitTextNodeCommand(node, offset));
+ return adoptRefWillBeNoop(new SplitTextNodeCommand(node, offset));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- SplitTextNodeCommand(PassRefPtr<Text>, int offset);
+ SplitTextNodeCommand(PassRefPtrWillBeRawPtr<Text>, int offset);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
virtual void doReapply() OVERRIDE;
void insertText1AndTrimText2();
- RefPtr<Text> m_text1;
- RefPtr<Text> m_text2;
+ RefPtrWillBeMember<Text> m_text1;
+ RefPtrWillBeMember<Text> m_text2;
unsigned m_offset;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.cpp
index a29ef84c75a..62231d6552a 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.cpp
@@ -33,7 +33,7 @@
namespace WebCore {
-SplitTextNodeContainingElementCommand::SplitTextNodeContainingElementCommand(PassRefPtr<Text> text, int offset)
+SplitTextNodeContainingElementCommand::SplitTextNodeContainingElementCommand(PassRefPtrWillBeRawPtr<Text> text, int offset)
: CompositeEditCommand(text->document()), m_text(text), m_offset(offset)
{
ASSERT(m_text);
@@ -60,7 +60,13 @@ void SplitTextNodeContainingElementCommand::doApply()
parent = toElement(firstChild);
}
- splitElement(parent, m_text);
+ splitElement(parent, m_text.get());
+}
+
+void SplitTextNodeContainingElementCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_text);
+ CompositeEditCommand::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.h b/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.h
index ba9da5b81a9..072ed1946cc 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/SplitTextNodeContainingElementCommand.h
@@ -30,19 +30,21 @@
namespace WebCore {
-class SplitTextNodeContainingElementCommand : public CompositeEditCommand {
+class SplitTextNodeContainingElementCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<SplitTextNodeContainingElementCommand> create(PassRefPtr<Text> node, int offset)
+ static PassRefPtrWillBeRawPtr<SplitTextNodeContainingElementCommand> create(PassRefPtrWillBeRawPtr<Text> node, int offset)
{
- return adoptRef(new SplitTextNodeContainingElementCommand(node, offset));
+ return adoptRefWillBeNoop(new SplitTextNodeContainingElementCommand(node, offset));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- SplitTextNodeContainingElementCommand(PassRefPtr<Text>, int offset);
+ SplitTextNodeContainingElementCommand(PassRefPtrWillBeRawPtr<Text>, int offset);
- virtual void doApply();
+ virtual void doApply() OVERRIDE;
- RefPtr<Text> m_text;
+ RefPtrWillBeMember<Text> m_text;
int m_offset;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/SurroundingText.cpp b/chromium/third_party/WebKit/Source/core/editing/SurroundingText.cpp
index e90e9e717e8..ca1a5ed17d8 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SurroundingText.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/SurroundingText.cpp
@@ -32,52 +32,77 @@
#include "core/editing/SurroundingText.h"
#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/Position.h"
#include "core/dom/Range.h"
#include "core/editing/TextIterator.h"
-#include "core/editing/VisiblePosition.h"
-#include "core/editing/VisibleUnits.h"
namespace WebCore {
-SurroundingText::SurroundingText(const VisiblePosition& visiblePosition, unsigned maxLength)
- : m_positionOffsetInContent(0)
+SurroundingText::SurroundingText(const Range& range, unsigned maxLength)
+ : m_startOffsetInContent(0)
+ , m_endOffsetInContent(0)
{
- if (visiblePosition.isNull())
- return;
+ initialize(range.startPosition(), range.endPosition(), maxLength);
+}
+
+SurroundingText::SurroundingText(const Position& position, unsigned maxLength)
+ : m_startOffsetInContent(0)
+ , m_endOffsetInContent(0)
+{
+ initialize(position, position, maxLength);
+}
+
+void SurroundingText::initialize(const Position& startPosition, const Position& endPosition, unsigned maxLength)
+{
+ ASSERT(startPosition.document() == endPosition.document());
const unsigned halfMaxLength = maxLength / 2;
- CharacterIterator forwardIterator(makeRange(visiblePosition, endOfDocument(visiblePosition)).get(), TextIteratorStopsOnFormControls);
+
+ Document* document = startPosition.document();
+ // The position will have no document if it is null (as in no position).
+ if (!document)
+ return;
+
+ // The forward range starts at the selection end and ends at the document's
+ // end. It will then be updated to only contain the text in the text in the
+ // right range around the selection.
+ RefPtrWillBeRawPtr<Range> forwardRange = Range::create(*document, endPosition, lastPositionInNode(document->documentElement()).parentAnchoredEquivalent());
+ CharacterIterator forwardIterator(forwardRange.get(), TextIteratorStopsOnFormControls);
+ // FIXME: why do we stop going trough the text if we were not able to select something on the right?
if (!forwardIterator.atEnd())
forwardIterator.advance(maxLength - halfMaxLength);
- Position position = visiblePosition.deepEquivalent().parentAnchoredEquivalent();
- Document* document = position.document();
- ASSERT(document);
- RefPtr<Range> forwardRange = forwardIterator.range();
- if (!forwardRange || !Range::create(*document, position, forwardRange->startPosition())->text().length()) {
+ forwardRange = forwardIterator.range();
+ if (!forwardRange || !Range::create(*document, endPosition, forwardRange->startPosition())->text().length()) {
ASSERT(forwardRange);
return;
}
- BackwardsCharacterIterator backwardsIterator(makeRange(startOfDocument(visiblePosition), visiblePosition).get(), TextIteratorStopsOnFormControls);
+ // Same as with the forward range but with the backward range. The range
+ // starts at the document's start and ends at the selection start and will
+ // be updated.
+ RefPtrWillBeRawPtr<Range> backwardsRange = Range::create(*document, firstPositionInNode(document->documentElement()).parentAnchoredEquivalent(), startPosition);
+ BackwardsCharacterIterator backwardsIterator(backwardsRange.get(), TextIteratorStopsOnFormControls);
if (!backwardsIterator.atEnd())
backwardsIterator.advance(halfMaxLength);
- RefPtr<Range> backwardsRange = backwardsIterator.range();
+ backwardsRange = backwardsIterator.range();
if (!backwardsRange) {
ASSERT(backwardsRange);
return;
}
- m_positionOffsetInContent = Range::create(*document, backwardsRange->endPosition(), position)->text().length();
+ m_startOffsetInContent = Range::create(*document, backwardsRange->endPosition(), startPosition)->text().length();
+ m_endOffsetInContent = Range::create(*document, backwardsRange->endPosition(), endPosition)->text().length();
m_contentRange = Range::create(*document, backwardsRange->endPosition(), forwardRange->startPosition());
ASSERT(m_contentRange);
}
-PassRefPtr<Range> SurroundingText::rangeFromContentOffsets(unsigned startOffsetInContent, unsigned endOffsetInContent)
+PassRefPtrWillBeRawPtr<Range> SurroundingText::rangeFromContentOffsets(unsigned startOffsetInContent, unsigned endOffsetInContent)
{
if (startOffsetInContent >= endOffsetInContent || endOffsetInContent > content().length())
- return 0;
+ return nullptr;
CharacterIterator iterator(m_contentRange.get());
@@ -104,9 +129,14 @@ String SurroundingText::content() const
return String();
}
-unsigned SurroundingText::positionOffsetInContent() const
+unsigned SurroundingText::startOffsetInContent() const
+{
+ return m_startOffsetInContent;
+}
+
+unsigned SurroundingText::endOffsetInContent() const
{
- return m_positionOffsetInContent;
+ return m_endOffsetInContent;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SurroundingText.h b/chromium/third_party/WebKit/Source/core/editing/SurroundingText.h
index 03ef2894155..05a5d7f2b5e 100644
--- a/chromium/third_party/WebKit/Source/core/editing/SurroundingText.h
+++ b/chromium/third_party/WebKit/Source/core/editing/SurroundingText.h
@@ -31,26 +31,32 @@
#ifndef SurroundingText_h
#define SurroundingText_h
+#include "platform/heap/Handle.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
+class Position;
class Range;
-class VisiblePosition;
class SurroundingText {
WTF_MAKE_NONCOPYABLE(SurroundingText);
public:
- SurroundingText(const VisiblePosition&, unsigned maxLength);
+ SurroundingText(const Range&, unsigned maxLength);
+ SurroundingText(const Position&, unsigned maxLength);
String content() const;
- unsigned positionOffsetInContent() const;
+ unsigned startOffsetInContent() const;
+ unsigned endOffsetInContent() const;
- PassRefPtr<Range> rangeFromContentOffsets(unsigned startOffsetInContent, unsigned endOffsetInContent);
+ PassRefPtrWillBeRawPtr<Range> rangeFromContentOffsets(unsigned startOffsetInContent, unsigned endOffsetInContent);
private:
- RefPtr<Range> m_contentRange;
- size_t m_positionOffsetInContent;
+ void initialize(const Position&, const Position&, unsigned maxLength);
+
+ RefPtrWillBePersistent<Range> m_contentRange;
+ size_t m_startOffsetInContent;
+ size_t m_endOffsetInContent;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp b/chromium/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp
new file mode 100644
index 00000000000..d6a58e5c45e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/editing/SurroundingTextTest.cpp
@@ -0,0 +1,264 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/editing/SurroundingText.h"
+
+#include "core/dom/Position.h"
+#include "core/dom/Range.h"
+#include "core/dom/Text.h"
+#include "core/editing/VisibleSelection.h"
+#include "core/html/HTMLElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class SurroundingTextTest : public ::testing::Test {
+protected:
+ Document& document() const { return m_dummyPageHolder->document(); }
+ void setHTML(const String&);
+ VisibleSelection select(int offset) { return select(offset, offset); }
+ VisibleSelection select(int start, int end);
+
+private:
+ virtual void SetUp() OVERRIDE;
+
+ OwnPtr<DummyPageHolder> m_dummyPageHolder;
+};
+
+void SurroundingTextTest::SetUp()
+{
+ m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+}
+
+void SurroundingTextTest::setHTML(const String& content)
+{
+ document().body()->setInnerHTML(content, ASSERT_NO_EXCEPTION);
+}
+
+VisibleSelection SurroundingTextTest::select(int start, int end)
+{
+ Element* element = document().getElementById("selection");
+ VisibleSelection selection;
+ selection.setBase(Position(toText(element->firstChild()), start));
+ selection.setExtent(Position(toText(element->firstChild()), end));
+ return selection;
+}
+
+TEST_F(SurroundingTextTest, BasicCaretSelection)
+{
+ setHTML(String("<p id='selection'>foo bar</p>"));
+
+ {
+ VisibleSelection selection = select(0);
+ SurroundingText surroundingText(selection.start(), 1);
+
+ EXPECT_EQ("f", surroundingText.content());
+ EXPECT_EQ(0u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(0u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0);
+ SurroundingText surroundingText(selection.start(), 5);
+
+ // maxlength/2 is used on the left and right.
+ EXPECT_EQ("foo", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(1u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(1u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0);
+ SurroundingText surroundingText(selection.start(), 42);
+
+ EXPECT_EQ("foo bar", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(1u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(1u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ // FIXME: if the selection is at the end of the text, SurroundingText
+ // will return nothing.
+ VisibleSelection selection = select(7);
+ SurroundingText surroundingText(selection.start(), 42);
+
+ EXPECT_EQ(0u, surroundingText.content().length());
+ EXPECT_EQ(0u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(0u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(6);
+ SurroundingText surroundingText(selection.start(), 2);
+
+ EXPECT_EQ("ar", surroundingText.content());
+ EXPECT_EQ(1u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(1u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(6);
+ SurroundingText surroundingText(selection.start(), 42);
+
+ EXPECT_EQ("foo bar", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(7u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(7u, surroundingText.endOffsetInContent());
+ }
+}
+
+TEST_F(SurroundingTextTest, BasicRangeSelection)
+{
+ setHTML(String("<p id='selection'>Lorem ipsum dolor sit amet</p>"));
+
+ {
+ VisibleSelection selection = select(0, 5);
+ SurroundingText surroundingText(*selection.firstRange(), 1);
+
+ EXPECT_EQ("Lorem ", surroundingText.content());
+ EXPECT_EQ(0u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(5u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0, 5);
+ SurroundingText surroundingText(*selection.firstRange(), 5);
+
+ EXPECT_EQ("Lorem ip", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(1u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(6u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0, 5);
+ SurroundingText surroundingText(*selection.firstRange(), 42);
+
+ EXPECT_EQ("Lorem ipsum dolor sit amet", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(1u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(6u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(6, 11);
+ SurroundingText surroundingText(*selection.firstRange(), 2);
+
+ EXPECT_EQ(" ipsum ", surroundingText.content());
+ EXPECT_EQ(1u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(6u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(6, 11);
+ SurroundingText surroundingText(*selection.firstRange(), 42);
+
+ EXPECT_EQ("Lorem ipsum dolor sit amet", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(7u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(12u, surroundingText.endOffsetInContent());
+ }
+}
+
+TEST_F(SurroundingTextTest, TreeCaretSelection)
+{
+ setHTML(String("<div>This is outside of <p id='selection'>foo bar</p> the selected node</div>"));
+
+ {
+ VisibleSelection selection = select(0);
+ SurroundingText surroundingText(selection.start(), 1);
+
+ EXPECT_EQ("f", surroundingText.content());
+ EXPECT_EQ(0u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(0u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0);
+ SurroundingText surroundingText(selection.start(), 5);
+
+ EXPECT_EQ("foo", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(1u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(1u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0);
+ SurroundingText surroundingText(selection.start(), 1337);
+
+ EXPECT_EQ("This is outside of foo bar the selected node", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(20u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(20u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(6);
+ SurroundingText surroundingText(selection.start(), 2);
+
+ EXPECT_EQ("ar", surroundingText.content());
+ EXPECT_EQ(1u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(1u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(6);
+ SurroundingText surroundingText(selection.start(), 1337);
+
+ EXPECT_EQ("This is outside of foo bar the selected node", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(26u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(26u, surroundingText.endOffsetInContent());
+ }
+}
+
+TEST_F(SurroundingTextTest, TreeRangeSelection)
+{
+ setHTML(String("<div>This is outside of <p id='selection'>foo bar</p> the selected node</div>"));
+
+ {
+ VisibleSelection selection = select(0, 1);
+ SurroundingText surroundingText(*selection.firstRange(), 1);
+
+ EXPECT_EQ("fo", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(0u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(1u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0, 3);
+ SurroundingText surroundingText(*selection.firstRange(), 12);
+
+ EXPECT_EQ("e of foo bar", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(5u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(8u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0, 3);
+ SurroundingText surroundingText(*selection.firstRange(), 1337);
+
+ EXPECT_EQ("This is outside of foo bar the selected node", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(20u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(23u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(4, 7);
+ SurroundingText surroundingText(*selection.firstRange(), 12);
+
+ EXPECT_EQ("foo bar the se", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(5u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(8u, surroundingText.endOffsetInContent());
+ }
+
+ {
+ VisibleSelection selection = select(0, 7);
+ SurroundingText surroundingText(*selection.firstRange(), 1337);
+
+ EXPECT_EQ("This is outside of foo bar the selected node", surroundingText.content().simplifyWhiteSpace());
+ EXPECT_EQ(20u, surroundingText.startOffsetInContent());
+ EXPECT_EQ(27u, surroundingText.endOffsetInContent());
+ }
+}
+
+} // anonymous namespace
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.cpp b/chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.cpp
index 091585afd09..0cebb80f33f 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.cpp
@@ -35,7 +35,7 @@
#include "core/editing/TextIterator.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/page/SpellCheckerClient.h"
#include "platform/text/TextBreakIterator.h"
@@ -98,15 +98,15 @@ static void findMisspellings(TextCheckerClient& client, const UChar* text, int s
}
}
-static PassRefPtr<Range> expandToParagraphBoundary(PassRefPtr<Range> range)
+static PassRefPtrWillBeRawPtr<Range> expandToParagraphBoundary(PassRefPtrWillBeRawPtr<Range> range)
{
- RefPtr<Range> paragraphRange = range->cloneRange(IGNORE_EXCEPTION);
- setStart(paragraphRange.get(), startOfParagraph(range->startPosition()));
- setEnd(paragraphRange.get(), endOfParagraph(range->endPosition()));
+ RefPtrWillBeRawPtr<Range> paragraphRange = range->cloneRange();
+ setStart(paragraphRange.get(), startOfParagraph(VisiblePosition(range->startPosition())));
+ setEnd(paragraphRange.get(), endOfParagraph(VisiblePosition(range->endPosition())));
return paragraphRange;
}
-TextCheckingParagraph::TextCheckingParagraph(PassRefPtr<Range> checkingRange)
+TextCheckingParagraph::TextCheckingParagraph(PassRefPtrWillBeRawPtr<Range> checkingRange)
: m_checkingRange(checkingRange)
, m_checkingStart(-1)
, m_checkingEnd(-1)
@@ -114,7 +114,7 @@ TextCheckingParagraph::TextCheckingParagraph(PassRefPtr<Range> checkingRange)
{
}
-TextCheckingParagraph::TextCheckingParagraph(PassRefPtr<Range> checkingRange, PassRefPtr<Range> paragraphRange)
+TextCheckingParagraph::TextCheckingParagraph(PassRefPtrWillBeRawPtr<Range> checkingRange, PassRefPtrWillBeRawPtr<Range> paragraphRange)
: m_checkingRange(checkingRange)
, m_paragraphRange(paragraphRange)
, m_checkingStart(-1)
@@ -130,14 +130,14 @@ TextCheckingParagraph::~TextCheckingParagraph()
void TextCheckingParagraph::expandRangeToNextEnd()
{
ASSERT(m_checkingRange);
- setEnd(paragraphRange().get(), endOfParagraph(startOfNextParagraph(paragraphRange()->startPosition())));
+ setEnd(paragraphRange().get(), endOfParagraph(startOfNextParagraph(VisiblePosition(paragraphRange()->startPosition()))));
invalidateParagraphRangeValues();
}
void TextCheckingParagraph::invalidateParagraphRangeValues()
{
m_checkingStart = m_checkingEnd = -1;
- m_offsetAsRange = 0;
+ m_offsetAsRange = nullptr;
m_text = String();
}
@@ -147,7 +147,7 @@ int TextCheckingParagraph::rangeLength() const
return TextIterator::rangeLength(paragraphRange().get());
}
-PassRefPtr<Range> TextCheckingParagraph::paragraphRange() const
+PassRefPtrWillBeRawPtr<Range> TextCheckingParagraph::paragraphRange() const
{
ASSERT(m_checkingRange);
if (!m_paragraphRange)
@@ -155,7 +155,7 @@ PassRefPtr<Range> TextCheckingParagraph::paragraphRange() const
return m_paragraphRange;
}
-PassRefPtr<Range> TextCheckingParagraph::subrange(int characterOffset, int characterCount) const
+PassRefPtrWillBeRawPtr<Range> TextCheckingParagraph::subrange(int characterOffset, int characterCount) const
{
ASSERT(m_checkingRange);
return TextIterator::subrange(paragraphRange().get(), characterOffset, characterCount);
@@ -164,7 +164,7 @@ PassRefPtr<Range> TextCheckingParagraph::subrange(int characterOffset, int chara
int TextCheckingParagraph::offsetTo(const Position& position, ExceptionState& exceptionState) const
{
ASSERT(m_checkingRange);
- RefPtr<Range> range = offsetAsRange()->cloneRange(ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<Range> range = offsetAsRange()->cloneRange();
range->setEnd(position.containerNode(), position.computeOffsetInContainerNode(), exceptionState);
if (exceptionState.hadException())
return 0;
@@ -178,7 +178,7 @@ bool TextCheckingParagraph::isEmpty() const
return isRangeEmpty() || isTextEmpty();
}
-PassRefPtr<Range> TextCheckingParagraph::offsetAsRange() const
+PassRefPtrWillBeRawPtr<Range> TextCheckingParagraph::offsetAsRange() const
{
ASSERT(m_checkingRange);
if (!m_offsetAsRange)
@@ -219,7 +219,7 @@ int TextCheckingParagraph::checkingLength() const
return m_checkingLength;
}
-TextCheckingHelper::TextCheckingHelper(SpellCheckerClient& client, PassRefPtr<Range> range)
+TextCheckingHelper::TextCheckingHelper(SpellCheckerClient& client, PassRefPtrWillBeRawPtr<Range> range)
: m_client(&client)
, m_range(range)
{
@@ -230,7 +230,7 @@ TextCheckingHelper::~TextCheckingHelper()
{
}
-String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, bool markAll, RefPtr<Range>& firstMisspellingRange)
+String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, bool markAll, RefPtrWillBeRawPtr<Range>& firstMisspellingRange)
{
WordAwareIterator it(m_range.get());
firstMisspellingOffset = 0;
@@ -261,7 +261,7 @@ String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, boo
if (misspellingLocation >= 0 && misspellingLength > 0 && misspellingLocation < length && misspellingLength <= length && misspellingLocation + misspellingLength <= length) {
// Compute range of misspelled word
- RefPtr<Range> misspellingRange = TextIterator::subrange(m_range.get(), currentChunkOffset + misspellingLocation, misspellingLength);
+ RefPtrWillBeRawPtr<Range> misspellingRange = TextIterator::subrange(m_range.get(), currentChunkOffset + misspellingLocation, misspellingLength);
// Remember first-encountered misspelling and its offset.
if (!firstMisspelling) {
@@ -271,7 +271,7 @@ String TextCheckingHelper::findFirstMisspelling(int& firstMisspellingOffset, boo
}
// Store marker for misspelled word.
- misspellingRange->startContainer()->document().markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
+ misspellingRange->startContainer()->document().markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling);
// Bail out if we're marking only the first misspelling, and not all instances.
if (!markAll)
@@ -306,12 +306,12 @@ String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool checkGrammar, b
// Expand the search range to encompass entire paragraphs, since text checking needs that much context.
// Determine the character offset from the start of the paragraph to the start of the original search range,
// since we will want to ignore results in this area.
- RefPtr<Range> paragraphRange = m_range->cloneRange(IGNORE_EXCEPTION);
- setStart(paragraphRange.get(), startOfParagraph(m_range->startPosition()));
+ RefPtrWillBeRawPtr<Range> paragraphRange = m_range->cloneRange();
+ setStart(paragraphRange.get(), startOfParagraph(VisiblePosition(m_range->startPosition())));
int totalRangeLength = TextIterator::rangeLength(paragraphRange.get());
- setEnd(paragraphRange.get(), endOfParagraph(m_range->startPosition()));
+ setEnd(paragraphRange.get(), endOfParagraph(VisiblePosition(m_range->startPosition())));
- RefPtr<Range> offsetAsRange = Range::create(paragraphRange->startContainer()->document(), paragraphRange->startPosition(), m_range->startPosition());
+ RefPtrWillBeRawPtr<Range> offsetAsRange = Range::create(paragraphRange->startContainer()->document(), paragraphRange->startPosition(), m_range->startPosition());
int rangeStartOffset = TextIterator::rangeLength(offsetAsRange.get());
int totalLengthProcessed = 0;
@@ -322,10 +322,10 @@ String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool checkGrammar, b
int currentLength = TextIterator::rangeLength(paragraphRange.get());
int currentStartOffset = firstIteration ? rangeStartOffset : 0;
int currentEndOffset = currentLength;
- if (inSameParagraph(paragraphRange->startPosition(), m_range->endPosition())) {
+ if (inSameParagraph(VisiblePosition(paragraphRange->startPosition()), VisiblePosition(m_range->endPosition()))) {
// Determine the character offset from the end of the original search range to the end of the paragraph,
// since we will want to ignore results in this area.
- RefPtr<Range> endOffsetAsRange = Range::create(paragraphRange->startContainer()->document(), paragraphRange->startPosition(), m_range->endPosition());
+ RefPtrWillBeRawPtr<Range> endOffsetAsRange = Range::create(paragraphRange->startContainer()->document(), paragraphRange->startPosition(), m_range->endPosition());
currentEndOffset = TextIterator::rangeLength(endOffsetAsRange.get());
lastIteration = true;
}
@@ -378,7 +378,7 @@ String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool checkGrammar, b
if (!misspelledWord.isEmpty() && (!checkGrammar || badGrammarPhrase.isEmpty() || spellingLocation <= grammarDetailLocation)) {
int spellingOffset = spellingLocation - currentStartOffset;
if (!firstIteration) {
- RefPtr<Range> paragraphOffsetAsRange = Range::create(paragraphRange->startContainer()->document(), m_range->startPosition(), paragraphRange->startPosition());
+ RefPtrWillBeRawPtr<Range> paragraphOffsetAsRange = Range::create(paragraphRange->startContainer()->document(), m_range->startPosition(), paragraphRange->startPosition());
spellingOffset += TextIterator::rangeLength(paragraphOffsetAsRange.get());
}
outIsSpelling = true;
@@ -389,7 +389,7 @@ String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool checkGrammar, b
if (checkGrammar && !badGrammarPhrase.isEmpty()) {
int grammarPhraseOffset = grammarPhraseLocation - currentStartOffset;
if (!firstIteration) {
- RefPtr<Range> paragraphOffsetAsRange = Range::create(paragraphRange->startContainer()->document(), m_range->startPosition(), paragraphRange->startPosition());
+ RefPtrWillBeRawPtr<Range> paragraphOffsetAsRange = Range::create(paragraphRange->startContainer()->document(), m_range->startPosition(), paragraphRange->startPosition());
grammarPhraseOffset += TextIterator::rangeLength(paragraphOffsetAsRange.get());
}
outIsSpelling = false;
@@ -401,7 +401,7 @@ String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool checkGrammar, b
}
if (lastIteration || totalLengthProcessed + currentLength >= totalRangeLength)
break;
- VisiblePosition newParagraphStart = startOfNextParagraph(paragraphRange->endPosition());
+ VisiblePosition newParagraphStart = startOfNextParagraph(VisiblePosition(paragraphRange->endPosition()));
setStart(paragraphRange.get(), newParagraphStart);
setEnd(paragraphRange.get(), endOfParagraph(newParagraphStart));
firstIteration = false;
@@ -431,8 +431,8 @@ int TextCheckingHelper::findFirstGrammarDetail(const Vector<GrammarDetail>& gram
continue;
if (markAll) {
- RefPtr<Range> badGrammarRange = TextIterator::subrange(m_range.get(), badGrammarPhraseLocation - startOffset + detail->location, detail->length);
- badGrammarRange->startContainer()->document().markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
+ RefPtrWillBeRawPtr<Range> badGrammarRange = TextIterator::subrange(m_range.get(), badGrammarPhraseLocation - startOffset + detail->location, detail->length);
+ badGrammarRange->startContainer()->document().markers().addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
}
// Remember this detail only if it's earlier than our current candidate (the details aren't in a guaranteed order)
@@ -504,7 +504,7 @@ String TextCheckingHelper::findFirstBadGrammar(GrammarDetail& outGrammarDetail,
return firstBadGrammarPhrase;
}
-void TextCheckingHelper::markAllMisspellings(RefPtr<Range>& firstMisspellingRange)
+void TextCheckingHelper::markAllMisspellings(RefPtrWillBeRawPtr<Range>& firstMisspellingRange)
{
// Use the "markAll" feature of findFirstMisspelling. Ignore the return value and the "out parameter";
// all we need to do is mark every instance.
@@ -559,11 +559,11 @@ void checkTextOfParagraph(TextCheckerClient& client, const String& text, TextChe
if (results.isEmpty())
results.swap(spellingResult);
else
- results.append(spellingResult);
+ results.appendVector(spellingResult);
}
}
-bool unifiedTextCheckerEnabled(const Frame* frame)
+bool unifiedTextCheckerEnabled(const LocalFrame* frame)
{
if (!frame)
return false;
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.h b/chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.h
index a69116e3345..412232cdbf5 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.h
+++ b/chromium/third_party/WebKit/Source/core/editing/TextCheckingHelper.h
@@ -21,13 +21,14 @@
#ifndef TextCheckingHelper_h
#define TextCheckingHelper_h
+#include "platform/heap/Handle.h"
#include "platform/text/TextChecking.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
class ExceptionState;
-class Frame;
+class LocalFrame;
class Range;
class Position;
class SpellCheckerClient;
@@ -35,13 +36,14 @@ class TextCheckerClient;
struct TextCheckingResult;
class TextCheckingParagraph {
+ STACK_ALLOCATED();
public:
- explicit TextCheckingParagraph(PassRefPtr<Range> checkingRange);
- TextCheckingParagraph(PassRefPtr<Range> checkingRange, PassRefPtr<Range> paragraphRange);
+ explicit TextCheckingParagraph(PassRefPtrWillBeRawPtr<Range> checkingRange);
+ TextCheckingParagraph(PassRefPtrWillBeRawPtr<Range> checkingRange, PassRefPtrWillBeRawPtr<Range> paragraphRange);
~TextCheckingParagraph();
int rangeLength() const;
- PassRefPtr<Range> subrange(int characterOffset, int characterCount) const;
+ PassRefPtrWillBeRawPtr<Range> subrange(int characterOffset, int characterCount) const;
int offsetTo(const Position&, ExceptionState&) const;
void expandRangeToNextEnd();
@@ -60,16 +62,16 @@ public:
String checkingSubstring() const { return textSubstring(checkingStart(), checkingLength()); }
bool checkingRangeCovers(int location, int length) const { return location < checkingEnd() && location + length > checkingStart(); }
- PassRefPtr<Range> paragraphRange() const;
- PassRefPtr<Range> checkingRange() const { return m_checkingRange; }
+ PassRefPtrWillBeRawPtr<Range> paragraphRange() const;
+ PassRefPtrWillBeRawPtr<Range> checkingRange() const { return m_checkingRange; }
private:
void invalidateParagraphRangeValues();
- PassRefPtr<Range> offsetAsRange() const;
+ PassRefPtrWillBeRawPtr<Range> offsetAsRange() const;
- RefPtr<Range> m_checkingRange;
- mutable RefPtr<Range> m_paragraphRange;
- mutable RefPtr<Range> m_offsetAsRange;
+ RefPtrWillBeMember<Range> m_checkingRange;
+ mutable RefPtrWillBeMember<Range> m_paragraphRange;
+ mutable RefPtrWillBeMember<Range> m_offsetAsRange;
mutable String m_text;
mutable int m_checkingStart;
mutable int m_checkingEnd;
@@ -78,19 +80,20 @@ private:
class TextCheckingHelper {
WTF_MAKE_NONCOPYABLE(TextCheckingHelper);
+ STACK_ALLOCATED();
public:
- TextCheckingHelper(SpellCheckerClient&, PassRefPtr<Range>);
+ TextCheckingHelper(SpellCheckerClient&, PassRefPtrWillBeRawPtr<Range>);
~TextCheckingHelper();
- String findFirstMisspelling(int& firstMisspellingOffset, bool markAll, RefPtr<Range>& firstMisspellingRange);
+ String findFirstMisspelling(int& firstMisspellingOffset, bool markAll, RefPtrWillBeRawPtr<Range>& firstMisspellingRange);
String findFirstMisspellingOrBadGrammar(bool checkGrammar, bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail);
String findFirstBadGrammar(GrammarDetail& outGrammarDetail, int& outGrammarPhraseOffset, bool markAll);
- void markAllMisspellings(RefPtr<Range>& firstMisspellingRange);
+ void markAllMisspellings(RefPtrWillBeRawPtr<Range>& firstMisspellingRange);
void markAllBadGrammar();
private:
SpellCheckerClient* m_client;
- RefPtr<Range> m_range;
+ RefPtrWillBeMember<Range> m_range;
int findFirstGrammarDetail(const Vector<GrammarDetail>& grammarDetails, int badGrammarPhraseLocation, int startOffset, int endOffset, bool markAll) const;
bool unifiedTextCheckerEnabled() const;
@@ -98,7 +101,7 @@ private:
void checkTextOfParagraph(TextCheckerClient&, const String&, TextCheckingTypeMask, Vector<TextCheckingResult>&);
-bool unifiedTextCheckerEnabled(const Frame*);
+bool unifiedTextCheckerEnabled(const LocalFrame*);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextGranularity.h b/chromium/third_party/WebKit/Source/core/editing/TextGranularity.h
index 4aea8d8e97e..d61f252bc83 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextGranularity.h
+++ b/chromium/third_party/WebKit/Source/core/editing/TextGranularity.h
@@ -29,7 +29,7 @@
namespace WebCore {
// FIXME: This really should be broken up into more than one concept.
-// Frame doesn't need the 3 boundaries in this enum.
+// LocalFrame doesn't need the 3 boundaries in this enum.
enum TextGranularity {
CharacterGranularity,
WordGranularity,
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.cpp
index 918bf755cb8..5302dd31f76 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.cpp
@@ -31,7 +31,7 @@
#include "core/dom/Element.h"
#include "core/dom/Node.h"
#include "core/editing/FrameSelection.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
@@ -40,7 +40,7 @@ TextInsertionBaseCommand::TextInsertionBaseCommand(Document& document)
{
}
-void TextInsertionBaseCommand::applyTextInsertionCommand(Frame* frame, PassRefPtr<TextInsertionBaseCommand> command, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection)
+void TextInsertionBaseCommand::applyTextInsertionCommand(LocalFrame* frame, PassRefPtrWillBeRawPtr<TextInsertionBaseCommand> command, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection)
{
bool changeSelection = selectionForInsertion != endingSelection;
if (changeSelection) {
@@ -63,7 +63,7 @@ String dispatchBeforeTextInsertedEvent(const String& text, const VisibleSelectio
if (Node* startNode = selectionForInsertion.start().containerNode()) {
if (startNode->rootEditableElement()) {
// Send BeforeTextInsertedEvent. The event handler will update text if necessary.
- RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
+ RefPtrWillBeRawPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
startNode->rootEditableElement()->dispatchEvent(evt, IGNORE_EXCEPTION);
newText = evt->text();
}
@@ -77,7 +77,7 @@ bool canAppendNewLineFeedToSelection(const VisibleSelection& selection)
if (!node)
return false;
- RefPtr<BeforeTextInsertedEvent> event = BeforeTextInsertedEvent::create(String("\n"));
+ RefPtrWillBeRawPtr<BeforeTextInsertedEvent> event = BeforeTextInsertedEvent::create(String("\n"));
node->dispatchEvent(event, IGNORE_EXCEPTION);
return event->text().length();
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.h b/chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.h
index 6f2f3555938..4a9bd49f39a 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/TextInsertionBaseCommand.h
@@ -40,7 +40,7 @@ public:
protected:
explicit TextInsertionBaseCommand(Document&);
- static void applyTextInsertionCommand(Frame*, PassRefPtr<TextInsertionBaseCommand>, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection);
+ static void applyTextInsertionCommand(LocalFrame*, PassRefPtrWillBeRawPtr<TextInsertionBaseCommand>, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection);
};
String dispatchBeforeTextInsertedEvent(const String& text, const VisibleSelection& selectionForInsertion, bool insertionIsForUpdatingComposition);
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextIterator.cpp b/chromium/third_party/WebKit/Source/core/editing/TextIterator.cpp
index 5fbb4e3f4b1..b1c9e137282 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextIterator.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/TextIterator.cpp
@@ -27,8 +27,8 @@
#include "config.h"
#include "core/editing/TextIterator.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/shadow/ShadowRoot.h"
@@ -43,6 +43,7 @@
#include "core/rendering/RenderTableRow.h"
#include "core/rendering/RenderTextControl.h"
#include "core/rendering/RenderTextFragment.h"
+#include "platform/fonts/Character.h"
#include "platform/fonts/Font.h"
#include "platform/text/TextBoundaries.h"
#include "platform/text/TextBreakIteratorInternalICU.h"
@@ -51,9 +52,9 @@
#include "wtf/text/StringBuilder.h"
#include "wtf/unicode/CharacterNames.h"
#include <unicode/usearch.h>
+#include <unicode/utf16.h>
using namespace WTF::Unicode;
-using namespace std;
namespace WebCore {
@@ -156,7 +157,7 @@ unsigned BitStack::size() const
// --------
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
static unsigned depthCrossingShadowBoundaries(Node* node)
{
@@ -174,7 +175,7 @@ static Node* nextInPreOrderCrossingShadowBoundaries(Node* rangeEndContainer, int
if (!rangeEndContainer)
return 0;
if (rangeEndOffset >= 0 && !rangeEndContainer->offsetInCharacters()) {
- if (Node* next = rangeEndContainer->childNode(rangeEndOffset))
+ if (Node* next = rangeEndContainer->traverseToChildAt(rangeEndOffset))
return next;
}
for (Node* node = rangeEndContainer; node; node = node->parentOrShadowHostNode()) {
@@ -239,16 +240,21 @@ static void setUpFullyClippedStack(BitStack& stack, Node* node)
// --------
TextIterator::TextIterator(const Range* range, TextIteratorBehaviorFlags behavior)
- : m_shadowDepth(0)
- , m_startContainer(0)
+ : m_startContainer(nullptr)
, m_startOffset(0)
- , m_endContainer(0)
+ , m_endContainer(nullptr)
, m_endOffset(0)
- , m_positionNode(0)
+ , m_positionNode(nullptr)
, m_textLength(0)
+ , m_needsAnotherNewline(false)
+ , m_textBox(0)
, m_remainingTextBox(0)
, m_firstLetterText(0)
+ , m_lastTextNode(nullptr)
+ , m_lastTextNodeEndedWithCollapsedSpace(false)
+ , m_lastCharacter(0)
, m_sortedTextBoxesPosition(0)
+ , m_hasEmitted(false)
, m_emitsCharactersBetweenAllVisiblePositions(behavior & TextIteratorEmitsCharactersBetweenAllVisiblePositions)
, m_entersTextControls(behavior & TextIteratorEntersTextControls)
, m_emitsOriginalText(behavior & TextIteratorEmitsOriginalText)
@@ -258,50 +264,91 @@ TextIterator::TextIterator(const Range* range, TextIteratorBehaviorFlags behavio
, m_shouldStop(false)
, m_emitsImageAltText(behavior & TextIteratorEmitsImageAltText)
, m_entersAuthorShadowRoots(behavior & TextIteratorEntersAuthorShadowRoots)
+ , m_emitsObjectReplacementCharacter(behavior & TextIteratorEmitsObjectReplacementCharacter)
{
- if (!range)
- return;
+ if (range)
+ initialize(range->startPosition(), range->endPosition());
+}
+
+TextIterator::TextIterator(const Position& start, const Position& end, TextIteratorBehaviorFlags behavior)
+ : m_startContainer(nullptr)
+ , m_startOffset(0)
+ , m_endContainer(nullptr)
+ , m_endOffset(0)
+ , m_positionNode(nullptr)
+ , m_textLength(0)
+ , m_needsAnotherNewline(false)
+ , m_textBox(0)
+ , m_remainingTextBox(0)
+ , m_firstLetterText(0)
+ , m_lastTextNode(nullptr)
+ , m_lastTextNodeEndedWithCollapsedSpace(false)
+ , m_lastCharacter(0)
+ , m_sortedTextBoxesPosition(0)
+ , m_hasEmitted(false)
+ , m_emitsCharactersBetweenAllVisiblePositions(behavior & TextIteratorEmitsCharactersBetweenAllVisiblePositions)
+ , m_entersTextControls(behavior & TextIteratorEntersTextControls)
+ , m_emitsOriginalText(behavior & TextIteratorEmitsOriginalText)
+ , m_handledFirstLetter(false)
+ , m_ignoresStyleVisibility(behavior & TextIteratorIgnoresStyleVisibility)
+ , m_stopsOnFormControls(behavior & TextIteratorStopsOnFormControls)
+ , m_shouldStop(false)
+ , m_emitsImageAltText(behavior & TextIteratorEmitsImageAltText)
+ , m_entersAuthorShadowRoots(behavior & TextIteratorEntersAuthorShadowRoots)
+ , m_emitsObjectReplacementCharacter(behavior & TextIteratorEmitsObjectReplacementCharacter)
+{
+ initialize(start, end);
+}
+
+void TextIterator::initialize(const Position& start, const Position& end)
+{
+ ASSERT(comparePositions(start, end) <= 0);
- // get and validate the range endpoints
- Node* startContainer = range->startContainer();
+ // Get and validate |start| and |end|.
+ Node* startContainer = start.containerNode();
if (!startContainer)
return;
- int startOffset = range->startOffset();
- Node* endContainer = range->endContainer();
- int endOffset = range->endOffset();
-
- // Callers should be handing us well-formed ranges. If we discover that this isn't
- // the case, we could consider changing this assertion to an early return.
- ASSERT(range->boundaryPointsValid());
+ int startOffset = start.computeOffsetInContainerNode();
+ Node* endContainer = end.containerNode();
+ if (!endContainer)
+ return;
+ int endOffset = end.computeOffsetInContainerNode();
- // remember range - this does not change
+ // Remember the range - this does not change.
m_startContainer = startContainer;
m_startOffset = startOffset;
m_endContainer = endContainer;
m_endOffset = endOffset;
- // set up the current node for processing
- m_node = range->firstNode();
+ // Figure out the initial value of m_shadowDepth: the depth of startContainer's tree scope from
+ // the common ancestor tree scope.
+ const TreeScope* commonAncestorTreeScope = startContainer->treeScope().commonAncestorTreeScope(endContainer->treeScope());
+ ASSERT(commonAncestorTreeScope);
+ m_shadowDepth = 0;
+ for (const TreeScope* treeScope = &startContainer->treeScope(); treeScope != commonAncestorTreeScope; treeScope = treeScope->parentTreeScope())
+ ++m_shadowDepth;
+
+ // Set up the current node for processing.
+ if (startContainer->offsetInCharacters())
+ m_node = startContainer;
+ else if (Node* child = startContainer->traverseToChildAt(startOffset))
+ m_node = child;
+ else if (!startOffset)
+ m_node = startContainer;
+ else
+ m_node = NodeTraversal::nextSkippingChildren(*startContainer);
+
if (!m_node)
return;
+
setUpFullyClippedStack(m_fullyClippedStack, m_node);
m_offset = m_node == m_startContainer ? m_startOffset : 0;
m_iterationProgress = HandledNone;
- // calculate first out of bounds node
+ // Calculate first out of bounds node.
m_pastEndNode = nextInPreOrderCrossingShadowBoundaries(endContainer, endOffset);
- // initialize node processing state
- m_needsAnotherNewline = false;
- m_textBox = 0;
-
- // initialize record of previous node processing
- m_hasEmitted = false;
- m_lastTextNode = 0;
- m_lastTextNodeEndedWithCollapsedSpace = false;
- m_lastCharacter = 0;
-
- // identify the first run
+ // Identify the first run.
advance();
}
@@ -315,7 +362,7 @@ void TextIterator::advance()
return;
// reset the run information
- m_positionNode = 0;
+ m_positionNode = nullptr;
m_textLength = 0;
// handle remembered node that needed a newline after the text node's newline
@@ -326,7 +373,7 @@ void TextIterator::advance()
// break begins.
// FIXME: It would be cleaner if we emitted two newlines during the last
// iteration, instead of using m_needsAnotherNewline.
- Node* baseNode = m_node->lastChild() ? m_node->lastChild() : m_node;
+ Node* baseNode = m_node->lastChild() ? m_node->lastChild() : m_node.get();
emitCharacter('\n', baseNode->parentNode(), baseNode, 1, 1);
m_needsAnotherNewline = false;
return;
@@ -355,7 +402,7 @@ void TextIterator::advance()
// precedes the element
if (m_node == m_endContainer && !m_endOffset) {
representNodeOffsetZero();
- m_node = 0;
+ m_node = nullptr;
return;
}
@@ -403,11 +450,11 @@ void TextIterator::advance()
if (renderer->isText() && m_node->nodeType() == Node::TEXT_NODE) { // FIXME: What about CDATA_SECTION_NODE?
handledNode = handleTextNode();
} else if (renderer && (renderer->isImage() || renderer->isWidget()
- || (renderer->node() && renderer->node()->isElementNode()
- && (toElement(renderer->node())->isFormControlElement()
- || toElement(renderer->node())->hasTagName(legendTag)
- || toElement(renderer->node())->hasTagName(meterTag)
- || toElement(renderer->node())->hasTagName(progressTag))))) {
+ || (m_node && m_node->isElementNode()
+ && (toElement(m_node)->isFormControlElement()
+ || isHTMLLegendElement(toElement(*m_node))
+ || isHTMLMeterElement(toElement(*m_node))
+ || isHTMLProgressElement(toElement(*m_node)))))) {
handledNode = handleReplacedElement();
} else {
handledNode = handleNonTextNode();
@@ -570,7 +617,7 @@ bool TextIterator::handleTextNode()
return false;
int strLength = str.length();
int end = (m_node == m_endContainer) ? m_endOffset : INT_MAX;
- int runEnd = min(strLength, end);
+ int runEnd = std::min(strLength, end);
if (runStart >= runEnd)
return true;
@@ -623,13 +670,13 @@ void TextIterator::handleTextBox()
unsigned end = (m_node == m_endContainer) ? static_cast<unsigned>(m_endOffset) : INT_MAX;
while (m_textBox) {
unsigned textBoxStart = m_textBox->start();
- unsigned runStart = max(textBoxStart, start);
+ unsigned runStart = std::max(textBoxStart, start);
// Check for collapsed space at the start of this run.
InlineTextBox* firstTextBox = renderer->containsReversedText() ? (m_sortedTextBoxes.isEmpty() ? 0 : m_sortedTextBoxes[0]) : renderer->firstTextBox();
bool needSpace = m_lastTextNodeEndedWithCollapsedSpace
|| (m_textBox == firstTextBox && textBoxStart == runStart && runStart > 0);
- if (needSpace && !isCollapsibleWhitespace(m_lastCharacter) && m_lastCharacter) {
+ if (needSpace && !renderer->style()->isCollapsibleWhiteSpace(m_lastCharacter) && m_lastCharacter) {
if (m_lastTextNode == m_node && runStart > 0 && str[runStart - 1] == ' ') {
unsigned spaceRunStart = runStart - 1;
while (spaceRunStart > 0 && str[spaceRunStart - 1] == ' ')
@@ -641,7 +688,7 @@ void TextIterator::handleTextBox()
return;
}
unsigned textBoxEnd = textBoxStart + m_textBox->len();
- unsigned runEnd = min(textBoxEnd, end);
+ unsigned runEnd = std::min(textBoxEnd, end);
// Determine what the next text box will be, but don't advance yet
InlineTextBox* nextTextBox = 0;
@@ -697,13 +744,13 @@ void TextIterator::handleTextBox()
}
}
-static inline RenderText* firstRenderTextInFirstLetter(RenderObject* firstLetter)
+static inline RenderText* firstRenderTextInFirstLetter(RenderBoxModelObject* firstLetter)
{
if (!firstLetter)
return 0;
// FIXME: Should this check descendent objects?
- for (RenderObject* current = firstLetter->firstChild(); current; current = current->nextSibling()) {
+ for (RenderObject* current = firstLetter->slowFirstChild(); current; current = current->nextSibling()) {
if (current->isText())
return toRenderText(current);
}
@@ -713,7 +760,7 @@ static inline RenderText* firstRenderTextInFirstLetter(RenderObject* firstLetter
void TextIterator::handleTextNodeFirstLetter(RenderTextFragment* renderer)
{
if (renderer->firstLetter()) {
- RenderObject* r = renderer->firstLetter();
+ RenderBoxModelObject* r = renderer->firstLetter();
if (r->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility)
return;
if (RenderText* firstLetter = firstRenderTextInFirstLetter(r)) {
@@ -736,6 +783,11 @@ bool TextIterator::handleReplacedElement()
if (renderer->style()->visibility() != VISIBLE && !m_ignoresStyleVisibility)
return false;
+ if (m_emitsObjectReplacementCharacter) {
+ emitCharacter(objectReplacementCharacter, m_node->parentNode(), m_node, 0, 1);
+ return true;
+ }
+
if (m_lastTextNodeEndedWithCollapsedSpace) {
emitCharacter(' ', m_lastTextNode->parentNode(), m_lastTextNode, 1, 1);
return false;
@@ -807,9 +859,9 @@ static bool shouldEmitNewlineForNode(Node* node, bool emitsOriginalText)
{
RenderObject* renderer = node->renderer();
- if (renderer ? !renderer->isBR() : !node->hasTagName(brTag))
+ if (renderer ? !renderer->isBR() : !isHTMLBRElement(node))
return false;
- return emitsOriginalText || !(node->isInShadowTree() && node->shadowHost()->hasTagName(inputTag));
+ return emitsOriginalText || !(node->isInShadowTree() && isHTMLInputElement(*node->shadowHost()));
}
static bool shouldEmitNewlinesBeforeAndAfterNode(Node& node)
@@ -974,7 +1026,7 @@ bool TextIterator::shouldRepresentNodeOffsetZero()
// Additionally, if the range we are iterating over contains huge sections of unrendered content,
// we would create VisiblePositions on every call to this function without this check.
if (!m_node->renderer() || m_node->renderer()->style()->visibility() != VISIBLE
- || (m_node->renderer()->isRenderBlockFlow() && !toRenderBlock(m_node->renderer())->height() && !m_node->hasTagName(bodyTag)))
+ || (m_node->renderer()->isRenderBlockFlow() && !toRenderBlock(m_node->renderer())->height() && !isHTMLBodyElement(*m_node)))
return false;
// The startPos.isNotNull() check is needed because the start could be before the body,
@@ -1035,7 +1087,7 @@ void TextIterator::exitNode()
// Emit with a position *inside* m_node, after m_node's contents, in
// case it is a block, because the run should start where the
// emitted character is positioned visually.
- Node* baseNode = m_node->lastChild() ? m_node->lastChild() : m_node;
+ Node* baseNode = m_node->lastChild() ? m_node->lastChild() : m_node.get();
// FIXME: This shouldn't require the m_lastTextNode to be true, but we can't change that without making
// the logic in _web_attributedStringFromRange match. We'll get that for free when we switch to use
// TextIterator in _web_attributedStringFromRange.
@@ -1094,7 +1146,7 @@ void TextIterator::emitText(Node* textNode, RenderObject* renderObject, int text
ASSERT(textStartOffset <= textEndOffset);
m_positionNode = textNode;
- m_positionOffsetBaseNode = 0;
+ m_positionOffsetBaseNode = nullptr;
m_positionStartOffset = textStartOffset;
m_positionEndOffset = textEndOffset;
m_singleCharacterBuffer = 0;
@@ -1110,7 +1162,7 @@ void TextIterator::emitText(Node* textNode, int textStartOffset, int textEndOffs
emitText(textNode, m_node->renderer(), textStartOffset, textEndOffset);
}
-PassRefPtr<Range> TextIterator::range() const
+PassRefPtrWillBeRawPtr<Range> TextIterator::range() const
{
// use the current run information, if we have it
if (m_positionNode) {
@@ -1118,7 +1170,7 @@ PassRefPtr<Range> TextIterator::range() const
int index = m_positionOffsetBaseNode->nodeIndex();
m_positionStartOffset += index;
m_positionEndOffset += index;
- m_positionOffsetBaseNode = 0;
+ m_positionOffsetBaseNode = nullptr;
}
return Range::create(m_positionNode->document(), m_positionNode, m_positionStartOffset, m_positionNode, m_positionEndOffset);
}
@@ -1127,12 +1179,12 @@ PassRefPtr<Range> TextIterator::range() const
if (m_endContainer)
return Range::create(m_endContainer->document(), m_endContainer, m_endOffset, m_endContainer, m_endOffset);
- return 0;
+ return nullptr;
}
Node* TextIterator::node() const
{
- RefPtr<Range> textRange = range();
+ RefPtrWillBeRawPtr<Range> textRange = range();
if (!textRange)
return 0;
@@ -1142,26 +1194,26 @@ Node* TextIterator::node() const
if (node->offsetInCharacters())
return node;
- return node->childNode(textRange->startOffset());
+ return node->traverseToChildAt(textRange->startOffset());
}
// --------
SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r, TextIteratorBehaviorFlags behavior)
- : m_node(0)
+ : m_node(nullptr)
, m_offset(0)
, m_handledNode(false)
, m_handledChildren(false)
- , m_startNode(0)
+ , m_startNode(nullptr)
, m_startOffset(0)
- , m_endNode(0)
+ , m_endNode(nullptr)
, m_endOffset(0)
- , m_positionNode(0)
+ , m_positionNode(nullptr)
, m_positionStartOffset(0)
, m_positionEndOffset(0)
, m_textOffset(0)
, m_textLength(0)
- , m_lastTextNode(0)
+ , m_lastTextNode(nullptr)
, m_lastCharacter(0)
, m_singleCharacterBuffer(0)
, m_havePassedStartNode(false)
@@ -1182,15 +1234,19 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
int startOffset = r->startOffset();
int endOffset = r->endOffset();
- if (!startNode->offsetInCharacters()) {
- if (startOffset >= 0 && startOffset < static_cast<int>(startNode->childNodeCount())) {
- startNode = startNode->childNode(startOffset);
+ if (!startNode->offsetInCharacters() && startOffset >= 0) {
+ // traverseToChildAt() will return 0 if the offset is out of range. We rely on this behavior
+ // instead of calling countChildren() to avoid traversing the children twice.
+ if (Node* childAtOffset = startNode->traverseToChildAt(startOffset)) {
+ startNode = childAtOffset;
startOffset = 0;
}
}
- if (!endNode->offsetInCharacters()) {
- if (endOffset > 0 && endOffset <= static_cast<int>(endNode->childNodeCount())) {
- endNode = endNode->childNode(endOffset - 1);
+ if (!endNode->offsetInCharacters() && endOffset > 0) {
+ // traverseToChildAt() will return 0 if the offset is out of range. We rely on this behavior
+ // instead of calling countChildren() to avoid traversing the children twice.
+ if (Node* childAtOffset = endNode->traverseToChildAt(endOffset - 1)) {
+ endNode = childAtOffset;
endOffset = lastOffsetInNode(endNode);
}
}
@@ -1211,7 +1267,7 @@ SimplifiedBackwardsTextIterator::SimplifiedBackwardsTextIterator(const Range* r,
m_positionNode = endNode;
#endif
- m_lastTextNode = 0;
+ m_lastTextNode = nullptr;
m_lastCharacter = '\n';
m_havePassedStartNode = false;
@@ -1231,7 +1287,7 @@ void SimplifiedBackwardsTextIterator::advance()
return;
}
- m_positionNode = 0;
+ m_positionNode = nullptr;
m_textLength = 0;
while (m_node && !m_havePassedStartNode) {
@@ -1252,7 +1308,7 @@ void SimplifiedBackwardsTextIterator::advance()
return;
}
- if (!m_handledChildren && m_node->hasChildNodes()) {
+ if (!m_handledChildren && m_node->hasChildren()) {
m_node = m_node->lastChild();
pushFullyClippedState(m_fullyClippedStack, m_node);
} else {
@@ -1287,7 +1343,7 @@ void SimplifiedBackwardsTextIterator::advance()
if (advanceRespectingRange(m_node->previousSibling()))
pushFullyClippedState(m_fullyClippedStack, m_node);
else
- m_node = 0;
+ m_node = nullptr;
}
// For the purpose of word boundary detection,
@@ -1361,7 +1417,12 @@ RenderText* SimplifiedBackwardsTextIterator::handleFirstLetter(int& startOffset,
m_shouldHandleFirstLetter = false;
offsetInNode = 0;
- return firstRenderTextInFirstLetter(fragment->firstLetter());
+ RenderText* firstLetterRenderer = firstRenderTextInFirstLetter(fragment->firstLetter());
+
+ m_offset = firstLetterRenderer->caretMaxOffset();
+ m_offset += collapsedSpaceLength(firstLetterRenderer, m_offset);
+
+ return firstLetterRenderer;
}
bool SimplifiedBackwardsTextIterator::handleReplacedElement()
@@ -1419,7 +1480,7 @@ bool SimplifiedBackwardsTextIterator::advanceRespectingRange(Node* next)
return true;
}
-PassRefPtr<Range> SimplifiedBackwardsTextIterator::range() const
+PassRefPtrWillBeRawPtr<Range> SimplifiedBackwardsTextIterator::range() const
{
if (m_positionNode)
return Range::create(m_positionNode->document(), m_positionNode, m_positionStartOffset, m_positionNode, m_positionEndOffset);
@@ -1429,19 +1490,33 @@ PassRefPtr<Range> SimplifiedBackwardsTextIterator::range() const
// --------
-CharacterIterator::CharacterIterator(const Range* r, TextIteratorBehaviorFlags behavior)
+CharacterIterator::CharacterIterator(const Range* range, TextIteratorBehaviorFlags behavior)
+ : m_offset(0)
+ , m_runOffset(0)
+ , m_atBreak(true)
+ , m_textIterator(range, behavior)
+{
+ initialize();
+}
+
+CharacterIterator::CharacterIterator(const Position& start, const Position& end, TextIteratorBehaviorFlags behavior)
: m_offset(0)
, m_runOffset(0)
, m_atBreak(true)
- , m_textIterator(r, behavior)
+ , m_textIterator(start, end, behavior)
+{
+ initialize();
+}
+
+void CharacterIterator::initialize()
{
while (!atEnd() && !m_textIterator.length())
m_textIterator.advance();
}
-PassRefPtr<Range> CharacterIterator::range() const
+PassRefPtrWillBeRawPtr<Range> CharacterIterator::range() const
{
- RefPtr<Range> r = m_textIterator.range();
+ RefPtrWillBeRawPtr<Range> r = m_textIterator.range();
if (!m_textIterator.atEnd()) {
if (m_textIterator.length() <= 1) {
ASSERT(!m_runOffset);
@@ -1501,31 +1576,16 @@ void CharacterIterator::advance(int count)
m_runOffset = 0;
}
-String CharacterIterator::string(int numChars)
-{
- StringBuilder result;
- result.reserveCapacity(numChars);
- while (numChars > 0 && !atEnd()) {
- int runSize = min(numChars, length());
- m_textIterator.appendTextToStringBuilder(result, m_runOffset, runSize);
- numChars -= runSize;
- advance(runSize);
- }
- return result.toString();
-}
-
-static PassRefPtr<Range> characterSubrange(CharacterIterator& it, int offset, int length)
+static void calculateCharacterSubrange(CharacterIterator& it, int offset, int length, Position& startPosition, Position& endPosition)
{
it.advance(offset);
- RefPtr<Range> start = it.range();
+ RefPtrWillBeRawPtr<Range> start = it.range();
+ startPosition = start->startPosition();
if (length > 1)
it.advance(length - 1);
- RefPtr<Range> end = it.range();
-
- return Range::create(start->startContainer()->document(),
- start->startContainer(), start->startOffset(),
- end->endContainer(), end->endOffset());
+ RefPtrWillBeRawPtr<Range> end = it.range();
+ endPosition = end->endPosition();
}
BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range, TextIteratorBehaviorFlags behavior)
@@ -1538,9 +1598,9 @@ BackwardsCharacterIterator::BackwardsCharacterIterator(const Range* range, TextI
m_textIterator.advance();
}
-PassRefPtr<Range> BackwardsCharacterIterator::range() const
+PassRefPtrWillBeRawPtr<Range> BackwardsCharacterIterator::range() const
{
- RefPtr<Range> r = m_textIterator.range();
+ RefPtrWillBeRawPtr<Range> r = m_textIterator.range();
if (!m_textIterator.atEnd()) {
if (m_textIterator.length() <= 1) {
ASSERT(!m_runOffset);
@@ -1731,7 +1791,7 @@ inline SearchBuffer::SearchBuffer(const String& target, FindOptions options)
foldQuoteMarksAndSoftHyphens(m_target.data(), m_target.size());
size_t targetLength = m_target.size();
- m_buffer.reserveInitialCapacity(max(targetLength * 8, minimumSearchBufferSize));
+ m_buffer.reserveInitialCapacity(std::max(targetLength * 8, minimumSearchBufferSize));
m_overlap = m_buffer.capacity() / 4;
if ((m_options & AtWordStarts) && targetLength) {
@@ -1789,12 +1849,12 @@ inline void SearchBuffer::append(const CharType* characters, size_t length)
m_atBreak = false;
} else if (m_buffer.size() == m_buffer.capacity()) {
memcpy(m_buffer.data(), m_buffer.data() + m_buffer.size() - m_overlap, m_overlap * sizeof(UChar));
- m_prefixLength -= min(m_prefixLength, m_buffer.size() - m_overlap);
+ m_prefixLength -= std::min(m_prefixLength, m_buffer.size() - m_overlap);
m_buffer.shrink(m_overlap);
}
size_t oldLength = m_buffer.size();
- size_t usableLength = min(m_buffer.capacity() - oldLength, length);
+ size_t usableLength = std::min(m_buffer.capacity() - oldLength, length);
ASSERT(usableLength);
m_buffer.resize(oldLength + usableLength);
UChar* destination = m_buffer.data() + oldLength;
@@ -1824,7 +1884,7 @@ inline void SearchBuffer::prependContext(const UChar* characters, size_t length)
wordBoundaryContextStart = startOfLastWordBoundaryContext(characters, wordBoundaryContextStart);
}
- size_t usableLength = min(m_buffer.capacity() - m_prefixLength, length - wordBoundaryContextStart);
+ size_t usableLength = std::min(m_buffer.capacity() - m_prefixLength, length - wordBoundaryContextStart);
m_buffer.prepend(characters + length - usableLength, usableLength);
m_prefixLength += usableLength;
@@ -1902,7 +1962,7 @@ inline bool SearchBuffer::isWordStartMatch(size_t start, size_t length) const
// Chinese and Japanese lack word boundary marks, and there is no clear agreement on what constitutes
// a word, so treat the position before any CJK character as a word start.
- if (Font::isCJKIdeographOrSymbol(firstCharacter))
+ if (Character::isCJKIdeographOrSymbol(firstCharacter))
return true;
size_t wordBreakSearchStart = start + length;
@@ -1951,10 +2011,10 @@ nextMatch:
int wordBoundaryContextStart = matchStart;
U16_BACK_1(m_buffer.data(), 0, wordBoundaryContextStart);
wordBoundaryContextStart = startOfLastWordBoundaryContext(m_buffer.data(), wordBoundaryContextStart);
- overlap = min(size - 1, max(overlap, size - wordBoundaryContextStart));
+ overlap = std::min(size - 1, std::max(overlap, size - wordBoundaryContextStart));
}
memcpy(m_buffer.data(), m_buffer.data() + size - overlap, overlap * sizeof(UChar));
- m_prefixLength -= min(m_prefixLength, size - overlap);
+ m_prefixLength -= std::min(m_prefixLength, size - overlap);
m_buffer.shrink(overlap);
return 0;
}
@@ -1971,7 +2031,7 @@ nextMatch:
size_t newSize = size - (matchStart + 1);
memmove(m_buffer.data(), m_buffer.data() + matchStart + 1, newSize * sizeof(UChar));
- m_prefixLength -= min<size_t>(m_prefixLength, matchStart + 1);
+ m_prefixLength -= std::min<size_t>(m_prefixLength, matchStart + 1);
m_buffer.shrink(newSize);
start = size - matchStart;
@@ -1983,16 +2043,22 @@ nextMatch:
int TextIterator::rangeLength(const Range* r, bool forSelectionPreservation)
{
int length = 0;
- for (TextIterator it(r, forSelectionPreservation ? TextIteratorEmitsCharactersBetweenAllVisiblePositions : TextIteratorDefaultBehavior); !it.atEnd(); it.advance())
+ TextIteratorBehaviorFlags behaviorFlags = TextIteratorEmitsObjectReplacementCharacter;
+ if (forSelectionPreservation)
+ behaviorFlags |= TextIteratorEmitsCharactersBetweenAllVisiblePositions;
+ for (TextIterator it(r, behaviorFlags); !it.atEnd(); it.advance())
length += it.length();
return length;
}
-PassRefPtr<Range> TextIterator::subrange(Range* entireRange, int characterOffset, int characterCount)
+PassRefPtrWillBeRawPtr<Range> TextIterator::subrange(Range* entireRange, int characterOffset, int characterCount)
{
CharacterIterator entireRangeIterator(entireRange);
- return characterSubrange(entireRangeIterator, characterOffset, characterCount);
+ Position start;
+ Position end;
+ calculateCharacterSubrange(entireRangeIterator, characterOffset, characterCount, start, end);
+ return Range::create(entireRange->ownerDocument(), start, end);
}
// --------
@@ -2017,23 +2083,44 @@ String plainText(const Range* r, TextIteratorBehaviorFlags behavior)
return builder.toString();
}
-static PassRefPtr<Range> collapsedToBoundary(const Range* range, bool forward)
+static PassRefPtrWillBeRawPtr<Range> collapsedToBoundary(const Range* range, bool forward)
{
- RefPtr<Range> result = range->cloneRange(ASSERT_NO_EXCEPTION);
- result->collapse(!forward, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<Range> result = range->cloneRange();
+ result->collapse(!forward);
return result.release();
}
-static size_t findPlainText(CharacterIterator& it, const String& target, FindOptions options, size_t& matchStart)
+// Check if there's any unpaird surrogate code point.
+// Non-character code points are not checked.
+static bool isValidUTF16(const String& s)
+{
+ if (s.is8Bit())
+ return true;
+ const UChar* ustr = s.characters16();
+ size_t length = s.length();
+ size_t position = 0;
+ while (position < length) {
+ UChar32 character;
+ U16_NEXT(ustr, position, length, character);
+ if (U_IS_SURROGATE(character))
+ return false;
+ }
+ return true;
+}
+
+static size_t findPlainTextInternal(CharacterIterator& it, const String& target, FindOptions options, size_t& matchStart)
{
matchStart = 0;
size_t matchLength = 0;
+ if (!isValidUTF16(target))
+ return 0;
+
SearchBuffer buffer(target, options);
if (buffer.needsMoreContext()) {
- RefPtr<Range> startRange = it.range();
- RefPtr<Range> beforeStartRange = startRange->ownerDocument().createRange();
+ RefPtrWillBeRawPtr<Range> startRange = it.range();
+ RefPtrWillBeRawPtr<Range> beforeStartRange = startRange->ownerDocument().createRange();
beforeStartRange->setEnd(startRange->startContainer(), startRange->startOffset(), IGNORE_EXCEPTION);
for (SimplifiedBackwardsTextIterator backwardsIterator(beforeStartRange.get()); !backwardsIterator.atEnd(); backwardsIterator.advance()) {
Vector<UChar, 1024> characters;
@@ -2070,7 +2157,9 @@ tryAgain:
return matchLength;
}
-PassRefPtr<Range> findPlainText(const Range* range, const String& target, FindOptions options)
+static const TextIteratorBehaviorFlags iteratorFlagsForFindPlainText = TextIteratorEntersTextControls | TextIteratorEntersAuthorShadowRoots;
+
+PassRefPtrWillBeRawPtr<Range> findPlainText(const Range* range, const String& target, FindOptions options)
{
// CharacterIterator requires renderers to be up-to-date
range->ownerDocument().updateLayout();
@@ -2079,15 +2168,46 @@ PassRefPtr<Range> findPlainText(const Range* range, const String& target, FindOp
size_t matchStart;
size_t matchLength;
{
- CharacterIterator findIterator(range, TextIteratorEntersTextControls | TextIteratorEntersAuthorShadowRoots);
- matchLength = findPlainText(findIterator, target, options, matchStart);
+ CharacterIterator findIterator(range, iteratorFlagsForFindPlainText);
+ matchLength = findPlainTextInternal(findIterator, target, options, matchStart);
if (!matchLength)
return collapsedToBoundary(range, !(options & Backwards));
}
// Then, find the document position of the start and the end of the text.
- CharacterIterator computeRangeIterator(range, TextIteratorEntersTextControls | TextIteratorEntersAuthorShadowRoots);
- return characterSubrange(computeRangeIterator, matchStart, matchLength);
+ CharacterIterator computeRangeIterator(range, iteratorFlagsForFindPlainText);
+ Position resultStart;
+ Position resultEnd;
+ calculateCharacterSubrange(computeRangeIterator, matchStart, matchLength, resultStart, resultEnd);
+ return Range::create(range->ownerDocument(), resultStart, resultEnd);
+}
+
+void findPlainText(const Position& inputStart, const Position& inputEnd, const String& target, FindOptions options, Position& resultStart, Position& resultEnd)
+{
+ resultStart.clear();
+ resultEnd.clear();
+ // CharacterIterator requires renderers to be up-to-date.
+ if (!inputStart.inDocument())
+ return;
+ ASSERT(inputStart.document() == inputEnd.document());
+ inputStart.document()->updateLayout();
+
+ // FIXME: Reduce the code duplication with above (but how?).
+ size_t matchStart;
+ size_t matchLength;
+ {
+ CharacterIterator findIterator(inputStart, inputEnd, iteratorFlagsForFindPlainText);
+ matchLength = findPlainTextInternal(findIterator, target, options, matchStart);
+ if (!matchLength) {
+ const Position& collapseTo = options & Backwards ? inputStart : inputEnd;
+ resultStart = collapseTo;
+ resultEnd = collapseTo;
+ return;
+ }
+ }
+
+ CharacterIterator computeRangeIterator(inputStart, inputEnd, iteratorFlagsForFindPlainText);
+ calculateCharacterSubrange(computeRangeIterator, matchStart, matchLength, resultStart, resultEnd);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextIterator.h b/chromium/third_party/WebKit/Source/core/editing/TextIterator.h
index fbcd9f53e81..08a91ed3c9c 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextIterator.h
+++ b/chromium/third_party/WebKit/Source/core/editing/TextIterator.h
@@ -28,6 +28,7 @@
#include "core/dom/Range.h"
#include "core/editing/FindOptions.h"
+#include "platform/heap/Handle.h"
#include "wtf/Vector.h"
namespace WebCore {
@@ -44,25 +45,14 @@ enum TextIteratorBehavior {
TextIteratorEmitsOriginalText = 1 << 3,
TextIteratorStopsOnFormControls = 1 << 4,
TextIteratorEmitsImageAltText = 1 << 5,
- TextIteratorEntersAuthorShadowRoots = 1 << 6
+ TextIteratorEntersAuthorShadowRoots = 1 << 6,
+ TextIteratorEmitsObjectReplacementCharacter = 1 << 7
};
typedef unsigned TextIteratorBehaviorFlags;
-// FIXME: Can't really answer this question correctly without knowing the white-space mode.
-// FIXME: Move this somewhere else in the editing directory. It doesn't belong here.
-inline bool isCollapsibleWhitespace(UChar c)
-{
- switch (c) {
- case ' ':
- case '\n':
- return true;
- default:
- return false;
- }
-}
-
String plainText(const Range*, TextIteratorBehaviorFlags = TextIteratorDefaultBehavior);
-PassRefPtr<Range> findPlainText(const Range*, const String&, FindOptions);
+PassRefPtrWillBeRawPtr<Range> findPlainText(const Range*, const String&, FindOptions);
+void findPlainText(const Position& inputStart, const Position& inputEnd, const String&, FindOptions, Position& resultStart, Position& resultEnd);
class BitStack {
public:
@@ -85,8 +75,11 @@ private:
// chunks so as to optimize for performance of the iteration.
class TextIterator {
+ STACK_ALLOCATED();
public:
explicit TextIterator(const Range*, TextIteratorBehaviorFlags = TextIteratorDefaultBehavior);
+ // [start, end] indicates the document range that the iteration should take place within (both ends inclusive).
+ TextIterator(const Position& start, const Position& end, TextIteratorBehaviorFlags = TextIteratorDefaultBehavior);
~TextIterator();
bool atEnd() const { return !m_positionNode || m_shouldStop; }
@@ -113,11 +106,16 @@ public:
}
}
- PassRefPtr<Range> range() const;
+ PassRefPtrWillBeRawPtr<Range> range() const;
Node* node() const;
- static int rangeLength(const Range*, bool spacesForReplacedElements = false);
- static PassRefPtr<Range> subrange(Range* entireRange, int characterOffset, int characterCount);
+ // Computes the length of the given range using a text iterator. The default
+ // iteration behavior is to always emit object replacement characters for
+ // replaced elements. When |forSelectionPreservation| is set to true, it
+ // also emits spaces for other non-text nodes using the
+ // |TextIteratorEmitsCharactersBetweenAllVisiblePosition| mode.
+ static int rangeLength(const Range*, bool forSelectionPreservation = false);
+ static PassRefPtrWillBeRawPtr<Range> subrange(Range* entireRange, int characterOffset, int characterCount);
private:
enum IterationProgress {
@@ -128,6 +126,8 @@ private:
HandledChildren
};
+ void initialize(const Position& start, const Position& end);
+
int startOffset() const { return m_positionStartOffset; }
const String& string() const { return m_text; }
void exitNode();
@@ -146,22 +146,22 @@ private:
// Current position, not necessarily of the text being returned, but position
// as we walk through the DOM tree.
- Node* m_node;
+ RawPtrWillBeMember<Node> m_node;
int m_offset;
IterationProgress m_iterationProgress;
BitStack m_fullyClippedStack;
int m_shadowDepth;
// The range.
- Node* m_startContainer;
+ RawPtrWillBeMember<Node> m_startContainer;
int m_startOffset;
- Node* m_endContainer;
+ RawPtrWillBeMember<Node> m_endContainer;
int m_endOffset;
- Node* m_pastEndNode;
+ RawPtrWillBeMember<Node> m_pastEndNode;
// The current text and its position, in the form to be returned from the iterator.
- Node* m_positionNode;
- mutable Node* m_positionOffsetBaseNode;
+ RawPtrWillBeMember<Node> m_positionNode;
+ mutable RawPtrWillBeMember<Node> m_positionOffsetBaseNode;
mutable int m_positionStartOffset;
mutable int m_positionEndOffset;
int m_textLength;
@@ -178,7 +178,7 @@ private:
RenderText *m_firstLetterText;
// Used to do the whitespace collapsing logic.
- Node* m_lastTextNode;
+ RawPtrWillBeMember<Node> m_lastTextNode;
bool m_lastTextNodeEndedWithCollapsedSpace;
UChar m_lastCharacter;
@@ -214,12 +214,15 @@ private:
bool m_emitsImageAltText;
bool m_entersAuthorShadowRoots;
+
+ bool m_emitsObjectReplacementCharacter;
};
// Iterates through the DOM range, returning all the text, and 0-length boundaries
// at points where replaced elements break up the text flow. The text comes back in
// chunks so as to optimize for performance of the iteration.
class SimplifiedBackwardsTextIterator {
+ STACK_ALLOCATED();
public:
explicit SimplifiedBackwardsTextIterator(const Range*, TextIteratorBehaviorFlags = TextIteratorDefaultBehavior);
@@ -241,7 +244,7 @@ public:
m_textContainer.prependTo(output, m_textOffset, m_textLength);
}
- PassRefPtr<Range> range() const;
+ PassRefPtrWillBeRawPtr<Range> range() const;
private:
void exitNode();
@@ -254,21 +257,21 @@ private:
// Current position, not necessarily of the text being returned, but position
// as we walk through the DOM tree.
- Node* m_node;
+ RawPtrWillBeMember<Node> m_node;
int m_offset;
bool m_handledNode;
bool m_handledChildren;
BitStack m_fullyClippedStack;
// End of the range.
- Node* m_startNode;
+ RawPtrWillBeMember<Node> m_startNode;
int m_startOffset;
// Start of the range.
- Node* m_endNode;
+ RawPtrWillBeMember<Node> m_endNode;
int m_endOffset;
// The current text and its position, in the form to be returned from the iterator.
- Node* m_positionNode;
+ RawPtrWillBeMember<Node> m_positionNode;
int m_positionStartOffset;
int m_positionEndOffset;
@@ -277,7 +280,7 @@ private:
int m_textLength;
// Used to do the whitespace logic.
- Node* m_lastTextNode;
+ RawPtrWillBeMember<Node> m_lastTextNode;
UChar m_lastCharacter;
// Used for whitespace characters that aren't in the DOM, so we can point at them.
@@ -302,8 +305,10 @@ private:
// Builds on the text iterator, adding a character position so we can walk one
// character at a time, or faster, as needed. Useful for searching.
class CharacterIterator {
+ STACK_ALLOCATED();
public:
explicit CharacterIterator(const Range*, TextIteratorBehaviorFlags = TextIteratorDefaultBehavior);
+ CharacterIterator(const Position& start, const Position& end, TextIteratorBehaviorFlags = TextIteratorDefaultBehavior);
void advance(int numCharacters);
@@ -316,12 +321,12 @@ public:
template<typename BufferType>
void appendTextTo(BufferType& output) { m_textIterator.appendTextTo(output, m_runOffset); }
- String string(int numChars);
-
int characterOffset() const { return m_offset; }
- PassRefPtr<Range> range() const;
+ PassRefPtrWillBeRawPtr<Range> range() const;
private:
+ void initialize();
+
int m_offset;
int m_runOffset;
bool m_atBreak;
@@ -330,6 +335,7 @@ private:
};
class BackwardsCharacterIterator {
+ STACK_ALLOCATED();
public:
explicit BackwardsCharacterIterator(const Range*, TextIteratorBehaviorFlags = TextIteratorDefaultBehavior);
@@ -337,7 +343,7 @@ public:
bool atEnd() const { return m_textIterator.atEnd(); }
- PassRefPtr<Range> range() const;
+ PassRefPtrWillBeRawPtr<Range> range() const;
private:
int m_offset;
@@ -350,6 +356,7 @@ private:
// Very similar to the TextIterator, except that the chunks of text returned are "well behaved",
// meaning they never end split up a word. This is useful for spellcheck or (perhaps one day) searching.
class WordAwareIterator {
+ STACK_ALLOCATED();
public:
explicit WordAwareIterator(const Range*);
~WordAwareIterator();
@@ -361,14 +368,11 @@ public:
UChar characterAt(unsigned index) const;
int length() const;
- // Range of the text we're currently returning
- PassRefPtr<Range> range() const { return m_range; }
-
private:
Vector<UChar> m_buffer;
// Did we have to look ahead in the textIterator to confirm the current chunk?
bool m_didLookAhead;
- RefPtr<Range> m_range;
+ RefPtrWillBeMember<Range> m_range;
TextIterator m_textIterator;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp b/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp
index 0692414f080..63a7f403f98 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/TextIteratorTest.cpp
@@ -62,11 +62,14 @@ protected:
HTMLDocument& document() const;
Vector<String> iterate(TextIteratorBehavior = TextIteratorDefaultBehavior);
+ Vector<String> iteratePartial(const Position& start, const Position& end, TextIteratorBehavior = TextIteratorDefaultBehavior);
void setBodyInnerHTML(const char*);
- PassRefPtr<Range> getBodyRange() const;
+ PassRefPtrWillBeRawPtr<Range> getBodyRange() const;
private:
+ Vector<String> iterateWithIterator(TextIterator&);
+
OwnPtr<DummyPageHolder> m_dummyPageHolder;
HTMLDocument* m_document;
@@ -82,13 +85,24 @@ void TextIteratorTest::SetUp()
Vector<String> TextIteratorTest::iterate(TextIteratorBehavior iteratorBehavior)
{
document().view()->updateLayoutAndStyleIfNeededRecursive(); // Force renderers to be created; TextIterator needs them.
+ RefPtrWillBeRawPtr<Range> range = getBodyRange();
+ TextIterator iterator(range.get(), iteratorBehavior);
+ return iterateWithIterator(iterator);
+}
+
+Vector<String> TextIteratorTest::iteratePartial(const Position& start, const Position& end, TextIteratorBehavior iteratorBehavior)
+{
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+ TextIterator iterator(start, end, iteratorBehavior);
+ return iterateWithIterator(iterator);
+}
- RefPtr<Range> range = getBodyRange();
- TextIterator textIterator(range.get(), iteratorBehavior);
+Vector<String> TextIteratorTest::iterateWithIterator(TextIterator& iterator)
+{
Vector<String> textChunks;
- while (!textIterator.atEnd()) {
- textChunks.append(textIterator.substring(0, textIterator.length()));
- textIterator.advance();
+ while (!iterator.atEnd()) {
+ textChunks.append(iterator.substring(0, iterator.length()));
+ iterator.advance();
}
return textChunks;
}
@@ -103,9 +117,9 @@ void TextIteratorTest::setBodyInnerHTML(const char* bodyContent)
document().body()->setInnerHTML(String::fromUTF8(bodyContent), ASSERT_NO_EXCEPTION);
}
-PassRefPtr<Range> TextIteratorTest::getBodyRange() const
+PassRefPtrWillBeRawPtr<Range> TextIteratorTest::getBodyRange() const
{
- RefPtr<Range> range(Range::create(document()));
+ RefPtrWillBeRawPtr<Range> range(Range::create(document()));
range->selectNode(document().body());
return range.release();
}
@@ -117,9 +131,9 @@ Vector<String> createVectorString(const char* const* rawStrings, size_t size)
return result;
}
-PassRefPtr<ShadowRoot> createShadowRootForElementWithIDAndSetInnerHTML(TreeScope& scope, const char* hostElementID, const char* shadowRootContent)
+PassRefPtrWillBeRawPtr<ShadowRoot> createShadowRootForElementWithIDAndSetInnerHTML(TreeScope& scope, const char* hostElementID, const char* shadowRootContent)
{
- RefPtr<ShadowRoot> shadowRoot = scope.getElementById(AtomicString::fromUTF8(hostElementID))->createShadowRoot(ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = scope.getElementById(AtomicString::fromUTF8(hostElementID))->createShadowRoot(ASSERT_NO_EXCEPTION);
shadowRoot->setInnerHTML(String::fromUTF8(shadowRootContent), ASSERT_NO_EXCEPTION);
return shadowRoot.release();
}
@@ -251,7 +265,7 @@ TEST_F(TextIteratorTest, NotEnteringShadowTreeWithNestedShadowTrees)
Vector<String> expectedTextChunks = createVectorString(expectedTextChunksRawString, WTF_ARRAY_LENGTH(expectedTextChunksRawString));
setBodyInnerHTML(bodyContent);
- RefPtr<ShadowRoot> shadowRoot1 = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host-in-document", shadowContent1);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot1 = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host-in-document", shadowContent1);
createShadowRootForElementWithIDAndSetInnerHTML(*shadowRoot1, "host-in-shadow", shadowContent2);
EXPECT_EQ(expectedTextChunks, iterate());
@@ -324,7 +338,7 @@ TEST_F(TextIteratorTest, EnteringShadowTreeWithNestedShadowTreesWithOption)
Vector<String> expectedTextChunks = createVectorString(expectedTextChunksRawString, WTF_ARRAY_LENGTH(expectedTextChunksRawString));
setBodyInnerHTML(bodyContent);
- RefPtr<ShadowRoot> shadowRoot1 = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host-in-document", shadowContent1);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot1 = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host-in-document", shadowContent1);
createShadowRootForElementWithIDAndSetInnerHTML(*shadowRoot1, "host-in-shadow", shadowContent2);
EXPECT_EQ(expectedTextChunks, iterate(TextIteratorEntersAuthorShadowRoots));
@@ -351,6 +365,47 @@ TEST_F(TextIteratorTest, EnteringShadowTreeWithContentInsertionPointWithOption)
EXPECT_EQ(expectedTextChunks, iterate(TextIteratorEntersAuthorShadowRoots));
}
+TEST_F(TextIteratorTest, StartingAtNodeInShadowRoot)
+{
+ static const char* bodyContent = "<div id=\"outer\">Hello, <span id=\"host\">text</span> iterator.</div>";
+ static const char* shadowContent = "<span><content>content</content> shadow</span>";
+ static const char* expectedTextChunksRawString[] = {
+ " shadow",
+ "text",
+ " iterator."
+ };
+ Vector<String> expectedTextChunks = createVectorString(expectedTextChunksRawString, WTF_ARRAY_LENGTH(expectedTextChunksRawString));
+
+ setBodyInnerHTML(bodyContent);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host", shadowContent);
+ Node* outerDiv = document().getElementById("outer");
+ Node* spanInShadow = shadowRoot->firstChild();
+ Position start(spanInShadow, Position::PositionIsBeforeChildren);
+ Position end(outerDiv, Position::PositionIsAfterChildren);
+
+ EXPECT_EQ(expectedTextChunks, iteratePartial(start, end, TextIteratorEntersAuthorShadowRoots));
+}
+
+TEST_F(TextIteratorTest, FinishingAtNodeInShadowRoot)
+{
+ static const char* bodyContent = "<div id=\"outer\">Hello, <span id=\"host\">text</span> iterator.</div>";
+ static const char* shadowContent = "<span><content>content</content> shadow</span>";
+ static const char* expectedTextChunksRawString[] = {
+ "Hello, ",
+ " shadow"
+ };
+ Vector<String> expectedTextChunks = createVectorString(expectedTextChunksRawString, WTF_ARRAY_LENGTH(expectedTextChunksRawString));
+
+ setBodyInnerHTML(bodyContent);
+ RefPtrWillBeRawPtr<ShadowRoot> shadowRoot = createShadowRootForElementWithIDAndSetInnerHTML(document(), "host", shadowContent);
+ Node* outerDiv = document().getElementById("outer");
+ Node* spanInShadow = shadowRoot->firstChild();
+ Position start(outerDiv, Position::PositionIsBeforeChildren);
+ Position end(spanInShadow, Position::PositionIsAfterChildren);
+
+ EXPECT_EQ(expectedTextChunks, iteratePartial(start, end, TextIteratorEntersAuthorShadowRoots));
+}
+
TEST_F(TextIteratorTest, FullyClipsContents)
{
static const char* bodyContent =
@@ -428,4 +483,73 @@ TEST_F(TextIteratorTest, IgnoresContainersClipDistributed)
EXPECT_EQ(expectedTextChunks, iterate(TextIteratorEntersAuthorShadowRoots));
}
+TEST_F(TextIteratorTest, FindPlainTextInvalidTarget)
+{
+ static const char* bodyContent = "<div>foo bar test</div>";
+ setBodyInnerHTML(bodyContent);
+ RefPtrWillBeRawPtr<Range> range = getBodyRange();
+
+ RefPtrWillBeRawPtr<Range> expectedRange = range->cloneRange();
+ expectedRange->collapse(false);
+
+ // A lone lead surrogate (0xDA0A) example taken from fuzz-58.
+ static const UChar invalid1[] = {
+ 0x1461u, 0x2130u, 0x129bu, 0xd711u, 0xd6feu, 0xccadu, 0x7064u,
+ 0xd6a0u, 0x4e3bu, 0x03abu, 0x17dcu, 0xb8b7u, 0xbf55u, 0xfca0u,
+ 0x07fau, 0x0427u, 0xda0au, 0
+ };
+
+ // A lone trailing surrogate (U+DC01).
+ static const UChar invalid2[] = {
+ 0x1461u, 0x2130u, 0x129bu, 0xdc01u, 0xd6feu, 0xccadu, 0
+ };
+ // A trailing surrogate followed by a lead surrogate (U+DC03 U+D901).
+ static const UChar invalid3[] = {
+ 0xd800u, 0xdc00u, 0x0061u, 0xdc03u, 0xd901u, 0xccadu, 0
+ };
+
+ static const UChar* invalidUStrings[] = { invalid1, invalid2, invalid3 };
+
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(invalidUStrings); ++i) {
+ String invalidTarget(invalidUStrings[i]);
+ RefPtrWillBeRawPtr<Range> actualRange = findPlainText(range.get(), invalidTarget, 0);
+ EXPECT_TRUE(areRangesEqual(expectedRange.get(), actualRange.get()));
+ }
+}
+
+TEST_F(TextIteratorTest, EmitsReplacementCharForInput)
+{
+ static const char* bodyContent =
+ "<div contenteditable=\"true\">"
+ "Before"
+ "<img src=\"foo.png\">"
+ "After"
+ "</div>";
+ // "Before".
+ static const UChar expectedRawString1[] = { 0x42, 0x65, 0x66, 0x6F, 0x72, 0x65, 0 };
+ // Object replacement char.
+ static const UChar expectedRawString2[] = { 0xFFFC, 0 };
+ // "After".
+ static const UChar expectedRawString3[] = { 0x41, 0x66, 0x74, 0x65, 0x72, 0 };
+ static const UChar* expectedRawStrings[] = { expectedRawString1, expectedRawString2, expectedRawString3 };
+ Vector<String> expectedTextChunks;
+ expectedTextChunks.append(expectedRawStrings, WTF_ARRAY_LENGTH(expectedRawStrings));
+
+ setBodyInnerHTML(bodyContent);
+ EXPECT_EQ(expectedTextChunks, iterate(TextIteratorEmitsObjectReplacementCharacter));
+}
+
+TEST_F(TextIteratorTest, RangeLengthWithReplacedElements)
+{
+ static const char* bodyContent =
+ "<div id=\"div\" contenteditable=\"true\">1<img src=\"foo.png\">3</div>";
+ setBodyInnerHTML(bodyContent);
+ document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+ Node* divNode = document().getElementById("div");
+ RefPtrWillBeRawPtr<Range> range = Range::create(document(), divNode, 0, divNode, 3);
+
+ EXPECT_EQ(3, TextIterator::rangeLength(range.get()));
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/editing/TypingCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/TypingCommand.cpp
index 46e1e7de7eb..c6418680b60 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TypingCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/TypingCommand.cpp
@@ -26,9 +26,10 @@
#include "config.h"
#include "core/editing/TypingCommand.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
#include "core/editing/BreakBlockquoteCommand.h"
#include "core/editing/Editor.h"
#include "core/editing/FrameSelection.h"
@@ -39,7 +40,8 @@
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLBRElement.h"
#include "core/rendering/RenderObject.h"
namespace WebCore {
@@ -92,13 +94,13 @@ TypingCommand::TypingCommand(Document& document, ETypingCommand commandType, con
void TypingCommand::deleteSelection(Document& document, Options options)
{
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
ASSERT(frame);
if (!frame->selection().isRange())
return;
- if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
+ if (RefPtrWillBeRawPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
lastTypingCommand->deleteSelection(options & SmartDelete);
return;
@@ -110,8 +112,8 @@ void TypingCommand::deleteSelection(Document& document, Options options)
void TypingCommand::deleteKeyPressed(Document& document, Options options, TextGranularity granularity)
{
if (granularity == CharacterGranularity) {
- Frame* frame = document.frame();
- if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
+ LocalFrame* frame = document.frame();
+ if (RefPtrWillBeRawPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
// If the last typing command is not Delete, open a new typing command.
// We need to group continuous delete commands alone in a single typing command.
if (lastTypingCommand->commandTypeOfOpenCommand() == DeleteKey) {
@@ -130,8 +132,8 @@ void TypingCommand::forwardDeleteKeyPressed(Document& document, Options options,
{
// FIXME: Forward delete in TextEdit appears to open and close a new typing command.
if (granularity == CharacterGranularity) {
- Frame* frame = document.frame();
- if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
+ LocalFrame* frame = document.frame();
+ if (RefPtrWillBeRawPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), frame);
lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
lastTypingCommand->forwardDeleteKeyPressed(granularity, options & KillRing);
@@ -142,7 +144,7 @@ void TypingCommand::forwardDeleteKeyPressed(Document& document, Options options,
TypingCommand::create(document, ForwardDeleteKey, "", options, granularity)->apply();
}
-void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(TypingCommand* typingCommand, Frame* frame)
+void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(TypingCommand* typingCommand, LocalFrame* frame)
{
ASSERT(frame);
VisibleSelection currentSelection = frame->selection().selection();
@@ -155,7 +157,7 @@ void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(TypingCommand
void TypingCommand::insertText(Document& document, const String& text, Options options, TextCompositionType composition)
{
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
ASSERT(frame);
if (!text.isEmpty())
@@ -167,7 +169,7 @@ void TypingCommand::insertText(Document& document, const String& text, Options o
// FIXME: We shouldn't need to take selectionForInsertion. It should be identical to FrameSelection's current selection.
void TypingCommand::insertText(Document& document, const String& text, const VisibleSelection& selectionForInsertion, Options options, TextCompositionType compositionType)
{
- RefPtr<Frame> frame = document.frame();
+ RefPtr<LocalFrame> frame = document.frame();
ASSERT(frame);
VisibleSelection currentSelection = frame->selection().selection();
@@ -177,7 +179,7 @@ void TypingCommand::insertText(Document& document, const String& text, const Vis
// Set the starting and ending selection appropriately if we are using a selection
// that is different from the current selection. In the future, we should change EditCommand
// to deal with custom selections in a general way that can be used by all of the commands.
- if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame.get())) {
+ if (RefPtrWillBeRawPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame.get())) {
if (lastTypingCommand->endingSelection() != selectionForInsertion) {
lastTypingCommand->setStartingSelection(selectionForInsertion);
lastTypingCommand->setEndingSelection(selectionForInsertion);
@@ -190,13 +192,13 @@ void TypingCommand::insertText(Document& document, const String& text, const Vis
return;
}
- RefPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, options, compositionType);
+ RefPtrWillBeRawPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, options, compositionType);
applyTextInsertionCommand(frame.get(), cmd, selectionForInsertion, currentSelection);
}
void TypingCommand::insertLineBreak(Document& document, Options options)
{
- if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document.frame())) {
+ if (RefPtrWillBeRawPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document.frame())) {
lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator);
lastTypingCommand->insertLineBreak();
return;
@@ -207,7 +209,7 @@ void TypingCommand::insertLineBreak(Document& document, Options options)
void TypingCommand::insertParagraphSeparatorInQuotedContent(Document& document)
{
- if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document.frame())) {
+ if (RefPtrWillBeRawPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document.frame())) {
lastTypingCommand->insertParagraphSeparatorInQuotedContent();
return;
}
@@ -217,7 +219,7 @@ void TypingCommand::insertParagraphSeparatorInQuotedContent(Document& document)
void TypingCommand::insertParagraphSeparator(Document& document, Options options)
{
- if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document.frame())) {
+ if (RefPtrWillBeRawPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(document.frame())) {
lastTypingCommand->setShouldRetainAutocorrectionIndicator(options & RetainAutocorrectionIndicator);
lastTypingCommand->insertParagraphSeparator();
return;
@@ -226,20 +228,20 @@ void TypingCommand::insertParagraphSeparator(Document& document, Options options
TypingCommand::create(document, InsertParagraphSeparator, "", options)->apply();
}
-PassRefPtr<TypingCommand> TypingCommand::lastTypingCommandIfStillOpenForTyping(Frame* frame)
+PassRefPtrWillBeRawPtr<TypingCommand> TypingCommand::lastTypingCommandIfStillOpenForTyping(LocalFrame* frame)
{
ASSERT(frame);
- RefPtr<CompositeEditCommand> lastEditCommand = frame->editor().lastEditCommand();
+ RefPtrWillBeRawPtr<CompositeEditCommand> lastEditCommand = frame->editor().lastEditCommand();
if (!lastEditCommand || !lastEditCommand->isTypingCommand() || !static_cast<TypingCommand*>(lastEditCommand.get())->isOpenForMoreTyping())
- return 0;
+ return nullptr;
return static_cast<TypingCommand*>(lastEditCommand.get());
}
-void TypingCommand::closeTyping(Frame* frame)
+void TypingCommand::closeTyping(LocalFrame* frame)
{
- if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame))
+ if (RefPtrWillBeRawPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame))
lastTypingCommand->closeTyping();
}
@@ -286,7 +288,7 @@ EditAction TypingCommand::editingAction() const
void TypingCommand::markMisspellingsAfterTyping(ETypingCommand commandType)
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
@@ -311,7 +313,7 @@ void TypingCommand::markMisspellingsAfterTyping(ETypingCommand commandType)
void TypingCommand::typingAddedToOpenCommand(ETypingCommand commandTypeForAddedTyping)
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
@@ -336,7 +338,7 @@ void TypingCommand::insertText(const String &text, bool selectInsertedText)
void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText)
{
- RefPtr<InsertTextCommand> command = InsertTextCommand::create(document(), text, selectInsertedText,
+ RefPtrWillBeRawPtr<InsertTextCommand> command = InsertTextCommand::create(document(), text, selectInsertedText,
m_compositionType == TextCompositionNone ? InsertTextCommand::RebalanceLeadingAndTrailingWhitespaces : InsertTextCommand::RebalanceAllWhitespaces);
applyCommandToComposite(command, endingSelection());
@@ -381,10 +383,13 @@ bool TypingCommand::makeEditableRootEmpty()
if (!root || !root->firstChild())
return false;
- if (root->firstChild() == root->lastChild() && root->firstElementChild() && root->firstElementChild()->hasTagName(brTag)) {
- // If there is a single child and it could be a placeholder, leave it alone.
- if (root->renderer() && root->renderer()->isRenderBlockFlow())
- return false;
+ if (root->firstChild() == root->lastChild()) {
+ Element* firstElementChild = ElementTraversal::firstWithin(*root);
+ if (isHTMLBRElement(firstElementChild)) {
+ // If there is a single child and it could be a placeholder, leave it alone.
+ if (root->renderer() && root->renderer()->isRenderBlockFlow())
+ return false;
+ }
}
while (Node* child = root->firstChild())
@@ -398,7 +403,7 @@ bool TypingCommand::makeEditableRootEmpty()
void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
@@ -420,29 +425,29 @@ void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
m_smartDelete = false;
- FrameSelection selection;
- selection.setSelection(endingSelection());
- selection.modify(FrameSelection::AlterationExtend, DirectionBackward, granularity);
- if (killRing && selection.isCaret() && granularity != CharacterGranularity)
- selection.modify(FrameSelection::AlterationExtend, DirectionBackward, CharacterGranularity);
+ OwnPtrWillBeRawPtr<FrameSelection> selection = FrameSelection::create();
+ selection->setSelection(endingSelection());
+ selection->modify(FrameSelection::AlterationExtend, DirectionBackward, granularity);
+ if (killRing && selection->isCaret() && granularity != CharacterGranularity)
+ selection->modify(FrameSelection::AlterationExtend, DirectionBackward, CharacterGranularity);
- if (endingSelection().visibleStart().previous(CannotCrossEditingBoundary).isNull()) {
+ VisiblePosition visibleStart(endingSelection().visibleStart());
+ if (visibleStart.previous(CannotCrossEditingBoundary).isNull()) {
// When the caret is at the start of the editable area in an empty list item, break out of the list item.
if (breakOutOfEmptyListItem()) {
typingAddedToOpenCommand(DeleteKey);
return;
}
// When there are no visible positions in the editing root, delete its entire contents.
- if (endingSelection().visibleStart().next(CannotCrossEditingBoundary).isNull() && makeEditableRootEmpty()) {
+ if (visibleStart.next(CannotCrossEditingBoundary).isNull() && makeEditableRootEmpty()) {
typingAddedToOpenCommand(DeleteKey);
return;
}
}
- VisiblePosition visibleStart(endingSelection().visibleStart());
// If we have a caret selection at the beginning of a cell, we have nothing to do.
Node* enclosingTableCell = enclosingNodeOfType(visibleStart.deepEquivalent(), &isTableCell);
- if (enclosingTableCell && visibleStart == firstPositionInNode(enclosingTableCell))
+ if (enclosingTableCell && visibleStart == VisiblePosition(firstPositionInNode(enclosingTableCell)))
return;
// If the caret is at the start of a paragraph after a table, move content into the last table cell.
@@ -451,7 +456,7 @@ void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
if (isLastPositionBeforeTable(visibleStart))
return;
// Extend the selection backward into the last cell, then deletion will handle the move.
- selection.modify(FrameSelection::AlterationExtend, DirectionBackward, granularity);
+ selection->modify(FrameSelection::AlterationExtend, DirectionBackward, granularity);
// If the caret is just after a table, select the table and don't delete anything.
} else if (Node* table = isFirstPositionAfterTable(visibleStart)) {
setEndingSelection(VisibleSelection(positionBeforeNode(table), endingSelection().start(), DOWNSTREAM, endingSelection().isDirectional()));
@@ -459,7 +464,7 @@ void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
return;
}
- selectionToDelete = selection.selection();
+ selectionToDelete = selection->selection();
if (granularity == CharacterGranularity && selectionToDelete.end().containerNode() == selectionToDelete.start().containerNode()
&& selectionToDelete.end().computeOffsetInContainerNode() - selectionToDelete.start().computeOffsetInContainerNode() > 1) {
@@ -502,7 +507,7 @@ void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool killRing)
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
@@ -522,16 +527,16 @@ void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool ki
// Handle delete at beginning-of-block case.
// Do nothing in the case that the caret is at the start of a
// root editable element or at the start of a document.
- FrameSelection selection;
- selection.setSelection(endingSelection());
- selection.modify(FrameSelection::AlterationExtend, DirectionForward, granularity);
- if (killRing && selection.isCaret() && granularity != CharacterGranularity)
- selection.modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity);
+ OwnPtrWillBeRawPtr<FrameSelection> selection = FrameSelection::create();
+ selection->setSelection(endingSelection());
+ selection->modify(FrameSelection::AlterationExtend, DirectionForward, granularity);
+ if (killRing && selection->isCaret() && granularity != CharacterGranularity)
+ selection->modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity);
Position downstreamEnd = endingSelection().end().downstream();
VisiblePosition visibleEnd = endingSelection().visibleEnd();
Node* enclosingTableCell = enclosingNodeOfType(visibleEnd.deepEquivalent(), &isTableCell);
- if (enclosingTableCell && visibleEnd == lastPositionInNode(enclosingTableCell))
+ if (enclosingTableCell && visibleEnd == VisiblePosition(lastPositionInNode(enclosingTableCell)))
return;
if (visibleEnd == endOfParagraph(visibleEnd))
downstreamEnd = visibleEnd.next(CannotCrossEditingBoundary).deepEquivalent().downstream();
@@ -543,10 +548,10 @@ void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool ki
}
// deleting to end of paragraph when at end of paragraph needs to merge the next paragraph (if any)
- if (granularity == ParagraphBoundary && selection.selection().isCaret() && isEndOfParagraph(selection.selection().visibleEnd()))
- selection.modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity);
+ if (granularity == ParagraphBoundary && selection->selection().isCaret() && isEndOfParagraph(selection->selection().visibleEnd()))
+ selection->modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity);
- selectionToDelete = selection.selection();
+ selectionToDelete = selection->selection();
if (!startingSelection().isRange() || selectionToDelete.base() != startingSelection().start())
selectionAfterUndo = selectionToDelete;
else {
diff --git a/chromium/third_party/WebKit/Source/core/editing/TypingCommand.h b/chromium/third_party/WebKit/Source/core/editing/TypingCommand.h
index 05032abe59b..47929e074d9 100644
--- a/chromium/third_party/WebKit/Source/core/editing/TypingCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/TypingCommand.h
@@ -30,7 +30,7 @@
namespace WebCore {
-class TypingCommand : public TextInsertionBaseCommand {
+class TypingCommand FINAL : public TextInsertionBaseCommand {
public:
enum ETypingCommand {
DeleteSelection,
@@ -65,7 +65,7 @@ public:
static void insertLineBreak(Document&, Options);
static void insertParagraphSeparator(Document&, Options);
static void insertParagraphSeparatorInQuotedContent(Document&);
- static void closeTyping(Frame*);
+ static void closeTyping(LocalFrame*);
void insertText(const String &text, bool selectInsertedText);
void insertTextRunWithoutNewlines(const String &text, bool selectInsertedText);
@@ -78,39 +78,33 @@ public:
void setCompositionType(TextCompositionType type) { m_compositionType = type; }
private:
- static PassRefPtr<TypingCommand> create(Document& document, ETypingCommand command, const String& text = "", Options options = 0, TextGranularity granularity = CharacterGranularity)
+ static PassRefPtrWillBeRawPtr<TypingCommand> create(Document& document, ETypingCommand command, const String& text = "", Options options = 0, TextGranularity granularity = CharacterGranularity)
{
- return adoptRef(new TypingCommand(document, command, text, options, granularity, TextCompositionNone));
+ return adoptRefWillBeNoop(new TypingCommand(document, command, text, options, granularity, TextCompositionNone));
}
- static PassRefPtr<TypingCommand> create(Document& document, ETypingCommand command, const String& text, Options options, TextCompositionType compositionType)
+ static PassRefPtrWillBeRawPtr<TypingCommand> create(Document& document, ETypingCommand command, const String& text, Options options, TextCompositionType compositionType)
{
- return adoptRef(new TypingCommand(document, command, text, options, CharacterGranularity, compositionType));
+ return adoptRefWillBeNoop(new TypingCommand(document, command, text, options, CharacterGranularity, compositionType));
}
TypingCommand(Document&, ETypingCommand, const String& text, Options, TextGranularity, TextCompositionType);
- bool smartDelete() const { return m_smartDelete; }
void setSmartDelete(bool smartDelete) { m_smartDelete = smartDelete; }
bool isOpenForMoreTyping() const { return m_openForMoreTyping; }
void closeTyping() { m_openForMoreTyping = false; }
- static PassRefPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(Frame*);
+ static PassRefPtrWillBeRawPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(LocalFrame*);
- virtual void doApply();
- virtual EditAction editingAction() const;
- virtual bool isTypingCommand() const;
- virtual bool preservesTypingStyle() const { return m_preservesTypingStyle; }
- virtual bool shouldRetainAutocorrectionIndicator() const
- {
- ASSERT(isTopLevelCommand());
- return m_shouldRetainAutocorrectionIndicator;
- }
- virtual void setShouldRetainAutocorrectionIndicator(bool retain) { m_shouldRetainAutocorrectionIndicator = retain; }
- virtual bool shouldStopCaretBlinking() const { return true; }
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE;
+ virtual bool isTypingCommand() const OVERRIDE;
+ virtual bool preservesTypingStyle() const OVERRIDE { return m_preservesTypingStyle; }
+ virtual void setShouldRetainAutocorrectionIndicator(bool retain) OVERRIDE { m_shouldRetainAutocorrectionIndicator = retain; }
+ virtual bool shouldStopCaretBlinking() const OVERRIDE { return true; }
void setShouldPreventSpellChecking(bool prevent) { m_shouldPreventSpellChecking = prevent; }
- static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
+ static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, LocalFrame*);
void updatePreservesTypingStyle(ETypingCommand);
void markMisspellingsAfterTyping(ETypingCommand);
diff --git a/chromium/third_party/WebKit/Source/core/editing/UndoStack.cpp b/chromium/third_party/WebKit/Source/core/editing/UndoStack.cpp
index cdcd9ae4014..a5b6c2e519d 100644
--- a/chromium/third_party/WebKit/Source/core/editing/UndoStack.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/UndoStack.cpp
@@ -25,9 +25,10 @@
*/
#include "config.h"
-#include "UndoStack.h"
+#include "core/editing/UndoStack.h"
#include "core/dom/ContainerNode.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/editing/UndoStep.h"
#include "wtf/TemporaryChange.h"
@@ -44,16 +45,14 @@ UndoStack::UndoStack()
{
}
-UndoStack::~UndoStack()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(UndoStack)
-PassOwnPtr<UndoStack> UndoStack::create()
+PassOwnPtrWillBeRawPtr<UndoStack> UndoStack::create()
{
- return adoptPtr(new UndoStack());
+ return adoptPtrWillBeNoop(new UndoStack());
}
-void UndoStack::registerUndoStep(PassRefPtr<UndoStep> step)
+void UndoStack::registerUndoStep(PassRefPtrWillBeRawPtr<UndoStep> step)
{
if (m_undoStack.size() == maximumUndoStackDepth)
m_undoStack.removeFirst(); // drop oldest item off the far end
@@ -62,19 +61,19 @@ void UndoStack::registerUndoStep(PassRefPtr<UndoStep> step)
m_undoStack.append(step);
}
-void UndoStack::registerRedoStep(PassRefPtr<UndoStep> step)
+void UndoStack::registerRedoStep(PassRefPtrWillBeRawPtr<UndoStep> step)
{
m_redoStack.append(step);
}
-void UndoStack::didUnloadFrame(const Frame& frame)
+void UndoStack::didUnloadFrame(const LocalFrame& frame)
{
NoEventDispatchAssertion assertNoEventDispatch;
filterOutUndoSteps(m_undoStack, frame);
filterOutUndoSteps(m_redoStack, frame);
}
-void UndoStack::filterOutUndoSteps(UndoStepStack& stack, const Frame& frame)
+void UndoStack::filterOutUndoSteps(UndoStepStack& stack, const LocalFrame& frame)
{
UndoStepStack newStack;
while (!stack.isEmpty()) {
@@ -100,7 +99,7 @@ void UndoStack::undo()
{
if (canUndo()) {
UndoStepStack::iterator back = --m_undoStack.end();
- RefPtr<UndoStep> step(*back);
+ RefPtrWillBeRawPtr<UndoStep> step(back->get());
m_undoStack.remove(back);
step->unapply();
// unapply will call us back to push this command onto the redo stack.
@@ -111,7 +110,7 @@ void UndoStack::redo()
{
if (canRedo()) {
UndoStepStack::iterator back = --m_redoStack.end();
- RefPtr<UndoStep> step(*back);
+ RefPtrWillBeRawPtr<UndoStep> step(back->get());
m_redoStack.remove(back);
ASSERT(!m_inRedo);
@@ -121,4 +120,10 @@ void UndoStack::redo()
}
}
+void UndoStack::trace(Visitor* visitor)
+{
+ visitor->trace(m_undoStack);
+ visitor->trace(m_redoStack);
+}
+
} // namesace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/UndoStack.h b/chromium/third_party/WebKit/Source/core/editing/UndoStack.h
index 507e8996fb8..212e98af8e6 100644
--- a/chromium/third_party/WebKit/Source/core/editing/UndoStack.h
+++ b/chromium/third_party/WebKit/Source/core/editing/UndoStack.h
@@ -31,35 +31,38 @@
#ifndef UndoStack_h
#define UndoStack_h
+#include "platform/heap/Handle.h"
#include "wtf/Deque.h"
#include "wtf/Forward.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
class UndoStep;
-class UndoStack {
+class UndoStack FINAL : public NoBaseWillBeGarbageCollected<UndoStack> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(UndoStack)
public:
- static PassOwnPtr<UndoStack> create();
+ static PassOwnPtrWillBeRawPtr<UndoStack> create();
- ~UndoStack();
-
- void registerUndoStep(PassRefPtr<UndoStep>);
- void registerRedoStep(PassRefPtr<UndoStep>);
- void didUnloadFrame(const Frame&);
+ void registerUndoStep(PassRefPtrWillBeRawPtr<UndoStep>);
+ void registerRedoStep(PassRefPtrWillBeRawPtr<UndoStep>);
+ void didUnloadFrame(const LocalFrame&);
bool canUndo() const;
bool canRedo() const;
void undo();
void redo();
+ void trace(Visitor*);
+
private:
UndoStack();
- bool m_inRedo;
+ typedef WillBeHeapDeque<RefPtrWillBeMember<UndoStep> > UndoStepStack;
- typedef Deque<RefPtr<UndoStep> > UndoStepStack;
- void filterOutUndoSteps(UndoStepStack&, const Frame&);
+ void filterOutUndoSteps(UndoStepStack&, const LocalFrame&);
+
+ bool m_inRedo;
UndoStepStack m_undoStack;
UndoStepStack m_redoStack;
};
diff --git a/chromium/third_party/WebKit/Source/core/editing/UndoStep.h b/chromium/third_party/WebKit/Source/core/editing/UndoStep.h
index 3084946773b..1502e975349 100644
--- a/chromium/third_party/WebKit/Source/core/editing/UndoStep.h
+++ b/chromium/third_party/WebKit/Source/core/editing/UndoStep.h
@@ -32,17 +32,19 @@
#define UndoStep_h
#include "core/editing/EditAction.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
-class UndoStep : public RefCounted<UndoStep> {
+class UndoStep : public RefCountedWillBeGarbageCollectedFinalized<UndoStep> {
public:
virtual ~UndoStep() { }
+ virtual void trace(Visitor*) { }
- virtual bool belongsTo(const Frame&) const = 0;
+ virtual bool belongsTo(const LocalFrame&) const = 0;
virtual void unapply() = 0;
virtual void reapply() = 0;
virtual EditAction editingAction() const = 0;
diff --git a/chromium/third_party/WebKit/Source/core/editing/UnlinkCommand.h b/chromium/third_party/WebKit/Source/core/editing/UnlinkCommand.h
index d6b8d17bd28..692b6deba44 100644
--- a/chromium/third_party/WebKit/Source/core/editing/UnlinkCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/UnlinkCommand.h
@@ -30,18 +30,18 @@
namespace WebCore {
-class UnlinkCommand : public CompositeEditCommand {
+class UnlinkCommand FINAL : public CompositeEditCommand {
public:
- static PassRefPtr<UnlinkCommand> create(Document& document)
+ static PassRefPtrWillBeRawPtr<UnlinkCommand> create(Document& document)
{
- return adoptRef(new UnlinkCommand(document));
+ return adoptRefWillBeNoop(new UnlinkCommand(document));
}
private:
explicit UnlinkCommand(Document&);
- virtual void doApply();
- virtual EditAction editingAction() const { return EditActionUnlink; }
+ virtual void doApply() OVERRIDE;
+ virtual EditAction editingAction() const OVERRIDE { return EditActionUnlink; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/VisiblePosition.cpp b/chromium/third_party/WebKit/Source/core/editing/VisiblePosition.cpp
index b158125184c..7c380bf591d 100644
--- a/chromium/third_party/WebKit/Source/core/editing/VisiblePosition.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/VisiblePosition.cpp
@@ -27,15 +27,14 @@
#include "config.h"
#include "core/editing/VisiblePosition.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Range.h"
#include "core/dom/Text.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
#include "core/html/HTMLElement.h"
-#include "core/html/HTMLHtmlElement.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RootInlineBox.h"
#include "platform/geometry/FloatQuad.h"
@@ -136,7 +135,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
if (!box)
return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
- RenderObject* renderer = box->renderer();
+ RenderObject* renderer = &box->renderer();
while (true) {
if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretRightmostOffset())
@@ -146,7 +145,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
box = box->prevLeafChild();
if (!box)
return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = box->caretRightmostOffset();
continue;
}
@@ -177,7 +176,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
// Reposition at the other logical position corresponding to our edge's visual position and go for another round.
box = prevBox;
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = prevBox->caretRightmostOffset();
continue;
}
@@ -190,9 +189,9 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
if (box->direction() == primaryDirection) {
if (!prevBox) {
InlineBox* logicalStart = 0;
- if (primaryDirection == LTR ? box->root()->getLogicalStartBoxWithNode(logicalStart) : box->root()->getLogicalEndBoxWithNode(logicalStart)) {
+ if (primaryDirection == LTR ? box->root().getLogicalStartBoxWithNode(logicalStart) : box->root().getLogicalEndBoxWithNode(logicalStart)) {
box = logicalStart;
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
}
break;
@@ -211,19 +210,19 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
break;
box = prevBox;
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = box->caretRightmostOffset();
if (box->direction() == primaryDirection)
break;
continue;
}
- while (prevBox && !prevBox->renderer()->node())
+ while (prevBox && !prevBox->renderer().node())
prevBox = prevBox->prevLeafChild();
if (prevBox) {
box = prevBox;
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = box->caretRightmostOffset();
if (box->bidiLevel() > level) {
do {
@@ -253,7 +252,7 @@ Position VisiblePosition::leftVisuallyDistinctCandidate() const
break;
level = box->bidiLevel();
}
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
}
break;
@@ -301,7 +300,7 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
if (!box)
return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
- RenderObject* renderer = box->renderer();
+ RenderObject* renderer = &box->renderer();
while (true) {
if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretLeftmostOffset())
@@ -311,7 +310,7 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
box = box->nextLeafChild();
if (!box)
return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = box->caretLeftmostOffset();
continue;
}
@@ -342,7 +341,7 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
// Reposition at the other logical position corresponding to our edge's visual position and go for another round.
box = nextBox;
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = nextBox->caretLeftmostOffset();
continue;
}
@@ -355,9 +354,9 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
if (box->direction() == primaryDirection) {
if (!nextBox) {
InlineBox* logicalEnd = 0;
- if (primaryDirection == LTR ? box->root()->getLogicalEndBoxWithNode(logicalEnd) : box->root()->getLogicalStartBoxWithNode(logicalEnd)) {
+ if (primaryDirection == LTR ? box->root().getLogicalEndBoxWithNode(logicalEnd) : box->root().getLogicalStartBoxWithNode(logicalEnd)) {
box = logicalEnd;
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
}
break;
@@ -378,19 +377,19 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
// For example, abc 123 ^ CBA or 123 ^ CBA abc
box = nextBox;
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = box->caretLeftmostOffset();
if (box->direction() == primaryDirection)
break;
continue;
}
- while (nextBox && !nextBox->renderer()->node())
+ while (nextBox && !nextBox->renderer().node())
nextBox = nextBox->nextLeafChild();
if (nextBox) {
box = nextBox;
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = box->caretLeftmostOffset();
if (box->bidiLevel() > level) {
@@ -421,7 +420,7 @@ Position VisiblePosition::rightVisuallyDistinctCandidate() const
break;
level = box->bidiLevel();
}
- renderer = box->renderer();
+ renderer = &box->renderer();
offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
}
break;
@@ -476,7 +475,7 @@ VisiblePosition VisiblePosition::honorEditingBoundaryAtOrBefore(const VisiblePos
return VisiblePosition();
// Return the last position before pos that is in the same editable region as this position
- return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
+ return lastEditableVisiblePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
}
VisiblePosition VisiblePosition::honorEditingBoundaryAtOrAfter(const VisiblePosition &pos) const
@@ -502,7 +501,7 @@ VisiblePosition VisiblePosition::honorEditingBoundaryAtOrAfter(const VisiblePosi
return VisiblePosition();
// Return the next position after pos that is in the same editable region as this position
- return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
+ return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
}
VisiblePosition VisiblePosition::skipToStartOfEditingBoundary(const VisiblePosition &pos) const
@@ -519,10 +518,10 @@ VisiblePosition VisiblePosition::skipToStartOfEditingBoundary(const VisiblePosit
// If |pos| has an editable root, skip to the start
if (highestRootOfPos)
- return previousVisuallyDistinctCandidate(Position(highestRootOfPos, Position::PositionIsBeforeAnchor).parentAnchoredEquivalent());
+ return VisiblePosition(previousVisuallyDistinctCandidate(Position(highestRootOfPos, Position::PositionIsBeforeAnchor).parentAnchoredEquivalent()));
// That must mean that |pos| is not editable. Return the last position before pos that is in the same editable region as this position
- return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
+ return lastEditableVisiblePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
}
VisiblePosition VisiblePosition::skipToEndOfEditingBoundary(const VisiblePosition &pos) const
@@ -539,10 +538,10 @@ VisiblePosition VisiblePosition::skipToEndOfEditingBoundary(const VisiblePositio
// If |pos| has an editable root, skip to the end
if (highestRootOfPos)
- return Position(highestRootOfPos, Position::PositionIsAfterAnchor).parentAnchoredEquivalent();
+ return VisiblePosition(Position(highestRootOfPos, Position::PositionIsAfterAnchor).parentAnchoredEquivalent());
// That must mean that |pos| is not editable. Return the next position after pos that is in the same editable region as this position
- return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
+ return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
}
static Position canonicalizeCandidate(const Position& candidate)
@@ -592,14 +591,14 @@ Position VisiblePosition::canonicalPosition(const Position& passedPosition)
// The new position must be in the same editable element. Enforce that first.
// Unless the descent is from a non-editable html element to an editable body.
- if (node && isHTMLHtmlElement(node) && !node->rendererIsEditable() && node->document().body() && node->document().body()->rendererIsEditable())
+ if (isHTMLHtmlElement(node) && !node->rendererIsEditable() && node->document().body() && node->document().body()->rendererIsEditable())
return next.isNotNull() ? next : prev;
Node* editingRoot = editableRootForPosition(position);
// If the html element is editable, descending into its body will look like a descent
// from non-editable to editable content since rootEditableElement() always stops at the body.
- if ((editingRoot && isHTMLHtmlElement(editingRoot)) || position.deprecatedNode()->isDocumentNode())
+ if (isHTMLHtmlElement(editingRoot) || position.deprecatedNode()->isDocumentNode())
return next.isNotNull() ? next : prev;
bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot;
@@ -665,7 +664,7 @@ LayoutRect VisiblePosition::localCaretRect(RenderObject*& renderer) const
getInlineBoxAndOffset(inlineBox, caretOffset);
if (inlineBox)
- renderer = inlineBox->renderer();
+ renderer = &inlineBox->renderer();
return renderer->localCaretRect(inlineBox, caretOffset);
}
@@ -721,15 +720,15 @@ void VisiblePosition::showTreeForThis() const
#endif
-PassRefPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition &end)
+PassRefPtrWillBeRawPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition &end)
{
if (start.isNull() || end.isNull())
- return 0;
+ return nullptr;
Position s = start.deepEquivalent().parentAnchoredEquivalent();
Position e = end.deepEquivalent().parentAnchoredEquivalent();
if (s.isNull() || e.isNull())
- return 0;
+ return nullptr;
return Range::create(s.containerNode()->document(), s.containerNode(), s.offsetInContainerNode(), e.containerNode(), e.offsetInContainerNode());
}
@@ -739,11 +738,6 @@ VisiblePosition startVisiblePosition(const Range *r, EAffinity affinity)
return VisiblePosition(r->startPosition(), affinity);
}
-VisiblePosition endVisiblePosition(const Range *r, EAffinity affinity)
-{
- return VisiblePosition(r->endPosition(), affinity);
-}
-
bool setStart(Range *r, const VisiblePosition &visiblePosition)
{
if (!r)
@@ -796,6 +790,11 @@ bool isLastVisiblePositionInNode(const VisiblePosition &visiblePosition, const N
return next.isNull() || !next.deepEquivalent().deprecatedNode()->isDescendantOf(node);
}
+void VisiblePosition::trace(Visitor* visitor)
+{
+ visitor->trace(m_deepPosition);
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/editing/VisiblePosition.h b/chromium/third_party/WebKit/Source/core/editing/VisiblePosition.h
index f48245089f7..aa76c05b045 100644
--- a/chromium/third_party/WebKit/Source/core/editing/VisiblePosition.h
+++ b/chromium/third_party/WebKit/Source/core/editing/VisiblePosition.h
@@ -28,6 +28,7 @@
#include "core/dom/Position.h"
#include "core/editing/EditingBoundary.h"
+#include "platform/heap/Handle.h"
#include "platform/text/TextDirection.h"
namespace WebCore {
@@ -48,12 +49,13 @@ namespace WebCore {
class InlineBox;
class Node;
-class VisiblePosition {
+class VisiblePosition FINAL {
+ DISALLOW_ALLOCATION();
public:
// NOTE: UPSTREAM affinity will be used only if pos is at end of a wrapped line,
// otherwise it will be converted to DOWNSTREAM
VisiblePosition() : m_affinity(VP_DEFAULT_AFFINITY) { }
- VisiblePosition(const Position&, EAffinity = VP_DEFAULT_AFFINITY);
+ explicit VisiblePosition(const Position&, EAffinity = VP_DEFAULT_AFFINITY);
explicit VisiblePosition(const PositionWithAffinity&);
void clear() { m_deepPosition.clear(); }
@@ -90,11 +92,6 @@ public:
m_deepPosition.getInlineBoxAndOffset(m_affinity, inlineBox, caretOffset);
}
- void getInlineBoxAndOffset(TextDirection primaryDirection, InlineBox*& inlineBox, int& caretOffset) const
- {
- m_deepPosition.getInlineBoxAndOffset(m_affinity, primaryDirection, inlineBox, caretOffset);
- }
-
// Rect is local to the returned renderer
LayoutRect localCaretRect(RenderObject*&) const;
// Bounds of (possibly transformed) caret in absolute coords
@@ -103,6 +100,8 @@ public:
// FIXME: navigation with transforms should be smarter.
int lineDirectionPointForBlockDirectionNavigation() const;
+ void trace(Visitor*);
+
#ifndef NDEBUG
void debugPosition(const char* msg = "") const;
void formatForDebugger(char* buffer, unsigned length) const;
@@ -131,11 +130,10 @@ inline bool operator!=(const VisiblePosition& a, const VisiblePosition& b)
return !(a == b);
}
-PassRefPtr<Range> makeRange(const VisiblePosition&, const VisiblePosition&);
+PassRefPtrWillBeRawPtr<Range> makeRange(const VisiblePosition&, const VisiblePosition&);
bool setStart(Range*, const VisiblePosition&);
bool setEnd(Range*, const VisiblePosition&);
VisiblePosition startVisiblePosition(const Range*, EAffinity);
-VisiblePosition endVisiblePosition(const Range*, EAffinity);
Element* enclosingBlockFlowElement(const VisiblePosition&);
diff --git a/chromium/third_party/WebKit/Source/core/editing/VisibleSelection.cpp b/chromium/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
index 418c1030e0a..09e2c8acb7a 100644
--- a/chromium/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/VisibleSelection.cpp
@@ -48,6 +48,7 @@ namespace WebCore {
VisibleSelection::VisibleSelection()
: m_affinity(DOWNSTREAM)
+ , m_changeObserver(nullptr)
, m_selectionType(NoSelection)
, m_baseIsFirst(true)
, m_isDirectional(false)
@@ -58,6 +59,7 @@ VisibleSelection::VisibleSelection(const Position& pos, EAffinity affinity, bool
: m_base(pos)
, m_extent(pos)
, m_affinity(affinity)
+ , m_changeObserver(nullptr)
, m_isDirectional(isDirectional)
{
validate();
@@ -67,6 +69,7 @@ VisibleSelection::VisibleSelection(const Position& base, const Position& extent,
: m_base(base)
, m_extent(extent)
, m_affinity(affinity)
+ , m_changeObserver(nullptr)
, m_isDirectional(isDirectional)
{
validate();
@@ -76,6 +79,7 @@ VisibleSelection::VisibleSelection(const VisiblePosition& pos, bool isDirectiona
: m_base(pos.deepEquivalent())
, m_extent(pos.deepEquivalent())
, m_affinity(pos.affinity())
+ , m_changeObserver(nullptr)
, m_isDirectional(isDirectional)
{
validate();
@@ -85,6 +89,7 @@ VisibleSelection::VisibleSelection(const VisiblePosition& base, const VisiblePos
: m_base(base.deepEquivalent())
, m_extent(extent.deepEquivalent())
, m_affinity(base.affinity())
+ , m_changeObserver(nullptr)
, m_isDirectional(isDirectional)
{
validate();
@@ -94,11 +99,48 @@ VisibleSelection::VisibleSelection(const Range* range, EAffinity affinity, bool
: m_base(range->startPosition())
, m_extent(range->endPosition())
, m_affinity(affinity)
+ , m_changeObserver(nullptr)
, m_isDirectional(isDirectional)
{
validate();
}
+VisibleSelection::VisibleSelection(const VisibleSelection& other)
+ : m_base(other.m_base)
+ , m_extent(other.m_extent)
+ , m_start(other.m_start)
+ , m_end(other.m_end)
+ , m_affinity(other.m_affinity)
+ , m_changeObserver(nullptr) // Observer is associated with only one VisibleSelection, so this should not be copied.
+ , m_selectionType(other.m_selectionType)
+ , m_baseIsFirst(other.m_baseIsFirst)
+ , m_isDirectional(other.m_isDirectional)
+{
+}
+
+VisibleSelection& VisibleSelection::operator=(const VisibleSelection& other)
+{
+ didChange();
+
+ m_base = other.m_base;
+ m_extent = other.m_extent;
+ m_start = other.m_start;
+ m_end = other.m_end;
+ m_affinity = other.m_affinity;
+ m_changeObserver = nullptr;
+ m_selectionType = other.m_selectionType;
+ m_baseIsFirst = other.m_baseIsFirst;
+ m_isDirectional = other.m_isDirectional;
+ return *this;
+}
+
+VisibleSelection::~VisibleSelection()
+{
+#if !ENABLE(OILPAN)
+ didChange();
+#endif
+}
+
VisibleSelection VisibleSelection::selectionFromContentsOfNode(Node* node)
{
ASSERT(!editingIgnoresContent(node));
@@ -107,41 +149,53 @@ VisibleSelection VisibleSelection::selectionFromContentsOfNode(Node* node)
void VisibleSelection::setBase(const Position& position)
{
+ Position oldBase = m_base;
m_base = position;
validate();
+ if (m_base != oldBase)
+ didChange();
}
void VisibleSelection::setBase(const VisiblePosition& visiblePosition)
{
+ Position oldBase = m_base;
m_base = visiblePosition.deepEquivalent();
validate();
+ if (m_base != oldBase)
+ didChange();
}
void VisibleSelection::setExtent(const Position& position)
{
+ Position oldExtent = m_extent;
m_extent = position;
validate();
+ if (m_extent != oldExtent)
+ didChange();
}
void VisibleSelection::setExtent(const VisiblePosition& visiblePosition)
{
+ Position oldExtent = m_extent;
m_extent = visiblePosition.deepEquivalent();
validate();
+ if (m_extent != oldExtent)
+ didChange();
}
-PassRefPtr<Range> VisibleSelection::firstRange() const
+PassRefPtrWillBeRawPtr<Range> VisibleSelection::firstRange() const
{
if (isNone())
- return 0;
+ return nullptr;
Position start = m_start.parentAnchoredEquivalent();
Position end = m_end.parentAnchoredEquivalent();
return Range::create(*start.document(), start, end);
}
-PassRefPtr<Range> VisibleSelection::toNormalizedRange() const
+PassRefPtrWillBeRawPtr<Range> VisibleSelection::toNormalizedRange() const
{
if (isNone())
- return 0;
+ return nullptr;
// Make sure we have an updated layout since this function is called
// in the course of running edit commands which modify the DOM.
@@ -151,7 +205,7 @@ PassRefPtr<Range> VisibleSelection::toNormalizedRange() const
// Check again, because updating layout can clear the selection.
if (isNone())
- return 0;
+ return nullptr;
Position s, e;
if (isCaret()) {
@@ -187,7 +241,7 @@ PassRefPtr<Range> VisibleSelection::toNormalizedRange() const
}
if (!s.containerNode() || !e.containerNode())
- return 0;
+ return nullptr;
// VisibleSelections are supposed to always be valid. This constructor will ASSERT
// if a valid range could not be created, which is fine for this callsite.
@@ -199,24 +253,31 @@ bool VisibleSelection::expandUsingGranularity(TextGranularity granularity)
if (isNone())
return false;
+ // FIXME: Do we need to check all of them?
+ Position oldBase = m_base;
+ Position oldExtent = m_extent;
+ Position oldStart = m_start;
+ Position oldEnd = m_end;
validate(granularity);
+ if (m_base != oldBase || m_extent != oldExtent || m_start != oldStart || m_end != oldEnd)
+ didChange();
return true;
}
-static PassRefPtr<Range> makeSearchRange(const Position& pos)
+static PassRefPtrWillBeRawPtr<Range> makeSearchRange(const Position& pos)
{
Node* n = pos.deprecatedNode();
if (!n)
- return 0;
+ return nullptr;
Document& d = n->document();
Node* de = d.documentElement();
if (!de)
- return 0;
+ return nullptr;
Node* boundary = n->enclosingBlockFlowElement();
if (!boundary)
- return 0;
+ return nullptr;
- RefPtr<Range> searchRange(Range::create(d));
+ RefPtrWillBeRawPtr<Range> searchRange(Range::create(d));
TrackExceptionState exceptionState;
Position start(pos.parentAnchoredEquivalent());
@@ -225,30 +286,29 @@ static PassRefPtr<Range> makeSearchRange(const Position& pos)
ASSERT(!exceptionState.hadException());
if (exceptionState.hadException())
- return 0;
+ return nullptr;
return searchRange.release();
}
-bool VisibleSelection::isAll(EditingBoundaryCrossingRule rule) const
-{
- return !nonBoundaryShadowTreeRootNode() && visibleStart().previous(rule).isNull() && visibleEnd().next(rule).isNull();
-}
-
void VisibleSelection::appendTrailingWhitespace()
{
- RefPtr<Range> searchRange = makeSearchRange(m_end);
+ RefPtrWillBeRawPtr<Range> searchRange = makeSearchRange(m_end);
if (!searchRange)
return;
CharacterIterator charIt(searchRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+ bool changed = false;
for (; charIt.length(); charIt.advance(1)) {
UChar c = charIt.characterAt(0);
if ((!isSpaceOrNewline(c) && c != noBreakSpace) || c == '\n')
break;
m_end = charIt.range()->endPosition();
+ changed = true;
}
+ if (changed)
+ didChange();
}
void VisibleSelection::setBaseAndExtentToDeepEquivalents()
@@ -465,6 +525,7 @@ void VisibleSelection::setWithoutValidation(const Position& base, const Position
m_end = base;
}
m_selectionType = base == extent ? CaretSelection : RangeSelection;
+ didChange();
}
static Position adjustPositionForEnd(const Position& currentPosition, Node* startContainerNode)
@@ -479,7 +540,7 @@ static Position adjustPositionForEnd(const Position& currentPosition, Node* star
return positionBeforeNode(ancestor);
}
- if (Node* lastChild = treeScope.rootNode()->lastChild())
+ if (Node* lastChild = treeScope.rootNode().lastChild())
return positionAfterNode(lastChild);
return Position();
@@ -497,7 +558,7 @@ static Position adjustPositionForStart(const Position& currentPosition, Node* en
return positionAfterNode(ancestor);
}
- if (Node* firstChild = treeScope.rootNode()->firstChild())
+ if (Node* firstChild = treeScope.rootNode().firstChild())
return positionBeforeNode(firstChild);
return Position();
@@ -543,7 +604,7 @@ void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries()
// If the start is in non-editable content that is inside the base's editable root, put it
// at the first editable position after start inside the base's editable root.
if (startRoot != baseRoot) {
- VisiblePosition first = firstEditablePositionAfterPositionInRoot(m_start, baseRoot);
+ VisiblePosition first = firstEditableVisiblePositionAfterPositionInRoot(m_start, baseRoot);
m_start = first.deepEquivalent();
if (m_start.isNull()) {
ASSERT_NOT_REACHED();
@@ -554,7 +615,7 @@ void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries()
// If the end is in non-editable content that is inside the base's root, put it
// at the last editable position before the end inside the base's root.
if (endRoot != baseRoot) {
- VisiblePosition last = lastEditablePositionBeforePositionInRoot(m_end, baseRoot);
+ VisiblePosition last = lastEditableVisiblePositionBeforePositionInRoot(m_end, baseRoot);
m_end = last.deepEquivalent();
if (m_end.isNull())
m_end = m_start;
@@ -576,7 +637,7 @@ void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries()
while (p.isNotNull() && !(lowestEditableAncestor(p.containerNode()) == baseEditableAncestor && !isEditablePosition(p))) {
Node* root = editableRootForPosition(p);
shadowAncestor = root ? root->shadowHost() : 0;
- p = isAtomicNode(p.containerNode()) ? positionInParentBeforeNode(p.containerNode()) : previousVisuallyDistinctCandidate(p);
+ p = isAtomicNode(p.containerNode()) ? positionInParentBeforeNode(*p.containerNode()) : previousVisuallyDistinctCandidate(p);
if (p.isNull() && shadowAncestor)
p = positionAfterNode(shadowAncestor);
}
@@ -605,7 +666,7 @@ void VisibleSelection::adjustSelectionToAvoidCrossingEditingBoundaries()
while (p.isNotNull() && !(lowestEditableAncestor(p.containerNode()) == baseEditableAncestor && !isEditablePosition(p))) {
Node* root = editableRootForPosition(p);
shadowAncestor = root ? root->shadowHost() : 0;
- p = isAtomicNode(p.containerNode()) ? positionInParentAfterNode(p.containerNode()) : nextVisuallyDistinctCandidate(p);
+ p = isAtomicNode(p.containerNode()) ? positionInParentAfterNode(*p.containerNode()) : nextVisuallyDistinctCandidate(p);
if (p.isNull() && shadowAncestor)
p = positionBeforeNode(shadowAncestor);
}
@@ -675,6 +736,63 @@ Node* VisibleSelection::nonBoundaryShadowTreeRootNode() const
return start().deprecatedNode() ? start().deprecatedNode()->nonBoundaryShadowTreeRootNode() : 0;
}
+VisibleSelection::ChangeObserver::ChangeObserver()
+{
+}
+
+VisibleSelection::ChangeObserver::~ChangeObserver()
+{
+}
+
+void VisibleSelection::setChangeObserver(ChangeObserver& observer)
+{
+ ASSERT(!m_changeObserver);
+ m_changeObserver = &observer;
+}
+
+void VisibleSelection::clearChangeObserver()
+{
+ ASSERT(m_changeObserver);
+ m_changeObserver = nullptr;
+}
+
+void VisibleSelection::didChange()
+{
+ if (m_changeObserver)
+ m_changeObserver->didChangeVisibleSelection();
+}
+
+void VisibleSelection::trace(Visitor* visitor)
+{
+ visitor->trace(m_base);
+ visitor->trace(m_extent);
+ visitor->trace(m_start);
+ visitor->trace(m_end);
+ visitor->trace(m_changeObserver);
+}
+
+static bool isValidPosition(const Position& position)
+{
+ if (!position.inDocument())
+ return false;
+
+ if (position.anchorType() != Position::PositionIsOffsetInAnchor)
+ return true;
+
+ if (position.offsetInContainerNode() < 0)
+ return false;
+
+ const unsigned offset = static_cast<unsigned>(position.offsetInContainerNode());
+ const unsigned nodeLength = position.anchorNode()->lengthOfContents();
+ return offset <= nodeLength;
+}
+
+void VisibleSelection::validatePositionsIfNeeded()
+{
+ if (!isValidPosition(m_base) || !isValidPosition(m_extent) || !isValidPosition(m_start) || !isValidPosition(m_end))
+ validate();
+}
+
#ifndef NDEBUG
void VisibleSelection::debugPosition() const
diff --git a/chromium/third_party/WebKit/Source/core/editing/VisibleSelection.h b/chromium/third_party/WebKit/Source/core/editing/VisibleSelection.h
index e5e9dd0a2fc..eb4f0e0d5bc 100644
--- a/chromium/third_party/WebKit/Source/core/editing/VisibleSelection.h
+++ b/chromium/third_party/WebKit/Source/core/editing/VisibleSelection.h
@@ -39,17 +39,23 @@ const EAffinity SEL_DEFAULT_AFFINITY = DOWNSTREAM;
enum SelectionDirection { DirectionForward, DirectionBackward, DirectionRight, DirectionLeft };
class VisibleSelection {
+ DISALLOW_ALLOCATION();
public:
VisibleSelection();
VisibleSelection(const Position&, EAffinity, bool isDirectional = false);
VisibleSelection(const Position&, const Position&, EAffinity = SEL_DEFAULT_AFFINITY, bool isDirectional = false);
- VisibleSelection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY, bool isDirectional = false);
+ explicit VisibleSelection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY, bool isDirectional = false);
- VisibleSelection(const VisiblePosition&, bool isDirectional = false);
+ explicit VisibleSelection(const VisiblePosition&, bool isDirectional = false);
VisibleSelection(const VisiblePosition&, const VisiblePosition&, bool isDirectional = false);
+ VisibleSelection(const VisibleSelection&);
+ VisibleSelection& operator=(const VisibleSelection&);
+
+ ~VisibleSelection();
+
static VisibleSelection selectionFromContentsOfNode(Node*);
SelectionType selectionType() const { return m_selectionType; }
@@ -83,19 +89,17 @@ public:
bool isDirectional() const { return m_isDirectional; }
void setIsDirectional(bool isDirectional) { m_isDirectional = isDirectional; }
- bool isAll(EditingBoundaryCrossingRule) const;
-
void appendTrailingWhitespace();
bool expandUsingGranularity(TextGranularity granularity);
// We don't yet support multi-range selections, so we only ever have one range to return.
- PassRefPtr<Range> firstRange() const;
+ PassRefPtrWillBeRawPtr<Range> firstRange() const;
// FIXME: Most callers probably don't want this function, but are using it
// for historical reasons. toNormalizedRange contracts the range around
// text, and moves the caret upstream before returning the range.
- PassRefPtr<Range> toNormalizedRange() const;
+ PassRefPtrWillBeRawPtr<Range> toNormalizedRange() const;
Element* rootEditableElement() const;
bool isContentEditable() const;
@@ -107,6 +111,28 @@ public:
VisiblePosition visiblePositionRespectingEditingBoundary(const LayoutPoint& localPoint, Node* targetNode) const;
+ void setWithoutValidation(const Position&, const Position&);
+
+ // Listener of VisibleSelection modification. didChangeVisibleSelection() will be invoked when base, extent, start
+ // or end is moved to a different position.
+ //
+ // Objects implementing |ChangeObserver| interface must outlive the VisibleSelection object.
+ class ChangeObserver : public WillBeGarbageCollectedMixin {
+ WTF_MAKE_NONCOPYABLE(ChangeObserver);
+ public:
+ ChangeObserver();
+ virtual ~ChangeObserver();
+ virtual void didChangeVisibleSelection() = 0;
+ virtual void trace(Visitor*) { }
+ };
+
+ void setChangeObserver(ChangeObserver&);
+ void clearChangeObserver();
+ void didChange(); // Fire the change observer, if any.
+
+ void trace(Visitor*);
+
+ void validatePositionsIfNeeded();
#ifndef NDEBUG
void debugPosition() const;
@@ -114,8 +140,6 @@ public:
void showTreeForThis() const;
#endif
- void setWithoutValidation(const Position&, const Position&);
-
private:
void validate(TextGranularity = CharacterGranularity);
@@ -138,6 +162,10 @@ private:
EAffinity m_affinity; // the upstream/downstream affinity of the caret
+ // Oilpan: this reference has a lifetime that is at least as long
+ // as this object.
+ RawPtrWillBeMember<ChangeObserver> m_changeObserver;
+
// these are cached, can be recalculated by validate()
SelectionType m_selectionType; // None, Caret, Range
bool m_baseIsFirst : 1; // True if base is before the extent
diff --git a/chromium/third_party/WebKit/Source/core/editing/VisibleSelectionTest.cpp b/chromium/third_party/WebKit/Source/core/editing/VisibleSelectionTest.cpp
new file mode 100644
index 00000000000..3ea9ff44c5a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/editing/VisibleSelectionTest.cpp
@@ -0,0 +1,171 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/editing/VisibleSelection.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/Range.h"
+#include "core/dom/Text.h"
+#include "core/html/HTMLElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include <gtest/gtest.h>
+
+#define LOREM_IPSUM \
+ "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor " \
+ "incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud " \
+ "exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " \
+ "dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." \
+ "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt " \
+ "mollit anim id est laborum."
+
+namespace WebCore {
+
+class VisibleSelectionTest : public ::testing::Test {
+protected:
+ virtual void SetUp() OVERRIDE;
+
+ // Oilpan: wrapper object needed to be able to trace VisibleSelection.
+ class VisibleSelectionWrapper : public NoBaseWillBeGarbageCollectedFinalized<VisibleSelectionWrapper> {
+ public:
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_selection);
+ }
+
+ VisibleSelection m_selection;
+ };
+
+ Document& document() const { return m_dummyPageHolder->document(); }
+ Text* textNode() const { return m_textNode.get(); }
+ VisibleSelection& selection() { return m_wrap->m_selection; }
+
+ // Helper function to set the VisibleSelection base/extent.
+ void setSelection(int base) { setSelection(base, base); }
+
+ // Helper function to set the VisibleSelection base/extent.
+ void setSelection(int base, int extend)
+ {
+ m_wrap->m_selection.setBase(Position(textNode(), base));
+ m_wrap->m_selection.setExtent(Position(textNode(), extend));
+ }
+
+private:
+ OwnPtr<DummyPageHolder> m_dummyPageHolder;
+ RefPtrWillBePersistent<Text> m_textNode;
+ OwnPtrWillBePersistent<VisibleSelectionWrapper> m_wrap;
+};
+
+void WebCore::VisibleSelectionTest::SetUp()
+{
+ m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+ m_textNode = document().createTextNode(LOREM_IPSUM);
+ m_wrap = adoptPtrWillBeNoop(new VisibleSelectionWrapper());
+ document().body()->appendChild(m_textNode.get());
+}
+
+} // namespace WebCore
+
+namespace {
+
+using namespace WebCore;
+
+TEST_F(VisibleSelectionTest, Initialisation)
+{
+ setSelection(0);
+
+ EXPECT_FALSE(selection().isNone());
+ EXPECT_TRUE(selection().isCaret());
+
+ RefPtrWillBeRawPtr<Range> range = selection().firstRange();
+ EXPECT_EQ(0, range->startOffset());
+ EXPECT_EQ(0, range->endOffset());
+ EXPECT_EQ("", range->text());
+}
+
+TEST_F(VisibleSelectionTest, WordGranularity)
+{
+ // Beginning of a word.
+ {
+ setSelection(0);
+ selection().expandUsingGranularity(WordGranularity);
+
+ RefPtrWillBeRawPtr<Range> range = selection().firstRange();
+ EXPECT_EQ(0, range->startOffset());
+ EXPECT_EQ(5, range->endOffset());
+ EXPECT_EQ("Lorem", range->text());
+ }
+
+ // Middle of a word.
+ {
+ setSelection(8);
+ selection().expandUsingGranularity(WordGranularity);
+
+ RefPtrWillBeRawPtr<Range> range = selection().firstRange();
+ EXPECT_EQ(6, range->startOffset());
+ EXPECT_EQ(11, range->endOffset());
+ EXPECT_EQ("ipsum", range->text());
+ }
+
+ // End of a word.
+ // FIXME: that sounds buggy, we might want to select the word _before_ instead
+ // of the space...
+ {
+ setSelection(5);
+ selection().expandUsingGranularity(WordGranularity);
+
+ RefPtrWillBeRawPtr<Range> range = selection().firstRange();
+ EXPECT_EQ(5, range->startOffset());
+ EXPECT_EQ(6, range->endOffset());
+ EXPECT_EQ(" ", range->text());
+ }
+
+ // Before comma.
+ // FIXME: that sounds buggy, we might want to select the word _before_ instead
+ // of the comma.
+ {
+ setSelection(26);
+ selection().expandUsingGranularity(WordGranularity);
+
+ RefPtrWillBeRawPtr<Range> range = selection().firstRange();
+ EXPECT_EQ(26, range->startOffset());
+ EXPECT_EQ(27, range->endOffset());
+ EXPECT_EQ(",", range->text());
+ }
+
+ // After comma.
+ {
+ setSelection(27);
+ selection().expandUsingGranularity(WordGranularity);
+
+ RefPtrWillBeRawPtr<Range> range = selection().firstRange();
+ EXPECT_EQ(27, range->startOffset());
+ EXPECT_EQ(28, range->endOffset());
+ EXPECT_EQ(" ", range->text());
+ }
+
+ // When selecting part of a word.
+ {
+ setSelection(0, 1);
+ selection().expandUsingGranularity(WordGranularity);
+
+ RefPtrWillBeRawPtr<Range> range = selection().firstRange();
+ EXPECT_EQ(0, range->startOffset());
+ EXPECT_EQ(5, range->endOffset());
+ EXPECT_EQ("Lorem", range->text());
+ }
+
+ // When selecting part of two words.
+ {
+ setSelection(2, 8);
+ selection().expandUsingGranularity(WordGranularity);
+
+ RefPtrWillBeRawPtr<Range> range = selection().firstRange();
+ EXPECT_EQ(0, range->startOffset());
+ EXPECT_EQ(11, range->endOffset());
+ EXPECT_EQ("Lorem ipsum", range->text());
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/chromium/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index 1f39b48d9d9..fac20284ca2 100644
--- a/chromium/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -26,10 +26,9 @@
#include "config.h"
#include "core/editing/VisibleUnits.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/NodeTraversal.h"
@@ -39,9 +38,12 @@
#include "core/editing/TextIterator.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/htmlediting.h"
+#include "core/html/HTMLBRElement.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderBlockFlow.h"
#include "core/rendering/RenderObject.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/heap/Handle.h"
#include "platform/text/TextBoundaries.h"
namespace WebCore {
@@ -82,14 +84,14 @@ static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible
Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent(), editableType);
Node* previousNode = previousLeafWithSameEditability(node, editableType);
- while (previousNode && (!previousNode->renderer() || inSameLine(firstPositionInOrBeforeNode(previousNode), visiblePosition)))
+ while (previousNode && (!previousNode->renderer() || inSameLine(VisiblePosition(firstPositionInOrBeforeNode(previousNode)), visiblePosition)))
previousNode = previousLeafWithSameEditability(previousNode, editableType);
while (previousNode && !previousNode->isShadowRoot()) {
if (highestEditableRoot(firstPositionInOrBeforeNode(previousNode), editableType) != highestRoot)
break;
- Position pos = previousNode->hasTagName(brTag) ? positionBeforeNode(previousNode) :
+ Position pos = isHTMLBRElement(*previousNode) ? positionBeforeNode(previousNode) :
createLegacyEditingPosition(previousNode, caretMaxOffset(previousNode));
if (pos.isCandidate())
@@ -104,7 +106,7 @@ static Position nextRootInlineBoxCandidatePosition(Node* node, const VisiblePosi
{
Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent(), editableType);
Node* nextNode = nextLeafWithSameEditability(node, editableType);
- while (nextNode && (!nextNode->renderer() || inSameLine(firstPositionInOrBeforeNode(nextNode), visiblePosition)))
+ while (nextNode && (!nextNode->renderer() || inSameLine(VisiblePosition(firstPositionInOrBeforeNode(nextNode)), visiblePosition)))
nextNode = nextLeafWithSameEditability(nextNode, ContentIsEditable);
while (nextNode && !nextNode->isShadowRoot()) {
@@ -207,16 +209,16 @@ static const InlineTextBox* logicallyPreviousBox(const VisiblePosition& visibleP
{
const InlineBox* startBox = textBox;
- const InlineTextBox* previousBox = leafBoxes.previousTextBox(startBox->root(), textBox);
+ const InlineTextBox* previousBox = leafBoxes.previousTextBox(&startBox->root(), textBox);
if (previousBox)
return previousBox;
- previousBox = leafBoxes.previousTextBox(startBox->root()->prevRootBox(), 0);
+ previousBox = leafBoxes.previousTextBox(startBox->root().prevRootBox(), 0);
if (previousBox)
return previousBox;
while (1) {
- Node* startNode = startBox->renderer() ? startBox->renderer()->nonPseudoNode() : 0;
+ Node* startNode = startBox->renderer().nonPseudoNode();
if (!startNode)
break;
@@ -248,16 +250,16 @@ static const InlineTextBox* logicallyNextBox(const VisiblePosition& visiblePosit
{
const InlineBox* startBox = textBox;
- const InlineTextBox* nextBox = leafBoxes.nextTextBox(startBox->root(), textBox);
+ const InlineTextBox* nextBox = leafBoxes.nextTextBox(&startBox->root(), textBox);
if (nextBox)
return nextBox;
- nextBox = leafBoxes.nextTextBox(startBox->root()->nextRootBox(), 0);
+ nextBox = leafBoxes.nextTextBox(startBox->root().nextRootBox(), 0);
if (nextBox)
return nextBox;
while (1) {
- Node* startNode = startBox->renderer() ? startBox->renderer()->nonPseudoNode() : 0;
+ Node* startNode =startBox->renderer().nonPseudoNode();
if (!startNode)
break;
@@ -295,10 +297,10 @@ static TextBreakIterator* wordBreakIteratorForMinOffsetBoundary(const VisiblePos
string.clear();
if (previousBox) {
previousBoxLength = previousBox->len();
- previousBox->textRenderer()->text().appendTo(string, previousBox->start(), previousBoxLength);
+ previousBox->textRenderer().text().appendTo(string, previousBox->start(), previousBoxLength);
len += previousBoxLength;
}
- textBox->textRenderer()->text().appendTo(string, textBox->start(), textBox->len());
+ textBox->textRenderer().text().appendTo(string, textBox->start(), textBox->len());
len += textBox->len();
return wordBreakIterator(string.data(), len);
@@ -314,10 +316,10 @@ static TextBreakIterator* wordBreakIteratorForMaxOffsetBoundary(const VisiblePos
int len = 0;
string.clear();
- textBox->textRenderer()->text().appendTo(string, textBox->start(), textBox->len());
+ textBox->textRenderer().text().appendTo(string, textBox->start(), textBox->len());
len += textBox->len();
if (nextBox) {
- nextBox->textRenderer()->text().appendTo(string, nextBox->start(), nextBox->len());
+ nextBox->textRenderer().text().appendTo(string, nextBox->start(), nextBox->len());
len += nextBox->len();
}
@@ -384,7 +386,7 @@ static VisiblePosition visualWordPosition(const VisiblePosition& visiblePosition
else if (offsetInBox == box->caretMaxOffset())
iter = wordBreakIteratorForMaxOffsetBoundary(visiblePosition, textBox, nextBoxInDifferentBlock, string, leafBoxes);
else if (movingIntoNewBox) {
- iter = wordBreakIterator(textBox->textRenderer()->text(), textBox->start(), textBox->len());
+ iter = wordBreakIterator(textBox->textRenderer().text(), textBox->start(), textBox->len());
previouslyVisitedBox = box;
}
@@ -455,14 +457,14 @@ static VisiblePosition previousBoundary(const VisiblePosition& c, BoundarySearch
Document& d = boundary->document();
Position start = createLegacyEditingPosition(boundary, 0).parentAnchoredEquivalent();
Position end = pos.parentAnchoredEquivalent();
- RefPtr<Range> searchRange = Range::create(d);
+ RefPtrWillBeRawPtr<Range> searchRange = Range::create(d);
Vector<UChar, 1024> string;
unsigned suffixLength = 0;
TrackExceptionState exceptionState;
if (requiresContextForWordBoundary(c.characterBefore())) {
- RefPtr<Range> forwardsScanRange(d.createRange());
+ RefPtrWillBeRawPtr<Range> forwardsScanRange(d.createRange());
forwardsScanRange->setEndAfter(boundary, exceptionState);
forwardsScanRange->setStart(end.deprecatedNode(), end.deprecatedEditingOffset(), exceptionState);
TextIterator forwardsIterator(forwardsScanRange.get());
@@ -534,14 +536,14 @@ static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
return VisiblePosition();
Document& d = boundary->document();
- RefPtr<Range> searchRange(d.createRange());
+ RefPtrWillBeRawPtr<Range> searchRange(d.createRange());
Position start(pos.parentAnchoredEquivalent());
Vector<UChar, 1024> string;
unsigned prefixLength = 0;
if (requiresContextForWordBoundary(c.characterAfter())) {
- RefPtr<Range> backwardsScanRange(d.createRange());
+ RefPtrWillBeRawPtr<Range> backwardsScanRange(d.createRange());
backwardsScanRange->setEnd(start.deprecatedNode(), start.deprecatedEditingOffset(), IGNORE_EXCEPTION);
SimplifiedBackwardsTextIterator backwardsIterator(backwardsScanRange.get());
while (!backwardsIterator.atEnd()) {
@@ -593,7 +595,7 @@ static VisiblePosition nextBoundary(const VisiblePosition& c, BoundarySearchFunc
// Use the character iterator to translate the next value into a DOM position.
CharacterIterator charIt(searchRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
charIt.advance(next - prefixLength - 1);
- RefPtr<Range> characterRange = charIt.range();
+ RefPtrWillBeRawPtr<Range> characterRange = charIt.range();
pos = characterRange->endPosition();
if (charIt.characterAt(0) == '\n') {
@@ -704,11 +706,6 @@ VisiblePosition nextWordPosition(const VisiblePosition &c)
return c.honorEditingBoundaryAtOrAfter(next);
}
-bool isStartOfWord(const VisiblePosition& p)
-{
- return p.isNotNull() && p == startOfWord(p, RightWordIfOnBoundary);
-}
-
// ---------
enum LineEndpointComputationMode { UseLogicalOrdering, UseInlineBoxOrdering };
@@ -742,11 +739,7 @@ static VisiblePosition startPositionForLine(const VisiblePosition& c, LineEndpoi
if (!startBox)
return VisiblePosition();
- RenderObject* startRenderer = startBox->renderer();
- if (!startRenderer)
- return VisiblePosition();
-
- startNode = startRenderer->nonPseudoNode();
+ startNode = startBox->renderer().nonPseudoNode();
if (startNode)
break;
@@ -754,8 +747,7 @@ static VisiblePosition startPositionForLine(const VisiblePosition& c, LineEndpoi
}
}
- return startNode->isTextNode() ? Position(toText(startNode), toInlineTextBox(startBox)->start())
- : positionBeforeNode(startNode);
+ return VisiblePosition(startNode->isTextNode() ? Position(toText(startNode), toInlineTextBox(startBox)->start()) : positionBeforeNode(startNode));
}
static VisiblePosition startOfLine(const VisiblePosition& c, LineEndpointComputationMode mode)
@@ -767,7 +759,7 @@ static VisiblePosition startOfLine(const VisiblePosition& c, LineEndpointComputa
if (mode == UseLogicalOrdering) {
if (Node* editableRoot = highestEditableRoot(c.deepEquivalent())) {
if (!editableRoot->contains(visPos.deepEquivalent().containerNode()))
- return firstPositionInNode(editableRoot);
+ return VisiblePosition(firstPositionInNode(editableRoot));
}
}
@@ -814,11 +806,7 @@ static VisiblePosition endPositionForLine(const VisiblePosition& c, LineEndpoint
if (!endBox)
return VisiblePosition();
- RenderObject* endRenderer = endBox->renderer();
- if (!endRenderer)
- return VisiblePosition();
-
- endNode = endRenderer->nonPseudoNode();
+ endNode = endBox->renderer().nonPseudoNode();
if (endNode)
break;
@@ -827,7 +815,7 @@ static VisiblePosition endPositionForLine(const VisiblePosition& c, LineEndpoint
}
Position pos;
- if (endNode->hasTagName(brTag))
+ if (isHTMLBRElement(*endNode))
pos = positionBeforeNode(endNode);
else if (endBox->isInlineTextBox() && endNode->isTextNode()) {
InlineTextBox* endTextBox = toInlineTextBox(endBox);
@@ -863,7 +851,7 @@ static VisiblePosition endOfLine(const VisiblePosition& c, LineEndpointComputati
if (Node* editableRoot = highestEditableRoot(c.deepEquivalent())) {
if (!editableRoot->contains(visPos.deepEquivalent().containerNode()))
- return lastPositionInNode(editableRoot);
+ return VisiblePosition(lastPositionInNode(editableRoot));
}
return c.honorEditingBoundaryAtOrAfter(visPos);
@@ -913,12 +901,12 @@ bool isEndOfLine(const VisiblePosition &p)
static inline IntPoint absoluteLineDirectionPointToLocalPointInBlock(RootInlineBox* root, int lineDirectionPoint)
{
ASSERT(root);
- RenderBlockFlow* containingBlock = root->block();
- FloatPoint absoluteBlockPoint = containingBlock->localToAbsolute(FloatPoint());
- if (containingBlock->hasOverflowClip())
- absoluteBlockPoint -= containingBlock->scrolledContentOffset();
+ RenderBlockFlow& containingBlock = root->block();
+ FloatPoint absoluteBlockPoint = containingBlock.localToAbsolute(FloatPoint());
+ if (containingBlock.hasOverflowClip())
+ absoluteBlockPoint -= containingBlock.scrolledContentOffset();
- if (root->block()->isHorizontalWritingMode())
+ if (root->block().isHorizontalWritingMode())
return IntPoint(lineDirectionPoint - absoluteBlockPoint.x(), root->blockDirectionPointInLine());
return IntPoint(root->blockDirectionPointInLine(), lineDirectionPoint - absoluteBlockPoint.y());
@@ -943,7 +931,7 @@ VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
int ignoredCaretOffset;
visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset);
if (box) {
- root = box->root()->prevRootBox();
+ root = box->root().prevRootBox();
// We want to skip zero height boxes.
// This could happen in case it is a TrailingFloatsRootInlineBox.
if (!root || !root->logicalHeight() || !root->firstLeafChild())
@@ -953,21 +941,21 @@ VisiblePosition previousLinePosition(const VisiblePosition &visiblePosition, int
if (!root) {
Position position = previousRootInlineBoxCandidatePosition(node, visiblePosition, editableType);
if (position.isNotNull()) {
- RenderedPosition renderedPosition(position);
+ RenderedPosition renderedPosition((VisiblePosition(position)));
root = renderedPosition.rootBox();
if (!root)
- return position;
+ return VisiblePosition(position);
}
}
if (root) {
// FIXME: Can be wrong for multi-column layout and with transforms.
IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint);
- RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
- Node* node = renderer->node();
+ RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
+ Node* node = renderer.node();
if (node && editingIgnoresContent(node))
- return positionInParentBeforeNode(node);
- return VisiblePosition(renderer->positionForPoint(pointInLine));
+ return VisiblePosition(positionInParentBeforeNode(*node));
+ return VisiblePosition(renderer.positionForPoint(pointInLine));
}
// Could not find a previous line. This means we must already be on the first line.
@@ -998,7 +986,7 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int lin
int ignoredCaretOffset;
visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset);
if (box) {
- root = box->root()->nextRootBox();
+ root = box->root().nextRootBox();
// We want to skip zero height boxes.
// This could happen in case it is a TrailingFloatsRootInlineBox.
if (!root || !root->logicalHeight() || !root->firstLeafChild())
@@ -1007,25 +995,25 @@ VisiblePosition nextLinePosition(const VisiblePosition &visiblePosition, int lin
if (!root) {
// FIXME: We need do the same in previousLinePosition.
- Node* child = node->childNode(p.deprecatedEditingOffset());
- node = child ? child : &node->lastDescendant();
+ Node* child = node->traverseToChildAt(p.deprecatedEditingOffset());
+ node = child ? child : &node->lastDescendantOrSelf();
Position position = nextRootInlineBoxCandidatePosition(node, visiblePosition, editableType);
if (position.isNotNull()) {
- RenderedPosition renderedPosition(position);
+ RenderedPosition renderedPosition((VisiblePosition(position)));
root = renderedPosition.rootBox();
if (!root)
- return position;
+ return VisiblePosition(position);
}
}
if (root) {
// FIXME: Can be wrong for multi-column layout and with transforms.
IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint);
- RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
- Node* node = renderer->node();
+ RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
+ Node* node = renderer.node();
if (node && editingIgnoresContent(node))
- return positionInParentBeforeNode(node);
- return VisiblePosition(renderer->positionForPoint(pointInLine));
+ return VisiblePosition(positionInParentBeforeNode(*node));
+ return VisiblePosition(renderer.positionForPoint(pointInLine));
}
// Could not find a next line. This means we must already be on the last line.
@@ -1100,7 +1088,7 @@ VisiblePosition startOfParagraph(const VisiblePosition& c, EditingBoundaryCrossi
return VisiblePosition();
if (isRenderedAsNonInlineTableImageOrHR(startNode))
- return positionBeforeNode(startNode);
+ return VisiblePosition(positionBeforeNode(startNode));
Node* startBlock = enclosingBlock(startNode);
@@ -1177,7 +1165,7 @@ VisiblePosition endOfParagraph(const VisiblePosition &c, EditingBoundaryCrossing
Node* startNode = p.deprecatedNode();
if (isRenderedAsNonInlineTableImageOrHR(startNode))
- return positionAfterNode(startNode);
+ return VisiblePosition(positionAfterNode(startNode));
Node* startBlock = enclosingBlock(startNode);
Node* stayInsideBlock = startBlock;
@@ -1303,7 +1291,7 @@ VisiblePosition startOfBlock(const VisiblePosition& visiblePosition, EditingBoun
Node* startBlock;
if (!position.containerNode() || !(startBlock = enclosingBlock(position.containerNode(), rule)))
return VisiblePosition();
- return firstPositionInNode(startBlock);
+ return VisiblePosition(firstPositionInNode(startBlock));
}
VisiblePosition endOfBlock(const VisiblePosition& visiblePosition, EditingBoundaryCrossingRule rule)
@@ -1312,7 +1300,7 @@ VisiblePosition endOfBlock(const VisiblePosition& visiblePosition, EditingBounda
Node* endBlock;
if (!position.containerNode() || !(endBlock = enclosingBlock(position.containerNode(), rule)))
return VisiblePosition();
- return lastPositionInNode(endBlock);
+ return VisiblePosition(lastPositionInNode(endBlock));
}
bool inSameBlock(const VisiblePosition &a, const VisiblePosition &b)
@@ -1359,20 +1347,6 @@ VisiblePosition endOfDocument(const VisiblePosition &c)
return endOfDocument(c.deepEquivalent().deprecatedNode());
}
-bool inSameDocument(const VisiblePosition &a, const VisiblePosition &b)
-{
- Position ap = a.deepEquivalent();
- Node* an = ap.deprecatedNode();
- if (!an)
- return false;
- Position bp = b.deepEquivalent();
- Node* bn = bp.deprecatedNode();
- if (an == bn)
- return true;
-
- return an->document() == bn->document();
-}
-
bool isStartOfDocument(const VisiblePosition &p)
{
return p.isNotNull() && p.previous(CanCrossEditingBoundary).isNull();
@@ -1391,7 +1365,7 @@ VisiblePosition startOfEditableContent(const VisiblePosition& visiblePosition)
if (!highestRoot)
return VisiblePosition();
- return firstPositionInNode(highestRoot);
+ return VisiblePosition(firstPositionInNode(highestRoot));
}
VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition)
@@ -1400,7 +1374,7 @@ VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition)
if (!highestRoot)
return VisiblePosition();
- return lastPositionInNode(highestRoot);
+ return VisiblePosition(lastPositionInNode(highestRoot));
}
bool isEndOfEditableOrNonEditableContent(const VisiblePosition &p)
diff --git a/chromium/third_party/WebKit/Source/core/editing/VisibleUnits.h b/chromium/third_party/WebKit/Source/core/editing/VisibleUnits.h
index 598990bd203..825c3aa3cb9 100644
--- a/chromium/third_party/WebKit/Source/core/editing/VisibleUnits.h
+++ b/chromium/third_party/WebKit/Source/core/editing/VisibleUnits.h
@@ -43,7 +43,6 @@ VisiblePosition previousWordPosition(const VisiblePosition &);
VisiblePosition nextWordPosition(const VisiblePosition &);
VisiblePosition rightWordPosition(const VisiblePosition&, bool skipsSpaceWhenMovingRight);
VisiblePosition leftWordPosition(const VisiblePosition&, bool skipsSpaceWhenMovingRight);
-bool isStartOfWord(const VisiblePosition&);
// sentences
VisiblePosition startOfSentence(const VisiblePosition &);
@@ -86,7 +85,6 @@ VisiblePosition startOfDocument(const Node*);
VisiblePosition endOfDocument(const Node*);
VisiblePosition startOfDocument(const VisiblePosition &);
VisiblePosition endOfDocument(const VisiblePosition &);
-bool inSameDocument(const VisiblePosition &, const VisiblePosition &);
bool isStartOfDocument(const VisiblePosition &);
bool isEndOfDocument(const VisiblePosition &);
diff --git a/chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.cpp b/chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.cpp
index dc5290923bb..f615a556743 100644
--- a/chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.cpp
@@ -32,7 +32,7 @@
namespace WebCore {
-WrapContentsInDummySpanCommand::WrapContentsInDummySpanCommand(PassRefPtr<Element> element)
+WrapContentsInDummySpanCommand::WrapContentsInDummySpanCommand(PassRefPtrWillBeRawPtr<Element> element)
: SimpleEditCommand(element->document())
, m_element(element)
{
@@ -41,7 +41,7 @@ WrapContentsInDummySpanCommand::WrapContentsInDummySpanCommand(PassRefPtr<Elemen
void WrapContentsInDummySpanCommand::executeApply()
{
- Vector<RefPtr<Node> > children;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > children;
for (Node* child = m_element->firstChild(); child; child = child->nextSibling())
children.append(child);
@@ -66,7 +66,7 @@ void WrapContentsInDummySpanCommand::doUnapply()
if (!m_dummySpan || !m_element->rendererIsEditable())
return;
- Vector<RefPtr<Node> > children;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > children;
for (Node* child = m_dummySpan->firstChild(); child; child = child->nextSibling())
children.append(child);
@@ -87,4 +87,11 @@ void WrapContentsInDummySpanCommand::doReapply()
executeApply();
}
+void WrapContentsInDummySpanCommand::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ visitor->trace(m_dummySpan);
+ SimpleEditCommand::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.h b/chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.h
index be7f4b6c013..52518f69f04 100644
--- a/chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.h
+++ b/chromium/third_party/WebKit/Source/core/editing/WrapContentsInDummySpanCommand.h
@@ -32,23 +32,25 @@ namespace WebCore {
class HTMLElement;
-class WrapContentsInDummySpanCommand : public SimpleEditCommand {
+class WrapContentsInDummySpanCommand FINAL : public SimpleEditCommand {
public:
- static PassRefPtr<WrapContentsInDummySpanCommand> create(PassRefPtr<Element> element)
+ static PassRefPtrWillBeRawPtr<WrapContentsInDummySpanCommand> create(PassRefPtrWillBeRawPtr<Element> element)
{
- return adoptRef(new WrapContentsInDummySpanCommand(element));
+ return adoptRefWillBeNoop(new WrapContentsInDummySpanCommand(element));
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- explicit WrapContentsInDummySpanCommand(PassRefPtr<Element>);
+ explicit WrapContentsInDummySpanCommand(PassRefPtrWillBeRawPtr<Element>);
virtual void doApply() OVERRIDE;
virtual void doUnapply() OVERRIDE;
virtual void doReapply() OVERRIDE;
void executeApply();
- RefPtr<Element> m_element;
- RefPtr<HTMLElement> m_dummySpan;
+ RefPtrWillBeMember<Element> m_element;
+ RefPtrWillBeMember<HTMLElement> m_dummySpan;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/editing/htmlediting.cpp b/chromium/third_party/WebKit/Source/core/editing/htmlediting.cpp
index 6c00bb5d9a3..aca644cd900 100644
--- a/chromium/third_party/WebKit/Source/core/editing/htmlediting.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/htmlediting.cpp
@@ -26,10 +26,10 @@
#include "config.h"
#include "core/editing/htmlediting.h"
-#include "HTMLElementFactory.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLElementFactory.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/PositionIterator.h"
@@ -43,21 +43,21 @@
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleSelection.h"
#include "core/editing/VisibleUnits.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLBRElement.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLLIElement.h"
#include "core/html/HTMLOListElement.h"
#include "core/html/HTMLParagraphElement.h"
-#include "core/html/HTMLTableElement.h"
+#include "core/html/HTMLTableCellElement.h"
#include "core/html/HTMLUListElement.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderObject.h"
+#include "core/rendering/RenderTableCell.h"
#include "wtf/Assertions.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -66,13 +66,15 @@ using namespace HTMLNames;
// purposes of editing.
bool isAtomicNode(const Node *node)
{
- return node && (!node->hasChildNodes() || editingIgnoresContent(node));
+ return node && (!node->hasChildren() || editingIgnoresContent(node));
}
// Compare two positions, taking into account the possibility that one or both
// could be inside a shadow tree. Only works for non-null values.
int comparePositions(const Position& a, const Position& b)
{
+ ASSERT(a.isNotNull());
+ ASSERT(b.isNotNull());
TreeScope* commonScope = commonTreeScope(a.containerNode(), b.containerNode());
ASSERT(commonScope);
@@ -121,14 +123,14 @@ Node* highestEditableRoot(const Position& position, EditableType editableType)
if (!highestRoot)
return 0;
- if (highestRoot->hasTagName(bodyTag))
+ if (isHTMLBodyElement(*highestRoot))
return highestRoot;
node = highestRoot->parentNode();
while (node) {
if (node->rendererIsEditable(editableType))
highestRoot = node;
- if (node->hasTagName(bodyTag))
+ if (isHTMLBodyElement(*node))
break;
node = node->parentNode();
}
@@ -141,7 +143,7 @@ Node* lowestEditableAncestor(Node* node)
while (node) {
if (node->rendererIsEditable())
return node->rootEditableElement();
- if (node->hasTagName(bodyTag))
+ if (isHTMLBodyElement(*node))
break;
node = node->parentNode();
}
@@ -151,7 +153,7 @@ Node* lowestEditableAncestor(Node* node)
bool isEditablePosition(const Position& p, EditableType editableType, EUpdateStyle updateStyle)
{
- Node* node = p.deprecatedNode();
+ Node* node = p.parentAnchoredEquivalent().anchorNode();
if (!node)
return false;
if (updateStyle == UpdateStyle)
@@ -159,7 +161,7 @@ bool isEditablePosition(const Position& p, EditableType editableType, EUpdateSty
else
ASSERT(updateStyle == DoNotUpdateStyle);
- if (isTableElement(node))
+ if (isRenderedTableElement(node))
node = node->parentNode();
return node->rendererIsEditable(editableType);
@@ -178,7 +180,7 @@ bool isRichlyEditablePosition(const Position& p, EditableType editableType)
if (!node)
return false;
- if (isTableElement(node))
+ if (isRenderedTableElement(node))
node = node->parentNode();
return node->rendererIsRichlyEditable(editableType);
@@ -190,7 +192,7 @@ Element* editableRootForPosition(const Position& p, EditableType editableType)
if (!node)
return 0;
- if (isTableElement(node))
+ if (isRenderedTableElement(node))
node = node->parentNode();
return node->rootEditableElement(editableType);
@@ -256,66 +258,70 @@ Position previousVisuallyDistinctCandidate(const Position& position)
return Position();
}
-VisiblePosition firstEditablePositionAfterPositionInRoot(const Position& position, Node* highestRoot)
+VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position& position, Node* highestRoot)
{
// position falls before highestRoot.
if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && highestRoot->rendererIsEditable())
- return firstPositionInNode(highestRoot);
+ return VisiblePosition(firstPositionInNode(highestRoot));
- Position p = position;
+ Position editablePosition = position;
if (position.deprecatedNode()->treeScope() != highestRoot->treeScope()) {
- Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(p.deprecatedNode());
+ Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(editablePosition.deprecatedNode());
if (!shadowAncestor)
return VisiblePosition();
- p = positionAfterNode(shadowAncestor);
+ editablePosition = positionAfterNode(shadowAncestor);
}
- while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
- p = isAtomicNode(p.deprecatedNode()) ? positionInParentAfterNode(p.deprecatedNode()) : nextVisuallyDistinctCandidate(p);
+ while (editablePosition.deprecatedNode() && !isEditablePosition(editablePosition) && editablePosition.deprecatedNode()->isDescendantOf(highestRoot))
+ editablePosition = isAtomicNode(editablePosition.deprecatedNode()) ? positionInParentAfterNode(*editablePosition.deprecatedNode()) : nextVisuallyDistinctCandidate(editablePosition);
- if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
+ if (editablePosition.deprecatedNode() && editablePosition.deprecatedNode() != highestRoot && !editablePosition.deprecatedNode()->isDescendantOf(highestRoot))
return VisiblePosition();
- return VisiblePosition(p);
+ return VisiblePosition(editablePosition);
+}
+
+VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position& position, Node* highestRoot)
+{
+ return VisiblePosition(lastEditablePositionBeforePositionInRoot(position, highestRoot));
}
-VisiblePosition lastEditablePositionBeforePositionInRoot(const Position& position, Node* highestRoot)
+Position lastEditablePositionBeforePositionInRoot(const Position& position, Node* highestRoot)
{
// When position falls after highestRoot, the result is easy to compute.
if (comparePositions(position, lastPositionInNode(highestRoot)) == 1)
return lastPositionInNode(highestRoot);
- Position p = position;
+ Position editablePosition = position;
if (position.deprecatedNode()->treeScope() != highestRoot->treeScope()) {
- Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(p.deprecatedNode());
+ Node* shadowAncestor = highestRoot->treeScope().ancestorInThisScope(editablePosition.deprecatedNode());
if (!shadowAncestor)
- return VisiblePosition();
+ return Position();
- p = firstPositionInOrBeforeNode(shadowAncestor);
+ editablePosition = firstPositionInOrBeforeNode(shadowAncestor);
}
- while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
- p = isAtomicNode(p.deprecatedNode()) ? positionInParentBeforeNode(p.deprecatedNode()) : previousVisuallyDistinctCandidate(p);
+ while (editablePosition.deprecatedNode() && !isEditablePosition(editablePosition) && editablePosition.deprecatedNode()->isDescendantOf(highestRoot))
+ editablePosition = isAtomicNode(editablePosition.deprecatedNode()) ? positionInParentBeforeNode(*editablePosition.deprecatedNode()) : previousVisuallyDistinctCandidate(editablePosition);
- if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
- return VisiblePosition();
-
- return VisiblePosition(p);
+ if (editablePosition.deprecatedNode() && editablePosition.deprecatedNode() != highestRoot && !editablePosition.deprecatedNode()->isDescendantOf(highestRoot))
+ return Position();
+ return editablePosition;
}
// FIXME: The method name, comment, and code say three different things here!
// Whether or not content before and after this node will collapse onto the same line as it.
bool isBlock(const Node* node)
{
- return node && node->isElementNode() && node->renderer() && !node->renderer()->isInline() && !node->renderer()->isRubyText();
+ return node && node->renderer() && !node->renderer()->isInline() && !node->renderer()->isRubyText();
}
bool isInline(const Node* node)
{
- return node && node->isElementNode() && node->renderer() && node->renderer()->isInline();
+ return node && node->renderer() && node->renderer()->isInline();
}
// FIXME: Deploy this in all of the places where enclosingBlockFlow/enclosingBlockFlowOrTableElement are used.
@@ -325,7 +331,7 @@ bool isInline(const Node* node)
Element* enclosingBlock(Node* node, EditingBoundaryCrossingRule rule)
{
Node* enclosingNode = enclosingNodeOfType(firstPositionInOrBeforeNode(node), isBlock, rule);
- return toElement(enclosingNode);
+ return enclosingNode && enclosingNode->isElementNode() ? toElement(enclosingNode) : 0;
}
TextDirection directionOfEnclosingBlock(const Position& position)
@@ -349,8 +355,8 @@ int lastOffsetForEditing(const Node* node)
if (node->offsetInCharacters())
return node->maxCharacterOffset();
- if (node->hasChildNodes())
- return node->childNodeCount();
+ if (node->hasChildren())
+ return node->countChildren();
// NOTE: This should preempt the childNodeCount for, e.g., select nodes
if (editingIgnoresContent(node))
@@ -461,7 +467,7 @@ Position positionBeforeContainingSpecialElement(const Position& pos, Node** cont
Node* n = firstInSpecialElement(pos);
if (!n)
return pos;
- Position result = positionInParentBeforeNode(n);
+ Position result = positionInParentBeforeNode(*n);
if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
return pos;
if (containingSpecialElement)
@@ -474,7 +480,7 @@ Position positionAfterContainingSpecialElement(const Position& pos, Node **conta
Node* n = lastInSpecialElement(pos);
if (!n)
return pos;
- Position result = positionInParentAfterNode(n);
+ Position result = positionInParentAfterNode(*n);
if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
return pos;
if (containingSpecialElement)
@@ -501,45 +507,43 @@ Node* isLastPositionBeforeTable(const VisiblePosition& visiblePosition)
}
// Returns the visible position at the beginning of a node
-VisiblePosition visiblePositionBeforeNode(Node* node)
+VisiblePosition visiblePositionBeforeNode(Node& node)
{
- ASSERT(node);
- if (node->childNodeCount())
- return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
- ASSERT(node->parentNode());
- ASSERT(!node->parentNode()->isShadowRoot());
- return positionInParentBeforeNode(node);
+ if (node.hasChildren())
+ return VisiblePosition(firstPositionInOrBeforeNode(&node), DOWNSTREAM);
+ ASSERT(node.parentNode());
+ ASSERT(!node.parentNode()->isShadowRoot());
+ return VisiblePosition(positionInParentBeforeNode(node));
}
// Returns the visible position at the ending of a node
-VisiblePosition visiblePositionAfterNode(Node* node)
+VisiblePosition visiblePositionAfterNode(Node& node)
{
- ASSERT(node);
- if (node->childNodeCount())
- return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
- ASSERT(node->parentNode());
- ASSERT(!node->parentNode()->isShadowRoot());
- return positionInParentAfterNode(node);
+ if (node.hasChildren())
+ return VisiblePosition(lastPositionInOrAfterNode(&node), DOWNSTREAM);
+ ASSERT(node.parentNode());
+ ASSERT(!node.parentNode()->isShadowRoot());
+ return VisiblePosition(positionInParentAfterNode(node));
}
// Create a range object with two visible positions, start and end.
// create(Document*, const Position&, const Position&); will use deprecatedEditingOffset
// Use this function instead of create a regular range object (avoiding editing offset).
-PassRefPtr<Range> createRange(Document& document, const VisiblePosition& start, const VisiblePosition& end, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Range> createRange(Document& document, const VisiblePosition& start, const VisiblePosition& end, ExceptionState& exceptionState)
{
- RefPtr<Range> selectedRange = Range::create(document);
+ RefPtrWillBeRawPtr<Range> selectedRange = Range::create(document);
selectedRange->setStart(start.deepEquivalent().containerNode(), start.deepEquivalent().computeOffsetInContainerNode(), exceptionState);
if (!exceptionState.hadException())
selectedRange->setEnd(end.deepEquivalent().containerNode(), end.deepEquivalent().computeOffsetInContainerNode(), exceptionState);
return selectedRange.release();
}
-bool isListElement(Node *n)
+bool isListElement(Node* n)
{
- return (n && (n->hasTagName(ulTag) || n->hasTagName(olTag) || n->hasTagName(dlTag)));
+ return (n && (isHTMLUListElement(*n) || isHTMLOListElement(*n) || isHTMLDListElement(*n)));
}
-bool isListItem(const Node *n)
+bool isListItem(const Node* n)
{
return n && n->renderer() && n->renderer()->isListItem();
}
@@ -652,7 +656,7 @@ HTMLElement* enclosingList(Node* node)
Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node));
for (ContainerNode* n = node->parentNode(); n; n = n->parentNode()) {
- if (n->hasTagName(ulTag) || n->hasTagName(olTag))
+ if (isHTMLUListElement(*n) || isHTMLOListElement(*n))
return toHTMLElement(n);
if (n == root)
return 0;
@@ -671,7 +675,7 @@ Node* enclosingListChild(Node *node)
// FIXME: This function is inappropriately named if it starts with node instead of node->parentNode()
for (Node* n = node; n && n->parentNode(); n = n->parentNode()) {
- if (n->hasTagName(liTag) || (isListElement(n->parentNode()) && n != root))
+ if (isHTMLLIElement(*n) || (isListElement(n->parentNode()) && n != root))
return n;
if (n == root || isTableCell(n))
return 0;
@@ -680,30 +684,6 @@ Node* enclosingListChild(Node *node)
return 0;
}
-static HTMLElement* embeddedSublist(Node* listItem)
-{
- // Check the DOM so that we'll find collapsed sublists without renderers.
- for (Node* n = listItem->firstChild(); n; n = n->nextSibling()) {
- if (isListElement(n))
- return toHTMLElement(n);
- }
-
- return 0;
-}
-
-static Node* appendedSublist(Node* listItem)
-{
- // Check the DOM so that we'll find collapsed sublists without renderers.
- for (Node* n = listItem->nextSibling(); n; n = n->nextSibling()) {
- if (isListElement(n))
- return toHTMLElement(n);
- if (isListItem(listItem))
- return 0;
- }
-
- return 0;
-}
-
// FIXME: This method should not need to call isStartOfParagraph/isEndOfParagraph
Node* enclosingEmptyListItem(const VisiblePosition& visiblePos)
{
@@ -718,9 +698,6 @@ Node* enclosingEmptyListItem(const VisiblePosition& visiblePos)
if (firstInListChild != visiblePos || lastInListChild != visiblePos)
return 0;
- if (embeddedSublist(listChildNode) || appendedSublist(listChildNode))
- return 0;
-
return listChildNode;
}
@@ -747,16 +724,13 @@ bool canMergeLists(Element* firstList, Element* secondList)
return firstList->hasTagName(secondList->tagQName()) // make sure the list types match (ol vs. ul)
&& firstList->rendererIsEditable() && secondList->rendererIsEditable() // both lists are editable
&& firstList->rootEditableElement() == secondList->rootEditableElement() // don't cross editing boundaries
- && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList));
+ && isVisiblyAdjacent(positionInParentAfterNode(*firstList), positionInParentBeforeNode(*secondList));
// Make sure there is no visible content between this li and the previous list
}
-bool isTableElement(const Node* node)
+bool isRenderedTableElement(const Node* node)
{
- if (!node || !node->isElementNode())
- return false;
-
- return node->hasTagName(tableTag);
+ return isHTMLTableElement(*node) && node->renderer();
}
bool isRenderedTable(const Node* node)
@@ -770,11 +744,9 @@ bool isRenderedTable(const Node* node)
bool isTableCell(const Node* node)
{
+ ASSERT(node);
RenderObject* r = node->renderer();
- if (!r)
- return node->hasTagName(tdTag) || node->hasTagName(thTag);
-
- return r->isTableCell();
+ return r ? r->isTableCell() : isHTMLTableCellElement(*node);
}
bool isEmptyTableCell(const Node* node)
@@ -802,7 +774,7 @@ bool isEmptyTableCell(const Node* node)
return false;
// Check that the table cell contains no child renderers except for perhaps a single <br>.
- RenderObject* childRenderer = renderer->firstChild();
+ RenderObject* childRenderer = toRenderTableCell(renderer)->firstChild();
if (!childRenderer)
return true;
if (!childRenderer->isBR())
@@ -810,7 +782,7 @@ bool isEmptyTableCell(const Node* node)
return !childRenderer->nextSibling();
}
-PassRefPtr<HTMLElement> createDefaultParagraphElement(Document& document)
+PassRefPtrWillBeRawPtr<HTMLElement> createDefaultParagraphElement(Document& document)
{
switch (document.frame()->editor().defaultParagraphSeparator()) {
case EditorParagraphSeparatorIsDiv:
@@ -820,74 +792,63 @@ PassRefPtr<HTMLElement> createDefaultParagraphElement(Document& document)
}
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
-PassRefPtr<HTMLElement> createBreakElement(Document& document)
+PassRefPtrWillBeRawPtr<HTMLElement> createBreakElement(Document& document)
{
return HTMLBRElement::create(document);
}
-PassRefPtr<HTMLElement> createOrderedListElement(Document& document)
+PassRefPtrWillBeRawPtr<HTMLElement> createOrderedListElement(Document& document)
{
return HTMLOListElement::create(document);
}
-PassRefPtr<HTMLElement> createUnorderedListElement(Document& document)
+PassRefPtrWillBeRawPtr<HTMLElement> createUnorderedListElement(Document& document)
{
return HTMLUListElement::create(document);
}
-PassRefPtr<HTMLElement> createListItemElement(Document& document)
+PassRefPtrWillBeRawPtr<HTMLElement> createListItemElement(Document& document)
{
return HTMLLIElement::create(document);
}
-PassRefPtr<HTMLElement> createHTMLElement(Document& document, const QualifiedName& name)
+PassRefPtrWillBeRawPtr<HTMLElement> createHTMLElement(Document& document, const QualifiedName& name)
{
return createHTMLElement(document, name.localName());
}
-PassRefPtr<HTMLElement> createHTMLElement(Document& document, const AtomicString& tagName)
+PassRefPtrWillBeRawPtr<HTMLElement> createHTMLElement(Document& document, const AtomicString& tagName)
{
return HTMLElementFactory::createHTMLElement(tagName, document, 0, false);
}
-bool isTabSpanNode(const Node *node)
+bool isTabSpanNode(const Node* node)
{
- return node && node->hasTagName(spanTag) && node->isElementNode() && toElement(node)->getAttribute(classAttr) == AppleTabSpanClass;
+ if (!isHTMLSpanElement(node) || toElement(node)->getAttribute(classAttr) != AppleTabSpanClass)
+ return false;
+ UseCounter::count(node->document(), UseCounter::EditingAppleTabSpanClass);
+ return true;
}
-bool isTabSpanTextNode(const Node *node)
+bool isTabSpanTextNode(const Node* node)
{
return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode());
}
-Node* tabSpanNode(const Node *node)
+Node* tabSpanNode(const Node* node)
{
return isTabSpanTextNode(node) ? node->parentNode() : 0;
}
-Position positionOutsideTabSpan(const Position& pos)
+PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document& document, PassRefPtrWillBeRawPtr<Node> prpTabTextNode)
{
- Node* node = pos.containerNode();
- if (isTabSpanTextNode(node))
- node = tabSpanNode(node);
- else if (!isTabSpanNode(node))
- return pos;
-
- if (node && VisiblePosition(pos) == lastPositionInNode(node))
- return positionInParentAfterNode(node);
-
- return positionInParentBeforeNode(node);
-}
-
-PassRefPtr<Element> createTabSpanElement(Document& document, PassRefPtr<Node> prpTabTextNode)
-{
- RefPtr<Node> tabTextNode = prpTabTextNode;
+ RefPtrWillBeRawPtr<Node> tabTextNode = prpTabTextNode;
// Make the span to hold the tab.
- RefPtr<Element> spanElement = document.createElement(spanTag, false);
+ RefPtrWillBeRawPtr<Element> spanElement = document.createElement(spanTag, false);
spanElement->setAttribute(classAttr, AppleTabSpanClass);
spanElement->setAttribute(styleAttr, "white-space:pre");
@@ -900,14 +861,14 @@ PassRefPtr<Element> createTabSpanElement(Document& document, PassRefPtr<Node> pr
return spanElement.release();
}
-PassRefPtr<Element> createTabSpanElement(Document& document, const String& tabText)
+PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document& document, const String& tabText)
{
return createTabSpanElement(document, document.createTextNode(tabText));
}
-PassRefPtr<Element> createTabSpanElement(Document& document)
+PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document& document)
{
- return createTabSpanElement(document, PassRefPtr<Node>());
+ return createTabSpanElement(document, PassRefPtrWillBeRawPtr<Node>(nullptr));
}
bool isNodeRendered(const Node *node)
@@ -932,7 +893,7 @@ unsigned numEnclosingMailBlockquotes(const Position& p)
return num;
}
-void updatePositionForNodeRemoval(Position& position, Node* node)
+void updatePositionForNodeRemoval(Position& position, Node& node)
{
if (position.isNull())
return;
@@ -946,17 +907,17 @@ void updatePositionForNodeRemoval(Position& position, Node* node)
position = positionInParentAfterNode(node);
break;
case Position::PositionIsOffsetInAnchor:
- if (position.containerNode() == node->parentNode() && static_cast<unsigned>(position.offsetInContainerNode()) > node->nodeIndex())
+ if (position.containerNode() == node.parentNode() && static_cast<unsigned>(position.offsetInContainerNode()) > node.nodeIndex())
position.moveToOffset(position.offsetInContainerNode() - 1);
- else if (node->containsIncludingShadowDOM(position.containerNode()))
+ else if (node.containsIncludingShadowDOM(position.containerNode()))
position = positionInParentBeforeNode(node);
break;
case Position::PositionIsAfterAnchor:
- if (node->containsIncludingShadowDOM(position.anchorNode()))
+ if (node.containsIncludingShadowDOM(position.anchorNode()))
position = positionInParentAfterNode(node);
break;
case Position::PositionIsBeforeAnchor:
- if (node->containsIncludingShadowDOM(position.anchorNode()))
+ if (node.containsIncludingShadowDOM(position.anchorNode()))
position = positionInParentBeforeNode(node);
break;
}
@@ -998,7 +959,7 @@ bool lineBreakExistsAtPosition(const Position& position)
if (position.isNull())
return false;
- if (position.anchorNode()->hasTagName(brTag) && position.atFirstEditingPositionForNode())
+ if (isHTMLBRElement(*position.anchorNode()) && position.atFirstEditingPositionForNode())
return true;
if (!position.anchorNode()->renderer())
@@ -1046,7 +1007,7 @@ VisibleSelection selectionForParagraphIteration(const VisibleSelection& original
// opertion is unreliable. TextIterator's TextIteratorEmitsCharactersBetweenAllVisiblePositions mode needs to be fixed,
// or these functions need to be changed to iterate using actual VisiblePositions.
// FIXME: Deploy these functions everywhere that TextIterators are used to convert between VisiblePositions and indices.
-int indexForVisiblePosition(const VisiblePosition& visiblePosition, RefPtr<ContainerNode>& scope)
+int indexForVisiblePosition(const VisiblePosition& visiblePosition, RefPtrWillBeRawPtr<ContainerNode>& scope)
{
if (visiblePosition.isNull())
return 0;
@@ -1060,7 +1021,7 @@ int indexForVisiblePosition(const VisiblePosition& visiblePosition, RefPtr<Conta
else
scope = document.documentElement();
- RefPtr<Range> range = Range::create(document, firstPositionInNode(scope.get()), p.parentAnchoredEquivalent());
+ RefPtrWillBeRawPtr<Range> range = Range::create(document, firstPositionInNode(scope.get()), p.parentAnchoredEquivalent());
return TextIterator::rangeLength(range.get(), true);
}
@@ -1069,7 +1030,7 @@ VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope)
{
if (!scope)
return VisiblePosition();
- RefPtr<Range> range = PlainTextRange(index).createRangeForSelection(*scope);
+ RefPtrWillBeRawPtr<Range> range = PlainTextRange(index).createRangeForSelection(*scope);
// Check for an invalid index. Certain editing operations invalidate indices because
// of problems with TextIteratorEmitsCharactersBetweenAllVisiblePositions.
if (!range)
@@ -1086,20 +1047,18 @@ bool isVisiblyAdjacent(const Position& first, const Position& second)
// Determines whether a node is inside a range or visibly starts and ends at the boundaries of the range.
// Call this function to determine whether a node is visibly fit inside selectedRange
-bool isNodeVisiblyContainedWithin(Node* node, const Range* selectedRange)
+bool isNodeVisiblyContainedWithin(Node& node, const Range& selectedRange)
{
- ASSERT(node);
- ASSERT(selectedRange);
// If the node is inside the range, then it surely is contained within
- if (selectedRange->compareNode(node, IGNORE_EXCEPTION) == Range::NODE_INSIDE)
+ if (selectedRange.compareNode(&node, IGNORE_EXCEPTION) == Range::NODE_INSIDE)
return true;
- bool startIsVisuallySame = visiblePositionBeforeNode(node) == selectedRange->startPosition();
- if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node), selectedRange->endPosition()) < 0)
+ bool startIsVisuallySame = visiblePositionBeforeNode(node) == VisiblePosition(selectedRange.startPosition());
+ if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node), selectedRange.endPosition()) < 0)
return true;
- bool endIsVisuallySame = visiblePositionAfterNode(node) == selectedRange->endPosition();
- if (endIsVisuallySame && comparePositions(selectedRange->startPosition(), positionInParentBeforeNode(node)) < 0)
+ bool endIsVisuallySame = visiblePositionAfterNode(node) == VisiblePosition(selectedRange.endPosition());
+ if (endIsVisuallySame && comparePositions(selectedRange.startPosition(), positionInParentBeforeNode(node)) < 0)
return true;
return startIsVisuallySame && endIsVisuallySame;
@@ -1131,7 +1090,7 @@ bool isNonTableCellHTMLBlockElement(const Node* node)
return node->hasTagName(listingTag)
|| node->hasTagName(olTag)
|| node->hasTagName(preTag)
- || isHTMLTableElement(node)
+ || node->hasTagName(tableTag)
|| node->hasTagName(ulTag)
|| node->hasTagName(xmpTag)
|| node->hasTagName(h1Tag)
@@ -1148,7 +1107,7 @@ Position adjustedSelectionStartForStyleComputation(const VisibleSelection& selec
// It is important to skip certain irrelevant content at the start of the selection, so we do not wind up
// with a spurious "mixed" style.
- VisiblePosition visiblePosition = selection.start();
+ VisiblePosition visiblePosition(selection.start());
if (visiblePosition.isNull())
return Position();
diff --git a/chromium/third_party/WebKit/Source/core/editing/htmlediting.h b/chromium/third_party/WebKit/Source/core/editing/htmlediting.h
index 1d7e52c49e0..d66d919f2cf 100644
--- a/chromium/third_party/WebKit/Source/core/editing/htmlediting.h
+++ b/chromium/third_party/WebKit/Source/core/editing/htmlediting.h
@@ -102,14 +102,14 @@ bool isTabSpanNode(const Node*);
bool isTabSpanTextNode(const Node*);
bool isMailBlockquote(const Node*);
bool isRenderedTable(const Node*);
-bool isTableElement(const Node*);
+bool isRenderedTableElement(const Node*);
bool isTableCell(const Node*);
bool isEmptyTableCell(const Node*);
bool isTableStructureNode(const Node*);
bool isListElement(Node*);
bool isListItem(const Node*);
bool isNodeRendered(const Node*);
-bool isNodeVisiblyContainedWithin(Node*, const Range*);
+bool isNodeVisiblyContainedWithin(Node&, const Range&);
bool isRenderedAsNonInlineTableImageOrHR(const Node*);
bool areIdenticalElements(const Node*, const Node*);
bool isNonTableCellHTMLBlockElement(const Node*);
@@ -127,7 +127,6 @@ Position previousCandidate(const Position&);
Position nextVisuallyDistinctCandidate(const Position&);
Position previousVisuallyDistinctCandidate(const Position&);
-Position positionOutsideTabSpan(const Position&);
Position positionBeforeContainingSpecialElement(const Position&, Node** containingSpecialElement = 0);
Position positionAfterContainingSpecialElement(const Position&, Node** containingSpecialElement = 0);
@@ -145,6 +144,8 @@ inline Position lastPositionInOrAfterNode(Node* node)
return editingIgnoresContent(node) ? positionAfterNode(node) : lastPositionInNode(node);
}
+Position lastEditablePositionBeforePositionInRoot(const Position&, Node*);
+
// comparision functions on Position
int comparePositions(const Position&, const Position&);
@@ -153,6 +154,10 @@ int comparePositions(const PositionWithAffinity&, const PositionWithAffinity&);
// boolean functions on Position
enum EUpdateStyle { UpdateStyle, DoNotUpdateStyle };
+// FIXME: Both isEditablePosition and isRichlyEditablePosition rely on up-to-date
+// style to give proper results. They shouldn't update style by default, but
+// should make it clear that that is the contract.
+// FIXME: isRichlyEditablePosition should also take EUpdateStyle.
bool isEditablePosition(const Position&, EditableType = ContentIsEditable, EUpdateStyle = UpdateStyle);
bool isRichlyEditablePosition(const Position&, EditableType = ContentIsEditable);
bool lineBreakExistsAtPosition(const Position&);
@@ -162,7 +167,7 @@ bool isAtUnsplittableElement(const Position&);
// miscellaneous functions on Position
unsigned numEnclosingMailBlockquotes(const Position&);
-void updatePositionForNodeRemoval(Position&, Node*);
+void updatePositionForNodeRemoval(Position&, Node&);
// -------------------------------------------------------------------------
// VisiblePosition
@@ -170,16 +175,16 @@ void updatePositionForNodeRemoval(Position&, Node*);
// Functions returning VisiblePosition
-VisiblePosition firstEditablePositionAfterPositionInRoot(const Position&, Node*);
-VisiblePosition lastEditablePositionBeforePositionInRoot(const Position&, Node*);
-VisiblePosition visiblePositionBeforeNode(Node*);
-VisiblePosition visiblePositionAfterNode(Node*);
+VisiblePosition firstEditableVisiblePositionAfterPositionInRoot(const Position&, Node*);
+VisiblePosition lastEditableVisiblePositionBeforePositionInRoot(const Position&, Node*);
+VisiblePosition visiblePositionBeforeNode(Node&);
+VisiblePosition visiblePositionAfterNode(Node&);
bool lineBreakExistsAtVisiblePosition(const VisiblePosition&);
int comparePositions(const VisiblePosition&, const VisiblePosition&);
-int indexForVisiblePosition(const VisiblePosition&, RefPtr<ContainerNode>& scope);
+int indexForVisiblePosition(const VisiblePosition&, RefPtrWillBeRawPtr<ContainerNode>& scope);
VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope);
// -------------------------------------------------------------------------
@@ -188,7 +193,7 @@ VisiblePosition visiblePositionForIndex(int index, ContainerNode* scope);
// Functions returning Range
-PassRefPtr<Range> createRange(Document&, const VisiblePosition& start, const VisiblePosition& end, ExceptionState&);
+PassRefPtrWillBeRawPtr<Range> createRange(Document&, const VisiblePosition& start, const VisiblePosition& end, ExceptionState&);
// -------------------------------------------------------------------------
// HTMLElement
@@ -196,13 +201,13 @@ PassRefPtr<Range> createRange(Document&, const VisiblePosition& start, const Vis
// Functions returning HTMLElement
-PassRefPtr<HTMLElement> createDefaultParagraphElement(Document&);
-PassRefPtr<HTMLElement> createBreakElement(Document&);
-PassRefPtr<HTMLElement> createOrderedListElement(Document&);
-PassRefPtr<HTMLElement> createUnorderedListElement(Document&);
-PassRefPtr<HTMLElement> createListItemElement(Document&);
-PassRefPtr<HTMLElement> createHTMLElement(Document&, const QualifiedName&);
-PassRefPtr<HTMLElement> createHTMLElement(Document&, const AtomicString&);
+PassRefPtrWillBeRawPtr<HTMLElement> createDefaultParagraphElement(Document&);
+PassRefPtrWillBeRawPtr<HTMLElement> createBreakElement(Document&);
+PassRefPtrWillBeRawPtr<HTMLElement> createOrderedListElement(Document&);
+PassRefPtrWillBeRawPtr<HTMLElement> createUnorderedListElement(Document&);
+PassRefPtrWillBeRawPtr<HTMLElement> createListItemElement(Document&);
+PassRefPtrWillBeRawPtr<HTMLElement> createHTMLElement(Document&, const QualifiedName&);
+PassRefPtrWillBeRawPtr<HTMLElement> createHTMLElement(Document&, const AtomicString&);
HTMLElement* enclosingList(Node*);
HTMLElement* outermostEnclosingList(Node*, Node* rootList = 0);
@@ -214,10 +219,10 @@ Node* enclosingListChild(Node*);
// Functions returning Element
-PassRefPtr<Element> createTabSpanElement(Document&);
-PassRefPtr<Element> createTabSpanElement(Document&, PassRefPtr<Node> tabTextNode);
-PassRefPtr<Element> createTabSpanElement(Document&, const String& tabText);
-PassRefPtr<Element> createBlockPlaceholderElement(Document&);
+PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document&);
+PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document&, PassRefPtrWillBeRawPtr<Node> tabTextNode);
+PassRefPtrWillBeRawPtr<Element> createTabSpanElement(Document&, const String& tabText);
+PassRefPtrWillBeRawPtr<Element> createBlockPlaceholderElement(Document&);
Element* editableRootForPosition(const Position&, EditableType = ContentIsEditable);
Element* unsplittableElementForPosition(const Position&);
@@ -242,6 +247,12 @@ inline bool isWhitespace(UChar c)
return c == noBreakSpace || c == ' ' || c == '\n' || c == '\t';
}
+// FIXME: Can't really answer this question correctly without knowing the white-space mode.
+inline bool isCollapsibleWhitespace(UChar c)
+{
+ return c == ' ' || c == '\n';
+}
+
inline bool isAmbiguousBoundaryCharacter(UChar character)
{
// These are characters that can behave as word boundaries, but can appear within words.
diff --git a/chromium/third_party/WebKit/Source/core/editing/markup.cpp b/chromium/third_party/WebKit/Source/core/editing/markup.cpp
index 184ed05a8a2..46f385064a3 100644
--- a/chromium/third_party/WebKit/Source/core/editing/markup.cpp
+++ b/chromium/third_party/WebKit/Source/core/editing/markup.cpp
@@ -29,10 +29,10 @@
#include "config.h"
#include "core/editing/markup.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSValue.h"
#include "core/css/StylePropertySet.h"
@@ -50,19 +50,16 @@
#include "core/editing/VisibleSelection.h"
#include "core/editing/VisibleUnits.h"
#include "core/editing/htmlediting.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLElement.h"
-#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLTableElement.h"
+#include "core/html/HTMLTableCellElement.h"
#include "core/html/HTMLTextFormControlElement.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderObject.h"
#include "platform/weborigin/KURL.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -70,13 +67,14 @@ using namespace HTMLNames;
static bool propertyMissingOrEqualToNone(StylePropertySet*, CSSPropertyID);
class AttributeChange {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
AttributeChange()
: m_name(nullAtom, nullAtom, nullAtom)
{
}
- AttributeChange(PassRefPtr<Element> element, const QualifiedName& name, const String& value)
+ AttributeChange(PassRefPtrWillBeRawPtr<Element> element, const QualifiedName& name, const String& value)
: m_element(element), m_name(name), m_value(value)
{
}
@@ -86,26 +84,37 @@ public:
m_element->setAttribute(m_name, AtomicString(m_value));
}
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_element);
+ }
+
private:
- RefPtr<Element> m_element;
+ RefPtrWillBeMember<Element> m_element;
QualifiedName m_name;
String m_value;
};
+} // namespace WebCore
+
+WTF_ALLOW_INIT_WITH_MEM_FUNCTIONS(WebCore::AttributeChange);
+
+namespace WebCore {
+
static void completeURLs(DocumentFragment& fragment, const String& baseURL)
{
- Vector<AttributeChange> changes;
+ WillBeHeapVector<AttributeChange> changes;
KURL parsedBaseURL(ParsedURLString, baseURL);
for (Element* element = ElementTraversal::firstWithin(fragment); element; element = ElementTraversal::next(*element, &fragment)) {
if (!element->hasAttributes())
continue;
- unsigned length = element->attributeCount();
- for (unsigned i = 0; i < length; i++) {
- const Attribute* attribute = element->attributeItem(i);
- if (element->isURLAttribute(*attribute) && !attribute->value().isEmpty())
- changes.append(AttributeChange(element, attribute->name(), KURL(parsedBaseURL, attribute->value()).string()));
+ AttributeCollection attributes = element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (element->isURLAttribute(*it) && !it->value().isEmpty())
+ changes.append(AttributeChange(element, it->name(), KURL(parsedBaseURL, it->value()).string()));
}
}
@@ -114,64 +123,63 @@ static void completeURLs(DocumentFragment& fragment, const String& baseURL)
changes[i].apply();
}
-class StyledMarkupAccumulator : public MarkupAccumulator {
+class StyledMarkupAccumulator FINAL : public MarkupAccumulator {
public:
enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
- StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs, EAnnotateForInterchange, const Range*, Node* highestNodeToBeSerialized = 0);
+ StyledMarkupAccumulator(WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs, EAnnotateForInterchange, RawPtr<const Range>, Node* highestNodeToBeSerialized = 0);
Node* serializeNodes(Node* startNode, Node* pastEnd);
- virtual void appendString(const String& s) { return MarkupAccumulator::appendString(s); }
- void wrapWithNode(Node*, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
- void wrapWithStyleNode(StylePropertySet*, Document*, bool isBlock = false);
+ void appendString(const String& s) { return MarkupAccumulator::appendString(s); }
+ void wrapWithNode(Node&, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
+ void wrapWithStyleNode(StylePropertySet*, const Document&, bool isBlock = false);
String takeResults();
private:
- void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, Document*, bool isBlock = false);
+ void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, const Document&, bool isBlock = false);
const String& styleNodeCloseTag(bool isBlock = false);
- virtual void appendText(StringBuilder& out, Text*);
- String renderedText(const Node*, const Range*);
- String stringValueForRange(const Node*, const Range*);
- void appendElement(StringBuilder& out, Element*, bool addDisplayInline, RangeFullySelectsNode);
- void appendElement(StringBuilder& out, Element* element, Namespaces*) { appendElement(out, element, false, DoesFullySelectNode); }
+ virtual void appendText(StringBuilder& out, Text&) OVERRIDE;
+ String renderedText(Node&, const Range*);
+ String stringValueForRange(const Node&, const Range*);
+ void appendElement(StringBuilder& out, Element&, bool addDisplayInline, RangeFullySelectsNode);
+ virtual void appendElement(StringBuilder& out, Element& element, Namespaces*) OVERRIDE { appendElement(out, element, false, DoesFullySelectNode); }
enum NodeTraversalMode { EmitString, DoNotEmitString };
Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTraversalMode);
bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
- bool shouldApplyWrappingStyle(Node* node) const
+ bool shouldApplyWrappingStyle(const Node& node) const
{
- return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() == node->parentNode()
+ return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() == node.parentNode()
&& m_wrappingStyle && m_wrappingStyle->style();
}
Vector<String> m_reversedPrecedingMarkup;
const EAnnotateForInterchange m_shouldAnnotate;
- Node* m_highestNodeToBeSerialized;
- RefPtr<EditingStyle> m_wrappingStyle;
+ RawPtrWillBeMember<Node> m_highestNodeToBeSerialized;
+ RefPtrWillBeMember<EditingStyle> m_wrappingStyle;
};
-inline StyledMarkupAccumulator::StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate,
- const Range* range, Node* highestNodeToBeSerialized)
+inline StyledMarkupAccumulator::StyledMarkupAccumulator(WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs shouldResolveURLs, EAnnotateForInterchange shouldAnnotate, RawPtr<const Range> range, Node* highestNodeToBeSerialized)
: MarkupAccumulator(nodes, shouldResolveURLs, range)
, m_shouldAnnotate(shouldAnnotate)
, m_highestNodeToBeSerialized(highestNodeToBeSerialized)
{
}
-void StyledMarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
+void StyledMarkupAccumulator::wrapWithNode(Node& node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
{
StringBuilder markup;
- if (node->isElementNode())
- appendElement(markup, toElement(node), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), rangeFullySelectsNode);
+ if (node.isElementNode())
+ appendElement(markup, toElement(node), convertBlocksToInlines && isBlock(&node), rangeFullySelectsNode);
else
appendStartMarkup(markup, node, 0);
m_reversedPrecedingMarkup.append(markup.toString());
appendEndTag(node);
if (m_nodes)
- m_nodes->append(node);
+ m_nodes->append(&node);
}
-void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, Document* document, bool isBlock)
+void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, const Document& document, bool isBlock)
{
StringBuilder openTag;
appendStyleNodeOpenTag(openTag, style, document, isBlock);
@@ -179,7 +187,7 @@ void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, Documen
appendString(styleNodeCloseTag(isBlock));
}
-void StyledMarkupAccumulator::appendStyleNodeOpenTag(StringBuilder& out, StylePropertySet* style, Document* document, bool isBlock)
+void StyledMarkupAccumulator::appendStyleNodeOpenTag(StringBuilder& out, StylePropertySet* style, const Document& document, bool isBlock)
{
// wrappingStyleForSerialization should have removed -webkit-text-decorations-in-effect
ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsInEffect));
@@ -187,9 +195,8 @@ void StyledMarkupAccumulator::appendStyleNodeOpenTag(StringBuilder& out, StylePr
out.appendLiteral("<div style=\"");
else
out.appendLiteral("<span style=\"");
- appendAttributeValue(out, style->asText(), document->isHTMLDocument());
- out.append('\"');
- out.append('>');
+ appendAttributeValue(out, style->asText(), document.isHTMLDocument());
+ out.appendLiteral("\">");
}
const String& StyledMarkupAccumulator::styleNodeCloseTag(bool isBlock)
@@ -213,25 +220,25 @@ String StyledMarkupAccumulator::takeResults()
return result.toString().replace(0, "");
}
-void StyledMarkupAccumulator::appendText(StringBuilder& out, Text* text)
+void StyledMarkupAccumulator::appendText(StringBuilder& out, Text& text)
{
- const bool parentIsTextarea = text->parentElement() && text->parentElement()->tagQName() == textareaTag;
+ const bool parentIsTextarea = text.parentElement() && text.parentElement()->tagQName() == textareaTag;
const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextarea;
if (wrappingSpan) {
- RefPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy();
+ RefPtrWillBeRawPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy();
// FIXME: <rdar://problem/5371536> Style rules that match pasted content can change it's appearance
// Make sure spans are inline style in paste side e.g. span { display: block }.
wrappingStyle->forceInline();
// FIXME: Should this be included in forceInline?
wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone);
- appendStyleNodeOpenTag(out, wrappingStyle->style(), &text->document());
+ appendStyleNodeOpenTag(out, wrappingStyle->style(), text.document());
}
if (!shouldAnnotate() || parentIsTextarea)
MarkupAccumulator::appendText(out, text);
else {
- const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(text), selectTag);
+ const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(&text), selectTag);
String content = useRenderedText ? renderedText(text, m_range) : stringValueForRange(text, m_range);
StringBuilder buffer;
appendCharactersReplacingEntities(buffer, content, 0, content.length(), EntityMaskInPCDATA);
@@ -242,31 +249,31 @@ void StyledMarkupAccumulator::appendText(StringBuilder& out, Text* text)
out.append(styleNodeCloseTag());
}
-String StyledMarkupAccumulator::renderedText(const Node* node, const Range* range)
+String StyledMarkupAccumulator::renderedText(Node& node, const Range* range)
{
- if (!node->isTextNode())
+ if (!node.isTextNode())
return String();
- const Text* textNode = toText(node);
+ const Text& textNode = toText(node);
unsigned startOffset = 0;
- unsigned endOffset = textNode->length();
+ unsigned endOffset = textNode.length();
if (range && node == range->startContainer())
startOffset = range->startOffset();
if (range && node == range->endContainer())
endOffset = range->endOffset();
- Position start = createLegacyEditingPosition(const_cast<Node*>(node), startOffset);
- Position end = createLegacyEditingPosition(const_cast<Node*>(node), endOffset);
- return plainText(Range::create(node->document(), start, end).get());
+ Position start = createLegacyEditingPosition(&node, startOffset);
+ Position end = createLegacyEditingPosition(&node, endOffset);
+ return plainText(Range::create(node.document(), start, end).get());
}
-String StyledMarkupAccumulator::stringValueForRange(const Node* node, const Range* range)
+String StyledMarkupAccumulator::stringValueForRange(const Node& node, const Range* range)
{
if (!range)
- return node->nodeValue();
+ return node.nodeValue();
- String str = node->nodeValue();
+ String str = node.nodeValue();
if (node == range->endContainer())
str.truncate(range->endOffset());
if (node == range->startContainer())
@@ -274,38 +281,41 @@ String StyledMarkupAccumulator::stringValueForRange(const Node* node, const Rang
return str;
}
-void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element* element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
+void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element& element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
{
- const bool documentIsHTML = element->document().isHTMLDocument();
+ const bool documentIsHTML = element.document().isHTMLDocument();
appendOpenTag(out, element, 0);
- const unsigned length = element->hasAttributes() ? element->attributeCount() : 0;
- const bool shouldAnnotateOrForceInline = element->isHTMLElement() && (shouldAnnotate() || addDisplayInline);
+ const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldAnnotate() || addDisplayInline);
const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element);
- for (unsigned i = 0; i < length; ++i) {
- const Attribute* attribute = element->attributeItem(i);
- // We'll handle the style attribute separately, below.
- if (attribute->name() == styleAttr && shouldOverrideStyleAttr)
- continue;
- appendAttribute(out, element, *attribute, 0);
+
+ if (element.hasAttributes()) {
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ // We'll handle the style attribute separately, below.
+ if (it->name() == styleAttr && shouldOverrideStyleAttr)
+ continue;
+ appendAttribute(out, element, *it, 0);
+ }
}
if (shouldOverrideStyleAttr) {
- RefPtr<EditingStyle> newInlineStyle;
+ RefPtrWillBeRawPtr<EditingStyle> newInlineStyle = nullptr;
if (shouldApplyWrappingStyle(element)) {
newInlineStyle = m_wrappingStyle->copy();
- newInlineStyle->removePropertiesInElementDefaultStyle(element);
- newInlineStyle->removeStyleConflictingWithStyleOfNode(element);
+ newInlineStyle->removePropertiesInElementDefaultStyle(&element);
+ newInlineStyle->removeStyleConflictingWithStyleOfNode(&element);
} else
newInlineStyle = EditingStyle::create();
- if (element->isStyledElement() && element->inlineStyle())
- newInlineStyle->overrideWithStyle(element->inlineStyle());
+ if (element.isStyledElement() && element.inlineStyle())
+ newInlineStyle->overrideWithStyle(element.inlineStyle());
if (shouldAnnotateOrForceInline) {
if (shouldAnnotate())
- newInlineStyle->mergeStyleFromRulesForSerialization(toHTMLElement(element));
+ newInlineStyle->mergeStyleFromRulesForSerialization(&toHTMLElement(element));
if (addDisplayInline)
newInlineStyle->forceInline();
@@ -342,7 +352,7 @@ Node* StyledMarkupAccumulator::serializeNodes(Node* startNode, Node* pastEnd)
Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTraversalMode traversalMode)
{
const bool shouldEmit = traversalMode == EmitString;
- Vector<Node*> ancestorsToClose;
+ WillBeHeapVector<RawPtrWillBeMember<Node> > ancestorsToClose;
Node* next;
Node* lastClosed = 0;
for (Node* n = startNode; n != pastEnd; n = next) {
@@ -369,12 +379,12 @@ Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No
} else {
// Add the node to the markup if we're not skipping the descendants
if (shouldEmit)
- appendStartTag(n);
+ appendStartTag(*n);
// If node has no children, close the tag now.
- if (!n->childNodeCount()) {
+ if (!n->hasChildren()) {
if (shouldEmit)
- appendEndTag(n);
+ appendEndTag(*n);
lastClosed = n;
} else {
openedTag = true;
@@ -388,11 +398,12 @@ Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No
// Close up the ancestors.
while (!ancestorsToClose.isEmpty()) {
Node* ancestor = ancestorsToClose.last();
+ ASSERT(ancestor);
if (next != pastEnd && next->isDescendantOf(ancestor))
break;
// Not at the end of the range, close ancestors up to sibling of next node.
if (shouldEmit)
- appendEndTag(ancestor);
+ appendEndTag(*ancestor);
lastClosed = ancestor;
ancestorsToClose.removeLast();
}
@@ -408,7 +419,7 @@ Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No
// or b) ancestors that we never encountered during a pre-order traversal starting at startNode:
ASSERT(startNode->isDescendantOf(parent));
if (shouldEmit)
- wrapWithNode(parent);
+ wrapWithNode(*parent);
lastClosed = parent;
}
}
@@ -420,8 +431,8 @@ Node* StyledMarkupAccumulator::traverseNodesForSerialization(Node* startNode, No
static bool isHTMLBlockElement(const Node* node)
{
- return node->hasTagName(tdTag)
- || node->hasTagName(thTag)
+ ASSERT(node);
+ return isHTMLTableCellElement(*node)
|| isNonTableCellHTMLBlockElement(node);
}
@@ -430,9 +441,9 @@ static Node* ancestorToRetainStructureAndAppearanceForBlock(Node* commonAncestor
if (!commonAncestorBlock)
return 0;
- if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTagName(trTag)) {
+ if (commonAncestorBlock->hasTagName(tbodyTag) || isHTMLTableRowElement(*commonAncestorBlock)) {
ContainerNode* table = commonAncestorBlock->parentNode();
- while (table && !isHTMLTableElement(table))
+ while (table && !isHTMLTableElement(*table))
table = table->parentNode();
return table;
@@ -459,7 +470,7 @@ static bool propertyMissingOrEqualToNone(StylePropertySet* style, CSSPropertyID
{
if (!style)
return false;
- RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
+ RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
if (!value)
return true;
if (!value->isPrimitiveValue())
@@ -473,18 +484,18 @@ static bool needInterchangeNewlineAfter(const VisiblePosition& v)
Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode();
Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode();
// Add an interchange newline if a paragraph break is selected and a br won't already be added to the markup to represent it.
- return isEndOfParagraph(v) && isStartOfParagraph(next) && !(upstreamNode->hasTagName(brTag) && upstreamNode == downstreamNode);
+ return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement(*upstreamNode) && upstreamNode == downstreamNode);
}
-static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* node)
+static PassRefPtrWillBeRawPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* node)
{
if (!node->isHTMLElement())
- return 0;
+ return nullptr;
// FIXME: Having to const_cast here is ugly, but it is quite a bit of work to untangle
// the non-const-ness of styleFromMatchedRulesForElement.
HTMLElement* element = const_cast<HTMLElement*>(toHTMLElement(node));
- RefPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle());
+ RefPtrWillBeRawPtr<EditingStyle> style = EditingStyle::create(element->inlineStyle());
style->mergeStyleFromRules(element);
return style.release();
}
@@ -497,7 +508,7 @@ static bool isElementPresentational(const Node* node)
static Node* highestAncestorToWrapMarkup(const Range* range, EAnnotateForInterchange shouldAnnotate, Node* constrainingAncestor)
{
- Node* commonAncestor = range->commonAncestorContainer(IGNORE_EXCEPTION);
+ Node* commonAncestor = range->commonAncestorContainer();
ASSERT(commonAncestor);
Node* specialCommonAncestor = 0;
if (shouldAnnotate == AnnotateForInterchange) {
@@ -542,17 +553,17 @@ static Node* highestAncestorToWrapMarkup(const Range* range, EAnnotateForInterch
// FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange?
// FIXME: At least, annotation and style info should probably not be included in range.markupString()
-static String createMarkupInternal(Document& document, const Range* range, const Range* updatedRange, Vector<Node*>* nodes,
+static String createMarkupInternal(Document& document, const Range* range, const Range* updatedRange, WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes,
EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs, Node* constrainingAncestor)
{
ASSERT(range);
ASSERT(updatedRange);
DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, ("<br class=\"" AppleInterchangeNewline "\">"));
- bool collapsed = updatedRange->collapsed(ASSERT_NO_EXCEPTION);
+ bool collapsed = updatedRange->collapsed();
if (collapsed)
return emptyString();
- Node* commonAncestor = updatedRange->commonAncestorContainer(ASSERT_NO_EXCEPTION);
+ Node* commonAncestor = updatedRange->commonAncestorContainer();
if (!commonAncestor)
return emptyString();
@@ -587,7 +598,7 @@ static String createMarkupInternal(Document& document, const Range* range, const
// Also include all of the ancestors of lastClosed up to this special ancestor.
for (ContainerNode* ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
- RefPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
+ RefPtrWillBeRawPtr<EditingStyle> fullySelectedRootStyle = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
// Bring the background attribute over, but not as an attribute because a background attribute on a div
// appears to have no effect.
@@ -603,18 +614,16 @@ static String createMarkupInternal(Document& document, const Range* range, const
fullySelectedRootStyle->style()->setProperty(CSSPropertyTextDecoration, CSSValueNone);
if (!propertyMissingOrEqualToNone(fullySelectedRootStyle->style(), CSSPropertyWebkitTextDecorationsInEffect))
fullySelectedRootStyle->style()->setProperty(CSSPropertyWebkitTextDecorationsInEffect, CSSValueNone);
- accumulator.wrapWithStyleNode(fullySelectedRootStyle->style(), &document, true);
+ accumulator.wrapWithStyleNode(fullySelectedRootStyle->style(), document, true);
}
} else {
// Since this node and all the other ancestors are not in the selection we want to set RangeFullySelectsNode to DoesNotFullySelectNode
// so that styles that affect the exterior of the node are not included.
- accumulator.wrapWithNode(ancestor, convertBlocksToInlines, StyledMarkupAccumulator::DoesNotFullySelectNode);
+ accumulator.wrapWithNode(*ancestor, convertBlocksToInlines, StyledMarkupAccumulator::DoesNotFullySelectNode);
}
if (nodes)
nodes->append(ancestor);
- lastClosed = ancestor;
-
if (ancestor == specialCommonAncestor)
break;
}
@@ -627,7 +636,7 @@ static String createMarkupInternal(Document& document, const Range* range, const
return accumulator.takeResults();
}
-String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs, Node* constrainingAncestor)
+String createMarkup(const Range* range, WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs, Node* constrainingAncestor)
{
if (!range)
return emptyString();
@@ -638,11 +647,11 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
return createMarkupInternal(document, range, updatedRange, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs, constrainingAncestor);
}
-PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy)
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy)
{
// We use a fake body element here to trick the HTML parser to using the InBody insertion mode.
- RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document);
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
+ RefPtrWillBeRawPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document);
fragment->parseHTML(markup, fakeBody.get(), parserContentPolicy);
@@ -654,7 +663,7 @@ PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document& document, const
static const char fragmentMarkerTag[] = "webkit-fragment-marker";
-static bool findNodesSurroundingContext(Document* document, RefPtr<Node>& nodeBeforeContext, RefPtr<Node>& nodeAfterContext)
+static bool findNodesSurroundingContext(Document* document, RefPtrWillBeRawPtr<Node>& nodeBeforeContext, RefPtrWillBeRawPtr<Node>& nodeAfterContext)
{
for (Node* node = document->firstChild(); node; node = NodeTraversal::next(*node)) {
if (node->nodeType() == Node::COMMENT_NODE && toCharacterData(node)->data() == fragmentMarkerTag) {
@@ -671,8 +680,8 @@ static bool findNodesSurroundingContext(Document* document, RefPtr<Node>& nodeBe
static void trimFragment(DocumentFragment* fragment, Node* nodeBeforeContext, Node* nodeAfterContext)
{
- RefPtr<Node> next;
- for (RefPtr<Node> node = fragment->firstChild(); node; node = next) {
+ RefPtrWillBeRawPtr<Node> next = nullptr;
+ for (RefPtrWillBeRawPtr<Node> node = fragment->firstChild(); node; node = next) {
if (nodeBeforeContext->isDescendantOf(node.get())) {
next = NodeTraversal::next(*node);
continue;
@@ -685,13 +694,13 @@ static void trimFragment(DocumentFragment* fragment, Node* nodeBeforeContext, No
}
ASSERT(nodeAfterContext->parentNode());
- for (RefPtr<Node> node = nodeAfterContext; node; node = next) {
+ for (RefPtrWillBeRawPtr<Node> node = nodeAfterContext; node; node = next) {
next = NodeTraversal::nextSkippingChildren(*node);
node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION);
}
}
-PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document& document, const String& markup, unsigned fragmentStart, unsigned fragmentEnd,
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document& document, const String& markup, unsigned fragmentStart, unsigned fragmentEnd,
const String& baseURL, ParserContentPolicy parserContentPolicy)
{
// FIXME: Need to handle the case where the markup already contains these markers.
@@ -703,30 +712,30 @@ PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document& docum
MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag);
taggedMarkup.append(markup.substring(fragmentEnd));
- RefPtr<DocumentFragment> taggedFragment = createFragmentFromMarkup(document, taggedMarkup.toString(), baseURL, parserContentPolicy);
- RefPtr<Document> taggedDocument = Document::create();
+ RefPtrWillBeRawPtr<DocumentFragment> taggedFragment = createFragmentFromMarkup(document, taggedMarkup.toString(), baseURL, parserContentPolicy);
+ RefPtrWillBeRawPtr<Document> taggedDocument = Document::create();
taggedDocument->setContextFeatures(document.contextFeatures());
// FIXME: It's not clear what this code is trying to do. It puts nodes as direct children of a
// Document that are not normally allowed by using the parser machinery.
taggedDocument->parserTakeAllChildrenFrom(*taggedFragment);
- RefPtr<Node> nodeBeforeContext;
- RefPtr<Node> nodeAfterContext;
+ RefPtrWillBeRawPtr<Node> nodeBeforeContext = nullptr;
+ RefPtrWillBeRawPtr<Node> nodeAfterContext = nullptr;
if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, nodeAfterContext))
- return 0;
+ return nullptr;
- RefPtr<Range> range = Range::create(*taggedDocument.get(),
+ RefPtrWillBeRawPtr<Range> range = Range::create(*taggedDocument.get(),
positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(),
positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent());
- Node* commonAncestor = range->commonAncestorContainer(ASSERT_NO_EXCEPTION);
+ Node* commonAncestor = range->commonAncestorContainer();
Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRenderer(commonAncestor);
// When there's a special common ancestor outside of the fragment, we must include it as well to
// preserve the structure and appearance of the fragment. For example, if the fragment contains
// TD, we need to include the enclosing TABLE tag as well.
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document);
if (specialCommonAncestor)
fragment->appendChild(specialCommonAncestor);
else
@@ -737,13 +746,13 @@ PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document& docum
return fragment;
}
-String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip)
+String createMarkup(const Node* node, EChildrenOnly childrenOnly, WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip)
{
if (!node)
return "";
MarkupAccumulator accumulator(nodes, shouldResolveURLs);
- return accumulator.serializeNodes(const_cast<Node*>(node), childrenOnly, tagNamesToSkip);
+ return accumulator.serializeNodes(const_cast<Node&>(*node), childrenOnly, tagNamesToSkip);
}
static void fillContainerFromString(ContainerNode* paragraph, const String& string)
@@ -759,7 +768,7 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
Vector<String> tabList;
string.split('\t', true, tabList);
- String tabText = emptyString();
+ StringBuilder tabText;
bool first = true;
size_t numEntries = tabList.size();
for (size_t i = 0; i < numEntries; ++i) {
@@ -768,10 +777,10 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
// append the non-tab textual part
if (!s.isEmpty()) {
if (!tabText.isEmpty()) {
- paragraph->appendChild(createTabSpanElement(document, tabText));
- tabText = emptyString();
+ paragraph->appendChild(createTabSpanElement(document, tabText.toString()));
+ tabText.clear();
}
- RefPtr<Node> textNode = document.createTextNode(stringWithRebalancedWhitespace(s, first, i + 1 == numEntries));
+ RefPtrWillBeRawPtr<Node> textNode = document.createTextNode(stringWithRebalancedWhitespace(s, first, i + 1 == numEntries));
paragraph->appendChild(textNode.release());
}
@@ -780,21 +789,26 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
if (i + 1 != numEntries)
tabText.append('\t');
else if (!tabText.isEmpty())
- paragraph->appendChild(createTabSpanElement(document, tabText));
+ paragraph->appendChild(createTabSpanElement(document, tabText.toString()));
first = false;
}
}
-bool isPlainTextMarkup(Node *node)
+bool isPlainTextMarkup(Node* node)
{
- if (!node->isElementNode() || !node->hasTagName(divTag) || toElement(node)->hasAttributes())
+ ASSERT(node);
+ if (!node->isElementNode())
+ return false;
+
+ Element* element = toElement(node);
+ if (!isHTMLDivElement(*element) || !element->hasAttributes())
return false;
- if (node->childNodeCount() == 1 && (node->firstChild()->isTextNode() || (node->firstChild()->firstChild())))
+ if (element->hasOneChild() && (element->firstChild()->isTextNode() || (element->firstChild()->firstChild())))
return true;
- return (node->childNodeCount() == 2 && isTabSpanTextNode(node->firstChild()->firstChild()) && node->firstChild()->nextSibling()->isTextNode());
+ return element->hasChildCount(2) && isTabSpanTextNode(element->firstChild()->firstChild()) && element->lastChild()->isTextNode();
}
static bool shouldPreserveNewline(const Range& range)
@@ -812,13 +826,13 @@ static bool shouldPreserveNewline(const Range& range)
return false;
}
-PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text)
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text)
{
if (!context)
- return 0;
+ return nullptr;
Document& document = context->ownerDocument();
- RefPtr<DocumentFragment> fragment = document.createDocumentFragment();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = document.createDocumentFragment();
if (text.isEmpty())
return fragment.release();
@@ -830,7 +844,7 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
if (shouldPreserveNewline(*context)) {
fragment->appendChild(document.createTextNode(string));
if (string.endsWith('\n')) {
- RefPtr<Element> element = createBreakElement(document);
+ RefPtrWillBeRawPtr<Element> element = createBreakElement(document);
element->setAttribute(classAttr, AppleInterchangeNewline);
fragment->appendChild(element.release());
}
@@ -848,8 +862,8 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
Element* block = toElement(blockNode);
bool useClonesOfEnclosingBlock = blockNode
&& blockNode->isElementNode()
- && !block->hasTagName(bodyTag)
- && !isHTMLHtmlElement(block)
+ && !isHTMLBodyElement(*block)
+ && !isHTMLHtmlElement(*block)
&& block != editableRootForPosition(context->startPosition());
bool useLineBreak = enclosingTextFormControl(context->startPosition());
@@ -859,7 +873,7 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
for (size_t i = 0; i < numLines; ++i) {
const String& s = list[i];
- RefPtr<Element> element;
+ RefPtrWillBeRawPtr<Element> element = nullptr;
if (s.isEmpty() && i + 1 == numLines) {
// For last line, use the "magic BR" rather than a P.
element = createBreakElement(document);
@@ -879,73 +893,40 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
return fragment.release();
}
-PassRefPtr<DocumentFragment> createFragmentFromNodes(Document *document, const Vector<Node*>& nodes)
-{
- if (!document)
- return 0;
-
- RefPtr<DocumentFragment> fragment = document->createDocumentFragment();
-
- size_t size = nodes.size();
- for (size_t i = 0; i < size; ++i) {
- RefPtr<Element> element = createDefaultParagraphElement(*document);
- element->appendChild(nodes[i]);
- fragment->appendChild(element.release());
- }
-
- return fragment.release();
-}
-
String createFullMarkup(const Node* node)
{
if (!node)
return String();
- Frame* frame = node->document().frame();
+ LocalFrame* frame = node->document().frame();
if (!frame)
return String();
// FIXME: This is never "for interchange". Is that right?
String markupString = createMarkup(node, IncludeNode, 0);
Node::NodeType nodeType = node->nodeType();
- if (nodeType != Node::DOCUMENT_NODE && nodeType != Node::DOCUMENT_TYPE_NODE)
+ if (nodeType != Node::DOCUMENT_NODE && !node->isDocumentTypeNode())
markupString = frame->documentTypeString() + markupString;
return markupString;
}
-String createFullMarkup(const Range* range)
-{
- if (!range)
- return String();
-
- Node* node = range->startContainer();
- if (!node)
- return String();
-
- Frame* frame = node->document().frame();
- if (!frame)
- return String();
-
- // FIXME: This is always "for interchange". Is that right? See the previous method.
- return frame->documentTypeString() + createMarkup(range, 0, AnnotateForInterchange);
-}
-
String urlToMarkup(const KURL& url, const String& title)
{
StringBuilder markup;
- markup.append("<a href=\"");
+ markup.appendLiteral("<a href=\"");
markup.append(url.string());
- markup.append("\">");
+ markup.appendLiteral("\">");
MarkupAccumulator::appendCharactersReplacingEntities(markup, title, 0, title.length(), EntityMaskInPCDATA);
- markup.append("</a>");
+ markup.appendLiteral("</a>");
return markup.toString();
}
-PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, ParserContentPolicy parserContentPolicy, const char* method, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, ParserContentPolicy parserContentPolicy, const char* method, ExceptionState& exceptionState)
{
- Document& document = contextElement->hasTagName(templateTag) ? contextElement->document().ensureTemplateDocument() : contextElement->document();
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
+ ASSERT(contextElement);
+ Document& document = isHTMLTemplateElement(*contextElement) ? contextElement->document().ensureTemplateDocument() : contextElement->document();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document);
if (document.isHTMLDocument()) {
fragment->parseHTML(markup, contextElement, parserContentPolicy);
@@ -955,28 +936,28 @@ PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& marku
bool wasValid = fragment->parseXML(markup, contextElement, parserContentPolicy);
if (!wasValid) {
exceptionState.throwDOMException(SyntaxError, "The provided markup is invalid XML, and therefore cannot be inserted into an XML document.");
- return 0;
+ return nullptr;
}
return fragment.release();
}
-PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String& sourceString, const String& sourceMIMEType, Document& outputDoc)
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForTransformToFragment(const String& sourceString, const String& sourceMIMEType, Document& outputDoc)
{
- RefPtr<DocumentFragment> fragment = outputDoc.createDocumentFragment();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = outputDoc.createDocumentFragment();
if (sourceMIMEType == "text/html") {
// As far as I can tell, there isn't a spec for how transformToFragment is supposed to work.
// Based on the documentation I can find, it looks like we want to start parsing the fragment in the InBody insertion mode.
// Unfortunately, that's an implementation detail of the parser.
// We achieve that effect here by passing in a fake body element as context for the fragment.
- RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc);
+ RefPtrWillBeRawPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(outputDoc);
fragment->parseHTML(sourceString, fakeBody.get());
} else if (sourceMIMEType == "text/plain") {
fragment->parserAppendChild(Text::create(outputDoc, sourceString));
} else {
bool successfulParse = fragment->parseXML(sourceString, 0);
if (!successfulParse)
- return 0;
+ return nullptr;
}
// FIXME: Do we need to mess with URLs here?
@@ -984,10 +965,10 @@ PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String&
return fragment.release();
}
-static inline void removeElementPreservingChildren(PassRefPtr<DocumentFragment> fragment, HTMLElement* element)
+static inline void removeElementPreservingChildren(PassRefPtrWillBeRawPtr<DocumentFragment> fragment, HTMLElement* element)
{
- RefPtr<Node> nextChild;
- for (RefPtr<Node> child = element->firstChild(); child; child = nextChild) {
+ RefPtrWillBeRawPtr<Node> nextChild = nullptr;
+ for (RefPtrWillBeRawPtr<Node> child = element->firstChild(); child; child = nextChild) {
nextChild = child->nextSibling();
element->removeChild(child.get());
fragment->insertBefore(child, element);
@@ -995,27 +976,27 @@ static inline void removeElementPreservingChildren(PassRefPtr<DocumentFragment>
fragment->removeChild(element);
}
-PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTMLElement* element, ParserContentPolicy parserContentPolicy, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> createContextualFragment(const String& markup, HTMLElement* element, ParserContentPolicy parserContentPolicy, ExceptionState& exceptionState)
{
ASSERT(element);
if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || element->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag)
|| element->hasLocalName(headTag) || element->hasLocalName(styleTag) || element->hasLocalName(titleTag)) {
exceptionState.throwDOMException(NotSupportedError, "The range's container is '" + element->localName() + "', which is not supported.");
- return 0;
+ return nullptr;
}
- RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, element, parserContentPolicy, "createContextualFragment", exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, element, parserContentPolicy, "createContextualFragment", exceptionState);
if (!fragment)
- return 0;
+ return nullptr;
// We need to pop <html> and <body> elements and remove <head> to
// accommodate folks passing complete HTML documents to make the
// child of an element.
- RefPtr<Node> nextNode;
- for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) {
+ RefPtrWillBeRawPtr<Node> nextNode = nullptr;
+ for (RefPtrWillBeRawPtr<Node> node = fragment->firstChild(); node; node = nextNode) {
nextNode = node->nextSibling();
- if (isHTMLHtmlElement(node.get()) || node->hasTagName(headTag) || node->hasTagName(bodyTag)) {
+ if (isHTMLHtmlElement(*node) || isHTMLHeadElement(*node) || isHTMLBodyElement(*node)) {
HTMLElement* element = toHTMLElement(node);
if (Node* firstChild = element->firstChild())
nextNode = firstChild;
@@ -1025,10 +1006,10 @@ PassRefPtr<DocumentFragment> createContextualFragment(const String& markup, HTML
return fragment.release();
}
-void replaceChildrenWithFragment(ContainerNode* container, PassRefPtr<DocumentFragment> fragment, ExceptionState& exceptionState)
+void replaceChildrenWithFragment(ContainerNode* container, PassRefPtrWillBeRawPtr<DocumentFragment> fragment, ExceptionState& exceptionState)
{
ASSERT(container);
- RefPtr<ContainerNode> containerNode(container);
+ RefPtrWillBeRawPtr<ContainerNode> containerNode(container);
ChildListMutationScope mutation(*containerNode);
@@ -1037,11 +1018,13 @@ void replaceChildrenWithFragment(ContainerNode* container, PassRefPtr<DocumentFr
return;
}
+ // FIXME: This is wrong if containerNode->firstChild() has more than one ref!
if (containerNode->hasOneTextChild() && fragment->hasOneTextChild()) {
toText(containerNode->firstChild())->setData(toText(fragment->firstChild())->data());
return;
}
+ // FIXME: No need to replace the child it is a text node and its contents are already == text.
if (containerNode->hasOneChild()) {
containerNode->replaceChild(fragment, containerNode->firstChild(), exceptionState);
return;
@@ -1054,17 +1037,29 @@ void replaceChildrenWithFragment(ContainerNode* container, PassRefPtr<DocumentFr
void replaceChildrenWithText(ContainerNode* container, const String& text, ExceptionState& exceptionState)
{
ASSERT(container);
- RefPtr<ContainerNode> containerNode(container);
+ RefPtrWillBeRawPtr<ContainerNode> containerNode(container);
ChildListMutationScope mutation(*containerNode);
+ // FIXME: This is wrong if containerNode->firstChild() has more than one ref! Example:
+ // <div>foo</div>
+ // <script>
+ // var oldText = div.firstChild;
+ // console.log(oldText.data); // foo
+ // div.innerText = "bar";
+ // console.log(oldText.data); // bar!?!
+ // </script>
+ // I believe this is an intentional benchmark cheat from years ago.
+ // We should re-visit if we actually want this still.
if (containerNode->hasOneTextChild()) {
toText(containerNode->firstChild())->setData(text);
return;
}
- RefPtr<Text> textNode = Text::create(containerNode->document(), text);
+ // NOTE: This method currently always creates a text node, even if that text node will be empty.
+ RefPtrWillBeRawPtr<Text> textNode = Text::create(containerNode->document(), text);
+ // FIXME: No need to replace the child it is a text node and its contents are already == text.
if (containerNode->hasOneChild()) {
containerNode->replaceChild(textNode.release(), containerNode->firstChild(), exceptionState);
return;
@@ -1074,15 +1069,15 @@ void replaceChildrenWithText(ContainerNode* container, const String& text, Excep
containerNode->appendChild(textNode.release(), exceptionState);
}
-void mergeWithNextTextNode(PassRefPtr<Node> node, ExceptionState& exceptionState)
+void mergeWithNextTextNode(PassRefPtrWillBeRawPtr<Node> node, ExceptionState& exceptionState)
{
ASSERT(node && node->isTextNode());
Node* next = node->nextSibling();
if (!next || !next->isTextNode())
return;
- RefPtr<Text> textNode = toText(node.get());
- RefPtr<Text> textNext = toText(next);
+ RefPtrWillBeRawPtr<Text> textNode = toText(node.get());
+ RefPtrWillBeRawPtr<Text> textNext = toText(next);
textNode->appendData(textNext->data());
if (textNext->parentNode()) // Might have been removed by mutation event.
textNext->remove(exceptionState);
diff --git a/chromium/third_party/WebKit/Source/core/editing/markup.h b/chromium/third_party/WebKit/Source/core/editing/markup.h
index f12209269e9..32819bdcb71 100644
--- a/chromium/third_party/WebKit/Source/core/editing/markup.h
+++ b/chromium/third_party/WebKit/Source/core/editing/markup.h
@@ -28,6 +28,7 @@
#include "core/dom/ParserContentPolicy.h"
#include "core/editing/HTMLInterchange.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/Vector.h"
@@ -47,29 +48,27 @@ class Range;
enum EChildrenOnly { IncludeNode, ChildrenOnly };
enum EAbsoluteURLs { DoNotResolveURLs, ResolveAllURLs, ResolveNonLocalURLs };
-PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text);
-PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document&, const String& markup, const String& baseURL, ParserContentPolicy = AllowScriptingContent);
-PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document&, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, const String& baseURL, ParserContentPolicy);
-PassRefPtr<DocumentFragment> createFragmentFromNodes(Document*, const Vector<Node*>&);
-PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String&, Element*, ParserContentPolicy, const char* method, ExceptionState&);
-PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String&, const String& sourceMIMEType, Document& outputDoc);
-PassRefPtr<DocumentFragment> createContextualFragment(const String&, HTMLElement*, ParserContentPolicy, ExceptionState&);
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text);
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkup(Document&, const String& markup, const String& baseURL, ParserContentPolicy = AllowScriptingContent);
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document&, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, const String& baseURL, ParserContentPolicy);
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String&, Element*, ParserContentPolicy, const char* method, ExceptionState&);
+PassRefPtrWillBeRawPtr<DocumentFragment> createFragmentForTransformToFragment(const String&, const String& sourceMIMEType, Document& outputDoc);
+PassRefPtrWillBeRawPtr<DocumentFragment> createContextualFragment(const String&, HTMLElement*, ParserContentPolicy, ExceptionState&);
bool isPlainTextMarkup(Node*);
// These methods are used by HTMLElement & ShadowRoot to replace the
// children with respected fragment/text.
-void replaceChildrenWithFragment(ContainerNode*, PassRefPtr<DocumentFragment>, ExceptionState&);
+void replaceChildrenWithFragment(ContainerNode*, PassRefPtrWillBeRawPtr<DocumentFragment>, ExceptionState&);
void replaceChildrenWithText(ContainerNode*, const String&, ExceptionState&);
-String createMarkup(const Range*, Vector<Node*>* = 0, EAnnotateForInterchange = DoNotAnnotateForInterchange, bool convertBlocksToInlines = false, EAbsoluteURLs = DoNotResolveURLs, Node* constrainingAncestor = 0);
-String createMarkup(const Node*, EChildrenOnly = IncludeNode, Vector<Node*>* = 0, EAbsoluteURLs = DoNotResolveURLs, Vector<QualifiedName>* tagNamesToSkip = 0);
+String createMarkup(const Range*, WillBeHeapVector<RawPtrWillBeMember<Node> >* = 0, EAnnotateForInterchange = DoNotAnnotateForInterchange, bool convertBlocksToInlines = false, EAbsoluteURLs = DoNotResolveURLs, Node* constrainingAncestor = 0);
+String createMarkup(const Node*, EChildrenOnly = IncludeNode, WillBeHeapVector<RawPtrWillBeMember<Node> >* = 0, EAbsoluteURLs = DoNotResolveURLs, Vector<QualifiedName>* tagNamesToSkip = 0);
String createFullMarkup(const Node*);
-String createFullMarkup(const Range*);
String urlToMarkup(const KURL&, const String& title);
-void mergeWithNextTextNode(PassRefPtr<Node>, ExceptionState&);
+void mergeWithNextTextNode(PassRefPtrWillBeRawPtr<Node>, ExceptionState&);
}
diff --git a/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.cpp b/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.cpp
new file mode 100644
index 00000000000..206e2c16b65
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.cpp
@@ -0,0 +1,63 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/events/AnimationPlayerEvent.h"
+
+namespace WebCore {
+
+AnimationPlayerEventInit::AnimationPlayerEventInit()
+ : currentTime(0.0)
+ , timelineTime(0.0)
+{
+}
+
+AnimationPlayerEvent::AnimationPlayerEvent()
+ : m_currentTime(0.0)
+ , m_timelineTime(0.0)
+{
+ ScriptWrappable::init(this);
+}
+
+AnimationPlayerEvent::AnimationPlayerEvent(const AtomicString& type, double currentTime, double timelineTime)
+ : Event(type, false, false)
+ , m_currentTime(currentTime)
+ , m_timelineTime(timelineTime)
+{
+ ScriptWrappable::init(this);
+}
+
+AnimationPlayerEvent::AnimationPlayerEvent(const AtomicString& type, const AnimationPlayerEventInit& initializer)
+ : Event(type, initializer)
+ , m_currentTime(initializer.currentTime)
+ , m_timelineTime(initializer.timelineTime)
+{
+ ScriptWrappable::init(this);
+}
+
+AnimationPlayerEvent::~AnimationPlayerEvent()
+{
+}
+
+double AnimationPlayerEvent::currentTime() const
+{
+ return m_currentTime;
+}
+
+double AnimationPlayerEvent::timelineTime() const
+{
+ return m_timelineTime;
+}
+
+const AtomicString& AnimationPlayerEvent::interfaceName() const
+{
+ return EventNames::AnimationPlayerEvent;
+}
+
+void AnimationPlayerEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.h b/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.h
new file mode 100644
index 00000000000..e19a85306c2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.h
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AnimationPlayerEvent_h
+#define AnimationPlayerEvent_h
+
+#include "core/events/Event.h"
+
+namespace WebCore {
+
+struct AnimationPlayerEventInit : public EventInit {
+ AnimationPlayerEventInit();
+
+ double currentTime;
+ double timelineTime;
+};
+
+class AnimationPlayerEvent FINAL : public Event {
+public:
+ static PassRefPtrWillBeRawPtr<AnimationPlayerEvent> create()
+ {
+ return adoptRefWillBeNoop(new AnimationPlayerEvent);
+ }
+ static PassRefPtrWillBeRawPtr<AnimationPlayerEvent> create(const AtomicString& type, double currentTime, double timelineTime)
+ {
+ return adoptRefWillBeNoop(new AnimationPlayerEvent(type, currentTime, timelineTime));
+ }
+ static PassRefPtrWillBeRawPtr<AnimationPlayerEvent> create(const AtomicString& type, const AnimationPlayerEventInit& initializer)
+ {
+ return adoptRefWillBeNoop(new AnimationPlayerEvent(type, initializer));
+ }
+
+ virtual ~AnimationPlayerEvent();
+
+ double currentTime() const;
+ double timelineTime() const;
+
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ AnimationPlayerEvent();
+ AnimationPlayerEvent(const AtomicString& type, double currentTime, double timelineTime);
+ AnimationPlayerEvent(const AtomicString&, const AnimationPlayerEventInit&);
+
+ double m_currentTime;
+ double m_timelineTime;
+};
+
+} // namespace WebCore
+
+#endif // AnimationPlayerEvent_h
diff --git a/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.idl b/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.idl
new file mode 100644
index 00000000000..a719ec75f0c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/AnimationPlayerEvent.idl
@@ -0,0 +1,12 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ EventConstructor,
+ RuntimeEnabled=WebAnimationsAPI,
+] interface AnimationPlayerEvent : Event {
+ [InitializedByEventConstructor] readonly attribute double currentTime;
+ [InitializedByEventConstructor] readonly attribute double timelineTime;
+};
+
diff --git a/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.cpp b/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.cpp
new file mode 100644
index 00000000000..2125f5afa14
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.cpp
@@ -0,0 +1,82 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/events/ApplicationCacheErrorEvent.h"
+
+namespace WebCore {
+
+static const String& errorReasonToString(blink::WebApplicationCacheHost::ErrorReason reason)
+{
+ DEFINE_STATIC_LOCAL(String, errorManifest, ("manifest"));
+ DEFINE_STATIC_LOCAL(String, errorSignature, ("signature"));
+ DEFINE_STATIC_LOCAL(String, errorResource, ("resource"));
+ DEFINE_STATIC_LOCAL(String, errorChanged, ("changed"));
+ DEFINE_STATIC_LOCAL(String, errorAbort, ("abort"));
+ DEFINE_STATIC_LOCAL(String, errorQuota, ("quota"));
+ DEFINE_STATIC_LOCAL(String, errorPolicy, ("policy"));
+ DEFINE_STATIC_LOCAL(String, errorUnknown, ("unknown"));
+
+ switch (reason) {
+ case blink::WebApplicationCacheHost::ManifestError:
+ return errorManifest;
+ case blink::WebApplicationCacheHost::SignatureError:
+ return errorSignature;
+ case blink::WebApplicationCacheHost::ResourceError:
+ return errorResource;
+ case blink::WebApplicationCacheHost::ChangedError:
+ return errorChanged;
+ case blink::WebApplicationCacheHost::AbortError:
+ return errorAbort;
+ case blink::WebApplicationCacheHost::QuotaError:
+ return errorQuota;
+ case blink::WebApplicationCacheHost::PolicyError:
+ return errorPolicy;
+ case blink::WebApplicationCacheHost::UnknownError:
+ return errorUnknown;
+ }
+ ASSERT_NOT_REACHED();
+ return emptyString();
+}
+
+ApplicationCacheErrorEventInit::ApplicationCacheErrorEventInit()
+ : status(0)
+{
+}
+
+ApplicationCacheErrorEvent::ApplicationCacheErrorEvent()
+{
+ ScriptWrappable::init(this);
+}
+
+ApplicationCacheErrorEvent::ApplicationCacheErrorEvent(blink::WebApplicationCacheHost::ErrorReason reason, const String& url, int status, const String& message)
+ : Event(EventTypeNames::error, false, false)
+ , m_reason(errorReasonToString(reason))
+ , m_url(url)
+ , m_status(status)
+ , m_message(message)
+{
+ ScriptWrappable::init(this);
+}
+
+ApplicationCacheErrorEvent::ApplicationCacheErrorEvent(const AtomicString& eventType, const ApplicationCacheErrorEventInit& initializer)
+ : Event(eventType, initializer)
+ , m_reason(initializer.reason)
+ , m_url(initializer.url)
+ , m_status(initializer.status)
+ , m_message(initializer.message)
+{
+ ScriptWrappable::init(this);
+}
+
+ApplicationCacheErrorEvent::~ApplicationCacheErrorEvent()
+{
+}
+
+void ApplicationCacheErrorEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.h b/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.h
new file mode 100644
index 00000000000..9ccad7eee31
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.h
@@ -0,0 +1,66 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ApplicationCacheErrorEvent_h
+#define ApplicationCacheErrorEvent_h
+
+#include "core/events/Event.h"
+#include "core/loader/appcache/ApplicationCacheHost.h"
+#include "public/platform/WebApplicationCacheHostClient.h"
+
+namespace WebCore {
+
+class ApplicationCacheErrorEvent;
+
+struct ApplicationCacheErrorEventInit : public EventInit {
+ ApplicationCacheErrorEventInit();
+
+ String reason;
+ String url;
+ int status;
+ String message;
+};
+
+class ApplicationCacheErrorEvent FINAL : public Event {
+public:
+ virtual ~ApplicationCacheErrorEvent();
+
+ static PassRefPtrWillBeRawPtr<ApplicationCacheErrorEvent> create()
+ {
+ return adoptRefWillBeNoop(new ApplicationCacheErrorEvent);
+ }
+
+ static PassRefPtrWillBeRawPtr<ApplicationCacheErrorEvent> create(blink::WebApplicationCacheHost::ErrorReason reason, const String& url, int status, const String& message)
+ {
+ return adoptRefWillBeNoop(new ApplicationCacheErrorEvent(reason, url, status, message));
+ }
+
+ static PassRefPtrWillBeRawPtr<ApplicationCacheErrorEvent> create(const AtomicString& eventType, const ApplicationCacheErrorEventInit& initializer)
+ {
+ return adoptRefWillBeNoop(new ApplicationCacheErrorEvent(eventType, initializer));
+ }
+
+ const String& reason() const { return m_reason; }
+ const String& url() const { return m_url; }
+ int status() const { return m_status; }
+ const String& message() const { return m_message; }
+
+ virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::ApplicationCacheErrorEvent; }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ ApplicationCacheErrorEvent();
+ ApplicationCacheErrorEvent(blink::WebApplicationCacheHost::ErrorReason, const String& url, int status, const String& message);
+ ApplicationCacheErrorEvent(const AtomicString& eventType, const ApplicationCacheErrorEventInit& initializer);
+
+ String m_reason;
+ String m_url;
+ int m_status;
+ String m_message;
+};
+
+} // namespace WebCore
+
+#endif // ApplicationCacheErrorEvent_h
diff --git a/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.idl b/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.idl
new file mode 100644
index 00000000000..c69c3f7fe97
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/ApplicationCacheErrorEvent.idl
@@ -0,0 +1,12 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ EventConstructor,
+] interface ApplicationCacheErrorEvent : Event {
+ [InitializedByEventConstructor] readonly attribute DOMString reason;
+ [InitializedByEventConstructor] readonly attribute DOMString url;
+ [InitializedByEventConstructor] readonly attribute unsigned short status;
+ [InitializedByEventConstructor] readonly attribute DOMString message;
+};
diff --git a/chromium/third_party/WebKit/Source/core/events/AutocompleteErrorEvent.h b/chromium/third_party/WebKit/Source/core/events/AutocompleteErrorEvent.h
index 1eed01deb6f..ba4cefe9ae5 100644
--- a/chromium/third_party/WebKit/Source/core/events/AutocompleteErrorEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/AutocompleteErrorEvent.h
@@ -26,7 +26,6 @@
#define AutocompleteErrorEvent_h
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
@@ -34,26 +33,28 @@ struct AutocompleteErrorEventInit : public EventInit {
String reason;
};
-class AutocompleteErrorEvent : public Event {
+class AutocompleteErrorEvent FINAL : public Event {
public:
- static PassRefPtr<AutocompleteErrorEvent> create()
+ static PassRefPtrWillBeRawPtr<AutocompleteErrorEvent> create()
{
- return adoptRef(new AutocompleteErrorEvent);
+ return adoptRefWillBeNoop(new AutocompleteErrorEvent);
}
- static PassRefPtr<AutocompleteErrorEvent> create(const String& reason)
+ static PassRefPtrWillBeRawPtr<AutocompleteErrorEvent> create(const String& reason)
{
- return adoptRef(new AutocompleteErrorEvent(reason));
+ return adoptRefWillBeNoop(new AutocompleteErrorEvent(reason));
}
- static PassRefPtr<AutocompleteErrorEvent> create(const AtomicString& eventType, const AutocompleteErrorEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<AutocompleteErrorEvent> create(const AtomicString& eventType, const AutocompleteErrorEventInit& initializer)
{
- return adoptRef(new AutocompleteErrorEvent(eventType, initializer));
+ return adoptRefWillBeNoop(new AutocompleteErrorEvent(eventType, initializer));
}
const String& reason() const { return m_reason; }
- virtual const AtomicString& interfaceName() const { return EventNames::AutocompleteErrorEvent; }
+ virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::AutocompleteErrorEvent; }
+
+ virtual void trace(Visitor* visitor) OVERRIDE { Event::trace(visitor); }
private:
AutocompleteErrorEvent()
@@ -62,7 +63,7 @@ private:
}
AutocompleteErrorEvent(const String& reason)
- : Event(EventTypeNames::autocompleteerror, false, false)
+ : Event(EventTypeNames::autocompleteerror, true, false)
, m_reason(reason)
{
ScriptWrappable::init(this);
diff --git a/chromium/third_party/WebKit/Source/core/events/BeforeLoadEvent.h b/chromium/third_party/WebKit/Source/core/events/BeforeLoadEvent.h
deleted file mode 100644
index f52c5377f2a..00000000000
--- a/chromium/third_party/WebKit/Source/core/events/BeforeLoadEvent.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef BeforeLoadEvent_h
-#define BeforeLoadEvent_h
-
-#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
-
-namespace WebCore {
-
-struct BeforeLoadEventInit : public EventInit {
- BeforeLoadEventInit()
- {
- };
-
- String url;
-};
-
-class BeforeLoadEvent : public Event {
-public:
- static PassRefPtr<BeforeLoadEvent> create()
- {
- return adoptRef(new BeforeLoadEvent);
- }
-
- static PassRefPtr<BeforeLoadEvent> create(const String& url)
- {
- return adoptRef(new BeforeLoadEvent(url));
- }
-
- static PassRefPtr<BeforeLoadEvent> create(const AtomicString& type, const BeforeLoadEventInit& initializer)
- {
- return adoptRef(new BeforeLoadEvent(type, initializer));
- }
-
- const String& url() const { return m_url; }
-
- virtual const AtomicString& interfaceName() const { return EventNames::BeforeLoadEvent; }
-
-private:
- BeforeLoadEvent()
- {
- ScriptWrappable::init(this);
- }
-
- explicit BeforeLoadEvent(const String& url)
- : Event(EventTypeNames::beforeload, false, true)
- , m_url(url)
- {
- ScriptWrappable::init(this);
- }
-
- BeforeLoadEvent(const AtomicString& type, const BeforeLoadEventInit& initializer)
- : Event(type, initializer)
- , m_url(initializer.url)
- {
- ScriptWrappable::init(this);
- }
-
- String m_url;
-};
-
-} // namespace WebCore
-
-#endif // BeforeLoadEvent_h
diff --git a/chromium/third_party/WebKit/Source/core/events/BeforeLoadEvent.idl b/chromium/third_party/WebKit/Source/core/events/BeforeLoadEvent.idl
deleted file mode 100644
index 6f8eca6e654..00000000000
--- a/chromium/third_party/WebKit/Source/core/events/BeforeLoadEvent.idl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-[
- EventConstructor,
-] interface BeforeLoadEvent : Event {
- [InitializedByEventConstructor] readonly attribute DOMString url;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp b/chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp
index fc0ed37f5d1..c092ac1d222 100644
--- a/chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.cpp
@@ -26,8 +26,6 @@
#include "config.h"
#include "core/events/BeforeTextInsertedEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
BeforeTextInsertedEvent::BeforeTextInsertedEvent(const String& text)
@@ -45,4 +43,9 @@ const AtomicString& BeforeTextInsertedEvent::interfaceName() const
return EventNames::Event;
}
+void BeforeTextInsertedEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.h b/chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.h
index 546c4fb7364..d92dbb9232e 100644
--- a/chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/BeforeTextInsertedEvent.h
@@ -30,21 +30,23 @@
namespace WebCore {
-class BeforeTextInsertedEvent : public Event {
+class BeforeTextInsertedEvent FINAL : public Event {
public:
virtual ~BeforeTextInsertedEvent();
- static PassRefPtr<BeforeTextInsertedEvent> create(const String& text)
+ static PassRefPtrWillBeRawPtr<BeforeTextInsertedEvent> create(const String& text)
{
- return adoptRef(new BeforeTextInsertedEvent(text));
+ return adoptRefWillBeNoop(new BeforeTextInsertedEvent(text));
}
- virtual const AtomicString& interfaceName() const;
- virtual bool isBeforeTextInsertedEvent() const { return true; }
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+ virtual bool isBeforeTextInsertedEvent() const OVERRIDE { return true; }
const String& text() const { return m_text; }
void setText(const String& s) { m_text = s; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit BeforeTextInsertedEvent(const String&);
diff --git a/chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.cpp b/chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.cpp
index 15dd1ad9520..06993cd557d 100644
--- a/chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.cpp
@@ -42,4 +42,9 @@ bool BeforeUnloadEvent::isBeforeUnloadEvent() const
return true;
}
+void BeforeUnloadEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.h b/chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.h
index 57136f92ae8..5c5b4f90edb 100644
--- a/chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/BeforeUnloadEvent.h
@@ -26,17 +26,16 @@
#define BeforeUnloadEvent_h
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
-class BeforeUnloadEvent : public Event {
+class BeforeUnloadEvent FINAL : public Event {
public:
virtual ~BeforeUnloadEvent();
- static PassRefPtr<BeforeUnloadEvent> create()
+ static PassRefPtrWillBeRawPtr<BeforeUnloadEvent> create()
{
- return adoptRef(new BeforeUnloadEvent);
+ return adoptRefWillBeNoop(new BeforeUnloadEvent);
}
virtual bool isBeforeUnloadEvent() const OVERRIDE;
@@ -46,6 +45,8 @@ public:
virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::BeforeUnloadEvent; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
BeforeUnloadEvent();
diff --git a/chromium/third_party/WebKit/Source/core/events/ClipboardEvent.cpp b/chromium/third_party/WebKit/Source/core/events/ClipboardEvent.cpp
index a8fa4f96699..72d5b1867b3 100644
--- a/chromium/third_party/WebKit/Source/core/events/ClipboardEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/ClipboardEvent.cpp
@@ -23,8 +23,7 @@
#include "config.h"
#include "core/events/ClipboardEvent.h"
-#include "core/dom/Clipboard.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/clipboard/Clipboard.h"
namespace WebCore {
@@ -32,7 +31,7 @@ ClipboardEvent::ClipboardEvent()
{
}
-ClipboardEvent::ClipboardEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<Clipboard> clipboard)
+ClipboardEvent::ClipboardEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<Clipboard> clipboard)
: Event(eventType, canBubble, cancelable), m_clipboard(clipboard)
{
}
@@ -52,4 +51,10 @@ bool ClipboardEvent::isClipboardEvent() const
return true;
}
+void ClipboardEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_clipboard);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/ClipboardEvent.h b/chromium/third_party/WebKit/Source/core/events/ClipboardEvent.h
index 671315b39f5..15eb8f4b56c 100644
--- a/chromium/third_party/WebKit/Source/core/events/ClipboardEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/ClipboardEvent.h
@@ -30,29 +30,27 @@ namespace WebCore {
class Clipboard;
- class ClipboardEvent : public Event {
+ class ClipboardEvent FINAL : public Event {
public:
virtual ~ClipboardEvent();
- static PassRefPtr<ClipboardEvent> create()
+ static PassRefPtrWillBeRawPtr<ClipboardEvent> create(const AtomicString& type, bool canBubbleArg, bool cancelableArg, PassRefPtrWillBeRawPtr<Clipboard> clipboardArg)
{
- return adoptRef(new ClipboardEvent);
- }
- static PassRefPtr<ClipboardEvent> create(const AtomicString& type, bool canBubbleArg, bool cancelableArg, PassRefPtr<Clipboard> clipboardArg)
- {
- return adoptRef(new ClipboardEvent(type, canBubbleArg, cancelableArg, clipboardArg));
+ return adoptRefWillBeNoop(new ClipboardEvent(type, canBubbleArg, cancelableArg, clipboardArg));
}
Clipboard* clipboard() const { return m_clipboard.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
ClipboardEvent();
- ClipboardEvent(const AtomicString& type, bool canBubbleArg, bool cancelableArg, PassRefPtr<Clipboard>);
+ ClipboardEvent(const AtomicString& type, bool canBubbleArg, bool cancelableArg, PassRefPtrWillBeRawPtr<Clipboard>);
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual bool isClipboardEvent() const OVERRIDE;
- RefPtr<Clipboard> m_clipboard;
+ RefPtrWillBeMember<Clipboard> m_clipboard;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/CompositionEvent.cpp b/chromium/third_party/WebKit/Source/core/events/CompositionEvent.cpp
index f4ecff6596f..ce1b9f7e983 100644
--- a/chromium/third_party/WebKit/Source/core/events/CompositionEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/CompositionEvent.cpp
@@ -27,8 +27,6 @@
#include "config.h"
#include "core/events/CompositionEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
CompositionEventInit::CompositionEventInit()
@@ -36,29 +34,38 @@ CompositionEventInit::CompositionEventInit()
}
CompositionEvent::CompositionEvent()
+ : m_activeSegmentStart(0)
+ , m_activeSegmentEnd(0)
{
ScriptWrappable::init(this);
+ initializeSegments();
}
-CompositionEvent::CompositionEvent(const AtomicString& type, PassRefPtr<AbstractView> view, const String& data)
+CompositionEvent::CompositionEvent(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView> view, const String& data, const Vector<CompositionUnderline>& underlines)
: UIEvent(type, true, true, view, 0)
, m_data(data)
+ , m_activeSegmentStart(0)
+ , m_activeSegmentEnd(0)
{
ScriptWrappable::init(this);
+ initializeSegments(&underlines);
}
CompositionEvent::CompositionEvent(const AtomicString& type, const CompositionEventInit& initializer)
: UIEvent(type, initializer)
, m_data(initializer.data)
+ , m_activeSegmentStart(0)
+ , m_activeSegmentEnd(0)
{
ScriptWrappable::init(this);
+ initializeSegments();
}
CompositionEvent::~CompositionEvent()
{
}
-void CompositionEvent::initCompositionEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view, const String& data)
+void CompositionEvent::initCompositionEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view, const String& data)
{
if (dispatched())
return;
@@ -66,6 +73,29 @@ void CompositionEvent::initCompositionEvent(const AtomicString& type, bool canBu
initUIEvent(type, canBubble, cancelable, view, 0);
m_data = data;
+ initializeSegments();
+}
+
+void CompositionEvent::initializeSegments(const Vector<CompositionUnderline>* underlines)
+{
+ m_activeSegmentStart = 0;
+ m_activeSegmentEnd = m_data.length();
+
+ if (!underlines || !underlines->size()) {
+ m_segments.append(0);
+ return;
+ }
+
+ for (size_t i = 0; i < underlines->size(); ++i) {
+ if (underlines->at(i).thick) {
+ m_activeSegmentStart = underlines->at(i).startOffset;
+ m_activeSegmentEnd = underlines->at(i).endOffset;
+ break;
+ }
+ }
+
+ for (size_t i = 0; i < underlines->size(); ++i)
+ m_segments.append(underlines->at(i).startOffset);
}
const AtomicString& CompositionEvent::interfaceName() const
@@ -73,4 +103,9 @@ const AtomicString& CompositionEvent::interfaceName() const
return EventNames::CompositionEvent;
}
+void CompositionEvent::trace(Visitor* visitor)
+{
+ UIEvent::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/CompositionEvent.h b/chromium/third_party/WebKit/Source/core/events/CompositionEvent.h
index c06da88c196..662f0596a3d 100644
--- a/chromium/third_party/WebKit/Source/core/events/CompositionEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/CompositionEvent.h
@@ -27,6 +27,7 @@
#ifndef CompositionEvent_h
#define CompositionEvent_h
+#include "core/editing/CompositionUnderline.h"
#include "core/events/UIEvent.h"
namespace WebCore {
@@ -37,37 +38,46 @@ struct CompositionEventInit : UIEventInit {
String data;
};
-class CompositionEvent : public UIEvent {
+class CompositionEvent FINAL : public UIEvent {
public:
- static PassRefPtr<CompositionEvent> create()
+ static PassRefPtrWillBeRawPtr<CompositionEvent> create()
{
- return adoptRef(new CompositionEvent);
+ return adoptRefWillBeNoop(new CompositionEvent);
}
- static PassRefPtr<CompositionEvent> create(const AtomicString& type, PassRefPtr<AbstractView> view, const String& data)
+ static PassRefPtrWillBeRawPtr<CompositionEvent> create(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView> view, const String& data, const Vector<CompositionUnderline>& underlines)
{
- return adoptRef(new CompositionEvent(type, view, data));
+ return adoptRefWillBeNoop(new CompositionEvent(type, view, data, underlines));
}
- static PassRefPtr<CompositionEvent> create(const AtomicString& type, const CompositionEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<CompositionEvent> create(const AtomicString& type, const CompositionEventInit& initializer)
{
- return adoptRef(new CompositionEvent(type, initializer));
+ return adoptRefWillBeNoop(new CompositionEvent(type, initializer));
}
virtual ~CompositionEvent();
- void initCompositionEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, const String& data);
+ void initCompositionEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>, const String& data);
String data() const { return m_data; }
+ int activeSegmentStart() const { return m_activeSegmentStart; }
+ int activeSegmentEnd() const { return m_activeSegmentEnd; }
+ const Vector<unsigned>& getSegments() const { return m_segments; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
CompositionEvent();
- CompositionEvent(const AtomicString& type, PassRefPtr<AbstractView>, const String&);
+ CompositionEvent(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView>, const String&, const Vector<CompositionUnderline>& underlines);
CompositionEvent(const AtomicString& type, const CompositionEventInit&);
+ void initializeSegments(const Vector<CompositionUnderline>* = 0);
String m_data;
+ int m_activeSegmentStart;
+ int m_activeSegmentEnd;
+ Vector<unsigned> m_segments;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/CompositionEvent.idl b/chromium/third_party/WebKit/Source/core/events/CompositionEvent.idl
index 4e14a952281..8b1d740fd68 100644
--- a/chromium/third_party/WebKit/Source/core/events/CompositionEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/events/CompositionEvent.idl
@@ -29,6 +29,10 @@
[InitializedByEventConstructor] readonly attribute DOMString data;
+ [RuntimeEnabled=IMEAPI] readonly attribute long activeSegmentStart;
+ [RuntimeEnabled=IMEAPI] readonly attribute long activeSegmentEnd;
+ [RuntimeEnabled=IMEAPI] sequence<unsigned long> getSegments();
+
void initCompositionEvent([Default=Undefined] optional DOMString typeArg,
[Default=Undefined] optional boolean canBubbleArg,
[Default=Undefined] optional boolean cancelableArg,
@@ -36,4 +40,3 @@
[Default=Undefined] optional DOMString dataArg);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/events/CustomEvent.cpp b/chromium/third_party/WebKit/Source/core/events/CustomEvent.cpp
index ea3ac91b9e3..deb3aba5c2e 100644
--- a/chromium/third_party/WebKit/Source/core/events/CustomEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/CustomEvent.cpp
@@ -27,7 +27,6 @@
#include "core/events/CustomEvent.h"
#include "bindings/v8/SerializedScriptValue.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
@@ -61,4 +60,9 @@ const AtomicString& CustomEvent::interfaceName() const
return EventNames::CustomEvent;
}
+void CustomEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/CustomEvent.h b/chromium/third_party/WebKit/Source/core/events/CustomEvent.h
index 9be0e119aa7..5340f75431b 100644
--- a/chromium/third_party/WebKit/Source/core/events/CustomEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/CustomEvent.h
@@ -34,23 +34,23 @@ class SerializedScriptValue;
typedef EventInit CustomEventInit;
-class CustomEvent : public Event {
+class CustomEvent FINAL : public Event {
public:
virtual ~CustomEvent();
- static PassRefPtr<CustomEvent> create()
+ static PassRefPtrWillBeRawPtr<CustomEvent> create()
{
- return adoptRef(new CustomEvent);
+ return adoptRefWillBeNoop(new CustomEvent);
}
- static PassRefPtr<CustomEvent> create(const AtomicString& type, const CustomEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<CustomEvent> create(const AtomicString& type, const CustomEventInit& initializer)
{
- return adoptRef(new CustomEvent(type, initializer));
+ return adoptRefWillBeNoop(new CustomEvent(type, initializer));
}
void initCustomEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue>);
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
SerializedScriptValue* serializedDetail() { return m_serializedDetail.get(); }
@@ -60,6 +60,8 @@ public:
m_serializedDetail = detail;
}
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
CustomEvent();
CustomEvent(const AtomicString& type, const CustomEventInit& initializer);
diff --git a/chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.cpp b/chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.cpp
index e18530c72a0..bd0be9936c9 100644
--- a/chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.cpp
@@ -29,31 +29,33 @@
#include "core/dom/Document.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/SuspendableTimer.h"
+#include "core/inspector/InspectorInstrumentation.h"
namespace WebCore {
-class DOMWindowEventQueueTimer : public SuspendableTimer {
+class DOMWindowEventQueueTimer : public NoBaseWillBeGarbageCollectedFinalized<DOMWindowEventQueueTimer>, public SuspendableTimer {
WTF_MAKE_NONCOPYABLE(DOMWindowEventQueueTimer);
public:
DOMWindowEventQueueTimer(DOMWindowEventQueue* eventQueue, ExecutionContext* context)
: SuspendableTimer(context)
, m_eventQueue(eventQueue) { }
+ void trace(Visitor* visitor) { visitor->trace(m_eventQueue); }
private:
virtual void fired() { m_eventQueue->pendingEventTimerFired(); }
- DOMWindowEventQueue* m_eventQueue;
+
+ RawPtrWillBeMember<DOMWindowEventQueue> m_eventQueue;
};
-PassRefPtr<DOMWindowEventQueue> DOMWindowEventQueue::create(ExecutionContext* context)
+PassRefPtrWillBeRawPtr<DOMWindowEventQueue> DOMWindowEventQueue::create(ExecutionContext* context)
{
- return adoptRef(new DOMWindowEventQueue(context));
+ return adoptRefWillBeNoop(new DOMWindowEventQueue(context));
}
DOMWindowEventQueue::DOMWindowEventQueue(ExecutionContext* context)
- : m_pendingEventTimer(adoptPtr(new DOMWindowEventQueueTimer(this, context)))
+ : m_pendingEventTimer(adoptPtrWillBeNoop(new DOMWindowEventQueueTimer(this, context)))
, m_isClosed(false)
{
m_pendingEventTimer->suspendIfNeeded();
@@ -63,27 +65,38 @@ DOMWindowEventQueue::~DOMWindowEventQueue()
{
}
-bool DOMWindowEventQueue::enqueueEvent(PassRefPtr<Event> event)
+void DOMWindowEventQueue::trace(Visitor* visitor)
+{
+ visitor->trace(m_pendingEventTimer);
+ visitor->trace(m_queuedEvents);
+ EventQueue::trace(visitor);
+}
+
+bool DOMWindowEventQueue::enqueueEvent(PassRefPtrWillBeRawPtr<Event> event)
{
if (m_isClosed)
return false;
ASSERT(event->target());
+ InspectorInstrumentation::didEnqueueEvent(event->target(), event.get());
+
bool wasAdded = m_queuedEvents.add(event).isNewEntry;
ASSERT_UNUSED(wasAdded, wasAdded); // It should not have already been in the list.
if (!m_pendingEventTimer->isActive())
- m_pendingEventTimer->startOneShot(0);
+ m_pendingEventTimer->startOneShot(0, FROM_HERE);
return true;
}
bool DOMWindowEventQueue::cancelEvent(Event* event)
{
- ListHashSet<RefPtr<Event>, 16>::iterator it = m_queuedEvents.find(event);
+ WillBeHeapListHashSet<RefPtrWillBeMember<Event>, 16>::iterator it = m_queuedEvents.find(event);
bool found = it != m_queuedEvents.end();
- if (found)
+ if (found) {
+ InspectorInstrumentation::didRemoveEvent(event->target(), event);
m_queuedEvents.remove(it);
+ }
if (m_queuedEvents.isEmpty())
m_pendingEventTimer->stop();
return found;
@@ -93,6 +106,11 @@ void DOMWindowEventQueue::close()
{
m_isClosed = true;
m_pendingEventTimer->stop();
+ if (InspectorInstrumentation::hasFrontends()) {
+ WillBeHeapListHashSet<RefPtrWillBeMember<Event>, 16>::iterator it = m_queuedEvents.begin();
+ for (; it != m_queuedEvents.end(); ++it)
+ InspectorInstrumentation::didRemoveEvent((*it)->target(), it->get());
+ }
m_queuedEvents.clear();
}
@@ -102,27 +120,28 @@ void DOMWindowEventQueue::pendingEventTimerFired()
ASSERT(!m_queuedEvents.isEmpty());
// Insert a marker for where we should stop.
- ASSERT(!m_queuedEvents.contains(0));
- bool wasAdded = m_queuedEvents.add(0).isNewEntry;
+ ASSERT(!m_queuedEvents.contains(nullptr));
+ bool wasAdded = m_queuedEvents.add(nullptr).isNewEntry;
ASSERT_UNUSED(wasAdded, wasAdded); // It should not have already been in the list.
- RefPtr<DOMWindowEventQueue> protector(this);
+ RefPtrWillBeRawPtr<DOMWindowEventQueue> protector(this);
while (!m_queuedEvents.isEmpty()) {
- ListHashSet<RefPtr<Event>, 16>::iterator iter = m_queuedEvents.begin();
- RefPtr<Event> event = *iter;
+ WillBeHeapListHashSet<RefPtrWillBeMember<Event>, 16>::iterator iter = m_queuedEvents.begin();
+ RefPtrWillBeRawPtr<Event> event = *iter;
m_queuedEvents.remove(iter);
if (!event)
break;
dispatchEvent(event.get());
+ InspectorInstrumentation::didRemoveEvent(event->target(), event.get());
}
}
-void DOMWindowEventQueue::dispatchEvent(PassRefPtr<Event> event)
+void DOMWindowEventQueue::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
EventTarget* eventTarget = event->target();
if (eventTarget->toDOMWindow())
- eventTarget->toDOMWindow()->dispatchEvent(event, 0);
+ eventTarget->toDOMWindow()->dispatchEvent(event, nullptr);
else
eventTarget->dispatchEvent(event);
}
diff --git a/chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.h b/chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.h
index f19e22b5d51..443f2876bc6 100644
--- a/chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.h
+++ b/chromium/third_party/WebKit/Source/core/events/DOMWindowEventQueue.h
@@ -28,7 +28,6 @@
#define DOMWindowEventQueue_h
#include "core/events/EventQueue.h"
-#include "wtf/Forward.h"
#include "wtf/HashSet.h"
#include "wtf/ListHashSet.h"
#include "wtf/OwnPtr.h"
@@ -41,13 +40,20 @@ class DOMWindowEventQueueTimer;
class Node;
class ExecutionContext;
-class DOMWindowEventQueue : public RefCounted<DOMWindowEventQueue>, public EventQueue {
+#if ENABLE(OILPAN)
+#define DOMWINDOWEVENTQUEUE_BASE_CLASSES public EventQueue
+#else
+#define DOMWINDOWEVENTQUEUE_BASE_CLASSES public RefCounted<DOMWindowEventQueue>, public EventQueue
+#endif
+
+class DOMWindowEventQueue FINAL : DOMWINDOWEVENTQUEUE_BASE_CLASSES {
public:
- static PassRefPtr<DOMWindowEventQueue> create(ExecutionContext*);
+ static PassRefPtrWillBeRawPtr<DOMWindowEventQueue> create(ExecutionContext*);
virtual ~DOMWindowEventQueue();
// EventQueue
- virtual bool enqueueEvent(PassRefPtr<Event>) OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+ virtual bool enqueueEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
virtual bool cancelEvent(Event*) OVERRIDE;
virtual void close() OVERRIDE;
@@ -55,10 +61,10 @@ private:
explicit DOMWindowEventQueue(ExecutionContext*);
void pendingEventTimerFired();
- void dispatchEvent(PassRefPtr<Event>);
+ void dispatchEvent(PassRefPtrWillBeRawPtr<Event>);
- OwnPtr<DOMWindowEventQueueTimer> m_pendingEventTimer;
- ListHashSet<RefPtr<Event>, 16> m_queuedEvents;
+ OwnPtrWillBeMember<DOMWindowEventQueueTimer> m_pendingEventTimer;
+ WillBeHeapListHashSet<RefPtrWillBeMember<Event>, 16> m_queuedEvents;
bool m_isClosed;
friend class DOMWindowEventQueueTimer;
diff --git a/chromium/third_party/WebKit/Source/core/events/ErrorEvent.cpp b/chromium/third_party/WebKit/Source/core/events/ErrorEvent.cpp
index 0bd32f4e9e2..ed95ff13afd 100644
--- a/chromium/third_party/WebKit/Source/core/events/ErrorEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/ErrorEvent.cpp
@@ -31,7 +31,8 @@
#include "config.h"
#include "core/events/ErrorEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "bindings/v8/V8Binding.h"
+#include <v8.h>
namespace WebCore {
@@ -54,12 +55,12 @@ ErrorEvent::ErrorEvent(const AtomicString& type, const ErrorEventInit& initializ
, m_fileName(initializer.filename)
, m_lineNumber(initializer.lineno)
, m_columnNumber(initializer.colno)
- , m_world(DOMWrapperWorld::current())
+ , m_world(DOMWrapperWorld::current(v8::Isolate::GetCurrent()))
{
ScriptWrappable::init(this);
}
-ErrorEvent::ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld> world)
+ErrorEvent::ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, DOMWrapperWorld* world)
: Event(EventTypeNames::error, false, true)
, m_sanitizedMessage(message)
, m_fileName(fileName)
@@ -85,4 +86,9 @@ const AtomicString& ErrorEvent::interfaceName() const
return EventNames::ErrorEvent;
}
+void ErrorEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/ErrorEvent.h b/chromium/third_party/WebKit/Source/core/events/ErrorEvent.h
index e0643e4895f..e0dbf837ee0 100644
--- a/chromium/third_party/WebKit/Source/core/events/ErrorEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/ErrorEvent.h
@@ -47,23 +47,23 @@ struct ErrorEventInit : public EventInit {
unsigned colno;
};
-class ErrorEvent : public Event {
+class ErrorEvent FINAL : public Event {
public:
- static PassRefPtr<ErrorEvent> create()
+ static PassRefPtrWillBeRawPtr<ErrorEvent> create()
{
- return adoptRef(new ErrorEvent);
+ return adoptRefWillBeNoop(new ErrorEvent);
}
- static PassRefPtr<ErrorEvent> create(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld> world)
+ static PassRefPtrWillBeRawPtr<ErrorEvent> create(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, DOMWrapperWorld* world)
{
- return adoptRef(new ErrorEvent(message, fileName, lineNumber, columnNumber, world));
+ return adoptRefWillBeNoop(new ErrorEvent(message, fileName, lineNumber, columnNumber, world));
}
- static PassRefPtr<ErrorEvent> create(const AtomicString& type, const ErrorEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<ErrorEvent> create(const AtomicString& type, const ErrorEventInit& initializer)
{
- return adoptRef(new ErrorEvent(type, initializer));
+ return adoptRefWillBeNoop(new ErrorEvent(type, initializer));
}
- static PassRefPtr<ErrorEvent> createSanitizedError(PassRefPtr<DOMWrapperWorld> world)
+ static PassRefPtrWillBeRawPtr<ErrorEvent> createSanitizedError(DOMWrapperWorld* world)
{
- return adoptRef(new ErrorEvent("Script error.", String(), 0, 0, world));
+ return adoptRefWillBeNoop(new ErrorEvent("Script error.", String(), 0, 0, world));
}
virtual ~ErrorEvent();
@@ -76,15 +76,17 @@ public:
// 'messageForConsole' is not exposed to JavaScript, and prefers 'm_unsanitizedMessage'.
const String& messageForConsole() const { return !m_unsanitizedMessage.isEmpty() ? m_unsanitizedMessage : m_sanitizedMessage; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
- PassRefPtr<DOMWrapperWorld> world() const { return m_world; }
+ DOMWrapperWorld* world() const { return m_world.get(); }
void setUnsanitizedMessage(const String&);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
ErrorEvent();
- ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld>);
+ ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, DOMWrapperWorld*);
ErrorEvent(const AtomicString&, const ErrorEventInit&);
String m_unsanitizedMessage;
diff --git a/chromium/third_party/WebKit/Source/core/events/Event.cpp b/chromium/third_party/WebKit/Source/core/events/Event.cpp
index 4ec60126722..6530b42c10c 100644
--- a/chromium/third_party/WebKit/Source/core/events/Event.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/Event.cpp
@@ -25,7 +25,8 @@
#include "core/dom/StaticNodeList.h"
#include "core/events/EventTarget.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/UseCounter.h"
+#include "core/svg/SVGElement.h"
#include "wtf/CurrentTime.h"
namespace WebCore {
@@ -46,9 +47,8 @@ Event::Event()
, m_defaultHandled(false)
, m_cancelBubble(false)
, m_eventPhase(0)
- , m_currentTarget(0)
+ , m_currentTarget(nullptr)
, m_createTime(convertSecondsToDOMTimeStamp(currentTime()))
- , m_eventPath(this)
{
ScriptWrappable::init(this);
}
@@ -63,9 +63,8 @@ Event::Event(const AtomicString& eventType, bool canBubbleArg, bool cancelableAr
, m_defaultHandled(false)
, m_cancelBubble(false)
, m_eventPhase(0)
- , m_currentTarget(0)
+ , m_currentTarget(nullptr)
, m_createTime(convertSecondsToDOMTimeStamp(currentTime()))
- , m_eventPath(this)
{
ScriptWrappable::init(this);
}
@@ -80,9 +79,8 @@ Event::Event(const AtomicString& eventType, const EventInit& initializer)
, m_defaultHandled(false)
, m_cancelBubble(false)
, m_eventPhase(0)
- , m_currentTarget(0)
+ , m_currentTarget(nullptr)
, m_createTime(convertSecondsToDOMTimeStamp(currentTime()))
- , m_eventPath(this)
{
ScriptWrappable::init(this);
}
@@ -105,6 +103,25 @@ void Event::initEvent(const AtomicString& eventTypeArg, bool canBubbleArg, bool
m_cancelable = cancelableArg;
}
+bool Event::legacyReturnValue(ExecutionContext* executionContext) const
+{
+ bool returnValue = !defaultPrevented();
+ if (returnValue)
+ UseCounter::count(executionContext, UseCounter::EventGetReturnValueTrue);
+ else
+ UseCounter::count(executionContext, UseCounter::EventGetReturnValueFalse);
+ return returnValue;
+}
+
+void Event::setLegacyReturnValue(ExecutionContext* executionContext, bool returnValue)
+{
+ if (returnValue)
+ UseCounter::count(executionContext, UseCounter::EventSetReturnValueTrue);
+ else
+ UseCounter::count(executionContext, UseCounter::EventSetReturnValueFalse);
+ setDefaultPrevented(!returnValue);
+}
+
const AtomicString& Event::interfaceName() const
{
return EventNames::Event;
@@ -170,7 +187,7 @@ bool Event::isBeforeUnloadEvent() const
return false;
}
-void Event::setTarget(PassRefPtr<EventTarget> target)
+void Event::setTarget(PassRefPtrWillBeRawPtr<EventTarget> target)
{
if (m_target == target)
return;
@@ -184,7 +201,7 @@ void Event::receivedTarget()
{
}
-void Event::setUnderlyingEvent(PassRefPtr<Event> ue)
+void Event::setUnderlyingEvent(PassRefPtrWillBeRawPtr<Event> ue)
{
// Prohibit creation of a cycle -- just do nothing in that case.
for (Event* e = ue.get(); e; e = e->underlyingEvent())
@@ -193,19 +210,48 @@ void Event::setUnderlyingEvent(PassRefPtr<Event> ue)
m_underlyingEvent = ue;
}
-PassRefPtr<NodeList> Event::path() const
+EventPath& Event::ensureEventPath()
+{
+ if (!m_eventPath)
+ m_eventPath = adoptPtrWillBeNoop(new EventPath(this));
+ return *m_eventPath;
+}
+
+PassRefPtrWillBeRawPtr<StaticNodeList> Event::path() const
{
if (!m_currentTarget || !m_currentTarget->toNode())
return StaticNodeList::createEmpty();
Node* node = m_currentTarget->toNode();
- size_t eventPathSize = m_eventPath.size();
+ // FIXME: Support SVG Elements.
+ if (node->isSVGElement())
+ return StaticNodeList::createEmpty();
+ size_t eventPathSize = m_eventPath->size();
for (size_t i = 0; i < eventPathSize; ++i) {
- if (node == m_eventPath[i].node()) {
- ASSERT(m_eventPath[i].eventPath());
- return m_eventPath[i].eventPath();
+ if (node == (*m_eventPath)[i].node()) {
+ return (*m_eventPath)[i].treeScopeEventContext().ensureEventPath(*m_eventPath);
}
}
return StaticNodeList::createEmpty();
}
+EventTarget* Event::currentTarget() const
+{
+ if (!m_currentTarget)
+ return 0;
+ Node* node = m_currentTarget->toNode();
+ if (node && node->isSVGElement()) {
+ if (SVGElement* svgElement = toSVGElement(node)->correspondingElement())
+ return svgElement;
+ }
+ return m_currentTarget;
+}
+
+void Event::trace(Visitor* visitor)
+{
+ visitor->trace(m_currentTarget);
+ visitor->trace(m_target);
+ visitor->trace(m_underlyingEvent);
+ visitor->trace(m_eventPath);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/Event.h b/chromium/third_party/WebKit/Source/core/events/Event.h
index b28f7f113d1..ef9d3657149 100644
--- a/chromium/third_party/WebKit/Source/core/events/Event.h
+++ b/chromium/third_party/WebKit/Source/core/events/Event.h
@@ -26,26 +26,27 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/DOMTimeStamp.h"
-#include "core/events/EventContext.h"
#include "core/events/EventPath.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
-class Clipboard;
class EventTarget;
class EventDispatcher;
-class HTMLIFrameElement;
+class ExecutionContext;
struct EventInit {
+ STACK_ALLOCATED();
+public:
EventInit();
bool bubbles;
bool cancelable;
};
-class Event : public ScriptWrappable, public RefCounted<Event> {
+class Event : public RefCountedWillBeGarbageCollectedFinalized<Event>, public ScriptWrappable {
public:
enum PhaseType {
NONE = 0,
@@ -73,34 +74,34 @@ public:
CHANGE = 32768
};
- static PassRefPtr<Event> create()
+ static PassRefPtrWillBeRawPtr<Event> create()
{
- return adoptRef(new Event);
+ return adoptRefWillBeNoop(new Event);
}
// A factory for a simple event. The event doesn't bubble, and isn't
// cancelable.
// http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#fire-a-simple-event
- static PassRefPtr<Event> create(const AtomicString& type)
+ static PassRefPtrWillBeRawPtr<Event> create(const AtomicString& type)
{
- return adoptRef(new Event(type, false, false));
+ return adoptRefWillBeNoop(new Event(type, false, false));
}
- static PassRefPtr<Event> createCancelable(const AtomicString& type)
+ static PassRefPtrWillBeRawPtr<Event> createCancelable(const AtomicString& type)
{
- return adoptRef(new Event(type, false, true));
+ return adoptRefWillBeNoop(new Event(type, false, true));
}
- static PassRefPtr<Event> createBubble(const AtomicString& type)
+ static PassRefPtrWillBeRawPtr<Event> createBubble(const AtomicString& type)
{
- return adoptRef(new Event(type, true, false));
+ return adoptRefWillBeNoop(new Event(type, true, false));
}
- static PassRefPtr<Event> createCancelableBubble(const AtomicString& type)
+ static PassRefPtrWillBeRawPtr<Event> createCancelableBubble(const AtomicString& type)
{
- return adoptRef(new Event(type, true, true));
+ return adoptRefWillBeNoop(new Event(type, true, true));
}
- static PassRefPtr<Event> create(const AtomicString& type, const EventInit& initializer)
+ static PassRefPtrWillBeRawPtr<Event> create(const AtomicString& type, const EventInit& initializer)
{
- return adoptRef(new Event(type, initializer));
+ return adoptRefWillBeNoop(new Event(type, initializer));
}
virtual ~Event();
@@ -111,9 +112,9 @@ public:
void setType(const AtomicString& type) { m_type = type; }
EventTarget* target() const { return m_target.get(); }
- void setTarget(PassRefPtr<EventTarget>);
+ void setTarget(PassRefPtrWillBeRawPtr<EventTarget>);
- EventTarget* currentTarget() const { return m_currentTarget; }
+ EventTarget* currentTarget() const;
void setCurrentTarget(EventTarget* currentTarget) { m_currentTarget = currentTarget; }
unsigned short eventPhase() const { return m_eventPhase; }
@@ -129,10 +130,8 @@ public:
// IE Extensions
EventTarget* srcElement() const { return target(); } // MSIE extension - "the object that fired the event"
- bool legacyReturnValue() const { return !defaultPrevented(); }
- void setLegacyReturnValue(bool returnValue) { setDefaultPrevented(!returnValue); }
-
- Clipboard* clipboardData() const { return isClipboardEvent() ? clipboard() : 0; }
+ bool legacyReturnValue(ExecutionContext*) const;
+ void setLegacyReturnValue(ExecutionContext*, bool returnValue);
virtual const AtomicString& interfaceName() const;
bool hasInterface(const AtomicString&) const;
@@ -159,7 +158,7 @@ public:
bool immediatePropagationStopped() const { return m_immediatePropagationStopped; }
bool defaultPrevented() const { return m_defaultPrevented; }
- void preventDefault()
+ virtual void preventDefault()
{
if (m_cancelable)
m_defaultPrevented = true;
@@ -173,15 +172,17 @@ public:
void setCancelBubble(bool cancel) { m_cancelBubble = cancel; }
Event* underlyingEvent() const { return m_underlyingEvent.get(); }
- void setUnderlyingEvent(PassRefPtr<Event>);
+ void setUnderlyingEvent(PassRefPtrWillBeRawPtr<Event>);
- EventPath& eventPath() { return m_eventPath; }
- PassRefPtr<NodeList> path() const;
+ EventPath& eventPath() { ASSERT(m_eventPath); return *m_eventPath; }
+ EventPath& ensureEventPath();
- virtual Clipboard* clipboard() const { return 0; }
+ PassRefPtrWillBeRawPtr<StaticNodeList> path() const;
bool isBeingDispatched() const { return eventPhase(); }
+ virtual void trace(Visitor*);
+
protected:
Event();
Event(const AtomicString& type, bool canBubble, bool cancelable);
@@ -202,11 +203,11 @@ private:
bool m_cancelBubble;
unsigned short m_eventPhase;
- EventTarget* m_currentTarget;
- RefPtr<EventTarget> m_target;
+ RawPtrWillBeMember<EventTarget> m_currentTarget;
+ RefPtrWillBeMember<EventTarget> m_target;
DOMTimeStamp m_createTime;
- RefPtr<Event> m_underlyingEvent;
- EventPath m_eventPath;
+ RefPtrWillBeMember<Event> m_underlyingEvent;
+ OwnPtrWillBeMember<EventPath> m_eventPath;
};
#define DEFINE_EVENT_TYPE_CASTS(typeName) \
diff --git a/chromium/third_party/WebKit/Source/core/events/Event.idl b/chromium/third_party/WebKit/Source/core/events/Event.idl
index 3f8e80b0523..58a832a3a62 100644
--- a/chromium/third_party/WebKit/Source/core/events/Event.idl
+++ b/chromium/third_party/WebKit/Source/core/events/Event.idl
@@ -20,6 +20,7 @@
// Introduced in DOM Level 2:
[
+ WillBeGarbageCollected,
Custom=Wrap,
EventConstructor,
] interface Event {
@@ -67,11 +68,9 @@
void stopImmediatePropagation();
// IE Extensions
- readonly attribute EventTarget srcElement;
- [ImplementedAs=legacyReturnValue, DeprecateAs=EventReturnValue] attribute boolean returnValue;
- attribute boolean cancelBubble;
-
- [RuntimeEnabled=ShadowDOM] readonly attribute NodeList path;
-
- [Custom=Getter] readonly attribute Clipboard clipboardData;
+ [MeasureAs=EventSrcElement] readonly attribute EventTarget srcElement;
+ [CallWith=ExecutionContext, ImplementedAs=legacyReturnValue, MeasureAs=EventReturnValue] attribute boolean returnValue;
+ [MeasureAs=EventCancelBubble] attribute boolean cancelBubble;
+ [MeasureAs=EventPath] readonly attribute NodeList path;
+ [Custom=Getter, MeasureAs=EventClipboardData] readonly attribute DataTransfer clipboardData;
};
diff --git a/chromium/third_party/WebKit/Source/core/events/EventAliases.in b/chromium/third_party/WebKit/Source/core/events/EventAliases.in
index 82b3a744fc9..f5d90635e0f 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventAliases.in
+++ b/chromium/third_party/WebKit/Source/core/events/EventAliases.in
@@ -5,7 +5,7 @@ HTMLEvents ImplementedAs=Event
KeyboardEvents ImplementedAs=KeyboardEvent
MouseEvents ImplementedAs=MouseEvent
MutationEvents ImplementedAs=MutationEvent
-OrientationEvent ImplementedAs=Event, Conditional=ORIENTATION_EVENTS
+OrientationEvent ImplementedAs=Event, RuntimeEnabled=OrientationEventEnabled
SVGEvents ImplementedAs=Event
SVGZoomEvents ImplementedAs=SVGZoomEvent
UIEvents ImplementedAs=UIEvent
diff --git a/chromium/third_party/WebKit/Source/core/events/EventContext.cpp b/chromium/third_party/WebKit/Source/core/events/EventContext.cpp
deleted file mode 100644
index 5fa4d5e42a4..00000000000
--- a/chromium/third_party/WebKit/Source/core/events/EventContext.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "config.h"
-#include "core/events/EventContext.h"
-
-#include "core/events/Event.h"
-#include "core/events/FocusEvent.h"
-#include "core/events/MouseEvent.h"
-#include "core/events/TouchEvent.h"
-#include "core/dom/TouchList.h"
-
-namespace WebCore {
-
-EventContext::EventContext(PassRefPtr<Node> node, PassRefPtr<EventTarget> currentTarget)
- : m_node(node)
- , m_currentTarget(currentTarget)
-{
- ASSERT(m_node);
-}
-
-EventContext::~EventContext()
-{
-}
-
-void EventContext::adoptEventPath(Vector<RefPtr<Node> >& nodes)
-{
- m_eventPath = StaticNodeList::adopt(nodes);
-}
-
-void EventContext::handleLocalEvents(Event* event) const
-{
- if (m_touchEventContext) {
- m_touchEventContext->handleLocalEvents(event);
- } else if (m_relatedTarget && event->isMouseEvent()) {
- toMouseEvent(event)->setRelatedTarget(m_relatedTarget.get());
- } else if (m_relatedTarget && event->isFocusEvent()) {
- toFocusEvent(event)->setRelatedTarget(m_relatedTarget.get());
- }
- event->setTarget(m_target);
- event->setCurrentTarget(m_currentTarget.get());
- m_node->handleLocalEvents(event);
-}
-
-TouchEventContext* EventContext::ensureTouchEventContext()
-{
- if (!m_touchEventContext)
- m_touchEventContext = TouchEventContext::create();
- return m_touchEventContext.get();
-}
-
-PassRefPtr<TouchEventContext> TouchEventContext::create()
-{
- return adoptRef(new TouchEventContext);
-}
-
-TouchEventContext::TouchEventContext()
- : m_touches(TouchList::create())
- , m_targetTouches(TouchList::create())
- , m_changedTouches(TouchList::create())
-{
-}
-
-TouchEventContext::~TouchEventContext()
-{
-}
-
-void TouchEventContext::handleLocalEvents(Event* event) const
-{
- ASSERT(event->isTouchEvent());
- TouchEvent* touchEvent = toTouchEvent(event);
- touchEvent->setTouches(m_touches);
- touchEvent->setTargetTouches(m_targetTouches);
- touchEvent->setChangedTouches(m_changedTouches);
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/events/EventContext.h b/chromium/third_party/WebKit/Source/core/events/EventContext.h
deleted file mode 100644
index c51c90d4aaf..00000000000
--- a/chromium/third_party/WebKit/Source/core/events/EventContext.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef EventContext_h
-#define EventContext_h
-
-#include "core/events/EventTarget.h"
-#include "core/dom/Node.h"
-#include "core/dom/StaticNodeList.h"
-#include "core/dom/TreeScope.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class Event;
-class TouchList;
-
-class TouchEventContext : public RefCounted<TouchEventContext> {
-public:
- static PassRefPtr<TouchEventContext> create();
- ~TouchEventContext();
- void handleLocalEvents(Event*) const;
- TouchList* touches() { return m_touches.get(); }
- TouchList* targetTouches() { return m_targetTouches.get(); }
- TouchList* changedTouches() { return m_changedTouches.get(); }
-
-private:
- TouchEventContext();
-
- RefPtr<TouchList> m_touches;
- RefPtr<TouchList> m_targetTouches;
- RefPtr<TouchList> m_changedTouches;
-};
-
-class EventContext {
-public:
- // FIXME: Use ContainerNode instead of Node.
- EventContext(PassRefPtr<Node>, PassRefPtr<EventTarget> currentTarget);
- ~EventContext();
-
- Node* node() const { return m_node.get(); }
- EventTarget* currentTarget() const { return m_currentTarget.get(); }
-
- EventTarget* target() const { return m_target.get(); }
- void setTarget(PassRefPtr<EventTarget>);
-
- EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
- void setRelatedTarget(PassRefPtr<EventTarget>);
-
- TouchEventContext* touchEventContext() const { return m_touchEventContext.get(); }
- TouchEventContext* ensureTouchEventContext();
-
- PassRefPtr<NodeList> eventPath() const { return m_eventPath; }
- void adoptEventPath(Vector<RefPtr<Node> >&);
- void setEventPath(PassRefPtr<NodeList> nodeList) { m_eventPath = nodeList; }
-
- bool currentTargetSameAsTarget() const { return m_currentTarget.get() == m_target.get(); }
- void handleLocalEvents(Event*) const;
-
-protected:
-#ifndef NDEBUG
- bool isUnreachableNode(EventTarget*);
-#endif
- RefPtr<Node> m_node;
- RefPtr<EventTarget> m_currentTarget;
- RefPtr<EventTarget> m_target;
- RefPtr<EventTarget> m_relatedTarget;
- RefPtr<NodeList> m_eventPath;
- RefPtr<TouchEventContext> m_touchEventContext;
-};
-
-#ifndef NDEBUG
-inline bool EventContext::isUnreachableNode(EventTarget* target)
-{
- // FIXME: Checks also for SVG elements.
- return target && target->toNode() && !target->toNode()->isSVGElement() && !target->toNode()->treeScope().isInclusiveAncestorOf(m_node->treeScope());
-}
-#endif
-
-inline void EventContext::setTarget(PassRefPtr<EventTarget> target)
-{
- ASSERT(!isUnreachableNode(target.get()));
- m_target = target;
-}
-
-inline void EventContext::setRelatedTarget(PassRefPtr<EventTarget> relatedTarget)
-{
- ASSERT(!isUnreachableNode(relatedTarget.get()));
- m_relatedTarget = relatedTarget;
-}
-
-}
-
-#endif // EventContext_h
diff --git a/chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.cpp b/chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.cpp
index 032d0b8f9ad..f2b261a6c50 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.cpp
@@ -36,16 +36,21 @@
namespace WebCore {
-PassRefPtr<EventDispatchMediator> EventDispatchMediator::create(PassRefPtr<Event> event)
+PassRefPtrWillBeRawPtr<EventDispatchMediator> EventDispatchMediator::create(PassRefPtrWillBeRawPtr<Event> event)
{
- return adoptRef(new EventDispatchMediator(event));
+ return adoptRefWillBeNoop(new EventDispatchMediator(event));
}
-EventDispatchMediator::EventDispatchMediator(PassRefPtr<Event> event)
+EventDispatchMediator::EventDispatchMediator(PassRefPtrWillBeRawPtr<Event> event)
: m_event(event)
{
}
+void EventDispatchMediator::trace(Visitor* visitor)
+{
+ visitor->trace(m_event);
+}
+
bool EventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
{
ASSERT(m_event.get() == dispatcher->event());
diff --git a/chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.h b/chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.h
index 00ab327689a..233c442273c 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventDispatchMediator.h
@@ -31,6 +31,7 @@
#ifndef EventDispatchMediator_h
#define EventDispatchMediator_h
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -41,20 +42,21 @@ class Event;
class EventDispatcher;
class Node;
-class EventDispatchMediator : public RefCounted<EventDispatchMediator> {
+class EventDispatchMediator : public RefCountedWillBeGarbageCollectedFinalized<EventDispatchMediator> {
public:
- static PassRefPtr<EventDispatchMediator> create(PassRefPtr<Event>);
+ static PassRefPtrWillBeRawPtr<EventDispatchMediator> create(PassRefPtrWillBeRawPtr<Event>);
virtual ~EventDispatchMediator() { };
+ virtual void trace(Visitor*);
virtual bool dispatchEvent(EventDispatcher*) const;
Event* event() const { return m_event.get(); };
protected:
- explicit EventDispatchMediator(PassRefPtr<Event>);
+ explicit EventDispatchMediator(PassRefPtrWillBeRawPtr<Event>);
EventDispatchMediator() { };
- void setEvent(PassRefPtr<Event> event) { m_event = event; };
+ void setEvent(PassRefPtrWillBeRawPtr<Event> event) { m_event = event; };
private:
- RefPtr<Event> m_event;
+ RefPtrWillBeMember<Event> m_event;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/EventDispatcher.cpp b/chromium/third_party/WebKit/Source/core/events/EventDispatcher.cpp
index fa5698ebce9..0a61afe7a2d 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventDispatcher.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/EventDispatcher.cpp
@@ -27,21 +27,24 @@
#include "core/events/EventDispatcher.h"
#include "core/dom/ContainerNode.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/events/EventDispatchMediator.h"
-#include "core/events/EventRetargeter.h"
#include "core/events/MouseEvent.h"
#include "core/events/ScopedEventQueue.h"
#include "core/events/WindowEventContext.h"
-#include "core/inspector/InspectorInstrumentation.h"
#include "core/frame/FrameView.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
+#include "platform/TraceEvent.h"
#include "wtf/RefPtr.h"
namespace WebCore {
static HashSet<Node*>* gNodesDispatchingSimulatedClicks = 0;
-bool EventDispatcher::dispatchEvent(Node* node, PassRefPtr<EventDispatchMediator> mediator)
+bool EventDispatcher::dispatchEvent(Node* node, PassRefPtrWillBeRawPtr<EventDispatchMediator> mediator)
{
+ TRACE_EVENT0("webkit", "EventDispatcher::dispatchEvent");
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
if (!mediator->event())
return true;
@@ -49,7 +52,7 @@ bool EventDispatcher::dispatchEvent(Node* node, PassRefPtr<EventDispatchMediator
return mediator->dispatchEvent(&dispatcher);
}
-EventDispatcher::EventDispatcher(Node* node, PassRefPtr<Event> event)
+EventDispatcher::EventDispatcher(Node* node, PassRefPtrWillBeRawPtr<Event> event)
: m_node(node)
, m_event(event)
#ifndef NDEBUG
@@ -60,10 +63,10 @@ EventDispatcher::EventDispatcher(Node* node, PassRefPtr<Event> event)
ASSERT(m_event.get());
ASSERT(!m_event->type().isNull()); // JavaScript code can create an event with an empty name, but not null.
m_view = node->document().view();
- m_event->eventPath().resetWith(m_node.get());
+ m_event->ensureEventPath().resetWith(m_node.get());
}
-void EventDispatcher::dispatchScopedEvent(Node* node, PassRefPtr<EventDispatchMediator> mediator)
+void EventDispatcher::dispatchScopedEvent(Node* node, PassRefPtrWillBeRawPtr<EventDispatchMediator> mediator)
{
// We need to set the target here because it can go away by the time we actually fire the event.
mediator->event()->setTarget(EventPath::eventTargetRespectingTargetRules(node));
@@ -85,11 +88,13 @@ void EventDispatcher::dispatchSimulatedClick(Node* node, Event* underlyingEvent,
if (mouseEventOptions == SendMouseOverUpDownEvents)
EventDispatcher(node, SimulatedMouseEvent::create(EventTypeNames::mouseover, node->document().domWindow(), underlyingEvent)).dispatch();
- if (mouseEventOptions != SendNoEvents)
+ if (mouseEventOptions != SendNoEvents) {
EventDispatcher(node, SimulatedMouseEvent::create(EventTypeNames::mousedown, node->document().domWindow(), underlyingEvent)).dispatch();
- node->setActive(true);
- if (mouseEventOptions != SendNoEvents)
+ node->setActive(true);
EventDispatcher(node, SimulatedMouseEvent::create(EventTypeNames::mouseup, node->document().domWindow(), underlyingEvent)).dispatch();
+ }
+ // Some elements (e.g. the color picker) may set active state to true before
+ // calling this method and expect the state to be reset during the call.
node->setActive(false);
// always send click
@@ -100,16 +105,19 @@ void EventDispatcher::dispatchSimulatedClick(Node* node, Event* underlyingEvent,
bool EventDispatcher::dispatch()
{
+ TRACE_EVENT0("webkit", "EventDispatcher::dispatch");
+
#ifndef NDEBUG
ASSERT(!m_eventDispatched);
m_eventDispatched = true;
#endif
- ChildNodesLazySnapshot::takeChildNodesLazySnapshot();
m_event->setTarget(EventPath::eventTargetRespectingTargetRules(m_node.get()));
ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
ASSERT(m_event->target());
- WindowEventContext windowEventContext(m_event.get(), m_node.get(), topEventContext());
+ WindowEventContext windowEventContext(m_event.get(), m_node.get(), topNodeEventContext());
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EventDispatch", "type", m_event->type().ascii());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(&m_node->document(), *m_event, windowEventContext.window(), m_node.get(), m_event->eventPath());
void* preDispatchEventHandlerResult;
@@ -124,6 +132,7 @@ bool EventDispatcher::dispatch()
m_event->setTarget(windowEventContext.target());
m_event->setCurrentTarget(0);
InspectorInstrumentation::didDispatchEvent(cookie);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
return !m_event->defaultPrevented();
}
@@ -144,7 +153,7 @@ inline EventDispatchContinuation EventDispatcher::dispatchEventAtCapturing(Windo
return DoneDispatching;
for (size_t i = m_event->eventPath().size() - 1; i > 0; --i) {
- const EventContext& eventContext = m_event->eventPath()[i];
+ const NodeEventContext& eventContext = m_event->eventPath()[i];
if (eventContext.currentTargetSameAsTarget())
continue;
eventContext.handleLocalEvents(m_event.get());
@@ -167,7 +176,7 @@ inline void EventDispatcher::dispatchEventAtBubbling(WindowEventContext& windowC
// Trigger bubbling event handlers, starting at the bottom and working our way up.
size_t size = m_event->eventPath().size();
for (size_t i = 1; i < size; ++i) {
- const EventContext& eventContext = m_event->eventPath()[i];
+ const NodeEventContext& eventContext = m_event->eventPath()[i];
if (eventContext.currentTargetSameAsTarget())
m_event->setEventPhase(Event::AT_TARGET);
else if (m_event->bubbles() && !m_event->cancelBubble())
@@ -218,7 +227,7 @@ inline void EventDispatcher::dispatchEventPostProcess(void* preDispatchEventHand
}
}
-const EventContext* EventDispatcher::topEventContext()
+const NodeEventContext* EventDispatcher::topNodeEventContext()
{
return m_event->eventPath().isEmpty() ? 0 : &m_event->eventPath().last();
}
diff --git a/chromium/third_party/WebKit/Source/core/events/EventDispatcher.h b/chromium/third_party/WebKit/Source/core/events/EventDispatcher.h
index aae65a2d7f2..891a9b9646e 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventDispatcher.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventDispatcher.h
@@ -26,22 +26,18 @@
#ifndef EventDispatcher_h
#define EventDispatcher_h
-#include "core/events/EventContext.h"
#include "core/dom/SimulatedClickOptions.h"
-#include "wtf/Forward.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
namespace WebCore {
class Event;
class EventDispatchMediator;
-class EventTarget;
class FrameView;
class Node;
-class PlatformKeyboardEvent;
-class PlatformMouseEvent;
-class ShadowRoot;
-class TreeScope;
+class NodeEventContext;
class WindowEventContext;
enum EventDispatchContinuation {
@@ -50,9 +46,10 @@ enum EventDispatchContinuation {
};
class EventDispatcher {
+ STACK_ALLOCATED();
public:
- static bool dispatchEvent(Node*, PassRefPtr<EventDispatchMediator>);
- static void dispatchScopedEvent(Node*, PassRefPtr<EventDispatchMediator>);
+ static bool dispatchEvent(Node*, PassRefPtrWillBeRawPtr<EventDispatchMediator>);
+ static void dispatchScopedEvent(Node*, PassRefPtrWillBeRawPtr<EventDispatchMediator>);
static void dispatchSimulatedClick(Node*, Event* underlyingEvent, SimulatedClickMouseEventOptions);
@@ -61,8 +58,8 @@ public:
Event* event() const { return m_event.get(); }
private:
- EventDispatcher(Node*, PassRefPtr<Event>);
- const EventContext* topEventContext();
+ EventDispatcher(Node*, PassRefPtrWillBeRawPtr<Event>);
+ const NodeEventContext* topNodeEventContext();
EventDispatchContinuation dispatchEventPreProcess(void*& preDispatchEventHandlerResult);
EventDispatchContinuation dispatchEventAtCapturing(WindowEventContext&);
@@ -70,8 +67,8 @@ private:
void dispatchEventAtBubbling(WindowEventContext&);
void dispatchEventPostProcess(void* preDispatchEventHandlerResult);
- RefPtr<Node> m_node;
- RefPtr<Event> m_event;
+ RefPtrWillBeMember<Node> m_node;
+ RefPtrWillBeMember<Event> m_event;
RefPtr<FrameView> m_view;
#ifndef NDEBUG
bool m_eventDispatched;
diff --git a/chromium/third_party/WebKit/Source/core/events/EventFactory.h b/chromium/third_party/WebKit/Source/core/events/EventFactory.h
index 2436e3f0000..df9cde337a7 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventFactory.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventFactory.h
@@ -26,6 +26,7 @@
#ifndef EventFactory_h
#define EventFactory_h
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/AtomicString.h"
@@ -33,9 +34,23 @@ namespace WebCore {
class Event;
-class EventFactory {
+class EventFactoryBase {
public:
- static PassRefPtr<Event> create(const String& eventType);
+ virtual PassRefPtrWillBeRawPtr<Event> create(const String& eventType) = 0;
+ virtual ~EventFactoryBase() { }
+
+protected:
+ EventFactoryBase() { }
+};
+
+class EventFactory FINAL : public EventFactoryBase {
+public:
+ static PassOwnPtr<EventFactory> create()
+ {
+ return adoptPtr(new EventFactory());
+ }
+
+ virtual PassRefPtrWillBeRawPtr<Event> create(const String& eventType) OVERRIDE;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/events/EventListener.h b/chromium/third_party/WebKit/Source/core/events/EventListener.h
index 78291043e83..a6270cc2a7a 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventListener.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventListener.h
@@ -43,7 +43,7 @@ namespace WebCore {
virtual bool operator==(const EventListener&) = 0;
virtual void handleEvent(ExecutionContext*, Event*) = 0;
virtual bool wasCreatedFromMarkup() const { return false; }
- virtual DOMWrapperWorld* world() const { return 0; }
+ virtual bool belongsToTheCurrentWorld() const { return false; }
bool isAttribute() const { return virtualisAttribute(); }
Type type() const { return m_type; }
diff --git a/chromium/third_party/WebKit/Source/core/events/EventListenerMap.h b/chromium/third_party/WebKit/Source/core/events/EventListenerMap.h
index fa39f2b23c1..37d72dd3260 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventListenerMap.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventListenerMap.h
@@ -34,7 +34,6 @@
#define EventListenerMap_h
#include "core/events/RegisteredEventListener.h"
-#include "wtf/Forward.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/AtomicStringHash.h"
diff --git a/chromium/third_party/WebKit/Source/core/events/EventPath.cpp b/chromium/third_party/WebKit/Source/core/events/EventPath.cpp
index ca9a57dcdfa..c69d7744ace 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventPath.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/EventPath.cpp
@@ -27,25 +27,22 @@
#include "config.h"
#include "core/events/EventPath.h"
-#include "EventNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
+#include "core/EventNames.h"
+#include "core/SVGNames.h"
#include "core/dom/FullscreenElementStack.h"
-#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/Touch.h"
+#include "core/dom/TouchList.h"
#include "core/dom/shadow/InsertionPoint.h"
#include "core/dom/shadow/ShadowRoot.h"
-#include "core/html/shadow/HTMLShadowElement.h"
-#include "core/svg/SVGElementInstance.h"
+#include "core/events/FocusEvent.h"
+#include "core/events/MouseEvent.h"
+#include "core/events/TouchEvent.h"
+#include "core/events/TouchEventContext.h"
#include "core/svg/SVGUseElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-Node* EventPath::parent(Node* node)
-{
- EventPath eventPath(node);
- return eventPath.size() > 1 ? eventPath[1].node() : 0;
-}
-
EventTarget* EventPath::eventTargetRespectingTargetRules(Node* referenceNode)
{
ASSERT(referenceNode);
@@ -53,20 +50,6 @@ EventTarget* EventPath::eventTargetRespectingTargetRules(Node* referenceNode)
if (referenceNode->isPseudoElement())
return referenceNode->parentNode();
- if (!referenceNode->isSVGElement() || !referenceNode->isInShadowTree())
- return referenceNode;
-
- // Spec: The event handling for the non-exposed tree works as if the referenced element had been textually included
- // as a deeply cloned child of the 'use' element, except that events are dispatched to the SVGElementInstance objects.
- Node* rootNode = referenceNode->treeScope().rootNode();
- Element* shadowHostElement = rootNode->isShadowRoot() ? toShadowRoot(rootNode)->host() : 0;
- // At this time, SVG nodes are not supported in non-<use> shadow trees.
- if (!shadowHostElement || !shadowHostElement->hasTagName(SVGNames::useTag))
- return referenceNode;
- SVGUseElement* useElement = toSVGUseElement(shadowHostElement);
- if (SVGElementInstance* instance = useElement->instanceForShadowTreeElement(referenceNode))
- return instance;
-
return referenceNode;
}
@@ -77,15 +60,6 @@ static inline bool inTheSameScope(ShadowRoot* shadowRoot, EventTarget* target)
static inline EventDispatchBehavior determineDispatchBehavior(Event* event, ShadowRoot* shadowRoot, EventTarget* target)
{
- // Video-only full screen is a mode where we use the shadow DOM as an implementation
- // detail that should not be detectable by the web content.
- if (Element* element = FullscreenElementStack::currentFullScreenElementFrom(&target->toNode()->document())) {
- // FIXME: We assume that if the full screen element is a media element that it's
- // the video-only full screen. Both here and elsewhere. But that is probably wrong.
- if (element->isMediaElement() && shadowRoot && shadowRoot->host() == element)
- return StayInsideShadowDOM;
- }
-
// WebKit never allowed selectstart event to cross the the shadow DOM boundary.
// Changing this breaks existing sites.
// See https://bugs.webkit.org/show_bug.cgi?id=52195 for details.
@@ -106,14 +80,14 @@ static inline EventDispatchBehavior determineDispatchBehavior(Event* event, Shad
}
EventPath::EventPath(Event* event)
- : m_node(0)
+ : m_node(nullptr)
, m_event(event)
{
}
EventPath::EventPath(Node* node)
: m_node(node)
- , m_event(0)
+ , m_event(nullptr)
{
resetWith(node);
}
@@ -122,31 +96,32 @@ void EventPath::resetWith(Node* node)
{
ASSERT(node);
m_node = node;
- m_eventContexts.clear();
+ m_nodeEventContexts.clear();
+ m_treeScopeEventContexts.clear();
calculatePath();
calculateAdjustedTargets();
- calculateAdjustedEventPathForEachNode();
+ calculateTreeScopePrePostOrderNumbers();
}
-void EventPath::addEventContext(Node* node)
+void EventPath::addNodeEventContext(Node* node)
{
- m_eventContexts.append(EventContext(node, eventTargetRespectingTargetRules(node)));
+ m_nodeEventContexts.append(NodeEventContext(node, eventTargetRespectingTargetRules(node)));
}
void EventPath::calculatePath()
{
ASSERT(m_node);
- ASSERT(m_eventContexts.isEmpty());
- m_node->document().updateDistributionForNodeIfNeeded(const_cast<Node*>(m_node));
+ ASSERT(m_nodeEventContexts.isEmpty());
+ m_node->document().updateDistributionForNodeIfNeeded(const_cast<Node*>(m_node.get()));
Node* current = m_node;
- addEventContext(current);
+ addNodeEventContext(current);
if (!m_node->inDocument())
return;
while (current) {
if (current->isShadowRoot() && m_event && determineDispatchBehavior(m_event, toShadowRoot(current), m_node) == StayInsideShadowDOM)
break;
- Vector<InsertionPoint*, 8> insertionPoints;
+ WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
collectDestinationInsertionPoints(*current, insertionPoints);
if (!insertionPoints.isEmpty()) {
for (size_t i = 0; i < insertionPoints.size(); ++i) {
@@ -155,103 +130,227 @@ void EventPath::calculatePath()
ShadowRoot* containingShadowRoot = insertionPoint->containingShadowRoot();
ASSERT(containingShadowRoot);
if (!containingShadowRoot->isOldest())
- addEventContext(containingShadowRoot->olderShadowRoot());
+ addNodeEventContext(containingShadowRoot->olderShadowRoot());
}
- addEventContext(insertionPoint);
+ addNodeEventContext(insertionPoint);
}
current = insertionPoints.last();
continue;
}
if (current->isShadowRoot()) {
current = current->shadowHost();
- addEventContext(current);
+ addNodeEventContext(current);
} else {
current = current->parentNode();
if (current)
- addEventContext(current);
+ addNodeEventContext(current);
}
}
}
-void EventPath::calculateAdjustedEventPathForEachNode()
+void EventPath::calculateTreeScopePrePostOrderNumbers()
{
- if (!RuntimeEnabledFeatures::shadowDOMEnabled())
- return;
- TreeScope* lastScope = 0;
- for (size_t i = 0; i < size(); ++i) {
- TreeScope* currentScope = &at(i).node()->treeScope();
- if (currentScope == lastScope) {
- // Fast path.
- at(i).setEventPath(at(i - 1).eventPath());
+ // Precondition:
+ // - TreeScopes in m_treeScopeEventContexts must be *connected* in the same tree of trees.
+ // - The root tree must be included.
+ WillBeHeapHashMap<RawPtrWillBeMember<const TreeScope>, RawPtrWillBeMember<TreeScopeEventContext> > treeScopeEventContextMap;
+ for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i)
+ treeScopeEventContextMap.add(&m_treeScopeEventContexts[i]->treeScope(), m_treeScopeEventContexts[i].get());
+ TreeScopeEventContext* rootTree = 0;
+ for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
+ TreeScopeEventContext* treeScopeEventContext = m_treeScopeEventContexts[i].get();
+ // Use olderShadowRootOrParentTreeScope here for parent-child relationships.
+ // See the definition of trees of trees in the Shado DOM spec: http://w3c.github.io/webcomponents/spec/shadow/
+ TreeScope* parent = treeScopeEventContext->treeScope().olderShadowRootOrParentTreeScope();
+ if (!parent) {
+ ASSERT(!rootTree);
+ rootTree = treeScopeEventContext;
continue;
}
- lastScope = currentScope;
- Vector<RefPtr<Node> > nodes;
- nodes.reserveInitialCapacity(size());
- for (size_t j = 0; j < size(); ++j) {
- if (at(j).node()->treeScope().isInclusiveAncestorOf(*currentScope))
- nodes.append(at(j).node());
+ ASSERT(treeScopeEventContextMap.find(parent) != treeScopeEventContextMap.end());
+ treeScopeEventContextMap.find(parent)->value->addChild(*treeScopeEventContext);
+ }
+ ASSERT(rootTree);
+ rootTree->calculatePrePostOrderNumber(0);
+}
+
+TreeScopeEventContext* EventPath::ensureTreeScopeEventContext(Node* currentTarget, TreeScope* treeScope, TreeScopeEventContextMap& treeScopeEventContextMap)
+{
+ if (!treeScope)
+ return 0;
+ TreeScopeEventContext* treeScopeEventContext;
+ bool isNewEntry;
+ {
+ TreeScopeEventContextMap::AddResult addResult = treeScopeEventContextMap.add(treeScope, nullptr);
+ if ((isNewEntry = addResult.isNewEntry))
+ addResult.storedValue->value = TreeScopeEventContext::create(*treeScope);
+ treeScopeEventContext = addResult.storedValue->value.get();
+ }
+ if (isNewEntry) {
+ TreeScopeEventContext* parentTreeScopeEventContext = ensureTreeScopeEventContext(0, treeScope->olderShadowRootOrParentTreeScope(), treeScopeEventContextMap);
+ if (parentTreeScopeEventContext && parentTreeScopeEventContext->target()) {
+ treeScopeEventContext->setTarget(parentTreeScopeEventContext->target());
+ } else if (currentTarget) {
+ treeScopeEventContext->setTarget(eventTargetRespectingTargetRules(currentTarget));
}
- at(i).adoptEventPath(nodes);
+ } else if (!treeScopeEventContext->target() && currentTarget) {
+ treeScopeEventContext->setTarget(eventTargetRespectingTargetRules(currentTarget));
}
+ return treeScopeEventContext;
}
-#ifndef NDEBUG
-static inline bool movedFromOlderToYounger(const TreeScope& lastTreeScope, const TreeScope& currentTreeScope)
+void EventPath::calculateAdjustedTargets()
{
- Node* rootNode = lastTreeScope.rootNode();
- return rootNode->isShadowRoot() && toShadowRoot(rootNode)->youngerShadowRoot() == currentTreeScope.rootNode();
+ const TreeScope* lastTreeScope = 0;
+
+ TreeScopeEventContextMap treeScopeEventContextMap;
+ TreeScopeEventContext* lastTreeScopeEventContext = 0;
+
+ for (size_t i = 0; i < size(); ++i) {
+ Node* currentNode = at(i).node();
+ TreeScope& currentTreeScope = currentNode->treeScope();
+ if (lastTreeScope != &currentTreeScope) {
+ lastTreeScopeEventContext = ensureTreeScopeEventContext(currentNode, &currentTreeScope, treeScopeEventContextMap);
+ }
+ ASSERT(lastTreeScopeEventContext);
+ at(i).setTreeScopeEventContext(lastTreeScopeEventContext);
+ lastTreeScope = &currentTreeScope;
+ }
+ m_treeScopeEventContexts.appendRange(treeScopeEventContextMap.values().begin(), treeScopeEventContextMap.values().end());
}
-static inline bool movedFromYoungerToOlder(const TreeScope& lastTreeScope, const TreeScope& currentTreeScope)
+void EventPath::buildRelatedNodeMap(const Node* relatedNode, RelatedTargetMap& relatedTargetMap)
{
- Node* rootNode = lastTreeScope.rootNode();
- return rootNode->isShadowRoot() && toShadowRoot(rootNode)->olderShadowRoot() == currentTreeScope.rootNode();
+ EventPath relatedTargetEventPath(const_cast<Node*>(relatedNode));
+ for (size_t i = 0; i < relatedTargetEventPath.m_treeScopeEventContexts.size(); ++i) {
+ TreeScopeEventContext* treeScopeEventContext = relatedTargetEventPath.m_treeScopeEventContexts[i].get();
+ relatedTargetMap.add(&treeScopeEventContext->treeScope(), treeScopeEventContext->target());
+ }
}
-#endif
-static inline bool movedFromChildToParent(const TreeScope& lastTreeScope, const TreeScope& currentTreeScope)
+EventTarget* EventPath::findRelatedNode(TreeScope* scope, RelatedTargetMap& relatedTargetMap)
{
- return lastTreeScope.parentTreeScope() == &currentTreeScope;
+ WillBeHeapVector<RawPtrWillBeMember<TreeScope>, 32> parentTreeScopes;
+ EventTarget* relatedNode = 0;
+ while (scope) {
+ parentTreeScopes.append(scope);
+ RelatedTargetMap::const_iterator iter = relatedTargetMap.find(scope);
+ if (iter != relatedTargetMap.end() && iter->value) {
+ relatedNode = iter->value;
+ break;
+ }
+ scope = scope->olderShadowRootOrParentTreeScope();
+ }
+ ASSERT(relatedNode);
+ for (WillBeHeapVector<RawPtrWillBeMember<TreeScope>, 32>::iterator iter = parentTreeScopes.begin(); iter < parentTreeScopes.end(); ++iter)
+ relatedTargetMap.add(*iter, relatedNode);
+ return relatedNode;
}
-static inline bool movedFromParentToChild(const TreeScope& lastTreeScope, const TreeScope& currentTreeScope)
+void EventPath::adjustForRelatedTarget(Node* target, EventTarget* relatedTarget)
{
- return currentTreeScope.parentTreeScope() == &lastTreeScope;
+ if (!target)
+ return;
+ if (!relatedTarget)
+ return;
+ Node* relatedNode = relatedTarget->toNode();
+ if (!relatedNode)
+ return;
+ if (target->document() != relatedNode->document())
+ return;
+ if (!target->inDocument() || !relatedNode->inDocument())
+ return;
+
+ RelatedTargetMap relatedNodeMap;
+ buildRelatedNodeMap(relatedNode, relatedNodeMap);
+
+ for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
+ TreeScopeEventContext* treeScopeEventContext = m_treeScopeEventContexts[i].get();
+ EventTarget* adjustedRelatedTarget = findRelatedNode(&treeScopeEventContext->treeScope(), relatedNodeMap);
+ ASSERT(adjustedRelatedTarget);
+ treeScopeEventContext->setRelatedTarget(adjustedRelatedTarget);
+ }
+
+ shrinkIfNeeded(target, relatedTarget);
}
-void EventPath::calculateAdjustedTargets()
+void EventPath::shrinkIfNeeded(const Node* target, const EventTarget* relatedTarget)
{
- Vector<Node*, 32> targetStack;
- const TreeScope* lastTreeScope = 0;
- bool isSVGElement = at(0).node()->isSVGElement();
+ // Synthetic mouse events can have a relatedTarget which is identical to the target.
+ bool targetIsIdenticalToToRelatedTarget = (target == relatedTarget);
for (size_t i = 0; i < size(); ++i) {
- Node* current = at(i).node();
- const TreeScope& currentTreeScope = current->treeScope();
- if (targetStack.isEmpty()) {
- targetStack.append(current);
- } else if (*lastTreeScope != currentTreeScope && !isSVGElement) {
- if (movedFromParentToChild(*lastTreeScope, currentTreeScope)) {
- targetStack.append(targetStack.last());
- } else if (movedFromChildToParent(*lastTreeScope, currentTreeScope)) {
- ASSERT(!targetStack.isEmpty());
- targetStack.removeLast();
- if (targetStack.isEmpty())
- targetStack.append(current);
- } else {
- ASSERT(movedFromYoungerToOlder(*lastTreeScope, currentTreeScope) || movedFromOlderToYounger(*lastTreeScope, currentTreeScope));
- ASSERT(!targetStack.isEmpty());
- targetStack.removeLast();
- if (targetStack.isEmpty())
- targetStack.append(current);
- else
- targetStack.append(targetStack.last());
+ if (targetIsIdenticalToToRelatedTarget) {
+ if (target->treeScope().rootNode() == at(i).node()) {
+ shrink(i + 1);
+ break;
}
+ } else if (at(i).target() == at(i).relatedTarget()) {
+ // Event dispatching should be stopped here.
+ shrink(i);
+ break;
+ }
+ }
+}
+
+void EventPath::adjustForTouchEvent(Node* node, TouchEvent& touchEvent)
+{
+ WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouches;
+ WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTargetTouches;
+ WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedChangedTouches;
+ WillBeHeapVector<RawPtrWillBeMember<TreeScope> > treeScopes;
+
+ for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
+ TouchEventContext* touchEventContext = m_treeScopeEventContexts[i]->ensureTouchEventContext();
+ adjustedTouches.append(&touchEventContext->touches());
+ adjustedTargetTouches.append(&touchEventContext->targetTouches());
+ adjustedChangedTouches.append(&touchEventContext->changedTouches());
+ treeScopes.append(&m_treeScopeEventContexts[i]->treeScope());
+ }
+
+ adjustTouchList(node, touchEvent.touches(), adjustedTouches, treeScopes);
+ adjustTouchList(node, touchEvent.targetTouches(), adjustedTargetTouches, treeScopes);
+ adjustTouchList(node, touchEvent.changedTouches(), adjustedChangedTouches, treeScopes);
+
+#ifndef NDEBUG
+ for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
+ TreeScope& treeScope = m_treeScopeEventContexts[i]->treeScope();
+ TouchEventContext* touchEventContext = m_treeScopeEventContexts[i]->touchEventContext();
+ checkReachability(treeScope, touchEventContext->touches());
+ checkReachability(treeScope, touchEventContext->targetTouches());
+ checkReachability(treeScope, touchEventContext->changedTouches());
+ }
+#endif
+}
+
+void EventPath::adjustTouchList(const Node* node, const TouchList* touchList, WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouchList, const WillBeHeapVector<RawPtrWillBeMember<TreeScope> >& treeScopes)
+{
+ if (!touchList)
+ return;
+ for (size_t i = 0; i < touchList->length(); ++i) {
+ const Touch& touch = *touchList->item(i);
+ RelatedTargetMap relatedNodeMap;
+ buildRelatedNodeMap(touch.target()->toNode(), relatedNodeMap);
+ for (size_t j = 0; j < treeScopes.size(); ++j) {
+ adjustedTouchList[j]->append(touch.cloneWithNewTarget(findRelatedNode(treeScopes[j], relatedNodeMap)));
}
- at(i).setTarget(eventTargetRespectingTargetRules(targetStack.last()));
- lastTreeScope = &currentTreeScope;
}
}
+#ifndef NDEBUG
+void EventPath::checkReachability(TreeScope& treeScope, TouchList& touchList)
+{
+ for (size_t i = 0; i < touchList.length(); ++i)
+ ASSERT(touchList.item(i)->target()->toNode()->treeScope().isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(treeScope));
+}
+#endif
+
+void EventPath::trace(Visitor* visitor)
+{
+ visitor->trace(m_nodeEventContexts);
+ visitor->trace(m_node);
+ visitor->trace(m_event);
+ visitor->trace(m_treeScopeEventContexts);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/events/EventPath.h b/chromium/third_party/WebKit/Source/core/events/EventPath.h
index e5db6c4caf1..85232b1cd49 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventPath.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventPath.h
@@ -27,9 +27,10 @@
#ifndef EventPath_h
#define EventPath_h
-#include "core/events/EventContext.h"
-
-#include "wtf/OwnPtr.h"
+#include "core/events/NodeEventContext.h"
+#include "core/events/TreeScopeEventContext.h"
+#include "platform/heap/Handle.h"
+#include "wtf/HashMap.h"
#include "wtf/Vector.h"
namespace WebCore {
@@ -37,44 +38,67 @@ namespace WebCore {
class Event;
class EventTarget;
class Node;
+class TouchEvent;
+class TouchList;
+class TreeScope;
enum EventDispatchBehavior {
RetargetEvent,
StayInsideShadowDOM
};
-class EventPath {
+class EventPath : public NoBaseWillBeGarbageCollectedFinalized<EventPath> {
public:
explicit EventPath(Event*);
explicit EventPath(Node*);
void resetWith(Node*);
- EventContext& operator[](size_t index) { return m_eventContexts[index]; }
- const EventContext& operator[](size_t index) const { return m_eventContexts[index]; }
- const EventContext& last() const { return m_eventContexts[size() - 1]; }
+ NodeEventContext& operator[](size_t index) { return m_nodeEventContexts[index]; }
+ const NodeEventContext& operator[](size_t index) const { return m_nodeEventContexts[index]; }
+ const NodeEventContext& last() const { return m_nodeEventContexts[size() - 1]; }
- bool isEmpty() const { return m_eventContexts.isEmpty(); }
- size_t size() const { return m_eventContexts.size(); }
+ bool isEmpty() const { return m_nodeEventContexts.isEmpty(); }
+ size_t size() const { return m_nodeEventContexts.size(); }
- void shrink(size_t newSize) { m_eventContexts.shrink(newSize); }
+ void adjustForRelatedTarget(Node*, EventTarget* relatedTarget);
+ void adjustForTouchEvent(Node*, TouchEvent&);
- static Node* parent(Node*);
static EventTarget* eventTargetRespectingTargetRules(Node*);
+ void trace(Visitor*);
+
private:
EventPath();
- EventContext& at(size_t index) { return m_eventContexts[index]; }
+ NodeEventContext& at(size_t index) { return m_nodeEventContexts[index]; }
- void addEventContext(Node*);
+ void addNodeEventContext(Node*);
void calculatePath();
void calculateAdjustedTargets();
- void calculateAdjustedEventPathForEachNode();
+ void calculateTreeScopePrePostOrderNumbers();
+
+ void shrink(size_t newSize) { m_nodeEventContexts.shrink(newSize); }
+ void shrinkIfNeeded(const Node* target, const EventTarget* relatedTarget);
+
+ void adjustTouchList(const Node*, const TouchList*, WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouchList, const WillBeHeapVector<RawPtrWillBeMember<TreeScope> >& treeScopes);
+
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<TreeScope>, RefPtrWillBeMember<TreeScopeEventContext> > TreeScopeEventContextMap;
+ TreeScopeEventContext* ensureTreeScopeEventContext(Node* currentTarget, TreeScope*, TreeScopeEventContextMap&);
+
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<TreeScope>, RawPtrWillBeMember<EventTarget> > RelatedTargetMap;
+
+ static void buildRelatedNodeMap(const Node*, RelatedTargetMap&);
+ static EventTarget* findRelatedNode(TreeScope*, RelatedTargetMap&);
+
+#ifndef NDEBUG
+ static void checkReachability(TreeScope&, TouchList&);
+#endif
- Vector<EventContext, 64> m_eventContexts;
- Node* m_node;
- Event* m_event;
+ WillBeHeapVector<NodeEventContext, 64> m_nodeEventContexts;
+ RawPtrWillBeMember<Node> m_node;
+ RawPtrWillBeMember<Event> m_event;
+ WillBeHeapVector<RefPtrWillBeMember<TreeScopeEventContext> > m_treeScopeEventContexts;
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/events/EventQueue.h b/chromium/third_party/WebKit/Source/core/events/EventQueue.h
index 770ae797d21..9f59b70cbd0 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventQueue.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventQueue.h
@@ -27,6 +27,7 @@
#ifndef EventQueue_h
#define EventQueue_h
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
#include "wtf/PassOwnPtr.h"
@@ -35,10 +36,11 @@ namespace WebCore {
class Event;
-class EventQueue {
+class EventQueue : public NoBaseWillBeGarbageCollectedFinalized<EventQueue> {
public:
virtual ~EventQueue() { }
- virtual bool enqueueEvent(PassRefPtr<Event>) = 0;
+ virtual void trace(Visitor*) { }
+ virtual bool enqueueEvent(PassRefPtrWillBeRawPtr<Event>) = 0;
virtual bool cancelEvent(Event*) = 0;
// The accumulated and all the future events will be discarded, no events will be dispatched anymore.
virtual void close() = 0;
diff --git a/chromium/third_party/WebKit/Source/core/events/EventRetargeter.cpp b/chromium/third_party/WebKit/Source/core/events/EventRetargeter.cpp
deleted file mode 100644
index d225dbc94b9..00000000000
--- a/chromium/third_party/WebKit/Source/core/events/EventRetargeter.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/events/EventRetargeter.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "core/dom/ContainerNode.h"
-#include "core/dom/FullscreenElementStack.h"
-#include "core/dom/Touch.h"
-#include "core/dom/TouchList.h"
-#include "core/dom/TreeScope.h"
-#include "core/dom/shadow/InsertionPoint.h"
-#include "core/dom/shadow/ShadowRoot.h"
-#include "core/events/EventContext.h"
-#include "core/events/EventPath.h"
-#include "core/events/FocusEvent.h"
-#include "core/events/MouseEvent.h"
-#include "core/events/TouchEvent.h"
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-void EventRetargeter::adjustForMouseEvent(Node* node, MouseEvent& mouseEvent)
-{
- adjustForRelatedTarget(node, mouseEvent.relatedTarget(), mouseEvent.eventPath());
-}
-
-void EventRetargeter::adjustForFocusEvent(Node* node, FocusEvent& focusEvent)
-{
- adjustForRelatedTarget(node, focusEvent.relatedTarget(), focusEvent.eventPath());
-}
-
-void EventRetargeter::adjustForTouchEvent(Node* node, TouchEvent& touchEvent)
-{
- EventPath& eventPath = touchEvent.eventPath();
- size_t eventPathSize = eventPath.size();
-
- EventPathTouchLists eventPathTouches(eventPathSize);
- EventPathTouchLists eventPathTargetTouches(eventPathSize);
- EventPathTouchLists eventPathChangedTouches(eventPathSize);
-
- for (size_t i = 0; i < eventPathSize; ++i) {
- TouchEventContext* touchEventContext = eventPath[i].ensureTouchEventContext();
- eventPathTouches[i] = touchEventContext->touches();
- eventPathTargetTouches[i] = touchEventContext->targetTouches();
- eventPathChangedTouches[i] = touchEventContext->changedTouches();
- }
-
- adjustTouchList(node, touchEvent.touches(), eventPath, eventPathTouches);
- adjustTouchList(node, touchEvent.targetTouches(), eventPath, eventPathTargetTouches);
- adjustTouchList(node, touchEvent.changedTouches(), eventPath, eventPathChangedTouches);
-
-#ifndef NDEBUG
- for (size_t i = 0; i < eventPathSize; ++i) {
- checkReachability(node, eventPath[i].touchEventContext()->touches());
- checkReachability(node, eventPath[i].touchEventContext()->targetTouches());
- checkReachability(node, eventPath[i].touchEventContext()->changedTouches());
- }
-#endif
-}
-
-#ifndef NDEBUG
-void EventRetargeter::checkReachability(Node* node, TouchList* touchList)
-{
- for (size_t i = 0; i < touchList->length(); ++i)
- ASSERT(touchList->item(i)->target()->toNode()->treeScope().isInclusiveAncestorOf(node->treeScope()));
-}
-#endif
-
-void EventRetargeter::adjustTouchList(const Node* node, const TouchList* touchList, const EventPath& eventPath, EventPathTouchLists& eventPathTouchLists)
-{
- if (!touchList)
- return;
- size_t eventPathSize = eventPath.size();
- ASSERT(eventPathTouchLists.size() == eventPathSize);
- for (size_t i = 0; i < touchList->length(); ++i) {
- const Touch& touch = *touchList->item(i);
- AdjustedTargets adjustedNodes;
- calculateAdjustedNodes(node, touch.target()->toNode(), DoesNotStopAtBoundary, const_cast<EventPath&>(eventPath), adjustedNodes);
- ASSERT(adjustedNodes.size() == eventPathSize);
- for (size_t j = 0; j < eventPathSize; ++j)
- eventPathTouchLists[j]->append(touch.cloneWithNewTarget(adjustedNodes[j].get()));
- }
-}
-
-void EventRetargeter::adjustForRelatedTarget(const Node* node, EventTarget* relatedTarget, EventPath& eventPath)
-{
- if (!node)
- return;
- if (!relatedTarget)
- return;
- Node* relatedNode = relatedTarget->toNode();
- if (!relatedNode)
- return;
- AdjustedTargets adjustedNodes;
- calculateAdjustedNodes(node, relatedNode, StopAtBoundaryIfNeeded, eventPath, adjustedNodes);
- ASSERT(adjustedNodes.size() <= eventPath.size());
- for (size_t i = 0; i < adjustedNodes.size(); ++i) {
- eventPath[i].setRelatedTarget(adjustedNodes[i]);
- }
-}
-
-void EventRetargeter::calculateAdjustedNodes(const Node* node, const Node* relatedNode, EventWithRelatedTargetDispatchBehavior eventWithRelatedTargetDispatchBehavior, EventPath& eventPath, AdjustedTargets& adjustedTargets)
-{
- RelatedTargetMap relatedNodeMap;
- buildRelatedNodeMap(relatedNode, relatedNodeMap);
-
- // Synthetic mouse events can have a relatedTarget which is identical to the target.
- bool targetIsIdenticalToToRelatedTarget = (node == relatedNode);
-
- TreeScope* lastTreeScope = 0;
- EventTarget* adjustedTarget = 0;
-
- for (size_t i = 0; i < eventPath.size(); ++i) {
- TreeScope* scope = &eventPath[i].node()->treeScope();
- if (scope == lastTreeScope) {
- // Re-use the previous adjustedRelatedTarget if treeScope does not change. Just for the performance optimization.
- adjustedTargets.append(adjustedTarget);
- } else {
- adjustedTarget = findRelatedNode(scope, relatedNodeMap);
- adjustedTargets.append(adjustedTarget);
- }
- lastTreeScope = scope;
- if (eventWithRelatedTargetDispatchBehavior == DoesNotStopAtBoundary)
- continue;
- if (targetIsIdenticalToToRelatedTarget) {
- if (node->treeScope().rootNode() == eventPath[i].node()) {
- eventPath.shrink(i + 1);
- break;
- }
- } else if (eventPath[i].target() == adjustedTarget) {
- // Event dispatching should be stopped here.
- eventPath.shrink(i);
- adjustedTargets.shrink(adjustedTargets.size() - 1);
- break;
- }
- }
-}
-
-void EventRetargeter::buildRelatedNodeMap(const Node* relatedNode, RelatedTargetMap& relatedTargetMap)
-{
- TreeScope* lastTreeScope = 0;
- EventPath eventPath(const_cast<Node*>(relatedNode));
- for (size_t i = 0; i < eventPath.size(); ++i) {
- TreeScope* treeScope = &eventPath[i].node()->treeScope();
- if (treeScope != lastTreeScope)
- relatedTargetMap.add(treeScope, eventPath[i].target());
- lastTreeScope = treeScope;
- }
-}
-
-EventTarget* EventRetargeter::findRelatedNode(TreeScope* scope, RelatedTargetMap& relatedTargetMap)
-{
- Vector<TreeScope*, 32> parentTreeScopes;
- EventTarget* relatedNode = 0;
- while (scope) {
- parentTreeScopes.append(scope);
- RelatedTargetMap::const_iterator found = relatedTargetMap.find(scope);
- if (found != relatedTargetMap.end()) {
- relatedNode = found->value;
- break;
- }
- scope = scope->parentTreeScope();
- }
- for (Vector<TreeScope*, 32>::iterator iter = parentTreeScopes.begin(); iter < parentTreeScopes.end(); ++iter)
- relatedTargetMap.add(*iter, relatedNode);
- return relatedNode;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/events/EventRetargeter.h b/chromium/third_party/WebKit/Source/core/events/EventRetargeter.h
deleted file mode 100644
index 38d391c348b..00000000000
--- a/chromium/third_party/WebKit/Source/core/events/EventRetargeter.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef EventRetargeter_h
-#define EventRetargeter_h
-
-#include "wtf/HashMap.h"
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class EventPath;
-class EventTarget;
-class FocusEvent;
-class MouseEvent;
-class Node;
-class TouchEvent;
-class TouchList;
-class TreeScope;
-
-class EventRetargeter {
-public:
- static void adjustForMouseEvent(Node*, MouseEvent&);
- static void adjustForFocusEvent(Node*, FocusEvent&);
- typedef Vector<RefPtr<TouchList> > EventPathTouchLists;
- static void adjustForTouchEvent(Node*, TouchEvent&);
-
-private:
- typedef Vector<RefPtr<EventTarget> > AdjustedTargets;
- typedef HashMap<TreeScope*, EventTarget*> RelatedTargetMap;
- enum EventWithRelatedTargetDispatchBehavior {
- StopAtBoundaryIfNeeded,
- DoesNotStopAtBoundary
- };
- static void adjustForRelatedTarget(const Node*, EventTarget* relatedTarget, EventPath&);
- static void calculateAdjustedNodes(const Node*, const Node* relatedNode, EventWithRelatedTargetDispatchBehavior, EventPath&, AdjustedTargets&);
- static void buildRelatedNodeMap(const Node*, RelatedTargetMap&);
- static EventTarget* findRelatedNode(TreeScope*, RelatedTargetMap&);
- static void adjustTouchList(const Node*, const TouchList*, const EventPath&, EventPathTouchLists&);
-#ifndef NDEBUG
- static void checkReachability(Node*, TouchList*);
-#endif
-};
-
-}
-
-#endif // EventRetargeter_h
diff --git a/chromium/third_party/WebKit/Source/core/events/EventSender.h b/chromium/third_party/WebKit/Source/core/events/EventSender.h
index f07678f23c4..b5da763e59b 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventSender.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventSender.h
@@ -54,8 +54,8 @@ private:
AtomicString m_eventType;
Timer<EventSender<T> > m_timer;
- Vector<T*> m_dispatchSoonList;
- Vector<T*> m_dispatchingList;
+ WillBePersistentHeapVector<RawPtrWillBeMember<T> > m_dispatchSoonList;
+ WillBePersistentHeapVector<RawPtrWillBeMember<T> > m_dispatchingList;
};
template<typename T> EventSender<T>::EventSender(const AtomicString& eventType)
@@ -68,7 +68,7 @@ template<typename T> void EventSender<T>::dispatchEventSoon(T* sender)
{
m_dispatchSoonList.append(sender);
if (!m_timer.isActive())
- m_timer.startOneShot(0);
+ m_timer.startOneShot(0, FROM_HERE);
}
template<typename T> void EventSender<T>::cancelEvent(T* sender)
@@ -78,12 +78,12 @@ template<typename T> void EventSender<T>::cancelEvent(T* sender)
size_t size = m_dispatchSoonList.size();
for (size_t i = 0; i < size; ++i) {
if (m_dispatchSoonList[i] == sender)
- m_dispatchSoonList[i] = 0;
+ m_dispatchSoonList[i] = nullptr;
}
size = m_dispatchingList.size();
for (size_t i = 0; i < size; ++i) {
if (m_dispatchingList[i] == sender)
- m_dispatchingList[i] = 0;
+ m_dispatchingList[i] = nullptr;
}
}
@@ -101,7 +101,7 @@ template<typename T> void EventSender<T>::dispatchPendingEvents()
size_t size = m_dispatchingList.size();
for (size_t i = 0; i < size; ++i) {
if (T* sender = m_dispatchingList[i]) {
- m_dispatchingList[i] = 0;
+ m_dispatchingList[i] = nullptr;
sender->dispatchPendingEvent(this);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/events/EventTarget.cpp b/chromium/third_party/WebKit/Source/core/events/EventTarget.cpp
index 6e96b47c6cd..04dea3543ff 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventTarget.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/EventTarget.cpp
@@ -32,14 +32,14 @@
#include "config.h"
#include "core/events/EventTarget.h"
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/events/Event.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/NoEventDispatchAssertion.h"
+#include "core/editing/Editor.h"
+#include "core/events/Event.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/DOMWindow.h"
-#include "platform/UserGestureIndicator.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/StdLibExtras.h"
#include "wtf/Vector.h"
@@ -64,7 +64,7 @@ Node* EventTarget::toNode()
return 0;
}
-DOMWindow* EventTarget::toDOMWindow()
+LocalDOMWindow* EventTarget::toDOMWindow()
{
return 0;
}
@@ -74,7 +74,7 @@ MessagePort* EventTarget::toMessagePort()
return 0;
}
-inline DOMWindow* EventTarget::executingWindow()
+inline LocalDOMWindow* EventTarget::executingWindow()
{
if (ExecutionContext* context = executionContext())
return context->executingWindow();
@@ -83,6 +83,10 @@ inline DOMWindow* EventTarget::executingWindow()
bool EventTarget::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
{
+ // FIXME: listener null check should throw TypeError (and be done in
+ // generated bindings), but breaks legacy content. http://crbug.com/249598
+ if (!listener)
+ return false;
return ensureEventTargetData().eventListenerMap.add(eventType, listener, useCapture);
}
@@ -117,44 +121,34 @@ bool EventTarget::removeEventListener(const AtomicString& eventType, EventListen
return true;
}
-bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld)
+bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
{
- clearAttributeEventListener(eventType, isolatedWorld);
+ clearAttributeEventListener(eventType);
if (!listener)
return false;
return addEventListener(eventType, listener, false);
}
-EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld)
+EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
{
const EventListenerVector& entry = getEventListeners(eventType);
for (size_t i = 0; i < entry.size(); ++i) {
EventListener* listener = entry[i].listener.get();
- if (listener->isAttribute()) {
- DOMWrapperWorld* listenerWorld = listener->world();
- // Worker listener
- if (!listenerWorld) {
- ASSERT(!isolatedWorld);
- return listener;
- }
- if (listenerWorld->isMainWorld() && !isolatedWorld)
- return listener;
- if (listenerWorld == isolatedWorld)
- return listener;
- }
+ if (listener->isAttribute() && listener->belongsToTheCurrentWorld())
+ return listener;
}
return 0;
}
-bool EventTarget::clearAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld)
+bool EventTarget::clearAttributeEventListener(const AtomicString& eventType)
{
- EventListener* listener = getAttributeEventListener(eventType, isolatedWorld);
+ EventListener* listener = getAttributeEventListener(eventType);
if (!listener)
return false;
return removeEventListener(eventType, listener, false);
}
-bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionState& exceptionState)
+bool EventTarget::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event, ExceptionState& exceptionState)
{
if (!event) {
exceptionState.throwDOMException(InvalidStateError, "The event provided is null.");
@@ -175,7 +169,7 @@ bool EventTarget::dispatchEvent(PassRefPtr<Event> event, ExceptionState& excepti
return dispatchEvent(event);
}
-bool EventTarget::dispatchEvent(PassRefPtr<Event> event)
+bool EventTarget::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
event->setTarget(this);
event->setCurrentTarget(this);
@@ -189,7 +183,7 @@ void EventTarget::uncaughtExceptionInEventHandler()
{
}
-static AtomicString legacyType(const Event* event)
+static const AtomicString& legacyType(const Event* event)
{
if (event->type() == EventTypeNames::transitionend)
return EventTypeNames::webkitTransitionEnd;
@@ -206,7 +200,7 @@ static AtomicString legacyType(const Event* event)
if (event->type() == EventTypeNames::wheel)
return EventTypeNames::mousewheel;
- return emptyString();
+ return emptyAtom;
}
void EventTarget::countLegacyEvents(const AtomicString& legacyTypeName, EventListenerVector* listenersVector, EventListenerVector* legacyListenersVector)
@@ -239,14 +233,14 @@ void EventTarget::countLegacyEvents(const AtomicString& legacyTypeName, EventLis
}
if (shouldCount) {
- if (DOMWindow* executingWindow = this->executingWindow()) {
+ if (LocalDOMWindow* executingWindow = this->executingWindow()) {
if (legacyListenersVector) {
if (listenersVector)
- UseCounter::count(executingWindow, prefixedAndUnprefixedFeature);
+ UseCounter::count(executingWindow->document(), prefixedAndUnprefixedFeature);
else
- UseCounter::count(executingWindow, prefixedFeature);
+ UseCounter::count(executingWindow->document(), prefixedFeature);
} else if (listenersVector) {
- UseCounter::count(executingWindow, unprefixedFeature);
+ UseCounter::count(executingWindow->document(), unprefixedFeature);
}
}
}
@@ -268,7 +262,11 @@ bool EventTarget::fireEventListeners(Event* event)
EventListenerVector* listenersVector = d->eventListenerMap.find(event->type());
if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled() && (event->type() == EventTypeNames::animationiteration || event->type() == EventTypeNames::animationend
- || event->type() == EventTypeNames::animationstart))
+ || event->type() == EventTypeNames::animationstart)
+ // Some code out-there uses custom events to dispatch unprefixed animation events manually,
+ // we can safely remove all this block when cssAnimationUnprefixedEnabled is always on, this
+ // is really a special case. DO NOT ADD MORE EVENTS HERE.
+ && event->interfaceName() != EventNames::CustomEvent)
listenersVector = 0;
if (listenersVector) {
@@ -280,13 +278,14 @@ bool EventTarget::fireEventListeners(Event* event)
event->setType(unprefixedTypeName);
}
+ Editor::countEvent(executionContext(), event);
countLegacyEvents(legacyTypeName, listenersVector, legacyListenersVector);
return !event->defaultPrevented();
}
void EventTarget::fireEventListeners(Event* event, EventTargetData* d, EventListenerVector& entry)
{
- RefPtr<EventTarget> protect = this;
+ RefPtrWillBeRawPtr<EventTarget> protect(this);
// Fire all listeners registered for this event. Don't fire listeners removed
// during event dispatch. Also, don't fire event listeners added during event
@@ -295,17 +294,22 @@ void EventTarget::fireEventListeners(Event* event, EventTargetData* d, EventList
// new event listeners.
if (event->type() == EventTypeNames::beforeunload) {
- if (DOMWindow* executingWindow = this->executingWindow()) {
+ if (LocalDOMWindow* executingWindow = this->executingWindow()) {
if (executingWindow->top())
- UseCounter::count(executingWindow, UseCounter::SubFrameBeforeUnloadFired);
- UseCounter::count(executingWindow, UseCounter::DocumentBeforeUnloadFired);
+ UseCounter::count(executingWindow->document(), UseCounter::SubFrameBeforeUnloadFired);
+ UseCounter::count(executingWindow->document(), UseCounter::DocumentBeforeUnloadFired);
}
} else if (event->type() == EventTypeNames::unload) {
- if (DOMWindow* executingWindow = this->executingWindow())
- UseCounter::count(executingWindow, UseCounter::DocumentUnloadFired);
+ if (LocalDOMWindow* executingWindow = this->executingWindow())
+ UseCounter::count(executingWindow->document(), UseCounter::DocumentUnloadFired);
+ } else if (event->type() == EventTypeNames::DOMFocusIn || event->type() == EventTypeNames::DOMFocusOut) {
+ if (LocalDOMWindow* executingWindow = this->executingWindow())
+ UseCounter::count(executingWindow->document(), UseCounter::DOMFocusInOutEvent);
+ } else if (event->type() == EventTypeNames::focusin || event->type() == EventTypeNames::focusout) {
+ if (LocalDOMWindow* executingWindow = this->executingWindow())
+ UseCounter::count(executingWindow->document(), UseCounter::FocusInOutEvent);
}
- bool userEventWasHandled = false;
size_t i = 0;
size_t size = entry.size();
if (!d->firingEventIterators)
@@ -327,19 +331,13 @@ void EventTarget::fireEventListeners(Event* event, EventTargetData* d, EventList
if (!context)
break;
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willHandleEvent(context, event);
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willHandleEvent(this, event, registeredListener.listener.get(), registeredListener.useCapture);
// To match Mozilla, the AT_TARGET phase fires both capturing and bubbling
// event listeners, even though that violates some versions of the DOM spec.
registeredListener.listener->handleEvent(context, event);
- if (!userEventWasHandled && UserGestureIndicator::processingUserGesture())
- userEventWasHandled = true;
InspectorInstrumentation::didHandleEvent(cookie);
}
d->firingEventIterators->removeLast();
- if (userEventWasHandled) {
- if (ExecutionContext* context = executionContext())
- context->userEventWasHandled();
- }
}
const EventListenerVector& EventTarget::getEventListeners(const AtomicString& eventType)
@@ -357,6 +355,12 @@ const EventListenerVector& EventTarget::getEventListeners(const AtomicString& ev
return *listenerVector;
}
+Vector<AtomicString> EventTarget::eventTypes()
+{
+ EventTargetData* d = eventTargetData();
+ return d ? d->eventListenerMap.eventTypes() : Vector<AtomicString>();
+}
+
void EventTarget::removeAllEventListeners()
{
EventTargetData* d = eventTargetData();
diff --git a/chromium/third_party/WebKit/Source/core/events/EventTarget.h b/chromium/third_party/WebKit/Source/core/events/EventTarget.h
index fa2192538a2..2e86b3c77db 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventTarget.h
+++ b/chromium/third_party/WebKit/Source/core/events/EventTarget.h
@@ -34,41 +34,17 @@
#include "core/events/EventListenerMap.h"
#include "core/events/ThreadLocalEventNames.h"
-#include "wtf/Forward.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
-class ApplicationCache;
-class AudioContext;
-class DOMWindow;
-class DedicatedWorkerGlobalScope;
+class LocalDOMWindow;
class Event;
-class EventListener;
-class EventSource;
class ExceptionState;
-class FileReader;
-class FileWriter;
-class IDBDatabase;
-class IDBRequest;
-class IDBTransaction;
-class MIDIAccess;
-class MIDIInput;
-class MIDIPort;
-class MediaController;
-class MediaStream;
class MessagePort;
-class NamedFlow;
class Node;
-class Notification;
-class SVGElementInstance;
-class ExecutionContext;
-class ScriptProcessorNode;
-class SharedWorker;
-class SharedWorkerGlobalScope;
class TextTrack;
class TextTrackCue;
-class WebSocket;
-class Worker;
class XMLHttpRequest;
class XMLHttpRequestUpload;
@@ -96,36 +72,47 @@ public:
OwnPtr<FiringEventIteratorVector> firingEventIterators;
};
-class EventTarget {
+class EventTarget : public WillBeGarbageCollectedMixin {
public:
+#if !ENABLE(OILPAN)
void ref() { refEventTarget(); }
void deref() { derefEventTarget(); }
+#endif
virtual const AtomicString& interfaceName() const = 0;
virtual ExecutionContext* executionContext() const = 0;
virtual Node* toNode();
- virtual DOMWindow* toDOMWindow();
+ virtual LocalDOMWindow* toDOMWindow();
virtual MessagePort* toMessagePort();
- virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+ // FIXME: first 2 args to addEventListener and removeEventListener should
+ // be required (per spec), but throwing TypeError breaks legacy content.
+ // http://crbug.com/353484
+ bool addEventListener() { return false; }
+ bool addEventListener(const AtomicString& eventType) { return false; }
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false);
+ bool removeEventListener() { return false; }
+ bool removeEventListener(const AtomicString& eventType) { return false; }
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture = false);
virtual void removeAllEventListeners();
- virtual bool dispatchEvent(PassRefPtr<Event>);
- bool dispatchEvent(PassRefPtr<Event>, ExceptionState&); // DOM API
+ virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>);
+ bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>, ExceptionState&); // DOM API
virtual void uncaughtExceptionInEventHandler();
// Used for legacy "onEvent" attribute APIs.
- bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, DOMWrapperWorld* isolatedWorld = 0);
- EventListener* getAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld = 0);
+ bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
+ EventListener* getAttributeEventListener(const AtomicString& eventType);
bool hasEventListeners() const;
bool hasEventListeners(const AtomicString& eventType) const;
bool hasCapturingEventListeners(const AtomicString& eventType);
const EventListenerVector& getEventListeners(const AtomicString& eventType);
+ Vector<AtomicString> eventTypes();
bool fireEventListeners(Event*);
- bool isFiringEventListeners();
+
+ virtual void trace(Visitor*) { }
protected:
virtual ~EventTarget();
@@ -135,15 +122,17 @@ protected:
virtual EventTargetData& ensureEventTargetData() = 0;
private:
+#if !ENABLE(OILPAN)
// Subclasses should likely not override these themselves; instead, they should use the REFCOUNTED_EVENT_TARGET() macro.
virtual void refEventTarget() = 0;
virtual void derefEventTarget() = 0;
+#endif
- DOMWindow* executingWindow();
+ LocalDOMWindow* executingWindow();
void fireEventListeners(Event*, EventTargetData*, EventListenerVector&);
void countLegacyEvents(const AtomicString& legacyTypeName, EventListenerVector*, EventListenerVector*);
- bool clearAttributeEventListener(const AtomicString& eventType, DOMWrapperWorld* isolatedWorld);
+ bool clearAttributeEventListener(const AtomicString& eventType);
friend class EventListenerIterator;
};
@@ -159,57 +148,49 @@ private:
// FIXME: These macros should be split into separate DEFINE and DECLARE
// macros to avoid causing so many header includes.
#define DEFINE_ATTRIBUTE_EVENT_LISTENER(attribute) \
- EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(EventTypeNames::attribute, isolatedWorld); } \
- void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld = 0) { setAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); } \
+ EventListener* on##attribute() { return getAttributeEventListener(EventTypeNames::attribute); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(EventTypeNames::attribute, listener); } \
#define DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(attribute) \
- static EventListener* on##attribute(EventTarget* eventTarget, DOMWrapperWorld* isolatedWorld) { return eventTarget->getAttributeEventListener(EventTypeNames::attribute, isolatedWorld); } \
- static void setOn##attribute(EventTarget* eventTarget, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld = 0) { eventTarget->setAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); } \
+ static EventListener* on##attribute(EventTarget& eventTarget) { return eventTarget.getAttributeEventListener(EventTypeNames::attribute); } \
+ static void setOn##attribute(EventTarget& eventTarget, PassRefPtr<EventListener> listener) { eventTarget.setAttributeEventListener(EventTypeNames::attribute, listener); } \
#define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
- EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return document().getWindowAttributeEventListener(EventTypeNames::attribute, isolatedWorld); } \
- void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { document().setWindowAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); } \
+ EventListener* on##attribute() { return document().getWindowAttributeEventListener(EventTypeNames::attribute); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener) { document().setWindowAttributeEventListener(EventTypeNames::attribute, listener); } \
#define DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
- static EventListener* on##attribute(EventTarget* eventTarget, DOMWrapperWorld* isolatedWorld) { \
- if (Node* node = eventTarget->toNode()) \
- return node->document().getWindowAttributeEventListener(EventTypeNames::attribute, isolatedWorld); \
- ASSERT(eventTarget->toDOMWindow()); \
- return eventTarget->getAttributeEventListener(EventTypeNames::attribute, isolatedWorld); \
+ static EventListener* on##attribute(EventTarget& eventTarget) { \
+ if (Node* node = eventTarget.toNode()) \
+ return node->document().getWindowAttributeEventListener(EventTypeNames::attribute); \
+ ASSERT(eventTarget.toDOMWindow()); \
+ return eventTarget.getAttributeEventListener(EventTypeNames::attribute); \
} \
- static void setOn##attribute(EventTarget* eventTarget, PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { \
- if (Node* node = eventTarget->toNode()) \
- node->document().setWindowAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); \
+ static void setOn##attribute(EventTarget& eventTarget, PassRefPtr<EventListener> listener) { \
+ if (Node* node = eventTarget.toNode()) \
+ node->document().setWindowAttributeEventListener(EventTypeNames::attribute, listener); \
else { \
- ASSERT(eventTarget->toDOMWindow()); \
- eventTarget->setAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); \
+ ASSERT(eventTarget.toDOMWindow()); \
+ eventTarget.setAttributeEventListener(EventTypeNames::attribute, listener); \
} \
}
#define DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(attribute, eventName) \
- EventListener* on##attribute(DOMWrapperWorld* isolatedWorld) { return getAttributeEventListener(EventTypeNames::eventName, isolatedWorld); } \
- void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) { setAttributeEventListener(EventTypeNames::eventName, listener, isolatedWorld); } \
+ EventListener* on##attribute() { return getAttributeEventListener(EventTypeNames::eventName); } \
+ void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(EventTypeNames::eventName, listener); } \
#define DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(recipient, attribute) \
- EventListener* on##attribute(DOMWrapperWorld* isolatedWorld); \
- void setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld);
+ EventListener* on##attribute(); \
+ void setOn##attribute(PassRefPtr<EventListener> listener);
#define DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(type, recipient, attribute) \
- EventListener* type::on##attribute(DOMWrapperWorld* isolatedWorld) { return recipient ? recipient->getAttributeEventListener(EventTypeNames::attribute, isolatedWorld) : 0; } \
- void type::setOn##attribute(PassRefPtr<EventListener> listener, DOMWrapperWorld* isolatedWorld) \
+ EventListener* type::on##attribute() { return recipient ? recipient->getAttributeEventListener(EventTypeNames::attribute) : 0; } \
+ void type::setOn##attribute(PassRefPtr<EventListener> listener) \
{ \
if (recipient) \
- recipient->setAttributeEventListener(EventTypeNames::attribute, listener, isolatedWorld); \
+ recipient->setAttributeEventListener(EventTypeNames::attribute, listener); \
}
-inline bool EventTarget::isFiringEventListeners()
-{
- EventTargetData* d = eventTargetData();
- if (!d)
- return false;
- return d->firingEventIterators && !d->firingEventIterators->isEmpty();
-}
-
inline bool EventTarget::hasEventListeners() const
{
// FIXME: We should have a const version of eventTargetData.
@@ -236,6 +217,15 @@ inline bool EventTarget::hasCapturingEventListeners(const AtomicString& eventTyp
} // namespace WebCore
+#if ENABLE(OILPAN)
+#define DEFINE_EVENT_TARGET_REFCOUNTING(baseClass) \
+public: \
+ using baseClass::ref; \
+ using baseClass::deref; \
+private: \
+ typedef int thisIsHereToForceASemiColonAfterThisEventTargetMacro
+#define DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(baseClass)
+#else
#define DEFINE_EVENT_TARGET_REFCOUNTING(baseClass) \
public: \
using baseClass::ref; \
@@ -244,10 +234,12 @@ private: \
virtual void refEventTarget() OVERRIDE FINAL { ref(); } \
virtual void derefEventTarget() OVERRIDE FINAL { deref(); } \
typedef int thisIsHereToForceASemiColonAfterThisEventTargetMacro
+#define DEFINE_EVENT_TARGET_REFCOUNTING_WILL_BE_REMOVED(baseClass) DEFINE_EVENT_TARGET_REFCOUNTING(baseClass)
+#endif
// Use this macro if your EventTarget subclass is also a subclass of WTF::RefCounted.
// A ref-counted class that uses a different method of refcounting should use DEFINE_EVENT_TARGET_REFCOUNTING directly.
// Both of these macros are meant to be placed just before the "public:" section of the class declaration.
-#define REFCOUNTED_EVENT_TARGET(className) DEFINE_EVENT_TARGET_REFCOUNTING(RefCounted<className>)
+#define REFCOUNTED_EVENT_TARGET(className) DEFINE_EVENT_TARGET_REFCOUNTING(RefCountedWillBeRefCountedGarbageCollected<className>)
#endif // EventTarget_h
diff --git a/chromium/third_party/WebKit/Source/core/events/EventTarget.idl b/chromium/third_party/WebKit/Source/core/events/EventTarget.idl
index 0cd1b1718f0..69a4bc18d7b 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventTarget.idl
+++ b/chromium/third_party/WebKit/Source/core/events/EventTarget.idl
@@ -20,12 +20,15 @@
[
Custom=ToV8,
+ WillBeGarbageCollected,
] interface EventTarget {
- void addEventListener(DOMString type,
- EventListener listener,
+ // FIXME: first 2 args should be required, but throwing TypeError breaks
+ // legacy content. http://crbug.com/353484
+ void addEventListener([TreatNullAs=NullString] optional DOMString type,
+ optional EventListener listener,
optional boolean useCapture);
- void removeEventListener(DOMString type,
- EventListener listener,
+ void removeEventListener([TreatNullAs=NullString] optional DOMString type,
+ optional EventListener listener,
optional boolean useCapture);
[RaisesException] boolean dispatchEvent(Event event);
};
diff --git a/chromium/third_party/WebKit/Source/core/events/EventTargetFactory.in b/chromium/third_party/WebKit/Source/core/events/EventTargetFactory.in
index fcb0aff0a75..2a528dddc5c 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventTargetFactory.in
+++ b/chromium/third_party/WebKit/Source/core/events/EventTargetFactory.in
@@ -1,50 +1,24 @@
namespace="EventTarget"
+core/animation/AnimationPlayer
core/css/FontFaceSet
core/dom/MessagePort
core/dom/Node
-core/dom/WebKitNamedFlow ImplementedAs=NamedFlow
core/fileapi/FileReader
core/html/MediaController
core/html/ime/InputMethodContext
+core/html/track/AudioTrackList
core/html/track/TextTrack
core/html/track/TextTrackCue
core/html/track/TextTrackList
+core/html/track/VideoTrackList
core/loader/appcache/ApplicationCache
core/page/EventSource
core/timing/Performance
-core/frame/Window ImplementedAs=DOMWindow
-core/svg/SVGElementInstance
+core/frame/Window ImplementedAs=LocalDOMWindow
core/workers/DedicatedWorkerGlobalScope
core/workers/SharedWorker
core/workers/SharedWorkerGlobalScope
core/workers/Worker
core/xml/XMLHttpRequest
core/xml/XMLHttpRequestUpload
-modules/encryptedmedia/MediaKeySession
-modules/filesystem/FileWriter
-modules/indexeddb/IDBDatabase
-modules/indexeddb/IDBOpenDBRequest
-modules/indexeddb/IDBRequest
-modules/indexeddb/IDBTransaction
-modules/mediasource/MediaSource
-modules/mediasource/SourceBuffer
-modules/mediasource/SourceBufferList
-modules/mediasource/WebKitMediaSource
-modules/mediasource/WebKitSourceBufferList
-modules/mediastream/MediaStream
-modules/mediastream/MediaStreamTrack
-modules/mediastream/RTCDTMFSender
-modules/mediastream/RTCDataChannel
-modules/mediastream/RTCPeerConnection
-modules/notifications/Notification
-modules/notifications/WebKitNotification Conditional=LEGACY_NOTIFICATIONS
-modules/serviceworkers/ServiceWorkerGlobalScope
-modules/speech/SpeechRecognition
-modules/speech/SpeechSynthesisUtterance
-modules/webaudio/AudioContext Conditional=WEB_AUDIO
-modules/webaudio/AudioNode Conditional=WEB_AUDIO
-modules/webmidi/MIDIAccess
-modules/webmidi/MIDIInput
-modules/webmidi/MIDIPort
-modules/websockets/WebSocket
diff --git a/chromium/third_party/WebKit/Source/core/events/EventTypeNames.in b/chromium/third_party/WebKit/Source/core/events/EventTypeNames.in
index b8148018635..762fbef8594 100644
--- a/chromium/third_party/WebKit/Source/core/events/EventTypeNames.in
+++ b/chromium/third_party/WebKit/Source/core/events/EventTypeNames.in
@@ -25,7 +25,6 @@ autocomplete
autocompleteerror
beforecopy
beforecut
-beforeload
beforepaste
beforeunload
beginEvent
@@ -51,12 +50,15 @@ compositionstart
compositionupdate
connect
connecting
+contextlost
contextmenu
+contextrestored
copy
cuechange
cut
datachannel
dblclick
+devicelight
devicemotion
deviceorientation
dischargingtimechange
@@ -79,9 +81,12 @@ enter
error
exit
fetch
+finish
focus
focusin
focusout
+gamepadconnected
+gamepaddisconnected
gesturescrollend
gesturescrollstart
gesturescrollupdate
@@ -98,6 +103,7 @@ invalid
keydown
keypress
keyup
+languagechange
levelchange
load
loadeddata
@@ -119,6 +125,7 @@ mouseover
mouseup
mousewheel
mute
+needkey
negotiationneeded
nomatch
noupdate
@@ -134,9 +141,13 @@ paste
pause
play
playing
+pointerlockchange
+pointerlockerror
popstate
progress
+push
ratechange
+ready
readystatechange
removesourcebuffer
removestream
@@ -165,19 +176,23 @@ speechend
speechstart
stalled
start
+statechange
storage
submit
success
suspend
+sync
textInput
timeout
timeupdate
+toggle
tonechange
touchcancel
touchend
touchmove
touchstart
transitionend
+typechange
unload
unmute
update
@@ -214,8 +229,6 @@ webkitprerenderdomcontentloaded
webkitprerenderload
webkitprerenderstart
webkitprerenderstop
-webkitregionlayoutupdate
-webkitregionoversetchange
webkitremovesourcebuffer
webkitresourcetimingbufferfull
webkitsourceclose
diff --git a/chromium/third_party/WebKit/Source/core/events/FocusEvent.cpp b/chromium/third_party/WebKit/Source/core/events/FocusEvent.cpp
index e201de0c419..a541b3bb60e 100644
--- a/chromium/third_party/WebKit/Source/core/events/FocusEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/FocusEvent.cpp
@@ -28,13 +28,11 @@
#include "core/events/Event.h"
#include "core/events/EventDispatcher.h"
-#include "core/events/EventRetargeter.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
FocusEventInit::FocusEventInit()
- : relatedTarget(0)
+ : relatedTarget(nullptr)
{
}
@@ -53,7 +51,7 @@ FocusEvent::FocusEvent()
ScriptWrappable::init(this);
}
-FocusEvent::FocusEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view, int detail, EventTarget* relatedTarget)
+FocusEvent::FocusEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view, int detail, EventTarget* relatedTarget)
: UIEvent(type, canBubble, cancelable, view, detail)
, m_relatedTarget(relatedTarget)
{
@@ -67,67 +65,73 @@ FocusEvent::FocusEvent(const AtomicString& type, const FocusEventInit& initializ
ScriptWrappable::init(this);
}
-PassRefPtr<FocusEventDispatchMediator> FocusEventDispatchMediator::create(PassRefPtr<FocusEvent> focusEvent)
+void FocusEvent::trace(Visitor* visitor)
{
- return adoptRef(new FocusEventDispatchMediator(focusEvent));
+ visitor->trace(m_relatedTarget);
+ UIEvent::trace(visitor);
}
-FocusEventDispatchMediator::FocusEventDispatchMediator(PassRefPtr<FocusEvent> focusEvent)
+PassRefPtrWillBeRawPtr<FocusEventDispatchMediator> FocusEventDispatchMediator::create(PassRefPtrWillBeRawPtr<FocusEvent> focusEvent)
+{
+ return adoptRefWillBeNoop(new FocusEventDispatchMediator(focusEvent));
+}
+
+FocusEventDispatchMediator::FocusEventDispatchMediator(PassRefPtrWillBeRawPtr<FocusEvent> focusEvent)
: EventDispatchMediator(focusEvent)
{
}
bool FocusEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
{
- EventRetargeter::adjustForFocusEvent(dispatcher->node(), *event());
+ event()->eventPath().adjustForRelatedTarget(dispatcher->node(), event()->relatedTarget());
return EventDispatchMediator::dispatchEvent(dispatcher);
}
-PassRefPtr<BlurEventDispatchMediator> BlurEventDispatchMediator::create(PassRefPtr<FocusEvent> focusEvent)
+PassRefPtrWillBeRawPtr<BlurEventDispatchMediator> BlurEventDispatchMediator::create(PassRefPtrWillBeRawPtr<FocusEvent> focusEvent)
{
- return adoptRef(new BlurEventDispatchMediator(focusEvent));
+ return adoptRefWillBeNoop(new BlurEventDispatchMediator(focusEvent));
}
-BlurEventDispatchMediator::BlurEventDispatchMediator(PassRefPtr<FocusEvent> focusEvent)
+BlurEventDispatchMediator::BlurEventDispatchMediator(PassRefPtrWillBeRawPtr<FocusEvent> focusEvent)
: EventDispatchMediator(focusEvent)
{
}
bool BlurEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
{
- EventRetargeter::adjustForFocusEvent(dispatcher->node(), *event());
+ event()->eventPath().adjustForRelatedTarget(dispatcher->node(), event()->relatedTarget());
return EventDispatchMediator::dispatchEvent(dispatcher);
}
-PassRefPtr<FocusInEventDispatchMediator> FocusInEventDispatchMediator::create(PassRefPtr<FocusEvent> focusEvent)
+PassRefPtrWillBeRawPtr<FocusInEventDispatchMediator> FocusInEventDispatchMediator::create(PassRefPtrWillBeRawPtr<FocusEvent> focusEvent)
{
- return adoptRef(new FocusInEventDispatchMediator(focusEvent));
+ return adoptRefWillBeNoop(new FocusInEventDispatchMediator(focusEvent));
}
-FocusInEventDispatchMediator::FocusInEventDispatchMediator(PassRefPtr<FocusEvent> focusEvent)
+FocusInEventDispatchMediator::FocusInEventDispatchMediator(PassRefPtrWillBeRawPtr<FocusEvent> focusEvent)
: EventDispatchMediator(focusEvent)
{
}
bool FocusInEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
{
- EventRetargeter::adjustForFocusEvent(dispatcher->node(), *event());
+ event()->eventPath().adjustForRelatedTarget(dispatcher->node(), event()->relatedTarget());
return EventDispatchMediator::dispatchEvent(dispatcher);
}
-PassRefPtr<FocusOutEventDispatchMediator> FocusOutEventDispatchMediator::create(PassRefPtr<FocusEvent> focusEvent)
+PassRefPtrWillBeRawPtr<FocusOutEventDispatchMediator> FocusOutEventDispatchMediator::create(PassRefPtrWillBeRawPtr<FocusEvent> focusEvent)
{
- return adoptRef(new FocusOutEventDispatchMediator(focusEvent));
+ return adoptRefWillBeNoop(new FocusOutEventDispatchMediator(focusEvent));
}
-FocusOutEventDispatchMediator::FocusOutEventDispatchMediator(PassRefPtr<FocusEvent> focusEvent)
+FocusOutEventDispatchMediator::FocusOutEventDispatchMediator(PassRefPtrWillBeRawPtr<FocusEvent> focusEvent)
: EventDispatchMediator(focusEvent)
{
}
bool FocusOutEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
{
- EventRetargeter::adjustForFocusEvent(dispatcher->node(), *event());
+ event()->eventPath().adjustForRelatedTarget(dispatcher->node(), event()->relatedTarget());
return EventDispatchMediator::dispatchEvent(dispatcher);
}
diff --git a/chromium/third_party/WebKit/Source/core/events/FocusEvent.h b/chromium/third_party/WebKit/Source/core/events/FocusEvent.h
index 20a9a28c0fe..5af4eb62f4e 100644
--- a/chromium/third_party/WebKit/Source/core/events/FocusEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/FocusEvent.h
@@ -36,75 +36,77 @@ class Node;
struct FocusEventInit : public UIEventInit {
FocusEventInit();
- RefPtr<EventTarget> relatedTarget;
+ RefPtrWillBeMember<EventTarget> relatedTarget;
};
-class FocusEvent : public UIEvent {
+class FocusEvent FINAL : public UIEvent {
public:
- static PassRefPtr<FocusEvent> create()
+ static PassRefPtrWillBeRawPtr<FocusEvent> create()
{
- return adoptRef(new FocusEvent);
+ return adoptRefWillBeNoop(new FocusEvent);
}
- static PassRefPtr<FocusEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view, int detail, EventTarget* relatedTarget)
+ static PassRefPtrWillBeRawPtr<FocusEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view, int detail, EventTarget* relatedTarget)
{
- return adoptRef(new FocusEvent(type, canBubble, cancelable, view, detail, relatedTarget));
+ return adoptRefWillBeNoop(new FocusEvent(type, canBubble, cancelable, view, detail, relatedTarget));
}
- static PassRefPtr<FocusEvent> create(const AtomicString& type, const FocusEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<FocusEvent> create(const AtomicString& type, const FocusEventInit& initializer)
{
- return adoptRef(new FocusEvent(type, initializer));
+ return adoptRefWillBeNoop(new FocusEvent(type, initializer));
}
EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
EventTarget* relatedTarget(bool& isNull) const { isNull = !m_relatedTarget; return m_relatedTarget.get(); }
void setRelatedTarget(EventTarget* relatedTarget) { m_relatedTarget = relatedTarget; }
- virtual const AtomicString& interfaceName() const;
- virtual bool isFocusEvent() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+ virtual bool isFocusEvent() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
FocusEvent();
- FocusEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, int, EventTarget*);
+ FocusEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>, int, EventTarget*);
FocusEvent(const AtomicString& type, const FocusEventInit&);
- RefPtr<EventTarget> m_relatedTarget;
+ RefPtrWillBeMember<EventTarget> m_relatedTarget;
};
DEFINE_EVENT_TYPE_CASTS(FocusEvent);
-class FocusEventDispatchMediator : public EventDispatchMediator {
+class FocusEventDispatchMediator FINAL : public EventDispatchMediator {
public:
- static PassRefPtr<FocusEventDispatchMediator> create(PassRefPtr<FocusEvent>);
+ static PassRefPtrWillBeRawPtr<FocusEventDispatchMediator> create(PassRefPtrWillBeRawPtr<FocusEvent>);
private:
- explicit FocusEventDispatchMediator(PassRefPtr<FocusEvent>);
+ explicit FocusEventDispatchMediator(PassRefPtrWillBeRawPtr<FocusEvent>);
FocusEvent* event() const { return static_cast<FocusEvent*>(EventDispatchMediator::event()); }
virtual bool dispatchEvent(EventDispatcher*) const OVERRIDE;
};
-class BlurEventDispatchMediator : public EventDispatchMediator {
+class BlurEventDispatchMediator FINAL : public EventDispatchMediator {
public:
- static PassRefPtr<BlurEventDispatchMediator> create(PassRefPtr<FocusEvent>);
+ static PassRefPtrWillBeRawPtr<BlurEventDispatchMediator> create(PassRefPtrWillBeRawPtr<FocusEvent>);
private:
- explicit BlurEventDispatchMediator(PassRefPtr<FocusEvent>);
+ explicit BlurEventDispatchMediator(PassRefPtrWillBeRawPtr<FocusEvent>);
FocusEvent* event() const { return static_cast<FocusEvent*>(EventDispatchMediator::event()); }
virtual bool dispatchEvent(EventDispatcher*) const OVERRIDE;
};
-class FocusInEventDispatchMediator : public EventDispatchMediator {
+class FocusInEventDispatchMediator FINAL : public EventDispatchMediator {
public:
- static PassRefPtr<FocusInEventDispatchMediator> create(PassRefPtr<FocusEvent>);
+ static PassRefPtrWillBeRawPtr<FocusInEventDispatchMediator> create(PassRefPtrWillBeRawPtr<FocusEvent>);
private:
- explicit FocusInEventDispatchMediator(PassRefPtr<FocusEvent>);
+ explicit FocusInEventDispatchMediator(PassRefPtrWillBeRawPtr<FocusEvent>);
FocusEvent* event() const { return static_cast<FocusEvent*>(EventDispatchMediator::event()); }
virtual bool dispatchEvent(EventDispatcher*) const OVERRIDE;
};
-class FocusOutEventDispatchMediator : public EventDispatchMediator {
+class FocusOutEventDispatchMediator FINAL : public EventDispatchMediator {
public:
- static PassRefPtr<FocusOutEventDispatchMediator> create(PassRefPtr<FocusEvent>);
+ static PassRefPtrWillBeRawPtr<FocusOutEventDispatchMediator> create(PassRefPtrWillBeRawPtr<FocusEvent>);
private:
- explicit FocusOutEventDispatchMediator(PassRefPtr<FocusEvent>);
+ explicit FocusOutEventDispatchMediator(PassRefPtrWillBeRawPtr<FocusEvent>);
FocusEvent* event() const { return static_cast<FocusEvent*>(EventDispatchMediator::event()); }
virtual bool dispatchEvent(EventDispatcher*) const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/events/GenericEventQueue.cpp b/chromium/third_party/WebKit/Source/core/events/GenericEventQueue.cpp
index b35f85c09f9..bc53048ddf4 100644
--- a/chromium/third_party/WebKit/Source/core/events/GenericEventQueue.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/GenericEventQueue.cpp
@@ -28,13 +28,14 @@
#include "core/events/GenericEventQueue.h"
#include "core/events/Event.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "platform/TraceEvent.h"
namespace WebCore {
-PassOwnPtr<GenericEventQueue> GenericEventQueue::create(EventTarget* owner)
+PassOwnPtrWillBeRawPtr<GenericEventQueue> GenericEventQueue::create(EventTarget* owner)
{
- return adoptPtr(new GenericEventQueue(owner));
+ return adoptPtrWillBeNoop(new GenericEventQueue(owner));
}
GenericEventQueue::GenericEventQueue(EventTarget* owner)
@@ -48,19 +49,27 @@ GenericEventQueue::~GenericEventQueue()
{
}
-bool GenericEventQueue::enqueueEvent(PassRefPtr<Event> event)
+void GenericEventQueue::trace(Visitor* visitor)
+{
+ visitor->trace(m_owner);
+ visitor->trace(m_pendingEvents);
+ EventQueue::trace(visitor);
+}
+
+bool GenericEventQueue::enqueueEvent(PassRefPtrWillBeRawPtr<Event> event)
{
if (m_isClosed)
return false;
if (event->target() == m_owner)
- event->setTarget(0);
+ event->setTarget(nullptr);
- TRACE_EVENT_ASYNC_BEGIN1("event", "GenericEventQueue:enqueueEvent", event.get(), "type", event->type().string().ascii());
+ TRACE_EVENT_ASYNC_BEGIN1("event", "GenericEventQueue:enqueueEvent", event.get(), "type", event->type().ascii());
+ InspectorInstrumentation::didEnqueueEvent(event->target() ? event->target() : m_owner.get(), event.get());
m_pendingEvents.append(event);
if (!m_timer.isActive())
- m_timer.startOneShot(0);
+ m_timer.startOneShot(0, FROM_HERE);
return true;
}
@@ -70,8 +79,9 @@ bool GenericEventQueue::cancelEvent(Event* event)
bool found = m_pendingEvents.contains(event);
if (found) {
+ InspectorInstrumentation::didRemoveEvent(event->target() ? event->target() : m_owner.get(), event);
m_pendingEvents.remove(m_pendingEvents.find(event));
- TRACE_EVENT_ASYNC_END2("event", "GenericEventQueue:enqueueEvent", event, "type", event->type().string().ascii(), "status", "cancelled");
+ TRACE_EVENT_ASYNC_END2("event", "GenericEventQueue:enqueueEvent", event, "type", event->type().ascii(), "status", "cancelled");
}
if (m_pendingEvents.isEmpty())
@@ -85,17 +95,18 @@ void GenericEventQueue::timerFired(Timer<GenericEventQueue>*)
ASSERT(!m_timer.isActive());
ASSERT(!m_pendingEvents.isEmpty());
- Vector<RefPtr<Event> > pendingEvents;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > pendingEvents;
m_pendingEvents.swap(pendingEvents);
- RefPtr<EventTarget> protect(m_owner);
+ RefPtrWillBeRawPtr<EventTarget> protect(m_owner.get());
for (size_t i = 0; i < pendingEvents.size(); ++i) {
Event* event = pendingEvents[i].get();
- EventTarget* target = event->target() ? event->target() : m_owner;
- CString type(event->type().string().ascii());
+ EventTarget* target = event->target() ? event->target() : m_owner.get();
+ CString type(event->type().ascii());
TRACE_EVENT_ASYNC_STEP_INTO1("event", "GenericEventQueue:enqueueEvent", event, "dispatch", "type", type);
- target->dispatchEvent(pendingEvents[i].release());
+ target->dispatchEvent(pendingEvents[i]);
TRACE_EVENT_ASYNC_END1("event", "GenericEventQueue:enqueueEvent", event, "type", type);
+ InspectorInstrumentation::didRemoveEvent(target, event);
}
}
@@ -111,7 +122,8 @@ void GenericEventQueue::cancelAllEvents()
for (size_t i = 0; i < m_pendingEvents.size(); ++i) {
Event* event = m_pendingEvents[i].get();
- TRACE_EVENT_ASYNC_END2("event", "GenericEventQueue:enqueueEvent", event, "type", event->type().string().ascii(), "status", "cancelled");
+ TRACE_EVENT_ASYNC_END2("event", "GenericEventQueue:enqueueEvent", event, "type", event->type().ascii(), "status", "cancelled");
+ InspectorInstrumentation::didRemoveEvent(event->target() ? event->target() : m_owner.get(), event);
}
m_pendingEvents.clear();
}
diff --git a/chromium/third_party/WebKit/Source/core/events/GenericEventQueue.h b/chromium/third_party/WebKit/Source/core/events/GenericEventQueue.h
index ab80f89a8ff..45ca524b315 100644
--- a/chromium/third_party/WebKit/Source/core/events/GenericEventQueue.h
+++ b/chromium/third_party/WebKit/Source/core/events/GenericEventQueue.h
@@ -35,15 +35,15 @@
namespace WebCore {
-class GenericEventQueue : public EventQueue {
- WTF_MAKE_FAST_ALLOCATED;
+class GenericEventQueue FINAL : public EventQueue {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- explicit GenericEventQueue(EventTarget*);
- static PassOwnPtr<GenericEventQueue> create(EventTarget*);
+ static PassOwnPtrWillBeRawPtr<GenericEventQueue> create(EventTarget*);
virtual ~GenericEventQueue();
// EventQueue
- virtual bool enqueueEvent(PassRefPtr<Event>) OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+ virtual bool enqueueEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
virtual bool cancelEvent(Event*) OVERRIDE;
virtual void close() OVERRIDE;
@@ -51,10 +51,11 @@ public:
bool hasPendingEvents() const;
private:
+ explicit GenericEventQueue(EventTarget*);
void timerFired(Timer<GenericEventQueue>*);
- EventTarget* m_owner;
- Vector<RefPtr<Event> > m_pendingEvents;
+ RawPtrWillBeMember<EventTarget> m_owner;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > m_pendingEvents;
Timer<GenericEventQueue> m_timer;
bool m_isClosed;
diff --git a/chromium/third_party/WebKit/Source/core/events/GestureEvent.cpp b/chromium/third_party/WebKit/Source/core/events/GestureEvent.cpp
index 13d5f6f2a01..1fb72214e80 100644
--- a/chromium/third_party/WebKit/Source/core/events/GestureEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/GestureEvent.cpp
@@ -30,12 +30,7 @@
namespace WebCore {
-PassRefPtr<GestureEvent> GestureEvent::create()
-{
- return adoptRef(new GestureEvent);
-}
-
-PassRefPtr<GestureEvent> GestureEvent::create(PassRefPtr<AbstractView> view, const PlatformGestureEvent& event)
+PassRefPtrWillBeRawPtr<GestureEvent> GestureEvent::create(PassRefPtrWillBeRawPtr<AbstractView> view, const PlatformGestureEvent& event)
{
AtomicString eventType;
float deltaX = 0;
@@ -68,27 +63,9 @@ PassRefPtr<GestureEvent> GestureEvent::create(PassRefPtr<AbstractView> view, con
case PlatformEvent::GesturePinchUpdate:
case PlatformEvent::GestureTapDownCancel:
default:
- return 0;
+ return nullptr;
}
- return adoptRef(new GestureEvent(eventType, view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), deltaX, deltaY));
-}
-
-void GestureEvent::initGestureEvent(const AtomicString& type, PassRefPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY)
-{
- if (dispatched())
- return;
-
- initUIEvent(type, true, true, view, 0);
- m_screenLocation = IntPoint(screenX, screenY);
- m_ctrlKey = ctrlKey;
- m_altKey = altKey;
- m_shiftKey = shiftKey;
- m_metaKey = metaKey;
-
- m_deltaX = deltaX;
- m_deltaY = deltaY;
-
- initCoordinates(IntPoint(clientX, clientY));
+ return adoptRefWillBeNoop(new GestureEvent(eventType, view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), deltaX, deltaY));
}
const AtomicString& GestureEvent::interfaceName() const
@@ -110,14 +87,19 @@ GestureEvent::GestureEvent()
{
}
-GestureEvent::GestureEvent(const AtomicString& type, PassRefPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY)
+GestureEvent::GestureEvent(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY)
: MouseRelatedEvent(type, true, true, view, 0, IntPoint(screenX, screenY), IntPoint(clientX, clientY), IntPoint(0, 0), ctrlKey, altKey, shiftKey, metaKey)
, m_deltaX(deltaX)
, m_deltaY(deltaY)
{
}
-GestureEventDispatchMediator::GestureEventDispatchMediator(PassRefPtr<GestureEvent> gestureEvent)
+void GestureEvent::trace(Visitor* visitor)
+{
+ MouseRelatedEvent::trace(visitor);
+}
+
+GestureEventDispatchMediator::GestureEventDispatchMediator(PassRefPtrWillBeRawPtr<GestureEvent> gestureEvent)
: EventDispatchMediator(gestureEvent)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/events/GestureEvent.h b/chromium/third_party/WebKit/Source/core/events/GestureEvent.h
index fe982006c92..f92a87578c8 100644
--- a/chromium/third_party/WebKit/Source/core/events/GestureEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/GestureEvent.h
@@ -32,39 +32,38 @@
namespace WebCore {
-class GestureEvent : public MouseRelatedEvent {
+class GestureEvent FINAL : public MouseRelatedEvent {
public:
virtual ~GestureEvent() { }
- static PassRefPtr<GestureEvent> create();
- static PassRefPtr<GestureEvent> create(PassRefPtr<AbstractView>, const PlatformGestureEvent&);
-
- void initGestureEvent(const AtomicString& type, PassRefPtr<AbstractView>, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY);
+ static PassRefPtrWillBeRawPtr<GestureEvent> create(PassRefPtrWillBeRawPtr<AbstractView>, const PlatformGestureEvent&);
virtual bool isGestureEvent() const OVERRIDE;
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
float deltaX() const { return m_deltaX; }
float deltaY() const { return m_deltaY; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
GestureEvent();
- GestureEvent(const AtomicString& type, PassRefPtr<AbstractView>, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY);
+ GestureEvent(const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView>, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY);
float m_deltaX;
float m_deltaY;
};
-class GestureEventDispatchMediator : public EventDispatchMediator {
+class GestureEventDispatchMediator FINAL : public EventDispatchMediator {
public:
- static PassRefPtr<GestureEventDispatchMediator> create(PassRefPtr<GestureEvent> gestureEvent)
+ static PassRefPtrWillBeRawPtr<GestureEventDispatchMediator> create(PassRefPtrWillBeRawPtr<GestureEvent> gestureEvent)
{
- return adoptRef(new GestureEventDispatchMediator(gestureEvent));
+ return adoptRefWillBeNoop(new GestureEventDispatchMediator(gestureEvent));
}
private:
- explicit GestureEventDispatchMediator(PassRefPtr<GestureEvent>);
+ explicit GestureEventDispatchMediator(PassRefPtrWillBeRawPtr<GestureEvent>);
GestureEvent* event() const;
diff --git a/chromium/third_party/WebKit/Source/core/events/HashChangeEvent.h b/chromium/third_party/WebKit/Source/core/events/HashChangeEvent.h
index e652df8dca6..334a443fe57 100644
--- a/chromium/third_party/WebKit/Source/core/events/HashChangeEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/HashChangeEvent.h
@@ -22,7 +22,6 @@
#define HashChangeEvent_h
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
@@ -35,21 +34,21 @@ struct HashChangeEventInit : public EventInit {
String newURL;
};
-class HashChangeEvent : public Event {
+class HashChangeEvent FINAL : public Event {
public:
- static PassRefPtr<HashChangeEvent> create()
+ static PassRefPtrWillBeRawPtr<HashChangeEvent> create()
{
- return adoptRef(new HashChangeEvent);
+ return adoptRefWillBeNoop(new HashChangeEvent);
}
- static PassRefPtr<HashChangeEvent> create(const String& oldURL, const String& newURL)
+ static PassRefPtrWillBeRawPtr<HashChangeEvent> create(const String& oldURL, const String& newURL)
{
- return adoptRef(new HashChangeEvent(oldURL, newURL));
+ return adoptRefWillBeNoop(new HashChangeEvent(oldURL, newURL));
}
- static PassRefPtr<HashChangeEvent> create(const AtomicString& type, const HashChangeEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<HashChangeEvent> create(const AtomicString& type, const HashChangeEventInit& initializer)
{
- return adoptRef(new HashChangeEvent(type, initializer));
+ return adoptRefWillBeNoop(new HashChangeEvent(type, initializer));
}
void initHashChangeEvent(const AtomicString& eventType, bool canBubble, bool cancelable, const String& oldURL, const String& newURL)
@@ -66,7 +65,9 @@ public:
const String& oldURL() const { return m_oldURL; }
const String& newURL() const { return m_newURL; }
- virtual const AtomicString& interfaceName() const { return EventNames::HashChangeEvent; }
+ virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::HashChangeEvent; }
+
+ virtual void trace(Visitor* visitor) OVERRIDE { Event::trace(visitor); }
private:
HashChangeEvent()
diff --git a/chromium/third_party/WebKit/Source/core/events/KeyboardEvent.cpp b/chromium/third_party/WebKit/Source/core/events/KeyboardEvent.cpp
index c03712edadd..a529f490977 100644
--- a/chromium/third_party/WebKit/Source/core/events/KeyboardEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/KeyboardEvent.cpp
@@ -23,7 +23,6 @@
#include "config.h"
#include "core/events/KeyboardEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "platform/PlatformKeyboardEvent.h"
#include "platform/WindowsKeyboardCodes.h"
@@ -217,21 +216,17 @@ int KeyboardEvent::which() const
return keyCode();
}
-KeyboardEvent* findKeyboardEvent(Event* event)
+void KeyboardEvent::trace(Visitor* visitor)
{
- for (Event* e = event; e; e = e->underlyingEvent()) {
- if (e->isKeyboardEvent())
- return toKeyboardEvent(e);
- }
- return 0;
+ UIEventWithKeyState::trace(visitor);
}
-PassRefPtr<KeyboardEventDispatchMediator> KeyboardEventDispatchMediator::create(PassRefPtr<KeyboardEvent> event)
+PassRefPtrWillBeRawPtr<KeyboardEventDispatchMediator> KeyboardEventDispatchMediator::create(PassRefPtrWillBeRawPtr<KeyboardEvent> event)
{
- return adoptRef(new KeyboardEventDispatchMediator(event));
+ return adoptRefWillBeNoop(new KeyboardEventDispatchMediator(event));
}
-KeyboardEventDispatchMediator::KeyboardEventDispatchMediator(PassRefPtr<KeyboardEvent> event)
+KeyboardEventDispatchMediator::KeyboardEventDispatchMediator(PassRefPtrWillBeRawPtr<KeyboardEvent> event)
: EventDispatchMediator(event)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/events/KeyboardEvent.h b/chromium/third_party/WebKit/Source/core/events/KeyboardEvent.h
index e4d1e9e6462..efd32a5bd7c 100644
--- a/chromium/third_party/WebKit/Source/core/events/KeyboardEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/KeyboardEvent.h
@@ -45,7 +45,7 @@ struct KeyboardEventInit : public UIEventInit {
bool repeat;
};
-class KeyboardEvent : public UIEventWithKeyState {
+class KeyboardEvent FINAL : public UIEventWithKeyState {
public:
enum KeyLocationCode {
DOM_KEY_LOCATION_STANDARD = 0x00,
@@ -54,26 +54,26 @@ public:
DOM_KEY_LOCATION_NUMPAD = 0x03
};
- static PassRefPtr<KeyboardEvent> create()
+ static PassRefPtrWillBeRawPtr<KeyboardEvent> create()
{
- return adoptRef(new KeyboardEvent);
+ return adoptRefWillBeNoop(new KeyboardEvent);
}
- static PassRefPtr<KeyboardEvent> create(const PlatformKeyboardEvent& platformEvent, AbstractView* view)
+ static PassRefPtrWillBeRawPtr<KeyboardEvent> create(const PlatformKeyboardEvent& platformEvent, AbstractView* view)
{
- return adoptRef(new KeyboardEvent(platformEvent, view));
+ return adoptRefWillBeNoop(new KeyboardEvent(platformEvent, view));
}
- static PassRefPtr<KeyboardEvent> create(const AtomicString& type, const KeyboardEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<KeyboardEvent> create(const AtomicString& type, const KeyboardEventInit& initializer)
{
- return adoptRef(new KeyboardEvent(type, initializer));
+ return adoptRefWillBeNoop(new KeyboardEvent(type, initializer));
}
- static PassRefPtr<KeyboardEvent> create(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view,
+ static PassRefPtrWillBeRawPtr<KeyboardEvent> create(const AtomicString& type, bool canBubble, bool cancelable, AbstractView* view,
const String& keyIdentifier, unsigned location,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool altGraphKey)
{
- return adoptRef(new KeyboardEvent(type, canBubble, cancelable, view, keyIdentifier, location,
+ return adoptRefWillBeNoop(new KeyboardEvent(type, canBubble, cancelable, view, keyIdentifier, location,
ctrlKey, altKey, shiftKey, metaKey, altGraphKey));
}
@@ -92,13 +92,15 @@ public:
const PlatformKeyboardEvent* keyEvent() const { return m_keyEvent.get(); }
- int keyCode() const; // key code for keydown and keyup, character for keypress
- int charCode() const; // character code for keypress, 0 for keydown and keyup
+ virtual int keyCode() const OVERRIDE; // key code for keydown and keyup, character for keypress
+ virtual int charCode() const OVERRIDE; // character code for keypress, 0 for keydown and keyup
bool repeat() const { return m_isAutoRepeat; }
- virtual const AtomicString& interfaceName() const;
- virtual bool isKeyboardEvent() const;
- virtual int which() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+ virtual bool isKeyboardEvent() const OVERRIDE;
+ virtual int which() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
KeyboardEvent();
@@ -115,13 +117,11 @@ private:
bool m_isAutoRepeat : 1;
};
-KeyboardEvent* findKeyboardEvent(Event*);
-
class KeyboardEventDispatchMediator : public EventDispatchMediator {
public:
- static PassRefPtr<KeyboardEventDispatchMediator> create(PassRefPtr<KeyboardEvent>);
+ static PassRefPtrWillBeRawPtr<KeyboardEventDispatchMediator> create(PassRefPtrWillBeRawPtr<KeyboardEvent>);
private:
- explicit KeyboardEventDispatchMediator(PassRefPtr<KeyboardEvent>);
+ explicit KeyboardEventDispatchMediator(PassRefPtrWillBeRawPtr<KeyboardEvent>);
virtual bool dispatchEvent(EventDispatcher*) const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/events/MessageEvent.cpp b/chromium/third_party/WebKit/Source/core/events/MessageEvent.cpp
index 883b1f969e5..18efe773262 100644
--- a/chromium/third_party/WebKit/Source/core/events/MessageEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/MessageEvent.cpp
@@ -30,7 +30,6 @@
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
@@ -54,14 +53,14 @@ MessageEvent::MessageEvent(const AtomicString& type, const MessageEventInit& ini
, m_dataType(DataTypeScriptValue)
, m_origin(initializer.origin)
, m_lastEventId(initializer.lastEventId)
- , m_source(isValidSource(initializer.source.get()) ? initializer.source : 0)
+ , m_source(isValidSource(initializer.source.get()) ? initializer.source : nullptr)
, m_ports(adoptPtr(new MessagePortArray(initializer.ports)))
{
ScriptWrappable::init(this);
ASSERT(isValidSource(m_source.get()));
}
-MessageEvent::MessageEvent(const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortArray> ports)
+MessageEvent::MessageEvent(const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortArray> ports)
: Event(EventTypeNames::message, false, false)
, m_dataType(DataTypeScriptValue)
, m_origin(origin)
@@ -73,7 +72,7 @@ MessageEvent::MessageEvent(const String& origin, const String& lastEventId, Pass
ASSERT(isValidSource(m_source.get()));
}
-MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortArray> ports)
+MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortArray> ports)
: Event(EventTypeNames::message, false, false)
, m_dataType(DataTypeSerializedScriptValue)
, m_dataAsSerializedScriptValue(data)
@@ -88,7 +87,7 @@ MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String&
ASSERT(isValidSource(m_source.get()));
}
-MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortChannelArray> channels)
+MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortChannelArray> channels)
: Event(EventTypeNames::message, false, false)
, m_dataType(DataTypeSerializedScriptValue)
, m_dataAsSerializedScriptValue(data)
@@ -112,7 +111,7 @@ MessageEvent::MessageEvent(const String& data, const String& origin)
ScriptWrappable::init(this);
}
-MessageEvent::MessageEvent(PassRefPtr<Blob> data, const String& origin)
+MessageEvent::MessageEvent(PassRefPtrWillBeRawPtr<Blob> data, const String& origin)
: Event(EventTypeNames::message, false, false)
, m_dataType(DataTypeBlob)
, m_dataAsBlob(data)
@@ -134,16 +133,16 @@ MessageEvent::~MessageEvent()
{
}
-PassRefPtr<MessageEvent> MessageEvent::create(const AtomicString& type, const MessageEventInit& initializer, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<MessageEvent> MessageEvent::create(const AtomicString& type, const MessageEventInit& initializer, ExceptionState& exceptionState)
{
if (initializer.source.get() && !isValidSource(initializer.source.get())) {
exceptionState.throwTypeError("The optional 'source' property is neither a Window nor MessagePort.");
- return 0;
+ return nullptr;
}
- return adoptRef(new MessageEvent(type, initializer));
+ return adoptRefWillBeNoop(new MessageEvent(type, initializer));
}
-void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray> ports)
+void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& origin, const String& lastEventId, LocalDOMWindow* source, PassOwnPtr<MessagePortArray> ports)
{
if (dispatched())
return;
@@ -157,7 +156,7 @@ void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bo
m_ports = ports;
}
-void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray> ports)
+void MessageEvent::initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, LocalDOMWindow* source, PassOwnPtr<MessagePortArray> ports)
{
if (dispatched())
return;
@@ -185,4 +184,11 @@ void MessageEvent::entangleMessagePorts(ExecutionContext* context)
m_ports = MessagePort::entanglePorts(*context, m_channels.release());
}
+void MessageEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_dataAsBlob);
+ visitor->trace(m_source);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/MessageEvent.h b/chromium/third_party/WebKit/Source/core/events/MessageEvent.h
index 64df40f7718..966f620d413 100644
--- a/chromium/third_party/WebKit/Source/core/events/MessageEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/MessageEvent.h
@@ -33,7 +33,7 @@
#include "core/events/EventTarget.h"
#include "core/dom/MessagePort.h"
#include "core/fileapi/Blob.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "wtf/ArrayBuffer.h"
namespace WebCore {
@@ -43,45 +43,45 @@ struct MessageEventInit : public EventInit {
String origin;
String lastEventId;
- RefPtr<EventTarget> source;
+ RefPtrWillBeMember<EventTarget> source;
MessagePortArray ports;
};
-class MessageEvent : public Event {
+class MessageEvent FINAL : public Event {
public:
- static PassRefPtr<MessageEvent> create()
+ static PassRefPtrWillBeRawPtr<MessageEvent> create()
{
- return adoptRef(new MessageEvent);
+ return adoptRefWillBeNoop(new MessageEvent);
}
- static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = 0)
+ static PassRefPtrWillBeRawPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const String& origin = String(), const String& lastEventId = String(), PassRefPtrWillBeRawPtr<EventTarget> source = nullptr)
{
- return adoptRef(new MessageEvent(origin, lastEventId, source, ports));
+ return adoptRefWillBeNoop(new MessageEvent(origin, lastEventId, source, ports));
}
- static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = 0)
+ static PassRefPtrWillBeRawPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtrWillBeRawPtr<EventTarget> source = nullptr)
{
- return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
+ return adoptRefWillBeNoop(new MessageEvent(data, origin, lastEventId, source, ports));
}
- static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortChannelArray> channels, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = 0)
+ static PassRefPtrWillBeRawPtr<MessageEvent> create(PassOwnPtr<MessagePortChannelArray> channels, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtrWillBeRawPtr<EventTarget> source = nullptr)
{
- return adoptRef(new MessageEvent(data, origin, lastEventId, source, channels));
+ return adoptRefWillBeNoop(new MessageEvent(data, origin, lastEventId, source, channels));
}
- static PassRefPtr<MessageEvent> create(const String& data, const String& origin = String())
+ static PassRefPtrWillBeRawPtr<MessageEvent> create(const String& data, const String& origin = String())
{
- return adoptRef(new MessageEvent(data, origin));
+ return adoptRefWillBeNoop(new MessageEvent(data, origin));
}
- static PassRefPtr<MessageEvent> create(PassRefPtr<Blob> data, const String& origin = String())
+ static PassRefPtrWillBeRawPtr<MessageEvent> create(PassRefPtrWillBeRawPtr<Blob> data, const String& origin = String())
{
- return adoptRef(new MessageEvent(data, origin));
+ return adoptRefWillBeNoop(new MessageEvent(data, origin));
}
- static PassRefPtr<MessageEvent> create(PassRefPtr<ArrayBuffer> data, const String& origin = String())
+ static PassRefPtrWillBeRawPtr<MessageEvent> create(PassRefPtr<ArrayBuffer> data, const String& origin = String())
{
- return adoptRef(new MessageEvent(data, origin));
+ return adoptRefWillBeNoop(new MessageEvent(data, origin));
}
- static PassRefPtr<MessageEvent> create(const AtomicString& type, const MessageEventInit& initializer, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<MessageEvent> create(const AtomicString& type, const MessageEventInit& initializer, ExceptionState&);
virtual ~MessageEvent();
- void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
- void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, DOMWindow* source, PassOwnPtr<MessagePortArray>);
+ void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& origin, const String& lastEventId, LocalDOMWindow* source, PassOwnPtr<MessagePortArray>);
+ void initMessageEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, LocalDOMWindow* source, PassOwnPtr<MessagePortArray>);
const String& origin() const { return m_origin; }
const String& lastEventId() const { return m_lastEventId; }
@@ -90,7 +90,7 @@ public:
MessagePortArray ports() const { return m_ports ? *m_ports : MessagePortArray(); }
MessagePortChannelArray* channels() const { return m_channels ? m_channels.get() : 0; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
enum DataType {
DataTypeScriptValue,
@@ -113,25 +113,27 @@ public:
void entangleMessagePorts(ExecutionContext*);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
MessageEvent();
MessageEvent(const AtomicString&, const MessageEventInit&);
- MessageEvent(const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortArray>);
- MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortArray>);
- MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortChannelArray>);
+ MessageEvent(const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortArray>);
+ MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortArray>);
+ MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtrWillBeRawPtr<EventTarget> source, PassOwnPtr<MessagePortChannelArray>);
- explicit MessageEvent(const String& data, const String& origin);
- explicit MessageEvent(PassRefPtr<Blob> data, const String& origin);
- explicit MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin);
+ MessageEvent(const String& data, const String& origin);
+ MessageEvent(PassRefPtrWillBeRawPtr<Blob> data, const String& origin);
+ MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin);
DataType m_dataType;
RefPtr<SerializedScriptValue> m_dataAsSerializedScriptValue;
String m_dataAsString;
- RefPtr<Blob> m_dataAsBlob;
+ RefPtrWillBeMember<Blob> m_dataAsBlob;
RefPtr<ArrayBuffer> m_dataAsArrayBuffer;
String m_origin;
String m_lastEventId;
- RefPtr<EventTarget> m_source;
+ RefPtrWillBeMember<EventTarget> m_source;
// m_ports are the MessagePorts in an engtangled state, and m_channels are
// the MessageChannels in a disentangled state. Only one of them can be
// non-empty at a time. entangleMessagePorts() moves between the states.
diff --git a/chromium/third_party/WebKit/Source/core/events/MessageEvent.idl b/chromium/third_party/WebKit/Source/core/events/MessageEvent.idl
index c482b082cfb..b9e155bd652 100644
--- a/chromium/third_party/WebKit/Source/core/events/MessageEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/events/MessageEvent.idl
@@ -27,30 +27,21 @@
[
EventConstructor,
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker,
RaisesException=Constructor,
+ Custom=Wrap,
] interface MessageEvent : Event {
[InitializedByEventConstructor] readonly attribute DOMString origin;
[InitializedByEventConstructor] readonly attribute DOMString lastEventId;
[InitializedByEventConstructor] readonly attribute EventTarget? source; // May be a Window or a MessagePort
[InitializedByEventConstructor, Custom=Getter] readonly attribute any data;
[InitializedByEventConstructor] readonly attribute MessagePort[] ports;
- [Custom] void initMessageEvent([Default=Undefined] optional DOMString typeArg,
+ [Custom, MeasureAs=InitMessageEvent] void initMessageEvent([Default=Undefined] optional DOMString typeArg,
[Default=Undefined] optional boolean canBubbleArg,
[Default=Undefined] optional boolean cancelableArg,
[Default=Undefined] optional any dataArg,
[Default=Undefined] optional DOMString originArg,
[Default=Undefined] optional DOMString lastEventIdArg,
[Default=Undefined] optional Window sourceArg,
- [Default=Undefined] optional Array messagePorts);
-
- [Custom] void webkitInitMessageEvent([Default=Undefined] optional DOMString typeArg,
- [Default=Undefined] optional boolean canBubbleArg,
- [Default=Undefined] optional boolean cancelableArg,
- [Default=Undefined] optional any dataArg,
- [Default=Undefined] optional DOMString originArg,
- [Default=Undefined] optional DOMString lastEventIdArg,
- [Default=Undefined] optional Window sourceArg,
- [Default=Undefined] optional Array transferables);
+ [Default=Undefined] optional MessagePort[] messagePorts);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/events/MouseEvent.cpp b/chromium/third_party/WebKit/Source/core/events/MouseEvent.cpp
index 1e6a6979b81..47977893d00 100644
--- a/chromium/third_party/WebKit/Source/core/events/MouseEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/MouseEvent.cpp
@@ -23,11 +23,9 @@
#include "config.h"
#include "core/events/MouseEvent.h"
-#include "core/dom/Clipboard.h"
+#include "core/clipboard/Clipboard.h"
#include "core/dom/Element.h"
#include "core/events/EventDispatcher.h"
-#include "core/events/EventRetargeter.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "platform/PlatformMouseEvent.h"
namespace WebCore {
@@ -42,16 +40,16 @@ MouseEventInit::MouseEventInit()
, shiftKey(false)
, metaKey(false)
, button(0)
- , relatedTarget(0)
+ , relatedTarget(nullptr)
{
}
-PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& type, const MouseEventInit& initializer)
+PassRefPtrWillBeRawPtr<MouseEvent> MouseEvent::create(const AtomicString& type, const MouseEventInit& initializer)
{
- return adoptRef(new MouseEvent(type, initializer));
+ return adoptRefWillBeNoop(new MouseEvent(type, initializer));
}
-PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& eventType, PassRefPtr<AbstractView> view, const PlatformMouseEvent& event, int detail, PassRefPtr<Node> relatedTarget)
+PassRefPtrWillBeRawPtr<MouseEvent> MouseEvent::create(const AtomicString& eventType, PassRefPtrWillBeRawPtr<AbstractView> view, const PlatformMouseEvent& event, int detail, PassRefPtrWillBeRawPtr<Node> relatedTarget)
{
ASSERT(event.type() == PlatformEvent::MouseMoved || event.button() != NoButton);
@@ -59,33 +57,21 @@ PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& eventType, PassRef
bool isCancelable = !isMouseEnterOrLeave;
bool isBubbling = !isMouseEnterOrLeave;
- return MouseEvent::create(eventType, isBubbling, isCancelable, view,
+ return MouseEvent::create(
+ eventType, isBubbling, isCancelable, view,
detail, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
event.movementDelta().x(), event.movementDelta().y(),
event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.button(),
- relatedTarget, 0, false);
+ relatedTarget, nullptr, false);
}
-PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
+PassRefPtrWillBeRawPtr<MouseEvent> MouseEvent::create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view,
int detail, int screenX, int screenY, int pageX, int pageY,
int movementX, int movementY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTarget> relatedTarget)
-
-{
- return MouseEvent::create(type, canBubble, cancelable, view,
- detail, screenX, screenY, pageX, pageY,
- movementX, movementY,
- ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget, 0, false);
-}
-
-PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
- int detail, int screenX, int screenY, int pageX, int pageY,
- int movementX, int movementY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard> clipboard, bool isSimulated)
+ PassRefPtrWillBeRawPtr<EventTarget> relatedTarget, PassRefPtrWillBeRawPtr<Clipboard> clipboard, bool isSimulated)
{
- return adoptRef(new MouseEvent(type, canBubble, cancelable, view,
+ return adoptRefWillBeNoop(new MouseEvent(type, canBubble, cancelable, view,
detail, screenX, screenY, pageX, pageY,
movementX, movementY,
ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget, clipboard, isSimulated));
@@ -98,12 +84,12 @@ MouseEvent::MouseEvent()
ScriptWrappable::init(this);
}
-MouseEvent::MouseEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
- int detail, int screenX, int screenY, int pageX, int pageY,
- int movementX, int movementY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTarget> relatedTarget,
- PassRefPtr<Clipboard> clipboard, bool isSimulated)
+MouseEvent::MouseEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view,
+ int detail, int screenX, int screenY, int pageX, int pageY,
+ int movementX, int movementY,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
+ unsigned short button, PassRefPtrWillBeRawPtr<EventTarget> relatedTarget,
+ PassRefPtrWillBeRawPtr<Clipboard> clipboard, bool isSimulated)
: MouseRelatedEvent(eventType, canBubble, cancelable, view, detail, IntPoint(screenX, screenY),
IntPoint(pageX, pageY),
IntPoint(movementX, movementY),
@@ -124,7 +110,7 @@ MouseEvent::MouseEvent(const AtomicString& eventType, const MouseEventInit& init
, m_button(initializer.button == (unsigned short)-1 ? 0 : initializer.button)
, m_buttonDown(initializer.button != (unsigned short)-1)
, m_relatedTarget(initializer.relatedTarget)
- , m_clipboard(0 /* clipboard */)
+ , m_clipboard(nullptr /* clipboard */)
{
ScriptWrappable::init(this);
initCoordinates(IntPoint(initializer.clientX, initializer.clientY));
@@ -134,10 +120,10 @@ MouseEvent::~MouseEvent()
{
}
-void MouseEvent::initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
+void MouseEvent::initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view,
int detail, int screenX, int screenY, int clientX, int clientY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTarget> relatedTarget)
+ unsigned short button, PassRefPtrWillBeRawPtr<EventTarget> relatedTarget)
{
if (dispatched())
return;
@@ -204,19 +190,26 @@ Node* MouseEvent::fromElement() const
return target() ? target()->toNode() : 0;
}
-PassRefPtr<SimulatedMouseEvent> SimulatedMouseEvent::create(const AtomicString& eventType, PassRefPtr<AbstractView> view, PassRefPtr<Event> underlyingEvent)
+void MouseEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_relatedTarget);
+ visitor->trace(m_clipboard);
+ MouseRelatedEvent::trace(visitor);
+}
+
+PassRefPtrWillBeRawPtr<SimulatedMouseEvent> SimulatedMouseEvent::create(const AtomicString& eventType, PassRefPtrWillBeRawPtr<AbstractView> view, PassRefPtrWillBeRawPtr<Event> underlyingEvent)
{
- return adoptRef(new SimulatedMouseEvent(eventType, view, underlyingEvent));
+ return adoptRefWillBeNoop(new SimulatedMouseEvent(eventType, view, underlyingEvent));
}
SimulatedMouseEvent::~SimulatedMouseEvent()
{
}
-SimulatedMouseEvent::SimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<AbstractView> view, PassRefPtr<Event> underlyingEvent)
+SimulatedMouseEvent::SimulatedMouseEvent(const AtomicString& eventType, PassRefPtrWillBeRawPtr<AbstractView> view, PassRefPtrWillBeRawPtr<Event> underlyingEvent)
: MouseEvent(eventType, true, true, view, 0, 0, 0, 0, 0,
0, 0,
- false, false, false, false, 0, 0, 0, true)
+ false, false, false, false, 0, nullptr, nullptr, true)
{
if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEvent.get())) {
m_ctrlKey = keyStateEvent->ctrlKey();
@@ -233,12 +226,17 @@ SimulatedMouseEvent::SimulatedMouseEvent(const AtomicString& eventType, PassRefP
}
}
-PassRefPtr<MouseEventDispatchMediator> MouseEventDispatchMediator::create(PassRefPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
+void SimulatedMouseEvent::trace(Visitor* visitor)
+{
+ MouseEvent::trace(visitor);
+}
+
+PassRefPtrWillBeRawPtr<MouseEventDispatchMediator> MouseEventDispatchMediator::create(PassRefPtrWillBeRawPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
{
- return adoptRef(new MouseEventDispatchMediator(mouseEvent, mouseEventType));
+ return adoptRefWillBeNoop(new MouseEventDispatchMediator(mouseEvent, mouseEventType));
}
-MouseEventDispatchMediator::MouseEventDispatchMediator(PassRefPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
+MouseEventDispatchMediator::MouseEventDispatchMediator(PassRefPtrWillBeRawPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
: EventDispatchMediator(mouseEvent), m_mouseEventType(mouseEventType)
{
}
@@ -251,7 +249,7 @@ MouseEvent* MouseEventDispatchMediator::event() const
bool MouseEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
{
if (isSyntheticMouseEvent()) {
- EventRetargeter::adjustForMouseEvent(dispatcher->node(), *event());
+ event()->eventPath().adjustForRelatedTarget(dispatcher->node(), event()->relatedTarget());
return dispatcher->dispatch();
}
@@ -264,7 +262,7 @@ bool MouseEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) cons
ASSERT(!event()->target() || event()->target() != event()->relatedTarget());
EventTarget* relatedTarget = event()->relatedTarget();
- EventRetargeter::adjustForMouseEvent(dispatcher->node(), *event());
+ event()->eventPath().adjustForRelatedTarget(dispatcher->node(), relatedTarget);
dispatcher->dispatch();
bool swallowEvent = event()->defaultHandled() || event()->defaultPrevented();
@@ -275,7 +273,7 @@ bool MouseEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) cons
// Special case: If it's a double click event, we also send the dblclick event. This is not part
// of the DOM specs, but is used for compatibility with the ondblclick="" attribute. This is treated
// as a separate event in other DOM-compliant browsers like Firefox, and so we do the same.
- RefPtr<MouseEvent> doubleClickEvent = MouseEvent::create();
+ RefPtrWillBeRawPtr<MouseEvent> doubleClickEvent = MouseEvent::create();
doubleClickEvent->initMouseEvent(EventTypeNames::dblclick, event()->bubbles(), event()->cancelable(), event()->view(),
event()->detail(), event()->screenX(), event()->screenY(), event()->clientX(), event()->clientY(),
event()->ctrlKey(), event()->altKey(), event()->shiftKey(), event()->metaKey(),
diff --git a/chromium/third_party/WebKit/Source/core/events/MouseEvent.h b/chromium/third_party/WebKit/Source/core/events/MouseEvent.h
index 41ab261eb8e..fc364c8e8c7 100644
--- a/chromium/third_party/WebKit/Source/core/events/MouseEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/MouseEvent.h
@@ -45,38 +45,32 @@ struct MouseEventInit : public UIEventInit {
bool shiftKey;
bool metaKey;
unsigned short button;
- RefPtr<EventTarget> relatedTarget;
+ RefPtrWillBeMember<EventTarget> relatedTarget;
};
class MouseEvent : public MouseRelatedEvent {
public:
- static PassRefPtr<MouseEvent> create()
+ static PassRefPtrWillBeRawPtr<MouseEvent> create()
{
- return adoptRef(new MouseEvent);
+ return adoptRefWillBeNoop(new MouseEvent);
}
- static PassRefPtr<MouseEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
+ static PassRefPtrWillBeRawPtr<MouseEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>,
int detail, int screenX, int screenY, int pageX, int pageY,
int movementX, int movementY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTarget> relatedTarget);
+ PassRefPtrWillBeRawPtr<EventTarget> relatedTarget, PassRefPtrWillBeRawPtr<Clipboard>, bool isSimulated = false);
- static PassRefPtr<MouseEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
- int detail, int screenX, int screenY, int pageX, int pageY,
- int movementX, int movementY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard>, bool isSimulated = false);
-
- static PassRefPtr<MouseEvent> create(const AtomicString& eventType, PassRefPtr<AbstractView>, const PlatformMouseEvent&, int detail, PassRefPtr<Node> relatedTarget);
+ static PassRefPtrWillBeRawPtr<MouseEvent> create(const AtomicString& eventType, PassRefPtrWillBeRawPtr<AbstractView>, const PlatformMouseEvent&, int detail, PassRefPtrWillBeRawPtr<Node> relatedTarget);
- static PassRefPtr<MouseEvent> create(const AtomicString& eventType, const MouseEventInit&);
+ static PassRefPtrWillBeRawPtr<MouseEvent> create(const AtomicString& eventType, const MouseEventInit&);
virtual ~MouseEvent();
- void initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
+ void initMouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>,
int detail, int screenX, int screenY, int clientX, int clientY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
- unsigned short button, PassRefPtr<EventTarget> relatedTarget);
+ unsigned short button, PassRefPtrWillBeRawPtr<EventTarget> relatedTarget);
// WinIE uses 1,4,2 for left/middle/right but not for click (just for mousedown/up, maybe others),
// but we will match the standard DOM.
@@ -84,27 +78,27 @@ public:
bool buttonDown() const { return m_buttonDown; }
EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
EventTarget* relatedTarget(bool& isNull) const { isNull = !m_relatedTarget; return m_relatedTarget.get(); }
- void setRelatedTarget(PassRefPtr<EventTarget> relatedTarget) { m_relatedTarget = relatedTarget; }
-
- Clipboard* clipboard() const { return m_clipboard.get(); }
+ void setRelatedTarget(PassRefPtrWillBeRawPtr<EventTarget> relatedTarget) { m_relatedTarget = relatedTarget; }
Node* toElement() const;
Node* fromElement() const;
Clipboard* dataTransfer() const { return isDragEvent() ? m_clipboard.get() : 0; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual bool isMouseEvent() const OVERRIDE;
+ virtual bool isDragEvent() const OVERRIDE FINAL;
+ virtual int which() const OVERRIDE FINAL;
- virtual bool isMouseEvent() const;
- virtual bool isDragEvent() const;
- virtual int which() const;
+ virtual void trace(Visitor*) OVERRIDE;
protected:
- MouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
+ MouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>,
int detail, int screenX, int screenY, int pageX, int pageY,
int movementX, int movementY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
- PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard>, bool isSimulated);
+ PassRefPtrWillBeRawPtr<EventTarget> relatedTarget, PassRefPtrWillBeRawPtr<Clipboard>, bool isSimulated);
MouseEvent(const AtomicString& type, const MouseEventInit&);
@@ -113,26 +107,28 @@ protected:
private:
unsigned short m_button;
bool m_buttonDown;
- RefPtr<EventTarget> m_relatedTarget;
- RefPtr<Clipboard> m_clipboard;
+ RefPtrWillBeMember<EventTarget> m_relatedTarget;
+ RefPtrWillBeMember<Clipboard> m_clipboard;
};
-class SimulatedMouseEvent : public MouseEvent {
+class SimulatedMouseEvent FINAL : public MouseEvent {
public:
- static PassRefPtr<SimulatedMouseEvent> create(const AtomicString& eventType, PassRefPtr<AbstractView>, PassRefPtr<Event> underlyingEvent);
+ static PassRefPtrWillBeRawPtr<SimulatedMouseEvent> create(const AtomicString& eventType, PassRefPtrWillBeRawPtr<AbstractView>, PassRefPtrWillBeRawPtr<Event> underlyingEvent);
virtual ~SimulatedMouseEvent();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- SimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<AbstractView>, PassRefPtr<Event> underlyingEvent);
+ SimulatedMouseEvent(const AtomicString& eventType, PassRefPtrWillBeRawPtr<AbstractView>, PassRefPtrWillBeRawPtr<Event> underlyingEvent);
};
-class MouseEventDispatchMediator : public EventDispatchMediator {
+class MouseEventDispatchMediator FINAL : public EventDispatchMediator {
public:
enum MouseEventType { SyntheticMouseEvent, NonSyntheticMouseEvent};
- static PassRefPtr<MouseEventDispatchMediator> create(PassRefPtr<MouseEvent>, MouseEventType = NonSyntheticMouseEvent);
+ static PassRefPtrWillBeRawPtr<MouseEventDispatchMediator> create(PassRefPtrWillBeRawPtr<MouseEvent>, MouseEventType = NonSyntheticMouseEvent);
private:
- explicit MouseEventDispatchMediator(PassRefPtr<MouseEvent>, MouseEventType);
+ explicit MouseEventDispatchMediator(PassRefPtrWillBeRawPtr<MouseEvent>, MouseEventType);
MouseEvent* event() const;
virtual bool dispatchEvent(EventDispatcher*) const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/events/MouseEvent.idl b/chromium/third_party/WebKit/Source/core/events/MouseEvent.idl
index 7dd8284bf78..f5b03c862d9 100644
--- a/chromium/third_party/WebKit/Source/core/events/MouseEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/events/MouseEvent.idl
@@ -30,8 +30,10 @@
[InitializedByEventConstructor] readonly attribute boolean metaKey;
[InitializedByEventConstructor] readonly attribute unsigned short button;
[InitializedByEventConstructor] readonly attribute EventTarget? relatedTarget;
- readonly attribute long webkitMovementX;
- readonly attribute long webkitMovementY;
+ [MeasureAs=MouseEventMovementX] readonly attribute long movementX;
+ [MeasureAs=MouseEventMovementY] readonly attribute long movementY;
+ [MeasureAs=PrefixedMouseEventMovementX, ImplementedAs=movementX] readonly attribute long webkitMovementX;
+ [MeasureAs=PrefixedMouseEventMovementY, ImplementedAs=movementY] readonly attribute long webkitMovementY;
void initMouseEvent([Default=Undefined] optional DOMString type,
[Default=Undefined] optional boolean canBubble,
@@ -57,6 +59,6 @@
readonly attribute Node fromElement;
readonly attribute Node toElement;
- readonly attribute Clipboard dataTransfer;
+ readonly attribute DataTransfer dataTransfer;
};
diff --git a/chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp b/chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp
index 4953243cae1..7ab48f3b5fd 100644
--- a/chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.cpp
@@ -24,9 +24,9 @@
#include "core/events/MouseRelatedEvent.h"
#include "core/dom/Document.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderObject.h"
@@ -42,7 +42,7 @@ static LayoutSize contentsScrollOffset(AbstractView* abstractView)
{
if (!abstractView)
return LayoutSize();
- Frame* frame = abstractView->frame();
+ LocalFrame* frame = abstractView->frame();
if (!frame)
return LayoutSize();
FrameView* frameView = frame->view();
@@ -52,7 +52,7 @@ static LayoutSize contentsScrollOffset(AbstractView* abstractView)
return LayoutSize(frameView->scrollX() / scaleFactor, frameView->scrollY() / scaleFactor);
}
-MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> abstractView,
+MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> abstractView,
int detail, const IntPoint& screenLocation, const IntPoint& windowLocation,
const IntPoint& movementDelta,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool isSimulated)
@@ -64,7 +64,7 @@ MouseRelatedEvent::MouseRelatedEvent(const AtomicString& eventType, bool canBubb
LayoutPoint adjustedPageLocation;
LayoutPoint scrollPosition;
- Frame* frame = view() ? view()->frame() : 0;
+ LocalFrame* frame = view() ? view()->frame() : 0;
if (frame && !isSimulated) {
if (FrameView* frameView = frame->view()) {
scrollPosition = frameView->scrollPosition();
@@ -110,10 +110,10 @@ void MouseRelatedEvent::initCoordinates(const LayoutPoint& clientLocation)
static float pageZoomFactor(const UIEvent* event)
{
- DOMWindow* window = event->view();
+ LocalDOMWindow* window = event->view();
if (!window)
return 1;
- Frame* frame = window->frame();
+ LocalFrame* frame = window->frame();
if (!frame)
return 1;
return frame->pageZoomFactor();
@@ -160,11 +160,9 @@ void MouseRelatedEvent::computeRelativePosition()
while (n && !n->renderer())
n = n->parentNode();
- RenderLayer* layer;
- if (n && (layer = n->renderer()->enclosingLayer())) {
- for (; layer; layer = layer->parent()) {
+ if (n) {
+ for (RenderLayer* layer = n->renderer()->enclosingLayer(); layer; layer = layer->parent())
m_layerLocation -= toLayoutSize(layer->location());
- }
}
m_hasCachedRelativePosition = true;
@@ -186,6 +184,8 @@ int MouseRelatedEvent::layerY()
int MouseRelatedEvent::offsetX()
{
+ if (isSimulated())
+ return 0;
if (!m_hasCachedRelativePosition)
computeRelativePosition();
return roundToInt(m_offsetLocation.x());
@@ -193,6 +193,8 @@ int MouseRelatedEvent::offsetX()
int MouseRelatedEvent::offsetY()
{
+ if (isSimulated())
+ return 0;
if (!m_hasCachedRelativePosition)
computeRelativePosition();
return roundToInt(m_offsetLocation.y());
@@ -208,11 +210,6 @@ int MouseRelatedEvent::pageY() const
return m_pageLocation.y();
}
-const LayoutPoint& MouseRelatedEvent::pageLocation() const
-{
- return m_pageLocation;
-}
-
int MouseRelatedEvent::x() const
{
// FIXME: This is not correct.
@@ -227,4 +224,9 @@ int MouseRelatedEvent::y() const
return m_clientLocation.y();
}
+void MouseRelatedEvent::trace(Visitor* visitor)
+{
+ UIEventWithKeyState::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.h b/chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.h
index fbaeb9c68aa..2dd28ca5b59 100644
--- a/chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/MouseRelatedEvent.h
@@ -39,17 +39,16 @@ namespace WebCore {
const IntPoint& screenLocation() const { return m_screenLocation; }
int clientX() const { return m_clientLocation.x(); }
int clientY() const { return m_clientLocation.y(); }
- int webkitMovementX() const { return m_movementDelta.x(); }
- int webkitMovementY() const { return m_movementDelta.y(); }
+ int movementX() const { return m_movementDelta.x(); }
+ int movementY() const { return m_movementDelta.y(); }
const LayoutPoint& clientLocation() const { return m_clientLocation; }
- int layerX();
- int layerY();
+ virtual int layerX() OVERRIDE FINAL;
+ virtual int layerY() OVERRIDE FINAL;
int offsetX();
int offsetY();
bool isSimulated() const { return m_isSimulated; }
- virtual int pageX() const;
- virtual int pageY() const;
- virtual const LayoutPoint& pageLocation() const;
+ virtual int pageX() const OVERRIDE FINAL;
+ virtual int pageY() const OVERRIDE FINAL;
int x() const;
int y() const;
@@ -58,16 +57,18 @@ namespace WebCore {
const LayoutPoint& absoluteLocation() const { return m_absoluteLocation; }
void setAbsoluteLocation(const LayoutPoint& p) { m_absoluteLocation = p; }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
MouseRelatedEvent();
- MouseRelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
+ MouseRelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>,
int detail, const IntPoint& screenLocation, const IntPoint& windowLocation,
const IntPoint& movementDelta,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool isSimulated = false);
void initCoordinates();
void initCoordinates(const LayoutPoint& clientLocation);
- virtual void receivedTarget();
+ virtual void receivedTarget() OVERRIDE FINAL;
void computePageLocation();
void computeRelativePosition();
diff --git a/chromium/third_party/WebKit/Source/core/events/MutationEvent.cpp b/chromium/third_party/WebKit/Source/core/events/MutationEvent.cpp
index 542b304505b..4c78269f9d9 100644
--- a/chromium/third_party/WebKit/Source/core/events/MutationEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/MutationEvent.cpp
@@ -23,8 +23,6 @@
#include "config.h"
#include "core/events/MutationEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
MutationEvent::MutationEvent()
@@ -33,7 +31,7 @@ MutationEvent::MutationEvent()
ScriptWrappable::init(this);
}
-MutationEvent::MutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
+MutationEvent::MutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<Node> relatedNode,
const String& prevValue, const String& newValue,
const String& attrName, unsigned short attrChange)
: Event(type, canBubble, cancelable)
@@ -50,7 +48,7 @@ MutationEvent::~MutationEvent()
{
}
-void MutationEvent::initMutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
+void MutationEvent::initMutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<Node> relatedNode,
const String& prevValue, const String& newValue,
const String& attrName, unsigned short attrChange)
{
@@ -71,4 +69,10 @@ const AtomicString& MutationEvent::interfaceName() const
return EventNames::MutationEvent;
}
+void MutationEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_relatedNode);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/MutationEvent.h b/chromium/third_party/WebKit/Source/core/events/MutationEvent.h
index f0ef13e5b6c..251f2f53134 100644
--- a/chromium/third_party/WebKit/Source/core/events/MutationEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/MutationEvent.h
@@ -29,7 +29,7 @@
namespace WebCore {
- class MutationEvent : public Event {
+ class MutationEvent FINAL : public Event {
public:
virtual ~MutationEvent();
@@ -39,18 +39,19 @@ namespace WebCore {
REMOVAL = 3
};
- static PassRefPtr<MutationEvent> create()
+ static PassRefPtrWillBeRawPtr<MutationEvent> create()
{
- return adoptRef(new MutationEvent);
+ return adoptRefWillBeNoop(new MutationEvent);
}
- static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode = 0,
+ static PassRefPtrWillBeRawPtr<MutationEvent> create(
+ const AtomicString& type, bool canBubble, PassRefPtrWillBeRawPtr<Node> relatedNode = nullptr,
const String& prevValue = String(), const String& newValue = String(), const String& attrName = String(), unsigned short attrChange = 0)
{
- return adoptRef(new MutationEvent(type, canBubble, false, relatedNode, prevValue, newValue, attrName, attrChange));
+ return adoptRefWillBeNoop(new MutationEvent(type, canBubble, false, relatedNode, prevValue, newValue, attrName, attrChange));
}
- void initMutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
+ void initMutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<Node> relatedNode,
const String& prevValue, const String& newValue,
const String& attrName, unsigned short attrChange);
@@ -60,15 +61,17 @@ namespace WebCore {
String attrName() const { return m_attrName; }
unsigned short attrChange() const { return m_attrChange; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
MutationEvent();
- MutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
+ MutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<Node> relatedNode,
const String& prevValue, const String& newValue,
const String& attrName, unsigned short attrChange);
- RefPtr<Node> m_relatedNode;
+ RefPtrWillBeMember<Node> m_relatedNode;
String m_prevValue;
String m_newValue;
String m_attrName;
diff --git a/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.cpp b/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.cpp
index a4285c21ef8..526cdc8ca65 100644
--- a/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.cpp
@@ -31,15 +31,15 @@
#include "config.h"
#include "core/events/NavigatorEvents.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Navigator.h"
#include "core/frame/Settings.h"
namespace WebCore {
-long NavigatorEvents::maxTouchPoints(Navigator* navigator)
+long NavigatorEvents::maxTouchPoints(Navigator& navigator)
{
- Frame* frame = navigator->frame();
+ LocalFrame* frame = navigator.frame();
if (!frame)
return 0;
if (Settings* settings = frame->settings())
diff --git a/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.h b/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.h
index 44cead91197..84f3ad7981e 100644
--- a/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.h
+++ b/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.h
@@ -37,7 +37,7 @@ class Navigator;
class NavigatorEvents {
public:
- static long maxTouchPoints(Navigator*);
+ static long maxTouchPoints(Navigator&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.idl b/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.idl
index fe899fc50b8..ed3d2068fff 100644
--- a/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.idl
+++ b/chromium/third_party/WebKit/Source/core/events/NavigatorEvents.idl
@@ -29,6 +29,5 @@
*/
partial interface Navigator {
- [RuntimeEnabled=PointerEventsMaxTouchPoints]
- readonly attribute long maxTouchPoints;
-}; \ No newline at end of file
+ readonly attribute long maxTouchPoints;
+};
diff --git a/chromium/third_party/WebKit/Source/core/events/NodeEventContext.cpp b/chromium/third_party/WebKit/Source/core/events/NodeEventContext.cpp
new file mode 100644
index 00000000000..3cfac4c8f03
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/NodeEventContext.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "core/events/NodeEventContext.h"
+
+#include "core/dom/TouchList.h"
+#include "core/events/Event.h"
+#include "core/events/FocusEvent.h"
+#include "core/events/MouseEvent.h"
+#include "core/events/TouchEventContext.h"
+
+namespace WebCore {
+
+NodeEventContext::NodeEventContext(PassRefPtrWillBeRawPtr<Node> node, PassRefPtrWillBeRawPtr<EventTarget> currentTarget)
+ : m_node(node)
+ , m_currentTarget(currentTarget)
+{
+ ASSERT(m_node);
+}
+
+NodeEventContext::~NodeEventContext()
+{
+}
+
+void NodeEventContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_node);
+ visitor->trace(m_currentTarget);
+ visitor->trace(m_treeScopeEventContext);
+}
+
+void NodeEventContext::handleLocalEvents(Event* event) const
+{
+ if (touchEventContext()) {
+ touchEventContext()->handleLocalEvents(event);
+ } else if (relatedTarget()) {
+ if (event->isMouseEvent()) {
+ toMouseEvent(event)->setRelatedTarget(relatedTarget());
+ } else if (event->isFocusEvent()) {
+ toFocusEvent(event)->setRelatedTarget(relatedTarget());
+ }
+ }
+ event->setTarget(target());
+ event->setCurrentTarget(m_currentTarget.get());
+ m_node->handleLocalEvents(event);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/events/NodeEventContext.h b/chromium/third_party/WebKit/Source/core/events/NodeEventContext.h
new file mode 100644
index 00000000000..e54da1896c1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/NodeEventContext.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NodeEventContext_h
+#define NodeEventContext_h
+
+#include "core/events/TreeScopeEventContext.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class EventTarget;
+class Node;
+class TouchEventContext;
+
+class NodeEventContext {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
+ // FIXME: Use ContainerNode instead of Node.
+ NodeEventContext(PassRefPtrWillBeRawPtr<Node>, PassRefPtrWillBeRawPtr<EventTarget> currentTarget);
+ ~NodeEventContext();
+ void trace(Visitor*);
+
+ Node* node() const { return m_node.get(); }
+
+ void setTreeScopeEventContext(PassRefPtrWillBeRawPtr<TreeScopeEventContext> prpTreeScopeEventContext) { m_treeScopeEventContext = prpTreeScopeEventContext; }
+ TreeScopeEventContext& treeScopeEventContext() { ASSERT(m_treeScopeEventContext); return *m_treeScopeEventContext; }
+
+ EventTarget* target() const { return m_treeScopeEventContext->target(); }
+ EventTarget* relatedTarget() const { return m_treeScopeEventContext->relatedTarget(); }
+ TouchEventContext* touchEventContext() const { return m_treeScopeEventContext->touchEventContext(); }
+
+ bool currentTargetSameAsTarget() const { return m_currentTarget.get() == target(); }
+ void handleLocalEvents(Event*) const;
+
+private:
+ RefPtrWillBeMember<Node> m_node;
+ RefPtrWillBeMember<EventTarget> m_currentTarget;
+ RefPtrWillBeMember<TreeScopeEventContext> m_treeScopeEventContext;
+};
+
+}
+
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::NodeEventContext);
+
+#endif // NodeEventContext_h
diff --git a/chromium/third_party/WebKit/Source/core/events/OverflowEvent.cpp b/chromium/third_party/WebKit/Source/core/events/OverflowEvent.cpp
index c958ce655e6..e6c469ddd5e 100644
--- a/chromium/third_party/WebKit/Source/core/events/OverflowEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/OverflowEvent.cpp
@@ -26,8 +26,6 @@
#include "config.h"
#include "core/events/OverflowEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
OverflowEventInit::OverflowEventInit()
@@ -76,14 +74,9 @@ const AtomicString& OverflowEvent::interfaceName() const
return EventNames::OverflowEvent;
}
-void OverflowEvent::initOverflowEvent(unsigned short orient, bool horizontalOverflow, bool verticalOverflow)
+void OverflowEvent::trace(Visitor* visitor)
{
- if (dispatched())
- return;
-
- m_orient = orient;
- m_horizontalOverflow = horizontalOverflow;
- m_verticalOverflow = verticalOverflow;
+ Event::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/events/OverflowEvent.h b/chromium/third_party/WebKit/Source/core/events/OverflowEvent.h
index 96c220b2198..3bc1dc3efb1 100644
--- a/chromium/third_party/WebKit/Source/core/events/OverflowEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/OverflowEvent.h
@@ -38,7 +38,7 @@ struct OverflowEventInit : public EventInit {
bool verticalOverflow;
};
-class OverflowEvent : public Event {
+class OverflowEvent FINAL : public Event {
public:
enum orientType {
HORIZONTAL = 0,
@@ -46,26 +46,26 @@ public:
BOTH = 2
};
- static PassRefPtr<OverflowEvent> create()
+ static PassRefPtrWillBeRawPtr<OverflowEvent> create()
{
- return adoptRef(new OverflowEvent);
+ return adoptRefWillBeNoop(new OverflowEvent);
}
- static PassRefPtr<OverflowEvent> create(bool horizontalOverflowChanged, bool horizontalOverflow, bool verticalOverflowChanged, bool verticalOverflow)
+ static PassRefPtrWillBeRawPtr<OverflowEvent> create(bool horizontalOverflowChanged, bool horizontalOverflow, bool verticalOverflowChanged, bool verticalOverflow)
{
- return adoptRef(new OverflowEvent(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow));
+ return adoptRefWillBeNoop(new OverflowEvent(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow));
}
- static PassRefPtr<OverflowEvent> create(const AtomicString& type, const OverflowEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<OverflowEvent> create(const AtomicString& type, const OverflowEventInit& initializer)
{
- return adoptRef(new OverflowEvent(type, initializer));
+ return adoptRefWillBeNoop(new OverflowEvent(type, initializer));
}
- void initOverflowEvent(unsigned short orient, bool horizontalOverflow, bool verticalOverflow);
-
unsigned short orient() const { return m_orient; }
bool horizontalOverflow() const { return m_horizontalOverflow; }
bool verticalOverflow() const { return m_verticalOverflow; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
OverflowEvent();
diff --git a/chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp b/chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp
index a1878c468c5..d6b9a66b3bc 100644
--- a/chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.cpp
@@ -26,8 +26,6 @@
#include "config.h"
#include "core/events/PageTransitionEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
PageTransitionEventInit::PageTransitionEventInit()
@@ -64,4 +62,9 @@ const AtomicString& PageTransitionEvent::interfaceName() const
return EventNames::PageTransitionEvent;
}
+void PageTransitionEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.h b/chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.h
index 1002f5562ad..b8b1ba4d80e 100644
--- a/chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/PageTransitionEvent.h
@@ -36,27 +36,29 @@ struct PageTransitionEventInit : public EventInit {
bool persisted;
};
-class PageTransitionEvent : public Event {
+class PageTransitionEvent FINAL : public Event {
public:
- static PassRefPtr<PageTransitionEvent> create()
+ static PassRefPtrWillBeRawPtr<PageTransitionEvent> create()
{
- return adoptRef(new PageTransitionEvent);
+ return adoptRefWillBeNoop(new PageTransitionEvent);
}
- static PassRefPtr<PageTransitionEvent> create(const AtomicString& type, bool persisted)
+ static PassRefPtrWillBeRawPtr<PageTransitionEvent> create(const AtomicString& type, bool persisted)
{
- return adoptRef(new PageTransitionEvent(type, persisted));
+ return adoptRefWillBeNoop(new PageTransitionEvent(type, persisted));
}
- static PassRefPtr<PageTransitionEvent> create(const AtomicString& type, const PageTransitionEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<PageTransitionEvent> create(const AtomicString& type, const PageTransitionEventInit& initializer)
{
- return adoptRef(new PageTransitionEvent(type, initializer));
+ return adoptRefWillBeNoop(new PageTransitionEvent(type, initializer));
}
virtual ~PageTransitionEvent();
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
bool persisted() const { return m_persisted; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
PageTransitionEvent();
PageTransitionEvent(const AtomicString& type, bool persisted);
diff --git a/chromium/third_party/WebKit/Source/core/events/PopStateEvent.cpp b/chromium/third_party/WebKit/Source/core/events/PopStateEvent.cpp
index 2ab213a18f2..bab1ac01adf 100644
--- a/chromium/third_party/WebKit/Source/core/events/PopStateEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/PopStateEvent.cpp
@@ -28,27 +28,26 @@
#include "core/events/PopStateEvent.h"
#include "bindings/v8/SerializedScriptValue.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/frame/History.h"
namespace WebCore {
PopStateEvent::PopStateEvent()
: Event(EventTypeNames::popstate, false, true)
- , m_serializedState(0)
- , m_history(0)
+ , m_serializedState(nullptr)
+ , m_history(nullptr)
{
ScriptWrappable::init(this);
}
PopStateEvent::PopStateEvent(const AtomicString& type, const PopStateEventInit& initializer)
: Event(type, initializer)
- , m_history(0)
+ , m_history(nullptr)
{
ScriptWrappable::init(this);
}
-PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtr<History> history)
+PopStateEvent::PopStateEvent(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtrWillBeRawPtr<History> history)
: Event(EventTypeNames::popstate, false, true)
, m_serializedState(serializedState)
, m_history(history)
@@ -60,19 +59,19 @@ PopStateEvent::~PopStateEvent()
{
}
-PassRefPtr<PopStateEvent> PopStateEvent::create()
+PassRefPtrWillBeRawPtr<PopStateEvent> PopStateEvent::create()
{
- return adoptRef(new PopStateEvent);
+ return adoptRefWillBeNoop(new PopStateEvent);
}
-PassRefPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtr<History> history)
+PassRefPtrWillBeRawPtr<PopStateEvent> PopStateEvent::create(PassRefPtr<SerializedScriptValue> serializedState, PassRefPtrWillBeRawPtr<History> history)
{
- return adoptRef(new PopStateEvent(serializedState, history));
+ return adoptRefWillBeNoop(new PopStateEvent(serializedState, history));
}
-PassRefPtr<PopStateEvent> PopStateEvent::create(const AtomicString& type, const PopStateEventInit& initializer)
+PassRefPtrWillBeRawPtr<PopStateEvent> PopStateEvent::create(const AtomicString& type, const PopStateEventInit& initializer)
{
- return adoptRef(new PopStateEvent(type, initializer));
+ return adoptRefWillBeNoop(new PopStateEvent(type, initializer));
}
const AtomicString& PopStateEvent::interfaceName() const
@@ -80,4 +79,10 @@ const AtomicString& PopStateEvent::interfaceName() const
return EventNames::PopStateEvent;
}
+void PopStateEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_history);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/PopStateEvent.h b/chromium/third_party/WebKit/Source/core/events/PopStateEvent.h
index 5f874ea0174..ba4996756cd 100644
--- a/chromium/third_party/WebKit/Source/core/events/PopStateEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/PopStateEvent.h
@@ -28,6 +28,7 @@
#define PopStateEvent_h
#include "core/events/Event.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -36,12 +37,12 @@ class SerializedScriptValue;
typedef EventInit PopStateEventInit;
-class PopStateEvent : public Event {
+class PopStateEvent FINAL : public Event {
public:
virtual ~PopStateEvent();
- static PassRefPtr<PopStateEvent> create();
- static PassRefPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>);
- static PassRefPtr<PopStateEvent> create(const AtomicString&, const PopStateEventInit&);
+ static PassRefPtrWillBeRawPtr<PopStateEvent> create();
+ static PassRefPtrWillBeRawPtr<PopStateEvent> create(PassRefPtr<SerializedScriptValue>, PassRefPtrWillBeRawPtr<History>);
+ static PassRefPtrWillBeRawPtr<PopStateEvent> create(const AtomicString&, const PopStateEventInit&);
SerializedScriptValue* serializedState() const { return m_serializedState.get(); }
void setSerializedState(PassRefPtr<SerializedScriptValue> state)
@@ -51,15 +52,17 @@ public:
}
History* history() const { return m_history.get(); }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
PopStateEvent();
PopStateEvent(const AtomicString&, const PopStateEventInit&);
- explicit PopStateEvent(PassRefPtr<SerializedScriptValue>, PassRefPtr<History>);
+ PopStateEvent(PassRefPtr<SerializedScriptValue>, PassRefPtrWillBeRawPtr<History>);
RefPtr<SerializedScriptValue> m_serializedState;
- RefPtr<History> m_history;
+ RefPtrWillBeMember<History> m_history;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/ProgressEvent.cpp b/chromium/third_party/WebKit/Source/core/events/ProgressEvent.cpp
index d50bdad5edf..176efe900c7 100644
--- a/chromium/third_party/WebKit/Source/core/events/ProgressEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/ProgressEvent.cpp
@@ -26,8 +26,6 @@
#include "config.h"
#include "core/events/ProgressEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
ProgressEventInit::ProgressEventInit()
@@ -68,4 +66,9 @@ const AtomicString& ProgressEvent::interfaceName() const
return EventNames::ProgressEvent;
}
+void ProgressEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/events/ProgressEvent.h b/chromium/third_party/WebKit/Source/core/events/ProgressEvent.h
index eb5edb72a21..cb6bcd154df 100644
--- a/chromium/third_party/WebKit/Source/core/events/ProgressEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/ProgressEvent.h
@@ -40,24 +40,26 @@ struct ProgressEventInit : public EventInit {
class ProgressEvent : public Event {
public:
- static PassRefPtr<ProgressEvent> create()
+ static PassRefPtrWillBeRawPtr<ProgressEvent> create()
{
- return adoptRef(new ProgressEvent);
+ return adoptRefWillBeNoop(new ProgressEvent);
}
- static PassRefPtr<ProgressEvent> create(const AtomicString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total)
+ static PassRefPtrWillBeRawPtr<ProgressEvent> create(const AtomicString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total)
{
- return adoptRef(new ProgressEvent(type, lengthComputable, loaded, total));
+ return adoptRefWillBeNoop(new ProgressEvent(type, lengthComputable, loaded, total));
}
- static PassRefPtr<ProgressEvent> create(const AtomicString& type, const ProgressEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<ProgressEvent> create(const AtomicString& type, const ProgressEventInit& initializer)
{
- return adoptRef(new ProgressEvent(type, initializer));
+ return adoptRefWillBeNoop(new ProgressEvent(type, initializer));
}
bool lengthComputable() const { return m_lengthComputable; }
unsigned long long loaded() const { return m_loaded; }
unsigned long long total() const { return m_total; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
protected:
ProgressEvent();
diff --git a/chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.cpp b/chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.cpp
index 59d10d4d27d..08fd75b2533 100644
--- a/chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.cpp
@@ -51,4 +51,9 @@ const AtomicString& ResourceProgressEvent::interfaceName() const
return EventNames::ResourceProgressEvent;
}
+void ResourceProgressEvent::trace(Visitor* visitor)
+{
+ ProgressEvent::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.h b/chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.h
index 9c88b193d38..b7feb94db71 100644
--- a/chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/ResourceProgressEvent.h
@@ -42,20 +42,22 @@ namespace WebCore {
// (and translate in the case of PNaCl) multiple binary files. It is not
// constructable by web content at all, and so does not provide the usual
// EventInit pattern for Event construction.
-class ResourceProgressEvent : public ProgressEvent {
+class ResourceProgressEvent FINAL : public ProgressEvent {
public:
- static PassRefPtr<ResourceProgressEvent> create()
+ static PassRefPtrWillBeRawPtr<ResourceProgressEvent> create()
{
- return adoptRef(new ResourceProgressEvent);
+ return adoptRefWillBeNoop(new ResourceProgressEvent);
}
- static PassRefPtr<ResourceProgressEvent> create(const AtomicString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const String& url)
+ static PassRefPtrWillBeRawPtr<ResourceProgressEvent> create(const AtomicString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const String& url)
{
- return adoptRef(new ResourceProgressEvent(type, lengthComputable, loaded, total, url));
+ return adoptRefWillBeNoop(new ResourceProgressEvent(type, lengthComputable, loaded, total, url));
}
const String& url() const;
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
protected:
ResourceProgressEvent();
diff --git a/chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.cpp b/chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.cpp
index 459816941b0..04a6aa02864 100644
--- a/chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.cpp
@@ -59,7 +59,7 @@ void ScopedEventQueue::initialize()
s_instance = instance.leakPtr();
}
-void ScopedEventQueue::enqueueEventDispatchMediator(PassRefPtr<EventDispatchMediator> mediator)
+void ScopedEventQueue::enqueueEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator> mediator)
{
if (m_scopingLevel)
m_queuedEventDispatchMediators.append(mediator);
@@ -69,14 +69,14 @@ void ScopedEventQueue::enqueueEventDispatchMediator(PassRefPtr<EventDispatchMedi
void ScopedEventQueue::dispatchAllEvents()
{
- Vector<RefPtr<EventDispatchMediator> > queuedEventDispatchMediators;
+ WillBeHeapVector<RefPtrWillBeMember<EventDispatchMediator> > queuedEventDispatchMediators;
queuedEventDispatchMediators.swap(m_queuedEventDispatchMediators);
for (size_t i = 0; i < queuedEventDispatchMediators.size(); i++)
dispatchEvent(queuedEventDispatchMediators[i].release());
}
-void ScopedEventQueue::dispatchEvent(PassRefPtr<EventDispatchMediator> mediator) const
+void ScopedEventQueue::dispatchEvent(PassRefPtrWillBeRawPtr<EventDispatchMediator> mediator) const
{
ASSERT(mediator->event()->target());
Node* node = mediator->event()->target()->toNode();
diff --git a/chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.h b/chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.h
index 4f3c928cb70..1e92d5308f4 100644
--- a/chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.h
+++ b/chromium/third_party/WebKit/Source/core/events/ScopedEventQueue.h
@@ -31,6 +31,7 @@
#ifndef ScopedEventQueue_h
#define ScopedEventQueue_h
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -45,7 +46,7 @@ class ScopedEventQueue {
public:
~ScopedEventQueue();
- void enqueueEventDispatchMediator(PassRefPtr<EventDispatchMediator>);
+ void enqueueEventDispatchMediator(PassRefPtrWillBeRawPtr<EventDispatchMediator>);
void dispatchAllEvents();
static ScopedEventQueue* instance();
@@ -55,9 +56,9 @@ public:
private:
ScopedEventQueue();
static void initialize();
- void dispatchEvent(PassRefPtr<EventDispatchMediator>) const;
+ void dispatchEvent(PassRefPtrWillBeRawPtr<EventDispatchMediator>) const;
- Vector<RefPtr<EventDispatchMediator> > m_queuedEventDispatchMediators;
+ WillBePersistentHeapVector<RefPtrWillBeMember<EventDispatchMediator> > m_queuedEventDispatchMediators;
unsigned m_scopingLevel;
static ScopedEventQueue* s_instance;
diff --git a/chromium/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.h b/chromium/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.h
index cc88d03875e..e35bb757f0d 100644
--- a/chromium/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/SecurityPolicyViolationEvent.h
@@ -26,7 +26,6 @@
#define SecurityPolicyViolationEvent_h
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
@@ -47,16 +46,16 @@ struct SecurityPolicyViolationEventInit : public EventInit {
int statusCode;
};
-class SecurityPolicyViolationEvent : public Event {
+class SecurityPolicyViolationEvent FINAL : public Event {
public:
- static PassRefPtr<SecurityPolicyViolationEvent> create()
+ static PassRefPtrWillBeRawPtr<SecurityPolicyViolationEvent> create()
{
- return adoptRef(new SecurityPolicyViolationEvent());
+ return adoptRefWillBeNoop(new SecurityPolicyViolationEvent());
}
- static PassRefPtr<SecurityPolicyViolationEvent> create(const AtomicString& type, const SecurityPolicyViolationEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<SecurityPolicyViolationEvent> create(const AtomicString& type, const SecurityPolicyViolationEventInit& initializer)
{
- return adoptRef(new SecurityPolicyViolationEvent(type, initializer));
+ return adoptRefWillBeNoop(new SecurityPolicyViolationEvent(type, initializer));
}
const String& documentURI() const { return m_documentURI; }
@@ -70,7 +69,9 @@ public:
int columnNumber() const { return m_columnNumber; }
int statusCode() const { return m_statusCode; }
- virtual const AtomicString& interfaceName() const { return EventNames::SecurityPolicyViolationEvent; }
+ virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::SecurityPolicyViolationEvent; }
+
+ virtual void trace(Visitor* visitor) OVERRIDE { Event::trace(visitor); }
private:
SecurityPolicyViolationEvent()
diff --git a/chromium/third_party/WebKit/Source/core/events/TextEvent.cpp b/chromium/third_party/WebKit/Source/core/events/TextEvent.cpp
index 2ed8274e580..6b014ce070d 100644
--- a/chromium/third_party/WebKit/Source/core/events/TextEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/TextEvent.cpp
@@ -31,29 +31,29 @@
namespace WebCore {
-PassRefPtr<TextEvent> TextEvent::create()
+PassRefPtrWillBeRawPtr<TextEvent> TextEvent::create()
{
- return adoptRef(new TextEvent);
+ return adoptRefWillBeNoop(new TextEvent);
}
-PassRefPtr<TextEvent> TextEvent::create(PassRefPtr<AbstractView> view, const String& data, TextEventInputType inputType)
+PassRefPtrWillBeRawPtr<TextEvent> TextEvent::create(PassRefPtrWillBeRawPtr<AbstractView> view, const String& data, TextEventInputType inputType)
{
- return adoptRef(new TextEvent(view, data, inputType));
+ return adoptRefWillBeNoop(new TextEvent(view, data, inputType));
}
-PassRefPtr<TextEvent> TextEvent::createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace)
+PassRefPtrWillBeRawPtr<TextEvent> TextEvent::createForPlainTextPaste(PassRefPtrWillBeRawPtr<AbstractView> view, const String& data, bool shouldSmartReplace)
{
- return adoptRef(new TextEvent(view, data, 0, shouldSmartReplace, false));
+ return adoptRefWillBeNoop(new TextEvent(view, data, nullptr, shouldSmartReplace, false));
}
-PassRefPtr<TextEvent> TextEvent::createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle)
+PassRefPtrWillBeRawPtr<TextEvent> TextEvent::createForFragmentPaste(PassRefPtrWillBeRawPtr<AbstractView> view, PassRefPtrWillBeRawPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle)
{
- return adoptRef(new TextEvent(view, "", data, shouldSmartReplace, shouldMatchStyle));
+ return adoptRefWillBeNoop(new TextEvent(view, "", data, shouldSmartReplace, shouldMatchStyle));
}
-PassRefPtr<TextEvent> TextEvent::createForDrop(PassRefPtr<AbstractView> view, const String& data)
+PassRefPtrWillBeRawPtr<TextEvent> TextEvent::createForDrop(PassRefPtrWillBeRawPtr<AbstractView> view, const String& data)
{
- return adoptRef(new TextEvent(view, data, TextEventInputDrop));
+ return adoptRefWillBeNoop(new TextEvent(view, data, TextEventInputDrop));
}
TextEvent::TextEvent()
@@ -64,18 +64,18 @@ TextEvent::TextEvent()
ScriptWrappable::init(this);
}
-TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data, TextEventInputType inputType)
+TextEvent::TextEvent(PassRefPtrWillBeRawPtr<AbstractView> view, const String& data, TextEventInputType inputType)
: UIEvent(EventTypeNames::textInput, true, true, view, 0)
, m_inputType(inputType)
, m_data(data)
- , m_pastingFragment(0)
+ , m_pastingFragment(nullptr)
, m_shouldSmartReplace(false)
, m_shouldMatchStyle(false)
{
ScriptWrappable::init(this);
}
-TextEvent::TextEvent(PassRefPtr<AbstractView> view, const String& data, PassRefPtr<DocumentFragment> pastingFragment,
+TextEvent::TextEvent(PassRefPtrWillBeRawPtr<AbstractView> view, const String& data, PassRefPtrWillBeRawPtr<DocumentFragment> pastingFragment,
bool shouldSmartReplace, bool shouldMatchStyle)
: UIEvent(EventTypeNames::textInput, true, true, view, 0)
, m_inputType(TextEventInputPaste)
@@ -91,7 +91,7 @@ TextEvent::~TextEvent()
{
}
-void TextEvent::initTextEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view, const String& data)
+void TextEvent::initTextEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view, const String& data)
{
if (dispatched())
return;
@@ -106,4 +106,10 @@ const AtomicString& TextEvent::interfaceName() const
return EventNames::TextEvent;
}
+void TextEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_pastingFragment);
+ UIEvent::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/TextEvent.h b/chromium/third_party/WebKit/Source/core/events/TextEvent.h
index 6c2f256cf14..fd15dcde25a 100644
--- a/chromium/third_party/WebKit/Source/core/events/TextEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/TextEvent.h
@@ -28,33 +28,31 @@
#define TextEvent_h
#include "core/events/TextEventInputType.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/UIEvent.h"
namespace WebCore {
class DocumentFragment;
- class TextEvent : public UIEvent {
+ class TextEvent FINAL : public UIEvent {
public:
- static PassRefPtr<TextEvent> create();
- static PassRefPtr<TextEvent> create(PassRefPtr<AbstractView>, const String& data, TextEventInputType = TextEventInputKeyboard);
- static PassRefPtr<TextEvent> createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace);
- static PassRefPtr<TextEvent> createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle);
- static PassRefPtr<TextEvent> createForDrop(PassRefPtr<AbstractView> view, const String& data);
+ static PassRefPtrWillBeRawPtr<TextEvent> create();
+ static PassRefPtrWillBeRawPtr<TextEvent> create(PassRefPtrWillBeRawPtr<AbstractView>, const String& data, TextEventInputType = TextEventInputKeyboard);
+ static PassRefPtrWillBeRawPtr<TextEvent> createForPlainTextPaste(PassRefPtrWillBeRawPtr<AbstractView>, const String& data, bool shouldSmartReplace);
+ static PassRefPtrWillBeRawPtr<TextEvent> createForFragmentPaste(PassRefPtrWillBeRawPtr<AbstractView>, PassRefPtrWillBeRawPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle);
+ static PassRefPtrWillBeRawPtr<TextEvent> createForDrop(PassRefPtrWillBeRawPtr<AbstractView>, const String& data);
virtual ~TextEvent();
- void initTextEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, const String& data);
+ void initTextEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>, const String& data);
String data() const { return m_data; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
bool isLineBreak() const { return m_inputType == TextEventInputLineBreak; }
bool isComposition() const { return m_inputType == TextEventInputComposition; }
- bool isBackTab() const { return m_inputType == TextEventInputBackTab; }
bool isPaste() const { return m_inputType == TextEventInputPaste; }
bool isDrop() const { return m_inputType == TextEventInputDrop; }
@@ -62,17 +60,19 @@ namespace WebCore {
bool shouldMatchStyle() const { return m_shouldMatchStyle; }
DocumentFragment* pastingFragment() const { return m_pastingFragment.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
TextEvent();
- TextEvent(PassRefPtr<AbstractView>, const String& data, TextEventInputType = TextEventInputKeyboard);
- TextEvent(PassRefPtr<AbstractView>, const String& data, PassRefPtr<DocumentFragment>,
+ TextEvent(PassRefPtrWillBeRawPtr<AbstractView>, const String& data, TextEventInputType = TextEventInputKeyboard);
+ TextEvent(PassRefPtrWillBeRawPtr<AbstractView>, const String& data, PassRefPtrWillBeRawPtr<DocumentFragment>,
bool shouldSmartReplace, bool shouldMatchStyle);
TextEventInputType m_inputType;
String m_data;
- RefPtr<DocumentFragment> m_pastingFragment;
+ RefPtrWillBeMember<DocumentFragment> m_pastingFragment;
bool m_shouldSmartReplace;
bool m_shouldMatchStyle;
};
diff --git a/chromium/third_party/WebKit/Source/core/events/ThreadLocalEventNames.h b/chromium/third_party/WebKit/Source/core/events/ThreadLocalEventNames.h
index efde7b6d451..fea7908a633 100644
--- a/chromium/third_party/WebKit/Source/core/events/ThreadLocalEventNames.h
+++ b/chromium/third_party/WebKit/Source/core/events/ThreadLocalEventNames.h
@@ -22,11 +22,11 @@
#ifndef ThreadLocalEventNames_h
#define ThreadLocalEventNames_h
-#include "EventInterfaces.h"
-#include "EventNames.h"
-#include "EventTargetInterfaces.h"
-#include "EventTargetNames.h"
-#include "EventTypeNames.h"
+#include "core/EventInterfaces.h"
+#include "core/EventNames.h"
+#include "core/EventTargetInterfaces.h"
+#include "core/EventTargetNames.h"
+#include "core/EventTypeNames.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/events/TouchEvent.cpp b/chromium/third_party/WebKit/Source/core/events/TouchEvent.cpp
index f0527eda7f4..d65bfe11478 100644
--- a/chromium/third_party/WebKit/Source/core/events/TouchEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/TouchEvent.cpp
@@ -29,8 +29,8 @@
#include "core/events/TouchEvent.h"
#include "core/events/EventDispatcher.h"
-#include "core/events/EventRetargeter.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
@@ -41,11 +41,9 @@ TouchEvent::TouchEvent()
TouchEvent::TouchEvent(TouchList* touches, TouchList* targetTouches,
TouchList* changedTouches, const AtomicString& type,
- PassRefPtr<AbstractView> view, int screenX, int screenY, int pageX, int pageY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
- : MouseRelatedEvent(type, true, true, view, 0, IntPoint(screenX, screenY),
- IntPoint(pageX, pageY),
- IntPoint(0, 0),
+ PassRefPtrWillBeRawPtr<AbstractView> view,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool cancelable)
+ : UIEventWithKeyState(type, true, cancelable, view, 0,
ctrlKey, altKey, shiftKey, metaKey)
, m_touches(touches)
, m_targetTouches(targetTouches)
@@ -60,23 +58,26 @@ TouchEvent::~TouchEvent()
void TouchEvent::initTouchEvent(TouchList* touches, TouchList* targetTouches,
TouchList* changedTouches, const AtomicString& type,
- PassRefPtr<AbstractView> view, int screenX, int screenY, int clientX, int clientY,
+ PassRefPtrWillBeRawPtr<AbstractView> view,
+ int, int, int, int,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
{
if (dispatched())
return;
- initUIEvent(type, true, true, view, 0);
+ bool cancelable = true;
+ if (type == EventTypeNames::touchcancel)
+ cancelable = false;
+
+ initUIEvent(type, true, cancelable, view, 0);
m_touches = touches;
m_targetTouches = targetTouches;
m_changedTouches = changedTouches;
- m_screenLocation = IntPoint(screenX, screenY);
m_ctrlKey = ctrlKey;
m_altKey = altKey;
m_shiftKey = shiftKey;
m_metaKey = metaKey;
- initCoordinates(IntPoint(clientX, clientY));
}
const AtomicString& TouchEvent::interfaceName() const
@@ -89,12 +90,32 @@ bool TouchEvent::isTouchEvent() const
return true;
}
-PassRefPtr<TouchEventDispatchMediator> TouchEventDispatchMediator::create(PassRefPtr<TouchEvent> touchEvent)
+void TouchEvent::preventDefault()
+{
+ UIEventWithKeyState::preventDefault();
+
+ // A common developer error is to wait too long before attempting to stop
+ // scrolling by consuming a touchmove event. Generate a warning if this
+ // event is uncancelable.
+ if (!cancelable() && view() && view()->frame()) {
+ view()->frame()->console().addMessage(JSMessageSource, WarningMessageLevel,
+ "Ignored attempt to cancel a " + type() + " event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.");
+ }
+}
+void TouchEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_touches);
+ visitor->trace(m_targetTouches);
+ visitor->trace(m_changedTouches);
+ UIEventWithKeyState::trace(visitor);
+}
+
+PassRefPtrWillBeRawPtr<TouchEventDispatchMediator> TouchEventDispatchMediator::create(PassRefPtrWillBeRawPtr<TouchEvent> touchEvent)
{
- return adoptRef(new TouchEventDispatchMediator(touchEvent));
+ return adoptRefWillBeNoop(new TouchEventDispatchMediator(touchEvent));
}
-TouchEventDispatchMediator::TouchEventDispatchMediator(PassRefPtr<TouchEvent> touchEvent)
+TouchEventDispatchMediator::TouchEventDispatchMediator(PassRefPtrWillBeRawPtr<TouchEvent> touchEvent)
: EventDispatchMediator(touchEvent)
{
}
@@ -106,7 +127,7 @@ TouchEvent* TouchEventDispatchMediator::event() const
bool TouchEventDispatchMediator::dispatchEvent(EventDispatcher* dispatcher) const
{
- EventRetargeter::adjustForTouchEvent(dispatcher->node(), *event());
+ event()->eventPath().adjustForTouchEvent(dispatcher->node(), *event());
return dispatcher->dispatch();
}
diff --git a/chromium/third_party/WebKit/Source/core/events/TouchEvent.h b/chromium/third_party/WebKit/Source/core/events/TouchEvent.h
index 25c6f610c63..9659c98d510 100644
--- a/chromium/third_party/WebKit/Source/core/events/TouchEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/TouchEvent.h
@@ -33,62 +33,63 @@
namespace WebCore {
-class TouchEvent : public MouseRelatedEvent {
+class TouchEvent FINAL : public UIEventWithKeyState {
public:
virtual ~TouchEvent();
- static PassRefPtr<TouchEvent> create()
+ static PassRefPtrWillBeRawPtr<TouchEvent> create()
{
- return adoptRef(new TouchEvent);
+ return adoptRefWillBeNoop(new TouchEvent);
}
- static PassRefPtr<TouchEvent> create(TouchList* touches,
- TouchList* targetTouches, TouchList* changedTouches,
- const AtomicString& type, PassRefPtr<AbstractView> view,
- int screenX, int screenY, int pageX, int pageY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
+ static PassRefPtrWillBeRawPtr<TouchEvent> create(TouchList* touches,
+ TouchList* targetTouches, TouchList* changedTouches,
+ const AtomicString& type, PassRefPtrWillBeRawPtr<AbstractView> view,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool cancelable)
{
- return adoptRef(new TouchEvent(touches, targetTouches, changedTouches,
- type, view, screenX, screenY, pageX, pageY,
- ctrlKey, altKey, shiftKey, metaKey));
+ return adoptRefWillBeNoop(new TouchEvent(touches, targetTouches, changedTouches, type, view,
+ ctrlKey, altKey, shiftKey, metaKey, cancelable));
}
void initTouchEvent(TouchList* touches, TouchList* targetTouches,
- TouchList* changedTouches, const AtomicString& type,
- PassRefPtr<AbstractView> view, int screenX, int screenY,
- int clientX, int clientY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
+ TouchList* changedTouches, const AtomicString& type,
+ PassRefPtrWillBeRawPtr<AbstractView>,
+ int, int, int, int, // unused useless members of web exposed API
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
TouchList* touches() const { return m_touches.get(); }
TouchList* targetTouches() const { return m_targetTouches.get(); }
TouchList* changedTouches() const { return m_changedTouches.get(); }
- void setTouches(PassRefPtr<TouchList> touches) { m_touches = touches; }
- void setTargetTouches(PassRefPtr<TouchList> targetTouches) { m_targetTouches = targetTouches; }
- void setChangedTouches(PassRefPtr<TouchList> changedTouches) { m_changedTouches = changedTouches; }
+ void setTouches(PassRefPtrWillBeRawPtr<TouchList> touches) { m_touches = touches; }
+ void setTargetTouches(PassRefPtrWillBeRawPtr<TouchList> targetTouches) { m_targetTouches = targetTouches; }
+ void setChangedTouches(PassRefPtrWillBeRawPtr<TouchList> changedTouches) { m_changedTouches = changedTouches; }
virtual bool isTouchEvent() const OVERRIDE;
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void preventDefault() OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
TouchEvent();
TouchEvent(TouchList* touches, TouchList* targetTouches,
TouchList* changedTouches, const AtomicString& type,
- PassRefPtr<AbstractView>, int screenX, int screenY, int pageX,
- int pageY,
- bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
+ PassRefPtrWillBeRawPtr<AbstractView>,
+ bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool cancelable);
- RefPtr<TouchList> m_touches;
- RefPtr<TouchList> m_targetTouches;
- RefPtr<TouchList> m_changedTouches;
+ RefPtrWillBeMember<TouchList> m_touches;
+ RefPtrWillBeMember<TouchList> m_targetTouches;
+ RefPtrWillBeMember<TouchList> m_changedTouches;
};
-class TouchEventDispatchMediator : public EventDispatchMediator {
+class TouchEventDispatchMediator FINAL : public EventDispatchMediator {
public:
- static PassRefPtr<TouchEventDispatchMediator> create(PassRefPtr<TouchEvent>);
+ static PassRefPtrWillBeRawPtr<TouchEventDispatchMediator> create(PassRefPtrWillBeRawPtr<TouchEvent>);
private:
- explicit TouchEventDispatchMediator(PassRefPtr<TouchEvent>);
+ explicit TouchEventDispatchMediator(PassRefPtrWillBeRawPtr<TouchEvent>);
TouchEvent* event() const;
virtual bool dispatchEvent(EventDispatcher*) const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/events/TouchEvent.idl b/chromium/third_party/WebKit/Source/core/events/TouchEvent.idl
index f4b396e01f1..36f0ac54e64 100644
--- a/chromium/third_party/WebKit/Source/core/events/TouchEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/events/TouchEvent.idl
@@ -36,10 +36,10 @@ interface TouchEvent : UIEvent {
[Default=Undefined] optional TouchList changedTouches,
[Default=Undefined] optional DOMString type,
[Default=Undefined] optional Window view,
- [Default=Undefined] optional long screenX,
- [Default=Undefined] optional long screenY,
- [Default=Undefined] optional long clientX,
- [Default=Undefined] optional long clientY,
+ [Default=Undefined] optional long unused1,
+ [Default=Undefined] optional long unused2,
+ [Default=Undefined] optional long unused3,
+ [Default=Undefined] optional long unused4,
[Default=Undefined] optional boolean ctrlKey,
[Default=Undefined] optional boolean altKey,
[Default=Undefined] optional boolean shiftKey,
diff --git a/chromium/third_party/WebKit/Source/core/events/TouchEventContext.cpp b/chromium/third_party/WebKit/Source/core/events/TouchEventContext.cpp
new file mode 100644
index 00000000000..c95ba8bf7d2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/TouchEventContext.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "core/events/TouchEventContext.h"
+
+#include "core/dom/TouchList.h"
+#include "core/events/Event.h"
+#include "core/events/TouchEvent.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<TouchEventContext> TouchEventContext::create()
+{
+ return adoptRefWillBeNoop(new TouchEventContext);
+}
+
+TouchEventContext::TouchEventContext()
+ : m_touches(TouchList::create())
+ , m_targetTouches(TouchList::create())
+ , m_changedTouches(TouchList::create())
+{
+}
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(TouchEventContext)
+
+void TouchEventContext::handleLocalEvents(Event* event) const
+{
+ ASSERT(event->isTouchEvent());
+ TouchEvent* touchEvent = toTouchEvent(event);
+ touchEvent->setTouches(m_touches);
+ touchEvent->setTargetTouches(m_targetTouches);
+ touchEvent->setChangedTouches(m_changedTouches);
+}
+
+void TouchEventContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_touches);
+ visitor->trace(m_targetTouches);
+ visitor->trace(m_changedTouches);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/events/TouchEventContext.h b/chromium/third_party/WebKit/Source/core/events/TouchEventContext.h
new file mode 100644
index 00000000000..c5044cfa04c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/TouchEventContext.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TouchEventContext_h
+#define TouchEventContext_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class Event;
+class TouchList;
+
+class TouchEventContext : public RefCountedWillBeGarbageCollected<TouchEventContext> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(TouchEventContext);
+public:
+ static PassRefPtrWillBeRawPtr<TouchEventContext> create();
+ void handleLocalEvents(Event*) const;
+ TouchList& touches() { return *m_touches; }
+ TouchList& targetTouches() { return *m_targetTouches; }
+ TouchList& changedTouches() { return *m_changedTouches; }
+
+ void trace(Visitor*);
+
+private:
+ TouchEventContext();
+
+ RefPtrWillBeMember<TouchList> m_touches;
+ RefPtrWillBeMember<TouchList> m_targetTouches;
+ RefPtrWillBeMember<TouchList> m_changedTouches;
+};
+
+}
+
+#endif // TouchEventContext_h
diff --git a/chromium/third_party/WebKit/Source/core/events/TransitionEvent.cpp b/chromium/third_party/WebKit/Source/core/events/TransitionEvent.cpp
index dfc32fd33e1..074d7e04057 100644
--- a/chromium/third_party/WebKit/Source/core/events/TransitionEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/TransitionEvent.cpp
@@ -27,8 +27,6 @@
#include "config.h"
#include "core/events/TransitionEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
TransitionEventInit::TransitionEventInit()
@@ -84,4 +82,9 @@ const AtomicString& TransitionEvent::interfaceName() const
return EventNames::TransitionEvent;
}
+void TransitionEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/TransitionEvent.h b/chromium/third_party/WebKit/Source/core/events/TransitionEvent.h
index e1d5fa26082..5c781a8ef41 100644
--- a/chromium/third_party/WebKit/Source/core/events/TransitionEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/TransitionEvent.h
@@ -39,19 +39,19 @@ struct TransitionEventInit : public EventInit {
String pseudoElement;
};
-class TransitionEvent : public Event {
+class TransitionEvent FINAL : public Event {
public:
- static PassRefPtr<TransitionEvent> create()
+ static PassRefPtrWillBeRawPtr<TransitionEvent> create()
{
- return adoptRef(new TransitionEvent);
+ return adoptRefWillBeNoop(new TransitionEvent);
}
- static PassRefPtr<TransitionEvent> create(const AtomicString& type, const String& propertyName, double elapsedTime, const String& pseudoElement)
+ static PassRefPtrWillBeRawPtr<TransitionEvent> create(const AtomicString& type, const String& propertyName, double elapsedTime, const String& pseudoElement)
{
- return adoptRef(new TransitionEvent(type, propertyName, elapsedTime, pseudoElement));
+ return adoptRefWillBeNoop(new TransitionEvent(type, propertyName, elapsedTime, pseudoElement));
}
- static PassRefPtr<TransitionEvent> create(const AtomicString& type, const TransitionEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<TransitionEvent> create(const AtomicString& type, const TransitionEventInit& initializer)
{
- return adoptRef(new TransitionEvent(type, initializer));
+ return adoptRefWillBeNoop(new TransitionEvent(type, initializer));
}
virtual ~TransitionEvent();
@@ -60,7 +60,9 @@ public:
double elapsedTime() const;
const String& pseudoElement() const;
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
TransitionEvent();
diff --git a/chromium/third_party/WebKit/Source/core/events/TreeScopeEventContext.cpp b/chromium/third_party/WebKit/Source/core/events/TreeScopeEventContext.cpp
new file mode 100644
index 00000000000..a332552d9b2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/TreeScopeEventContext.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "core/events/TreeScopeEventContext.h"
+
+#include "core/dom/StaticNodeList.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/events/EventPath.h"
+#include "core/events/TouchEventContext.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<StaticNodeList> TreeScopeEventContext::ensureEventPath(EventPath& path)
+{
+ if (m_eventPath)
+ return m_eventPath;
+
+ WillBeHeapVector<RefPtrWillBeMember<Node> > nodes;
+ nodes.reserveInitialCapacity(path.size());
+ for (size_t i = 0; i < path.size(); ++i) {
+ TreeScope& treeScope = path[i].treeScopeEventContext().treeScope();
+ if (treeScope.rootNode().isShadowRoot() && toShadowRoot(treeScope).type() == ShadowRoot::AuthorShadowRoot)
+ nodes.append(path[i].node());
+ else if (path[i].treeScopeEventContext().isInclusiveAncestorOf(*this))
+ nodes.append(path[i].node());
+ }
+ m_eventPath = StaticNodeList::adopt(nodes);
+ return m_eventPath;
+}
+
+TouchEventContext* TreeScopeEventContext::ensureTouchEventContext()
+{
+ if (!m_touchEventContext)
+ m_touchEventContext = TouchEventContext::create();
+ return m_touchEventContext.get();
+}
+
+PassRefPtrWillBeRawPtr<TreeScopeEventContext> TreeScopeEventContext::create(TreeScope& treeScope)
+{
+ return adoptRefWillBeNoop(new TreeScopeEventContext(treeScope));
+}
+
+TreeScopeEventContext::TreeScopeEventContext(TreeScope& treeScope)
+ : m_treeScope(treeScope)
+ , m_preOrder(-1)
+ , m_postOrder(-1)
+{
+}
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(TreeScopeEventContext)
+
+void TreeScopeEventContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_treeScope);
+ visitor->trace(m_target);
+ visitor->trace(m_relatedTarget);
+ visitor->trace(m_eventPath);
+ visitor->trace(m_touchEventContext);
+#if ENABLE(OILPAN)
+ visitor->trace(m_children);
+#endif
+}
+
+int TreeScopeEventContext::calculatePrePostOrderNumber(int orderNumber)
+{
+ m_preOrder = orderNumber;
+ for (size_t i = 0; i < m_children.size(); ++i)
+ orderNumber = m_children[i]->calculatePrePostOrderNumber(orderNumber + 1);
+ m_postOrder = orderNumber + 1;
+ return orderNumber + 1;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/events/TreeScopeEventContext.h b/chromium/third_party/WebKit/Source/core/events/TreeScopeEventContext.h
new file mode 100644
index 00000000000..141dff94757
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/events/TreeScopeEventContext.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TreeScopeEventContext_h
+#define TreeScopeEventContext_h
+
+#include "core/dom/Node.h"
+#include "core/dom/TreeScope.h"
+#include "core/events/EventTarget.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class EventPath;
+class EventTarget;
+class Node;
+class StaticNodeList;
+class TouchEventContext;
+class TreeScope;
+
+class TreeScopeEventContext FINAL : public RefCountedWillBeGarbageCollected<TreeScopeEventContext> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(TreeScopeEventContext);
+public:
+ static PassRefPtrWillBeRawPtr<TreeScopeEventContext> create(TreeScope&);
+ void trace(Visitor*);
+
+ TreeScope& treeScope() const { return *m_treeScope; }
+
+ EventTarget* target() const { return m_target.get(); }
+ void setTarget(PassRefPtrWillBeRawPtr<EventTarget>);
+
+ EventTarget* relatedTarget() const { return m_relatedTarget.get(); }
+ void setRelatedTarget(PassRefPtrWillBeRawPtr<EventTarget>);
+
+ TouchEventContext* touchEventContext() const { return m_touchEventContext.get(); }
+ TouchEventContext* ensureTouchEventContext();
+
+ PassRefPtrWillBeRawPtr<StaticNodeList> ensureEventPath(EventPath&);
+
+ bool isInclusiveAncestorOf(const TreeScopeEventContext&);
+ void addChild(TreeScopeEventContext& child) { m_children.append(&child); }
+
+ // For ancestor-descendant relationship check in Q(1).
+ // Preprocessing takes O(N).
+ int calculatePrePostOrderNumber(int orderNumber);
+
+private:
+ TreeScopeEventContext(TreeScope&);
+
+#ifndef NDEBUG
+ bool isUnreachableNode(EventTarget&);
+#endif
+
+ RawPtrWillBeMember<TreeScope> m_treeScope;
+ RefPtrWillBeMember<EventTarget> m_target;
+ RefPtrWillBeMember<EventTarget> m_relatedTarget;
+ RefPtrWillBeMember<StaticNodeList> m_eventPath;
+ RefPtrWillBeMember<TouchEventContext> m_touchEventContext;
+
+ WillBeHeapVector<RawPtrWillBeMember<TreeScopeEventContext> > m_children;
+ int m_preOrder;
+ int m_postOrder;
+};
+
+#ifndef NDEBUG
+inline bool TreeScopeEventContext::isUnreachableNode(EventTarget& target)
+{
+ // FIXME: Checks also for SVG elements.
+ return target.toNode() && !target.toNode()->isSVGElement() && !target.toNode()->treeScope().isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(treeScope());
+}
+#endif
+
+inline void TreeScopeEventContext::setTarget(PassRefPtrWillBeRawPtr<EventTarget> target)
+{
+ ASSERT(target);
+ ASSERT(!isUnreachableNode(*target));
+ m_target = target;
+}
+
+inline void TreeScopeEventContext::setRelatedTarget(PassRefPtrWillBeRawPtr<EventTarget> relatedTarget)
+{
+ ASSERT(relatedTarget);
+ ASSERT(!isUnreachableNode(*relatedTarget));
+ m_relatedTarget = relatedTarget;
+}
+
+inline bool TreeScopeEventContext::isInclusiveAncestorOf(const TreeScopeEventContext& other)
+{
+ ASSERT(m_preOrder != -1 && m_postOrder != -1 && other.m_preOrder != -1 && other.m_postOrder != -1);
+ return m_preOrder <= other.m_preOrder && other.m_postOrder <= m_postOrder;
+}
+
+}
+
+#endif // TreeScopeEventContext_h
diff --git a/chromium/third_party/WebKit/Source/core/events/UIEvent.cpp b/chromium/third_party/WebKit/Source/core/events/UIEvent.cpp
index 6a0db63dac8..ba85c8185a8 100644
--- a/chromium/third_party/WebKit/Source/core/events/UIEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/UIEvent.cpp
@@ -27,7 +27,7 @@
namespace WebCore {
UIEventInit::UIEventInit()
- : view(0)
+ : view(nullptr)
, detail(0)
{
}
@@ -38,7 +38,7 @@ UIEvent::UIEvent()
ScriptWrappable::init(this);
}
-UIEvent::UIEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, PassRefPtr<AbstractView> viewArg, int detailArg)
+UIEvent::UIEvent(const AtomicString& eventType, bool canBubbleArg, bool cancelableArg, PassRefPtrWillBeRawPtr<AbstractView> viewArg, int detailArg)
: Event(eventType, canBubbleArg, cancelableArg)
, m_view(viewArg)
, m_detail(detailArg)
@@ -58,7 +58,7 @@ UIEvent::~UIEvent()
{
}
-void UIEvent::initUIEvent(const AtomicString& typeArg, bool canBubbleArg, bool cancelableArg, PassRefPtr<AbstractView> viewArg, int detailArg)
+void UIEvent::initUIEvent(const AtomicString& typeArg, bool canBubbleArg, bool cancelableArg, PassRefPtrWillBeRawPtr<AbstractView> viewArg, int detailArg)
{
if (dispatched())
return;
@@ -114,4 +114,10 @@ int UIEvent::which() const
return 0;
}
+void UIEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_view);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/UIEvent.h b/chromium/third_party/WebKit/Source/core/events/UIEvent.h
index 27503311307..48935975ab0 100644
--- a/chromium/third_party/WebKit/Source/core/events/UIEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/UIEvent.h
@@ -26,43 +26,43 @@
#include "core/events/Event.h"
#include "core/events/EventDispatchMediator.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
namespace WebCore {
-typedef DOMWindow AbstractView;
+typedef LocalDOMWindow AbstractView;
struct UIEventInit : public EventInit {
UIEventInit();
- RefPtr<AbstractView> view;
+ RefPtrWillBeMember<AbstractView> view;
int detail;
};
class UIEvent : public Event {
public:
- static PassRefPtr<UIEvent> create()
+ static PassRefPtrWillBeRawPtr<UIEvent> create()
{
- return adoptRef(new UIEvent);
+ return adoptRefWillBeNoop(new UIEvent);
}
- static PassRefPtr<UIEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view, int detail)
+ static PassRefPtrWillBeRawPtr<UIEvent> create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view, int detail)
{
- return adoptRef(new UIEvent(type, canBubble, cancelable, view, detail));
+ return adoptRefWillBeNoop(new UIEvent(type, canBubble, cancelable, view, detail));
}
- static PassRefPtr<UIEvent> create(const AtomicString& type, const UIEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<UIEvent> create(const AtomicString& type, const UIEventInit& initializer)
{
- return adoptRef(new UIEvent(type, initializer));
+ return adoptRefWillBeNoop(new UIEvent(type, initializer));
}
virtual ~UIEvent();
- void initUIEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, int detail);
+ void initUIEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>, int detail);
AbstractView* view() const { return m_view.get(); }
AbstractView* view(bool& isNull) const { isNull = !m_view; return m_view.get(); }
int detail() const { return m_detail; }
- virtual const AtomicString& interfaceName() const;
- virtual bool isUIEvent() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+ virtual bool isUIEvent() const OVERRIDE FINAL;
virtual int keyCode() const;
virtual int charCode() const;
@@ -75,13 +75,15 @@ public:
virtual int which() const;
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
UIEvent();
- UIEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, int detail);
+ UIEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView>, int detail);
UIEvent(const AtomicString&, const UIEventInit&);
private:
- RefPtr<AbstractView> m_view;
+ RefPtrWillBeMember<AbstractView> m_view;
int m_detail;
};
diff --git a/chromium/third_party/WebKit/Source/core/events/UIEventWithKeyState.h b/chromium/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
index 29c8c190044..97e5094ad7a 100644
--- a/chromium/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
+++ b/chromium/third_party/WebKit/Source/core/events/UIEventWithKeyState.h
@@ -44,7 +44,7 @@ namespace WebCore {
{
}
- UIEventWithKeyState(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
+ UIEventWithKeyState(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<AbstractView> view,
int detail, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
: UIEvent(type, canBubble, cancelable, view, detail)
, m_ctrlKey(ctrlKey)
diff --git a/chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.cpp b/chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.cpp
index cefe08f766c..68064f3bbfb 100644
--- a/chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.cpp
@@ -26,8 +26,6 @@
#include "config.h"
#include "core/events/WebKitAnimationEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
WebKitAnimationEventInit::WebKitAnimationEventInit()
@@ -77,4 +75,9 @@ const AtomicString& WebKitAnimationEvent::interfaceName() const
return EventNames::WebKitAnimationEvent;
}
+void WebKitAnimationEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.h b/chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.h
index b91c98005bd..0ce4ed035b0 100644
--- a/chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/WebKitAnimationEvent.h
@@ -40,19 +40,19 @@ struct WebKitAnimationEventInit : public EventInit {
double elapsedTime;
};
-class WebKitAnimationEvent : public Event {
+class WebKitAnimationEvent FINAL : public Event {
public:
- static PassRefPtr<WebKitAnimationEvent> create()
+ static PassRefPtrWillBeRawPtr<WebKitAnimationEvent> create()
{
- return adoptRef(new WebKitAnimationEvent);
+ return adoptRefWillBeNoop(new WebKitAnimationEvent);
}
- static PassRefPtr<WebKitAnimationEvent> create(const AtomicString& type, const String& animationName, double elapsedTime)
+ static PassRefPtrWillBeRawPtr<WebKitAnimationEvent> create(const AtomicString& type, const String& animationName, double elapsedTime)
{
- return adoptRef(new WebKitAnimationEvent(type, animationName, elapsedTime));
+ return adoptRefWillBeNoop(new WebKitAnimationEvent(type, animationName, elapsedTime));
}
- static PassRefPtr<WebKitAnimationEvent> create(const AtomicString& type, const WebKitAnimationEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<WebKitAnimationEvent> create(const AtomicString& type, const WebKitAnimationEventInit& initializer)
{
- return adoptRef(new WebKitAnimationEvent(type, initializer));
+ return adoptRefWillBeNoop(new WebKitAnimationEvent(type, initializer));
}
virtual ~WebKitAnimationEvent();
@@ -60,7 +60,9 @@ public:
const String& animationName() const;
double elapsedTime() const;
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
WebKitAnimationEvent();
diff --git a/chromium/third_party/WebKit/Source/core/events/WheelEvent.cpp b/chromium/third_party/WebKit/Source/core/events/WheelEvent.cpp
index 0c23299b6fc..7a1e16e5f9b 100644
--- a/chromium/third_party/WebKit/Source/core/events/WheelEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/WheelEvent.cpp
@@ -24,8 +24,7 @@
#include "config.h"
#include "core/events/WheelEvent.h"
-#include "core/dom/Clipboard.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/clipboard/Clipboard.h"
#include "platform/PlatformWheelEvent.h"
namespace WebCore {
@@ -62,13 +61,13 @@ WheelEvent::WheelEvent(const AtomicString& type, const WheelEventInit& initializ
}
WheelEvent::WheelEvent(const FloatPoint& wheelTicks, const FloatPoint& rawDelta, unsigned deltaMode,
- PassRefPtr<AbstractView> view, const IntPoint& screenLocation, const IntPoint& pageLocation,
+ PassRefPtrWillBeRawPtr<AbstractView> view, const IntPoint& screenLocation, const IntPoint& pageLocation,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool directionInvertedFromDevice)
: MouseEvent(EventTypeNames::wheel,
true, true, view, 0, screenLocation.x(), screenLocation.y(),
pageLocation.x(), pageLocation.y(),
0, 0,
- ctrlKey, altKey, shiftKey, metaKey, 0, 0, 0, false)
+ ctrlKey, altKey, shiftKey, metaKey, 0, nullptr, nullptr, false)
, m_wheelDelta(wheelTicks.x() * TickMultiplier, wheelTicks.y() * TickMultiplier)
, m_deltaX(-rawDelta.x())
, m_deltaY(-rawDelta.y())
@@ -79,7 +78,7 @@ WheelEvent::WheelEvent(const FloatPoint& wheelTicks, const FloatPoint& rawDelta,
ScriptWrappable::init(this);
}
-void WheelEvent::initWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<AbstractView> view,
+void WheelEvent::initWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtrWillBeRawPtr<AbstractView> view,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
{
@@ -103,7 +102,7 @@ void WheelEvent::initWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<Abstrac
initCoordinates(IntPoint(pageX, pageY));
}
-void WheelEvent::initWebKitWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<AbstractView> view,
+void WheelEvent::initWebKitWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtrWillBeRawPtr<AbstractView> view,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
{
@@ -126,17 +125,22 @@ bool WheelEvent::isWheelEvent() const
return true;
}
+void WheelEvent::trace(Visitor* visitor)
+{
+ MouseEvent::trace(visitor);
+}
+
inline static unsigned deltaMode(const PlatformWheelEvent& event)
{
return event.granularity() == ScrollByPageWheelEvent ? WheelEvent::DOM_DELTA_PAGE : WheelEvent::DOM_DELTA_PIXEL;
}
-PassRefPtr<WheelEventDispatchMediator> WheelEventDispatchMediator::create(const PlatformWheelEvent& event, PassRefPtr<AbstractView> view)
+PassRefPtrWillBeRawPtr<WheelEventDispatchMediator> WheelEventDispatchMediator::create(const PlatformWheelEvent& event, PassRefPtrWillBeRawPtr<AbstractView> view)
{
- return adoptRef(new WheelEventDispatchMediator(event, view));
+ return adoptRefWillBeNoop(new WheelEventDispatchMediator(event, view));
}
-WheelEventDispatchMediator::WheelEventDispatchMediator(const PlatformWheelEvent& event, PassRefPtr<AbstractView> view)
+WheelEventDispatchMediator::WheelEventDispatchMediator(const PlatformWheelEvent& event, PassRefPtrWillBeRawPtr<AbstractView> view)
{
if (!(event.deltaX() || event.deltaY()))
return;
diff --git a/chromium/third_party/WebKit/Source/core/events/WheelEvent.h b/chromium/third_party/WebKit/Source/core/events/WheelEvent.h
index 6c8ea020cba..efe1c7572b2 100644
--- a/chromium/third_party/WebKit/Source/core/events/WheelEvent.h
+++ b/chromium/third_party/WebKit/Source/core/events/WheelEvent.h
@@ -44,7 +44,7 @@ struct WheelEventInit : public MouseEventInit {
unsigned deltaMode;
};
-class WheelEvent : public MouseEvent {
+class WheelEvent FINAL : public MouseEvent {
public:
enum { TickMultiplier = 120 };
@@ -54,30 +54,30 @@ public:
DOM_DELTA_PAGE
};
- static PassRefPtr<WheelEvent> create()
+ static PassRefPtrWillBeRawPtr<WheelEvent> create()
{
- return adoptRef(new WheelEvent);
+ return adoptRefWillBeNoop(new WheelEvent);
}
- static PassRefPtr<WheelEvent> create(const AtomicString& type, const WheelEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<WheelEvent> create(const AtomicString& type, const WheelEventInit& initializer)
{
- return adoptRef(new WheelEvent(type, initializer));
+ return adoptRefWillBeNoop(new WheelEvent(type, initializer));
}
- static PassRefPtr<WheelEvent> create(const FloatPoint& wheelTicks,
- const FloatPoint& rawDelta, unsigned deltaMode, PassRefPtr<AbstractView> view,
+ static PassRefPtrWillBeRawPtr<WheelEvent> create(const FloatPoint& wheelTicks,
+ const FloatPoint& rawDelta, unsigned deltaMode, PassRefPtrWillBeRawPtr<AbstractView> view,
const IntPoint& screenLocation, const IntPoint& pageLocation,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool directionInvertedFromDevice)
{
- return adoptRef(new WheelEvent(wheelTicks, rawDelta, deltaMode, view,
+ return adoptRefWillBeNoop(new WheelEvent(wheelTicks, rawDelta, deltaMode, view,
screenLocation, pageLocation, ctrlKey, altKey, shiftKey, metaKey, directionInvertedFromDevice));
}
- void initWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<AbstractView>,
+ void initWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtrWillBeRawPtr<AbstractView>,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
- void initWebKitWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtr<AbstractView>,
+ void initWebKitWheelEvent(int rawDeltaX, int rawDeltaY, PassRefPtrWillBeRawPtr<AbstractView>,
int screenX, int screenY, int pageX, int pageY,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
@@ -93,15 +93,17 @@ public:
bool webkitDirectionInvertedFromDevice() const { return m_directionInvertedFromDevice; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
virtual bool isMouseEvent() const OVERRIDE;
virtual bool isWheelEvent() const OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
WheelEvent();
WheelEvent(const AtomicString&, const WheelEventInit&);
WheelEvent(const FloatPoint& wheelTicks, const FloatPoint& rawDelta,
- unsigned, PassRefPtr<AbstractView>, const IntPoint& screenLocation, const IntPoint& pageLocation,
+ unsigned, PassRefPtrWillBeRawPtr<AbstractView>, const IntPoint& screenLocation, const IntPoint& pageLocation,
bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, bool directionInvertedFromDevice);
IntPoint m_wheelDelta;
@@ -114,11 +116,11 @@ private:
DEFINE_EVENT_TYPE_CASTS(WheelEvent);
-class WheelEventDispatchMediator : public EventDispatchMediator {
+class WheelEventDispatchMediator FINAL : public EventDispatchMediator {
public:
- static PassRefPtr<WheelEventDispatchMediator> create(const PlatformWheelEvent&, PassRefPtr<AbstractView>);
+ static PassRefPtrWillBeRawPtr<WheelEventDispatchMediator> create(const PlatformWheelEvent&, PassRefPtrWillBeRawPtr<AbstractView>);
private:
- WheelEventDispatchMediator(const PlatformWheelEvent&, PassRefPtr<AbstractView>);
+ WheelEventDispatchMediator(const PlatformWheelEvent&, PassRefPtrWillBeRawPtr<AbstractView>);
WheelEvent* event() const;
virtual bool dispatchEvent(EventDispatcher*) const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/events/WheelEvent.idl b/chromium/third_party/WebKit/Source/core/events/WheelEvent.idl
index 1cba713f668..6c7acff7177 100644
--- a/chromium/third_party/WebKit/Source/core/events/WheelEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/events/WheelEvent.idl
@@ -39,8 +39,10 @@
readonly attribute long wheelDelta;
// WebKit Extension
+ [MeasureAs=PrefixedWheelEventDirectionInvertedFromDevice]
readonly attribute boolean webkitDirectionInvertedFromDevice;
+ [MeasureAs=PrefixedWheelEventInit]
void initWebKitWheelEvent([Default=Undefined] optional long wheelDeltaX,
[Default=Undefined] optional long wheelDeltaY,
[Default=Undefined] optional Window view,
diff --git a/chromium/third_party/WebKit/Source/core/events/WindowEventContext.cpp b/chromium/third_party/WebKit/Source/core/events/WindowEventContext.cpp
index 673ef36f5c6..b48725fdbfe 100644
--- a/chromium/third_party/WebKit/Source/core/events/WindowEventContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/events/WindowEventContext.cpp
@@ -28,26 +28,26 @@
#include "core/events/WindowEventContext.h"
#include "core/dom/Document.h"
-#include "core/events/Event.h"
-#include "core/events/EventContext.h"
#include "core/dom/Node.h"
-#include "core/frame/DOMWindow.h"
+#include "core/events/Event.h"
+#include "core/events/NodeEventContext.h"
+#include "core/frame/LocalDOMWindow.h"
namespace WebCore {
-WindowEventContext::WindowEventContext(Event* event, PassRefPtr<Node> node, const EventContext* topEventContext)
+WindowEventContext::WindowEventContext(Event* event, PassRefPtrWillBeRawPtr<Node> node, const NodeEventContext* topNodeEventContext)
{
// We don't dispatch load events to the window. This quirk was originally
// added because Mozilla doesn't propagate load events to the window object.
if (event->type() == EventTypeNames::load)
return;
- Node* topLevelContainer = topEventContext ? topEventContext->node() : node.get();
+ Node* topLevelContainer = topNodeEventContext ? topNodeEventContext->node() : node.get();
if (!topLevelContainer->isDocumentNode())
return;
m_window = toDocument(topLevelContainer)->domWindow();
- m_target = topEventContext ? topEventContext->target() : node.get();
+ m_target = topNodeEventContext ? topNodeEventContext->target() : node.get();
}
bool WindowEventContext::handleLocalEvents(Event* event)
diff --git a/chromium/third_party/WebKit/Source/core/events/WindowEventContext.h b/chromium/third_party/WebKit/Source/core/events/WindowEventContext.h
index 25c5079c257..976c1756f6f 100644
--- a/chromium/third_party/WebKit/Source/core/events/WindowEventContext.h
+++ b/chromium/third_party/WebKit/Source/core/events/WindowEventContext.h
@@ -27,30 +27,32 @@
#ifndef WindowEventContext_h
#define WindowEventContext_h
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class EventTarget;
-class EventContext;
class Event;
class Node;
+class NodeEventContext;
class WindowEventContext {
+ STACK_ALLOCATED();
public:
- WindowEventContext(Event*, PassRefPtr<Node>, const EventContext*);
+ WindowEventContext(Event*, PassRefPtrWillBeRawPtr<Node>, const NodeEventContext*);
- DOMWindow* window() const;
+ LocalDOMWindow* window() const;
EventTarget* target() const;
bool handleLocalEvents(Event* event);
private:
- RefPtr<DOMWindow> m_window;
- RefPtr<EventTarget> m_target;
+ RefPtrWillBeMember<LocalDOMWindow> m_window;
+ RefPtrWillBeMember<EventTarget> m_target;
};
-inline DOMWindow* WindowEventContext::window() const
+inline LocalDOMWindow* WindowEventContext::window() const
{
return m_window.get();
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
index 7952ec5da2e..2eab0d54d4a 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp
@@ -30,7 +30,6 @@
#include "core/css/StyleSheetContents.h"
#include "core/fetch/ResourceClientWalker.h"
#include "core/fetch/StyleSheetResourceClient.h"
-#include "core/fetch/TextResourceDecoder.h"
#include "platform/SharedBuffer.h"
#include "platform/network/HTTPParsers.h"
#include "wtf/CurrentTime.h"
@@ -39,8 +38,7 @@
namespace WebCore {
CSSStyleSheetResource::CSSStyleSheetResource(const ResourceRequest& resourceRequest, const String& charset)
- : StyleSheetResource(resourceRequest, CSSStyleSheet)
- , m_decoder(TextResourceDecoder::create("text/css", charset))
+ : StyleSheetResource(resourceRequest, CSSStyleSheet, "text/css", charset)
{
DEFINE_STATIC_LOCAL(const AtomicString, acceptCSS, ("text/css,*/*;q=0.1", AtomicString::ConstructFromLiteral));
@@ -64,17 +62,7 @@ void CSSStyleSheetResource::didAddClient(ResourceClient* c)
Resource::didAddClient(c);
if (!isLoading())
- static_cast<StyleSheetResourceClient*>(c)->setCSSStyleSheet(m_resourceRequest.url(), m_response.url(), m_decoder->encoding().name(), this);
-}
-
-void CSSStyleSheetResource::setEncoding(const String& chs)
-{
- m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
-}
-
-String CSSStyleSheetResource::encoding() const
-{
- return m_decoder->encoding().name();
+ static_cast<StyleSheetResourceClient*>(c)->setCSSStyleSheet(m_resourceRequest.url(), m_response.url(), encoding(), this);
}
const String CSSStyleSheetResource::sheetText(bool enforceMIMEType, bool* hasValidMIMEType) const
@@ -88,26 +76,38 @@ const String CSSStyleSheetResource::sheetText(bool enforceMIMEType, bool* hasVal
return m_decodedSheetText;
// Don't cache the decoded text, regenerating is cheap and it can use quite a bit of memory
- String sheetText = m_decoder->decode(m_data->data(), m_data->size());
- sheetText.append(m_decoder->flush());
- return sheetText;
+ return decodedText();
}
void CSSStyleSheetResource::checkNotify()
{
// Decode the data to find out the encoding and keep the sheet text around during checkNotify()
- if (m_data) {
- m_decodedSheetText = m_decoder->decode(m_data->data(), m_data->size());
- m_decodedSheetText.append(m_decoder->flush());
- }
+ if (m_data)
+ m_decodedSheetText = decodedText();
ResourceClientWalker<StyleSheetResourceClient> w(m_clients);
while (StyleSheetResourceClient* c = w.next())
- c->setCSSStyleSheet(m_resourceRequest.url(), m_response.url(), m_decoder->encoding().name(), this);
+ c->setCSSStyleSheet(m_resourceRequest.url(), m_response.url(), encoding(), this);
// Clear the decoded text as it is unlikely to be needed immediately again and is cheap to regenerate.
m_decodedSheetText = String();
}
+bool CSSStyleSheetResource::isSafeToUnlock() const
+{
+ return m_data->hasOneRef();
+}
+
+void CSSStyleSheetResource::destroyDecodedDataIfPossible()
+{
+ if (!m_parsedStyleSheetCache)
+ return;
+
+ m_parsedStyleSheetCache->removedFromMemoryCache();
+ m_parsedStyleSheetCache.clear();
+
+ setDecodedSize(0);
+}
+
bool CSSStyleSheetResource::canUseSheet(bool enforceMIMEType, bool* hasValidMIMEType) const
{
if (errorOccurred())
@@ -132,28 +132,14 @@ bool CSSStyleSheetResource::canUseSheet(bool enforceMIMEType, bool* hasValidMIME
return typeOK;
}
-void CSSStyleSheetResource::destroyDecodedData()
-{
- if (!m_parsedStyleSheetCache)
- return;
-
- m_parsedStyleSheetCache->removedFromMemoryCache();
- m_parsedStyleSheetCache.clear();
-
- setDecodedSize(0);
-
- if (isSafeToMakePurgeable())
- makePurgeable(true);
-}
-
-PassRefPtr<StyleSheetContents> CSSStyleSheetResource::restoreParsedStyleSheet(const CSSParserContext& context)
+PassRefPtrWillBeRawPtr<StyleSheetContents> CSSStyleSheetResource::restoreParsedStyleSheet(const CSSParserContext& context)
{
if (!m_parsedStyleSheetCache)
- return 0;
+ return nullptr;
if (m_parsedStyleSheetCache->hasFailedOrCanceledSubresources()) {
m_parsedStyleSheetCache->removedFromMemoryCache();
m_parsedStyleSheetCache.clear();
- return 0;
+ return nullptr;
}
ASSERT(m_parsedStyleSheetCache->isCacheable());
@@ -161,14 +147,14 @@ PassRefPtr<StyleSheetContents> CSSStyleSheetResource::restoreParsedStyleSheet(co
// Contexts must be identical so we know we would get the same exact result if we parsed again.
if (m_parsedStyleSheetCache->parserContext() != context)
- return 0;
+ return nullptr;
- didAccessDecodedData(currentTime());
+ didAccessDecodedData();
return m_parsedStyleSheetCache;
}
-void CSSStyleSheetResource::saveParsedStyleSheet(PassRefPtr<StyleSheetContents> sheet)
+void CSSStyleSheetResource::saveParsedStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet)
{
ASSERT(sheet && sheet->isCacheable());
diff --git a/chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h b/chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h
index 4ca19857c87..b15eb9d99fd 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.h
@@ -28,6 +28,7 @@
#include "core/fetch/ResourcePtr.h"
#include "core/fetch/StyleSheetResource.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -36,31 +37,29 @@ class ResourceClient;
class StyleSheetContents;
class TextResourceDecoder;
-class CSSStyleSheetResource : public StyleSheetResource {
+class CSSStyleSheetResource FINAL : public StyleSheetResource {
public:
CSSStyleSheetResource(const ResourceRequest&, const String& charset);
virtual ~CSSStyleSheetResource();
const String sheetText(bool enforceMIMEType = true, bool* hasValidMIMEType = 0) const;
- virtual void didAddClient(ResourceClient*);
- virtual void setEncoding(const String&);
- virtual String encoding() const;
- virtual void destroyDecodedData() OVERRIDE;
+ virtual void didAddClient(ResourceClient*) OVERRIDE;
- PassRefPtr<StyleSheetContents> restoreParsedStyleSheet(const CSSParserContext&);
- void saveParsedStyleSheet(PassRefPtr<StyleSheetContents>);
+ PassRefPtrWillBeRawPtr<StyleSheetContents> restoreParsedStyleSheet(const CSSParserContext&);
+ void saveParsedStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>);
+
+protected:
+ virtual bool isSafeToUnlock() const OVERRIDE;
+ virtual void destroyDecodedDataIfPossible() OVERRIDE;
private:
bool canUseSheet(bool enforceMIMEType, bool* hasValidMIMEType) const;
+ virtual void checkNotify() OVERRIDE;
-protected:
- virtual void checkNotify();
-
- OwnPtr<TextResourceDecoder> m_decoder;
String m_decodedSheetText;
- RefPtr<StyleSheetContents> m_parsedStyleSheetCache;
+ RefPtrWillBePersistent<StyleSheetContents> m_parsedStyleSheetCache;
};
DEFINE_RESOURCE_TYPE_CASTS(CSSStyleSheet);
diff --git a/chromium/third_party/WebKit/Source/core/fetch/CachedMetadata.cpp b/chromium/third_party/WebKit/Source/core/fetch/CachedMetadata.cpp
deleted file mode 100644
index 7edcac53f32..00000000000
--- a/chromium/third_party/WebKit/Source/core/fetch/CachedMetadata.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/fetch/CachedMetadata.h"
-
-namespace WebCore {
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fetch/CachingCorrectnessTest.cpp b/chromium/third_party/WebKit/Source/core/fetch/CachingCorrectnessTest.cpp
new file mode 100644
index 00000000000..b733023027c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/fetch/CachingCorrectnessTest.cpp
@@ -0,0 +1,580 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/fetch/ImageResource.h"
+#include "core/fetch/MemoryCache.h"
+#include "core/fetch/Resource.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/fetch/ResourcePtr.h"
+#include "core/html/HTMLDocument.h"
+#include "core/loader/DocumentLoader.h"
+#include "platform/network/ResourceRequest.h"
+#include "public/platform/Platform.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/RefPtr.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+// An URL for the original request.
+const char kResourceURL[] = "http://resource.com/";
+
+// The origin time of our first request.
+const char kOriginalRequestDateAsString[] = "Thu, 25 May 1977 18:30:00 GMT";
+const double kOriginalRequestDateAsDouble = 233433000.;
+
+const char kOneDayBeforeOriginalRequest[] = "Wed, 24 May 1977 18:30:00 GMT";
+const char kOneDayAfterOriginalRequest[] = "Fri, 26 May 1977 18:30:00 GMT";
+
+const unsigned char kAConstUnsignedCharZero = 0;
+
+class CachingCorrectnessTest : public ::testing::Test {
+protected:
+ void advanceClock(double seconds)
+ {
+ m_proxyPlatform.advanceClock(seconds);
+ }
+
+ ResourcePtr<Resource> resourceFromResourceResponse(ResourceResponse response, Resource::Type type = Resource::Raw)
+ {
+ if (response.url().isNull())
+ response.setURL(KURL(ParsedURLString, kResourceURL));
+ ResourcePtr<Resource> resource =
+ new Resource(ResourceRequest(response.url()), type);
+ resource->setResponse(response);
+ memoryCache()->add(resource.get());
+
+ return resource;
+ }
+
+ ResourcePtr<Resource> resourceFromResourceRequest(ResourceRequest request, Resource::Type type = Resource::Raw)
+ {
+ if (request.url().isNull())
+ request.setURL(KURL(ParsedURLString, kResourceURL));
+ ResourcePtr<Resource> resource =
+ new Resource(request, type);
+ resource->setResponse(ResourceResponse(KURL(ParsedURLString, kResourceURL), "text/html", 0, nullAtom, String()));
+ memoryCache()->add(resource.get());
+
+ return resource;
+ }
+
+ ResourcePtr<Resource> fetch()
+ {
+ FetchRequest fetchRequest(ResourceRequest(KURL(ParsedURLString, kResourceURL)), FetchInitiatorInfo());
+ return m_fetcher->fetchSynchronously(fetchRequest);
+ }
+
+ ResourcePtr<Resource> fetchImage()
+ {
+ FetchRequest fetchRequest(ResourceRequest(KURL(ParsedURLString, kResourceURL)), FetchInitiatorInfo());
+ return m_fetcher->fetchImage(fetchRequest);
+ }
+
+ ResourceFetcher* fetcher() const { return m_fetcher.get(); }
+
+private:
+ // A simple platform that mocks out the clock, for cache freshness testing.
+ class ProxyPlatform : public blink::Platform {
+ public:
+ ProxyPlatform() : m_elapsedSeconds(0.) { }
+
+ void advanceClock(double seconds)
+ {
+ m_elapsedSeconds += seconds;
+ }
+
+ private:
+ // From blink::Platform:
+ virtual double currentTime()
+ {
+ return kOriginalRequestDateAsDouble + m_elapsedSeconds;
+ }
+
+ // These blink::Platform methods must be overriden to make a usable object.
+ virtual void cryptographicallyRandomValues(unsigned char* buffer, size_t length) { ASSERT_NOT_REACHED(); }
+ virtual const unsigned char* getTraceCategoryEnabledFlag(const char* categoryName)
+ {
+ return &kAConstUnsignedCharZero;
+ }
+
+ double m_elapsedSeconds;
+ };
+
+ virtual void SetUp()
+ {
+ m_savedPlatform = blink::Platform::current();
+ blink::Platform::initialize(&m_proxyPlatform);
+
+ // Save the global memory cache to restore it upon teardown.
+ m_globalMemoryCache = adoptPtr(memoryCache());
+ // Create the test memory cache instance and hook it in.
+ m_testingMemoryCache = adoptPtr(new MemoryCache());
+ setMemoryCacheForTesting(m_testingMemoryCache.leakPtr());
+
+ // Create a ResourceFetcher that has a real DocumentLoader and Document, but is not attached to a LocalFrame.
+ const KURL kDocumentURL(ParsedURLString, "http://document.com/");
+ m_documentLoader = DocumentLoader::create(0, ResourceRequest(kDocumentURL), SubstituteData());
+ m_document = HTMLDocument::create();
+ m_fetcher = ResourceFetcher::create(m_documentLoader.get());
+ m_fetcher->setDocument(m_document.get());
+ }
+
+ virtual void TearDown()
+ {
+ memoryCache()->evictResources();
+
+ // Regain the ownership of testing memory cache, so that it will be
+ // destroyed.
+ m_testingMemoryCache = adoptPtr(memoryCache());
+
+ // Yield the ownership of the global memory cache back.
+ setMemoryCacheForTesting(m_globalMemoryCache.leakPtr());
+
+ blink::Platform::initialize(m_savedPlatform);
+ }
+
+ blink::Platform* m_savedPlatform;
+ ProxyPlatform m_proxyPlatform;
+
+ OwnPtr<MemoryCache> m_testingMemoryCache;
+ OwnPtr<MemoryCache> m_globalMemoryCache;
+
+ RefPtr<DocumentLoader> m_documentLoader;
+
+ RefPtrWillBePersistent<HTMLDocument> m_document;
+ RefPtrWillBePersistent<ResourceFetcher> m_fetcher;
+};
+
+TEST_F(CachingCorrectnessTest, FreshFromLastModified)
+{
+ ResourceResponse fresh200Response;
+ fresh200Response.setHTTPStatusCode(200);
+ fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200Response.setHTTPHeaderField("Last-Modified", kOneDayBeforeOriginalRequest);
+
+ ResourcePtr<Resource> fresh200 = resourceFromResourceResponse(fresh200Response);
+
+ // Advance the clock within the implicit freshness period of this resource before we make a request.
+ advanceClock(600.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_EQ(fresh200, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, FreshFromExpires)
+{
+ ResourceResponse fresh200Response;
+ fresh200Response.setHTTPStatusCode(200);
+ fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ ResourcePtr<Resource> fresh200 = resourceFromResourceResponse(fresh200Response);
+
+ // Advance the clock within the freshness period of this resource before we make a request.
+ advanceClock(24. * 60. * 60. - 15.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_EQ(fresh200, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, FreshFromMaxAge)
+{
+ ResourceResponse fresh200Response;
+ fresh200Response.setHTTPStatusCode(200);
+ fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200Response.setHTTPHeaderField("Cache-Control", "max-age=600");
+
+ ResourcePtr<Resource> fresh200 = resourceFromResourceResponse(fresh200Response);
+
+ // Advance the clock within the freshness period of this resource before we make a request.
+ advanceClock(500.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_EQ(fresh200, fetched);
+}
+
+// The strong validator causes a revalidation to be launched, and the proxy and original resources leak because of their reference loop.
+TEST_F(CachingCorrectnessTest, DISABLED_ExpiredFromLastModified)
+{
+ ResourceResponse expired200Response;
+ expired200Response.setHTTPStatusCode(200);
+ expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ expired200Response.setHTTPHeaderField("Last-Modified", kOneDayBeforeOriginalRequest);
+
+ ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response);
+
+ // Advance the clock beyond the implicit freshness period.
+ advanceClock(24. * 60. * 60. * 0.2);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(expired200, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, ExpiredFromExpires)
+{
+ ResourceResponse expired200Response;
+ expired200Response.setHTTPStatusCode(200);
+ expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response);
+
+ // Advance the clock within the expiredness period of this resource before we make a request.
+ advanceClock(24. * 60. * 60. + 15.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(expired200, fetched);
+}
+
+// If the image hasn't been loaded in this "document" before, then it shouldn't have list of available images logic.
+TEST_F(CachingCorrectnessTest, NewImageExpiredFromExpires)
+{
+ ResourceResponse expired200Response;
+ expired200Response.setHTTPStatusCode(200);
+ expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response, Resource::Image);
+
+ // Advance the clock within the expiredness period of this resource before we make a request.
+ advanceClock(24. * 60. * 60. + 15.);
+
+ ResourcePtr<Resource> fetched = fetchImage();
+ EXPECT_NE(expired200, fetched);
+}
+
+// If the image has been loaded in this "document" before, then it should have list of available images logic, and so
+// normal cache testing should be bypassed.
+TEST_F(CachingCorrectnessTest, ReuseImageExpiredFromExpires)
+{
+ ResourceResponse expired200Response;
+ expired200Response.setHTTPStatusCode(200);
+ expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response, Resource::Image);
+
+ // Advance the clock within the freshness period, and make a request to add this image to the document resources.
+ advanceClock(15.);
+ ResourcePtr<Resource> firstFetched = fetchImage();
+ EXPECT_EQ(expired200, firstFetched);
+
+ // Advance the clock within the expiredness period of this resource before we make a request.
+ advanceClock(24. * 60. * 60. + 15.);
+
+ ResourcePtr<Resource> fetched = fetchImage();
+ EXPECT_EQ(expired200, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, ExpiredFromMaxAge)
+{
+ ResourceResponse expired200Response;
+ expired200Response.setHTTPStatusCode(200);
+ expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ expired200Response.setHTTPHeaderField("Cache-Control", "max-age=600");
+
+ ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response);
+
+ // Advance the clock within the expiredness period of this resource before we make a request.
+ advanceClock(700.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(expired200, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, FreshButNoCache)
+{
+ ResourceResponse fresh200NocacheResponse;
+ fresh200NocacheResponse.setHTTPStatusCode(200);
+ fresh200NocacheResponse.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200NocacheResponse.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+ fresh200NocacheResponse.setHTTPHeaderField("Cache-Control", "no-cache");
+
+ ResourcePtr<Resource> fresh200Nocache = resourceFromResourceResponse(fresh200NocacheResponse);
+
+ // Advance the clock within the freshness period of this resource before we make a request.
+ advanceClock(24. * 60. * 60. - 15.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(fresh200Nocache, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, RequestWithNoCahe)
+{
+ ResourceRequest noCacheRequest;
+ noCacheRequest.setHTTPHeaderField("Cache-Control", "no-cache");
+ ResourcePtr<Resource> noCacheResource = resourceFromResourceRequest(noCacheRequest);
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(noCacheResource, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, FreshButNoStore)
+{
+ ResourceResponse fresh200NostoreResponse;
+ fresh200NostoreResponse.setHTTPStatusCode(200);
+ fresh200NostoreResponse.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200NostoreResponse.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+ fresh200NostoreResponse.setHTTPHeaderField("Cache-Control", "no-store");
+
+ ResourcePtr<Resource> fresh200Nostore = resourceFromResourceResponse(fresh200NostoreResponse);
+
+ // Advance the clock within the freshness period of this resource before we make a request.
+ advanceClock(24. * 60. * 60. - 15.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(fresh200Nostore, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, RequestWithNoStore)
+{
+ ResourceRequest noStoreRequest;
+ noStoreRequest.setHTTPHeaderField("Cache-Control", "no-store");
+ ResourcePtr<Resource> noStoreResource = resourceFromResourceRequest(noStoreRequest);
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(noStoreResource, fetched);
+}
+
+// FIXME: Determine if ignoring must-revalidate for blink is correct behaviour.
+// See crbug.com/340088 .
+TEST_F(CachingCorrectnessTest, DISABLED_FreshButMustRevalidate)
+{
+ ResourceResponse fresh200MustRevalidateResponse;
+ fresh200MustRevalidateResponse.setHTTPStatusCode(200);
+ fresh200MustRevalidateResponse.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200MustRevalidateResponse.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+ fresh200MustRevalidateResponse.setHTTPHeaderField("Cache-Control", "must-revalidate");
+
+ ResourcePtr<Resource> fresh200MustRevalidate = resourceFromResourceResponse(fresh200MustRevalidateResponse);
+
+ // Advance the clock within the freshness period of this resource before we make a request.
+ advanceClock(24. * 60. * 60. - 15.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(fresh200MustRevalidate, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, FreshWithFreshRedirect)
+{
+ KURL redirectUrl(ParsedURLString, kResourceURL);
+ const char redirectTargetUrlString[] = "http://redirect-target.com";
+ KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString);
+
+ ResourcePtr<Resource> firstResource = new Resource(ResourceRequest(redirectUrl), Resource::Raw);
+
+ ResourceResponse fresh301Response;
+ fresh301Response.setURL(redirectUrl);
+ fresh301Response.setHTTPStatusCode(301);
+ fresh301Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh301Response.setHTTPHeaderField("Location", redirectTargetUrlString);
+ fresh301Response.setHTTPHeaderField("Cache-Control", "max-age=600");
+
+ // Add the redirect to our request.
+ ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl);
+ firstResource->willSendRequest(redirectRequest, fresh301Response);
+
+ // Add the final response to our request.
+ ResourceResponse fresh200Response;
+ fresh200Response.setURL(redirectTargetUrl);
+ fresh200Response.setHTTPStatusCode(200);
+ fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ firstResource->setResponse(fresh200Response);
+ memoryCache()->add(firstResource.get());
+
+ advanceClock(500.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_EQ(firstResource, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, FreshWithStaleRedirect)
+{
+ KURL redirectUrl(ParsedURLString, kResourceURL);
+ const char redirectTargetUrlString[] = "http://redirect-target.com";
+ KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString);
+
+ ResourcePtr<Resource> firstResource = new Resource(ResourceRequest(redirectUrl), Resource::Raw);
+
+ ResourceResponse stale301Response;
+ stale301Response.setURL(redirectUrl);
+ stale301Response.setHTTPStatusCode(301);
+ stale301Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ stale301Response.setHTTPHeaderField("Location", redirectTargetUrlString);
+
+ // Add the redirect to our request.
+ ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl);
+ firstResource->willSendRequest(redirectRequest, stale301Response);
+
+ // Add the final response to our request.
+ ResourceResponse fresh200Response;
+ fresh200Response.setURL(redirectTargetUrl);
+ fresh200Response.setHTTPStatusCode(200);
+ fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ firstResource->setResponse(fresh200Response);
+ memoryCache()->add(firstResource.get());
+
+ advanceClock(500.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(firstResource, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, PostToSameURLTwice)
+{
+ ResourceRequest request1(KURL(ParsedURLString, kResourceURL));
+ request1.setHTTPMethod("POST");
+ ResourcePtr<Resource> resource1 = new Resource(ResourceRequest(request1.url()), Resource::Raw);
+ resource1->setLoading(true);
+ memoryCache()->add(resource1.get());
+
+ ResourceRequest request2(KURL(ParsedURLString, kResourceURL));
+ request2.setHTTPMethod("POST");
+ FetchRequest fetch2(request2, FetchInitiatorInfo());
+ ResourcePtr<Resource> resource2 = fetcher()->fetchSynchronously(fetch2);
+
+ EXPECT_EQ(resource2, memoryCache()->resourceForURL(request2.url()));
+ EXPECT_NE(resource1, resource2);
+}
+
+TEST_F(CachingCorrectnessTest, 302RedirectNotImplicitlyFresh)
+{
+ KURL redirectUrl(ParsedURLString, kResourceURL);
+ const char redirectTargetUrlString[] = "http://redirect-target.com";
+ KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString);
+
+ ResourcePtr<Resource> firstResource = new Resource(ResourceRequest(redirectUrl), Resource::Raw);
+
+ ResourceResponse fresh302Response;
+ fresh302Response.setURL(redirectUrl);
+ fresh302Response.setHTTPStatusCode(302);
+ fresh302Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh302Response.setHTTPHeaderField("Last-Modified", kOneDayBeforeOriginalRequest);
+ fresh302Response.setHTTPHeaderField("Location", redirectTargetUrlString);
+
+ // Add the redirect to our request.
+ ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl);
+ firstResource->willSendRequest(redirectRequest, fresh302Response);
+
+ // Add the final response to our request.
+ ResourceResponse fresh200Response;
+ fresh200Response.setURL(redirectTargetUrl);
+ fresh200Response.setHTTPStatusCode(200);
+ fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ firstResource->setResponse(fresh200Response);
+ memoryCache()->add(firstResource.get());
+
+ advanceClock(500.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_NE(firstResource, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, 302RedirectExplicitlyFreshMaxAge)
+{
+ KURL redirectUrl(ParsedURLString, kResourceURL);
+ const char redirectTargetUrlString[] = "http://redirect-target.com";
+ KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString);
+
+ ResourcePtr<Resource> firstResource = new Resource(ResourceRequest(redirectUrl), Resource::Raw);
+
+ ResourceResponse fresh302Response;
+ fresh302Response.setURL(redirectUrl);
+ fresh302Response.setHTTPStatusCode(302);
+ fresh302Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh302Response.setHTTPHeaderField("Cache-Control", "max-age=600");
+ fresh302Response.setHTTPHeaderField("Location", redirectTargetUrlString);
+
+ // Add the redirect to our request.
+ ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl);
+ firstResource->willSendRequest(redirectRequest, fresh302Response);
+
+ // Add the final response to our request.
+ ResourceResponse fresh200Response;
+ fresh200Response.setURL(redirectTargetUrl);
+ fresh200Response.setHTTPStatusCode(200);
+ fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ firstResource->setResponse(fresh200Response);
+ memoryCache()->add(firstResource.get());
+
+ advanceClock(500.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_EQ(firstResource, fetched);
+}
+
+TEST_F(CachingCorrectnessTest, 302RedirectExplicitlyFreshExpires)
+{
+ KURL redirectUrl(ParsedURLString, kResourceURL);
+ const char redirectTargetUrlString[] = "http://redirect-target.com";
+ KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString);
+
+ ResourcePtr<Resource> firstResource = new Resource(ResourceRequest(redirectUrl), Resource::Raw);
+
+ ResourceResponse fresh302Response;
+ fresh302Response.setURL(redirectUrl);
+ fresh302Response.setHTTPStatusCode(302);
+ fresh302Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh302Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+ fresh302Response.setHTTPHeaderField("Location", redirectTargetUrlString);
+
+ // Add the redirect to our request.
+ ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl);
+ firstResource->willSendRequest(redirectRequest, fresh302Response);
+
+ // Add the final response to our request.
+ ResourceResponse fresh200Response;
+ fresh200Response.setURL(redirectTargetUrl);
+ fresh200Response.setHTTPStatusCode(200);
+ fresh200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
+ fresh200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
+
+ firstResource->setResponse(fresh200Response);
+ memoryCache()->add(firstResource.get());
+
+ advanceClock(500.);
+
+ ResourcePtr<Resource> fetched = fetch();
+ EXPECT_EQ(firstResource, fetched);
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp b/chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp
index f35116c73f8..ddcb29c4064 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp
@@ -27,8 +27,12 @@
#include "config.h"
#include "core/fetch/CrossOriginAccessControl.h"
+#include "core/fetch/Resource.h"
+#include "core/fetch/ResourceLoaderOptions.h"
#include "platform/network/HTTPParsers.h"
+#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"
+#include "platform/weborigin/SchemeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/Threading.h"
#include "wtf/text/AtomicString.h"
@@ -99,10 +103,10 @@ bool isOnAccessControlResponseHeaderWhitelist(const String& name)
void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* securityOrigin, StoredCredentials allowCredentials)
{
request.removeCredentials();
- request.setAllowCookies(allowCredentials == AllowStoredCredentials);
+ request.setAllowStoredCredentials(allowCredentials == AllowStoredCredentials);
if (securityOrigin)
- request.setHTTPOrigin(securityOrigin->toString());
+ request.setHTTPOrigin(securityOrigin->toAtomicString());
}
ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& request, SecurityOrigin* securityOrigin)
@@ -127,7 +131,7 @@ ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& reque
headerBuffer.append(it->key);
}
- preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", headerBuffer.toString().lower());
+ preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", AtomicString(headerBuffer.toString().lower()));
}
return preflightRequest;
@@ -143,16 +147,23 @@ bool passesAccessControlCheck(const ResourceResponse& response, StoredCredential
AtomicallyInitializedStatic(AtomicString&, accessControlAllowOrigin = *new AtomicString("access-control-allow-origin", AtomicString::ConstructFromLiteral));
AtomicallyInitializedStatic(AtomicString&, accessControlAllowCredentials = *new AtomicString("access-control-allow-credentials", AtomicString::ConstructFromLiteral));
- // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
- // even with Access-Control-Allow-Credentials set to true.
- const AtomicString& accessControlOriginString = response.httpHeaderField(accessControlAllowOrigin);
- if (accessControlOriginString == starAtom && includeCredentials == DoNotAllowStoredCredentials)
- return true;
+ if (!response.httpStatusCode()) {
+ errorDescription = "Received an invalid response. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
+ return false;
+ }
- if (accessControlOriginString != securityOrigin->toString()) {
- if (accessControlOriginString == starAtom) {
+ const AtomicString& accessControlOriginString = response.httpHeaderField(accessControlAllowOrigin);
+ if (accessControlOriginString == starAtom) {
+ // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
+ // even with Access-Control-Allow-Credentials set to true.
+ if (includeCredentials == DoNotAllowStoredCredentials)
+ return true;
+ if (response.isHTTP()) {
errorDescription = "A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
- } else if (accessControlOriginString.isEmpty()) {
+ return false;
+ }
+ } else if (accessControlOriginString != securityOrigin->toAtomicString()) {
+ if (accessControlOriginString.isEmpty()) {
errorDescription = "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
} else if (accessControlOriginString.string().find(isOriginSeparator, 0) != kNotFound) {
errorDescription = "The 'Access-Control-Allow-Origin' header contains multiple values '" + accessControlOriginString + "', but only one is allowed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
@@ -198,4 +209,67 @@ void parseAccessControlExposeHeadersAllowList(const String& headerValue, HTTPHea
}
}
+bool CrossOriginAccessControl::isLegalRedirectLocation(const KURL& requestURL, String& errorDescription)
+{
+ // CORS restrictions imposed on Location: URL -- http://www.w3.org/TR/cors/#redirect-steps (steps 2 + 3.)
+ if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(requestURL.protocol())) {
+ errorDescription = "The request was redirected to a URL ('" + requestURL.string() + "') which has a disallowed scheme for cross-origin requests.";
+ return false;
+ }
+
+ if (!(requestURL.user().isEmpty() && requestURL.pass().isEmpty())) {
+ errorDescription = "The request was redirected to a URL ('" + requestURL.string() + "') containing userinfo, which is disallowed for cross-origin requests.";
+ return false;
+ }
+
+ return true;
+}
+
+bool CrossOriginAccessControl::handleRedirect(Resource* resource, SecurityOrigin* securityOrigin, ResourceRequest& request, const ResourceResponse& redirectResponse, ResourceLoaderOptions& options, String& errorMessage)
+{
+ // http://www.w3.org/TR/cors/#redirect-steps terminology:
+ const KURL& originalURL = redirectResponse.url();
+ const KURL& requestURL = request.url();
+
+ bool redirectCrossOrigin = !securityOrigin->canRequest(requestURL);
+
+ // Same-origin request URLs that redirect are allowed without checking access.
+ if (!securityOrigin->canRequest(originalURL)) {
+ // Follow http://www.w3.org/TR/cors/#redirect-steps
+ String errorDescription;
+
+ // Steps 3 & 4 - check if scheme and other URL restrictions hold.
+ bool allowRedirect = isLegalRedirectLocation(requestURL, errorDescription);
+ if (allowRedirect) {
+ // Step 5: perform resource sharing access check.
+ StoredCredentials withCredentials = resource->lastResourceRequest().allowStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+ allowRedirect = passesAccessControlCheck(redirectResponse, withCredentials, securityOrigin, errorDescription);
+ if (allowRedirect) {
+ RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(originalURL);
+ // Step 6: if the request URL origin is not same origin as the original URL's,
+ // set the source origin to a globally unique identifier.
+ if (!originalOrigin->canRequest(requestURL)) {
+ options.securityOrigin = SecurityOrigin::createUnique();
+ securityOrigin = options.securityOrigin.get();
+ }
+ }
+ }
+ if (!allowRedirect) {
+ const String& originalOrigin = SecurityOrigin::create(originalURL)->toString();
+ errorMessage = "Redirect at origin '" + originalOrigin + "' has been blocked from loading by Cross-Origin Resource Sharing policy: " + errorDescription;
+ return false;
+ }
+ }
+ if (redirectCrossOrigin) {
+ // If now to a different origin, update/set Origin:.
+ request.clearHTTPOrigin();
+ request.setHTTPOrigin(securityOrigin->toAtomicString());
+ // If the user didn't request credentials in the first place, update our
+ // state so we neither request them nor expect they must be allowed.
+ if (options.credentialsRequested == ClientDidNotRequestCredentials)
+ options.allowCredentials = DoNotAllowStoredCredentials;
+ }
+ return true;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.h b/chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.h
index 450c342253f..a96536f553a 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.h
@@ -37,6 +37,9 @@ namespace WebCore {
typedef HashSet<String, CaseFoldingHash> HTTPHeaderSet;
class HTTPHeaderMap;
+class Resource;
+struct ResourceLoaderOptions;
+class ResourceRequest;
class ResourceResponse;
class SecurityOrigin;
@@ -45,6 +48,12 @@ enum AccessControlStatus {
SharableCrossOrigin
};
+class CrossOriginAccessControl {
+public:
+ static bool isLegalRedirectLocation(const KURL&, String& errorDescription);
+ static bool handleRedirect(Resource*, SecurityOrigin*, ResourceRequest&, const ResourceResponse&, ResourceLoaderOptions&, String&);
+};
+
bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
bool isOnAccessControlSimpleRequestHeaderWhitelist(const AtomicString& name, const AtomicString& value);
diff --git a/chromium/third_party/WebKit/Source/core/fetch/DocumentResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/DocumentResource.cpp
index 61521b06ae2..f3b8925e940 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/DocumentResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/DocumentResource.cpp
@@ -24,8 +24,8 @@
#include "core/fetch/DocumentResource.h"
+#include "core/dom/XMLDocument.h"
#include "platform/SharedBuffer.h"
-#include "core/svg/SVGDocument.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -65,15 +65,15 @@ void DocumentResource::checkNotify()
Resource::checkNotify();
}
-PassRefPtr<Document> DocumentResource::createDocument(const KURL& url)
+PassRefPtrWillBeRawPtr<Document> DocumentResource::createDocument(const KURL& url)
{
switch (type()) {
case SVGDocument:
- return SVGDocument::create(DocumentInit(url));
+ return XMLDocument::createSVG(DocumentInit(url));
default:
// FIXME: We'll add more types to support HTMLImports.
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/DocumentResource.h b/chromium/third_party/WebKit/Source/core/fetch/DocumentResource.h
index 292f977d01a..6ded9f721a6 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/DocumentResource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/DocumentResource.h
@@ -26,13 +26,13 @@
#include "core/fetch/Resource.h"
#include "core/fetch/ResourceClient.h"
#include "core/fetch/ResourcePtr.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
namespace WebCore {
class Document;
-class DocumentResource : public Resource {
+class DocumentResource FINAL : public Resource {
public:
typedef ResourceClient ClientType;
@@ -41,14 +41,14 @@ public:
Document* document() const { return m_document.get(); }
- virtual void setEncoding(const String&);
- virtual String encoding() const;
+ virtual void setEncoding(const String&) OVERRIDE;
+ virtual String encoding() const OVERRIDE;
virtual void checkNotify() OVERRIDE;
private:
- PassRefPtr<Document> createDocument(const KURL&);
+ PassRefPtrWillBeRawPtr<Document> createDocument(const KURL&);
- RefPtr<Document> m_document;
+ RefPtrWillBePersistent<Document> m_document;
OwnPtr<TextResourceDecoder> m_decoder;
};
@@ -59,7 +59,7 @@ class DocumentResourceClient : public ResourceClient {
public:
virtual ~DocumentResourceClient() { }
static ResourceClientType expectedType() { return DocumentType; }
- virtual ResourceClientType resourceClientType() const { return expectedType(); }
+ virtual ResourceClientType resourceClientType() const OVERRIDE { return expectedType(); }
};
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/DocumentResourceReference.h b/chromium/third_party/WebKit/Source/core/fetch/DocumentResourceReference.h
index 9e8433583f9..60f74488188 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/DocumentResourceReference.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/DocumentResourceReference.h
@@ -31,7 +31,7 @@
namespace WebCore {
-class DocumentResourceReference : public DocumentResourceClient {
+class DocumentResourceReference FINAL : public DocumentResourceClient {
public:
DocumentResourceReference(DocumentResource* document) : m_document(document) { m_document->addClient(this); }
virtual ~DocumentResourceReference() { m_document->removeClient(this); }
diff --git a/chromium/third_party/WebKit/Source/core/fetch/FetchContext.cpp b/chromium/third_party/WebKit/Source/core/fetch/FetchContext.cpp
index cc7a6d9ce6a..4f64ca607d3 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/FetchContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/FetchContext.cpp
@@ -40,7 +40,7 @@ FetchContext& FetchContext::nullInstance()
return instance;
}
-void FetchContext::dispatchDidChangeResourcePriority(unsigned long, ResourceLoadPriority)
+void FetchContext::dispatchDidChangeResourcePriority(unsigned long, ResourceLoadPriority, int)
{
}
@@ -48,7 +48,11 @@ void FetchContext::reportLocalLoadFailed(const KURL&)
{
}
-void FetchContext::addAdditionalRequestHeaders(Document&, ResourceRequest&, Resource::Type)
+void FetchContext::addAdditionalRequestHeaders(Document*, ResourceRequest&, FetchResourceType)
+{
+}
+
+void FetchContext::setFirstPartyForCookies(ResourceRequest&)
{
}
@@ -77,7 +81,7 @@ void FetchContext::dispatchDidDownloadData(DocumentLoader*, unsigned long, int,
{
}
-void FetchContext::dispatchDidFinishLoading(DocumentLoader*, unsigned long, double)
+void FetchContext::dispatchDidFinishLoading(DocumentLoader*, unsigned long, double, int64_t)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/FetchContext.h b/chromium/third_party/WebKit/Source/core/fetch/FetchContext.h
index 48803408e00..9ab7e9df836 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/FetchContext.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/FetchContext.h
@@ -41,7 +41,7 @@ namespace WebCore {
class Document;
class DocumentLoader;
-class Frame;
+class LocalFrame;
class KURL;
class Page;
class ResourceError;
@@ -49,6 +49,11 @@ class ResourceLoader;
class ResourceResponse;
class ResourceRequest;
+enum FetchResourceType {
+ FetchMainResource,
+ FetchSubresource
+};
+
class FetchContext {
WTF_MAKE_NONCOPYABLE(FetchContext);
public:
@@ -58,16 +63,17 @@ public:
virtual ~FetchContext() { }
virtual void reportLocalLoadFailed(const KURL&);
- virtual void addAdditionalRequestHeaders(Document&, ResourceRequest&, Resource::Type);
+ virtual void addAdditionalRequestHeaders(Document*, ResourceRequest&, FetchResourceType);
+ virtual void setFirstPartyForCookies(ResourceRequest&);
virtual CachePolicy cachePolicy(Document*) const;
- virtual void dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority);
+ virtual void dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority, int intraPriorityValue);
virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& = FetchInitiatorInfo());
virtual void dispatchDidLoadResourceFromMemoryCache(const ResourceRequest&, const ResourceResponse&);
virtual void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, ResourceLoader* = 0);
virtual void dispatchDidReceiveData(DocumentLoader*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
virtual void dispatchDidDownloadData(DocumentLoader*, unsigned long identifier, int dataLength, int encodedDataLength);
- virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier, double finishTime);
+ virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier, double finishTime, int64_t encodedDataLength);
virtual void dispatchDidFail(DocumentLoader*, unsigned long identifier, const ResourceError&);
virtual void sendRemainingDelegateMessages(DocumentLoader*, unsigned long identifier, const ResourceResponse&, int dataLength);
};
diff --git a/chromium/third_party/WebKit/Source/core/fetch/FetchInitiatorTypeNames.in b/chromium/third_party/WebKit/Source/core/fetch/FetchInitiatorTypeNames.in
index f0cf1b83884..472aa1095d9 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/FetchInitiatorTypeNames.in
+++ b/chromium/third_party/WebKit/Source/core/fetch/FetchInitiatorTypeNames.in
@@ -1,11 +1,14 @@
namespace="FetchInitiatorType"
+beacon
css
document
icon
internal
link
+ping
processinginstruction
texttrack
+violationreport
xml
xmlhttprequest
diff --git a/chromium/third_party/WebKit/Source/core/fetch/FetchRequest.cpp b/chromium/third_party/WebKit/Source/core/fetch/FetchRequest.cpp
index 956ae9630f2..6b08b9fd87b 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/FetchRequest.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/FetchRequest.cpp
@@ -69,9 +69,24 @@ FetchRequest::~FetchRequest()
{
}
-void FetchRequest::setCrossOriginAccessControl(SecurityOrigin* origin, StoredCredentials allowCredentials)
+void FetchRequest::setCrossOriginAccessControl(SecurityOrigin* origin, StoredCredentials allowCredentials, CredentialRequest requested)
{
+ ASSERT(requested == ClientDidNotRequestCredentials || allowCredentials == AllowStoredCredentials);
updateRequestForAccessControl(m_resourceRequest, origin, allowCredentials);
+ m_options.allowCredentials = allowCredentials;
+ m_options.corsEnabled = IsCORSEnabled;
+ m_options.securityOrigin = origin;
+ m_options.credentialsRequested = requested;
+}
+
+void FetchRequest::setCrossOriginAccessControl(SecurityOrigin* origin, StoredCredentials allowCredentials)
+{
+ setCrossOriginAccessControl(origin, allowCredentials, allowCredentials == AllowStoredCredentials ? ClientRequestedCredentials : ClientDidNotRequestCredentials);
+}
+
+void FetchRequest::setCrossOriginAccessControl(SecurityOrigin* origin, const AtomicString& crossOriginMode)
+{
+ setCrossOriginAccessControl(origin, equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fetch/FetchRequest.h b/chromium/third_party/WebKit/Source/core/fetch/FetchRequest.h
index 1954cedbeef..57c2e13fcaf 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/FetchRequest.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/FetchRequest.h
@@ -59,7 +59,9 @@ public:
DeferOption defer() const { return m_defer; }
void setDefer(DeferOption defer) { m_defer = defer; }
void setContentSecurityCheck(ContentSecurityPolicyCheck contentSecurityPolicyOption) { m_options.contentSecurityPolicyOption = contentSecurityPolicyOption; }
+ void setCrossOriginAccessControl(SecurityOrigin*, StoredCredentials, CredentialRequest);
void setCrossOriginAccessControl(SecurityOrigin*, StoredCredentials);
+ void setCrossOriginAccessControl(SecurityOrigin*, const AtomicString& crossOriginMode);
OriginRestriction originRestriction() const { return m_originRestriction; }
void setOriginRestriction(OriginRestriction restriction) { m_originRestriction = restriction; }
diff --git a/chromium/third_party/WebKit/Source/core/fetch/FontResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/FontResource.cpp
index 0fdbcc1d39e..22df8287e6c 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/FontResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/FontResource.cpp
@@ -27,8 +27,9 @@
#include "config.h"
#include "core/fetch/FontResource.h"
+#include "core/dom/TagCollection.h"
#include "core/fetch/ResourceClientWalker.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "platform/SharedBuffer.h"
#include "platform/fonts/FontCustomPlatformData.h"
#include "platform/fonts/FontPlatformData.h"
@@ -36,17 +37,48 @@
#include "wtf/CurrentTime.h"
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
-#include "core/dom/NodeList.h"
-#include "core/svg/SVGDocument.h"
+#include "core/SVGNames.h"
+#include "core/dom/XMLDocument.h"
+#include "core/html/HTMLCollection.h"
#include "core/svg/SVGFontElement.h"
#endif
namespace WebCore {
+static const double fontLoadWaitLimitSec = 3.0;
+
+enum FontPackageFormat {
+ PackageFormatUnknown,
+ PackageFormatSFNT,
+ PackageFormatWOFF,
+ PackageFormatWOFF2,
+ PackageFormatSVG,
+ PackageFormatEnumMax
+};
+
+static FontPackageFormat packageFormatOf(SharedBuffer* buffer)
+{
+ if (buffer->size() < 4)
+ return PackageFormatUnknown;
+
+ const char* data = buffer->data();
+ if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F')
+ return PackageFormatWOFF;
+ if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2')
+ return PackageFormatWOFF2;
+ return PackageFormatSFNT;
+}
+
+static void recordPackageFormatHistogram(FontPackageFormat format)
+{
+ blink::Platform::current()->histogramEnumeration("WebFont.PackageFormat", format, PackageFormatEnumMax);
+}
+
FontResource::FontResource(const ResourceRequest& resourceRequest)
: Resource(resourceRequest, Font)
, m_loadInitiated(false)
+ , m_exceedsFontLoadWaitLimit(false)
+ , m_fontLoadWaitLimitTimer(this, &FontResource::fontLoadWaitLimitCallback)
{
}
@@ -74,6 +106,7 @@ void FontResource::beginLoadIfNeeded(ResourceFetcher* dl)
if (!m_loadInitiated) {
m_loadInitiated = true;
Resource::load(dl, m_options);
+ m_fontLoadWaitLimitTimer.startOneShot(fontLoadWaitLimitSec, FROM_HERE);
ResourceClientWalker<FontResourceClient> walker(m_clients);
while (FontResourceClient* client = walker.next())
@@ -86,8 +119,13 @@ bool FontResource::ensureCustomFontData()
if (!m_fontData && !errorOccurred() && !isLoading()) {
if (m_data)
m_fontData = FontCustomPlatformData::create(m_data.get());
- if (!m_fontData)
+
+ if (m_fontData) {
+ recordPackageFormatHistogram(packageFormatOf(m_data.get()));
+ } else {
setStatus(DecodeError);
+ recordPackageFormatHistogram(PackageFormatUnknown);
+ }
}
return m_fontData;
}
@@ -107,19 +145,23 @@ bool FontResource::ensureSVGFontData()
{
if (!m_externalSVGDocument && !errorOccurred() && !isLoading()) {
if (m_data) {
- m_externalSVGDocument = SVGDocument::create();
+ m_externalSVGDocument = XMLDocument::createSVG();
OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
String svgSource = decoder->decode(m_data->data(), m_data->size());
- svgSource.append(decoder->flush());
+ svgSource = svgSource + decoder->flush();
m_externalSVGDocument->setContent(svgSource);
if (decoder->sawError())
- m_externalSVGDocument = 0;
+ m_externalSVGDocument = nullptr;
}
- if (!m_externalSVGDocument)
+ if (m_externalSVGDocument) {
+ recordPackageFormatHistogram(PackageFormatSVG);
+ } else {
setStatus(DecodeError);
+ recordPackageFormatHistogram(PackageFormatUnknown);
+ }
}
return m_externalSVGDocument;
@@ -127,26 +169,26 @@ bool FontResource::ensureSVGFontData()
SVGFontElement* FontResource::getSVGFontById(const String& fontName) const
{
- RefPtr<NodeList> list = m_externalSVGDocument->getElementsByTagNameNS(SVGNames::fontTag.namespaceURI(), SVGNames::fontTag.localName());
- if (!list)
+ RefPtrWillBeRawPtr<TagCollection> collection = m_externalSVGDocument->getElementsByTagNameNS(SVGNames::fontTag.namespaceURI(), SVGNames::fontTag.localName());
+ if (!collection)
return 0;
- unsigned listLength = list->length();
- if (!listLength)
+ unsigned collectionLength = collection->length();
+ if (!collectionLength)
return 0;
#ifndef NDEBUG
- for (unsigned i = 0; i < listLength; ++i) {
- ASSERT(list->item(i));
- ASSERT(list->item(i)->hasTagName(SVGNames::fontTag));
+ for (unsigned i = 0; i < collectionLength; ++i) {
+ ASSERT(collection->item(i));
+ ASSERT(isSVGFontElement(collection->item(i)));
}
#endif
if (fontName.isEmpty())
- return toSVGFontElement(list->item(0));
+ return toSVGFontElement(collection->item(0));
- for (unsigned i = 0; i < listLength; ++i) {
- SVGFontElement* element = toSVGFontElement(list->item(i));
+ for (unsigned i = 0; i < collectionLength; ++i) {
+ SVGFontElement* element = toSVGFontElement(collection->item(i));
if (element->getIdAttribute() == fontName)
return element;
}
@@ -155,6 +197,21 @@ SVGFontElement* FontResource::getSVGFontById(const String& fontName) const
}
#endif
+bool FontResource::isSafeToUnlock() const
+{
+ return m_data->hasOneRef();
+}
+
+void FontResource::fontLoadWaitLimitCallback(Timer<FontResource>*)
+{
+ if (!isLoading())
+ return;
+ m_exceedsFontLoadWaitLimit = true;
+ ResourceClientWalker<FontResourceClient> walker(m_clients);
+ while (FontResourceClient* client = walker.next())
+ client->fontLoadWaitLimitExceeded(this);
+}
+
void FontResource::allClientsRemoved()
{
m_fontData.clear();
@@ -163,6 +220,7 @@ void FontResource::allClientsRemoved()
void FontResource::checkNotify()
{
+ m_fontLoadWaitLimitTimer.stop();
ResourceClientWalker<FontResourceClient> w(m_clients);
while (FontResourceClient* c = w.next())
c->fontLoaded(this);
diff --git a/chromium/third_party/WebKit/Source/core/fetch/FontResource.h b/chromium/third_party/WebKit/Source/core/fetch/FontResource.h
index f92d7d21bd6..51f353bb014 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/FontResource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/FontResource.h
@@ -28,32 +28,34 @@
#include "core/fetch/ResourceClient.h"
#include "core/fetch/ResourcePtr.h"
+#include "platform/Timer.h"
#include "platform/fonts/FontOrientation.h"
#include "platform/fonts/FontWidthVariant.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
+class Document;
class ResourceFetcher;
class FontPlatformData;
-class SVGDocument;
class SVGFontElement;
class FontCustomPlatformData;
-class FontResource : public Resource {
+class FontResource FINAL : public Resource {
public:
typedef ResourceClient ClientType;
FontResource(const ResourceRequest&);
virtual ~FontResource();
- virtual void load(ResourceFetcher*, const ResourceLoaderOptions&);
+ virtual void load(ResourceFetcher*, const ResourceLoaderOptions&) OVERRIDE;
- virtual void didAddClient(ResourceClient*);
+ virtual void didAddClient(ResourceClient*) OVERRIDE;
- virtual void allClientsRemoved();
+ virtual void allClientsRemoved() OVERRIDE;
void beginLoadIfNeeded(ResourceFetcher* dl);
- bool stillNeedsLoad() const { return !m_loadInitiated; }
+ virtual bool stillNeedsLoad() const OVERRIDE { return !m_loadInitiated; }
+ bool exceedsFontLoadWaitLimit() const { return m_exceedsFontLoadWaitLimit; }
bool ensureCustomFontData();
FontPlatformData platformDataFromCustomData(float size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth);
@@ -63,13 +65,20 @@ public:
SVGFontElement* getSVGFontById(const String&) const;
#endif
+protected:
+ virtual bool isSafeToUnlock() const OVERRIDE;
+
private:
- virtual void checkNotify();
+ virtual void checkNotify() OVERRIDE;
+ void fontLoadWaitLimitCallback(Timer<FontResource>*);
+
OwnPtr<FontCustomPlatformData> m_fontData;
bool m_loadInitiated;
+ bool m_exceedsFontLoadWaitLimit;
+ Timer<FontResource> m_fontLoadWaitLimitTimer;
#if ENABLE(SVG_FONTS)
- RefPtr<WebCore::SVGDocument> m_externalSVGDocument;
+ RefPtrWillBePersistent<Document> m_externalSVGDocument;
#endif
friend class MemoryCache;
@@ -81,9 +90,10 @@ class FontResourceClient : public ResourceClient {
public:
virtual ~FontResourceClient() { }
static ResourceClientType expectedType() { return FontType; }
- virtual ResourceClientType resourceClientType() const { return expectedType(); }
+ virtual ResourceClientType resourceClientType() const OVERRIDE FINAL { return expectedType(); }
virtual void fontLoaded(FontResource*) { }
virtual void didStartFontLoad(FontResource*) { }
+ virtual void fontLoadWaitLimitExceeded(FontResource*) { }
};
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/ImageResource.cpp
index 598e616f1fa..feb42065501 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ImageResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/ImageResource.cpp
@@ -24,7 +24,6 @@
#include "config.h"
#include "core/fetch/ImageResource.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/fetch/ImageResourceClient.h"
#include "core/fetch/MemoryCache.h"
#include "core/fetch/ResourceClient.h"
@@ -33,20 +32,20 @@
#include "core/frame/FrameView.h"
#include "core/rendering/RenderObject.h"
#include "core/svg/graphics/SVGImage.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/SharedBuffer.h"
+#include "platform/TraceEvent.h"
#include "platform/graphics/BitmapImage.h"
#include "wtf/CurrentTime.h"
#include "wtf/StdLibExtras.h"
#include "wtf/Vector.h"
-using namespace std;
-
namespace WebCore {
ImageResource::ImageResource(const ResourceRequest& resourceRequest)
: Resource(resourceRequest, Image)
, m_devicePixelRatioHeaderValue(1.0)
- , m_image(0)
+ , m_image(nullptr)
, m_loadingMultipartContent(false)
, m_hasDevicePixelRatioHeaderValue(false)
{
@@ -63,6 +62,15 @@ ImageResource::ImageResource(WebCore::Image* image)
setCustomAcceptHeader();
}
+ImageResource::ImageResource(const ResourceRequest& resourceRequest, WebCore::Image* image)
+ : Resource(resourceRequest, Image)
+ , m_image(image)
+{
+ setStatus(Cached);
+ setLoading(false);
+ setCustomAcceptHeader();
+}
+
ImageResource::~ImageResource()
{
clearImage();
@@ -122,6 +130,22 @@ void ImageResource::switchClientsToRevalidatedResource()
Resource::switchClientsToRevalidatedResource();
}
+bool ImageResource::isSafeToUnlock() const
+{
+ // Note that |m_image| holds a reference to |m_data| in addition to the one held by the Resource parent class.
+ return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2);
+}
+
+void ImageResource::destroyDecodedDataIfPossible()
+{
+ if (!hasClients() && !isLoading() && (!m_image || (m_image->hasOneRef() && m_image->isBitmapImage()))) {
+ m_image = nullptr;
+ setDecodedSize(0);
+ } else if (m_image && !errorOccurred()) {
+ m_image->destroyDecodedData(true);
+ }
+}
+
void ImageResource::allClientsRemoved()
{
m_pendingContainerSizeRequests.clear();
@@ -272,7 +296,7 @@ void ImageResource::notifyObservers(const IntRect* changeRect)
void ImageResource::clear()
{
- destroyDecodedData();
+ prune();
clearImage();
m_pendingContainerSizeRequests.clear();
setEncodedSize(0);
@@ -346,7 +370,7 @@ void ImageResource::updateImage(bool allDataReceived)
if (sizeAvailable || allDataReceived) {
if (!m_image || m_image->isNull()) {
error(errorOccurred() ? status() : DecodeError);
- if (inCache())
+ if (memoryCache()->contains(this))
memoryCache()->remove(this);
return;
}
@@ -390,20 +414,6 @@ void ImageResource::responseReceived(const ResourceResponse& response)
Resource::responseReceived(response);
}
-void ImageResource::destroyDecodedData()
-{
- bool canDeleteImage = !m_image || (m_image->hasOneRef() && m_image->isBitmapImage());
- if (isSafeToMakePurgeable() && canDeleteImage && !isLoading()) {
- // Image refs the data buffer so we should not make it purgeable while the image is alive.
- // Invoking addClient() will reconstruct the image object.
- m_image = 0;
- setDecodedSize(0);
- makePurgeable(true);
- } else if (m_image && !errorOccurred()) {
- m_image->destroyDecodedData(true);
- }
-}
-
void ImageResource::decodedSizeChanged(const WebCore::Image* image, int delta)
{
if (!image || image != m_image)
@@ -416,12 +426,7 @@ void ImageResource::didDraw(const WebCore::Image* image)
{
if (!image || image != m_image)
return;
-
- double timeStamp = FrameView::currentFrameTimeStamp();
- if (!timeStamp) // If didDraw is called outside of a Frame paint.
- timeStamp = currentTime();
-
- Resource::didAccessDecodedData(timeStamp);
+ Resource::didAccessDecodedData();
}
bool ImageResource::shouldPauseAnimation(const WebCore::Image* image)
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ImageResource.h b/chromium/third_party/WebKit/Source/core/fetch/ImageResource.h
index f04260641db..951af3e57fd 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ImageResource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/ImageResource.h
@@ -41,7 +41,7 @@ class MemoryCache;
class RenderObject;
class SecurityOrigin;
-class ImageResource : public Resource, public ImageObserver {
+class ImageResource FINAL : public Resource, public ImageObserver {
friend class MemoryCache;
public:
@@ -49,9 +49,11 @@ public:
ImageResource(const ResourceRequest&);
ImageResource(WebCore::Image*);
+ // Exposed for testing
+ ImageResource(const ResourceRequest&, WebCore::Image*);
virtual ~ImageResource();
- virtual void load(ResourceFetcher*, const ResourceLoaderOptions&);
+ virtual void load(ResourceFetcher*, const ResourceLoaderOptions&) OVERRIDE;
WebCore::Image* image(); // Returns the nullImage() if the image is not available yet.
WebCore::Image* imageForRenderer(const RenderObject*); // Returns the nullImage() if the image is not available yet.
@@ -61,7 +63,7 @@ public:
static std::pair<WebCore::Image*, float> brokenImage(float deviceScaleFactor); // Returns an image and the image's resolution scale factor.
bool willPaintBrokenImage() const;
- bool canRender(const RenderObject* renderer, float multiplier) { return !errorOccurred() && !imageSizeForRenderer(renderer, multiplier).isEmpty(); }
+ bool canRender(const RenderObject& renderer, float multiplier) { return !errorOccurred() && !imageSizeForRenderer(&renderer, multiplier).isEmpty(); }
void setContainerSizeForRenderer(const ImageResourceClient*, const IntSize&, float);
bool usesImageContainerSize() const;
@@ -81,30 +83,33 @@ public:
bool isAccessAllowed(SecurityOrigin*);
- virtual void didAddClient(ResourceClient*);
- virtual void didRemoveClient(ResourceClient*);
+ virtual void didAddClient(ResourceClient*) OVERRIDE;
+ virtual void didRemoveClient(ResourceClient*) OVERRIDE;
- virtual void allClientsRemoved();
- virtual void destroyDecodedData();
+ virtual void allClientsRemoved() OVERRIDE;
virtual void appendData(const char*, int) OVERRIDE;
- virtual void error(Resource::Status);
- virtual void responseReceived(const ResourceResponse&);
+ virtual void error(Resource::Status) OVERRIDE;
+ virtual void responseReceived(const ResourceResponse&) OVERRIDE;
virtual void finishOnePart() OVERRIDE;
// For compatibility, images keep loading even if there are HTTP errors.
- virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return true; }
+ virtual bool shouldIgnoreHTTPStatusCodeErrors() const OVERRIDE { return true; }
- virtual bool isImage() const { return true; }
+ virtual bool isImage() const OVERRIDE { return true; }
virtual bool stillNeedsLoad() const OVERRIDE { return !errorOccurred() && status() == Unknown && !isLoading(); }
// ImageObserver
- virtual void decodedSizeChanged(const WebCore::Image*, int delta);
- virtual void didDraw(const WebCore::Image*);
+ virtual void decodedSizeChanged(const WebCore::Image*, int delta) OVERRIDE;
+ virtual void didDraw(const WebCore::Image*) OVERRIDE;
- virtual bool shouldPauseAnimation(const WebCore::Image*);
- virtual void animationAdvanced(const WebCore::Image*);
- virtual void changedInRect(const WebCore::Image*, const IntRect&);
+ virtual bool shouldPauseAnimation(const WebCore::Image*) OVERRIDE;
+ virtual void animationAdvanced(const WebCore::Image*) OVERRIDE;
+ virtual void changedInRect(const WebCore::Image*, const IntRect&) OVERRIDE;
+
+protected:
+ virtual bool isSafeToUnlock() const OVERRIDE;
+ virtual void destroyDecodedDataIfPossible() OVERRIDE;
private:
void clear();
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ImageResourceClient.h b/chromium/third_party/WebKit/Source/core/fetch/ImageResourceClient.h
index 900550e618e..b242fc88429 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ImageResourceClient.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/ImageResourceClient.h
@@ -34,7 +34,7 @@ class ImageResourceClient : public ResourceClient {
public:
virtual ~ImageResourceClient() { }
static ResourceClientType expectedType() { return ImageType; }
- virtual ResourceClientType resourceClientType() const { return expectedType(); }
+ virtual ResourceClientType resourceClientType() const OVERRIDE FINAL { return expectedType(); }
// Called whenever a frame of an image changes, either because we got more data from the network or
// because we are animating. If not null, the IntRect is the changed rect of the image.
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp b/chromium/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
index c54767ec5eb..0ec0b39a170 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
@@ -37,6 +37,7 @@
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ResourcePtr.h"
#include "core/loader/DocumentLoader.h"
+#include "core/loader/UniqueIdentifier.h"
#include "core/testing/DummyPageHolder.h"
#include "core/testing/UnitTestHelpers.h"
#include "platform/SharedBuffer.h"
@@ -58,7 +59,7 @@ TEST(ImageResourceTest, MultipartImage)
cachedImage->addClient(&client);
// Send the multipart response. No image or data buffer is created.
- cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, String(), String()));
+ cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String()));
ASSERT_FALSE(cachedImage->resourceBuffer());
ASSERT_FALSE(cachedImage->hasImage());
ASSERT_EQ(client.imageChangedCount(), 0);
@@ -67,7 +68,7 @@ TEST(ImageResourceTest, MultipartImage)
// Send the response for the first real part. No image or data buffer is created.
const char* svgData = "<svg xmlns='http://www.w3.org/2000/svg' width='1' height='1'><rect width='1' height='1' fill='green'/></svg>";
unsigned svgDataLength = strlen(svgData);
- cachedImage->responseReceived(ResourceResponse(KURL(), "image/svg+xml", svgDataLength, String(), String()));
+ cachedImage->responseReceived(ResourceResponse(KURL(), "image/svg+xml", svgDataLength, nullAtom, String()));
ASSERT_FALSE(cachedImage->resourceBuffer());
ASSERT_FALSE(cachedImage->hasImage());
ASSERT_EQ(client.imageChangedCount(), 0);
@@ -100,17 +101,17 @@ TEST(ImageResourceTest, CancelOnDetach)
blink::WebURLResponse response;
response.initialize();
response.setMIMEType("text/html");
- WTF::String localPath = blink::Platform::current()->unitTestSupport()->webKitRootDir();
- localPath.append("/Source/web/tests/data/cancelTest.html");
+ WTF::String localPath = String(blink::Platform::current()->unitTestSupport()->webKitRootDir()) + "/Source/web/tests/data/cancelTest.html";
blink::Platform::current()->unitTestSupport()->registerMockedURL(testURL, response, localPath);
// Create enough of a mocked world to get a functioning ResourceLoader.
OwnPtr<DummyPageHolder> dummyPageHolder = DummyPageHolder::create();
- RefPtr<DocumentLoader> documentLoader = DocumentLoader::create(ResourceRequest(testURL), SubstituteData());
- documentLoader->setFrame(&dummyPageHolder->frame());
+ RefPtr<DocumentLoader> documentLoader = DocumentLoader::create(&dummyPageHolder->frame(), ResourceRequest(testURL), SubstituteData());
// Emulate starting a real load.
ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest(testURL));
+ cachedImage->setIdentifier(createUniqueIdentifier());
+
cachedImage->load(documentLoader->fetcher(), ResourceLoaderOptions());
memoryCache()->add(cachedImage.get());
@@ -131,4 +132,61 @@ TEST(ImageResourceTest, CancelOnDetach)
blink::Platform::current()->unitTestSupport()->unregisterMockedURL(testURL);
}
+TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients)
+{
+ ResourcePtr<ImageResource> cachedImage = new ImageResource(ResourceRequest());
+ cachedImage->setLoading(true);
+
+ MockImageResourceClient client;
+ cachedImage->addClient(&client);
+
+ // Send the image response.
+ cachedImage->responseReceived(ResourceResponse(KURL(), "multipart/x-mixed-replace", 0, nullAtom, String()));
+ static const unsigned char jpegData[] = {
+ 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00,
+ 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
+ 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0xff, 0xdb, 0x00, 0x43,
+ 0x00, 0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06,
+ 0x07, 0x0c, 0x08, 0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09, 0x0c, 0x11, 0x0f, 0x12,
+ 0x12, 0x11, 0x0f, 0x11, 0x11, 0x13, 0x16, 0x1c, 0x17, 0x13, 0x14, 0x1a, 0x15, 0x11, 0x11,
+ 0x18, 0x21, 0x18, 0x1a, 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x13, 0x17, 0x22, 0x24, 0x22, 0x1e,
+ 0x24, 0x1c, 0x1e, 0x1f, 0x1e, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x05, 0x05, 0x05, 0x07, 0x06,
+ 0x07, 0x0e, 0x08, 0x08, 0x0e, 0x1e, 0x14, 0x11, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
+ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0xff,
+ 0xc0, 0x00, 0x11, 0x08, 0x00, 0x01, 0x00, 0x01, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01,
+ 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xc4, 0x00, 0x14,
+ 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc4, 0x00, 0x14, 0x11,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f,
+ 0x00, 0xb2, 0xc0, 0x07, 0xff, 0xd9
+ };
+
+ unsigned jpegDataLength = sizeof(jpegData);
+ cachedImage->responseReceived(ResourceResponse(KURL(), "image/jpeg", jpegDataLength, nullAtom, String()));
+ cachedImage->appendData(reinterpret_cast<const char*>(jpegData), jpegDataLength);
+ cachedImage->finish();
+ ASSERT_FALSE(cachedImage->errorOccurred());
+ ASSERT_TRUE(cachedImage->hasImage());
+ ASSERT_FALSE(cachedImage->image()->isNull());
+ ASSERT_TRUE(client.notifyFinishedCalled());
+
+ // The prune comes when the ImageResource still has clients. The image should not be deleted.
+ cachedImage->prune();
+ ASSERT_TRUE(cachedImage->hasClients());
+ ASSERT_TRUE(cachedImage->hasImage());
+ ASSERT_FALSE(cachedImage->image()->isNull());
+
+ // The ImageResource no longer has clients. The image should be deleted by prune.
+ cachedImage->removeClient(&client);
+ cachedImage->prune();
+ ASSERT_FALSE(cachedImage->hasClients());
+ ASSERT_FALSE(cachedImage->hasImage());
+ ASSERT_TRUE(cachedImage->image()->isNull());
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/fetch/MemoryCache.cpp b/chromium/third_party/WebKit/Source/core/fetch/MemoryCache.cpp
index bdc1df2a4b3..87792916af6 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/MemoryCache.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/MemoryCache.cpp
@@ -41,8 +41,6 @@
#include "wtf/TemporaryChange.h"
#include "wtf/text/CString.h"
-using namespace std;
-
namespace WebCore {
static MemoryCache* gMemoryCache;
@@ -83,7 +81,7 @@ MemoryCache::MemoryCache()
{
#ifdef MEMORY_CACHE_STATS
const double statsIntervalInSeconds = 15;
- m_statsTimer.startRepeating(statsIntervalInSeconds);
+ m_statsTimer.startRepeating(statsIntervalInSeconds, FROM_HERE);
#endif
m_pruneTimeStamp = m_pruneFrameTimeStamp = FrameView::currentFrameTimeStamp();
}
@@ -111,35 +109,51 @@ KURL MemoryCache::removeFragmentIdentifierIfNeeded(const KURL& originalURL)
void MemoryCache::add(Resource* resource)
{
ASSERT(WTF::isMainThread());
- m_resources.set(resource->url(), resource);
- resource->setInCache(true);
- resource->updateForAccess();
+ RELEASE_ASSERT(!m_resources.contains(resource->url()));
+ m_resources.set(resource->url(), MemoryCacheEntry::create(resource));
+ update(resource, 0, resource->size(), true);
WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().string().latin1().data(), resource);
}
void MemoryCache::replace(Resource* newResource, Resource* oldResource)
{
- evict(oldResource);
- ASSERT(!m_resources.get(newResource->url()));
- m_resources.set(newResource->url(), newResource);
- newResource->setInCache(true);
- insertInLRUList(newResource);
- int delta = newResource->size();
+ if (MemoryCacheEntry* oldEntry = m_resources.get(oldResource->url()))
+ evict(oldEntry);
+ add(newResource);
if (newResource->decodedSize() && newResource->hasClients())
- insertInLiveDecodedResourcesList(newResource);
- if (delta)
- adjustSize(newResource->hasClients(), delta);
+ insertInLiveDecodedResourcesList(m_resources.get(newResource->url()));
+}
+
+void MemoryCache::remove(Resource* resource)
+{
+ // The resource may have already been removed by someone other than our caller,
+ // who needed a fresh copy for a reload.
+ if (!contains(resource))
+ return;
+ evict(m_resources.get(resource->url()));
+}
+
+bool MemoryCache::contains(const Resource* resource) const
+{
+ if (resource->url().isNull())
+ return false;
+ const MemoryCacheEntry* entry = m_resources.get(resource->url());
+ return entry && entry->m_resource == resource;
}
Resource* MemoryCache::resourceForURL(const KURL& resourceURL)
{
ASSERT(WTF::isMainThread());
KURL url = removeFragmentIdentifierIfNeeded(resourceURL);
- Resource* resource = m_resources.get(url);
- if (resource && !resource->makePurgeable(false)) {
+ MemoryCacheEntry* entry = m_resources.get(url);
+ if (!entry)
+ return 0;
+ Resource* resource = entry->m_resource.get();
+ if (resource && !resource->lock()) {
ASSERT(!resource->hasClients());
- evict(resource);
+ bool didEvict = evict(entry);
+ ASSERT_UNUSED(didEvict, didEvict);
return 0;
}
return resource;
@@ -148,9 +162,9 @@ Resource* MemoryCache::resourceForURL(const KURL& resourceURL)
size_t MemoryCache::deadCapacity() const
{
// Dead resource capacity is whatever space is not occupied by live resources, bounded by an independent minimum and maximum.
- size_t capacity = m_capacity - min(m_liveSize, m_capacity); // Start with available capacity.
- capacity = max(capacity, m_minDeadCapacity); // Make sure it's above the minimum.
- capacity = min(capacity, m_maxDeadCapacity); // Make sure it's below the maximum.
+ size_t capacity = m_capacity - std::min(m_liveSize, m_capacity); // Start with available capacity.
+ capacity = std::max(capacity, m_minDeadCapacity); // Make sure it's above the minimum.
+ capacity = std::min(capacity, m_maxDeadCapacity); // Make sure it's below the maximum.
return capacity;
}
@@ -180,26 +194,26 @@ void MemoryCache::pruneLiveResources()
// For more details see: https://bugs.webkit.org/show_bug.cgi?id=30209
// Start pruning from the lowest priority list.
- for (int priority = Resource::CacheLiveResourcePriorityLow; priority <= Resource::CacheLiveResourcePriorityHigh; ++priority) {
- Resource* current = m_liveDecodedResources[priority].m_tail;
+ for (int priority = MemoryCacheLiveResourcePriorityLow; priority <= MemoryCacheLiveResourcePriorityHigh; ++priority) {
+ MemoryCacheEntry* current = m_liveDecodedResources[priority].m_tail;
while (current) {
- Resource* prev = current->m_prevInLiveResourcesList;
- ASSERT(current->hasClients());
- if (current->isLoaded() && current->decodedSize()) {
+ MemoryCacheEntry* previous = current->m_previousInLiveResourcesList;
+ ASSERT(current->m_resource->hasClients());
+ if (current->m_resource->isLoaded() && current->m_resource->decodedSize()) {
// Check to see if the remaining resources are too new to prune.
double elapsedTime = m_pruneFrameTimeStamp - current->m_lastDecodedAccessTime;
if (elapsedTime < m_delayBeforeLiveDecodedPrune)
return;
- // Destroy our decoded data. This will remove us from
- // m_liveDecodedResources, and possibly move us to a different LRU
- // list in m_allResources.
- current->destroyDecodedData();
+ // Destroy our decoded data if possible. This will remove us
+ // from m_liveDecodedResources, and possibly move us to a
+ // different LRU list in m_allResources.
+ current->m_resource->prune();
if (targetSize && m_liveSize <= targetSize)
return;
}
- current = prev;
+ current = previous;
}
}
}
@@ -216,15 +230,19 @@ void MemoryCache::pruneDeadResources()
// See if we have any purged resources we can evict.
for (int i = 0; i < size; i++) {
- Resource* current = m_allResources[i].m_tail;
+ MemoryCacheEntry* current = m_allResources[i].m_tail;
while (current) {
- Resource* prev = current->m_prevInAllResourcesList;
- if (current->wasPurged()) {
- ASSERT(!current->hasClients());
- ASSERT(!current->isPreloaded());
- evict(current);
+ MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
+ // Main Resources in the cache are only substitue data that was
+ // precached and should not be evicted.
+ if (current->m_resource->wasPurged() && current->m_resource->canDelete()
+ && current->m_resource->type() != Resource::MainResource) {
+ ASSERT(!current->m_resource->hasClients());
+ ASSERT(!current->m_resource->isPreloaded());
+ bool wasEvicted = evict(current);
+ ASSERT_UNUSED(wasEvicted, wasEvicted);
}
- current = prev;
+ current = previous;
}
}
if (targetSize && m_deadSize <= targetSize)
@@ -233,42 +251,47 @@ void MemoryCache::pruneDeadResources()
bool canShrinkLRULists = true;
for (int i = size - 1; i >= 0; i--) {
// Remove from the tail, since this is the least frequently accessed of the objects.
- Resource* current = m_allResources[i].m_tail;
+ MemoryCacheEntry* current = m_allResources[i].m_tail;
// First flush all the decoded data in this queue.
while (current) {
// Protect 'previous' so it can't get deleted during destroyDecodedData().
- ResourcePtr<Resource> previous = current->m_prevInAllResourcesList;
- ASSERT(!previous || previous->inCache());
- if (!current->hasClients() && !current->isPreloaded() && current->isLoaded()) {
+ MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
+ ASSERT(!previous || contains(previous->m_resource.get()));
+ if (!current->m_resource->hasClients() && !current->m_resource->isPreloaded() && current->m_resource->isLoaded()) {
// Destroy our decoded data. This will remove us from
// m_liveDecodedResources, and possibly move us to a different
// LRU list in m_allResources.
- current->destroyDecodedData();
+ current->m_resource->prune();
if (targetSize && m_deadSize <= targetSize)
return;
}
// Decoded data may reference other resources. Stop iterating if 'previous' somehow got
// kicked out of cache during destroyDecodedData().
- if (previous && !previous->inCache())
+ if (previous && !contains(previous->m_resource.get()))
break;
- current = previous.get();
+ current = previous;
}
// Now evict objects from this queue.
current = m_allResources[i].m_tail;
while (current) {
- ResourcePtr<Resource> previous = current->m_prevInAllResourcesList;
- ASSERT(!previous || previous->inCache());
- if (!current->hasClients() && !current->isPreloaded() && !current->isCacheValidator()) {
- evict(current);
+ MemoryCacheEntry* previous = current->m_previousInAllResourcesList;
+ ASSERT(!previous || contains(previous->m_resource.get()));
+ if (!current->m_resource->hasClients() && !current->m_resource->isPreloaded()
+ && !current->m_resource->isCacheValidator() && current->m_resource->canDelete()
+ && current->m_resource->type() != Resource::MainResource) {
+ // Main Resources in the cache are only substitue data that was
+ // precached and should not be evicted.
+ bool wasEvicted = evict(current);
+ ASSERT_UNUSED(wasEvicted, wasEvicted);
if (targetSize && m_deadSize <= targetSize)
return;
}
- if (previous && !previous->inCache())
+ if (previous && !contains(previous->m_resource.get()))
break;
- current = previous.get();
+ current = previous;
}
// Shrink the vector back down so we don't waste time inspecting
@@ -291,60 +314,42 @@ void MemoryCache::setCapacities(size_t minDeadBytes, size_t maxDeadBytes, size_t
prune();
}
-void MemoryCache::evict(Resource* resource)
+bool MemoryCache::evict(MemoryCacheEntry* entry)
{
ASSERT(WTF::isMainThread());
+
+ Resource* resource = entry->m_resource.get();
+ bool canDelete = resource->canDelete();
WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().string().latin1().data());
// The resource may have already been removed by someone other than our caller,
// who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>.
- if (resource->inCache()) {
- // Remove from the resource map.
- m_resources.remove(resource->url());
- resource->setInCache(false);
-
- // Remove from the appropriate LRU list.
- removeFromLRUList(resource);
- removeFromLiveDecodedResourcesList(resource);
- adjustSize(resource->hasClients(), -static_cast<ptrdiff_t>(resource->size()));
- } else {
- ASSERT(m_resources.get(resource->url()) != resource);
- }
+ update(resource, resource->size(), 0, false);
+ removeFromLiveDecodedResourcesList(entry);
- resource->deleteIfPossible();
+ ResourceMap::iterator it = m_resources.find(resource->url());
+ ASSERT(it != m_resources.end());
+ OwnPtr<MemoryCacheEntry> entryPtr;
+ entryPtr.swap(it->value);
+ m_resources.remove(it);
+ return canDelete;
}
-MemoryCache::LRUList* MemoryCache::lruListFor(Resource* resource)
+MemoryCache::LRUList* MemoryCache::lruListFor(unsigned accessCount, size_t size)
{
- unsigned accessCount = max(resource->accessCount(), 1U);
- unsigned queueIndex = WTF::fastLog2(resource->size() / accessCount);
-#ifndef NDEBUG
- resource->m_lruIndex = queueIndex;
-#endif
+ ASSERT(accessCount > 0);
+ unsigned queueIndex = WTF::fastLog2(size / accessCount);
if (m_allResources.size() <= queueIndex)
m_allResources.grow(queueIndex + 1);
return &m_allResources[queueIndex];
}
-void MemoryCache::removeFromLRUList(Resource* resource)
+void MemoryCache::removeFromLRUList(MemoryCacheEntry* entry, LRUList* list)
{
- // If we've never been accessed, then we're brand new and not in any list.
- if (!resource->accessCount())
- return;
-
-#if !ASSERT_DISABLED
- unsigned oldListIndex = resource->m_lruIndex;
-#endif
-
- LRUList* list = lruListFor(resource);
-
-#if !ASSERT_DISABLED
- // Verify that the list we got is the list we want.
- ASSERT(resource->m_lruIndex == oldListIndex);
-
+#if ASSERT_ENABLED
// Verify that we are in fact in this list.
bool found = false;
- for (Resource* current = list->m_head; current; current = current->m_nextInAllResourcesList) {
- if (current == resource) {
+ for (MemoryCacheEntry* current = list->m_head; current; current = current->m_nextInAllResourcesList) {
+ if (current == entry) {
found = true;
break;
}
@@ -352,72 +357,61 @@ void MemoryCache::removeFromLRUList(Resource* resource)
ASSERT(found);
#endif
- Resource* next = resource->m_nextInAllResourcesList;
- Resource* prev = resource->m_prevInAllResourcesList;
-
- if (!next && !prev && list->m_head != resource)
- return;
-
- resource->m_nextInAllResourcesList = 0;
- resource->m_prevInAllResourcesList = 0;
+ MemoryCacheEntry* next = entry->m_nextInAllResourcesList;
+ MemoryCacheEntry* previous = entry->m_previousInAllResourcesList;
+ entry->m_nextInAllResourcesList = 0;
+ entry->m_previousInAllResourcesList = 0;
if (next)
- next->m_prevInAllResourcesList = prev;
- else if (list->m_tail == resource)
- list->m_tail = prev;
+ next->m_previousInAllResourcesList = previous;
+ else
+ list->m_tail = previous;
- if (prev)
- prev->m_nextInAllResourcesList = next;
- else if (list->m_head == resource)
+ if (previous)
+ previous->m_nextInAllResourcesList = next;
+ else
list->m_head = next;
}
-void MemoryCache::insertInLRUList(Resource* resource)
+void MemoryCache::insertInLRUList(MemoryCacheEntry* entry, LRUList* list)
{
- // Make sure we aren't in some list already.
- ASSERT(!resource->m_nextInAllResourcesList && !resource->m_prevInAllResourcesList);
- ASSERT(resource->inCache());
- ASSERT(resource->accessCount() > 0);
-
- LRUList* list = lruListFor(resource);
+ ASSERT(!entry->m_nextInAllResourcesList && !entry->m_previousInAllResourcesList);
- resource->m_nextInAllResourcesList = list->m_head;
- if (list->m_head)
- list->m_head->m_prevInAllResourcesList = resource;
- list->m_head = resource;
+ entry->m_nextInAllResourcesList = list->m_head;
+ list->m_head = entry;
- if (!resource->m_nextInAllResourcesList)
- list->m_tail = resource;
+ if (entry->m_nextInAllResourcesList)
+ entry->m_nextInAllResourcesList->m_previousInAllResourcesList = entry;
+ else
+ list->m_tail = entry;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
// Verify that we are in now in the list like we should be.
- list = lruListFor(resource);
bool found = false;
- for (Resource* current = list->m_head; current; current = current->m_nextInAllResourcesList) {
- if (current == resource) {
+ for (MemoryCacheEntry* current = list->m_head; current; current = current->m_nextInAllResourcesList) {
+ if (current == entry) {
found = true;
break;
}
}
ASSERT(found);
#endif
-
}
-void MemoryCache::removeFromLiveDecodedResourcesList(Resource* resource)
+void MemoryCache::removeFromLiveDecodedResourcesList(MemoryCacheEntry* entry)
{
// If we've never been accessed, then we're brand new and not in any list.
- if (!resource->m_inLiveDecodedResourcesList)
+ if (!entry->m_inLiveDecodedResourcesList)
return;
- resource->m_inLiveDecodedResourcesList = false;
+ entry->m_inLiveDecodedResourcesList = false;
- LRUList* list = &m_liveDecodedResources[resource->cacheLiveResourcePriority()];
+ LRUList* list = &m_liveDecodedResources[entry->m_liveResourcePriority];
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
// Verify that we are in fact in this list.
bool found = false;
- for (Resource* current = list->m_head; current; current = current->m_nextInLiveResourcesList) {
- if (current == resource) {
+ for (MemoryCacheEntry* current = list->m_head; current; current = current->m_nextInLiveResourcesList) {
+ if (current == entry) {
found = true;
break;
}
@@ -425,72 +419,86 @@ void MemoryCache::removeFromLiveDecodedResourcesList(Resource* resource)
ASSERT(found);
#endif
- Resource* next = resource->m_nextInLiveResourcesList;
- Resource* prev = resource->m_prevInLiveResourcesList;
-
- if (!next && !prev && list->m_head != resource)
- return;
+ MemoryCacheEntry* next = entry->m_nextInLiveResourcesList;
+ MemoryCacheEntry* previous = entry->m_previousInLiveResourcesList;
- resource->m_nextInLiveResourcesList = 0;
- resource->m_prevInLiveResourcesList = 0;
+ entry->m_nextInLiveResourcesList = 0;
+ entry->m_previousInLiveResourcesList = 0;
if (next)
- next->m_prevInLiveResourcesList = prev;
- else if (list->m_tail == resource)
- list->m_tail = prev;
+ next->m_previousInLiveResourcesList = previous;
+ else
+ list->m_tail = previous;
- if (prev)
- prev->m_nextInLiveResourcesList = next;
- else if (list->m_head == resource)
+ if (previous)
+ previous->m_nextInLiveResourcesList = next;
+ else
list->m_head = next;
}
-void MemoryCache::insertInLiveDecodedResourcesList(Resource* resource)
+void MemoryCache::insertInLiveDecodedResourcesList(MemoryCacheEntry* entry)
{
// Make sure we aren't in the list already.
- ASSERT(!resource->m_nextInLiveResourcesList && !resource->m_prevInLiveResourcesList && !resource->m_inLiveDecodedResourcesList);
- resource->m_inLiveDecodedResourcesList = true;
+ ASSERT(!entry->m_nextInLiveResourcesList && !entry->m_previousInLiveResourcesList && !entry->m_inLiveDecodedResourcesList);
+ entry->m_inLiveDecodedResourcesList = true;
- LRUList* list = &m_liveDecodedResources[resource->cacheLiveResourcePriority()];
- resource->m_nextInLiveResourcesList = list->m_head;
+ LRUList* list = &m_liveDecodedResources[entry->m_liveResourcePriority];
+ entry->m_nextInLiveResourcesList = list->m_head;
if (list->m_head)
- list->m_head->m_prevInLiveResourcesList = resource;
- list->m_head = resource;
+ list->m_head->m_previousInLiveResourcesList = entry;
+ list->m_head = entry;
- if (!resource->m_nextInLiveResourcesList)
- list->m_tail = resource;
+ if (!entry->m_nextInLiveResourcesList)
+ list->m_tail = entry;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
// Verify that we are in now in the list like we should be.
bool found = false;
- for (Resource* current = list->m_head; current; current = current->m_nextInLiveResourcesList) {
- if (current == resource) {
+ for (MemoryCacheEntry* current = list->m_head; current; current = current->m_nextInLiveResourcesList) {
+ if (current == entry) {
found = true;
break;
}
}
ASSERT(found);
#endif
-
}
-void MemoryCache::addToLiveResourcesSize(Resource* resource)
+void MemoryCache::makeLive(Resource* resource)
{
+ if (!contains(resource))
+ return;
ASSERT(m_deadSize >= resource->size());
m_liveSize += resource->size();
m_deadSize -= resource->size();
}
-void MemoryCache::removeFromLiveResourcesSize(Resource* resource)
+void MemoryCache::makeDead(Resource* resource)
{
- ASSERT(m_liveSize >= resource->size());
+ if (!contains(resource))
+ return;
m_liveSize -= resource->size();
m_deadSize += resource->size();
+ removeFromLiveDecodedResourcesList(m_resources.get(resource->url()));
}
-void MemoryCache::adjustSize(bool live, ptrdiff_t delta)
+void MemoryCache::update(Resource* resource, size_t oldSize, size_t newSize, bool wasAccessed)
{
- if (live) {
+ if (!contains(resource))
+ return;
+ MemoryCacheEntry* entry = m_resources.get(resource->url());
+
+ // The object must now be moved to a different queue, since either its size or its accessCount has been changed,
+ // and both of those are used to determine which LRU queue the resource should be in.
+ if (oldSize)
+ removeFromLRUList(entry, lruListFor(entry->m_accessCount, oldSize));
+ if (wasAccessed)
+ entry->m_accessCount++;
+ if (newSize)
+ insertInLRUList(entry, lruListFor(entry->m_accessCount, newSize));
+
+ ptrdiff_t delta = newSize - oldSize;
+ if (resource->hasClients()) {
ASSERT(delta >= 0 || m_liveSize >= static_cast<size_t>(-delta) );
m_liveSize += delta;
} else {
@@ -499,6 +507,35 @@ void MemoryCache::adjustSize(bool live, ptrdiff_t delta)
}
}
+void MemoryCache::updateDecodedResource(Resource* resource, UpdateReason reason, MemoryCacheLiveResourcePriority priority)
+{
+ if (!contains(resource))
+ return;
+ MemoryCacheEntry* entry = m_resources.get(resource->url());
+
+ removeFromLiveDecodedResourcesList(entry);
+ if (priority != MemoryCacheLiveResourcePriorityUnknown && priority != entry->m_liveResourcePriority)
+ entry->m_liveResourcePriority = priority;
+ if (resource->decodedSize() && resource->hasClients())
+ insertInLiveDecodedResourcesList(entry);
+
+ if (reason != UpdateForAccess)
+ return;
+
+ double timestamp = resource->isImage() ? FrameView::currentFrameTimeStamp() : 0.0;
+ if (!timestamp)
+ timestamp = currentTime();
+ entry->m_lastDecodedAccessTime = timestamp;
+}
+
+MemoryCacheLiveResourcePriority MemoryCache::priority(Resource* resource) const
+{
+ if (!contains(resource))
+ return MemoryCacheLiveResourcePriorityUnknown;
+ MemoryCacheEntry* entry = m_resources.get(resource->url());
+ return entry->m_liveResourcePriority;
+}
+
void MemoryCache::removeURLFromCache(ExecutionContext* context, const KURL& url)
{
if (context->isWorkerGlobalScope()) {
@@ -535,7 +572,7 @@ MemoryCache::Statistics MemoryCache::getStatistics()
Statistics stats;
ResourceMap::iterator e = m_resources.end();
for (ResourceMap::iterator i = m_resources.begin(); i != e; ++i) {
- Resource* resource = i->value;
+ Resource* resource = i->value->m_resource.get();
switch (resource->type()) {
case Resource::Image:
stats.images.addResource(resource);
@@ -566,7 +603,7 @@ void MemoryCache::evictResources()
ResourceMap::iterator i = m_resources.begin();
if (i == m_resources.end())
break;
- evict(i->value);
+ evict(i->value.get());
}
}
@@ -608,7 +645,10 @@ void MemoryCache::prune(Resource* justReleasedResource)
// objects O(N^2) if we pruned immediately. This immediate eviction is a
// safeguard against runaway memory consumption by dead resources
// while a prune is pending.
- evict(justReleasedResource);
+ // Main Resources in the cache are only substitue data that was
+ // precached and should not be evicted.
+ if (contains(justReleasedResource) && justReleasedResource->type() != Resource::MainResource)
+ evict(m_resources.get(justReleasedResource->url()));
// As a last resort, prune immediately
if (m_deadSize > m_maxDeferredPruneDeadCapacity)
diff --git a/chromium/third_party/WebKit/Source/core/fetch/MemoryCache.h b/chromium/third_party/WebKit/Source/core/fetch/MemoryCache.h
index 7944256513d..1d594e2c920 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/MemoryCache.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/MemoryCache.h
@@ -26,6 +26,7 @@
#define MemoryCache_h
#include "core/fetch/Resource.h"
+#include "core/fetch/ResourcePtr.h"
#include "public/platform/WebThread.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
@@ -59,17 +60,58 @@ struct SecurityOriginHash;
// Enable this macro to periodically log information about the memory cache.
#undef MEMORY_CACHE_STATS
-class MemoryCache : public blink::WebThread::TaskObserver {
+// Determines the order in which CachedResources are evicted
+// from the decoded resources cache.
+enum MemoryCacheLiveResourcePriority {
+ MemoryCacheLiveResourcePriorityLow = 0,
+ MemoryCacheLiveResourcePriorityHigh,
+ MemoryCacheLiveResourcePriorityUnknown
+};
+
+enum UpdateReason {
+ UpdateForAccess,
+ UpdateForPropertyChange
+};
+
+class MemoryCache FINAL : public blink::WebThread::TaskObserver {
WTF_MAKE_NONCOPYABLE(MemoryCache); WTF_MAKE_FAST_ALLOCATED;
public:
MemoryCache();
virtual ~MemoryCache();
- typedef HashMap<String, Resource*> ResourceMap;
+ class MemoryCacheEntry {
+ public:
+ static PassOwnPtr<MemoryCacheEntry> create(Resource* resource) { return adoptPtr(new MemoryCacheEntry(resource)); }
+
+ ResourcePtr<Resource> m_resource;
+ bool m_inLiveDecodedResourcesList;
+ unsigned m_accessCount;
+ MemoryCacheLiveResourcePriority m_liveResourcePriority;
+ double m_lastDecodedAccessTime; // Used as a thrash guard
+
+ MemoryCacheEntry* m_previousInLiveResourcesList;
+ MemoryCacheEntry* m_nextInLiveResourcesList;
+ MemoryCacheEntry* m_previousInAllResourcesList;
+ MemoryCacheEntry* m_nextInAllResourcesList;
+
+ private:
+ MemoryCacheEntry(Resource* resource)
+ : m_resource(resource)
+ , m_inLiveDecodedResourcesList(false)
+ , m_accessCount(0)
+ , m_liveResourcePriority(MemoryCacheLiveResourcePriorityLow)
+ , m_lastDecodedAccessTime(0.0)
+ , m_previousInLiveResourcesList(0)
+ , m_nextInLiveResourcesList(0)
+ , m_previousInAllResourcesList(0)
+ , m_nextInAllResourcesList(0)
+ {
+ }
+ };
struct LRUList {
- Resource* m_head;
- Resource* m_tail;
+ MemoryCacheEntry* m_head;
+ MemoryCacheEntry* m_tail;
LRUList() : m_head(0), m_tail(0) { }
};
@@ -111,7 +153,8 @@ public:
void add(Resource*);
void replace(Resource* newResource, Resource* oldResource);
- void remove(Resource* resource) { evict(resource); }
+ void remove(Resource*);
+ bool contains(const Resource*) const;
static KURL removeFragmentIdentifierIfNeeded(const KURL& originalURL);
@@ -128,19 +171,13 @@ public:
void prune(Resource* justReleasedResource = 0);
- // Calls to put the cached resource into and out of LRU lists.
- void insertInLRUList(Resource*);
- void removeFromLRUList(Resource*);
-
- // Called to adjust the cache totals when a resource changes size.
- void adjustSize(bool live, ptrdiff_t delta);
-
- // Track decoded resources that are in the cache and referenced by a Web page.
- void insertInLiveDecodedResourcesList(Resource*);
- void removeFromLiveDecodedResourcesList(Resource*);
+ // Called to adjust a resource's size, lru list position, and access count.
+ void update(Resource*, size_t oldSize, size_t newSize, bool wasAccessed = false);
+ void updateForAccess(Resource* resource) { update(resource, resource->size(), resource->size(), true); }
+ void updateDecodedResource(Resource*, UpdateReason, MemoryCacheLiveResourcePriority = MemoryCacheLiveResourcePriorityUnknown);
- void addToLiveResourcesSize(Resource*);
- void removeFromLiveResourcesSize(Resource*);
+ void makeLive(Resource*);
+ void makeDead(Resource*);
static void removeURLFromCache(ExecutionContext*, const KURL&);
@@ -152,18 +189,29 @@ public:
size_t liveSize() const { return m_liveSize; }
size_t deadSize() const { return m_deadSize; }
+ // Exposed for testing
+ MemoryCacheLiveResourcePriority priority(Resource*) const;
+
// TaskObserver implementation
virtual void willProcessTask() OVERRIDE;
virtual void didProcessTask() OVERRIDE;
private:
- LRUList* lruListFor(Resource*);
+ LRUList* lruListFor(unsigned accessCount, size_t);
#ifdef MEMORY_CACHE_STATS
void dumpStats(Timer<MemoryCache>*);
void dumpLRULists(bool includeLive) const;
#endif
+ // Calls to put the cached resource into and out of LRU lists.
+ void insertInLRUList(MemoryCacheEntry*, LRUList*);
+ void removeFromLRUList(MemoryCacheEntry*, LRUList*);
+
+ // Track decoded resources that are in the cache and referenced by a Web page.
+ void insertInLiveDecodedResourcesList(MemoryCacheEntry*);
+ void removeFromLiveDecodedResourcesList(MemoryCacheEntry*);
+
size_t liveCapacity() const;
size_t deadCapacity() const;
@@ -173,13 +221,12 @@ private:
void pruneLiveResources();
void pruneNow(double currentTime);
- void evict(Resource*);
+ bool evict(MemoryCacheEntry*);
static void removeURLFromCacheInternal(ExecutionContext*, const KURL&);
bool m_inPruneResources;
bool m_prunePending;
- bool m_prePainting;
double m_maxPruneDeferralDelay;
double m_pruneTimeStamp;
double m_pruneFrameTimeStamp;
@@ -189,7 +236,6 @@ private:
size_t m_maxDeadCapacity;
size_t m_maxDeferredPruneDeadCapacity;
double m_delayBeforeLiveDecodedPrune;
- double m_deadDecodedDataDeletionInterval;
size_t m_liveSize; // The number of bytes currently consumed by "live" resources in the cache.
size_t m_deadSize; // The number of bytes currently consumed by "dead" resources in the cache.
@@ -201,11 +247,12 @@ private:
// Lists just for live resources with decoded data. Access to this list is based off of painting the resource.
// The lists are ordered by decode priority, with higher indices having higher priorities.
- LRUList m_liveDecodedResources[Resource::CacheLiveResourcePriorityHigh + 1];
+ LRUList m_liveDecodedResources[MemoryCacheLiveResourcePriorityHigh + 1];
// A URL-based map of all resources that are in the cache (including the freshest version of objects that are currently being
// referenced by a Web page).
- HashMap<String, Resource*> m_resources;
+ typedef HashMap<String, OwnPtr<MemoryCacheEntry> > ResourceMap;
+ ResourceMap m_resources;
friend class MemoryCacheTest;
#ifdef MEMORY_CACHE_STATS
diff --git a/chromium/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp b/chromium/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp
index 90fecd0ca2e..387ec73871d 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/MemoryCacheTest.cpp
@@ -57,7 +57,8 @@ public:
setDecodedSize(this->size());
}
- virtual void destroyDecodedData()
+ protected:
+ virtual void destroyDecodedDataIfPossible() OVERRIDE
{
setDecodedSize(0);
}
@@ -152,7 +153,7 @@ TEST_F(MemoryCacheTest, DeadResourceEviction)
const unsigned maxDeadCapacity = 0;
memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity);
- ResourcePtr<Resource> cachedResource =
+ Resource* cachedResource =
new Resource(ResourceRequest(""), Resource::Raw);
const char data[5] = "abcd";
cachedResource->appendData(data, 3);
@@ -163,7 +164,7 @@ TEST_F(MemoryCacheTest, DeadResourceEviction)
ASSERT_EQ(0u, memoryCache()->deadSize());
ASSERT_EQ(0u, memoryCache()->liveSize());
- memoryCache()->add(cachedResource.get());
+ memoryCache()->add(cachedResource);
ASSERT_EQ(cachedResource->size(), memoryCache()->deadSize());
ASSERT_EQ(0u, memoryCache()->liveSize());
@@ -182,8 +183,8 @@ TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask)
const unsigned maxDeadCapacity = 0;
memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity);
const char data[6] = "abcde";
- ResourcePtr<Resource> cachedDeadResource =
- new Resource(ResourceRequest(""), Resource::Raw);
+ Resource* cachedDeadResource =
+ new Resource(ResourceRequest("hhtp://foo"), Resource::Raw);
cachedDeadResource->appendData(data, 3);
ResourcePtr<Resource> cachedLiveResource =
new FakeDecodedResource(ResourceRequest(""), Resource::Raw);
@@ -193,7 +194,7 @@ TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask)
class Task1 : public blink::WebThread::Task {
public:
- Task1(const ResourcePtr<Resource>& live, const ResourcePtr<Resource>& dead)
+ Task1(const ResourcePtr<Resource>& live, Resource* dead)
: m_live(live)
, m_dead(dead)
{ }
@@ -208,9 +209,9 @@ TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask)
ASSERT_EQ(0u, memoryCache()->deadSize());
ASSERT_EQ(0u, memoryCache()->liveSize());
- memoryCache()->add(m_dead.get());
+ memoryCache()->add(m_dead);
memoryCache()->add(m_live.get());
- memoryCache()->insertInLiveDecodedResourcesList(m_live.get());
+ memoryCache()->updateDecodedResource(m_live.get(), UpdateForPropertyChange);
ASSERT_EQ(m_dead->size(), memoryCache()->deadSize());
ASSERT_EQ(m_live->size(), memoryCache()->liveSize());
ASSERT_GT(m_live->decodedSize(), 0u);
@@ -222,7 +223,8 @@ TEST_F(MemoryCacheTest, LiveResourceEvictionAtEndOfTask)
}
private:
- ResourcePtr<Resource> m_live, m_dead;
+ ResourcePtr<Resource> m_live;
+ Resource* m_dead;
};
class Task2 : public blink::WebThread::Task {
@@ -255,7 +257,7 @@ TEST_F(MemoryCacheTest, ClientRemoval)
{
const char data[6] = "abcde";
ResourcePtr<Resource> resource1 =
- new FakeDecodedResource(ResourceRequest(""), Resource::Raw);
+ new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw);
MockImageResourceClient client1;
resource1->addClient(&client1);
resource1->appendData(data, 4);
@@ -266,7 +268,7 @@ TEST_F(MemoryCacheTest, ClientRemoval)
resource2->appendData(data, 4);
const unsigned minDeadCapacity = 0;
- const unsigned maxDeadCapacity = resource1->size() - 1;
+ const unsigned maxDeadCapacity = ((resource1->size() + resource2->size()) / 2) - 1;
const unsigned totalCapacity = maxDeadCapacity;
memoryCache()->setCapacities(minDeadCapacity, maxDeadCapacity, totalCapacity);
memoryCache()->add(resource1.get());
@@ -286,8 +288,8 @@ TEST_F(MemoryCacheTest, ClientRemoval)
ASSERT_GT(resource2->decodedSize(), 0u);
ASSERT_EQ(memoryCache()->deadSize(), resource1->size());
ASSERT_EQ(memoryCache()->liveSize(), resource2->size());
- ASSERT_TRUE(resource1->inCache());
- ASSERT_TRUE(resource2->inCache());
+ ASSERT_TRUE(memoryCache()->contains(resource1.get()));
+ ASSERT_TRUE(memoryCache()->contains(resource2.get()));
// Removing the client from resource2 should result in immediate
// eviction of resource2 because we are over the prune deferral limit.
@@ -296,8 +298,8 @@ TEST_F(MemoryCacheTest, ClientRemoval)
ASSERT_GT(resource2->decodedSize(), 0u);
ASSERT_EQ(memoryCache()->deadSize(), resource1->size());
ASSERT_EQ(memoryCache()->liveSize(), 0u);
- ASSERT_TRUE(resource1->inCache());
- ASSERT_FALSE(resource2->inCache());
+ ASSERT_TRUE(memoryCache()->contains(resource1.get()));
+ ASSERT_FALSE(memoryCache()->contains(resource2.get()));
}
// Verifies that CachedResources are evicted from the decode cache
@@ -307,7 +309,7 @@ TEST_F(MemoryCacheTest, DecodeCacheOrder)
memoryCache()->setDelayBeforeLiveDecodedPrune(0);
memoryCache()->setMaxPruneDeferralDelay(0);
ResourcePtr<FakeDecodedResource> cachedImageLowPriority =
- new FakeDecodedResource(ResourceRequest(""), Resource::Raw);
+ new FakeDecodedResource(ResourceRequest("http://foo.com"), Resource::Raw);
ResourcePtr<FakeDecodedResource> cachedImageHighPriority =
new FakeDecodedResource(ResourceRequest(""), Resource::Raw);
@@ -344,14 +346,14 @@ TEST_F(MemoryCacheTest, DecodeCacheOrder)
ASSERT_EQ(memoryCache()->liveSize(), highPrioritySize + lowPrioritySize);
// Insert all items in the decoded items list with the same priority
- memoryCache()->insertInLiveDecodedResourcesList(cachedImageHighPriority.get());
- memoryCache()->insertInLiveDecodedResourcesList(cachedImageLowPriority.get());
+ memoryCache()->updateDecodedResource(cachedImageHighPriority.get(), UpdateForPropertyChange);
+ memoryCache()->updateDecodedResource(cachedImageLowPriority.get(), UpdateForPropertyChange);
ASSERT_EQ(memoryCache()->deadSize(), 0u);
ASSERT_EQ(memoryCache()->liveSize(), totalSize);
// Now we will assign their priority and make sure they are moved to the correct buckets.
- cachedImageLowPriority->setCacheLiveResourcePriority(Resource::CacheLiveResourcePriorityLow);
- cachedImageHighPriority->setCacheLiveResourcePriority(Resource::CacheLiveResourcePriorityHigh);
+ memoryCache()->updateDecodedResource(cachedImageLowPriority.get(), UpdateForPropertyChange, MemoryCacheLiveResourcePriorityLow);
+ memoryCache()->updateDecodedResource(cachedImageHighPriority.get(), UpdateForPropertyChange, MemoryCacheLiveResourcePriorityHigh);
// Should first prune the LowPriority item.
memoryCache()->setCapacities(memoryCache()->minDeadCapacity(), memoryCache()->liveSize() - 10, memoryCache()->liveSize() - 10);
@@ -365,4 +367,44 @@ TEST_F(MemoryCacheTest, DecodeCacheOrder)
ASSERT_EQ(memoryCache()->deadSize(), 0u);
ASSERT_EQ(memoryCache()->liveSize(), totalSize - lowPriorityMockDecodeSize - highPriorityMockDecodeSize);
}
+
+TEST_F(MemoryCacheTest, MultipleReplace)
+{
+ ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest(""), Resource::Raw);
+ memoryCache()->add(resource1.get());
+
+ ResourcePtr<FakeResource> resource2 = new FakeResource(ResourceRequest(""), Resource::Raw);
+ memoryCache()->replace(resource2.get(), resource1.get());
+ EXPECT_TRUE(memoryCache()->contains(resource2.get()));
+ EXPECT_FALSE(memoryCache()->contains(resource1.get()));
+
+ ResourcePtr<FakeResource> resource3 = new FakeResource(ResourceRequest(""), Resource::Raw);
+ memoryCache()->replace(resource3.get(), resource2.get());
+ EXPECT_TRUE(memoryCache()->contains(resource3.get()));
+ EXPECT_FALSE(memoryCache()->contains(resource2.get()));
+}
+
+TEST_F(MemoryCacheTest, RemoveDuringRevalidation)
+{
+ ResourcePtr<FakeResource> resource1 = new FakeResource(ResourceRequest(""), Resource::Raw);
+ memoryCache()->add(resource1.get());
+
+ ResourcePtr<FakeResource> resource2 = new FakeResource(ResourceRequest(""), Resource::Raw);
+ memoryCache()->remove(resource1.get());
+ memoryCache()->add(resource2.get());
+ EXPECT_TRUE(memoryCache()->contains(resource2.get()));
+ EXPECT_FALSE(memoryCache()->contains(resource1.get()));
+
+ ResourcePtr<FakeResource> resource3 = new FakeResource(ResourceRequest(""), Resource::Raw);
+ memoryCache()->remove(resource2.get());
+ memoryCache()->add(resource3.get());
+ EXPECT_TRUE(memoryCache()->contains(resource3.get()));
+ EXPECT_FALSE(memoryCache()->contains(resource2.get()));
+
+ memoryCache()->replace(resource1.get(), resource2.get());
+ EXPECT_TRUE(memoryCache()->contains(resource1.get()));
+ EXPECT_FALSE(memoryCache()->contains(resource2.get()));
+ EXPECT_FALSE(memoryCache()->contains(resource3.get()));
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h b/chromium/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h
index 44993966cdd..be1867d48c2 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/MockImageResourceClient.h
@@ -37,7 +37,7 @@
namespace WebCore {
-class MockImageResourceClient : public WebCore::ImageResourceClient {
+class MockImageResourceClient FINAL : public WebCore::ImageResourceClient {
public:
MockImageResourceClient()
: m_imageChangedCount(0)
@@ -46,12 +46,12 @@ public:
}
virtual ~MockImageResourceClient() { }
- virtual void imageChanged(ImageResource*, const IntRect*)
+ virtual void imageChanged(ImageResource*, const IntRect*) OVERRIDE
{
m_imageChangedCount++;
}
- virtual void notifyFinished(Resource*)
+ virtual void notifyFinished(Resource*) OVERRIDE
{
ASSERT_FALSE(m_notifyFinishedCalled);
m_notifyFinishedCalled = true;
diff --git a/chromium/third_party/WebKit/Source/core/fetch/RawResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/RawResource.cpp
index c58b8440f54..d6379b10315 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/RawResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/RawResource.cpp
@@ -57,15 +57,15 @@ void RawResource::didAddClient(ResourceClient* c)
// so a protector is necessary.
ResourcePtr<RawResource> protect(this);
RawResourceClient* client = static_cast<RawResourceClient*>(c);
- size_t redirectCount = m_redirectChain.size();
+ size_t redirectCount = redirectChain().size();
for (size_t i = 0; i < redirectCount; i++) {
- RedirectPair redirect = m_redirectChain[i];
+ RedirectPair redirect = redirectChain()[i];
ResourceRequest request(redirect.m_request);
client->redirectReceived(this, request, redirect.m_redirectResponse);
if (!hasClient(c))
return;
}
- ASSERT(redirectCount == m_redirectChain.size());
+ ASSERT(redirectCount == redirectChain().size());
if (!m_response.isNull())
client->responseReceived(this, m_response);
@@ -85,11 +85,18 @@ void RawResource::willSendRequest(ResourceRequest& request, const ResourceRespon
ResourceClientWalker<RawResourceClient> w(m_clients);
while (RawResourceClient* c = w.next())
c->redirectReceived(this, request, response);
- m_redirectChain.append(RedirectPair(request, response));
}
Resource::willSendRequest(request, response);
}
+void RawResource::updateRequest(const ResourceRequest& request)
+{
+ ResourcePtr<RawResource> protect(this);
+ ResourceClientWalker<RawResourceClient> w(m_clients);
+ while (RawResourceClient* c = w.next())
+ c->updateRequest(this, request);
+}
+
void RawResource::responseReceived(const ResourceResponse& response)
{
InternalResourcePtr protect(this);
@@ -119,12 +126,6 @@ void RawResource::setDefersLoading(bool defers)
m_loader->setDefersLoading(defers);
}
-void RawResource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
-{
- m_options.dataBufferingPolicy = dataBufferingPolicy;
- clear();
-}
-
static bool shouldIgnoreHeaderForCacheReuse(AtomicString headerName)
{
// FIXME: This list of headers that don't affect cache policy almost certainly isn't complete.
@@ -142,18 +143,27 @@ static bool shouldIgnoreHeaderForCacheReuse(AtomicString headerName)
return m_headers.contains(headerName);
}
+static bool isCacheableHTTPMethod(const AtomicString& method)
+{
+ // Per http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10,
+ // these methods always invalidate the cache entry.
+ return method != "POST" && method != "PUT" && method != "DELETE";
+}
+
bool RawResource::canReuse(const ResourceRequest& newRequest) const
{
if (m_options.dataBufferingPolicy == DoNotBufferData)
return false;
+ if (!isCacheableHTTPMethod(m_resourceRequest.httpMethod()))
+ return false;
if (m_resourceRequest.httpMethod() != newRequest.httpMethod())
return false;
if (m_resourceRequest.httpBody() != newRequest.httpBody())
return false;
- if (m_resourceRequest.allowCookies() != newRequest.allowCookies())
+ if (m_resourceRequest.allowStoredCredentials() != newRequest.allowStoredCredentials())
return false;
// Ensure most headers match the existing headers before continuing.
@@ -177,18 +187,7 @@ bool RawResource::canReuse(const ResourceRequest& newRequest) const
return false;
}
- for (size_t i = 0; i < m_redirectChain.size(); i++) {
- if (m_redirectChain[i].m_redirectResponse.cacheControlContainsNoStore())
- return false;
- }
-
return true;
}
-void RawResource::clear()
-{
- m_data.clear();
- setEncodedSize(0);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fetch/RawResource.h b/chromium/third_party/WebKit/Source/core/fetch/RawResource.h
index e1b6753e0c9..10bae27deb1 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/RawResource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/RawResource.h
@@ -30,7 +30,7 @@ namespace WebCore {
class RawResourceCallback;
class RawResourceClient;
-class RawResource : public Resource {
+class RawResource FINAL : public Resource {
public:
typedef RawResourceClient ClientType;
@@ -39,45 +39,28 @@ public:
// FIXME: AssociatedURLLoader shouldn't be a DocumentThreadableLoader and therefore shouldn't
// use RawResource. However, it is, and it needs to be able to defer loading.
// This can be fixed by splitting CORS preflighting out of DocumentThreacableLoader.
- virtual void setDefersLoading(bool);
+ void setDefersLoading(bool);
- virtual void setDataBufferingPolicy(DataBufferingPolicy);
-
- void clear();
-
- virtual bool canReuse(const ResourceRequest&) const;
+ virtual bool canReuse(const ResourceRequest&) const OVERRIDE;
private:
- virtual void didAddClient(ResourceClient*);
+ virtual void didAddClient(ResourceClient*) OVERRIDE;
virtual void appendData(const char*, int) OVERRIDE;
- virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return true; }
-
- virtual void willSendRequest(ResourceRequest&, const ResourceResponse&);
- virtual void responseReceived(const ResourceResponse&);
- virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
- virtual void didDownloadData(int);
-
- struct RedirectPair {
- public:
- explicit RedirectPair(const ResourceRequest& request, const ResourceResponse& redirectResponse)
- : m_request(request)
- , m_redirectResponse(redirectResponse)
- {
- }
-
- const ResourceRequest m_request;
- const ResourceResponse m_redirectResponse;
- };
+ virtual bool shouldIgnoreHTTPStatusCodeErrors() const OVERRIDE { return true; }
- Vector<RedirectPair> m_redirectChain;
+ virtual void willSendRequest(ResourceRequest&, const ResourceResponse&) OVERRIDE;
+ virtual void updateRequest(const ResourceRequest&) OVERRIDE;
+ virtual void responseReceived(const ResourceResponse&) OVERRIDE;
+ virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
+ virtual void didDownloadData(int) OVERRIDE;
};
#ifdef SECURITY_ASSERT_ENABLED
inline bool isRawResource(const Resource& resource)
{
Resource::Type type = resource.type();
- return type == Resource::MainResource || type == Resource::Raw || type == Resource::TextTrack || type == Resource::ImportResource;
+ return type == Resource::MainResource || type == Resource::Raw || type == Resource::TextTrack || type == Resource::Media || type == Resource::ImportResource;
}
#endif
inline RawResource* toRawResource(const ResourcePtr<Resource>& resource)
@@ -90,12 +73,13 @@ class RawResourceClient : public ResourceClient {
public:
virtual ~RawResourceClient() { }
static ResourceClientType expectedType() { return RawResourceType; }
- virtual ResourceClientType resourceClientType() const { return expectedType(); }
+ virtual ResourceClientType resourceClientType() const OVERRIDE FINAL { return expectedType(); }
virtual void dataSent(Resource*, unsigned long long /* bytesSent */, unsigned long long /* totalBytesToBeSent */) { }
virtual void responseReceived(Resource*, const ResourceResponse&) { }
virtual void dataReceived(Resource*, const char* /* data */, int /* length */) { }
virtual void redirectReceived(Resource*, ResourceRequest&, const ResourceResponse&) { }
+ virtual void updateRequest(Resource*, const ResourceRequest&) { }
virtual void dataDownloaded(Resource*, int) { }
};
diff --git a/chromium/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp b/chromium/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp
index 3c4d0099479..f51ff481863 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp
@@ -47,7 +47,7 @@
using namespace WebCore;
-namespace {
+namespace WebCore {
TEST(RawResourceTest, DontIgnoreAcceptForCacheReuse)
{
@@ -86,4 +86,105 @@ TEST(RawResourceTest, RevalidationSucceeded)
EXPECT_NE(newResource.get(), newResourcePointer);
}
-} // namespace
+class DummyClient : public RawResourceClient {
+public:
+ DummyClient() : m_called(false) { }
+ virtual ~DummyClient() { }
+
+ // ResourceClient implementation.
+ virtual void notifyFinished(Resource* resource)
+ {
+ m_called = true;
+ }
+
+ bool called() { return m_called; }
+private:
+ bool m_called;
+};
+
+// This client adds another client when notified.
+class AddingClient : public RawResourceClient {
+public:
+ AddingClient(DummyClient* client, Resource* resource)
+ : m_dummyClient(client)
+ , m_resource(resource)
+ , m_removeClientTimer(this, &AddingClient::removeClient) { }
+
+ virtual ~AddingClient() { }
+
+ // ResourceClient implementation.
+ virtual void notifyFinished(Resource* resource)
+ {
+ // First schedule an asynchronous task to remove the client.
+ // We do not expect the client to be called.
+ m_removeClientTimer.startOneShot(0, FROM_HERE);
+ resource->addClient(m_dummyClient);
+ }
+ void removeClient(Timer<AddingClient>* timer)
+ {
+ m_resource->removeClient(m_dummyClient);
+ }
+private:
+ DummyClient* m_dummyClient;
+ Resource* m_resource;
+ Timer<AddingClient> m_removeClientTimer;
+};
+
+TEST(RawResourceTest, AddClientDuringCallback)
+{
+ ResourcePtr<Resource> raw = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
+ raw->setLoading(false);
+
+ // Create a non-null response.
+ ResourceResponse response = raw->response();
+ response.setURL(KURL(ParsedURLString, "http://600.613/"));
+ raw->setResponse(response);
+ EXPECT_FALSE(raw->response().isNull());
+
+ OwnPtr<DummyClient> dummyClient = adoptPtr(new DummyClient());
+ OwnPtr<AddingClient> addingClient = adoptPtr(new AddingClient(dummyClient.get(), raw.get()));
+ raw->addClient(addingClient.get());
+ testing::runPendingTasks();
+ raw->removeClient(addingClient.get());
+ EXPECT_FALSE(dummyClient->called());
+ EXPECT_FALSE(raw->hasClients());
+}
+
+// This client removes another client when notified.
+class RemovingClient : public RawResourceClient {
+public:
+ RemovingClient(DummyClient* client)
+ : m_dummyClient(client) { }
+
+ virtual ~RemovingClient() { }
+
+ // ResourceClient implementation.
+ virtual void notifyFinished(Resource* resource)
+ {
+ resource->removeClient(m_dummyClient);
+ resource->removeClient(this);
+ }
+private:
+ DummyClient* m_dummyClient;
+};
+
+TEST(RawResourceTest, RemoveClientDuringCallback)
+{
+ ResourcePtr<Resource> raw = new RawResource(ResourceRequest("data:text/html,"), Resource::Raw);
+ raw->setLoading(false);
+
+ // Create a non-null response.
+ ResourceResponse response = raw->response();
+ response.setURL(KURL(ParsedURLString, "http://600.613/"));
+ raw->setResponse(response);
+ EXPECT_FALSE(raw->response().isNull());
+
+ OwnPtr<DummyClient> dummyClient = adoptPtr(new DummyClient());
+ OwnPtr<RemovingClient> removingClient = adoptPtr(new RemovingClient(dummyClient.get()));
+ raw->addClient(dummyClient.get());
+ raw->addClient(removingClient.get());
+ testing::runPendingTasks();
+ EXPECT_FALSE(raw->hasClients());
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fetch/Resource.cpp b/chromium/third_party/WebKit/Source/core/fetch/Resource.cpp
index 8f56b290ade..0e83923fd91 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/Resource.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/Resource.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "core/fetch/Resource.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/fetch/CachedMetadata.h"
#include "core/fetch/CrossOriginAccessControl.h"
#include "core/fetch/MemoryCache.h"
@@ -34,8 +35,8 @@
#include "core/fetch/ResourcePtr.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "platform/Logging.h"
-#include "platform/PurgeableBuffer.h"
#include "platform/SharedBuffer.h"
+#include "platform/TraceEvent.h"
#include "platform/weborigin/KURL.h"
#include "public/platform/Platform.h"
#include "wtf/CurrentTime.h"
@@ -97,32 +98,24 @@ Resource::Resource(const ResourceRequest& request, Type type)
: m_resourceRequest(request)
, m_responseTimestamp(currentTime())
, m_cancelTimer(this, &Resource::cancelTimerFired)
- , m_lastDecodedAccessTime(0)
, m_loadFinishTime(0)
, m_identifier(0)
, m_encodedSize(0)
, m_decodedSize(0)
- , m_accessCount(0)
, m_handleCount(0)
, m_preloadCount(0)
, m_protectorCount(0)
, m_preloadResult(PreloadNotReferenced)
- , m_cacheLiveResourcePriority(CacheLiveResourcePriorityLow)
- , m_inLiveDecodedResourcesList(false)
, m_requestedFromNetworkingLayer(false)
- , m_inCache(false)
, m_loading(false)
, m_switchingClientsToRevalidatedResource(false)
, m_type(type)
, m_status(Pending)
-#ifndef NDEBUG
+ , m_wasPurged(false)
+ , m_needsSynchronousCacheHit(false)
+#ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
, m_deleted(false)
- , m_lruIndex(0)
#endif
- , m_nextInAllResourcesList(0)
- , m_prevInAllResourcesList(0)
- , m_nextInLiveResourcesList(0)
- , m_prevInLiveResourcesList(0)
, m_resourceToRevalidate(0)
, m_proxyResource(0)
{
@@ -144,12 +137,15 @@ Resource::~Resource()
{
ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() checks this.
ASSERT(canDelete());
- ASSERT(!inCache());
- ASSERT(!m_deleted);
+ RELEASE_ASSERT(!memoryCache()->contains(this));
+ RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this));
ASSERT(url().isNull() || memoryCache()->resourceForURL(KURL(ParsedURLString, url())) != this);
+ assertAlive();
-#ifndef NDEBUG
+#ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
m_deleted = true;
+#endif
+#ifndef NDEBUG
cachedResourceLeakCounter.decrement();
#endif
}
@@ -212,7 +208,7 @@ void Resource::appendData(const char* data, int length)
if (m_data)
m_data->append(data, length);
else
- m_data = SharedBuffer::create(data, length);
+ m_data = SharedBuffer::createPurgeable(data, length);
setEncodedSize(m_data->size());
}
@@ -225,6 +221,13 @@ void Resource::setResourceBuffer(PassRefPtr<SharedBuffer> resourceBuffer)
setEncodedSize(m_data->size());
}
+void Resource::setDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
+{
+ m_options.dataBufferingPolicy = dataBufferingPolicy;
+ m_data.clear();
+ setEncodedSize(0);
+}
+
void Resource::error(Resource::Status status)
{
if (m_resourceToRevalidate)
@@ -265,57 +268,109 @@ bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin)
bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin, String& errorDescription)
{
- return WebCore::passesAccessControlCheck(m_response, resourceRequest().allowCookies() ? AllowStoredCredentials : DoNotAllowStoredCredentials, securityOrigin, errorDescription);
+ return WebCore::passesAccessControlCheck(m_response, resourceRequest().allowStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials, securityOrigin, errorDescription);
}
-bool Resource::isExpired() const
-{
- if (m_response.isNull())
- return false;
-
- return currentAge() > freshnessLifetime();
-}
-
-double Resource::currentAge() const
+static double currentAge(const ResourceResponse& response, double responseTimestamp)
{
// RFC2616 13.2.3
// No compensation for latency as that is not terribly important in practice
- double dateValue = m_response.date();
- double apparentAge = std::isfinite(dateValue) ? std::max(0., m_responseTimestamp - dateValue) : 0;
- double ageValue = m_response.age();
+ double dateValue = response.date();
+ double apparentAge = std::isfinite(dateValue) ? std::max(0., responseTimestamp - dateValue) : 0;
+ double ageValue = response.age();
double correctedReceivedAge = std::isfinite(ageValue) ? std::max(apparentAge, ageValue) : apparentAge;
- double residentTime = currentTime() - m_responseTimestamp;
+ double residentTime = currentTime() - responseTimestamp;
return correctedReceivedAge + residentTime;
}
-double Resource::freshnessLifetime() const
+static double freshnessLifetime(ResourceResponse& response, double responseTimestamp)
{
#if !OS(ANDROID)
// On desktop, local files should be reloaded in case they change.
- if (m_response.url().isLocalFile())
+ if (response.url().isLocalFile())
return 0;
#endif
- // Cache other non-http resources liberally.
- if (!m_response.url().protocolIsInHTTPFamily())
+ // Cache other non-http / non-filesystem resources liberally.
+ if (!response.url().protocolIsInHTTPFamily()
+ && !response.url().protocolIs("filesystem"))
return std::numeric_limits<double>::max();
// RFC2616 13.2.4
- double maxAgeValue = m_response.cacheControlMaxAge();
+ double maxAgeValue = response.cacheControlMaxAge();
if (std::isfinite(maxAgeValue))
return maxAgeValue;
- double expiresValue = m_response.expires();
- double dateValue = m_response.date();
- double creationTime = std::isfinite(dateValue) ? dateValue : m_responseTimestamp;
+ double expiresValue = response.expires();
+ double dateValue = response.date();
+ double creationTime = std::isfinite(dateValue) ? dateValue : responseTimestamp;
if (std::isfinite(expiresValue))
return expiresValue - creationTime;
- double lastModifiedValue = m_response.lastModified();
+ double lastModifiedValue = response.lastModified();
if (std::isfinite(lastModifiedValue))
return (creationTime - lastModifiedValue) * 0.1;
// If no cache headers are present, the specification leaves the decision to the UA. Other browsers seem to opt for 0.
return 0;
}
+static bool canUseResponse(ResourceResponse& response, double responseTimestamp)
+{
+ if (response.isNull())
+ return false;
+
+ // FIXME: Why isn't must-revalidate considered a reason we can't use the response?
+ if (response.cacheControlContainsNoCache() || response.cacheControlContainsNoStore())
+ return false;
+
+ if (response.httpStatusCode() == 303) {
+ // Must not be cached.
+ return false;
+ }
+
+ if (response.httpStatusCode() == 302 || response.httpStatusCode() == 307) {
+ // Default to not cacheable unless explicitly allowed.
+ bool hasMaxAge = std::isfinite(response.cacheControlMaxAge());
+ bool hasExpires = std::isfinite(response.expires());
+ // TODO: consider catching Cache-Control "private" and "public" here.
+ if (!hasMaxAge && !hasExpires)
+ return false;
+ }
+
+ return currentAge(response, responseTimestamp) <= freshnessLifetime(response, responseTimestamp);
+}
+
+const ResourceRequest& Resource::lastResourceRequest()
+{
+ if (!m_redirectChain.size())
+ return m_resourceRequest;
+ return m_redirectChain.last().m_request;
+}
+
+void Resource::willSendRequest(ResourceRequest& request, const ResourceResponse& response)
+{
+ m_redirectChain.append(RedirectPair(request, response));
+ m_requestedFromNetworkingLayer = true;
+}
+
+bool Resource::unlock()
+{
+ if (!m_data)
+ return false;
+
+ if (!m_data->isLocked())
+ return true;
+
+ if (!memoryCache()->contains(this) || hasClients() || m_handleCount > 1 || m_proxyResource || m_resourceToRevalidate || !m_loadFinishTime || !isSafeToUnlock())
+ return false;
+
+ m_data->unlock();
+ return true;
+}
+
+bool Resource::hasRightHandleCountApartFromCache(unsigned targetCount) const
+{
+ return m_handleCount == targetCount + (memoryCache()->contains(this) ? 1 : 0);
+}
+
void Resource::responseReceived(const ResourceResponse& response)
{
setResponse(response);
@@ -355,6 +410,17 @@ void Resource::setCachedMetadata(unsigned dataTypeID, const char* data, size_t s
blink::Platform::current()->cacheMetadata(m_response.url(), m_response.responseTime(), serializedData.data(), serializedData.size());
}
+bool Resource::canDelete() const
+{
+ return !hasClients() && !m_loader && !m_preloadCount && hasRightHandleCountApartFromCache(0)
+ && !m_protectorCount && !m_resourceToRevalidate && !m_proxyResource;
+}
+
+bool Resource::hasOneHandle() const
+{
+ return hasRightHandleCountApartFromCache(1);
+}
+
CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const
{
if (!m_cachedMetadata || m_cachedMetadata->dataTypeID() != dataTypeID)
@@ -362,19 +428,9 @@ CachedMetadata* Resource::cachedMetadata(unsigned dataTypeID) const
return m_cachedMetadata.get();
}
-void Resource::setCacheLiveResourcePriority(CacheLiveResourcePriority priority)
-{
- if (inCache() && m_inLiveDecodedResourcesList && cacheLiveResourcePriority() != static_cast<unsigned>(priority)) {
- memoryCache()->removeFromLiveDecodedResourcesList(this);
- m_cacheLiveResourcePriority = priority;
- memoryCache()->insertInLiveDecodedResourcesList(this);
- memoryCache()->prune();
- }
-}
-
void Resource::clearLoader()
{
- m_loader = 0;
+ m_loader = nullptr;
}
void Resource::addClient(ResourceClient* client)
@@ -420,11 +476,11 @@ bool Resource::addClientToSet(ResourceClient* client)
else
m_preloadResult = PreloadReferenced;
}
- if (!hasClients() && inCache())
- memoryCache()->addToLiveResourcesSize(this);
+ if (!hasClients())
+ memoryCache()->makeLive(this);
// If we have existing data to send to the new client and the resource type supprts it, send it asynchronously.
- if (!m_response.isNull() && !m_proxyResource && !shouldSendCachedDataSynchronouslyForType(type())) {
+ if (!m_response.isNull() && !m_proxyResource && !shouldSendCachedDataSynchronouslyForType(type()) && !m_needsSynchronousCacheHit) {
m_clientsAwaitingCallback.add(client);
ResourceCallback::callbackHandler()->schedule(this);
return false;
@@ -439,29 +495,28 @@ void Resource::removeClient(ResourceClient* client)
if (m_clientsAwaitingCallback.contains(client)) {
ASSERT(!m_clients.contains(client));
m_clientsAwaitingCallback.remove(client);
- if (m_clientsAwaitingCallback.isEmpty())
- ResourceCallback::callbackHandler()->cancel(this);
} else {
ASSERT(m_clients.contains(client));
m_clients.remove(client);
didRemoveClient(client);
}
+ if (m_clientsAwaitingCallback.isEmpty())
+ ResourceCallback::callbackHandler()->cancel(this);
+
bool deleted = deleteIfPossible();
if (!deleted && !hasClients()) {
- if (inCache()) {
- memoryCache()->removeFromLiveResourcesSize(this);
- memoryCache()->removeFromLiveDecodedResourcesList(this);
- }
+ memoryCache()->makeDead(this);
if (!m_switchingClientsToRevalidatedResource)
allClientsRemoved();
- if (response().cacheControlContainsNoStore()) {
- // RFC2616 14.9.2:
- // "no-store: ... MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible"
- // "... History buffers MAY store such responses as part of their normal operation."
- // We allow non-secure content to be reused in history, but we do not allow secure content to be reused.
- if (url().protocolIs("https"))
- memoryCache()->remove(this);
+
+ // RFC2616 14.9.2:
+ // "no-store: ... MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible"
+ // "... History buffers MAY store such responses as part of their normal operation."
+ // We allow non-secure content to be reused in history, but we do not allow secure content to be reused.
+ if (hasCacheControlNoStoreHeader() && url().protocolIs("https")) {
+ memoryCache()->remove(this);
+ memoryCache()->prune();
} else {
memoryCache()->prune(this);
}
@@ -476,7 +531,9 @@ void Resource::allClientsRemoved()
if (m_type == MainResource || m_type == Raw)
cancelTimerFired(&m_cancelTimer);
else if (!m_cancelTimer.isActive())
- m_cancelTimer.startOneShot(0);
+ m_cancelTimer.startOneShot(0, FROM_HERE);
+
+ unlock();
}
void Resource::cancelTimerFired(Timer<Resource>* timer)
@@ -492,7 +549,7 @@ void Resource::cancelTimerFired(Timer<Resource>* timer)
bool Resource::deleteIfPossible()
{
- if (canDelete() && !inCache()) {
+ if (canDelete() && !memoryCache()->contains(this)) {
InspectorInstrumentation::willDestroyResource(this);
delete this;
return true;
@@ -500,86 +557,69 @@ bool Resource::deleteIfPossible()
return false;
}
-void Resource::setDecodedSize(size_t size)
+void Resource::setDecodedSize(size_t decodedSize)
{
- if (size == m_decodedSize)
+ if (decodedSize == m_decodedSize)
return;
-
- ptrdiff_t delta = size - m_decodedSize;
-
- // The object must now be moved to a different queue, since its size has been changed.
- // We have to remove explicitly before updating m_decodedSize, so that we find the correct previous
- // queue.
- if (inCache())
- memoryCache()->removeFromLRUList(this);
-
- m_decodedSize = size;
-
- if (inCache()) {
- // Now insert into the new LRU list.
- memoryCache()->insertInLRUList(this);
-
- // Insert into or remove from the live decoded list if necessary.
- // When inserting into the LiveDecodedResourcesList it is possible
- // that the m_lastDecodedAccessTime is still zero or smaller than
- // the m_lastDecodedAccessTime of the current list head. This is a
- // violation of the invariant that the list is to be kept sorted
- // by access time. The weakening of the invariant does not pose
- // a problem. For more details please see: https://bugs.webkit.org/show_bug.cgi?id=30209
- if (m_decodedSize && !m_inLiveDecodedResourcesList && hasClients())
- memoryCache()->insertInLiveDecodedResourcesList(this);
- else if (!m_decodedSize && m_inLiveDecodedResourcesList)
- memoryCache()->removeFromLiveDecodedResourcesList(this);
-
- // Update the cache's size totals.
- memoryCache()->adjustSize(hasClients(), delta);
- }
+ size_t oldSize = size();
+ m_decodedSize = decodedSize;
+ memoryCache()->update(this, oldSize, size());
+ memoryCache()->updateDecodedResource(this, UpdateForPropertyChange);
}
-void Resource::setEncodedSize(size_t size)
+void Resource::setEncodedSize(size_t encodedSize)
{
- if (size == m_encodedSize)
+ if (encodedSize == m_encodedSize)
return;
-
- ptrdiff_t delta = size - m_encodedSize;
-
- // The object must now be moved to a different queue, since its size has been changed.
- // We have to remove explicitly before updating m_encodedSize, so that we find the correct previous
- // queue.
- if (inCache())
- memoryCache()->removeFromLRUList(this);
-
- m_encodedSize = size;
-
- if (inCache()) {
- // Now insert into the new LRU list.
- memoryCache()->insertInLRUList(this);
-
- // Update the cache's size totals.
- memoryCache()->adjustSize(hasClients(), delta);
- }
+ size_t oldSize = size();
+ m_encodedSize = encodedSize;
+ memoryCache()->update(this, oldSize, size());
}
-void Resource::didAccessDecodedData(double timeStamp)
+void Resource::didAccessDecodedData()
{
- m_lastDecodedAccessTime = timeStamp;
- if (inCache()) {
- if (m_inLiveDecodedResourcesList) {
- memoryCache()->removeFromLiveDecodedResourcesList(this);
- memoryCache()->insertInLiveDecodedResourcesList(this);
- }
- memoryCache()->prune();
- }
+ memoryCache()->updateDecodedResource(this, UpdateForAccess);
+ memoryCache()->prune();
}
void Resource::finishPendingClients()
{
- while (!m_clientsAwaitingCallback.isEmpty()) {
- ResourceClient* client = m_clientsAwaitingCallback.begin()->key;
- m_clientsAwaitingCallback.remove(client);
+ // We're going to notify clients one by one. It is simple if the client does nothing.
+ // However there are a couple other things that can happen.
+ //
+ // 1. Clients can be added during the loop. Make sure they are not processed.
+ // 2. Clients can be removed during the loop. Make sure they are always available to be
+ // removed. Also don't call removed clients or add them back.
+
+ // Handle case (1) by saving a list of clients to notify. A separate list also ensure
+ // a client is either in m_clients or m_clientsAwaitingCallback.
+ Vector<ResourceClient*> clientsToNotify;
+ copyToVector(m_clientsAwaitingCallback, clientsToNotify);
+
+ for (size_t i = 0; i < clientsToNotify.size(); ++i) {
+ ResourceClient* client = clientsToNotify[i];
+
+ // Handle case (2) to skip removed clients.
+ if (!m_clientsAwaitingCallback.remove(client))
+ continue;
m_clients.add(client);
didAddClient(client);
}
+
+ // It is still possible for the above loop to finish a new client synchronously.
+ // If there's no client waiting we should deschedule.
+ bool scheduled = ResourceCallback::callbackHandler()->isScheduled(this);
+ if (scheduled && m_clientsAwaitingCallback.isEmpty())
+ ResourceCallback::callbackHandler()->cancel(this);
+
+ // Prevent the case when there are clients waiting but no callback scheduled.
+ ASSERT(m_clientsAwaitingCallback.isEmpty() || scheduled);
+}
+
+void Resource::prune()
+{
+ destroyDecodedDataIfPossible();
+ unlock();
}
void Resource::setResourceToRevalidate(Resource* resource)
@@ -620,8 +660,8 @@ void Resource::clearResourceToRevalidate()
void Resource::switchClientsToRevalidatedResource()
{
ASSERT(m_resourceToRevalidate);
- ASSERT(m_resourceToRevalidate->inCache());
- ASSERT(!inCache());
+ ASSERT(memoryCache()->contains(m_resourceToRevalidate));
+ ASSERT(!memoryCache()->contains(this));
WTF_LOG(ResourceLoading, "Resource %p switchClientsToRevalidatedResource %p", this, m_resourceToRevalidate);
@@ -690,9 +730,8 @@ void Resource::updateResponseAfterRevalidation(const ResourceResponse& validatin
void Resource::revalidationSucceeded(const ResourceResponse& response)
{
ASSERT(m_resourceToRevalidate);
- ASSERT(!m_resourceToRevalidate->inCache());
+ ASSERT(!memoryCache()->contains(m_resourceToRevalidate));
ASSERT(m_resourceToRevalidate->isLoaded());
- ASSERT(inCache());
// Calling evict() can potentially delete revalidatingResource, which we use
// below. This mustn't be the case since revalidation means it is loaded
@@ -703,7 +742,7 @@ void Resource::revalidationSucceeded(const ResourceResponse& response)
memoryCache()->replace(m_resourceToRevalidate, this);
switchClientsToRevalidatedResource();
- ASSERT(!m_deleted);
+ assertAlive();
// clearResourceToRevalidate deletes this.
clearResourceToRevalidate();
}
@@ -716,24 +755,9 @@ void Resource::revalidationFailed()
clearResourceToRevalidate();
}
-void Resource::updateForAccess()
-{
- ASSERT(inCache());
-
- // Need to make sure to remove before we increase the access count, since
- // the queue will possibly change.
- memoryCache()->removeFromLRUList(this);
-
- // If this is the first time the resource has been accessed, adjust the size of the cache to account for its initial size.
- if (!m_accessCount)
- memoryCache()->adjustSize(hasClients(), size());
-
- m_accessCount++;
- memoryCache()->insertInLRUList(this);
-}
-
void Resource::registerHandle(ResourcePtrBase* h)
{
+ assertAlive();
++m_handleCount;
if (m_resourceToRevalidate)
m_handlesToRevalidate.add(h);
@@ -741,105 +765,91 @@ void Resource::registerHandle(ResourcePtrBase* h)
void Resource::unregisterHandle(ResourcePtrBase* h)
{
+ assertAlive();
ASSERT(m_handleCount > 0);
--m_handleCount;
if (m_resourceToRevalidate)
m_handlesToRevalidate.remove(h);
- if (!m_handleCount)
- deleteIfPossible();
+ if (!m_handleCount) {
+ if (deleteIfPossible())
+ return;
+ unlock();
+ } else if (m_handleCount == 1 && memoryCache()->contains(this)) {
+ unlock();
+ if (!hasClients())
+ memoryCache()->prune(this);
+ }
}
-bool Resource::canUseCacheValidator() const
+bool Resource::canReuseRedirectChain()
{
- if (m_loading || errorOccurred())
- return false;
-
- if (m_response.cacheControlContainsNoStore())
- return false;
- return m_response.hasCacheValidatorFields();
+ for (size_t i = 0; i < m_redirectChain.size(); ++i) {
+ if (!canUseResponse(m_redirectChain[i].m_redirectResponse, m_responseTimestamp))
+ return false;
+ if (m_redirectChain[i].m_request.cacheControlContainsNoCache() || m_redirectChain[i].m_request.cacheControlContainsNoStore())
+ return false;
+ }
+ return true;
}
-bool Resource::mustRevalidateDueToCacheHeaders() const
+bool Resource::hasCacheControlNoStoreHeader()
{
- if (m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore()) {
- WTF_LOG(ResourceLoading, "Resource %p mustRevalidate because of m_response.cacheControlContainsNoCache() || m_response.cacheControlContainsNoStore()\n", this);
- return true;
- }
-
- if (isExpired()) {
- WTF_LOG(ResourceLoading, "Resource %p mustRevalidate because of isExpired()\n", this);
- return true;
- }
-
- return false;
+ return m_response.cacheControlContainsNoStore() || m_resourceRequest.cacheControlContainsNoStore();
}
-bool Resource::isSafeToMakePurgeable() const
+bool Resource::mustRevalidateDueToCacheHeaders()
{
- return !hasClients() && !m_proxyResource && !m_resourceToRevalidate;
+ return !canUseResponse(m_response, m_responseTimestamp) || m_resourceRequest.cacheControlContainsNoCache() || m_resourceRequest.cacheControlContainsNoStore();
}
-bool Resource::makePurgeable(bool purgeable)
+bool Resource::canUseCacheValidator()
{
- if (purgeable) {
- ASSERT(isSafeToMakePurgeable());
+ if (m_loading || errorOccurred())
+ return false;
- if (m_purgeableData) {
- ASSERT(!m_data);
- return true;
- }
- if (!m_data)
- return false;
+ if (hasCacheControlNoStoreHeader())
+ return false;
+ return m_response.hasCacheValidatorFields() || m_resourceRequest.hasCacheValidatorFields();
+}
- // Should not make buffer purgeable if it has refs other than this since we don't want two copies.
- if (!m_data->hasOneRef())
- return false;
+bool Resource::isPurgeable() const
+{
+ return m_data && !m_data->isLocked();
+}
- m_data->createPurgeableBuffer();
- if (!m_data->hasPurgeableBuffer())
- return false;
+bool Resource::wasPurged() const
+{
+ return m_wasPurged;
+}
- m_purgeableData = m_data->releasePurgeableBuffer();
- m_purgeableData->unlock();
- m_data.clear();
+bool Resource::lock()
+{
+ if (!m_data)
return true;
- }
-
- if (!m_purgeableData)
+ if (m_data->isLocked())
return true;
- ASSERT(!m_data);
ASSERT(!hasClients());
- if (!m_purgeableData->lock())
+ if (!m_data->lock()) {
+ m_wasPurged = true;
return false;
-
- m_data = SharedBuffer::adoptPurgeableBuffer(m_purgeableData.release());
+ }
return true;
}
-bool Resource::isPurgeable() const
-{
- return m_purgeableData && m_purgeableData->isPurgeable();
-}
-
-bool Resource::wasPurged() const
-{
- return m_purgeableData && m_purgeableData->wasPurged();
-}
-
size_t Resource::overheadSize() const
{
static const int kAverageClientsHashMapSize = 384;
return sizeof(Resource) + m_response.memoryUsage() + kAverageClientsHashMapSize + m_resourceRequest.url().string().length() * 2;
}
-void Resource::didChangePriority(ResourceLoadPriority loadPriority)
+void Resource::didChangePriority(ResourceLoadPriority loadPriority, int intraPriorityValue)
{
if (m_loader)
- m_loader->didChangePriority(loadPriority);
+ m_loader->didChangePriority(loadPriority, intraPriorityValue);
}
Resource::ResourceCallback* Resource::ResourceCallback::callbackHandler()
@@ -856,17 +866,24 @@ Resource::ResourceCallback::ResourceCallback()
void Resource::ResourceCallback::schedule(Resource* resource)
{
if (!m_callbackTimer.isActive())
- m_callbackTimer.startOneShot(0);
+ m_callbackTimer.startOneShot(0, FROM_HERE);
+ resource->assertAlive();
m_resourcesWithPendingClients.add(resource);
}
void Resource::ResourceCallback::cancel(Resource* resource)
{
+ resource->assertAlive();
m_resourcesWithPendingClients.remove(resource);
if (m_callbackTimer.isActive() && m_resourcesWithPendingClients.isEmpty())
m_callbackTimer.stop();
}
+bool Resource::ResourceCallback::isScheduled(Resource* resource) const
+{
+ return m_resourcesWithPendingClients.contains(resource);
+}
+
void Resource::ResourceCallback::timerFired(Timer<ResourceCallback>*)
{
HashSet<Resource*>::iterator end = m_resourcesWithPendingClients.end();
@@ -874,8 +891,73 @@ void Resource::ResourceCallback::timerFired(Timer<ResourceCallback>*)
for (HashSet<Resource*>::iterator it = m_resourcesWithPendingClients.begin(); it != end; ++it)
resources.append(*it);
m_resourcesWithPendingClients.clear();
- for (size_t i = 0; i < resources.size(); i++)
+
+ for (size_t i = 0; i < resources.size(); i++) {
+ resources[i]->assertAlive();
resources[i]->finishPendingClients();
+ resources[i]->assertAlive();
+ }
+
+ for (size_t i = 0; i < resources.size(); i++)
+ resources[i]->assertAlive();
+}
+
+static const char* initatorTypeNameToString(const AtomicString& initiatorTypeName)
+{
+ if (initiatorTypeName == FetchInitiatorTypeNames::css)
+ return "CSS resource";
+ if (initiatorTypeName == FetchInitiatorTypeNames::document)
+ return "Document";
+ if (initiatorTypeName == FetchInitiatorTypeNames::icon)
+ return "Icon";
+ if (initiatorTypeName == FetchInitiatorTypeNames::internal)
+ return "Internal resource";
+ if (initiatorTypeName == FetchInitiatorTypeNames::link)
+ return "Link element resource";
+ if (initiatorTypeName == FetchInitiatorTypeNames::processinginstruction)
+ return "Processing instruction";
+ if (initiatorTypeName == FetchInitiatorTypeNames::texttrack)
+ return "Text track";
+ if (initiatorTypeName == FetchInitiatorTypeNames::xml)
+ return "XML resource";
+ if (initiatorTypeName == FetchInitiatorTypeNames::xmlhttprequest)
+ return "XMLHttpRequest";
+
+ return "Resource";
+}
+
+const char* Resource::resourceTypeToString(Type type, const FetchInitiatorInfo& initiatorInfo)
+{
+ switch (type) {
+ case Resource::MainResource:
+ return "Main resource";
+ case Resource::Image:
+ return "Image";
+ case Resource::CSSStyleSheet:
+ return "CSS stylesheet";
+ case Resource::Script:
+ return "Script";
+ case Resource::Font:
+ return "Font";
+ case Resource::Raw:
+ return initatorTypeNameToString(initiatorInfo.name);
+ case Resource::SVGDocument:
+ return "SVG document";
+ case Resource::XSLStyleSheet:
+ return "XSL stylesheet";
+ case Resource::LinkPrefetch:
+ return "Link prefetch resource";
+ case Resource::LinkSubresource:
+ return "Link subresource";
+ case Resource::TextTrack:
+ return "Text track";
+ case Resource::ImportResource:
+ return "Imported resource";
+ case Resource::Media:
+ return "Media";
+ }
+ ASSERT_NOT_REACHED();
+ return initatorTypeNameToString(initiatorInfo.name);
}
#if !LOG_DISABLED
@@ -904,10 +986,10 @@ const char* ResourceTypeName(Resource::Type type)
return "LinkSubresource";
case Resource::TextTrack:
return "TextTrack";
- case Resource::Shader:
- return "Shader";
case Resource::ImportResource:
return "ImportResource";
+ case Resource::Media:
+ return "Media";
}
ASSERT_NOT_REACHED();
return "Unknown";
diff --git a/chromium/third_party/WebKit/Source/core/fetch/Resource.h b/chromium/third_party/WebKit/Source/core/fetch/Resource.h
index 968e7577264..829cd67cc86 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/Resource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/Resource.h
@@ -34,15 +34,18 @@
#include "wtf/OwnPtr.h"
#include "wtf/text/WTFString.h"
+// FIXME(crbug.com/352043): This is temporarily enabled even on RELEASE to diagnose a wild crash.
+#define ENABLE_RESOURCE_IS_DELETED_CHECK
+
namespace WebCore {
+struct FetchInitiatorInfo;
class MemoryCache;
class CachedMetadata;
class ResourceClient;
class ResourcePtrBase;
class ResourceFetcher;
class InspectorResource;
-class PurgeableBuffer;
class ResourceLoader;
class SecurityOrigin;
class SharedBuffer;
@@ -52,7 +55,6 @@ class SharedBuffer;
// This class also does the actual communication with the loader to obtain the resource from the network.
class Resource {
WTF_MAKE_NONCOPYABLE(Resource); WTF_MAKE_FAST_ALLOCATED;
- friend class MemoryCache;
friend class InspectorResource;
public:
@@ -68,8 +70,8 @@ public:
LinkPrefetch,
LinkSubresource,
TextTrack,
- Shader,
- ImportResource
+ ImportResource,
+ Media // Audio or video file requested by a HTML5 media element
};
enum Status {
@@ -83,13 +85,6 @@ public:
Resource(const ResourceRequest&, Type);
virtual ~Resource();
- // Determines the order in which CachedResources are evicted
- // from the decoded resources cache.
- enum CacheLiveResourcePriority {
- CacheLiveResourcePriorityLow = 0,
- CacheLiveResourcePriorityHigh
- };
-
virtual void load(ResourceFetcher*, const ResourceLoaderOptions&);
virtual void setEncoding(const String&) { }
@@ -97,6 +92,8 @@ public:
virtual void appendData(const char*, int);
virtual void error(Resource::Status);
+ void setNeedsSynchronousCacheHit(bool needsSynchronousCacheHit) { m_needsSynchronousCacheHit = needsSynchronousCacheHit; }
+
void setResourceError(const ResourceError& error) { m_error = error; }
const ResourceError& resourceError() const { return m_error; }
@@ -106,12 +103,13 @@ public:
virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return false; }
ResourceRequest& resourceRequest() { return m_resourceRequest; }
+ const ResourceRequest& lastResourceRequest();
const KURL& url() const { return m_resourceRequest.url();}
Type type() const { return static_cast<Type>(m_type); }
const ResourceLoaderOptions& options() const { return m_options; }
void setOptions(const ResourceLoaderOptions& options) { m_options = options; }
- void didChangePriority(ResourceLoadPriority);
+ void didChangePriority(ResourceLoadPriority, int intraPriorityValue);
void addClient(ResourceClient*);
void removeClient(ResourceClient*);
@@ -154,12 +152,11 @@ public:
return type() == MainResource
|| type() == LinkPrefetch
|| type() == LinkSubresource
- || type() == Raw;
+ || type() == Media
+ || type() == Raw
+ || type() == TextTrack;
}
- void updateForAccess();
- unsigned accessCount() const { return m_accessCount; }
-
// Computes the status of an object after loading.
// Updates the expire date on the cache entry file
void finish(double finishTime = 0.0);
@@ -168,23 +165,14 @@ public:
bool passesAccessControlCheck(SecurityOrigin*);
bool passesAccessControlCheck(SecurityOrigin*, String& errorDescription);
- // Called by the cache if the object has been removed from the cache
- // while still being referenced. This means the object should delete itself
- // if the number of clients observing it ever drops to 0.
- // The resource can be brought back to cache after successful revalidation.
- void setInCache(bool inCache) { m_inCache = inCache; }
- bool inCache() const { return m_inCache; }
-
- void setCacheLiveResourcePriority(CacheLiveResourcePriority);
- unsigned cacheLiveResourcePriority() const { return m_cacheLiveResourcePriority; }
- bool inLiveDecodedResourcesList() { return m_inLiveDecodedResourcesList; }
-
void clearLoader();
- SharedBuffer* resourceBuffer() const { ASSERT(!m_purgeableData); return m_data.get(); }
+ SharedBuffer* resourceBuffer() const { return m_data.get(); }
void setResourceBuffer(PassRefPtr<SharedBuffer>);
- virtual void willSendRequest(ResourceRequest&, const ResourceResponse&) { m_requestedFromNetworkingLayer = true; }
+ virtual void willSendRequest(ResourceRequest&, const ResourceResponse&);
+
+ virtual void updateRequest(const ResourceRequest&) { }
virtual void responseReceived(const ResourceResponse&);
void setResponse(const ResourceResponse& response) { m_response = response; }
const ResourceResponse& response() const { return m_response; }
@@ -200,10 +188,8 @@ public:
// Returns cached metadata of the given type associated with this resource.
CachedMetadata* cachedMetadata(unsigned dataTypeID) const;
- bool canDelete() const { return !hasClients() && !m_loader && !m_preloadCount && !m_handleCount && !m_protectorCount && !m_resourceToRevalidate && !m_proxyResource; }
- bool hasOneHandle() const { return m_handleCount == 1; }
-
- bool isExpired() const;
+ bool hasOneHandle() const;
+ bool canDelete() const;
// List of acceptable MIME types separated by ",".
// A MIME type may contain a wildcard, e.g. "text/*".
@@ -214,10 +200,8 @@ public:
bool errorOccurred() const { return m_status == LoadError || m_status == DecodeError; }
bool loadFailedOrCanceled() { return !m_error.isNull(); }
- bool shouldSendResourceLoadCallbacks() const { return m_options.sendLoadCallbacks == SendCallbacks; }
DataBufferingPolicy dataBufferingPolicy() const { return m_options.dataBufferingPolicy; }
-
- virtual void destroyDecodedData() { }
+ void setDataBufferingPolicy(DataBufferingPolicy);
bool isPreloaded() const { return m_preloadCount; }
void increasePreloadCount() { ++m_preloadCount; }
@@ -226,19 +210,17 @@ public:
void registerHandle(ResourcePtrBase* h);
void unregisterHandle(ResourcePtrBase* h);
- bool canUseCacheValidator() const;
- bool mustRevalidateDueToCacheHeaders() const;
+ bool canReuseRedirectChain();
+ bool mustRevalidateDueToCacheHeaders();
+ bool canUseCacheValidator();
bool isCacheValidator() const { return m_resourceToRevalidate; }
Resource* resourceToRevalidate() const { return m_resourceToRevalidate; }
void setResourceToRevalidate(Resource*);
+ bool hasCacheControlNoStoreHeader();
bool isPurgeable() const;
bool wasPurged() const;
-
- // This is used by the archive machinery to get at a purged resource without
- // triggering a load. We should make it protected again if we can find a
- // better way to handle the archive case.
- bool makePurgeable(bool purgeable);
+ bool lock();
virtual void didSendData(unsigned long long /* bytesSent */, unsigned long long /* totalBytesToBeSent */) { }
virtual void didDownloadData(int) { }
@@ -247,6 +229,17 @@ public:
virtual bool canReuse(const ResourceRequest&) const { return true; }
+ // Used by the MemoryCache to reduce the memory consumption of the entry.
+ void prune();
+
+ static const char* resourceTypeToString(Type, const FetchInitiatorInfo&);
+
+#ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
+ void assertAlive() const { RELEASE_ASSERT(!m_deleted); }
+#else
+ void assertAlive() const { }
+#endif
+
protected:
virtual void checkNotify();
virtual void finishOnePart();
@@ -279,9 +272,7 @@ protected:
void setEncodedSize(size_t);
void setDecodedSize(size_t);
- void didAccessDecodedData(double timeStamp);
-
- bool isSafeToMakePurgeable() const;
+ void didAccessDecodedData();
virtual void switchClientsToRevalidatedResource();
void clearResourceToRevalidate();
@@ -297,6 +288,7 @@ protected:
static ResourceCallback* callbackHandler();
void schedule(Resource*);
void cancel(Resource*);
+ bool isScheduled(Resource*) const;
private:
ResourceCallback();
void timerFired(Timer<ResourceCallback>*);
@@ -306,6 +298,22 @@ protected:
bool hasClient(ResourceClient* client) { return m_clients.contains(client) || m_clientsAwaitingCallback.contains(client); }
+ struct RedirectPair {
+ public:
+ explicit RedirectPair(const ResourceRequest& request, const ResourceResponse& redirectResponse)
+ : m_request(request)
+ , m_redirectResponse(redirectResponse)
+ {
+ }
+
+ ResourceRequest m_request;
+ ResourceResponse m_redirectResponse;
+ };
+ const Vector<RedirectPair>& redirectChain() const { return m_redirectChain; }
+
+ virtual bool isSafeToUnlock() const { return false; }
+ virtual void destroyDecodedDataIfPossible() { }
+
ResourceRequest m_resourceRequest;
AtomicString m_accept;
RefPtr<ResourceLoader> m_loader;
@@ -315,7 +323,6 @@ protected:
double m_responseTimestamp;
RefPtr<SharedBuffer> m_data;
- OwnPtr<PurgeableBuffer> m_purgeableData;
Timer<Resource> m_cancelTimer;
private:
@@ -325,8 +332,9 @@ private:
void revalidationSucceeded(const ResourceResponse&);
void revalidationFailed();
- double currentAge() const;
- double freshnessLifetime() const;
+ bool unlock();
+
+ bool hasRightHandleCountApartFromCache(unsigned targetCount) const;
void failBeforeStarting();
@@ -336,24 +344,19 @@ private:
ResourceError m_error;
- double m_lastDecodedAccessTime; // Used as a "thrash guard" in the cache
double m_loadFinishTime;
unsigned long m_identifier;
size_t m_encodedSize;
size_t m_decodedSize;
- unsigned m_accessCount;
unsigned m_handleCount;
unsigned m_preloadCount;
unsigned m_protectorCount;
unsigned m_preloadResult : 2; // PreloadResult
- unsigned m_cacheLiveResourcePriority : 2; // CacheLiveResourcePriority
- unsigned m_inLiveDecodedResourcesList : 1;
unsigned m_requestedFromNetworkingLayer : 1;
- unsigned m_inCache : 1;
unsigned m_loading : 1;
unsigned m_switchingClientsToRevalidatedResource : 1;
@@ -361,16 +364,13 @@ private:
unsigned m_type : 4; // Type
unsigned m_status : 3; // Status
-#ifndef NDEBUG
- bool m_deleted;
- unsigned m_lruIndex;
-#endif
+ unsigned m_wasPurged : 1;
- Resource* m_nextInAllResourcesList;
- Resource* m_prevInAllResourcesList;
+ unsigned m_needsSynchronousCacheHit : 1;
- Resource* m_nextInLiveResourcesList;
- Resource* m_prevInLiveResourcesList;
+#ifdef ENABLE_RESOURCE_IS_DELETED_CHECK
+ bool m_deleted;
+#endif
// If this field is non-null we are using the resource as a proxy for checking whether an existing resource is still up to date
// using HTTP If-Modified-Since/If-None-Match headers. If the response is 304 all clients of this resource are moved
@@ -383,6 +383,9 @@ private:
// These handles will need to be updated to point to the m_resourceToRevalidate in case we get 304 response.
HashSet<ResourcePtrBase*> m_handlesToRevalidate;
+
+ // Ordered list of all redirects followed while fetching this resource.
+ Vector<RedirectPair> m_redirectChain;
};
#if !LOG_DISABLED
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
index 799fc87065d..edfc1d26d8e 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -27,10 +27,10 @@
#include "config.h"
#include "core/fetch/ResourceFetcher.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ScriptController.h"
#include "core/dom/Document.h"
#include "core/fetch/CSSStyleSheetResource.h"
+#include "core/fetch/CrossOriginAccessControl.h"
#include "core/fetch/DocumentResource.h"
#include "core/fetch/FetchContext.h"
#include "core/fetch/FontResource.h"
@@ -40,25 +40,27 @@
#include "core/fetch/ResourceLoader.h"
#include "core/fetch/ResourceLoaderSet.h"
#include "core/fetch/ScriptResource.h"
-#include "core/fetch/ShaderResource.h"
#include "core/fetch/XSLStyleSheetResource.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/html/HTMLImport.h"
+#include "core/html/imports/HTMLImportsController.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/loader/PingLoader.h"
+#include "core/loader/SubstituteData.h"
#include "core/loader/UniqueIdentifier.h"
#include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/timing/Performance.h"
#include "core/timing/ResourceTimingInfo.h"
#include "core/frame/Settings.h"
+#include "core/svg/graphics/SVGImageChromeClient.h"
#include "platform/Logging.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "platform/weborigin/SecurityPolicy.h"
@@ -87,15 +89,14 @@ static Resource* createResource(Resource::Type type, const ResourceRequest& requ
case Resource::MainResource:
case Resource::Raw:
case Resource::TextTrack:
+ case Resource::Media:
return new RawResource(request, type);
case Resource::XSLStyleSheet:
- return new XSLStyleSheetResource(request);
+ return new XSLStyleSheetResource(request, charset);
case Resource::LinkPrefetch:
return new Resource(request, Resource::LinkPrefetch);
case Resource::LinkSubresource:
return new Resource(request, Resource::LinkSubresource);
- case Resource::Shader:
- return new ShaderResource(request);
case Resource::ImportResource:
return new RawResource(request, type);
}
@@ -124,6 +125,8 @@ static ResourceLoadPriority loadPriority(Resource::Type type, const FetchRequest
// We'll default images to VeryLow, and promote whatever is visible. This improves
// speed-index by ~5% on average, ~14% at the 99th percentile.
return ResourceLoadPriorityVeryLow;
+ case Resource::Media:
+ return ResourceLoadPriorityLow;
case Resource::XSLStyleSheet:
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
return ResourceLoadPriorityHigh;
@@ -135,8 +138,6 @@ static ResourceLoadPriority loadPriority(Resource::Type type, const FetchRequest
return ResourceLoadPriorityLow;
case Resource::TextTrack:
return ResourceLoadPriorityLow;
- case Resource::Shader:
- return ResourceLoadPriorityMedium;
}
ASSERT_NOT_REACHED();
return ResourceLoadPriorityUnresolved;
@@ -157,9 +158,8 @@ static Resource* resourceFromDataURIRequest(const ResourceRequest& request, cons
Resource* resource = createResource(Resource::Image, request, charset);
resource->setOptions(resourceOptions);
resource->responseReceived(response);
- // FIXME: AppendData causes an unnecessary memcpy.
if (data->size())
- resource->appendData(data->data(), data->size());
+ resource->setResourceBuffer(data);
resource->finish();
return resource;
}
@@ -168,9 +168,12 @@ static void populateResourceTiming(ResourceTimingInfo* info, Resource* resource,
{
info->setInitialRequest(resource->resourceRequest());
info->setFinalResponse(resource->response());
- if (clearLoadTimings)
+ if (clearLoadTimings) {
info->clearLoadTimings();
- info->setLoadFinishTime(resource->loadFinishTime());
+ info->setLoadFinishTime(info->initialTime());
+ } else {
+ info->setLoadFinishTime(resource->loadFinishTime());
+ }
}
static void reportResourceTiming(ResourceTimingInfo* info, Document* initiatorDocument, bool isMainResource)
@@ -179,10 +182,8 @@ static void reportResourceTiming(ResourceTimingInfo* info, Document* initiatorDo
initiatorDocument = initiatorDocument->parentDocument();
if (!initiatorDocument || !initiatorDocument->loader())
return;
- if (DOMWindow* initiatorWindow = initiatorDocument->domWindow()) {
- if (Performance* performance = initiatorWindow->performance())
- performance->addResourceTiming(*info, initiatorDocument);
- }
+ if (LocalDOMWindow* initiatorWindow = initiatorDocument->domWindow())
+ initiatorWindow->performance().addResourceTiming(*info, initiatorDocument);
}
static ResourceRequest::TargetType requestTargetType(const ResourceFetcher* fetcher, const ResourceRequest& request, Resource::Type type)
@@ -202,7 +203,6 @@ static ResourceRequest::TargetType requestTargetType(const ResourceFetcher* fetc
return ResourceRequest::TargetIsFont;
case Resource::Image:
return ResourceRequest::TargetIsImage;
- case Resource::Shader:
case Resource::Raw:
case Resource::ImportResource:
return ResourceRequest::TargetIsSubresource;
@@ -214,13 +214,15 @@ static ResourceRequest::TargetType requestTargetType(const ResourceFetcher* fetc
return ResourceRequest::TargetIsTextTrack;
case Resource::SVGDocument:
return ResourceRequest::TargetIsImage;
+ case Resource::Media:
+ return ResourceRequest::TargetIsMedia;
}
ASSERT_NOT_REACHED();
return ResourceRequest::TargetIsSubresource;
}
ResourceFetcher::ResourceFetcher(DocumentLoader* documentLoader)
- : m_document(0)
+ : m_document(nullptr)
, m_documentLoader(documentLoader)
, m_requestCount(0)
, m_garbageCollectDocumentResourcesTimer(this, &ResourceFetcher::garbageCollectDocumentResourcesTimerFired)
@@ -234,7 +236,7 @@ ResourceFetcher::ResourceFetcher(DocumentLoader* documentLoader)
ResourceFetcher::~ResourceFetcher()
{
m_documentLoader = 0;
- m_document = 0;
+ m_document = nullptr;
clearPreloads();
@@ -242,30 +244,24 @@ ResourceFetcher::~ResourceFetcher()
ASSERT(!m_requestCount);
}
-Resource* ResourceFetcher::cachedResource(const String& resourceURL) const
-{
- KURL url = m_document->completeURL(resourceURL);
- return cachedResource(url);
-}
-
Resource* ResourceFetcher::cachedResource(const KURL& resourceURL) const
{
KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(resourceURL);
return m_documentResources.get(url).get();
}
-Frame* ResourceFetcher::frame() const
+LocalFrame* ResourceFetcher::frame() const
{
if (m_documentLoader)
return m_documentLoader->frame();
- if (m_document && m_document->import())
- return m_document->import()->frame();
+ if (m_document && m_document->importsController())
+ return m_document->importsController()->master()->frame();
return 0;
}
FetchContext& ResourceFetcher::context() const
{
- if (Frame* frame = this->frame())
+ if (LocalFrame* frame = this->frame())
return frame->fetchContext();
return FetchContext::nullInstance();
}
@@ -282,7 +278,7 @@ ResourcePtr<Resource> ResourceFetcher::fetchSynchronously(FetchRequest& request)
ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request)
{
- if (Frame* f = frame()) {
+ if (LocalFrame* f = frame()) {
if (f->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) {
KURL requestURL = request.resourceRequest().url();
if (requestURL.isValid() && canRequest(Resource::Image, requestURL, request.options(), request.forPreload(), request.originRestriction()))
@@ -306,8 +302,10 @@ void ResourceFetcher::preCacheDataURIImage(const FetchRequest& request)
if (memoryCache()->resourceForURL(url))
return;
- if (Resource* resource = resourceFromDataURIRequest(request.resourceRequest(), request.options()))
+ if (Resource* resource = resourceFromDataURIRequest(request.resourceRequest(), request.options())) {
memoryCache()->add(resource);
+ scheduleDocumentResourcesGC();
+ }
}
ResourcePtr<FontResource> ResourceFetcher::fetchFont(FetchRequest& request)
@@ -315,11 +313,6 @@ ResourcePtr<FontResource> ResourceFetcher::fetchFont(FetchRequest& request)
return toFontResource(requestResource(Resource::Font, request));
}
-ResourcePtr<ShaderResource> ResourceFetcher::fetchShader(FetchRequest& request)
-{
- return toShaderResource(requestResource(Resource::Shader, request));
-}
-
ResourcePtr<RawResource> ResourceFetcher::fetchImport(FetchRequest& request)
{
return toRawResource(requestResource(Resource::ImportResource, request));
@@ -340,7 +333,7 @@ ResourcePtr<CSSStyleSheetResource> ResourceFetcher::fetchUserCSSStyleSheet(Fetch
memoryCache()->remove(existing);
}
- request.setOptions(ResourceLoaderOptions(DoNotSendCallbacks, SniffContent, BufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck, CheckContentSecurityPolicy, DocumentContext));
+ request.setOptions(ResourceLoaderOptions(SniffContent, BufferData, AllowStoredCredentials, ClientRequestedCredentials, CheckContentSecurityPolicy, DocumentContext));
return toCSSStyleSheetResource(requestResource(Resource::CSSStyleSheet, request));
}
@@ -372,11 +365,41 @@ ResourcePtr<RawResource> ResourceFetcher::fetchRawResource(FetchRequest& request
return toRawResource(requestResource(Resource::Raw, request));
}
-ResourcePtr<RawResource> ResourceFetcher::fetchMainResource(FetchRequest& request)
+ResourcePtr<RawResource> ResourceFetcher::fetchMainResource(FetchRequest& request, const SubstituteData& substituteData)
{
+ if (substituteData.isValid())
+ preCacheSubstituteDataForMainResource(request, substituteData);
return toRawResource(requestResource(Resource::MainResource, request));
}
+ResourcePtr<RawResource> ResourceFetcher::fetchMedia(FetchRequest& request)
+{
+ return toRawResource(requestResource(Resource::Media, request));
+}
+
+ResourcePtr<RawResource> ResourceFetcher::fetchTextTrack(FetchRequest& request)
+{
+ return toRawResource(requestResource(Resource::TextTrack, request));
+}
+
+void ResourceFetcher::preCacheSubstituteDataForMainResource(const FetchRequest& request, const SubstituteData& substituteData)
+{
+ const KURL& url = request.url();
+ if (Resource* oldResource = memoryCache()->resourceForURL(url))
+ memoryCache()->remove(oldResource);
+
+ ResourceResponse response(url, substituteData.mimeType(), substituteData.content()->size(), substituteData.textEncoding(), emptyString());
+ ResourcePtr<Resource> resource = createResource(Resource::MainResource, request.resourceRequest(), substituteData.textEncoding());
+ resource->setNeedsSynchronousCacheHit(substituteData.forceSynchronousLoad());
+ resource->setOptions(request.options());
+ resource->setDataBufferingPolicy(BufferData);
+ resource->responseReceived(response);
+ if (substituteData.content()->size())
+ resource->setResourceBuffer(substituteData.content());
+ resource->finish();
+ memoryCache()->add(resource.get());
+}
+
bool ResourceFetcher::checkInsecureContent(Resource::Type type, const KURL& url, MixedContentBlockingTreatment treatment) const
{
if (treatment == TreatAsDefaultForType) {
@@ -392,11 +415,16 @@ bool ResourceFetcher::checkInsecureContent(Resource::Type type, const KURL& url,
treatment = TreatAsActiveContent;
break;
+ case Resource::Font:
+ // These resources are passive, but mixed usage is low enough that we
+ // can block them in a mixed context.
+ treatment = TreatAsActiveContent;
+ break;
+
case Resource::TextTrack:
- case Resource::Shader:
case Resource::Raw:
case Resource::Image:
- case Resource::Font:
+ case Resource::Media:
// These resources can corrupt only the frame's pixels.
treatment = TreatAsPassiveContent;
break;
@@ -409,19 +437,46 @@ bool ResourceFetcher::checkInsecureContent(Resource::Type type, const KURL& url,
break;
}
}
+ // FIXME: We need a way to access the top-level frame's mixedContentChecker when that frame
+ // is in a different process from the current frame. Until that is done, we fail loading
+ // mixed content in remote frames.
+ if (frame() && !frame()->tree().top()->isLocalFrame())
+ return false;
if (treatment == TreatAsActiveContent) {
- if (Frame* f = frame()) {
+ if (LocalFrame* f = frame()) {
if (!f->loader().mixedContentChecker()->canRunInsecureContent(m_document->securityOrigin(), url))
return false;
Frame* top = f->tree().top();
- if (top != f && !top->loader().mixedContentChecker()->canRunInsecureContent(top->document()->securityOrigin(), url))
+ if (top != f && !toLocalFrame(top)->loader().mixedContentChecker()->canRunInsecureContent(toLocalFrame(top)->document()->securityOrigin(), url))
return false;
}
} else if (treatment == TreatAsPassiveContent) {
- if (Frame* f = frame()) {
+ if (LocalFrame* f = frame()) {
Frame* top = f->tree().top();
- if (!top->loader().mixedContentChecker()->canDisplayInsecureContent(top->document()->securityOrigin(), url))
+ if (!toLocalFrame(top)->loader().mixedContentChecker()->canDisplayInsecureContent(toLocalFrame(top)->document()->securityOrigin(), url))
return false;
+ if (MixedContentChecker::isMixedContent(toLocalFrame(top)->document()->securityOrigin(), url)) {
+ switch (type) {
+ case Resource::TextTrack:
+ UseCounter::count(toLocalFrame(top)->document(), UseCounter::MixedContentTextTrack);
+ break;
+
+ case Resource::Raw:
+ UseCounter::count(toLocalFrame(top)->document(), UseCounter::MixedContentRaw);
+ break;
+
+ case Resource::Image:
+ UseCounter::count(toLocalFrame(top)->document(), UseCounter::MixedContentImage);
+ break;
+
+ case Resource::Media:
+ UseCounter::count(toLocalFrame(top)->document(), UseCounter::MixedContentMedia);
+ break;
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
}
} else {
ASSERT(treatment == TreatAsAlwaysAllowedContent);
@@ -429,7 +484,7 @@ bool ResourceFetcher::checkInsecureContent(Resource::Type type, const KURL& url,
return true;
}
-bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const ResourceLoaderOptions& options, bool forPreload, FetchRequest::OriginRestriction originRestriction)
+bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const ResourceLoaderOptions& options, bool forPreload, FetchRequest::OriginRestriction originRestriction) const
{
SecurityOrigin* securityOrigin = options.securityOrigin.get();
if (!securityOrigin && document())
@@ -458,8 +513,8 @@ bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res
case Resource::LinkPrefetch:
case Resource::LinkSubresource:
case Resource::TextTrack:
- case Resource::Shader:
case Resource::ImportResource:
+ case Resource::Media:
// By default these types of resources can be loaded from any origin.
// FIXME: Are we sure about Resource::Font?
if (originRestriction == FetchRequest::RestrictToSameOrigin && !securityOrigin->canRequest(url)) {
@@ -477,38 +532,40 @@ bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res
break;
}
+ // Don't send CSP messages for preloads, we might never actually display those items.
+ ContentSecurityPolicy::ReportingStatus cspReporting = forPreload ?
+ ContentSecurityPolicy::SuppressReport : ContentSecurityPolicy::SendReport;
+
switch (type) {
case Resource::XSLStyleSheet:
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
- if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url))
+ if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url, cspReporting))
return false;
break;
case Resource::Script:
case Resource::ImportResource:
- if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url))
+ if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowScriptFromSource(url, cspReporting))
return false;
if (frame()) {
Settings* settings = frame()->settings();
- if (!frame()->loader().client()->allowScriptFromSource(!settings || settings->isScriptEnabled(), url)) {
+ if (!frame()->loader().client()->allowScriptFromSource(!settings || settings->scriptEnabled(), url)) {
frame()->loader().client()->didNotAllowScript();
return false;
}
}
break;
- case Resource::Shader:
- // Since shaders are referenced from CSS Styles use the same rules here.
case Resource::CSSStyleSheet:
- if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowStyleFromSource(url))
+ if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowStyleFromSource(url, cspReporting))
return false;
break;
case Resource::SVGDocument:
case Resource::Image:
- if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowImageFromSource(url))
+ if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowImageFromSource(url, cspReporting))
return false;
break;
case Resource::Font: {
- if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowFontFromSource(url))
+ if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowFontFromSource(url, cspReporting))
return false;
break;
}
@@ -517,12 +574,20 @@ bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res
case Resource::LinkPrefetch:
case Resource::LinkSubresource:
break;
+ case Resource::Media:
case Resource::TextTrack:
- if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowMediaFromSource(url))
+ if (!shouldBypassMainWorldContentSecurityPolicy && !m_document->contentSecurityPolicy()->allowMediaFromSource(url, cspReporting))
return false;
break;
}
+ // SVG Images have unique security rules that prevent all subresource requests
+ // except for data urls.
+ if (type != Resource::MainResource) {
+ if (frame() && frame()->chromeClient().isSVGImageChromeClient() && !url.protocolIsData())
+ return false;
+ }
+
// Last of all, check for insecure content. We do this last so that when
// folks block insecure content with a CSP policy, they don't get a warning.
// They'll still get a warning in the console about CSP blocking the load.
@@ -534,42 +599,38 @@ bool ResourceFetcher::canRequest(Resource::Type type, const KURL& url, const Res
return true;
}
-bool ResourceFetcher::canAccess(Resource* resource, CORSEnabled corsEnabled, FetchRequest::OriginRestriction originRestriction)
+bool ResourceFetcher::canAccessResource(Resource* resource, SecurityOrigin* sourceOrigin, const KURL& url) const
{
// Redirects can change the response URL different from one of request.
- if (!canRequest(resource->type(), resource->response().url(), resource->options(), false, originRestriction))
+ if (!canRequest(resource->type(), url, resource->options(), false, FetchRequest::UseDefaultOriginRestrictionForType))
return false;
- String error;
- switch (resource->type()) {
- case Resource::Script:
- case Resource::ImportResource:
- if (corsEnabled == PotentiallyCORSEnabled
- && !m_document->securityOrigin()->canRequest(resource->response().url())
- && !resource->passesAccessControlCheck(m_document->securityOrigin(), error)) {
- if (frame() && frame()->document())
- frame()->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, "Script from origin '" + SecurityOrigin::create(resource->response().url())->toString() + "' has been blocked from loading by Cross-Origin Resource Sharing policy: " + error);
- return false;
- }
+ if (!sourceOrigin && document())
+ sourceOrigin = document()->securityOrigin();
- break;
- default:
- ASSERT_NOT_REACHED(); // FIXME: generalize to non-script resources
+ if (sourceOrigin->canRequest(url))
+ return true;
+
+ String errorDescription;
+ if (!resource->passesAccessControlCheck(sourceOrigin, errorDescription)) {
+ if (frame() && frame()->document()) {
+ String resourceType = Resource::resourceTypeToString(resource->type(), resource->options().initiatorInfo);
+ frame()->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, resourceType + " from origin '" + SecurityOrigin::create(url)->toString() + "' has been blocked from loading by Cross-Origin Resource Sharing policy: " + errorDescription);
+ }
return false;
}
-
return true;
}
-bool ResourceFetcher::shouldLoadNewResource() const
+bool ResourceFetcher::shouldLoadNewResource(Resource::Type type) const
{
if (!frame())
return false;
if (!m_documentLoader)
return true;
- if (m_documentLoader == frame()->loader().activeDocumentLoader())
- return true;
- return document() && document()->pageDismissalEventBeingDispatched() != Document::NoDismissal;
+ if (type == Resource::MainResource)
+ return m_documentLoader == frame()->loader().provisionalDocumentLoader();
+ return m_documentLoader == frame()->loader().documentLoader();
}
bool ResourceFetcher::resourceNeedsLoad(Resource* resource, const FetchRequest& request, RevalidationPolicy policy)
@@ -583,10 +644,32 @@ bool ResourceFetcher::resourceNeedsLoad(Resource* resource, const FetchRequest&
return request.options().synchronousPolicy == RequestSynchronously && resource->isLoading();
}
+void ResourceFetcher::requestLoadStarted(Resource* resource, const FetchRequest& request, ResourceLoadStartType type)
+{
+ if (type == ResourceLoadingFromCache)
+ notifyLoadedFromMemoryCache(resource);
+
+ if (request.resourceRequest().url().protocolIsData() || (m_documentLoader && m_documentLoader->substituteData().isValid()))
+ return;
+
+ if (type == ResourceLoadingFromCache && !m_validatedURLs.contains(request.resourceRequest().url())) {
+ // Resources loaded from memory cache should be reported the first time they're used.
+ RefPtr<ResourceTimingInfo> info = ResourceTimingInfo::create(request.options().initiatorInfo.name, monotonicallyIncreasingTime());
+ populateResourceTiming(info.get(), resource, true);
+ m_scheduledResourceTimingReports.add(info, resource->type() == Resource::MainResource);
+ if (!m_resourceTimingReportTimer.isActive())
+ m_resourceTimingReportTimer.startOneShot(0, FROM_HERE);
+ }
+
+ m_validatedURLs.add(request.resourceRequest().url());
+}
+
ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, FetchRequest& request)
{
ASSERT(request.options().synchronousPolicy == RequestAsynchronously || type == Resource::Raw);
+ TRACE_EVENT0("webkit", "ResourceFetcher::requestResource");
+
KURL url = request.resourceRequest().url();
WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource '%s', charset '%s', priority=%d, forPreload=%u, type=%s", url.elidedString().latin1().data(), request.charset().latin1().data(), request.priority(), request.forPreload(), ResourceTypeName(type));
@@ -600,32 +683,34 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
if (!canRequest(type, url, request.options(), request.forPreload(), request.originRestriction()))
return 0;
- if (Frame* f = frame())
+ if (LocalFrame* f = frame())
f->loader().client()->dispatchWillRequestResource(&request);
// See if we can use an existing resource from the cache.
ResourcePtr<Resource> resource = memoryCache()->resourceForURL(url);
- const RevalidationPolicy policy = determineRevalidationPolicy(type, request.mutableResourceRequest(), request.forPreload(), resource.get(), request.defer());
+ const RevalidationPolicy policy = determineRevalidationPolicy(type, request.mutableResourceRequest(), request.forPreload(), resource.get(), request.defer(), request.options());
switch (policy) {
case Reload:
memoryCache()->remove(resource.get());
// Fall through
case Load:
- resource = loadResource(type, request, request.charset());
+ resource = createResourceForLoading(type, request, request.charset());
break;
case Revalidate:
- resource = revalidateResource(request, resource.get());
+ resource = createResourceForRevalidation(request, resource.get());
break;
case Use:
- resource->updateForAccess();
- notifyLoadedFromMemoryCache(resource.get());
+ memoryCache()->updateForAccess(resource.get());
break;
}
if (!resource)
return 0;
+ if (!resource->hasClients())
+ m_deadStatsRecorder.update(policy);
+
if (policy != Use)
resource->setIdentifier(createUniqueIdentifier());
@@ -633,13 +718,13 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
ResourceLoadPriority priority = loadPriority(type, request);
if (priority != resource->resourceRequest().priority()) {
resource->resourceRequest().setPriority(priority);
- resource->didChangePriority(priority);
+ resource->didChangePriority(priority, 0);
}
}
if (resourceNeedsLoad(resource.get(), request, policy)) {
- if (!shouldLoadNewResource()) {
- if (resource->inCache())
+ if (!shouldLoadNewResource(type)) {
+ if (memoryCache()->contains(resource.get()))
memoryCache()->remove(resource.get());
return 0;
}
@@ -654,7 +739,7 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
// In that case, the requester should have access to the relevant ResourceError, so
// we need to return a non-null Resource.
if (resource->errorOccurred()) {
- if (resource->inCache())
+ if (memoryCache()->contains(resource.get()))
memoryCache()->remove(resource.get());
return request.options().synchronousPolicy == RequestSynchronously ? resource : 0;
}
@@ -664,29 +749,14 @@ ResourcePtr<Resource> ResourceFetcher::requestResource(Resource::Type type, Fetc
// see https://bugs.webkit.org/show_bug.cgi?id=107962. Before caching main
// resources, we should be sure to understand the implications for memory
// use.
- //
- // Ensure main resources aren't preloaded, and other main resource loads
- // are removed from cache to prevent reuse.
+ // Remove main resource from cache to prevent reuse.
if (type == Resource::MainResource) {
- ASSERT(policy != Use);
+ ASSERT(policy != Use || m_documentLoader->substituteData().isValid());
ASSERT(policy != Revalidate);
memoryCache()->remove(resource.get());
- if (request.forPreload())
- return 0;
}
- if (!request.resourceRequest().url().protocolIsData()) {
- if (policy == Use && !m_validatedURLs.contains(request.resourceRequest().url())) {
- // Resources loaded from memory cache should be reported the first time they're used.
- RefPtr<ResourceTimingInfo> info = ResourceTimingInfo::create(request.options().initiatorInfo.name, monotonicallyIncreasingTime());
- populateResourceTiming(info.get(), resource.get(), true);
- m_scheduledResourceTimingReports.add(info, resource->type() == Resource::MainResource);
- if (!m_resourceTimingReportTimer.isActive())
- m_resourceTimingReportTimer.startOneShot(0);
- }
-
- m_validatedURLs.add(request.resourceRequest().url());
- }
+ requestLoadStarted(resource.get(), request, policy == Use ? ResourceLoadingFromCache : ResourceLoadingFromNetwork);
ASSERT(resource->url() == url.string());
m_documentResources.set(resource->url(), resource);
@@ -716,22 +786,24 @@ ResourceRequestCachePolicy ResourceFetcher::resourceRequestCachePolicy(const Res
{
if (type == Resource::MainResource) {
FrameLoadType frameLoadType = frame()->loader().loadType();
- bool isReload = frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin;
if (request.httpMethod() == "POST" && frameLoadType == FrameLoadTypeBackForward)
return ReturnCacheDataDontLoad;
if (!m_documentLoader->overrideEncoding().isEmpty() || frameLoadType == FrameLoadTypeBackForward)
return ReturnCacheDataElseLoad;
- if (isReload || frameLoadType == FrameLoadTypeSame || request.isConditional() || request.httpMethod() == "POST")
+ if (frameLoadType == FrameLoadTypeReloadFromOrigin)
+ return ReloadBypassingCache;
+ if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeSame || request.isConditional() || request.httpMethod() == "POST")
return ReloadIgnoringCacheData;
- if (Frame* parent = frame()->tree().parent())
- return parent->document()->fetcher()->resourceRequestCachePolicy(request, type);
+ Frame* parent = frame()->tree().parent();
+ if (parent && parent->isLocalFrame())
+ return toLocalFrame(parent)->document()->fetcher()->resourceRequestCachePolicy(request, type);
return UseProtocolCachePolicy;
}
if (request.isConditional())
return ReloadIgnoringCacheData;
- if (m_documentLoader && m_documentLoader->isLoadingInAPISense()) {
+ if (m_documentLoader && m_document && !m_document->loadEventFinished()) {
// For POST requests, we mutate the main resource's cache policy to avoid form resubmission.
// This policy should not be inherited by subresources.
ResourceRequestCachePolicy mainResourceCachePolicy = m_documentLoader->request().cachePolicy();
@@ -754,18 +826,19 @@ void ResourceFetcher::addAdditionalRequestHeaders(ResourceRequest& request, Reso
if (type == Resource::LinkPrefetch || type == Resource::LinkSubresource)
request.setHTTPHeaderField("Purpose", "prefetch");
- context().addAdditionalRequestHeaders(*document(), request, type);
+ context().addAdditionalRequestHeaders(document(), request, (type == Resource::MainResource) ? FetchMainResource : FetchSubresource);
}
-ResourcePtr<Resource> ResourceFetcher::revalidateResource(const FetchRequest& request, Resource* resource)
+ResourcePtr<Resource> ResourceFetcher::createResourceForRevalidation(const FetchRequest& request, Resource* resource)
{
ASSERT(resource);
- ASSERT(resource->inCache());
+ ASSERT(memoryCache()->contains(resource));
ASSERT(resource->isLoaded());
ASSERT(resource->canUseCacheValidator());
ASSERT(!resource->resourceToRevalidate());
ResourceRequest revalidatingRequest(resource->resourceRequest());
+ revalidatingRequest.clearHTTPReferrer();
addAdditionalRequestHeaders(revalidatingRequest, resource->type());
const AtomicString& lastModified = resource->response().httpHeaderField("Last-Modified");
@@ -774,59 +847,62 @@ ResourcePtr<Resource> ResourceFetcher::revalidateResource(const FetchRequest& re
ASSERT(context().cachePolicy(document()) != CachePolicyReload);
if (context().cachePolicy(document()) == CachePolicyRevalidate)
revalidatingRequest.setHTTPHeaderField("Cache-Control", "max-age=0");
- if (!lastModified.isEmpty())
- revalidatingRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
- if (!eTag.isEmpty())
- revalidatingRequest.setHTTPHeaderField("If-None-Match", eTag);
}
+ if (!lastModified.isEmpty())
+ revalidatingRequest.setHTTPHeaderField("If-Modified-Since", lastModified);
+ if (!eTag.isEmpty())
+ revalidatingRequest.setHTTPHeaderField("If-None-Match", eTag);
ResourcePtr<Resource> newResource = createResource(resource->type(), revalidatingRequest, resource->encoding());
-
WTF_LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource.get(), resource);
+
newResource->setResourceToRevalidate(resource);
memoryCache()->remove(resource);
memoryCache()->add(newResource.get());
- storeResourceTimingInitiatorInformation(newResource, request);
- TRACE_EVENT_ASYNC_BEGIN2("net", "Resource", newResource.get(), "url", newResource->url().string().ascii(), "priority", newResource->resourceRequest().priority());
return newResource;
}
-ResourcePtr<Resource> ResourceFetcher::loadResource(Resource::Type type, FetchRequest& request, const String& charset)
+ResourcePtr<Resource> ResourceFetcher::createResourceForLoading(Resource::Type type, FetchRequest& request, const String& charset)
{
ASSERT(!memoryCache()->resourceForURL(request.resourceRequest().url()));
WTF_LOG(ResourceLoading, "Loading Resource for '%s'.", request.resourceRequest().url().elidedString().latin1().data());
addAdditionalRequestHeaders(request.mutableResourceRequest(), type);
- ResourcePtr<Resource> resource = createResource(type, request.mutableResourceRequest(), charset);
+ ResourcePtr<Resource> resource = createResource(type, request.resourceRequest(), charset);
memoryCache()->add(resource.get());
- storeResourceTimingInitiatorInformation(resource, request);
- TRACE_EVENT_ASYNC_BEGIN2("net", "Resource", resource.get(), "url", resource->url().string().ascii(), "priority", resource->resourceRequest().priority());
return resource;
}
-void ResourceFetcher::storeResourceTimingInitiatorInformation(const ResourcePtr<Resource>& resource, const FetchRequest& request)
+void ResourceFetcher::storeResourceTimingInitiatorInformation(Resource* resource)
{
- if (request.options().requestInitiatorContext != DocumentContext)
+ if (resource->options().requestInitiatorContext != DocumentContext)
return;
- RefPtr<ResourceTimingInfo> info = ResourceTimingInfo::create(request.options().initiatorInfo.name, monotonicallyIncreasingTime());
+ RefPtr<ResourceTimingInfo> info = ResourceTimingInfo::create(resource->options().initiatorInfo.name, monotonicallyIncreasingTime());
+
+ if (resource->isCacheValidator()) {
+ const AtomicString& timingAllowOrigin = resource->resourceToRevalidate()->response().httpHeaderField("Timing-Allow-Origin");
+ if (!timingAllowOrigin.isEmpty())
+ info->setOriginalTimingAllowOrigin(timingAllowOrigin);
+ }
if (resource->type() == Resource::MainResource) {
// <iframe>s should report the initial navigation requested by the parent document, but not subsequent navigations.
- if (frame()->ownerElement() && !frame()->ownerElement()->loadedNonEmptyDocument()) {
- info->setInitiatorType(frame()->ownerElement()->localName());
- m_resourceTimingInfoMap.add(resource.get(), info);
- frame()->ownerElement()->didLoadNonEmptyDocument();
+ // FIXME: Resource timing is broken when the parent is a remote frame.
+ if (frame()->deprecatedLocalOwner() && !frame()->deprecatedLocalOwner()->loadedNonEmptyDocument()) {
+ info->setInitiatorType(frame()->deprecatedLocalOwner()->localName());
+ m_resourceTimingInfoMap.add(resource, info);
+ frame()->deprecatedLocalOwner()->didLoadNonEmptyDocument();
}
} else {
- m_resourceTimingInfoMap.add(resource.get(), info);
+ m_resourceTimingInfoMap.add(resource, info);
}
}
-ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy(Resource::Type type, ResourceRequest& request, bool forPreload, Resource* existingResource, FetchRequest::DeferOption defer) const
+ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy(Resource::Type type, ResourceRequest& request, bool forPreload, Resource* existingResource, FetchRequest::DeferOption defer, const ResourceLoaderOptions& options) const
{
if (!existingResource)
return Load;
@@ -851,9 +927,17 @@ ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy
if (type == Resource::Image && request.url().protocolIsData())
return Use;
+ // If a main resource was populated from a SubstituteData load, use it.
+ if (type == Resource::MainResource && m_documentLoader->substituteData().isValid())
+ return Use;
+
if (!existingResource->canReuse(request))
return Reload;
+ // Never use cache entries for downloadToFile requests. The caller expects the resource in a file.
+ if (request.downloadToFile())
+ return Reload;
+
// Certain requests (e.g., XHRs) might have manually set headers that require revalidation.
// FIXME: In theory, this should be a Revalidate case. In practice, the MemoryCache revalidation path assumes a whole bunch
// of things about how revalidation works that manual headers violate, so punt to Reload instead.
@@ -864,7 +948,7 @@ ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy
if (m_allowStaleResources)
return Use;
- // Alwaus use preloads.
+ // Always use preloads.
if (existingResource->isPreloaded())
return Use;
@@ -874,26 +958,37 @@ ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy
return Use;
// Don't reuse resources with Cache-control: no-store.
- if (existingResource->response().cacheControlContainsNoStore()) {
+ if (existingResource->hasCacheControlNoStoreHeader()) {
WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to Cache-control: no-store.");
return Reload;
}
+ // If fetching a resource with a different 'CORS enabled' flag, reload.
+ if (type != Resource::MainResource && options.corsEnabled != existingResource->options().corsEnabled)
+ return Reload;
+
// If credentials were sent with the previous request and won't be
// with this one, or vice versa, re-fetch the resource.
//
// This helps with the case where the server sends back
// "Access-Control-Allow-Origin: *" all the time, but some of the
// client's requests are made without CORS and some with.
- if (existingResource->resourceRequest().allowCookies() != request.allowCookies()) {
+ if (existingResource->resourceRequest().allowStoredCredentials() != request.allowStoredCredentials()) {
WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to difference in credentials settings.");
return Reload;
}
// During the initial load, avoid loading the same resource multiple times for a single document,
- // even if the cache policies would tell us to. Raw resources are exempted.
- if (type != Resource::Raw && document() && !document()->loadEventFinished() && m_validatedURLs.contains(existingResource->url()))
- return Use;
+ // even if the cache policies would tell us to.
+ // We also group loads of the same resource together.
+ // Raw resources are exempted, as XHRs fall into this category and may have user-set Cache-Control:
+ // headers or other factors that require separate requests.
+ if (type != Resource::Raw) {
+ if (document() && !document()->loadEventFinished() && m_validatedURLs.contains(existingResource->url()))
+ return Use;
+ if (existingResource->isLoading())
+ return Use;
+ }
// CachePolicyReload always reloads
if (cachePolicy == CachePolicyReload) {
@@ -907,12 +1002,20 @@ ResourceFetcher::RevalidationPolicy ResourceFetcher::determineRevalidationPolicy
return Reload;
}
- // For resources that are not yet loaded we ignore the cache policy.
- if (existingResource->isLoading())
+ // List of available images logic allows images to be re-used without cache validation. We restrict this only to images
+ // from memory cache which are the same as the version in the current document.
+ if (type == Resource::Image && existingResource == cachedResource(request.url()))
return Use;
+ // If any of the redirects in the chain to loading the resource were not cacheable, we cannot reuse our cached resource.
+ if (!existingResource->canReuseRedirectChain()) {
+ WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to an uncacheable redirect");
+ return Reload;
+ }
+
// Check if the cache headers requires us to revalidate (cache expiration for example).
- if (cachePolicy == CachePolicyRevalidate || existingResource->mustRevalidateDueToCacheHeaders()) {
+ if (cachePolicy == CachePolicyRevalidate || existingResource->mustRevalidateDueToCacheHeaders()
+ || request.cacheControlContainsNoCache()) {
// See if the resource has usable ETag or Last-modified headers.
if (existingResource->canUseCacheValidator())
return Revalidate;
@@ -998,7 +1101,7 @@ void ResourceFetcher::redirectReceived(Resource* resource, const ResourceRespons
void ResourceFetcher::didLoadResource(Resource* resource)
{
RefPtr<DocumentLoader> protectDocumentLoader(m_documentLoader);
- RefPtr<Document> protectDocument(m_document);
+ RefPtrWillBeRawPtr<Document> protectDocument(m_document.get());
if (resource && resource->response().isHTTP() && ((!resource->errorOccurred() && !resource->wasCanceled()) || resource->response().httpStatusCode() == 304) && document()) {
ResourceTimingInfoMap::iterator it = m_resourceTimingInfoMap.find(resource);
@@ -1012,10 +1115,13 @@ void ResourceFetcher::didLoadResource(Resource* resource)
if (frame())
frame()->loader().loadDone();
- performPostLoadActions();
+ scheduleDocumentResourcesGC();
+}
+void ResourceFetcher::scheduleDocumentResourcesGC()
+{
if (!m_garbageCollectDocumentResourcesTimer.isActive())
- m_garbageCollectDocumentResourcesTimer.startOneShot(0);
+ m_garbageCollectDocumentResourcesTimer.startOneShot(0, FROM_HERE);
}
// Garbage collecting m_documentResources is a workaround for the
@@ -1040,27 +1146,19 @@ void ResourceFetcher::garbageCollectDocumentResources()
resourcesToDelete.append(it->key);
}
- for (StringVector::const_iterator it = resourcesToDelete.begin(); it != resourcesToDelete.end(); ++it)
- m_documentResources.remove(*it);
-}
-
-void ResourceFetcher::performPostLoadActions()
-{
- checkForPendingPreloads();
+ m_documentResources.removeAll(resourcesToDelete);
}
void ResourceFetcher::notifyLoadedFromMemoryCache(Resource* resource)
{
if (!frame() || !frame()->page() || resource->status() != Resource::Cached || m_validatedURLs.contains(resource->url()))
return;
- if (!resource->shouldSendResourceLoadCallbacks())
- return;
ResourceRequest request(resource->url());
unsigned long identifier = createUniqueIdentifier();
context().dispatchDidLoadResourceFromMemoryCache(request, resource->response());
// FIXME: If willSendRequest changes the request, we don't respect it.
- willSendRequest(identifier, request, ResourceResponse(), resource->options());
+ willSendRequest(identifier, request, ResourceResponse(), resource->options().initiatorInfo);
InspectorInstrumentation::markResourceAsCached(frame()->page(), identifier);
context().sendRemainingDelegateMessages(m_documentLoader, identifier, resource->response(), resource->encodedSize());
}
@@ -1087,22 +1185,12 @@ void ResourceFetcher::preload(Resource::Type type, FetchRequest& request, const
requestPreload(type, request, charset);
}
-void ResourceFetcher::checkForPendingPreloads()
+void ResourceFetcher::requestPreload(Resource::Type type, FetchRequest& request, const String& charset)
{
- // FIXME: It seems wrong to poke body()->renderer() here.
- if (m_pendingPreloads.isEmpty() || !m_document->body() || !m_document->body()->renderer())
+ // Ensure main resources aren't preloaded, since the cache can't actually reuse the preload.
+ if (type == Resource::MainResource)
return;
- while (!m_pendingPreloads.isEmpty()) {
- PendingPreload preload = m_pendingPreloads.takeFirst();
- // Don't request preload if the resource already loaded normally (this will result in double load if the page is being reloaded with cached results ignored).
- if (!cachedResource(preload.m_request.resourceRequest().url()))
- requestPreload(preload.m_type, preload.m_request, preload.m_charset);
- }
- m_pendingPreloads.clear();
-}
-void ResourceFetcher::requestPreload(Resource::Type type, FetchRequest& request, const String& charset)
-{
String encoding;
if (type == Resource::Script || type == Resource::CSSStyleSheet)
encoding = charset.isEmpty() ? m_document->charset().string() : charset;
@@ -1121,7 +1209,7 @@ void ResourceFetcher::requestPreload(Resource::Type type, FetchRequest& request,
m_preloads->add(resource.get());
#if PRELOAD_DEBUG
- printf("PRELOADING %s\n", resource->url().latin1().data());
+ printf("PRELOADING %s\n", resource->url().string().latin1().data());
#endif
}
@@ -1138,12 +1226,6 @@ bool ResourceFetcher::isPreloaded(const String& urlString) const
}
}
- Deque<PendingPreload>::const_iterator dequeEnd = m_pendingPreloads.end();
- for (Deque<PendingPreload>::const_iterator it = m_pendingPreloads.begin(); it != dequeEnd; ++it) {
- PendingPreload pendingPreload = *it;
- if (pendingPreload.m_request.resourceRequest().url() == url)
- return true;
- }
return false;
}
@@ -1166,75 +1248,52 @@ void ResourceFetcher::clearPreloads()
m_preloads.clear();
}
-void ResourceFetcher::clearPendingPreloads()
-{
- m_pendingPreloads.clear();
-}
-
-void ResourceFetcher::didFinishLoading(const Resource* resource, double finishTime, const ResourceLoaderOptions& options)
+void ResourceFetcher::didFinishLoading(const Resource* resource, double finishTime, int64_t encodedDataLength)
{
TRACE_EVENT_ASYNC_END0("net", "Resource", resource);
- if (options.sendLoadCallbacks != SendCallbacks)
- return;
- context().dispatchDidFinishLoading(m_documentLoader, resource->identifier(), finishTime);
+ context().dispatchDidFinishLoading(m_documentLoader, resource->identifier(), finishTime, encodedDataLength);
}
-void ResourceFetcher::didChangeLoadingPriority(const Resource* resource, ResourceLoadPriority loadPriority)
+void ResourceFetcher::didChangeLoadingPriority(const Resource* resource, ResourceLoadPriority loadPriority, int intraPriorityValue)
{
TRACE_EVENT_ASYNC_STEP_INTO1("net", "Resource", resource, "ChangePriority", "priority", loadPriority);
- context().dispatchDidChangeResourcePriority(resource->identifier(), loadPriority);
+ context().dispatchDidChangeResourcePriority(resource->identifier(), loadPriority, intraPriorityValue);
}
-void ResourceFetcher::didFailLoading(const Resource* resource, const ResourceError& error, const ResourceLoaderOptions& options)
+void ResourceFetcher::didFailLoading(const Resource* resource, const ResourceError& error)
{
TRACE_EVENT_ASYNC_END0("net", "Resource", resource);
- if (options.sendLoadCallbacks != SendCallbacks)
- return;
context().dispatchDidFail(m_documentLoader, resource->identifier(), error);
}
-void ResourceFetcher::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse, const ResourceLoaderOptions& options)
+void ResourceFetcher::willSendRequest(unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& initiatorInfo)
{
- if (options.sendLoadCallbacks == SendCallbacks)
- context().dispatchWillSendRequest(m_documentLoader, identifier, request, redirectResponse, options.initiatorInfo);
- else
- InspectorInstrumentation::willSendRequest(frame(), identifier, m_documentLoader, request, redirectResponse, options.initiatorInfo);
+ context().dispatchWillSendRequest(m_documentLoader, identifier, request, redirectResponse, initiatorInfo);
}
-void ResourceFetcher::didReceiveResponse(const Resource* resource, const ResourceResponse& response, const ResourceLoaderOptions& options)
+void ResourceFetcher::didReceiveResponse(const Resource* resource, const ResourceResponse& response)
{
- if (options.sendLoadCallbacks != SendCallbacks)
- return;
context().dispatchDidReceiveResponse(m_documentLoader, resource->identifier(), response, resource->loader());
}
-void ResourceFetcher::didReceiveData(const Resource* resource, const char* data, int dataLength, int encodedDataLength, const ResourceLoaderOptions& options)
+void ResourceFetcher::didReceiveData(const Resource* resource, const char* data, int dataLength, int encodedDataLength)
{
- // FIXME: use frame of master document for imported documents.
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceData(frame(), resource->identifier(), encodedDataLength);
- if (options.sendLoadCallbacks != SendCallbacks)
- return;
context().dispatchDidReceiveData(m_documentLoader, resource->identifier(), data, dataLength, encodedDataLength);
- InspectorInstrumentation::didReceiveResourceData(cookie);
}
-void ResourceFetcher::didDownloadData(const Resource* resource, int dataLength, int encodedDataLength, const ResourceLoaderOptions& options)
+void ResourceFetcher::didDownloadData(const Resource* resource, int dataLength, int encodedDataLength)
{
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willReceiveResourceData(frame(), resource->identifier(), encodedDataLength);
- if (options.sendLoadCallbacks != SendCallbacks)
- return;
context().dispatchDidDownloadData(m_documentLoader, resource->identifier(), dataLength, encodedDataLength);
- InspectorInstrumentation::didReceiveResourceData(cookie);
}
void ResourceFetcher::subresourceLoaderFinishedLoadingOnePart(ResourceLoader* loader)
{
- if (m_multipartLoaders)
- m_multipartLoaders->add(loader);
- if (m_loaders)
- m_loaders->remove(loader);
- if (Frame* frame = this->frame())
- return frame->loader().checkLoadComplete(m_documentLoader);
+ if (!m_multipartLoaders)
+ m_multipartLoaders = adoptPtr(new ResourceLoaderSet());
+ m_multipartLoaders->add(loader);
+ m_loaders->remove(loader);
+ if (LocalFrame* frame = this->frame())
+ return frame->loader().checkLoadComplete();
}
void ResourceFetcher::didInitializeResourceLoader(ResourceLoader* loader)
@@ -1249,17 +1308,21 @@ void ResourceFetcher::didInitializeResourceLoader(ResourceLoader* loader)
void ResourceFetcher::willTerminateResourceLoader(ResourceLoader* loader)
{
- if (!m_loaders || !m_loaders->contains(loader))
- return;
- m_loaders->remove(loader);
- if (Frame* frame = this->frame())
- frame->loader().checkLoadComplete(m_documentLoader);
+ if (m_loaders && m_loaders->contains(loader))
+ m_loaders->remove(loader);
+ if (m_multipartLoaders && m_multipartLoaders->contains(loader))
+ m_multipartLoaders->remove(loader);
+ if (LocalFrame* frame = this->frame())
+ frame->loader().checkLoadComplete();
}
-void ResourceFetcher::willStartLoadingResource(ResourceRequest& request)
+void ResourceFetcher::willStartLoadingResource(Resource* resource, ResourceRequest& request)
{
if (m_documentLoader)
m_documentLoader->applicationCacheHost()->willStartLoadingResource(request);
+
+ storeResourceTimingInitiatorInformation(resource);
+ TRACE_EVENT_ASYNC_BEGIN2("net", "Resource", resource, "url", resource->url().string().ascii(), "priority", resource->resourceRequest().priority());
}
void ResourceFetcher::stopFetching()
@@ -1283,7 +1346,7 @@ void ResourceFetcher::setDefersLoading(bool defers)
bool ResourceFetcher::defersLoading() const
{
- if (Frame* frame = this->frame())
+ if (LocalFrame* frame = this->frame())
return frame->page()->defersLoading();
return false;
}
@@ -1293,15 +1356,28 @@ bool ResourceFetcher::isLoadedBy(ResourceLoaderHost* possibleOwner) const
return this == possibleOwner;
}
-bool ResourceFetcher::shouldRequest(Resource* resource, const ResourceRequest& request, const ResourceLoaderOptions& options)
+bool ResourceFetcher::canAccessRedirect(Resource* resource, ResourceRequest& request, const ResourceResponse& redirectResponse, ResourceLoaderOptions& options)
{
if (!canRequest(resource->type(), request.url(), options, false, FetchRequest::UseDefaultOriginRestrictionForType))
return false;
+ if (options.corsEnabled == IsCORSEnabled) {
+ SecurityOrigin* sourceOrigin = options.securityOrigin.get();
+ if (!sourceOrigin && document())
+ sourceOrigin = document()->securityOrigin();
+
+ String errorMessage;
+ if (!CrossOriginAccessControl::handleRedirect(resource, sourceOrigin, request, redirectResponse, options, errorMessage)) {
+ if (frame() && frame()->document())
+ frame()->document()->addConsoleMessage(JSMessageSource, ErrorMessageLevel, errorMessage);
+ return false;
+ }
+ }
if (resource->type() == Resource::Image && shouldDeferImageLoad(request.url()))
return false;
return true;
}
+#if !ENABLE(OILPAN)
void ResourceFetcher::refResourceLoaderHost()
{
ref();
@@ -1311,25 +1387,29 @@ void ResourceFetcher::derefResourceLoaderHost()
{
deref();
}
+#endif
#if PRELOAD_DEBUG
void ResourceFetcher::printPreloadStats()
{
+ if (!m_preloads)
+ return;
+
unsigned scripts = 0;
unsigned scriptMisses = 0;
unsigned stylesheets = 0;
unsigned stylesheetMisses = 0;
unsigned images = 0;
unsigned imageMisses = 0;
- ListHashSet<Resource*>::iterator end = m_preloads.end();
- for (ListHashSet<Resource*>::iterator it = m_preloads.begin(); it != end; ++it) {
+ ListHashSet<Resource*>::iterator end = m_preloads->end();
+ for (ListHashSet<Resource*>::iterator it = m_preloads->begin(); it != end; ++it) {
Resource* res = *it;
if (res->preloadResult() == Resource::PreloadNotReferenced)
- printf("!! UNREFERENCED PRELOAD %s\n", res->url().latin1().data());
+ printf("!! UNREFERENCED PRELOAD %s\n", res->url().string().latin1().data());
else if (res->preloadResult() == Resource::PreloadReferencedWhileComplete)
- printf("HIT COMPLETE PRELOAD %s\n", res->url().latin1().data());
+ printf("HIT COMPLETE PRELOAD %s\n", res->url().string().latin1().data());
else if (res->preloadResult() == Resource::PreloadReferencedWhileLoading)
- printf("HIT LOADING PRELOAD %s\n", res->url().latin1().data());
+ printf("HIT LOADING PRELOAD %s\n", res->url().string().latin1().data());
if (res->type() == Resource::Script) {
scripts++;
@@ -1363,8 +1443,47 @@ void ResourceFetcher::printPreloadStats()
const ResourceLoaderOptions& ResourceFetcher::defaultResourceOptions()
{
- DEFINE_STATIC_LOCAL(ResourceLoaderOptions, options, (SendCallbacks, SniffContent, BufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientForCrossOriginCredentials, DoSecurityCheck, CheckContentSecurityPolicy, DocumentContext));
+ DEFINE_STATIC_LOCAL(ResourceLoaderOptions, options, (SniffContent, BufferData, AllowStoredCredentials, ClientRequestedCredentials, CheckContentSecurityPolicy, DocumentContext));
return options;
}
+ResourceFetcher::DeadResourceStatsRecorder::DeadResourceStatsRecorder()
+ : m_useCount(0)
+ , m_revalidateCount(0)
+ , m_loadCount(0)
+{
+}
+
+ResourceFetcher::DeadResourceStatsRecorder::~DeadResourceStatsRecorder()
+{
+ blink::Platform::current()->histogramCustomCounts(
+ "WebCore.ResourceFetcher.HitCount", m_useCount, 0, 1000, 50);
+ blink::Platform::current()->histogramCustomCounts(
+ "WebCore.ResourceFetcher.RevalidateCount", m_revalidateCount, 0, 1000, 50);
+ blink::Platform::current()->histogramCustomCounts(
+ "WebCore.ResourceFetcher.LoadCount", m_loadCount, 0, 1000, 50);
+}
+
+void ResourceFetcher::DeadResourceStatsRecorder::update(RevalidationPolicy policy)
+{
+ switch (policy) {
+ case Reload:
+ case Load:
+ ++m_loadCount;
+ return;
+ case Revalidate:
+ ++m_revalidateCount;
+ return;
+ case Use:
+ ++m_useCount;
+ return;
+ }
+}
+
+void ResourceFetcher::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ ResourceLoaderHost::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
index bb1995ed325..95a15426939 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -49,41 +49,40 @@ class FontResource;
class ImageResource;
class RawResource;
class ScriptResource;
-class ShaderResource;
+class SubstituteData;
class XSLStyleSheetResource;
class Document;
class DocumentLoader;
-class Frame;
+class LocalFrame;
class FrameLoader;
class ImageLoader;
class KURL;
class ResourceTimingInfo;
class ResourceLoaderSet;
-enum CORSEnabled {
- NotCORSEnabled,
- PotentiallyCORSEnabled // Indicates "potentially CORS-enabled fetch" in HTML standard.
-};
-
// The ResourceFetcher provides a per-context interface to the MemoryCache
// and enforces a bunch of security checks and rules for resource revalidation.
// Its lifetime is roughly per-DocumentLoader, in that it is generally created
// in the DocumentLoader constructor and loses its ability to generate network
// requests when the DocumentLoader is destroyed. Documents also hold a
// RefPtr<ResourceFetcher> for their lifetime (and will create one if they
-// are initialized without a Frame), so a Document can keep a ResourceFetcher
+// are initialized without a LocalFrame), so a Document can keep a ResourceFetcher
// alive past detach if scripts still reference the Document.
-class ResourceFetcher : public RefCounted<ResourceFetcher>, public ResourceLoaderHost {
- WTF_MAKE_NONCOPYABLE(ResourceFetcher); WTF_MAKE_FAST_ALLOCATED;
+class ResourceFetcher FINAL : public RefCountedWillBeGarbageCollectedFinalized<ResourceFetcher>, public ResourceLoaderHost {
+ WTF_MAKE_NONCOPYABLE(ResourceFetcher); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(ResourceFetcher);
friend class ImageLoader;
friend class ResourceCacheValidationSuppressor;
public:
- static PassRefPtr<ResourceFetcher> create(DocumentLoader* documentLoader) { return adoptRef(new ResourceFetcher(documentLoader)); }
+ static PassRefPtrWillBeRawPtr<ResourceFetcher> create(DocumentLoader* documentLoader) { return adoptRefWillBeNoop(new ResourceFetcher(documentLoader)); }
virtual ~ResourceFetcher();
+ virtual void trace(Visitor*);
+#if !ENABLE(OILPAN)
using RefCounted<ResourceFetcher>::ref;
using RefCounted<ResourceFetcher>::deref;
+#endif
ResourcePtr<Resource> fetchSynchronously(FetchRequest&);
ResourcePtr<ImageResource> fetchImage(FetchRequest&);
@@ -92,17 +91,17 @@ public:
ResourcePtr<ScriptResource> fetchScript(FetchRequest&);
ResourcePtr<FontResource> fetchFont(FetchRequest&);
ResourcePtr<RawResource> fetchRawResource(FetchRequest&);
- ResourcePtr<RawResource> fetchMainResource(FetchRequest&);
+ ResourcePtr<RawResource> fetchMainResource(FetchRequest&, const SubstituteData&);
ResourcePtr<DocumentResource> fetchSVGDocument(FetchRequest&);
ResourcePtr<XSLStyleSheetResource> fetchXSLStyleSheet(FetchRequest&);
ResourcePtr<Resource> fetchLinkResource(Resource::Type, FetchRequest&);
- ResourcePtr<ShaderResource> fetchShader(FetchRequest&);
ResourcePtr<RawResource> fetchImport(FetchRequest&);
+ ResourcePtr<RawResource> fetchMedia(FetchRequest&);
+ ResourcePtr<RawResource> fetchTextTrack(FetchRequest&);
// Logs an access denied message to the console for the specified URL.
void printAccessDeniedMessage(const KURL&) const;
- Resource* cachedResource(const String& url) const;
Resource* cachedResource(const KURL&) const;
typedef HashMap<String, ResourcePtr<Resource> > DocumentResourceMap;
@@ -115,10 +114,10 @@ public:
bool shouldDeferImageLoad(const KURL&) const;
- Frame* frame() const; // Can be null
+ LocalFrame* frame() const; // Can be null
FetchContext& context() const;
Document* document() const { return m_document; } // Can be null
- void setDocument(Document* document) { m_document = document; }
+ void setDocument(RawPtr<Document> document) { m_document = document; }
DocumentLoader* documentLoader() const { return m_documentLoader; }
void clearDocumentLoader() { m_documentLoader = 0; }
@@ -129,11 +128,8 @@ public:
bool isPreloaded(const String& urlString) const;
void clearPreloads();
- void clearPendingPreloads();
void preload(Resource::Type, FetchRequest&, const String& charset);
- void checkForPendingPreloads();
void printPreloadStats();
- bool canAccess(Resource*, CORSEnabled, FetchRequest::OriginRestriction = FetchRequest::UseDefaultOriginRestrictionForType);
void setDefersLoading(bool);
void stopFetching();
@@ -144,45 +140,55 @@ public:
virtual void decrementRequestCount(const Resource*) OVERRIDE;
virtual void didLoadResource(Resource*) OVERRIDE;
virtual void redirectReceived(Resource*, const ResourceResponse&) OVERRIDE;
- virtual void didFinishLoading(const Resource*, double finishTime, const ResourceLoaderOptions&) OVERRIDE;
- virtual void didChangeLoadingPriority(const Resource*, ResourceLoadPriority) OVERRIDE;
- virtual void didFailLoading(const Resource*, const ResourceError&, const ResourceLoaderOptions&) OVERRIDE;
- virtual void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const ResourceLoaderOptions&) OVERRIDE;
- virtual void didReceiveResponse(const Resource*, const ResourceResponse&, const ResourceLoaderOptions&) OVERRIDE;
- virtual void didReceiveData(const Resource*, const char* data, int dataLength, int encodedDataLength, const ResourceLoaderOptions&) OVERRIDE;
- virtual void didDownloadData(const Resource*, int dataLength, int encodedDataLength, const ResourceLoaderOptions&) OVERRIDE;
+ virtual void didFinishLoading(const Resource*, double finishTime, int64_t encodedDataLength) OVERRIDE;
+ virtual void didChangeLoadingPriority(const Resource*, ResourceLoadPriority, int intraPriorityValue) OVERRIDE;
+ virtual void didFailLoading(const Resource*, const ResourceError&) OVERRIDE;
+ virtual void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&) OVERRIDE;
+ virtual void didReceiveResponse(const Resource*, const ResourceResponse&) OVERRIDE;
+ virtual void didReceiveData(const Resource*, const char* data, int dataLength, int encodedDataLength) OVERRIDE;
+ virtual void didDownloadData(const Resource*, int dataLength, int encodedDataLength) OVERRIDE;
virtual void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*) OVERRIDE;
virtual void didInitializeResourceLoader(ResourceLoader*) OVERRIDE;
virtual void willTerminateResourceLoader(ResourceLoader*) OVERRIDE;
- virtual void willStartLoadingResource(ResourceRequest&) OVERRIDE;
+ virtual void willStartLoadingResource(Resource*, ResourceRequest&) OVERRIDE;
virtual bool defersLoading() const OVERRIDE;
virtual bool isLoadedBy(ResourceLoaderHost*) const OVERRIDE;
- virtual bool shouldRequest(Resource*, const ResourceRequest&, const ResourceLoaderOptions&) OVERRIDE;
+ virtual bool canAccessRedirect(Resource*, ResourceRequest&, const ResourceResponse&, ResourceLoaderOptions&) OVERRIDE;
+ virtual bool canAccessResource(Resource*, SecurityOrigin*, const KURL&) const OVERRIDE;
+
+#if !ENABLE(OILPAN)
virtual void refResourceLoaderHost() OVERRIDE;
virtual void derefResourceLoaderHost() OVERRIDE;
+#endif
+ enum ResourceLoadStartType {
+ ResourceLoadingFromNetwork,
+ ResourceLoadingFromCache
+ };
+ void requestLoadStarted(Resource*, const FetchRequest&, ResourceLoadStartType);
static const ResourceLoaderOptions& defaultResourceOptions();
private:
explicit ResourceFetcher(DocumentLoader*);
- bool shouldLoadNewResource() const;
+ bool shouldLoadNewResource(Resource::Type) const;
ResourcePtr<Resource> requestResource(Resource::Type, FetchRequest&);
- ResourcePtr<Resource> revalidateResource(const FetchRequest&, Resource*);
- ResourcePtr<Resource> loadResource(Resource::Type, FetchRequest&, const String& charset);
+ ResourcePtr<Resource> createResourceForRevalidation(const FetchRequest&, Resource*);
+ ResourcePtr<Resource> createResourceForLoading(Resource::Type, FetchRequest&, const String& charset);
void preCacheDataURIImage(const FetchRequest&);
- void storeResourceTimingInitiatorInformation(const ResourcePtr<Resource>&, const FetchRequest&);
+ void preCacheSubstituteDataForMainResource(const FetchRequest&, const SubstituteData&);
+ void storeResourceTimingInitiatorInformation(Resource*);
void requestPreload(Resource::Type, FetchRequest&, const String& charset);
enum RevalidationPolicy { Use, Revalidate, Reload, Load };
- RevalidationPolicy determineRevalidationPolicy(Resource::Type, ResourceRequest&, bool forPreload, Resource* existingResource, FetchRequest::DeferOption) const;
+ RevalidationPolicy determineRevalidationPolicy(Resource::Type, ResourceRequest&, bool forPreload, Resource* existingResource, FetchRequest::DeferOption, const ResourceLoaderOptions&) const;
void determineTargetType(ResourceRequest&, Resource::Type);
ResourceRequestCachePolicy resourceRequestCachePolicy(const ResourceRequest&, Resource::Type);
void addAdditionalRequestHeaders(ResourceRequest&, Resource::Type);
- bool canRequest(Resource::Type, const KURL&, const ResourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction);
+ bool canRequest(Resource::Type, const KURL&, const ResourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction) const;
bool checkInsecureContent(Resource::Type, const KURL&, MixedContentBlockingTreatment) const;
static bool resourceNeedsLoad(Resource*, const FetchRequest&, RevalidationPolicy);
@@ -190,28 +196,24 @@ private:
void notifyLoadedFromMemoryCache(Resource*);
void garbageCollectDocumentResourcesTimerFired(Timer<ResourceFetcher>*);
+ void scheduleDocumentResourcesGC();
void resourceTimingReportTimerFired(Timer<ResourceFetcher>*);
- void performPostLoadActions();
-
bool clientDefersImage(const KURL&) const;
void reloadImagesIfNotDeferred();
HashSet<String> m_validatedURLs;
mutable DocumentResourceMap m_documentResources;
- Document* m_document;
+ // FIXME: Oilpan: Ideally this should just be a traced Member but that will
+ // currently leak because RenderStyle and its data are not on the heap.
+ // See crbug.com/383860 for details.
+ RawPtrWillBeWeakMember<Document> m_document;
DocumentLoader* m_documentLoader;
int m_requestCount;
OwnPtr<ListHashSet<Resource*> > m_preloads;
- struct PendingPreload {
- Resource::Type m_type;
- FetchRequest m_request;
- String m_charset;
- };
- Deque<PendingPreload> m_pendingPreloads;
Timer<ResourceFetcher> m_garbageCollectDocumentResourcesTimer;
Timer<ResourceFetcher> m_resourceTimingReportTimer;
@@ -224,6 +226,21 @@ private:
OwnPtr<ResourceLoaderSet> m_loaders;
OwnPtr<ResourceLoaderSet> m_multipartLoaders;
+ // Used in hit rate histograms.
+ class DeadResourceStatsRecorder {
+ public:
+ DeadResourceStatsRecorder();
+ ~DeadResourceStatsRecorder();
+
+ void update(RevalidationPolicy);
+
+ private:
+ int m_useCount;
+ int m_revalidateCount;
+ int m_loadCount;
+ };
+ DeadResourceStatsRecorder m_deadStatsRecorder;
+
// 29 bits left
bool m_autoLoadImages : 1;
bool m_imagesEnabled : 1;
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp b/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
index adc8b4bb803..8f83bea17d9 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
@@ -48,14 +48,14 @@ TEST(ResourceFetcherTest, StartLoadAfterFrameDetach)
{
KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.jpg");
- // Create a ResourceFetcher that has a real DocumentLoader and Document, but is not attached to a Frame.
- // Technically, we're concerned about what happens after a Frame is detached (rather than before
+ // Create a ResourceFetcher that has a real DocumentLoader and Document, but is not attached to a LocalFrame.
+ // Technically, we're concerned about what happens after a LocalFrame is detached (rather than before
// any attach occurs), but ResourceFetcher can't tell the difference.
- RefPtr<DocumentLoader> documentLoader = DocumentLoader::create(ResourceRequest(testURL), SubstituteData());
- RefPtr<HTMLDocument> document = HTMLDocument::create();
- RefPtr<ResourceFetcher> fetcher(documentLoader->fetcher());
+ RefPtr<DocumentLoader> documentLoader = DocumentLoader::create(0, ResourceRequest(testURL), SubstituteData());
+ RefPtrWillBeRawPtr<HTMLDocument> document = HTMLDocument::create();
+ RefPtrWillBeRawPtr<ResourceFetcher> fetcher(documentLoader->fetcher());
fetcher->setDocument(document.get());
- EXPECT_EQ(fetcher->frame(), static_cast<Frame*>(0));
+ EXPECT_EQ(fetcher->frame(), static_cast<LocalFrame*>(0));
// Try to request a url. The request should fail, no resource should be returned,
// and no resource should be present in the cache.
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.cpp b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.cpp
index 29882526a7c..7e99a0bc721 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.cpp
@@ -30,12 +30,23 @@
#include "config.h"
#include "core/fetch/ResourceLoadPriorityOptimizer.h"
+#include "core/rendering/RenderObject.h"
+#include "platform/TraceEvent.h"
+
+#include "wtf/Vector.h"
namespace WebCore {
-ResourceLoadPriorityOptimizer::ResourceAndVisibility::ResourceAndVisibility(ImageResource* image, VisibilityStatus v)
+ResourceLoadPriorityOptimizer* ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()
+{
+ DEFINE_STATIC_LOCAL(ResourceLoadPriorityOptimizer, s_renderLoadOptimizer, ());
+ return &s_renderLoadOptimizer;
+}
+
+ResourceLoadPriorityOptimizer::ResourceAndVisibility::ResourceAndVisibility(ImageResource* image, VisibilityStatus visibilityStatus, uint32_t screenArea)
: imageResource(image)
- , status(v)
+ , status(visibilityStatus)
+ , screenArea(screenArea)
{
}
@@ -49,6 +60,37 @@ ResourceLoadPriorityOptimizer::ResourceLoadPriorityOptimizer()
ResourceLoadPriorityOptimizer::~ResourceLoadPriorityOptimizer()
{
+}
+
+void ResourceLoadPriorityOptimizer::addRenderObject(RenderObject* renderer)
+{
+ m_objects.add(renderer);
+ renderer->setHasPendingResourceUpdate(true);
+}
+
+void ResourceLoadPriorityOptimizer::removeRenderObject(RenderObject* renderer)
+{
+ if (!renderer->hasPendingResourceUpdate())
+ return;
+ m_objects.remove(renderer);
+ renderer->setHasPendingResourceUpdate(false);
+}
+
+void ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities()
+{
+ TRACE_EVENT0("webkit", "ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities");
+
+ m_imageResources.clear();
+
+ Vector<RenderObject*> objectsToRemove;
+ for (RenderObjectSet::iterator it = m_objects.begin(); it != m_objects.end(); ++it) {
+ RenderObject* obj = *it;
+ if (!obj->updateImageLoadingPriorities()) {
+ objectsToRemove.append(obj);
+ }
+ }
+ m_objects.removeAll(objectsToRemove);
+
updateImageResourcesWithLoadPriority();
}
@@ -59,21 +101,27 @@ void ResourceLoadPriorityOptimizer::updateImageResourcesWithLoadPriority()
ResourceLoadPriorityLow : ResourceLoadPriorityVeryLow;
if (priority != it->value->imageResource->resourceRequest().priority()) {
- it->value->imageResource->resourceRequest().setPriority(priority);
- it->value->imageResource->didChangePriority(priority);
+ it->value->imageResource->resourceRequest().setPriority(priority, it->value->screenArea);
+ it->value->imageResource->didChangePriority(priority, it->value->screenArea);
}
}
m_imageResources.clear();
}
-void ResourceLoadPriorityOptimizer::notifyImageResourceVisibility(ImageResource* img, VisibilityStatus status)
+void ResourceLoadPriorityOptimizer::notifyImageResourceVisibility(ImageResource* img, VisibilityStatus status, const LayoutRect& screenRect)
{
if (!img || img->isLoaded())
return;
- ImageResourceMap::AddResult result = m_imageResources.add(img->identifier(), adoptPtr(new ResourceAndVisibility(img, status)));
- if (!result.isNewEntry && status == Visible)
- result.iterator->value->status = status;
+ int screenArea = 0;
+ if (!screenRect.isEmpty() && status == Visible)
+ screenArea += static_cast<uint32_t>(screenRect.width() * screenRect.height());
+
+ ImageResourceMap::AddResult result = m_imageResources.add(img->identifier(), adoptPtr(new ResourceAndVisibility(img, status, screenArea)));
+ if (!result.isNewEntry && status == Visible) {
+ result.storedValue->value->status = status;
+ result.storedValue->value->screenArea = status;
+ }
}
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.h b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.h
index cb58320a410..3dd05c3e6b4 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoadPriorityOptimizer.h
@@ -36,6 +36,7 @@
#include "platform/geometry/LayoutRect.h"
#include "wtf/HashMap.h"
+#include "wtf/HashSet.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
@@ -46,22 +47,32 @@ public:
NotVisible,
Visible,
};
+ void notifyImageResourceVisibility(ImageResource*, VisibilityStatus, const LayoutRect&);
+ void updateAllImageResourcePriorities();
+ void addRenderObject(RenderObject*);
+ void removeRenderObject(RenderObject*);
+
+ static ResourceLoadPriorityOptimizer* resourceLoadPriorityOptimizer();
+
+private:
ResourceLoadPriorityOptimizer();
~ResourceLoadPriorityOptimizer();
- void notifyImageResourceVisibility(ImageResource*, VisibilityStatus);
-private:
void updateImageResourcesWithLoadPriority();
struct ResourceAndVisibility {
- ResourceAndVisibility(ImageResource*, VisibilityStatus);
+ ResourceAndVisibility(ImageResource*, VisibilityStatus, uint32_t);
~ResourceAndVisibility();
ResourcePtr<ImageResource> imageResource;
VisibilityStatus status;
+ int screenArea;
};
- typedef HashMap<unsigned long, OwnPtr<ResourceAndVisibility> > ImageResourceMap;
+ typedef HashMap<unsigned long, OwnPtr<ResourceAndVisibility>, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > ImageResourceMap;
ImageResourceMap m_imageResources;
+
+ typedef HashSet<RenderObject*> RenderObjectSet;
+ RenderObjectSet m_objects;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
index f1356b75b53..f8de6d8a640 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
@@ -40,6 +40,7 @@
#include "platform/network/ResourceError.h"
#include "public/platform/Platform.h"
#include "public/platform/WebData.h"
+#include "public/platform/WebThreadedDataReceiver.h"
#include "public/platform/WebURLError.h"
#include "public/platform/WebURLRequest.h"
#include "public/platform/WebURLResponse.h"
@@ -60,6 +61,13 @@ ResourceLoader::RequestCountTracker::~RequestCountTracker()
m_host->decrementRequestCount(m_resource);
}
+ResourceLoader::RequestCountTracker::RequestCountTracker(const RequestCountTracker& other)
+{
+ m_host = other.m_host;
+ m_resource = other.m_resource;
+ m_host->incrementRequestCount(m_resource);
+}
+
PassRefPtr<ResourceLoader> ResourceLoader::create(ResourceLoaderHost* host, Resource* resource, const ResourceRequest& request, const ResourceLoaderOptions& options)
{
RefPtr<ResourceLoader> loader(adoptRef(new ResourceLoader(host, resource, options)));
@@ -87,6 +95,7 @@ ResourceLoader::~ResourceLoader()
void ResourceLoader::releaseResources()
{
ASSERT(m_state != Terminated);
+ ASSERT(m_notifiedLoadComplete);
m_requestCountTracker.clear();
m_host->didLoadResource(m_resource);
if (m_state == Terminated)
@@ -116,11 +125,11 @@ void ResourceLoader::releaseResources()
void ResourceLoader::init(const ResourceRequest& passedRequest)
{
ResourceRequest request(passedRequest);
- m_host->willSendRequest(m_resource->identifier(), request, ResourceResponse(), m_options);
- request.setReportLoadTiming(true);
+ m_host->willSendRequest(m_resource->identifier(), request, ResourceResponse(), m_options.initiatorInfo);
ASSERT(m_state != Terminated);
ASSERT(!request.isNull());
- m_originalRequest = m_request = request;
+ m_originalRequest = m_request = applyOptions(request);
+ m_resource->updateRequest(request);
m_host->didInitializeResourceLoader(this);
}
@@ -130,7 +139,7 @@ void ResourceLoader::start()
ASSERT(!m_request.isNull());
ASSERT(m_deferredRequest.isNull());
- m_host->willStartLoadingResource(m_request);
+ m_host->willStartLoadingResource(m_resource, m_request);
if (m_options.synchronousPolicy == RequestSynchronously) {
requestSynchronously();
@@ -151,7 +160,6 @@ void ResourceLoader::start()
m_loader = adoptPtr(blink::Platform::current()->createURLLoader());
ASSERT(m_loader);
blink::WrappedResourceRequest wrappedRequest(m_request);
- wrappedRequest.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials);
m_loader->loadAsynchronously(wrappedRequest, this);
}
@@ -172,21 +180,33 @@ void ResourceLoader::setDefersLoading(bool defers)
if (m_loader)
m_loader->setDefersLoading(defers);
if (!defers && !m_deferredRequest.isNull()) {
- m_request = m_deferredRequest;
+ m_request = applyOptions(m_deferredRequest);
m_deferredRequest = ResourceRequest();
start();
}
}
+void ResourceLoader::attachThreadedDataReceiver(PassOwnPtr<blink::WebThreadedDataReceiver> threadedDataReceiver)
+{
+ if (m_loader) {
+ // The implementor of the WebURLLoader assumes ownership of the
+ // threaded data receiver if it signals that it got successfully
+ // attached.
+ blink::WebThreadedDataReceiver* rawThreadedDataReceiver = threadedDataReceiver.leakPtr();
+ if (!m_loader->attachThreadedDataReceiver(rawThreadedDataReceiver))
+ delete rawThreadedDataReceiver;
+ }
+}
+
void ResourceLoader::didDownloadData(blink::WebURLLoader*, int length, int encodedDataLength)
{
RefPtr<ResourceLoader> protect(this);
RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse);
- m_host->didDownloadData(m_resource, length, encodedDataLength, m_options);
+ m_host->didDownloadData(m_resource, length, encodedDataLength);
m_resource->didDownloadData(length);
}
-void ResourceLoader::didFinishLoadingOnePart(double finishTime)
+void ResourceLoader::didFinishLoadingOnePart(double finishTime, int64 encodedDataLength)
{
// If load has been cancelled after finishing (which could happen with a
// JavaScript that changes the window location), do nothing.
@@ -196,14 +216,14 @@ void ResourceLoader::didFinishLoadingOnePart(double finishTime)
if (m_notifiedLoadComplete)
return;
m_notifiedLoadComplete = true;
- m_host->didFinishLoading(m_resource, finishTime, m_options);
+ m_host->didFinishLoading(m_resource, finishTime, encodedDataLength);
}
-void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority)
+void ResourceLoader::didChangePriority(ResourceLoadPriority loadPriority, int intraPriorityValue)
{
if (m_loader) {
- m_host->didChangeLoadingPriority(m_resource, loadPriority);
- m_loader->didChangePriority(static_cast<blink::WebURLRequest::Priority>(loadPriority));
+ m_host->didChangeLoadingPriority(m_resource, loadPriority, intraPriorityValue);
+ m_loader->didChangePriority(static_cast<blink::WebURLRequest::Priority>(loadPriority), intraPriorityValue);
}
}
@@ -246,7 +266,10 @@ void ResourceLoader::cancel(const ResourceError& error)
m_loader.clear();
}
- m_host->didFailLoading(m_resource, nonNullError, m_options);
+ if (!m_notifiedLoadComplete) {
+ m_notifiedLoadComplete = true;
+ m_host->didFailLoading(m_resource, nonNullError);
+ }
if (m_state == Finishing)
m_resource->error(Resource::LoadError);
@@ -258,22 +281,24 @@ void ResourceLoader::willSendRequest(blink::WebURLLoader*, blink::WebURLRequest&
{
RefPtr<ResourceLoader> protect(this);
- ResourceRequest& request(passedRequest.toMutableResourceRequest());
+ ResourceRequest& request(applyOptions(passedRequest.toMutableResourceRequest()));
ASSERT(!request.isNull());
const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceResponse());
ASSERT(!redirectResponse.isNull());
- if (!m_host->shouldRequest(m_resource, request, m_options)) {
+ if (!m_host->canAccessRedirect(m_resource, request, redirectResponse, m_options)) {
cancel();
return;
}
+
+ applyOptions(request); // canAccessRedirect() can modify m_options so we should re-apply it.
m_host->redirectReceived(m_resource, redirectResponse);
m_resource->willSendRequest(request, redirectResponse);
if (request.isNull() || m_state == Terminated)
return;
- m_host->willSendRequest(m_resource->identifier(), request, redirectResponse, m_options);
- request.setReportLoadTiming(true);
+ m_host->willSendRequest(m_resource->identifier(), request, redirectResponse, m_options.initiatorInfo);
ASSERT(!request.isNull());
+ m_resource->updateRequest(request);
m_request = request;
}
@@ -291,6 +316,12 @@ void ResourceLoader::didSendData(blink::WebURLLoader*, unsigned long long bytesS
m_resource->didSendData(bytesSent, totalBytesToBeSent);
}
+bool ResourceLoader::responseNeedsAccessControlCheck() const
+{
+ // If the fetch was (potentially) CORS enabled, an access control check of the response is required.
+ return m_options.corsEnabled == IsCORSEnabled;
+}
+
void ResourceLoader::didReceiveResponse(blink::WebURLLoader*, const blink::WebURLResponse& response)
{
ASSERT(!response.isNull());
@@ -302,14 +333,32 @@ void ResourceLoader::didReceiveResponse(blink::WebURLLoader*, const blink::WebUR
RELEASE_ASSERT(isMultipartPayload || isValidStateTransition);
m_connectionState = ConnectionStateReceivedResponse;
+ const ResourceResponse& resourceResponse = response.toResourceResponse();
+
+ if (responseNeedsAccessControlCheck()) {
+ // If the response successfully validated a cached resource, perform
+ // the access control with respect to it. Need to do this right here
+ // before the resource switches clients over to that validated resource.
+ Resource* resource = m_resource;
+ if (resource->isCacheValidator() && resourceResponse.httpStatusCode() == 304)
+ resource = m_resource->resourceToRevalidate();
+ else
+ m_resource->setResponse(resourceResponse);
+ if (!m_host->canAccessResource(resource, m_options.securityOrigin.get(), response.url())) {
+ m_host->didReceiveResponse(m_resource, resourceResponse);
+ cancel();
+ return;
+ }
+ }
+
// Reference the object in this method since the additional processing can do
// anything including removing the last reference to this object.
RefPtr<ResourceLoader> protect(this);
- m_resource->responseReceived(response.toResourceResponse());
+ m_resource->responseReceived(resourceResponse);
if (m_state == Terminated)
return;
- m_host->didReceiveResponse(m_resource, response.toResourceResponse(), m_options);
+ m_host->didReceiveResponse(m_resource, resourceResponse);
if (response.toResourceResponse().isMultipart()) {
// We don't count multiParts in a ResourceFetcher's request count
@@ -322,12 +371,18 @@ void ResourceLoader::didReceiveResponse(blink::WebURLLoader*, const blink::WebUR
// Since a subresource loader does not load multipart sections progressively, data was delivered to the loader all at once.
// After the first multipart section is complete, signal to delegates that this load is "finished"
m_host->subresourceLoaderFinishedLoadingOnePart(this);
- didFinishLoadingOnePart(0);
+ didFinishLoadingOnePart(0, blink::WebURLLoaderClient::kUnknownEncodedDataLength);
}
if (m_resource->response().httpStatusCode() < 400 || m_resource->shouldIgnoreHTTPStatusCodeErrors())
return;
m_state = Finishing;
+
+ if (!m_notifiedLoadComplete) {
+ m_notifiedLoadComplete = true;
+ m_host->didFailLoading(m_resource, ResourceError::cancelledError(m_request.url()));
+ }
+
m_resource->error(Resource::LoadError);
cancel();
}
@@ -350,11 +405,11 @@ void ResourceLoader::didReceiveData(blink::WebURLLoader*, const char* data, int
// FIXME: If we get a resource with more than 2B bytes, this code won't do the right thing.
// However, with today's computers and networking speeds, this won't happen in practice.
// Could be an issue with a giant local file.
- m_host->didReceiveData(m_resource, data, length, encodedDataLength, m_options);
+ m_host->didReceiveData(m_resource, data, length, encodedDataLength);
m_resource->appendData(data, length);
}
-void ResourceLoader::didFinishLoading(blink::WebURLLoader*, double finishTime)
+void ResourceLoader::didFinishLoading(blink::WebURLLoader*, double finishTime, int64 encodedDataLength)
{
RELEASE_ASSERT(m_connectionState == ConnectionStateReceivedResponse || m_connectionState == ConnectionStateReceivingData);
m_connectionState = ConnectionStateFinishedLoading;
@@ -366,8 +421,8 @@ void ResourceLoader::didFinishLoading(blink::WebURLLoader*, double finishTime)
RefPtr<ResourceLoader> protect(this);
ResourcePtr<Resource> protectResource(m_resource);
m_state = Finishing;
+ didFinishLoadingOnePart(finishTime, encodedDataLength);
m_resource->finish(finishTime);
- didFinishLoadingOnePart(finishTime);
// If the load has been cancelled by a delegate in response to didFinishLoad(), do not release
// the resources a second time, they have been released by cancel.
@@ -383,20 +438,21 @@ void ResourceLoader::didFail(blink::WebURLLoader*, const blink::WebURLError& err
WTF_LOG(ResourceLoading, "Failed to load '%s'.\n", m_resource->url().string().latin1().data());
RefPtr<ResourceLoader> protect(this);
- RefPtr<ResourceLoaderHost> protectHost(m_host);
+ RefPtrWillBeRawPtr<ResourceLoaderHost> protectHost(m_host.get());
ResourcePtr<Resource> protectResource(m_resource);
m_state = Finishing;
m_resource->setResourceError(error);
- m_resource->error(Resource::LoadError);
-
- if (m_state == Terminated)
- return;
if (!m_notifiedLoadComplete) {
m_notifiedLoadComplete = true;
- m_host->didFailLoading(m_resource, error, m_options);
+ m_host->didFailLoading(m_resource, error);
}
+ m_resource->error(Resource::LoadError);
+
+ if (m_state == Terminated)
+ return;
+
releaseResources();
}
@@ -410,15 +466,17 @@ void ResourceLoader::requestSynchronously()
OwnPtr<blink::WebURLLoader> loader = adoptPtr(blink::Platform::current()->createURLLoader());
ASSERT(loader);
+ // downloadToFile is not supported for synchronous requests.
+ ASSERT(!m_request.downloadToFile());
+
RefPtr<ResourceLoader> protect(this);
- RefPtr<ResourceLoaderHost> protectHost(m_host);
+ RefPtrWillBeRawPtr<ResourceLoaderHost> protectHost(m_host.get());
ResourcePtr<Resource> protectResource(m_resource);
RELEASE_ASSERT(m_connectionState == ConnectionStateNew);
m_connectionState = ConnectionStateStarted;
blink::WrappedResourceRequest requestIn(m_request);
- requestIn.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials);
blink::WebURLResponse responseOut;
responseOut.initialize();
blink::WebURLError errorOut;
@@ -432,9 +490,16 @@ void ResourceLoader::requestSynchronously()
if (m_state == Terminated)
return;
RefPtr<ResourceLoadInfo> resourceLoadInfo = responseOut.toResourceResponse().resourceLoadInfo();
- m_host->didReceiveData(m_resource, dataOut.data(), dataOut.size(), resourceLoadInfo ? resourceLoadInfo->encodedDataLength : -1, m_options);
+ int64 encodedDataLength = resourceLoadInfo ? resourceLoadInfo->encodedDataLength : blink::WebURLLoaderClient::kUnknownEncodedDataLength;
+ m_host->didReceiveData(m_resource, dataOut.data(), dataOut.size(), encodedDataLength);
m_resource->setResourceBuffer(dataOut);
- didFinishLoading(0, monotonicallyIncreasingTime());
+ didFinishLoading(0, monotonicallyIncreasingTime(), encodedDataLength);
+}
+
+ResourceRequest& ResourceLoader::applyOptions(ResourceRequest& request) const
+{
+ request.setAllowStoredCredentials(m_options.allowCredentials == AllowStoredCredentials);
+ return request;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.h b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.h
index 814cecf6850..e54611ec74f 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoader.h
@@ -36,6 +36,10 @@
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
+namespace blink {
+class WebThreadedDataReceiver;
+}
+
namespace WebCore {
class Resource;
@@ -44,7 +48,7 @@ class ResourceError;
class ResourceResponse;
class ResourceLoaderHost;
-class ResourceLoader : public RefCounted<ResourceLoader>, protected blink::WebURLLoaderClient {
+class ResourceLoader FINAL : public RefCounted<ResourceLoader>, protected blink::WebURLLoaderClient {
public:
static PassRefPtr<ResourceLoader> create(ResourceLoaderHost*, Resource*, const ResourceRequest&, const ResourceLoaderOptions&);
virtual ~ResourceLoader();
@@ -62,9 +66,11 @@ public:
void setDefersLoading(bool);
bool defersLoading() const { return m_defersLoading; }
+ void attachThreadedDataReceiver(PassOwnPtr<blink::WebThreadedDataReceiver>);
+
void releaseResources();
- void didChangePriority(ResourceLoadPriority);
+ void didChangePriority(ResourceLoadPriority, int intraPriorityValue);
// WebURLLoaderClient
virtual void willSendRequest(blink::WebURLLoader*, blink::WebURLRequest&, const blink::WebURLResponse& redirectResponse) OVERRIDE;
@@ -72,28 +78,41 @@ public:
virtual void didReceiveResponse(blink::WebURLLoader*, const blink::WebURLResponse&) OVERRIDE;
virtual void didReceiveData(blink::WebURLLoader*, const char*, int, int encodedDataLength) OVERRIDE;
virtual void didReceiveCachedMetadata(blink::WebURLLoader*, const char* data, int length) OVERRIDE;
- virtual void didFinishLoading(blink::WebURLLoader*, double finishTime) OVERRIDE;
+ virtual void didFinishLoading(blink::WebURLLoader*, double finishTime, int64 encodedDataLength) OVERRIDE;
virtual void didFail(blink::WebURLLoader*, const blink::WebURLError&) OVERRIDE;
virtual void didDownloadData(blink::WebURLLoader*, int, int) OVERRIDE;
const KURL& url() const { return m_request.url(); }
- bool shouldSendResourceLoadCallbacks() const { return m_options.sendLoadCallbacks == SendCallbacks; }
bool shouldSniffContent() const { return m_options.sniffContent == SniffContent; }
bool isLoadedBy(ResourceLoaderHost*) const;
bool reachedTerminalState() const { return m_state == Terminated; }
const ResourceRequest& request() const { return m_request; }
+ class RequestCountTracker {
+ public:
+ RequestCountTracker(ResourceLoaderHost*, Resource*);
+ RequestCountTracker(const RequestCountTracker&);
+ ~RequestCountTracker();
+ private:
+ ResourceLoaderHost* m_host;
+ Resource* m_resource;
+ };
+
private:
ResourceLoader(ResourceLoaderHost*, Resource*, const ResourceLoaderOptions&);
void init(const ResourceRequest&);
void requestSynchronously();
- void didFinishLoadingOnePart(double finishTime);
+ void didFinishLoadingOnePart(double finishTime, int64_t encodedDataLength);
+
+ bool responseNeedsAccessControlCheck() const;
+
+ ResourceRequest& applyOptions(ResourceRequest&) const;
OwnPtr<blink::WebURLLoader> m_loader;
- RefPtr<ResourceLoaderHost> m_host;
+ RefPtrWillBePersistent<ResourceLoaderHost> m_host;
ResourceRequest m_request;
ResourceRequest m_originalRequest; // Before redirects.
@@ -120,15 +139,6 @@ private:
ConnectionStateFailed,
};
- class RequestCountTracker {
- public:
- RequestCountTracker(ResourceLoaderHost*, Resource*);
- ~RequestCountTracker();
- private:
- ResourceLoaderHost* m_host;
- Resource* m_resource;
- };
-
Resource* m_resource;
ResourceLoaderState m_state;
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderHost.h b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderHost.h
index 6748276d57b..cbf79d31f4b 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderHost.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderHost.h
@@ -38,44 +38,48 @@ namespace WebCore {
class Resource;
class ResourceFetcher;
-class Frame;
+class LocalFrame;
class ResourceLoader;
class ResourceRequest;
class ResourceResponse;
struct FetchInitiatorInfo;
-struct ResourceLoaderOptions;
-class ResourceLoaderHost {
+class ResourceLoaderHost : public WillBeGarbageCollectedMixin {
public:
- void ref() { refResourceLoaderHost(); }
- void deref() { derefResourceLoaderHost(); }
-
virtual void incrementRequestCount(const Resource*) = 0;
virtual void decrementRequestCount(const Resource*) = 0;
virtual void didLoadResource(Resource*) = 0;
virtual void redirectReceived(Resource*, const ResourceResponse&) = 0;
- virtual void didFinishLoading(const Resource*, double finishTime, const ResourceLoaderOptions&) = 0;
- virtual void didChangeLoadingPriority(const Resource*, ResourceLoadPriority) = 0;
- virtual void didFailLoading(const Resource*, const ResourceError&, const ResourceLoaderOptions&) = 0;
+ virtual void didFinishLoading(const Resource*, double finishTime, int64_t encodedDataLength) = 0;
+ virtual void didChangeLoadingPriority(const Resource*, ResourceLoadPriority, int intraPriorityValue) = 0;
+ virtual void didFailLoading(const Resource*, const ResourceError&) = 0;
- virtual void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const ResourceLoaderOptions&) = 0;
- virtual void didReceiveResponse(const Resource*, const ResourceResponse&, const ResourceLoaderOptions&) = 0;
- virtual void didReceiveData(const Resource*, const char* data, int dataLength, int encodedDataLength, const ResourceLoaderOptions&) = 0;
- virtual void didDownloadData(const Resource*, int dataLength, int encodedDataLength, const ResourceLoaderOptions&) = 0;
+ virtual void willSendRequest(unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&) = 0;
+ virtual void didReceiveResponse(const Resource*, const ResourceResponse&) = 0;
+ virtual void didReceiveData(const Resource*, const char* data, int dataLength, int encodedDataLength) = 0;
+ virtual void didDownloadData(const Resource*, int dataLength, int encodedDataLength) = 0;
virtual void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*) = 0;
virtual void didInitializeResourceLoader(ResourceLoader*) = 0;
virtual void willTerminateResourceLoader(ResourceLoader*) = 0;
- virtual void willStartLoadingResource(ResourceRequest&) = 0;
+ virtual void willStartLoadingResource(Resource*, ResourceRequest&) = 0;
- virtual bool shouldRequest(Resource*, const ResourceRequest&, const ResourceLoaderOptions&) = 0;
+ virtual bool canAccessRedirect(Resource*, ResourceRequest&, const ResourceResponse&, ResourceLoaderOptions&) = 0;
+ virtual bool canAccessResource(Resource*, SecurityOrigin* sourceOrigin, const KURL&) const = 0;
virtual bool defersLoading() const = 0;
virtual bool isLoadedBy(ResourceLoaderHost*) const = 0;
+ virtual void trace(Visitor*) { }
+
+#if !ENABLE(OILPAN)
virtual void refResourceLoaderHost() = 0;
virtual void derefResourceLoaderHost() = 0;
+
+ void ref() { refResourceLoaderHost(); }
+ void deref() { derefResourceLoaderHost(); }
+#endif
};
}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderOptions.h b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderOptions.h
index 59136225c33..b183901ee24 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderOptions.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/ResourceLoaderOptions.h
@@ -36,11 +36,6 @@
namespace WebCore {
-enum SendCallbackPolicy {
- SendCallbacks,
- DoNotSendCallbacks
-};
-
enum ContentSniffingPolicy {
SniffContent,
DoNotSniffContent
@@ -51,16 +46,6 @@ enum DataBufferingPolicy {
DoNotBufferData
};
-enum ClientCrossOriginCredentialPolicy {
- AskClientForCrossOriginCredentials,
- DoNotAskClientForCrossOriginCredentials
-};
-
-enum SecurityCheckPolicy {
- SkipSecurityCheck,
- DoSecurityCheck
-};
-
enum ContentSecurityPolicyCheck {
CheckContentSecurityPolicy,
DoNotCheckContentSecurityPolicy
@@ -97,58 +82,56 @@ enum SynchronousPolicy {
RequestAsynchronously
};
+// A resource fetch can be marked as being CORS enabled. The loader
+// must perform an access check upon seeing the response.
+enum CORSEnabled {
+ NotCORSEnabled,
+ IsCORSEnabled
+};
+
struct ResourceLoaderOptions {
ResourceLoaderOptions()
- : sendLoadCallbacks(DoNotSendCallbacks)
- , sniffContent(DoNotSniffContent)
+ : sniffContent(DoNotSniffContent)
, dataBufferingPolicy(BufferData)
, allowCredentials(DoNotAllowStoredCredentials)
, credentialsRequested(ClientDidNotRequestCredentials)
- , crossOriginCredentialPolicy(DoNotAskClientForCrossOriginCredentials)
- , securityCheck(DoSecurityCheck)
, contentSecurityPolicyOption(CheckContentSecurityPolicy)
, requestInitiatorContext(DocumentContext)
, mixedContentBlockingTreatment(TreatAsDefaultForType)
, synchronousPolicy(RequestAsynchronously)
+ , corsEnabled(NotCORSEnabled)
{
}
ResourceLoaderOptions(
- SendCallbackPolicy sendLoadCallbacks,
ContentSniffingPolicy sniffContent,
DataBufferingPolicy dataBufferingPolicy,
StoredCredentials allowCredentials,
CredentialRequest credentialsRequested,
- ClientCrossOriginCredentialPolicy crossOriginCredentialPolicy,
- SecurityCheckPolicy securityCheck,
ContentSecurityPolicyCheck contentSecurityPolicyOption,
RequestInitiatorContext requestInitiatorContext)
- : sendLoadCallbacks(sendLoadCallbacks)
- , sniffContent(sniffContent)
+ : sniffContent(sniffContent)
, dataBufferingPolicy(dataBufferingPolicy)
, allowCredentials(allowCredentials)
, credentialsRequested(credentialsRequested)
- , crossOriginCredentialPolicy(crossOriginCredentialPolicy)
- , securityCheck(securityCheck)
, contentSecurityPolicyOption(contentSecurityPolicyOption)
, requestInitiatorContext(requestInitiatorContext)
, mixedContentBlockingTreatment(TreatAsDefaultForType)
, synchronousPolicy(RequestAsynchronously)
+ , corsEnabled(NotCORSEnabled)
{
}
- SendCallbackPolicy sendLoadCallbacks;
ContentSniffingPolicy sniffContent;
DataBufferingPolicy dataBufferingPolicy;
StoredCredentials allowCredentials; // Whether HTTP credentials and cookies are sent with the request.
CredentialRequest credentialsRequested; // Whether the client (e.g. XHR) wanted credentials in the first place.
- ClientCrossOriginCredentialPolicy crossOriginCredentialPolicy; // Whether we will ask the client for credentials (if we allow credentials at all).
- SecurityCheckPolicy securityCheck;
ContentSecurityPolicyCheck contentSecurityPolicyOption;
FetchInitiatorInfo initiatorInfo;
RequestInitiatorContext requestInitiatorContext;
MixedContentBlockingTreatment mixedContentBlockingTreatment;
SynchronousPolicy synchronousPolicy;
+ CORSEnabled corsEnabled; // If the resource is loaded out-of-origin, whether or not to use CORS.
RefPtr<SecurityOrigin> securityOrigin;
};
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ScriptResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/ScriptResource.cpp
index 873ef332272..34a29a3f224 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ScriptResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/ScriptResource.cpp
@@ -27,7 +27,6 @@
#include "config.h"
#include "core/fetch/ScriptResource.h"
-#include "core/fetch/TextResourceDecoder.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/SharedBuffer.h"
#include "platform/network/HTTPParsers.h"
@@ -35,8 +34,7 @@
namespace WebCore {
ScriptResource::ScriptResource(const ResourceRequest& resourceRequest, const String& charset)
- : Resource(resourceRequest, Script)
- , m_decoder(TextResourceDecoder::create("application/javascript", charset))
+ : TextResource(resourceRequest, Script, "application/javascript", charset)
{
DEFINE_STATIC_LOCAL(const AtomicString, acceptScript, ("*/*", AtomicString::ConstructFromLiteral));
@@ -50,16 +48,6 @@ ScriptResource::~ScriptResource()
{
}
-void ScriptResource::setEncoding(const String& chs)
-{
- m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
-}
-
-String ScriptResource::encoding() const
-{
- return m_decoder->encoding().name();
-}
-
AtomicString ScriptResource::mimeType() const
{
return extractMIMETypeFromMediaType(m_response.httpHeaderField("Content-Type")).lower();
@@ -71,14 +59,13 @@ const String& ScriptResource::script()
ASSERT(isLoaded());
if (!m_script && m_data) {
- String script = m_decoder->decode(m_data->data(), encodedSize());
- script.append(m_decoder->flush());
+ String script = decodedText();
m_data.clear();
// We lie a it here and claim that script counts as encoded data (even though it's really decoded data).
// That's because the MemoryCache thinks that it can clear out decoded data by calling destroyDecodedData(),
// but we can't destroy script in destroyDecodedData because that's our only copy of the data!
setEncodedSize(script.sizeInBytes());
- m_script = script;
+ m_script = AtomicString(script);
}
return m_script.string();
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ScriptResource.h b/chromium/third_party/WebKit/Source/core/fetch/ScriptResource.h
index 09502e3eddf..53d9b4e6e19 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/ScriptResource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/ScriptResource.h
@@ -26,14 +26,11 @@
#ifndef ScriptResource_h
#define ScriptResource_h
-#include "core/fetch/ResourcePtr.h"
+#include "core/fetch/TextResource.h"
namespace WebCore {
-class ResourceFetcher;
-class TextResourceDecoder;
-
-class ScriptResource : public Resource {
+class ScriptResource FINAL : public TextResource {
public:
typedef ResourceClient ClientType;
@@ -42,15 +39,12 @@ public:
const String& script();
- virtual void setEncoding(const String&);
- virtual String encoding() const;
AtomicString mimeType() const;
bool mimeTypeAllowedByNosniff() const;
private:
AtomicString m_script;
- OwnPtr<TextResourceDecoder> m_decoder;
};
DEFINE_RESOURCE_TYPE_CASTS(Script);
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ShaderResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/ShaderResource.cpp
deleted file mode 100644
index da0fa7ef847..00000000000
--- a/chromium/third_party/WebKit/Source/core/fetch/ShaderResource.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/fetch/ShaderResource.h"
-
-#include "core/fetch/TextResourceDecoder.h"
-#include "platform/SharedBuffer.h"
-#include "wtf/text/StringBuilder.h"
-
-namespace WebCore {
-
-ShaderResource::ShaderResource(const ResourceRequest& resourceRequest)
- : Resource(resourceRequest, Shader)
- , m_decoder(TextResourceDecoder::create("application/shader"))
-{
-}
-
-ShaderResource::~ShaderResource()
-{
-}
-
-const String& ShaderResource::shaderString()
-{
- if (m_shaderString.isNull() && m_data) {
- StringBuilder builder;
- builder.append(m_decoder->decode(m_data->data(), m_data->size()));
- builder.append(m_decoder->flush());
- m_shaderString = builder.toString();
- }
-
- return m_shaderString;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fetch/ShaderResource.h b/chromium/third_party/WebKit/Source/core/fetch/ShaderResource.h
deleted file mode 100644
index fb975b8d9d1..00000000000
--- a/chromium/third_party/WebKit/Source/core/fetch/ShaderResource.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef ShaderResource_h
-#define ShaderResource_h
-
-#include "core/fetch/ResourcePtr.h"
-
-namespace WebCore {
-
-class TextResourceDecoder;
-
-class ShaderResource : public Resource {
-public:
- typedef ResourceClient ClientType;
-
- ShaderResource(const ResourceRequest&);
- virtual ~ShaderResource();
-
- const String& shaderString();
-
-private:
- OwnPtr<TextResourceDecoder> m_decoder;
- String m_shaderString;
-};
-
-DEFINE_RESOURCE_TYPE_CASTS(Shader);
-
-}
-
-
-#endif // ShaderResource_h
diff --git a/chromium/third_party/WebKit/Source/core/fetch/StyleSheetResource.h b/chromium/third_party/WebKit/Source/core/fetch/StyleSheetResource.h
index d714ac5555d..bee7247cbed 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/StyleSheetResource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/StyleSheetResource.h
@@ -31,18 +31,18 @@
#ifndef StyleSheetResource_h
#define StyleSheetResource_h
-#include "core/fetch/Resource.h"
+#include "core/fetch/TextResource.h"
namespace WebCore {
class StyleSheetResourceClient;
-class StyleSheetResource : public Resource {
+class StyleSheetResource : public TextResource {
public:
typedef StyleSheetResourceClient ClientType;
- StyleSheetResource(const ResourceRequest& request, Type type)
- : Resource(request, type)
+ StyleSheetResource(const ResourceRequest& request, Type type, const String& mimeType, const String& charset)
+ : TextResource(request, type, mimeType, charset)
{ }
};
diff --git a/chromium/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h b/chromium/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h
index 8597200568a..05a6a487670 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/StyleSheetResourceClient.h
@@ -37,7 +37,7 @@ class StyleSheetResourceClient : public ResourceClient {
public:
virtual ~StyleSheetResourceClient() { }
static ResourceClientType expectedType() { return StyleSheetType; }
- virtual ResourceClientType resourceClientType() const { return expectedType(); }
+ virtual ResourceClientType resourceClientType() const OVERRIDE FINAL { return expectedType(); }
virtual void setCSSStyleSheet(const String& /* href */, const KURL& /* baseURL */, const String& /* charset */, const CSSStyleSheetResource*) { }
virtual void setXSLStyleSheet(const String& /* href */, const KURL& /* baseURL */, const String& /* sheet */) { }
};
diff --git a/chromium/third_party/WebKit/Source/core/fetch/TextResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/TextResource.cpp
new file mode 100644
index 00000000000..93f8675e163
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/fetch/TextResource.cpp
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/fetch/TextResource.h"
+
+#include "core/html/parser/TextResourceDecoder.h"
+#include "platform/SharedBuffer.h"
+
+namespace WebCore {
+
+TextResource::TextResource(const ResourceRequest& resourceRequest, Resource::Type type, const String& mimeType, const String& charset)
+ : Resource(resourceRequest, type)
+ , m_decoder(TextResourceDecoder::create(mimeType, charset))
+{
+}
+
+TextResource::~TextResource()
+{
+}
+
+void TextResource::setEncoding(const String& chs)
+{
+ m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
+}
+
+String TextResource::encoding() const
+{
+ return m_decoder->encoding().name();
+}
+
+String TextResource::decodedText() const
+{
+ ASSERT(m_data);
+
+ String text = m_decoder->decode(m_data->data(), encodedSize());
+ text = text + m_decoder->flush();
+
+ return text;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fetch/TextResource.h b/chromium/third_party/WebKit/Source/core/fetch/TextResource.h
new file mode 100644
index 00000000000..1e6f3747775
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/fetch/TextResource.h
@@ -0,0 +1,34 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TextResource_h
+#define TextResource_h
+
+#include "core/fetch/ResourcePtr.h"
+
+namespace WebCore {
+
+class ResourceFetcher;
+class TextResourceDecoder;
+
+class TextResource : public Resource {
+public:
+ // Returns the decoded data in text form. The data has to be available at
+ // call time.
+ String decodedText() const;
+
+ virtual void setEncoding(const String&) OVERRIDE;
+ virtual String encoding() const OVERRIDE;
+
+protected:
+ TextResource(const ResourceRequest&, Type, const String& mimeType, const String& charset);
+ virtual ~TextResource();
+
+private:
+ OwnPtr<TextResourceDecoder> m_decoder;
+};
+
+}
+
+#endif // TextResource_h
diff --git a/chromium/third_party/WebKit/Source/core/fetch/TextResourceDecoder.cpp b/chromium/third_party/WebKit/Source/core/fetch/TextResourceDecoder.cpp
deleted file mode 100644
index 5a21dd5e233..00000000000
--- a/chromium/third_party/WebKit/Source/core/fetch/TextResourceDecoder.cpp
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
- Copyright (C) 2005, 2006, 2007 Alexey Proskuryakov (ap@nypop.com)
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-
-#include "config.h"
-#include "core/fetch/TextResourceDecoder.h"
-
-#include "HTMLNames.h"
-#include "core/dom/DOMImplementation.h"
-#include "core/html/parser/HTMLMetaCharsetParser.h"
-#include "platform/text/TextEncodingDetector.h"
-#include "wtf/StringExtras.h"
-#include "wtf/text/TextCodec.h"
-#include "wtf/text/TextEncodingRegistry.h"
-
-using namespace WTF;
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4)
-{
- return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4;
-}
-
-static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5)
-{
- return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5;
-}
-
-static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7)
-{
- return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5 && p[6] == b6 && p[7] == b7;
-}
-
-static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7, char b8, char b9)
-{
- return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5 && p[6] == b6 && p[7] == b7 && p[8] == b8 && p[9] == b9;
-}
-
-// You might think we should put these find functions elsewhere, perhaps with the
-// similar functions that operate on UChar, but arguably only the decoder has
-// a reason to process strings of char rather than UChar.
-
-static int find(const char* subject, size_t subjectLength, const char* target)
-{
- size_t targetLength = strlen(target);
- if (targetLength > subjectLength)
- return -1;
- for (size_t i = 0; i <= subjectLength - targetLength; ++i) {
- bool match = true;
- for (size_t j = 0; j < targetLength; ++j) {
- if (subject[i + j] != target[j]) {
- match = false;
- break;
- }
- }
- if (match)
- return i;
- }
- return -1;
-}
-
-static WTF::TextEncoding findTextEncoding(const char* encodingName, int length)
-{
- Vector<char, 64> buffer(length + 1);
- memcpy(buffer.data(), encodingName, length);
- buffer[length] = '\0';
- return buffer.data();
-}
-
-TextResourceDecoder::ContentType TextResourceDecoder::determineContentType(const String& mimeType)
-{
- if (equalIgnoringCase(mimeType, "text/css"))
- return CSS;
- if (equalIgnoringCase(mimeType, "text/html"))
- return HTML;
- if (DOMImplementation::isXMLMIMEType(mimeType))
- return XML;
- return PlainText;
-}
-
-const WTF::TextEncoding& TextResourceDecoder::defaultEncoding(ContentType contentType, const WTF::TextEncoding& specifiedDefaultEncoding)
-{
- // Despite 8.5 "Text/xml with Omitted Charset" of RFC 3023, we assume UTF-8 instead of US-ASCII
- // for text/xml. This matches Firefox.
- if (contentType == XML)
- return UTF8Encoding();
- if (!specifiedDefaultEncoding.isValid())
- return Latin1Encoding();
- return specifiedDefaultEncoding;
-}
-
-TextResourceDecoder::TextResourceDecoder(const String& mimeType, const WTF::TextEncoding& specifiedDefaultEncoding, bool usesEncodingDetector)
- : m_contentType(determineContentType(mimeType))
- , m_encoding(defaultEncoding(m_contentType, specifiedDefaultEncoding))
- , m_source(DefaultEncoding)
- , m_hintEncoding(0)
- , m_checkedForBOM(false)
- , m_checkedForCSSCharset(false)
- , m_checkedForXMLCharset(false)
- , m_checkedForMetaCharset(false)
- , m_useLenientXMLDecoding(false)
- , m_sawError(false)
- , m_usesEncodingDetector(usesEncodingDetector)
-{
-}
-
-TextResourceDecoder::~TextResourceDecoder()
-{
-}
-
-void TextResourceDecoder::setEncoding(const WTF::TextEncoding& encoding, EncodingSource source)
-{
- // In case the encoding didn't exist, we keep the old one (helps some sites specifying invalid encodings).
- if (!encoding.isValid())
- return;
-
- // When encoding comes from meta tag (i.e. it cannot be XML files sent via XHR),
- // treat x-user-defined as windows-1252 (bug 18270)
- if (source == EncodingFromMetaTag && !strcasecmp(encoding.name(), "x-user-defined"))
- m_encoding = "windows-1252";
- else if (source == EncodingFromMetaTag || source == EncodingFromXMLHeader || source == EncodingFromCSSCharset)
- m_encoding = encoding.closestByteBasedEquivalent();
- else
- m_encoding = encoding;
-
- m_codec.clear();
- m_source = source;
-}
-
-// Returns the position of the encoding string.
-static int findXMLEncoding(const char* str, int len, int& encodingLength)
-{
- int pos = find(str, len, "encoding");
- if (pos == -1)
- return -1;
- pos += 8;
-
- // Skip spaces and stray control characters.
- while (pos < len && str[pos] <= ' ')
- ++pos;
-
- // Skip equals sign.
- if (pos >= len || str[pos] != '=')
- return -1;
- ++pos;
-
- // Skip spaces and stray control characters.
- while (pos < len && str[pos] <= ' ')
- ++pos;
-
- // Skip quotation mark.
- if (pos >= len)
- return - 1;
- char quoteMark = str[pos];
- if (quoteMark != '"' && quoteMark != '\'')
- return -1;
- ++pos;
-
- // Find the trailing quotation mark.
- int end = pos;
- while (end < len && str[end] != quoteMark)
- ++end;
- if (end >= len)
- return -1;
-
- encodingLength = end - pos;
- return pos;
-}
-
-size_t TextResourceDecoder::checkForBOM(const char* data, size_t len)
-{
- // Check for UTF-16/32 or UTF-8 BOM mark at the beginning, which is a sure sign of a Unicode encoding.
- // We let it override even a user-chosen encoding.
- ASSERT(!m_checkedForBOM);
-
- size_t lengthOfBOM = 0;
-
- size_t bufferLength = m_buffer.size();
-
- size_t buf1Len = bufferLength;
- size_t buf2Len = len;
- const unsigned char* buf1 = reinterpret_cast<const unsigned char*>(m_buffer.data());
- const unsigned char* buf2 = reinterpret_cast<const unsigned char*>(data);
- unsigned char c1 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
- unsigned char c2 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
- unsigned char c3 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
- unsigned char c4 = buf2Len ? (--buf2Len, *buf2++) : 0;
-
- // Check for the BOM.
- if (c1 == 0xFF && c2 == 0xFE) {
- if (c3 || c4) {
- setEncoding(UTF16LittleEndianEncoding(), AutoDetectedEncoding);
- lengthOfBOM = 2;
- } else {
- setEncoding(UTF32LittleEndianEncoding(), AutoDetectedEncoding);
- lengthOfBOM = 4;
- }
- } else if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) {
- setEncoding(UTF8Encoding(), AutoDetectedEncoding);
- lengthOfBOM = 3;
- } else if (c1 == 0xFE && c2 == 0xFF) {
- setEncoding(UTF16BigEndianEncoding(), AutoDetectedEncoding);
- lengthOfBOM = 2;
- } else if (!c1 && !c2 && c3 == 0xFE && c4 == 0xFF) {
- setEncoding(UTF32BigEndianEncoding(), AutoDetectedEncoding);
- lengthOfBOM = 4;
- }
-
- if (lengthOfBOM || bufferLength + len >= 4)
- m_checkedForBOM = true;
-
- return lengthOfBOM;
-}
-
-bool TextResourceDecoder::checkForCSSCharset(const char* data, size_t len, bool& movedDataToBuffer)
-{
- if (m_source != DefaultEncoding && m_source != EncodingFromParentFrame) {
- m_checkedForCSSCharset = true;
- return true;
- }
-
- size_t oldSize = m_buffer.size();
- m_buffer.grow(oldSize + len);
- memcpy(m_buffer.data() + oldSize, data, len);
-
- movedDataToBuffer = true;
-
- if (m_buffer.size() <= 13) // strlen('@charset "x";') == 13
- return false;
-
- const char* dataStart = m_buffer.data();
- const char* dataEnd = dataStart + m_buffer.size();
-
- if (bytesEqual(dataStart, '@', 'c', 'h', 'a', 'r', 's', 'e', 't', ' ', '"')) {
- dataStart += 10;
- const char* pos = dataStart;
-
- while (pos < dataEnd && *pos != '"')
- ++pos;
- if (pos == dataEnd)
- return false;
-
- int encodingNameLength = pos - dataStart;
-
- ++pos;
-
- if (*pos == ';')
- setEncoding(findTextEncoding(dataStart, encodingNameLength), EncodingFromCSSCharset);
- }
-
- m_checkedForCSSCharset = true;
- return true;
-}
-
-bool TextResourceDecoder::checkForXMLCharset(const char* data, size_t len, bool& movedDataToBuffer)
-{
- if (m_source != DefaultEncoding && m_source != EncodingFromParentFrame) {
- m_checkedForXMLCharset = true;
- return true;
- }
-
- // This is not completely efficient, since the function might go
- // through the HTML head several times.
-
- size_t oldSize = m_buffer.size();
- m_buffer.grow(oldSize + len);
- memcpy(m_buffer.data() + oldSize, data, len);
-
- movedDataToBuffer = true;
-
- const char* ptr = m_buffer.data();
- const char* pEnd = ptr + m_buffer.size();
-
- // Is there enough data available to check for XML declaration?
- if (m_buffer.size() < 8)
- return false;
-
- // Handle XML declaration, which can have encoding in it. This encoding is honored even for HTML documents.
- // It is an error for an XML declaration not to be at the start of an XML document, and it is ignored in HTML documents in such case.
- if (bytesEqual(ptr, '<', '?', 'x', 'm', 'l')) {
- const char* xmlDeclarationEnd = ptr;
- while (xmlDeclarationEnd != pEnd && *xmlDeclarationEnd != '>')
- ++xmlDeclarationEnd;
- if (xmlDeclarationEnd == pEnd)
- return false;
- // No need for +1, because we have an extra "?" to lose at the end of XML declaration.
- int len = 0;
- int pos = findXMLEncoding(ptr, xmlDeclarationEnd - ptr, len);
- if (pos != -1)
- setEncoding(findTextEncoding(ptr + pos, len), EncodingFromXMLHeader);
- // continue looking for a charset - it may be specified in an HTTP-Equiv meta
- } else if (bytesEqual(ptr, '<', 0, '?', 0, 'x', 0)) {
- setEncoding(UTF16LittleEndianEncoding(), AutoDetectedEncoding);
- } else if (bytesEqual(ptr, 0, '<', 0, '?', 0, 'x')) {
- setEncoding(UTF16BigEndianEncoding(), AutoDetectedEncoding);
- } else if (bytesEqual(ptr, '<', 0, 0, 0, '?', 0, 0, 0)) {
- setEncoding(UTF32LittleEndianEncoding(), AutoDetectedEncoding);
- } else if (bytesEqual(ptr, 0, 0, 0, '<', 0, 0, 0, '?')) {
- setEncoding(UTF32BigEndianEncoding(), AutoDetectedEncoding);
- }
-
- m_checkedForXMLCharset = true;
- return true;
-}
-
-void TextResourceDecoder::checkForMetaCharset(const char* data, size_t length)
-{
- if (m_source == UserChosenEncoding || m_source == EncodingFromHTTPHeader || m_source == AutoDetectedEncoding) {
- m_checkedForMetaCharset = true;
- return;
- }
-
- if (!m_charsetParser)
- m_charsetParser = HTMLMetaCharsetParser::create();
-
- if (!m_charsetParser->checkForMetaCharset(data, length))
- return;
-
- setEncoding(m_charsetParser->encoding(), EncodingFromMetaTag);
- m_charsetParser.clear();
- m_checkedForMetaCharset = true;
- return;
-}
-
-// We use the encoding detector in two cases:
-// 1. Encoding detector is turned ON and no other encoding source is
-// available (that is, it's DefaultEncoding).
-// 2. Encoding detector is turned ON and the encoding is set to
-// the encoding of the parent frame, which is also auto-detected.
-// Note that condition #2 is NOT satisfied unless parent-child frame
-// relationship is compliant to the same-origin policy. If they're from
-// different domains, |m_source| would not be set to EncodingFromParentFrame
-// in the first place.
-bool TextResourceDecoder::shouldAutoDetect() const
-{
- // Just checking m_hintEncoding suffices here because it's only set
- // in setHintEncoding when the source is AutoDetectedEncoding.
- return m_usesEncodingDetector
- && (m_source == DefaultEncoding || (m_source == EncodingFromParentFrame && m_hintEncoding));
-}
-
-String TextResourceDecoder::decode(const char* data, size_t len)
-{
- size_t lengthOfBOM = 0;
- if (!m_checkedForBOM)
- lengthOfBOM = checkForBOM(data, len);
-
- bool movedDataToBuffer = false;
-
- if (m_contentType == CSS && !m_checkedForCSSCharset) {
- if (!checkForCSSCharset(data, len, movedDataToBuffer))
- return emptyString();
- }
-
- if ((m_contentType == HTML || m_contentType == XML) && !m_checkedForXMLCharset) {
- if (!checkForXMLCharset(data, len, movedDataToBuffer))
- return emptyString();
- }
-
- const char* dataForDecode = data + lengthOfBOM;
- size_t lengthForDecode = len - lengthOfBOM;
-
- if (!m_buffer.isEmpty()) {
- if (!movedDataToBuffer) {
- size_t oldSize = m_buffer.size();
- m_buffer.grow(oldSize + len);
- memcpy(m_buffer.data() + oldSize, data, len);
- }
-
- dataForDecode = m_buffer.data() + lengthOfBOM;
- lengthForDecode = m_buffer.size() - lengthOfBOM;
- }
-
- if (m_contentType == HTML && !m_checkedForMetaCharset)
- checkForMetaCharset(dataForDecode, lengthForDecode);
-
- if (shouldAutoDetect()) {
- WTF::TextEncoding detectedEncoding;
- if (detectTextEncoding(data, len, m_hintEncoding, &detectedEncoding))
- setEncoding(detectedEncoding, EncodingFromContentSniffing);
- }
-
- ASSERT(m_encoding.isValid());
-
- if (!m_codec)
- m_codec = newTextCodec(m_encoding);
-
- String result = m_codec->decode(dataForDecode, lengthForDecode, false, m_contentType == XML && !m_useLenientXMLDecoding, m_sawError);
-
- m_buffer.clear();
- return result;
-}
-
-String TextResourceDecoder::flush()
-{
- // If we can not identify the encoding even after a document is completely
- // loaded, we need to detect the encoding if other conditions for
- // autodetection is satisfied.
- if (m_buffer.size() && shouldAutoDetect()
- && ((!m_checkedForXMLCharset && (m_contentType == HTML || m_contentType == XML)) || (!m_checkedForCSSCharset && (m_contentType == CSS)))) {
- WTF::TextEncoding detectedEncoding;
- if (detectTextEncoding(m_buffer.data(), m_buffer.size(), m_hintEncoding, &detectedEncoding))
- setEncoding(detectedEncoding, EncodingFromContentSniffing);
- }
-
- if (!m_codec)
- m_codec = newTextCodec(m_encoding);
-
- String result = m_codec->decode(m_buffer.data(), m_buffer.size(), true, m_contentType == XML && !m_useLenientXMLDecoding, m_sawError);
- m_buffer.clear();
- m_codec.clear();
- m_checkedForBOM = false; // Skip BOM again when re-decoding.
- return result;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/fetch/TextResourceDecoder.h b/chromium/third_party/WebKit/Source/core/fetch/TextResourceDecoder.h
deleted file mode 100644
index 4c773478148..00000000000
--- a/chromium/third_party/WebKit/Source/core/fetch/TextResourceDecoder.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
- Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
- Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-
-*/
-
-#ifndef TextResourceDecoder_h
-#define TextResourceDecoder_h
-
-#include "wtf/RefCounted.h"
-#include "wtf/text/TextEncoding.h"
-
-namespace WebCore {
-
-class HTMLMetaCharsetParser;
-
-class TextResourceDecoder {
-public:
- enum EncodingSource {
- DefaultEncoding,
- AutoDetectedEncoding,
- EncodingFromContentSniffing,
- EncodingFromXMLHeader,
- EncodingFromMetaTag,
- EncodingFromCSSCharset,
- EncodingFromHTTPHeader,
- UserChosenEncoding,
- EncodingFromParentFrame
- };
-
- static PassOwnPtr<TextResourceDecoder> create(const String& mimeType, const WTF::TextEncoding& defaultEncoding = WTF::TextEncoding(), bool usesEncodingDetector = false)
- {
- return adoptPtr(new TextResourceDecoder(mimeType, defaultEncoding, usesEncodingDetector));
- }
- ~TextResourceDecoder();
-
- void setEncoding(const WTF::TextEncoding&, EncodingSource);
- const WTF::TextEncoding& encoding() const { return m_encoding; }
- bool encodingWasDetectedHeuristically() const
- {
- return m_source == AutoDetectedEncoding
- || m_source == EncodingFromContentSniffing;
- }
-
- String decode(const char* data, size_t length);
- String flush();
-
- void setHintEncoding(const WTF::TextEncoding& encoding)
- {
- m_hintEncoding = encoding.name();
- }
-
- void useLenientXMLDecoding() { m_useLenientXMLDecoding = true; }
- bool sawError() const { return m_sawError; }
-
-private:
- TextResourceDecoder(const String& mimeType, const WTF::TextEncoding& defaultEncoding, bool usesEncodingDetector);
-
- enum ContentType { PlainText, HTML, XML, CSS }; // PlainText only checks for BOM.
- static ContentType determineContentType(const String& mimeType);
- static const WTF::TextEncoding& defaultEncoding(ContentType, const WTF::TextEncoding& defaultEncoding);
-
- size_t checkForBOM(const char*, size_t);
- bool checkForCSSCharset(const char*, size_t, bool& movedDataToBuffer);
- bool checkForXMLCharset(const char*, size_t, bool& movedDataToBuffer);
- void checkForMetaCharset(const char*, size_t);
- void detectJapaneseEncoding(const char*, size_t);
- bool shouldAutoDetect() const;
-
- ContentType m_contentType;
- WTF::TextEncoding m_encoding;
- OwnPtr<TextCodec> m_codec;
- EncodingSource m_source;
- const char* m_hintEncoding;
- Vector<char> m_buffer;
- bool m_checkedForBOM;
- bool m_checkedForCSSCharset;
- bool m_checkedForXMLCharset;
- bool m_checkedForMetaCharset;
- bool m_useLenientXMLDecoding; // Don't stop on XML decoding errors.
- bool m_sawError;
- bool m_usesEncodingDetector;
-
- OwnPtr<HTMLMetaCharsetParser> m_charsetParser;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.cpp b/chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.cpp
index 053a445d456..dabfc3620a5 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.cpp
@@ -27,18 +27,16 @@
#include "config.h"
#include "core/fetch/XSLStyleSheetResource.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/fetch/ResourceClientWalker.h"
#include "core/fetch/StyleSheetResourceClient.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/SharedBuffer.h"
#include "wtf/Vector.h"
namespace WebCore {
-XSLStyleSheetResource::XSLStyleSheetResource(const ResourceRequest& resourceRequest)
- : StyleSheetResource(resourceRequest, XSLStyleSheet)
- , m_decoder(TextResourceDecoder::create("text/xsl"))
+XSLStyleSheetResource::XSLStyleSheetResource(const ResourceRequest& resourceRequest, const String& charset)
+ : StyleSheetResource(resourceRequest, XSLStyleSheet, "text/xsl", charset)
{
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
DEFINE_STATIC_LOCAL(const AtomicString, acceptXSLT, ("text/xml, application/xml, application/xhtml+xml, text/xsl, application/rss+xml, application/atom+xml", AtomicString::ConstructFromLiteral));
@@ -56,22 +54,10 @@ void XSLStyleSheetResource::didAddClient(ResourceClient* c)
static_cast<StyleSheetResourceClient*>(c)->setXSLStyleSheet(m_resourceRequest.url(), m_response.url(), m_sheet);
}
-void XSLStyleSheetResource::setEncoding(const String& chs)
-{
- m_decoder->setEncoding(chs, TextResourceDecoder::EncodingFromHTTPHeader);
-}
-
-String XSLStyleSheetResource::encoding() const
-{
- return m_decoder->encoding().name();
-}
-
void XSLStyleSheetResource::checkNotify()
{
- if (m_data.get()) {
- m_sheet = m_decoder->decode(m_data->data(), encodedSize());
- m_sheet.append(m_decoder->flush());
- }
+ if (m_data.get())
+ m_sheet = decodedText();
ResourceClientWalker<StyleSheetResourceClient> w(m_clients);
while (StyleSheetResourceClient* c = w.next())
diff --git a/chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.h b/chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.h
index 353b9da6a84..c3b0e5f206c 100644
--- a/chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.h
+++ b/chromium/third_party/WebKit/Source/core/fetch/XSLStyleSheetResource.h
@@ -34,21 +34,18 @@ namespace WebCore {
class ResourceFetcher;
class TextResourceDecoder;
-class XSLStyleSheetResource : public StyleSheetResource {
+class XSLStyleSheetResource FINAL : public StyleSheetResource {
public:
- XSLStyleSheetResource(const ResourceRequest&);
+ XSLStyleSheetResource(const ResourceRequest&, const String& charset);
const String& sheet() const { return m_sheet; }
- virtual void didAddClient(ResourceClient*);
- virtual void setEncoding(const String&);
- virtual String encoding() const;
+ virtual void didAddClient(ResourceClient*) OVERRIDE;
protected:
- virtual void checkNotify();
+ virtual void checkNotify() OVERRIDE;
String m_sheet;
- OwnPtr<TextResourceDecoder> m_decoder;
};
DEFINE_RESOURCE_TYPE_CASTS(XSLStyleSheet);
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/Blob.cpp b/chromium/third_party/WebKit/Source/core/fileapi/Blob.cpp
index def1ae0cb4b..ec9b1f4b48b 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/Blob.cpp
+++ b/chromium/third_party/WebKit/Source/core/fileapi/Blob.cpp
@@ -31,6 +31,10 @@
#include "config.h"
#include "core/fileapi/Blob.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/DOMURL.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/dom/ExecutionContext.h"
#include "core/fileapi/File.h"
#include "platform/blob/BlobRegistry.h"
#include "platform/blob/BlobURL.h"
@@ -39,7 +43,7 @@ namespace WebCore {
namespace {
-class BlobURLRegistry : public URLRegistry {
+class BlobURLRegistry FINAL : public URLRegistry {
public:
virtual void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*) OVERRIDE;
virtual void unregisterURL(const KURL&) OVERRIDE;
@@ -47,10 +51,11 @@ public:
static URLRegistry& registry();
};
-void BlobURLRegistry::registerURL(SecurityOrigin* origin, const KURL& publicURL, URLRegistrable* blob)
+void BlobURLRegistry::registerURL(SecurityOrigin* origin, const KURL& publicURL, URLRegistrable* registrableObject)
{
- ASSERT(&blob->registry() == this);
- BlobRegistry::registerPublicBlobURL(origin, publicURL, static_cast<Blob*>(blob)->blobDataHandle());
+ ASSERT(&registrableObject->registry() == this);
+ Blob* blob = static_cast<Blob*>(registrableObject);
+ BlobRegistry::registerPublicBlobURL(origin, publicURL, blob->blobDataHandle());
}
void BlobURLRegistry::unregisterURL(const KURL& publicURL)
@@ -68,6 +73,7 @@ URLRegistry& BlobURLRegistry::registry()
Blob::Blob(PassRefPtr<BlobDataHandle> dataHandle)
: m_blobDataHandle(dataHandle)
+ , m_hasBeenClosed(false)
{
ScriptWrappable::init(this);
}
@@ -76,19 +82,9 @@ Blob::~Blob()
{
}
-PassRefPtr<Blob> Blob::slice(long long start, long long end, const String& contentType) const
+void Blob::clampSliceOffsets(long long size, long long& start, long long& end)
{
- // When we slice a file for the first time, we obtain a snapshot of the file by capturing its current size and modification time.
- // The modification time will be used to verify if the file has been changed or not, when the underlying data are accessed.
- long long size;
- double modificationTime;
- if (hasBackingFile()) {
- // FIXME: This involves synchronous file operation. We need to figure out how to make it asynchronous.
- toFile(this)->captureSnapshot(size, modificationTime);
- } else {
- size = this->size();
- ASSERT(size != -1);
- }
+ ASSERT(size != -1);
// Convert the negative value that is used to select from the end.
if (start < 0)
@@ -108,25 +104,55 @@ PassRefPtr<Blob> Blob::slice(long long start, long long end, const String& conte
end = start;
else if (end > size)
end = size;
+}
+
+PassRefPtrWillBeRawPtr<Blob> Blob::slice(long long start, long long end, const String& contentType, ExceptionState& exceptionState) const
+{
+ if (hasBeenClosed()) {
+ exceptionState.throwDOMException(InvalidStateError, "Blob has been closed.");
+ return nullptr;
+ }
+
+ long long size = this->size();
+ clampSliceOffsets(size, start, end);
long long length = end - start;
OwnPtr<BlobData> blobData = BlobData::create();
blobData->setContentType(contentType);
- if (hasBackingFile()) {
- if (!toFile(this)->fileSystemURL().isEmpty())
- blobData->appendFileSystemURL(toFile(this)->fileSystemURL(), start, length, modificationTime);
- else
- blobData->appendFile(toFile(this)->path(), start, length, modificationTime);
- } else {
- blobData->appendBlob(m_blobDataHandle, start, length);
- }
+ blobData->appendBlob(m_blobDataHandle, start, length);
return Blob::create(BlobDataHandle::create(blobData.release(), length));
}
+void Blob::close(ExecutionContext* executionContext, ExceptionState& exceptionState)
+{
+ if (hasBeenClosed()) {
+ exceptionState.throwDOMException(InvalidStateError, "Blob has been closed.");
+ return;
+ }
+
+ // Dereferencing a Blob that has been closed should result in
+ // a network error. Revoke URLs registered against it through
+ // its UUID.
+ DOMURL::revokeObjectUUID(executionContext, uuid());
+
+ // A Blob enters a 'readability state' of closed, where it will report its
+ // size as zero. Blob and FileReader operations now throws on
+ // being passed a Blob in that state. Downstream uses of closed Blobs
+ // (e.g., XHR.send()) consider them as empty.
+ OwnPtr<BlobData> blobData = BlobData::create();
+ blobData->setContentType(type());
+ m_blobDataHandle = BlobDataHandle::create(blobData.release(), 0);
+ m_hasBeenClosed = true;
+}
+
+void Blob::appendTo(BlobData& blobData) const
+{
+ blobData.appendBlob(m_blobDataHandle, 0, m_blobDataHandle->size());
+}
+
URLRegistry& Blob::registry() const
{
return BlobURLRegistry::registry();
}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/Blob.h b/chromium/third_party/WebKit/Source/core/fileapi/Blob.h
index 6a721554590..76af6e718e1 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/Blob.h
+++ b/chromium/third_party/WebKit/Source/core/fileapi/Blob.h
@@ -34,6 +34,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/URLRegistry.h"
#include "platform/blob/BlobData.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -41,41 +42,68 @@
namespace WebCore {
+class ExceptionState;
class ExecutionContext;
-class Blob : public ScriptWrappable, public URLRegistrable, public RefCounted<Blob> {
+class Blob : public RefCountedWillBeGarbageCollectedFinalized<Blob>, public ScriptWrappable, public URLRegistrable {
public:
- static PassRefPtr<Blob> create()
+ static PassRefPtrWillBeRawPtr<Blob> create()
{
- return adoptRef(new Blob(BlobDataHandle::create()));
+ return adoptRefWillBeNoop(new Blob(BlobDataHandle::create()));
}
- static PassRefPtr<Blob> create(PassRefPtr<BlobDataHandle> blobDataHandle)
+ static PassRefPtrWillBeRawPtr<Blob> create(PassRefPtr<BlobDataHandle> blobDataHandle)
{
- return adoptRef(new Blob(blobDataHandle));
+ return adoptRefWillBeNoop(new Blob(blobDataHandle));
}
virtual ~Blob();
- String uuid() const { return m_blobDataHandle->uuid(); }
- String type() const { return m_blobDataHandle->type(); }
virtual unsigned long long size() const { return m_blobDataHandle->size(); }
+ virtual PassRefPtrWillBeRawPtr<Blob> slice(long long start, long long end, const String& contentType, ExceptionState&) const;
+
+ // To allow ExceptionState to be passed in last, manually enumerate the optional argument overloads.
+ PassRefPtrWillBeRawPtr<Blob> slice(ExceptionState& exceptionState) const
+ {
+ return slice(0, std::numeric_limits<long long>::max(), String(), exceptionState);
+ }
+ PassRefPtrWillBeRawPtr<Blob> slice(long long start, ExceptionState& exceptionState) const
+ {
+ return slice(start, std::numeric_limits<long long>::max(), String(), exceptionState);
+ }
+ PassRefPtrWillBeRawPtr<Blob> slice(long long start, long long end, ExceptionState& exceptionState) const
+ {
+ return slice(start, end, String(), exceptionState);
+ }
+
+ virtual void close(ExecutionContext*, ExceptionState&);
+
+ String type() const { return m_blobDataHandle->type(); }
+ String uuid() const { return m_blobDataHandle->uuid(); }
+ PassRefPtr<BlobDataHandle> blobDataHandle() const { return m_blobDataHandle; }
// True for all File instances, including the user-built ones.
virtual bool isFile() const { return false; }
// Only true for File instances that are backed by platform files.
virtual bool hasBackingFile() const { return false; }
- PassRefPtr<BlobDataHandle> blobDataHandle() const { return m_blobDataHandle; }
- PassRefPtr<Blob> slice(long long start = 0, long long end = std::numeric_limits<long long>::max(), const String& contentType = String()) const;
+ bool hasBeenClosed() const { return m_hasBeenClosed; }
+
+ // Used by the JavaScript Blob and File constructors.
+ virtual void appendTo(BlobData&) const;
// URLRegistrable to support PublicURLs.
- virtual URLRegistry& registry() const OVERRIDE;
+ virtual URLRegistry& registry() const OVERRIDE FINAL;
+
+ void trace(Visitor*) { }
protected:
explicit Blob(PassRefPtr<BlobDataHandle>);
+ static void clampSliceOffsets(long long size, long long& start, long long& end);
private:
Blob();
+
RefPtr<BlobDataHandle> m_blobDataHandle;
+ bool m_hasBeenClosed;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/Blob.idl b/chromium/third_party/WebKit/Source/core/fileapi/Blob.idl
index 28fd1aaec37..df6662d3af4 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/Blob.idl
+++ b/chromium/third_party/WebKit/Source/core/fileapi/Blob.idl
@@ -29,14 +29,16 @@
*/
[
+ WillBeGarbageCollected,
CustomConstructor,
CustomConstructor(sequence<any> blobParts, optional BlobPropertyBag options),
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker,
SpecialWrapFor=File,
] interface Blob {
readonly attribute unsigned long long size;
readonly attribute DOMString type;
- Blob slice(optional long long start, optional long long end, [TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString contentType);
+ [RaisesException] Blob slice(optional long long start, optional long long end, [TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString contentType);
+ [RaisesException, CallWith=ExecutionContext, RuntimeEnabled=FileAPIBlobClose] void close();
};
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/BlobBuilder.cpp b/chromium/third_party/WebKit/Source/core/fileapi/BlobBuilder.cpp
deleted file mode 100644
index 70583af4105..00000000000
--- a/chromium/third_party/WebKit/Source/core/fileapi/BlobBuilder.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/fileapi/BlobBuilder.h"
-
-#include "core/fileapi/Blob.h"
-#include "core/fileapi/File.h"
-#include "platform/text/LineEnding.h"
-#include "wtf/ArrayBuffer.h"
-#include "wtf/ArrayBufferView.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/Vector.h"
-#include "wtf/text/CString.h"
-#include "wtf/text/TextEncoding.h"
-
-namespace WebCore {
-
-BlobBuilder::BlobBuilder()
- : m_size(0)
-{
-}
-
-Vector<char>& BlobBuilder::getBuffer()
-{
- // If the last item is not a data item, create one. Otherwise, we simply append the new string to the last data item.
- if (m_items.isEmpty() || m_items[m_items.size() - 1].type != BlobDataItem::Data)
- m_items.append(BlobDataItem(RawData::create()));
-
- return *m_items[m_items.size() - 1].data->mutableData();
-}
-
-void BlobBuilder::append(const String& text, const String& endingType)
-{
- CString utf8Text = UTF8Encoding().normalizeAndEncode(text, WTF::EntitiesForUnencodables);
-
- Vector<char>& buffer = getBuffer();
- size_t oldSize = buffer.size();
-
- if (endingType == "native")
- normalizeLineEndingsToNative(utf8Text, buffer);
- else {
- ASSERT(endingType == "transparent");
- buffer.append(utf8Text.data(), utf8Text.length());
- }
- m_size += buffer.size() - oldSize;
-}
-
-void BlobBuilder::append(ArrayBuffer* arrayBuffer)
-{
- if (!arrayBuffer)
- return;
-
- appendBytesData(arrayBuffer->data(), arrayBuffer->byteLength());
-}
-
-void BlobBuilder::append(ArrayBufferView* arrayBufferView)
-{
- if (!arrayBufferView)
- return;
-
- appendBytesData(arrayBufferView->baseAddress(), arrayBufferView->byteLength());
-}
-
-void BlobBuilder::append(Blob* blob)
-{
- if (!blob)
- return;
- if (blob->hasBackingFile()) {
- File* file = toFile(blob);
- // If the blob is file that is not snapshoted, capture the snapshot now.
- // FIXME: This involves synchronous file operation. We need to figure out how to make it asynchronous.
- long long snapshotSize;
- double snapshotModificationTime;
- file->captureSnapshot(snapshotSize, snapshotModificationTime);
-
- m_size += snapshotSize;
- if (!file->fileSystemURL().isEmpty())
- m_items.append(BlobDataItem(file->fileSystemURL(), 0, snapshotSize, snapshotModificationTime));
- else
- m_items.append(BlobDataItem(file->path(), 0, snapshotSize, snapshotModificationTime));
- } else {
- long long blobSize = static_cast<long long>(blob->size());
- m_size += blobSize;
- m_items.append(BlobDataItem(blob->blobDataHandle(), 0, blobSize));
- }
-}
-
-void BlobBuilder::appendBytesData(const void* data, size_t length)
-{
- Vector<char>& buffer = getBuffer();
- size_t oldSize = buffer.size();
- buffer.append(static_cast<const char*>(data), length);
- m_size += buffer.size() - oldSize;
-}
-
-PassRefPtr<Blob> BlobBuilder::createBlob(const String& contentType)
-{
- OwnPtr<BlobData> blobData = BlobData::create();
- blobData->setContentType(contentType);
- blobData->swapItems(m_items);
-
- RefPtr<Blob> blob = Blob::create(BlobDataHandle::create(blobData.release(), m_size));
-
- // After creating a blob from the current blob data, we do not need to keep the data around any more.
- // Instead, we only need to keep a reference to the blob data just created.
- m_items.append(BlobDataItem(blob->blobDataHandle(), 0, m_size));
-
- return blob.release();
-}
-
-PassRefPtr<File> BlobBuilder::createFile(const String& contentType, const String& fileName, double modificationTime)
-{
- OwnPtr<BlobData> blobData = BlobData::create();
- blobData->setContentType(contentType);
- blobData->swapItems(m_items);
-
- RefPtr<File> file = File::create(fileName, modificationTime, BlobDataHandle::create(blobData.release(), m_size));
-
- // After creating a file from the current blob data, we do not need to keep the data around any more.
- // Instead, we only need to keep a reference to the blob data just created.
- m_items.append(BlobDataItem(file->blobDataHandle(), 0, m_size));
-
- return file.release();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/BlobBuilder.h b/chromium/third_party/WebKit/Source/core/fileapi/BlobBuilder.h
deleted file mode 100644
index cdf3cc562a9..00000000000
--- a/chromium/third_party/WebKit/Source/core/fileapi/BlobBuilder.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef BlobBuilder_h
-#define BlobBuilder_h
-
-#include "platform/blob/BlobData.h"
-#include "wtf/Forward.h"
-
-namespace WebCore {
-
-class Blob;
-class File;
-
-class BlobBuilder {
-public:
- BlobBuilder();
-
- void append(Blob*);
- void append(const String& text, const String& ending);
- void append(ArrayBuffer*);
- void append(ArrayBufferView*);
-
- PassRefPtr<Blob> createBlob(const String& contentType);
- PassRefPtr<File> createFile(const String& contentType, const String& fileName, double modificationTime);
-
-private:
- void appendBytesData(const void*, size_t);
-
- Vector<char>& getBuffer();
-
- long long m_size;
- BlobDataItemList m_items;
-};
-
-} // namespace WebCore
-
-#endif // BlobBuilder_h
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/File.cpp b/chromium/third_party/WebKit/Source/core/fileapi/File.cpp
index 16a810ae833..dbf3ee6c166 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/File.cpp
+++ b/chromium/third_party/WebKit/Source/core/fileapi/File.cpp
@@ -26,6 +26,8 @@
#include "config.h"
#include "core/fileapi/File.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
#include "platform/FileMetadata.h"
#include "platform/MIMETypeRegistry.h"
#include "public/platform/Platform.h"
@@ -84,9 +86,9 @@ static PassOwnPtr<BlobData> createBlobDataForFileSystemURL(const KURL& fileSyste
return blobData.release();
}
-PassRefPtr<File> File::createWithRelativePath(const String& path, const String& relativePath)
+PassRefPtrWillBeRawPtr<File> File::createWithRelativePath(const String& path, const String& relativePath)
{
- RefPtr<File> file = adoptRef(new File(path, AllContentTypes));
+ RefPtrWillBeRawPtr<File> file = adoptRefWillBeNoop(new File(path, AllContentTypes));
file->m_relativePath = relativePath;
return file.release();
}
@@ -149,6 +151,7 @@ File::File(const String& name, const FileMetadata& metadata)
File::File(const KURL& fileSystemURL, const FileMetadata& metadata)
: Blob(BlobDataHandle::create(createBlobDataForFileSystemURL(fileSystemURL, metadata), metadata.length))
, m_hasBackingFile(true)
+ , m_name(decodeURLEscapeSequences(fileSystemURL.lastPathComponent()))
, m_fileSystemURL(fileSystemURL)
, m_snapshotSize(metadata.length)
, m_snapshotModificationTime(metadata.modificationTime)
@@ -162,7 +165,7 @@ double File::lastModifiedDate() const
return m_snapshotModificationTime * msPerSecond;
time_t modificationTime;
- if (getFileModificationTime(m_path, modificationTime) && isValidFileTime(modificationTime))
+ if (hasBackingFile() && getFileModificationTime(m_path, modificationTime) && isValidFileTime(modificationTime))
return modificationTime * msPerSecond;
return currentTime() * msPerSecond;
@@ -176,11 +179,39 @@ unsigned long long File::size() const
// FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to
// come up with an exception to throw if file size is not representable.
long long size;
- if (!getFileSize(m_path, size))
+ if (!hasBackingFile() || !getFileSize(m_path, size))
return 0;
return static_cast<unsigned long long>(size);
}
+PassRefPtrWillBeRawPtr<Blob> File::slice(long long start, long long end, const String& contentType, ExceptionState& exceptionState) const
+{
+ if (hasBeenClosed()) {
+ exceptionState.throwDOMException(InvalidStateError, "File has been closed.");
+ return nullptr;
+ }
+
+ if (!m_hasBackingFile)
+ return Blob::slice(start, end, contentType, exceptionState);
+
+ // FIXME: This involves synchronous file operation. We need to figure out how to make it asynchronous.
+ long long size;
+ double modificationTime;
+ captureSnapshot(size, modificationTime);
+ clampSliceOffsets(size, start, end);
+
+ long long length = end - start;
+ OwnPtr<BlobData> blobData = BlobData::create();
+ blobData->setContentType(contentType);
+ if (!m_fileSystemURL.isEmpty()) {
+ blobData->appendFileSystemURL(m_fileSystemURL, start, length, modificationTime);
+ } else {
+ ASSERT(!m_path.isEmpty());
+ blobData->appendFile(m_path, start, length, modificationTime);
+ }
+ return Blob::create(BlobDataHandle::create(blobData.release(), length));
+}
+
void File::captureSnapshot(long long& snapshotSize, double& snapshotModificationTime) const
{
if (hasValidSnapshotMetadata()) {
@@ -192,7 +223,7 @@ void File::captureSnapshot(long long& snapshotSize, double& snapshotModification
// Obtains a snapshot of the file by capturing its current size and modification time. This is used when we slice a file for the first time.
// If we fail to retrieve the size or modification time, probably due to that the file has been deleted, 0 size is returned.
FileMetadata metadata;
- if (!getFileMetadata(m_path, metadata)) {
+ if (!hasBackingFile() || !getFileMetadata(m_path, metadata)) {
snapshotSize = 0;
snapshotModificationTime = invalidFileTime();
return;
@@ -202,4 +233,41 @@ void File::captureSnapshot(long long& snapshotSize, double& snapshotModification
snapshotModificationTime = metadata.modificationTime;
}
+void File::close(ExecutionContext* executionContext, ExceptionState& exceptionState)
+{
+ if (hasBeenClosed()) {
+ exceptionState.throwDOMException(InvalidStateError, "Blob has been closed.");
+ return;
+ }
+
+ // Reset the File to its closed representation, an empty
+ // Blob. The name isn't cleared, as it should still be
+ // available.
+ m_hasBackingFile = false;
+ m_path = String();
+ m_fileSystemURL = KURL();
+ invalidateSnapshotMetadata();
+ m_relativePath = String();
+ Blob::close(executionContext, exceptionState);
+}
+
+void File::appendTo(BlobData& blobData) const
+{
+ if (!m_hasBackingFile) {
+ Blob::appendTo(blobData);
+ return;
+ }
+
+ // FIXME: This involves synchronous file operation. We need to figure out how to make it asynchronous.
+ long long size;
+ double modificationTime;
+ captureSnapshot(size, modificationTime);
+ if (!m_fileSystemURL.isEmpty()) {
+ blobData.appendFileSystemURL(m_fileSystemURL, 0, size, modificationTime);
+ return;
+ }
+ ASSERT(!m_path.isEmpty());
+ blobData.appendFile(m_path, 0, size, modificationTime);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/File.h b/chromium/third_party/WebKit/Source/core/fileapi/File.h
index 6ff3c5b2e9b..4b9dec71c66 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/File.h
+++ b/chromium/third_party/WebKit/Source/core/fileapi/File.h
@@ -27,15 +27,18 @@
#define File_h
#include "core/fileapi/Blob.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
+class ExceptionState;
+class ExecutionContext;
struct FileMetadata;
class KURL;
-class File : public Blob {
+class File FINAL : public Blob {
public:
// AllContentTypes should only be used when the full path/name are trusted; otherwise, it could
// allow arbitrary pages to determine what applications an user has installed.
@@ -44,55 +47,64 @@ public:
AllContentTypes,
};
- static PassRefPtr<File> create(const String& path, ContentTypeLookupPolicy policy = WellKnownContentTypes)
+ static PassRefPtrWillBeRawPtr<File> create(const String& path, ContentTypeLookupPolicy policy = WellKnownContentTypes)
{
- return adoptRef(new File(path, policy));
+ return adoptRefWillBeNoop(new File(path, policy));
}
- static PassRefPtr<File> create(const String& name, double modificationTime, PassRefPtr<BlobDataHandle> blobDataHandle)
+ static PassRefPtrWillBeRawPtr<File> create(const String& name, double modificationTime, PassRefPtr<BlobDataHandle> blobDataHandle)
{
- return adoptRef(new File(name, modificationTime, blobDataHandle));
+ return adoptRefWillBeNoop(new File(name, modificationTime, blobDataHandle));
}
// For deserialization.
- static PassRefPtr<File> create(const String& path, const String& name, const String& relativePath, bool hasSnaphotData, uint64_t size, double lastModified, PassRefPtr<BlobDataHandle> blobDataHandle)
+ static PassRefPtrWillBeRawPtr<File> create(const String& path, const String& name, const String& relativePath, bool hasSnaphotData, uint64_t size, double lastModified, PassRefPtr<BlobDataHandle> blobDataHandle)
{
- return adoptRef(new File(path, name, relativePath, hasSnaphotData, size, lastModified, blobDataHandle));
+ return adoptRefWillBeNoop(new File(path, name, relativePath, hasSnaphotData, size, lastModified, blobDataHandle));
+ }
+ static PassRefPtrWillBeRawPtr<File> create(const String& path, const String& name, uint64_t size, double lastModified, PassRefPtr<BlobDataHandle> blobDataHandle)
+ {
+ return adoptRefWillBeNoop(new File(path, name, String(), true, size, lastModified, blobDataHandle));
}
- static PassRefPtr<File> createWithRelativePath(const String& path, const String& relativePath);
+ static PassRefPtrWillBeRawPtr<File> createWithRelativePath(const String& path, const String& relativePath);
// If filesystem files live in the remote filesystem, the port might pass the valid metadata (whose length field is non-negative) and cache in the File object.
//
// Otherwise calling size(), lastModifiedTime() and slice() will synchronously query the file metadata.
- static PassRefPtr<File> createForFileSystemFile(const String& name, const FileMetadata& metadata)
+ static PassRefPtrWillBeRawPtr<File> createForFileSystemFile(const String& name, const FileMetadata& metadata)
{
- return adoptRef(new File(name, metadata));
+ return adoptRefWillBeNoop(new File(name, metadata));
}
- static PassRefPtr<File> createForFileSystemFile(const KURL& url, const FileMetadata& metadata)
+ static PassRefPtrWillBeRawPtr<File> createForFileSystemFile(const KURL& url, const FileMetadata& metadata)
{
- return adoptRef(new File(url, metadata));
+ return adoptRefWillBeNoop(new File(url, metadata));
}
- KURL fileSystemURL() const { ASSERT(m_hasBackingFile); return m_fileSystemURL; }
+ KURL fileSystemURL() const { ASSERT(hasValidFileSystemURL()); return m_fileSystemURL; }
// Create a file with a name exposed to the author (via File.name and associated DOM properties) that differs from the one provided in the path.
- static PassRefPtr<File> createWithName(const String& path, const String& name, ContentTypeLookupPolicy policy = WellKnownContentTypes)
+ static PassRefPtrWillBeRawPtr<File> createWithName(const String& path, const String& name, ContentTypeLookupPolicy policy = WellKnownContentTypes)
{
if (name.isEmpty())
- return adoptRef(new File(path, policy));
- return adoptRef(new File(path, name, policy));
+ return adoptRefWillBeNoop(new File(path, policy));
+ return adoptRefWillBeNoop(new File(path, name, policy));
}
virtual unsigned long long size() const OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Blob> slice(long long start, long long end, const String& contentType, ExceptionState&) const OVERRIDE;
+ virtual void close(ExecutionContext*, ExceptionState&) OVERRIDE;
+
virtual bool isFile() const OVERRIDE { return true; }
virtual bool hasBackingFile() const OVERRIDE { return m_hasBackingFile; }
- const String& path() const { ASSERT(m_hasBackingFile); return m_path; }
- const String& name() const { return m_name; }
+ virtual void appendTo(BlobData&) const OVERRIDE;
- // This returns the current date and time if the file's last modifiecation date is not known (per spec: http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate).
+ const String& path() const { ASSERT(hasValidFilePath()); return m_path; }
+ const String name() const { return m_name; }
+
+ // This returns the current date and time if the file's last modification date is not known (per spec: http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate).
double lastModifiedDate() const;
// Returns the relative path of this file in the context of a directory selection.
@@ -112,6 +124,14 @@ private:
File(const String& name, const FileMetadata&);
File(const KURL& fileSystemURL, const FileMetadata&);
+ void invalidateSnapshotMetadata() { m_snapshotSize = -1; }
+
+#ifndef NDEBUG
+ bool hasValidFileSystemURL() const { return hasBackingFile(); }
+ // Instances not backed by a file must have an empty path set.
+ bool hasValidFilePath() const { return hasBackingFile() || m_path.isEmpty(); }
+#endif
+
bool m_hasBackingFile;
String m_path;
String m_name;
@@ -120,7 +140,7 @@ private:
// If m_snapshotSize is negative (initialized to -1 by default), the snapshot metadata is invalid and we retrieve the latest metadata synchronously in size(), lastModifiedTime() and slice().
// Otherwise, the snapshot metadata are used directly in those methods.
- const long long m_snapshotSize;
+ long long m_snapshotSize;
const double m_snapshotModificationTime;
String m_relativePath;
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/File.idl b/chromium/third_party/WebKit/Source/core/fileapi/File.idl
index 2daf799c2ca..db6c4254d5b 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/File.idl
+++ b/chromium/third_party/WebKit/Source/core/fileapi/File.idl
@@ -25,10 +25,10 @@
[
CustomConstructor(sequence<any> blobParts, DOMString fileName, optional BlobPropertyBag options),
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker,
] interface File : Blob {
readonly attribute DOMString name;
[Custom=Getter, MeasureAs=FileGetLastModifiedDate] readonly attribute Date lastModifiedDate;
[Custom=Getter, RuntimeEnabled=FileConstructor] readonly attribute long long lastModified;
- [RuntimeEnabled=DirectoryUpload] readonly attribute DOMString webkitRelativePath;
+ [MeasureAs=PrefixedFileRelativePath] readonly attribute DOMString webkitRelativePath;
};
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileError.h b/chromium/third_party/WebKit/Source/core/fileapi/FileError.h
index 26dd392577e..572684fc79a 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileError.h
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileError.h
@@ -33,6 +33,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/DOMError.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -70,7 +71,10 @@ public:
static const char syntaxErrorMessage[];
static const char typeMismatchErrorMessage[];
- static PassRefPtr<FileError> create(ErrorCode code) { return adoptRef(new FileError(code)); }
+ static PassRefPtrWillBeRawPtr<FileError> create(ErrorCode code)
+ {
+ return adoptRefWillBeNoop(new FileError(code));
+ }
ErrorCode code() const { return m_code; }
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileList.cpp b/chromium/third_party/WebKit/Source/core/fileapi/FileList.cpp
index 267a7f5d056..22d612b7a14 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileList.cpp
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileList.cpp
@@ -50,4 +50,9 @@ Vector<String> FileList::paths() const
return paths;
}
+void FileList::trace(Visitor* visitor)
+{
+ visitor->trace(m_files);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileList.h b/chromium/third_party/WebKit/Source/core/fileapi/FileList.h
index 75e07ae6feb..344adcfa709 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileList.h
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileList.h
@@ -28,6 +28,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/fileapi/File.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -35,11 +36,11 @@
namespace WebCore {
-class FileList : public ScriptWrappable, public RefCounted<FileList> {
+class FileList : public RefCountedWillBeGarbageCollectedFinalized<FileList>, public ScriptWrappable {
public:
- static PassRefPtr<FileList> create()
+ static PassRefPtrWillBeRawPtr<FileList> create()
{
- return adoptRef(new FileList);
+ return adoptRefWillBeNoop(new FileList);
}
unsigned length() const { return m_files.size(); }
@@ -47,13 +48,15 @@ public:
bool isEmpty() const { return m_files.isEmpty(); }
void clear() { m_files.clear(); }
- void append(PassRefPtr<File> file) { m_files.append(file); }
+ void append(PassRefPtrWillBeRawPtr<File> file) { m_files.append(file); }
Vector<String> paths() const;
+ void trace(Visitor*);
+
private:
FileList();
- Vector<RefPtr<File> > m_files;
+ WillBeHeapVector<RefPtrWillBeMember<File> > m_files;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileList.idl b/chromium/third_party/WebKit/Source/core/fileapi/FileList.idl
index a2a247207cb..d82231369e2 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileList.idl
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileList.idl
@@ -24,6 +24,7 @@
*/
[
+ WillBeGarbageCollected
] interface FileList {
readonly attribute unsigned long length;
getter File item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileReader.cpp b/chromium/third_party/WebKit/Source/core/fileapi/FileReader.cpp
index c94eadb93f6..e0cd3359c90 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileReader.cpp
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileReader.cpp
@@ -75,12 +75,15 @@ public:
ThrottlingController() : m_maxRunningReaders(kMaxOutstandingRequestsPerThread) { }
~ThrottlingController() { }
+ enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders };
+
void pushReader(FileReader* reader)
{
reader->setPendingActivity(reader);
if (m_pendingReaders.isEmpty()
&& m_runningReaders.size() < m_maxRunningReaders) {
reader->executePendingRead();
+ ASSERT(!m_runningReaders.contains(reader));
m_runningReaders.add(reader);
return;
}
@@ -88,23 +91,28 @@ public:
executeReaders();
}
- void removeReader(FileReader* reader)
+ FinishReaderType removeReader(FileReader* reader)
{
HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(reader);
if (hashIter != m_runningReaders.end()) {
m_runningReaders.remove(hashIter);
- reader->unsetPendingActivity(reader);
- executeReaders();
- return;
+ return RunPendingReaders;
}
Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end();
for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); it != dequeEnd; ++it) {
if (*it == reader) {
m_pendingReaders.remove(it);
- reader->unsetPendingActivity(reader);
- return;
+ break;
}
}
+ return DoNotRunPendingReaders;
+ }
+
+ void finishReader(FileReader* reader, FinishReaderType nextStep)
+ {
+ reader->unsetPendingActivity(reader);
+ if (nextStep == RunPendingReaders)
+ executeReaders();
}
private:
@@ -124,9 +132,9 @@ private:
HashSet<FileReader*> m_runningReaders;
};
-PassRefPtr<FileReader> FileReader::create(ExecutionContext* context)
+PassRefPtrWillBeRawPtr<FileReader> FileReader::create(ExecutionContext* context)
{
- RefPtr<FileReader> fileReader(adoptRef(new FileReader(context)));
+ RefPtrWillBeRawPtr<FileReader> fileReader(adoptRefWillBeRefCountedGarbageCollected(new FileReader(context)));
fileReader->suspendIfNeeded();
return fileReader.release();
}
@@ -154,7 +162,7 @@ const AtomicString& FileReader::interfaceName() const
void FileReader::stop()
{
if (m_loadingState == LoadingStateLoading || m_loadingState == LoadingStatePending)
- throttlingController()->removeReader(this);
+ throttlingController()->finishReader(this, throttlingController()->removeReader(this));
terminate();
}
@@ -220,11 +228,20 @@ void FileReader::readInternal(Blob* blob, FileReaderLoader::ReadType type, Excep
return;
}
- m_blob = blob;
+ if (blob->hasBeenClosed()) {
+ exceptionState.throwDOMException(InvalidStateError, String(blob->isFile() ? "File" : "Blob") + " has been closed.");
+ return;
+ }
+
+ // "Snapshot" the Blob data rather than the Blob itself as ongoing
+ // read operations should not be affected if close() is called on
+ // the Blob being read.
+ m_blobDataHandle = blob->blobDataHandle();
+ m_blobType = blob->type();
m_readType = type;
m_state = LOADING;
m_loadingState = LoadingStatePending;
- m_error = 0;
+ m_error = nullptr;
throttlingController()->pushReader(this);
}
@@ -235,8 +252,9 @@ void FileReader::executePendingRead()
m_loader = adoptPtr(new FileReaderLoader(m_readType, this));
m_loader->setEncoding(m_encoding);
- m_loader->setDataType(m_blob->type());
- m_loader->start(executionContext(), m_blob->blobDataHandle());
+ m_loader->setDataType(m_blobType);
+ m_loader->start(executionContext(), m_blobDataHandle);
+ m_blobDataHandle = nullptr;
}
static void delayedAbort(ExecutionContext*, FileReader* reader)
@@ -267,12 +285,15 @@ void FileReader::doAbort()
m_error = FileError::create(FileError::ABORT_ERR);
+ // Unregister the reader.
+ ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+
fireEvent(EventTypeNames::error);
fireEvent(EventTypeNames::abort);
fireEvent(EventTypeNames::loadend);
// All possible events have fired and we're done, no more pending activity.
- throttlingController()->removeReader(this);
+ throttlingController()->finishReader(this, finalStep);
}
void FileReader::terminate()
@@ -318,11 +339,14 @@ void FileReader::didFinishLoading()
ASSERT(m_state != DONE);
m_state = DONE;
+ // Unregister the reader.
+ ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+
fireEvent(EventTypeNames::load);
fireEvent(EventTypeNames::loadend);
// All possible events have fired and we're done, no more pending activity.
- throttlingController()->removeReader(this);
+ throttlingController()->finishReader(this, finalStep);
}
void FileReader::didFail(FileError::ErrorCode errorCode)
@@ -336,11 +360,15 @@ void FileReader::didFail(FileError::ErrorCode errorCode)
m_state = DONE;
m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode));
+
+ // Unregister the reader.
+ ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+
fireEvent(EventTypeNames::error);
fireEvent(EventTypeNames::loadend);
// All possible events have fired and we're done, no more pending activity.
- throttlingController()->removeReader(this);
+ throttlingController()->finishReader(this, finalStep);
}
void FileReader::fireEvent(const AtomicString& type)
@@ -365,7 +393,7 @@ ThreadSpecific<FileReader::ThrottlingController>& FileReader::throttlingControll
PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const
{
if (!m_loader || m_error)
- return 0;
+ return nullptr;
return m_loader->arrayBufferResult();
}
@@ -376,4 +404,10 @@ String FileReader::stringResult()
return m_loader->stringResult();
}
+void FileReader::trace(Visitor* visitor)
+{
+ visitor->trace(m_error);
+ EventTargetWithInlineData::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileReader.h b/chromium/third_party/WebKit/Source/core/fileapi/FileReader.h
index 65fd97aa18a..0454fae173c 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileReader.h
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileReader.h
@@ -37,6 +37,7 @@
#include "core/fileapi/FileError.h"
#include "core/fileapi/FileReaderLoader.h"
#include "core/fileapi/FileReaderLoaderClient.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/ThreadSpecific.h"
@@ -48,10 +49,11 @@ class Blob;
class ExceptionState;
class ExecutionContext;
-class FileReader : public RefCounted<FileReader>, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public FileReaderLoaderClient {
+class FileReader FINAL : public RefCountedWillBeRefCountedGarbageCollected<FileReader>, public ScriptWrappable, public ActiveDOMObject, public FileReaderLoaderClient, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(FileReader);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FileReader);
public:
- static PassRefPtr<FileReader> create(ExecutionContext*);
+ static PassRefPtrWillBeRawPtr<FileReader> create(ExecutionContext*);
virtual ~FileReader();
@@ -71,23 +73,23 @@ public:
void doAbort();
ReadyState readyState() const { return m_state; }
- PassRefPtr<FileError> error() { return m_error; }
+ PassRefPtrWillBeRawPtr<FileError> error() { return m_error; }
FileReaderLoader::ReadType readType() const { return m_readType; }
PassRefPtr<ArrayBuffer> arrayBufferResult() const;
String stringResult();
// ActiveDOMObject
- virtual void stop();
+ virtual void stop() OVERRIDE;
// EventTarget
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ExecutionContext* executionContext() const OVERRIDE { return ActiveDOMObject::executionContext(); }
// FileReaderLoaderClient
- virtual void didStartLoading();
- virtual void didReceiveData();
- virtual void didFinishLoading();
- virtual void didFail(FileError::ErrorCode);
+ virtual void didStartLoading() OVERRIDE;
+ virtual void didReceiveData() OVERRIDE;
+ virtual void didFinishLoading() OVERRIDE;
+ virtual void didFail(FileError::ErrorCode) OVERRIDE;
DEFINE_ATTRIBUTE_EVENT_LISTENER(loadstart);
DEFINE_ATTRIBUTE_EVENT_LISTENER(progress);
@@ -96,6 +98,8 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
class ThrottlingController;
@@ -121,12 +125,13 @@ private:
};
LoadingState m_loadingState;
- RefPtr<Blob> m_blob;
+ String m_blobType;
+ RefPtr<BlobDataHandle> m_blobDataHandle;
FileReaderLoader::ReadType m_readType;
String m_encoding;
OwnPtr<FileReaderLoader> m_loader;
- RefPtr<FileError> m_error;
+ RefPtrWillBeMember<FileError> m_error;
double m_lastProgressNotificationTimeMS;
};
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileReader.idl b/chromium/third_party/WebKit/Source/core/fileapi/FileReader.idl
index 6faaffff29e..07bb5a84896 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileReader.idl
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileReader.idl
@@ -30,10 +30,11 @@
*/
[
+ WillBeGarbageCollected,
ActiveDOMObject,
Constructor,
ConstructorCallWith=ExecutionContext,
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker
] interface FileReader : EventTarget {
// ready states
const unsigned short EMPTY = 0;
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
index 29827a4ab34..614aecc8a28 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
@@ -32,12 +32,12 @@
#include "core/fileapi/FileReaderLoader.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/ExecutionContext.h"
-#include "core/fetch/TextResourceDecoder.h"
#include "core/fileapi/Blob.h"
#include "core/fileapi/FileReaderLoaderClient.h"
#include "core/fileapi/Stream.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/loader/ThreadableLoader.h"
#include "platform/blob/BlobRegistry.h"
#include "platform/blob/BlobURL.h"
@@ -50,8 +50,6 @@
#include "wtf/text/Base64.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
FileReaderLoader::FileReaderLoader(ReadType readType, FileReaderLoaderClient* client)
@@ -81,10 +79,10 @@ FileReaderLoader::~FileReaderLoader()
}
}
-void FileReaderLoader::startInternal(ExecutionContext* executionContext, const Stream* stream, PassRefPtr<BlobDataHandle> blobData)
+void FileReaderLoader::startInternal(ExecutionContext& executionContext, const Stream* stream, PassRefPtr<BlobDataHandle> blobData)
{
// The blob is read by routing through the request handling layer given a temporary public url.
- m_urlForReading = BlobURL::createPublicURL(executionContext->securityOrigin());
+ m_urlForReading = BlobURL::createPublicURL(executionContext.securityOrigin());
if (m_urlForReading.isEmpty()) {
failed(FileError::SECURITY_ERR);
return;
@@ -92,43 +90,45 @@ void FileReaderLoader::startInternal(ExecutionContext* executionContext, const S
if (blobData) {
ASSERT(!stream);
- BlobRegistry::registerPublicBlobURL(executionContext->securityOrigin(), m_urlForReading, blobData);
+ BlobRegistry::registerPublicBlobURL(executionContext.securityOrigin(), m_urlForReading, blobData);
} else {
ASSERT(stream);
- BlobRegistry::registerStreamURL(executionContext->securityOrigin(), m_urlForReading, stream->url());
+ BlobRegistry::registerStreamURL(executionContext.securityOrigin(), m_urlForReading, stream->url());
}
// Construct and load the request.
ResourceRequest request(m_urlForReading);
request.setHTTPMethod("GET");
if (m_hasRange)
- request.setHTTPHeaderField("Range", String::format("bytes=%d-%d", m_rangeStart, m_rangeEnd));
+ request.setHTTPHeaderField("Range", AtomicString(String::format("bytes=%d-%d", m_rangeStart, m_rangeEnd)));
ThreadableLoaderOptions options;
- options.sendLoadCallbacks = SendCallbacks;
- options.sniffContent = DoNotSniffContent;
options.preflightPolicy = ConsiderPreflight;
- options.allowCredentials = AllowStoredCredentials;
options.crossOriginRequestPolicy = DenyCrossOriginRequests;
// FIXME: Is there a directive to which this load should be subject?
options.contentSecurityPolicyEnforcement = DoNotEnforceContentSecurityPolicy;
// Use special initiator to hide the request from the inspector.
options.initiator = FetchInitiatorTypeNames::internal;
+ ResourceLoaderOptions resourceLoaderOptions;
+ resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
+
if (m_client)
- m_loader = ThreadableLoader::create(executionContext, this, request, options);
+ m_loader = ThreadableLoader::create(executionContext, this, request, options, resourceLoaderOptions);
else
- ThreadableLoader::loadResourceSynchronously(executionContext, request, *this, options);
+ ThreadableLoader::loadResourceSynchronously(executionContext, request, *this, options, resourceLoaderOptions);
}
void FileReaderLoader::start(ExecutionContext* executionContext, PassRefPtr<BlobDataHandle> blobData)
{
+ ASSERT(executionContext);
m_urlForReadingIsStream = false;
- startInternal(executionContext, 0, blobData);
+ startInternal(*executionContext, 0, blobData);
}
void FileReaderLoader::start(ExecutionContext* executionContext, const Stream& stream, unsigned readSize)
{
+ ASSERT(executionContext);
if (readSize > 0) {
m_hasRange = true;
m_rangeStart = 0;
@@ -136,7 +136,7 @@ void FileReaderLoader::start(ExecutionContext* executionContext, const Stream& s
}
m_urlForReadingIsStream = true;
- startInternal(executionContext, &stream, 0);
+ startInternal(*executionContext, &stream, nullptr);
}
void FileReaderLoader::cancel()
@@ -155,7 +155,7 @@ void FileReaderLoader::terminate()
void FileReaderLoader::cleanup()
{
- m_loader = 0;
+ m_loader = nullptr;
// If we get any error, we do not need to keep a buffer around.
if (m_errorCode) {
@@ -197,23 +197,25 @@ void FileReaderLoader::didReceiveResponse(unsigned long, const ResourceResponse&
// Check that we can cast to unsigned since we have to do
// so to call ArrayBuffer's create function.
// FIXME: Support reading more than the current size limit of ArrayBuffer.
- if (initialBufferLength > numeric_limits<unsigned>::max()) {
+ if (initialBufferLength > std::numeric_limits<unsigned>::max()) {
failed(FileError::NOT_READABLE_ERR);
return;
}
- if (initialBufferLength < 0) {
+ if (initialBufferLength < 0)
m_rawData = adoptPtr(new ArrayBufferBuilder());
- } else {
+ else
m_rawData = adoptPtr(new ArrayBufferBuilder(static_cast<unsigned>(initialBufferLength)));
- // Total size is known. Set m_rawData to ignore overflowed data.
- m_rawData->setVariableCapacity(false);
- }
- if (!m_rawData) {
+ if (!m_rawData || !m_rawData->isValid()) {
failed(FileError::NOT_READABLE_ERR);
return;
}
+
+ if (initialBufferLength >= 0) {
+ // Total size is known. Set m_rawData to ignore overflowed data.
+ m_rawData->setVariableCapacity(false);
+ }
}
if (m_client)
@@ -305,7 +307,7 @@ PassRefPtr<ArrayBuffer> FileReaderLoader::arrayBufferResult() const
// If the loading is not started or an error occurs, return an empty result.
if (!m_rawData || m_errorCode)
- return 0;
+ return nullptr;
return m_rawData->toArrayBuffer();
}
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h
index 6bb4459ae07..d9fd0b5dd36 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h
@@ -50,7 +50,7 @@ class Stream;
class TextResourceDecoder;
class ThreadableLoader;
-class FileReaderLoader : public ThreadableLoaderClient {
+class FileReaderLoader FINAL : public ThreadableLoaderClient {
public:
enum ReadType {
ReadAsArrayBuffer,
@@ -63,17 +63,17 @@ public:
// If client is given, do the loading asynchronously. Otherwise, load synchronously.
FileReaderLoader(ReadType, FileReaderLoaderClient*);
- ~FileReaderLoader();
+ virtual ~FileReaderLoader();
void start(ExecutionContext*, PassRefPtr<BlobDataHandle>);
void start(ExecutionContext*, const Stream&, unsigned readSize);
void cancel();
// ThreadableLoaderClient
- virtual void didReceiveResponse(unsigned long, const ResourceResponse&);
- virtual void didReceiveData(const char*, int);
- virtual void didFinishLoading(unsigned long, double);
- virtual void didFail(const ResourceError&);
+ virtual void didReceiveResponse(unsigned long, const ResourceResponse&) OVERRIDE;
+ virtual void didReceiveData(const char*, int) OVERRIDE;
+ virtual void didFinishLoading(unsigned long, double) OVERRIDE;
+ virtual void didFail(const ResourceError&) OVERRIDE;
String stringResult();
PassRefPtr<ArrayBuffer> arrayBufferResult() const;
@@ -99,7 +99,7 @@ public:
void setDataType(const String& dataType) { m_dataType = dataType; }
private:
- void startInternal(ExecutionContext*, const Stream*, PassRefPtr<BlobDataHandle>);
+ void startInternal(ExecutionContext&, const Stream*, PassRefPtr<BlobDataHandle>);
void terminate();
void cleanup();
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
index cbef4c1608e..7269155be79 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.cpp
@@ -50,7 +50,7 @@ PassRefPtr<ArrayBuffer> FileReaderSync::readAsArrayBuffer(ExecutionContext* exec
{
if (!blob) {
exceptionState.throwDOMException(NotFoundError, FileError::notFoundErrorMessage);
- return 0;
+ return nullptr;
}
FileReaderLoader loader(FileReaderLoader::ReadAsArrayBuffer, 0);
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.h b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
index 060633e738d..98febc3831f 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.h
@@ -32,6 +32,7 @@
#define FileReaderSync_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -43,14 +44,14 @@ class ExceptionState;
class FileReaderLoader;
class ExecutionContext;
-class FileReaderSync : public RefCounted<FileReaderSync>, public ScriptWrappable {
+class FileReaderSync FINAL : public RefCountedWillBeGarbageCollectedFinalized<FileReaderSync>, public ScriptWrappable {
public:
- static PassRefPtr<FileReaderSync> create()
+ static PassRefPtrWillBeRawPtr<FileReaderSync> create()
{
- return adoptRef(new FileReaderSync());
+ return adoptRefWillBeNoop(new FileReaderSync());
}
- virtual ~FileReaderSync() { }
+ ~FileReaderSync() { }
PassRefPtr<ArrayBuffer> readAsArrayBuffer(ExecutionContext*, Blob*, ExceptionState&);
String readAsBinaryString(ExecutionContext*, Blob*, ExceptionState&);
@@ -61,6 +62,8 @@ public:
String readAsText(ExecutionContext*, Blob*, const String& encoding, ExceptionState&);
String readAsDataURL(ExecutionContext*, Blob*, ExceptionState&);
+ void trace(Visitor*) { }
+
private:
FileReaderSync();
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
index 125e002cbd0..8a15084277a 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
+++ b/chromium/third_party/WebKit/Source/core/fileapi/FileReaderSync.idl
@@ -29,7 +29,8 @@
*/
[
- GlobalContext=WorkerGlobalScope,
+ WillBeGarbageCollected,
+ Exposed=Worker,
Constructor
] interface FileReaderSync {
[CallWith=ExecutionContext, RaisesException] ArrayBuffer readAsArrayBuffer(Blob blob);
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/Stream.h b/chromium/third_party/WebKit/Source/core/fileapi/Stream.h
index 3e9b3e04984..86b29807028 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/Stream.h
+++ b/chromium/third_party/WebKit/Source/core/fileapi/Stream.h
@@ -33,6 +33,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/ActiveDOMObject.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -42,11 +43,11 @@ namespace WebCore {
class ExecutionContext;
-class Stream : public ScriptWrappable, public ActiveDOMObject, public RefCounted<Stream> {
+class Stream FINAL : public RefCountedWillBeRefCountedGarbageCollected<Stream>, public ScriptWrappable, public ActiveDOMObject {
public:
- static PassRefPtr<Stream> create(ExecutionContext* context, const String& mediaType)
+ static PassRefPtrWillBeRawPtr<Stream> create(ExecutionContext* context, const String& mediaType)
{
- RefPtr<Stream> stream = adoptRef(new Stream(context, mediaType));
+ RefPtrWillBeRawPtr<Stream> stream = adoptRefWillBeRefCountedGarbageCollected(new Stream(context, mediaType));
stream->suspendIfNeeded();
return stream.release();
}
@@ -80,6 +81,8 @@ public:
virtual void resume() OVERRIDE;
virtual void stop() OVERRIDE;
+ void trace(Visitor*) { }
+
protected:
Stream(ExecutionContext*, const String& mediaType);
diff --git a/chromium/third_party/WebKit/Source/core/fileapi/Stream.idl b/chromium/third_party/WebKit/Source/core/fileapi/Stream.idl
index 1406b7bbde8..11f03fdbd60 100644
--- a/chromium/third_party/WebKit/Source/core/fileapi/Stream.idl
+++ b/chromium/third_party/WebKit/Source/core/fileapi/Stream.idl
@@ -38,7 +38,8 @@
[
RuntimeEnabled=Stream,
- ActiveDOMObject
+ ActiveDOMObject,
+ WillBeGarbageCollected
] interface Stream {
readonly attribute DOMString type;
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/AdjustViewSizeOrNot.h b/chromium/third_party/WebKit/Source/core/frame/AdjustViewSizeOrNot.h
deleted file mode 100644
index 0137ad9102c..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/AdjustViewSizeOrNot.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AdjustViewSizeOrNot_h
-#define AdjustViewSizeOrNot_h
-
-namespace WebCore {
-
-enum AdjustViewSizeOrNot {
- DoNotAdjustViewSize,
- AdjustViewSize
-};
-
-} // namespace WebCore
-
-#endif // AdjustViewSizeOrNot_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/BarProp.cpp b/chromium/third_party/WebKit/Source/core/frame/BarProp.cpp
index cc987187cd7..e4de0eaaca5 100644
--- a/chromium/third_party/WebKit/Source/core/frame/BarProp.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/BarProp.cpp
@@ -30,42 +30,37 @@
#include "core/frame/BarProp.h"
#include "core/page/Chrome.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-BarProp::BarProp(Frame* frame, Type type)
+BarProp::BarProp(LocalFrame* frame, Type type)
: DOMWindowProperty(frame)
, m_type(type)
{
ScriptWrappable::init(this);
}
-BarProp::Type BarProp::type() const
-{
- return m_type;
-}
-
bool BarProp::visible() const
{
if (!m_frame)
return false;
- Page* page = m_frame->page();
- if (!page)
+ FrameHost* host = m_frame->host();
+ if (!host)
return false;
switch (m_type) {
case Locationbar:
case Personalbar:
case Toolbar:
- return page->chrome().toolbarsVisible();
+ return host->chrome().toolbarsVisible();
case Menubar:
- return page->chrome().menubarVisible();
+ return host->chrome().menubarVisible();
case Scrollbars:
- return page->chrome().scrollbarsVisible();
+ return host->chrome().scrollbarsVisible();
case Statusbar:
- return page->chrome().statusbarVisible();
+ return host->chrome().statusbarVisible();
}
ASSERT_NOT_REACHED();
diff --git a/chromium/third_party/WebKit/Source/core/frame/BarProp.h b/chromium/third_party/WebKit/Source/core/frame/BarProp.h
index 1d188e14a84..534a4c6373e 100644
--- a/chromium/third_party/WebKit/Source/core/frame/BarProp.h
+++ b/chromium/third_party/WebKit/Source/core/frame/BarProp.h
@@ -31,24 +31,29 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
- class Frame;
+ class LocalFrame;
- class BarProp : public ScriptWrappable, public RefCounted<BarProp>, public DOMWindowProperty {
+ class BarProp FINAL : public RefCountedWillBeGarbageCollectedFinalized<BarProp>, public ScriptWrappable, public DOMWindowProperty {
public:
enum Type { Locationbar, Menubar, Personalbar, Scrollbars, Statusbar, Toolbar };
- static PassRefPtr<BarProp> create(Frame* frame, Type type) { return adoptRef(new BarProp(frame, type)); }
+ static PassRefPtrWillBeRawPtr<BarProp> create(LocalFrame* frame, Type type)
+ {
+ return adoptRefWillBeNoop(new BarProp(frame, type));
+ }
- Type type() const;
bool visible() const;
+ void trace(Visitor*) { }
+
private:
- BarProp(Frame*, Type);
+ BarProp(LocalFrame*, Type);
Type m_type;
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/BarProp.idl b/chromium/third_party/WebKit/Source/core/frame/BarProp.idl
index cc9ce71cedf..a7be530c7ac 100644
--- a/chromium/third_party/WebKit/Source/core/frame/BarProp.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/BarProp.idl
@@ -26,7 +26,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface BarProp {
+[
+ WillBeGarbageCollected,
+] interface BarProp {
readonly attribute boolean visible;
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/Console.cpp b/chromium/third_party/WebKit/Source/core/frame/Console.cpp
index 12cff31d383..ef2759ec1af 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Console.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/Console.cpp
@@ -31,23 +31,22 @@
#include "bindings/v8/ScriptCallStackFactory.h"
#include "core/frame/ConsoleTypes.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/ConsoleAPITypes.h"
#include "core/inspector/ScriptArguments.h"
#include "core/inspector/ScriptCallStack.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
#include "core/timing/MemoryInfo.h"
+#include "platform/TraceEvent.h"
#include "wtf/text/CString.h"
#include "wtf/text/WTFString.h"
-#include "platform/TraceEvent.h"
-
namespace WebCore {
-Console::Console(Frame* frame)
+Console::Console(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
@@ -64,24 +63,24 @@ ExecutionContext* Console::context()
return m_frame->document();
}
-void Console::reportMessageToClient(MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack)
+void Console::reportMessageToClient(MessageLevel level, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
{
- if (!m_frame || !m_frame->page() || !callStack.get())
+ if (!m_frame || !m_frame->host() || !callStack.get())
return;
String stackTrace;
- if (m_frame->page()->chrome().client().shouldReportDetailedMessageForSource(callStack->at(0).sourceURL())) {
- RefPtr<ScriptCallStack> fullStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture);
- stackTrace = PageConsole::formatStackTraceString(message, fullStack);
+ if (m_frame->chromeClient().shouldReportDetailedMessageForSource(callStack->at(0).sourceURL())) {
+ RefPtrWillBeRawPtr<ScriptCallStack> fullStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture);
+ stackTrace = FrameConsole::formatStackTraceString(message, fullStack);
}
- m_frame->page()->chrome().client().addMessageToConsole(ConsoleAPIMessageSource, level, message, callStack->at(0).lineNumber(), callStack->at(0).sourceURL(), stackTrace);
+ m_frame->chromeClient().addMessageToConsole(m_frame, ConsoleAPIMessageSource, level, message, callStack->at(0).lineNumber(), callStack->at(0).sourceURL(), stackTrace);
}
-PassRefPtr<MemoryInfo> Console::memory() const
+PassRefPtrWillBeRawPtr<MemoryInfo> Console::memory() const
{
// FIXME: Because we create a new object here each time,
// console.memory !== console.memory, which seems wrong.
- return MemoryInfo::create(m_frame);
+ return MemoryInfo::create();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/Console.h b/chromium/third_party/WebKit/Source/core/frame/Console.h
index 0cdfffdc5e3..1406aa3e8a1 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Console.h
+++ b/chromium/third_party/WebKit/Source/core/frame/Console.h
@@ -29,41 +29,39 @@
#ifndef Console_h
#define Console_h
-#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/ConsoleBase.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
class MemoryInfo;
class Page;
class ScriptArguments;
-class Console : public RefCounted<Console>, public ConsoleBase, public ScriptWrappable, public DOMWindowProperty {
+class Console FINAL : public ConsoleBase, public ScriptWrappable, public DOMWindowProperty {
public:
- using RefCounted<Console>::ref;
- using RefCounted<Console>::deref;
-
- static PassRefPtr<Console> create(Frame* frame) { return adoptRef(new Console(frame)); }
+ static PassRefPtrWillBeRawPtr<Console> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new Console(frame));
+ }
virtual ~Console();
- PassRefPtr<MemoryInfo> memory() const;
+ PassRefPtrWillBeRawPtr<MemoryInfo> memory() const;
+
+ virtual void trace(Visitor* visitor) OVERRIDE { ConsoleBase::trace(visitor); }
protected:
- virtual ExecutionContext* context();
- virtual void reportMessageToClient(MessageLevel, const String& message, PassRefPtr<ScriptCallStack>) OVERRIDE;
+ virtual ExecutionContext* context() OVERRIDE;
+ virtual void reportMessageToClient(MessageLevel, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack>) OVERRIDE;
private:
- explicit Console(Frame*);
- inline Page* page() const;
-
- virtual void refConsole() { ref(); }
- virtual void derefConsole() { deref(); }
+ explicit Console(LocalFrame*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.cpp b/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.cpp
index 8f54d86c0d1..d33525eb883 100644
--- a/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.cpp
@@ -43,67 +43,67 @@ ConsoleBase::~ConsoleBase()
{
}
-void ConsoleBase::debug(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::debug(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(LogMessageType, DebugMessageLevel, state, arguments);
+ internalAddMessage(LogMessageType, DebugMessageLevel, scriptState, arguments);
}
-void ConsoleBase::error(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::error(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(LogMessageType, ErrorMessageLevel, state, arguments);
+ internalAddMessage(LogMessageType, ErrorMessageLevel, scriptState, arguments);
}
-void ConsoleBase::info(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::info(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(LogMessageType, InfoMessageLevel, state, arguments);
+ internalAddMessage(LogMessageType, InfoMessageLevel, scriptState, arguments);
}
-void ConsoleBase::log(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::log(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(LogMessageType, LogMessageLevel, state, arguments);
+ internalAddMessage(LogMessageType, LogMessageLevel, scriptState, arguments);
}
-void ConsoleBase::warn(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::warn(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(LogMessageType, WarningMessageLevel, state, arguments);
+ internalAddMessage(LogMessageType, WarningMessageLevel, scriptState, arguments);
}
-void ConsoleBase::dir(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::dir(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(DirMessageType, LogMessageLevel, state, arguments);
+ internalAddMessage(DirMessageType, LogMessageLevel, scriptState, arguments);
}
-void ConsoleBase::dirxml(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::dirxml(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(DirXMLMessageType, LogMessageLevel, state, arguments);
+ internalAddMessage(DirXMLMessageType, LogMessageLevel, scriptState, arguments);
}
-void ConsoleBase::table(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::table(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(TableMessageType, LogMessageLevel, state, arguments);
+ internalAddMessage(TableMessageType, LogMessageLevel, scriptState, arguments);
}
-void ConsoleBase::clear(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::clear(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, ClearMessageType, LogMessageLevel, String(), state, arguments);
+ InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, ClearMessageType, LogMessageLevel, String(), scriptState, arguments);
}
-void ConsoleBase::trace(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::trace(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- internalAddMessage(TraceMessageType, LogMessageLevel, state, arguments, true, true);
+ internalAddMessage(TraceMessageType, LogMessageLevel, scriptState, arguments, true, true);
}
-void ConsoleBase::assertCondition(ScriptState* state, PassRefPtr<ScriptArguments> arguments, bool condition)
+void ConsoleBase::assertCondition(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments, bool condition)
{
if (condition)
return;
- internalAddMessage(AssertMessageType, ErrorMessageLevel, state, arguments, true);
+ internalAddMessage(AssertMessageType, ErrorMessageLevel, scriptState, arguments, true);
}
-void ConsoleBase::count(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::count(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- InspectorInstrumentation::consoleCount(context(), state, arguments);
+ InspectorInstrumentation::consoleCount(context(), scriptState, arguments);
}
void ConsoleBase::markTimeline(const String& title)
@@ -111,14 +111,14 @@ void ConsoleBase::markTimeline(const String& title)
InspectorInstrumentation::consoleTimeStamp(context(), title);
}
-void ConsoleBase::profile(ScriptState* state, const String& title)
+void ConsoleBase::profile(ScriptState* scriptState, const String& title)
{
- InspectorInstrumentation::consoleProfile(context(), title, state);
+ InspectorInstrumentation::consoleProfile(context(), title, scriptState);
}
-void ConsoleBase::profileEnd(ScriptState* state, const String& title)
+void ConsoleBase::profileEnd(ScriptState* scriptState, const String& title)
{
- InspectorInstrumentation::consoleProfileEnd(context(), title);
+ InspectorInstrumentation::consoleProfileEnd(context(), title, scriptState);
}
void ConsoleBase::time(const String& title)
@@ -127,10 +127,10 @@ void ConsoleBase::time(const String& title)
TRACE_EVENT_COPY_ASYNC_BEGIN0("webkit.console", title.utf8().data(), this);
}
-void ConsoleBase::timeEnd(ScriptState* state, const String& title)
+void ConsoleBase::timeEnd(ScriptState* scriptState, const String& title)
{
TRACE_EVENT_COPY_ASYNC_END0("webkit.console", title.utf8().data(), this);
- InspectorInstrumentation::consoleTimeEnd(context(), title, state);
+ InspectorInstrumentation::consoleTimeEnd(context(), title, scriptState);
}
void ConsoleBase::timeStamp(const String& title)
@@ -138,46 +138,46 @@ void ConsoleBase::timeStamp(const String& title)
InspectorInstrumentation::consoleTimeStamp(context(), title);
}
-void ConsoleBase::timeline(ScriptState* state, const String& title)
+void ConsoleBase::timeline(ScriptState* scriptState, const String& title)
{
- InspectorInstrumentation::consoleTimeline(context(), title, state);
+ InspectorInstrumentation::consoleTimeline(context(), title, scriptState);
}
-void ConsoleBase::timelineEnd(ScriptState* state, const String& title)
+void ConsoleBase::timelineEnd(ScriptState* scriptState, const String& title)
{
- InspectorInstrumentation::consoleTimelineEnd(context(), title, state);
+ InspectorInstrumentation::consoleTimelineEnd(context(), title, scriptState);
}
-void ConsoleBase::group(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::group(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, StartGroupMessageType, LogMessageLevel, String(), state, arguments);
+ InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, StartGroupMessageType, LogMessageLevel, String(), scriptState, arguments);
}
-void ConsoleBase::groupCollapsed(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void ConsoleBase::groupCollapsed(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, StartGroupCollapsedMessageType, LogMessageLevel, String(), state, arguments);
+ InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, StartGroupCollapsedMessageType, LogMessageLevel, String(), scriptState, arguments);
}
void ConsoleBase::groupEnd()
{
- InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, EndGroupMessageType, LogMessageLevel, String(), 0);
+ InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, EndGroupMessageType, LogMessageLevel, String(), nullptr);
}
-void ConsoleBase::internalAddMessage(MessageType type, MessageLevel level, ScriptState* state, PassRefPtr<ScriptArguments> scriptArguments, bool acceptNoArguments, bool printTrace)
+void ConsoleBase::internalAddMessage(MessageType type, MessageLevel level, ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> scriptArguments, bool acceptNoArguments, bool printTrace)
{
if (!context())
return;
- RefPtr<ScriptArguments> arguments = scriptArguments;
+ RefPtrWillBeRawPtr<ScriptArguments> arguments = scriptArguments;
if (!acceptNoArguments && !arguments->argumentCount())
return;
size_t stackSize = printTrace ? ScriptCallStack::maxCallStackSizeToCapture : 1;
- RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(stackSize));
+ RefPtrWillBeRawPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(scriptState, stackSize));
String message;
bool gotStringMessage = arguments->getFirstArgumentAsString(message);
- InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, type, level, message, state, arguments);
+ InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, type, level, message, scriptState, arguments);
if (gotStringMessage)
reportMessageToClient(level, message, callStack);
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.h b/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.h
index 30858d02731..7fc36680628 100644
--- a/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.h
+++ b/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.h
@@ -36,6 +36,7 @@
#include "core/inspector/ScriptCallStack.h"
#include "core/frame/ConsoleTypes.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -44,23 +45,20 @@ namespace WebCore {
class ScriptArguments;
-class ConsoleBase {
+class ConsoleBase : public RefCountedWillBeGarbageCollectedFinalized<ConsoleBase> {
public:
- void ref() { refConsole(); }
- void deref() { derefConsole(); }
-
- void debug(ScriptState*, PassRefPtr<ScriptArguments>);
- void error(ScriptState*, PassRefPtr<ScriptArguments>);
- void info(ScriptState*, PassRefPtr<ScriptArguments>);
- void log(ScriptState*, PassRefPtr<ScriptArguments>);
- void clear(ScriptState*, PassRefPtr<ScriptArguments>);
- void warn(ScriptState*, PassRefPtr<ScriptArguments>);
- void dir(ScriptState*, PassRefPtr<ScriptArguments>);
- void dirxml(ScriptState*, PassRefPtr<ScriptArguments>);
- void table(ScriptState*, PassRefPtr<ScriptArguments>);
- void trace(ScriptState*, PassRefPtr<ScriptArguments>);
- void assertCondition(ScriptState*, PassRefPtr<ScriptArguments>, bool condition);
- void count(ScriptState*, PassRefPtr<ScriptArguments>);
+ void debug(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void error(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void info(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void log(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void clear(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void warn(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void dir(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void dirxml(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void table(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void trace(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void assertCondition(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>, bool condition);
+ void count(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
void markTimeline(const String&);
void profile(ScriptState*, const String&);
void profileEnd(ScriptState*, const String&);
@@ -69,20 +67,20 @@ public:
void timeStamp(const String&);
void timeline(ScriptState*, const String&);
void timelineEnd(ScriptState*, const String&);
- void group(ScriptState*, PassRefPtr<ScriptArguments>);
- void groupCollapsed(ScriptState*, PassRefPtr<ScriptArguments>);
+ void group(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
+ void groupCollapsed(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
void groupEnd();
-protected:
+ virtual void trace(Visitor*) { }
+
virtual ~ConsoleBase();
+
+protected:
virtual ExecutionContext* context() = 0;
- virtual void reportMessageToClient(MessageLevel, const String& message, PassRefPtr<ScriptCallStack>) = 0;
+ virtual void reportMessageToClient(MessageLevel, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack>) = 0;
private:
- virtual void refConsole() = 0;
- virtual void derefConsole() = 0;
-
- void internalAddMessage(MessageType, MessageLevel, ScriptState*, PassRefPtr<ScriptArguments>, bool acceptNoArguments = false, bool printTrace = false);
+ void internalAddMessage(MessageType, MessageLevel, ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>, bool acceptNoArguments = false, bool printTrace = false);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.idl b/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.idl
index b63a7f5aca2..355cb597334 100644
--- a/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/ConsoleBase.idl
@@ -29,6 +29,7 @@
[
NoInterfaceObject,
+ WillBeGarbageCollected,
] interface ConsoleBase {
[CallWith=ScriptArguments&ScriptState] void debug();
[CallWith=ScriptArguments&ScriptState] void error();
@@ -41,17 +42,17 @@
[CallWith=ScriptArguments&ScriptState] void trace();
[CallWith=ScriptArguments&ScriptState, ImplementedAs=assertCondition] void assert([Default=Undefined] optional boolean condition);
[CallWith=ScriptArguments&ScriptState] void count();
- [DeprecateAs=ConsoleMarkTimeline] void markTimeline([Default=NullString] optional DOMString title);
+ [DeprecateAs=ConsoleMarkTimeline] void markTimeline(optional DOMString title = null);
- [CallWith=ScriptState] void profile([Default=NullString] optional DOMString title);
- [CallWith=ScriptState] void profileEnd([Default=NullString] optional DOMString title);
+ [CallWith=ScriptState] void profile(optional DOMString title = null);
+ [CallWith=ScriptState] void profileEnd(optional DOMString title = null);
- void time([Default=NullString] optional DOMString title);
- [CallWith=ScriptState] void timeEnd([Default=NullString] optional DOMString title);
- void timeStamp([Default=NullString] optional DOMString title);
+ void time(optional DOMString title = null);
+ [CallWith=ScriptState] void timeEnd(optional DOMString title = null);
+ void timeStamp(optional DOMString title = null);
- [CallWith=ScriptState] void timeline([Default=NullString] optional DOMString title);
- [CallWith=ScriptState] void timelineEnd([Default=NullString] optional DOMString title);
+ [CallWith=ScriptState] void timeline(optional DOMString title = null);
+ [CallWith=ScriptState] void timelineEnd(optional DOMString title = null);
[CallWith=ScriptArguments&ScriptState] void group();
[CallWith=ScriptArguments&ScriptState] void groupCollapsed();
diff --git a/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp b/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp
deleted file mode 100644
index 4c3cbe42472..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp
+++ /dev/null
@@ -1,2032 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/ContentSecurityPolicy.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ScriptCallStackFactory.h"
-#include "bindings/v8/ScriptController.h"
-#include "core/dom/DOMStringList.h"
-#include "core/dom/Document.h"
-#include "core/events/SecurityPolicyViolationEvent.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/inspector/ScriptCallStack.h"
-#include "core/loader/DocumentLoader.h"
-#include "core/loader/PingLoader.h"
-#include "core/frame/UseCounter.h"
-#include "platform/JSONValues.h"
-#include "platform/NotImplemented.h"
-#include "platform/ParsingUtilities.h"
-#include "platform/network/FormData.h"
-#include "platform/network/ResourceResponse.h"
-#include "platform/weborigin/KURL.h"
-#include "platform/weborigin/KnownPorts.h"
-#include "platform/weborigin/SchemeRegistry.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "wtf/SHA1.h"
-#include "wtf/StringHasher.h"
-#include "wtf/text/Base64.h"
-#include "wtf/text/StringBuilder.h"
-
-namespace WTF {
-
-struct VectorIntHash {
- static unsigned hash(const Vector<uint8_t>& v) { return StringHasher::computeHash(v.data(), v.size()); }
- static bool equal(const Vector<uint8_t>& a, const Vector<uint8_t>& b) { return a == b; };
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-template<> struct DefaultHash<Vector<uint8_t> > {
- typedef VectorIntHash Hash;
-};
-
-} // namespace WTF
-
-namespace WebCore {
-
-typedef std::pair<unsigned, Vector<uint8_t> > SourceHashValue;
-
-// Normally WebKit uses "static" for internal linkage, but using "static" for
-// these functions causes a compile error because these functions are used as
-// template parameters.
-namespace {
-
-bool isDirectiveNameCharacter(UChar c)
-{
- return isASCIIAlphanumeric(c) || c == '-';
-}
-
-bool isDirectiveValueCharacter(UChar c)
-{
- return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR
-}
-
-// Only checks for general Base64 encoded chars, not '=' chars since '=' is
-// positional and may only appear at the end of a Base64 encoded string.
-bool isBase64EncodedCharacter(UChar c)
-{
- return isASCIIAlphanumeric(c) || c == '+' || c == '/';
-}
-
-bool isNonceCharacter(UChar c)
-{
- return isBase64EncodedCharacter(c) || c == '=';
-}
-
-bool isSourceCharacter(UChar c)
-{
- return !isASCIISpace(c);
-}
-
-bool isPathComponentCharacter(UChar c)
-{
- return c != '?' && c != '#';
-}
-
-bool isHostCharacter(UChar c)
-{
- return isASCIIAlphanumeric(c) || c == '-';
-}
-
-bool isSchemeContinuationCharacter(UChar c)
-{
- return isASCIIAlphanumeric(c) || c == '+' || c == '-' || c == '.';
-}
-
-bool isNotASCIISpace(UChar c)
-{
- return !isASCIISpace(c);
-}
-
-bool isNotColonOrSlash(UChar c)
-{
- return c != ':' && c != '/';
-}
-
-bool isMediaTypeCharacter(UChar c)
-{
- return !isASCIISpace(c) && c != '/';
-}
-
-// CSP 1.0 Directives
-static const char connectSrc[] = "connect-src";
-static const char defaultSrc[] = "default-src";
-static const char fontSrc[] = "font-src";
-static const char frameSrc[] = "frame-src";
-static const char imgSrc[] = "img-src";
-static const char mediaSrc[] = "media-src";
-static const char objectSrc[] = "object-src";
-static const char reportURI[] = "report-uri";
-static const char sandbox[] = "sandbox";
-static const char scriptSrc[] = "script-src";
-static const char styleSrc[] = "style-src";
-
-// CSP 1.1 Directives
-static const char baseURI[] = "base-uri";
-static const char formAction[] = "form-action";
-static const char pluginTypes[] = "plugin-types";
-static const char reflectedXSS[] = "reflected-xss";
-
-bool isDirectiveName(const String& name)
-{
- return (equalIgnoringCase(name, connectSrc)
- || equalIgnoringCase(name, defaultSrc)
- || equalIgnoringCase(name, fontSrc)
- || equalIgnoringCase(name, frameSrc)
- || equalIgnoringCase(name, imgSrc)
- || equalIgnoringCase(name, mediaSrc)
- || equalIgnoringCase(name, objectSrc)
- || equalIgnoringCase(name, reportURI)
- || equalIgnoringCase(name, sandbox)
- || equalIgnoringCase(name, scriptSrc)
- || equalIgnoringCase(name, styleSrc)
- || equalIgnoringCase(name, baseURI)
- || equalIgnoringCase(name, formAction)
- || equalIgnoringCase(name, pluginTypes)
- || equalIgnoringCase(name, reflectedXSS)
- );
-}
-
-UseCounter::Feature getUseCounterType(ContentSecurityPolicy::HeaderType type)
-{
- switch (type) {
- case ContentSecurityPolicy::Enforce:
- return UseCounter::ContentSecurityPolicy;
- case ContentSecurityPolicy::Report:
- return UseCounter::ContentSecurityPolicyReportOnly;
- }
- ASSERT_NOT_REACHED();
- return UseCounter::NumberOfFeatures;
-}
-
-} // namespace
-
-static bool isSourceListNone(const UChar* begin, const UChar* end)
-{
- skipWhile<UChar, isASCIISpace>(begin, end);
-
- const UChar* position = begin;
- skipWhile<UChar, isSourceCharacter>(position, end);
- if (!equalIgnoringCase("'none'", begin, position - begin))
- return false;
-
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position != end)
- return false;
-
- return true;
-}
-
-class CSPSource {
-public:
- CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
- : m_policy(policy)
- , m_scheme(scheme)
- , m_host(host)
- , m_port(port)
- , m_path(path)
- , m_hostHasWildcard(hostHasWildcard)
- , m_portHasWildcard(portHasWildcard)
- {
- }
-
- bool matches(const KURL& url) const
- {
- if (!schemeMatches(url))
- return false;
- if (isSchemeOnly())
- return true;
- return hostMatches(url) && portMatches(url) && pathMatches(url);
- }
-
-private:
- bool schemeMatches(const KURL& url) const
- {
- if (m_scheme.isEmpty()) {
- String protectedResourceScheme(m_policy->securityOrigin()->protocol());
- if (equalIgnoringCase("http", protectedResourceScheme))
- return url.protocolIs("http") || url.protocolIs("https");
- return equalIgnoringCase(url.protocol(), protectedResourceScheme);
- }
- return equalIgnoringCase(url.protocol(), m_scheme);
- }
-
- bool hostMatches(const KURL& url) const
- {
- const String& host = url.host();
- if (equalIgnoringCase(host, m_host))
- return true;
- return m_hostHasWildcard && host.endsWith("." + m_host, false);
-
- }
-
- bool pathMatches(const KURL& url) const
- {
- if (m_path.isEmpty())
- return true;
-
- String path = decodeURLEscapeSequences(url.path());
-
- if (m_path.endsWith("/"))
- return path.startsWith(m_path, false);
-
- return path == m_path;
- }
-
- bool portMatches(const KURL& url) const
- {
- if (m_portHasWildcard)
- return true;
-
- int port = url.port();
-
- if (port == m_port)
- return true;
-
- if (!port)
- return isDefaultPortForProtocol(m_port, url.protocol());
-
- if (!m_port)
- return isDefaultPortForProtocol(port, url.protocol());
-
- return false;
- }
-
- bool isSchemeOnly() const { return m_host.isEmpty(); }
-
- ContentSecurityPolicy* m_policy;
- String m_scheme;
- String m_host;
- int m_port;
- String m_path;
-
- bool m_hostHasWildcard;
- bool m_portHasWildcard;
-};
-
-class CSPSourceList {
-public:
- CSPSourceList(ContentSecurityPolicy*, const String& directiveName);
-
- void parse(const UChar* begin, const UChar* end);
-
- bool matches(const KURL&);
- bool allowInline() const { return m_allowInline; }
- bool allowEval() const { return m_allowEval; }
- bool allowNonce(const String& nonce) const { return !nonce.isNull() && m_nonces.contains(nonce); }
- bool allowHash(const SourceHashValue& hashValue) const { return m_hashes.contains(hashValue); }
- uint8_t hashAlgorithmsUsed() const { return m_hashAlgorithmsUsed; }
-
-private:
- bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
- bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
- bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard);
- bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
- bool parsePath(const UChar* begin, const UChar* end, String& path);
- bool parseNonce(const UChar* begin, const UChar* end, String& nonce);
- bool parseHash(const UChar* begin, const UChar* end, Vector<uint8_t>& hash, ContentSecurityPolicy::HashAlgorithms&);
-
- void addSourceSelf();
- void addSourceStar();
- void addSourceUnsafeInline();
- void addSourceUnsafeEval();
- void addSourceNonce(const String& nonce);
- void addSourceHash(const ContentSecurityPolicy::HashAlgorithms&, const Vector<uint8_t>& hash);
-
- ContentSecurityPolicy* m_policy;
- Vector<CSPSource> m_list;
- String m_directiveName;
- bool m_allowStar;
- bool m_allowInline;
- bool m_allowEval;
- HashSet<String> m_nonces;
- HashSet<SourceHashValue> m_hashes;
- uint8_t m_hashAlgorithmsUsed;
-};
-
-CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& directiveName)
- : m_policy(policy)
- , m_directiveName(directiveName)
- , m_allowStar(false)
- , m_allowInline(false)
- , m_allowEval(false)
- , m_hashAlgorithmsUsed(0)
-{
-}
-
-bool CSPSourceList::matches(const KURL& url)
-{
- if (m_allowStar)
- return true;
-
- KURL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;
-
- for (size_t i = 0; i < m_list.size(); ++i) {
- if (m_list[i].matches(effectiveURL))
- return true;
- }
-
- return false;
-}
-
-// source-list = *WSP [ source *( 1*WSP source ) *WSP ]
-// / *WSP "'none'" *WSP
-//
-void CSPSourceList::parse(const UChar* begin, const UChar* end)
-{
- // We represent 'none' as an empty m_list.
- if (isSourceListNone(begin, end))
- return;
-
- const UChar* position = begin;
- while (position < end) {
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end)
- return;
-
- const UChar* beginSource = position;
- skipWhile<UChar, isSourceCharacter>(position, end);
-
- String scheme, host, path;
- int port = 0;
- bool hostHasWildcard = false;
- bool portHasWildcard = false;
-
- if (parseSource(beginSource, position, scheme, host, port, path, hostHasWildcard, portHasWildcard)) {
- // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
- // etc.) aren't stored in m_list, but as attributes on the source
- // list itself.
- if (scheme.isEmpty() && host.isEmpty())
- continue;
- if (isDirectiveName(host))
- m_policy->reportDirectiveAsSourceExpression(m_directiveName, host);
- m_list.append(CSPSource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard));
- } else {
- m_policy->reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
- }
-
- ASSERT(position == end || isASCIISpace(*position));
- }
-}
-
-// source = scheme ":"
-// / ( [ scheme "://" ] host [ port ] [ path ] )
-// / "'self'"
-bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard)
-{
- if (begin == end)
- return false;
-
- if (equalIgnoringCase("'none'", begin, end - begin))
- return false;
-
- if (end - begin == 1 && *begin == '*') {
- addSourceStar();
- return true;
- }
-
- if (equalIgnoringCase("'self'", begin, end - begin)) {
- addSourceSelf();
- return true;
- }
-
- if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) {
- addSourceUnsafeInline();
- return true;
- }
-
- if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) {
- addSourceUnsafeEval();
- return true;
- }
-
- if (m_policy->experimentalFeaturesEnabled()) {
- String nonce;
- if (!parseNonce(begin, end, nonce))
- return false;
-
- if (!nonce.isNull()) {
- addSourceNonce(nonce);
- return true;
- }
-
- Vector<uint8_t> hash;
- ContentSecurityPolicy::HashAlgorithms algorithm = ContentSecurityPolicy::HashAlgorithmsNone;
- if (!parseHash(begin, end, hash, algorithm))
- return false;
-
- if (hash.size() > 0) {
- addSourceHash(algorithm, hash);
- return true;
- }
- }
-
- const UChar* position = begin;
- const UChar* beginHost = begin;
- const UChar* beginPath = end;
- const UChar* beginPort = 0;
-
- skipWhile<UChar, isNotColonOrSlash>(position, end);
-
- if (position == end) {
- // host
- // ^
- return parseHost(beginHost, position, host, hostHasWildcard);
- }
-
- if (position < end && *position == '/') {
- // host/path || host/ || /
- // ^ ^ ^
- return parseHost(beginHost, position, host, hostHasWildcard) && parsePath(position, end, path);
- }
-
- if (position < end && *position == ':') {
- if (end - position == 1) {
- // scheme:
- // ^
- return parseScheme(begin, position, scheme);
- }
-
- if (position[1] == '/') {
- // scheme://host || scheme://
- // ^ ^
- if (!parseScheme(begin, position, scheme)
- || !skipExactly<UChar>(position, end, ':')
- || !skipExactly<UChar>(position, end, '/')
- || !skipExactly<UChar>(position, end, '/'))
- return false;
- if (position == end)
- return true;
- beginHost = position;
- skipWhile<UChar, isNotColonOrSlash>(position, end);
- }
-
- if (position < end && *position == ':') {
- // host:port || scheme://host:port
- // ^ ^
- beginPort = position;
- skipUntil<UChar>(position, end, '/');
- }
- }
-
- if (position < end && *position == '/') {
- // scheme://host/path || scheme://host:port/path
- // ^ ^
- if (position == beginHost)
- return false;
- beginPath = position;
- }
-
- if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostHasWildcard))
- return false;
-
- if (beginPort) {
- if (!parsePort(beginPort, beginPath, port, portHasWildcard))
- return false;
- } else {
- port = 0;
- }
-
- if (beginPath != end) {
- if (!parsePath(beginPath, end, path))
- return false;
- }
-
- return true;
-}
-
-// nonce-source = "'nonce-" nonce-value "'"
-// nonce-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
-//
-bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& nonce)
-{
- DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-"));
-
- if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length()))
- return true;
-
- const UChar* position = begin + noncePrefix.length();
- const UChar* nonceBegin = position;
-
- skipWhile<UChar, isNonceCharacter>(position, end);
- ASSERT(nonceBegin <= position);
-
- if ((position + 1) != end || *position != '\'' || !(position - nonceBegin))
- return false;
-
- nonce = String(nonceBegin, position - nonceBegin);
- return true;
-}
-
-// hash-source = "'" hash-algorithm "-" hash-value "'"
-// hash-algorithm = "sha1" / "sha256"
-// hash-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
-//
-bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, Vector<uint8_t>& hash, ContentSecurityPolicy::HashAlgorithms& hashAlgorithm)
-{
- DEFINE_STATIC_LOCAL(const String, sha1Prefix, ("'sha1-"));
- DEFINE_STATIC_LOCAL(const String, sha256Prefix, ("'sha256-"));
-
- String prefix;
- if (equalIgnoringCase(sha1Prefix.characters8(), begin, sha1Prefix.length())) {
- prefix = sha1Prefix;
- hashAlgorithm = ContentSecurityPolicy::HashAlgorithmsSha1;
- } else if (equalIgnoringCase(sha256Prefix.characters8(), begin, sha256Prefix.length())) {
- notImplemented();
- } else {
- return true;
- }
-
- const UChar* position = begin + prefix.length();
- const UChar* hashBegin = position;
-
- skipWhile<UChar, isBase64EncodedCharacter>(position, end);
- ASSERT(hashBegin <= position);
-
- // Base64 encodings may end with exactly one or two '=' characters
- skipExactly<UChar>(position, position + 1, '=');
- skipExactly<UChar>(position, position + 1, '=');
-
- if ((position + 1) != end || *position != '\'' || !(position - hashBegin))
- return false;
-
- Vector<char> hashVector;
- base64Decode(hashBegin, position - hashBegin, hashVector);
- hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size());
- return true;
-}
-
-// ; <scheme> production from RFC 3986
-// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-//
-bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& scheme)
-{
- ASSERT(begin <= end);
- ASSERT(scheme.isEmpty());
-
- if (begin == end)
- return false;
-
- const UChar* position = begin;
-
- if (!skipExactly<UChar, isASCIIAlpha>(position, end))
- return false;
-
- skipWhile<UChar, isSchemeContinuationCharacter>(position, end);
-
- if (position != end)
- return false;
-
- scheme = String(begin, end - begin);
- return true;
-}
-
-// host = [ "*." ] 1*host-char *( "." 1*host-char )
-// / "*"
-// host-char = ALPHA / DIGIT / "-"
-//
-bool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard)
-{
- ASSERT(begin <= end);
- ASSERT(host.isEmpty());
- ASSERT(!hostHasWildcard);
-
- if (begin == end)
- return false;
-
- const UChar* position = begin;
-
- if (skipExactly<UChar>(position, end, '*')) {
- hostHasWildcard = true;
-
- if (position == end)
- return true;
-
- if (!skipExactly<UChar>(position, end, '.'))
- return false;
- }
-
- const UChar* hostBegin = position;
-
- while (position < end) {
- if (!skipExactly<UChar, isHostCharacter>(position, end))
- return false;
-
- skipWhile<UChar, isHostCharacter>(position, end);
-
- if (position < end && !skipExactly<UChar>(position, end, '.'))
- return false;
- }
-
- ASSERT(position == end);
- host = String(hostBegin, end - hostBegin);
- return true;
-}
-
-bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path)
-{
- ASSERT(begin <= end);
- ASSERT(path.isEmpty());
-
- const UChar* position = begin;
- skipWhile<UChar, isPathComponentCharacter>(position, end);
- // path/to/file.js?query=string || path/to/file.js#anchor
- // ^ ^
- if (position < end)
- m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
-
- path = decodeURLEscapeSequences(String(begin, position - begin));
-
- ASSERT(position <= end);
- ASSERT(position == end || (*position == '#' || *position == '?'));
- return true;
-}
-
-// port = ":" ( 1*DIGIT / "*" )
-//
-bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard)
-{
- ASSERT(begin <= end);
- ASSERT(!port);
- ASSERT(!portHasWildcard);
-
- if (!skipExactly<UChar>(begin, end, ':'))
- ASSERT_NOT_REACHED();
-
- if (begin == end)
- return false;
-
- if (end - begin == 1 && *begin == '*') {
- port = 0;
- portHasWildcard = true;
- return true;
- }
-
- const UChar* position = begin;
- skipWhile<UChar, isASCIIDigit>(position, end);
-
- if (position != end)
- return false;
-
- bool ok;
- port = charactersToIntStrict(begin, end - begin, &ok);
- return ok;
-}
-
-void CSPSourceList::addSourceSelf()
-{
- m_list.append(CSPSource(m_policy, m_policy->securityOrigin()->protocol(), m_policy->securityOrigin()->host(), m_policy->securityOrigin()->port(), String(), false, false));
-}
-
-void CSPSourceList::addSourceStar()
-{
- m_allowStar = true;
-}
-
-void CSPSourceList::addSourceUnsafeInline()
-{
- m_allowInline = true;
-}
-
-void CSPSourceList::addSourceUnsafeEval()
-{
- m_allowEval = true;
-}
-
-void CSPSourceList::addSourceNonce(const String& nonce)
-{
- m_nonces.add(nonce);
-}
-
-void CSPSourceList::addSourceHash(const ContentSecurityPolicy::HashAlgorithms& algorithm, const Vector<uint8_t>& hash)
-{
- m_hashes.add(SourceHashValue(algorithm, hash));
- m_hashAlgorithmsUsed |= algorithm;
-}
-
-class CSPDirective {
-public:
- CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
- : m_name(name)
- , m_text(name + ' ' + value)
- , m_policy(policy)
- {
- }
-
- const String& text() const { return m_text; }
-
-protected:
- const ContentSecurityPolicy* policy() const { return m_policy; }
-
-private:
- String m_name;
- String m_text;
- ContentSecurityPolicy* m_policy;
-};
-
-class MediaListDirective : public CSPDirective {
-public:
- MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
- : CSPDirective(name, value, policy)
- {
- Vector<UChar> characters;
- value.appendTo(characters);
- parse(characters.data(), characters.data() + characters.size());
- }
-
- bool allows(const String& type)
- {
- return m_pluginTypes.contains(type);
- }
-
-private:
- void parse(const UChar* begin, const UChar* end)
- {
- const UChar* position = begin;
-
- // 'plugin-types ____;' OR 'plugin-types;'
- if (position == end) {
- policy()->reportInvalidPluginTypes(String());
- return;
- }
-
- while (position < end) {
- // _____ OR _____mime1/mime1
- // ^ ^
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end)
- return;
-
- // mime1/mime1 mime2/mime2
- // ^
- begin = position;
- if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- policy()->reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- skipWhile<UChar, isMediaTypeCharacter>(position, end);
-
- // mime1/mime1 mime2/mime2
- // ^
- if (!skipExactly<UChar>(position, end, '/')) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- policy()->reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
-
- // mime1/mime1 mime2/mime2
- // ^
- if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- policy()->reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- skipWhile<UChar, isMediaTypeCharacter>(position, end);
-
- // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error
- // ^ ^ ^
- if (position < end && isNotASCIISpace(*position)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- policy()->reportInvalidPluginTypes(String(begin, position - begin));
- continue;
- }
- m_pluginTypes.add(String(begin, position - begin));
-
- ASSERT(position == end || isASCIISpace(*position));
- }
- }
-
- HashSet<String> m_pluginTypes;
-};
-
-class SourceListDirective : public CSPDirective {
-public:
- SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
- : CSPDirective(name, value, policy)
- , m_sourceList(policy, name)
- {
- Vector<UChar> characters;
- value.appendTo(characters);
-
- m_sourceList.parse(characters.data(), characters.data() + characters.size());
- }
-
- bool allows(const KURL& url)
- {
- return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
- }
-
- bool allowInline() const { return m_sourceList.allowInline(); }
- bool allowEval() const { return m_sourceList.allowEval(); }
- bool allowNonce(const String& nonce) const { return m_sourceList.allowNonce(nonce.stripWhiteSpace()); }
- bool allowHash(const SourceHashValue& hashValue) const { return m_sourceList.allowHash(hashValue); }
-
- uint8_t hashAlgorithmsUsed() const { return m_sourceList.hashAlgorithmsUsed(); }
-
-private:
- CSPSourceList m_sourceList;
-};
-
-class CSPDirectiveList {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, ContentSecurityPolicy::HeaderType);
-
- void parse(const UChar* begin, const UChar* end);
-
- const String& header() const { return m_header; }
- ContentSecurityPolicy::HeaderType headerType() const { return m_headerType; }
-
- bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
- bool allowEval(ScriptState*, ContentSecurityPolicy::ReportingStatus) const;
- bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-
- bool allowScriptFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowObjectFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
- bool allowScriptNonce(const String&) const;
- bool allowStyleNonce(const String&) const;
- bool allowScriptHash(const SourceHashValue&) const;
-
- void gatherReportURIs(DOMStringList&) const;
- const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
- ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
- bool isReportOnly() const { return m_reportOnly; }
- const Vector<KURL>& reportURIs() const { return m_reportURIs; }
-
-private:
- CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType);
-
- bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
- void parseReportURI(const String& name, const String& value);
- void parsePluginTypes(const String& name, const String& value);
- void parseReflectedXSS(const String& name, const String& value);
- void addDirective(const String& name, const String& value);
- void applySandboxPolicy(const String& name, const String& sandboxPolicy);
-
- template <class CSPDirectiveType>
- void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>&);
-
- SourceListDirective* operativeDirective(SourceListDirective*) const;
- void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const;
- void reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
- void reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState*) const;
-
- bool checkEval(SourceListDirective*) const;
- bool checkInline(SourceListDirective*) const;
- bool checkNonce(SourceListDirective*, const String&) const;
- bool checkHash(SourceListDirective*, const SourceHashValue&) const;
- bool checkSource(SourceListDirective*, const KURL&) const;
- bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
-
- void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
-
- bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, ScriptState*) const;
- bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
-
- bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const;
- bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
-
- bool denyIfEnforcingPolicy() const { return m_reportOnly; }
-
- ContentSecurityPolicy* m_policy;
-
- String m_header;
- ContentSecurityPolicy::HeaderType m_headerType;
-
- bool m_reportOnly;
- bool m_haveSandboxPolicy;
- ReflectedXSSDisposition m_reflectedXSSDisposition;
-
- OwnPtr<MediaListDirective> m_pluginTypes;
- OwnPtr<SourceListDirective> m_baseURI;
- OwnPtr<SourceListDirective> m_connectSrc;
- OwnPtr<SourceListDirective> m_defaultSrc;
- OwnPtr<SourceListDirective> m_fontSrc;
- OwnPtr<SourceListDirective> m_formAction;
- OwnPtr<SourceListDirective> m_frameSrc;
- OwnPtr<SourceListDirective> m_imgSrc;
- OwnPtr<SourceListDirective> m_mediaSrc;
- OwnPtr<SourceListDirective> m_objectSrc;
- OwnPtr<SourceListDirective> m_scriptSrc;
- OwnPtr<SourceListDirective> m_styleSrc;
-
- Vector<KURL> m_reportURIs;
-
- String m_evalDisabledErrorMessage;
-};
-
-CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicy::HeaderType type)
- : m_policy(policy)
- , m_headerType(type)
- , m_reportOnly(false)
- , m_haveSandboxPolicy(false)
- , m_reflectedXSSDisposition(ReflectedXSSUnset)
-{
- m_reportOnly = type == ContentSecurityPolicy::Report;
-}
-
-PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, ContentSecurityPolicy::HeaderType type)
-{
- OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type));
- directives->parse(begin, end);
-
- if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
- String message = "Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"" + directives->operativeDirective(directives->m_scriptSrc.get())->text() + "\".\n";
- directives->setEvalDisabledErrorMessage(message);
- }
-
- if (directives->isReportOnly() && directives->reportURIs().isEmpty())
- policy->reportMissingReportURI(String(begin, end - begin));
-
- return directives.release();
-}
-
-void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const
-{
- String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
- m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
- m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-void CSPDirectiveList::reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
-{
- String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
- m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt());
- m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-void CSPDirectiveList::reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState* state) const
-{
- String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
- m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, state);
- m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
-{
- return !directive || directive->allowEval();
-}
-
-bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
-{
- return !directive || directive->allowInline();
-}
-
-bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const
-{
- return !directive || directive->allowNonce(nonce);
-}
-
-bool CSPDirectiveList::checkHash(SourceListDirective* directive, const SourceHashValue& hashValue) const
-{
- return !directive || directive->allowHash(hashValue);
-}
-
-bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& url) const
-{
- return !directive || directive->allows(url);
-}
-
-bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
-{
- if (!directive)
- return true;
- if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
- return false;
- return directive->allows(type);
-}
-
-SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
-{
- return directive ? directive : m_defaultSrc.get();
-}
-
-bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, ScriptState* state) const
-{
- if (checkEval(directive))
- return true;
-
- String suffix = String();
- if (directive == m_defaultSrc)
- suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
-
- reportViolationWithState(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), state);
- if (!m_reportOnly) {
- m_policy->reportBlockedScriptExecutionToInspector(directive->text());
- return false;
- }
- return true;
-}
-
-bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
-{
- if (checkMediaType(directive, type, typeAttribute))
- return true;
-
- String message = consoleMessage + "\'" + directive->text() + "\'.";
- if (typeAttribute.isEmpty())
- message = message + " When enforcing the 'plugin-types' directive, the plugin's media type must be explicitly declared with a 'type' attribute on the containing element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>').";
-
- reportViolation(directive->text(), pluginTypes, message + "\n", KURL());
- return denyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
-{
- if (checkInline(directive))
- return true;
-
- String suffix = String();
- if (directive == m_defaultSrc)
- suffix = " Note that '" + String(isScript ? "script" : "style") + "-src' was not explicitly set, so 'default-src' is used as a fallback.";
-
- reportViolationWithLocation(directive->text(), isScript ? scriptSrc : styleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), contextURL, contextLine);
-
- if (!m_reportOnly) {
- if (isScript)
- m_policy->reportBlockedScriptExecutionToInspector(directive->text());
- return false;
- }
- return true;
-}
-
-bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const KURL& url, const String& effectiveDirective) const
-{
- if (checkSource(directive, url))
- return true;
-
- String prefix;
- if (baseURI == effectiveDirective)
- prefix = "Refused to set the document's base URI to '";
- else if (connectSrc == effectiveDirective)
- prefix = "Refused to connect to '";
- else if (fontSrc == effectiveDirective)
- prefix = "Refused to load the font '";
- else if (formAction == effectiveDirective)
- prefix = "Refused to send form data to '";
- else if (frameSrc == effectiveDirective)
- prefix = "Refused to frame '";
- else if (imgSrc == effectiveDirective)
- prefix = "Refused to load the image '";
- else if (mediaSrc == effectiveDirective)
- prefix = "Refused to load media from '";
- else if (objectSrc == effectiveDirective)
- prefix = "Refused to load plugin data from '";
- else if (scriptSrc == effectiveDirective)
- prefix = "Refused to load the script '";
- else if (styleSrc == effectiveDirective)
- prefix = "Refused to load the stylesheet '";
-
- String suffix = String();
- if (directive == m_defaultSrc)
- suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
-
- reportViolation(directive->text(), effectiveDirective, prefix + url.elidedString() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url);
- return denyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::SendReport)
- return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
-
- return checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline event handler because it violates the following Content Security Policy directive: "));
- if (reportingStatus == ContentSecurityPolicy::SendReport)
- return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
- return checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline script because it violates the following Content Security Policy directive: "));
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true) :
- checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to apply inline style because it violates the following Content Security Policy directive: "));
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false) :
- checkInline(operativeDirective(m_styleSrc.get()));
-}
-
-bool CSPDirectiveList::allowEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "));
-
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, state) :
- checkEval(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.elidedString() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
- checkMediaType(m_pluginTypes.get(), type, typeAttribute);
-}
-
-bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, scriptSrc) :
- checkSource(operativeDirective(m_scriptSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (url.isBlankURL())
- return true;
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, objectSrc) :
- checkSource(operativeDirective(m_objectSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (url.isBlankURL())
- return true;
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_frameSrc.get()), url, frameSrc) :
- checkSource(operativeDirective(m_frameSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, imgSrc) :
- checkSource(operativeDirective(m_imgSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, styleSrc) :
- checkSource(operativeDirective(m_styleSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, fontSrc) :
- checkSource(operativeDirective(m_fontSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, mediaSrc) :
- checkSource(operativeDirective(m_mediaSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, connectSrc) :
- checkSource(operativeDirective(m_connectSrc.get()), url);
-}
-
-void CSPDirectiveList::gatherReportURIs(DOMStringList& list) const
-{
- for (size_t i = 0; i < m_reportURIs.size(); ++i)
- list.append(m_reportURIs[i].string());
-}
-
-bool CSPDirectiveList::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(m_formAction.get(), url, formAction) :
- checkSource(m_formAction.get(), url);
-}
-
-bool CSPDirectiveList::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return reportingStatus == ContentSecurityPolicy::SendReport ?
- checkSourceAndReportViolation(m_baseURI.get(), url, baseURI) :
- checkSource(m_baseURI.get(), url);
-}
-
-bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
-{
- return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
-}
-
-bool CSPDirectiveList::allowStyleNonce(const String& nonce) const
-{
- return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
-}
-
-bool CSPDirectiveList::allowScriptHash(const SourceHashValue& hashValue) const
-{
- return checkHash(operativeDirective(m_scriptSrc.get()), hashValue);
-}
-
-// policy = directive-list
-// directive-list = [ directive *( ";" [ directive ] ) ]
-//
-void CSPDirectiveList::parse(const UChar* begin, const UChar* end)
-{
- m_header = String(begin, end - begin);
-
- if (begin == end)
- return;
-
- const UChar* position = begin;
- while (position < end) {
- const UChar* directiveBegin = position;
- skipUntil<UChar>(position, end, ';');
-
- String name, value;
- if (parseDirective(directiveBegin, position, name, value)) {
- ASSERT(!name.isEmpty());
- addDirective(name, value);
- }
-
- ASSERT(position == end || *position == ';');
- skipExactly<UChar>(position, end, ';');
- }
-}
-
-// directive = *WSP [ directive-name [ WSP directive-value ] ]
-// directive-name = 1*( ALPHA / DIGIT / "-" )
-// directive-value = *( WSP / <VCHAR except ";"> )
-//
-bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
-{
- ASSERT(name.isEmpty());
- ASSERT(value.isEmpty());
-
- const UChar* position = begin;
- skipWhile<UChar, isASCIISpace>(position, end);
-
- // Empty directive (e.g. ";;;"). Exit early.
- if (position == end)
- return false;
-
- const UChar* nameBegin = position;
- skipWhile<UChar, isDirectiveNameCharacter>(position, end);
-
- // The directive-name must be non-empty.
- if (nameBegin == position) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
- return false;
- }
-
- name = String(nameBegin, position - nameBegin);
-
- if (position == end)
- return true;
-
- if (!skipExactly<UChar, isASCIISpace>(position, end)) {
- skipWhile<UChar, isNotASCIISpace>(position, end);
- m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
- return false;
- }
-
- skipWhile<UChar, isASCIISpace>(position, end);
-
- const UChar* valueBegin = position;
- skipWhile<UChar, isDirectiveValueCharacter>(position, end);
-
- if (position != end) {
- m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
- return false;
- }
-
- // The directive-value may be empty.
- if (valueBegin == position)
- return true;
-
- value = String(valueBegin, position - valueBegin);
- return true;
-}
-
-void CSPDirectiveList::parseReportURI(const String& name, const String& value)
-{
- if (!m_reportURIs.isEmpty()) {
- m_policy->reportDuplicateDirective(name);
- return;
- }
-
- Vector<UChar> characters;
- value.appendTo(characters);
-
- const UChar* position = characters.data();
- const UChar* end = position + characters.size();
-
- while (position < end) {
- skipWhile<UChar, isASCIISpace>(position, end);
-
- const UChar* urlBegin = position;
- skipWhile<UChar, isNotASCIISpace>(position, end);
-
- if (urlBegin < position) {
- String url = String(urlBegin, position - urlBegin);
- m_reportURIs.append(m_policy->completeURL(url));
- }
- }
-}
-
-
-template<class CSPDirectiveType>
-void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive)
-{
- if (directive) {
- m_policy->reportDuplicateDirective(name);
- return;
- }
- directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
-}
-
-void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
-{
- if (m_haveSandboxPolicy) {
- m_policy->reportDuplicateDirective(name);
- return;
- }
- m_haveSandboxPolicy = true;
- String invalidTokens;
- m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidTokens));
- if (!invalidTokens.isNull())
- m_policy->reportInvalidSandboxFlags(invalidTokens);
-}
-
-void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
-{
- if (m_reflectedXSSDisposition != ReflectedXSSUnset) {
- m_policy->reportDuplicateDirective(name);
- m_reflectedXSSDisposition = ReflectedXSSInvalid;
- return;
- }
-
- if (value.isEmpty()) {
- m_reflectedXSSDisposition = ReflectedXSSInvalid;
- m_policy->reportInvalidReflectedXSS(value);
- return;
- }
-
- Vector<UChar> characters;
- value.appendTo(characters);
-
- const UChar* position = characters.data();
- const UChar* end = position + characters.size();
-
- skipWhile<UChar, isASCIISpace>(position, end);
- const UChar* begin = position;
- skipWhile<UChar, isNotASCIISpace>(position, end);
-
- // value1
- // ^
- if (equalIgnoringCase("allow", begin, position - begin)) {
- m_reflectedXSSDisposition = AllowReflectedXSS;
- } else if (equalIgnoringCase("filter", begin, position - begin)) {
- m_reflectedXSSDisposition = FilterReflectedXSS;
- } else if (equalIgnoringCase("block", begin, position - begin)) {
- m_reflectedXSSDisposition = BlockReflectedXSS;
- } else {
- m_reflectedXSSDisposition = ReflectedXSSInvalid;
- m_policy->reportInvalidReflectedXSS(value);
- return;
- }
-
- skipWhile<UChar, isASCIISpace>(position, end);
- if (position == end && m_reflectedXSSDisposition != ReflectedXSSUnset)
- return;
-
- // value1 value2
- // ^
- m_reflectedXSSDisposition = ReflectedXSSInvalid;
- m_policy->reportInvalidReflectedXSS(value);
-}
-
-void CSPDirectiveList::addDirective(const String& name, const String& value)
-{
- ASSERT(!name.isEmpty());
-
- if (equalIgnoringCase(name, defaultSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
- } else if (equalIgnoringCase(name, scriptSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
- m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed());
- } else if (equalIgnoringCase(name, objectSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
- } else if (equalIgnoringCase(name, frameSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
- } else if (equalIgnoringCase(name, imgSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
- } else if (equalIgnoringCase(name, styleSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
- } else if (equalIgnoringCase(name, fontSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
- } else if (equalIgnoringCase(name, mediaSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
- } else if (equalIgnoringCase(name, connectSrc)) {
- setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
- } else if (equalIgnoringCase(name, sandbox)) {
- applySandboxPolicy(name, value);
- } else if (equalIgnoringCase(name, reportURI)) {
- parseReportURI(name, value);
- } else if (m_policy->experimentalFeaturesEnabled()) {
- if (equalIgnoringCase(name, baseURI))
- setCSPDirective<SourceListDirective>(name, value, m_baseURI);
- else if (equalIgnoringCase(name, formAction))
- setCSPDirective<SourceListDirective>(name, value, m_formAction);
- else if (equalIgnoringCase(name, pluginTypes))
- setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
- else if (equalIgnoringCase(name, reflectedXSS))
- parseReflectedXSS(name, value);
- else
- m_policy->reportUnsupportedDirective(name);
- } else {
- m_policy->reportUnsupportedDirective(name);
- }
-}
-
-ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContextClient* client)
- : m_client(client)
- , m_overrideInlineStyleAllowed(false)
- , m_sourceHashAlgorithmsUsed(HashAlgorithmsNone)
-{
-}
-
-ContentSecurityPolicy::~ContentSecurityPolicy()
-{
-}
-
-void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
-{
- ASSERT(m_policies.isEmpty());
- for (CSPDirectiveListVector::const_iterator iter = other->m_policies.begin(); iter != other->m_policies.end(); ++iter)
- addPolicyFromHeaderValue((*iter)->header(), (*iter)->headerType());
-}
-
-void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers)
-{
- if (!headers.contentSecurityPolicy().isEmpty())
- didReceiveHeader(headers.contentSecurityPolicy(), ContentSecurityPolicy::Enforce);
- if (!headers.contentSecurityPolicyReportOnly().isEmpty())
- didReceiveHeader(headers.contentSecurityPolicyReportOnly(), ContentSecurityPolicy::Report);
-
- // FIXME: Remove this reporting (and the 'xWebKitCSP*' methods) after the next release branch.
- if (m_client->isDocument()) {
- Document* document = static_cast<Document*>(m_client);
- if (!headers.xWebKitCSP().isEmpty())
- UseCounter::countDeprecation(*document, UseCounter::PrefixedContentSecurityPolicy);
- if (!headers.xWebKitCSPReportOnly().isEmpty())
- UseCounter::countDeprecation(*document, UseCounter::PrefixedContentSecurityPolicyReportOnly);
- }
-}
-
-void ContentSecurityPolicy::didReceiveHeader(const String& header, HeaderType type)
-{
- addPolicyFromHeaderValue(header, type);
-}
-
-void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, HeaderType type)
-{
- if (m_client->isDocument()) {
- Document* document = static_cast<Document*>(m_client);
- UseCounter::count(*document, getUseCounterType(type));
- }
-
- Vector<UChar> characters;
- header.appendTo(characters);
-
- const UChar* begin = characters.data();
- const UChar* end = begin + characters.size();
-
- // RFC2616, section 4.2 specifies that headers appearing multiple times can
- // be combined with a comma. Walk the header string, and parse each comma
- // separated chunk as a separate header.
- const UChar* position = begin;
- while (position < end) {
- skipUntil<UChar>(position, end, ',');
-
- // header1,header2 OR header1
- // ^ ^
- OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type);
-
- // We disable 'eval()' even in the case of report-only policies, and rely on the check in the V8Initializer::codeGenerationCheckCallbackInMainThread callback to determine whether the call should execute or not.
- if (!policy->allowEval(0, SuppressReport))
- m_client->disableEval(policy->evalDisabledErrorMessage());
-
- m_policies.append(policy.release());
-
- // Skip the comma, and begin the next header from the current position.
- ASSERT(position == end || *position == ',');
- skipExactly<UChar>(position, end, ',');
- begin = position;
- }
-}
-
-void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
-{
- m_overrideInlineStyleAllowed = value;
-}
-
-const String& ContentSecurityPolicy::deprecatedHeader() const
-{
- return m_policies.isEmpty() ? emptyString() : m_policies[0]->header();
-}
-
-ContentSecurityPolicy::HeaderType ContentSecurityPolicy::deprecatedHeaderType() const
-{
- return m_policies.isEmpty() ? Enforce : m_policies[0]->headerType();
-}
-
-template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
- for (size_t i = 0; i < policies.size(); ++i) {
- if (!(policies[i].get()->*allowed)(reportingStatus))
- return false;
- }
- return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(ScriptState* state, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
- for (size_t i = 0; i < policies.size(); ++i) {
- if (!(policies[i].get()->*allowed)(state, reportingStatus))
- return false;
- }
- return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
- for (size_t i = 0; i < policies.size(); ++i) {
- if (!(policies[i].get()->*allowed)(contextURL, contextLine, reportingStatus))
- return false;
- }
- return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(const String&) const>
-bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce)
-{
- for (size_t i = 0; i < policies.size(); ++i) {
- if (!(policies[i].get()->*allowed)(nonce))
- return false;
- }
- return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(const SourceHashValue&) const>
-bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const SourceHashValue& hashValue)
-{
- for (size_t i = 0; i < policies.size(); ++i) {
- if (!(policies[i].get()->*allowed)(hashValue))
- return false;
- }
- return true;
-}
-
-template<bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
- if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
- return true;
-
- for (size_t i = 0; i < policies.size(); ++i) {
- if (!(policies[i].get()->*allowFromURL)(url, reportingStatus))
- return false;
- }
- return true;
-}
-
-bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- if (m_overrideInlineStyleAllowed)
- return true;
- return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithState<&CSPDirectiveList::allowEval>(m_policies, state, reportingStatus);
-}
-
-String ContentSecurityPolicy::evalDisabledErrorMessage() const
-{
- for (size_t i = 0; i < m_policies.size(); ++i) {
- if (!m_policies[i]->allowEval(0, SuppressReport))
- return m_policies[i]->evalDisabledErrorMessage();
- }
- return String();
-}
-
-bool ContentSecurityPolicy::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- for (size_t i = 0; i < m_policies.size(); ++i) {
- if (!m_policies[i]->allowPluginType(type, typeAttribute, url, reportingStatus))
- return false;
- }
- return true;
-}
-
-bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowScriptNonce(const String& nonce) const
-{
- return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_policies, nonce);
-}
-
-bool ContentSecurityPolicy::allowStyleNonce(const String& nonce) const
-{
- return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policies, nonce);
-}
-
-bool ContentSecurityPolicy::allowScriptHash(const String& source) const
-{
- // TODO(jww) We don't currently have a WTF SHA256 implementation. Once we
- // have that, we should implement a proper check for sha256 hash values here.
- if (HashAlgorithmsSha1 & m_sourceHashAlgorithmsUsed) {
- Vector<uint8_t, 20> digest;
- SHA1 sourceSha1;
- sourceSha1.addBytes(UTF8Encoding().normalizeAndEncode(source, WTF::EntitiesForUnencodables));
- sourceSha1.computeHash(digest);
-
- if (isAllowedByAllWithHash<&CSPDirectiveList::allowScriptHash>(m_policies, SourceHashValue(HashAlgorithmsSha1, Vector<uint8_t>(digest))))
- return true;
- }
-
- return false;
-}
-
-void ContentSecurityPolicy::usesScriptHashAlgorithms(uint8_t algorithms)
-{
- m_sourceHashAlgorithmsUsed |= algorithms;
-}
-
-bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowStyleFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowFormAction>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
- return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::isActive() const
-{
- return !m_policies.isEmpty();
-}
-
-ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const
-{
- ReflectedXSSDisposition disposition = ReflectedXSSUnset;
- for (size_t i = 0; i < m_policies.size(); ++i) {
- if (m_policies[i]->reflectedXSSDisposition() > disposition)
- disposition = std::max(disposition, m_policies[i]->reflectedXSSDisposition());
- }
- return disposition;
-}
-
-void ContentSecurityPolicy::gatherReportURIs(DOMStringList& list) const
-{
- for (size_t i = 0; i < m_policies.size(); ++i)
- m_policies[i]->gatherReportURIs(list);
-}
-
-SecurityOrigin* ContentSecurityPolicy::securityOrigin() const
-{
- return m_client->securityContext().securityOrigin();
-}
-
-const KURL ContentSecurityPolicy::url() const
-{
- return m_client->contextURL();
-}
-
-KURL ContentSecurityPolicy::completeURL(const String& url) const
-{
- return m_client->contextCompleteURL(url);
-}
-
-void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) const
-{
- if (m_client->isDocument())
- static_cast<Document*>(m_client)->enforceSandboxFlags(mask);
-}
-
-static String stripURLForUseInReport(Document* document, const KURL& url)
-{
- if (!url.isValid())
- return String();
- if (!url.isHierarchical() || url.protocolIs("file"))
- return url.protocol();
- return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsReferrer() : SecurityOrigin::create(url)->toString();
-}
-
-static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventInit& init, Document* document, const String& directiveText, const String& effectiveDirective, const KURL& blockedURL, const String& header)
-{
- init.documentURI = document->url().string();
- init.referrer = document->referrer();
- init.blockedURI = stripURLForUseInReport(document, blockedURL);
- init.violatedDirective = directiveText;
- init.effectiveDirective = effectiveDirective;
- init.originalPolicy = header;
- init.sourceFile = String();
- init.lineNumber = 0;
- init.columnNumber = 0;
- init.statusCode = 0;
-
- if (!SecurityOrigin::isSecure(document->url()) && document->loader())
- init.statusCode = document->loader()->response().httpStatusCode();
-
- RefPtr<ScriptCallStack> stack = createScriptCallStack(1, false);
- if (!stack)
- return;
-
- const ScriptCallFrame& callFrame = stack->at(0);
-
- if (callFrame.lineNumber()) {
- KURL source = KURL(ParsedURLString, callFrame.sourceURL());
- init.sourceFile = stripURLForUseInReport(document, source);
- init.lineNumber = callFrame.lineNumber();
- init.columnNumber = callFrame.columnNumber();
- }
-}
-
-void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header)
-{
- // FIXME: Support sending reports from worker.
- if (!m_client->isDocument())
- return;
-
- Document* document = static_cast<Document*>(m_client);
- Frame* frame = document->frame();
- if (!frame)
- return;
-
- SecurityPolicyViolationEventInit violationData;
- gatherSecurityPolicyViolationEventData(violationData, document, directiveText, effectiveDirective, blockedURL, header);
-
- if (experimentalFeaturesEnabled())
- frame->domWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::create(EventTypeNames::securitypolicyviolation, violationData));
-
- if (reportURIs.isEmpty())
- return;
-
- // We need to be careful here when deciding what information to send to the
- // report-uri. Currently, we send only the current document's URL and the
- // directive that was violated. The document's URL is safe to send because
- // it's the document itself that's requesting that it be sent. You could
- // make an argument that we shouldn't send HTTPS document URLs to HTTP
- // report-uris (for the same reasons that we supress the Referer in that
- // case), but the Referer is sent implicitly whereas this request is only
- // sent explicitly. As for which directive was violated, that's pretty
- // harmless information.
-
- RefPtr<JSONObject> cspReport = JSONObject::create();
- cspReport->setString("document-uri", violationData.documentURI);
- cspReport->setString("referrer", violationData.referrer);
- cspReport->setString("violated-directive", violationData.violatedDirective);
- if (experimentalFeaturesEnabled())
- cspReport->setString("effective-directive", violationData.effectiveDirective);
- cspReport->setString("original-policy", violationData.originalPolicy);
- cspReport->setString("blocked-uri", violationData.blockedURI);
- if (!violationData.sourceFile.isEmpty() && violationData.lineNumber) {
- cspReport->setString("source-file", violationData.sourceFile);
- cspReport->setNumber("line-number", violationData.lineNumber);
- cspReport->setNumber("column-number", violationData.columnNumber);
- }
- cspReport->setNumber("status-code", violationData.statusCode);
-
- RefPtr<JSONObject> reportObject = JSONObject::create();
- reportObject->setObject("csp-report", cspReport.release());
- String stringifiedReport = reportObject->toJSONString();
-
- if (!shouldSendViolationReport(stringifiedReport))
- return;
-
- RefPtr<FormData> report = FormData::create(stringifiedReport.utf8());
-
- for (size_t i = 0; i < reportURIs.size(); ++i)
- PingLoader::sendViolationReport(frame, reportURIs[i], report, PingLoader::ContentSecurityPolicyViolationReport);
-
- didSendViolationReport(stringifiedReport);
-}
-
-void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const
-{
- DEFINE_STATIC_LOCAL(String, allow, ("allow"));
- DEFINE_STATIC_LOCAL(String, options, ("options"));
- DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri"));
- DEFINE_STATIC_LOCAL(String, allowMessage, ("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect."));
- DEFINE_STATIC_LOCAL(String, optionsMessage, ("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect."));
- DEFINE_STATIC_LOCAL(String, policyURIMessage, ("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header."));
-
- String message = "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
- if (equalIgnoringCase(name, allow))
- message = allowMessage;
- else if (equalIgnoringCase(name, options))
- message = optionsMessage;
- else if (equalIgnoringCase(name, policyURI))
- message = policyURIMessage;
-
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const
-{
- String message = "The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?";
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportDuplicateDirective(const String& name) const
-{
- String message = "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n";
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) const
-{
- String message;
- if (pluginType.isNull())
- message = "'plugin-types' Content Security Policy directive is empty; all plugins will be blocked.\n";
- else
- message = "Invalid plugin type in 'plugin-types' Content Security Policy directive: '" + pluginType + "'.\n";
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags) const
-{
- logToConsole("Error while parsing the 'sandbox' Content Security Policy directive: " + invalidFlags);
-}
-
-void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue) const
-{
- logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\".");
-}
-
-void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const
-{
- String message = "The value for Content Security Policy directive '" + directiveName + "' contains an invalid character: '" + value + "'. Non-whitespace characters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.";
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveName, const String& value, const char invalidChar) const
-{
- ASSERT(invalidChar == '#' || invalidChar == '?');
-
- String ignoring = "The fragment identifier, including the '#', will be ignored.";
- if (invalidChar == '?')
- ignoring = "The query component, including the '?', will be ignored.";
- String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring;
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiveName, const String& source) const
-{
- String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ignored.";
- if (equalIgnoringCase(source, "'none'"))
- message = message + " Note that 'none' has no effect unless it is the only expression in the source list.";
- logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const
-{
- logToConsole("The Content Security Policy '" + policy + "' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.");
-}
-
-void ContentSecurityPolicy::logToConsole(const String& message) const
-{
- m_client->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
-}
-
-void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String& directiveText) const
-{
- m_client->reportBlockedScriptExecutionToInspector(directiveText);
-}
-
-bool ContentSecurityPolicy::experimentalFeaturesEnabled() const
-{
- return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled();
-}
-
-bool ContentSecurityPolicy::shouldBypassMainWorld(ExecutionContext* context)
-{
- if (context && context->isDocument()) {
- Document* document = toDocument(context);
- if (document->frame())
- return document->frame()->script().shouldBypassMainWorldContentSecurityPolicy();
- }
- return false;
-}
-
-bool ContentSecurityPolicy::shouldSendViolationReport(const String& report) const
-{
- // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report.
- return !m_violationReportsSent.contains(report.impl()->hash());
-}
-
-void ContentSecurityPolicy::didSendViolationReport(const String& report)
-{
- m_violationReportsSent.add(report.impl()->hash());
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicy.h b/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicy.h
deleted file mode 100644
index 0720123a02d..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicy.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicy_h
-#define ContentSecurityPolicy_h
-
-#include "bindings/v8/ScriptState.h"
-#include "platform/network/HTTPParsers.h"
-#include "wtf/HashSet.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
-#include "wtf/text/StringHash.h"
-#include "wtf/text/TextPosition.h"
-#include "wtf/text/WTFString.h"
-
-namespace WTF {
-class OrdinalNumber;
-}
-
-namespace WebCore {
-
-class ContentSecurityPolicyResponseHeaders;
-class CSPDirectiveList;
-class DOMStringList;
-class JSONObject;
-class KURL;
-class ExecutionContextClient;
-class SecurityOrigin;
-
-typedef int SandboxFlags;
-typedef Vector<OwnPtr<CSPDirectiveList> > CSPDirectiveListVector;
-
-class ContentSecurityPolicy {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassOwnPtr<ContentSecurityPolicy> create(ExecutionContextClient* client)
- {
- return adoptPtr(new ContentSecurityPolicy(client));
- }
- ~ContentSecurityPolicy();
-
- void copyStateFrom(const ContentSecurityPolicy*);
-
- enum HeaderType {
- Report,
- Enforce,
- };
-
- enum ReportingStatus {
- SendReport,
- SuppressReport
- };
-
- enum HashAlgorithms {
- HashAlgorithmsNone = 0,
- HashAlgorithmsSha1 = 1 << 1,
- HashAlgorithmsSha256 = 1 << 2
- };
-
- void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
- void didReceiveHeader(const String&, HeaderType);
-
- // These functions are wrong because they assume that there is only one header.
- // FIXME: Replace them with functions that return vectors.
- const String& deprecatedHeader() const;
- HeaderType deprecatedHeaderType() const;
-
- bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
- bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
- bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
- bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
- bool allowEval(ScriptState* = 0, ReportingStatus = SendReport) const;
- bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ReportingStatus = SendReport) const;
-
- bool allowScriptFromSource(const KURL&, ReportingStatus = SendReport) const;
- bool allowObjectFromSource(const KURL&, ReportingStatus = SendReport) const;
- bool allowChildFrameFromSource(const KURL&, ReportingStatus = SendReport) const;
- bool allowImageFromSource(const KURL&, ReportingStatus = SendReport) const;
- bool allowStyleFromSource(const KURL&, ReportingStatus = SendReport) const;
- bool allowFontFromSource(const KURL&, ReportingStatus = SendReport) const;
- bool allowMediaFromSource(const KURL&, ReportingStatus = SendReport) const;
- bool allowConnectToSource(const KURL&, ReportingStatus = SendReport) const;
- bool allowFormAction(const KURL&, ReportingStatus = SendReport) const;
- bool allowBaseURI(const KURL&, ReportingStatus = SendReport) const;
- // The nonce and hash allow functions are guaranteed to not have any side
- // effects, including reporting.
- bool allowScriptNonce(const String& nonce) const;
- bool allowStyleNonce(const String& nonce) const;
- bool allowScriptHash(const String& source) const;
-
- void usesScriptHashAlgorithms(uint8_t HashAlgorithms);
-
- ReflectedXSSDisposition reflectedXSSDisposition() const;
-
- void setOverrideAllowInlineStyle(bool);
-
- bool isActive() const;
- void gatherReportURIs(DOMStringList&) const;
-
- void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const;
- void reportDuplicateDirective(const String&) const;
- void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const;
- void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
- void reportInvalidPluginTypes(const String&) const;
- void reportInvalidSandboxFlags(const String&) const;
- void reportInvalidSourceExpression(const String& directiveName, const String& source) const;
- void reportInvalidReflectedXSS(const String&) const;
- void reportMissingReportURI(const String&) const;
- void reportUnsupportedDirective(const String&) const;
- void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header);
-
- void reportBlockedScriptExecutionToInspector(const String& directiveText) const;
-
- const KURL url() const;
- KURL completeURL(const String&) const;
- SecurityOrigin* securityOrigin() const;
- void enforceSandboxFlags(SandboxFlags) const;
- String evalDisabledErrorMessage() const;
-
- bool experimentalFeaturesEnabled() const;
-
- static bool shouldBypassMainWorld(ExecutionContext*);
-
- ExecutionContextClient* client() { return m_client; }
-
-private:
- explicit ContentSecurityPolicy(ExecutionContextClient*);
-
- void logToConsole(const String& message) const;
- void addPolicyFromHeaderValue(const String&, HeaderType);
-
- bool shouldSendViolationReport(const String&) const;
- void didSendViolationReport(const String&);
-
- ExecutionContextClient* m_client;
- bool m_overrideInlineStyleAllowed;
- CSPDirectiveListVector m_policies;
-
- HashSet<unsigned, AlreadyHashed> m_violationReportsSent;
-
- // We put the hash functions used on the policy object so that we only need
- // to calculate a script hash once and then distribute it to all of the
- // directives for validation.
- uint8_t m_sourceHashAlgorithmsUsed;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp b/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp
deleted file mode 100644
index 1b58eac6c72..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
-
-#include "platform/network/ResourceResponse.h"
-
-namespace WebCore {
-
-ContentSecurityPolicyResponseHeaders::ContentSecurityPolicyResponseHeaders(const ResourceResponse& response)
- : m_contentSecurityPolicy(response.httpHeaderField("Content-Security-Policy"))
- , m_contentSecurityPolicyReportOnly(response.httpHeaderField("Content-Security-Policy-Report-Only"))
- , m_xWebKitCSP(response.httpHeaderField("X-WebKit-CSP"))
- , m_xWebKitCSPReportOnly(response.httpHeaderField("X-WebKit-CSP-Report-Only"))
-{
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.h b/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.h
deleted file mode 100644
index d5076d4a062..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicyResponseHeaders_h
-#define ContentSecurityPolicyResponseHeaders_h
-
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class ResourceResponse;
-
-class ContentSecurityPolicyResponseHeaders {
-public:
- ContentSecurityPolicyResponseHeaders() { }
- explicit ContentSecurityPolicyResponseHeaders(const ResourceResponse&);
-
- const String& contentSecurityPolicy() const { return m_contentSecurityPolicy; }
- const String& contentSecurityPolicyReportOnly() const { return m_contentSecurityPolicyReportOnly; }
- const String& xWebKitCSP() const { return m_xWebKitCSP; }
- const String& xWebKitCSPReportOnly() const { return m_xWebKitCSPReportOnly; }
-
-private:
- String m_contentSecurityPolicy;
- String m_contentSecurityPolicyReportOnly;
- String m_xWebKitCSP;
- String m_xWebKitCSPReportOnly;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMPoint.h b/chromium/third_party/WebKit/Source/core/frame/DOMPoint.h
index ae8478b25af..bbf2e5bbeff 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMPoint.h
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMPoint.h
@@ -27,20 +27,21 @@
#define DOMPoint_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class DOMPoint : public RefCounted<DOMPoint>, public ScriptWrappable {
+class DOMPoint FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMPoint>, public ScriptWrappable {
public:
- static PassRefPtr<DOMPoint> create()
+ static PassRefPtrWillBeRawPtr<DOMPoint> create()
{
- return adoptRef(new DOMPoint());
+ return adoptRefWillBeNoop(new DOMPoint());
}
- static PassRefPtr<DOMPoint> create(float x, float y)
+ static PassRefPtrWillBeRawPtr<DOMPoint> create(float x, float y)
{
- return adoptRef(new DOMPoint(x, y));
+ return adoptRefWillBeNoop(new DOMPoint(x, y));
}
float x() const { return m_x; }
@@ -49,6 +50,8 @@ public:
void setX(float x) { m_x = x; }
void setY(float y) { m_y = y; }
+ void trace(Visitor*) { }
+
private:
DOMPoint(float x = 0, float y = 0)
: m_x(x)
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMSecurityPolicy.cpp b/chromium/third_party/WebKit/Source/core/frame/DOMSecurityPolicy.cpp
deleted file mode 100644
index c60cdadc168..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/DOMSecurityPolicy.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2012 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/DOMSecurityPolicy.h"
-
-#include "core/dom/DOMStringList.h"
-#include "core/dom/ExecutionContext.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "wtf/text/TextPosition.h"
-
-namespace WebCore {
-
-namespace {
-
-bool isPolicyActiveInContext(ExecutionContext* context)
-{
- // If the ExecutionContext has been destroyed, there's no active policy.
- if (!context)
- return false;
-
- return context->contentSecurityPolicy()->isActive();
-}
-
-template<bool (ContentSecurityPolicy::*allowWithType)(const String&, const String&, const KURL&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedWithType(ExecutionContext* context, const String& type)
-{
- if (!isPolicyActiveInContext(context))
- return true;
-
- return (context->contentSecurityPolicy()->*allowWithType)(type, type, KURL(), ContentSecurityPolicy::SuppressReport);
-}
-
-template<bool (ContentSecurityPolicy::*allowWithURL)(const KURL&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedWithURL(ExecutionContext* context, const String& url)
-{
- if (!isPolicyActiveInContext(context))
- return true;
-
- KURL parsedURL = context->completeURL(url);
- if (!parsedURL.isValid())
- return false; // FIXME: Figure out how to throw a JavaScript error.
-
- return (context->contentSecurityPolicy()->*allowWithURL)(parsedURL, ContentSecurityPolicy::SuppressReport);
-}
-
-template<bool (ContentSecurityPolicy::*allowWithContext)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowed(ExecutionContext* context)
-{
- if (!isPolicyActiveInContext(context))
- return true;
-
- return (context->contentSecurityPolicy()->*allowWithContext)(String(), WTF::OrdinalNumber::beforeFirst(), ContentSecurityPolicy::SuppressReport);
-}
-
-} // namespace
-
-DOMSecurityPolicy::DOMSecurityPolicy(ExecutionContext* context)
- : ContextLifecycleObserver(context)
-{
- ScriptWrappable::init(this);
-}
-
-DOMSecurityPolicy::~DOMSecurityPolicy()
-{
-}
-
-bool DOMSecurityPolicy::isActive() const
-{
- return isPolicyActiveInContext(executionContext());
-}
-
-PassRefPtr<DOMStringList> DOMSecurityPolicy::reportURIs() const
-{
- RefPtr<DOMStringList> result = DOMStringList::create();
-
- if (isActive())
- executionContext()->contentSecurityPolicy()->gatherReportURIs(*result.get());
-
- return result.release();
-}
-
-bool DOMSecurityPolicy::allowsInlineScript() const
-{
- return isAllowed<&ContentSecurityPolicy::allowInlineScript>(executionContext());
-}
-
-bool DOMSecurityPolicy::allowsInlineStyle() const
-{
- return isAllowed<&ContentSecurityPolicy::allowInlineStyle>(executionContext());
-}
-
-bool DOMSecurityPolicy::allowsEval() const
-{
- if (!isActive())
- return true;
-
- return executionContext()->contentSecurityPolicy()->allowEval(0, ContentSecurityPolicy::SuppressReport);
-}
-
-
-bool DOMSecurityPolicy::allowsConnectionTo(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowConnectToSource>(executionContext(), url);
-}
-
-bool DOMSecurityPolicy::allowsFontFrom(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowFontFromSource>(executionContext(), url);
-}
-
-bool DOMSecurityPolicy::allowsFormAction(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowFormAction>(executionContext(), url);
-}
-
-bool DOMSecurityPolicy::allowsFrameFrom(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowChildFrameFromSource>(executionContext(), url);
-}
-
-bool DOMSecurityPolicy::allowsImageFrom(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowImageFromSource>(executionContext(), url);
-}
-
-bool DOMSecurityPolicy::allowsMediaFrom(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowMediaFromSource>(executionContext(), url);
-}
-
-bool DOMSecurityPolicy::allowsObjectFrom(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowObjectFromSource>(executionContext(), url);
-}
-
-bool DOMSecurityPolicy::allowsPluginType(const String& type) const
-{
- return isAllowedWithType<&ContentSecurityPolicy::allowPluginType>(executionContext(), type);
-}
-
-bool DOMSecurityPolicy::allowsScriptFrom(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowScriptFromSource>(executionContext(), url);
-}
-
-bool DOMSecurityPolicy::allowsStyleFrom(const String& url) const
-{
- return isAllowedWithURL<&ContentSecurityPolicy::allowStyleFromSource>(executionContext(), url);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMSecurityPolicy.h b/chromium/third_party/WebKit/Source/core/frame/DOMSecurityPolicy.h
deleted file mode 100644
index 78813013993..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/DOMSecurityPolicy.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DOMSecurityPolicy_h
-#define DOMSecurityPolicy_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/dom/ContextLifecycleObserver.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class ContentSecurityPolicy;
-class DOMStringList;
-class Frame;
-
-class DOMSecurityPolicy : public RefCounted<DOMSecurityPolicy>, public ScriptWrappable, public ContextLifecycleObserver {
-public:
- static PassRefPtr<DOMSecurityPolicy> create(ExecutionContext* context)
- {
- return adoptRef(new DOMSecurityPolicy(context));
- }
- ~DOMSecurityPolicy();
-
- bool isActive() const;
- PassRefPtr<DOMStringList> reportURIs() const;
-
- bool allowsInlineScript() const;
- bool allowsInlineStyle() const;
- bool allowsEval() const;
-
- bool allowsConnectionTo(const String& url) const;
- bool allowsFontFrom(const String& url) const;
- bool allowsFormAction(const String& url) const;
- bool allowsFrameFrom(const String& url) const;
- bool allowsImageFrom(const String& url) const;
- bool allowsMediaFrom(const String& url) const;
- bool allowsObjectFrom(const String& url) const;
- bool allowsPluginType(const String& type) const;
- bool allowsScriptFrom(const String& url) const;
- bool allowsStyleFrom(const String& url) const;
-
-private:
- explicit DOMSecurityPolicy(ExecutionContext*);
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMTimer.cpp b/chromium/third_party/WebKit/Source/core/frame/DOMTimer.cpp
index a41845ddc25..4d9b76a27ff 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMTimer.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMTimer.cpp
@@ -29,10 +29,10 @@
#include "core/dom/ExecutionContext.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
+#include "platform/TraceEvent.h"
#include "wtf/CurrentTime.h"
-using namespace std;
-
namespace WebCore {
static const int maxIntervalForUserGestureForwarding = 1000; // One second matches Gecko.
@@ -70,6 +70,9 @@ double DOMTimer::visiblePageAlignmentInterval()
int DOMTimer::install(ExecutionContext* context, PassOwnPtr<ScheduledAction> action, int timeout, bool singleShot)
{
int timeoutID = context->installNewTimeout(action, timeout, singleShot);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "TimerInstall", "data", InspectorTimerInstallEvent::data(context, timeoutID, timeout, singleShot));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didInstallTimer(context, timeoutID, timeout, singleShot);
return timeoutID;
}
@@ -77,6 +80,9 @@ int DOMTimer::install(ExecutionContext* context, PassOwnPtr<ScheduledAction> act
void DOMTimer::removeByID(ExecutionContext* context, int timeoutID)
{
context->removeTimeoutByID(timeoutID);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "TimerRemove", "data", InspectorTimerRemoveEvent::data(context, timeoutID));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didRemoveTimer(context, timeoutID);
}
@@ -90,13 +96,13 @@ DOMTimer::DOMTimer(ExecutionContext* context, PassOwnPtr<ScheduledAction> action
if (shouldForwardUserGesture(interval, m_nestingLevel))
m_userGestureToken = UserGestureIndicator::currentToken();
- double intervalMilliseconds = max(oneMillisecond, interval * oneMillisecond);
+ double intervalMilliseconds = std::max(oneMillisecond, interval * oneMillisecond);
if (intervalMilliseconds < minimumInterval && m_nestingLevel >= maxTimerNestingLevel)
intervalMilliseconds = minimumInterval;
if (singleShot)
- startOneShot(intervalMilliseconds);
+ startOneShot(intervalMilliseconds, FROM_HERE);
else
- startRepeating(intervalMilliseconds);
+ startRepeating(intervalMilliseconds, FROM_HERE);
}
DOMTimer::~DOMTimer()
@@ -116,6 +122,8 @@ void DOMTimer::fired()
// Only the first execution of a multi-shot timer should get an affirmative user gesture indicator.
UserGestureIndicator gestureIndicator(m_userGestureToken.release());
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "TimerFire", "data", InspectorTimerFireEvent::data(context, m_timeoutID));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireTimer(context, m_timeoutID);
// Simple case for non-one-shot timers.
@@ -143,6 +151,7 @@ void DOMTimer::fired()
action->execute(context);
InspectorInstrumentation::didFireTimer(cookie);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
timerNestingLevel = 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMTimer.h b/chromium/third_party/WebKit/Source/core/frame/DOMTimer.h
index 95c094b0605..19c22d22c78 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMTimer.h
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMTimer.h
@@ -38,7 +38,7 @@ namespace WebCore {
class ExecutionContext;
-class DOMTimer : public SuspendableTimer {
+class DOMTimer FINAL : public SuspendableTimer {
public:
// Creates a new timer owned by the ExecutionContext, starts it and returns its ID.
static int install(ExecutionContext*, PassOwnPtr<ScheduledAction>, int timeout, bool singleShot);
@@ -66,10 +66,10 @@ private:
}
DOMTimer(ExecutionContext*, PassOwnPtr<ScheduledAction>, int interval, bool singleShot, int timeoutID);
- virtual void fired();
+ virtual void fired() OVERRIDE;
// Retuns timer fire time rounded to the next multiple of timer alignment interval.
- virtual double alignedFireTime(double) const;
+ virtual double alignedFireTime(double) const OVERRIDE;
int m_timeoutID;
int m_nestingLevel;
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindow.cpp b/chromium/third_party/WebKit/Source/core/frame/DOMWindow.cpp
deleted file mode 100644
index bc36d37e3fe..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindow.cpp
+++ /dev/null
@@ -1,1890 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/DOMWindow.h"
-
-#include <algorithm>
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "bindings/v8/ScriptCallStackFactory.h"
-#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/SerializedScriptValue.h"
-#include "core/css/CSSComputedStyleDeclaration.h"
-#include "core/css/CSSRuleList.h"
-#include "core/css/DOMWindowCSS.h"
-#include "core/css/MediaQueryList.h"
-#include "core/css/MediaQueryMatcher.h"
-#include "core/css/StyleMedia.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/ContextFeatures.h"
-#include "core/dom/DOMImplementation.h"
-#include "core/dom/Document.h"
-#include "core/dom/Element.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/dom/ExecutionContext.h"
-#include "core/dom/RequestAnimationFrameCallback.h"
-#include "core/editing/Editor.h"
-#include "core/events/DOMWindowEventQueue.h"
-#include "core/events/EventListener.h"
-#include "core/events/HashChangeEvent.h"
-#include "core/events/MessageEvent.h"
-#include "core/events/PageTransitionEvent.h"
-#include "core/events/PopStateEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/BarProp.h"
-#include "core/frame/Console.h"
-#include "core/frame/DOMPoint.h"
-#include "core/frame/DOMWindowLifecycleNotifier.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/History.h"
-#include "core/frame/Location.h"
-#include "core/frame/Navigator.h"
-#include "core/frame/Screen.h"
-#include "core/frame/Settings.h"
-#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/inspector/ScriptCallStack.h"
-#include "core/loader/DocumentLoader.h"
-#include "core/loader/FrameLoadRequest.h"
-#include "core/loader/FrameLoader.h"
-#include "core/loader/FrameLoaderClient.h"
-#include "core/loader/SinkDocument.h"
-#include "core/loader/appcache/ApplicationCache.h"
-#include "core/page/BackForwardClient.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/page/CreateWindow.h"
-#include "core/page/EventHandler.h"
-#include "core/page/FrameTree.h"
-#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
-#include "core/page/PageGroup.h"
-#include "core/page/WindowFeatures.h"
-#include "core/page/WindowFocusAllowedIndicator.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/storage/Storage.h"
-#include "core/storage/StorageArea.h"
-#include "core/storage/StorageNamespace.h"
-#include "core/timing/Performance.h"
-#include "platform/PlatformScreen.h"
-#include "platform/UserGestureIndicator.h"
-#include "platform/geometry/FloatRect.h"
-#include "platform/graphics/media/MediaPlayer.h"
-#include "platform/weborigin/KURL.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "platform/weborigin/SecurityPolicy.h"
-#include "public/platform/Platform.h"
-#include "wtf/MainThread.h"
-#include "wtf/MathExtras.h"
-#include "wtf/text/WTFString.h"
-
-using std::min;
-using std::max;
-
-namespace WebCore {
-
-class PostMessageTimer : public TimerBase {
-public:
- PostMessageTimer(DOMWindow* window, PassRefPtr<SerializedScriptValue> message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin, PassRefPtr<ScriptCallStack> stackTrace)
- : m_window(window)
- , m_message(message)
- , m_origin(sourceOrigin)
- , m_source(source)
- , m_channels(channels)
- , m_targetOrigin(targetOrigin)
- , m_stackTrace(stackTrace)
- {
- }
-
- PassRefPtr<MessageEvent> event()
- {
- return MessageEvent::create(m_channels.release(), m_message, m_origin, String(), m_source);
-
- }
- SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
- ScriptCallStack* stackTrace() const { return m_stackTrace.get(); }
-
-private:
- virtual void fired()
- {
- m_window->postMessageTimerFired(adoptPtr(this));
- // This object is deleted now.
- }
-
- RefPtr<DOMWindow> m_window;
- RefPtr<SerializedScriptValue> m_message;
- String m_origin;
- RefPtr<DOMWindow> m_source;
- OwnPtr<MessagePortChannelArray> m_channels;
- RefPtr<SecurityOrigin> m_targetOrigin;
- RefPtr<ScriptCallStack> m_stackTrace;
-};
-
-static void disableSuddenTermination()
-{
- blink::Platform::current()->suddenTerminationChanged(false);
-}
-
-static void enableSuddenTermination()
-{
- blink::Platform::current()->suddenTerminationChanged(true);
-}
-
-typedef HashCountedSet<DOMWindow*> DOMWindowSet;
-
-static DOMWindowSet& windowsWithUnloadEventListeners()
-{
- DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithUnloadEventListeners, ());
- return windowsWithUnloadEventListeners;
-}
-
-static DOMWindowSet& windowsWithBeforeUnloadEventListeners()
-{
- DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithBeforeUnloadEventListeners, ());
- return windowsWithBeforeUnloadEventListeners;
-}
-
-static void addUnloadEventListener(DOMWindow* domWindow)
-{
- DOMWindowSet& set = windowsWithUnloadEventListeners();
- if (set.isEmpty())
- disableSuddenTermination();
- set.add(domWindow);
-}
-
-static void removeUnloadEventListener(DOMWindow* domWindow)
-{
- DOMWindowSet& set = windowsWithUnloadEventListeners();
- DOMWindowSet::iterator it = set.find(domWindow);
- if (it == set.end())
- return;
- set.remove(it);
- if (set.isEmpty())
- enableSuddenTermination();
-}
-
-static void removeAllUnloadEventListeners(DOMWindow* domWindow)
-{
- DOMWindowSet& set = windowsWithUnloadEventListeners();
- DOMWindowSet::iterator it = set.find(domWindow);
- if (it == set.end())
- return;
- set.removeAll(it);
- if (set.isEmpty())
- enableSuddenTermination();
-}
-
-static void addBeforeUnloadEventListener(DOMWindow* domWindow)
-{
- DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
- if (set.isEmpty())
- disableSuddenTermination();
- set.add(domWindow);
-}
-
-static void removeBeforeUnloadEventListener(DOMWindow* domWindow)
-{
- DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
- DOMWindowSet::iterator it = set.find(domWindow);
- if (it == set.end())
- return;
- set.remove(it);
- if (set.isEmpty())
- enableSuddenTermination();
-}
-
-static void removeAllBeforeUnloadEventListeners(DOMWindow* domWindow)
-{
- DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
- DOMWindowSet::iterator it = set.find(domWindow);
- if (it == set.end())
- return;
- set.removeAll(it);
- if (set.isEmpty())
- enableSuddenTermination();
-}
-
-static bool allowsBeforeUnloadListeners(DOMWindow* window)
-{
- ASSERT_ARG(window, window);
- Frame* frame = window->frame();
- if (!frame)
- return false;
- return frame->isMainFrame();
-}
-
-unsigned DOMWindow::pendingUnloadEventListeners() const
-{
- return windowsWithUnloadEventListeners().count(const_cast<DOMWindow*>(this));
-}
-
-// This function:
-// 1) Validates the pending changes are not changing any value to NaN; in that case keep original value.
-// 2) Constrains the window rect to the minimum window size and no bigger than the float rect's dimensions.
-// 3) Constrains the window rect to within the top and left boundaries of the available screen rect.
-// 4) Constrains the window rect to within the bottom and right boundaries of the available screen rect.
-// 5) Translate the window rect coordinates to be within the coordinate space of the screen.
-FloatRect DOMWindow::adjustWindowRect(Page* page, const FloatRect& pendingChanges)
-{
- ASSERT(page);
-
- FloatRect screen = screenAvailableRect(page->mainFrame()->view());
- FloatRect window = page->chrome().windowRect();
-
- // Make sure we're in a valid state before adjusting dimensions.
- ASSERT(std::isfinite(screen.x()));
- ASSERT(std::isfinite(screen.y()));
- ASSERT(std::isfinite(screen.width()));
- ASSERT(std::isfinite(screen.height()));
- ASSERT(std::isfinite(window.x()));
- ASSERT(std::isfinite(window.y()));
- ASSERT(std::isfinite(window.width()));
- ASSERT(std::isfinite(window.height()));
-
- // Update window values if new requested values are not NaN.
- if (!std::isnan(pendingChanges.x()))
- window.setX(pendingChanges.x());
- if (!std::isnan(pendingChanges.y()))
- window.setY(pendingChanges.y());
- if (!std::isnan(pendingChanges.width()))
- window.setWidth(pendingChanges.width());
- if (!std::isnan(pendingChanges.height()))
- window.setHeight(pendingChanges.height());
-
- FloatSize minimumSize = page->chrome().client().minimumWindowSize();
- // Let size 0 pass through, since that indicates default size, not minimum size.
- if (window.width())
- window.setWidth(min(max(minimumSize.width(), window.width()), screen.width()));
- if (window.height())
- window.setHeight(min(max(minimumSize.height(), window.height()), screen.height()));
-
- // Constrain the window position within the valid screen area.
- window.setX(max(screen.x(), min(window.x(), screen.maxX() - window.width())));
- window.setY(max(screen.y(), min(window.y(), screen.maxY() - window.height())));
-
- return window;
-}
-
-bool DOMWindow::allowPopUp(Frame* firstFrame)
-{
- ASSERT(firstFrame);
-
- if (UserGestureIndicator::processingUserGesture())
- return true;
-
- Settings* settings = firstFrame->settings();
- return settings && settings->javaScriptCanOpenWindowsAutomatically();
-}
-
-bool DOMWindow::allowPopUp()
-{
- return m_frame && allowPopUp(m_frame);
-}
-
-bool DOMWindow::canShowModalDialog(const Frame* frame)
-{
- if (!frame)
- return false;
- Page* page = frame->page();
- if (!page)
- return false;
- return page->chrome().canRunModal();
-}
-
-bool DOMWindow::canShowModalDialogNow(const Frame* frame)
-{
- if (!frame)
- return false;
- Page* page = frame->page();
- if (!page)
- return false;
- return page->chrome().canRunModalNow();
-}
-
-DOMWindow::DOMWindow(Frame* frame)
- : FrameDestructionObserver(frame)
- , m_shouldPrintWhenFinishedLoading(false)
-{
- ASSERT(frame);
- ScriptWrappable::init(this);
-}
-
-void DOMWindow::clearDocument()
-{
- if (!m_document)
- return;
-
- if (m_document->isActive()) {
- // FIXME: We don't call willRemove here. Why is that OK?
- // This detach() call is also mostly redundant. Most of the calls to
- // this function come via DocumentLoader::createWriterFor, which
- // always detaches the previous Document first. Only XSLTProcessor
- // depends on this detach() call, so it seems like there's some room
- // for cleanup.
- m_document->detach();
- }
-
- // FIXME: This should be part of ActiveDOM Object shutdown
- clearEventQueue();
-
- m_document->clearDOMWindow();
- m_document = 0;
-}
-
-void DOMWindow::clearEventQueue()
-{
- if (!m_eventQueue)
- return;
- m_eventQueue->close();
- m_eventQueue.clear();
-}
-
-PassRefPtr<Document> DOMWindow::createDocument(const String& mimeType, const DocumentInit& init, bool forceXHTML)
-{
- RefPtr<Document> document;
- if (forceXHTML) {
- // This is a hack for XSLTProcessor. See XSLTProcessor::createDocumentFromSource().
- document = Document::create(init);
- } else {
- document = DOMImplementation::createDocument(mimeType, init, init.frame() ? init.frame()->inViewSourceMode() : false);
- if (document->isPluginDocument() && document->isSandboxed(SandboxPlugins))
- document = SinkDocument::create(init);
- }
-
- return document.release();
-}
-
-PassRefPtr<Document> DOMWindow::installNewDocument(const String& mimeType, const DocumentInit& init, bool forceXHTML)
-{
- ASSERT(init.frame() == m_frame);
-
- clearDocument();
-
- m_document = createDocument(mimeType, init, forceXHTML);
- m_eventQueue = DOMWindowEventQueue::create(m_document.get());
- m_document->attach();
-
- if (!m_frame)
- return m_document;
-
- m_frame->script().updateDocument();
- m_document->updateViewportDescription();
-
- if (m_frame->page() && m_frame->view()) {
- if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator()) {
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_frame->view(), HorizontalScrollbar);
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_frame->view(), VerticalScrollbar);
- scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_frame->view());
- }
- }
-
- m_frame->selection().updateSecureKeyboardEntryIfActive();
-
- if (m_frame->isMainFrame()) {
- m_frame->page()->mainFrame()->notifyChromeClientWheelEventHandlerCountChanged();
- if (m_document->hasTouchEventHandlers())
- m_frame->page()->chrome().client().needTouchEvents(true);
- }
-
- return m_document;
-}
-
-EventQueue* DOMWindow::eventQueue() const
-{
- return m_eventQueue.get();
-}
-
-void DOMWindow::enqueueWindowEvent(PassRefPtr<Event> event)
-{
- if (!m_eventQueue)
- return;
- event->setTarget(this);
- m_eventQueue->enqueueEvent(event);
-}
-
-void DOMWindow::enqueueDocumentEvent(PassRefPtr<Event> event)
-{
- if (!m_eventQueue)
- return;
- event->setTarget(m_document);
- m_eventQueue->enqueueEvent(event);
-}
-
-void DOMWindow::dispatchWindowLoadEvent()
-{
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
- dispatchLoadEvent();
-}
-
-void DOMWindow::documentWasClosed()
-{
- dispatchWindowLoadEvent();
- enqueuePageshowEvent(PageshowEventNotPersisted);
- enqueuePopstateEvent(m_pendingStateObject ? m_pendingStateObject.release() : SerializedScriptValue::nullValue());
-}
-
-void DOMWindow::enqueuePageshowEvent(PageshowEventPersistence persisted)
-{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36334 Pageshow event needs to fire asynchronously.
- dispatchEvent(PageTransitionEvent::create(EventTypeNames::pageshow, persisted), m_document.get());
-}
-
-void DOMWindow::enqueueHashchangeEvent(const String& oldURL, const String& newURL)
-{
- enqueueWindowEvent(HashChangeEvent::create(oldURL, newURL));
-}
-
-void DOMWindow::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
-{
- if (!ContextFeatures::pushStateEnabled(document()))
- return;
-
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
- dispatchEvent(PopStateEvent::create(stateObject, history()));
-}
-
-void DOMWindow::statePopped(PassRefPtr<SerializedScriptValue> stateObject)
-{
- if (!frame())
- return;
-
- // Per step 11 of section 6.5.9 (history traversal) of the HTML5 spec, we
- // defer firing of popstate until we're in the complete state.
- if (document()->isLoadCompleted())
- enqueuePopstateEvent(stateObject);
- else
- m_pendingStateObject = stateObject;
-}
-
-DOMWindow::~DOMWindow()
-{
- ASSERT(!m_screen);
- ASSERT(!m_history);
- ASSERT(!m_locationbar);
- ASSERT(!m_menubar);
- ASSERT(!m_personalbar);
- ASSERT(!m_scrollbars);
- ASSERT(!m_statusbar);
- ASSERT(!m_toolbar);
- ASSERT(!m_console);
- ASSERT(!m_navigator);
- ASSERT(!m_performance);
- ASSERT(!m_location);
- ASSERT(!m_media);
- ASSERT(!m_sessionStorage);
- ASSERT(!m_localStorage);
- ASSERT(!m_applicationCache);
-
- reset();
-
- removeAllEventListeners();
-
- ASSERT(m_document->isStopped());
- clearDocument();
-}
-
-const AtomicString& DOMWindow::interfaceName() const
-{
- return EventTargetNames::DOMWindow;
-}
-
-ExecutionContext* DOMWindow::executionContext() const
-{
- return m_document.get();
-}
-
-DOMWindow* DOMWindow::toDOMWindow()
-{
- return this;
-}
-
-PassRefPtr<MediaQueryList> DOMWindow::matchMedia(const String& media)
-{
- return document() ? document()->mediaQueryMatcher().matchMedia(media) : 0;
-}
-
-Page* DOMWindow::page()
-{
- return frame() ? frame()->page() : 0;
-}
-
-void DOMWindow::frameDestroyed()
-{
- FrameDestructionObserver::frameDestroyed();
- reset();
-}
-
-void DOMWindow::willDetachPage()
-{
- InspectorInstrumentation::frameWindowDiscarded(m_frame, this);
-}
-
-void DOMWindow::willDestroyDocumentInFrame()
-{
- // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
- // unregister themselves from the DOMWindow as a result of the call to willDestroyGlobalObjectInFrame.
- Vector<DOMWindowProperty*> properties;
- copyToVector(m_properties, properties);
- for (size_t i = 0; i < properties.size(); ++i)
- properties[i]->willDestroyGlobalObjectInFrame();
-}
-
-void DOMWindow::willDetachDocumentFromFrame()
-{
- // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
- // unregister themselves from the DOMWindow as a result of the call to willDetachGlobalObjectFromFrame.
- Vector<DOMWindowProperty*> properties;
- copyToVector(m_properties, properties);
- for (size_t i = 0; i < properties.size(); ++i)
- properties[i]->willDetachGlobalObjectFromFrame();
-}
-
-void DOMWindow::registerProperty(DOMWindowProperty* property)
-{
- m_properties.add(property);
-}
-
-void DOMWindow::unregisterProperty(DOMWindowProperty* property)
-{
- m_properties.remove(property);
-}
-
-void DOMWindow::reset()
-{
- willDestroyDocumentInFrame();
- resetDOMWindowProperties();
-}
-
-void DOMWindow::resetDOMWindowProperties()
-{
- m_properties.clear();
-
- m_screen = 0;
- m_history = 0;
- m_locationbar = 0;
- m_menubar = 0;
- m_personalbar = 0;
- m_scrollbars = 0;
- m_statusbar = 0;
- m_toolbar = 0;
- m_console = 0;
- m_navigator = 0;
- m_performance = 0;
- m_location = 0;
- m_media = 0;
- m_sessionStorage = 0;
- m_localStorage = 0;
- m_applicationCache = 0;
-}
-
-bool DOMWindow::isCurrentlyDisplayedInFrame() const
-{
- return m_frame && m_frame->domWindow() == this;
-}
-
-#if ENABLE(ORIENTATION_EVENTS)
-int DOMWindow::orientation() const
-{
- if (!m_frame)
- return 0;
-
- return m_frame->orientation();
-}
-#endif
-
-Screen* DOMWindow::screen() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_screen)
- m_screen = Screen::create(m_frame);
- return m_screen.get();
-}
-
-History* DOMWindow::history() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_history)
- m_history = History::create(m_frame);
- return m_history.get();
-}
-
-BarProp* DOMWindow::locationbar() const
-{
- UseCounter::count(this, UseCounter::BarPropLocationbar);
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_locationbar)
- m_locationbar = BarProp::create(m_frame, BarProp::Locationbar);
- return m_locationbar.get();
-}
-
-BarProp* DOMWindow::menubar() const
-{
- UseCounter::count(this, UseCounter::BarPropMenubar);
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_menubar)
- m_menubar = BarProp::create(m_frame, BarProp::Menubar);
- return m_menubar.get();
-}
-
-BarProp* DOMWindow::personalbar() const
-{
- UseCounter::count(this, UseCounter::BarPropPersonalbar);
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_personalbar)
- m_personalbar = BarProp::create(m_frame, BarProp::Personalbar);
- return m_personalbar.get();
-}
-
-BarProp* DOMWindow::scrollbars() const
-{
- UseCounter::count(this, UseCounter::BarPropScrollbars);
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_scrollbars)
- m_scrollbars = BarProp::create(m_frame, BarProp::Scrollbars);
- return m_scrollbars.get();
-}
-
-BarProp* DOMWindow::statusbar() const
-{
- UseCounter::count(this, UseCounter::BarPropStatusbar);
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_statusbar)
- m_statusbar = BarProp::create(m_frame, BarProp::Statusbar);
- return m_statusbar.get();
-}
-
-BarProp* DOMWindow::toolbar() const
-{
- UseCounter::count(this, UseCounter::BarPropToolbar);
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_toolbar)
- m_toolbar = BarProp::create(m_frame, BarProp::Toolbar);
- return m_toolbar.get();
-}
-
-Console* DOMWindow::console() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_console)
- m_console = Console::create(m_frame);
- return m_console.get();
-}
-
-PageConsole* DOMWindow::pageConsole() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- return m_frame->page() ? &m_frame->page()->console() : 0;
-}
-
-ApplicationCache* DOMWindow::applicationCache() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_applicationCache)
- m_applicationCache = ApplicationCache::create(m_frame);
- return m_applicationCache.get();
-}
-
-Navigator* DOMWindow::navigator() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_navigator)
- m_navigator = Navigator::create(m_frame);
- return m_navigator.get();
-}
-
-Performance* DOMWindow::performance() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_performance)
- m_performance = Performance::create(m_frame);
- return m_performance.get();
-}
-
-Location* DOMWindow::location() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_location)
- m_location = Location::create(m_frame);
- return m_location.get();
-}
-
-Storage* DOMWindow::sessionStorage(ExceptionState& exceptionState) const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
-
- Document* document = this->document();
- if (!document)
- return 0;
-
- String accessDeniedMessage = "Access is denied for this document.";
- if (!document->securityOrigin()->canAccessLocalStorage()) {
- if (document->isSandboxed(SandboxOrigin))
- exceptionState.throwSecurityError("The document is sandboxed and lacks the 'allow-same-origin' flag.");
- else if (document->url().protocolIs("data"))
- exceptionState.throwSecurityError("Storage is disabled inside 'data:' URLs.");
- else
- exceptionState.throwSecurityError(accessDeniedMessage);
- return 0;
- }
-
- if (m_sessionStorage) {
- if (!m_sessionStorage->area()->canAccessStorage(m_frame)) {
- exceptionState.throwSecurityError(accessDeniedMessage);
- return 0;
- }
- return m_sessionStorage.get();
- }
-
- Page* page = document->page();
- if (!page)
- return 0;
-
- OwnPtr<StorageArea> storageArea = page->sessionStorage()->storageArea(document->securityOrigin());
- if (!storageArea->canAccessStorage(m_frame)) {
- exceptionState.throwSecurityError(accessDeniedMessage);
- return 0;
- }
-
- m_sessionStorage = Storage::create(m_frame, storageArea.release());
- return m_sessionStorage.get();
-}
-
-Storage* DOMWindow::localStorage(ExceptionState& exceptionState) const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
-
- Document* document = this->document();
- if (!document)
- return 0;
-
- String accessDeniedMessage = "Access is denied for this document.";
- if (!document->securityOrigin()->canAccessLocalStorage()) {
- if (document->isSandboxed(SandboxOrigin))
- exceptionState.throwSecurityError("The document is sandboxed and lacks the 'allow-same-origin' flag.");
- else if (document->url().protocolIs("data"))
- exceptionState.throwSecurityError("Storage is disabled inside 'data:' URLs.");
- else
- exceptionState.throwSecurityError(accessDeniedMessage);
- return 0;
- }
-
- if (m_localStorage) {
- if (!m_localStorage->area()->canAccessStorage(m_frame)) {
- exceptionState.throwSecurityError(accessDeniedMessage);
- return 0;
- }
- return m_localStorage.get();
- }
-
- Page* page = document->page();
- if (!page)
- return 0;
-
- if (!page->settings().localStorageEnabled())
- return 0;
-
- OwnPtr<StorageArea> storageArea = StorageNamespace::localStorageArea(document->securityOrigin());
- if (!storageArea->canAccessStorage(m_frame)) {
- exceptionState.throwSecurityError(accessDeniedMessage);
- return 0;
- }
-
- m_localStorage = Storage::create(m_frame, storageArea.release());
- return m_localStorage.get();
-}
-
-void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, const String& targetOrigin, DOMWindow* source, ExceptionState& exceptionState)
-{
- if (!isCurrentlyDisplayedInFrame())
- return;
-
- Document* sourceDocument = source->document();
-
- // Compute the target origin. We need to do this synchronously in order
- // to generate the SyntaxError exception correctly.
- RefPtr<SecurityOrigin> target;
- if (targetOrigin == "/") {
- if (!sourceDocument)
- return;
- target = sourceDocument->securityOrigin();
- } else if (targetOrigin != "*") {
- target = SecurityOrigin::createFromString(targetOrigin);
- // It doesn't make sense target a postMessage at a unique origin
- // because there's no way to represent a unique origin in a string.
- if (target->isUnique()) {
- exceptionState.throwDOMException(SyntaxError, "Invalid target origin '" + targetOrigin + "' in a call to 'postMessage'.");
- return;
- }
- }
-
- OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, exceptionState);
- if (exceptionState.hadException())
- return;
-
- // Capture the source of the message. We need to do this synchronously
- // in order to capture the source of the message correctly.
- if (!sourceDocument)
- return;
- String sourceOrigin = sourceDocument->securityOrigin()->toString();
-
- // Capture stack trace only when inspector front-end is loaded as it may be time consuming.
- RefPtr<ScriptCallStack> stackTrace;
- if (InspectorInstrumentation::consoleAgentEnabled(sourceDocument))
- stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
-
- // Schedule the message.
- PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, source, channels.release(), target.get(), stackTrace.release());
- timer->startOneShot(0);
-}
-
-void DOMWindow::postMessageTimerFired(PassOwnPtr<PostMessageTimer> t)
-{
- OwnPtr<PostMessageTimer> timer(t);
-
- if (!document() || !isCurrentlyDisplayedInFrame())
- return;
-
- RefPtr<MessageEvent> event = timer->event();
-
- // Give the embedder a chance to intercept this postMessage because this
- // DOMWindow might be a proxy for another in browsers that support
- // postMessage calls across WebKit instances.
- if (m_frame->loader().client()->willCheckAndDispatchMessageEvent(timer->targetOrigin(), event.get()))
- return;
-
- event->entangleMessagePorts(document());
- dispatchMessageEventWithOriginCheck(timer->targetOrigin(), event, timer->stackTrace());
-}
-
-void DOMWindow::dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, PassRefPtr<Event> event, PassRefPtr<ScriptCallStack> stackTrace)
-{
- if (intendedTargetOrigin) {
- // Check target origin now since the target document may have changed since the timer was scheduled.
- if (!intendedTargetOrigin->isSameSchemeHostPort(document()->securityOrigin())) {
- String message = ExceptionMessages::failedToExecute("postMessage", "DOMWindow", "The target origin provided ('" + intendedTargetOrigin->toString() + "') does not match the recipient window's origin ('" + document()->securityOrigin()->toString() + "').");
- pageConsole()->addMessage(SecurityMessageSource, ErrorMessageLevel, message, stackTrace);
- return;
- }
- }
-
- dispatchEvent(event);
-}
-
-DOMSelection* DOMWindow::getSelection()
-{
- if (!isCurrentlyDisplayedInFrame() || !m_frame)
- return 0;
-
- return m_frame->document()->getSelection();
-}
-
-Element* DOMWindow::frameElement() const
-{
- if (!m_frame)
- return 0;
-
- return m_frame->ownerElement();
-}
-
-void DOMWindow::focus(ExecutionContext* context)
-{
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- bool allowFocus = WindowFocusAllowedIndicator::windowFocusAllowed();
- if (context) {
- ASSERT(isMainThread());
- Document* activeDocument = toDocument(context);
- if (opener() && opener() != this && activeDocument->domWindow() == opener())
- allowFocus = true;
- }
-
- // If we're a top level window, bring the window to the front.
- if (m_frame->isMainFrame() && allowFocus)
- page->chrome().focus();
-
- if (!m_frame)
- return;
-
- m_frame->eventHandler().focusDocumentView();
-}
-
-void DOMWindow::blur()
-{
-}
-
-void DOMWindow::close(ExecutionContext* context)
-{
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- if (m_frame != page->mainFrame())
- return;
-
- if (context) {
- ASSERT(isMainThread());
- Document* activeDocument = toDocument(context);
- if (!activeDocument)
- return;
-
- if (!activeDocument->canNavigate(m_frame))
- return;
- }
-
- Settings* settings = m_frame->settings();
- bool allowScriptsToCloseWindows = settings && settings->allowScriptsToCloseWindows();
-
- if (!(page->openedByDOM() || page->backForward().backForwardListCount() <= 1 || allowScriptsToCloseWindows)) {
- pageConsole()->addMessage(JSMessageSource, WarningMessageLevel, "Scripts may close only the windows that were opened by it.");
- return;
- }
-
- if (!m_frame->loader().shouldClose())
- return;
-
- page->chrome().closeWindowSoon();
-}
-
-void DOMWindow::print()
-{
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- if (m_frame->loader().activeDocumentLoader()->isLoading()) {
- m_shouldPrintWhenFinishedLoading = true;
- return;
- }
- m_shouldPrintWhenFinishedLoading = false;
- page->chrome().print(m_frame);
-}
-
-void DOMWindow::stop()
-{
- if (!m_frame)
- return;
- m_frame->loader().stopAllLoaders();
-}
-
-void DOMWindow::alert(const String& message)
-{
- if (!m_frame)
- return;
-
- m_frame->document()->updateStyleIfNeeded();
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- page->chrome().runJavaScriptAlert(m_frame, message);
-}
-
-bool DOMWindow::confirm(const String& message)
-{
- if (!m_frame)
- return false;
-
- m_frame->document()->updateStyleIfNeeded();
-
- Page* page = m_frame->page();
- if (!page)
- return false;
-
- return page->chrome().runJavaScriptConfirm(m_frame, message);
-}
-
-String DOMWindow::prompt(const String& message, const String& defaultValue)
-{
- if (!m_frame)
- return String();
-
- m_frame->document()->updateStyleIfNeeded();
-
- Page* page = m_frame->page();
- if (!page)
- return String();
-
- String returnValue;
- if (page->chrome().runJavaScriptPrompt(m_frame, message, defaultValue, returnValue))
- return returnValue;
-
- return String();
-}
-
-bool DOMWindow::find(const String& string, bool caseSensitive, bool backwards, bool wrap, bool /*wholeWord*/, bool /*searchInFrames*/, bool /*showDialog*/) const
-{
- if (!isCurrentlyDisplayedInFrame())
- return false;
-
- // |m_frame| can be destructed during |Editor::findString()| via
- // |Document::updateLayou()|, e.g. event handler removes a frame.
- RefPtr<Frame> protectFrame(m_frame);
-
- // FIXME (13016): Support wholeWord, searchInFrames and showDialog
- return m_frame->editor().findString(string, !backwards, caseSensitive, wrap, false);
-}
-
-bool DOMWindow::offscreenBuffering() const
-{
- return true;
-}
-
-int DOMWindow::outerHeight() const
-{
- if (!m_frame)
- return 0;
-
- Page* page = m_frame->page();
- if (!page)
- return 0;
-
- if (page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(page->chrome().windowRect().height() * page->deviceScaleFactor());
- return static_cast<int>(page->chrome().windowRect().height());
-}
-
-int DOMWindow::outerWidth() const
-{
- if (!m_frame)
- return 0;
-
- Page* page = m_frame->page();
- if (!page)
- return 0;
-
- if (page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(page->chrome().windowRect().width() * page->deviceScaleFactor());
- return static_cast<int>(page->chrome().windowRect().width());
-}
-
-int DOMWindow::innerHeight() const
-{
- if (!m_frame)
- return 0;
-
- FrameView* view = m_frame->view();
- if (!view)
- return 0;
-
- // FIXME: This is potentially too much work. We really only need to know the dimensions of the parent frame's renderer.
- if (Frame* parent = m_frame->tree().parent())
- parent->document()->updateLayoutIgnorePendingStylesheets();
-
- return adjustForAbsoluteZoom(view->visibleContentRect(ScrollableArea::IncludeScrollbars).height(), m_frame->pageZoomFactor());
-}
-
-int DOMWindow::innerWidth() const
-{
- if (!m_frame)
- return 0;
-
- FrameView* view = m_frame->view();
- if (!view)
- return 0;
-
- // FIXME: This is potentially too much work. We really only need to know the dimensions of the parent frame's renderer.
- if (Frame* parent = m_frame->tree().parent())
- parent->document()->updateLayoutIgnorePendingStylesheets();
-
- return adjustForAbsoluteZoom(view->visibleContentRect(ScrollableArea::IncludeScrollbars).width(), m_frame->pageZoomFactor());
-}
-
-int DOMWindow::screenX() const
-{
- if (!m_frame)
- return 0;
-
- Page* page = m_frame->page();
- if (!page)
- return 0;
-
- if (page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(page->chrome().windowRect().x() * page->deviceScaleFactor());
- return static_cast<int>(page->chrome().windowRect().x());
-}
-
-int DOMWindow::screenY() const
-{
- if (!m_frame)
- return 0;
-
- Page* page = m_frame->page();
- if (!page)
- return 0;
-
- if (page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(page->chrome().windowRect().y() * page->deviceScaleFactor());
- return static_cast<int>(page->chrome().windowRect().y());
-}
-
-int DOMWindow::scrollX() const
-{
- if (!m_frame)
- return 0;
-
- FrameView* view = m_frame->view();
- if (!view)
- return 0;
-
- m_frame->document()->updateLayoutIgnorePendingStylesheets();
-
- return adjustForAbsoluteZoom(view->scrollX(), m_frame->pageZoomFactor());
-}
-
-int DOMWindow::scrollY() const
-{
- if (!m_frame)
- return 0;
-
- FrameView* view = m_frame->view();
- if (!view)
- return 0;
-
- m_frame->document()->updateLayoutIgnorePendingStylesheets();
-
- return adjustForAbsoluteZoom(view->scrollY(), m_frame->pageZoomFactor());
-}
-
-bool DOMWindow::closed() const
-{
- return !m_frame;
-}
-
-unsigned DOMWindow::length() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
-
- return m_frame->tree().scopedChildCount();
-}
-
-const AtomicString& DOMWindow::name() const
-{
- if (!m_frame)
- return nullAtom;
-
- return m_frame->tree().name();
-}
-
-void DOMWindow::setName(const AtomicString& name)
-{
- if (!m_frame)
- return;
-
- m_frame->tree().setName(name);
- m_frame->loader().client()->didChangeName(name);
-}
-
-void DOMWindow::setStatus(const String& string)
-{
- m_status = string;
-
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- ASSERT(m_frame->document()); // Client calls shouldn't be made when the frame is in inconsistent state.
- page->chrome().setStatusbarText(m_frame, m_status);
-}
-
-void DOMWindow::setDefaultStatus(const String& string)
-{
- m_defaultStatus = string;
-
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- ASSERT(m_frame->document()); // Client calls shouldn't be made when the frame is in inconsistent state.
- page->chrome().setStatusbarText(m_frame, m_defaultStatus);
-}
-
-DOMWindow* DOMWindow::self() const
-{
- if (!m_frame)
- return 0;
-
- return m_frame->domWindow();
-}
-
-DOMWindow* DOMWindow::opener() const
-{
- if (!m_frame)
- return 0;
-
- Frame* opener = m_frame->loader().opener();
- if (!opener)
- return 0;
-
- return opener->domWindow();
-}
-
-DOMWindow* DOMWindow::parent() const
-{
- if (!m_frame)
- return 0;
-
- Frame* parent = m_frame->tree().parent();
- if (parent)
- return parent->domWindow();
-
- return m_frame->domWindow();
-}
-
-DOMWindow* DOMWindow::top() const
-{
- if (!m_frame)
- return 0;
-
- Page* page = m_frame->page();
- if (!page)
- return 0;
-
- return m_frame->tree().top()->domWindow();
-}
-
-Document* DOMWindow::document() const
-{
- return m_document.get();
-}
-
-PassRefPtr<StyleMedia> DOMWindow::styleMedia() const
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- if (!m_media)
- m_media = StyleMedia::create(m_frame);
- return m_media.get();
-}
-
-PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const String& pseudoElt) const
-{
- if (!elt)
- return 0;
-
- return CSSComputedStyleDeclaration::create(elt, false, pseudoElt);
-}
-
-PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* element, const String& pseudoElement, bool authorOnly) const
-{
- UseCounter::count(this, UseCounter::GetMatchedCSSRules);
- if (!element)
- return 0;
-
- if (!isCurrentlyDisplayedInFrame())
- return 0;
-
- unsigned colonStart = pseudoElement[0] == ':' ? (pseudoElement[1] == ':' ? 2 : 1) : 0;
- CSSSelector::PseudoType pseudoType = CSSSelector::parsePseudoType(AtomicString(pseudoElement.substring(colonStart)));
- if (pseudoType == CSSSelector::PseudoUnknown && !pseudoElement.isEmpty())
- return 0;
-
- unsigned rulesToInclude = StyleResolver::AuthorCSSRules;
- if (!authorOnly)
- rulesToInclude |= StyleResolver::UAAndUserCSSRules;
-
- PseudoId pseudoId = CSSSelector::pseudoId(pseudoType);
-
- return m_frame->document()->ensureStyleResolver().pseudoCSSRulesForElement(element, pseudoId, rulesToInclude);
-}
-
-PassRefPtr<DOMPoint> DOMWindow::webkitConvertPointFromNodeToPage(Node* node, const DOMPoint* p) const
-{
- if (!node || !p)
- return 0;
-
- if (!document())
- return 0;
-
- document()->updateLayoutIgnorePendingStylesheets();
-
- FloatPoint pagePoint(p->x(), p->y());
- pagePoint = node->convertToPage(pagePoint);
- return DOMPoint::create(pagePoint.x(), pagePoint.y());
-}
-
-PassRefPtr<DOMPoint> DOMWindow::webkitConvertPointFromPageToNode(Node* node, const DOMPoint* p) const
-{
- if (!node || !p)
- return 0;
-
- if (!document())
- return 0;
-
- document()->updateLayoutIgnorePendingStylesheets();
-
- FloatPoint nodePoint(p->x(), p->y());
- nodePoint = node->convertFromPage(nodePoint);
- return DOMPoint::create(nodePoint.x(), nodePoint.y());
-}
-
-double DOMWindow::devicePixelRatio() const
-{
- if (!m_frame)
- return 0.0;
-
- return m_frame->devicePixelRatio();
-}
-
-void DOMWindow::scrollBy(int x, int y) const
-{
- if (!isCurrentlyDisplayedInFrame())
- return;
-
- document()->updateLayoutIgnorePendingStylesheets();
-
- FrameView* view = m_frame->view();
- if (!view)
- return;
-
-
- IntSize scaledOffset(x * m_frame->pageZoomFactor(), y * m_frame->pageZoomFactor());
- view->scrollBy(scaledOffset);
-}
-
-void DOMWindow::scrollTo(int x, int y) const
-{
- if (!isCurrentlyDisplayedInFrame())
- return;
-
- document()->updateLayoutIgnorePendingStylesheets();
-
- RefPtr<FrameView> view = m_frame->view();
- if (!view)
- return;
-
- IntPoint layoutPos(x * m_frame->pageZoomFactor(), y * m_frame->pageZoomFactor());
- view->setScrollPosition(layoutPos);
-}
-
-void DOMWindow::moveBy(float x, float y) const
-{
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- if (m_frame != page->mainFrame())
- return;
-
- FloatRect fr = page->chrome().windowRect();
- FloatRect update = fr;
- update.move(x, y);
- // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
- page->chrome().setWindowRect(adjustWindowRect(page, update));
-}
-
-void DOMWindow::moveTo(float x, float y) const
-{
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- if (m_frame != page->mainFrame())
- return;
-
- FloatRect update = page->chrome().windowRect();
- update.setLocation(FloatPoint(x, y));
- // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
- page->chrome().setWindowRect(adjustWindowRect(page, update));
-}
-
-void DOMWindow::resizeBy(float x, float y) const
-{
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- if (m_frame != page->mainFrame())
- return;
-
- FloatRect fr = page->chrome().windowRect();
- FloatSize dest = fr.size() + FloatSize(x, y);
- FloatRect update(fr.location(), dest);
- page->chrome().setWindowRect(adjustWindowRect(page, update));
-}
-
-void DOMWindow::resizeTo(float width, float height) const
-{
- if (!m_frame)
- return;
-
- Page* page = m_frame->page();
- if (!page)
- return;
-
- if (m_frame != page->mainFrame())
- return;
-
- FloatRect fr = page->chrome().windowRect();
- FloatSize dest = FloatSize(width, height);
- FloatRect update(fr.location(), dest);
- page->chrome().setWindowRect(adjustWindowRect(page, update));
-}
-
-int DOMWindow::requestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback> callback)
-{
- callback->m_useLegacyTimeBase = false;
- if (Document* d = document())
- return d->requestAnimationFrame(callback);
- return 0;
-}
-
-int DOMWindow::webkitRequestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback> callback)
-{
- callback->m_useLegacyTimeBase = true;
- if (Document* d = document())
- return d->requestAnimationFrame(callback);
- return 0;
-}
-
-void DOMWindow::cancelAnimationFrame(int id)
-{
- if (Document* d = document())
- d->cancelAnimationFrame(id);
-}
-
-DOMWindowCSS* DOMWindow::css()
-{
- if (!m_css)
- m_css = DOMWindowCSS::create();
- return m_css.get();
-}
-
-static void didAddStorageEventListener(DOMWindow* window)
-{
- // Creating these WebCore::Storage objects informs the system that we'd like to receive
- // notifications about storage events that might be triggered in other processes. Rather
- // than subscribe to these notifications explicitly, we subscribe to them implicitly to
- // simplify the work done by the system.
- window->localStorage(IGNORE_EXCEPTION);
- window->sessionStorage(IGNORE_EXCEPTION);
-}
-
-bool DOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
- if (!EventTarget::addEventListener(eventType, listener, useCapture))
- return false;
-
- if (Document* document = this->document()) {
- document->addListenerTypeIfNeeded(eventType);
- if (isTouchEventType(eventType))
- document->didAddTouchEventHandler(document);
- else if (eventType == EventTypeNames::storage)
- didAddStorageEventListener(this);
- }
-
- lifecycleNotifier().notifyAddEventListener(this, eventType);
-
- if (eventType == EventTypeNames::unload) {
- UseCounter::count(this, UseCounter::DocumentUnloadRegistered);
- addUnloadEventListener(this);
- } else if (eventType == EventTypeNames::beforeunload) {
- UseCounter::count(this, UseCounter::DocumentBeforeUnloadRegistered);
- if (allowsBeforeUnloadListeners(this)) {
- // This is confusingly named. It doesn't actually add the listener. It just increments a count
- // so that we know we have listeners registered for the purposes of determining if we can
- // fast terminate the renderer process.
- addBeforeUnloadEventListener(this);
- } else {
- // Subframes return false from allowsBeforeUnloadListeners.
- UseCounter::count(this, UseCounter::SubFrameBeforeUnloadRegistered);
- }
- }
-
- return true;
-}
-
-bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
-{
- if (!EventTarget::removeEventListener(eventType, listener, useCapture))
- return false;
-
- if (Document* document = this->document()) {
- if (isTouchEventType(eventType))
- document->didRemoveTouchEventHandler(document);
- }
-
- lifecycleNotifier().notifyRemoveEventListener(this, eventType);
-
- if (eventType == EventTypeNames::unload) {
- removeUnloadEventListener(this);
- } else if (eventType == EventTypeNames::beforeunload && allowsBeforeUnloadListeners(this)) {
- removeBeforeUnloadEventListener(this);
- }
-
- return true;
-}
-
-void DOMWindow::dispatchLoadEvent()
-{
- RefPtr<Event> loadEvent(Event::create(EventTypeNames::load));
- if (m_frame && m_frame->loader().documentLoader() && !m_frame->loader().documentLoader()->timing()->loadEventStart()) {
- // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed while dispatching
- // the event, so protect it to prevent writing the end time into freed memory.
- RefPtr<DocumentLoader> documentLoader = m_frame->loader().documentLoader();
- DocumentLoadTiming* timing = documentLoader->timing();
- timing->markLoadEventStart();
- dispatchEvent(loadEvent, document());
- timing->markLoadEventEnd();
- } else
- dispatchEvent(loadEvent, document());
-
- // For load events, send a separate load event to the enclosing frame only.
- // This is a DOM extension and is independent of bubbling/capturing rules of
- // the DOM.
- Element* ownerElement = m_frame ? m_frame->ownerElement() : 0;
- if (ownerElement)
- ownerElement->dispatchEvent(Event::create(EventTypeNames::load));
-
- InspectorInstrumentation::loadEventFired(frame());
-}
-
-bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget)
-{
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- RefPtr<EventTarget> protect = this;
- RefPtr<Event> event = prpEvent;
-
- event->setTarget(prpTarget ? prpTarget : this);
- event->setCurrentTarget(this);
- event->setEventPhase(Event::AT_TARGET);
-
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEventOnWindow(frame(), *event, this);
-
- bool result = fireEventListeners(event.get());
-
- InspectorInstrumentation::didDispatchEventOnWindow(cookie);
-
- return result;
-}
-
-void DOMWindow::removeAllEventListeners()
-{
- EventTarget::removeAllEventListeners();
-
- lifecycleNotifier().notifyRemoveAllEventListeners(this);
-
- if (Document* document = this->document())
- document->didRemoveEventTargetNode(document);
-
- removeAllUnloadEventListeners(this);
- removeAllBeforeUnloadEventListeners(this);
-}
-
-void DOMWindow::finishedLoading()
-{
- if (m_shouldPrintWhenFinishedLoading) {
- m_shouldPrintWhenFinishedLoading = false;
- print();
- }
-}
-
-void DOMWindow::setLocation(const String& urlString, DOMWindow* activeWindow, DOMWindow* firstWindow, SetLocationLocking locking)
-{
- if (!isCurrentlyDisplayedInFrame())
- return;
-
- Document* activeDocument = activeWindow->document();
- if (!activeDocument)
- return;
-
- if (!activeDocument->canNavigate(m_frame))
- return;
-
- Frame* firstFrame = firstWindow->frame();
- if (!firstFrame)
- return;
-
- KURL completedURL = firstFrame->document()->completeURL(urlString);
- if (completedURL.isNull())
- return;
-
- if (isInsecureScriptAccess(activeWindow, completedURL))
- return;
-
- // We want a new history item if we are processing a user gesture.
- m_frame->navigationScheduler().scheduleLocationChange(activeDocument,
- // FIXME: What if activeDocument()->frame() is 0?
- completedURL, activeDocument->outgoingReferrer(),
- locking != LockHistoryBasedOnGestureState);
-}
-
-void DOMWindow::printErrorMessage(const String& message)
-{
- if (message.isEmpty())
- return;
-
- pageConsole()->addMessage(JSMessageSource, ErrorMessageLevel, message);
-}
-
-// FIXME: Once we're throwing exceptions for cross-origin access violations, we will always sanitize the target
-// frame details, so we can safely combine 'crossDomainAccessErrorMessage' with this method after considering
-// exactly which details may be exposed to JavaScript.
-//
-// http://crbug.com/17325
-String DOMWindow::sanitizedCrossDomainAccessErrorMessage(DOMWindow* activeWindow)
-{
- if (!activeWindow || !activeWindow->document())
- return String();
-
- const KURL& activeWindowURL = activeWindow->document()->url();
- if (activeWindowURL.isNull())
- return String();
-
- ASSERT(!activeWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()));
-
- SecurityOrigin* activeOrigin = activeWindow->document()->securityOrigin();
- String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a cross-origin frame.";
-
- // FIXME: Evaluate which details from 'crossDomainAccessErrorMessage' may safely be reported to JavaScript.
-
- return message;
-}
-
-String DOMWindow::crossDomainAccessErrorMessage(DOMWindow* activeWindow)
-{
- if (!activeWindow || !activeWindow->document())
- return String();
-
- const KURL& activeWindowURL = activeWindow->document()->url();
- if (activeWindowURL.isNull())
- return String();
-
- ASSERT(!activeWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()));
-
- // FIXME: This message, and other console messages, have extra newlines. Should remove them.
- SecurityOrigin* activeOrigin = activeWindow->document()->securityOrigin();
- SecurityOrigin* targetOrigin = document()->securityOrigin();
- String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a frame with origin \"" + targetOrigin->toString() + "\". ";
-
- // Sandbox errors: Use the origin of the frames' location, rather than their actual origin (since we know that at least one will be "null").
- KURL activeURL = activeWindow->document()->url();
- KURL targetURL = document()->url();
- if (document()->isSandboxed(SandboxOrigin) || activeWindow->document()->isSandboxed(SandboxOrigin)) {
- message = "Blocked a frame at \"" + SecurityOrigin::create(activeURL)->toString() + "\" from accessing a frame at \"" + SecurityOrigin::create(targetURL)->toString() + "\". ";
- if (document()->isSandboxed(SandboxOrigin) && activeWindow->document()->isSandboxed(SandboxOrigin))
- return "Sandbox access violation: " + message + " Both frames are sandboxed and lack the \"allow-same-origin\" flag.";
- if (document()->isSandboxed(SandboxOrigin))
- return "Sandbox access violation: " + message + " The frame being accessed is sandboxed and lacks the \"allow-same-origin\" flag.";
- return "Sandbox access violation: " + message + " The frame requesting access is sandboxed and lacks the \"allow-same-origin\" flag.";
- }
-
- // Protocol errors: Use the URL's protocol rather than the origin's protocol so that we get a useful message for non-heirarchal URLs like 'data:'.
- if (targetOrigin->protocol() != activeOrigin->protocol())
- return message + " The frame requesting access has a protocol of \"" + activeURL.protocol() + "\", the frame being accessed has a protocol of \"" + targetURL.protocol() + "\". Protocols must match.\n";
-
- // 'document.domain' errors.
- if (targetOrigin->domainWasSetInDOM() && activeOrigin->domainWasSetInDOM())
- return message + "The frame requesting access set \"document.domain\" to \"" + activeOrigin->domain() + "\", the frame being accessed set it to \"" + targetOrigin->domain() + "\". Both must set \"document.domain\" to the same value to allow access.";
- if (activeOrigin->domainWasSetInDOM())
- return message + "The frame requesting access set \"document.domain\" to \"" + activeOrigin->domain() + "\", but the frame being accessed did not. Both must set \"document.domain\" to the same value to allow access.";
- if (targetOrigin->domainWasSetInDOM())
- return message + "The frame being accessed set \"document.domain\" to \"" + targetOrigin->domain() + "\", but the frame requesting access did not. Both must set \"document.domain\" to the same value to allow access.";
-
- // Default.
- return message + "Protocols, domains, and ports must match.";
-}
-
-bool DOMWindow::isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString)
-{
- if (!protocolIsJavaScript(urlString))
- return false;
-
- // If this DOMWindow isn't currently active in the Frame, then there's no
- // way we should allow the access.
- // FIXME: Remove this check if we're able to disconnect DOMWindow from
- // Frame on navigation: https://bugs.webkit.org/show_bug.cgi?id=62054
- if (isCurrentlyDisplayedInFrame()) {
- // FIXME: Is there some way to eliminate the need for a separate "activeWindow == this" check?
- if (activeWindow == this)
- return false;
-
- // FIXME: The name canAccess seems to be a roundabout way to ask "can execute script".
- // Can we name the SecurityOrigin function better to make this more clear?
- if (activeWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()))
- return false;
- }
-
- printErrorMessage(crossDomainAccessErrorMessage(activeWindow));
- return true;
-}
-
-PassRefPtr<DOMWindow> DOMWindow::open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
- DOMWindow* activeWindow, DOMWindow* firstWindow)
-{
- if (!isCurrentlyDisplayedInFrame())
- return 0;
- Document* activeDocument = activeWindow->document();
- if (!activeDocument)
- return 0;
- Frame* firstFrame = firstWindow->frame();
- if (!firstFrame)
- return 0;
-
- if (!firstWindow->allowPopUp()) {
- // Because FrameTree::find() returns true for empty strings, we must check for empty frame names.
- // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
- if (frameName.isEmpty() || !m_frame->tree().find(frameName))
- return 0;
- }
-
- // Get the target frame for the special cases of _top and _parent.
- // In those cases, we schedule a location change right now and return early.
- Frame* targetFrame = 0;
- if (frameName == "_top")
- targetFrame = m_frame->tree().top();
- else if (frameName == "_parent") {
- if (Frame* parent = m_frame->tree().parent())
- targetFrame = parent;
- else
- targetFrame = m_frame;
- }
- if (targetFrame) {
- if (!activeDocument->canNavigate(targetFrame))
- return 0;
-
- KURL completedURL = firstFrame->document()->completeURL(urlString);
-
- if (targetFrame->domWindow()->isInsecureScriptAccess(activeWindow, completedURL))
- return targetFrame->domWindow();
-
- if (urlString.isEmpty())
- return targetFrame->domWindow();
-
- // For whatever reason, Firefox uses the first window rather than the active window to
- // determine the outgoing referrer. We replicate that behavior here.
- targetFrame->navigationScheduler().scheduleLocationChange(
- activeDocument,
- completedURL,
- firstFrame->document()->outgoingReferrer(),
- false);
- return targetFrame->domWindow();
- }
-
- WindowFeatures windowFeatures(windowFeaturesString);
- Frame* result = createWindow(urlString, frameName, windowFeatures, activeWindow, firstFrame, m_frame);
- return result ? result->domWindow() : 0;
-}
-
-void DOMWindow::showModalDialog(const String& urlString, const String& dialogFeaturesString,
- DOMWindow* activeWindow, DOMWindow* firstWindow, PrepareDialogFunction function, void* functionContext)
-{
- if (!isCurrentlyDisplayedInFrame())
- return;
- Frame* activeFrame = activeWindow->frame();
- if (!activeFrame)
- return;
- Frame* firstFrame = firstWindow->frame();
- if (!firstFrame)
- return;
-
- if (!canShowModalDialogNow(m_frame) || !firstWindow->allowPopUp())
- return;
-
- UseCounter::countDeprecation(this, UseCounter::ShowModalDialog);
-
- WindowFeatures windowFeatures(dialogFeaturesString, screenAvailableRect(m_frame->view()));
- Frame* dialogFrame = createWindow(urlString, emptyAtom, windowFeatures,
- activeWindow, firstFrame, m_frame, function, functionContext);
- if (!dialogFrame)
- return;
- UserGestureIndicatorDisabler disabler;
- dialogFrame->page()->chrome().runModal();
-}
-
-DOMWindow* DOMWindow::anonymousIndexedGetter(uint32_t index)
-{
- Frame* frame = this->frame();
- if (!frame)
- return 0;
-
- Frame* child = frame->tree().scopedChild(index);
- if (child)
- return child->domWindow();
-
- return 0;
-}
-
-DOMWindowLifecycleNotifier& DOMWindow::lifecycleNotifier()
-{
- return static_cast<DOMWindowLifecycleNotifier&>(LifecycleContext<DOMWindow>::lifecycleNotifier());
-}
-
-PassOwnPtr<LifecycleNotifier<DOMWindow> > DOMWindow::createLifecycleNotifier()
-{
- return DOMWindowLifecycleNotifier::create(this);
-}
-
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindow.h b/chromium/third_party/WebKit/Source/core/frame/DOMWindow.h
deleted file mode 100644
index f4590573794..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindow.h
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DOMWindow_h
-#define DOMWindow_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/events/EventTarget.h"
-#include "core/frame/FrameDestructionObserver.h"
-#include "platform/LifecycleContext.h"
-#include "platform/Supplementable.h"
-
-#include "wtf/Forward.h"
-
-namespace WebCore {
- class ApplicationCache;
- class BarProp;
- class CSSRuleList;
- class CSSStyleDeclaration;
- class Console;
- class DOMPoint;
- class DOMSelection;
- class DOMURL;
- class DOMWindowProperty;
- class Database;
- class DatabaseCallback;
- class Document;
- class DocumentInit;
- class DOMWindowEventQueue;
- class DOMWindowLifecycleNotifier;
- class Element;
- class EventListener;
- class EventQueue;
- class ExceptionState;
- class FloatRect;
- class Frame;
- class History;
- class IDBFactory;
- class Location;
- class MediaQueryList;
- class MessageEvent;
- class Navigator;
- class Node;
- class Page;
- class PageConsole;
- class Performance;
- class PostMessageTimer;
- class RequestAnimationFrameCallback;
- class ScheduledAction;
- class Screen;
- class ScriptCallStack;
- class SecurityOrigin;
- class SerializedScriptValue;
- class Storage;
- class StyleMedia;
- class DOMWindowCSS;
-
- struct WindowFeatures;
-
- typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
-
-enum PageshowEventPersistence {
- PageshowEventNotPersisted = 0,
- PageshowEventPersisted = 1
-};
-
- enum SetLocationLocking { LockHistoryBasedOnGestureState, LockHistoryAndBackForwardList };
-
- class DOMWindow : public RefCounted<DOMWindow>, public ScriptWrappable, public EventTargetWithInlineData, public FrameDestructionObserver, public Supplementable<DOMWindow>, public LifecycleContext<DOMWindow> {
- REFCOUNTED_EVENT_TARGET(DOMWindow);
- public:
- static PassRefPtr<Document> createDocument(const String& mimeType, const DocumentInit&, bool forceXHTML);
- static PassRefPtr<DOMWindow> create(Frame* frame) { return adoptRef(new DOMWindow(frame)); }
- virtual ~DOMWindow();
-
- PassRefPtr<Document> installNewDocument(const String& mimeType, const DocumentInit&, bool forceXHTML = false);
-
- virtual const AtomicString& interfaceName() const OVERRIDE;
- virtual ExecutionContext* executionContext() const OVERRIDE;
-
- virtual DOMWindow* toDOMWindow();
-
- void registerProperty(DOMWindowProperty*);
- void unregisterProperty(DOMWindowProperty*);
-
- void reset();
-
- PassRefPtr<MediaQueryList> matchMedia(const String&);
-
- unsigned pendingUnloadEventListeners() const;
-
- static FloatRect adjustWindowRect(Page*, const FloatRect& pendingChanges);
-
- bool allowPopUp(); // Call on first window, not target window.
- static bool allowPopUp(Frame* firstFrame);
- static bool canShowModalDialog(const Frame*);
- static bool canShowModalDialogNow(const Frame*);
-
- // DOM Level 0
-
- Screen* screen() const;
- History* history() const;
- BarProp* locationbar() const;
- BarProp* menubar() const;
- BarProp* personalbar() const;
- BarProp* scrollbars() const;
- BarProp* statusbar() const;
- BarProp* toolbar() const;
- Navigator* navigator() const;
- Navigator* clientInformation() const { return navigator(); }
-
- Location* location() const;
- void setLocation(const String& location, DOMWindow* activeWindow, DOMWindow* firstWindow,
- SetLocationLocking = LockHistoryBasedOnGestureState);
-
- DOMSelection* getSelection();
-
- Element* frameElement() const;
-
- void focus(ExecutionContext* = 0);
- void blur();
- void close(ExecutionContext* = 0);
- void print();
- void stop();
-
- PassRefPtr<DOMWindow> open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
- DOMWindow* activeWindow, DOMWindow* firstWindow);
-
- typedef void (*PrepareDialogFunction)(DOMWindow*, void* context);
- void showModalDialog(const String& urlString, const String& dialogFeaturesString,
- DOMWindow* activeWindow, DOMWindow* firstWindow, PrepareDialogFunction, void* functionContext);
-
- void alert(const String& message);
- bool confirm(const String& message);
- String prompt(const String& message, const String& defaultValue);
-
- bool find(const String&, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const;
-
- bool offscreenBuffering() const;
-
- int outerHeight() const;
- int outerWidth() const;
- int innerHeight() const;
- int innerWidth() const;
- int screenX() const;
- int screenY() const;
- int screenLeft() const { return screenX(); }
- int screenTop() const { return screenY(); }
- int scrollX() const;
- int scrollY() const;
- int pageXOffset() const { return scrollX(); }
- int pageYOffset() const { return scrollY(); }
-
- bool closed() const;
-
- unsigned length() const;
-
- const AtomicString& name() const;
- void setName(const AtomicString&);
-
- String status() const;
- void setStatus(const String&);
- String defaultStatus() const;
- void setDefaultStatus(const String&);
-
- // Self-referential attributes
-
- DOMWindow* self() const;
- DOMWindow* window() const { return self(); }
- DOMWindow* frames() const { return self(); }
-
- DOMWindow* opener() const;
- DOMWindow* parent() const;
- DOMWindow* top() const;
-
- // DOM Level 2 AbstractView Interface
-
- Document* document() const;
-
- // CSSOM View Module
-
- PassRefPtr<StyleMedia> styleMedia() const;
-
- // DOM Level 2 Style Interface
-
- PassRefPtr<CSSStyleDeclaration> getComputedStyle(Element*, const String& pseudoElt) const;
-
- // WebKit extensions
-
- PassRefPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt, bool authorOnly = true) const;
- double devicePixelRatio() const;
-
- PassRefPtr<DOMPoint> webkitConvertPointFromPageToNode(Node*, const DOMPoint*) const;
- PassRefPtr<DOMPoint> webkitConvertPointFromNodeToPage(Node*, const DOMPoint*) const;
-
- Console* console() const;
- PageConsole* pageConsole() const;
-
- void printErrorMessage(const String&);
- String crossDomainAccessErrorMessage(DOMWindow* activeWindow);
- String sanitizedCrossDomainAccessErrorMessage(DOMWindow* activeWindow);
-
- void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow* source, ExceptionState&);
- void postMessageTimerFired(PassOwnPtr<PostMessageTimer>);
- void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, PassRefPtr<Event>, PassRefPtr<ScriptCallStack>);
-
- void scrollBy(int x, int y) const;
- void scrollTo(int x, int y) const;
- void scroll(int x, int y) const { scrollTo(x, y); }
-
- void moveBy(float x, float y) const;
- void moveTo(float x, float y) const;
-
- void resizeBy(float x, float y) const;
- void resizeTo(float width, float height) const;
-
- // WebKit animation extensions
- int requestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback>);
- int webkitRequestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback>);
- void cancelAnimationFrame(int id);
-
- DOMWindowCSS* css();
-
- // Events
- // EventTarget API
- virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) OVERRIDE;
- virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) OVERRIDE;
- virtual void removeAllEventListeners() OVERRIDE;
-
- using EventTarget::dispatchEvent;
- bool dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget);
-
- void dispatchLoadEvent();
-
- DEFINE_ATTRIBUTE_EVENT_LISTENER(animationend);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(animationiteration);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(animationstart);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(transitionend);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);
-
- DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, webkitAnimationStart);
- DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, webkitAnimationIteration);
- DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
- DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
-
- void captureEvents() { }
- void releaseEvents() { }
-
- void finishedLoading();
-
- DEFINE_ATTRIBUTE_EVENT_LISTENER(devicemotion);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(deviceorientation);
-
- // HTML 5 key/value storage
- Storage* sessionStorage(ExceptionState&) const;
- Storage* localStorage(ExceptionState&) const;
- Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
- Storage* optionalLocalStorage() const { return m_localStorage.get(); }
-
- ApplicationCache* applicationCache() const;
- ApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); }
-
-#if ENABLE(ORIENTATION_EVENTS)
- // This is the interface orientation in degrees. Some examples are:
- // 0 is straight up; -90 is when the device is rotated 90 clockwise;
- // 90 is when rotated counter clockwise.
- int orientation() const;
-
- DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
-#endif
-
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
-
- Performance* performance() const;
-
- // FIXME: When this DOMWindow is no longer the active DOMWindow (i.e.,
- // when its document is no longer the document that is displayed in its
- // frame), we would like to zero out m_frame to avoid being confused
- // by the document that is currently active in m_frame.
- bool isCurrentlyDisplayedInFrame() const;
-
- void willDetachDocumentFromFrame();
- DOMWindow* anonymousIndexedGetter(uint32_t);
-
- bool isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString);
-
- PassOwnPtr<LifecycleNotifier<DOMWindow> > createLifecycleNotifier();
-
- EventQueue* eventQueue() const;
- void enqueueWindowEvent(PassRefPtr<Event>);
- void enqueueDocumentEvent(PassRefPtr<Event>);
- void enqueuePageshowEvent(PageshowEventPersistence);
- void enqueueHashchangeEvent(const String& oldURL, const String& newURL);
- void enqueuePopstateEvent(PassRefPtr<SerializedScriptValue>);
- void dispatchWindowLoadEvent();
- void documentWasClosed();
- void statePopped(PassRefPtr<SerializedScriptValue>);
-
- // FIXME: This shouldn't be public once DOMWindow becomes ExecutionContext.
- void clearEventQueue();
-
- protected:
- DOMWindowLifecycleNotifier& lifecycleNotifier();
-
- private:
- explicit DOMWindow(Frame*);
-
- Page* page();
-
- virtual void frameDestroyed() OVERRIDE;
- virtual void willDetachPage() OVERRIDE;
-
- void clearDocument();
- void resetDOMWindowProperties();
- void willDestroyDocumentInFrame();
-
- RefPtr<Document> m_document;
-
- bool m_shouldPrintWhenFinishedLoading;
-
- HashSet<DOMWindowProperty*> m_properties;
-
- mutable RefPtr<Screen> m_screen;
- mutable RefPtr<History> m_history;
- mutable RefPtr<BarProp> m_locationbar;
- mutable RefPtr<BarProp> m_menubar;
- mutable RefPtr<BarProp> m_personalbar;
- mutable RefPtr<BarProp> m_scrollbars;
- mutable RefPtr<BarProp> m_statusbar;
- mutable RefPtr<BarProp> m_toolbar;
- mutable RefPtr<Console> m_console;
- mutable RefPtr<Navigator> m_navigator;
- mutable RefPtr<Location> m_location;
- mutable RefPtr<StyleMedia> m_media;
-
- String m_status;
- String m_defaultStatus;
-
- mutable RefPtr<Storage> m_sessionStorage;
- mutable RefPtr<Storage> m_localStorage;
- mutable RefPtr<ApplicationCache> m_applicationCache;
-
- mutable RefPtr<Performance> m_performance;
-
- mutable RefPtr<DOMWindowCSS> m_css;
-
- RefPtr<DOMWindowEventQueue> m_eventQueue;
- RefPtr<SerializedScriptValue> m_pendingStateObject;
- };
-
- inline String DOMWindow::status() const
- {
- return m_status;
- }
-
- inline String DOMWindow::defaultStatus() const
- {
- return m_defaultStatus;
- }
-
-} // namespace WebCore
-
-#endif // DOMWindow_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp b/chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp
index 2f43d507a77..81e3a4be945 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp
@@ -40,9 +40,7 @@
namespace WebCore {
-namespace DOMWindowBase64 {
-
-String btoa(void*, const String& stringToEncode, ExceptionState& exceptionState)
+String DOMWindowBase64::btoa(const String& stringToEncode, ExceptionState& exceptionState)
{
if (stringToEncode.isNull())
return String();
@@ -55,7 +53,7 @@ String btoa(void*, const String& stringToEncode, ExceptionState& exceptionState)
return base64Encode(stringToEncode.latin1());
}
-String atob(void*, const String& encodedString, ExceptionState& exceptionState)
+String DOMWindowBase64::atob(const String& encodedString, ExceptionState& exceptionState)
{
if (encodedString.isNull())
return String();
@@ -73,6 +71,4 @@ String atob(void*, const String& encodedString, ExceptionState& exceptionState)
return String(out.data(), out.size());
}
-} // namespace DOMWindowBase64
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.h b/chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.h
index 21001e0bf62..55ccfb71f5d 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.h
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowBase64.h
@@ -39,10 +39,11 @@ namespace WebCore {
class ExceptionState;
-namespace DOMWindowBase64 {
-String btoa(void*, const String& stringToEncode, ExceptionState&);
-String atob(void*, const String& encodedString, ExceptionState&);
-}
+class DOMWindowBase64 {
+public:
+ String btoa(const String& stringToEncode, ExceptionState&);
+ String atob(const String& encodedString, ExceptionState&);
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h b/chromium/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h
index bf897717772..fbacb01a7f6 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowEventHandlers.h
@@ -37,13 +37,13 @@ namespace WebCore {
namespace DOMWindowEventHandlers {
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(beforeunload);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(hashchange);
+DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(languagechange);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(message);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(offline);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(online);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pagehide);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(pageshow);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(popstate);
-DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(storage);
DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(unload);
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.cpp b/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.cpp
index 92fafea2796..e503f37f780 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.cpp
@@ -29,8 +29,8 @@
namespace WebCore {
-DOMWindowLifecycleNotifier::DOMWindowLifecycleNotifier(DOMWindow* context)
- : LifecycleNotifier<DOMWindow>(context)
+DOMWindowLifecycleNotifier::DOMWindowLifecycleNotifier(LocalDOMWindow* context)
+ : LifecycleNotifier<LocalDOMWindow>(context)
{
}
@@ -41,7 +41,7 @@ void DOMWindowLifecycleNotifier::addObserver(DOMWindowLifecycleNotifier::Observe
m_windowObservers.add(static_cast<DOMWindowLifecycleObserver*>(observer));
}
- LifecycleNotifier<DOMWindow>::addObserver(observer);
+ LifecycleNotifier<LocalDOMWindow>::addObserver(observer);
}
void DOMWindowLifecycleNotifier::removeObserver(DOMWindowLifecycleNotifier::Observer* observer)
@@ -51,29 +51,29 @@ void DOMWindowLifecycleNotifier::removeObserver(DOMWindowLifecycleNotifier::Obse
m_windowObservers.remove(static_cast<DOMWindowLifecycleObserver*>(observer));
}
- LifecycleNotifier<DOMWindow>::removeObserver(observer);
+ LifecycleNotifier<LocalDOMWindow>::removeObserver(observer);
}
-PassOwnPtr<DOMWindowLifecycleNotifier> DOMWindowLifecycleNotifier::create(DOMWindow* context)
+PassOwnPtr<DOMWindowLifecycleNotifier> DOMWindowLifecycleNotifier::create(LocalDOMWindow* context)
{
return adoptPtr(new DOMWindowLifecycleNotifier(context));
}
-void DOMWindowLifecycleNotifier::notifyAddEventListener(DOMWindow* window, const AtomicString& eventType)
+void DOMWindowLifecycleNotifier::notifyAddEventListener(LocalDOMWindow* window, const AtomicString& eventType)
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverDOMWindowObservers);
for (DOMWindowObserverSet::iterator it = m_windowObservers.begin(); it != m_windowObservers.end(); ++it)
(*it)->didAddEventListener(window, eventType);
}
-void DOMWindowLifecycleNotifier::notifyRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
+void DOMWindowLifecycleNotifier::notifyRemoveEventListener(LocalDOMWindow* window, const AtomicString& eventType)
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverDOMWindowObservers);
for (DOMWindowObserverSet::iterator it = m_windowObservers.begin(); it != m_windowObservers.end(); ++it)
(*it)->didRemoveEventListener(window, eventType);
}
-void DOMWindowLifecycleNotifier::notifyRemoveAllEventListeners(DOMWindow* window)
+void DOMWindowLifecycleNotifier::notifyRemoveAllEventListeners(LocalDOMWindow* window)
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverDOMWindowObservers);
for (DOMWindowObserverSet::iterator it = m_windowObservers.begin(); it != m_windowObservers.end(); ++it)
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.h b/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.h
index 7db48593e52..e652e99d9e5 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.h
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleNotifier.h
@@ -34,21 +34,21 @@
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
-class DOMWindowLifecycleNotifier : public LifecycleNotifier<DOMWindow> {
+class DOMWindowLifecycleNotifier FINAL : public LifecycleNotifier<LocalDOMWindow> {
public:
- static PassOwnPtr<DOMWindowLifecycleNotifier> create(DOMWindow*);
+ static PassOwnPtr<DOMWindowLifecycleNotifier> create(LocalDOMWindow*);
- void notifyAddEventListener(DOMWindow*, const AtomicString& eventType);
- void notifyRemoveEventListener(DOMWindow*, const AtomicString& eventType);
- void notifyRemoveAllEventListeners(DOMWindow*);
+ void notifyAddEventListener(LocalDOMWindow*, const AtomicString& eventType);
+ void notifyRemoveEventListener(LocalDOMWindow*, const AtomicString& eventType);
+ void notifyRemoveAllEventListeners(LocalDOMWindow*);
virtual void addObserver(Observer*) OVERRIDE;
virtual void removeObserver(Observer*) OVERRIDE;
private:
- explicit DOMWindowLifecycleNotifier(DOMWindow*);
+ explicit DOMWindowLifecycleNotifier(LocalDOMWindow*);
typedef HashSet<DOMWindowLifecycleObserver*> DOMWindowObserverSet;
DOMWindowObserverSet m_windowObservers;
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.cpp b/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.cpp
index aa4f97b8661..8f08ea0fdf0 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.cpp
@@ -27,22 +27,22 @@
#include "config.h"
#include "core/frame/DOMWindowLifecycleObserver.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
namespace WebCore {
-template<> void observerContext(DOMWindow* context, LifecycleObserver<DOMWindow>* observer)
+template<> void observerContext(LocalDOMWindow* context, LifecycleObserver<LocalDOMWindow>* observer)
{
context->wasObservedBy(observer);
}
-template<> void unobserverContext(DOMWindow* context, LifecycleObserver<DOMWindow>* observer)
+template<> void unobserverContext(LocalDOMWindow* context, LifecycleObserver<LocalDOMWindow>* observer)
{
context->wasUnobservedBy(observer);
}
-DOMWindowLifecycleObserver::DOMWindowLifecycleObserver(DOMWindow* window)
- : LifecycleObserver<DOMWindow>(window, DOMWindowLifecycleObserverType)
+DOMWindowLifecycleObserver::DOMWindowLifecycleObserver(LocalDOMWindow* window)
+ : LifecycleObserver<LocalDOMWindow>(window, DOMWindowLifecycleObserverType)
{
}
@@ -50,9 +50,9 @@ DOMWindowLifecycleObserver::~DOMWindowLifecycleObserver()
{
}
-DOMWindow* DOMWindowLifecycleObserver::window() const
+LocalDOMWindow* DOMWindowLifecycleObserver::window() const
{
- return static_cast<DOMWindow*>(lifecycleContext());
+ return static_cast<LocalDOMWindow*>(lifecycleContext());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.h b/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.h
index de49449697a..eb7b7b071ef 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.h
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowLifecycleObserver.h
@@ -32,21 +32,21 @@
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
-template<> void observerContext(DOMWindow*, LifecycleObserver<DOMWindow>*);
-template<> void unobserverContext(DOMWindow*, LifecycleObserver<DOMWindow>*);
+template<> void observerContext(LocalDOMWindow*, LifecycleObserver<LocalDOMWindow>*);
+template<> void unobserverContext(LocalDOMWindow*, LifecycleObserver<LocalDOMWindow>*);
-class DOMWindowLifecycleObserver : public LifecycleObserver<DOMWindow> {
+class DOMWindowLifecycleObserver : public LifecycleObserver<LocalDOMWindow> {
public:
- explicit DOMWindowLifecycleObserver(DOMWindow*);
+ explicit DOMWindowLifecycleObserver(LocalDOMWindow*);
virtual ~DOMWindowLifecycleObserver();
- DOMWindow* window() const;
+ LocalDOMWindow* window() const;
- virtual void didAddEventListener(DOMWindow*, const AtomicString&) { }
- virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) { }
- virtual void didRemoveAllEventListeners(DOMWindow*) { }
+ virtual void didAddEventListener(LocalDOMWindow*, const AtomicString&) { }
+ virtual void didRemoveEventListener(LocalDOMWindow*, const AtomicString&) { }
+ virtual void didRemoveAllEventListeners(LocalDOMWindow*) { }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp b/chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp
index 6649a2f7947..785b61519eb 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.cpp
@@ -28,12 +28,12 @@
#include "core/frame/DOMWindowProperty.h"
#include "core/dom/Document.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-DOMWindowProperty::DOMWindowProperty(Frame* frame)
+DOMWindowProperty::DOMWindowProperty(LocalFrame* frame)
: m_frame(frame)
, m_associatedDOMWindow(0)
{
@@ -57,12 +57,12 @@ DOMWindowProperty::~DOMWindowProperty()
void DOMWindowProperty::willDestroyGlobalObjectInFrame()
{
- // If the property is getting this callback it must have been created with a Frame/DOMWindow and it should still have them.
+ // If the property is getting this callback it must have been created with a LocalFrame/LocalDOMWindow and it should still have them.
ASSERT(m_frame);
ASSERT(m_associatedDOMWindow);
- // DOMWindowProperty lifetime isn't tied directly to the DOMWindow itself so it is important that it unregister
- // itself from any DOMWindow it is associated with if that DOMWindow is going away.
+ // DOMWindowProperty lifetime isn't tied directly to the LocalDOMWindow itself so it is important that it unregister
+ // itself from any LocalDOMWindow it is associated with if that LocalDOMWindow is going away.
if (m_associatedDOMWindow)
m_associatedDOMWindow->unregisterProperty(this);
m_associatedDOMWindow = 0;
@@ -71,7 +71,7 @@ void DOMWindowProperty::willDestroyGlobalObjectInFrame()
void DOMWindowProperty::willDetachGlobalObjectFromFrame()
{
- // If the property is getting this callback it must have been created with a Frame/DOMWindow and it should still have them.
+ // If the property is getting this callback it must have been created with a LocalFrame/LocalDOMWindow and it should still have them.
ASSERT(m_frame);
ASSERT(m_associatedDOMWindow);
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.h b/chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.h
index 3a4645c9081..495d715a7ac 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.h
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowProperty.h
@@ -28,23 +28,23 @@
namespace WebCore {
-class DOMWindow;
-class Frame;
+class LocalDOMWindow;
+class LocalFrame;
class DOMWindowProperty {
public:
- explicit DOMWindowProperty(Frame*);
+ explicit DOMWindowProperty(LocalFrame*);
virtual void willDestroyGlobalObjectInFrame();
virtual void willDetachGlobalObjectFromFrame();
- Frame* frame() const { return m_frame; }
+ LocalFrame* frame() const { return m_frame; }
protected:
virtual ~DOMWindowProperty();
- Frame* m_frame;
- DOMWindow* m_associatedDOMWindow;
+ LocalFrame* m_frame;
+ LocalDOMWindow* m_associatedDOMWindow;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.cpp b/chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.cpp
index b0e082c27ed..af3e06b94fb 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.cpp
@@ -40,25 +40,25 @@ namespace WebCore {
namespace DOMWindowTimers {
-int setTimeout(EventTarget* eventTarget, PassOwnPtr<ScheduledAction> action, int timeout)
+int setTimeout(EventTarget& eventTarget, PassOwnPtr<ScheduledAction> action, int timeout)
{
- return DOMTimer::install(eventTarget->executionContext(), action, timeout, true);
+ return DOMTimer::install(eventTarget.executionContext(), action, timeout, true);
}
-int setInterval(EventTarget* eventTarget, PassOwnPtr<ScheduledAction> action, int timeout)
+int setInterval(EventTarget& eventTarget, PassOwnPtr<ScheduledAction> action, int timeout)
{
- return DOMTimer::install(eventTarget->executionContext(), action, timeout, false);
+ return DOMTimer::install(eventTarget.executionContext(), action, timeout, false);
}
-void clearTimeout(EventTarget* eventTarget, int timeoutID)
+void clearTimeout(EventTarget& eventTarget, int timeoutID)
{
- if (ExecutionContext* context = eventTarget->executionContext())
+ if (ExecutionContext* context = eventTarget.executionContext())
DOMTimer::removeByID(context, timeoutID);
}
-void clearInterval(EventTarget* eventTarget, int timeoutID)
+void clearInterval(EventTarget& eventTarget, int timeoutID)
{
- if (ExecutionContext* context = eventTarget->executionContext())
+ if (ExecutionContext* context = eventTarget.executionContext())
DOMTimer::removeByID(context, timeoutID);
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.h b/chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.h
index 2a28f81810c..0465cf27570 100644
--- a/chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.h
+++ b/chromium/third_party/WebKit/Source/core/frame/DOMWindowTimers.h
@@ -41,10 +41,10 @@ class EventTarget;
class ScheduledAction;
namespace DOMWindowTimers {
-int setTimeout(EventTarget*, PassOwnPtr<ScheduledAction>, int timeout);
-int setInterval(EventTarget*, PassOwnPtr<ScheduledAction>, int timeout);
-void clearTimeout(EventTarget*, int timeoutId);
-void clearInterval(EventTarget*, int timeoutId);
+int setTimeout(EventTarget&, PassOwnPtr<ScheduledAction>, int timeout);
+int setInterval(EventTarget&, PassOwnPtr<ScheduledAction>, int timeout);
+void clearTimeout(EventTarget&, int timeoutId);
+void clearInterval(EventTarget&, int timeoutId);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DeprecatedScheduleStyleRecalcDuringLayout.cpp b/chromium/third_party/WebKit/Source/core/frame/DeprecatedScheduleStyleRecalcDuringLayout.cpp
new file mode 100644
index 00000000000..88f35ae44ee
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/DeprecatedScheduleStyleRecalcDuringLayout.cpp
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h"
+
+#include "wtf/Assertions.h"
+
+namespace WebCore {
+
+DeprecatedScheduleStyleRecalcDuringLayout::DeprecatedScheduleStyleRecalcDuringLayout(DocumentLifecycle& lifecycle)
+ : m_lifecycle(lifecycle)
+ , m_deprecatedTransition(DocumentLifecycle::InPerformLayout, DocumentLifecycle::VisualUpdatePending)
+ , m_wasInPerformLayout(lifecycle.state() == DocumentLifecycle::InPerformLayout)
+{
+}
+
+DeprecatedScheduleStyleRecalcDuringLayout::~DeprecatedScheduleStyleRecalcDuringLayout()
+{
+ // This block of code is intended to restore the state machine to the
+ // proper state. The style recalc will still have been schedule, however.
+ if (m_wasInPerformLayout && m_lifecycle.state() != DocumentLifecycle::InPerformLayout) {
+ ASSERT(m_lifecycle.state() == DocumentLifecycle::VisualUpdatePending);
+ m_lifecycle.advanceTo(DocumentLifecycle::InPerformLayout);
+ }
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h b/chromium/third_party/WebKit/Source/core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h
new file mode 100644
index 00000000000..90b9223f8ca
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DeprecatedScheduleStyleRecalcDuringLayout_h
+#define DeprecatedScheduleStyleRecalcDuringLayout_h
+
+#include "core/dom/DocumentLifecycle.h"
+
+namespace WebCore {
+
+class DeprecatedScheduleStyleRecalcDuringLayout {
+ WTF_MAKE_NONCOPYABLE(DeprecatedScheduleStyleRecalcDuringLayout);
+public:
+ explicit DeprecatedScheduleStyleRecalcDuringLayout(DocumentLifecycle&);
+ ~DeprecatedScheduleStyleRecalcDuringLayout();
+
+private:
+ DocumentLifecycle& m_lifecycle;
+ DocumentLifecycle::DeprecatedTransition m_deprecatedTransition;
+ bool m_wasInPerformLayout;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/DeviceEventControllerBase.cpp b/chromium/third_party/WebKit/Source/core/frame/DeviceEventControllerBase.cpp
new file mode 100644
index 00000000000..f5f5eab4a0f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/DeviceEventControllerBase.cpp
@@ -0,0 +1,70 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/DeviceEventControllerBase.h"
+
+#include "core/page/Page.h"
+
+namespace WebCore {
+
+DeviceEventControllerBase::DeviceEventControllerBase(Page* page)
+ : PageLifecycleObserver(page)
+ , m_hasEventListener(false)
+ , m_isActive(false)
+ , m_timer(this, &DeviceEventControllerBase::oneShotCallback)
+{
+}
+
+DeviceEventControllerBase::~DeviceEventControllerBase()
+{
+}
+
+void DeviceEventControllerBase::oneShotCallback(Timer<DeviceEventControllerBase>* timer)
+{
+ ASSERT_UNUSED(timer, timer == &m_timer);
+ ASSERT(hasLastData());
+ ASSERT(!m_timer.isActive());
+
+ didUpdateData();
+}
+
+void DeviceEventControllerBase::startUpdating()
+{
+ if (m_isActive)
+ return;
+
+ if (hasLastData() && !m_timer.isActive()) {
+ // Make sure to fire the data as soon as possible.
+ m_timer.startOneShot(0, FROM_HERE);
+ }
+
+ registerWithDispatcher();
+ m_isActive = true;
+}
+
+void DeviceEventControllerBase::stopUpdating()
+{
+ if (!m_isActive)
+ return;
+
+ if (m_timer.isActive())
+ m_timer.stop();
+
+ unregisterWithDispatcher();
+ m_isActive = false;
+}
+
+void DeviceEventControllerBase::pageVisibilityChanged()
+{
+ if (!m_hasEventListener)
+ return;
+
+ if (page()->visibilityState() == PageVisibilityStateVisible)
+ startUpdating();
+ else
+ stopUpdating();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DeviceEventControllerBase.h b/chromium/third_party/WebKit/Source/core/frame/DeviceEventControllerBase.h
new file mode 100644
index 00000000000..9d2902a47d2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/DeviceEventControllerBase.h
@@ -0,0 +1,49 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DeviceEventControllerBase_h
+#define DeviceEventControllerBase_h
+
+#include "core/page/PageLifecycleObserver.h"
+#include "platform/Timer.h"
+
+namespace WebCore {
+
+// Base controller class for registering controllers with a dispatcher.
+// It watches page visibility and calls stopUpdating when page is not visible.
+// It provides a didUpdateData() callback method which is called when new data
+// it available.
+class DeviceEventControllerBase : public PageLifecycleObserver {
+public:
+ void startUpdating();
+ void stopUpdating();
+
+ // This is called when new data becomes available.
+ virtual void didUpdateData() = 0;
+
+protected:
+ explicit DeviceEventControllerBase(Page*);
+ virtual ~DeviceEventControllerBase();
+
+ virtual void registerWithDispatcher() = 0;
+ virtual void unregisterWithDispatcher() = 0;
+
+ // When true initiates a one-shot didUpdateData() when startUpdating() is called.
+ virtual bool hasLastData() = 0;
+
+ bool m_hasEventListener;
+
+private:
+ // Inherited from PageLifecycleObserver.
+ virtual void pageVisibilityChanged() OVERRIDE FINAL;
+
+ void oneShotCallback(Timer<DeviceEventControllerBase>*);
+
+ bool m_isActive;
+ Timer<DeviceEventControllerBase> m_timer;
+};
+
+} // namespace WebCore
+
+#endif // DeviceEventControllerBase_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/DeviceEventDispatcherBase.cpp b/chromium/third_party/WebKit/Source/core/frame/DeviceEventDispatcherBase.cpp
new file mode 100644
index 00000000000..4f01bf52cde
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/DeviceEventDispatcherBase.cpp
@@ -0,0 +1,87 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/DeviceEventDispatcherBase.h"
+
+#include "core/frame/DeviceEventControllerBase.h"
+#include "wtf/TemporaryChange.h"
+
+namespace WebCore {
+
+DeviceEventDispatcherBase::DeviceEventDispatcherBase()
+ : m_needsPurge(false)
+ , m_isDispatching(false)
+{
+}
+
+DeviceEventDispatcherBase::~DeviceEventDispatcherBase()
+{
+}
+
+void DeviceEventDispatcherBase::addController(DeviceEventControllerBase* controller)
+{
+ bool wasEmpty = m_controllers.isEmpty();
+ if (!m_controllers.contains(controller))
+ m_controllers.append(controller);
+ if (wasEmpty)
+ startListening();
+}
+
+void DeviceEventDispatcherBase::removeController(DeviceEventControllerBase* controller)
+{
+ // Do not actually remove the controller from the vector, instead zero them out.
+ // The zeros are removed in these two cases:
+ // 1. either immediately if we are not dispatching any events,
+ // 2. or after events to all controllers have dispatched (see notifyControllers()).
+ // This is to correctly handle the re-entrancy case when a controller is destroyed
+ // while the events are still being dispatched.
+ size_t index = m_controllers.find(controller);
+ if (index == kNotFound)
+ return;
+
+ m_controllers[index] = 0;
+ m_needsPurge = true;
+
+ if (!m_isDispatching)
+ purgeControllers();
+}
+
+void DeviceEventDispatcherBase::purgeControllers()
+{
+ ASSERT(m_needsPurge);
+
+ size_t i = 0;
+ while (i < m_controllers.size()) {
+ if (!m_controllers[i]) {
+ m_controllers[i] = m_controllers.last();
+ m_controllers.removeLast();
+ } else {
+ ++i;
+ }
+ }
+
+ m_needsPurge = false;
+
+ if (m_controllers.isEmpty())
+ stopListening();
+}
+
+void DeviceEventDispatcherBase::notifyControllers()
+{
+ {
+ TemporaryChange<bool> changeIsDispatching(m_isDispatching, true);
+ // Don't notify controllers removed or added during event dispatch.
+ size_t size = m_controllers.size();
+ for (size_t i = 0; i < size; ++i) {
+ if (m_controllers[i])
+ m_controllers[i]->didUpdateData();
+ }
+ }
+
+ if (m_needsPurge)
+ purgeControllers();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DeviceEventDispatcherBase.h b/chromium/third_party/WebKit/Source/core/frame/DeviceEventDispatcherBase.h
new file mode 100644
index 00000000000..94b226698a9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/DeviceEventDispatcherBase.h
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DeviceEventDispatcherBase_h
+#define DeviceEventDispatcherBase_h
+
+#include "wtf/Vector.h"
+
+namespace WebCore {
+class DeviceEventControllerBase;
+
+class DeviceEventDispatcherBase {
+public:
+ void addController(DeviceEventControllerBase*);
+ void removeController(DeviceEventControllerBase*);
+
+protected:
+ DeviceEventDispatcherBase();
+ virtual ~DeviceEventDispatcherBase();
+
+ void notifyControllers();
+
+ virtual void startListening() = 0;
+ virtual void stopListening() = 0;
+
+private:
+ void purgeControllers();
+
+ Vector<DeviceEventControllerBase*> m_controllers;
+ bool m_needsPurge;
+ bool m_isDispatching;
+};
+
+} // namespace WebCore
+
+#endif // DeviceEventDispatcherBase_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp b/chromium/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp
new file mode 100644
index 00000000000..b0f6c30ce48
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.cpp
@@ -0,0 +1,73 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/DeviceSingleWindowEventController.h"
+
+#include "core/dom/Document.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/page/Page.h"
+
+namespace WebCore {
+
+DeviceSingleWindowEventController::DeviceSingleWindowEventController(Document& document)
+ : DeviceEventControllerBase(document.page())
+ , DOMWindowLifecycleObserver(document.domWindow())
+ , m_needsCheckingNullEvents(true)
+ , m_document(document)
+{
+}
+
+DeviceSingleWindowEventController::~DeviceSingleWindowEventController()
+{
+}
+
+void DeviceSingleWindowEventController::didUpdateData()
+{
+ dispatchDeviceEvent(lastEvent());
+}
+
+void DeviceSingleWindowEventController::dispatchDeviceEvent(PassRefPtrWillBeRawPtr<Event> prpEvent)
+{
+ if (!m_document.domWindow() || m_document.activeDOMObjectsAreSuspended() || m_document.activeDOMObjectsAreStopped())
+ return;
+
+ RefPtrWillBeRawPtr<Event> event = prpEvent;
+ m_document.domWindow()->dispatchEvent(event);
+
+ if (m_needsCheckingNullEvents) {
+ if (isNullEvent(event.get()))
+ stopUpdating();
+ else
+ m_needsCheckingNullEvents = false;
+ }
+}
+
+void DeviceSingleWindowEventController::didAddEventListener(LocalDOMWindow* window, const AtomicString& eventType)
+{
+ if (eventType != eventTypeName())
+ return;
+
+ if (page() && page()->visibilityState() == PageVisibilityStateVisible)
+ startUpdating();
+
+ m_hasEventListener = true;
+}
+
+void DeviceSingleWindowEventController::didRemoveEventListener(LocalDOMWindow* window, const AtomicString& eventType)
+{
+ if (eventType != eventTypeName() || window->hasEventListeners(eventTypeName()))
+ return;
+
+ stopUpdating();
+ m_hasEventListener = false;
+}
+
+void DeviceSingleWindowEventController::didRemoveAllEventListeners(LocalDOMWindow*)
+{
+ stopUpdating();
+ m_hasEventListener = false;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.h b/chromium/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.h
new file mode 100644
index 00000000000..d28d46dd3e6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/DeviceSingleWindowEventController.h
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DeviceSingleWindowEventController_h
+#define DeviceSingleWindowEventController_h
+
+#include "core/frame/DOMWindowLifecycleObserver.h"
+#include "core/frame/DeviceEventControllerBase.h"
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class Document;
+class Event;
+
+class DeviceSingleWindowEventController : public DeviceEventControllerBase, public DOMWindowLifecycleObserver {
+public:
+ // Inherited from DeviceEventControllerBase.
+ virtual void didUpdateData() OVERRIDE;
+
+ // Inherited from DOMWindowLifecycleObserver.
+ virtual void didAddEventListener(LocalDOMWindow*, const AtomicString&) OVERRIDE;
+ virtual void didRemoveEventListener(LocalDOMWindow*, const AtomicString&) OVERRIDE;
+ virtual void didRemoveAllEventListeners(LocalDOMWindow*) OVERRIDE;
+
+protected:
+ explicit DeviceSingleWindowEventController(Document&);
+ virtual ~DeviceSingleWindowEventController();
+
+ void dispatchDeviceEvent(const PassRefPtrWillBeRawPtr<Event>);
+
+ virtual PassRefPtrWillBeRawPtr<Event> lastEvent() const = 0;
+ virtual const AtomicString& eventTypeName() const = 0;
+ virtual bool isNullEvent(Event*) const = 0;
+
+private:
+ bool m_needsCheckingNullEvents;
+ Document& m_document;
+};
+
+} // namespace WebCore
+
+#endif // DeviceSingleWindowEventController_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/EventHandlerRegistry.cpp b/chromium/third_party/WebKit/Source/core/frame/EventHandlerRegistry.cpp
new file mode 100644
index 00000000000..014e94eac5b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/EventHandlerRegistry.cpp
@@ -0,0 +1,255 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/EventHandlerRegistry.h"
+
+#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/page/Page.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+
+namespace WebCore {
+
+EventHandlerRegistry::EventHandlerRegistry(FrameHost& frameHost)
+ : m_frameHost(frameHost)
+{
+}
+
+EventHandlerRegistry::~EventHandlerRegistry()
+{
+ checkConsistency();
+}
+
+bool EventHandlerRegistry::eventTypeToClass(const AtomicString& eventType, EventHandlerClass* result)
+{
+ if (eventType == EventTypeNames::scroll) {
+ *result = ScrollEvent;
+ } else if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel) {
+ *result = WheelEvent;
+#if ASSERT_ENABLED
+ } else if (eventType == EventTypeNames::load || eventType == EventTypeNames::mousemove || eventType == EventTypeNames::touchstart) {
+ *result = EventsForTesting;
+#endif
+ } else {
+ return false;
+ }
+ return true;
+}
+
+const EventTargetSet* EventHandlerRegistry::eventHandlerTargets(EventHandlerClass handlerClass) const
+{
+ checkConsistency();
+ return &m_targets[handlerClass];
+}
+
+bool EventHandlerRegistry::hasEventHandlers(EventHandlerClass handlerClass) const
+{
+ return m_targets[handlerClass].size();
+}
+
+bool EventHandlerRegistry::updateEventHandlerTargets(ChangeOperation op, EventHandlerClass handlerClass, EventTarget* target)
+{
+ EventTargetSet* targets = &m_targets[handlerClass];
+ if (op == Add) {
+ if (!targets->add(target).isNewEntry) {
+ // Just incremented refcount, no real change.
+ return false;
+ }
+ } else {
+ ASSERT(op == Remove || op == RemoveAll);
+ ASSERT(op == RemoveAll || targets->contains(target));
+
+ if (op == RemoveAll) {
+ if (!targets->contains(target))
+ return false;
+ targets->removeAll(target);
+ } else {
+ if (!targets->remove(target)) {
+ // Just decremented refcount, no real update.
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void EventHandlerRegistry::updateEventHandlerInternal(ChangeOperation op, EventHandlerClass handlerClass, EventTarget* target)
+{
+ bool hadHandlers = hasEventHandlers(handlerClass);
+ updateEventHandlerTargets(op, handlerClass, target);
+ bool hasHandlers = hasEventHandlers(handlerClass);
+
+ if (hadHandlers != hasHandlers) {
+ notifyHasHandlersChanged(handlerClass, hasHandlers);
+ }
+ checkConsistency();
+}
+
+void EventHandlerRegistry::updateEventHandlerOfType(ChangeOperation op, const AtomicString& eventType, EventTarget* target)
+{
+ EventHandlerClass handlerClass;
+ if (!eventTypeToClass(eventType, &handlerClass))
+ return;
+ updateEventHandlerInternal(op, handlerClass, target);
+}
+
+void EventHandlerRegistry::didAddEventHandler(EventTarget& target, const AtomicString& eventType)
+{
+ updateEventHandlerOfType(Add, eventType, &target);
+}
+
+void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, const AtomicString& eventType)
+{
+ updateEventHandlerOfType(Remove, eventType, &target);
+}
+
+void EventHandlerRegistry::didAddEventHandler(EventTarget& target, EventHandlerClass handlerClass)
+{
+ updateEventHandlerInternal(Add, handlerClass, &target);
+}
+
+void EventHandlerRegistry::didRemoveEventHandler(EventTarget& target, EventHandlerClass handlerClass)
+{
+ updateEventHandlerInternal(Remove, handlerClass, &target);
+}
+
+void EventHandlerRegistry::didMoveIntoFrameHost(EventTarget& target)
+{
+ updateAllEventHandlers(Add, target);
+}
+
+void EventHandlerRegistry::didMoveOutOfFrameHost(EventTarget& target)
+{
+ updateAllEventHandlers(RemoveAll, target);
+}
+
+void EventHandlerRegistry::didRemoveAllEventHandlers(EventTarget& target)
+{
+ for (size_t i = 0; i < EventHandlerClassCount; ++i) {
+ EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
+ updateEventHandlerInternal(RemoveAll, handlerClass, &target);
+ }
+}
+
+void EventHandlerRegistry::updateAllEventHandlers(ChangeOperation op, EventTarget& target)
+{
+ if (!target.hasEventListeners())
+ return;
+
+ Vector<AtomicString> eventTypes = target.eventTypes();
+ for (size_t i = 0; i < eventTypes.size(); ++i) {
+ EventHandlerClass handlerClass;
+ if (!eventTypeToClass(eventTypes[i], &handlerClass))
+ continue;
+ if (op == RemoveAll) {
+ updateEventHandlerInternal(op, handlerClass, &target);
+ continue;
+ }
+ for (unsigned count = target.getEventListeners(eventTypes[i]).size(); count > 0; --count)
+ updateEventHandlerInternal(op, handlerClass, &target);
+ }
+}
+
+void EventHandlerRegistry::notifyHasHandlersChanged(EventHandlerClass handlerClass, bool hasActiveHandlers)
+{
+ ScrollingCoordinator* scrollingCoordinator = m_frameHost.page().scrollingCoordinator();
+
+ switch (handlerClass) {
+ case ScrollEvent:
+ if (scrollingCoordinator)
+ scrollingCoordinator->updateHaveScrollEventHandlers();
+ break;
+ case WheelEvent:
+ if (scrollingCoordinator)
+ scrollingCoordinator->updateHaveWheelEventHandlers();
+ break;
+#if ASSERT_ENABLED
+ case EventsForTesting:
+ break;
+#endif
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+void EventHandlerRegistry::trace(Visitor* visitor)
+{
+ visitor->registerWeakMembers<EventHandlerRegistry, &EventHandlerRegistry::clearWeakMembers>(this);
+}
+
+void EventHandlerRegistry::clearWeakMembers(Visitor* visitor)
+{
+ Vector<EventTarget*> deadTargets;
+ for (size_t i = 0; i < EventHandlerClassCount; ++i) {
+ EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
+ const EventTargetSet* targets = &m_targets[handlerClass];
+ for (EventTargetSet::const_iterator it = targets->begin(); it != targets->end(); ++it) {
+ Node* node = it->key->toNode();
+ LocalDOMWindow* window = it->key->toDOMWindow();
+ if (node && !visitor->isAlive(node)) {
+ deadTargets.append(node);
+ } else if (window && !visitor->isAlive(window)) {
+ deadTargets.append(window);
+ }
+ }
+ }
+ for (size_t i = 0; i < deadTargets.size(); ++i)
+ didRemoveAllEventHandlers(*deadTargets[i]);
+}
+
+void EventHandlerRegistry::documentDetached(Document& document)
+{
+ // Remove all event targets under the detached document.
+ for (size_t handlerClassIndex = 0; handlerClassIndex < EventHandlerClassCount; ++handlerClassIndex) {
+ EventHandlerClass handlerClass = static_cast<EventHandlerClass>(handlerClassIndex);
+ Vector<EventTarget*> targetsToRemove;
+ const EventTargetSet* targets = &m_targets[handlerClass];
+ for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) {
+ if (Node* node = iter->key->toNode()) {
+ for (Document* doc = &node->document(); doc; doc = doc->ownerElement() ? &doc->ownerElement()->document() : 0) {
+ if (doc == &document) {
+ targetsToRemove.append(iter->key);
+ break;
+ }
+ }
+ } else if (iter->key->toDOMWindow()) {
+ // DOMWindows may outlive their documents, so we shouldn't remove their handlers
+ // here.
+ } else {
+ ASSERT_NOT_REACHED();
+ }
+ }
+ for (size_t i = 0; i < targetsToRemove.size(); ++i)
+ updateEventHandlerInternal(RemoveAll, handlerClass, targetsToRemove[i]);
+ }
+}
+
+void EventHandlerRegistry::checkConsistency() const
+{
+#if ASSERT_ENABLED
+ for (size_t i = 0; i < EventHandlerClassCount; ++i) {
+ EventHandlerClass handlerClass = static_cast<EventHandlerClass>(i);
+ const EventTargetSet* targets = &m_targets[handlerClass];
+ for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) {
+ if (Node* node = iter->key->toNode()) {
+ // See the comment for |documentDetached| if either of these assertions fails.
+ ASSERT(node->document().frameHost());
+ ASSERT(node->document().frameHost() == &m_frameHost);
+ } else if (LocalDOMWindow* window = iter->key->toDOMWindow()) {
+ // If any of these assertions fail, LocalDOMWindow failed to unregister its handlers
+ // properly.
+ ASSERT(window->frame());
+ ASSERT(window->frame()->host());
+ ASSERT(window->frame()->host() == &m_frameHost);
+ }
+ }
+ }
+#endif // ASSERT_ENABLED
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/EventHandlerRegistry.h b/chromium/third_party/WebKit/Source/core/frame/EventHandlerRegistry.h
new file mode 100644
index 00000000000..4d53b31def1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/EventHandlerRegistry.h
@@ -0,0 +1,96 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EventHandlerRegistry_h
+#define EventHandlerRegistry_h
+
+#include "core/events/Event.h"
+#include "core/frame/FrameHost.h"
+#include "wtf/HashCountedSet.h"
+
+namespace WebCore {
+
+typedef HashCountedSet<EventTarget*> EventTargetSet;
+
+// Registry for keeping track of event handlers. Note that only handlers on
+// documents that can be rendered or can receive input (i.e., are attached to a
+// FrameHost) are registered here.
+class EventHandlerRegistry FINAL : public NoBaseWillBeGarbageCollectedFinalized<EventHandlerRegistry> {
+public:
+ explicit EventHandlerRegistry(FrameHost&);
+ virtual ~EventHandlerRegistry();
+
+ // Supported event handler classes. Note that each one may correspond to
+ // multiple event types.
+ enum EventHandlerClass {
+ ScrollEvent,
+ WheelEvent,
+#if ASSERT_ENABLED
+ // Additional event categories for verifying handler tracking logic.
+ EventsForTesting,
+#endif
+ EventHandlerClassCount, // Must be the last entry.
+ };
+
+ // Returns true if the FrameHost has event handlers of the specified class.
+ bool hasEventHandlers(EventHandlerClass) const;
+
+ // Returns a set of EventTargets which have registered handlers of the given class.
+ const EventTargetSet* eventHandlerTargets(EventHandlerClass) const;
+
+ // Registration and management of event handlers attached to EventTargets.
+ void didAddEventHandler(EventTarget&, const AtomicString& eventType);
+ void didAddEventHandler(EventTarget&, EventHandlerClass);
+ void didRemoveEventHandler(EventTarget&, const AtomicString& eventType);
+ void didRemoveEventHandler(EventTarget&, EventHandlerClass);
+ void didRemoveAllEventHandlers(EventTarget&);
+ void didMoveIntoFrameHost(EventTarget&);
+ void didMoveOutOfFrameHost(EventTarget&);
+
+ // Either |documentDetached| or |didMoveOutOfFrameHost| must be called
+ // whenever the FrameHost that is associated with a registered event target
+ // changes. This ensures the registry does not end up with stale references
+ // to handlers that are no longer related to it.
+ void documentDetached(Document&);
+
+ void trace(Visitor*);
+ void clearWeakMembers(Visitor*);
+
+private:
+ enum ChangeOperation {
+ Add, // Add a new event handler.
+ Remove, // Remove an existing event handler.
+ RemoveAll // Remove any and all existing event handlers for a given target.
+ };
+
+ // Returns true if |eventType| belongs to a class this registry tracks.
+ static bool eventTypeToClass(const AtomicString& eventType, EventHandlerClass* result);
+
+ // Returns true if the operation actually added a new target or completely
+ // removed an existing one.
+ bool updateEventHandlerTargets(ChangeOperation, EventHandlerClass, EventTarget*);
+
+ // Called on the EventHandlerRegistry of the root Document to notify
+ // clients when we have added the first handler or removed the last one for
+ // a given event class. |hasActiveHandlers| can be used to distinguish
+ // between the two cases.
+ void notifyHasHandlersChanged(EventHandlerClass, bool hasActiveHandlers);
+
+ // Record a change operation to a given event handler class and notify any
+ // parent registry and other clients accordingly.
+ void updateEventHandlerOfType(ChangeOperation, const AtomicString& eventType, EventTarget*);
+
+ void updateEventHandlerInternal(ChangeOperation, EventHandlerClass, EventTarget*);
+
+ void updateAllEventHandlers(ChangeOperation, EventTarget&);
+
+ void checkConsistency() const;
+
+ FrameHost& m_frameHost;
+ EventTargetSet m_targets[EventHandlerClassCount];
+};
+
+} // namespace WebCore
+
+#endif // EventHandlerRegistry_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/Frame.cpp b/chromium/third_party/WebKit/Source/core/frame/Frame.cpp
index cac41bdafc9..52813512bdd 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Frame.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/Frame.cpp
@@ -30,23 +30,12 @@
#include "config.h"
#include "core/frame/Frame.h"
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ScriptController.h"
#include "core/dom/DocumentType.h"
-#include "core/dom/WheelController.h"
-#include "core/editing/Editor.h"
-#include "core/editing/FrameSelection.h"
-#include "core/editing/InputMethodController.h"
-#include "core/editing/SpellChecker.h"
-#include "core/editing/htmlediting.h"
-#include "core/editing/markup.h"
#include "core/events/Event.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameDestructionObserver.h"
-#include "core/frame/FrameView.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/Settings.h"
-#include "core/frame/animation/AnimationController.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/EmptyClients.h"
@@ -56,21 +45,10 @@
#include "core/page/EventHandler.h"
#include "core/page/FocusController.h"
#include "core/page/Page.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/platform/DragImage.h"
-#include "core/rendering/HitTestResult.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderPart.h"
-#include "core/rendering/RenderView.h"
-#include "core/svg/SVGDocument.h"
-#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/ImageBuffer.h"
#include "public/platform/WebLayer.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCountedLeakCounter.h"
-#include "wtf/StdLibExtras.h"
-
-using namespace std;
namespace WebCore {
@@ -78,75 +56,32 @@ using namespace HTMLNames;
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, frameCounter, ("Frame"));
-static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement)
-{
- if (!ownerElement)
- return 0;
- return ownerElement->document().frame();
-}
-
-static inline float parentPageZoomFactor(Frame* frame)
-{
- Frame* parent = frame->tree().parent();
- if (!parent)
- return 1;
- return parent->pageZoomFactor();
-}
-
-static inline float parentTextZoomFactor(Frame* frame)
-{
- Frame* parent = frame->tree().parent();
- if (!parent)
- return 1;
- return parent->textZoomFactor();
-}
-
-inline Frame::Frame(PassRefPtr<FrameInit> frameInit)
- : m_page(frameInit->page())
- , m_treeNode(this, parentFromOwnerElement(frameInit->ownerElement()))
- , m_loader(this, frameInit->frameLoaderClient())
- , m_navigationScheduler(this)
- , m_script(adoptPtr(new ScriptController(this)))
- , m_editor(Editor::create(*this))
- , m_spellChecker(SpellChecker::create(*this))
- , m_selection(adoptPtr(new FrameSelection(this)))
- , m_eventHandler(adoptPtr(new EventHandler(this)))
- , m_animationController(adoptPtr(new AnimationController(this)))
- , m_inputMethodController(InputMethodController::create(*this))
- , m_frameInit(frameInit)
- , m_pageZoomFactor(parentPageZoomFactor(this))
- , m_textZoomFactor(parentTextZoomFactor(this))
-#if ENABLE(ORIENTATION_EVENTS)
- , m_orientation(0)
-#endif
- , m_inViewSourceMode(false)
+Frame::Frame(FrameClient* client, FrameHost* host, FrameOwner* owner)
+ : m_treeNode(this)
+ , m_host(host)
+ , m_owner(owner)
+ , m_client(client)
, m_remotePlatformLayer(0)
{
- ASSERT(m_page);
-
- if (ownerElement()) {
- m_page->incrementSubframeCount();
- ownerElement()->setContentFrame(*this);
- }
+ ASSERT(page());
#ifndef NDEBUG
frameCounter.increment();
#endif
-}
-PassRefPtr<Frame> Frame::create(PassRefPtr<FrameInit> frameInit)
-{
- RefPtr<Frame> frame = adoptRef(new Frame(frameInit));
- if (!frame->ownerElement())
- frame->page()->setMainFrame(frame);
- InspectorInstrumentation::frameAttachedToParent(frame.get());
- return frame.release();
+ if (m_owner) {
+ page()->incrementSubframeCount();
+ if (m_owner->isLocal())
+ toHTMLFrameOwnerElement(m_owner)->setContentFrame(*this);
+ } else {
+ page()->setMainFrame(this);
+ }
}
Frame::~Frame()
{
- setView(0);
- loader().clear(ClearScriptObjects | ClearWindowObject);
+ disconnectOwnerElement();
+ setDOMWindow(nullptr);
// FIXME: We should not be doing all this work inside the destructor
@@ -154,25 +89,11 @@ Frame::~Frame()
frameCounter.decrement();
#endif
- disconnectOwnerElement();
-
HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
(*it)->frameDestroyed();
}
-bool Frame::inScope(TreeScope* scope) const
-{
- ASSERT(scope);
- Document* doc = document();
- if (!doc)
- return false;
- HTMLFrameOwnerElement* owner = doc->ownerElement();
- if (!owner)
- return false;
- return owner->treeScope() == scope;
-}
-
void Frame::addDestructionObserver(FrameDestructionObserver* observer)
{
m_destructionObservers.add(observer);
@@ -183,99 +104,29 @@ void Frame::removeDestructionObserver(FrameDestructionObserver* observer)
m_destructionObservers.remove(observer);
}
-void Frame::setView(PassRefPtr<FrameView> view)
+FrameHost* Frame::host() const
{
- // We the custom scroll bars as early as possible to prevent m_doc->detach()
- // from messing with the view such that its scroll bars won't be torn down.
- // FIXME: We should revisit this.
- if (m_view)
- m_view->prepareForDetach();
-
- // Prepare for destruction now, so any unload event handlers get run and the DOMWindow is
- // notified. If we wait until the view is destroyed, then things won't be hooked up enough for
- // these calls to work.
- if (!view && document() && document()->isActive()) {
- // FIXME: We don't call willRemove here. Why is that OK?
- document()->prepareForDestruction();
- }
-
- if (m_view)
- m_view->unscheduleRelayout();
-
- eventHandler().clear();
-
- m_view = view;
-
- if (m_view && isMainFrame())
- m_view->setVisibleContentScaleFactor(m_page->pageScaleFactor());
+ return m_host;
}
-#if ENABLE(ORIENTATION_EVENTS)
-void Frame::sendOrientationChangeEvent(int orientation)
+Page* Frame::page() const
{
- m_orientation = orientation;
- if (DOMWindow* window = domWindow())
- window->dispatchEvent(Event::create(EventTypeNames::orientationchange));
+ if (m_host)
+ return &m_host->page();
+ return 0;
}
-#endif // ENABLE(ORIENTATION_EVENTS)
Settings* Frame::settings() const
{
- return m_page ? &m_page->settings() : 0;
-}
-
-void Frame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot shouldAdjustViewSize)
-{
- // In setting printing, we should not validate resources already cached for the document.
- // See https://bugs.webkit.org/show_bug.cgi?id=43704
- ResourceCacheValidationSuppressor validationSuppressor(document()->fetcher());
-
- document()->setPrinting(printing);
- view()->adjustMediaTypeForPrinting(printing);
-
- document()->styleResolverChanged(RecalcStyleImmediately);
- if (shouldUsePrintingLayout()) {
- view()->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize);
- } else {
- view()->forceLayout();
- if (shouldAdjustViewSize == AdjustViewSize)
- view()->adjustViewSize();
- }
-
- // Subframes of the one we're printing don't lay out to the page size.
- for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling())
- child->setPrinting(printing, FloatSize(), FloatSize(), 0, shouldAdjustViewSize);
-}
-
-bool Frame::shouldUsePrintingLayout() const
-{
- // Only top frame being printed should be fit to page size.
- // Subframes should be constrained by parents only.
- return document()->printing() && (!tree().parent() || !tree().parent()->document()->printing());
-}
-
-FloatSize Frame::resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize)
-{
- FloatSize resultSize;
- if (!contentRenderer())
- return FloatSize();
-
- if (contentRenderer()->style()->isHorizontalWritingMode()) {
- ASSERT(fabs(originalSize.width()) > numeric_limits<float>::epsilon());
- float ratio = originalSize.height() / originalSize.width();
- resultSize.setWidth(floorf(expectedSize.width()));
- resultSize.setHeight(floorf(resultSize.width() * ratio));
- } else {
- ASSERT(fabs(originalSize.height()) > numeric_limits<float>::epsilon());
- float ratio = originalSize.width() / originalSize.height();
- resultSize.setHeight(floorf(expectedSize.height()));
- resultSize.setWidth(floorf(resultSize.height() * ratio));
- }
- return resultSize;
+ if (m_host)
+ return &m_host->settings();
+ return 0;
}
-void Frame::setDOMWindow(PassRefPtr<DOMWindow> domWindow)
+void Frame::setDOMWindow(PassRefPtrWillBeRawPtr<LocalDOMWindow> domWindow)
{
+ if (m_domWindow)
+ m_domWindow->reset();
m_domWindow = domWindow;
}
@@ -292,21 +143,11 @@ ChromeClient& Frame::chromeClient() const
return emptyChromeClient();
}
-Document* Frame::document() const
-{
- return m_domWindow ? m_domWindow->document() : 0;
-}
-
-RenderView* Frame::contentRenderer() const
-{
- return document() ? document()->renderView() : 0;
-}
-
RenderPart* Frame::ownerRenderer() const
{
- if (!ownerElement())
+ if (!deprecatedLocalOwner())
return 0;
- RenderObject* object = ownerElement()->renderer();
+ RenderObject* object = deprecatedLocalOwner()->renderer();
if (!object)
return 0;
// FIXME: If <object> is ever fixed to disassociate itself from frames
@@ -318,391 +159,45 @@ RenderPart* Frame::ownerRenderer() const
return toRenderPart(object);
}
-void Frame::dispatchVisibilityStateChangeEvent()
-{
- if (document())
- document()->dispatchVisibilityStateChangeEvent();
-
- Vector<RefPtr<Frame> > childFrames;
- for (Frame* child = tree().firstChild(); child; child = child->tree().nextSibling())
- childFrames.append(child);
-
- for (size_t i = 0; i < childFrames.size(); ++i)
- childFrames[i]->dispatchVisibilityStateChangeEvent();
-}
-void Frame::willDetachPage()
+void Frame::willDetachFrameHost()
{
- // We should never be detatching the page during a Layout.
- RELEASE_ASSERT(!m_view || !m_view->isInLayout());
-
- if (Frame* parent = tree().parent())
- parent->loader().checkLoadComplete();
-
HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
- (*it)->willDetachPage();
+ (*it)->willDetachFrameHost();
+ // FIXME: Page should take care of updating focus/scrolling instead of Frame.
// FIXME: It's unclear as to why this is called more than once, but it is,
- // so page() could be NULL.
+ // so page() could be null.
if (page() && page()->focusController().focusedFrame() == this)
- page()->focusController().setFocusedFrame(0);
-
- if (page() && page()->scrollingCoordinator() && m_view)
- page()->scrollingCoordinator()->willDestroyScrollableArea(m_view.get());
-
- script().clearScriptObjects();
+ page()->focusController().setFocusedFrame(nullptr);
}
-void Frame::detachFromPage()
-{
- // We should never be detatching the page during a Layout.
- RELEASE_ASSERT(!m_view || !m_view->isInLayout());
- m_page = 0;
-}
-
-void Frame::disconnectOwnerElement()
+void Frame::detachFromFrameHost()
{
- if (ownerElement()) {
- if (Document* doc = document())
- doc->topDocument()->clearAXObjectCache();
- ownerElement()->clearContentFrame();
- if (m_page)
- m_page->decrementSubframeCount();
- }
- m_frameInit->setOwnerElement(0);
+ m_host = 0;
}
bool Frame::isMainFrame() const
{
- return m_page && this == m_page->mainFrame();
-}
-
-String Frame::documentTypeString() const
-{
- if (DocumentType* doctype = document()->doctype())
- return createMarkup(doctype);
-
- return String();
-}
-
-String Frame::selectedText() const
-{
- return selection().selectedText();
-}
-
-String Frame::selectedTextForClipboard() const
-{
- return selection().selectedTextForClipboard();
-}
-
-VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
-{
- HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint);
- Node* node = result.innerNonSharedNode();
- if (!node)
- return VisiblePosition();
- RenderObject* renderer = node->renderer();
- if (!renderer)
- return VisiblePosition();
- VisiblePosition visiblePos = VisiblePosition(renderer->positionForPoint(result.localPoint()));
- if (visiblePos.isNull())
- visiblePos = firstPositionInOrBeforeNode(node);
- return visiblePos;
-}
-
-Document* Frame::documentAtPoint(const IntPoint& point)
-{
- if (!view())
- return 0;
-
- IntPoint pt = view()->windowToContents(point);
- HitTestResult result = HitTestResult(pt);
-
- if (contentRenderer())
- result = eventHandler().hitTestResultAtPoint(pt, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
- return result.innerNode() ? &result.innerNode()->document() : 0;
-}
-
-PassRefPtr<Range> Frame::rangeForPoint(const IntPoint& framePoint)
-{
- VisiblePosition position = visiblePositionForPoint(framePoint);
- if (position.isNull())
- return 0;
-
- VisiblePosition previous = position.previous();
- if (previous.isNotNull()) {
- RefPtr<Range> previousCharacterRange = makeRange(previous, position);
- LayoutRect rect = editor().firstRectForRange(previousCharacterRange.get());
- if (rect.contains(framePoint))
- return previousCharacterRange.release();
- }
-
- VisiblePosition next = position.next();
- if (RefPtr<Range> nextCharacterRange = makeRange(position, next)) {
- LayoutRect rect = editor().firstRectForRange(nextCharacterRange.get());
- if (rect.contains(framePoint))
- return nextCharacterRange.release();
- }
-
- return 0;
-}
-
-void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor, bool transparent,
- ScrollbarMode horizontalScrollbarMode, bool horizontalLock,
- ScrollbarMode verticalScrollbarMode, bool verticalLock)
-{
- ASSERT(this);
- ASSERT(m_page);
-
- bool isMainFrame = this->isMainFrame();
-
- if (isMainFrame && view())
- view()->setParentVisible(false);
-
- setView(0);
-
- RefPtr<FrameView> frameView;
- if (isMainFrame) {
- frameView = FrameView::create(this, viewportSize);
-
- // The layout size is set by WebViewImpl to support @viewport
- frameView->setLayoutSizeFixedToFrameSize(false);
- } else
- frameView = FrameView::create(this);
-
- frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode, horizontalLock, verticalLock);
-
- setView(frameView);
-
- if (backgroundColor.isValid())
- frameView->updateBackgroundRecursively(backgroundColor, transparent);
-
- if (isMainFrame)
- frameView->setParentVisible(true);
-
- if (ownerRenderer())
- ownerRenderer()->setWidget(frameView);
-
- if (HTMLFrameOwnerElement* owner = ownerElement())
- view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
-}
-
-String Frame::layerTreeAsText(unsigned flags) const
-{
- document()->updateLayout();
-
- if (!contentRenderer())
- return String();
-
- return contentRenderer()->compositor()->layerTreeAsText(static_cast<LayerTreeFlags>(flags));
-}
-
-String Frame::trackedRepaintRectsAsText() const
-{
- if (!m_view)
- return String();
- return m_view->trackedRepaintRectsAsText();
-}
-
-void Frame::setPageZoomFactor(float factor)
-{
- setPageAndTextZoomFactors(factor, m_textZoomFactor);
-}
-
-void Frame::setTextZoomFactor(float factor)
-{
- setPageAndTextZoomFactors(m_pageZoomFactor, factor);
-}
-
-void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor)
-{
- if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
- return;
-
Page* page = this->page();
- if (!page)
- return;
-
- Document* document = this->document();
- if (!document)
- return;
-
- // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
- // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
- if (document->isSVGDocument()) {
- if (!toSVGDocument(document)->zoomAndPanEnabled())
- return;
- }
-
- if (m_pageZoomFactor != pageZoomFactor) {
- if (FrameView* view = this->view()) {
- // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
- LayoutPoint scrollPosition = view->scrollPosition();
- float percentDifference = (pageZoomFactor / m_pageZoomFactor);
- view->setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
- }
- }
-
- m_pageZoomFactor = pageZoomFactor;
- m_textZoomFactor = textZoomFactor;
-
- document->recalcStyle(Force);
-
- for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling())
- child->setPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor);
-
- if (FrameView* view = this->view()) {
- if (document->renderer() && document->renderer()->needsLayout() && view->didFirstLayout())
- view->layout();
- }
-}
-
-void Frame::deviceOrPageScaleFactorChanged()
-{
- document()->mediaQueryAffectingValueChanged();
- for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling())
- child->deviceOrPageScaleFactorChanged();
-}
-
-void Frame::notifyChromeClientWheelEventHandlerCountChanged() const
-{
- // Ensure that this method is being called on the main frame of the page.
- ASSERT(isMainFrame());
-
- unsigned count = 0;
- for (const Frame* frame = this; frame; frame = frame->tree().traverseNext()) {
- if (frame->document())
- count += WheelController::from(frame->document())->wheelEventHandlerCount();
- }
-
- m_page->chrome().client().numWheelEventHandlersChanged(count);
+ return page && this == page->mainFrame();
}
-bool Frame::isURLAllowed(const KURL& url) const
+void Frame::disconnectOwnerElement()
{
- // We allow one level of self-reference because some sites depend on that,
- // but we don't allow more than one.
- if (m_page->subframeCount() >= Page::maxNumberOfFrames)
- return false;
- bool foundSelfReference = false;
- for (const Frame* frame = this; frame; frame = frame->tree().parent()) {
- if (equalIgnoringFragmentIdentifier(frame->document()->url(), url)) {
- if (foundSelfReference)
- return false;
- foundSelfReference = true;
- }
+ if (m_owner) {
+ if (m_owner->isLocal())
+ toHTMLFrameOwnerElement(m_owner)->clearContentFrame();
+ if (page())
+ page()->decrementSubframeCount();
}
- return true;
-}
-
-struct ScopedFramePaintingState {
- ScopedFramePaintingState(Frame* frame, Node* node)
- : frame(frame)
- , node(node)
- , paintBehavior(frame->view()->paintBehavior())
- , backgroundColor(frame->view()->baseBackgroundColor())
- {
- ASSERT(!node || node->renderer());
- if (node)
- node->renderer()->updateDragState(true);
- }
-
- ~ScopedFramePaintingState()
- {
- if (node && node->renderer())
- node->renderer()->updateDragState(false);
- frame->view()->setPaintBehavior(paintBehavior);
- frame->view()->setBaseBackgroundColor(backgroundColor);
- frame->view()->setNodeToDraw(0);
- }
-
- Frame* frame;
- Node* node;
- PaintBehavior paintBehavior;
- Color backgroundColor;
-};
-
-PassOwnPtr<DragImage> Frame::nodeImage(Node* node)
-{
- if (!node->renderer())
- return nullptr;
-
- const ScopedFramePaintingState state(this, node);
-
- m_view->setPaintBehavior(state.paintBehavior | PaintBehaviorFlattenCompositingLayers);
-
- // When generating the drag image for an element, ignore the document background.
- m_view->setBaseBackgroundColor(Color::transparent);
- document()->updateLayout();
- m_view->setNodeToDraw(node); // Enable special sub-tree drawing mode.
-
- // Document::updateLayout may have blown away the original RenderObject.
- RenderObject* renderer = node->renderer();
- if (!renderer)
- return nullptr;
-
- LayoutRect topLevelRect;
- IntRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect));
-
- float deviceScaleFactor = 1;
- if (m_page)
- deviceScaleFactor = m_page->deviceScaleFactor();
- paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
- paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
-
- OwnPtr<ImageBuffer> buffer = ImageBuffer::create(paintingRect.size());
- if (!buffer)
- return nullptr;
- buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
- buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
- buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
-
- m_view->paintContents(buffer->context(), paintingRect);
-
- RefPtr<Image> image = buffer->copyImage();
- return DragImage::create(image.get(), renderer->shouldRespectImageOrientation(), deviceScaleFactor);
+ m_owner = 0;
}
-PassOwnPtr<DragImage> Frame::dragImageForSelection()
+HTMLFrameOwnerElement* Frame::deprecatedLocalOwner() const
{
- if (!selection().isRange())
- return nullptr;
-
- const ScopedFramePaintingState state(this, 0);
- m_view->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorFlattenCompositingLayers);
- document()->updateLayout();
-
- IntRect paintingRect = enclosingIntRect(selection().bounds());
-
- float deviceScaleFactor = 1;
- if (m_page)
- deviceScaleFactor = m_page->deviceScaleFactor();
- paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
- paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
-
- OwnPtr<ImageBuffer> buffer = ImageBuffer::create(paintingRect.size());
- if (!buffer)
- return nullptr;
- buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
- buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
- buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
-
- m_view->paintContents(buffer->context(), paintingRect);
-
- RefPtr<Image> image = buffer->copyImage();
- return DragImage::create(image.get(), DoNotRespectImageOrientation, deviceScaleFactor);
-}
-
-double Frame::devicePixelRatio() const
-{
- if (!m_page)
- return 0;
-
- double ratio = m_page->deviceScaleFactor();
- if (RuntimeEnabledFeatures::devicePixelRatioIncludesZoomEnabled())
- ratio *= pageZoomFactor();
- return ratio;
+ return m_owner && m_owner->isLocal() ? toHTMLFrameOwnerElement(m_owner) : 0;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/Frame.h b/chromium/third_party/WebKit/Source/core/frame/Frame.h
index 3c669f7db3d..c6cb1f96cfc 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Frame.h
+++ b/chromium/third_party/WebKit/Source/core/frame/Frame.h
@@ -28,13 +28,10 @@
#ifndef Frame_h
#define Frame_h
-#include "core/loader/FrameLoader.h"
-#include "core/loader/NavigationScheduler.h"
-#include "core/frame/AdjustViewSizeOrNot.h"
#include "core/page/FrameTree.h"
-#include "platform/geometry/IntSize.h"
-#include "platform/scroll/ScrollTypes.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
+#include "wtf/HashSet.h"
#include "wtf/RefCounted.h"
namespace blink {
@@ -43,295 +40,112 @@ class WebLayer;
namespace WebCore {
- class AnimationController;
- class ChromeClient;
- class Color;
- class DOMWindow;
- class Document;
- class DragImage;
- class Editor;
- class Element;
- class EventHandler;
- class FetchContext;
- class FloatSize;
- class FrameDestructionObserver;
- class FrameSelection;
- class FrameView;
- class HTMLFrameOwnerElement;
- class HTMLTableCellElement;
- class InputMethodController;
- class IntPoint;
- class Node;
- class Range;
- class RenderPart;
- class RenderView;
- class TreeScope;
- class ScriptController;
- class Settings;
- class SpellChecker;
- class TreeScope;
- class VisiblePosition;
- class Widget;
-
- class FrameInit : public RefCounted<FrameInit> {
- public:
- // For creating a dummy Frame
- static PassRefPtr<FrameInit> create(int64_t frameID, Page* page, FrameLoaderClient* client)
- {
- return adoptRef(new FrameInit(frameID, page, client));
- }
-
- void setFrameLoaderClient(FrameLoaderClient* client) { m_client = client; }
- FrameLoaderClient* frameLoaderClient() const { return m_client; }
-
- int64_t frameID() const { return m_frameID; }
-
- void setPage(Page* page) { m_page = page; }
- Page* page() const { return m_page; }
-
- void setOwnerElement(HTMLFrameOwnerElement* ownerElement) { m_ownerElement = ownerElement; }
- HTMLFrameOwnerElement* ownerElement() const { return m_ownerElement; }
-
- protected:
- FrameInit(int64_t frameID, Page* page = 0, FrameLoaderClient* client = 0)
- : m_frameID(frameID)
- , m_client(client)
- , m_page(page)
- , m_ownerElement(0)
- {
- }
-
- private:
- int64_t m_frameID;
- FrameLoaderClient* m_client;
- Page* m_page;
- HTMLFrameOwnerElement* m_ownerElement;
- };
-
- class Frame : public RefCounted<Frame> {
- public:
- static PassRefPtr<Frame> create(PassRefPtr<FrameInit>);
-
- void init();
- void setView(PassRefPtr<FrameView>);
- void createView(const IntSize&, const Color&, bool,
- ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
- ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
-
- ~Frame();
-
- void addDestructionObserver(FrameDestructionObserver*);
- void removeDestructionObserver(FrameDestructionObserver*);
-
- void willDetachPage();
- void detachFromPage();
- void disconnectOwnerElement();
-
- Page* page() const;
- HTMLFrameOwnerElement* ownerElement() const;
- bool isMainFrame() const;
-
- void setDOMWindow(PassRefPtr<DOMWindow>);
- DOMWindow* domWindow() const;
- Document* document() const;
- FrameView* view() const;
-
- ChromeClient& chromeClient() const;
- Editor& editor() const;
- EventHandler& eventHandler() const;
- FrameLoader& loader() const;
- NavigationScheduler& navigationScheduler() const;
- FrameSelection& selection() const;
- FrameTree& tree() const;
- AnimationController& animation() const;
- InputMethodController& inputMethodController() const;
- FetchContext& fetchContext() const { return loader().fetchContext(); }
- ScriptController& script();
- SpellChecker& spellChecker() const;
-
- RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame.
- RenderPart* ownerRenderer() const; // Renderer for the element that contains this frame.
-
- void dispatchVisibilityStateChangeEvent();
-
- int64_t frameID() const { return m_frameInit->frameID(); }
-
- void setRemotePlatformLayer(blink::WebLayer* remotePlatformLayer) { m_remotePlatformLayer = remotePlatformLayer; }
- blink::WebLayer* remotePlatformLayer() const { return m_remotePlatformLayer; }
-
- // ======== All public functions below this point are candidates to move out of Frame into another class. ========
-
- bool inScope(TreeScope*) const;
-
- // See GraphicsLayerClient.h for accepted flags.
- String layerTreeAsText(unsigned flags = 0) const;
- String trackedRepaintRectsAsText() const;
+class ChromeClient;
+class FrameClient;
+class FrameDestructionObserver;
+class FrameHost;
+class FrameOwner;
+class HTMLFrameOwnerElement;
+class LocalDOMWindow;
+class Page;
+class RenderPart;
+class Settings;
- Settings* settings() const; // can be NULL
+class Frame : public RefCounted<Frame> {
+public:
+ virtual bool isLocalFrame() const { return false; }
+ virtual bool isRemoteFrame() const { return false; }
- void setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot);
- bool shouldUsePrintingLayout() const;
- FloatSize resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize);
+ virtual ~Frame();
- bool inViewSourceMode() const;
- void setInViewSourceMode(bool = true);
+ void addDestructionObserver(FrameDestructionObserver*);
+ void removeDestructionObserver(FrameDestructionObserver*);
- void setPageZoomFactor(float factor);
- float pageZoomFactor() const { return m_pageZoomFactor; }
- void setTextZoomFactor(float factor);
- float textZoomFactor() const { return m_textZoomFactor; }
- void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);
+ virtual void willDetachFrameHost();
+ virtual void detachFromFrameHost();
- void deviceOrPageScaleFactorChanged();
- double devicePixelRatio() const;
+ FrameClient* client() const;
+ void clearClient();
-#if ENABLE(ORIENTATION_EVENTS)
- // Orientation is the interface orientation in degrees. Some examples are:
- // 0 is straight up; -90 is when the device is rotated 90 clockwise;
- // 90 is when rotated counter clockwise.
- void sendOrientationChangeEvent(int orientation);
- int orientation() const { return m_orientation; }
-#endif
-
- String documentTypeString() const;
-
- PassOwnPtr<DragImage> nodeImage(Node*);
- PassOwnPtr<DragImage> dragImageForSelection();
+ // NOTE: Page is moving out of Blink up into the browser process as
+ // part of the site-isolation (out of process iframes) work.
+ // FrameHost should be used instead where possible.
+ Page* page() const;
+ FrameHost* host() const; // Null when the frame is detached.
- String selectedText() const;
- String selectedTextForClipboard() const;
+ bool isMainFrame() const;
- VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
- Document* documentAtPoint(const IntPoint& windowPoint);
- PassRefPtr<Range> rangeForPoint(const IntPoint& framePoint);
+ virtual void disconnectOwnerElement();
- // Should only be called on the main frame of a page.
- void notifyChromeClientWheelEventHandlerCountChanged() const;
+ FrameOwner* owner() const;
+ HTMLFrameOwnerElement* deprecatedLocalOwner() const;
- bool isURLAllowed(const KURL&) const;
+ // FIXME: LocalDOMWindow and Document should both be moved to LocalFrame
+ // after RemoteFrame is complete enough to exist without them.
+ virtual void setDOMWindow(PassRefPtrWillBeRawPtr<LocalDOMWindow>);
+ LocalDOMWindow* domWindow() const;
- // ========
+ FrameTree& tree() const;
+ ChromeClient& chromeClient() const;
- private:
- Frame(PassRefPtr<FrameInit>);
+ RenderPart* ownerRenderer() const; // Renderer for the element that contains this frame.
- HashSet<FrameDestructionObserver*> m_destructionObservers;
+ // FIXME: These should move to RemoteFrame when that is instantiated.
+ void setRemotePlatformLayer(blink::WebLayer* remotePlatformLayer) { m_remotePlatformLayer = remotePlatformLayer; }
+ blink::WebLayer* remotePlatformLayer() const { return m_remotePlatformLayer; }
- Page* m_page;
- mutable FrameTree m_treeNode;
- mutable FrameLoader m_loader;
- mutable NavigationScheduler m_navigationScheduler;
+ Settings* settings() const; // can be null
- RefPtr<FrameView> m_view;
- RefPtr<DOMWindow> m_domWindow;
-
- OwnPtr<ScriptController> m_script;
- const OwnPtr<Editor> m_editor;
- const OwnPtr<SpellChecker> m_spellChecker;
- const OwnPtr<FrameSelection> m_selection;
- const OwnPtr<EventHandler> m_eventHandler;
- OwnPtr<AnimationController> m_animationController;
- OwnPtr<InputMethodController> m_inputMethodController;
-
- RefPtr<FrameInit> m_frameInit;
-
- float m_pageZoomFactor;
- float m_textZoomFactor;
-
-#if ENABLE(ORIENTATION_EVENTS)
- int m_orientation;
-#endif
+ // FIXME: This method identifies a LocalFrame that is acting as a RemoteFrame.
+ // It is necessary only until we can instantiate a RemoteFrame, at which point
+ // it can be removed and its callers can be converted to use the isRemoteFrame()
+ // method.
+ bool isRemoteFrameTemporary() const { return m_remotePlatformLayer; }
- bool m_inViewSourceMode;
+protected:
+ Frame(FrameClient*, FrameHost*, FrameOwner*);
- blink::WebLayer* m_remotePlatformLayer;
- };
+ mutable FrameTree m_treeNode;
- inline void Frame::init()
- {
- m_loader.init();
- }
+ FrameHost* m_host;
+ FrameOwner* m_owner;
- inline FrameLoader& Frame::loader() const
- {
- return m_loader;
- }
-
- inline NavigationScheduler& Frame::navigationScheduler() const
- {
- return m_navigationScheduler;
- }
-
- inline FrameView* Frame::view() const
- {
- return m_view.get();
- }
-
- inline ScriptController& Frame::script()
- {
- return *m_script;
- }
-
- inline DOMWindow* Frame::domWindow() const
- {
- return m_domWindow.get();
- }
-
- inline FrameSelection& Frame::selection() const
- {
- return *m_selection;
- }
-
- inline Editor& Frame::editor() const
- {
- return *m_editor;
- }
-
- inline SpellChecker& Frame::spellChecker() const
- {
- return *m_spellChecker;
- }
-
- inline AnimationController& Frame::animation() const
- {
- return *m_animationController;
- }
-
- inline InputMethodController& Frame::inputMethodController() const
- {
- return *m_inputMethodController;
- }
-
- inline HTMLFrameOwnerElement* Frame::ownerElement() const
- {
- return m_frameInit->ownerElement();
- }
-
- inline bool Frame::inViewSourceMode() const
- {
- return m_inViewSourceMode;
- }
-
- inline void Frame::setInViewSourceMode(bool mode)
- {
- m_inViewSourceMode = mode;
- }
-
- inline FrameTree& Frame::tree() const
- {
- return m_treeNode;
- }
-
- inline Page* Frame::page() const
- {
- return m_page;
- }
-
- inline EventHandler& Frame::eventHandler() const
- {
- ASSERT(m_eventHandler);
- return *m_eventHandler;
- }
+ RefPtrWillBePersistent<LocalDOMWindow> m_domWindow;
+
+private:
+ FrameClient* m_client;
+ HashSet<FrameDestructionObserver*> m_destructionObservers;
+
+ blink::WebLayer* m_remotePlatformLayer;
+};
+
+inline FrameClient* Frame::client() const
+{
+ return m_client;
+}
+
+inline void Frame::clearClient()
+{
+ m_client = 0;
+}
+
+inline LocalDOMWindow* Frame::domWindow() const
+{
+ return m_domWindow.get();
+}
+
+inline FrameOwner* Frame::owner() const
+{
+ return m_owner;
+}
+
+inline FrameTree& Frame::tree() const
+{
+ return m_treeNode;
+}
+
+// Allow equality comparisons of Frames by reference or pointer, interchangeably.
+DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES_REFCOUNTED(Frame)
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameClient.h b/chromium/third_party/WebKit/Source/core/frame/FrameClient.h
new file mode 100644
index 00000000000..79968742ec1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameClient.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FrameClient_h
+#define FrameClient_h
+
+namespace WebCore {
+
+class Frame;
+
+class FrameClient {
+public:
+ virtual Frame* opener() const = 0;
+ virtual void setOpener(Frame*) = 0;
+
+ virtual Frame* parent() const = 0;
+ virtual Frame* top() const = 0;
+ virtual Frame* previousSibling() const = 0;
+ virtual Frame* nextSibling() const = 0;
+ virtual Frame* firstChild() const = 0;
+ virtual Frame* lastChild() const = 0;
+
+ virtual ~FrameClient() { }
+};
+
+} // namespace WebCore
+
+#endif // FrameClient_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameConsole.cpp b/chromium/third_party/WebKit/Source/core/frame/FrameConsole.cpp
new file mode 100644
index 00000000000..bc1a1106605
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameConsole.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/frame/FrameConsole.h"
+
+#include "core/dom/Document.h"
+#include "core/frame/FrameHost.h"
+#include "core/inspector/ConsoleAPITypes.h"
+#include "core/inspector/InspectorConsoleInstrumentation.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
+#include "wtf/text/StringBuilder.h"
+
+namespace WebCore {
+
+namespace {
+
+int muteCount = 0;
+
+}
+
+FrameConsole::FrameConsole(LocalFrame& frame)
+ : m_frame(frame)
+{
+}
+
+void FrameConsole::addMessage(MessageSource source, MessageLevel level, const String& message)
+{
+ addMessage(source, level, message, String(), 0, 0, nullptr, 0, 0);
+}
+
+void FrameConsole::addMessage(MessageSource source, MessageLevel level, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
+{
+ addMessage(source, level, message, String(), 0, 0, callStack, 0);
+}
+
+void FrameConsole::addMessage(MessageSource source, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, ScriptState* scriptState, unsigned long requestIdentifier)
+{
+ if (muteCount)
+ return;
+
+ // FIXME: This should not need to reach for the main-frame.
+ // Inspector code should just take the current frame and know how to walk itself.
+ ExecutionContext* context = m_frame.document();
+ if (!context)
+ return;
+
+ String messageURL;
+ if (callStack) {
+ messageURL = callStack->at(0).sourceURL();
+ InspectorInstrumentation::addMessageToConsole(context, source, LogMessageType, level, message, callStack, requestIdentifier);
+ } else {
+ messageURL = url;
+ InspectorInstrumentation::addMessageToConsole(context, source, LogMessageType, level, message, url, lineNumber, columnNumber, scriptState, requestIdentifier);
+ }
+
+ if (source == CSSMessageSource)
+ return;
+
+ String stackTrace;
+ if (callStack && m_frame.chromeClient().shouldReportDetailedMessageForSource(messageURL))
+ stackTrace = FrameConsole::formatStackTraceString(message, callStack);
+
+ m_frame.chromeClient().addMessageToConsole(&m_frame, source, level, message, lineNumber, messageURL, stackTrace);
+}
+
+String FrameConsole::formatStackTraceString(const String& originalMessage, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
+{
+ StringBuilder stackTrace;
+ for (size_t i = 0; i < callStack->size(); ++i) {
+ const ScriptCallFrame& frame = callStack->at(i);
+ stackTrace.append("\n at " + (frame.functionName().length() ? frame.functionName() : "(anonymous function)"));
+ stackTrace.append(" (");
+ stackTrace.append(frame.sourceURL());
+ stackTrace.append(':');
+ stackTrace.append(String::number(frame.lineNumber()));
+ stackTrace.append(':');
+ stackTrace.append(String::number(frame.columnNumber()));
+ stackTrace.append(')');
+ }
+
+ return stackTrace.toString();
+}
+
+void FrameConsole::mute()
+{
+ muteCount++;
+}
+
+void FrameConsole::unmute()
+{
+ ASSERT(muteCount > 0);
+ muteCount--;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameConsole.h b/chromium/third_party/WebKit/Source/core/frame/FrameConsole.h
new file mode 100644
index 00000000000..05146e003d3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameConsole.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FrameConsole_h
+#define FrameConsole_h
+
+#include "bindings/v8/ScriptState.h"
+#include "core/frame/ConsoleTypes.h"
+#include "core/inspector/ScriptCallStack.h"
+#include "wtf/Forward.h"
+#include "wtf/PassOwnPtr.h"
+
+namespace WebCore {
+
+class FrameHost;
+
+// FrameConsole takes per-frame console messages and routes them up through the FrameHost to the ChromeClient and Inspector.
+// It's meant as an abstraction around ChromeClient calls and the way that Blink core/ can add messages to the console.
+class FrameConsole FINAL {
+public:
+ static PassOwnPtr<FrameConsole> create(LocalFrame& frame) { return adoptPtr(new FrameConsole(frame)); }
+
+ void addMessage(MessageSource, MessageLevel, const String& message);
+ void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber = 0, PassRefPtrWillBeRawPtr<ScriptCallStack> = nullptr, ScriptState* = 0, unsigned long requestIdentifier = 0);
+ void addMessage(MessageSource, MessageLevel, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack>);
+ static String formatStackTraceString(const String& originalMessage, PassRefPtrWillBeRawPtr<ScriptCallStack>);
+
+ static void mute();
+ static void unmute();
+
+private:
+ explicit FrameConsole(LocalFrame&);
+
+ LocalFrame& m_frame;
+};
+
+} // namespace WebCore
+
+#endif // FrameConsole_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.cpp b/chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.cpp
index ea3923e5cdc..7ab5868c9a4 100644
--- a/chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.cpp
@@ -26,11 +26,11 @@
#include "config.h"
#include "core/frame/FrameDestructionObserver.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-FrameDestructionObserver::FrameDestructionObserver(Frame* frame)
+FrameDestructionObserver::FrameDestructionObserver(LocalFrame* frame)
: m_frame(0)
{
observeFrame(frame);
@@ -42,7 +42,7 @@ FrameDestructionObserver::~FrameDestructionObserver()
}
-void FrameDestructionObserver::observeFrame(Frame* frame)
+void FrameDestructionObserver::observeFrame(LocalFrame* frame)
{
if (m_frame)
m_frame->removeDestructionObserver(this);
@@ -58,7 +58,7 @@ void FrameDestructionObserver::frameDestroyed()
m_frame = 0;
}
-void FrameDestructionObserver::willDetachPage()
+void FrameDestructionObserver::willDetachFrameHost()
{
// Subclasses should override this function to handle this notification.
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.h b/chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.h
index 8989e4a9f53..db7341f1dae 100644
--- a/chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.h
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameDestructionObserver.h
@@ -28,22 +28,22 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class FrameDestructionObserver {
public:
- explicit FrameDestructionObserver(Frame*);
+ explicit FrameDestructionObserver(LocalFrame*);
virtual void frameDestroyed();
- virtual void willDetachPage();
+ virtual void willDetachFrameHost();
- Frame* frame() const { return m_frame; }
+ LocalFrame* frame() const { return m_frame; }
protected:
virtual ~FrameDestructionObserver();
- void observeFrame(Frame*);
+ void observeFrame(LocalFrame*);
- Frame* m_frame;
+ LocalFrame* m_frame;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameHost.cpp b/chromium/third_party/WebKit/Source/core/frame/FrameHost.cpp
new file mode 100644
index 00000000000..cc562c9076f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameHost.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/frame/FrameHost.h"
+
+#include "core/frame/EventHandlerRegistry.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<FrameHost> FrameHost::create(Page& page)
+{
+ return adoptPtrWillBeNoop(new FrameHost(page));
+}
+
+FrameHost::FrameHost(Page& page)
+ : m_page(&page)
+ , m_pinchViewport(adoptPtr(new PinchViewport(*this)))
+ , m_eventHandlerRegistry(adoptPtrWillBeNoop(new EventHandlerRegistry(*this)))
+{
+}
+
+// Explicitly in the .cpp to avoid default constructor in .h
+FrameHost::~FrameHost()
+{
+}
+
+Settings& FrameHost::settings() const
+{
+ return m_page->settings();
+}
+
+Chrome& FrameHost::chrome() const
+{
+ return m_page->chrome();
+}
+
+UseCounter& FrameHost::useCounter() const
+{
+ return m_page->useCounter();
+}
+
+float FrameHost::deviceScaleFactor() const
+{
+ return m_page->deviceScaleFactor();
+}
+
+PinchViewport& FrameHost::pinchViewport() const
+{
+ return *m_pinchViewport;
+}
+
+EventHandlerRegistry& FrameHost::eventHandlerRegistry() const
+{
+ return *m_eventHandlerRegistry;
+}
+
+void FrameHost::trace(Visitor* visitor)
+{
+ visitor->trace(m_page);
+ visitor->trace(m_eventHandlerRegistry);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameHost.h b/chromium/third_party/WebKit/Source/core/frame/FrameHost.h
new file mode 100644
index 00000000000..494e17161d9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameHost.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FrameHost_h
+#define FrameHost_h
+
+#include "core/frame/PinchViewport.h"
+#include "platform/heap/Handle.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+
+namespace WebCore {
+
+class Chrome;
+class EventHandlerRegistry;
+class Page;
+class PinchViewport;
+class Settings;
+class UseCounter;
+class Visitor;
+
+// FrameHost is the set of global data shared between multiple frames
+// and is provided by the embedder to each frame when created.
+// FrameHost currently corresponds to the Page object in core/page
+// however the concept of a Page is moving up out of Blink.
+// In an out-of-process iframe world, a single Page may have
+// multiple frames in different process, thus Page becomes a
+// browser-level concept and Blink core/ only knows about its LocalFrame (and FrameHost).
+// Separating Page from the rest of core/ through this indirection
+// allows us to slowly refactor Page without breaking the rest of core.
+class FrameHost FINAL : public NoBaseWillBeGarbageCollectedFinalized<FrameHost> {
+ WTF_MAKE_NONCOPYABLE(FrameHost); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+ static PassOwnPtrWillBeRawPtr<FrameHost> create(Page&);
+ ~FrameHost();
+
+ // Careful: This function will eventually be removed.
+ Page& page() const { return *m_page; }
+ Settings& settings() const;
+ Chrome& chrome() const;
+ UseCounter& useCounter() const;
+
+ // Corresponds to pixel density of the device where this Page is
+ // being displayed. In multi-monitor setups this can vary between pages.
+ // This value does not account for Page zoom, use LocalFrame::devicePixelRatio instead.
+ float deviceScaleFactor() const;
+
+ PinchViewport& pinchViewport() const;
+ EventHandlerRegistry& eventHandlerRegistry() const;
+
+ void trace(Visitor*);
+
+private:
+ explicit FrameHost(Page&);
+
+ RawPtrWillBeMember<Page> m_page;
+ const OwnPtr<PinchViewport> m_pinchViewport;
+ const OwnPtrWillBeMember<EventHandlerRegistry> m_eventHandlerRegistry;
+};
+
+}
+
+#endif // FrameHost_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameOwner.h b/chromium/third_party/WebKit/Source/core/frame/FrameOwner.h
new file mode 100644
index 00000000000..f8c7d1d7788
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameOwner.h
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FrameOwner_h
+#define FrameOwner_h
+
+#include "core/dom/SandboxFlags.h"
+
+namespace WebCore {
+
+class FrameOwner {
+public:
+ virtual ~FrameOwner() { }
+
+ virtual bool isLocal() const = 0;
+
+ virtual SandboxFlags sandboxFlags() const = 0;
+ virtual void dispatchLoad() = 0;
+};
+
+} // namespace WebCore
+
+#endif // FrameOwner_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameView.cpp b/chromium/third_party/WebKit/Source/core/frame/FrameView.cpp
index 5bb9474eec3..c7e788df777 100644
--- a/chromium/third_party/WebKit/Source/core/frame/FrameView.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -27,26 +27,24 @@
#include "config.h"
#include "core/frame/FrameView.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
-#include "core/animation/DocumentAnimations.h"
#include "core/css/FontFaceSet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/DocumentMarkerController.h"
+#include "core/dom/ScriptForbiddenScope.h"
#include "core/editing/FrameSelection.h"
#include "core/events/OverflowEvent.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ResourceLoadPriorityOptimizer.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/frame/Frame.h"
-#include "core/frame/GraphicsLayerDebugInfo.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
-#include "core/frame/animation/AnimationController.h"
#include "core/html/HTMLFrameElement.h"
-#include "core/html/HTMLHtmlElement.h"
#include "core/html/HTMLPlugInElement.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/page/Chrome.h"
@@ -55,26 +53,30 @@
#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/CompositedLayerMapping.h"
-#include "core/rendering/LayoutIndicator.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/RenderCounter.h"
#include "core/rendering/RenderEmbeddedObject.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
+#include "core/rendering/RenderListBox.h"
#include "core/rendering/RenderPart.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/RenderScrollbarPart.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/RenderWidget.h"
#include "core/rendering/TextAutosizer.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/svg/RenderSVGRoot.h"
-#include "core/svg/SVGDocument.h"
+#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGSVGElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "platform/fonts/FontCache.h"
#include "platform/geometry/FloatRect.h"
#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/GraphicsLayerDebugInfo.h"
#include "platform/scroll/ScrollAnimator.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "platform/text/TextStream.h"
@@ -88,88 +90,26 @@ using namespace HTMLNames;
double FrameView::s_currentFrameTimeStamp = 0.0;
bool FrameView::s_inPaintContents = false;
-
-// REPAINT_THROTTLING now chooses default values for throttling parameters.
-// Should be removed when applications start using runtime configuration.
-#if ENABLE(REPAINT_THROTTLING)
-// Normal delay
-double FrameView::s_normalDeferredRepaintDelay = 0.016;
-// Negative value would mean that first few repaints happen without a delay
-double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
-// The delay grows on each repaint to this maximum value
-double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5;
-// On each repaint the delay increses by this amount
-double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5;
-#else
-// FIXME: Repaint throttling could be good to have on all platform.
-// The balance between CPU use and repaint frequency will need some tuning for desktop.
-// More hooks may be needed to reset the delay on things like GIF and CSS animations.
-double FrameView::s_normalDeferredRepaintDelay = 0;
-double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
-double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
-double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
-#endif
-
// The maximum number of updateWidgets iterations that should be done before returning.
static const unsigned maxUpdateWidgetsIterations = 2;
+static const double resourcePriorityUpdateDelayAfterScroll = 0.250;
-static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullRepaint)
+static RenderLayer::UpdateLayerPositionsFlags updateLayerPositionFlags(RenderLayer* layer, bool isRelayoutingSubtree, bool didFullPaintInvalidation)
{
- RenderLayer::UpdateLayerPositionsFlags flags = RenderLayer::defaultFlags;
+ RenderLayer::UpdateLayerPositionsFlags flags = didFullPaintInvalidation ? RenderLayer::NeedsFullRepaintInBacking : RenderLayer::CheckForRepaint;
- if (didFullRepaint) {
- flags &= ~RenderLayer::CheckForRepaint;
- flags |= RenderLayer::NeedsFullRepaintInBacking;
- }
- if (isRelayoutingSubtree && layer->isPaginated())
+ if (isRelayoutingSubtree && (layer->isPaginated() || layer->enclosingPaginationLayer()))
flags |= RenderLayer::UpdatePagination;
- return flags;
-}
-
-Pagination::Mode paginationModeForRenderStyle(RenderStyle* style)
-{
- EOverflow overflow = style->overflowY();
- if (overflow != OPAGEDX && overflow != OPAGEDY)
- return Pagination::Unpaginated;
-
- bool isHorizontalWritingMode = style->isHorizontalWritingMode();
- TextDirection textDirection = style->direction();
- WritingMode writingMode = style->writingMode();
- // paged-x always corresponds to LeftToRightPaginated or RightToLeftPaginated. If the WritingMode
- // is horizontal, then we use TextDirection to choose between those options. If the WritingMode
- // is vertical, then the direction of the verticality dictates the choice.
- if (overflow == OPAGEDX) {
- if ((isHorizontalWritingMode && textDirection == LTR) || writingMode == LeftToRightWritingMode)
- return Pagination::LeftToRightPaginated;
- return Pagination::RightToLeftPaginated;
- }
-
- // paged-y always corresponds to TopToBottomPaginated or BottomToTopPaginated. If the WritingMode
- // is horizontal, then the direction of the horizontality dictates the choice. If the WritingMode
- // is vertical, then we use TextDirection to choose between those options.
- if (writingMode == TopToBottomWritingMode || (!isHorizontalWritingMode && textDirection == RTL))
- return Pagination::TopToBottomPaginated;
- return Pagination::BottomToTopPaginated;
-}
-
-FrameView::DeferredRepaintScope::DeferredRepaintScope(FrameView& view)
- : m_view(&view)
-{
- m_view->beginDeferredRepaints();
-}
-
-FrameView::DeferredRepaintScope::~DeferredRepaintScope()
-{
- m_view->endDeferredRepaints();
+ return flags;
}
-FrameView::FrameView(Frame* frame)
+FrameView::FrameView(LocalFrame* frame)
: m_frame(frame)
, m_canHaveScrollbars(true)
, m_slowRepaintObjectCount(0)
- , m_layoutTimer(this, &FrameView::layoutTimerFired)
- , m_layoutRoot(0)
+ , m_hasPendingLayout(false)
+ , m_layoutSubtreeRoot(0)
, m_inSynchronousPostLayout(false)
, m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
, m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired)
@@ -181,9 +121,7 @@ FrameView::FrameView(Frame* frame)
, m_wasScrolledByUser(false)
, m_inProgrammaticScroll(false)
, m_safeToPropagateScrollToParent(true)
- , m_deferredRepaintTimer(this, &FrameView::deferredRepaintTimerFired)
- , m_isTrackingRepaints(false)
- , m_shouldUpdateWhileOffscreen(true)
+ , m_isTrackingPaintInvalidations(false)
, m_scrollCorner(0)
, m_shouldAutoSize(false)
, m_inAutoSize(false)
@@ -191,27 +129,27 @@ FrameView::FrameView(Frame* frame)
, m_hasSoftwareFilters(false)
, m_visibleContentScaleFactor(1)
, m_inputEventsScaleFactorForEmulation(1)
- , m_partialLayout()
, m_layoutSizeFixedToFrameSize(true)
+ , m_didScrollTimer(this, &FrameView::didScrollTimerFired)
{
ASSERT(m_frame);
init();
- if (!isMainFrame())
+ if (!m_frame->isMainFrame())
return;
ScrollableArea::setVerticalScrollElasticity(ScrollElasticityAllowed);
ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
}
-PassRefPtr<FrameView> FrameView::create(Frame* frame)
+PassRefPtr<FrameView> FrameView::create(LocalFrame* frame)
{
RefPtr<FrameView> view = adoptRef(new FrameView(frame));
view->show();
return view.release();
}
-PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize)
+PassRefPtr<FrameView> FrameView::create(LocalFrame* frame, const IntSize& initialSize)
{
RefPtr<FrameView> view = adoptRef(new FrameView(frame));
view->Widget::setFrameRect(IntRect(view->location(), initialSize));
@@ -226,6 +164,9 @@ FrameView::~FrameView()
if (m_postLayoutTasksTimer.isActive())
m_postLayoutTasksTimer.stop();
+ if (m_didScrollTimer.isActive())
+ m_didScrollTimer.stop();
+
removeFromAXObjectCache();
resetScrollbars();
@@ -240,9 +181,10 @@ FrameView::~FrameView()
ASSERT(m_frame);
ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
- RenderPart* renderer = m_frame->ownerRenderer();
- if (renderer && renderer->widget() == this)
- renderer->setWidget(0);
+ // FIXME: Do we need to do something here for OOPI?
+ HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
+ if (ownerElement && ownerElement->ownedWidget() == this)
+ ownerElement->setWidget(nullptr);
}
void FrameView::reset()
@@ -250,15 +192,12 @@ void FrameView::reset()
m_cannotBlitToWindow = false;
m_isOverlapped = false;
m_contentIsOpaque = false;
- m_borderX = 30;
- m_borderY = 30;
- m_layoutTimer.stop();
- m_layoutRoot = 0;
- m_delayedLayout = false;
- m_doFullRepaint = true;
+ m_hasPendingLayout = false;
+ m_layoutSubtreeRoot = 0;
+ m_doFullPaintInvalidation = false;
m_layoutSchedulingEnabled = true;
- m_inLayout = false;
- m_doingPreLayoutStyleUpdate = false;
+ m_inPerformLayout = false;
+ m_canInvalidatePaintDuringPerformLayout = false;
m_inSynchronousPostLayout = false;
m_layoutCount = 0;
m_nestedLayoutCount = 0;
@@ -270,13 +209,8 @@ void FrameView::reset()
m_safeToPropagateScrollToParent = true;
m_lastViewportSize = IntSize();
m_lastZoomFactor = 1.0f;
- m_deferringRepaints = 0;
- m_repaintCount = 0;
- m_repaintRects.clear();
- m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading;
- m_deferredRepaintTimer.stop();
- m_isTrackingRepaints = false;
- m_trackedRepaintRects.clear();
+ m_isTrackingPaintInvalidations = false;
+ m_trackedPaintInvalidationRects.clear();
m_lastPaintTime = 0;
m_paintBehavior = PaintBehaviorNormal;
m_isPainting = false;
@@ -284,8 +218,7 @@ void FrameView::reset()
m_visuallyNonEmptyPixelCount = 0;
m_isVisuallyNonEmpty = false;
m_firstVisuallyNonEmptyLayoutCallbackPending = true;
- m_maintainScrollPositionAnchor = 0;
- m_partialLayout.reset();
+ m_maintainScrollPositionAnchor = nullptr;
m_viewportConstrainedObjects.clear();
}
@@ -311,27 +244,21 @@ void FrameView::init()
{
reset();
- m_margins = LayoutSize(-1, -1); // undefined
m_size = LayoutSize();
// Propagate the marginwidth/height and scrolling modes to the view.
- Element* ownerElement = m_frame->ownerElement();
- if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
+ // FIXME: Do we need to do this for OOPI?
+ Element* ownerElement = m_frame->deprecatedLocalOwner();
+ if (ownerElement && (isHTMLFrameElement(*ownerElement) || isHTMLIFrameElement(*ownerElement))) {
HTMLFrameElementBase* frameElt = toHTMLFrameElementBase(ownerElement);
if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
setCanHaveScrollbars(false);
- LayoutUnit marginWidth = frameElt->marginWidth();
- LayoutUnit marginHeight = frameElt->marginHeight();
- if (marginWidth != -1)
- setMarginWidth(marginWidth);
- if (marginHeight != -1)
- setMarginHeight(marginHeight);
}
}
void FrameView::prepareForDetach()
{
- RELEASE_ASSERT(!isInLayout());
+ RELEASE_ASSERT(!isInPerformLayout());
if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
scrollAnimator->cancelAnimations();
@@ -369,15 +296,13 @@ void FrameView::recalculateScrollbarOverlayStyle()
ScrollbarOverlayStyle overlayStyle = ScrollbarOverlayStyleDefault;
Color backgroundColor = documentBackgroundColor();
- if (backgroundColor.isValid()) {
- // Reduce the background color from RGB to a lightness value
- // and determine which scrollbar style to use based on a lightness
- // heuristic.
- double hue, saturation, lightness;
- backgroundColor.getHSL(hue, saturation, lightness);
- if (lightness <= .5)
- overlayStyle = ScrollbarOverlayStyleLight;
- }
+ // Reduce the background color from RGB to a lightness value
+ // and determine which scrollbar style to use based on a lightness
+ // heuristic.
+ double hue, saturation, lightness;
+ backgroundColor.getHSL(hue, saturation, lightness);
+ if (lightness <= .5)
+ overlayStyle = ScrollbarOverlayStyleLight;
if (oldOverlayStyle != overlayStyle)
setScrollbarOverlayStyle(overlayStyle);
@@ -385,13 +310,7 @@ void FrameView::recalculateScrollbarOverlayStyle()
void FrameView::clear()
{
- setCanBlitOnScroll(true);
-
reset();
-
- if (RenderPart* renderer = m_frame->ownerRenderer())
- renderer->viewCleared();
-
setScrollbarsSuppressed(true);
}
@@ -412,10 +331,10 @@ void FrameView::invalidateRect(const IntRect& rect)
if (!renderer)
return;
- IntRect repaintRect = rect;
- repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
+ IntRect paintInvalidationRect = rect;
+ paintInvalidationRect.move(renderer->borderLeft() + renderer->paddingLeft(),
renderer->borderTop() + renderer->paddingTop());
- renderer->repaintRectangle(repaintRect);
+ renderer->invalidatePaintRectangle(paintInvalidationRect);
}
void FrameView::setFrameRect(const IntRect& newRect)
@@ -425,12 +344,14 @@ void FrameView::setFrameRect(const IntRect& newRect)
return;
// Autosized font sizes depend on the width of the viewing area.
+ bool autosizerNeedsUpdating = false;
if (newRect.width() != oldRect.width()) {
- Page* page = m_frame->page();
- if (isMainFrame() && page->settings().textAutosizingEnabled()) {
- TextAutosizer* textAutosizer = m_frame->document()->textAutosizer();
- if (textAutosizer) {
- for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
+ if (m_frame->isMainFrame() && m_frame->settings()->textAutosizingEnabled()) {
+ autosizerNeedsUpdating = true;
+ for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (TextAutosizer* textAutosizer = toLocalFrame(frame)->document()->textAutosizer())
textAutosizer->recalculateMultipliers();
}
}
@@ -440,10 +361,23 @@ void FrameView::setFrameRect(const IntRect& newRect)
updateScrollableAreaSet();
+ if (autosizerNeedsUpdating) {
+ // This needs to be after the call to ScrollView::setFrameRect, because it reads the new width.
+ if (FastTextAutosizer* textAutosizer = m_frame->document()->fastTextAutosizer())
+ textAutosizer->updatePageInfoInAllFrames();
+ }
+
if (RenderView* renderView = this->renderView()) {
if (renderView->usesCompositing())
renderView->compositor()->frameViewDidChangeSize();
}
+
+ viewportConstrainedVisibleContentSizeChanged(newRect.width() != oldRect.width(), newRect.height() != oldRect.height());
+
+ if (oldRect.size() != newRect.size()
+ && m_frame->isMainFrame()
+ && m_frame->settings()->pinchVirtualViewportEnabled())
+ page()->frameHost().pinchViewport().mainFrameDidChangeSize();
}
bool FrameView::scheduleAnimation()
@@ -455,21 +389,14 @@ bool FrameView::scheduleAnimation()
return false;
}
-RenderView* FrameView::renderView() const
-{
- return frame().contentRenderer();
-}
-
-void FrameView::setMarginWidth(LayoutUnit w)
+Page* FrameView::page() const
{
- // make it update the rendering area when set
- m_margins.setWidth(w);
+ return frame().page();
}
-void FrameView::setMarginHeight(LayoutUnit h)
+RenderView* FrameView::renderView() const
{
- // make it update the rendering area when set
- m_margins.setHeight(h);
+ return frame().contentRenderer();
}
void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
@@ -478,24 +405,13 @@ void FrameView::setCanHaveScrollbars(bool canHaveScrollbars)
ScrollView::setCanHaveScrollbars(canHaveScrollbars);
}
-void FrameView::updateCanHaveScrollbars()
-{
- ScrollbarMode hMode;
- ScrollbarMode vMode;
- scrollbarModes(hMode, vMode);
- if (hMode == ScrollbarAlwaysOff && vMode == ScrollbarAlwaysOff)
- setCanHaveScrollbars(false);
- else
- setCanHaveScrollbars(true);
-}
-
-bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, Frame*& customScrollbarFrame)
+bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, LocalFrame*& customScrollbarFrame)
{
customScrollbarElement = 0;
customScrollbarFrame = 0;
if (Settings* settings = m_frame->settings()) {
- if (!settings->allowCustomScrollbarInMainFrame() && isMainFrame())
+ if (!settings->allowCustomScrollbarInMainFrame() && m_frame->isMainFrame())
return false;
}
@@ -516,7 +432,7 @@ bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, Fram
return true;
}
- // If we have an owning ipage/Frame element, then it can set the custom scrollbar also.
+ // If we have an owning ipage/LocalFrame element, then it can set the custom scrollbar also.
RenderPart* frameRenderer = m_frame->ownerRenderer();
if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR)) {
customScrollbarFrame = m_frame.get();
@@ -529,7 +445,7 @@ bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, Fram
PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
{
Element* customScrollbarElement = 0;
- Frame* customScrollbarFrame = 0;
+ LocalFrame* customScrollbarFrame = 0;
if (shouldUseCustomScrollbars(customScrollbarElement, customScrollbarFrame))
return RenderScrollbar::createCustomScrollbar(this, orientation, customScrollbarElement, customScrollbarFrame);
@@ -554,6 +470,20 @@ void FrameView::setContentsSize(const IntSize& size)
page->chrome().contentsSizeChanged(m_frame.get(), size);
}
+IntPoint FrameView::clampOffsetAtScale(const IntPoint& offset, float scale) const
+{
+ IntPoint maxScrollExtent(contentsSize().width() - scrollOrigin().x(), contentsSize().height() - scrollOrigin().y());
+ FloatSize scaledSize = unscaledVisibleContentSize();
+ if (scale)
+ scaledSize.scale(1 / scale);
+
+ IntPoint clampedOffset = offset;
+ clampedOffset = clampedOffset.shrunkTo(maxScrollExtent - expandedIntSize(scaledSize));
+ clampedOffset = clampedOffset.expandedTo(-scrollOrigin());
+
+ return clampedOffset;
+}
+
void FrameView::adjustViewSize()
{
RenderView* renderView = this->renderView();
@@ -569,7 +499,7 @@ void FrameView::adjustViewSize()
setContentsSize(size);
}
-void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
+void FrameView::applyOverflowToViewportAndSetRenderer(RenderObject* o, ScrollbarMode& hMode, ScrollbarMode& vMode)
{
// Handle the overflow:hidden/scroll case for the body/html elements. WinIE treats
// overflow:hidden and overflow:scroll on <body> as applying to the document's
@@ -580,11 +510,16 @@ void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, S
EOverflow overflowY = o->style()->overflowY();
if (o->isSVGRoot()) {
- // overflow is ignored in stand-alone SVG documents.
- if (!toRenderSVGRoot(o)->isEmbeddedThroughFrameContainingSVGDocument())
+ // Don't allow overflow to affect <img> and css backgrounds
+ if (toRenderSVGRoot(o)->isEmbeddedThroughSVGImage())
return;
- overflowX = OHIDDEN;
- overflowY = OHIDDEN;
+
+ // FIXME: evaluate if we can allow overflow for these cases too.
+ // Overflow is always hidden when stand-alone SVG documents are embedded.
+ if (toRenderSVGRoot(o)->isEmbeddedThroughFrameContainingSVGDocument()) {
+ overflowX = OHIDDEN;
+ overflowY = OHIDDEN;
+ }
}
bool ignoreOverflowHidden = false;
@@ -619,46 +554,19 @@ void FrameView::applyOverflowToViewport(RenderObject* o, ScrollbarMode& hMode, S
vMode = ScrollbarAuto;
break;
default:
- // Don't set it at all. Values of OPAGEDX and OPAGEDY are handled by applyPaginationToViewPort().
+ // Don't set it at all.
;
}
m_viewportRenderer = o;
}
-void FrameView::applyPaginationToViewport()
-{
- Document* document = m_frame->document();
- Node* documentElement = document->documentElement();
- RenderObject* documentRenderer = documentElement ? documentElement->renderer() : 0;
- RenderObject* documentOrBodyRenderer = documentRenderer;
- Node* body = document->body();
- if (body && body->renderer()) {
- if (body->hasTagName(bodyTag))
- documentOrBodyRenderer = documentRenderer->style()->overflowX() == OVISIBLE && isHTMLHtmlElement(documentElement) ? body->renderer() : documentRenderer;
- }
-
- Pagination pagination;
-
- if (!documentOrBodyRenderer) {
- setPagination(pagination);
- return;
- }
-
- EOverflow overflowY = documentOrBodyRenderer->style()->overflowY();
- if (overflowY == OPAGEDX || overflowY == OPAGEDY) {
- pagination.mode = WebCore::paginationModeForRenderStyle(documentOrBodyRenderer->style());
- pagination.gap = static_cast<unsigned>(documentOrBodyRenderer->style()->columnGap());
- }
-
- setPagination(pagination);
-}
-
-void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
+void FrameView::calculateScrollbarModesForLayoutAndSetViewportRenderer(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy strategy)
{
m_viewportRenderer = 0;
- const HTMLFrameOwnerElement* owner = m_frame->ownerElement();
+ // FIXME: How do we handle this for OOPI?
+ const HTMLFrameOwnerElement* owner = m_frame->deprecatedLocalOwner();
if (owner && (owner->scrollingMode() == ScrollbarAlwaysOff)) {
hMode = ScrollbarAlwaysOff;
vMode = ScrollbarAlwaysOff;
@@ -667,71 +575,61 @@ void FrameView::calculateScrollbarModesForLayout(ScrollbarMode& hMode, Scrollbar
if (m_canHaveScrollbars || strategy == RulesFromWebContentOnly) {
hMode = ScrollbarAuto;
- // Seamless documents begin with heights of 0; we special case that here
- // to correctly render documents that don't need scrollbars.
- IntSize fullVisibleSize = visibleContentRect(IncludeScrollbars).size();
- bool isSeamlessDocument = frame().document() && frame().document()->shouldDisplaySeamlesslyWithParent();
- vMode = (isSeamlessDocument && !fullVisibleSize.height()) ? ScrollbarAlwaysOff : ScrollbarAuto;
+ vMode = ScrollbarAuto;
} else {
hMode = ScrollbarAlwaysOff;
vMode = ScrollbarAlwaysOff;
}
- if (!m_layoutRoot) {
+ if (!isSubtreeLayout()) {
Document* document = m_frame->document();
- Node* documentElement = document->documentElement();
- RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0;
Node* body = document->body();
- if (body && body->renderer()) {
- if (body->hasTagName(framesetTag)) {
- vMode = ScrollbarAlwaysOff;
- hMode = ScrollbarAlwaysOff;
- } else if (body->hasTagName(bodyTag)) {
- // It's sufficient to just check the X overflow,
- // since it's illegal to have visible in only one direction.
- RenderObject* o = rootRenderer->style()->overflowX() == OVISIBLE && isHTMLHtmlElement(document->documentElement()) ? body->renderer() : rootRenderer;
- if (o->style())
- applyOverflowToViewport(o, hMode, vMode);
+ if (isHTMLFrameSetElement(body) && body->renderer()) {
+ vMode = ScrollbarAlwaysOff;
+ hMode = ScrollbarAlwaysOff;
+ } else if (Element* viewportElement = document->viewportDefiningElement()) {
+ if (RenderObject* viewportRenderer = viewportElement->renderer()) {
+ if (viewportRenderer->style())
+ applyOverflowToViewportAndSetRenderer(viewportRenderer, hMode, vMode);
}
- } else if (rootRenderer)
- applyOverflowToViewport(rootRenderer, hMode, vMode);
+ }
}
}
-void FrameView::updateCompositingLayersAfterStyleChange()
+void FrameView::updateAcceleratedCompositingSettings()
+{
+ if (RenderView* renderView = this->renderView())
+ renderView->compositor()->updateAcceleratedCompositingSettings();
+}
+
+void FrameView::recalcOverflowAfterStyleChange()
{
- TRACE_EVENT0("webkit", "FrameView::updateCompositingLayersAfterStyleChange");
RenderView* renderView = this->renderView();
- if (!renderView)
+ ASSERT(renderView);
+ if (!renderView->needsOverflowRecalcAfterStyleChange())
return;
- // If we expect to update compositing after an incipient layout, don't do so here.
- if (m_doingPreLayoutStyleUpdate || layoutPending() || renderView->needsLayout())
- return;
+ renderView->recalcOverflowAfterStyleChange();
- // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
- renderView->compositor()->cacheAcceleratedCompositingFlags();
+ if (needsLayout())
+ return;
- // Sometimes we will change a property (for example, z-index) that will not
- // cause a layout, but will require us to update compositing state. We only
- // need to do this if a layout is not already scheduled.
- if (!needsLayout())
- renderView->compositor()->updateCompositingRequirementsState();
+ InUpdateScrollbarsScope inUpdateScrollbarsScope(this);
- renderView->compositor()->updateCompositingLayers(CompositingUpdateAfterStyleChange);
-}
+ bool shouldHaveHorizontalScrollbar = false;
+ bool shouldHaveVerticalScrollbar = false;
+ computeScrollbarExistence(shouldHaveHorizontalScrollbar, shouldHaveVerticalScrollbar);
-void FrameView::updateCompositingLayersAfterLayout()
-{
- TRACE_EVENT0("webkit", "FrameView::updateCompositingLayersAfterLayout");
- RenderView* renderView = this->renderView();
- if (!renderView)
+ bool hasHorizontalScrollbar = horizontalScrollbar();
+ bool hasVerticalScrollbar = verticalScrollbar();
+ if (hasHorizontalScrollbar != shouldHaveHorizontalScrollbar
+ || hasVerticalScrollbar != shouldHaveVerticalScrollbar) {
+ setNeedsLayout();
return;
+ }
- // This call will make sure the cached hasAcceleratedCompositing is updated from the pref
- renderView->compositor()->cacheAcceleratedCompositingFlags();
- renderView->compositor()->updateCompositingRequirementsState();
- renderView->compositor()->updateCompositingLayers(CompositingUpdateAfterLayout);
+ adjustViewSize();
+ updateScrollbarGeometry();
}
bool FrameView::usesCompositedScrolling() const
@@ -740,7 +638,7 @@ bool FrameView::usesCompositedScrolling() const
if (!renderView)
return false;
if (m_frame->settings() && m_frame->settings()->compositedScrollingForFramesEnabled())
- return renderView->compositor()->inForcedCompositingMode();
+ return renderView->compositor()->inCompositingMode();
return false;
}
@@ -778,15 +676,19 @@ GraphicsLayer* FrameView::layerForScrollCorner() const
bool FrameView::hasCompositedContent() const
{
+ // FIXME: change to inCompositingMode. Fails fast/repaint/iframe-scroll-repaint.html.
if (RenderView* renderView = this->renderView())
- return renderView->compositor()->inCompositingMode();
+ return renderView->compositor()->staleInCompositingMode();
return false;
}
bool FrameView::isEnclosedInCompositingLayer() const
{
+ // FIXME: It's a bug that compositing state isn't always up to date when this is called. crbug.com/366314
+ DisableCompositingQueryAsserts disabler;
+
RenderObject* frameOwnerRenderer = m_frame->ownerRenderer();
- if (frameOwnerRenderer && frameOwnerRenderer->containerForRepaint())
+ if (frameOwnerRenderer && frameOwnerRenderer->enclosingLayer()->enclosingCompositingLayerForRepaint())
return true;
if (FrameView* parentView = parentFrameView())
@@ -795,28 +697,9 @@ bool FrameView::isEnclosedInCompositingLayer() const
return false;
}
-bool FrameView::isSoftwareRenderable() const
-{
- RenderView* renderView = this->renderView();
- return !renderView || !renderView->compositor()->has3DContent();
-}
-
RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
{
- return onlyDuringLayout && layoutPending() ? 0 : m_layoutRoot;
-}
-
-static inline void collectFrameViewChildren(FrameView* frameView, Vector<RefPtr<FrameView> >& frameViews)
-{
- const HashSet<RefPtr<Widget> >* viewChildren = frameView->children();
- ASSERT(viewChildren);
-
- const HashSet<RefPtr<Widget> >::iterator end = viewChildren->end();
- for (HashSet<RefPtr<Widget> >::iterator current = viewChildren->begin(); current != end; ++current) {
- Widget* widget = (*current).get();
- if (widget->isFrameView())
- frameViews.append(toFrameView(widget));
- }
+ return onlyDuringLayout && layoutPending() ? 0 : m_layoutSubtreeRoot;
}
inline void FrameView::forceLayoutParentViewIfNeeded()
@@ -843,7 +726,7 @@ inline void FrameView::forceLayoutParentViewIfNeeded()
RefPtr<FrameView> frameView = ownerRenderer->frame()->view();
// Mark the owner renderer as needing layout.
- ownerRenderer->setNeedsLayoutAndPrefWidthsRecalc();
+ ownerRenderer->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
// Synchronously enter layout, to layout the view containing the host object/embed/iframe.
ASSERT(frameView);
@@ -852,20 +735,25 @@ inline void FrameView::forceLayoutParentViewIfNeeded()
void FrameView::performPreLayoutTasks()
{
+ TRACE_EVENT0("webkit", "FrameView::performPreLayoutTasks");
+ lifecycle().advanceTo(DocumentLifecycle::InPreLayout);
+
// Don't schedule more layouts, we're in one.
TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
- if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive() && !frame().document()->shouldDisplaySeamlesslyWithParent()) {
+ if (!m_nestedLayoutCount && !m_inSynchronousPostLayout && m_postLayoutTasksTimer.isActive()) {
// This is a new top-level layout. If there are any remaining tasks from the previous layout, finish them now.
m_inSynchronousPostLayout = true;
performPostLayoutTasks();
m_inSynchronousPostLayout = false;
}
- // Viewport-dependent media queries may cause us to need completely different style information.
Document* document = m_frame->document();
- if (!document->styleResolver() || document->styleResolver()->affectedByViewportChange()) {
- document->styleResolverChanged(RecalcStyleDeferred);
+ document->notifyResizeForViewportUnits();
+
+ // Viewport-dependent media queries may cause us to need completely different style information.
+ if (!document->styleResolver() || document->styleResolver()->mediaQueryAffectedByViewportChange()) {
+ document->styleResolverChanged();
document->mediaQueryAffectingValueChanged();
// FIXME: This instrumentation event is not strictly accurate since cached media query results
@@ -875,65 +763,50 @@ void FrameView::performPreLayoutTasks()
document->evaluateMediaQueryList();
}
- // If there is any pagination to apply, it will affect the RenderView's style, so we should
- // take care of that now.
- applyPaginationToViewport();
-
- // Always ensure our style info is up-to-date. This can happen in situations where
- // the layout beats any sort of style recalc update that needs to occur.
- TemporaryChange<bool> changeDoingPreLayoutStyleUpdate(m_doingPreLayoutStyleUpdate, true);
- document->updateStyleIfNeeded();
+ document->updateRenderTreeIfNeeded();
+ lifecycle().advanceTo(DocumentLifecycle::StyleClean);
}
void FrameView::performLayout(RenderObject* rootForThisLayout, bool inSubtreeLayout)
{
+ TRACE_EVENT0("webkit", "FrameView::performLayout");
+
+ ScriptForbiddenScope forbidScript;
+
+ ASSERT(!isInPerformLayout());
+ lifecycle().advanceTo(DocumentLifecycle::InPerformLayout);
+
+ TemporaryChange<bool> changeInPerformLayout(m_inPerformLayout, true);
+
// performLayout is the actual guts of layout().
// FIXME: The 300 other lines in layout() probably belong in other helper functions
// so that a single human could understand what layout() is actually doing.
- FrameView::DeferredRepaintScope deferRepaints(*this);
- {
- bool disableLayoutState = false;
- if (inSubtreeLayout) {
- RenderView* view = rootForThisLayout->view();
- disableLayoutState = view->shouldDisableLayoutStateForSubtree(rootForThisLayout);
- view->pushLayoutState(rootForThisLayout);
- }
- LayoutStateDisabler layoutStateDisabler(disableLayoutState ? rootForThisLayout->view() : 0);
+ LayoutState layoutState(*rootForThisLayout);
- m_inLayout = true;
+ forceLayoutParentViewIfNeeded();
- forceLayoutParentViewIfNeeded();
+ // FIXME (crbug.com/256657): Do not do two layouts for text autosizing.
+ rootForThisLayout->layout();
+ gatherDebugLayoutRects(rootForThisLayout);
- // Text Autosizing requires two-pass layout which is incompatible with partial layout.
- // If enabled, only do partial layout for the second layout.
- // FIXME (crbug.com/256657): Do not do two layouts for text autosizing.
- PartialLayoutDisabler partialLayoutDisabler(partialLayout(), m_frame->settings() && m_frame->settings()->textAutosizingEnabled());
-
- LayoutIndicator layoutIndicator;
- rootForThisLayout->layout();
- gatherDebugLayoutRects(rootForThisLayout);
+ ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllImageResourcePriorities();
- ResourceLoadPriorityOptimizer modifier;
- rootForThisLayout->didLayout(modifier);
+ TextAutosizer* textAutosizer = frame().document()->textAutosizer();
+ bool autosized;
+ {
+ AllowPaintInvalidationScope paintInvalidationAllowed(this);
+ autosized = textAutosizer && textAutosizer->processSubtree(rootForThisLayout);
}
- TextAutosizer* textAutosizer = frame().document()->textAutosizer();
- bool autosized = textAutosizer && textAutosizer->processSubtree(rootForThisLayout);
if (autosized && rootForThisLayout->needsLayout()) {
TRACE_EVENT0("webkit", "2nd layout due to Text Autosizing");
- LayoutIndicator layoutIndicator;
+ UseCounter::count(*frame().document(), UseCounter::TextAutosizingLayout);
rootForThisLayout->layout();
gatherDebugLayoutRects(rootForThisLayout);
-
- ResourceLoadPriorityOptimizer modifier;
- rootForThisLayout->didLayout(modifier);
}
- m_inLayout = false;
-
- if (inSubtreeLayout)
- rootForThisLayout->view()->popLayoutState(rootForThisLayout);
+ lifecycle().advanceTo(DocumentLifecycle::AfterPerformLayout);
}
void FrameView::scheduleOrPerformPostLayoutTasks()
@@ -941,47 +814,34 @@ void FrameView::scheduleOrPerformPostLayoutTasks()
if (m_postLayoutTasksTimer.isActive())
return;
- // Partial layouts should not happen with synchronous post layouts.
- ASSERT(!(m_inSynchronousPostLayout && partialLayout().isStopping()));
-
if (!m_inSynchronousPostLayout) {
- if (frame().document()->shouldDisplaySeamlesslyWithParent()) {
- if (RenderView* renderView = this->renderView())
- renderView->updateWidgetPositions();
- } else {
- m_inSynchronousPostLayout = true;
- // Calls resumeScheduledEvents()
- performPostLayoutTasks();
- m_inSynchronousPostLayout = false;
- }
+ m_inSynchronousPostLayout = true;
+ // Calls resumeScheduledEvents()
+ performPostLayoutTasks();
+ m_inSynchronousPostLayout = false;
}
- if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout || frame().document()->shouldDisplaySeamlesslyWithParent())) {
+ if (!m_postLayoutTasksTimer.isActive() && (needsLayout() || m_inSynchronousPostLayout)) {
// If we need layout or are already in a synchronous call to postLayoutTasks(),
// defer widget updates and event dispatch until after we return. postLayoutTasks()
// can make us need to update again, and we can get stuck in a nasty cycle unless
// we call it through the timer here.
- m_postLayoutTasksTimer.startOneShot(0);
- if (!partialLayout().isStopping() && needsLayout())
+ m_postLayoutTasksTimer.startOneShot(0, FROM_HERE);
+ if (needsLayout())
layout();
}
}
void FrameView::layout(bool allowSubtree)
{
- // We should never layout a Document which is not in a Frame.
+ // We should never layout a Document which is not in a LocalFrame.
ASSERT(m_frame);
ASSERT(m_frame->view() == this);
ASSERT(m_frame->page());
- if (m_inLayout)
+ if (isInPerformLayout() || !m_frame->document()->isActive())
return;
- if (!m_frame->document()->isActive())
- return;
-
- ASSERT(!partialLayout().isStopping());
-
TRACE_EVENT0("webkit", "FrameView::layout");
TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "Layout");
@@ -991,23 +851,19 @@ void FrameView::layout(bool allowSubtree)
// Every scroll that happens during layout is programmatic.
TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
- m_layoutTimer.stop();
- m_delayedLayout = false;
+ m_hasPendingLayout = false;
+ DocumentLifecycle::Scope lifecycleScope(lifecycle(), DocumentLifecycle::LayoutClean);
- // we shouldn't enter layout() while painting
- ASSERT(!isPainting());
- if (isPainting())
- return;
-
- // Store the current maximal outline size to use when computing the old/new
- // outline rects for repainting.
- renderView()->setOldMaximalOutlineSize(renderView()->maximalOutlineSize());
+ RELEASE_ASSERT(!isPainting());
+ TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Layout", "beginData", InspectorLayoutEvent::beginData(this));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(m_frame.get());
- if (!allowSubtree && m_layoutRoot) {
- m_layoutRoot->markContainingBlocksForLayout(false);
- m_layoutRoot = 0;
+ if (!allowSubtree && isSubtreeLayout()) {
+ m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
+ m_layoutSubtreeRoot = 0;
}
performPreLayoutTasks();
@@ -1018,29 +874,27 @@ void FrameView::layout(bool allowSubtree)
return;
Document* document = m_frame->document();
- bool inSubtreeLayout = m_layoutRoot;
- RenderObject* rootForThisLayout = inSubtreeLayout ? m_layoutRoot : document->renderer();
+ bool inSubtreeLayout = isSubtreeLayout();
+ RenderObject* rootForThisLayout = inSubtreeLayout ? m_layoutSubtreeRoot : document->renderView();
if (!rootForThisLayout) {
// FIXME: Do we need to set m_size here?
ASSERT_NOT_REACHED();
return;
}
- bool isPartialLayout = partialLayout().isPartialLayout();
-
FontCachePurgePreventer fontCachePurgePreventer;
RenderLayer* layer;
{
TemporaryChange<bool> changeSchedulingEnabled(m_layoutSchedulingEnabled, false);
m_nestedLayoutCount++;
- if (!m_layoutRoot) {
+ if (!inSubtreeLayout) {
Document* document = m_frame->document();
Node* body = document->body();
if (body && body->renderer()) {
- if (body->hasTagName(framesetTag)) {
+ if (isHTMLFrameSetElement(*body)) {
body->renderer()->setChildNeedsLayout();
- } else if (body->hasTagName(bodyTag)) {
+ } else if (isHTMLBodyElement(*body)) {
if (!m_firstLayout && m_size.height() != layoutSize().height() && body->renderer()->enclosingBox()->stretchesToViewport())
body->renderer()->setChildNeedsLayout();
}
@@ -1051,121 +905,109 @@ void FrameView::layout(bool allowSubtree)
ScrollbarMode hMode;
ScrollbarMode vMode;
- calculateScrollbarModesForLayout(hMode, vMode);
-
- m_doFullRepaint = !inSubtreeLayout && !isPartialLayout && (m_firstLayout || toRenderView(rootForThisLayout)->document().printing());
+ calculateScrollbarModesForLayoutAndSetViewportRenderer(hMode, vMode);
- if (!inSubtreeLayout && !isPartialLayout) {
+ if (!inSubtreeLayout) {
// Now set our scrollbar state for the layout.
ScrollbarMode currentHMode = horizontalScrollbarMode();
ScrollbarMode currentVMode = verticalScrollbarMode();
- if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
- if (m_firstLayout) {
- setScrollbarsSuppressed(true);
-
- m_firstLayout = false;
- m_firstLayoutCallbackPending = true;
- m_lastViewportSize = layoutSize(IncludeScrollbars);
- m_lastZoomFactor = rootForThisLayout->style()->zoom();
-
- // Set the initial vMode to AlwaysOn if we're auto.
- if (vMode == ScrollbarAuto)
- setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
- // Set the initial hMode to AlwaysOff if we're auto.
- if (hMode == ScrollbarAuto)
- setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
-
- setScrollbarModes(hMode, vMode);
- setScrollbarsSuppressed(false, true);
- } else
- setScrollbarModes(hMode, vMode);
+ if (m_firstLayout) {
+ setScrollbarsSuppressed(true);
+
+ m_doFullPaintInvalidation = true;
+ m_firstLayout = false;
+ m_firstLayoutCallbackPending = true;
+ m_lastViewportSize = layoutSize(IncludeScrollbars);
+ m_lastZoomFactor = rootForThisLayout->style()->zoom();
+
+ // Set the initial vMode to AlwaysOn if we're auto.
+ if (vMode == ScrollbarAuto)
+ setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
+ // Set the initial hMode to AlwaysOff if we're auto.
+ if (hMode == ScrollbarAuto)
+ setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
+
+ setScrollbarModes(hMode, vMode);
+ setScrollbarsSuppressed(false, true);
+ } else if (hMode != currentHMode || vMode != currentVMode) {
+ setScrollbarModes(hMode, vMode);
}
LayoutSize oldSize = m_size;
m_size = LayoutSize(layoutSize().width(), layoutSize().height());
- if (oldSize != m_size) {
- m_doFullRepaint = true;
- if (!m_firstLayout) {
- RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
- RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
- if (bodyRenderer && bodyRenderer->stretchesToViewport())
- bodyRenderer->setChildNeedsLayout();
- else if (rootRenderer && rootRenderer->stretchesToViewport())
- rootRenderer->setChildNeedsLayout();
- }
+ if (oldSize != m_size && !m_firstLayout) {
+ RenderBox* rootRenderer = document->documentElement() ? document->documentElement()->renderBox() : 0;
+ RenderBox* bodyRenderer = rootRenderer && document->body() ? document->body()->renderBox() : 0;
+ if (bodyRenderer && bodyRenderer->stretchesToViewport())
+ bodyRenderer->setChildNeedsLayout();
+ else if (rootRenderer && rootRenderer->stretchesToViewport())
+ rootRenderer->setChildNeedsLayout();
}
+
+ // We need to set m_doFullPaintInvalidation before triggering layout as RenderObject::checkForPaintInvalidation
+ // checks the boolean to disable local paint invalidations.
+ m_doFullPaintInvalidation |= renderView()->shouldDoFullRepaintForNextLayout();
}
layer = rootForThisLayout->enclosingLayer();
performLayout(rootForThisLayout, inSubtreeLayout);
- m_layoutRoot = 0;
+ m_layoutSubtreeRoot = 0;
} // Reset m_layoutSchedulingEnabled to its previous value.
- bool neededFullRepaint = m_doFullRepaint;
-
- if (!inSubtreeLayout && !isPartialLayout && !toRenderView(rootForThisLayout)->document().printing())
+ if (!inSubtreeLayout && !toRenderView(rootForThisLayout)->document().printing())
adjustViewSize();
- m_doFullRepaint = neededFullRepaint;
-
- {
- // FIXME: Can this scope just encompass this entire function?
- FrameView::DeferredRepaintScope deferRepaints(*this);
-
- if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
- if (m_doFullRepaint)
- renderView()->setShouldDoFullRepaintAfterLayout(true);
-
- if (m_doFullRepaint || !partialLayout().isStopping())
- repaintTree(rootForThisLayout);
-
- } else if (m_doFullRepaint) {
- // FIXME: This isn't really right, since the RenderView doesn't fully encompass
- // the visibleContentRect(). It just happens to work out most of the time,
- // since first layouts and printing don't have you scrolled anywhere.
- renderView()->repaint();
- }
- layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, inSubtreeLayout, m_doFullRepaint));
- }
- updateCompositingLayersAfterLayout();
+ layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, inSubtreeLayout, m_doFullPaintInvalidation));
+ renderView()->compositor()->didLayout();
m_layoutCount++;
- if (AXObjectCache* cache = rootForThisLayout->document().existingAXObjectCache())
- cache->postNotification(rootForThisLayout, AXObjectCache::AXLayoutComplete, true);
+ if (AXObjectCache* cache = rootForThisLayout->document().axObjectCache()) {
+ const KURL& url = rootForThisLayout->document().url();
+ if (url.isValid() && !url.isAboutBlankURL())
+ cache->handleLayoutComplete(rootForThisLayout);
+ }
updateAnnotatedRegions();
- ASSERT(partialLayout().isStopping() || !rootForThisLayout->needsLayout());
-
- updateCanBlitOnScrollRecursively();
+ ASSERT(!rootForThisLayout->needsLayout());
if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
updateOverflowStatus(layoutSize().width() < contentsWidth(), layoutSize().height() < contentsHeight());
scheduleOrPerformPostLayoutTasks();
+ TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Layout", "endData", InspectorLayoutEvent::endData(rootForThisLayout));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didLayout(cookie, rootForThisLayout);
m_nestedLayoutCount--;
if (m_nestedLayoutCount)
return;
- if (partialLayout().isStopping())
- return;
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ invalidateTree(rootForThisLayout);
+ } else if (m_doFullPaintInvalidation) {
+ // FIXME: This isn't really right, since the RenderView doesn't fully encompass
+ // the visibleContentRect(). It just happens to work out most of the time,
+ // since first layouts and printing don't have you scrolled anywhere.
+ renderView()->paintInvalidationForWholeRenderer();
+ }
+
+ m_doFullPaintInvalidation = false;
#ifndef NDEBUG
// Post-layout assert that nobody was re-marked as needing layout during layout.
- document->renderer()->assertSubtreeIsLaidOut();
+ document->renderView()->assertSubtreeIsLaidOut();
#endif
// FIXME: It should be not possible to remove the FrameView from the frame/page during layout
- // however m_inLayout is not set for most of this function, so none of our RELEASE_ASSERTS
- // in Frame/Page will fire. One of the post-layout tasks is disconnecting the Frame from
+ // however m_inPerformLayout is not set for most of this function, so none of our RELEASE_ASSERTS
+ // in LocalFrame/Page will fire. One of the post-layout tasks is disconnecting the LocalFrame from
// the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.html
// necessitating this check here.
// ASSERT(frame()->page());
@@ -1173,46 +1015,39 @@ void FrameView::layout(bool allowSubtree)
frame().page()->chrome().client().layoutUpdated(m_frame.get());
}
-// The plan is to move to compositor-queried repainting, in which case this
+// The plan is to move to compositor-queried paint invalidation, in which case this
// method would setNeedsRedraw on the GraphicsLayers with invalidations and
// let the compositor pick which to actually draw.
// See http://crbug.com/306706
-void FrameView::repaintTree(RenderObject* root)
+void FrameView::invalidateTree(RenderObject* root)
{
ASSERT(RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
ASSERT(!root->needsLayout());
+ // We should only invalidate paints for the outer most layout. This works as
+ // we continue to track paint invalidation rects until this function is called.
+ ASSERT(!m_nestedLayoutCount);
- for (RenderObject* renderer = root; renderer; renderer = renderer->nextInPreOrder()) {
- const LayoutRect& oldRepaintRect = renderer->oldRepaintRect();
- const LayoutRect& newRepaintRect = renderer->newRepaintRect();
-
- LayoutRect oldOutlineRect = oldRepaintRect;
- oldOutlineRect.inflate(renderView()->oldMaximalOutlineSize());
-
- LayoutRect newOutlineRect = newRepaintRect;
- newOutlineRect.inflate(renderView()->maximalOutlineSize());
-
- // FIXME: Currently renderers with layers will get repainted when we call updateLayerPositionsAfterLayout.
- // That call should be broken apart to position the layers be done before
- // the repaintTree call so this will repaint everything.
- bool didFullRepaint = false;
- if (!renderer->hasLayer()) {
- if (!renderer->layoutDidGetCalled()) {
- if (renderer->shouldDoFullRepaintAfterLayout()) {
- renderer->repaint();
- didFullRepaint = true;
- }
+ TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", root->debugName().ascii());
- } else {
- didFullRepaint = renderer->repaintAfterLayoutIfNeeded(renderer->containerForRepaint(), renderer->shouldDoFullRepaintAfterLayout(),
- oldRepaintRect, oldOutlineRect, &newRepaintRect, &newOutlineRect);
- }
- }
- if (!didFullRepaint && renderer->shouldRepaintOverflowIfNeeded())
- renderer->repaintOverflow();
- renderer->clearRepaintRects();
- }
- renderView()->setOldMaximalOutlineSize(0);
+ // FIXME: really, we're in the paint invalidation phase here, and the compositing queries are legal.
+ // Until those states are fully fledged, I'll just disable the ASSERTS.
+ DisableCompositingQueryAsserts compositingQueryAssertsDisabler;
+
+ LayoutState rootLayoutState(*root);
+
+ root->invalidateTreeAfterLayout(*root->containerForPaintInvalidation());
+
+ // Invalidate the paint of the frameviews scrollbars if needed
+ if (hasVerticalBarDamage())
+ invalidateRect(verticalBarDamage());
+ if (hasHorizontalBarDamage())
+ invalidateRect(horizontalBarDamage());
+ resetScrollbarDamage();
+}
+
+DocumentLifecycle& FrameView::lifecycle() const
+{
+ return m_frame->document()->lifecycle();
}
void FrameView::gatherDebugLayoutRects(RenderObject* layoutRoot)
@@ -1227,19 +1062,19 @@ void FrameView::gatherDebugLayoutRects(RenderObject* layoutRoot)
if (!graphicsLayer)
return;
- GraphicsLayerDebugInfo* debugInfo = new GraphicsLayerDebugInfo();
+ GraphicsLayerDebugInfo& debugInfo = graphicsLayer->debugInfo();
+
+ debugInfo.currentLayoutRects().clear();
for (RenderObject* renderer = layoutRoot; renderer; renderer = renderer->nextInPreOrder()) {
if (renderer->layoutDidGetCalled()) {
- LayoutRect rect = renderer->newRepaintRect();
- debugInfo->m_currentLayoutRects.append(rect);
+ FloatQuad quad = renderer->localToAbsoluteQuad(FloatQuad(renderer->previousPaintInvalidationRect()));
+ LayoutRect rect = quad.enclosingBoundingBox();
+ debugInfo.currentLayoutRects().append(rect);
renderer->setLayoutDidGetCalled(false);
}
}
-
- graphicsLayer->setDebugInfo(debugInfo);
}
-
RenderBox* FrameView::embeddedContentBox() const
{
RenderView* renderView = this->renderView();
@@ -1257,11 +1092,38 @@ RenderBox* FrameView::embeddedContentBox() const
return 0;
}
+
+void FrameView::addWidget(RenderWidget* object)
+{
+ m_widgets.add(object);
+}
+
+void FrameView::removeWidget(RenderWidget* object)
+{
+ m_widgets.remove(object);
+}
+
+void FrameView::updateWidgetPositions()
+{
+ Vector<RefPtr<RenderWidget> > widgets;
+ copyToVector(m_widgets, widgets);
+
+ // Script or plugins could detach the frame so abort processing if that happens.
+
+ for (size_t i = 0; i < widgets.size() && renderView(); ++i)
+ widgets[i]->updateWidgetPosition();
+
+ for (size_t i = 0; i < widgets.size() && renderView(); ++i)
+ widgets[i]->widgetPositionsUpdated();
+}
+
void FrameView::addWidgetToUpdate(RenderEmbeddedObject& object)
{
+ ASSERT(isInPerformLayout());
// Tell the DOM element that it needs a widget update.
Node* node = object.node();
- if (node->hasTagName(objectTag) || node->hasTagName(embedTag))
+ ASSERT(node);
+ if (isHTMLObjectElement(*node) || isHTMLEmbedElement(*node))
toHTMLPlugInElement(node)->setNeedsWidgetUpdate(true);
m_widgetUpdateSet.add(&object);
@@ -1280,7 +1142,7 @@ AtomicString FrameView::mediaType() const
String overrideType;
InspectorInstrumentation::applyEmulatedMedia(m_frame.get(), &overrideType);
if (!overrideType.isNull())
- return overrideType;
+ return AtomicString(overrideType);
return m_mediaType;
}
@@ -1299,19 +1161,28 @@ void FrameView::adjustMediaTypeForPrinting(bool printing)
bool FrameView::useSlowRepaints(bool considerOverlap) const
{
- bool mustBeSlow = m_slowRepaintObjectCount > 0;
+ // FIXME: It is incorrect to determine blit-scrolling eligibility using dirty compositing state.
+ // https://code.google.com/p/chromium/issues/detail?id=357345
+ DisableCompositingQueryAsserts disabler;
+
+ if (m_slowRepaintObjectCount > 0)
+ return true;
if (contentsInCompositedLayer())
- return mustBeSlow;
+ return false;
// The chromium compositor does not support scrolling a non-composited frame within a composited page through
// the fast scrolling path, so force slow scrolling in that case.
- if (m_frame->ownerElement() && !hasCompositedContent() && m_frame->page() && m_frame->page()->mainFrame()->view()->hasCompositedContent())
+ if (m_frame->owner() && !hasCompositedContent() && m_frame->page() && m_frame->page()->mainFrame()->isLocalFrame() && m_frame->page()->deprecatedLocalMainFrame()->view()->hasCompositedContent())
+ return true;
+
+ if (m_isOverlapped && considerOverlap)
return true;
- bool isOverlapped = m_isOverlapped && considerOverlap;
+ if (m_cannotBlitToWindow)
+ return true;
- if (mustBeSlow || m_cannotBlitToWindow || isOverlapped || !m_contentIsOpaque)
+ if (!m_contentIsOpaque)
return true;
if (FrameView* parentView = parentFrameView())
@@ -1325,12 +1196,9 @@ bool FrameView::useSlowRepaintsIfNotOverlapped() const
return useSlowRepaints(false);
}
-void FrameView::updateCanBlitOnScrollRecursively()
+bool FrameView::shouldAttemptToScrollUsingFastPath() const
{
- for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
- if (FrameView* view = frame->view())
- view->setCanBlitOnScroll(!view->useSlowRepaints());
- }
+ return !useSlowRepaints();
}
bool FrameView::contentsInCompositedLayer() const
@@ -1348,14 +1216,11 @@ bool FrameView::contentsInCompositedLayer() const
void FrameView::setCannotBlitToWindow()
{
m_cannotBlitToWindow = true;
- updateCanBlitOnScrollRecursively();
}
void FrameView::addSlowRepaintObject()
{
if (!m_slowRepaintObjectCount++) {
- updateCanBlitOnScrollRecursively();
-
if (Page* page = m_frame->page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
@@ -1368,8 +1233,6 @@ void FrameView::removeSlowRepaintObject()
ASSERT(m_slowRepaintObjectCount > 0);
m_slowRepaintObjectCount--;
if (!m_slowRepaintObjectCount) {
- updateCanBlitOnScrollRecursively();
-
if (Page* page = m_frame->page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
@@ -1396,14 +1259,11 @@ void FrameView::removeViewportConstrainedObject(RenderObject* object)
{
if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->contains(object)) {
m_viewportConstrainedObjects->remove(object);
+
if (Page* page = m_frame->page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
scrollingCoordinator->frameViewFixedObjectsDidChange(this);
}
-
- // FIXME: In addFixedObject() we only call this if there's a platform widget,
- // why isn't the same check being made here?
- updateCanBlitOnScrollRecursively();
}
}
@@ -1415,6 +1275,39 @@ LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
return viewportRect;
}
+void FrameView::viewportConstrainedVisibleContentSizeChanged(bool widthChanged, bool heightChanged)
+{
+ if (!hasViewportConstrainedObjects())
+ return;
+
+ // If viewport is not enabled, frameRect change will cause layout size change and then layout.
+ // Otherwise, viewport constrained objects need their layout flags set separately to ensure
+ // they are positioned correctly. In the virtual-viewport pinch mode frame rect changes wont
+ // necessarily cause a layout size change so only take this early-out if we're in old-style
+ // pinch.
+ if (m_frame->settings()
+ && !m_frame->settings()->viewportEnabled()
+ && !m_frame->settings()->pinchVirtualViewportEnabled())
+ return;
+
+ ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
+ for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
+ RenderObject* renderer = *it;
+ RenderStyle* style = renderer->style();
+ if (widthChanged) {
+ if (style->width().isFixed() && (style->left().isAuto() || style->right().isAuto()))
+ renderer->setNeedsPositionedMovementLayout();
+ else
+ renderer->setNeedsLayoutAndFullPaintInvalidation();
+ }
+ if (heightChanged) {
+ if (style->height().isFixed() && (style->top().isAuto() || style->bottom().isAuto()))
+ renderer->setNeedsPositionedMovementLayout();
+ else
+ renderer->setNeedsLayoutAndFullPaintInvalidation();
+ }
+ }
+}
IntSize FrameView::scrollOffsetForFixedPosition() const
{
@@ -1429,7 +1322,27 @@ IntPoint FrameView::lastKnownMousePosition() const
bool FrameView::shouldSetCursor() const
{
Page* page = frame().page();
- return page && page->visibilityState() != PageVisibilityStateHidden && page->focusController().isActive();
+ return page && page->visibilityState() != PageVisibilityStateHidden && page->focusController().isActive() && page->settings().deviceSupportsMouse();
+}
+
+void FrameView::scrollContentsIfNeededRecursive()
+{
+ scrollContentsIfNeeded();
+
+ for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (!child->isLocalFrame())
+ continue;
+ if (FrameView* view = toLocalFrame(child)->view())
+ view->scrollContentsIfNeededRecursive();
+ }
+}
+
+void FrameView::scrollContentsIfNeeded()
+{
+ bool didScroll = !pendingScrollDelta().isZero();
+ ScrollView::scrollContentsIfNeeded();
+ if (didScroll)
+ updateFixedElementPaintInvalidationRectsAfterScroll();
}
bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect)
@@ -1446,16 +1359,16 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
RenderObject* renderer = *it;
- if (!renderer->style()->hasViewportConstrainedPosition())
- continue;
+ // m_viewportConstrainedObjects should not contain non-viewport constrained objects.
+ ASSERT(renderer->style()->hasViewportConstrainedPosition());
// Fixed items should always have layers.
ASSERT(renderer->hasLayer());
RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
// Layers that paint into their ancestor or into a grouped backing will still need
- // to apply a repaint invalidation. If the layer paints into its own backing, then
- // it does not need repainting just to scroll.
+ // to apply a paint invalidation. If the layer paints into its own backing, then
+ // it does not need paint invalidation just to scroll.
if (layer->compositingState() == PaintsIntoOwnBacking)
continue;
@@ -1473,19 +1386,21 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
IntRect updateRect = pixelSnappedIntRect(layer->repainter().repaintRectIncludingNonCompositingDescendants());
- RenderLayer* enclosingCompositingLayer = layer->enclosingCompositingLayer(false);
- if (enclosingCompositingLayer && !enclosingCompositingLayer->renderer()->isRenderView()) {
+ const RenderLayerModelObject* repaintContainer = layer->renderer()->containerForPaintInvalidation();
+ if (repaintContainer && !repaintContainer->isRenderView()) {
// If the fixed-position layer is contained by a composited layer that is not its containing block,
- // then we have to invlidate that enclosing layer, not the RenderView.
+ // then we have to invalidate that enclosing layer, not the RenderView.
+ // FIXME: Why do we need to issue this invalidation? Won't the fixed position element just scroll
+ // with the enclosing layer.
updateRect.moveBy(scrollPosition());
IntRect previousRect = updateRect;
previousRect.move(scrollDelta);
updateRect.unite(previousRect);
- enclosingCompositingLayer->repainter().setBackingNeedsRepaintInRect(updateRect);
+ layer->renderer()->invalidatePaintUsingContainer(repaintContainer, updateRect, InvalidationScroll);
} else {
- // Coalesce the repaints that will be issued to the renderView.
+ // Coalesce the paint invalidations that will be issued to the renderView.
updateRect = contentsToRootView(updateRect);
- if (!isCompositedContentLayer && clipsRepaints())
+ if (!isCompositedContentLayer && clipsPaintInvalidations())
updateRect.intersect(rectToScroll);
if (!updateRect.isEmpty())
regionToUpdate.unite(updateRect);
@@ -1501,7 +1416,7 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
for (size_t i = 0; i < viewportConstrainedObjectsCount; ++i) {
IntRect updateRect = subRectsToUpdate[i];
IntRect scrolledRect = updateRect;
- scrolledRect.move(scrollDelta);
+ scrolledRect.move(-scrollDelta);
updateRect.unite(scrolledRect);
if (isCompositedContentLayer) {
updateRect = rootViewToContents(updateRect);
@@ -1509,7 +1424,7 @@ bool FrameView::scrollContentsFastPath(const IntSize& scrollDelta, const IntRect
renderView()->layer()->repainter().setBackingNeedsRepaintInRect(updateRect);
continue;
}
- if (clipsRepaints())
+ if (clipsPaintInvalidations())
updateRect.intersect(rectToScroll);
hostWindow()->invalidateContentsAndRootView(updateRect);
}
@@ -1529,7 +1444,7 @@ void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
LayoutRect rect(frameRenderer->borderLeft() + frameRenderer->paddingLeft(),
frameRenderer->borderTop() + frameRenderer->paddingTop(),
visibleWidth(), visibleHeight());
- frameRenderer->repaintRectangle(rect);
+ frameRenderer->invalidatePaintRectangle(rect);
return;
}
}
@@ -1540,33 +1455,12 @@ void FrameView::scrollContentsSlowPath(const IntRect& updateRect)
// Note that this gets called at painting time.
void FrameView::setIsOverlapped(bool isOverlapped)
{
- if (isOverlapped == m_isOverlapped)
- return;
-
m_isOverlapped = isOverlapped;
- updateCanBlitOnScrollRecursively();
-}
-
-bool FrameView::isOverlappedIncludingAncestors() const
-{
- if (isOverlapped())
- return true;
-
- if (FrameView* parentView = parentFrameView()) {
- if (parentView->isOverlapped())
- return true;
- }
-
- return false;
}
void FrameView::setContentIsOpaque(bool contentIsOpaque)
{
- if (contentIsOpaque == m_contentIsOpaque)
- return;
-
m_contentIsOpaque = contentIsOpaque;
- updateCanBlitOnScrollRecursively();
}
void FrameView::restoreScrollbar()
@@ -1578,7 +1472,7 @@ bool FrameView::scrollToFragment(const KURL& url)
{
// If our URL has no ref, then we have no place we need to jump to.
// OTOH If CSS target was set previously, we want to set it to 0, recalc
- // and possibly repaint because :target pseudo class may have been
+ // and possibly paint invalidation because :target pseudo class may have been
// set (see bug 11321).
if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget())
return false;
@@ -1598,7 +1492,7 @@ bool FrameView::scrollToAnchor(const String& name)
{
ASSERT(m_frame->document());
- if (!m_frame->document()->haveStylesheetsLoaded()) {
+ if (!m_frame->document()->isRenderingReady()) {
m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true);
return false;
}
@@ -1611,7 +1505,7 @@ bool FrameView::scrollToAnchor(const String& name)
m_frame->document()->setCSSTarget(anchorNode);
if (m_frame->document()->isSVGDocument()) {
- if (SVGSVGElement* svg = toSVGDocument(m_frame->document())->rootElement()) {
+ if (SVGSVGElement* svg = SVGDocumentExtensions::rootElement(*m_frame->document())) {
svg->setupInitialView(name, anchorNode);
if (!anchorNode)
return true;
@@ -1639,7 +1533,7 @@ void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
// We need to update the layout before scrolling, otherwise we could
// really mess things up if an anchor scroll comes at a bad moment.
- m_frame->document()->updateStyleIfNeeded();
+ m_frame->document()->updateRenderTreeIfNeeded();
// Only do a layout if changes have occurred that make it necessary.
RenderView* renderView = this->renderView();
if (renderView && renderView->needsLayout())
@@ -1650,18 +1544,42 @@ void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode)
void FrameView::scrollElementToRect(Element* element, const IntRect& rect)
{
+ // FIXME(http://crbug.com/371896) - This method shouldn't be manually doing
+ // coordinate transformations to the PinchViewport.
+ IntRect targetRect(rect);
+
m_frame->document()->updateLayoutIgnorePendingStylesheets();
+ bool pinchVirtualViewportEnabled = m_frame->settings()->pinchVirtualViewportEnabled();
+
+ if (pinchVirtualViewportEnabled) {
+ PinchViewport& pinchViewport = m_frame->page()->frameHost().pinchViewport();
+
+ IntSize pinchViewportSize = expandedIntSize(pinchViewport.visibleRect().size());
+ targetRect.moveBy(ceiledIntPoint(pinchViewport.visibleRect().location()));
+ targetRect.setSize(pinchViewportSize.shrunkTo(targetRect.size()));
+ }
+
LayoutRect bounds = element->boundingBox();
- int centeringOffsetX = (rect.width() - bounds.width()) / 2;
- int centeringOffsetY = (rect.height() - bounds.height()) / 2;
- setScrollPosition(IntPoint(bounds.x() - centeringOffsetX - rect.x(), bounds.y() - centeringOffsetY - rect.y()));
+ int centeringOffsetX = (targetRect.width() - bounds.width()) / 2;
+ int centeringOffsetY = (targetRect.height() - bounds.height()) / 2;
+
+ IntPoint targetOffset(
+ bounds.x() - centeringOffsetX - targetRect.x(),
+ bounds.y() - centeringOffsetY - targetRect.y());
+
+ setScrollPosition(targetOffset);
+
+ if (pinchVirtualViewportEnabled) {
+ IntPoint remainder = IntPoint(targetOffset - scrollPosition());
+ m_frame->page()->frameHost().pinchViewport().move(remainder);
+ }
}
void FrameView::setScrollPosition(const IntPoint& scrollPoint)
{
TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
- m_maintainScrollPositionAnchor = 0;
+ m_maintainScrollPositionAnchor = nullptr;
IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
@@ -1682,18 +1600,6 @@ void FrameView::setScrollPositionNonProgrammatically(const IntPoint& scrollPoint
notifyScrollPositionChanged(newScrollPosition);
}
-void FrameView::setViewportConstrainedObjectsNeedLayout()
-{
- if (!hasViewportConstrainedObjects())
- return;
-
- ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
- for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
- RenderObject* renderer = *it;
- renderer->setNeedsLayout();
- }
-}
-
IntSize FrameView::layoutSize(IncludeScrollbarsInRect scrollbarInclusion) const
{
return scrollbarInclusion == ExcludeScrollbars ? excludeScrollbars(m_layoutSize) : m_layoutSize;
@@ -1720,38 +1626,73 @@ void FrameView::scrollPositionChanged()
renderView->compositor()->frameViewDidScroll();
}
- if (m_frame->document() && m_frame->document()->renderer()) {
- ResourceLoadPriorityOptimizer modifier;
- m_frame->document()->renderer()->didScroll(modifier);
+ if (m_didScrollTimer.isActive())
+ m_didScrollTimer.stop();
+ m_didScrollTimer.startOneShot(resourcePriorityUpdateDelayAfterScroll, FROM_HERE);
+
+ if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
+ cache->handleScrollPositionChanged(this);
+
+ frame().loader().saveScrollState();
+}
+
+void FrameView::didScrollTimerFired(Timer<FrameView>*)
+{
+ if (m_frame->document() && m_frame->document()->renderView()) {
+ ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllImageResourcePriorities();
}
}
-void FrameView::repaintFixedElementsAfterScrolling()
+void FrameView::updateLayersAndCompositingAfterScrollIfNeeded()
{
- // For fixed position elements, update widget positions and compositing layers after scrolling,
- // but only if we're not inside of layout.
- if (!m_nestedLayoutCount && hasViewportConstrainedObjects()) {
+ // Nothing to do after scrolling if there are no fixed position elements.
+ if (!hasViewportConstrainedObjects())
+ return;
+
+ RefPtr<FrameView> protect(this);
+
+ // If there fixed position elements, scrolling may cause compositing layers to change.
+ // Update widget and layer positions after scrolling, but only if we're not inside of
+ // layout.
+ if (!m_nestedLayoutCount) {
+ updateWidgetPositions();
if (RenderView* renderView = this->renderView()) {
- renderView->updateWidgetPositions();
renderView->layer()->updateLayerPositionsAfterDocumentScroll();
+ renderView->layer()->setNeedsCompositingInputsUpdate();
+ renderView->compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
}
}
}
-void FrameView::updateFixedElementsAfterScrolling()
+void FrameView::updateFixedElementPaintInvalidationRectsAfterScroll()
{
- if (m_nestedLayoutCount <= 1 && hasViewportConstrainedObjects()) {
- if (RenderView* renderView = this->renderView())
- renderView->compositor()->updateCompositingLayers(CompositingUpdateOnScroll);
- }
-}
+ if (!hasViewportConstrainedObjects())
+ return;
-bool FrameView::shouldRubberBandInDirection(ScrollDirection direction) const
-{
- Page* page = frame().page();
- if (!page)
- return ScrollView::shouldRubberBandInDirection(direction);
- return page->chrome().client().shouldRubberBandInDirection(direction);
+ // Update the paint invalidation rects for fixed elements after scrolling and invalidation to reflect
+ // the new scroll position.
+ ViewportConstrainedObjectSet::const_iterator end = m_viewportConstrainedObjects->end();
+ for (ViewportConstrainedObjectSet::const_iterator it = m_viewportConstrainedObjects->begin(); it != end; ++it) {
+ RenderObject* renderer = *it;
+ // m_viewportConstrainedObjects should not contain non-viewport constrained objects.
+ ASSERT(renderer->style()->hasViewportConstrainedPosition());
+
+ // Fixed items should always have layers.
+ ASSERT(renderer->hasLayer());
+
+ RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
+
+ // Don't need to do this for composited fixed items.
+ if (layer->compositingState() == PaintsIntoOwnBacking)
+ continue;
+
+ // Also don't need to do this for invisible items.
+ if (layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForBoundsOutOfView
+ || layer->viewportConstrainedNotCompositedReason() == RenderLayer::NotCompositedForNoVisibleContent)
+ continue;
+
+ layer->repainter().computeRepaintRectsIncludingNonCompositingDescendants();
+ }
}
bool FrameView::isRubberBandInProgress() const
@@ -1775,52 +1716,31 @@ HostWindow* FrameView::hostWindow() const
return &page->chrome();
}
-const unsigned cRepaintRectUnionThreshold = 25;
-
-void FrameView::repaintContentRectangle(const IntRect& r)
+void FrameView::contentRectangleForPaintInvalidation(const IntRect& r)
{
- ASSERT(!m_frame->ownerElement());
-
- if (m_isTrackingRepaints) {
- IntRect repaintRect = r;
- repaintRect.move(-scrollOffset());
- m_trackedRepaintRects.append(repaintRect);
- }
-
- double delay = m_deferringRepaints ? 0 : adjustedDeferredRepaintDelay();
- if (m_deferringRepaints || m_deferredRepaintTimer.isActive() || delay) {
- IntRect paintRect = r;
- if (clipsRepaints() && !paintsEntireContents())
- paintRect.intersect(visibleContentRect());
- if (paintRect.isEmpty())
- return;
- if (m_repaintCount == cRepaintRectUnionThreshold) {
- IntRect unionedRect;
- for (unsigned i = 0; i < cRepaintRectUnionThreshold; ++i)
- unionedRect.unite(pixelSnappedIntRect(m_repaintRects[i]));
- m_repaintRects.clear();
- m_repaintRects.append(unionedRect);
- }
- if (m_repaintCount < cRepaintRectUnionThreshold)
- m_repaintRects.append(paintRect);
- else
- m_repaintRects[0].unite(paintRect);
- m_repaintCount++;
+ ASSERT(paintInvalidationIsAllowed());
+ ASSERT(!m_frame->owner());
- if (!m_deferringRepaints)
- startDeferredRepaintTimer(delay);
-
- return;
+ if (m_isTrackingPaintInvalidations) {
+ IntRect paintInvalidationRect = r;
+ paintInvalidationRect.move(-scrollOffset());
+ m_trackedPaintInvalidationRects.append(paintInvalidationRect);
+ // FIXME: http://crbug.com/368518. Eventually, invalidateContentRectangleForPaint
+ // is going away entirely once all layout tests are FCM. In the short
+ // term, no code should be tracking non-composited FrameView paint invalidations.
+ RELEASE_ASSERT_NOT_REACHED();
}
- if (!shouldUpdate())
- return;
-
- ScrollView::repaintContentRectangle(r);
+ ScrollView::contentRectangleForPaintInvalidation(r);
}
void FrameView::contentsResized()
{
+ if (m_frame->isMainFrame() && m_frame->document()) {
+ if (FastTextAutosizer* textAutosizer = m_frame->document()->fastTextAutosizer())
+ textAutosizer->updatePageInfoInAllFrames();
+ }
+
ScrollView::contentsResized();
setNeedsLayout();
}
@@ -1828,7 +1748,7 @@ void FrameView::contentsResized()
void FrameView::scrollbarExistenceDidChange()
{
// We check to make sure the view is attached to a frame() as this method can
- // be triggered before the view is attached by Frame::createView(...) setting
+ // be triggered before the view is attached by LocalFrame::createView(...) setting
// various values such as setScrollBarModes(...) for example. An ASSERT is
// triggered when a view is layout before being attached to a frame().
if (!frame().view())
@@ -1852,151 +1772,20 @@ void FrameView::scrollbarExistenceDidChange()
}
}
-void FrameView::beginDeferredRepaints()
-{
- Page* page = m_frame->page();
- ASSERT(page);
-
- if (!isMainFrame()) {
- page->mainFrame()->view()->beginDeferredRepaints();
- return;
- }
-
- m_deferringRepaints++;
-}
-
-void FrameView::endDeferredRepaints()
-{
- Page* page = m_frame->page();
- ASSERT(page);
-
- if (!isMainFrame()) {
- page->mainFrame()->view()->endDeferredRepaints();
- return;
- }
-
- ASSERT(m_deferringRepaints > 0);
-
- if (--m_deferringRepaints)
- return;
-
- if (m_deferredRepaintTimer.isActive())
- return;
-
- if (double delay = adjustedDeferredRepaintDelay()) {
- startDeferredRepaintTimer(delay);
- return;
- }
-
- doDeferredRepaints();
-}
-
-void FrameView::startDeferredRepaintTimer(double delay)
-{
- if (m_deferredRepaintTimer.isActive())
- return;
-
- m_deferredRepaintTimer.startOneShot(delay);
-}
-
void FrameView::handleLoadCompleted()
{
// Once loading has completed, allow autoSize one last opportunity to
// reduce the size of the frame.
autoSizeIfEnabled();
- if (shouldUseLoadTimeDeferredRepaintDelay())
- return;
- m_deferredRepaintDelay = s_normalDeferredRepaintDelay;
- flushDeferredRepaints();
-}
-
-void FrameView::flushDeferredRepaints()
-{
- if (!m_deferredRepaintTimer.isActive())
- return;
- m_deferredRepaintTimer.stop();
- doDeferredRepaints();
-}
-
-void FrameView::doDeferredRepaints()
-{
- ASSERT(!m_deferringRepaints);
- if (!shouldUpdate()) {
- m_repaintRects.clear();
- m_repaintCount = 0;
- return;
- }
- unsigned size = m_repaintRects.size();
- for (unsigned i = 0; i < size; i++) {
- ScrollView::repaintContentRectangle(pixelSnappedIntRect(m_repaintRects[i]));
- }
- m_repaintRects.clear();
- m_repaintCount = 0;
-
- updateDeferredRepaintDelayAfterRepaint();
-}
-
-bool FrameView::shouldUseLoadTimeDeferredRepaintDelay() const
-{
- // Don't defer after the initial load of the page has been completed.
- if (m_frame->tree().top()->document()->loadEventFinished())
- return false;
- Document* document = m_frame->document();
- if (!document)
- return false;
- if (document->parsing())
- return true;
- if (document->fetcher()->requestCount())
- return true;
- return false;
-}
-
-void FrameView::updateDeferredRepaintDelayAfterRepaint()
-{
- if (!shouldUseLoadTimeDeferredRepaintDelay()) {
- m_deferredRepaintDelay = s_normalDeferredRepaintDelay;
- return;
- }
- double incrementedRepaintDelay = m_deferredRepaintDelay + s_deferredRepaintDelayIncrementDuringLoading;
- m_deferredRepaintDelay = std::min(incrementedRepaintDelay, s_maxDeferredRepaintDelayDuringLoading);
-}
-
-void FrameView::resetDeferredRepaintDelay()
-{
- m_deferredRepaintDelay = 0;
- if (m_deferredRepaintTimer.isActive()) {
- m_deferredRepaintTimer.stop();
- if (!m_deferringRepaints)
- doDeferredRepaints();
- }
-}
-
-double FrameView::adjustedDeferredRepaintDelay() const
-{
- ASSERT(!m_deferringRepaints);
- if (!m_deferredRepaintDelay)
- return 0;
- double timeSinceLastPaint = currentTime() - m_lastPaintTime;
- return max(0., m_deferredRepaintDelay - timeSinceLastPaint);
-}
-
-void FrameView::deferredRepaintTimerFired(Timer<FrameView>*)
-{
- doDeferredRepaints();
-}
-
-void FrameView::layoutTimerFired(Timer<FrameView>*)
-{
- layout();
}
void FrameView::scheduleRelayout()
{
ASSERT(m_frame->view() == this);
- if (m_layoutRoot) {
- m_layoutRoot->markContainingBlocksForLayout(false);
- m_layoutRoot = 0;
+ if (isSubtreeLayout()) {
+ m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
+ m_layoutSubtreeRoot = 0;
}
if (!m_layoutSchedulingEnabled)
return;
@@ -2004,21 +1793,17 @@ void FrameView::scheduleRelayout()
return;
if (!m_frame->document()->shouldScheduleLayout())
return;
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "InvalidateLayout", "frame", m_frame.get());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didInvalidateLayout(m_frame.get());
- // When frame seamless is enabled, the contents of the frame could affect the layout of the parent frames.
- // Also invalidate parent frame starting from the owner element of this frame.
- if (m_frame->ownerRenderer() && m_frame->document()->shouldDisplaySeamlesslyWithParent())
- m_frame->ownerRenderer()->setNeedsLayout();
-
- int delay = m_frame->document()->minimumLayoutDelay();
- if (m_layoutTimer.isActive() && m_delayedLayout && !delay)
- unscheduleRelayout();
- if (m_layoutTimer.isActive())
+ if (m_hasPendingLayout)
return;
+ m_hasPendingLayout = true;
- m_delayedLayout = delay != 0;
- m_layoutTimer.startOneShot(delay * 0.001);
+ page()->animator().scheduleVisualUpdate();
+ lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean);
}
static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
@@ -2034,6 +1819,10 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
{
ASSERT(m_frame->view() == this);
+ // FIXME: Should this call shouldScheduleLayout instead?
+ if (!m_frame->document()->isActive())
+ return;
+
RenderView* renderView = this->renderView();
if (renderView && renderView->needsLayout()) {
if (relayoutRoot)
@@ -2042,39 +1831,48 @@ void FrameView::scheduleRelayoutOfSubtree(RenderObject* relayoutRoot)
}
if (layoutPending() || !m_layoutSchedulingEnabled) {
- if (m_layoutRoot != relayoutRoot) {
- if (isObjectAncestorContainerOf(m_layoutRoot, relayoutRoot)) {
+ if (m_layoutSubtreeRoot != relayoutRoot) {
+ if (isObjectAncestorContainerOf(m_layoutSubtreeRoot, relayoutRoot)) {
// Keep the current root
- relayoutRoot->markContainingBlocksForLayout(false, m_layoutRoot);
- ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
- } else if (m_layoutRoot && isObjectAncestorContainerOf(relayoutRoot, m_layoutRoot)) {
+ relayoutRoot->markContainingBlocksForLayout(false, m_layoutSubtreeRoot);
+ ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
+ } else if (isSubtreeLayout() && isObjectAncestorContainerOf(relayoutRoot, m_layoutSubtreeRoot)) {
// Re-root at relayoutRoot
- m_layoutRoot->markContainingBlocksForLayout(false, relayoutRoot);
- m_layoutRoot = relayoutRoot;
- ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
- InspectorInstrumentation::didInvalidateLayout(m_frame.get());
+ m_layoutSubtreeRoot->markContainingBlocksForLayout(false, relayoutRoot);
+ m_layoutSubtreeRoot = relayoutRoot;
+ ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
} else {
// Just do a full relayout
- if (m_layoutRoot)
- m_layoutRoot->markContainingBlocksForLayout(false);
- m_layoutRoot = 0;
+ if (isSubtreeLayout())
+ m_layoutSubtreeRoot->markContainingBlocksForLayout(false);
+ m_layoutSubtreeRoot = 0;
relayoutRoot->markContainingBlocksForLayout(false);
- InspectorInstrumentation::didInvalidateLayout(m_frame.get());
}
}
} else if (m_layoutSchedulingEnabled) {
- int delay = m_frame->document()->minimumLayoutDelay();
- m_layoutRoot = relayoutRoot;
- ASSERT(!m_layoutRoot->container() || !m_layoutRoot->container()->needsLayout());
- InspectorInstrumentation::didInvalidateLayout(m_frame.get());
- m_delayedLayout = delay != 0;
- m_layoutTimer.startOneShot(delay * 0.001);
+ m_layoutSubtreeRoot = relayoutRoot;
+ ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
+ m_hasPendingLayout = true;
+
+ page()->animator().scheduleVisualUpdate();
+ lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean);
}
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "InvalidateLayout", "frame", m_frame.get());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didInvalidateLayout(m_frame.get());
}
bool FrameView::layoutPending() const
{
- return m_layoutTimer.isActive();
+ // FIXME: This should check Document::lifecycle instead.
+ return m_hasPendingLayout;
+}
+
+bool FrameView::isInPerformLayout() const
+{
+ ASSERT(m_inPerformLayout == (lifecycle().state() == DocumentLifecycle::InPerformLayout));
+ return m_inPerformLayout;
}
bool FrameView::needsLayout() const
@@ -2086,7 +1884,7 @@ bool FrameView::needsLayout() const
RenderView* renderView = this->renderView();
return layoutPending()
|| (renderView && renderView->needsLayout())
- || m_layoutRoot;
+ || isSubtreeLayout();
}
void FrameView::setNeedsLayout()
@@ -2095,33 +1893,6 @@ void FrameView::setNeedsLayout()
renderView->setNeedsLayout();
}
-void FrameView::unscheduleRelayout()
-{
- if (!m_layoutTimer.isActive())
- return;
-
- m_layoutTimer.stop();
- m_delayedLayout = false;
-}
-
-void FrameView::serviceScriptedAnimations(double monotonicAnimationStartTime)
-{
- for (RefPtr<Frame> frame = m_frame; frame; frame = frame->tree().traverseNext()) {
- frame->view()->serviceScrollAnimations();
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- frame->animation().serviceAnimations();
-
- DocumentAnimations::serviceOnAnimationFrame(*frame->document(), monotonicAnimationStartTime);
- }
-
- Vector<RefPtr<Document> > documents;
- for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext())
- documents.append(frame->document());
-
- for (size_t i = 0; i < documents.size(); ++i)
- documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime);
-}
-
bool FrameView::isTransparent() const
{
return m_isTransparent;
@@ -2130,6 +1901,7 @@ bool FrameView::isTransparent() const
void FrameView::setTransparent(bool isTransparent)
{
m_isTransparent = isTransparent;
+ DisableCompositingQueryAsserts disabler;
if (renderView() && renderView()->layer()->hasCompositedLayerMapping())
renderView()->layer()->compositedLayerMapping()->updateContentsOpaque();
}
@@ -2146,10 +1918,7 @@ Color FrameView::baseBackgroundColor() const
void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
{
- if (!backgroundColor.isValid())
- m_baseBackgroundColor = Color::white;
- else
- m_baseBackgroundColor = backgroundColor;
+ m_baseBackgroundColor = backgroundColor;
if (renderView() && renderView()->layer()->hasCompositedLayerMapping()) {
CompositedLayerMappingPtr compositedLayerMapping = renderView()->layer()->compositedLayerMapping();
@@ -2163,33 +1932,18 @@ void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
{
for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
- if (FrameView* view = frame->view()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (FrameView* view = toLocalFrame(frame)->view()) {
view->setTransparent(transparent);
view->setBaseBackgroundColor(backgroundColor);
}
}
}
-bool FrameView::shouldUpdateWhileOffscreen() const
-{
- return m_shouldUpdateWhileOffscreen;
-}
-
-void FrameView::setShouldUpdateWhileOffscreen(bool shouldUpdateWhileOffscreen)
-{
- m_shouldUpdateWhileOffscreen = shouldUpdateWhileOffscreen;
-}
-
-bool FrameView::shouldUpdate() const
-{
- if (isOffscreen() && !shouldUpdateWhileOffscreen())
- return false;
- return true;
-}
-
void FrameView::scrollToAnchor()
{
- RefPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
+ RefPtrWillBeRawPtr<Node> anchorNode = m_maintainScrollPositionAnchor;
if (!anchorNode)
return;
@@ -2213,6 +1967,10 @@ void FrameView::scrollToAnchor()
bool FrameView::updateWidgets()
{
+ // This is always called from updateWidgetsTimerFired.
+ // m_updateWidgetsTimer should only be scheduled if we have widgets to update.
+ // Thus I believe we can stop checking isEmpty here, and just ASSERT isEmpty:
+ ASSERT(!m_widgetUpdateSet.isEmpty());
if (m_nestedLayoutCount > 1 || m_widgetUpdateSet.isEmpty())
return true;
@@ -2247,6 +2005,7 @@ bool FrameView::updateWidgets()
void FrameView::updateWidgetsTimerFired(Timer<FrameView>*)
{
+ ASSERT(!isInPerformLayout());
RefPtr<FrameView> protect(this);
m_updateWidgetsTimer.stop();
for (unsigned i = 0; i < maxUpdateWidgetsIterations; ++i) {
@@ -2257,27 +2016,45 @@ void FrameView::updateWidgetsTimerFired(Timer<FrameView>*)
void FrameView::flushAnyPendingPostLayoutTasks()
{
+ ASSERT(!isInPerformLayout());
if (m_postLayoutTasksTimer.isActive())
performPostLayoutTasks();
if (m_updateWidgetsTimer.isActive())
updateWidgetsTimerFired(0);
}
+void FrameView::scheduleUpdateWidgetsIfNecessary()
+{
+ ASSERT(!isInPerformLayout());
+ if (m_updateWidgetsTimer.isActive() || m_widgetUpdateSet.isEmpty())
+ return;
+ m_updateWidgetsTimer.startOneShot(0, FROM_HERE);
+}
+
void FrameView::performPostLayoutTasks()
{
+ // FIXME: We can reach here, even when the page is not active!
+ // http/tests/inspector/elements/html-link-import.html and many other
+ // tests hit that case.
+ // We should ASSERT(isActive()); or at least return early if we can!
+ ASSERT(!isInPerformLayout()); // Always before or after performLayout(), part of the highest-level layout() call.
TRACE_EVENT0("webkit", "FrameView::performPostLayoutTasks");
RefPtr<FrameView> protect(this);
m_postLayoutTasksTimer.stop();
m_frame->selection().setCaretRectNeedsUpdate();
- m_frame->selection().updateAppearance();
+ {
+ // Hits in compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html
+ DisableCompositingQueryAsserts disabler;
+ m_frame->selection().updateAppearance();
+ }
+
+ ASSERT(m_frame->document());
if (m_nestedLayoutCount <= 1) {
- if (m_firstLayoutCallbackPending) {
+ if (m_firstLayoutCallbackPending)
m_firstLayoutCallbackPending = false;
- m_frame->loader().didFirstLayout();
- }
// Ensure that we always send this eventually.
if (!m_frame->document()->parsing() && m_frame->loader().stateMachine()->committedFirstRealDocumentLoad())
@@ -2292,14 +2069,15 @@ void FrameView::performPostLayoutTasks()
}
}
- FontFaceSet::didLayout(m_frame->document());
+ FontFaceSet::didLayout(*m_frame->document());
- RenderView* renderView = this->renderView();
- if (renderView)
- renderView->updateWidgetPositions();
+ updateWidgetPositions();
+
+ // Plugins could have torn down the page inside updateWidgetPositions().
+ if (!renderView())
+ return;
- if (!m_updateWidgetsTimer.isActive())
- m_updateWidgetsTimer.startOneShot(0);
+ scheduleUpdateWidgetsIfNecessary();
if (Page* page = m_frame->page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
@@ -2332,7 +2110,7 @@ void FrameView::sendResizeEventIfNeeded()
m_frame->document()->enqueueResizeEvent();
- if (isMainFrame())
+ if (m_frame->isMainFrame())
InspectorInstrumentation::didResizeMainFrame(m_frame->page());
}
@@ -2366,16 +2144,11 @@ void FrameView::autoSizeIfEnabled()
TemporaryChange<bool> changeInAutoSize(m_inAutoSize, true);
Document* document = frame().document();
- if (!document)
+ if (!document || !document->isActive())
return;
- RenderView* documentView = document->renderView();
Element* documentElement = document->documentElement();
- if (!documentView || !documentElement)
- return;
-
- RenderBox* documentRenderBox = documentElement->renderBox();
- if (!documentRenderBox)
+ if (!documentElement)
return;
// If this is the first time we run autosize, start from small height and
@@ -2390,7 +2163,17 @@ void FrameView::autoSizeIfEnabled()
for (int i = 0; i < 2; i++) {
// Update various sizes including contentsSize, scrollHeight, etc.
document->updateLayoutIgnorePendingStylesheets();
- int width = documentView->minPreferredLogicalWidth();
+
+ RenderView* renderView = document->renderView();
+ if (!renderView)
+ return;
+
+ int width = renderView->minPreferredLogicalWidth();
+
+ RenderBox* documentRenderBox = documentElement->renderBox();
+ if (!documentRenderBox)
+ return;
+
int height = documentRenderBox->scrollHeight();
IntSize newSize(width, height);
@@ -2471,35 +2254,14 @@ void FrameView::updateOverflowStatus(bool horizontalOverflow, bool verticalOverf
m_horizontalOverflow = horizontalOverflow;
m_verticalOverflow = verticalOverflow;
- RefPtr<OverflowEvent> event = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow);
+ RefPtrWillBeRawPtr<OverflowEvent> event = OverflowEvent::create(horizontalOverflowChanged, horizontalOverflow, verticalOverflowChanged, verticalOverflow);
event->setTarget(m_viewportRenderer->node());
m_frame->document()->enqueueAnimationFrameEvent(event.release());
}
}
-const Pagination& FrameView::pagination() const
-{
- if (m_pagination != Pagination())
- return m_pagination;
-
- if (isMainFrame())
- return m_frame->page()->pagination();
-
- return m_pagination;
-}
-
-void FrameView::setPagination(const Pagination& pagination)
-{
- if (m_pagination == pagination)
- return;
-
- m_pagination = pagination;
-
- m_frame->document()->styleResolverChanged(RecalcStyleDeferred);
-}
-
-IntRect FrameView::windowClipRect(bool clipToContents) const
+IntRect FrameView::windowClipRect(IncludeScrollbarsInRect scrollbarInclusion) const
{
ASSERT(m_frame->view() == this);
@@ -2507,19 +2269,20 @@ IntRect FrameView::windowClipRect(bool clipToContents) const
return IntRect(IntPoint(), contentsSize());
// Set our clip rect to be our contents.
- IntRect clipRect = contentsToWindow(visibleContentRect(clipToContents ? ExcludeScrollbars : IncludeScrollbars));
- if (!m_frame->ownerElement())
+ IntRect clipRect = contentsToWindow(visibleContentRect(scrollbarInclusion));
+ if (!m_frame->deprecatedLocalOwner())
return clipRect;
// Take our owner element and get its clip rect.
- HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement();
+ // FIXME: Do we need to do this for remote frames?
+ HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
FrameView* parentView = ownerElement->document().view();
if (parentView)
- clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement, true));
+ clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement));
return clipRect;
}
-IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement, bool clipToLayerContents) const
+IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement) const
{
// The renderer can sometimes be null when style="display:none" interacts
// with external content and plugins.
@@ -2531,13 +2294,12 @@ IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* owne
if (!enclosingLayer)
return windowClipRect();
+ // FIXME: childrenClipRect relies on compositingState, which is not necessarily up to date.
+ // https://code.google.com/p/chromium/issues/detail?id=343769
+ DisableCompositingQueryAsserts disabler;
+
// Apply the clip from the layer.
- IntRect clipRect;
- if (clipToLayerContents)
- clipRect = pixelSnappedIntRect(enclosingLayer->childrenClipRect());
- else
- clipRect = pixelSnappedIntRect(enclosingLayer->selfClipRect());
- clipRect = contentsToWindow(clipRect);
+ IntRect clipRect = contentsToWindow(pixelSnappedIntRect(enclosingLayer->clipper().childrenClipRect()));
return intersection(clipRect, windowClipRect());
}
@@ -2551,8 +2313,10 @@ void FrameView::scrollTo(const IntSize& newOffset)
{
LayoutSize offset = scrollOffset();
ScrollView::scrollTo(newOffset);
- if (offset != scrollOffset())
+ if (offset != scrollOffset()) {
+ updateLayersAndCompositingAfterScrollIfNeeded();
scrollPositionChanged();
+ }
frame().loader().client()->didChangeScrollOffset();
}
@@ -2561,12 +2325,26 @@ void FrameView::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rec
// Add in our offset within the FrameView.
IntRect dirtyRect = rect;
dirtyRect.moveBy(scrollbar->location());
- invalidateRect(dirtyRect);
+
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && isInPerformLayout()) {
+ if (scrollbar == verticalScrollbar()) {
+ m_verticalBarDamage = dirtyRect;
+ m_hasVerticalBarDamage = true;
+ } else {
+ m_horizontalBarDamage = dirtyRect;
+ m_hasHorizontalBarDamage = true;
+ }
+ } else {
+ invalidateRect(dirtyRect);
+ }
}
void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
{
- tickmarks = frame().document()->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
+ if (!m_tickmarks.isEmpty())
+ tickmarks = m_tickmarks;
+ else
+ tickmarks = frame().document()->markers().renderedRectsForMarkers(DocumentMarker::TextMatch);
}
IntRect FrameView::windowResizerRect() const
@@ -2599,7 +2377,10 @@ IntSize FrameView::inputEventsOffsetForEmulation() const
float FrameView::inputEventsScaleFactor() const
{
- return visibleContentScaleFactor() * m_inputEventsScaleFactorForEmulation;
+ float pageScale = m_frame->settings()->pinchVirtualViewportEnabled()
+ ? m_frame->page()->frameHost().pinchViewport().scale()
+ : visibleContentScaleFactor();
+ return pageScale * m_inputEventsScaleFactorForEmulation;
}
bool FrameView::scrollbarsCanBeActive() const
@@ -2610,12 +2391,6 @@ bool FrameView::scrollbarsCanBeActive() const
return !!m_frame->document();
}
-ScrollableArea* FrameView::enclosingScrollableArea() const
-{
- // FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer.
- return 0;
-}
-
IntRect FrameView::scrollableAreaBoundingBox() const
{
RenderPart* ownerRenderer = frame().ownerRenderer();
@@ -2640,14 +2415,15 @@ bool FrameView::isScrollable()
return false;
// Covers #2.
- HTMLFrameOwnerElement* owner = m_frame->ownerElement();
+ // FIXME: Do we need to fix this for OOPI?
+ HTMLFrameOwnerElement* owner = m_frame->deprecatedLocalOwner();
if (owner && (!owner->renderer() || !owner->renderer()->visibleToHitTesting()))
return false;
// Cover #3 and #4.
ScrollbarMode horizontalMode;
ScrollbarMode verticalMode;
- calculateScrollbarModesForLayout(horizontalMode, verticalMode, RulesFromWebContentOnly);
+ calculateScrollbarModesForLayoutAndSetViewportRenderer(horizontalMode, verticalMode, RulesFromWebContentOnly);
if (horizontalMode == ScrollbarAlwaysOff && verticalMode == ScrollbarAlwaysOff)
return false;
@@ -2674,33 +2450,12 @@ bool FrameView::shouldSuspendScrollAnimations() const
return m_frame->loader().state() != FrameStateComplete;
}
-void FrameView::scrollbarStyleChanged(int newStyle, bool forceUpdate)
-{
- if (!isMainFrame())
- return;
-
- if (forceUpdate)
- ScrollView::scrollbarStyleChanged(newStyle, forceUpdate);
-}
-
-void FrameView::setAnimatorsAreActive()
+void FrameView::scrollbarStyleChanged()
{
- Page* page = m_frame->page();
- if (!page)
- return;
-
- if (ScrollAnimator* scrollAnimator = existingScrollAnimator())
- scrollAnimator->setIsActive();
-
- if (!m_scrollableAreas)
+ // FIXME: Why does this only apply to the main frame?
+ if (!m_frame->isMainFrame())
return;
-
- for (HashSet<ScrollableArea*>::const_iterator it = m_scrollableAreas->begin(), end = m_scrollableAreas->end(); it != end; ++it) {
- ScrollableArea* scrollableArea = *it;
-
- ASSERT(scrollableArea->scrollbarsCanBeActive());
- scrollableArea->scrollAnimator()->setIsActive();
- }
+ ScrollView::scrollbarStyleChanged();
}
void FrameView::notifyPageThatContentAreaWillPaint() const
@@ -2726,9 +2481,7 @@ void FrameView::notifyPageThatContentAreaWillPaint() const
bool FrameView::scrollAnimatorEnabled() const
{
- if (m_frame->settings())
- return m_frame->settings()->scrollAnimatorEnabled();
- return false;
+ return m_frame->settings() && m_frame->settings()->scrollAnimatorEnabled();
}
void FrameView::updateAnnotatedRegions()
@@ -2767,7 +2520,7 @@ void FrameView::updateScrollCorner()
}
if (!cornerStyle) {
- // If we have an owning ipage/Frame element, then it can set the custom scrollbar also.
+ // If we have an owning ipage/LocalFrame element, then it can set the custom scrollbar also.
if (RenderPart* renderer = m_frame->ownerRenderer())
cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
}
@@ -2794,7 +2547,7 @@ void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& corne
}
if (m_scrollCorner) {
- bool needsBackgorund = isMainFrame();
+ bool needsBackgorund = m_frame->isMainFrame();
if (needsBackgorund)
context->fillRect(cornerRect, baseBackgroundColor());
m_scrollCorner->paintIntoRect(context, cornerRect.location(), cornerRect);
@@ -2806,7 +2559,7 @@ void FrameView::paintScrollCorner(GraphicsContext* context, const IntRect& corne
void FrameView::paintScrollbar(GraphicsContext* context, Scrollbar* bar, const IntRect& rect)
{
- bool needsBackgorund = bar->isCustomScrollbar() && isMainFrame();
+ bool needsBackgorund = bar->isCustomScrollbar() && m_frame->isMainFrame();
if (needsBackgorund) {
IntRect toFill = bar->frameRect();
toFill.intersect(rect);
@@ -2822,30 +2575,13 @@ Color FrameView::documentBackgroundColor() const
// the document and the body against the base background color of the frame view.
// Background images are unfortunately impractical to include.
- // Return invalid Color objects whenever there is insufficient information.
+ Color result = baseBackgroundColor();
if (!frame().document())
- return Color();
+ return result;
Element* htmlElement = frame().document()->documentElement();
Element* bodyElement = frame().document()->body();
- // Start with invalid colors.
- Color htmlBackgroundColor;
- Color bodyBackgroundColor;
- if (htmlElement && htmlElement->renderer())
- htmlBackgroundColor = htmlElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor);
- if (bodyElement && bodyElement->renderer())
- bodyBackgroundColor = bodyElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor);
-
- if (!bodyBackgroundColor.isValid()) {
- if (!htmlBackgroundColor.isValid())
- return Color();
- return baseBackgroundColor().blend(htmlBackgroundColor);
- }
-
- if (!htmlBackgroundColor.isValid())
- return baseBackgroundColor().blend(bodyBackgroundColor);
-
// We take the aggregate of the base background color
// the <html> background color, and the <body>
// background color to find the document color. The
@@ -2853,7 +2589,12 @@ Color FrameView::documentBackgroundColor() const
// technically part of the document background, but it
// otherwise poses problems when the aggregate is not
// fully opaque.
- return baseBackgroundColor().blend(htmlBackgroundColor).blend(bodyBackgroundColor);
+ if (htmlElement && htmlElement->renderer())
+ result = result.blend(htmlElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor));
+ if (bodyElement && bodyElement->renderer())
+ result = result.blend(bodyElement->renderer()->style()->visitedDependentColor(CSSPropertyBackgroundColor));
+
+ return result;
}
bool FrameView::hasCustomScrollbars() const
@@ -2880,8 +2621,9 @@ FrameView* FrameView::parentFrameView() const
if (!parent())
return 0;
- if (Frame* parentFrame = m_frame->tree().parent())
- return parentFrame->view();
+ Frame* parentFrame = m_frame->tree().parent();
+ if (parentFrame && parentFrame->isLocalFrame())
+ return toLocalFrame(parentFrame)->view();
return 0;
}
@@ -2897,14 +2639,14 @@ void FrameView::updateControlTints()
if (m_frame->document()->url().isEmpty())
return;
- if (RenderTheme::theme().supportsControlTints() || hasCustomScrollbars())
- paintControlTints();
-}
+ // FIXME: We shouldn't rely on the paint code to implement :window-inactive on custom scrollbars.
+ if (!RenderTheme::theme().supportsControlTints() && !hasCustomScrollbars())
+ return;
+
+ // Updating layout can run script, which can tear down the FrameView.
+ RefPtr<FrameView> protector(this);
+ updateLayoutAndStyleForPainting();
-void FrameView::paintControlTints()
-{
- if (needsLayout())
- layout();
// FIXME: The use of paint seems like overkill: crbug.com/236892
GraphicsContext context(0); // NULL canvas to get a non-painting context.
context.setUpdatingControlTints(true);
@@ -2920,7 +2662,7 @@ void FrameView::setWasScrolledByUser(bool wasScrolledByUser)
{
if (m_inProgrammaticScroll)
return;
- m_maintainScrollPositionAnchor = 0;
+ m_maintainScrollPositionAnchor = nullptr;
m_wasScrolledByUser = wasScrolledByUser;
}
@@ -2932,7 +2674,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
bool fillWithRed;
if (document->printing())
fillWithRed = false; // Printing, don't fill with red (can't remember why).
- else if (m_frame->ownerElement())
+ else if (m_frame->owner())
fillWithRed = false; // Subframe, don't fill with red.
else if (isTransparent())
fillWithRed = false; // Transparent, don't fill with red.
@@ -2957,6 +2699,9 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
if (needsLayout())
return;
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Paint", "data", InspectorPaintEvent::data(renderView, rect, 0));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::willPaint(renderView, 0);
bool isTopLevelPainter = !s_inPaintContents;
@@ -2972,7 +2717,7 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
}
if (m_paintBehavior == PaintBehaviorNormal)
- document->markers()->invalidateRenderedRectsForMarkersInRect(rect);
+ document->markers().invalidateRenderedRectsForMarkersInRect(rect);
if (document->printing())
m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
@@ -2981,19 +2726,18 @@ void FrameView::paintContents(GraphicsContext* p, const IntRect& rect)
m_isPainting = true;
// m_nodeToDraw is used to draw only one element (and its descendants)
- RenderObject* eltRenderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
+ RenderObject* renderer = m_nodeToDraw ? m_nodeToDraw->renderer() : 0;
RenderLayer* rootLayer = renderView->layer();
#ifndef NDEBUG
renderView->assertSubtreeIsLaidOut();
- RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(rootLayer->renderer());
+ RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(*rootLayer->renderer());
#endif
- RenderObject* enclosingLayerRenderer = eltRenderer->enclosingLayer() ? eltRenderer->enclosingLayer()->renderer() : eltRenderer;
- rootLayer->paint(p, rect, m_paintBehavior, enclosingLayerRenderer);
+ rootLayer->paint(p, rect, m_paintBehavior, renderer);
if (rootLayer->containsDirtyOverlayScrollbars())
- rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, eltRenderer);
+ rootLayer->paintOverlayScrollbars(p, rect, m_paintBehavior, renderer);
m_isPainting = false;
@@ -3042,7 +2786,7 @@ void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& hori
if (m_frame->document()->printing())
return;
- if (isMainFrame()) {
+ if (m_frame->isMainFrame()) {
if (m_frame->page()->chrome().client().paintCustomOverhangArea(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect))
return;
}
@@ -3050,6 +2794,27 @@ void FrameView::paintOverhangAreas(GraphicsContext* context, const IntRect& hori
ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
}
+void FrameView::updateLayoutAndStyleForPainting()
+{
+ // Updating layout can run script, which can tear down the FrameView.
+ RefPtr<FrameView> protector(this);
+
+ updateLayoutAndStyleIfNeededRecursive();
+
+ if (RenderView* view = renderView()) {
+ InspectorInstrumentation::willUpdateLayerTree(view->frame());
+
+ view->compositor()->updateIfNeededRecursive();
+
+ if (view->compositor()->inCompositingMode() && m_frame->isMainFrame())
+ m_frame->page()->scrollingCoordinator()->updateAfterCompositingChangeIfNeeded();
+
+ InspectorInstrumentation::didUpdateLayerTree(view->frame());
+ }
+
+ scrollContentsIfNeededRecursive();
+}
+
void FrameView::updateLayoutAndStyleIfNeededRecursive()
{
// We have to crawl our entire tree looking for any FrameViews that need
@@ -3061,29 +2826,43 @@ void FrameView::updateLayoutAndStyleIfNeededRecursive()
// region but then become included later by the second frame adding rects to the dirty region
// when it lays out.
- m_frame->document()->updateStyleIfNeeded();
+ m_frame->document()->updateRenderTreeIfNeeded();
if (needsLayout())
layout();
- // Grab a copy of the children() set, as it may be mutated by the following updateLayoutAndStyleIfNeededRecursive
- // calls, as they can potentially re-enter a layout of the parent frame view, which may add/remove scrollbars
- // and thus mutates the children() set.
+ // FIXME: Calling layout() shouldn't trigger scripe execution or have any
+ // observable effects on the frame tree but we're not quite there yet.
Vector<RefPtr<FrameView> > frameViews;
- collectFrameViewChildren(this, frameViews);
+ for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (!child->isLocalFrame())
+ continue;
+ if (FrameView* view = toLocalFrame(child)->view())
+ frameViews.append(view);
+ }
const Vector<RefPtr<FrameView> >::iterator end = frameViews.end();
for (Vector<RefPtr<FrameView> >::iterator it = frameViews.begin(); it != end; ++it)
(*it)->updateLayoutAndStyleIfNeededRecursive();
- // updateLayoutAndStyleIfNeededRecursive is called when we need to make sure style and layout are up-to-date before
- // painting, so we need to flush out any deferred repaints too.
- flushDeferredRepaints();
+ // When an <iframe> gets composited, it triggers an extra style recalc in its containing FrameView.
+ // To avoid pushing an invalid tree for display, we have to check for this case and do another
+ // style recalc. The extra style recalc needs to happen after our child <iframes> were updated.
+ // FIXME: We shouldn't be triggering an extra style recalc in the first place.
+ if (m_frame->document()->hasSVGFilterElementsRequiringLayerUpdate()) {
+ m_frame->document()->updateRenderTreeIfNeeded();
+
+ if (needsLayout())
+ layout();
+ }
- // When seamless is on, child frame can mark parent frame dirty. In such case, child frame
- // needs to call layout on parent frame recursively.
- // This assert ensures that parent frames are clean, when child frames finished updating layout and style.
+ // These asserts ensure that parent frames are clean, when child frames finished updating layout and style.
ASSERT(!needsLayout());
+ ASSERT(!m_frame->document()->hasSVGFilterElementsRequiringLayerUpdate());
+#ifndef NDEBUG
+ m_frame->document()->renderView()->assertRendererLaidOut();
+#endif
+
}
void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
@@ -3118,7 +2897,7 @@ void FrameView::forceLayout(bool allowSubtree)
layout(allowSubtree);
}
-void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot shouldAdjustViewSize)
+void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor)
{
// Dumping externalRepresentation(m_frame->renderer()).ascii() is a good trick to see
// the state of things before and after the layout
@@ -3130,7 +2909,7 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatS
LayoutUnit flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
renderView->setLogicalWidth(flooredPageLogicalWidth);
renderView->setPageLogicalHeight(flooredPageLogicalHeight);
- renderView->setNeedsLayoutAndPrefWidthsRecalc();
+ renderView->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
forceLayout();
// If we don't fit in the given page width, we'll lay out again. If we don't fit in the
@@ -3141,9 +2920,8 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatS
const LayoutRect& documentRect = renderView->documentRect();
LayoutUnit docLogicalWidth = horizontalWritingMode ? documentRect.width() : documentRect.height();
if (docLogicalWidth > pageLogicalWidth) {
- int expectedPageWidth = std::min<float>(documentRect.width(), pageSize.width() * maximumShrinkFactor);
- int expectedPageHeight = std::min<float>(documentRect.height(), pageSize.height() * maximumShrinkFactor);
- FloatSize maxPageSize = m_frame->resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), FloatSize(expectedPageWidth, expectedPageHeight));
+ FloatSize expectedPageSize(std::min<float>(documentRect.width().toFloat(), pageSize.width() * maximumShrinkFactor), std::min<float>(documentRect.height().toFloat(), pageSize.height() * maximumShrinkFactor));
+ FloatSize maxPageSize = m_frame->resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), expectedPageSize);
pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
@@ -3151,7 +2929,7 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatS
flooredPageLogicalHeight = static_cast<LayoutUnit>(pageLogicalHeight);
renderView->setLogicalWidth(flooredPageLogicalWidth);
renderView->setPageLogicalHeight(flooredPageLogicalHeight);
- renderView->setNeedsLayoutAndPrefWidthsRecalc();
+ renderView->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
forceLayout();
const LayoutRect& updatedDocumentRect = renderView->documentRect();
@@ -3170,13 +2948,12 @@ void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatS
}
}
- if (shouldAdjustViewSize)
- adjustViewSize();
+ adjustViewSize();
}
-IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRect& rendererRect) const
+IntRect FrameView::convertFromRenderer(const RenderObject& renderer, const IntRect& rendererRect) const
{
- IntRect rect = pixelSnappedIntRect(enclosingLayoutRect(renderer->localToAbsoluteQuad(FloatRect(rendererRect)).boundingBox()));
+ IntRect rect = pixelSnappedIntRect(enclosingLayoutRect(renderer.localToAbsoluteQuad(FloatRect(rendererRect)).boundingBox()));
// Convert from page ("absolute") to FrameView coordinates.
rect.moveBy(-scrollPosition());
@@ -3184,7 +2961,7 @@ IntRect FrameView::convertFromRenderer(const RenderObject* renderer, const IntRe
return rect;
}
-IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect& viewRect) const
+IntRect FrameView::convertToRenderer(const RenderObject& renderer, const IntRect& viewRect) const
{
IntRect rect = viewRect;
@@ -3193,27 +2970,27 @@ IntRect FrameView::convertToRenderer(const RenderObject* renderer, const IntRect
// FIXME: we don't have a way to map an absolute rect down to a local quad, so just
// move the rect for now.
- rect.setLocation(roundedIntPoint(renderer->absoluteToLocal(rect.location(), UseTransforms)));
+ rect.setLocation(roundedIntPoint(renderer.absoluteToLocal(rect.location(), UseTransforms)));
return rect;
}
-IntPoint FrameView::convertFromRenderer(const RenderObject* renderer, const IntPoint& rendererPoint) const
+IntPoint FrameView::convertFromRenderer(const RenderObject& renderer, const IntPoint& rendererPoint) const
{
- IntPoint point = roundedIntPoint(renderer->localToAbsolute(rendererPoint, UseTransforms));
+ IntPoint point = roundedIntPoint(renderer.localToAbsolute(rendererPoint, UseTransforms));
// Convert from page ("absolute") to FrameView coordinates.
point.moveBy(-scrollPosition());
return point;
}
-IntPoint FrameView::convertToRenderer(const RenderObject* renderer, const IntPoint& viewPoint) const
+IntPoint FrameView::convertToRenderer(const RenderObject& renderer, const IntPoint& viewPoint) const
{
IntPoint point = viewPoint;
// Convert from FrameView coords into page ("absolute") coordinates.
point += IntSize(scrollX(), scrollY());
- return roundedIntPoint(renderer->absoluteToLocal(point, UseTransforms));
+ return roundedIntPoint(renderer.absoluteToLocal(point, UseTransforms));
}
IntRect FrameView::convertToContainingView(const IntRect& localRect) const
@@ -3230,7 +3007,7 @@ IntRect FrameView::convertToContainingView(const IntRect& localRect) const
// Add borders and padding??
rect.move(renderer->borderLeft() + renderer->paddingLeft(),
renderer->borderTop() + renderer->paddingTop());
- return parentView->convertFromRenderer(renderer, rect);
+ return parentView->convertFromRenderer(*renderer, rect);
}
return Widget::convertToContainingView(localRect);
@@ -3250,7 +3027,7 @@ IntRect FrameView::convertFromContainingView(const IntRect& parentRect) const
if (!renderer)
return parentRect;
- IntRect rect = parentView->convertToRenderer(renderer, parentRect);
+ IntRect rect = parentView->convertToRenderer(*renderer, parentRect);
// Subtract borders and padding
rect.move(-renderer->borderLeft() - renderer->paddingLeft(),
-renderer->borderTop() - renderer->paddingTop());
@@ -3279,7 +3056,7 @@ IntPoint FrameView::convertToContainingView(const IntPoint& localPoint) const
// Add borders and padding
point.move(renderer->borderLeft() + renderer->paddingLeft(),
renderer->borderTop() + renderer->paddingTop());
- return parentView->convertFromRenderer(renderer, point);
+ return parentView->convertFromRenderer(*renderer, point);
}
return Widget::convertToContainingView(localPoint);
@@ -3299,7 +3076,7 @@ IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
if (!renderer)
return parentPoint;
- IntPoint point = parentView->convertToRenderer(renderer, parentPoint);
+ IntPoint point = parentView->convertToRenderer(*renderer, parentPoint);
// Subtract borders and padding
point.move(-renderer->borderLeft() - renderer->paddingLeft(),
-renderer->borderTop() - renderer->paddingTop());
@@ -3312,107 +3089,74 @@ IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
return parentPoint;
}
-// Normal delay
-void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
-{
- s_normalDeferredRepaintDelay = p;
-}
-
-// Negative value would mean that first few repaints happen without a delay
-void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
+void FrameView::setTracksPaintInvalidations(bool trackPaintInvalidations)
{
- s_initialDeferredRepaintDelayDuringLoading = p;
-}
-
-// The delay grows on each repaint to this maximum value
-void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
-{
- s_maxDeferredRepaintDelayDuringLoading = p;
-}
-
-// On each repaint the delay increases by this amount
-void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
-{
- s_deferredRepaintDelayIncrementDuringLoading = p;
-}
-
-void FrameView::setTracksRepaints(bool trackRepaints)
-{
- if (trackRepaints == m_isTrackingRepaints)
+ if (trackPaintInvalidations == m_isTrackingPaintInvalidations)
return;
for (Frame* frame = m_frame->tree().top(); frame; frame = frame->tree().traverseNext()) {
- if (RenderView* renderView = frame->contentRenderer())
- renderView->compositor()->setTracksRepaints(trackRepaints);
+ if (!frame->isLocalFrame())
+ continue;
+ if (RenderView* renderView = toLocalFrame(frame)->contentRenderer())
+ renderView->compositor()->setTracksRepaints(trackPaintInvalidations);
}
- resetTrackedRepaints();
- m_isTrackingRepaints = trackRepaints;
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"),
+ "FrameView::setTracksPaintInvalidations", "enabled", trackPaintInvalidations);
+
+ resetTrackedPaintInvalidations();
+ m_isTrackingPaintInvalidations = trackPaintInvalidations;
}
-void FrameView::resetTrackedRepaints()
+void FrameView::resetTrackedPaintInvalidations()
{
- m_trackedRepaintRects.clear();
+ m_trackedPaintInvalidationRects.clear();
if (RenderView* renderView = this->renderView())
renderView->compositor()->resetTrackedRepaintRects();
}
-String FrameView::trackedRepaintRectsAsText() const
+String FrameView::trackedPaintInvalidationRectsAsText() const
{
TextStream ts;
- if (!m_trackedRepaintRects.isEmpty()) {
+ if (!m_trackedPaintInvalidationRects.isEmpty()) {
ts << "(repaint rects\n";
- for (size_t i = 0; i < m_trackedRepaintRects.size(); ++i)
- ts << " (rect " << m_trackedRepaintRects[i].x() << " " << m_trackedRepaintRects[i].y() << " " << m_trackedRepaintRects[i].width() << " " << m_trackedRepaintRects[i].height() << ")\n";
+ for (size_t i = 0; i < m_trackedPaintInvalidationRects.size(); ++i)
+ ts << " (rect " << m_trackedPaintInvalidationRects[i].x() << " " << m_trackedPaintInvalidationRects[i].y() << " " << m_trackedPaintInvalidationRects[i].width() << " " << m_trackedPaintInvalidationRects[i].height() << ")\n";
ts << ")\n";
}
return ts.release();
}
-void FrameView::addResizerArea(RenderBox* resizerBox)
+void FrameView::addResizerArea(RenderBox& resizerBox)
{
if (!m_resizerAreas)
m_resizerAreas = adoptPtr(new ResizerAreaSet);
- m_resizerAreas->add(resizerBox);
+ m_resizerAreas->add(&resizerBox);
}
-void FrameView::removeResizerArea(RenderBox* resizerBox)
+void FrameView::removeResizerArea(RenderBox& resizerBox)
{
if (!m_resizerAreas)
return;
- ResizerAreaSet::iterator it = m_resizerAreas->find(resizerBox);
+ ResizerAreaSet::iterator it = m_resizerAreas->find(&resizerBox);
if (it != m_resizerAreas->end())
m_resizerAreas->remove(it);
}
-bool FrameView::addScrollableArea(ScrollableArea* scrollableArea)
+void FrameView::addScrollableArea(ScrollableArea* scrollableArea)
{
ASSERT(scrollableArea);
if (!m_scrollableAreas)
m_scrollableAreas = adoptPtr(new ScrollableAreaSet);
- return m_scrollableAreas->add(scrollableArea).isNewEntry;
+ m_scrollableAreas->add(scrollableArea);
}
-bool FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
+void FrameView::removeScrollableArea(ScrollableArea* scrollableArea)
{
if (!m_scrollableAreas)
- return false;
-
- ScrollableAreaSet::iterator it = m_scrollableAreas->find(scrollableArea);
- if (it == m_scrollableAreas->end())
- return false;
-
- m_scrollableAreas->remove(it);
- return true;
-}
-
-bool FrameView::containsScrollableArea(const ScrollableArea* scrollableArea) const
-{
- ASSERT(scrollableArea);
- if (!m_scrollableAreas || !scrollableArea)
- return false;
- return m_scrollableAreas->contains(const_cast<ScrollableArea*>(scrollableArea));
+ return;
+ m_scrollableAreas->remove(scrollableArea);
}
void FrameView::removeChild(Widget* widget)
@@ -3425,18 +3169,24 @@ void FrameView::removeChild(Widget* widget)
bool FrameView::wheelEvent(const PlatformWheelEvent& wheelEvent)
{
+ bool allowScrolling = userInputScrollable(HorizontalScrollbar) || userInputScrollable(VerticalScrollbar);
+
// Note that to allow for rubber-band over-scroll behavior, even non-scrollable views
// should handle wheel events.
#if !USE(RUBBER_BANDING)
if (!isScrollable())
- return false;
+ allowScrolling = false;
#endif
- // We don't allow mouse wheeling to happen in a ScrollView that has had its scrollbars explicitly disabled.
- if (!canHaveScrollbars())
- return false;
+ if (allowScrolling && ScrollableArea::handleWheelEvent(wheelEvent))
+ return true;
- return ScrollableArea::handleWheelEvent(wheelEvent);
+ // If the frame didn't handle the event, give the pinch-zoom viewport a chance to
+ // process the scroll event.
+ if (m_frame->settings()->pinchVirtualViewportEnabled() && m_frame->isMainFrame())
+ return page()->frameHost().pinchViewport().handleWheelEvent(wheelEvent);
+
+ return false;
}
bool FrameView::isVerticalDocument() const
@@ -3467,16 +3217,11 @@ AXObjectCache* FrameView::axObjectCache() const
void FrameView::setCursor(const Cursor& cursor)
{
Page* page = frame().page();
- if (!page)
+ if (!page || !page->settings().deviceSupportsMouse())
return;
page->chrome().setCursor(cursor);
}
-bool FrameView::isMainFrame() const
-{
- return m_frame->isMainFrame();
-}
-
void FrameView::frameRectsChanged()
{
if (layoutSizeFixedToFrameSize())
diff --git a/chromium/third_party/WebKit/Source/core/frame/FrameView.h b/chromium/third_party/WebKit/Source/core/frame/FrameView.h
index e408b984c70..9585f6c9e98 100644
--- a/chromium/third_party/WebKit/Source/core/frame/FrameView.h
+++ b/chromium/third_party/WebKit/Source/core/frame/FrameView.h
@@ -25,10 +25,8 @@
#ifndef FrameView_h
#define FrameView_h
-#include "core/frame/AdjustViewSizeOrNot.h"
-#include "core/rendering/Pagination.h"
#include "core/rendering/PaintPhase.h"
-#include "core/rendering/PartialLayoutState.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/geometry/LayoutRect.h"
#include "platform/graphics/Color.h"
#include "platform/scroll/ScrollView.h"
@@ -39,9 +37,12 @@
namespace WebCore {
class AXObjectCache;
+class DocumentLifecycle;
+class Cursor;
class Element;
class FloatSize;
-class Frame;
+class HTMLFrameOwnerElement;
+class LocalFrame;
class KURL;
class Node;
class Page;
@@ -50,60 +51,56 @@ class RenderEmbeddedObject;
class RenderObject;
class RenderScrollbarPart;
class RenderStyle;
-
-Pagination::Mode paginationModeForRenderStyle(RenderStyle*);
+class RenderView;
+class RenderWidget;
typedef unsigned long long DOMTimeStamp;
-class FrameView : public ScrollView {
+class FrameView FINAL : public ScrollView {
public:
friend class RenderView;
friend class Internals;
- static PassRefPtr<FrameView> create(Frame*);
- static PassRefPtr<FrameView> create(Frame*, const IntSize& initialSize);
+ static PassRefPtr<FrameView> create(LocalFrame*);
+ static PassRefPtr<FrameView> create(LocalFrame*, const IntSize& initialSize);
virtual ~FrameView();
- virtual HostWindow* hostWindow() const;
+ virtual HostWindow* hostWindow() const OVERRIDE;
- virtual void invalidateRect(const IntRect&);
- virtual void setFrameRect(const IntRect&);
+ virtual void invalidateRect(const IntRect&) OVERRIDE;
+ virtual void setFrameRect(const IntRect&) OVERRIDE;
- virtual bool scheduleAnimation();
+ virtual bool scheduleAnimation() OVERRIDE;
- Frame& frame() const { return *m_frame; }
+ LocalFrame& frame() const { return *m_frame; }
+ Page* page() const;
RenderView* renderView() const;
- LayoutUnit marginWidth() const { return m_margins.width(); } // -1 means default
- LayoutUnit marginHeight() const { return m_margins.height(); } // -1 means default
- void setMarginWidth(LayoutUnit);
- void setMarginHeight(LayoutUnit);
-
- virtual void setCanHaveScrollbars(bool);
- void updateCanHaveScrollbars();
+ virtual void setCanHaveScrollbars(bool) OVERRIDE;
- virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation);
+ virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation) OVERRIDE;
- virtual void setContentsSize(const IntSize&);
+ virtual void setContentsSize(const IntSize&) OVERRIDE;
+ IntPoint clampOffsetAtScale(const IntPoint& offset, float scale) const;
void layout(bool allowSubtree = true);
bool didFirstLayout() const;
- void layoutTimerFired(Timer<FrameView>*);
void scheduleRelayout();
void scheduleRelayoutOfSubtree(RenderObject*);
- void unscheduleRelayout();
bool layoutPending() const;
- bool isInLayout() const { return m_inLayout; }
+ bool isInPerformLayout() const;
+
+ void setCanInvalidatePaintDuringPerformLayout(bool b) { m_canInvalidatePaintDuringPerformLayout = b; }
+ bool canInvalidatePaintDuringPerformLayout() const { return m_canInvalidatePaintDuringPerformLayout; }
RenderObject* layoutRoot(bool onlyDuringLayout = false) const;
- void clearLayoutRoot() { m_layoutRoot = 0; }
+ void clearLayoutSubtreeRoot() { m_layoutSubtreeRoot = 0; }
int layoutCount() const { return m_layoutCount; }
bool needsLayout() const;
void setNeedsLayout();
- void setViewportConstrainedObjectsNeedLayout();
// Methods for getting/setting the size Blink should use to layout the contents.
IntSize layoutSize(IncludeScrollbarsInRect = ExcludeScrollbars) const;
@@ -114,20 +111,15 @@ public:
void setLayoutSizeFixedToFrameSize(bool isFixed) { m_layoutSizeFixedToFrameSize = isFixed; }
bool layoutSizeFixedToFrameSize() { return m_layoutSizeFixedToFrameSize; }
- bool needsFullRepaint() const { return m_doFullRepaint; }
+ bool needsFullPaintInvalidation() const { return m_doFullPaintInvalidation; }
- void serviceScriptedAnimations(double monotonicAnimationStartTime);
+ void updateAcceleratedCompositingSettings();
- void updateCompositingLayersAfterStyleChange();
- void updateCompositingLayersAfterLayout();
+ void recalcOverflowAfterStyleChange();
bool hasCompositedContent() const;
bool isEnclosedInCompositingLayer() const;
- // Returns true when a paint with the PaintBehaviorFlattenCompositingLayers flag set gives
- // a faithful representation of the content.
- bool isSoftwareRenderable() const;
-
void resetScrollbars();
void prepareForDetach();
void detachCustomScrollbars();
@@ -145,16 +137,12 @@ public:
void setBaseBackgroundColor(const Color&);
void updateBackgroundRecursively(const Color&, bool);
- bool shouldUpdateWhileOffscreen() const;
- void setShouldUpdateWhileOffscreen(bool);
- bool shouldUpdate() const;
-
void adjustViewSize();
- virtual IntRect windowClipRect(bool clipToContents = true) const;
- IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*, bool clipToLayerContents) const;
+ virtual IntRect windowClipRect(IncludeScrollbarsInRect = ExcludeScrollbars) const OVERRIDE;
+ IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*) const;
- virtual IntRect windowResizerRect() const;
+ virtual IntRect windowResizerRect() const OVERRIDE;
virtual float visibleContentScaleFactor() const OVERRIDE { return m_visibleContentScaleFactor; }
void setVisibleContentScaleFactor(float);
@@ -164,15 +152,13 @@ public:
void setInputEventsTransformForEmulation(const IntSize&, float);
virtual void setScrollPosition(const IntPoint&) OVERRIDE;
- virtual void repaintFixedElementsAfterScrolling();
- virtual void updateFixedElementsAfterScrolling();
- virtual bool shouldRubberBandInDirection(ScrollDirection) const;
virtual bool isRubberBandInProgress() const OVERRIDE;
void setScrollPositionNonProgrammatically(const IntPoint&);
// This is different than visibleContentRect() in that it ignores negative (or overly positive)
// offsets from rubber-banding, and it takes zooming into account.
LayoutRect viewportConstrainedVisibleContentRect() const;
+ void viewportConstrainedVisibleContentSizeChanged(bool widthChanged, bool heightChanged);
AtomicString mediaType() const;
void setMediaType(const AtomicString&);
@@ -181,7 +167,6 @@ public:
void setCannotBlitToWindow();
void setIsOverlapped(bool);
bool isOverlapped() const { return m_isOverlapped; }
- bool isOverlappedIncludingAncestors() const;
void setContentIsOpaque(bool);
void addSlowRepaintObject();
@@ -196,7 +181,6 @@ public:
bool hasViewportConstrainedObjects() const { return m_viewportConstrainedObjects && m_viewportConstrainedObjects->size() > 0; }
void handleLoadCompleted();
- void resetDeferredRepaintDelay();
void updateAnnotatedRegions();
void updateControlTints();
@@ -211,63 +195,58 @@ public:
bool safeToPropagateScrollToParent() const { return m_safeToPropagateScrollToParent; }
void setSafeToPropagateScrollToParent(bool isSafe) { m_safeToPropagateScrollToParent = isSafe; }
+ void addWidget(RenderWidget*);
+ void removeWidget(RenderWidget*);
+ void updateWidgetPositions();
+
void addWidgetToUpdate(RenderEmbeddedObject&);
- virtual void paintContents(GraphicsContext*, const IntRect& damageRect);
+ virtual void paintContents(GraphicsContext*, const IntRect& damageRect) OVERRIDE;
void setPaintBehavior(PaintBehavior);
PaintBehavior paintBehavior() const;
bool isPainting() const;
bool hasEverPainted() const { return m_lastPaintTime; }
- void setLastPaintTime(double lastPaintTime) { m_lastPaintTime = lastPaintTime; }
void setNodeToDraw(Node*);
- virtual void paintOverhangAreas(GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect);
- virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect);
+ virtual void paintOverhangAreas(GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect) OVERRIDE;
+ virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect) OVERRIDE;
virtual void paintScrollbar(GraphicsContext*, Scrollbar*, const IntRect&) OVERRIDE;
Color documentBackgroundColor() const;
static double currentFrameTimeStamp() { return s_currentFrameTimeStamp; }
+ void updateLayoutAndStyleForPainting();
void updateLayoutAndStyleIfNeededRecursive();
void incrementVisuallyNonEmptyCharacterCount(unsigned);
void incrementVisuallyNonEmptyPixelCount(const IntSize&);
void setIsVisuallyNonEmpty() { m_isVisuallyNonEmpty = true; }
- bool isVisuallyNonEmpty() const { return m_isVisuallyNonEmpty; }
void enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize);
void forceLayout(bool allowSubtree = false);
- void forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot);
+ void forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor);
bool scrollToFragment(const KURL&);
bool scrollToAnchor(const String&);
void maintainScrollPositionAtAnchor(Node*);
void scrollElementToRect(Element*, const IntRect&);
+ void scrollContentsIfNeededRecursive();
// Methods to convert points and rects between the coordinate space of the renderer, and this view.
- virtual IntRect convertFromRenderer(const RenderObject*, const IntRect&) const;
- virtual IntRect convertToRenderer(const RenderObject*, const IntRect&) const;
- virtual IntPoint convertFromRenderer(const RenderObject*, const IntPoint&) const;
- virtual IntPoint convertToRenderer(const RenderObject*, const IntPoint&) const;
+ IntRect convertFromRenderer(const RenderObject&, const IntRect&) const;
+ IntRect convertToRenderer(const RenderObject&, const IntRect&) const;
+ IntPoint convertFromRenderer(const RenderObject&, const IntPoint&) const;
+ IntPoint convertToRenderer(const RenderObject&, const IntPoint&) const;
bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
bool isScrollable();
enum ScrollbarModesCalculationStrategy { RulesFromWebContentOnly, AnyRule };
- void calculateScrollbarModesForLayout(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy = AnyRule);
-
- // Normal delay
- static void setRepaintThrottlingDeferredRepaintDelay(double);
- // Negative value would mean that first few repaints happen without a delay
- static void setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double);
- // The delay grows on each repaint to this maximum value
- static void setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double);
- // On each repaint the delay increses by this amount
- static void setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double);
-
- virtual IntPoint lastKnownMousePosition() const;
+ void calculateScrollbarModesForLayoutAndSetViewportRenderer(ScrollbarMode& hMode, ScrollbarMode& vMode, ScrollbarModesCalculationStrategy = AnyRule);
+
+ virtual IntPoint lastKnownMousePosition() const OVERRIDE;
bool shouldSetCursor() const;
void setCursor(const Cursor&);
@@ -277,33 +256,27 @@ public:
// FIXME: Remove this method once plugin loading is decoupled from layout.
void flushAnyPendingPostLayoutTasks();
- virtual bool shouldSuspendScrollAnimations() const;
- virtual void scrollbarStyleChanged(int newStyle, bool forceUpdate);
-
- void setAnimatorsAreActive();
+ virtual bool shouldSuspendScrollAnimations() const OVERRIDE;
+ virtual void scrollbarStyleChanged() OVERRIDE;
RenderBox* embeddedContentBox() const;
- void setTracksRepaints(bool);
- bool isTrackingRepaints() const { return m_isTrackingRepaints; }
- void resetTrackedRepaints();
- const Vector<IntRect>& trackedRepaintRects() const { return m_trackedRepaintRects; }
- String trackedRepaintRectsAsText() const;
+ void setTracksPaintInvalidations(bool);
+ bool isTrackingPaintInvalidations() const { return m_isTrackingPaintInvalidations; }
+ void resetTrackedPaintInvalidations();
+ String trackedPaintInvalidationRectsAsText() const;
typedef HashSet<ScrollableArea*> ScrollableAreaSet;
- // Returns whether the scrollable area has just been newly added.
- bool addScrollableArea(ScrollableArea*);
- // Returns whether the scrollable area has just been removed.
- bool removeScrollableArea(ScrollableArea*);
- bool containsScrollableArea(const ScrollableArea*) const;
+ void addScrollableArea(ScrollableArea*);
+ void removeScrollableArea(ScrollableArea*);
const ScrollableAreaSet* scrollableAreas() const { return m_scrollableAreas.get(); }
// With CSS style "resize:" enabled, a little resizer handle will appear at the bottom
// right of the object. We keep track of these resizer areas for checking if touches
// (implemented using Scroll gesture) are targeting the resizer.
typedef HashSet<RenderBox*> ResizerAreaSet;
- void addResizerArea(RenderBox*);
- void removeResizerArea(RenderBox*);
+ void addResizerArea(RenderBox&);
+ void removeResizerArea(RenderBox&);
const ResizerAreaSet* resizerAreas() const { return m_resizerAreas.get(); }
virtual void removeChild(Widget*) OVERRIDE;
@@ -313,15 +286,6 @@ public:
// we need this function in order to do the scroll ourselves.
bool wheelEvent(const PlatformWheelEvent&);
- // Page and FrameView both store a Pagination value. Page::pagination() is set only by API,
- // and FrameView::pagination() is set only by CSS. Page::pagination() will affect all
- // FrameViews in the page cache, but FrameView::pagination() only affects the current
- // FrameView. FrameView::pagination() will return m_pagination if it has been set. Otherwise,
- // it will return Page::pagination() since currently there are no callers that need to
- // distinguish between the two.
- const Pagination& pagination() const;
- void setPagination(const Pagination&);
-
bool inProgrammaticScroll() const { return m_inProgrammaticScroll; }
void setInProgrammaticScroll(bool programmaticScroll) { m_inProgrammaticScroll = programmaticScroll; }
@@ -333,54 +297,59 @@ public:
// DEPRECATED: Use viewportConstrainedVisibleContentRect() instead.
IntSize scrollOffsetForFixedPosition() const;
- PartialLayoutState& partialLayout() { return m_partialLayout; }
-
// Override scrollbar notifications to update the AXObject cache.
virtual void didAddScrollbar(Scrollbar*, ScrollbarOrientation) OVERRIDE;
virtual void willRemoveScrollbar(Scrollbar*, ScrollbarOrientation) OVERRIDE;
- class DeferredRepaintScope {
- public:
- DeferredRepaintScope(FrameView&);
- ~DeferredRepaintScope();
- private:
- RefPtr<FrameView> m_view;
- };
+ virtual bool shouldAttemptToScrollUsingFastPath() const OVERRIDE;
+ // FIXME: This should probably be renamed as the 'inSubtreeLayout' parameter
+ // passed around the FrameView layout methods can be true while this returns
+ // false.
+ bool isSubtreeLayout() const { return !!m_layoutSubtreeRoot; }
+
+ // Sets the tickmarks for the FrameView, overriding the default behavior
+ // which is to display the tickmarks corresponding to find results.
+ // If |m_tickmarks| is empty, the default behavior is restored.
+ void setTickmarks(const Vector<IntRect>& tickmarks) { m_tickmarks = tickmarks; }
+
+ // ScrollableArea interface
+ virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE;
+ virtual void getTickmarks(Vector<IntRect>&) const OVERRIDE;
+ virtual void scrollTo(const IntSize&) OVERRIDE;
+ virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
+ virtual bool scrollAnimatorEnabled() const OVERRIDE;
+ virtual bool usesCompositedScrolling() const OVERRIDE;
+ virtual GraphicsLayer* layerForScrolling() const OVERRIDE;
+ virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
+ virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE;
+ virtual GraphicsLayer* layerForScrollCorner() const OVERRIDE;
protected:
- virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
- virtual void scrollContentsSlowPath(const IntRect& updateRect);
+ virtual void scrollContentsIfNeeded();
+ virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) OVERRIDE;
+ virtual void scrollContentsSlowPath(const IntRect& updateRect) OVERRIDE;
- virtual bool isVerticalDocument() const;
- virtual bool isFlippedDocument() const;
+ virtual bool isVerticalDocument() const OVERRIDE;
+ virtual bool isFlippedDocument() const OVERRIDE;
private:
- explicit FrameView(Frame*);
-
- void beginDeferredRepaints();
- void endDeferredRepaints();
- void flushDeferredRepaints();
- void startDeferredRepaintTimer(double delay);
+ explicit FrameView(LocalFrame*);
void reset();
void init();
- virtual void frameRectsChanged();
+ virtual void frameRectsChanged() OVERRIDE;
virtual bool isFrameView() const OVERRIDE { return true; }
friend class RenderWidget;
bool useSlowRepaints(bool considerOverlap = true) const;
bool useSlowRepaintsIfNotOverlapped() const;
- void updateCanBlitOnScrollRecursively();
- bool contentsInCompositedLayer() const;
- void applyOverflowToViewport(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
- void applyPaginationToViewport();
+ bool contentsInCompositedLayer() const;
+ void applyOverflowToViewportAndSetRenderer(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
void updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow);
- void paintControlTints();
-
void updateCounters();
void autoSizeIfEnabled();
void forceLayoutParentViewIfNeeded();
@@ -389,13 +358,15 @@ private:
void scheduleOrPerformPostLayoutTasks();
void performPostLayoutTasks();
- void repaintTree(RenderObject* root);
+ void invalidateTree(RenderObject* root);
+
+ void gatherDebugLayoutRects(RenderObject* layoutRoot);
- virtual void gatherDebugLayoutRects(RenderObject* layoutRoot);
+ DocumentLifecycle& lifecycle() const;
- virtual void repaintContentRectangle(const IntRect&);
+ virtual void contentRectangleForPaintInvalidation(const IntRect&) OVERRIDE;
virtual void contentsResized() OVERRIDE;
- virtual void scrollbarExistenceDidChange();
+ virtual void scrollbarExistenceDidChange() OVERRIDE;
// Override ScrollView methods to do point conversion via renderers, in order to
// take transforms into account.
@@ -404,79 +375,70 @@ private:
virtual IntPoint convertToContainingView(const IntPoint&) const OVERRIDE;
virtual IntPoint convertFromContainingView(const IntPoint&) const OVERRIDE;
- // ScrollableArea interface
- virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE;
- virtual void getTickmarks(Vector<IntRect>&) const OVERRIDE;
- virtual void scrollTo(const IntSize&) OVERRIDE;
- virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE;
- virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
- virtual bool scrollAnimatorEnabled() const OVERRIDE;
- virtual bool usesCompositedScrolling() const OVERRIDE;
- virtual GraphicsLayer* layerForScrolling() const OVERRIDE;
- virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
- virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE;
- virtual GraphicsLayer* layerForScrollCorner() const OVERRIDE;
-
void sendResizeEventIfNeeded();
void updateScrollableAreaSet();
- virtual void notifyPageThatContentAreaWillPaint() const;
-
- bool shouldUseLoadTimeDeferredRepaintDelay() const;
- void deferredRepaintTimerFired(Timer<FrameView>*);
- void doDeferredRepaints();
- void updateDeferredRepaintDelayAfterRepaint();
- double adjustedDeferredRepaintDelay() const;
+ virtual void notifyPageThatContentAreaWillPaint() const OVERRIDE;
+ void scheduleUpdateWidgetsIfNecessary();
void updateWidgetsTimerFired(Timer<FrameView>*);
bool updateWidgets();
void scrollToAnchor();
void scrollPositionChanged();
+ void didScrollTimerFired(Timer<FrameView>*);
+
+ void updateLayersAndCompositingAfterScrollIfNeeded();
+ void updateFixedElementPaintInvalidationRectsAfterScroll();
bool hasCustomScrollbars() const;
- bool shouldUseCustomScrollbars(Element*& customScrollbarElement, Frame*& customScrollbarFrame);
+ bool shouldUseCustomScrollbars(Element*& customScrollbarElement, LocalFrame*& customScrollbarFrame);
- virtual void updateScrollCorner();
+ virtual void updateScrollCorner() OVERRIDE;
FrameView* parentFrameView() const;
- virtual AXObjectCache* axObjectCache() const;
+ AXObjectCache* axObjectCache() const;
void removeFromAXObjectCache();
- bool isMainFrame() const;
-
void setLayoutSizeInternal(const IntSize&);
+ bool paintInvalidationIsAllowed() const
+ {
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ return true;
+
+ return !isInPerformLayout() || canInvalidatePaintDuringPerformLayout();
+ }
+
static double s_currentFrameTimeStamp; // used for detecting decoded resource thrash in the cache
static bool s_inPaintContents;
LayoutSize m_size;
- LayoutSize m_margins;
typedef HashSet<RefPtr<RenderEmbeddedObject> > EmbeddedObjectSet;
EmbeddedObjectSet m_widgetUpdateSet;
- RefPtr<Frame> m_frame;
+ // FIXME: These are just "children" of the FrameView and should be RefPtr<Widget> instead.
+ HashSet<RefPtr<RenderWidget> > m_widgets;
+
+ RefPtr<LocalFrame> m_frame;
- bool m_doFullRepaint;
+ bool m_doFullPaintInvalidation;
bool m_canHaveScrollbars;
bool m_cannotBlitToWindow;
bool m_isOverlapped;
bool m_contentIsOpaque;
unsigned m_slowRepaintObjectCount;
- int m_borderX;
- int m_borderY;
- Timer<FrameView> m_layoutTimer;
- bool m_delayedLayout;
- RenderObject* m_layoutRoot;
+ bool m_hasPendingLayout;
+ RenderObject* m_layoutSubtreeRoot;
bool m_layoutSchedulingEnabled;
- bool m_inLayout;
- bool m_doingPreLayoutStyleUpdate;
+ bool m_inPerformLayout;
+ bool m_canInvalidatePaintDuringPerformLayout;
bool m_inSynchronousPostLayout;
int m_layoutCount;
unsigned m_nestedLayoutCount;
@@ -498,25 +460,16 @@ private:
bool m_verticalOverflow;
RenderObject* m_viewportRenderer;
- Pagination m_pagination;
-
bool m_wasScrolledByUser;
bool m_inProgrammaticScroll;
bool m_safeToPropagateScrollToParent;
- unsigned m_deferringRepaints;
- unsigned m_repaintCount;
- Vector<LayoutRect> m_repaintRects;
- Timer<FrameView> m_deferredRepaintTimer;
- double m_deferredRepaintDelay;
double m_lastPaintTime;
- bool m_isTrackingRepaints; // Used for testing.
- Vector<IntRect> m_trackedRepaintRects;
-
- bool m_shouldUpdateWhileOffscreen;
+ bool m_isTrackingPaintInvalidations; // Used for testing.
+ Vector<IntRect> m_trackedPaintInvalidationRects;
- RefPtr<Node> m_nodeToDraw;
+ RefPtrWillBePersistent<Node> m_nodeToDraw;
PaintBehavior m_paintBehavior;
bool m_isPainting;
@@ -525,7 +478,7 @@ private:
bool m_isVisuallyNonEmpty;
bool m_firstVisuallyNonEmptyLayoutCallbackPending;
- RefPtr<Node> m_maintainScrollPositionAnchor;
+ RefPtrWillBePersistent<Node> m_maintainScrollPositionAnchor;
// Renderer to hold our custom scroll corner.
RenderScrollbarPart* m_scrollCorner;
@@ -544,20 +497,18 @@ private:
OwnPtr<ResizerAreaSet> m_resizerAreas;
OwnPtr<ViewportConstrainedObjectSet> m_viewportConstrainedObjects;
- static double s_normalDeferredRepaintDelay;
- static double s_initialDeferredRepaintDelayDuringLoading;
- static double s_maxDeferredRepaintDelayDuringLoading;
- static double s_deferredRepaintDelayIncrementDuringLoading;
-
bool m_hasSoftwareFilters;
float m_visibleContentScaleFactor;
IntSize m_inputEventsOffsetForEmulation;
float m_inputEventsScaleFactorForEmulation;
- PartialLayoutState m_partialLayout;
IntSize m_layoutSize;
bool m_layoutSizeFixedToFrameSize;
+
+ Timer<FrameView> m_didScrollTimer;
+
+ Vector<IntRect> m_tickmarks;
};
inline void FrameView::incrementVisuallyNonEmptyCharacterCount(unsigned count)
@@ -585,6 +536,30 @@ inline void FrameView::incrementVisuallyNonEmptyPixelCount(const IntSize& size)
DEFINE_TYPE_CASTS(FrameView, Widget, widget, widget->isFrameView(), widget.isFrameView());
+class AllowPaintInvalidationScope {
+public:
+ explicit AllowPaintInvalidationScope(FrameView* view)
+ : m_view(view)
+ , m_originalValue(view ? view->canInvalidatePaintDuringPerformLayout() : false)
+ {
+ if (!m_view)
+ return;
+
+ m_view->setCanInvalidatePaintDuringPerformLayout(true);
+ }
+
+ ~AllowPaintInvalidationScope()
+ {
+ if (!m_view)
+ return;
+
+ m_view->setCanInvalidatePaintDuringPerformLayout(m_originalValue);
+ }
+private:
+ FrameView* m_view;
+ bool m_originalValue;
+};
+
} // namespace WebCore
#endif // FrameView_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/GraphicsLayerDebugInfo.cpp b/chromium/third_party/WebKit/Source/core/frame/GraphicsLayerDebugInfo.cpp
deleted file mode 100644
index 51470a2210e..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/GraphicsLayerDebugInfo.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/frame/GraphicsLayerDebugInfo.h"
-
-#include "platform/JSONValues.h"
-#include "wtf/text/CString.h"
-
-namespace WebCore {
-
-void GraphicsLayerDebugInfo::appendAsTraceFormat(blink::WebString* out) const
-{
- RefPtr<JSONArray> jsonArray = JSONArray::create();
- for (size_t i = 0; i < m_currentLayoutRects.size(); i++) {
- const LayoutRect& rect = m_currentLayoutRects[i];
- RefPtr<JSONObject> rectContainer = JSONObject::create();
- RefPtr<JSONArray> rectArray = JSONArray::create();
- rectArray->pushNumber(rect.x().toFloat());
- rectArray->pushNumber(rect.y().toFloat());
- rectArray->pushNumber(rect.maxX().toFloat());
- rectArray->pushNumber(rect.maxY().toFloat());
- rectContainer->setArray("geometry_rect", rectArray);
- jsonArray->pushObject(rectContainer);
- }
- *out = jsonArray->toJSONString();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/GraphicsLayerDebugInfo.h b/chromium/third_party/WebKit/Source/core/frame/GraphicsLayerDebugInfo.h
deleted file mode 100644
index 26d2fce117a..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/GraphicsLayerDebugInfo.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef GraphicsLayerDebugInfo_h
-#define GraphicsLayerDebugInfo_h
-
-#include "platform/geometry/LayoutRect.h"
-#include "public/platform/WebGraphicsLayerDebugInfo.h"
-
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class GraphicsLayerDebugInfo FINAL : public blink::WebGraphicsLayerDebugInfo {
-public:
- virtual void appendAsTraceFormat(blink::WebString* out) const OVERRIDE;
- virtual ~GraphicsLayerDebugInfo() { };
- Vector<LayoutRect> m_currentLayoutRects;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/History.cpp b/chromium/third_party/WebKit/Source/core/frame/History.cpp
index 863c93683ca..492a69d08a8 100644
--- a/chromium/third_party/WebKit/Source/core/frame/History.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/History.cpp
@@ -29,11 +29,11 @@
#include "bindings/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
-#include "core/history/HistoryItem.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
+#include "core/loader/HistoryItem.h"
#include "core/page/BackForwardClient.h"
#include "core/page/Page.h"
#include "platform/weborigin/KURL.h"
@@ -42,9 +42,9 @@
namespace WebCore {
-History::History(Frame* frame)
+History::History(LocalFrame* frame)
: DOMWindowProperty(frame)
- , m_lastStateObjectRequested(0)
+ , m_lastStateObjectRequested(nullptr)
{
ScriptWrappable::init(this);
}
@@ -105,7 +105,7 @@ void History::go(ExecutionContext* context, int distance)
if (!activeDocument)
return;
- if (!activeDocument->canNavigate(m_frame))
+ if (!activeDocument->canNavigate(*m_frame))
return;
m_frame->navigationScheduler().scheduleHistoryNavigation(distance);
@@ -123,9 +123,9 @@ KURL History::urlForState(const String& urlString)
return KURL(document->baseURL(), urlString);
}
-void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& /* title */, const String& urlString, SameDocumentNavigationSource sameDocumentNavigationSource, ExceptionState& exceptionState)
+void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const String& /* title */, const String& urlString, FrameLoadType type, ExceptionState& exceptionState)
{
- if (!m_frame || !m_frame->page())
+ if (!m_frame || !m_frame->page() || !m_frame->loader().documentLoader())
return;
KURL fullURL = urlForState(urlString);
@@ -134,7 +134,7 @@ void History::stateObjectAdded(PassRefPtr<SerializedScriptValue> data, const Str
exceptionState.throwSecurityError("A history state object with URL '" + fullURL.elidedString() + "' cannot be created in a document with origin '" + m_frame->document()->securityOrigin()->toString() + "'.");
return;
}
- m_frame->loader().updateForSameDocumentNavigation(fullURL, sameDocumentNavigationSource, data, FrameLoader::DoNotUpdateBackForwardList);
+ m_frame->loader().updateForSameDocumentNavigation(fullURL, SameDocumentNavigationHistoryApi, data, type);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/History.h b/chromium/third_party/WebKit/Source/core/frame/History.h
index 42ec3456a02..e4211486b37 100644
--- a/chromium/third_party/WebKit/Source/core/frame/History.h
+++ b/chromium/third_party/WebKit/Source/core/frame/History.h
@@ -30,20 +30,24 @@
#include "bindings/v8/SerializedScriptValue.h"
#include "core/loader/FrameLoaderTypes.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
class KURL;
class ExecutionContext;
class ExceptionState;
-class History : public ScriptWrappable, public RefCounted<History>, public DOMWindowProperty {
+class History FINAL : public RefCountedWillBeGarbageCollectedFinalized<History>, public ScriptWrappable, public DOMWindowProperty {
public:
- static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); }
+ static PassRefPtrWillBeRawPtr<History> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new History(frame));
+ }
unsigned length() const;
SerializedScriptValue* state();
@@ -55,10 +59,12 @@ public:
bool stateChanged() const;
bool isSameAsCurrentState(SerializedScriptValue*) const;
- void stateObjectAdded(PassRefPtr<SerializedScriptValue>, const String& title, const String& url, SameDocumentNavigationSource, ExceptionState&);
+ void stateObjectAdded(PassRefPtr<SerializedScriptValue>, const String& title, const String& url, FrameLoadType, ExceptionState&);
+
+ void trace(Visitor*) { }
private:
- explicit History(Frame*);
+ explicit History(LocalFrame*);
KURL urlForState(const String& url);
diff --git a/chromium/third_party/WebKit/Source/core/frame/History.idl b/chromium/third_party/WebKit/Source/core/frame/History.idl
index 6bd64396230..40606047612 100644
--- a/chromium/third_party/WebKit/Source/core/frame/History.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/History.idl
@@ -23,7 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface History {
+[
+ WillBeGarbageCollected,
+] interface History {
readonly attribute unsigned long length;
[Custom=Getter] readonly attribute SerializedScriptValue state;
diff --git a/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index ec54c645533..bbd9e0fd5d8 100644
--- a/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -14,23 +14,21 @@
#include "platform/graphics/ImageBuffer.h"
#include "wtf/RefPtr.h"
-using namespace std;
-
namespace WebCore {
static inline IntRect normalizeRect(const IntRect& rect)
{
- return IntRect(min(rect.x(), rect.maxX()),
- min(rect.y(), rect.maxY()),
- max(rect.width(), -rect.width()),
- max(rect.height(), -rect.height()));
+ return IntRect(std::min(rect.x(), rect.maxX()),
+ std::min(rect.y(), rect.maxY()),
+ std::max(rect.width(), -rect.width()),
+ std::max(rect.height(), -rect.height()));
}
static inline PassRefPtr<Image> cropImage(Image* image, const IntRect& cropRect)
{
IntRect intersectRect = intersection(IntRect(IntPoint(), image->size()), cropRect);
if (!intersectRect.width() || !intersectRect.height())
- return 0;
+ return nullptr;
SkBitmap cropped;
image->nativeImageForCurrentFrame()->bitmap().extractSubset(&cropped, intersectRect);
@@ -39,15 +37,15 @@ static inline PassRefPtr<Image> cropImage(Image* image, const IntRect& cropRect)
ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect)
: m_imageElement(image)
- , m_bitmap(0)
+ , m_bitmap(nullptr)
, m_cropRect(cropRect)
{
IntRect srcRect = intersection(cropRect, IntRect(0, 0, image->width(), image->height()));
- m_bitmapRect = IntRect(IntPoint(max(0, -cropRect.x()), max(0, -cropRect.y())), srcRect.size());
+ m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
m_bitmapOffset = srcRect.location();
if (!srcRect.width() || !srcRect.height())
- m_imageElement = 0;
+ m_imageElement = nullptr;
else
m_imageElement->addClient(this);
@@ -55,11 +53,16 @@ ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect)
}
ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
- : m_imageElement(0)
+ : m_imageElement(nullptr)
, m_cropRect(cropRect)
, m_bitmapOffset(IntPoint())
{
- IntRect videoRect = IntRect(IntPoint(), video->player()->naturalSize());
+ IntSize playerSize;
+
+ if (video->webMediaPlayer())
+ playerSize = video->webMediaPlayer()->naturalSize();
+
+ IntRect videoRect = IntRect(IntPoint(), playerSize);
IntRect srcRect = intersection(cropRect, videoRect);
IntRect dstRect(IntPoint(), srcRect.size());
@@ -71,13 +74,13 @@ ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
c->translate(-srcRect.x(), -srcRect.y());
video->paintCurrentFrameInContext(c, videoRect);
m_bitmap = buf->copyImage(DontCopyBackingStore);
- m_bitmapRect = IntRect(IntPoint(max(0, -cropRect.x()), max(0, -cropRect.y())), srcRect.size());
+ m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
ScriptWrappable::init(this);
}
ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect)
- : m_imageElement(0)
+ : m_imageElement(nullptr)
, m_cropRect(cropRect)
, m_bitmapOffset(IntPoint())
{
@@ -86,14 +89,14 @@ ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect)
sourceContext->paintRenderingResultsToCanvas();
IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), canvas->size()));
- m_bitmapRect = IntRect(IntPoint(max(0, -cropRect.x()), max(0, -cropRect.y())), srcRect.size());
+ m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
m_bitmap = cropImage(canvas->buffer()->copyImage(CopyBackingStore).get(), cropRect);
ScriptWrappable::init(this);
}
ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect)
- : m_imageElement(0)
+ : m_imageElement(nullptr)
, m_cropRect(cropRect)
, m_bitmapOffset(IntPoint())
{
@@ -103,23 +106,23 @@ ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect)
if (!buf)
return;
if (srcRect.width() > 0 && srcRect.height() > 0)
- buf->putByteArray(Premultiplied, data->data(), data->size(), srcRect, IntPoint(min(0, -cropRect.x()), min(0, -cropRect.y())));
+ buf->putByteArray(Premultiplied, data->data(), data->size(), srcRect, IntPoint(std::min(0, -cropRect.x()), std::min(0, -cropRect.y())));
m_bitmap = buf->copyImage(DontCopyBackingStore);
- m_bitmapRect = IntRect(IntPoint(max(0, -cropRect.x()), max(0, -cropRect.y())), srcRect.size());
+ m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
ScriptWrappable::init(this);
}
ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect)
: m_imageElement(bitmap->imageElement())
- , m_bitmap(0)
+ , m_bitmap(nullptr)
, m_cropRect(cropRect)
, m_bitmapOffset(IntPoint())
{
IntRect oldBitmapRect = bitmap->bitmapRect();
IntRect srcRect = intersection(cropRect, oldBitmapRect);
- m_bitmapRect = IntRect(IntPoint(max(0, oldBitmapRect.x() - cropRect.x()), max(0, oldBitmapRect.y() - cropRect.y())), srcRect.size());
+ m_bitmapRect = IntRect(IntPoint(std::max(0, oldBitmapRect.x() - cropRect.x()), std::max(0, oldBitmapRect.y() - cropRect.y())), srcRect.size());
if (m_imageElement) {
m_imageElement->addClient(this);
@@ -133,63 +136,65 @@ ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect)
}
ImageBitmap::ImageBitmap(Image* image, const IntRect& cropRect)
- : m_imageElement(0)
+ : m_imageElement(nullptr)
, m_cropRect(cropRect)
{
IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), image->size()));
m_bitmap = cropImage(image, cropRect);
- m_bitmapRect = IntRect(IntPoint(max(0, -cropRect.x()), max(0, -cropRect.y())), srcRect.size());
+ m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
ScriptWrappable::init(this);
}
ImageBitmap::~ImageBitmap()
{
+#if !ENABLE(OILPAN)
if (m_imageElement)
m_imageElement->removeClient(this);
+#endif
}
-PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLImageElement* image, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(HTMLImageElement* image, const IntRect& cropRect)
{
IntRect normalizedCropRect = normalizeRect(cropRect);
- return adoptRef(new ImageBitmap(image, normalizedCropRect));
+ return adoptRefWillBeNoop(new ImageBitmap(image, normalizedCropRect));
}
-PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLVideoElement* video, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(HTMLVideoElement* video, const IntRect& cropRect)
{
IntRect normalizedCropRect = normalizeRect(cropRect);
- return adoptRef(new ImageBitmap(video, normalizedCropRect));
+ return adoptRefWillBeNoop(new ImageBitmap(video, normalizedCropRect));
}
-PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLCanvasElement* canvas, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(HTMLCanvasElement* canvas, const IntRect& cropRect)
{
IntRect normalizedCropRect = normalizeRect(cropRect);
- return adoptRef(new ImageBitmap(canvas, normalizedCropRect));
+ return adoptRefWillBeNoop(new ImageBitmap(canvas, normalizedCropRect));
}
-PassRefPtr<ImageBitmap> ImageBitmap::create(ImageData* data, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(ImageData* data, const IntRect& cropRect)
{
IntRect normalizedCropRect = normalizeRect(cropRect);
- return adoptRef(new ImageBitmap(data, normalizedCropRect));
+ return adoptRefWillBeNoop(new ImageBitmap(data, normalizedCropRect));
}
-PassRefPtr<ImageBitmap> ImageBitmap::create(ImageBitmap* bitmap, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(ImageBitmap* bitmap, const IntRect& cropRect)
{
IntRect normalizedCropRect = normalizeRect(cropRect);
- return adoptRef(new ImageBitmap(bitmap, normalizedCropRect));
+ return adoptRefWillBeNoop(new ImageBitmap(bitmap, normalizedCropRect));
}
-PassRefPtr<ImageBitmap> ImageBitmap::create(Image* image, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(Image* image, const IntRect& cropRect)
{
IntRect normalizedCropRect = normalizeRect(cropRect);
- return adoptRef(new ImageBitmap(image, normalizedCropRect));
+ return adoptRefWillBeNoop(new ImageBitmap(image, normalizedCropRect));
}
void ImageBitmap::notifyImageSourceChanged()
{
m_bitmap = cropImage(m_imageElement->cachedImage()->image(), m_cropRect);
m_bitmapOffset = IntPoint();
- m_imageElement = 0;
+ m_imageElement = nullptr;
}
PassRefPtr<Image> ImageBitmap::bitmapImage() const
@@ -200,4 +205,34 @@ PassRefPtr<Image> ImageBitmap::bitmapImage() const
return m_bitmap;
}
+PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageMode, SourceImageStatus* status) const
+{
+ *status = NormalSourceImageStatus;
+ return bitmapImage();
+}
+
+void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const
+{
+ FloatRect intersectRect = intersection(m_bitmapRect, *srcRect);
+ FloatRect newSrcRect = intersectRect;
+ newSrcRect.move(m_bitmapOffset - m_bitmapRect.location());
+ FloatRect newDstRect(FloatPoint(intersectRect.location() - srcRect->location()), m_bitmapRect.size());
+ newDstRect.scale(dstRect->width() / srcRect->width() * intersectRect.width() / m_bitmapRect.width(),
+ dstRect->height() / srcRect->height() * intersectRect.height() / m_bitmapRect.height());
+ newDstRect.moveBy(dstRect->location());
+ *srcRect = newSrcRect;
+ *dstRect = newDstRect;
+}
+
+FloatSize ImageBitmap::sourceSize() const
+{
+ return FloatSize(width(), height());
+}
+
+void ImageBitmap::trace(Visitor* visitor)
+{
+ visitor->trace(m_imageElement);
+ ImageLoaderClient::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.h b/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.h
index 8c9229d5102..653a82b8e35 100644
--- a/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.h
+++ b/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.h
@@ -7,8 +7,10 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/HTMLImageElement.h"
+#include "core/html/canvas/CanvasImageSource.h"
#include "platform/geometry/IntRect.h"
#include "platform/graphics/Image.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -18,21 +20,20 @@ class HTMLCanvasElement;
class HTMLVideoElement;
class ImageData;
-class ImageBitmap : public RefCounted<ImageBitmap>, public ScriptWrappable, public ImageLoaderClient {
-
+class ImageBitmap FINAL : public RefCountedWillBeGarbageCollectedFinalized<ImageBitmap>, public ScriptWrappable, public ImageLoaderClient, public CanvasImageSource {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(ImageBitmap);
public:
- static PassRefPtr<ImageBitmap> create(HTMLImageElement*, const IntRect&);
- static PassRefPtr<ImageBitmap> create(HTMLVideoElement*, const IntRect&);
- static PassRefPtr<ImageBitmap> create(HTMLCanvasElement*, const IntRect&);
- static PassRefPtr<ImageBitmap> create(ImageData*, const IntRect&);
- static PassRefPtr<ImageBitmap> create(ImageBitmap*, const IntRect&);
- static PassRefPtr<ImageBitmap> create(Image*, const IntRect&);
+ static PassRefPtrWillBeRawPtr<ImageBitmap> create(HTMLImageElement*, const IntRect&);
+ static PassRefPtrWillBeRawPtr<ImageBitmap> create(HTMLVideoElement*, const IntRect&);
+ static PassRefPtrWillBeRawPtr<ImageBitmap> create(HTMLCanvasElement*, const IntRect&);
+ static PassRefPtrWillBeRawPtr<ImageBitmap> create(ImageData*, const IntRect&);
+ static PassRefPtrWillBeRawPtr<ImageBitmap> create(ImageBitmap*, const IntRect&);
+ static PassRefPtrWillBeRawPtr<ImageBitmap> create(Image*, const IntRect&);
PassRefPtr<Image> bitmapImage() const;
- PassRefPtr<HTMLImageElement> imageElement() const { return m_imageElement; }
+ PassRefPtrWillBeRawPtr<HTMLImageElement> imageElement() const { return m_imageElement; }
IntRect bitmapRect() const { return m_bitmapRect; }
- IntPoint bitmapOffset() const { return m_bitmapOffset; }
int width() const { return m_cropRect.width(); }
int height() const { return m_cropRect.height(); }
@@ -40,6 +41,14 @@ public:
virtual ~ImageBitmap();
+ // CanvasImageSource implementation
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const OVERRIDE;
+ virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE { return false; };
+ virtual void adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const OVERRIDE;
+ virtual FloatSize sourceSize() const OVERRIDE;
+
+ virtual void trace(Visitor*);
+
private:
ImageBitmap(HTMLImageElement*, const IntRect&);
ImageBitmap(HTMLVideoElement*, const IntRect&);
@@ -49,12 +58,12 @@ private:
ImageBitmap(Image*, const IntRect&);
// ImageLoaderClient
- virtual void notifyImageSourceChanged();
- virtual bool requestsHighLiveResourceCachePriority() { return true; }
+ virtual void notifyImageSourceChanged() OVERRIDE;
+ virtual bool requestsHighLiveResourceCachePriority() OVERRIDE { return true; }
// ImageBitmaps constructed from HTMLImageElements hold a reference to the HTMLImageElement until
// the image source changes.
- RefPtr<HTMLImageElement> m_imageElement;
+ RefPtrWillBeMember<HTMLImageElement> m_imageElement;
RefPtr<Image> m_bitmap;
IntRect m_bitmapRect; // The rect where the underlying Image should be placed in reference to the ImageBitmap.
diff --git a/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.idl b/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.idl
index 903a2d7421f..b211d6ec29b 100644
--- a/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/ImageBitmap.idl
@@ -3,6 +3,7 @@
// found in the LICENSE file.
[
+ WillBeGarbageCollected,
] interface ImageBitmap {
readonly attribute long width;
readonly attribute long height;
diff --git a/chromium/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp b/chromium/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
index 6a6626ae7ab..ad2e9fdcab1 100644
--- a/chromium/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "core/frame/ImageBitmap.h"
-#include "SkPixelRef.h"
+#include "SkPixelRef.h" // FIXME: qualify this skia header file.
#include "core/dom/Document.h"
#include "core/fetch/ImageResource.h"
#include "core/fetch/MemoryCache.h"
@@ -42,6 +42,7 @@
#include "core/html/canvas/CanvasRenderingContext2D.h"
#include "platform/graphics/BitmapImage.h"
#include "platform/graphics/skia/NativeImageSkia.h"
+#include "platform/heap/Handle.h"
#include "platform/network/ResourceRequest.h"
#include "wtf/OwnPtr.h"
@@ -53,12 +54,10 @@ class ImageBitmapTest : public ::testing::Test {
protected:
virtual void SetUp()
{
- m_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10);
- m_bitmap.allocPixels();
+ ASSERT_TRUE(m_bitmap.allocN32Pixels(10, 10));
m_bitmap.eraseColor(0xFFFFFFFF);
- m_bitmap2.setConfig(SkBitmap::kARGB_8888_Config, 5, 5);
- m_bitmap2.allocPixels();
+ ASSERT_TRUE(m_bitmap2.allocN32Pixels(5, 5));
m_bitmap2.eraseColor(0xAAAAAAAA);
// Save the global memory cache to restore it upon teardown.
@@ -69,6 +68,11 @@ protected:
}
virtual void TearDown()
{
+ // Garbage collection is required prior to switching out the
+ // test's memory cache; image resources are released, evicting
+ // them from the cache.
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
+
// Regain the ownership of testing memory cache, so that it will be
// destroyed.
m_testingMemoryCache = adoptPtr(memoryCache());
@@ -85,13 +89,13 @@ protected:
// one held by the HTMLImageElement.
TEST_F(ImageBitmapTest, ImageResourceConsistency)
{
- RefPtr<HTMLImageElement> imageElement = HTMLImageElement::create(*Document::create().get());
+ RefPtrWillBeRawPtr<HTMLImageElement> imageElement = HTMLImageElement::create(*Document::create().get());
imageElement->setImageResource(new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get()));
- RefPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageElement.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
- RefPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageElement.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width() / 2, m_bitmap.height() / 2));
- RefPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageElement.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
- RefPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageElement.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBeRawPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageElement.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBeRawPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageElement.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width() / 2, m_bitmap.height() / 2));
+ RefPtrWillBeRawPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageElement.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBeRawPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageElement.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.height()));
ASSERT_EQ(imageBitmapNoCrop->bitmapImage().get(), imageElement->cachedImage()->image());
ASSERT_EQ(imageBitmapInteriorCrop->bitmapImage().get(), imageElement->cachedImage()->image());
@@ -105,20 +109,20 @@ TEST_F(ImageBitmapTest, ImageResourceConsistency)
// ImageBitmaps that have crop rects outside of the bounds of the HTMLImageElement do not have elevated CacheLiveResourcePriority.
TEST_F(ImageBitmapTest, ImageBitmapLiveResourcePriority)
{
- RefPtr<HTMLImageElement> imageNoCrop = HTMLImageElement::create(*Document::create().get());
- ResourcePtr<ImageResource> cachedImageNoCrop = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
+ RefPtrWillBePersistent<HTMLImageElement> imageNoCrop = HTMLImageElement::create(*Document::create().get());
+ ResourcePtr<ImageResource> cachedImageNoCrop = new ImageResource(ResourceRequest("http://foo.com/1"), BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
imageNoCrop->setImageResource(cachedImageNoCrop.get());
- RefPtr<HTMLImageElement> imageInteriorCrop = HTMLImageElement::create(*Document::create().get());
- ResourcePtr<ImageResource> cachedImageInteriorCrop = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
+ RefPtrWillBePersistent<HTMLImageElement> imageInteriorCrop = HTMLImageElement::create(*Document::create().get());
+ ResourcePtr<ImageResource> cachedImageInteriorCrop = new ImageResource(ResourceRequest("http://foo.com/2"), BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
imageInteriorCrop->setImageResource(cachedImageInteriorCrop.get());
- RefPtr<HTMLImageElement> imageExteriorCrop = HTMLImageElement::create(*Document::create().get());
- ResourcePtr<ImageResource> cachedImageExteriorCrop = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
+ RefPtrWillBePersistent<HTMLImageElement> imageExteriorCrop = HTMLImageElement::create(*Document::create().get());
+ ResourcePtr<ImageResource> cachedImageExteriorCrop = new ImageResource(ResourceRequest("http://foo.com/3"), BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
imageExteriorCrop->setImageResource(cachedImageExteriorCrop.get());
- RefPtr<HTMLImageElement> imageOutsideCrop = HTMLImageElement::create(*Document::create().get());
- ResourcePtr<ImageResource> cachedImageOutsideCrop = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
+ RefPtrWillBePersistent<HTMLImageElement> imageOutsideCrop = HTMLImageElement::create(*Document::create().get());
+ ResourcePtr<ImageResource> cachedImageOutsideCrop = new ImageResource(ResourceRequest("http://foo.com/4"), BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
imageOutsideCrop->setImageResource(cachedImageOutsideCrop.get());
MockImageResourceClient mockClient1, mockClient2, mockClient3, mockClient4;
@@ -131,50 +135,53 @@ TEST_F(ImageBitmapTest, ImageBitmapLiveResourcePriority)
memoryCache()->add(cachedImageInteriorCrop.get());
memoryCache()->add(cachedImageExteriorCrop.get());
memoryCache()->add(cachedImageOutsideCrop.get());
- memoryCache()->insertInLiveDecodedResourcesList(cachedImageNoCrop.get());
- memoryCache()->insertInLiveDecodedResourcesList(cachedImageInteriorCrop.get());
- memoryCache()->insertInLiveDecodedResourcesList(cachedImageExteriorCrop.get());
- memoryCache()->insertInLiveDecodedResourcesList(cachedImageOutsideCrop.get());
+ memoryCache()->updateDecodedResource(cachedImageNoCrop.get(), UpdateForPropertyChange);
+ memoryCache()->updateDecodedResource(cachedImageInteriorCrop.get(), UpdateForPropertyChange);
+ memoryCache()->updateDecodedResource(cachedImageExteriorCrop.get(), UpdateForPropertyChange);
+ memoryCache()->updateDecodedResource(cachedImageOutsideCrop.get(), UpdateForPropertyChange);
// HTMLImageElements should default to CacheLiveResourcePriorityLow.
- ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
- ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
- ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
- ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
+ ASSERT_EQ(memoryCache()->priority(imageNoCrop->cachedImage()), MemoryCacheLiveResourcePriorityLow);
+ ASSERT_EQ(memoryCache()->priority(imageInteriorCrop->cachedImage()), MemoryCacheLiveResourcePriorityLow);
+ ASSERT_EQ(memoryCache()->priority(imageExteriorCrop->cachedImage()), MemoryCacheLiveResourcePriorityLow);
+ ASSERT_EQ(memoryCache()->priority(imageOutsideCrop->cachedImage()), MemoryCacheLiveResourcePriorityLow);
- RefPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageInteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBePersistent<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageInteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
{
- RefPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageNoCrop.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
- RefPtr<ImageBitmap> imageBitmapInteriorCrop2 = ImageBitmap::create(imageInteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
- RefPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageExteriorCrop.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
- RefPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageOutsideCrop.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBePersistent<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageNoCrop.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBePersistent<ImageBitmap> imageBitmapInteriorCrop2 = ImageBitmap::create(imageInteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBePersistent<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageExteriorCrop.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBePersistent<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageOutsideCrop.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.height()));
// Images that are referenced by ImageBitmaps have CacheLiveResourcePriorityHigh.
- ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh);
- ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh);
- ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh);
+ ASSERT_EQ(memoryCache()->priority(imageNoCrop->cachedImage()), MemoryCacheLiveResourcePriorityHigh);
+ ASSERT_EQ(memoryCache()->priority(imageInteriorCrop->cachedImage()), MemoryCacheLiveResourcePriorityHigh);
+ ASSERT_EQ(memoryCache()->priority(imageExteriorCrop->cachedImage()), MemoryCacheLiveResourcePriorityHigh);
// ImageBitmaps that do not contain any of the source image do not elevate CacheLiveResourcePriority.
- ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
+ ASSERT_EQ(memoryCache()->priority(imageOutsideCrop->cachedImage()), MemoryCacheLiveResourcePriorityLow);
}
+ // Force a garbage collection to sweep out the local ImageBitmaps.
+ Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
// CacheLiveResourcePriroity should return to CacheLiveResourcePriorityLow when no ImageBitmaps reference the image.
- ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
- ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
- ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
+ ASSERT_EQ(memoryCache()->priority(imageNoCrop->cachedImage()), MemoryCacheLiveResourcePriorityLow);
+ ASSERT_EQ(memoryCache()->priority(imageExteriorCrop->cachedImage()), MemoryCacheLiveResourcePriorityLow);
+ ASSERT_EQ(memoryCache()->priority(imageOutsideCrop->cachedImage()), MemoryCacheLiveResourcePriorityLow);
// There is still an ImageBitmap that references this image.
- ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh);
+ ASSERT_EQ(memoryCache()->priority(imageInteriorCrop->cachedImage()), MemoryCacheLiveResourcePriorityHigh);
+ imageBitmapInteriorCrop = nullptr;
}
// Verifies that ImageBitmaps constructed from HTMLImageElements hold a reference to the original Image if the HTMLImageElement src is changed.
TEST_F(ImageBitmapTest, ImageBitmapSourceChanged)
{
- RefPtr<HTMLImageElement> image = HTMLImageElement::create(*Document::create().get());
+ RefPtrWillBeRawPtr<HTMLImageElement> image = HTMLImageElement::create(*Document::create().get());
ResourcePtr<ImageResource> originalImageResource = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
image->setImageResource(originalImageResource.get());
- RefPtr<ImageBitmap> imageBitmap = ImageBitmap::create(image.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
+ RefPtrWillBeRawPtr<ImageBitmap> imageBitmap = ImageBitmap::create(image.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
ASSERT_EQ(imageBitmap->bitmapImage().get(), originalImageResource->image());
ResourcePtr<ImageResource> newImageResource = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap2)).get());
@@ -193,12 +200,12 @@ TEST_F(ImageBitmapTest, ImageBitmapSourceChanged)
// Verifies that ImageBitmaps constructed from ImageBitmaps hold onto their own Image.
TEST_F(ImageBitmapTest, ImageResourceLifetime)
{
- RefPtr<HTMLCanvasElement> canvasElement = HTMLCanvasElement::create(*Document::create().get());
+ RefPtrWillBeRawPtr<HTMLCanvasElement> canvasElement = HTMLCanvasElement::create(*Document::create().get());
canvasElement->setHeight(40);
canvasElement->setWidth(40);
- RefPtr<ImageBitmap> imageBitmapDerived;
+ RefPtrWillBeRawPtr<ImageBitmap> imageBitmapDerived = nullptr;
{
- RefPtr<ImageBitmap> imageBitmapFromCanvas = ImageBitmap::create(canvasElement.get(), IntRect(0, 0, canvasElement->width(), canvasElement->height()));
+ RefPtrWillBeRawPtr<ImageBitmap> imageBitmapFromCanvas = ImageBitmap::create(canvasElement.get(), IntRect(0, 0, canvasElement->width(), canvasElement->height()));
imageBitmapDerived = ImageBitmap::create(imageBitmapFromCanvas.get(), IntRect(0, 0, 20, 20));
}
CanvasRenderingContext* context = canvasElement->getContext("2d");
diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/chromium/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
new file mode 100644
index 00000000000..135263cd6d4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -0,0 +1,1946 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/frame/LocalDOMWindow.h"
+
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "bindings/v8/ScriptCallStackFactory.h"
+#include "bindings/v8/ScriptController.h"
+#include "bindings/v8/SerializedScriptValue.h"
+#include "core/css/CSSComputedStyleDeclaration.h"
+#include "core/css/CSSRuleList.h"
+#include "core/css/DOMWindowCSS.h"
+#include "core/css/MediaQueryList.h"
+#include "core/css/MediaQueryMatcher.h"
+#include "core/css/StyleMedia.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/ContextFeatures.h"
+#include "core/dom/DOMImplementation.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/dom/ExecutionContext.h"
+#include "core/dom/NoEventDispatchAssertion.h"
+#include "core/dom/RequestAnimationFrameCallback.h"
+#include "core/editing/Editor.h"
+#include "core/events/DOMWindowEventQueue.h"
+#include "core/events/EventListener.h"
+#include "core/events/HashChangeEvent.h"
+#include "core/events/MessageEvent.h"
+#include "core/events/PageTransitionEvent.h"
+#include "core/events/PopStateEvent.h"
+#include "core/frame/BarProp.h"
+#include "core/frame/Console.h"
+#include "core/frame/DOMPoint.h"
+#include "core/frame/DOMWindowLifecycleNotifier.h"
+#include "core/frame/EventHandlerRegistry.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/History.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Location.h"
+#include "core/frame/Navigator.h"
+#include "core/frame/Screen.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
+#include "core/inspector/ScriptCallStack.h"
+#include "core/loader/DocumentLoader.h"
+#include "core/loader/FrameLoadRequest.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "core/loader/MixedContentChecker.h"
+#include "core/loader/SinkDocument.h"
+#include "core/loader/appcache/ApplicationCache.h"
+#include "core/page/BackForwardClient.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/CreateWindow.h"
+#include "core/page/EventHandler.h"
+#include "core/page/FrameTree.h"
+#include "core/page/Page.h"
+#include "core/page/WindowFeatures.h"
+#include "core/page/WindowFocusAllowedIndicator.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "core/storage/Storage.h"
+#include "core/storage/StorageArea.h"
+#include "core/storage/StorageNamespace.h"
+#include "core/timing/Performance.h"
+#include "platform/PlatformScreen.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/UserGestureIndicator.h"
+#include "platform/geometry/FloatRect.h"
+#include "platform/graphics/media/MediaPlayer.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "platform/weborigin/SecurityPolicy.h"
+#include "public/platform/Platform.h"
+#include "wtf/MainThread.h"
+#include "wtf/MathExtras.h"
+#include "wtf/text/WTFString.h"
+#include <algorithm>
+
+using std::min;
+using std::max;
+
+namespace WebCore {
+
+class PostMessageTimer FINAL : public SuspendableTimer {
+public:
+ PostMessageTimer(LocalDOMWindow& window, PassRefPtr<SerializedScriptValue> message, const String& sourceOrigin, PassRefPtrWillBeRawPtr<LocalDOMWindow> source, PassOwnPtr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin, PassRefPtrWillBeRawPtr<ScriptCallStack> stackTrace, UserGestureToken* userGestureToken)
+ : SuspendableTimer(window.document())
+ , m_window(&window)
+ , m_message(message)
+ , m_origin(sourceOrigin)
+ , m_source(source)
+ , m_channels(channels)
+ , m_targetOrigin(targetOrigin)
+ , m_stackTrace(stackTrace)
+ , m_userGestureToken(userGestureToken)
+ {
+ }
+
+ PassRefPtrWillBeRawPtr<MessageEvent> event()
+ {
+ return MessageEvent::create(m_channels.release(), m_message, m_origin, String(), m_source.get());
+
+ }
+ SecurityOrigin* targetOrigin() const { return m_targetOrigin.get(); }
+ ScriptCallStack* stackTrace() const { return m_stackTrace.get(); }
+ UserGestureToken* userGestureToken() const { return m_userGestureToken.get(); }
+
+private:
+ virtual void fired() OVERRIDE
+ {
+ m_window->postMessageTimerFired(this);
+ // This object is deleted now.
+ }
+
+ // FIXME: Oilpan: This raw pointer is safe because the PostMessageTimer is
+ // owned by the LocalDOMWindow. Ideally PostMessageTimer should be moved to
+ // the heap and use Member<LocalDOMWindow>.
+ LocalDOMWindow* m_window;
+ RefPtr<SerializedScriptValue> m_message;
+ String m_origin;
+ RefPtrWillBePersistent<LocalDOMWindow> m_source;
+ OwnPtr<MessagePortChannelArray> m_channels;
+ RefPtr<SecurityOrigin> m_targetOrigin;
+ RefPtrWillBePersistent<ScriptCallStack> m_stackTrace;
+ RefPtr<UserGestureToken> m_userGestureToken;
+};
+
+static void disableSuddenTermination()
+{
+ blink::Platform::current()->suddenTerminationChanged(false);
+}
+
+static void enableSuddenTermination()
+{
+ blink::Platform::current()->suddenTerminationChanged(true);
+}
+
+typedef HashCountedSet<LocalDOMWindow*> DOMWindowSet;
+
+static DOMWindowSet& windowsWithUnloadEventListeners()
+{
+ DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithUnloadEventListeners, ());
+ return windowsWithUnloadEventListeners;
+}
+
+static DOMWindowSet& windowsWithBeforeUnloadEventListeners()
+{
+ DEFINE_STATIC_LOCAL(DOMWindowSet, windowsWithBeforeUnloadEventListeners, ());
+ return windowsWithBeforeUnloadEventListeners;
+}
+
+static void addUnloadEventListener(LocalDOMWindow* domWindow)
+{
+ DOMWindowSet& set = windowsWithUnloadEventListeners();
+ if (set.isEmpty())
+ disableSuddenTermination();
+ set.add(domWindow);
+}
+
+static void removeUnloadEventListener(LocalDOMWindow* domWindow)
+{
+ DOMWindowSet& set = windowsWithUnloadEventListeners();
+ DOMWindowSet::iterator it = set.find(domWindow);
+ if (it == set.end())
+ return;
+ set.remove(it);
+ if (set.isEmpty())
+ enableSuddenTermination();
+}
+
+static void removeAllUnloadEventListeners(LocalDOMWindow* domWindow)
+{
+ DOMWindowSet& set = windowsWithUnloadEventListeners();
+ DOMWindowSet::iterator it = set.find(domWindow);
+ if (it == set.end())
+ return;
+ set.removeAll(it);
+ if (set.isEmpty())
+ enableSuddenTermination();
+}
+
+static void addBeforeUnloadEventListener(LocalDOMWindow* domWindow)
+{
+ DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+ if (set.isEmpty())
+ disableSuddenTermination();
+ set.add(domWindow);
+}
+
+static void removeBeforeUnloadEventListener(LocalDOMWindow* domWindow)
+{
+ DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+ DOMWindowSet::iterator it = set.find(domWindow);
+ if (it == set.end())
+ return;
+ set.remove(it);
+ if (set.isEmpty())
+ enableSuddenTermination();
+}
+
+static void removeAllBeforeUnloadEventListeners(LocalDOMWindow* domWindow)
+{
+ DOMWindowSet& set = windowsWithBeforeUnloadEventListeners();
+ DOMWindowSet::iterator it = set.find(domWindow);
+ if (it == set.end())
+ return;
+ set.removeAll(it);
+ if (set.isEmpty())
+ enableSuddenTermination();
+}
+
+static bool allowsBeforeUnloadListeners(LocalDOMWindow* window)
+{
+ ASSERT_ARG(window, window);
+ LocalFrame* frame = window->frame();
+ if (!frame)
+ return false;
+ return frame->isMainFrame();
+}
+
+unsigned LocalDOMWindow::pendingUnloadEventListeners() const
+{
+ return windowsWithUnloadEventListeners().count(const_cast<LocalDOMWindow*>(this));
+}
+
+// This function:
+// 1) Validates the pending changes are not changing any value to NaN; in that case keep original value.
+// 2) Constrains the window rect to the minimum window size and no bigger than the float rect's dimensions.
+// 3) Constrains the window rect to within the top and left boundaries of the available screen rect.
+// 4) Constrains the window rect to within the bottom and right boundaries of the available screen rect.
+// 5) Translate the window rect coordinates to be within the coordinate space of the screen.
+FloatRect LocalDOMWindow::adjustWindowRect(LocalFrame& frame, const FloatRect& pendingChanges)
+{
+ FrameHost* host = frame.host();
+ ASSERT(host);
+
+ FloatRect screen = screenAvailableRect(frame.view());
+ FloatRect window = host->chrome().windowRect();
+
+ // Make sure we're in a valid state before adjusting dimensions.
+ ASSERT(std::isfinite(screen.x()));
+ ASSERT(std::isfinite(screen.y()));
+ ASSERT(std::isfinite(screen.width()));
+ ASSERT(std::isfinite(screen.height()));
+ ASSERT(std::isfinite(window.x()));
+ ASSERT(std::isfinite(window.y()));
+ ASSERT(std::isfinite(window.width()));
+ ASSERT(std::isfinite(window.height()));
+
+ // Update window values if new requested values are not NaN.
+ if (!std::isnan(pendingChanges.x()))
+ window.setX(pendingChanges.x());
+ if (!std::isnan(pendingChanges.y()))
+ window.setY(pendingChanges.y());
+ if (!std::isnan(pendingChanges.width()))
+ window.setWidth(pendingChanges.width());
+ if (!std::isnan(pendingChanges.height()))
+ window.setHeight(pendingChanges.height());
+
+ FloatSize minimumSize = host->chrome().client().minimumWindowSize();
+ // Let size 0 pass through, since that indicates default size, not minimum size.
+ if (window.width())
+ window.setWidth(min(max(minimumSize.width(), window.width()), screen.width()));
+ if (window.height())
+ window.setHeight(min(max(minimumSize.height(), window.height()), screen.height()));
+
+ // Constrain the window position within the valid screen area.
+ window.setX(max(screen.x(), min(window.x(), screen.maxX() - window.width())));
+ window.setY(max(screen.y(), min(window.y(), screen.maxY() - window.height())));
+
+ return window;
+}
+
+bool LocalDOMWindow::allowPopUp(LocalFrame& firstFrame)
+{
+ if (UserGestureIndicator::processingUserGesture())
+ return true;
+
+ Settings* settings = firstFrame.settings();
+ return settings && settings->javaScriptCanOpenWindowsAutomatically();
+}
+
+bool LocalDOMWindow::allowPopUp()
+{
+ return m_frame && allowPopUp(*m_frame);
+}
+
+bool LocalDOMWindow::canShowModalDialogNow(const LocalFrame* frame)
+{
+ if (!frame)
+ return false;
+ FrameHost* host = frame->host();
+ if (!host)
+ return false;
+ return host->chrome().canRunModalNow();
+}
+
+LocalDOMWindow::LocalDOMWindow(LocalFrame& frame)
+ : FrameDestructionObserver(&frame)
+ , m_shouldPrintWhenFinishedLoading(false)
+#if ASSERT_ENABLED
+ , m_hasBeenReset(false)
+#endif
+{
+ ScriptWrappable::init(this);
+}
+
+void LocalDOMWindow::clearDocument()
+{
+ if (!m_document)
+ return;
+
+ if (m_document->isActive()) {
+ // FIXME: We don't call willRemove here. Why is that OK?
+ // This detach() call is also mostly redundant. Most of the calls to
+ // this function come via DocumentLoader::createWriterFor, which
+ // always detaches the previous Document first. Only XSLTProcessor
+ // depends on this detach() call, so it seems like there's some room
+ // for cleanup.
+ m_document->detach();
+ }
+
+ // FIXME: This should be part of ActiveDOMObject shutdown
+ clearEventQueue();
+
+ m_document->clearDOMWindow();
+ m_document = nullptr;
+}
+
+void LocalDOMWindow::clearEventQueue()
+{
+ if (!m_eventQueue)
+ return;
+ m_eventQueue->close();
+ m_eventQueue.clear();
+}
+
+void LocalDOMWindow::acceptLanguagesChanged()
+{
+ if (m_navigator)
+ m_navigator->setLanguagesChanged();
+
+ dispatchEvent(Event::create(EventTypeNames::languagechange));
+}
+
+PassRefPtrWillBeRawPtr<Document> LocalDOMWindow::createDocument(const String& mimeType, const DocumentInit& init, bool forceXHTML)
+{
+ RefPtrWillBeRawPtr<Document> document = nullptr;
+ if (forceXHTML) {
+ // This is a hack for XSLTProcessor. See XSLTProcessor::createDocumentFromSource().
+ document = Document::create(init);
+ } else {
+ document = DOMImplementation::createDocument(mimeType, init, init.frame() ? init.frame()->inViewSourceMode() : false);
+ if (document->isPluginDocument() && document->isSandboxed(SandboxPlugins))
+ document = SinkDocument::create(init);
+ }
+
+ return document.release();
+}
+
+PassRefPtrWillBeRawPtr<Document> LocalDOMWindow::installNewDocument(const String& mimeType, const DocumentInit& init, bool forceXHTML)
+{
+ ASSERT(init.frame() == m_frame);
+
+ clearDocument();
+
+ m_document = createDocument(mimeType, init, forceXHTML);
+ m_eventQueue = DOMWindowEventQueue::create(m_document.get());
+ m_document->attach();
+
+ if (!m_frame) {
+ // FIXME: Oilpan: Remove .get() when m_document becomes Member<>.
+ return m_document.get();
+ }
+
+ m_frame->script().updateDocument();
+ m_document->updateViewportDescription();
+
+ if (m_frame->page() && m_frame->view()) {
+ if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator()) {
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_frame->view(), HorizontalScrollbar);
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_frame->view(), VerticalScrollbar);
+ scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_frame->view());
+ }
+ }
+
+ m_frame->selection().updateSecureKeyboardEntryIfActive();
+
+ if (m_frame->isMainFrame()) {
+ if (m_document->hasTouchEventHandlers())
+ m_frame->host()->chrome().client().needTouchEvents(true);
+ }
+
+ // FIXME: Oilpan: Remove .get() when m_document becomes Member<>.
+ return m_document.get();
+}
+
+EventQueue* LocalDOMWindow::eventQueue() const
+{
+ return m_eventQueue.get();
+}
+
+void LocalDOMWindow::enqueueWindowEvent(PassRefPtrWillBeRawPtr<Event> event)
+{
+ if (!m_eventQueue)
+ return;
+ event->setTarget(this);
+ m_eventQueue->enqueueEvent(event);
+}
+
+void LocalDOMWindow::enqueueDocumentEvent(PassRefPtrWillBeRawPtr<Event> event)
+{
+ if (!m_eventQueue)
+ return;
+ event->setTarget(m_document.get());
+ m_eventQueue->enqueueEvent(event);
+}
+
+void LocalDOMWindow::dispatchWindowLoadEvent()
+{
+ ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
+ dispatchLoadEvent();
+}
+
+void LocalDOMWindow::documentWasClosed()
+{
+ dispatchWindowLoadEvent();
+ enqueuePageshowEvent(PageshowEventNotPersisted);
+ if (m_pendingStateObject)
+ enqueuePopstateEvent(m_pendingStateObject.release());
+}
+
+void LocalDOMWindow::enqueuePageshowEvent(PageshowEventPersistence persisted)
+{
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36334 Pageshow event needs to fire asynchronously.
+ // As per spec pageshow must be triggered asynchronously.
+ // However to be compatible with other browsers blink fires pageshow synchronously.
+ dispatchEvent(PageTransitionEvent::create(EventTypeNames::pageshow, persisted), m_document.get());
+}
+
+void LocalDOMWindow::enqueueHashchangeEvent(const String& oldURL, const String& newURL)
+{
+ enqueueWindowEvent(HashChangeEvent::create(oldURL, newURL));
+}
+
+void LocalDOMWindow::enqueuePopstateEvent(PassRefPtr<SerializedScriptValue> stateObject)
+{
+ if (!ContextFeatures::pushStateEnabled(document()))
+ return;
+
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
+ dispatchEvent(PopStateEvent::create(stateObject, &history()));
+}
+
+void LocalDOMWindow::statePopped(PassRefPtr<SerializedScriptValue> stateObject)
+{
+ if (!frame())
+ return;
+
+ // Per step 11 of section 6.5.9 (history traversal) of the HTML5 spec, we
+ // defer firing of popstate until we're in the complete state.
+ if (document()->isLoadCompleted())
+ enqueuePopstateEvent(stateObject);
+ else
+ m_pendingStateObject = stateObject;
+}
+
+LocalDOMWindow::~LocalDOMWindow()
+{
+ ASSERT(m_hasBeenReset);
+ reset();
+
+#if ENABLE(OILPAN)
+ // Oilpan: the frame host and document objects are
+ // also garbage collected; cannot notify these
+ // when removing event listeners.
+ removeAllEventListenersInternal(DoNotBroadcastListenerRemoval);
+
+ // Cleared when detaching document.
+ ASSERT(!m_eventQueue);
+#else
+ removeAllEventListenersInternal(DoBroadcastListenerRemoval);
+
+ ASSERT(m_document->isStopped());
+ clearDocument();
+#endif
+}
+
+const AtomicString& LocalDOMWindow::interfaceName() const
+{
+ return EventTargetNames::LocalDOMWindow;
+}
+
+ExecutionContext* LocalDOMWindow::executionContext() const
+{
+ return m_document.get();
+}
+
+LocalDOMWindow* LocalDOMWindow::toDOMWindow()
+{
+ return this;
+}
+
+PassRefPtrWillBeRawPtr<MediaQueryList> LocalDOMWindow::matchMedia(const String& media)
+{
+ return document() ? document()->mediaQueryMatcher().matchMedia(media) : nullptr;
+}
+
+Page* LocalDOMWindow::page()
+{
+ return frame() ? frame()->page() : 0;
+}
+
+void LocalDOMWindow::frameDestroyed()
+{
+ FrameDestructionObserver::frameDestroyed();
+ reset();
+}
+
+void LocalDOMWindow::willDetachFrameHost()
+{
+ m_frame->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*this);
+ InspectorInstrumentation::frameWindowDiscarded(m_frame, this);
+}
+
+void LocalDOMWindow::willDestroyDocumentInFrame()
+{
+ // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
+ // unregister themselves from the LocalDOMWindow as a result of the call to willDestroyGlobalObjectInFrame.
+ Vector<DOMWindowProperty*> properties;
+ copyToVector(m_properties, properties);
+ for (size_t i = 0; i < properties.size(); ++i)
+ properties[i]->willDestroyGlobalObjectInFrame();
+}
+
+void LocalDOMWindow::willDetachDocumentFromFrame()
+{
+ // It is necessary to copy m_properties to a separate vector because the DOMWindowProperties may
+ // unregister themselves from the LocalDOMWindow as a result of the call to willDetachGlobalObjectFromFrame.
+ Vector<DOMWindowProperty*> properties;
+ copyToVector(m_properties, properties);
+ for (size_t i = 0; i < properties.size(); ++i)
+ properties[i]->willDetachGlobalObjectFromFrame();
+}
+
+void LocalDOMWindow::registerProperty(DOMWindowProperty* property)
+{
+ m_properties.add(property);
+}
+
+void LocalDOMWindow::unregisterProperty(DOMWindowProperty* property)
+{
+ m_properties.remove(property);
+}
+
+void LocalDOMWindow::reset()
+{
+ willDestroyDocumentInFrame();
+ resetDOMWindowProperties();
+}
+
+void LocalDOMWindow::resetDOMWindowProperties()
+{
+ m_properties.clear();
+
+ m_screen = nullptr;
+ m_history = nullptr;
+ m_locationbar = nullptr;
+ m_menubar = nullptr;
+ m_personalbar = nullptr;
+ m_scrollbars = nullptr;
+ m_statusbar = nullptr;
+ m_toolbar = nullptr;
+ m_console = nullptr;
+ m_navigator = nullptr;
+ m_performance = nullptr;
+ m_location = nullptr;
+ m_media = nullptr;
+ m_sessionStorage = nullptr;
+ m_localStorage = nullptr;
+ m_applicationCache = nullptr;
+#if ASSERT_ENABLED
+ m_hasBeenReset = true;
+#endif
+}
+
+bool LocalDOMWindow::isCurrentlyDisplayedInFrame() const
+{
+ return m_frame && m_frame->domWindow() == this && m_frame->host();
+}
+
+int LocalDOMWindow::orientation() const
+{
+ ASSERT(RuntimeEnabledFeatures::orientationEventEnabled());
+
+ if (!m_frame)
+ return 0;
+
+ int orientation = screenOrientationAngle(m_frame->view());
+ // For backward compatibility, we want to return a value in the range of
+ // [-90; 180] instead of [0; 360[ because window.orientation used to behave
+ // like that in WebKit (this is a WebKit proprietary API).
+ if (orientation == 270)
+ return -90;
+ return orientation;
+}
+
+Screen& LocalDOMWindow::screen() const
+{
+ if (!m_screen)
+ m_screen = Screen::create(m_frame);
+ return *m_screen;
+}
+
+History& LocalDOMWindow::history() const
+{
+ if (!m_history)
+ m_history = History::create(m_frame);
+ return *m_history;
+}
+
+BarProp& LocalDOMWindow::locationbar() const
+{
+ if (!m_locationbar)
+ m_locationbar = BarProp::create(m_frame, BarProp::Locationbar);
+ return *m_locationbar;
+}
+
+BarProp& LocalDOMWindow::menubar() const
+{
+ if (!m_menubar)
+ m_menubar = BarProp::create(m_frame, BarProp::Menubar);
+ return *m_menubar;
+}
+
+BarProp& LocalDOMWindow::personalbar() const
+{
+ if (!m_personalbar)
+ m_personalbar = BarProp::create(m_frame, BarProp::Personalbar);
+ return *m_personalbar;
+}
+
+BarProp& LocalDOMWindow::scrollbars() const
+{
+ if (!m_scrollbars)
+ m_scrollbars = BarProp::create(m_frame, BarProp::Scrollbars);
+ return *m_scrollbars;
+}
+
+BarProp& LocalDOMWindow::statusbar() const
+{
+ if (!m_statusbar)
+ m_statusbar = BarProp::create(m_frame, BarProp::Statusbar);
+ return *m_statusbar;
+}
+
+BarProp& LocalDOMWindow::toolbar() const
+{
+ if (!m_toolbar)
+ m_toolbar = BarProp::create(m_frame, BarProp::Toolbar);
+ return *m_toolbar;
+}
+
+Console& LocalDOMWindow::console() const
+{
+ if (!m_console)
+ m_console = Console::create(m_frame);
+ return *m_console;
+}
+
+FrameConsole* LocalDOMWindow::frameConsole() const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return 0;
+ return &m_frame->console();
+}
+
+ApplicationCache* LocalDOMWindow::applicationCache() const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return 0;
+ if (!m_applicationCache)
+ m_applicationCache = ApplicationCache::create(m_frame);
+ return m_applicationCache.get();
+}
+
+Navigator& LocalDOMWindow::navigator() const
+{
+ if (!m_navigator)
+ m_navigator = Navigator::create(m_frame);
+ return *m_navigator;
+}
+
+Performance& LocalDOMWindow::performance() const
+{
+ if (!m_performance)
+ m_performance = Performance::create(m_frame);
+ return *m_performance;
+}
+
+Location& LocalDOMWindow::location() const
+{
+ if (!m_location)
+ m_location = Location::create(m_frame);
+ return *m_location;
+}
+
+Storage* LocalDOMWindow::sessionStorage(ExceptionState& exceptionState) const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return 0;
+
+ Document* document = this->document();
+ if (!document)
+ return 0;
+
+ String accessDeniedMessage = "Access is denied for this document.";
+ if (!document->securityOrigin()->canAccessLocalStorage()) {
+ if (document->isSandboxed(SandboxOrigin))
+ exceptionState.throwSecurityError("The document is sandboxed and lacks the 'allow-same-origin' flag.");
+ else if (document->url().protocolIs("data"))
+ exceptionState.throwSecurityError("Storage is disabled inside 'data:' URLs.");
+ else
+ exceptionState.throwSecurityError(accessDeniedMessage);
+ return 0;
+ }
+
+ if (m_sessionStorage) {
+ if (!m_sessionStorage->area()->canAccessStorage(m_frame)) {
+ exceptionState.throwSecurityError(accessDeniedMessage);
+ return 0;
+ }
+ return m_sessionStorage.get();
+ }
+
+ Page* page = document->page();
+ if (!page)
+ return 0;
+
+ OwnPtrWillBeRawPtr<StorageArea> storageArea = page->sessionStorage()->storageArea(document->securityOrigin());
+ if (!storageArea->canAccessStorage(m_frame)) {
+ exceptionState.throwSecurityError(accessDeniedMessage);
+ return 0;
+ }
+
+ m_sessionStorage = Storage::create(m_frame, storageArea.release());
+ return m_sessionStorage.get();
+}
+
+Storage* LocalDOMWindow::localStorage(ExceptionState& exceptionState) const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return 0;
+
+ Document* document = this->document();
+ if (!document)
+ return 0;
+
+ String accessDeniedMessage = "Access is denied for this document.";
+ if (!document->securityOrigin()->canAccessLocalStorage()) {
+ if (document->isSandboxed(SandboxOrigin))
+ exceptionState.throwSecurityError("The document is sandboxed and lacks the 'allow-same-origin' flag.");
+ else if (document->url().protocolIs("data"))
+ exceptionState.throwSecurityError("Storage is disabled inside 'data:' URLs.");
+ else
+ exceptionState.throwSecurityError(accessDeniedMessage);
+ return 0;
+ }
+
+ if (m_localStorage) {
+ if (!m_localStorage->area()->canAccessStorage(m_frame)) {
+ exceptionState.throwSecurityError(accessDeniedMessage);
+ return 0;
+ }
+ return m_localStorage.get();
+ }
+
+ // FIXME: Seems this check should be much higher?
+ FrameHost* host = document->frameHost();
+ if (!host || !host->settings().localStorageEnabled())
+ return 0;
+
+ OwnPtrWillBeRawPtr<StorageArea> storageArea = StorageNamespace::localStorageArea(document->securityOrigin());
+ if (!storageArea->canAccessStorage(m_frame)) {
+ exceptionState.throwSecurityError(accessDeniedMessage);
+ return 0;
+ }
+
+ m_localStorage = Storage::create(m_frame, storageArea.release());
+ return m_localStorage.get();
+}
+
+void LocalDOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, const String& targetOrigin, LocalDOMWindow* source, ExceptionState& exceptionState)
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return;
+
+ Document* sourceDocument = source->document();
+
+ // Compute the target origin. We need to do this synchronously in order
+ // to generate the SyntaxError exception correctly.
+ RefPtr<SecurityOrigin> target;
+ if (targetOrigin == "/") {
+ if (!sourceDocument)
+ return;
+ target = sourceDocument->securityOrigin();
+ } else if (targetOrigin != "*") {
+ target = SecurityOrigin::createFromString(targetOrigin);
+ // It doesn't make sense target a postMessage at a unique origin
+ // because there's no way to represent a unique origin in a string.
+ if (target->isUnique()) {
+ exceptionState.throwDOMException(SyntaxError, "Invalid target origin '" + targetOrigin + "' in a call to 'postMessage'.");
+ return;
+ }
+ }
+
+ OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, exceptionState);
+ if (exceptionState.hadException())
+ return;
+
+ // Capture the source of the message. We need to do this synchronously
+ // in order to capture the source of the message correctly.
+ if (!sourceDocument)
+ return;
+ String sourceOrigin = sourceDocument->securityOrigin()->toString();
+
+ if (MixedContentChecker::isMixedContent(sourceDocument->securityOrigin(), document()->url()))
+ UseCounter::count(document(), UseCounter::PostMessageFromSecureToInsecure);
+ else if (MixedContentChecker::isMixedContent(document()->securityOrigin(), sourceDocument->url()))
+ UseCounter::count(document(), UseCounter::PostMessageFromInsecureToSecure);
+
+ // Capture stack trace only when inspector front-end is loaded as it may be time consuming.
+ RefPtrWillBeRawPtr<ScriptCallStack> stackTrace = nullptr;
+ if (InspectorInstrumentation::consoleAgentEnabled(sourceDocument))
+ stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
+
+ // Schedule the message.
+ OwnPtr<PostMessageTimer> timer = adoptPtr(new PostMessageTimer(*this, message, sourceOrigin, source, channels.release(), target.get(), stackTrace.release(), UserGestureIndicator::currentToken()));
+ timer->startOneShot(0, FROM_HERE);
+ timer->suspendIfNeeded();
+ m_postMessageTimers.add(timer.release());
+}
+
+void LocalDOMWindow::postMessageTimerFired(PostMessageTimer* timer)
+{
+ if (!isCurrentlyDisplayedInFrame()) {
+ m_postMessageTimers.remove(timer);
+ return;
+ }
+
+ RefPtrWillBeRawPtr<MessageEvent> event = timer->event();
+
+ // Give the embedder a chance to intercept this postMessage because this
+ // LocalDOMWindow might be a proxy for another in browsers that support
+ // postMessage calls across WebKit instances.
+ if (m_frame->loader().client()->willCheckAndDispatchMessageEvent(timer->targetOrigin(), event.get())) {
+ m_postMessageTimers.remove(timer);
+ return;
+ }
+
+ UserGestureIndicator gestureIndicator(timer->userGestureToken());
+
+ event->entangleMessagePorts(document());
+ dispatchMessageEventWithOriginCheck(timer->targetOrigin(), event, timer->stackTrace());
+ m_postMessageTimers.remove(timer);
+}
+
+void LocalDOMWindow::dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, PassRefPtrWillBeRawPtr<Event> event, PassRefPtrWillBeRawPtr<ScriptCallStack> stackTrace)
+{
+ if (intendedTargetOrigin) {
+ // Check target origin now since the target document may have changed since the timer was scheduled.
+ if (!intendedTargetOrigin->isSameSchemeHostPort(document()->securityOrigin())) {
+ String message = ExceptionMessages::failedToExecute("postMessage", "DOMWindow", "The target origin provided ('" + intendedTargetOrigin->toString() + "') does not match the recipient window's origin ('" + document()->securityOrigin()->toString() + "').");
+ frameConsole()->addMessage(SecurityMessageSource, ErrorMessageLevel, message, stackTrace);
+ return;
+ }
+ }
+
+ dispatchEvent(event);
+}
+
+DOMSelection* LocalDOMWindow::getSelection()
+{
+ if (!isCurrentlyDisplayedInFrame() || !m_frame)
+ return 0;
+
+ return m_frame->document()->getSelection();
+}
+
+Element* LocalDOMWindow::frameElement() const
+{
+ if (!m_frame)
+ return 0;
+
+ // The bindings security check should ensure we're same origin...
+ ASSERT(!m_frame->owner() || m_frame->owner()->isLocal());
+ return m_frame->deprecatedLocalOwner();
+}
+
+void LocalDOMWindow::focus(ExecutionContext* context)
+{
+ if (!m_frame)
+ return;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ bool allowFocus = WindowFocusAllowedIndicator::windowFocusAllowed();
+ if (context) {
+ ASSERT(isMainThread());
+ Document* activeDocument = toDocument(context);
+ if (opener() && opener() != this && activeDocument->domWindow() == opener())
+ allowFocus = true;
+ }
+
+ // If we're a top level window, bring the window to the front.
+ if (m_frame->isMainFrame() && allowFocus)
+ host->chrome().focus();
+
+ if (!m_frame)
+ return;
+
+ m_frame->eventHandler().focusDocumentView();
+}
+
+void LocalDOMWindow::blur()
+{
+}
+
+void LocalDOMWindow::close(ExecutionContext* context)
+{
+ if (!m_frame || !m_frame->isMainFrame())
+ return;
+
+ Page* page = m_frame->page();
+ if (!page)
+ return;
+
+ if (context) {
+ ASSERT(isMainThread());
+ Document* activeDocument = toDocument(context);
+ if (!activeDocument)
+ return;
+
+ if (!activeDocument->canNavigate(*m_frame))
+ return;
+ }
+
+ Settings* settings = m_frame->settings();
+ bool allowScriptsToCloseWindows = settings && settings->allowScriptsToCloseWindows();
+
+ if (!(page->openedByDOM() || page->backForward().backForwardListCount() <= 1 || allowScriptsToCloseWindows)) {
+ frameConsole()->addMessage(JSMessageSource, WarningMessageLevel, "Scripts may close only the windows that were opened by it.");
+ return;
+ }
+
+ if (!m_frame->loader().shouldClose())
+ return;
+
+ page->chrome().closeWindowSoon();
+}
+
+void LocalDOMWindow::print()
+{
+ if (!m_frame)
+ return;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ if (m_frame->loader().state() != FrameStateComplete) {
+ m_shouldPrintWhenFinishedLoading = true;
+ return;
+ }
+ m_shouldPrintWhenFinishedLoading = false;
+ host->chrome().print(m_frame);
+}
+
+void LocalDOMWindow::stop()
+{
+ if (!m_frame)
+ return;
+ m_frame->loader().stopAllLoaders();
+}
+
+void LocalDOMWindow::alert(const String& message)
+{
+ if (!m_frame)
+ return;
+
+ m_frame->document()->updateRenderTreeIfNeeded();
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ host->chrome().runJavaScriptAlert(m_frame, message);
+}
+
+bool LocalDOMWindow::confirm(const String& message)
+{
+ if (!m_frame)
+ return false;
+
+ m_frame->document()->updateRenderTreeIfNeeded();
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return false;
+
+ return host->chrome().runJavaScriptConfirm(m_frame, message);
+}
+
+String LocalDOMWindow::prompt(const String& message, const String& defaultValue)
+{
+ if (!m_frame)
+ return String();
+
+ m_frame->document()->updateRenderTreeIfNeeded();
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return String();
+
+ String returnValue;
+ if (host->chrome().runJavaScriptPrompt(m_frame, message, defaultValue, returnValue))
+ return returnValue;
+
+ return String();
+}
+
+bool LocalDOMWindow::find(const String& string, bool caseSensitive, bool backwards, bool wrap, bool /*wholeWord*/, bool /*searchInFrames*/, bool /*showDialog*/) const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return false;
+
+ // |m_frame| can be destructed during |Editor::findString()| via
+ // |Document::updateLayou()|, e.g. event handler removes a frame.
+ RefPtr<LocalFrame> protectFrame(m_frame);
+
+ // FIXME (13016): Support wholeWord, searchInFrames and showDialog
+ return m_frame->editor().findString(string, !backwards, caseSensitive, wrap, false);
+}
+
+bool LocalDOMWindow::offscreenBuffering() const
+{
+ return true;
+}
+
+int LocalDOMWindow::outerHeight() const
+{
+ if (!m_frame)
+ return 0;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return 0;
+
+ if (host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(host->chrome().windowRect().height() * host->deviceScaleFactor());
+ return static_cast<int>(host->chrome().windowRect().height());
+}
+
+int LocalDOMWindow::outerWidth() const
+{
+ if (!m_frame)
+ return 0;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return 0;
+
+ if (host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(host->chrome().windowRect().width() * host->deviceScaleFactor());
+ return static_cast<int>(host->chrome().windowRect().width());
+}
+
+int LocalDOMWindow::innerHeight() const
+{
+ if (!m_frame)
+ return 0;
+
+ FrameView* view = m_frame->view();
+ if (!view)
+ return 0;
+
+ // FIXME: This is potentially too much work. We really only need to know the dimensions of the parent frame's renderer.
+ if (Frame* parent = m_frame->tree().parent()) {
+ if (parent && parent->isLocalFrame())
+ toLocalFrame(parent)->document()->updateLayoutIgnorePendingStylesheets();
+ }
+
+ return adjustForAbsoluteZoom(view->visibleContentRect(IncludeScrollbars).height(), m_frame->pageZoomFactor());
+}
+
+int LocalDOMWindow::innerWidth() const
+{
+ if (!m_frame)
+ return 0;
+
+ FrameView* view = m_frame->view();
+ if (!view)
+ return 0;
+
+ // FIXME: This is potentially too much work. We really only need to know the dimensions of the parent frame's renderer.
+ if (Frame* parent = m_frame->tree().parent()) {
+ if (parent && parent->isLocalFrame())
+ toLocalFrame(parent)->document()->updateLayoutIgnorePendingStylesheets();
+ }
+
+ return adjustForAbsoluteZoom(view->visibleContentRect(IncludeScrollbars).width(), m_frame->pageZoomFactor());
+}
+
+int LocalDOMWindow::screenX() const
+{
+ if (!m_frame)
+ return 0;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return 0;
+
+ if (host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(host->chrome().windowRect().x() * host->deviceScaleFactor());
+ return static_cast<int>(host->chrome().windowRect().x());
+}
+
+int LocalDOMWindow::screenY() const
+{
+ if (!m_frame)
+ return 0;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return 0;
+
+ if (host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(host->chrome().windowRect().y() * host->deviceScaleFactor());
+ return static_cast<int>(host->chrome().windowRect().y());
+}
+
+int LocalDOMWindow::scrollX() const
+{
+ if (!m_frame)
+ return 0;
+
+ FrameView* view = m_frame->view();
+ if (!view)
+ return 0;
+
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
+
+ return adjustForAbsoluteZoom(view->scrollX(), m_frame->pageZoomFactor());
+}
+
+int LocalDOMWindow::scrollY() const
+{
+ if (!m_frame)
+ return 0;
+
+ FrameView* view = m_frame->view();
+ if (!view)
+ return 0;
+
+ m_frame->document()->updateLayoutIgnorePendingStylesheets();
+
+ return adjustForAbsoluteZoom(view->scrollY(), m_frame->pageZoomFactor());
+}
+
+bool LocalDOMWindow::closed() const
+{
+ return !m_frame;
+}
+
+unsigned LocalDOMWindow::length() const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return 0;
+
+ return m_frame->tree().scopedChildCount();
+}
+
+const AtomicString& LocalDOMWindow::name() const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return nullAtom;
+
+ return m_frame->tree().name();
+}
+
+void LocalDOMWindow::setName(const AtomicString& name)
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return;
+
+ m_frame->tree().setName(name);
+ ASSERT(m_frame->loader().client());
+ m_frame->loader().client()->didChangeName(name);
+}
+
+void LocalDOMWindow::setStatus(const String& string)
+{
+ m_status = string;
+
+ if (!m_frame)
+ return;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ ASSERT(m_frame->document()); // Client calls shouldn't be made when the frame is in inconsistent state.
+ host->chrome().setStatusbarText(m_frame, m_status);
+}
+
+void LocalDOMWindow::setDefaultStatus(const String& string)
+{
+ m_defaultStatus = string;
+
+ if (!m_frame)
+ return;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ ASSERT(m_frame->document()); // Client calls shouldn't be made when the frame is in inconsistent state.
+ host->chrome().setStatusbarText(m_frame, m_defaultStatus);
+}
+
+LocalDOMWindow* LocalDOMWindow::self() const
+{
+ if (!m_frame)
+ return 0;
+
+ return m_frame->domWindow();
+}
+
+LocalDOMWindow* LocalDOMWindow::opener() const
+{
+ if (!m_frame)
+ return 0;
+
+ LocalFrame* opener = m_frame->loader().opener();
+ if (!opener)
+ return 0;
+
+ return opener->domWindow();
+}
+
+LocalDOMWindow* LocalDOMWindow::parent() const
+{
+ if (!m_frame)
+ return 0;
+
+ Frame* parent = m_frame->tree().parent();
+ if (parent)
+ return parent->domWindow();
+
+ return m_frame->domWindow();
+}
+
+LocalDOMWindow* LocalDOMWindow::top() const
+{
+ if (!m_frame)
+ return 0;
+
+ return m_frame->tree().top()->domWindow();
+}
+
+Document* LocalDOMWindow::document() const
+{
+ return m_document.get();
+}
+
+StyleMedia& LocalDOMWindow::styleMedia() const
+{
+ if (!m_media)
+ m_media = StyleMedia::create(m_frame);
+ return *m_media;
+}
+
+PassRefPtrWillBeRawPtr<CSSStyleDeclaration> LocalDOMWindow::getComputedStyle(Element* elt, const String& pseudoElt) const
+{
+ if (!elt)
+ return nullptr;
+
+ return CSSComputedStyleDeclaration::create(elt, false, pseudoElt);
+}
+
+PassRefPtrWillBeRawPtr<CSSRuleList> LocalDOMWindow::getMatchedCSSRules(Element* element, const String& pseudoElement) const
+{
+ if (!element)
+ return nullptr;
+
+ if (!isCurrentlyDisplayedInFrame())
+ return nullptr;
+
+ unsigned colonStart = pseudoElement[0] == ':' ? (pseudoElement[1] == ':' ? 2 : 1) : 0;
+ CSSSelector::PseudoType pseudoType = CSSSelector::parsePseudoType(AtomicString(pseudoElement.substring(colonStart)));
+ if (pseudoType == CSSSelector::PseudoUnknown && !pseudoElement.isEmpty())
+ return nullptr;
+
+ unsigned rulesToInclude = StyleResolver::AuthorCSSRules;
+ PseudoId pseudoId = CSSSelector::pseudoId(pseudoType);
+ return m_frame->document()->ensureStyleResolver().pseudoCSSRulesForElement(element, pseudoId, rulesToInclude);
+}
+
+PassRefPtrWillBeRawPtr<DOMPoint> LocalDOMWindow::webkitConvertPointFromNodeToPage(Node* node, const DOMPoint* p) const
+{
+ if (!node || !p)
+ return nullptr;
+
+ if (!document())
+ return nullptr;
+
+ document()->updateLayoutIgnorePendingStylesheets();
+
+ FloatPoint pagePoint(p->x(), p->y());
+ pagePoint = node->convertToPage(pagePoint);
+ return DOMPoint::create(pagePoint.x(), pagePoint.y());
+}
+
+PassRefPtrWillBeRawPtr<DOMPoint> LocalDOMWindow::webkitConvertPointFromPageToNode(Node* node, const DOMPoint* p) const
+{
+ if (!node || !p)
+ return nullptr;
+
+ if (!document())
+ return nullptr;
+
+ document()->updateLayoutIgnorePendingStylesheets();
+
+ FloatPoint nodePoint(p->x(), p->y());
+ nodePoint = node->convertFromPage(nodePoint);
+ return DOMPoint::create(nodePoint.x(), nodePoint.y());
+}
+
+double LocalDOMWindow::devicePixelRatio() const
+{
+ if (!m_frame)
+ return 0.0;
+
+ return m_frame->devicePixelRatio();
+}
+
+static bool scrollBehaviorFromScrollOptions(const Dictionary& scrollOptions, ScrollBehavior& scrollBehavior, ExceptionState& exceptionState)
+{
+ String scrollBehaviorString;
+ if (!scrollOptions.get("behavior", scrollBehaviorString)) {
+ scrollBehavior = ScrollBehaviorAuto;
+ return true;
+ }
+
+ if (ScrollableArea::scrollBehaviorFromString(scrollBehaviorString, scrollBehavior))
+ return true;
+
+ exceptionState.throwTypeError("The ScrollBehavior provided is invalid.");
+ return false;
+}
+
+void LocalDOMWindow::scrollBy(int x, int y) const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return;
+
+ document()->updateLayoutIgnorePendingStylesheets();
+
+ FrameView* view = m_frame->view();
+ if (!view)
+ return;
+
+ IntSize scaledOffset(x * m_frame->pageZoomFactor(), y * m_frame->pageZoomFactor());
+ // FIXME: Use scrollBehavior to decide whether to scroll smoothly or instantly.
+ view->scrollBy(scaledOffset);
+}
+
+void LocalDOMWindow::scrollBy(int x, int y, const Dictionary& scrollOptions, ExceptionState &exceptionState) const
+{
+ ScrollBehavior scrollBehavior = ScrollBehaviorAuto;
+ if (!scrollBehaviorFromScrollOptions(scrollOptions, scrollBehavior, exceptionState))
+ return;
+ scrollBy(x, y);
+}
+
+void LocalDOMWindow::scrollTo(int x, int y) const
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return;
+
+ document()->updateLayoutIgnorePendingStylesheets();
+
+ RefPtr<FrameView> view = m_frame->view();
+ if (!view)
+ return;
+
+ IntPoint layoutPos(x * m_frame->pageZoomFactor(), y * m_frame->pageZoomFactor());
+ // FIXME: Use scrollBehavior to decide whether to scroll smoothly or instantly.
+ view->setScrollPosition(layoutPos);
+}
+
+void LocalDOMWindow::scrollTo(int x, int y, const Dictionary& scrollOptions, ExceptionState& exceptionState) const
+{
+ ScrollBehavior scrollBehavior = ScrollBehaviorAuto;
+ if (!scrollBehaviorFromScrollOptions(scrollOptions, scrollBehavior, exceptionState))
+ return;
+ scrollTo(x, y);
+}
+
+void LocalDOMWindow::moveBy(float x, float y) const
+{
+ if (!m_frame || !m_frame->isMainFrame())
+ return;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ FloatRect windowRect = host->chrome().windowRect();
+ windowRect.move(x, y);
+ // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
+ host->chrome().setWindowRect(adjustWindowRect(*m_frame, windowRect));
+}
+
+void LocalDOMWindow::moveTo(float x, float y) const
+{
+ if (!m_frame || !m_frame->isMainFrame())
+ return;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ FloatRect windowRect = host->chrome().windowRect();
+ windowRect.setLocation(FloatPoint(x, y));
+ // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
+ host->chrome().setWindowRect(adjustWindowRect(*m_frame, windowRect));
+}
+
+void LocalDOMWindow::resizeBy(float x, float y) const
+{
+ if (!m_frame || !m_frame->isMainFrame())
+ return;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ FloatRect fr = host->chrome().windowRect();
+ FloatSize dest = fr.size() + FloatSize(x, y);
+ FloatRect update(fr.location(), dest);
+ host->chrome().setWindowRect(adjustWindowRect(*m_frame, update));
+}
+
+void LocalDOMWindow::resizeTo(float width, float height) const
+{
+ if (!m_frame || !m_frame->isMainFrame())
+ return;
+
+ FrameHost* host = m_frame->host();
+ if (!host)
+ return;
+
+ FloatRect fr = host->chrome().windowRect();
+ FloatSize dest = FloatSize(width, height);
+ FloatRect update(fr.location(), dest);
+ host->chrome().setWindowRect(adjustWindowRect(*m_frame, update));
+}
+
+int LocalDOMWindow::requestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback> callback)
+{
+ callback->m_useLegacyTimeBase = false;
+ if (Document* d = document())
+ return d->requestAnimationFrame(callback);
+ return 0;
+}
+
+int LocalDOMWindow::webkitRequestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback> callback)
+{
+ callback->m_useLegacyTimeBase = true;
+ if (Document* d = document())
+ return d->requestAnimationFrame(callback);
+ return 0;
+}
+
+void LocalDOMWindow::cancelAnimationFrame(int id)
+{
+ if (Document* d = document())
+ d->cancelAnimationFrame(id);
+}
+
+DOMWindowCSS& LocalDOMWindow::css() const
+{
+ if (!m_css)
+ m_css = DOMWindowCSS::create();
+ return *m_css;
+}
+
+static void didAddStorageEventListener(LocalDOMWindow* window)
+{
+ // Creating these WebCore::Storage objects informs the system that we'd like to receive
+ // notifications about storage events that might be triggered in other processes. Rather
+ // than subscribe to these notifications explicitly, we subscribe to them implicitly to
+ // simplify the work done by the system.
+ window->localStorage(IGNORE_EXCEPTION);
+ window->sessionStorage(IGNORE_EXCEPTION);
+}
+
+bool LocalDOMWindow::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+{
+ if (!EventTarget::addEventListener(eventType, listener, useCapture))
+ return false;
+
+ if (m_frame && m_frame->host())
+ m_frame->host()->eventHandlerRegistry().didAddEventHandler(*this, eventType);
+
+ if (Document* document = this->document()) {
+ document->addListenerTypeIfNeeded(eventType);
+ if (isTouchEventType(eventType))
+ document->didAddTouchEventHandler(document);
+ else if (eventType == EventTypeNames::storage)
+ didAddStorageEventListener(this);
+ }
+
+ lifecycleNotifier().notifyAddEventListener(this, eventType);
+
+ if (eventType == EventTypeNames::unload) {
+ UseCounter::count(document(), UseCounter::DocumentUnloadRegistered);
+ addUnloadEventListener(this);
+ } else if (eventType == EventTypeNames::beforeunload) {
+ UseCounter::count(document(), UseCounter::DocumentBeforeUnloadRegistered);
+ if (allowsBeforeUnloadListeners(this)) {
+ // This is confusingly named. It doesn't actually add the listener. It just increments a count
+ // so that we know we have listeners registered for the purposes of determining if we can
+ // fast terminate the renderer process.
+ addBeforeUnloadEventListener(this);
+ } else {
+ // Subframes return false from allowsBeforeUnloadListeners.
+ UseCounter::count(document(), UseCounter::SubFrameBeforeUnloadRegistered);
+ }
+ }
+
+ return true;
+}
+
+bool LocalDOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+{
+ if (!EventTarget::removeEventListener(eventType, listener, useCapture))
+ return false;
+
+ if (m_frame && m_frame->host())
+ m_frame->host()->eventHandlerRegistry().didRemoveEventHandler(*this, eventType);
+
+ if (Document* document = this->document()) {
+ if (isTouchEventType(eventType))
+ document->didRemoveTouchEventHandler(document);
+ }
+
+ lifecycleNotifier().notifyRemoveEventListener(this, eventType);
+
+ if (eventType == EventTypeNames::unload) {
+ removeUnloadEventListener(this);
+ } else if (eventType == EventTypeNames::beforeunload && allowsBeforeUnloadListeners(this)) {
+ removeBeforeUnloadEventListener(this);
+ }
+
+ return true;
+}
+
+void LocalDOMWindow::dispatchLoadEvent()
+{
+ RefPtrWillBeRawPtr<Event> loadEvent(Event::create(EventTypeNames::load));
+ if (m_frame && m_frame->loader().documentLoader() && !m_frame->loader().documentLoader()->timing()->loadEventStart()) {
+ // The DocumentLoader (and thus its DocumentLoadTiming) might get destroyed while dispatching
+ // the event, so protect it to prevent writing the end time into freed memory.
+ RefPtr<DocumentLoader> documentLoader = m_frame->loader().documentLoader();
+ DocumentLoadTiming* timing = documentLoader->timing();
+ timing->markLoadEventStart();
+ dispatchEvent(loadEvent, document());
+ timing->markLoadEventEnd();
+ } else
+ dispatchEvent(loadEvent, document());
+
+ // For load events, send a separate load event to the enclosing frame only.
+ // This is a DOM extension and is independent of bubbling/capturing rules of
+ // the DOM.
+ FrameOwner* owner = m_frame ? m_frame->owner() : 0;
+ if (owner)
+ owner->dispatchLoad();
+
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "MarkLoad", "data", InspectorMarkLoadEvent::data(frame()));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::loadEventFired(frame());
+}
+
+bool LocalDOMWindow::dispatchEvent(PassRefPtrWillBeRawPtr<Event> prpEvent, PassRefPtrWillBeRawPtr<EventTarget> prpTarget)
+{
+ ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
+
+ RefPtrWillBeRawPtr<EventTarget> protect(this);
+ RefPtrWillBeRawPtr<Event> event = prpEvent;
+
+ event->setTarget(prpTarget ? prpTarget : this);
+ event->setCurrentTarget(this);
+ event->setEventPhase(Event::AT_TARGET);
+
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EventDispatch", "type", event->type().ascii());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEventOnWindow(frame(), *event, this);
+
+ bool result = fireEventListeners(event.get());
+
+ InspectorInstrumentation::didDispatchEventOnWindow(cookie);
+
+ return result;
+}
+
+void LocalDOMWindow::removeAllEventListenersInternal(BroadcastListenerRemoval mode)
+{
+ EventTarget::removeAllEventListeners();
+
+ lifecycleNotifier().notifyRemoveAllEventListeners(this);
+
+ if (mode == DoBroadcastListenerRemoval) {
+ if (m_frame && m_frame->host())
+ m_frame->host()->eventHandlerRegistry().didRemoveAllEventHandlers(*this);
+
+ if (Document* document = this->document())
+ document->didClearTouchEventHandlers(document);
+ }
+
+ removeAllUnloadEventListeners(this);
+ removeAllBeforeUnloadEventListeners(this);
+}
+
+void LocalDOMWindow::removeAllEventListeners()
+{
+ removeAllEventListenersInternal(DoBroadcastListenerRemoval);
+}
+
+void LocalDOMWindow::finishedLoading()
+{
+ if (m_shouldPrintWhenFinishedLoading) {
+ m_shouldPrintWhenFinishedLoading = false;
+ print();
+ }
+}
+
+void LocalDOMWindow::setLocation(const String& urlString, LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, SetLocationLocking locking)
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return;
+
+ Document* activeDocument = callingWindow->document();
+ if (!activeDocument)
+ return;
+
+ ASSERT(m_frame);
+ if (!activeDocument->canNavigate(*m_frame))
+ return;
+
+ LocalFrame* firstFrame = enteredWindow->frame();
+ if (!firstFrame)
+ return;
+
+ KURL completedURL = firstFrame->document()->completeURL(urlString);
+ if (completedURL.isNull())
+ return;
+
+ if (isInsecureScriptAccess(*callingWindow, completedURL))
+ return;
+
+ // We want a new history item if we are processing a user gesture.
+ m_frame->navigationScheduler().scheduleLocationChange(activeDocument,
+ // FIXME: What if activeDocument()->frame() is 0?
+ completedURL, Referrer(activeDocument->outgoingReferrer(), activeDocument->referrerPolicy()),
+ locking != LockHistoryBasedOnGestureState);
+}
+
+void LocalDOMWindow::printErrorMessage(const String& message)
+{
+ if (message.isEmpty())
+ return;
+
+ frameConsole()->addMessage(JSMessageSource, ErrorMessageLevel, message);
+}
+
+// FIXME: Once we're throwing exceptions for cross-origin access violations, we will always sanitize the target
+// frame details, so we can safely combine 'crossDomainAccessErrorMessage' with this method after considering
+// exactly which details may be exposed to JavaScript.
+//
+// http://crbug.com/17325
+String LocalDOMWindow::sanitizedCrossDomainAccessErrorMessage(LocalDOMWindow* callingWindow)
+{
+ if (!callingWindow || !callingWindow->document())
+ return String();
+
+ const KURL& callingWindowURL = callingWindow->document()->url();
+ if (callingWindowURL.isNull())
+ return String();
+
+ ASSERT(!callingWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()));
+
+ SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin();
+ String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a cross-origin frame.";
+
+ // FIXME: Evaluate which details from 'crossDomainAccessErrorMessage' may safely be reported to JavaScript.
+
+ return message;
+}
+
+String LocalDOMWindow::crossDomainAccessErrorMessage(LocalDOMWindow* callingWindow)
+{
+ if (!callingWindow || !callingWindow->document())
+ return String();
+
+ const KURL& callingWindowURL = callingWindow->document()->url();
+ if (callingWindowURL.isNull())
+ return String();
+
+ ASSERT(!callingWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()));
+
+ // FIXME: This message, and other console messages, have extra newlines. Should remove them.
+ SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin();
+ SecurityOrigin* targetOrigin = document()->securityOrigin();
+ String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a frame with origin \"" + targetOrigin->toString() + "\". ";
+
+ // Sandbox errors: Use the origin of the frames' location, rather than their actual origin (since we know that at least one will be "null").
+ KURL activeURL = callingWindow->document()->url();
+ KURL targetURL = document()->url();
+ if (document()->isSandboxed(SandboxOrigin) || callingWindow->document()->isSandboxed(SandboxOrigin)) {
+ message = "Blocked a frame at \"" + SecurityOrigin::create(activeURL)->toString() + "\" from accessing a frame at \"" + SecurityOrigin::create(targetURL)->toString() + "\". ";
+ if (document()->isSandboxed(SandboxOrigin) && callingWindow->document()->isSandboxed(SandboxOrigin))
+ return "Sandbox access violation: " + message + " Both frames are sandboxed and lack the \"allow-same-origin\" flag.";
+ if (document()->isSandboxed(SandboxOrigin))
+ return "Sandbox access violation: " + message + " The frame being accessed is sandboxed and lacks the \"allow-same-origin\" flag.";
+ return "Sandbox access violation: " + message + " The frame requesting access is sandboxed and lacks the \"allow-same-origin\" flag.";
+ }
+
+ // Protocol errors: Use the URL's protocol rather than the origin's protocol so that we get a useful message for non-heirarchal URLs like 'data:'.
+ if (targetOrigin->protocol() != activeOrigin->protocol())
+ return message + " The frame requesting access has a protocol of \"" + activeURL.protocol() + "\", the frame being accessed has a protocol of \"" + targetURL.protocol() + "\". Protocols must match.\n";
+
+ // 'document.domain' errors.
+ if (targetOrigin->domainWasSetInDOM() && activeOrigin->domainWasSetInDOM())
+ return message + "The frame requesting access set \"document.domain\" to \"" + activeOrigin->domain() + "\", the frame being accessed set it to \"" + targetOrigin->domain() + "\". Both must set \"document.domain\" to the same value to allow access.";
+ if (activeOrigin->domainWasSetInDOM())
+ return message + "The frame requesting access set \"document.domain\" to \"" + activeOrigin->domain() + "\", but the frame being accessed did not. Both must set \"document.domain\" to the same value to allow access.";
+ if (targetOrigin->domainWasSetInDOM())
+ return message + "The frame being accessed set \"document.domain\" to \"" + targetOrigin->domain() + "\", but the frame requesting access did not. Both must set \"document.domain\" to the same value to allow access.";
+
+ // Default.
+ return message + "Protocols, domains, and ports must match.";
+}
+
+bool LocalDOMWindow::isInsecureScriptAccess(LocalDOMWindow& callingWindow, const String& urlString)
+{
+ if (!protocolIsJavaScript(urlString))
+ return false;
+
+ // If this LocalDOMWindow isn't currently active in the LocalFrame, then there's no
+ // way we should allow the access.
+ // FIXME: Remove this check if we're able to disconnect LocalDOMWindow from
+ // LocalFrame on navigation: https://bugs.webkit.org/show_bug.cgi?id=62054
+ if (isCurrentlyDisplayedInFrame()) {
+ // FIXME: Is there some way to eliminate the need for a separate "callingWindow == this" check?
+ if (&callingWindow == this)
+ return false;
+
+ // FIXME: The name canAccess seems to be a roundabout way to ask "can execute script".
+ // Can we name the SecurityOrigin function better to make this more clear?
+ if (callingWindow.document()->securityOrigin()->canAccess(document()->securityOrigin()))
+ return false;
+ }
+
+ printErrorMessage(crossDomainAccessErrorMessage(&callingWindow));
+ return true;
+}
+
+PassRefPtrWillBeRawPtr<LocalDOMWindow> LocalDOMWindow::open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
+ LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow)
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return nullptr;
+ Document* activeDocument = callingWindow->document();
+ if (!activeDocument)
+ return nullptr;
+ LocalFrame* firstFrame = enteredWindow->frame();
+ if (!firstFrame)
+ return nullptr;
+
+ if (!enteredWindow->allowPopUp()) {
+ // Because FrameTree::find() returns true for empty strings, we must check for empty frame names.
+ // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
+ if (frameName.isEmpty() || !m_frame->tree().find(frameName))
+ return nullptr;
+ }
+
+ // Get the target frame for the special cases of _top and _parent.
+ // In those cases, we schedule a location change right now and return early.
+ Frame* targetFrame = 0;
+ if (frameName == "_top")
+ targetFrame = m_frame->tree().top();
+ else if (frameName == "_parent") {
+ if (Frame* parent = m_frame->tree().parent())
+ targetFrame = parent;
+ else
+ targetFrame = m_frame;
+ }
+ // FIXME: Navigating RemoteFrames is not yet supported.
+ if (targetFrame && targetFrame->isLocalFrame()) {
+ if (!activeDocument->canNavigate(*targetFrame))
+ return nullptr;
+
+ KURL completedURL = firstFrame->document()->completeURL(urlString);
+
+ if (targetFrame->domWindow()->isInsecureScriptAccess(*callingWindow, completedURL))
+ return targetFrame->domWindow();
+
+ if (urlString.isEmpty())
+ return targetFrame->domWindow();
+
+ // For whatever reason, Firefox uses the first window rather than the active window to
+ // determine the outgoing referrer. We replicate that behavior here.
+ toLocalFrame(targetFrame)->navigationScheduler().scheduleLocationChange(
+ activeDocument,
+ completedURL,
+ Referrer(firstFrame->document()->outgoingReferrer(), firstFrame->document()->referrerPolicy()),
+ false);
+ return targetFrame->domWindow();
+ }
+
+ WindowFeatures windowFeatures(windowFeaturesString);
+ LocalFrame* result = createWindow(urlString, frameName, windowFeatures, *callingWindow, *firstFrame, *m_frame);
+ return result ? result->domWindow() : 0;
+}
+
+void LocalDOMWindow::showModalDialog(const String& urlString, const String& dialogFeaturesString,
+ LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, PrepareDialogFunction function, void* functionContext)
+{
+ if (!isCurrentlyDisplayedInFrame())
+ return;
+ LocalFrame* activeFrame = callingWindow->frame();
+ if (!activeFrame)
+ return;
+ LocalFrame* firstFrame = enteredWindow->frame();
+ if (!firstFrame)
+ return;
+
+ if (!canShowModalDialogNow(m_frame) || !enteredWindow->allowPopUp())
+ return;
+
+ UseCounter::countDeprecation(this, UseCounter::ShowModalDialog);
+
+ WindowFeatures windowFeatures(dialogFeaturesString, screenAvailableRect(m_frame->view()));
+ LocalFrame* dialogFrame = createWindow(urlString, emptyAtom, windowFeatures,
+ *callingWindow, *firstFrame, *m_frame, function, functionContext);
+ if (!dialogFrame)
+ return;
+ UserGestureIndicatorDisabler disabler;
+ dialogFrame->host()->chrome().runModal();
+}
+
+LocalDOMWindow* LocalDOMWindow::anonymousIndexedGetter(uint32_t index)
+{
+ LocalFrame* frame = this->frame();
+ if (!frame)
+ return 0;
+
+ Frame* child = frame->tree().scopedChild(index);
+ if (child)
+ return child->domWindow();
+
+ return 0;
+}
+
+DOMWindowLifecycleNotifier& LocalDOMWindow::lifecycleNotifier()
+{
+ return static_cast<DOMWindowLifecycleNotifier&>(LifecycleContext<LocalDOMWindow>::lifecycleNotifier());
+}
+
+PassOwnPtr<LifecycleNotifier<LocalDOMWindow> > LocalDOMWindow::createLifecycleNotifier()
+{
+ return DOMWindowLifecycleNotifier::create(this);
+}
+
+void LocalDOMWindow::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_screen);
+ visitor->trace(m_history);
+ visitor->trace(m_locationbar);
+ visitor->trace(m_menubar);
+ visitor->trace(m_personalbar);
+ visitor->trace(m_scrollbars);
+ visitor->trace(m_statusbar);
+ visitor->trace(m_toolbar);
+ visitor->trace(m_console);
+ visitor->trace(m_navigator);
+ visitor->trace(m_location);
+ visitor->trace(m_media);
+ visitor->trace(m_sessionStorage);
+ visitor->trace(m_localStorage);
+ visitor->trace(m_applicationCache);
+ visitor->trace(m_performance);
+ visitor->trace(m_css);
+ visitor->trace(m_eventQueue);
+ WillBeHeapSupplementable<LocalDOMWindow>::trace(visitor);
+ EventTargetWithInlineData::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/chromium/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
new file mode 100644
index 00000000000..82394787576
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2006, 2007, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DOMWindow_h
+#define DOMWindow_h
+
+#include "bindings/v8/Dictionary.h"
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/events/EventTarget.h"
+#include "core/frame/DOMWindowBase64.h"
+#include "core/frame/FrameDestructionObserver.h"
+#include "platform/LifecycleContext.h"
+#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
+
+#include "wtf/Forward.h"
+
+namespace WebCore {
+ class ApplicationCache;
+ class BarProp;
+ class CSSRuleList;
+ class CSSStyleDeclaration;
+ class Console;
+ class DOMPoint;
+ class DOMSelection;
+ class DOMURL;
+ class DOMWindowProperty;
+ class Database;
+ class DatabaseCallback;
+ class Document;
+ class DocumentInit;
+ class DOMWindowEventQueue;
+ class DOMWindowLifecycleNotifier;
+ class Element;
+ class EventListener;
+ class EventQueue;
+ class ExceptionState;
+ class FloatRect;
+ class FrameConsole;
+ class History;
+ class IDBFactory;
+ class LocalFrame;
+ class Location;
+ class MediaQueryList;
+ class MessageEvent;
+ class Navigator;
+ class Node;
+ class Page;
+ class Performance;
+ class PostMessageTimer;
+ class RequestAnimationFrameCallback;
+ class ScheduledAction;
+ class Screen;
+ class ScriptCallStack;
+ class SecurityOrigin;
+ class SerializedScriptValue;
+ class Storage;
+ class StyleMedia;
+ class DOMWindowCSS;
+
+ struct WindowFeatures;
+
+ typedef Vector<RefPtr<MessagePort>, 1> MessagePortArray;
+
+enum PageshowEventPersistence {
+ PageshowEventNotPersisted = 0,
+ PageshowEventPersisted = 1
+};
+
+ enum SetLocationLocking { LockHistoryBasedOnGestureState, LockHistoryAndBackForwardList };
+
+ class LocalDOMWindow FINAL : public RefCountedWillBeRefCountedGarbageCollected<LocalDOMWindow>, public ScriptWrappable, public EventTargetWithInlineData, public DOMWindowBase64, public FrameDestructionObserver, public WillBeHeapSupplementable<LocalDOMWindow>, public LifecycleContext<LocalDOMWindow> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(LocalDOMWindow);
+ REFCOUNTED_EVENT_TARGET(LocalDOMWindow);
+ public:
+ static PassRefPtrWillBeRawPtr<Document> createDocument(const String& mimeType, const DocumentInit&, bool forceXHTML);
+ static PassRefPtrWillBeRawPtr<LocalDOMWindow> create(LocalFrame& frame)
+ {
+ return adoptRefWillBeRefCountedGarbageCollected(new LocalDOMWindow(frame));
+ }
+ virtual ~LocalDOMWindow();
+
+ PassRefPtrWillBeRawPtr<Document> installNewDocument(const String& mimeType, const DocumentInit&, bool forceXHTML = false);
+
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+ virtual ExecutionContext* executionContext() const OVERRIDE;
+
+ virtual LocalDOMWindow* toDOMWindow() OVERRIDE;
+
+ void registerProperty(DOMWindowProperty*);
+ void unregisterProperty(DOMWindowProperty*);
+
+ void reset();
+
+ PassRefPtrWillBeRawPtr<MediaQueryList> matchMedia(const String&);
+
+ unsigned pendingUnloadEventListeners() const;
+
+ static FloatRect adjustWindowRect(LocalFrame&, const FloatRect& pendingChanges);
+
+ bool allowPopUp(); // Call on first window, not target window.
+ static bool allowPopUp(LocalFrame& firstFrame);
+ static bool canShowModalDialogNow(const LocalFrame*);
+
+ // DOM Level 0
+
+ Screen& screen() const;
+ History& history() const;
+ BarProp& locationbar() const;
+ BarProp& menubar() const;
+ BarProp& personalbar() const;
+ BarProp& scrollbars() const;
+ BarProp& statusbar() const;
+ BarProp& toolbar() const;
+ Navigator& navigator() const;
+ Navigator& clientInformation() const { return navigator(); }
+
+ Location& location() const;
+ void setLocation(const String& location, LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow,
+ SetLocationLocking = LockHistoryBasedOnGestureState);
+
+ DOMSelection* getSelection();
+
+ Element* frameElement() const;
+
+ void focus(ExecutionContext* = 0);
+ void blur();
+ void close(ExecutionContext* = 0);
+ void print();
+ void stop();
+
+ PassRefPtrWillBeRawPtr<LocalDOMWindow> open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
+ LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow);
+
+ typedef void (*PrepareDialogFunction)(LocalDOMWindow*, void* context);
+ void showModalDialog(const String& urlString, const String& dialogFeaturesString,
+ LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, PrepareDialogFunction, void* functionContext);
+
+ void alert(const String& message = String());
+ bool confirm(const String& message);
+ String prompt(const String& message, const String& defaultValue);
+
+ bool find(const String&, bool caseSensitive, bool backwards, bool wrap, bool wholeWord, bool searchInFrames, bool showDialog) const;
+
+ bool offscreenBuffering() const;
+
+ int outerHeight() const;
+ int outerWidth() const;
+ int innerHeight() const;
+ int innerWidth() const;
+ int screenX() const;
+ int screenY() const;
+ int screenLeft() const { return screenX(); }
+ int screenTop() const { return screenY(); }
+ int scrollX() const;
+ int scrollY() const;
+ int pageXOffset() const { return scrollX(); }
+ int pageYOffset() const { return scrollY(); }
+
+ bool closed() const;
+
+ unsigned length() const;
+
+ const AtomicString& name() const;
+ void setName(const AtomicString&);
+
+ String status() const;
+ void setStatus(const String&);
+ String defaultStatus() const;
+ void setDefaultStatus(const String&);
+
+ // Self-referential attributes
+
+ LocalDOMWindow* self() const;
+ LocalDOMWindow* window() const { return self(); }
+ LocalDOMWindow* frames() const { return self(); }
+
+ LocalDOMWindow* opener() const;
+ LocalDOMWindow* parent() const;
+ LocalDOMWindow* top() const;
+
+ // DOM Level 2 AbstractView Interface
+
+ Document* document() const;
+
+ // CSSOM View Module
+
+ StyleMedia& styleMedia() const;
+
+ // DOM Level 2 Style Interface
+
+ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> getComputedStyle(Element*, const String& pseudoElt) const;
+
+ // WebKit extensions
+
+ PassRefPtrWillBeRawPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt) const;
+ double devicePixelRatio() const;
+
+ PassRefPtrWillBeRawPtr<DOMPoint> webkitConvertPointFromPageToNode(Node*, const DOMPoint*) const;
+ PassRefPtrWillBeRawPtr<DOMPoint> webkitConvertPointFromNodeToPage(Node*, const DOMPoint*) const;
+
+ Console& console() const;
+ FrameConsole* frameConsole() const;
+
+ void printErrorMessage(const String&);
+ String crossDomainAccessErrorMessage(LocalDOMWindow* callingWindow);
+ String sanitizedCrossDomainAccessErrorMessage(LocalDOMWindow* callingWindow);
+
+ void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, LocalDOMWindow* source, ExceptionState&);
+ void postMessageTimerFired(PostMessageTimer*);
+ void dispatchMessageEventWithOriginCheck(SecurityOrigin* intendedTargetOrigin, PassRefPtrWillBeRawPtr<Event>, PassRefPtrWillBeRawPtr<ScriptCallStack>);
+
+ void scrollBy(int x, int y) const;
+ void scrollBy(int x, int y, const Dictionary& scrollOptions, ExceptionState&) const;
+ void scrollTo(int x, int y) const;
+ void scrollTo(int x, int y, const Dictionary& scrollOptions, ExceptionState&) const;
+ void scroll(int x, int y) const { scrollTo(x, y); }
+ void scroll(int x, int y, const Dictionary& scrollOptions, ExceptionState& exceptionState) const { scrollTo(x, y, scrollOptions, exceptionState); }
+
+ void moveBy(float x, float y) const;
+ void moveTo(float x, float y) const;
+
+ void resizeBy(float x, float y) const;
+ void resizeTo(float width, float height) const;
+
+ // WebKit animation extensions
+ int requestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback>);
+ int webkitRequestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback>);
+ void cancelAnimationFrame(int id);
+
+ DOMWindowCSS& css() const;
+
+ // Events
+ // EventTarget API
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE;
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture = false) OVERRIDE;
+ virtual void removeAllEventListeners() OVERRIDE;
+
+ using EventTarget::dispatchEvent;
+ bool dispatchEvent(PassRefPtrWillBeRawPtr<Event> prpEvent, PassRefPtrWillBeRawPtr<EventTarget> prpTarget);
+
+ void dispatchLoadEvent();
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(animationend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(animationiteration);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(animationstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(search);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(transitionend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(wheel);
+
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationstart, webkitAnimationStart);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationiteration, webkitAnimationIteration);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkitanimationend, webkitAnimationEnd);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(webkittransitionend, webkitTransitionEnd);
+
+ void captureEvents() { }
+ void releaseEvents() { }
+
+ void finishedLoading();
+
+ // HTML 5 key/value storage
+ Storage* sessionStorage(ExceptionState&) const;
+ Storage* localStorage(ExceptionState&) const;
+ Storage* optionalSessionStorage() const { return m_sessionStorage.get(); }
+ Storage* optionalLocalStorage() const { return m_localStorage.get(); }
+
+ ApplicationCache* applicationCache() const;
+ ApplicationCache* optionalApplicationCache() const { return m_applicationCache.get(); }
+
+ // This is the interface orientation in degrees. Some examples are:
+ // 0 is straight up; -90 is when the device is rotated 90 clockwise;
+ // 90 is when rotated counter clockwise.
+ int orientation() const;
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(orientationchange);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchstart);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchmove);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
+
+ Performance& performance() const;
+
+ // FIXME: When this LocalDOMWindow is no longer the active LocalDOMWindow (i.e.,
+ // when its document is no longer the document that is displayed in its
+ // frame), we would like to zero out m_frame to avoid being confused
+ // by the document that is currently active in m_frame.
+ bool isCurrentlyDisplayedInFrame() const;
+
+ void willDetachDocumentFromFrame();
+ LocalDOMWindow* anonymousIndexedGetter(uint32_t);
+
+ bool isInsecureScriptAccess(LocalDOMWindow& callingWindow, const String& urlString);
+
+ PassOwnPtr<LifecycleNotifier<LocalDOMWindow> > createLifecycleNotifier();
+
+ EventQueue* eventQueue() const;
+ void enqueueWindowEvent(PassRefPtrWillBeRawPtr<Event>);
+ void enqueueDocumentEvent(PassRefPtrWillBeRawPtr<Event>);
+ void enqueuePageshowEvent(PageshowEventPersistence);
+ void enqueueHashchangeEvent(const String& oldURL, const String& newURL);
+ void enqueuePopstateEvent(PassRefPtr<SerializedScriptValue>);
+ void dispatchWindowLoadEvent();
+ void documentWasClosed();
+ void statePopped(PassRefPtr<SerializedScriptValue>);
+
+ // FIXME: This shouldn't be public once LocalDOMWindow becomes ExecutionContext.
+ void clearEventQueue();
+
+ void acceptLanguagesChanged();
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ protected:
+ DOMWindowLifecycleNotifier& lifecycleNotifier();
+
+ private:
+ explicit LocalDOMWindow(LocalFrame&);
+
+ Page* page();
+
+ virtual void frameDestroyed() OVERRIDE;
+ virtual void willDetachFrameHost() OVERRIDE;
+
+ void clearDocument();
+ void resetDOMWindowProperties();
+ void willDestroyDocumentInFrame();
+
+ // FIXME: Oilpan: the need for this internal method will fall
+ // away when EventTargets are no longer using refcounts and
+ // window properties are also on the heap. Inline the minimal
+ // do-not-broadcast handling then and remove the enum +
+ // removeAllEventListenersInternal().
+ enum BroadcastListenerRemoval {
+ DoNotBroadcastListenerRemoval,
+ DoBroadcastListenerRemoval
+ };
+
+ void removeAllEventListenersInternal(BroadcastListenerRemoval);
+
+ RefPtrWillBeMember<Document> m_document;
+
+ bool m_shouldPrintWhenFinishedLoading;
+#if ASSERT_ENABLED
+ bool m_hasBeenReset;
+#endif
+
+ HashSet<DOMWindowProperty*> m_properties;
+
+ mutable RefPtrWillBeMember<Screen> m_screen;
+ mutable RefPtrWillBeMember<History> m_history;
+ mutable RefPtrWillBeMember<BarProp> m_locationbar;
+ mutable RefPtrWillBeMember<BarProp> m_menubar;
+ mutable RefPtrWillBeMember<BarProp> m_personalbar;
+ mutable RefPtrWillBeMember<BarProp> m_scrollbars;
+ mutable RefPtrWillBeMember<BarProp> m_statusbar;
+ mutable RefPtrWillBeMember<BarProp> m_toolbar;
+ mutable RefPtrWillBeMember<Console> m_console;
+ mutable RefPtrWillBeMember<Navigator> m_navigator;
+ mutable RefPtrWillBeMember<Location> m_location;
+ mutable RefPtrWillBeMember<StyleMedia> m_media;
+
+ String m_status;
+ String m_defaultStatus;
+
+ mutable RefPtrWillBeMember<Storage> m_sessionStorage;
+ mutable RefPtrWillBeMember<Storage> m_localStorage;
+ mutable RefPtrWillBeMember<ApplicationCache> m_applicationCache;
+
+ mutable RefPtrWillBeMember<Performance> m_performance;
+
+ mutable RefPtrWillBeMember<DOMWindowCSS> m_css;
+
+ RefPtrWillBeMember<DOMWindowEventQueue> m_eventQueue;
+ RefPtr<SerializedScriptValue> m_pendingStateObject;
+
+ HashSet<OwnPtr<PostMessageTimer> > m_postMessageTimers;
+ };
+
+ inline String LocalDOMWindow::status() const
+ {
+ return m_status;
+ }
+
+ inline String LocalDOMWindow::defaultStatus() const
+ {
+ return m_defaultStatus;
+ }
+
+} // namespace WebCore
+
+#endif // DOMWindow_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp
new file mode 100644
index 00000000000..7fedecbd984
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -0,0 +1,660 @@
+/*
+ * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+ * 1999 Lars Knoll <knoll@kde.org>
+ * 1999 Antti Koivisto <koivisto@kde.org>
+ * 2000 Simon Hausmann <hausmann@kde.org>
+ * 2000 Stefan Schimanski <1Stein@gmx.de>
+ * 2001 George Staikos <staikos@kde.org>
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/frame/LocalFrame.h"
+
+#include "bindings/v8/ScriptController.h"
+#include "core/dom/DocumentType.h"
+#include "core/editing/Editor.h"
+#include "core/editing/FrameSelection.h"
+#include "core/editing/InputMethodController.h"
+#include "core/editing/SpellChecker.h"
+#include "core/editing/htmlediting.h"
+#include "core/editing/markup.h"
+#include "core/events/Event.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/EventHandlerRegistry.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLFrameElementBase.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "core/page/Chrome.h"
+#include "core/page/EventHandler.h"
+#include "core/page/FocusController.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "core/rendering/HitTestResult.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "core/svg/SVGDocumentExtensions.h"
+#include "platform/DragImage.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/ImageBuffer.h"
+#include "platform/text/TextStream.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/StdLibExtras.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static inline float parentPageZoomFactor(LocalFrame* frame)
+{
+ Frame* parent = frame->tree().parent();
+ if (!parent || !parent->isLocalFrame())
+ return 1;
+ return toLocalFrame(parent)->pageZoomFactor();
+}
+
+static inline float parentTextZoomFactor(LocalFrame* frame)
+{
+ Frame* parent = frame->tree().parent();
+ if (!parent || !parent->isLocalFrame())
+ return 1;
+ return toLocalFrame(parent)->textZoomFactor();
+}
+
+inline LocalFrame::LocalFrame(FrameLoaderClient* client, FrameHost* host, FrameOwner* owner)
+ : Frame(client, host, owner)
+ , m_loader(this)
+ , m_navigationScheduler(this)
+ , m_script(adoptPtr(new ScriptController(this)))
+ , m_editor(Editor::create(*this))
+ , m_spellChecker(SpellChecker::create(*this))
+ , m_selection(FrameSelection::create(this))
+ , m_eventHandler(adoptPtrWillBeNoop(new EventHandler(this)))
+ , m_console(FrameConsole::create(*this))
+ , m_inputMethodController(InputMethodController::create(*this))
+ , m_pageZoomFactor(parentPageZoomFactor(this))
+ , m_textZoomFactor(parentTextZoomFactor(this))
+ , m_inViewSourceMode(false)
+{
+}
+
+PassRefPtr<LocalFrame> LocalFrame::create(FrameLoaderClient* client, FrameHost* host, FrameOwner* owner)
+{
+ RefPtr<LocalFrame> frame = adoptRef(new LocalFrame(client, host, owner));
+ InspectorInstrumentation::frameAttachedToParent(frame.get());
+ return frame.release();
+}
+
+LocalFrame::~LocalFrame()
+{
+ setView(nullptr);
+ loader().clear();
+ setDOMWindow(nullptr);
+}
+
+bool LocalFrame::inScope(TreeScope* scope) const
+{
+ ASSERT(scope);
+ Document* doc = document();
+ if (!doc)
+ return false;
+ // FIXME: This check is broken in for OOPI.
+ HTMLFrameOwnerElement* owner = doc->ownerElement();
+ if (!owner)
+ return false;
+ return owner->treeScope() == scope;
+}
+
+void LocalFrame::setView(PassRefPtr<FrameView> view)
+{
+ // We the custom scroll bars as early as possible to prevent m_doc->detach()
+ // from messing with the view such that its scroll bars won't be torn down.
+ // FIXME: We should revisit this.
+ if (m_view)
+ m_view->prepareForDetach();
+
+ // Prepare for destruction now, so any unload event handlers get run and the LocalDOMWindow is
+ // notified. If we wait until the view is destroyed, then things won't be hooked up enough for
+ // these calls to work.
+ if (!view && document() && document()->isActive()) {
+ // FIXME: We don't call willRemove here. Why is that OK?
+ document()->prepareForDestruction();
+ }
+
+ eventHandler().clear();
+
+ m_view = view;
+
+ if (m_view && isMainFrame()) {
+ if (settings()->pinchVirtualViewportEnabled())
+ m_host->pinchViewport().mainFrameDidChangeSize();
+ else
+ m_view->setVisibleContentScaleFactor(page()->pageScaleFactor());
+ }
+}
+
+void LocalFrame::sendOrientationChangeEvent()
+{
+ if (!RuntimeEnabledFeatures::orientationEventEnabled() && !RuntimeEnabledFeatures::screenOrientationEnabled())
+ return;
+
+ if (page()->visibilityState() != PageVisibilityStateVisible)
+ return;
+
+ LocalDOMWindow* window = domWindow();
+ if (!window)
+ return;
+ window->dispatchEvent(Event::create(EventTypeNames::orientationchange));
+
+ // Notify subframes.
+ Vector<RefPtr<LocalFrame> > childFrames;
+ for (Frame* child = tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ childFrames.append(toLocalFrame(child));
+ }
+
+ for (size_t i = 0; i < childFrames.size(); ++i)
+ childFrames[i]->sendOrientationChangeEvent();
+}
+
+void LocalFrame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio)
+{
+ // In setting printing, we should not validate resources already cached for the document.
+ // See https://bugs.webkit.org/show_bug.cgi?id=43704
+ ResourceCacheValidationSuppressor validationSuppressor(document()->fetcher());
+
+ document()->setPrinting(printing);
+ view()->adjustMediaTypeForPrinting(printing);
+
+ document()->styleResolverChanged();
+ if (shouldUsePrintingLayout()) {
+ view()->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio);
+ } else {
+ view()->forceLayout();
+ view()->adjustViewSize();
+ }
+
+ // Subframes of the one we're printing don't lay out to the page size.
+ for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ toLocalFrame(child.get())->setPrinting(printing, FloatSize(), FloatSize(), 0);
+ }
+}
+
+bool LocalFrame::shouldUsePrintingLayout() const
+{
+ // Only top frame being printed should be fit to page size.
+ // Subframes should be constrained by parents only.
+ return document()->printing() && (!tree().parent() || !tree().parent()->isLocalFrame() || !toLocalFrame(tree().parent())->document()->printing());
+}
+
+FloatSize LocalFrame::resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize)
+{
+ FloatSize resultSize;
+ if (!contentRenderer())
+ return FloatSize();
+
+ if (contentRenderer()->style()->isHorizontalWritingMode()) {
+ ASSERT(fabs(originalSize.width()) > std::numeric_limits<float>::epsilon());
+ float ratio = originalSize.height() / originalSize.width();
+ resultSize.setWidth(floorf(expectedSize.width()));
+ resultSize.setHeight(floorf(resultSize.width() * ratio));
+ } else {
+ ASSERT(fabs(originalSize.height()) > std::numeric_limits<float>::epsilon());
+ float ratio = originalSize.width() / originalSize.height();
+ resultSize.setHeight(floorf(expectedSize.height()));
+ resultSize.setWidth(floorf(resultSize.height() * ratio));
+ }
+ return resultSize;
+}
+
+void LocalFrame::setDOMWindow(PassRefPtrWillBeRawPtr<LocalDOMWindow> domWindow)
+{
+ InspectorInstrumentation::frameWindowDiscarded(this, m_domWindow.get());
+ if (domWindow)
+ script().clearWindowShell();
+ Frame::setDOMWindow(domWindow);
+}
+
+void LocalFrame::didChangeVisibilityState()
+{
+ if (document())
+ document()->didChangeVisibilityState();
+
+ Vector<RefPtr<LocalFrame> > childFrames;
+ for (Frame* child = tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ childFrames.append(toLocalFrame(child));
+ }
+
+ for (size_t i = 0; i < childFrames.size(); ++i)
+ childFrames[i]->didChangeVisibilityState();
+}
+
+void LocalFrame::willDetachFrameHost()
+{
+ // We should never be detatching the page during a Layout.
+ RELEASE_ASSERT(!m_view || !m_view->isInPerformLayout());
+
+ Frame* parent = tree().parent();
+ if (parent && parent->isLocalFrame())
+ toLocalFrame(parent)->loader().checkLoadComplete();
+
+ Frame::willDetachFrameHost();
+ script().clearScriptObjects();
+
+ if (page() && page()->scrollingCoordinator() && m_view)
+ page()->scrollingCoordinator()->willDestroyScrollableArea(m_view.get());
+}
+
+void LocalFrame::detachFromFrameHost()
+{
+ // We should never be detatching the page during a Layout.
+ RELEASE_ASSERT(!m_view || !m_view->isInPerformLayout());
+ Frame::detachFromFrameHost();
+}
+
+String LocalFrame::documentTypeString() const
+{
+ if (DocumentType* doctype = document()->doctype())
+ return createMarkup(doctype);
+
+ return String();
+}
+
+String LocalFrame::selectedText() const
+{
+ return selection().selectedText();
+}
+
+String LocalFrame::selectedTextForClipboard() const
+{
+ return selection().selectedTextForClipboard();
+}
+
+VisiblePosition LocalFrame::visiblePositionForPoint(const IntPoint& framePoint)
+{
+ HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint);
+ Node* node = result.innerNonSharedNode();
+ if (!node)
+ return VisiblePosition();
+ RenderObject* renderer = node->renderer();
+ if (!renderer)
+ return VisiblePosition();
+ VisiblePosition visiblePos = VisiblePosition(renderer->positionForPoint(result.localPoint()));
+ if (visiblePos.isNull())
+ visiblePos = VisiblePosition(firstPositionInOrBeforeNode(node));
+ return visiblePos;
+}
+
+RenderView* LocalFrame::contentRenderer() const
+{
+ return document() ? document()->renderView() : 0;
+}
+
+Document* LocalFrame::document() const
+{
+ return m_domWindow ? m_domWindow->document() : 0;
+}
+
+Document* LocalFrame::documentAtPoint(const IntPoint& point)
+{
+ if (!view())
+ return 0;
+
+ IntPoint pt = view()->windowToContents(point);
+ HitTestResult result = HitTestResult(pt);
+
+ if (contentRenderer())
+ result = eventHandler().hitTestResultAtPoint(pt, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
+ return result.innerNode() ? &result.innerNode()->document() : 0;
+}
+
+PassRefPtrWillBeRawPtr<Range> LocalFrame::rangeForPoint(const IntPoint& framePoint)
+{
+ VisiblePosition position = visiblePositionForPoint(framePoint);
+ if (position.isNull())
+ return nullptr;
+
+ VisiblePosition previous = position.previous();
+ if (previous.isNotNull()) {
+ RefPtrWillBeRawPtr<Range> previousCharacterRange = makeRange(previous, position);
+ LayoutRect rect = editor().firstRectForRange(previousCharacterRange.get());
+ if (rect.contains(framePoint))
+ return previousCharacterRange.release();
+ }
+
+ VisiblePosition next = position.next();
+ if (RefPtrWillBeRawPtr<Range> nextCharacterRange = makeRange(position, next)) {
+ LayoutRect rect = editor().firstRectForRange(nextCharacterRange.get());
+ if (rect.contains(framePoint))
+ return nextCharacterRange.release();
+ }
+
+ return nullptr;
+}
+
+void LocalFrame::createView(const IntSize& viewportSize, const Color& backgroundColor, bool transparent,
+ ScrollbarMode horizontalScrollbarMode, bool horizontalLock,
+ ScrollbarMode verticalScrollbarMode, bool verticalLock)
+{
+ ASSERT(this);
+ ASSERT(page());
+
+ bool isMainFrame = this->isMainFrame();
+
+ if (isMainFrame && view())
+ view()->setParentVisible(false);
+
+ setView(nullptr);
+
+ RefPtr<FrameView> frameView;
+ if (isMainFrame) {
+ frameView = FrameView::create(this, viewportSize);
+
+ // The layout size is set by WebViewImpl to support @viewport
+ frameView->setLayoutSizeFixedToFrameSize(false);
+ } else
+ frameView = FrameView::create(this);
+
+ frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode, horizontalLock, verticalLock);
+
+ setView(frameView);
+
+ frameView->updateBackgroundRecursively(backgroundColor, transparent);
+
+ if (isMainFrame)
+ frameView->setParentVisible(true);
+
+ // FIXME: Not clear what the right thing for OOPI is here.
+ if (ownerRenderer()) {
+ HTMLFrameOwnerElement* owner = deprecatedLocalOwner();
+ ASSERT(owner);
+ owner->setWidget(frameView);
+ }
+
+ if (HTMLFrameOwnerElement* owner = deprecatedLocalOwner())
+ view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
+}
+
+
+void LocalFrame::countObjectsNeedingLayout(unsigned& needsLayoutObjects, unsigned& totalObjects, bool& isPartial)
+{
+ RenderObject* root = view()->layoutRoot();
+ isPartial = true;
+ if (!root) {
+ isPartial = false;
+ root = contentRenderer();
+ }
+
+ needsLayoutObjects = 0;
+ totalObjects = 0;
+
+ for (RenderObject* o = root; o; o = o->nextInPreOrder(root)) {
+ ++totalObjects;
+ if (o->needsLayout())
+ ++needsLayoutObjects;
+ }
+}
+
+String LocalFrame::layerTreeAsText(LayerTreeFlags flags) const
+{
+ TextStream textStream;
+ textStream << localLayerTreeAsText(flags);
+
+ for (Frame* child = tree().firstChild(); child; child = child->tree().traverseNext(this)) {
+ if (!child->isLocalFrame())
+ continue;
+ String childLayerTree = toLocalFrame(child)->localLayerTreeAsText(flags);
+ if (!childLayerTree.length())
+ continue;
+
+ textStream << "\n\n--------\nFrame: '";
+ textStream << child->tree().uniqueName();
+ textStream << "'\n--------\n";
+ textStream << childLayerTree;
+ }
+
+ return textStream.release();
+}
+
+String LocalFrame::localLayerTreeAsText(unsigned flags) const
+{
+ if (!contentRenderer())
+ return String();
+
+ return contentRenderer()->compositor()->layerTreeAsText(static_cast<LayerTreeFlags>(flags));
+}
+
+String LocalFrame::trackedRepaintRectsAsText() const
+{
+ if (!m_view)
+ return String();
+ return m_view->trackedPaintInvalidationRectsAsText();
+}
+
+void LocalFrame::setPageZoomFactor(float factor)
+{
+ setPageAndTextZoomFactors(factor, m_textZoomFactor);
+}
+
+void LocalFrame::setTextZoomFactor(float factor)
+{
+ setPageAndTextZoomFactors(m_pageZoomFactor, factor);
+}
+
+void LocalFrame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor)
+{
+ if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
+ return;
+
+ Page* page = this->page();
+ if (!page)
+ return;
+
+ Document* document = this->document();
+ if (!document)
+ return;
+
+ // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
+ // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
+ if (document->isSVGDocument()) {
+ if (!document->accessSVGExtensions().zoomAndPanEnabled())
+ return;
+ }
+
+ if (m_pageZoomFactor != pageZoomFactor) {
+ if (FrameView* view = this->view()) {
+ // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
+ LayoutPoint scrollPosition = view->scrollPosition();
+ float percentDifference = (pageZoomFactor / m_pageZoomFactor);
+ view->setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
+ }
+ }
+
+ m_pageZoomFactor = pageZoomFactor;
+ m_textZoomFactor = textZoomFactor;
+
+ for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ toLocalFrame(child.get())->setPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor);
+ }
+
+ document->setNeedsStyleRecalc(SubtreeStyleChange);
+ document->updateLayoutIgnorePendingStylesheets();
+}
+
+void LocalFrame::deviceOrPageScaleFactorChanged()
+{
+ document()->mediaQueryAffectingValueChanged();
+ for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ toLocalFrame(child.get())->deviceOrPageScaleFactorChanged();
+ }
+}
+
+bool LocalFrame::isURLAllowed(const KURL& url) const
+{
+ // We allow one level of self-reference because some sites depend on that,
+ // but we don't allow more than one.
+ if (page()->subframeCount() >= Page::maxNumberOfFrames)
+ return false;
+ bool foundSelfReference = false;
+ for (const Frame* frame = this; frame; frame = frame->tree().parent()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (equalIgnoringFragmentIdentifier(toLocalFrame(frame)->document()->url(), url)) {
+ if (foundSelfReference)
+ return false;
+ foundSelfReference = true;
+ }
+ }
+ return true;
+}
+
+struct ScopedFramePaintingState {
+ ScopedFramePaintingState(LocalFrame* frame, Node* node)
+ : frame(frame)
+ , node(node)
+ , paintBehavior(frame->view()->paintBehavior())
+ {
+ ASSERT(!node || node->renderer());
+ if (node)
+ node->renderer()->updateDragState(true);
+ }
+
+ ~ScopedFramePaintingState()
+ {
+ if (node && node->renderer())
+ node->renderer()->updateDragState(false);
+ frame->view()->setPaintBehavior(paintBehavior);
+ frame->view()->setNodeToDraw(0);
+ }
+
+ LocalFrame* frame;
+ Node* node;
+ PaintBehavior paintBehavior;
+};
+
+PassOwnPtr<DragImage> LocalFrame::nodeImage(Node& node)
+{
+ if (!node.renderer())
+ return nullptr;
+
+ const ScopedFramePaintingState state(this, &node);
+
+ m_view->updateLayoutAndStyleForPainting();
+
+ m_view->setPaintBehavior(state.paintBehavior | PaintBehaviorFlattenCompositingLayers);
+
+ m_view->setNodeToDraw(&node); // Enable special sub-tree drawing mode.
+
+ // Document::updateLayout may have blown away the original RenderObject.
+ RenderObject* renderer = node.renderer();
+ if (!renderer)
+ return nullptr;
+
+ LayoutRect topLevelRect;
+ IntRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect));
+
+ ASSERT(document()->isActive());
+ float deviceScaleFactor = m_host->deviceScaleFactor();
+ paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
+ paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
+
+ OwnPtr<ImageBuffer> buffer = ImageBuffer::create(paintingRect.size());
+ if (!buffer)
+ return nullptr;
+ buffer->context()->scale(deviceScaleFactor, deviceScaleFactor);
+ buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
+ buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
+
+ m_view->paintContents(buffer->context(), paintingRect);
+
+ RefPtr<Image> image = buffer->copyImage();
+ return DragImage::create(image.get(), renderer->shouldRespectImageOrientation(), deviceScaleFactor);
+}
+
+PassOwnPtr<DragImage> LocalFrame::dragImageForSelection()
+{
+ if (!selection().isRange())
+ return nullptr;
+
+ const ScopedFramePaintingState state(this, 0);
+ m_view->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorFlattenCompositingLayers);
+ document()->updateLayout();
+
+ IntRect paintingRect = enclosingIntRect(selection().bounds());
+
+ ASSERT(document()->isActive());
+ float deviceScaleFactor = m_host->deviceScaleFactor();
+ paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
+ paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
+
+ OwnPtr<ImageBuffer> buffer = ImageBuffer::create(paintingRect.size());
+ if (!buffer)
+ return nullptr;
+ buffer->context()->scale(deviceScaleFactor, deviceScaleFactor);
+ buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
+ buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
+
+ m_view->paintContents(buffer->context(), paintingRect);
+
+ RefPtr<Image> image = buffer->copyImage();
+ return DragImage::create(image.get(), DoNotRespectImageOrientation, deviceScaleFactor);
+}
+
+double LocalFrame::devicePixelRatio() const
+{
+ if (!m_host)
+ return 0;
+
+ double ratio = m_host->deviceScaleFactor();
+ ratio *= pageZoomFactor();
+ return ratio;
+}
+
+void LocalFrame::disconnectOwnerElement()
+{
+ if (owner()) {
+ if (Document* doc = document())
+ doc->topDocument().clearAXObjectCache();
+ }
+ Frame::disconnectOwnerElement();
+}
+
+LocalFrame* LocalFrame::localFrameRoot()
+{
+ LocalFrame* curFrame = this;
+ while (curFrame && curFrame->tree().parent() && curFrame->tree().parent()->isLocalFrame())
+ curFrame = toLocalFrame(curFrame->tree().parent());
+
+ return curFrame;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h
new file mode 100644
index 00000000000..61c98f9b255
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/LocalFrame.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+ * 1999-2001 Lars Knoll <knoll@kde.org>
+ * 1999-2001 Antti Koivisto <koivisto@kde.org>
+ * 2000-2001 Simon Hausmann <hausmann@kde.org>
+ * 2000-2001 Dirk Mueller <mueller@kde.org>
+ * 2000 Stefan Schimanski <1Stein@gmx.de>
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LocalFrame_h
+#define LocalFrame_h
+
+#include "core/frame/Frame.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/NavigationScheduler.h"
+#include "core/page/FrameTree.h"
+#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
+#include "platform/scroll/ScrollTypes.h"
+
+namespace WebCore {
+
+ class Color;
+ class Document;
+ class DragImage;
+ class Editor;
+ class EventHandler;
+ class FetchContext;
+ class FloatSize;
+ class FrameConsole;
+ class FrameSelection;
+ class FrameView;
+ class InputMethodController;
+ class IntPoint;
+ class IntSize;
+ class Node;
+ class Range;
+ class RenderView;
+ class TreeScope;
+ class ScriptController;
+ class SpellChecker;
+ class TreeScope;
+ class VisiblePosition;
+
+ class LocalFrame : public Frame, public WillBePersistentHeapSupplementable<LocalFrame> {
+ public:
+ static PassRefPtr<LocalFrame> create(FrameLoaderClient*, FrameHost*, FrameOwner*);
+
+ virtual bool isLocalFrame() const OVERRIDE { return true; }
+
+ void init();
+ void setView(PassRefPtr<FrameView>);
+ void createView(const IntSize&, const Color&, bool,
+ ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
+ ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
+
+ virtual ~LocalFrame();
+
+ virtual void willDetachFrameHost() OVERRIDE;
+ virtual void detachFromFrameHost() OVERRIDE;
+
+ virtual void disconnectOwnerElement() OVERRIDE;
+
+ virtual void setDOMWindow(PassRefPtrWillBeRawPtr<LocalDOMWindow>) OVERRIDE;
+ FrameView* view() const;
+ Document* document() const;
+
+ RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame.
+
+ Editor& editor() const;
+ EventHandler& eventHandler() const;
+ FrameLoader& loader() const;
+ NavigationScheduler& navigationScheduler() const;
+ FrameSelection& selection() const;
+ InputMethodController& inputMethodController() const;
+ FetchContext& fetchContext() const { return loader().fetchContext(); }
+ ScriptController& script();
+ SpellChecker& spellChecker() const;
+ FrameConsole& console() const;
+
+ void didChangeVisibilityState();
+
+ // FIXME: This method is only used by EventHandler to get the highest level
+ // LocalFrame in this frame's in-process subtree. When user gesture tokens
+ // are synchronized across processes this method should be removed.
+ LocalFrame* localFrameRoot();
+
+ // ======== All public functions below this point are candidates to move out of LocalFrame into another class. ========
+
+ bool inScope(TreeScope*) const;
+
+ void countObjectsNeedingLayout(unsigned& needsLayoutObjects, unsigned& totalObjects, bool& isPartial);
+
+ // See GraphicsLayerClient.h for accepted flags.
+ String layerTreeAsText(unsigned flags = 0) const;
+ String trackedRepaintRectsAsText() const;
+
+ void setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio);
+ bool shouldUsePrintingLayout() const;
+ FloatSize resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize);
+
+ bool inViewSourceMode() const;
+ void setInViewSourceMode(bool = true);
+
+ void setPageZoomFactor(float factor);
+ float pageZoomFactor() const { return m_pageZoomFactor; }
+ void setTextZoomFactor(float factor);
+ float textZoomFactor() const { return m_textZoomFactor; }
+ void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);
+
+ void deviceOrPageScaleFactorChanged();
+ double devicePixelRatio() const;
+
+ void sendOrientationChangeEvent();
+
+ String documentTypeString() const;
+
+ PassOwnPtr<DragImage> nodeImage(Node&);
+ PassOwnPtr<DragImage> dragImageForSelection();
+
+ String selectedText() const;
+ String selectedTextForClipboard() const;
+
+ VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
+ Document* documentAtPoint(const IntPoint& windowPoint);
+ PassRefPtrWillBeRawPtr<Range> rangeForPoint(const IntPoint& framePoint);
+
+ bool isURLAllowed(const KURL&) const;
+
+ // ========
+
+ private:
+ LocalFrame(FrameLoaderClient*, FrameHost*, FrameOwner*);
+
+ String localLayerTreeAsText(unsigned flags) const;
+
+ mutable FrameLoader m_loader;
+ mutable NavigationScheduler m_navigationScheduler;
+
+ RefPtr<FrameView> m_view;
+
+ OwnPtr<ScriptController> m_script;
+ const OwnPtrWillBePersistent<Editor> m_editor;
+ const OwnPtr<SpellChecker> m_spellChecker;
+ const OwnPtrWillBePersistent<FrameSelection> m_selection;
+ const OwnPtrWillBePersistent<EventHandler> m_eventHandler;
+ const OwnPtr<FrameConsole> m_console;
+ OwnPtr<InputMethodController> m_inputMethodController;
+
+ float m_pageZoomFactor;
+ float m_textZoomFactor;
+
+ bool m_inViewSourceMode;
+ };
+
+ inline void LocalFrame::init()
+ {
+ m_loader.init();
+ }
+
+ inline FrameLoader& LocalFrame::loader() const
+ {
+ return m_loader;
+ }
+
+ inline NavigationScheduler& LocalFrame::navigationScheduler() const
+ {
+ return m_navigationScheduler;
+ }
+
+ inline FrameView* LocalFrame::view() const
+ {
+ return m_view.get();
+ }
+
+ inline ScriptController& LocalFrame::script()
+ {
+ return *m_script;
+ }
+
+ inline FrameSelection& LocalFrame::selection() const
+ {
+ return *m_selection;
+ }
+
+ inline Editor& LocalFrame::editor() const
+ {
+ return *m_editor;
+ }
+
+ inline SpellChecker& LocalFrame::spellChecker() const
+ {
+ return *m_spellChecker;
+ }
+
+ inline FrameConsole& LocalFrame::console() const
+ {
+ return *m_console;
+ }
+
+ inline InputMethodController& LocalFrame::inputMethodController() const
+ {
+ return *m_inputMethodController;
+ }
+
+ inline bool LocalFrame::inViewSourceMode() const
+ {
+ return m_inViewSourceMode;
+ }
+
+ inline void LocalFrame::setInViewSourceMode(bool mode)
+ {
+ m_inViewSourceMode = mode;
+ }
+
+ inline EventHandler& LocalFrame::eventHandler() const
+ {
+ ASSERT(m_eventHandler);
+ return *m_eventHandler;
+ }
+
+ DEFINE_TYPE_CASTS(LocalFrame, Frame, localFrame, localFrame->isLocalFrame(), localFrame.isLocalFrame());
+
+} // namespace WebCore
+
+// During refactoring, there are some places where we need to do type conversions that
+// will not be needed once all instances of LocalFrame and RemoteFrame are sorted out.
+// At that time this #define will be removed and all the uses of it will need to be corrected.
+#define toLocalFrameTemporary toLocalFrame
+
+#endif // LocalFrame_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/Location.cpp b/chromium/third_party/WebKit/Source/core/frame/Location.cpp
index e38b2fde82e..42851fd2c7c 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Location.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/Location.cpp
@@ -33,15 +33,15 @@
#include "core/dom/DOMURLUtilsReadOnly.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/FrameLoader.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace WebCore {
-Location::Location(Frame* frame)
+Location::Location(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
@@ -115,13 +115,16 @@ String Location::origin() const
return DOMURLUtilsReadOnly::origin(url());
}
-PassRefPtr<DOMStringList> Location::ancestorOrigins() const
+PassRefPtrWillBeRawPtr<DOMStringList> Location::ancestorOrigins() const
{
- RefPtr<DOMStringList> origins = DOMStringList::create();
+ RefPtrWillBeRawPtr<DOMStringList> origins = DOMStringList::create();
if (!m_frame)
return origins.release();
- for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent())
- origins->append(frame->document()->securityOrigin()->toString());
+ // FIXME: We do not yet have access to remote frame's origin.
+ for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) {
+ if (frame->isLocalFrame())
+ origins->append(toLocalFrame(frame)->document()->securityOrigin()->toString());
+ }
return origins.release();
}
@@ -133,14 +136,14 @@ String Location::hash() const
return DOMURLUtilsReadOnly::hash(url());
}
-void Location::setHref(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& url)
+void Location::setHref(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url)
{
if (!m_frame)
return;
- setLocation(url, activeWindow, firstWindow);
+ setLocation(url, callingWindow, enteredWindow);
}
-void Location::setProtocol(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& protocol, ExceptionState& exceptionState)
+void Location::setProtocol(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& protocol, ExceptionState& exceptionState)
{
if (!m_frame)
return;
@@ -149,55 +152,55 @@ void Location::setProtocol(DOMWindow* activeWindow, DOMWindow* firstWindow, cons
exceptionState.throwDOMException(SyntaxError, "'" + protocol + "' is an invalid protocol.");
return;
}
- setLocation(url.string(), activeWindow, firstWindow);
+ setLocation(url.string(), callingWindow, enteredWindow);
}
-void Location::setHost(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& host)
+void Location::setHost(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& host)
{
if (!m_frame)
return;
KURL url = m_frame->document()->url();
url.setHostAndPort(host);
- setLocation(url.string(), activeWindow, firstWindow);
+ setLocation(url.string(), callingWindow, enteredWindow);
}
-void Location::setHostname(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& hostname)
+void Location::setHostname(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& hostname)
{
if (!m_frame)
return;
KURL url = m_frame->document()->url();
url.setHost(hostname);
- setLocation(url.string(), activeWindow, firstWindow);
+ setLocation(url.string(), callingWindow, enteredWindow);
}
-void Location::setPort(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& portString)
+void Location::setPort(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& portString)
{
if (!m_frame)
return;
KURL url = m_frame->document()->url();
url.setPort(portString);
- setLocation(url.string(), activeWindow, firstWindow);
+ setLocation(url.string(), callingWindow, enteredWindow);
}
-void Location::setPathname(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& pathname)
+void Location::setPathname(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& pathname)
{
if (!m_frame)
return;
KURL url = m_frame->document()->url();
url.setPath(pathname);
- setLocation(url.string(), activeWindow, firstWindow);
+ setLocation(url.string(), callingWindow, enteredWindow);
}
-void Location::setSearch(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& search)
+void Location::setSearch(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& search)
{
if (!m_frame)
return;
KURL url = m_frame->document()->url();
url.setQuery(search);
- setLocation(url.string(), activeWindow, firstWindow);
+ setLocation(url.string(), callingWindow, enteredWindow);
}
-void Location::setHash(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& hash)
+void Location::setHash(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& hash)
{
if (!m_frame)
return;
@@ -212,25 +215,25 @@ void Location::setHash(DOMWindow* activeWindow, DOMWindow* firstWindow, const St
// cases where fragment identifiers are ignored or invalid.
if (equalIgnoringNullity(oldFragmentIdentifier, url.fragmentIdentifier()))
return;
- setLocation(url.string(), activeWindow, firstWindow);
+ setLocation(url.string(), callingWindow, enteredWindow);
}
-void Location::assign(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& url)
+void Location::assign(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url)
{
if (!m_frame)
return;
- setLocation(url, activeWindow, firstWindow);
+ setLocation(url, callingWindow, enteredWindow);
}
-void Location::replace(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& url)
+void Location::replace(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String& url)
{
if (!m_frame)
return;
- // Note: We call DOMWindow::setLocation directly here because replace() always operates on the current frame.
- m_frame->domWindow()->setLocation(url, activeWindow, firstWindow, LockHistoryAndBackForwardList);
+ // Note: We call LocalDOMWindow::setLocation directly here because replace() always operates on the current frame.
+ m_frame->domWindow()->setLocation(url, callingWindow, enteredWindow, LockHistoryAndBackForwardList);
}
-void Location::reload(DOMWindow* activeWindow)
+void Location::reload(LocalDOMWindow* callingWindow)
{
if (!m_frame)
return;
@@ -239,14 +242,13 @@ void Location::reload(DOMWindow* activeWindow)
m_frame->navigationScheduler().scheduleRefresh();
}
-void Location::setLocation(const String& url, DOMWindow* activeWindow, DOMWindow* firstWindow)
+void Location::setLocation(const String& url, LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow)
{
ASSERT(m_frame);
- // We call findFrameForNavigation to handle the case of a seamless iframe correctly.
- Frame* frame = m_frame->loader().findFrameForNavigation(String(), activeWindow->document());
+ LocalFrame* frame = m_frame->loader().findFrameForNavigation(nullAtom, callingWindow->document());
if (!frame)
return;
- frame->domWindow()->setLocation(url, activeWindow, firstWindow);
+ frame->domWindow()->setLocation(url, callingWindow, enteredWindow);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/Location.h b/chromium/third_party/WebKit/Source/core/frame/Location.h
index 50b4b23cd87..d029b9727d0 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Location.h
+++ b/chromium/third_party/WebKit/Source/core/frame/Location.h
@@ -38,44 +38,49 @@
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class ExceptionState;
-class Frame;
+class LocalFrame;
class KURL;
-class Location : public ScriptWrappable, public RefCounted<Location>, public DOMWindowProperty {
+class Location FINAL : public RefCountedWillBeGarbageCollectedFinalized<Location>, public ScriptWrappable, public DOMWindowProperty {
public:
- static PassRefPtr<Location> create(Frame* frame) { return adoptRef(new Location(frame)); }
+ static PassRefPtrWillBeRawPtr<Location> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new Location(frame));
+ }
- void setHref(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+ void setHref(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
String href() const;
- void assign(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
- void replace(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
- void reload(DOMWindow* activeWindow);
+ void assign(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
+ void replace(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
+ void reload(LocalDOMWindow* callingWindow);
- void setProtocol(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&, ExceptionState&);
+ void setProtocol(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&, ExceptionState&);
String protocol() const;
- void setHost(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+ void setHost(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
String host() const;
- void setHostname(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+ void setHostname(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
String hostname() const;
- void setPort(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+ void setPort(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
String port() const;
- void setPathname(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+ void setPathname(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
String pathname() const;
- void setSearch(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+ void setSearch(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
String search() const;
- void setHash(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+ void setHash(LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow, const String&);
String hash() const;
String origin() const;
- PassRefPtr<DOMStringList> ancestorOrigins() const;
+ PassRefPtrWillBeRawPtr<DOMStringList> ancestorOrigins() const;
+
+ void trace(Visitor*) { }
private:
- explicit Location(Frame*);
+ explicit Location(LocalFrame*);
- void setLocation(const String&, DOMWindow* activeWindow, DOMWindow* firstWindow);
+ void setLocation(const String&, LocalDOMWindow* callingWindow, LocalDOMWindow* enteredWindow);
const KURL& url() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/Location.idl b/chromium/third_party/WebKit/Source/core/frame/Location.idl
index 5ce29901ece..88aa1b79638 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Location.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/Location.idl
@@ -28,6 +28,7 @@
[
CheckSecurity=Frame,
+ WillBeGarbageCollected,
] interface Location {
// |assign|, |replace|, and *writing* |href| do not require a security
// check, as they *change* the page, and thus these do not change any
@@ -36,8 +37,8 @@
// problem, since that allows tracking navigation.
[SetterCallWith=ActiveWindow&FirstWindow, DoNotCheckSecurity=Setter, Unforgeable] attribute DOMString href;
- [CallWith=ActiveWindow&FirstWindow, DoNotCheckSecurity, Unforgeable, ReadOnly, PerWorldBindings, ActivityLogging=ForIsolatedWorlds] void assign(DOMString url);
- [CallWith=ActiveWindow&FirstWindow, DoNotCheckSecurity, Unforgeable, ReadOnly, PerWorldBindings, ActivityLogging=ForIsolatedWorlds] void replace(DOMString url);
+ [CallWith=ActiveWindow&FirstWindow, DoNotCheckSecurity, Unforgeable, ReadOnly, LogActivity] void assign(DOMString url);
+ [CallWith=ActiveWindow&FirstWindow, DoNotCheckSecurity, Unforgeable, ReadOnly, LogActivity] void replace(DOMString url);
[CallWith=ActiveWindow, Unforgeable, ReadOnly] void reload();
// URI decomposition attributes
diff --git a/chromium/third_party/WebKit/Source/core/frame/Navigator.cpp b/chromium/third_party/WebKit/Source/core/frame/Navigator.cpp
index 37b0b6f4121..08059baa407 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Navigator.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/Navigator.cpp
@@ -25,11 +25,14 @@
#include "bindings/v8/ScriptController.h"
#include "core/dom/Document.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/NavigatorID.h"
+#include "core/frame/Settings.h"
#include "core/loader/CookieJar.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
#include "core/plugins/DOMMimeTypeArray.h"
#include "core/plugins/DOMPluginArray.h"
#include "platform/Language.h"
@@ -48,7 +51,7 @@
namespace WebCore {
-Navigator::Navigator(Frame* frame)
+Navigator::Navigator(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
@@ -58,38 +61,6 @@ Navigator::~Navigator()
{
}
-// If this function returns true, we need to hide the substring "4." that would otherwise
-// appear in the appVersion string. This is to avoid problems with old versions of a
-// library called OpenCube QuickMenu, which as of this writing is still being used on
-// sites such as nwa.com -- the library thinks Safari is Netscape 4 if we don't do this!
-static bool shouldHideFourDot(Frame* frame)
-{
- const String* sourceURL = frame->script().sourceURL();
- if (!sourceURL)
- return false;
- if (!(sourceURL->endsWith("/dqm_script.js") || sourceURL->endsWith("/dqm_loader.js") || sourceURL->endsWith("/tdqm_loader.js")))
- return false;
- Settings* settings = frame->settings();
- if (!settings)
- return false;
- return settings->needsSiteSpecificQuirks();
-}
-
-String Navigator::appVersion() const
-{
- if (!m_frame)
- return String();
- String appVersion = NavigatorID::appVersion(this);
- if (shouldHideFourDot(m_frame))
- appVersion.replace("4.", "4_");
- return appVersion;
-}
-
-String Navigator::language() const
-{
- return defaultLanguage();
-}
-
String Navigator::productSub() const
{
return WEBCORE_NAVIGATOR_PRODUCT_SUB;
@@ -156,4 +127,36 @@ void Navigator::getStorageUpdates()
// FIXME: Remove this method or rename to yieldForStorageUpdates.
}
+Vector<String> Navigator::languages()
+{
+ Vector<String> languages;
+
+ if (!m_frame || !m_frame->host()) {
+ languages.append(defaultLanguage());
+ return languages;
+ }
+
+ String acceptLanguages = m_frame->host()->chrome().client().acceptLanguages();
+ acceptLanguages.split(",", languages);
+
+ // Sanitizing tokens. We could do that more extensively but we should assume
+ // that the accept languages are already sane and support BCP47. It is
+ // likely a waste of time to make sure the tokens matches that spec here.
+ for (size_t i = 0; i < languages.size(); ++i) {
+ String& token = languages[i];
+ token = token.stripWhiteSpace();
+ if (token.length() >= 3 && token[2] == '_')
+ token.replace(2, 1, "-");
+ }
+
+ return languages;
+}
+
+void Navigator::trace(Visitor* visitor)
+{
+ visitor->trace(m_plugins);
+ visitor->trace(m_mimeTypes);
+ WillBeHeapSupplementable<Navigator>::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/Navigator.h b/chromium/third_party/WebKit/Source/core/frame/Navigator.h
index 0f289b3910e..44f8038d0b9 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Navigator.h
+++ b/chromium/third_party/WebKit/Source/core/frame/Navigator.h
@@ -22,8 +22,12 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/DOMWindowProperty.h"
-#include "core/frame/NavigatorBase.h"
+#include "core/frame/NavigatorCPU.h"
+#include "core/frame/NavigatorID.h"
+#include "core/frame/NavigatorLanguage.h"
+#include "core/frame/NavigatorOnLine.h"
#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -33,18 +37,29 @@ namespace WebCore {
class DOMMimeTypeArray;
class DOMPluginArray;
-class Frame;
+class LocalFrame;
class PluginData;
typedef int ExceptionCode;
-class Navigator : public NavigatorBase, public ScriptWrappable, public RefCounted<Navigator>, public DOMWindowProperty, public Supplementable<Navigator> {
+class Navigator FINAL
+ : public RefCountedWillBeGarbageCollectedFinalized<Navigator>
+ , public NavigatorCPU
+ , public NavigatorID
+ , public NavigatorLanguage
+ , public NavigatorOnLine
+ , public ScriptWrappable
+ , public DOMWindowProperty
+ , public WillBeHeapSupplementable<Navigator> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Navigator);
public:
- static PassRefPtr<Navigator> create(Frame* frame) { return adoptRef(new Navigator(frame)); }
+ static PassRefPtrWillBeRawPtr<Navigator> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new Navigator(frame));
+ }
+
virtual ~Navigator();
- String appVersion() const;
- String language() const;
DOMPluginArray* plugins() const;
DOMMimeTypeArray* mimeTypes() const;
bool cookieEnabled() const;
@@ -59,11 +74,16 @@ public:
// Relinquishes the storage lock, if one exists.
void getStorageUpdates();
+ // NavigatorLanguage
+ virtual Vector<String> languages() OVERRIDE;
+
+ virtual void trace(Visitor*);
+
private:
- explicit Navigator(Frame*);
+ explicit Navigator(LocalFrame*);
- mutable RefPtr<DOMPluginArray> m_plugins;
- mutable RefPtr<DOMMimeTypeArray> m_mimeTypes;
+ mutable RefPtrWillBeMember<DOMPluginArray> m_plugins;
+ mutable RefPtrWillBeMember<DOMMimeTypeArray> m_mimeTypes;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/Navigator.idl b/chromium/third_party/WebKit/Source/core/frame/Navigator.idl
index 546e3e0f809..07fb6a2f08b 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Navigator.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/Navigator.idl
@@ -17,12 +17,16 @@
Boston, MA 02110-1301, USA.
*/
-interface Navigator {
- readonly attribute DOMString language;
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#navigator
+
+[
+ WillBeGarbageCollected,
+] interface Navigator {
+ // FIXME: move these 3 to NavigatorPlugins
readonly attribute PluginArray plugins;
readonly attribute MimeTypeArray mimeTypes;
- readonly attribute boolean cookieEnabled;
boolean javaEnabled();
+ readonly attribute boolean cookieEnabled; // FIXME: move to NavigatorStorageUtils
void getStorageUpdates(); // FIXME: Remove this method or rename to yieldForStorageUpdates.
@@ -32,5 +36,7 @@ interface Navigator {
[MeasureAs=NavigatorVendorSub] readonly attribute DOMString vendorSub;
};
+Navigator implements NavigatorCPU;
Navigator implements NavigatorID;
+Navigator implements NavigatorLanguage;
Navigator implements NavigatorOnLine;
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorBase.h b/chromium/third_party/WebKit/Source/core/frame/NavigatorBase.h
deleted file mode 100644
index 38ae2660553..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/NavigatorBase.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef NavigatorBase_h
-#define NavigatorBase_h
-
-#include "wtf/Forward.h"
-
-namespace WebCore {
-
-class NavigatorBase {
-public:
- virtual String userAgent() const = 0;
-
-protected:
- virtual ~NavigatorBase() { }
-};
-
-} // namespace WebCore
-
-#endif // NavigatorBase_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.cpp b/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.cpp
new file mode 100644
index 00000000000..a5bee3d1fc7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.cpp
@@ -0,0 +1,17 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/NavigatorCPU.h"
+
+#include "public/platform/Platform.h"
+
+namespace WebCore {
+
+unsigned NavigatorCPU::hardwareConcurrency() const
+{
+ return blink::Platform::current()->numberOfProcessors();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.h b/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.h
new file mode 100644
index 00000000000..1bf35d9e463
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.h
@@ -0,0 +1,17 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NavigatorCPU_h
+#define NavigatorCPU_h
+
+namespace WebCore {
+
+class NavigatorCPU {
+public:
+ unsigned hardwareConcurrency() const;
+};
+
+} // namespace WebCore
+
+#endif // NavigatorCPU_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.idl b/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.idl
new file mode 100644
index 00000000000..8ec502c58fc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorCPU.idl
@@ -0,0 +1,9 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ NoInterfaceObject,
+] interface NavigatorCPU {
+ readonly attribute unsigned long hardwareConcurrency;
+};
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorID.cpp b/chromium/third_party/WebKit/Source/core/frame/NavigatorID.cpp
index 1b771dd1488..f3c04fdbcd0 100644
--- a/chromium/third_party/WebKit/Source/core/frame/NavigatorID.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorID.cpp
@@ -30,9 +30,7 @@
*/
#include "config.h"
-#include "NavigatorID.h"
-
-#include "core/frame/NavigatorBase.h"
+#include "core/frame/NavigatorID.h"
#if !defined(WEBCORE_NAVIGATOR_PLATFORM) && OS(POSIX) && !OS(MACOSX)
#include "wtf/StdLibExtras.h"
@@ -45,24 +43,24 @@
namespace WebCore {
-String NavigatorID::appName(const NavigatorBase*)
+String NavigatorID::appCodeName()
{
- return "Netscape";
+ return "Mozilla";
}
-String NavigatorID::appVersion(const NavigatorBase* navigator)
+String NavigatorID::appName()
{
- // Version is everything in the user agent string past the "Mozilla/" prefix.
- const String& agent = navigator->userAgent();
- return agent.substring(agent.find('/') + 1);
+ return "Netscape";
}
-String NavigatorID::userAgent(const NavigatorBase* navigator)
+String NavigatorID::appVersion()
{
- return navigator->userAgent();
+ // Version is everything in the user agent string past the "Mozilla/" prefix.
+ const String& agent = userAgent();
+ return agent.substring(agent.find('/') + 1);
}
-String NavigatorID::platform(const NavigatorBase*)
+String NavigatorID::platform()
{
#if defined(WEBCORE_NAVIGATOR_PLATFORM)
return WEBCORE_NAVIGATOR_PLATFORM;
@@ -79,12 +77,7 @@ String NavigatorID::platform(const NavigatorBase*)
#endif
}
-String NavigatorID::appCodeName(const NavigatorBase*)
-{
- return "Mozilla";
-}
-
-String NavigatorID::product(const NavigatorBase*)
+String NavigatorID::product()
{
return WEBCORE_NAVIGATOR_PRODUCT;
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorID.h b/chromium/third_party/WebKit/Source/core/frame/NavigatorID.h
index 9e31d3100ee..fa383d6d732 100644
--- a/chromium/third_party/WebKit/Source/core/frame/NavigatorID.h
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorID.h
@@ -35,16 +35,14 @@
namespace WebCore {
-class NavigatorBase;
-
class NavigatorID {
public:
- static String appName(const NavigatorBase*);
- static String appVersion(const NavigatorBase*);
- static String userAgent(const NavigatorBase*);
- static String platform(const NavigatorBase*);
- static String appCodeName(const NavigatorBase*);
- static String product(const NavigatorBase*);
+ String appCodeName();
+ String appName();
+ String appVersion();
+ String platform();
+ String product();
+ virtual String userAgent() const = 0;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorID.idl b/chromium/third_party/WebKit/Source/core/frame/NavigatorID.idl
index c581ad98bf2..a23bcb12a76 100644
--- a/chromium/third_party/WebKit/Source/core/frame/NavigatorID.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorID.idl
@@ -28,13 +28,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/#navigatorid
+
[
- NoInterfaceObject
+ NoInterfaceObject, // Always used on target of 'implements'
] interface NavigatorID {
+ readonly attribute DOMString appCodeName; // constant "Mozilla"
readonly attribute DOMString appName;
readonly attribute DOMString appVersion;
readonly attribute DOMString platform;
+ readonly attribute DOMString product; // constant "Gecko"
readonly attribute DOMString userAgent;
- readonly attribute DOMString appCodeName;
- readonly attribute DOMString product;
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.cpp b/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.cpp
new file mode 100644
index 00000000000..ad520541539
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.cpp
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/NavigatorLanguage.h"
+
+#include "platform/Language.h"
+
+namespace WebCore {
+
+NavigatorLanguage::NavigatorLanguage()
+ : m_languagesChanged(true)
+{
+}
+
+AtomicString NavigatorLanguage::language(bool& isNull)
+{
+ isNull = false;
+ return defaultLanguage();
+}
+
+bool NavigatorLanguage::hasLanguagesChanged()
+{
+ if (!m_languagesChanged)
+ return false;
+
+ m_languagesChanged = false;
+ return true;
+}
+
+void NavigatorLanguage::setLanguagesChanged()
+{
+ m_languagesChanged = true;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.h b/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.h
new file mode 100644
index 00000000000..71515fe7f00
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.h
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NavigatorLanguage_h
+#define NavigatorLanguage_h
+
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class NavigatorLanguage {
+public:
+ NavigatorLanguage();
+
+ AtomicString language(bool&);
+ virtual Vector<String> languages() = 0;
+ bool hasLanguagesChanged();
+ void setLanguagesChanged();
+
+private:
+ bool m_languagesChanged;
+};
+
+} // namespace WebCore
+
+#endif // NavigatorLanguage_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.idl b/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.idl
new file mode 100644
index 00000000000..fe689f6c0d7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorLanguage.idl
@@ -0,0 +1,10 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ NoInterfaceObject,
+] interface NavigatorLanguage {
+ readonly attribute DOMString? language;
+ [CachedAttribute=hasLanguagesChanged] readonly attribute DOMString[] languages;
+};
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.h b/chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.h
index 5ae204d437c..5a99e84cbb4 100644
--- a/chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.h
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.h
@@ -37,7 +37,7 @@ namespace WebCore {
class NavigatorOnLine {
public:
- static bool onLine(void*)
+ bool onLine()
{
return networkStateNotifier().onLine();
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.idl b/chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.idl
index db4b08c1e0f..9268e63c126 100644
--- a/chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/NavigatorOnLine.idl
@@ -28,8 +28,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/#navigatoronline
+
[
- NoInterfaceObject
+ NoInterfaceObject, // Always used on target of 'implements'
] interface NavigatorOnLine {
readonly attribute boolean onLine;
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/PRESUBMIT.py b/chromium/third_party/WebKit/Source/core/frame/PRESUBMIT.py
new file mode 100644
index 00000000000..eba4c2f6642
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/PRESUBMIT.py
@@ -0,0 +1,57 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Blink frame presubmit script
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into gcl.
+"""
+
+
+def _RunUseCounterChecks(input_api, output_api):
+ for f in input_api.AffectedFiles():
+ if f.LocalPath().endswith('UseCounter.cpp'):
+ useCounterCpp = f
+ break
+ else:
+ return []
+
+ largestFoundBucket = 0
+ maximumBucket = 0
+ # Looking for a line like "case CSSPropertyGrid: return 453;"
+ bucketFinder = input_api.re.compile(r'.*CSSProperty.*return\s*([0-9]+).*')
+ # Looking for a line like "static int maximumCSSSampleId() { return 452; }"
+ maximumFinder = input_api.re.compile(
+ r'static int maximumCSSSampleId\(\) { return ([0-9]+)')
+ for line in useCounterCpp.NewContents():
+ bucketMatch = bucketFinder.match(line)
+ if bucketMatch:
+ bucket = int(bucketMatch.group(1))
+ largestFoundBucket = max(largestFoundBucket, bucket)
+ else:
+ maximumMatch = maximumFinder.match(line)
+ if maximumMatch:
+ maximumBucket = int(maximumMatch.group(1))
+
+ if largestFoundBucket != maximumBucket:
+ if input_api.is_committing:
+ message_type = output_api.PresubmitError
+ else:
+ message_type = output_api.PresubmitPromptWarning
+
+ return [message_type(
+ 'Largest found CSSProperty bucket Id (%d) does not match '
+ 'maximumCSSSampleId (%d)' %
+ (largestFoundBucket, maximumBucket),
+ items=[useCounterCpp.LocalPath()])]
+
+ return []
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ return _RunUseCounterChecks(input_api, output_api)
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ return _RunUseCounterChecks(input_api, output_api)
diff --git a/chromium/third_party/WebKit/Source/core/frame/PinchViewport.cpp b/chromium/third_party/WebKit/Source/core/frame/PinchViewport.cpp
new file mode 100644
index 00000000000..09947a9b41d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/PinchViewport.cpp
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/frame/PinchViewport.h"
+
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "platform/TraceEvent.h"
+#include "platform/geometry/FloatSize.h"
+#include "platform/graphics/GraphicsLayer.h"
+#include "platform/graphics/GraphicsLayerFactory.h"
+#include "platform/scroll/Scrollbar.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebCompositorSupport.h"
+#include "public/platform/WebLayer.h"
+#include "public/platform/WebLayerTreeView.h"
+#include "public/platform/WebScrollbar.h"
+#include "public/platform/WebScrollbarLayer.h"
+
+using blink::WebLayer;
+using blink::WebLayerTreeView;
+using blink::WebScrollbar;
+using blink::WebScrollbarLayer;
+using WebCore::FrameHost;
+using WebCore::GraphicsLayer;
+using WebCore::GraphicsLayerFactory;
+
+namespace WebCore {
+
+PinchViewport::PinchViewport(FrameHost& owner)
+ : m_frameHost(owner)
+ , m_scale(1)
+{
+ reset();
+}
+
+PinchViewport::~PinchViewport() { }
+
+void PinchViewport::setSize(const IntSize& size)
+{
+ if (m_size == size)
+ return;
+
+ TRACE_EVENT2("webkit", "PinchViewport::setSize", "width", size.width(), "height", size.height());
+ m_size = size;
+
+ // Make sure we clamp the offset to within the new bounds.
+ setLocation(m_offset);
+
+ if (m_innerViewportContainerLayer) {
+ m_innerViewportContainerLayer->setSize(m_size);
+
+ // Need to re-compute sizes for the overlay scrollbars.
+ setupScrollbar(WebScrollbar::Horizontal);
+ setupScrollbar(WebScrollbar::Vertical);
+ }
+}
+
+void PinchViewport::reset()
+{
+ setLocation(FloatPoint());
+ setScale(1);
+}
+
+void PinchViewport::mainFrameDidChangeSize()
+{
+ TRACE_EVENT0("webkit", "PinchViewport::mainFrameDidChangeSize");
+
+ // In unit tests we may not have initialized the layer tree.
+ if (m_innerViewportScrollLayer)
+ m_innerViewportScrollLayer->setSize(contentsSize());
+
+ // Make sure the viewport's offset is clamped within the newly sized main frame.
+ setLocation(m_offset);
+}
+
+FloatRect PinchViewport::visibleRect() const
+{
+ FloatSize scaledSize(m_size);
+ scaledSize.scale(1 / m_scale);
+ return FloatRect(m_offset, scaledSize);
+}
+
+FloatRect PinchViewport::visibleRectInDocument() const
+{
+ if (!mainFrame() || !mainFrame()->view())
+ return FloatRect();
+
+ FloatRect viewRect = mainFrame()->view()->visibleContentRect();
+ FloatRect pinchRect = visibleRect();
+ pinchRect.moveBy(viewRect.location());
+ return pinchRect;
+}
+
+void PinchViewport::scrollIntoView(const FloatRect& rect)
+{
+ if (!mainFrame() || !mainFrame()->view())
+ return;
+
+ FrameView* view = mainFrame()->view();
+
+ float centeringOffsetX = (visibleRect().width() - rect.width()) / 2;
+ float centeringOffsetY = (visibleRect().height() - rect.height()) / 2;
+
+ FloatPoint targetOffset(
+ rect.x() - centeringOffsetX - visibleRect().x(),
+ rect.y() - centeringOffsetY - visibleRect().y());
+
+ view->setScrollPosition(flooredIntPoint(targetOffset));
+
+ FloatPoint remainder = FloatPoint(targetOffset - view->scrollPosition());
+ move(remainder);
+}
+
+void PinchViewport::setLocation(const FloatPoint& newLocation)
+{
+ FloatPoint clampedOffset(clampOffsetToBoundaries(newLocation));
+
+ if (clampedOffset == m_offset)
+ return;
+
+ m_offset = clampedOffset;
+
+ ScrollingCoordinator* coordinator = m_frameHost.page().scrollingCoordinator();
+ ASSERT(coordinator);
+ coordinator->scrollableAreaScrollLayerDidChange(this);
+
+ mainFrame()->loader().saveScrollState();
+}
+
+void PinchViewport::move(const FloatPoint& delta)
+{
+ setLocation(m_offset + delta);
+}
+
+void PinchViewport::setScale(float scale)
+{
+ if (scale == m_scale)
+ return;
+
+ m_scale = scale;
+
+ if (mainFrame())
+ mainFrame()->loader().saveScrollState();
+
+ // Old-style pinch sets scale here but we shouldn't call into the
+ // clamping code below.
+ if (!m_innerViewportScrollLayer)
+ return;
+
+ // Ensure we clamp so we remain within the bounds.
+ setLocation(visibleRect().location());
+
+ // TODO: We should probably be calling scaleDidChange type functions here.
+ // see Page::setPageScaleFactor.
+}
+
+// Modifies the top of the graphics layer tree to add layers needed to support
+// the inner/outer viewport fixed-position model for pinch zoom. When finished,
+// the tree will look like this (with * denoting added layers):
+//
+// *rootTransformLayer
+// +- *innerViewportContainerLayer (fixed pos container)
+// +- *pageScaleLayer
+// | +- *innerViewportScrollLayer
+// | +-- overflowControlsHostLayer (root layer)
+// | +-- outerViewportContainerLayer (fixed pos container) [frame container layer in RenderLayerCompositor]
+// | | +-- outerViewportScrollLayer [frame scroll layer in RenderLayerCompositor]
+// | | +-- content layers ...
+// | +-- horizontal ScrollbarLayer (non-overlay)
+// | +-- verticalScrollbarLayer (non-overlay)
+// | +-- scroll corner (non-overlay)
+// +- *horizontalScrollbarLayer (overlay)
+// +- *verticalScrollbarLayer (overlay)
+//
+void PinchViewport::attachToLayerTree(GraphicsLayer* currentLayerTreeRoot, GraphicsLayerFactory* graphicsLayerFactory)
+{
+ TRACE_EVENT1("webkit", "PinchViewport::attachToLayerTree", "currentLayerTreeRoot", (bool)currentLayerTreeRoot);
+ if (!currentLayerTreeRoot) {
+ m_innerViewportScrollLayer->removeAllChildren();
+ return;
+ }
+
+ if (currentLayerTreeRoot->parent() && currentLayerTreeRoot->parent() == m_innerViewportScrollLayer)
+ return;
+
+ if (!m_innerViewportScrollLayer) {
+ ASSERT(!m_overlayScrollbarHorizontal
+ && !m_overlayScrollbarVertical
+ && !m_pageScaleLayer
+ && !m_innerViewportContainerLayer);
+
+ // FIXME: The root transform layer should only be created on demand.
+ m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+ m_innerViewportContainerLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+ m_pageScaleLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+ m_innerViewportScrollLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+ m_overlayScrollbarHorizontal = GraphicsLayer::create(graphicsLayerFactory, this);
+ m_overlayScrollbarVertical = GraphicsLayer::create(graphicsLayerFactory, this);
+
+ WebCore::ScrollingCoordinator* coordinator = m_frameHost.page().scrollingCoordinator();
+ ASSERT(coordinator);
+ coordinator->setLayerIsContainerForFixedPositionLayers(m_innerViewportScrollLayer.get(), true);
+
+ // Set masks to bounds so the compositor doesn't clobber a manually
+ // set inner viewport container layer size.
+ m_innerViewportContainerLayer->setMasksToBounds(m_frameHost.settings().mainFrameClipsContent());
+ m_innerViewportContainerLayer->setSize(m_size);
+
+ m_innerViewportScrollLayer->platformLayer()->setScrollClipLayer(
+ m_innerViewportContainerLayer->platformLayer());
+ m_innerViewportScrollLayer->platformLayer()->setUserScrollable(true, true);
+
+ m_rootTransformLayer->addChild(m_innerViewportContainerLayer.get());
+ m_innerViewportContainerLayer->addChild(m_pageScaleLayer.get());
+ m_pageScaleLayer->addChild(m_innerViewportScrollLayer.get());
+ m_innerViewportContainerLayer->addChild(m_overlayScrollbarHorizontal.get());
+ m_innerViewportContainerLayer->addChild(m_overlayScrollbarVertical.get());
+
+ // Ensure this class is set as the scroll layer's ScrollableArea.
+ coordinator->scrollableAreaScrollLayerDidChange(this);
+
+ // Setup the inner viewport overlay scrollbars.
+ setupScrollbar(WebScrollbar::Horizontal);
+ setupScrollbar(WebScrollbar::Vertical);
+ }
+
+ m_innerViewportScrollLayer->removeAllChildren();
+ m_innerViewportScrollLayer->addChild(currentLayerTreeRoot);
+
+ // We only need to disable the existing (outer viewport) scrollbars
+ // if the existing ones are already overlay.
+ // FIXME: If we knew in advance before the overflowControlsHostLayer goes
+ // away, we would re-enable the drawing of these scrollbars.
+ // FIXME: This doesn't seem to work (at least on Android). Commenting out for now until
+ // I figure out how to access RenderLayerCompositor from here.
+ // if (GraphicsLayer* scrollbar = m_frameHost->compositor()->layerForHorizontalScrollbar())
+ // scrollbar->setDrawsContent(!page->mainFrame()->view()->hasOverlayScrollbars());
+ // if (GraphicsLayer* scrollbar = m_frameHost->compositor()->layerForVerticalScrollbar())
+ // scrollbar->setDrawsContent(!page->mainFrame()->view()->hasOverlayScrollbars());
+}
+
+void PinchViewport::setupScrollbar(WebScrollbar::Orientation orientation)
+{
+ bool isHorizontal = orientation == WebScrollbar::Horizontal;
+ GraphicsLayer* scrollbarGraphicsLayer = isHorizontal ?
+ m_overlayScrollbarHorizontal.get() : m_overlayScrollbarVertical.get();
+ OwnPtr<WebScrollbarLayer>& webScrollbarLayer = isHorizontal ?
+ m_webOverlayScrollbarHorizontal : m_webOverlayScrollbarVertical;
+
+ const int overlayScrollbarThickness = m_frameHost.settings().pinchOverlayScrollbarThickness();
+
+ if (!webScrollbarLayer) {
+ ScrollingCoordinator* coordinator = m_frameHost.page().scrollingCoordinator();
+ ASSERT(coordinator);
+ ScrollbarOrientation webcoreOrientation = isHorizontal ? HorizontalScrollbar : VerticalScrollbar;
+ webScrollbarLayer = coordinator->createSolidColorScrollbarLayer(webcoreOrientation, overlayScrollbarThickness, 0, false);
+
+ webScrollbarLayer->setClipLayer(m_innerViewportContainerLayer->platformLayer());
+ scrollbarGraphicsLayer->setContentsToPlatformLayer(webScrollbarLayer->layer());
+ scrollbarGraphicsLayer->setDrawsContent(false);
+ }
+
+ int xPosition = isHorizontal ? 0 : m_innerViewportContainerLayer->size().width() - overlayScrollbarThickness;
+ int yPosition = isHorizontal ? m_innerViewportContainerLayer->size().height() - overlayScrollbarThickness : 0;
+ int width = isHorizontal ? m_innerViewportContainerLayer->size().width() - overlayScrollbarThickness : overlayScrollbarThickness;
+ int height = isHorizontal ? overlayScrollbarThickness : m_innerViewportContainerLayer->size().height() - overlayScrollbarThickness;
+
+ // Use the GraphicsLayer to position the scrollbars.
+ scrollbarGraphicsLayer->setPosition(IntPoint(xPosition, yPosition));
+ scrollbarGraphicsLayer->setSize(IntSize(width, height));
+ scrollbarGraphicsLayer->setContentsRect(IntRect(0, 0, width, height));
+}
+
+void PinchViewport::registerLayersWithTreeView(WebLayerTreeView* layerTreeView) const
+{
+ TRACE_EVENT0("webkit", "PinchViewport::registerLayersWithTreeView");
+ ASSERT(layerTreeView);
+ ASSERT(m_frameHost.page().mainFrame());
+ ASSERT(m_frameHost.page().mainFrame()->isLocalFrame());
+ ASSERT(m_frameHost.page().deprecatedLocalMainFrame()->contentRenderer());
+
+ RenderLayerCompositor* compositor = m_frameHost.page().deprecatedLocalMainFrame()->contentRenderer()->compositor();
+ // Get the outer viewport scroll layer.
+ WebLayer* scrollLayer = compositor->scrollLayer()->platformLayer();
+
+ m_webOverlayScrollbarHorizontal->setScrollLayer(scrollLayer);
+ m_webOverlayScrollbarVertical->setScrollLayer(scrollLayer);
+
+ ASSERT(compositor);
+ layerTreeView->registerViewportLayers(
+ m_pageScaleLayer->platformLayer(),
+ m_innerViewportScrollLayer->platformLayer(),
+ scrollLayer);
+}
+
+void PinchViewport::clearLayersForTreeView(WebLayerTreeView* layerTreeView) const
+{
+ ASSERT(layerTreeView);
+
+ layerTreeView->clearViewportLayers();
+}
+
+int PinchViewport::scrollSize(ScrollbarOrientation orientation) const
+{
+ IntSize scrollDimensions = maximumScrollPosition() - minimumScrollPosition();
+ return (orientation == HorizontalScrollbar) ? scrollDimensions.width() : scrollDimensions.height();
+}
+
+IntPoint PinchViewport::minimumScrollPosition() const
+{
+ return IntPoint();
+}
+
+IntPoint PinchViewport::maximumScrollPosition() const
+{
+ return flooredIntPoint(FloatSize(contentsSize()) - visibleRect().size());
+}
+
+IntRect PinchViewport::scrollableAreaBoundingBox() const
+{
+ // This method should return the bounding box in the parent view's coordinate
+ // space; however, PinchViewport technically isn't a child of any Frames.
+ // Nonetheless, the PinchViewport always occupies the entire main frame so just
+ // return that.
+ LocalFrame* frame = mainFrame();
+
+ if (!frame || !frame->view())
+ return IntRect();
+
+ return frame->view()->frameRect();
+}
+
+IntSize PinchViewport::contentsSize() const
+{
+ LocalFrame* frame = mainFrame();
+
+ if (!frame || !frame->view())
+ return IntSize();
+
+ ASSERT(frame->view()->visibleContentScaleFactor() == 1);
+ return frame->view()->visibleContentRect(IncludeScrollbars).size();
+}
+
+void PinchViewport::invalidateScrollbarRect(Scrollbar*, const IntRect&)
+{
+ // Do nothing. Pinch scrollbars live on the compositor thread and will
+ // be updated when the viewport is synced to the CC.
+}
+
+void PinchViewport::setScrollOffset(const IntPoint& offset)
+{
+ setLocation(offset);
+}
+
+GraphicsLayer* PinchViewport::layerForContainer() const
+{
+ return m_innerViewportContainerLayer.get();
+}
+
+GraphicsLayer* PinchViewport::layerForScrolling() const
+{
+ return m_innerViewportScrollLayer.get();
+}
+
+GraphicsLayer* PinchViewport::layerForHorizontalScrollbar() const
+{
+ return m_overlayScrollbarHorizontal.get();
+}
+
+GraphicsLayer* PinchViewport::layerForVerticalScrollbar() const
+{
+ return m_overlayScrollbarVertical.get();
+}
+
+void PinchViewport::notifyAnimationStarted(const GraphicsLayer*, double monotonicTime)
+{
+}
+
+void PinchViewport::paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip)
+{
+}
+
+LocalFrame* PinchViewport::mainFrame() const
+{
+ return m_frameHost.page().mainFrame() && m_frameHost.page().mainFrame()->isLocalFrame() ? m_frameHost.page().deprecatedLocalMainFrame() : 0;
+}
+
+FloatPoint PinchViewport::clampOffsetToBoundaries(const FloatPoint& offset)
+{
+ FloatPoint clampedOffset(offset);
+ clampedOffset = clampedOffset.shrunkTo(FloatPoint(maximumScrollPosition()));
+ clampedOffset = clampedOffset.expandedTo(FloatPoint(minimumScrollPosition()));
+ return clampedOffset;
+}
+
+String PinchViewport::debugName(const GraphicsLayer* graphicsLayer)
+{
+ String name;
+ if (graphicsLayer == m_innerViewportContainerLayer.get()) {
+ name = "Inner Viewport Container Layer";
+ } else if (graphicsLayer == m_pageScaleLayer.get()) {
+ name = "Page Scale Layer";
+ } else if (graphicsLayer == m_innerViewportScrollLayer.get()) {
+ name = "Inner Viewport Scroll Layer";
+ } else if (graphicsLayer == m_overlayScrollbarHorizontal.get()) {
+ name = "Overlay Scrollbar Horizontal Layer";
+ } else if (graphicsLayer == m_overlayScrollbarVertical.get()) {
+ name = "Overlay Scrollbar Vertical Layer";
+ } else {
+ ASSERT_NOT_REACHED();
+ }
+
+ return name;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/PinchViewport.h b/chromium/third_party/WebKit/Source/core/frame/PinchViewport.h
new file mode 100644
index 00000000000..2dbc16f5707
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/PinchViewport.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PinchViewport_h
+#define PinchViewport_h
+
+#include "platform/geometry/FloatPoint.h"
+#include "platform/geometry/FloatRect.h"
+#include "platform/geometry/IntSize.h"
+#include "platform/graphics/GraphicsLayerClient.h"
+#include "platform/scroll/ScrollableArea.h"
+#include "public/platform/WebScrollbar.h"
+#include "public/platform/WebSize.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+
+namespace blink {
+class WebLayerTreeView;
+class WebScrollbarLayer;
+}
+
+namespace WebCore {
+
+class FrameHost;
+class GraphicsContext;
+class GraphicsLayer;
+class GraphicsLayerFactory;
+class IntRect;
+class IntSize;
+class LocalFrame;
+
+// Represents the pinch-to-zoom viewport the user is currently seeing the page through. This
+// class corresponds to the InnerViewport on the compositor. It is a ScrollableArea; it's
+// offset is set through the GraphicsLayer <-> CC sync mechanisms. Its contents is the page's
+// main FrameView, which corresponds to the outer viewport. The inner viewport is always contained
+// in the outer viewport and can pan within it.
+class PinchViewport FINAL : public GraphicsLayerClient, public ScrollableArea {
+public:
+ explicit PinchViewport(FrameHost&);
+ virtual ~PinchViewport();
+
+ void attachToLayerTree(GraphicsLayer*, GraphicsLayerFactory*);
+ GraphicsLayer* rootGraphicsLayer()
+ {
+ return m_rootTransformLayer.get();
+ }
+ GraphicsLayer* containerLayer()
+ {
+ return m_innerViewportContainerLayer.get();
+ }
+
+ // Sets the location of the inner viewport relative to the outer viewport. The
+ // coordinates are in partial CSS pixels.
+ void setLocation(const FloatPoint&);
+ void move(const FloatPoint&);
+
+ // Sets the size of the inner viewport when unscaled in CSS pixels.
+ // This will be clamped to the size of the outer viewport (the main frame).
+ void setSize(const IntSize&);
+ IntSize size() const { return m_size; }
+
+ // Resets the viewport to initial state.
+ void reset();
+
+ // Let the viewport know that the main frame changed size (either through screen
+ // rotation on Android or window resize elsewhere).
+ void mainFrameDidChangeSize();
+
+ void setScale(float);
+ float scale() const { return m_scale; }
+
+ void registerLayersWithTreeView(blink::WebLayerTreeView*) const;
+ void clearLayersForTreeView(blink::WebLayerTreeView*) const;
+
+ // The portion of the unzoomed frame visible in the inner "pinch" viewport,
+ // in partial CSS pixels. Relative to the main frame.
+ FloatRect visibleRect() const;
+
+ // The viewport rect relative to the document origin, in partial CSS pixels.
+ FloatRect visibleRectInDocument() const;
+
+ // Scroll the main frame and pinch viewport so that the given rect in the
+ // top-level document is centered in the viewport. This method will avoid
+ // scrolling the pinch viewport unless necessary.
+ void scrollIntoView(const FloatRect&);
+private:
+ // ScrollableArea implementation
+ virtual bool isActive() const OVERRIDE { return false; }
+ virtual int scrollSize(ScrollbarOrientation) const OVERRIDE;
+ virtual bool isScrollCornerVisible() const OVERRIDE { return false; }
+ virtual IntRect scrollCornerRect() const OVERRIDE { return IntRect(); }
+ virtual IntPoint scrollPosition() const OVERRIDE { return flooredIntPoint(m_offset); }
+ virtual IntPoint minimumScrollPosition() const OVERRIDE;
+ virtual IntPoint maximumScrollPosition() const OVERRIDE;
+ virtual int visibleHeight() const OVERRIDE { return visibleRect().height(); };
+ virtual int visibleWidth() const OVERRIDE { return visibleRect().width(); };
+ virtual IntSize contentsSize() const OVERRIDE;
+ virtual bool scrollbarsCanBeActive() const OVERRIDE { return false; }
+ virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
+ virtual bool userInputScrollable(ScrollbarOrientation) const OVERRIDE { return true; }
+ virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE { return false; }
+ virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE;
+ virtual void invalidateScrollCornerRect(const IntRect&) OVERRIDE { }
+ virtual void setScrollOffset(const IntPoint&) OVERRIDE;
+ virtual GraphicsLayer* layerForContainer() const OVERRIDE;
+ virtual GraphicsLayer* layerForScrolling() const OVERRIDE;
+ virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
+ virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE;
+
+ // GraphicsLayerClient implementation.
+ virtual void notifyAnimationStarted(const GraphicsLayer*, double monotonicTime) OVERRIDE;
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& inClip) OVERRIDE;
+ virtual String debugName(const GraphicsLayer*) OVERRIDE;
+
+ void setupScrollbar(blink::WebScrollbar::Orientation);
+ FloatPoint clampOffsetToBoundaries(const FloatPoint&);
+
+ LocalFrame* mainFrame() const;
+
+ FrameHost& m_frameHost;
+ OwnPtr<GraphicsLayer> m_rootTransformLayer;
+ OwnPtr<GraphicsLayer> m_innerViewportContainerLayer;
+ OwnPtr<GraphicsLayer> m_pageScaleLayer;
+ OwnPtr<GraphicsLayer> m_innerViewportScrollLayer;
+ OwnPtr<GraphicsLayer> m_overlayScrollbarHorizontal;
+ OwnPtr<GraphicsLayer> m_overlayScrollbarVertical;
+ OwnPtr<blink::WebScrollbarLayer> m_webOverlayScrollbarHorizontal;
+ OwnPtr<blink::WebScrollbarLayer> m_webOverlayScrollbarVertical;
+
+ // Offset of the pinch viewport from the main frame's origin, in CSS pixels.
+ FloatPoint m_offset;
+ float m_scale;
+ IntSize m_size;
+};
+
+} // namespace WebCore
+
+#endif // PinchViewport_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.cpp b/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
new file mode 100644
index 00000000000..f4c9176abab
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
@@ -0,0 +1,46 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/RemoteFrame.h"
+
+#include "core/frame/RemoteFrameView.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+
+namespace WebCore {
+
+inline RemoteFrame::RemoteFrame(FrameClient* client, FrameHost* host, FrameOwner* owner)
+ : Frame(client, host, owner)
+{
+}
+
+PassRefPtr<RemoteFrame> RemoteFrame::create(FrameClient* client, FrameHost* host, FrameOwner* owner)
+{
+ RefPtr<RemoteFrame> frame = adoptRef(new RemoteFrame(client, host, owner));
+ return frame.release();
+}
+
+RemoteFrame::~RemoteFrame()
+{
+ setView(nullptr);
+}
+
+void RemoteFrame::setView(PassRefPtr<RemoteFrameView> view)
+{
+ m_view = view;
+}
+
+void RemoteFrame::createView()
+{
+ RefPtr<RemoteFrameView> view = RemoteFrameView::create(this);
+ setView(view);
+
+ if (ownerRenderer()) {
+ HTMLFrameOwnerElement* owner = deprecatedLocalOwner();
+ ASSERT(owner);
+ owner->setWidget(view);
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.h b/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.h
new file mode 100644
index 00000000000..d8ec29be138
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/RemoteFrame.h
@@ -0,0 +1,41 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef RemoteFrame_h
+#define RemoteFrame_h
+
+#include "core/frame/Frame.h"
+
+namespace WebCore {
+
+class RemoteFrameView;
+
+class RemoteFrame: public Frame {
+public:
+ static PassRefPtr<RemoteFrame> create(FrameClient*, FrameHost*, FrameOwner*);
+ virtual bool isRemoteFrame() const OVERRIDE { return true; }
+
+ virtual ~RemoteFrame();
+
+ void setView(PassRefPtr<RemoteFrameView>);
+ void createView();
+
+ RemoteFrameView* view() const;
+
+private:
+ RemoteFrame(FrameClient*, FrameHost*, FrameOwner*);
+
+ RefPtr<RemoteFrameView> m_view;
+};
+
+inline RemoteFrameView* RemoteFrame::view() const
+{
+ return m_view.get();
+}
+
+DEFINE_TYPE_CASTS(RemoteFrame, Frame, remoteFrame, remoteFrame->isRemoteFrame(), remoteFrame.isRemoteFrame());
+
+} // namespace WebCore
+
+#endif // RemoteFrame_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp b/chromium/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp
new file mode 100644
index 00000000000..bd4e7c85c0d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/RemoteFrameView.cpp
@@ -0,0 +1,59 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/RemoteFrameView.h"
+
+#include "core/frame/RemoteFrame.h"
+#include "core/rendering/RenderPart.h"
+
+namespace WebCore {
+
+RemoteFrameView::RemoteFrameView(RemoteFrame* remoteFrame)
+ : m_remoteFrame(remoteFrame)
+{
+ ASSERT(remoteFrame);
+}
+
+RemoteFrameView::~RemoteFrameView()
+{
+}
+
+PassRefPtr<RemoteFrameView> RemoteFrameView::create(RemoteFrame* remoteFrame)
+{
+ RefPtr<RemoteFrameView> view = adoptRef(new RemoteFrameView(remoteFrame));
+ view->show();
+ return view.release();
+}
+
+void RemoteFrameView::invalidateRect(const IntRect& rect)
+{
+ RenderPart* renderer = m_remoteFrame->ownerRenderer();
+ if (!renderer)
+ return;
+
+ IntRect repaintRect = rect;
+ repaintRect.move(renderer->borderLeft() + renderer->paddingLeft(),
+ renderer->borderTop() + renderer->paddingTop());
+ renderer->invalidatePaintRectangle(repaintRect);
+}
+
+void RemoteFrameView::setFrameRect(const IntRect& newRect)
+{
+ IntRect oldRect = frameRect();
+
+ if (newRect == oldRect)
+ return;
+
+ Widget::setFrameRect(newRect);
+
+ frameRectsChanged();
+}
+
+void RemoteFrameView::frameRectsChanged()
+{
+ // FIXME: Notify embedder via WebLocalFrameClient when that is possible.
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/RemoteFrameView.h b/chromium/third_party/WebKit/Source/core/frame/RemoteFrameView.h
new file mode 100644
index 00000000000..a8d31f2e21e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/RemoteFrameView.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef RemoteFrameView_h
+#define RemoteFrameView_h
+
+#include "platform/Widget.h"
+#include "platform/geometry/IntRect.h"
+
+namespace WebCore {
+
+class RemoteFrame;
+
+class RemoteFrameView : public Widget {
+public:
+ static PassRefPtr<RemoteFrameView> create(RemoteFrame*);
+
+ virtual ~RemoteFrameView();
+
+ virtual bool isRemoteFrameView() const OVERRIDE { return true; }
+
+ RemoteFrame& frame() const { return *m_remoteFrame; }
+
+ // Override to notify remote frame that its viewport size has changed.
+ virtual void frameRectsChanged() OVERRIDE;
+
+ virtual void invalidateRect(const IntRect&) OVERRIDE;
+
+ virtual void setFrameRect(const IntRect&) OVERRIDE;
+
+private:
+ explicit RemoteFrameView(RemoteFrame*);
+
+ RefPtr<RemoteFrame> m_remoteFrame;
+};
+
+DEFINE_TYPE_CASTS(RemoteFrameView, Widget, widget, widget->isRemoteFrameView(), widget.isRemoteFrameView());
+
+} // namespace WebCore
+
+#endif // RemoteFrameView_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/Screen.cpp b/chromium/third_party/WebKit/Source/core/frame/Screen.cpp
index 18b22d63503..13523f46223 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Screen.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/Screen.cpp
@@ -30,17 +30,17 @@
#include "config.h"
#include "core/frame/Screen.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "platform/PlatformScreen.h"
#include "platform/geometry/FloatRect.h"
namespace WebCore {
-Screen::Screen(Frame* frame)
+Screen::Screen(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
@@ -50,9 +50,9 @@ unsigned Screen::height() const
{
if (!m_frame)
return 0;
- Page* page = m_frame->page();
- if (page && page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(screenRect(m_frame->view()).height() * page->deviceScaleFactor());
+ FrameHost* host = m_frame->host();
+ if (host && host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(screenRect(m_frame->view()).height() * host->deviceScaleFactor());
return static_cast<unsigned>(screenRect(m_frame->view()).height());
}
@@ -60,9 +60,9 @@ unsigned Screen::width() const
{
if (!m_frame)
return 0;
- Page* page = m_frame->page();
- if (page && page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(screenRect(m_frame->view()).width() * page->deviceScaleFactor());
+ FrameHost* host = m_frame->host();
+ if (host && host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(screenRect(m_frame->view()).width() * host->deviceScaleFactor());
return static_cast<unsigned>(screenRect(m_frame->view()).width());
}
@@ -84,9 +84,9 @@ int Screen::availLeft() const
{
if (!m_frame)
return 0;
- Page* page = m_frame->page();
- if (page && page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(screenAvailableRect(m_frame->view()).x() * page->deviceScaleFactor());
+ FrameHost* host = m_frame->host();
+ if (host && host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(screenAvailableRect(m_frame->view()).x() * host->deviceScaleFactor());
return static_cast<int>(screenAvailableRect(m_frame->view()).x());
}
@@ -94,9 +94,9 @@ int Screen::availTop() const
{
if (!m_frame)
return 0;
- Page* page = m_frame->page();
- if (page && page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(screenAvailableRect(m_frame->view()).y() * page->deviceScaleFactor());
+ FrameHost* host = m_frame->host();
+ if (host && host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(screenAvailableRect(m_frame->view()).y() * host->deviceScaleFactor());
return static_cast<int>(screenAvailableRect(m_frame->view()).y());
}
@@ -104,9 +104,9 @@ unsigned Screen::availHeight() const
{
if (!m_frame)
return 0;
- Page* page = m_frame->page();
- if (page && page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(screenAvailableRect(m_frame->view()).height() * page->deviceScaleFactor());
+ FrameHost* host = m_frame->host();
+ if (host && host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(screenAvailableRect(m_frame->view()).height() * host->deviceScaleFactor());
return static_cast<unsigned>(screenAvailableRect(m_frame->view()).height());
}
@@ -114,10 +114,15 @@ unsigned Screen::availWidth() const
{
if (!m_frame)
return 0;
- Page* page = m_frame->page();
- if (page && page->settings().reportScreenSizeInPhysicalPixelsQuirk())
- return lroundf(screenAvailableRect(m_frame->view()).width() * page->deviceScaleFactor());
+ FrameHost* host = m_frame->host();
+ if (host && host->settings().reportScreenSizeInPhysicalPixelsQuirk())
+ return lroundf(screenAvailableRect(m_frame->view()).width() * host->deviceScaleFactor());
return static_cast<unsigned>(screenAvailableRect(m_frame->view()).width());
}
+void Screen::trace(Visitor* visitor)
+{
+ WillBeHeapSupplementable<Screen>::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/Screen.h b/chromium/third_party/WebKit/Source/core/frame/Screen.h
index 7b2036b677e..99514918f28 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Screen.h
+++ b/chromium/third_party/WebKit/Source/core/frame/Screen.h
@@ -32,16 +32,22 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
- class Frame;
+ class LocalFrame;
- class Screen : public ScriptWrappable, public RefCounted<Screen>, public DOMWindowProperty {
+ class Screen FINAL : public RefCountedWillBeGarbageCollectedFinalized<Screen>, public ScriptWrappable, public DOMWindowProperty, public WillBeHeapSupplementable<Screen> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Screen);
public:
- static PassRefPtr<Screen> create(Frame *frame) { return adoptRef(new Screen(frame)); }
+ static PassRefPtrWillBeRawPtr<Screen> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new Screen(frame));
+ }
unsigned height() const;
unsigned width() const;
@@ -52,8 +58,10 @@ namespace WebCore {
unsigned availHeight() const;
unsigned availWidth() const;
+ void trace(Visitor*);
+
private:
- explicit Screen(Frame*);
+ explicit Screen(LocalFrame*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/Screen.idl b/chromium/third_party/WebKit/Source/core/frame/Screen.idl
index 184a863c4d9..a0b6385676f 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Screen.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/Screen.idl
@@ -27,7 +27,9 @@
*/
-interface Screen {
+[
+ WillBeGarbageCollected,
+] interface Screen {
readonly attribute unsigned long height;
readonly attribute unsigned long width;
readonly attribute unsigned long colorDepth;
diff --git a/chromium/third_party/WebKit/Source/core/frame/SecurityPolicy.idl b/chromium/third_party/WebKit/Source/core/frame/SecurityPolicy.idl
deleted file mode 100644
index f5651dac093..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/SecurityPolicy.idl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- ImplementedAs=DOMSecurityPolicy
-] interface SecurityPolicy {
- readonly attribute boolean allowsEval;
- readonly attribute boolean allowsInlineScript;
- readonly attribute boolean allowsInlineStyle;
- readonly attribute boolean isActive;
-
- readonly attribute DOMStringList reportURIs;
-
- boolean allowsConnectionTo(DOMString url);
- boolean allowsFontFrom(DOMString url);
- boolean allowsFormAction(DOMString url);
- boolean allowsFrameFrom(DOMString url);
- boolean allowsImageFrom(DOMString url);
- boolean allowsMediaFrom(DOMString url);
- boolean allowsObjectFrom(DOMString url);
- boolean allowsPluginType(DOMString type);
- boolean allowsScriptFrom(DOMString url);
- boolean allowsStyleFrom(DOMString url);
-};
diff --git a/chromium/third_party/WebKit/Source/core/frame/Settings.cpp b/chromium/third_party/WebKit/Source/core/frame/Settings.cpp
index b7d8d76b6ab..b4f209e29b3 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Settings.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/Settings.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/frame/Settings.h"
-#include "core/inspector/InspectorInstrumentation.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/scroll/ScrollbarTheme.h"
namespace WebCore {
@@ -65,7 +65,7 @@ static const bool defaultSelectTrailingWhitespaceEnabled = false;
#endif
Settings::Settings()
- : m_deviceScaleAdjustment(1.0f)
+ : m_openGLMultisamplingEnabled(false)
#if HACK_FORCE_TEXT_AUTOSIZING_ON_DESKTOP
, m_textAutosizingWindowSizeOverride(320, 480)
, m_textAutosizingEnabled(true)
@@ -73,8 +73,6 @@ Settings::Settings()
, m_textAutosizingEnabled(false)
#endif
SETTINGS_INITIALIZER_LIST
- , m_isScriptEnabled(false)
- , m_openGLMultisamplingEnabled(false)
{
}
@@ -96,26 +94,13 @@ void Settings::invalidate(SettingsDelegate::ChangeType changeType)
m_delegate->settingsChanged(changeType);
}
-// This is a total hack and should be removed.
-Page* Settings::pageOfShame() const
-{
- if (!m_delegate)
- return 0;
- return m_delegate->page();
-}
-
void Settings::setTextAutosizingEnabled(bool textAutosizingEnabled)
{
if (m_textAutosizingEnabled == textAutosizingEnabled)
return;
m_textAutosizingEnabled = textAutosizingEnabled;
- invalidate(SettingsDelegate::StyleChange);
-}
-
-bool Settings::textAutosizingEnabled() const
-{
- return InspectorInstrumentation::overrideTextAutosizing(pageOfShame(), m_textAutosizingEnabled);
+ invalidate(SettingsDelegate::TextAutosizingChange);
}
// FIXME: Move to Settings.in once make_settings can understand IntSize.
@@ -125,26 +110,9 @@ void Settings::setTextAutosizingWindowSizeOverride(const IntSize& textAutosizing
return;
m_textAutosizingWindowSizeOverride = textAutosizingWindowSizeOverride;
- invalidate(SettingsDelegate::StyleChange);
-}
-
-void Settings::setDeviceScaleAdjustment(float deviceScaleAdjustment)
-{
- m_deviceScaleAdjustment = deviceScaleAdjustment;
invalidate(SettingsDelegate::TextAutosizingChange);
}
-float Settings::deviceScaleAdjustment() const
-{
- return InspectorInstrumentation::overrideFontScaleFactor(pageOfShame(), m_deviceScaleAdjustment);
-}
-
-void Settings::setScriptEnabled(bool isScriptEnabled)
-{
- m_isScriptEnabled = isScriptEnabled;
- InspectorInstrumentation::scriptsEnabled(pageOfShame(), m_isScriptEnabled);
-}
-
void Settings::setMockScrollbarsEnabled(bool flag)
{
ScrollbarTheme::setMockScrollbarsEnabled(flag);
diff --git a/chromium/third_party/WebKit/Source/core/frame/Settings.h b/chromium/third_party/WebKit/Source/core/frame/Settings.h
index 76f5ac5097f..13a03394c0e 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Settings.h
+++ b/chromium/third_party/WebKit/Source/core/frame/Settings.h
@@ -27,7 +27,7 @@
#ifndef Settings_h
#define Settings_h
-#include "SettingsMacros.h"
+#include "core/SettingsMacros.h"
#include "core/editing/EditingBehaviorTypes.h"
#include "core/frame/SettingsDelegate.h"
#include "platform/Timer.h"
@@ -39,42 +39,21 @@
namespace WebCore {
-class Page; // For inspector, remove after http://crbug.com/327476
-
-enum EditableLinkBehavior {
- EditableLinkDefaultBehavior,
- EditableLinkAlwaysLive,
- EditableLinkOnlyLiveWithShiftKey,
- EditableLinkLiveWhenNotFocused,
- EditableLinkNeverLive
-};
-
class Settings {
WTF_MAKE_NONCOPYABLE(Settings); WTF_MAKE_FAST_ALLOCATED;
public:
static PassOwnPtr<Settings> create();
GenericFontFamilySettings& genericFontFamilySettings() { return m_genericFontFamilySettings; }
+ void notifyGenericFontFamilyChange() { invalidate(SettingsDelegate::FontFamilyChange); }
void setTextAutosizingEnabled(bool);
- bool textAutosizingEnabled() const;
-
- // Compensates for poor text legibility on mobile devices. This value is
- // multiplied by the font scale factor when performing text autosizing of
- // websites that do not set an explicit viewport description.
- void setDeviceScaleAdjustment(float);
- float deviceScaleAdjustment() const;
+ bool textAutosizingEnabled() const { return m_textAutosizingEnabled; }
// Only set by Layout Tests, and only used if textAutosizingEnabled() returns true.
void setTextAutosizingWindowSizeOverride(const IntSize&);
const IntSize& textAutosizingWindowSizeOverride() const { return m_textAutosizingWindowSizeOverride; }
- // Clients that execute script should call ScriptController::canExecuteScripts()
- // instead of this function. ScriptController::canExecuteScripts() checks the
- // HTML sandbox, plug-in sandboxing, and other important details.
- bool isScriptEnabled() const { return m_isScriptEnabled; }
- void setScriptEnabled(bool);
-
SETTINGS_GETTERS_AND_SETTERS
// FIXME: This does not belong here.
@@ -93,21 +72,14 @@ private:
void invalidate(SettingsDelegate::ChangeType);
- // FIXME: pageOfShame() is a hack for the inspector code:
- // http://crbug.com/327476
- Page* pageOfShame() const;
-
SettingsDelegate* m_delegate;
GenericFontFamilySettings m_genericFontFamilySettings;
- float m_deviceScaleAdjustment;
+ bool m_openGLMultisamplingEnabled : 1;
IntSize m_textAutosizingWindowSizeOverride;
bool m_textAutosizingEnabled : 1;
SETTINGS_MEMBER_VARIABLES
-
- bool m_isScriptEnabled : 1;
- bool m_openGLMultisamplingEnabled : 1;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/Settings.in b/chromium/third_party/WebKit/Source/core/frame/Settings.in
index b45c89ad2cd..20b73637afd 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Settings.in
+++ b/chromium/third_party/WebKit/Source/core/frame/Settings.in
@@ -25,7 +25,6 @@
# FIXME: Add support for custom getters/setters.
defaultTextEncodingName type=String
-editableLinkBehavior type=EditableLinkBehavior, initial=EditableLinkDefaultBehavior
# Do not hide chars typed in password fields immediately, but let the last char stay
# visible for N seconds, configured by the passwordEchoDurationInSeconds setting
@@ -51,10 +50,6 @@ validationMessageTimerMagnification type=int, initial=50
# draw canvas in software.
minimumAccelerated2dCanvasSize type=int, initial=257*256
-# The layout width used with --enable-viewport when no viewport meta tag was defined.
-# FIXME: This should get the value from the @viewport UA sheet instead.
-layoutFallbackWidth type=int, initial=980
-
minimumFontSize type=int, initial=0, invalidate=Style
minimumLogicalFontSize type=int, initial=0, invalidate=Style
defaultFontSize type=int, initial=0, invalidate=Style
@@ -73,10 +68,7 @@ shouldPrintBackgrounds initial=false
shouldClearDocumentBackground initial=true
textAreasAreResizable initial=false, invalidate=Style
-acceleratedCompositingEnabled initial=true, invalidate=Style
-
-# Debugging feature used for accelerated compositing layers.
-showRepaintCounter initial=false, invalidate=Style
+acceleratedCompositingEnabled initial=true, invalidate=AcceleratedCompositing
shrinksStandaloneImagesToFit initial=true
@@ -87,9 +79,11 @@ needsSiteSpecificQuirks initial=false
offlineWebApplicationCacheEnabled initial=false
usesEncodingDetector initial=false
allowScriptsToCloseWindows initial=false
-acceleratedFiltersEnabled initial=false
+deferredFiltersEnabled initial=true
regionBasedColumnsEnabled initial=false
+containerCullingEnabled initial=false
+
# FIXME: This should really be disabled by default as it makes platforms that
# don't support the feature download files they can't use by.
# Leaving enabled for now to not change existing behavior.
@@ -99,29 +93,18 @@ xssAuditorEnabled initial=false
unsafePluginPastingEnabled initial=true
treatIPAddressAsDomain initial=false
-acceleratedCompositingFor3DTransformsEnabled initial=true
-acceleratedCompositingForVideoEnabled initial=true
-acceleratedCompositingForPluginsEnabled initial=true
-acceleratedCompositingForCanvasEnabled initial=true
-acceleratedCompositingForAnimationEnabled initial=true
-acceleratedCompositingForFiltersEnabled initial=false
-acceleratedCompositingForFixedPositionEnabled initial=false
-acceleratedCompositingForOverflowScrollEnabled initial=false
-acceleratedCompositingForTransitionEnabled initial=false
+acceleratedCompositingForVideoEnabled initial=true, invalidate=AcceleratedCompositing
+acceleratedCompositingForCanvasEnabled initial=true, invalidate=AcceleratedCompositing
+acceleratedCompositingForFiltersEnabled initial=false, invalidate=AcceleratedCompositing
+acceleratedCompositingForFixedPositionEnabled initial=false, invalidate=AcceleratedCompositing
+acceleratedCompositingForOverflowScrollEnabled initial=false, invalidate=AcceleratedCompositing
acceleratedCompositingForFixedRootBackgroundEnabled initial=false
-
-forceCompositingMode initial=false
-
-# Works only in conjunction with forceCompositingMode.
-# crbug.com/304900 tracks removal once enabled on all platforms.
-acceleratedCompositingForScrollableFramesEnabled initial=false
-compositedScrollingForFramesEnabled initial=false
+compositedScrollingForFramesEnabled initial=false, invalidate=AcceleratedCompositing
# 3D canvas (WebGL) support.
webGLEnabled initial=false
webGLErrorsToConsoleEnabled initial=true
-privilegedWebGLExtensionsEnabled initial=false
accelerated2dCanvasEnabled initial=false
antialiased2dCanvasEnabled initial=true
accelerated2dCanvasMSAASampleCount type=int, initial=0
@@ -129,21 +112,17 @@ accelerated2dCanvasMSAASampleCount type=int, initial=0
# WebAudio support.
webAudioEnabled initial=false
-fullScreenEnabled initial=false
asynchronousSpellCheckingEnabled initial=false
-memoryInfoEnabled initial=false
hyperlinkAuditingEnabled initial=false
allowDisplayOfInsecureContent initial=true
allowRunningOfInsecureContent initial=true
+# FIXME: Remove this temporary flag. See crbug.com/366483 for the target
+# milestone.
+allowConnectingInsecureWebSocket initial=false
+mediaControlsOverlayPlayButtonEnabled initial=false
mediaPlaybackRequiresUserGesture initial=false
-mediaFullscreenRequiresUserGesture initial=true
-visualWordMovementEnabled initial=false
-shouldDisplaySubtitles initial=false
-shouldDisplayCaptions initial=false
-shouldDisplayTextDescriptions initial=false
-scrollingCoordinatorEnabled initial=false
scrollAnimatorEnabled initial=true
shouldRespectImageOrientation initial=false
@@ -172,17 +151,11 @@ touchAdjustmentEnabled initial=true
# A mostly-stable performance optimization. crbug.com/304518 tracks removal.
compositorTouchHitTesting initial=true
-fixedPositionCreatesStackingContext initial=false
syncXHRInDocumentsEnabled initial=true
cookieEnabled initial=true
-mediaEnabled initial=true
+navigateOnDragDrop initial=true
DOMPasteAllowed initial=false
-threadedHTMLParser initial=false
-useThreadedHTMLParserForDataURLs initial=false
-
-applyPageScaleFactorInCompositor initial=false
-
allowCustomScrollbarInMainFrame initial=true
webSecurityEnabled initial=true
@@ -234,8 +207,6 @@ wideViewportQuirkEnabled initial=false
# crbug.com/304873 tracks removal once it's been enabled on all platforms.
touchEditingEnabled initial=false
-experimentalWebSocketEnabled initial=false
-
# Settings for experimental desktop pinch-zoom support (with semantics
# optimized for large screens). Pinch-zoom generally is implemented mainly
# outside of blink (in the compositor) and doesn't require any settings.
@@ -244,13 +215,10 @@ experimentalWebSocketEnabled initial=false
# crbug.com/304869 tracks removal.
pinchVirtualViewportEnabled initial=false
useSolidColorScrollbars initial=false
+pinchOverlayScrollbarThickness type=int, initial=0
mainFrameClipsContent initial=true
-# Enable decoration shadow nodes to test password genration feature
-# crbug.com/114092. This flag should not be enabled for production.
-passwordGenerationDecorationEnabled initial=false
-
# Presumably used by LayoutTests? Unclear.
useWideViewport initial=true, invalidate=ViewportDescription
@@ -277,13 +245,31 @@ viewportMetaEnabled initial=false
dnsPrefetchingEnabled initial=false, invalidate=DNSPrefetching
-touchEventEmulationEnabled initial=false
-
# FIXME: This is a temporary flag and should be removed once
# accelerated overflow scroll is ready (crbug.com/254111).
-compositorDrivenAcceleratedScrollingEnabled initial=false
+compositorDrivenAcceleratedScrollingEnabled initial=false, invalidate=AcceleratedCompositing
# FIXME: This is a temporary flag and should be removed
# when squashing is ready. (crbug.com/261605)
layerSquashingEnabled initial=false
+
+# Clients that execute script should call ScriptController::canExecuteScripts()
+# instead of this function. ScriptController::canExecuteScripts() checks the
+# HTML sandbox, plug-in sandboxing, and other important details.
+scriptEnabled initial=false, invalidate=ScriptEnable
+
+# Compensates for poor text legibility on mobile devices. This value is
+# multiplied by the font scale factor when performing text autosizing of
+# websites that do not set an explicit viewport description.
+deviceScaleAdjustment type=double, initial=1.0, invalidate=TextAutosizing
+
+# This value indicates the maximum number of bytes a document is allowed
+# to transmit in Beacons (via navigator.sendBeacon()) -- Beacons are
+# intended to be smaller payloads transmitted as a page is unloading, not
+# a general (one-way) network transmission API.
+# The spec ( https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/Beacon/Overview.html )
+# does not proscribe an upper limit, but allows for it -- the underlying
+# API will return 'false' in that case.
+maxBeaconTransmission type=int, initial=16384
+
diff --git a/chromium/third_party/WebKit/Source/core/frame/SettingsDelegate.h b/chromium/third_party/WebKit/Source/core/frame/SettingsDelegate.h
index 2ea0bf2fe07..9c22ee9be57 100644
--- a/chromium/third_party/WebKit/Source/core/frame/SettingsDelegate.h
+++ b/chromium/third_party/WebKit/Source/core/frame/SettingsDelegate.h
@@ -56,14 +56,13 @@ public:
MultisamplingChange,
ImageLoadingChange,
TextAutosizingChange,
+ ScriptEnableChange,
+ FontFamilyChange,
+ AcceleratedCompositingChange,
};
virtual void settingsChanged(ChangeType) = 0;
- // FIXME: This is a hack until the Inspector code can
- // be removed from Settings. http://crbug.com/327476
- virtual Page* page() = 0;
-
protected:
OwnPtr<Settings> const m_settings;
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/SmartClip.cpp b/chromium/third_party/WebKit/Source/core/frame/SmartClip.cpp
index 52f9b03dabd..40c773edf13 100644
--- a/chromium/third_party/WebKit/Source/core/frame/SmartClip.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/SmartClip.cpp
@@ -34,10 +34,11 @@
#include "core/dom/ContainerNode.h"
#include "core/dom/Document.h"
#include "core/dom/NodeTraversal.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/page/Page.h"
+#include "core/rendering/RenderObject.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
@@ -69,7 +70,7 @@ static Node* nodeInsideFrame(Node* node)
// read/write code in one place!
String SmartClipData::toString()
{
- if (!m_node)
+ if (m_isEmpty)
return emptyString();
const UChar fieldSeparator = 0xFFFE;
@@ -89,7 +90,7 @@ String SmartClipData::toString()
return result.toString();
}
-SmartClip::SmartClip(PassRefPtr<Frame> frame)
+SmartClip::SmartClip(PassRefPtr<LocalFrame> frame)
: m_frame(frame)
{
}
@@ -108,10 +109,10 @@ SmartClipData SmartClip::dataForRect(const IntRect& cropRect)
bestNode = bestNodeInFrame;
}
- Vector<Node*> hitNodes;
+ WillBeHeapVector<RawPtrWillBeMember<Node> > hitNodes;
collectOverlappingChildNodes(bestNode, resizedCropRect, hitNodes);
- if (hitNodes.isEmpty() || hitNodes.size() == bestNode->childNodeCount()) {
+ if (hitNodes.isEmpty() || hitNodes.size() == bestNode->countChildren()) {
hitNodes.clear();
hitNodes.append(bestNode);
}
@@ -220,8 +221,9 @@ Node* SmartClip::findBestOverlappingNode(Node* rootNode, const IntRect& cropRect
// CSS background images but to skip actual backgrounds.
bool SmartClip::shouldSkipBackgroundImage(Node* node)
{
+ ASSERT(node);
// Apparently we're only interested in background images on spans and divs.
- if (!node->hasTagName(HTMLNames::spanTag) && !node->hasTagName(HTMLNames::divTag))
+ if (!isHTMLSpanElement(*node) && !isHTMLDivElement(*node))
return true;
// This check actually makes a bit of sense. If you're going to sprite an
@@ -235,7 +237,7 @@ bool SmartClip::shouldSkipBackgroundImage(Node* node)
return false;
}
-void SmartClip::collectOverlappingChildNodes(Node* parentNode, const IntRect& cropRect, Vector<Node*>& hitNodes)
+void SmartClip::collectOverlappingChildNodes(Node* parentNode, const IntRect& cropRect, WillBeHeapVector<RawPtrWillBeMember<Node> >& hitNodes)
{
if (!parentNode)
return;
diff --git a/chromium/third_party/WebKit/Source/core/frame/SmartClip.h b/chromium/third_party/WebKit/Source/core/frame/SmartClip.h
index 7481b2a3879..21955a2b3ea 100644
--- a/chromium/third_party/WebKit/Source/core/frame/SmartClip.h
+++ b/chromium/third_party/WebKit/Source/core/frame/SmartClip.h
@@ -32,18 +32,19 @@
#define SmartClip_h
#include "core/dom/Node.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
class SmartClipData {
public:
SmartClipData()
+ : m_isEmpty(true)
{
}
SmartClipData(Node* node, IntRect rect, String string)
- : m_node(node)
+ : m_isEmpty(!node)
, m_rect(rect)
, m_string(string)
{
@@ -52,7 +53,7 @@ public:
String toString();
private:
- RefPtr<Node> m_node;
+ bool m_isEmpty;
IntRect m_rect;
String m_string;
};
@@ -64,7 +65,7 @@ private:
// selection followed by a copy operation.
class SmartClip {
public:
- explicit SmartClip(PassRefPtr<Frame>);
+ explicit SmartClip(PassRefPtr<LocalFrame>);
SmartClipData dataForRect(const IntRect&);
@@ -74,11 +75,11 @@ private:
Node* minNodeContainsNodes(Node* minNode, Node* newNode);
Node* findBestOverlappingNode(Node*, const IntRect& cropRect);
bool shouldSkipBackgroundImage(Node*);
- void collectOverlappingChildNodes(Node* parentNode, const IntRect& cropRect, Vector<Node*>& overlappingNodeInfoTable);
+ void collectOverlappingChildNodes(Node* parentNode, const IntRect& cropRect, WillBeHeapVector<RawPtrWillBeMember<Node> >& overlappingNodeInfoTable);
IntRect convertRectToWindow(const IntRect& nodeRect);
String extractTextFromNode(Node*);
- RefPtr<Frame> m_frame;
+ RefPtr<LocalFrame> m_frame;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.cpp b/chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.cpp
index e3ffcf819ae..afbf6275677 100644
--- a/chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.cpp
@@ -34,7 +34,7 @@ SuspendableTimer::SuspendableTimer(ExecutionContext* context)
, m_nextFireInterval(0)
, m_repeatInterval(0)
, m_active(false)
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
, m_suspended(false)
#endif
{
@@ -56,7 +56,7 @@ void SuspendableTimer::stop()
void SuspendableTimer::suspend()
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
ASSERT(!m_suspended);
m_suspended = true;
#endif
@@ -70,12 +70,13 @@ void SuspendableTimer::suspend()
void SuspendableTimer::resume()
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
ASSERT(m_suspended);
m_suspended = false;
#endif
+ // FIXME: FROM_HERE is wrong here.
if (m_active)
- start(m_nextFireInterval, m_repeatInterval);
+ start(m_nextFireInterval, m_repeatInterval, FROM_HERE);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.h b/chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.h
index 3981ab7e077..9b92b6372bc 100644
--- a/chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.h
+++ b/chromium/third_party/WebKit/Source/core/frame/SuspendableTimer.h
@@ -38,10 +38,10 @@ public:
virtual ~SuspendableTimer();
// ActiveDOMObject
- virtual bool hasPendingActivity() const;
- virtual void stop();
- virtual void suspend();
- virtual void resume();
+ virtual bool hasPendingActivity() const OVERRIDE FINAL;
+ virtual void stop() OVERRIDE;
+ virtual void suspend() OVERRIDE FINAL;
+ virtual void resume() OVERRIDE FINAL;
private:
virtual void fired() = 0;
@@ -49,7 +49,7 @@ private:
double m_nextFireInterval;
double m_repeatInterval;
bool m_active;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool m_suspended;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/UseCounter.cpp b/chromium/third_party/WebKit/Source/core/frame/UseCounter.cpp
index 667e5f9313d..a0ce4057a5c 100644
--- a/chromium/third_party/WebKit/Source/core/frame/UseCounter.cpp
+++ b/chromium/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -31,15 +31,19 @@
#include "core/css/StyleSheetContents.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
-#include "core/frame/DOMWindow.h"
-#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/workers/WorkerGlobalScope.h"
#include "public/platform/Platform.h"
namespace WebCore {
static int totalPagesMeasuredCSSSampleId() { return 1; }
+int UseCounter::m_muteCount = 0;
+
// FIXME : This mapping should be autogenerated. This function should
// be moved to a separate file and a script run at build time
// to detect new values in CSSPropertyID and add them to the
@@ -64,7 +68,7 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyWebkitFontFeatureSettings: return 12;
case CSSPropertyFontKerning: return 13;
case CSSPropertyWebkitFontSmoothing: return 14;
- case CSSPropertyWebkitFontVariantLigatures: return 15;
+ case CSSPropertyFontVariantLigatures: return 15;
case CSSPropertyWebkitLocale: return 16;
case CSSPropertyWebkitTextOrientation: return 17;
case CSSPropertyWebkitWritingMode: return 18;
@@ -262,13 +266,13 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyWebkitBoxPack: return 210;
case CSSPropertyWebkitBoxReflect: return 211;
case CSSPropertyWebkitBoxShadow: return 212;
- case CSSPropertyWebkitColumnAxis: return 214;
+ // CSSPropertyWebkitColumnAxis was 214
case CSSPropertyWebkitColumnBreakAfter: return 215;
case CSSPropertyWebkitColumnBreakBefore: return 216;
case CSSPropertyWebkitColumnBreakInside: return 217;
case CSSPropertyWebkitColumnCount: return 218;
case CSSPropertyWebkitColumnGap: return 219;
- case CSSPropertyWebkitColumnProgression: return 220;
+ // CSSPropertyWebkitColumnProgression was 220
case CSSPropertyWebkitColumnRule: return 221;
case CSSPropertyWebkitColumnRuleColor: return 222;
case CSSPropertyWebkitColumnRuleStyle: return 223;
@@ -294,8 +298,8 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyFlexWrap: return 239;
case CSSPropertyJustifyContent: return 240;
case CSSPropertyWebkitFontSizeDelta: return 241;
- case CSSPropertyGridDefinitionColumns: return 242;
- case CSSPropertyGridDefinitionRows: return 243;
+ case CSSPropertyGridTemplateColumns: return 242;
+ case CSSPropertyGridTemplateRows: return 243;
case CSSPropertyGridColumnStart: return 244;
case CSSPropertyGridColumnEnd: return 245;
case CSSPropertyGridRowStart: return 246;
@@ -306,11 +310,11 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyWebkitHighlight: return 251;
case CSSPropertyWebkitHyphenateCharacter: return 252;
case CSSPropertyWebkitLineBoxContain: return 257;
- case CSSPropertyWebkitLineAlign: return 258;
+ // case CSSPropertyWebkitLineAlign: return 258;
case CSSPropertyWebkitLineBreak: return 259;
case CSSPropertyWebkitLineClamp: return 260;
- case CSSPropertyWebkitLineGrid: return 261;
- case CSSPropertyWebkitLineSnap: return 262;
+ // case CSSPropertyWebkitLineGrid: return 261;
+ // case CSSPropertyWebkitLineSnap: return 262;
case CSSPropertyWebkitLogicalWidth: return 263;
case CSSPropertyWebkitLogicalHeight: return 264;
case CSSPropertyWebkitMarginAfterCollapse: return 265;
@@ -384,16 +388,16 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyWebkitUserDrag: return 337;
case CSSPropertyWebkitUserModify: return 338;
case CSSPropertyWebkitUserSelect: return 339;
- case CSSPropertyWebkitFlowInto: return 340;
- case CSSPropertyWebkitFlowFrom: return 341;
- case CSSPropertyWebkitRegionFragment: return 342;
- case CSSPropertyWebkitRegionBreakAfter: return 343;
- case CSSPropertyWebkitRegionBreakBefore: return 344;
- case CSSPropertyWebkitRegionBreakInside: return 345;
- case CSSPropertyShapeInside: return 346;
+ // case CSSPropertyWebkitFlowInto: return 340;
+ // case CSSPropertyWebkitFlowFrom: return 341;
+ // case CSSPropertyWebkitRegionFragment: return 342;
+ // case CSSPropertyWebkitRegionBreakAfter: return 343;
+ // case CSSPropertyWebkitRegionBreakBefore: return 344;
+ // case CSSPropertyWebkitRegionBreakInside: return 345;
+ // case CSSPropertyShapeInside: return 346;
case CSSPropertyShapeOutside: return 347;
case CSSPropertyShapeMargin: return 348;
- case CSSPropertyShapePadding: return 349;
+ // case CSSPropertyShapePadding: return 349;
case CSSPropertyWebkitWrapFlow: return 350;
case CSSPropertyWebkitWrapThrough: return 351;
// CSSPropertyWebkitWrap was 352.
@@ -415,7 +419,7 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyStopOpacity: return 364;
case CSSPropertyColorInterpolation: return 365;
case CSSPropertyColorInterpolationFilters: return 366;
- case CSSPropertyColorProfile: return 367;
+ // case CSSPropertyColorProfile: return 367;
case CSSPropertyColorRendering: return 368;
case CSSPropertyFill: return 369;
case CSSPropertyFillOpacity: return 370;
@@ -439,7 +443,7 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyDominantBaseline: return 388;
case CSSPropertyGlyphOrientationHorizontal: return 389;
case CSSPropertyGlyphOrientationVertical: return 390;
- case CSSPropertyKerning: return 391;
+ // CSSPropertyKerning has been removed, was return 391;
case CSSPropertyTextAnchor: return 392;
case CSSPropertyVectorEffect: return 393;
case CSSPropertyWritingMode: return 394;
@@ -475,7 +479,7 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyMixBlendMode: return 420;
case CSSPropertyTouchAction: return 421;
case CSSPropertyGridArea: return 422;
- case CSSPropertyGridTemplate: return 423;
+ case CSSPropertyGridTemplateAreas: return 423;
case CSSPropertyAnimation: return 424;
case CSSPropertyAnimationDelay: return 425;
case CSSPropertyAnimationDirection: return 426;
@@ -495,9 +499,24 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyColumnFill: return 440;
case CSSPropertyTextJustify: return 441;
case CSSPropertyTouchActionDelay: return 442;
-
- // Add new features above this line (don't change the assigned numbers of the existing
- // items) and update maximumCSSSampleId() with the new maximum value.
+ case CSSPropertyJustifySelf: return 443;
+ case CSSPropertyScrollBehavior: return 444;
+ case CSSPropertyWillChange: return 445;
+ case CSSPropertyTransform: return 446;
+ case CSSPropertyTransformOrigin: return 447;
+ case CSSPropertyTransformStyle: return 448;
+ case CSSPropertyPerspective: return 449;
+ case CSSPropertyPerspectiveOrigin: return 450;
+ case CSSPropertyBackfaceVisibility: return 451;
+ case CSSPropertyGridTemplate: return 452;
+ case CSSPropertyGrid: return 453;
+ case CSSPropertyAll: return 454;
+
+ // 1. Add new features above this line (don't change the assigned numbers of the existing
+ // items).
+ // 2. Update maximumCSSSampleId() with the new maximum value.
+ // 3. Run the update_use_counter_css.py script in
+ // chromium/src/tools/metrics/histograms to update the UMA histogram names.
// Internal properties should not be counted.
case CSSPropertyInternalMarqueeDirection:
@@ -506,7 +525,6 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
case CSSPropertyInternalMarqueeSpeed:
case CSSPropertyInternalMarqueeStyle:
case CSSPropertyInvalid:
- case CSSPropertyVariable:
ASSERT_NOT_REACHED();
return 0;
}
@@ -515,7 +533,17 @@ int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(int id)
return 0;
}
-static int maximumCSSSampleId() { return 442; }
+static int maximumCSSSampleId() { return 454; }
+
+void UseCounter::muteForInspector()
+{
+ UseCounter::m_muteCount++;
+}
+
+void UseCounter::unmuteForInspector()
+{
+ UseCounter::m_muteCount--;
+}
UseCounter::UseCounter()
{
@@ -569,30 +597,39 @@ void UseCounter::didCommitLoad()
void UseCounter::count(const Document& document, Feature feature)
{
- Page* page = document.page();
- if (!page)
+ FrameHost* host = document.frameHost();
+ if (!host)
return;
- ASSERT(page->useCounter().deprecationMessage(feature).isEmpty());
- page->useCounter().recordMeasurement(feature);
+ ASSERT(host->useCounter().deprecationMessage(feature).isEmpty());
+ host->useCounter().recordMeasurement(feature);
}
-void UseCounter::count(const DOMWindow* domWindow, Feature feature)
+void UseCounter::count(const ExecutionContext* context, Feature feature)
{
- ASSERT(domWindow);
- if (!domWindow->document())
+ if (!context)
+ return;
+ if (context->isDocument()) {
+ count(*toDocument(context), feature);
return;
- count(*domWindow->document(), feature);
+ }
+ if (context->isWorkerGlobalScope())
+ toWorkerGlobalScope(context)->countFeature(feature);
}
void UseCounter::countDeprecation(ExecutionContext* context, Feature feature)
{
- if (!context || !context->isDocument())
+ if (!context)
+ return;
+ if (context->isDocument()) {
+ UseCounter::countDeprecation(*toDocument(context), feature);
return;
- UseCounter::countDeprecation(*toDocument(context), feature);
+ }
+ if (context->isWorkerGlobalScope())
+ toWorkerGlobalScope(context)->countDeprecation(feature);
}
-void UseCounter::countDeprecation(const DOMWindow* window, Feature feature)
+void UseCounter::countDeprecation(const LocalDOMWindow* window, Feature feature)
{
if (!window || !window->document())
return;
@@ -601,86 +638,115 @@ void UseCounter::countDeprecation(const DOMWindow* window, Feature feature)
void UseCounter::countDeprecation(const Document& document, Feature feature)
{
- Page* page = document.page();
- if (!page)
+ FrameHost* host = document.frameHost();
+ LocalFrame* frame = document.frame();
+ if (!host || !frame)
return;
- if (page->useCounter().recordMeasurement(feature)) {
- ASSERT(!page->useCounter().deprecationMessage(feature).isEmpty());
- page->console().addMessage(DeprecationMessageSource, WarningMessageLevel, page->useCounter().deprecationMessage(feature));
+ if (host->useCounter().recordMeasurement(feature)) {
+ ASSERT(!host->useCounter().deprecationMessage(feature).isEmpty());
+ frame->console().addMessage(DeprecationMessageSource, WarningMessageLevel, host->useCounter().deprecationMessage(feature));
}
}
String UseCounter::deprecationMessage(Feature feature)
{
switch (feature) {
- // Content Security Policy
- case PrefixedContentSecurityPolicy:
- case PrefixedContentSecurityPolicyReportOnly:
- return "The 'X-WebKit-CSP' headers are no longer supported. Please consider using the canonical 'Content-Security-Policy' header instead.";
-
- // HTMLMediaElement
- case PrefixedMediaGenerateKeyRequest:
- return "'HTMLMediaElement.webkitGenerateKeyRequest()' is deprecated. Please use 'MediaKeys.createSession()' instead.";
-
// Quota
- case StorageInfo:
+ case PrefixedStorageInfo:
return "'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.";
- // Performance
- case PrefixedPerformanceTimeline:
- return "'window.performance.webkitGet*' methods have been deprecated. Please use the unprefixed 'performance.get*' methods instead.";
- case PrefixedUserTiming:
- return "'window.performance.webkit*' methods have been deprecated. Please use the unprefixed 'window.performance.*' methods instead.";
+ // Keyboard Event (DOM Level 3)
+ case KeyboardEventKeyLocation:
+ return "'KeyboardEvent.keyLocation' is deprecated. Please use 'KeyboardEvent.location' instead.";
+
+ case ConsoleMarkTimeline:
+ return "console.markTimeline is deprecated. Please use the console.timeStamp instead.";
+
+ case FileError:
+ return "FileError is deprecated. Please use the 'name' or 'message' attributes of DOMError rather than 'code'.";
+
+ case ShowModalDialog:
+ return "showModalDialog is deprecated. Please use window.open and postMessage instead.";
- // Web Audio
- case WebAudioLooping:
- return "AudioBufferSourceNode 'looping' attribute is deprecated. Use 'loop' instead.";
+ case CSSStyleSheetInsertRuleOptionalArg:
+ return "Calling CSSStyleSheet.insertRule() with one argument is deprecated. Please pass the index argument as well: insertRule(x, 0).";
- case DocumentClear:
- return "document.clear() is deprecated. This method doesn't do anything.";
+ case PrefixedVideoSupportsFullscreen:
+ return "'HTMLVideoElement.webkitSupportsFullscreen' is deprecated. Its value is true if the video is loaded.";
- case PrefixedTransitionMediaFeature:
- return "The '(-webkit-transition)' media query feature is deprecated; please consider using the more exact conditional \"@supports('(transition-property: prop_name)')\" instead.";
+ case PrefixedVideoDisplayingFullscreen:
+ return "'HTMLVideoElement.webkitDisplayingFullscreen' is deprecated. Please use the 'fullscreenchange' and 'webkitfullscreenchange' events instead.";
- // Web Components
- case HTMLShadowElementOlderShadowRoot:
- return "HTMLShadowElement.olderShadowRoot is deprecated.";
+ case PrefixedVideoEnterFullscreen:
+ return "'HTMLVideoElement.webkitEnterFullscreen()' is deprecated. Please use 'Element.requestFullscreen()' and 'Element.webkitRequestFullscreen()' instead.";
- // HTML Media Capture
- case CaptureAttributeAsEnum:
- return "Using the 'capture' attribute as an enum is deprecated. Please use it as a boolean and specify the media types that should be accepted in the 'accept' attribute.";
+ case PrefixedVideoExitFullscreen:
+ return "'HTMLVideoElement.webkitExitFullscreen()' is deprecated. Please use 'Document.exitFullscreen()' and 'Document.webkitExitFullscreen()' instead.";
- // Keyboard Event (DOM Level 3)
- case KeyboardEventKeyLocation:
- return "'KeyboardEvent.keyLocation'' is deprecated. Please use 'KeyboardEvent.location' instead.";
+ case PrefixedVideoEnterFullScreen:
+ return "'HTMLVideoElement.webkitEnterFullScreen()' is deprecated. Please use 'Element.requestFullscreen()' and 'Element.webkitRequestFullscreen()' instead.";
- case CaptureEvents:
- return "captureEvents() is deprecated. This method doesn't do anything.";
+ case PrefixedVideoExitFullScreen:
+ return "'HTMLVideoElement.webkitExitFullScreen()' is deprecated. Please use 'Document.exitFullscreen()' and 'Document.webkitExitFullscreen()' instead.";
- case ReleaseEvents:
- return "releaseEvents() is deprecated. This method doesn't do anything.";
+ case MediaErrorEncrypted:
+ return "'MediaError.MEDIA_ERR_ENCRYPTED' is deprecated. This error code is never used.";
- case ConsoleMarkTimeline:
- return "console.markTimeline is deprecated. Please use the console.timeStamp instead.";
+ case PrefixedGamepad:
+ return "'navigator.webkitGetGamepads' is deprecated. Please use 'navigator.getGamepads' instead.";
- case FileError:
- return "FileError is deprecated. Please use the 'name' or 'message' attributes of DOMError rather than 'code'.";
+ case PrefixedRequestAnimationFrame:
+ return "'webkitRequestAnimationFrame' is vendor-specific. Please use the standard 'requestAnimationFrame' instead.";
- case EventReturnValue:
- return "event.returnValue is deprecated. Please use the standard event.preventDefault() instead.";
+ case PrefixedCancelAnimationFrame:
+ return "'webkitCancelAnimationFrame' is vendor-specific. Please use the standard 'cancelAnimationFrame' instead.";
- case ScrollTopBodyNotQuirksMode:
- return "body.scrollTop is deprecated in strict mode. Please use 'documentElement.scrollTop' if in strict mode and 'body.scrollTop' only if in quirks mode.";
+ case PrefixedCancelRequestAnimationFrame:
+ return "'webkitCancelRequestAnimationFrame' is vendor-specific. Please use the standard 'cancelAnimationFrame' instead.";
- case ScrollLeftBodyNotQuirksMode:
- return "body.scrollLeft is deprecated in strict mode. Please use 'documentElement.scrollLeft' if in strict mode and 'body.scrollLeft' only if in quirks mode.";
+ case DocumentCreateAttributeNS:
+ return "'Document.createAttributeNS' is deprecated and has been removed from DOM4 (http://w3.org/tr/dom).";
- case ShowModalDialog:
- return "Chromium is considering deprecating showModalDialog. Please use window.open and postMessage instead.";
+ case AttributeOwnerElement:
+ return "'Attr.ownerElement' is deprecated and has been removed from DOM4 (http://w3.org/tr/dom).";
- case CSSStyleSheetInsertRuleOptionalArg:
- return "Calling CSSStyleSheet.insertRule() with one argument is deprecated. Please pass the index argument as well: insertRule(x, 0).";
+ case ElementSetAttributeNodeNS:
+ return "'Element.setAttributeNodeNS' is deprecated and has been removed from DOM4 (http://w3.org/tr/dom).";
+
+ case NodeIteratorDetach:
+ return "'NodeIterator.detach' is now a no-op, as per DOM (http://dom.spec.whatwg.org/#dom-nodeiterator-detach).";
+
+ case AttrNodeValue:
+ return "'Attr.nodeValue' is deprecated. Please use 'value' instead.";
+
+ case AttrTextContent:
+ return "'Attr.textContent' is deprecated. Please use 'value' instead.";
+
+ case NodeIteratorExpandEntityReferences:
+ return "'NodeIterator.expandEntityReferences' is deprecated and has been removed from DOM. It always returns false.";
+
+ case TreeWalkerExpandEntityReferences:
+ return "'TreeWalker.expandEntityReferences' is deprecated and has been removed from DOM. It always returns false.";
+
+ case RangeDetach:
+ return "'Range.detach' is now a no-op, as per DOM (http://dom.spec.whatwg.org/#dom-range-detach).";
+
+ case DocumentImportNodeOptionalArgument:
+ return "The behavior of importNode() with no boolean argument is about to change from doing a deep clone to doing a shallow clone. "
+ "Make sure to pass an explicit boolean argument to keep your current behavior.";
+
+ case OverflowChangedEvent:
+ return "The 'overflowchanged' event is deprecated and may be removed. Please do not use it.";
+
+ case HTMLHeadElementProfile:
+ return "'HTMLHeadElement.profile' is deprecated. The reflected attribute has no effect.";
+
+ case ElementSetPrefix:
+ return "Setting 'Element.prefix' is deprecated, as it is read-only per DOM (http://dom.spec.whatwg.org/#element).";
+
+ case SyncXHRWithCredentials:
+ return "Setting 'XMLHttpRequest.withCredentials' for synchronous requests is deprecated.";
// Features that aren't deprecated don't have a deprecation message.
default:
@@ -708,8 +774,8 @@ void UseCounter::count(Feature feature)
UseCounter* UseCounter::getFrom(const Document* document)
{
- if (document && document->page())
- return &document->page()->useCounter();
+ if (document && document->frameHost())
+ return &document->frameHost()->useCounter();
return 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/frame/UseCounter.h b/chromium/third_party/WebKit/Source/core/frame/UseCounter.h
index 4f0c2fde527..9e9abca6d1d 100644
--- a/chromium/third_party/WebKit/Source/core/frame/UseCounter.h
+++ b/chromium/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -26,7 +26,7 @@
#ifndef UseCounter_h
#define UseCounter_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "wtf/BitVector.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
@@ -36,7 +36,7 @@
namespace WebCore {
class CSSStyleSheet;
-class DOMWindow;
+class LocalDOMWindow;
class Document;
class ExecutionContext;
class StyleSheetContents;
@@ -59,245 +59,442 @@ public:
~UseCounter();
enum Feature {
- PageDestruction,
- LegacyNotifications,
- MultipartMainResource,
- PrefixedIndexedDB,
- WorkerStart,
- SharedWorkerStart,
- LegacyWebAudio,
- WebAudioStart,
- PrefixedContentSecurityPolicy,
- UnprefixedIndexedDB,
- OpenWebDatabase,
- UnusedSlot01, // Prior to 7/2013, we used this slot for LegacyHTMLNotifications.
- LegacyTextNotifications,
- UnprefixedRequestAnimationFrame,
- PrefixedRequestAnimationFrame,
- ContentSecurityPolicy,
- ContentSecurityPolicyReportOnly,
- PrefixedContentSecurityPolicyReportOnly,
- PrefixedTransitionEndEvent,
- UnprefixedTransitionEndEvent,
- PrefixedAndUnprefixedTransitionEndEvent,
- AutoFocusAttribute,
- UnusedSlot02, // Prior to 4/2013, we used this slot for AutoSaveAttribute.
- DataListElement,
- FormAttribute,
- IncrementalAttribute,
- InputTypeColor,
- InputTypeDate,
- InputTypeDateTime,
- InputTypeDateTimeFallback,
- InputTypeDateTimeLocal,
- InputTypeEmail,
- InputTypeMonth,
- InputTypeNumber,
- InputTypeRange,
- InputTypeSearch,
- InputTypeTel,
- InputTypeTime,
- InputTypeURL,
- InputTypeWeek,
- InputTypeWeekFallback,
- ListAttribute,
- MaxAttribute,
- MinAttribute,
- PatternAttribute,
- PlaceholderAttribute,
- PrecisionAttribute,
- PrefixedDirectoryAttribute,
- PrefixedSpeechAttribute,
- RequiredAttribute,
- ResultsAttribute,
- StepAttribute,
- PageVisits,
- HTMLMarqueeElement,
- UnusedSlot03, // Removed, was tracking overflow: -webkit-marquee.
- Reflection,
- CursorVisibility, // Removed, was -webkit-cursor-visibility.
- StorageInfo,
- XFrameOptions,
- XFrameOptionsSameOrigin,
- XFrameOptionsSameOriginWithBadAncestorChain,
- DeprecatedFlexboxWebContent,
- DeprecatedFlexboxChrome,
- DeprecatedFlexboxChromeExtension,
- UnusedSlot04,
- UnprefixedPerformanceTimeline,
- PrefixedPerformanceTimeline,
- UnprefixedUserTiming,
- PrefixedUserTiming,
- WindowEvent,
- ContentSecurityPolicyWithBaseElement,
- PrefixedMediaAddKey,
- PrefixedMediaGenerateKeyRequest,
- WebAudioLooping,
- DocumentClear,
- PrefixedTransitionMediaFeature,
- SVGFontElement,
- XMLDocument,
- XSLProcessingInstruction,
- XSLTProcessor,
- SVGSwitchElement,
- UnusedSlot05, // Removed, was document.webkitRegister
- HTMLShadowElementOlderShadowRoot,
- DocumentAll,
- FormElement,
- DemotedFormElement,
- CaptureAttributeAsEnum,
- ShadowDOMPrefixedPseudo,
- ShadowDOMPrefixedCreateShadowRoot,
- ShadowDOMPrefixedShadowRoot,
- SVGAnimationElement,
- KeyboardEventKeyLocation,
- CaptureEvents,
- ReleaseEvents,
- CSSDisplayRunIn,
- CSSDisplayCompact,
- LineClamp,
- SubFrameBeforeUnloadRegistered,
- SubFrameBeforeUnloadFired,
- CSSPseudoElementPrefixedDistributed,
- TextReplaceWholeText,
- PrefixedShadowRootConstructor,
- ConsoleMarkTimeline,
- CSSPseudoElementUserAgentCustomPseudo,
- DocumentTypeEntities, // Removed from DOM4.
- DocumentTypeInternalSubset, // Removed from DOM4.
- DocumentTypeNotations, // Removed from DOM4.
- ElementGetAttributeNode, // Removed from DOM4.
- ElementSetAttributeNode, // Removed from DOM4.
- ElementRemoveAttributeNode, // Removed from DOM4.
- ElementGetAttributeNodeNS, // Removed from DOM4.
- DocumentCreateAttribute, // Removed from DOM4.
- DocumentCreateAttributeNS, // Removed from DOM4.
- DocumentCreateCDATASection, // Removed from DOM4.
- DocumentInputEncoding, // Removed from DOM4.
- DocumentXMLEncoding, // Removed from DOM4.
- DocumentXMLStandalone, // Removed from DOM4.
- DocumentXMLVersion, // Removed from DOM4.
- NodeIsSameNode, // Removed from DOM4.
- NodeIsSupported, // Removed from DOM4.
- NodeNamespaceURI, // Removed from DOM4.
- NodePrefix, // Removed from DOM4.
- NodeLocalName, // Removed from DOM4.
- NavigatorProductSub,
- NavigatorVendor,
- NavigatorVendorSub,
- FileError,
- DocumentCharset, // Documented as IE extensions, from KHTML days.
- PrefixedAnimationEndEvent,
- UnprefixedAnimationEndEvent,
- PrefixedAndUnprefixedAnimationEndEvent,
- PrefixedAnimationStartEvent,
- UnprefixedAnimationStartEvent,
- PrefixedAndUnprefixedAnimationStartEvent,
- PrefixedAnimationIterationEvent,
- UnprefixedAnimationIterationEvent,
- PrefixedAndUnprefixedAnimationIterationEvent,
- EventReturnValue, // Legacy IE extension.
- SVGSVGElement,
- SVGAnimateColorElement,
- InsertAdjacentText,
- InsertAdjacentElement,
- HasAttributes, // Removed from DOM4.
- DOMSubtreeModifiedEvent,
- DOMNodeInsertedEvent,
- DOMNodeRemovedEvent,
- DOMNodeRemovedFromDocumentEvent,
- DOMNodeInsertedIntoDocumentEvent,
- DOMCharacterDataModifiedEvent,
- DocumentAllTags,
- DocumentAllLegacyCall,
- HTMLAppletElementLegacyCall,
- HTMLEmbedElementLegacyCall,
- HTMLObjectElementLegacyCall,
- BeforeLoadEvent,
- GetMatchedCSSRules,
- SVGFontInCSS,
- ScrollTopBodyNotQuirksMode,
- ScrollLeftBodyNotQuirksMode,
- AttributeIsId, // Removed in DOM4.
- AttributeOwnerElement, // Removed in DOM4.
- AttributeSetPrefix, // Attribute prefix is readonly in DOM4.
- AttributeSpecified, // Removed in DOM4.
- BeforeLoadEventInIsolatedWorld,
- PrefixedAudioDecodedByteCount,
- PrefixedVideoDecodedByteCount,
- PrefixedVideoSupportsFullscreen,
- PrefixedVideoDisplayingFullscreen,
- PrefixedVideoEnterFullscreen,
- PrefixedVideoExitFullscreen,
- PrefixedVideoEnterFullScreen,
- PrefixedVideoExitFullScreen,
- PrefixedVideoDecodedFrameCount,
- PrefixedVideoDroppedFrameCount,
- SourceElementCandidate,
- SourceElementNonMatchingMedia,
- PrefixedElementRequestFullscreen,
- PrefixedElementRequestFullScreen,
- BarPropLocationbar,
- BarPropMenubar,
- BarPropPersonalbar,
- BarPropScrollbars,
- BarPropStatusbar,
- BarPropToolbar,
- InputTypeEmailMultiple,
- InputTypeEmailMaxLength,
- InputTypeEmailMultipleMaxLength,
- TextTrackCueConstructor,
- CSSStyleDeclarationPropertyName, // Removed in CSSOM.
- CSSStyleDeclarationFloatPropertyName, // Pending removal in CSSOM.
- InputTypeText,
- InputTypeTextMaxLength,
- InputTypePassword,
- InputTypePasswordMaxLength,
- SVGInstanceRoot,
- ShowModalDialog,
- PrefixedPageVisibility,
- HTMLFrameElementLocation,
- CSSStyleSheetInsertRuleOptionalArg, // Inconsistent with the specification and other browsers.
- CSSWebkitRegionAtRule, // @region rule changed to ::region()
- DocumentBeforeUnloadRegistered,
- DocumentBeforeUnloadFired,
- DocumentUnloadRegistered,
- DocumentUnloadFired,
- SVGLocatableNearestViewportElement,
- SVGLocatableFarthestViewportElement,
- IsIndexElement,
- HTMLHeadElementProfile,
- OverflowChangedEvent,
- SVGPointMatrixTransform,
- HTMLHtmlElementManifest,
- DOMFocusInOutEvent,
- FileGetLastModifiedDate,
- HTMLElementInnerText,
- HTMLElementOuterText,
- ReplaceDocumentViaJavaScriptURL,
- ElementSetAttributeNodeNS, // Removed from DOM4.
- ElementPrefixedMatchesSelector,
- DOMImplementationCreateCSSStyleSheet,
- CSSStyleSheetRules,
- CSSStyleSheetAddRule,
- CSSStyleSheetRemoveRule,
+ // Do not change assigned numbers of existing items: add new features
+ // to the end of the list.
+ PageDestruction = 0,
+ PrefixedIndexedDB = 3,
+ WorkerStart = 4,
+ SharedWorkerStart = 5,
+ UnprefixedIndexedDB = 9,
+ OpenWebDatabase = 10,
+ UnprefixedRequestAnimationFrame = 13,
+ PrefixedRequestAnimationFrame = 14,
+ ContentSecurityPolicy = 15,
+ ContentSecurityPolicyReportOnly = 16,
+ PrefixedTransitionEndEvent = 18,
+ UnprefixedTransitionEndEvent = 19,
+ PrefixedAndUnprefixedTransitionEndEvent = 20,
+ AutoFocusAttribute = 21,
+ DataListElement = 23,
+ FormAttribute = 24,
+ IncrementalAttribute = 25,
+ InputTypeColor = 26,
+ InputTypeDate = 27,
+ InputTypeDateTimeFallback = 29,
+ InputTypeDateTimeLocal = 30,
+ InputTypeEmail = 31,
+ InputTypeMonth = 32,
+ InputTypeNumber = 33,
+ InputTypeRange = 34,
+ InputTypeSearch = 35,
+ InputTypeTel = 36,
+ InputTypeTime = 37,
+ InputTypeURL = 38,
+ InputTypeWeek = 39,
+ InputTypeWeekFallback = 40,
+ ListAttribute = 41,
+ MaxAttribute = 42,
+ MinAttribute = 43,
+ PatternAttribute = 44,
+ PlaceholderAttribute = 45,
+ PrefixedDirectoryAttribute = 47,
+ RequiredAttribute = 49,
+ ResultsAttribute = 50,
+ StepAttribute = 51,
+ PageVisits = 52,
+ HTMLMarqueeElement = 53,
+ Reflection = 55,
+ PrefixedStorageInfo = 57,
+ XFrameOptions = 58,
+ XFrameOptionsSameOrigin = 59,
+ XFrameOptionsSameOriginWithBadAncestorChain = 60,
+ DeprecatedFlexboxWebContent = 61,
+ DeprecatedFlexboxChrome = 62,
+ DeprecatedFlexboxChromeExtension = 63,
+ UnprefixedPerformanceTimeline = 65,
+ UnprefixedUserTiming = 67,
+ WindowEvent = 69,
+ ContentSecurityPolicyWithBaseElement = 70,
+ PrefixedMediaAddKey = 71,
+ PrefixedMediaGenerateKeyRequest = 72,
+ DocumentClear = 74,
+ SVGFontElement = 76,
+ XMLDocument = 77,
+ XSLProcessingInstruction = 78,
+ XSLTProcessor = 79,
+ SVGSwitchElement = 80,
+ DocumentAll = 83,
+ FormElement = 84,
+ DemotedFormElement = 85,
+ SVGAnimationElement = 90,
+ KeyboardEventKeyLocation = 91,
+ LineClamp = 96,
+ SubFrameBeforeUnloadRegistered = 97,
+ SubFrameBeforeUnloadFired = 98,
+ TextReplaceWholeText = 100,
+ ConsoleMarkTimeline = 102,
+ CSSPseudoElementUserAgentCustomPseudo = 103,
+ ElementGetAttributeNode = 107, // Removed from DOM4.
+ ElementSetAttributeNode = 108, // Removed from DOM4.
+ ElementRemoveAttributeNode = 109, // Removed from DOM4.
+ ElementGetAttributeNodeNS = 110, // Removed from DOM4.
+ DocumentCreateAttribute = 111, // Removed from DOM4.
+ DocumentCreateAttributeNS = 112, // Removed from DOM4.
+ DocumentCreateCDATASection = 113, // Removed from DOM4.
+ DocumentInputEncoding = 114, // Removed from DOM4.
+ DocumentXMLEncoding = 115, // Removed from DOM4.
+ DocumentXMLStandalone = 116, // Removed from DOM4.
+ DocumentXMLVersion = 117, // Removed from DOM4.
+ NodeIsSameNode = 118, // Removed from DOM4.
+ NodeNamespaceURI = 120, // Removed from DOM4.
+ NodeLocalName = 122, // Removed from DOM4.
+ NavigatorProductSub = 123,
+ NavigatorVendor = 124,
+ NavigatorVendorSub = 125,
+ FileError = 126,
+ DocumentCharset = 127, // Documented as IE extensions = 0, from KHTML days.
+ PrefixedAnimationEndEvent = 128,
+ UnprefixedAnimationEndEvent = 129,
+ PrefixedAndUnprefixedAnimationEndEvent = 130,
+ PrefixedAnimationStartEvent = 131,
+ UnprefixedAnimationStartEvent = 132,
+ PrefixedAndUnprefixedAnimationStartEvent = 133,
+ PrefixedAnimationIterationEvent = 134,
+ UnprefixedAnimationIterationEvent = 135,
+ PrefixedAndUnprefixedAnimationIterationEvent = 136,
+ EventReturnValue = 137, // Legacy IE extension.
+ SVGSVGElement = 138,
+ InsertAdjacentText = 140,
+ InsertAdjacentElement = 141,
+ HasAttributes = 142, // Removed from DOM4.
+ DOMSubtreeModifiedEvent = 143,
+ DOMNodeInsertedEvent = 144,
+ DOMNodeRemovedEvent = 145,
+ DOMNodeRemovedFromDocumentEvent = 146,
+ DOMNodeInsertedIntoDocumentEvent = 147,
+ DOMCharacterDataModifiedEvent = 148,
+ DocumentAllLegacyCall = 150,
+ HTMLAppletElementLegacyCall = 151,
+ HTMLEmbedElementLegacyCall = 152,
+ HTMLObjectElementLegacyCall = 153,
+ GetMatchedCSSRules = 155,
+ SVGFontInCSS = 156,
+ AttributeOwnerElement = 160, // Removed in DOM4.
+ AttributeSpecified = 162, // Removed in DOM4.
+ PrefixedAudioDecodedByteCount = 164,
+ PrefixedVideoDecodedByteCount = 165,
+ PrefixedVideoSupportsFullscreen = 166,
+ PrefixedVideoDisplayingFullscreen = 167,
+ PrefixedVideoEnterFullscreen = 168,
+ PrefixedVideoExitFullscreen = 169,
+ PrefixedVideoEnterFullScreen = 170,
+ PrefixedVideoExitFullScreen = 171,
+ PrefixedVideoDecodedFrameCount = 172,
+ PrefixedVideoDroppedFrameCount = 173,
+ PrefixedElementRequestFullscreen = 176,
+ PrefixedElementRequestFullScreen = 177,
+ BarPropLocationbar = 178,
+ BarPropMenubar = 179,
+ BarPropPersonalbar = 180,
+ BarPropScrollbars = 181,
+ BarPropStatusbar = 182,
+ BarPropToolbar = 183,
+ InputTypeEmailMultiple = 184,
+ InputTypeEmailMaxLength = 185,
+ InputTypeEmailMultipleMaxLength = 186,
+ InputTypeText = 190,
+ InputTypeTextMaxLength = 191,
+ InputTypePassword = 192,
+ InputTypePasswordMaxLength = 193,
+ SVGInstanceRoot = 194,
+ ShowModalDialog = 195,
+ PrefixedPageVisibility = 196,
+ CSSStyleSheetInsertRuleOptionalArg = 198, // Inconsistent with the specification and other browsers.
+ DocumentBeforeUnloadRegistered = 200,
+ DocumentBeforeUnloadFired = 201,
+ DocumentUnloadRegistered = 202,
+ DocumentUnloadFired = 203,
+ SVGLocatableNearestViewportElement = 204,
+ SVGLocatableFarthestViewportElement = 205,
+ HTMLHeadElementProfile = 207,
+ OverflowChangedEvent = 208,
+ SVGPointMatrixTransform = 209,
+ DOMFocusInOutEvent = 211,
+ FileGetLastModifiedDate = 212,
+ HTMLElementInnerText = 213,
+ HTMLElementOuterText = 214,
+ ReplaceDocumentViaJavaScriptURL = 215,
+ ElementSetAttributeNodeNS = 216, // Removed from DOM4.
+ ElementPrefixedMatchesSelector = 217,
+ CSSStyleSheetRules = 219,
+ CSSStyleSheetAddRule = 220,
+ CSSStyleSheetRemoveRule = 221,
+ // The above items are available in M33 branch.
+
+ InitMessageEvent = 222,
+ ElementSetPrefix = 224, // Element.prefix is readonly in DOM4.
+ CSSStyleDeclarationGetPropertyCSSValue = 225,
+ PrefixedMediaCancelKeyRequest = 229,
+ DOMImplementationHasFeature = 230,
+ DOMImplementationHasFeatureReturnFalse = 231,
+ CanPlayTypeKeySystem = 232,
+ PrefixedDevicePixelRatioMediaFeature = 233,
+ PrefixedMaxDevicePixelRatioMediaFeature = 234,
+ PrefixedMinDevicePixelRatioMediaFeature = 235,
+ PrefixedTransform3dMediaFeature = 237,
+ PrefixedStorageQuota = 240,
+ ContentSecurityPolicyReportOnlyInMeta = 241,
+ ResetReferrerPolicy = 243,
+ CaseInsensitiveAttrSelectorMatch = 244, // Case-insensitivity dropped from specification.
+ FormNameAccessForImageElement = 246,
+ FormNameAccessForPastNamesMap = 247,
+ FormAssociationByParser = 248,
+ SVGSVGElementInDocument = 250,
+ SVGDocumentRootElement = 251,
+ MediaErrorEncrypted = 253,
+ EventSourceURL = 254,
+ WebSocketURL = 255,
+ WorkerSubjectToCSP = 257,
+ WorkerAllowedByChildBlockedByScript = 258,
+ DeprecatedWebKitGradient = 260,
+ DeprecatedWebKitLinearGradient = 261,
+ DeprecatedWebKitRepeatingLinearGradient = 262,
+ DeprecatedWebKitRadialGradient = 263,
+ DeprecatedWebKitRepeatingRadialGradient = 264,
+ PrefixedImageSmoothingEnabled = 267,
+ UnprefixedImageSmoothingEnabled = 268,
+ PromiseConstructor = 270,
+ PromiseCast = 271,
+ PromiseReject = 272,
+ PromiseResolve = 273,
+ // The above items are available in M34 branch.
+
+ TextAutosizing = 274,
+ TextAutosizingLayout = 275,
+ HTMLAnchorElementPingAttribute = 276,
+ InsertAdjacentHTML = 278,
+ SVGClassName = 279,
+ HTMLAppletElement = 280,
+ HTMLMediaElementSeekToFragmentStart = 281,
+ HTMLMediaElementPauseAtFragmentEnd = 282,
+ PrefixedWindowURL = 283,
+ PrefixedWorkerURL = 284, // This didn't work because of crbug.com/376039. Available since M37.
+ WindowOrientation = 285,
+ DOMStringListContains = 286,
+ DocumentCaptureEvents = 287,
+ DocumentReleaseEvents = 288,
+ WindowCaptureEvents = 289,
+ WindowReleaseEvents = 290,
+ PrefixedGamepad = 291,
+ ElementAnimateKeyframeListEffectObjectTiming = 292,
+ ElementAnimateKeyframeListEffectDoubleTiming = 293,
+ ElementAnimateKeyframeListEffectNoTiming = 294,
+ DocumentXPathCreateExpression = 295,
+ DocumentXPathCreateNSResolver = 296,
+ DocumentXPathEvaluate = 297,
+ AttrGetValue = 298,
+ AttrSetValue = 299,
+ AnimationConstructorKeyframeListEffectObjectTiming = 300,
+ AnimationConstructorKeyframeListEffectDoubleTiming = 301,
+ AnimationConstructorKeyframeListEffectNoTiming = 302,
+ AttrSetValueWithElement = 303,
+ PrefixedCancelAnimationFrame = 304,
+ PrefixedCancelRequestAnimationFrame = 305,
+ NamedNodeMapGetNamedItem = 306,
+ NamedNodeMapSetNamedItem = 307,
+ NamedNodeMapRemoveNamedItem = 308,
+ NamedNodeMapItem = 309,
+ NamedNodeMapGetNamedItemNS = 310,
+ NamedNodeMapSetNamedItemNS = 311,
+ NamedNodeMapRemoveNamedItemNS = 312,
+ OpenWebDatabaseInWorker = 313, // This didn't work because of crbug.com/376039. Available since M37.
+ OpenWebDatabaseSyncInWorker = 314, // This didn't work because of crbug.com/376039. Available since M37.
+ PrefixedAllowFullscreenAttribute = 315,
+ XHRProgressEventPosition = 316,
+ XHRProgressEventTotalSize = 317,
+ PrefixedDocumentIsFullscreen = 318,
+ PrefixedDocumentFullScreenKeyboardInputAllowed = 319,
+ PrefixedDocumentCurrentFullScreenElement = 320,
+ PrefixedDocumentCancelFullScreen = 321,
+ PrefixedDocumentFullscreenEnabled = 322,
+ PrefixedDocumentFullscreenElement = 323,
+ PrefixedDocumentExitFullscreen = 324,
+ // The above items are available in M35 branch.
+
+ SVGForeignObjectElement = 325,
+ PrefixedElementRequestPointerLock = 326,
+ SelectionSetPosition = 327,
+ AnimationPlayerFinishEvent = 328,
+ SVGSVGElementInXMLDocument = 329,
+ CanvasRenderingContext2DSetAlpha = 330,
+ CanvasRenderingContext2DSetCompositeOperation = 331,
+ CanvasRenderingContext2DSetLineWidth = 332,
+ CanvasRenderingContext2DSetLineCap = 333,
+ CanvasRenderingContext2DSetLineJoin = 334,
+ CanvasRenderingContext2DSetMiterLimit = 335,
+ CanvasRenderingContext2DClearShadow = 336,
+ CanvasRenderingContext2DSetStrokeColor = 337,
+ CanvasRenderingContext2DSetFillColor = 338,
+ CanvasRenderingContext2DDrawImageFromRect = 339,
+ CanvasRenderingContext2DSetShadow = 340,
+ PrefixedPerformanceClearResourceTimings = 341,
+ PrefixedPerformanceSetResourceTimingBufferSize = 342,
+ EventSrcElement = 343,
+ EventCancelBubble = 344,
+ EventPath = 345,
+ EventClipboardData = 346,
+ NodeIteratorDetach = 347,
+ AttrNodeValue = 348,
+ AttrTextContent = 349,
+ EventGetReturnValueTrue = 350,
+ EventGetReturnValueFalse = 351,
+ EventSetReturnValueTrue = 352,
+ EventSetReturnValueFalse = 353,
+ NodeIteratorExpandEntityReferences = 354,
+ TreeWalkerExpandEntityReferences = 355,
+ WindowOffscreenBuffering = 356,
+ WindowDefaultStatus = 357,
+ WindowDefaultstatus = 358,
+ PrefixedConvertPointFromPageToNode = 359,
+ PrefixedConvertPointFromNodeToPage = 360,
+ PrefixedTransitionEventConstructor = 361,
+ PrefixedMutationObserverConstructor = 362,
+ PrefixedIDBCursorConstructor = 363,
+ PrefixedIDBDatabaseConstructor = 364,
+ PrefixedIDBFactoryConstructor = 365,
+ PrefixedIDBIndexConstructor = 366,
+ PrefixedIDBKeyRangeConstructor = 367,
+ PrefixedIDBObjectStoreConstructor = 368,
+ PrefixedIDBRequestConstructor = 369,
+ PrefixedIDBTransactionConstructor = 370,
+ NotificationPermission = 371,
+ RangeDetach = 372,
+ DocumentImportNodeOptionalArgument = 373,
+ HTMLTableElementVspace = 374,
+ HTMLTableElementHspace = 375,
+ PrefixedDocumentExitPointerLock = 376,
+ PrefixedDocumentPointerLockElement = 377,
+ PrefixedTouchRadiusX = 378,
+ PrefixedTouchRadiusY = 379,
+ PrefixedTouchRotationAngle = 380,
+ PrefixedTouchForce = 381,
+ PrefixedMouseEventMovementX = 382,
+ PrefixedMouseEventMovementY = 383,
+ PrefixedWheelEventDirectionInvertedFromDevice = 384,
+ PrefixedWheelEventInit = 385,
+ PrefixedFileRelativePath = 386,
+ DocumentCaretRangeFromPoint = 387,
+ DocumentGetCSSCanvasContext = 388,
+ ElementScrollIntoViewIfNeeded = 389,
+ ElementScrollByLines = 390,
+ ElementScrollByPages = 391,
+ RangeCompareNode = 392,
+ RangeExpand = 393,
+ HTMLFrameElementWidth = 394,
+ HTMLFrameElementHeight = 395,
+ HTMLImageElementX = 396,
+ HTMLImageElementY = 397,
+ HTMLOptionsCollectionRemoveElement = 398,
+ HTMLPreElementWrap = 399,
+ SelectionBaseNode = 400,
+ SelectionBaseOffset = 401,
+ SelectionExtentNode = 402,
+ SelectionExtentOffset = 403,
+ SelectionType = 404,
+ SelectionModify = 405,
+ SelectionSetBaseAndExtent = 406,
+ SelectionEmpty = 407,
+ SVGFEMorphologyElementSetRadius = 408,
+ VTTCue = 409,
+ VTTCueRender = 410,
+ VTTCueRenderVertical = 411,
+ VTTCueRenderSnapToLinesFalse = 412,
+ VTTCueRenderLineNotAuto = 413,
+ VTTCueRenderPositionNot50 = 414,
+ VTTCueRenderSizeNot100 = 415,
+ VTTCueRenderAlignNotMiddle = 416,
+ // The above items are available in M36 branch.
+
+ ElementRequestPointerLock = 417,
+ VTTCueRenderRtl = 418,
+ PostMessageFromSecureToInsecure = 419,
+ PostMessageFromInsecureToSecure = 420,
+ DocumentExitPointerLock = 421,
+ DocumentPointerLockElement = 422,
+ PrefixedCursorZoomIn = 424,
+ PrefixedCursorZoomOut = 425,
+ CSSCharsetRuleEncoding = 426,
+ DocumentSetCharset = 427,
+ DocumentDefaultCharset = 428,
+ TextEncoderConstructor = 429,
+ TextEncoderEncode = 430,
+ TextDecoderConstructor = 431,
+ TextDecoderDecode= 432,
+ FocusInOutEvent = 433,
+ MouseEventMovementX = 434,
+ MouseEventMovementY = 435,
+ MixedContentTextTrack = 436,
+ MixedContentRaw = 437,
+ MixedContentImage = 438,
+ MixedContentMedia = 439,
+ DocumentFonts = 440,
+ MixedContentFormsSubmitted = 441,
+ FormsSubmitted = 442,
+ TextInputEventOnInput = 443,
+ TextInputEventOnTextArea = 444,
+ TextInputEventOnContentEditable= 445,
+ TextInputEventOnNotNode = 446,
+ WebkitBeforeTextInsertedOnInput = 447,
+ WebkitBeforeTextInsertedOnTextArea = 448,
+ WebkitBeforeTextInsertedOnContentEditable = 449,
+ WebkitBeforeTextInsertedOnNotNode = 450,
+ WebkitEditableContentChangedOnInput = 451,
+ WebkitEditableContentChangedOnTextArea = 452,
+ WebkitEditableContentChangedOnContentEditable = 453,
+ WebkitEditableContentChangedOnNotNode = 454,
+ HTMLImports = 455,
+ ElementCreateShadowRoot = 456,
+ DocumentRegisterElement = 457,
+ EditingAppleInterchangeNewline = 458,
+ EditingAppleConvertedSpace = 459,
+ EditingApplePasteAsQuotation = 460,
+ EditingAppleStyleSpanClass = 461,
+ EditingAppleTabSpanClass = 462,
+ HTMLImportsAsyncAttribute = 463,
+ FontFaceSetReady = 464,
+ XMLHttpRequestSynchronous = 465,
+ CSSSelectorPseudoUnresolved = 466,
+ CSSSelectorPseudoShadow = 467,
+ CSSSelectorPseudoContent = 468,
+ CSSSelectorPseudoHost = 469,
+ CSSSelectorPseudoHostContext = 470,
+ CSSDeepCombinator = 471,
+ SyncXHRWithCredentials = 472,
// Add new features immediately above this line. Don't change assigned
- // numbers of each items, and don't reuse unused slots.
+ // numbers of any item, and don't reuse removed slots.
+ // Also, run update_use_counter_feature_enum.py in chromium/src/tools/metrics/histograms/
+ // to update the UMA mapping.
NumberOfFeatures, // This enum value must be last.
};
// "count" sets the bit for this feature to 1. Repeated calls are ignored.
static void count(const Document&, Feature);
- static void count(const DOMWindow*, Feature);
+ // This doesn't count for ExecutionContexts for shared workers and service
+ // workers.
+ static void count(const ExecutionContext*, Feature);
void count(CSSParserContext, CSSPropertyID);
void count(Feature);
// "countDeprecation" sets the bit for this feature to 1, and sends a deprecation
// warning to the console. Repeated calls are ignored.
//
- // Be considerate to developers' consoles: features should only send deprecation warnings
- // when we're actively interested in removing them from the platform.
- static void countDeprecation(const DOMWindow*, Feature);
+ // Be considerate to developers' consoles: features should only send
+ // deprecation warnings when we're actively interested in removing them from
+ // the platform.
+ //
+ // The ExecutionContext* overload doesn't work for shared workers and
+ // service workers.
+ static void countDeprecation(const LocalDOMWindow*, Feature);
static void countDeprecation(ExecutionContext*, Feature);
static void countDeprecation(const Document&, Feature);
String deprecationMessage(Feature);
@@ -310,9 +507,16 @@ public:
static int mapCSSPropertyIdToCSSSampleIdForHistogram(int id);
+ static void muteForInspector();
+ static void unmuteForInspector();
+
private:
+ static int m_muteCount;
+
bool recordMeasurement(Feature feature)
{
+ if (UseCounter::m_muteCount)
+ return false;
ASSERT(feature != PageDestruction); // PageDestruction is reserved as a scaling factor.
ASSERT(feature < NumberOfFeatures);
if (!m_countBits) {
diff --git a/chromium/third_party/WebKit/Source/core/frame/WebKitPoint.idl b/chromium/third_party/WebKit/Source/core/frame/WebKitPoint.idl
index 88b4be2a4ad..bddd6759e0b 100644
--- a/chromium/third_party/WebKit/Source/core/frame/WebKitPoint.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/WebKitPoint.idl
@@ -27,6 +27,7 @@
CustomConstructor,
CustomConstructor(float x, float y),
ImplementedAs=DOMPoint,
+ WillBeGarbageCollected,
] interface WebKitPoint {
attribute float x;
attribute float y;
diff --git a/chromium/third_party/WebKit/Source/core/frame/Window.idl b/chromium/third_party/WebKit/Source/core/frame/Window.idl
index 632e3a26b45..3e75b0b9529 100644
--- a/chromium/third_party/WebKit/Source/core/frame/Window.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/Window.idl
@@ -30,20 +30,22 @@
[
CheckSecurity=Frame,
Custom=ToV8,
- ImplementedAs=DOMWindow,
+ ImplementedAs=LocalDOMWindow,
+ PrimaryGlobal,
+ WillBeGarbageCollected,
] interface Window : EventTarget {
// DOM Level 0
- [Replaceable] readonly attribute Screen screen;
- [Replaceable] readonly attribute History history;
- [Replaceable] readonly attribute BarProp locationbar;
- [Replaceable] readonly attribute BarProp menubar;
- [Replaceable] readonly attribute BarProp personalbar;
- [Replaceable] readonly attribute BarProp scrollbars;
- [Replaceable] readonly attribute BarProp statusbar;
- [Replaceable] readonly attribute BarProp toolbar;
- [Replaceable, PerWorldBindings, ActivityLogging=GetterForIsolatedWorlds] readonly attribute Navigator navigator;
+ readonly attribute Screen screen;
+ readonly attribute History history;
+ [Replaceable, MeasureAs=BarPropLocationbar] readonly attribute BarProp locationbar;
+ [Replaceable, MeasureAs=BarPropMenubar] readonly attribute BarProp menubar;
+ [Replaceable, MeasureAs=BarPropPersonalbar] readonly attribute BarProp personalbar;
+ [Replaceable, MeasureAs=BarPropScrollbars] readonly attribute BarProp scrollbars;
+ [Replaceable, MeasureAs=BarPropStatusbar] readonly attribute BarProp statusbar;
+ [Replaceable, MeasureAs=BarPropToolbar] readonly attribute BarProp toolbar;
+ [LogActivity=GetterOnly] readonly attribute Navigator navigator;
[Replaceable] readonly attribute Navigator clientInformation;
- [DoNotCheckSecurity, Unforgeable, Replaceable, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, PutForwards=href] readonly attribute Location location;
+ [DoNotCheckSecurity, Unforgeable, Replaceable, LogActivity, PutForwards=href] readonly attribute Location location;
[Custom, MeasureAs=WindowEvent, NotEnumerable] attribute Event event;
Selection getSelection();
@@ -61,14 +63,15 @@
DOMString name,
optional DOMString options);
- [Custom] any showModalDialog(DOMString url,
+ [RuntimeEnabled=ShowModalDialog, Custom] any showModalDialog(DOMString url,
optional any dialogArgs,
optional DOMString featureArgs);
- void alert([Default=Undefined] optional DOMString message);
- boolean confirm([Default=Undefined] optional DOMString message);
- [TreatReturnedNullStringAs=Null] DOMString prompt([Default=Undefined] optional DOMString message,
- [TreatNullAs=NullString, TreatUndefinedAs=NullString,Default=Undefined] optional DOMString defaultValue);
+ void alert();
+ void alert(DOMString message);
+ boolean confirm(optional DOMString message = null);
+ [TreatReturnedNullStringAs=Null] DOMString prompt(optional DOMString message = null,
+ optional DOMString defaultValue = null);
boolean find([Default=Undefined] optional DOMString string,
[Default=Undefined] optional boolean caseSensitive,
@@ -78,7 +81,7 @@
[Default=Undefined] optional boolean searchInFrames,
[Default=Undefined] optional boolean showDialog);
- [Replaceable] readonly attribute boolean offscreenBuffering;
+ [Replaceable, MeasureAs=WindowOffscreenBuffering] readonly attribute boolean offscreenBuffering;
[Replaceable] readonly attribute long outerHeight;
[Replaceable] readonly attribute long outerWidth;
@@ -93,9 +96,14 @@
readonly attribute long pageXOffset;
readonly attribute long pageYOffset;
+ // Overloading can be replaced by optional if RuntimeEnabled is removed, by
+ // changing the third argument to *optional* Dictionary scrollOptions
void scrollBy(long x, long y);
+ [RuntimeEnabled=CSSOMSmoothScroll, RaisesException] void scrollBy(long x, long y, Dictionary scrollOptions);
void scrollTo(long x, long y);
+ [RuntimeEnabled=CSSOMSmoothScroll, RaisesException] void scrollTo(long x, long y, Dictionary scrollOptions);
void scroll(long x, long y);
+ [RuntimeEnabled=CSSOMSmoothScroll, RaisesException] void scroll(long x, long y, Dictionary scrollOptions);
void moveBy([Default=Undefined] optional float x, [Default=Undefined] optional float y); // FIXME: this should take longs not floats.
void moveTo([Default=Undefined] optional float x, [Default=Undefined] optional float y); // FIXME: this should take longs not floats.
void resizeBy([Default=Undefined] optional float x, [Default=Undefined] optional float y); // FIXME: this should take longs not floats.
@@ -108,9 +116,9 @@
attribute DOMString name;
attribute DOMString status;
- attribute DOMString defaultStatus;
+ [MeasureAs=WindowDefaultStatus] attribute DOMString defaultStatus;
// This attribute is an alias of defaultStatus and is necessary for legacy uses.
- [ImplementedAs=defaultStatus] attribute DOMString defaultstatus;
+ [ImplementedAs=defaultStatus, MeasureAs=WindowDefaultstatus] attribute DOMString defaultstatus;
// Self referential attributes
[Replaceable, DoNotCheckSecurity] readonly attribute Window self;
@@ -131,42 +139,42 @@
readonly attribute StyleMedia styleMedia;
// DOM Level 2 Style Interface
- [PerWorldBindings] CSSStyleDeclaration getComputedStyle([Default=Undefined] optional Element element,
- [TreatNullAs=NullString, TreatUndefinedAs=NullString,Default=Undefined] optional DOMString pseudoElement);
+ CSSStyleDeclaration getComputedStyle([Default=Undefined] optional Element element,
+ [TreatNullAs=NullString, TreatUndefinedAs=NullString, Default=Undefined] optional DOMString pseudoElement);
// WebKit extensions
- CSSRuleList getMatchedCSSRules([Default=Undefined] optional Element element,
- [TreatNullAs=NullString, TreatUndefinedAs=NullString,Default=Undefined] optional DOMString pseudoElement);
+ [MeasureAs=GetMatchedCSSRules] CSSRuleList getMatchedCSSRules([Default=Undefined] optional Element element,
+ [TreatNullAs=NullString, TreatUndefinedAs=NullString, Default=Undefined] optional DOMString pseudoElement);
[Replaceable] readonly attribute double devicePixelRatio;
- WebKitPoint webkitConvertPointFromPageToNode([Default=Undefined] optional Node node,
- [Default=Undefined] optional WebKitPoint p);
- WebKitPoint webkitConvertPointFromNodeToPage([Default=Undefined] optional Node node,
- [Default=Undefined] optional WebKitPoint p);
+ [MeasureAs=PrefixedConvertPointFromPageToNode] WebKitPoint webkitConvertPointFromPageToNode([Default=Undefined] optional Node node,
+ [Default=Undefined] optional WebKitPoint p);
+ [MeasureAs=PrefixedConvertPointFromNodeToPage] WebKitPoint webkitConvertPointFromNodeToPage([Default=Undefined] optional Node node,
+ [Default=Undefined] optional WebKitPoint p);
- [RuntimeEnabled=ApplicationCache, PerWorldBindings, ActivityLogging=GetterForIsolatedWorlds] readonly attribute ApplicationCache applicationCache;
+ [RuntimeEnabled=ApplicationCache, LogActivity=GetterOnly] readonly attribute ApplicationCache applicationCache;
- [RuntimeEnabled=SessionStorage, PerWorldBindings, ActivityLogging=GetterForIsolatedWorlds, RaisesException=Getter] readonly attribute Storage sessionStorage;
- [RuntimeEnabled=LocalStorage, PerWorldBindings, ActivityLogging=GetterForIsolatedWorlds, RaisesException=Getter] readonly attribute Storage localStorage;
+ [RuntimeEnabled=SessionStorage, LogActivity=GetterOnly, RaisesException=Getter] readonly attribute Storage sessionStorage;
+ [RuntimeEnabled=LocalStorage, LogActivity=GetterOnly, RaisesException=Getter] readonly attribute Storage localStorage;
// This is the interface orientation in degrees. Some examples are:
// 0 is straight up; -90 is when the device is rotated 90 clockwise;
// 90 is when rotated counter clockwise.
- [Conditional=ORIENTATION_EVENTS] readonly attribute long orientation;
+ [RuntimeEnabled=OrientationEvent, MeasureAs=WindowOrientation] readonly attribute long orientation;
[Replaceable] readonly attribute Console console;
// cross-document messaging
- [DoNotCheckSecurity, Custom, RaisesException] void postMessage(SerializedScriptValue message, DOMString targetOrigin, optional Array messagePorts);
+ [DoNotCheckSecurity, Custom, RaisesException] void postMessage(SerializedScriptValue message, DOMString targetOrigin, optional MessagePort[] messagePorts);
[Replaceable] readonly attribute Performance performance;
[MeasureAs=UnprefixedRequestAnimationFrame] long requestAnimationFrame(RequestAnimationFrameCallback callback);
void cancelAnimationFrame(long id);
- [MeasureAs=PrefixedRequestAnimationFrame] long webkitRequestAnimationFrame(RequestAnimationFrameCallback callback);
- [ImplementedAs=cancelAnimationFrame] void webkitCancelAnimationFrame(long id);
- [ImplementedAs=cancelAnimationFrame] void webkitCancelRequestAnimationFrame(long id); // This is a deprecated alias for webkitCancelAnimationFrame(). Remove this when removing vendor prefix.
+ [DeprecateAs=PrefixedRequestAnimationFrame] long webkitRequestAnimationFrame(RequestAnimationFrameCallback callback);
+ [DeprecateAs=PrefixedCancelAnimationFrame, ImplementedAs=cancelAnimationFrame] void webkitCancelAnimationFrame(long id);
+ [DeprecateAs=PrefixedCancelRequestAnimationFrame, ImplementedAs=cancelAnimationFrame] void webkitCancelRequestAnimationFrame(long id);
[Replaceable] readonly attribute CSS CSS;
@@ -174,9 +182,7 @@
[RuntimeEnabled=CSSAnimationUnprefixed] attribute EventHandler onanimationend;
[RuntimeEnabled=CSSAnimationUnprefixed] attribute EventHandler onanimationiteration;
[RuntimeEnabled=CSSAnimationUnprefixed] attribute EventHandler onanimationstart;
- [RuntimeEnabled=DeviceMotion] attribute EventHandler ondevicemotion;
- [RuntimeEnabled=DeviceOrientation] attribute EventHandler ondeviceorientation;
- [Conditional=ORIENTATION_EVENTS] attribute EventHandler onorientationchange;
+ [RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange;
attribute EventHandler onsearch;
[RuntimeEnabled=Touch] attribute EventHandler ontouchcancel;
[RuntimeEnabled=Touch] attribute EventHandler ontouchend;
@@ -187,57 +193,25 @@
attribute EventHandler onwebkitanimationiteration;
attribute EventHandler onwebkitanimationstart;
attribute EventHandler onwebkittransitionend;
- [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onwheel;
+ [LogActivity=SetterOnly] attribute EventHandler onwheel;
- [DeprecateAs=CaptureEvents] void captureEvents();
- [DeprecateAs=ReleaseEvents] void releaseEvents();
+ [MeasureAs=WindowCaptureEvents] void captureEvents();
+ [MeasureAs=WindowReleaseEvents] void releaseEvents();
// Additional constructors.
- attribute TransitionEventConstructor WebKitTransitionEvent;
+ [MeasureAs=PrefixedTransitionEventConstructor] attribute TransitionEventConstructor WebKitTransitionEvent;
[RuntimeEnabled=CSSAnimationUnprefixed] attribute WebKitAnimationEventConstructor AnimationEvent;
- // Mozilla has a separate XMLDocument object for XML documents.
- // We just use Document for this.
- attribute DocumentConstructor XMLDocument;
- attribute URLConstructor webkitURL; // FIXME: deprecate this.
- attribute MutationObserverConstructor WebKitMutationObserver; // FIXME: Add metrics to determine when we can remove this.
- attribute IDBCursorConstructor webkitIDBCursor;
- attribute IDBDatabaseConstructor webkitIDBDatabase;
- attribute IDBFactoryConstructor webkitIDBFactory;
- attribute IDBIndexConstructor webkitIDBIndex;
- attribute IDBKeyRangeConstructor webkitIDBKeyRange;
- attribute IDBObjectStoreConstructor webkitIDBObjectStore;
- attribute IDBRequestConstructor webkitIDBRequest;
- attribute IDBTransactionConstructor webkitIDBTransaction;
-
- // Constructors whose name does not match the interface name.
- // FIXME: Remove these once [ImplementedAs] is used and once constructor names match interface names.
- [RuntimeEnabled=MediaStream] attribute MediaStreamConstructor webkitMediaStream;
- [Conditional=WEB_AUDIO, RuntimeEnabled=WebAudio] attribute AudioContextConstructor webkitAudioContext;
- [Conditional=WEB_AUDIO, RuntimeEnabled=WebAudio] attribute OfflineAudioContextConstructor webkitOfflineAudioContext;
- [RuntimeEnabled=PeerConnection] attribute RTCPeerConnectionConstructor webkitRTCPeerConnection;
- [RuntimeEnabled=ScriptedSpeech] attribute SpeechGrammarConstructor webkitSpeechGrammar;
- [RuntimeEnabled=ScriptedSpeech] attribute SpeechGrammarListConstructor webkitSpeechGrammarList;
- [RuntimeEnabled=ScriptedSpeech] attribute SpeechRecognitionConstructor webkitSpeechRecognition;
- [RuntimeEnabled=ScriptedSpeech] attribute SpeechRecognitionErrorConstructor webkitSpeechRecognitionError;
- [RuntimeEnabled=ScriptedSpeech] attribute SpeechRecognitionEventConstructor webkitSpeechRecognitionEvent;
- [Conditional=WEB_AUDIO] attribute PannerNodeConstructor webkitAudioPannerNode;
-
- // Prefixed ShadowRoot constructor should be phased out eventually, but for the moment it must be always exposed.
- // Unprefixed ShadowRoot constructor should be visible when the feature flag is enabled.
- // FIXME: When it's ready to remove WebKitShadowRoot, get rid of both constructors from Window.idl and remove
- // [NoInterfaceObject] from ShadowRoot interface definition.
- [RuntimeEnabled=ShadowDOM] attribute ShadowRootConstructor ShadowRoot;
- [MeasureAs=PrefixedShadowRootConstructor] attribute ShadowRootConstructor WebKitShadowRoot;
+ [MeasureAs=PrefixedWindowURL] attribute URLConstructor webkitURL; // FIXME: deprecate this.
+ [MeasureAs=PrefixedMutationObserverConstructor] attribute MutationObserverConstructor WebKitMutationObserver;
// window.toString() requires special handling in V8
[DoNotCheckSignature, DoNotCheckSecurity, Custom, NotEnumerable] DOMString toString();
- [ImplementedAs=anonymousIndexedGetter, NotEnumerable] getter Window(unsigned long index);
+ [NotEnumerable] getter Window (unsigned long index);
[Custom, NotEnumerable] getter Window (DOMString name);
};
Window implements GlobalEventHandlers;
-Window implements ImageBitmapFactories;
Window implements WindowBase64;
Window implements WindowEventHandlers;
Window implements WindowTimers;
diff --git a/chromium/third_party/WebKit/Source/core/frame/WindowBase64.idl b/chromium/third_party/WebKit/Source/core/frame/WindowBase64.idl
index 134018ddc3e..c5ed3a6b248 100644
--- a/chromium/third_party/WebKit/Source/core/frame/WindowBase64.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/WindowBase64.idl
@@ -25,10 +25,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#windowbase64
+
[
- ImplementedAs=DOMWindowBase64,
- NoInterfaceObject,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface WindowBase64 {
- [RaisesException] DOMString atob(DOMString string);
[RaisesException] DOMString btoa(DOMString string);
+ [RaisesException] DOMString atob(DOMString string);
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl b/chromium/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl
index b7634ae98bf..95de525822a 100644
--- a/chromium/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/WindowEventHandlers.idl
@@ -27,21 +27,24 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#windoweventhandlers
+
[
- NoInterfaceObject,
- ImplementedAs=DOMWindowEventHandlers
+ ImplementedAs=DOMWindowEventHandlers,
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface WindowEventHandlers {
//attribute EventHandler onafterprint;
//attribute EventHandler onbeforeprint;
attribute EventHandler onbeforeunload;
attribute EventHandler onhashchange;
+ attribute EventHandler onlanguagechange;
attribute EventHandler onmessage;
attribute EventHandler onoffline;
attribute EventHandler ononline;
attribute EventHandler onpagehide;
attribute EventHandler onpageshow;
attribute EventHandler onpopstate;
- attribute EventHandler onresize;
attribute EventHandler onstorage;
attribute EventHandler onunload;
};
diff --git a/chromium/third_party/WebKit/Source/core/frame/WindowTimers.idl b/chromium/third_party/WebKit/Source/core/frame/WindowTimers.idl
index 744567d39e1..47f394fc249 100644
--- a/chromium/third_party/WebKit/Source/core/frame/WindowTimers.idl
+++ b/chromium/third_party/WebKit/Source/core/frame/WindowTimers.idl
@@ -25,13 +25,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#windowtimers
+
[
- NoInterfaceObject,
- ImplementedAs=DOMWindowTimers
+ ImplementedAs=DOMWindowTimers,
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
] interface WindowTimers {
+ // FIXME: currently using [Custom] and |any| because overload algorithm
+ // can't handle Function/DOMString overload properly
+ // http://crbug.com/293561
+ // FIXME: would be clearer as a union type, like:
+ // typedef (Function or DOMString) Handler
+ // Needs spec update and better union support: http://crbug.com/240176
[Custom] long setTimeout(any handler, [Default=Undefined] optional long timeout);
void clearTimeout([Default=Undefined] optional long handle);
[Custom] long setInterval(any handler, [Default=Undefined] optional long timeout);
void clearInterval([Default=Undefined] optional long handle);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationBase.cpp b/chromium/third_party/WebKit/Source/core/frame/animation/AnimationBase.cpp
deleted file mode 100644
index 5dafb2de2fd..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationBase.cpp
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/animation/AnimationBase.h"
-
-#include "core/frame/animation/AnimationControllerPrivate.h"
-#include "core/frame/animation/CompositeAnimation.h"
-#include "core/platform/animation/TimingFunction.h"
-#include "core/rendering/RenderBox.h"
-#include "platform/animation/AnimationUtilities.h"
-#include <algorithm>
-
-using namespace std;
-
-namespace WebCore {
-
-AnimationBase::AnimationBase(const CSSAnimationData* transition, RenderObject& renderer, CompositeAnimation* compAnim)
- : m_animState(AnimationStateNew)
- , m_isAccelerated(false)
- , m_transformFunctionListValid(false)
- , m_filterFunctionListsMatch(false)
- , m_startTime(0)
- , m_pauseTime(-1)
- , m_requestedStartTime(0)
- , m_totalDuration(-1)
- , m_nextIterationDuration(-1)
- , m_object(&renderer)
- , m_animation(const_cast<CSSAnimationData*>(transition))
- , m_compAnim(compAnim)
-{
- // Compute the total duration
- if (m_animation->iterationCount() > 0)
- m_totalDuration = m_animation->duration() * m_animation->iterationCount();
-}
-
-void AnimationBase::setNeedsStyleRecalc(Node* node)
-{
- if (node)
- node->setNeedsStyleRecalc(LocalStyleChange);
-}
-
-double AnimationBase::duration() const
-{
- return m_animation->duration();
-}
-
-bool AnimationBase::playStatePlaying() const
-{
- return m_animation->playState() == AnimPlayStatePlaying;
-}
-
-void AnimationBase::updateStateMachine(AnimStateInput input, double param)
-{
- if (!m_compAnim)
- return;
-
- // If we get AnimationStateInputRestartAnimation then we force a new animation, regardless of state.
- if (input == AnimationStateInputMakeNew) {
- if (m_animState == AnimationStateStartWaitStyleAvailable)
- m_compAnim->animationController()->removeFromAnimationsWaitingForStyle(this);
- m_animState = AnimationStateNew;
- m_startTime = 0;
- m_pauseTime = -1;
- m_requestedStartTime = 0;
- m_nextIterationDuration = -1;
- endAnimation();
- return;
- }
-
- if (input == AnimationStateInputRestartAnimation) {
- if (m_animState == AnimationStateStartWaitStyleAvailable)
- m_compAnim->animationController()->removeFromAnimationsWaitingForStyle(this);
- m_animState = AnimationStateNew;
- m_startTime = 0;
- m_pauseTime = -1;
- m_requestedStartTime = 0;
- m_nextIterationDuration = -1;
- endAnimation();
-
- if (!paused())
- updateStateMachine(AnimationStateInputStartAnimation, -1);
- return;
- }
-
- if (input == AnimationStateInputEndAnimation) {
- if (m_animState == AnimationStateStartWaitStyleAvailable)
- m_compAnim->animationController()->removeFromAnimationsWaitingForStyle(this);
- m_animState = AnimationStateDone;
- endAnimation();
- return;
- }
-
- if (input == AnimationStateInputPauseOverride) {
- if (m_animState == AnimationStateStartWaitResponse) {
- // If we are in AnimationStateStartWaitResponse, the animation will get canceled before
- // we get a response, so move to the next state.
- endAnimation();
- updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
- }
- return;
- }
-
- if (input == AnimationStateInputResumeOverride) {
- if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) {
- // Start the animation
- startAnimation(beginAnimationUpdateTime() - m_startTime);
- }
- return;
- }
-
- // Execute state machine
- switch (m_animState) {
- case AnimationStateNew:
- ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunning || input == AnimationStateInputPlayStatePaused);
- if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunning) {
- m_requestedStartTime = beginAnimationUpdateTime();
- m_animState = AnimationStateStartWaitTimer;
- }
- break;
- case AnimationStateStartWaitTimer:
- ASSERT(input == AnimationStateInputStartTimerFired || input == AnimationStateInputPlayStatePaused);
-
- if (input == AnimationStateInputStartTimerFired) {
- ASSERT(param >= 0);
- // Start timer has fired, tell the animation to start and wait for it to respond with start time
- m_animState = AnimationStateStartWaitStyleAvailable;
- m_compAnim->animationController()->addToAnimationsWaitingForStyle(this);
-
- // Trigger a render so we can start the animation
- if (m_object)
- m_compAnim->animationController()->addNodeChangeToDispatch(m_object->node());
- } else {
- ASSERT(!paused());
- // We're waiting for the start timer to fire and we got a pause. Cancel the timer, pause and wait
- m_pauseTime = beginAnimationUpdateTime();
- m_animState = AnimationStatePausedWaitTimer;
- }
- break;
- case AnimationStateStartWaitStyleAvailable:
- ASSERT(input == AnimationStateInputStyleAvailable || input == AnimationStateInputPlayStatePaused);
-
- if (input == AnimationStateInputStyleAvailable) {
- // Start timer has fired, tell the animation to start and wait for it to respond with start time
- m_animState = AnimationStateStartWaitResponse;
-
- overrideAnimations();
-
- // Start the animation
- if (overridden()) {
- m_animState = AnimationStateStartWaitResponse;
- updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
- } else {
- double timeOffset = 0;
- // If the value for 'animation-delay' is negative then the animation appears to have started in the past.
- if (m_animation->delay() < 0)
- timeOffset = -m_animation->delay();
- startAnimation(timeOffset);
- m_compAnim->animationController()->addToAnimationsWaitingForStartTimeResponse(this, isAccelerated());
- }
- } else {
- // We're waiting for the style to be available and we got a pause. Pause and wait
- m_pauseTime = beginAnimationUpdateTime();
- m_animState = AnimationStatePausedWaitStyleAvailable;
- }
- break;
- case AnimationStateStartWaitResponse:
- ASSERT(input == AnimationStateInputStartTimeSet || input == AnimationStateInputPlayStatePaused);
-
- if (input == AnimationStateInputStartTimeSet) {
- ASSERT(param >= 0);
- // We have a start time, set it, unless the startTime is already set
- if (m_startTime <= 0) {
- m_startTime = param;
- // If the value for 'animation-delay' is negative then the animation appears to have started in the past.
- if (m_animation->delay() < 0)
- m_startTime += m_animation->delay();
- }
-
- // Now that we know the start time, fire the start event.
- onAnimationStart(0); // The elapsedTime is 0.
-
- // Decide whether to go into looping or ending state
- goIntoEndingOrLoopingState();
-
- // Dispatch updateStyleIfNeeded so we can start the animation
- if (m_object)
- m_compAnim->animationController()->addNodeChangeToDispatch(m_object->node());
- } else {
- // We are pausing while waiting for a start response. Cancel the animation and wait. When
- // we unpause, we will act as though the start timer just fired
- m_pauseTime = beginAnimationUpdateTime();
- pauseAnimation(beginAnimationUpdateTime() - m_startTime);
- m_animState = AnimationStatePausedWaitResponse;
- }
- break;
- case AnimationStateLooping:
- ASSERT(input == AnimationStateInputLoopTimerFired || input == AnimationStateInputPlayStatePaused);
-
- if (input == AnimationStateInputLoopTimerFired) {
- ASSERT(param >= 0);
- // Loop timer fired, loop again or end.
- onAnimationIteration(param);
-
- // Decide whether to go into looping or ending state
- goIntoEndingOrLoopingState();
- } else {
- // We are pausing while running. Cancel the animation and wait
- m_pauseTime = beginAnimationUpdateTime();
- pauseAnimation(beginAnimationUpdateTime() - m_startTime);
- m_animState = AnimationStatePausedRun;
- }
- break;
- case AnimationStateEnding:
-#if !LOG_DISABLED
- if (input != AnimationStateInputEndTimerFired && input != AnimationStateInputPlayStatePaused)
- WTF_LOG_ERROR("State is AnimationStateEnding, but input is not AnimationStateInputEndTimerFired or AnimationStateInputPlayStatePaused. It is %d.", input);
-#endif
- if (input == AnimationStateInputEndTimerFired) {
-
- ASSERT(param >= 0);
- // End timer fired, finish up
- onAnimationEnd(param);
-
- m_animState = AnimationStateDone;
-
- if (m_object) {
- if (m_animation->fillsForwards())
- m_animState = AnimationStateFillingForwards;
- else
- resumeOverriddenAnimations();
-
- // Fire off another style change so we can set the final value
- m_compAnim->animationController()->addNodeChangeToDispatch(m_object->node());
- }
- } else {
- // We are pausing while running. Cancel the animation and wait
- m_pauseTime = beginAnimationUpdateTime();
- pauseAnimation(beginAnimationUpdateTime() - m_startTime);
- m_animState = AnimationStatePausedRun;
- }
- // |this| may be deleted here
- break;
- case AnimationStatePausedWaitTimer:
- ASSERT(input == AnimationStateInputPlayStateRunning);
- ASSERT(paused());
- // Update the times
- m_startTime += beginAnimationUpdateTime() - m_pauseTime;
- m_pauseTime = -1;
-
- // we were waiting for the start timer to fire, go back and wait again
- m_animState = AnimationStateNew;
- updateStateMachine(AnimationStateInputStartAnimation, 0);
- break;
- case AnimationStatePausedWaitResponse:
- case AnimationStatePausedWaitStyleAvailable:
- case AnimationStatePausedRun:
- // We treat these two cases the same. The only difference is that, when we are in
- // AnimationStatePausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation.
- // When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice
- // that we have already set the startTime and will ignore it.
- ASSERT(input == AnimationStateInputPlayStateRunning || input == AnimationStateInputStartTimeSet || input == AnimationStateInputStyleAvailable);
- ASSERT(paused());
-
- if (input == AnimationStateInputPlayStateRunning) {
- // Update the times
- if (m_animState == AnimationStatePausedRun)
- m_startTime += beginAnimationUpdateTime() - m_pauseTime;
- else
- m_startTime = 0;
- m_pauseTime = -1;
-
- if (m_animState == AnimationStatePausedWaitStyleAvailable)
- m_animState = AnimationStateStartWaitStyleAvailable;
- else {
- // We were either running or waiting for a begin time response from the animation.
- // Either way we need to restart the animation (possibly with an offset if we
- // had already been running) and wait for it to start.
- m_animState = AnimationStateStartWaitResponse;
-
- // Start the animation
- if (overridden()) {
- updateStateMachine(AnimationStateInputStartTimeSet, beginAnimationUpdateTime());
- } else {
- startAnimation(beginAnimationUpdateTime() - m_startTime);
- m_compAnim->animationController()->addToAnimationsWaitingForStartTimeResponse(this, isAccelerated());
- }
- }
- break;
- }
-
- if (input == AnimationStateInputStartTimeSet) {
- ASSERT(m_animState == AnimationStatePausedWaitResponse);
-
- // We are paused but we got the callback that notifies us that an accelerated animation started.
- // We ignore the start time and just move into the paused-run state.
- m_animState = AnimationStatePausedRun;
- ASSERT(m_startTime == 0);
- m_startTime = param;
- m_pauseTime += m_startTime;
- break;
- }
-
- ASSERT(m_animState == AnimationStatePausedWaitStyleAvailable);
- // We are paused but we got the callback that notifies us that style has been updated.
- // We move to the AnimationStatePausedWaitResponse state
- m_animState = AnimationStatePausedWaitResponse;
- overrideAnimations();
- break;
- case AnimationStateFillingForwards:
- case AnimationStateDone:
- // We're done. Stay in this state until we are deleted
- break;
- }
-}
-
-void AnimationBase::fireAnimationEventsIfNeeded()
-{
- if (!m_compAnim)
- return;
-
- // If we are waiting for the delay time to expire and it has, go to the next state
- if (m_animState != AnimationStateStartWaitTimer && m_animState != AnimationStateLooping && m_animState != AnimationStateEnding)
- return;
-
- // We have to make sure to keep a ref to the this pointer, because it could get destroyed
- // during an animation callback that might get called. Since the owner is a CompositeAnimation
- // and it ref counts this object, we will keep a ref to that instead. That way the AnimationBase
- // can still access the resources of its CompositeAnimation as needed.
- RefPtr<AnimationBase> protector(this);
- RefPtr<CompositeAnimation> compProtector(m_compAnim);
-
- // Check for start timeout
- if (m_animState == AnimationStateStartWaitTimer) {
- if (beginAnimationUpdateTime() - m_requestedStartTime >= m_animation->delay())
- updateStateMachine(AnimationStateInputStartTimerFired, 0);
- return;
- }
-
- double elapsedDuration = getElapsedTime();
-
- // Check for end timeout
- if (m_totalDuration >= 0 && elapsedDuration >= m_totalDuration) {
- // We may still be in AnimationStateLooping if we've managed to skip a
- // whole iteration, in which case we should jump to the end state.
- m_animState = AnimationStateEnding;
-
- // Fire an end event
- updateStateMachine(AnimationStateInputEndTimerFired, m_totalDuration);
- } else {
- // Check for iteration timeout
- if (m_nextIterationDuration < 0) {
- // Hasn't been set yet, set it
- double durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
- m_nextIterationDuration = elapsedDuration + durationLeft;
- }
-
- if (elapsedDuration >= m_nextIterationDuration) {
- // Set to the next iteration
- double previous = m_nextIterationDuration;
- double durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
- m_nextIterationDuration = elapsedDuration + durationLeft;
-
- // Send the event
- updateStateMachine(AnimationStateInputLoopTimerFired, previous);
- }
- }
-}
-
-void AnimationBase::updatePlayState(EAnimPlayState playState)
-{
- if (!m_compAnim)
- return;
-
- // Set the state machine to the desired state.
- bool pause = playState == AnimPlayStatePaused;
-
- if (pause == paused() && !isNew())
- return;
-
- updateStateMachine(pause ? AnimationStateInputPlayStatePaused : AnimationStateInputPlayStateRunning, -1);
-}
-
-double AnimationBase::timeToNextService()
-{
- // Returns the time at which next service is required. -1 means no service is required. 0 means
- // service is required now, and > 0 means service is required that many seconds in the future.
- if (paused() || isNew() || m_animState == AnimationStateFillingForwards)
- return -1;
-
- if (m_animState == AnimationStateStartWaitTimer) {
- double timeFromNow = m_animation->delay() - (beginAnimationUpdateTime() - m_requestedStartTime);
- return max(timeFromNow, 0.0);
- }
-
- fireAnimationEventsIfNeeded();
-
- // In all other cases, we need service right away.
- return 0;
-}
-
-// Compute the fractional time, taking into account direction.
-// There is no need to worry about iterations, we assume that we would have
-// short circuited above if we were done.
-
-double AnimationBase::fractionalTime(double scale, double elapsedTime, double offset) const
-{
- double fractionalTime = m_animation->duration() ? (elapsedTime / m_animation->duration()) : 1;
- // FIXME: startTime can be before the current animation "frame" time. This is to sync with the frame time
- // concept in AnimationTimeController. So we need to somehow sync the two. Until then, the possible
- // error is small and will probably not be noticeable. Until we fix this, remove the assert.
- // https://bugs.webkit.org/show_bug.cgi?id=52037
- // ASSERT(fractionalTime >= 0);
- if (fractionalTime < 0)
- fractionalTime = 0;
-
- int integralTime = static_cast<int>(fractionalTime);
- const int integralIterationCount = static_cast<int>(m_animation->iterationCount());
- const bool iterationCountHasFractional = m_animation->iterationCount() - integralIterationCount;
- if (m_animation->iterationCount() != CSSAnimationData::IterationCountInfinite && !iterationCountHasFractional)
- integralTime = min(integralTime, integralIterationCount - 1);
-
- fractionalTime -= integralTime;
-
- // Thie method can be called with an elapsedTime which very slightly
- // exceeds the end of the animation. In this case, clamp the
- // fractionalTime.
- if (fractionalTime > 1)
- fractionalTime = 1;
- ASSERT(fractionalTime >= 0 && fractionalTime <= 1);
-
- if (((m_animation->direction() == CSSAnimationData::AnimationDirectionAlternate) && (integralTime & 1))
- || ((m_animation->direction() == CSSAnimationData::AnimationDirectionAlternateReverse) && !(integralTime & 1))
- || m_animation->direction() == CSSAnimationData::AnimationDirectionReverse)
- fractionalTime = 1 - fractionalTime;
-
- fractionalTime -= offset;
- // Note that if fractionalTime == 0 here, scale may be infinity, but in
- // this case we don't need to apply scale anyway.
- if (scale != 1.0 && fractionalTime) {
- ASSERT(scale >= 0 && !std::isinf(scale));
- fractionalTime *= scale;
- }
-
- ASSERT(fractionalTime >= 0 && fractionalTime <= 1);
- return fractionalTime;
-}
-
-double AnimationBase::progress(double scale, double offset, const TimingFunction* timingFunction) const
-{
- if (preActive())
- return 0;
-
- double dur = m_animation->duration();
- if (m_animation->iterationCount() > 0)
- dur *= m_animation->iterationCount();
-
- if (postActive() || !m_animation->duration())
- return 1.0;
-
- double elapsedTime = getElapsedTime();
- if (m_animation->iterationCount() > 0 && elapsedTime >= dur) {
- const int integralIterationCount = static_cast<int>(m_animation->iterationCount());
- const bool iterationCountHasFractional = m_animation->iterationCount() - integralIterationCount;
- return (integralIterationCount % 2 || iterationCountHasFractional) ? 1.0 : 0.0;
- }
-
- const double fractionalTime = this->fractionalTime(scale, elapsedTime, offset);
-
- if (!timingFunction)
- timingFunction = m_animation->timingFunction();
-
- return timingFunction->evaluate(fractionalTime, accuracyForDuration(m_animation->duration()));
-}
-
-void AnimationBase::getTimeToNextEvent(double& time, bool& isLooping) const
-{
- if (postActive()) {
- time = -1;
- isLooping = false;
- return;
- }
-
- // Decide when the end or loop event needs to fire
- const double elapsedDuration = getElapsedTime();
- double durationLeft = 0;
- double nextIterationTime = m_totalDuration;
-
- if (m_totalDuration < 0 || elapsedDuration < m_totalDuration) {
- durationLeft = m_animation->duration() > 0 ? (m_animation->duration() - fmod(elapsedDuration, m_animation->duration())) : 0;
- nextIterationTime = elapsedDuration + durationLeft;
- }
-
- if (m_totalDuration < 0 || nextIterationTime < m_totalDuration) {
- // We are not at the end yet
- ASSERT(m_totalDuration < 0 || nextIterationTime > 0);
- isLooping = true;
- } else {
- // We are at the end
- isLooping = false;
- }
-
- time = durationLeft;
-}
-
-void AnimationBase::goIntoEndingOrLoopingState()
-{
- double t;
- bool isLooping;
- getTimeToNextEvent(t, isLooping);
- m_animState = isLooping ? AnimationStateLooping : AnimationStateEnding;
-}
-
-void AnimationBase::freezeAtTime(double t)
-{
- if (!m_compAnim)
- return;
-
- if (!m_startTime) {
- // If we haven't started yet, make it as if we started.
- m_animState = AnimationStateStartWaitResponse;
- onAnimationStartResponse(beginAnimationUpdateTime());
- }
-
- ASSERT(m_startTime); // if m_startTime is zero, we haven't started yet, so we'll get a bad pause time.
- if (t <= m_animation->delay())
- m_pauseTime = m_startTime;
- else
- m_pauseTime = m_startTime + t - m_animation->delay();
-
- // It is possible that m_isAccelerated is true and m_object->compositingState() is NotComposited, because of style change.
- // So, both conditions need to be checked.
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
- pauseAnimation(t);
-}
-
-double AnimationBase::beginAnimationUpdateTime() const
-{
- if (!m_compAnim)
- return 0;
-
- return m_compAnim->animationController()->beginAnimationUpdateTime();
-}
-
-double AnimationBase::getElapsedTime() const
-{
- ASSERT(!postActive());
- if (paused())
- return m_pauseTime - m_startTime;
- if (m_startTime <= 0)
- return 0;
-
- double elapsedTime = beginAnimationUpdateTime() - m_startTime;
- // It's possible for the start time to be ahead of the last update time
- // if the compositor has just sent notification for the start of an
- // accelerated animation.
- return max(elapsedTime, 0.0);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationBase.h b/chromium/third_party/WebKit/Source/core/frame/animation/AnimationBase.h
deleted file mode 100644
index 6ab1d5801e4..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationBase.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AnimationBase_h
-#define AnimationBase_h
-
-#include "CSSPropertyNames.h"
-#include "core/platform/animation/CSSAnimationData.h"
-#include "core/rendering/style/RenderStyleConstants.h"
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-class AnimationBase;
-class AnimationController;
-class CompositeAnimation;
-class Element;
-class Node;
-class RenderObject;
-class RenderStyle;
-class TimingFunction;
-
-class AnimationBase : public RefCounted<AnimationBase> {
- friend class CompositeAnimation;
- friend class CSSPropertyAnimation;
-
-public:
- AnimationBase(const CSSAnimationData* transition, RenderObject& renderer, CompositeAnimation* compAnim);
- virtual ~AnimationBase() { }
-
- RenderObject* renderer() const { return m_object; }
- void clear()
- {
- endAnimation();
- m_object = 0;
- m_compAnim = 0;
- }
-
- double duration() const;
-
- // Animations and Transitions go through the states below. When entering the STARTED state
- // the animation is started. This may or may not require deferred response from the animator.
- // If so, we stay in this state until that response is received (and it returns the start time).
- // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping
- // or AnimationStateEnding.
- enum AnimState {
- AnimationStateNew, // animation just created, animation not running yet
- AnimationStateStartWaitTimer, // start timer running, waiting for fire
- AnimationStateStartWaitStyleAvailable, // waiting for style setup so we can start animations
- AnimationStateStartWaitResponse, // animation started, waiting for response
- AnimationStateLooping, // response received, animation running, loop timer running, waiting for fire
- AnimationStateEnding, // received, animation running, end timer running, waiting for fire
- AnimationStatePausedWaitTimer, // in pause mode when animation started
- AnimationStatePausedWaitStyleAvailable, // in pause mode when waiting for style setup
- AnimationStatePausedWaitResponse, // animation paused when in STARTING state
- AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state
- AnimationStateDone, // end timer fired, animation finished and removed
- AnimationStateFillingForwards // animation has ended and is retaining its final value
- };
-
- enum AnimStateInput {
- AnimationStateInputMakeNew, // reset back to new from any state
- AnimationStateInputStartAnimation, // animation requests a start
- AnimationStateInputRestartAnimation, // force a restart from any state
- AnimationStateInputStartTimerFired, // start timer fired
- AnimationStateInputStyleAvailable, // style is setup, ready to start animating
- AnimationStateInputStartTimeSet, // m_startTime was set
- AnimationStateInputLoopTimerFired, // loop timer fired
- AnimationStateInputEndTimerFired, // end timer fired
- AnimationStateInputPauseOverride, // pause an animation due to override
- AnimationStateInputResumeOverride, // resume an overridden animation
- AnimationStateInputPlayStateRunning, // play state paused -> running
- AnimationStateInputPlayStatePaused, // play state running -> paused
- AnimationStateInputEndAnimation // force an end from any state
- };
-
- // Called when animation is in AnimationStateNew to start animation
- void updateStateMachine(AnimStateInput, double param);
-
- // Animation has actually started, at passed time
- void onAnimationStartResponse(double startTime)
- {
- updateStateMachine(AnimationBase::AnimationStateInputStartTimeSet, startTime);
- }
-
- // Called to change to or from paused state
- void updatePlayState(EAnimPlayState);
- bool playStatePlaying() const;
-
- bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; }
- bool preActive() const
- {
- return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse;
- }
-
- bool postActive() const { return m_animState == AnimationStateDone; }
- bool active() const { return !postActive() && !preActive(); }
- bool running() const { return !isNew() && !postActive(); }
- bool paused() const { return m_pauseTime >= 0; }
- bool isNew() const { return m_animState == AnimationStateNew; }
- bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; }
- bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; }
-
- virtual double timeToNextService();
-
- double progress(double scale, double offset, const TimingFunction*) const;
-
- virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* /*currentStyle*/, RenderStyle* /*targetStyle*/, RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
- virtual void getAnimatedStyle(RefPtr<RenderStyle>& /*animatedStyle*/) = 0;
-
- virtual bool shouldFireEvents() const { return false; }
-
- void fireAnimationEventsIfNeeded();
-
- void setAnimation(const CSSAnimationData* anim) { m_animation = const_cast<CSSAnimationData*>(anim); }
-
- // Return true if this animation is overridden. This will only be the case for
- // ImplicitAnimations and is used to determine whether or not we should force
- // set the start time. If an animation is overridden, it will probably not get
- // back the AnimationStateInputStartTimeSet input.
- virtual bool overridden() const { return false; }
-
- // Does this animation/transition involve the given property?
- virtual bool affectsProperty(CSSPropertyID /*property*/) const { return false; }
-
- bool isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, bool isRunningNow) const
- {
- if (acceleratedOnly && !m_isAccelerated)
- return false;
-
- if (isRunningNow)
- return (!waitingToStart() && !postActive()) && affectsProperty(property);
-
- return !postActive() && affectsProperty(property);
- }
-
- // FIXME: rename this using the "lists match" terminology.
- bool isTransformFunctionListValid() const { return m_transformFunctionListValid; }
- bool filterFunctionListsMatch() const { return m_filterFunctionListsMatch; }
-
- // Freeze the animation; used by DumpRenderTree.
- void freezeAtTime(double t);
-
- double beginAnimationUpdateTime() const;
-
- double getElapsedTime() const;
-
- void styleAvailable()
- {
- ASSERT(waitingForStyleAvailable());
- updateStateMachine(AnimationBase::AnimationStateInputStyleAvailable, -1);
- }
-
- const CSSAnimationData* animation() const { return m_animation.get(); }
-
-protected:
- virtual void overrideAnimations() { }
- virtual void resumeOverriddenAnimations() { }
-
- CompositeAnimation* compositeAnimation() { return m_compAnim; }
-
- // These are called when the corresponding timer fires so subclasses can do any extra work
- virtual void onAnimationStart(double /*elapsedTime*/) { }
- virtual void onAnimationIteration(double /*elapsedTime*/) { }
- virtual void onAnimationEnd(double /*elapsedTime*/) { }
-
- // timeOffset is an offset from the current time when the animation should start. Negative values are OK.
- virtual void startAnimation(double /*timeOffset*/) { }
- // timeOffset is the time at which the animation is being paused.
- virtual void pauseAnimation(double /*timeOffset*/) { }
- virtual void endAnimation() { }
-
- void goIntoEndingOrLoopingState();
-
- bool isAccelerated() const { return m_isAccelerated; }
-
- static void setNeedsStyleRecalc(Node*);
-
- void getTimeToNextEvent(double& time, bool& isLooping) const;
-
- double fractionalTime(double scale, double elapsedTime, double offset) const;
-
- AnimState m_animState;
-
- bool m_isAccelerated;
- bool m_transformFunctionListValid;
- bool m_filterFunctionListsMatch;
- double m_startTime;
- double m_pauseTime;
- double m_requestedStartTime;
-
- double m_totalDuration;
- double m_nextIterationDuration;
-
- RenderObject* m_object;
-
- RefPtr<CSSAnimationData> m_animation;
- CompositeAnimation* m_compAnim;
-};
-
-} // namespace WebCore
-
-#endif // AnimationBase_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationController.cpp b/chromium/third_party/WebKit/Source/core/frame/animation/AnimationController.cpp
deleted file mode 100644
index 8521e139a08..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationController.cpp
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/animation/AnimationController.h"
-
-#include "core/dom/PseudoElement.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/events/TransitionEvent.h"
-#include "core/events/WebKitAnimationEvent.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
-#include "core/frame/animation/AnimationBase.h"
-#include "core/frame/animation/AnimationControllerPrivate.h"
-#include "core/frame/animation/CSSPropertyAnimation.h"
-#include "core/frame/animation/CompositeAnimation.h"
-#include "core/rendering/RenderView.h"
-#include "wtf/CurrentTime.h"
-
-namespace WebCore {
-
-static const double cBeginAnimationUpdateTimeNotSet = -1;
-
-AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame)
- : m_animationTimer(this, &AnimationControllerPrivate::animationTimerFired)
- , m_updateStyleIfNeededDispatcher(this, &AnimationControllerPrivate::updateStyleIfNeededDispatcherFired)
- , m_frame(frame)
- , m_beginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet)
- , m_animationsWaitingForStyle()
- , m_animationsWaitingForStartTimeResponse()
- , m_animationsWaitingForAsyncStartNotification()
-{
-}
-
-AnimationControllerPrivate::~AnimationControllerPrivate()
-{
-}
-
-PassRefPtr<CompositeAnimation> AnimationControllerPrivate::accessCompositeAnimation(RenderObject& renderer)
-{
- RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(&renderer);
- if (!animation) {
- animation = CompositeAnimation::create(this);
- m_compositeAnimations.set(&renderer, animation);
- }
- return animation;
-}
-
-bool AnimationControllerPrivate::clear(RenderObject* renderer)
-{
- // Return false if we didn't do anything.
- PassRefPtr<CompositeAnimation> animation = m_compositeAnimations.take(renderer);
- if (!animation)
- return false;
- animation->clearRenderer();
- return true;
-}
-
-void AnimationControllerPrivate::updateAnimations(double& timeToNextService, double& timeToNextEvent, SetNeedsStyleRecalc callSetNeedsStyleRecalc/* = DoNotCallSetNeedsStyleRecalc*/)
-{
- double minTimeToNextService = -1;
- double minTimeToNextEvent = -1;
- bool updateStyleNeeded = false;
-
- RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
- for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
- CompositeAnimation* compAnim = it->value.get();
- if (compAnim->hasAnimations()) {
- double t = compAnim->timeToNextService();
- if (t != -1 && (t < minTimeToNextService || minTimeToNextService == -1))
- minTimeToNextService = t;
- double nextEvent = compAnim->timeToNextEvent();
- if (nextEvent != -1 && (nextEvent < minTimeToNextEvent || minTimeToNextEvent == -1))
- minTimeToNextEvent = nextEvent;
- if (callSetNeedsStyleRecalc == CallSetNeedsStyleRecalc) {
- if (!t) {
- Node* node = it->key->node();
- node->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
- updateStyleNeeded = true;
- }
- } else if (!minTimeToNextService && !minTimeToNextEvent) {
- // Found the minimum values and do not need to mark for style recalc.
- break;
- }
- }
- }
-
- if (updateStyleNeeded)
- m_frame->document()->updateStyleIfNeeded();
-
- timeToNextService = minTimeToNextService;
- timeToNextEvent = minTimeToNextEvent;
-}
-
-void AnimationControllerPrivate::scheduleServiceForRenderer(RenderObject& renderer)
-{
- double timeToNextService = -1;
- double timeToNextEvent = -1;
-
- RefPtr<CompositeAnimation> compAnim = m_compositeAnimations.get(&renderer);
- if (compAnim->hasAnimations()) {
- timeToNextService = compAnim->timeToNextService();
- timeToNextEvent = compAnim->timeToNextEvent();
- }
-
- if (timeToNextService >= 0)
- scheduleService(timeToNextService, timeToNextEvent);
-}
-
-void AnimationControllerPrivate::scheduleService()
-{
- double timeToNextService = -1;
- double timeToNextEvent = -1;
- updateAnimations(timeToNextService, timeToNextEvent, DoNotCallSetNeedsStyleRecalc);
- scheduleService(timeToNextService, timeToNextEvent);
-}
-
-void AnimationControllerPrivate::scheduleService(double timeToNextService, double timeToNextEvent)
-{
- if (!m_frame->page())
- return;
-
- bool visible = m_frame->page()->visibilityState() == WebCore::PageVisibilityStateVisible;
-
- // This std::max to 1 second limits how often we service animations on background tabs.
- // Without this, plus and gmail were recalculating style as every 200ms or even more
- // often, burning CPU needlessly for background tabs.
- // FIXME: Do we want to fire events at all on background tabs?
- if (!visible)
- timeToNextService = std::max(timeToNextEvent, 1.0);
-
- if (visible && !timeToNextService) {
- m_frame->document()->view()->scheduleAnimation();
- if (m_animationTimer.isActive())
- m_animationTimer.stop();
- return;
- }
-
- if (timeToNextService < 0) {
- if (m_animationTimer.isActive())
- m_animationTimer.stop();
- return;
- }
-
- if (m_animationTimer.isActive() && m_animationTimer.nextFireInterval() <= timeToNextService)
- return;
-
- m_animationTimer.startOneShot(timeToNextService);
-}
-
-void AnimationControllerPrivate::updateStyleIfNeededDispatcherFired(Timer<AnimationControllerPrivate>*)
-{
- fireEventsAndUpdateStyle();
-}
-
-void AnimationControllerPrivate::fireEventsAndUpdateStyle()
-{
- // Protect the frame from getting destroyed in the event handler
- RefPtr<Frame> protector = m_frame;
-
- bool updateStyle = !m_eventsToDispatch.isEmpty() || !m_nodeChangesToDispatch.isEmpty();
-
- // fire all the events
- Vector<EventToDispatch> eventsToDispatch = m_eventsToDispatch;
- m_eventsToDispatch.clear();
- Vector<EventToDispatch>::const_iterator eventsToDispatchEnd = eventsToDispatch.end();
- for (Vector<EventToDispatch>::const_iterator it = eventsToDispatch.begin(); it != eventsToDispatchEnd; ++it) {
- Element* element = it->element.get();
- if (it->eventType == EventTypeNames::transitionend)
- element->dispatchEvent(TransitionEvent::create(it->eventType, it->name, it->elapsedTime, PseudoElement::pseudoElementNameForEvents(element->pseudoId())));
- else
- element->dispatchEvent(WebKitAnimationEvent::create(it->eventType, it->name, it->elapsedTime));
- }
-
- // call setChanged on all the elements
- Vector<RefPtr<Node> >::const_iterator nodeChangesToDispatchEnd = m_nodeChangesToDispatch.end();
- for (Vector<RefPtr<Node> >::const_iterator it = m_nodeChangesToDispatch.begin(); it != nodeChangesToDispatchEnd; ++it)
- (*it)->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
-
- m_nodeChangesToDispatch.clear();
-
- if (updateStyle && m_frame)
- m_frame->document()->updateStyleIfNeeded();
-}
-
-void AnimationControllerPrivate::startUpdateStyleIfNeededDispatcher()
-{
- if (!m_updateStyleIfNeededDispatcher.isActive())
- m_updateStyleIfNeededDispatcher.startOneShot(0);
-}
-
-void AnimationControllerPrivate::addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime)
-{
- m_eventsToDispatch.grow(m_eventsToDispatch.size()+1);
- EventToDispatch& event = m_eventsToDispatch[m_eventsToDispatch.size()-1];
- event.element = element;
- event.eventType = eventType;
- event.name = name;
- event.elapsedTime = elapsedTime;
-
- startUpdateStyleIfNeededDispatcher();
-}
-
-void AnimationControllerPrivate::addNodeChangeToDispatch(PassRefPtr<Node> node)
-{
- if (!node)
- return;
-
- m_nodeChangesToDispatch.append(node);
- startUpdateStyleIfNeededDispatcher();
-}
-
-void AnimationControllerPrivate::serviceAnimations()
-{
- double timeToNextService = -1;
- double timeToNextEvent = -1;
- updateAnimations(timeToNextService, timeToNextEvent, CallSetNeedsStyleRecalc);
- scheduleService(timeToNextService, timeToNextEvent);
-
- // Fire events right away, to avoid a flash of unanimated style after an animation completes, and before
- // the 'end' event fires.
- fireEventsAndUpdateStyle();
-}
-
-void AnimationControllerPrivate::animationTimerFired(Timer<AnimationControllerPrivate>*)
-{
- // Make sure animationUpdateTime is updated, so that it is current even if no
- // styleChange has happened (e.g. accelerated animations)
- setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
- serviceAnimations();
-}
-
-bool AnimationControllerPrivate::isRunningAnimationOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const
-{
- RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);
- if (!animation)
- return false;
-
- return animation->isAnimatingProperty(property, false, isRunningNow);
-}
-
-bool AnimationControllerPrivate::isRunningAcceleratableAnimationOnRenderer(RenderObject *renderer) const
-{
- RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);
- if (!animation)
- return false;
-
- bool acceleratedOnly = false;
- bool isRunningNow = true;
- return animation->isAnimatingProperty(CSSPropertyOpacity, acceleratedOnly, isRunningNow)
- || animation->isAnimatingProperty(CSSPropertyWebkitTransform, acceleratedOnly, isRunningNow)
- || animation->isAnimatingProperty(CSSPropertyWebkitFilter, acceleratedOnly, isRunningNow);
-}
-
-bool AnimationControllerPrivate::isRunningAcceleratedAnimationOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const
-{
- RefPtr<CompositeAnimation> animation = m_compositeAnimations.get(renderer);
- if (!animation)
- return false;
-
- return animation->isAnimatingProperty(property, true, isRunningNow);
-}
-
-void AnimationControllerPrivate::pauseAnimationsForTesting(double t)
-{
- RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
- for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
- it->value->pauseAnimationsForTesting(t);
- it->key->node()->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
- }
-}
-
-double AnimationControllerPrivate::beginAnimationUpdateTime()
-{
- if (m_beginAnimationUpdateTime == cBeginAnimationUpdateTimeNotSet)
- m_beginAnimationUpdateTime = currentTime();
- return m_beginAnimationUpdateTime;
-}
-
-void AnimationControllerPrivate::endAnimationUpdate()
-{
- styleAvailable();
- if (m_animationsWaitingForAsyncStartNotification.isEmpty())
- startTimeResponse(beginAnimationUpdateTime());
-}
-
-void AnimationControllerPrivate::receivedStartTimeResponse(double time)
-{
- startTimeResponse(time);
-}
-
-PassRefPtr<RenderStyle> AnimationControllerPrivate::getAnimatedStyleForRenderer(RenderObject* renderer)
-{
- if (!renderer)
- return 0;
-
- RefPtr<CompositeAnimation> rendererAnimations = m_compositeAnimations.get(renderer);
- if (!rendererAnimations)
- return renderer->style();
-
- RefPtr<RenderStyle> animatingStyle = rendererAnimations->getAnimatedStyle();
- if (!animatingStyle)
- animatingStyle = renderer->style();
-
- return animatingStyle.release();
-}
-
-unsigned AnimationControllerPrivate::numberOfActiveAnimations(Document* document) const
-{
- unsigned count = 0;
-
- RenderObjectAnimationMap::const_iterator animationsEnd = m_compositeAnimations.end();
- for (RenderObjectAnimationMap::const_iterator it = m_compositeAnimations.begin(); it != animationsEnd; ++it) {
- RenderObject* renderer = it->key;
- CompositeAnimation* compAnim = it->value.get();
- if (renderer->document() == document)
- count += compAnim->numberOfActiveAnimations();
- }
-
- return count;
-}
-
-void AnimationControllerPrivate::addToAnimationsWaitingForStyle(AnimationBase* animation)
-{
- // Make sure this animation is not in the start time waiters
- m_animationsWaitingForStartTimeResponse.remove(animation);
- m_animationsWaitingForAsyncStartNotification.remove(animation);
-
- m_animationsWaitingForStyle.add(animation);
-}
-
-void AnimationControllerPrivate::removeFromAnimationsWaitingForStyle(AnimationBase* animationToRemove)
-{
- m_animationsWaitingForStyle.remove(animationToRemove);
-}
-
-void AnimationControllerPrivate::styleAvailable()
-{
- // Go through list of waiters and send them on their way
- WaitingAnimationsSet::const_iterator it = m_animationsWaitingForStyle.begin();
- WaitingAnimationsSet::const_iterator end = m_animationsWaitingForStyle.end();
- for (; it != end; ++it)
- (*it)->styleAvailable();
-
- m_animationsWaitingForStyle.clear();
-}
-
-void AnimationControllerPrivate::addToAnimationsWaitingForStartTimeResponse(AnimationBase* animation, bool willGetResponse)
-{
- // If willGetResponse is true, it means this animation is actually waiting for a response
- // (which will come in as a call to notifyAnimationStarted()).
- // In that case we don't need to add it to this list. We just set a waitingForAResponse flag
- // which says we are waiting for the response. If willGetResponse is false, this animation
- // is not waiting for a response for itself, but rather for a notifyXXXStarted() call for
- // another animation to which it will sync.
- //
- // When endAnimationUpdate() is called we check to see if the waitingForAResponse flag is
- // true. If so, we just return and will do our work when the first notifyXXXStarted() call
- // comes in. If it is false, we will not be getting a notifyXXXStarted() call, so we will
- // do our work right away. In both cases we call the onAnimationStartResponse() method
- // on each animation. In the first case we send in the time we got from notifyXXXStarted().
- // In the second case, we just pass in the beginAnimationUpdateTime().
- //
- // This will synchronize all software and accelerated animations started in the same
- // updateStyleIfNeeded cycle.
- //
-
- if (willGetResponse)
- m_animationsWaitingForAsyncStartNotification.add(animation);
-
- m_animationsWaitingForStartTimeResponse.add(animation);
-}
-
-void AnimationControllerPrivate::removeFromAnimationsWaitingForStartTimeResponse(AnimationBase* animationToRemove)
-{
- m_animationsWaitingForStartTimeResponse.remove(animationToRemove);
- m_animationsWaitingForAsyncStartNotification.remove(animationToRemove);
-}
-
-void AnimationControllerPrivate::startTimeResponse(double time)
-{
- // Go through list of waiters and send them on their way
-
- WaitingAnimationsSet::const_iterator it = m_animationsWaitingForStartTimeResponse.begin();
- WaitingAnimationsSet::const_iterator end = m_animationsWaitingForStartTimeResponse.end();
- for (; it != end; ++it)
- (*it)->onAnimationStartResponse(time);
-
- m_animationsWaitingForStartTimeResponse.clear();
- m_animationsWaitingForAsyncStartNotification.clear();
-}
-
-void AnimationControllerPrivate::animationWillBeRemoved(AnimationBase* animation)
-{
- removeFromAnimationsWaitingForStyle(animation);
- removeFromAnimationsWaitingForStartTimeResponse(animation);
-}
-
-AnimationController::AnimationController(Frame* frame)
- : m_data(adoptPtr(new AnimationControllerPrivate(frame)))
- , m_beginAnimationUpdateCount(0)
-{
-}
-
-AnimationController::~AnimationController()
-{
-}
-
-void AnimationController::cancelAnimations(RenderObject* renderer)
-{
- if (!m_data->hasAnimations())
- return;
-
- if (m_data->clear(renderer)) {
- if (Node* node = renderer->node())
- node->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
- }
-}
-
-PassRefPtr<RenderStyle> AnimationController::updateAnimations(RenderObject& renderer, RenderStyle& newStyle)
-{
- RenderStyle* oldStyle = renderer.style();
-
- if ((!oldStyle || (!oldStyle->animations() && !oldStyle->transitions())) && (!newStyle.animations() && !newStyle.transitions()))
- return PassRefPtr<RenderStyle>(newStyle);
-
- // Don't run transitions when printing.
- if (renderer.view()->document().printing())
- return PassRefPtr<RenderStyle>(newStyle);
-
- // Fetch our current set of implicit animations from a hashtable. We then compare them
- // against the animations in the style and make sure we're in sync. If destination values
- // have changed, we reset the animation. We then do a blend to get new values and we return
- // a new style.
-
- // We don't support anonymous pseudo elements like :first-line or :first-letter.
- ASSERT(renderer.node());
-
- RefPtr<CompositeAnimation> rendererAnimations = m_data->accessCompositeAnimation(renderer);
- RefPtr<RenderStyle> blendedStyle = rendererAnimations->animate(renderer, oldStyle, newStyle);
-
- if (renderer.parent() || newStyle.animations() || (oldStyle && oldStyle->animations())) {
- m_data->scheduleServiceForRenderer(renderer);
- }
-
- if (blendedStyle != &newStyle) {
- // If the animations/transitions change opacity or transform, we need to update
- // the style to impose the stacking rules. Note that this is also
- // done in StyleResolver::adjustRenderStyle().
- if (blendedStyle->hasAutoZIndex() && (blendedStyle->opacity() < 1.0f || blendedStyle->hasTransform()))
- blendedStyle->setZIndex(0);
- }
- return blendedStyle.release();
-}
-
-PassRefPtr<RenderStyle> AnimationController::getAnimatedStyleForRenderer(RenderObject* renderer)
-{
- return m_data->getAnimatedStyleForRenderer(renderer);
-}
-
-void AnimationController::notifyAnimationStarted(RenderObject*, double startTime)
-{
- m_data->receivedStartTimeResponse(startTime);
-}
-
-void AnimationController::pauseAnimationsForTesting(double t)
-{
- m_data->pauseAnimationsForTesting(t);
-}
-
-unsigned AnimationController::numberOfActiveAnimations(Document* document) const
-{
- return m_data->numberOfActiveAnimations(document);
-}
-
-bool AnimationController::isRunningAnimationOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const
-{
- return m_data->isRunningAnimationOnRenderer(renderer, property, isRunningNow);
-}
-
-bool AnimationController::isRunningAcceleratableAnimationOnRenderer(RenderObject* renderer) const
-{
- return m_data->isRunningAcceleratableAnimationOnRenderer(renderer);
-}
-
-bool AnimationController::isRunningAcceleratedAnimationOnRenderer(RenderObject* renderer, CSSPropertyID property, bool isRunningNow) const
-{
- return m_data->isRunningAcceleratedAnimationOnRenderer(renderer, property, isRunningNow);
-}
-
-void AnimationController::serviceAnimations()
-{
- m_data->serviceAnimations();
-}
-
-void AnimationController::beginAnimationUpdate()
-{
- if (!m_beginAnimationUpdateCount)
- m_data->setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
- ++m_beginAnimationUpdateCount;
-}
-
-void AnimationController::endAnimationUpdate()
-{
- ASSERT(m_beginAnimationUpdateCount > 0);
- --m_beginAnimationUpdateCount;
- if (!m_beginAnimationUpdateCount)
- m_data->endAnimationUpdate();
-}
-
-bool AnimationController::supportsAcceleratedAnimationOfProperty(CSSPropertyID property)
-{
- return CSSPropertyAnimation::animationOfPropertyIsAccelerated(property);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationController.h b/chromium/third_party/WebKit/Source/core/frame/animation/AnimationController.h
deleted file mode 100644
index 01cf32699ba..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationController.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AnimationController_h
-#define AnimationController_h
-
-#include "CSSPropertyNames.h"
-#include "wtf/Forward.h"
-#include "wtf/OwnPtr.h"
-
-namespace WebCore {
-
-class AnimationBase;
-class AnimationControllerPrivate;
-class Document;
-class Element;
-class Frame;
-class Node;
-class RenderObject;
-class RenderStyle;
-
-class AnimationController {
-public:
- AnimationController(Frame*);
- ~AnimationController();
-
- void cancelAnimations(RenderObject*);
- PassRefPtr<RenderStyle> updateAnimations(RenderObject&, RenderStyle& newStyle);
- PassRefPtr<RenderStyle> getAnimatedStyleForRenderer(RenderObject*);
-
- // This is called when an accelerated animation or transition has actually started to animate.
- void notifyAnimationStarted(RenderObject*, double startTime);
-
- void pauseAnimationsForTesting(double t);
- unsigned numberOfActiveAnimations(Document*) const; // To be used only for testing
-
- bool isRunningAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const;
- bool isRunningAcceleratableAnimationOnRenderer(RenderObject*) const;
- bool isRunningAcceleratedAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow = true) const;
-
- void serviceAnimations();
-
- void beginAnimationUpdate();
- void endAnimationUpdate();
-
- static bool supportsAcceleratedAnimationOfProperty(CSSPropertyID);
-
-private:
- OwnPtr<AnimationControllerPrivate> m_data;
- int m_beginAnimationUpdateCount;
-};
-
-class AnimationUpdateBlock {
-public:
- explicit AnimationUpdateBlock(AnimationController* animationController)
- : m_animationController(animationController)
- {
- if (m_animationController)
- m_animationController->beginAnimationUpdate();
- }
-
- explicit AnimationUpdateBlock(AnimationController& animationController)
- : m_animationController(&animationController)
- {
- m_animationController->beginAnimationUpdate();
- }
-
- ~AnimationUpdateBlock()
- {
- if (m_animationController)
- m_animationController->endAnimationUpdate();
- }
-
- AnimationController* m_animationController;
-};
-
-} // namespace WebCore
-
-#endif // AnimationController_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationControllerPrivate.h b/chromium/third_party/WebKit/Source/core/frame/animation/AnimationControllerPrivate.h
deleted file mode 100644
index 671ec89b573..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/AnimationControllerPrivate.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AnimationControllerPrivate_h
-#define AnimationControllerPrivate_h
-
-#include "CSSPropertyNames.h"
-#include "platform/Timer.h"
-#include "wtf/HashMap.h"
-#include "wtf/HashSet.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
-#include "wtf/text/AtomicString.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class AnimationBase;
-class CompositeAnimation;
-class Document;
-class Element;
-class Frame;
-class Node;
-class RenderObject;
-class RenderStyle;
-
-enum SetNeedsStyleRecalc {
- DoNotCallSetNeedsStyleRecalc = 0,
- CallSetNeedsStyleRecalc = 1
-};
-
-class AnimationControllerPrivate {
- WTF_MAKE_NONCOPYABLE(AnimationControllerPrivate); WTF_MAKE_FAST_ALLOCATED;
-public:
- AnimationControllerPrivate(Frame*);
- ~AnimationControllerPrivate();
-
- void updateAnimations(double& timeToNextService, double& timeToNextEvent, SetNeedsStyleRecalc callSetNeedsStyleRecalc = DoNotCallSetNeedsStyleRecalc);
- void scheduleService();
-
- PassRefPtr<CompositeAnimation> accessCompositeAnimation(RenderObject&);
- bool clear(RenderObject*);
-
- void updateStyleIfNeededDispatcherFired(Timer<AnimationControllerPrivate>*);
- void startUpdateStyleIfNeededDispatcher();
- void addEventToDispatch(PassRefPtr<Element> element, const AtomicString& eventType, const String& name, double elapsedTime);
- void addNodeChangeToDispatch(PassRefPtr<Node>);
-
- bool hasAnimations() const { return !m_compositeAnimations.isEmpty(); }
-
- void serviceAnimations();
-
- bool isRunningAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const;
- bool isRunningAcceleratableAnimationOnRenderer(RenderObject*) const;
- bool isRunningAcceleratedAnimationOnRenderer(RenderObject*, CSSPropertyID, bool isRunningNow) const;
-
- void pauseAnimationsForTesting(double t);
- unsigned numberOfActiveAnimations(Document*) const;
-
- PassRefPtr<RenderStyle> getAnimatedStyleForRenderer(RenderObject* renderer);
-
- double beginAnimationUpdateTime();
- void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; }
- void endAnimationUpdate();
- void receivedStartTimeResponse(double);
-
- void addToAnimationsWaitingForStyle(AnimationBase*);
- void removeFromAnimationsWaitingForStyle(AnimationBase*);
-
- void addToAnimationsWaitingForStartTimeResponse(AnimationBase*, bool willGetResponse);
- void removeFromAnimationsWaitingForStartTimeResponse(AnimationBase*);
-
- void animationWillBeRemoved(AnimationBase*);
-
- void scheduleServiceForRenderer(RenderObject&);
-
-private:
- void animationTimerFired(Timer<AnimationControllerPrivate>*);
-
- void scheduleService(double timeToNextService, double timeToNextEvent);
-
- void styleAvailable();
- void fireEventsAndUpdateStyle();
- void startTimeResponse(double t);
-
- typedef HashMap<RenderObject*, RefPtr<CompositeAnimation> > RenderObjectAnimationMap;
-
- RenderObjectAnimationMap m_compositeAnimations;
- Timer<AnimationControllerPrivate> m_animationTimer;
- Timer<AnimationControllerPrivate> m_updateStyleIfNeededDispatcher;
- Frame* m_frame;
-
- class EventToDispatch {
- public:
- RefPtr<Element> element;
- AtomicString eventType;
- String name;
- double elapsedTime;
- };
-
- Vector<EventToDispatch> m_eventsToDispatch;
- Vector<RefPtr<Node> > m_nodeChangesToDispatch;
-
- double m_beginAnimationUpdateTime;
-
- typedef HashSet<RefPtr<AnimationBase> > WaitingAnimationsSet;
- WaitingAnimationsSet m_animationsWaitingForStyle;
- WaitingAnimationsSet m_animationsWaitingForStartTimeResponse;
- WaitingAnimationsSet m_animationsWaitingForAsyncStartNotification;
-};
-
-} // namespace WebCore
-
-#endif // AnimationControllerPrivate_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/CSSPropertyAnimation.cpp b/chromium/third_party/WebKit/Source/core/frame/animation/CSSPropertyAnimation.cpp
deleted file mode 100644
index 4d07ebf1e86..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/CSSPropertyAnimation.cpp
+++ /dev/null
@@ -1,1153 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/animation/CSSPropertyAnimation.h"
-
-#include <algorithm>
-#include "StylePropertyShorthand.h"
-#include "core/animation/css/CSSAnimations.h"
-#include "core/css/CSSCrossfadeValue.h"
-#include "core/css/CSSImageValue.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/fetch/ImageResource.h"
-#include "core/frame/animation/AnimationBase.h"
-#include "core/rendering/ClipPathOperation.h"
-#include "core/rendering/RenderBox.h"
-#include "core/rendering/style/RenderStyle.h"
-#include "core/rendering/style/ShadowList.h"
-#include "core/rendering/style/StyleFetchedImage.h"
-#include "core/rendering/style/StyleGeneratedImage.h"
-#include "platform/FloatConversion.h"
-#include "wtf/Noncopyable.h"
-
-namespace WebCore {
-
-template <typename T>
-static inline T blendFunc(const AnimationBase*, T from, T to, double progress)
-{
- return blend(from, to, progress);
-}
-
-static inline float blendFunc(const AnimationBase*, float from, float to, double progress)
-{
- return narrowPrecisionToFloat(from + (to - from) * progress);
-}
-
-static inline Color blendFunc(const AnimationBase*, const Color& from, const Color& to, double progress)
-{
- return blend(from, to, progress);
-}
-
-static inline Length blendFunc(const AnimationBase*, const Length& from, const Length& to, double progress)
-{
- return to.blend(from, progress, ValueRangeAll);
-}
-
-static inline BorderImageLength blendFunc(const AnimationBase* anim, const BorderImageLength& from, const BorderImageLength& to, double progress)
-{
- if (from.isNumber() && to.isNumber())
- return BorderImageLength(blendFunc(anim, from.number(), to.number(), progress));
-
- if (from.isLength() && to.isLength())
- return BorderImageLength(blendFunc(anim, from.length(), to.length(), progress));
-
- // FIXME: Converting numbers to lengths using the computed border
- // width would make it possible to interpolate between numbers and
- // lengths.
- // https://code.google.com/p/chromium/issues/detail?id=316164
- return to;
-}
-
-static inline BorderImageLengthBox blendFunc(const AnimationBase* anim, const BorderImageLengthBox& from,
- const BorderImageLengthBox& to, double progress)
-{
- return BorderImageLengthBox(blendFunc(anim, from.top(), to.top(), progress),
- blendFunc(anim, from.right(), to.right(), progress),
- blendFunc(anim, from.bottom(), to.bottom(), progress),
- blendFunc(anim, from.left(), to.left(), progress));
-}
-
-static inline LengthSize blendFunc(const AnimationBase* anim, const LengthSize& from, const LengthSize& to, double progress)
-{
- return LengthSize(blendFunc(anim, from.width(), to.width(), progress),
- blendFunc(anim, from.height(), to.height(), progress));
-}
-
-static inline LengthPoint blendFunc(const AnimationBase* anim, const LengthPoint& from, const LengthPoint& to, double progress)
-{
- return LengthPoint(blendFunc(anim, from.x(), to.x(), progress), blendFunc(anim, from.y(), to.y(), progress));
-}
-
-static inline TransformOperations blendFunc(const AnimationBase* anim, const TransformOperations& from, const TransformOperations& to, double progress)
-{
- if (anim->isTransformFunctionListValid())
- return to.blendByMatchingOperations(from, progress);
- return to.blendByUsingMatrixInterpolation(from, progress);
-}
-
-static inline PassRefPtr<ClipPathOperation> blendFunc(const AnimationBase*, ClipPathOperation* from, ClipPathOperation* to, double progress)
-{
- // Other clip-path operations than BasicShapes can not be animated.
- if (!from || !to || from->type() != ClipPathOperation::SHAPE || to->type() != ClipPathOperation::SHAPE)
- return to;
-
- const BasicShape* fromShape = toShapeClipPathOperation(from)->basicShape();
- const BasicShape* toShape = toShapeClipPathOperation(to)->basicShape();
-
- if (!fromShape->canBlend(toShape))
- return to;
-
- return ShapeClipPathOperation::create(toShape->blend(fromShape, progress));
-}
-
-static inline PassRefPtr<ShapeValue> blendFunc(const AnimationBase*, ShapeValue* from, ShapeValue* to, double progress)
-{
- // FIXME Bug 102723: Shape-inside should be able to animate a value of 'outside-shape' when shape-outside is set to a BasicShape
- if (!from || !to || from->type() != ShapeValue::Shape || to->type() != ShapeValue::Shape)
- return to;
-
- const BasicShape* fromShape = from->shape();
- const BasicShape* toShape = to->shape();
-
- if (!fromShape->canBlend(toShape))
- return to;
-
- return ShapeValue::createShapeValue(toShape->blend(fromShape, progress));
-}
-
-static inline FilterOperations blendFunc(const AnimationBase* anim, const FilterOperations& from, const FilterOperations& to, double progress)
-{
- FilterOperations result;
-
- // If we have a filter function list, use that to do a per-function animation.
- if (anim->filterFunctionListsMatch()) {
- size_t fromSize = from.operations().size();
- size_t toSize = to.operations().size();
- size_t size = max(fromSize, toSize);
- for (size_t i = 0; i < size; i++) {
- const FilterOperation* fromOp = (i < fromSize) ? from.operations()[i].get() : 0;
- const FilterOperation* toOp = (i < toSize) ? to.operations()[i].get() : 0;
- RefPtr<FilterOperation> blendedOp = FilterOperation::blend(fromOp, toOp, progress);
- if (blendedOp)
- result.operations().append(blendedOp);
- else
- ASSERT_NOT_REACHED();
- }
- } else {
- // If the filter function lists don't match, we could try to cross-fade, but don't yet have a way to represent that in CSS.
- // For now we'll just fail to animate.
- result = to;
- }
-
- return result;
-}
-
-static inline EVisibility blendFunc(const AnimationBase* anim, EVisibility from, EVisibility to, double progress)
-{
- // Any non-zero result means we consider the object to be visible. Only at 0 do we consider the object to be
- // invisible. The invisible value we use (HIDDEN vs. COLLAPSE) depends on the specified from/to values.
- double fromVal = from == VISIBLE ? 1. : 0.;
- double toVal = to == VISIBLE ? 1. : 0.;
- if (fromVal == toVal)
- return to;
- double result = blendFunc(anim, fromVal, toVal, progress);
- return result > 0. ? VISIBLE : (to != VISIBLE ? to : from);
-}
-
-static inline LengthBox blendFunc(const AnimationBase* anim, const LengthBox& from, const LengthBox& to, double progress)
-{
- // Length types have to match to animate
- if (from.top().type() != to.top().type()
- || from.right().type() != to.right().type()
- || from.bottom().type() != to.bottom().type()
- || from.left().type() != to.left().type())
- return to;
-
- LengthBox result(blendFunc(anim, from.top(), to.top(), progress),
- blendFunc(anim, from.right(), to.right(), progress),
- blendFunc(anim, from.bottom(), to.bottom(), progress),
- blendFunc(anim, from.left(), to.left(), progress));
- return result;
-}
-
-static inline SVGLength blendFunc(const AnimationBase*, const SVGLength& from, const SVGLength& to, double progress)
-{
- return to.blend(from, narrowPrecisionToFloat(progress));
-}
-
-static inline Vector<SVGLength> blendFunc(const AnimationBase*, const Vector<SVGLength>& from, const Vector<SVGLength>& to, double progress)
-{
- size_t fromLength = from.size();
- size_t toLength = to.size();
- if (!fromLength)
- return !progress ? from : to;
- if (!toLength)
- return progress == 1 ? from : to;
-
- size_t resultLength = fromLength;
- if (fromLength != toLength) {
- if (!(fromLength % toLength))
- resultLength = fromLength;
- else if (!(toLength % fromLength))
- resultLength = toLength;
- else
- resultLength = fromLength * toLength;
- }
- Vector<SVGLength> result(resultLength);
- for (size_t i = 0; i < resultLength; ++i)
- result[i] = to[i % toLength].blend(from[i % fromLength], narrowPrecisionToFloat(progress));
- return result;
-}
-
-static inline PassRefPtr<StyleImage> crossfadeBlend(const AnimationBase*, StyleFetchedImage* fromStyleImage, StyleFetchedImage* toStyleImage, double progress)
-{
- // If progress is at one of the extremes, we want getComputedStyle to show the image,
- // not a completed cross-fade, so we hand back one of the existing images.
- if (!progress)
- return fromStyleImage;
- if (progress == 1)
- return toStyleImage;
-
- ImageResource* fromImageResource = static_cast<ImageResource*>(fromStyleImage->data());
- ImageResource* toImageResource = static_cast<ImageResource*>(toStyleImage->data());
-
- RefPtr<CSSImageValue> fromImageValue = CSSImageValue::create(fromImageResource->url(), fromStyleImage);
- RefPtr<CSSImageValue> toImageValue = CSSImageValue::create(toImageResource->url(), toStyleImage);
- RefPtr<CSSCrossfadeValue> crossfadeValue = CSSCrossfadeValue::create(fromImageValue, toImageValue);
-
- crossfadeValue->setPercentage(CSSPrimitiveValue::create(progress, CSSPrimitiveValue::CSS_NUMBER));
-
- return StyleGeneratedImage::create(crossfadeValue.get());
-}
-
-static inline PassRefPtr<StyleImage> blendFunc(const AnimationBase* anim, StyleImage* from, StyleImage* to, double progress)
-{
- if (!from || !to)
- return to;
-
- if (from->isImageResource() && to->isImageResource())
- return crossfadeBlend(anim, toStyleFetchedImage(from), toStyleFetchedImage(to), progress);
-
- // FIXME: Support transitioning generated images as well. (gradients, etc.)
-
- return to;
-}
-
-class AnimationPropertyWrapperBase {
- WTF_MAKE_NONCOPYABLE(AnimationPropertyWrapperBase);
- WTF_MAKE_FAST_ALLOCATED;
-public:
- AnimationPropertyWrapperBase(CSSPropertyID prop)
- : m_prop(prop)
- {
- }
-
- virtual ~AnimationPropertyWrapperBase() { }
-
- virtual bool isShorthandWrapper() const { return false; }
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0;
- virtual void blend(const AnimationBase*, RenderStyle*, const RenderStyle*, const RenderStyle*, double) const = 0;
-
- CSSPropertyID property() const { return m_prop; }
-
- virtual bool animationIsAccelerated() const { return false; }
-
-private:
- CSSPropertyID m_prop;
-};
-
-static int gPropertyWrapperMap[numCSSProperties];
-static const int cInvalidPropertyWrapperIndex = -1;
-static Vector<AnimationPropertyWrapperBase*>* gPropertyWrappers = 0;
-
-static void addPropertyWrapper(CSSPropertyID propertyID, AnimationPropertyWrapperBase* wrapper)
-{
- int propIndex = propertyID - firstCSSProperty;
-
- ASSERT(gPropertyWrapperMap[propIndex] == cInvalidPropertyWrapperIndex);
-
- unsigned wrapperIndex = gPropertyWrappers->size();
- gPropertyWrappers->append(wrapper);
- gPropertyWrapperMap[propIndex] = wrapperIndex;
-}
-
-static AnimationPropertyWrapperBase* wrapperForProperty(CSSPropertyID propertyID)
-{
- int propIndex = propertyID - firstCSSProperty;
- if (propIndex >= 0 && propIndex < numCSSProperties) {
- int wrapperIndex = gPropertyWrapperMap[propIndex];
- if (wrapperIndex >= 0)
- return (*gPropertyWrappers)[wrapperIndex];
- }
- return 0;
-}
-
-template <typename T>
-class PropertyWrapperGetter : public AnimationPropertyWrapperBase {
-public:
- PropertyWrapperGetter(CSSPropertyID prop, T (RenderStyle::*getter)() const)
- : AnimationPropertyWrapperBase(prop)
- , m_getter(getter)
- {
- }
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- // If the style pointers are the same, don't bother doing the test.
- // If either is null, return false. If both are null, return true.
- if ((!a && !b) || a == b)
- return true;
- if (!a || !b)
- return false;
- return (a->*m_getter)() == (b->*m_getter)();
- }
-
-protected:
- T (RenderStyle::*m_getter)() const;
-};
-
-template <typename T>
-class PropertyWrapper : public PropertyWrapperGetter<T> {
-public:
- PropertyWrapper(CSSPropertyID prop, T (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T))
- : PropertyWrapperGetter<T>(prop, getter)
- , m_setter(setter)
- {
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<T>::m_getter)(), (b->*PropertyWrapperGetter<T>::m_getter)(), progress));
- }
-
-protected:
- void (RenderStyle::*m_setter)(T);
-};
-
-class NonNegativeLengthWrapper : public PropertyWrapper<Length> {
-public:
- NonNegativeLengthWrapper(CSSPropertyID prop, Length (RenderStyle::*getter)() const, void (RenderStyle::*setter)(Length))
- : PropertyWrapper<Length>(prop, getter, setter)
- {
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- Length from = (a->*PropertyWrapperGetter<Length>::m_getter)();
- Length to = (b->*PropertyWrapperGetter<Length>::m_getter)();
- (dst->*PropertyWrapper<Length>::m_setter)(to.blend(from, progress, ValueRangeNonNegative));
- }
-};
-
-template <typename T>
-class RefCountedPropertyWrapper : public PropertyWrapperGetter<T*> {
-public:
- RefCountedPropertyWrapper(CSSPropertyID prop, T* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<T>))
- : PropertyWrapperGetter<T*>(prop, getter)
- , m_setter(setter)
- {
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<T*>::m_getter)(), (b->*PropertyWrapperGetter<T*>::m_getter)(), progress));
- }
-
-protected:
- void (RenderStyle::*m_setter)(PassRefPtr<T>);
-};
-
-
-class PropertyWrapperClipPath : public RefCountedPropertyWrapper<ClipPathOperation> {
-public:
- PropertyWrapperClipPath(CSSPropertyID prop, ClipPathOperation* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<ClipPathOperation>))
- : RefCountedPropertyWrapper<ClipPathOperation>(prop, getter, setter)
- {
- }
-};
-
-class PropertyWrapperShape : public RefCountedPropertyWrapper<ShapeValue> {
-public:
- PropertyWrapperShape(CSSPropertyID prop, ShapeValue* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<ShapeValue>))
- : RefCountedPropertyWrapper<ShapeValue>(prop, getter, setter)
- {
- }
-};
-
-class StyleImagePropertyWrapper : public RefCountedPropertyWrapper<StyleImage> {
-public:
- StyleImagePropertyWrapper(CSSPropertyID prop, StyleImage* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<StyleImage>))
- : RefCountedPropertyWrapper<StyleImage>(prop, getter, setter)
- {
- }
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- // If the style pointers are the same, don't bother doing the test.
- // If either is null, return false. If both are null, return true.
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
- StyleImage* imageA = (a->*m_getter)();
- StyleImage* imageB = (b->*m_getter)();
- return StyleImage::imagesEquivalent(imageA, imageB);
- }
-};
-
-class PropertyWrapperColor : public PropertyWrapperGetter<Color> {
-public:
- PropertyWrapperColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&))
- : PropertyWrapperGetter<Color>(prop, getter)
- , m_setter(setter)
- {
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- (dst->*m_setter)(blendFunc(anim, (a->*PropertyWrapperGetter<Color>::m_getter)(), (b->*PropertyWrapperGetter<Color>::m_getter)(), progress));
- }
-
-protected:
- void (RenderStyle::*m_setter)(const Color&);
-};
-
-class PropertyWrapperAcceleratedOpacity : public PropertyWrapper<float> {
-public:
- PropertyWrapperAcceleratedOpacity()
- : PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity, &RenderStyle::setOpacity)
- {
- }
-
- virtual bool animationIsAccelerated() const { return true; }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- float fromOpacity = a->opacity();
-
- // This makes sure we put the object being animated into a RenderLayer during the animation
- dst->setOpacity(blendFunc(anim, (fromOpacity == 1) ? 0.999999f : fromOpacity, b->opacity(), progress));
- }
-};
-
-class PropertyWrapperAcceleratedTransform : public PropertyWrapper<const TransformOperations&> {
-public:
- PropertyWrapperAcceleratedTransform()
- : PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform, &RenderStyle::setTransform)
- {
- }
-
- virtual bool animationIsAccelerated() const { return true; }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- dst->setTransform(blendFunc(anim, a->transform(), b->transform(), progress));
- }
-};
-
-class PropertyWrapperAcceleratedFilter : public PropertyWrapper<const FilterOperations&> {
-public:
- PropertyWrapperAcceleratedFilter()
- : PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter, &RenderStyle::setFilter)
- {
- }
-
- virtual bool animationIsAccelerated() const { return true; }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- dst->setFilter(blendFunc(anim, a->filter(), b->filter(), progress));
- }
-};
-
-class PropertyWrapperShadow : public AnimationPropertyWrapperBase {
-public:
- PropertyWrapperShadow(CSSPropertyID prop, ShadowList* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(PassRefPtr<ShadowList>))
- : AnimationPropertyWrapperBase(prop)
- , m_getter(getter)
- , m_setter(setter)
- {
- }
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- const ShadowList* shadowA = (a->*m_getter)();
- const ShadowList* shadowB = (b->*m_getter)();
- if (shadowA == shadowB)
- return true;
- if (shadowA && shadowB)
- return *shadowA == *shadowB;
- return false;
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- (dst->*m_setter)(ShadowList::blend((a->*m_getter)(), (b->*m_getter)(), progress));
- }
-
- ShadowList* (RenderStyle::*m_getter)() const;
- void (RenderStyle::*m_setter)(PassRefPtr<ShadowList>);
-};
-
-class PropertyWrapperMaybeInvalidColor : public AnimationPropertyWrapperBase {
-public:
- PropertyWrapperMaybeInvalidColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&))
- : AnimationPropertyWrapperBase(prop)
- , m_getter(getter)
- , m_setter(setter)
- {
- }
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- Color fromColor = (a->*m_getter)();
- Color toColor = (b->*m_getter)();
-
- if (!fromColor.isValid() && !toColor.isValid())
- return true;
-
- if (!fromColor.isValid())
- fromColor = a->color();
- if (!toColor.isValid())
- toColor = b->color();
-
- return fromColor == toColor;
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- Color fromColor = (a->*m_getter)();
- Color toColor = (b->*m_getter)();
-
- if (!fromColor.isValid() && !toColor.isValid())
- return;
-
- if (!fromColor.isValid())
- fromColor = a->color();
- if (!toColor.isValid())
- toColor = b->color();
- (dst->*m_setter)(blendFunc(anim, fromColor, toColor, progress));
- }
-
-private:
- Color (RenderStyle::*m_getter)() const;
- void (RenderStyle::*m_setter)(const Color&);
-};
-
-
-enum MaybeInvalidColorTag { MaybeInvalidColor };
-class PropertyWrapperVisitedAffectedColor : public AnimationPropertyWrapperBase {
-public:
- PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&),
- Color (RenderStyle::*visitedGetter)() const, void (RenderStyle::*visitedSetter)(const Color&))
- : AnimationPropertyWrapperBase(prop)
- , m_wrapper(adoptPtr(new PropertyWrapperColor(prop, getter, setter)))
- , m_visitedWrapper(adoptPtr(new PropertyWrapperColor(prop, visitedGetter, visitedSetter)))
- {
- }
- PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, MaybeInvalidColorTag, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&),
- Color (RenderStyle::*visitedGetter)() const, void (RenderStyle::*visitedSetter)(const Color&))
- : AnimationPropertyWrapperBase(prop)
- , m_wrapper(adoptPtr(new PropertyWrapperMaybeInvalidColor(prop, getter, setter)))
- , m_visitedWrapper(adoptPtr(new PropertyWrapperMaybeInvalidColor(prop, visitedGetter, visitedSetter)))
- {
- }
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- return m_wrapper->equals(a, b) && m_visitedWrapper->equals(a, b);
- }
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- m_wrapper->blend(anim, dst, a, b, progress);
- m_visitedWrapper->blend(anim, dst, a, b, progress);
- }
-
-private:
- OwnPtr<AnimationPropertyWrapperBase> m_wrapper;
- OwnPtr<AnimationPropertyWrapperBase> m_visitedWrapper;
-};
-
-// Wrapper base class for an animatable property in a FillLayer
-class FillLayerAnimationPropertyWrapperBase {
-public:
- FillLayerAnimationPropertyWrapperBase()
- {
- }
-
- virtual ~FillLayerAnimationPropertyWrapperBase() { }
-
- virtual bool equals(const FillLayer*, const FillLayer*) const = 0;
- virtual void blend(const AnimationBase*, FillLayer*, const FillLayer*, const FillLayer*, double) const = 0;
-};
-
-template <typename T>
-class FillLayerPropertyWrapperGetter : public FillLayerAnimationPropertyWrapperBase {
- WTF_MAKE_NONCOPYABLE(FillLayerPropertyWrapperGetter);
-public:
- FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
- : m_getter(getter)
- {
- }
-
- virtual bool equals(const FillLayer* a, const FillLayer* b) const
- {
- // If the style pointers are the same, don't bother doing the test.
- // If either is null, return false. If both are null, return true.
- if ((!a && !b) || a == b)
- return true;
- if (!a || !b)
- return false;
- return (a->*m_getter)() == (b->*m_getter)();
- }
-
-protected:
- T (FillLayer::*m_getter)() const;
-};
-
-template <typename T>
-class FillLayerPropertyWrapper : public FillLayerPropertyWrapperGetter<T> {
-public:
- FillLayerPropertyWrapper(T (FillLayer::*getter)() const, void (FillLayer::*setter)(T))
- : FillLayerPropertyWrapperGetter<T>(getter)
- , m_setter(setter)
- {
- }
-
- virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const
- {
- (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<T>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<T>::m_getter)(), progress));
- }
-
-protected:
- void (FillLayer::*m_setter)(T);
-};
-
-template <typename T>
-class FillLayerRefCountedPropertyWrapper : public FillLayerPropertyWrapperGetter<T*> {
-public:
- FillLayerRefCountedPropertyWrapper(T* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<T>))
- : FillLayerPropertyWrapperGetter<T*>(getter)
- , m_setter(setter)
- {
- }
-
- virtual void blend(const AnimationBase* anim, FillLayer* dst, const FillLayer* a, const FillLayer* b, double progress) const
- {
- (dst->*m_setter)(blendFunc(anim, (a->*FillLayerPropertyWrapperGetter<T*>::m_getter)(), (b->*FillLayerPropertyWrapperGetter<T*>::m_getter)(), progress));
- }
-
-protected:
- void (FillLayer::*m_setter)(PassRefPtr<T>);
-};
-
-class FillLayerStyleImagePropertyWrapper : public FillLayerRefCountedPropertyWrapper<StyleImage> {
-public:
- FillLayerStyleImagePropertyWrapper(StyleImage* (FillLayer::*getter)() const, void (FillLayer::*setter)(PassRefPtr<StyleImage>))
- : FillLayerRefCountedPropertyWrapper<StyleImage>(getter, setter)
- {
- }
-
- virtual bool equals(const FillLayer* a, const FillLayer* b) const
- {
- // If the style pointers are the same, don't bother doing the test.
- // If either is null, return false. If both are null, return true.
- if (a == b)
- return true;
- if (!a || !b)
- return false;
-
- StyleImage* imageA = (a->*m_getter)();
- StyleImage* imageB = (b->*m_getter)();
- return StyleImage::imagesEquivalent(imageA, imageB);
- }
-};
-
-
-class FillLayersPropertyWrapper : public AnimationPropertyWrapperBase {
-public:
- typedef const FillLayer* (RenderStyle::*LayersGetter)() const;
- typedef FillLayer* (RenderStyle::*LayersAccessor)();
-
- FillLayersPropertyWrapper(CSSPropertyID prop, LayersGetter getter, LayersAccessor accessor)
- : AnimationPropertyWrapperBase(prop)
- , m_layersGetter(getter)
- , m_layersAccessor(accessor)
- {
- switch (prop) {
- case CSSPropertyBackgroundPositionX:
- case CSSPropertyWebkitMaskPositionX:
- m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::xPosition, &FillLayer::setXPosition);
- break;
- case CSSPropertyBackgroundPositionY:
- case CSSPropertyWebkitMaskPositionY:
- m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::yPosition, &FillLayer::setYPosition);
- break;
- case CSSPropertyBackgroundSize:
- case CSSPropertyWebkitBackgroundSize:
- case CSSPropertyWebkitMaskSize:
- m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<LengthSize>(&FillLayer::sizeLength, &FillLayer::setSizeLength);
- break;
- case CSSPropertyBackgroundImage:
- m_fillLayerPropertyWrapper = new FillLayerStyleImagePropertyWrapper(&FillLayer::image, &FillLayer::setImage);
- break;
- default:
- break;
- }
- }
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- const FillLayer* fromLayer = (a->*m_layersGetter)();
- const FillLayer* toLayer = (b->*m_layersGetter)();
-
- while (fromLayer && toLayer) {
- if (!m_fillLayerPropertyWrapper->equals(fromLayer, toLayer))
- return false;
-
- fromLayer = fromLayer->next();
- toLayer = toLayer->next();
- }
-
- return true;
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- const FillLayer* aLayer = (a->*m_layersGetter)();
- const FillLayer* bLayer = (b->*m_layersGetter)();
- FillLayer* dstLayer = (dst->*m_layersAccessor)();
-
- while (aLayer && bLayer && dstLayer) {
- m_fillLayerPropertyWrapper->blend(anim, dstLayer, aLayer, bLayer, progress);
- aLayer = aLayer->next();
- bLayer = bLayer->next();
- dstLayer = dstLayer->next();
- }
- }
-
-private:
- FillLayerAnimationPropertyWrapperBase* m_fillLayerPropertyWrapper;
-
- LayersGetter m_layersGetter;
- LayersAccessor m_layersAccessor;
-};
-
-class ShorthandPropertyWrapper : public AnimationPropertyWrapperBase {
-public:
- ShorthandPropertyWrapper(CSSPropertyID property, const StylePropertyShorthand& shorthand)
- : AnimationPropertyWrapperBase(property)
- {
- for (unsigned i = 0; i < shorthand.length(); ++i) {
- AnimationPropertyWrapperBase* wrapper = wrapperForProperty(shorthand.properties()[i]);
- if (wrapper)
- m_propertyWrappers.append(wrapper);
- }
- }
-
- virtual bool isShorthandWrapper() const { return true; }
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- Vector<AnimationPropertyWrapperBase*>::const_iterator end = m_propertyWrappers.end();
- for (Vector<AnimationPropertyWrapperBase*>::const_iterator it = m_propertyWrappers.begin(); it != end; ++it) {
- if (!(*it)->equals(a, b))
- return false;
- }
- return true;
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- Vector<AnimationPropertyWrapperBase*>::const_iterator end = m_propertyWrappers.end();
- for (Vector<AnimationPropertyWrapperBase*>::const_iterator it = m_propertyWrappers.begin(); it != end; ++it)
- (*it)->blend(anim, dst, a, b, progress);
- }
-
- const Vector<AnimationPropertyWrapperBase*> propertyWrappers() const { return m_propertyWrappers; }
-
-private:
- Vector<AnimationPropertyWrapperBase*> m_propertyWrappers;
-};
-
-class PropertyWrapperFlex : public AnimationPropertyWrapperBase {
-public:
- PropertyWrapperFlex()
- : AnimationPropertyWrapperBase(CSSPropertyFlex)
- {
- }
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- // If the style pointers are the same, don't bother doing the test.
- // If either is null, return false. If both are null, return true.
- if ((!a && !b) || a == b)
- return true;
- if (!a || !b)
- return false;
-
- return a->flexBasis() == b->flexBasis() && a->flexGrow() == b->flexGrow() && a->flexShrink() == b->flexShrink();
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- dst->setFlexBasis(blendFunc(anim, a->flexBasis(), b->flexBasis(), progress));
- dst->setFlexGrow(blendFunc(anim, a->flexGrow(), b->flexGrow(), progress));
- dst->setFlexShrink(blendFunc(anim, a->flexShrink(), b->flexShrink(), progress));
- }
-};
-
-class PropertyWrapperSVGPaint : public AnimationPropertyWrapperBase {
-public:
- PropertyWrapperSVGPaint(CSSPropertyID prop, const SVGPaint::SVGPaintType& (RenderStyle::*paintTypeGetter)() const, Color (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&))
- : AnimationPropertyWrapperBase(prop)
- , m_paintTypeGetter(paintTypeGetter)
- , m_getter(getter)
- , m_setter(setter)
- {
- }
-
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
- {
- if ((a->*m_paintTypeGetter)() != (b->*m_paintTypeGetter)())
- return false;
-
- // We only support animations between SVGPaints that are pure Color values.
- // For everything else we must return true for this method, otherwise
- // we will try to animate between values forever.
- if ((a->*m_paintTypeGetter)() == SVGPaint::SVG_PAINTTYPE_RGBCOLOR) {
- Color fromColor = (a->*m_getter)();
- Color toColor = (b->*m_getter)();
-
- if (!fromColor.isValid() && !toColor.isValid())
- return true;
-
- if (!fromColor.isValid())
- fromColor = Color();
- if (!toColor.isValid())
- toColor = Color();
-
- return fromColor == toColor;
- }
- return true;
- }
-
- virtual void blend(const AnimationBase* anim, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
- {
- if ((a->*m_paintTypeGetter)() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR
- || (b->*m_paintTypeGetter)() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR)
- return;
-
- Color fromColor = (a->*m_getter)();
- Color toColor = (b->*m_getter)();
-
- if (!fromColor.isValid() && !toColor.isValid())
- return;
-
- if (!fromColor.isValid())
- fromColor = Color();
- if (!toColor.isValid())
- toColor = Color();
- (dst->*m_setter)(blendFunc(anim, fromColor, toColor, progress));
- }
-
-private:
- const SVGPaint::SVGPaintType& (RenderStyle::*m_paintTypeGetter)() const;
- Color (RenderStyle::*m_getter)() const;
- void (RenderStyle::*m_setter)(const Color&);
-};
-
-static void addShorthandProperties()
-{
- static const CSSPropertyID animatableShorthandProperties[] = {
- CSSPropertyBackground, // for background-color, background-position, background-image
- CSSPropertyBackgroundPosition,
- CSSPropertyFont, // for font-size, font-weight
- CSSPropertyWebkitMask, // for mask-position
- CSSPropertyWebkitMaskPosition,
- CSSPropertyBorderTop, CSSPropertyBorderRight, CSSPropertyBorderBottom, CSSPropertyBorderLeft,
- CSSPropertyBorderColor,
- CSSPropertyBorderRadius,
- CSSPropertyBorderWidth,
- CSSPropertyBorder,
- CSSPropertyBorderImage,
- CSSPropertyBorderSpacing,
- CSSPropertyListStyle, // for list-style-image
- CSSPropertyMargin,
- CSSPropertyOutline,
- CSSPropertyPadding,
- CSSPropertyWebkitTextStroke,
- CSSPropertyWebkitColumnRule,
- CSSPropertyWebkitBorderRadius,
- CSSPropertyWebkitTransformOrigin
- };
-
- for (size_t i = 0; i < WTF_ARRAY_LENGTH(animatableShorthandProperties); ++i) {
- CSSPropertyID propertyID = animatableShorthandProperties[i];
- StylePropertyShorthand shorthand = shorthandForProperty(propertyID);
- if (shorthand.length() > 0)
- addPropertyWrapper(propertyID, new ShorthandPropertyWrapper(propertyID, shorthand));
- }
-}
-
-void CSSPropertyAnimation::ensurePropertyMap()
-{
- // FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed?
- if (gPropertyWrappers)
- return;
-
- gPropertyWrappers = new Vector<AnimationPropertyWrapperBase*>();
-
- // build the list of property wrappers to do the comparisons and blends
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLeft, &RenderStyle::left, &RenderStyle::setLeft));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyRight, &RenderStyle::right, &RenderStyle::setRight));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyTop, &RenderStyle::top, &RenderStyle::setTop));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBottom, &RenderStyle::bottom, &RenderStyle::setBottom));
-
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWidth, &RenderStyle::width, &RenderStyle::setWidth));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMinWidth, &RenderStyle::minWidth, &RenderStyle::setMinWidth));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMaxWidth, &RenderStyle::maxWidth, &RenderStyle::setMaxWidth));
-
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyHeight, &RenderStyle::height, &RenderStyle::setHeight));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMinHeight, &RenderStyle::minHeight, &RenderStyle::setMinHeight));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMaxHeight, &RenderStyle::maxHeight, &RenderStyle::setMaxHeight));
-
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- gPropertyWrappers->append(new PropertyWrapperFlex());
-
- gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth, &RenderStyle::setBorderLeftWidth));
- gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth, &RenderStyle::setBorderRightWidth));
- gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth, &RenderStyle::setBorderTopWidth));
- gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth, &RenderStyle::setBorderBottomWidth));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginLeft, &RenderStyle::marginLeft, &RenderStyle::setMarginLeft));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginRight, &RenderStyle::marginRight, &RenderStyle::setMarginRight));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginTop, &RenderStyle::marginTop, &RenderStyle::setMarginTop));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginBottom, &RenderStyle::marginBottom, &RenderStyle::setMarginBottom));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingLeft, &RenderStyle::paddingLeft, &RenderStyle::setPaddingLeft));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingRight, &RenderStyle::paddingRight, &RenderStyle::setPaddingRight));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingTop, &RenderStyle::paddingTop, &RenderStyle::setPaddingTop));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom, &RenderStyle::setPaddingBottom));
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyColor, &RenderStyle::color, &RenderStyle::setColor, &RenderStyle::visitedLinkColor, &RenderStyle::setVisitedLinkColor));
-
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::setBackgroundColor, &RenderStyle::visitedLinkBackgroundColor, &RenderStyle::setVisitedLinkBackgroundColor));
-
- gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
- gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyListStyleImage, &RenderStyle::listStyleImage, &RenderStyle::setListStyleImage));
- gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage));
-
- gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyBorderImageSource, &RenderStyle::borderImageSource, &RenderStyle::setBorderImageSource));
- gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyBorderImageSlice, &RenderStyle::borderImageSlices, &RenderStyle::setBorderImageSlices));
- gPropertyWrappers->append(new PropertyWrapper<const BorderImageLengthBox&>(CSSPropertyBorderImageWidth, &RenderStyle::borderImageWidth, &RenderStyle::setBorderImageWidth));
- gPropertyWrappers->append(new PropertyWrapper<const BorderImageLengthBox&>(CSSPropertyBorderImageOutset, &RenderStyle::borderImageOutset, &RenderStyle::setBorderImageOutset));
-
- gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource));
- gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyWebkitMaskBoxImageSlice, &RenderStyle::maskBoxImageSlices, &RenderStyle::setMaskBoxImageSlices));
- gPropertyWrappers->append(new PropertyWrapper<const BorderImageLengthBox&>(CSSPropertyWebkitMaskBoxImageWidth, &RenderStyle::maskBoxImageWidth, &RenderStyle::setMaskBoxImageWidth));
- gPropertyWrappers->append(new PropertyWrapper<const BorderImageLengthBox&>(CSSPropertyWebkitMaskBoxImageOutset, &RenderStyle::maskBoxImageOutset, &RenderStyle::setMaskBoxImageOutset));
-
- gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
- gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
- gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
- gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers, &RenderStyle::accessBackgroundLayers));
-
- gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
- gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
- gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers, &RenderStyle::accessMaskLayers));
-
- gPropertyWrappers->append(new PropertyWrapper<LengthPoint>(CSSPropertyObjectPosition, &RenderStyle::objectPosition, &RenderStyle::setObjectPosition));
-
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFontSize,
- // Must pass a specified size to setFontSize if Text Autosizing is enabled, but a computed size
- // if text zoom is enabled (if neither is enabled it's irrelevant as they're probably the same).
- // FIXME: Should we introduce an option to pass the computed font size here, allowing consumers to
- // enable text zoom rather than Text Autosizing? See http://crbug.com/227545.
- &RenderStyle::specifiedFontSize,
- &RenderStyle::setFontSize));
- gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth, &RenderStyle::setColumnRuleWidth));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitColumnGap, &RenderStyle::columnGap, &RenderStyle::setColumnGap));
- gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnCount, &RenderStyle::columnCount, &RenderStyle::setColumnCount));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitColumnWidth, &RenderStyle::columnWidth, &RenderStyle::setColumnWidth));
- gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing, &RenderStyle::setHorizontalBorderSpacing));
- gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing, &RenderStyle::setVerticalBorderSpacing));
- gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyZIndex, &RenderStyle::zIndex, &RenderStyle::setZIndex));
- gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyOrphans, &RenderStyle::orphans, &RenderStyle::setOrphans));
- gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWidows, &RenderStyle::widows, &RenderStyle::setWidows));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLineHeight, &RenderStyle::specifiedLineHeight, &RenderStyle::setLineHeight));
- gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset, &RenderStyle::setOutlineOffset));
- gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth, &RenderStyle::setOutlineWidth));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing, &RenderStyle::setLetterSpacing));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWordSpacing, &RenderStyle::wordSpacing, &RenderStyle::setWordSpacing));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyTextIndent, &RenderStyle::textIndent, &RenderStyle::setTextIndent));
-
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitPerspective, &RenderStyle::perspective, &RenderStyle::setPerspective));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginX, &RenderStyle::perspectiveOriginX, &RenderStyle::setPerspectiveOriginX));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginY, &RenderStyle::perspectiveOriginY, &RenderStyle::setPerspectiveOriginY));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX, &RenderStyle::setTransformOriginX));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY, &RenderStyle::setTransformOriginY));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitTransformOriginZ, &RenderStyle::transformOriginZ, &RenderStyle::setTransformOriginZ));
- gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius, &RenderStyle::setBorderTopLeftRadius));
- gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyBorderTopRightRadius, &RenderStyle::borderTopRightRadius, &RenderStyle::setBorderTopRightRadius));
- gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius, &RenderStyle::setBorderBottomLeftRadius));
- gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius));
- gPropertyWrappers->append(new PropertyWrapper<EVisibility>(CSSPropertyVisibility, &RenderStyle::visibility, &RenderStyle::setVisibility));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyZoom, &RenderStyle::zoom, &RenderStyle::setZoomWithoutReturnValue));
-
- gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyClip, &RenderStyle::clip, &RenderStyle::setClip));
-
- gPropertyWrappers->append(new PropertyWrapperAcceleratedOpacity());
- gPropertyWrappers->append(new PropertyWrapperAcceleratedTransform());
- gPropertyWrappers->append(new PropertyWrapperAcceleratedFilter());
-
- gPropertyWrappers->append(new PropertyWrapperClipPath(CSSPropertyWebkitClipPath, &RenderStyle::clipPath, &RenderStyle::setClipPath));
-
- gPropertyWrappers->append(new PropertyWrapperShape(CSSPropertyShapeInside, &RenderStyle::shapeInside, &RenderStyle::setShapeInside));
- gPropertyWrappers->append(new PropertyWrapperShape(CSSPropertyShapeOutside, &RenderStyle::shapeOutside, &RenderStyle::setShapeOutside));
- gPropertyWrappers->append(new NonNegativeLengthWrapper(CSSPropertyShapeMargin, &RenderStyle::shapeMargin, &RenderStyle::setShapeMargin));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyShapeImageThreshold, &RenderStyle::shapeImageThreshold, &RenderStyle::setShapeImageThreshold));
-
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitColumnRuleColor, MaybeInvalidColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor, &RenderStyle::visitedLinkColumnRuleColor, &RenderStyle::setVisitedLinkColumnRuleColor));
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyWebkitTextStrokeColor, MaybeInvalidColor, &RenderStyle::textStrokeColor, &RenderStyle::setTextStrokeColor, &RenderStyle::visitedLinkTextStrokeColor, &RenderStyle::setVisitedLinkTextStrokeColor));
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderLeftColor, MaybeInvalidColor, &RenderStyle::borderLeftColor, &RenderStyle::setBorderLeftColor, &RenderStyle::visitedLinkBorderLeftColor, &RenderStyle::setVisitedLinkBorderLeftColor));
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderRightColor, MaybeInvalidColor, &RenderStyle::borderRightColor, &RenderStyle::setBorderRightColor, &RenderStyle::visitedLinkBorderRightColor, &RenderStyle::setVisitedLinkBorderRightColor));
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderTopColor, MaybeInvalidColor, &RenderStyle::borderTopColor, &RenderStyle::setBorderTopColor, &RenderStyle::visitedLinkBorderTopColor, &RenderStyle::setVisitedLinkBorderTopColor));
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyBorderBottomColor, MaybeInvalidColor, &RenderStyle::borderBottomColor, &RenderStyle::setBorderBottomColor, &RenderStyle::visitedLinkBorderBottomColor, &RenderStyle::setVisitedLinkBorderBottomColor));
- gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyOutlineColor, MaybeInvalidColor, &RenderStyle::outlineColor, &RenderStyle::setOutlineColor, &RenderStyle::visitedLinkOutlineColor, &RenderStyle::setVisitedLinkOutlineColor));
-
- gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow));
- gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow));
- gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow));
-
- gPropertyWrappers->append(new PropertyWrapperSVGPaint(CSSPropertyFill, &RenderStyle::fillPaintType, &RenderStyle::fillPaintColor, &RenderStyle::setFillPaintColor));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFillOpacity, &RenderStyle::fillOpacity, &RenderStyle::setFillOpacity));
-
- gPropertyWrappers->append(new PropertyWrapperSVGPaint(CSSPropertyStroke, &RenderStyle::strokePaintType, &RenderStyle::strokePaintColor, &RenderStyle::setStrokePaintColor));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity, &RenderStyle::setStrokeOpacity));
- gPropertyWrappers->append(new PropertyWrapper<SVGLength>(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth, &RenderStyle::setStrokeWidth));
- gPropertyWrappers->append(new PropertyWrapper< Vector<SVGLength> >(CSSPropertyStrokeDasharray, &RenderStyle::strokeDashArray, &RenderStyle::setStrokeDashArray));
- gPropertyWrappers->append(new PropertyWrapper<SVGLength>(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset, &RenderStyle::setStrokeDashOffset));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStrokeMiterlimit, &RenderStyle::strokeMiterLimit, &RenderStyle::setStrokeMiterLimit));
-
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity, &RenderStyle::setFloodOpacity));
- gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyFloodColor, &RenderStyle::floodColor, &RenderStyle::setFloodColor));
-
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStopOpacity, &RenderStyle::stopOpacity, &RenderStyle::setStopOpacity));
- gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyStopColor, &RenderStyle::stopColor, &RenderStyle::setStopColor));
-
- gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyLightingColor, &RenderStyle::lightingColor, &RenderStyle::setLightingColor));
-
- gPropertyWrappers->append(new PropertyWrapper<SVGLength>(CSSPropertyBaselineShift, &RenderStyle::baselineShiftValue, &RenderStyle::setBaselineShiftValue));
- gPropertyWrappers->append(new PropertyWrapper<SVGLength>(CSSPropertyKerning, &RenderStyle::kerning, &RenderStyle::setKerning));
-
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFlexGrow, &RenderStyle::flexGrow, &RenderStyle::setFlexGrow));
- gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFlexShrink, &RenderStyle::flexShrink, &RenderStyle::setFlexShrink));
- gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyFlexBasis, &RenderStyle::flexBasis, &RenderStyle::setFlexBasis));
- }
-
- // TODO:
- //
- // CSSPropertyVerticalAlign
- //
- // Compound properties that have components that should be animatable:
- //
- // CSSPropertyWebkitColumns
- // CSSPropertyWebkitBoxReflect
-
- // Make sure unused slots have a value
- for (unsigned int i = 0; i < static_cast<unsigned int>(numCSSProperties); ++i)
- gPropertyWrapperMap[i] = cInvalidPropertyWrapperIndex;
-
- // First we put the non-shorthand property wrappers into the map, so the shorthand-building
- // code can find them.
- size_t n = gPropertyWrappers->size();
- for (unsigned int i = 0; i < n; ++i) {
- CSSPropertyID property = (*gPropertyWrappers)[i]->property();
- ASSERT_WITH_MESSAGE(RuntimeEnabledFeatures::webAnimationsCSSEnabled() || CSSAnimations::isAnimatableProperty(property), "%s is not whitelisted for animation", getPropertyNameString(property).utf8().data());
- ASSERT(property - firstCSSProperty < numCSSProperties);
- gPropertyWrapperMap[property - firstCSSProperty] = i;
- }
-
- // Now add the shorthand wrappers.
- addShorthandProperties();
-}
-
-// Returns true if we need to start animation timers
-bool CSSPropertyAnimation::blendProperties(const AnimationBase* anim, CSSPropertyID prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress)
-{
- ASSERT(prop != CSSPropertyInvalid);
-
- ensurePropertyMap();
-
- AnimationPropertyWrapperBase* wrapper = wrapperForProperty(prop);
- if (wrapper) {
- wrapper->blend(anim, dst, a, b, progress);
- return !wrapper->animationIsAccelerated() || !anim->isAccelerated();
- }
-
- return false;
-}
-
-bool CSSPropertyAnimation::animationOfPropertyIsAccelerated(CSSPropertyID prop)
-{
- ensurePropertyMap();
- AnimationPropertyWrapperBase* wrapper = wrapperForProperty(prop);
- return wrapper ? wrapper->animationIsAccelerated() : false;
-}
-
-bool CSSPropertyAnimation::propertiesEqual(CSSPropertyID prop, const RenderStyle* a, const RenderStyle* b)
-{
- ensurePropertyMap();
-
- AnimationPropertyWrapperBase* wrapper = wrapperForProperty(prop);
- if (wrapper)
- return wrapper->equals(a, b);
- return true;
-}
-
-CSSPropertyID CSSPropertyAnimation::getPropertyAtIndex(int i, bool& isShorthand)
-{
- ensurePropertyMap();
-
- if (i < 0 || i >= getNumProperties())
- return CSSPropertyInvalid;
-
- AnimationPropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
- isShorthand = wrapper->isShorthandWrapper();
- return wrapper->property();
-}
-
-int CSSPropertyAnimation::getNumProperties()
-{
- ensurePropertyMap();
-
- return gPropertyWrappers->size();
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/CSSPropertyAnimation.h b/chromium/third_party/WebKit/Source/core/frame/animation/CSSPropertyAnimation.h
deleted file mode 100644
index 6ffd75c1a83..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/CSSPropertyAnimation.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSPropertyAnimation_h
-#define CSSPropertyAnimation_h
-
-#include "CSSPropertyNames.h"
-
-namespace WebCore {
-
-class AnimationBase;
-class RenderStyle;
-
-class CSSPropertyAnimation {
-public:
- static bool animationOfPropertyIsAccelerated(CSSPropertyID);
- static bool propertiesEqual(CSSPropertyID, const RenderStyle* a, const RenderStyle* b);
- static CSSPropertyID getPropertyAtIndex(int, bool& isShorthand);
- static int getNumProperties();
-
- // Return true if we need to start software animation timers
- static bool blendProperties(const AnimationBase*, CSSPropertyID, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress);
-private:
- static void ensurePropertyMap();
-};
-
-} // namespace WebCore
-
-#endif // CSSPropertyAnimation_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/CompositeAnimation.cpp b/chromium/third_party/WebKit/Source/core/frame/animation/CompositeAnimation.cpp
deleted file mode 100644
index f20f6856683..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/CompositeAnimation.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/animation/CompositeAnimation.h"
-
-#include "CSSPropertyNames.h"
-#include "core/frame/animation/AnimationControllerPrivate.h"
-#include "core/frame/animation/CSSPropertyAnimation.h"
-#include "core/rendering/style/RenderStyle.h"
-
-namespace WebCore {
-
-CompositeAnimation::~CompositeAnimation()
-{
- // Toss the refs to all animations, but make sure we remove them from
- // any waiting lists first.
-
- clearRenderer();
- m_transitions.clear();
- m_keyframeAnimations.clear();
-}
-
-void CompositeAnimation::clearRenderer()
-{
- if (!m_transitions.isEmpty()) {
- // Clear the renderers from all running animations, in case we are in the middle of
- // an animation callback (see https://bugs.webkit.org/show_bug.cgi?id=22052)
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* transition = it->value.get();
- animationController()->animationWillBeRemoved(transition);
- transition->clear();
- }
- }
- if (!m_keyframeAnimations.isEmpty()) {
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->value.get();
- animationController()->animationWillBeRemoved(anim);
- anim->clear();
- }
- }
-}
-
-void CompositeAnimation::updateTransitions(RenderObject& renderer, RenderStyle* currentStyle, RenderStyle& targetStyle)
-{
- // If currentStyle is null or there are no old or new transitions, just skip it
- if (!currentStyle || (!targetStyle.transitions() && m_transitions.isEmpty()))
- return;
-
- // Mark all existing transitions as no longer active. We will mark the still active ones
- // in the next loop and then toss the ones that didn't get marked.
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it)
- it->value->setActive(false);
-
- RefPtr<RenderStyle> modifiedCurrentStyle;
-
- // Check to see if we need to update the active transitions
- if (targetStyle.transitions()) {
- for (size_t i = 0; i < targetStyle.transitions()->size(); ++i) {
- const CSSAnimationData* anim = targetStyle.transitions()->animation(i);
- bool isActiveTransition = anim->duration() || anim->delay() > 0;
-
- CSSAnimationData::AnimationMode mode = anim->animationMode();
- if (mode == CSSAnimationData::AnimateNone)
- continue;
-
- CSSPropertyID prop = anim->property();
-
- bool all = mode == CSSAnimationData::AnimateAll;
-
- // Handle both the 'all' and single property cases. For the single prop case, we make only one pass
- // through the loop.
- for (int propertyIndex = 0; propertyIndex < CSSPropertyAnimation::getNumProperties(); ++propertyIndex) {
- if (all) {
- // Get the next property which is not a shorthand.
- bool isShorthand;
- prop = CSSPropertyAnimation::getPropertyAtIndex(propertyIndex, isShorthand);
- if (isShorthand)
- continue;
- }
-
- // ImplicitAnimations are always hashed by actual properties, never animateAll.
- ASSERT(prop >= firstCSSProperty && prop < (firstCSSProperty + numCSSProperties));
-
- // If there is a running animation for this property, the transition is overridden
- // and we have to use the unanimatedStyle from the animation. We do the test
- // against the unanimated style here, but we "override" the transition later.
- RefPtr<KeyframeAnimation> keyframeAnim = getAnimationForProperty(prop);
- RenderStyle* fromStyle = keyframeAnim ? keyframeAnim->unanimatedStyle() : currentStyle;
-
- // See if there is a current transition for this prop
- ImplicitAnimation* implAnim = m_transitions.get(prop);
- bool equal = true;
-
- if (implAnim) {
- // If we are post active don't bother setting the active flag. This will cause
- // this animation to get removed at the end of this function.
- if (!implAnim->postActive())
- implAnim->setActive(true);
-
- // This might be a transition that is just finishing. That would be the case
- // if it were postActive. But we still need to check for equality because
- // it could be just finishing AND changing to a new goal state.
- //
- // This implAnim might also not be an already running transition. It might be
- // newly added to the list in a previous iteration. This would happen if
- // you have both an explicit transition-property and 'all' in the same
- // list. In this case, the latter one overrides the earlier one, so we
- // behave as though this is a running animation being replaced.
- if (!implAnim->isTargetPropertyEqual(prop, &targetStyle)) {
- // For accelerated animations we need to return a new RenderStyle with the _current_ value
- // of the property, so that restarted transitions use the correct starting point.
- if (CSSPropertyAnimation::animationOfPropertyIsAccelerated(prop) && implAnim->isAccelerated()) {
- if (!modifiedCurrentStyle)
- modifiedCurrentStyle = RenderStyle::clone(currentStyle);
-
- implAnim->blendPropertyValueInStyle(prop, modifiedCurrentStyle.get());
- }
- animationController()->animationWillBeRemoved(implAnim);
- m_transitions.remove(prop);
- equal = false;
- }
- } else {
- // We need to start a transition if it is active and the properties don't match
- equal = !isActiveTransition || CSSPropertyAnimation::propertiesEqual(prop, fromStyle, &targetStyle);
- }
-
- // We can be in this loop with an inactive transition (!isActiveTransition). We need
- // to do that to check to see if we are canceling a transition. But we don't want to
- // start one of the inactive transitions. So short circuit that here. (See
- // <https://bugs.webkit.org/show_bug.cgi?id=24787>
- if (!equal && isActiveTransition) {
- // Add the new transition
- m_transitions.set(prop, ImplicitAnimation::create(const_cast<CSSAnimationData*>(anim), prop, renderer, this, modifiedCurrentStyle ? modifiedCurrentStyle.get() : fromStyle));
- }
-
- // We only need one pass for the single prop case
- if (!all)
- break;
- }
- }
- }
-
- // Make a list of transitions to be removed
- Vector<int> toBeRemoved;
- end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (!anim->active()) {
- animationController()->animationWillBeRemoved(anim);
- toBeRemoved.append(anim->animatingProperty());
- }
- }
-
- // Now remove the transitions from the list
- for (size_t j = 0; j < toBeRemoved.size(); ++j)
- m_transitions.remove(toBeRemoved[j]);
-}
-
-void CompositeAnimation::updateKeyframeAnimations(RenderObject& renderer, RenderStyle* currentStyle, RenderStyle& targetStyle)
-{
- // Nothing to do if we don't have any animations, and didn't have any before
- if (m_keyframeAnimations.isEmpty() && !targetStyle.hasAnimations())
- return;
-
- AnimationNameMap::const_iterator kfend = m_keyframeAnimations.end();
-
- if (currentStyle && currentStyle->hasAnimations() && targetStyle.hasAnimations() && *(currentStyle->animations()) == *(targetStyle.animations())) {
- // The current and target animations are the same so we just need to toss any
- // animation which is finished (postActive).
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
- if (it->value->postActive())
- it->value->setIndex(-1);
- }
- } else {
- // Mark all existing animations as no longer active.
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it)
- it->value->setIndex(-1);
-
- // Toss the animation order map.
- m_keyframeAnimationOrderList.clear();
-
- DEFINE_STATIC_LOCAL(const AtomicString, none, ("none", AtomicString::ConstructFromLiteral));
-
- // Now mark any still active animations as active and add any new animations.
- if (targetStyle.animations()) {
- int numAnims = targetStyle.animations()->size();
- for (int i = 0; i < numAnims; ++i) {
- const CSSAnimationData* anim = targetStyle.animations()->animation(i);
- if (!anim->isValidAnimation())
- continue;
-
- // See if there is a current animation for this name.
- AtomicString name(anim->name());
- RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name);
- if (keyframeAnim) {
- // If this animation is postActive, skip it so it gets removed at the end of this function.
- if (keyframeAnim->postActive())
- continue;
-
- // This one is still active.
-
- // Animations match, but play states may differ. Update if needed.
- keyframeAnim->updatePlayState(anim->playState());
-
- // Set the saved animation to this new one, just in case the play state has changed.
- keyframeAnim->setAnimation(anim);
- keyframeAnim->setIndex(i);
- } else if ((anim->duration() || anim->delay()) && anim->iterationCount() && name != none) {
- keyframeAnim = KeyframeAnimation::create(const_cast<CSSAnimationData*>(anim), renderer, i, this, targetStyle);
- m_keyframeAnimations.set(name, keyframeAnim);
- }
-
- // Add this to the animation order map.
- if (keyframeAnim)
- m_keyframeAnimationOrderList.append(name);
- }
- }
- }
-
- // Make a list of animations to be removed.
- Vector<AtomicString> animsToBeRemoved;
- kfend = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != kfend; ++it) {
- KeyframeAnimation* keyframeAnim = it->value.get();
- if (keyframeAnim->index() < 0) {
- animsToBeRemoved.append(keyframeAnim->name());
- animationController()->animationWillBeRemoved(keyframeAnim);
- keyframeAnim->clear();
- }
- }
-
- // Now remove the animations from the list, and keep stale keys out of the order list.
- if (animsToBeRemoved.size()) {
- for (size_t j = 0; j < animsToBeRemoved.size(); ++j) {
- ASSERT(m_keyframeAnimations.contains(animsToBeRemoved[j]));
- m_keyframeAnimations.remove(animsToBeRemoved[j]);
- }
- Vector<AtomicString> newOrderList;
- for (size_t j = 0; j < m_keyframeAnimationOrderList.size(); ++j) {
- AtomicString key = m_keyframeAnimationOrderList[j];
- if (m_keyframeAnimations.contains(key))
- newOrderList.append(key);
- }
- m_keyframeAnimationOrderList.swap(newOrderList);
- }
-}
-
-PassRefPtr<RenderStyle> CompositeAnimation::animate(RenderObject& renderer, RenderStyle* currentStyle, RenderStyle& targetStyle)
-{
- RefPtr<RenderStyle> resultStyle;
-
- // We don't do any transitions if we don't have a currentStyle (on startup).
- updateTransitions(renderer, currentStyle, targetStyle);
- updateKeyframeAnimations(renderer, currentStyle, targetStyle);
-
- if (currentStyle) {
- // Now that we have transition objects ready, let them know about the new goal state. We want them
- // to fill in a RenderStyle*& only if needed.
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- if (ImplicitAnimation* anim = it->value.get())
- anim->animate(this, &renderer, currentStyle, &targetStyle, resultStyle);
- }
- }
- }
-
- // Now that we have animation objects ready, let them know about the new goal state. We want them
- // to fill in a RenderStyle*& only if needed.
- for (Vector<AtomicString>::const_iterator it = m_keyframeAnimationOrderList.begin(); it != m_keyframeAnimationOrderList.end(); ++it) {
- RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(*it);
- ASSERT(keyframeAnim);
- keyframeAnim->animate(this, &renderer, currentStyle, &targetStyle, resultStyle);
- }
-
- return resultStyle ? resultStyle.release() : PassRefPtr<RenderStyle>(targetStyle);
-}
-
-PassRefPtr<RenderStyle> CompositeAnimation::getAnimatedStyle() const
-{
- RefPtr<RenderStyle> resultStyle;
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- if (ImplicitAnimation* implicitAnimation = it->value.get())
- implicitAnimation->getAnimatedStyle(resultStyle);
- }
-
- for (Vector<AtomicString>::const_iterator it = m_keyframeAnimationOrderList.begin(); it != m_keyframeAnimationOrderList.end(); ++it) {
- RefPtr<KeyframeAnimation> keyframeAnimation = m_keyframeAnimations.get(*it);
- ASSERT(keyframeAnimation);
- keyframeAnimation->getAnimatedStyle(resultStyle);
- }
-
- return resultStyle;
-}
-
-double CompositeAnimation::timeToNextService() const
-{
- // Returns the time at which next service is required. -1 means no service is required. 0 means
- // service is required now, and > 0 means service is required that many seconds in the future.
- double minT = -1;
-
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* transition = it->value.get();
- double t = transition ? transition->timeToNextService() : -1;
- if (t < minT || minT == -1)
- minT = t;
- if (minT == 0)
- return 0;
- }
- }
- if (!m_keyframeAnimations.isEmpty()) {
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* animation = it->value.get();
- double t = animation ? animation->timeToNextService() : -1;
- if (t < minT || minT == -1)
- minT = t;
- if (minT == 0)
- return 0;
- }
- }
-
- return minT;
-}
-
-double CompositeAnimation::timeToNextEvent() const
-{
- // Returns the time at which next service to trigger events is required. -1 means no service is required. 0 means
- // service is required now, and > 0 means service is required that many seconds in the future.
- double minT = -1;
-
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* transition = it->value.get();
- double t = -1;
- bool isLooping;
- if (transition)
- transition->getTimeToNextEvent(t, isLooping);
- if (t < minT || minT == -1)
- minT = t;
- if (!minT)
- return 0;
- }
- }
- if (!m_keyframeAnimations.isEmpty()) {
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* animation = it->value.get();
- double t = -1;
- bool isLooping;
- if (animation)
- animation->getTimeToNextEvent(t, isLooping);
- if (t < minT || minT == -1)
- minT = t;
- if (!minT)
- return 0;
- }
- }
-
- return minT;
-}
-
-PassRefPtr<KeyframeAnimation> CompositeAnimation::getAnimationForProperty(CSSPropertyID property) const
-{
- RefPtr<KeyframeAnimation> retval;
-
- // We want to send back the last animation with the property if there are multiples.
- // So we need to iterate through all animations
- if (!m_keyframeAnimations.isEmpty()) {
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- RefPtr<KeyframeAnimation> anim = it->value;
- if (anim->hasAnimationForProperty(property))
- retval = anim;
- }
- }
-
- return retval;
-}
-
-void CompositeAnimation::overrideImplicitAnimations(CSSPropertyID property)
-{
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- if (!m_transitions.isEmpty()) {
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim && anim->animatingProperty() == property)
- anim->setOverridden(true);
- }
- }
-}
-
-void CompositeAnimation::resumeOverriddenImplicitAnimations(CSSPropertyID property)
-{
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator end = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != end; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim && anim->animatingProperty() == property)
- anim->setOverridden(false);
- }
- }
-}
-
-bool CompositeAnimation::isAnimatingProperty(CSSPropertyID property, bool acceleratedOnly, bool isRunningNow) const
-{
- if (!m_keyframeAnimations.isEmpty()) {
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->value.get();
- if (anim && anim->isAnimatingProperty(property, acceleratedOnly, isRunningNow))
- return true;
- }
- }
-
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim && anim->isAnimatingProperty(property, acceleratedOnly, isRunningNow))
- return true;
- }
- }
- return false;
-}
-
-void CompositeAnimation::pauseAnimationsForTesting(double t)
-{
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- RefPtr<KeyframeAnimation> keyframeAnim = it->value;
- if (!keyframeAnim || !keyframeAnim->running())
- continue;
-
- double count = keyframeAnim->m_animation->iterationCount();
- if ((t >= 0.0) && ((count == CSSAnimationData::IterationCountInfinite) || (t <= count * keyframeAnim->duration())))
- keyframeAnim->freezeAtTime(t);
- }
-
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- RefPtr<ImplicitAnimation> implAnim = it->value;
-
- if (!implAnim->running())
- continue;
-
- if ((t >= 0.0) && (t <= implAnim->duration()))
- implAnim->freezeAtTime(t);
- }
-}
-
-unsigned CompositeAnimation::numberOfActiveAnimations() const
-{
- unsigned count = 0;
-
- if (!m_keyframeAnimations.isEmpty()) {
- AnimationNameMap::const_iterator animationsEnd = m_keyframeAnimations.end();
- for (AnimationNameMap::const_iterator it = m_keyframeAnimations.begin(); it != animationsEnd; ++it) {
- KeyframeAnimation* anim = it->value.get();
- if (anim->running())
- ++count;
- }
- }
-
- if (!m_transitions.isEmpty()) {
- CSSPropertyTransitionsMap::const_iterator transitionsEnd = m_transitions.end();
- for (CSSPropertyTransitionsMap::const_iterator it = m_transitions.begin(); it != transitionsEnd; ++it) {
- ImplicitAnimation* anim = it->value.get();
- if (anim->running())
- ++count;
- }
- }
-
- return count;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/CompositeAnimation.h b/chromium/third_party/WebKit/Source/core/frame/animation/CompositeAnimation.h
deleted file mode 100644
index ee0bd467288..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/CompositeAnimation.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CompositeAnimation_h
-#define CompositeAnimation_h
-
-#include "core/frame/animation/ImplicitAnimation.h"
-#include "core/frame/animation/KeyframeAnimation.h"
-#include "wtf/HashMap.h"
-
-namespace WebCore {
-
-class AnimationControllerPrivate;
-class AnimationController;
-class RenderObject;
-class RenderStyle;
-
-// A CompositeAnimation represents a collection of animations that are running
-// on a single RenderObject, such as a number of properties transitioning at once.
-class CompositeAnimation : public RefCounted<CompositeAnimation> {
-public:
- static PassRefPtr<CompositeAnimation> create(AnimationControllerPrivate* animationController)
- {
- return adoptRef(new CompositeAnimation(animationController));
- };
-
- ~CompositeAnimation();
-
- void clearRenderer();
-
- PassRefPtr<RenderStyle> animate(RenderObject&, RenderStyle* currentStyle, RenderStyle& targetStyle);
- PassRefPtr<RenderStyle> getAnimatedStyle() const;
-
- double timeToNextService() const;
- double timeToNextEvent() const;
-
- AnimationControllerPrivate* animationController() const { return m_animationController; }
-
- bool hasAnimations() const { return !m_transitions.isEmpty() || !m_keyframeAnimations.isEmpty(); }
-
- bool isAnimatingProperty(CSSPropertyID, bool acceleratedOnly, bool isRunningNow) const;
-
- PassRefPtr<KeyframeAnimation> getAnimationForProperty(CSSPropertyID) const;
-
- void overrideImplicitAnimations(CSSPropertyID);
- void resumeOverriddenImplicitAnimations(CSSPropertyID);
-
- void pauseAnimationsForTesting(double t);
- unsigned numberOfActiveAnimations() const;
-
-private:
- CompositeAnimation(AnimationControllerPrivate* animationController)
- : m_animationController(animationController)
- {
- }
-
- void updateTransitions(RenderObject&, RenderStyle* currentStyle, RenderStyle& targetStyle);
- void updateKeyframeAnimations(RenderObject&, RenderStyle* currentStyle, RenderStyle& targetStyle);
-
- typedef HashMap<int, RefPtr<ImplicitAnimation> > CSSPropertyTransitionsMap;
- typedef HashMap<AtomicString, RefPtr<KeyframeAnimation> > AnimationNameMap;
-
- AnimationControllerPrivate* m_animationController;
- CSSPropertyTransitionsMap m_transitions;
- AnimationNameMap m_keyframeAnimations;
- Vector<AtomicString> m_keyframeAnimationOrderList;
-};
-
-} // namespace WebCore
-
-#endif // CompositeAnimation_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/ImplicitAnimation.cpp b/chromium/third_party/WebKit/Source/core/frame/animation/ImplicitAnimation.cpp
deleted file mode 100644
index 2cf82b64b2b..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/ImplicitAnimation.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/UseCounter.h"
-#include "core/frame/animation/AnimationControllerPrivate.h"
-#include "core/frame/animation/CSSPropertyAnimation.h"
-#include "core/frame/animation/CompositeAnimation.h"
-#include "core/frame/animation/ImplicitAnimation.h"
-#include "core/frame/animation/KeyframeAnimation.h"
-#include "core/rendering/RenderBoxModelObject.h"
-#include "public/platform/Platform.h"
-
-namespace WebCore {
-
-ImplicitAnimation::ImplicitAnimation(const CSSAnimationData* transition, CSSPropertyID animatingProperty, RenderObject& renderer, CompositeAnimation* compAnim, RenderStyle* fromStyle)
- : AnimationBase(transition, renderer, compAnim)
- , m_transitionProperty(transition->property())
- , m_animatingProperty(animatingProperty)
- , m_overridden(false)
- , m_active(true)
- , m_fromStyle(fromStyle)
-{
- ASSERT(animatingProperty != CSSPropertyInvalid);
- blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProperties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(m_animatingProperty));
-}
-
-ImplicitAnimation::~ImplicitAnimation()
-{
- // // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
- if (!postActive())
- endAnimation();
-}
-
-bool ImplicitAnimation::shouldSendEventForListener(Document::ListenerType inListenerType) const
-{
- return m_object->document().hasListenerType(inListenerType);
-}
-
-void ImplicitAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
-{
- // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
- // So just return. Everything is already all cleaned up.
- if (postActive())
- return;
-
- // Reset to start the transition if we are new
- if (isNew())
- reset(targetStyle);
-
- // Run a cycle of animation.
- // We know we will need a new render style, so make one if needed
- if (!animatedStyle)
- animatedStyle = RenderStyle::clone(targetStyle);
-
- bool needsAnim = CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
- // FIXME: we also need to detect cases where we have to software animate for other reasons,
- // such as a child using inheriting the transform. https://bugs.webkit.org/show_bug.cgi?id=23902
- if (!needsAnim)
- // If we are running an accelerated animation, set a flag in the style which causes the style
- // to compare as different to any other style. This ensures that changes to the property
- // that is animating are correctly detected during the animation (e.g. when a transition
- // gets interrupted).
- animatedStyle->setIsRunningAcceleratedAnimation();
-
- // Fire the start timeout if needed
- fireAnimationEventsIfNeeded();
-}
-
-void ImplicitAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
-{
- if (!animatedStyle)
- animatedStyle = RenderStyle::clone(m_toStyle.get());
-
- CSSPropertyAnimation::blendProperties(this, m_animatingProperty, animatedStyle.get(), m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
-}
-
-void ImplicitAnimation::startAnimation(double timeOffset)
-{
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking)
- m_isAccelerated = toRenderBoxModelObject(m_object)->startTransition(timeOffset, m_animatingProperty, m_fromStyle.get(), m_toStyle.get());
-}
-
-void ImplicitAnimation::pauseAnimation(double timeOffset)
-{
- if (!m_object)
- return;
-
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
- toRenderBoxModelObject(m_object)->transitionPaused(timeOffset, m_animatingProperty);
-
- // Restore the original (unanimated) style
- if (!paused())
- setNeedsStyleRecalc(m_object->node());
-}
-
-void ImplicitAnimation::endAnimation()
-{
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
- toRenderBoxModelObject(m_object)->transitionFinished(m_animatingProperty);
- m_isAccelerated = false;
-}
-
-void ImplicitAnimation::onAnimationEnd(double elapsedTime)
-{
- // If we have a keyframe animation on this property, this transition is being overridden. The keyframe
- // animation keeps an unanimated style in case a transition starts while the keyframe animation is
- // running. But now that the transition has completed, we need to update this style with its new
- // destination. If we didn't, the next time through we would think a transition had started
- // (comparing the old unanimated style with the new final style of the transition).
- RefPtr<KeyframeAnimation> keyframeAnim = m_compAnim->getAnimationForProperty(m_animatingProperty);
- if (keyframeAnim)
- keyframeAnim->setUnanimatedStyle(m_toStyle);
-
- sendTransitionEvent(EventTypeNames::transitionend, elapsedTime);
- endAnimation();
-}
-
-bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime)
-{
- if (eventType == EventTypeNames::transitionend) {
- Document::ListenerType listenerType = Document::TRANSITIONEND_LISTENER;
-
- if (shouldSendEventForListener(listenerType)) {
- String propertyName = getPropertyNameString(m_animatingProperty);
-
- // Dispatch the event
- RefPtr<Element> element = 0;
- if (m_object->node() && m_object->node()->isElementNode())
- element = toElement(m_object->node());
-
- if (!element)
- return false;
-
- // Schedule event handling
- m_compAnim->animationController()->addEventToDispatch(element, eventType, propertyName, elapsedTime);
-
- // Restore the original (unanimated) style
- if (eventType == EventTypeNames::transitionend && element->renderer())
- setNeedsStyleRecalc(element.get());
-
- return true; // Did dispatch an event
- }
- }
-
- return false; // Didn't dispatch an event
-}
-
-void ImplicitAnimation::reset(RenderStyle* to)
-{
- ASSERT(to);
- ASSERT(m_fromStyle);
-
- m_toStyle = to;
-
- // Restart the transition
- if (m_fromStyle && m_toStyle)
- updateStateMachine(AnimationStateInputRestartAnimation, -1);
-
- // set the transform animation list
- validateTransformFunctionList();
- checkForMatchingFilterFunctionLists();
-}
-
-void ImplicitAnimation::setOverridden(bool b)
-{
- if (b == m_overridden)
- return;
-
- m_overridden = b;
- updateStateMachine(m_overridden ? AnimationStateInputPauseOverride : AnimationStateInputResumeOverride, -1);
-}
-
-bool ImplicitAnimation::affectsProperty(CSSPropertyID property) const
-{
- return (m_animatingProperty == property);
-}
-
-bool ImplicitAnimation::isTargetPropertyEqual(CSSPropertyID prop, const RenderStyle* targetStyle)
-{
- // We can get here for a transition that has not started yet. This would make m_toStyle unset and null.
- // So we check that here (see <https://bugs.webkit.org/show_bug.cgi?id=26706>)
- if (!m_toStyle)
- return false;
- return CSSPropertyAnimation::propertiesEqual(prop, m_toStyle.get(), targetStyle);
-}
-
-void ImplicitAnimation::blendPropertyValueInStyle(CSSPropertyID prop, RenderStyle* currentStyle)
-{
- // We should never add a transition with a 0 duration and delay. But if we ever did
- // it would have a null toStyle. So just in case, let's check that here. (See
- // <https://bugs.webkit.org/show_bug.cgi?id=24787>
- if (!m_toStyle)
- return;
-
- CSSPropertyAnimation::blendProperties(this, prop, currentStyle, m_fromStyle.get(), m_toStyle.get(), progress(1, 0, 0));
-}
-
-void ImplicitAnimation::validateTransformFunctionList()
-{
- m_transformFunctionListValid = false;
-
- if (!m_fromStyle || !m_toStyle)
- return;
-
- const TransformOperations* val = &m_fromStyle->transform();
- const TransformOperations* toVal = &m_toStyle->transform();
-
- if (val->operations().isEmpty())
- val = toVal;
-
- if (val->operations().isEmpty())
- return;
-
- // An emtpy transform list matches anything.
- if (val != toVal && !toVal->operations().isEmpty() && !val->operationsMatch(*toVal))
- return;
-
- // Transform lists match.
- m_transformFunctionListValid = true;
-}
-
-void ImplicitAnimation::checkForMatchingFilterFunctionLists()
-{
- m_filterFunctionListsMatch = false;
-
- if (!m_fromStyle || !m_toStyle)
- return;
-
- const FilterOperations* val = &m_fromStyle->filter();
- const FilterOperations* toVal = &m_toStyle->filter();
-
- if (!val->canInterpolateWith(*toVal))
- return;
-
- // Filter lists match.
- m_filterFunctionListsMatch = true;
-}
-
-double ImplicitAnimation::timeToNextService()
-{
- double t = AnimationBase::timeToNextService();
- if (t != 0 || preActive())
- return t;
-
- // A return value of 0 means we need service. But if this is an accelerated animation we
- // only need service at the end of the transition.
- if (CSSPropertyAnimation::animationOfPropertyIsAccelerated(m_animatingProperty) && isAccelerated()) {
- bool isLooping;
- getTimeToNextEvent(t, isLooping);
- }
-
- return t;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/ImplicitAnimation.h b/chromium/third_party/WebKit/Source/core/frame/animation/ImplicitAnimation.h
deleted file mode 100644
index c531b36a81d..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/ImplicitAnimation.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ImplicitAnimation_h
-#define ImplicitAnimation_h
-
-#include "CSSPropertyNames.h"
-#include "core/dom/Document.h"
-#include "core/frame/animation/AnimationBase.h"
-
-namespace WebCore {
-
-// An ImplicitAnimation tracks the state of a transition of a specific CSS property
-// for a single RenderObject.
-class ImplicitAnimation : public AnimationBase {
-public:
- static PassRefPtr<ImplicitAnimation> create(const CSSAnimationData* animation, CSSPropertyID animatingProperty, RenderObject& renderer, CompositeAnimation* compositeAnimation, RenderStyle* fromStyle)
- {
- return adoptRef(new ImplicitAnimation(animation, animatingProperty, renderer, compositeAnimation, fromStyle));
- };
-
- CSSPropertyID transitionProperty() const { return m_transitionProperty; }
- CSSPropertyID animatingProperty() const { return m_animatingProperty; }
-
- virtual void onAnimationEnd(double elapsedTime);
- virtual void startAnimation(double timeOffset);
- virtual void pauseAnimation(double /*timeOffset*/);
- virtual void endAnimation();
-
- virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
- virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle);
- virtual void reset(RenderStyle* to);
-
- void setOverridden(bool);
- virtual bool overridden() const { return m_overridden; }
-
- virtual bool affectsProperty(CSSPropertyID) const;
-
- bool hasStyle() const { return m_fromStyle && m_toStyle; }
-
- bool isTargetPropertyEqual(CSSPropertyID, const RenderStyle*);
-
- void blendPropertyValueInStyle(CSSPropertyID, RenderStyle*);
-
- virtual double timeToNextService();
-
- bool active() const { return m_active; }
- void setActive(bool b) { m_active = b; }
-
-protected:
- bool shouldSendEventForListener(Document::ListenerType) const;
- bool sendTransitionEvent(const AtomicString&, double elapsedTime);
-
- void validateTransformFunctionList();
- void checkForMatchingFilterFunctionLists();
-
-private:
- ImplicitAnimation(const CSSAnimationData*, CSSPropertyID, RenderObject&, CompositeAnimation*, RenderStyle*);
- virtual ~ImplicitAnimation();
-
- CSSPropertyID m_transitionProperty; // Transition property as specified in the RenderStyle.
- CSSPropertyID m_animatingProperty; // Specific property for this ImplicitAnimation
- bool m_overridden; // true when there is a keyframe animation that overrides the transitioning property
- bool m_active; // used for culling the list of transitions
-
- // The two styles that we are blending.
- RefPtr<RenderStyle> m_fromStyle;
- RefPtr<RenderStyle> m_toStyle;
-};
-
-} // namespace WebCore
-
-#endif // ImplicitAnimation_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/KeyframeAnimation.cpp b/chromium/third_party/WebKit/Source/core/frame/animation/KeyframeAnimation.cpp
deleted file mode 100644
index 948ca03ce42..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/KeyframeAnimation.cpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (C) 2007, 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/animation/KeyframeAnimation.h"
-
-#include "CSSPropertyNames.h"
-#include "core/css/resolver/StyleResolver.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/UseCounter.h"
-#include "core/frame/animation/AnimationControllerPrivate.h"
-#include "core/frame/animation/CSSPropertyAnimation.h"
-#include "core/frame/animation/CompositeAnimation.h"
-#include "core/rendering/RenderBoxModelObject.h"
-#include "core/rendering/style/RenderStyle.h"
-#include "public/platform/Platform.h"
-
-using namespace std;
-
-namespace WebCore {
-
-KeyframeAnimation::KeyframeAnimation(const CSSAnimationData* animation, RenderObject& renderer, int index, CompositeAnimation* compAnim, RenderStyle& unanimatedStyle)
- : AnimationBase(animation, renderer, compAnim)
- , m_keyframes(renderer, animation->name())
- , m_index(index)
- , m_startEventDispatched(false)
- , m_unanimatedStyle(unanimatedStyle)
-{
- // Get the keyframe RenderStyles
- if (m_object && m_object->node() && m_object->node()->isElementNode())
- m_object->document().ensureStyleResolver().keyframeStylesForAnimation(toElement(m_object->node()), unanimatedStyle, m_keyframes);
-
- // Update the m_transformFunctionListValid flag based on whether the function lists in the keyframes match.
- validateTransformFunctionList();
- checkForMatchingFilterFunctionLists();
- HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it)
- blink::Platform::current()->histogramSparse("WebCore.Animation.CSSProperties", UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(*it));
-}
-
-KeyframeAnimation::~KeyframeAnimation()
-{
- // Make sure to tell the renderer that we are ending. This will make sure any accelerated animations are removed.
- if (!postActive())
- endAnimation();
-}
-
-void KeyframeAnimation::fetchIntervalEndpointsForProperty(CSSPropertyID property, const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& prog) const
-{
- // Find the first key
- double elapsedTime = getElapsedTime();
- if (m_animation->duration() && m_animation->iterationCount() != CSSAnimationData::IterationCountInfinite)
- elapsedTime = min(elapsedTime, m_animation->duration() * m_animation->iterationCount());
-
- const double fractionalTime = this->fractionalTime(1, elapsedTime, 0);
-
- size_t numKeyframes = m_keyframes.size();
- if (!numKeyframes)
- return;
-
- ASSERT(!m_keyframes[0].key());
- ASSERT(m_keyframes[m_keyframes.size() - 1].key() == 1);
-
- size_t currentIndex = 0;
- size_t firstIndex = 0;
- size_t lastIndex = numKeyframes - 1;
- size_t distance = numKeyframes;
-
- // Find keyframe that is closest to elapsed time.
- while (distance > 1) {
- currentIndex = (lastIndex + firstIndex) >> 1;
- double key = m_keyframes[currentIndex].key();
- distance = lastIndex - currentIndex;
-
- if (key < fractionalTime) {
- if (distance < 2)
- currentIndex++;
- firstIndex = currentIndex;
- } else {
- lastIndex = currentIndex;
- }
- }
-
- int prevIndex = -1;
- int nextIndex = -1;
-
- // Iterate forward to find next keyframe that is used to animate CSS property.
- for (size_t i = currentIndex; i < numKeyframes; ++i) {
- const KeyframeValue& keyFrame = m_keyframes[i];
- if (keyFrame.key() > fractionalTime && keyFrame.containsProperty(property)) {
- nextIndex = i;
- break;
- }
- }
-
- // Iterate backward to find previous keyframe.
- for (int i = currentIndex; i >= 0; --i) {
- const KeyframeValue& keyFrame = m_keyframes[i];
- if (keyFrame.key() <= fractionalTime && keyFrame.containsProperty(property)) {
- prevIndex = i;
- break;
- }
- }
-
- double scale = 1;
- double offset = 0;
-
- if (prevIndex == -1)
- prevIndex = 0;
-
- if (nextIndex == -1)
- nextIndex = numKeyframes - 1;
-
- const KeyframeValue& prevKeyframe = m_keyframes[prevIndex];
- const KeyframeValue& nextKeyframe = m_keyframes[nextIndex];
-
- fromStyle = prevKeyframe.style();
- toStyle = nextKeyframe.style();
-
- offset = prevKeyframe.key();
- scale = 1.0 / (nextKeyframe.key() - prevKeyframe.key());
- // A scale of infinity is handled in AnimationBase::fractionalTime().
- ASSERT(scale >= 0 && (!std::isinf(scale) || prevIndex == nextIndex));
-
- prog = progress(scale, offset, KeyframeValue::timingFunction(*prevKeyframe.style()));
-}
-
-void KeyframeAnimation::animate(CompositeAnimation*, RenderObject*, const RenderStyle*, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle)
-{
- // Fire the start timeout if needed
- fireAnimationEventsIfNeeded();
-
- // If we have not yet started, we will not have a valid start time, so just start the animation if needed.
- if (isNew() && m_animation->playState() == AnimPlayStatePlaying)
- updateStateMachine(AnimationStateInputStartAnimation, -1);
-
- // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
- // If so, we need to send back the targetStyle.
- if (postActive()) {
- if (!animatedStyle)
- animatedStyle = const_cast<RenderStyle*>(targetStyle);
- return;
- }
-
- // If we are waiting for the start timer, we don't want to change the style yet.
- // Special case 1 - if the delay time is 0, then we do want to set the first frame of the
- // animation right away. This avoids a flash when the animation starts.
- // Special case 2 - if there is a backwards fill mode, then we want to continue
- // through to the style blend so that we get the fromStyle.
- if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
- return;
-
- // If we have no keyframes, don't animate.
- if (!m_keyframes.size()) {
- updateStateMachine(AnimationStateInputEndAnimation, -1);
- return;
- }
-
- // Run a cycle of animation.
- // We know we will need a new render style, so make one if needed.
- if (!animatedStyle)
- animatedStyle = RenderStyle::clone(targetStyle);
-
- // FIXME: we need to be more efficient about determining which keyframes we are animating between.
- // We should cache the last pair or something.
- HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
- // Get the from/to styles and progress between
- const RenderStyle* fromStyle = 0;
- const RenderStyle* toStyle = 0;
- double progress = 0.0;
- fetchIntervalEndpointsForProperty(*it, fromStyle, toStyle, progress);
-
- bool needsAnim = CSSPropertyAnimation::blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress);
- if (!needsAnim)
- // If we are running an accelerated animation, set a flag in the style
- // to indicate it. This can be used to make sure we get an updated
- // style for hit testing, etc.
- animatedStyle->setIsRunningAcceleratedAnimation();
- }
-}
-
-void KeyframeAnimation::getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle)
-{
- // If we're in the delay phase and we're not backwards filling, tell the caller
- // to use the current style.
- if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
- return;
-
- if (!m_keyframes.size())
- return;
-
- if (!animatedStyle)
- animatedStyle = RenderStyle::clone(m_object->style());
-
- HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
- // Get the from/to styles and progress between
- const RenderStyle* fromStyle = 0;
- const RenderStyle* toStyle = 0;
- double progress = 0.0;
- fetchIntervalEndpointsForProperty(*it, fromStyle, toStyle, progress);
-
- CSSPropertyAnimation::blendProperties(this, *it, animatedStyle.get(), fromStyle, toStyle, progress);
- }
-}
-
-bool KeyframeAnimation::hasAnimationForProperty(CSSPropertyID property) const
-{
- return m_keyframes.containsProperty(property);
-}
-
-void KeyframeAnimation::startAnimation(double timeOffset)
-{
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking)
- m_isAccelerated = toRenderBoxModelObject(m_object)->startAnimation(timeOffset, m_animation.get(), m_keyframes);
-}
-
-void KeyframeAnimation::pauseAnimation(double timeOffset)
-{
- if (!m_object)
- return;
-
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
- toRenderBoxModelObject(m_object)->animationPaused(timeOffset, m_keyframes.animationName());
-
- // Restore the original (unanimated) style
- if (!paused())
- setNeedsStyleRecalc(m_object->node());
-}
-
-void KeyframeAnimation::endAnimation()
-{
- if (!m_object)
- return;
-
- if (m_object && m_object->compositingState() == PaintsIntoOwnBacking && isAccelerated())
- toRenderBoxModelObject(m_object)->animationFinished(m_keyframes.animationName());
- m_isAccelerated = false;
-
- // Restore the original (unanimated) style
- if (!paused())
- setNeedsStyleRecalc(m_object->node());
-}
-
-bool KeyframeAnimation::shouldSendEventForListener(Document::ListenerType listenerType) const
-{
- return m_object->document().hasListenerType(listenerType);
-}
-
-void KeyframeAnimation::onAnimationStart(double elapsedTime)
-{
- sendAnimationEvent(EventTypeNames::animationstart, elapsedTime);
-}
-
-void KeyframeAnimation::onAnimationIteration(double elapsedTime)
-{
- sendAnimationEvent(EventTypeNames::animationiteration, elapsedTime);
-}
-
-void KeyframeAnimation::onAnimationEnd(double elapsedTime)
-{
- sendAnimationEvent(EventTypeNames::animationend, elapsedTime);
- // End the animation if we don't fill forwards. Forward filling
- // animations are ended properly in the class destructor.
- if (!m_animation->fillsForwards())
- endAnimation();
-}
-
-bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime)
-{
- Document::ListenerType listenerType;
- if (eventType == EventTypeNames::animationiteration)
- listenerType = Document::ANIMATIONITERATION_LISTENER;
- else if (eventType == EventTypeNames::animationend)
- listenerType = Document::ANIMATIONEND_LISTENER;
- else {
- ASSERT(eventType == EventTypeNames::animationstart);
- if (m_startEventDispatched)
- return false;
- m_startEventDispatched = true;
- listenerType = Document::ANIMATIONSTART_LISTENER;
- }
-
- if (shouldSendEventForListener(listenerType)) {
- // Dispatch the event
- RefPtr<Element> element;
- if (m_object->node() && m_object->node()->isElementNode())
- element = toElement(m_object->node());
-
- if (!element)
- return false;
-
- // Schedule event handling
- m_compAnim->animationController()->addEventToDispatch(element, eventType, m_keyframes.animationName(), elapsedTime);
-
- // Restore the original (unanimated) style
- if (eventType == EventTypeNames::animationend && element->renderer())
- setNeedsStyleRecalc(element.get());
-
- return true; // Did dispatch an event
- }
-
- return false; // Did not dispatch an event
-}
-
-void KeyframeAnimation::overrideAnimations()
-{
- // This will override implicit animations that match the properties in the keyframe animation
- HashSet<CSSPropertyID>::const_iterator end = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
- compositeAnimation()->overrideImplicitAnimations(*it);
-}
-
-void KeyframeAnimation::resumeOverriddenAnimations()
-{
- // This will resume overridden implicit animations
- HashSet<CSSPropertyID>::const_iterator end = m_keyframes.endProperties();
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != end; ++it)
- compositeAnimation()->resumeOverriddenImplicitAnimations(*it);
-}
-
-bool KeyframeAnimation::affectsProperty(CSSPropertyID property) const
-{
- return m_keyframes.containsProperty(property);
-}
-
-void KeyframeAnimation::validateTransformFunctionList()
-{
- m_transformFunctionListValid = false;
-
- if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitTransform))
- return;
-
- // Empty transforms match anything, so find the first non-empty entry as the reference
- size_t numKeyframes = m_keyframes.size();
- size_t firstNonEmptyTransformKeyframeIndex = numKeyframes;
-
- for (size_t i = 0; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- if (currentKeyframe.style()->transform().operations().size()) {
- firstNonEmptyTransformKeyframeIndex = i;
- break;
- }
- }
-
- if (firstNonEmptyTransformKeyframeIndex == numKeyframes)
- return;
-
- const TransformOperations* firstVal = &m_keyframes[firstNonEmptyTransformKeyframeIndex].style()->transform();
-
- // See if the keyframes are valid
- for (size_t i = firstNonEmptyTransformKeyframeIndex + 1; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- const TransformOperations* val = &currentKeyframe.style()->transform();
-
- // An emtpy transform list matches anything.
- if (val->operations().isEmpty())
- continue;
-
- if (!firstVal->operationsMatch(*val))
- return;
- }
-
- // Keyframes are valid
- m_transformFunctionListValid = true;
-}
-
-void KeyframeAnimation::checkForMatchingFilterFunctionLists()
-{
- m_filterFunctionListsMatch = false;
-
- if (m_keyframes.size() < 2 || !m_keyframes.containsProperty(CSSPropertyWebkitFilter))
- return;
-
- // Empty filters match anything, so find the first non-empty entry as the reference
- size_t numKeyframes = m_keyframes.size();
- size_t firstNonEmptyFilterKeyframeIndex = numKeyframes;
-
- for (size_t i = 0; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- if (currentKeyframe.style()->filter().operations().size()) {
- firstNonEmptyFilterKeyframeIndex = i;
- break;
- }
- }
-
- if (firstNonEmptyFilterKeyframeIndex == numKeyframes)
- return;
-
- const FilterOperations* firstVal = &m_keyframes[firstNonEmptyFilterKeyframeIndex].style()->filter();
-
- for (size_t i = firstNonEmptyFilterKeyframeIndex + 1; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = m_keyframes[i];
- const FilterOperations* val = &currentKeyframe.style()->filter();
-
- if (!firstVal->canInterpolateWith(*val))
- return;
- }
-
- m_filterFunctionListsMatch = true;
-}
-
-double KeyframeAnimation::timeToNextService()
-{
- double t = AnimationBase::timeToNextService();
- if (t != 0 || preActive())
- return t;
-
- // A return value of 0 means we need service. But if we only have accelerated animations we
- // only need service at the end of the transition
- HashSet<CSSPropertyID>::const_iterator endProperties = m_keyframes.endProperties();
- bool acceleratedPropertiesOnly = true;
-
- for (HashSet<CSSPropertyID>::const_iterator it = m_keyframes.beginProperties(); it != endProperties; ++it) {
- if (!CSSPropertyAnimation::animationOfPropertyIsAccelerated(*it) || !isAccelerated()) {
- acceleratedPropertiesOnly = false;
- break;
- }
- }
-
- if (acceleratedPropertiesOnly) {
- bool isLooping;
- getTimeToNextEvent(t, isLooping);
- }
-
- return t;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/animation/KeyframeAnimation.h b/chromium/third_party/WebKit/Source/core/frame/animation/KeyframeAnimation.h
deleted file mode 100644
index 93334d93c62..00000000000
--- a/chromium/third_party/WebKit/Source/core/frame/animation/KeyframeAnimation.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef KeyframeAnimation_h
-#define KeyframeAnimation_h
-
-#include "core/dom/Document.h"
-#include "core/frame/animation/AnimationBase.h"
-#include "core/rendering/style/KeyframeList.h"
-
-namespace WebCore {
-
-class RenderStyle;
-
-// A KeyframeAnimation tracks the state of an explicit animation
-// for a single RenderObject.
-class KeyframeAnimation : public AnimationBase {
-public:
- static PassRefPtr<KeyframeAnimation> create(const CSSAnimationData* animation, RenderObject& renderer, int index, CompositeAnimation* compositeAnimation, RenderStyle& unanimatedStyle)
- {
- return adoptRef(new KeyframeAnimation(animation, renderer, index, compositeAnimation, unanimatedStyle));
- };
-
- virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle, RenderStyle* targetStyle, RefPtr<RenderStyle>& animatedStyle);
- virtual void getAnimatedStyle(RefPtr<RenderStyle>& animatedStyle);
-
- const AtomicString& name() const { return m_keyframes.animationName(); }
- int index() const { return m_index; }
- void setIndex(int i) { m_index = i; }
-
- bool hasAnimationForProperty(CSSPropertyID) const;
-
- void setUnanimatedStyle(PassRefPtr<RenderStyle> style) { m_unanimatedStyle = style; }
- RenderStyle* unanimatedStyle() const { return m_unanimatedStyle.get(); }
-
- virtual double timeToNextService();
-
-protected:
- virtual void onAnimationStart(double elapsedTime);
- virtual void onAnimationIteration(double elapsedTime);
- virtual void onAnimationEnd(double elapsedTime);
- virtual void startAnimation(double timeOffset);
- virtual void pauseAnimation(double timeOffset);
- virtual void endAnimation();
-
- virtual void overrideAnimations();
- virtual void resumeOverriddenAnimations();
-
- bool shouldSendEventForListener(Document::ListenerType inListenerType) const;
- bool sendAnimationEvent(const AtomicString&, double elapsedTime);
-
- virtual bool affectsProperty(CSSPropertyID) const;
-
- void validateTransformFunctionList();
- void checkForMatchingFilterFunctionLists();
-
-private:
- KeyframeAnimation(const CSSAnimationData*, RenderObject&, int index, CompositeAnimation*, RenderStyle& unanimatedStyle);
- virtual ~KeyframeAnimation();
-
- // Get the styles for the given property surrounding the current animation time and the progress between them.
- void fetchIntervalEndpointsForProperty(CSSPropertyID, const RenderStyle*& fromStyle, const RenderStyle*& toStyle, double& progress) const;
-
- // The keyframes that we are blending.
- KeyframeList m_keyframes;
-
- // The order in which this animation appears in the animation-name style.
- int m_index;
- bool m_startEventDispatched;
-
- // The style just before we started animation
- RefPtr<RenderStyle> m_unanimatedStyle;
-};
-
-} // namespace WebCore
-
-#endif // KeyframeAnimation_h
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirective.h b/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirective.h
new file mode 100644
index 00000000000..e870ccb9c94
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirective.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSPDirective_h
+#define CSPDirective_h
+
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class KURL;
+
+class CSPDirective {
+ WTF_MAKE_NONCOPYABLE(CSPDirective);
+public:
+ CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : m_name(name)
+ , m_text(name + ' ' + value)
+ , m_policy(policy)
+ {
+ }
+
+ const String& text() const { return m_text; }
+
+protected:
+ const ContentSecurityPolicy* policy() const { return m_policy; }
+
+private:
+ String m_name;
+ String m_text;
+ ContentSecurityPolicy* m_policy;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp b/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
new file mode 100644
index 00000000000..a453dfdeb6c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -0,0 +1,679 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/CSPDirectiveList.h"
+
+#include "core/frame/LocalFrame.h"
+#include "platform/ParsingUtilities.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
+ : m_policy(policy)
+ , m_headerType(type)
+ , m_headerSource(source)
+ , m_reportOnly(false)
+ , m_haveSandboxPolicy(false)
+ , m_reflectedXSSDisposition(ReflectedXSSUnset)
+ , m_didSetReferrerPolicy(false)
+ , m_referrerPolicy(ReferrerPolicyDefault)
+{
+ m_reportOnly = type == ContentSecurityPolicyHeaderTypeReport;
+}
+
+PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
+{
+ OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type, source));
+ directives->parse(begin, end);
+
+ if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
+ String message = "Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"" + directives->operativeDirective(directives->m_scriptSrc.get())->text() + "\".\n";
+ directives->setEvalDisabledErrorMessage(message);
+ }
+
+ if (directives->isReportOnly() && directives->reportURIs().isEmpty())
+ policy->reportMissingReportURI(String(begin, end - begin));
+
+ return directives.release();
+}
+
+void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const
+{
+ String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
+ m_policy->executionContext()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+ m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
+}
+
+void CSPDirectiveList::reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
+{
+ String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
+ m_policy->executionContext()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt());
+ m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
+}
+
+void CSPDirectiveList::reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState* scriptState) const
+{
+ String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
+ m_policy->executionContext()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, scriptState);
+ m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
+}
+
+bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
+{
+ return !directive || directive->allowEval();
+}
+
+bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
+{
+ return !directive || (directive->allowInline() && !directive->isHashOrNoncePresent());
+}
+
+bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const
+{
+ return !directive || directive->allowNonce(nonce);
+}
+
+bool CSPDirectiveList::checkHash(SourceListDirective* directive, const CSPHashValue& hashValue) const
+{
+ return !directive || directive->allowHash(hashValue);
+}
+
+bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& url) const
+{
+ return !directive || directive->allows(url);
+}
+
+bool CSPDirectiveList::checkAncestors(SourceListDirective* directive, LocalFrame* frame) const
+{
+ if (!frame || !directive)
+ return true;
+
+ for (Frame* current = frame->tree().parent(); current; current = current->tree().parent()) {
+ // FIXME: To make this work for out-of-process iframes, we need to propagate URL information of ancestor frames across processes.
+ if (!current->isLocalFrame() || !directive->allows(toLocalFrame(current)->document()->url()))
+ return false;
+ }
+ return true;
+}
+
+bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
+{
+ if (!directive)
+ return true;
+ if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
+ return false;
+ return directive->allows(type);
+}
+
+SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
+{
+ return directive ? directive : m_defaultSrc.get();
+}
+
+SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive, SourceListDirective* override) const
+{
+ return directive ? directive : override;
+}
+
+bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, ScriptState* scriptState) const
+{
+ if (checkEval(directive))
+ return true;
+
+ String suffix = String();
+ if (directive == m_defaultSrc)
+ suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
+
+ reportViolationWithState(directive->text(), ContentSecurityPolicy::ScriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), scriptState);
+ if (!m_reportOnly) {
+ m_policy->reportBlockedScriptExecutionToInspector(directive->text());
+ return false;
+ }
+ return true;
+}
+
+bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
+{
+ if (checkMediaType(directive, type, typeAttribute))
+ return true;
+
+ String message = consoleMessage + "\'" + directive->text() + "\'.";
+ if (typeAttribute.isEmpty())
+ message = message + " When enforcing the 'plugin-types' directive, the plugin's media type must be explicitly declared with a 'type' attribute on the containing element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>').";
+
+ reportViolation(directive->text(), ContentSecurityPolicy::PluginTypes, message + "\n", KURL());
+ return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
+{
+ if (checkInline(directive))
+ return true;
+
+ String suffix = String();
+ if (directive->allowInline() && directive->isHashOrNoncePresent()) {
+ // If inline is allowed, but a hash or nonce is present, we ignore 'unsafe-inline'. Throw a reasonable error.
+ suffix = " Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.";
+ } else {
+ suffix = " Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.";
+ if (directive == m_defaultSrc)
+ suffix = suffix + " Note also that '" + String(isScript ? "script" : "style") + "-src' was not explicitly set, so 'default-src' is used as a fallback.";
+ }
+
+ reportViolationWithLocation(directive->text(), isScript ? ContentSecurityPolicy::ScriptSrc : ContentSecurityPolicy::StyleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), contextURL, contextLine);
+
+ if (!m_reportOnly) {
+ if (isScript)
+ m_policy->reportBlockedScriptExecutionToInspector(directive->text());
+ return false;
+ }
+ return true;
+}
+
+bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const KURL& url, const String& effectiveDirective) const
+{
+ if (checkSource(directive, url))
+ return true;
+
+ String prefix;
+ if (ContentSecurityPolicy::BaseURI == effectiveDirective)
+ prefix = "Refused to set the document's base URI to '";
+ else if (ContentSecurityPolicy::ChildSrc == effectiveDirective)
+ prefix = "Refused to create a child context containing '";
+ else if (ContentSecurityPolicy::ConnectSrc == effectiveDirective)
+ prefix = "Refused to connect to '";
+ else if (ContentSecurityPolicy::FontSrc == effectiveDirective)
+ prefix = "Refused to load the font '";
+ else if (ContentSecurityPolicy::FormAction == effectiveDirective)
+ prefix = "Refused to send form data to '";
+ else if (ContentSecurityPolicy::FrameSrc == effectiveDirective)
+ prefix = "Refused to frame '";
+ else if (ContentSecurityPolicy::ImgSrc == effectiveDirective)
+ prefix = "Refused to load the image '";
+ else if (ContentSecurityPolicy::MediaSrc == effectiveDirective)
+ prefix = "Refused to load media from '";
+ else if (ContentSecurityPolicy::ObjectSrc == effectiveDirective)
+ prefix = "Refused to load plugin data from '";
+ else if (ContentSecurityPolicy::ScriptSrc == effectiveDirective)
+ prefix = "Refused to load the script '";
+ else if (ContentSecurityPolicy::StyleSrc == effectiveDirective)
+ prefix = "Refused to load the stylesheet '";
+
+ String suffix = String();
+ if (directive == m_defaultSrc)
+ suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
+
+ reportViolation(directive->text(), effectiveDirective, prefix + url.elidedString() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url);
+ return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::checkAncestorsAndReportViolation(SourceListDirective* directive, LocalFrame* frame) const
+{
+ if (checkAncestors(directive, frame))
+ return true;
+
+ reportViolation(directive->text(), "frame-ancestors", "Refused to display '" + frame->document()->url().elidedString() + " in a frame because an ancestor violates the following Content Security Policy directive: \"" + directive->text() + "\".", frame->document()->url());
+ return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
+ if (reportingStatus == ContentSecurityPolicy::SendReport)
+ return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
+
+ return checkInline(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline event handler because it violates the following Content Security Policy directive: "));
+ if (reportingStatus == ContentSecurityPolicy::SendReport)
+ return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
+ return checkInline(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline script because it violates the following Content Security Policy directive: "));
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true) :
+ checkInline(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to apply inline style because it violates the following Content Security Policy directive: "));
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false) :
+ checkInline(operativeDirective(m_styleSrc.get()));
+}
+
+bool CSPDirectiveList::allowEval(ScriptState* scriptState, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "));
+
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, scriptState) :
+ checkEval(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.elidedString() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
+ checkMediaType(m_pluginTypes.get(), type, typeAttribute);
+}
+
+bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, ContentSecurityPolicy::ScriptSrc) :
+ checkSource(operativeDirective(m_scriptSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ if (url.protocolIsAbout())
+ return true;
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, ContentSecurityPolicy::ObjectSrc) :
+ checkSource(operativeDirective(m_objectSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ if (url.protocolIsAbout())
+ return true;
+
+ // 'frame-src' is the only directive which overrides something other than the default sources.
+ // It overrides 'child-src', which overrides the default sources. So, we do this nested set
+ // of calls to 'operativeDirective()' to grab 'frame-src' if it exists, 'child-src' if it
+ // doesn't, and 'defaut-src' if neither are available.
+ //
+ // All of this only applies, of course, if we're in CSP 1.1. In CSP 1.0, 'frame-src'
+ // overrides 'default-src' directly.
+ SourceListDirective* whichDirective = m_policy->experimentalFeaturesEnabled() ?
+ operativeDirective(m_frameSrc.get(), operativeDirective(m_childSrc.get())) :
+ operativeDirective(m_frameSrc.get());
+
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(whichDirective, url, ContentSecurityPolicy::FrameSrc) :
+ checkSource(whichDirective, url);
+}
+
+bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, ContentSecurityPolicy::ImgSrc) :
+ checkSource(operativeDirective(m_imgSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, ContentSecurityPolicy::StyleSrc) :
+ checkSource(operativeDirective(m_styleSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, ContentSecurityPolicy::FontSrc) :
+ checkSource(operativeDirective(m_fontSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, ContentSecurityPolicy::MediaSrc) :
+ checkSource(operativeDirective(m_mediaSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, ContentSecurityPolicy::ConnectSrc) :
+ checkSource(operativeDirective(m_connectSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(m_formAction.get(), url, ContentSecurityPolicy::FormAction) :
+ checkSource(m_formAction.get(), url);
+}
+
+bool CSPDirectiveList::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(m_baseURI.get(), url, ContentSecurityPolicy::BaseURI) :
+ checkSource(m_baseURI.get(), url);
+}
+
+bool CSPDirectiveList::allowAncestors(LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkAncestorsAndReportViolation(m_frameAncestors.get(), frame) :
+ checkAncestors(m_frameAncestors.get(), frame);
+}
+
+bool CSPDirectiveList::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return reportingStatus == ContentSecurityPolicy::SendReport ?
+ checkSourceAndReportViolation(operativeDirective(m_childSrc.get()), url, ContentSecurityPolicy::ChildSrc) :
+ checkSource(operativeDirective(m_childSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
+{
+ return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
+}
+
+bool CSPDirectiveList::allowStyleNonce(const String& nonce) const
+{
+ return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
+}
+
+bool CSPDirectiveList::allowScriptHash(const CSPHashValue& hashValue) const
+{
+ return checkHash(operativeDirective(m_scriptSrc.get()), hashValue);
+}
+
+bool CSPDirectiveList::allowStyleHash(const CSPHashValue& hashValue) const
+{
+ return checkHash(operativeDirective(m_styleSrc.get()), hashValue);
+}
+
+// policy = directive-list
+// directive-list = [ directive *( ";" [ directive ] ) ]
+//
+void CSPDirectiveList::parse(const UChar* begin, const UChar* end)
+{
+ m_header = String(begin, end - begin);
+
+ if (begin == end)
+ return;
+
+ const UChar* position = begin;
+ while (position < end) {
+ const UChar* directiveBegin = position;
+ skipUntil<UChar>(position, end, ';');
+
+ String name, value;
+ if (parseDirective(directiveBegin, position, name, value)) {
+ ASSERT(!name.isEmpty());
+ addDirective(name, value);
+ }
+
+ ASSERT(position == end || *position == ';');
+ skipExactly<UChar>(position, end, ';');
+ }
+}
+
+// directive = *WSP [ directive-name [ WSP directive-value ] ]
+// directive-name = 1*( ALPHA / DIGIT / "-" )
+// directive-value = *( WSP / <VCHAR except ";"> )
+//
+bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
+{
+ ASSERT(name.isEmpty());
+ ASSERT(value.isEmpty());
+
+ const UChar* position = begin;
+ skipWhile<UChar, isASCIISpace>(position, end);
+
+ // Empty directive (e.g. ";;;"). Exit early.
+ if (position == end)
+ return false;
+
+ const UChar* nameBegin = position;
+ skipWhile<UChar, isCSPDirectiveNameCharacter>(position, end);
+
+ // The directive-name must be non-empty.
+ if (nameBegin == position) {
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+ m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
+ return false;
+ }
+
+ name = String(nameBegin, position - nameBegin);
+
+ if (position == end)
+ return true;
+
+ if (!skipExactly<UChar, isASCIISpace>(position, end)) {
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+ m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
+ return false;
+ }
+
+ skipWhile<UChar, isASCIISpace>(position, end);
+
+ const UChar* valueBegin = position;
+ skipWhile<UChar, isCSPDirectiveValueCharacter>(position, end);
+
+ if (position != end) {
+ m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
+ return false;
+ }
+
+ // The directive-value may be empty.
+ if (valueBegin == position)
+ return true;
+
+ value = String(valueBegin, position - valueBegin);
+ return true;
+}
+
+void CSPDirectiveList::parseReportURI(const String& name, const String& value)
+{
+ if (!m_reportURIs.isEmpty()) {
+ m_policy->reportDuplicateDirective(name);
+ return;
+ }
+
+ Vector<UChar> characters;
+ value.appendTo(characters);
+
+ const UChar* position = characters.data();
+ const UChar* end = position + characters.size();
+
+ while (position < end) {
+ skipWhile<UChar, isASCIISpace>(position, end);
+
+ const UChar* urlBegin = position;
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+
+ if (urlBegin < position) {
+ String url = String(urlBegin, position - urlBegin);
+ m_reportURIs.append(m_policy->completeURL(url));
+ }
+ }
+}
+
+
+template<class CSPDirectiveType>
+void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive)
+{
+ if (directive) {
+ m_policy->reportDuplicateDirective(name);
+ return;
+ }
+ directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
+}
+
+void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
+{
+ if (m_reportOnly) {
+ m_policy->reportInvalidInReportOnly(name);
+ return;
+ }
+ if (m_haveSandboxPolicy) {
+ m_policy->reportDuplicateDirective(name);
+ return;
+ }
+ m_haveSandboxPolicy = true;
+ String invalidTokens;
+ m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidTokens));
+ if (!invalidTokens.isNull())
+ m_policy->reportInvalidSandboxFlags(invalidTokens);
+}
+
+void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
+{
+ if (m_reflectedXSSDisposition != ReflectedXSSUnset) {
+ m_policy->reportDuplicateDirective(name);
+ m_reflectedXSSDisposition = ReflectedXSSInvalid;
+ return;
+ }
+
+ if (value.isEmpty()) {
+ m_reflectedXSSDisposition = ReflectedXSSInvalid;
+ m_policy->reportInvalidReflectedXSS(value);
+ return;
+ }
+
+ Vector<UChar> characters;
+ value.appendTo(characters);
+
+ const UChar* position = characters.data();
+ const UChar* end = position + characters.size();
+
+ skipWhile<UChar, isASCIISpace>(position, end);
+ const UChar* begin = position;
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+
+ // value1
+ // ^
+ if (equalIgnoringCase("allow", begin, position - begin)) {
+ m_reflectedXSSDisposition = AllowReflectedXSS;
+ } else if (equalIgnoringCase("filter", begin, position - begin)) {
+ m_reflectedXSSDisposition = FilterReflectedXSS;
+ } else if (equalIgnoringCase("block", begin, position - begin)) {
+ m_reflectedXSSDisposition = BlockReflectedXSS;
+ } else {
+ m_reflectedXSSDisposition = ReflectedXSSInvalid;
+ m_policy->reportInvalidReflectedXSS(value);
+ return;
+ }
+
+ skipWhile<UChar, isASCIISpace>(position, end);
+ if (position == end && m_reflectedXSSDisposition != ReflectedXSSUnset)
+ return;
+
+ // value1 value2
+ // ^
+ m_reflectedXSSDisposition = ReflectedXSSInvalid;
+ m_policy->reportInvalidReflectedXSS(value);
+}
+
+void CSPDirectiveList::parseReferrer(const String& name, const String& value)
+{
+ if (m_didSetReferrerPolicy) {
+ m_policy->reportDuplicateDirective(name);
+ m_referrerPolicy = ReferrerPolicyNever;
+ return;
+ }
+
+ m_didSetReferrerPolicy = true;
+
+ if (value.isEmpty()) {
+ m_policy->reportInvalidReferrer(value);
+ m_referrerPolicy = ReferrerPolicyNever;
+ return;
+ }
+
+ Vector<UChar> characters;
+ value.appendTo(characters);
+
+ const UChar* position = characters.data();
+ const UChar* end = position + characters.size();
+
+ skipWhile<UChar, isASCIISpace>(position, end);
+ const UChar* begin = position;
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+
+ // value1
+ // ^
+ if (equalIgnoringCase("always", begin, position - begin)) {
+ m_referrerPolicy = ReferrerPolicyAlways;
+ } else if (equalIgnoringCase("default", begin, position - begin)) {
+ m_referrerPolicy = ReferrerPolicyDefault;
+ } else if (equalIgnoringCase("never", begin, position - begin)) {
+ m_referrerPolicy = ReferrerPolicyNever;
+ } else if (equalIgnoringCase("origin", begin, position - begin)) {
+ m_referrerPolicy = ReferrerPolicyOrigin;
+ } else {
+ m_referrerPolicy = ReferrerPolicyNever;
+ m_policy->reportInvalidReferrer(value);
+ return;
+ }
+
+ skipWhile<UChar, isASCIISpace>(position, end);
+ if (position == end)
+ return;
+
+ // value1 value2
+ // ^
+ m_referrerPolicy = ReferrerPolicyNever;
+ m_policy->reportInvalidReferrer(value);
+
+}
+
+void CSPDirectiveList::addDirective(const String& name, const String& value)
+{
+ ASSERT(!name.isEmpty());
+
+ if (equalIgnoringCase(name, ContentSecurityPolicy::DefaultSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::ScriptSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
+ m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed());
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::ObjectSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::FrameAncestors)) {
+ setCSPDirective<SourceListDirective>(name, value, m_frameAncestors);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::FrameSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::ImgSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::StyleSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
+ m_policy->usesStyleHashAlgorithms(m_styleSrc->hashAlgorithmsUsed());
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::FontSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::MediaSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::ConnectSrc)) {
+ setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::Sandbox)) {
+ applySandboxPolicy(name, value);
+ } else if (equalIgnoringCase(name, ContentSecurityPolicy::ReportURI)) {
+ parseReportURI(name, value);
+ } else if (m_policy->experimentalFeaturesEnabled()) {
+ if (equalIgnoringCase(name, ContentSecurityPolicy::BaseURI))
+ setCSPDirective<SourceListDirective>(name, value, m_baseURI);
+ else if (equalIgnoringCase(name, ContentSecurityPolicy::ChildSrc))
+ setCSPDirective<SourceListDirective>(name, value, m_childSrc);
+ else if (equalIgnoringCase(name, ContentSecurityPolicy::FormAction))
+ setCSPDirective<SourceListDirective>(name, value, m_formAction);
+ else if (equalIgnoringCase(name, ContentSecurityPolicy::PluginTypes))
+ setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
+ else if (equalIgnoringCase(name, ContentSecurityPolicy::ReflectedXSS))
+ parseReflectedXSS(name, value);
+ else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer))
+ parseReferrer(name, value);
+ else
+ m_policy->reportUnsupportedDirective(name);
+ } else {
+ m_policy->reportUnsupportedDirective(name);
+ }
+}
+
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h b/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
new file mode 100644
index 00000000000..b33b18693ad
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.h
@@ -0,0 +1,141 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSPDirectiveList_h
+#define CSPDirectiveList_h
+
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/frame/csp/MediaListDirective.h"
+#include "core/frame/csp/SourceListDirective.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "platform/network/HTTPParsers.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/ReferrerPolicy.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+
+class CSPDirectiveList {
+ WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(CSPDirectiveList);
+public:
+ static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
+
+ void parse(const UChar* begin, const UChar* end);
+
+ const String& header() const { return m_header; }
+ ContentSecurityPolicyHeaderType headerType() const { return m_headerType; }
+ ContentSecurityPolicyHeaderSource headerSource() const { return m_headerSource; }
+
+ bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowEval(ScriptState*, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+
+ bool allowScriptFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowObjectFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowAncestors(LocalFrame*, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowChildContextFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+ bool allowScriptNonce(const String&) const;
+ bool allowStyleNonce(const String&) const;
+ bool allowScriptHash(const CSPHashValue&) const;
+ bool allowStyleHash(const CSPHashValue&) const;
+
+ const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
+ ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
+ ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
+ bool didSetReferrerPolicy() const { return m_didSetReferrerPolicy; }
+ bool isReportOnly() const { return m_reportOnly; }
+ const Vector<KURL>& reportURIs() const { return m_reportURIs; }
+
+private:
+ CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
+
+ bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
+ void parseReportURI(const String& name, const String& value);
+ void parsePluginTypes(const String& name, const String& value);
+ void parseReflectedXSS(const String& name, const String& value);
+ void parseReferrer(const String& name, const String& value);
+ void addDirective(const String& name, const String& value);
+ void applySandboxPolicy(const String& name, const String& sandboxPolicy);
+
+ template <class CSPDirectiveType>
+ void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>&);
+
+ SourceListDirective* operativeDirective(SourceListDirective*) const;
+ SourceListDirective* operativeDirective(SourceListDirective*, SourceListDirective* override) const;
+ void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const;
+ void reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
+ void reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState*) const;
+
+ bool checkEval(SourceListDirective*) const;
+ bool checkInline(SourceListDirective*) const;
+ bool checkNonce(SourceListDirective*, const String&) const;
+ bool checkHash(SourceListDirective*, const CSPHashValue&) const;
+ bool checkSource(SourceListDirective*, const KURL&) const;
+ bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
+ bool checkAncestors(SourceListDirective*, LocalFrame*) const;
+
+ void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
+
+ bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, ScriptState*) const;
+ bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
+
+ bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const;
+ bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
+ bool checkAncestorsAndReportViolation(SourceListDirective*, LocalFrame*) const;
+
+ bool denyIfEnforcingPolicy() const { return m_reportOnly; }
+
+ ContentSecurityPolicy* m_policy;
+
+ String m_header;
+ ContentSecurityPolicyHeaderType m_headerType;
+ ContentSecurityPolicyHeaderSource m_headerSource;
+
+ bool m_reportOnly;
+ bool m_haveSandboxPolicy;
+ ReflectedXSSDisposition m_reflectedXSSDisposition;
+
+ bool m_didSetReferrerPolicy;
+ ReferrerPolicy m_referrerPolicy;
+
+ OwnPtr<MediaListDirective> m_pluginTypes;
+ OwnPtr<SourceListDirective> m_baseURI;
+ OwnPtr<SourceListDirective> m_childSrc;
+ OwnPtr<SourceListDirective> m_connectSrc;
+ OwnPtr<SourceListDirective> m_defaultSrc;
+ OwnPtr<SourceListDirective> m_fontSrc;
+ OwnPtr<SourceListDirective> m_formAction;
+ OwnPtr<SourceListDirective> m_frameAncestors;
+ OwnPtr<SourceListDirective> m_frameSrc;
+ OwnPtr<SourceListDirective> m_imgSrc;
+ OwnPtr<SourceListDirective> m_mediaSrc;
+ OwnPtr<SourceListDirective> m_objectSrc;
+ OwnPtr<SourceListDirective> m_scriptSrc;
+ OwnPtr<SourceListDirective> m_styleSrc;
+
+ Vector<KURL> m_reportURIs;
+
+ String m_evalDisabledErrorMessage;
+};
+
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp b/chromium/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp
new file mode 100644
index 00000000000..863addc09ce
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/CSPSource.cpp
@@ -0,0 +1,93 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/CSPSource.h"
+
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/KnownPorts.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+CSPSource::CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
+ : m_policy(policy)
+ , m_scheme(scheme)
+ , m_host(host)
+ , m_port(port)
+ , m_path(path)
+ , m_hostHasWildcard(hostHasWildcard)
+ , m_portHasWildcard(portHasWildcard)
+{
+}
+
+bool CSPSource::matches(const KURL& url) const
+{
+ if (!schemeMatches(url))
+ return false;
+ if (isSchemeOnly())
+ return true;
+ return hostMatches(url) && portMatches(url) && pathMatches(url);
+}
+
+bool CSPSource::schemeMatches(const KURL& url) const
+{
+ if (m_scheme.isEmpty()) {
+ String protectedResourceScheme(m_policy->securityOrigin()->protocol());
+ if (equalIgnoringCase("http", protectedResourceScheme))
+ return url.protocolIs("http") || url.protocolIs("https");
+ return equalIgnoringCase(url.protocol(), protectedResourceScheme);
+ }
+ return equalIgnoringCase(url.protocol(), m_scheme);
+}
+
+bool CSPSource::hostMatches(const KURL& url) const
+{
+ const String& host = url.host();
+ if (equalIgnoringCase(host, m_host))
+ return true;
+ return m_hostHasWildcard && host.endsWith("." + m_host, false);
+
+}
+
+bool CSPSource::pathMatches(const KURL& url) const
+{
+ if (m_path.isEmpty())
+ return true;
+
+ String path = decodeURLEscapeSequences(url.path());
+
+ if (m_path.endsWith("/"))
+ return path.startsWith(m_path, false);
+
+ return path == m_path;
+}
+
+bool CSPSource::portMatches(const KURL& url) const
+{
+ if (m_portHasWildcard)
+ return true;
+
+ int port = url.port();
+
+ if (port == m_port)
+ return true;
+
+ if (!port)
+ return isDefaultPortForProtocol(m_port, url.protocol());
+
+ if (!m_port)
+ return isDefaultPortForProtocol(port, url.protocol());
+
+ return false;
+}
+
+bool CSPSource::isSchemeOnly() const
+{
+ return m_host.isEmpty();
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/CSPSource.h b/chromium/third_party/WebKit/Source/core/frame/csp/CSPSource.h
new file mode 100644
index 00000000000..9088b196b3f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/CSPSource.h
@@ -0,0 +1,39 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSPSource_h
+#define CSPSource_h
+
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class KURL;
+
+class CSPSource {
+public:
+ CSPSource(ContentSecurityPolicy*, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard);
+ bool matches(const KURL&) const;
+
+private:
+ bool schemeMatches(const KURL&) const;
+ bool hostMatches(const KURL&) const;
+ bool pathMatches(const KURL&) const;
+ bool portMatches(const KURL&) const;
+ bool isSchemeOnly() const;
+
+ ContentSecurityPolicy* m_policy;
+ String m_scheme;
+ String m_host;
+ int m_port;
+ String m_path;
+
+ bool m_hostHasWildcard;
+ bool m_portHasWildcard;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp b/chromium/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp
new file mode 100644
index 00000000000..bff7146dab0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp
@@ -0,0 +1,485 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/CSPSourceList.h"
+
+#include "core/frame/csp/CSPSource.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "platform/ParsingUtilities.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/Base64.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+static bool isSourceListNone(const UChar* begin, const UChar* end)
+{
+ skipWhile<UChar, isASCIISpace>(begin, end);
+
+ const UChar* position = begin;
+ skipWhile<UChar, isSourceCharacter>(position, end);
+ if (!equalIgnoringCase("'none'", begin, position - begin))
+ return false;
+
+ skipWhile<UChar, isASCIISpace>(position, end);
+ if (position != end)
+ return false;
+
+ return true;
+}
+
+CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& directiveName)
+ : m_policy(policy)
+ , m_directiveName(directiveName)
+ , m_allowStar(false)
+ , m_allowInline(false)
+ , m_allowEval(false)
+ , m_hashAlgorithmsUsed(0)
+{
+}
+
+bool CSPSourceList::matches(const KURL& url) const
+{
+ if (m_allowStar)
+ return true;
+
+ KURL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;
+
+ for (size_t i = 0; i < m_list.size(); ++i) {
+ if (m_list[i].matches(effectiveURL))
+ return true;
+ }
+
+ return false;
+}
+
+bool CSPSourceList::allowInline() const
+{
+ return m_allowInline;
+}
+
+bool CSPSourceList::allowEval() const
+{
+ return m_allowEval;
+}
+
+bool CSPSourceList::allowNonce(const String& nonce) const
+{
+ return !nonce.isNull() && m_nonces.contains(nonce);
+}
+
+bool CSPSourceList::allowHash(const CSPHashValue& hashValue) const
+{
+ return m_hashes.contains(hashValue);
+}
+
+uint8_t CSPSourceList::hashAlgorithmsUsed() const
+{
+ return m_hashAlgorithmsUsed;
+}
+
+bool CSPSourceList::isHashOrNoncePresent() const
+{
+ return !m_nonces.isEmpty() || m_hashAlgorithmsUsed != ContentSecurityPolicyHashAlgorithmNone;
+}
+
+// source-list = *WSP [ source *( 1*WSP source ) *WSP ]
+// / *WSP "'none'" *WSP
+//
+void CSPSourceList::parse(const UChar* begin, const UChar* end)
+{
+ // We represent 'none' as an empty m_list.
+ if (isSourceListNone(begin, end))
+ return;
+
+ const UChar* position = begin;
+ while (position < end) {
+ skipWhile<UChar, isASCIISpace>(position, end);
+ if (position == end)
+ return;
+
+ const UChar* beginSource = position;
+ skipWhile<UChar, isSourceCharacter>(position, end);
+
+ String scheme, host, path;
+ int port = 0;
+ bool hostHasWildcard = false;
+ bool portHasWildcard = false;
+
+ if (parseSource(beginSource, position, scheme, host, port, path, hostHasWildcard, portHasWildcard)) {
+ // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
+ // etc.) aren't stored in m_list, but as attributes on the source
+ // list itself.
+ if (scheme.isEmpty() && host.isEmpty())
+ continue;
+ if (m_policy->isDirectiveName(host))
+ m_policy->reportDirectiveAsSourceExpression(m_directiveName, host);
+ m_list.append(CSPSource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard));
+ } else {
+ m_policy->reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
+ }
+
+ ASSERT(position == end || isASCIISpace(*position));
+ }
+}
+
+// source = scheme ":"
+// / ( [ scheme "://" ] host [ port ] [ path ] )
+// / "'self'"
+bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard)
+{
+ if (begin == end)
+ return false;
+
+ if (equalIgnoringCase("'none'", begin, end - begin))
+ return false;
+
+ if (end - begin == 1 && *begin == '*') {
+ addSourceStar();
+ return true;
+ }
+
+ if (equalIgnoringCase("'self'", begin, end - begin)) {
+ addSourceSelf();
+ return true;
+ }
+
+ if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) {
+ addSourceUnsafeInline();
+ return true;
+ }
+
+ if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) {
+ addSourceUnsafeEval();
+ return true;
+ }
+
+ String nonce;
+ if (!parseNonce(begin, end, nonce))
+ return false;
+
+ if (!nonce.isNull()) {
+ addSourceNonce(nonce);
+ return true;
+ }
+
+ DigestValue hash;
+ ContentSecurityPolicyHashAlgorithm algorithm = ContentSecurityPolicyHashAlgorithmNone;
+ if (!parseHash(begin, end, hash, algorithm))
+ return false;
+
+ if (hash.size() > 0) {
+ addSourceHash(algorithm, hash);
+ return true;
+ }
+
+ const UChar* position = begin;
+ const UChar* beginHost = begin;
+ const UChar* beginPath = end;
+ const UChar* beginPort = 0;
+
+ skipWhile<UChar, isNotColonOrSlash>(position, end);
+
+ if (position == end) {
+ // host
+ // ^
+ return parseHost(beginHost, position, host, hostHasWildcard);
+ }
+
+ if (position < end && *position == '/') {
+ // host/path || host/ || /
+ // ^ ^ ^
+ return parseHost(beginHost, position, host, hostHasWildcard) && parsePath(position, end, path);
+ }
+
+ if (position < end && *position == ':') {
+ if (end - position == 1) {
+ // scheme:
+ // ^
+ return parseScheme(begin, position, scheme);
+ }
+
+ if (position[1] == '/') {
+ // scheme://host || scheme://
+ // ^ ^
+ if (!parseScheme(begin, position, scheme)
+ || !skipExactly<UChar>(position, end, ':')
+ || !skipExactly<UChar>(position, end, '/')
+ || !skipExactly<UChar>(position, end, '/'))
+ return false;
+ if (position == end)
+ return true;
+ beginHost = position;
+ skipWhile<UChar, isNotColonOrSlash>(position, end);
+ }
+
+ if (position < end && *position == ':') {
+ // host:port || scheme://host:port
+ // ^ ^
+ beginPort = position;
+ skipUntil<UChar>(position, end, '/');
+ }
+ }
+
+ if (position < end && *position == '/') {
+ // scheme://host/path || scheme://host:port/path
+ // ^ ^
+ if (position == beginHost)
+ return false;
+ beginPath = position;
+ }
+
+ if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostHasWildcard))
+ return false;
+
+ if (beginPort) {
+ if (!parsePort(beginPort, beginPath, port, portHasWildcard))
+ return false;
+ } else {
+ port = 0;
+ }
+
+ if (beginPath != end) {
+ if (!parsePath(beginPath, end, path))
+ return false;
+ }
+
+ return true;
+}
+
+// nonce-source = "'nonce-" nonce-value "'"
+// nonce-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
+//
+bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& nonce)
+{
+ DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-"));
+
+ if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length()))
+ return true;
+
+ const UChar* position = begin + noncePrefix.length();
+ const UChar* nonceBegin = position;
+
+ skipWhile<UChar, isNonceCharacter>(position, end);
+ ASSERT(nonceBegin <= position);
+
+ if ((position + 1) != end || *position != '\'' || !(position - nonceBegin))
+ return false;
+
+ nonce = String(nonceBegin, position - nonceBegin);
+ return true;
+}
+
+// hash-source = "'" hash-algorithm "-" hash-value "'"
+// hash-algorithm = "sha1" / "sha256" / "sha384" / "sha512"
+// hash-value = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
+//
+bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, DigestValue& hash, ContentSecurityPolicyHashAlgorithm& hashAlgorithm)
+{
+ // Any additions or subtractions from this struct should also modify the
+ // respective entries in the kAlgorithmMap array in checkDigest().
+ static const struct {
+ const char* prefix;
+ ContentSecurityPolicyHashAlgorithm algorithm;
+ } kSupportedPrefixes[] = {
+ { "'sha1-", ContentSecurityPolicyHashAlgorithmSha1 },
+ { "'sha256-", ContentSecurityPolicyHashAlgorithmSha256 },
+ { "'sha384-", ContentSecurityPolicyHashAlgorithmSha384 },
+ { "'sha512-", ContentSecurityPolicyHashAlgorithmSha512 }
+ };
+
+ String prefix;
+ hashAlgorithm = ContentSecurityPolicyHashAlgorithmNone;
+
+ // Instead of this sizeof() calculation to get the length of this array,
+ // it would be preferable to use WTF_ARRAY_LENGTH for simplicity and to
+ // guarantee a compile time calculation. Unfortunately, on some
+ // compliers, the call to WTF_ARRAY_LENGTH fails on arrays of anonymous
+ // stucts, so, for now, it is necessary to resort to this sizeof
+ // calculation.
+ for (size_t i = 0; i < (sizeof(kSupportedPrefixes) / sizeof(kSupportedPrefixes[0])); i++) {
+ if (equalIgnoringCase(kSupportedPrefixes[i].prefix, begin, strlen(kSupportedPrefixes[i].prefix))) {
+ prefix = kSupportedPrefixes[i].prefix;
+ hashAlgorithm = kSupportedPrefixes[i].algorithm;
+ break;
+ }
+ }
+
+ if (hashAlgorithm == ContentSecurityPolicyHashAlgorithmNone)
+ return true;
+
+ const UChar* position = begin + prefix.length();
+ const UChar* hashBegin = position;
+
+ skipWhile<UChar, isBase64EncodedCharacter>(position, end);
+ ASSERT(hashBegin <= position);
+
+ // Base64 encodings may end with exactly one or two '=' characters
+ skipExactly<UChar>(position, position + 1, '=');
+ skipExactly<UChar>(position, position + 1, '=');
+
+ if ((position + 1) != end || *position != '\'' || !(position - hashBegin))
+ return false;
+
+ Vector<char> hashVector;
+ base64Decode(hashBegin, position - hashBegin, hashVector);
+ if (hashVector.size() > kMaxDigestSize)
+ return false;
+ hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size());
+ return true;
+}
+
+// ; <scheme> production from RFC 3986
+// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+//
+bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& scheme)
+{
+ ASSERT(begin <= end);
+ ASSERT(scheme.isEmpty());
+
+ if (begin == end)
+ return false;
+
+ const UChar* position = begin;
+
+ if (!skipExactly<UChar, isASCIIAlpha>(position, end))
+ return false;
+
+ skipWhile<UChar, isSchemeContinuationCharacter>(position, end);
+
+ if (position != end)
+ return false;
+
+ scheme = String(begin, end - begin);
+ return true;
+}
+
+// host = [ "*." ] 1*host-char *( "." 1*host-char )
+// / "*"
+// host-char = ALPHA / DIGIT / "-"
+//
+bool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard)
+{
+ ASSERT(begin <= end);
+ ASSERT(host.isEmpty());
+ ASSERT(!hostHasWildcard);
+
+ if (begin == end)
+ return false;
+
+ const UChar* position = begin;
+
+ if (skipExactly<UChar>(position, end, '*')) {
+ hostHasWildcard = true;
+
+ if (position == end)
+ return true;
+
+ if (!skipExactly<UChar>(position, end, '.'))
+ return false;
+ }
+
+ const UChar* hostBegin = position;
+
+ while (position < end) {
+ if (!skipExactly<UChar, isHostCharacter>(position, end))
+ return false;
+
+ skipWhile<UChar, isHostCharacter>(position, end);
+
+ if (position < end && !skipExactly<UChar>(position, end, '.'))
+ return false;
+ }
+
+ ASSERT(position == end);
+ host = String(hostBegin, end - hostBegin);
+ return true;
+}
+
+bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path)
+{
+ ASSERT(begin <= end);
+ ASSERT(path.isEmpty());
+
+ const UChar* position = begin;
+ skipWhile<UChar, isPathComponentCharacter>(position, end);
+ // path/to/file.js?query=string || path/to/file.js#anchor
+ // ^ ^
+ if (position < end)
+ m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
+
+ path = decodeURLEscapeSequences(String(begin, position - begin));
+
+ ASSERT(position <= end);
+ ASSERT(position == end || (*position == '#' || *position == '?'));
+ return true;
+}
+
+// port = ":" ( 1*DIGIT / "*" )
+//
+bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard)
+{
+ ASSERT(begin <= end);
+ ASSERT(!port);
+ ASSERT(!portHasWildcard);
+
+ if (!skipExactly<UChar>(begin, end, ':'))
+ ASSERT_NOT_REACHED();
+
+ if (begin == end)
+ return false;
+
+ if (end - begin == 1 && *begin == '*') {
+ port = 0;
+ portHasWildcard = true;
+ return true;
+ }
+
+ const UChar* position = begin;
+ skipWhile<UChar, isASCIIDigit>(position, end);
+
+ if (position != end)
+ return false;
+
+ bool ok;
+ port = charactersToIntStrict(begin, end - begin, &ok);
+ return ok;
+}
+
+void CSPSourceList::addSourceSelf()
+{
+ m_list.append(CSPSource(m_policy, m_policy->securityOrigin()->protocol(), m_policy->securityOrigin()->host(), m_policy->securityOrigin()->port(), String(), false, false));
+}
+
+void CSPSourceList::addSourceStar()
+{
+ m_allowStar = true;
+}
+
+void CSPSourceList::addSourceUnsafeInline()
+{
+ m_allowInline = true;
+}
+
+void CSPSourceList::addSourceUnsafeEval()
+{
+ m_allowEval = true;
+}
+
+void CSPSourceList::addSourceNonce(const String& nonce)
+{
+ m_nonces.add(nonce);
+}
+
+void CSPSourceList::addSourceHash(const ContentSecurityPolicyHashAlgorithm& algorithm, const DigestValue& hash)
+{
+ m_hashes.add(CSPHashValue(algorithm, hash));
+ m_hashAlgorithmsUsed |= algorithm;
+}
+
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/CSPSourceList.h b/chromium/third_party/WebKit/Source/core/frame/csp/CSPSourceList.h
new file mode 100644
index 00000000000..c982fe68ac7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/CSPSourceList.h
@@ -0,0 +1,65 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSPSourceList_h
+#define CSPSourceList_h
+
+#include "core/frame/csp/CSPSource.h"
+#include "platform/Crypto.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class KURL;
+
+class CSPSourceList {
+ WTF_MAKE_NONCOPYABLE(CSPSourceList);
+public:
+ CSPSourceList(ContentSecurityPolicy*, const String& directiveName);
+
+ void parse(const UChar* begin, const UChar* end);
+
+ bool matches(const KURL&) const;
+ bool allowInline() const;
+ bool allowEval() const;
+ bool allowNonce(const String&) const;
+ bool allowHash(const CSPHashValue&) const;
+ uint8_t hashAlgorithmsUsed() const;
+
+ bool isHashOrNoncePresent() const;
+
+private:
+ bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
+ bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
+ bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard);
+ bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
+ bool parsePath(const UChar* begin, const UChar* end, String& path);
+ bool parseNonce(const UChar* begin, const UChar* end, String& nonce);
+ bool parseHash(const UChar* begin, const UChar* end, DigestValue& hash, ContentSecurityPolicyHashAlgorithm&);
+
+ void addSourceSelf();
+ void addSourceStar();
+ void addSourceUnsafeInline();
+ void addSourceUnsafeEval();
+ void addSourceNonce(const String& nonce);
+ void addSourceHash(const ContentSecurityPolicyHashAlgorithm&, const DigestValue& hash);
+
+ ContentSecurityPolicy* m_policy;
+ Vector<CSPSource> m_list;
+ String m_directiveName;
+ bool m_allowStar;
+ bool m_allowInline;
+ bool m_allowEval;
+ HashSet<String> m_nonces;
+ HashSet<CSPHashValue> m_hashes;
+ uint8_t m_hashAlgorithmsUsed;
+};
+
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp b/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
new file mode 100644
index 00000000000..cdd5d063a27
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -0,0 +1,786 @@
+/*
+ * Copyright (C) 2011 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+
+#include "bindings/v8/ScriptCallStackFactory.h"
+#include "bindings/v8/ScriptController.h"
+#include "core/dom/DOMStringList.h"
+#include "core/dom/Document.h"
+#include "core/events/SecurityPolicyViolationEvent.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
+#include "core/frame/csp/CSPDirectiveList.h"
+#include "core/frame/csp/CSPSource.h"
+#include "core/frame/csp/CSPSourceList.h"
+#include "core/frame/csp/MediaListDirective.h"
+#include "core/frame/csp/SourceListDirective.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/ScriptCallStack.h"
+#include "core/loader/DocumentLoader.h"
+#include "core/loader/PingLoader.h"
+#include "platform/Crypto.h"
+#include "platform/JSONValues.h"
+#include "platform/NotImplemented.h"
+#include "platform/ParsingUtilities.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "platform/network/ContentSecurityPolicyResponseHeaders.h"
+#include "platform/network/FormData.h"
+#include "platform/network/ResourceResponse.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/KnownPorts.h"
+#include "platform/weborigin/SchemeRegistry.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebArrayBuffer.h"
+#include "public/platform/WebCrypto.h"
+#include "public/platform/WebCryptoAlgorithm.h"
+#include "wtf/StringHasher.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/StringUTF8Adaptor.h"
+
+namespace WebCore {
+
+// CSP 1.0 Directives
+const char ContentSecurityPolicy::ConnectSrc[] = "connect-src";
+const char ContentSecurityPolicy::DefaultSrc[] = "default-src";
+const char ContentSecurityPolicy::FontSrc[] = "font-src";
+const char ContentSecurityPolicy::FrameSrc[] = "frame-src";
+const char ContentSecurityPolicy::ImgSrc[] = "img-src";
+const char ContentSecurityPolicy::MediaSrc[] = "media-src";
+const char ContentSecurityPolicy::ObjectSrc[] = "object-src";
+const char ContentSecurityPolicy::ReportURI[] = "report-uri";
+const char ContentSecurityPolicy::Sandbox[] = "sandbox";
+const char ContentSecurityPolicy::ScriptSrc[] = "script-src";
+const char ContentSecurityPolicy::StyleSrc[] = "style-src";
+
+// CSP 1.1 Directives
+const char ContentSecurityPolicy::BaseURI[] = "base-uri";
+const char ContentSecurityPolicy::ChildSrc[] = "child-src";
+const char ContentSecurityPolicy::FormAction[] = "form-action";
+const char ContentSecurityPolicy::FrameAncestors[] = "frame-ancestors";
+const char ContentSecurityPolicy::PluginTypes[] = "plugin-types";
+const char ContentSecurityPolicy::ReflectedXSS[] = "reflected-xss";
+const char ContentSecurityPolicy::Referrer[] = "referrer";
+
+bool ContentSecurityPolicy::isDirectiveName(const String& name)
+{
+ return (equalIgnoringCase(name, ConnectSrc)
+ || equalIgnoringCase(name, DefaultSrc)
+ || equalIgnoringCase(name, FontSrc)
+ || equalIgnoringCase(name, FrameSrc)
+ || equalIgnoringCase(name, ImgSrc)
+ || equalIgnoringCase(name, MediaSrc)
+ || equalIgnoringCase(name, ObjectSrc)
+ || equalIgnoringCase(name, ReportURI)
+ || equalIgnoringCase(name, Sandbox)
+ || equalIgnoringCase(name, ScriptSrc)
+ || equalIgnoringCase(name, StyleSrc)
+ || equalIgnoringCase(name, BaseURI)
+ || equalIgnoringCase(name, ChildSrc)
+ || equalIgnoringCase(name, FormAction)
+ || equalIgnoringCase(name, FrameAncestors)
+ || equalIgnoringCase(name, PluginTypes)
+ || equalIgnoringCase(name, ReflectedXSS)
+ || equalIgnoringCase(name, Referrer)
+ );
+}
+
+static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType type)
+{
+ switch (type) {
+ case ContentSecurityPolicyHeaderTypeEnforce:
+ return UseCounter::ContentSecurityPolicy;
+ case ContentSecurityPolicyHeaderTypeReport:
+ return UseCounter::ContentSecurityPolicyReportOnly;
+ }
+ ASSERT_NOT_REACHED();
+ return UseCounter::NumberOfFeatures;
+}
+
+static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b)
+{
+ if (a != b)
+ return ReferrerPolicyNever;
+ return a;
+}
+
+ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContext* executionContext)
+ : m_executionContext(executionContext)
+ , m_overrideInlineStyleAllowed(false)
+ , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone)
+ , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone)
+{
+}
+
+ContentSecurityPolicy::~ContentSecurityPolicy()
+{
+}
+
+void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
+{
+ ASSERT(m_policies.isEmpty());
+ for (CSPDirectiveListVector::const_iterator iter = other->m_policies.begin(); iter != other->m_policies.end(); ++iter)
+ addPolicyFromHeaderValue((*iter)->header(), (*iter)->headerType(), (*iter)->headerSource());
+}
+
+void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers)
+{
+ if (!headers.contentSecurityPolicy().isEmpty())
+ didReceiveHeader(headers.contentSecurityPolicy(), ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceHTTP);
+ if (!headers.contentSecurityPolicyReportOnly().isEmpty())
+ didReceiveHeader(headers.contentSecurityPolicyReportOnly(), ContentSecurityPolicyHeaderTypeReport, ContentSecurityPolicyHeaderSourceHTTP);
+}
+
+void ContentSecurityPolicy::didReceiveHeader(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
+{
+ addPolicyFromHeaderValue(header, type, source);
+}
+
+void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
+{
+ Document* document = this->document();
+ if (document) {
+ UseCounter::count(*document, getUseCounterType(type));
+
+ // CSP 1.1 defines report-only in a <meta> element as invalid. Measure for now, disable in experimental mode.
+ if (source == ContentSecurityPolicyHeaderSourceMeta && type == ContentSecurityPolicyHeaderTypeReport) {
+ UseCounter::count(*document, UseCounter::ContentSecurityPolicyReportOnlyInMeta);
+ if (experimentalFeaturesEnabled()) {
+ reportReportOnlyInMeta(header);
+ return;
+ }
+ }
+ }
+
+
+ Vector<UChar> characters;
+ header.appendTo(characters);
+
+ const UChar* begin = characters.data();
+ const UChar* end = begin + characters.size();
+
+ // RFC2616, section 4.2 specifies that headers appearing multiple times can
+ // be combined with a comma. Walk the header string, and parse each comma
+ // separated chunk as a separate header.
+ const UChar* position = begin;
+ while (position < end) {
+ skipUntil<UChar>(position, end, ',');
+
+ // header1,header2 OR header1
+ // ^ ^
+ OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type, source);
+
+ // We disable 'eval()' even in the case of report-only policies, and rely on the check in the V8Initializer::codeGenerationCheckCallbackInMainThread callback to determine whether the call should execute or not.
+ if (!policy->allowEval(0, SuppressReport))
+ m_executionContext->disableEval(policy->evalDisabledErrorMessage());
+
+ m_policies.append(policy.release());
+
+ // Skip the comma, and begin the next header from the current position.
+ ASSERT(position == end || *position == ',');
+ skipExactly<UChar>(position, end, ',');
+ begin = position;
+ }
+
+ if (document && type != ContentSecurityPolicyHeaderTypeReport && didSetReferrerPolicy())
+ document->setReferrerPolicy(referrerPolicy());
+}
+
+void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
+{
+ m_overrideInlineStyleAllowed = value;
+}
+
+const String& ContentSecurityPolicy::deprecatedHeader() const
+{
+ return m_policies.isEmpty() ? emptyString() : m_policies[0]->header();
+}
+
+ContentSecurityPolicyHeaderType ContentSecurityPolicy::deprecatedHeaderType() const
+{
+ return m_policies.isEmpty() ? ContentSecurityPolicyHeaderTypeEnforce : m_policies[0]->headerType();
+}
+
+template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(ScriptState* scriptState, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, ScriptState* scriptState, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(scriptState, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(contextURL, contextLine, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const String&) const>
+bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(nonce))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const>
+bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHashValue& hashValue)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(hashValue))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+ return true;
+
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowFromURL)(url, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(LocalFrame*, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+ for (size_t i = 0; i < policies.size(); ++i) {
+ if (!(policies[i].get()->*allowed)(frame, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const>
+bool checkDigest(const String& source, uint8_t hashAlgorithmsUsed, const CSPDirectiveListVector& policies)
+{
+ // Any additions or subtractions from this struct should also modify the
+ // respective entries in the kSupportedPrefixes array in
+ // CSPSourceList::parseHash().
+ static const struct {
+ ContentSecurityPolicyHashAlgorithm cspHashAlgorithm;
+ HashAlgorithm algorithm;
+ } kAlgorithmMap[] = {
+ { ContentSecurityPolicyHashAlgorithmSha1, HashAlgorithmSha1 },
+ { ContentSecurityPolicyHashAlgorithmSha256, HashAlgorithmSha256 },
+ { ContentSecurityPolicyHashAlgorithmSha384, HashAlgorithmSha384 },
+ { ContentSecurityPolicyHashAlgorithmSha512, HashAlgorithmSha512 }
+ };
+
+ // Only bother normalizing the source/computing digests if there are any checks to be done.
+ if (hashAlgorithmsUsed == ContentSecurityPolicyHashAlgorithmNone)
+ return false;
+
+ StringUTF8Adaptor normalizedSource(source, StringUTF8Adaptor::Normalize, WTF::EntitiesForUnencodables);
+
+ // See comment in CSPSourceList::parseHash about why we are using this sizeof
+ // calculation instead of WTF_ARRAY_LENGTH.
+ for (size_t i = 0; i < (sizeof(kAlgorithmMap) / sizeof(kAlgorithmMap[0])); i++) {
+ DigestValue digest;
+ if (kAlgorithmMap[i].cspHashAlgorithm & hashAlgorithmsUsed) {
+ bool digestSuccess = computeDigest(kAlgorithmMap[i].algorithm, normalizedSource.data(), normalizedSource.length(), digest);
+ if (digestSuccess && isAllowedByAllWithHash<allowed>(policies, CSPHashValue(kAlgorithmMap[i].cspHashAlgorithm, digest)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ if (m_overrideInlineStyleAllowed)
+ return true;
+ return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowEval(ScriptState* scriptState, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithState<&CSPDirectiveList::allowEval>(m_policies, scriptState, reportingStatus);
+}
+
+String ContentSecurityPolicy::evalDisabledErrorMessage() const
+{
+ for (size_t i = 0; i < m_policies.size(); ++i) {
+ if (!m_policies[i]->allowEval(0, SuppressReport))
+ return m_policies[i]->evalDisabledErrorMessage();
+ }
+ return String();
+}
+
+bool ContentSecurityPolicy::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ for (size_t i = 0; i < m_policies.size(); ++i) {
+ if (!m_policies[i]->allowPluginType(type, typeAttribute, url, reportingStatus))
+ return false;
+ }
+ return true;
+}
+
+bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowScriptNonce(const String& nonce) const
+{
+ return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_policies, nonce);
+}
+
+bool ContentSecurityPolicy::allowStyleNonce(const String& nonce) const
+{
+ return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policies, nonce);
+}
+
+bool ContentSecurityPolicy::allowScriptHash(const String& source) const
+{
+ return checkDigest<&CSPDirectiveList::allowScriptHash>(source, m_scriptHashAlgorithmsUsed, m_policies);
+}
+
+bool ContentSecurityPolicy::allowStyleHash(const String& source) const
+{
+ return checkDigest<&CSPDirectiveList::allowStyleHash>(source, m_styleHashAlgorithmsUsed, m_policies);
+}
+
+void ContentSecurityPolicy::usesScriptHashAlgorithms(uint8_t algorithms)
+{
+ m_scriptHashAlgorithmsUsed |= algorithms;
+}
+
+void ContentSecurityPolicy::usesStyleHashAlgorithms(uint8_t algorithms)
+{
+ m_styleHashAlgorithmsUsed |= algorithms;
+}
+
+bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowStyleFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowFormAction>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowAncestors(LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithFrame<&CSPDirectiveList::allowAncestors>(m_policies, frame, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ return isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowWorkerContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+ // CSP 1.1 moves workers from 'script-src' to the new 'child-src'. Measure the impact of this backwards-incompatible change.
+ if (m_executionContext->isDocument()) {
+ Document* document = static_cast<Document*>(m_executionContext);
+ UseCounter::count(*document, UseCounter::WorkerSubjectToCSP);
+ if (isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, SuppressReport) && !isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, SuppressReport))
+ UseCounter::count(*document, UseCounter::WorkerAllowedByChildBlockedByScript);
+ }
+
+ return experimentalFeaturesEnabled() ?
+ isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, reportingStatus) :
+ isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::isActive() const
+{
+ return !m_policies.isEmpty();
+}
+
+ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const
+{
+ ReflectedXSSDisposition disposition = ReflectedXSSUnset;
+ for (size_t i = 0; i < m_policies.size(); ++i) {
+ if (m_policies[i]->reflectedXSSDisposition() > disposition)
+ disposition = std::max(disposition, m_policies[i]->reflectedXSSDisposition());
+ }
+ return disposition;
+}
+
+ReferrerPolicy ContentSecurityPolicy::referrerPolicy() const
+{
+ ReferrerPolicy policy = ReferrerPolicyDefault;
+ bool first = true;
+ for (size_t i = 0; i < m_policies.size(); ++i) {
+ if (m_policies[i]->didSetReferrerPolicy()) {
+ if (first)
+ policy = m_policies[i]->referrerPolicy();
+ else
+ policy = mergeReferrerPolicies(policy, m_policies[i]->referrerPolicy());
+ }
+ }
+ return policy;
+}
+
+bool ContentSecurityPolicy::didSetReferrerPolicy() const
+{
+ for (size_t i = 0; i < m_policies.size(); ++i) {
+ if (m_policies[i]->didSetReferrerPolicy())
+ return true;
+ }
+ return false;
+}
+
+SecurityOrigin* ContentSecurityPolicy::securityOrigin() const
+{
+ return m_executionContext->securityContext().securityOrigin();
+}
+
+const KURL ContentSecurityPolicy::url() const
+{
+ return m_executionContext->contextURL();
+}
+
+KURL ContentSecurityPolicy::completeURL(const String& url) const
+{
+ return m_executionContext->contextCompleteURL(url);
+}
+
+void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) const
+{
+ if (Document* document = this->document())
+ document->enforceSandboxFlags(mask);
+}
+
+static String stripURLForUseInReport(Document* document, const KURL& url)
+{
+ if (!url.isValid())
+ return String();
+ if (!url.isHierarchical() || url.protocolIs("file"))
+ return url.protocol();
+ return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsReferrer() : SecurityOrigin::create(url)->toString();
+}
+
+static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventInit& init, Document* document, const String& directiveText, const String& effectiveDirective, const KURL& blockedURL, const String& header)
+{
+ init.documentURI = document->url().string();
+ init.referrer = document->referrer();
+ init.blockedURI = stripURLForUseInReport(document, blockedURL);
+ init.violatedDirective = directiveText;
+ init.effectiveDirective = effectiveDirective;
+ init.originalPolicy = header;
+ init.sourceFile = String();
+ init.lineNumber = 0;
+ init.columnNumber = 0;
+ init.statusCode = 0;
+
+ if (!SecurityOrigin::isSecure(document->url()) && document->loader())
+ init.statusCode = document->loader()->response().httpStatusCode();
+
+ RefPtrWillBeRawPtr<ScriptCallStack> stack = createScriptCallStack(1, false);
+ if (!stack)
+ return;
+
+ const ScriptCallFrame& callFrame = stack->at(0);
+
+ if (callFrame.lineNumber()) {
+ KURL source = KURL(ParsedURLString, callFrame.sourceURL());
+ init.sourceFile = stripURLForUseInReport(document, source);
+ init.lineNumber = callFrame.lineNumber();
+ init.columnNumber = callFrame.columnNumber();
+ }
+}
+
+void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header)
+{
+ // FIXME: Support sending reports from worker.
+ if (!m_executionContext->isDocument())
+ return;
+
+ Document* document = this->document();
+ LocalFrame* frame = document->frame();
+ if (!frame)
+ return;
+
+ SecurityPolicyViolationEventInit violationData;
+ gatherSecurityPolicyViolationEventData(violationData, document, directiveText, effectiveDirective, blockedURL, header);
+
+ if (experimentalFeaturesEnabled())
+ frame->domWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::create(EventTypeNames::securitypolicyviolation, violationData));
+
+ if (reportURIs.isEmpty())
+ return;
+
+ // We need to be careful here when deciding what information to send to the
+ // report-uri. Currently, we send only the current document's URL and the
+ // directive that was violated. The document's URL is safe to send because
+ // it's the document itself that's requesting that it be sent. You could
+ // make an argument that we shouldn't send HTTPS document URLs to HTTP
+ // report-uris (for the same reasons that we supress the Referer in that
+ // case), but the Referer is sent implicitly whereas this request is only
+ // sent explicitly. As for which directive was violated, that's pretty
+ // harmless information.
+
+ RefPtr<JSONObject> cspReport = JSONObject::create();
+ cspReport->setString("document-uri", violationData.documentURI);
+ cspReport->setString("referrer", violationData.referrer);
+ cspReport->setString("violated-directive", violationData.violatedDirective);
+ if (experimentalFeaturesEnabled())
+ cspReport->setString("effective-directive", violationData.effectiveDirective);
+ cspReport->setString("original-policy", violationData.originalPolicy);
+ cspReport->setString("blocked-uri", violationData.blockedURI);
+ if (!violationData.sourceFile.isEmpty() && violationData.lineNumber) {
+ cspReport->setString("source-file", violationData.sourceFile);
+ cspReport->setNumber("line-number", violationData.lineNumber);
+ cspReport->setNumber("column-number", violationData.columnNumber);
+ }
+ cspReport->setNumber("status-code", violationData.statusCode);
+
+ RefPtr<JSONObject> reportObject = JSONObject::create();
+ reportObject->setObject("csp-report", cspReport.release());
+ String stringifiedReport = reportObject->toJSONString();
+
+ if (!shouldSendViolationReport(stringifiedReport))
+ return;
+
+ RefPtr<FormData> report = FormData::create(stringifiedReport.utf8());
+
+ for (size_t i = 0; i < reportURIs.size(); ++i)
+ PingLoader::sendViolationReport(frame, reportURIs[i], report, PingLoader::ContentSecurityPolicyViolationReport);
+
+ didSendViolationReport(stringifiedReport);
+}
+
+void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) const
+{
+ logToConsole("The 'referrer' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"always\", \"default\", \"never\", and \"origin\".");
+}
+
+void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) const
+{
+ logToConsole("The report-only Content Security Policy '" + header + "' was delivered via a <meta> element, which is disallowed. The policy has been ignored.");
+}
+
+void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) const
+{
+ logToConsole("The Content Security Policy '" + header + "' was delivered via a <meta> element outside the document's <head>, which is disallowed. The policy has been ignored.");
+}
+
+void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) const
+{
+ logToConsole("The Content Security Policy directive '" + name + "' is ignored when delivered in a report-only policy.");
+}
+
+void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const
+{
+ DEFINE_STATIC_LOCAL(String, allow, ("allow"));
+ DEFINE_STATIC_LOCAL(String, options, ("options"));
+ DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri"));
+ DEFINE_STATIC_LOCAL(String, allowMessage, ("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect."));
+ DEFINE_STATIC_LOCAL(String, optionsMessage, ("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect."));
+ DEFINE_STATIC_LOCAL(String, policyURIMessage, ("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header."));
+
+ String message = "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
+ if (equalIgnoringCase(name, allow))
+ message = allowMessage;
+ else if (equalIgnoringCase(name, options))
+ message = optionsMessage;
+ else if (equalIgnoringCase(name, policyURI))
+ message = policyURIMessage;
+
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const
+{
+ String message = "The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?";
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportDuplicateDirective(const String& name) const
+{
+ String message = "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n";
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) const
+{
+ String message;
+ if (pluginType.isNull())
+ message = "'plugin-types' Content Security Policy directive is empty; all plugins will be blocked.\n";
+ else
+ message = "Invalid plugin type in 'plugin-types' Content Security Policy directive: '" + pluginType + "'.\n";
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags) const
+{
+ logToConsole("Error while parsing the 'sandbox' Content Security Policy directive: " + invalidFlags);
+}
+
+void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue) const
+{
+ logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\".");
+}
+
+void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const
+{
+ String message = "The value for Content Security Policy directive '" + directiveName + "' contains an invalid character: '" + value + "'. Non-whitespace characters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.";
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveName, const String& value, const char invalidChar) const
+{
+ ASSERT(invalidChar == '#' || invalidChar == '?');
+
+ String ignoring = "The fragment identifier, including the '#', will be ignored.";
+ if (invalidChar == '?')
+ ignoring = "The query component, including the '?', will be ignored.";
+ String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring;
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiveName, const String& source) const
+{
+ String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ignored.";
+ if (equalIgnoringCase(source, "'none'"))
+ message = message + " Note that 'none' has no effect unless it is the only expression in the source list.";
+ logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const
+{
+ logToConsole("The Content Security Policy '" + policy + "' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.");
+}
+
+void ContentSecurityPolicy::logToConsole(const String& message) const
+{
+ m_executionContext->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+}
+
+void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String& directiveText) const
+{
+ m_executionContext->reportBlockedScriptExecutionToInspector(directiveText);
+}
+
+bool ContentSecurityPolicy::experimentalFeaturesEnabled() const
+{
+ return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled();
+}
+
+bool ContentSecurityPolicy::shouldBypassMainWorld(ExecutionContext* context)
+{
+ if (context && context->isDocument()) {
+ Document* document = toDocument(context);
+ if (document->frame())
+ return document->frame()->script().shouldBypassMainWorldContentSecurityPolicy();
+ }
+ return false;
+}
+
+bool ContentSecurityPolicy::shouldSendViolationReport(const String& report) const
+{
+ // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report.
+ return !m_violationReportsSent.contains(report.impl()->hash());
+}
+
+void ContentSecurityPolicy::didSendViolationReport(const String& report)
+{
+ m_violationReportsSent.add(report.impl()->hash());
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h b/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h
new file mode 100644
index 00000000000..5d07921bfef
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2011 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ContentSecurityPolicy_h
+#define ContentSecurityPolicy_h
+
+#include "bindings/v8/ScriptState.h"
+#include "core/dom/Document.h"
+#include "core/dom/ExecutionContext.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "platform/network/HTTPParsers.h"
+#include "platform/weborigin/ReferrerPolicy.h"
+#include "wtf/HashSet.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
+#include "wtf/text/StringHash.h"
+#include "wtf/text/TextPosition.h"
+#include "wtf/text/WTFString.h"
+
+namespace WTF {
+class OrdinalNumber;
+}
+
+namespace WebCore {
+
+class ContentSecurityPolicyResponseHeaders;
+class CSPDirectiveList;
+class DOMStringList;
+class JSONObject;
+class KURL;
+class SecurityOrigin;
+
+typedef int SandboxFlags;
+typedef Vector<OwnPtr<CSPDirectiveList> > CSPDirectiveListVector;
+
+class ContentSecurityPolicy : public RefCounted<ContentSecurityPolicy> {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ // CSP 1.0 Directives
+ static const char ConnectSrc[];
+ static const char DefaultSrc[];
+ static const char FontSrc[];
+ static const char FrameSrc[];
+ static const char ImgSrc[];
+ static const char MediaSrc[];
+ static const char ObjectSrc[];
+ static const char ReportURI[];
+ static const char Sandbox[];
+ static const char ScriptSrc[];
+ static const char StyleSrc[];
+
+ // CSP 1.1 Directives
+ static const char BaseURI[];
+ static const char ChildSrc[];
+ static const char FormAction[];
+ static const char FrameAncestors[];
+ static const char PluginTypes[];
+ static const char ReflectedXSS[];
+ static const char Referrer[];
+
+ static PassRefPtr<ContentSecurityPolicy> create(ExecutionContext* executionContext)
+ {
+ return adoptRef(new ContentSecurityPolicy(executionContext));
+ }
+ ~ContentSecurityPolicy();
+
+ void copyStateFrom(const ContentSecurityPolicy*);
+
+ enum ReportingStatus {
+ SendReport,
+ SuppressReport
+ };
+
+ void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
+ void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
+
+ // These functions are wrong because they assume that there is only one header.
+ // FIXME: Replace them with functions that return vectors.
+ const String& deprecatedHeader() const;
+ ContentSecurityPolicyHeaderType deprecatedHeaderType() const;
+
+ bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
+ bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
+ bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
+ bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
+ bool allowEval(ScriptState* = 0, ReportingStatus = SendReport) const;
+ bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ReportingStatus = SendReport) const;
+
+ bool allowScriptFromSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowObjectFromSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowChildFrameFromSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowImageFromSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowStyleFromSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowFontFromSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowMediaFromSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowConnectToSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowFormAction(const KURL&, ReportingStatus = SendReport) const;
+ bool allowBaseURI(const KURL&, ReportingStatus = SendReport) const;
+ bool allowAncestors(LocalFrame*, ReportingStatus = SendReport) const;
+ bool allowChildContextFromSource(const KURL&, ReportingStatus = SendReport) const;
+ bool allowWorkerContextFromSource(const KURL&, ReportingStatus = SendReport) const;
+
+ // The nonce and hash allow functions are guaranteed to not have any side
+ // effects, including reporting.
+ bool allowScriptNonce(const String& nonce) const;
+ bool allowStyleNonce(const String& nonce) const;
+ bool allowScriptHash(const String& source) const;
+ bool allowStyleHash(const String& source) const;
+
+ void usesScriptHashAlgorithms(uint8_t ContentSecurityPolicyHashAlgorithm);
+ void usesStyleHashAlgorithms(uint8_t ContentSecurityPolicyHashAlgorithm);
+
+ ReflectedXSSDisposition reflectedXSSDisposition() const;
+
+ ReferrerPolicy referrerPolicy() const;
+ bool didSetReferrerPolicy() const;
+
+ void setOverrideAllowInlineStyle(bool);
+
+ bool isActive() const;
+
+ void reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const;
+ void reportDuplicateDirective(const String&) const;
+ void reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const;
+ void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
+ void reportInvalidPluginTypes(const String&) const;
+ void reportInvalidSandboxFlags(const String&) const;
+ void reportInvalidSourceExpression(const String& directiveName, const String& source) const;
+ void reportInvalidReflectedXSS(const String&) const;
+ void reportMissingReportURI(const String&) const;
+ void reportUnsupportedDirective(const String&) const;
+ void reportInvalidInReportOnly(const String&) const;
+ void reportInvalidReferrer(const String&) const;
+ void reportReportOnlyInMeta(const String&) const;
+ void reportMetaOutsideHead(const String&) const;
+ void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header);
+
+ void reportBlockedScriptExecutionToInspector(const String& directiveText) const;
+
+ const KURL url() const;
+ KURL completeURL(const String&) const;
+ SecurityOrigin* securityOrigin() const;
+ void enforceSandboxFlags(SandboxFlags) const;
+ String evalDisabledErrorMessage() const;
+
+ bool experimentalFeaturesEnabled() const;
+
+ static bool shouldBypassMainWorld(ExecutionContext*);
+
+ static bool isDirectiveName(const String&);
+
+ ExecutionContext* executionContext() const { return m_executionContext; }
+ Document* document() const { return m_executionContext->isDocument() ? toDocument(m_executionContext) : 0; }
+
+private:
+ explicit ContentSecurityPolicy(ExecutionContext*);
+
+ void logToConsole(const String& message) const;
+ void addPolicyFromHeaderValue(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
+
+ bool shouldSendViolationReport(const String&) const;
+ void didSendViolationReport(const String&);
+
+ ExecutionContext* m_executionContext;
+ bool m_overrideInlineStyleAllowed;
+ CSPDirectiveListVector m_policies;
+
+ HashSet<unsigned, AlreadyHashed> m_violationReportsSent;
+
+ // We put the hash functions used on the policy object so that we only need
+ // to calculate a hash once and then distribute it to all of the directives
+ // for validation.
+ uint8_t m_scriptHashAlgorithmsUsed;
+ uint8_t m_styleHashAlgorithmsUsed;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp b/chromium/third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp
new file mode 100644
index 00000000000..434c779dfd8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp
@@ -0,0 +1,86 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/MediaListDirective.h"
+
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "platform/ParsingUtilities.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+MediaListDirective::MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy)
+{
+ Vector<UChar> characters;
+ value.appendTo(characters);
+ parse(characters.data(), characters.data() + characters.size());
+}
+
+bool MediaListDirective::allows(const String& type)
+{
+ return m_pluginTypes.contains(type);
+}
+
+void MediaListDirective::parse(const UChar* begin, const UChar* end)
+{
+ const UChar* position = begin;
+
+ // 'plugin-types ____;' OR 'plugin-types;'
+ if (position == end) {
+ policy()->reportInvalidPluginTypes(String());
+ return;
+ }
+
+ while (position < end) {
+ // _____ OR _____mime1/mime1
+ // ^ ^
+ skipWhile<UChar, isASCIISpace>(position, end);
+ if (position == end)
+ return;
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ begin = position;
+ if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ skipWhile<UChar, isMediaTypeCharacter>(position, end);
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ if (!skipExactly<UChar>(position, end, '/')) {
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+
+ // mime1/mime1 mime2/mime2
+ // ^
+ if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ skipWhile<UChar, isMediaTypeCharacter>(position, end);
+
+ // mime1/mime1 mime2/mime2 OR mime1/mime1 OR mime1/mime1/error
+ // ^ ^ ^
+ if (position < end && isNotASCIISpace(*position)) {
+ skipWhile<UChar, isNotASCIISpace>(position, end);
+ policy()->reportInvalidPluginTypes(String(begin, position - begin));
+ continue;
+ }
+ m_pluginTypes.add(String(begin, position - begin));
+
+ ASSERT(position == end || isASCIISpace(*position));
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/MediaListDirective.h b/chromium/third_party/WebKit/Source/core/frame/csp/MediaListDirective.h
new file mode 100644
index 00000000000..9f230ce987e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/MediaListDirective.h
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaListDirective_h
+#define MediaListDirective_h
+
+#include "core/frame/csp/CSPDirective.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+
+class MediaListDirective FINAL : public CSPDirective {
+ WTF_MAKE_NONCOPYABLE(MediaListDirective);
+public:
+ MediaListDirective(const String& name, const String& value, ContentSecurityPolicy*);
+ bool allows(const String& type);
+
+private:
+ void parse(const UChar* begin, const UChar* end);
+
+ HashSet<String> m_pluginTypes;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp b/chromium/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp
new file mode 100644
index 00000000000..ccf8c37d792
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp
@@ -0,0 +1,62 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/SourceListDirective.h"
+
+#include "core/frame/csp/CSPSourceList.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+SourceListDirective::SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+ : CSPDirective(name, value, policy)
+ , m_sourceList(policy, name)
+{
+ Vector<UChar> characters;
+ value.appendTo(characters);
+
+ m_sourceList.parse(characters.data(), characters.data() + characters.size());
+}
+
+bool SourceListDirective::allows(const KURL& url) const
+{
+ return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
+}
+
+bool SourceListDirective::allowInline() const
+{
+ return m_sourceList.allowInline();
+}
+
+bool SourceListDirective::allowEval() const
+{
+ return m_sourceList.allowEval();
+}
+
+bool SourceListDirective::allowNonce(const String& nonce) const
+{
+ return m_sourceList.allowNonce(nonce.stripWhiteSpace());
+}
+
+bool SourceListDirective::allowHash(const CSPHashValue& hashValue) const
+{
+ return m_sourceList.allowHash(hashValue);
+}
+
+bool SourceListDirective::isHashOrNoncePresent() const
+{
+ return m_sourceList.isHashOrNoncePresent();
+}
+
+uint8_t SourceListDirective::hashAlgorithmsUsed() const
+{
+ return m_sourceList.hashAlgorithmsUsed();
+}
+
+} // namespace WebCore
+
diff --git a/chromium/third_party/WebKit/Source/core/frame/csp/SourceListDirective.h b/chromium/third_party/WebKit/Source/core/frame/csp/SourceListDirective.h
new file mode 100644
index 00000000000..38005d13833
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/frame/csp/SourceListDirective.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SourceListDirective_h
+#define SourceListDirective_h
+
+#include "core/frame/csp/CSPDirective.h"
+#include "core/frame/csp/CSPSourceList.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class KURL;
+
+class SourceListDirective FINAL : public CSPDirective {
+ WTF_MAKE_NONCOPYABLE(SourceListDirective);
+public:
+ SourceListDirective(const String& name, const String& value, ContentSecurityPolicy*);
+
+ bool allows(const KURL&) const;
+ bool allowInline() const;
+ bool allowEval() const;
+ bool allowNonce(const String& nonce) const;
+ bool allowHash(const CSPHashValue&) const;
+ bool isHashOrNoncePresent() const;
+ uint8_t hashAlgorithmsUsed() const;
+
+private:
+ CSPSourceList m_sourceList;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/history/HistoryItem.cpp b/chromium/third_party/WebKit/Source/core/history/HistoryItem.cpp
deleted file mode 100644
index a26929a2865..00000000000
--- a/chromium/third_party/WebKit/Source/core/history/HistoryItem.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2005, 2006, 2008, 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/history/HistoryItem.h"
-
-#include "core/dom/Document.h"
-#include "platform/network/ResourceRequest.h"
-#include "wtf/CurrentTime.h"
-#include "wtf/text/CString.h"
-
-namespace WebCore {
-
-static long long generateSequenceNumber()
-{
- // Initialize to the current time to reduce the likelihood of generating
- // identifiers that overlap with those from past/future browser sessions.
- static long long next = static_cast<long long>(currentTime() * 1000000.0);
- return ++next;
-}
-
-HistoryItem::HistoryItem()
- : m_pageScaleFactor(0)
- , m_itemSequenceNumber(generateSequenceNumber())
- , m_documentSequenceNumber(generateSequenceNumber())
- , m_targetFrameID(0)
-{
-}
-
-HistoryItem::~HistoryItem()
-{
-}
-
-inline HistoryItem::HistoryItem(const HistoryItem& item)
- : RefCounted<HistoryItem>()
- , m_urlString(item.m_urlString)
- , m_originalURLString(item.m_originalURLString)
- , m_referrer(item.m_referrer)
- , m_target(item.m_target)
- , m_scrollPoint(item.m_scrollPoint)
- , m_pageScaleFactor(item.m_pageScaleFactor)
- , m_documentState(item.m_documentState)
- , m_itemSequenceNumber(item.m_itemSequenceNumber)
- , m_documentSequenceNumber(item.m_documentSequenceNumber)
- , m_targetFrameID(item.m_targetFrameID)
- , m_stateObject(item.m_stateObject)
- , m_formContentType(item.m_formContentType)
-{
- if (item.m_formData)
- m_formData = item.m_formData->copy();
-
- unsigned size = item.m_children.size();
- m_children.reserveInitialCapacity(size);
- for (unsigned i = 0; i < size; ++i)
- m_children.uncheckedAppend(item.m_children[i]->copy());
-}
-
-PassRefPtr<HistoryItem> HistoryItem::copy() const
-{
- return adoptRef(new HistoryItem(*this));
-}
-
-void HistoryItem::reset()
-{
- m_urlString = String();
- m_originalURLString = String();
- m_referrer = nullAtom;
- m_target = String();
- m_itemSequenceNumber = generateSequenceNumber();
- m_stateObject = 0;
- m_documentSequenceNumber = generateSequenceNumber();
- m_targetFrameID = 0;
- m_formData = 0;
- m_formContentType = nullAtom;
- clearChildren();
-}
-
-const String& HistoryItem::urlString() const
-{
- return m_urlString;
-}
-
-// The first URL we loaded to get to where this history item points. Includes both client
-// and server redirects.
-const String& HistoryItem::originalURLString() const
-{
- return m_originalURLString;
-}
-
-KURL HistoryItem::url() const
-{
- return KURL(ParsedURLString, m_urlString);
-}
-
-KURL HistoryItem::originalURL() const
-{
- return KURL(ParsedURLString, m_originalURLString);
-}
-
-const AtomicString& HistoryItem::referrer() const
-{
- return m_referrer;
-}
-
-const String& HistoryItem::target() const
-{
- return m_target;
-}
-
-void HistoryItem::setURLString(const String& urlString)
-{
- if (m_urlString != urlString)
- m_urlString = urlString;
-}
-
-void HistoryItem::setURL(const KURL& url)
-{
- setURLString(url.string());
- clearDocumentState();
-}
-
-void HistoryItem::setOriginalURLString(const String& urlString)
-{
- m_originalURLString = urlString;
-}
-
-void HistoryItem::setReferrer(const AtomicString& referrer)
-{
- m_referrer = referrer;
-}
-
-void HistoryItem::setTarget(const String& target)
-{
- m_target = target;
-}
-
-const IntPoint& HistoryItem::scrollPoint() const
-{
- return m_scrollPoint;
-}
-
-void HistoryItem::setScrollPoint(const IntPoint& point)
-{
- m_scrollPoint = point;
-}
-
-void HistoryItem::clearScrollPoint()
-{
- m_scrollPoint.setX(0);
- m_scrollPoint.setY(0);
-}
-
-float HistoryItem::pageScaleFactor() const
-{
- return m_pageScaleFactor;
-}
-
-void HistoryItem::setPageScaleFactor(float scaleFactor)
-{
- m_pageScaleFactor = scaleFactor;
-}
-
-void HistoryItem::setDocumentState(const Vector<String>& state)
-{
- m_documentState = state;
-}
-
-const Vector<String>& HistoryItem::documentState() const
-{
- return m_documentState;
-}
-
-void HistoryItem::clearDocumentState()
-{
- m_documentState.clear();
-}
-
-void HistoryItem::setStateObject(PassRefPtr<SerializedScriptValue> object)
-{
- m_stateObject = object;
-}
-
-void HistoryItem::addChildItem(PassRefPtr<HistoryItem> child)
-{
- m_children.append(child);
-}
-
-const HistoryItemVector& HistoryItem::children() const
-{
- return m_children;
-}
-
-void HistoryItem::clearChildren()
-{
- m_children.clear();
-}
-
-const AtomicString& HistoryItem::formContentType() const
-{
- return m_formContentType;
-}
-
-void HistoryItem::setFormInfoFromRequest(const ResourceRequest& request)
-{
- m_referrer = request.httpReferrer();
-
- if (equalIgnoringCase(request.httpMethod(), "POST")) {
- // FIXME: Eventually we have to make this smart enough to handle the case where
- // we have a stream for the body to handle the "data interspersed with files" feature.
- m_formData = request.httpBody();
- m_formContentType = request.httpContentType();
- } else {
- m_formData = 0;
- m_formContentType = nullAtom;
- }
-}
-
-void HistoryItem::setFormData(PassRefPtr<FormData> formData)
-{
- m_formData = formData;
-}
-
-void HistoryItem::setFormContentType(const AtomicString& formContentType)
-{
- m_formContentType = formContentType;
-}
-
-FormData* HistoryItem::formData()
-{
- return m_formData.get();
-}
-
-bool HistoryItem::isCurrentDocument(Document* doc) const
-{
- // FIXME: We should find a better way to check if this is the current document.
- return equalIgnoringFragmentIdentifier(url(), doc->url());
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/history/HistoryItem.h b/chromium/third_party/WebKit/Source/core/history/HistoryItem.h
deleted file mode 100644
index e2fa91eb49a..00000000000
--- a/chromium/third_party/WebKit/Source/core/history/HistoryItem.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved.
- * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HistoryItem_h
-#define HistoryItem_h
-
-#include "bindings/v8/SerializedScriptValue.h"
-#include "platform/geometry/IntPoint.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class Document;
-class FormData;
-class HistoryItem;
-class Image;
-class KURL;
-class ResourceRequest;
-
-typedef Vector<RefPtr<HistoryItem> > HistoryItemVector;
-
-class HistoryItem : public RefCounted<HistoryItem> {
-public:
- static PassRefPtr<HistoryItem> create() { return adoptRef(new HistoryItem); }
-
- ~HistoryItem();
-
- PassRefPtr<HistoryItem> copy() const;
-
- // Resets the HistoryItem to its initial state, as returned by create().
- void reset();
-
- const String& originalURLString() const;
- const String& urlString() const;
- KURL url() const;
- KURL originalURL() const;
-
- const AtomicString& referrer() const;
- const String& target() const;
-
- FormData* formData();
- const AtomicString& formContentType() const;
-
- const IntPoint& scrollPoint() const;
- void setScrollPoint(const IntPoint&);
- void clearScrollPoint();
-
- float pageScaleFactor() const;
- void setPageScaleFactor(float);
-
- const Vector<String>& documentState() const;
- void setDocumentState(const Vector<String>&);
- void clearDocumentState();
-
- void setURL(const KURL&);
- void setURLString(const String&);
- void setOriginalURLString(const String&);
- void setReferrer(const AtomicString&);
- void setTarget(const String&);
-
- void setStateObject(PassRefPtr<SerializedScriptValue> object);
- SerializedScriptValue* stateObject() const { return m_stateObject.get(); }
-
- void setItemSequenceNumber(long long number) { m_itemSequenceNumber = number; }
- long long itemSequenceNumber() const { return m_itemSequenceNumber; }
-
- void setDocumentSequenceNumber(long long number) { m_documentSequenceNumber = number; }
- long long documentSequenceNumber() const { return m_documentSequenceNumber; }
-
- void setTargetFrameID(int64_t id) { m_targetFrameID = id; }
- int64_t targetFrameID() const { return m_targetFrameID; }
-
- void setFormInfoFromRequest(const ResourceRequest&);
- void setFormData(PassRefPtr<FormData>);
- void setFormContentType(const AtomicString&);
-
- void addChildItem(PassRefPtr<HistoryItem>);
- const HistoryItemVector& children() const;
- void clearChildren();
-
- bool isCurrentDocument(Document*) const;
-
-private:
- HistoryItem();
- explicit HistoryItem(const HistoryItem&);
-
- String m_urlString;
- String m_originalURLString;
- AtomicString m_referrer;
- String m_target;
-
- IntPoint m_scrollPoint;
- float m_pageScaleFactor;
- Vector<String> m_documentState;
-
- HistoryItemVector m_children;
-
- // If two HistoryItems have the same item sequence number, then they are
- // clones of one another. Traversing history from one such HistoryItem to
- // another is a no-op. HistoryItem clones are created for parent and
- // sibling frames when only a subframe navigates.
- int64_t m_itemSequenceNumber;
-
- // If two HistoryItems have the same document sequence number, then they
- // refer to the same instance of a document. Traversing history from one
- // such HistoryItem to another preserves the document.
- int64_t m_documentSequenceNumber;
-
- int64_t m_targetFrameID;
-
- // Support for HTML5 History
- RefPtr<SerializedScriptValue> m_stateObject;
-
- // info used to repost form data
- RefPtr<FormData> m_formData;
- AtomicString m_formContentType;
-
-}; //class HistoryItem
-
-} //namespace WebCore
-
-#endif // HISTORYITEM_H
diff --git a/chromium/third_party/WebKit/Source/core/html/ClassList.cpp b/chromium/third_party/WebKit/Source/core/html/ClassList.cpp
index ba44f7b0b0d..a6c8156260a 100644
--- a/chromium/third_party/WebKit/Source/core/html/ClassList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/ClassList.cpp
@@ -25,6 +25,7 @@
#include "config.h"
#include "core/html/ClassList.h"
+#include "core/dom/Document.h"
namespace WebCore {
@@ -32,6 +33,7 @@ using namespace HTMLNames;
ClassList::ClassList(Element* element) : m_element(element) { }
+#if !ENABLE(OILPAN)
void ClassList::ref()
{
m_element->ref();
@@ -41,6 +43,7 @@ void ClassList::deref()
{
m_element->deref();
}
+#endif
unsigned ClassList::length() const
{
@@ -70,4 +73,10 @@ const SpaceSplitString& ClassList::classNames() const
return m_element->elementData()->classNames();
}
+void ClassList::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ DOMTokenList::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ClassList.h b/chromium/third_party/WebKit/Source/core/html/ClassList.h
index cc2217fab5e..13444d97253 100644
--- a/chromium/third_party/WebKit/Source/core/html/ClassList.h
+++ b/chromium/third_party/WebKit/Source/core/html/ClassList.h
@@ -25,7 +25,7 @@
#ifndef ClassList_h
#define ClassList_h
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/DOMTokenList.h"
#include "core/dom/Element.h"
#include "core/dom/SpaceSplitString.h"
@@ -38,15 +38,17 @@ class Element;
typedef int ExceptionCode;
-class ClassList : public DOMTokenList {
+class ClassList FINAL : public DOMTokenList {
public:
- static PassOwnPtr<ClassList> create(Element* element)
+ static PassOwnPtrWillBeRawPtr<ClassList> create(Element* element)
{
- return adoptPtr(new ClassList(element));
+ return adoptPtrWillBeNoop(new ClassList(element));
}
+#if !ENABLE(OILPAN)
virtual void ref() OVERRIDE;
virtual void deref() OVERRIDE;
+#endif
virtual unsigned length() const OVERRIDE;
virtual const AtomicString item(unsigned index) const OVERRIDE;
@@ -55,17 +57,19 @@ public:
void clearValueForQuirksMode() { m_classNamesForQuirksMode = nullptr; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- ClassList(Element*);
+ explicit ClassList(Element*);
virtual bool containsInternal(const AtomicString&) const OVERRIDE;
const SpaceSplitString& classNames() const;
- virtual AtomicString value() const OVERRIDE { return m_element->getAttribute(HTMLNames::classAttr); }
+ virtual const AtomicString& value() const OVERRIDE { return m_element->getAttribute(HTMLNames::classAttr); }
virtual void setValue(const AtomicString& value) OVERRIDE { m_element->setAttribute(HTMLNames::classAttr, value); }
- Element* m_element;
+ RawPtrWillBeMember<Element> m_element;
mutable OwnPtr<SpaceSplitString> m_classNamesForQuirksMode;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/CollectionIndexCache.h b/chromium/third_party/WebKit/Source/core/html/CollectionIndexCache.h
new file mode 100644
index 00000000000..865104ba059
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/CollectionIndexCache.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CollectionIndexCache_h
+#define CollectionIndexCache_h
+
+#include "core/dom/Element.h"
+
+namespace WebCore {
+
+template <typename Collection, typename NodeType>
+class CollectionIndexCache {
+ DISALLOW_ALLOCATION();
+public:
+ CollectionIndexCache();
+
+ bool isEmpty(const Collection& collection)
+ {
+ if (isCachedNodeCountValid())
+ return !cachedNodeCount();
+ if (cachedNode())
+ return false;
+ return !nodeAt(collection, 0);
+ }
+ bool hasExactlyOneNode(const Collection& collection)
+ {
+ if (isCachedNodeCountValid())
+ return cachedNodeCount() == 1;
+ if (cachedNode())
+ return !cachedNodeIndex() && !nodeAt(collection, 1);
+ return nodeAt(collection, 0) && !nodeAt(collection, 1);
+ }
+
+ unsigned nodeCount(const Collection&);
+ NodeType* nodeAt(const Collection&, unsigned index);
+
+ void invalidate();
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_currentNode);
+ }
+
+private:
+ NodeType* nodeBeforeCachedNode(const Collection&, unsigned index);
+ NodeType* nodeAfterCachedNode(const Collection&, unsigned index);
+
+ ALWAYS_INLINE NodeType* cachedNode() const { return m_currentNode; }
+ ALWAYS_INLINE unsigned cachedNodeIndex() const { ASSERT(cachedNode()); return m_cachedNodeIndex; }
+ ALWAYS_INLINE void setCachedNode(NodeType* node, unsigned index)
+ {
+ ASSERT(node);
+ m_currentNode = node;
+ m_cachedNodeIndex = index;
+ }
+
+ ALWAYS_INLINE bool isCachedNodeCountValid() const { return m_isLengthCacheValid; }
+ ALWAYS_INLINE unsigned cachedNodeCount() const { return m_cachedNodeCount; }
+ ALWAYS_INLINE void setCachedNodeCount(unsigned length)
+ {
+ m_cachedNodeCount = length;
+ m_isLengthCacheValid = true;
+ }
+
+ RawPtrWillBeMember<NodeType> m_currentNode;
+ unsigned m_cachedNodeCount;
+ unsigned m_cachedNodeIndex;
+ unsigned m_isLengthCacheValid : 1;
+};
+
+template <typename Collection, typename NodeType>
+CollectionIndexCache<Collection, NodeType>::CollectionIndexCache()
+ : m_currentNode(nullptr)
+ , m_cachedNodeCount(0)
+ , m_cachedNodeIndex(0)
+ , m_isLengthCacheValid(false)
+{
+}
+
+template <typename Collection, typename NodeType>
+void CollectionIndexCache<Collection, NodeType>::invalidate()
+{
+ m_currentNode = nullptr;
+ m_isLengthCacheValid = false;
+}
+
+template <typename Collection, typename NodeType>
+inline unsigned CollectionIndexCache<Collection, NodeType>::nodeCount(const Collection& collection)
+{
+ if (isCachedNodeCountValid())
+ return cachedNodeCount();
+
+ nodeAt(collection, UINT_MAX);
+ ASSERT(isCachedNodeCountValid());
+
+ return cachedNodeCount();
+}
+
+template <typename Collection, typename NodeType>
+inline NodeType* CollectionIndexCache<Collection, NodeType>::nodeAt(const Collection& collection, unsigned index)
+{
+ if (isCachedNodeCountValid() && index >= cachedNodeCount())
+ return 0;
+
+ if (cachedNode()) {
+ if (index > cachedNodeIndex())
+ return nodeAfterCachedNode(collection, index);
+ if (index < cachedNodeIndex())
+ return nodeBeforeCachedNode(collection, index);
+ return cachedNode();
+ }
+
+ // No valid cache yet, let's find the first matching element.
+ ASSERT(!isCachedNodeCountValid());
+ NodeType* firstNode = collection.traverseToFirstElement();
+ if (!firstNode) {
+ // The collection is empty.
+ setCachedNodeCount(0);
+ return 0;
+ }
+ setCachedNode(firstNode, 0);
+ return index ? nodeAfterCachedNode(collection, index) : firstNode;
+}
+
+template <typename Collection, typename NodeType>
+inline NodeType* CollectionIndexCache<Collection, NodeType>::nodeBeforeCachedNode(const Collection& collection, unsigned index)
+{
+ ASSERT(cachedNode()); // Cache should be valid.
+ unsigned currentIndex = cachedNodeIndex();
+ ASSERT(currentIndex > index);
+
+ // Determine if we should traverse from the beginning of the collection instead of the cached node.
+ bool firstIsCloser = index < currentIndex - index;
+ if (firstIsCloser || !collection.canTraverseBackward()) {
+ NodeType* firstNode = collection.traverseToFirstElement();
+ ASSERT(firstNode);
+ setCachedNode(firstNode, 0);
+ return index ? nodeAfterCachedNode(collection, index) : firstNode;
+ }
+
+ // Backward traversal from the cached node to the requested index.
+ ASSERT(collection.canTraverseBackward());
+ NodeType* currentNode = collection.traverseBackwardToOffset(index, *cachedNode(), currentIndex);
+ ASSERT(currentNode);
+ setCachedNode(currentNode, currentIndex);
+ return currentNode;
+}
+
+template <typename Collection, typename NodeType>
+inline NodeType* CollectionIndexCache<Collection, NodeType>::nodeAfterCachedNode(const Collection& collection, unsigned index)
+{
+ ASSERT(cachedNode()); // Cache should be valid.
+ unsigned currentIndex = cachedNodeIndex();
+ ASSERT(currentIndex < index);
+
+ // Determine if we should traverse from the end of the collection instead of the cached node.
+ bool lastIsCloser = isCachedNodeCountValid() && cachedNodeCount() - index < index - currentIndex;
+ if (lastIsCloser && collection.canTraverseBackward()) {
+ NodeType* lastItem = collection.traverseToLastElement();
+ ASSERT(lastItem);
+ setCachedNode(lastItem, cachedNodeCount() - 1);
+ if (index < cachedNodeCount() - 1)
+ return nodeBeforeCachedNode(collection, index);
+ return lastItem;
+ }
+
+ // Forward traversal from the cached node to the requested index.
+ NodeType* currentNode = collection.traverseForwardToOffset(index, *cachedNode(), currentIndex);
+ if (!currentNode) {
+ // Did not find the node. On plus side, we now know the length.
+ setCachedNodeCount(currentIndex + 1);
+ return 0;
+ }
+ setCachedNode(currentNode, currentIndex);
+ return currentNode;
+}
+
+} // namespace WebCore
+
+#endif // CollectionIndexCache_h
diff --git a/chromium/third_party/WebKit/Source/core/html/CollectionType.h b/chromium/third_party/WebKit/Source/core/html/CollectionType.h
index 9db25d42e2e..f57a0c223b9 100644
--- a/chromium/third_party/WebKit/Source/core/html/CollectionType.h
+++ b/chromium/third_party/WebKit/Source/core/html/CollectionType.h
@@ -36,10 +36,6 @@ enum CollectionType {
DocScripts, // all <script> elements
DocAll, // "all" elements (IE)
- // Named collection types cached in the document.
- WindowNamedItems,
- DocumentNamedItems,
-
// Unnamed HTMLCollection types cached in elements.
NodeChildren, // first-level children (ParentNode DOM interface)
TableTBodies, // all <tbody> elements in this table
@@ -52,21 +48,38 @@ enum CollectionType {
MapAreas,
FormControls,
+ // Named HTMLCollection types cached in the document.
+ WindowNamedItems,
+ DocumentNamedItems,
+
+ // Named HTMLCollection types cached in elements.
+ ClassCollectionType,
+ TagCollectionType,
+ HTMLTagCollectionType,
+
// Live NodeList.
- ChildNodeListType,
- ClassNodeListType,
NameNodeListType,
- TagNodeListType,
- HTMLTagNodeListType,
RadioNodeListType,
+ RadioImgNodeListType,
LabelsNodeListType,
};
-static const CollectionType FirstNodeListType = ChildNodeListType;
+static const CollectionType FirstNamedCollectionType = WindowNamedItems;
+static const CollectionType FirstLiveNodeListType = NameNodeListType;
+
+inline bool isUnnamedHTMLCollectionType(CollectionType type)
+{
+ return type < FirstNamedCollectionType;
+}
+
+inline bool isHTMLCollectionType(CollectionType type)
+{
+ return type < FirstLiveNodeListType;
+}
-inline bool isNodeList(CollectionType type)
+inline bool isLiveNodeListType(CollectionType type)
{
- return type >= FirstNodeListType;
+ return type >= FirstLiveNodeListType;
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/DOMFormData.h b/chromium/third_party/WebKit/Source/core/html/DOMFormData.h
index c522b72a0c8..58ce890a29d 100644
--- a/chromium/third_party/WebKit/Source/core/html/DOMFormData.h
+++ b/chromium/third_party/WebKit/Source/core/html/DOMFormData.h
@@ -32,6 +32,7 @@
#define DOMFormData_h
#include "core/html/FormDataList.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -45,10 +46,17 @@ namespace WebCore {
class Blob;
class HTMLFormElement;
-class DOMFormData : public FormDataList, public ScriptWrappable, public RefCounted<DOMFormData> {
+class DOMFormData : public RefCountedWillBeGarbageCollectedFinalized<DOMFormData>, public FormDataList, public ScriptWrappable {
public:
- static PassRefPtr<DOMFormData> create(HTMLFormElement* form) { return adoptRef(new DOMFormData(form)); }
- static PassRefPtr<DOMFormData> create(const WTF::TextEncoding& encoding) { return adoptRef(new DOMFormData(encoding)); }
+ static PassRefPtrWillBeRawPtr<DOMFormData> create(HTMLFormElement* form = 0)
+ {
+ return adoptRefWillBeNoop(new DOMFormData(form));
+ }
+
+ static PassRefPtrWillBeRawPtr<DOMFormData> create(const WTF::TextEncoding& encoding)
+ {
+ return adoptRefWillBeNoop(new DOMFormData(encoding));
+ }
void append(const String& name, const String& value);
void append(const String& name, Blob*, const String& filename = String());
diff --git a/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.cpp b/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.cpp
new file mode 100644
index 00000000000..223f8a90cf8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.cpp
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/DocumentNameCollection.h"
+
+#include "core/html/HTMLEmbedElement.h"
+#include "core/html/HTMLFormElement.h"
+#include "core/html/HTMLObjectElement.h"
+
+namespace WebCore {
+
+DocumentNameCollection::DocumentNameCollection(ContainerNode& document, const AtomicString& name)
+ : HTMLNameCollection(document, DocumentNamedItems, name)
+{
+}
+
+bool DocumentNameCollection::elementMatches(const Element& element) const
+{
+ // Match images, forms, applets, embeds, objects and iframes by name,
+ // applets and object by id, and images by id but only if they have
+ // a name attribute (this very strange rule matches IE)
+ if (isHTMLFormElement(element) || isHTMLIFrameElement(element) || (isHTMLEmbedElement(element) && toHTMLEmbedElement(element).isExposed()))
+ return element.getNameAttribute() == m_name;
+ if (isHTMLAppletElement(element) || (isHTMLObjectElement(element) && toHTMLObjectElement(element).isExposed()))
+ return element.getNameAttribute() == m_name || element.getIdAttribute() == m_name;
+ if (isHTMLImageElement(element))
+ return element.getNameAttribute() == m_name || (element.getIdAttribute() == m_name && element.hasName());
+ return false;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.h b/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.h
new file mode 100644
index 00000000000..2789bacfb9b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/DocumentNameCollection.h
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DocumentNameCollection_h
+#define DocumentNameCollection_h
+
+#include "core/html/HTMLNameCollection.h"
+
+namespace WebCore {
+
+class DocumentNameCollection FINAL : public HTMLNameCollection {
+public:
+ static PassRefPtrWillBeRawPtr<DocumentNameCollection> create(ContainerNode& document, CollectionType type, const AtomicString& name)
+ {
+ ASSERT_UNUSED(type, type == DocumentNamedItems);
+ return adoptRefWillBeNoop(new DocumentNameCollection(document, name));
+ }
+
+ bool elementMatches(const Element&) const;
+
+private:
+ DocumentNameCollection(ContainerNode& document, const AtomicString& name);
+};
+
+DEFINE_TYPE_CASTS(DocumentNameCollection, LiveNodeListBase, collection, collection->type() == DocumentNamedItems, collection.type() == DocumentNamedItems);
+
+} // namespace WebCore
+
+#endif // DocumentNameCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp b/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
index ce1f4b58ddb..41c49e81d43 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/html/FormAssociatedElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/IdTargetObserver.h"
#include "core/html/HTMLFormControlElement.h"
#include "core/html/HTMLFormElement.h"
@@ -36,20 +36,21 @@ namespace WebCore {
using namespace HTMLNames;
-class FormAttributeTargetObserver : IdTargetObserver {
- WTF_MAKE_FAST_ALLOCATED;
+class FormAttributeTargetObserver : public IdTargetObserver {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<FormAttributeTargetObserver> create(const AtomicString& id, FormAssociatedElement*);
+ static PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> create(const AtomicString& id, FormAssociatedElement*);
+ virtual void trace(Visitor*) OVERRIDE;
virtual void idTargetChanged() OVERRIDE;
private:
FormAttributeTargetObserver(const AtomicString& id, FormAssociatedElement*);
- FormAssociatedElement* m_element;
+ RawPtrWillBeMember<FormAssociatedElement> m_element;
};
FormAssociatedElement::FormAssociatedElement()
- : m_form(0)
+ : m_formWasSetByParser(false)
{
}
@@ -58,6 +59,13 @@ FormAssociatedElement::~FormAssociatedElement()
// We can't call setForm here because it contains virtual calls.
}
+void FormAssociatedElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_formAttributeTargetObserver);
+ visitor->trace(m_form);
+ visitor->trace(m_validityState);
+}
+
ValidityState* FormAssociatedElement::validity()
{
if (!m_validityState)
@@ -70,15 +78,14 @@ void FormAssociatedElement::didMoveToNewDocument(Document& oldDocument)
{
HTMLElement* element = toHTMLElement(this);
if (element->fastHasAttribute(formAttr))
- m_formAttributeTargetObserver = nullptr;
+ setFormAttributeTargetObserver(nullptr);
}
void FormAssociatedElement::insertedInto(ContainerNode* insertionPoint)
{
- if (m_form && insertionPoint->highestAncestor() != m_form->highestAncestor())
- setForm(0);
+ if (!m_formWasSetByParser || insertionPoint->highestAncestorOrSelf() != m_form->highestAncestorOrSelf())
+ resetFormOwner();
- resetFormOwner();
if (!insertionPoint->inDocument())
return;
@@ -91,52 +98,71 @@ void FormAssociatedElement::removedFrom(ContainerNode* insertionPoint)
{
HTMLElement* element = toHTMLElement(this);
if (insertionPoint->inDocument() && element->fastHasAttribute(formAttr))
- m_formAttributeTargetObserver = nullptr;
+ setFormAttributeTargetObserver(nullptr);
// If the form and element are both in the same tree, preserve the connection to the form.
// Otherwise, null out our form and remove ourselves from the form's list of elements.
- if (m_form && element->highestAncestor() != m_form->highestAncestor())
- setForm(0);
+ if (m_form && element->highestAncestorOrSelf() != m_form->highestAncestorOrSelf())
+ resetFormOwner();
}
-HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* element, HTMLFormElement* currentAssociatedForm)
+HTMLFormElement* FormAssociatedElement::findAssociatedForm(const HTMLElement* element)
{
const AtomicString& formId(element->fastGetAttribute(formAttr));
+ // 3. If the element is reassociateable, has a form content attribute, and
+ // is itself in a Document, then run these substeps:
if (!formId.isNull() && element->inDocument()) {
- // The HTML5 spec says that the element should be associated with
- // the first element in the document to have an ID that equal to
- // the value of form attribute, so we put the result of
- // treeScope()->getElementById() over the given element.
- HTMLFormElement* newForm = 0;
+ // 3.1. If the first element in the Document to have an ID that is
+ // case-sensitively equal to the element's form content attribute's
+ // value is a form element, then associate the form-associated element
+ // with that form element.
+ // 3.2. Abort the "reset the form owner" steps.
Element* newFormCandidate = element->treeScope().getElementById(formId);
- if (newFormCandidate && newFormCandidate->hasTagName(formTag))
- newForm = toHTMLFormElement(newFormCandidate);
- return newForm;
+ return isHTMLFormElement(newFormCandidate) ? toHTMLFormElement(newFormCandidate) : 0;
}
-
- if (!currentAssociatedForm)
- return element->findFormAncestor();
-
- return currentAssociatedForm;
+ // 4. Otherwise, if the form-associated element in question has an ancestor
+ // form element, then associate the form-associated element with the nearest
+ // such ancestor form element.
+ return element->findFormAncestor();
}
-void FormAssociatedElement::formRemovedFromTree(const Node* formRoot)
+void FormAssociatedElement::formRemovedFromTree(const Node& formRoot)
{
ASSERT(m_form);
- if (toHTMLElement(this)->highestAncestor() == formRoot)
+ if (toHTMLElement(this)->highestAncestorOrSelf() == formRoot)
return;
- setForm(0);
+ resetFormOwner();
+}
+
+void FormAssociatedElement::associateByParser(HTMLFormElement* form)
+{
+ if (form && form->inDocument()) {
+ m_formWasSetByParser = true;
+ setForm(form);
+ form->didAssociateByParser();
+ }
}
void FormAssociatedElement::setForm(HTMLFormElement* newForm)
{
- if (m_form == newForm)
+ if (m_form.get() == newForm)
return;
willChangeForm();
if (m_form)
- m_form->removeFormElement(this);
- m_form = newForm;
- if (m_form)
- m_form->registerFormElement(*this);
+ m_form->disassociate(*this);
+ if (newForm) {
+#if ENABLE(OILPAN)
+ m_form = newForm;
+#else
+ m_form = newForm->createWeakPtr();
+#endif
+ m_form->associate(*this);
+ } else {
+#if ENABLE(OILPAN)
+ m_form = nullptr;
+#else
+ m_form = WeakPtr<HTMLFormElement>();
+#endif
+ }
didChangeForm();
}
@@ -148,41 +174,31 @@ void FormAssociatedElement::didChangeForm()
{
}
-void FormAssociatedElement::formWillBeDestroyed()
-{
- ASSERT(m_form);
- if (!m_form)
- return;
- willChangeForm();
- m_form = 0;
- didChangeForm();
-}
-
void FormAssociatedElement::resetFormOwner()
{
- HTMLFormElement* originalForm = m_form;
- setForm(findAssociatedForm(toHTMLElement(this), m_form));
+ m_formWasSetByParser = false;
HTMLElement* element = toHTMLElement(this);
- if (m_form && m_form != originalForm && m_form->inDocument())
+ const AtomicString& formId(element->fastGetAttribute(formAttr));
+ HTMLFormElement* nearestForm = element->findFormAncestor();
+ // 1. If the element's form owner is not null, and either the element is not
+ // reassociateable or its form content attribute is not present, and the
+ // element's form owner is its nearest form element ancestor after the
+ // change to the ancestor chain, then do nothing, and abort these steps.
+ if (m_form && formId.isNull() && m_form.get() == nearestForm)
+ return;
+
+ HTMLFormElement* originalForm = m_form.get();
+ setForm(findAssociatedForm(element));
+ // FIXME: Move didAssociateFormControl call to didChangeForm or
+ // HTMLFormElement::associate.
+ if (m_form && m_form.get() != originalForm && m_form->inDocument())
element->document().didAssociateFormControl(element);
}
void FormAssociatedElement::formAttributeChanged()
{
- HTMLElement* element = toHTMLElement(this);
- if (!element->fastHasAttribute(formAttr)) {
- // The form attribute removed. We need to reset form owner here.
- HTMLFormElement* originalForm = m_form;
- setForm(element->findFormAncestor());
- HTMLElement* element = toHTMLElement(this);
- if (m_form && m_form != originalForm && m_form->inDocument())
- element->document().didAssociateFormControl(element);
- m_formAttributeTargetObserver = nullptr;
- } else {
- resetFormOwner();
- if (element->inDocument())
- resetFormAttributeTargetObserver();
- }
+ resetFormOwner();
+ resetFormAttributeTargetObserver();
}
bool FormAssociatedElement::customError() const
@@ -253,10 +269,21 @@ void FormAssociatedElement::setCustomValidity(const String& error)
m_customValidationMessage = error;
}
+void FormAssociatedElement::setFormAttributeTargetObserver(PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> newObserver)
+{
+ if (m_formAttributeTargetObserver)
+ m_formAttributeTargetObserver->unregister();
+ m_formAttributeTargetObserver = newObserver;
+}
+
void FormAssociatedElement::resetFormAttributeTargetObserver()
{
- ASSERT(toHTMLElement(this)->inDocument());
- m_formAttributeTargetObserver = FormAttributeTargetObserver::create(toHTMLElement(this)->fastGetAttribute(formAttr), this);
+ HTMLElement* element = toHTMLElement(this);
+ const AtomicString& formId(element->fastGetAttribute(formAttr));
+ if (!formId.isNull() && element->inDocument())
+ setFormAttributeTargetObserver(FormAttributeTargetObserver::create(formId, this));
+ else
+ setFormAttributeTargetObserver(nullptr);
}
void FormAssociatedElement::formAttributeTargetChanged()
@@ -299,9 +326,9 @@ HTMLElement& toHTMLElement(FormAssociatedElement& associatedElement)
return const_cast<HTMLElement&>(toHTMLElement(static_cast<const FormAssociatedElement&>(associatedElement)));
}
-PassOwnPtr<FormAttributeTargetObserver> FormAttributeTargetObserver::create(const AtomicString& id, FormAssociatedElement* element)
+PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver> FormAttributeTargetObserver::create(const AtomicString& id, FormAssociatedElement* element)
{
- return adoptPtr(new FormAttributeTargetObserver(id, element));
+ return adoptPtrWillBeNoop(new FormAttributeTargetObserver(id, element));
}
FormAttributeTargetObserver::FormAttributeTargetObserver(const AtomicString& id, FormAssociatedElement* element)
@@ -310,6 +337,12 @@ FormAttributeTargetObserver::FormAttributeTargetObserver(const AtomicString& id,
{
}
+void FormAttributeTargetObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ IdTargetObserver::trace(visitor);
+}
+
void FormAttributeTargetObserver::idTargetChanged()
{
m_element->formAttributeTargetChanged();
diff --git a/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h b/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h
index 15f2fa1fbc8..e41483a55c0 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/FormAssociatedElement.h
@@ -24,6 +24,8 @@
#ifndef FormAssociatedElement_h
#define FormAssociatedElement_h
+#include "platform/heap/Handle.h"
+#include "wtf/WeakPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -39,15 +41,17 @@ class ValidationMessage;
class ValidityState;
class VisibleSelection;
-class FormAssociatedElement {
+class FormAssociatedElement : public WillBeGarbageCollectedMixin {
public:
virtual ~FormAssociatedElement();
+#if !ENABLE(OILPAN)
void ref() { refFormAssociatedElement(); }
void deref() { derefFormAssociatedElement(); }
+#endif
- static HTMLFormElement* findAssociatedForm(const HTMLElement*, HTMLFormElement*);
- HTMLFormElement* form() const { return m_form; }
+ static HTMLFormElement* findAssociatedForm(const HTMLElement*);
+ HTMLFormElement* form() const { return m_form.get(); }
ValidityState* validity();
virtual bool isFormControlElement() const = 0;
@@ -63,11 +67,9 @@ public:
// Return true for a successful control (see HTML4-17.13.2).
virtual bool appendFormData(FormDataList&, bool) { return false; }
- void formWillBeDestroyed();
-
void resetFormOwner();
- void formRemovedFromTree(const Node* formRoot);
+ void formRemovedFromTree(const Node& formRoot);
// ValidityState attribute implementations
bool customError() const;
@@ -88,14 +90,20 @@ public:
void formAttributeTargetChanged();
+ typedef WillBeHeapVector<RawPtrWillBeMember<FormAssociatedElement> > List;
+
protected:
FormAssociatedElement();
+ void trace(Visitor*);
void insertedInto(ContainerNode*);
void removedFrom(ContainerNode*);
void didMoveToNewDocument(Document& oldDocument);
+ // FIXME: Remove usage of setForm. resetFormOwner should be enough, and
+ // setForm is confusing.
void setForm(HTMLFormElement*);
+ void associateByParser(HTMLFormElement*);
void formAttributeChanged();
// If you add an override of willChangeForm() or didChangeForm() to a class
@@ -107,15 +115,23 @@ protected:
String customValidationMessage() const;
private:
+#if !ENABLE(OILPAN)
virtual void refFormAssociatedElement() = 0;
virtual void derefFormAssociatedElement() = 0;
+#endif
+ void setFormAttributeTargetObserver(PassOwnPtrWillBeRawPtr<FormAttributeTargetObserver>);
void resetFormAttributeTargetObserver();
- OwnPtr<FormAttributeTargetObserver> m_formAttributeTargetObserver;
- HTMLFormElement* m_form;
- OwnPtr<ValidityState> m_validityState;
+ OwnPtrWillBeMember<FormAttributeTargetObserver> m_formAttributeTargetObserver;
+#if ENABLE(OILPAN)
+ Member<HTMLFormElement> m_form;
+#else
+ WeakPtr<HTMLFormElement> m_form;
+#endif
+ OwnPtrWillBeMember<ValidityState> m_validityState;
String m_customValidationMessage;
+ bool m_formWasSetByParser;
};
HTMLElement* toHTMLElement(FormAssociatedElement*);
diff --git a/chromium/third_party/WebKit/Source/core/html/FormData.idl b/chromium/third_party/WebKit/Source/core/html/FormData.idl
index 73dcbfb9479..49914a7b35c 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormData.idl
+++ b/chromium/third_party/WebKit/Source/core/html/FormData.idl
@@ -28,14 +28,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// https://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#formdata
+
[
- Constructor([Default=Undefined] optional HTMLFormElement form),
- ImplementedAs=DOMFormData
+ Constructor(optional HTMLFormElement form),
+ Exposed=Window&Worker,
+ ImplementedAs=DOMFormData,
+ WillBeGarbageCollected,
] interface FormData {
- // void append(DOMString name, DOMString value);
- // void append(DOMString name, Blob value, optional DOMString filename);
- [Custom] void append([Default=Undefined] optional DOMString name,
- [Default=Undefined] optional DOMString value,
- [Default=Undefined] optional DOMString filename);
+ void append(DOMString name, Blob value, optional DOMString filename);
+ void append(DOMString name, DOMString value);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/FormDataList.cpp b/chromium/third_party/WebKit/Source/core/html/FormDataList.cpp
index b564d2cc102..39aa18ddaed 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormDataList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/FormDataList.cpp
@@ -43,22 +43,22 @@ void FormDataList::appendString(const CString& string)
m_items.append(string);
}
-void FormDataList::appendBlob(PassRefPtr<Blob> blob, const String& filename)
+void FormDataList::appendBlob(PassRefPtrWillBeRawPtr<Blob> blob, const String& filename)
{
m_items.append(Item(blob, filename));
}
-PassRefPtr<FormData> FormDataList::createFormData(const WTF::TextEncoding& encoding, FormData::EncodingType encodingType)
+PassRefPtr<FormData> FormDataList::createFormData(FormData::EncodingType encodingType)
{
RefPtr<FormData> result = FormData::create();
- appendKeyValuePairItemsTo(result.get(), encoding, false, encodingType);
+ appendKeyValuePairItemsTo(result.get(), m_encoding, false, encodingType);
return result.release();
}
-PassRefPtr<FormData> FormDataList::createMultiPartFormData(const WTF::TextEncoding& encoding)
+PassRefPtr<FormData> FormDataList::createMultiPartFormData()
{
RefPtr<FormData> result = FormData::create();
- appendKeyValuePairItemsTo(result.get(), encoding, true);
+ appendKeyValuePairItemsTo(result.get(), m_encoding, true);
return result.release();
}
@@ -69,7 +69,7 @@ void FormDataList::appendKeyValuePairItemsTo(FormData* formData, const WTF::Text
Vector<char> encodedData;
- const Vector<FormDataList::Item>& items = this->items();
+ const WillBeHeapVector<Item>& items = this->items();
size_t formDataListSize = items.size();
ASSERT(!(formDataListSize % 2));
for (size_t i = 0; i < formDataListSize; i += 2) {
@@ -130,12 +130,7 @@ void FormDataList::appendKeyValuePairItemsTo(FormData* formData, const WTF::Text
}
formData->appendData("\r\n", 2);
} else {
- // Omit the name "isindex" if it's the first form data element.
- // FIXME: Why is this a good rule? Is this obsolete now?
- if (encodedData.isEmpty() && key.data() == "isindex")
- FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
- else
- FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
+ FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
}
}
@@ -145,4 +140,14 @@ void FormDataList::appendKeyValuePairItemsTo(FormData* formData, const WTF::Text
formData->appendData(encodedData.data(), encodedData.size());
}
+void FormDataList::trace(Visitor* visitor)
+{
+ visitor->trace(m_items);
+}
+
+void FormDataList::Item::trace(Visitor* visitor)
+{
+ visitor->trace(m_blob);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/FormDataList.h b/chromium/third_party/WebKit/Source/core/html/FormDataList.h
index 123e566f621..301365951d1 100644
--- a/chromium/third_party/WebKit/Source/core/html/FormDataList.h
+++ b/chromium/third_party/WebKit/Source/core/html/FormDataList.h
@@ -22,6 +22,7 @@
#define FormDataList_h
#include "core/fileapi/Blob.h"
+#include "platform/heap/Handle.h"
#include "platform/network/FormData.h"
#include "wtf/Forward.h"
#include "wtf/text/CString.h"
@@ -32,18 +33,21 @@ namespace WebCore {
class FormDataList {
public:
class Item {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
Item() { }
Item(const WTF::CString& data) : m_data(data) { }
- Item(PassRefPtr<Blob> blob, const String& filename) : m_blob(blob), m_filename(filename) { }
+ Item(PassRefPtrWillBeRawPtr<Blob> blob, const String& filename) : m_blob(blob), m_filename(filename) { }
const WTF::CString& data() const { return m_data; }
Blob* blob() const { return m_blob.get(); }
const String& filename() const { return m_filename; }
+ void trace(Visitor*);
+
private:
WTF::CString m_data;
- RefPtr<Blob> m_blob;
+ RefPtrWillBeMember<Blob> m_blob;
String m_filename;
};
@@ -64,29 +68,33 @@ public:
appendString(key);
appendString(String::number(value));
}
- void appendBlob(const String& key, PassRefPtr<Blob> blob, const String& filename = String())
+ void appendBlob(const String& key, PassRefPtrWillBeRawPtr<Blob> blob, const String& filename = String())
{
appendString(key);
appendBlob(blob, filename);
}
- const Vector<Item>& items() const { return m_items; }
+ const WillBeHeapVector<Item>& items() const { return m_items; }
const WTF::TextEncoding& encoding() const { return m_encoding; }
- PassRefPtr<FormData> createFormData(const WTF::TextEncoding&, FormData::EncodingType = FormData::FormURLEncoded);
- PassRefPtr<FormData> createMultiPartFormData(const WTF::TextEncoding&);
+ PassRefPtr<FormData> createFormData(FormData::EncodingType = FormData::FormURLEncoded);
+ PassRefPtr<FormData> createMultiPartFormData();
+
+ void trace(Visitor*);
private:
void appendKeyValuePairItemsTo(FormData*, const WTF::TextEncoding&, bool isMultiPartForm, FormData::EncodingType = FormData::FormURLEncoded);
void appendString(const CString&);
void appendString(const String&);
- void appendBlob(PassRefPtr<Blob>, const String& filename);
+ void appendBlob(PassRefPtrWillBeRawPtr<Blob>, const String& filename);
WTF::TextEncoding m_encoding;
- Vector<Item> m_items;
+ WillBeHeapVector<Item> m_items;
};
} // namespace WebCore
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::FormDataList::Item);
+
#endif // FormDataList_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp
index 5fc4b8bee57..38c620a350b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.cpp
@@ -31,13 +31,14 @@
namespace WebCore {
-PassRefPtr<HTMLAllCollection> HTMLAllCollection::create(Node* node, CollectionType type)
+PassRefPtrWillBeRawPtr<HTMLAllCollection> HTMLAllCollection::create(ContainerNode& node, CollectionType type)
{
- return adoptRef(new HTMLAllCollection(node, type));
+ ASSERT_UNUSED(type, type == DocAll);
+ return adoptRefWillBeNoop(new HTMLAllCollection(node));
}
-HTMLAllCollection::HTMLAllCollection(Node* node, CollectionType type)
- : HTMLCollection(node, type, DoesNotOverrideItemAfter)
+HTMLAllCollection::HTMLAllCollection(ContainerNode& node)
+ : HTMLCollection(node, DocAll, DoesNotOverrideItemAfter)
{
ScriptWrappable::init(this);
}
@@ -46,27 +47,28 @@ HTMLAllCollection::~HTMLAllCollection()
{
}
-Node* HTMLAllCollection::namedItemWithIndex(const AtomicString& name, unsigned index) const
+Element* HTMLAllCollection::namedItemWithIndex(const AtomicString& name, unsigned index) const
{
- updateNameCache();
+ updateIdNameCache();
- if (Vector<Element*>* cache = idCache(name)) {
- if (index < cache->size())
- return cache->at(index);
- index -= cache->size();
+ const NamedItemCache& cache = namedItemCache();
+ if (WillBeHeapVector<RawPtrWillBeMember<Element> >* elements = cache.getElementsById(name)) {
+ if (index < elements->size())
+ return elements->at(index);
+ index -= elements->size();
}
- if (Vector<Element*>* cache = nameCache(name)) {
- if (index < cache->size())
- return cache->at(index);
+ if (WillBeHeapVector<RawPtrWillBeMember<Element> >* elements = cache.getElementsByName(name)) {
+ if (index < elements->size())
+ return elements->at(index);
}
return 0;
}
-void HTMLAllCollection::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Node>& returnValue1)
+void HTMLAllCollection::namedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtrWillBeRawPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtrWillBeRawPtr<Element>& returnValue1)
{
- Vector<RefPtr<Node> > namedItems;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > namedItems;
this->namedItems(name, namedItems);
if (!namedItems.size())
@@ -84,9 +86,4 @@ void HTMLAllCollection::anonymousNamedGetter(const AtomicString& name, bool& ret
returnValue0 = NamedNodesCollection::create(namedItems);
}
-PassRefPtr<NodeList> HTMLAllCollection::tags(const String& name)
-{
- return ownerNode()->getElementsByTagName(name);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h
index d5f1106ac5d..458e3bc96ac 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.h
@@ -32,17 +32,18 @@ namespace WebCore {
class HTMLAllCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<HTMLAllCollection> create(Node*, CollectionType);
+ static PassRefPtrWillBeRawPtr<HTMLAllCollection> create(ContainerNode&, CollectionType);
virtual ~HTMLAllCollection();
- Node* namedItemWithIndex(const AtomicString& name, unsigned index) const;
- void anonymousNamedGetter(const AtomicString& name, bool&, RefPtr<NodeList>&, bool&, RefPtr<Node>&);
- PassRefPtr<NodeList> tags(const String&);
+ Element* namedItemWithIndex(const AtomicString& name, unsigned index) const;
+ void namedGetter(const AtomicString& name, bool&, RefPtrWillBeRawPtr<NodeList>&, bool&, RefPtrWillBeRawPtr<Element>&);
private:
- HTMLAllCollection(Node*, CollectionType);
+ explicit HTMLAllCollection(ContainerNode&);
};
+DEFINE_TYPE_CASTS(HTMLAllCollection, LiveNodeListBase, collection, collection->type() == DocAll, collection.type() == DocAll);
+
} // namespace WebCore
#endif // HTMLAllCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl
index 3508f8bc731..d56b8b6dbf5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAllCollection.idl
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,17 +24,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// FIXME: This interface should inherit HTMLCollection.
[
Custom=LegacyCallAsFunction,
DependentLifetime,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
+ WillBeGarbageCollected,
] interface HTMLAllCollection {
readonly attribute unsigned long length;
- [ImplementedAs=item] getter Node (unsigned long index);
- [Custom] Node item([Default=Undefined] optional unsigned long index);
- [ImplementedAs=anonymousNamedGetter, NotEnumerable] getter (NodeList or Node)(DOMString name);
- [Custom] Node namedItem(DOMString name);
- // FIXME: This should return an HTMLAllCollection.
- [MeasureAs=DocumentAllTags] NodeList tags(DOMString name);
+ [ImplementedAs=item] getter Element (unsigned long index);
+ [Custom] Element item([Default=Undefined] optional unsigned long index);
+ // FIXME: This should return an (HTMLCollection or Element) union.
+ [ImplementedAs=namedGetter] getter (NodeList or Element) namedItem(DOMString name);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
index 8a0e9f372d8..7c955b5f483 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
@@ -28,8 +28,10 @@
#include "core/editing/FrameSelection.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -40,10 +42,7 @@
#include "core/loader/PingLoader.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderImage.h"
-#include "core/svg/graphics/SVGImage.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/network/DNS.h"
#include "platform/network/ResourceRequest.h"
@@ -70,11 +69,11 @@ void preconnectToURL(const KURL& url, blink::WebPreconnectMotivation motivation)
}
-class HTMLAnchorElement::PrefetchEventHandler {
+class HTMLAnchorElement::PrefetchEventHandler FINAL : public NoBaseWillBeGarbageCollected<HTMLAnchorElement::PrefetchEventHandler> {
public:
- static PassOwnPtr<PrefetchEventHandler> create(HTMLAnchorElement* anchorElement)
+ static PassOwnPtrWillBeRawPtr<PrefetchEventHandler> create(HTMLAnchorElement* anchorElement)
{
- return adoptPtr(new HTMLAnchorElement::PrefetchEventHandler(anchorElement));
+ return adoptPtrWillBeNoop(new HTMLAnchorElement::PrefetchEventHandler(anchorElement));
}
void reset();
@@ -83,6 +82,8 @@ public:
void didChangeHREF() { m_hadHREFChanged = true; }
bool hasIssuedPreconnect() const { return m_hasIssuedPreconnect; }
+ void trace(Visitor* visitor) { visitor->trace(m_anchorElement); }
+
private:
explicit PrefetchEventHandler(HTMLAnchorElement*);
@@ -96,7 +97,7 @@ private:
bool shouldPrefetch(const KURL&);
void prefetch(blink::WebPreconnectMotivation);
- HTMLAnchorElement* m_anchorElement;
+ RawPtrWillBeMember<HTMLAnchorElement> m_anchorElement;
double m_mouseOverTimestamp;
double m_mouseDownTimestamp;
double m_tapDownTimestamp;
@@ -109,27 +110,19 @@ using namespace HTMLNames;
HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
- , m_hasRootEditableElementForSelectionOnMouseDown(false)
- , m_wasShiftKeyDownOnMouseDown(false)
, m_linkRelations(0)
, m_cachedVisitedLinkHash(0)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLAnchorElement> HTMLAnchorElement::create(Document& document)
{
- return adoptRef(new HTMLAnchorElement(aTag, document));
-}
-
-PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLAnchorElement(tagName, document));
+ return adoptRefWillBeNoop(new HTMLAnchorElement(aTag, document));
}
HTMLAnchorElement::~HTMLAnchorElement()
{
- clearRootEditableElementForSelectionOnMouseDown();
}
bool HTMLAnchorElement::supportsFocus() const
@@ -152,16 +145,13 @@ bool HTMLAnchorElement::isMouseFocusable() const
bool HTMLAnchorElement::isKeyboardFocusable() const
{
+ ASSERT(document().isActive());
+
if (isFocusable() && Element::supportsFocus())
return HTMLElement::isKeyboardFocusable();
- if (isLink()) {
- Page* page = document().page();
- if (!page)
- return false;
- if (!page->chrome().client().tabsToLinks())
- return false;
- }
+ if (isLink() && !document().frameHost()->chrome().client().tabsToLinks())
+ return false;
return HTMLElement::isKeyboardFocusable();
}
@@ -173,16 +163,16 @@ static void appendServerMapMousePosition(StringBuilder& url, Event* event)
ASSERT(event->target());
Node* target = event->target()->toNode();
ASSERT(target);
- if (!target->hasTagName(imgTag))
+ if (!isHTMLImageElement(*target))
return;
- HTMLImageElement* imageElement = toHTMLImageElement(event->target()->toNode());
- if (!imageElement || !imageElement->isServerMap())
+ HTMLImageElement& imageElement = toHTMLImageElement(*target);
+ if (!imageElement.isServerMap())
return;
- if (!imageElement->renderer() || !imageElement->renderer()->isRenderImage())
+ if (!imageElement.renderer() || !imageElement.renderer()->isRenderImage())
return;
- RenderImage* renderer = toRenderImage(imageElement->renderer());
+ RenderImage* renderer = toRenderImage(imageElement.renderer());
// FIXME: This should probably pass true for useTransforms.
FloatPoint absolutePosition = renderer->absoluteToLocal(FloatPoint(toMouseEvent(event)->pageX(), toMouseEvent(event)->pageY()));
@@ -197,7 +187,7 @@ static void appendServerMapMousePosition(StringBuilder& url, Event* event)
void HTMLAnchorElement::defaultEventHandler(Event* event)
{
if (isLink()) {
- if (focused() && isEnterKeyKeydownEvent(event) && treatLinkAsLiveForEventType(NonMouseEvent)) {
+ if (focused() && isEnterKeyKeydownEvent(event) && isLiveLink()) {
event->setDefaultHandled();
dispatchSimulatedClick(event);
return;
@@ -205,25 +195,11 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
prefetchEventHandler()->handleEvent(event);
- if (isLinkClick(event) && treatLinkAsLiveForEventType(eventType(event))) {
+ if (isLinkClick(event) && isLiveLink()) {
handleClick(event);
prefetchEventHandler()->reset();
return;
}
-
- if (rendererIsEditable()) {
- // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
- // for the LiveWhenNotFocused editable link behavior
- if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() != RightButton && document().frame()) {
- setRootEditableElementForSelectionOnMouseDown(document().frame()->selection().rootEditableElement());
- m_wasShiftKeyDownOnMouseDown = toMouseEvent(event)->shiftKey();
- } else if (event->type() == EventTypeNames::mouseover) {
- // These are cleared on mouseover and not mouseout because their values are needed for drag events,
- // but drag events happen after mouse out events.
- clearRootEditableElementForSelectionOnMouseDown();
- m_wasShiftKeyDownOnMouseDown = false;
- }
- }
}
HTMLElement::defaultEventHandler(event);
@@ -231,32 +207,8 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
void HTMLAnchorElement::setActive(bool down)
{
- if (rendererIsEditable()) {
- EditableLinkBehavior editableLinkBehavior = EditableLinkDefaultBehavior;
- if (Settings* settings = document().settings())
- editableLinkBehavior = settings->editableLinkBehavior();
-
- switch (editableLinkBehavior) {
- default:
- case EditableLinkDefaultBehavior:
- case EditableLinkAlwaysLive:
- break;
-
- case EditableLinkNeverLive:
- return;
-
- // Don't set the link to be active if the current selection is in the same editable block as
- // this link
- case EditableLinkLiveWhenNotFocused:
- if (down && document().frame() && document().frame()->selection().rootEditableElement() == rootEditableElement())
- return;
- break;
-
- case EditableLinkOnlyLiveWithShiftKey:
- return;
- }
-
- }
+ if (rendererIsEditable())
+ return;
ContainerNode::setActive(down);
}
@@ -303,9 +255,13 @@ bool HTMLAnchorElement::isURLAttribute(const Attribute& attribute) const
return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLAnchorElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == hrefAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
bool HTMLAnchorElement::canStartSelection() const
{
- // FIXME: We probably want this same behavior in SVGAElement too
if (!isLink())
return HTMLElement::canStartSelection();
return rendererIsEditable();
@@ -349,7 +305,7 @@ String HTMLAnchorElement::input() const
void HTMLAnchorElement::setInput(const String& value)
{
- setHref(value);
+ setHref(AtomicString(value));
}
bool HTMLAnchorElement::hasRel(uint32_t relation) const
@@ -357,7 +313,7 @@ bool HTMLAnchorElement::hasRel(uint32_t relation) const
return m_linkRelations & relation;
}
-void HTMLAnchorElement::setRel(const String& value)
+void HTMLAnchorElement::setRel(const AtomicString& value)
{
m_linkRelations = 0;
SpaceSplitString newLinkRelations(value, true);
@@ -377,37 +333,34 @@ short HTMLAnchorElement::tabIndex() const
return Element::tabIndex();
}
-String HTMLAnchorElement::target() const
+AtomicString HTMLAnchorElement::target() const
{
return getAttribute(targetAttr);
}
-
-String HTMLAnchorElement::text()
-{
- return innerText();
-}
-
bool HTMLAnchorElement::isLiveLink() const
{
- return isLink() && treatLinkAsLiveForEventType(m_wasShiftKeyDownOnMouseDown ? MouseEventWithShiftKey : MouseEventWithoutShiftKey);
+ return isLink() && !rendererIsEditable();
}
void HTMLAnchorElement::sendPings(const KURL& destinationURL)
{
- if (!hasAttribute(pingAttr) || !document().settings() || !document().settings()->hyperlinkAuditingEnabled())
+ const AtomicString& pingValue = getAttribute(pingAttr);
+ if (pingValue.isNull() || !document().settings() || !document().settings()->hyperlinkAuditingEnabled())
return;
- SpaceSplitString pingURLs(getAttribute(pingAttr), false);
+ UseCounter::count(document(), UseCounter::HTMLAnchorElementPingAttribute);
+
+ SpaceSplitString pingURLs(pingValue, false);
for (unsigned i = 0; i < pingURLs.size(); i++)
- PingLoader::sendPing(document().frame(), document().completeURL(pingURLs[i]), destinationURL);
+ PingLoader::sendLinkAuditPing(document().frame(), document().completeURL(pingURLs[i]), destinationURL);
}
void HTMLAnchorElement::handleClick(Event* event)
{
event->setDefaultHandled();
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
@@ -427,10 +380,13 @@ void HTMLAnchorElement::handleClick(Event* event)
if (!hasRel(RelationNoReferrer)) {
String referrer = SecurityPolicy::generateReferrerHeader(document().referrerPolicy(), completedURL, document().outgoingReferrer());
if (!referrer.isEmpty())
- request.setHTTPReferrer(referrer);
+ request.setHTTPReferrer(Referrer(referrer, document().referrerPolicy()));
}
- frame->loader().client()->loadURLExternally(request, NavigationPolicyDownload, fastGetAttribute(downloadAttr));
+ bool isSameOrigin = completedURL.protocolIsData() || document().securityOrigin()->canRequest(completedURL);
+ const AtomicString& suggestedName = (isSameOrigin ? fastGetAttribute(downloadAttr) : nullAtom);
+
+ frame->loader().client()->loadURLExternally(request, NavigationPolicyDownload, suggestedName);
} else {
FrameLoadRequest frameRequest(&document(), request, target());
frameRequest.setTriggeringEvent(event);
@@ -440,43 +396,6 @@ void HTMLAnchorElement::handleClick(Event* event)
}
}
-HTMLAnchorElement::EventType HTMLAnchorElement::eventType(Event* event)
-{
- if (!event->isMouseEvent())
- return NonMouseEvent;
- return toMouseEvent(event)->shiftKey() ? MouseEventWithShiftKey : MouseEventWithoutShiftKey;
-}
-
-bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
-{
- if (!rendererIsEditable())
- return true;
-
- Settings* settings = document().settings();
- if (!settings)
- return true;
-
- switch (settings->editableLinkBehavior()) {
- case EditableLinkDefaultBehavior:
- case EditableLinkAlwaysLive:
- return true;
-
- case EditableLinkNeverLive:
- return false;
-
- // If the selection prior to clicking on this link resided in the same editable block as this link,
- // and the shift key isn't pressed, we don't want to follow the link.
- case EditableLinkLiveWhenNotFocused:
- return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && rootEditableElementForSelectionOnMouseDown() != rootEditableElement());
-
- case EditableLinkOnlyLiveWithShiftKey:
- return eventType == MouseEventWithShiftKey;
- }
-
- ASSERT_NOT_REACHED();
- return false;
-}
-
bool isEnterKeyKeydownEvent(Event* event)
{
return event->type() == EventTypeNames::keydown && event->isKeyboardEvent() && toKeyboardEvent(event)->keyIdentifier() == "Enter";
@@ -492,40 +411,6 @@ bool HTMLAnchorElement::willRespondToMouseClickEvents()
return isLink() || HTMLElement::willRespondToMouseClickEvents();
}
-typedef HashMap<const HTMLAnchorElement*, RefPtr<Element> > RootEditableElementMap;
-
-static RootEditableElementMap& rootEditableElementMap()
-{
- DEFINE_STATIC_LOCAL(RootEditableElementMap, map, ());
- return map;
-}
-
-Element* HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown() const
-{
- if (!m_hasRootEditableElementForSelectionOnMouseDown)
- return 0;
- return rootEditableElementMap().get(this);
-}
-
-void HTMLAnchorElement::clearRootEditableElementForSelectionOnMouseDown()
-{
- if (!m_hasRootEditableElementForSelectionOnMouseDown)
- return;
- rootEditableElementMap().remove(this);
- m_hasRootEditableElementForSelectionOnMouseDown = false;
-}
-
-void HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown(Element* element)
-{
- if (!element) {
- clearRootEditableElementForSelectionOnMouseDown();
- return;
- }
-
- rootEditableElementMap().set(this, element);
- m_hasRootEditableElementForSelectionOnMouseDown = true;
-}
-
HTMLAnchorElement::PrefetchEventHandler* HTMLAnchorElement::prefetchEventHandler()
{
if (!m_prefetchEventHandler)
@@ -667,7 +552,7 @@ bool HTMLAnchorElement::PrefetchEventHandler::shouldPrefetch(const KURL& url)
if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document.url(), url))
return false;
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
if (!frame)
return false;
@@ -698,4 +583,10 @@ bool HTMLAnchorElement::isInteractiveContent() const
return isLink();
}
+void HTMLAnchorElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_prefetchEventHandler);
+ HTMLElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h
index bfb0d634729..769c6d2a0ea 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.h
@@ -24,8 +24,9 @@
#ifndef HTMLAnchorElement_h
#define HTMLAnchorElement_h
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/DOMURLUtils.h"
+#include "core/dom/Document.h"
#include "core/html/HTMLElement.h"
#include "platform/LinkHash.h"
@@ -56,8 +57,7 @@ enum {
class HTMLAnchorElement : public HTMLElement, public DOMURLUtils {
public:
- static PassRefPtr<HTMLAnchorElement> create(Document&);
- static PassRefPtr<HTMLAnchorElement> create(const QualifiedName&, Document&);
+ static PassRefPtrWillBeRawPtr<HTMLAnchorElement> create(Document&);
virtual ~HTMLAnchorElement();
@@ -66,66 +66,52 @@ public:
const AtomicString& name() const;
- virtual KURL url() const OVERRIDE;
- virtual void setURL(const KURL&) OVERRIDE;
+ virtual KURL url() const OVERRIDE FINAL;
+ virtual void setURL(const KURL&) OVERRIDE FINAL;
- virtual String input() const OVERRIDE;
- virtual void setInput(const String&) OVERRIDE;
-
- String text();
+ virtual String input() const OVERRIDE FINAL;
+ virtual void setInput(const String&) OVERRIDE FINAL;
bool isLiveLink() const;
- virtual bool willRespondToMouseClickEvents() OVERRIDE;
+ virtual bool willRespondToMouseClickEvents() OVERRIDE FINAL;
bool hasRel(uint32_t relation) const;
- void setRel(const String&);
+ void setRel(const AtomicString&);
LinkHash visitedLinkHash() const;
void invalidateCachedVisitedLinkHash() { m_cachedVisitedLinkHash = 0; }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
HTMLAnchorElement(const QualifiedName&, Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE;
private:
- virtual bool supportsFocus() const;
- virtual bool isMouseFocusable() const;
+ virtual bool isMouseFocusable() const OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE FINAL;
virtual void setActive(bool = true) OVERRIDE FINAL;
- virtual void accessKeyAction(bool sendMouseEvents);
- virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual bool canStartSelection() const;
- virtual String target() const;
- virtual short tabIndex() const;
- virtual bool draggable() const;
- virtual bool isInteractiveContent() const OVERRIDE;
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE FINAL;
+ virtual bool isURLAttribute(const Attribute&) const OVERRIDE FINAL;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual bool canStartSelection() const OVERRIDE FINAL;
+ virtual short tabIndex() const OVERRIDE FINAL;
+ virtual bool draggable() const OVERRIDE FINAL;
+ virtual bool isInteractiveContent() const OVERRIDE FINAL;
void sendPings(const KURL& destinationURL);
-
+ AtomicString target() const;
void handleClick(Event*);
- enum EventType {
- MouseEventWithoutShiftKey,
- MouseEventWithShiftKey,
- NonMouseEvent,
- };
- static EventType eventType(Event*);
- bool treatLinkAsLiveForEventType(EventType) const;
-
- Element* rootEditableElementForSelectionOnMouseDown() const;
- void setRootEditableElementForSelectionOnMouseDown(Element*);
- void clearRootEditableElementForSelectionOnMouseDown();
-
class PrefetchEventHandler;
PrefetchEventHandler* prefetchEventHandler();
- bool m_hasRootEditableElementForSelectionOnMouseDown : 1;
- bool m_wasShiftKeyDownOnMouseDown : 1;
- uint32_t m_linkRelations : 30;
- OwnPtr<PrefetchEventHandler> m_prefetchEventHandler;
+ uint32_t m_linkRelations;
+ OwnPtrWillBeMember<PrefetchEventHandler> m_prefetchEventHandler;
mutable LinkHash m_cachedVisitedLinkHash;
};
@@ -141,23 +127,6 @@ inline LinkHash HTMLAnchorElement::visitedLinkHash() const
bool isEnterKeyKeydownEvent(Event*);
bool isLinkClick(Event*);
-inline bool isHTMLAnchorElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::aTag);
-}
-
-inline bool isHTMLAnchorElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::aTag);
-}
-
-inline bool isHTMLAnchorElement(const Element& element)
-{
- return element.hasTagName(HTMLNames::aTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLAnchorElement, hasTagName(HTMLNames::aTag));
-
} // namespace WebCore
#endif // HTMLAnchorElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl
index 525c307807f..63775c24b9b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAnchorElement.idl
@@ -31,8 +31,9 @@ interface HTMLAnchorElement : HTMLElement {
[Reflect] attribute DOMString target;
[Reflect] attribute DOMString type;
- readonly attribute DOMString text;
+ [ImplementedAs=textContent] attribute DOMString text;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
-// force rebuild: crbug.com/307023
HTMLAnchorElement implements URLUtils;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp
index 242e2ea2110..6dd43e9d911 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.cpp
@@ -24,14 +24,14 @@
#include "config.h"
#include "core/html/HTMLAppletElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLParamElement.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/rendering/RenderApplet.h"
#include "platform/Widget.h"
#include "platform/weborigin/KURL.h"
@@ -49,9 +49,9 @@ HTMLAppletElement::HTMLAppletElement(Document& document, bool createdByParser)
m_serviceType = "application/x-java-applet";
}
-PassRefPtr<HTMLAppletElement> HTMLAppletElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLAppletElement> HTMLAppletElement::create(Document& document, bool createdByParser)
{
- RefPtr<HTMLAppletElement> element = adoptRef(new HTMLAppletElement(document, createdByParser));
+ RefPtrWillBeRawPtr<HTMLAppletElement> element = adoptRefWillBeNoop(new HTMLAppletElement(document, createdByParser));
element->ensureUserAgentShadowRoot();
return element.release();
}
@@ -77,6 +77,11 @@ bool HTMLAppletElement::isURLAttribute(const Attribute& attribute) const
|| HTMLPlugInElement::isURLAttribute(attribute);
}
+bool HTMLAppletElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == codebaseAttr || HTMLPlugInElement::hasLegalLinkAttribute(name);
+}
+
bool HTMLAppletElement::rendererIsNeeded(const RenderStyle& style)
{
if (!fastHasAttribute(codeAttr) && !hasAuthorShadowRoot())
@@ -114,14 +119,9 @@ void HTMLAppletElement::updateWidgetInternal()
RenderEmbeddedObject* renderer = renderEmbeddedObject();
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
ASSERT(frame);
- LayoutUnit contentWidth = renderer->style()->width().isFixed() ? LayoutUnit(renderer->style()->width().value()) :
- renderer->width() - renderer->borderAndPaddingWidth();
- LayoutUnit contentHeight = renderer->style()->height().isFixed() ? LayoutUnit(renderer->style()->height().value()) :
- renderer->height() - renderer->borderAndPaddingHeight();
-
Vector<String> paramNames;
Vector<String> paramValues;
@@ -172,11 +172,7 @@ void HTMLAppletElement::updateWidgetInternal()
paramValues.append(mayScript.string());
}
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->hasTagName(paramTag))
- continue;
-
- HTMLParamElement* param = toHTMLParamElement(child);
+ for (HTMLParamElement* param = Traversal<HTMLParamElement>::firstChild(*this); param; param = Traversal<HTMLParamElement>::nextSibling(*param)) {
if (param->name().isEmpty())
continue;
@@ -186,7 +182,7 @@ void HTMLAppletElement::updateWidgetInternal()
RefPtr<Widget> widget;
if (frame->loader().allowPlugins(AboutToInstantiatePlugin))
- widget = frame->loader().client()->createJavaAppletWidget(roundedIntSize(LayoutSize(contentWidth, contentHeight)), this, baseURL, paramNames, paramValues);
+ widget = frame->loader().client()->createJavaAppletWidget(this, baseURL, paramNames, paramValues);
if (!widget) {
if (!renderer->showsUnavailablePluginIndicator())
@@ -194,7 +190,7 @@ void HTMLAppletElement::updateWidgetInternal()
return;
}
document().setContainsPlugins();
- renderer->setWidget(widget);
+ setWidget(widget);
}
bool HTMLAppletElement::canEmbedJava() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h
index 41c5193a81e..fbba123f567 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAppletElement.h
@@ -31,7 +31,7 @@ class KURL;
class HTMLAppletElement FINAL : public HTMLPlugInElement {
public:
- static PassRefPtr<HTMLAppletElement> create(Document&, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLAppletElement> create(Document&, bool createdByParser);
protected:
virtual RenderWidget* renderWidgetForJSBindings() const OVERRIDE;
@@ -41,6 +41,7 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp
index 73cd5fb7ac0..1606791ed62 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.cpp
@@ -22,17 +22,16 @@
#include "config.h"
#include "core/html/HTMLAreaElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLMapElement.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderView.h"
+#include "platform/LengthFunctions.h"
#include "platform/graphics/Path.h"
#include "platform/transforms/AffineTransform.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -45,10 +44,7 @@ inline HTMLAreaElement::HTMLAreaElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLAreaElement> HTMLAreaElement::create(Document& document)
-{
- return adoptRef(new HTMLAreaElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLAreaElement)
void HTMLAreaElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
@@ -102,7 +98,7 @@ Path HTMLAreaElement::computePath(RenderObject* obj) const
// Default should default to the size of the containing object.
LayoutSize size = m_lastSize;
if (m_shape == Default)
- size = obj->absoluteOutlineBounds().size();
+ size = obj->absoluteClippedOverflowRect().size();
Path p = getRegion(size);
float zoomFactor = obj->style()->effectiveZoom();
@@ -141,35 +137,34 @@ Path HTMLAreaElement::getRegion(const LayoutSize& size) const
}
Path path;
- RenderView* renderView = document().renderView();
switch (shape) {
case Poly:
if (m_coords.size() >= 6) {
int numPoints = m_coords.size() / 2;
- path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width, renderView), minimumValueForLength(m_coords[1], height, renderView)));
+ path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width).toFloat(), minimumValueForLength(m_coords[1], height).toFloat()));
for (int i = 1; i < numPoints; ++i)
- path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width, renderView), minimumValueForLength(m_coords[i * 2 + 1], height, renderView)));
+ path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width).toFloat(), minimumValueForLength(m_coords[i * 2 + 1], height).toFloat()));
path.closeSubpath();
}
break;
case Circle:
if (m_coords.size() >= 3) {
Length radius = m_coords[2];
- int r = min(minimumValueForLength(radius, width, renderView), minimumValueForLength(radius, height, renderView));
- path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width, renderView) - r, minimumValueForLength(m_coords[1], height, renderView) - r, 2 * r, 2 * r));
+ float r = std::min(minimumValueForLength(radius, width).toFloat(), minimumValueForLength(radius, height).toFloat());
+ path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width).toFloat() - r, minimumValueForLength(m_coords[1], height).toFloat() - r, 2 * r, 2 * r));
}
break;
case Rect:
if (m_coords.size() >= 4) {
- int x0 = minimumValueForLength(m_coords[0], width, renderView);
- int y0 = minimumValueForLength(m_coords[1], height, renderView);
- int x1 = minimumValueForLength(m_coords[2], width, renderView);
- int y1 = minimumValueForLength(m_coords[3], height, renderView);
+ float x0 = minimumValueForLength(m_coords[0], width).toFloat();
+ float y0 = minimumValueForLength(m_coords[1], height).toFloat();
+ float x1 = minimumValueForLength(m_coords[2], width).toFloat();
+ float y1 = minimumValueForLength(m_coords[3], height).toFloat();
path.addRect(FloatRect(x0, y0, x1 - x0, y1 - y0));
}
break;
case Default:
- path.addRect(FloatRect(0, 0, width, height));
+ path.addRect(FloatRect(0, 0, width.toFloat(), height.toFloat()));
break;
case Unknown:
break;
@@ -181,13 +176,13 @@ Path HTMLAreaElement::getRegion(const LayoutSize& size) const
HTMLImageElement* HTMLAreaElement::imageElement() const
{
Element* mapElement = parentElement();
- while (mapElement && !mapElement->hasTagName(mapTag))
+ while (mapElement && !isHTMLMapElement(*mapElement))
mapElement = mapElement->parentElement();
if (!mapElement)
return 0;
- return toHTMLMapElement(mapElement)->imageElement();
+ return toHTMLMapElement(*mapElement).imageElement();
}
bool HTMLAreaElement::isKeyboardFocusable() const
@@ -239,16 +234,4 @@ void HTMLAreaElement::updateFocusAppearance(bool restorePreviousSelection)
imageElement->updateFocusAppearance(restorePreviousSelection);
}
-bool HTMLAreaElement::supportsFocus() const
-{
- // If the AREA element was a link, it should support focus.
- // FIXME: This means that an AREA that is not a link cannot be made focusable through contenteditable or tabindex. Is it correct?
- return isLink();
-}
-
-String HTMLAreaElement::target() const
-{
- return getAttribute(targetAttr);
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h
index 35f34387d52..b68450ef951 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.h
@@ -34,7 +34,7 @@ class Path;
class HTMLAreaElement FINAL : public HTMLAnchorElement {
public:
- static PassRefPtr<HTMLAreaElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLAreaElement);
bool isDefault() const { return m_shape == Default; }
@@ -50,12 +50,10 @@ private:
explicit HTMLAreaElement(Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool supportsFocus() const;
- virtual String target() const;
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual bool isMouseFocusable() const;
+ virtual bool isMouseFocusable() const OVERRIDE;
virtual bool rendererIsFocusable() const OVERRIDE;
- virtual void updateFocusAppearance(bool /*restorePreviousSelection*/);
+ virtual void updateFocusAppearance(bool /*restorePreviousSelection*/) OVERRIDE;
virtual void setFocus(bool) OVERRIDE;
enum Shape { Default, Poly, Rect, Circle, Unknown };
@@ -68,18 +66,6 @@ private:
Shape m_shape;
};
-inline bool isHTMLAreaElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::areaTag);
-}
-
-inline bool isHTMLAreaElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::areaTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLAreaElement, hasTagName(HTMLNames::areaTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl
index 1ad7233a1f9..471e5835a6f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAreaElement.idl
@@ -27,5 +27,4 @@ interface HTMLAreaElement : HTMLElement {
[Reflect] attribute DOMString target;
};
-// force rebuild: crbug.com/307023
HTMLAreaElement implements URLUtils;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in b/chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in
index 4ae7745ae45..9494fad2a03 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAttributeNames.in
@@ -126,6 +126,7 @@ id
incremental
indeterminate
inputmode
+integrity
is
ismap
itemid
@@ -176,7 +177,6 @@ onautocomplete
onautocompleteerror
onbeforecopy
onbeforecut
-onbeforeload
onbeforepaste
onbeforeunload
onblur
@@ -211,6 +211,7 @@ oninvalid
onkeydown
onkeypress
onkeyup
+onlanguagechange
onload
onloadeddata
onloadedmetadata
@@ -252,6 +253,7 @@ onstorage
onsuspend
onsubmit
ontimeupdate
+ontoggle
ontouchstart
ontouchmove
ontouchend
@@ -282,7 +284,6 @@ pluginspage
pluginurl
ping
poster
-precision
preload
primary
profile
@@ -292,7 +293,6 @@ pseudo
readonly
rel
required
-reset-style-inheritance
results
rev
reversed
@@ -307,7 +307,6 @@ scoped
scrollamount
scrolldelay
scrolling
-seamless
select
selected
shape
@@ -316,8 +315,6 @@ sizes
sortable
sortdirection
span
-x-webkit-speech
-x-webkit-grammar
spellcheck
src
srcset
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp
index bdc0d9f3a04..07db2563fc3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.cpp
@@ -26,29 +26,32 @@
#include "config.h"
#include "core/html/HTMLAudioElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/dom/shadow/ShadowRoot.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLAudioElement::HTMLAudioElement(Document& document, bool createdByParser)
- : HTMLMediaElement(audioTag, document, createdByParser)
+HTMLAudioElement::HTMLAudioElement(Document& document)
+ : HTMLMediaElement(audioTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLAudioElement> HTMLAudioElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLAudioElement> HTMLAudioElement::create(Document& document)
{
- RefPtr<HTMLAudioElement> audioElement(adoptRef(new HTMLAudioElement(document, createdByParser)));
- audioElement->suspendIfNeeded();
- return audioElement.release();
+ RefPtrWillBeRawPtr<HTMLAudioElement> audio = adoptRefWillBeNoop(new HTMLAudioElement(document));
+ audio->ensureUserAgentShadowRoot();
+ audio->suspendIfNeeded();
+ return audio.release();
}
-PassRefPtr<HTMLAudioElement> HTMLAudioElement::createForJSConstructor(Document& document, const AtomicString& src)
+PassRefPtrWillBeRawPtr<HTMLAudioElement> HTMLAudioElement::createForJSConstructor(Document& document, const AtomicString& src)
{
- RefPtr<HTMLAudioElement> audio = adoptRef(new HTMLAudioElement(document, false));
- audio->setPreload("auto");
+ RefPtrWillBeRawPtr<HTMLAudioElement> audio = adoptRefWillBeNoop(new HTMLAudioElement(document));
+ audio->ensureUserAgentShadowRoot();
+ audio->setPreload(AtomicString("auto", AtomicString::ConstructFromLiteral));
if (!src.isNull())
audio->setSrc(src);
audio->suspendIfNeeded();
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h
index c69a3057630..9969491d803 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.h
@@ -35,13 +35,11 @@ class Document;
class HTMLAudioElement FINAL : public HTMLMediaElement {
public:
- static PassRefPtr<HTMLAudioElement> create(Document&, bool);
- static PassRefPtr<HTMLAudioElement> createForJSConstructor(Document&, const AtomicString& src);
+ static PassRefPtrWillBeRawPtr<HTMLAudioElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLAudioElement> createForJSConstructor(Document&, const AtomicString& src);
private:
- HTMLAudioElement(Document&, bool);
-
- virtual bool isVideo() const OVERRIDE { return false; }
+ HTMLAudioElement(Document&);
};
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl
index ffb4769c23f..f1e3629d65e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLAudioElement.idl
@@ -25,6 +25,7 @@
[
RuntimeEnabled=Media,
- NamedConstructor=Audio([Default=NullString] optional DOMString src)
+ NamedConstructor=Audio(optional DOMString src = null),
+ ConstructorCallWith=Document
] interface HTMLAudioElement : HTMLMediaElement {
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h
index b5050a6ddee..52db54e9369 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBDIElement.h
@@ -27,13 +27,10 @@ namespace WebCore {
class HTMLBDIElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLBDIElement> create(Document& document)
- {
- return adoptRef(new HTMLBDIElement(document));
- }
+ DECLARE_NODE_FACTORY(HTMLBDIElement);
private:
- explicit HTMLBDIElement(Document& document)
+ inline explicit HTMLBDIElement(Document& document)
: HTMLElement(HTMLNames::bdiTag, document)
{
// FIXME: Rename setSelfOrAncestorHasDirAutoAttribute to reflect the fact bdi also uses this flag.
@@ -41,6 +38,8 @@ private:
}
};
+DEFINE_NODE_FACTORY(HTMLBDIElement)
+
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp
index 19b3aa9dab9..b04ba6edef5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.cpp
@@ -23,25 +23,22 @@
#include "config.h"
#include "core/html/HTMLBRElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/rendering/RenderBR.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLBRElement::HTMLBRElement(Document& document)
+inline HTMLBRElement::HTMLBRElement(Document& document)
: HTMLElement(brTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLBRElement> HTMLBRElement::create(Document& document)
-{
- return adoptRef(new HTMLBRElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLBRElement)
bool HTMLBRElement::isPresentationAttribute(const QualifiedName& name) const
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h
index 0188c71bd41..01af5657750 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBRElement.h
@@ -30,9 +30,9 @@ namespace WebCore {
class HTMLBRElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLBRElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLBRElement);
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
private:
explicit HTMLBRElement(Document&);
@@ -40,7 +40,7 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp
index 6ec6654c17f..de1075c7907 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.cpp
@@ -23,11 +23,11 @@
#include "config.h"
#include "core/html/HTMLBaseElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
-#include "core/fetch/TextResourceDecoder.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/html/parser/TextResourceDecoder.h"
namespace WebCore {
@@ -39,10 +39,7 @@ inline HTMLBaseElement::HTMLBaseElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLBaseElement> HTMLBaseElement::create(Document& document)
-{
- return adoptRef(new HTMLBaseElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLBaseElement)
void HTMLBaseElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
@@ -72,11 +69,6 @@ bool HTMLBaseElement::isURLAttribute(const Attribute& attribute) const
return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
}
-String HTMLBaseElement::target() const
-{
- return fastGetAttribute(targetAttr);
-}
-
KURL HTMLBaseElement::href() const
{
// This does not use the getURLAttribute function because that will resolve relative to the document's base URL;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h
index 39c8bfeadff..cefdc19f3f0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBaseElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLBaseElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLBaseElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLBaseElement);
KURL href() const;
void setHref(const AtomicString&);
@@ -37,7 +37,6 @@ public:
private:
explicit HTMLBaseElement(Document&);
- virtual String target() const;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
index 44a1572fec5..624dec6126e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.cpp
@@ -24,33 +24,30 @@
#include "config.h"
#include "core/html/HTMLBodyElement.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSImageValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Attribute.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
+#include "core/rendering/RenderBox.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLBodyElement::HTMLBodyElement(Document& document)
+inline HTMLBodyElement::HTMLBodyElement(Document& document)
: HTMLElement(bodyTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLBodyElement> HTMLBodyElement::create(Document& document)
-{
- return adoptRef(new HTMLBodyElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLBodyElement)
HTMLBodyElement::~HTMLBodyElement()
{
@@ -68,8 +65,9 @@ void HTMLBodyElement::collectStyleForPresentationAttribute(const QualifiedName&
if (name == backgroundAttr) {
String url = stripLeadingAndTrailingHTMLSpaces(value);
if (!url.isEmpty()) {
- RefPtr<CSSImageValue> imageValue = CSSImageValue::create(document().completeURL(url).string());
+ RefPtrWillBeRawPtr<CSSImageValue> imageValue = CSSImageValue::create(url, document().completeURL(url));
imageValue->setInitiator(localName());
+ imageValue->setReferrer(Referrer(document().outgoingReferrer(), document().referrerPolicy()));
style->setProperty(CSSProperty(CSSPropertyBackgroundImage, imageValue.release()));
}
} else if (name == marginwidthAttr || name == leftmarginAttr) {
@@ -101,7 +99,7 @@ void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicStri
document().textLinkColors().resetActiveLinkColor();
} else {
RGBA32 color;
- if (CSSParser::parseColor(color, value, !document().inQuirksMode())) {
+ if (BisonCSSParser::parseColor(color, value, !document().inQuirksMode())) {
if (name == linkAttr)
document().textLinkColors().setLinkColor(color);
else if (name == vlinkAttr)
@@ -111,45 +109,45 @@ void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicStri
}
}
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
} else if (name == onloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onbeforeunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpagehideAttr)
- document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpageshowAttr)
- document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpopstateAttr)
- document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onblurAttr)
- document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onerrorAttr)
- document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onfocusAttr)
- document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value));
-#if ENABLE(ORIENTATION_EVENTS)
- else if (name == onorientationchangeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value));
-#endif
+ document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ else if (RuntimeEnabledFeatures::orientationEventEnabled() && name == onorientationchangeAttr)
+ document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onhashchangeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onmessageAttr)
- document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onresizeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onscrollAttr)
- document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onselectionchangeAttr)
- document().setAttributeEventListener(EventTypeNames::selectionchange, createAttributeEventListener(document().frame(), name, value));
+ document().setAttributeEventListener(EventTypeNames::selectionchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onstorageAttr)
- document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == ononlineAttr)
- document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onofflineAttr)
- document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ else if (name == onlanguagechangeAttr)
+ document().setWindowAttributeEventListener(EventTypeNames::languagechange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else
HTMLElement::parseAttribute(name, value);
}
@@ -157,22 +155,24 @@ void HTMLBodyElement::parseAttribute(const QualifiedName& name, const AtomicStri
Node::InsertionNotificationRequest HTMLBodyElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
- if (insertionPoint->inDocument()) {
- // FIXME: It's surprising this is web compatible since it means a marginwidth
- // and marginheight attribute can magically appear on the <body> of all documents
- // embedded through <iframe> or <frame>.
- Element* ownerElement = document().ownerElement();
- if (ownerElement && ownerElement->isFrameElementBase()) {
- HTMLFrameElementBase* ownerFrameElement = toHTMLFrameElementBase(ownerElement);
- int marginWidth = ownerFrameElement->marginWidth();
- if (marginWidth != -1)
- setIntegralAttribute(marginwidthAttr, marginWidth);
- int marginHeight = ownerFrameElement->marginHeight();
- if (marginHeight != -1)
- setIntegralAttribute(marginheightAttr, marginHeight);
- }
- }
- return InsertionDone;
+ return InsertionShouldCallDidNotifySubtreeInsertions;
+}
+
+void HTMLBodyElement::didNotifySubtreeInsertionsToDocument()
+{
+ // FIXME: It's surprising this is web compatible since it means a
+ // marginwidth and marginheight attribute can magically appear on the <body>
+ // of all documents embedded through <iframe> or <frame>.
+ Element* ownerElement = document().ownerElement();
+ if (!isHTMLFrameElementBase(ownerElement))
+ return;
+ HTMLFrameElementBase& ownerFrameElement = toHTMLFrameElementBase(*ownerElement);
+ int marginWidth = ownerFrameElement.marginWidth();
+ int marginHeight = ownerFrameElement.marginHeight();
+ if (marginWidth != -1)
+ setIntegralAttribute(marginwidthAttr, marginWidth);
+ if (marginHeight != -1)
+ setIntegralAttribute(marginheightAttr, marginHeight);
}
bool HTMLBodyElement::isURLAttribute(const Attribute& attribute) const
@@ -180,6 +180,16 @@ bool HTMLBodyElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == backgroundAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLBodyElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == backgroundAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLBodyElement::subResourceAttributeName() const
+{
+ return backgroundAttr;
+}
+
bool HTMLBodyElement::supportsFocus() const
{
// This override is needed because the inherited method bails if the parent is editable.
@@ -189,7 +199,7 @@ bool HTMLBodyElement::supportsFocus() const
static int adjustForZoom(int value, Document* document)
{
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
float zoomFactor = frame->pageZoomFactor();
if (zoomFactor == 1)
return value;
@@ -199,17 +209,28 @@ static int adjustForZoom(int value, Document* document)
return static_cast<int>(value / zoomFactor);
}
-// FIXME: There are cases where body.scrollLeft is allowed to return
-// non-zero values in both quirks and strict mode. It happens when
-// <body> has an overflow that is not the Frame overflow.
-// http://dev.w3.org/csswg/cssom-view/#dom-element-scrollleft
-// http://code.google.com/p/chromium/issues/detail?id=312435
+// Blink, Gecko and Presto's quirks mode implementations of overflow set to the
+// body element differ from IE's: the formers can create a scrollable area for the
+// body element that is not the same as the root elements's one. On IE's quirks mode
+// though, as body is the root element, body's and the root element's scrollable areas,
+// if any, are the same.
+// In order words, a <body> will only have an overflow clip (that differs from
+// documentElement's) if both html and body nodes have its overflow set to either hidden,
+// auto or scroll.
+// That said, Blink's {set}scroll{Top,Left} behaviors match Gecko's: even if there is a non-overflown
+// scrollable area, scrolling should not get propagated to the viewport in neither strict
+// or quirks modes.
int HTMLBodyElement::scrollLeft()
{
Document& document = this->document();
document.updateLayoutIgnorePendingStylesheets();
if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
+ RenderBox* render = renderBox();
+ if (!render)
+ return 0;
+ if (render->hasOverflowClip())
+ return adjustForAbsoluteZoom(render->scrollLeft(), render);
if (!document.inQuirksMode())
return 0;
}
@@ -224,11 +245,19 @@ void HTMLBodyElement::setScrollLeft(int scrollLeft)
document.updateLayoutIgnorePendingStylesheets();
if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
+ RenderBox* render = renderBox();
+ if (!render)
+ return;
+ if (render->hasOverflowClip()) {
+ // FIXME: Investigate how are other browsers casting to int (rounding, ceiling, ...).
+ render->setScrollLeft(static_cast<int>(scrollLeft * render->style()->effectiveZoom()));
+ return;
+ }
if (!document.inQuirksMode())
return;
}
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
if (!frame)
return;
FrameView* view = frame->view();
@@ -243,6 +272,11 @@ int HTMLBodyElement::scrollTop()
document.updateLayoutIgnorePendingStylesheets();
if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
+ RenderBox* render = renderBox();
+ if (!render)
+ return 0;
+ if (render->hasOverflowClip())
+ return adjustForAbsoluteZoom(render->scrollTop(), render);
if (!document.inQuirksMode())
return 0;
}
@@ -257,11 +291,19 @@ void HTMLBodyElement::setScrollTop(int scrollTop)
document.updateLayoutIgnorePendingStylesheets();
if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) {
+ RenderBox* render = renderBox();
+ if (!render)
+ return;
+ if (render->hasOverflowClip()) {
+ // FIXME: Investigate how are other browsers casting to int (rounding, ceiling, ...).
+ render->setScrollTop(static_cast<int>(scrollTop * render->style()->effectiveZoom()));
+ return;
+ }
if (!document.inQuirksMode())
return;
}
- Frame* frame = document.frame();
+ LocalFrame* frame = document.frame();
if (!frame)
return;
FrameView* view = frame->view();
@@ -288,11 +330,4 @@ int HTMLBodyElement::scrollWidth()
return view ? adjustForZoom(view->contentsWidth(), &document) : 0;
}
-void HTMLBodyElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h
index d7a5c45da0a..7dd1f21c09b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.h
@@ -24,6 +24,7 @@
#ifndef HTMLBodyElement_h
#define HTMLBodyElement_h
+#include "core/dom/Document.h"
#include "core/html/HTMLElement.h"
namespace WebCore {
@@ -32,18 +33,16 @@ class Document;
class HTMLBodyElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLBodyElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLBodyElement);
virtual ~HTMLBodyElement();
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(scroll);
-
-#if ENABLE(ORIENTATION_EVENTS)
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange);
-#endif
private:
explicit HTMLBodyElement(Document&);
@@ -53,25 +52,24 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
+ virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
- virtual bool supportsFocus() const;
+ virtual bool supportsFocus() const OVERRIDE;
- virtual int scrollLeft();
- virtual void setScrollLeft(int scrollLeft);
+ virtual int scrollLeft() OVERRIDE;
+ virtual void setScrollLeft(int) OVERRIDE;
- virtual int scrollTop();
- virtual void setScrollTop(int scrollTop);
+ virtual int scrollTop() OVERRIDE;
+ virtual void setScrollTop(int) OVERRIDE;
- virtual int scrollHeight();
- virtual int scrollWidth();
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual int scrollHeight() OVERRIDE;
+ virtual int scrollWidth() OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLBodyElement, hasTagName(HTMLNames::bodyTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
index 139b34a52a1..6f454c6aeef 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLBodyElement.idl
@@ -26,13 +26,14 @@ interface HTMLBodyElement : HTMLElement {
[Reflect, TreatNullAs=NullString] attribute DOMString text;
[Reflect, TreatNullAs=NullString] attribute DOMString vLink;
- [Conditional=ORIENTATION_EVENTS] attribute EventHandler onorientationchange;
+ [RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange;
// Overrides of GlobalEventHandler attributes
attribute EventHandler onblur;
attribute EventHandler onerror;
attribute EventHandler onfocus;
attribute EventHandler onload;
+ attribute EventHandler onresize;
attribute EventHandler onscroll;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
index 4b3c235fdab..55f7defa1a4 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.cpp
@@ -26,10 +26,9 @@
#include "config.h"
#include "core/html/HTMLButtonElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/events/KeyboardEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLFormElement.h"
#include "core/rendering/RenderButton.h"
@@ -47,9 +46,9 @@ inline HTMLButtonElement::HTMLButtonElement(Document& document, HTMLFormElement*
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLButtonElement> HTMLButtonElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLButtonElement> HTMLButtonElement::create(Document& document, HTMLFormElement* form)
{
- return adoptRef(new HTMLButtonElement(document, form));
+ return adoptRefWillBeNoop(new HTMLButtonElement(document, form));
}
void HTMLButtonElement::setType(const AtomicString& type)
@@ -209,4 +208,9 @@ bool HTMLButtonElement::isInteractiveContent() const
return true;
}
+bool HTMLButtonElement::supportsAutofocus() const
+{
+ return true;
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h
index 5032c386975..110e411f480 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLButtonElement FINAL : public HTMLFormControlElement {
public:
- static PassRefPtr<HTMLButtonElement> create(Document&, HTMLFormElement*);
+ static PassRefPtrWillBeRawPtr<HTMLButtonElement> create(Document&, HTMLFormElement*);
void setType(const AtomicString&);
@@ -43,34 +43,35 @@ private:
enum Type { SUBMIT, RESET, BUTTON };
- virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
// HTMLFormControlElement always creates one, but buttons don't need it.
virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE { return false; }
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual bool appendFormData(FormDataList&, bool);
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
- virtual bool isEnumeratable() const { return true; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool supportLabels() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
+ virtual bool supportsAutofocus() const OVERRIDE;
virtual bool canBeSuccessfulSubmitButton() const OVERRIDE;
- virtual bool isActivatedSubmit() const;
- virtual void setActivatedSubmit(bool flag);
+ virtual bool isActivatedSubmit() const OVERRIDE;
+ virtual void setActivatedSubmit(bool flag) OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual bool canStartSelection() const { return false; }
+ virtual bool canStartSelection() const OVERRIDE { return false; }
- virtual bool isOptionalFormControl() const { return true; }
- virtual bool recalcWillValidate() const;
+ virtual bool isOptionalFormControl() const OVERRIDE { return true; }
+ virtual bool recalcWillValidate() const OVERRIDE;
Type m_type;
bool m_isActivatedSubmit;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl
index aa402325ce4..d92dcd166a6 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLButtonElement.idl
@@ -22,7 +22,7 @@ interface HTMLButtonElement : HTMLElement {
[Reflect] attribute boolean autofocus;
[Reflect] attribute boolean disabled;
[ImplementedAs=formOwner] readonly attribute HTMLFormElement form;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString formAction;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString formAction;
attribute DOMString formEnctype;
attribute DOMString formMethod;
[Reflect] attribute boolean formNoValidate;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index ba778484dbc..4d6c77edb14 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -28,29 +28,32 @@
#include "config.h"
#include "core/html/HTMLCanvasElement.h"
-#include <math.h>
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptController.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/html/ImageData.h"
#include "core/html/canvas/Canvas2DContextAttributes.h"
#include "core/html/canvas/CanvasRenderingContext2D.h"
#include "core/html/canvas/WebGLContextAttributes.h"
+#include "core/html/canvas/WebGLContextEvent.h"
#include "core/html/canvas/WebGLRenderingContext.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderHTMLCanvas.h"
#include "platform/MIMETypeRegistry.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/graphics/Canvas2DImageBufferSurface.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/UnacceleratedImageBufferSurface.h"
#include "platform/graphics/gpu/WebGLImageBufferSurface.h"
+#include "platform/transforms/AffineTransform.h"
#include "public/platform/Platform.h"
+#include <math.h>
+#include <v8.h>
namespace WebCore {
@@ -68,10 +71,12 @@ static const int MaxCanvasArea = 32768 * 8192; // Maximum canvas area in CSS pix
//In Skia, we will also limit width/height to 32767.
static const int MaxSkiaDim = 32767; // Maximum width/height in CSS pixels.
-HTMLCanvasElement::HTMLCanvasElement(Document& document)
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver);
+
+inline HTMLCanvasElement::HTMLCanvasElement(Document& document)
: HTMLElement(canvasTag, document)
+ , DocumentVisibilityObserver(document)
, m_size(DefaultWidth, DefaultHeight)
- , m_rendererIsCanvas(false)
, m_ignoreReset(false)
, m_accelerationDisabled(false)
, m_externallyAllocatedMemory(0)
@@ -82,19 +87,19 @@ HTMLCanvasElement::HTMLCanvasElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLCanvasElement> HTMLCanvasElement::create(Document& document)
-{
- return adoptRef(new HTMLCanvasElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLCanvasElement)
HTMLCanvasElement::~HTMLCanvasElement()
{
- setExternallyAllocatedMemory(0);
- HashSet<CanvasObserver*>::iterator end = m_observers.end();
- for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory);
+#if !ENABLE(OILPAN)
+ HashSet<RawPtr<CanvasObserver> >::iterator end = m_observers.end();
+ for (HashSet<RawPtr<CanvasObserver> >::iterator it = m_observers.begin(); it != end; ++it)
(*it)->canvasDestroyed(this);
-
- m_context.clear(); // Ensure this goes away before the ImageBuffer.
+ // Ensure these go away before the ImageBuffer.
+ m_contextStateSaver.clear();
+ m_context.clear();
+#endif
}
void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -106,13 +111,9 @@ void HTMLCanvasElement::parseAttribute(const QualifiedName& name, const AtomicSt
RenderObject* HTMLCanvasElement::createRenderer(RenderStyle* style)
{
- Frame* frame = document().frame();
- if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript)) {
- m_rendererIsCanvas = true;
+ LocalFrame* frame = document().frame();
+ if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript))
return new RenderHTMLCanvas(this);
- }
-
- m_rendererIsCanvas = false;
return HTMLElement::createRenderer(style);
}
@@ -166,38 +167,33 @@ CanvasRenderingContext* HTMLCanvasElement::getContext(const String& type, Canvas
if (!m_context) {
blink::Platform::current()->histogramEnumeration("Canvas.ContextType", Context2d, ContextTypeCount);
m_context = CanvasRenderingContext2D::create(this, static_cast<Canvas2DContextAttributes*>(attrs), document().inQuirksMode());
- if (m_context)
- scheduleLayerUpdate();
+ setNeedsCompositingUpdate();
}
return m_context.get();
}
- Settings* settings = document().settings();
- if (settings && settings->webGLEnabled()) {
- // Accept the legacy "webkit-3d" name as well as the provisional "experimental-webgl" name.
- // Now that WebGL is ratified, we will also accept "webgl" as the context name in Chrome.
- ContextType contextType;
- bool is3dContext = true;
- if (type == "webkit-3d")
- contextType = ContextWebkit3d;
- else if (type == "experimental-webgl")
- contextType = ContextExperimentalWebgl;
- else if (type == "webgl")
- contextType = ContextWebgl;
- else
- is3dContext = false;
-
- if (is3dContext) {
- if (m_context && !m_context->is3d())
- return 0;
- if (!m_context) {
- blink::Platform::current()->histogramEnumeration("Canvas.ContextType", contextType, ContextTypeCount);
- m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs));
- if (m_context)
- scheduleLayerUpdate();
- }
- return m_context.get();
+ // Accept the the provisional "experimental-webgl" or official "webgl" context ID.
+ ContextType contextType;
+ bool is3dContext = true;
+ if (type == "experimental-webgl")
+ contextType = ContextExperimentalWebgl;
+ else if (type == "webgl")
+ contextType = ContextWebgl;
+ else
+ is3dContext = false;
+
+ if (is3dContext) {
+ if (m_context && !m_context->is3d()) {
+ dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Canvas has an existing, non-WebGL context"));
+ return 0;
}
+ if (!m_context) {
+ blink::Platform::current()->histogramEnumeration("Canvas.ContextType", contextType, ContextTypeCount);
+ m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs));
+ setNeedsCompositingUpdate();
+ updateExternallyAllocatedMemory();
+ }
+ return m_context.get();
}
return 0;
}
@@ -214,7 +210,7 @@ void HTMLCanvasElement::didDraw(const FloatRect& rect)
return;
m_dirtyRect.unite(r);
- ro->repaintRectangle(enclosingIntRect(m_dirtyRect));
+ ro->invalidatePaintRectangle(enclosingIntRect(m_dirtyRect));
}
notifyObserversCanvasChanged(rect);
@@ -222,8 +218,8 @@ void HTMLCanvasElement::didDraw(const FloatRect& rect)
void HTMLCanvasElement::notifyObserversCanvasChanged(const FloatRect& rect)
{
- HashSet<CanvasObserver*>::iterator end = m_observers.end();
- for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator end = m_observers.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator it = m_observers.begin(); it != end; ++it)
(*it)->canvasChanged(this, rect);
}
@@ -269,19 +265,19 @@ void HTMLCanvasElement::reset()
toWebGLRenderingContext(m_context.get())->reshape(width(), height());
if (RenderObject* renderer = this->renderer()) {
- if (m_rendererIsCanvas) {
+ if (renderer->isCanvas()) {
if (oldSize != size()) {
toRenderHTMLCanvas(renderer)->canvasSizeChanged();
if (renderBox() && renderBox()->hasAcceleratedCompositing())
renderBox()->contentChanged(CanvasChanged);
}
if (hadImageBuffer)
- renderer->repaint();
+ renderer->paintInvalidationForWholeRenderer();
}
}
- HashSet<CanvasObserver*>::iterator end = m_observers.end();
- for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator end = m_observers.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> >::iterator it = m_observers.begin(); it != end; ++it)
(*it)->canvasResized(this);
}
@@ -299,7 +295,7 @@ bool HTMLCanvasElement::paintsIntoCanvasBuffer() const
}
-void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r, bool useLowQualityScale)
+void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r)
{
// Clear the dirty rect
m_dirtyRect = FloatRect();
@@ -318,10 +314,14 @@ void HTMLCanvasElement::paint(GraphicsContext* context, const LayoutRect& r, boo
if (imageBuffer) {
CompositeOperator compositeOperator = !m_context || m_context->hasAlpha() ? CompositeSourceOver : CompositeCopy;
if (m_presentedImage)
- context->drawImage(m_presentedImage.get(), pixelSnappedIntRect(r), compositeOperator, DoNotRespectImageOrientation, useLowQualityScale);
+ context->drawImage(m_presentedImage.get(), pixelSnappedIntRect(r), compositeOperator, DoNotRespectImageOrientation);
else
- context->drawImageBuffer(imageBuffer, pixelSnappedIntRect(r), compositeOperator, blink::WebBlendModeNormal, useLowQualityScale);
+ context->drawImageBuffer(imageBuffer, pixelSnappedIntRect(r), 0, compositeOperator);
}
+ } else {
+ // When alpha is false, we should draw to opaque black.
+ if (m_context && !m_context->hasAlpha())
+ context->fillRect(FloatRect(r), Color(0, 0, 0));
}
if (is3D())
@@ -338,22 +338,28 @@ void HTMLCanvasElement::makePresentationCopy()
if (!m_presentedImage) {
// The buffer contains the last presented data, so save a copy of it.
m_presentedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
+ updateExternallyAllocatedMemory();
}
}
void HTMLCanvasElement::clearPresentationCopy()
{
m_presentedImage.clear();
+ updateExternallyAllocatedMemory();
}
void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
{
m_size = size;
m_didFailToCreateImageBuffer = false;
- m_contextStateSaver.clear();
- m_imageBuffer.clear();
- setExternallyAllocatedMemory(0);
+ discardImageBuffer();
clearCopiedImage();
+ if (m_context && m_context->is2d()) {
+ CanvasRenderingContext2D* context2d = toCanvasRenderingContext2D(m_context.get());
+ if (context2d->isContextLost()) {
+ context2d->restoreContext();
+ }
+ }
}
String HTMLCanvasElement::toEncodingMimeType(const String& mimeType)
@@ -367,34 +373,47 @@ String HTMLCanvasElement::toEncodingMimeType(const String& mimeType)
return lowercaseMimeType;
}
-String HTMLCanvasElement::toDataURL(const String& mimeType, const double* quality, ExceptionState& exceptionState)
+const AtomicString HTMLCanvasElement::imageSourceURL() const
{
- if (!m_originClean) {
- exceptionState.throwSecurityError("Tainted canvases may not be exported.");
- return String();
- }
+ return AtomicString(toDataURLInternal("image/png", 0, true));
+}
+String HTMLCanvasElement::toDataURLInternal(const String& mimeType, const double* quality, bool isSaving) const
+{
if (m_size.isEmpty() || !buffer())
return String("data:,");
String encodingMimeType = toEncodingMimeType(mimeType);
// Try to get ImageData first, as that may avoid lossy conversions.
- RefPtr<ImageData> imageData = getImageData();
+ RefPtrWillBeRawPtr<ImageData> imageData = getImageData();
if (imageData)
return ImageDataToDataURL(ImageDataBuffer(imageData->size(), imageData->data()), encodingMimeType, quality);
- if (m_context)
+ if (m_context && m_context->is3d()) {
+ toWebGLRenderingContext(m_context.get())->setSavingImage(isSaving);
m_context->paintRenderingResultsToCanvas();
+ toWebGLRenderingContext(m_context.get())->setSavingImage(false);
+ }
return buffer()->toDataURL(encodingMimeType, quality);
}
-PassRefPtr<ImageData> HTMLCanvasElement::getImageData()
+String HTMLCanvasElement::toDataURL(const String& mimeType, const double* quality, ExceptionState& exceptionState) const
+{
+ if (!m_originClean) {
+ exceptionState.throwSecurityError("Tainted canvases may not be exported.");
+ return String();
+ }
+
+ return toDataURLInternal(mimeType, quality);
+}
+
+PassRefPtrWillBeRawPtr<ImageData> HTMLCanvasElement::getImageData() const
{
if (!m_context || !m_context->is3d())
- return 0;
+ return nullptr;
return toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImageData();
}
@@ -446,7 +465,15 @@ PassOwnPtr<ImageBufferSurface> HTMLCanvasElement::createImageBufferSurface(const
void HTMLCanvasElement::createImageBuffer()
{
+ createImageBufferInternal();
+ if (m_didFailToCreateImageBuffer && m_context && m_context->is2d())
+ toCanvasRenderingContext2D(m_context.get())->loseContext();
+}
+
+void HTMLCanvasElement::createImageBufferInternal()
+{
ASSERT(!m_imageBuffer);
+ ASSERT(!m_contextStateSaver);
m_didFailToCreateImageBuffer = true;
m_didClearImageBuffer = true;
@@ -465,20 +492,23 @@ void HTMLCanvasElement::createImageBuffer()
OwnPtr<ImageBufferSurface> surface = createImageBufferSurface(deviceSize, &msaaSampleCount);
if (!surface->isValid())
return;
+
m_imageBuffer = ImageBuffer::create(surface.release());
+ m_imageBuffer->setClient(this);
m_didFailToCreateImageBuffer = false;
- setExternallyAllocatedMemory(4 * width() * height());
+ updateExternallyAllocatedMemory();
if (is3D()) {
// Early out for WebGL canvases
- m_contextStateSaver.clear();
return;
}
+ m_imageBuffer->setClient(this);
m_imageBuffer->context()->setShouldClampToSourceRect(false);
- m_imageBuffer->context()->setImageInterpolationQuality(DefaultInterpolationQuality);
+ m_imageBuffer->context()->disableAntialiasingOptimizationForHairlineImages();
+ m_imageBuffer->context()->setImageInterpolationQuality(CanvasDefaultInterpolationQuality);
// Enabling MSAA overrides a request to disable antialiasing. This is true regardless of whether the
// rendering mode is accelerated or not. For consistency, we don't want to apply AA in accelerated
// canvases but not in unaccelerated canvases.
@@ -488,15 +518,51 @@ void HTMLCanvasElement::createImageBuffer()
// See CanvasRenderingContext2D::State::State() for more information.
m_imageBuffer->context()->setMiterLimit(10);
m_imageBuffer->context()->setStrokeThickness(1);
+#if ASSERT_ENABLED
+ m_imageBuffer->context()->disableDestructionChecks(); // 2D canvas is allowed to leave context in an unfinalized state.
+#endif
m_contextStateSaver = adoptPtr(new GraphicsContextStateSaver(*m_imageBuffer->context()));
- // Recalculate compositing requirements if acceleration state changed.
if (m_context)
- scheduleLayerUpdate();
+ setNeedsCompositingUpdate();
+}
+
+void HTMLCanvasElement::notifySurfaceInvalid()
+{
+ if (m_context && m_context->is2d()) {
+ CanvasRenderingContext2D* context2d = toCanvasRenderingContext2D(m_context.get());
+ context2d->loseContext();
+ }
+}
+
+void HTMLCanvasElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_observers);
+ visitor->trace(m_context);
+ DocumentVisibilityObserver::trace(visitor);
+ HTMLElement::trace(visitor);
}
-void HTMLCanvasElement::setExternallyAllocatedMemory(intptr_t externallyAllocatedMemory)
+void HTMLCanvasElement::updateExternallyAllocatedMemory() const
{
+ int bufferCount = 0;
+ if (m_imageBuffer)
+ bufferCount++;
+ if (is3D())
+ bufferCount += 2;
+ if (m_copiedImage)
+ bufferCount++;
+ if (m_presentedImage)
+ bufferCount++;
+
+ Checked<intptr_t, RecordOverflow> checkedExternallyAllocatedMemory = 4 * bufferCount;
+ checkedExternallyAllocatedMemory *= width();
+ checkedExternallyAllocatedMemory *= height();
+ intptr_t externallyAllocatedMemory;
+ if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == CheckedState::DidOverflow)
+ externallyAllocatedMemory = std::numeric_limits<intptr_t>::max();
+
+ // Subtracting two intptr_t that are known to be positive will never underflow.
v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyAllocatedMemory - m_externallyAllocatedMemory);
m_externallyAllocatedMemory = externallyAllocatedMemory;
}
@@ -508,10 +574,8 @@ GraphicsContext* HTMLCanvasElement::drawingContext() const
GraphicsContext* HTMLCanvasElement::existingDrawingContext() const
{
- if (m_didFailToCreateImageBuffer) {
- ASSERT(!hasImageBuffer());
+ if (!hasImageBuffer())
return 0;
- }
return drawingContext();
}
@@ -527,7 +591,7 @@ void HTMLCanvasElement::ensureUnacceleratedImageBuffer()
{
if ((hasImageBuffer() && !m_imageBuffer->isAccelerated()) || m_didFailToCreateImageBuffer)
return;
- m_imageBuffer.clear();
+ discardImageBuffer();
OpacityMode opacityMode = !m_context || m_context->hasAlpha() ? NonOpaque : Opaque;
m_imageBuffer = ImageBuffer::create(size(), opacityMode);
m_didFailToCreateImageBuffer = !m_imageBuffer;
@@ -539,6 +603,7 @@ Image* HTMLCanvasElement::copiedImage() const
if (m_context)
m_context->paintRenderingResultsToCanvas();
m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
+ updateExternallyAllocatedMemory();
}
return m_copiedImage.get();
}
@@ -558,10 +623,23 @@ void HTMLCanvasElement::clearImageBuffer()
}
}
+void HTMLCanvasElement::discardImageBuffer()
+{
+ m_contextStateSaver.clear(); // uses context owned by m_imageBuffer
+ m_imageBuffer.clear();
+ updateExternallyAllocatedMemory();
+}
+
+bool HTMLCanvasElement::hasValidImageBuffer() const
+{
+ return m_imageBuffer && m_imageBuffer->isSurfaceValid();
+}
+
void HTMLCanvasElement::clearCopiedImage()
{
m_copiedImage.clear();
m_didClearImageBuffer = false;
+ updateExternallyAllocatedMemory();
}
AffineTransform HTMLCanvasElement::baseTransform() const
@@ -570,4 +648,62 @@ AffineTransform HTMLCanvasElement::baseTransform() const
return m_imageBuffer->baseTransform();
}
+void HTMLCanvasElement::didChangeVisibilityState(PageVisibilityState visibility)
+{
+ if (hasImageBuffer()) {
+ bool hidden = visibility != PageVisibilityStateVisible;
+ if (hidden) {
+ clearCopiedImage();
+ if (is3D()) {
+ discardImageBuffer();
+ }
+ }
+ if (hasImageBuffer()) {
+ m_imageBuffer->setIsHidden(hidden);
+ }
+ }
+}
+
+void HTMLCanvasElement::didMoveToNewDocument(Document& oldDocument)
+{
+ setObservedDocument(document());
+ HTMLElement::didMoveToNewDocument(oldDocument);
+}
+
+PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(SourceImageMode mode, SourceImageStatus* status) const
+{
+ if (!width() || !height()) {
+ *status = ZeroSizeCanvasSourceImageStatus;
+ return nullptr;
+ }
+
+ if (!buffer()) {
+ *status = InvalidSourceImageStatus;
+ return nullptr;
+ }
+
+ if (mode == CopySourceImageIfVolatile) {
+ *status = NormalSourceImageStatus;
+ return copiedImage();
+ }
+
+ if (m_context && m_context->is3d()) {
+ m_context->paintRenderingResultsToCanvas();
+ *status = ExternalSourceImageStatus;
+ } else {
+ *status = NormalSourceImageStatus;
+ }
+ return m_imageBuffer->copyImage(DontCopyBackingStore, Unscaled);
+}
+
+bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const
+{
+ return !originClean();
+}
+
+FloatSize HTMLCanvasElement::sourceSize() const
+{
+ return FloatSize(width(), height());
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
index 8db8a6d70a0..175bd4e11d9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.h
@@ -28,15 +28,22 @@
#ifndef HTMLCanvasElement_h
#define HTMLCanvasElement_h
+#include "core/dom/Document.h"
#include "core/html/HTMLElement.h"
+#include "core/html/canvas/CanvasImageSource.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntSize.h"
+#include "platform/graphics/Canvas2DLayerBridge.h"
+#include "platform/graphics/GraphicsTypes.h"
+#include "platform/graphics/ImageBufferClient.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
-#define DefaultInterpolationQuality InterpolationMedium
+#define CanvasDefaultInterpolationQuality InterpolationLow
namespace WebCore {
+class AffineTransform;
class CanvasContextAttributes;
class CanvasRenderingContext;
class GraphicsContext;
@@ -48,18 +55,22 @@ class ImageBuffer;
class ImageBufferSurface;
class IntSize;
-class CanvasObserver {
+class CanvasObserver : public WillBeGarbageCollectedMixin {
+ DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(CanvasObserver);
public:
- virtual ~CanvasObserver() { }
-
virtual void canvasChanged(HTMLCanvasElement*, const FloatRect& changedRect) = 0;
virtual void canvasResized(HTMLCanvasElement*) = 0;
+#if !ENABLE(OILPAN)
virtual void canvasDestroyed(HTMLCanvasElement*) = 0;
+#endif
+
+ virtual void trace(Visitor*) { }
};
-class HTMLCanvasElement FINAL : public HTMLElement {
+class HTMLCanvasElement FINAL : public HTMLElement, public DocumentVisibilityObserver, public CanvasImageSource, public ImageBufferClient {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLCanvasElement);
public:
- static PassRefPtr<HTMLCanvasElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLCanvasElement);
virtual ~HTMLCanvasElement();
void addObserver(CanvasObserver*);
@@ -90,14 +101,14 @@ public:
CanvasRenderingContext* getContext(const String&, CanvasContextAttributes* attributes = 0);
static String toEncodingMimeType(const String& mimeType);
- String toDataURL(const String& mimeType, const double* quality, ExceptionState&);
- String toDataURL(const String& mimeType, ExceptionState& exceptionState) { return toDataURL(mimeType, 0, exceptionState); }
+ String toDataURL(const String& mimeType, const double* quality, ExceptionState&) const;
+ String toDataURL(const String& mimeType, ExceptionState& exceptionState) const { return toDataURL(mimeType, 0, exceptionState); }
// Used for rendering
void didDraw(const FloatRect&);
void notifyObserversCanvasChanged(const FloatRect&);
- void paint(GraphicsContext*, const LayoutRect&, bool useLowQualityScale = false);
+ void paint(GraphicsContext*, const LayoutRect&);
GraphicsContext* drawingContext() const;
GraphicsContext* existingDrawingContext() const;
@@ -108,56 +119,77 @@ public:
ImageBuffer* buffer() const;
Image* copiedImage() const;
void clearCopiedImage();
- PassRefPtr<ImageData> getImageData();
+ PassRefPtrWillBeRawPtr<ImageData> getImageData() const;
void makePresentationCopy();
void clearPresentationCopy();
SecurityOrigin* securityOrigin() const;
- void setOriginTainted() { m_originClean = false; }
bool originClean() const { return m_originClean; }
+ void setOriginTainted() { m_originClean = false; }
AffineTransform baseTransform() const;
bool is3D() const;
- bool hasImageBuffer() const { return m_imageBuffer.get(); }
+ bool hasImageBuffer() const { return m_imageBuffer; }
+ bool hasValidImageBuffer() const;
+ void discardImageBuffer();
bool shouldAccelerate(const IntSize&) const;
- InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
+ virtual const AtomicString imageSourceURL() const OVERRIDE;
+
+ virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
+
+ // DocumentVisibilityObserver implementation
+ virtual void didChangeVisibilityState(PageVisibilityState) OVERRIDE;
+
+ // CanvasImageSource implementation
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const OVERRIDE;
+ virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+ virtual FloatSize sourceSize() const OVERRIDE;
+
+ // ImageBufferClient implementation
+ virtual void notifySurfaceInvalid() OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+protected:
+ virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
private:
explicit HTMLCanvasElement(Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
void reset();
PassOwnPtr<ImageBufferSurface> createImageBufferSurface(const IntSize& deviceSize, int* msaaSampleCount);
void createImageBuffer();
+ void createImageBufferInternal();
void clearImageBuffer();
void setSurfaceSize(const IntSize&);
bool paintsIntoCanvasBuffer() const;
- void setExternallyAllocatedMemory(intptr_t);
+ void updateExternallyAllocatedMemory() const;
- HashSet<CanvasObserver*> m_observers;
+ String toDataURLInternal(const String& mimeType, const double* quality, bool isSaving = false) const;
- IntSize m_size;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<CanvasObserver> > m_observers;
- OwnPtr<CanvasRenderingContext> m_context;
+ IntSize m_size;
- bool m_rendererIsCanvas;
+ OwnPtrWillBeMember<CanvasRenderingContext> m_context;
bool m_ignoreReset;
bool m_accelerationDisabled;
FloatRect m_dirtyRect;
- intptr_t m_externallyAllocatedMemory;
+ mutable intptr_t m_externallyAllocatedMemory;
bool m_originClean;
@@ -172,8 +204,6 @@ private:
mutable RefPtr<Image> m_copiedImage; // FIXME: This is temporary for platforms that have to copy the image buffer to render (and for CSSCanvasValue).
};
-DEFINE_NODE_TYPE_CASTS(HTMLCanvasElement, hasTagName(HTMLNames::canvasTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
index 0bee59fe085..e900490949d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCanvasElement.idl
@@ -32,6 +32,5 @@ interface HTMLCanvasElement : HTMLElement {
[Custom, RaisesException] DOMString toDataURL([TreatNullAs=NullString, TreatUndefinedAs=NullString,Default=Undefined] optional DOMString type);
// The custom binding is needed to handle context creation attributes.
- [Custom, PerWorldBindings, ActivityLogging=ForIsolatedWorlds] any getContext([Default=Undefined] optional DOMString contextId);
+ [Custom, LogActivity] any getContext([Default=Undefined] optional DOMString contextId);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp
index a0edbbc2f20..7f7d597f521 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,23 +24,27 @@
#include "config.h"
#include "core/html/HTMLCollection.h"
-#include "HTMLNames.h"
-#include "core/dom/ClassNodeList.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ClassCollection.h"
#include "core/dom/ElementTraversal.h"
-#include "core/dom/NodeList.h"
#include "core/dom/NodeRareData.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/html/DocumentNameCollection.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLObjectElement.h"
#include "core/html/HTMLOptionElement.h"
+#include "core/html/WindowNameCollection.h"
+#include "wtf/HashSet.h"
namespace WebCore {
using namespace HTMLNames;
-static bool shouldOnlyIncludeDirectChildren(CollectionType type)
+static bool shouldTypeOnlyIncludeDirectChildren(CollectionType type)
{
switch (type) {
+ case ClassCollectionType:
+ case TagCollectionType:
+ case HTMLTagCollectionType:
case DocAll:
case DocAnchors:
case DocApplets:
@@ -62,12 +67,9 @@ static bool shouldOnlyIncludeDirectChildren(CollectionType type)
case TSectionRows:
case TableTBodies:
return true;
- case ChildNodeListType:
- case ClassNodeListType:
case NameNodeListType:
- case TagNodeListType:
- case HTMLTagNodeListType:
case RadioNodeListType:
+ case RadioImgNodeListType:
case LabelsNodeListType:
break;
}
@@ -90,6 +92,9 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
case DocumentNamedItems:
case FormControls:
return NodeListIsRootedAtDocument;
+ case ClassCollectionType:
+ case TagCollectionType:
+ case HTMLTagCollectionType:
case NodeChildren:
case TableTBodies:
case TSectionRows:
@@ -100,12 +105,9 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
case DataListOptions:
case MapAreas:
return NodeListIsRootedAtNode;
- case ChildNodeListType:
- case ClassNodeListType:
case NameNodeListType:
- case TagNodeListType:
- case HTMLTagNodeListType:
case RadioNodeListType:
+ case RadioImgNodeListType:
case LabelsNodeListType:
break;
}
@@ -116,6 +118,8 @@ static NodeListRootType rootTypeFromCollectionType(CollectionType type)
static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(CollectionType type)
{
switch (type) {
+ case TagCollectionType:
+ case HTMLTagCollectionType:
case DocImages:
case DocEmbeds:
case DocForms:
@@ -144,12 +148,11 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
return InvalidateOnIdNameAttrChange;
case FormControls:
return InvalidateForFormControls;
- case ChildNodeListType:
- case ClassNodeListType:
+ case ClassCollectionType:
+ return InvalidateOnClassAttrChange;
case NameNodeListType:
- case TagNodeListType:
- case HTMLTagNodeListType:
case RadioNodeListType:
+ case RadioImgNodeListType:
case LabelsNodeListType:
break;
}
@@ -157,536 +160,367 @@ static NodeListInvalidationType invalidationTypeExcludingIdAndNameAttributes(Col
return DoNotInvalidateOnAttributeChanges;
}
-HTMLCollection::HTMLCollection(Node* ownerNode, CollectionType type, ItemAfterOverrideType itemAfterOverrideType)
- : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type),
- WebCore::shouldOnlyIncludeDirectChildren(type), type, itemAfterOverrideType)
+HTMLCollection::HTMLCollection(ContainerNode& ownerNode, CollectionType type, ItemAfterOverrideType itemAfterOverrideType)
+ : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), type)
+ , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter)
+ , m_shouldOnlyIncludeDirectChildren(shouldTypeOnlyIncludeDirectChildren(type))
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLCollection> HTMLCollection::create(Node* base, CollectionType type)
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLCollection::create(ContainerNode& base, CollectionType type)
{
- return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter));
+ return adoptRefWillBeNoop(new HTMLCollection(base, type, DoesNotOverrideItemAfter));
}
HTMLCollection::~HTMLCollection()
{
- // HTMLNameCollection removes cache by itself.
- if (type() != WindowNamedItems && type() != DocumentNamedItems)
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type());
+#if !ENABLE(OILPAN)
+ if (hasValidIdNameCache())
+ unregisterIdNameCacheFromDocument(document());
+ // Named HTMLCollection types remove cache by themselves.
+ if (isUnnamedHTMLCollectionType(type()))
+ ownerNode().nodeLists()->removeCache(this, type());
+#endif
+}
+
+void HTMLCollection::invalidateCache(Document* oldDocument) const
+{
+ m_collectionIndexCache.invalidate();
+ invalidateIdNameCacheMaps(oldDocument);
}
template <class NodeListType>
-inline bool isMatchingElement(const NodeListType*, Element*);
+inline bool isMatchingElement(const NodeListType&, const Element&);
-template <> inline bool isMatchingElement(const HTMLCollection* htmlCollection, Element* element)
+template <> inline bool isMatchingElement(const HTMLCollection& htmlCollection, const Element& element)
{
- CollectionType type = htmlCollection->type();
- if (!element->isHTMLElement() && !(type == DocAll || type == NodeChildren || type == WindowNamedItems))
+ CollectionType type = htmlCollection.type();
+
+ // These collections apply to any kind of Elements, not just HTMLElements.
+ switch (type) {
+ case DocAll:
+ case NodeChildren:
+ return true;
+ case ClassCollectionType:
+ return toClassCollection(htmlCollection).elementMatches(element);
+ case TagCollectionType:
+ return toTagCollection(htmlCollection).elementMatches(element);
+ case HTMLTagCollectionType:
+ return toHTMLTagCollection(htmlCollection).elementMatches(element);
+ case DocumentNamedItems:
+ return toDocumentNameCollection(htmlCollection).elementMatches(element);
+ case WindowNamedItems:
+ return toWindowNameCollection(htmlCollection).elementMatches(element);
+ default:
+ break;
+ }
+
+ // The following only applies to HTMLElements.
+ if (!element.isHTMLElement())
return false;
switch (type) {
case DocImages:
- return element->hasLocalName(imgTag);
+ return element.hasLocalName(imgTag);
case DocScripts:
- return element->hasLocalName(scriptTag);
+ return element.hasLocalName(scriptTag);
case DocForms:
- return element->hasLocalName(formTag);
+ return element.hasLocalName(formTag);
case TableTBodies:
- return element->hasLocalName(tbodyTag);
+ return element.hasLocalName(tbodyTag);
case TRCells:
- return element->hasLocalName(tdTag) || element->hasLocalName(thTag);
+ return element.hasLocalName(tdTag) || element.hasLocalName(thTag);
case TSectionRows:
- return element->hasLocalName(trTag);
+ return element.hasLocalName(trTag);
case SelectOptions:
- return element->hasLocalName(optionTag);
+ return element.hasLocalName(optionTag);
case SelectedOptions:
- return element->hasLocalName(optionTag) && toHTMLOptionElement(element)->selected();
+ return element.hasLocalName(optionTag) && toHTMLOptionElement(element).selected();
case DataListOptions:
- if (element->hasLocalName(optionTag)) {
- HTMLOptionElement* option = toHTMLOptionElement(element);
- if (!option->isDisabledFormControl() && !option->value().isEmpty())
+ if (element.hasLocalName(optionTag)) {
+ const HTMLOptionElement& option = toHTMLOptionElement(element);
+ if (!option.isDisabledFormControl() && !option.value().isEmpty())
return true;
}
return false;
case MapAreas:
- return element->hasLocalName(areaTag);
+ return element.hasLocalName(areaTag);
case DocApplets:
- return element->hasLocalName(appletTag) || (element->hasLocalName(objectTag) && toHTMLObjectElement(element)->containsJavaApplet());
+ return element.hasLocalName(appletTag) || (element.hasLocalName(objectTag) && toHTMLObjectElement(element).containsJavaApplet());
case DocEmbeds:
- return element->hasLocalName(embedTag);
+ return element.hasLocalName(embedTag);
case DocLinks:
- return (element->hasLocalName(aTag) || element->hasLocalName(areaTag)) && element->fastHasAttribute(hrefAttr);
+ return (element.hasLocalName(aTag) || element.hasLocalName(areaTag)) && element.fastHasAttribute(hrefAttr);
case DocAnchors:
- return element->hasLocalName(aTag) && element->fastHasAttribute(nameAttr);
+ return element.hasLocalName(aTag) && element.fastHasAttribute(nameAttr);
+ case ClassCollectionType:
+ case TagCollectionType:
+ case HTMLTagCollectionType:
case DocAll:
case NodeChildren:
- return true;
case FormControls:
case DocumentNamedItems:
case TableRows:
case WindowNamedItems:
- case ChildNodeListType:
- case ClassNodeListType:
case NameNodeListType:
- case TagNodeListType:
- case HTMLTagNodeListType:
case RadioNodeListType:
+ case RadioImgNodeListType:
case LabelsNodeListType:
ASSERT_NOT_REACHED();
}
return false;
}
-template <> inline bool isMatchingElement(const LiveNodeList* nodeList, Element* element)
-{
- return nodeList->nodeMatches(element);
-}
-
-template <> inline bool isMatchingElement(const HTMLTagNodeList* nodeList, Element* element)
-{
- return nodeList->nodeMatchesInlined(element);
-}
-
-template <> inline bool isMatchingElement(const ClassNodeList* nodeList, Element* element)
+template <> inline bool isMatchingElement(const ClassCollection& collection, const Element& element)
{
- return nodeList->nodeMatchesInlined(element);
+ return collection.elementMatches(element);
}
-static Node* previousNode(Node& base, Node& previous, bool onlyIncludeDirectChildren)
+template <> inline bool isMatchingElement(const HTMLTagCollection& collection, const Element& element)
{
- return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversal::previous(previous, &base);
+ return collection.elementMatches(element);
}
-static inline Node* lastDescendent(Node& node)
+Element* HTMLCollection::virtualItemAfter(Element*) const
{
- Node* descendent = node.lastChild();
- for (Node* current = descendent; current; current = current->lastChild())
- descendent = current;
- return descendent;
-}
-
-static Node* lastNode(Node& rootNode, bool onlyIncludeDirectChildren)
-{
- return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendent(rootNode);
-}
-
-ALWAYS_INLINE Node* LiveNodeListBase::iterateForPreviousNode(Node* current) const
-{
- bool onlyIncludeDirectChildren = shouldOnlyIncludeDirectChildren();
- CollectionType collectionType = type();
- Node& rootNode = this->rootNode();
- for (; current; current = previousNode(rootNode, *current, onlyIncludeDirectChildren)) {
- if (isNodeList(collectionType)) {
- if (current->isElementNode() && isMatchingElement(static_cast<const LiveNodeList*>(this), toElement(current)))
- return toElement(current);
- } else {
- if (current->isElementNode() && isMatchingElement(static_cast<const HTMLCollection*>(this), toElement(current)))
- return toElement(current);
- }
- }
+ ASSERT_NOT_REACHED();
return 0;
}
-ALWAYS_INLINE Node* LiveNodeListBase::itemBefore(Node* previous) const
+static inline bool nameShouldBeVisibleInDocumentAll(const HTMLElement& element)
{
- Node* current;
- if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower.
- current = previousNode(rootNode(), *previous, shouldOnlyIncludeDirectChildren());
- else
- current = lastNode(rootNode(), shouldOnlyIncludeDirectChildren());
-
- if (type() == ChildNodeListType)
- return current;
- return iterateForPreviousNode(current);
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#dom-htmlallcollection-nameditem:
+ // The document.all collection returns only certain types of elements by name,
+ // although it returns any type of element by id.
+ return element.hasLocalName(aTag)
+ || element.hasLocalName(appletTag)
+ || element.hasLocalName(areaTag)
+ || element.hasLocalName(embedTag)
+ || element.hasLocalName(formTag)
+ || element.hasLocalName(frameTag)
+ || element.hasLocalName(framesetTag)
+ || element.hasLocalName(iframeTag)
+ || element.hasLocalName(imgTag)
+ || element.hasLocalName(inputTag)
+ || element.hasLocalName(objectTag)
+ || element.hasLocalName(selectTag);
+}
+
+inline Element* firstMatchingChildElement(const HTMLCollection& nodeList)
+{
+ Element* element = ElementTraversal::firstChild(nodeList.rootNode());
+ while (element && !isMatchingElement(nodeList, *element))
+ element = ElementTraversal::nextSibling(*element);
+ return element;
}
-template <class NodeListType>
-inline Element* firstMatchingElement(const NodeListType* nodeList, ContainerNode& root)
+inline Element* lastMatchingChildElement(const HTMLCollection& nodeList)
{
- Element* element = ElementTraversal::firstWithin(root);
- while (element && !isMatchingElement(nodeList, element))
- element = ElementTraversal::next(*element, &root);
+ Element* element = ElementTraversal::lastChild(nodeList.rootNode());
+ while (element && !isMatchingElement(nodeList, *element))
+ element = ElementTraversal::previousSibling(*element);
return element;
}
-template <class NodeListType>
-inline Element* nextMatchingElement(const NodeListType* nodeList, Element& current, ContainerNode* root)
+inline Element* nextMatchingChildElement(const HTMLCollection& nodeList, Element& current)
{
Element* next = &current;
do {
- next = ElementTraversal::next(*next, root);
- } while (next && !isMatchingElement(nodeList, next));
+ next = ElementTraversal::nextSibling(*next);
+ } while (next && !isMatchingElement(nodeList, *next));
return next;
}
-template <class NodeListType>
-inline Element* traverseMatchingElementsForwardToOffset(const NodeListType* nodeList, unsigned offset, Element& currentElement, unsigned& currentOffset, ContainerNode* root)
-{
- ASSERT(currentOffset < offset);
- Element* next = &currentElement;
- while ((next = nextMatchingElement(nodeList, *next, root))) {
- if (++currentOffset == offset)
- return next;
- }
- return 0;
-}
-
-// FIXME: This should be in ChildNodeList
-inline Node* LiveNodeListBase::traverseChildNodeListForwardToOffset(unsigned offset, Node* currentNode, unsigned& currentOffset) const
+inline Element* previousMatchingChildElement(const HTMLCollection& nodeList, Element& current)
{
- ASSERT(type() == ChildNodeListType);
- ASSERT(currentOffset < offset);
- while ((currentNode = currentNode->nextSibling())) {
- if (++currentOffset == offset)
- return currentNode;
+ Element* previous = &current;
+ do {
+ previous = ElementTraversal::previousSibling(*previous);
+ } while (previous && !isMatchingElement(nodeList, *previous));
+ return previous;
+}
+
+Element* HTMLCollection::traverseToFirstElement() const
+{
+ switch (type()) {
+ case HTMLTagCollectionType:
+ return firstMatchingElement(toHTMLTagCollection(*this));
+ case ClassCollectionType:
+ return firstMatchingElement(toClassCollection(*this));
+ default:
+ if (overridesItemAfter())
+ return virtualItemAfter(0);
+ if (shouldOnlyIncludeDirectChildren())
+ return firstMatchingChildElement(*this);
+ return firstMatchingElement(*this);
}
- return 0;
-}
-
-// FIXME: This should be in LiveNodeList
-inline Element* LiveNodeListBase::traverseLiveNodeListFirstElement(ContainerNode& root) const
-{
- ASSERT(isNodeList(type()));
- ASSERT(type() != ChildNodeListType);
- if (type() == HTMLTagNodeListType)
- return firstMatchingElement(static_cast<const HTMLTagNodeList*>(this), root);
- if (type() == ClassNodeListType)
- return firstMatchingElement(static_cast<const ClassNodeList*>(this), root);
- return firstMatchingElement(static_cast<const LiveNodeList*>(this), root);
-}
-
-// FIXME: This should be in LiveNodeList
-inline Element* LiveNodeListBase::traverseLiveNodeListForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, ContainerNode* root) const
-{
- ASSERT(isNodeList(type()));
- ASSERT(type() != ChildNodeListType);
- if (type() == HTMLTagNodeListType)
- return traverseMatchingElementsForwardToOffset(static_cast<const HTMLTagNodeList*>(this), offset, currentElement, currentOffset, root);
- if (type() == ClassNodeListType)
- return traverseMatchingElementsForwardToOffset(static_cast<const ClassNodeList*>(this), offset, currentElement, currentOffset, root);
- return traverseMatchingElementsForwardToOffset(static_cast<const LiveNodeList*>(this), offset, currentElement, currentOffset, root);
-}
-
-bool ALWAYS_INLINE LiveNodeListBase::isLastItemCloserThanLastOrCachedItem(unsigned offset) const
-{
- ASSERT(isLengthCacheValid());
- unsigned distanceFromLastItem = cachedLength() - offset;
- if (!isItemCacheValid())
- return distanceFromLastItem < offset;
-
- return cachedItemOffset() < offset && distanceFromLastItem < offset - cachedItemOffset();
-}
-
-bool ALWAYS_INLINE LiveNodeListBase::isFirstItemCloserThanCachedItem(unsigned offset) const
-{
- ASSERT(isItemCacheValid());
- if (cachedItemOffset() < offset)
- return false;
-
- unsigned distanceFromCachedItem = cachedItemOffset() - offset;
- return offset < distanceFromCachedItem;
}
-ALWAYS_INLINE void LiveNodeListBase::setItemCache(Node* item, unsigned offset, unsigned elementsArrayOffset) const
+Element* HTMLCollection::traverseToLastElement() const
{
- setItemCache(item, offset);
- if (overridesItemAfter()) {
- ASSERT_WITH_SECURITY_IMPLICATION(item->isElementNode());
- static_cast<const HTMLCollection*>(this)->m_cachedElementsArrayOffset = elementsArrayOffset;
- } else
- ASSERT(!elementsArrayOffset);
-}
-
-unsigned LiveNodeListBase::length() const
-{
- if (isLengthCacheValid())
- return cachedLength();
-
- item(UINT_MAX);
- ASSERT(isLengthCacheValid());
-
- return cachedLength();
+ ASSERT(canTraverseBackward());
+ if (shouldOnlyIncludeDirectChildren())
+ return lastMatchingChildElement(*this);
+ return lastMatchingElement(*this);
}
-// FIXME: It is silly that these functions are in HTMLCollection.cpp.
-Node* LiveNodeListBase::item(unsigned offset) const
+Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const
{
- if (isItemCacheValid() && cachedItemOffset() == offset)
- return cachedItem();
-
- if (isLengthCacheValid() && cachedLength() <= offset)
- return 0;
-
- ContainerNode* root = rootContainerNode();
- if (!root) {
- // FIMXE: In someTextNode.childNodes case the root is Text. We shouldn't even make a LiveNodeList for that.
- setLengthCache(0);
- return 0;
- }
-
- if (isLengthCacheValid() && !overridesItemAfter() && isLastItemCloserThanLastOrCachedItem(offset)) {
- Node* lastItem = itemBefore(0);
- ASSERT(lastItem);
- setItemCache(lastItem, cachedLength() - 1, 0);
- } else if (!isItemCacheValid() || isFirstItemCloserThanCachedItem(offset) || (overridesItemAfter() && offset < cachedItemOffset())) {
- unsigned offsetInArray = 0;
- Node* firstItem;
- if (type() == ChildNodeListType)
- firstItem = root->firstChild();
- else if (isNodeList(type()))
- firstItem = traverseLiveNodeListFirstElement(*root);
- else
- firstItem = static_cast<const HTMLCollection*>(this)->traverseFirstElement(offsetInArray, *root);
-
- if (!firstItem) {
- setLengthCache(0);
+ ASSERT(currentOffset < offset);
+ switch (type()) {
+ case HTMLTagCollectionType:
+ return traverseMatchingElementsForwardToOffset(toHTMLTagCollection(*this), offset, currentElement, currentOffset);
+ case ClassCollectionType:
+ return traverseMatchingElementsForwardToOffset(toClassCollection(*this), offset, currentElement, currentOffset);
+ default:
+ if (overridesItemAfter()) {
+ Element* next = &currentElement;
+ while ((next = virtualItemAfter(next))) {
+ if (++currentOffset == offset)
+ return next;
+ }
return 0;
}
- setItemCache(firstItem, 0, offsetInArray);
- ASSERT(!cachedItemOffset());
+ if (shouldOnlyIncludeDirectChildren()) {
+ Element* next = &currentElement;
+ while ((next = nextMatchingChildElement(*this, *next))) {
+ if (++currentOffset == offset)
+ return next;
+ }
+ return 0;
+ }
+ return traverseMatchingElementsForwardToOffset(*this, offset, currentElement, currentOffset);
}
-
- if (cachedItemOffset() == offset)
- return cachedItem();
-
- return itemBeforeOrAfterCachedItem(offset, root);
}
-inline Node* LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned offset, ContainerNode* root) const
+Element* HTMLCollection::traverseBackwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const
{
- unsigned currentOffset = cachedItemOffset();
- Node* currentItem = cachedItem();
- ASSERT(currentItem);
- ASSERT(currentOffset != offset);
-
- if (offset < cachedItemOffset()) {
- ASSERT(!overridesItemAfter());
- while ((currentItem = itemBefore(currentItem))) {
- ASSERT(currentOffset);
- currentOffset--;
- if (currentOffset == offset) {
- setItemCache(currentItem, currentOffset, 0);
- return currentItem;
- }
+ ASSERT(currentOffset > offset);
+ ASSERT(canTraverseBackward());
+ if (shouldOnlyIncludeDirectChildren()) {
+ Element* previous = &currentElement;
+ while ((previous = previousMatchingChildElement(*this, *previous))) {
+ if (--currentOffset == offset)
+ return previous;
}
- ASSERT_NOT_REACHED();
- return 0;
- }
-
- unsigned offsetInArray = 0;
- if (type() == ChildNodeListType)
- currentItem = traverseChildNodeListForwardToOffset(offset, currentItem, currentOffset);
- else if (isNodeList(type()))
- currentItem = traverseLiveNodeListForwardToOffset(offset, toElement(*currentItem), currentOffset, root);
- else
- currentItem = static_cast<const HTMLCollection*>(this)->traverseForwardToOffset(offset, toElement(*currentItem), currentOffset, offsetInArray, root);
-
- if (!currentItem) {
- // Did not find the item. On plus side, we now know the length.
- setLengthCache(currentOffset + 1);
return 0;
}
- setItemCache(currentItem, currentOffset, offsetInArray);
- return currentItem;
-}
-
-Element* HTMLCollection::virtualItemAfter(unsigned&, Element*) const
-{
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-static inline bool nameShouldBeVisibleInDocumentAll(HTMLElement* element)
-{
- // The document.all collection returns only certain types of elements by name,
- // although it returns any type of element by id.
- return element->hasLocalName(appletTag)
- || element->hasLocalName(embedTag)
- || element->hasLocalName(formTag)
- || element->hasLocalName(imgTag)
- || element->hasLocalName(inputTag)
- || element->hasLocalName(objectTag)
- || element->hasLocalName(selectTag);
+ return traverseMatchingElementsBackwardToOffset(*this, offset, currentElement, currentOffset);
}
-bool HTMLCollection::checkForNameMatch(Element* element, bool checkName, const AtomicString& name) const
+Element* HTMLCollection::namedItem(const AtomicString& name) const
{
- if (!element->isHTMLElement())
- return false;
-
- HTMLElement* e = toHTMLElement(element);
- if (!checkName)
- return e->getIdAttribute() == name;
-
- if (type() == DocAll && !nameShouldBeVisibleInDocumentAll(e))
- return false;
+ // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
+ // This method first searches for an object with a matching id
+ // attribute. If a match is not found, the method then searches for an
+ // object with a matching name attribute, but only on those elements
+ // that are allowed a name attribute.
+ updateIdNameCache();
- return e->getNameAttribute() == name && e->getIdAttribute() != name;
-}
+ const NamedItemCache& cache = namedItemCache();
+ WillBeHeapVector<RawPtrWillBeMember<Element> >* idResults = cache.getElementsById(name);
+ if (idResults && !idResults->isEmpty())
+ return idResults->first();
-inline Element* firstMatchingChildElement(const HTMLCollection* nodeList, ContainerNode& root)
-{
- Element* element = ElementTraversal::firstWithin(root);
- while (element && !isMatchingElement(nodeList, element))
- element = ElementTraversal::nextSkippingChildren(*element, &root);
- return element;
-}
+ WillBeHeapVector<RawPtrWillBeMember<Element> >* nameResults = cache.getElementsByName(name);
+ if (nameResults && !nameResults->isEmpty())
+ return nameResults->first();
-inline Element* nextMatchingChildElement(const HTMLCollection* nodeList, Element& current, ContainerNode* root)
-{
- Element* next = &current;
- do {
- next = ElementTraversal::nextSkippingChildren(*next, root);
- } while (next && !isMatchingElement(nodeList, next));
- return next;
-}
-
-inline Element* HTMLCollection::traverseFirstElement(unsigned& offsetInArray, ContainerNode& root) const
-{
- if (overridesItemAfter())
- return virtualItemAfter(offsetInArray, 0);
- ASSERT(!offsetInArray);
- if (shouldOnlyIncludeDirectChildren())
- return firstMatchingChildElement(static_cast<const HTMLCollection*>(this), root);
- return firstMatchingElement(static_cast<const HTMLCollection*>(this), root);
+ return 0;
}
-inline Element* HTMLCollection::traverseNextElement(unsigned& offsetInArray, Element& previous, ContainerNode* root) const
+bool HTMLCollection::namedPropertyQuery(const AtomicString& name, ExceptionState&)
{
- if (overridesItemAfter())
- return virtualItemAfter(offsetInArray, &previous);
- ASSERT(!offsetInArray);
- if (shouldOnlyIncludeDirectChildren())
- return nextMatchingChildElement(this, previous, root);
- return nextMatchingElement(this, previous, root);
+ return namedItem(name);
}
-inline Element* HTMLCollection::traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, unsigned& offsetInArray, ContainerNode* root) const
+void HTMLCollection::supportedPropertyNames(Vector<String>& names)
{
- ASSERT(currentOffset < offset);
- if (overridesItemAfter()) {
- offsetInArray = m_cachedElementsArrayOffset;
- Element* next = &currentElement;
- while ((next = virtualItemAfter(offsetInArray, next))) {
- if (++currentOffset == offset)
- return next;
+ // As per the specification (http://dom.spec.whatwg.org/#htmlcollection):
+ // The supported property names are the values from the list returned by these steps:
+ // 1. Let result be an empty list.
+ // 2. For each element represented by the collection, in tree order, run these substeps:
+ // 1. If element has an ID which is neither the empty string nor is in result, append element's ID to result.
+ // 2. If element is in the HTML namespace and has a name attribute whose value is neither the empty string
+ // nor is in result, append element's name attribute value to result.
+ // 3. Return result.
+ HashSet<AtomicString> existingNames;
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Element* element = item(i);
+ const AtomicString& idAttribute = element->getIdAttribute();
+ if (!idAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(idAttribute);
+ if (addResult.isNewEntry)
+ names.append(idAttribute);
}
- return 0;
- }
- if (shouldOnlyIncludeDirectChildren()) {
- Element* next = &currentElement;
- while ((next = nextMatchingChildElement(this, *next, root))) {
- if (++currentOffset == offset)
- return next;
+ if (!element->isHTMLElement())
+ continue;
+ const AtomicString& nameAttribute = element->getNameAttribute();
+ if (!nameAttribute.isEmpty() && (type() != DocAll || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element)))) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(nameAttribute);
+ if (addResult.isNewEntry)
+ names.append(nameAttribute);
}
- return 0;
}
- return traverseMatchingElementsForwardToOffset(this, offset, currentElement, currentOffset, root);
}
-Node* HTMLCollection::namedItem(const AtomicString& name) const
+void HTMLCollection::namedPropertyEnumerator(Vector<String>& names, ExceptionState&)
{
- // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
- // This method first searches for an object with a matching id
- // attribute. If a match is not found, the method then searches for an
- // object with a matching name attribute, but only on those elements
- // that are allowed a name attribute.
-
- ContainerNode* root = rootContainerNode();
- if (!root)
- return 0;
-
- unsigned arrayOffset = 0;
- unsigned i = 0;
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) {
- if (checkForNameMatch(element, /* checkName */ false, name)) {
- setItemCache(element, i, arrayOffset);
- return element;
- }
- i++;
- }
-
- i = 0;
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) {
- if (checkForNameMatch(element, /* checkName */ true, name)) {
- setItemCache(element, i, arrayOffset);
- return element;
- }
- i++;
- }
-
- return 0;
+ supportedPropertyNames(names);
}
-void HTMLCollection::updateNameCache() const
+void HTMLCollection::updateIdNameCache() const
{
- if (hasNameCache())
- return;
-
- ContainerNode* root = rootContainerNode();
- if (!root)
+ if (hasValidIdNameCache())
return;
- unsigned arrayOffset = 0;
- for (Element* element = traverseFirstElement(arrayOffset, *root); element; element = traverseNextElement(arrayOffset, *element, root)) {
+ OwnPtrWillBeRawPtr<NamedItemCache> cache = NamedItemCache::create();
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Element* element = item(i);
const AtomicString& idAttrVal = element->getIdAttribute();
if (!idAttrVal.isEmpty())
- appendIdCache(idAttrVal, element);
+ cache->addElementWithId(idAttrVal, element);
if (!element->isHTMLElement())
continue;
const AtomicString& nameAttrVal = element->getNameAttribute();
- if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != DocAll || nameShouldBeVisibleInDocumentAll(toHTMLElement(element))))
- appendNameCache(nameAttrVal, element);
+ if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && (type() != DocAll || nameShouldBeVisibleInDocumentAll(toHTMLElement(*element))))
+ cache->addElementWithName(nameAttrVal, element);
}
-
- setHasNameCache();
+ // Set the named item cache last as traversing the tree may cause cache invalidation.
+ setNamedItemCache(cache.release());
}
-bool HTMLCollection::hasNamedItem(const AtomicString& name) const
+void HTMLCollection::namedItems(const AtomicString& name, WillBeHeapVector<RefPtrWillBeMember<Element> >& result) const
{
+ ASSERT(result.isEmpty());
if (name.isEmpty())
- return false;
+ return;
- updateNameCache();
+ updateIdNameCache();
- if (Vector<Element*>* cache = idCache(name)) {
- if (!cache->isEmpty())
- return true;
+ const NamedItemCache& cache = namedItemCache();
+ if (WillBeHeapVector<RawPtrWillBeMember<Element> >* idResults = cache.getElementsById(name)) {
+ for (unsigned i = 0; i < idResults->size(); ++i)
+ result.append(idResults->at(i));
}
-
- if (Vector<Element*>* cache = nameCache(name)) {
- if (!cache->isEmpty())
- return true;
+ if (WillBeHeapVector<RawPtrWillBeMember<Element> >* nameResults = cache.getElementsByName(name)) {
+ for (unsigned i = 0; i < nameResults->size(); ++i)
+ result.append(nameResults->at(i));
}
-
- return false;
}
-void HTMLCollection::namedItems(const AtomicString& name, Vector<RefPtr<Node> >& result) const
+HTMLCollection::NamedItemCache::NamedItemCache()
{
- ASSERT(result.isEmpty());
- if (name.isEmpty())
- return;
-
- updateNameCache();
-
- Vector<Element*>* idResults = idCache(name);
- Vector<Element*>* nameResults = nameCache(name);
-
- for (unsigned i = 0; idResults && i < idResults->size(); ++i)
- result.append(idResults->at(i));
-
- for (unsigned i = 0; nameResults && i < nameResults->size(); ++i)
- result.append(nameResults->at(i));
}
-void HTMLCollection::append(NodeCacheMap& map, const AtomicString& key, Element* element)
+void HTMLCollection::trace(Visitor* visitor)
{
- OwnPtr<Vector<Element*> >& vector = map.add(key.impl(), nullptr).iterator->value;
- if (!vector)
- vector = adoptPtr(new Vector<Element*>);
- vector->append(element);
+ visitor->trace(m_namedItemCache);
+ visitor->trace(m_collectionIndexCache);
+ LiveNodeListBase::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.h
index 967b247db4d..97416341978 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.h
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,7 +24,8 @@
#ifndef HTMLCollection_h
#define HTMLCollection_h
-#include "core/dom/LiveNodeList.h"
+#include "core/dom/LiveNodeListBase.h"
+#include "core/html/CollectionIndexCache.h"
#include "core/html/CollectionType.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
@@ -31,65 +33,133 @@
namespace WebCore {
-class HTMLCollection : public LiveNodeListBase {
+class HTMLCollection : public RefCountedWillBeGarbageCollectedFinalized<HTMLCollection>, public ScriptWrappable, public LiveNodeListBase {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLCollection);
public:
- static PassRefPtr<HTMLCollection> create(Node* base, CollectionType);
+ enum ItemAfterOverrideType {
+ OverridesItemAfter,
+ DoesNotOverrideItemAfter,
+ };
+
+ static PassRefPtrWillBeRawPtr<HTMLCollection> create(ContainerNode& base, CollectionType);
virtual ~HTMLCollection();
+ virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE;
+ void invalidateCacheForAttribute(const QualifiedName*) const;
// DOM API
- virtual Node* namedItem(const AtomicString& name) const;
+ unsigned length() const { return m_collectionIndexCache.nodeCount(*this); }
+ Element* item(unsigned offset) const { return m_collectionIndexCache.nodeAt(*this, offset); }
+ virtual Element* namedItem(const AtomicString& name) const;
+ bool namedPropertyQuery(const AtomicString&, ExceptionState&);
+ void namedPropertyEnumerator(Vector<String>& names, ExceptionState&);
// Non-DOM API
- virtual bool hasNamedItem(const AtomicString& name) const;
- void namedItems(const AtomicString& name, Vector<RefPtr<Node> >&) const;
- bool isEmpty() const
- {
- if (isLengthCacheValid())
- return !cachedLength();
- if (isItemCacheValid())
- return !cachedItem();
- return !item(0);
- }
- bool hasExactlyOneItem() const
- {
- if (isLengthCacheValid())
- return cachedLength() == 1;
- if (isItemCacheValid())
- return cachedItem() && !cachedItemOffset() && !item(1);
- return item(0) && !item(1);
- }
+ void namedItems(const AtomicString& name, WillBeHeapVector<RefPtrWillBeMember<Element> >&) const;
+ bool isEmpty() const { return m_collectionIndexCache.isEmpty(*this); }
+ bool hasExactlyOneItem() const { return m_collectionIndexCache.hasExactlyOneNode(*this); }
- virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const;
+ // CollectionIndexCache API.
+ bool canTraverseBackward() const { return !overridesItemAfter(); }
+ Element* traverseToFirstElement() const;
+ Element* traverseToLastElement() const;
+ Element* traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const;
+ Element* traverseBackwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset) const;
- Element* traverseFirstElement(unsigned& offsetInArray, ContainerNode& root) const;
- Element* traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, unsigned& offsetInArray, ContainerNode* root) const;
+ virtual void trace(Visitor*);
protected:
- HTMLCollection(Node* base, CollectionType, ItemAfterOverrideType);
-
- virtual void updateNameCache() const;
+ HTMLCollection(ContainerNode& base, CollectionType, ItemAfterOverrideType);
+
+ class NamedItemCache FINAL : public NoBaseWillBeGarbageCollected<NamedItemCache> {
+ public:
+ static PassOwnPtrWillBeRawPtr<NamedItemCache> create()
+ {
+ return adoptPtrWillBeNoop(new NamedItemCache);
+ }
+
+ WillBeHeapVector<RawPtrWillBeMember<Element> >* getElementsById(const AtomicString& id) const { return m_idCache.get(id.impl()); }
+ WillBeHeapVector<RawPtrWillBeMember<Element> >* getElementsByName(const AtomicString& name) const { return m_nameCache.get(name.impl()); }
+ void addElementWithId(const AtomicString& id, Element* element) { addElementToMap(m_idCache, id, element); }
+ void addElementWithName(const AtomicString& name, Element* element) { addElementToMap(m_nameCache, name, element); }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_idCache);
+ visitor->trace(m_nameCache);
+ }
+
+ private:
+ NamedItemCache();
+ typedef WillBeHeapHashMap<StringImpl*, OwnPtrWillBeMember<WillBeHeapVector<RawPtrWillBeMember<Element> > > > StringToElementsMap;
+ static void addElementToMap(StringToElementsMap& map, const AtomicString& key, Element* element)
+ {
+ OwnPtrWillBeMember<WillBeHeapVector<RawPtrWillBeMember<Element> > >& vector = map.add(key.impl(), nullptr).storedValue->value;
+ if (!vector)
+ vector = adoptPtrWillBeNoop(new WillBeHeapVector<RawPtrWillBeMember<Element> >);
+ vector->append(element);
+ }
+
+ StringToElementsMap m_idCache;
+ StringToElementsMap m_nameCache;
+ };
+
+ bool overridesItemAfter() const { return m_overridesItemAfter; }
+ virtual Element* virtualItemAfter(Element*) const;
+ bool shouldOnlyIncludeDirectChildren() const { return m_shouldOnlyIncludeDirectChildren; }
+ virtual void supportedPropertyNames(Vector<String>& names);
+
+ virtual void updateIdNameCache() const;
+ bool hasValidIdNameCache() const { return m_namedItemCache; }
+
+ void setNamedItemCache(PassOwnPtrWillBeRawPtr<NamedItemCache> cache) const
+ {
+ ASSERT(!m_namedItemCache);
+ document().registerNodeListWithIdNameCache(this);
+ m_namedItemCache = cache;
+ }
- typedef HashMap<StringImpl*, OwnPtr<Vector<Element*> > > NodeCacheMap;
- Vector<Element*>* idCache(const AtomicString& name) const { return m_idCache.get(name.impl()); }
- Vector<Element*>* nameCache(const AtomicString& name) const { return m_nameCache.get(name.impl()); }
- void appendIdCache(const AtomicString& name, Element* element) const { append(m_idCache, name, element); }
- void appendNameCache(const AtomicString& name, Element* element) const { append(m_nameCache, name, element); }
+ NamedItemCache& namedItemCache() const
+ {
+ ASSERT(m_namedItemCache);
+ return *m_namedItemCache;
+ }
private:
- bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const;
- Element* traverseNextElement(unsigned& offsetInArray, Element& previous, ContainerNode* root) const;
+ void invalidateIdNameCacheMaps(Document* oldDocument = 0) const
+ {
+ if (!hasValidIdNameCache())
+ return;
- virtual bool isLiveNodeList() const OVERRIDE { ASSERT_NOT_REACHED(); return true; }
+ // Make sure we decrement the NodeListWithIdNameCache count from
+ // the old document instead of the new one in the case the collection
+ // is moved to a new document.
+ unregisterIdNameCacheFromDocument(oldDocument ? *oldDocument : document());
- static void append(NodeCacheMap&, const AtomicString&, Element*);
+ m_namedItemCache.clear();
+ }
- mutable NodeCacheMap m_idCache;
- mutable NodeCacheMap m_nameCache;
- mutable unsigned m_cachedElementsArrayOffset;
+ void unregisterIdNameCacheFromDocument(Document& document) const
+ {
+ ASSERT(hasValidIdNameCache());
+ document.unregisterNodeListWithIdNameCache(this);
+ }
- friend class LiveNodeListBase;
+ const unsigned m_overridesItemAfter : 1;
+ const unsigned m_shouldOnlyIncludeDirectChildren : 1;
+ mutable OwnPtrWillBeMember<NamedItemCache> m_namedItemCache;
+ mutable CollectionIndexCache<HTMLCollection, Element> m_collectionIndexCache;
};
+DEFINE_TYPE_CASTS(HTMLCollection, LiveNodeListBase, collection, isHTMLCollectionType(collection->type()), isHTMLCollectionType(collection.type()));
+
+inline void HTMLCollection::invalidateCacheForAttribute(const QualifiedName* attrName) const
+{
+ if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
+ invalidateCache();
+ else if (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr)
+ invalidateIdNameCacheMaps();
+}
+
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl
index 0198742a6cb..cab83cd6177 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLCollection.idl
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,11 +22,11 @@
[
Custom=Wrap,
DependentLifetime,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
+ WillBeGarbageCollected,
] interface HTMLCollection {
readonly attribute unsigned long length;
- getter Node item([Default=Undefined] optional unsigned long index);
- Node namedItem([Default=Undefined] optional DOMString name);
- [NotEnumerable, ImplementedAs=namedItem] getter Node ([Default=Undefined] optional DOMString name);
+ getter Element item([Default=Undefined] optional unsigned long index);
+ getter Element namedItem(DOMString name);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.cpp
new file mode 100644
index 00000000000..e47e91002d5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.cpp
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/HTMLContentElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/css/SelectorChecker.h"
+#include "core/css/SiblingTraversalStrategies.h"
+#include "core/css/parser/BisonCSSParser.h"
+#include "core/dom/QualifiedName.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "platform/RuntimeEnabledFeatures.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLContentElement::HTMLContentElement(Document& document)
+ : InsertionPoint(contentTag, document)
+ , m_shouldParseSelect(false)
+ , m_isValidSelector(true)
+{
+ ScriptWrappable::init(this);
+}
+
+DEFINE_NODE_FACTORY(HTMLContentElement)
+
+HTMLContentElement::~HTMLContentElement()
+{
+}
+
+void HTMLContentElement::parseSelect()
+{
+ ASSERT(m_shouldParseSelect);
+
+ BisonCSSParser parser(CSSParserContext(document(), 0));
+ parser.parseSelector(m_select, m_selectorList);
+ m_shouldParseSelect = false;
+ m_isValidSelector = validateSelect();
+ if (!m_isValidSelector) {
+ CSSSelectorList emptyList;
+ m_selectorList.adopt(emptyList);
+ }
+}
+
+void HTMLContentElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
+{
+ if (name == selectAttr) {
+ if (ShadowRoot* root = containingShadowRoot())
+ root->owner()->willAffectSelector();
+ m_shouldParseSelect = true;
+ m_select = value;
+ } else {
+ InsertionPoint::parseAttribute(name, value);
+ }
+}
+
+static inline bool includesDisallowedPseudoClass(const CSSSelector& selector)
+{
+ return selector.match() == CSSSelector::PseudoClass && selector.pseudoType() != CSSSelector::PseudoNot;
+}
+
+bool HTMLContentElement::validateSelect() const
+{
+ ASSERT(!m_shouldParseSelect);
+
+ if (m_select.isNull() || m_select.isEmpty())
+ return true;
+
+ if (!m_selectorList.isValid())
+ return false;
+
+ bool allowAnyPseudoClasses = RuntimeEnabledFeatures::pseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled() || (containingShadowRoot() && containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot);
+
+ for (const CSSSelector* selector = m_selectorList.first(); selector; selector = m_selectorList.next(*selector)) {
+ if (!selector->isCompound())
+ return false;
+ if (allowAnyPseudoClasses)
+ continue;
+ for (const CSSSelector* subSelector = selector; subSelector; subSelector = subSelector->tagHistory()) {
+ if (includesDisallowedPseudoClass(*subSelector))
+ return false;
+ }
+ }
+ return true;
+}
+
+static inline bool checkOneSelector(const CSSSelector& selector, const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth)
+{
+ Element* element = toElement(siblings[nth]);
+ SelectorChecker selectorChecker(element->document(), SelectorChecker::CollectingCSSRules);
+ SelectorChecker::SelectorCheckingContext context(selector, element, SelectorChecker::VisitedMatchEnabled);
+ ShadowDOMSiblingTraversalStrategy strategy(siblings, nth);
+ return selectorChecker.match(context, strategy) == SelectorChecker::SelectorMatches;
+}
+
+bool HTMLContentElement::matchSelector(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth) const
+{
+ for (const CSSSelector* selector = selectorList().first(); selector; selector = CSSSelectorList::next(*selector)) {
+ if (checkOneSelector(*selector, siblings, nth))
+ return true;
+ }
+ return false;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h
index 9d14a277dc7..775813415d1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.h
@@ -1,2 +1,94 @@
-// FIXME: Move HTMLContentElement.h here.
-#include "core/html/shadow/HTMLContentElement.h"
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLContentElement_h
+#define HTMLContentElement_h
+
+#include "core/css/CSSSelectorList.h"
+#include "core/dom/shadow/InsertionPoint.h"
+
+namespace WebCore {
+
+class HTMLContentElement FINAL : public InsertionPoint {
+public:
+ DECLARE_NODE_FACTORY(HTMLContentElement);
+ virtual ~HTMLContentElement();
+
+ virtual bool canAffectSelector() const OVERRIDE { return true; }
+
+ bool canSelectNode(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth) const;
+
+ const CSSSelectorList& selectorList() const;
+ bool isSelectValid() const;
+
+private:
+ explicit HTMLContentElement(Document&);
+
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
+
+ bool validateSelect() const;
+ void parseSelect();
+
+ bool matchSelector(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth) const;
+
+ bool m_shouldParseSelect;
+ bool m_isValidSelector;
+ AtomicString m_select;
+ CSSSelectorList m_selectorList;
+};
+
+inline const CSSSelectorList& HTMLContentElement::selectorList() const
+{
+ if (m_shouldParseSelect)
+ const_cast<HTMLContentElement*>(this)->parseSelect();
+ return m_selectorList;
+}
+
+inline bool HTMLContentElement::isSelectValid() const
+{
+ if (m_shouldParseSelect)
+ const_cast<HTMLContentElement*>(this)->parseSelect();
+ return m_isValidSelector;
+}
+
+inline bool HTMLContentElement::canSelectNode(const WillBeHeapVector<RawPtrWillBeMember<Node>, 32>& siblings, int nth) const
+{
+ if (m_select.isNull() || m_select.isEmpty())
+ return true;
+ if (!isSelectValid())
+ return false;
+ if (!siblings[nth]->isElementNode())
+ return false;
+ return matchSelector(siblings, nth);
+}
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.idl
new file mode 100644
index 00000000000..15d63d6681a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLContentElement.idl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+[
+] interface HTMLContentElement : HTMLElement {
+ [Reflect, TreatNullAs=NullString] attribute DOMString select;
+ NodeList getDistributedNodes();
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp
index 7196698f622..59f54a6e039 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLDListElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -35,9 +35,6 @@ inline HTMLDListElement::HTMLDListElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDListElement> HTMLDListElement::create(Document& document)
-{
- return adoptRef(new HTMLDListElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLDListElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h
index 24aeb814c09..8942e5e29ff 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDListElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLDListElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDListElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLDListElement);
private:
explicit HTMLDListElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp
index d8666e88e91..99f268c9395 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/HTMLDataListElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/IdTargetObserverRegistry.h"
#include "core/frame/UseCounter.h"
@@ -44,13 +44,13 @@ inline HTMLDataListElement::HTMLDataListElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDataListElement> HTMLDataListElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLDataListElement> HTMLDataListElement::create(Document& document)
{
UseCounter::count(document, UseCounter::DataListElement);
- return adoptRef(new HTMLDataListElement(document));
+ return adoptRefWillBeNoop(new HTMLDataListElement(document));
}
-PassRefPtr<HTMLCollection> HTMLDataListElement::options()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLDataListElement::options()
{
return ensureCachedHTMLCollection(DataListOptions);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h
index e19686bfa5c..7d79c7720f3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.h
@@ -39,9 +39,9 @@ namespace WebCore {
class HTMLDataListElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDataListElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLDataListElement> create(Document&);
- PassRefPtr<HTMLCollection> options();
+ PassRefPtrWillBeRawPtr<HTMLCollection> options();
void optionElementChildrenChanged();
@@ -51,8 +51,6 @@ private:
virtual void finishParsingChildren() OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLDataListElement, hasTagName(HTMLNames::datalistTag));
-
} // namespace WebCore
#endif // HTMLDataListElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl
index 93c8663c2bb..4dd3654e759 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDataListElement.idl
@@ -28,8 +28,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- RuntimeEnabled=DataListElement
-] interface HTMLDataListElement : HTMLElement {
+interface HTMLDataListElement : HTMLElement {
readonly attribute HTMLCollection options;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp
index 28c6bbeae6c..b2973cf2e51 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp
@@ -21,12 +21,17 @@
#include "config.h"
#include "core/html/HTMLDetailsElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/events/EventSender.h"
+#include "core/html/HTMLContentElement.h"
+#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLSummaryElement.h"
-#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/shadow/ShadowElementNames.h"
#include "core/rendering/RenderBlockFlow.h"
#include "platform/text/PlatformLocale.h"
@@ -34,9 +39,15 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<HTMLDetailsElement> HTMLDetailsElement::create(Document& document)
+static DetailsEventSender& detailsToggleEventSender()
{
- RefPtr<HTMLDetailsElement> details = adoptRef(new HTMLDetailsElement(document));
+ DEFINE_STATIC_LOCAL(DetailsEventSender, sharedToggleEventSender, (EventTypeNames::toggle));
+ return sharedToggleEventSender;
+}
+
+PassRefPtrWillBeRawPtr<HTMLDetailsElement> HTMLDetailsElement::create(Document& document)
+{
+ RefPtrWillBeRawPtr<HTMLDetailsElement> details = adoptRefWillBeNoop(new HTMLDetailsElement(document));
details->ensureUserAgentShadowRoot();
return details.release();
}
@@ -48,6 +59,18 @@ HTMLDetailsElement::HTMLDetailsElement(Document& document)
ScriptWrappable::init(this);
}
+HTMLDetailsElement::~HTMLDetailsElement()
+{
+ detailsToggleEventSender().cancelEvent(this);
+}
+
+void HTMLDetailsElement::dispatchPendingEvent(DetailsEventSender* eventSender)
+{
+ ASSERT_UNUSED(eventSender, eventSender == &detailsToggleEventSender());
+ dispatchEvent(Event::create(EventTypeNames::toggle));
+}
+
+
RenderObject* HTMLDetailsElement::createRenderer(RenderStyle*)
{
return new RenderBlockFlow(this);
@@ -57,26 +80,29 @@ void HTMLDetailsElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
DEFINE_STATIC_LOCAL(const AtomicString, summarySelector, ("summary:first-of-type", AtomicString::ConstructFromLiteral));
- RefPtr<HTMLSummaryElement> defaultSummary = HTMLSummaryElement::create(document());
+ RefPtrWillBeRawPtr<HTMLSummaryElement> defaultSummary = HTMLSummaryElement::create(document());
defaultSummary->appendChild(Text::create(document(), locale().queryString(blink::WebLocalizedString::DetailsLabel)));
- RefPtr<HTMLContentElement> content = HTMLContentElement::create(document());
- content->setAttribute(selectAttr, summarySelector);
- content->appendChild(defaultSummary);
-
- root.appendChild(content);
- root.appendChild(HTMLContentElement::create(document()));
+ RefPtrWillBeRawPtr<HTMLContentElement> summary = HTMLContentElement::create(document());
+ summary->setIdAttribute(ShadowElementNames::detailsSummary());
+ summary->setAttribute(selectAttr, summarySelector);
+ summary->appendChild(defaultSummary);
+ root.appendChild(summary.release());
+
+ RefPtrWillBeRawPtr<HTMLDivElement> content = HTMLDivElement::create(document());
+ content->setIdAttribute(ShadowElementNames::detailsContent());
+ content->appendChild(HTMLContentElement::create(document()));
+ content->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
+ root.appendChild(content.release());
}
Element* HTMLDetailsElement::findMainSummary() const
{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(summaryTag))
- return toElement(child);
- }
+ if (HTMLSummaryElement* summary = Traversal<HTMLSummaryElement>::firstChild(*this))
+ return summary;
HTMLContentElement* content = toHTMLContentElement(userAgentShadowRoot()->firstChild());
- ASSERT(content->firstChild() && content->firstChild()->hasTagName(summaryTag));
+ ASSERT(content->firstChild() && isHTMLSummaryElement(*content->firstChild()));
return toElement(content->firstChild());
}
@@ -85,20 +111,28 @@ void HTMLDetailsElement::parseAttribute(const QualifiedName& name, const AtomicS
if (name == openAttr) {
bool oldValue = m_isOpen;
m_isOpen = !value.isNull();
- if (oldValue != m_isOpen)
- lazyReattachIfAttached();
- } else
- HTMLElement::parseAttribute(name, value);
-}
-
-bool HTMLDetailsElement::childShouldCreateRenderer(const Node& child) const
-{
- // FIXME: These checks do not look correct, we should just use insertion points instead.
- if (m_isOpen)
- return HTMLElement::childShouldCreateRenderer(child);
- if (!child.hasTagName(summaryTag))
- return false;
- return child == findMainSummary() && HTMLElement::childShouldCreateRenderer(child);
+ if (m_isOpen == oldValue)
+ return;
+
+ // Dispatch toggle event asynchronously.
+ detailsToggleEventSender().cancelEvent(this);
+ detailsToggleEventSender().dispatchEventSoon(this);
+
+ Element* content = ensureUserAgentShadowRoot().getElementById(ShadowElementNames::detailsContent());
+ ASSERT(content);
+ if (m_isOpen)
+ content->removeInlineStyleProperty(CSSPropertyDisplay);
+ else
+ content->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
+ Element* summary = ensureUserAgentShadowRoot().getElementById(ShadowElementNames::detailsSummary());
+ ASSERT(summary);
+ // FIXME: DetailsMarkerControl's RenderDetailsMarker has no concept of being updated
+ // without recreating it causing a repaint. Instead we should change it so we can tell
+ // it to toggle the open/closed triangle state and avoid reattaching the entire summary.
+ summary->lazyReattachIfAttached();
+ return;
+ }
+ HTMLElement::parseAttribute(name, value);
}
void HTMLDetailsElement::toggleOpen()
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h
index d5a6b4a6169..2e9d762d980 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDetailsElement.h
@@ -25,18 +25,23 @@
namespace WebCore {
+template<typename T> class EventSender;
+typedef EventSender<HTMLDetailsElement> DetailsEventSender;
+
class HTMLDetailsElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDetailsElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLDetailsElement> create(Document&);
void toggleOpen();
+ virtual ~HTMLDetailsElement();
+
+ void dispatchPendingEvent(DetailsEventSender*);
Element* findMainSummary() const;
private:
explicit HTMLDetailsElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
virtual bool isInteractiveContent() const OVERRIDE;
@@ -44,18 +49,6 @@ private:
bool m_isOpen;
};
-inline bool isHTMLDetailsElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::detailsTag);
-}
-
-inline bool isHTMLDetailsElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::detailsTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLDetailsElement, hasTagName(HTMLNames::detailsTag));
-
} // namespace WebCore
#endif // HTMLDetailsElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
index 59d5bc04a5e..5eb8125e534 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.cpp
@@ -45,7 +45,7 @@ static void setFocusForModalDialog(HTMLDialogElement* dialog)
Element* focusableDescendant = 0;
Node* next = 0;
for (Node* node = dialog->firstChild(); node; node = next) {
- if (node->hasTagName(dialogTag))
+ if (isHTMLDialogElement(*node))
next = NodeTraversal::nextSkippingChildren(*node, dialog);
else
next = NodeTraversal::next(*node, dialog);
@@ -57,7 +57,6 @@ static void setFocusForModalDialog(HTMLDialogElement* dialog)
HTMLFormControlElement* control = toHTMLFormControlElement(node);
if (control->isAutofocusable()) {
control->focus();
- control->setAutofocused();
return;
}
}
@@ -75,7 +74,7 @@ static void setFocusForModalDialog(HTMLDialogElement* dialog)
return;
}
- dialog->document().setFocusedElement(0);
+ dialog->document().setFocusedElement(nullptr);
}
static void inertSubtreesChanged(Document& document)
@@ -84,25 +83,22 @@ static void inertSubtreesChanged(Document& document)
// tree can change inertness which means they must be added or removed from
// the tree. The most foolproof way is to clear the entire tree and rebuild
// it, though a more clever way is probably possible.
- Document* topDocument = document.topDocument();
- topDocument->clearAXObjectCache();
- if (AXObjectCache* cache = topDocument->axObjectCache())
- cache->childrenChanged(cache->getOrCreate(topDocument));
+ Document& topDocument = document.topDocument();
+ topDocument.clearAXObjectCache();
+ if (AXObjectCache* cache = topDocument.axObjectCache())
+ cache->childrenChanged(cache->getOrCreate(&topDocument));
}
-HTMLDialogElement::HTMLDialogElement(Document& document)
+inline HTMLDialogElement::HTMLDialogElement(Document& document)
: HTMLElement(dialogTag, document)
- , m_centeringMode(Uninitialized)
+ , m_centeringMode(NotCentered)
, m_centeredPosition(0)
, m_returnValue("")
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDialogElement> HTMLDialogElement::create(Document& document)
-{
- return adoptRef(new HTMLDialogElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLDialogElement)
void HTMLDialogElement::close(const String& returnValue, ExceptionState& exceptionState)
{
@@ -132,10 +128,10 @@ void HTMLDialogElement::closeDialog(const String& returnValue)
void HTMLDialogElement::forceLayoutForCentering()
{
- m_centeringMode = Uninitialized;
+ m_centeringMode = NeedsCentering;
document().updateLayoutIgnorePendingStylesheets();
- if (m_centeringMode == Uninitialized)
- m_centeringMode = NotCentered;
+ if (m_centeringMode == NeedsCentering)
+ setNotCentered();
}
void HTMLDialogElement::show()
@@ -143,7 +139,6 @@ void HTMLDialogElement::show()
if (fastHasAttribute(openAttr))
return;
setBooleanAttribute(openAttr, true);
- forceLayoutForCentering();
}
void HTMLDialogElement::showModal(ExceptionState& exceptionState)
@@ -168,16 +163,22 @@ void HTMLDialogElement::showModal(ExceptionState& exceptionState)
setFocusForModalDialog(this);
}
+void HTMLDialogElement::removedFrom(ContainerNode* insertionPoint)
+{
+ HTMLElement::removedFrom(insertionPoint);
+ setNotCentered();
+ // FIXME: We should call inertSubtreesChanged() here.
+}
+
void HTMLDialogElement::setCentered(LayoutUnit centeredPosition)
{
- ASSERT(m_centeringMode == Uninitialized);
+ ASSERT(m_centeringMode == NeedsCentering);
m_centeredPosition = centeredPosition;
m_centeringMode = Centered;
}
void HTMLDialogElement::setNotCentered()
{
- ASSERT(m_centeringMode == Uninitialized);
m_centeringMode = NotCentered;
}
@@ -201,11 +202,4 @@ void HTMLDialogElement::defaultEventHandler(Event* event)
HTMLElement::defaultEventHandler(event);
}
-bool HTMLDialogElement::shouldBeReparentedUnderRenderView(const RenderStyle* style) const
-{
- if (style && style->position() == AbsolutePosition)
- return true;
- return Element::shouldBeReparentedUnderRenderView(style);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h
index 248044e98f8..2f003c9dc95 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.h
@@ -26,7 +26,6 @@
#ifndef HTMLDialogElement_h
#define HTMLDialogElement_h
-#include "RuntimeEnabledFeatures.h"
#include "core/html/HTMLElement.h"
namespace WebCore {
@@ -37,14 +36,18 @@ class QualifiedName;
class HTMLDialogElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDialogElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLDialogElement);
void close(const String& returnValue, ExceptionState&);
void closeDialog(const String& returnValue = String());
void show();
void showModal(ExceptionState&);
+ virtual void removedFrom(ContainerNode*) OVERRIDE;
- enum CenteringMode { Uninitialized, Centered, NotCentered };
+ // NotCentered means do not center the dialog. Centered means the dialog has
+ // been centered and centeredPosition() is set. NeedsCentering means attempt
+ // to center on the next layout, then set to Centered or NotCentered.
+ enum CenteringMode { NotCentered, Centered, NeedsCentering };
CenteringMode centeringMode() const { return m_centeringMode; }
LayoutUnit centeredPosition() const
{
@@ -62,7 +65,6 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual bool shouldBeReparentedUnderRenderView(const RenderStyle*) const OVERRIDE;
void forceLayoutForCentering();
@@ -71,13 +73,6 @@ private:
String m_returnValue;
};
-inline HTMLDialogElement* toHTMLDialogElement(Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->hasTagName(HTMLNames::dialogTag));
- ASSERT_WITH_SECURITY_IMPLICATION(RuntimeEnabledFeatures::dialogElementEnabled());
- return static_cast<HTMLDialogElement*>(node);
-}
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl
index 6c2d0c8c0fe..c26e3941dce 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDialogElement.idl
@@ -28,7 +28,7 @@
] interface HTMLDialogElement : HTMLElement {
[Reflect] attribute boolean open;
attribute DOMString returnValue;
- [RaisesException] void close([Default=NullString] optional DOMString returnValue);
+ [RaisesException] void close(optional DOMString returnValue = null);
void show();
[RaisesException] void showModal();
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp
index 2010c5a5178..8d739dc3d7e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLDirectoryElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -35,9 +35,6 @@ inline HTMLDirectoryElement::HTMLDirectoryElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDirectoryElement> HTMLDirectoryElement::create(Document& document)
-{
- return adoptRef(new HTMLDirectoryElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLDirectoryElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h
index 7c0dcaa7951..fc2a0792ef9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDirectoryElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLDirectoryElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLDirectoryElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLDirectoryElement);
private:
explicit HTMLDirectoryElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp
index af3d8938783..29d4ce2f7e5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.cpp
@@ -23,9 +23,9 @@
#include "config.h"
#include "core/html/HTMLDivElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -37,17 +37,7 @@ HTMLDivElement::HTMLDivElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLDivElement> HTMLDivElement::create(Document& document)
-{
- return adoptRef(new HTMLDivElement(document));
-}
-
-bool HTMLDivElement::isPresentationAttribute(const QualifiedName& name) const
-{
- if (name == alignAttr)
- return true;
- return HTMLElement::isPresentationAttribute(name);
-}
+DEFINE_NODE_FACTORY(HTMLDivElement)
void HTMLDivElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h
index 12e230088b2..37279ed111d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDivElement.h
@@ -29,18 +29,15 @@ namespace WebCore {
class HTMLDivElement : public HTMLElement {
public:
- static PassRefPtr<HTMLDivElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLDivElement);
protected:
explicit HTMLDivElement(Document&);
private:
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLDivElement, hasTagName(HTMLNames::divTag));
-
} // namespace WebCore
#endif // HTMLDivElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp
index 761a6e3093a..298f8b6e91d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.cpp
@@ -53,11 +53,11 @@
#include "config.h"
#include "core/html/HTMLDocument.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptController.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/HTMLNames.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLBodyElement.h"
#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
@@ -73,69 +73,20 @@ HTMLDocument::HTMLDocument(const DocumentInit& initializer, DocumentClassFlags e
{
ScriptWrappable::init(this);
clearXMLVersion();
+ if (isSrcdocDocument() || initializer.importsController()) {
+ ASSERT(inNoQuirksMode());
+ lockCompatibilityMode();
+ }
}
HTMLDocument::~HTMLDocument()
{
}
-const AtomicString& HTMLDocument::dir()
-{
- HTMLElement* b = body();
- if (!b)
- return nullAtom;
- return b->getAttribute(dirAttr);
-}
-
-void HTMLDocument::setDir(const AtomicString& value)
-{
- HTMLElement* b = body();
- if (b)
- b->setAttribute(dirAttr, value);
-}
-
-String HTMLDocument::designMode() const
-{
- return inDesignMode() ? "on" : "off";
-}
-
-void HTMLDocument::setDesignMode(const String& value)
-{
- InheritedBool mode;
- if (equalIgnoringCase(value, "on"))
- mode = on;
- else if (equalIgnoringCase(value, "off"))
- mode = off;
- else
- mode = inherit;
- Document::setDesignMode(mode);
-}
-
-Element* HTMLDocument::activeElement()
-{
- if (Element* element = treeScope().adjustedFocusedElement())
- return element;
- return body();
-}
-
-bool HTMLDocument::hasFocus()
-{
- Page* page = this->page();
- if (!page)
- return false;
- if (!page->focusController().isActive() || !page->focusController().isFocused())
- return false;
- if (Frame* focusedFrame = page->focusController().focusedFrame()) {
- if (focusedFrame->tree().isDescendantOf(frame()))
- return true;
- }
- return false;
-}
-
HTMLBodyElement* HTMLDocument::htmlBodyElement() const
{
HTMLElement* body = this->body();
- return (body && body->hasTagName(bodyTag)) ? toHTMLBodyElement(body) : 0;
+ return isHTMLBodyElement(body) ? toHTMLBodyElement(body) : 0;
}
const AtomicString& HTMLDocument::bodyAttributeValue(const QualifiedName& name) const
@@ -207,7 +158,7 @@ void HTMLDocument::setVlinkColor(const AtomicString& value)
setBodyAttribute(vlinkAttr, value);
}
-PassRefPtr<Document> HTMLDocument::cloneDocumentWithoutChildren()
+PassRefPtrWillBeRawPtr<Document> HTMLDocument::cloneDocumentWithoutChildren()
{
return create(DocumentInit(url()).withRegistrationContext(registrationContext()));
}
@@ -221,7 +172,7 @@ void HTMLDocument::addItemToMap(HashCountedSet<AtomicString>& map, const AtomicS
if (name.isEmpty())
return;
map.add(name);
- if (Frame* f = frame())
+ if (LocalFrame* f = frame())
f->script().namedItemAdded(this, name);
}
@@ -230,7 +181,7 @@ void HTMLDocument::removeItemFromMap(HashCountedSet<AtomicString>& map, const At
if (name.isEmpty())
return;
map.remove(name);
- if (Frame* f = frame())
+ if (LocalFrame* f = frame())
f->script().namedItemRemoved(this, name);
}
@@ -321,29 +272,22 @@ bool HTMLDocument::isCaseSensitiveAttribute(const QualifiedName& attributeName)
return !isPossibleHTMLAttr || !htmlCaseInsensitiveAttributesSet->contains(attributeName.localName().impl());
}
-void HTMLDocument::clear()
-{
- // FIXME: This does nothing, and that seems unlikely to be correct.
- // We've long had a comment saying that IE doesn't support this.
- // But I do see it in the documentation for Mozilla.
-}
-
-void HTMLDocument::write(DOMWindow* activeWindow, const Vector<String>& text)
+void HTMLDocument::write(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
{
- ASSERT(activeWindow);
+ ASSERT(callingWindow);
StringBuilder builder;
for (size_t i = 0; i < text.size(); ++i)
builder.append(text[i]);
- write(builder.toString(), activeWindow->document());
+ write(builder.toString(), callingWindow->document(), exceptionState);
}
-void HTMLDocument::writeln(DOMWindow* activeWindow, const Vector<String>& text)
+void HTMLDocument::writeln(LocalDOMWindow* callingWindow, const Vector<String>& text, ExceptionState& exceptionState)
{
- ASSERT(activeWindow);
+ ASSERT(callingWindow);
StringBuilder builder;
for (size_t i = 0; i < text.size(); ++i)
builder.append(text[i]);
- writeln(builder.toString(), activeWindow->document());
+ writeln(builder.toString(), callingWindow->document(), exceptionState);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.h b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.h
index aa52f77ac85..f89c1b7639f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.h
@@ -35,21 +35,12 @@ class HTMLElement;
class HTMLDocument : public Document, public ResourceClient {
public:
- static PassRefPtr<HTMLDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<HTMLDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new HTMLDocument(initializer));
+ return adoptRefWillBeNoop(new HTMLDocument(initializer));
}
virtual ~HTMLDocument();
- const AtomicString& dir();
- void setDir(const AtomicString&);
-
- String designMode() const;
- void setDesignMode(const String&);
-
- Element* activeElement();
- bool hasFocus();
-
const AtomicString& bgColor() const;
void setBgColor(const AtomicString&);
const AtomicString& fgColor() const;
@@ -61,7 +52,7 @@ public:
const AtomicString& vlinkColor() const;
void setVlinkColor(const AtomicString&);
- void clear();
+ void clear() { }
void captureEvents() { }
void releaseEvents() { }
@@ -76,12 +67,12 @@ public:
using Document::write;
using Document::writeln;
- void write(DOMWindow*, const Vector<String>& text);
- void writeln(DOMWindow*, const Vector<String>& text);
+ void write(LocalDOMWindow*, const Vector<String>& text, ExceptionState&);
+ void writeln(LocalDOMWindow*, const Vector<String>& text, ExceptionState&);
static bool isCaseSensitiveAttribute(const QualifiedName&);
- virtual PassRefPtr<Document> cloneDocumentWithoutChildren() OVERRIDE FINAL;
+ virtual PassRefPtrWillBeRawPtr<Document> cloneDocumentWithoutChildren() OVERRIDE FINAL;
protected:
HTMLDocument(const DocumentInit&, DocumentClassFlags extendedDocumentClasses = DefaultDocumentClass);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl
index 84328c8565f..04ba97f3187 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLDocument.idl
@@ -18,36 +18,30 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLDocument : Document {
+[
+ // FIXME: Oilpan: remove this once Node specifies WillBeGarbageCollected.
+ WillBeGarbageCollected
+] interface HTMLDocument : Document {
[Custom, CustomElementCallbacks] void open();
- void close();
+ [RaisesException] void close();
// We support multiple DOMString arguments to match FF / IE, e.g.:
// document.write("a", "b", "c") --> document.write("abc")
// document.write() --> document.write("")
- [CallWith=ActiveWindow, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, CustomElementCallbacks] void write(DOMString... text);
- [CallWith=ActiveWindow, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, CustomElementCallbacks] void writeln(DOMString... text);
-
- readonly attribute HTMLCollection embeds;
- [ImplementedAs=embeds] readonly attribute HTMLCollection plugins;
- readonly attribute HTMLCollection scripts;
+ [CallWith=ActiveWindow,LogActivity, CustomElementCallbacks, RaisesException] void write(DOMString... text);
+ [CallWith=ActiveWindow, LogActivity, CustomElementCallbacks, RaisesException] void writeln(DOMString... text);
// Extensions
[Replaceable, ImplementedAs=allForBinding] readonly attribute HTMLAllCollection all;
- [DeprecateAs=DocumentClear] void clear();
+ [MeasureAs=DocumentClear] void clear();
- [DeprecateAs=CaptureEvents] void captureEvents();
- [DeprecateAs=ReleaseEvents] void releaseEvents();
+ [MeasureAs=DocumentCaptureEvents] void captureEvents();
+ [MeasureAs=DocumentReleaseEvents] void releaseEvents();
- [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString dir;
- [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString designMode;
readonly attribute DOMString compatMode;
- readonly attribute Element activeElement;
- boolean hasFocus();
-
// Deprecated attributes
[TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString bgColor;
[TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString fgColor;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp
index 8fcff5b5bfb..6a64bc4b5b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLElement.cpp
@@ -25,35 +25,34 @@
#include "config.h"
#include "core/html/HTMLElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
-#include "XMLNames.h"
#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptEventListener.h"
-#include "core/css/CSSParser.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
+#include "core/XMLNames.h"
+#include "core/css/CSSMarkup.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/Text.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/markup.h"
#include "core/events/EventListener.h"
#include "core/events/KeyboardEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLBRElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLTemplateElement.h"
#include "core/html/HTMLTextFormControlElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
-#include "core/rendering/RenderWordBreak.h"
+#include "core/rendering/RenderObject.h"
#include "platform/text/BidiResolver.h"
+#include "platform/text/BidiTextRun.h"
#include "platform/text/TextRunIterator.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/CString.h"
@@ -66,18 +65,18 @@ using namespace WTF;
using std::min;
using std::max;
-PassRefPtr<HTMLElement> HTMLElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLElement);
String HTMLElement::nodeName() const
{
// FIXME: Would be nice to have an atomicstring lookup based off uppercase
// chars that does not have to copy the string on a hit in the hash.
// FIXME: We should have a way to detect XHTML elements and replace the hasPrefix() check with it.
- if (document().isHTMLDocument() && !tagQName().hasPrefix())
- return tagQName().localNameUpper();
+ if (document().isHTMLDocument()) {
+ if (!tagQName().hasPrefix())
+ return tagQName().localNameUpper();
+ return Element::nodeName().upper();
+ }
return Element::nodeName();
}
@@ -101,7 +100,6 @@ bool HTMLElement::ieForbidsInsertHTML() const
|| hasLocalName(imageTag)
|| hasLocalName(imgTag)
|| hasLocalName(inputTag)
- || hasLocalName(isindexTag)
|| hasLocalName(linkTag)
|| hasLocalName(metaTag)
|| hasLocalName(paramTag)
@@ -204,95 +202,102 @@ void HTMLElement::collectStyleForPresentationAttribute(const QualifiedName& name
Element::collectStyleForPresentationAttribute(name, value, style);
}
-const AtomicString& HTMLElement::eventNameForAttributeName(const QualifiedName& attrName) const
+const AtomicString& HTMLElement::eventNameForAttributeName(const QualifiedName& attrName)
{
if (!attrName.namespaceURI().isNull())
return nullAtom;
+ if (!attrName.localName().startsWith("on", false))
+ return nullAtom;
+
typedef HashMap<AtomicString, AtomicString> StringToStringMap;
DEFINE_STATIC_LOCAL(StringToStringMap, attributeNameToEventNameMap, ());
if (!attributeNameToEventNameMap.size()) {
- attributeNameToEventNameMap.set(onanimationstartAttr.localName(), EventTypeNames::animationstart);
- attributeNameToEventNameMap.set(onanimationiterationAttr.localName(), EventTypeNames::animationiteration);
+ attributeNameToEventNameMap.set(onabortAttr.localName(), EventTypeNames::abort);
attributeNameToEventNameMap.set(onanimationendAttr.localName(), EventTypeNames::animationend);
+ attributeNameToEventNameMap.set(onanimationiterationAttr.localName(), EventTypeNames::animationiteration);
+ attributeNameToEventNameMap.set(onanimationstartAttr.localName(), EventTypeNames::animationstart);
+ attributeNameToEventNameMap.set(onautocompleteAttr.localName(), EventTypeNames::autocomplete);
+ attributeNameToEventNameMap.set(onautocompleteerrorAttr.localName(), EventTypeNames::autocompleteerror);
+ attributeNameToEventNameMap.set(onbeforecopyAttr.localName(), EventTypeNames::beforecopy);
+ attributeNameToEventNameMap.set(onbeforecutAttr.localName(), EventTypeNames::beforecut);
+ attributeNameToEventNameMap.set(onbeforepasteAttr.localName(), EventTypeNames::beforepaste);
+ attributeNameToEventNameMap.set(onblurAttr.localName(), EventTypeNames::blur);
attributeNameToEventNameMap.set(oncancelAttr.localName(), EventTypeNames::cancel);
+ attributeNameToEventNameMap.set(oncanplayAttr.localName(), EventTypeNames::canplay);
+ attributeNameToEventNameMap.set(oncanplaythroughAttr.localName(), EventTypeNames::canplaythrough);
+ attributeNameToEventNameMap.set(onchangeAttr.localName(), EventTypeNames::change);
attributeNameToEventNameMap.set(onclickAttr.localName(), EventTypeNames::click);
attributeNameToEventNameMap.set(oncloseAttr.localName(), EventTypeNames::close);
attributeNameToEventNameMap.set(oncontextmenuAttr.localName(), EventTypeNames::contextmenu);
- attributeNameToEventNameMap.set(ondblclickAttr.localName(), EventTypeNames::dblclick);
- attributeNameToEventNameMap.set(onmousedownAttr.localName(), EventTypeNames::mousedown);
- attributeNameToEventNameMap.set(onmouseenterAttr.localName(), EventTypeNames::mouseenter);
- attributeNameToEventNameMap.set(onmouseleaveAttr.localName(), EventTypeNames::mouseleave);
- attributeNameToEventNameMap.set(onmousemoveAttr.localName(), EventTypeNames::mousemove);
- attributeNameToEventNameMap.set(onmouseoutAttr.localName(), EventTypeNames::mouseout);
- attributeNameToEventNameMap.set(onmouseoverAttr.localName(), EventTypeNames::mouseover);
- attributeNameToEventNameMap.set(onmouseupAttr.localName(), EventTypeNames::mouseup);
- attributeNameToEventNameMap.set(onmousewheelAttr.localName(), EventTypeNames::mousewheel);
- attributeNameToEventNameMap.set(onwheelAttr.localName(), EventTypeNames::wheel);
- attributeNameToEventNameMap.set(onfocusAttr.localName(), EventTypeNames::focus);
- attributeNameToEventNameMap.set(onfocusinAttr.localName(), EventTypeNames::focusin);
- attributeNameToEventNameMap.set(onfocusoutAttr.localName(), EventTypeNames::focusout);
- attributeNameToEventNameMap.set(onblurAttr.localName(), EventTypeNames::blur);
- attributeNameToEventNameMap.set(onkeydownAttr.localName(), EventTypeNames::keydown);
- attributeNameToEventNameMap.set(onkeypressAttr.localName(), EventTypeNames::keypress);
- attributeNameToEventNameMap.set(onkeyupAttr.localName(), EventTypeNames::keyup);
- attributeNameToEventNameMap.set(onscrollAttr.localName(), EventTypeNames::scroll);
- attributeNameToEventNameMap.set(onbeforecutAttr.localName(), EventTypeNames::beforecut);
- attributeNameToEventNameMap.set(oncutAttr.localName(), EventTypeNames::cut);
- attributeNameToEventNameMap.set(onbeforecopyAttr.localName(), EventTypeNames::beforecopy);
attributeNameToEventNameMap.set(oncopyAttr.localName(), EventTypeNames::copy);
- attributeNameToEventNameMap.set(onbeforepasteAttr.localName(), EventTypeNames::beforepaste);
- attributeNameToEventNameMap.set(onpasteAttr.localName(), EventTypeNames::paste);
+ attributeNameToEventNameMap.set(oncuechangeAttr.localName(), EventTypeNames::cuechange);
+ attributeNameToEventNameMap.set(oncutAttr.localName(), EventTypeNames::cut);
+ attributeNameToEventNameMap.set(ondblclickAttr.localName(), EventTypeNames::dblclick);
+ attributeNameToEventNameMap.set(ondragAttr.localName(), EventTypeNames::drag);
+ attributeNameToEventNameMap.set(ondragendAttr.localName(), EventTypeNames::dragend);
attributeNameToEventNameMap.set(ondragenterAttr.localName(), EventTypeNames::dragenter);
- attributeNameToEventNameMap.set(ondragoverAttr.localName(), EventTypeNames::dragover);
attributeNameToEventNameMap.set(ondragleaveAttr.localName(), EventTypeNames::dragleave);
- attributeNameToEventNameMap.set(ondropAttr.localName(), EventTypeNames::drop);
+ attributeNameToEventNameMap.set(ondragoverAttr.localName(), EventTypeNames::dragover);
attributeNameToEventNameMap.set(ondragstartAttr.localName(), EventTypeNames::dragstart);
- attributeNameToEventNameMap.set(ondragAttr.localName(), EventTypeNames::drag);
- attributeNameToEventNameMap.set(ondragendAttr.localName(), EventTypeNames::dragend);
- attributeNameToEventNameMap.set(onselectstartAttr.localName(), EventTypeNames::selectstart);
- attributeNameToEventNameMap.set(onsubmitAttr.localName(), EventTypeNames::submit);
- attributeNameToEventNameMap.set(onerrorAttr.localName(), EventTypeNames::error);
- attributeNameToEventNameMap.set(onwebkitanimationstartAttr.localName(), EventTypeNames::webkitAnimationStart);
- attributeNameToEventNameMap.set(onwebkitanimationiterationAttr.localName(), EventTypeNames::webkitAnimationIteration);
- attributeNameToEventNameMap.set(onwebkitanimationendAttr.localName(), EventTypeNames::webkitAnimationEnd);
- attributeNameToEventNameMap.set(onwebkittransitionendAttr.localName(), EventTypeNames::webkitTransitionEnd);
- attributeNameToEventNameMap.set(ontransitionendAttr.localName(), EventTypeNames::webkitTransitionEnd);
- attributeNameToEventNameMap.set(oninputAttr.localName(), EventTypeNames::input);
- attributeNameToEventNameMap.set(oninvalidAttr.localName(), EventTypeNames::invalid);
- attributeNameToEventNameMap.set(ontouchstartAttr.localName(), EventTypeNames::touchstart);
- attributeNameToEventNameMap.set(ontouchmoveAttr.localName(), EventTypeNames::touchmove);
- attributeNameToEventNameMap.set(ontouchendAttr.localName(), EventTypeNames::touchend);
- attributeNameToEventNameMap.set(ontouchcancelAttr.localName(), EventTypeNames::touchcancel);
- attributeNameToEventNameMap.set(onwebkitfullscreenchangeAttr.localName(), EventTypeNames::webkitfullscreenchange);
- attributeNameToEventNameMap.set(onwebkitfullscreenerrorAttr.localName(), EventTypeNames::webkitfullscreenerror);
- attributeNameToEventNameMap.set(onabortAttr.localName(), EventTypeNames::abort);
- attributeNameToEventNameMap.set(oncanplayAttr.localName(), EventTypeNames::canplay);
- attributeNameToEventNameMap.set(oncanplaythroughAttr.localName(), EventTypeNames::canplaythrough);
- attributeNameToEventNameMap.set(onchangeAttr.localName(), EventTypeNames::change);
- attributeNameToEventNameMap.set(oncuechangeAttr.localName(), EventTypeNames::cuechange);
+ attributeNameToEventNameMap.set(ondropAttr.localName(), EventTypeNames::drop);
attributeNameToEventNameMap.set(ondurationchangeAttr.localName(), EventTypeNames::durationchange);
attributeNameToEventNameMap.set(onemptiedAttr.localName(), EventTypeNames::emptied);
attributeNameToEventNameMap.set(onendedAttr.localName(), EventTypeNames::ended);
+ attributeNameToEventNameMap.set(onerrorAttr.localName(), EventTypeNames::error);
+ attributeNameToEventNameMap.set(onfocusAttr.localName(), EventTypeNames::focus);
+ attributeNameToEventNameMap.set(onfocusinAttr.localName(), EventTypeNames::focusin);
+ attributeNameToEventNameMap.set(onfocusoutAttr.localName(), EventTypeNames::focusout);
+ attributeNameToEventNameMap.set(oninputAttr.localName(), EventTypeNames::input);
+ attributeNameToEventNameMap.set(oninvalidAttr.localName(), EventTypeNames::invalid);
+ attributeNameToEventNameMap.set(onkeydownAttr.localName(), EventTypeNames::keydown);
+ attributeNameToEventNameMap.set(onkeypressAttr.localName(), EventTypeNames::keypress);
+ attributeNameToEventNameMap.set(onkeyupAttr.localName(), EventTypeNames::keyup);
+ attributeNameToEventNameMap.set(onloadAttr.localName(), EventTypeNames::load);
attributeNameToEventNameMap.set(onloadeddataAttr.localName(), EventTypeNames::loadeddata);
attributeNameToEventNameMap.set(onloadedmetadataAttr.localName(), EventTypeNames::loadedmetadata);
attributeNameToEventNameMap.set(onloadstartAttr.localName(), EventTypeNames::loadstart);
+ attributeNameToEventNameMap.set(onmousedownAttr.localName(), EventTypeNames::mousedown);
+ attributeNameToEventNameMap.set(onmouseenterAttr.localName(), EventTypeNames::mouseenter);
+ attributeNameToEventNameMap.set(onmouseleaveAttr.localName(), EventTypeNames::mouseleave);
+ attributeNameToEventNameMap.set(onmousemoveAttr.localName(), EventTypeNames::mousemove);
+ attributeNameToEventNameMap.set(onmouseoutAttr.localName(), EventTypeNames::mouseout);
+ attributeNameToEventNameMap.set(onmouseoverAttr.localName(), EventTypeNames::mouseover);
+ attributeNameToEventNameMap.set(onmouseupAttr.localName(), EventTypeNames::mouseup);
+ attributeNameToEventNameMap.set(onmousewheelAttr.localName(), EventTypeNames::mousewheel);
+ attributeNameToEventNameMap.set(onpasteAttr.localName(), EventTypeNames::paste);
attributeNameToEventNameMap.set(onpauseAttr.localName(), EventTypeNames::pause);
attributeNameToEventNameMap.set(onplayAttr.localName(), EventTypeNames::play);
attributeNameToEventNameMap.set(onplayingAttr.localName(), EventTypeNames::playing);
attributeNameToEventNameMap.set(onprogressAttr.localName(), EventTypeNames::progress);
attributeNameToEventNameMap.set(onratechangeAttr.localName(), EventTypeNames::ratechange);
attributeNameToEventNameMap.set(onresetAttr.localName(), EventTypeNames::reset);
+ attributeNameToEventNameMap.set(onresizeAttr.localName(), EventTypeNames::resize);
+ attributeNameToEventNameMap.set(onscrollAttr.localName(), EventTypeNames::scroll);
attributeNameToEventNameMap.set(onseekedAttr.localName(), EventTypeNames::seeked);
attributeNameToEventNameMap.set(onseekingAttr.localName(), EventTypeNames::seeking);
attributeNameToEventNameMap.set(onselectAttr.localName(), EventTypeNames::select);
+ attributeNameToEventNameMap.set(onselectstartAttr.localName(), EventTypeNames::selectstart);
attributeNameToEventNameMap.set(onshowAttr.localName(), EventTypeNames::show);
attributeNameToEventNameMap.set(onstalledAttr.localName(), EventTypeNames::stalled);
+ attributeNameToEventNameMap.set(onsubmitAttr.localName(), EventTypeNames::submit);
attributeNameToEventNameMap.set(onsuspendAttr.localName(), EventTypeNames::suspend);
attributeNameToEventNameMap.set(ontimeupdateAttr.localName(), EventTypeNames::timeupdate);
+ attributeNameToEventNameMap.set(ontoggleAttr.localName(), EventTypeNames::toggle);
+ attributeNameToEventNameMap.set(ontouchcancelAttr.localName(), EventTypeNames::touchcancel);
+ attributeNameToEventNameMap.set(ontouchendAttr.localName(), EventTypeNames::touchend);
+ attributeNameToEventNameMap.set(ontouchmoveAttr.localName(), EventTypeNames::touchmove);
+ attributeNameToEventNameMap.set(ontouchstartAttr.localName(), EventTypeNames::touchstart);
+ attributeNameToEventNameMap.set(ontransitionendAttr.localName(), EventTypeNames::webkitTransitionEnd);
attributeNameToEventNameMap.set(onvolumechangeAttr.localName(), EventTypeNames::volumechange);
attributeNameToEventNameMap.set(onwaitingAttr.localName(), EventTypeNames::waiting);
- attributeNameToEventNameMap.set(onloadAttr.localName(), EventTypeNames::load);
+ attributeNameToEventNameMap.set(onwebkitanimationendAttr.localName(), EventTypeNames::webkitAnimationEnd);
+ attributeNameToEventNameMap.set(onwebkitanimationiterationAttr.localName(), EventTypeNames::webkitAnimationIteration);
+ attributeNameToEventNameMap.set(onwebkitanimationstartAttr.localName(), EventTypeNames::webkitAnimationStart);
+ attributeNameToEventNameMap.set(onwebkitfullscreenchangeAttr.localName(), EventTypeNames::webkitfullscreenchange);
+ attributeNameToEventNameMap.set(onwebkitfullscreenerrorAttr.localName(), EventTypeNames::webkitfullscreenerror);
+ attributeNameToEventNameMap.set(onwebkittransitionendAttr.localName(), EventTypeNames::webkitTransitionEnd);
+ attributeNameToEventNameMap.set(onwheelAttr.localName(), EventTypeNames::wheel);
}
return attributeNameToEventNameMap.get(attrName.localName());
@@ -300,37 +305,24 @@ const AtomicString& HTMLElement::eventNameForAttributeName(const QualifiedName&
void HTMLElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (isIdAttributeName(name) || name == classAttr || name == styleAttr)
+ if (name == tabindexAttr)
return Element::parseAttribute(name, value);
- if (name == dirAttr)
+ if (name == dirAttr) {
dirAttributeChanged(value);
- else if (name == tabindexAttr) {
- int tabindex = 0;
- if (value.isEmpty()) {
- clearTabIndexExplicitlyIfNeeded();
- if (treeScope().adjustedFocusedElement() == this) {
- // We might want to call blur(), but it's dangerous to dispatch
- // events here.
- document().setNeedsFocusedElementCheck();
- }
- } else if (parseHTMLInteger(value, tabindex)) {
- // Clamp tabindex to the range of 'short' to match Firefox's behavior.
- setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
- }
} else {
const AtomicString& eventName = eventNameForAttributeName(name);
if (!eventName.isNull())
- setAttributeEventListener(eventName, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(eventName, createAttributeEventListener(this, name, value, eventParameterName()));
}
}
-PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionState& exceptionState)
{
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
- unsigned int i, length = text.length();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document());
+ unsigned i, length = text.length();
UChar c = 0;
- for (unsigned int start = 0; start < length; ) {
+ for (unsigned start = 0; start < length; ) {
// Find next line break.
for (i = start; i < length; i++) {
@@ -341,12 +333,12 @@ PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, Exc
fragment->appendChild(Text::create(document(), text.substring(start, i - start)), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
if (c == '\r' || c == '\n') {
fragment->appendChild(HTMLBRElement::create(document()), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
// Make sure \r\n doesn't result in two line breaks.
if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
i++;
@@ -400,7 +392,7 @@ void HTMLElement::setInnerText(const String& text, ExceptionState& exceptionStat
}
// Add text nodes and <br> elements.
- RefPtr<DocumentFragment> fragment = textToFragment(text, exceptionState);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = textToFragment(text, exceptionState);
if (!exceptionState.hadException())
replaceChildrenWithFragment(this, fragment.release(), exceptionState);
}
@@ -425,9 +417,9 @@ void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
return;
}
- RefPtr<Node> prev = previousSibling();
- RefPtr<Node> next = nextSibling();
- RefPtr<Node> newChild;
+ RefPtrWillBeRawPtr<Node> prev = previousSibling();
+ RefPtrWillBeRawPtr<Node> next = nextSibling();
+ RefPtrWillBeRawPtr<Node> newChild = nullptr;
// Convert text to fragment with <br> tags instead of linebreaks if needed.
if (text.contains('\r') || text.contains('\n'))
@@ -436,7 +428,7 @@ void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
newChild = Text::create(document(), text);
// textToFragment might cause mutation events.
- if (!this || !parentNode())
+ if (!parentNode())
exceptionState.throwDOMException(HierarchyRequestError, "The element has no parent.");
if (exceptionState.hadException())
@@ -444,7 +436,7 @@ void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
parent->replaceChild(newChild.release(), this, exceptionState);
- RefPtr<Node> node = next ? next->previousSibling() : 0;
+ RefPtrWillBeRawPtr<Node> node = next ? next->previousSibling() : nullptr;
if (!exceptionState.hadException() && node && node->isTextNode())
mergeWithNextTextNode(node.release(), exceptionState);
@@ -452,24 +444,6 @@ void HTMLElement::setOuterText(const String &text, ExceptionState& exceptionStat
mergeWithNextTextNode(prev.release(), exceptionState);
}
-Element* HTMLElement::insertAdjacentElement(const String& where, Element* newChild, ExceptionState& exceptionState)
-{
- if (!newChild) {
- // IE throws COM Exception E_INVALIDARG; this is the best DOM exception alternative.
- exceptionState.throwTypeError("The node provided is null.");
- return 0;
- }
-
- Node* returnValue = insertAdjacent(where, newChild, exceptionState);
- return toElement(returnValue);
-}
-
-void HTMLElement::insertAdjacentText(const String& where, const String& text, ExceptionState& exceptionState)
-{
- RefPtr<Text> textNode = document().createTextNode(text);
- insertAdjacent(where, textNode.get(), exceptionState);
-}
-
void HTMLElement::applyAlignmentAttributeToStyle(const AtomicString& alignment, MutableStylePropertySet* style)
{
// Vertical alignment with respect to the current baseline of the text
@@ -510,33 +484,6 @@ bool HTMLElement::hasCustomFocusLogic() const
return false;
}
-bool HTMLElement::supportsSpatialNavigationFocus() const
-{
- // This function checks whether the element satisfies the extended criteria
- // for the element to be focusable, introduced by spatial navigation feature,
- // i.e. checks if click or keyboard event handler is specified.
- // This is the way to make it possible to navigate to (focus) elements
- // which web designer meant for being active (made them respond to click events).
-
- if (!document().settings() || !document().settings()->spatialNavigationEnabled())
- return false;
- return hasEventListeners(EventTypeNames::click)
- || hasEventListeners(EventTypeNames::keydown)
- || hasEventListeners(EventTypeNames::keypress)
- || hasEventListeners(EventTypeNames::keyup);
-}
-
-bool HTMLElement::supportsFocus() const
-{
- // FIXME: supportsFocus() can be called when layout is not up to date.
- // Logic that deals with the renderer should be moved to rendererIsFocusable().
- // But supportsFocus must return true when the element is editable, or else
- // it won't be focusable. Furthermore, supportsFocus cannot just return true
- // always or else tabIndex() will change for all HTML elements.
- return Element::supportsFocus() || (rendererIsEditable() && parentNode() && !parentNode()->rendererIsEditable())
- || supportsSpatialNavigationFocus();
-}
-
String HTMLElement::contentEditable() const
{
const AtomicString& value = fastGetAttribute(contenteditableAttr);
@@ -600,7 +547,7 @@ void HTMLElement::accessKeyAction(bool sendMouseEvents)
String HTMLElement::title() const
{
- return getAttribute(titleAttr);
+ return fastGetAttribute(titleAttr);
}
short HTMLElement::tabIndex() const
@@ -610,11 +557,6 @@ short HTMLElement::tabIndex() const
return -1;
}
-void HTMLElement::setTabIndex(int value)
-{
- setIntegralAttribute(tabindexAttr, value);
-}
-
TranslateAttributeMode HTMLElement::translateAttributeMode() const
{
const AtomicString& value = getAttribute(translateAttr);
@@ -631,13 +573,11 @@ TranslateAttributeMode HTMLElement::translateAttributeMode() const
bool HTMLElement::translate() const
{
- for (const Node* n = this; n; n = n->parentNode()) {
- if (n->isHTMLElement()) {
- TranslateAttributeMode mode = toHTMLElement(n)->translateAttributeMode();
- if (mode != TranslateAttributeInherit) {
- ASSERT(mode == TranslateAttributeYes || mode == TranslateAttributeNo);
- return mode == TranslateAttributeYes;
- }
+ for (const HTMLElement* element = this; element; element = Traversal<HTMLElement>::firstAncestor(*element)) {
+ TranslateAttributeMode mode = element->translateAttributeMode();
+ if (mode != TranslateAttributeInherit) {
+ ASSERT(mode == TranslateAttributeYes || mode == TranslateAttributeNo);
+ return mode == TranslateAttributeYes;
}
}
@@ -650,39 +590,43 @@ void HTMLElement::setTranslate(bool enable)
setAttribute(translateAttr, enable ? "yes" : "no");
}
-bool HTMLElement::rendererIsNeeded(const RenderStyle& style)
+// Returns the conforming 'dir' value associated with the state the attribute is in (in its canonical case), if any,
+// or the empty string if the attribute is in a state that has no associated keyword value or if the attribute is
+// not in a defined state (e.g. the attribute is missing and there is no missing value default).
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#limited-to-only-known-values
+static inline const AtomicString& toValidDirValue(const AtomicString& value)
{
- if (hasLocalName(noscriptTag)) {
- Frame* frame = document().frame();
- if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript))
- return false;
- } else if (hasLocalName(noembedTag)) {
- Frame* frame = document().frame();
- if (frame && frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
- return false;
- }
- return Element::rendererIsNeeded(style);
+ DEFINE_STATIC_LOCAL(const AtomicString, ltrValue, ("ltr", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, rtlValue, ("rtl", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(const AtomicString, autoValue, ("auto", AtomicString::ConstructFromLiteral));
+
+ if (equalIgnoringCase(value, ltrValue))
+ return ltrValue;
+ if (equalIgnoringCase(value, rtlValue))
+ return rtlValue;
+ if (equalIgnoringCase(value, autoValue))
+ return autoValue;
+ return nullAtom;
+}
+
+const AtomicString& HTMLElement::dir()
+{
+ return toValidDirValue(fastGetAttribute(dirAttr));
}
-RenderObject* HTMLElement::createRenderer(RenderStyle* style)
+void HTMLElement::setDir(const AtomicString& value)
{
- if (hasLocalName(wbrTag))
- return new RenderWordBreak(this);
- return RenderObject::createObject(this, style);
+ setAttribute(dirAttr, value);
}
HTMLFormElement* HTMLElement::findFormAncestor() const
{
- for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (ancestor->hasTagName(formTag))
- return toHTMLFormElement(ancestor);
- }
- return 0;
+ return Traversal<HTMLFormElement>::firstAncestor(*this);
}
static inline bool elementAffectsDirectionality(const Node* node)
{
- return node->isHTMLElement() && (node->hasTagName(bdiTag) || toHTMLElement(node)->hasAttribute(dirAttr));
+ return node->isHTMLElement() && (isHTMLBDIElement(*node) || toHTMLElement(node)->hasAttribute(dirAttr));
}
static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastNode = 0)
@@ -692,9 +636,6 @@ static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastN
Node* node = firstNode->firstChild();
while (node) {
- if (node->selfOrAncestorHasDirAutoAttribute() == flag)
- return;
-
if (elementAffectsDirectionality(node)) {
if (node == lastNode)
return;
@@ -717,7 +658,7 @@ void HTMLElement::childrenChanged(bool changedByParser, Node* beforeChange, Node
bool HTMLElement::hasDirectionAuto() const
{
const AtomicString& direction = fastGetAttribute(dirAttr);
- return (hasTagName(bdiTag) && direction == nullAtom) || equalIgnoringCase(direction, "auto");
+ return (isHTMLBDIElement(*this) && direction == nullAtom) || equalIgnoringCase(direction, "auto");
}
TextDirection HTMLElement::directionalityIfhasDirAutoAttribute(bool& isAuto) const
@@ -731,18 +672,9 @@ TextDirection HTMLElement::directionalityIfhasDirAutoAttribute(bool& isAuto) con
return directionality();
}
-static TextDirection determineDirectionality(const String& value, bool& hasStrongDirectionality)
-{
- TextRun run(value);
- BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
- bidiResolver.setStatus(BidiStatus(run.direction(), run.directionalOverride()));
- bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0));
- return bidiResolver.determineParagraphDirectionality(&hasStrongDirectionality);
-}
-
TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) const
{
- if (hasTagName(inputTag)) {
+ if (isHTMLInputElement(*this)) {
HTMLInputElement* inputElement = toHTMLInputElement(const_cast<HTMLElement*>(this));
bool hasStrongDirectionality;
TextDirection textDirection = determineDirectionality(inputElement->value(), hasStrongDirectionality);
@@ -754,7 +686,7 @@ TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) c
Node* node = firstChild();
while (node) {
// Skip bdi, script, style and text form controls.
- if (equalIgnoringCase(node->nodeName(), "bdi") || node->hasTagName(scriptTag) || node->hasTagName(styleTag)
+ if (equalIgnoringCase(node->nodeName(), "bdi") || isHTMLScriptElement(*node) || isHTMLStyleElement(*node)
|| (node->isElementNode() && toElement(node)->isTextFormControl())) {
node = NodeTraversal::nextSkippingChildren(*node, this);
continue;
@@ -806,7 +738,7 @@ void HTMLElement::adjustDirectionalityIfNeededAfterChildAttributeChanged(Element
Element* elementToAdjust = this;
for (; elementToAdjust; elementToAdjust = elementToAdjust->parentElement()) {
if (elementAffectsDirectionality(elementToAdjust)) {
- elementToAdjust->setNeedsStyleRecalc();
+ elementToAdjust->setNeedsStyleRecalc(SubtreeStyleChange);
return;
}
}
@@ -817,14 +749,16 @@ void HTMLElement::calculateAndAdjustDirectionality()
{
Node* strongDirectionalityTextNode;
TextDirection textDirection = directionality(&strongDirectionalityTextNode);
- setHasDirAutoFlagRecursively(this, true, strongDirectionalityTextNode);
+ setHasDirAutoFlagRecursively(this, hasDirectionAuto(), strongDirectionalityTextNode);
+ for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
+ setHasDirAutoFlagRecursively(root, hasDirectionAuto());
if (renderer() && renderer()->style() && renderer()->style()->direction() != textDirection)
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
void HTMLElement::adjustDirectionalityIfNeededAfterChildrenChanged(Node* beforeChange, int childCountDelta)
{
- if (document().renderer() && childCountDelta < 0) {
+ if (document().renderView() && childCountDelta < 0) {
Node* node = beforeChange ? NodeTraversal::nextSkippingChildren(*beforeChange) : 0;
for (int counter = 0; node && counter < childCountDelta; counter++, node = NodeTraversal::nextSkippingChildren(*node)) {
if (elementAffectsDirectionality(node))
@@ -859,25 +793,25 @@ void HTMLElement::addHTMLLengthToStyle(MutableStylePropertySet* style, CSSProper
// strip attribute garbage..
StringImpl* v = value.impl();
if (v) {
- unsigned int l = 0;
+ unsigned length = 0;
- while (l < v->length() && (*v)[l] <= ' ')
- l++;
+ while (length < v->length() && (*v)[length] <= ' ')
+ length++;
- for (; l < v->length(); l++) {
- UChar cc = (*v)[l];
+ for (; length < v->length(); length++) {
+ UChar cc = (*v)[length];
if (cc > '9')
break;
if (cc < '0') {
if (cc == '%' || cc == '*')
- l++;
+ length++;
if (cc != '.')
break;
}
}
- if (l != v->length()) {
- addPropertyToPresentationAttributeStyle(style, propertyID, v->substring(0, l));
+ if (length != v->length()) {
+ addPropertyToPresentationAttributeStyle(style, propertyID, v->substring(0, length));
return;
}
}
@@ -955,8 +889,8 @@ void HTMLElement::addHTMLColorToStyle(MutableStylePropertySet* style, CSSPropert
return;
// If the string is a named CSS color or a 3/6-digit hex color, use that.
- Color parsedColor(colorString);
- if (!parsedColor.isValid())
+ Color parsedColor;
+ if (!parsedColor.setFromString(colorString))
parsedColor.setRGB(parseColorStringWithCrazyLegacyRules(colorString));
style->setProperty(propertyID, cssValuePool().createColorValue(parsedColor.rgb()));
@@ -978,6 +912,26 @@ void HTMLElement::defaultEventHandler(Event* event)
Element::defaultEventHandler(event);
}
+bool HTMLElement::matchesReadOnlyPseudoClass() const
+{
+ return !matchesReadWritePseudoClass();
+}
+
+bool HTMLElement::matchesReadWritePseudoClass() const
+{
+ if (fastHasAttribute(contenteditableAttr)) {
+ const AtomicString& value = fastGetAttribute(contenteditableAttr);
+
+ if (value.isEmpty() || equalIgnoringCase(value, "true") || equalIgnoringCase(value, "plaintext-only"))
+ return true;
+ if (equalIgnoringCase(value, "false"))
+ return false;
+ // All other values should be treated as "inherit".
+ }
+
+ return parentElement() && parentElement()->rendererIsEditable();
+}
+
void HTMLElement::handleKeypressEvent(KeyboardEvent* event)
{
if (!document().settings() || !document().settings()->spatialNavigationEnabled() || !supportsFocus())
@@ -994,6 +948,12 @@ void HTMLElement::handleKeypressEvent(KeyboardEvent* event)
}
}
+const AtomicString& HTMLElement::eventParameterName()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, eventString, ("event", AtomicString::ConstructFromLiteral));
+ return eventString;
+}
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLElement.h
index ef4736aa9bc..492555175a6 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLElement.h
@@ -40,21 +40,15 @@ enum TranslateAttributeMode {
class HTMLElement : public Element {
public:
- static PassRefPtr<HTMLElement> create(const QualifiedName& tagName, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLElement);
virtual String title() const OVERRIDE FINAL;
-
- virtual short tabIndex() const;
- void setTabIndex(int);
+ virtual short tabIndex() const OVERRIDE;
void setInnerText(const String&, ExceptionState&);
void setOuterText(const String&, ExceptionState&);
- Element* insertAdjacentElement(const String& where, Element* newChild, ExceptionState&);
- void insertAdjacentText(const String& where, const String& text, ExceptionState&);
-
virtual bool hasCustomFocusLogic() const;
- virtual bool supportsFocus() const;
String contentEditable() const;
void setContentEditable(const String&, ExceptionState&);
@@ -68,15 +62,15 @@ public:
bool translate() const;
void setTranslate(bool);
+ const AtomicString& dir();
+ void setDir(const AtomicString&);
+
void click();
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
bool ieForbidsInsertHTML() const;
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
-
virtual HTMLFormElement* formOwner() const { return 0; }
HTMLFormElement* findFormAncestor() const;
@@ -85,12 +79,20 @@ public:
TextDirection directionalityIfhasDirAutoAttribute(bool& isAuto) const;
virtual bool isHTMLUnknownElement() const { return false; }
+ virtual bool isPluginElement() const { return false; }
virtual bool isLabelable() const { return false; }
// http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#interactive-content
virtual bool isInteractiveContent() const;
virtual void defaultEventHandler(Event*) OVERRIDE;
+ static const AtomicString& eventNameForAttributeName(const QualifiedName& attrName);
+
+ virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
+ virtual bool matchesReadWritePseudoClass() const OVERRIDE;
+
+ static const AtomicString& eventParameterName();
+
protected:
HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
@@ -105,7 +107,7 @@ protected:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
unsigned parseBorderWidthAttribute(const AtomicString&) const;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
void calculateAndAdjustDirectionality();
private:
@@ -113,7 +115,7 @@ private:
void mapLanguageAttributeToLocale(const AtomicString&, MutableStylePropertySet*);
- PassRefPtr<DocumentFragment> textToFragment(const String&, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DocumentFragment> textToFragment(const String&, ExceptionState&);
void dirAttributeChanged(const AtomicString&);
void adjustDirectionalityIfNeededAfterChildAttributeChanged(Element* child);
@@ -122,13 +124,14 @@ private:
TranslateAttributeMode translateAttributeMode() const;
- const AtomicString& eventNameForAttributeName(const QualifiedName& attrName) const;
-
void handleKeypressEvent(KeyboardEvent*);
- bool supportsSpatialNavigationFocus() const;
};
-DEFINE_NODE_TYPE_CASTS(HTMLElement, isHTMLElement());
+DEFINE_ELEMENT_TYPE_CASTS(HTMLElement, isHTMLElement());
+
+template <> inline bool isElementOfType<const HTMLElement>(const Node& node) { return node.isHTMLElement(); }
+template <typename T> bool isElementOfType(const HTMLElement&);
+template <> inline bool isElementOfType<const HTMLElement>(const HTMLElement&) { return true; }
inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document, ConstructionType type = CreateHTMLElement)
: Element(tagName, &document, type)
@@ -137,6 +140,22 @@ inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document
ScriptWrappable::init(this);
}
+// This requires isHTML*Element(const Element&) and isHTML*Element(const HTMLElement&).
+// When the input element is an HTMLElement, we don't need to check the namespace URI, just the local name.
+#define DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
+ inline bool is##thisType(const thisType* element); \
+ inline bool is##thisType(const thisType& element); \
+ inline bool is##thisType(const HTMLElement* element) { return element && is##thisType(*element); } \
+ inline bool is##thisType(const Element* element) { return element && is##thisType(*element); } \
+ inline bool is##thisType(const Node& node) { return node.isElementNode() ? is##thisType(toElement(node)) : false; } \
+ inline bool is##thisType(const Node* node) { return node && node->isElementNode() ? is##thisType(*toElement(node)) : false; } \
+ template<typename T> inline bool is##thisType(const PassRefPtr<T>& node) { return is##thisType(node.get()); } \
+ template<typename T> inline bool is##thisType(const RefPtr<T>& node) { return is##thisType(node.get()); } \
+ template <> inline bool isElementOfType<const thisType>(const HTMLElement& element) { return is##thisType(element); } \
+ DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType)
+
} // namespace WebCore
+#include "core/HTMLElementTypeHelpers.h"
+
#endif // HTMLElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLElement.idl
index 5d065681ee8..65e7cb26ae9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLElement.idl
@@ -24,7 +24,7 @@
[Reflect] attribute DOMString title;
[Reflect] attribute DOMString lang;
attribute boolean translate;
- [Reflect] attribute DOMString dir;
+ attribute DOMString dir;
[CustomElementCallbacks] attribute long tabIndex;
[CustomElementCallbacks] attribute boolean draggable;
@@ -36,11 +36,6 @@
[TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementInnerText] attribute DOMString innerText;
[TreatNullAs=NullString, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementOuterText] attribute DOMString outerText;
- [RaisesException, CustomElementCallbacks, MeasureAs=InsertAdjacentElement] Element insertAdjacentElement([Default=Undefined] optional DOMString where,
- [Default=Undefined] optional Element element);
- [RaisesException, MeasureAs=InsertAdjacentText] void insertAdjacentText([Default=Undefined] optional DOMString where,
- [Default=Undefined] optional DOMString text);
-
[RuntimeEnabled=IMEAPI] readonly attribute InputMethodContext inputMethodContext;
[CustomElementCallbacks, RaisesException=Setter] attribute DOMString contentEditable;
@@ -52,3 +47,4 @@
};
HTMLElement implements GlobalEventHandlers;
+
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
index c6bde0181e1..99e3467a03f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
@@ -24,8 +24,8 @@
#include "config.h"
#include "core/html/HTMLEmbedElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLImageLoader.h"
@@ -45,9 +45,9 @@ inline HTMLEmbedElement::HTMLEmbedElement(Document& document, bool createdByPars
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLEmbedElement> HTMLEmbedElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLEmbedElement> HTMLEmbedElement::create(Document& document, bool createdByParser)
{
- RefPtr<HTMLEmbedElement> element = adoptRef(new HTMLEmbedElement(document, createdByParser));
+ RefPtrWillBeRawPtr<HTMLEmbedElement> element = adoptRefWillBeNoop(new HTMLEmbedElement(document, createdByParser));
element->ensureUserAgentShadowRoot();
return element.release();
}
@@ -55,9 +55,7 @@ PassRefPtr<HTMLEmbedElement> HTMLEmbedElement::create(Document& document, bool c
static inline RenderWidget* findWidgetRenderer(const Node* n)
{
if (!n->renderer())
- do
- n = n->parentNode();
- while (n && !n->hasTagName(objectTag));
+ n = Traversal<HTMLObjectElement>::firstAncestor(*n);
if (n && n->renderer() && n->renderer()->isWidget())
return toRenderWidget(n->renderer());
@@ -96,13 +94,15 @@ void HTMLEmbedElement::parseAttribute(const QualifiedName& name, const AtomicStr
size_t pos = m_serviceType.find(";");
if (pos != kNotFound)
m_serviceType = m_serviceType.left(pos);
+ if (!renderer())
+ requestPluginCreationWithoutRendererIfPossible();
} else if (name == codeAttr) {
m_url = stripLeadingAndTrailingHTMLSpaces(value);
} else if (name == srcAttr) {
m_url = stripLeadingAndTrailingHTMLSpaces(value);
if (renderer() && isImageType()) {
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
m_imageLoader->updateFromElementIgnoringPreviousError();
}
} else {
@@ -115,10 +115,11 @@ void HTMLEmbedElement::parametersForPlugin(Vector<String>& paramNames, Vector<St
if (!hasAttributes())
return;
- for (unsigned i = 0; i < attributeCount(); ++i) {
- const Attribute* attribute = attributeItem(i);
- paramNames.append(attribute->localName().string());
- paramValues.append(attribute->value().string());
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ paramNames.append(it->localName().string());
+ paramValues.append(it->value().string());
}
}
@@ -143,21 +144,12 @@ void HTMLEmbedElement::updateWidgetInternal()
Vector<String> paramValues;
parametersForPlugin(paramNames, paramValues);
- RefPtr<HTMLEmbedElement> protect(this); // Loading the plugin might remove us from the document.
- bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(m_url);
- if (!beforeLoadAllowedLoad) {
- if (document().isPluginDocument()) {
- // Plugins inside plugin documents load differently than other plugins. By the time
- // we are here in a plugin document, the load of the plugin (which is the plugin document's
- // main resource) has already started. We need to explicitly cancel the main resource load here.
- toPluginDocument(document()).cancelManualPluginLoad();
- }
- return;
- }
- if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer.
+ RefPtrWillBeRawPtr<HTMLEmbedElement> protect(this); // Loading the plugin might remove us from the document.
+
+ // FIXME: Can we not have renderer here now that beforeload events are gone?
+ if (!renderer())
return;
- // FIXME: beforeLoad could have detached the renderer! Just like in the <object> case above.
requestObject(m_url, m_serviceType, paramNames, paramValues);
}
@@ -166,14 +158,14 @@ bool HTMLEmbedElement::rendererIsNeeded(const RenderStyle& style)
if (isImageType())
return HTMLPlugInElement::rendererIsNeeded(style);
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return false;
// If my parent is an <object> and is not set to use fallback content, I
// should be ignored and not get a renderer.
ContainerNode* p = parentNode();
- if (p && p->hasTagName(objectTag)) {
+ if (isHTMLObjectElement(p)) {
ASSERT(p->renderer());
if (!toHTMLObjectElement(p)->useFallbackContent()) {
ASSERT(!p->renderer()->isEmbeddedObject());
@@ -188,16 +180,14 @@ bool HTMLEmbedElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || HTMLPlugInElement::isURLAttribute(attribute);
}
-const AtomicString HTMLEmbedElement::imageSourceURL() const
+const QualifiedName& HTMLEmbedElement::subResourceAttributeName() const
{
- return getAttribute(srcAttr);
+ return srcAttr;
}
-void HTMLEmbedElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+const AtomicString HTMLEmbedElement::imageSourceURL() const
{
- HTMLPlugInElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(srcAttr)));
+ return getAttribute(srcAttr);
}
bool HTMLEmbedElement::isInteractiveContent() const
@@ -208,8 +198,8 @@ bool HTMLEmbedElement::isInteractiveContent() const
bool HTMLEmbedElement::isExposed() const
{
// http://www.whatwg.org/specs/web-apps/current-work/#exposed
- for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (ancestor->hasTagName(objectTag) && toHTMLObjectElement(ancestor)->isExposed())
+ for (HTMLObjectElement* object = Traversal<HTMLObjectElement>::firstAncestor(*this); object; object = Traversal<HTMLObjectElement>::firstAncestor(*object)) {
+ if (object->isExposed())
return false;
}
return true;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h
index 8107fd188f2..becba85d94c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLEmbedElement FINAL : public HTMLPlugInElement {
public:
- static PassRefPtr<HTMLEmbedElement> create(Document&, bool createdByParser = false);
+ static PassRefPtrWillBeRawPtr<HTMLEmbedElement> create(Document&, bool createdByParser = false);
bool isExposed() const;
@@ -40,25 +40,22 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
virtual const AtomicString imageSourceURL() const OVERRIDE;
virtual RenderWidget* existingRenderWidget() const OVERRIDE;
virtual void updateWidgetInternal() OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-
void parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues);
virtual bool shouldRegisterAsNamedItem() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLEmbedElement, hasTagName(HTMLNames::embedTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
index 74524f3ec05..399417d8c00 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLEmbedElement.idl
@@ -24,7 +24,7 @@
[Reflect] attribute DOMString align;
[Reflect] attribute DOMString height;
[Reflect] attribute DOMString name;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly, LogPreviousValue] attribute DOMString src;
[Reflect] attribute DOMString type;
[Reflect] attribute DOMString width;
[Custom, NotEnumerable] getter boolean (unsigned long index);
@@ -32,5 +32,7 @@
[Custom, NotEnumerable] getter Node (DOMString name);
[Custom] setter Node (DOMString name, Node value);
- [CheckSecurity=Node, RaisesException] SVGDocument getSVGDocument();
+ [CheckSecurity=Node, RaisesException] Document getSVGDocument();
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
index bf568d1417c..54f6d7bbb93 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.cpp
@@ -25,9 +25,10 @@
#include "config.h"
#include "core/html/HTMLFieldSetElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLCollection.h"
+#include "core/html/HTMLFormControlsCollection.h"
#include "core/html/HTMLLegendElement.h"
#include "core/html/HTMLObjectElement.h"
#include "core/rendering/RenderFieldset.h"
@@ -44,9 +45,17 @@ inline HTMLFieldSetElement::HTMLFieldSetElement(Document& document, HTMLFormElem
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFieldSetElement> HTMLFieldSetElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLFieldSetElement> HTMLFieldSetElement::create(Document& document, HTMLFormElement* form)
{
- return adoptRef(new HTMLFieldSetElement(document, form));
+ return adoptRefWillBeNoop(new HTMLFieldSetElement(document, form));
+}
+
+void HTMLFieldSetElement::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_associatedElements);
+#endif
+ HTMLFormControlElement::trace(visitor);
}
void HTMLFieldSetElement::invalidateDisabledStateUnder(Element& base)
@@ -67,10 +76,8 @@ void HTMLFieldSetElement::disabledAttributeChanged()
void HTMLFieldSetElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::nextSkippingChildren(*element, this)) {
- if (element->hasTagName(legendTag))
- invalidateDisabledStateUnder(*element);
- }
+ for (HTMLLegendElement* legend = Traversal<HTMLLegendElement>::firstChild(*this); legend; legend = Traversal<HTMLLegendElement>::nextSibling(*legend))
+ invalidateDisabledStateUnder(*legend);
}
bool HTMLFieldSetElement::supportsFocus() const
@@ -91,16 +98,12 @@ RenderObject* HTMLFieldSetElement::createRenderer(RenderStyle*)
HTMLLegendElement* HTMLFieldSetElement::legend() const
{
- for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSkippingChildren(*child, this)) {
- if (child->hasTagName(legendTag))
- return toHTMLLegendElement(child);
- }
- return 0;
+ return Traversal<HTMLLegendElement>::firstChild(*this);
}
-PassRefPtr<HTMLCollection> HTMLFieldSetElement::elements()
+PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> HTMLFieldSetElement::elements()
{
- return ensureCachedHTMLCollection(FormControls);
+ return toHTMLFormControlsCollection(ensureCachedHTMLCollection(FormControls).get());
}
void HTMLFieldSetElement::refreshElementsIfNeeded() const
@@ -113,8 +116,8 @@ void HTMLFieldSetElement::refreshElementsIfNeeded() const
m_associatedElements.clear();
- for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element, this)) {
- if (element->hasTagName(objectTag)) {
+ for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(*this); element; element = Traversal<HTMLElement>::next(*element, this)) {
+ if (isHTMLObjectElement(*element)) {
m_associatedElements.append(toHTMLObjectElement(element));
continue;
}
@@ -126,20 +129,10 @@ void HTMLFieldSetElement::refreshElementsIfNeeded() const
}
}
-const Vector<FormAssociatedElement*>& HTMLFieldSetElement::associatedElements() const
+const FormAssociatedElement::List& HTMLFieldSetElement::associatedElements() const
{
refreshElementsIfNeeded();
return m_associatedElements;
}
-unsigned HTMLFieldSetElement::length() const
-{
- refreshElementsIfNeeded();
- unsigned len = 0;
- for (unsigned i = 0; i < m_associatedElements.size(); ++i)
- if (m_associatedElements[i]->isEnumeratable())
- ++len;
- return len;
-}
-
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
index e0835449cdf..bb6da9e2bc1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFieldSetElement.h
@@ -30,16 +30,17 @@ namespace WebCore {
class FormAssociatedElement;
class HTMLCollection;
+class HTMLFormControlsCollection;
class HTMLFieldSetElement FINAL : public HTMLFormControlElement {
public:
- static PassRefPtr<HTMLFieldSetElement> create(Document&, HTMLFormElement*);
+ static PassRefPtrWillBeRawPtr<HTMLFieldSetElement> create(Document&, HTMLFormElement*);
+ virtual void trace(Visitor*) OVERRIDE;
HTMLLegendElement* legend() const;
- PassRefPtr<HTMLCollection> elements();
+ PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> elements();
- const Vector<FormAssociatedElement*>& associatedElements() const;
- unsigned length() const;
+ const FormAssociatedElement::List& associatedElements() const;
protected:
virtual void disabledAttributeChanged() OVERRIDE;
@@ -47,24 +48,22 @@ protected:
private:
HTMLFieldSetElement(Document&, HTMLFormElement*);
- virtual bool isEnumeratable() const { return true; }
- virtual bool supportsFocus() const;
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual const AtomicString& formControlType() const;
- virtual bool recalcWillValidate() const { return false; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
+ virtual bool supportsFocus() const OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual const AtomicString& formControlType() const OVERRIDE;
+ virtual bool recalcWillValidate() const OVERRIDE { return false; }
virtual void childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta) OVERRIDE;
virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
static void invalidateDisabledStateUnder(Element&);
void refreshElementsIfNeeded() const;
- mutable Vector<FormAssociatedElement*> m_associatedElements;
+ mutable FormAssociatedElement::List m_associatedElements;
// When dom tree is modified, we have to refresh the m_associatedElements array.
mutable uint64_t m_documentVersion;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFieldSetElement, hasTagName(HTMLNames::fieldsetTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp
index 853eae4a786..3f808f855d1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.cpp
@@ -23,9 +23,9 @@
#include "config.h"
#include "core/html/HTMLFontElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSValueList.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
@@ -38,16 +38,13 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLFontElement::HTMLFontElement(Document& document)
+inline HTMLFontElement::HTMLFontElement(Document& document)
: HTMLElement(fontTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFontElement> HTMLFontElement::create(Document& document)
-{
- return adoptRef(new HTMLFontElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLFontElement)
// http://www.whatwg.org/specs/web-apps/current-work/multipage/rendering.html#fonts-and-colors
template <typename CharacterType>
@@ -193,7 +190,7 @@ void HTMLFontElement::collectStyleForPresentationAttribute(const QualifiedName&
} else if (name == colorAttr)
addHTMLColorToStyle(style, CSSPropertyColor, value);
else if (name == faceAttr) {
- if (RefPtr<CSSValueList> fontFaceValue = cssValuePool().createFontFaceValue(value))
+ if (RefPtrWillBeRawPtr<CSSValueList> fontFaceValue = cssValuePool().createFontFaceValue(value))
style->setProperty(CSSProperty(CSSPropertyFontFamily, fontFaceValue.release()));
} else
HTMLElement::collectStyleForPresentationAttribute(name, value, style);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h
index 229c5c94896..e0f542cfb76 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFontElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLFontElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLFontElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLFontElement);
static bool cssValueFromFontSizeNumber(const String&, CSSValueID&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
index 4c68907eaf4..d3d3b22cbcb 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.cpp
@@ -25,14 +25,12 @@
#include "config.h"
#include "core/html/HTMLFormControlElement.h"
-#include "core/dom/PostAttachCallbacks.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/html/HTMLDataListElement.h"
#include "core/html/HTMLFieldSetElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLLegendElement.h"
-#include "core/html/HTMLTextAreaElement.h"
#include "core/html/ValidityState.h"
#include "core/html/forms/ValidationMessage.h"
#include "core/frame/UseCounter.h"
@@ -43,7 +41,6 @@
namespace WebCore {
using namespace HTMLNames;
-using namespace std;
HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form)
: LabelableElement(tagName, document)
@@ -51,7 +48,6 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
, m_isAutofilled(false)
, m_isReadOnly(false)
, m_isRequired(false)
- , m_valueMatchesRenderer(false)
, m_ancestorDisabledState(AncestorDisabledStateUnknown)
, m_dataListAncestorState(Unknown)
, m_willValidateInitialized(false)
@@ -59,15 +55,22 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tagName, Doc
, m_isValid(true)
, m_wasChangedSinceLastFormControlChangeEvent(false)
, m_wasFocusedByMouse(false)
- , m_hasAutofocused(false)
{
- setForm(form ? form : findFormAncestor());
setHasCustomStyleCallbacks();
+ associateByParser(form);
}
HTMLFormControlElement::~HTMLFormControlElement()
{
+#if !ENABLE(OILPAN)
setForm(0);
+#endif
+}
+
+void HTMLFormControlElement::trace(Visitor* visitor)
+{
+ FormAssociatedElement::trace(visitor);
+ LabelableElement::trace(visitor);
}
String HTMLFormControlElement::formEnctype() const
@@ -105,10 +108,10 @@ void HTMLFormControlElement::updateAncestorDisabledState() const
{
HTMLFieldSetElement* fieldSetAncestor = 0;
ContainerNode* legendAncestor = 0;
- for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (!legendAncestor && ancestor->hasTagName(legendTag))
+ for (HTMLElement* ancestor = Traversal<HTMLElement>::firstAncestor(*this); ancestor; ancestor = Traversal<HTMLElement>::firstAncestor(*ancestor)) {
+ if (!legendAncestor && isHTMLLegendElement(*ancestor))
legendAncestor = ancestor;
- if (ancestor->hasTagName(fieldsetTag)) {
+ if (isHTMLFieldSetElement(*ancestor)) {
fieldSetAncestor = toHTMLFieldSetElement(ancestor);
break;
}
@@ -143,9 +146,9 @@ void HTMLFormControlElement::parseAttribute(const QualifiedName& name, const Ato
m_isReadOnly = !value.isNull();
if (wasReadOnly != m_isReadOnly) {
setNeedsWillValidateCheck();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), ReadOnlyState);
+ RenderTheme::theme().stateChanged(renderer(), ReadOnlyControlState);
}
} else if (name == requiredAttr) {
bool wasRequired = m_isRequired;
@@ -165,7 +168,7 @@ void HTMLFormControlElement::disabledAttributeChanged()
setNeedsWillValidateCheck();
didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), EnabledState);
+ RenderTheme::theme().stateChanged(renderer(), EnabledControlState);
if (isDisabledFormControl() && treeScope().adjustedFocusedElement() == this) {
// We might want to call blur(), but it's dangerous to dispatch events
// here.
@@ -178,33 +181,17 @@ void HTMLFormControlElement::requiredAttributeChanged()
setNeedsValidityCheck();
// Style recalculation is needed because style selectors may include
// :required and :optional pseudo-classes.
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
-static void focusPostAttach(Node* element)
+bool HTMLFormControlElement::supportsAutofocus() const
{
- toElement(element)->focus();
- element->deref();
+ return false;
}
bool HTMLFormControlElement::isAutofocusable() const
{
- if (!fastHasAttribute(autofocusAttr))
- return false;
-
- // FIXME: Should this set of hasTagName checks be replaced by a
- // virtual member function?
- if (hasTagName(inputTag))
- return !toHTMLInputElement(this)->isInputTypeHidden();
- if (hasTagName(selectTag))
- return true;
- if (hasTagName(keygenTag))
- return true;
- if (hasTagName(buttonTag))
- return true;
- if (isHTMLTextAreaElement(this))
- return true;
- return false;
+ return fastHasAttribute(autofocusAttr) && supportsAutofocus();
}
void HTMLFormControlElement::setAutofilled(bool autofilled)
@@ -213,15 +200,13 @@ void HTMLFormControlElement::setAutofilled(bool autofilled)
return;
m_isAutofilled = autofilled;
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
static bool shouldAutofocusOnAttach(const HTMLFormControlElement* element)
{
if (!element->isAutofocusable())
return false;
- if (element->hasAutofocused())
- return false;
if (element->document().isSandboxed(SandboxAutomaticFeatures)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
element->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked autofocusing on a form control because the form's frame is sandboxed and the 'allow-scripts' permission is not set.");
@@ -243,11 +228,10 @@ void HTMLFormControlElement::attach(const AttachContext& context)
// on the renderer.
renderer()->updateFromElement();
- if (shouldAutofocusOnAttach(this)) {
- setAutofocused();
- ref();
- PostAttachCallbacks::queueCallback(focusPostAttach, this);
- }
+ // FIXME: Autofocus handling should be moved to insertedInto according to
+ // the standard.
+ if (shouldAutofocusOnAttach(this))
+ document().setAutofocusElement(this);
}
void HTMLFormControlElement::didMoveToNewDocument(Document& oldDocument)
@@ -268,6 +252,7 @@ Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(Containe
void HTMLFormControlElement::removedFrom(ContainerNode* insertionPoint)
{
+ hideVisibleValidationMessage();
m_validationMessage = nullptr;
m_ancestorDisabledState = AncestorDisabledStateUnknown;
m_dataListAncestorState = Unknown;
@@ -275,19 +260,19 @@ void HTMLFormControlElement::removedFrom(ContainerNode* insertionPoint)
FormAssociatedElement::removedFrom(insertionPoint);
}
-bool HTMLFormControlElement::wasChangedSinceLastFormControlChangeEvent() const
+void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
{
- return m_wasChangedSinceLastFormControlChangeEvent;
+ m_wasChangedSinceLastFormControlChangeEvent = changed;
}
-void HTMLFormControlElement::setChangedSinceLastFormControlChangeEvent(bool changed)
+void HTMLFormControlElement::dispatchChangeEvent()
{
- m_wasChangedSinceLastFormControlChangeEvent = changed;
+ dispatchScopedEvent(Event::createBubble(EventTypeNames::change));
}
void HTMLFormControlElement::dispatchFormControlChangeEvent()
{
- HTMLElement::dispatchChangeEvent();
+ dispatchChangeEvent();
setChangedSinceLastFormControlChangeEvent(false);
}
@@ -322,20 +307,10 @@ String HTMLFormControlElement::resultForDialogSubmit()
return fastGetAttribute(valueAttr);
}
-static void updateFromElementCallback(Node* node)
-{
- ASSERT_ARG(node, node->isElementNode());
- ASSERT_ARG(node, toElement(node)->isFormControlElement());
- if (RenderObject* renderer = node->renderer())
- renderer->updateFromElement();
-}
-
void HTMLFormControlElement::didRecalcStyle(StyleRecalcChange)
{
- // updateFromElement() can cause the selection to change, and in turn
- // trigger synchronous layout, so it must not be called during style recalc.
- if (renderer())
- PostAttachCallbacks::queueCallback(updateFromElementCallback, this);
+ if (RenderObject* renderer = this->renderer())
+ renderer->updateFromElement();
}
bool HTMLFormControlElement::supportsFocus() const
@@ -354,11 +329,11 @@ bool HTMLFormControlElement::shouldShowFocusRingOnMouseFocus() const
return false;
}
-void HTMLFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void HTMLFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType type)
{
- if (direction != FocusDirectionPage)
- m_wasFocusedByMouse = direction == FocusDirectionMouse;
- HTMLElement::dispatchFocusEvent(oldFocusedElement, direction);
+ if (type != FocusTypePage)
+ m_wasFocusedByMouse = type == FocusTypeMouse;
+ HTMLElement::dispatchFocusEvent(oldFocusedElement, type);
}
bool HTMLFormControlElement::shouldHaveFocusAppearance() const
@@ -375,7 +350,7 @@ void HTMLFormControlElement::willCallDefaultEventHandler(const Event& event)
return;
m_wasFocusedByMouse = false;
if (renderer())
- renderer()->repaint();
+ renderer()->paintInvalidationForWholeRenderer();
}
@@ -388,13 +363,9 @@ short HTMLFormControlElement::tabIndex() const
bool HTMLFormControlElement::recalcWillValidate() const
{
if (m_dataListAncestorState == Unknown) {
- for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (ancestor->hasTagName(datalistTag)) {
- m_dataListAncestorState = InsideDataList;
- break;
- }
- }
- if (m_dataListAncestorState == Unknown)
+ if (Traversal<HTMLDataListElement>::firstAncestor(*this))
+ m_dataListAncestorState = InsideDataList;
+ else
m_dataListAncestorState = NotInsideDataList;
}
return m_dataListAncestorState == NotInsideDataList && !isDisabledOrReadOnly();
@@ -427,7 +398,7 @@ void HTMLFormControlElement::setNeedsWillValidateCheck()
m_willValidateInitialized = true;
m_willValidate = newWillValidate;
setNeedsValidityCheck();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (!m_willValidate)
hideVisibleValidationMessage();
}
@@ -451,15 +422,13 @@ void HTMLFormControlElement::hideVisibleValidationMessage()
m_validationMessage->requestToHideMessage();
}
-bool HTMLFormControlElement::checkValidity(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls, CheckValidityDispatchEvents dispatchEvents)
+bool HTMLFormControlElement::checkValidity(WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> >* unhandledInvalidControls)
{
if (!willValidate() || isValidFormControlElement())
return true;
- if (dispatchEvents == CheckValidityDispatchEventsNone)
- return false;
// An event handler can deref this object.
- RefPtr<HTMLFormControlElement> protector(this);
- RefPtr<Document> originalDocument(document());
+ RefPtrWillBeRawPtr<HTMLFormControlElement> protector(this);
+ RefPtrWillBeRawPtr<Document> originalDocument(document());
bool needsDefaultAction = dispatchEvent(Event::createCancelable(EventTypeNames::invalid));
if (needsDefaultAction && unhandledInvalidControls && inDocument() && originalDocument == document())
unhandledInvalidControls->append(this);
@@ -479,11 +448,11 @@ void HTMLFormControlElement::setNeedsValidityCheck()
bool newIsValid = valid();
if (willValidate() && newIsValid != m_isValid) {
// Update style for pseudo classes such as :valid :invalid.
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
m_isValid = newIsValid;
- // Updates only if this control already has a validtion message.
+ // Updates only if this control already has a validation message.
if (m_validationMessage && m_validationMessage->isVisible()) {
// Calls updateVisibleValidationMessage() even if m_isValid is not
// changed because a validation message can be chagned.
@@ -515,11 +484,9 @@ bool HTMLFormControlElement::isDefaultButtonForForm() const
HTMLFormControlElement* HTMLFormControlElement::enclosingFormControlElement(Node* node)
{
- for (; node; node = node->parentNode()) {
- if (node->isElementNode() && toElement(node)->isFormControlElement())
- return toHTMLFormControlElement(node);
- }
- return 0;
+ if (!node)
+ return 0;
+ return Traversal<HTMLFormControlElement>::firstAncestorOrSelf(*node);
}
String HTMLFormControlElement::nameForAutofill() const
@@ -533,4 +500,12 @@ String HTMLFormControlElement::nameForAutofill() const
return trimmedName;
}
+void HTMLFormControlElement::setFocus(bool flag)
+{
+ LabelableElement::setFocus(flag);
+
+ if (!flag && wasChangedSinceLastFormControlChangeEvent())
+ dispatchFormControlChangeEvent();
+}
+
} // namespace Webcore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
index bb5cdd8c8a2..eae67074b0b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElement.h
@@ -40,8 +40,11 @@ class ValidityState;
// and form-associated element implementations should use HTMLFormControlElement
// unless there is a special reason.
class HTMLFormControlElement : public LabelableElement, public FormAssociatedElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLFormControlElement);
+
public:
virtual ~HTMLFormControlElement();
+ virtual void trace(Visitor*) OVERRIDE;
String formEnctype() const;
void setFormEnctype(const AtomicString&);
@@ -53,32 +56,30 @@ public:
void reset();
- virtual bool formControlValueMatchesRenderer() const { return m_valueMatchesRenderer; }
- virtual void setFormControlValueMatchesRenderer(bool b) { m_valueMatchesRenderer = b; }
-
- virtual bool wasChangedSinceLastFormControlChangeEvent() const;
- virtual void setChangedSinceLastFormControlChangeEvent(bool);
+ bool wasChangedSinceLastFormControlChangeEvent() const { return m_wasChangedSinceLastFormControlChangeEvent; }
+ void setChangedSinceLastFormControlChangeEvent(bool);
virtual void dispatchFormControlChangeEvent();
- virtual void dispatchFormControlInputEvent();
+ void dispatchChangeEvent();
+ void dispatchFormControlInputEvent();
- virtual HTMLFormElement* formOwner() const OVERRIDE;
+ virtual HTMLFormElement* formOwner() const OVERRIDE FINAL;
virtual bool isDisabledFormControl() const OVERRIDE;
- virtual bool isEnumeratable() const { return false; }
+ virtual bool isEnumeratable() const OVERRIDE { return false; }
bool isRequired() const;
const AtomicString& type() const { return formControlType(); }
- virtual const AtomicString& formControlType() const OVERRIDE = 0;
+ virtual const AtomicString& formControlType() const = 0;
virtual bool canTriggerImplicitSubmission() const { return false; }
// Override in derived classes to get the encoded name=value pair for submitting.
// Return true for a successful control (see HTML4-17.13.2).
- virtual bool appendFormData(FormDataList&, bool) { return false; }
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE { return false; }
virtual String resultForDialogSubmit();
virtual bool canBeSuccessfulSubmitButton() const { return false; }
@@ -86,21 +87,17 @@ public:
virtual bool isActivatedSubmit() const { return false; }
virtual void setActivatedSubmit(bool) { }
- enum CheckValidityDispatchEvents { CheckValidityDispatchEventsAllowed, CheckValidityDispatchEventsNone };
-
- virtual bool willValidate() const;
+ virtual bool willValidate() const OVERRIDE;
void updateVisibleValidationMessage();
void hideVisibleValidationMessage();
- bool checkValidity(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls = 0, CheckValidityDispatchEvents = CheckValidityDispatchEventsAllowed);
+ bool checkValidity(WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> >* unhandledInvalidControls = 0);
// This must be called when a validation constraint or control value is changed.
void setNeedsValidityCheck();
- virtual void setCustomValidity(const String&) OVERRIDE;
+ virtual void setCustomValidity(const String&) OVERRIDE FINAL;
bool isReadOnly() const { return m_isReadOnly; }
bool isDisabledOrReadOnly() const { return isDisabledFormControl() || m_isReadOnly; }
- bool hasAutofocused() const { return m_hasAutofocused; }
- void setAutofocused() { m_hasAutofocused = true; }
bool isAutofocusable() const;
bool isAutofilled() const { return m_isAutofilled; }
@@ -110,8 +107,12 @@ public:
String nameForAutofill() const;
+ virtual void setFocus(bool flag) OVERRIDE;
+
+#if !ENABLE(OILPAN)
using Node::ref;
using Node::deref;
+#endif
protected:
HTMLFormControlElement(const QualifiedName& tagName, Document&, HTMLFormElement*);
@@ -127,30 +128,33 @@ protected:
virtual bool supportsFocus() const OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
virtual bool shouldShowFocusRingOnMouseFocus() const;
- virtual bool shouldHaveFocusAppearance() const OVERRIDE;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
+ virtual bool shouldHaveFocusAppearance() const OVERRIDE FINAL;
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE;
virtual void dispatchBlurEvent(Element* newFocusedElement) OVERRIDE;
- virtual void willCallDefaultEventHandler(const Event&) OVERRIDE;
+ virtual void willCallDefaultEventHandler(const Event&) OVERRIDE FINAL;
- virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE FINAL;
// This must be called any time the result of willValidate() has changed.
void setNeedsWillValidateCheck();
virtual bool recalcWillValidate() const;
virtual void resetImpl() { }
+ virtual bool supportsAutofocus() const;
private:
- virtual void refFormAssociatedElement() { ref(); }
- virtual void derefFormAssociatedElement() { deref(); }
+#if !ENABLE(OILPAN)
+ virtual void refFormAssociatedElement() OVERRIDE FINAL { ref(); }
+ virtual void derefFormAssociatedElement() OVERRIDE FINAL { deref(); }
+#endif
- virtual bool isFormControlElement() const { return true; }
+ virtual bool isFormControlElement() const OVERRIDE FINAL { return true; }
virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE { return true; }
- virtual short tabIndex() const;
+ virtual short tabIndex() const OVERRIDE FINAL;
- virtual bool isDefaultButtonForForm() const;
- virtual bool isValidFormControlElement();
+ virtual bool isDefaultButtonForForm() const OVERRIDE FINAL;
+ virtual bool isValidFormControlElement() OVERRIDE FINAL;
void updateAncestorDisabledState() const;
OwnPtr<ValidationMessage> m_validationMessage;
@@ -158,7 +162,6 @@ private:
bool m_isAutofilled : 1;
bool m_isReadOnly : 1;
bool m_isRequired : 1;
- bool m_valueMatchesRenderer : 1;
enum AncestorDisabledState { AncestorDisabledStateUnknown, AncestorDisabledStateEnabled, AncestorDisabledStateDisabled };
mutable AncestorDisabledState m_ancestorDisabledState;
@@ -177,15 +180,14 @@ private:
bool m_wasChangedSinceLastFormControlChangeEvent : 1;
bool m_wasFocusedByMouse : 1;
- bool m_hasAutofocused : 1;
};
-inline bool isHTMLFormControlElement(const Node& node)
+inline bool isHTMLFormControlElement(const Element& element)
{
- return node.isElementNode() && toElement(node).isFormControlElement();
+ return element.isFormControlElement();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLFormControlElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLFormControlElement);
DEFINE_TYPE_CASTS(HTMLFormControlElement, FormAssociatedElement, control, control->isFormControlElement(), control.isFormControlElement());
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
index 1508d798f18..23375e1dd90 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.cpp
@@ -25,12 +25,13 @@
#include "config.h"
#include "core/html/HTMLFormControlElementWithState.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/forms/FormController.h"
+#include "core/loader/FrameLoaderClient.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
namespace WebCore {
@@ -46,14 +47,14 @@ HTMLFormControlElementWithState::~HTMLFormControlElementWithState()
Node::InsertionNotificationRequest HTMLFormControlElementWithState::insertedInto(ContainerNode* insertionPoint)
{
if (insertionPoint->inDocument() && !containingShadowRoot())
- document().formController()->registerFormElementWithState(this);
+ document().formController().registerStatefulFormControl(*this);
return HTMLFormControlElement::insertedInto(insertionPoint);
}
void HTMLFormControlElementWithState::removedFrom(ContainerNode* insertionPoint)
{
if (insertionPoint->inDocument() && !containingShadowRoot() && !insertionPoint->containingShadowRoot())
- document().formController()->unregisterFormElementWithState(this);
+ document().formController().unregisterStatefulFormControl(*this);
HTMLFormControlElement::removedFrom(insertionPoint);
}
@@ -66,18 +67,17 @@ bool HTMLFormControlElementWithState::shouldAutocomplete() const
void HTMLFormControlElementWithState::notifyFormStateChanged()
{
- Frame* frame = document().frame();
- if (!frame)
+ // This can be called during fragment parsing as a result of option
+ // selection before the document is active (or even in a frame).
+ if (!document().isActive())
return;
-
- if (Page* page = frame->page())
- page->chrome().client().formStateDidChange(this);
+ document().frame()->loader().client()->didUpdateCurrentHistoryItem();
}
bool HTMLFormControlElementWithState::shouldSaveAndRestoreFormControlState() const
{
// We don't save/restore control state in a form with autocomplete=off.
- return inActiveDocument() && shouldAutocomplete();
+ return inDocument() && shouldAutocomplete();
}
FormControlState HTMLFormControlElementWithState::saveFormControlState() const
@@ -88,7 +88,7 @@ FormControlState HTMLFormControlElementWithState::saveFormControlState() const
void HTMLFormControlElementWithState::finishParsingChildren()
{
HTMLFormControlElement::finishParsingChildren();
- document().formController()->restoreControlStateFor(*this);
+ document().formController().restoreControlStateFor(*this);
}
bool HTMLFormControlElementWithState::isFormControlElementWithState() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
index 0328920e53a..d81fd207d69 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlElementWithState.h
@@ -34,8 +34,9 @@ class HTMLFormControlElementWithState : public HTMLFormControlElement {
public:
virtual ~HTMLFormControlElementWithState();
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return false; }
+ virtual bool shouldAutocomplete() const;
virtual bool shouldSaveAndRestoreFormControlState() const;
virtual FormControlState saveFormControlState() const;
// The specified FormControlState must have at least one string value.
@@ -45,11 +46,10 @@ public:
protected:
HTMLFormControlElementWithState(const QualifiedName& tagName, Document&, HTMLFormElement*);
- virtual bool shouldAutocomplete() const;
- virtual void finishParsingChildren();
+ virtual void finishParsingChildren() OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool isFormControlElementWithState() const OVERRIDE;
+ virtual bool isFormControlElementWithState() const OVERRIDE FINAL;
};
DEFINE_TYPE_CASTS(HTMLFormControlElementWithState, FormAssociatedElement, control, control->isFormControlElementWithState(), control.isFormControlElementWithState());
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp
index 972bb757c54..a7c4a9fecb9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,10 +24,12 @@
#include "config.h"
#include "core/html/HTMLFormControlsCollection.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLFieldSetElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLImageElement.h"
+#include "wtf/HashSet.h"
namespace WebCore {
@@ -35,53 +38,80 @@ using namespace HTMLNames;
// Since the collections are to be "live", we have to do the
// calculation every time if anything has changed.
-HTMLFormControlsCollection::HTMLFormControlsCollection(Node* ownerNode)
+HTMLFormControlsCollection::HTMLFormControlsCollection(ContainerNode& ownerNode)
: HTMLCollection(ownerNode, FormControls, OverridesItemAfter)
+ , m_cachedElement(nullptr)
+ , m_cachedElementOffsetInArray(0)
{
- ASSERT(ownerNode->hasTagName(formTag) || ownerNode->hasTagName(fieldsetTag));
+ ASSERT(isHTMLFormElement(ownerNode) || isHTMLFieldSetElement(ownerNode));
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(Node* ownerNode, CollectionType)
+PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(ContainerNode& ownerNode, CollectionType type)
{
- return adoptRef(new HTMLFormControlsCollection(ownerNode));
+ ASSERT_UNUSED(type, type == FormControls);
+ return adoptRefWillBeNoop(new HTMLFormControlsCollection(ownerNode));
}
HTMLFormControlsCollection::~HTMLFormControlsCollection()
{
}
-const Vector<FormAssociatedElement*>& HTMLFormControlsCollection::formControlElements() const
+const FormAssociatedElement::List& HTMLFormControlsCollection::formControlElements() const
{
- ASSERT(ownerNode());
- ASSERT(ownerNode()->hasTagName(formTag) || ownerNode()->hasTagName(fieldsetTag));
- if (ownerNode()->hasTagName(formTag))
- return toHTMLFormElement(ownerNode())->associatedElements();
- return toHTMLFieldSetElement(ownerNode())->associatedElements();
+ ASSERT(isHTMLFormElement(ownerNode()) || isHTMLFieldSetElement(ownerNode()));
+ if (isHTMLFormElement(ownerNode()))
+ return toHTMLFormElement(ownerNode()).associatedElements();
+ return toHTMLFieldSetElement(ownerNode()).associatedElements();
}
-const Vector<HTMLImageElement*>& HTMLFormControlsCollection::formImageElements() const
+const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& HTMLFormControlsCollection::formImageElements() const
{
- ASSERT(ownerNode());
- return toHTMLFormElement(ownerNode())->imageElements();
+ return toHTMLFormElement(ownerNode()).imageElements();
}
-Element* HTMLFormControlsCollection::virtualItemAfter(unsigned& offset, Element* previousItem) const
+static unsigned findFormAssociatedElement(const FormAssociatedElement::List& associatedElements, Element* element)
{
- const Vector<FormAssociatedElement*>& elementsArray = formControlElements();
- if (previousItem)
- offset++;
- while (offset < elementsArray.size()) {
- FormAssociatedElement* element = elementsArray[offset];
- if (element->isEnumeratable())
- return toHTMLElement(element);
- offset++;
+ unsigned i = 0;
+ for (; i < associatedElements.size(); ++i) {
+ FormAssociatedElement* associatedElement = associatedElements[i];
+ if (associatedElement->isEnumeratable() && toHTMLElement(associatedElement) == element)
+ break;
+ }
+ return i;
+}
+
+Element* HTMLFormControlsCollection::virtualItemAfter(Element* previous) const
+{
+ const FormAssociatedElement::List& associatedElements = formControlElements();
+ unsigned offset;
+ if (!previous)
+ offset = 0;
+ else if (m_cachedElement == previous)
+ offset = m_cachedElementOffsetInArray + 1;
+ else
+ offset = findFormAssociatedElement(associatedElements, previous) + 1;
+
+ for (unsigned i = offset; i < associatedElements.size(); ++i) {
+ FormAssociatedElement* associatedElement = associatedElements[i];
+ if (associatedElement->isEnumeratable()) {
+ m_cachedElement = toHTMLElement(associatedElement);
+ m_cachedElementOffsetInArray = i;
+ return m_cachedElement;
+ }
}
return 0;
}
-static HTMLElement* firstNamedItem(const Vector<FormAssociatedElement*>& elementsArray,
- const Vector<HTMLImageElement*>* imageElementsArray, const QualifiedName& attrName, const String& name)
+void HTMLFormControlsCollection::invalidateCache(Document* oldDocument) const
+{
+ HTMLCollection::invalidateCache(oldDocument);
+ m_cachedElement = nullptr;
+ m_cachedElementOffsetInArray = 0;
+}
+
+static HTMLElement* firstNamedItem(const FormAssociatedElement::List& elementsArray,
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >* imageElementsArray, const QualifiedName& attrName, const String& name)
{
ASSERT(attrName == idAttr || attrName == nameAttr);
@@ -96,35 +126,38 @@ static HTMLElement* firstNamedItem(const Vector<FormAssociatedElement*>& element
for (unsigned i = 0; i < imageElementsArray->size(); ++i) {
HTMLImageElement* element = (*imageElementsArray)[i];
- if (element->fastGetAttribute(attrName) == name)
+ if (element->fastGetAttribute(attrName) == name) {
+ UseCounter::count(element->document(), UseCounter::FormNameAccessForImageElement);
return element;
+ }
}
return 0;
}
-Node* HTMLFormControlsCollection::namedItem(const AtomicString& name) const
+Element* HTMLFormControlsCollection::namedItem(const AtomicString& name) const
{
// http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
// This method first searches for an object with a matching id
// attribute. If a match is not found, the method then searches for an
// object with a matching name attribute, but only on those elements
// that are allowed a name attribute.
- const Vector<HTMLImageElement*>* imagesElements = ownerNode()->hasTagName(fieldsetTag) ? 0 : &formImageElements();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >* imagesElements = isHTMLFieldSetElement(ownerNode()) ? 0 : &formImageElements();
if (HTMLElement* item = firstNamedItem(formControlElements(), imagesElements, idAttr, name))
return item;
return firstNamedItem(formControlElements(), imagesElements, nameAttr, name);
}
-void HTMLFormControlsCollection::updateNameCache() const
+void HTMLFormControlsCollection::updateIdNameCache() const
{
- if (hasNameCache())
+ if (hasValidIdNameCache())
return;
+ OwnPtrWillBeRawPtr<NamedItemCache> cache = NamedItemCache::create();
HashSet<StringImpl*> foundInputElements;
- const Vector<FormAssociatedElement*>& elementsArray = formControlElements();
+ const FormAssociatedElement::List& elementsArray = formControlElements();
for (unsigned i = 0; i < elementsArray.size(); ++i) {
FormAssociatedElement* associatedElement = elementsArray[i];
@@ -133,48 +166,82 @@ void HTMLFormControlsCollection::updateNameCache() const
const AtomicString& idAttrVal = element->getIdAttribute();
const AtomicString& nameAttrVal = element->getNameAttribute();
if (!idAttrVal.isEmpty()) {
- appendIdCache(idAttrVal, element);
+ cache->addElementWithId(idAttrVal, element);
foundInputElements.add(idAttrVal.impl());
}
if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) {
- appendNameCache(nameAttrVal, element);
+ cache->addElementWithName(nameAttrVal, element);
foundInputElements.add(nameAttrVal.impl());
}
}
}
- if (ownerNode()->hasTagName(formTag)) {
- const Vector<HTMLImageElement*>& imageElementsArray = formImageElements();
+ if (isHTMLFormElement(ownerNode())) {
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& imageElementsArray = formImageElements();
for (unsigned i = 0; i < imageElementsArray.size(); ++i) {
HTMLImageElement* element = imageElementsArray[i];
const AtomicString& idAttrVal = element->getIdAttribute();
const AtomicString& nameAttrVal = element->getNameAttribute();
if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl()))
- appendIdCache(idAttrVal, element);
+ cache->addElementWithId(idAttrVal, element);
if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && !foundInputElements.contains(nameAttrVal.impl()))
- appendNameCache(nameAttrVal, element);
+ cache->addElementWithName(nameAttrVal, element);
}
}
- setHasNameCache();
+ // Set the named item cache last as traversing the tree may cause cache invalidation.
+ setNamedItemCache(cache.release());
}
-void HTMLFormControlsCollection::namedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<RadioNodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Node>& returnValue1)
+void HTMLFormControlsCollection::namedGetter(const AtomicString& name, bool& radioNodeListEnabled, RefPtrWillBeRawPtr<RadioNodeList>& radioNodeList, bool& elementEnabled, RefPtrWillBeRawPtr<Element>& element)
{
- Vector<RefPtr<Node> > namedItems;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > namedItems;
this->namedItems(name, namedItems);
- if (!namedItems.size())
+ if (namedItems.isEmpty())
return;
if (namedItems.size() == 1) {
- returnValue1Enabled = true;
- returnValue1 = namedItems.at(0);
+ elementEnabled = true;
+ element = namedItems.at(0);
return;
}
- returnValue0Enabled = true;
- returnValue0 = this->ownerNode()->radioNodeList(name);
+ radioNodeListEnabled = true;
+ radioNodeList = ownerNode().radioNodeList(name);
+}
+
+void HTMLFormControlsCollection::supportedPropertyNames(Vector<String>& names)
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmlformcontrolscollection-0:
+ // The supported property names consist of the non-empty values of all the id and name attributes
+ // of all the elements represented by the collection, in tree order, ignoring later duplicates,
+ // with the id of an element preceding its name if it contributes both, they differ from each
+ // other, and neither is the duplicate of an earlier entry.
+ HashSet<AtomicString> existingNames;
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Element* element = item(i);
+ ASSERT(element);
+ const AtomicString& idAttribute = element->getIdAttribute();
+ if (!idAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(idAttribute);
+ if (addResult.isNewEntry)
+ names.append(idAttribute);
+ }
+ const AtomicString& nameAttribute = element->getNameAttribute();
+ if (!nameAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(nameAttribute);
+ if (addResult.isNewEntry)
+ names.append(nameAttribute);
+ }
+ }
+}
+
+void HTMLFormControlsCollection::trace(Visitor* visitor)
+{
+ visitor->trace(m_cachedElement);
+ HTMLCollection::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h
index 45b286ccb78..df90351776a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.h
@@ -2,6 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,12 +24,12 @@
#ifndef HTMLFormControlsCollection_h
#define HTMLFormControlsCollection_h
+#include "core/html/FormAssociatedElement.h"
#include "core/html/HTMLCollection.h"
#include "core/html/RadioNodeList.h"
namespace WebCore {
-class FormAssociatedElement;
class HTMLElement;
class HTMLImageElement;
class QualifiedName;
@@ -38,22 +39,30 @@ class QualifiedName;
class HTMLFormControlsCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<HTMLFormControlsCollection> create(Node*, CollectionType);
+ static PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> create(ContainerNode&, CollectionType);
virtual ~HTMLFormControlsCollection();
- virtual Node* namedItem(const AtomicString& name) const;
- void namedGetter(const AtomicString& name, bool&, RefPtr<RadioNodeList>&, bool&, RefPtr<Node>&);
+ virtual Element* namedItem(const AtomicString& name) const OVERRIDE;
+ void namedGetter(const AtomicString& name, bool& radioNodeListEnabled, RefPtrWillBeRawPtr<RadioNodeList>&, bool& elementEnabled, RefPtrWillBeRawPtr<Element>&);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- explicit HTMLFormControlsCollection(Node*);
+ explicit HTMLFormControlsCollection(ContainerNode&);
+
+ virtual void updateIdNameCache() const OVERRIDE;
+ virtual void supportedPropertyNames(Vector<String>& names) OVERRIDE;
- virtual void updateNameCache() const OVERRIDE;
+ const FormAssociatedElement::List& formControlElements() const;
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& formImageElements() const;
+ virtual Element* virtualItemAfter(Element*) const OVERRIDE;
+ virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE;
- const Vector<FormAssociatedElement*>& formControlElements() const;
- const Vector<HTMLImageElement*>& formImageElements() const;
- virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE;
+ mutable RawPtrWillBeMember<Element> m_cachedElement;
+ mutable unsigned m_cachedElementOffsetInArray;
};
+DEFINE_TYPE_CASTS(HTMLFormControlsCollection, LiveNodeListBase, collection, collection->type() == FormControls, collection.type() == FormControls);
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl
index f483a675a31..5ed779f2dfa 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormControlsCollection.idl
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006, 2007, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -20,9 +21,8 @@
[
DependentLifetime,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
] interface HTMLFormControlsCollection : HTMLCollection {
- [ImplementedAs=item] getter Node(unsigned long index);
- [Custom] Node namedItem([Default=Undefined] optional DOMString name);
- [ImplementedAs=namedGetter, NotEnumerable] getter (RadioNodeList or Node)(DOMString name);
+ [ImplementedAs=item] getter Node (unsigned long index);
+ [ImplementedAs=namedGetter] getter (RadioNodeList or Element) namedItem(DOMString name); // shadows inherited namedItem()
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
index 0e5cc98d302..18ef044388a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.cpp
@@ -26,34 +26,35 @@
#include "core/html/HTMLFormElement.h"
#include <limits>
-#include "HTMLNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
-#include "core/dom/NamedNodesCollection.h"
+#include "core/dom/IdTargetObserverRegistry.h"
#include "core/events/AutocompleteErrorEvent.h"
#include "core/events/Event.h"
+#include "core/events/GenericEventQueue.h"
#include "core/events/ScopedEventQueue.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDialogElement.h"
+#include "core/html/HTMLFormControlsCollection.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLObjectElement.h"
-#include "core/html/HTMLTableElement.h"
+#include "core/html/RadioNodeList.h"
#include "core/html/forms/FormController.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
-#include "core/frame/UseCounter.h"
+#include "core/loader/MixedContentChecker.h"
#include "core/rendering/RenderTextControl.h"
#include "platform/UserGestureIndicator.h"
-
-using namespace std;
+#include "wtf/text/AtomicString.h"
namespace WebCore {
@@ -61,37 +62,47 @@ using namespace HTMLNames;
HTMLFormElement::HTMLFormElement(Document& document)
: HTMLElement(formTag, document)
- , m_associatedElementsBeforeIndex(0)
- , m_associatedElementsAfterIndex(0)
+#if !ENABLE(OILPAN)
+ , m_weakPtrFactory(this)
+#endif
+ , m_associatedElementsAreDirty(false)
+ , m_imageElementsAreDirty(false)
+ , m_hasElementsAssociatedByParser(false)
+ , m_didFinishParsingChildren(false)
, m_wasUserSubmitted(false)
- , m_isSubmittingOrPreparingForSubmission(false)
- , m_shouldSubmit(false)
, m_isInResetFunction(false)
, m_wasDemoted(false)
- , m_requestAutocompleteTimer(this, &HTMLFormElement::requestAutocompleteTimerFired)
+ , m_pendingAutocompleteEventsQueue(GenericEventQueue::create(this))
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFormElement> HTMLFormElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLFormElement> HTMLFormElement::create(Document& document)
{
UseCounter::count(document, UseCounter::FormElement);
- return adoptRef(new HTMLFormElement(document));
+ return adoptRefWillBeNoop(new HTMLFormElement(document));
}
HTMLFormElement::~HTMLFormElement()
{
- document().formController()->willDeleteForm(this);
-
- for (unsigned i = 0; i < m_associatedElements.size(); ++i)
- m_associatedElements[i]->formWillBeDestroyed();
- for (unsigned i = 0; i < m_imageElements.size(); ++i)
- m_imageElements[i]->m_form = 0;
+#if !ENABLE(OILPAN)
+ // With Oilpan, either removedFrom is called or the document and
+ // form controller are dead as well and there is no need to remove
+ // this form element from it.
+ document().formController().willDeleteForm(this);
+#endif
}
-bool HTMLFormElement::formWouldHaveSecureSubmission(const String& url)
+void HTMLFormElement::trace(Visitor* visitor)
{
- return document().completeURL(url).protocolIs("https");
+#if ENABLE(OILPAN)
+ visitor->trace(m_pastNamesMap);
+ visitor->trace(m_radioButtonGroupScope);
+ visitor->trace(m_associatedElements);
+ visitor->trace(m_imageElements);
+ visitor->trace(m_pendingAutocompleteEventsQueue);
+#endif
+ HTMLElement::trace(visitor);
}
bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style)
@@ -100,14 +111,16 @@ bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style)
return HTMLElement::rendererIsNeeded(style);
ContainerNode* node = parentNode();
+ if (!node || !node->renderer())
+ return HTMLElement::rendererIsNeeded(style);
RenderObject* parentRenderer = node->renderer();
// FIXME: Shouldn't we also check for table caption (see |formIsTablePart| below).
// FIXME: This check is not correct for Shadow DOM.
- bool parentIsTableElementPart = (parentRenderer->isTable() && isHTMLTableElement(node))
- || (parentRenderer->isTableRow() && node->hasTagName(trTag))
+ bool parentIsTableElementPart = (parentRenderer->isTable() && isHTMLTableElement(*node))
+ || (parentRenderer->isTableRow() && isHTMLTableRowElement(*node))
|| (parentRenderer->isTableSection() && node->hasTagName(tbodyTag))
|| (parentRenderer->isRenderTableCol() && node->hasTagName(colTag))
- || (parentRenderer->isTableCell() && node->hasTagName(trTag));
+ || (parentRenderer->isTableCell() && isHTMLTableRowElement(*node));
if (!parentIsTableElementPart)
return true;
@@ -129,20 +142,46 @@ Node::InsertionNotificationRequest HTMLFormElement::insertedInto(ContainerNode*
return InsertionDone;
}
-static inline Node* findRoot(Node* n)
+template<class T>
+void notifyFormRemovedFromTree(const T& elements, Node& root)
{
- Node* root = n;
- for (; n; n = n->parentNode())
- root = n;
- return root;
+ size_t size = elements.size();
+ for (size_t i = 0; i < size; ++i)
+ elements[i]->formRemovedFromTree(root);
+ ASSERT(elements.size() == size);
}
void HTMLFormElement::removedFrom(ContainerNode* insertionPoint)
{
- Node* root = findRoot(this);
- Vector<FormAssociatedElement*> associatedElements(m_associatedElements);
- for (unsigned i = 0; i < associatedElements.size(); ++i)
- associatedElements[i]->formRemovedFromTree(root);
+ // We don't need to take care of form association by 'form' content
+ // attribute becuse IdTargetObserver handles it.
+ if (m_hasElementsAssociatedByParser) {
+ Node& root = highestAncestorOrSelf();
+ if (!m_associatedElementsAreDirty) {
+ FormAssociatedElement::List elements(associatedElements());
+ notifyFormRemovedFromTree(elements, root);
+ } else {
+ FormAssociatedElement::List elements;
+ collectAssociatedElements(insertionPoint->highestAncestorOrSelf(), elements);
+ notifyFormRemovedFromTree(elements, root);
+ collectAssociatedElements(root, elements);
+ notifyFormRemovedFromTree(elements, root);
+ }
+
+ if (!m_imageElementsAreDirty) {
+ WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> > images(imageElements());
+ notifyFormRemovedFromTree(images, root);
+ } else {
+ WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> > images;
+ collectImageElements(insertionPoint->highestAncestorOrSelf(), images);
+ notifyFormRemovedFromTree(images, root);
+ collectImageElements(root, images);
+ notifyFormRemovedFromTree(images, root);
+ }
+ }
+#if ENABLE(OILPAN)
+ document().formController().willDeleteForm(this);
+#endif
HTMLElement::removedFrom(insertionPoint);
}
@@ -158,14 +197,16 @@ void HTMLFormElement::handleLocalEvents(Event* event)
unsigned HTMLFormElement::length() const
{
+ const FormAssociatedElement::List& elements = associatedElements();
unsigned len = 0;
- for (unsigned i = 0; i < m_associatedElements.size(); ++i)
- if (m_associatedElements[i]->isEnumeratable())
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (elements[i]->isEnumeratable())
++len;
+ }
return len;
}
-Node* HTMLFormElement::item(unsigned index)
+Element* HTMLFormElement::item(unsigned index)
{
return elements()->item(index);
}
@@ -174,8 +215,9 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
{
int submissionTriggerCount = 0;
bool seenDefaultButton = false;
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- FormAssociatedElement* formAssociatedElement = m_associatedElements[i];
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ FormAssociatedElement* formAssociatedElement = elements[i];
if (!formAssociatedElement->isFormControlElement())
continue;
HTMLFormControlElement* control = toHTMLFormControlElement(formAssociatedElement);
@@ -183,10 +225,8 @@ void HTMLFormElement::submitImplicitly(Event* event, bool fromImplicitSubmission
if (fromImplicitSubmissionTrigger)
seenDefaultButton = true;
if (control->isSuccessfulSubmitButton()) {
- if (control->renderer()) {
- control->dispatchSimulatedClick(event);
- return;
- }
+ control->dispatchSimulatedClick(event);
+ return;
} else if (fromImplicitSubmissionTrigger) {
// Default (submit) button is not activated; no implicit submission.
return;
@@ -219,12 +259,13 @@ bool HTMLFormElement::validateInteractively(Event* event)
if (submitElement && submitElement->formNoValidate())
return true;
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (m_associatedElements[i]->isFormControlElement())
- toHTMLFormControlElement(m_associatedElements[i])->hideVisibleValidationMessage();
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (elements[i]->isFormControlElement())
+ toHTMLFormControlElement(elements[i])->hideVisibleValidationMessage();
}
- Vector<RefPtr<FormAssociatedElement> > unhandledInvalidControls;
+ WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> > unhandledInvalidControls;
if (!checkInvalidControlsAndCollectUnhandled(&unhandledInvalidControls))
return true;
// Because the form has invalid controls, we abort the form submission and
@@ -234,7 +275,7 @@ bool HTMLFormElement::validateInteractively(Event* event)
// has !renderer()->needsLayout() assertion.
document().updateLayoutIgnorePendingStylesheets();
- RefPtr<HTMLFormElement> protector(this);
+ RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
// Focus on the first focusable control and show a validation message.
for (unsigned i = 0; i < unhandledInvalidControls.size(); ++i) {
FormAssociatedElement* unhandledAssociatedElement = unhandledInvalidControls[i].get();
@@ -262,36 +303,21 @@ bool HTMLFormElement::validateInteractively(Event* event)
return false;
}
-bool HTMLFormElement::prepareForSubmission(Event* event)
+void HTMLFormElement::prepareForSubmission(Event* event)
{
- RefPtr<HTMLFormElement> protector(this);
- Frame* frame = document().frame();
- if (m_isSubmittingOrPreparingForSubmission || !frame)
- return m_isSubmittingOrPreparingForSubmission;
-
- m_isSubmittingOrPreparingForSubmission = true;
- m_shouldSubmit = false;
+ RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
+ LocalFrame* frame = document().frame();
+ if (!frame)
+ return;
// Interactive validation must be done before dispatching the submit event.
- if (!validateInteractively(event)) {
- m_isSubmittingOrPreparingForSubmission = false;
- return false;
- }
+ if (!validateInteractively(event))
+ return;
- StringPairVector controlNamesAndValues;
- getTextFieldValues(controlNamesAndValues);
- RefPtr<FormState> formState = FormState::create(this, controlNamesAndValues, &document(), NotSubmittedByJavaScript);
- frame->loader().client()->dispatchWillSendSubmitEvent(formState.release());
+ frame->loader().client()->dispatchWillSendSubmitEvent(this);
if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit)))
- m_shouldSubmit = true;
-
- m_isSubmittingOrPreparingForSubmission = false;
-
- if (m_shouldSubmit)
submit(event, true, true, NotSubmittedByJavaScript);
-
- return m_shouldSubmit;
}
void HTMLFormElement::submit()
@@ -304,30 +330,11 @@ void HTMLFormElement::submitFromJavaScript()
submit(0, false, UserGestureIndicator::processingUserGesture(), SubmittedByJavaScript);
}
-void HTMLFormElement::getTextFieldValues(StringPairVector& fieldNamesAndValues) const
-{
- ASSERT_ARG(fieldNamesAndValues, fieldNamesAndValues.isEmpty());
-
- fieldNamesAndValues.reserveCapacity(m_associatedElements.size());
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- FormAssociatedElement* control = m_associatedElements[i];
- HTMLElement* element = toHTMLElement(control);
- if (!element->hasTagName(inputTag))
- continue;
-
- HTMLInputElement* input = toHTMLInputElement(element);
- if (!input->isTextField())
- continue;
-
- fieldNamesAndValues.append(make_pair(input->name().string(), input->value()));
- }
-}
-
-void HTMLFormElement::submitDialog(PassRefPtr<FormSubmission> formSubmission)
+void HTMLFormElement::submitDialog(PassRefPtrWillBeRawPtr<FormSubmission> formSubmission)
{
for (Node* node = this; node; node = node->parentOrShadowHostNode()) {
- if (node->hasTagName(dialogTag)) {
- toHTMLDialogElement(node)->closeDialog(formSubmission->result());
+ if (isHTMLDialogElement(*node)) {
+ toHTMLDialogElement(*node).closeDialog(formSubmission->result());
return;
}
}
@@ -336,23 +343,18 @@ void HTMLFormElement::submitDialog(PassRefPtr<FormSubmission> formSubmission)
void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger formSubmissionTrigger)
{
FrameView* view = document().view();
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!view || !frame || !frame->page())
return;
- if (m_isSubmittingOrPreparingForSubmission) {
- m_shouldSubmit = true;
- return;
- }
-
- m_isSubmittingOrPreparingForSubmission = true;
m_wasUserSubmitted = processingUserGesture;
- RefPtr<HTMLFormControlElement> firstSuccessfulSubmitButton;
+ RefPtrWillBeRawPtr<HTMLFormControlElement> firstSuccessfulSubmitButton = nullptr;
bool needButtonActivation = activateSubmitButton; // do we need to activate a submit button?
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- FormAssociatedElement* associatedElement = m_associatedElements[i];
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ FormAssociatedElement* associatedElement = elements[i];
if (!associatedElement->isFormControlElement())
continue;
if (needButtonActivation) {
@@ -367,7 +369,7 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool proce
if (needButtonActivation && firstSuccessfulSubmitButton)
firstSuccessfulSubmitButton->setActivatedSubmit(true);
- RefPtr<FormSubmission> formSubmission = FormSubmission::create(this, m_attributes, event, formSubmissionTrigger);
+ RefPtrWillBeRawPtr<FormSubmission> formSubmission = FormSubmission::create(this, m_attributes, event, formSubmissionTrigger);
EventQueueScope scopeForDialogClose; // Delay dispatching 'close' to dialog until done submitting.
if (formSubmission->method() == FormSubmission::DialogMethod)
submitDialog(formSubmission.release());
@@ -376,12 +378,9 @@ void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool proce
if (needButtonActivation && firstSuccessfulSubmitButton)
firstSuccessfulSubmitButton->setActivatedSubmit(false);
-
- m_shouldSubmit = false;
- m_isSubmittingOrPreparingForSubmission = false;
}
-void HTMLFormElement::scheduleFormSubmission(PassRefPtr<FormSubmission> submission)
+void HTMLFormElement::scheduleFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission> submission)
{
ASSERT(submission->method() == FormSubmission::PostMethod || submission->method() == FormSubmission::GetMethod);
ASSERT(submission->data());
@@ -395,15 +394,15 @@ void HTMLFormElement::scheduleFormSubmission(PassRefPtr<FormSubmission> submissi
}
if (protocolIsJavaScript(submission->action())) {
- if (!document().contentSecurityPolicy()->allowFormAction(KURL(submission->action())))
+ if (!document().contentSecurityPolicy()->allowFormAction(submission->action()))
return;
document().frame()->script().executeScriptIfJavaScriptURL(submission->action());
return;
}
- Frame* targetFrame = document().frame()->loader().findFrameForNavigation(submission->target(), submission->state()->sourceDocument());
+ LocalFrame* targetFrame = document().frame()->loader().findFrameForNavigation(submission->target(), submission->state()->sourceDocument());
if (!targetFrame) {
- if (!DOMWindow::allowPopUp(document().frame()) && !UserGestureIndicator::processingUserGesture())
+ if (!LocalDOMWindow::allowPopUp(*document().frame()) && !UserGestureIndicator::processingUserGesture())
return;
targetFrame = document().frame();
} else {
@@ -412,7 +411,15 @@ void HTMLFormElement::scheduleFormSubmission(PassRefPtr<FormSubmission> submissi
if (!targetFrame->page())
return;
- submission->setReferrer(document().outgoingReferrer());
+ if (MixedContentChecker::isMixedContent(document().securityOrigin(), submission->action())) {
+ UseCounter::count(document(), UseCounter::MixedContentFormsSubmitted);
+ if (!document().frame()->loader().mixedContentChecker()->canSubmitToInsecureForm(document().securityOrigin(), submission->action()))
+ return;
+ } else {
+ UseCounter::count(document(), UseCounter::FormsSubmitted);
+ }
+
+ submission->setReferrer(Referrer(document().outgoingReferrer(), document().referrerPolicy()));
submission->setOrigin(document().outgoingOrigin());
targetFrame->navigationScheduler().scheduleFormSubmission(submission);
@@ -420,7 +427,7 @@ void HTMLFormElement::scheduleFormSubmission(PassRefPtr<FormSubmission> submissi
void HTMLFormElement::reset()
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (m_isInResetFunction || !frame)
return;
@@ -431,9 +438,10 @@ void HTMLFormElement::reset()
return;
}
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (m_associatedElements[i]->isFormControlElement())
- toHTMLFormControlElement(m_associatedElements[i])->reset();
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (elements[i]->isFormControlElement())
+ toHTMLFormControlElement(elements[i])->reset();
}
m_isInResetFunction = false;
@@ -441,54 +449,51 @@ void HTMLFormElement::reset()
void HTMLFormElement::requestAutocomplete()
{
- Frame* frame = document().frame();
- if (!frame)
- return;
+ String errorMessage;
+
+ if (!document().frame())
+ errorMessage = "requestAutocomplete: form is not owned by a displayed document.";
+ else if (!shouldAutocomplete())
+ errorMessage = "requestAutocomplete: form autocomplete attribute is set to off.";
+ else if (!UserGestureIndicator::processingUserGesture())
+ errorMessage = "requestAutocomplete: must be called in response to a user gesture.";
- if (!shouldAutocomplete() || !UserGestureIndicator::processingUserGesture()) {
+ if (!errorMessage.isEmpty()) {
+ document().addConsoleMessage(RenderingMessageSource, LogMessageLevel, errorMessage);
finishRequestAutocomplete(AutocompleteResultErrorDisabled);
- return;
+ } else {
+ document().frame()->loader().client()->didRequestAutocomplete(this);
}
-
- StringPairVector controlNamesAndValues;
- getTextFieldValues(controlNamesAndValues);
- RefPtr<FormState> formState = FormState::create(this, controlNamesAndValues, &document(), SubmittedByJavaScript);
- frame->loader().client()->didRequestAutocomplete(formState.release());
}
void HTMLFormElement::finishRequestAutocomplete(AutocompleteResult result)
{
- RefPtr<Event> event;
+ RefPtrWillBeRawPtr<Event> event = nullptr;
if (result == AutocompleteResultSuccess)
- event = Event::create(EventTypeNames::autocomplete);
+ event = Event::createBubble(EventTypeNames::autocomplete);
else if (result == AutocompleteResultErrorDisabled)
event = AutocompleteErrorEvent::create("disabled");
else if (result == AutocompleteResultErrorCancel)
event = AutocompleteErrorEvent::create("cancel");
else if (result == AutocompleteResultErrorInvalid)
event = AutocompleteErrorEvent::create("invalid");
+ else
+ ASSERT_NOT_REACHED();
event->setTarget(this);
- m_pendingAutocompleteEvents.append(event.release());
-
- // Dispatch events later as this API is meant to work asynchronously in all situations and implementations.
- if (!m_requestAutocompleteTimer.isActive())
- m_requestAutocompleteTimer.startOneShot(0);
-}
-
-void HTMLFormElement::requestAutocompleteTimerFired(Timer<HTMLFormElement>*)
-{
- Vector<RefPtr<Event> > pendingEvents;
- m_pendingAutocompleteEvents.swap(pendingEvents);
- for (size_t i = 0; i < pendingEvents.size(); ++i)
- dispatchEvent(pendingEvents[i].release());
+ m_pendingAutocompleteEventsQueue->enqueueEvent(event.release());
}
void HTMLFormElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (name == actionAttr)
+ if (name == actionAttr) {
m_attributes.parseAction(value);
- else if (name == targetAttr)
+ // If the new action attribute is pointing to insecure "action" location from a secure page
+ // it is marked as "passive" mixed content.
+ KURL actionURL = document().completeURL(m_attributes.action().isEmpty() ? document().url().string() : m_attributes.action());
+ if (MixedContentChecker::isMixedContent(document().securityOrigin(), actionURL))
+ document().frame()->loader().mixedContentChecker()->canSubmitToInsecureForm(document().securityOrigin(), actionURL);
+ } else if (name == targetAttr)
m_attributes.setTarget(value);
else if (name == methodAttr)
m_attributes.updateMethodType(value);
@@ -497,135 +502,119 @@ void HTMLFormElement::parseAttribute(const QualifiedName& name, const AtomicStri
else if (name == accept_charsetAttr)
m_attributes.setAcceptCharset(value);
else if (name == onautocompleteAttr)
- setAttributeEventListener(EventTypeNames::autocomplete, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(EventTypeNames::autocomplete, createAttributeEventListener(this, name, value, eventParameterName()));
else if (name == onautocompleteerrorAttr)
- setAttributeEventListener(EventTypeNames::autocompleteerror, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(EventTypeNames::autocompleteerror, createAttributeEventListener(this, name, value, eventParameterName()));
else
HTMLElement::parseAttribute(name, value);
}
-template<class T, size_t n> static void removeFromVector(Vector<T*, n> & vec, T* item)
+void HTMLFormElement::associate(FormAssociatedElement& e)
{
- size_t size = vec.size();
- for (size_t i = 0; i != size; ++i)
- if (vec[i] == item) {
- vec.remove(i);
- break;
- }
+ m_associatedElementsAreDirty = true;
+ m_associatedElements.clear();
}
-unsigned HTMLFormElement::formElementIndexWithFormAttribute(Element* element, unsigned rangeStart, unsigned rangeEnd)
+void HTMLFormElement::disassociate(FormAssociatedElement& e)
{
- if (m_associatedElements.isEmpty())
- return 0;
-
- ASSERT(rangeStart <= rangeEnd);
-
- if (rangeStart == rangeEnd)
- return rangeStart;
+ m_associatedElementsAreDirty = true;
+ m_associatedElements.clear();
+ removeFromPastNamesMap(toHTMLElement(e));
+}
- unsigned left = rangeStart;
- unsigned right = rangeEnd - 1;
- unsigned short position;
+bool HTMLFormElement::isURLAttribute(const Attribute& attribute) const
+{
+ return attribute.name() == actionAttr || HTMLElement::isURLAttribute(attribute);
+}
- // Does binary search on m_associatedElements in order to find the index
- // to be inserted.
- while (left != right) {
- unsigned middle = left + ((right - left) / 2);
- ASSERT(middle < m_associatedElementsBeforeIndex || middle >= m_associatedElementsAfterIndex);
- position = element->compareDocumentPosition(toHTMLElement(m_associatedElements[middle]));
- if (position & DOCUMENT_POSITION_FOLLOWING)
- right = middle;
- else
- left = middle + 1;
- }
+bool HTMLFormElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == actionAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
- ASSERT(left < m_associatedElementsBeforeIndex || left >= m_associatedElementsAfterIndex);
- position = element->compareDocumentPosition(toHTMLElement(m_associatedElements[left]));
- if (position & DOCUMENT_POSITION_FOLLOWING)
- return left;
- return left + 1;
+void HTMLFormElement::associate(HTMLImageElement& e)
+{
+ m_imageElementsAreDirty = true;
+ m_imageElements.clear();
}
-unsigned HTMLFormElement::formElementIndex(FormAssociatedElement& associatedElement)
+void HTMLFormElement::disassociate(HTMLImageElement& e)
{
- HTMLElement& associatedHTMLElement = toHTMLElement(associatedElement);
- // Treats separately the case where this element has the form attribute
- // for performance consideration.
- if (associatedHTMLElement.fastHasAttribute(formAttr)) {
- unsigned short position = compareDocumentPosition(&associatedHTMLElement);
- if (position & DOCUMENT_POSITION_PRECEDING) {
- ++m_associatedElementsBeforeIndex;
- ++m_associatedElementsAfterIndex;
- return HTMLFormElement::formElementIndexWithFormAttribute(&associatedHTMLElement, 0, m_associatedElementsBeforeIndex - 1);
- }
- if (position & DOCUMENT_POSITION_FOLLOWING && !(position & DOCUMENT_POSITION_CONTAINED_BY))
- return HTMLFormElement::formElementIndexWithFormAttribute(&associatedHTMLElement, m_associatedElementsAfterIndex, m_associatedElements.size());
- }
+ m_imageElementsAreDirty = true;
+ m_imageElements.clear();
+ removeFromPastNamesMap(e);
+}
- // Check for the special case where this element is the very last thing in
- // the form's tree of children; we don't want to walk the entire tree in that
- // common case that occurs during parsing; instead we'll just return a value
- // that says "add this form element to the end of the array".
- if (ElementTraversal::next(associatedHTMLElement, this)) {
- unsigned i = m_associatedElementsBeforeIndex;
- for (Element* element = this; element; element = ElementTraversal::next(*element, this)) {
- if (element == associatedHTMLElement) {
- ++m_associatedElementsAfterIndex;
- return i;
- }
- if (!element->isFormControlElement() && !element->hasTagName(objectTag))
- continue;
- if (!element->isHTMLElement() || toHTMLElement(element)->formOwner() != this)
- continue;
- ++i;
- }
- }
- return m_associatedElementsAfterIndex++;
+#if !ENABLE(OILPAN)
+WeakPtr<HTMLFormElement> HTMLFormElement::createWeakPtr()
+{
+ return m_weakPtrFactory.createWeakPtr();
}
+#endif
-void HTMLFormElement::registerFormElement(FormAssociatedElement& e)
+void HTMLFormElement::didAssociateByParser()
{
- m_associatedElements.insert(formElementIndex(e), &e);
+ if (!m_didFinishParsingChildren)
+ return;
+ m_hasElementsAssociatedByParser = true;
+ UseCounter::count(document(), UseCounter::FormAssociationByParser);
}
-void HTMLFormElement::removeFormElement(FormAssociatedElement* e)
+PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> HTMLFormElement::elements()
{
- unsigned index;
- for (index = 0; index < m_associatedElements.size(); ++index) {
- if (m_associatedElements[index] == e)
- break;
- }
- ASSERT_WITH_SECURITY_IMPLICATION(index < m_associatedElements.size());
- if (index < m_associatedElementsBeforeIndex)
- --m_associatedElementsBeforeIndex;
- if (index < m_associatedElementsAfterIndex)
- --m_associatedElementsAfterIndex;
- removeFromPastNamesMap(*toHTMLElement(e));
- removeFromVector(m_associatedElements, e);
+ return toHTMLFormControlsCollection(ensureCachedHTMLCollection(FormControls).get());
}
-bool HTMLFormElement::isURLAttribute(const Attribute& attribute) const
+void HTMLFormElement::collectAssociatedElements(Node& root, FormAssociatedElement::List& elements) const
{
- return attribute.name() == actionAttr || HTMLElement::isURLAttribute(attribute);
+ elements.clear();
+ for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(root); element; element = Traversal<HTMLElement>::next(*element)) {
+ FormAssociatedElement* associatedElement = 0;
+ if (element->isFormControlElement())
+ associatedElement = toHTMLFormControlElement(element);
+ else if (isHTMLObjectElement(*element))
+ associatedElement = toHTMLObjectElement(element);
+ else
+ continue;
+ if (associatedElement->form()== this)
+ elements.append(associatedElement);
+ }
}
-void HTMLFormElement::registerImgElement(HTMLImageElement* e)
+// This function should be const conceptually. However we update some fields
+// because of lazy evaluation.
+const FormAssociatedElement::List& HTMLFormElement::associatedElements() const
{
- ASSERT(m_imageElements.find(e) == kNotFound);
- m_imageElements.append(e);
+ if (!m_associatedElementsAreDirty)
+ return m_associatedElements;
+ HTMLFormElement* mutableThis = const_cast<HTMLFormElement*>(this);
+ Node* scope = mutableThis;
+ if (m_hasElementsAssociatedByParser)
+ scope = &highestAncestorOrSelf();
+ if (inDocument() && treeScope().idTargetObserverRegistry().hasObservers(fastGetAttribute(idAttr)))
+ scope = &treeScope().rootNode();
+ ASSERT(scope);
+ collectAssociatedElements(*scope, mutableThis->m_associatedElements);
+ mutableThis->m_associatedElementsAreDirty = false;
+ return m_associatedElements;
}
-void HTMLFormElement::removeImgElement(HTMLImageElement* e)
+void HTMLFormElement::collectImageElements(Node& root, WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& elements)
{
- ASSERT(m_imageElements.find(e) != kNotFound);
- removeFromPastNamesMap(*e);
- removeFromVector(m_imageElements, e);
+ elements.clear();
+ for (HTMLImageElement* image = Traversal<HTMLImageElement>::firstWithin(root); image; image = Traversal<HTMLImageElement>::next(*image)) {
+ if (image->formOwner() == this)
+ elements.append(image);
+ }
}
-PassRefPtr<HTMLCollection> HTMLFormElement::elements()
+const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& HTMLFormElement::imageElements()
{
- return ensureCachedHTMLCollection(FormControls);
+ if (!m_imageElementsAreDirty)
+ return m_imageElements;
+ collectImageElements(m_hasElementsAssociatedByParser ? highestAncestorOrSelf() : *this, m_imageElements);
+ m_imageElementsAreDirty = false;
+ return m_imageElements;
}
String HTMLFormElement::name() const
@@ -646,11 +635,6 @@ const AtomicString& HTMLFormElement::action() const
return getAttribute(actionAttr);
}
-void HTMLFormElement::setAction(const AtomicString& value)
-{
- setAttribute(actionAttr, value);
-}
-
void HTMLFormElement::setEnctype(const AtomicString& value)
{
setAttribute(enctypeAttr, value);
@@ -666,11 +650,6 @@ void HTMLFormElement::setMethod(const AtomicString& value)
setAttribute(methodAttr, value);
}
-String HTMLFormElement::target() const
-{
- return getAttribute(targetAttr);
-}
-
bool HTMLFormElement::wasUserSubmitted() const
{
return m_wasUserSubmitted;
@@ -678,10 +657,11 @@ bool HTMLFormElement::wasUserSubmitted() const
HTMLFormControlElement* HTMLFormElement::defaultButton() const
{
- for (unsigned i = 0; i < m_associatedElements.size(); ++i) {
- if (!m_associatedElements[i]->isFormControlElement())
+ const FormAssociatedElement::List& elements = associatedElements();
+ for (unsigned i = 0; i < elements.size(); ++i) {
+ if (!elements[i]->isFormControlElement())
continue;
- HTMLFormControlElement* control = toHTMLFormControlElement(m_associatedElements[i]);
+ HTMLFormControlElement* control = toHTMLFormControlElement(elements[i]);
if (control->isSuccessfulSubmitButton())
return control;
}
@@ -691,61 +671,56 @@ HTMLFormControlElement* HTMLFormElement::defaultButton() const
bool HTMLFormElement::checkValidity()
{
- Vector<RefPtr<FormAssociatedElement> > controls;
- return !checkInvalidControlsAndCollectUnhandled(&controls);
-}
-
-bool HTMLFormElement::checkValidityWithoutDispatchingEvents()
-{
- return !checkInvalidControlsAndCollectUnhandled(0, HTMLFormControlElement::CheckValidityDispatchEventsNone);
+ return !checkInvalidControlsAndCollectUnhandled(0);
}
-bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >* unhandledInvalidControls, HTMLFormControlElement::CheckValidityDispatchEvents dispatchEvents)
+bool HTMLFormElement::checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> >* unhandledInvalidControls)
{
- RefPtr<HTMLFormElement> protector(this);
- // Copy m_associatedElements because event handlers called from
- // HTMLFormControlElement::checkValidity() might change m_associatedElements.
- Vector<RefPtr<FormAssociatedElement> > elements;
- elements.reserveCapacity(m_associatedElements.size());
- for (unsigned i = 0; i < m_associatedElements.size(); ++i)
- elements.append(m_associatedElements[i]);
+ RefPtrWillBeRawPtr<HTMLFormElement> protector(this);
+ // Copy associatedElements because event handlers called from
+ // HTMLFormControlElement::checkValidity() might change associatedElements.
+ const FormAssociatedElement::List& associatedElements = this->associatedElements();
+ WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> > elements;
+ elements.reserveCapacity(associatedElements.size());
+ for (unsigned i = 0; i < associatedElements.size(); ++i)
+ elements.append(associatedElements[i]);
bool hasInvalidControls = false;
for (unsigned i = 0; i < elements.size(); ++i) {
if (elements[i]->form() == this && elements[i]->isFormControlElement()) {
HTMLFormControlElement* control = toHTMLFormControlElement(elements[i].get());
- if (!control->checkValidity(unhandledInvalidControls, dispatchEvents) && control->formOwner() == this)
+ if (!control->checkValidity(unhandledInvalidControls) && control->formOwner() == this)
hasInvalidControls = true;
}
}
return hasInvalidControls;
}
-Node* HTMLFormElement::elementFromPastNamesMap(const AtomicString& pastName) const
+Element* HTMLFormElement::elementFromPastNamesMap(const AtomicString& pastName)
{
if (pastName.isEmpty() || !m_pastNamesMap)
return 0;
- Node* node = m_pastNamesMap->get(pastName);
-#if !ASSERT_DISABLED
- if (!node)
+ Element* element = m_pastNamesMap->get(pastName);
+#if ASSERT_ENABLED
+ if (!element)
return 0;
- ASSERT_WITH_SECURITY_IMPLICATION(toHTMLElement(node)->formOwner() == this);
- if (node->hasTagName(imgTag)) {
- ASSERT_WITH_SECURITY_IMPLICATION(m_imageElements.find(node) != kNotFound);
- } else if (node->hasTagName(objectTag)) {
- ASSERT_WITH_SECURITY_IMPLICATION(m_associatedElements.find(toHTMLObjectElement(node)) != kNotFound);
+ ASSERT_WITH_SECURITY_IMPLICATION(toHTMLElement(element)->formOwner() == this);
+ if (isHTMLImageElement(*element)) {
+ ASSERT_WITH_SECURITY_IMPLICATION(imageElements().find(element) != kNotFound);
+ } else if (isHTMLObjectElement(*element)) {
+ ASSERT_WITH_SECURITY_IMPLICATION(associatedElements().find(toHTMLObjectElement(element)) != kNotFound);
} else {
- ASSERT_WITH_SECURITY_IMPLICATION(m_associatedElements.find(toHTMLFormControlElement(node)) != kNotFound);
+ ASSERT_WITH_SECURITY_IMPLICATION(associatedElements().find(toHTMLFormControlElement(element)) != kNotFound);
}
#endif
- return node;
+ return element;
}
-void HTMLFormElement::addToPastNamesMap(Node* element, const AtomicString& pastName)
+void HTMLFormElement::addToPastNamesMap(Element* element, const AtomicString& pastName)
{
if (pastName.isEmpty())
return;
if (!m_pastNamesMap)
- m_pastNamesMap = adoptPtr(new PastNamesMap);
+ m_pastNamesMap = adoptPtrWillBeNoop(new PastNamesMap);
m_pastNamesMap->set(pastName, element);
}
@@ -756,22 +731,24 @@ void HTMLFormElement::removeFromPastNamesMap(HTMLElement& element)
PastNamesMap::iterator end = m_pastNamesMap->end();
for (PastNamesMap::iterator it = m_pastNamesMap->begin(); it != end; ++it) {
if (it->value == &element) {
- it->value = 0;
+ it->value = nullptr;
// Keep looping. Single element can have multiple names.
}
}
}
-void HTMLFormElement::getNamedElements(const AtomicString& name, Vector<RefPtr<Node> >& namedItems)
+void HTMLFormElement::getNamedElements(const AtomicString& name, WillBeHeapVector<RefPtrWillBeMember<Element> >& namedItems)
{
// http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#dom-form-nameditem
elements()->namedItems(name, namedItems);
- Node* elementFromPast = elementFromPastNamesMap(name);
- if (namedItems.size() && namedItems.first() != elementFromPast)
+ Element* elementFromPast = elementFromPastNamesMap(name);
+ if (namedItems.size() && namedItems.first() != elementFromPast) {
addToPastNamesMap(namedItems.first().get(), name);
- else if (elementFromPast && namedItems.isEmpty())
+ } else if (elementFromPast && namedItems.isEmpty()) {
namedItems.append(elementFromPast);
+ UseCounter::count(document(), UseCounter::FormNameAccessForPastNamesMap);
+ }
}
bool HTMLFormElement::shouldAutocomplete() const
@@ -782,7 +759,8 @@ bool HTMLFormElement::shouldAutocomplete() const
void HTMLFormElement::finishParsingChildren()
{
HTMLElement::finishParsingChildren();
- document().formController()->restoreControlStateIn(*this);
+ document().formController().restoreControlStateIn(*this);
+ m_didFinishParsingChildren = true;
}
void HTMLFormElement::copyNonAttributePropertiesFromElement(const Element& source)
@@ -791,13 +769,13 @@ void HTMLFormElement::copyNonAttributePropertiesFromElement(const Element& sourc
HTMLElement::copyNonAttributePropertiesFromElement(source);
}
-void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Node>& returnValue1)
+void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtrWillBeRawPtr<RadioNodeList>& returnValue0, bool& returnValue1Enabled, RefPtrWillBeRawPtr<Element>& returnValue1)
{
// Call getNamedElements twice, first time check if it has a value
// and let HTMLFormElement update its cache.
// See issue: 867404
{
- Vector<RefPtr<Node> > elements;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > elements;
getNamedElements(name, elements);
if (elements.isEmpty())
return;
@@ -805,7 +783,7 @@ void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, bool& retur
// Second call may return different results from the first call,
// but if the first the size cannot be zero.
- Vector<RefPtr<Node> > elements;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > elements;
getNamedElements(name, elements);
ASSERT(!elements.isEmpty());
@@ -815,8 +793,9 @@ void HTMLFormElement::anonymousNamedGetter(const AtomicString& name, bool& retur
return;
}
+ bool onlyMatchImg = !elements.isEmpty() && isHTMLImageElement(*elements.first());
returnValue0Enabled = true;
- returnValue0 = NamedNodesCollection::create(elements);
+ returnValue0 = radioNodeList(name, onlyMatchImg);
}
void HTMLFormElement::setDemoted(bool demoted)
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h
index d2f118e08c3..b4fb4793566 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.h
@@ -26,10 +26,10 @@
#include "core/html/HTMLElement.h"
#include "core/html/HTMLFormControlElement.h"
-#include "core/html/forms/CheckedRadioButtons.h"
-#include "core/loader/FormState.h"
+#include "core/html/forms/RadioButtonGroupScope.h"
#include "core/loader/FormSubmission.h"
#include "wtf/OwnPtr.h"
+#include "wtf/WeakPtr.h"
namespace WTF{
class TextEncoding;
@@ -40,20 +40,23 @@ namespace WebCore {
class Event;
class FormAssociatedElement;
class FormData;
+class GenericEventQueue;
class HTMLFormControlElement;
+class HTMLFormControlsCollection;
class HTMLImageElement;
class HTMLInputElement;
class HTMLFormElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLFormElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLFormElement> create(Document&);
virtual ~HTMLFormElement();
+ virtual void trace(Visitor*) OVERRIDE;
- PassRefPtr<HTMLCollection> elements();
- void getNamedElements(const AtomicString&, Vector<RefPtr<Node> >&);
+ PassRefPtrWillBeRawPtr<HTMLFormControlsCollection> elements();
+ void getNamedElements(const AtomicString&, WillBeHeapVector<RefPtrWillBeMember<Element> >&);
unsigned length() const;
- Node* item(unsigned index);
+ Element* item(unsigned index);
String enctype() const { return m_attributes.encodingType(); }
void setEnctype(const AtomicString&);
@@ -63,14 +66,16 @@ public:
bool shouldAutocomplete() const;
- // FIXME: Should rename these two functions to say "form control" or "form-associated element" instead of "form element".
- void registerFormElement(FormAssociatedElement&);
- void removeFormElement(FormAssociatedElement*);
+ void associate(FormAssociatedElement&);
+ void disassociate(FormAssociatedElement&);
+ void associate(HTMLImageElement&);
+ void disassociate(HTMLImageElement&);
+#if !ENABLE(OILPAN)
+ WeakPtr<HTMLFormElement> createWeakPtr();
+#endif
+ void didAssociateByParser();
- void registerImgElement(HTMLImageElement*);
- void removeImgElement(HTMLImageElement*);
-
- bool prepareForSubmission(Event*);
+ void prepareForSubmission(Event*);
void submit();
void submitFromJavaScript();
void reset();
@@ -78,26 +83,21 @@ public:
void setDemoted(bool);
void submitImplicitly(Event*, bool fromImplicitSubmissionTrigger);
- bool formWouldHaveSecureSubmission(const String& url);
String name() const;
bool noValidate() const;
const AtomicString& action() const;
- void setAction(const AtomicString&);
String method() const;
void setMethod(const AtomicString&);
- virtual String target() const;
-
bool wasUserSubmitted() const;
HTMLFormControlElement* defaultButton() const;
bool checkValidity();
- bool checkValidityWithoutDispatchingEvents();
enum AutocompleteResult {
AutocompleteResultSuccess,
@@ -112,38 +112,38 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(autocomplete);
DEFINE_ATTRIBUTE_EVENT_LISTENER(autocompleteerror);
- CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
+ RadioButtonGroupScope& radioButtonGroupScope() { return m_radioButtonGroupScope; }
- const Vector<FormAssociatedElement*>& associatedElements() const { return m_associatedElements; }
- const Vector<HTMLImageElement*>& imageElements() const { return m_imageElements; }
+ const FormAssociatedElement::List& associatedElements() const;
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >& imageElements();
- void getTextFieldValues(StringPairVector& fieldNamesAndValues) const;
- void anonymousNamedGetter(const AtomicString& name, bool&, RefPtr<NodeList>&, bool&, RefPtr<Node>&);
+ void anonymousNamedGetter(const AtomicString& name, bool&, RefPtrWillBeRawPtr<RadioNodeList>&, bool&, RefPtrWillBeRawPtr<Element>&);
private:
explicit HTMLFormElement(Document&);
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual void finishParsingChildren() OVERRIDE;
- virtual void handleLocalEvents(Event*);
+ virtual void handleLocalEvents(Event*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
virtual bool shouldRegisterAsNamedItem() const OVERRIDE { return true; }
virtual void copyNonAttributePropertiesFromElement(const Element&) OVERRIDE;
- void submitDialog(PassRefPtr<FormSubmission>);
+ void submitDialog(PassRefPtrWillBeRawPtr<FormSubmission>);
void submit(Event*, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger);
- void scheduleFormSubmission(PassRefPtr<FormSubmission>);
+ void scheduleFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission>);
- unsigned formElementIndexWithFormAttribute(Element*, unsigned rangeStart, unsigned rangeEnd);
- unsigned formElementIndex(FormAssociatedElement&);
+ void collectAssociatedElements(Node& root, FormAssociatedElement::List&) const;
+ void collectImageElements(Node& root, WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> >&);
// Returns true if the submission should proceed.
bool validateInteractively(Event*);
@@ -151,40 +151,40 @@ private:
// Validates each of the controls, and stores controls of which 'invalid'
// event was not canceled to the specified vector. Returns true if there
// are any invalid controls in this form.
- bool checkInvalidControlsAndCollectUnhandled(Vector<RefPtr<FormAssociatedElement> >*, HTMLFormControlElement::CheckValidityDispatchEvents = HTMLFormControlElement::CheckValidityDispatchEventsAllowed);
+ bool checkInvalidControlsAndCollectUnhandled(WillBeHeapVector<RefPtrWillBeMember<FormAssociatedElement> >*);
- Node* elementFromPastNamesMap(const AtomicString&) const;
- void addToPastNamesMap(Node*, const AtomicString& pastName);
+ Element* elementFromPastNamesMap(const AtomicString&);
+ void addToPastNamesMap(Element*, const AtomicString& pastName);
void removeFromPastNamesMap(HTMLElement&);
- typedef HashMap<AtomicString, Node*> PastNamesMap;
+ typedef WillBeHeapHashMap<AtomicString, RawPtrWillBeMember<Element> > PastNamesMap;
FormSubmission::Attributes m_attributes;
- OwnPtr<PastNamesMap> m_pastNamesMap;
-
- CheckedRadioButtons m_checkedRadioButtons;
-
- unsigned m_associatedElementsBeforeIndex;
- unsigned m_associatedElementsAfterIndex;
- Vector<FormAssociatedElement*> m_associatedElements;
- Vector<HTMLImageElement*> m_imageElements;
+ OwnPtrWillBeMember<PastNamesMap> m_pastNamesMap;
+
+ RadioButtonGroupScope m_radioButtonGroupScope;
+
+ // Do not access m_associatedElements directly. Use associatedElements() instead.
+ FormAssociatedElement::List m_associatedElements;
+ // Do not access m_imageElements directly. Use imageElements() instead.
+ WillBeHeapVector<RawPtrWillBeMember<HTMLImageElement> > m_imageElements;
+#if !ENABLE(OILPAN)
+ WeakPtrFactory<HTMLFormElement> m_weakPtrFactory;
+#endif
+ bool m_associatedElementsAreDirty;
+ bool m_imageElementsAreDirty;
+ bool m_hasElementsAssociatedByParser;
+ bool m_didFinishParsingChildren;
bool m_wasUserSubmitted;
- bool m_isSubmittingOrPreparingForSubmission;
- bool m_shouldSubmit;
bool m_isInResetFunction;
bool m_wasDemoted;
- void requestAutocompleteTimerFired(Timer<HTMLFormElement>*);
-
- Vector<RefPtr<Event> > m_pendingAutocompleteEvents;
- Timer<HTMLFormElement> m_requestAutocompleteTimer;
+ OwnPtrWillBeMember<GenericEventQueue> m_pendingAutocompleteEventsQueue;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFormElement, hasTagName(HTMLNames::formTag));
-
} // namespace WebCore
#endif // HTMLFormElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl
index 6ba5f418c01..68283fc8058 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFormElement.idl
@@ -18,10 +18,12 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLFormElement : HTMLElement {
+[
+ OverrideBuiltins,
+] interface HTMLFormElement : HTMLElement {
[Reflect=accept_charset] attribute DOMString acceptCharset;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString action;
- [Reflect] attribute DOMString autocomplete;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString action;
+ [Reflect, ReflectOnly="on"|"off", ReflectMissing="on", ReflectInvalid="on"] attribute DOMString autocomplete;
[CustomElementCallbacks] attribute DOMString enctype;
[CustomElementCallbacks] attribute DOMString encoding;
[CustomElementCallbacks] attribute DOMString method;
@@ -31,14 +33,12 @@ interface HTMLFormElement : HTMLElement {
readonly attribute HTMLCollection elements;
readonly attribute long length;
- [ImplementedAs=item] getter Node(unsigned long index);
- [ImplementedAs=anonymousNamedGetter, OverrideBuiltins, NotEnumerable] getter (NodeList or Node)(DOMString name);
+ [ImplementedAs=item] getter Element (unsigned long index);
+ [NotEnumerable] getter (RadioNodeList or Element) (DOMString name);
- [ImplementedAs=submitFromJavaScript, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] void submit();
+ [ImplementedAs=submitFromJavaScript, LogActivity] void submit();
[CustomElementCallbacks] void reset();
boolean checkValidity();
[RuntimeEnabled=RequestAutocomplete] void requestAutocomplete();
- [RuntimeEnabled=RequestAutocomplete] attribute EventHandler onautocomplete;
- [RuntimeEnabled=RequestAutocomplete] attribute EventHandler onautocompleteerror;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
index 218a2216167..7f5a19fbf82 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "core/html/HTMLFrameElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLFrameSetElement.h"
#include "core/rendering/RenderFrame.h"
@@ -40,10 +40,7 @@ inline HTMLFrameElement::HTMLFrameElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLFrameElement> HTMLFrameElement::create(Document& document)
-{
- return adoptRef(new HTMLFrameElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLFrameElement)
bool HTMLFrameElement::rendererIsNeeded(const RenderStyle&)
{
@@ -56,15 +53,6 @@ RenderObject* HTMLFrameElement::createRenderer(RenderStyle*)
return new RenderFrame(this);
}
-static inline HTMLFrameSetElement* containingFrameSetElement(Node* node)
-{
- while ((node = node->parentNode())) {
- if (node->hasTagName(framesetTag))
- return toHTMLFrameSetElement(node);
- }
- return 0;
-}
-
bool HTMLFrameElement::noResize() const
{
return hasAttribute(noresizeAttr);
@@ -74,7 +62,7 @@ void HTMLFrameElement::attach(const AttachContext& context)
{
HTMLFrameElementBase::attach(context);
- if (HTMLFrameSetElement* frameSetElement = containingFrameSetElement(this)) {
+ if (HTMLFrameSetElement* frameSetElement = Traversal<HTMLFrameSetElement>::firstAncestor(*this)) {
if (!m_frameBorderSet)
m_frameBorder = frameSetElement->hasFrameBorder();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h
index 72ca10399ab..20ba93597bc 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLFrameElement FINAL : public HTMLFrameElementBase {
public:
- static PassRefPtr<HTMLFrameElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLFrameElement);
bool hasFrameBorder() const { return m_frameBorder; }
@@ -41,19 +41,15 @@ private:
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool allowFullScreen() const { return false; }
-
bool m_frameBorder;
bool m_frameBorderSet;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFrameElement, hasTagName(HTMLNames::frameTag));
-
} // namespace WebCore
#endif // HTMLFrameElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
index 1ab494ce552..ed43c3c69e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElement.idl
@@ -27,7 +27,7 @@ interface HTMLFrameElement : HTMLElement {
[Reflect] attribute DOMString name;
[Reflect] attribute boolean noResize;
[Reflect] attribute DOMString scrolling;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
// Introduced in DOM Level 2:
[CheckSecurity=Node] readonly attribute Document contentDocument;
@@ -35,10 +35,8 @@ interface HTMLFrameElement : HTMLElement {
// Extensions
readonly attribute Window contentWindow;
- [CheckSecurity=Node, RaisesException] SVGDocument getSVGDocument();
+ [CheckSecurity=Node, RaisesException] Document getSVGDocument();
- [TreatNullAs=NullString, Custom=Setter, MeasureAs=HTMLFrameElementLocation] attribute DOMString location;
-
- readonly attribute long width;
- readonly attribute long height;
+ [MeasureAs=HTMLFrameElementWidth] readonly attribute long width;
+ [MeasureAs=HTMLFrameElementHeight] readonly attribute long height;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp
index fc6bfb98c35..182189a86e5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.cpp
@@ -24,17 +24,17 @@
#include "config.h"
#include "core/html/HTMLFrameElementBase.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/loader/FrameLoader.h"
+#include "core/page/ChromeClient.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/rendering/RenderPart.h"
@@ -63,7 +63,7 @@ bool HTMLFrameElementBase::isURLAllowed() const
return false;
}
- Frame* parentFrame = document().frame();
+ LocalFrame* parentFrame = document().frame();
if (parentFrame)
return parentFrame->isURLAllowed(completeURL);
@@ -76,9 +76,9 @@ void HTMLFrameElementBase::openURL(bool lockBackForwardList)
return;
if (m_URL.isEmpty())
- m_URL = blankURL().string();
+ m_URL = AtomicString(blankURL().string());
- Frame* parentFrame = document().frame();
+ LocalFrame* parentFrame = document().frame();
if (!parentFrame)
return;
@@ -92,9 +92,9 @@ void HTMLFrameElementBase::openURL(bool lockBackForwardList)
if (!loadOrRedirectSubframe(url, m_frameName, lockBackForwardList))
return;
- if (!contentFrame() || scriptURL.isEmpty())
+ if (!contentFrame() || scriptURL.isEmpty() || !contentFrame()->isLocalFrame())
return;
- contentFrame()->script().executeScriptIfJavaScriptURL(scriptURL);
+ toLocalFrame(contentFrame())->script().executeScriptIfJavaScriptURL(scriptURL);
}
void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -125,11 +125,9 @@ void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const Atomi
else if (equalIgnoringCase(value, "no"))
m_scrolling = ScrollbarAlwaysOff;
// FIXME: If we are already attached, this has no effect.
- } else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
- else if (name == onbeforeunloadAttr) {
+ } else if (name == onbeforeunloadAttr) {
// FIXME: should <frame> elements have beforeunload handlers?
- setAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(this, name, value, eventParameterName()));
} else
HTMLFrameOwnerElement::parseAttribute(name, value);
}
@@ -137,8 +135,6 @@ void HTMLFrameElementBase::parseAttribute(const QualifiedName& name, const Atomi
void HTMLFrameElementBase::setNameAndOpenURL()
{
m_frameName = getNameAttribute();
- if (m_frameName.isNull())
- m_frameName = getIdAttribute();
openURL();
}
@@ -163,19 +159,14 @@ void HTMLFrameElementBase::attach(const AttachContext& context)
{
HTMLFrameOwnerElement::attach(context);
- if (RenderPart* part = renderPart()) {
- if (Frame* frame = contentFrame())
- part->setWidget(frame->view());
+ if (renderPart()) {
+ if (Frame* frame = contentFrame()) {
+ if (frame->isLocalFrame())
+ setWidget(toLocalFrame(frame)->view());
+ }
}
}
-KURL HTMLFrameElementBase::location() const
-{
- if (fastHasAttribute(srcdocAttr))
- return KURL(ParsedURLString, "about:srcdoc");
- return document().completeURL(getAttribute(srcAttr));
-}
-
void HTMLFrameElementBase::setLocation(const String& str)
{
m_URL = AtomicString(str);
@@ -196,7 +187,7 @@ void HTMLFrameElementBase::setFocus(bool received)
if (received)
page->focusController().setFocusedFrame(contentFrame());
else if (page->focusController().focusedFrame() == contentFrame()) // Focus may have already been given to another frame, don't take it away.
- page->focusController().setFocusedFrame(0);
+ page->focusController().setFocusedFrame(nullptr);
}
}
@@ -206,6 +197,11 @@ bool HTMLFrameElementBase::isURLAttribute(const Attribute& attribute) const
|| HTMLFrameOwnerElement::isURLAttribute(attribute);
}
+bool HTMLFrameElementBase::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == srcAttr || HTMLFrameOwnerElement::hasLegalLinkAttribute(name);
+}
+
bool HTMLFrameElementBase::isHTMLContentAttribute(const Attribute& attribute) const
{
return attribute.name() == srcdocAttr || HTMLFrameOwnerElement::isHTMLContentAttribute(attribute);
@@ -227,4 +223,15 @@ int HTMLFrameElementBase::height()
return renderBox()->height();
}
+// FIXME: Remove this code once we have input routing in the browser
+// process. See http://crbug.com/339659.
+void HTMLFrameElementBase::defaultEventHandler(Event* event)
+{
+ if (contentFrame() && contentFrame()->isRemoteFrameTemporary()) {
+ contentFrame()->chromeClient().forwardInputEvent(contentFrame(), event);
+ return;
+ }
+ HTMLFrameOwnerElement::defaultEventHandler(event);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h
index 9352e4e7056..dc6d9204385 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameElementBase.h
@@ -31,10 +31,7 @@ namespace WebCore {
class HTMLFrameElementBase : public HTMLFrameOwnerElement {
public:
- KURL location() const;
- void setLocation(const String&);
-
- virtual ScrollbarMode scrollingMode() const { return m_scrolling; }
+ virtual ScrollbarMode scrollingMode() const OVERRIDE FINAL { return m_scrolling; }
int marginWidth() const { return m_marginWidth; }
int marginHeight() const { return m_marginHeight; }
@@ -42,7 +39,7 @@ public:
int width();
int height();
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return false; }
protected:
HTMLFrameElementBase(const QualifiedName&, Document&);
@@ -51,20 +48,24 @@ protected:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
+ virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE FINAL;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
-private:
- virtual bool supportsFocus() const;
- virtual void setFocus(bool) OVERRIDE;
+ // FIXME: Remove this method once we have input routing in the browser
+ // process. See http://crbug.com/339659.
+ virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual bool isHTMLContentAttribute(const Attribute&) const OVERRIDE;
+private:
+ virtual bool supportsFocus() const OVERRIDE FINAL;
+ virtual void setFocus(bool) OVERRIDE FINAL;
- virtual bool isFrameElementBase() const { return true; }
+ virtual bool isURLAttribute(const Attribute&) const OVERRIDE FINAL;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual bool isHTMLContentAttribute(const Attribute&) const OVERRIDE FINAL;
- virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
+ virtual bool areAuthorShadowsAllowed() const OVERRIDE FINAL { return false; }
+ void setLocation(const String&);
void setNameAndOpenURL();
void openURL(bool lockBackForwardList = true);
@@ -77,12 +78,17 @@ private:
int m_marginHeight;
};
-inline bool isHTMLFrameElementBase(const Node& node)
+inline bool isHTMLFrameElementBase(const Element& element)
+{
+ return isHTMLFrameElement(element) || isHTMLIFrameElement(element);
+}
+
+inline bool isHTMLFrameElementBase(const HTMLElement& element)
{
- return node.isElementNode() && toElement(node).isFrameElementBase();
+ return isHTMLFrameElement(element) || isHTMLIFrameElement(element);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLFrameElementBase);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLFrameElementBase);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
index aaa73ff224c..3a5fea5d421 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
@@ -23,21 +23,77 @@
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/accessibility/AXObjectCache.h"
#include "core/dom/ExceptionCode.h"
+#include "core/events/Event.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
+#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderPart.h"
-#include "core/svg/SVGDocument.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "platform/weborigin/SecurityPolicy.h"
namespace WebCore {
+typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
+static WidgetToParentMap& widgetNewParentMap()
+{
+ DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ());
+ return map;
+}
+
+static unsigned s_updateSuspendCount = 0;
+
+HTMLFrameOwnerElement::UpdateSuspendScope::UpdateSuspendScope()
+{
+ ++s_updateSuspendCount;
+}
+
+void HTMLFrameOwnerElement::UpdateSuspendScope::performDeferredWidgetTreeOperations()
+{
+ WidgetToParentMap map;
+ widgetNewParentMap().swap(map);
+ WidgetToParentMap::iterator end = map.end();
+ for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) {
+ Widget* child = it->key.get();
+ ScrollView* currentParent = toScrollView(child->parent());
+ FrameView* newParent = it->value;
+ if (newParent != currentParent) {
+ if (currentParent)
+ currentParent->removeChild(child);
+ if (newParent)
+ newParent->addChild(child);
+ }
+ }
+}
+
+HTMLFrameOwnerElement::UpdateSuspendScope::~UpdateSuspendScope()
+{
+ ASSERT(s_updateSuspendCount > 0);
+ if (s_updateSuspendCount == 1)
+ performDeferredWidgetTreeOperations();
+ --s_updateSuspendCount;
+}
+
+static void moveWidgetToParentSoon(Widget* child, FrameView* parent)
+{
+ if (!s_updateSuspendCount) {
+ if (parent)
+ parent->addChild(child);
+ else if (toScrollView(child->parent()))
+ toScrollView(child->parent())->removeChild(child);
+ return;
+ }
+ widgetNewParentMap().set(child, parent);
+}
+
HTMLFrameOwnerElement::HTMLFrameOwnerElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
, m_contentFrame(0)
+ , m_widget(nullptr)
, m_sandboxFlags(SandboxNone)
{
}
@@ -54,7 +110,7 @@ RenderPart* HTMLFrameOwnerElement::renderPart() const
void HTMLFrameOwnerElement::setContentFrame(Frame& frame)
{
// Make sure we will not end up with two frames referencing the same owner element.
- ASSERT(!m_contentFrame || m_contentFrame->ownerElement() != this);
+ ASSERT(!m_contentFrame || m_contentFrame->owner() != this);
// Disconnected frames should not be allowed to load.
ASSERT(inDocument());
m_contentFrame = &frame;
@@ -82,7 +138,8 @@ void HTMLFrameOwnerElement::disconnectContentFrame()
// see if this behavior is really needed as Gecko does not allow this.
if (Frame* frame = contentFrame()) {
RefPtr<Frame> protect(frame);
- frame->loader().frameDetached();
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->loader().frameDetached();
frame->disconnectOwnerElement();
}
}
@@ -95,10 +152,10 @@ HTMLFrameOwnerElement::~HTMLFrameOwnerElement()
Document* HTMLFrameOwnerElement::contentDocument() const
{
- return m_contentFrame ? m_contentFrame->document() : 0;
+ return (m_contentFrame && m_contentFrame->isLocalFrame()) ? toLocalFrame(m_contentFrame)->document() : 0;
}
-DOMWindow* HTMLFrameOwnerElement::contentWindow() const
+LocalDOMWindow* HTMLFrameOwnerElement::contentWindow() const
{
return m_contentFrame ? m_contentFrame->domWindow() : 0;
}
@@ -113,19 +170,59 @@ bool HTMLFrameOwnerElement::isKeyboardFocusable() const
return m_contentFrame && HTMLElement::isKeyboardFocusable();
}
-SVGDocument* HTMLFrameOwnerElement::getSVGDocument(ExceptionState& exceptionState) const
+void HTMLFrameOwnerElement::dispatchLoad()
+{
+ dispatchEvent(Event::create(EventTypeNames::load));
+}
+
+Document* HTMLFrameOwnerElement::getSVGDocument(ExceptionState& exceptionState) const
{
Document* doc = contentDocument();
if (doc && doc->isSVGDocument())
- return toSVGDocument(doc);
+ return doc;
return 0;
}
+void HTMLFrameOwnerElement::setWidget(PassRefPtr<Widget> widget)
+{
+ if (widget == m_widget)
+ return;
+
+ if (m_widget) {
+ if (m_widget->parent())
+ moveWidgetToParentSoon(m_widget.get(), 0);
+ m_widget = nullptr;
+ }
+
+ m_widget = widget;
+
+ RenderWidget* renderWidget = toRenderWidget(renderer());
+ if (!renderWidget)
+ return;
+
+ if (m_widget) {
+ renderWidget->updateOnWidgetChange();
+
+ ASSERT(document().view() == renderWidget->frameView());
+ ASSERT(renderWidget->frameView());
+ moveWidgetToParentSoon(m_widget.get(), renderWidget->frameView());
+ }
+
+ if (AXObjectCache* cache = document().existingAXObjectCache())
+ cache->childrenChanged(renderWidget);
+}
+
+Widget* HTMLFrameOwnerElement::ownedWidget() const
+{
+ return m_widget.get();
+}
+
bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const AtomicString& frameName, bool lockBackForwardList)
{
- RefPtr<Frame> parentFrame = document().frame();
- if (contentFrame()) {
- contentFrame()->navigationScheduler().scheduleLocationChange(&document(), url.string(), document().outgoingReferrer(), lockBackForwardList);
+ RefPtr<LocalFrame> parentFrame = document().frame();
+ // FIXME(kenrb): The necessary semantics for RemoteFrames have not been worked out yet, but this will likely need some logic to handle them.
+ if (contentFrame() && contentFrame()->isLocalFrame()) {
+ toLocalFrame(contentFrame())->navigationScheduler().scheduleLocationChange(&document(), url.string(), Referrer(document().outgoingReferrer(), document().referrerPolicy()), lockBackForwardList);
return true;
}
@@ -138,7 +235,7 @@ bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const Atomic
return false;
String referrer = SecurityPolicy::generateReferrerHeader(document().referrerPolicy(), url, document().outgoingReferrer());
- RefPtr<Frame> childFrame = parentFrame->loader().client()->createFrame(url, frameName, referrer, this);
+ RefPtr<LocalFrame> childFrame = parentFrame->loader().client()->createFrame(url, frameName, Referrer(referrer, document().referrerPolicy()), this);
if (!childFrame) {
parentFrame->loader().checkCompleted();
@@ -153,10 +250,12 @@ bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const Atomic
// FIXME: Can we remove this entirely? m_isComplete normally gets set to false when a load is committed.
childFrame->loader().started();
- RenderObject* renderObject = renderer();
FrameView* view = childFrame->view();
+ RenderObject* renderObject = renderer();
+ // We need to test the existence of renderObject and its widget-ness, as
+ // failing to do so causes problems.
if (renderObject && renderObject->isWidget() && view)
- toRenderWidget(renderObject)->setWidget(view);
+ setWidget(view);
// Some loads are performed synchronously (e.g., about:blank and loads
// cancelled by returning a null ResourceRequest from requestFromDelegate).
@@ -164,7 +263,7 @@ bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const Atomic
// before we could connect the signals, so make sure to send the
// completed() signal for the child by hand and mark the load as being
// complete.
- // FIXME: In this case the Frame will have finished loading before
+ // FIXME: In this case the LocalFrame will have finished loading before
// it's being added to the child list. It would be a good idea to
// create the child first, then invoke the loader separately.
if (childFrame->loader().state() == FrameStateComplete && !childFrame->loader().policyDocumentLoader())
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h
index 834ac123c70..b9f4a7bbfe8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.h
@@ -21,23 +21,25 @@
#ifndef HTMLFrameOwnerElement_h
#define HTMLFrameOwnerElement_h
+#include "core/dom/Document.h"
+#include "core/frame/FrameOwner.h"
#include "core/html/HTMLElement.h"
#include "wtf/HashCountedSet.h"
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class ExceptionState;
class Frame;
class RenderPart;
-class SVGDocument;
+class Widget;
-class HTMLFrameOwnerElement : public HTMLElement {
+class HTMLFrameOwnerElement : public HTMLElement, public FrameOwner {
public:
virtual ~HTMLFrameOwnerElement();
Frame* contentFrame() const { return m_contentFrame; }
- DOMWindow* contentWindow() const;
+ LocalDOMWindow* contentWindow() const;
Document* contentDocument() const;
void setContentFrame(Frame&);
@@ -50,18 +52,27 @@ public:
// RenderObject when using fallback content.
RenderPart* renderPart() const;
- SVGDocument* getSVGDocument(ExceptionState&) const;
+ Document* getSVGDocument(ExceptionState&) const;
virtual ScrollbarMode scrollingMode() const { return ScrollbarAuto; }
- SandboxFlags sandboxFlags() const { return m_sandboxFlags; }
-
virtual bool loadedNonEmptyDocument() const { return false; }
virtual void didLoadNonEmptyDocument() { }
virtual void renderFallbackContent() { }
virtual bool isObjectElement() const { return false; }
+ void setWidget(PassRefPtr<Widget>);
+ Widget* ownedWidget() const;
+
+ class UpdateSuspendScope {
+ public:
+ UpdateSuspendScope();
+ ~UpdateSuspendScope();
+
+ private:
+ void performDeferredWidgetTreeOperations();
+ };
protected:
HTMLFrameOwnerElement(const QualifiedName& tagName, Document&);
@@ -71,13 +82,19 @@ protected:
private:
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual bool isFrameOwnerElement() const OVERRIDE { return true; }
+ virtual bool isFrameOwnerElement() const OVERRIDE FINAL { return true; }
+
+ // FrameOwner overrides:
+ virtual bool isLocal() const { return true; }
+ virtual SandboxFlags sandboxFlags() const OVERRIDE { return m_sandboxFlags; }
+ virtual void dispatchLoad() OVERRIDE;
Frame* m_contentFrame;
+ RefPtr<Widget> m_widget;
SandboxFlags m_sandboxFlags;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFrameOwnerElement, isFrameOwnerElement());
+DEFINE_ELEMENT_TYPE_CASTS(HTMLFrameOwnerElement, isFrameOwnerElement());
class SubframeLoadingDisabler {
public:
@@ -94,6 +111,8 @@ public:
static bool canLoadFrame(HTMLFrameOwnerElement& owner)
{
+ if (owner.document().unloadStarted())
+ return false;
for (Node* node = &owner; node; node = node->parentOrShadowHostNode()) {
if (disabledSubtreeRoots().contains(node))
return false;
@@ -111,6 +130,8 @@ private:
Node& m_root;
};
+DEFINE_TYPE_CASTS(HTMLFrameOwnerElement, FrameOwner, owner, owner->isLocal(), owner.isLocal());
+
} // namespace WebCore
#endif // HTMLFrameOwnerElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
index cfa41341e71..0a00f463f19 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.cpp
@@ -24,24 +24,23 @@
#include "config.h"
#include "core/html/HTMLFrameSetElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLFrameElement.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderFrameSet.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLFrameSetElement::HTMLFrameSetElement(Document& document)
+inline HTMLFrameSetElement::HTMLFrameSetElement(Document& document)
: HTMLElement(framesetTag, document)
, m_border(6)
, m_borderSet(false)
@@ -54,10 +53,7 @@ HTMLFrameSetElement::HTMLFrameSetElement(Document& document)
setHasCustomStyleCallbacks();
}
-PassRefPtr<HTMLFrameSetElement> HTMLFrameSetElement::create(Document& document)
-{
- return adoptRef(new HTMLFrameSetElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLFrameSetElement)
bool HTMLFrameSetElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -79,12 +75,12 @@ void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const Atomic
if (name == rowsAttr) {
if (!value.isNull()) {
m_rowLengths = parseListOfDimensions(value.string());
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
} else if (name == colsAttr) {
if (!value.isNull()) {
m_colLengths = parseListOfDimensions(value.string());
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
} else if (name == frameborderAttr) {
if (!value.isNull()) {
@@ -109,45 +105,45 @@ void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const Atomic
} else if (name == bordercolorAttr)
m_borderColorSet = !value.isEmpty();
else if (name == onloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::load, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onbeforeunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::beforeunload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpagehideAttr)
- document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::pagehide, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpageshowAttr)
- document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::pageshow, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onblurAttr)
- document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::blur, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onerrorAttr)
- document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onfocusAttr)
- document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::focus, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onfocusinAttr)
- document().setWindowAttributeEventListener(EventTypeNames::focusin, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::focusin, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onfocusoutAttr)
- document().setWindowAttributeEventListener(EventTypeNames::focusout, createAttributeEventListener(document().frame(), name, value));
-#if ENABLE(ORIENTATION_EVENTS)
- else if (name == onorientationchangeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value));
-#endif
+ document().setWindowAttributeEventListener(EventTypeNames::focusout, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ else if (RuntimeEnabledFeatures::orientationEventEnabled() && name == onorientationchangeAttr)
+ document().setWindowAttributeEventListener(EventTypeNames::orientationchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onhashchangeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::hashchange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onmessageAttr)
- document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::message, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onresizeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onscrollAttr)
- document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onstorageAttr)
- document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::storage, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == ononlineAttr)
- document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::online, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onofflineAttr)
- document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::offline, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == onpopstateAttr)
- document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::popstate, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ else if (name == onlanguagechangeAttr)
+ document().setWindowAttributeEventListener(EventTypeNames::languagechange, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else
HTMLElement::parseAttribute(name, value);
}
@@ -171,21 +167,17 @@ void HTMLFrameSetElement::attach(const AttachContext& context)
{
// Inherit default settings from parent frameset
// FIXME: This is not dynamic.
- for (ContainerNode* node = parentNode(); node; node = node->parentNode()) {
- if (node->hasTagName(framesetTag)) {
- HTMLFrameSetElement* frameset = toHTMLFrameSetElement(node);
- if (!m_frameborderSet)
- m_frameborder = frameset->hasFrameBorder();
- if (m_frameborder) {
- if (!m_borderSet)
- m_border = frameset->border();
- if (!m_borderColorSet)
- m_borderColorSet = frameset->hasBorderColor();
- }
- if (!m_noresize)
- m_noresize = frameset->noResize();
- break;
+ if (HTMLFrameSetElement* frameset = Traversal<HTMLFrameSetElement>::firstAncestor(*this)) {
+ if (!m_frameborderSet)
+ m_frameborder = frameset->hasFrameBorder();
+ if (m_frameborder) {
+ if (!m_borderSet)
+ m_border = frameset->border();
+ if (!m_borderColorSet)
+ m_borderColorSet = frameset->hasBorderColor();
}
+ if (!m_noresize)
+ m_noresize = frameset->noResize();
}
HTMLElement::attach(context);
@@ -214,17 +206,17 @@ Node::InsertionNotificationRequest HTMLFrameSetElement::insertedInto(ContainerNo
void HTMLFrameSetElement::willRecalcStyle(StyleRecalcChange)
{
if (needsStyleRecalc() && renderer()) {
- renderer()->setNeedsLayout();
+ renderer()->setNeedsLayoutAndFullPaintInvalidation();
clearNeedsStyleRecalc();
}
}
-DOMWindow* HTMLFrameSetElement::anonymousNamedGetter(const AtomicString& name)
+LocalDOMWindow* HTMLFrameSetElement::anonymousNamedGetter(const AtomicString& name)
{
- Node* frameNode = children()->namedItem(name);
- if (!frameNode || !frameNode->hasTagName(HTMLNames::frameTag))
+ Element* frameElement = children()->namedItem(name);
+ if (!isHTMLFrameElement(frameElement))
return 0;
- Document* document = toHTMLFrameElement(frameNode)->contentDocument();
+ Document* document = toHTMLFrameElement(frameElement)->contentDocument();
if (!document || !document->frame())
return 0;
return document->domWindow();
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h
index 3138495cd2b..36ce2073a65 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.h
@@ -24,6 +24,7 @@
#ifndef HTMLFrameSetElement_h
#define HTMLFrameSetElement_h
+#include "core/dom/Document.h"
#include "core/html/HTMLDimension.h"
#include "core/html/HTMLElement.h"
@@ -31,7 +32,7 @@ namespace WebCore {
class HTMLFrameSetElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLFrameSetElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLFrameSetElement);
bool hasFrameBorder() const { return m_frameborder; }
bool noResize() const { return m_noresize; }
@@ -45,17 +46,15 @@ public:
const Vector<HTMLDimension>& rowLengths() const { return m_rowLengths; }
const Vector<HTMLDimension>& colLengths() const { return m_colLengths; }
- DOMWindow* anonymousNamedGetter(const AtomicString&);
+ LocalDOMWindow* anonymousNamedGetter(const AtomicString&);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(blur);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(error);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(focus);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(load);
+ DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(resize);
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(scroll);
-
-#if ENABLE(ORIENTATION_EVENTS)
DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(orientationchange);
-#endif
private:
explicit HTMLFrameSetElement(Document&);
@@ -65,10 +64,10 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
@@ -86,8 +85,6 @@ private:
bool m_noresize;
};
-DEFINE_NODE_TYPE_CASTS(HTMLFrameSetElement, hasTagName(HTMLNames::framesetTag));
-
} // namespace WebCore
#endif // HTMLFrameSetElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl
index 38a5f21424b..e7c6a243cf8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLFrameSetElement.idl
@@ -18,18 +18,21 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLFrameSetElement : HTMLElement {
- [ImplementedAs=anonymousNamedGetter, OverrideBuiltins, NotEnumerable] getter Window (DOMString name);
+[
+ OverrideBuiltins,
+] interface HTMLFrameSetElement : HTMLElement {
+ [NotEnumerable] getter Window (DOMString name);
[Reflect] attribute DOMString cols;
[Reflect] attribute DOMString rows;
- [Conditional=ORIENTATION_EVENTS] attribute EventHandler onorientationchange;
+ [RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange;
// Overrides of GlobalEventHandler attributes
attribute EventHandler onblur;
attribute EventHandler onerror;
attribute EventHandler onfocus;
attribute EventHandler onload;
+ attribute EventHandler onresize;
attribute EventHandler onscroll;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
index 7a6edf88eb5..9df1cad4af9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
@@ -23,9 +23,9 @@
#include "config.h"
#include "core/html/HTMLHRElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
@@ -33,16 +33,13 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLHRElement::HTMLHRElement(Document& document)
+inline HTMLHRElement::HTMLHRElement(Document& document)
: HTMLElement(hrTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLHRElement> HTMLHRElement::create(Document& document)
-{
- return adoptRef(new HTMLHRElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLHRElement)
bool HTMLHRElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -76,11 +73,13 @@ void HTMLHRElement::collectStyleForPresentationAttribute(const QualifiedName& na
addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
} else if (name == noshadeAttr) {
- addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, CSSValueSolid);
+ if (!hasAttribute(colorAttr)) {
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, CSSValueSolid);
- RefPtr<CSSPrimitiveValue> darkGrayValue = cssValuePool().createColorValue(Color::darkGray);
- style->setProperty(CSSPropertyBorderColor, darkGrayValue);
- style->setProperty(CSSPropertyBackgroundColor, darkGrayValue);
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> darkGrayValue = cssValuePool().createColorValue(Color::darkGray);
+ style->setProperty(CSSPropertyBorderColor, darkGrayValue);
+ style->setProperty(CSSPropertyBackgroundColor, darkGrayValue);
+ }
} else if (name == sizeAttr) {
StringImpl* si = value.impl();
int size = si->toInt();
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h
index ec5bcb01442..79b2fc410b7 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHRElement.h
@@ -29,9 +29,9 @@ namespace WebCore {
class HTMLHRElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLHRElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLHRElement);
- virtual bool canContainRangeEndPoint() const { return hasChildNodes(); }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return hasChildren(); }
private:
explicit HTMLHRElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp
index 8a25aa6a51d..494154590ac 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.cpp
@@ -24,21 +24,18 @@
#include "config.h"
#include "core/html/HTMLHeadElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLHeadElement::HTMLHeadElement(Document& document)
+inline HTMLHeadElement::HTMLHeadElement(Document& document)
: HTMLElement(headTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLHeadElement> HTMLHeadElement::create(Document& document)
-{
- return adoptRef(new HTMLHeadElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLHeadElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h
index 7abcac7df45..4a68f2e1e85 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.h
@@ -30,14 +30,12 @@ namespace WebCore {
class HTMLHeadElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLHeadElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLHeadElement);
private:
explicit HTMLHeadElement(Document&);
};
-DEFINE_NODE_TYPE_CASTS(HTMLHeadElement, hasTagName(HTMLNames::headTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl
index 738deb73d92..fb54cb5ab73 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadElement.idl
@@ -18,5 +18,5 @@
*/
interface HTMLHeadElement : HTMLElement {
- [Reflect, TreatNullAs=NullString, MeasureAs=HTMLHeadElementProfile] attribute DOMString profile;
+ [Reflect, TreatNullAs=NullString, DeprecateAs=HTMLHeadElementProfile] attribute DOMString profile;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp
index 7e9c986e4b7..fb0431cd999 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.cpp
@@ -31,9 +31,6 @@ inline HTMLHeadingElement::HTMLHeadingElement(const QualifiedName& tagName, Docu
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLHeadingElement> HTMLHeadingElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLHeadingElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLHeadingElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h
index e99bac5867b..fb0a4d52761 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHeadingElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLHeadingElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLHeadingElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLHeadingElement);
private:
HTMLHeadingElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp
index e4a56c917c4..991176eee99 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.cpp
@@ -24,28 +24,25 @@
#include "config.h"
#include "core/html/HTMLHtmlElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentParser.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/frame/Frame.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLHtmlElement::HTMLHtmlElement(Document& document)
+inline HTMLHtmlElement::HTMLHtmlElement(Document& document)
: HTMLElement(htmlTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLHtmlElement> HTMLHtmlElement::create(Document& document)
-{
- return adoptRef(new HTMLHtmlElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLHtmlElement)
bool HTMLHtmlElement::isURLAttribute(const Attribute& attribute) const
{
@@ -65,7 +62,7 @@ void HTMLHtmlElement::insertedByParser()
if (!documentLoader)
return;
- const AtomicString& manifest = getAttribute(manifestAttr);
+ const AtomicString& manifest = fastGetAttribute(manifestAttr);
if (manifest.isEmpty())
documentLoader->applicationCacheHost()->selectCacheWithoutManifest();
else
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h
index 4976aac0c8c..77f43061f74 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.h
@@ -30,7 +30,7 @@ namespace WebCore {
class HTMLHtmlElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLHtmlElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLHtmlElement);
void insertedByParser();
@@ -40,18 +40,6 @@ private:
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
};
-inline bool isHTMLHtmlElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::htmlTag);
-}
-
-inline bool isHTMLHtmlElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::htmlTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLHtmlElement, hasTagName(HTMLNames::htmlTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl
index 3e329da57d1..3099de60b2d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLHtmlElement.idl
@@ -19,5 +19,4 @@
interface HTMLHtmlElement : HTMLElement {
[Reflect] attribute DOMString version;
- [Reflect, TreatNullAs=NullString, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds, MeasureAs=HTMLHtmlElementManifest] attribute DOMString manifest;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
index 016fba4ec0e..b447e52765a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/html/HTMLIFrameElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLDocument.h"
#include "core/rendering/RenderIFrame.h"
@@ -39,17 +39,13 @@ inline HTMLIFrameElement::HTMLIFrameElement(Document& document)
, m_didLoadNonEmptyDocument(false)
{
ScriptWrappable::init(this);
- setHasCustomStyleCallbacks();
}
-PassRefPtr<HTMLIFrameElement> HTMLIFrameElement::create(Document& document)
-{
- return adoptRef(new HTMLIFrameElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLIFrameElement)
bool HTMLIFrameElement::isPresentationAttribute(const QualifiedName& name) const
{
- if (name == widthAttr || name == heightAttr || name == alignAttr || name == frameborderAttr || name == seamlessAttr)
+ if (name == widthAttr || name == heightAttr || name == alignAttr || name == frameborderAttr)
return true;
return HTMLFrameElementBase::isPresentationAttribute(name);
}
@@ -63,7 +59,7 @@ void HTMLIFrameElement::collectStyleForPresentationAttribute(const QualifiedName
else if (name == alignAttr)
applyAlignmentAttributeToStyle(value, style);
else if (name == frameborderAttr) {
- // Frame border doesn't really match the HTML4 spec definition for iframes. It simply adds
+ // LocalFrame border doesn't really match the HTML4 spec definition for iframes. It simply adds
// a presentational hint that the border should be off if set to zero.
if (!value.toInt()) {
// Add a rule that nulls out our border width.
@@ -87,12 +83,9 @@ void HTMLIFrameElement::parseAttribute(const QualifiedName& name, const AtomicSt
setSandboxFlags(value.isNull() ? SandboxNone : parseSandboxPolicy(value, invalidTokens));
if (!invalidTokens.isNull())
document().addConsoleMessage(OtherMessageSource, ErrorMessageLevel, "Error while parsing the 'sandbox' attribute: " + invalidTokens);
- } else if (name == seamlessAttr) {
- // If we're adding or removing the seamless attribute, we need to force the content document to recalculate its StyleResolver.
- if (contentDocument())
- contentDocument()->styleResolverChanged(RecalcStyleDeferred);
- } else
+ } else {
HTMLFrameElementBase::parseAttribute(name, value);
+ }
}
bool HTMLIFrameElement::rendererIsNeeded(const RenderStyle& style)
@@ -120,20 +113,6 @@ void HTMLIFrameElement::removedFrom(ContainerNode* insertionPoint)
toHTMLDocument(document()).removeExtraNamedItem(m_name);
}
-bool HTMLIFrameElement::shouldDisplaySeamlessly() const
-{
- return contentDocument() && contentDocument()->shouldDisplaySeamlesslyWithParent();
-}
-
-void HTMLIFrameElement::didRecalcStyle(StyleRecalcChange styleChange)
-{
- if (!shouldDisplaySeamlessly())
- return;
- Document* childDocument = contentDocument();
- if (shouldRecalcStyle(styleChange, childDocument))
- contentDocument()->recalcStyle(styleChange);
-}
-
bool HTMLIFrameElement::isInteractiveContent() const
{
return true;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h
index eab2678af2c..9017d774a22 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.h
@@ -30,9 +30,7 @@ namespace WebCore {
class HTMLIFrameElement FINAL : public HTMLFrameElementBase {
public:
- static PassRefPtr<HTMLIFrameElement> create(Document&);
-
- bool shouldDisplaySeamlessly() const;
+ DECLARE_NODE_FACTORY(HTMLIFrameElement);
private:
explicit HTMLIFrameElement(Document&);
@@ -44,10 +42,8 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
-
- virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual bool loadedNonEmptyDocument() const OVERRIDE { return m_didLoadNonEmptyDocument; }
virtual void didLoadNonEmptyDocument() OVERRIDE { m_didLoadNonEmptyDocument = true; }
@@ -57,8 +53,6 @@ private:
bool m_didLoadNonEmptyDocument;
};
-DEFINE_NODE_TYPE_CASTS(HTMLIFrameElement, hasTagName(HTMLNames::iframeTag));
-
} // namespace WebCore
#endif // HTMLIFrameElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
index d8a8a8eb700..90c3a7a77f9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLIFrameElement.idl
@@ -27,9 +27,8 @@ interface HTMLIFrameElement : HTMLElement {
[Reflect, TreatNullAs=NullString] attribute DOMString marginWidth;
[Reflect] attribute DOMString name;
[Reflect, TreatNullAs=NullString] attribute DOMString sandbox;
- [Reflect, RuntimeEnabled=SeamlessIFrames] attribute boolean seamless;
[Reflect] attribute DOMString scrolling;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly, LogPreviousValue] attribute DOMString src;
[Reflect] attribute DOMString srcdoc;
[Reflect] attribute DOMString width;
@@ -39,5 +38,7 @@ interface HTMLIFrameElement : HTMLElement {
// Extensions
readonly attribute Window contentWindow;
- [CheckSecurity=Node, RaisesException] SVGDocument getSVGDocument();
+ [CheckSecurity=Node, RaisesException] Document getSVGDocument();
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
index d7d8c971b57..cd7063cdcf0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.cpp
@@ -23,60 +23,84 @@
#include "config.h"
#include "core/html/HTMLImageElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
+#include "core/MediaTypeNames.h"
+#include "core/css/MediaQueryMatcher.h"
+#include "core/css/MediaValuesCached.h"
+#include "core/css/parser/SizesAttributeParser.h"
#include "core/dom/Attribute.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
#include "core/html/HTMLAnchorElement.h"
+#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLFormElement.h"
+#include "core/html/HTMLSourceElement.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLSrcsetParser.h"
#include "core/rendering/RenderImage.h"
-
-using namespace std;
+#include "platform/MIMETypeRegistry.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form)
+HTMLImageElement::HTMLImageElement(Document& document, HTMLFormElement* form, bool createdByParser)
: HTMLElement(imgTag, document)
- , m_imageLoader(this)
- , m_form(form)
+ , m_imageLoader(HTMLImageLoader::create(this))
, m_compositeOperator(CompositeSourceOver)
, m_imageDevicePixelRatio(1.0f)
+ , m_formWasSetByParser(false)
+ , m_elementCreatedByParser(createdByParser)
{
ScriptWrappable::init(this);
- if (form)
- form->registerImgElement(this);
+ if (form && form->inDocument()) {
+#if ENABLE(OILPAN)
+ m_form = form;
+#else
+ m_form = form->createWeakPtr();
+#endif
+ m_formWasSetByParser = true;
+ m_form->associate(*this);
+ m_form->didAssociateByParser();
+ }
}
-PassRefPtr<HTMLImageElement> HTMLImageElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& document)
{
- return adoptRef(new HTMLImageElement(document));
+ return adoptRefWillBeNoop(new HTMLImageElement(document));
}
-PassRefPtr<HTMLImageElement> HTMLImageElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
{
- return adoptRef(new HTMLImageElement(document, form));
+ return adoptRefWillBeNoop(new HTMLImageElement(document, form, createdByParser));
}
HTMLImageElement::~HTMLImageElement()
{
+#if !ENABLE(OILPAN)
if (m_form)
- m_form->removeImgElement(this);
+ m_form->disassociate(*this);
+#endif
+}
+
+void HTMLImageElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_imageLoader);
+ visitor->trace(m_form);
+ HTMLElement::trace(visitor);
}
-PassRefPtr<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document& document, int width, int height)
+PassRefPtrWillBeRawPtr<HTMLImageElement> HTMLImageElement::createForJSConstructor(Document& document, int width, int height)
{
- RefPtr<HTMLImageElement> image = adoptRef(new HTMLImageElement(document));
+ RefPtrWillBeRawPtr<HTMLImageElement> image = adoptRefWillBeNoop(new HTMLImageElement(document));
if (width)
image->setWidth(width);
if (height)
image->setHeight(height);
+ image->m_elementCreatedByParser = false;
return image.release();
}
@@ -116,7 +140,49 @@ const AtomicString HTMLImageElement::imageSourceURL() const
HTMLFormElement* HTMLImageElement::formOwner() const
{
- return findFormAncestor();
+ return m_form.get();
+}
+
+void HTMLImageElement::formRemovedFromTree(const Node& formRoot)
+{
+ ASSERT(m_form);
+ if (highestAncestorOrSelf() != formRoot)
+ resetFormOwner();
+}
+
+void HTMLImageElement::resetFormOwner()
+{
+ m_formWasSetByParser = false;
+ HTMLFormElement* nearestForm = findFormAncestor();
+ if (m_form) {
+ if (nearestForm == m_form.get())
+ return;
+ m_form->disassociate(*this);
+ }
+ if (nearestForm) {
+#if ENABLE(OILPAN)
+ m_form = nearestForm;
+#else
+ m_form = nearestForm->createWeakPtr();
+#endif
+ m_form->associate(*this);
+ } else {
+#if ENABLE(OILPAN)
+ m_form = nullptr;
+#else
+ m_form = WeakPtr<HTMLFormElement>();
+#endif
+ }
+}
+
+void HTMLImageElement::setBestFitURLAndDPRFromImageCandidate(const ImageCandidate& candidate)
+{
+ m_bestFitImageURL = candidate.url();
+ float candidateDensity = candidate.density();
+ if (candidateDensity >= 0)
+ m_imageDevicePixelRatio = 1.0 / candidateDensity;
+ if (renderer() && renderer()->isImage())
+ toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRatio);
}
void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -124,29 +190,18 @@ void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr
if (name == altAttr) {
if (renderer() && renderer()->isImage())
toRenderImage(renderer())->updateAltText();
- } else if (name == srcAttr || name == srcsetAttr) {
- if (RuntimeEnabledFeatures::srcsetEnabled()) {
- ImageCandidate candidate = bestFitSourceForImageAttributes(document().devicePixelRatio(), fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr));
- m_bestFitImageURL = candidate.toString();
- float candidateScaleFactor = candidate.scaleFactor();
- if (candidateScaleFactor > 0)
- m_imageDevicePixelRatio = 1 / candidateScaleFactor;
- if (renderer() && renderer()->isImage())
- toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRatio);
- }
- m_imageLoader.updateFromElementIgnoringPreviousError();
- }
- else if (name == usemapAttr)
+ } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr) {
+ selectSourceURL(UpdateIgnorePreviousError);
+ } else if (name == usemapAttr) {
setIsLink(!value.isNull());
- else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
- else if (name == compositeAttr) {
+ } else if (name == compositeAttr) {
// FIXME: images don't support blend modes in their compositing attribute.
blink::WebBlendMode blendOp = blink::WebBlendModeNormal;
if (!parseCompositeAndBlendOperator(value, m_compositeOperator, blendOp))
m_compositeOperator = CompositeSourceOver;
- } else
+ } else {
HTMLElement::parseAttribute(name, value);
+ }
}
const AtomicString& HTMLImageElement::altText() const
@@ -154,10 +209,54 @@ const AtomicString& HTMLImageElement::altText() const
// lets figure out the alt text.. magic stuff
// http://www.w3.org/TR/1998/REC-html40-19980424/appendix/notes.html#altgen
// also heavily discussed by Hixie on bugzilla
- if (!getAttribute(altAttr).isNull())
- return getAttribute(altAttr);
+ const AtomicString& alt = fastGetAttribute(altAttr);
+ if (!alt.isNull())
+ return alt;
// fall back to title attribute
- return getAttribute(titleAttr);
+ return fastGetAttribute(titleAttr);
+}
+
+static bool supportedImageType(const String& type)
+{
+ return MIMETypeRegistry::isSupportedImageResourceMIMEType(type);
+}
+
+// http://picture.responsiveimages.org/#update-source-set
+ImageCandidate HTMLImageElement::findBestFitImageFromPictureParent()
+{
+ ASSERT(isMainThread());
+ Node* parent = parentNode();
+ if (!parent || !isHTMLPictureElement(*parent))
+ return ImageCandidate();
+ for (Node* child = parent->firstChild(); child; child = child->nextSibling()) {
+ if (child == this)
+ return ImageCandidate();
+
+ if (!isHTMLSourceElement(*child))
+ continue;
+
+ HTMLSourceElement* source = toHTMLSourceElement(child);
+ String srcset = source->fastGetAttribute(srcsetAttr);
+ if (srcset.isEmpty())
+ continue;
+ String type = source->fastGetAttribute(typeAttr);
+ if (!type.isEmpty() && !supportedImageType(type))
+ continue;
+
+ String media = source->fastGetAttribute(mediaAttr);
+ if (!media.isEmpty()) {
+ RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media);
+ if (!document().mediaQueryMatcher().evaluate(mediaQueries.get()))
+ continue;
+ }
+
+ unsigned effectiveSize = SizesAttributeParser::findEffectiveSize(source->fastGetAttribute(sizesAttr), MediaValuesCached::create(document()));
+ ImageCandidate candidate = bestFitSourceForSrcsetAttribute(document().devicePixelRatio(), effectiveSize, source->fastGetAttribute(srcsetAttr));
+ if (candidate.isEmpty())
+ continue;
+ return candidate;
+ }
+ return ImageCandidate();
}
RenderObject* HTMLImageElement::createRenderer(RenderStyle* style)
@@ -183,7 +282,7 @@ void HTMLImageElement::attach(const AttachContext& context)
{
HTMLElement::attach(context);
- if (renderer() && renderer()->isImage() && !m_imageLoader.hasPendingBeforeLoadEvent()) {
+ if (renderer() && renderer()->isImage()) {
RenderImage* renderImage = toRenderImage(renderer());
RenderImageResource* renderImageResource = renderImage->imageResource();
if (renderImageResource->hasImage())
@@ -191,41 +290,40 @@ void HTMLImageElement::attach(const AttachContext& context)
// If we have no image at all because we have no src attribute, set
// image height and width for the alt text instead.
- if (!m_imageLoader.image() && !renderImageResource->cachedImage())
+ if (!imageLoader().image() && !renderImageResource->cachedImage())
renderImage->setImageSizeForAltText();
else
- renderImageResource->setImageResource(m_imageLoader.image());
+ renderImageResource->setImageResource(imageLoader().image());
}
}
Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode* insertionPoint)
{
- // m_form can be non-null if it was set in constructor.
- if (m_form && insertionPoint->highestAncestor() != m_form->highestAncestor()) {
- m_form->removeImgElement(this);
- m_form = 0;
- }
+ if (!m_formWasSetByParser || insertionPoint->highestAncestorOrSelf() != m_form->highestAncestorOrSelf())
+ resetFormOwner();
- if (!m_form) {
- m_form = findFormAncestor();
- if (m_form)
- m_form->registerImgElement(this);
+ bool imageWasModified = false;
+ if (RuntimeEnabledFeatures::pictureEnabled()) {
+ ImageCandidate candidate = findBestFitImageFromPictureParent();
+ if (!candidate.isEmpty()) {
+ setBestFitURLAndDPRFromImageCandidate(candidate);
+ imageWasModified = true;
+ }
}
// If we have been inserted from a renderer-less document,
// our loader may have not fetched the image, so do it now.
- if (insertionPoint->inDocument() && !m_imageLoader.image())
- m_imageLoader.updateFromElement();
+ if ((insertionPoint->inDocument() && !imageLoader().image()) || imageWasModified)
+ imageLoader().updateFromElement(m_elementCreatedByParser ? ImageLoader::ForceLoadImmediately : ImageLoader::LoadNormally);
return HTMLElement::insertedInto(insertionPoint);
}
void HTMLImageElement::removedFrom(ContainerNode* insertionPoint)
{
- if (m_form)
- m_form->removeImgElement(this);
- m_form = 0;
+ if (!m_form || m_form->highestAncestorOrSelf() != highestAncestorOrSelf())
+ resetFormOwner();
HTMLElement::removedFrom(insertionPoint);
}
@@ -239,8 +337,8 @@ int HTMLImageElement::width(bool ignorePendingStylesheets)
return width;
// if the image is available, use its width
- if (m_imageLoader.image())
- return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).width();
+ if (imageLoader().image())
+ return imageLoader().image()->imageSizeForRenderer(renderer(), 1.0f).width();
}
if (ignorePendingStylesheets)
@@ -262,8 +360,8 @@ int HTMLImageElement::height(bool ignorePendingStylesheets)
return height;
// if the image is available, use its height
- if (m_imageLoader.image())
- return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).height();
+ if (imageLoader().image())
+ return imageLoader().image()->imageSizeForRenderer(renderer(), 1.0f).height();
}
if (ignorePendingStylesheets)
@@ -277,18 +375,30 @@ int HTMLImageElement::height(bool ignorePendingStylesheets)
int HTMLImageElement::naturalWidth() const
{
- if (!m_imageLoader.image())
+ if (!imageLoader().image())
return 0;
- return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).width();
+ return imageLoader().image()->imageSizeForRenderer(renderer(), 1.0f).width();
}
int HTMLImageElement::naturalHeight() const
{
- if (!m_imageLoader.image())
+ if (!imageLoader().image())
return 0;
- return m_imageLoader.image()->imageSizeForRenderer(renderer(), 1.0f).height();
+ return imageLoader().image()->imageSizeForRenderer(renderer(), 1.0f).height();
+}
+
+const String& HTMLImageElement::currentSrc() const
+{
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/edits.html#dom-img-currentsrc
+ // The currentSrc IDL attribute must return the img element's current request's current URL.
+ // Initially, the pending request turns into current request when it is either available or broken.
+ // We use the image's dimensions as a proxy to it being in any of these states.
+ if (!imageLoader().image() || !imageLoader().image()->image() || !imageLoader().image()->image()->width())
+ return emptyAtom;
+
+ return imageLoader().image()->url().string();
}
bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const
@@ -300,9 +410,19 @@ bool HTMLImageElement::isURLAttribute(const Attribute& attribute) const
|| HTMLElement::isURLAttribute(attribute);
}
+bool HTMLImageElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == srcAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLImageElement::subResourceAttributeName() const
+{
+ return srcAttr;
+}
+
const AtomicString& HTMLImageElement::alt() const
{
- return getAttribute(altAttr);
+ return fastGetAttribute(altAttr);
}
bool HTMLImageElement::draggable() const
@@ -355,21 +475,12 @@ int HTMLImageElement::y() const
bool HTMLImageElement::complete() const
{
- return m_imageLoader.imageComplete();
-}
-
-void HTMLImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, src());
- // FIXME: What about when the usemap attribute begins with "#"?
- addSubresourceURL(urls, document().completeURL(getAttribute(usemapAttr)));
+ return imageLoader().imageComplete();
}
void HTMLImageElement::didMoveToNewDocument(Document& oldDocument)
{
- m_imageLoader.elementDidMoveToNewDocument();
+ imageLoader().elementDidMoveToNewDocument();
HTMLElement::didMoveToNewDocument(oldDocument);
}
@@ -389,10 +500,10 @@ bool HTMLImageElement::isServerMap() const
Image* HTMLImageElement::imageContents()
{
- if (!m_imageLoader.imageComplete())
+ if (!imageLoader().imageComplete())
return 0;
- return m_imageLoader.image()->image();
+ return imageLoader().image()->image();
}
bool HTMLImageElement::isInteractiveContent() const
@@ -400,4 +511,86 @@ bool HTMLImageElement::isInteractiveContent() const
return fastHasAttribute(usemapAttr);
}
+PassRefPtr<Image> HTMLImageElement::getSourceImageForCanvas(SourceImageMode, SourceImageStatus* status) const
+{
+ if (!complete() || !cachedImage()) {
+ *status = IncompleteSourceImageStatus;
+ return nullptr;
+ }
+
+ if (cachedImage()->errorOccurred()) {
+ *status = UndecodableSourceImageStatus;
+ return nullptr;
+ }
+
+ RefPtr<Image> sourceImage = cachedImage()->imageForRenderer(renderer());
+
+ // We need to synthesize a container size if a renderer is not available to provide one.
+ if (!renderer() && sourceImage->usesContainerSize())
+ sourceImage->setContainerSize(sourceImage->size());
+
+ *status = NormalSourceImageStatus;
+ return sourceImage.release();
+}
+
+bool HTMLImageElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
+{
+ ImageResource* image = cachedImage();
+ if (!image)
+ return false;
+ return !image->isAccessAllowed(destinationSecurityOrigin);
+}
+
+FloatSize HTMLImageElement::sourceSize() const
+{
+ ImageResource* image = cachedImage();
+ if (!image)
+ return FloatSize();
+ LayoutSize size;
+ size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure about this.
+
+ return size;
+}
+
+FloatSize HTMLImageElement::defaultDestinationSize() const
+{
+ ImageResource* image = cachedImage();
+ if (!image)
+ return FloatSize();
+ LayoutSize size;
+ size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure about this.
+ if (renderer() && renderer()->isRenderImage() && image->image() && !image->image()->hasRelativeWidth())
+ size.scale(toRenderImage(renderer())->imageDevicePixelRatio());
+ return size;
+}
+
+void HTMLImageElement::selectSourceURL(UpdateFromElementBehavior behavior)
+{
+ bool foundURL = false;
+ if (RuntimeEnabledFeatures::pictureEnabled()) {
+ ImageCandidate candidate = findBestFitImageFromPictureParent();
+ if (!candidate.isEmpty()) {
+ setBestFitURLAndDPRFromImageCandidate(candidate);
+ foundURL = true;
+ }
+ }
+
+ if (!foundURL) {
+ unsigned effectiveSize = 0;
+ if (RuntimeEnabledFeatures::pictureSizesEnabled())
+ effectiveSize = SizesAttributeParser::findEffectiveSize(fastGetAttribute(sizesAttr), MediaValuesCached::create(document()));
+ ImageCandidate candidate = bestFitSourceForImageAttributes(document().devicePixelRatio(), effectiveSize, fastGetAttribute(srcAttr), fastGetAttribute(srcsetAttr));
+ setBestFitURLAndDPRFromImageCandidate(candidate);
+ }
+ if (behavior == UpdateIgnorePreviousError)
+ imageLoader().updateFromElementIgnoringPreviousError();
+ else
+ imageLoader().updateFromElement();
+}
+
+const KURL& HTMLImageElement::sourceURL() const
+{
+ return cachedImage()->response().url();
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h
index 05c5d81db3f..4328dceceba 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.h
@@ -26,26 +26,30 @@
#include "core/html/HTMLElement.h"
#include "core/html/HTMLImageLoader.h"
+#include "core/html/canvas/CanvasImageSource.h"
#include "platform/graphics/GraphicsTypes.h"
+#include "wtf/WeakPtr.h"
namespace WebCore {
class HTMLFormElement;
+class ImageCandidate;
-class HTMLImageElement FINAL : public HTMLElement {
- friend class HTMLFormElement;
+class HTMLImageElement FINAL : public HTMLElement, public CanvasImageSource {
public:
- static PassRefPtr<HTMLImageElement> create(Document&);
- static PassRefPtr<HTMLImageElement> create(Document&, HTMLFormElement*);
- static PassRefPtr<HTMLImageElement> createForJSConstructor(Document&, int width, int height);
+ static PassRefPtrWillBeRawPtr<HTMLImageElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLImageElement> create(Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLImageElement> createForJSConstructor(Document&, int width, int height);
virtual ~HTMLImageElement();
+ virtual void trace(Visitor*) OVERRIDE;
int width(bool ignorePendingStylesheets = false);
int height(bool ignorePendingStylesheets = false);
int naturalWidth() const;
int naturalHeight() const;
+ const String& currentSrc() const;
bool isServerMap() const;
@@ -53,10 +57,10 @@ public:
CompositeOperator compositeOperator() const { return m_compositeOperator; }
- ImageResource* cachedImage() const { return m_imageLoader.image(); }
- void setImageResource(ImageResource* i) { m_imageLoader.setImage(i); };
+ ImageResource* cachedImage() const { return imageLoader().image(); }
+ void setImageResource(ImageResource* i) { imageLoader().setImage(i); };
- void setLoadManually(bool loadManually) { m_imageLoader.setLoadManually(loadManually); }
+ void setLoadManually(bool loadManually) { imageLoader().setLoadManually(loadManually); }
const AtomicString& alt() const;
@@ -72,19 +76,33 @@ public:
bool complete() const;
- bool hasPendingActivity() const { return m_imageLoader.hasPendingActivity(); }
+ bool hasPendingActivity() const { return imageLoader().hasPendingActivity(); }
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
- void addClient(ImageLoaderClient* client) { m_imageLoader.addClient(client); }
- void removeClient(ImageLoaderClient* client) { m_imageLoader.removeClient(client); }
+ void addClient(ImageLoaderClient* client) { imageLoader().addClient(client); }
+ void removeClient(ImageLoaderClient* client) { imageLoader().removeClient(client); }
virtual const AtomicString imageSourceURL() const OVERRIDE;
virtual HTMLFormElement* formOwner() const OVERRIDE;
-
+ void formRemovedFromTree(const Node& formRoot);
+
+ // CanvasImageSourceImplementations
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const;
+ virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+ virtual FloatSize sourceSize() const OVERRIDE;
+ virtual FloatSize defaultDestinationSize() const OVERRIDE;
+ virtual const KURL& sourceURL() const OVERRIDE;
+
+ enum UpdateFromElementBehavior {
+ UpdateNormal,
+ UpdateIgnorePreviousError
+ };
+ // public so that HTMLPictureElement can call this as well.
+ void selectSourceURL(UpdateFromElementBehavior);
protected:
- explicit HTMLImageElement(Document&, HTMLFormElement* = 0);
+ explicit HTMLImageElement(Document&, HTMLFormElement* = 0, bool createdByParser = false);
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
@@ -96,15 +114,15 @@ private:
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool canStartSelection() const;
+ virtual bool canStartSelection() const OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
- virtual bool draggable() const;
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool draggable() const OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
@@ -113,15 +131,24 @@ private:
virtual bool isInteractiveContent() const OVERRIDE;
virtual Image* imageContents() OVERRIDE;
- HTMLImageLoader m_imageLoader;
- HTMLFormElement* m_form;
+ void resetFormOwner();
+ ImageCandidate findBestFitImageFromPictureParent();
+ void setBestFitURLAndDPRFromImageCandidate(const ImageCandidate&);
+ HTMLImageLoader& imageLoader() const { return *m_imageLoader; }
+
+ OwnPtrWillBeMember<HTMLImageLoader> m_imageLoader;
+#if ENABLE(OILPAN)
+ Member<HTMLFormElement> m_form;
+#else
+ WeakPtr<HTMLFormElement> m_form;
+#endif
CompositeOperator m_compositeOperator;
AtomicString m_bestFitImageURL;
float m_imageDevicePixelRatio;
+ bool m_formWasSetByParser;
+ bool m_elementCreatedByParser;
};
-DEFINE_NODE_TYPE_CASTS(HTMLImageElement, hasTagName(HTMLNames::imgTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl
index a5480236fd6..1914a5fad72 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageElement.idl
@@ -21,28 +21,33 @@
// FIXME: NamedConstructor does not support optional without Default. Fortunately using Undefined makes
// us use 0 which happens to be the default width and height anyway.
[
- NamedConstructor=Image([Default=Undefined] optional long width, [Default=Undefined] optional long height)
+ NamedConstructor=Image([Default=Undefined] optional long width, [Default=Undefined] optional long height),
+ ConstructorCallWith=Document
] interface HTMLImageElement : HTMLElement {
[Reflect] attribute DOMString align;
[Reflect] attribute DOMString alt;
[Reflect, TreatNullAs=NullString] attribute DOMString border;
readonly attribute boolean complete;
- [Reflect] attribute DOMString crossOrigin;
+ [Reflect, ReflectOnly="anonymous"|"use-credentials", ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString crossOrigin;
attribute long height;
[Reflect] attribute long hspace;
[Reflect] attribute boolean isMap;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString longDesc;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString lowsrc;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString longDesc;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString lowsrc;
[Reflect] attribute DOMString name;
readonly attribute long naturalHeight;
readonly attribute long naturalWidth;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
- [Reflect, RuntimeEnabled=Srcset] attribute DOMString srcset;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
+ [Reflect] attribute DOMString srcset;
+ [Reflect, RuntimeEnabled=PictureSizes] attribute DOMString sizes;
+ [RuntimeEnabled=PictureSizes] readonly attribute DOMString currentSrc;
[Reflect] attribute DOMString useMap;
[Reflect] attribute long vspace;
attribute long width;
// Extensions
- readonly attribute long x;
- readonly attribute long y;
+ [MeasureAs=HTMLImageElementX] readonly attribute long x;
+ [MeasureAs=HTMLImageElementY] readonly attribute long y;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
index 9a50c5f94db..1a909a71555 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
@@ -22,13 +22,12 @@
#include "config.h"
#include "core/html/HTMLImageLoader.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
+#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLObjectElement.h"
-#include "core/html/HTMLVideoElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
namespace WebCore {
@@ -45,12 +44,12 @@ HTMLImageLoader::~HTMLImageLoader()
void HTMLImageLoader::dispatchLoadEvent()
{
// HTMLVideoElement uses this class to load the poster image, but it should not fire events for loading or failure.
- if (isHTMLVideoElement(element()))
+ if (isHTMLVideoElement(*element()))
return;
bool errorOccurred = image()->errorOccurred();
- if (!errorOccurred && image()->response().httpStatusCode() >= 400)
- errorOccurred = element()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror.
+ if (isHTMLObjectElement(*element()) && !errorOccurred)
+ errorOccurred = (image()->response().httpStatusCode() >= 400); // An <object> considers a 404 to be an error and should fire onerror.
element()->dispatchEvent(Event::create(errorOccurred ? EventTypeNames::error : EventTypeNames::load));
}
@@ -63,12 +62,12 @@ void HTMLImageLoader::notifyFinished(Resource*)
{
ImageResource* cachedImage = image();
- RefPtr<Element> element = this->element();
+ RefPtrWillBeRawPtr<Element> element = this->element();
ImageLoader::notifyFinished(cachedImage);
bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400;
- if (loadError && element->hasTagName(HTMLNames::objectTag))
+ if (loadError && isHTMLObjectElement(*element))
toHTMLObjectElement(element)->renderFallbackContent();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h b/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h
index 4ee2d8e419e..b9b93b8f9bd 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLImageLoader.h
@@ -27,15 +27,21 @@
namespace WebCore {
-class HTMLImageLoader : public ImageLoader {
+class HTMLImageLoader FINAL : public ImageLoader {
public:
- HTMLImageLoader(Element*);
+ static PassOwnPtrWillBeRawPtr<HTMLImageLoader> create(Element* element)
+ {
+ return adoptPtrWillBeNoop(new HTMLImageLoader(element));
+ }
virtual ~HTMLImageLoader();
- virtual void dispatchLoadEvent();
- virtual String sourceURI(const AtomicString&) const;
+ virtual void dispatchLoadEvent() OVERRIDE;
+ virtual String sourceURI(const AtomicString&) const OVERRIDE;
- virtual void notifyFinished(Resource*);
+ virtual void notifyFinished(Resource*) OVERRIDE;
+
+private:
+ explicit HTMLImageLoader(Element*);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImport.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImport.cpp
deleted file mode 100644
index 8ac2d7d127c..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImport.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/HTMLImport.h"
-
-#include "core/dom/Document.h"
-
-namespace WebCore {
-
-Frame* HTMLImport::frame()
-{
- return master()->frame();
-}
-
-Document* HTMLImport::master()
-{
- return root()->document();
-}
-
-HTMLImportsController* HTMLImport::controller()
-{
- return root()->toController();
-}
-
-void HTMLImport::appendChild(HTMLImport* child)
-{
- if (isScriptBlocked())
- child->blockScript();
- if (lastChild() && !lastChild()->isDone())
- child->blockDocument();
- TreeNode<HTMLImport>::appendChild(child);
- blockAfter(child);
-}
-
-bool HTMLImport::areChilrenLoaded() const
-{
- for (HTMLImport* child = firstChild(); child; child = child->next()) {
- if (!child->isLoaded())
- return false;
- }
-
- return true;
-}
-
-bool HTMLImport::arePredecessorsLoaded() const
-{
- HTMLImport* parent = this->parent();
- if (!parent)
- return true;
-
- for (HTMLImport* sibling = parent->firstChild(); sibling; sibling = sibling->next()) {
- if (sibling == this)
- break;
- if (!sibling->isLoaded())
- return false;
- }
-
- return true;
-}
-
-void HTMLImport::blockScript()
-{
- m_scriptBlocked = true;
-}
-
-void HTMLImport::unblockScript()
-{
- bool wasBlocked = m_scriptBlocked;
- m_scriptBlocked = false;
- if (wasBlocked)
- didUnblockScript();
-}
-
-void HTMLImport::didUnblockScript()
-{
- ASSERT(!isDocumentBlocked());
- ASSERT(!isScriptBlocked());
-
- if (!isProcessing())
- return;
-
- if (Document* document = this->document())
- document->didLoadAllImports();
-}
-
-
-void HTMLImport::blockDocument()
-{
- m_documentBlocked = true;
-}
-
-void HTMLImport::unblockDocument()
-{
- bool wasBlocked = m_documentBlocked;
- m_documentBlocked = false;
- if (wasBlocked)
- didUnblockDocument();
-}
-
-void HTMLImport::didUnblockDocument()
-{
- ASSERT(!isDocumentBlocked());
- ASSERT(isScriptBlocked());
-}
-
-inline bool HTMLImport::needsBlockingDocument() const
-{
- ASSERT(isDocumentBlocked());
- HTMLImport* elder = previous();
- return (elder && !elder->isDone());
-}
-
-bool HTMLImport::unblock(HTMLImport* import)
-{
- ASSERT(import->arePredecessorsLoaded());
- ASSERT(import->isScriptBlocked() || import->areChilrenLoaded());
-
- if (import->isDocumentBlocked() && import->needsBlockingDocument())
- return false;
- import->unblockDocument();
-
- if (import->isScriptBlocked()) {
- for (HTMLImport* child = import->firstChild(); child; child = child->next()) {
- if (!unblock(child))
- return false;
- }
- }
-
- import->unblockScript();
- return import->isLoaded();
-}
-
-void HTMLImport::block(HTMLImport* import)
-{
- for (HTMLImport* child = import; child; child = traverseNext(child, import))
- child->blockScript();
-}
-
-void HTMLImport::blockAfter(HTMLImport* child)
-{
- ASSERT(child->parent() == this);
-
- for (HTMLImport* sibling = lastChild(); sibling; sibling = sibling->previous()) {
- if (sibling == child)
- break;
- HTMLImport::block(sibling);
- }
-
- this->blockScript();
-
- if (HTMLImport* parent = this->parent())
- parent->blockAfter(this);
-}
-
-bool HTMLImport::isMaster(Document* document)
-{
- if (!document->import())
- return true;
- return (document->import()->master() == document);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImport.h b/chromium/third_party/WebKit/Source/core/html/HTMLImport.h
deleted file mode 100644
index 2c80c9775e9..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImport.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLImport_h
-#define HTMLImport_h
-
-#include "wtf/TreeNode.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class Frame;
-class Document;
-class Frame;
-class HTMLImportChild;
-class HTMLImportRoot;
-class HTMLImportsController;
-class KURL;
-
-//
-// # Basic Data Structure and Algorithms of HTML Imports implemenation.
-//
-// ## The Import Tree
-//
-// HTML Imports form a tree:
-//
-// * The root of the tree is HTMLImportsController, which is owned by the master
-// document as a DocumentSupplement. HTMLImportsController has an abstract class called
-// HTMLImportRoot to deal with cycler dependency.
-//
-// * The non-root nodes are HTMLImportChild, which is owned by LinkStyle, that is owned by HTMLLinkElement.
-// LinkStyle is wired into HTMLImportChild by implementing HTMLImportChildClient interface
-//
-// * Both HTMLImportsController and HTMLImportChild are derived from HTMLImport superclass
-// that models the tree data structure using WTF::TreeNode and provides a set of
-// virtual functions.
-//
-// HTMLImportsController also owns all loaders in the tree and manages their lifetime through it.
-// One assumption is that the tree is append-only and nodes are never inserted in the middle of the tree nor removed.
-//
-//
-// HTMLImport <|- HTMLImportRoot <|- HTMLImportsController <- Document
-// *
-// |
-// <|- HTMLImportChild <- LinkStyle <- HTMLLinkElement
-//
-//
-// # Import Sharing and HTMLImportLoader
-//
-// The HTML Imports spec calls for de-dup mechanism to share already loaded imports.
-// To implement this, the actual loading machinery is split out from HTMLImportChild to
-// HTMLImportLoader, and each loader shares HTMLImportLoader with other loader if the URL is same.
-// Check around HTMLImportsController::findLink() for more detail.
-//
-// Note that HTMLImportLoader provides HTMLImportLoaderClient to hook it up.
-// As it can be shared, HTMLImportLoader supports multiple clients.
-//
-// HTMLImportChild (1)-->(*) HTMLImportLoader
-//
-//
-// # Script Blocking
-//
-// The HTML parser blocks on <script> when preceding <link>s aren't finish loading imports.
-// Each HTMLImport instance tracks such a blocking state, that is called "script-blocked"
-// or HTMLImport::isScriptBlocked().
-//
-// ## Blocking Imports
-//
-// Each imports can become being script-blocked when new imports are added to the import tree.
-// For example, the parser of a parent import is blocked when new child import is given.
-// See HTMLImport::appendChild() to see how it is handled. Note that this blocking-ness is
-// transitive. HTMLImport::blockAfter() flips the flags iteratively to fullfill this transitivity.
-//
-// ## Unblocking Imports
-//
-// The blocking state can change when one of the imports finish loading. The Document notices it through
-// HTMLImportRoot::blockerGone(). The blockerGone() triggers HTMLImport::unblockScript(), which traverses
-// whole import tree and find unblock-able imports and unblock them.
-// Unblocked imported documents are notified through Document::didLoadAllImports() so that
-// it can resume its parser.
-//
-// # Document Blocking
-//
-// There is another type of blocking state that is called
-// "document-blocked". If the import is document-blocked, it cannot
-// create its own document object because sharable imported document
-// can appear later. The spec defines the loading order of the
-// import: The earlier one in the import-tree order should win and
-// later ones should share earlier one.
-//
-// The "document-blocked" state keeps the tree node from loading its
-// import until all preceding imports are ready t respect the
-// order. Note that the node may fetch the bytes from the URL
-// speculatively, even though it doesn't process it.
-//
-// The node is "document-unblocked" when there are unfinished,
-// preceeding import loading. Unblocking attempt for
-// "document-blocked" happens at the same timing as unblocking
-// "script-blocked".
-//
-
-// The superclass of HTMLImportsController and HTMLImportChild
-// This represents the import tree data structure.
-class HTMLImport : public TreeNode<HTMLImport> {
-public:
- static bool unblock(HTMLImport*);
- static bool isMaster(Document*);
-
- virtual ~HTMLImport() { }
-
- Frame* frame();
- Document* master();
- HTMLImportsController* controller();
-
- bool isLoaded() const { return !isScriptBlocked() && !isProcessing(); }
- bool isScriptBlocked() const { return m_scriptBlocked; }
- bool isDocumentBlocked() const { return m_documentBlocked; }
- bool isBlocked() const { return m_scriptBlocked || m_documentBlocked; }
-
- void appendChild(HTMLImport*);
-
- virtual HTMLImportRoot* root() = 0;
- virtual Document* document() const = 0;
- virtual void wasDetachedFromDocument() = 0;
- virtual void didFinishParsing() = 0;
- virtual bool isProcessing() const = 0;
- virtual bool isDone() const = 0;
-
-protected:
- HTMLImport()
- : m_scriptBlocked(false)
- , m_documentBlocked(false)
- { }
-
- virtual void didUnblockDocument();
-
-private:
- static void block(HTMLImport*);
-
- void blockAfter(HTMLImport* child);
- void blockScript();
- void unblockScript();
- void didUnblockScript();
-
- void blockDocument();
- void unblockDocument();
-
- bool needsBlockingDocument() const;
- bool arePredecessorsLoaded() const;
- bool areChilrenLoaded() const;
-
- bool m_scriptBlocked; // If any of decendants or predecessors is in processing, the parser blocks on <script>.
- bool m_documentBlocked; // If its predecessor is not done yet, the document creation is blocked.
-};
-
-// An abstract class to decouple its sublcass HTMLImportsController.
-class HTMLImportRoot : public HTMLImport {
-public:
- virtual void blockerGone() = 0;
- virtual HTMLImportsController* toController() = 0;
- virtual HTMLImportChild* findLinkFor(const KURL&, HTMLImport* excluding = 0) const = 0;
-};
-
-} // namespace WebCore
-
-#endif // HTMLImport_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.cpp
deleted file mode 100644
index 52445f355ea..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/HTMLImportChild.h"
-
-#include "core/dom/Document.h"
-#include "core/html/HTMLImportChildClient.h"
-#include "core/html/HTMLImportLoader.h"
-
-namespace WebCore {
-
-HTMLImportChild::HTMLImportChild(const KURL& url, HTMLImportChildClient* client)
- : m_url(url)
- , m_client(client)
-{
-}
-
-HTMLImportChild::~HTMLImportChild()
-{
- // importDestroyed() should be called before the destruction.
- ASSERT(!m_loader);
-}
-
-void HTMLImportChild::wasAlreadyLoadedAs(HTMLImportChild* found)
-{
- ASSERT(!m_loader);
- ASSERT(m_client);
- shareLoader(found);
-}
-
-void HTMLImportChild::startLoading(const ResourcePtr<RawResource>& resource)
-{
- ASSERT(!hasResource());
- ASSERT(!m_loader);
-
- HTMLImportResourceOwner::setResource(resource);
-
- // If the node is "document blocked", it cannot create HTMLImportLoader
- // even if there is no sharable one found, as there is possibility that
- // preceding imports load the sharable imports.
- // In that case preceding one should win because it comes first in the tree order.
- // See also didUnblockDocument().
- if (isDocumentBlocked())
- return;
-
- createLoader();
-}
-
-void HTMLImportChild::didFinish()
-{
- if (m_client)
- m_client->didFinish();
- clearResource();
- root()->blockerGone();
-}
-
-Document* HTMLImportChild::importedDocument() const
-{
- if (!m_loader)
- return 0;
- return m_loader->importedDocument();
-}
-
-void HTMLImportChild::importDestroyed()
-{
- if (parent())
- parent()->removeChild(this);
- if (m_loader) {
- m_loader->removeClient(this);
- m_loader.clear();
- }
-}
-
-HTMLImportRoot* HTMLImportChild::root()
-{
- return parent() ? parent()->root() : 0;
-}
-
-Document* HTMLImportChild::document() const
-{
- return (m_loader && m_loader->isOwnedBy(this)) ? m_loader->document() : 0;
-}
-
-void HTMLImportChild::wasDetachedFromDocument()
-{
- // For imported documens this shouldn't be called because Document::m_import is
- // cleared before Document is destroyed by HTMLImportChild::importDestroyed().
- ASSERT_NOT_REACHED();
-}
-
-void HTMLImportChild::didFinishParsing()
-{
- ASSERT(m_loader->isOwnedBy(this));
- m_loader->didFinishParsing();
-}
-
-// Once all preceding imports are loaded and "document blocking" ends,
-// HTMLImportChild can decide whether it should load the import by itself
-// or it can share existing one.
-void HTMLImportChild::didUnblockDocument()
-{
- HTMLImport::didUnblockDocument();
- ASSERT(!isDocumentBlocked());
- ASSERT(!m_loader || !m_loader->isOwnedBy(this));
-
- if (m_loader)
- return;
- if (HTMLImportChild* found = root()->findLinkFor(m_url, this))
- shareLoader(found);
- else
- createLoader();
-}
-
-void HTMLImportChild::createLoader()
-{
- ASSERT(!isDocumentBlocked());
- ASSERT(!m_loader);
- m_loader = HTMLImportLoader::create(this, parent()->document()->fetcher());
- m_loader->addClient(this);
- m_loader->startLoading(resource());
-}
-
-void HTMLImportChild::shareLoader(HTMLImportChild* loader)
-{
- ASSERT(!m_loader);
- m_loader = loader->m_loader;
- m_loader->addClient(this);
- root()->blockerGone();
-}
-
-bool HTMLImportChild::isProcessing() const
-{
- return m_loader && m_loader->isOwnedBy(this) && m_loader->isProcessing();
-}
-
-bool HTMLImportChild::isDone() const
-{
- return m_loader && m_loader->isDone();
-}
-
-bool HTMLImportChild::isLoaded() const
-{
- return m_loader->isLoaded();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.h b/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.h
deleted file mode 100644
index 72f0329c2c5..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportChild.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLImportChild_h
-#define HTMLImportChild_h
-
-#include "core/html/HTMLImport.h"
-#include "core/html/HTMLImportLoaderClient.h"
-#include "core/html/HTMLImportResourceOwner.h"
-#include "platform/weborigin/KURL.h"
-
-namespace WebCore {
-
-class HTMLImportLoader;
-class HTMLImportChildClient;
-
-//
-// An import tree node subclas to encapsulate imported document
-// lifecycle. This class is owned by LinkStyle. The actual loading
-// is done by HTMLImportLoader, which can be shared among multiple
-// HTMLImportChild of same link URL.
-//
-// HTMLImportChild implements ResourceClient through HTMLImportResourceOwner
-// so that it can speculatively request linked resources while it is unblocked.
-//
-class HTMLImportChild : public HTMLImport, public HTMLImportLoaderClient, public HTMLImportResourceOwner {
-public:
- HTMLImportChild(const KURL&, HTMLImportChildClient*);
- virtual ~HTMLImportChild();
-
- Document* importedDocument() const;
- const KURL& url() const { return m_url; }
-
- void wasAlreadyLoadedAs(HTMLImportChild* found);
- void startLoading(const ResourcePtr<RawResource>&);
- void importDestroyed();
- bool isLoaded() const;
-
- // HTMLImport
- virtual HTMLImportRoot* root() OVERRIDE;
- virtual Document* document() const OVERRIDE;
- virtual void wasDetachedFromDocument() OVERRIDE;
- virtual void didFinishParsing() OVERRIDE;
- virtual bool isProcessing() const OVERRIDE;
- virtual bool isDone() const OVERRIDE;
- virtual void didUnblockDocument() OVERRIDE;
-
- void clearClient() { m_client = 0; }
-
-private:
- // RawResourceOwner doing nothing.
- // HTMLImportChild owns the resource so that the contents of prefetched Resource doesn't go away.
- virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE { }
- virtual void dataReceived(Resource*, const char*, int) OVERRIDE { }
- virtual void notifyFinished(Resource*) OVERRIDE { }
-
- // HTMLImportLoaderClient
- virtual void didFinish() OVERRIDE;
-
- void createLoader();
- void shareLoader(HTMLImportChild*);
-
- KURL m_url;
- HTMLImportChildClient* m_client;
- RefPtr<HTMLImportLoader> m_loader;
-};
-
-} // namespace WebCore
-
-#endif // HTMLImportChild_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportChildClient.h b/chromium/third_party/WebKit/Source/core/html/HTMLImportChildClient.h
deleted file mode 100644
index 62866e8c4f7..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportChildClient.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLImportChildClient_h
-#define HTMLImportChildClient_h
-
-namespace WebCore {
-
-class HTMLImportChildClient {
-public:
- virtual ~HTMLImportChildClient() { }
- virtual void didFinish() = 0;
- virtual void loaderWillBeDestroyed() = 0;
-};
-
-} // namespace WebCore
-
-#endif // HTMLImportChildClient_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.cpp
deleted file mode 100644
index 5781c79791e..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/HTMLImportLoader.h"
-
-#include "core/dom/Document.h"
-#include "core/dom/custom/CustomElementRegistrationContext.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
-#include "core/html/HTMLDocument.h"
-#include "core/html/HTMLImport.h"
-#include "core/html/HTMLImportLoaderClient.h"
-#include "core/loader/DocumentWriter.h"
-
-
-namespace WebCore {
-
-PassRefPtr<HTMLImportLoader> HTMLImportLoader::create(HTMLImport* import, ResourceFetcher* fetcher)
-{
- RefPtr<HTMLImportLoader> self = adoptRef(new HTMLImportLoader(import, fetcher));
- return self.release();
-}
-
-HTMLImportLoader::HTMLImportLoader(HTMLImport* import, ResourceFetcher* fetcher)
- : m_import(import)
- , m_fetcher(fetcher)
- , m_state(StateLoading)
-{
-}
-
-HTMLImportLoader::~HTMLImportLoader()
-{
- if (m_importedDocument)
- m_importedDocument->setImport(0);
-}
-
-void HTMLImportLoader::startLoading(const ResourcePtr<RawResource>& resource)
-{
- setResource(resource);
-}
-
-void HTMLImportLoader::responseReceived(Resource* resource, const ResourceResponse& response)
-{
- // Current canAccess() implementation isn't sufficient for catching cross-domain redirects: http://crbug.com/256976
- if (!m_fetcher->canAccess(resource, PotentiallyCORSEnabled)) {
- setState(StateError);
- return;
- }
-
- setState(startWritingAndParsing(response));
-}
-
-void HTMLImportLoader::dataReceived(Resource*, const char* data, int length)
-{
- RefPtr<DocumentWriter> protectingWriter(m_writer);
- m_writer->addData(data, length);
-}
-
-void HTMLImportLoader::notifyFinished(Resource* resource)
-{
- // The writer instance indicates that a part of the document can be already loaded.
- // We don't take such a case as an error because the partially-loaded document has been visible from script at this point.
- if (resource->loadFailedOrCanceled() && !m_writer) {
- setState(StateError);
- return;
- }
-
- setState(finishWriting());
-}
-
-HTMLImportLoader::State HTMLImportLoader::startWritingAndParsing(const ResourceResponse& response)
-{
- DocumentInit init = DocumentInit(response.url(), 0, m_import->master()->contextDocument(), m_import)
- .withRegistrationContext(m_import->master()->registrationContext());
- m_importedDocument = HTMLDocument::create(init);
- m_importedDocument->initContentSecurityPolicy(ContentSecurityPolicyResponseHeaders(response));
- m_writer = DocumentWriter::create(m_importedDocument.get(), response.mimeType(), response.textEncodingName());
-
- return StateLoading;
-}
-
-HTMLImportLoader::State HTMLImportLoader::finishWriting()
-{
- return StateWritten;
-}
-
-HTMLImportLoader::State HTMLImportLoader::finishParsing()
-{
- return StateReady;
-}
-
-void HTMLImportLoader::setState(State state)
-{
- if (m_state == state)
- return;
-
- m_state = state;
-
- if (m_state == StateReady || m_state == StateError || m_state == StateWritten) {
- if (RefPtr<DocumentWriter> writer = m_writer.release())
- writer->end();
- }
-
- // Since DocumentWriter::end() can let setState() reenter, we shouldn't refer to m_state here.
- if (state == StateReady || state == StateError)
- didFinish();
-}
-
-void HTMLImportLoader::didFinishParsing()
-{
- setState(finishParsing());
-}
-
-Document* HTMLImportLoader::importedDocument() const
-{
- if (m_state == StateError)
- return 0;
- return m_importedDocument.get();
-}
-
-bool HTMLImportLoader::isProcessing() const
-{
- if (!m_importedDocument)
- return !isDone();
- return m_importedDocument->parsing();
-}
-
-void HTMLImportLoader::didFinish()
-{
- for (size_t i = 0; i < m_clients.size(); ++i)
- m_clients[i]->didFinish();
-
- clearResource();
-
- ASSERT(!m_importedDocument || !m_importedDocument->parsing());
-}
-
-void HTMLImportLoader::addClient(HTMLImportLoaderClient* client)
-{
- ASSERT(kNotFound == m_clients.find(client));
- m_clients.append(client);
- if (isDone())
- client->didFinish();
-}
-
-void HTMLImportLoader::removeClient(HTMLImportLoaderClient* client)
-{
- ASSERT(kNotFound != m_clients.find(client));
- m_clients.remove(m_clients.find(client));
-}
-
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.h b/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.h
deleted file mode 100644
index 83ea998e310..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoader.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLImportLoader_h
-#define HTMLImportLoader_h
-
-#include "core/html/HTMLImportResourceOwner.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class Document;
-class DocumentWriter;
-class HTMLImport;
-class HTMLImportLoaderClient;
-
-//
-// Owning imported Document lifetime. It also implements ResourceClient through HTMLImportResourceOwner
-// to feed fetched bytes to the DocumentWriter of the imported document.
-// HTMLImportLoader is owned by and shared between HTMLImportChild.
-//
-//
-class HTMLImportLoader : public RefCounted<HTMLImportLoader>, public HTMLImportResourceOwner {
-public:
- enum State {
- StateLoading,
- StateWritten,
- StateError,
- StateReady
- };
-
- static PassRefPtr<HTMLImportLoader> create(HTMLImport*, ResourceFetcher*);
-
- virtual ~HTMLImportLoader();
-
- Document* document() const { return m_importedDocument.get(); }
- Document* importedDocument() const;
- void addClient(HTMLImportLoaderClient*);
- void removeClient(HTMLImportLoaderClient*);
-
- bool isDone() const { return m_state == StateReady || m_state == StateError; }
- bool isLoaded() const { return m_state == StateReady; }
- bool isProcessing() const;
-
- void startLoading(const ResourcePtr<RawResource>&);
- void didFinishParsing();
- bool isOwnedBy(const HTMLImport* import) const { return m_import == import; }
-
-private:
- HTMLImportLoader(HTMLImport*, ResourceFetcher*);
-
- // RawResourceClient
- virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE;
- virtual void dataReceived(Resource*, const char* data, int length) OVERRIDE;
- virtual void notifyFinished(Resource*) OVERRIDE;
-
- State startWritingAndParsing(const ResourceResponse&);
- State finishWriting();
- State finishParsing();
-
- void setState(State);
- void didFinish();
-
- HTMLImport* m_import;
- ResourceFetcher* m_fetcher;
- Vector<HTMLImportLoaderClient*> m_clients;
- State m_state;
- RefPtr<Document> m_importedDocument;
- RefPtr<DocumentWriter> m_writer;
-};
-
-} // namespace WebCore
-
-#endif // HTMLImportLoader_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoaderClient.h b/chromium/third_party/WebKit/Source/core/html/HTMLImportLoaderClient.h
deleted file mode 100644
index 5d510d1248b..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportLoaderClient.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLImportLoaderClient_h
-#define HTMLImportLoaderClient_h
-
-namespace WebCore {
-
-class HTMLImportLoaderClient {
-public:
- virtual ~HTMLImportLoaderClient() { }
- virtual void didFinish() = 0;
-};
-
-}
-
-#endif // HTMLImportLoaderClient_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.cpp
deleted file mode 100644
index 3a3109c477d..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/HTMLImportResourceOwner.h"
-
-namespace WebCore {
-
-HTMLImportResourceOwner::HTMLImportResourceOwner()
-{
-}
-
-HTMLImportResourceOwner::~HTMLImportResourceOwner()
-{
- clearResource();
-}
-
-void HTMLImportResourceOwner::setResource(const ResourcePtr<RawResource>& resource)
-{
- ASSERT(!hasResource());
- m_resource = resource;
- m_resource->addClient(this);
-}
-
-void HTMLImportResourceOwner::clearResource()
-{
- if (!hasResource())
- return;
- m_resource->removeClient(this);
- m_resource = 0;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.h b/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.h
deleted file mode 100644
index a8f5c52a193..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportResourceOwner.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLImportResourceOwner_h
-#define HTMLImportResourceOwner_h
-
-#include "core/fetch/RawResource.h"
-#include "core/fetch/ResourcePtr.h"
-
-namespace WebCore {
-
-// A RawResourceClient implenetation which is responsible for
-// owning RawResource object and adding/removing itself as a client
-// according to its lifetime.
-//
-// FIXME: This could be geneeric ResouceOwner<ResourceType> once it is
-// found that this class is broadly useful even outside HTMLImports module.
-//
-class HTMLImportResourceOwner : public RawResourceClient {
-public:
- HTMLImportResourceOwner();
- virtual ~HTMLImportResourceOwner();
-
-protected:
- const ResourcePtr<RawResource>& resource() const { return m_resource; }
-
- void setResource(const ResourcePtr<RawResource>&);
- void clearResource();
- bool hasResource() const { return m_resource.get(); }
-
-private:
- ResourcePtr<RawResource> m_resource;
-};
-
-} // namespace WebCore
-
-#endif // HTMLImportResourceOwner_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.cpp
deleted file mode 100644
index bc057d50390..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/HTMLImportsController.h"
-
-#include "core/dom/Document.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/html/HTMLImportChild.h"
-#include "core/html/HTMLImportChildClient.h"
-
-namespace WebCore {
-
-void HTMLImportsController::provideTo(Document* master)
-{
- DEFINE_STATIC_LOCAL(const char*, name, ("HTMLImportsController"));
- OwnPtr<HTMLImportsController> controller = adoptPtr(new HTMLImportsController(master));
- master->setImport(controller.get());
- DocumentSupplement::provideTo(master, name, controller.release());
-}
-
-HTMLImportsController::HTMLImportsController(Document* master)
- : m_master(master)
- , m_unblockTimer(this, &HTMLImportsController::unblockTimerFired)
-{
-}
-
-HTMLImportsController::~HTMLImportsController()
-{
- ASSERT(!m_master);
-}
-
-void HTMLImportsController::clear()
-{
- for (size_t i = 0; i < m_imports.size(); ++i)
- m_imports[i]->importDestroyed();
- if (m_master)
- m_master->setImport(0);
- m_master = 0;
-}
-
-HTMLImportChild* HTMLImportsController::createChild(const KURL& url, HTMLImport* parent, HTMLImportChildClient* client)
-{
- OwnPtr<HTMLImportChild> loader = adoptPtr(new HTMLImportChild(url, client));
- parent->appendChild(loader.get());
- m_imports.append(loader.release());
- return m_imports.last().get();
-}
-
-HTMLImportChild* HTMLImportsController::load(HTMLImport* parent, HTMLImportChildClient* client, FetchRequest request)
-{
- ASSERT(!request.url().isEmpty() && request.url().isValid());
-
- if (HTMLImportChild* found = findLinkFor(request.url())) {
- HTMLImportChild* child = createChild(request.url(), parent, client);
- child->wasAlreadyLoadedAs(found);
- return child;
- }
-
- request.setCrossOriginAccessControl(securityOrigin(), DoNotAllowStoredCredentials);
- ResourcePtr<RawResource> resource = parent->document()->fetcher()->fetchImport(request);
- if (!resource)
- return 0;
-
- HTMLImportChild* child = createChild(request.url(), parent, client);
- // We set resource after the import tree is built since
- // Resource::addClient() immediately calls back to feed the bytes when the resource is cached.
- child->startLoading(resource);
-
- return child;
-}
-
-void HTMLImportsController::showSecurityErrorMessage(const String& message)
-{
- m_master->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message);
-}
-
-HTMLImportChild* HTMLImportsController::findLinkFor(const KURL& url, HTMLImport* excluding) const
-{
- for (size_t i = 0; i < m_imports.size(); ++i) {
- HTMLImportChild* candidate = m_imports[i].get();
- if (candidate != excluding && equalIgnoringFragmentIdentifier(candidate->url(), url) && !candidate->isDocumentBlocked())
- return candidate;
- }
-
- return 0;
-}
-
-SecurityOrigin* HTMLImportsController::securityOrigin() const
-{
- return m_master->securityOrigin();
-}
-
-ResourceFetcher* HTMLImportsController::fetcher() const
-{
- return m_master->fetcher();
-}
-
-HTMLImportRoot* HTMLImportsController::root()
-{
- return this;
-}
-
-Document* HTMLImportsController::document() const
-{
- return m_master;
-}
-
-void HTMLImportsController::wasDetachedFromDocument()
-{
- clear();
-}
-
-void HTMLImportsController::didFinishParsing()
-{
-}
-
-bool HTMLImportsController::isProcessing() const
-{
- return m_master->parsing();
-}
-
-bool HTMLImportsController::isDone() const
-{
- return !m_master->parsing();
-}
-
-void HTMLImportsController::blockerGone()
-{
- scheduleUnblock();
-}
-
-void HTMLImportsController::scheduleUnblock()
-{
- if (m_unblockTimer.isActive())
- return;
- m_unblockTimer.startOneShot(0);
-}
-
-void HTMLImportsController::unblockTimerFired(Timer<HTMLImportsController>*)
-{
- do {
- m_unblockTimer.stop();
- HTMLImport::unblock(this);
- } while (m_unblockTimer.isActive());
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.h b/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.h
deleted file mode 100644
index 7cc1b92ea08..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/HTMLImportsController.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLImportsController_h
-#define HTMLImportsController_h
-
-#include "core/fetch/RawResource.h"
-#include "core/html/HTMLImport.h"
-#include "core/html/LinkResource.h"
-#include "platform/Supplementable.h"
-#include "platform/Timer.h"
-#include "wtf/FastAllocBase.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class FetchRequest;
-class ExecutionContext;
-class ResourceFetcher;
-class HTMLImportChild;
-class HTMLImportChildClient;
-
-class HTMLImportsController : public HTMLImportRoot, public DocumentSupplement {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static void provideTo(Document*);
-
- explicit HTMLImportsController(Document*);
- virtual ~HTMLImportsController();
-
- // HTMLImport
- virtual HTMLImportRoot* root() OVERRIDE;
- virtual Document* document() const OVERRIDE;
- virtual void wasDetachedFromDocument() OVERRIDE;
- virtual void didFinishParsing() OVERRIDE;
- virtual bool isProcessing() const OVERRIDE;
- virtual bool isDone() const OVERRIDE;
-
- // HTMLImportRoot
- virtual void blockerGone() OVERRIDE;
- virtual HTMLImportsController* toController() OVERRIDE { return this; }
- virtual HTMLImportChild* findLinkFor(const KURL&, HTMLImport* excluding = 0) const OVERRIDE;
-
- HTMLImportChild* load(HTMLImport* parent, HTMLImportChildClient*, FetchRequest);
- void showSecurityErrorMessage(const String&);
-
- SecurityOrigin* securityOrigin() const;
- ResourceFetcher* fetcher() const;
-
- void scheduleUnblock();
- void unblockTimerFired(Timer<HTMLImportsController>*);
-
-private:
- HTMLImportChild* createChild(const KURL&, HTMLImport* parent, HTMLImportChildClient*);
- void clear();
-
- Document* m_master;
- Timer<HTMLImportsController> m_unblockTimer;
-
- // List of import which has been loaded or being loaded.
- typedef Vector<OwnPtr<HTMLImportChild> > ImportList;
- ImportList m_imports;
-};
-
-} // namespace WebCore
-
-#endif // HTMLImportsController_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
index 6d2e2e8eeb6..6cc8bddeacb 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.cpp
@@ -29,12 +29,11 @@
#include "config.h"
#include "core/html/HTMLInputElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
@@ -48,11 +47,12 @@
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
#include "core/events/ScopedEventQueue.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/TouchEvent.h"
#include "core/fileapi/FileList.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDataListElement.h"
#include "core/html/HTMLFormElement.h"
@@ -65,34 +65,33 @@
#include "core/html/forms/SearchInputType.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/shadow/ShadowElementNames.h"
-#include "core/frame/UseCounter.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
#include "core/rendering/RenderTextControlSingleLine.h"
#include "core/rendering/RenderTheme.h"
+#include "platform/ColorChooser.h"
#include "platform/DateTimeChooser.h"
#include "platform/Language.h"
#include "platform/PlatformMouseEvent.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/MathExtras.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
-class ListAttributeTargetObserver : IdTargetObserver {
- WTF_MAKE_FAST_ALLOCATED;
+class ListAttributeTargetObserver : public IdTargetObserver {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<ListAttributeTargetObserver> create(const AtomicString& id, HTMLInputElement*);
+ static PassOwnPtrWillBeRawPtr<ListAttributeTargetObserver> create(const AtomicString& id, HTMLInputElement*);
+ virtual void trace(Visitor*) OVERRIDE;
virtual void idTargetChanged() OVERRIDE;
private:
ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*);
- HTMLInputElement* m_element;
+ RawPtrWillBeMember<HTMLInputElement> m_element;
};
// FIXME: According to HTML4, the length attribute's value can be arbitrarily
@@ -111,7 +110,6 @@ HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo
, m_isChecked(false)
, m_reflectsCheckedAttribute(true)
, m_isIndeterminate(false)
- , m_hasType(false)
, m_isActivatedSubmit(false)
, m_autocomplete(Uninitialized)
, m_hasNonEmptyList(false)
@@ -120,6 +118,8 @@ HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo
, m_valueAttributeWasUpdatedAfterParsing(false)
, m_canReceiveDroppedFiles(false)
, m_hasTouchEventHandler(false)
+ , m_shouldRevealPassword(false)
+ , m_needsToUpdateViewValue(true)
, m_inputType(InputType::createText(*this))
, m_inputTypeView(m_inputType)
{
@@ -129,17 +129,26 @@ HTMLInputElement::HTMLInputElement(Document& document, HTMLFormElement* form, bo
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLInputElement> HTMLInputElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLInputElement> HTMLInputElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
{
- RefPtr<HTMLInputElement> inputElement = adoptRef(new HTMLInputElement(document, form, createdByParser));
+ RefPtrWillBeRawPtr<HTMLInputElement> inputElement = adoptRefWillBeNoop(new HTMLInputElement(document, form, createdByParser));
inputElement->ensureUserAgentShadowRoot();
return inputElement.release();
}
+void HTMLInputElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_inputType);
+ visitor->trace(m_inputTypeView);
+ visitor->trace(m_listAttributeTargetObserver);
+ visitor->trace(m_imageLoader);
+ HTMLTextFormControlElement::trace(visitor);
+}
+
HTMLImageLoader* HTMLInputElement::imageLoader()
{
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
return m_imageLoader.get();
}
@@ -148,10 +157,8 @@ void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot&)
m_inputTypeView->createShadowSubtree();
}
-void HTMLInputElement::didAddShadowRoot(ShadowRoot& root)
+void HTMLInputElement::willAddFirstAuthorShadowRoot()
{
- if (!root.isOldestAuthorShadowRoot())
- return;
m_inputTypeView->destroyShadowSubtree();
m_inputTypeView = InputTypeView::create(*this);
lazyReattachIfAttached();
@@ -159,15 +166,17 @@ void HTMLInputElement::didAddShadowRoot(ShadowRoot& root)
HTMLInputElement::~HTMLInputElement()
{
+#if !ENABLE(OILPAN)
// Need to remove form association while this is still an HTMLInputElement
// so that virtual functions are called correctly.
setForm(0);
// setForm(0) may register this to a document-level radio button group.
// We should unregister it to avoid accessing a deleted object.
if (isRadioButton())
- document().formController()->checkedRadioButtons().removeButton(this);
+ document().formController().radioButtonGroupScope().removeButton(this);
if (m_hasTouchEventHandler)
- document().didRemoveEventTargetNode(this);
+ document().didRemoveTouchEventHandler(this);
+#endif
}
const AtomicString& HTMLInputElement::name() const
@@ -180,11 +189,6 @@ Vector<FileChooserFileInfo> HTMLInputElement::filesFromFileInputFormControlState
return FileInputType::filesFromFormControlState(state);
}
-HTMLElement* HTMLInputElement::passwordGeneratorButtonElement() const
-{
- return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementNames::passwordGenerator()));
-}
-
bool HTMLInputElement::shouldAutocomplete() const
{
if (m_autocomplete != Uninitialized)
@@ -339,7 +343,7 @@ bool HTMLInputElement::shouldShowFocusRingOnMouseFocus() const
void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
{
if (isTextField()) {
- if (!restorePreviousSelection || !hasCachedSelection())
+ if (!restorePreviousSelection)
select();
else
restoreCachedSelection();
@@ -351,23 +355,28 @@ void HTMLInputElement::updateFocusAppearance(bool restorePreviousSelection)
void HTMLInputElement::beginEditing()
{
+ ASSERT(document().isActive());
+ if (!document().isActive())
+ return;
+
if (!isTextField())
return;
- if (Frame* frame = document().frame())
- frame->spellChecker().didBeginEditing(this);
+ document().frame()->spellChecker().didBeginEditing(this);
}
void HTMLInputElement::endEditing()
{
+ ASSERT(document().isActive());
+ if (!document().isActive())
+ return;
+
if (!isTextField())
return;
- if (Frame* frame = document().frame()) {
- frame->spellChecker().didEndEditingOnTextField(this);
- if (Page* page = frame->page())
- page->chrome().client().didEndEditingOnTextField(*this);
- }
+ LocalFrame* frame = document().frame();
+ frame->spellChecker().didEndEditingOnTextField(this);
+ frame->host()->chrome().client().didEndEditingOnTextField(*this);
}
bool HTMLInputElement::shouldUseInputMethod()
@@ -375,9 +384,9 @@ bool HTMLInputElement::shouldUseInputMethod()
return m_inputType->shouldUseInputMethod();
}
-void HTMLInputElement::handleFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void HTMLInputElement::handleFocusEvent(Element* oldFocusedElement, FocusType type)
{
- m_inputTypeView->handleFocusEvent(oldFocusedElement, direction);
+ m_inputTypeView->handleFocusEvent(oldFocusedElement, type);
m_inputType->enableSecureTextInput();
}
@@ -389,32 +398,17 @@ void HTMLInputElement::handleBlurEvent()
void HTMLInputElement::setType(const AtomicString& type)
{
- // FIXME: This should just call setAttribute. No reason to handle the empty string specially.
- // We should write a test case to show that setting to the empty string does not remove the
- // attribute in other browsers and then fix this. Note that setting to null *does* remove
- // the attribute and setAttribute implements that.
- if (type.isEmpty())
- removeAttribute(typeAttr);
- else
- setAttribute(typeAttr, type);
+ setAttribute(typeAttr, type);
}
void HTMLInputElement::updateType()
{
const AtomicString& newTypeName = InputType::normalizeTypeName(fastGetAttribute(typeAttr));
- bool hadType = m_hasType;
- m_hasType = true;
- if (m_inputType->formControlType() == newTypeName)
- return;
- if (hadType && !InputType::canChangeFromAnotherType(newTypeName)) {
- // Set the attribute back to the old value.
- // Useful in case we were called from inside parseAttribute.
- setAttribute(typeAttr, type());
+ if (m_inputType->formControlType() == newTypeName)
return;
- }
- RefPtr<InputType> newType = InputType::create(*this, newTypeName);
+ RefPtrWillBeRawPtr<InputType> newType = InputType::create(*this, newTypeName);
removeFromRadioButtonGroup();
bool didStoreValue = m_inputType->storesValueSeparateFromAttribute();
@@ -453,16 +447,16 @@ void HTMLInputElement::updateType()
} else
updateValueIfNeeded();
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_inputTypeView->updateView();
if (didRespectHeightAndWidth != m_inputType->shouldRespectHeightAndWidthAttributes()) {
ASSERT(elementData());
- if (const Attribute* height = getAttributeItem(heightAttr))
+ if (const Attribute* height = findAttributeByName(heightAttr))
attributeChanged(heightAttr, height->value());
- if (const Attribute* width = getAttributeItem(widthAttr))
+ if (const Attribute* width = findAttributeByName(widthAttr))
attributeChanged(widthAttr, width->value());
- if (const Attribute* align = getAttributeItem(alignAttr))
+ if (const Attribute* align = findAttributeByName(alignAttr))
attributeChanged(alignAttr, align->value());
}
@@ -514,11 +508,6 @@ bool HTMLInputElement::canStartSelection() const
return HTMLTextFormControlElement::canStartSelection();
}
-bool HTMLInputElement::canHaveSelection() const
-{
- return isTextField();
-}
-
int HTMLInputElement::selectionStartForBinding(ExceptionState& exceptionState) const
{
if (!m_inputType->supportsSelectionAPI()) {
@@ -648,9 +637,9 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
// We only need to setChanged if the form is looking at the default value right now.
if (!hasDirtyValue()) {
updatePlaceholderVisibility(false);
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
setNeedsValidityCheck();
m_valueAttributeWasUpdatedAfterParsing = !m_parsingInProgress;
m_inputTypeView->valueAttributeChanged();
@@ -670,7 +659,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
int valueAsInteger = value.toInt();
m_size = valueAsInteger > 0 ? valueAsInteger : defaultSize;
if (m_size != oldSize && renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
} else if (name == altAttr)
m_inputTypeView->altAttributeChanged();
else if (name == srcAttr)
@@ -679,7 +668,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
// FIXME: ignore for the moment
} else if (name == onsearchAttr) {
// Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
- setAttributeEventListener(EventTypeNames::search, createAttributeEventListener(this, name, value));
+ setAttributeEventListener(EventTypeNames::search, createAttributeEventListener(this, name, value, eventParameterName()));
} else if (name == resultsAttr) {
int oldResults = m_maxResults;
m_maxResults = !value.isNull() ? std::min(value.toInt(), maxSavedResults) : -1;
@@ -687,10 +676,10 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
// time to relayout for this change.
if (m_maxResults != oldResults && (m_maxResults <= 0 || oldResults <= 0))
lazyReattachIfAttached();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
UseCounter::count(document(), UseCounter::ResultsAttribute);
} else if (name == incrementalAttr) {
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
UseCounter::count(document(), UseCounter::IncrementalAttribute);
} else if (name == minAttr) {
m_inputTypeView->minOrMaxAttributeChanged();
@@ -711,9 +700,6 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
} else if (name == patternAttr) {
setNeedsValidityCheck();
UseCounter::count(document(), UseCounter::PatternAttribute);
- } else if (name == precisionAttr) {
- setNeedsValidityCheck();
- UseCounter::count(document(), UseCounter::PrecisionAttribute);
} else if (name == disabledAttr) {
HTMLTextFormControlElement::parseAttribute(name, value);
m_inputTypeView->disabledAttributeChanged();
@@ -727,24 +713,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicStr
listAttributeTargetChanged();
}
UseCounter::count(document(), UseCounter::ListAttribute);
- }
-#if ENABLE(INPUT_SPEECH)
- else if (name == webkitspeechAttr) {
- if (RuntimeEnabledFeatures::speechInputEnabled() && m_inputType->shouldRespectSpeechAttribute()) {
- // This renderer and its children have quite different layouts and
- // styles depending on whether the speech button is visible or
- // not. So we reset the whole thing and recreate to get the right
- // styles and layout.
- m_inputTypeView->destroyShadowSubtree();
- lazyReattachIfAttached();
- m_inputTypeView->createShadowSubtree();
- setFormControlValueMatchesRenderer(false);
- }
- UseCounter::count(document(), UseCounter::PrefixedSpeechAttribute);
- } else if (name == onwebkitspeechchangeAttr)
- setAttributeEventListener(EventTypeNames::webkitspeechchange, createAttributeEventListener(this, name, value));
-#endif
- else if (name == webkitdirectoryAttr) {
+ } else if (name == webkitdirectoryAttr) {
HTMLTextFormControlElement::parseAttribute(name, value);
UseCounter::count(document(), UseCounter::PrefixedDirectoryAttribute);
}
@@ -777,9 +746,6 @@ RenderObject* HTMLInputElement::createRenderer(RenderStyle* style)
void HTMLInputElement::attach(const AttachContext& context)
{
- if (!m_hasType)
- updateType();
-
HTMLTextFormControlElement::attach(context);
m_inputTypeView->startResourceLoading();
@@ -792,7 +758,7 @@ void HTMLInputElement::attach(const AttachContext& context)
void HTMLInputElement::detach(const AttachContext& context)
{
HTMLTextFormControlElement::detach(context);
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_inputTypeView->closePopupView();
}
@@ -804,9 +770,9 @@ String HTMLInputElement::altText() const
String alt = fastGetAttribute(altAttr);
// fall back to title attribute
if (alt.isNull())
- alt = getAttribute(titleAttr);
+ alt = fastGetAttribute(titleAttr);
if (alt.isNull())
- alt = getAttribute(valueAttr);
+ alt = fastGetAttribute(valueAttr);
if (alt.isEmpty())
alt = locale().queryString(blink::WebLocalizedString::InputElementAltText);
return alt;
@@ -839,8 +805,10 @@ String HTMLInputElement::resultForDialogSubmit()
void HTMLInputElement::resetImpl()
{
- if (m_inputType->storesValueSeparateFromAttribute())
+ if (m_inputType->storesValueSeparateFromAttribute()) {
setValue(String());
+ setNeedsValidityCheck();
+ }
setChecked(hasAttribute(checkedAttr));
m_reflectsCheckedAttribute = true;
@@ -861,14 +829,15 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
if (checked() == nowChecked)
return;
+ RefPtrWillBeRawPtr<HTMLInputElement> protector(this);
m_reflectsCheckedAttribute = false;
m_isChecked = nowChecked;
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- buttons->updateCheckedState(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ scope->updateCheckedState(this);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), CheckedState);
+ RenderTheme::theme().stateChanged(renderer(), CheckedControlState);
setNeedsValidityCheck();
@@ -887,6 +856,8 @@ void HTMLInputElement::setChecked(bool nowChecked, TextFieldEventBehavior eventB
// definitely wrong in practice for these types of elements.
if (eventBehavior != DispatchNoEvent && inDocument() && m_inputType->shouldSendChangeEventAfterCheckedChanged()) {
setTextAsOfLastFormControlChangeEvent(String());
+ if (eventBehavior == DispatchInputAndChangeEvent)
+ dispatchFormControlInputEvent();
dispatchFormControlChangeEvent();
}
@@ -903,7 +874,7 @@ void HTMLInputElement::setIndeterminate(bool newValue)
didAffectSelector(AffectedSelectorIndeterminate);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), CheckedState);
+ RenderTheme::theme().stateChanged(renderer(), CheckedControlState);
}
int HTMLInputElement::size() const
@@ -927,7 +898,7 @@ void HTMLInputElement::copyNonAttributePropertiesFromElement(const Element& sour
HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(source);
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_inputTypeView->updateView();
}
@@ -973,9 +944,9 @@ void HTMLInputElement::setSuggestedValue(const String& value)
{
if (!m_inputType->canSetSuggestedValue())
return;
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_suggestedValue = sanitizeValue(value);
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
m_inputTypeView->updateView();
}
@@ -983,7 +954,7 @@ void HTMLInputElement::setEditingValue(const String& value)
{
if (!renderer() || !isTextField())
return;
- setInnerTextValue(value);
+ setInnerEditorValue(value);
subtreeHasChanged();
unsigned max = value.length();
@@ -995,10 +966,16 @@ void HTMLInputElement::setEditingValue(const String& value)
dispatchInputEvent();
}
+void HTMLInputElement::setInnerEditorValue(const String& value)
+{
+ HTMLTextFormControlElement::setInnerEditorValue(value);
+ m_needsToUpdateViewValue = false;
+}
+
void HTMLInputElement::setValue(const String& value, ExceptionState& exceptionState, TextFieldEventBehavior eventBehavior)
{
if (isFileUpload() && !value.isEmpty()) {
- exceptionState.throwDOMException(InvalidStateError, "This input element accepts a filename, which may only be programatically set to the empty string.");
+ exceptionState.throwDOMException(InvalidStateError, "This input element accepts a filename, which may only be programmatically set to the empty string.");
return;
}
setValue(value, eventBehavior);
@@ -1009,13 +986,13 @@ void HTMLInputElement::setValue(const String& value, TextFieldEventBehavior even
if (!m_inputType->canSetValue(value))
return;
- RefPtr<HTMLInputElement> protector(this);
+ RefPtrWillBeRawPtr<HTMLInputElement> protector(this);
EventQueueScope scope;
String sanitizedValue = sanitizeValue(value);
bool valueChanged = sanitizedValue != this->value();
setLastChangeWasNotUserEdit();
- setFormControlValueMatchesRenderer(false);
+ m_needsToUpdateViewValue = true;
m_suggestedValue = String(); // Prevent TextFieldInputType::setValue from using the suggested value.
m_inputType->setValue(sanitizedValue, valueChanged, eventBehavior);
@@ -1033,11 +1010,20 @@ void HTMLInputElement::setValueInternal(const String& sanitizedValue, TextFieldE
{
m_valueIfDirty = sanitizedValue;
setNeedsValidityCheck();
+ if (document().focusedElement() == this)
+ document().frameHost()->chrome().client().didUpdateTextOfFocusedElementByNonUserInput();
+}
+
+void HTMLInputElement::updateView()
+{
+ m_inputTypeView->updateView();
}
-double HTMLInputElement::valueAsDate() const
+double HTMLInputElement::valueAsDate(bool& isNull) const
{
- return m_inputType->valueAsDate();
+ double date = m_inputType->valueAsDate();
+ isNull = !std::isfinite(date);
+ return date;
}
void HTMLInputElement::setValueAsDate(double value, ExceptionState& exceptionState)
@@ -1052,8 +1038,10 @@ double HTMLInputElement::valueAsNumber() const
void HTMLInputElement::setValueAsNumber(double newValue, ExceptionState& exceptionState, TextFieldEventBehavior eventBehavior)
{
- if (!std::isfinite(newValue)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(newValue));
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#dom-input-valueasnumber
+ // On setting, if the new value is infinite, then throw a TypeError exception.
+ if (std::isinf(newValue)) {
+ exceptionState.throwTypeError(ExceptionMessages::notAFiniteNumber(newValue));
return;
}
m_inputType->setValueAsDouble(newValue, eventBehavior, exceptionState);
@@ -1070,8 +1058,7 @@ void HTMLInputElement::setValueFromRenderer(const String& value)
ASSERT(value == sanitizeValue(value) || sanitizeValue(value).isEmpty());
m_valueIfDirty = value;
-
- setFormControlValueMatchesRenderer(true);
+ m_needsToUpdateViewValue = false;
// Input event is fired by the Node::defaultEventHandler for editable controls.
if (!isTextField())
@@ -1094,13 +1081,17 @@ void* HTMLInputElement::preDispatchEventHandler(Event* event)
return 0;
if (!event->isMouseEvent() || toMouseEvent(event)->button() != LeftButton)
return 0;
+#if ENABLE(OILPAN)
+ return m_inputTypeView->willDispatchClick();
+#else
// FIXME: Check whether there are any cases where this actually ends up leaking.
return m_inputTypeView->willDispatchClick().leakPtr();
+#endif
}
void HTMLInputElement::postDispatchEventHandler(Event* event, void* dataFromPreDispatch)
{
- OwnPtr<ClickHandlingState> state = adoptPtr(static_cast<ClickHandlingState*>(dataFromPreDispatch));
+ OwnPtrWillBeRawPtr<ClickHandlingState> state = adoptPtrWillBeNoop(static_cast<ClickHandlingState*>(dataFromPreDispatch));
if (!state)
return;
m_inputTypeView->didDispatchClick(event, *state);
@@ -1114,7 +1105,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
return;
}
- if (evt->isTouchEvent()) {
+ if (evt->isTouchEvent() && m_inputTypeView->hasTouchEventHandler()) {
m_inputTypeView->handleTouchEvent(toTouchEvent(evt));
if (evt->defaultHandled())
return;
@@ -1167,7 +1158,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
if (wasChangedSinceLastFormControlChangeEvent())
dispatchFormControlChangeEvent();
- RefPtr<HTMLFormElement> formForSubmission = m_inputTypeView->formForSubmission();
+ RefPtrWillBeRawPtr<HTMLFormElement> formForSubmission = m_inputTypeView->formForSubmission();
// Form may never have been present, or may have been destroyed by code responding to the change event.
if (formForSubmission)
formForSubmission->submitImplicitly(evt, canTriggerImplicitSubmission());
@@ -1205,6 +1196,16 @@ bool HTMLInputElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || attribute.name() == formactionAttr || HTMLTextFormControlElement::isURLAttribute(attribute);
}
+bool HTMLInputElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return m_inputType->hasLegalLinkAttribute(name) || HTMLTextFormControlElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLInputElement::subResourceAttributeName() const
+{
+ return m_inputType->subResourceAttributeName();
+}
+
const AtomicString& HTMLInputElement::defaultValue() const
{
return fastGetAttribute(valueAttr);
@@ -1269,11 +1270,6 @@ Vector<String> HTMLInputElement::acceptFileExtensions()
return parseAcceptAttribute(fastGetAttribute(acceptAttr), isValidFileExtension);
}
-const AtomicString& HTMLInputElement::accept() const
-{
- return fastGetAttribute(acceptAttr);
-}
-
const AtomicString& HTMLInputElement::alt() const
{
return fastGetAttribute(altAttr);
@@ -1320,7 +1316,7 @@ FileList* HTMLInputElement::files()
return m_inputType->files();
}
-void HTMLInputElement::setFiles(PassRefPtr<FileList> files)
+void HTMLInputElement::setFiles(PassRefPtrWillBeRawPtr<FileList> files)
{
m_inputType->setFiles(files);
}
@@ -1349,11 +1345,6 @@ void HTMLInputElement::setCanReceiveDroppedFiles(bool canReceiveDroppedFiles)
renderer()->updateFromElement();
}
-String HTMLInputElement::visibleValue() const
-{
- return m_inputType->visibleValue();
-}
-
String HTMLInputElement::sanitizeValue(const String& proposedValue) const
{
if (proposedValue.isNull())
@@ -1442,9 +1433,9 @@ void HTMLInputElement::didMoveToNewDocument(Document& oldDocument)
imageLoader()->elementDidMoveToNewDocument();
if (isRadioButton())
- oldDocument.formController()->checkedRadioButtons().removeButton(this);
+ oldDocument.formController().radioButtonGroupScope().removeButton(this);
if (m_hasTouchEventHandler)
- oldDocument.didRemoveEventTargetNode(this);
+ oldDocument.didRemoveTouchEventHandler(this);
if (m_hasTouchEventHandler)
document().didAddTouchEventHandler(this);
@@ -1452,11 +1443,10 @@ void HTMLInputElement::didMoveToNewDocument(Document& oldDocument)
HTMLTextFormControlElement::didMoveToNewDocument(oldDocument);
}
-void HTMLInputElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+void HTMLInputElement::removeAllEventListeners()
{
- HTMLTextFormControlElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, src());
+ HTMLTextFormControlElement::removeAllEventListeners();
+ m_hasTouchEventHandler = false;
}
bool HTMLInputElement::recalcWillValidate() const
@@ -1467,8 +1457,8 @@ bool HTMLInputElement::recalcWillValidate() const
void HTMLInputElement::requiredAttributeChanged()
{
HTMLTextFormControlElement::requiredAttributeChanged();
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- buttons->requiredAttributeChanged(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ scope->requiredAttributeChanged(this);
m_inputTypeView->requiredAttributeChanged();
}
@@ -1495,7 +1485,7 @@ HTMLDataListElement* HTMLInputElement::dataList() const
Element* element = treeScope().getElementById(fastGetAttribute(listAttr));
if (!element)
return 0;
- if (!element->hasTagName(datalistTag))
+ if (!isHTMLDataListElement(*element))
return 0;
return toHTMLDataListElement(element);
@@ -1506,7 +1496,7 @@ bool HTMLInputElement::hasValidDataListOptions() const
HTMLDataListElement* dataList = this->dataList();
if (!dataList)
return false;
- RefPtr<HTMLCollection> options = dataList->options();
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
if (isValidValue(option->value()))
return true;
@@ -1514,12 +1504,19 @@ bool HTMLInputElement::hasValidDataListOptions() const
return false;
}
+void HTMLInputElement::setListAttributeTargetObserver(PassOwnPtrWillBeRawPtr<ListAttributeTargetObserver> newObserver)
+{
+ if (m_listAttributeTargetObserver)
+ m_listAttributeTargetObserver->unregister();
+ m_listAttributeTargetObserver = newObserver;
+}
+
void HTMLInputElement::resetListAttributeTargetObserver()
{
if (inDocument())
- m_listAttributeTargetObserver = ListAttributeTargetObserver::create(fastGetAttribute(listAttr), this);
+ setListAttributeTargetObserver(ListAttributeTargetObserver::create(fastGetAttribute(listAttr), this));
else
- m_listAttributeTargetObserver = nullptr;
+ setListAttributeTargetObserver(nullptr);
}
void HTMLInputElement::listAttributeTargetChanged()
@@ -1532,16 +1529,6 @@ bool HTMLInputElement::isSteppable() const
return m_inputType->isSteppable();
}
-#if ENABLE(INPUT_SPEECH)
-
-bool HTMLInputElement::isSpeechEnabled() const
-{
- // FIXME: Add support for RANGE, EMAIL, URL, COLOR and DATE/TIME input types.
- return m_inputType->shouldRespectSpeechAttribute() && RuntimeEnabledFeatures::speechInputEnabled() && hasAttribute(webkitspeechAttr);
-}
-
-#endif
-
bool HTMLInputElement::isTextButton() const
{
return m_inputType->isTextButton();
@@ -1577,11 +1564,6 @@ bool HTMLInputElement::isRangeControl() const
return m_inputType->isRangeControl();
}
-bool HTMLInputElement::isColorControl() const
-{
- return m_inputType->isColorControl();
-}
-
bool HTMLInputElement::isText() const
{
return m_inputType->isTextType();
@@ -1607,11 +1589,6 @@ bool HTMLInputElement::isNumberField() const
return m_inputType->isNumberField();
}
-bool HTMLInputElement::isSubmitButton() const
-{
- return m_inputType->isSubmitButton();
-}
-
bool HTMLInputElement::isTelephoneField() const
{
return m_inputType->isTelephoneField();
@@ -1669,7 +1646,7 @@ bool HTMLInputElement::supportsPlaceholder() const
void HTMLInputElement::updatePlaceholderText()
{
- return m_inputType->updatePlaceholderText();
+ return m_inputTypeView->updatePlaceholderText();
}
void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
@@ -1683,7 +1660,7 @@ void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
m_maxLength = maxLength;
if (oldMaxLength != maxLength)
updateValueIfNeeded();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
setNeedsValidityCheck();
}
@@ -1705,61 +1682,42 @@ bool HTMLInputElement::shouldAppearIndeterminate() const
return m_inputType->supportsIndeterminateAppearance() && indeterminate();
}
-#if ENABLE(MEDIA_CAPTURE)
-bool HTMLInputElement::capture() const
-{
- if (!isFileUpload() || !fastHasAttribute(captureAttr))
- return false;
-
- // As per crbug.com/240252, emit a deprecation warning when the "capture"
- // attribute is used as an enum. The spec has been updated and "capture" is
- // supposed to be used as a boolean.
- bool hasDeprecatedUsage = !fastGetAttribute(captureAttr).isNull();
- if (hasDeprecatedUsage)
- UseCounter::countDeprecation(document(), UseCounter::CaptureAttributeAsEnum);
- else
- UseCounter::count(document(), UseCounter::CaptureAttributeAsEnum);
-
- return true;
-}
-#endif
-
bool HTMLInputElement::isInRequiredRadioButtonGroup()
{
ASSERT(isRadioButton());
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- return buttons->isInRequiredGroup(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ return scope->isInRequiredGroup(this);
return false;
}
HTMLInputElement* HTMLInputElement::checkedRadioButtonForGroup() const
{
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- return buttons->checkedButtonForGroup(name());
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ return scope->checkedButtonForGroup(name());
return 0;
}
-CheckedRadioButtons* HTMLInputElement::checkedRadioButtons() const
+RadioButtonGroupScope* HTMLInputElement::radioButtonGroupScope() const
{
if (!isRadioButton())
return 0;
if (HTMLFormElement* formElement = form())
- return &formElement->checkedRadioButtons();
+ return &formElement->radioButtonGroupScope();
if (inDocument())
- return &document().formController()->checkedRadioButtons();
+ return &document().formController().radioButtonGroupScope();
return 0;
}
inline void HTMLInputElement::addToRadioButtonGroup()
{
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- buttons->addButton(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ scope->addButton(this);
}
inline void HTMLInputElement::removeFromRadioButtonGroup()
{
- if (CheckedRadioButtons* buttons = checkedRadioButtons())
- buttons->removeButton(this);
+ if (RadioButtonGroupScope* scope = radioButtonGroupScope())
+ scope->removeButton(this);
}
unsigned HTMLInputElement::height() const
@@ -1782,9 +1740,9 @@ void HTMLInputElement::setWidth(unsigned width)
setUnsignedIntegralAttribute(widthAttr, width);
}
-PassOwnPtr<ListAttributeTargetObserver> ListAttributeTargetObserver::create(const AtomicString& id, HTMLInputElement* element)
+PassOwnPtrWillBeRawPtr<ListAttributeTargetObserver> ListAttributeTargetObserver::create(const AtomicString& id, HTMLInputElement* element)
{
- return adoptPtr(new ListAttributeTargetObserver(id, element));
+ return adoptPtrWillBeNoop(new ListAttributeTargetObserver(id, element));
}
ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement* element)
@@ -1793,6 +1751,12 @@ ListAttributeTargetObserver::ListAttributeTargetObserver(const AtomicString& id,
{
}
+void ListAttributeTargetObserver::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ IdTargetObserver::trace(visitor);
+}
+
void ListAttributeTargetObserver::idTargetChanged()
{
m_element->listAttributeTargetChanged();
@@ -1831,7 +1795,7 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
parameters.locale = defaultLanguage();
else {
AtomicString computedLocale = computeInheritedLanguage();
- parameters.locale = computedLocale.isEmpty() ? AtomicString(defaultLanguage()) : computedLocale;
+ parameters.locale = computedLocale.isEmpty() ? defaultLanguage() : computedLocale;
}
StepRange stepRange = createStepRange(RejectAny);
@@ -1847,20 +1811,18 @@ bool HTMLInputElement::setupDateTimeChooserParameters(DateTimeChooserParameters&
parameters.currentValue = value();
parameters.doubleValue = m_inputType->valueAsDouble();
parameters.isAnchorElementRTL = computedStyle()->direction() == RTL;
- if (RuntimeEnabledFeatures::dataListElementEnabled()) {
- if (HTMLDataListElement* dataList = this->dataList()) {
- RefPtr<HTMLCollection> options = dataList->options();
- for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
- if (!isValidValue(option->value()))
- continue;
- DateTimeSuggestion suggestion;
- suggestion.value = m_inputType->parseToNumber(option->value(), Decimal::nan()).toDouble();
- if (std::isnan(suggestion.value))
- continue;
- suggestion.localizedValue = localizeValue(option->value());
- suggestion.label = option->value() == option->label() ? String() : option->label();
- parameters.suggestions.append(suggestion);
- }
+ if (HTMLDataListElement* dataList = this->dataList()) {
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
+ for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
+ if (!isValidValue(option->value()))
+ continue;
+ DateTimeSuggestion suggestion;
+ suggestion.value = m_inputType->parseToNumber(option->value(), Decimal::nan()).toDouble();
+ if (std::isnan(suggestion.value))
+ continue;
+ suggestion.localizedValue = localizeValue(option->value());
+ suggestion.label = option->value() == option->label() ? String() : option->label();
+ parameters.suggestions.append(suggestion);
}
}
return true;
@@ -1871,11 +1833,24 @@ bool HTMLInputElement::supportsInputModeAttribute() const
return m_inputType->supportsInputModeAttribute();
}
+void HTMLInputElement::setShouldRevealPassword(bool value)
+{
+ if (m_shouldRevealPassword == value)
+ return;
+ m_shouldRevealPassword = value;
+ lazyReattachIfAttached();
+}
+
bool HTMLInputElement::isInteractiveContent() const
{
return m_inputType->isInteractiveContent();
}
+bool HTMLInputElement::supportsAutofocus() const
+{
+ return m_inputType->isInteractiveContent();
+}
+
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
PassRefPtr<RenderStyle> HTMLInputElement::customStyleForRenderer()
{
@@ -1883,4 +1858,9 @@ PassRefPtr<RenderStyle> HTMLInputElement::customStyleForRenderer()
}
#endif
+bool HTMLInputElement::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
+{
+ return m_inputType->shouldDispatchFormControlChangeEvent(oldValue, newValue);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h
index 4e61ec102c2..4bf5c86a1ec 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.h
@@ -31,39 +31,39 @@
namespace WebCore {
-class CheckedRadioButtons;
class DragData;
class ExceptionState;
class FileList;
class HTMLDataListElement;
class HTMLImageLoader;
class HTMLOptionElement;
-class Icon;
class InputType;
class InputTypeView;
class KURL;
class ListAttributeTargetObserver;
+class RadioButtonGroupScope;
struct DateTimeChooserParameters;
class HTMLInputElement : public HTMLTextFormControlElement {
public:
- static PassRefPtr<HTMLInputElement> create(Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLInputElement> create(Document&, HTMLFormElement*, bool createdByParser);
virtual ~HTMLInputElement();
+ virtual void trace(Visitor*) OVERRIDE;
DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitspeechchange);
- virtual bool shouldAutocomplete() const;
+ virtual bool shouldAutocomplete() const OVERRIDE FINAL;
// For ValidityState
- virtual bool hasBadInput() const OVERRIDE;
- virtual bool patternMismatch() const OVERRIDE;
- virtual bool rangeUnderflow() const OVERRIDE;
- virtual bool rangeOverflow() const;
- virtual bool stepMismatch() const OVERRIDE;
- virtual bool tooLong() const OVERRIDE;
- virtual bool typeMismatch() const OVERRIDE;
- virtual bool valueMissing() const OVERRIDE;
- virtual String validationMessage() const OVERRIDE;
+ virtual bool hasBadInput() const OVERRIDE FINAL;
+ virtual bool patternMismatch() const OVERRIDE FINAL;
+ virtual bool rangeUnderflow() const OVERRIDE FINAL;
+ virtual bool rangeOverflow() const OVERRIDE FINAL;
+ virtual bool stepMismatch() const OVERRIDE FINAL;
+ virtual bool tooLong() const OVERRIDE FINAL;
+ virtual bool typeMismatch() const OVERRIDE FINAL;
+ virtual bool valueMissing() const OVERRIDE FINAL;
+ virtual String validationMessage() const OVERRIDE FINAL;
// Returns the minimum value for type=date, number, or range. Don't call this for other types.
double minimum() const;
@@ -94,7 +94,6 @@ public:
bool isPasswordField() const;
bool isCheckbox() const;
bool isRangeControl() const;
- bool isColorControl() const;
// FIXME: It's highly likely that any call site calling this function should instead
// be using a different one. Many input elements behave like text fields, and in addition
@@ -106,7 +105,6 @@ public:
bool isFileUpload() const;
bool isImageButton() const;
bool isNumberField() const;
- bool isSubmitButton() const;
bool isTelephoneField() const;
bool isURLField() const;
bool isDateField() const;
@@ -115,12 +113,6 @@ public:
bool isTimeField() const;
bool isWeekField() const;
-#if ENABLE(INPUT_SPEECH)
- bool isSpeechEnabled() const;
-#endif
-
- HTMLElement* passwordGeneratorButtonElement() const;
-
bool checked() const { return m_isChecked; }
void setChecked(bool, TextFieldEventBehavior = DispatchNoEvent);
@@ -136,7 +128,7 @@ public:
void setType(const AtomicString&);
- String value() const;
+ virtual String value() const OVERRIDE;
void setValue(const String&, ExceptionState&, TextFieldEventBehavior = DispatchNoEvent);
void setValue(const String&, TextFieldEventBehavior = DispatchNoEvent);
void setValueForUser(const String&);
@@ -149,15 +141,12 @@ public:
String localizeValue(const String&) const;
- // The value which is drawn by a renderer.
- String visibleValue() const;
-
const String& suggestedValue() const;
void setSuggestedValue(const String&);
void setEditingValue(const String&);
- double valueAsDate() const;
+ double valueAsDate(bool& isNull) const;
void setValueAsDate(double, ExceptionState&);
double valueAsNumber() const;
@@ -176,15 +165,16 @@ public:
void setSelectionRangeForBinding(int start, int end, ExceptionState&);
void setSelectionRangeForBinding(int start, int end, const String& direction, ExceptionState&);
- virtual bool rendererIsNeeded(const RenderStyle&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE FINAL;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual void detach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
+ virtual void updateFocusAppearance(bool restorePreviousSelection) OVERRIDE FINAL;
// FIXME: For isActivatedSubmit and setActivatedSubmit, we should use the NVI-idiom here by making
// it private virtual in all classes and expose a public method in HTMLFormControlElement to call
// the private virtual method.
- virtual bool isActivatedSubmit() const;
- virtual void setActivatedSubmit(bool flag);
+ virtual bool isActivatedSubmit() const OVERRIDE FINAL;
+ virtual void setActivatedSubmit(bool flag) OVERRIDE FINAL;
String altText() const;
@@ -195,7 +185,6 @@ public:
Vector<String> acceptMIMETypes();
Vector<String> acceptFileExtensions();
- const AtomicString& accept() const;
const AtomicString& alt() const;
void setSize(unsigned);
@@ -203,20 +192,19 @@ public:
KURL src() const;
- virtual int maxLength() const;
+ int maxLength() const;
void setMaxLength(int, ExceptionState&);
bool multiple() const;
FileList* files();
- void setFiles(PassRefPtr<FileList>);
+ void setFiles(PassRefPtrWillBeRawPtr<FileList>);
// Returns true if the given DragData has more than one dropped files.
bool receiveDroppedFiles(const DragData*);
String droppedFileSystemId();
- Icon* icon() const;
// These functions are used for rendering the input active during a
// drag-and-drop operation.
bool canReceiveDroppedFiles() const;
@@ -239,6 +227,9 @@ public:
// Functions for InputType classes.
void setValueInternal(const String&, TextFieldEventBehavior);
bool valueAttributeWasUpdatedAfterParsing() const { return m_valueAttributeWasUpdatedAfterParsing; }
+ void updateView();
+ bool needsToUpdateViewValue() const { return m_needsToUpdateViewValue; }
+ virtual void setInnerEditorValue(const String&) OVERRIDE;
void cacheSelectionInResponseToSetValue(int caretOffset) { cacheSelection(caretOffset, caretOffset, SelectionHasNoDirection); }
@@ -247,10 +238,6 @@ public:
String defaultToolTip() const;
-#if ENABLE(MEDIA_CAPTURE)
- bool capture() const;
-#endif
-
static const int maximumLength;
unsigned height() const;
@@ -258,20 +245,20 @@ public:
void setHeight(unsigned);
void setWidth(unsigned);
- virtual void blur() OVERRIDE;
+ virtual void blur() OVERRIDE FINAL;
void defaultBlur();
- virtual const AtomicString& name() const OVERRIDE;
+ virtual const AtomicString& name() const OVERRIDE FINAL;
void beginEditing();
void endEditing();
static Vector<FileChooserFileInfo> filesFromFileInputFormControlState(const FormControlState&);
- virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
- virtual bool matchesReadWritePseudoClass() const OVERRIDE;
- virtual void setRangeText(const String& replacement, ExceptionState&) OVERRIDE;
- virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState&) OVERRIDE;
+ virtual bool matchesReadOnlyPseudoClass() const OVERRIDE FINAL;
+ virtual bool matchesReadWritePseudoClass() const OVERRIDE FINAL;
+ virtual void setRangeText(const String& replacement, ExceptionState&) OVERRIDE FINAL;
+ virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState&) OVERRIDE FINAL;
bool hasImageLoader() const { return m_imageLoader; }
HTMLImageLoader* imageLoader();
@@ -280,105 +267,109 @@ public:
bool supportsInputModeAttribute() const;
+ void setShouldRevealPassword(bool value);
+ bool shouldRevealPassword() const { return m_shouldRevealPassword; }
+
protected:
HTMLInputElement(Document&, HTMLFormElement*, bool createdByParser);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
private:
enum AutoCompleteSetting { Uninitialized, On, Off };
- virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
- virtual void didAddShadowRoot(ShadowRoot&) OVERRIDE;
+ virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE FINAL;
+ virtual void willAddFirstAuthorShadowRoot() OVERRIDE FINAL;
- virtual void willChangeForm() OVERRIDE;
- virtual void didChangeForm() OVERRIDE;
+ virtual void willChangeForm() OVERRIDE FINAL;
+ virtual void didChangeForm() OVERRIDE FINAL;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
+ virtual void removedFrom(ContainerNode*) OVERRIDE FINAL;
+ virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE FINAL;
+ virtual void removeAllEventListeners() OVERRIDE FINAL;
- virtual bool hasCustomFocusLogic() const OVERRIDE;
- virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE;
- virtual bool isEnumeratable() const;
- virtual bool isInteractiveContent() const OVERRIDE;
- virtual bool supportLabels() const OVERRIDE;
- virtual void updateFocusAppearance(bool restorePreviousSelection);
- virtual bool shouldUseInputMethod();
+ virtual bool hasCustomFocusLogic() const OVERRIDE FINAL;
+ virtual bool isKeyboardFocusable() const OVERRIDE FINAL;
+ virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE FINAL;
+ virtual bool isEnumeratable() const OVERRIDE FINAL;
+ virtual bool isInteractiveContent() const OVERRIDE FINAL;
+ virtual bool supportLabels() const OVERRIDE FINAL;
+ virtual bool shouldUseInputMethod() OVERRIDE FINAL;
- virtual bool isTextFormControl() const { return isTextField(); }
+ virtual bool isTextFormControl() const OVERRIDE FINAL { return isTextField(); }
- virtual bool canTriggerImplicitSubmission() const { return isTextField(); }
+ virtual bool canTriggerImplicitSubmission() const OVERRIDE FINAL { return isTextField(); }
- virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const OVERRIDE FINAL;
- virtual bool shouldSaveAndRestoreFormControlState() const OVERRIDE;
- virtual FormControlState saveFormControlState() const OVERRIDE;
- virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
+ virtual bool shouldSaveAndRestoreFormControlState() const OVERRIDE FINAL;
+ virtual FormControlState saveFormControlState() const OVERRIDE FINAL;
+ virtual void restoreFormControlState(const FormControlState&) OVERRIDE FINAL;
- virtual bool canStartSelection() const;
+ virtual bool canStartSelection() const OVERRIDE FINAL;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE FINAL;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
- virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual void finishParsingChildren();
-
- virtual void copyNonAttributePropertiesFromElement(const Element&);
+ virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE FINAL;
+ virtual void finishParsingChildren() OVERRIDE FINAL;
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
+ virtual void copyNonAttributePropertiesFromElement(const Element&) OVERRIDE FINAL;
- virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
- virtual String resultForDialogSubmit() OVERRIDE;
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
- virtual bool canBeSuccessfulSubmitButton() const OVERRIDE;
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE FINAL;
+ virtual String resultForDialogSubmit() OVERRIDE FINAL;
- virtual void resetImpl() OVERRIDE;
+ virtual bool canBeSuccessfulSubmitButton() const OVERRIDE FINAL;
- virtual void* preDispatchEventHandler(Event*);
- virtual void postDispatchEventHandler(Event*, void* dataFromPreDispatch);
+ virtual void resetImpl() OVERRIDE FINAL;
+ virtual bool supportsAutofocus() const OVERRIDE FINAL;
- virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual bool isInRange() const;
- virtual bool isOutOfRange() const;
+ virtual void* preDispatchEventHandler(Event*) OVERRIDE FINAL;
+ virtual void postDispatchEventHandler(Event*, void* dataFromPreDispatch) OVERRIDE FINAL;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool isURLAttribute(const Attribute&) const OVERRIDE FINAL;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE FINAL;
+ virtual bool isInRange() const OVERRIDE FINAL;
+ virtual bool isOutOfRange() const OVERRIDE FINAL;
- bool supportsMaxLength() const { return isTextType(); }
bool isTextType() const;
bool tooLong(const String&, NeedsToCheckDirtyFlag) const;
- virtual bool supportsPlaceholder() const;
- virtual void updatePlaceholderText();
- virtual bool isEmptyValue() const OVERRIDE { return innerTextValue().isEmpty(); }
- virtual bool isEmptySuggestedValue() const { return suggestedValue().isEmpty(); }
- virtual void handleFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
- virtual void handleBlurEvent();
+ virtual bool supportsPlaceholder() const OVERRIDE FINAL;
+ virtual void updatePlaceholderText() OVERRIDE FINAL;
+ virtual bool isEmptyValue() const OVERRIDE FINAL { return innerEditorValue().isEmpty(); }
+ virtual bool isEmptySuggestedValue() const OVERRIDE FINAL { return suggestedValue().isEmpty(); }
+ virtual void handleFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE FINAL;
+ virtual void handleBlurEvent() OVERRIDE FINAL;
- virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
- virtual bool isRequiredFormControl() const;
- virtual bool recalcWillValidate() const;
- virtual void requiredAttributeChanged() OVERRIDE;
+ virtual bool isOptionalFormControl() const OVERRIDE FINAL { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const OVERRIDE FINAL;
+ virtual bool recalcWillValidate() const OVERRIDE FINAL;
+ virtual void requiredAttributeChanged() OVERRIDE FINAL;
void updateType();
- virtual void subtreeHasChanged();
+ virtual void subtreeHasChanged() OVERRIDE FINAL;
+ void setListAttributeTargetObserver(PassOwnPtrWillBeRawPtr<ListAttributeTargetObserver>);
void resetListAttributeTargetObserver();
void parseMaxLengthAttribute(const AtomicString&);
void updateValueIfNeeded();
- bool canHaveSelection() const;
-
// Returns null if this isn't associated with any radio button group.
- CheckedRadioButtons* checkedRadioButtons() const;
+ RadioButtonGroupScope* radioButtonGroupScope() const;
void addToRadioButtonGroup();
void removeFromRadioButtonGroup();
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
#endif
+ virtual bool shouldDispatchFormControlChangeEvent(String&, String&) OVERRIDE;
+
AtomicString m_name;
String m_valueIfDirty;
String m_suggestedValue;
@@ -388,7 +379,6 @@ private:
bool m_isChecked : 1;
bool m_reflectsCheckedAttribute : 1;
bool m_isIndeterminate : 1;
- bool m_hasType : 1;
bool m_isActivatedSubmit : 1;
unsigned m_autocomplete : 2; // AutoCompleteSetting
bool m_hasNonEmptyList : 1;
@@ -397,16 +387,16 @@ private:
bool m_valueAttributeWasUpdatedAfterParsing : 1;
bool m_canReceiveDroppedFiles : 1;
bool m_hasTouchEventHandler : 1;
- RefPtr<InputType> m_inputType;
- RefPtr<InputTypeView> m_inputTypeView;
+ bool m_shouldRevealPassword : 1;
+ bool m_needsToUpdateViewValue : 1;
+ RefPtrWillBeMember<InputType> m_inputType;
+ RefPtrWillBeMember<InputTypeView> m_inputTypeView;
// The ImageLoader must be owned by this element because the loader code assumes
// that it lives as long as its owning element lives. If we move the loader into
// the ImageInput object we may delete the loader while this element lives on.
- OwnPtr<HTMLImageLoader> m_imageLoader;
- OwnPtr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
+ OwnPtrWillBeMember<HTMLImageLoader> m_imageLoader;
+ OwnPtrWillBeMember<ListAttributeTargetObserver> m_listAttributeTargetObserver;
};
-DEFINE_NODE_TYPE_CASTS(HTMLInputElement, hasTagName(HTMLNames::inputTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl
index 6c2fa4e818d..8f44cfb2c30 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLInputElement.idl
@@ -19,6 +19,8 @@
* Boston, MA 02110-1301, USA.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#htmlinputelement
+
interface HTMLInputElement : HTMLElement {
[Reflect] attribute DOMString accept;
[Reflect] attribute DOMString align;
@@ -33,7 +35,7 @@ interface HTMLInputElement : HTMLElement {
// The 'files' attribute is intentionally not readonly.
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=22682
attribute FileList files;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString formAction;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString formAction;
[CustomElementCallbacks] attribute DOMString formEnctype;
[CustomElementCallbacks] attribute DOMString formMethod;
[Reflect] attribute boolean formNoValidate;
@@ -41,7 +43,7 @@ interface HTMLInputElement : HTMLElement {
[CustomElementCallbacks] attribute unsigned long height;
attribute boolean indeterminate;
[RuntimeEnabled=InputModeAttribute, Reflect] attribute DOMString inputMode;
- [RuntimeEnabled=DataListElement] readonly attribute HTMLElement list;
+ readonly attribute HTMLElement list;
[Reflect] attribute DOMString max;
[RaisesException=Setter, CustomElementCallbacks] attribute long maxLength;
[Reflect] attribute DOMString min;
@@ -52,15 +54,15 @@ interface HTMLInputElement : HTMLElement {
[Reflect] attribute boolean readOnly;
[Reflect] attribute boolean required;
[RaisesException=Setter, CustomElementCallbacks] attribute unsigned long size; // Changed string -> long -> unsigned long
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
[Reflect] attribute DOMString step;
[CustomElementCallbacks] attribute DOMString type; // readonly dropped as part of DOM level 2
[CustomElementCallbacks] attribute DOMString defaultValue;
[Reflect] attribute DOMString useMap;
// See the discussion in https://bugs.webkit.org/show_bug.cgi?id=100085
[TreatNullAs=NullString, RaisesException=Setter, CustomElementCallbacks] attribute DOMString value;
- [RaisesException=Setter, CustomElementCallbacks] attribute Date valueAsDate;
- [RaisesException=Setter, CustomElementCallbacks] attribute double valueAsNumber;
+ [RaisesException=Setter, CustomElementCallbacks] attribute Date? valueAsDate;
+ [RaisesException=Setter, CustomElementCallbacks] attribute unrestricted double valueAsNumber;
[RaisesException, CustomElementCallbacks] void stepUp(optional long n);
[RaisesException, CustomElementCallbacks] void stepDown(optional long n);
@@ -83,7 +85,7 @@ interface HTMLInputElement : HTMLElement {
[RaisesException] void setRangeText(DOMString replacement,
unsigned long start,
unsigned long end,
- [Default=NullString] optional DOMString selectionMode);
+ optional DOMString selectionMode = null);
[RaisesException, ImplementedAs=setSelectionRangeForBinding]
void setSelectionRange([Default=Undefined] optional long start,
@@ -91,11 +93,8 @@ interface HTMLInputElement : HTMLElement {
optional DOMString direction);
// Non-standard attributes
- [Reflect, RuntimeEnabled=DirectoryUpload] attribute boolean webkitdirectory;
- [Reflect] attribute boolean incremental;
- [Conditional=INPUT_SPEECH, Reflect, RuntimeEnabled=SpeechInput] attribute boolean webkitSpeech;
- [Conditional=INPUT_SPEECH, Reflect, RuntimeEnabled=SpeechInput] attribute boolean webkitGrammar;
- [Conditional=INPUT_SPEECH] attribute EventHandler onwebkitspeechchange;
+ [Reflect, MeasureAs=PrefixedDirectoryAttribute] attribute boolean webkitdirectory;
+ [Reflect, MeasureAs=IncrementalAttribute] attribute boolean incremental;
// See http://www.w3.org/TR/html-media-capture/
[Conditional=MEDIA_CAPTURE, Reflect] attribute boolean capture;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
index e6c80d009ae..231ee99672c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/html/HTMLKeygenElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ShadowRoot.h"
@@ -46,7 +46,13 @@ HTMLKeygenElement::HTMLKeygenElement(Document& document, HTMLFormElement* form)
: HTMLFormControlElementWithState(keygenTag, document, form)
{
ScriptWrappable::init(this);
- ensureUserAgentShadowRoot();
+}
+
+PassRefPtrWillBeRawPtr<HTMLKeygenElement> HTMLKeygenElement::create(Document& document, HTMLFormElement* form)
+{
+ RefPtrWillBeRawPtr<HTMLKeygenElement> keygen = adoptRefWillBeNoop(new HTMLKeygenElement(document, form));
+ keygen->ensureUserAgentShadowRoot();
+ return keygen.release();
}
void HTMLKeygenElement::didAddUserAgentShadowRoot(ShadowRoot& root)
@@ -57,10 +63,10 @@ void HTMLKeygenElement::didAddUserAgentShadowRoot(ShadowRoot& root)
getSupportedKeySizes(locale(), keys);
// Create a select element with one option element for each key size.
- RefPtr<HTMLSelectElement> select = HTMLSelectElement::create(document());
- select->setPseudo(keygenSelectPseudoId);
+ RefPtrWillBeRawPtr<HTMLSelectElement> select = HTMLSelectElement::create(document());
+ select->setShadowPseudoId(keygenSelectPseudoId);
for (size_t i = 0; i < keys.size(); ++i) {
- RefPtr<HTMLOptionElement> option = HTMLOptionElement::create(document());
+ RefPtrWillBeRawPtr<HTMLOptionElement> option = HTMLOptionElement::create(document());
option->appendChild(Text::create(document(), keys[i]));
select->appendChild(option);
}
@@ -112,4 +118,9 @@ bool HTMLKeygenElement::isInteractiveContent() const
return true;
}
+bool HTMLKeygenElement::supportsAutofocus() const
+{
+ return true;
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
index 292a78ea29d..7c4f783caa1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.h
@@ -32,10 +32,7 @@ class HTMLSelectElement;
class HTMLKeygenElement FINAL : public HTMLFormControlElementWithState {
public:
- static PassRefPtr<HTMLKeygenElement> create(Document& document, HTMLFormElement* form)
- {
- return adoptRef(new HTMLKeygenElement(document, form));
- }
+ static PassRefPtrWillBeRawPtr<HTMLKeygenElement> create(Document&, HTMLFormElement*);
virtual bool willValidate() const OVERRIDE { return false; }
@@ -54,6 +51,7 @@ private:
virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
+ virtual bool supportsAutofocus() const OVERRIDE;
virtual bool supportLabels() const OVERRIDE { return true; }
virtual void resetImpl() OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl
index 59af63817b0..4484e2b7b11 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLKeygenElement.idl
@@ -33,7 +33,7 @@ interface HTMLKeygenElement : HTMLElement {
[Reflect] attribute DOMString challenge;
[Reflect] attribute boolean disabled;
[ImplementedAs=formOwner] readonly attribute HTMLFormElement form;
- [Reflect] attribute DOMString keytype;
+ [Reflect, ReflectOnly="rsa", ReflectMissing="rsa"] attribute DOMString keytype;
[Reflect] attribute DOMString name;
readonly attribute DOMString type;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp
index aba20072981..c74defe7134 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.cpp
@@ -23,25 +23,23 @@
#include "config.h"
#include "core/html/HTMLLIElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/rendering/RenderListItem.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLLIElement::HTMLLIElement(Document& document)
+inline HTMLLIElement::HTMLLIElement(Document& document)
: HTMLElement(liTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLLIElement> HTMLLIElement::create(Document& document)
-{
- return adoptRef(new HTMLLIElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLLIElement)
bool HTMLLIElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -85,23 +83,23 @@ void HTMLLIElement::attach(const AttachContext& context)
if (renderer() && renderer()->isListItem()) {
RenderListItem* listItemRenderer = toRenderListItem(renderer());
+ ASSERT(!document().childNeedsDistributionRecalc());
+
// Find the enclosing list node.
Element* listNode = 0;
Element* current = this;
while (!listNode) {
- current = current->parentElement();
+ current = NodeRenderingTraversal::parentElement(current);
if (!current)
break;
- if (current->hasTagName(ulTag) || current->hasTagName(olTag))
+ if (isHTMLUListElement(*current) || isHTMLOListElement(*current))
listNode = current;
}
// If we are not in a list, tell the renderer so it can position us inside.
// We don't want to change our style to say "inside" since that would affect nested nodes.
- if (!listNode) {
+ if (!listNode)
listItemRenderer->setNotInList(true);
- listItemRenderer->updateMarkerLocation();
- }
parseValue(fastGetAttribute(valueAttr));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h
index a16f4b06f85..d71b76c73a5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLIElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLLIElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLLIElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLLIElement);
private:
explicit HTMLLIElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
index 6e8fa3d5ea0..ffaa6316873 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.cpp
@@ -25,23 +25,25 @@
#include "config.h"
#include "core/html/HTMLLabelElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
-#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/editing/FrameSelection.h"
+#include "core/events/MouseEvent.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/FormAssociatedElement.h"
namespace WebCore {
using namespace HTMLNames;
-static bool supportsLabels(Element* element)
+static bool supportsLabels(const Element& element)
{
- if (!element || !element->isHTMLElement())
+ if (!element.isHTMLElement())
return false;
- if (!toHTMLElement(element)->isLabelable())
+ if (!toHTMLElement(element).isLabelable())
return false;
- return toLabelableElement(element)->supportLabels();
+ return toLabelableElement(element).supportLabels();
}
inline HTMLLabelElement::HTMLLabelElement(Document& document)
@@ -50,10 +52,7 @@ inline HTMLLabelElement::HTMLLabelElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLLabelElement> HTMLLabelElement::create(Document& document)
-{
- return adoptRef(new HTMLLabelElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLLabelElement)
bool HTMLLabelElement::rendererIsFocusable() const
{
@@ -61,16 +60,15 @@ bool HTMLLabelElement::rendererIsFocusable() const
return that->isContentEditable();
}
-LabelableElement* HTMLLabelElement::control()
+LabelableElement* HTMLLabelElement::control() const
{
const AtomicString& controlId = getAttribute(forAttr);
if (controlId.isNull()) {
// Search the children and descendants of the label element for a form element.
// per http://dev.w3.org/html5/spec/Overview.html#the-label-element
// the form element must be "labelable form-associated element".
- Element* element = this;
- while ((element = ElementTraversal::next(*element, this))) {
- if (!supportsLabels(element))
+ for (Element* element = ElementTraversal::next(*this, this); element; element = ElementTraversal::next(*element, this)) {
+ if (!supportsLabels(*element))
continue;
return toLabelableElement(element);
}
@@ -78,7 +76,7 @@ LabelableElement* HTMLLabelElement::control()
}
if (Element* element = treeScope().getElementById(controlId)) {
- if (supportsLabels(element))
+ if (supportsLabels(*element))
return toLabelableElement(element);
}
@@ -87,7 +85,7 @@ LabelableElement* HTMLLabelElement::control()
HTMLFormElement* HTMLLabelElement::formOwner() const
{
- return FormAssociatedElement::findAssociatedForm(this, 0);
+ return FormAssociatedElement::findAssociatedForm(this);
}
void HTMLLabelElement::setActive(bool down)
@@ -138,7 +136,19 @@ void HTMLLabelElement::defaultEventHandler(Event* evt)
static bool processingClick = false;
if (evt->type() == EventTypeNames::click && !processingClick) {
- RefPtr<HTMLElement> element = control();
+ // If the click is not simulated and the text of label element is
+ // selected, do not pass the event to control element.
+ // Note: a click event may be not a mouse event if created by
+ // document.createEvent().
+ if (evt->isMouseEvent() && !toMouseEvent(evt)->isSimulated()) {
+ if (LocalFrame* frame = document().frame()) {
+ if (frame->selection().selection().isRange())
+ return;
+ }
+ }
+
+
+ RefPtrWillBeRawPtr<HTMLElement> element = control();
// If we can't find a control or if the control received the click
// event, then there's no need for us to do anything.
@@ -152,7 +162,7 @@ void HTMLLabelElement::defaultEventHandler(Event* evt)
document().updateLayoutIgnorePendingStylesheets();
if (element->isMouseFocusable())
- element->focus(true, FocusDirectionMouse);
+ element->focus(true, FocusTypeMouse);
// Click the corresponding control.
element->dispatchSimulatedClick(evt);
@@ -173,13 +183,13 @@ bool HTMLLabelElement::willRespondToMouseClickEvents()
return HTMLElement::willRespondToMouseClickEvents();
}
-void HTMLLabelElement::focus(bool, FocusDirection direction)
+void HTMLLabelElement::focus(bool, FocusType type)
{
// to match other browsers, always restore previous selection
if (HTMLElement* element = control())
- element->focus(true, direction);
+ element->focus(true, type);
if (isFocusable())
- HTMLElement::focus(true, direction);
+ HTMLElement::focus(true, type);
}
void HTMLLabelElement::accessKeyAction(bool sendMouseEvents)
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h
index 8ad7c6770ae..2e585d8e7ac 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLabelElement.h
@@ -31,9 +31,9 @@ namespace WebCore {
class HTMLLabelElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLLabelElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLLabelElement);
- LabelableElement* control();
+ LabelableElement* control() const;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
@@ -45,30 +45,18 @@ private:
virtual bool rendererIsFocusable() const OVERRIDE;
virtual bool isInteractiveContent() const OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
// Overridden to update the hover/active state of the corresponding control.
virtual void setActive(bool = true) OVERRIDE;
virtual void setHovered(bool = true) OVERRIDE;
// Overridden to either click() or focus() the corresponding control.
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual void focus(bool restorePreviousSelection, FocusDirection) OVERRIDE;
+ virtual void focus(bool restorePreviousSelection, FocusType) OVERRIDE;
};
-inline bool isHTMLLabelElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::labelTag);
-}
-
-inline bool isHTMLLabelElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::labelTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLLabelElement, hasTagName(HTMLNames::labelTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp
index f15aed3010b..d5d32b16d89 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/html/HTMLLegendElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLFieldSetElement.h"
#include "core/html/HTMLFormControlElement.h"
@@ -41,39 +41,30 @@ inline HTMLLegendElement::HTMLLegendElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLLegendElement> HTMLLegendElement::create(Document& document)
-{
- return adoptRef(new HTMLLegendElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLLegendElement)
HTMLFormControlElement* HTMLLegendElement::associatedControl()
{
// Check if there's a fieldset belonging to this legend.
Element* fieldset = parentElement();
- while (fieldset && !fieldset->hasTagName(fieldsetTag))
+ while (fieldset && !isHTMLFieldSetElement(*fieldset))
fieldset = fieldset->parentElement();
if (!fieldset)
return 0;
// Find first form element inside the fieldset that is not a legend element.
// FIXME: Should we consider tabindex?
- Element* element = fieldset;
- while ((element = ElementTraversal::next(*element, fieldset))) {
- if (element->isFormControlElement())
- return toHTMLFormControlElement(element);
- }
-
- return 0;
+ return Traversal<HTMLFormControlElement>::next(*fieldset, fieldset);
}
-void HTMLLegendElement::focus(bool, FocusDirection direction)
+void HTMLLegendElement::focus(bool, FocusType type)
{
if (isFocusable())
- Element::focus(true, direction);
+ Element::focus(true, type);
// To match other browsers' behavior, never restore previous selection.
if (HTMLFormControlElement* control = associatedControl())
- control->focus(false, direction);
+ control->focus(false, type);
}
void HTMLLegendElement::accessKeyAction(bool sendMouseEvents)
@@ -88,7 +79,7 @@ HTMLFormElement* HTMLLegendElement::form() const
// its parent, then the form attribute must return the same value as the
// form attribute on that fieldset element. Otherwise, it must return null.
ContainerNode* fieldset = parentNode();
- if (!fieldset || !fieldset->hasTagName(fieldsetTag))
+ if (!isHTMLFieldSetElement(fieldset))
return 0;
return toHTMLFieldSetElement(fieldset)->formOwner();
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h
index 74290a8ea33..e456be8a7ee 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLegendElement.h
@@ -32,7 +32,7 @@ class HTMLFormControlElement;
class HTMLLegendElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLLegendElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLLegendElement);
HTMLFormElement* form() const;
@@ -42,12 +42,10 @@ private:
// Control in the legend's fieldset that gets focus and access key.
HTMLFormControlElement* associatedControl();
- virtual void accessKeyAction(bool sendMouseEvents);
- virtual void focus(bool restorePreviousSelection, FocusDirection) OVERRIDE;
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
+ virtual void focus(bool restorePreviousSelection, FocusType) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLLegendElement, hasTagName(HTMLNames::legendTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
index eea0d9d3d27..f36b9200c18 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -25,61 +25,136 @@
#include "config.h"
#include "core/html/HTMLLinkElement.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/css/MediaList.h"
#include "core/css/MediaQueryEvaluator.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
#include "core/events/Event.h"
#include "core/events/EventSender.h"
-#include "core/dom/StyleEngine.h"
#include "core/fetch/CSSStyleSheetResource.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/html/LinkImport.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/LinkManifest.h"
+#include "core/html/imports/LinkImport.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
+#include "core/rendering/style/StyleInheritedData.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/StdLibExtras.h"
namespace WebCore {
using namespace HTMLNames;
+template <typename CharacterType>
+static void parseSizes(const CharacterType* value, unsigned length, Vector<IntSize>& iconSizes)
+{
+ enum State {
+ ParseStart,
+ ParseWidth,
+ ParseHeight
+ };
+ int width = 0;
+ unsigned start = 0;
+ unsigned i = 0;
+ State state = ParseStart;
+ bool invalid = false;
+ for (; i < length; ++i) {
+ if (state == ParseWidth) {
+ if (value[i] == 'x' || value[i] == 'X') {
+ if (i == start) {
+ invalid = true;
+ break;
+ }
+ width = charactersToInt(value + start, i - start);
+ start = i + 1;
+ state = ParseHeight;
+ } else if (value[i] < '0' || value[i] > '9') {
+ invalid = true;
+ break;
+ }
+ } else if (state == ParseHeight) {
+ if (value[i] == ' ') {
+ if (i == start) {
+ invalid = true;
+ break;
+ }
+ int height = charactersToInt(value + start, i - start);
+ iconSizes.append(IntSize(width, height));
+ start = i + 1;
+ state = ParseStart;
+ } else if (value[i] < '0' || value[i] > '9') {
+ invalid = true;
+ break;
+ }
+ } else if (state == ParseStart) {
+ if (value[i] >= '0' && value[i] <= '9') {
+ start = i;
+ state = ParseWidth;
+ } else if (value[i] != ' ') {
+ invalid = true;
+ break;
+ }
+ }
+ }
+ if (invalid || state == ParseWidth || (state == ParseHeight && start == i)) {
+ iconSizes.clear();
+ return;
+ }
+ if (state == ParseHeight && i > start) {
+ int height = charactersToInt(value + start, i - start);
+ iconSizes.append(IntSize(width, height));
+ }
+}
+
static LinkEventSender& linkLoadEventSender()
{
DEFINE_STATIC_LOCAL(LinkEventSender, sharedLoadEventSender, (EventTypeNames::load));
return sharedLoadEventSender;
}
+void HTMLLinkElement::parseSizesAttribute(const AtomicString& value, Vector<IntSize>& iconSizes)
+{
+ ASSERT(iconSizes.isEmpty());
+ if (value.isEmpty())
+ return;
+ if (value.is8Bit())
+ parseSizes(value.characters8(), value.length(), iconSizes);
+ else
+ parseSizes(value.characters16(), value.length(), iconSizes);
+}
+
inline HTMLLinkElement::HTMLLinkElement(Document& document, bool createdByParser)
: HTMLElement(linkTag, document)
, m_linkLoader(this)
, m_sizes(DOMSettableTokenList::create())
, m_createdByParser(createdByParser)
, m_isInShadowTree(false)
- , m_beforeLoadRecurseCount(0)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLLinkElement> HTMLLinkElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLLinkElement> HTMLLinkElement::create(Document& document, bool createdByParser)
{
- return adoptRef(new HTMLLinkElement(document, createdByParser));
+ return adoptRefWillBeNoop(new HTMLLinkElement(document, createdByParser));
}
HTMLLinkElement::~HTMLLinkElement()
{
+#if !ENABLE(OILPAN)
m_link.clear();
if (inDocument())
document().styleEngine()->removeStyleSheetCandidateNode(this);
+#endif
linkLoadEventSender().cancelEvent(this);
}
@@ -96,6 +171,7 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
process();
} else if (name == sizesAttr) {
m_sizes->setValue(value);
+ parseSizesAttribute(value, m_iconSizes);
process();
} else if (name == mediaAttr) {
m_media = value.string().lower();
@@ -103,9 +179,7 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
} else if (name == disabledAttr) {
if (LinkStyle* link = linkStyle())
link->setDisabledState(!value.isNull());
- } else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
- else {
+ } else {
if (name == titleAttr) {
if (LinkStyle* link = linkStyle())
link->setSheetTitle(value);
@@ -117,25 +191,12 @@ void HTMLLinkElement::parseAttribute(const QualifiedName& name, const AtomicStri
bool HTMLLinkElement::shouldLoadLink()
{
- bool continueLoad = true;
- RefPtr<Document> originalDocument(document());
- int recursionRank = ++m_beforeLoadRecurseCount;
- if (!dispatchBeforeLoadEvent(getNonEmptyURLAttribute(hrefAttr)))
- continueLoad = false;
-
- // A beforeload handler might have removed us from the document or changed the document.
- if (continueLoad && (!inDocument() || document() != originalDocument))
- continueLoad = false;
-
- // If the beforeload handler recurses into the link element by mutating it, we should only
- // let the latest (innermost) mutation occur.
- if (recursionRank != m_beforeLoadRecurseCount)
- continueLoad = false;
-
- if (recursionRank == 1)
- m_beforeLoadRecurseCount = 0;
+ return inDocument();
+}
- return continueLoad;
+bool HTMLLinkElement::loadLink(const String& type, const KURL& url)
+{
+ return m_linkLoader.loadLink(m_relAttribute, fastGetAttribute(HTMLNames::crossoriginAttr), type, url, document());
}
LinkResource* HTMLLinkElement::linkResourceToProcess()
@@ -147,11 +208,13 @@ LinkResource* HTMLLinkElement::linkResourceToProcess()
}
if (!m_link) {
- if (m_relAttribute.isImport() && RuntimeEnabledFeatures::htmlImportsEnabled())
+ if (m_relAttribute.isImport() && RuntimeEnabledFeatures::htmlImportsEnabled()) {
m_link = LinkImport::create(this);
- else {
- OwnPtr<LinkStyle> link = LinkStyle::create(this);
- if (fastHasAttribute(disabledAttr))
+ } else if (m_relAttribute.isManifest() && RuntimeEnabledFeatures::manifestEnabled()) {
+ m_link = LinkManifest::create(this);
+ } else {
+ OwnPtrWillBeRawPtr<LinkStyle> link = LinkStyle::create(this);
+ if (fastHasAttribute(disabledAttr) || m_relAttribute.isTransitionExitingStylesheet())
link->setDisabledState(true);
m_link = link.release();
}
@@ -187,6 +250,14 @@ void HTMLLinkElement::process()
link->process();
}
+void HTMLLinkElement::enableIfExitTransitionStyle()
+{
+ if (m_relAttribute.isTransitionExitingStylesheet()) {
+ if (LinkStyle* link = linkStyle())
+ link->setDisabledState(false);
+ }
+}
+
Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
@@ -200,6 +271,10 @@ Node::InsertionNotificationRequest HTMLLinkElement::insertedInto(ContainerNode*
document().styleEngine()->addStyleSheetCandidateNode(this, m_createdByParser);
process();
+
+ if (m_link)
+ m_link->ownerInserted();
+
return InsertionDone;
}
@@ -217,7 +292,7 @@ void HTMLLinkElement::removedFrom(ContainerNode* insertionPoint)
}
document().styleEngine()->removeStyleSheetCandidateNode(this);
- RefPtr<StyleSheet> removedSheet = sheet();
+ RefPtrWillBeRawPtr<StyleSheet> removedSheet = sheet();
if (m_link)
m_link->ownerRemoved();
@@ -309,6 +384,22 @@ bool HTMLLinkElement::isURLAttribute(const Attribute& attribute) const
return attribute.name().localName() == hrefAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLLinkElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == hrefAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLLinkElement::subResourceAttributeName() const
+{
+ // If the link element is not css, ignore it.
+ if (equalIgnoringCase(getAttribute(typeAttr), "text/css")) {
+ // FIXME: Add support for extracting links of sub-resources which
+ // are inside style-sheet such as @import, @font-face, url(), etc.
+ return hrefAttr;
+ }
+ return HTMLElement::subResourceAttributeName();
+}
+
KURL HTMLLinkElement::href() const
{
return document().completeURL(getAttribute(hrefAttr));
@@ -319,14 +410,14 @@ const AtomicString& HTMLLinkElement::rel() const
return getAttribute(relAttr);
}
-String HTMLLinkElement::target() const
+const AtomicString& HTMLLinkElement::type() const
{
- return getAttribute(targetAttr);
+ return getAttribute(typeAttr);
}
-const AtomicString& HTMLLinkElement::type() const
+bool HTMLLinkElement::async() const
{
- return getAttribute(typeAttr);
+ return fastHasAttribute(HTMLNames::asyncAttr);
}
IconType HTMLLinkElement::iconType() const
@@ -334,38 +425,26 @@ IconType HTMLLinkElement::iconType() const
return m_relAttribute.iconType();
}
-String HTMLLinkElement::iconSizes() const
+const Vector<IntSize>& HTMLLinkElement::iconSizes() const
{
- return m_sizes->toString();
+ return m_iconSizes;
}
-void HTMLLinkElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+DOMSettableTokenList* HTMLLinkElement::sizes() const
{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- // Favicons are handled by a special case in LegacyWebArchive::create()
- if (m_relAttribute.iconType() != InvalidIcon)
- return;
-
- if (!m_relAttribute.isStyleSheet())
- return;
-
- // Append the URL of this link element.
- addSubresourceURL(urls, href());
-
- // Walk the URLs linked by the linked-to stylesheet.
- if (CSSStyleSheet* styleSheet = const_cast<HTMLLinkElement*>(this)->sheet())
- styleSheet->contents()->addSubresourceStyleURLs(urls);
+ return m_sizes.get();
}
-DOMSettableTokenList* HTMLLinkElement::sizes() const
+void HTMLLinkElement::trace(Visitor* visitor)
{
- return m_sizes.get();
+ visitor->trace(m_link);
+ visitor->trace(m_sizes);
+ HTMLElement::trace(visitor);
}
-PassOwnPtr<LinkStyle> LinkStyle::create(HTMLLinkElement* owner)
+PassOwnPtrWillBeRawPtr<LinkStyle> LinkStyle::create(HTMLLinkElement* owner)
{
- return adoptPtr(new LinkStyle(owner));
+ return adoptPtrWillBeNoop(new LinkStyle(owner));
}
LinkStyle::LinkStyle(HTMLLinkElement* owner)
@@ -380,8 +459,10 @@ LinkStyle::LinkStyle(HTMLLinkElement* owner)
LinkStyle::~LinkStyle()
{
+#if !ENABLE(OILPAN)
if (m_sheet)
m_sheet->clearOwnerNode();
+#endif
}
Document& LinkStyle::document()
@@ -397,11 +478,11 @@ void LinkStyle::setCSSStyleSheet(const String& href, const KURL& baseURL, const
}
// Completing the sheet load may cause scripts to execute.
- RefPtr<Node> protector(m_owner);
+ RefPtrWillBeRawPtr<Node> protector(m_owner.get());
- CSSParserContext parserContext(m_owner->document(), baseURL, charset);
+ CSSParserContext parserContext(m_owner->document(), 0, baseURL, charset);
- if (RefPtr<StyleSheetContents> restoredSheet = const_cast<CSSStyleSheetResource*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) {
+ if (RefPtrWillBeRawPtr<StyleSheetContents> restoredSheet = const_cast<CSSStyleSheetResource*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) {
ASSERT(restoredSheet->isCacheable());
ASSERT(!restoredSheet->isLoading());
@@ -412,12 +493,11 @@ void LinkStyle::setCSSStyleSheet(const String& href, const KURL& baseURL, const
m_sheet->setTitle(m_owner->title());
m_loading = false;
- sheetLoaded();
- notifyLoadedSheetAndAllCriticalSubresources(false);
+ restoredSheet->checkLoaded();
return;
}
- RefPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(href, parserContext);
+ RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(href, parserContext);
if (m_sheet)
clearSheet();
@@ -465,7 +545,7 @@ void LinkStyle::clearSheet()
ASSERT(m_sheet);
ASSERT(m_sheet->ownerNode() == m_owner);
m_sheet->clearOwnerNode();
- m_sheet = 0;
+ m_sheet = nullptr;
}
bool LinkStyle::styleSheetIsLoading() const
@@ -488,7 +568,7 @@ void LinkStyle::addPendingSheet(PendingSheetType type)
m_owner->document().styleEngine()->addPendingSheet();
}
-void LinkStyle::removePendingSheet(RemovePendingSheetNotificationType notification)
+void LinkStyle::removePendingSheet()
{
PendingSheetType type = m_pendingSheetType;
m_pendingSheetType = None;
@@ -501,14 +581,11 @@ void LinkStyle::removePendingSheet(RemovePendingSheetNotificationType notificati
// Document::removePendingSheet() triggers the style selector recalc for blocking sheets.
// FIXME: We don't have enough knowledge at this point to know if we're adding or removing a sheet
// so we can't call addedStyleSheet() or removedStyleSheet().
- m_owner->document().styleResolverChanged(RecalcStyleImmediately);
+ m_owner->document().styleResolverChanged();
return;
}
- m_owner->document().styleEngine()->removePendingSheet(m_owner,
- notification == RemovePendingSheetNotifyImmediately
- ? StyleEngine::RemovePendingSheetNotifyImmediately
- : StyleEngine::RemovePendingSheetNotifyLater);
+ m_owner->document().styleEngine()->removePendingSheet(m_owner);
}
void LinkStyle::setDisabledState(bool disabled)
@@ -548,7 +625,7 @@ void LinkStyle::setDisabledState(bool disabled)
process();
} else {
// FIXME: We don't have enough knowledge here to know if we should call addedStyleSheet() or removedStyleSheet().
- m_owner->document().styleResolverChanged(RecalcStyleDeferred);
+ m_owner->document().styleResolverChanged();
}
}
}
@@ -566,14 +643,14 @@ void LinkStyle::process()
return;
if (!document().contentSecurityPolicy()->allowImageFromSource(builder.url()))
return;
- if (document().frame())
+ if (document().frame() && document().frame()->loader().client())
document().frame()->loader().client()->dispatchDidChangeIcons(m_owner->relAttribute().iconType());
}
if (!m_owner->loadLink(type, builder.url()))
return;
- if ((m_disabledState != Disabled) && m_owner->relAttribute().isStyleSheet()
+ if ((m_disabledState != Disabled) && (m_owner->relAttribute().isStyleSheet() || m_owner->relAttribute().isTransitionExitingStylesheet())
&& shouldLoadResource() && builder.url().isValid()) {
if (resource()) {
@@ -584,15 +661,17 @@ void LinkStyle::process()
if (!m_owner->shouldLoadLink())
return;
- Frame* frame = loadingFrame();
m_loading = true;
bool mediaQueryMatches = true;
if (!m_owner->media().isEmpty()) {
- RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(document());
- RefPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
- MediaQueryEvaluator evaluator(frame->view()->mediaType(), frame, documentStyle.get());
- mediaQueryMatches = evaluator.eval(media.get());
+ LocalFrame* frame = loadingFrame();
+ if (Document* document = loadingFrame()->document()) {
+ RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*document);
+ RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
+ MediaQueryEvaluator evaluator(frame->view()->mediaType(), frame);
+ mediaQueryMatches = evaluator.eval(media.get());
+ }
}
// Don't hold up render tree construction and script execution on stylesheets
@@ -602,6 +681,9 @@ void LinkStyle::process()
// Load stylesheets that are not needed for the rendering immediately with low priority.
FetchRequest request = builder.build(blocking);
+ AtomicString crossOriginMode = m_owner->fastGetAttribute(HTMLNames::crossoriginAttr);
+ if (!crossOriginMode.isNull())
+ request.setCrossOriginAccessControl(document().securityOrigin(), crossOriginMode);
setResource(document().fetcher()->fetchCSSStyleSheet(request));
if (!resource()) {
@@ -611,7 +693,7 @@ void LinkStyle::process()
}
} else if (m_sheet) {
// we no longer contain a stylesheet, e.g. perhaps rel or type was changed
- RefPtr<StyleSheet> removedSheet = m_sheet;
+ RefPtrWillBeRawPtr<StyleSheet> removedSheet = m_sheet.get();
clearSheet();
document().removedStyleSheet(removedSheet.get());
}
@@ -629,7 +711,13 @@ void LinkStyle::ownerRemoved()
clearSheet();
if (styleSheetIsLoading())
- removePendingSheet(RemovePendingSheetNotifyLater);
+ removePendingSheet();
+}
+
+void LinkStyle::trace(Visitor* visitor)
+{
+ visitor->trace(m_sheet);
+ LinkResource::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h
index 28b01dff582..e9ac4431e35 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.h
@@ -56,9 +56,9 @@ typedef EventSender<HTMLLinkElement> LinkEventSender;
// sticking current way so far.
//
class LinkStyle FINAL : public LinkResource, ResourceOwner<StyleSheetResource> {
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<LinkStyle> create(HTMLLinkElement* owner);
+ static PassOwnPtrWillBeRawPtr<LinkStyle> create(HTMLLinkElement* owner);
explicit LinkStyle(HTMLLinkElement* owner);
virtual ~LinkStyle();
@@ -67,6 +67,7 @@ public:
virtual void process() OVERRIDE;
virtual void ownerRemoved() OVERRIDE;
virtual bool hasLoaded() const OVERRIDE { return m_loadedSheet; }
+ virtual void trace(Visitor*) OVERRIDE;
void startLoadingDynamicSheet();
void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred);
@@ -84,7 +85,7 @@ public:
CSSStyleSheet* sheet() const { return m_sheet.get(); }
private:
- // From ResourceClient
+ // From StyleSheetResourceClient
virtual void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*) OVERRIDE;
enum DisabledState {
@@ -99,17 +100,12 @@ private:
Blocking
};
- enum RemovePendingSheetNotificationType {
- RemovePendingSheetNotifyImmediately,
- RemovePendingSheetNotifyLater
- };
-
void clearSheet();
void addPendingSheet(PendingSheetType);
- void removePendingSheet(RemovePendingSheetNotificationType = RemovePendingSheetNotifyImmediately);
+ void removePendingSheet();
Document& document();
- RefPtr<CSSStyleSheet> m_sheet;
+ RefPtrWillBeMember<CSSStyleSheet> m_sheet;
DisabledState m_disabledState;
PendingSheetType m_pendingSheetType;
bool m_loading;
@@ -120,7 +116,7 @@ private:
class HTMLLinkElement FINAL : public HTMLElement, public LinkLoaderClient {
public:
- static PassRefPtr<HTMLLinkElement> create(Document&, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLLinkElement> create(Document&, bool createdByParser);
virtual ~HTMLLinkElement();
KURL href() const;
@@ -129,35 +125,46 @@ public:
String typeValue() const { return m_type; }
const LinkRelAttribute& relAttribute() const { return m_relAttribute; }
- virtual String target() const;
-
const AtomicString& type() const;
IconType iconType() const;
- // the icon size string as parsed from the HTML attribute
- String iconSizes() const;
+ // the icon sizes as parsed from the HTML attribute
+ const Vector<IntSize>& iconSizes() const;
+
+ bool async() const;
CSSStyleSheet* sheet() const { return linkStyle() ? linkStyle()->sheet() : 0; }
Document* import() const;
bool styleSheetIsLoading() const;
+ bool isImport() const { return linkImport(); }
bool isDisabled() const { return linkStyle() && linkStyle()->isDisabled(); }
bool isEnabledViaScript() const { return linkStyle() && linkStyle()->isEnabledViaScript(); }
+ void enableIfExitTransitionStyle();
+
DOMSettableTokenList* sizes() const;
void dispatchPendingEvent(LinkEventSender*);
void scheduleEvent();
+ void dispatchEventImmediately();
static void dispatchPendingLoadEvents();
// From LinkLoaderClient
virtual bool shouldLoadLink() OVERRIDE;
// For LinkStyle
- bool loadLink(const String& type, const KURL& url) { return m_linkLoader.loadLink(m_relAttribute, type, url, document()); }
+ bool loadLink(const String& type, const KURL&);
bool isAlternate() const { return linkStyle()->isUnset() && m_relAttribute.isAlternate(); }
bool shouldProcessStyle() { return linkResourceToProcess() && linkStyle(); }
+ bool isCreatedByParser() const { return m_createdByParser; }
+
+ // Parse the icon size attribute into |iconSizes|, make this method public
+ // visible for testing purpose.
+ static void parseSizesAttribute(const AtomicString& value, Vector<IntSize>& iconSizes);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
@@ -173,11 +180,12 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
virtual bool sheetLoaded() OVERRIDE;
virtual void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred) OVERRIDE;
virtual void startLoadingDynamicSheet() OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const OVERRIDE;
- virtual void finishParsingChildren();
+ virtual void finishParsingChildren() OVERRIDE;
// From LinkLoaderClient
virtual void linkLoaded() OVERRIDE;
@@ -190,21 +198,19 @@ private:
private:
HTMLLinkElement(Document&, bool createdByParser);
- OwnPtr<LinkResource> m_link;
+ OwnPtrWillBeMember<LinkResource> m_link;
LinkLoader m_linkLoader;
String m_type;
String m_media;
- RefPtr<DOMSettableTokenList> m_sizes;
+ RefPtrWillBeMember<DOMSettableTokenList> m_sizes;
+ Vector<IntSize> m_iconSizes;
LinkRelAttribute m_relAttribute;
bool m_createdByParser;
bool m_isInShadowTree;
- int m_beforeLoadRecurseCount;
};
-DEFINE_NODE_TYPE_CASTS(HTMLLinkElement, hasTagName(HTMLNames::linkTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl
index 73c2426ce04..3ba1aff4c50 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElement.idl
@@ -22,7 +22,8 @@
interface HTMLLinkElement : HTMLElement {
[Reflect] attribute boolean disabled;
[Reflect] attribute DOMString charset;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString href;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString href;
+ [Reflect, ReflectOnly="anonymous"|"use-credentials", ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString crossOrigin;
[Reflect] attribute DOMString hreflang;
[Reflect] attribute DOMString media;
[Reflect] attribute DOMString rel;
@@ -35,4 +36,6 @@ interface HTMLLinkElement : HTMLElement {
readonly attribute StyleSheet sheet;
[RuntimeEnabled=HTMLImports] readonly attribute Document import;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLLinkElementSizesAttributeTest.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElementSizesAttributeTest.cpp
new file mode 100644
index 00000000000..62cce281a90
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLLinkElementSizesAttributeTest.cpp
@@ -0,0 +1,77 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLLinkElement.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class HTMLLinkElementSizesAttributeTest : public testing::Test {
+};
+
+TEST(HTMLLinkElementSizesAttributeTest, parseSizes)
+{
+ AtomicString sizesAttribute = "32x33";
+ Vector<IntSize> sizes;
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(1U, sizes.size());
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
+
+ UChar attribute[] = {'3', '2', 'x', '3', '3', 0};
+ sizesAttribute = attribute;
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(1U, sizes.size());
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
+
+
+ sizesAttribute = " 32x33 16X17 128x129 ";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(3U, sizes.size());
+ EXPECT_EQ(32, sizes[0].width());
+ EXPECT_EQ(33, sizes[0].height());
+ EXPECT_EQ(16, sizes[1].width());
+ EXPECT_EQ(17, sizes[1].height());
+ EXPECT_EQ(128, sizes[2].width());
+ EXPECT_EQ(129, sizes[2].height());
+
+ sizesAttribute = "any";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33 32";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33 32x";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33 x32";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33 any";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+
+ sizesAttribute = "32x33, 64x64";
+ sizes.clear();
+ HTMLLinkElement::parseSizesAttribute(sizesAttribute, sizes);
+ ASSERT_EQ(0U, sizes.size());
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp
index d1f055a2fc6..27a525c1b33 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "core/html/HTMLMapElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLAreaElement.h"
@@ -30,22 +30,17 @@
#include "core/html/HTMLImageElement.h"
#include "core/rendering/HitTestResult.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
-HTMLMapElement::HTMLMapElement(Document& document)
+inline HTMLMapElement::HTMLMapElement(Document& document)
: HTMLElement(mapTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLMapElement> HTMLMapElement::create(Document& document)
-{
- return adoptRef(new HTMLMapElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLMapElement)
HTMLMapElement::~HTMLMapElement()
{
@@ -54,15 +49,12 @@ HTMLMapElement::~HTMLMapElement()
bool HTMLMapElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size, HitTestResult& result)
{
HTMLAreaElement* defaultArea = 0;
- Element* element = this;
- while ((element = ElementTraversal::next(*element, this))) {
- if (isHTMLAreaElement(element)) {
- HTMLAreaElement* areaElt = toHTMLAreaElement(element);
- if (areaElt->isDefault()) {
- if (!defaultArea)
- defaultArea = areaElt;
- } else if (areaElt->mapMouseEvent(location, size, result))
- return true;
+ for (HTMLAreaElement* area = Traversal<HTMLAreaElement>::firstWithin(*this); area; area = Traversal<HTMLAreaElement>::next(*area, this)) {
+ if (area->isDefault()) {
+ if (!defaultArea)
+ defaultArea = area;
+ } else if (area->mapMouseEvent(location, size, result)) {
+ return true;
}
}
@@ -75,17 +67,16 @@ bool HTMLMapElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size,
HTMLImageElement* HTMLMapElement::imageElement()
{
- RefPtr<HTMLCollection> images = document().images();
- for (unsigned i = 0; Node* curr = images->item(i); i++) {
- if (!curr->hasTagName(imgTag))
- continue;
+ RefPtrWillBeRawPtr<HTMLCollection> images = document().images();
+ for (unsigned i = 0; Element* curr = images->item(i); ++i) {
+ ASSERT(isHTMLImageElement(curr));
// The HTMLImageElement's useMap() value includes the '#' symbol at the beginning,
// which has to be stripped off.
- HTMLImageElement* imageElement = toHTMLImageElement(curr);
- String useMapName = imageElement->getAttribute(usemapAttr).string().substring(1);
+ HTMLImageElement& imageElement = toHTMLImageElement(*curr);
+ String useMapName = imageElement.getAttribute(usemapAttr).string().substring(1);
if (equalIgnoringCase(useMapName, m_name))
- return imageElement;
+ return &imageElement;
}
return 0;
@@ -108,7 +99,7 @@ void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicStrin
String mapName = value;
if (mapName[0] == '#')
mapName = mapName.substring(1);
- m_name = document().isHTMLDocument() ? mapName.lower() : mapName;
+ m_name = AtomicString(document().isHTMLDocument() ? mapName.lower() : mapName);
if (inDocument())
treeScope().addImageMap(this);
@@ -118,7 +109,7 @@ void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicStrin
HTMLElement::parseAttribute(name, value);
}
-PassRefPtr<HTMLCollection> HTMLMapElement::areas()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLMapElement::areas()
{
return ensureCachedHTMLCollection(MapAreas);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h
index cdd5c7654a8..36ca426bc0b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMapElement.h
@@ -32,7 +32,7 @@ class HTMLImageElement;
class HTMLMapElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLMapElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLMapElement);
virtual ~HTMLMapElement();
const AtomicString& getName() const { return m_name; }
@@ -40,7 +40,7 @@ public:
bool mapMouseEvent(LayoutPoint location, const LayoutSize&, HitTestResult&);
HTMLImageElement* imageElement();
- PassRefPtr<HTMLCollection> areas();
+ PassRefPtrWillBeRawPtr<HTMLCollection> areas();
private:
explicit HTMLMapElement(Document&);
@@ -53,8 +53,6 @@ private:
AtomicString m_name;
};
-DEFINE_NODE_TYPE_CASTS(HTMLMapElement, hasTagName(HTMLNames::mapTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp
index 882cb06c454..491755fbf41 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.cpp
@@ -23,10 +23,10 @@
#include "config.h"
#include "core/html/HTMLMarqueeElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/rendering/RenderMarquee.h"
@@ -41,9 +41,9 @@ inline HTMLMarqueeElement::HTMLMarqueeElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLMarqueeElement> HTMLMarqueeElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLMarqueeElement> HTMLMarqueeElement::create(Document& document)
{
- RefPtr<HTMLMarqueeElement> marqueeElement(adoptRef(new HTMLMarqueeElement(document)));
+ RefPtrWillBeRawPtr<HTMLMarqueeElement> marqueeElement(adoptRefWillBeNoop(new HTMLMarqueeElement(document)));
marqueeElement->suspendIfNeeded();
return marqueeElement.release();
}
@@ -57,6 +57,12 @@ int HTMLMarqueeElement::minimumDelay() const
return 0;
}
+void HTMLMarqueeElement::didMoveToNewDocument(Document& oldDocument)
+{
+ ActiveDOMObject::didMoveToNewExecutionContext(&document());
+ HTMLElement::didMoveToNewDocument(oldDocument);
+}
+
bool HTMLMarqueeElement::isPresentationAttribute(const QualifiedName& name) const
{
if (name == widthAttr || name == heightAttr || name == bgcolorAttr || name == vspaceAttr || name == hspaceAttr || name == scrollamountAttr || name == scrolldelayAttr || name == loopAttr || name == behaviorAttr || name == directionAttr)
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h
index 90add468471..129ed22392d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMarqueeElement.h
@@ -25,6 +25,7 @@
#include "core/dom/ActiveDOMObject.h"
#include "core/html/HTMLElement.h"
+#include "platform/Timer.h"
namespace WebCore {
@@ -33,14 +34,14 @@ class RenderMarquee;
class HTMLMarqueeElement FINAL : public HTMLElement, private ActiveDOMObject {
public:
- static PassRefPtr<HTMLMarqueeElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLMarqueeElement> create(Document&);
int minimumDelay() const;
// DOM Functions
void start();
- void stop();
+ virtual void stop() OVERRIDE;
int scrollAmount() const;
void setScrollAmount(int, ExceptionState&);
@@ -56,20 +57,20 @@ public:
private:
explicit HTMLMarqueeElement(Document&);
+ virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
+
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
// ActiveDOMObject
- virtual void suspend();
- virtual void resume();
+ virtual void suspend() OVERRIDE;
+ virtual void resume() OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE FINAL;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
RenderMarquee* renderMarquee() const;
};
-DEFINE_NODE_TYPE_CASTS(HTMLMarqueeElement, hasTagName(HTMLNames::marqueeTag));
-
} // namespace WebCore
#endif // HTMLMarqueeElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
index c43d49009f1..ed492e58133 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -27,55 +27,52 @@
#include "core/html/HTMLMediaElement.h"
#include <limits>
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/css/MediaList.h"
-#include "core/css/MediaQueryEvaluator.h"
#include "core/dom/Attribute.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLMediaSource.h"
#include "core/html/HTMLSourceElement.h"
#include "core/html/HTMLTrackElement.h"
#include "core/html/MediaController.h"
#include "core/html/MediaError.h"
#include "core/html/MediaFragmentURIParser.h"
-#include "core/html/MediaKeyError.h"
-#include "core/html/MediaKeyEvent.h"
#include "core/html/TimeRanges.h"
#include "core/html/shadow/MediaControls.h"
+#include "core/html/track/AudioTrack.h"
+#include "core/html/track/AudioTrackList.h"
#include "core/html/track/InbandTextTrack.h"
#include "core/html/track/TextTrackCueList.h"
#include "core/html/track/TextTrackList.h"
+#include "core/html/track/VideoTrack.h"
+#include "core/html/track/VideoTrackList.h"
#include "core/loader/FrameLoader.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderVideo.h"
#include "core/rendering/RenderView.h"
-// FIXME: Remove dependency on modules/encryptedmedia (http://crbug.com/242754).
-#include "modules/encryptedmedia/MediaKeyNeededEvent.h"
-#include "modules/encryptedmedia/MediaKeys.h"
-#include "modules/mediastream/MediaStreamRegistry.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/ContentType.h"
#include "platform/Language.h"
#include "platform/Logging.h"
#include "platform/MIMETypeFromURL.h"
#include "platform/MIMETypeRegistry.h"
#include "platform/NotImplemented.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/UserGestureIndicator.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebContentDecryptionModule.h"
#include "public/platform/WebInbandTextTrack.h"
#include "wtf/CurrentTime.h"
#include "wtf/MathExtras.h"
@@ -85,12 +82,13 @@
#if ENABLE(WEB_AUDIO)
#include "platform/audio/AudioSourceProvider.h"
-#include "modules/webaudio/MediaElementAudioSourceNode.h"
+#include "platform/audio/AudioSourceProviderClient.h"
#endif
-using namespace std;
using blink::WebInbandTextTrack;
+using blink::WebMediaPlayer;
using blink::WebMimeRegistry;
+using blink::WebMediaPlayerClient;
namespace WebCore {
@@ -126,19 +124,19 @@ static const char* boolString(bool val)
static const char mediaSourceBlobProtocol[] = "blob";
using namespace HTMLNames;
-using namespace std;
-typedef HashMap<Document*, HashSet<HTMLMediaElement*> > DocumentElementSetMap;
+typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<HTMLMediaElement> > WeakMediaElementSet;
+typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<Document>, WeakMediaElementSet> DocumentElementSetMap;
static DocumentElementSetMap& documentToElementSetMap()
{
- DEFINE_STATIC_LOCAL(DocumentElementSetMap, map, ());
- return map;
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<DocumentElementSetMap>, map, (adoptPtrWillBeNoop(new DocumentElementSetMap())));
+ return *map;
}
static void addElementToDocumentMap(HTMLMediaElement* element, Document* document)
{
DocumentElementSetMap& map = documentToElementSetMap();
- HashSet<HTMLMediaElement*> set = map.take(document);
+ WeakMediaElementSet set = map.take(document);
set.add(element);
map.add(document, set);
}
@@ -146,33 +144,14 @@ static void addElementToDocumentMap(HTMLMediaElement* element, Document* documen
static void removeElementFromDocumentMap(HTMLMediaElement* element, Document* document)
{
DocumentElementSetMap& map = documentToElementSetMap();
- HashSet<HTMLMediaElement*> set = map.take(document);
+ WeakMediaElementSet set = map.take(document);
set.remove(element);
if (!set.isEmpty())
map.add(document, set);
}
-static void throwExceptionForMediaKeyException(MediaPlayer::MediaKeyException exception, ExceptionState& exceptionState)
-{
- switch (exception) {
- case MediaPlayer::NoError:
- return;
- case MediaPlayer::InvalidPlayerState:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- case MediaPlayer::KeySystemNotSupported:
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- case MediaPlayer::InvalidAccess:
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return;
- }
-
- ASSERT_NOT_REACHED();
- return;
-}
-
class TrackDisplayUpdateScope {
+ STACK_ALLOCATED();
public:
TrackDisplayUpdateScope(HTMLMediaElement* mediaElement)
{
@@ -186,9 +165,55 @@ public:
}
private:
- HTMLMediaElement* m_mediaElement;
+ RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
};
+static const AtomicString& AudioKindToString(WebMediaPlayerClient::AudioTrackKind kind)
+{
+ switch (kind) {
+ case WebMediaPlayerClient::AudioTrackKindNone:
+ return emptyAtom;
+ case WebMediaPlayerClient::AudioTrackKindAlternative:
+ return AudioTrack::alternativeKeyword();
+ case WebMediaPlayerClient::AudioTrackKindDescriptions:
+ return AudioTrack::descriptionsKeyword();
+ case WebMediaPlayerClient::AudioTrackKindMain:
+ return AudioTrack::mainKeyword();
+ case WebMediaPlayerClient::AudioTrackKindMainDescriptions:
+ return AudioTrack::mainDescriptionsKeyword();
+ case WebMediaPlayerClient::AudioTrackKindTranslation:
+ return AudioTrack::translationKeyword();
+ case WebMediaPlayerClient::AudioTrackKindCommentary:
+ return AudioTrack::commentaryKeyword();
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+}
+
+static const AtomicString& VideoKindToString(WebMediaPlayerClient::VideoTrackKind kind)
+{
+ switch (kind) {
+ case WebMediaPlayerClient::VideoTrackKindNone:
+ return emptyAtom;
+ case WebMediaPlayerClient::VideoTrackKindAlternative:
+ return VideoTrack::alternativeKeyword();
+ case WebMediaPlayerClient::VideoTrackKindCaptions:
+ return VideoTrack::captionsKeyword();
+ case WebMediaPlayerClient::VideoTrackKindMain:
+ return VideoTrack::mainKeyword();
+ case WebMediaPlayerClient::VideoTrackKindSign:
+ return VideoTrack::signKeyword();
+ case WebMediaPlayerClient::VideoTrackKindSubtitles:
+ return VideoTrack::subtitlesKeyword();
+ case WebMediaPlayerClient::VideoTrackKindCommentary:
+ return VideoTrack::commentaryKeyword();
+ }
+
+ ASSERT_NOT_REACHED();
+ return emptyAtom;
+}
+
static bool canLoadURL(const KURL& url, const ContentType& contentType, const String& keySystem)
{
DEFINE_STATIC_LOCAL(const String, codecs, ("codecs"));
@@ -241,12 +266,26 @@ WebMimeRegistry::SupportsType HTMLMediaElement::supportsType(const ContentType&
return blink::Platform::current()->mimeRegistry()->supportsMediaMIMEType(type, typeCodecs, system);
}
-HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document, bool createdByParser)
+URLRegistry* HTMLMediaElement::s_mediaStreamRegistry = 0;
+
+void HTMLMediaElement::setMediaStreamRegistry(URLRegistry* registry)
+{
+ ASSERT(!s_mediaStreamRegistry);
+ s_mediaStreamRegistry = registry;
+}
+
+bool HTMLMediaElement::isMediaStreamURL(const String& url)
+{
+ return s_mediaStreamRegistry ? s_mediaStreamRegistry->contains(url) : false;
+}
+
+HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& document)
: HTMLElement(tagName, document)
, ActiveDOMObject(&document)
, m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
, m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
+ , m_audioTracksTimer(this, &HTMLMediaElement::audioTracksTimerFired)
, m_playedTimeRanges()
, m_asyncEventQueue(GenericEventQueue::create(this))
, m_playbackRate(1.0f)
@@ -256,14 +295,14 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
, m_readyStateMaximum(HAVE_NOTHING)
, m_volume(1.0f)
, m_lastSeekTime(0)
- , m_previousProgressTime(numeric_limits<double>::max())
- , m_duration(numeric_limits<double>::quiet_NaN())
+ , m_previousProgressTime(std::numeric_limits<double>::max())
+ , m_duration(std::numeric_limits<double>::quiet_NaN())
, m_lastTimeUpdateEventWallTime(0)
- , m_lastTimeUpdateEventMovieTime(numeric_limits<double>::max())
+ , m_lastTimeUpdateEventMovieTime(std::numeric_limits<double>::max())
, m_loadState(WaitingForSource)
+ , m_deferredLoadState(NotDeferred)
+ , m_deferredLoadTimer(this, &HTMLMediaElement::deferredLoadTimerFired)
, m_webLayer(0)
- , m_opaque(false)
- , m_restrictions(RequirePageConsentToLoadMediaRestriction)
, m_preload(MediaPlayer::Auto)
, m_displayMode(Unknown)
, m_cachedTime(MediaPlayer::invalidTime())
@@ -272,6 +311,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
, m_fragmentStartTime(MediaPlayer::invalidTime())
, m_fragmentEndTime(MediaPlayer::invalidTime())
, m_pendingActionFlags(0)
+ , m_userGestureRequiredForPlay(false)
, m_playing(false)
, m_shouldDelayLoadEvent(false)
, m_haveFiredLoadedData(false)
@@ -284,18 +324,21 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
, m_sentEndEvent(false)
, m_pausedInternal(false)
, m_closedCaptionsVisible(false)
- , m_loadInitiatedByUserGesture(false)
, m_completelyLoaded(false)
, m_havePreparedToPlay(false)
- , m_parsingInProgress(createdByParser)
, m_tracksAreReady(true)
, m_haveVisibleTextTrack(false)
, m_processingPreferenceChange(false)
+#if ENABLE(OILPAN)
+ , m_isFinalizing(false)
+#endif
, m_lastTextTrackUpdateTime(-1)
- , m_textTracks(0)
+ , m_audioTracks(AudioTrackList::create(*this))
+ , m_videoTracks(VideoTrackList::create(*this))
+ , m_textTracks(nullptr)
, m_ignoreTrackDisplayUpdate(0)
#if ENABLE(WEB_AUDIO)
- , m_audioSourceNode(0)
+ , m_audioSourceNode(nullptr)
#endif
{
ASSERT(RuntimeEnabledFeatures::mediaEnabled());
@@ -303,45 +346,54 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document& docum
WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement");
ScriptWrappable::init(this);
- if (document.settings()) {
- if (document.settings()->mediaPlaybackRequiresUserGesture()) {
- addBehaviorRestriction(RequireUserGestureForRateChangeRestriction);
- addBehaviorRestriction(RequireUserGestureForLoadRestriction);
- }
- if (document.settings()->mediaFullscreenRequiresUserGesture()) {
- addBehaviorRestriction(RequireUserGestureForFullscreenRestriction);
- }
- }
+ if (document.settings() && document.settings()->mediaPlaybackRequiresUserGesture())
+ m_userGestureRequiredForPlay = true;
setHasCustomStyleCallbacks();
addElementToDocumentMap(this, &document);
-
}
HTMLMediaElement::~HTMLMediaElement()
{
WTF_LOG(Media, "HTMLMediaElement::~HTMLMediaElement");
+#if ENABLE(OILPAN)
+ // If the HTMLMediaElement dies with the document we are not
+ // allowed to touch the document to adjust delay load event counts
+ // because the document could have been already
+ // destructed. However, if the HTMLMediaElement dies with the
+ // document there is no need to change the delayed load counts
+ // because no load event will fire anyway. If the document is
+ // still alive we do have to decrement the load delay counts. We
+ // determine if the document is alive via the ActiveDOMObject
+ // which is a context lifecycle observer. If the Document has been
+ // destructed ActiveDOMObject::executionContext() returns 0.
+ if (ActiveDOMObject::executionContext())
+ setShouldDelayLoadEvent(false);
+#else
+ // HTMLMediaElement and m_asyncEventQueue always become unreachable
+ // together. So HTMLMediaElemenet and m_asyncEventQueue are destructed in
+ // the same GC. We don't need to close it explicitly in Oilpan.
m_asyncEventQueue->close();
setShouldDelayLoadEvent(false);
+
if (m_textTracks)
m_textTracks->clearOwner();
- if (m_textTracks) {
- for (unsigned i = 0; i < m_textTracks->length(); ++i)
- m_textTracks->item(i)->clearClient();
- }
+ m_audioTracks->shutdown();
+ m_videoTracks->shutdown();
if (m_mediaController) {
m_mediaController->removeMediaElement(this);
- m_mediaController = 0;
+ m_mediaController = nullptr;
}
+#endif
closeMediaSource();
- setMediaKeys(0);
-
+#if !ENABLE(OILPAN)
removeElementFromDocumentMap(this, &document());
+#endif
// Destroying the player may cause a resource load to be canceled,
// which could result in userCancelledLoad() being called back.
@@ -350,6 +402,10 @@ HTMLMediaElement::~HTMLMediaElement()
// See http://crbug.com/233654 for more details.
m_completelyLoaded = true;
+ // With Oilpan load events on the Document are always delayed during
+ // sweeping so we don't need to explicitly increment and decrement
+ // load event delay counts.
+#if !ENABLE(OILPAN)
// Destroying the player may cause a resource load to be canceled,
// which could result in Document::dispatchWindowLoadEvent() being
// called via ResourceFetch::didLoadResource() then
@@ -357,10 +413,33 @@ HTMLMediaElement::~HTMLMediaElement()
// object destruction, we use Document::incrementLoadEventDelayCount().
// See http://crbug.com/275223 for more details.
document().incrementLoadEventDelayCount();
+#endif
+
+#if ENABLE(OILPAN)
+ // Oilpan: the player must be released, but the player object
+ // cannot safely access this player client any longer as parts of
+ // it may have been finalized already (like the media element's
+ // supplementable table.) Handled for now by entering an
+ // is-finalizing state, which is explicitly checked for if the
+ // player tries to access the media element during shutdown.
+ //
+ // FIXME: Oilpan: move the media player to the heap instead and
+ // avoid having to finalize it from here; this whole #if block
+ // could then be removed (along with the state bit it depends on.)
+ // crbug.com/378229
+ m_isFinalizing = true;
+#endif
- clearMediaPlayerAndAudioSourceProviderClient();
+ // The m_audioSourceNode is either dead already or it is dying together with
+ // this HTMLMediaElement which it strongly keeps alive.
+#if ENABLE(WEB_AUDIO) && !ENABLE(OILPAN)
+ ASSERT(!m_audioSourceNode);
+#endif
+ clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
+#if !ENABLE(OILPAN)
document().decrementLoadEventDelayCount();
+#endif
}
void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
@@ -382,9 +461,9 @@ void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
addElementToDocumentMap(this, &document());
// FIXME: This is a temporary fix to prevent this object from causing the
- // MediaPlayer to dereference Frame and FrameLoader pointers from the
+ // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the
// previous document. A proper fix would provide a mechanism to allow this
- // object to refresh the MediaPlayer's Frame and FrameLoader references on
+ // object to refresh the MediaPlayer's LocalFrame and FrameLoader references on
// document changes so that playback can be resumed properly.
userCancelledLoad();
@@ -392,14 +471,10 @@ void HTMLMediaElement::didMoveToNewDocument(Document& oldDocument)
// and there is no risk of dispatching a load event from within the destructor.
oldDocument.decrementLoadEventDelayCount();
+ ActiveDOMObject::didMoveToNewExecutionContext(&document());
HTMLElement::didMoveToNewDocument(oldDocument);
}
-bool HTMLMediaElement::hasCustomFocusLogic() const
-{
- return true;
-}
-
bool HTMLMediaElement::supportsFocus() const
{
if (ownerDocument()->isMediaDocument())
@@ -422,9 +497,9 @@ void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr
clearMediaPlayer(LoadMediaResource);
scheduleDelayedAction(LoadMediaResource);
}
- } else if (name == controlsAttr)
+ } else if (name == controlsAttr) {
configureMediaControls();
- else if (name == preloadAttr) {
+ } else if (name == preloadAttr) {
if (equalIgnoringCase(value, "none"))
m_preload = MediaPlayer::None;
else if (equalIgnoringCase(value, "metadata"))
@@ -437,30 +512,21 @@ void HTMLMediaElement::parseAttribute(const QualifiedName& name, const AtomicStr
// The attribute must be ignored if the autoplay attribute is present
if (!autoplay() && m_player)
- m_player->setPreload(m_preload);
+ setPlayerPreload();
- } else if (name == mediagroupAttr)
+ } else if (name == mediagroupAttr && RuntimeEnabledFeatures::mediaControllerEnabled()) {
setMediaGroup(value);
- else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
- else
+ } else {
HTMLElement::parseAttribute(name, value);
+ }
}
void HTMLMediaElement::finishParsingChildren()
{
HTMLElement::finishParsingChildren();
- m_parsingInProgress = false;
-
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
- return;
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(trackTag)) {
- scheduleDelayedAction(LoadTextTrackResource);
- break;
- }
- }
+ if (Traversal<HTMLTrackElement>::firstChild(*this))
+ scheduleDelayedAction(LoadTextTrackResource);
}
bool HTMLMediaElement::rendererIsNeeded(const RenderStyle& style)
@@ -473,11 +539,6 @@ RenderObject* HTMLMediaElement::createRenderer(RenderStyle*)
return new RenderMedia(this);
}
-bool HTMLMediaElement::childShouldCreateRenderer(const Node& child) const
-{
- return hasMediaControls() && HTMLElement::childShouldCreateRenderer(child);
-}
-
Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode* insertionPoint)
{
WTF_LOG(Media, "HTMLMediaElement::insertedInto");
@@ -490,8 +551,12 @@ Node::InsertionNotificationRequest HTMLMediaElement::insertedInto(ContainerNode*
scheduleDelayedAction(LoadMediaResource);
}
+ return InsertionShouldCallDidNotifySubtreeInsertions;
+}
+
+void HTMLMediaElement::didNotifySubtreeInsertionsToDocument()
+{
configureMediaControls();
- return InsertionDone;
}
void HTMLMediaElement::removedFrom(ContainerNode* insertionPoint)
@@ -499,7 +564,7 @@ void HTMLMediaElement::removedFrom(ContainerNode* insertionPoint)
WTF_LOG(Media, "HTMLMediaElement::removedFrom");
m_active = false;
- if (insertionPoint->inDocument()) {
+ if (insertionPoint->inDocument() && insertionPoint->document().isActive()) {
configureMediaControls();
if (m_networkState > NETWORK_EMPTY)
pause();
@@ -531,33 +596,36 @@ void HTMLMediaElement::scheduleDelayedAction(DelayedActionType actionType)
m_pendingActionFlags |= LoadMediaResource;
}
- if (RuntimeEnabledFeatures::videoTrackEnabled() && (actionType & LoadTextTrackResource))
+ if (actionType & LoadTextTrackResource)
m_pendingActionFlags |= LoadTextTrackResource;
if (!m_loadTimer.isActive())
- m_loadTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0, FROM_HERE);
}
void HTMLMediaElement::scheduleNextSourceChild()
{
// Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad.
m_pendingActionFlags |= LoadMediaResource;
- m_loadTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0, FROM_HERE);
}
void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
{
+ scheduleEvent(Event::createCancelable(eventName));
+}
+
+void HTMLMediaElement::scheduleEvent(PassRefPtrWillBeRawPtr<Event> event)
+{
#if LOG_MEDIA_EVENTS
- WTF_LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.string().ascii().data());
+ WTF_LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", event->type().ascii().data());
#endif
- m_asyncEventQueue->enqueueEvent(Event::createCancelable(eventName));
+ m_asyncEventQueue->enqueueEvent(event);
}
void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
{
- RefPtr<HTMLMediaElement> protect(this); // loadNextSourceChild may fire 'beforeload', which can make arbitrary DOM mutations.
-
- if (RuntimeEnabledFeatures::videoTrackEnabled() && (m_pendingActionFlags & LoadTextTrackResource))
+ if (m_pendingActionFlags & LoadTextTrackResource)
configureTextTracks();
if (m_pendingActionFlags & LoadMediaResource) {
@@ -570,7 +638,7 @@ void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
m_pendingActionFlags = 0;
}
-PassRefPtr<MediaError> HTMLMediaElement::error() const
+PassRefPtrWillBeRawPtr<MediaError> HTMLMediaElement::error() const
{
return m_error;
}
@@ -585,8 +653,11 @@ HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const
return m_networkState;
}
-String HTMLMediaElement::canPlayType(const String& mimeType, const String& keySystem, const KURL& url) const
+String HTMLMediaElement::canPlayType(const String& mimeType, const String& keySystem) const
{
+ if (!keySystem.isNull())
+ UseCounter::count(document(), UseCounter::CanPlayTypeKeySystem);
+
WebMimeRegistry::SupportsType support = supportsType(ContentType(mimeType), keySystem);
String canPlay;
@@ -604,26 +675,18 @@ String HTMLMediaElement::canPlayType(const String& mimeType, const String& keySy
break;
}
- WTF_LOG(Media, "HTMLMediaElement::canPlayType(%s, %s, %s) -> %s", mimeType.utf8().data(), keySystem.utf8().data(), url.elidedString().utf8().data(), canPlay.utf8().data());
+ WTF_LOG(Media, "HTMLMediaElement::canPlayType(%s, %s) -> %s", mimeType.utf8().data(), keySystem.utf8().data(), canPlay.utf8().data());
return canPlay;
}
void HTMLMediaElement::load()
{
- RefPtr<HTMLMediaElement> protect(this); // loadInternal may result in a 'beforeload' event, which can make arbitrary DOM mutations.
-
WTF_LOG(Media, "HTMLMediaElement::load()");
- if (document().settings() && !document().settings()->mediaEnabled())
- return;
-
- if (userGestureRequiredForLoad() && !UserGestureIndicator::processingUserGesture())
- return;
+ if (UserGestureIndicator::processingUserGesture())
+ m_userGestureRequiredForPlay = false;
- m_loadInitiatedByUserGesture = UserGestureIndicator::processingUserGesture();
- if (m_loadInitiatedByUserGesture)
- removeBehaviorsRestrictionsAfterFirstUserGesture();
prepareForLoad();
loadInternal();
prepareToPlay();
@@ -636,6 +699,9 @@ void HTMLMediaElement::prepareForLoad()
// Perform the cleanup required for the resource load algorithm to run.
stopPeriodicTimers();
m_loadTimer.stop();
+ cancelDeferredLoad();
+ // FIXME: Figure out appropriate place to reset LoadTextTrackResource if necessary and set m_pendingActionFlags to 0 here.
+ m_pendingActionFlags &= ~LoadMediaResource;
m_sentEndEvent = false;
m_sentStalledEvent = false;
m_haveFiredLoadedData = false;
@@ -645,7 +711,7 @@ void HTMLMediaElement::prepareForLoad()
// 1 - Abort any already-running instance of the resource selection algorithm for this element.
m_loadState = WaitingForSource;
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
// 2 - If there are any tasks from the media element's media element event task source in
// one of the task queues, then remove those tasks.
@@ -656,30 +722,53 @@ void HTMLMediaElement::prepareForLoad()
if (m_networkState == NETWORK_LOADING || m_networkState == NETWORK_IDLE)
scheduleEvent(EventTypeNames::abort);
- closeMediaSource();
-
createMediaPlayer();
// 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
if (m_networkState != NETWORK_EMPTY) {
+ // 4.1 - Queue a task to fire a simple event named emptied at the media element.
+ scheduleEvent(EventTypeNames::emptied);
+
+ // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it.
m_networkState = NETWORK_EMPTY;
+
+ // 4.3 - Forget the media element's media-resource-specific tracks.
+ forgetResourceSpecificTracks();
+
+ // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that state.
m_readyState = HAVE_NOTHING;
m_readyStateMaximum = HAVE_NOTHING;
- refreshCachedTime();
+
+ // 4.5 - If the paused attribute is false, then set it to true.
m_paused = true;
+
+ // 4.6 - If seeking is true, set it to false.
m_seeking = false;
+
+ // 4.7 - Set the current playback position to 0.
+ // Set the official playback position to 0.
+ // If this changed the official playback position, then queue a task to fire a simple event named timeupdate at the media element.
+ // FIXME: Add support for firing this event.
+
+ // 4.8 - Set the initial playback position to 0.
+ // FIXME: Make this less subtle. The position only becomes 0 because of the createMediaPlayer() call
+ // above.
+ refreshCachedTime();
invalidateCachedTime();
- scheduleEvent(EventTypeNames::emptied);
+
+ // 4.9 - Set the timeline offset to Not-a-Number (NaN).
+ // 4.10 - Update the duration attribute to Not-a-Number (NaN).
+
+
updateMediaController();
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(0);
+ updateActiveTextTrackCues(0);
}
// 5 - Set the playbackRate attribute to the value of the defaultPlaybackRate attribute.
setPlaybackRate(defaultPlaybackRate());
// 6 - Set the error attribute to null and the autoplaying flag to true.
- m_error = 0;
+ m_error = nullptr;
m_autoplaying = true;
// 7 - Invoke the media element's resource selection algorithm.
@@ -693,8 +782,11 @@ void HTMLMediaElement::prepareForLoad()
// 2 - Asynchronously await a stable state.
m_playedTimeRanges = TimeRanges::create();
+
+ // FIXME: Investigate whether these can be moved into m_networkState != NETWORK_EMPTY block above
+ // so they are closer to the relevant spec steps.
m_lastSeekTime = 0;
- m_duration = numeric_limits<double>::quiet_NaN();
+ m_duration = std::numeric_limits<double>::quiet_NaN();
// The spec doesn't say to block the load event until we actually run the asynchronous section
// algorithm, but do it now because we won't start that until after the timer fires and the
@@ -706,26 +798,14 @@ void HTMLMediaElement::prepareForLoad()
void HTMLMediaElement::loadInternal()
{
- // Some of the code paths below this function dispatch the BeforeLoad event. This ASSERT helps
- // us catch those bugs more quickly without needing all the branches to align to actually
- // trigger the event.
- ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden());
-
- // Once the page has allowed an element to load media, it is free to load at will. This allows a
- // playlist that starts in a foreground tab to continue automatically if the tab is subsequently
- // put in the the background.
- removeBehaviorRestriction(RequirePageConsentToLoadMediaRestriction);
-
// HTMLMediaElement::textTracksAreReady will need "... the text tracks whose mode was not in the
// disabled state when the element's resource selection algorithm last started".
- if (RuntimeEnabledFeatures::videoTrackEnabled()) {
- m_textTracksWhenResourceSelectionBegan.clear();
- if (m_textTracks) {
- for (unsigned i = 0; i < m_textTracks->length(); ++i) {
- TextTrack* track = m_textTracks->item(i);
- if (track->mode() != TextTrack::disabledKeyword())
- m_textTracksWhenResourceSelectionBegan.append(track);
- }
+ m_textTracksWhenResourceSelectionBegan.clear();
+ if (m_textTracks) {
+ for (unsigned i = 0; i < m_textTracks->length(); ++i) {
+ TextTrack* track = m_textTracks->item(i);
+ if (track->mode() != TextTrack::disabledKeyword())
+ m_textTracksWhenResourceSelectionBegan.append(track);
}
}
@@ -741,19 +821,13 @@ void HTMLMediaElement::selectMediaResource()
// 3 - If the media element has a src attribute, then let mode be attribute.
Mode mode = attribute;
if (!fastHasAttribute(srcAttr)) {
- Node* node;
- for (node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(sourceTag))
- break;
- }
-
// Otherwise, if the media element does not have a src attribute but has a source
// element child, then let mode be children and let candidate be the first such
// source element child in tree order.
- if (node) {
+ if (HTMLSourceElement* element = Traversal<HTMLSourceElement>::firstChild(*this)) {
mode = children;
- m_nextChildNodeToConsider = node;
- m_currentSourceNode = 0;
+ m_nextChildNodeToConsider = element;
+ m_currentSourceNode = nullptr;
} else {
// Otherwise the media element has neither a src attribute nor a source element
// child: set the networkState to NETWORK_EMPTY, and abort these steps; the
@@ -787,7 +861,7 @@ void HTMLMediaElement::selectMediaResource()
return;
}
- if (!isSafeToLoadURL(mediaURL, Complain) || !dispatchBeforeLoadEvent(mediaURL.string())) {
+ if (!isSafeToLoadURL(mediaURL, Complain)) {
mediaLoadingFailed(MediaPlayer::FormatError);
return;
}
@@ -828,7 +902,7 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
WTF_LOG(Media, "HTMLMediaElement::loadResource(%s, %s, %s)", urlForLoggingMedia(url).utf8().data(), contentType.raw().utf8().data(), keySystem.utf8().data());
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame) {
mediaLoadingFailed(MediaPlayer::FormatError);
return;
@@ -843,16 +917,13 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
WTF_LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLoggingMedia(m_currentSrc).utf8().data());
- if (MediaStreamRegistry::registry().lookupMediaStreamDescriptor(url.string()))
- removeBehaviorRestriction(RequireUserGestureForRateChangeRestriction);
-
startProgressEventTimer();
// Reset display mode to force a recalculation of what to show because we are resetting the player.
setDisplayMode(Unknown);
if (!autoplay())
- m_player->setPreload(m_preload);
+ setPlayerPreload();
if (fastHasAttribute(mutedAttr))
m_muted = true;
@@ -860,20 +931,34 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
ASSERT(!m_mediaSource);
- if (url.protocolIs(mediaSourceBlobProtocol))
- m_mediaSource = HTMLMediaSource::lookup(url.string());
+ bool attemptLoad = true;
- if (m_mediaSource) {
- if (m_mediaSource->attachToElement(this)) {
- m_player->load(url, m_mediaSource);
+ if (url.protocolIs(mediaSourceBlobProtocol)) {
+ if (isMediaStreamURL(url.string())) {
+ m_userGestureRequiredForPlay = false;
} else {
- // Forget our reference to the MediaSource, so we leave it alone
- // while processing remainder of load failure.
- m_mediaSource = 0;
- mediaLoadingFailed(MediaPlayer::FormatError);
+ m_mediaSource = HTMLMediaSource::lookup(url.string());
+
+ if (m_mediaSource) {
+ if (!m_mediaSource->attachToElement(this)) {
+ // Forget our reference to the MediaSource, so we leave it alone
+ // while processing remainder of load failure.
+ m_mediaSource = nullptr;
+ attemptLoad = false;
+ }
+ }
+ }
+ }
+
+ if (attemptLoad && canLoadURL(url, contentType, keySystem)) {
+ ASSERT(!webMediaPlayer());
+
+ if (!m_havePreparedToPlay && !autoplay() && m_preload == MediaPlayer::None) {
+ WTF_LOG(Media, "HTMLMediaElement::loadResource : Delaying load because preload == 'none'");
+ deferLoad();
+ } else {
+ startPlayerLoad();
}
- } else if (canLoadURL(url, contentType, keySystem)) {
- m_player->load(url);
} else {
mediaLoadingFailed(MediaPlayer::FormatError);
}
@@ -886,6 +971,118 @@ void HTMLMediaElement::loadResource(const KURL& url, ContentType& contentType, c
renderer()->updateFromElement();
}
+void HTMLMediaElement::startPlayerLoad()
+{
+ // Filter out user:pass as those two URL components aren't
+ // considered for media resource fetches (including for the CORS
+ // use-credentials mode.) That behavior aligns with Gecko, with IE
+ // being more restrictive and not allowing fetches to such URLs.
+ //
+ // Spec reference: http://whatwg.org/c/#concept-media-load-resource
+ //
+ // FIXME: when the HTML spec switches to specifying resource
+ // fetches in terms of Fetch (http://fetch.spec.whatwg.org), and
+ // along with that potentially also specifying a setting for its
+ // 'authentication flag' to control how user:pass embedded in a
+ // media resource URL should be treated, then update the handling
+ // here to match.
+ KURL requestURL = m_currentSrc;
+ if (!requestURL.user().isEmpty())
+ requestURL.setUser(String());
+ if (!requestURL.pass().isEmpty())
+ requestURL.setPass(String());
+
+ m_player->load(loadType(), requestURL, corsMode());
+}
+
+void HTMLMediaElement::setPlayerPreload()
+{
+ m_player->setPreload(m_preload);
+
+ if (loadIsDeferred() && m_preload != MediaPlayer::None)
+ startDeferredLoad();
+}
+
+bool HTMLMediaElement::loadIsDeferred() const
+{
+ return m_deferredLoadState != NotDeferred;
+}
+
+void HTMLMediaElement::deferLoad()
+{
+ // This implements the "optional" step 3 from the resource fetch algorithm.
+ ASSERT(!m_deferredLoadTimer.isActive());
+ ASSERT(m_deferredLoadState == NotDeferred);
+ // 1. Set the networkState to NETWORK_IDLE.
+ // 2. Queue a task to fire a simple event named suspend at the element.
+ changeNetworkStateFromLoadingToIdle();
+ // 3. Queue a task to set the element's delaying-the-load-event
+ // flag to false. This stops delaying the load event.
+ m_deferredLoadTimer.startOneShot(0, FROM_HERE);
+ // 4. Wait for the task to be run.
+ m_deferredLoadState = WaitingForStopDelayingLoadEventTask;
+ // Continued in executeDeferredLoad().
+}
+
+void HTMLMediaElement::cancelDeferredLoad()
+{
+ m_deferredLoadTimer.stop();
+ m_deferredLoadState = NotDeferred;
+}
+
+void HTMLMediaElement::executeDeferredLoad()
+{
+ ASSERT(m_deferredLoadState >= WaitingForTrigger);
+
+ // resource fetch algorithm step 3 - continued from deferLoad().
+
+ // 5. Wait for an implementation-defined event (e.g. the user requesting that the media element begin playback).
+ // This is assumed to be whatever 'event' ended up calling this method.
+ cancelDeferredLoad();
+ // 6. Set the element's delaying-the-load-event flag back to true (this
+ // delays the load event again, in case it hasn't been fired yet).
+ setShouldDelayLoadEvent(true);
+ // 7. Set the networkState to NETWORK_LOADING.
+ m_networkState = NETWORK_LOADING;
+
+ startProgressEventTimer();
+
+ startPlayerLoad();
+}
+
+void HTMLMediaElement::startDeferredLoad()
+{
+ if (m_deferredLoadState == WaitingForTrigger) {
+ executeDeferredLoad();
+ return;
+ }
+ ASSERT(m_deferredLoadState == WaitingForStopDelayingLoadEventTask);
+ m_deferredLoadState = ExecuteOnStopDelayingLoadEventTask;
+}
+
+void HTMLMediaElement::deferredLoadTimerFired(Timer<HTMLMediaElement>*)
+{
+ setShouldDelayLoadEvent(false);
+
+ if (m_deferredLoadState == ExecuteOnStopDelayingLoadEventTask) {
+ executeDeferredLoad();
+ return;
+ }
+ ASSERT(m_deferredLoadState == WaitingForStopDelayingLoadEventTask);
+ m_deferredLoadState = WaitingForTrigger;
+}
+
+WebMediaPlayer::LoadType HTMLMediaElement::loadType() const
+{
+ if (m_mediaSource)
+ return WebMediaPlayer::LoadTypeMediaSource;
+
+ if (isMediaStreamURL(m_currentSrc.string()))
+ return WebMediaPlayer::LoadTypeMediaStream;
+
+ return WebMediaPlayer::LoadTypeURL;
+}
+
static bool trackIndexCompare(TextTrack* a,
TextTrack* b)
{
@@ -923,8 +1120,6 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
if (ignoreTrackDisplayUpdateRequests())
return;
- WTF_LOG(Media, "HTMLMediaElement::updateActiveTextTrackCues");
-
// 1 - Let current cues be a list of cues, initialized to contain all the
// cues of all the hidden, showing, or showing by default text tracks of the
// media element (not the disabled ones) whose start times are less than or
@@ -965,7 +1160,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
double cueEndTime = potentiallySkippedCues[i].high();
// Consider cues that may have been missed since the last seek time.
- if (cueStartTime > max(m_lastSeekTime, lastTime) && cueEndTime < movieTime)
+ if (cueStartTime > std::max(m_lastSeekTime, lastTime) && cueEndTime < movieTime)
missedCues.append(potentiallySkippedCues[i]);
}
}
@@ -1079,7 +1274,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
affectedTracks.append(eventTasks[i].second->track());
// 13 - Queue each task in events, in list order.
- RefPtr<Event> event;
+ RefPtrWillBeRawPtr<Event> event = nullptr;
// Each event in eventTasks may be either an enterEvent or an exitEvent,
// depending on the time that is associated with the event. This
@@ -1111,7 +1306,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
// 15 - For each text track in affected tracks, in the list order, queue a
// task to fire a simple event named cuechange at the TextTrack object, and, ...
for (size_t i = 0; i < affectedTracks.size(); ++i) {
- RefPtr<Event> event = Event::create(EventTypeNames::cuechange);
+ RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::cuechange);
event->setTarget(affectedTracks[i]);
m_asyncEventQueue->enqueueEvent(event.release());
@@ -1119,7 +1314,7 @@ void HTMLMediaElement::updateActiveTextTrackCues(double movieTime)
// ... if the text track has a corresponding track element, to then fire a
// simple event named cuechange at the track element as well.
if (affectedTracks[i]->trackType() == TextTrack::TrackElement) {
- RefPtr<Event> event = Event::create(EventTypeNames::cuechange);
+ RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::cuechange);
HTMLTrackElement* trackElement = static_cast<LoadableTextTrack*>(affectedTracks[i])->trackElement();
ASSERT(trackElement);
event->setTarget(trackElement);
@@ -1163,9 +1358,9 @@ bool HTMLMediaElement::textTracksAreReady() const
void HTMLMediaElement::textTrackReadyStateChanged(TextTrack* track)
{
- if (m_player && m_textTracksWhenResourceSelectionBegan.contains(track)) {
+ if (webMediaPlayer()&& m_textTracksWhenResourceSelectionBegan.contains(track)) {
if (track->readinessState() != TextTrack::Loading)
- setReadyState(m_player->readyState());
+ setReadyState(static_cast<ReadyState>(webMediaPlayer()->readyState()));
} else {
// The track readiness state might have changed as a result of the user
// clicking the captions button. In this case, a check whether all the
@@ -1184,10 +1379,7 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
// or showing by default for the first time, the user agent must immediately and synchronously
// run the following algorithm ...
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (!node->hasTagName(trackTag))
- continue;
- HTMLTrackElement* trackElement = toHTMLTrackElement(node);
+ for (HTMLTrackElement* trackElement = Traversal<HTMLTrackElement>::firstChild(*this); trackElement; trackElement = Traversal<HTMLTrackElement>::nextSibling(*trackElement)) {
if (trackElement->track() != track)
continue;
@@ -1203,8 +1395,9 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
}
break;
}
- } else if (track->trackType() == TextTrack::AddTrack && track->mode() != TextTrack::disabledKeyword())
+ } else if (track->trackType() == TextTrack::AddTrack && track->mode() != TextTrack::disabledKeyword()) {
textTrackAddCues(track, track->cues());
+ }
configureTextTrackDisplay(AssumeVisibleChange);
@@ -1251,14 +1444,14 @@ void HTMLMediaElement::textTrackRemoveCues(TextTrack*, const TextTrackCueList* c
textTrackRemoveCue(cues->item(i)->track(), cues->item(i));
}
-void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
+void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtrWillBeRawPtr<TextTrackCue> cue)
{
if (track->mode() == TextTrack::disabledKeyword())
return;
// Negative duration cues need be treated in the interval tree as
// zero-length cues.
- double endTime = max(cue->startTime(), cue->endTime());
+ double endTime = std::max(cue->startTime(), cue->endTime());
CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, cue.get());
if (!m_cueTree.contains(interval))
@@ -1266,11 +1459,11 @@ void HTMLMediaElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue
updateActiveTextTrackCues(currentTime());
}
-void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue> cue)
+void HTMLMediaElement::textTrackRemoveCue(TextTrack*, PassRefPtrWillBeRawPtr<TextTrackCue> cue)
{
// Negative duration cues need to be treated in the interval tree as
// zero-length cues.
- double endTime = max(cue->startTime(), cue->endTime());
+ double endTime = std::max(cue->startTime(), cue->endTime());
CueInterval interval = m_cueTree.createInterval(cue->startTime(), endTime, cue.get());
m_cueTree.remove(interval);
@@ -1299,7 +1492,7 @@ bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidURLAction actionI
return false;
}
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame || !document().securityOrigin()->canDisplay(url)) {
if (actionIfInvalid == Complain)
FrameLoader::reportLocalLoadFailed(frame, url.elidedString());
@@ -1322,7 +1515,7 @@ void HTMLMediaElement::startProgressEventTimer()
m_previousProgressTime = WTF::currentTime();
// 350ms is not magic, it is in the spec!
- m_progressEventTimer.startRepeating(0.350);
+ m_progressEventTimer.startRepeating(0.350, FROM_HERE);
}
void HTMLMediaElement::waitForSourceChange()
@@ -1350,7 +1543,7 @@ void HTMLMediaElement::noneSupported()
stopPeriodicTimers();
m_loadState = WaitingForSource;
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
// 4.8.10.5
// 6 - Reaching this step indicates that the media resource failed to load or that the given
@@ -1361,6 +1554,7 @@ void HTMLMediaElement::noneSupported()
m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
// 6.2 - Forget the media element's media-resource-specific text tracks.
+ forgetResourceSpecificTracks();
// 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
m_networkState = NETWORK_NO_SOURCE;
@@ -1382,7 +1576,7 @@ void HTMLMediaElement::noneSupported()
renderer()->updateFromElement();
}
-void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
+void HTMLMediaElement::mediaEngineError(PassRefPtrWillBeRawPtr<MediaError> err)
{
WTF_LOG(Media, "HTMLMediaElement::mediaEngineError(%d)", static_cast<int>(err->code()));
@@ -1408,7 +1602,7 @@ void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
setShouldDelayLoadEvent(false);
// 6 - Abort the overall resource selection algorithm.
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
}
void HTMLMediaElement::cancelPendingEventsAndCallbacks()
@@ -1416,10 +1610,8 @@ void HTMLMediaElement::cancelPendingEventsAndCallbacks()
WTF_LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks");
m_asyncEventQueue->cancelAllEvents();
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(sourceTag))
- toHTMLSourceElement(node)->cancelPendingErrorEvent();
- }
+ for (HTMLSourceElement* source = Traversal<HTMLSourceElement>::firstChild(*this); source; source = Traversal<HTMLSourceElement>::nextSibling(*source))
+ source->cancelPendingErrorEvent();
}
void HTMLMediaElement::mediaPlayerNetworkStateChanged()
@@ -1435,11 +1627,18 @@ void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error)
// <source> children, schedule the next one
if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
+ // resource selection algorithm
+ // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM manipulation task source, to fire a simple event named error at the candidate element.
if (m_currentSourceNode)
m_currentSourceNode->scheduleErrorEvent();
else
WTF_LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed");
+ // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the synchronous section has ended.
+
+ // 9.Otherwise.11 - Forget the media element's media-resource-specific tracks.
+ forgetResourceSpecificTracks();
+
if (havePotentialSourceChild()) {
WTF_LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>");
scheduleNextSourceChild();
@@ -1459,10 +1658,8 @@ void HTMLMediaElement::mediaLoadingFailed(MediaPlayer::NetworkState error)
noneSupported();
updateDisplayState();
- if (hasMediaControls()) {
+ if (hasMediaControls())
mediaControls()->reset();
- mediaControls()->reportedError();
- }
}
void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
@@ -1500,30 +1697,27 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
changeNetworkStateFromLoadingToIdle();
m_completelyLoaded = true;
}
-
- if (hasMediaControls())
- mediaControls()->updateStatusDisplay();
}
void HTMLMediaElement::changeNetworkStateFromLoadingToIdle()
{
+ ASSERT(m_player);
m_progressEventTimer.stop();
- if (hasMediaControls() && m_player->didLoadingProgress())
- mediaControls()->bufferingProgressed();
// Schedule one last progress event so we guarantee that at least one is fired
// for files that load very quickly.
- scheduleEvent(EventTypeNames::progress);
+ if (m_player->didLoadingProgress())
+ scheduleEvent(EventTypeNames::progress);
scheduleEvent(EventTypeNames::suspend);
m_networkState = NETWORK_IDLE;
}
void HTMLMediaElement::mediaPlayerReadyStateChanged()
{
- setReadyState(m_player->readyState());
+ setReadyState(static_cast<ReadyState>(webMediaPlayer()->readyState()));
}
-void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
+void HTMLMediaElement::setReadyState(ReadyState state)
{
WTF_LOG(Media, "HTMLMediaElement::setReadyState(%d) - current state is %d,", static_cast<int>(state), static_cast<int>(m_readyState));
@@ -1531,9 +1725,9 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
bool wasPotentiallyPlaying = potentiallyPlaying();
ReadyState oldState = m_readyState;
- ReadyState newState = static_cast<ReadyState>(state);
+ ReadyState newState = state;
- bool tracksAreReady = !RuntimeEnabledFeatures::videoTrackEnabled() || textTracksAreReady();
+ bool tracksAreReady = textTracksAreReady();
if (newState == oldState && m_tracksAreReady == tracksAreReady)
return;
@@ -1576,11 +1770,20 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
}
if (m_readyState >= HAVE_METADATA && oldState < HAVE_METADATA) {
+ createPlaceholderTracksIfNecessary();
+
prepareMediaFragmentURI();
+
+ selectInitialTracksIfNecessary();
+
+ m_duration = duration();
scheduleEvent(EventTypeNames::durationchange);
+
+ if (isHTMLVideoElement(*this))
+ scheduleEvent(EventTypeNames::resize);
scheduleEvent(EventTypeNames::loadedmetadata);
if (hasMediaControls())
- mediaControls()->loadedMetadata();
+ mediaControls()->reset();
if (renderer())
renderer()->updateFromElement();
}
@@ -1604,154 +1807,33 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
}
if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && tracksAreReady) {
- if (oldState <= HAVE_CURRENT_DATA)
+ if (oldState <= HAVE_CURRENT_DATA) {
scheduleEvent(EventTypeNames::canplay);
+ if (isPotentiallyPlaying)
+ scheduleEvent(EventTypeNames::playing);
+ }
- scheduleEvent(EventTypeNames::canplaythrough);
-
- if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
- scheduleEvent(EventTypeNames::playing);
-
- if (m_autoplaying && m_paused && autoplay() && !document().isSandboxed(SandboxAutomaticFeatures) && !userGestureRequiredForRateChange()) {
+ if (m_autoplaying && m_paused && autoplay() && !document().isSandboxed(SandboxAutomaticFeatures) && !m_userGestureRequiredForPlay) {
m_paused = false;
invalidateCachedTime();
scheduleEvent(EventTypeNames::play);
scheduleEvent(EventTypeNames::playing);
}
+ scheduleEvent(EventTypeNames::canplaythrough);
+
shouldUpdateDisplayState = true;
}
if (shouldUpdateDisplayState) {
updateDisplayState();
- if (hasMediaControls()) {
+ if (hasMediaControls())
mediaControls()->refreshClosedCaptionsButtonVisibility();
- mediaControls()->updateStatusDisplay();
- }
}
updatePlayState();
updateMediaController();
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(currentTime());
-}
-
-void HTMLMediaElement::mediaPlayerKeyAdded(const String& keySystem, const String& sessionId)
-{
- MediaKeyEventInit initializer;
- initializer.keySystem = keySystem;
- initializer.sessionId = sessionId;
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeyadded, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-void HTMLMediaElement::mediaPlayerKeyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode errorCode, unsigned short systemCode)
-{
- MediaKeyError::Code mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
- switch (errorCode) {
- case MediaPlayerClient::UnknownError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
- break;
- case MediaPlayerClient::ClientError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_CLIENT;
- break;
- case MediaPlayerClient::ServiceError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_SERVICE;
- break;
- case MediaPlayerClient::OutputError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_OUTPUT;
- break;
- case MediaPlayerClient::HardwareChangeError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_HARDWARECHANGE;
- break;
- case MediaPlayerClient::DomainError:
- mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_DOMAIN;
- break;
- }
-
- MediaKeyEventInit initializer;
- initializer.keySystem = keySystem;
- initializer.sessionId = sessionId;
- initializer.errorCode = MediaKeyError::create(mediaKeyErrorCode);
- initializer.systemCode = systemCode;
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeyerror, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-void HTMLMediaElement::mediaPlayerKeyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL)
-{
- MediaKeyEventInit initializer;
- initializer.keySystem = keySystem;
- initializer.sessionId = sessionId;
- initializer.message = Uint8Array::create(message, messageLength);
- initializer.defaultURL = defaultURL;
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeymessage, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-bool HTMLMediaElement::mediaPlayerKeyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength)
-{
- if (!hasEventListeners(EventTypeNames::webkitneedkey)) {
- m_error = MediaError::create(MediaError::MEDIA_ERR_ENCRYPTED);
- scheduleEvent(EventTypeNames::error);
- return false;
- }
-
- MediaKeyEventInit initializer;
- initializer.keySystem = keySystem;
- initializer.sessionId = sessionId;
- initializer.initData = Uint8Array::create(initData, initDataLength);
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitneedkey, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
- return true;
-}
-
-bool HTMLMediaElement::mediaPlayerKeyNeeded(Uint8Array* initData)
-{
- if (!hasEventListeners("webkitneedkey")) {
- m_error = MediaError::create(MediaError::MEDIA_ERR_ENCRYPTED);
- scheduleEvent(EventTypeNames::error);
- return false;
- }
-
- MediaKeyNeededEventInit initializer;
- initializer.initData = initData;
- initializer.bubbles = false;
- initializer.cancelable = false;
-
- RefPtr<Event> event = MediaKeyNeededEvent::create(EventTypeNames::webkitneedkey, initializer);
- event->setTarget(this);
- m_asyncEventQueue->enqueueEvent(event.release());
-
- return true;
-}
-
-void HTMLMediaElement::setMediaKeys(MediaKeys* mediaKeys)
-{
- if (m_mediaKeys == mediaKeys)
- return;
-
- if (m_mediaKeys)
- m_mediaKeys->setMediaElement(0);
- m_mediaKeys = mediaKeys;
- if (m_mediaKeys)
- m_mediaKeys->setMediaElement(this);
+ updateActiveTextTrackCues(currentTime());
}
void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
@@ -1769,8 +1851,6 @@ void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
m_sentStalledEvent = false;
if (renderer())
renderer()->updateFromElement();
- if (hasMediaControls())
- mediaControls()->bufferingProgressed();
} else if (timedelta > 3.0 && !m_sentStalledEvent) {
scheduleEvent(EventTypeNames::stalled);
m_sentStalledEvent = true;
@@ -1797,7 +1877,9 @@ void HTMLMediaElement::prepareToPlay()
if (m_havePreparedToPlay)
return;
m_havePreparedToPlay = true;
- m_player->prepareToPlay();
+
+ if (loadIsDeferred())
+ startDeferredLoad();
}
void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
@@ -1808,7 +1890,7 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
// 1 - If the media element's readyState is HAVE_NOTHING, then raise an InvalidStateError exception.
if (m_readyState == HAVE_NOTHING || !m_player) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "The element's readyState is HAVE_NOTHING.");
return;
}
@@ -1827,14 +1909,15 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
// 3 - Set the seeking IDL attribute to true.
// The flag will be cleared when the engine tells us the time has actually changed.
+ bool previousSeekStillPending = m_seeking;
m_seeking = true;
// 5 - If the new playback position is later than the end of the media resource, then let it be the end
// of the media resource instead.
- time = min(time, duration());
+ time = std::min(time, duration());
// 6 - If the new playback position is less than the earliest possible position, let it be that position instead.
- time = max(time, 0.0);
+ time = std::max(time, 0.0);
// Ask the media engine for the time value in the movie's time scale before comparing with current time. This
// is necessary because if the seek time is not equal to currentTime but the delta is less than the movie's
@@ -1859,14 +1942,11 @@ void HTMLMediaElement::seek(double time, ExceptionState& exceptionState)
// cancel poster display.
bool noSeekRequired = !seekableRanges->length() || (time == now && displayMode() != Poster);
- // Always notify the media engine of a seek if the source is not closed. This ensures that the source is
- // always in a flushed state when the 'seeking' event fires.
- if (m_mediaSource && m_mediaSource->isClosed())
- noSeekRequired = false;
-
if (noSeekRequired) {
if (time == now) {
scheduleEvent(EventTypeNames::seeking);
+ if (previousSeekStillPending)
+ return;
// FIXME: There must be a stable state before timeupdate+seeked are dispatched and seeking
// is reset to false. See http://crbug.com/266631
scheduleTimeupdateEvent(false);
@@ -1918,7 +1998,7 @@ HTMLMediaElement::ReadyState HTMLMediaElement::readyState() const
bool HTMLMediaElement::hasAudio() const
{
- return m_player ? m_player->hasAudio() : false;
+ return webMediaPlayer() && webMediaPlayer()->hasAudio();
}
bool HTMLMediaElement::seeking() const
@@ -1977,7 +2057,7 @@ double HTMLMediaElement::currentTime() const
void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionState)
{
if (m_mediaController) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "The element is slaved to a MediaController.");
return;
}
seek(time, exceptionState);
@@ -1986,12 +2066,12 @@ void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionStat
double HTMLMediaElement::duration() const
{
if (!m_player || m_readyState < HAVE_METADATA)
- return numeric_limits<double>::quiet_NaN();
+ return std::numeric_limits<double>::quiet_NaN();
// FIXME: Refactor so m_duration is kept current (in both MSE and
// non-MSE cases) once we have transitioned from HAVE_NOTHING ->
// HAVE_METADATA. Currently, m_duration may be out of date for at least MSE
- // case because MediaSourceBase and SourceBuffer do not notify the element
+ // case because MediaSource and SourceBuffer do not notify the element
// directly upon duration changes caused by endOfStream, remove, or append
// operations; rather the notification is triggered by the WebMediaPlayer
// implementation observing that the underlying engine has updated duration
@@ -2016,10 +2096,11 @@ double HTMLMediaElement::defaultPlaybackRate() const
void HTMLMediaElement::setDefaultPlaybackRate(double rate)
{
- if (m_defaultPlaybackRate != rate) {
- m_defaultPlaybackRate = rate;
- scheduleEvent(EventTypeNames::ratechange);
- }
+ if (m_defaultPlaybackRate == rate)
+ return;
+
+ m_defaultPlaybackRate = rate;
+ scheduleEvent(EventTypeNames::ratechange);
}
double HTMLMediaElement::playbackRate() const
@@ -2037,13 +2118,22 @@ void HTMLMediaElement::setPlaybackRate(double rate)
scheduleEvent(EventTypeNames::ratechange);
}
- if (m_player && potentiallyPlaying() && m_player->rate() != rate && !m_mediaController)
- m_player->setRate(rate);
+ updatePlaybackRate();
+}
+
+double HTMLMediaElement::effectivePlaybackRate() const
+{
+ return m_mediaController ? m_mediaController->playbackRate() : m_playbackRate;
+}
+
+HTMLMediaElement::DirectionOfPlayback HTMLMediaElement::directionOfPlayback() const
+{
+ return m_playbackRate >= 0 ? Forward : Backward;
}
void HTMLMediaElement::updatePlaybackRate()
{
- double effectiveRate = m_mediaController ? m_mediaController->playbackRate() : m_playbackRate;
+ double effectiveRate = effectivePlaybackRate();
if (m_player && potentiallyPlaying() && m_player->rate() != effectiveRate)
m_player->setRate(effectiveRate);
}
@@ -2053,7 +2143,7 @@ bool HTMLMediaElement::ended() const
// 4.8.10.8 Playing the media resource
// The ended attribute must return true if the media element has ended
// playback and the direction of playback is forwards, and false otherwise.
- return endedPlayback() && m_playbackRate > 0;
+ return endedPlayback() && directionOfPlayback() == Forward;
}
bool HTMLMediaElement::autoplay() const
@@ -2079,7 +2169,7 @@ String HTMLMediaElement::preload() const
return String();
}
-void HTMLMediaElement::setPreload(const String& preload)
+void HTMLMediaElement::setPreload(const AtomicString& preload)
{
WTF_LOG(Media, "HTMLMediaElement::setPreload(%s)", preload.utf8().data());
setAttribute(preloadAttr, preload);
@@ -2089,10 +2179,10 @@ void HTMLMediaElement::play()
{
WTF_LOG(Media, "HTMLMediaElement::play()");
- if (userGestureRequiredForRateChange() && !UserGestureIndicator::processingUserGesture())
+ if (m_userGestureRequiredForPlay && !UserGestureIndicator::processingUserGesture())
return;
if (UserGestureIndicator::processingUserGesture())
- removeBehaviorsRestrictionsAfterFirstUserGesture();
+ m_userGestureRequiredForPlay = false;
playInternal();
}
@@ -2131,18 +2221,6 @@ void HTMLMediaElement::pause()
{
WTF_LOG(Media, "HTMLMediaElement::pause()");
- if (userGestureRequiredForRateChange() && !UserGestureIndicator::processingUserGesture())
- return;
-
- pauseInternal();
-}
-
-
-void HTMLMediaElement::pauseInternal()
-{
- WTF_LOG(Media, "HTMLMediaElement::pauseInternal");
-
- // 4.8.10.9. Playing the media resource
if (!m_player || m_networkState == NETWORK_EMPTY)
scheduleDelayedAction(LoadMediaResource);
@@ -2163,89 +2241,7 @@ void HTMLMediaElement::closeMediaSource()
return;
m_mediaSource->close();
- m_mediaSource = 0;
-}
-
-void HTMLMediaElement::webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState& exceptionState)
-{
- if (keySystem.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- if (!m_player) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- const unsigned char* initDataPointer = 0;
- unsigned initDataLength = 0;
- if (initData) {
- initDataPointer = initData->data();
- initDataLength = initData->length();
- }
-
- MediaPlayer::MediaKeyException result = m_player->generateKeyRequest(keySystem, initDataPointer, initDataLength);
- throwExceptionForMediaKeyException(result, exceptionState);
-}
-
-void HTMLMediaElement::webkitGenerateKeyRequest(const String& keySystem, ExceptionState& exceptionState)
-{
- webkitGenerateKeyRequest(keySystem, Uint8Array::create(0), exceptionState);
-}
-
-void HTMLMediaElement::webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState& exceptionState)
-{
- if (keySystem.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- if (!key) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- if (!key->length()) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- if (!m_player) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- const unsigned char* initDataPointer = 0;
- unsigned initDataLength = 0;
- if (initData) {
- initDataPointer = initData->data();
- initDataLength = initData->length();
- }
-
- MediaPlayer::MediaKeyException result = m_player->addKey(keySystem, key->data(), key->length(), initDataPointer, initDataLength, sessionId);
- throwExceptionForMediaKeyException(result, exceptionState);
-}
-
-void HTMLMediaElement::webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionState& exceptionState)
-{
- webkitAddKey(keySystem, key, Uint8Array::create(0), String(), exceptionState);
-}
-
-void HTMLMediaElement::webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionState& exceptionState)
-{
- if (keySystem.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- if (!m_player) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- MediaPlayer::MediaKeyException result = m_player->cancelKeyRequest(keySystem, sessionId);
- throwExceptionForMediaKeyException(result, exceptionState);
+ m_mediaSource = nullptr;
}
bool HTMLMediaElement::loop() const
@@ -2261,7 +2257,7 @@ void HTMLMediaElement::setLoop(bool b)
bool HTMLMediaElement::controls() const
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
// always show controls when scripting is disabled
if (frame && !frame->script().canExecuteScripts(NotAboutToExecuteScript))
@@ -2289,16 +2285,17 @@ void HTMLMediaElement::setVolume(double vol, ExceptionState& exceptionState)
{
WTF_LOG(Media, "HTMLMediaElement::setVolume(%f)", vol);
+ if (m_volume == vol)
+ return;
+
if (vol < 0.0f || vol > 1.0f) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("volume", vol, 0.0, ExceptionMessages::InclusiveBound, 1.0, ExceptionMessages::InclusiveBound));
return;
}
- if (m_volume != vol) {
- m_volume = vol;
- updateVolume();
- scheduleEvent(EventTypeNames::volumechange);
- }
+ m_volume = vol;
+ updateVolume();
+ scheduleEvent(EventTypeNames::volumechange);
}
bool HTMLMediaElement::muted() const
@@ -2310,55 +2307,14 @@ void HTMLMediaElement::setMuted(bool muted)
{
WTF_LOG(Media, "HTMLMediaElement::setMuted(%s)", boolString(muted));
- if (m_muted != muted) {
- m_muted = muted;
- if (m_player) {
- m_player->setMuted(m_muted);
- if (hasMediaControls())
- mediaControls()->changedMute();
- }
- scheduleEvent(EventTypeNames::volumechange);
- }
-}
-
-void HTMLMediaElement::togglePlayState()
-{
- WTF_LOG(Media, "HTMLMediaElement::togglePlayState - canPlay() is %s", boolString(canPlay()));
-
- // We can safely call the internal play/pause methods, which don't check restrictions, because
- // this method is only called from the built-in media controller
- if (canPlay()) {
- updatePlaybackRate();
- playInternal();
- } else
- pauseInternal();
-}
-
-void HTMLMediaElement::beginScrubbing()
-{
- WTF_LOG(Media, "HTMLMediaElement::beginScrubbing - paused() is %s", boolString(paused()));
+ if (m_muted == muted)
+ return;
- if (!paused()) {
- if (ended()) {
- // Because a media element stays in non-paused state when it reaches end, playback resumes
- // when the slider is dragged from the end to another position unless we pause first. Do
- // a "hard pause" so an event is generated, since we want to stay paused after scrubbing finishes.
- pause();
- } else {
- // Not at the end but we still want to pause playback so the media engine doesn't try to
- // continue playing during scrubbing. Pause without generating an event as we will
- // unpause after scrubbing finishes.
- setPausedInternal(true);
- }
- }
-}
+ m_muted = muted;
-void HTMLMediaElement::endScrubbing()
-{
- WTF_LOG(Media, "HTMLMediaElement::endScrubbing - m_pausedInternal is %s", boolString(m_pausedInternal));
+ updateVolume();
- if (m_pausedInternal)
- setPausedInternal(false);
+ scheduleEvent(EventTypeNames::volumechange);
}
// The spec says to fire periodic timeupdate events (those sent while playing) every
@@ -2371,32 +2327,32 @@ void HTMLMediaElement::startPlaybackProgressTimer()
return;
m_previousProgressTime = WTF::currentTime();
- m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency);
+ m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HERE);
}
void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
{
ASSERT(m_player);
- if (m_fragmentEndTime != MediaPlayer::invalidTime() && currentTime() >= m_fragmentEndTime && m_playbackRate > 0) {
+ if (m_fragmentEndTime != MediaPlayer::invalidTime() && currentTime() >= m_fragmentEndTime && directionOfPlayback() == Forward) {
m_fragmentEndTime = MediaPlayer::invalidTime();
if (!m_mediaController && !m_paused) {
+ UseCounter::count(document(), UseCounter::HTMLMediaElementPauseAtFragmentEnd);
// changes paused to true and fires a simple event named pause at the media element.
- pauseInternal();
+ pause();
}
}
if (!m_seeking)
scheduleTimeupdateEvent(true);
- if (!m_playbackRate)
+ if (!effectivePlaybackRate())
return;
if (!m_paused && hasMediaControls())
mediaControls()->playbackProgressed();
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(currentTime());
+ updateActiveTextTrackCues(currentTime());
}
void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
@@ -2418,38 +2374,139 @@ void HTMLMediaElement::scheduleTimeupdateEvent(bool periodicEvent)
}
}
-bool HTMLMediaElement::canPlay() const
+bool HTMLMediaElement::togglePlayStateWillPlay() const
{
- return paused() || ended() || m_readyState < HAVE_METADATA;
+ if (m_mediaController)
+ return m_mediaController->paused() || m_mediaController->isRestrained();
+ return paused();
}
-double HTMLMediaElement::percentLoaded() const
+void HTMLMediaElement::togglePlayState()
{
- if (!m_player)
+ if (m_mediaController) {
+ if (m_mediaController->isRestrained())
+ m_mediaController->play();
+ else if (m_mediaController->paused())
+ m_mediaController->unpause();
+ else
+ m_mediaController->pause();
+ } else {
+ if (paused())
+ play();
+ else
+ pause();
+ }
+}
+
+AudioTrackList& HTMLMediaElement::audioTracks()
+{
+ ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+ return *m_audioTracks;
+}
+
+void HTMLMediaElement::audioTrackChanged()
+{
+ WTF_LOG(Media, "HTMLMediaElement::audioTrackChanged()");
+ ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+
+ audioTracks().scheduleChangeEvent();
+
+ // FIXME: Add call on m_mediaSource to notify it of track changes once the SourceBuffer.audioTracks attribute is added.
+
+ if (!m_audioTracksTimer.isActive())
+ m_audioTracksTimer.startOneShot(0, FROM_HERE);
+}
+
+void HTMLMediaElement::audioTracksTimerFired(Timer<HTMLMediaElement>*)
+{
+ Vector<WebMediaPlayer::TrackId> enabledTrackIds;
+ for (unsigned i = 0; i < audioTracks().length(); ++i) {
+ AudioTrack* track = audioTracks().anonymousIndexedGetter(i);
+ if (track->enabled())
+ enabledTrackIds.append(track->trackId());
+ }
+
+ webMediaPlayer()->enabledAudioTracksChanged(enabledTrackIds);
+}
+
+WebMediaPlayer::TrackId HTMLMediaElement::addAudioTrack(const String& id, blink::WebMediaPlayerClient::AudioTrackKind kind, const AtomicString& label, const AtomicString& language, bool enabled)
+{
+ AtomicString kindString = AudioKindToString(kind);
+ WTF_LOG(Media, "HTMLMediaElement::addAudioTrack('%s', '%s', '%s', '%s', %d)",
+ id.ascii().data(), kindString.ascii().data(), label.ascii().data(), language.ascii().data(), enabled);
+
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
return 0;
- double duration = m_player->duration();
- if (!duration || std::isinf(duration))
+ RefPtrWillBeRawPtr<AudioTrack> audioTrack = AudioTrack::create(id, kindString, label, language, enabled);
+ audioTracks().add(audioTrack);
+
+ return audioTrack->trackId();
+}
+
+void HTMLMediaElement::removeAudioTrack(WebMediaPlayer::TrackId trackId)
+{
+ WTF_LOG(Media, "HTMLMediaElement::removeAudioTrack()");
+
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
+ return;
+
+ audioTracks().remove(trackId);
+}
+
+VideoTrackList& HTMLMediaElement::videoTracks()
+{
+ ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+ return *m_videoTracks;
+}
+
+void HTMLMediaElement::selectedVideoTrackChanged(WebMediaPlayer::TrackId* selectedTrackId)
+{
+ WTF_LOG(Media, "HTMLMediaElement::selectedVideoTrackChanged()");
+ ASSERT(RuntimeEnabledFeatures::audioVideoTracksEnabled());
+
+ if (selectedTrackId)
+ videoTracks().trackSelected(*selectedTrackId);
+
+ // FIXME: Add call on m_mediaSource to notify it of track changes once the SourceBuffer.videoTracks attribute is added.
+
+ webMediaPlayer()->selectedVideoTrackChanged(selectedTrackId);
+}
+
+WebMediaPlayer::TrackId HTMLMediaElement::addVideoTrack(const String& id, blink::WebMediaPlayerClient::VideoTrackKind kind, const AtomicString& label, const AtomicString& language, bool selected)
+{
+ AtomicString kindString = VideoKindToString(kind);
+ WTF_LOG(Media, "HTMLMediaElement::addVideoTrack('%s', '%s', '%s', '%s', %d)",
+ id.ascii().data(), kindString.ascii().data(), label.ascii().data(), language.ascii().data(), selected);
+
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
return 0;
- double buffered = 0;
- RefPtr<TimeRanges> timeRanges = m_player->buffered();
- for (unsigned i = 0; i < timeRanges->length(); ++i) {
- double start = timeRanges->start(i, IGNORE_EXCEPTION);
- double end = timeRanges->end(i, IGNORE_EXCEPTION);
- buffered += end - start;
- }
- return buffered / duration;
+ // If another track was selected (potentially by the user), leave it selected.
+ if (selected && videoTracks().selectedIndex() != -1)
+ selected = false;
+
+ RefPtrWillBeRawPtr<VideoTrack> videoTrack = VideoTrack::create(id, kindString, label, language, selected);
+ videoTracks().add(videoTrack);
+
+ return videoTrack->trackId();
}
-void HTMLMediaElement::mediaPlayerDidAddTrack(WebInbandTextTrack* webTrack)
+void HTMLMediaElement::removeVideoTrack(WebMediaPlayer::TrackId trackId)
{
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
+ WTF_LOG(Media, "HTMLMediaElement::removeVideoTrack()");
+
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
return;
+ videoTracks().remove(trackId);
+}
+
+void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack)
+{
// 4.8.10.12.2 Sourcing in-band text tracks
// 1. Associate the relevant data with a new text track and its corresponding new TextTrack object.
- RefPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), this, webTrack);
+ RefPtrWillBeRawPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), webTrack);
// 2. Set the new text track's kind, label, and language based on the semantics of the relevant data,
// as defined by the relevant specification. If there is no label in that data, then the label must
@@ -2474,24 +2531,21 @@ void HTMLMediaElement::mediaPlayerDidAddTrack(WebInbandTextTrack* webTrack)
// 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent
// interface, with the track attribute initialized to the text track's TextTrack object, at the media element's
// textTracks attribute's TextTrackList object.
- addTrack(textTrack.get());
+ addTextTrack(textTrack.get());
}
-void HTMLMediaElement::mediaPlayerDidRemoveTrack(WebInbandTextTrack* webTrack)
+void HTMLMediaElement::mediaPlayerDidRemoveTextTrack(WebInbandTextTrack* webTrack)
{
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
- return;
-
if (!m_textTracks)
return;
// This cast is safe because we created the InbandTextTrack with the WebInbandTextTrack
- // passed to mediaPlayerDidAddTrack.
- RefPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack->client());
+ // passed to mediaPlayerDidAddTextTrack.
+ RefPtrWillBeRawPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack->client());
if (!textTrack)
return;
- removeTrack(textTrack.get());
+ removeTextTrack(textTrack.get());
}
void HTMLMediaElement::closeCaptionTracksChanged()
@@ -2500,49 +2554,47 @@ void HTMLMediaElement::closeCaptionTracksChanged()
mediaControls()->closedCaptionTracksChanged();
}
-void HTMLMediaElement::addTrack(TextTrack* track)
+void HTMLMediaElement::addTextTrack(TextTrack* track)
{
textTracks()->append(track);
closeCaptionTracksChanged();
}
-void HTMLMediaElement::removeTrack(TextTrack* track)
+void HTMLMediaElement::removeTextTrack(TextTrack* track)
{
TrackDisplayUpdateScope scope(this);
- TextTrackCueList* cues = track->cues();
- if (cues)
- textTrackRemoveCues(track, cues);
m_textTracks->remove(track);
closeCaptionTracksChanged();
}
-void HTMLMediaElement::removeAllInbandTracks()
+void HTMLMediaElement::forgetResourceSpecificTracks()
{
- if (!m_textTracks)
- return;
+ // Implements the "forget the media element's media-resource-specific tracks" algorithm.
+ // The order is explicitly specified as text, then audio, and finally video. Also
+ // 'removetrack' events should not be fired.
+ if (m_textTracks) {
+ TrackDisplayUpdateScope scope(this);
+ m_textTracks->removeAllInbandTracks();
+ closeCaptionTracksChanged();
+ }
- TrackDisplayUpdateScope scope(this);
- for (int i = m_textTracks->length() - 1; i >= 0; --i) {
- TextTrack* track = m_textTracks->item(i);
+ m_audioTracks->removeAll();
+ m_videoTracks->removeAll();
- if (track->trackType() == TextTrack::InBand)
- removeTrack(track);
- }
+ m_audioTracksTimer.stop();
}
-PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const String& kind, const String& label, const String& language, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<TextTrack> HTMLMediaElement::addTextTrack(const AtomicString& kind, const AtomicString& label, const AtomicString& language, ExceptionState& exceptionState)
{
- ASSERT(RuntimeEnabledFeatures::videoTrackEnabled());
-
// 4.8.10.12.4 Text track API
// The addTextTrack(kind, label, language) method of media elements, when invoked, must run the following steps:
// 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps
if (!TextTrack::isValidKindKeyword(kind)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return 0;
+ exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid.");
+ return nullptr;
}
// 2. If the label argument was omitted, let label be the empty string.
@@ -2551,13 +2603,13 @@ PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const String& kind, const S
// 5. Create a new text track corresponding to the new object, and set its text track kind to kind, its text
// track label to label, its text track language to language...
- RefPtr<TextTrack> textTrack = TextTrack::create(document(), this, kind, label, language);
+ RefPtrWillBeRawPtr<TextTrack> textTrack = TextTrack::create(document(), kind, label, language);
// Note, due to side effects when changing track parameters, we have to
// first append the track to the text track list.
// 6. Add the new text track to the media element's list of text tracks.
- addTrack(textTrack.get());
+ addTextTrack(textTrack.get());
// ... its text track readiness state to the text track loaded state ...
textTrack->setReadinessState(TextTrack::Loaded);
@@ -2570,55 +2622,41 @@ PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const String& kind, const S
TextTrackList* HTMLMediaElement::textTracks()
{
- ASSERT(RuntimeEnabledFeatures::videoTrackEnabled());
-
if (!m_textTracks)
m_textTracks = TextTrackList::create(this);
return m_textTracks.get();
}
-void HTMLMediaElement::didAddTrack(HTMLTrackElement* trackElement)
+void HTMLMediaElement::didAddTrackElement(HTMLTrackElement* trackElement)
{
- ASSERT(trackElement->hasTagName(trackTag));
-
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
- return;
-
// 4.8.10.12.3 Sourcing out-of-band text tracks
// When a track element's parent element changes and the new parent is a media element,
// then the user agent must add the track element's corresponding text track to the
// media element's list of text tracks ... [continues in TextTrackList::append]
- RefPtr<TextTrack> textTrack = trackElement->track();
+ RefPtrWillBeRawPtr<TextTrack> textTrack = trackElement->track();
if (!textTrack)
return;
- addTrack(textTrack.get());
+ addTextTrack(textTrack.get());
// Do not schedule the track loading until parsing finishes so we don't start before all tracks
// in the markup have been added.
- if (!m_parsingInProgress)
+ if (isFinishedParsingChildren())
scheduleDelayedAction(LoadTextTrackResource);
if (hasMediaControls())
mediaControls()->closedCaptionTracksChanged();
}
-void HTMLMediaElement::didRemoveTrack(HTMLTrackElement* trackElement)
+void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement)
{
- ASSERT(trackElement->hasTagName(trackTag));
-
- if (!RuntimeEnabledFeatures::videoTrackEnabled())
- return;
-
#if !LOG_DISABLED
- if (trackElement->hasTagName(trackTag)) {
- KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
- WTF_LOG(Media, "HTMLMediaElement::didRemoveTrack - 'src' is %s", urlForLoggingMedia(url).utf8().data());
- }
+ KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
+ WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement - 'src' is %s", urlForLoggingMedia(url).utf8().data());
#endif
- RefPtr<TextTrack> textTrack = trackElement->track();
+ RefPtrWillBeRawPtr<TextTrack> textTrack = trackElement->track();
if (!textTrack)
return;
@@ -2631,7 +2669,7 @@ void HTMLMediaElement::didRemoveTrack(HTMLTrackElement* trackElement)
// When a track element's parent element changes and the old parent was a media element,
// then the user agent must remove the track element's corresponding text track from the
// media element's list of text tracks.
- removeTrack(textTrack.get());
+ removeTextTrack(textTrack.get());
size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack.get());
if (index != kNotFound)
@@ -2643,32 +2681,20 @@ static int textTrackLanguageSelectionScore(const TextTrack& track)
if (track.language().isEmpty())
return 0;
- Vector<String> languages = userPreferredLanguages();
+ Vector<AtomicString> languages = userPreferredLanguages();
size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track.language(), languages);
if (languageMatchIndex >= languages.size())
return 0;
- // Matching a track language is more important than matching track type, so this multiplier must be
- // greater than the maximum value returned by textTrackSelectionScore.
- return (languages.size() - languageMatchIndex) * 10;
+ return languages.size() - languageMatchIndex;
}
-static int textTrackSelectionScore(const TextTrack& track, Settings* settings)
+static int textTrackSelectionScore(const TextTrack& track)
{
- int trackScore = 0;
-
- if (!settings)
- return trackScore;
-
if (track.kind() != TextTrack::captionsKeyword() && track.kind() != TextTrack::subtitlesKeyword())
- return trackScore;
-
- if (track.kind() == TextTrack::subtitlesKeyword() && settings->shouldDisplaySubtitles())
- trackScore = 1;
- else if (track.kind() == TextTrack::captionsKeyword() && settings->shouldDisplayCaptions())
- trackScore = 1;
+ return 0;
- return trackScore + textTrackLanguageSelectionScore(track);
+ return textTrackLanguageSelectionScore(track);
}
void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
@@ -2677,21 +2703,19 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
WTF_LOG(Media, "HTMLMediaElement::configureTextTrackGroup(%d)", group.kind);
- Settings* settings = document().settings();
-
// First, find the track in the group that should be enabled (if any).
- Vector<RefPtr<TextTrack> > currentlyEnabledTracks;
- RefPtr<TextTrack> trackToEnable;
- RefPtr<TextTrack> defaultTrack;
- RefPtr<TextTrack> fallbackTrack;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > currentlyEnabledTracks;
+ RefPtrWillBeRawPtr<TextTrack> trackToEnable = nullptr;
+ RefPtrWillBeRawPtr<TextTrack> defaultTrack = nullptr;
+ RefPtrWillBeRawPtr<TextTrack> fallbackTrack = nullptr;
int highestTrackScore = 0;
for (size_t i = 0; i < group.tracks.size(); ++i) {
- RefPtr<TextTrack> textTrack = group.tracks[i];
+ RefPtrWillBeRawPtr<TextTrack> textTrack = group.tracks[i];
if (m_processingPreferenceChange && textTrack->mode() == TextTrack::showingKeyword())
currentlyEnabledTracks.append(textTrack);
- int trackScore = textTrackSelectionScore(*textTrack, settings);
+ int trackScore = textTrackSelectionScore(*textTrack);
if (trackScore) {
// * If the text track kind is { [subtitles or captions] [descriptions] } and the user has indicated an interest in having a
// track with this text track kind, text track language, and text track label enabled, and there is no
@@ -2732,7 +2756,7 @@ void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group)
if (currentlyEnabledTracks.size()) {
for (size_t i = 0; i < currentlyEnabledTracks.size(); ++i) {
- RefPtr<TextTrack> textTrack = currentlyEnabledTracks[i];
+ RefPtrWillBeRawPtr<TextTrack> textTrack = currentlyEnabledTracks[i];
if (textTrack != trackToEnable)
textTrack->setMode(TextTrack::disabledKeyword());
}
@@ -2754,7 +2778,7 @@ void HTMLMediaElement::configureTextTracks()
return;
for (size_t i = 0; i < m_textTracks->length(); ++i) {
- RefPtr<TextTrack> textTrack = m_textTracks->item(i);
+ RefPtrWillBeRawPtr<TextTrack> textTrack = m_textTracks->item(i);
if (!textTrack)
continue;
@@ -2809,8 +2833,8 @@ bool HTMLMediaElement::havePotentialSourceChild()
{
// Stash the current <source> node and next nodes so we can restore them after checking
// to see there is another potential.
- RefPtr<HTMLSourceElement> currentSourceNode = m_currentSourceNode;
- RefPtr<Node> nextNode = m_nextChildNodeToConsider;
+ RefPtrWillBeRawPtr<HTMLSourceElement> currentSourceNode = m_currentSourceNode;
+ RefPtrWillBeRawPtr<Node> nextNode = m_nextChildNodeToConsider;
KURL nextURL = selectNextSourceChild(0, 0, DoNothing);
@@ -2844,7 +2868,6 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* k
String system;
bool lookingForStartNode = m_nextChildNodeToConsider;
bool canUseSourceElement = false;
- bool okToLoadSourceURL;
NodeVector potentialSourceNodes;
getChildNodes(*this, potentialSourceNodes);
@@ -2855,12 +2878,11 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* k
continue;
lookingForStartNode = false;
- if (!node->hasTagName(sourceTag))
+ if (!isHTMLSourceElement(*node))
continue;
if (node->parentNode() != this)
continue;
- UseCounter::count(document(), UseCounter::SourceElementCandidate);
source = toHTMLSourceElement(node);
// If candidate does not have a src attribute, or if its src attribute's value is the empty string ... jump down to the failed step below
@@ -2872,19 +2894,6 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* k
if (mediaURL.isEmpty())
goto check_again;
- if (source->fastHasAttribute(mediaAttr)) {
- MediaQueryEvaluator screenEval("screen", document().frame(), renderer() ? renderer()->style() : 0);
- RefPtr<MediaQuerySet> media = MediaQuerySet::create(source->media());
-#if !LOG_DISABLED
- if (shouldLog)
- WTF_LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'media' is %s", source->media().string().utf8().data());
-#endif
- if (!screenEval.eval(media.get())) {
- UseCounter::count(document(), UseCounter::SourceElementNonMatchingMedia);
- goto check_again;
- }
- }
-
type = source->type();
// FIXME(82965): Add support for keySystem in <source> and set system from source.
if (type.isEmpty() && mediaURL.protocolIsData())
@@ -2899,16 +2908,7 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType* contentType, String* k
}
// Is it safe to load this url?
- okToLoadSourceURL = isSafeToLoadURL(mediaURL, actionIfInvalid) && dispatchBeforeLoadEvent(mediaURL.string());
-
- // A 'beforeload' event handler can mutate the DOM, so check to see if the source element is still a child node.
- if (node->parentNode() != this) {
- WTF_LOG(Media, "HTMLMediaElement::selectNextSourceChild : 'beforeload' removed current element");
- source = 0;
- goto check_again;
- }
-
- if (!okToLoadSourceURL)
+ if (!isSafeToLoadURL(mediaURL, actionIfInvalid))
goto check_again;
// Making it this far means the <source> looks reasonable.
@@ -2927,8 +2927,8 @@ check_again:
m_currentSourceNode = source;
m_nextChildNodeToConsider = source->nextSibling();
} else {
- m_currentSourceNode = 0;
- m_nextChildNodeToConsider = 0;
+ m_currentSourceNode = nullptr;
+ m_nextChildNodeToConsider = nullptr;
}
#if !LOG_DISABLED
@@ -2943,10 +2943,8 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p)", source);
#if !LOG_DISABLED
- if (source->hasTagName(sourceTag)) {
- KURL url = source->getNonEmptyURLAttribute(srcAttr);
- WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLoggingMedia(url).utf8().data());
- }
+ KURL url = source->getNonEmptyURLAttribute(srcAttr);
+ WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLoggingMedia(url).utf8().data());
#endif
// We should only consider a <source> element when there is not src attribute at all.
@@ -2991,10 +2989,8 @@ void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source)
WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p)", source);
#if !LOG_DISABLED
- if (source->hasTagName(sourceTag)) {
- KURL url = source->getNonEmptyURLAttribute(srcAttr);
- WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved - 'src' is %s", urlForLoggingMedia(url).utf8().data());
- }
+ KURL url = source->getNonEmptyURLAttribute(srcAttr);
+ WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved - 'src' is %s", urlForLoggingMedia(url).utf8().data());
#endif
if (source != m_currentSourceNode && source != m_nextChildNodeToConsider)
@@ -3008,7 +3004,7 @@ void HTMLMediaElement::sourceWasRemoved(HTMLSourceElement* source)
// Clear the current source node pointer, but don't change the movie as the spec says:
// 4.8.8 - Dynamically modifying a source element and its attribute when the element is already
// inserted in a video or audio element will have no effect.
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
WTF_LOG(Media, "HTMLMediaElement::sourceRemoved - m_currentSourceNode set to 0");
}
}
@@ -3017,8 +3013,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged()
{
WTF_LOG(Media, "HTMLMediaElement::mediaPlayerTimeChanged");
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(currentTime());
+ updateActiveTextTrackCues(currentTime());
invalidateCachedTime();
@@ -3036,7 +3031,7 @@ void HTMLMediaElement::mediaPlayerTimeChanged()
// When the current playback position reaches the end of the media resource when the direction of
// playback is forwards, then the user agent must follow these steps:
- if (!std::isnan(dur) && dur && now >= dur && m_playbackRate > 0) {
+ if (!std::isnan(dur) && dur && now >= dur && directionOfPlayback() == Forward) {
// If the media element has a loop attribute specified and does not have a current media controller,
if (loop() && !m_mediaController) {
m_sentEndEvent = false;
@@ -3070,17 +3065,22 @@ void HTMLMediaElement::mediaPlayerTimeChanged()
void HTMLMediaElement::mediaPlayerDurationChanged()
{
WTF_LOG(Media, "HTMLMediaElement::mediaPlayerDurationChanged");
- durationChanged(duration());
+ // FIXME: Change MediaPlayerClient & WebMediaPlayer to convey
+ // the currentTime when the duration change occured. The current
+ // WebMediaPlayer implementations always clamp currentTime() to
+ // duration() so the requestSeek condition here is always false.
+ durationChanged(duration(), currentTime() > duration());
}
-void HTMLMediaElement::durationChanged(double duration)
+void HTMLMediaElement::durationChanged(double duration, bool requestSeek)
{
- WTF_LOG(Media, "HTMLMediaElement::durationChanged(%f)", duration);
+ WTF_LOG(Media, "HTMLMediaElement::durationChanged(%f, %d)", duration, requestSeek);
// Abort if duration unchanged.
if (m_duration == duration)
return;
+ WTF_LOG(Media, "HTMLMediaElement::durationChanged : %f -> %f", m_duration, duration);
m_duration = duration;
scheduleEvent(EventTypeNames::durationchange);
@@ -3089,7 +3089,7 @@ void HTMLMediaElement::durationChanged(double duration)
if (renderer())
renderer()->updateFromElement();
- if (currentTime() > duration)
+ if (requestSeek)
seek(duration, IGNORE_EXCEPTION);
}
@@ -3101,7 +3101,7 @@ void HTMLMediaElement::mediaPlayerPlaybackStateChanged()
return;
if (m_player->paused())
- pauseInternal();
+ pause();
else
playInternal();
}
@@ -3109,6 +3109,11 @@ void HTMLMediaElement::mediaPlayerPlaybackStateChanged()
void HTMLMediaElement::mediaPlayerRequestFullscreen()
{
WTF_LOG(Media, "HTMLMediaElement::mediaPlayerRequestFullscreen");
+
+ // The player is responsible for only invoking this callback in response to
+ // user interaction or when it is technically required to play the video.
+ UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
+
enterFullscreen();
}
@@ -3130,14 +3135,15 @@ void HTMLMediaElement::mediaPlayerRepaint()
updateDisplayState();
if (renderer())
- renderer()->repaint();
+ renderer()->paintInvalidationForWholeRenderer();
}
void HTMLMediaElement::mediaPlayerSizeChanged()
{
WTF_LOG(Media, "HTMLMediaElement::mediaPlayerSizeChanged");
- if (m_readyState > HAVE_NOTHING)
+ ASSERT(hasVideo()); // "resize" makes no sense absent video.
+ if (m_readyState > HAVE_NOTHING && isHTMLVideoElement(*this))
scheduleEvent(EventTypeNames::resize);
if (renderer())
@@ -3190,7 +3196,7 @@ bool HTMLMediaElement::potentiallyPlaying() const
bool HTMLMediaElement::couldPlayIfEnoughData() const
{
- return !paused() && !endedPlayback() && !stoppedDueToErrors() && !pausedForUserInteraction();
+ return !paused() && !endedPlayback() && !stoppedDueToErrors();
}
bool HTMLMediaElement::endedPlayback() const
@@ -3210,15 +3216,13 @@ bool HTMLMediaElement::endedPlayback() const
// of playback is forwards, Either the media element does not have a loop attribute specified,
// or the media element has a current media controller.
double now = currentTime();
- if (m_playbackRate > 0)
+ if (directionOfPlayback() == Forward)
return dur > 0 && now >= dur && (!loop() || m_mediaController);
// or the current playback position is the earliest possible position and the direction
// of playback is backwards
- if (m_playbackRate < 0)
- return now <= 0;
-
- return false;
+ ASSERT(directionOfPlayback() == Backward);
+ return now <= 0;
}
bool HTMLMediaElement::stoppedDueToErrors() const
@@ -3232,17 +3236,17 @@ bool HTMLMediaElement::stoppedDueToErrors() const
return false;
}
-bool HTMLMediaElement::pausedForUserInteraction() const
+void HTMLMediaElement::updateVolume()
{
-// return !paused() && m_readyState >= HAVE_FUTURE_DATA && [UA requires a decitions from the user]
- return false;
+ if (webMediaPlayer())
+ webMediaPlayer()->setVolume(playerVolume());
+
+ if (hasMediaControls())
+ mediaControls()->updateVolume();
}
-void HTMLMediaElement::updateVolume()
+double HTMLMediaElement::playerVolume() const
{
- if (!m_player)
- return;
-
double volumeMultiplier = 1;
bool shouldMute = m_muted;
@@ -3251,11 +3255,7 @@ void HTMLMediaElement::updateVolume()
shouldMute = m_mediaController->muted();
}
- m_player->setMuted(shouldMute);
- m_player->setVolume(m_volume * volumeMultiplier);
-
- if (hasMediaControls())
- mediaControls()->changedVolume();
+ return shouldMute ? 0 : m_volume * volumeMultiplier;
}
void HTMLMediaElement::updatePlayState()
@@ -3286,8 +3286,8 @@ void HTMLMediaElement::updatePlayState()
if (playerPaused) {
// Set rate, muted before calling play in case they were set before the media engine was setup.
// The media engine should just stash the rate and muted values since it isn't already playing.
- m_player->setRate(m_playbackRate);
- m_player->setMuted(m_muted);
+ m_player->setRate(effectivePlaybackRate());
+ updateVolume();
m_player->play();
}
@@ -3368,40 +3368,42 @@ void HTMLMediaElement::userCancelledLoad()
setShouldDelayLoadEvent(false);
// 6 - Abort the overall resource selection algorithm.
- m_currentSourceNode = 0;
+ m_currentSourceNode = nullptr;
// Reset m_readyState since m_player is gone.
m_readyState = HAVE_NOTHING;
updateMediaController();
- if (RuntimeEnabledFeatures::videoTrackEnabled())
- updateActiveTextTrackCues(0);
+ updateActiveTextTrackCues(0);
}
-void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClient()
+void HTMLMediaElement::clearMediaPlayerAndAudioSourceProviderClientWithoutLocking()
{
#if ENABLE(WEB_AUDIO)
- if (m_audioSourceNode)
- m_audioSourceNode->lock();
-
if (audioSourceProvider())
audioSourceProvider()->setClient(0);
#endif
-
m_player.clear();
-
-#if ENABLE(WEB_AUDIO)
- if (m_audioSourceNode)
- m_audioSourceNode->unlock();
-#endif
}
void HTMLMediaElement::clearMediaPlayer(int flags)
{
- removeAllInbandTracks();
+ forgetResourceSpecificTracks();
closeMediaSource();
- clearMediaPlayerAndAudioSourceProviderClient();
+ cancelDeferredLoad();
+
+#if ENABLE(WEB_AUDIO)
+ if (m_audioSourceNode)
+ m_audioSourceNode->lock();
+#endif
+
+ clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
+
+#if ENABLE(WEB_AUDIO)
+ if (m_audioSourceNode)
+ m_audioSourceNode->unlock();
+#endif
stopPeriodicTimers();
m_loadTimer.stop();
@@ -3440,8 +3442,12 @@ bool HTMLMediaElement::hasPendingActivity() const
void HTMLMediaElement::contextDestroyed()
{
+ // With Oilpan the ExecutionContext is weakly referenced from the media
+ // controller and so it will clear itself on destruction.
+#if !ENABLE(OILPAN)
if (m_mediaController)
m_mediaController->clearExecutionContext();
+#endif
ActiveDOMObject::contextDestroyed();
}
@@ -3454,32 +3460,30 @@ void HTMLMediaElement::enterFullscreen()
{
WTF_LOG(Media, "HTMLMediaElement::enterFullscreen");
- if (document().settings() && document().settings()->fullScreenEnabled())
- FullscreenElementStack::from(&document())->requestFullScreenForElement(this, 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
+ FullscreenElementStack::from(document()).requestFullScreenForElement(this, 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
}
void HTMLMediaElement::exitFullscreen()
{
WTF_LOG(Media, "HTMLMediaElement::exitFullscreen");
- if (document().settings() && document().settings()->fullScreenEnabled() && isFullscreen())
- FullscreenElementStack::from(&document())->webkitCancelFullScreen();
+ FullscreenElementStack::from(document()).webkitCancelFullScreen();
}
void HTMLMediaElement::didBecomeFullscreenElement()
{
if (hasMediaControls())
mediaControls()->enteredFullscreen();
- if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isVideo())
- document().renderView()->compositor()->setCompositingLayersNeedRebuild(true);
+ if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isHTMLVideoElement(*this))
+ document().renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
}
void HTMLMediaElement::willStopBeingFullscreenElement()
{
if (hasMediaControls())
mediaControls()->exitedFullscreen();
- if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isVideo())
- document().renderView()->compositor()->setCompositingLayersNeedRebuild(true);
+ if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isHTMLVideoElement(*this))
+ document().renderView()->compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
}
blink::WebLayer* HTMLMediaElement::platformLayer() const
@@ -3489,7 +3493,7 @@ blink::WebLayer* HTMLMediaElement::platformLayer() const
bool HTMLMediaElement::hasClosedCaptions() const
{
- if (RuntimeEnabledFeatures::videoTrackEnabled() && m_textTracks) {
+ if (m_textTracks) {
for (unsigned i = 0; i < m_textTracks->length(); ++i) {
if (m_textTracks->item(i)->readinessState() == TextTrack::FailedToLoad)
continue;
@@ -3526,27 +3530,25 @@ void HTMLMediaElement::setClosedCaptionsVisible(bool closedCaptionVisible)
m_closedCaptionsVisible = closedCaptionVisible;
- if (RuntimeEnabledFeatures::videoTrackEnabled()) {
- m_processingPreferenceChange = true;
- markCaptionAndSubtitleTracksAsUnconfigured();
- m_processingPreferenceChange = false;
+ m_processingPreferenceChange = true;
+ markCaptionAndSubtitleTracksAsUnconfigured();
+ m_processingPreferenceChange = false;
- updateTextTrackDisplay();
- }
+ updateTextTrackDisplay();
}
unsigned HTMLMediaElement::webkitAudioDecodedByteCount() const
{
- if (!m_player)
+ if (!webMediaPlayer())
return 0;
- return m_player->audioDecodedByteCount();
+ return webMediaPlayer()->audioDecodedByteCount();
}
unsigned HTMLMediaElement::webkitVideoDecodedByteCount() const
{
- if (!m_player)
+ if (!webMediaPlayer())
return 0;
- return m_player->videoDecodedByteCount();
+ return webMediaPlayer()->videoDecodedByteCount();
}
bool HTMLMediaElement::isURLAttribute(const Attribute& attribute) const
@@ -3590,11 +3592,10 @@ bool HTMLMediaElement::createMediaControls()
if (hasMediaControls())
return true;
- RefPtr<MediaControls> mediaControls = MediaControls::create(document());
+ RefPtrWillBeRawPtr<MediaControls> mediaControls = MediaControls::create(*this);
if (!mediaControls)
return false;
- mediaControls->setMediaController(m_mediaController ? m_mediaController.get() : static_cast<MediaControllerInterface*>(this));
mediaControls->reset();
if (isFullscreen())
mediaControls->enteredFullscreen();
@@ -3618,6 +3619,7 @@ void HTMLMediaElement::configureMediaControls()
if (!hasMediaControls() && !createMediaControls())
return;
+ mediaControls()->reset();
mediaControls()->show();
}
@@ -3652,10 +3654,8 @@ void HTMLMediaElement::configureTextTrackDisplay(VisibilityChangeAssumption assu
mediaControls()->changedClosedCaptionsVisibility();
- if (RuntimeEnabledFeatures::videoTrackEnabled()) {
- updateActiveTextTrackCues(currentTime());
- updateTextTrackDisplay();
- }
+ updateActiveTextTrackCues(currentTime());
+ updateTextTrackDisplay();
}
void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured()
@@ -3669,7 +3669,7 @@ void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured()
// captions and non-default tracks should be displayed based on language
// preferences if the user has turned captions on).
for (unsigned i = 0; i < m_textTracks->length(); ++i) {
- RefPtr<TextTrack> textTrack = m_textTracks->item(i);
+ RefPtrWillBeRawPtr<TextTrack> textTrack = m_textTracks->item(i);
String kind = textTrack->kind();
if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword())
@@ -3678,7 +3678,6 @@ void HTMLMediaElement::markCaptionAndSubtitleTracksAsUnconfigured()
configureTextTracks();
}
-
void* HTMLMediaElement::preDispatchEventHandler(Event* event)
{
if (event && event->type() == EventTypeNames::webkitfullscreenchange)
@@ -3694,14 +3693,13 @@ void HTMLMediaElement::createMediaPlayer()
m_audioSourceNode->lock();
#endif
- if (m_mediaSource)
- closeMediaSource();
+ closeMediaSource();
m_player = MediaPlayer::create(this);
#if ENABLE(WEB_AUDIO)
if (m_audioSourceNode) {
- // When creating the player, make sure its AudioSourceProvider knows about the MediaElementAudioSourceNode.
+ // When creating the player, make sure its AudioSourceProvider knows about the client.
if (audioSourceProvider())
audioSourceProvider()->setClient(m_audioSourceNode);
@@ -3711,7 +3709,7 @@ void HTMLMediaElement::createMediaPlayer()
}
#if ENABLE(WEB_AUDIO)
-void HTMLMediaElement::setAudioSourceNode(MediaElementAudioSourceNode* sourceNode)
+void HTMLMediaElement::setAudioSourceNode(AudioSourceProviderClient* sourceNode)
{
m_audioSourceNode = sourceNode;
@@ -3745,7 +3743,7 @@ void HTMLMediaElement::setMediaGroup(const AtomicString& group)
// attribute is set, changed, or removed, the user agent must run the following steps:
// 1. Let m [this] be the media element in question.
// 2. Let m have no current media controller, if it currently has one.
- setControllerInternal(0);
+ setControllerInternal(nullptr);
// 3. If m's mediagroup attribute is being removed, then abort these steps.
if (group.isNull() || group.isEmpty())
@@ -3753,8 +3751,8 @@ void HTMLMediaElement::setMediaGroup(const AtomicString& group)
// 4. If there is another media element whose Document is the same as m's Document (even if one or both
// of these elements are not actually in the Document),
- HashSet<HTMLMediaElement*> elements = documentToElementSetMap().get(&document());
- for (HashSet<HTMLMediaElement*>::iterator i = elements.begin(); i != elements.end(); ++i) {
+ WeakMediaElementSet elements = documentToElementSetMap().get(&document());
+ for (WeakMediaElementSet::iterator i = elements.begin(); i != elements.end(); ++i) {
if (*i == this)
continue;
@@ -3776,7 +3774,7 @@ MediaController* HTMLMediaElement::controller() const
return m_mediaController.get();
}
-void HTMLMediaElement::setController(PassRefPtr<MediaController> controller)
+void HTMLMediaElement::setController(PassRefPtrWillBeRawPtr<MediaController> controller)
{
// 4.8.10.11.2 Media controllers: controller attribute.
// On setting, it must first remove the element's mediagroup attribute, if any,
@@ -3785,7 +3783,7 @@ void HTMLMediaElement::setController(PassRefPtr<MediaController> controller)
setControllerInternal(controller);
}
-void HTMLMediaElement::setControllerInternal(PassRefPtr<MediaController> controller)
+void HTMLMediaElement::setControllerInternal(PassRefPtrWillBeRawPtr<MediaController> controller)
{
if (m_mediaController)
m_mediaController->removeMediaElement(this);
@@ -3794,9 +3792,6 @@ void HTMLMediaElement::setControllerInternal(PassRefPtr<MediaController> control
if (m_mediaController)
m_mediaController->addMediaElement(this);
-
- if (hasMediaControls())
- mediaControls()->setMediaController(m_mediaController ? m_mediaController.get() : static_cast<MediaControllerInterface*>(this));
}
void HTMLMediaElement::updateMediaController()
@@ -3809,11 +3804,11 @@ bool HTMLMediaElement::isBlocked() const
{
// A media element is a blocked media element if its readyState attribute is in the
// HAVE_NOTHING state, the HAVE_METADATA state, or the HAVE_CURRENT_DATA state,
+ // or if the element has paused for user interaction or paused for in-band content.
if (m_readyState <= HAVE_CURRENT_DATA)
return true;
- // or if the element has paused for user interaction.
- return pausedForUserInteraction();
+ return false;
}
bool HTMLMediaElement::isBlockedOnMediaController() const
@@ -3857,6 +3852,8 @@ void HTMLMediaElement::prepareMediaFragmentURI()
} else
m_fragmentEndTime = MediaPlayer::invalidTime();
+ // FIXME: Add support for selecting tracks by ID with the Media Fragments track dimension.
+
if (m_fragmentStartTime != MediaPlayer::invalidTime() && m_readyState < HAVE_FUTURE_DATA)
prepareToPlay();
}
@@ -3865,22 +3862,19 @@ void HTMLMediaElement::applyMediaFragmentURI()
{
if (m_fragmentStartTime != MediaPlayer::invalidTime()) {
m_sentEndEvent = false;
+ UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragmentStart);
seek(m_fragmentStartTime, IGNORE_EXCEPTION);
}
}
-MediaPlayerClient::CORSMode HTMLMediaElement::mediaPlayerCORSMode() const
+WebMediaPlayer::CORSMode HTMLMediaElement::corsMode() const
{
- if (!fastHasAttribute(crossoriginAttr))
- return Unspecified;
- if (equalIgnoringCase(fastGetAttribute(crossoriginAttr), "use-credentials"))
- return UseCredentials;
- return Anonymous;
-}
-
-void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
-{
- m_restrictions = NoRestrictions;
+ const AtomicString& crossOriginMode = fastGetAttribute(crossoriginAttr);
+ if (crossOriginMode.isNull())
+ return WebMediaPlayer::CORSModeUnspecified;
+ if (equalIgnoringCase(crossOriginMode, "use-credentials"))
+ return WebMediaPlayer::CORSModeUseCredentials;
+ return WebMediaPlayer::CORSModeAnonymous;
}
void HTMLMediaElement::mediaPlayerSetWebLayer(blink::WebLayer* webLayer)
@@ -3890,22 +3884,19 @@ void HTMLMediaElement::mediaPlayerSetWebLayer(blink::WebLayer* webLayer)
// If either of the layers is null we need to enable or disable compositing. This is done by triggering a style recalc.
if (!m_webLayer || !webLayer)
- scheduleLayerUpdate();
+ setNeedsCompositingUpdate();
if (m_webLayer)
GraphicsLayer::unregisterContentsLayer(m_webLayer);
m_webLayer = webLayer;
if (m_webLayer) {
- m_webLayer->setOpaque(m_opaque);
GraphicsLayer::registerContentsLayer(m_webLayer);
}
}
-void HTMLMediaElement::mediaPlayerSetOpaque(bool opaque)
+void HTMLMediaElement::mediaPlayerMediaSourceOpened(blink::WebMediaSource* webMediaSource)
{
- m_opaque = opaque;
- if (m_webLayer)
- m_webLayer->setOpaque(m_opaque);
+ m_mediaSource->setWebMediaSourceAndOpen(adoptPtr(webMediaSource));
}
bool HTMLMediaElement::isInteractiveContent() const
@@ -3913,4 +3904,67 @@ bool HTMLMediaElement::isInteractiveContent() const
return fastHasAttribute(controlsAttr);
}
+void HTMLMediaElement::defaultEventHandler(Event* event)
+{
+ if (event->type() == EventTypeNames::focusin) {
+ if (hasMediaControls())
+ mediaControls()->mediaElementFocused();
+ }
+ HTMLElement::defaultEventHandler(event);
+}
+
+void HTMLMediaElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_asyncEventQueue);
+ visitor->trace(m_error);
+ visitor->trace(m_currentSourceNode);
+ visitor->trace(m_nextChildNodeToConsider);
+ visitor->trace(m_audioTracks);
+ visitor->trace(m_videoTracks);
+ visitor->trace(m_textTracks);
+ visitor->trace(m_textTracksWhenResourceSelectionBegan);
+ visitor->trace(m_mediaController);
+#if ENABLE(WEB_AUDIO)
+ visitor->registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::clearWeakMembers>(this);
+#endif
+ WillBeHeapSupplementable<HTMLMediaElement>::trace(visitor);
+ HTMLElement::trace(visitor);
+}
+
+void HTMLMediaElement::createPlaceholderTracksIfNecessary()
+{
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
+ return;
+
+ // Create a placeholder audio track if the player says it has audio but it didn't explicitly announce the tracks.
+ if (hasAudio() && !audioTracks().length())
+ addAudioTrack("audio", WebMediaPlayerClient::AudioTrackKindMain, "Audio Track", "", true);
+
+ // Create a placeholder video track if the player says it has video but it didn't explicitly announce the tracks.
+ if (webMediaPlayer() && webMediaPlayer()->hasVideo() && !videoTracks().length())
+ addVideoTrack("video", WebMediaPlayerClient::VideoTrackKindMain, "Video Track", "", true);
+}
+
+void HTMLMediaElement::selectInitialTracksIfNecessary()
+{
+ if (!RuntimeEnabledFeatures::audioVideoTracksEnabled())
+ return;
+
+ // Enable the first audio track if an audio track hasn't been enabled yet.
+ if (audioTracks().length() > 0 && !audioTracks().hasEnabledTrack())
+ audioTracks().anonymousIndexedGetter(0)->setEnabled(true);
+
+ // Select the first video track if a video track hasn't been selected yet.
+ if (videoTracks().length() > 0 && videoTracks().selectedIndex() == -1)
+ videoTracks().anonymousIndexedGetter(0)->setSelected(true);
+}
+
+#if ENABLE(WEB_AUDIO)
+void HTMLMediaElement::clearWeakMembers(Visitor* visitor)
+{
+ if (!visitor->isAlive(m_audioSourceNode) && audioSourceProvider())
+ audioSourceProvider()->setClient(0);
+}
+#endif
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h
index 18374c781bb..5b2756e307c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -29,15 +29,16 @@
#include "core/dom/ActiveDOMObject.h"
#include "core/events/GenericEventQueue.h"
#include "core/html/HTMLElement.h"
-#include "core/html/MediaControllerInterface.h"
#include "core/html/track/TextTrack.h"
#include "core/html/track/TextTrackCue.h"
#include "core/html/track/vtt/VTTCue.h"
#include "platform/PODIntervalTree.h"
#include "platform/graphics/media/MediaPlayer.h"
+#include "public/platform/WebMediaPlayerClient.h"
#include "public/platform/WebMimeRegistry.h"
namespace blink {
+class WebContentDecryptionModule;
class WebInbandTextTrack;
class WebLayer;
}
@@ -46,8 +47,9 @@ namespace WebCore {
#if ENABLE(WEB_AUDIO)
class AudioSourceProvider;
-class MediaElementAudioSourceNode;
+class AudioSourceProviderClient;
#endif
+class AudioTrackList;
class ContentType;
class Event;
class ExceptionState;
@@ -57,10 +59,11 @@ class KURL;
class MediaController;
class MediaControls;
class MediaError;
-class MediaKeys;
class HTMLMediaSource;
class TextTrackList;
class TimeRanges;
+class URLRegistry;
+class VideoTrackList;
typedef PODIntervalTree<double, TextTrackCue*> CueIntervalTree;
typedef CueIntervalTree::IntervalType CueInterval;
@@ -70,20 +73,27 @@ typedef Vector<CueInterval> CueList;
// But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
// no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
-class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, public ActiveDOMObject, public MediaControllerInterface
- , private TextTrackClient
+class HTMLMediaElement : public HTMLElement, public WillBeHeapSupplementable<HTMLMediaElement>, public MediaPlayerClient, public ActiveDOMObject
{
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLMediaElement);
public:
static blink::WebMimeRegistry::SupportsType supportsType(const ContentType&, const String& keySystem = String());
- MediaPlayer* player() const { return m_player.get(); }
+ static void setMediaStreamRegistry(URLRegistry*);
+ static bool isMediaStreamURL(const String& url);
- virtual bool isVideo() const = 0;
- virtual bool hasVideo() const OVERRIDE { return false; }
- virtual bool hasAudio() const OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+#if ENABLE(WEB_AUDIO)
+ void clearWeakMembers(Visitor*);
+#endif
+
+ // Do not use player().
+ // FIXME: Replace all uses with webMediaPlayer() and remove this API.
+ MediaPlayer* player() const { return m_player.get(); }
+ blink::WebMediaPlayer* webMediaPlayer() const { return m_player ? m_player->webMediaPlayer() : 0; }
- // Eventually overloaded in HTMLVideoElement
- virtual bool supportsFullscreen() const OVERRIDE { return false; };
+ virtual bool hasVideo() const { return false; }
+ bool hasAudio() const;
bool supportsSave() const;
@@ -99,7 +109,7 @@ public:
bool isActive() const { return m_active; }
// error state
- PassRefPtr<MediaError> error() const;
+ PassRefPtrWillBeRawPtr<MediaError> error() const;
// network state
void setSrc(const AtomicString&);
@@ -109,13 +119,14 @@ public:
NetworkState networkState() const;
String preload() const;
- void setPreload(const String&);
+ void setPreload(const AtomicString&);
PassRefPtr<TimeRanges> buffered() const;
void load();
- String canPlayType(const String& mimeType, const String& keySystem = String(), const KURL& = KURL()) const;
+ String canPlayType(const String& mimeType, const String& keySystem = String()) const;
// ready state
+ enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
ReadyState readyState() const;
bool seeking() const;
@@ -144,22 +155,7 @@ public:
// media source extensions
void closeMediaSource();
- void durationChanged(double duration);
-
- // encrypted media extensions
- void webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState&);
- void webkitGenerateKeyRequest(const String& keySystem, ExceptionState&);
- void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState&);
- void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionState&);
- void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionState&);
-
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyadded);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyerror);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeymessage);
- DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitneedkey);
-
- MediaKeys* mediaKeys() const { return m_mediaKeys.get(); }
- void setMediaKeys(MediaKeys*);
+ void durationChanged(double duration, bool requestSeek);
// controls
bool controls() const;
@@ -169,47 +165,61 @@ public:
bool muted() const;
void setMuted(bool);
+ // play/pause toggling that uses the media controller if present. togglePlayStateWillPlay() is
+ // true if togglePlayState() will call play() or unpause() on the media element or controller.
+ bool togglePlayStateWillPlay() const;
void togglePlayState();
- void beginScrubbing();
- void endScrubbing();
- bool canPlay() const;
+ AudioTrackList& audioTracks();
+ void audioTrackChanged();
- double percentLoaded() const;
+ VideoTrackList& videoTracks();
+ void selectedVideoTrackChanged(blink::WebMediaPlayer::TrackId*);
- PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, const String& language, ExceptionState&);
- PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, ExceptionState& exceptionState) { return addTextTrack(kind, label, emptyString(), exceptionState); }
- PassRefPtr<TextTrack> addTextTrack(const String& kind, ExceptionState& exceptionState) { return addTextTrack(kind, emptyString(), emptyString(), exceptionState); }
+ PassRefPtrWillBeRawPtr<TextTrack> addTextTrack(const AtomicString& kind, const AtomicString& label, const AtomicString& language, ExceptionState&);
+ PassRefPtrWillBeRawPtr<TextTrack> addTextTrack(const AtomicString& kind, const AtomicString& label, ExceptionState& exceptionState) { return addTextTrack(kind, label, emptyAtom, exceptionState); }
+ PassRefPtrWillBeRawPtr<TextTrack> addTextTrack(const AtomicString& kind, ExceptionState& exceptionState) { return addTextTrack(kind, emptyAtom, emptyAtom, exceptionState); }
TextTrackList* textTracks();
CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
- void addTrack(TextTrack*);
- void removeTrack(TextTrack*);
- void removeAllInbandTracks();
+ void addTextTrack(TextTrack*);
+ void removeTextTrack(TextTrack*);
void closeCaptionTracksChanged();
void notifyMediaPlayerOfTextTrackChanges();
- void didAddTrack(HTMLTrackElement*);
- void didRemoveTrack(HTMLTrackElement*);
+ // Implements the "forget the media element's media-resource-specific tracks" algorithm in the HTML5 spec.
+ void forgetResourceSpecificTracks();
+
+ void didAddTrackElement(HTMLTrackElement*);
+ void didRemoveTrackElement(HTMLTrackElement*);
+
+ blink::WebMediaPlayer::TrackId addAudioTrack(const String& id, blink::WebMediaPlayerClient::AudioTrackKind, const AtomicString& label, const AtomicString& language, bool enabled);
+ void removeAudioTrack(blink::WebMediaPlayer::TrackId);
+ blink::WebMediaPlayer::TrackId addVideoTrack(const String& id, blink::WebMediaPlayerClient::VideoTrackKind, const AtomicString& label, const AtomicString& language, bool selected);
+ void removeVideoTrack(blink::WebMediaPlayer::TrackId);
- virtual void mediaPlayerDidAddTrack(blink::WebInbandTextTrack*) OVERRIDE;
- virtual void mediaPlayerDidRemoveTrack(blink::WebInbandTextTrack*) OVERRIDE;
+ virtual void mediaPlayerDidAddTextTrack(blink::WebInbandTextTrack*) OVERRIDE FINAL;
+ virtual void mediaPlayerDidRemoveTextTrack(blink::WebInbandTextTrack*) OVERRIDE FINAL;
+ // FIXME: Remove this when WebMediaPlayerClientImpl::loadInternal does not depend on it.
+ virtual KURL mediaPlayerPosterURL() OVERRIDE { return KURL(); }
- struct TrackGroup {
+ class TrackGroup {
+ STACK_ALLOCATED();
+ public:
enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other };
- TrackGroup(GroupKind kind)
- : visibleTrack(0)
- , defaultTrack(0)
+ explicit TrackGroup(GroupKind kind)
+ : visibleTrack(nullptr)
+ , defaultTrack(nullptr)
, kind(kind)
, hasSrcLang(false)
{
}
- Vector<RefPtr<TextTrack> > tracks;
- RefPtr<TextTrack> visibleTrack;
- RefPtr<TextTrack> defaultTrack;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > tracks;
+ RefPtrWillBeMember<TextTrack> visibleTrack;
+ RefPtrWillBeMember<TextTrack> defaultTrack;
GroupKind kind;
bool hasSrcLang;
};
@@ -227,20 +237,19 @@ public:
void updateTextTrackDisplay();
void textTrackReadyStateChanged(TextTrack*);
- // TextTrackClient
- virtual void textTrackKindChanged(TextTrack*) OVERRIDE;
- virtual void textTrackModeChanged(TextTrack*) OVERRIDE;
- virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
- virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
- virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
- virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
+ void textTrackKindChanged(TextTrack*);
+ void textTrackModeChanged(TextTrack*);
+ void textTrackAddCues(TextTrack*, const TextTrackCueList*);
+ void textTrackRemoveCues(TextTrack*, const TextTrackCueList*);
+ void textTrackAddCue(TextTrack*, PassRefPtrWillBeRawPtr<TextTrackCue>);
+ void textTrackRemoveCue(TextTrack*, PassRefPtrWillBeRawPtr<TextTrackCue>);
// EventTarget function.
// Both Node (via HTMLElement) and ActiveDOMObject define this method, which
// causes an ambiguity error at compile time. This class's constructor
// ensures that both implementations return document, so return the result
// of one of them here.
- virtual ExecutionContext* executionContext() const OVERRIDE { return HTMLElement::executionContext(); }
+ using HTMLElement::executionContext;
bool hasSingleSecurityOrigin() const { return !m_player || m_player->hasSingleSecurityOrigin(); }
@@ -260,12 +269,12 @@ public:
bool isPlaying() const { return m_playing; }
// ActiveDOMObject functions.
- virtual bool hasPendingActivity() const OVERRIDE;
- virtual void contextDestroyed() OVERRIDE;
+ virtual bool hasPendingActivity() const OVERRIDE FINAL;
+ virtual void contextDestroyed() OVERRIDE FINAL;
#if ENABLE(WEB_AUDIO)
- MediaElementAudioSourceNode* audioSourceNode() { return m_audioSourceNode; }
- void setAudioSourceNode(MediaElementAudioSourceNode*);
+ AudioSourceProviderClient* audioSourceNode() { return m_audioSourceNode; }
+ void setAudioSourceNode(AudioSourceProviderClient*);
AudioSourceProvider* audioSourceProvider();
#endif
@@ -274,44 +283,34 @@ public:
bool isSafeToLoadURL(const KURL&, InvalidURLAction);
MediaController* controller() const;
- void setController(PassRefPtr<MediaController>); // Resets the MediaGroup and sets the MediaController.
+ void setController(PassRefPtrWillBeRawPtr<MediaController>); // Resets the MediaGroup and sets the MediaController.
+
+ void scheduleEvent(PassRefPtrWillBeRawPtr<Event>);
+
+ // Current volume that should be used by the webMediaPlayer(). This method takes muted state
+ // and m_mediaController multipliers into account.
+ double playerVolume() const;
+
+#if ENABLE(OILPAN)
+ bool isFinalizing() const { return m_isFinalizing; }
+#endif
protected:
- HTMLMediaElement(const QualifiedName&, Document&, bool);
+ HTMLMediaElement(const QualifiedName&, Document&);
virtual ~HTMLMediaElement();
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void finishParsingChildren() OVERRIDE;
+ virtual void finishParsingChildren() OVERRIDE FINAL;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
- enum DisplayMode { Unknown, None, Poster, PosterWaitingForVideo, Video };
+ enum DisplayMode { Unknown, Poster, PosterWaitingForVideo, Video };
DisplayMode displayMode() const { return m_displayMode; }
virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
- virtual bool isMediaElement() const OVERRIDE { return true; }
-
- void setControllerInternal(PassRefPtr<MediaController>);
-
- // Restrictions to change default behaviors.
- enum BehaviorRestrictionFlags {
- NoRestrictions = 0,
- RequireUserGestureForLoadRestriction = 1 << 0,
- RequireUserGestureForRateChangeRestriction = 1 << 1,
- RequireUserGestureForFullscreenRestriction = 1 << 2,
- RequirePageConsentToLoadMediaRestriction = 1 << 3,
- };
- typedef unsigned BehaviorRestrictions;
-
- bool userGestureRequiredForLoad() const { return m_restrictions & RequireUserGestureForLoadRestriction; }
- bool userGestureRequiredForRateChange() const { return m_restrictions & RequireUserGestureForRateChangeRestriction; }
- bool userGestureRequiredForFullscreen() const { return m_restrictions & RequireUserGestureForFullscreenRestriction; }
- bool pageConsentRequiredForLoad() const { return m_restrictions & RequirePageConsentToLoadMediaRestriction; }
-
- void addBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions |= restriction; }
- void removeBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions &= ~restriction; }
+ void setControllerInternal(PassRefPtrWillBeRawPtr<MediaController>);
bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0; }
void beginIgnoringTrackDisplayUpdateRequests();
@@ -320,51 +319,42 @@ protected:
private:
void createMediaPlayer();
- virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE { return true; }
- virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
+ virtual bool alwaysCreateUserAgentShadowRoot() const OVERRIDE FINAL { return true; }
+ virtual bool areAuthorShadowsAllowed() const OVERRIDE FINAL { return false; }
- virtual bool hasCustomFocusLogic() const OVERRIDE;
- virtual bool supportsFocus() const OVERRIDE;
- virtual bool isMouseFocusable() const OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE FINAL;
+ virtual bool isMouseFocusable() const OVERRIDE FINAL;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
- virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE FINAL;
+ virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
+ virtual void removedFrom(ContainerNode*) OVERRIDE FINAL;
+ virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE FINAL;
- virtual void didBecomeFullscreenElement() OVERRIDE;
- virtual void willStopBeingFullscreenElement() OVERRIDE;
- virtual bool isInteractiveContent() const OVERRIDE;
+ virtual void didBecomeFullscreenElement() OVERRIDE FINAL;
+ virtual void willStopBeingFullscreenElement() OVERRIDE FINAL;
+ virtual bool isInteractiveContent() const OVERRIDE FINAL;
+ virtual void defaultEventHandler(Event*) OVERRIDE FINAL;
// ActiveDOMObject functions.
- virtual void stop() OVERRIDE;
+ virtual void stop() OVERRIDE FINAL;
virtual void updateDisplayState() { }
- void setReadyState(MediaPlayer::ReadyState);
+ void setReadyState(ReadyState);
void setNetworkState(MediaPlayer::NetworkState);
- virtual void mediaPlayerNetworkStateChanged() OVERRIDE;
- virtual void mediaPlayerReadyStateChanged() OVERRIDE;
- virtual void mediaPlayerTimeChanged() OVERRIDE;
- virtual void mediaPlayerDurationChanged() OVERRIDE;
- virtual void mediaPlayerPlaybackStateChanged() OVERRIDE;
- virtual void mediaPlayerRequestFullscreen() OVERRIDE;
- virtual void mediaPlayerRequestSeek(double) OVERRIDE;
- virtual void mediaPlayerRepaint() OVERRIDE;
- virtual void mediaPlayerSizeChanged() OVERRIDE;
-
- virtual void mediaPlayerKeyAdded(const String& keySystem, const String& sessionId) OVERRIDE;
- virtual void mediaPlayerKeyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode) OVERRIDE;
- virtual void mediaPlayerKeyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL) OVERRIDE;
- virtual bool mediaPlayerKeyNeeded(const String& keySystem, const String& sessionId, const unsigned char* initData, unsigned initDataLength) OVERRIDE;
- virtual bool mediaPlayerKeyNeeded(Uint8Array*) OVERRIDE;
-
- virtual CORSMode mediaPlayerCORSMode() const OVERRIDE;
-
- virtual void mediaPlayerSetWebLayer(blink::WebLayer*) OVERRIDE;
- virtual void mediaPlayerSetOpaque(bool) OVERRIDE;
+ virtual void mediaPlayerNetworkStateChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerReadyStateChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerTimeChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerDurationChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerPlaybackStateChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerRequestFullscreen() OVERRIDE FINAL;
+ virtual void mediaPlayerRequestSeek(double) OVERRIDE FINAL;
+ virtual void mediaPlayerRepaint() OVERRIDE FINAL;
+ virtual void mediaPlayerSizeChanged() OVERRIDE FINAL;
+ virtual void mediaPlayerSetWebLayer(blink::WebLayer*) OVERRIDE FINAL;
+ virtual void mediaPlayerMediaSourceOpened(blink::WebMediaSource*) OVERRIDE FINAL;
void loadTimerFired(Timer<HTMLMediaElement>*);
void progressEventTimerFired(Timer<HTMLMediaElement>*);
@@ -379,19 +369,24 @@ private:
void addPlayedRange(double start, double end);
void scheduleTimeupdateEvent(bool periodicEvent);
- void scheduleEvent(const AtomicString& eventName);
+ void scheduleEvent(const AtomicString& eventName); // FIXME: Rename to scheduleNamedEvent for clarity.
// loading
+ void prepareForLoad();
+ void loadInternal();
void selectMediaResource();
void loadResource(const KURL&, ContentType&, const String& keySystem);
+ void startPlayerLoad();
+ void setPlayerPreload();
+ blink::WebMediaPlayer::LoadType loadType() const;
void scheduleNextSourceChild();
void loadNextSourceChild();
void userCancelledLoad();
void clearMediaPlayer(int flags);
- void clearMediaPlayerAndAudioSourceProviderClient();
+ void clearMediaPlayerAndAudioSourceProviderClientWithoutLocking();
bool havePotentialSourceChild();
void noneSupported();
- void mediaEngineError(PassRefPtr<MediaError> err);
+ void mediaEngineError(PassRefPtrWillBeRawPtr<MediaError>);
void cancelPendingEventsAndCallbacks();
void waitForSourceChange();
void prepareToPlay();
@@ -400,17 +395,22 @@ private:
void mediaLoadingFailed(MediaPlayer::NetworkState);
+ // deferred loading (preload=none)
+ bool loadIsDeferred() const;
+ void deferLoad();
+ void cancelDeferredLoad();
+ void startDeferredLoad();
+ void executeDeferredLoad();
+ void deferredLoadTimerFired(Timer<HTMLMediaElement>*);
+
void updateActiveTextTrackCues(double);
HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
void markCaptionAndSubtitleTracksAsUnconfigured();
- // These "internal" functions do not check user gesture restrictions.
- void loadInternal();
+ // This does not check user gesture restrictions.
void playInternal();
- void pauseInternal();
- void prepareForLoad();
void allowVideoRendering();
void updateVolume();
@@ -418,14 +418,11 @@ private:
bool potentiallyPlaying() const;
bool endedPlayback() const;
bool stoppedDueToErrors() const;
- bool pausedForUserInteraction() const;
bool couldPlayIfEnoughData() const;
// Pauses playback without changing any states or generating events
void setPausedInternal(bool);
- void setPlaybackRateInternal(double);
-
void setShouldDelayLoadEvent(bool);
void invalidateCachedTime();
void refreshCachedTime() const;
@@ -437,25 +434,44 @@ private:
void prepareMediaFragmentURI();
void applyMediaFragmentURI();
- virtual void* preDispatchEventHandler(Event*) OVERRIDE;
+ virtual void* preDispatchEventHandler(Event*) OVERRIDE FINAL;
void changeNetworkStateFromLoadingToIdle();
- void removeBehaviorsRestrictionsAfterFirstUserGesture();
-
const AtomicString& mediaGroup() const;
void setMediaGroup(const AtomicString&);
void updateMediaController();
bool isBlocked() const;
bool isBlockedOnMediaController() const;
- bool hasCurrentSrc() const { return !m_currentSrc.isEmpty(); }
bool isAutoplaying() const { return m_autoplaying; }
+ blink::WebMediaPlayer::CORSMode corsMode() const;
+
+ // Returns the "direction of playback" value as specified in the HTML5 spec.
+ enum DirectionOfPlayback { Backward, Forward };
+ DirectionOfPlayback directionOfPlayback() const;
+
+ // Returns the "effective playback rate" value as specified in the HTML5 spec.
+ double effectivePlaybackRate() const;
+
+ // Creates placeholder AudioTrack and/or VideoTrack objects when WebMemediaPlayer objects
+ // advertise they have audio and/or video, but don't explicitly signal them via
+ // addAudioTrack() and addVideoTrack().
+ // FIXME: Remove this once all WebMediaPlayer implementations properly report their track info.
+ void createPlaceholderTracksIfNecessary();
+
+ // Sets the selected/enabled tracks if they aren't set before we initially
+ // transition to HAVE_METADATA.
+ void selectInitialTracksIfNecessary();
+
+ void audioTracksTimerFired(Timer<HTMLMediaElement>*);
+
Timer<HTMLMediaElement> m_loadTimer;
Timer<HTMLMediaElement> m_progressEventTimer;
Timer<HTMLMediaElement> m_playbackProgressTimer;
+ Timer<HTMLMediaElement> m_audioTracksTimer;
RefPtr<TimeRanges> m_playedTimeRanges;
- OwnPtr<GenericEventQueue> m_asyncEventQueue;
+ OwnPtrWillBeMember<GenericEventQueue> m_asyncEventQueue;
double m_playbackRate;
double m_defaultPlaybackRate;
@@ -464,12 +480,11 @@ private:
ReadyState m_readyStateMaximum;
KURL m_currentSrc;
- RefPtr<MediaError> m_error;
+ RefPtrWillBeMember<MediaError> m_error;
double m_volume;
double m_lastSeekTime;
- unsigned m_previousProgress;
double m_previousProgressTime;
// Cached duration to suppress duplicate events if duration unchanged.
@@ -484,14 +499,27 @@ private:
// Loading state.
enum LoadState { WaitingForSource, LoadingFromSrcAttr, LoadingFromSourceElement };
LoadState m_loadState;
- RefPtr<HTMLSourceElement> m_currentSourceNode;
- RefPtr<Node> m_nextChildNodeToConsider;
+ RefPtrWillBeMember<HTMLSourceElement> m_currentSourceNode;
+ RefPtrWillBeMember<Node> m_nextChildNodeToConsider;
+
+ // "Deferred loading" state (for preload=none).
+ enum DeferredLoadState {
+ // The load is not deferred.
+ NotDeferred,
+ // The load is deferred, and waiting for the task to set the
+ // delaying-the-load-event flag (to false).
+ WaitingForStopDelayingLoadEventTask,
+ // The load is the deferred, and waiting for a triggering event.
+ WaitingForTrigger,
+ // The load is deferred, and waiting for the task to set the
+ // delaying-the-load-event flag, after which the load will be executed.
+ ExecuteOnStopDelayingLoadEventTask
+ };
+ DeferredLoadState m_deferredLoadState;
+ Timer<HTMLMediaElement> m_deferredLoadTimer;
OwnPtr<MediaPlayer> m_player;
blink::WebLayer* m_webLayer;
- bool m_opaque;
-
- BehaviorRestrictions m_restrictions;
MediaPlayer::Preload m_preload;
@@ -510,6 +538,7 @@ private:
PendingActionFlags m_pendingActionFlags;
// FIXME: MediaElement has way too many state bits.
+ bool m_userGestureRequiredForPlay : 1;
bool m_playing : 1;
bool m_shouldDelayLoadEvent : 1;
bool m_haveFiredLoadedData : 1;
@@ -529,18 +558,22 @@ private:
bool m_closedCaptionsVisible : 1;
- bool m_loadInitiatedByUserGesture : 1;
bool m_completelyLoaded : 1;
bool m_havePreparedToPlay : 1;
- bool m_parsingInProgress : 1;
+ bool m_delayingLoadForPreloadNone : 1;
bool m_tracksAreReady : 1;
bool m_haveVisibleTextTrack : 1;
bool m_processingPreferenceChange : 1;
+#if ENABLE(OILPAN)
+ bool m_isFinalizing : 1;
+#endif
double m_lastTextTrackUpdateTime;
- RefPtr<TextTrackList> m_textTracks;
- Vector<RefPtr<TextTrack> > m_textTracksWhenResourceSelectionBegan;
+ RefPtrWillBeMember<AudioTrackList> m_audioTracks;
+ RefPtrWillBeMember<VideoTrackList> m_videoTracks;
+ RefPtrWillBeMember<TextTrackList> m_textTracks;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > m_textTracksWhenResourceSelectionBegan;
CueIntervalTree m_cueTree;
@@ -549,17 +582,17 @@ private:
#if ENABLE(WEB_AUDIO)
// This is a weak reference, since m_audioSourceNode holds a reference to us.
- // The value is set just after the MediaElementAudioSourceNode is created.
- // The value is cleared in MediaElementAudioSourceNode::~MediaElementAudioSourceNode().
- MediaElementAudioSourceNode* m_audioSourceNode;
+ // FIXME: Oilpan: Consider making this a strongly traced pointer with oilpan where strong cycles are not a problem.
+ RawPtrWillBeWeakMember<AudioSourceProviderClient> m_audioSourceNode;
#endif
friend class MediaController;
- RefPtr<MediaController> m_mediaController;
+ RefPtrWillBeMember<MediaController> m_mediaController;
+ friend class Internals;
friend class TrackDisplayUpdateScope;
- RefPtr<MediaKeys> m_mediaKeys;
+ static URLRegistry* s_mediaStreamRegistry;
};
#ifndef NDEBUG
@@ -581,17 +614,17 @@ struct ValueToString<TextTrackCue*> {
};
#endif
-inline bool isHTMLMediaElement(Node* node)
+inline bool isHTMLMediaElement(const Element& element)
{
- return node && node->isElementNode() && toElement(node)->isMediaElement();
+ return isHTMLAudioElement(element) || isHTMLVideoElement(element);
}
-inline bool isHTMLMediaElement(const Node& node)
+inline bool isHTMLMediaElement(const HTMLElement& element)
{
- return node.isElementNode() && toElement(node).isMediaElement();
+ return isHTMLAudioElement(element) || isHTMLVideoElement(element);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement);
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl
index a4dbf6fdf6d..3d87a591ba3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaElement.idl
@@ -24,17 +24,18 @@
*/
[
+ ActiveDOMObject,
RuntimeEnabled=Media,
- ActiveDOMObject
+ TypeChecking=Unrestricted,
] interface HTMLMediaElement : HTMLElement {
// error state
- readonly attribute MediaError error;
+ [TypeChecking=Interface|Nullable] readonly attribute MediaError? error;
// network state
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
- [URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] readonly attribute DOMString currentSrc;
- [Reflect] attribute DOMString crossOrigin;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
+ [URL, LogActivity=SetterOnly] readonly attribute DOMString currentSrc;
+ [Reflect, ReflectOnly="anonymous"|"use-credentials", ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString crossOrigin;
const unsigned short NETWORK_EMPTY = 0;
const unsigned short NETWORK_IDLE = 1;
@@ -45,7 +46,7 @@
readonly attribute TimeRanges buffered;
void load();
- DOMString canPlayType([Default=Undefined] optional DOMString type, [Default=Undefined, TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString keySystem);
+ DOMString canPlayType(DOMString type, [Default=Undefined, TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString keySystem);
// ready state
const unsigned short HAVE_NOTHING = 0;
@@ -58,7 +59,7 @@
// playback state
[RaisesException=Setter] attribute double currentTime;
- readonly attribute double duration;
+ readonly attribute unrestricted double duration;
readonly attribute boolean paused;
attribute double defaultPlaybackRate;
attribute double playbackRate;
@@ -71,8 +72,8 @@
void pause();
// media controller
- [Reflect] attribute DOMString mediaGroup;
- [StrictTypeChecking] attribute MediaController controller;
+ [RuntimeEnabled=MediaController, Reflect] attribute DOMString mediaGroup;
+ [RuntimeEnabled=MediaController, TypeChecking=Interface|Nullable] attribute MediaController? controller;
// controls
attribute boolean controls;
@@ -81,8 +82,10 @@
[Reflect=muted] attribute boolean defaultMuted;
// tracks
- [RuntimeEnabled=VideoTrack] readonly attribute TextTrackList textTracks;
- [RuntimeEnabled=VideoTrack, RaisesException] TextTrack addTextTrack(DOMString kind, optional DOMString label, optional DOMString language);
+ [RuntimeEnabled=AudioVideoTracks] readonly attribute AudioTrackList audioTracks;
+ [RuntimeEnabled=AudioVideoTracks] readonly attribute VideoTrackList videoTracks;
+ readonly attribute TextTrackList textTracks;
+ [RaisesException] TextTrack addTextTrack(DOMString kind, optional DOMString label, optional DOMString language);
// WebKit extensions
@@ -90,15 +93,5 @@
[MeasureAs=PrefixedAudioDecodedByteCount] readonly attribute unsigned long webkitAudioDecodedByteCount;
[MeasureAs=PrefixedVideoDecodedByteCount] readonly attribute unsigned long webkitVideoDecodedByteCount;
- // FIXME: add DeprecateAs=PrefixedMediaGenerateKeyRequest when MediaKeys is ready.
- [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException] void webkitGenerateKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, optional Uint8Array initData);
- [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException] void webkitAddKey([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, Uint8Array key, optional Uint8Array initData, [Default=NullString] optional DOMString sessionId);
- [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException] void webkitCancelKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, [Default=NullString] optional DOMString sessionId);
-
- [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeyadded;
- [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeyerror;
- [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeymessage;
- [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitneedkey;
-
- [RuntimeEnabled=EncryptedMedia] attribute MediaKeys mediaKeys;
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h b/chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h
index f40206ce094..14baccb8e49 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMediaSource.h
@@ -31,7 +31,6 @@
#ifndef HTMLMediaSource_h
#define HTMLMediaSource_h
-#include "core/html/HTMLMediaElement.h"
#include "core/html/URLRegistry.h"
#include "wtf/Forward.h"
@@ -41,6 +40,7 @@ class WebMediaSource;
namespace WebCore {
+class HTMLMediaElement;
class TimeRanges;
class HTMLMediaSource : public URLRegistrable {
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp
index 2783c047b6a..5643bc146a5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLMenuElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -35,9 +35,6 @@ inline HTMLMenuElement::HTMLMenuElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLMenuElement> HTMLMenuElement::create(Document& document)
-{
- return adoptRef(new HTMLMenuElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLMenuElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h
index b1fdab64b05..4df4c6d101c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMenuElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLMenuElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLMenuElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLMenuElement);
private:
explicit HTMLMenuElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp
index 02060a45742..78505207eb5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement-in.cpp
@@ -23,9 +23,12 @@
#include "config.h"
#include "core/html/HTMLMetaElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -51,10 +54,7 @@ inline HTMLMetaElement::HTMLMetaElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLMetaElement> HTMLMetaElement::create(Document& document)
-{
- return adoptRef(new HTMLMetaElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLMetaElement)
static bool isInvalidSeparator(UChar c)
{
@@ -72,13 +72,12 @@ void HTMLMetaElement::parseContentAttribute(const String& content, KeyValuePairC
bool error = false;
// Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
- int keyBegin, keyEnd;
- int valueBegin, valueEnd;
+ unsigned keyBegin, keyEnd;
+ unsigned valueBegin, valueEnd;
- int i = 0;
- int length = content.length();
String buffer = content.lower();
- while (i < length) {
+ unsigned length = buffer.length();
+ for (unsigned i = 0; i < length; /* no increment here */) {
// skip to first non-separator, but don't skip past the end of the string
while (isSeparator(buffer[i])) {
if (i >= length)
@@ -90,6 +89,8 @@ void HTMLMetaElement::parseContentAttribute(const String& content, KeyValuePairC
// skip to first separator
while (!isSeparator(buffer[i])) {
error |= isInvalidSeparator(buffer[i]);
+ if (i >= length)
+ break;
i++;
}
keyEnd = i;
@@ -113,6 +114,8 @@ void HTMLMetaElement::parseContentAttribute(const String& content, KeyValuePairC
// skip to first separator
while (!isSeparator(buffer[i])) {
error |= isInvalidSeparator(buffer[i]);
+ if (i >= length)
+ break;
i++;
}
valueEnd = i;
@@ -177,10 +180,10 @@ Length HTMLMetaElement::parseViewportValueAsLength(const String& keyString, cons
DEFINE_ARRAY_FOR_MATCHING(characters, valueString, 13);
SWITCH(characters, length) {
CASE("device-width") {
- return Length(100, ViewportPercentageWidth);
+ return Length(DeviceWidth);
}
CASE("device-height") {
- return Length(100, ViewportPercentageHeight);
+ return Length(DeviceHeight);
}
}
@@ -192,7 +195,7 @@ Length HTMLMetaElement::parseViewportValueAsLength(const String& keyString, cons
return Length(clampLengthValue(value), Fixed);
}
-float HTMLMetaElement::parseViewportValueAsZoom(const String& keyString, const String& valueString)
+float HTMLMetaElement::parseViewportValueAsZoom(const String& keyString, const String& valueString, bool& computedValueMatchesParsedValue)
{
// 1) Non-negative number values are translated to <number> values.
// 2) Negative number values are translated to auto.
@@ -200,6 +203,7 @@ float HTMLMetaElement::parseViewportValueAsZoom(const String& keyString, const S
// 4) device-width and device-height are translated to 10.0.
// 5) no and unknown values are translated to 0.0
+ computedValueMatchesParsedValue = false;
unsigned length = valueString.length();
DEFINE_ARRAY_FOR_MATCHING(characters, valueString, 13);
SWITCH(characters, length) {
@@ -228,37 +232,44 @@ float HTMLMetaElement::parseViewportValueAsZoom(const String& keyString, const S
if (!value && document().settings() && document().settings()->viewportMetaZeroValuesQuirk())
return ViewportDescription::ValueAuto;
- return clampScaleValue(value);
+ float clampedValue = clampScaleValue(value);
+ if (clampedValue == value)
+ computedValueMatchesParsedValue = true;
+
+ return clampedValue;
}
-float HTMLMetaElement::parseViewportValueAsUserZoom(const String& keyString, const String& valueString)
+bool HTMLMetaElement::parseViewportValueAsUserZoom(const String& keyString, const String& valueString, bool& computedValueMatchesParsedValue)
{
// yes and no are used as keywords.
// Numbers >= 1, numbers <= -1, device-width and device-height are mapped to yes.
// Numbers in the range <-1, 1>, and unknown values, are mapped to no.
+ computedValueMatchesParsedValue = false;
unsigned length = valueString.length();
DEFINE_ARRAY_FOR_MATCHING(characters, valueString, 13);
SWITCH(characters, length) {
CASE("yes") {
- return 1;
+ computedValueMatchesParsedValue = true;
+ return true;
}
CASE("no") {
- return 0;
+ computedValueMatchesParsedValue = true;
+ return false;
}
CASE("device-width") {
- return 1;
+ return true;
}
CASE("device-height") {
- return 1;
+ return true;
}
}
float value = parsePositiveNumber(keyString, valueString);
if (fabs(value) < 1)
- return 0;
+ return false;
- return 1;
+ return true;
}
float HTMLMetaElement::parseViewportValueAsDPI(const String& keyString, const String& valueString)
@@ -313,19 +324,19 @@ void HTMLMetaElement::processViewportKeyValuePair(const String& keyString, const
return;
}
CASE("initial-scale") {
- description->zoom = parseViewportValueAsZoom(keyString, valueString);
+ description->zoom = parseViewportValueAsZoom(keyString, valueString, description->zoomIsExplicit);
return;
}
CASE("minimum-scale") {
- description->minZoom = parseViewportValueAsZoom(keyString, valueString);
+ description->minZoom = parseViewportValueAsZoom(keyString, valueString, description->minZoomIsExplicit);
return;
}
CASE("maximum-scale") {
- description->maxZoom = parseViewportValueAsZoom(keyString, valueString);
+ description->maxZoom = parseViewportValueAsZoom(keyString, valueString, description->maxZoomIsExplicit);
return;
}
CASE("user-scalable") {
- description->userZoom = parseViewportValueAsUserZoom(keyString, valueString);
+ description->userZoom = parseViewportValueAsUserZoom(keyString, valueString, description->userZoomIsExplicit);
return;
}
CASE("target-densitydpi") {
@@ -333,6 +344,10 @@ void HTMLMetaElement::processViewportKeyValuePair(const String& keyString, const
reportViewportWarning(TargetDensityDpiUnsupported, String(), String());
return;
}
+ CASE("minimal-ui") {
+ // Ignore vendor-specific argument.
+ return;
+ }
}
reportViewportWarning(UnrecognizedViewportArgumentKeyError, keyString, String());
}
@@ -355,11 +370,10 @@ static MessageLevel viewportErrorMessageLevel(ViewportErrorCode errorCode)
switch (errorCode) {
case TruncatedViewportArgumentValueError:
case TargetDensityDpiUnsupported:
- return WarningMessageLevel;
case UnrecognizedViewportArgumentKeyError:
case UnrecognizedViewportArgumentValueError:
case MaximumScaleTooLargeError:
- return ErrorMessageLevel;
+ return WarningMessageLevel;
}
ASSERT_NOT_REACHED();
@@ -385,9 +399,6 @@ void HTMLMetaElement::processViewportContentAttribute(const String& content, Vie
{
ASSERT(!content.isNull());
- if (!document().settings())
- return;
-
if (!document().shouldOverrideLegacyDescription(origin))
return;
@@ -405,18 +416,6 @@ void HTMLMetaElement::processViewportContentAttribute(const String& content, Vie
descriptionFromLegacyTag.minZoom = std::min(descriptionFromLegacyTag.minZoom, float(5));
}
- const Settings* settings = document().settings();
-
- if (descriptionFromLegacyTag.maxWidth.isAuto()) {
- if (descriptionFromLegacyTag.zoom == ViewportDescription::ValueAuto) {
- descriptionFromLegacyTag.minWidth = Length(ExtendToZoom);
- descriptionFromLegacyTag.maxWidth = Length(settings->layoutFallbackWidth(), Fixed);
- } else if (descriptionFromLegacyTag.maxHeight.isAuto()) {
- descriptionFromLegacyTag.minWidth = Length(ExtendToZoom);
- descriptionFromLegacyTag.maxWidth = Length(ExtendToZoom);
- }
- }
-
document().setViewportDescription(descriptionFromLegacyTag);
}
@@ -435,9 +434,24 @@ void HTMLMetaElement::parseAttribute(const QualifiedName& name, const AtomicStri
Node::InsertionNotificationRequest HTMLMetaElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
- if (insertionPoint->inDocument())
- process();
- return InsertionDone;
+ return InsertionShouldCallDidNotifySubtreeInsertions;
+}
+
+void HTMLMetaElement::didNotifySubtreeInsertionsToDocument()
+{
+ process();
+}
+
+static bool inDocumentHead(HTMLMetaElement* element)
+{
+ if (!element->inDocument())
+ return false;
+
+ for (Element* current = element; current; current = current->parentElement()) {
+ if (isHTMLHeadElement(*current))
+ return true;
+ }
+ return false;
}
void HTMLMetaElement::process()
@@ -451,24 +465,26 @@ void HTMLMetaElement::process()
return;
const AtomicString& nameValue = fastGetAttribute(nameAttr);
- if (nameValue.isNull()) {
- // Get the document to process the tag, but only if we're actually part of DOM
- // tree (changing a meta tag while it's not in the tree shouldn't have any effect
- // on the document).
- const AtomicString& httpEquivValue = fastGetAttribute(http_equivAttr);
- if (!httpEquivValue.isNull())
- document().processHttpEquiv(httpEquivValue, contentValue);
- return;
+ if (!nameValue.isEmpty()) {
+ if (equalIgnoringCase(nameValue, "viewport"))
+ processViewportContentAttribute(contentValue, ViewportDescription::ViewportMeta);
+ else if (equalIgnoringCase(nameValue, "referrer"))
+ document().processReferrerPolicy(contentValue);
+ else if (equalIgnoringCase(nameValue, "handheldfriendly") && equalIgnoringCase(contentValue, "true"))
+ processViewportContentAttribute("width=device-width", ViewportDescription::HandheldFriendlyMeta);
+ else if (equalIgnoringCase(nameValue, "mobileoptimized"))
+ processViewportContentAttribute("width=device-width, initial-scale=1", ViewportDescription::MobileOptimizedMeta);
+ else if (RuntimeEnabledFeatures::themeColorEnabled() && equalIgnoringCase(nameValue, "theme-color") && document().frame())
+ document().frame()->loader().client()->dispatchDidChangeThemeColor();
}
- if (equalIgnoringCase(nameValue, "viewport"))
- processViewportContentAttribute(contentValue, ViewportDescription::ViewportMeta);
- else if (equalIgnoringCase(nameValue, "referrer"))
- document().processReferrerPolicy(contentValue);
- else if (equalIgnoringCase(nameValue, "handheldfriendly") && equalIgnoringCase(contentValue, "true"))
- processViewportContentAttribute("width=device-width", ViewportDescription::HandheldFriendlyMeta);
- else if (equalIgnoringCase(nameValue, "mobileoptimized"))
- processViewportContentAttribute("width=device-width, initial-scale=1", ViewportDescription::MobileOptimizedMeta);
+ // Get the document to process the tag, but only if we're actually part of DOM
+ // tree (changing a meta tag while it's not in the tree shouldn't have any effect
+ // on the document).
+
+ const AtomicString& httpEquivValue = fastGetAttribute(http_equivAttr);
+ if (!httpEquivValue.isEmpty())
+ document().processHttpEquiv(httpEquivValue, contentValue, inDocumentHead(this));
}
const AtomicString& HTMLMetaElement::content() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h
index c859a33c744..ccdeffbc96c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMetaElement.h
@@ -23,6 +23,7 @@
#ifndef HTMLMetaElement_h
#define HTMLMetaElement_h
+#include "core/dom/ViewportDescription.h"
#include "core/html/HTMLElement.h"
namespace WebCore {
@@ -37,7 +38,7 @@ enum ViewportErrorCode {
class HTMLMetaElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLMetaElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLMetaElement);
const AtomicString& content() const;
const AtomicString& httpEquiv() const;
@@ -52,12 +53,13 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
+ virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
float parsePositiveNumber(const String& key, const String& value, bool* ok = 0);
Length parseViewportValueAsLength(const String& key, const String& value);
- float parseViewportValueAsZoom(const String& key, const String& value);
- float parseViewportValueAsUserZoom(const String& key, const String& value);
+ float parseViewportValueAsZoom(const String& key, const String& value, bool& computedValueMatchesParsedValue);
+ bool parseViewportValueAsUserZoom(const String& key, const String& value, bool& computedValueMatchesParsedValue);
float parseViewportValueAsDPI(const String& key, const String& value);
void reportViewportWarning(ViewportErrorCode, const String& replacement1, const String& replacement2);
@@ -66,8 +68,6 @@ private:
void processViewportContentAttribute(const String& content, ViewportDescription::Type origin);
};
-DEFINE_NODE_TYPE_CASTS(HTMLMetaElement, hasTagName(HTMLNames::metaTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
index 41e536d9944..f745a7aeaa3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.cpp
@@ -22,10 +22,10 @@
#include "core/html/HTMLMeterElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -47,11 +47,11 @@ HTMLMeterElement::~HTMLMeterElement()
{
}
-PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLMeterElement> HTMLMeterElement::create(Document& document)
{
- RefPtr<HTMLMeterElement> meter = adoptRef(new HTMLMeterElement(document));
+ RefPtrWillBeRawPtr<HTMLMeterElement> meter = adoptRefWillBeNoop(new HTMLMeterElement(document));
meter->ensureUserAgentShadowRoot();
- return meter;
+ return meter.release();
}
RenderObject* HTMLMeterElement::createRenderer(RenderStyle* style)
@@ -70,47 +70,35 @@ void HTMLMeterElement::parseAttribute(const QualifiedName& name, const AtomicStr
LabelableElement::parseAttribute(name, value);
}
-double HTMLMeterElement::min() const
+double HTMLMeterElement::value() const
{
- return getFloatingPointAttribute(minAttr, 0);
+ double value = getFloatingPointAttribute(valueAttr, 0);
+ return std::min(std::max(value, min()), max());
}
-void HTMLMeterElement::setMin(double min, ExceptionState& exceptionState)
+void HTMLMeterElement::setValue(double value)
{
- if (!std::isfinite(min)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(min));
- return;
- }
- setFloatingPointAttribute(minAttr, min);
+ setFloatingPointAttribute(valueAttr, value);
}
-double HTMLMeterElement::max() const
+double HTMLMeterElement::min() const
{
- return std::max(getFloatingPointAttribute(maxAttr, std::max(1.0, min())), min());
+ return getFloatingPointAttribute(minAttr, 0);
}
-void HTMLMeterElement::setMax(double max, ExceptionState& exceptionState)
+void HTMLMeterElement::setMin(double min)
{
- if (!std::isfinite(max)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(max));
- return;
- }
- setFloatingPointAttribute(maxAttr, max);
+ setFloatingPointAttribute(minAttr, min);
}
-double HTMLMeterElement::value() const
+double HTMLMeterElement::max() const
{
- double value = getFloatingPointAttribute(valueAttr, 0);
- return std::min(std::max(value, min()), max());
+ return std::max(getFloatingPointAttribute(maxAttr, std::max(1.0, min())), min());
}
-void HTMLMeterElement::setValue(double value, ExceptionState& exceptionState)
+void HTMLMeterElement::setMax(double max)
{
- if (!std::isfinite(value)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(value));
- return;
- }
- setFloatingPointAttribute(valueAttr, value);
+ setFloatingPointAttribute(maxAttr, max);
}
double HTMLMeterElement::low() const
@@ -119,12 +107,8 @@ double HTMLMeterElement::low() const
return std::min(std::max(low, min()), max());
}
-void HTMLMeterElement::setLow(double low, ExceptionState& exceptionState)
+void HTMLMeterElement::setLow(double low)
{
- if (!std::isfinite(low)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(low));
- return;
- }
setFloatingPointAttribute(lowAttr, low);
}
@@ -134,12 +118,8 @@ double HTMLMeterElement::high() const
return std::min(std::max(high, low()), max());
}
-void HTMLMeterElement::setHigh(double high, ExceptionState& exceptionState)
+void HTMLMeterElement::setHigh(double high)
{
- if (!std::isfinite(high)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(high));
- return;
- }
setFloatingPointAttribute(highAttr, high);
}
@@ -149,12 +129,8 @@ double HTMLMeterElement::optimum() const
return std::min(std::max(optimum, min()), max());
}
-void HTMLMeterElement::setOptimum(double optimum, ExceptionState& exceptionState)
+void HTMLMeterElement::setOptimum(double optimum)
{
- if (!std::isfinite(optimum)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(optimum));
- return;
- }
setFloatingPointAttribute(optimumAttr, optimum);
}
@@ -223,10 +199,10 @@ void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
ASSERT(!m_value);
- RefPtr<MeterInnerElement> inner = MeterInnerElement::create(document());
+ RefPtrWillBeRawPtr<MeterInnerElement> inner = MeterInnerElement::create(document());
root.appendChild(inner);
- RefPtr<MeterBarElement> bar = MeterBarElement::create(document());
+ RefPtrWillBeRawPtr<MeterBarElement> bar = MeterBarElement::create(document());
m_value = MeterValueElement::create(document());
m_value->setWidthPercentage(0);
m_value->updatePseudo();
@@ -235,4 +211,10 @@ void HTMLMeterElement::didAddUserAgentShadowRoot(ShadowRoot& root)
inner->appendChild(bar);
}
+void HTMLMeterElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ LabelableElement::trace(visitor);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h
index e815e602442..44d9e6fd20c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.h
@@ -31,7 +31,7 @@ class RenderMeter;
class HTMLMeterElement FINAL : public LabelableElement {
public:
- static PassRefPtr<HTMLMeterElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLMeterElement> create(Document&);
enum GaugeRegion {
GaugeRegionOptimum,
@@ -39,28 +39,30 @@ public:
GaugeRegionEvenLessGood
};
+ double value() const;
+ void setValue(double);
+
double min() const;
- void setMin(double, ExceptionState&);
+ void setMin(double);
double max() const;
- void setMax(double, ExceptionState&);
-
- double value() const;
- void setValue(double, ExceptionState&);
+ void setMax(double);
double low() const;
- void setLow(double, ExceptionState&);
+ void setLow(double);
double high() const;
- void setHigh(double, ExceptionState&);
+ void setHigh(double);
double optimum() const;
- void setOptimum(double, ExceptionState&);
+ void setOptimum(double);
double valueRatio() const;
GaugeRegion gaugeRegion() const;
- bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit HTMLMeterElement(Document&);
@@ -71,23 +73,15 @@ private:
virtual bool supportLabels() const OVERRIDE { return true; }
- virtual bool recalcWillValidate() const { return false; }
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
void didElementStateChange();
virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
- RefPtr<MeterValueElement> m_value;
+ RefPtrWillBeMember<MeterValueElement> m_value;
};
-inline bool isHTMLMeterElement(Node* node)
-{
- return node->hasTagName(HTMLNames::meterTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLMeterElement, hasTagName(HTMLNames::meterTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl
index fde8591538e..144f83ec411 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLMeterElement.idl
@@ -17,12 +17,16 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLMeterElement : HTMLElement {
- [RaisesException=Setter] attribute double value;
- [RaisesException=Setter] attribute double min;
- [RaisesException=Setter] attribute double max;
- [RaisesException=Setter] attribute double low;
- [RaisesException=Setter] attribute double high;
- [RaisesException=Setter] attribute double optimum;
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#htmlmeterelement
+
+[
+ TypeChecking=Unrestricted,
+] interface HTMLMeterElement : HTMLElement {
+ attribute double value;
+ attribute double min;
+ attribute double max;
+ attribute double low;
+ attribute double high;
+ attribute double optimum;
readonly attribute NodeList labels;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp
index e609ef53499..bf4fbd48407 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLModElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -35,14 +35,21 @@ inline HTMLModElement::HTMLModElement(const QualifiedName& tagName, Document& do
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLModElement> HTMLModElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLModElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLModElement)
bool HTMLModElement::isURLAttribute(const Attribute& attribute) const
{
return attribute.name() == citeAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLModElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == citeAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLModElement::subResourceAttributeName() const
+{
+ return citeAttr;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.h
index 7fcc7c93edf..cf112ccdcbc 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.h
@@ -30,12 +30,14 @@ namespace WebCore {
class HTMLModElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLModElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLModElement);
private:
HTMLModElement(const QualifiedName&, Document&);
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
};
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl
index c066b68c0ec..3c9bf9f9792 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLModElement.idl
@@ -18,6 +18,6 @@
*/
interface HTMLModElement : HTMLElement {
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString cite;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString cite;
[Reflect] attribute DOMString dateTime;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp
index 9941f554c51..a4829862410 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.cpp
@@ -23,83 +23,23 @@
#include "config.h"
#include "core/html/HTMLNameCollection.h"
-#include "HTMLNames.h"
-#include "core/dom/Element.h"
-#include "core/dom/ElementTraversal.h"
#include "core/dom/NodeRareData.h"
-#include "core/html/HTMLEmbedElement.h"
-#include "core/html/HTMLObjectElement.h"
namespace WebCore {
-using namespace HTMLNames;
-
-HTMLNameCollection::HTMLNameCollection(Node* document, CollectionType type, const AtomicString& name)
- : HTMLCollection(document, type, OverridesItemAfter)
+HTMLNameCollection::HTMLNameCollection(ContainerNode& document, CollectionType type, const AtomicString& name)
+ : HTMLCollection(document, type, DoesNotOverrideItemAfter)
, m_name(name)
{
}
HTMLNameCollection::~HTMLNameCollection()
{
- ASSERT(ownerNode());
- ASSERT(ownerNode()->isDocumentNode());
ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems);
-
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, type(), m_name);
+#if !ENABLE(OILPAN)
+ ASSERT(ownerNode().isDocumentNode());
+ ownerNode().nodeLists()->removeCache(this, type(), m_name);
+#endif
}
-Element* HTMLNameCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const
-{
- ASSERT_UNUSED(offsetInArray, !offsetInArray);
- ASSERT(previous != ownerNode());
-
- Element* current;
- if (!previous)
- current = ElementTraversal::firstWithin(*ownerNode());
- else
- current = ElementTraversal::next(*previous, ownerNode());
-
- for (; current; current = ElementTraversal::next(*current, ownerNode())) {
- switch (type()) {
- case WindowNamedItems:
- // find only images, forms, applets, embeds and objects by name,
- // but anything by id
- if (current->hasTagName(imgTag)
- || current->hasTagName(formTag)
- || current->hasTagName(appletTag)
- || current->hasTagName(embedTag)
- || current->hasTagName(objectTag)) {
- if (current->getNameAttribute() == m_name)
- return current;
- }
- if (current->getIdAttribute() == m_name)
- return current;
- break;
- case DocumentNamedItems:
- // find images, forms, applets, embeds, objects and iframes by name,
- // applets and object by id, and images by id but only if they have
- // a name attribute (this very strange rule matches IE)
- if (current->hasTagName(formTag)
- || current->hasTagName(iframeTag)
- || (current->hasTagName(embedTag) && toHTMLEmbedElement(current)->isExposed())) {
- if (current->getNameAttribute() == m_name)
- return current;
- } else if (current->hasTagName(appletTag)
- || (current->hasTagName(objectTag) && toHTMLObjectElement(current)->isExposed())) {
- if (current->getNameAttribute() == m_name || current->getIdAttribute() == m_name)
- return current;
- } else if (current->hasTagName(imgTag)) {
- if (current->getNameAttribute() == m_name || (current->getIdAttribute() == m_name && current->hasName()))
- return current;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- }
-
- return 0;
-}
-
-}
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h
index 435d4395860..b7ce7d4317d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNameCollection.h
@@ -24,26 +24,16 @@
#define HTMLNameCollection_h
#include "core/html/HTMLCollection.h"
-
#include "wtf/text/AtomicString.h"
namespace WebCore {
-class Document;
-
-class HTMLNameCollection FINAL : public HTMLCollection {
+class HTMLNameCollection : public HTMLCollection {
public:
- static PassRefPtr<HTMLNameCollection> create(Node* document, CollectionType type, const AtomicString& name)
- {
- return adoptRef(new HTMLNameCollection(document, type, name));
- }
-
- ~HTMLNameCollection();
-
-private:
- HTMLNameCollection(Node*, CollectionType, const AtomicString& name);
+ virtual ~HTMLNameCollection();
- virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE;
+protected:
+ HTMLNameCollection(ContainerNode&, CollectionType, const AtomicString& name);
AtomicString m_name;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.cpp
new file mode 100644
index 00000000000..aa6800d7a0f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/HTMLNoEmbedElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/loader/FrameLoader.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLNoEmbedElement::HTMLNoEmbedElement(Document& document)
+ : HTMLElement(noembedTag, document)
+{
+}
+
+DEFINE_NODE_FACTORY(HTMLNoEmbedElement)
+
+bool HTMLNoEmbedElement::rendererIsNeeded(const RenderStyle& style)
+{
+ if (document().frame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
+ return false;
+ return Element::rendererIsNeeded(style);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.h
new file mode 100644
index 00000000000..1575f4d483c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNoEmbedElement.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLNoEmbedElement_h
+#define HTMLNoEmbedElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <noembed> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's rendererIsNeeded doesn't need to know about it.
+class HTMLNoEmbedElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLNoEmbedElement);
+
+private:
+ explicit HTMLNoEmbedElement(Document&);
+
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.cpp
new file mode 100644
index 00000000000..7357a74e251
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/HTMLNoScriptElement.h"
+
+#include "bindings/v8/ScriptController.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLNoScriptElement::HTMLNoScriptElement(Document& document)
+ : HTMLElement(noscriptTag, document)
+{
+}
+
+DEFINE_NODE_FACTORY(HTMLNoScriptElement)
+
+bool HTMLNoScriptElement::rendererIsNeeded(const RenderStyle& style)
+{
+ if (document().frame()->script().canExecuteScripts(NotAboutToExecuteScript))
+ return false;
+ return Element::rendererIsNeeded(style);
+
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.h
new file mode 100644
index 00000000000..ace1a493f0e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLNoScriptElement.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLNoScriptElement_h
+#define HTMLNoScriptElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <noscript> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's rendererIsNeeded doesn't need to know about it.
+class HTMLNoScriptElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLNoScriptElement);
+
+private:
+ explicit HTMLNoScriptElement(Document&);
+
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp
index 03675516a07..40ac89d6349 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.cpp
@@ -23,16 +23,16 @@
#include "config.h"
#include "core/html/HTMLOListElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/rendering/RenderListItem.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLOListElement::HTMLOListElement(Document& document)
+inline HTMLOListElement::HTMLOListElement(Document& document)
: HTMLElement(olTag, document)
, m_start(0xBADBEEF)
, m_itemCount(0)
@@ -43,10 +43,7 @@ HTMLOListElement::HTMLOListElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOListElement> HTMLOListElement::create(Document& document)
-{
- return adoptRef(new HTMLOListElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLOListElement)
bool HTMLOListElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -100,6 +97,9 @@ void HTMLOListElement::setStart(int start)
void HTMLOListElement::updateItemValues()
{
+ if (!renderer())
+ return;
+ document().updateDistributionForNodeIfNeeded(this);
RenderListItem::updateItemValuesForOrderedList(this);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h
index 0da2e2c713d..407c9166979 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOListElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLOListElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLOListElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLOListElement);
int start() const { return m_hasExplicitStart ? m_start : (m_isReversed ? itemCount() : 1); }
void setStart(int);
@@ -64,8 +64,6 @@ private:
bool m_shouldRecalculateItemCount : 1;
};
-DEFINE_NODE_TYPE_CASTS(HTMLOListElement, hasTagName(HTMLNames::olTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
index 87a5c3eae98..3a503060ff6 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.cpp
@@ -24,14 +24,13 @@
#include "config.h"
#include "core/html/HTMLObjectElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/ElementTraversal.h"
-#include "core/dom/NodeList.h"
+#include "core/dom/TagCollection.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ShadowRoot.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLDocument.h"
@@ -53,22 +52,30 @@ inline HTMLObjectElement::HTMLObjectElement(Document& document, HTMLFormElement*
: HTMLPlugInElement(objectTag, document, createdByParser, ShouldNotPreferPlugInsForImages)
, m_useFallbackContent(false)
{
- setForm(form ? form : findFormAncestor());
ScriptWrappable::init(this);
+ associateByParser(form);
}
inline HTMLObjectElement::~HTMLObjectElement()
{
+#if !ENABLE(OILPAN)
setForm(0);
+#endif
}
-PassRefPtr<HTMLObjectElement> HTMLObjectElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLObjectElement> HTMLObjectElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
{
- RefPtr<HTMLObjectElement> element = adoptRef(new HTMLObjectElement(document, form, createdByParser));
+ RefPtrWillBeRawPtr<HTMLObjectElement> element = adoptRefWillBeNoop(new HTMLObjectElement(document, form, createdByParser));
element->ensureUserAgentShadowRoot();
return element.release();
}
+void HTMLObjectElement::trace(Visitor* visitor)
+{
+ FormAssociatedElement::trace(visitor);
+ HTMLPlugInElement::trace(visitor);
+}
+
RenderWidget* HTMLObjectElement::existingRenderWidget() const
{
return renderPart(); // This will return 0 if the renderer is not a RenderPart.
@@ -98,24 +105,24 @@ void HTMLObjectElement::parseAttribute(const QualifiedName& name, const AtomicSt
size_t pos = m_serviceType.find(";");
if (pos != kNotFound)
m_serviceType = m_serviceType.left(pos);
- if (renderer())
- setNeedsWidgetUpdate(true);
+ // FIXME: What is the right thing to do here? Should we supress the
+ // reload stuff when a persistable widget-type is specified?
+ reloadPluginOnAttributeChange(name);
+ if (!renderer())
+ requestPluginCreationWithoutRendererIfPossible();
} else if (name == dataAttr) {
m_url = stripLeadingAndTrailingHTMLSpaces(value);
- if (renderer()) {
+ if (renderer() && isImageType()) {
setNeedsWidgetUpdate(true);
- if (isImageType()) {
- if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
- m_imageLoader->updateFromElementIgnoringPreviousError();
- }
+ if (!m_imageLoader)
+ m_imageLoader = HTMLImageLoader::create(this);
+ m_imageLoader->updateFromElementIgnoringPreviousError();
+ } else {
+ reloadPluginOnAttributeChange(name);
}
} else if (name == classidAttr) {
m_classId = value;
- if (renderer())
- setNeedsWidgetUpdate(true);
- } else if (name == onbeforeloadAttr) {
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
+ reloadPluginOnAttributeChange(name);
} else {
HTMLPlugInElement::parseAttribute(name, value);
}
@@ -126,7 +133,7 @@ static void mapDataParamToSrc(Vector<String>* paramNames, Vector<String>* paramV
// Some plugins don't understand the "data" attribute of the OBJECT tag (i.e. Real and WMP
// require "src" attribute).
int srcIndex = -1, dataIndex = -1;
- for (unsigned int i = 0; i < paramNames->size(); ++i) {
+ for (unsigned i = 0; i < paramNames->size(); ++i) {
if (equalIgnoringCase((*paramNames)[i], "src"))
srcIndex = i;
else if (equalIgnoringCase((*paramNames)[i], "data"))
@@ -147,11 +154,7 @@ void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<S
// Scan the PARAM children and store their name/value pairs.
// Get the URL and type from the params if we don't already have them.
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->hasTagName(paramTag))
- continue;
-
- HTMLParamElement* p = toHTMLParamElement(child);
+ for (HTMLParamElement* p = Traversal<HTMLParamElement>::firstChild(*this); p; p = Traversal<HTMLParamElement>::nextSibling(*p)) {
String name = p->name();
if (name.isEmpty())
continue;
@@ -185,12 +188,13 @@ void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<S
// Turn the attributes of the <object> element into arrays, but don't override <param> values.
if (hasAttributes()) {
- for (unsigned i = 0; i < attributeCount(); ++i) {
- const Attribute* attribute = attributeItem(i);
- const AtomicString& name = attribute->name().localName();
+ AttributeCollection attributes = this->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ const AtomicString& name = it->name().localName();
if (!uniqueParamNames.contains(name.impl())) {
paramNames.append(name.string());
- paramValues.append(attribute->value().string());
+ paramValues.append(it->value().string());
}
}
}
@@ -217,8 +221,9 @@ bool HTMLObjectElement::hasFallbackContent() const
if (child->isTextNode()) {
if (!toText(child)->containsOnlyWhitespace())
return true;
- } else if (!child->hasTagName(paramTag))
+ } else if (!isHTMLParamElement(*child)) {
return true;
+ }
}
return false;
}
@@ -237,7 +242,7 @@ bool HTMLObjectElement::shouldAllowQuickTimeClassIdQuirk()
|| !equalIgnoringCase(classId(), "clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"))
return false;
- RefPtr<NodeList> metaElements = document().getElementsByTagName(HTMLNames::metaTag.localName());
+ RefPtrWillBeRawPtr<TagCollection> metaElements = document().getElementsByTagName(HTMLNames::metaTag.localName());
unsigned length = metaElements->length();
for (unsigned i = 0; i < length; ++i) {
ASSERT(metaElements->item(i)->isHTMLElement());
@@ -262,6 +267,30 @@ bool HTMLObjectElement::hasValidClassId()
return classId().isEmpty();
}
+void HTMLObjectElement::reloadPluginOnAttributeChange(const QualifiedName& name)
+{
+ // Following,
+ // http://www.whatwg.org/specs/web-apps/current-work/#the-object-element
+ // (Enumerated list below "Whenever one of the following conditions occur:")
+ //
+ // the updating of certain attributes should bring about "redetermination"
+ // of what the element contains.
+ bool needsInvalidation;
+ if (name == typeAttr) {
+ needsInvalidation = !fastHasAttribute(classidAttr) && !fastHasAttribute(dataAttr);
+ } else if (name == dataAttr) {
+ needsInvalidation = !fastHasAttribute(classidAttr);
+ } else if (name == classidAttr) {
+ needsInvalidation = true;
+ } else {
+ ASSERT_NOT_REACHED();
+ needsInvalidation = false;
+ }
+ setNeedsWidgetUpdate(true);
+ if (needsInvalidation)
+ setNeedsStyleRecalc(SubtreeStyleChange);
+}
+
// FIXME: This should be unified with HTMLEmbedElement::updateWidget and
// moved down into HTMLPluginElement.cpp
void HTMLObjectElement::updateWidgetInternal()
@@ -270,14 +299,18 @@ void HTMLObjectElement::updateWidgetInternal()
ASSERT(needsWidgetUpdate());
setNeedsWidgetUpdate(false);
// FIXME: This should ASSERT isFinishedParsingChildren() instead.
- if (!isFinishedParsingChildren())
+ if (!isFinishedParsingChildren()) {
+ dispatchErrorEvent();
return;
+ }
// FIXME: I'm not sure it's ever possible to get into updateWidget during a
// removal, but just in case we should avoid loading the frame to prevent
// security bugs.
- if (!SubframeLoadingDisabler::canLoadFrame(*this))
+ if (!SubframeLoadingDisabler::canLoadFrame(*this)) {
+ dispatchErrorEvent();
return;
+ }
String url = this->url();
String serviceType = m_serviceType;
@@ -288,20 +321,21 @@ void HTMLObjectElement::updateWidgetInternal()
parametersForPlugin(paramNames, paramValues, url, serviceType);
// Note: url is modified above by parametersForPlugin.
- if (!allowedToLoadFrameURL(url))
+ if (!allowedToLoadFrameURL(url)) {
+ dispatchErrorEvent();
return;
+ }
- bool fallbackContent = hasFallbackContent();
- renderEmbeddedObject()->setHasFallbackContent(fallbackContent);
-
- RefPtr<HTMLObjectElement> protect(this); // beforeload and plugin loading can make arbitrary DOM mutations.
- bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url);
- if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer.
+ // FIXME: Is it possible to get here without a renderer now that we don't have beforeload events?
+ if (!renderer())
return;
- bool success = beforeLoadAllowedLoad && hasValidClassId() && requestObject(url, serviceType, paramNames, paramValues);
- if (!success && fallbackContent)
- renderFallbackContent();
+ if (!hasValidClassId() || !requestObject(url, serviceType, paramNames, paramValues)) {
+ if (!url.isEmpty())
+ dispatchErrorEvent();
+ if (hasFallbackContent())
+ renderFallbackContent();
+ }
}
bool HTMLObjectElement::rendererIsNeeded(const RenderStyle& style)
@@ -329,7 +363,7 @@ void HTMLObjectElement::childrenChanged(bool changedByParser, Node* beforeChange
{
if (inDocument() && !useFallbackContent()) {
setNeedsWidgetUpdate(true);
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
HTMLPlugInElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
}
@@ -341,6 +375,16 @@ bool HTMLObjectElement::isURLAttribute(const Attribute& attribute) const
|| HTMLPlugInElement::isURLAttribute(attribute);
}
+bool HTMLObjectElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == classidAttr || name == dataAttr || name == codebaseAttr || HTMLPlugInElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLObjectElement::subResourceAttributeName() const
+{
+ return dataAttr;
+}
+
const AtomicString HTMLObjectElement::imageSourceURL() const
{
return getAttribute(dataAttr);
@@ -385,12 +429,12 @@ void HTMLObjectElement::renderFallbackContent()
bool HTMLObjectElement::isExposed() const
{
// http://www.whatwg.org/specs/web-apps/current-work/#exposed
- for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
- if (ancestor->hasTagName(objectTag) && toHTMLObjectElement(ancestor)->isExposed())
+ for (HTMLObjectElement* ancestor = Traversal<HTMLObjectElement>::firstAncestor(*this); ancestor; ancestor = Traversal<HTMLObjectElement>::firstAncestor(*ancestor)) {
+ if (ancestor->isExposed())
return false;
}
- for (Node* node = firstChild(); node; node = NodeTraversal::next(*node, this)) {
- if (node->hasTagName(objectTag) || node->hasTagName(embedTag))
+ for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(*this); element; element = Traversal<HTMLElement>::next(*element, this)) {
+ if (isHTMLObjectElement(*element) || isHTMLEmbedElement(*element))
return false;
}
return true;
@@ -401,33 +445,20 @@ bool HTMLObjectElement::containsJavaApplet() const
if (MIMETypeRegistry::isJavaAppletMIMEType(getAttribute(typeAttr)))
return true;
- for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSkippingChildren(*child, this)) {
- if (child->hasTagName(paramTag)
+ for (HTMLElement* child = Traversal<HTMLElement>::firstChild(*this); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ if (isHTMLParamElement(*child)
&& equalIgnoringCase(child->getNameAttribute(), "type")
&& MIMETypeRegistry::isJavaAppletMIMEType(child->getAttribute(valueAttr).string()))
return true;
- if (child->hasTagName(objectTag) && toHTMLObjectElement(child)->containsJavaApplet())
+ if (isHTMLObjectElement(*child) && toHTMLObjectElement(*child).containsJavaApplet())
return true;
- if (child->hasTagName(appletTag))
+ if (isHTMLAppletElement(*child))
return true;
}
return false;
}
-void HTMLObjectElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLPlugInElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(dataAttr)));
-
- // FIXME: Passing a string that starts with "#" to the completeURL function does
- // not seem like it would work. The image element has similar but not identical code.
- const AtomicString& useMap = getAttribute(usemapAttr);
- if (useMap.startsWith('#'))
- addSubresourceURL(urls, document().completeURL(useMap));
-}
-
void HTMLObjectElement::didMoveToNewDocument(Document& oldDocument)
{
FormAssociatedElement::didMoveToNewDocument(oldDocument);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h
index fc2c20860b5..ae30514a0e0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.h
@@ -31,9 +31,12 @@ namespace WebCore {
class HTMLFormElement;
class HTMLObjectElement FINAL : public HTMLPlugInElement, public FormAssociatedElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLObjectElement);
+
public:
- static PassRefPtr<HTMLObjectElement> create(Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLObjectElement> create(Document&, HTMLFormElement*, bool createdByParser);
virtual ~HTMLObjectElement();
+ virtual void trace(Visitor*) OVERRIDE;
const String& classId() const { return m_classId; }
@@ -41,14 +44,15 @@ public:
bool containsJavaApplet() const;
+ virtual bool hasFallbackContent() const OVERRIDE;
virtual bool useFallbackContent() const OVERRIDE;
virtual void renderFallbackContent() OVERRIDE;
- virtual bool isFormControlElement() const { return false; }
+ virtual bool isFormControlElement() const OVERRIDE { return false; }
- virtual bool isEnumeratable() const { return true; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
- virtual bool appendFormData(FormDataList&, bool);
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
virtual bool isObjectElement() const OVERRIDE { return true; }
@@ -58,10 +62,12 @@ public:
bool checkValidity() { return true; }
virtual void setCustomValidity(const String&) OVERRIDE { }
+#if !ENABLE(OILPAN)
using Node::ref;
using Node::deref;
+#endif
- virtual bool canContainRangeEndPoint() const { return useFallbackContent(); }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return useFallbackContent(); }
bool isExposed() const;
@@ -75,25 +81,23 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
virtual const AtomicString imageSourceURL() const OVERRIDE;
virtual RenderWidget* existingRenderWidget() const OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-
virtual void updateWidgetInternal() OVERRIDE;
void updateDocNamedItem();
void reattachFallbackContent();
- bool hasFallbackContent() const;
-
// FIXME: This function should not deal with url or serviceType
// so that we can better share code between <object> and <embed>.
void parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues, String& url, String& serviceType);
@@ -101,8 +105,12 @@ private:
bool shouldAllowQuickTimeClassIdQuirk();
bool hasValidClassId();
- virtual void refFormAssociatedElement() { ref(); }
- virtual void derefFormAssociatedElement() { deref(); }
+ void reloadPluginOnAttributeChange(const QualifiedName&);
+
+#if !ENABLE(OILPAN)
+ virtual void refFormAssociatedElement() OVERRIDE { ref(); }
+ virtual void derefFormAssociatedElement() OVERRIDE { deref(); }
+#endif
virtual bool shouldRegisterAsNamedItem() const OVERRIDE { return true; }
virtual bool shouldRegisterAsExtraNamedItem() const OVERRIDE { return true; }
@@ -111,9 +119,13 @@ private:
bool m_useFallbackContent : 1;
};
-DEFINE_NODE_TYPE_CASTS(HTMLObjectElement, hasTagName(HTMLNames::objectTag));
+// Intentionally left unimplemented, template specialization needs to be provided for specific
+// return types.
+template<typename T> inline const T& toElement(const FormAssociatedElement&);
+template<typename T> inline const T* toElement(const FormAssociatedElement*);
-inline const HTMLObjectElement* toHTMLObjectElement(const FormAssociatedElement* element)
+// Make toHTMLObjectElement() accept a FormAssociatedElement as input instead of a Node.
+template<> inline const HTMLObjectElement* toElement<HTMLObjectElement>(const FormAssociatedElement* element)
{
ASSERT_WITH_SECURITY_IMPLICATION(!element || !element->isFormControlElement());
const HTMLObjectElement* objectElement = static_cast<const HTMLObjectElement*>(element);
@@ -123,7 +135,7 @@ inline const HTMLObjectElement* toHTMLObjectElement(const FormAssociatedElement*
return objectElement;
}
-inline const HTMLObjectElement& toHTMLObjectElement(const FormAssociatedElement& element)
+template<> inline const HTMLObjectElement& toElement<HTMLObjectElement>(const FormAssociatedElement& element)
{
ASSERT_WITH_SECURITY_IMPLICATION(!element.isFormControlElement());
const HTMLObjectElement& objectElement = static_cast<const HTMLObjectElement&>(element);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
index 2393f057dd9..b6c7ccee7c2 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLObjectElement.idl
@@ -28,7 +28,7 @@
[Reflect, TreatNullAs=NullString] attribute DOMString border;
[Reflect, URL] attribute DOMString codeBase;
[Reflect] attribute DOMString codeType;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString data;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString data;
[Reflect] attribute boolean declare;
[Reflect] attribute DOMString height;
[Reflect] attribute long hspace;
@@ -51,5 +51,7 @@
[Custom, NotEnumerable] getter Node (DOMString name);
[Custom] setter Node (DOMString name, Node value);
- [CheckSecurity=Node, RaisesException] SVGDocument getSVGDocument();
+ [CheckSecurity=Node, RaisesException] Document getSVGDocument();
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp
index c9963b0ece4..01c307a46d6 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/html/HTMLOptGroupElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/html/HTMLSelectElement.h"
@@ -42,10 +42,7 @@ inline HTMLOptGroupElement::HTMLOptGroupElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOptGroupElement> HTMLOptGroupElement::create(Document& document)
-{
- return adoptRef(new HTMLOptGroupElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLOptGroupElement)
bool HTMLOptGroupElement::isDisabledFormControl() const
{
@@ -58,12 +55,6 @@ bool HTMLOptGroupElement::rendererIsFocusable() const
return renderStyle() && renderStyle()->display() != NONE;
}
-const AtomicString& HTMLOptGroupElement::formControlType() const
-{
- DEFINE_STATIC_LOCAL(const AtomicString, optgroup, ("optgroup", AtomicString::ConstructFromLiteral));
- return optgroup;
-}
-
void HTMLOptGroupElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
recalcSelectOptions();
@@ -81,21 +72,17 @@ void HTMLOptGroupElement::parseAttribute(const QualifiedName& name, const Atomic
void HTMLOptGroupElement::recalcSelectOptions()
{
- ContainerNode* select = parentNode();
- while (select && !select->hasTagName(selectTag))
- select = select->parentNode();
- if (select)
- toHTMLSelectElement(select)->setRecalcListItems();
+ if (HTMLSelectElement* select = Traversal<HTMLSelectElement>::firstAncestor(*this))
+ select->setRecalcListItems();
}
void HTMLOptGroupElement::attach(const AttachContext& context)
{
+ if (context.resolvedStyle) {
+ ASSERT(!m_style || m_style == context.resolvedStyle);
+ m_style = context.resolvedStyle;
+ }
HTMLElement::attach(context);
- // If after attaching nothing called styleForRenderer() on this node we
- // manually cache the value. This happens if our parent doesn't have a
- // renderer like <optgroup> or if it doesn't allow children like <select>.
- if (!m_style && parentNode()->renderStyle())
- updateNonRenderStyle();
}
void HTMLOptGroupElement::detach(const AttachContext& context)
@@ -106,7 +93,12 @@ void HTMLOptGroupElement::detach(const AttachContext& context)
void HTMLOptGroupElement::updateNonRenderStyle()
{
+ bool oldDisplayNoneStatus = isDisplayNone();
m_style = originalStyleForRenderer();
+ if (oldDisplayNoneStatus != isDisplayNone()) {
+ if (HTMLSelectElement* select = ownerSelectElement())
+ select->updateListOnRenderer();
+ }
}
RenderStyle* HTMLOptGroupElement::nonRendererStyle() const
@@ -116,8 +108,6 @@ RenderStyle* HTMLOptGroupElement::nonRendererStyle() const
PassRefPtr<RenderStyle> HTMLOptGroupElement::customStyleForRenderer()
{
- // styleForRenderer is called whenever a new style should be associated
- // with an Element so now is a good time to update our cached style.
updateNonRenderStyle();
return m_style;
}
@@ -136,14 +126,7 @@ String HTMLOptGroupElement::groupLabelText() const
HTMLSelectElement* HTMLOptGroupElement::ownerSelectElement() const
{
- ContainerNode* select = parentNode();
- while (select && !select->hasTagName(selectTag))
- select = select->parentNode();
-
- if (!select)
- return 0;
-
- return toHTMLSelectElement(select);
+ return Traversal<HTMLSelectElement>::firstAncestor(*this);
}
void HTMLOptGroupElement::accessKeyAction(bool)
@@ -154,4 +137,10 @@ void HTMLOptGroupElement::accessKeyAction(bool)
select->accessKeyAction(false);
}
+bool HTMLOptGroupElement::isDisplayNone() const
+{
+ RenderStyle* style = nonRendererStyle();
+ return style && style->display() == NONE;
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h
index 54ed7b5647d..a6674e0784e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h
@@ -32,26 +32,27 @@ class HTMLSelectElement;
class HTMLOptGroupElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLOptGroupElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLOptGroupElement);
virtual bool isDisabledFormControl() const OVERRIDE;
HTMLSelectElement* ownerSelectElement() const;
String groupLabelText() const;
+ bool isDisplayNone() const;
+
private:
explicit HTMLOptGroupElement(Document&);
- virtual const AtomicString& formControlType() const;
virtual bool rendererIsFocusable() const OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
// <optgroup> never has a renderer so we manually manage a cached style.
void updateNonRenderStyle();
@@ -63,23 +64,6 @@ private:
RefPtr<RenderStyle> m_style;
};
-inline bool isHTMLOptGroupElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::optgroupTag);
-}
-
-inline bool isHTMLOptGroupElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::optgroupTag);
-}
-
-inline bool isHTMLOptGroupElement(const Element& element)
-{
- return element.hasTagName(HTMLNames::optgroupTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLOptGroupElement, hasTagName(HTMLNames::optgroupTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp
index 0240fb2871e..79239f43d70 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.cpp
@@ -27,15 +27,14 @@
#include "config.h"
#include "core/html/HTMLOptionElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/ScriptLoader.h"
#include "core/dom/Text.h"
#include "core/html/HTMLDataListElement.h"
-#include "core/html/HTMLOptGroupElement.h"
#include "core/html/HTMLSelectElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/rendering/RenderTheme.h"
@@ -55,21 +54,18 @@ HTMLOptionElement::HTMLOptionElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOptionElement> HTMLOptionElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLOptionElement> HTMLOptionElement::create(Document& document)
{
- return adoptRef(new HTMLOptionElement(document));
+ return adoptRefWillBeNoop(new HTMLOptionElement(document));
}
-PassRefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document& document, const String& data, const AtomicString& value,
+PassRefPtrWillBeRawPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document& document, const String& data, const AtomicString& value,
bool defaultSelected, bool selected, ExceptionState& exceptionState)
{
- RefPtr<HTMLOptionElement> element = adoptRef(new HTMLOptionElement(document));
-
- RefPtr<Text> text = Text::create(document, data.isNull() ? "" : data);
-
- element->appendChild(text.release(), exceptionState);
+ RefPtrWillBeRawPtr<HTMLOptionElement> element = adoptRefWillBeNoop(new HTMLOptionElement(document));
+ element->appendChild(Text::create(document, data.isNull() ? "" : data), exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
if (!value.isNull())
element->setValue(value);
@@ -82,12 +78,15 @@ PassRefPtr<HTMLOptionElement> HTMLOptionElement::createForJSConstructor(Document
void HTMLOptionElement::attach(const AttachContext& context)
{
- HTMLElement::attach(context);
- // If after attaching nothing called styleForRenderer() on this node we
- // manually cache the value. This happens if our parent doesn't have a
- // renderer like <optgroup> or if it doesn't allow children like <select>.
- if (!m_style && parentNode()->renderStyle())
+ AttachContext optionContext(context);
+ if (context.resolvedStyle) {
+ ASSERT(!m_style || m_style == context.resolvedStyle);
+ m_style = context.resolvedStyle;
+ } else {
updateNonRenderStyle();
+ optionContext.resolvedStyle = m_style.get();
+ }
+ HTMLElement::attach(optionContext);
}
void HTMLOptionElement::detach(const AttachContext& context)
@@ -122,12 +121,12 @@ String HTMLOptionElement::text() const
void HTMLOptionElement::setText(const String &text, ExceptionState& exceptionState)
{
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
// Changing the text causes a recalc of a select's items, which will reset the selected
// index to the first item if the select is single selection with a menu list. We attempt to
// preserve the selected item.
- RefPtr<HTMLSelectElement> select = ownerSelectElement();
+ RefPtrWillBeRawPtr<HTMLSelectElement> select = ownerSelectElement();
bool selectIsMenuList = select && select->usesMenuList();
int oldSelectedIndex = selectIsMenuList ? select->selectedIndex() : -1;
@@ -146,8 +145,7 @@ void HTMLOptionElement::setText(const String &text, ExceptionState& exceptionSta
void HTMLOptionElement::accessKeyAction(bool)
{
- HTMLSelectElement* select = ownerSelectElement();
- if (select)
+ if (HTMLSelectElement* select = ownerSelectElement())
select->accessKeySetSelectedIndex(index());
}
@@ -161,12 +159,12 @@ int HTMLOptionElement::index() const
int optionIndex = 0;
- const Vector<HTMLElement*>& items = selectElement->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = selectElement->listItems();
size_t length = items.size();
for (size_t i = 0; i < length; ++i) {
- if (!items[i]->hasTagName(optionTag))
+ if (!isHTMLOptionElement(*items[i]))
continue;
- if (items[i] == this)
+ if (items[i].get() == this)
return optionIndex;
++optionIndex;
}
@@ -185,7 +183,7 @@ void HTMLOptionElement::parseAttribute(const QualifiedName& name, const AtomicSt
if (oldDisabled != m_disabled) {
didAffectSelector(AffectedSelectorDisabled | AffectedSelectorEnabled);
if (renderer() && renderer()->style()->hasAppearance())
- RenderTheme::theme().stateChanged(renderer(), EnabledState);
+ RenderTheme::theme().stateChanged(renderer(), EnabledControlState);
}
} else if (name == selectedAttr) {
if (bool willBeSelected = !value.isNull())
@@ -207,17 +205,17 @@ void HTMLOptionElement::setValue(const AtomicString& value)
setAttribute(valueAttr, value);
}
-bool HTMLOptionElement::selected()
+bool HTMLOptionElement::selected() const
{
if (HTMLSelectElement* select = ownerSelectElement()) {
// If a stylesheet contains option:checked selectors, this function is
// called during parsing. updateListItemSelectedStates() is O(N) where N
// is the number of option elements, so the <select> parsing would be
- // O(N^2) without isParsingInProgress check. Also,
+ // O(N^2) without the isFinishedParsingChildren check. Also,
// updateListItemSelectedStates() determines default selection, and we'd
// like to avoid to determine default selection with incomplete option
// list.
- if (select->isParsingInProgress())
+ if (!select->isFinishedParsingChildren())
return m_isSelected;
select->updateListItemSelectedStates();
}
@@ -258,23 +256,12 @@ void HTMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange
HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const
{
- for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) {
- if (parent->hasTagName(datalistTag))
- return toHTMLDataListElement(parent);
- }
- return 0;
+ return Traversal<HTMLDataListElement>::firstAncestor(*this);
}
HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const
{
- ContainerNode* select = parentNode();
- while (select && !select->hasTagName(selectTag))
- select = select->parentNode();
-
- if (!select)
- return 0;
-
- return toHTMLSelectElement(select);
+ return Traversal<HTMLSelectElement>::firstAncestor(*this);
}
String HTMLOptionElement::label() const
@@ -292,7 +279,12 @@ void HTMLOptionElement::setLabel(const AtomicString& label)
void HTMLOptionElement::updateNonRenderStyle()
{
+ bool oldDisplayNoneStatus = isDisplayNone();
m_style = originalStyleForRenderer();
+ if (oldDisplayNoneStatus != isDisplayNone()) {
+ if (HTMLSelectElement* select = ownerSelectElement())
+ select->updateListOnRenderer();
+ }
}
RenderStyle* HTMLOptionElement::nonRendererStyle() const
@@ -302,26 +294,26 @@ RenderStyle* HTMLOptionElement::nonRendererStyle() const
PassRefPtr<RenderStyle> HTMLOptionElement::customStyleForRenderer()
{
- // styleForRenderer is called whenever a new style should be associated
- // with an Element so now is a good time to update our cached style.
updateNonRenderStyle();
return m_style;
}
-void HTMLOptionElement::didRecalcStyle(StyleRecalcChange)
+void HTMLOptionElement::didRecalcStyle(StyleRecalcChange change)
{
- // FIXME: This is nasty, we ask our owner select to repaint even if the new
- // style is exactly the same.
+ if (change == NoChange)
+ return;
+
+ // FIXME: We ask our owner select to repaint regardless of which property changed.
if (HTMLSelectElement* select = ownerSelectElement()) {
if (RenderObject* renderer = select->renderer())
- renderer->repaint();
+ renderer->paintInvalidationForWholeRenderer();
}
}
String HTMLOptionElement::textIndentedToRespectGroupLabel() const
{
ContainerNode* parent = parentNode();
- if (parent && isHTMLOptGroupElement(parent))
+ if (parent && isHTMLOptGroupElement(*parent))
return " " + text();
return text();
}
@@ -331,7 +323,7 @@ bool HTMLOptionElement::isDisabledFormControl() const
if (ownElementDisabled())
return true;
if (Element* parent = parentElement())
- return isHTMLOptGroupElement(parent) && parent->isDisabledFormControl();
+ return isHTMLOptGroupElement(*parent) && parent->isDisabledFormControl();
return false;
}
@@ -368,11 +360,22 @@ String HTMLOptionElement::collectOptionInnerText() const
HTMLFormElement* HTMLOptionElement::form() const
{
- HTMLSelectElement* selectElement = ownerSelectElement();
- if (!selectElement)
- return 0;
+ if (HTMLSelectElement* selectElement = ownerSelectElement())
+ return selectElement->formOwner();
- return selectElement->formOwner();
+ return 0;
+}
+
+bool HTMLOptionElement::isDisplayNone() const
+{
+ ContainerNode* parent = parentNode();
+ // Check for parent optgroup having display NONE
+ if (parent && isHTMLOptGroupElement(*parent)) {
+ if (toHTMLOptGroupElement(*parent).isDisplayNone())
+ return true;
+ }
+ RenderStyle* style = nonRendererStyle();
+ return style && style->display() == NONE;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h
index 1f79a1bd81a..65e1a2394b8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.h
@@ -35,11 +35,11 @@ class HTMLSelectElement;
class HTMLOptionElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLOptionElement> create(Document&);
- static PassRefPtr<HTMLOptionElement> createForJSConstructor(Document&, const String& data, const AtomicString& value,
+ static PassRefPtrWillBeRawPtr<HTMLOptionElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLOptionElement> createForJSConstructor(Document&, const String& data, const AtomicString& value,
bool defaultSelected, bool selected, ExceptionState&);
- virtual String text() const;
+ String text() const;
void setText(const String&, ExceptionState&);
int index() const;
@@ -47,7 +47,7 @@ public:
String value() const;
void setValue(const AtomicString&);
- bool selected();
+ bool selected() const;
void setSelected(bool);
HTMLDataListElement* ownerDataListElement() const;
@@ -66,27 +66,28 @@ public:
HTMLFormElement* form() const;
+ bool isDisplayNone() const;
+
private:
explicit HTMLOptionElement(Document&);
virtual bool rendererIsFocusable() const OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual void accessKeyAction(bool);
+ virtual void accessKeyAction(bool) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
// <option> never has a renderer so we manually manage a cached style.
void updateNonRenderStyle();
virtual RenderStyle* nonRendererStyle() const OVERRIDE;
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
-
- void didRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
String collectOptionInnerText() const;
@@ -95,8 +96,6 @@ private:
RefPtr<RenderStyle> m_style;
};
-DEFINE_NODE_TYPE_CASTS(HTMLOptionElement, hasTagName(HTMLNames::optionTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl
index 41c6592f239..d57d72a5a97 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionElement.idl
@@ -19,7 +19,11 @@
*/
[
- NamedConstructor=Option([Default=NullString] optional DOMString data, [Default=NullString] optional DOMString value, [Default=Undefined] optional boolean defaultSelected, [Default=Undefined] optional boolean selected),
+ NamedConstructor=Option(optional DOMString data = null,
+ optional DOMString value = null,
+ [Default=Undefined] optional boolean defaultSelected,
+ [Default=Undefined] optional boolean selected),
+ ConstructorCallWith=Document,
RaisesException=Constructor
] interface HTMLOptionElement : HTMLElement {
[Reflect] attribute boolean disabled;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp
index aae87b078b9..e27e0e1629d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006, 2011, 2012 Apple Computer, Inc.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -30,24 +31,50 @@
namespace WebCore {
-HTMLOptionsCollection::HTMLOptionsCollection(Node* select)
+HTMLOptionsCollection::HTMLOptionsCollection(ContainerNode& select)
: HTMLCollection(select, SelectOptions, DoesNotOverrideItemAfter)
{
- ASSERT(select->hasTagName(HTMLNames::selectTag));
+ ASSERT(isHTMLSelectElement(select));
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(Node* select, CollectionType)
+void HTMLOptionsCollection::supportedPropertyNames(Vector<String>& names)
{
- return adoptRef(new HTMLOptionsCollection(select));
+ // As per http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmloptionscollection:
+ // The supported property names consist of the non-empty values of all the id and name attributes of all the elements
+ // represented by the collection, in tree order, ignoring later duplicates, with the id of an element preceding its
+ // name if it contributes both, they differ from each other, and neither is the duplicate of an earlier entry.
+ HashSet<AtomicString> existingNames;
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ Element* element = item(i);
+ ASSERT(element);
+ const AtomicString& idAttribute = element->getIdAttribute();
+ if (!idAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(idAttribute);
+ if (addResult.isNewEntry)
+ names.append(idAttribute);
+ }
+ const AtomicString& nameAttribute = element->getNameAttribute();
+ if (!nameAttribute.isEmpty()) {
+ HashSet<AtomicString>::AddResult addResult = existingNames.add(nameAttribute);
+ if (addResult.isNewEntry)
+ names.append(nameAttribute);
+ }
+ }
+}
+
+PassRefPtrWillBeRawPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(ContainerNode& select, CollectionType)
+{
+ return adoptRefWillBeNoop(new HTMLOptionsCollection(select));
}
-void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, ExceptionState& exceptionState)
+void HTMLOptionsCollection::add(PassRefPtrWillBeRawPtr<HTMLOptionElement> element, ExceptionState& exceptionState)
{
add(element, length(), exceptionState);
}
-void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, int index, ExceptionState& exceptionState)
+void HTMLOptionsCollection::add(PassRefPtrWillBeRawPtr<HTMLOptionElement> element, int index, ExceptionState& exceptionState)
{
HTMLOptionElement* newOption = element.get();
@@ -61,19 +88,19 @@ void HTMLOptionsCollection::add(PassRefPtr<HTMLOptionElement> element, int index
return;
}
- HTMLSelectElement* select = toHTMLSelectElement(ownerNode());
+ HTMLSelectElement& select = toHTMLSelectElement(ownerNode());
if (index == -1 || unsigned(index) >= length())
- select->add(newOption, 0, exceptionState);
+ select.add(newOption, 0, exceptionState);
else
- select->add(newOption, toHTMLOptionElement(item(index)), exceptionState);
+ select.addBeforeOptionAtIndex(newOption, index, exceptionState);
ASSERT(!exceptionState.hadException());
}
void HTMLOptionsCollection::remove(int index)
{
- toHTMLSelectElement(ownerNode())->remove(index);
+ toHTMLSelectElement(ownerNode()).remove(index);
}
void HTMLOptionsCollection::remove(HTMLOptionElement* option)
@@ -83,22 +110,22 @@ void HTMLOptionsCollection::remove(HTMLOptionElement* option)
int HTMLOptionsCollection::selectedIndex() const
{
- return toHTMLSelectElement(ownerNode())->selectedIndex();
+ return toHTMLSelectElement(ownerNode()).selectedIndex();
}
void HTMLOptionsCollection::setSelectedIndex(int index)
{
- toHTMLSelectElement(ownerNode())->setSelectedIndex(index);
+ toHTMLSelectElement(ownerNode()).setSelectedIndex(index);
}
void HTMLOptionsCollection::setLength(unsigned length, ExceptionState& exceptionState)
{
- toHTMLSelectElement(ownerNode())->setLength(length, exceptionState);
+ toHTMLSelectElement(ownerNode()).setLength(length, exceptionState);
}
-void HTMLOptionsCollection::anonymousNamedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Node>& returnValue1)
+void HTMLOptionsCollection::namedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtrWillBeRawPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtrWillBeRawPtr<Element>& returnValue1)
{
- Vector<RefPtr<Node> > namedItems;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > namedItems;
this->namedItems(name, namedItems);
if (!namedItems.size())
@@ -110,25 +137,19 @@ void HTMLOptionsCollection::anonymousNamedGetter(const AtomicString& name, bool&
return;
}
+ // FIXME: The spec and Firefox do not return a NodeList. They always return the first matching Element.
returnValue0Enabled = true;
returnValue0 = NamedNodesCollection::create(namedItems);
}
-bool HTMLOptionsCollection::anonymousIndexedSetterRemove(unsigned index, ExceptionState& exceptionState)
-{
- HTMLSelectElement* base = toHTMLSelectElement(ownerNode());
- base->remove(index);
- return true;
-}
-
-bool HTMLOptionsCollection::anonymousIndexedSetter(unsigned index, PassRefPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
+bool HTMLOptionsCollection::anonymousIndexedSetter(unsigned index, PassRefPtrWillBeRawPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
{
- HTMLSelectElement* base = toHTMLSelectElement(ownerNode());
- if (!value) {
- exceptionState.throwTypeError(ExceptionMessages::failedToSet(String::number(index), "HTMLOptionsCollection", "The element provided was not an HTMLOptionElement."));
+ HTMLSelectElement& base = toHTMLSelectElement(ownerNode());
+ if (!value) { // undefined or null
+ base.remove(index);
return true;
}
- base->setOption(index, value.get(), exceptionState);
+ base.setOption(index, value.get(), exceptionState);
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h
index fe5ad5d746e..bb888abf002 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.h
@@ -34,10 +34,10 @@ class HTMLSelectElement;
class HTMLOptionsCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<HTMLOptionsCollection> create(Node*, CollectionType);
+ static PassRefPtrWillBeRawPtr<HTMLOptionsCollection> create(ContainerNode&, CollectionType);
- void add(PassRefPtr<HTMLOptionElement>, ExceptionState&);
- void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionState&);
+ void add(PassRefPtrWillBeRawPtr<HTMLOptionElement>, ExceptionState&);
+ void add(PassRefPtrWillBeRawPtr<HTMLOptionElement>, int index, ExceptionState&);
void remove(int index);
void remove(HTMLOptionElement*);
@@ -45,14 +45,17 @@ public:
void setSelectedIndex(int);
void setLength(unsigned, ExceptionState&);
- void anonymousNamedGetter(const AtomicString& name, bool&, RefPtr<NodeList>&, bool&, RefPtr<Node>&);
- bool anonymousIndexedSetter(unsigned, PassRefPtr<HTMLOptionElement>, ExceptionState&);
- bool anonymousIndexedSetterRemove(unsigned, ExceptionState&);
+ void namedGetter(const AtomicString& name, bool&, RefPtrWillBeRawPtr<NodeList>&, bool&, RefPtrWillBeRawPtr<Element>&);
+ bool anonymousIndexedSetter(unsigned, PassRefPtrWillBeRawPtr<HTMLOptionElement>, ExceptionState&);
private:
- explicit HTMLOptionsCollection(Node*);
+ explicit HTMLOptionsCollection(ContainerNode&);
+
+ virtual void supportedPropertyNames(Vector<String>& names) OVERRIDE;
};
+DEFINE_TYPE_CASTS(HTMLOptionsCollection, LiveNodeListBase, collection, collection->type() == SelectOptions, collection.type() == SelectOptions);
+
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl
index 32c414795d1..a802b20e388 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOptionsCollection.idl
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
* Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2013, 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,19 +21,17 @@
[
DependentLifetime,
- GenerateVisitDOMWrapper=ownerNode,
+ SetWrapperReferenceFrom=ownerNode,
] interface HTMLOptionsCollection : HTMLCollection {
attribute long selectedIndex;
[Custom=Setter, RaisesException=Setter] attribute unsigned long length;
- [ImplementedAs=item] getter Node(unsigned long index);
- [ImplementedAs=anonymousIndexedSetter, RaisesException] setter HTMLOptionElement (unsigned long index, [TreatNullAs=anonymousIndexedSetterRemove, TreatUndefinedAs=anonymousIndexedSetterRemove] HTMLOptionElement value);
- [ImplementedAs=anonymousNamedGetter, NotEnumerable] getter (NodeList or Node)(DOMString name);
+ [ImplementedAs=item] getter Node (unsigned long index);
+ [RaisesException, TypeChecking=Interface|Nullable] setter HTMLOptionElement (unsigned long index, HTMLOptionElement? value);
- [Custom] Node namedItem([Default=Undefined] optional DOMString name);
+ // FIXME: The spec and firefox return an Element (the first matching Element).
+ [ImplementedAs=namedGetter] getter (NodeList or Element) namedItem(DOMString name);
- [Custom, RaisesException] void add([Default=Undefined] optional HTMLOptionElement option,
- optional unsigned long index);
+ [Custom, RaisesException] void add([Default=Undefined] optional HTMLOptionElement option, optional unsigned long index);
void remove(unsigned long index);
- void remove(HTMLOptionElement option); // Non standard.
+ [MeasureAs=HTMLOptionsCollectionRemoveElement] void remove(HTMLOptionElement option); // non-standard
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
index 00d04356f9c..733b6ff38d0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.cpp
@@ -31,24 +31,23 @@
#include "config.h"
#include "core/html/HTMLOutputElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
namespace WebCore {
inline HTMLOutputElement::HTMLOutputElement(Document& document, HTMLFormElement* form)
: HTMLFormControlElement(HTMLNames::outputTag, document, form)
, m_isDefaultValueMode(true)
- , m_isSetTextContentInProgress(false)
, m_defaultValue("")
, m_tokens(DOMSettableTokenList::create())
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLOutputElement> HTMLOutputElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLOutputElement> HTMLOutputElement::create(Document& document, HTMLFormElement* form)
{
- return adoptRef(new HTMLOutputElement(document, form));
+ return adoptRefWillBeNoop(new HTMLOutputElement(document, form));
}
const AtomicString& HTMLOutputElement::formControlType() const
@@ -75,7 +74,7 @@ DOMSettableTokenList* HTMLOutputElement::htmlFor() const
return m_tokens.get();
}
-void HTMLOutputElement::setFor(const String& value)
+void HTMLOutputElement::setFor(const AtomicString& value)
{
m_tokens->setValue(value);
}
@@ -84,11 +83,6 @@ void HTMLOutputElement::childrenChanged(bool createdByParser, Node* beforeChange
{
HTMLFormControlElement::childrenChanged(createdByParser, beforeChange, afterChange, childCountDelta);
- if (createdByParser || m_isSetTextContentInProgress) {
- m_isSetTextContentInProgress = false;
- return;
- }
-
if (m_isDefaultValueMode)
m_defaultValue = textContent();
}
@@ -98,10 +92,10 @@ void HTMLOutputElement::resetImpl()
// The reset algorithm for output elements is to set the element's
// value mode flag to "default" and then to set the element's textContent
// attribute to the default value.
- m_isDefaultValueMode = true;
if (m_defaultValue == value())
return;
- setTextContentInternal(m_defaultValue);
+ setTextContent(m_defaultValue);
+ m_isDefaultValueMode = true;
}
String HTMLOutputElement::value() const
@@ -115,7 +109,7 @@ void HTMLOutputElement::setValue(const String& value)
m_isDefaultValueMode = false;
if (value == this->value())
return;
- setTextContentInternal(value);
+ setTextContent(value);
}
String HTMLOutputElement::defaultValue() const
@@ -131,14 +125,14 @@ void HTMLOutputElement::setDefaultValue(const String& value)
// The spec requires the value attribute set to the default value
// when the element's value mode flag to "default".
if (m_isDefaultValueMode)
- setTextContentInternal(value);
+ setTextContent(value);
}
-void HTMLOutputElement::setTextContentInternal(const String& value)
+
+void HTMLOutputElement::trace(Visitor* visitor)
{
- ASSERT(!m_isSetTextContentInProgress);
- m_isSetTextContentInProgress = true;
- setTextContent(value);
+ visitor->trace(m_tokens);
+ HTMLFormControlElement::trace(visitor);
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h
index bf1e469e715..d554341032a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLOutputElement.h
@@ -38,36 +38,35 @@ namespace WebCore {
class HTMLOutputElement FINAL : public HTMLFormControlElement {
public:
- static PassRefPtr<HTMLOutputElement> create(Document&, HTMLFormElement*);
+ static PassRefPtrWillBeRawPtr<HTMLOutputElement> create(Document&, HTMLFormElement*);
- virtual bool willValidate() const { return false; }
+ virtual bool willValidate() const OVERRIDE { return false; }
String value() const;
void setValue(const String&);
String defaultValue() const;
void setDefaultValue(const String&);
- void setFor(const String&);
+ void setFor(const AtomicString&);
DOMSettableTokenList* htmlFor() const;
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
HTMLOutputElement(Document&, HTMLFormElement*);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual const AtomicString& formControlType() const;
- virtual bool isEnumeratable() const { return true; }
+ virtual const AtomicString& formControlType() const OVERRIDE;
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool supportLabels() const OVERRIDE { return true; }
- virtual bool supportsFocus() const;
- virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual bool supportsFocus() const OVERRIDE;
+ virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual void resetImpl() OVERRIDE;
- void setTextContentInternal(const String&);
-
bool m_isDefaultValueMode;
- bool m_isSetTextContentInProgress;
String m_defaultValue;
- RefPtr<DOMSettableTokenList> m_tokens;
+ RefPtrWillBeMember<DOMSettableTokenList> m_tokens;
};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp
index 459800856f9..7cfea938976 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.cpp
@@ -23,9 +23,9 @@
#include "config.h"
#include "core/html/HTMLParagraphElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -37,17 +37,7 @@ inline HTMLParagraphElement::HTMLParagraphElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLParagraphElement> HTMLParagraphElement::create(Document& document)
-{
- return adoptRef(new HTMLParagraphElement(document));
-}
-
-bool HTMLParagraphElement::isPresentationAttribute(const QualifiedName& name) const
-{
- if (name == alignAttr)
- return true;
- return HTMLElement::isPresentationAttribute(name);
-}
+DEFINE_NODE_FACTORY(HTMLParagraphElement)
void HTMLParagraphElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h
index 4bfbbf64425..43b8d0ead20 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLParagraphElement.h
@@ -29,12 +29,11 @@ namespace WebCore {
class HTMLParagraphElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLParagraphElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLParagraphElement);
private:
explicit HTMLParagraphElement(Document&);
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp
index 982d53d993f..63c65aed352 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLParamElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
@@ -37,10 +37,7 @@ inline HTMLParamElement::HTMLParamElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLParamElement> HTMLParamElement::create(Document& document)
-{
- return adoptRef(new HTMLParamElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLParamElement)
const AtomicString& HTMLParamElement::name() const
{
@@ -66,14 +63,4 @@ bool HTMLParamElement::isURLAttribute(const Attribute& attribute) const
return HTMLElement::isURLAttribute(attribute);
}
-void HTMLParamElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- if (!isURLParameter(name()))
- return;
-
- addSubresourceURL(urls, document().completeURL(value()));
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h
index 991e9595db9..1d04d46b0d8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLParamElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLParamElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLParamElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLParamElement);
const AtomicString& name() const;
const AtomicString& value() const;
@@ -40,12 +40,8 @@ private:
explicit HTMLParamElement(Document&);
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
};
-DEFINE_NODE_TYPE_CASTS(HTMLParamElement, hasTagName(HTMLNames::paramTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.cpp
new file mode 100644
index 00000000000..d5361777b0b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.cpp
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLPictureElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/html/HTMLImageElement.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLPictureElement::HTMLPictureElement(Document& document)
+ : HTMLElement(pictureTag, document)
+{
+ ScriptWrappable::init(this);
+}
+
+DEFINE_NODE_FACTORY(HTMLPictureElement)
+
+void HTMLPictureElement::sourceOrMediaChanged()
+{
+ for (HTMLImageElement* imageElement = Traversal<HTMLImageElement>::firstChild(*this); imageElement; imageElement = Traversal<HTMLImageElement>::nextSibling(*imageElement)) {
+ imageElement->selectSourceURL(HTMLImageElement::UpdateNormal);
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.h
new file mode 100644
index 00000000000..c5cb0f501fd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.h
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HTMLPictureElement_h
+#define HTMLPictureElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+class HTMLPictureElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLPictureElement);
+
+ void sourceOrMediaChanged();
+
+protected:
+ explicit HTMLPictureElement(Document&);
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.idl
new file mode 100644
index 00000000000..649316cb8a1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPictureElement.idl
@@ -0,0 +1,10 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// http://picture.responsiveimages.org
+[
+ RuntimeEnabled=Picture
+] interface HTMLPictureElement : HTMLElement {
+};
+
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
index c4ba8d0a939..7cbceed497d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
@@ -23,19 +23,20 @@
#include "config.h"
#include "core/html/HTMLPlugInElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/npruntime_impl.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
-#include "core/dom/PostAttachCallbacks.h"
+#include "core/dom/Node.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/Event.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/HTMLContentElement.h"
#include "core/html/HTMLImageLoader.h"
#include "core/html/PluginDocument.h"
-#include "core/html/shadow/HTMLContentElement.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/page/EventHandler.h"
#include "core/page/Page.h"
@@ -59,7 +60,6 @@ HTMLPlugInElement::HTMLPlugInElement(const QualifiedName& tagName, Document& doc
, m_isDelayingLoadEvent(false)
, m_NPObject(0)
, m_isCapturingMouseEvents(false)
- , m_inBeforeLoadEventHandler(false)
// m_needsWidgetUpdate(!createdByParser) allows HTMLObjectElement to delay
// widget updates until after all children are parsed. For HTMLEmbedElement
// this delay is unnecessary, but it is simpler to make both classes share
@@ -82,6 +82,12 @@ HTMLPlugInElement::~HTMLPlugInElement()
}
}
+void HTMLPlugInElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_imageLoader);
+ HTMLFrameOwnerElement::trace(visitor);
+}
+
bool HTMLPlugInElement::canProcessDrag() const
{
return pluginWidget() && pluginWidget()->isPluginView() && toPluginView(pluginWidget())->canProcessDrag();
@@ -117,9 +123,10 @@ void HTMLPlugInElement::attach(const AttachContext& context)
if (!renderer() || useFallbackContent())
return;
+
if (isImageType()) {
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
m_imageLoader->updateFromElement();
} else if (needsWidgetUpdate()
&& renderEmbeddedObject()
@@ -128,12 +135,13 @@ void HTMLPlugInElement::attach(const AttachContext& context)
&& !m_isDelayingLoadEvent) {
m_isDelayingLoadEvent = true;
document().incrementLoadEventDelayCount();
+ document().loadPluginsSoon();
}
}
void HTMLPlugInElement::updateWidget()
{
- RefPtr<HTMLPlugInElement> protector(this);
+ RefPtrWillBeRawPtr<HTMLPlugInElement> protector(this);
updateWidgetInternal();
if (m_isDelayingLoadEvent) {
m_isDelayingLoadEvent = false;
@@ -141,6 +149,43 @@ void HTMLPlugInElement::updateWidget()
}
}
+void HTMLPlugInElement::requestPluginCreationWithoutRendererIfPossible()
+{
+ if (m_serviceType.isEmpty())
+ return;
+
+ if (!document().frame()
+ || !document().frame()->loader().client()->canCreatePluginWithoutRenderer(m_serviceType))
+ return;
+
+ if (renderer() && renderer()->isWidget())
+ return;
+
+ createPluginWithoutRenderer();
+}
+
+void HTMLPlugInElement::createPluginWithoutRenderer()
+{
+ ASSERT(document().frame()->loader().client()->canCreatePluginWithoutRenderer(m_serviceType));
+
+ KURL url;
+ Vector<String> paramNames;
+ Vector<String> paramValues;
+
+ paramNames.append("type");
+ paramValues.append(m_serviceType);
+
+ bool useFallback = false;
+ loadPlugin(url, m_serviceType, paramNames, paramValues, useFallback, false);
+}
+
+bool HTMLPlugInElement::shouldAccelerate() const
+{
+ if (Widget* widget = ownedWidget())
+ return widget->isPluginView() && toPluginView(widget)->platformLayer();
+ return false;
+}
+
void HTMLPlugInElement::detach(const AttachContext& context)
{
// Update the widget the next time we attach (detaching destroys the plugin).
@@ -152,11 +197,17 @@ void HTMLPlugInElement::detach(const AttachContext& context)
document().decrementLoadEventDelayCount();
}
+ // Only try to persist a plugin widget we actually own.
+ Widget* plugin = ownedWidget();
+ if (plugin && plugin->pluginShouldPersist())
+ m_persistedPluginWidget = plugin;
resetInstance();
+ // FIXME - is this next line necessary?
+ setWidget(nullptr);
if (m_isCapturingMouseEvents) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_isCapturingMouseEvents = false;
}
@@ -200,7 +251,7 @@ void HTMLPlugInElement::finishParsingChildren()
setNeedsWidgetUpdate(true);
if (inDocument())
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
void HTMLPlugInElement::resetInstance()
@@ -210,7 +261,7 @@ void HTMLPlugInElement::resetInstance()
SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper()
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return 0;
@@ -218,34 +269,21 @@ SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper()
// return the cached allocated Bindings::Instance. Not supporting this
// edge-case is OK.
if (!m_pluginWrapper) {
- if (Widget* widget = pluginWidget())
- m_pluginWrapper = frame->script().createPluginWrapper(widget);
+ Widget* plugin;
+
+ if (m_persistedPluginWidget)
+ plugin = m_persistedPluginWidget.get();
+ else
+ plugin = pluginWidget();
+
+ if (plugin)
+ m_pluginWrapper = frame->script().createPluginWrapper(plugin);
}
return m_pluginWrapper.get();
}
-bool HTMLPlugInElement::dispatchBeforeLoadEvent(const String& sourceURL)
-{
- // FIXME: Our current plug-in loading design can't guarantee the following
- // assertion is true, since plug-in loading can be initiated during layout,
- // and synchronous layout can be initiated in a beforeload event handler!
- // See <http://webkit.org/b/71264>.
- // ASSERT(!m_inBeforeLoadEventHandler);
- m_inBeforeLoadEventHandler = true;
- bool beforeLoadAllowedLoad = HTMLFrameOwnerElement::dispatchBeforeLoadEvent(sourceURL);
- m_inBeforeLoadEventHandler = false;
- return beforeLoadAllowedLoad;
-}
-
Widget* HTMLPlugInElement::pluginWidget() const
{
- if (m_inBeforeLoadEventHandler) {
- // The plug-in hasn't loaded yet, and it makes no sense to try to load
- // if beforeload handler happened to touch the plug-in element. That
- // would recursively call beforeload for the same element.
- return 0;
- }
-
if (RenderWidget* renderWidget = renderWidgetForJSBindings())
return renderWidget->widget();
return 0;
@@ -356,7 +394,7 @@ bool HTMLPlugInElement::isImageType()
if (m_serviceType.isEmpty() && protocolIs(m_url, "data"))
m_serviceType = mimeTypeFromDataURL(m_url);
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
KURL completedURL = document().completeURL(m_url);
return frame->loader().client()->objectContentType(completedURL, m_serviceType, shouldPreferPlugInsForImages()) == ObjectContentImage;
}
@@ -364,14 +402,6 @@ bool HTMLPlugInElement::isImageType()
return Image::supportsType(m_serviceType);
}
-const String HTMLPlugInElement::loadedMimeType() const
-{
- String mimeType = m_serviceType;
- if (mimeType.isEmpty())
- mimeType = mimeTypeFromURL(m_loadedUrl);
- return mimeType;
-}
-
RenderEmbeddedObject* HTMLPlugInElement::renderEmbeddedObject() const
{
// HTMLObjectElement and HTMLEmbedElement may return arbitrary renderers
@@ -415,10 +445,13 @@ bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
return false;
KURL completedURL = document().completeURL(url);
+ if (!pluginIsLoadable(completedURL, mimeType))
+ return false;
bool useFallback;
- if (shouldUsePlugin(completedURL, mimeType, renderer->hasFallbackContent(), useFallback))
- return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFallback);
+ bool requireRenderer = true;
+ if (shouldUsePlugin(completedURL, mimeType, hasFallbackContent(), useFallback))
+ return loadPlugin(completedURL, mimeType, paramNames, paramValues, useFallback, requireRenderer);
// If the plug-in element already contains a subframe,
// loadOrRedirectSubframe will re-use it. Otherwise, it will create a new
@@ -427,38 +460,43 @@ bool HTMLPlugInElement::requestObject(const String& url, const String& mimeType,
return loadOrRedirectSubframe(completedURL, getNameAttribute(), true);
}
-bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
+bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback, bool requireRenderer)
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame->loader().allowPlugins(AboutToInstantiatePlugin))
return false;
- if (!pluginIsLoadable(url, mimeType))
- return false;
-
RenderEmbeddedObject* renderer = renderEmbeddedObject();
// FIXME: This code should not depend on renderer!
- if (!renderer || useFallback)
+ if ((!renderer && requireRenderer) || useFallback)
return false;
WTF_LOG(Plugins, "%p Plug-in URL: %s", this, m_url.utf8().data());
WTF_LOG(Plugins, " Loaded URL: %s", url.string().utf8().data());
m_loadedUrl = url;
- IntSize contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), renderer->contentHeight()));
- bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
- RefPtr<Widget> widget = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually);
+ RefPtr<Widget> widget = m_persistedPluginWidget;
+ if (!widget) {
+ bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
+ FrameLoaderClient::DetachedPluginPolicy policy = requireRenderer ? FrameLoaderClient::FailOnDetachedPlugin : FrameLoaderClient::AllowDetachedPlugin;
+ widget = frame->loader().client()->createPlugin(this, url, paramNames, paramValues, mimeType, loadManually, policy);
+ }
if (!widget) {
- if (!renderer->showsUnavailablePluginIndicator())
+ if (renderer && !renderer->showsUnavailablePluginIndicator())
renderer->setPluginUnavailabilityReason(RenderEmbeddedObject::PluginMissing);
return false;
}
- renderer->setWidget(widget);
+ if (renderer) {
+ setWidget(widget);
+ m_persistedPluginWidget = nullptr;
+ } else if (widget != m_persistedPluginWidget) {
+ m_persistedPluginWidget = widget;
+ }
document().setContainsPlugins();
- setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
+ scheduleSVGFilterLayerUpdateHack();
return true;
}
@@ -482,9 +520,17 @@ bool HTMLPlugInElement::shouldUsePlugin(const KURL& url, const String& mimeType,
}
+void HTMLPlugInElement::dispatchErrorEvent()
+{
+ if (document().isPluginDocument() && document().ownerElement())
+ document().ownerElement()->dispatchEvent(Event::create(EventTypeNames::error));
+ else
+ dispatchEvent(Event::create(EventTypeNames::error));
+}
+
bool HTMLPlugInElement::pluginIsLoadable(const KURL& url, const String& mimeType)
{
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
Settings* settings = frame->settings();
if (!settings)
return false;
@@ -517,10 +563,14 @@ void HTMLPlugInElement::didAddUserAgentShadowRoot(ShadowRoot&)
userAgentShadowRoot()->appendChild(HTMLContentElement::create(document()));
}
-void HTMLPlugInElement::didAddShadowRoot(ShadowRoot& root)
+void HTMLPlugInElement::willAddFirstAuthorShadowRoot()
+{
+ lazyReattachIfAttached();
+}
+
+bool HTMLPlugInElement::hasFallbackContent() const
{
- if (root.isOldestAuthorShadowRoot())
- lazyReattachIfAttached();
+ return false;
}
bool HTMLPlugInElement::useFallbackContent() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h
index 37d631466b5..9de4531c647 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPlugInElement.h
@@ -25,6 +25,7 @@
#include "bindings/v8/SharedPersistent.h"
#include "core/html/HTMLFrameOwnerElement.h"
+#include <v8.h>
struct NPObject;
@@ -43,6 +44,7 @@ enum PreferPlugInsForImagesOption {
class HTMLPlugInElement : public HTMLFrameOwnerElement {
public:
virtual ~HTMLPlugInElement();
+ virtual void trace(Visitor*) OVERRIDE;
void resetInstance();
SharedPersistent<v8::Object>* pluginWrapper();
@@ -56,17 +58,22 @@ public:
void setNeedsWidgetUpdate(bool needsWidgetUpdate) { m_needsWidgetUpdate = needsWidgetUpdate; }
void updateWidget();
+ bool shouldAccelerate() const;
+
+ void requestPluginCreationWithoutRendererIfPossible();
+ void createPluginWithoutRenderer();
+
protected:
HTMLPlugInElement(const QualifiedName& tagName, Document&, bool createdByParser, PreferPlugInsForImagesOption);
// Node functions:
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
- virtual bool dispatchBeforeLoadEvent(const String& sourceURL) OVERRIDE;
// Element functions:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
+ virtual bool hasFallbackContent() const;
virtual bool useFallbackContent() const;
// Create or update the RenderWidget and return it, triggering layout if
// necessary.
@@ -79,10 +86,12 @@ protected:
bool requestObject(const String& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues);
bool shouldUsePlugin(const KURL&, const String& mimeType, bool hasFallback, bool& useFallback);
+ void dispatchErrorEvent();
+
String m_serviceType;
String m_url;
KURL m_loadedUrl;
- OwnPtr<HTMLImageLoader> m_imageLoader;
+ OwnPtrWillBeMember<HTMLImageLoader> m_imageLoader;
bool m_isDelayingLoadEvent;
private:
@@ -91,24 +100,24 @@ private:
// Node functions:
virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
- virtual bool willRespondToMouseClickEvents() OVERRIDE;
- virtual void defaultEventHandler(Event*) OVERRIDE;
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void finishParsingChildren() OVERRIDE;
- virtual bool isPluginElement() const OVERRIDE;
+ virtual bool willRespondToMouseClickEvents() OVERRIDE FINAL;
+ virtual void defaultEventHandler(Event*) OVERRIDE FINAL;
+ virtual void attach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
+ virtual void detach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
+ virtual void finishParsingChildren() OVERRIDE FINAL;
// Element functions:
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE FINAL;
- virtual bool supportsFocus() const OVERRIDE { return true; };
- virtual bool rendererIsFocusable() const OVERRIDE;
- virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
- virtual void didAddShadowRoot(ShadowRoot&) OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE FINAL { return true; }
+ virtual bool rendererIsFocusable() const OVERRIDE FINAL;
+ virtual bool isKeyboardFocusable() const OVERRIDE FINAL;
+ virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE FINAL;
+ virtual void willAddFirstAuthorShadowRoot() OVERRIDE FINAL;
// HTMLElement function:
virtual bool hasCustomFocusLogic() const OVERRIDE;
+ virtual bool isPluginElement() const OVERRIDE FINAL;
// Return any existing RenderWidget without triggering relayout, or 0 if it
// doesn't yet exist.
@@ -122,21 +131,36 @@ private:
};
DisplayState displayState() const { return m_displayState; }
void setDisplayState(DisplayState state) { m_displayState = state; }
- const String loadedMimeType() const;
- bool loadPlugin(const KURL&, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback);
+ bool loadPlugin(const KURL&, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback, bool requireRenderer);
bool pluginIsLoadable(const KURL&, const String& mimeType);
bool wouldLoadAsNetscapePlugin(const String& url, const String& serviceType);
mutable RefPtr<SharedPersistent<v8::Object> > m_pluginWrapper;
NPObject* m_NPObject;
bool m_isCapturingMouseEvents;
- bool m_inBeforeLoadEventHandler;
bool m_needsWidgetUpdate;
bool m_shouldPreferPlugInsForImages;
DisplayState m_displayState;
+
+ // Normally the Widget is stored in HTMLFrameOwnerElement::m_widget.
+ // However, plugins can persist even when not rendered. In order to
+ // prevent confusing code which may assume that widget() != null
+ // means the frame is active, we save off m_widget here while
+ // the plugin is persisting but not being displayed.
+ RefPtr<Widget> m_persistedPluginWidget;
};
-DEFINE_NODE_TYPE_CASTS(HTMLPlugInElement, isPluginElement());
+inline bool isHTMLPlugInElement(const Element& element)
+{
+ return element.isHTMLElement() && toHTMLElement(element).isPluginElement();
+}
+
+inline bool isHTMLPlugInElement(const HTMLElement& element)
+{
+ return element.isPluginElement();
+}
+
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLPlugInElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
index 830f015f841..f8693761312 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.cpp
@@ -23,10 +23,11 @@
#include "config.h"
#include "core/html/HTMLPreElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/StylePropertySet.h"
+#include "core/frame/UseCounter.h"
namespace WebCore {
@@ -38,10 +39,7 @@ inline HTMLPreElement::HTMLPreElement(const QualifiedName& tagName, Document& do
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLPreElement> HTMLPreElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLPreElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLPreElement)
bool HTMLPreElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -52,10 +50,12 @@ bool HTMLPreElement::isPresentationAttribute(const QualifiedName& name) const
void HTMLPreElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
- if (name == wrapAttr)
+ if (name == wrapAttr) {
+ UseCounter::count(document(), UseCounter::HTMLPreElementWrap);
style->setProperty(CSSPropertyWhiteSpace, CSSValuePreWrap);
- else
+ } else {
HTMLElement::collectStyleForPresentationAttribute(name, value, style);
+ }
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h
index 408475f457d..0ae5a6affb5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLPreElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLPreElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLPreElement);
private:
HTMLPreElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl
index 3d035940d33..6224bc901f2 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLPreElement.idl
@@ -19,11 +19,8 @@
*/
interface HTMLPreElement : HTMLElement {
- // FIXME: DOM spec says that width should be of type DOMString
- // see http://bugs.webkit.org/show_bug.cgi?id=8992
[Reflect] attribute long width;
// Extensions
- [Reflect] attribute boolean wrap;
+ [Reflect, MeasureAs=HTMLPreElementWrap] attribute boolean wrap;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp
index 3baeb6506a6..e8597d0d273 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.cpp
@@ -22,10 +22,10 @@
#include "core/html/HTMLProgressElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -41,7 +41,7 @@ const double HTMLProgressElement::InvalidPosition = -2;
HTMLProgressElement::HTMLProgressElement(Document& document)
: LabelableElement(progressTag, document)
- , m_value(0)
+ , m_value(nullptr)
{
ScriptWrappable::init(this);
}
@@ -50,9 +50,9 @@ HTMLProgressElement::~HTMLProgressElement()
{
}
-PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLProgressElement> HTMLProgressElement::create(Document& document)
{
- RefPtr<HTMLProgressElement> progress = adoptRef(new HTMLProgressElement(document));
+ RefPtrWillBeRawPtr<HTMLProgressElement> progress = adoptRefWillBeNoop(new HTMLProgressElement(document));
progress->ensureUserAgentShadowRoot();
return progress.release();
}
@@ -95,30 +95,30 @@ void HTMLProgressElement::attach(const AttachContext& context)
double HTMLProgressElement::value() const
{
double value = getFloatingPointAttribute(valueAttr);
+ // Otherwise, if the parsed value was greater than or equal to the maximum
+ // value, then the current value of the progress bar is the maximum value
+ // of the progress bar. Otherwise, if parsing the value attribute's value
+ // resulted in an error, or a number less than or equal to zero, then the
+ // current value of the progress bar is zero.
return !std::isfinite(value) || value < 0 ? 0 : std::min(value, max());
}
-void HTMLProgressElement::setValue(double value, ExceptionState& exceptionState)
+void HTMLProgressElement::setValue(double value)
{
- if (!std::isfinite(value)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(value));
- return;
- }
setFloatingPointAttribute(valueAttr, std::max(value, 0.));
}
double HTMLProgressElement::max() const
{
double max = getFloatingPointAttribute(maxAttr);
+ // Otherwise, if the element has no max attribute, or if it has one but
+ // parsing it resulted in an error, or if the parsed value was less than or
+ // equal to zero, then the maximum value of the progress bar is 1.0.
return !std::isfinite(max) || max <= 0 ? 1 : max;
}
-void HTMLProgressElement::setMax(double max, ExceptionState& exceptionState)
+void HTMLProgressElement::setMax(double max)
{
- if (!std::isfinite(max)) {
- exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(max));
- return;
- }
// FIXME: The specification says we should ignore the input value if it is inferior or equal to 0.
setFloatingPointAttribute(maxAttr, max > 0 ? max : 1);
}
@@ -150,15 +150,15 @@ void HTMLProgressElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
ASSERT(!m_value);
- RefPtr<ProgressInnerElement> inner = ProgressInnerElement::create(document());
- inner->setPseudo(AtomicString("-webkit-progress-inner-element", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<ProgressInnerElement> inner = ProgressInnerElement::create(document());
+ inner->setShadowPseudoId(AtomicString("-webkit-progress-inner-element", AtomicString::ConstructFromLiteral));
root.appendChild(inner);
- RefPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
- bar->setPseudo(AtomicString("-webkit-progress-bar", AtomicString::ConstructFromLiteral));
- RefPtr<ProgressValueElement> value = ProgressValueElement::create(document());
+ RefPtrWillBeRawPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
+ bar->setShadowPseudoId(AtomicString("-webkit-progress-bar", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<ProgressValueElement> value = ProgressValueElement::create(document());
m_value = value.get();
- m_value->setPseudo(AtomicString("-webkit-progress-value", AtomicString::ConstructFromLiteral));
+ m_value->setShadowPseudoId(AtomicString("-webkit-progress-value", AtomicString::ConstructFromLiteral));
m_value->setWidthPercentage(HTMLProgressElement::IndeterminatePosition * 100);
bar->appendChild(m_value);
@@ -170,4 +170,10 @@ bool HTMLProgressElement::shouldAppearIndeterminate() const
return !isDeterminate();
}
+void HTMLProgressElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ LabelableElement::trace(visitor);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h
index 6162ded1570..cce0dfbbb64 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.h
@@ -34,17 +34,19 @@ public:
static const double IndeterminatePosition;
static const double InvalidPosition;
- static PassRefPtr<HTMLProgressElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLProgressElement> create(Document&);
double value() const;
- void setValue(double, ExceptionState&);
+ void setValue(double);
double max() const;
- void setMax(double, ExceptionState&);
+ void setMax(double);
double position() const;
- virtual bool canContainRangeEndPoint() const { return false; }
+ virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit HTMLProgressElement(Document&);
@@ -54,7 +56,7 @@ private:
virtual bool shouldAppearIndeterminate() const OVERRIDE;
virtual bool supportLabels() const OVERRIDE { return true; }
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
RenderProgress* renderProgress() const;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
@@ -65,17 +67,9 @@ private:
virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
bool isDeterminate() const;
- ProgressValueElement* m_value;
+ RawPtrWillBeMember<ProgressValueElement> m_value;
};
-inline bool isHTMLProgressElement(Node* node)
-{
- ASSERT(node);
- return node->hasTagName(HTMLNames::progressTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLProgressElement, hasTagName(HTMLNames::progressTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl
index b2f5a9cdbba..a3da90a39e7 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLProgressElement.idl
@@ -17,10 +17,13 @@
* Boston, MA 02110-1301, USA.
*/
-interface HTMLProgressElement : HTMLElement {
- [RaisesException=Setter] attribute double value;
- [RaisesException=Setter] attribute double max;
- readonly attribute double position;
- readonly attribute NodeList labels;
-};
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#htmlprogresselement
+[
+ TypeChecking=Unrestricted,
+] interface HTMLProgressElement : HTMLElement {
+ attribute double value;
+ attribute double max;
+ readonly attribute double position;
+ readonly attribute NodeList labels;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp
index ff18c6006e4..228af64484d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.cpp
@@ -23,7 +23,7 @@
#include "config.h"
#include "core/html/HTMLQuoteElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/StyleEngine.h"
@@ -38,14 +38,21 @@ inline HTMLQuoteElement::HTMLQuoteElement(const QualifiedName& tagName, Document
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLQuoteElement> HTMLQuoteElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLQuoteElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLQuoteElement)
bool HTMLQuoteElement::isURLAttribute(const Attribute& attribute) const
{
return attribute.name() == citeAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLQuoteElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == citeAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLQuoteElement::subResourceAttributeName() const
+{
+ return citeAttr;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h
index bfdc9ee176a..fcf12adcf85 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.h
@@ -31,12 +31,14 @@ namespace WebCore {
class HTMLQuoteElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLQuoteElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLQuoteElement);
private:
HTMLQuoteElement(const QualifiedName&, Document&);
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
};
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl
index 93a2aff07ea..db0ab9dd9ca 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLQuoteElement.idl
@@ -18,5 +18,5 @@
*/
interface HTMLQuoteElement : HTMLElement {
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString cite;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString cite;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.cpp
new file mode 100644
index 00000000000..d1fb7c03f22
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.cpp
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLRTElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/rendering/RenderRubyText.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLRTElement::HTMLRTElement(Document& document)
+ : HTMLElement(rtTag, document)
+{
+}
+
+DEFINE_NODE_FACTORY(HTMLRTElement)
+
+RenderObject* HTMLRTElement::createRenderer(RenderStyle* style)
+{
+ if (style->display() == BLOCK)
+ return new RenderRubyText(this);
+ return RenderObject::createObject(this, style);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.h
new file mode 100644
index 00000000000..eea1e94bf30
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLRTElement.h
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HTMLRTElement_h
+#define HTMLRTElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <rt> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's createRenderer doesn't need to know about it.
+class HTMLRTElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLRTElement);
+
+private:
+ explicit HTMLRTElement(Document&);
+
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.cpp
new file mode 100644
index 00000000000..ab6febd1ecc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.cpp
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLRubyElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/rendering/RenderRuby.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLRubyElement::HTMLRubyElement(Document& document)
+ : HTMLElement(rubyTag, document)
+{
+}
+
+DEFINE_NODE_FACTORY(HTMLRubyElement)
+
+RenderObject* HTMLRubyElement::createRenderer(RenderStyle* style)
+{
+ if (style->display() == INLINE)
+ return new RenderRubyAsInline(this);
+ if (style->display() == BLOCK)
+ return new RenderRubyAsBlock(this);
+ return RenderObject::createObject(this, style);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.h
new file mode 100644
index 00000000000..bf177a6daae
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLRubyElement.h
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HTMLRubyElement_h
+#define HTMLRubyElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <ruby> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's createRenderer doesn't need to know about it.
+class HTMLRubyElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLRubyElement);
+
+private:
+ explicit HTMLRubyElement(Document&);
+
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
index fd54cc283c2..ce1adaf24a7 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.cpp
@@ -23,15 +23,14 @@
#include "config.h"
#include "core/html/HTMLScriptElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/dom/ScriptLoader.h"
#include "core/dom/Text.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
@@ -44,9 +43,9 @@ inline HTMLScriptElement::HTMLScriptElement(Document& document, bool wasInserted
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLScriptElement> HTMLScriptElement::create(Document& document, bool wasInsertedByParser, bool alreadyStarted)
+PassRefPtrWillBeRawPtr<HTMLScriptElement> HTMLScriptElement::create(Document& document, bool wasInsertedByParser, bool alreadyStarted)
{
- return adoptRef(new HTMLScriptElement(document, wasInsertedByParser, alreadyStarted));
+ return adoptRefWillBeNoop(new HTMLScriptElement(document, wasInsertedByParser, alreadyStarted));
}
bool HTMLScriptElement::isURLAttribute(const Attribute& attribute) const
@@ -54,6 +53,16 @@ bool HTMLScriptElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
}
+bool HTMLScriptElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == srcAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLScriptElement::subResourceAttributeName() const
+{
+ return srcAttr;
+}
+
void HTMLScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
@@ -66,8 +75,6 @@ void HTMLScriptElement::parseAttribute(const QualifiedName& name, const AtomicSt
m_loader->handleSourceAttribute(value);
else if (name == asyncAttr)
m_loader->handleAsyncAttribute();
- else if (name == onbeforeloadAttr)
- setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
else
HTMLElement::parseAttribute(name, value);
}
@@ -85,7 +92,7 @@ void HTMLScriptElement::didNotifySubtreeInsertionsToDocument()
void HTMLScriptElement::setText(const String &value)
{
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
if (hasOneTextChild()) {
toText(firstChild())->setData(value);
@@ -112,13 +119,6 @@ KURL HTMLScriptElement::src() const
return document().completeURL(sourceAttributeValue());
}
-void HTMLScriptElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, src());
-}
-
String HTMLScriptElement::sourceAttributeValue() const
{
return getAttribute(srcAttr).string();
@@ -170,9 +170,9 @@ void HTMLScriptElement::dispatchLoadEvent()
dispatchEvent(Event::create(EventTypeNames::load));
}
-PassRefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren()
+PassRefPtrWillBeRawPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren()
{
- return adoptRef(new HTMLScriptElement(document(), false, m_loader->alreadyStarted()));
+ return adoptRefWillBeNoop(new HTMLScriptElement(document(), false, m_loader->alreadyStarted()));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h
index d4e0efd047e..9dbc0c86fa4 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.h
@@ -33,7 +33,7 @@ class ScriptLoader;
class HTMLScriptElement FINAL : public HTMLElement, public ScriptLoaderClient {
public:
- static PassRefPtr<HTMLScriptElement> create(Document&, bool wasInsertedByParser, bool alreadyStarted = false);
+ static PassRefPtrWillBeRawPtr<HTMLScriptElement> create(Document&, bool wasInsertedByParser, bool alreadyStarted = false);
String text() { return textFromChildren(); }
void setText(const String&);
@@ -51,31 +51,29 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual String sourceAttributeValue() const OVERRIDE;
+ virtual String charsetAttributeValue() const OVERRIDE;
+ virtual String typeAttributeValue() const OVERRIDE;
+ virtual String languageAttributeValue() const OVERRIDE;
+ virtual String forAttributeValue() const OVERRIDE;
+ virtual String eventAttributeValue() const OVERRIDE;
+ virtual bool asyncAttributeValue() const OVERRIDE;
+ virtual bool deferAttributeValue() const OVERRIDE;
+ virtual bool hasSourceAttribute() const OVERRIDE;
- virtual String sourceAttributeValue() const;
- virtual String charsetAttributeValue() const;
- virtual String typeAttributeValue() const;
- virtual String languageAttributeValue() const;
- virtual String forAttributeValue() const;
- virtual String eventAttributeValue() const;
- virtual bool asyncAttributeValue() const;
- virtual bool deferAttributeValue() const;
- virtual bool hasSourceAttribute() const;
+ virtual void dispatchLoadEvent() OVERRIDE;
- virtual void dispatchLoadEvent();
-
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
OwnPtr<ScriptLoader> m_loader;
};
-DEFINE_NODE_TYPE_CASTS(HTMLScriptElement, hasTagName(HTMLNames::scriptTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
index 1f1e260a7f9..71b542261e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLScriptElement.idl
@@ -24,8 +24,10 @@ interface HTMLScriptElement : HTMLElement {
[Reflect] attribute DOMString charset;
attribute boolean async;
[Reflect] attribute boolean defer;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
[Reflect] attribute DOMString type;
- [Reflect] attribute DOMString crossOrigin;
+ [Reflect, ReflectOnly="anonymous"|"use-credentials", ReflectEmpty="anonymous", ReflectInvalid="anonymous"] attribute DOMString crossOrigin;
[Reflect, RuntimeEnabled=ExperimentalContentSecurityPolicyFeatures] attribute DOMString nonce;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
index 8d8332a3e86..b0dc747ff14 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.cpp
@@ -28,24 +28,23 @@
#include "config.h"
#include "core/html/HTMLSelectElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Attribute.h"
#include "core/dom/ElementTraversal.h"
#include "core/dom/NodeTraversal.h"
+#include "core/events/GestureEvent.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLFormElement.h"
-#include "core/html/HTMLOptGroupElement.h"
#include "core/html/HTMLOptionElement.h"
#include "core/html/forms/FormController.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/page/SpatialNavigation.h"
#include "core/rendering/RenderListBox.h"
#include "core/rendering/RenderMenuList.h"
@@ -53,7 +52,6 @@
#include "platform/PlatformMouseEvent.h"
#include "platform/text/PlatformLocale.h"
-using namespace std;
using namespace WTF::Unicode;
namespace WebCore {
@@ -63,7 +61,7 @@ using namespace HTMLNames;
// Upper limit agreed upon with representatives of Opera and Mozilla.
static const unsigned maxSelectItems = 10000;
-HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form, bool createdByParser)
+HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form)
: HTMLFormControlElementWithState(selectTag, document, form)
, m_typeAhead(this)
, m_size(0)
@@ -74,19 +72,20 @@ HTMLSelectElement::HTMLSelectElement(Document& document, HTMLFormElement* form,
, m_multiple(false)
, m_activeSelectionState(false)
, m_shouldRecalcListItems(false)
- , m_isParsingInProgress(createdByParser)
+ , m_suggestedIndex(-1)
{
ScriptWrappable::init(this);
+ setHasCustomStyleCallbacks();
}
-PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document)
{
- return adoptRef(new HTMLSelectElement(document, 0, false));
+ return adoptRefWillBeNoop(new HTMLSelectElement(document, 0));
}
-PassRefPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document, HTMLFormElement* form, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLSelectElement> HTMLSelectElement::create(Document& document, HTMLFormElement* form)
{
- return adoptRef(new HTMLSelectElement(document, form, createdByParser));
+ return adoptRefWillBeNoop(new HTMLSelectElement(document, form));
}
const AtomicString& HTMLSelectElement::formControlType() const
@@ -96,12 +95,6 @@ const AtomicString& HTMLSelectElement::formControlType() const
return m_multiple ? selectMultiple : selectOne;
}
-void HTMLSelectElement::deselectItems(HTMLOptionElement* excludeElement)
-{
- deselectItemsWithoutValidation(excludeElement);
- setNeedsValidityCheck();
-}
-
void HTMLSelectElement::optionSelectedByUser(int optionIndex, bool fireOnChangeNow, bool allowMultipleSelection)
{
// User interaction such as mousedown events can cause list box select elements to send change events.
@@ -121,7 +114,7 @@ void HTMLSelectElement::optionSelectedByUser(int optionIndex, bool fireOnChangeN
if (optionIndex == selectedIndex())
return;
- selectOption(optionIndex, DeselectOtherOptions | (fireOnChangeNow ? DispatchChangeEvent : 0) | UserDriven);
+ selectOption(optionIndex, DeselectOtherOptions | (fireOnChangeNow ? DispatchInputAndChangeEvent : 0) | UserDriven);
}
bool HTMLSelectElement::hasPlaceholderLabelOption() const
@@ -209,15 +202,21 @@ int HTMLSelectElement::activeSelectionEndListIndex() const
void HTMLSelectElement::add(HTMLElement* element, HTMLElement* before, ExceptionState& exceptionState)
{
// Make sure the element is ref'd and deref'd so we don't leak it.
- RefPtr<HTMLElement> protectNewChild(element);
+ RefPtrWillBeRawPtr<HTMLElement> protectNewChild(element);
- if (!element || !(element->hasLocalName(optionTag) || element->hasLocalName(hrTag)))
+ if (!element || !(isHTMLOptionElement(element) || isHTMLOptGroupElement(element) || isHTMLHRElement(element)))
return;
insertBefore(element, before, exceptionState);
setNeedsValidityCheck();
}
+void HTMLSelectElement::addBeforeOptionAtIndex(HTMLElement* element, int beforeIndex, ExceptionState& exceptionState)
+{
+ HTMLElement* beforeElement = toHTMLElement(options()->item(beforeIndex));
+ add(element, beforeElement, exceptionState);
+}
+
void HTMLSelectElement::remove(int optionIndex)
{
int listIndex = optionToListIndex(optionIndex);
@@ -227,46 +226,80 @@ void HTMLSelectElement::remove(int optionIndex)
listItems()[listIndex]->remove(IGNORE_EXCEPTION);
}
-void HTMLSelectElement::remove(HTMLOptionElement* option)
-{
- if (option->ownerSelectElement() != this)
- return;
-
- option->remove(IGNORE_EXCEPTION);
-}
-
String HTMLSelectElement::value() const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag) && toHTMLOptionElement(items[i])->selected())
+ if (isHTMLOptionElement(items[i]) && toHTMLOptionElement(items[i])->selected())
return toHTMLOptionElement(items[i])->value();
}
return "";
}
-void HTMLSelectElement::setValue(const String &value)
+void HTMLSelectElement::setValue(const String &value, bool sendEvents)
{
// We clear the previously selected option(s) when needed, to guarantee calling setSelectedIndex() only once.
+ int optionIndex = 0;
+ if (value.isNull()) {
+ optionIndex = -1;
+ } else {
+ // Find the option with value() matching the given parameter and make it the current selection.
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
+ for (unsigned i = 0; i < items.size(); i++) {
+ if (isHTMLOptionElement(items[i])) {
+ if (toHTMLOptionElement(items[i])->value() == value)
+ break;
+ optionIndex++;
+ }
+ }
+ if (optionIndex >= static_cast<int>(items.size()))
+ optionIndex = -1;
+ }
+
+ int previousSelectedIndex = selectedIndex();
+ setSuggestedIndex(-1);
+ setSelectedIndex(optionIndex);
+
+ if (sendEvents && previousSelectedIndex != selectedIndex()) {
+ if (usesMenuList())
+ dispatchInputAndChangeEventForMenuList(false);
+ else
+ listBoxOnChange();
+ }
+}
+
+String HTMLSelectElement::suggestedValue() const
+{
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
+ for (unsigned i = 0; i < items.size(); ++i) {
+ if (isHTMLOptionElement(items[i]) && m_suggestedIndex >= 0) {
+ if (i == static_cast<unsigned>(m_suggestedIndex))
+ return toHTMLOptionElement(items[i])->value();
+ }
+ }
+ return "";
+}
+
+void HTMLSelectElement::setSuggestedValue(const String& value)
+{
if (value.isNull()) {
- setSelectedIndex(-1);
+ setSuggestedIndex(-1);
return;
}
- // Find the option with value() matching the given parameter and make it the current selection.
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
unsigned optionIndex = 0;
- for (unsigned i = 0; i < items.size(); i++) {
- if (items[i]->hasLocalName(optionTag)) {
+ for (unsigned i = 0; i < items.size(); ++i) {
+ if (isHTMLOptionElement(items[i])) {
if (toHTMLOptionElement(items[i])->value() == value) {
- setSelectedIndex(optionIndex);
+ setSuggestedIndex(optionIndex);
return;
}
optionIndex++;
}
}
- setSelectedIndex(-1);
+ setSuggestedIndex(-1);
}
bool HTMLSelectElement::isPresentationAttribute(const QualifiedName& name) const
@@ -290,10 +323,10 @@ void HTMLSelectElement::parseAttribute(const QualifiedName& name, const AtomicSt
AtomicString attrSize = AtomicString::number(size);
if (attrSize != value) {
// FIXME: This is horribly factored.
- if (Attribute* sizeAttribute = ensureUniqueElementData()->getAttributeItem(sizeAttr))
+ if (Attribute* sizeAttribute = ensureUniqueElementData().findAttributeByName(sizeAttr))
sizeAttribute->setValue(attrSize);
}
- size = max(size, 1);
+ size = std::max(size, 1);
// Ensure that we've determined selectedness of the items at least once prior to changing the size.
if (oldSize != size)
@@ -310,6 +343,15 @@ void HTMLSelectElement::parseAttribute(const QualifiedName& name, const AtomicSt
else if (name == accesskeyAttr) {
// FIXME: ignore for the moment.
//
+ } else if (name == disabledAttr) {
+ HTMLFormControlElementWithState::parseAttribute(name, value);
+ if (renderer() && renderer()->isMenuList()) {
+ if (RenderMenuList* menuList = toRenderMenuList(renderer())) {
+ if (menuList->popupIsVisible())
+ menuList->hidePopup();
+ }
+ }
+
} else
HTMLFormControlElementWithState::parseAttribute(name, value);
}
@@ -331,24 +373,15 @@ RenderObject* HTMLSelectElement::createRenderer(RenderStyle*)
return new RenderListBox(this);
}
-bool HTMLSelectElement::childShouldCreateRenderer(const Node& child) const
-{
- if (!HTMLFormControlElementWithState::childShouldCreateRenderer(child))
- return false;
- if (!usesMenuList())
- return child.hasTagName(HTMLNames::optionTag) || isHTMLOptGroupElement(&child);
- return false;
-}
-
-PassRefPtr<HTMLCollection> HTMLSelectElement::selectedOptions()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLSelectElement::selectedOptions()
{
updateListItemSelectedStates();
return ensureCachedHTMLCollection(SelectedOptions);
}
-PassRefPtr<HTMLOptionsCollection> HTMLSelectElement::options()
+PassRefPtrWillBeRawPtr<HTMLOptionsCollection> HTMLSelectElement::options()
{
- return static_cast<HTMLOptionsCollection*>(ensureCachedHTMLCollection(SelectOptions).get());
+ return toHTMLOptionsCollection(ensureCachedHTMLCollection(SelectOptions).get());
}
void HTMLSelectElement::updateListItemSelectedStates()
@@ -402,12 +435,12 @@ void HTMLSelectElement::setSize(int size)
setIntegralAttribute(sizeAttr, size);
}
-Node* HTMLSelectElement::namedItem(const AtomicString& name)
+Element* HTMLSelectElement::namedItem(const AtomicString& name)
{
return options()->namedItem(name);
}
-Node* HTMLSelectElement::item(unsigned index)
+Element* HTMLSelectElement::item(unsigned index)
{
return options()->item(index);
}
@@ -417,7 +450,7 @@ void HTMLSelectElement::setOption(unsigned index, HTMLOptionElement* option, Exc
if (index > maxSelectItems - 1)
index = maxSelectItems - 1;
int diff = index - length();
- RefPtr<HTMLElement> before = 0;
+ RefPtrWillBeRawPtr<HTMLElement> before = nullptr;
// Out of array bounds? First insert empty dummies.
if (diff > 0) {
setLength(index, exceptionState);
@@ -442,22 +475,22 @@ void HTMLSelectElement::setLength(unsigned newLen, ExceptionState& exceptionStat
if (diff < 0) { // Add dummy elements.
do {
- RefPtr<Element> option = document().createElement(optionTag, false);
+ RefPtrWillBeRawPtr<Element> option = document().createElement(optionTag, false);
ASSERT(option);
add(toHTMLElement(option), 0, exceptionState);
if (exceptionState.hadException())
break;
} while (++diff);
} else {
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
// Removing children fires mutation events, which might mutate the DOM further, so we first copy out a list
// of elements that we intend to remove then attempt to remove them one at a time.
- Vector<RefPtr<Element> > itemsToRemove;
+ WillBeHeapVector<RefPtrWillBeMember<Element> > itemsToRemove;
size_t optionIndex = 0;
for (size_t i = 0; i < items.size(); ++i) {
Element* item = items[i];
- if (item->hasLocalName(optionTag) && optionIndex++ >= newLen) {
+ if (isHTMLOptionElement(items[i]) && optionIndex++ >= newLen) {
ASSERT(item->parentNode());
itemsToRemove.append(item);
}
@@ -484,16 +517,17 @@ bool HTMLSelectElement::isRequiredFormControl() const
int HTMLSelectElement::nextValidIndex(int listIndex, SkipDirection direction, int skip) const
{
ASSERT(direction == -1 || direction == 1);
- const Vector<HTMLElement*>& listItems = this->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this->listItems();
int lastGoodIndex = listIndex;
int size = listItems.size();
for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex += direction) {
--skip;
- if (!listItems[listIndex]->isDisabledFormControl() && listItems[listIndex]->hasTagName(optionTag)) {
- lastGoodIndex = listIndex;
- if (skip <= 0)
- break;
- }
+ HTMLElement* element = listItems[listIndex];
+ if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl() || toHTMLOptionElement(element)->isDisplayNone())
+ continue;
+ lastGoodIndex = listIndex;
+ if (skip <= 0)
+ break;
}
return lastGoodIndex;
}
@@ -512,7 +546,7 @@ int HTMLSelectElement::previousSelectableListIndex(int startIndex) const
int HTMLSelectElement::firstSelectableListIndex() const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
int index = nextValidIndex(items.size(), SkipBackwards, INT_MAX);
if (static_cast<size_t>(index) == items.size())
return -1;
@@ -527,7 +561,7 @@ int HTMLSelectElement::lastSelectableListIndex() const
// Returns the index of the next valid item one page away from |startIndex| in direction |direction|.
int HTMLSelectElement::nextSelectableListIndexPageAway(int startIndex, SkipDirection direction) const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
// Can't use m_size because renderer forces a minimum size.
int pageSize = 0;
if (renderer()->isListBox())
@@ -568,10 +602,10 @@ void HTMLSelectElement::saveLastSelection()
}
m_lastOnChangeSelection.clear();
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- m_lastOnChangeSelection.append(element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected());
+ m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected());
}
}
@@ -583,10 +617,10 @@ void HTMLSelectElement::setActiveSelectionAnchorIndex(int index)
// selection pivots around this anchor index.
m_cachedStateForActiveSelection.clear();
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- m_cachedStateForActiveSelection.append(element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected());
+ m_cachedStateForActiveSelection.append(isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected());
}
}
@@ -600,13 +634,13 @@ void HTMLSelectElement::updateListBoxSelection(bool deselectOtherOptions)
ASSERT(renderer() && (renderer()->isListBox() || m_multiple));
ASSERT(!listItems().size() || m_activeSelectionAnchorIndex >= 0);
- unsigned start = min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
- unsigned end = max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
+ unsigned start = std::min(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
+ unsigned end = std::max(m_activeSelectionAnchorIndex, m_activeSelectionEndIndex);
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isDisabledFormControl())
+ if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl() || toHTMLOptionElement(element)->isDisplayNone())
continue;
if (i >= start && i <= end)
@@ -626,7 +660,7 @@ void HTMLSelectElement::listBoxOnChange()
{
ASSERT(!usesMenuList() || m_multiple);
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
// If the cached selection list is empty, or the size has changed, then fire
// dispatchFormControlChangeEvent, and return early.
@@ -640,24 +674,29 @@ void HTMLSelectElement::listBoxOnChange()
bool fireOnChange = false;
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- bool selected = element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected();
+ bool selected = isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected();
if (selected != m_lastOnChangeSelection[i])
fireOnChange = true;
m_lastOnChangeSelection[i] = selected;
}
- if (fireOnChange)
+ if (fireOnChange) {
+ RefPtrWillBeRawPtr<HTMLSelectElement> protector(this);
+ dispatchInputEvent();
dispatchFormControlChangeEvent();
+ }
}
-void HTMLSelectElement::dispatchChangeEventForMenuList()
+void HTMLSelectElement::dispatchInputAndChangeEventForMenuList(bool requiresUserGesture)
{
ASSERT(usesMenuList());
int selected = selectedIndex();
- if (m_lastOnChangeIndex != selected && m_isProcessingUserDrivenChange) {
+ if (m_lastOnChangeIndex != selected && (!requiresUserGesture || m_isProcessingUserDrivenChange)) {
m_lastOnChangeIndex = selected;
m_isProcessingUserDrivenChange = false;
+ RefPtrWillBeRawPtr<HTMLSelectElement> protector(this);
+ dispatchInputEvent();
dispatchFormControlChangeEvent();
}
}
@@ -681,13 +720,13 @@ void HTMLSelectElement::setOptionsChangedOnRenderer()
}
}
-const Vector<HTMLElement*>& HTMLSelectElement::listItems() const
+const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& HTMLSelectElement::listItems() const
{
if (m_shouldRecalcListItems)
recalcListItems();
else {
-#if !ASSERT_DISABLED
- Vector<HTMLElement*> items = m_listItems;
+#if ASSERT_ENABLED
+ WillBeHeapVector<RawPtrWillBeMember<HTMLElement> > items = m_listItems;
recalcListItems(false);
ASSERT(items == m_listItems);
#endif
@@ -711,7 +750,7 @@ void HTMLSelectElement::setRecalcListItems()
// Manual selection anchor is reset when manipulating the select programmatically.
m_activeSelectionAnchorIndex = -1;
setOptionsChangedOnRenderer();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
if (!inDocument()) {
if (HTMLCollection* collection = cachedHTMLCollection(SelectOptions))
collection->invalidateCache();
@@ -751,7 +790,7 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
}
}
- if (current.hasTagName(optionTag)) {
+ if (isHTMLOptionElement(current)) {
m_listItems.append(&current);
if (updateSelectedStates && !m_multiple) {
@@ -769,7 +808,7 @@ void HTMLSelectElement::recalcListItems(bool updateSelectedStates) const
}
}
- if (current.hasTagName(hrTag))
+ if (isHTMLHRElement(current))
m_listItems.append(&current);
// In conforming HTML code, only <optgroup> and <option> will be found
@@ -790,11 +829,11 @@ int HTMLSelectElement::selectedIndex() const
unsigned index = 0;
// Return the number of the first option selected.
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (size_t i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (element->hasTagName(optionTag)) {
- if (toHTMLOptionElement(element)->selected())
+ if (isHTMLOptionElement(*element)) {
+ if (toHTMLOptionElement(*element).selected())
return index;
++index;
}
@@ -808,6 +847,22 @@ void HTMLSelectElement::setSelectedIndex(int index)
selectOption(index, DeselectOtherOptions);
}
+int HTMLSelectElement::suggestedIndex() const
+{
+ return m_suggestedIndex;
+}
+
+void HTMLSelectElement::setSuggestedIndex(int suggestedIndex)
+{
+ m_suggestedIndex = suggestedIndex;
+
+ if (RenderObject* renderer = this->renderer()) {
+ renderer->updateFromElement();
+ if (renderer->isListBox())
+ toRenderListBox(renderer)->scrollToRevealElementAtListIndex(suggestedIndex);
+ }
+}
+
void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, bool optionIsSelected)
{
ASSERT(option->ownerSelectElement() == this);
@@ -823,18 +878,18 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
{
bool shouldDeselect = !m_multiple || (flags & DeselectOtherOptions);
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
int listIndex = optionToListIndex(optionIndex);
HTMLElement* element = 0;
if (listIndex >= 0) {
element = items[listIndex];
- if (element->hasTagName(optionTag)) {
+ if (isHTMLOptionElement(*element)) {
if (m_activeSelectionAnchorIndex < 0 || shouldDeselect)
setActiveSelectionAnchorIndex(listIndex);
if (m_activeSelectionEndIndex < 0 || shouldDeselect)
setActiveSelectionEndIndex(listIndex);
- toHTMLOptionElement(element)->setSelectedState(true);
+ toHTMLOptionElement(*element).setSelectedState(true);
}
}
@@ -847,10 +902,12 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
scrollToSelection();
+ setNeedsValidityCheck();
+
if (usesMenuList()) {
m_isProcessingUserDrivenChange = flags & UserDriven;
- if (flags & DispatchChangeEvent)
- dispatchChangeEventForMenuList();
+ if (flags & DispatchInputAndChangeEvent)
+ dispatchInputAndChangeEventForMenuList();
if (RenderObject* renderer = this->renderer()) {
if (usesMenuList())
toRenderMenuList(renderer)->didSetSelectedIndex(listIndex);
@@ -859,20 +916,19 @@ void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
}
}
- setNeedsValidityCheck();
notifyFormStateChanged();
}
int HTMLSelectElement::optionToListIndex(int optionIndex) const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
int listSize = static_cast<int>(items.size());
if (optionIndex < 0 || optionIndex >= listSize)
return -1;
int optionIndex2 = -1;
for (int listIndex = 0; listIndex < listSize; ++listIndex) {
- if (items[listIndex]->hasTagName(optionTag)) {
+ if (isHTMLOptionElement(*items[listIndex])) {
++optionIndex2;
if (optionIndex2 == optionIndex)
return listIndex;
@@ -884,27 +940,27 @@ int HTMLSelectElement::optionToListIndex(int optionIndex) const
int HTMLSelectElement::listToOptionIndex(int listIndex) const
{
- const Vector<HTMLElement*>& items = listItems();
- if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !items[listIndex]->hasTagName(optionTag))
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
+ if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLOptionElement(*items[listIndex]))
return -1;
// Actual index of option not counting OPTGROUP entries that may be in list.
int optionIndex = 0;
for (int i = 0; i < listIndex; ++i) {
- if (items[i]->hasTagName(optionTag))
+ if (isHTMLOptionElement(*items[i]))
++optionIndex;
}
return optionIndex;
}
-void HTMLSelectElement::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void HTMLSelectElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType type)
{
// Save the selection so it can be compared to the new selection when
// dispatching change events during blur event dispatch.
if (usesMenuList())
saveLastSelection();
- HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction);
+ HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, type);
}
void HTMLSelectElement::dispatchBlurEvent(Element* newFocusedElement)
@@ -913,27 +969,27 @@ void HTMLSelectElement::dispatchBlurEvent(Element* newFocusedElement)
// change events for list boxes whenever the selection change is actually made.
// This matches other browsers' behavior.
if (usesMenuList())
- dispatchChangeEventForMenuList();
+ dispatchInputAndChangeEventForMenuList();
HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
}
void HTMLSelectElement::deselectItemsWithoutValidation(HTMLElement* excludeElement)
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (element != excludeElement && element->hasTagName(optionTag))
+ if (element != excludeElement && isHTMLOptionElement(*element))
toHTMLOptionElement(element)->setSelectedState(false);
}
}
FormControlState HTMLSelectElement::saveFormControlState() const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
size_t length = items.size();
FormControlState state;
for (unsigned i = 0; i < length; ++i) {
- if (!items[i]->hasTagName(optionTag))
+ if (!isHTMLOptionElement(*items[i]))
continue;
HTMLOptionElement* option = toHTMLOptionElement(items[i]);
if (!option->selected())
@@ -947,10 +1003,10 @@ FormControlState HTMLSelectElement::saveFormControlState() const
size_t HTMLSelectElement::searchOptionsForValue(const String& value, size_t listIndexStart, size_t listIndexEnd) const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
size_t loopEndIndex = std::min(items.size(), listIndexEnd);
for (size_t i = listIndexStart; i < loopEndIndex; ++i) {
- if (!items[i]->hasLocalName(optionTag))
+ if (!isHTMLOptionElement(items[i]))
continue;
if (toHTMLOptionElement(items[i])->value() == value)
return i;
@@ -962,13 +1018,13 @@ void HTMLSelectElement::restoreFormControlState(const FormControlState& state)
{
recalcListItems();
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
size_t itemsSize = items.size();
if (!itemsSize)
return;
for (size_t i = 0; i < itemsSize; ++i) {
- if (!items[i]->hasLocalName(optionTag))
+ if (!isHTMLOptionElement(items[i]))
continue;
toHTMLOptionElement(items[i])->setSelectedState(false);
}
@@ -1011,12 +1067,12 @@ bool HTMLSelectElement::appendFormData(FormDataList& list, bool)
return false;
bool successful = false;
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected() && !toHTMLOptionElement(element)->isDisabledFormControl()) {
- list.appendData(name, toHTMLOptionElement(element)->value());
+ if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selected() && !toHTMLOptionElement(*element).isDisabledFormControl()) {
+ list.appendData(name, toHTMLOptionElement(*element).value());
successful = true;
}
}
@@ -1032,10 +1088,10 @@ void HTMLSelectElement::resetImpl()
HTMLOptionElement* firstOption = 0;
HTMLOptionElement* selectedOption = 0;
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
HTMLElement* element = items[i];
- if (!element->hasTagName(optionTag))
+ if (!isHTMLOptionElement(*element))
continue;
if (items[i]->fastHasAttribute(selectedAttr)) {
@@ -1054,7 +1110,7 @@ void HTMLSelectElement::resetImpl()
firstOption->setSelectedState(true);
setOptionsChangedOnRenderer();
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
setNeedsValidityCheck();
}
@@ -1070,7 +1126,7 @@ bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event)
// Calling focus() may cause us to lose our renderer. Return true so
// that our caller doesn't process the event further, but don't set
// the event as handled.
- if (!renderer())
+ if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl())
return true;
// Save the selection so it can be compared to the new selection
@@ -1110,7 +1166,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
const String& keyIdentifier = toKeyboardEvent(event)->keyIdentifier();
bool handled = true;
- const Vector<HTMLElement*>& listItems = this->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this->listItems();
int listIndex = optionToListIndex(selectedIndex());
if (keyIdentifier == "Down" || keyIdentifier == "Right")
@@ -1129,7 +1185,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
handled = false;
if (handled && static_cast<size_t>(listIndex) < listItems.size())
- selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchChangeEvent | UserDriven);
+ selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchInputAndChangeEvent | UserDriven);
if (handled)
event->setDefaultHandled();
@@ -1157,7 +1213,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
// Calling focus() may remove the renderer or change the
// renderer type.
- if (!renderer() || !renderer()->isMenuList())
+ if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl())
return;
// Save the selection so it can be compared to the new selection
@@ -1175,7 +1231,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
// Calling focus() may remove the renderer or change the
// renderer type.
- if (!renderer() || !renderer()->isMenuList())
+ if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl())
return;
// Save the selection so it can be compared to the new selection
@@ -1189,7 +1245,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
} else if (keyCode == '\r') {
if (form())
form()->submitImplicitly(event, false);
- dispatchChangeEventForMenuList();
+ dispatchInputAndChangeEventForMenuList();
handled = true;
}
}
@@ -1200,7 +1256,7 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
focus();
- if (renderer() && renderer()->isMenuList()) {
+ if (renderer() && renderer()->isMenuList() && !isDisabledFormControl()) {
if (RenderMenuList* menuList = toRenderMenuList(renderer())) {
if (menuList->popupIsVisible())
menuList->hidePopup();
@@ -1230,6 +1286,11 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
{
ASSERT(listIndex >= 0);
+ HTMLElement* clickedElement = listItems()[listIndex];
+ ASSERT(clickedElement);
+ if (isHTMLOptGroupElement(clickedElement))
+ return;
+
// Save the selection so it can be compared to the new selection when
// dispatching change events during mouseup, or after autoscroll finishes.
saveLastSelection();
@@ -1239,14 +1300,13 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
bool shiftSelect = m_multiple && shift;
bool multiSelect = m_multiple && multi && !shift;
- HTMLElement* clickedElement = listItems()[listIndex];
- if (clickedElement->hasTagName(optionTag)) {
+ if (isHTMLOptionElement(*clickedElement)) {
// Keep track of whether an active selection (like during drag
// selection), should select or deselect.
- if (toHTMLOptionElement(clickedElement)->selected() && multiSelect)
+ if (toHTMLOptionElement(*clickedElement).selected() && multiSelect)
m_activeSelectionState = false;
if (!m_activeSelectionState)
- toHTMLOptionElement(clickedElement)->setSelectedState(false);
+ toHTMLOptionElement(*clickedElement).setSelectedState(false);
}
// If we're not in any special multiple selection mode, then deselect all
@@ -1261,8 +1321,8 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
setActiveSelectionAnchorIndex(selectedIndex());
// Set the selection state of the clicked option.
- if (clickedElement->hasTagName(optionTag) && !toHTMLOptionElement(clickedElement)->isDisabledFormControl())
- toHTMLOptionElement(clickedElement)->setSelectedState(true);
+ if (isHTMLOptionElement(*clickedElement) && !toHTMLOptionElement(*clickedElement).isDisabledFormControl())
+ toHTMLOptionElement(*clickedElement).setSelectedState(true);
// If there was no selectedIndex() for the previous initialization, or If
// we're doing a single selection, or a multiple selection (using cmd or
@@ -1277,12 +1337,26 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
{
- const Vector<HTMLElement*>& listItems = this->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = this->listItems();
+ if (event->type() == EventTypeNames::gesturetap && event->isGestureEvent()) {
+ focus();
+ // Calling focus() may cause us to lose our renderer or change the render type, in which case do not want to handle the event.
+ if (!renderer() || !renderer()->isListBox())
+ return;
- if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
+ // Convert to coords relative to the list box if needed.
+ GestureEvent& gestureEvent = toGestureEvent(*event);
+ IntPoint localOffset = roundedIntPoint(renderer()->absoluteToLocal(gestureEvent.absoluteLocation(), UseTransforms));
+ int listIndex = toRenderListBox(renderer())->listIndexAtOffset(toIntSize(localOffset));
+ if (listIndex >= 0) {
+ if (!isDisabledFormControl())
+ updateSelectedState(listIndex, true, gestureEvent.shiftKey());
+ event->setDefaultHandled();
+ }
+ } else if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
focus();
// Calling focus() may cause us to lose our renderer, in which case do not want to handle the event.
- if (!renderer())
+ if (!renderer() || !renderer()->isListBox() || isDisabledFormControl())
return;
// Convert to coords relative to the list box if needed.
@@ -1297,7 +1371,7 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent->shiftKey());
#endif
}
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->eventHandler().setMouseDownMayStartAutoscroll();
event->setDefaultHandled();
@@ -1324,15 +1398,11 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
updateListBoxSelection(true);
}
}
- event->setDefaultHandled();
}
} else if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton && renderer() && !toRenderBox(renderer())->autoscrollInProgress()) {
// We didn't start this click/drag on any options.
if (m_lastOnChangeSelection.isEmpty())
return;
- // This makes sure we fire dispatchFormControlChangeEvent for a single
- // click. For drag selection, onChange will fire when the autoscroll
- // timer stops.
listBoxOnChange();
} else if (event->type() == EventTypeNames::keydown) {
if (!event->isKeyboardEvent())
@@ -1466,10 +1536,10 @@ void HTMLSelectElement::defaultEventHandler(Event* event)
int HTMLSelectElement::lastSelectedListIndex() const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (size_t i = items.size(); i;) {
HTMLElement* element = items[--i];
- if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected())
+ if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected())
return i;
}
return -1;
@@ -1487,10 +1557,10 @@ int HTMLSelectElement::optionCount() const
String HTMLSelectElement::optionAtIndex(int index) const
{
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
HTMLElement* element = items[index];
- if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isDisabledFormControl())
+ if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl())
return String();
return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
}
@@ -1500,7 +1570,7 @@ void HTMLSelectElement::typeAheadFind(KeyboardEvent* event)
int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar);
if (index < 0)
return;
- selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchChangeEvent | UserDriven);
+ selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchInputAndChangeEvent | UserDriven);
if (!usesMenuList())
listBoxOnChange();
}
@@ -1522,20 +1592,20 @@ void HTMLSelectElement::accessKeySetSelectedIndex(int index)
accessKeyAction(false);
// If this index is already selected, unselect. otherwise update the selected index.
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
int listIndex = optionToListIndex(index);
if (listIndex >= 0) {
HTMLElement* element = items[listIndex];
- if (element->hasTagName(optionTag)) {
- if (toHTMLOptionElement(element)->selected())
- toHTMLOptionElement(element)->setSelectedState(false);
+ if (isHTMLOptionElement(*element)) {
+ if (toHTMLOptionElement(*element).selected())
+ toHTMLOptionElement(*element).setSelectedState(false);
else
- selectOption(index, DispatchChangeEvent | UserDriven);
+ selectOption(index, DispatchInputAndChangeEvent | UserDriven);
}
}
if (usesMenuList())
- dispatchChangeEventForMenuList();
+ dispatchInputAndChangeEventForMenuList();
else
listBoxOnChange();
@@ -1546,9 +1616,9 @@ unsigned HTMLSelectElement::length() const
{
unsigned options = 0;
- const Vector<HTMLElement*>& items = listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& items = listItems();
for (unsigned i = 0; i < items.size(); ++i) {
- if (items[i]->hasTagName(optionTag))
+ if (isHTMLOptionElement(*items[i]))
++options;
}
@@ -1558,29 +1628,40 @@ unsigned HTMLSelectElement::length() const
void HTMLSelectElement::finishParsingChildren()
{
HTMLFormControlElementWithState::finishParsingChildren();
- m_isParsingInProgress = false;
updateListItemSelectedStates();
}
-bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
+bool HTMLSelectElement::anonymousIndexedSetter(unsigned index, PassRefPtrWillBeRawPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
{
- if (!value) {
- exceptionState.throwTypeError(ExceptionMessages::failedToSet(String::number(index), "HTMLSelectElement", "The value provided was not an HTMLOptionElement."));
- return false;
+ if (!value) { // undefined or null
+ remove(index);
+ return true;
}
setOption(index, value.get(), exceptionState);
return true;
}
-bool HTMLSelectElement::anonymousIndexedSetterRemove(unsigned index, ExceptionState& exceptionState)
+bool HTMLSelectElement::isInteractiveContent() const
{
- remove(index);
return true;
}
-bool HTMLSelectElement::isInteractiveContent() const
+bool HTMLSelectElement::supportsAutofocus() const
{
return true;
}
+void HTMLSelectElement::updateListOnRenderer()
+{
+ setOptionsChangedOnRenderer();
+}
+
+void HTMLSelectElement::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_listItems);
+#endif
+ HTMLFormControlElementWithState::trace(visitor);
+}
+
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h
index 7564360b5cc..05bf5124376 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.h
@@ -39,11 +39,13 @@ class HTMLOptionElement;
class HTMLSelectElement FINAL : public HTMLFormControlElementWithState, public TypeAheadDataSource {
public:
- static PassRefPtr<HTMLSelectElement> create(Document&);
- static PassRefPtr<HTMLSelectElement> create(Document&, HTMLFormElement*, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLSelectElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLSelectElement> create(Document&, HTMLFormElement*);
int selectedIndex() const;
void setSelectedIndex(int);
+ int suggestedIndex() const;
+ void setSuggestedIndex(int);
void optionSelectedByUser(int index, bool dispatchChangeEvent, bool allowMultipleSelection = false);
@@ -61,16 +63,18 @@ public:
bool usesMenuList() const;
void add(HTMLElement*, HTMLElement* beforeElement, ExceptionState&);
+ void addBeforeOptionAtIndex(HTMLElement*, int beforeIndex, ExceptionState&);
using Node::remove;
void remove(int index);
- void remove(HTMLOptionElement*);
String value() const;
- void setValue(const String&);
+ void setValue(const String&, bool sendEvents = false);
+ String suggestedValue() const;
+ void setSuggestedValue(const String&);
- PassRefPtr<HTMLOptionsCollection> options();
- PassRefPtr<HTMLCollection> selectedOptions();
+ PassRefPtrWillBeRawPtr<HTMLOptionsCollection> options();
+ PassRefPtrWillBeRawPtr<HTMLCollection> selectedOptions();
void optionElementChildrenChanged();
@@ -78,9 +82,9 @@ public:
void invalidateSelectedItems();
void updateListItemSelectedStates();
- const Vector<HTMLElement*>& listItems() const;
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems() const;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
void accessKeySetSelectedIndex(int);
void setMultiple(bool);
@@ -90,8 +94,8 @@ public:
void setOption(unsigned index, HTMLOptionElement*, ExceptionState&);
void setLength(unsigned, ExceptionState&);
- Node* namedItem(const AtomicString& name);
- Node* item(unsigned index);
+ Element* namedItem(const AtomicString& name);
+ Element* item(unsigned index);
void scrollToSelection();
@@ -110,25 +114,28 @@ public:
// For use in the implementation of HTMLOptionElement.
void optionSelectionStateChanged(HTMLOptionElement*, bool optionIsSelected);
- bool isParsingInProgress() const { return m_isParsingInProgress; }
- bool anonymousIndexedSetter(unsigned, PassRefPtr<HTMLOptionElement>, ExceptionState&);
- bool anonymousIndexedSetterRemove(unsigned, ExceptionState&);
+ bool anonymousIndexedSetter(unsigned, PassRefPtrWillBeRawPtr<HTMLOptionElement>, ExceptionState&);
+
+ void updateListOnRenderer();
+
+ virtual void trace(Visitor*) OVERRIDE;
protected:
- HTMLSelectElement(Document&, HTMLFormElement*, bool createdByParser);
+ HTMLSelectElement(Document&, HTMLFormElement*);
private:
- virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const OVERRIDE;
virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE;
virtual void dispatchBlurEvent(Element* newFocusedElemnet) OVERRIDE;
- virtual bool canStartSelection() const { return false; }
+ virtual bool canStartSelection() const OVERRIDE { return false; }
- virtual bool isEnumeratable() const { return true; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
+ virtual bool supportsAutofocus() const OVERRIDE;
virtual bool supportLabels() const OVERRIDE { return true; }
virtual FormControlState saveFormControlState() const OVERRIDE;
@@ -137,30 +144,28 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle *);
- virtual bool appendFormData(FormDataList&, bool);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
- void dispatchChangeEventForMenuList();
+ void dispatchInputAndChangeEventForMenuList(bool requiresUserGesture = true);
void recalcListItems(bool updateSelectedStates = true) const;
- void deselectItems(HTMLOptionElement* excludeElement = 0);
void typeAheadFind(KeyboardEvent*);
void saveLastSelection();
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
- virtual bool isRequiredFormControl() const;
+ virtual bool isOptionalFormControl() const OVERRIDE { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const OVERRIDE;
bool hasPlaceholderLabelOption() const;
enum SelectOptionFlag {
DeselectOtherOptions = 1 << 0,
- DispatchChangeEvent = 1 << 1,
+ DispatchInputAndChangeEvent = 1 << 1,
UserDriven = 1 << 2,
};
typedef unsigned SelectOptionFlags;
@@ -186,7 +191,7 @@ private:
int lastSelectableListIndex() const;
int nextSelectableListIndexPageAway(int startIndex, SkipDirection) const;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
virtual void finishParsingChildren() OVERRIDE;
@@ -196,7 +201,7 @@ private:
virtual String optionAtIndex(int index) const OVERRIDE;
// m_listItems contains HTMLOptionElement, HTMLOptGroupElement, and HTMLHRElement objects.
- mutable Vector<HTMLElement*> m_listItems;
+ mutable WillBeHeapVector<RawPtrWillBeMember<HTMLElement> > m_listItems;
Vector<bool> m_lastOnChangeSelection;
Vector<bool> m_cachedStateForActiveSelection;
TypeAhead m_typeAhead;
@@ -208,11 +213,9 @@ private:
bool m_multiple;
bool m_activeSelectionState;
mutable bool m_shouldRecalcListItems;
- bool m_isParsingInProgress;
+ int m_suggestedIndex;
};
-DEFINE_NODE_TYPE_CASTS(HTMLSelectElement, hasTagName(HTMLNames::selectTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl
index b61f5128247..52a124495f9 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSelectElement.idl
@@ -19,6 +19,8 @@
* Boston, MA 02110-1301, USA.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#htmlselectelement
+
interface HTMLSelectElement : HTMLElement {
[Reflect] attribute boolean autofocus;
[Reflect] attribute boolean disabled;
@@ -33,17 +35,18 @@ interface HTMLSelectElement : HTMLElement {
readonly attribute HTMLOptionsCollection options;
[RaisesException=Setter] attribute unsigned long length;
- getter Node item(unsigned long index);
- [ImplementedAs=anonymousIndexedSetter, RaisesException] setter HTMLOptionElement (unsigned long index, [TreatNullAs=anonymousIndexedSetterRemove, TreatUndefinedAs=anonymousIndexedSetterRemove] HTMLOptionElement value);
- Node namedItem([Default=Undefined] optional DOMString name);
- [RaisesException] void add([Default=Undefined] optional HTMLElement element,
- [Default=Undefined] optional HTMLElement before);
+ getter Element item(unsigned long index);
+ Element namedItem([Default=Undefined] optional DOMString name);
+ // FIXME: should be union type http://crbug.com/240176
+ [RaisesException, TypeChecking=Interface] void add(HTMLElement element, optional HTMLElement? before = null);
+ [ImplementedAs=addBeforeOptionAtIndex, RaisesException, TypeChecking=Interface] void add(HTMLElement element, long before);
+ [RaisesException] void remove(); // ChildNode overload
void remove(long index);
- void remove(HTMLOptionElement option); // Non standard.
- [RaisesException] void remove();
+ [RaisesException, TypeChecking=Interface|Nullable] setter HTMLOptionElement (unsigned long index, HTMLOptionElement? value);
+
readonly attribute HTMLCollection selectedOptions;
- attribute long selectedIndex;
- attribute DOMString value;
+ attribute long selectedIndex;
+ attribute DOMString value;
readonly attribute boolean willValidate;
readonly attribute ValidityState validity;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.cpp
new file mode 100644
index 00000000000..d44d71b741f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/HTMLShadowElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/shadow/ShadowRoot.h"
+
+namespace WebCore {
+
+class Document;
+
+inline HTMLShadowElement::HTMLShadowElement(Document& document)
+ : InsertionPoint(HTMLNames::shadowTag, document)
+{
+ ScriptWrappable::init(this);
+}
+
+DEFINE_NODE_FACTORY(HTMLShadowElement)
+
+HTMLShadowElement::~HTMLShadowElement()
+{
+}
+
+ShadowRoot* HTMLShadowElement::olderShadowRoot()
+{
+ ShadowRoot* containingRoot = containingShadowRoot();
+ if (!containingRoot)
+ return 0;
+
+ document().updateDistributionForNodeIfNeeded(this);
+
+ ShadowRoot* older = containingRoot->olderShadowRoot();
+ if (!older || !older->shouldExposeToBindings() || older->shadowInsertionPointOfYoungerShadowRoot() != this)
+ return 0;
+
+ ASSERT(older->shouldExposeToBindings());
+ return older;
+}
+
+Node::InsertionNotificationRequest HTMLShadowElement::insertedInto(ContainerNode* insertionPoint)
+{
+ if (insertionPoint->inDocument()) {
+ // Warn if trying to reproject between user agent and author shadows.
+ ShadowRoot* root = containingShadowRoot();
+ if (root && root->olderShadowRoot() && root->type() != root->olderShadowRoot()->type()) {
+ String message = String::format("<shadow> doesn't work for %s element host.", root->host()->tagName().utf8().data());
+ document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
+ }
+ }
+ return InsertionPoint::insertedInto(insertionPoint);
+}
+
+} // namespace WebCore
+
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h
index 70833399beb..5f0f02695b1 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.h
@@ -1,2 +1,53 @@
-// FIXME: Move HTMLShadowElement.h here.
-#include "core/html/shadow/HTMLShadowElement.h"
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLShadowElement_h
+#define HTMLShadowElement_h
+
+#include "core/dom/shadow/InsertionPoint.h"
+#include "wtf/Forward.h"
+
+namespace WebCore {
+
+class HTMLShadowElement FINAL : public InsertionPoint {
+public:
+ DECLARE_NODE_FACTORY(HTMLShadowElement);
+ virtual ~HTMLShadowElement();
+
+ ShadowRoot* olderShadowRoot();
+
+private:
+ explicit HTMLShadowElement(Document&);
+ virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint) OVERRIDE;
+};
+
+} // namespace WebCore
+
+#endif // HTMLShadowElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.idl
new file mode 100644
index 00000000000..86532b18888
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLShadowElement.idl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface HTMLShadowElement : HTMLElement {
+ NodeList getDistributedNodes();
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp
index 75daceb07a4..6364f84b11d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp
@@ -26,37 +26,45 @@
#include "config.h"
#include "core/html/HTMLSourceElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/events/EventSender.h"
#include "core/html/HTMLMediaElement.h"
+#include "core/html/HTMLPictureElement.h"
#include "platform/Logging.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
+static SourceEventSender& sourceErrorEventSender()
+{
+ DEFINE_STATIC_LOCAL(SourceEventSender, sharedErrorEventSender, (EventTypeNames::error));
+ return sharedErrorEventSender;
+}
+
inline HTMLSourceElement::HTMLSourceElement(Document& document)
: HTMLElement(sourceTag, document)
- , m_errorEventTimer(this, &HTMLSourceElement::errorEventTimerFired)
{
WTF_LOG(Media, "HTMLSourceElement::HTMLSourceElement - %p", this);
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLSourceElement> HTMLSourceElement::create(Document& document)
+DEFINE_NODE_FACTORY(HTMLSourceElement)
+
+HTMLSourceElement::~HTMLSourceElement()
{
- return adoptRef(new HTMLSourceElement(document));
+ sourceErrorEventSender().cancelEvent(this);
}
Node::InsertionNotificationRequest HTMLSourceElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
Element* parent = parentElement();
- if (parent && parent->isMediaElement())
- toHTMLMediaElement(parentNode())->sourceWasAdded(this);
+ if (isHTMLMediaElement(parent))
+ toHTMLMediaElement(parent)->sourceWasAdded(this);
+ if (isHTMLPictureElement(parent))
+ toHTMLPictureElement(parent)->sourceOrMediaChanged();
return InsertionDone;
}
@@ -65,8 +73,10 @@ void HTMLSourceElement::removedFrom(ContainerNode* removalRoot)
Element* parent = parentElement();
if (!parent && removalRoot->isElementNode())
parent = toElement(removalRoot);
- if (parent && parent->isMediaElement())
+ if (isHTMLMediaElement(parent))
toHTMLMediaElement(parent)->sourceWasRemoved(this);
+ if (isHTMLPictureElement(parent))
+ toHTMLPictureElement(parent)->sourceOrMediaChanged();
HTMLElement::removedFrom(removalRoot);
}
@@ -75,16 +85,6 @@ void HTMLSourceElement::setSrc(const String& url)
setAttribute(srcAttr, AtomicString(url));
}
-const AtomicString& HTMLSourceElement::media() const
-{
- return getAttribute(mediaAttr);
-}
-
-void HTMLSourceElement::setMedia(const AtomicString& media)
-{
- setAttribute(mediaAttr, media);
-}
-
const AtomicString& HTMLSourceElement::type() const
{
return getAttribute(typeAttr);
@@ -98,21 +98,19 @@ void HTMLSourceElement::setType(const AtomicString& type)
void HTMLSourceElement::scheduleErrorEvent()
{
WTF_LOG(Media, "HTMLSourceElement::scheduleErrorEvent - %p", this);
- if (m_errorEventTimer.isActive())
- return;
-
- m_errorEventTimer.startOneShot(0);
+ sourceErrorEventSender().dispatchEventSoon(this);
}
void HTMLSourceElement::cancelPendingErrorEvent()
{
WTF_LOG(Media, "HTMLSourceElement::cancelPendingErrorEvent - %p", this);
- m_errorEventTimer.stop();
+ sourceErrorEventSender().cancelEvent(this);
}
-void HTMLSourceElement::errorEventTimerFired(Timer<HTMLSourceElement>*)
+void HTMLSourceElement::dispatchPendingEvent(SourceEventSender* eventSender)
{
- WTF_LOG(Media, "HTMLSourceElement::errorEventTimerFired - %p", this);
+ ASSERT_UNUSED(eventSender, eventSender == &sourceErrorEventSender());
+ WTF_LOG(Media, "HTMLSourceElement::dispatchPendingEvent - %p", this);
dispatchEvent(Event::createCancelable(EventTypeNames::error));
}
@@ -121,4 +119,14 @@ bool HTMLSourceElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == srcAttr || HTMLElement::isURLAttribute(attribute);
}
+void HTMLSourceElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
+{
+ HTMLElement::parseAttribute(name, value);
+ if (name == srcsetAttr || name == sizesAttr || name == mediaAttr || name == typeAttr) {
+ Element* parent = parentElement();
+ if (isHTMLPictureElement(parent))
+ toHTMLPictureElement(parent)->sourceOrMediaChanged();
+ }
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h
index 0002d210706..339c12a99af 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.h
@@ -31,33 +31,32 @@
namespace WebCore {
+template<typename T> class EventSender;
+typedef EventSender<HTMLSourceElement> SourceEventSender;
+
class HTMLSourceElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLSourceElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLSourceElement);
+ virtual ~HTMLSourceElement();
- const AtomicString& media() const;
const AtomicString& type() const;
void setSrc(const String&);
- void setMedia(const AtomicString&);
void setType(const AtomicString&);
void scheduleErrorEvent();
void cancelPendingErrorEvent();
+ void dispatchPendingEvent(SourceEventSender*);
+
private:
explicit HTMLSourceElement(Document&);
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
-
- void errorEventTimerFired(Timer<HTMLSourceElement>*);
-
- Timer<HTMLSourceElement> m_errorEventTimer;
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLSourceElement, hasTagName(HTMLNames::sourceTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl
index 4e10349051e..45f76b93977 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSourceElement.idl
@@ -26,7 +26,12 @@
[
RuntimeEnabled=Media
] interface HTMLSourceElement : HTMLElement {
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
attribute DOMString type;
- attribute DOMString media;
+
+ [Reflect, RuntimeEnabled=Picture] attribute DOMString srcset;
+ [Reflect, RuntimeEnabled=Picture] attribute DOMString sizes;
+ [Reflect, RuntimeEnabled=Picture] attribute DOMString media;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp
index 193c659b84d..840377e2aa2 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/html/HTMLSpanElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -38,9 +38,6 @@ HTMLSpanElement::HTMLSpanElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLSpanElement> HTMLSpanElement::create(Document& document)
-{
- return adoptRef(new HTMLSpanElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLSpanElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h
index ca77b867cfb..69e0e049b2e 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSpanElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLSpanElement : public HTMLElement {
public:
- static PassRefPtr<HTMLSpanElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLSpanElement);
protected:
explicit HTMLSpanElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
index c3d7e1c31aa..3076436827d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "core/html/HTMLStyleElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/MediaList.h"
#include "core/css/StyleSheetContents.h"
#include "core/dom/ContextFeatures.h"
@@ -49,135 +49,48 @@ inline HTMLStyleElement::HTMLStyleElement(Document& document, bool createdByPars
, StyleElement(&document, createdByParser)
, m_firedLoad(false)
, m_loadedSheet(false)
- , m_scopedStyleRegistrationState(NotRegistered)
{
ScriptWrappable::init(this);
}
HTMLStyleElement::~HTMLStyleElement()
{
- // During tear-down, willRemove isn't called, so m_scopedStyleRegistrationState may still be RegisteredAsScoped or RegisteredInShadowRoot here.
- // Therefore we can't ASSERT(m_scopedStyleRegistrationState == NotRegistered).
+#if !ENABLE(OILPAN)
StyleElement::clearDocumentData(document(), this);
+#endif
styleLoadEventSender().cancelEvent(this);
}
-PassRefPtr<HTMLStyleElement> HTMLStyleElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<HTMLStyleElement> HTMLStyleElement::create(Document& document, bool createdByParser)
{
- return adoptRef(new HTMLStyleElement(document, createdByParser));
+ return adoptRefWillBeNoop(new HTMLStyleElement(document, createdByParser));
}
void HTMLStyleElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == titleAttr && m_sheet) {
m_sheet->setTitle(value);
- } else if (name == scopedAttr && ContextFeatures::styleScopedEnabled(&document())) {
- scopedAttributeChanged(!value.isNull());
} else if (name == mediaAttr && inDocument() && document().isActive() && m_sheet) {
m_sheet->setMediaQueries(MediaQuerySet::create(value));
- // FIXME: This shold be RecalcStyleDeferred.
- document().modifiedStyleSheet(m_sheet.get(), RecalcStyleImmediately);
+ document().modifiedStyleSheet(m_sheet.get());
} else {
HTMLElement::parseAttribute(name, value);
}
}
-void HTMLStyleElement::scopedAttributeChanged(bool scoped)
-{
- ASSERT(ContextFeatures::styleScopedEnabled(&document()));
-
- if (!inDocument())
- return;
-
- if (scoped) {
- if (m_scopedStyleRegistrationState == RegisteredAsScoped)
- return;
-
- // As any <style> in a shadow tree is treated as "scoped",
- // need to remove the <style> from its shadow root.
- ContainerNode* scopingNode = 0;
- if (m_scopedStyleRegistrationState == RegisteredInShadowRoot) {
- scopingNode = containingShadowRoot();
- unregisterWithScopingNode(scopingNode);
- }
- document().styleEngine()->removeStyleSheetCandidateNode(this, scopingNode);
- registerWithScopingNode(true);
-
- document().styleEngine()->addStyleSheetCandidateNode(this, false);
- document().modifiedStyleSheet(sheet());
- return;
- }
-
- // If the <style> was scoped, need to remove the <style> from the scoping
- // element, i.e. the parent node.
- if (m_scopedStyleRegistrationState != RegisteredAsScoped)
- return;
-
- unregisterWithScopingNode(parentNode());
- document().styleEngine()->removeStyleSheetCandidateNode(this, parentNode());
-
- // As any <style> in a shadow tree is treated as "scoped",
- // need to add the <style> to its shadow root.
- if (isInShadowTree())
- registerWithScopingNode(false);
-
- document().styleEngine()->addStyleSheetCandidateNode(this, false);
- // FIXME: currently need to use FullStyleUpdate here.
- // Because ShadowTreeStyleSheetCollection doesn't know old scoping node.
- // So setNeedsStyleRecalc for old scoping node is not invoked.
- document().modifiedStyleSheet(sheet());
-}
-
void HTMLStyleElement::finishParsingChildren()
{
StyleElement::finishParsingChildren(this);
HTMLElement::finishParsingChildren();
}
-void HTMLStyleElement::registerWithScopingNode(bool scoped)
-{
- // Note: We cannot rely on the 'scoped' element already being present when this method is invoked.
- // Therefore we cannot rely on scoped()!
- ASSERT(m_scopedStyleRegistrationState == NotRegistered);
- ASSERT(inDocument());
- if (m_scopedStyleRegistrationState != NotRegistered)
- return;
-
- ContainerNode* scope = scoped ? parentNode() : containingShadowRoot();
- if (!scope)
- return;
- if (!scope->isElementNode() && !scope->isShadowRoot()) {
- // DocumentFragment nodes should never be inDocument,
- // <style> should not be a child of Document, PI or some such.
- ASSERT_NOT_REACHED();
- return;
- }
- scope->registerScopedHTMLStyleChild();
- m_scopedStyleRegistrationState = scoped ? RegisteredAsScoped : RegisteredInShadowRoot;
-}
-
-void HTMLStyleElement::unregisterWithScopingNode(ContainerNode* scope)
-{
- ASSERT(m_scopedStyleRegistrationState != NotRegistered || !ContextFeatures::styleScopedEnabled(&document()));
- if (!isRegisteredAsScoped())
- return;
-
- ASSERT(scope);
- if (scope) {
- ASSERT(scope->hasScopedHTMLStyleChild());
- scope->unregisterScopedHTMLStyleChild();
- }
-
- m_scopedStyleRegistrationState = NotRegistered;
-}
-
Node::InsertionNotificationRequest HTMLStyleElement::insertedInto(ContainerNode* insertionPoint)
{
HTMLElement::insertedInto(insertionPoint);
- if (insertionPoint->inDocument()) {
- if (m_scopedStyleRegistrationState == NotRegistered && (scoped() || isInShadowTree()))
- registerWithScopingNode(scoped());
+ if (insertionPoint->inDocument() && isInShadowTree()) {
+ if (ShadowRoot* scope = containingShadowRoot())
+ scope->registerScopedHTMLStyleChild();
}
return InsertionShouldCallDidNotifySubtreeInsertions;
}
@@ -186,23 +99,18 @@ void HTMLStyleElement::removedFrom(ContainerNode* insertionPoint)
{
HTMLElement::removedFrom(insertionPoint);
- // In the current implementation, <style scoped> is only registered if the node is in the document.
- // That is, because willRemove() is also called if an ancestor is removed from the document.
- // Now, if we want to register <style scoped> even if it's not inDocument,
- // we'd need to find a way to discern whether that is the case, or whether <style scoped> itself is about to be removed.
- ContainerNode* scope = 0;
- if (m_scopedStyleRegistrationState != NotRegistered) {
- if (m_scopedStyleRegistrationState == RegisteredInShadowRoot) {
- scope = containingShadowRoot();
- if (!scope)
- scope = insertionPoint->containingShadowRoot();
- } else
- scope = parentNode() ? parentNode() : insertionPoint;
- unregisterWithScopingNode(scope);
- }
+ if (!insertionPoint->inDocument())
+ return;
+
+ ShadowRoot* scopingNode = containingShadowRoot();
+ if (!scopingNode)
+ scopingNode = insertionPoint->containingShadowRoot();
+
+ if (scopingNode)
+ scopingNode->unregisterScopedHTMLStyleChild();
- if (insertionPoint->inDocument())
- StyleElement::removedFromDocument(document(), this, scope);
+ TreeScope* containingScope = containingShadowRoot();
+ StyleElement::removedFromDocument(document(), this, scopingNode, containingScope ? *containingScope : insertionPoint->treeScope());
}
void HTMLStyleElement::didNotifySubtreeInsertionsToDocument()
@@ -226,28 +134,15 @@ const AtomicString& HTMLStyleElement::type() const
return getAttribute(typeAttr);
}
-bool HTMLStyleElement::scoped() const
-{
- return fastHasAttribute(scopedAttr) && ContextFeatures::styleScopedEnabled(&document());
-}
-
-void HTMLStyleElement::setScoped(bool scopedValue)
-{
- setBooleanAttribute(scopedAttr, scopedValue);
-}
-
ContainerNode* HTMLStyleElement::scopingNode()
{
if (!inDocument())
return 0;
- if (!isRegisteredAsScoped())
- return &document();
-
- if (isRegisteredInShadowRoot())
+ if (isInShadowTree())
return containingShadowRoot();
- return parentNode();
+ return &document();
}
void HTMLStyleElement::dispatchPendingLoadEvents()
@@ -270,14 +165,6 @@ void HTMLStyleElement::notifyLoadedSheetAndAllCriticalSubresources(bool errorOcc
m_firedLoad = true;
}
-void HTMLStyleElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- if (CSSStyleSheet* styleSheet = const_cast<HTMLStyleElement*>(this)->sheet())
- styleSheet->contents()->addSubresourceStyleURLs(urls);
-}
-
bool HTMLStyleElement::disabled() const
{
if (!m_sheet)
@@ -292,4 +179,10 @@ void HTMLStyleElement::setDisabled(bool setDisabled)
styleSheet->setDisabled(setDisabled);
}
+void HTMLStyleElement::trace(Visitor* visitor)
+{
+ StyleElement::trace(visitor);
+ HTMLElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h
index 3ab95c6c0ee..71da210804c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.h
@@ -35,28 +35,14 @@ template<typename T> class EventSender;
typedef EventSender<HTMLStyleElement> StyleEventSender;
class HTMLStyleElement FINAL : public HTMLElement, private StyleElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLStyleElement);
public:
- static PassRefPtr<HTMLStyleElement> create(Document&, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<HTMLStyleElement> create(Document&, bool createdByParser);
virtual ~HTMLStyleElement();
void setType(const AtomicString&);
- bool scoped() const;
- void setScoped(bool);
ContainerNode* scopingNode();
- bool isRegisteredAsScoped() const
- {
- // Note: We cannot rely on the 'scoped' attribute still being present when this method is invoked.
- // Therefore we cannot rely on scoped()!
- if (m_scopedStyleRegistrationState == NotRegistered)
- return false;
- return true;
- }
-
- bool isRegisteredInShadowRoot() const
- {
- return m_scopedStyleRegistrationState == RegisteredInShadowRoot;
- }
using StyleElement::sheet;
@@ -66,6 +52,8 @@ public:
void dispatchPendingEvent(StyleEventSender*);
static void dispatchPendingLoadEvents();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
HTMLStyleElement(Document&, bool createdByParser);
@@ -74,43 +62,21 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-
- virtual void finishParsingChildren();
-
- virtual bool isLoading() const { return StyleElement::isLoading(); }
- virtual bool sheetLoaded() { return StyleElement::sheetLoaded(document()); }
- virtual void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred);
- virtual void startLoadingDynamicSheet() { StyleElement::startLoadingDynamicSheet(document()); }
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual void finishParsingChildren() OVERRIDE;
- virtual const AtomicString& media() const;
- virtual const AtomicString& type() const;
+ virtual bool sheetLoaded() OVERRIDE { return StyleElement::sheetLoaded(document()); }
+ virtual void notifyLoadedSheetAndAllCriticalSubresources(bool errorOccurred) OVERRIDE;
+ virtual void startLoadingDynamicSheet() OVERRIDE { StyleElement::startLoadingDynamicSheet(document()); }
- void scopedAttributeChanged(bool);
- void registerWithScopingNode(bool);
- void unregisterWithScopingNode(ContainerNode*);
+ virtual const AtomicString& media() const OVERRIDE;
+ virtual const AtomicString& type() const OVERRIDE;
bool m_firedLoad;
bool m_loadedSheet;
-
- enum ScopedStyleRegistrationState {
- NotRegistered,
- RegisteredAsScoped,
- RegisteredInShadowRoot
- };
- ScopedStyleRegistrationState m_scopedStyleRegistrationState;
};
-inline bool isHTMLStyleElement(Node* node)
-{
- ASSERT(node);
- return node->hasTagName(HTMLNames::styleTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLStyleElement, hasTagName(HTMLNames::styleTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl
index 42a38de99d4..ecc6b2bd57d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLStyleElement.idl
@@ -20,7 +20,6 @@
interface HTMLStyleElement : HTMLElement {
attribute boolean disabled;
- [RuntimeEnabled=StyleScoped] attribute boolean scoped;
[Reflect] attribute DOMString media;
[Reflect] attribute DOMString type;
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp
index 7f13462137e..821b37a8e99 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.cpp
@@ -21,23 +21,23 @@
#include "config.h"
#include "core/html/HTMLSummaryElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLContentElement.h"
#include "core/html/HTMLDetailsElement.h"
#include "core/html/shadow/DetailsMarkerControl.h"
-#include "core/html/shadow/HTMLContentElement.h"
#include "core/rendering/RenderBlockFlow.h"
namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<HTMLSummaryElement> HTMLSummaryElement::create(Document& document)
+PassRefPtrWillBeRawPtr<HTMLSummaryElement> HTMLSummaryElement::create(Document& document)
{
- RefPtr<HTMLSummaryElement> summary = adoptRef(new HTMLSummaryElement(document));
+ RefPtrWillBeRawPtr<HTMLSummaryElement> summary = adoptRefWillBeNoop(new HTMLSummaryElement(document));
summary->ensureUserAgentShadowRoot();
return summary.release();
}
@@ -61,7 +61,7 @@ void HTMLSummaryElement::didAddUserAgentShadowRoot(ShadowRoot& root)
HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
{
Node* parent = NodeRenderingTraversal::parent(this);
- if (parent && isHTMLDetailsElement(parent))
+ if (isHTMLDetailsElement(parent))
return toHTMLDetailsElement(parent);
return 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h
index 45f14630a86..1a05da725ae 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLSummaryElement.h
@@ -29,23 +29,21 @@ class HTMLDetailsElement;
class HTMLSummaryElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLSummaryElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<HTMLSummaryElement> create(Document&);
bool isMainSummary() const;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
private:
explicit HTMLSummaryElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual void defaultEventHandler(Event*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual void didAddUserAgentShadowRoot(ShadowRoot&) OVERRIDE;
HTMLDetailsElement* detailsElement() const;
- bool supportsFocus() const OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLSummaryElement, hasTagName(HTMLNames::summaryTag));
-
}
#endif // HTMLSummaryElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp
index 0212e3249e4..872845f736f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/html/HTMLTableCaptionElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
@@ -38,17 +38,7 @@ inline HTMLTableCaptionElement::HTMLTableCaptionElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableCaptionElement> HTMLTableCaptionElement::create(Document& document)
-{
- return adoptRef(new HTMLTableCaptionElement(document));
-}
-
-bool HTMLTableCaptionElement::isPresentationAttribute(const QualifiedName& name) const
-{
- if (name == alignAttr)
- return true;
- return HTMLElement::isPresentationAttribute(name);
-}
+DEFINE_NODE_FACTORY(HTMLTableCaptionElement)
void HTMLTableCaptionElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h
index 33315acfdb0..ce8b6c11d91 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableCaptionElement.h
@@ -32,17 +32,14 @@ namespace WebCore {
class HTMLTableCaptionElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTableCaptionElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTableCaptionElement);
private:
HTMLTableCaptionElement(Document&);
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(HTMLTableCaptionElement, hasTagName(HTMLNames::captionTag));
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp
index 01b712585fc..2f6d5d5418f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.cpp
@@ -25,9 +25,9 @@
#include "config.h"
#include "core/html/HTMLTableCellElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/html/HTMLTableElement.h"
#include "core/rendering/RenderTableCell.h"
@@ -48,10 +48,7 @@ inline HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tagName,
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableCellElement> HTMLTableCellElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLTableCellElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableCellElement)
int HTMLTableCellElement::colSpan() const
{
@@ -67,14 +64,12 @@ int HTMLTableCellElement::rowSpan() const
int HTMLTableCellElement::cellIndex() const
{
- int index = 0;
- if (!parentElement() || !parentElement()->hasTagName(trTag))
+ if (!isHTMLTableRowElement(parentElement()))
return -1;
- for (const Node * node = previousSibling(); node; node = node->previousSibling()) {
- if (node->hasTagName(tdTag) || node->hasTagName(thTag))
- index++;
- }
+ int index = 0;
+ for (const HTMLTableCellElement* element = Traversal<HTMLTableCellElement>::previousSibling(*this); element; element = Traversal<HTMLTableCellElement>::previousSibling(*element))
+ ++index;
return index;
}
@@ -130,14 +125,24 @@ bool HTMLTableCellElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == backgroundAttr || HTMLTablePartElement::isURLAttribute(attribute);
}
+bool HTMLTableCellElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return (hasLocalName(tdTag) && name == backgroundAttr) || HTMLTablePartElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLTableCellElement::subResourceAttributeName() const
+{
+ return hasLocalName(tdTag) ? backgroundAttr : HTMLTablePartElement::subResourceAttributeName();
+}
+
const AtomicString& HTMLTableCellElement::abbr() const
{
- return getAttribute(abbrAttr);
+ return fastGetAttribute(abbrAttr);
}
const AtomicString& HTMLTableCellElement::axis() const
{
- return getAttribute(axisAttr);
+ return fastGetAttribute(axisAttr);
}
void HTMLTableCellElement::setColSpan(int n)
@@ -147,7 +152,7 @@ void HTMLTableCellElement::setColSpan(int n)
const AtomicString& HTMLTableCellElement::headers() const
{
- return getAttribute(headersAttr);
+ return fastGetAttribute(headersAttr);
}
void HTMLTableCellElement::setRowSpan(int n)
@@ -157,14 +162,7 @@ void HTMLTableCellElement::setRowSpan(int n)
const AtomicString& HTMLTableCellElement::scope() const
{
- return getAttribute(scopeAttr);
-}
-
-void HTMLTableCellElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- HTMLTablePartElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
+ return fastGetAttribute(scopeAttr);
}
HTMLTableCellElement* HTMLTableCellElement::cellAbove() const
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h
index 8c22cccfb38..55cbd5f4b6b 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableCellElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLTableCellElement FINAL : public HTMLTablePartElement {
public:
- static PassRefPtr<HTMLTableCellElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableCellElement);
int cellIndex() const;
@@ -59,16 +59,21 @@ private:
virtual const StylePropertySet* additionalPresentationAttributeStyle() OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
-
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
};
-inline bool isHTMLTableCellElement(const Node& node)
+inline bool isHTMLTableCellElement(const Element& element)
+{
+ return element.hasTagName(HTMLNames::tdTag) || element.hasTagName(HTMLNames::thTag);
+}
+
+inline bool isHTMLTableCellElement(const HTMLElement& element)
{
- return node.hasTagName(HTMLNames::tdTag) || node.hasTagName(HTMLNames::thTag);
+ return element.hasLocalName(HTMLNames::tdTag) || element.hasLocalName(HTMLNames::thTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableCellElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableCellElement);
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp
index 19e301d95c0..5094868e388 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/html/HTMLTableColElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLTableElement.h"
#include "core/rendering/RenderTableCol.h"
@@ -41,10 +41,7 @@ inline HTMLTableColElement::HTMLTableColElement(const QualifiedName& tagName, Do
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableColElement> HTMLTableColElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLTableColElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableColElement)
bool HTMLTableColElement::isPresentationAttribute(const QualifiedName& name) const
{
@@ -64,7 +61,10 @@ void HTMLTableColElement::collectStyleForPresentationAttribute(const QualifiedNa
void HTMLTableColElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
if (name == spanAttr) {
- m_span = !value.isNull() ? value.toInt() : 1;
+ int newSpan = value.toInt();
+ // If the value of span is not a valid non-negative integer greater than zero,
+ // set it to 1.
+ m_span = newSpan ? newSpan : 1;
if (renderer() && renderer()->isRenderTableCol())
renderer()->updateFromElement();
} else if (name == widthAttr) {
@@ -73,7 +73,7 @@ void HTMLTableColElement::parseAttribute(const QualifiedName& name, const Atomic
RenderTableCol* col = toRenderTableCol(renderer());
int newWidth = width().toInt();
if (newWidth != col->width())
- col->setNeedsLayoutAndPrefWidthsRecalc();
+ col->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
}
} else
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h
index ecd3f73f241..72e859673ec 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableColElement.h
@@ -32,7 +32,7 @@ namespace WebCore {
class HTMLTableColElement FINAL : public HTMLTablePartElement {
public:
- static PassRefPtr<HTMLTableColElement> create(const QualifiedName& tagName, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableColElement);
int span() const { return m_span; }
void setSpan(int);
@@ -50,12 +50,17 @@ private:
int m_span;
};
-inline bool isHTMLTableColElement(const Node& node)
+inline bool isHTMLTableColElement(const Element& element)
{
- return node.hasTagName(HTMLNames::colTag) || node.hasTagName(HTMLNames::colgroupTag);
+ return element.hasTagName(HTMLNames::colTag) || element.hasTagName(HTMLNames::colgroupTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableColElement);
+inline bool isHTMLTableColElement(const HTMLElement& element)
+{
+ return element.hasLocalName(HTMLNames::colTag) || element.hasLocalName(HTMLNames::colgroupTag);
+}
+
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableColElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
index c963c1f65a0..cebf9c3d6ea 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
@@ -25,29 +25,33 @@
#include "config.h"
#include "core/html/HTMLTableElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSImageValue.h"
#include "core/css/CSSValuePool.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Attribute.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLTableCaptionElement.h"
+#include "core/html/HTMLTableCellElement.h"
#include "core/html/HTMLTableRowElement.h"
#include "core/html/HTMLTableRowsCollection.h"
#include "core/html/HTMLTableSectionElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/rendering/RenderTable.h"
+#include "platform/weborigin/Referrer.h"
#include "wtf/StdLibExtras.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLTableElement::HTMLTableElement(Document& document)
+inline HTMLTableElement::HTMLTableElement(Document& document)
: HTMLElement(tableTag, document)
, m_borderAttr(false)
, m_borderColorAttr(false)
@@ -58,21 +62,14 @@ HTMLTableElement::HTMLTableElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableElement> HTMLTableElement::create(Document& document)
-{
- return adoptRef(new HTMLTableElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLTableElement)
HTMLTableCaptionElement* HTMLTableElement::caption() const
{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(captionTag))
- return toHTMLTableCaptionElement(child);
- }
- return 0;
+ return Traversal<HTMLTableCaptionElement>::firstChild(*this);
}
-void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption, ExceptionState& exceptionState)
+void HTMLTableElement::setCaption(PassRefPtrWillBeRawPtr<HTMLTableCaptionElement> newCaption, ExceptionState& exceptionState)
{
deleteCaption();
insertBefore(newCaption, firstChild(), exceptionState);
@@ -80,51 +77,53 @@ void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption
HTMLTableSectionElement* HTMLTableElement::tHead() const
{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
if (child->hasTagName(theadTag))
return toHTMLTableSectionElement(child);
}
return 0;
}
-void HTMLTableElement::setTHead(PassRefPtr<HTMLTableSectionElement> newHead, ExceptionState& exceptionState)
+void HTMLTableElement::setTHead(PassRefPtrWillBeRawPtr<HTMLTableSectionElement> newHead, ExceptionState& exceptionState)
{
deleteTHead();
- Node* child;
- for (child = firstChild(); child; child = child->nextSibling())
- if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
+ Element* child;
+ for (child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
+ if (!child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
break;
+ }
insertBefore(newHead, child, exceptionState);
}
HTMLTableSectionElement* HTMLTableElement::tFoot() const
{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
+ for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
if (child->hasTagName(tfootTag))
return toHTMLTableSectionElement(child);
}
return 0;
}
-void HTMLTableElement::setTFoot(PassRefPtr<HTMLTableSectionElement> newFoot, ExceptionState& exceptionState)
+void HTMLTableElement::setTFoot(PassRefPtrWillBeRawPtr<HTMLTableSectionElement> newFoot, ExceptionState& exceptionState)
{
deleteTFoot();
- Node* child;
- for (child = firstChild(); child; child = child->nextSibling())
- if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
+ Element* child;
+ for (child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
+ if (!child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
break;
+ }
insertBefore(newFoot, child, exceptionState);
}
-PassRefPtr<HTMLElement> HTMLTableElement::createTHead()
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::createTHead()
{
if (HTMLTableSectionElement* existingHead = tHead())
return existingHead;
- RefPtr<HTMLTableSectionElement> head = HTMLTableSectionElement::create(theadTag, document());
+ RefPtrWillBeRawPtr<HTMLTableSectionElement> head = HTMLTableSectionElement::create(theadTag, document());
setTHead(head, IGNORE_EXCEPTION);
return head.release();
}
@@ -134,11 +133,11 @@ void HTMLTableElement::deleteTHead()
removeChild(tHead(), IGNORE_EXCEPTION);
}
-PassRefPtr<HTMLElement> HTMLTableElement::createTFoot()
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::createTFoot()
{
if (HTMLTableSectionElement* existingFoot = tFoot())
return existingFoot;
- RefPtr<HTMLTableSectionElement> foot = HTMLTableSectionElement::create(tfootTag, document());
+ RefPtrWillBeRawPtr<HTMLTableSectionElement> foot = HTMLTableSectionElement::create(tfootTag, document());
setTFoot(foot, IGNORE_EXCEPTION);
return foot.release();
}
@@ -148,20 +147,20 @@ void HTMLTableElement::deleteTFoot()
removeChild(tFoot(), IGNORE_EXCEPTION);
}
-PassRefPtr<HTMLElement> HTMLTableElement::createTBody()
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::createTBody()
{
- RefPtr<HTMLTableSectionElement> body = HTMLTableSectionElement::create(tbodyTag, document());
+ RefPtrWillBeRawPtr<HTMLTableSectionElement> body = HTMLTableSectionElement::create(tbodyTag, document());
Node* referenceElement = lastBody() ? lastBody()->nextSibling() : 0;
insertBefore(body, referenceElement);
return body.release();
}
-PassRefPtr<HTMLElement> HTMLTableElement::createCaption()
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::createCaption()
{
if (HTMLTableCaptionElement* existingCaption = caption())
return existingCaption;
- RefPtr<HTMLTableCaptionElement> caption = HTMLTableCaptionElement::create(document());
+ RefPtrWillBeRawPtr<HTMLTableCaptionElement> caption = HTMLTableCaptionElement::create(document());
setCaption(caption, IGNORE_EXCEPTION);
return caption.release();
}
@@ -180,26 +179,32 @@ HTMLTableSectionElement* HTMLTableElement::lastBody() const
return 0;
}
-PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::insertRow(ExceptionState& exceptionState)
+{
+ // The default 'index' argument value is -1.
+ return insertRow(-1, exceptionState);
+}
+
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionState& exceptionState)
{
if (index < -1) {
exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is less than -1.");
- return 0;
+ return nullptr;
}
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
- RefPtr<HTMLTableRowElement> lastRow = 0;
- RefPtr<HTMLTableRowElement> row = 0;
+ RefPtrWillBeRawPtr<HTMLTableRowElement> lastRow = nullptr;
+ RefPtrWillBeRawPtr<HTMLTableRowElement> row = nullptr;
if (index == -1)
- lastRow = HTMLTableRowsCollection::lastRow(this);
+ lastRow = HTMLTableRowsCollection::lastRow(*this);
else {
for (int i = 0; i <= index; ++i) {
- row = HTMLTableRowsCollection::rowAfter(this, lastRow.get());
+ row = HTMLTableRowsCollection::rowAfter(*this, lastRow.get());
if (!row) {
if (i != index) {
exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is greater than the number of rows in the table (" + String::number(i) + ").");
- return 0;
+ return nullptr;
}
break;
}
@@ -207,21 +212,21 @@ PassRefPtr<HTMLElement> HTMLTableElement::insertRow(int index, ExceptionState& e
}
}
- RefPtr<ContainerNode> parent;
+ RefPtrWillBeRawPtr<ContainerNode> parent;
if (lastRow)
parent = row ? row->parentNode() : lastRow->parentNode();
else {
parent = lastBody();
if (!parent) {
- RefPtr<HTMLTableSectionElement> newBody = HTMLTableSectionElement::create(tbodyTag, document());
- RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
+ RefPtrWillBeRawPtr<HTMLTableSectionElement> newBody = HTMLTableSectionElement::create(tbodyTag, document());
+ RefPtrWillBeRawPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
newBody->appendChild(newRow, exceptionState);
appendChild(newBody.release(), exceptionState);
return newRow.release();
}
}
- RefPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
+ RefPtrWillBeRawPtr<HTMLTableRowElement> newRow = HTMLTableRowElement::create(document());
parent->insertBefore(newRow, row.get(), exceptionState);
return newRow.release();
}
@@ -236,10 +241,10 @@ void HTMLTableElement::deleteRow(int index, ExceptionState& exceptionState)
HTMLTableRowElement* row = 0;
int i = 0;
if (index == -1)
- row = HTMLTableRowsCollection::lastRow(this);
+ row = HTMLTableRowsCollection::lastRow(*this);
else {
for (i = 0; i <= index; ++i) {
- row = HTMLTableRowsCollection::rowAfter(this, row);
+ row = HTMLTableRowsCollection::rowAfter(*this, row);
if (!row)
break;
}
@@ -251,29 +256,16 @@ void HTMLTableElement::deleteRow(int index, ExceptionState& exceptionState)
row->remove(exceptionState);
}
-static inline bool isTableCellAncestor(Node* n)
-{
- return n->hasTagName(theadTag) || n->hasTagName(tbodyTag) ||
- n->hasTagName(tfootTag) || n->hasTagName(trTag) ||
- n->hasTagName(thTag);
-}
-
-static bool setTableCellsChanged(Node* n)
+void HTMLTableElement::setNeedsTableStyleRecalc() const
{
- ASSERT(n);
- bool cellChanged = false;
-
- if (n->hasTagName(tdTag))
- cellChanged = true;
- else if (isTableCellAncestor(n)) {
- for (Node* child = n->firstChild(); child; child = child->nextSibling())
- cellChanged |= setTableCellsChanged(child);
+ Element* element = ElementTraversal::next(*this, this);
+ while (element) {
+ element->setNeedsStyleRecalc(LocalStyleChange);
+ if (isHTMLTableCellElement(*element))
+ element = ElementTraversal::nextSkippingChildren(*element, this);
+ else
+ element = ElementTraversal::next(*element, this);
}
-
- if (cellChanged)
- n->setNeedsStyleRecalc();
-
- return cellChanged;
}
static bool getBordersFromFrameAttributeValue(const AtomicString& value, bool& borderTop, bool& borderRight, bool& borderBottom, bool& borderLeft)
@@ -317,8 +309,11 @@ void HTMLTableElement::collectStyleForPresentationAttribute(const QualifiedName&
addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
else if (name == backgroundAttr) {
String url = stripLeadingAndTrailingHTMLSpaces(value);
- if (!url.isEmpty())
- style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document().completeURL(url).string())));
+ if (!url.isEmpty()) {
+ RefPtrWillBeRawPtr<CSSImageValue> imageValue = CSSImageValue::create(url, document().completeURL(url));
+ imageValue->setReferrer(Referrer(document().outgoingReferrer(), document().referrerPolicy()));
+ style->setProperty(CSSProperty(CSSPropertyBackgroundImage, imageValue.release()));
+ }
} else if (name == valignAttr) {
if (!value.isEmpty())
addPropertyToPresentationAttributeStyle(style, CSSPropertyVerticalAlign, value);
@@ -326,9 +321,11 @@ void HTMLTableElement::collectStyleForPresentationAttribute(const QualifiedName&
if (!value.isEmpty())
addHTMLLengthToStyle(style, CSSPropertyBorderSpacing, value);
} else if (name == vspaceAttr) {
+ UseCounter::count(document(), UseCounter::HTMLTableElementVspace);
addHTMLLengthToStyle(style, CSSPropertyMarginTop, value);
addHTMLLengthToStyle(style, CSSPropertyMarginBottom, value);
} else if (name == hspaceAttr) {
+ UseCounter::count(document(), UseCounter::HTMLTableElementHspace);
addHTMLLengthToStyle(style, CSSPropertyMarginLeft, value);
addHTMLLengthToStyle(style, CSSPropertyMarginRight, value);
} else if (name == alignAttr) {
@@ -406,18 +403,14 @@ void HTMLTableElement::parseAttribute(const QualifiedName& name, const AtomicStr
HTMLElement::parseAttribute(name, value);
if (bordersBefore != cellBorders() || oldPadding != m_padding) {
- m_sharedCellStyle = 0;
- bool cellChanged = false;
- for (Node* child = firstChild(); child; child = child->nextSibling())
- cellChanged |= setTableCellsChanged(child);
- if (cellChanged)
- setNeedsStyleRecalc();
+ m_sharedCellStyle = nullptr;
+ setNeedsTableStyleRecalc();
}
}
static PassRefPtr<StylePropertySet> createBorderStyle(CSSValueID value)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
style->setProperty(CSSPropertyBorderTopStyle, value);
style->setProperty(CSSPropertyBorderBottomStyle, value);
style->setProperty(CSSPropertyBorderLeftStyle, value);
@@ -471,9 +464,9 @@ HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
return NoBorders;
}
-PassRefPtr<StylePropertySet> HTMLTableElement::createSharedCellStyle()
+PassRefPtrWillBeRawPtr<StylePropertySet> HTMLTableElement::createSharedCellStyle()
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
switch (cellBorders()) {
case SolidBordersColsOnly:
@@ -518,9 +511,9 @@ const StylePropertySet* HTMLTableElement::additionalCellStyle()
return m_sharedCellStyle.get();
}
-static PassRefPtr<StylePropertySet> createGroupBorderStyle(int rows)
+static PassRefPtrWillBeRawPtr<StylePropertySet> createGroupBorderStyle(int rows)
{
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
if (rows) {
style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
@@ -553,12 +546,22 @@ bool HTMLTableElement::isURLAttribute(const Attribute& attribute) const
return attribute.name() == backgroundAttr || HTMLElement::isURLAttribute(attribute);
}
-PassRefPtr<HTMLCollection> HTMLTableElement::rows()
+bool HTMLTableElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == backgroundAttr || HTMLElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLTableElement::subResourceAttributeName() const
+{
+ return backgroundAttr;
+}
+
+PassRefPtrWillBeRawPtr<HTMLTableRowsCollection> HTMLTableElement::rows()
{
- return ensureCachedHTMLCollection(TableRows);
+ return toHTMLTableRowsCollection(ensureCachedHTMLCollection(TableRows).get());
}
-PassRefPtr<HTMLCollection> HTMLTableElement::tBodies()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLTableElement::tBodies()
{
return ensureCachedHTMLCollection(TableTBodies);
}
@@ -573,11 +576,10 @@ const AtomicString& HTMLTableElement::summary() const
return getAttribute(summaryAttr);
}
-void HTMLTableElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
+void HTMLTableElement::trace(Visitor* visitor)
{
- HTMLElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(getAttribute(backgroundAttr)));
+ visitor->trace(m_sharedCellStyle);
+ HTMLElement::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h
index d25a23c59bf..c8b2dbcf35a 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.h
@@ -38,29 +38,30 @@ class HTMLTableSectionElement;
class HTMLTableElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTableElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTableElement);
HTMLTableCaptionElement* caption() const;
- void setCaption(PassRefPtr<HTMLTableCaptionElement>, ExceptionState&);
+ void setCaption(PassRefPtrWillBeRawPtr<HTMLTableCaptionElement>, ExceptionState&);
HTMLTableSectionElement* tHead() const;
- void setTHead(PassRefPtr<HTMLTableSectionElement>, ExceptionState&);
+ void setTHead(PassRefPtrWillBeRawPtr<HTMLTableSectionElement>, ExceptionState&);
HTMLTableSectionElement* tFoot() const;
- void setTFoot(PassRefPtr<HTMLTableSectionElement>, ExceptionState&);
+ void setTFoot(PassRefPtrWillBeRawPtr<HTMLTableSectionElement>, ExceptionState&);
- PassRefPtr<HTMLElement> createTHead();
+ PassRefPtrWillBeRawPtr<HTMLElement> createTHead();
void deleteTHead();
- PassRefPtr<HTMLElement> createTFoot();
+ PassRefPtrWillBeRawPtr<HTMLElement> createTFoot();
void deleteTFoot();
- PassRefPtr<HTMLElement> createTBody();
- PassRefPtr<HTMLElement> createCaption();
+ PassRefPtrWillBeRawPtr<HTMLElement> createTBody();
+ PassRefPtrWillBeRawPtr<HTMLElement> createCaption();
void deleteCaption();
- PassRefPtr<HTMLElement> insertRow(int index, ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertRow(ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertRow(int index, ExceptionState&);
void deleteRow(int index, ExceptionState&);
- PassRefPtr<HTMLCollection> rows();
- PassRefPtr<HTMLCollection> tBodies();
+ PassRefPtrWillBeRawPtr<HTMLTableRowsCollection> rows();
+ PassRefPtrWillBeRawPtr<HTMLCollection> tBodies();
const AtomicString& rules() const;
const AtomicString& summary() const;
@@ -68,6 +69,8 @@ public:
const StylePropertySet* additionalCellStyle();
const StylePropertySet* additionalGroupStyle(bool rows);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit HTMLTableElement(Document&);
@@ -75,21 +78,23 @@ private:
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
// Used to obtain either a solid or outset border decl and to deal with the frame and rules attributes.
virtual const StylePropertySet* additionalPresentationAttributeStyle() OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
-
enum TableRules { UnsetRules, NoneRules, GroupsRules, RowsRules, ColsRules, AllRules };
enum CellBorders { NoBorders, SolidBorders, InsetBorders, SolidBordersColsOnly, SolidBordersRowsOnly };
CellBorders cellBorders() const;
- PassRefPtr<StylePropertySet> createSharedCellStyle();
+ PassRefPtrWillBeRawPtr<StylePropertySet> createSharedCellStyle();
HTMLTableSectionElement* lastBody() const;
+ void setNeedsTableStyleRecalc() const;
+
bool m_borderAttr; // Sets a precise border width and creates an outset border for the table and for its cells.
bool m_borderColorAttr; // Overrides the outset border and makes it solid for the table and cells instead.
bool m_frameAttr; // Implies a thin border width if no border is set and then a certain set of solid/hidden borders based off the value.
@@ -97,21 +102,9 @@ private:
// are present, to none otherwise).
unsigned short m_padding;
- RefPtr<StylePropertySet> m_sharedCellStyle;
+ RefPtrWillBeMember<StylePropertySet> m_sharedCellStyle;
};
-inline bool isHTMLTableElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::tableTag);
-}
-
-inline bool isHTMLTableElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::tableTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLTableElement, hasTagName(HTMLNames::tableTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl
index 4cd6d6f573b..3072583711c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableElement.idl
@@ -45,6 +45,6 @@ interface HTMLTableElement : HTMLElement {
HTMLElement createCaption();
void deleteCaption();
- [RaisesException] HTMLElement insertRow([Default=Undefined] optional long index);
+ [RaisesException] HTMLElement insertRow(optional long index);
[RaisesException] void deleteRow([Default=Undefined] optional long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
index 79b2b6c1138..4483de09ecc 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTablePartElement.cpp
@@ -25,15 +25,16 @@
#include "config.h"
#include "core/html/HTMLTablePartElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSImageValue.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderingTraversal.h"
#include "core/html/HTMLTableElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "platform/weborigin/Referrer.h"
namespace WebCore {
@@ -52,8 +53,11 @@ void HTMLTablePartElement::collectStyleForPresentationAttribute(const QualifiedN
addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
else if (name == backgroundAttr) {
String url = stripLeadingAndTrailingHTMLSpaces(value);
- if (!url.isEmpty())
- style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document().completeURL(url).string())));
+ if (!url.isEmpty()) {
+ RefPtrWillBeRawPtr<CSSImageValue> imageValue = CSSImageValue::create(url, document().completeURL(url));
+ imageValue->setReferrer(Referrer(document().outgoingReferrer(), document().referrerPolicy()));
+ style->setProperty(CSSProperty(CSSPropertyBackgroundImage, imageValue.release()));
+ }
} else if (name == valignAttr) {
if (equalIgnoringCase(value, "top"))
addPropertyToPresentationAttributeStyle(style, CSSPropertyVerticalAlign, CSSValueTop);
@@ -86,7 +90,7 @@ void HTMLTablePartElement::collectStyleForPresentationAttribute(const QualifiedN
HTMLTableElement* HTMLTablePartElement::findParentTable() const
{
ContainerNode* parent = NodeRenderingTraversal::parent(this);
- while (parent && !isHTMLTableElement(parent))
+ while (parent && !isHTMLTableElement(*parent))
parent = NodeRenderingTraversal::parent(parent);
return toHTMLTableElement(parent);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp
index b643924cf72..2aadf0ba3e3 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.cpp
@@ -25,8 +25,9 @@
#include "config.h"
#include "core/html/HTMLTableRowElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLTableCellElement.h"
@@ -37,15 +38,22 @@ namespace WebCore {
using namespace HTMLNames;
-HTMLTableRowElement::HTMLTableRowElement(Document& document)
+inline HTMLTableRowElement::HTMLTableRowElement(Document& document)
: HTMLTablePartElement(trTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableRowElement> HTMLTableRowElement::create(Document& document)
+DEFINE_NODE_FACTORY(HTMLTableRowElement)
+
+bool HTMLTableRowElement::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == backgroundAttr || HTMLTablePartElement::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& HTMLTableRowElement::subResourceAttributeName() const
{
- return adoptRef(new HTMLTableRowElement(document));
+ return backgroundAttr;
}
int HTMLTableRowElement::rowIndex() const
@@ -54,7 +62,7 @@ int HTMLTableRowElement::rowIndex() const
if (!table)
return -1;
table = table->parentNode();
- if (!table || !isHTMLTableElement(table))
+ if (!isHTMLTableElement(table))
return -1;
// To match Firefox, the row indices work like this:
@@ -65,32 +73,29 @@ int HTMLTableRowElement::rowIndex() const
int rIndex = 0;
if (HTMLTableSectionElement* head = toHTMLTableElement(table)->tHead()) {
- for (Node *row = head->firstChild(); row; row = row->nextSibling()) {
+ for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*head); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
if (row == this)
return rIndex;
- if (row->hasTagName(trTag))
- ++rIndex;
+ ++rIndex;
}
}
- for (Node *node = table->firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(tbodyTag)) {
- HTMLTableSectionElement* section = toHTMLTableSectionElement(node);
- for (Node* row = section->firstChild(); row; row = row->nextSibling()) {
+ for (Element* child = ElementTraversal::firstWithin(*table); child; child = ElementTraversal::nextSibling(*child)) {
+ if (child->hasTagName(tbodyTag)) {
+ HTMLTableSectionElement* section = toHTMLTableSectionElement(child);
+ for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*section); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
if (row == this)
return rIndex;
- if (row->hasTagName(trTag))
- ++rIndex;
+ ++rIndex;
}
}
}
if (HTMLTableSectionElement* foot = toHTMLTableElement(table)->tFoot()) {
- for (Node *row = foot->firstChild(); row; row = row->nextSibling()) {
+ for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*foot); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
if (row == this)
return rIndex;
- if (row->hasTagName(trTag))
- ++rIndex;
+ ++rIndex;
}
}
@@ -101,55 +106,54 @@ int HTMLTableRowElement::rowIndex() const
int HTMLTableRowElement::sectionRowIndex() const
{
int rIndex = 0;
- const Node *n = this;
+ const Node* n = this;
do {
n = n->previousSibling();
- if (n && n->hasTagName(trTag))
- rIndex++;
- }
- while (n);
+ if (n && isHTMLTableRowElement(*n))
+ ++rIndex;
+ } while (n);
return rIndex;
}
-PassRefPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableRowElement::insertCell(ExceptionState& exceptionState)
+{
+ // The default 'index' argument value is -1.
+ return insertCell(-1, exceptionState);
+}
+
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableRowElement::insertCell(int index, ExceptionState& exceptionState)
{
- RefPtr<HTMLCollection> children = cells();
+ RefPtrWillBeRawPtr<HTMLCollection> children = cells();
int numCells = children ? children->length() : 0;
if (index < -1 || index > numCells) {
exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [-1, " + String::number(numCells) + "].");
- return 0;
+ return nullptr;
}
- RefPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document());
- if (index < 0 || index >= numCells)
+ RefPtrWillBeRawPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document());
+ if (numCells == index || index == -1)
appendChild(cell, exceptionState);
- else {
- Node* n;
- if (index < 1)
- n = firstChild();
- else
- n = children->item(index);
- insertBefore(cell, n, exceptionState);
- }
+ else
+ insertBefore(cell, children->item(index), exceptionState);
return cell.release();
}
void HTMLTableRowElement::deleteCell(int index, ExceptionState& exceptionState)
{
- RefPtr<HTMLCollection> children = cells();
+ RefPtrWillBeRawPtr<HTMLCollection> children = cells();
int numCells = children ? children->length() : 0;
if (index == -1)
index = numCells-1;
if (index >= 0 && index < numCells) {
- RefPtr<Node> cell = children->item(index);
+ RefPtrWillBeRawPtr<Element> cell = children->item(index);
HTMLElement::removeChild(cell.get(), exceptionState);
} else {
exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [0, " + String::number(numCells) + ").");
}
}
-PassRefPtr<HTMLCollection> HTMLTableRowElement::cells()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLTableRowElement::cells()
{
return ensureCachedHTMLCollection(TRCells);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h
index 1fe3867218b..539856ef5d5 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.h
@@ -34,27 +34,24 @@ class ExceptionState;
class HTMLTableRowElement FINAL : public HTMLTablePartElement {
public:
- static PassRefPtr<HTMLTableRowElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTableRowElement);
int rowIndex() const;
int sectionRowIndex() const;
- PassRefPtr<HTMLElement> insertCell(int index, ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertCell(ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertCell(int index, ExceptionState&);
void deleteCell(int index, ExceptionState&);
- PassRefPtr<HTMLCollection> cells();
+ PassRefPtrWillBeRawPtr<HTMLCollection> cells();
private:
explicit HTMLTableRowElement(Document&);
-};
-
-inline bool isHTMLTableRowElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::trTag);
-}
-DEFINE_NODE_TYPE_CASTS(HTMLTableRowElement, hasTagName(HTMLNames::trTag));
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
+};
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
index aa7b9cae5bd..e38f999ef53 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowElement.idl
@@ -27,6 +27,6 @@ interface HTMLTableRowElement : HTMLElement {
[Reflect=char] attribute DOMString ch;
[Reflect=charoff] attribute DOMString chOff;
[Reflect] attribute DOMString vAlign;
- [RaisesException] HTMLElement insertCell([Default=Undefined] optional long index);
+ [RaisesException] HTMLElement insertCell(optional long index);
[RaisesException] void deleteCell([Default=Undefined] optional long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp
index 3037aff1c61..dbf5e04e827 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.cpp
@@ -29,7 +29,8 @@
#include "config.h"
#include "core/html/HTMLTableRowsCollection.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLTableElement.h"
#include "core/html/HTMLTableRowElement.h"
@@ -52,96 +53,81 @@ static bool isInFoot(Element* row)
return row->parentNode() && toElement(row->parentNode())->hasLocalName(tfootTag);
}
-HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table, HTMLTableRowElement* previous)
+HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement& table, HTMLTableRowElement* previous)
{
- Node* child = 0;
-
// Start by looking for the next row in this section.
// Continue only if there is none.
if (previous && previous->parentNode() != table) {
- for (child = previous->nextSibling(); child; child = child->nextSibling()) {
- if (isHTMLTableRowElement(child))
- return toHTMLTableRowElement(child);
- }
+ if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::nextSibling(*previous))
+ return row;
}
// If still looking at head sections, find the first row in the next head section.
+ HTMLElement* child = 0;
if (!previous)
- child = table->firstChild();
+ child = Traversal<HTMLElement>::firstChild(table);
else if (isInHead(previous))
- child = previous->parentNode()->nextSibling();
- for (; child; child = child->nextSibling()) {
- if (child->hasTagName(theadTag)) {
- for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ child = Traversal<HTMLElement>::nextSibling(*previous->parentNode());
+ for (; child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ if (child->hasLocalName(theadTag)) {
+ if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*child))
+ return row;
}
}
// If still looking at top level and bodies, find the next row in top level or the first in the next body section.
if (!previous || isInHead(previous))
- child = table->firstChild();
+ child = Traversal<HTMLElement>::firstChild(table);
else if (previous->parentNode() == table)
- child = previous->nextSibling();
+ child = Traversal<HTMLElement>::nextSibling(*previous);
else if (isInBody(previous))
- child = previous->parentNode()->nextSibling();
- for (; child; child = child->nextSibling()) {
+ child = Traversal<HTMLElement>::nextSibling(*previous->parentNode());
+ for (; child; child = Traversal<HTMLElement>::nextSibling(*child)) {
if (isHTMLTableRowElement(child))
return toHTMLTableRowElement(child);
- if (child->hasTagName(tbodyTag)) {
- for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ if (child->hasLocalName(tbodyTag)) {
+ if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*child))
+ return row;
}
}
// Find the first row in the next foot section.
if (!previous || !isInFoot(previous))
- child = table->firstChild();
+ child = Traversal<HTMLElement>::firstChild(table);
else
- child = previous->parentNode()->nextSibling();
- for (; child; child = child->nextSibling()) {
- if (child->hasTagName(tfootTag)) {
- for (Node* grandchild = child->firstChild(); grandchild; grandchild = grandchild->nextSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ child = Traversal<HTMLElement>::nextSibling(*previous->parentNode());
+ for (; child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+ if (child->hasLocalName(tfootTag)) {
+ if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*child))
+ return row;
}
}
return 0;
}
-HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
+HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement& table)
{
- for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
- if (child->hasTagName(tfootTag)) {
- for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ for (HTMLElement* child = Traversal<HTMLElement>::lastChild(table); child; child = Traversal<HTMLElement>::previousSibling(*child)) {
+ if (child->hasLocalName(tfootTag)) {
+ if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+ return lastRow;
}
}
- for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+ for (HTMLElement* child = Traversal<HTMLElement>::lastChild(table); child; child = Traversal<HTMLElement>::previousSibling(*child)) {
if (isHTMLTableRowElement(child))
return toHTMLTableRowElement(child);
- if (child->hasTagName(tbodyTag)) {
- for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ if (child->hasLocalName(tbodyTag)) {
+ if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+ return lastRow;
}
}
- for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
- if (child->hasTagName(theadTag)) {
- for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
- if (isHTMLTableRowElement(grandchild))
- return toHTMLTableRowElement(grandchild);
- }
+ for (HTMLElement* child = Traversal<HTMLElement>::lastChild(table); child; child = Traversal<HTMLElement>::previousSibling(*child)) {
+ if (child->hasLocalName(theadTag)) {
+ if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+ return lastRow;
}
}
@@ -151,20 +137,20 @@ HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
// Must call get() on the table in case that argument is compiled before dereferencing the
// table to get at the collection cache. Order of argument evaluation is undefined and can
// differ between compilers.
-HTMLTableRowsCollection::HTMLTableRowsCollection(Node* table)
+HTMLTableRowsCollection::HTMLTableRowsCollection(ContainerNode& table)
: HTMLCollection(table, TableRows, OverridesItemAfter)
{
ASSERT(isHTMLTableElement(table));
}
-PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(Node* table, CollectionType)
+PassRefPtrWillBeRawPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(ContainerNode& table, CollectionType type)
{
- return adoptRef(new HTMLTableRowsCollection(table));
+ ASSERT_UNUSED(type, type == TableRows);
+ return adoptRefWillBeNoop(new HTMLTableRowsCollection(table));
}
-Element* HTMLTableRowsCollection::virtualItemAfter(unsigned& offsetInArray, Element* previous) const
+Element* HTMLTableRowsCollection::virtualItemAfter(Element* previous) const
{
- ASSERT_UNUSED(offsetInArray, !offsetInArray);
return rowAfter(toHTMLTableElement(ownerNode()), toHTMLTableRowElement(previous));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h
index d643d430de4..653328e7305 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableRowsCollection.h
@@ -38,17 +38,19 @@ class HTMLTableRowElement;
class HTMLTableRowsCollection FINAL : public HTMLCollection {
public:
- static PassRefPtr<HTMLTableRowsCollection> create(Node*, CollectionType);
+ static PassRefPtrWillBeRawPtr<HTMLTableRowsCollection> create(ContainerNode&, CollectionType);
- static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
- static HTMLTableRowElement* lastRow(HTMLTableElement*);
+ static HTMLTableRowElement* rowAfter(HTMLTableElement&, HTMLTableRowElement*);
+ static HTMLTableRowElement* lastRow(HTMLTableElement&);
private:
- explicit HTMLTableRowsCollection(Node*);
+ explicit HTMLTableRowsCollection(ContainerNode&);
- virtual Element* virtualItemAfter(unsigned& offsetInArray, Element*) const OVERRIDE;
+ virtual Element* virtualItemAfter(Element*) const OVERRIDE;
};
+DEFINE_TYPE_CASTS(HTMLTableRowsCollection, LiveNodeListBase, collection, collection->type() == TableRows, collection.type() == TableRows);
+
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp
index 01ec777a27f..e4b42660287 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.cpp
@@ -25,8 +25,9 @@
#include "config.h"
#include "core/html/HTMLTableSectionElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/ExceptionCode.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLTableElement.h"
@@ -42,10 +43,7 @@ inline HTMLTableSectionElement::HTMLTableSectionElement(const QualifiedName& tag
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTableSectionElement> HTMLTableSectionElement::create(const QualifiedName& tagName, Document& document)
-{
- return adoptRef(new HTMLTableSectionElement(tagName, document));
-}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableSectionElement)
const StylePropertySet* HTMLTableSectionElement::additionalPresentationAttributeStyle()
{
@@ -54,99 +52,54 @@ const StylePropertySet* HTMLTableSectionElement::additionalPresentationAttribute
return 0;
}
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableSectionElement::insertRow(ExceptionState& exceptionState)
+{
+ // The default 'index' argument value is -1.
+ return insertRow(-1, exceptionState);
+}
+
// these functions are rather slow, since we need to get the row at
// the index... but they aren't used during usual HTML parsing anyway
-PassRefPtr<HTMLElement> HTMLTableSectionElement::insertRow(int index, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<HTMLElement> HTMLTableSectionElement::insertRow(int index, ExceptionState& exceptionState)
{
- RefPtr<HTMLTableRowElement> row;
- RefPtr<HTMLCollection> children = rows();
- int numRows = children ? (int)children->length() : 0;
- if (index < -1 || index > numRows)
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError); // per the DOM
- else {
- row = HTMLTableRowElement::create(document());
- if (numRows == index || index == -1)
- appendChild(row, exceptionState);
- else {
- Node* n;
- if (index < 1)
- n = firstChild();
- else
- n = children->item(index);
- insertBefore(row, n, exceptionState);
- }
+ RefPtrWillBeRawPtr<HTMLCollection> children = rows();
+ int numRows = children ? static_cast<int>(children->length()) : 0;
+ if (index < -1 || index > numRows) {
+ exceptionState.throwDOMException(IndexSizeError, "The provided index (" + String::number(index) + " is outside the range [-1, " + String::number(numRows) + "].");
+ return nullptr;
}
+
+ RefPtrWillBeRawPtr<HTMLTableRowElement> row = HTMLTableRowElement::create(document());
+ if (numRows == index || index == -1)
+ appendChild(row, exceptionState);
+ else
+ insertBefore(row, children->item(index), exceptionState);
return row.release();
}
void HTMLTableSectionElement::deleteRow(int index, ExceptionState& exceptionState)
{
- RefPtr<HTMLCollection> children = rows();
+ RefPtrWillBeRawPtr<HTMLCollection> children = rows();
int numRows = children ? (int)children->length() : 0;
if (index == -1)
index = numRows - 1;
if (index >= 0 && index < numRows) {
- RefPtr<Node> row = children->item(index);
+ RefPtrWillBeRawPtr<Element> row = children->item(index);
HTMLElement::removeChild(row.get(), exceptionState);
} else {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The provided index (" + String::number(index) + " is outside the range [-1, " + String::number(numRows) + "].");
}
}
int HTMLTableSectionElement::numRows() const
{
- int rows = 0;
- const Node *n = firstChild();
- while (n) {
- if (n->hasTagName(trTag))
- rows++;
- n = n->nextSibling();
- }
-
- return rows;
-}
-
-const AtomicString& HTMLTableSectionElement::align() const
-{
- return getAttribute(alignAttr);
-}
-
-void HTMLTableSectionElement::setAlign(const AtomicString& value)
-{
- setAttribute(alignAttr, value);
-}
-
-const AtomicString& HTMLTableSectionElement::ch() const
-{
- return getAttribute(charAttr);
-}
-
-void HTMLTableSectionElement::setCh(const AtomicString& value)
-{
- setAttribute(charAttr, value);
-}
-
-const AtomicString& HTMLTableSectionElement::chOff() const
-{
- return getAttribute(charoffAttr);
-}
-
-void HTMLTableSectionElement::setChOff(const AtomicString& value)
-{
- setAttribute(charoffAttr, value);
-}
-
-const AtomicString& HTMLTableSectionElement::vAlign() const
-{
- return getAttribute(valignAttr);
-}
-
-void HTMLTableSectionElement::setVAlign(const AtomicString& value)
-{
- setAttribute(valignAttr, value);
+ int rowCount = 0;
+ for (const HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*this); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row))
+ ++rowCount;
+ return rowCount;
}
-PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows()
+PassRefPtrWillBeRawPtr<HTMLCollection> HTMLTableSectionElement::rows()
{
return ensureCachedHTMLCollection(TSectionRows);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h
index 02d55167adb..4fa633b2b4c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.h
@@ -34,26 +34,15 @@ class ExceptionState;
class HTMLTableSectionElement FINAL : public HTMLTablePartElement {
public:
- static PassRefPtr<HTMLTableSectionElement> create(const QualifiedName&, Document&);
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableSectionElement);
- PassRefPtr<HTMLElement> insertRow(int index, ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertRow(ExceptionState&);
+ PassRefPtrWillBeRawPtr<HTMLElement> insertRow(int index, ExceptionState&);
void deleteRow(int index, ExceptionState&);
int numRows() const;
- const AtomicString& align() const;
- void setAlign(const AtomicString&);
-
- const AtomicString& ch() const;
- void setCh(const AtomicString&);
-
- const AtomicString& chOff() const;
- void setChOff(const AtomicString&);
-
- const AtomicString& vAlign() const;
- void setVAlign(const AtomicString&);
-
- PassRefPtr<HTMLCollection> rows();
+ PassRefPtrWillBeRawPtr<HTMLCollection> rows();
private:
HTMLTableSectionElement(const QualifiedName& tagName, Document&);
@@ -61,12 +50,17 @@ private:
virtual const StylePropertySet* additionalPresentationAttributeStyle() OVERRIDE;
};
-inline bool isHTMLTableSectionElement(const Node& node)
+inline bool isHTMLTableSectionElement(const Element& element)
+{
+ return element.hasTagName(HTMLNames::tbodyTag) || element.hasTagName(HTMLNames::tfootTag) || element.hasTagName(HTMLNames::theadTag);
+}
+
+inline bool isHTMLTableSectionElement(const HTMLElement& element)
{
- return node.hasTagName(HTMLNames::tbodyTag) || node.hasTagName(HTMLNames::tfootTag) || node.hasTagName(HTMLNames::theadTag);
+ return element.hasLocalName(HTMLNames::tbodyTag) || element.hasLocalName(HTMLNames::tfootTag) || element.hasLocalName(HTMLNames::theadTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableSectionElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableSectionElement);
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl
index 836b712c43e..a8f0b894191 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTableSectionElement.idl
@@ -24,6 +24,6 @@ interface HTMLTableSectionElement : HTMLElement {
[Reflect=charoff] attribute DOMString chOff;
[Reflect] attribute DOMString vAlign;
readonly attribute HTMLCollection rows;
- [RaisesException] HTMLElement insertRow([Default=Undefined] optional long index);
+ [RaisesException] HTMLElement insertRow(optional long index);
[RaisesException] void deleteRow([Default=Undefined] optional long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in b/chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in
index ee8c92f89f3..9e349119186 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTagNames.in
@@ -11,7 +11,7 @@ applet constructorNeedsCreatedByParser
area
article interfaceName=HTMLElement
aside interfaceName=HTMLElement
-audio runtimeEnabled=media, constructorNeedsCreatedByParser
+audio runtimeEnabled=media
b interfaceName=HTMLElement
base
basefont interfaceName=HTMLElement
@@ -66,10 +66,9 @@ html
i interfaceName=HTMLElement
iframe interfaceName=HTMLIFrameElement
image interfaceName=HTMLUnknownElement
-img interfaceName=HTMLImageElement, constructorNeedsFormElement
+img interfaceName=HTMLImageElement, constructorNeedsFormElement, constructorNeedsCreatedByParser
input constructorNeedsFormElement, constructorNeedsCreatedByParser
ins interfaceName=HTMLModElement
-isindex interfaceName=HTMLUnknownElement
kbd interfaceName=HTMLElement
keygen constructorNeedsFormElement
label
@@ -87,7 +86,7 @@ meta
meter interfaceName=HTMLMeterElement
nav interfaceName=HTMLElement
nobr interfaceName=HTMLElement
-noembed interfaceName=HTMLElement
+noembed interfaceName=HTMLNoEmbedElement, JSInterfaceName=HTMLElement
noframes interfaceName=HTMLElement
nolayer interfaceName=HTMLElement
object constructorNeedsFormElement, constructorNeedsCreatedByParser
@@ -98,18 +97,19 @@ output constructorNeedsFormElement
shadow interfaceName=HTMLShadowElement
p interfaceName=HTMLParagraphElement
param
+picture interfaceName=HTMLPictureElement, runtimeEnabled=picture
plaintext interfaceName=HTMLElement
pre
progress interfaceName=HTMLProgressElement
q interfaceName=HTMLQuoteElement
rp interfaceName=HTMLElement
-rt interfaceName=HTMLElement
-ruby interfaceName=HTMLElement
+rt interfaceName=HTMLRTElement, JSInterfaceName=HTMLElement
+ruby interfaceName=HTMLRubyElement, JSInterfaceName=HTMLElement
s interfaceName=HTMLElement
samp interfaceName=HTMLElement
script constructorNeedsCreatedByParser
section interfaceName=HTMLElement
-select constructorNeedsFormElement, constructorNeedsCreatedByParser
+select constructorNeedsFormElement
small interfaceName=HTMLElement
source runtimeEnabled=media
span
@@ -129,12 +129,12 @@ th interfaceName=HTMLTableCellElement
thead interfaceName=HTMLTableSectionElement
title
tr interfaceName=HTMLTableRowElement
-track runtimeEnabled=videoTrack
+track
tt interfaceName=HTMLElement
u interfaceName=HTMLElement
ul interfaceName=HTMLUListElement
var interfaceName=HTMLElement
-video runtimeEnabled=media, constructorNeedsCreatedByParser
-wbr interfaceName=HTMLElement
+video runtimeEnabled=media
+wbr interfaceName=HTMLWBRElement, JSInterfaceName=HTMLElement
xmp interfaceName=HTMLPreElement
-noscript interfaceName=HTMLElement
+noscript interfaceName=HTMLNoScriptElement, JSInterfaceName=HTMLElement
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp
index 2990838c707..3d24f522f91 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.cpp
@@ -32,6 +32,7 @@
#include "core/html/HTMLTemplateElement.h"
+#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/TemplateContentDocumentFragment.h"
@@ -45,15 +46,14 @@ inline HTMLTemplateElement::HTMLTemplateElement(Document& document)
ScriptWrappable::init(this);
}
+DEFINE_NODE_FACTORY(HTMLTemplateElement)
+
HTMLTemplateElement::~HTMLTemplateElement()
{
+#if !ENABLE(OILPAN)
if (m_content)
m_content->clearHost();
-}
-
-PassRefPtr<HTMLTemplateElement> HTMLTemplateElement::create(Document& document)
-{
- return adoptRef(new HTMLTemplateElement(document));
+#endif
}
DocumentFragment* HTMLTemplateElement::content() const
@@ -64,12 +64,12 @@ DocumentFragment* HTMLTemplateElement::content() const
return m_content.get();
}
-PassRefPtr<Node> HTMLTemplateElement::cloneNode(bool deep)
+PassRefPtrWillBeRawPtr<Node> HTMLTemplateElement::cloneNode(bool deep)
{
if (!deep)
return cloneElementWithoutChildren();
- RefPtr<Node> clone = cloneElementWithChildren();
+ RefPtrWillBeRawPtr<Node> clone = cloneElementWithChildren();
if (m_content)
content()->cloneChildNodes(toHTMLTemplateElement(clone.get())->content());
return clone.release();
@@ -83,4 +83,10 @@ void HTMLTemplateElement::didMoveToNewDocument(Document& oldDocument)
document().ensureTemplateDocument().adoptIfNeeded(*m_content);
}
+void HTMLTemplateElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_content);
+ HTMLElement::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
index b27958dafb1..78467973f94 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTemplateElement.h
@@ -40,22 +40,21 @@ class TemplateContentDocumentFragment;
class HTMLTemplateElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTemplateElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTemplateElement);
virtual ~HTMLTemplateElement();
+ virtual void trace(Visitor*) OVERRIDE;
DocumentFragment* content() const;
private:
- virtual PassRefPtr<Node> cloneNode(bool deep = true) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Node> cloneNode(bool deep = true) OVERRIDE;
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
explicit HTMLTemplateElement(Document&);
- mutable RefPtr<TemplateContentDocumentFragment> m_content;
+ mutable RefPtrWillBeMember<TemplateContentDocumentFragment> m_content;
};
-DEFINE_NODE_TYPE_CASTS(HTMLTemplateElement, hasTagName(HTMLNames::templateTag));
-
} // namespace WebCore
#endif // HTMLTemplateElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
index ca7494e2af6..5b4fde76b34 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.cpp
@@ -26,10 +26,10 @@
#include "config.h"
#include "core/html/HTMLTextAreaElement.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/Text.h"
@@ -39,12 +39,14 @@
#include "core/editing/TextIterator.h"
#include "core/events/BeforeTextInsertedEvent.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/FormDataList.h"
#include "core/html/forms/FormController.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/html/shadow/TextControlInnerElements.h"
-#include "core/frame/Frame.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
#include "core/rendering/RenderTextControlMultiLine.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/StdLibExtras.h"
@@ -81,21 +83,21 @@ HTMLTextAreaElement::HTMLTextAreaElement(Document& document, HTMLFormElement* fo
, m_cols(defaultCols)
, m_wrap(SoftWrap)
, m_isDirty(false)
+ , m_valueIsUpToDate(true)
{
- setFormControlValueMatchesRenderer(true);
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(Document& document, HTMLFormElement* form)
+PassRefPtrWillBeRawPtr<HTMLTextAreaElement> HTMLTextAreaElement::create(Document& document, HTMLFormElement* form)
{
- RefPtr<HTMLTextAreaElement> textArea = adoptRef(new HTMLTextAreaElement(document, form));
+ RefPtrWillBeRawPtr<HTMLTextAreaElement> textArea = adoptRefWillBeNoop(new HTMLTextAreaElement(document, form));
textArea->ensureUserAgentShadowRoot();
return textArea.release();
}
void HTMLTextAreaElement::didAddUserAgentShadowRoot(ShadowRoot& root)
{
- root.appendChild(TextControlInnerTextElement::create(document()));
+ root.appendChild(TextControlInnerEditorElement::create(document()));
}
const AtomicString& HTMLTextAreaElement::formControlType() const
@@ -119,7 +121,7 @@ void HTMLTextAreaElement::childrenChanged(bool changedByParser, Node* beforeChan
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
setLastChangeWasNotUserEdit();
if (m_isDirty)
- setInnerTextValue(value());
+ setInnerEditorValue(value());
else
setNonDirtyValue(defaultValue());
}
@@ -160,7 +162,7 @@ void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const Atomic
if (m_rows != rows) {
m_rows = rows;
if (renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
} else if (name == colsAttr) {
int cols = value.toInt();
@@ -169,7 +171,7 @@ void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const Atomic
if (m_cols != cols) {
m_cols = cols;
if (renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
} else if (name == wrapAttr) {
// The virtual/physical values were a Netscape extension of HTML 3.0, now deprecated.
@@ -184,7 +186,7 @@ void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const Atomic
if (wrap != m_wrap) {
m_wrap = wrap;
if (renderer())
- renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
} else if (name == accesskeyAttr) {
// ignore for the moment
@@ -238,12 +240,9 @@ bool HTMLTextAreaElement::shouldShowFocusRingOnMouseFocus() const
void HTMLTextAreaElement::updateFocusAppearance(bool restorePreviousSelection)
{
- if (!restorePreviousSelection || !hasCachedSelection()) {
- // If this is the first focus, set a caret at the beginning of the text.
- // This matches some browsers' behavior; see bug 11746 Comment #15.
- // http://bugs.webkit.org/show_bug.cgi?id=11746#c15
+ if (!restorePreviousSelection)
setSelectionRange(0, 0);
- } else
+ else
restoreCachedSelection();
if (document().frame())
@@ -260,16 +259,16 @@ void HTMLTextAreaElement::defaultEventHandler(Event* event)
HTMLTextFormControlElement::defaultEventHandler(event);
}
-void HTMLTextAreaElement::handleFocusEvent(Element*, FocusDirection)
+void HTMLTextAreaElement::handleFocusEvent(Element*, FocusType)
{
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->spellChecker().didBeginEditing(this);
}
void HTMLTextAreaElement::subtreeHasChanged()
{
setChangedSinceLastFormControlChangeEvent(true);
- setFormControlValueMatchesRenderer(false);
+ m_valueIsUpToDate = false;
setNeedsValidityCheck();
if (!focused())
@@ -277,6 +276,9 @@ void HTMLTextAreaElement::subtreeHasChanged()
// When typing in a textarea, childrenChanged is not called, so we need to force the directionality check.
calculateAndAdjustDirectionality();
+
+ ASSERT(document().isActive());
+ document().frameHost()->chrome().client().didChangeValueInTextField(*this);
}
void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const
@@ -288,7 +290,7 @@ void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
return;
unsigned unsignedMaxLength = static_cast<unsigned>(signedMaxLength);
- const String& currentValue = innerTextValue();
+ const String& currentValue = innerEditorValue();
unsigned currentLength = computeLengthForSubmission(currentValue);
if (currentLength + computeLengthForSubmission(event->text()) < unsignedMaxLength)
return;
@@ -312,19 +314,14 @@ String HTMLTextAreaElement::sanitizeUserInputValue(const String& proposedValue,
return proposedValue.left(maxLength);
}
-void HTMLTextAreaElement::rendererWillBeDestroyed()
-{
- updateValue();
-}
-
void HTMLTextAreaElement::updateValue() const
{
- if (formControlValueMatchesRenderer())
+ if (m_valueIsUpToDate)
return;
ASSERT(renderer());
- m_value = innerTextValue();
- const_cast<HTMLTextAreaElement*>(this)->setFormControlValueMatchesRenderer(true);
+ m_value = innerEditorValue();
+ const_cast<HTMLTextAreaElement*>(this)->m_valueIsUpToDate = true;
const_cast<HTMLTextAreaElement*>(this)->notifyFormStateChanged();
m_isDirty = true;
const_cast<HTMLTextAreaElement*>(this)->updatePlaceholderVisibility(false);
@@ -336,21 +333,24 @@ String HTMLTextAreaElement::value() const
return m_value;
}
-void HTMLTextAreaElement::setValue(const String& value)
+void HTMLTextAreaElement::setValue(const String& value, TextFieldEventBehavior eventBehavior)
{
- setValueCommon(value);
+ RefPtrWillBeRawPtr<HTMLTextAreaElement> protector(this);
+ setValueCommon(value, eventBehavior);
m_isDirty = true;
setNeedsValidityCheck();
+ if (document().focusedElement() == this)
+ document().frameHost()->chrome().client().didUpdateTextOfFocusedElementByNonUserInput();
}
void HTMLTextAreaElement::setNonDirtyValue(const String& value)
{
- setValueCommon(value);
+ setValueCommon(value, DispatchNoEvent);
m_isDirty = false;
setNeedsValidityCheck();
}
-void HTMLTextAreaElement::setValueCommon(const String& newValue)
+void HTMLTextAreaElement::setValueCommon(const String& newValue, TextFieldEventBehavior eventBehavior)
{
// Code elsewhere normalizes line endings added by the user via the keyboard or pasting.
// We normalize line endings coming from JavaScript here.
@@ -364,11 +364,12 @@ void HTMLTextAreaElement::setValueCommon(const String& newValue)
return;
m_value = normalizedValue;
- setInnerTextValue(m_value);
- setLastChangeWasNotUserEdit();
+ setInnerEditorValue(m_value);
+ if (eventBehavior == DispatchNoEvent)
+ setLastChangeWasNotUserEdit();
updatePlaceholderVisibility(false);
- setNeedsStyleRecalc();
- setFormControlValueMatchesRenderer(true);
+ setNeedsStyleRecalc(SubtreeStyleChange);
+ m_suggestedValue = String();
// Set the caret to the end of the text value.
if (document().focusedElement() == this) {
@@ -377,7 +378,19 @@ void HTMLTextAreaElement::setValueCommon(const String& newValue)
}
notifyFormStateChanged();
- setTextAsOfLastFormControlChangeEvent(normalizedValue);
+ if (eventBehavior == DispatchNoEvent) {
+ setTextAsOfLastFormControlChangeEvent(normalizedValue);
+ } else {
+ if (eventBehavior == DispatchInputAndChangeEvent)
+ dispatchFormControlInputEvent();
+ dispatchFormControlChangeEvent();
+ }
+}
+
+void HTMLTextAreaElement::setInnerEditorValue(const String& value)
+{
+ HTMLTextFormControlElement::setInnerEditorValue(value);
+ m_valueIsUpToDate = true;
}
String HTMLTextAreaElement::defaultValue() const
@@ -395,10 +408,10 @@ String HTMLTextAreaElement::defaultValue() const
void HTMLTextAreaElement::setDefaultValue(const String& defaultValue)
{
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
// To preserve comments, remove only the text nodes, then add a single text node.
- Vector<RefPtr<Node> > textNodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > textNodes;
for (Node* n = firstChild(); n; n = n->nextSibling()) {
if (n->isTextNode())
textNodes.append(n);
@@ -433,6 +446,23 @@ void HTMLTextAreaElement::setMaxLength(int newValue, ExceptionState& exceptionSt
setIntegralAttribute(maxlengthAttr, newValue);
}
+String HTMLTextAreaElement::suggestedValue() const
+{
+ return m_suggestedValue;
+}
+
+void HTMLTextAreaElement::setSuggestedValue(const String& value)
+{
+ m_suggestedValue = value;
+
+ if (!value.isNull())
+ setInnerEditorValue(m_suggestedValue);
+ else
+ setInnerEditorValue(m_value);
+ updatePlaceholderVisibility(false);
+ setNeedsStyleRecalc(SubtreeStyleChange);
+}
+
String HTMLTextAreaElement::validationMessage() const
{
if (!willValidate())
@@ -511,18 +541,18 @@ bool HTMLTextAreaElement::matchesReadWritePseudoClass() const
void HTMLTextAreaElement::updatePlaceholderText()
{
HTMLElement* placeholder = placeholderElement();
- String placeholderText = strippedPlaceholder();
+ const AtomicString& placeholderText = fastGetAttribute(placeholderAttr);
if (placeholderText.isEmpty()) {
if (placeholder)
userAgentShadowRoot()->removeChild(placeholder);
return;
}
if (!placeholder) {
- RefPtr<HTMLDivElement> newElement = HTMLDivElement::create(document());
+ RefPtrWillBeRawPtr<HTMLDivElement> newElement = HTMLDivElement::create(document());
placeholder = newElement.get();
- placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
+ placeholder->setShadowPseudoId(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
placeholder->setAttribute(idAttr, ShadowElementNames::placeholder());
- userAgentShadowRoot()->insertBefore(placeholder, innerTextElement()->nextSibling());
+ userAgentShadowRoot()->insertBefore(placeholder, innerEditorElement()->nextSibling());
}
placeholder->setTextContent(placeholderText);
}
@@ -532,4 +562,9 @@ bool HTMLTextAreaElement::isInteractiveContent() const
return true;
}
+bool HTMLTextAreaElement::supportsAutofocus() const
+{
+ return true;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
index a5693348c08..57b3b4e52b8 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.h
@@ -34,28 +34,30 @@ class VisibleSelection;
class HTMLTextAreaElement FINAL : public HTMLTextFormControlElement {
public:
- static PassRefPtr<HTMLTextAreaElement> create(Document&, HTMLFormElement*);
+ static PassRefPtrWillBeRawPtr<HTMLTextAreaElement> create(Document&, HTMLFormElement*);
int cols() const { return m_cols; }
int rows() const { return m_rows; }
bool shouldWrapText() const { return m_wrap != NoWrap; }
- virtual String value() const;
- void setValue(const String&);
+ virtual String value() const OVERRIDE;
+ void setValue(const String&, TextFieldEventBehavior = DispatchNoEvent);
String defaultValue() const;
void setDefaultValue(const String&);
int textLength() const { return value().length(); }
- virtual int maxLength() const;
+ int maxLength() const;
void setMaxLength(int, ExceptionState&);
+
+ String suggestedValue() const;
+ void setSuggestedValue(const String&);
+
// For ValidityState
virtual String validationMessage() const OVERRIDE;
virtual bool valueMissing() const OVERRIDE;
virtual bool tooLong() const OVERRIDE;
bool isValidValue(const String&) const;
- void rendererWillBeDestroyed();
-
void setCols(int);
void setRows(int);
@@ -72,47 +74,50 @@ private:
void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) const;
static String sanitizeUserInputValue(const String&, unsigned maxLength);
void updateValue() const;
+ virtual void setInnerEditorValue(const String&) OVERRIDE;
void setNonDirtyValue(const String&);
- void setValueCommon(const String&);
+ void setValueCommon(const String&, TextFieldEventBehavior);
- virtual bool supportsPlaceholder() const { return true; }
- virtual void updatePlaceholderText();
- virtual bool isEmptyValue() const { return value().isEmpty(); }
+ virtual bool supportsPlaceholder() const OVERRIDE { return true; }
+ virtual void updatePlaceholderText() OVERRIDE;
+ virtual bool isEmptyValue() const OVERRIDE { return value().isEmpty(); }
+ virtual bool isEmptySuggestedValue() const OVERRIDE FINAL { return suggestedValue().isEmpty(); }
- virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
- virtual bool isRequiredFormControl() const { return isRequired(); }
+ virtual bool isOptionalFormControl() const OVERRIDE { return !isRequiredFormControl(); }
+ virtual bool isRequiredFormControl() const OVERRIDE { return isRequired(); }
- virtual void defaultEventHandler(Event*);
- virtual void handleFocusEvent(Element* oldFocusedNode, FocusDirection) OVERRIDE;
+ virtual void defaultEventHandler(Event*) OVERRIDE;
+ virtual void handleFocusEvent(Element* oldFocusedNode, FocusType) OVERRIDE;
- virtual void subtreeHasChanged();
+ virtual void subtreeHasChanged() OVERRIDE;
- virtual bool isEnumeratable() const { return true; }
+ virtual bool isEnumeratable() const OVERRIDE { return true; }
virtual bool isInteractiveContent() const OVERRIDE;
+ virtual bool supportsAutofocus() const OVERRIDE;
virtual bool supportLabels() const OVERRIDE { return true; }
- virtual const AtomicString& formControlType() const;
+ virtual const AtomicString& formControlType() const OVERRIDE;
virtual FormControlState saveFormControlState() const OVERRIDE;
virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
- virtual bool isTextFormControl() const { return true; }
+ virtual bool isTextFormControl() const OVERRIDE { return true; }
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool appendFormData(FormDataList&, bool);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool appendFormData(FormDataList&, bool) OVERRIDE;
virtual void resetImpl() OVERRIDE;
virtual bool hasCustomFocusLogic() const OVERRIDE;
virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual void updateFocusAppearance(bool restorePreviousSelection);
+ virtual void updateFocusAppearance(bool restorePreviousSelection) OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents);
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
- virtual bool shouldUseInputMethod();
+ virtual bool shouldUseInputMethod() OVERRIDE;
virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
virtual bool matchesReadWritePseudoClass() const OVERRIDE;
@@ -124,20 +129,10 @@ private:
WrapMethod m_wrap;
mutable String m_value;
mutable bool m_isDirty;
+ bool m_valueIsUpToDate;
+ String m_suggestedValue;
};
-inline bool isHTMLTextAreaElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::textareaTag);
-}
-
-inline bool isHTMLTextAreaElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::textareaTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLTextAreaElement, hasTagName(HTMLNames::textareaTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl
index e5d79264392..937c8c94193 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextAreaElement.idl
@@ -56,7 +56,7 @@ interface HTMLTextAreaElement : HTMLElement {
[RaisesException] void setRangeText(DOMString replacement,
unsigned long start,
unsigned long end,
- [Default=NullString] optional DOMString selectionMode);
+ optional DOMString selectionMode = null);
void setSelectionRange([Default=Undefined] optional long start,
[Default=Undefined] optional long end,
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
index d4b83cb03d8..06a5579087d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp
@@ -25,9 +25,9 @@
#include "config.h"
#include "core/html/HTMLTextFormControlElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Document.h"
#include "core/dom/NodeTraversal.h"
@@ -36,25 +36,24 @@
#include "core/editing/FrameSelection.h"
#include "core/editing/TextIterator.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLBRElement.h"
#include "core/html/shadow/ShadowElementNames.h"
-#include "core/frame/Frame.h"
-#include "core/frame/UseCounter.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderTheme.h"
+#include "platform/heap/Handle.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
using namespace HTMLNames;
-using namespace std;
HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagName, Document& doc, HTMLFormElement* form)
: HTMLFormControlElementWithState(tagName, doc, form)
, m_lastChangeWasUserEdit(false)
- , m_cachedSelectionStart(-1)
- , m_cachedSelectionEnd(-1)
+ , m_cachedSelectionStart(0)
+ , m_cachedSelectionEnd(0)
, m_cachedSelectionDirection(SelectionHasNoDirection)
{
}
@@ -73,12 +72,12 @@ Node::InsertionNotificationRequest HTMLTextFormControlElement::insertedInto(Cont
return InsertionDone;
}
-void HTMLTextFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void HTMLTextFormControlElement::dispatchFocusEvent(Element* oldFocusedElement, FocusType type)
{
if (supportsPlaceholder())
updatePlaceholderVisibility(false);
- handleFocusEvent(oldFocusedElement, direction);
- HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, direction);
+ handleFocusEvent(oldFocusedElement, type);
+ HTMLFormControlElementWithState::dispatchFocusEvent(oldFocusedElement, type);
}
void HTMLTextFormControlElement::dispatchBlurEvent(Element* newFocusedElement)
@@ -104,7 +103,7 @@ void HTMLTextFormControlElement::forwardEvent(Event* event)
{
if (event->type() == EventTypeNames::blur || event->type() == EventTypeNames::focus)
return;
- innerTextElement()->defaultEventHandler(event);
+ innerEditorElement()->defaultEventHandler(event);
}
String HTMLTextFormControlElement::strippedPlaceholder() const
@@ -164,12 +163,12 @@ void HTMLTextFormControlElement::updatePlaceholderVisibility(bool placeholderVal
void HTMLTextFormControlElement::setSelectionStart(int start)
{
- setSelectionRange(start, max(start, selectionEnd()), selectionDirection());
+ setSelectionRange(start, std::max(start, selectionEnd()), selectionDirection());
}
void HTMLTextFormControlElement::setSelectionEnd(int end)
{
- setSelectionRange(min(end, selectionStart()), end, selectionDirection());
+ setSelectionRange(std::min(end, selectionStart()), end, selectionDirection());
}
void HTMLTextFormControlElement::setSelectionDirection(const String& direction)
@@ -179,21 +178,20 @@ void HTMLTextFormControlElement::setSelectionDirection(const String& direction)
void HTMLTextFormControlElement::select()
{
- setSelectionRange(0, numeric_limits<int>::max(), SelectionHasNoDirection);
+ setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirection);
}
-String HTMLTextFormControlElement::selectedText() const
+bool HTMLTextFormControlElement::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
{
- if (!isTextFormControl())
- return String();
- return value().substring(selectionStart(), selectionEnd() - selectionStart());
+ return !equalIgnoringNullity(oldValue, newValue);
}
void HTMLTextFormControlElement::dispatchFormControlChangeEvent()
{
- if (m_textAsOfLastFormControlChangeEvent != value()) {
- HTMLElement::dispatchChangeEvent();
- setTextAsOfLastFormControlChangeEvent(value());
+ String newValue = value();
+ if (shouldDispatchFormControlChangeEvent(m_textAsOfLastFormControlChangeEvent, newValue)) {
+ setTextAsOfLastFormControlChangeEvent(newValue);
+ dispatchChangeEvent();
}
setChangedSinceLastFormControlChangeEvent(false);
}
@@ -216,8 +214,10 @@ void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne
exceptionState.throwDOMException(IndexSizeError, "The provided start value (" + String::number(start) + ") is larger than the provided end value (" + String::number(end) + ").");
return;
}
+ if (hasAuthorShadowRoot())
+ return;
- String text = innerTextValue();
+ String text = innerEditorValue();
unsigned textLength = text.length();
unsigned replacementLength = replacement.length();
unsigned newSelectionStart = selectionStart();
@@ -231,7 +231,7 @@ void HTMLTextFormControlElement::setRangeText(const String& replacement, unsigne
else
text.insert(replacement, start);
- setInnerTextValue(text);
+ setInnerEditorValue(text);
// FIXME: What should happen to the value (as in value()) if there's no renderer?
if (!renderer())
@@ -282,10 +282,10 @@ void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
if (!renderer() || !renderer()->isTextControl())
return;
- end = max(end, 0);
- start = min(max(start, 0), end);
+ end = std::max(end, 0);
+ start = std::min(std::max(start, 0), end);
- if (!hasVisibleTextArea(renderer(), innerTextElement())) {
+ if (!hasVisibleTextArea(renderer(), innerEditorElement())) {
cacheSelection(start, end, direction);
return;
}
@@ -309,16 +309,16 @@ void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
newSelection = VisibleSelection(startPosition, endPosition);
newSelection.setIsDirectional(direction != SelectionHasNoDirection);
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->selection().setSelection(newSelection);
}
VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) const
{
if (index <= 0)
- return VisiblePosition(firstPositionInNode(innerTextElement()), DOWNSTREAM);
- RefPtr<Range> range = Range::create(document());
- range->selectNodeContents(innerTextElement(), ASSERT_NO_EXCEPTION);
+ return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNSTREAM);
+ RefPtrWillBeRawPtr<Range> range = Range::create(document());
+ range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION);
CharacterIterator it(range.get());
it.advance(index - 1);
return VisiblePosition(it.range()->endPosition(), UPSTREAM);
@@ -330,8 +330,8 @@ int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& p
if (enclosingTextFormControl(indexPosition) != this)
return 0;
ASSERT(indexPosition.document());
- RefPtr<Range> range = Range::create(*indexPosition.document());
- range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION);
+ RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document());
+ range->setStart(innerEditorElement(), 0, ASSERT_NO_EXCEPTION);
range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainerNode(), ASSERT_NO_EXCEPTION);
return TextIterator::rangeLength(range.get());
}
@@ -340,7 +340,7 @@ int HTMLTextFormControlElement::selectionStart() const
{
if (!isTextFormControl())
return 0;
- if (document().focusedElement() != this && hasCachedSelection())
+ if (document().focusedElement() != this)
return m_cachedSelectionStart;
return computeSelectionStart();
@@ -349,18 +349,18 @@ int HTMLTextFormControlElement::selectionStart() const
int HTMLTextFormControlElement::computeSelectionStart() const
{
ASSERT(isTextFormControl());
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return 0;
- return indexForVisiblePosition(frame->selection().start());
+ return indexForVisiblePosition(VisiblePosition(frame->selection().start()));
}
int HTMLTextFormControlElement::selectionEnd() const
{
if (!isTextFormControl())
return 0;
- if (document().focusedElement() != this && hasCachedSelection())
+ if (document().focusedElement() != this)
return m_cachedSelectionEnd;
return computeSelectionEnd();
}
@@ -368,11 +368,11 @@ int HTMLTextFormControlElement::selectionEnd() const
int HTMLTextFormControlElement::computeSelectionEnd() const
{
ASSERT(isTextFormControl());
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return 0;
- return indexForVisiblePosition(frame->selection().end());
+ return indexForVisiblePosition(VisiblePosition(frame->selection().end()));
}
static const AtomicString& directionString(TextFieldSelectionDirection direction)
@@ -398,7 +398,7 @@ const AtomicString& HTMLTextFormControlElement::selectionDirection() const
{
if (!isTextFormControl())
return directionString(SelectionHasNoDirection);
- if (document().focusedElement() != this && hasCachedSelection())
+ if (document().focusedElement() != this)
return directionString(m_cachedSelectionDirection);
return directionString(computeSelectionDirection());
@@ -407,7 +407,7 @@ const AtomicString& HTMLTextFormControlElement::selectionDirection() const
TextFieldSelectionDirection HTMLTextFormControlElement::computeSelectionDirection() const
{
ASSERT(isTextFormControl());
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return SelectionHasNoDirection;
@@ -426,18 +426,18 @@ static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*&
}
}
-PassRefPtr<Range> HTMLTextFormControlElement::selection() const
+PassRefPtrWillBeRawPtr<Range> HTMLTextFormControlElement::selection() const
{
- if (!renderer() || !isTextFormControl() || !hasCachedSelection())
- return 0;
+ if (!renderer() || !isTextFormControl())
+ return nullptr;
int start = m_cachedSelectionStart;
int end = m_cachedSelectionEnd;
ASSERT(start <= end);
- HTMLElement* innerText = innerTextElement();
+ HTMLElement* innerText = innerEditorElement();
if (!innerText)
- return 0;
+ return nullptr;
if (!innerText->firstChild())
return Range::create(document(), innerText, 0, innerText, 0);
@@ -447,7 +447,7 @@ PassRefPtr<Range> HTMLTextFormControlElement::selection() const
Node* endNode = 0;
for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
ASSERT(!node->firstChild());
- ASSERT(node->isTextNode() || node->hasTagName(brTag));
+ ASSERT(node->isTextNode() || isHTMLBRElement(*node));
int length = node->isTextNode() ? lastOffsetInNode(node) : 1;
if (offset <= start && start <= offset + length)
@@ -462,7 +462,7 @@ PassRefPtr<Range> HTMLTextFormControlElement::selection() const
}
if (!startNode || !endNode)
- return 0;
+ return nullptr;
return Range::create(document(), startNode, start, endNode, end);
}
@@ -480,7 +480,7 @@ void HTMLTextFormControlElement::selectionChanged(bool userTriggered)
// selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus
cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelectionDirection());
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
if (frame->selection().isRange() && userTriggered)
dispatchEvent(Event::createBubble(EventTypeNames::select));
}
@@ -502,24 +502,23 @@ bool HTMLTextFormControlElement::lastChangeWasUserEdit() const
return m_lastChangeWasUserEdit;
}
-void HTMLTextFormControlElement::setInnerTextValue(const String& value)
+void HTMLTextFormControlElement::setInnerEditorValue(const String& value)
{
- if (!isTextFormControl())
+ ASSERT(!hasAuthorShadowRoot());
+ if (!isTextFormControl() || hasAuthorShadowRoot())
return;
- bool textIsChanged = value != innerTextValue();
- if (textIsChanged || !innerTextElement()->hasChildNodes()) {
+ bool textIsChanged = value != innerEditorValue();
+ if (textIsChanged || !innerEditorElement()->hasChildren()) {
if (textIsChanged && renderer()) {
if (AXObjectCache* cache = document().existingAXObjectCache())
cache->postNotification(this, AXObjectCache::AXValueChanged, false);
}
- innerTextElement()->setInnerText(value, ASSERT_NO_EXCEPTION);
+ innerEditorElement()->setInnerText(value, ASSERT_NO_EXCEPTION);
if (value.endsWith('\n') || value.endsWith('\r'))
- innerTextElement()->appendChild(HTMLBRElement::create(document()));
+ innerEditorElement()->appendChild(HTMLBRElement::create(document()));
}
-
- setFormControlValueMatchesRenderer(true);
}
static String finishText(StringBuilder& result)
@@ -531,15 +530,16 @@ static String finishText(StringBuilder& result)
return result.toString();
}
-String HTMLTextFormControlElement::innerTextValue() const
+String HTMLTextFormControlElement::innerEditorValue() const
{
- HTMLElement* innerText = innerTextElement();
- if (!innerText || !isTextFormControl())
+ ASSERT(!hasAuthorShadowRoot());
+ HTMLElement* innerEditor = innerEditorElement();
+ if (!innerEditor || !isTextFormControl())
return emptyString();
StringBuilder result;
- for (Node* node = innerText; node; node = NodeTraversal::next(*node, innerText)) {
- if (node->hasTagName(brTag))
+ for (Node* node = innerEditor; node; node = NodeTraversal::next(*node, innerEditor)) {
+ if (isHTMLBRElement(*node))
result.append(newlineCharacter);
else if (node->isTextNode())
result.append(toText(node)->data());
@@ -568,7 +568,7 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const
{
// FIXME: It's not acceptable to ignore the HardWrap setting when there is no renderer.
// While we have no evidence this has ever been a practical problem, it would be best to fix it some day.
- HTMLElement* innerText = innerTextElement();
+ HTMLElement* innerText = innerEditorElement();
if (!innerText || !isTextFormControl())
return value();
@@ -586,7 +586,7 @@ String HTMLTextFormControlElement::valueWithHardLineBreaks() const
StringBuilder result;
for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
- if (node->hasTagName(brTag))
+ if (isHTMLBRElement(*node))
result.append(newlineCharacter);
else if (node->isTextNode()) {
String data = toText(node)->data();
@@ -613,12 +613,15 @@ HTMLTextFormControlElement* enclosingTextFormControl(const Position& position)
ASSERT(position.isNull() || position.anchorType() == Position::PositionIsOffsetInAnchor
|| position.containerNode() || !position.anchorNode()->shadowHost()
|| (position.anchorNode()->parentNode() && position.anchorNode()->parentNode()->isShadowRoot()));
+ return enclosingTextFormControl(position.containerNode());
+}
- Node* container = position.containerNode();
+HTMLTextFormControlElement* enclosingTextFormControl(Node* container)
+{
if (!container)
return 0;
Element* ancestor = container->shadowHost();
- return ancestor && isHTMLTextFormControlElement(ancestor) ? toHTMLTextFormControlElement(ancestor) : 0;
+ return ancestor && isHTMLTextFormControlElement(*ancestor) && container->containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot ? toHTMLTextFormControlElement(ancestor) : 0;
}
static const HTMLElement* parentHTMLElement(const Element* element)
@@ -651,7 +654,7 @@ String HTMLTextFormControlElement::directionForFormData() const
return "ltr";
}
-HTMLElement* HTMLTextFormControlElement::innerTextElement() const
+HTMLElement* HTMLTextFormControlElement::innerEditorElement() const
{
return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementNames::innerEditor()));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
index 2c7a9bf8895..6d1c5921f2f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElement.h
@@ -31,6 +31,7 @@ namespace WebCore {
class ExceptionState;
class Position;
+class Range;
class RenderTextControl;
class VisiblePosition;
@@ -69,20 +70,18 @@ public:
virtual void setRangeText(const String& replacement, unsigned start, unsigned end, const String& selectionMode, ExceptionState&);
void setSelectionRange(int start, int end, const String& direction);
void setSelectionRange(int start, int end, TextFieldSelectionDirection = SelectionHasNoDirection);
- PassRefPtr<Range> selection() const;
- String selectedText() const;
+ PassRefPtrWillBeRawPtr<Range> selection() const;
- virtual void dispatchFormControlChangeEvent();
+ virtual void dispatchFormControlChangeEvent() OVERRIDE FINAL;
- virtual int maxLength() const = 0;
virtual String value() const = 0;
- HTMLElement* innerTextElement() const;
+ HTMLElement* innerEditorElement() const;
void selectionChanged(bool userTriggered);
bool lastChangeWasUserEdit() const;
- void setInnerTextValue(const String&);
- String innerTextValue() const;
+ virtual void setInnerEditorValue(const String&);
+ String innerEditorValue() const;
String directionForFormData() const;
@@ -97,35 +96,37 @@ protected:
void cacheSelection(int start, int end, TextFieldSelectionDirection direction)
{
+ ASSERT(start >= 0);
m_cachedSelectionStart = start;
m_cachedSelectionEnd = end;
m_cachedSelectionDirection = direction;
}
void restoreCachedSelection();
- bool hasCachedSelection() const { return m_cachedSelectionStart >= 0; }
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual void subtreeHasChanged() = 0;
void setLastChangeWasNotUserEdit() { m_lastChangeWasUserEdit = false; }
String valueWithHardLineBreaks() const;
+ virtual bool shouldDispatchFormControlChangeEvent(String&, String&);
+
private:
int computeSelectionStart() const;
int computeSelectionEnd() const;
TextFieldSelectionDirection computeSelectionDirection() const;
- virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
- virtual void dispatchBlurEvent(Element* newFocusedElement) OVERRIDE;
+ virtual void dispatchFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE FINAL;
+ virtual void dispatchBlurEvent(Element* newFocusedElement) OVERRIDE FINAL;
// Returns true if user-editable value is empty. Used to check placeholder visibility.
virtual bool isEmptyValue() const = 0;
// Returns true if suggested value is empty. Used to check placeholder visibility.
virtual bool isEmptySuggestedValue() const { return true; }
// Called in dispatchFocusEvent(), after placeholder process, before calling parent's dispatchFocusEvent().
- virtual void handleFocusEvent(Element* /* oldFocusedNode */, FocusDirection) { }
+ virtual void handleFocusEvent(Element* /* oldFocusedNode */, FocusType) { }
// Called in dispatchBlurEvent(), after placeholder process, before calling parent's dispatchBlurEvent().
virtual void handleBlurEvent() { }
@@ -137,19 +138,15 @@ private:
TextFieldSelectionDirection m_cachedSelectionDirection;
};
-inline bool isHTMLTextFormControlElement(const Node* node)
-{
- return node->isElementNode() && toElement(node)->isTextFormControl();
-}
-
-inline bool isHTMLTextFormControlElement(const Node& node)
+inline bool isHTMLTextFormControlElement(const Element& element)
{
- return node.isElementNode() && toElement(node).isTextFormControl();
+ return element.isTextFormControl();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTextFormControlElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTextFormControlElement);
HTMLTextFormControlElement* enclosingTextFormControl(const Position&);
+HTMLTextFormControlElement* enclosingTextFormControl(Node*);
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp
new file mode 100644
index 00000000000..1134854814f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTextFormControlElementTest.cpp
@@ -0,0 +1,54 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/HTMLTextFormControlElement.h"
+
+#include "core/frame/FrameView.h"
+#include "core/html/HTMLDocument.h"
+#include "core/testing/DummyPageHolder.h"
+#include "wtf/OwnPtr.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class HTMLTextFormControlElementTest : public ::testing::Test {
+protected:
+ virtual void SetUp() OVERRIDE;
+
+ HTMLTextFormControlElement& textControl() const { return *m_textControl; }
+
+private:
+ OwnPtr<DummyPageHolder> m_dummyPageHolder;
+
+ RefPtrWillBePersistent<HTMLTextFormControlElement> m_textControl;
+};
+
+void HTMLTextFormControlElementTest::SetUp()
+{
+ m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+ HTMLDocument& document = toHTMLDocument(m_dummyPageHolder->document());
+ document.documentElement()->setInnerHTML("<body><textarea id=textarea></textarea></body>", ASSERT_NO_EXCEPTION);
+ document.view()->updateLayoutAndStyleIfNeededRecursive();
+ m_textControl = toHTMLTextFormControlElement(document.getElementById("textarea"));
+ m_textControl->focus();
+}
+
+TEST_F(HTMLTextFormControlElementTest, SetSelectionRange)
+{
+ EXPECT_EQ(0, textControl().selectionStart());
+ EXPECT_EQ(0, textControl().selectionEnd());
+
+ textControl().setInnerEditorValue("Hello, text form.");
+ EXPECT_EQ(0, textControl().selectionStart());
+ EXPECT_EQ(0, textControl().selectionEnd());
+
+ textControl().setSelectionRange(1, 3);
+ EXPECT_EQ(1, textControl().selectionStart());
+ EXPECT_EQ(3, textControl().selectionEnd());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp
index c9fdaedc0f2..33060e20b43 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.cpp
@@ -23,8 +23,9 @@
#include "config.h"
#include "core/html/HTMLTitleElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ChildListMutationScope.h"
#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/rendering/style/RenderStyle.h"
@@ -37,15 +38,13 @@ using namespace HTMLNames;
inline HTMLTitleElement::HTMLTitleElement(Document& document)
: HTMLElement(titleTag, document)
+ , m_ignoreTitleUpdatesWhenChildrenChange(false)
{
setHasCustomStyleCallbacks();
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLTitleElement> HTMLTitleElement::create(Document& document)
-{
- return adoptRef(new HTMLTitleElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLTitleElement)
Node::InsertionNotificationRequest HTMLTitleElement::insertedInto(ContainerNode* insertionPoint)
{
@@ -65,7 +64,7 @@ void HTMLTitleElement::removedFrom(ContainerNode* insertionPoint)
void HTMLTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (inDocument() && !isInShadowTree())
+ if (inDocument() && !isInShadowTree() && !m_ignoreTitleUpdatesWhenChildrenChange)
document().setTitleElement(text(), this);
}
@@ -83,23 +82,16 @@ String HTMLTitleElement::text() const
void HTMLTitleElement::setText(const String &value)
{
- RefPtr<Node> protectFromMutationEvents(this);
+ RefPtrWillBeRawPtr<Node> protectFromMutationEvents(this);
+ ChildListMutationScope mutation(*this);
- int numChildren = childNodeCount();
+ // Avoid calling Document::setTitleElement() during intermediate steps.
+ m_ignoreTitleUpdatesWhenChildrenChange = !value.isEmpty();
+ removeChildren();
+ m_ignoreTitleUpdatesWhenChildrenChange = false;
- if (numChildren == 1 && firstChild()->isTextNode())
- toText(firstChild())->setData(value);
- else {
- // We make a copy here because entity of "value" argument can be Document::m_title,
- // which goes empty during removeChildren() invocation below,
- // which causes HTMLTitleElement::childrenChanged(), which ends up Document::setTitle().
- String valueCopy(value);
-
- if (numChildren > 0)
- removeChildren();
-
- appendChild(document().createTextNode(valueCopy.impl()), IGNORE_EXCEPTION);
- }
+ if (!value.isEmpty())
+ appendChild(document().createTextNode(value.impl()), IGNORE_EXCEPTION);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h
index 988f77ac96e..76f2e6bfb9f 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTitleElement.h
@@ -28,7 +28,7 @@ namespace WebCore {
class HTMLTitleElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTitleElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTitleElement);
String text() const;
void setText(const String&);
@@ -38,20 +38,10 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-};
-
-inline bool isHTMLTitleElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::titleTag);
-}
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
-inline bool isHTMLTitleElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::titleTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLTitleElement, hasTagName(HTMLNames::titleTag));
+ bool m_ignoreTitleUpdatesWhenChildrenChange;
+};
} //namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp
index 0182bcef28f..0c1bae6eeb0 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp
@@ -26,15 +26,13 @@
#include "config.h"
#include "core/html/HTMLTrackElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/events/Event.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLMediaElement.h"
-#include "core/frame/ContentSecurityPolicy.h"
#include "platform/Logging.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -58,15 +56,14 @@ inline HTMLTrackElement::HTMLTrackElement(Document& document)
ScriptWrappable::init(this);
}
+DEFINE_NODE_FACTORY(HTMLTrackElement)
+
HTMLTrackElement::~HTMLTrackElement()
{
+#if !ENABLE(OILPAN)
if (m_track)
- m_track->clearClient();
-}
-
-PassRefPtr<HTMLTrackElement> HTMLTrackElement::create(Document& document)
-{
- return adoptRef(new HTMLTrackElement(document));
+ m_track->clearTrackElement();
+#endif
}
Node::InsertionNotificationRequest HTMLTrackElement::insertedInto(ContainerNode* insertionPoint)
@@ -79,14 +76,14 @@ Node::InsertionNotificationRequest HTMLTrackElement::insertedInto(ContainerNode*
HTMLElement::insertedInto(insertionPoint);
HTMLMediaElement* parent = mediaElement();
if (insertionPoint == parent)
- parent->didAddTrack(this);
+ parent->didAddTrackElement(this);
return InsertionDone;
}
void HTMLTrackElement::removedFrom(ContainerNode* insertionPoint)
{
- if (!parentNode() && isHTMLMediaElement(insertionPoint))
- toHTMLMediaElement(insertionPoint)->didRemoveTrack(this);
+ if (!parentNode() && isHTMLMediaElement(*insertionPoint))
+ toHTMLMediaElement(insertionPoint)->didRemoveTrackElement(this);
HTMLElement::removedFrom(insertionPoint);
}
@@ -162,7 +159,7 @@ void HTMLTrackElement::scheduleLoad()
return;
// 4. Run the remainder of these steps asynchronously, allowing whatever caused these steps to run to continue.
- m_loadTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0, FROM_HERE);
}
void HTMLTrackElement::loadTimerFired(Timer<HTMLTrackElement>*)
@@ -207,7 +204,7 @@ bool HTMLTrackElement::canLoadUrl(const KURL& url)
return false;
}
- return dispatchBeforeLoadEvent(url.string());
+ return true;
}
void HTMLTrackElement::didCompleteLoad(LoadStatus status)
@@ -264,53 +261,18 @@ const AtomicString& HTMLTrackElement::mediaElementCrossOriginAttribute() const
return nullAtom;
}
-void HTMLTrackElement::textTrackKindChanged(TextTrack* track)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackKindChanged(track);
-}
-
-void HTMLTrackElement::textTrackModeChanged(TextTrack* track)
-{
- // Since we've moved to a new parent, we may now be able to load.
- if (readyState() == HTMLTrackElement::NONE)
- scheduleLoad();
-
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackModeChanged(track);
-}
-
-void HTMLTrackElement::textTrackAddCues(TextTrack* track, const TextTrackCueList* cues)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackAddCues(track, cues);
-}
-
-void HTMLTrackElement::textTrackRemoveCues(TextTrack* track, const TextTrackCueList* cues)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackRemoveCues(track, cues);
-}
-
-void HTMLTrackElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackAddCue(track, cue);
-}
-
-void HTMLTrackElement::textTrackRemoveCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
-{
- if (HTMLMediaElement* parent = mediaElement())
- return parent->textTrackRemoveCue(track, cue);
-}
-
HTMLMediaElement* HTMLTrackElement::mediaElement() const
{
Element* parent = parentElement();
- if (parent && parent->isMediaElement())
- return toHTMLMediaElement(parentNode());
+ if (isHTMLMediaElement(parent))
+ return toHTMLMediaElement(parent);
return 0;
}
+void HTMLTrackElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_track);
+ HTMLElement::trace(visitor);
}
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h
index 9e70146d56d..6657fd51f8d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.h
@@ -29,14 +29,15 @@
#include "core/html/HTMLElement.h"
#include "core/html/track/LoadableTextTrack.h"
#include "core/html/track/TextTrack.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class HTMLMediaElement;
-class HTMLTrackElement FINAL : public HTMLElement, public TextTrackClient {
+class HTMLTrackElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLTrackElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLTrackElement);
const AtomicString& kind();
void setKind(const AtomicString&);
@@ -54,6 +55,8 @@ public:
const AtomicString& mediaElementCrossOriginAttribute() const;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit HTMLTrackElement(Document&);
virtual ~HTMLTrackElement();
@@ -69,23 +72,13 @@ private:
HTMLMediaElement* mediaElement() const;
- // TextTrackClient
- virtual void textTrackModeChanged(TextTrack*) OVERRIDE;
- virtual void textTrackKindChanged(TextTrack*) OVERRIDE;
- virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
- virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
- virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
- virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
-
LoadableTextTrack* ensureTrack();
bool canLoadUrl(const KURL&);
- RefPtr<LoadableTextTrack> m_track;
+ RefPtrWillBeMember<LoadableTextTrack> m_track;
Timer<HTMLTrackElement> m_loadTimer;
};
-DEFINE_NODE_TYPE_CASTS(HTMLTrackElement, hasTagName(HTMLNames::trackTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl
index da7e22e9e64..7ad3e606e3d 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLTrackElement.idl
@@ -23,11 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-[
- RuntimeEnabled=VideoTrack
-] interface HTMLTrackElement : HTMLElement {
+interface HTMLTrackElement : HTMLElement {
attribute DOMString kind;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString src;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString src;
[Reflect] attribute DOMString srclang;
[Reflect] attribute DOMString label;
[Reflect] attribute boolean default;
@@ -40,4 +38,6 @@
readonly attribute unsigned short readyState;
readonly attribute TextTrack track;
+
+ [Reflect, RuntimeEnabled=SubresourceIntegrity] attribute DOMString integrity;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp
index 9eb6e55e679..0261d0f7d78 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.cpp
@@ -23,23 +23,20 @@
#include "config.h"
#include "core/html/HTMLUListElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
namespace WebCore {
using namespace HTMLNames;
-HTMLUListElement::HTMLUListElement(Document& document)
+inline HTMLUListElement::HTMLUListElement(Document& document)
: HTMLElement(ulTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<HTMLUListElement> HTMLUListElement::create(Document& document)
-{
- return adoptRef(new HTMLUListElement(document));
-}
+DEFINE_NODE_FACTORY(HTMLUListElement)
bool HTMLUListElement::isPresentationAttribute(const QualifiedName& name) const
{
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h
index 899467c4945..9a7c238fb38 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLUListElement.h
@@ -29,7 +29,7 @@ namespace WebCore {
class HTMLUListElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLUListElement> create(Document&);
+ DECLARE_NODE_FACTORY(HTMLUListElement);
private:
explicit HTMLUListElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h
index 1c1794c0ed5..09d87365f01 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLUnknownElement.h
@@ -36,9 +36,9 @@ namespace WebCore {
class HTMLUnknownElement FINAL : public HTMLElement {
public:
- static PassRefPtr<HTMLUnknownElement> create(const QualifiedName& tagName, Document& document)
+ static PassRefPtrWillBeRawPtr<HTMLUnknownElement> create(const QualifiedName& tagName, Document& document)
{
- return adoptRef(new HTMLUnknownElement(tagName, document));
+ return adoptRefWillBeNoop(new HTMLUnknownElement(tagName, document));
}
virtual bool isHTMLUnknownElement() const OVERRIDE { return true; }
@@ -51,12 +51,17 @@ private:
}
};
-inline bool isHTMLUnknownElement(const Node& node)
+inline bool isHTMLUnknownElement(const Element& element)
{
- return node.isElementNode() && toHTMLElement(node).isHTMLUnknownElement();
+ return element.isHTMLElement() && toHTMLElement(element).isHTMLUnknownElement();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLUnknownElement);
+inline bool isHTMLUnknownElement(const HTMLElement& element)
+{
+ return element.isHTMLUnknownElement();
+}
+
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLUnknownElement);
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
index b5c1c00ebb4..c03e09716cf 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.cpp
@@ -26,15 +26,17 @@
#include "config.h"
#include "core/html/HTMLVideoElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLImageLoader.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderVideo.h"
#include "platform/UserGestureIndicator.h"
@@ -43,19 +45,26 @@ namespace WebCore {
using namespace HTMLNames;
-inline HTMLVideoElement::HTMLVideoElement(Document& document, bool createdByParser)
- : HTMLMediaElement(videoTag, document, createdByParser)
+inline HTMLVideoElement::HTMLVideoElement(Document& document)
+ : HTMLMediaElement(videoTag, document)
{
ScriptWrappable::init(this);
if (document.settings())
- m_defaultPosterURL = document.settings()->defaultVideoPosterURL();
+ m_defaultPosterURL = AtomicString(document.settings()->defaultVideoPosterURL());
+}
+
+PassRefPtrWillBeRawPtr<HTMLVideoElement> HTMLVideoElement::create(Document& document)
+{
+ RefPtrWillBeRawPtr<HTMLVideoElement> video = adoptRefWillBeNoop(new HTMLVideoElement(document));
+ video->ensureUserAgentShadowRoot();
+ video->suspendIfNeeded();
+ return video.release();
}
-PassRefPtr<HTMLVideoElement> HTMLVideoElement::create(Document& document, bool createdByParser)
+void HTMLVideoElement::trace(Visitor* visitor)
{
- RefPtr<HTMLVideoElement> videoElement(adoptRef(new HTMLVideoElement(document, createdByParser)));
- videoElement->suspendIfNeeded();
- return videoElement.release();
+ visitor->trace(m_imageLoader);
+ HTMLMediaElement::trace(visitor);
}
bool HTMLVideoElement::rendererIsNeeded(const RenderStyle& style)
@@ -75,7 +84,7 @@ void HTMLVideoElement::attach(const AttachContext& context)
updateDisplayState();
if (shouldDisplayPosterImage()) {
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
m_imageLoader->updateFromElement();
if (renderer())
toRenderImage(renderer())->imageResource()->setImageResource(m_imageLoader->image());
@@ -107,12 +116,15 @@ void HTMLVideoElement::parseAttribute(const QualifiedName& name, const AtomicStr
updateDisplayState();
if (shouldDisplayPosterImage()) {
if (!m_imageLoader)
- m_imageLoader = adoptPtr(new HTMLImageLoader(this));
+ m_imageLoader = HTMLImageLoader::create(this);
m_imageLoader->updateFromElementIgnoringPreviousError();
} else {
if (renderer())
toRenderImage(renderer())->imageResource()->setImageResource(0);
}
+ // Notify the player when the poster image URL changes.
+ if (player())
+ player()->setPoster(posterImageURL());
} else
HTMLMediaElement::parseAttribute(name, value);
}
@@ -122,7 +134,7 @@ bool HTMLVideoElement::supportsFullscreen() const
if (!document().page())
return false;
- if (!player() || !player()->supportsFullscreen())
+ if (!player())
return false;
return true;
@@ -130,16 +142,16 @@ bool HTMLVideoElement::supportsFullscreen() const
unsigned HTMLVideoElement::videoWidth() const
{
- if (!player())
+ if (!webMediaPlayer())
return 0;
- return player()->naturalSize().width();
+ return webMediaPlayer()->naturalSize().width;
}
unsigned HTMLVideoElement::videoHeight() const
{
- if (!player())
+ if (!webMediaPlayer())
return 0;
- return player()->naturalSize().height();
+ return webMediaPlayer()->naturalSize().height;
}
bool HTMLVideoElement::isURLAttribute(const Attribute& attribute) const
@@ -163,7 +175,9 @@ void HTMLVideoElement::setDisplayMode(DisplayMode mode)
if (!poster.isEmpty()) {
// We have a poster path, but only show it until the user triggers display by playing or seeking and the
// media engine has something to display.
- if (mode == Video && !hasAvailableVideoFrame())
+ // Don't show the poster if there is a seek operation or
+ // the video has restarted because of loop attribute
+ if (mode == Video && oldMode == Poster && !hasAvailableVideoFrame())
mode = PosterWaitingForVideo;
}
@@ -181,7 +195,7 @@ void HTMLVideoElement::updateDisplayState()
setDisplayMode(Poster);
}
-void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
+void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect) const
{
MediaPlayer* player = HTMLMediaElement::player();
if (!player)
@@ -189,7 +203,7 @@ void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, cons
player->paint(context, destRect);
}
-bool HTMLVideoElement::copyVideoTextureToPlatformTexture(GraphicsContext3D* context, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY)
+bool HTMLVideoElement::copyVideoTextureToPlatformTexture(blink::WebGraphicsContext3D* context, Platform3DObject texture, GLint level, GLenum type, GLenum internalFormat, bool premultiplyAlpha, bool flipY)
{
if (!player())
return false;
@@ -198,10 +212,10 @@ bool HTMLVideoElement::copyVideoTextureToPlatformTexture(GraphicsContext3D* cont
bool HTMLVideoElement::hasAvailableVideoFrame() const
{
- if (!player())
+ if (!webMediaPlayer())
return false;
- return player()->hasVideo() && player()->readyState() >= MediaPlayer::HaveCurrentData;
+ return webMediaPlayer()->hasVideo() && webMediaPlayer()->readyState() >= blink::WebMediaPlayer::ReadyStateHaveCurrentData;
}
void HTMLVideoElement::webkitEnterFullscreen(ExceptionState& exceptionState)
@@ -209,12 +223,6 @@ void HTMLVideoElement::webkitEnterFullscreen(ExceptionState& exceptionState)
if (isFullscreen())
return;
- // Generate an exception if this isn't called in response to a user gesture, or if the
- // element does not support fullscreen.
- if (userGestureRequiredForFullscreen() && !UserGestureIndicator::processingUserGesture()) {
- exceptionState.throwDOMException(InvalidStateError, "This element may only enter fullscreen mode in response to a user gesture ('click', for example).");
- return;
- }
if (!supportsFullscreen()) {
exceptionState.throwDOMException(InvalidStateError, "This element does not support fullscreen mode.");
return;
@@ -248,18 +256,18 @@ void HTMLVideoElement::didMoveToNewDocument(Document& oldDocument)
unsigned HTMLVideoElement::webkitDecodedFrameCount() const
{
- if (!player())
+ if (!webMediaPlayer())
return 0;
- return player()->decodedFrameCount();
+ return webMediaPlayer()->decodedFrameCount();
}
unsigned HTMLVideoElement::webkitDroppedFrameCount() const
{
- if (!player())
+ if (!webMediaPlayer())
return 0;
- return player()->droppedFrameCount();
+ return webMediaPlayer()->droppedFrameCount();
}
KURL HTMLVideoElement::posterImageURL() const
@@ -270,4 +278,39 @@ KURL HTMLVideoElement::posterImageURL() const
return document().completeURL(url);
}
+KURL HTMLVideoElement::mediaPlayerPosterURL()
+{
+ return posterImageURL();
+}
+
+PassRefPtr<Image> HTMLVideoElement::getSourceImageForCanvas(SourceImageMode mode, SourceImageStatus* status) const
+{
+ if (!hasAvailableVideoFrame()) {
+ *status = InvalidSourceImageStatus;
+ return nullptr;
+ }
+
+ IntSize intrinsicSize(videoWidth(), videoHeight());
+ OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(intrinsicSize);
+ if (!imageBuffer) {
+ *status = InvalidSourceImageStatus;
+ return nullptr;
+ }
+
+ paintCurrentFrameInContext(imageBuffer->context(), IntRect(IntPoint(0, 0), intrinsicSize));
+
+ *status = NormalSourceImageStatus;
+ return imageBuffer->copyImage(mode == CopySourceImageIfVolatile ? CopyBackingStore : DontCopyBackingStore, Unscaled);
+}
+
+bool HTMLVideoElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
+{
+ return !hasSingleSecurityOrigin() || (!(webMediaPlayer() && webMediaPlayer()->didPassCORSAccessCheck()) && destinationSecurityOrigin->taintsCanvas(currentSrc()));
+}
+
+FloatSize HTMLVideoElement::sourceSize() const
+{
+ return FloatSize(videoWidth(), videoHeight());
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h
index 4d729f39fa5..fa8f5fe1984 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.h
@@ -27,15 +27,21 @@
#define HTMLVideoElement_h
#include "core/html/HTMLMediaElement.h"
+#include "core/html/canvas/CanvasImageSource.h"
+
+namespace blink {
+class WebGraphicsContext3D;
+}
namespace WebCore {
class ExceptionState;
class HTMLImageLoader;
-class HTMLVideoElement FINAL : public HTMLMediaElement {
+class HTMLVideoElement FINAL : public HTMLMediaElement, public CanvasImageSource {
public:
- static PassRefPtr<HTMLVideoElement> create(Document&, bool createdByParser = false);
+ static PassRefPtrWillBeRawPtr<HTMLVideoElement> create(Document&);
+ virtual void trace(Visitor*) OVERRIDE;
unsigned videoWidth() const;
unsigned videoHeight() const;
@@ -51,18 +57,28 @@ public:
unsigned webkitDroppedFrameCount() const;
// Used by canvas to gain raw pixel access
- void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
+ void paintCurrentFrameInContext(GraphicsContext*, const IntRect&) const;
// Used by WebGL to do GPU-GPU textures copy if possible.
// See more details at MediaPlayer::copyVideoTextureToPlatformTexture() defined in Source/WebCore/platform/graphics/MediaPlayer.h.
- bool copyVideoTextureToPlatformTexture(GraphicsContext3D*, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY);
+ bool copyVideoTextureToPlatformTexture(blink::WebGraphicsContext3D*, Platform3DObject texture, GC3Dint level, GC3Denum type, GC3Denum internalFormat, bool premultiplyAlpha, bool flipY);
bool shouldDisplayPosterImage() const { return displayMode() == Poster || displayMode() == PosterWaitingForVideo; }
KURL posterImageURL() const;
+ // FIXME: Remove this when WebMediaPlayerClientImpl::loadInternal does not depend on it.
+ virtual KURL mediaPlayerPosterURL() OVERRIDE;
+
+ // CanvasImageSource implementation
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const OVERRIDE;
+ virtual bool isVideoElement() const OVERRIDE { return true; }
+ virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+ virtual FloatSize sourceSize() const OVERRIDE;
+ virtual const KURL& sourceURL() const OVERRIDE { return currentSrc(); }
+
private:
- HTMLVideoElement(Document&, bool);
+ HTMLVideoElement(Document&);
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
@@ -70,9 +86,8 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual bool isVideo() const OVERRIDE { return true; }
- virtual bool hasVideo() const OVERRIDE { return player() && player()->hasVideo(); }
- virtual bool supportsFullscreen() const OVERRIDE;
+ virtual bool hasVideo() const OVERRIDE { return webMediaPlayer() && webMediaPlayer()->hasVideo(); }
+ bool supportsFullscreen() const;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
virtual const AtomicString imageSourceURL() const OVERRIDE;
@@ -81,23 +96,11 @@ private:
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
virtual void setDisplayMode(DisplayMode) OVERRIDE;
- OwnPtr<HTMLImageLoader> m_imageLoader;
+ OwnPtrWillBeMember<HTMLImageLoader> m_imageLoader;
AtomicString m_defaultPosterURL;
};
-inline bool isHTMLVideoElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::videoTag);
-}
-
-inline bool isHTMLVideoElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::videoTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLVideoElement, hasTagName(HTMLNames::videoTag));
-
} //namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl
index 4448cd23542..30825e5b91c 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLVideoElement.idl
@@ -30,17 +30,17 @@
[Reflect] attribute unsigned long height;
readonly attribute unsigned long videoWidth;
readonly attribute unsigned long videoHeight;
- [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString poster;
+ [Reflect, URL, LogActivity=SetterOnly] attribute DOMString poster;
- [MeasureAs=PrefixedVideoSupportsFullscreen] readonly attribute boolean webkitSupportsFullscreen;
- [MeasureAs=PrefixedVideoDisplayingFullscreen] readonly attribute boolean webkitDisplayingFullscreen;
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoSupportsFullscreen] readonly attribute boolean webkitSupportsFullscreen;
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoDisplayingFullscreen] readonly attribute boolean webkitDisplayingFullscreen;
- [MeasureAs=PrefixedVideoEnterFullscreen, RaisesException, PerWorldBindings, ActivityLogging=ForAllWorlds] void webkitEnterFullscreen();
- [MeasureAs=PrefixedVideoExitFullscreen] void webkitExitFullscreen();
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoEnterFullscreen, RaisesException, LogActivity, LogAllWorlds] void webkitEnterFullscreen();
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoExitFullscreen] void webkitExitFullscreen();
// Note the different capitalization of the "S" in FullScreen.
- [MeasureAs=PrefixedVideoEnterFullScreen, ImplementedAs=webkitEnterFullscreen, RaisesException, PerWorldBindings, ActivityLogging=ForAllWorlds] void webkitEnterFullScreen();
- [MeasureAs=PrefixedVideoExitFullScreen, ImplementedAs=webkitExitFullscreen] void webkitExitFullScreen();
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoEnterFullScreen, ImplementedAs=webkitEnterFullscreen, RaisesException, LogActivity, LogAllWorlds] void webkitEnterFullScreen();
+ [RuntimeEnabled=PrefixedVideoFullscreen, DeprecateAs=PrefixedVideoExitFullScreen, ImplementedAs=webkitExitFullscreen] void webkitExitFullScreen();
// The number of frames that have been decoded and made available for
// playback.
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
index 4a55226d0b4..80bfd5cf740 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/html/HTMLViewSourceDocument.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/StyleEngine.h"
#include "core/dom/Text.h"
#include "core/html/HTMLAnchorElement.h"
@@ -47,6 +47,12 @@ namespace WebCore {
using namespace HTMLNames;
+namespace {
+
+const char kXSSDetected[] = "Token contains a reflected XSS vector";
+
+} // namespace
+
HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer, const String& mimeType)
: HTMLDocument(initializer)
, m_type(mimeType)
@@ -58,27 +64,27 @@ HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer,
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> HTMLViewSourceDocument::createParser()
{
- return HTMLViewSourceParser::create(this, m_type);
+ return HTMLViewSourceParser::create(*this, m_type);
}
void HTMLViewSourceDocument::createContainingTable()
{
- RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*this);
parserAppendChild(html);
- RefPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
html->parserAppendChild(head);
- RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
html->parserAppendChild(body);
// Create a line gutter div that can be used to make sure the gutter extends down the height of the whole
// document.
- RefPtr<HTMLDivElement> div = HTMLDivElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLDivElement> div = HTMLDivElement::create(*this);
div->setAttribute(classAttr, "webkit-line-gutter-backdrop");
body->parserAppendChild(div);
- RefPtr<HTMLTableElement> table = HTMLTableElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLTableElement> table = HTMLTableElement::create(*this);
body->parserAppendChild(table);
m_tbody = HTMLTableSectionElement::create(tbodyTag, *this);
table->parserAppendChild(m_tbody);
@@ -86,7 +92,7 @@ void HTMLViewSourceDocument::createContainingTable()
m_lineNumber = 0;
}
-void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
+void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token, SourceAnnotation annotation)
{
if (!m_current)
createContainingTable();
@@ -103,13 +109,13 @@ void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token)
break;
case HTMLToken::StartTag:
case HTMLToken::EndTag:
- processTagToken(source, token);
+ processTagToken(source, token, annotation);
break;
case HTMLToken::Comment:
processCommentToken(source, token);
break;
case HTMLToken::Character:
- processCharacterToken(source, token);
+ processCharacterToken(source, token, annotation);
break;
}
}
@@ -128,8 +134,9 @@ void HTMLViewSourceDocument::processEndOfFileToken(const String& source, HTMLTok
m_current = m_td;
}
-void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token)
+void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token, SourceAnnotation annotation)
{
+ maybeAddSpanForAnnotation(annotation);
m_current = addSpanWithClassName("webkit-html-tag");
AtomicString tagName(token.name());
@@ -139,21 +146,21 @@ void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& to
while (index < source.length()) {
if (iter == token.attributes().end()) {
// We want to show the remaining characters in the token.
- index = addRange(source, index, source.length(), "");
+ index = addRange(source, index, source.length(), emptyAtom);
ASSERT(index == source.length());
break;
}
AtomicString name(iter->name);
- String value = StringImpl::create8BitIfPossible(iter->value);
+ AtomicString value(StringImpl::create8BitIfPossible(iter->value));
- index = addRange(source, index, iter->nameRange.start - token.startIndex(), "");
+ index = addRange(source, index, iter->nameRange.start - token.startIndex(), emptyAtom);
index = addRange(source, index, iter->nameRange.end - token.startIndex(), "webkit-html-attribute-name");
if (tagName == baseTag && name == hrefAttr)
addBase(value);
- index = addRange(source, index, iter->valueRange.start - token.startIndex(), "");
+ index = addRange(source, index, iter->valueRange.start - token.startIndex(), emptyAtom);
bool isLink = name == srcAttr || name == hrefAttr;
index = addRange(source, index, iter->valueRange.end - token.startIndex(), "webkit-html-attribute-value", isLink, tagName == aTag, value);
@@ -170,19 +177,19 @@ void HTMLViewSourceDocument::processCommentToken(const String& source, HTMLToken
m_current = m_td;
}
-void HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&)
+void HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&, SourceAnnotation annotation)
{
- addText(source, "");
+ addText(source, "", annotation);
}
-PassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className)
+PassRefPtrWillBeRawPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className)
{
if (m_current == m_tbody) {
addLine(className);
return m_current;
}
- RefPtr<HTMLSpanElement> span = HTMLSpanElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLSpanElement> span = HTMLSpanElement::create(*this);
span->setAttribute(classAttr, className);
m_current->parserAppendChild(span);
return span.release();
@@ -191,11 +198,11 @@ PassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicStr
void HTMLViewSourceDocument::addLine(const AtomicString& className)
{
// Create a table row.
- RefPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(*this);
m_tbody->parserAppendChild(trow);
// Create a cell that will hold the line number (it is generated in the stylesheet using counters).
- RefPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, *this);
+ RefPtrWillBeRawPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, *this);
td->setAttribute(classAttr, "webkit-line-number");
td->setIntegralAttribute(valueAttr, ++m_lineNumber);
trow->parserAppendChild(td);
@@ -216,14 +223,14 @@ void HTMLViewSourceDocument::addLine(const AtomicString& className)
void HTMLViewSourceDocument::finishLine()
{
- if (!m_current->hasChildNodes()) {
- RefPtr<HTMLBRElement> br = HTMLBRElement::create(*this);
+ if (!m_current->hasChildren()) {
+ RefPtrWillBeRawPtr<HTMLBRElement> br = HTMLBRElement::create(*this);
m_current->parserAppendChild(br);
}
m_current = m_tbody;
}
-void HTMLViewSourceDocument::addText(const String& text, const AtomicString& className)
+void HTMLViewSourceDocument::addText(const String& text, const AtomicString& className, SourceAnnotation annotation)
{
if (text.isEmpty())
return;
@@ -242,14 +249,16 @@ void HTMLViewSourceDocument::addText(const String& text, const AtomicString& cla
finishLine();
continue;
}
- RefPtr<Text> t = Text::create(*this, substring);
- m_current->parserAppendChild(t);
+ RefPtrWillBeRawPtr<Element> oldElement = m_current;
+ maybeAddSpanForAnnotation(annotation);
+ m_current->parserAppendChild(Text::create(*this, substring));
+ m_current = oldElement;
if (i < size - 1)
finishLine();
}
}
-int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const String& className, bool isLink, bool isAnchor, const String& link)
+int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const AtomicString& className, bool isLink, bool isAnchor, const AtomicString& link)
{
ASSERT(start <= end);
if (start == end)
@@ -268,21 +277,21 @@ int HTMLViewSourceDocument::addRange(const String& source, int start, int end, c
return end;
}
-PassRefPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
+PassRefPtrWillBeRawPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href)
{
- RefPtr<HTMLBaseElement> base = HTMLBaseElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLBaseElement> base = HTMLBaseElement::create(*this);
base->setAttribute(hrefAttr, href);
m_current->parserAppendChild(base);
return base.release();
}
-PassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, bool isAnchor)
+PassRefPtrWillBeRawPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, bool isAnchor)
{
if (m_current == m_tbody)
addLine("webkit-html-tag");
// Now create a link for the attribute value instead of a span.
- RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(*this);
const char* classValue;
if (isAnchor)
classValue = "webkit-html-attribute-value webkit-html-external-link";
@@ -295,4 +304,20 @@ PassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, boo
return anchor.release();
}
+void HTMLViewSourceDocument::maybeAddSpanForAnnotation(SourceAnnotation annotation)
+{
+ if (annotation == AnnotateSourceAsXSS) {
+ m_current = addSpanWithClassName("webkit-highlight");
+ m_current->setAttribute(titleAttr, kXSSDetected);
+ }
+}
+
+void HTMLViewSourceDocument::trace(Visitor* visitor)
+{
+ visitor->trace(m_current);
+ visitor->trace(m_tbody);
+ visitor->trace(m_td);
+ HTMLDocument::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h b/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h
index a1988cc7e2c..29e44ae7a98 100644
--- a/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLViewSourceDocument.h
@@ -35,37 +35,46 @@ class HTMLToken;
class HTMLViewSourceDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<HTMLViewSourceDocument> create(const DocumentInit& initializer, const String& mimeType)
+ enum SourceAnnotation {
+ AnnotateSourceAsSafe,
+ AnnotateSourceAsXSS
+ };
+
+ static PassRefPtrWillBeRawPtr<HTMLViewSourceDocument> create(const DocumentInit& initializer, const String& mimeType)
{
- return adoptRef(new HTMLViewSourceDocument(initializer, mimeType));
+ return adoptRefWillBeNoop(new HTMLViewSourceDocument(initializer, mimeType));
}
- void addSource(const String&, HTMLToken&);
+ void addSource(const String&, HTMLToken&, SourceAnnotation);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
HTMLViewSourceDocument(const DocumentInit&, const String& mimeType);
- virtual PassRefPtr<DocumentParser> createParser() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
void processDoctypeToken(const String& source, HTMLToken&);
void processEndOfFileToken(const String& source, HTMLToken&);
- void processTagToken(const String& source, HTMLToken&);
+ void processTagToken(const String& source, HTMLToken&, SourceAnnotation);
void processCommentToken(const String& source, HTMLToken&);
- void processCharacterToken(const String& source, HTMLToken&);
+ void processCharacterToken(const String& source, HTMLToken&, SourceAnnotation);
void createContainingTable();
- PassRefPtr<Element> addSpanWithClassName(const AtomicString&);
+ PassRefPtrWillBeRawPtr<Element> addSpanWithClassName(const AtomicString&);
void addLine(const AtomicString& className);
void finishLine();
- void addText(const String& text, const AtomicString& className);
- int addRange(const String& source, int start, int end, const String& className, bool isLink = false, bool isAnchor = false, const String& link = String());
- PassRefPtr<Element> addLink(const AtomicString& url, bool isAnchor);
- PassRefPtr<Element> addBase(const AtomicString& href);
+ void addText(const String& text, const AtomicString& className, SourceAnnotation = AnnotateSourceAsSafe);
+ int addRange(const String& source, int start, int end, const AtomicString& className, bool isLink = false, bool isAnchor = false, const AtomicString& link = nullAtom);
+ void maybeAddSpanForAnnotation(SourceAnnotation);
+
+ PassRefPtrWillBeRawPtr<Element> addLink(const AtomicString& url, bool isAnchor);
+ PassRefPtrWillBeRawPtr<Element> addBase(const AtomicString& href);
String m_type;
- RefPtr<Element> m_current;
- RefPtr<HTMLTableSectionElement> m_tbody;
- RefPtr<HTMLTableCellElement> m_td;
+ RefPtrWillBeMember<Element> m_current;
+ RefPtrWillBeMember<HTMLTableSectionElement> m_tbody;
+ RefPtrWillBeMember<HTMLTableCellElement> m_td;
int m_lineNumber;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.cpp b/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.cpp
new file mode 100644
index 00000000000..74e06d30b05
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/HTMLWBRElement.h"
+
+#include "core/HTMLNames.h"
+#include "core/rendering/RenderWordBreak.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline HTMLWBRElement::HTMLWBRElement(Document& document)
+ : HTMLElement(wbrTag, document)
+{
+}
+
+DEFINE_NODE_FACTORY(HTMLWBRElement)
+
+RenderObject* HTMLWBRElement::createRenderer(RenderStyle* style)
+{
+ return new RenderWordBreak(this);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.h b/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.h
new file mode 100644
index 00000000000..0f187e2e309
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/HTMLWBRElement.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLWBRElement_h
+#define HTMLWBRElement_h
+
+#include "core/html/HTMLElement.h"
+
+namespace WebCore {
+
+// <wbr> is an HTMLElement in script, but we use a separate interface here
+// so HTMLElement's createRenderer doesn't need to know about it.
+class HTMLWBRElement FINAL : public HTMLElement {
+public:
+ DECLARE_NODE_FACTORY(HTMLWBRElement);
+
+private:
+ explicit HTMLWBRElement(Document&);
+
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+};
+
+} // namespace
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageData.cpp b/chromium/third_party/WebKit/Source/core/html/ImageData.cpp
index 64c86c931b6..14b6fbed3ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageData.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/ImageData.cpp
@@ -29,37 +29,104 @@
#include "config.h"
#include "core/html/ImageData.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "platform/RuntimeEnabledFeatures.h"
+
namespace WebCore {
-PassRefPtr<ImageData> ImageData::create(const IntSize& size)
+PassRefPtrWillBeRawPtr<ImageData> ImageData::create(const IntSize& size)
{
Checked<int, RecordOverflow> dataSize = 4;
dataSize *= size.width();
dataSize *= size.height();
if (dataSize.hasOverflowed())
- return 0;
+ return nullptr;
- return adoptRef(new ImageData(size));
+ return adoptRefWillBeNoop(new ImageData(size));
}
-PassRefPtr<ImageData> ImageData::create(const IntSize& size, PassRefPtr<Uint8ClampedArray> byteArray)
+PassRefPtrWillBeRawPtr<ImageData> ImageData::create(const IntSize& size, PassRefPtr<Uint8ClampedArray> byteArray)
{
Checked<int, RecordOverflow> dataSize = 4;
dataSize *= size.width();
dataSize *= size.height();
if (dataSize.hasOverflowed())
- return 0;
+ return nullptr;
if (dataSize.unsafeGet() < 0
|| static_cast<unsigned>(dataSize.unsafeGet()) > byteArray->length())
- return 0;
+ return nullptr;
+
+ return adoptRefWillBeNoop(new ImageData(size, byteArray));
+}
+
+PassRefPtrWillBeRawPtr<ImageData> ImageData::create(unsigned width, unsigned height, ExceptionState& exceptionState)
+{
+ if (!RuntimeEnabledFeatures::imageDataConstructorEnabled()) {
+ exceptionState.throwTypeError("Illegal constructor");
+ return nullptr;
+ }
+ if (!width || !height) {
+ exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is zero or not a number.", width ? "height" : "width"));
+ return nullptr;
+ }
+
+ Checked<unsigned, RecordOverflow> dataSize = 4;
+ dataSize *= width;
+ dataSize *= height;
+ if (dataSize.hasOverflowed()) {
+ exceptionState.throwDOMException(IndexSizeError, "The requested image size exceeds the supported range.");
+ return nullptr;
+ }
+
+ RefPtrWillBeRawPtr<ImageData> imageData = adoptRefWillBeNoop(new ImageData(IntSize(width, height)));
+ imageData->data()->zeroFill();
+ return imageData.release();
+}
+
+PassRefPtrWillBeRawPtr<ImageData> ImageData::create(Uint8ClampedArray* data, unsigned width, unsigned height, ExceptionState& exceptionState)
+{
+ if (!RuntimeEnabledFeatures::imageDataConstructorEnabled()) {
+ exceptionState.throwTypeError("Illegal constructor");
+ return nullptr;
+ }
+ if (!data) {
+ exceptionState.throwTypeError("Expected a Uint8ClampedArray as first argument.");
+ return nullptr;
+ }
+ if (!width) {
+ exceptionState.throwDOMException(IndexSizeError, "The source width is zero or not a number.");
+ return nullptr;
+ }
+
+ unsigned length = data->length();
+ if (!length) {
+ exceptionState.throwDOMException(IndexSizeError, "The input data has a zero byte length.");
+ return nullptr;
+ }
+ if (length % 4) {
+ exceptionState.throwDOMException(IndexSizeError, "The input data byte length is not a multiple of 4.");
+ return nullptr;
+ }
+ length /= 4;
+ if (length % width) {
+ exceptionState.throwDOMException(IndexSizeError, "The input data byte length is not a multiple of (4 * width).");
+ return nullptr;
+ }
+ if (!height) {
+ height = length / width;
+ } else if (height != length / width) {
+ exceptionState.throwDOMException(IndexSizeError, "The input data byte length is not equal to (4 * width * height).");
+ return nullptr;
+ }
- return adoptRef(new ImageData(size, byteArray));
+ return adoptRefWillBeNoop(new ImageData(IntSize(width, height), data));
}
ImageData::ImageData(const IntSize& size)
: m_size(size)
- , m_data(Uint8ClampedArray::createUninitialized(size.width() * size.height() * 4))
+ , m_data(Uint8ClampedArray::create(size.width() * size.height() * 4))
{
ScriptWrappable::init(this);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageData.h b/chromium/third_party/WebKit/Source/core/html/ImageData.h
index 5015885998b..94fbaa10c72 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageData.h
+++ b/chromium/third_party/WebKit/Source/core/html/ImageData.h
@@ -31,24 +31,31 @@
#include "bindings/v8/ScriptWrappable.h"
#include "platform/geometry/IntSize.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
#include "wtf/Uint8ClampedArray.h"
namespace WebCore {
-class ImageData : public RefCounted<ImageData>, public ScriptWrappable {
+class ExceptionState;
+
+class ImageData FINAL : public RefCountedWillBeGarbageCollectedFinalized<ImageData>, public ScriptWrappable {
public:
- static PassRefPtr<ImageData> create(const IntSize&);
- static PassRefPtr<ImageData> create(const IntSize&, PassRefPtr<Uint8ClampedArray>);
+ static PassRefPtrWillBeRawPtr<ImageData> create(const IntSize&);
+ static PassRefPtrWillBeRawPtr<ImageData> create(const IntSize&, PassRefPtr<Uint8ClampedArray>);
+ static PassRefPtrWillBeRawPtr<ImageData> create(unsigned width, unsigned height, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<ImageData> create(Uint8ClampedArray*, unsigned width, unsigned height, ExceptionState&);
IntSize size() const { return m_size; }
int width() const { return m_size.width(); }
int height() const { return m_size.height(); }
Uint8ClampedArray* data() const { return m_data.get(); }
+ void trace(Visitor*) { }
+
private:
- ImageData(const IntSize&);
+ explicit ImageData(const IntSize&);
ImageData(const IntSize&, PassRefPtr<Uint8ClampedArray>);
IntSize m_size;
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageData.idl b/chromium/third_party/WebKit/Source/core/html/ImageData.idl
index 06847999097..18ed72f2478 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageData.idl
+++ b/chromium/third_party/WebKit/Source/core/html/ImageData.idl
@@ -26,10 +26,16 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata
+
[
+ Constructor(unsigned long width, unsigned long height),
+ Constructor(Uint8ClampedArray data, unsigned long width, [Default=Undefined] optional unsigned long height),
Custom=Wrap,
+ Exposed=Window&Worker,
+ RaisesException=Constructor,
+ WillBeGarbageCollected,
] interface ImageData {
readonly attribute long width;
readonly attribute long height;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp b/chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp
index aaeff99d644..62903c2344c 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/ImageDocument.cpp
@@ -25,13 +25,15 @@
#include "config.h"
#include "core/html/ImageDocument.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/RawDataDocumentParser.h"
#include "core/events/EventListener.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLHeadElement.h"
#include "core/html/HTMLHtmlElement.h"
@@ -40,9 +42,6 @@
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/Settings.h"
#include "wtf/text/StringBuilder.h"
using std::min;
@@ -77,9 +76,9 @@ private:
class ImageDocumentParser : public RawDataDocumentParser {
public:
- static PassRefPtr<ImageDocumentParser> create(ImageDocument* document)
+ static PassRefPtrWillBeRawPtr<ImageDocumentParser> create(ImageDocument* document)
{
- return adoptRef(new ImageDocumentParser(document));
+ return adoptRefWillBeNoop(new ImageDocumentParser(document));
}
ImageDocument* document() const
@@ -101,7 +100,7 @@ private:
static float pageZoomFactor(const Document* document)
{
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
return frame ? frame->pageZoomFactor() : 1;
}
@@ -124,18 +123,22 @@ void ImageDocumentParser::appendBytes(const char* data, size_t length)
if (!length)
return;
- Frame* frame = document()->frame();
+ LocalFrame* frame = document()->frame();
Settings* settings = frame->settings();
if (!frame->loader().client()->allowImage(!settings || settings->imagesEnabled(), document()->url()))
return;
- document()->cachedImage()->appendData(data, length);
+ if (document()->cachedImage())
+ document()->cachedImage()->appendData(data, length);
+ // Make sure the image renderer gets created because we need the renderer
+ // to read the aspect ratio. See crbug.com/320244
+ document()->updateRenderTreeIfNeeded();
document()->imageUpdated();
}
void ImageDocumentParser::finish()
{
- if (!isStopped() && document()->imageElement()) {
+ if (!isStopped() && document()->imageElement() && document()->cachedImage()) {
ImageResource* cachedImage = document()->cachedImage();
cachedImage->finish();
cachedImage->setResponse(document()->frame()->loader().documentLoader()->response());
@@ -162,7 +165,7 @@ void ImageDocumentParser::finish()
ImageDocument::ImageDocument(const DocumentInit& initializer)
: HTMLDocument(initializer, ImageDocumentClass)
- , m_imageElement(0)
+ , m_imageElement(nullptr)
, m_imageSizeIsKnown(false)
, m_didShrinkImage(false)
, m_shouldShrinkImage(shouldShrinkToFit())
@@ -171,27 +174,27 @@ ImageDocument::ImageDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> ImageDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> ImageDocument::createParser()
{
return ImageDocumentParser::create(this);
}
void ImageDocument::createDocumentStructure()
{
- RefPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*this);
appendChild(rootElement);
rootElement->insertedByParser();
if (frame())
frame()->loader().dispatchDocumentElementAvailable();
- RefPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
- RefPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*this);
meta->setAttribute(nameAttr, "viewport");
- meta->setAttribute(contentAttr, "width=device-width");
+ meta->setAttribute(contentAttr, "width=device-width, minimum-scale=0.1");
head->appendChild(meta);
- RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
+ RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this);
body->setAttribute(styleAttr, "margin: 0px;");
m_imageElement = HTMLImageElement::create(*this);
@@ -203,7 +206,7 @@ void ImageDocument::createDocumentStructure()
if (shouldShrinkToFit()) {
// Add event listeners
RefPtr<EventListener> listener = ImageEventListener::create(this);
- if (DOMWindow* domWindow = this->domWindow())
+ if (LocalDOMWindow* domWindow = this->domWindow())
domWindow->addEventListener("resize", listener, false);
m_imageElement->addEventListener("click", listener.release(), false);
}
@@ -224,15 +227,15 @@ float ImageDocument::scale() const
LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
LayoutSize windowSize = LayoutSize(view->width(), view->height());
- float widthScale = (float)windowSize.width() / imageSize.width();
- float heightScale = (float)windowSize.height() / imageSize.height();
+ float widthScale = windowSize.width().toFloat() / imageSize.width().toFloat();
+ float heightScale = windowSize.height().toFloat() / imageSize.height().toFloat();
return min(widthScale, heightScale);
}
-void ImageDocument::resizeImageToFit()
+void ImageDocument::resizeImageToFit(ScaleType type)
{
- if (!m_imageElement || m_imageElement->document() != this || pageZoomFactor(this) > 1)
+ if (!m_imageElement || m_imageElement->document() != this || (pageZoomFactor(this) > 1 && type == ScaleOnlyUnzoomedDocument))
return;
LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), pageZoomFactor(this));
@@ -241,7 +244,7 @@ void ImageDocument::resizeImageToFit()
m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomIn);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomIn);
}
void ImageDocument::imageClicked(int x, int y)
@@ -252,9 +255,9 @@ void ImageDocument::imageClicked(int x, int y)
m_shouldShrinkImage = !m_shouldShrinkImage;
if (m_shouldShrinkImage)
- windowSizeChanged();
+ windowSizeChanged(ScaleZoomedDocument);
else {
- restoreImageSize();
+ restoreImageSize(ScaleZoomedDocument);
updateLayout();
@@ -281,13 +284,13 @@ void ImageDocument::imageUpdated()
if (shouldShrinkToFit()) {
// Force resizing of the image
- windowSizeChanged();
+ windowSizeChanged(ScaleOnlyUnzoomedDocument);
}
}
-void ImageDocument::restoreImageSize()
+void ImageDocument::restoreImageSize(ScaleType type)
{
- if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this || pageZoomFactor(this) < 1)
+ if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this || (pageZoomFactor(this) < 1 && type == ScaleOnlyUnzoomedDocument))
return;
LayoutSize imageSize = m_imageElement->cachedImage()->imageSizeForRenderer(m_imageElement->renderer(), 1.0f);
@@ -297,7 +300,7 @@ void ImageDocument::restoreImageSize()
if (imageFitsInWindow())
m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
else
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomOut);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
m_didShrinkImage = false;
}
@@ -317,7 +320,7 @@ bool ImageDocument::imageFitsInWindow() const
return imageSize.width() <= windowSize.width() && imageSize.height() <= windowSize.height();
}
-void ImageDocument::windowSizeChanged()
+void ImageDocument::windowSizeChanged(ScaleType type)
{
if (!m_imageElement || !m_imageSizeIsKnown || m_imageElement->document() != this)
return;
@@ -330,7 +333,7 @@ void ImageDocument::windowSizeChanged()
if (fitsInWindow)
m_imageElement->removeInlineStyleProperty(CSSPropertyCursor);
else
- m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueWebkitZoomOut);
+ m_imageElement->setInlineStyleProperty(CSSPropertyCursor, CSSValueZoomOut);
return;
}
@@ -338,13 +341,13 @@ void ImageDocument::windowSizeChanged()
// If the window has been resized so that the image fits, restore the image size
// otherwise update the restored image size.
if (fitsInWindow)
- restoreImageSize();
+ restoreImageSize(type);
else
- resizeImageToFit();
+ resizeImageToFit(type);
} else {
// If the image isn't resized but needs to be, then resize it.
if (!fitsInWindow) {
- resizeImageToFit();
+ resizeImageToFit(type);
m_didShrinkImage = true;
}
}
@@ -363,18 +366,26 @@ bool ImageDocument::shouldShrinkToFit() const
return frame()->settings()->shrinksStandaloneImagesToFit() && frame()->isMainFrame();
}
+#if !ENABLE(OILPAN)
void ImageDocument::dispose()
{
- m_imageElement = 0;
+ m_imageElement = nullptr;
HTMLDocument::dispose();
}
+#endif
+
+void ImageDocument::trace(Visitor* visitor)
+{
+ visitor->trace(m_imageElement);
+ HTMLDocument::trace(visitor);
+}
// --------
void ImageEventListener::handleEvent(ExecutionContext*, Event* event)
{
if (event->type() == EventTypeNames::resize)
- m_doc->windowSizeChanged();
+ m_doc->windowSizeChanged(ImageDocument::ScaleOnlyUnzoomedDocument);
else if (event->type() == EventTypeNames::click && event->isMouseEvent()) {
MouseEvent* mouseEvent = toMouseEvent(event);
m_doc->imageClicked(mouseEvent->x(), mouseEvent->y());
diff --git a/chromium/third_party/WebKit/Source/core/html/ImageDocument.h b/chromium/third_party/WebKit/Source/core/html/ImageDocument.h
index 896a46261da..b52f08f34e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/ImageDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/ImageDocument.h
@@ -35,32 +35,41 @@ class HTMLImageElement;
class ImageDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<ImageDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<ImageDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new ImageDocument(initializer));
+ return adoptRefWillBeNoop(new ImageDocument(initializer));
}
+ enum ScaleType {
+ ScaleZoomedDocument,
+ ScaleOnlyUnzoomedDocument
+ };
+
ImageResource* cachedImage();
HTMLImageElement* imageElement() const { return m_imageElement.get(); }
- void windowSizeChanged();
+ void windowSizeChanged(ScaleType);
void imageUpdated();
void imageClicked(int x, int y);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- ImageDocument(const DocumentInit&);
+ explicit ImageDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
+#if !ENABLE(OILPAN)
virtual void dispose() OVERRIDE;
+#endif
void createDocumentStructure();
- void resizeImageToFit();
- void restoreImageSize();
+ void resizeImageToFit(ScaleType);
+ void restoreImageSize(ScaleType);
bool imageFitsInWindow() const;
bool shouldShrinkToFit() const;
float scale() const;
- RefPtr<HTMLImageElement> m_imageElement;
+ RefPtrWillBeMember<HTMLImageElement> m_imageElement;
// Whether enough of the image has been loaded to determine its size
bool m_imageSizeIsKnown;
diff --git a/chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp b/chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp
index ad302516baf..5233425facd 100644
--- a/chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LabelableElement.cpp
@@ -39,12 +39,17 @@ LabelableElement::~LabelableElement()
{
}
-PassRefPtr<NodeList> LabelableElement::labels()
+PassRefPtrWillBeRawPtr<LabelsNodeList> LabelableElement::labels()
{
if (!supportLabels())
- return 0;
+ return nullptr;
- return ensureRareData().ensureNodeLists().addCacheWithAtomicName<LabelsNodeList>(this, LabelsNodeListType, starAtom);
+ return ensureRareData().ensureNodeLists().addCache<LabelsNodeList>(*this, LabelsNodeListType);
+}
+
+void LabelableElement::trace(Visitor* visitor)
+{
+ HTMLElement::trace(visitor);
}
} // namespace Webcore
diff --git a/chromium/third_party/WebKit/Source/core/html/LabelableElement.h b/chromium/third_party/WebKit/Source/core/html/LabelableElement.h
index f3d2188dbfb..b633b8ab5a5 100644
--- a/chromium/third_party/WebKit/Source/core/html/LabelableElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/LabelableElement.h
@@ -35,14 +35,18 @@
namespace WebCore {
+class LabelsNodeList;
+
// LabelableElement represents "labelable element" defined in the HTML
// specification, and provides the implementation of the "labels" attribute.
class LabelableElement : public HTMLElement {
public:
virtual ~LabelableElement();
- PassRefPtr<NodeList> labels();
+ PassRefPtrWillBeRawPtr<LabelsNodeList> labels();
virtual bool supportLabels() const { return false; }
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
LabelableElement(const QualifiedName& tagName, Document&);
@@ -50,12 +54,17 @@ private:
virtual bool isLabelable() const OVERRIDE FINAL { return true; }
};
-inline bool isLabelableElement(const Node& node)
+inline bool isLabelableElement(const Element& element)
+{
+ return element.isHTMLElement() && toHTMLElement(element).isLabelable();
+}
+
+inline bool isLabelableElement(const HTMLElement& element)
{
- return node.isHTMLElement() && toHTMLElement(node).isLabelable();
+ return element.isLabelable();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(LabelableElement);
+DEFINE_HTMLELEMENT_TYPE_CASTS_WITH_FUNCTION(LabelableElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp b/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
index a3a6579370f..389af27af5f 100644
--- a/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "core/html/LabelsNodeList.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "core/dom/NodeRareData.h"
#include "core/html/HTMLLabelElement.h"
@@ -33,19 +33,21 @@ namespace WebCore {
using namespace HTMLNames;
-LabelsNodeList::LabelsNodeList(Node* ownerNode)
+LabelsNodeList::LabelsNodeList(ContainerNode& ownerNode)
: LiveNodeList(ownerNode, LabelsNodeListType, InvalidateOnForAttrChange, NodeListIsRootedAtDocument)
{
}
LabelsNodeList::~LabelsNodeList()
{
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, LabelsNodeListType, starAtom);
+#if !ENABLE(OILPAN)
+ ownerNode().nodeLists()->removeCache(this, LabelsNodeListType);
+#endif
}
-bool LabelsNodeList::nodeMatches(Element* testNode) const
+bool LabelsNodeList::elementMatches(const Element& element) const
{
- return isHTMLLabelElement(testNode) && toHTMLLabelElement(testNode)->control() == ownerNode();
+ return isHTMLLabelElement(element) && toHTMLLabelElement(element).control() == ownerNode();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h b/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h
index 0e5b125ca69..4a8a485be33 100644
--- a/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/html/LabelsNodeList.h
@@ -32,18 +32,18 @@ namespace WebCore {
class LabelsNodeList FINAL : public LiveNodeList {
public:
- static PassRefPtr<LabelsNodeList> create(Node* ownerNode, CollectionType type, const AtomicString&)
+ static PassRefPtrWillBeRawPtr<LabelsNodeList> create(ContainerNode& ownerNode, CollectionType type)
{
ASSERT_UNUSED(type, type == LabelsNodeListType);
- return adoptRef(new LabelsNodeList(ownerNode));
+ return adoptRefWillBeNoop(new LabelsNodeList(ownerNode));
}
virtual ~LabelsNodeList();
protected:
- explicit LabelsNodeList(Node*);
+ explicit LabelsNodeList(ContainerNode&);
- virtual bool nodeMatches(Element*) const;
+ virtual bool elementMatches(const Element&) const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkImport.cpp b/chromium/third_party/WebKit/Source/core/html/LinkImport.cpp
deleted file mode 100644
index 18e5d4a51a7..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/LinkImport.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/LinkImport.h"
-
-#include "core/dom/Document.h"
-#include "core/fetch/CrossOriginAccessControl.h"
-#include "core/html/HTMLImportChild.h"
-#include "core/html/HTMLImportsController.h"
-#include "core/html/HTMLLinkElement.h"
-
-
-namespace WebCore {
-
-PassOwnPtr<LinkImport> LinkImport::create(HTMLLinkElement* owner)
-{
- return adoptPtr(new LinkImport(owner));
-}
-
-LinkImport::LinkImport(HTMLLinkElement* owner)
- : LinkResource(owner)
- , m_loader(0)
-{
-}
-
-LinkImport::~LinkImport()
-{
- clear();
-}
-
-Document* LinkImport::importedDocument() const
-{
- if (!m_loader)
- return 0;
- return m_loader->importedDocument();
-}
-
-void LinkImport::process()
-{
- if (m_loader)
- return;
- if (!m_owner)
- return;
- if (!shouldLoadResource())
- return;
-
- if (!m_owner->document().import()) {
- ASSERT(m_owner->document().frame()); // The document should be the master.
- HTMLImportsController::provideTo(&m_owner->document());
- }
-
- LinkRequestBuilder builder(m_owner);
- if (!builder.isValid()) {
- didFinish();
- return;
- }
-
- HTMLImport* parent = m_owner->document().import();
- HTMLImportsController* controller = parent->controller();
- m_loader = controller->load(parent, this, builder.build(true));
- if (!m_loader) {
- didFinish();
- return;
- }
-}
-
-void LinkImport::clear()
-{
- m_owner = 0;
- if (m_loader) {
- m_loader->clearClient();
- m_loader = 0;
- }
-}
-
-void LinkImport::ownerRemoved()
-{
- clear();
-}
-
-void LinkImport::didFinish()
-{
- if (!m_owner)
- return;
- m_owner->scheduleEvent();
-}
-
-void LinkImport::loaderWillBeDestroyed()
-{
- clear();
-}
-
-bool LinkImport::hasLoaded() const
-{
- return m_loader && m_loader->isLoaded();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkImport.h b/chromium/third_party/WebKit/Source/core/html/LinkImport.h
deleted file mode 100644
index bc2ec95bfb5..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/LinkImport.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LinkImport_h
-#define LinkImport_h
-
-#include "core/html/HTMLImportChildClient.h"
-#include "core/html/LinkResource.h"
-#include "wtf/FastAllocBase.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class Document;
-class HTMLImportChild;
-
-//
-// A LinkResource subclasss used for @rel=import.
-//
-class LinkImport : public LinkResource, public HTMLImportChildClient {
- WTF_MAKE_FAST_ALLOCATED;
-public:
-
- static PassOwnPtr<LinkImport> create(HTMLLinkElement* owner);
-
- explicit LinkImport(HTMLLinkElement* owner);
- virtual ~LinkImport();
-
- // LinkResource
- virtual void process() OVERRIDE;
- virtual Type type() const OVERRIDE { return Import; }
- virtual void ownerRemoved() OVERRIDE;
- virtual bool hasLoaded() const OVERRIDE;
-
- // HTMLImportChildClient
- virtual void didFinish() OVERRIDE;
- virtual void loaderWillBeDestroyed() OVERRIDE;
-
- Document* importedDocument() const;
-
-private:
- void clear();
-
- HTMLImportChild* m_loader;
-};
-
-} // namespace WebCore
-
-#endif // LinkImport_h
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkManifest.cpp b/chromium/third_party/WebKit/Source/core/html/LinkManifest.cpp
new file mode 100644
index 00000000000..09153932596
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/LinkManifest.cpp
@@ -0,0 +1,47 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/LinkManifest.h"
+
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/loader/FrameLoaderClient.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<LinkManifest> LinkManifest::create(HTMLLinkElement* owner)
+{
+ return adoptPtrWillBeNoop(new LinkManifest(owner));
+}
+
+LinkManifest::LinkManifest(HTMLLinkElement* owner)
+ : LinkResource(owner)
+{
+}
+
+LinkManifest::~LinkManifest()
+{
+}
+
+void LinkManifest::process()
+{
+ if (!m_owner || !m_owner->document().frame())
+ return;
+
+ m_owner->document().frame()->loader().client()->dispatchDidChangeManifest();
+}
+
+bool LinkManifest::hasLoaded() const
+{
+ return false;
+}
+
+void LinkManifest::ownerRemoved()
+{
+ process();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkManifest.h b/chromium/third_party/WebKit/Source/core/html/LinkManifest.h
new file mode 100644
index 00000000000..c89b449818e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/LinkManifest.h
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LinkManifest_h
+#define LinkManifest_h
+
+#include "core/html/LinkResource.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class HTMLLinkElement;
+
+class LinkManifest FINAL : public LinkResource {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+
+ static PassOwnPtrWillBeRawPtr<LinkManifest> create(HTMLLinkElement* owner);
+
+ virtual ~LinkManifest();
+
+ // LinkResource
+ virtual void process() OVERRIDE;
+ virtual Type type() const OVERRIDE { return Manifest; }
+ virtual bool hasLoaded() const OVERRIDE;
+ virtual void ownerRemoved() OVERRIDE;
+
+private:
+ explicit LinkManifest(HTMLLinkElement* owner);
+};
+
+}
+
+#endif // LinkManifest_h
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp b/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp
index 0c2f32be4ca..bc2d746167e 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.cpp
@@ -32,22 +32,10 @@
#include "config.h"
#include "core/html/LinkRelAttribute.h"
-#include "wtf/text/WTFString.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-LinkRelAttribute::LinkRelAttribute()
- : m_iconType(InvalidIcon)
- , m_isStyleSheet(false)
- , m_isAlternate(false)
- , m_isDNSPrefetch(false)
- , m_isLinkPrefetch(false)
- , m_isLinkSubresource(false)
- , m_isLinkPrerender(false)
- , m_isImport(false)
-{
-}
-
LinkRelAttribute::LinkRelAttribute(const String& rel)
: m_iconType(InvalidIcon)
, m_isStyleSheet(false)
@@ -56,51 +44,53 @@ LinkRelAttribute::LinkRelAttribute(const String& rel)
, m_isLinkPrefetch(false)
, m_isLinkSubresource(false)
, m_isLinkPrerender(false)
+ , m_isLinkNext(false)
, m_isImport(false)
+ , m_isManifest(false)
+ , m_isTransitionExitingStylesheet(false)
{
- if (equalIgnoringCase(rel, "stylesheet"))
- m_isStyleSheet = true;
- else if (equalIgnoringCase(rel, "icon") || equalIgnoringCase(rel, "shortcut icon"))
- m_iconType = Favicon;
-#if ENABLE(TOUCH_ICON_LOADING)
- else if (equalIgnoringCase(rel, "apple-touch-icon"))
- m_iconType = TouchIcon;
- else if (equalIgnoringCase(rel, "apple-touch-icon-precomposed"))
- m_iconType = TouchPrecomposedIcon;
-#endif
- else if (equalIgnoringCase(rel, "dns-prefetch"))
- m_isDNSPrefetch = true;
- else if (equalIgnoringCase(rel, "alternate stylesheet") || equalIgnoringCase(rel, "stylesheet alternate")) {
- m_isStyleSheet = true;
- m_isAlternate = true;
- } else if (equalIgnoringCase(rel, "import")) {
- m_isImport = true;
- } else {
- // Tokenize the rel attribute and set bits based on specific keywords that we find.
- String relCopy = rel;
- relCopy.replace('\n', ' ');
- Vector<String> list;
- relCopy.split(' ', list);
- Vector<String>::const_iterator end = list.end();
- for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
- if (equalIgnoringCase(*it, "stylesheet"))
+ if (rel.isEmpty())
+ return;
+ String relCopy = rel;
+ relCopy.replace('\n', ' ');
+ Vector<String> list;
+ relCopy.split(' ', list);
+ Vector<String>::const_iterator end = list.end();
+ for (Vector<String>::const_iterator it = list.begin(); it != end; ++it) {
+ if (equalIgnoringCase(*it, "stylesheet")) {
+ if (!m_isImport)
m_isStyleSheet = true;
- else if (equalIgnoringCase(*it, "alternate"))
- m_isAlternate = true;
- else if (equalIgnoringCase(*it, "icon"))
- m_iconType = Favicon;
-#if ENABLE(TOUCH_ICON_LOADING)
- else if (equalIgnoringCase(*it, "apple-touch-icon"))
+ } else if (equalIgnoringCase(*it, "import")) {
+ if (!m_isStyleSheet)
+ m_isImport = true;
+ } else if (equalIgnoringCase(*it, "alternate")) {
+ m_isAlternate = true;
+ } else if (equalIgnoringCase(*it, "icon")) {
+ // This also allows "shortcut icon" since we just ignore the non-standard "shortcut" token.
+ // FIXME: This doesn't really follow the spec that requires "shortcut icon" to be the
+ // entire string http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#rel-icon
+ m_iconType = Favicon;
+ } else if (equalIgnoringCase(*it, "prefetch")) {
+ m_isLinkPrefetch = true;
+ } else if (equalIgnoringCase(*it, "dns-prefetch")) {
+ m_isDNSPrefetch = true;
+ } else if (equalIgnoringCase(*it, "subresource")) {
+ m_isLinkSubresource = true;
+ } else if (equalIgnoringCase(*it, "prerender")) {
+ m_isLinkPrerender = true;
+ } else if (equalIgnoringCase(*it, "next")) {
+ m_isLinkNext = true;
+ } else if (equalIgnoringCase(*it, "apple-touch-icon")) {
+ if (RuntimeEnabledFeatures::touchIconLoadingEnabled())
m_iconType = TouchIcon;
- else if (equalIgnoringCase(*it, "apple-touch-icon-precomposed"))
+ } else if (equalIgnoringCase(*it, "apple-touch-icon-precomposed")) {
+ if (RuntimeEnabledFeatures::touchIconLoadingEnabled())
m_iconType = TouchPrecomposedIcon;
-#endif
- else if (equalIgnoringCase(*it, "prefetch"))
- m_isLinkPrefetch = true;
- else if (equalIgnoringCase(*it, "subresource"))
- m_isLinkSubresource = true;
- else if (equalIgnoringCase(*it, "prerender"))
- m_isLinkPrerender = true;
+ } else if (equalIgnoringCase(*it, "manifest")) {
+ m_isManifest = true;
+ } else if (equalIgnoringCase(rel, "transition-exiting-stylesheet")) {
+ if (RuntimeEnabledFeatures::navigationTransitionsEnabled())
+ m_isTransitionExitingStylesheet = true;
}
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h b/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h
index a124012055d..d4424100e93 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h
+++ b/chromium/third_party/WebKit/Source/core/html/LinkRelAttribute.h
@@ -33,17 +33,13 @@
#define LinkRelAttribute_h
#include "core/dom/IconURL.h"
-
-namespace WTF {
-class String;
-}
+#include "wtf/text/WTFString.h"
namespace WebCore {
class LinkRelAttribute {
public:
- LinkRelAttribute();
- explicit LinkRelAttribute(const String&);
+ explicit LinkRelAttribute(const String& = "");
bool isStyleSheet() const { return m_isStyleSheet; }
IconType iconType() const { return m_iconType; }
@@ -52,7 +48,10 @@ public:
bool isLinkPrefetch() const { return m_isLinkPrefetch; }
bool isLinkSubresource() const { return m_isLinkSubresource; }
bool isLinkPrerender() const { return m_isLinkPrerender; }
+ bool isLinkNext() const { return m_isLinkNext; }
bool isImport() const { return m_isImport; }
+ bool isManifest() const { return m_isManifest; }
+ bool isTransitionExitingStylesheet() const { return m_isTransitionExitingStylesheet; }
private:
IconType m_iconType;
@@ -62,7 +61,10 @@ private:
bool m_isLinkPrefetch : 1;
bool m_isLinkSubresource : 1;
bool m_isLinkPrerender : 1;
+ bool m_isLinkNext : 1;
bool m_isImport : 1;
+ bool m_isManifest : 1;
+ bool m_isTransitionExitingStylesheet : 1;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp b/chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp
index beac0e64066..e75ea4d97eb 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LinkRelAttributeTest.cpp
@@ -30,6 +30,7 @@
#include "config.h"
#include "core/html/LinkRelAttribute.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/text/CString.h"
#include <gtest/gtest.h>
@@ -38,6 +39,22 @@ using namespace WebCore;
namespace {
+class LinkRelAttributeTest : public testing::Test {
+protected:
+ virtual void SetUp()
+ {
+ m_touchIconLoadingEnabled = RuntimeEnabledFeatures::touchIconLoadingEnabled();
+ }
+
+ virtual void TearDown()
+ {
+ RuntimeEnabledFeatures::setTouchIconLoadingEnabled(m_touchIconLoadingEnabled);
+ }
+
+private:
+ bool m_touchIconLoadingEnabled;
+};
+
static inline void testLinkRelAttribute(String value, bool isStyleSheet, IconType iconType, bool isAlternate, bool isDNSPrefetch, bool isLinkSubresource, bool isLinkPrerender, bool isImport = false)
{
LinkRelAttribute linkRelAttribute(value);
@@ -50,8 +67,10 @@ static inline void testLinkRelAttribute(String value, bool isStyleSheet, IconTyp
ASSERT_EQ(isImport, linkRelAttribute.isImport()) << value.utf8().data();
}
-TEST(CoreLinkRelAttribute, Constructor)
+TEST_F(LinkRelAttributeTest, Constructor)
{
+ RuntimeEnabledFeatures::setTouchIconLoadingEnabled(false);
+
testLinkRelAttribute("stylesheet", true, InvalidIcon, false, false, false, false);
testLinkRelAttribute("sTyLeShEeT", true, InvalidIcon, false, false, false, false);
@@ -60,16 +79,48 @@ TEST(CoreLinkRelAttribute, Constructor)
testLinkRelAttribute("shortcut icon", false, Favicon, false, false, false, false);
testLinkRelAttribute("sHoRtCuT iCoN", false, Favicon, false, false, false, false);
-#if ENABLE(TOUCH_ICON_LOADING)
- testLinkRelAttribute("apple-touch-icon", false, TouchIcon, false, false, false, false);
- testLinkRelAttribute("aPpLe-tOuCh-IcOn", false, TouchIcon, false, false, false, false);
+ testLinkRelAttribute("dns-prefetch", false, InvalidIcon, false, true, false, false);
+ testLinkRelAttribute("dNs-pReFeTcH", false, InvalidIcon, false, true, false, false);
- testLinkRelAttribute("apple-touch-icon-precomposed", false, TouchPrecomposedIcon, false, false, false, false);
- testLinkRelAttribute("aPpLe-tOuCh-IcOn-pReCoMpOsEd", false, TouchPrecomposedIcon, false, false, false, false);
-#endif
+ testLinkRelAttribute("apple-touch-icon", false, InvalidIcon, false, false, false, false);
+ testLinkRelAttribute("aPpLe-tOuCh-IcOn", false, InvalidIcon, false, false, false, false);
+ testLinkRelAttribute("apple-touch-icon-precomposed", false, InvalidIcon, false, false, false, false);
+ testLinkRelAttribute("aPpLe-tOuCh-IcOn-pReCoMpOsEd", false, InvalidIcon, false, false, false, false);
+
+ testLinkRelAttribute("alternate stylesheet", true, InvalidIcon, true, false, false, false);
+ testLinkRelAttribute("stylesheet alternate", true, InvalidIcon, true, false, false, false);
+ testLinkRelAttribute("aLtErNaTe sTyLeShEeT", true, InvalidIcon, true, false, false, false);
+ testLinkRelAttribute("sTyLeShEeT aLtErNaTe", true, InvalidIcon, true, false, false, false);
+
+ testLinkRelAttribute("stylesheet icon prerender aLtErNaTe", true, Favicon, true, false, false, true);
+ testLinkRelAttribute("alternate subresource", false, InvalidIcon, true, false, true, false);
+ testLinkRelAttribute("alternate icon stylesheet", true, Favicon, true, false, false, false);
+
+ testLinkRelAttribute("import", false, InvalidIcon, false, false, false, false, true);
+ // "import" is mutually exclusive and "stylesheet" wins when they conflict.
+ testLinkRelAttribute("stylesheet import", true, InvalidIcon, false, false, false, false, false);
+}
+
+TEST_F(LinkRelAttributeTest, ConstructorTouchIconLoadingEnabled)
+{
+ RuntimeEnabledFeatures::setTouchIconLoadingEnabled(true);
+
+ testLinkRelAttribute("stylesheet", true, InvalidIcon, false, false, false, false);
+ testLinkRelAttribute("sTyLeShEeT", true, InvalidIcon, false, false, false, false);
+
+ testLinkRelAttribute("icon", false, Favicon, false, false, false, false);
+ testLinkRelAttribute("iCoN", false, Favicon, false, false, false, false);
+ testLinkRelAttribute("shortcut icon", false, Favicon, false, false, false, false);
+ testLinkRelAttribute("sHoRtCuT iCoN", false, Favicon, false, false, false, false);
testLinkRelAttribute("dns-prefetch", false, InvalidIcon, false, true, false, false);
testLinkRelAttribute("dNs-pReFeTcH", false, InvalidIcon, false, true, false, false);
+ testLinkRelAttribute("alternate dNs-pReFeTcH", false, InvalidIcon, true, true, false, false);
+
+ testLinkRelAttribute("apple-touch-icon", false, TouchIcon, false, false, false, false);
+ testLinkRelAttribute("aPpLe-tOuCh-IcOn", false, TouchIcon, false, false, false, false);
+ testLinkRelAttribute("apple-touch-icon-precomposed", false, TouchPrecomposedIcon, false, false, false, false);
+ testLinkRelAttribute("aPpLe-tOuCh-IcOn-pReCoMpOsEd", false, TouchPrecomposedIcon, false, false, false, false);
testLinkRelAttribute("alternate stylesheet", true, InvalidIcon, true, false, false, false);
testLinkRelAttribute("stylesheet alternate", true, InvalidIcon, true, false, false, false);
@@ -81,7 +132,7 @@ TEST(CoreLinkRelAttribute, Constructor)
testLinkRelAttribute("alternate icon stylesheet", true, Favicon, true, false, false, false);
testLinkRelAttribute("import", false, InvalidIcon, false, false, false, false, true);
- // "import" is mutually exclusive and "stylesheet" wins when they conflict.
+ testLinkRelAttribute("alternate import", false, InvalidIcon, true, false, false, false, true);
testLinkRelAttribute("stylesheet import", true, InvalidIcon, false, false, false, false, false);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkResource.cpp b/chromium/third_party/WebKit/Source/core/html/LinkResource.cpp
index ef239527a14..850fbd40d6d 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/LinkResource.cpp
@@ -31,9 +31,10 @@
#include "config.h"
#include "core/html/LinkResource.h"
-#include "HTMLNames.h"
-#include "core/html/HTMLImport.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/html/HTMLLinkElement.h"
+#include "core/html/imports/HTMLImportsController.h"
namespace WebCore {
@@ -50,15 +51,20 @@ LinkResource::~LinkResource()
bool LinkResource::shouldLoadResource() const
{
- return m_owner->document().frame() || m_owner->document().import();
+ return m_owner->document().frame() || m_owner->document().importsController();
}
-Frame* LinkResource::loadingFrame() const
+LocalFrame* LinkResource::loadingFrame() const
{
- HTMLImport* import = m_owner->document().import();
- if (!import)
+ HTMLImportsController* importsController = m_owner->document().importsController();
+ if (!importsController)
return m_owner->document().frame();
- return import->master()->document().frame();
+ return importsController->master()->frame();
+}
+
+void LinkResource::trace(Visitor* visitor)
+{
+ visitor->trace(m_owner);
}
LinkRequestBuilder::LinkRequestBuilder(HTMLLinkElement* owner)
diff --git a/chromium/third_party/WebKit/Source/core/html/LinkResource.h b/chromium/third_party/WebKit/Source/core/html/LinkResource.h
index a922639d216..93815b08526 100644
--- a/chromium/third_party/WebKit/Source/core/html/LinkResource.h
+++ b/chromium/third_party/WebKit/Source/core/html/LinkResource.h
@@ -32,6 +32,7 @@
#define LinkResource_h
#include "core/fetch/FetchRequest.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/text/WTFString.h"
@@ -39,30 +40,35 @@ namespace WebCore {
class HTMLLinkElement;
-class LinkResource {
- WTF_MAKE_NONCOPYABLE(LinkResource); WTF_MAKE_FAST_ALLOCATED;
+class LinkResource : public NoBaseWillBeGarbageCollectedFinalized<LinkResource> {
+ WTF_MAKE_NONCOPYABLE(LinkResource); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
enum Type {
Style,
- Import
+ Import,
+ Manifest
};
explicit LinkResource(HTMLLinkElement*);
virtual ~LinkResource();
bool shouldLoadResource() const;
- Frame* loadingFrame() const;
+ LocalFrame* loadingFrame() const;
virtual Type type() const = 0;
virtual void process() = 0;
- virtual void ownerRemoved() = 0;
+ virtual void ownerRemoved() { }
+ virtual void ownerInserted() { }
virtual bool hasLoaded() const = 0;
+ virtual void trace(Visitor*);
+
protected:
- HTMLLinkElement* m_owner;
+ RawPtrWillBeMember<HTMLLinkElement> m_owner;
};
class LinkRequestBuilder {
+ STACK_ALLOCATED();
public:
explicit LinkRequestBuilder(HTMLLinkElement* owner);
@@ -72,7 +78,7 @@ public:
FetchRequest build(bool blocking) const;
private:
- HTMLLinkElement* m_owner;
+ RawPtrWillBeMember<HTMLLinkElement> m_owner;
KURL m_url;
AtomicString m_charset;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaController.cpp b/chromium/third_party/WebKit/Source/core/html/MediaController.cpp
index e93bbc1df30..2cf4b0a9863 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaController.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/MediaController.cpp
@@ -30,6 +30,9 @@
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/ExecutionContext.h"
+#include "core/events/Event.h"
+#include "core/events/GenericEventQueue.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/TimeRanges.h"
#include "platform/Clock.h"
@@ -37,12 +40,11 @@
#include "wtf/StdLibExtras.h"
#include "wtf/text/AtomicString.h"
-using namespace WebCore;
-using namespace std;
+namespace WebCore {
-PassRefPtr<MediaController> MediaController::create(ExecutionContext* context)
+PassRefPtrWillBeRawPtr<MediaController> MediaController::create(ExecutionContext* context)
{
- return adoptRef(new MediaController(context));
+ return adoptRefWillBeRefCountedGarbageCollected(new MediaController(context));
}
MediaController::MediaController(ExecutionContext* context)
@@ -51,11 +53,10 @@ MediaController::MediaController(ExecutionContext* context)
, m_volume(1)
, m_position(MediaPlayer::invalidTime())
, m_muted(false)
- , m_readyState(HAVE_NOTHING)
+ , m_readyState(HTMLMediaElement::HAVE_NOTHING)
, m_playbackState(WAITING)
- , m_asyncEventTimer(this, &MediaController::asyncEventTimerFired)
+ , m_pendingEventsQueue(GenericEventQueue::create(this))
, m_clearPositionTimer(this, &MediaController::clearPositionTimerFired)
- , m_closedCaptionsVisible(false)
, m_clock(Clock::create())
, m_executionContext(context)
, m_timeupdateTimer(this, &MediaController::timeupdateTimerFired)
@@ -73,7 +74,7 @@ void MediaController::addMediaElement(HTMLMediaElement* element)
ASSERT(element);
ASSERT(!m_mediaElements.contains(element));
- m_mediaElements.append(element);
+ m_mediaElements.add(element);
bringElementUpToSpeed(element);
}
@@ -84,11 +85,6 @@ void MediaController::removeMediaElement(HTMLMediaElement* element)
m_mediaElements.remove(m_mediaElements.find(element));
}
-bool MediaController::containsMediaElement(HTMLMediaElement* element) const
-{
- return m_mediaElements.contains(element);
-}
-
PassRefPtr<TimeRanges> MediaController::buffered() const
{
if (m_mediaElements.isEmpty())
@@ -97,9 +93,10 @@ PassRefPtr<TimeRanges> MediaController::buffered() const
// The buffered attribute must return a new static normalized TimeRanges object that represents
// the intersection of the ranges of the media resources of the slaved media elements that the
// user agent has buffered, at the time the attribute is evaluated.
- RefPtr<TimeRanges> bufferedRanges = m_mediaElements.first()->buffered();
- for (size_t index = 1; index < m_mediaElements.size(); ++index)
- bufferedRanges->intersectWith(m_mediaElements[index]->buffered().get());
+ MediaElementSequence::const_iterator it = m_mediaElements.begin();
+ RefPtr<TimeRanges> bufferedRanges = (*it)->buffered();
+ for (++it; it != m_mediaElements.end(); ++it)
+ bufferedRanges->intersectWith((*it)->buffered().get());
return bufferedRanges;
}
@@ -111,9 +108,10 @@ PassRefPtr<TimeRanges> MediaController::seekable() const
// The seekable attribute must return a new static normalized TimeRanges object that represents
// the intersection of the ranges of the media resources of the slaved media elements that the
// user agent is able to seek to, at the time the attribute is evaluated.
- RefPtr<TimeRanges> seekableRanges = m_mediaElements.first()->seekable();
- for (size_t index = 1; index < m_mediaElements.size(); ++index)
- seekableRanges->intersectWith(m_mediaElements[index]->seekable().get());
+ MediaElementSequence::const_iterator it = m_mediaElements.begin();
+ RefPtr<TimeRanges> seekableRanges = (*it)->seekable();
+ for (++it; it != m_mediaElements.end(); ++it)
+ seekableRanges->intersectWith((*it)->seekable().get());
return seekableRanges;
}
@@ -125,9 +123,10 @@ PassRefPtr<TimeRanges> MediaController::played()
// The played attribute must return a new static normalized TimeRanges object that represents
// the union of the ranges of the media resources of the slaved media elements that the
// user agent has so far rendered, at the time the attribute is evaluated.
- RefPtr<TimeRanges> playedRanges = m_mediaElements.first()->played();
- for (size_t index = 1; index < m_mediaElements.size(); ++index)
- playedRanges->unionWith(m_mediaElements[index]->played().get());
+ MediaElementSequence::const_iterator it = m_mediaElements.begin();
+ RefPtr<TimeRanges> playedRanges = (*it)->played();
+ for (++it; it != m_mediaElements.end(); ++it)
+ playedRanges->unionWith((*it)->played().get());
return playedRanges;
}
@@ -136,11 +135,11 @@ double MediaController::duration() const
// FIXME: Investigate caching the maximum duration and only updating the cached value
// when the slaved media elements' durations change.
double maxDuration = 0;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- double duration = m_mediaElements[index]->duration();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it) {
+ double duration = (*it)->duration();
if (std::isnan(duration))
continue;
- maxDuration = max(maxDuration, duration);
+ maxDuration = std::max(maxDuration, duration);
}
return maxDuration;
}
@@ -152,8 +151,8 @@ double MediaController::currentTime() const
if (m_position == MediaPlayer::invalidTime()) {
// Some clocks may return times outside the range of [0..duration].
- m_position = max(0.0, min(duration(), m_clock->currentTime()));
- m_clearPositionTimer.startOneShot(0);
+ m_position = std::max(0.0, std::min(duration(), m_clock->currentTime()));
+ m_clearPositionTimer.startOneShot(0, FROM_HERE);
}
return m_position;
@@ -164,18 +163,19 @@ void MediaController::setCurrentTime(double time, ExceptionState& exceptionState
// When the user agent is to seek the media controller to a particular new playback position,
// it must follow these steps:
// If the new playback position is less than zero, then set it to zero.
- time = max(0.0, time);
+ time = std::max(0.0, time);
// If the new playback position is greater than the media controller duration, then set it
// to the media controller duration.
- time = min(time, duration());
+ time = std::min(time, duration());
// Set the media controller position to the new playback position.
+ m_position = time;
m_clock->setCurrentTime(time);
// Seek each slaved media element to the new playback position relative to the media element timeline.
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->seek(time, exceptionState);
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->seek(time, exceptionState);
scheduleTimeupdateEvent();
}
@@ -198,8 +198,8 @@ void MediaController::play()
{
// When the play() method is invoked, the user agent must invoke the play method of each
// slaved media element in turn,
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->play();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->play();
// and then invoke the unpause method of the MediaController.
unpause();
@@ -246,8 +246,8 @@ void MediaController::setPlaybackRate(double rate)
// playback rate to the new value,
m_clock->setPlayRate(rate);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updatePlaybackRate();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->updatePlaybackRate();
// then queue a task to fire a simple event named ratechange at the MediaController.
scheduleEvent(EventTypeNames::ratechange);
@@ -261,7 +261,7 @@ void MediaController::setVolume(double level, ExceptionState& exceptionState)
// If the new value is outside the range 0.0 to 1.0 inclusive, then, on setting, an
// IndexSizeError exception must be raised instead.
if (level < 0 || level > 1) {
- exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::failedToSet("volume", "MediaController", "The value provided (" + String::number(level) + ") is not in the range [0.0, 1.0]."));
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("volume", level, 0.0, ExceptionMessages::InclusiveBound, 1.0, ExceptionMessages::InclusiveBound));
return;
}
@@ -272,8 +272,8 @@ void MediaController::setVolume(double level, ExceptionState& exceptionState)
// and queue a task to fire a simple event named volumechange at the MediaController.
scheduleEvent(EventTypeNames::volumechange);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updateVolume();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->updateVolume();
}
void MediaController::setMuted(bool flag)
@@ -288,8 +288,8 @@ void MediaController::setMuted(bool flag)
// and queue a task to fire a simple event named volumechange at the MediaController.
scheduleEvent(EventTypeNames::volumechange);
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updateVolume();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->updateVolume();
}
static const AtomicString& playbackStateWaiting()
@@ -331,18 +331,18 @@ void MediaController::reportControllerState()
updatePlaybackState();
}
-static AtomicString eventNameForReadyState(MediaControllerInterface::ReadyState state)
+static const AtomicString& eventNameForReadyState(HTMLMediaElement::ReadyState state)
{
switch (state) {
- case MediaControllerInterface::HAVE_NOTHING:
+ case HTMLMediaElement::HAVE_NOTHING:
return EventTypeNames::emptied;
- case MediaControllerInterface::HAVE_METADATA:
+ case HTMLMediaElement::HAVE_METADATA:
return EventTypeNames::loadedmetadata;
- case MediaControllerInterface::HAVE_CURRENT_DATA:
+ case HTMLMediaElement::HAVE_CURRENT_DATA:
return EventTypeNames::loadeddata;
- case MediaControllerInterface::HAVE_FUTURE_DATA:
+ case HTMLMediaElement::HAVE_FUTURE_DATA:
return EventTypeNames::canplay;
- case MediaControllerInterface::HAVE_ENOUGH_DATA:
+ case HTMLMediaElement::HAVE_ENOUGH_DATA:
return EventTypeNames::canplaythrough;
default:
ASSERT_NOT_REACHED();
@@ -357,13 +357,14 @@ void MediaController::updateReadyState()
if (m_mediaElements.isEmpty()) {
// If the MediaController has no slaved media elements, let new readiness state be 0.
- newReadyState = HAVE_NOTHING;
+ newReadyState = HTMLMediaElement::HAVE_NOTHING;
} else {
// Otherwise, let it have the lowest value of the readyState IDL attributes of all of its
// slaved media elements.
- newReadyState = m_mediaElements.first()->readyState();
- for (size_t index = 1; index < m_mediaElements.size(); ++index)
- newReadyState = min(newReadyState, m_mediaElements[index]->readyState());
+ MediaElementSequence::const_iterator it = m_mediaElements.begin();
+ newReadyState = (*it)->readyState();
+ for (++it; it != m_mediaElements.end(); ++it)
+ newReadyState = std::min(newReadyState, (*it)->readyState());
}
if (newReadyState == oldReadyState)
@@ -471,8 +472,8 @@ void MediaController::updatePlaybackState()
void MediaController::updateMediaElements()
{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->updatePlayState();
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it)
+ (*it)->updatePlayState();
}
void MediaController::bringElementUpToSpeed(HTMLMediaElement* element)
@@ -486,20 +487,51 @@ void MediaController::bringElementUpToSpeed(HTMLMediaElement* element)
element->seek(currentTime(), IGNORE_EXCEPTION);
}
+bool MediaController::isRestrained() const
+{
+ ASSERT(!m_mediaElements.isEmpty());
+
+ // A MediaController is a restrained media controller if the MediaController is a playing media
+ // controller,
+ if (m_paused)
+ return false;
+
+ bool anyAutoplayingAndPaused = false;
+ bool allPaused = true;
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it) {
+ HTMLMediaElement* element = *it;
+
+ // and none of its slaved media elements are blocked media elements,
+ if (element->isBlocked())
+ return false;
+
+ if (element->isAutoplaying() && element->paused())
+ anyAutoplayingAndPaused = true;
+
+ if (!element->paused())
+ allPaused = false;
+ }
+
+ // but either at least one of its slaved media elements whose autoplaying flag is true still has
+ // its paused attribute set to true, or, all of its slaved media elements have their paused
+ // attribute set to true.
+ return anyAutoplayingAndPaused || allPaused;
+}
+
bool MediaController::isBlocked() const
{
+ ASSERT(!m_mediaElements.isEmpty());
+
// A MediaController is a blocked media controller if the MediaController is a paused media
// controller,
if (m_paused)
return true;
- if (m_mediaElements.isEmpty())
- return false;
-
bool allPaused = true;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- HTMLMediaElement* element = m_mediaElements[index];
- // or if any of its slaved media elements are blocked media elements,
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it) {
+ HTMLMediaElement* element = *it;
+
+ // or if any of its slaved media elements are blocked media elements,
if (element->isBlocked())
return true;
@@ -528,8 +560,8 @@ bool MediaController::hasEnded() const
return false;
bool allHaveEnded = true;
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->ended())
+ for (MediaElementSequence::const_iterator it = m_mediaElements.begin(); it != m_mediaElements.end(); ++it) {
+ if (!(*it)->ended())
allHaveEnded = false;
}
return allHaveEnded;
@@ -537,19 +569,7 @@ bool MediaController::hasEnded() const
void MediaController::scheduleEvent(const AtomicString& eventName)
{
- m_pendingEvents.append(Event::createCancelable(eventName));
- if (!m_asyncEventTimer.isActive())
- m_asyncEventTimer.startOneShot(0);
-}
-
-void MediaController::asyncEventTimerFired(Timer<MediaController>*)
-{
- Vector<RefPtr<Event> > pendingEvents;
-
- m_pendingEvents.swap(pendingEvents);
- size_t count = pendingEvents.size();
- for (size_t index = 0; index < count; ++index)
- dispatchEvent(pendingEvents[index].release(), IGNORE_EXCEPTION);
+ m_pendingEventsQueue->enqueueEvent(Event::createCancelable(eventName));
}
void MediaController::clearPositionTimerFired(Timer<MediaController>*)
@@ -557,77 +577,6 @@ void MediaController::clearPositionTimerFired(Timer<MediaController>*)
m_position = MediaPlayer::invalidTime();
}
-bool MediaController::hasAudio() const
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasAudio())
- return true;
- }
- return false;
-}
-
-bool MediaController::hasVideo() const
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasVideo())
- return true;
- }
- return false;
-}
-
-bool MediaController::hasClosedCaptions() const
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (m_mediaElements[index]->hasClosedCaptions())
- return true;
- }
- return false;
-}
-
-void MediaController::setClosedCaptionsVisible(bool visible)
-{
- m_closedCaptionsVisible = visible;
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->setClosedCaptionsVisible(visible);
-}
-
-void MediaController::beginScrubbing()
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->beginScrubbing();
- if (m_playbackState == PLAYING)
- m_clock->stop();
-}
-
-void MediaController::endScrubbing()
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index)
- m_mediaElements[index]->endScrubbing();
- if (m_playbackState == PLAYING)
- m_clock->start();
-}
-
-bool MediaController::canPlay() const
-{
- if (m_paused)
- return true;
-
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->canPlay())
- return false;
- }
- return true;
-}
-
-bool MediaController::hasCurrentSrc() const
-{
- for (size_t index = 0; index < m_mediaElements.size(); ++index) {
- if (!m_mediaElements[index]->hasCurrentSrc())
- return false;
- }
- return true;
-}
-
const AtomicString& MediaController::interfaceName() const
{
return EventTargetNames::MediaController;
@@ -642,7 +591,7 @@ void MediaController::startTimeupdateTimer()
if (m_timeupdateTimer.isActive())
return;
- m_timeupdateTimer.startRepeating(maxTimeupdateEventFrequency);
+ m_timeupdateTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HERE);
}
void MediaController::timeupdateTimerFired(Timer<MediaController>*)
@@ -661,3 +610,13 @@ void MediaController::scheduleTimeupdateEvent()
scheduleEvent(EventTypeNames::timeupdate);
m_previousTimeupdateTime = now;
}
+
+void MediaController::trace(Visitor* visitor)
+{
+ visitor->trace(m_mediaElements);
+ visitor->trace(m_pendingEventsQueue);
+ visitor->trace(m_executionContext);
+ EventTargetWithInlineData::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaController.h b/chromium/third_party/WebKit/Source/core/html/MediaController.h
index 5b31cc24e18..c9311a906d7 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaController.h
+++ b/chromium/third_party/WebKit/Source/core/html/MediaController.h
@@ -27,84 +27,68 @@
#define MediaController_h
#include "bindings/v8/ScriptWrappable.h"
-#include "core/events/Event.h"
#include "core/events/EventTarget.h"
-#include "core/html/MediaControllerInterface.h"
-#include "platform/Timer.h"
+#include "core/html/HTMLMediaElement.h"
+#include "wtf/LinkedHashSet.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
namespace WebCore {
class Clock;
-class Event;
class ExceptionState;
-class HTMLMediaElement;
class ExecutionContext;
+class GenericEventQueue;
-class MediaController : public RefCounted<MediaController>, public ScriptWrappable, public MediaControllerInterface, public EventTargetWithInlineData {
+class MediaController FINAL : public RefCountedWillBeRefCountedGarbageCollected<MediaController>, public ScriptWrappable, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(MediaController);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MediaController);
public:
- static PassRefPtr<MediaController> create(ExecutionContext*);
+ static PassRefPtrWillBeRawPtr<MediaController> create(ExecutionContext*);
virtual ~MediaController();
void addMediaElement(HTMLMediaElement*);
void removeMediaElement(HTMLMediaElement*);
- bool containsMediaElement(HTMLMediaElement*) const;
- const String& mediaGroup() const { return m_mediaGroup; }
+ PassRefPtr<TimeRanges> buffered() const;
+ PassRefPtr<TimeRanges> seekable() const;
+ PassRefPtr<TimeRanges> played();
- virtual PassRefPtr<TimeRanges> buffered() const;
- virtual PassRefPtr<TimeRanges> seekable() const;
- virtual PassRefPtr<TimeRanges> played();
+ double duration() const;
+ double currentTime() const;
+ void setCurrentTime(double, ExceptionState&);
- virtual double duration() const;
- virtual double currentTime() const;
- virtual void setCurrentTime(double, ExceptionState&);
-
- virtual bool paused() const { return m_paused; }
- virtual void play();
- virtual void pause();
+ bool paused() const { return m_paused; }
+ void play();
+ void pause();
void unpause();
- virtual double defaultPlaybackRate() const { return m_defaultPlaybackRate; }
- virtual void setDefaultPlaybackRate(double);
+ double defaultPlaybackRate() const { return m_defaultPlaybackRate; }
+ void setDefaultPlaybackRate(double);
- virtual double playbackRate() const;
- virtual void setPlaybackRate(double);
+ double playbackRate() const;
+ void setPlaybackRate(double);
- virtual double volume() const { return m_volume; }
- virtual void setVolume(double, ExceptionState&);
+ double volume() const { return m_volume; }
+ void setVolume(double, ExceptionState&);
- virtual bool muted() const { return m_muted; }
- virtual void setMuted(bool);
+ bool muted() const { return m_muted; }
+ void setMuted(bool);
- virtual ReadyState readyState() const { return m_readyState; }
+ typedef HTMLMediaElement::ReadyState ReadyState;
+ ReadyState readyState() const { return m_readyState; }
enum PlaybackState { WAITING, PLAYING, ENDED };
const AtomicString& playbackState() const;
- virtual bool supportsFullscreen() const { return false; }
- virtual bool isFullscreen() const { return false; }
- virtual void enterFullscreen() { }
-
- virtual bool hasAudio() const;
- virtual bool hasVideo() const;
- virtual bool hasClosedCaptions() const;
- virtual void setClosedCaptionsVisible(bool);
- virtual bool closedCaptionsVisible() const { return m_closedCaptionsVisible; }
-
- virtual void beginScrubbing();
- virtual void endScrubbing();
-
- virtual bool canPlay() const;
-
- virtual bool hasCurrentSrc() const;
-
+ bool isRestrained() const;
bool isBlocked() const;
- void clearExecutionContext() { m_executionContext = 0; }
+#if !ENABLE(OILPAN)
+ void clearExecutionContext() { m_executionContext = nullptr; }
+#endif
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
MediaController(ExecutionContext*);
@@ -114,7 +98,6 @@ private:
void updateMediaElements();
void bringElementUpToSpeed(HTMLMediaElement*);
void scheduleEvent(const AtomicString& eventName);
- void asyncEventTimerFired(Timer<MediaController>*);
void clearPositionTimerFired(Timer<MediaController>*);
bool hasEnded() const;
void scheduleTimeupdateEvent();
@@ -127,7 +110,12 @@ private:
friend class HTMLMediaElement;
friend class MediaControllerEventListener;
- Vector<HTMLMediaElement*> m_mediaElements;
+ // FIXME: A MediaController should ideally keep an otherwise
+ // unreferenced slaved media element alive. When Oilpan is
+ // enabled by default, consider making the hash set references
+ // strong to accomplish that. crbug.com/383072
+ typedef WillBeHeapLinkedHashSet<RawPtrWillBeWeakMember<HTMLMediaElement> > MediaElementSequence;
+ MediaElementSequence m_mediaElements;
bool m_paused;
double m_defaultPlaybackRate;
double m_volume;
@@ -135,13 +123,10 @@ private:
bool m_muted;
ReadyState m_readyState;
PlaybackState m_playbackState;
- Vector<RefPtr<Event> > m_pendingEvents;
- Timer<MediaController> m_asyncEventTimer;
+ OwnPtrWillBeMember<GenericEventQueue> m_pendingEventsQueue;
mutable Timer<MediaController> m_clearPositionTimer;
- String m_mediaGroup;
- bool m_closedCaptionsVisible;
OwnPtr<Clock> m_clock;
- ExecutionContext* m_executionContext;
+ RawPtrWillBeWeakMember<ExecutionContext> m_executionContext;
Timer<MediaController> m_timeupdateTimer;
double m_previousTimeupdateTime;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaController.idl b/chromium/third_party/WebKit/Source/core/html/MediaController.idl
index ad46115d889..8e70a8b0531 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaController.idl
+++ b/chromium/third_party/WebKit/Source/core/html/MediaController.idl
@@ -23,15 +23,18 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#mediacontroller
+
[
Constructor,
ConstructorCallWith=ExecutionContext,
- RuntimeEnabled=Media,
+ RuntimeEnabled=MediaController,
+ TypeChecking=Unrestricted,
] interface MediaController : EventTarget {
readonly attribute TimeRanges buffered;
readonly attribute TimeRanges seekable;
- readonly attribute double duration;
+ readonly attribute unrestricted double duration;
[RaisesException=Setter] attribute double currentTime;
readonly attribute boolean paused;
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaControllerInterface.h b/chromium/third_party/WebKit/Source/core/html/MediaControllerInterface.h
deleted file mode 100644
index 9f8f7042f39..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/MediaControllerInterface.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaControllerInterface_h
-#define MediaControllerInterface_h
-
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-class ExceptionState;
-class TimeRanges;
-
-class MediaControllerInterface {
-public:
- virtual ~MediaControllerInterface() { };
-
- // MediaController IDL:
- virtual PassRefPtr<TimeRanges> buffered() const = 0;
- virtual PassRefPtr<TimeRanges> seekable() const = 0;
- virtual PassRefPtr<TimeRanges> played() = 0;
-
- virtual double duration() const = 0;
- virtual double currentTime() const = 0;
- virtual void setCurrentTime(double, ExceptionState&) = 0;
-
- virtual bool paused() const = 0;
- virtual void play() = 0;
- virtual void pause() = 0;
-
- virtual double defaultPlaybackRate() const = 0;
- virtual void setDefaultPlaybackRate(double) = 0;
-
- virtual double playbackRate() const = 0;
- virtual void setPlaybackRate(double) = 0;
-
- virtual double volume() const = 0;
- virtual void setVolume(double, ExceptionState&) = 0;
-
- virtual bool muted() const = 0;
- virtual void setMuted(bool) = 0;
-
- enum ReadyState { HAVE_NOTHING, HAVE_METADATA, HAVE_CURRENT_DATA, HAVE_FUTURE_DATA, HAVE_ENOUGH_DATA };
- virtual ReadyState readyState() const = 0;
-
- // MediaControlElements:
- virtual bool supportsFullscreen() const = 0;
- virtual bool isFullscreen() const = 0;
- virtual void enterFullscreen() = 0;
-
- virtual bool hasAudio() const = 0;
- virtual bool hasVideo() const = 0;
- virtual bool hasClosedCaptions() const = 0;
- virtual void setClosedCaptionsVisible(bool) = 0;
- virtual bool closedCaptionsVisible() const = 0;
-
- virtual void beginScrubbing() = 0;
- virtual void endScrubbing() = 0;
-
- virtual bool canPlay() const = 0;
-
- virtual bool hasCurrentSrc() const = 0;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp b/chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp
index ef6207470d6..1a9235d6546 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/MediaDocument.cpp
@@ -27,12 +27,12 @@
#include "core/html/MediaDocument.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/HTMLNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/dom/RawDataDocumentParser.h"
#include "core/events/KeyboardEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLHeadElement.h"
#include "core/html/HTMLHtmlElement.h"
@@ -41,7 +41,6 @@
#include "core/html/HTMLVideoElement.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
#include "platform/KeyboardCodes.h"
namespace WebCore {
@@ -51,9 +50,9 @@ using namespace HTMLNames;
// FIXME: Share more code with PluginDocumentParser.
class MediaDocumentParser : public RawDataDocumentParser {
public:
- static PassRefPtr<MediaDocumentParser> create(MediaDocument* document)
+ static PassRefPtrWillBeRawPtr<MediaDocumentParser> create(MediaDocument* document)
{
- return adoptRef(new MediaDocumentParser(document));
+ return adoptRefWillBeNoop(new MediaDocumentParser(document));
}
private:
@@ -73,25 +72,25 @@ private:
void MediaDocumentParser::createDocumentStructure()
{
ASSERT(document());
- RefPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
rootElement->insertedByParser();
document()->appendChild(rootElement);
if (document()->frame())
document()->frame()->loader().dispatchDocumentElementAvailable();
- RefPtr<HTMLHeadElement> head = HTMLHeadElement::create(*document());
- RefPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLHeadElement> head = HTMLHeadElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(*document());
meta->setAttribute(nameAttr, "viewport");
meta->setAttribute(contentAttr, "width=device-width");
head->appendChild(meta.release());
- RefPtr<HTMLVideoElement> media = HTMLVideoElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLVideoElement> media = HTMLVideoElement::create(*document());
media->setAttribute(controlsAttr, "");
media->setAttribute(autoplayAttr, "");
media->setAttribute(nameAttr, "media");
- RefPtr<HTMLSourceElement> source = HTMLSourceElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLSourceElement> source = HTMLSourceElement::create(*document());
source->setSrc(document()->url());
if (DocumentLoader* loader = document()->loader())
@@ -99,7 +98,7 @@ void MediaDocumentParser::createDocumentStructure()
media->appendChild(source.release());
- RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
body->appendChild(media.release());
rootElement->appendChild(head.release());
@@ -124,23 +123,11 @@ MediaDocument::MediaDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> MediaDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> MediaDocument::createParser()
{
return MediaDocumentParser::create(this);
}
-static inline HTMLVideoElement* descendentVideoElement(Node* root)
-{
- ASSERT(root);
-
- for (Node* node = root; node; node = NodeTraversal::next(*node, root)) {
- if (isHTMLVideoElement(node))
- return toHTMLVideoElement(node);
- }
-
- return 0;
-}
-
void MediaDocument::defaultEventHandler(Event* event)
{
Node* targetNode = event->target()->toNode();
@@ -148,18 +135,14 @@ void MediaDocument::defaultEventHandler(Event* event)
return;
if (event->type() == EventTypeNames::keydown && event->isKeyboardEvent()) {
- HTMLVideoElement* video = descendentVideoElement(targetNode);
+ HTMLVideoElement* video = Traversal<HTMLVideoElement>::firstWithin(*targetNode);
if (!video)
return;
KeyboardEvent* keyboardEvent = toKeyboardEvent(event);
if (keyboardEvent->keyIdentifier() == "U+0020" || keyboardEvent->keyCode() == VKEY_MEDIA_PLAY_PAUSE) {
// space or media key (play/pause)
- if (video->paused()) {
- if (video->canPlay())
- video->play();
- } else
- video->pause();
+ video->togglePlayState();
event->setDefaultHandled();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaDocument.h b/chromium/third_party/WebKit/Source/core/html/MediaDocument.h
index b5d264ec976..a2b55c5c385 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/MediaDocument.h
@@ -32,15 +32,15 @@ namespace WebCore {
class MediaDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<MediaDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<MediaDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new MediaDocument(initializer));
+ return adoptRefWillBeNoop(new MediaDocument(initializer));
}
private:
MediaDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaError.h b/chromium/third_party/WebKit/Source/core/html/MediaError.h
index 86ace1108bf..0169c759713 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaError.h
+++ b/chromium/third_party/WebKit/Source/core/html/MediaError.h
@@ -32,7 +32,7 @@
namespace WebCore {
-class MediaError : public RefCounted<MediaError>, public ScriptWrappable {
+class MediaError FINAL : public RefCountedWillBeGarbageCollectedFinalized<MediaError>, public ScriptWrappable {
public:
enum Code {
MEDIA_ERR_ABORTED = 1,
@@ -42,10 +42,15 @@ public:
MEDIA_ERR_ENCRYPTED
};
- static PassRefPtr<MediaError> create(Code code) { return adoptRef(new MediaError(code)); }
+ static PassRefPtrWillBeRawPtr<MediaError> create(Code code)
+ {
+ return adoptRefWillBeNoop(new MediaError(code));
+ }
Code code() const { return m_code; }
+ void trace(Visitor*) { }
+
private:
MediaError(Code code) : m_code(code)
{
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaError.idl b/chromium/third_party/WebKit/Source/core/html/MediaError.idl
index 4cf13edcef5..aaffbc230d9 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaError.idl
+++ b/chromium/third_party/WebKit/Source/core/html/MediaError.idl
@@ -24,12 +24,13 @@
*/
[
- RuntimeEnabled=Media
+ RuntimeEnabled=Media,
+ WillBeGarbageCollected,
] interface MediaError {
const unsigned short MEDIA_ERR_ABORTED = 1;
const unsigned short MEDIA_ERR_NETWORK = 2;
const unsigned short MEDIA_ERR_DECODE = 3;
const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
- [RuntimeEnabled=EncryptedMediaAnyVersion] const unsigned short MEDIA_ERR_ENCRYPTED = 5;
+ [RuntimeEnabled=EncryptedMediaAnyVersion, DeprecateAs=MediaErrorEncrypted] const unsigned short MEDIA_ERR_ENCRYPTED = 5;
readonly attribute unsigned short code;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp b/chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp
index f887a05f163..70cd27fe98f 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/MediaFragmentURIParser.cpp
@@ -134,11 +134,11 @@ void MediaFragmentURIParser::parseFragments()
// name or value are not valid UTF-8 strings, then remove the name-value pair from the list.
bool validUTF8 = true;
if (!name.isEmpty()) {
- name = name.utf8(String::StrictConversion).data();
+ name = name.utf8(StrictUTF8Conversion).data();
validUTF8 = !name.isEmpty();
}
if (validUTF8 && !value.isEmpty()) {
- value = value.utf8(String::StrictConversion).data();
+ value = value.utf8(StrictUTF8Conversion).data();
validUTF8 = !value.isEmpty();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp b/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp
index 38f02b701bd..270236ec6c0 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "core/html/MediaKeyEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "wtf/Uint8Array.h"
namespace WebCore {
@@ -63,4 +62,9 @@ const AtomicString& MediaKeyEvent::interfaceName() const
return EventNames::MediaKeyEvent;
}
+void MediaKeyEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h b/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h
index 370abafce6b..cf95046f657 100644
--- a/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h
+++ b/chromium/third_party/WebKit/Source/core/html/MediaKeyEvent.h
@@ -43,21 +43,21 @@ struct MediaKeyEventInit : public EventInit {
unsigned short systemCode;
};
-class MediaKeyEvent : public Event {
+class MediaKeyEvent FINAL : public Event {
public:
virtual ~MediaKeyEvent();
- static PassRefPtr<MediaKeyEvent> create()
+ static PassRefPtrWillBeRawPtr<MediaKeyEvent> create()
{
- return adoptRef(new MediaKeyEvent);
+ return adoptRefWillBeNoop(new MediaKeyEvent);
}
- static PassRefPtr<MediaKeyEvent> create(const AtomicString& type, const MediaKeyEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<MediaKeyEvent> create(const AtomicString& type, const MediaKeyEventInit& initializer)
{
- return adoptRef(new MediaKeyEvent(type, initializer));
+ return adoptRefWillBeNoop(new MediaKeyEvent(type, initializer));
}
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
String keySystem() const { return m_keySystem; }
String sessionId() const { return m_sessionId; }
@@ -68,6 +68,8 @@ public:
MediaKeyError* errorCode(bool& isNull) const { isNull = !m_errorCode; return m_errorCode.get(); }
unsigned short systemCode() const { return m_systemCode; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
MediaKeyEvent();
MediaKeyEvent(const AtomicString& type, const MediaKeyEventInit& initializer);
diff --git a/chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp b/chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp
index 366ee643ba3..15e112713f0 100644
--- a/chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/PluginDocument.cpp
@@ -25,17 +25,17 @@
#include "config.h"
#include "core/html/PluginDocument.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
#include "core/dom/RawDataDocumentParser.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLEmbedElement.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/plugins/PluginView.h"
#include "core/rendering/RenderEmbeddedObject.h"
@@ -46,15 +46,21 @@ using namespace HTMLNames;
// FIXME: Share more code with MediaDocumentParser.
class PluginDocumentParser : public RawDataDocumentParser {
public:
- static PassRefPtr<PluginDocumentParser> create(PluginDocument* document)
+ static PassRefPtrWillBeRawPtr<PluginDocumentParser> create(PluginDocument* document)
{
- return adoptRef(new PluginDocumentParser(document));
+ return adoptRefWillBeNoop(new PluginDocumentParser(document));
+ }
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_embedElement);
+ RawDataDocumentParser::trace(visitor);
}
private:
PluginDocumentParser(Document* document)
: RawDataDocumentParser(document)
- , m_embedElement(0)
+ , m_embedElement(nullptr)
{
}
@@ -66,7 +72,7 @@ private:
PluginView* pluginView() const;
- RefPtr<HTMLEmbedElement> m_embedElement;
+ RefPtrWillBeMember<HTMLEmbedElement> m_embedElement;
};
void PluginDocumentParser::createDocumentStructure()
@@ -76,7 +82,7 @@ void PluginDocumentParser::createDocumentStructure()
ASSERT(document());
RELEASE_ASSERT(document()->loader());
- Frame* frame = document()->frame();
+ LocalFrame* frame = document()->frame();
if (!frame)
return;
@@ -84,12 +90,12 @@ void PluginDocumentParser::createDocumentStructure()
if (!frame->settings() || !frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
return;
- RefPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLHtmlElement> rootElement = HTMLHtmlElement::create(*document());
rootElement->insertedByParser();
document()->appendChild(rootElement);
frame->loader().dispatchDocumentElementAvailable();
- RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
+ RefPtrWillBeRawPtr<HTMLBodyElement> body = HTMLBodyElement::create(*document());
body->setAttribute(marginwidthAttr, "0");
body->setAttribute(marginheightAttr, "0");
body->setAttribute(styleAttr, "background-color: rgb(38,38,38)");
@@ -134,7 +140,7 @@ void PluginDocumentParser::finish()
view->didFinishLoading();
else
view->didFailLoading(error);
- m_embedElement = 0;
+ m_embedElement = nullptr;
}
RawDataDocumentParser::finish();
}
@@ -156,7 +162,7 @@ PluginDocument::PluginDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> PluginDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> PluginDocument::createParser()
{
return PluginDocumentParser::create(this);
}
@@ -178,20 +184,14 @@ Node* PluginDocument::pluginNode()
void PluginDocument::detach(const AttachContext& context)
{
// Release the plugin node so that we don't have a circular reference.
- m_pluginNode = 0;
+ m_pluginNode = nullptr;
HTMLDocument::detach(context);
}
-void PluginDocument::cancelManualPluginLoad()
+void PluginDocument::trace(Visitor* visitor)
{
- // PluginDocument::cancelManualPluginLoad should only be called once, but there are issues
- // with how many times we call beforeload on object elements. <rdar://problem/8441094>.
- if (!shouldLoadPluginManually())
- return;
-
- DocumentLoader* documentLoader = frame()->loader().activeDocumentLoader();
- documentLoader->cancelMainResourceLoad(ResourceError::cancelledError(documentLoader->request().url()));
- setShouldLoadPluginManually(false);
+ visitor->trace(m_pluginNode);
+ HTMLDocument::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/PluginDocument.h b/chromium/third_party/WebKit/Source/core/html/PluginDocument.h
index 590cb30303f..021e5c100ec 100644
--- a/chromium/third_party/WebKit/Source/core/html/PluginDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/PluginDocument.h
@@ -34,9 +34,9 @@ class Widget;
class PluginDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<PluginDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<PluginDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new PluginDocument(initializer));
+ return adoptRefWillBeNoop(new PluginDocument(initializer));
}
void setPluginNode(Node* pluginNode) { m_pluginNode = pluginNode; }
@@ -46,19 +46,19 @@ public:
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- void cancelManualPluginLoad();
-
bool shouldLoadPluginManually() { return m_shouldLoadPluginManually; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- PluginDocument(const DocumentInit&);
+ explicit PluginDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
void setShouldLoadPluginManually(bool loadManually) { m_shouldLoadPluginManually = loadManually; }
bool m_shouldLoadPluginManually;
- RefPtr<Node> m_pluginNode;
+ RefPtrWillBeMember<Node> m_pluginNode;
};
DEFINE_DOCUMENT_TYPE_CASTS(PluginDocument);
diff --git a/chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp b/chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp
index 09157de9df7..f084b7cae8a 100644
--- a/chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/PublicURLManager.cpp
@@ -27,8 +27,10 @@
#include "config.h"
#include "core/html/PublicURLManager.h"
+#include "core/fetch/MemoryCache.h"
#include "core/html/URLRegistry.h"
#include "platform/weborigin/KURL.h"
+#include "wtf/Vector.h"
#include "wtf/text/StringHash.h"
namespace WebCore {
@@ -46,14 +48,14 @@ PublicURLManager::PublicURLManager(ExecutionContext* context)
{
}
-void PublicURLManager::registerURL(SecurityOrigin* origin, const KURL& url, URLRegistrable* registrable)
+void PublicURLManager::registerURL(SecurityOrigin* origin, const KURL& url, URLRegistrable* registrable, const String& uuid)
{
if (m_isStopped)
return;
- RegistryURLMap::iterator found = m_registryToURL.add(&registrable->registry(), URLSet()).iterator;
+ RegistryURLMap::ValueType* found = m_registryToURL.add(&registrable->registry(), URLMap()).storedValue;
found->key->registerURL(origin, url, registrable);
- found->value.add(url.string());
+ found->value.add(url.string(), uuid);
}
void PublicURLManager::revoke(const KURL& url)
@@ -67,6 +69,27 @@ void PublicURLManager::revoke(const KURL& url)
}
}
+void PublicURLManager::revoke(const String& uuid)
+{
+ // A linear scan; revoking by UUID is assumed rare.
+ Vector<String> urlsToRemove;
+ for (RegistryURLMap::iterator i = m_registryToURL.begin(); i != m_registryToURL.end(); ++i) {
+ URLRegistry* registry = i->key;
+ URLMap& registeredURLs = i->value;
+ for (URLMap::iterator j = registeredURLs.begin(); j != registeredURLs.end(); ++j) {
+ if (uuid == j->value) {
+ KURL url(ParsedURLString, j->key);
+ MemoryCache::removeURLFromCache(executionContext(), url);
+ registry->unregisterURL(url);
+ urlsToRemove.append(j->key);
+ }
+ }
+ for (unsigned j = 0; j < urlsToRemove.size(); j++)
+ registeredURLs.remove(urlsToRemove[j]);
+ urlsToRemove.clear();
+ }
+}
+
void PublicURLManager::stop()
{
if (m_isStopped)
@@ -74,8 +97,8 @@ void PublicURLManager::stop()
m_isStopped = true;
for (RegistryURLMap::iterator i = m_registryToURL.begin(); i != m_registryToURL.end(); ++i) {
- for (URLSet::iterator j = i->value.begin(); j != i->value.end(); ++j)
- i->key->unregisterURL(KURL(ParsedURLString, *j));
+ for (URLMap::iterator j = i->value.begin(); j != i->value.end(); ++j)
+ i->key->unregisterURL(KURL(ParsedURLString, j->key));
}
m_registryToURL.clear();
diff --git a/chromium/third_party/WebKit/Source/core/html/PublicURLManager.h b/chromium/third_party/WebKit/Source/core/html/PublicURLManager.h
index 08848772701..094d42b4204 100644
--- a/chromium/third_party/WebKit/Source/core/html/PublicURLManager.h
+++ b/chromium/third_party/WebKit/Source/core/html/PublicURLManager.h
@@ -40,13 +40,14 @@ class SecurityOrigin;
class URLRegistry;
class URLRegistrable;
-class PublicURLManager : public ActiveDOMObject {
+class PublicURLManager FINAL : public ActiveDOMObject {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassOwnPtr<PublicURLManager> create(ExecutionContext*);
- void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*);
+ void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*, const String& uuid = String());
void revoke(const KURL&);
+ void revoke(const String& uuid);
// ActiveDOMObject interface.
virtual void stop() OVERRIDE;
@@ -54,12 +55,16 @@ public:
private:
PublicURLManager(ExecutionContext*);
- typedef HashSet<String> URLSet;
- typedef HashMap<URLRegistry*, URLSet > RegistryURLMap;
+ // One or more URLs can be associated with the same unique ID.
+ // Objects need be revoked by unique ID in some cases.
+ typedef String URLString;
+ typedef HashMap<URLString, String> URLMap;
+ typedef HashMap<URLRegistry*, URLMap> RegistryURLMap;
+
RegistryURLMap m_registryToURL;
bool m_isStopped;
};
} // namespace WebCore
-#endif // PUBLICURLMANAGER_h
+#endif // PublicURLManager_h
diff --git a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp
index f7cbfa982a2..423badc97c1 100644
--- a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/html/RadioNodeList.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
#include "core/dom/NodeRareData.h"
#include "core/html/HTMLFormElement.h"
@@ -37,34 +37,38 @@ namespace WebCore {
using namespace HTMLNames;
-RadioNodeList::RadioNodeList(Node* rootNode, const AtomicString& name)
- : LiveNodeList(rootNode, RadioNodeListType, InvalidateForFormControls, rootNode->hasTagName(formTag) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)
+RadioNodeList::RadioNodeList(ContainerNode& rootNode, const AtomicString& name, CollectionType type)
+ : LiveNodeList(rootNode, type, InvalidateForFormControls, isHTMLFormElement(rootNode) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)
, m_name(name)
+ , m_onlyMatchImgElements(type == RadioImgNodeListType)
{
ScriptWrappable::init(this);
}
RadioNodeList::~RadioNodeList()
{
- ownerNode()->nodeLists()->removeCacheWithAtomicName(this, RadioNodeListType, m_name);
+#if !ENABLE(OILPAN)
+ ownerNode().nodeLists()->removeCache(this, m_onlyMatchImgElements ? RadioImgNodeListType : RadioNodeListType, m_name);
+#endif
}
-static inline HTMLInputElement* toRadioButtonInputElement(Node* node)
+static inline HTMLInputElement* toRadioButtonInputElement(Element& element)
{
- ASSERT(node->isElementNode());
- if (!node->hasTagName(inputTag))
+ if (!isHTMLInputElement(element))
return 0;
- HTMLInputElement* inputElement = toHTMLInputElement(node);
- if (!inputElement->isRadioButton() || inputElement->value().isEmpty())
+ HTMLInputElement& inputElement = toHTMLInputElement(element);
+ if (!inputElement.isRadioButton() || inputElement.value().isEmpty())
return 0;
- return inputElement;
+ return &inputElement;
}
String RadioNodeList::value() const
{
- for (unsigned i = 0; i < length(); ++i) {
- Node* node = item(i);
- const HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+ if (m_onlyMatchImgElements)
+ return String();
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ const HTMLInputElement* inputElement = toRadioButtonInputElement(*item(i));
if (!inputElement || !inputElement->checked())
continue;
return inputElement->value();
@@ -74,9 +78,11 @@ String RadioNodeList::value() const
void RadioNodeList::setValue(const String& value)
{
- for (unsigned i = 0; i < length(); ++i) {
- Node* node = item(i);
- HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+ if (m_onlyMatchImgElements)
+ return;
+ unsigned length = this->length();
+ for (unsigned i = 0; i < length; ++i) {
+ HTMLInputElement* inputElement = toRadioButtonInputElement(*item(i));
if (!inputElement || inputElement->value() != value)
continue;
inputElement->setChecked(true);
@@ -84,28 +90,43 @@ void RadioNodeList::setValue(const String& value)
}
}
-bool RadioNodeList::checkElementMatchesRadioNodeListFilter(Element* testElement) const
+bool RadioNodeList::matchesByIdOrName(const Element& testElement) const
+{
+ return testElement.getIdAttribute() == m_name || testElement.getNameAttribute() == m_name;
+}
+
+bool RadioNodeList::checkElementMatchesRadioNodeListFilter(const Element& testElement) const
{
- ASSERT(testElement->hasTagName(objectTag) || testElement->isFormControlElement());
- if (ownerNode()->hasTagName(formTag)) {
- HTMLFormElement* formElement = toHTMLElement(testElement)->formOwner();
+ ASSERT(!m_onlyMatchImgElements);
+ ASSERT(isHTMLObjectElement(testElement) || testElement.isFormControlElement());
+ if (isHTMLFormElement(ownerNode())) {
+ HTMLFormElement* formElement = toHTMLElement(testElement).formOwner();
if (!formElement || formElement != ownerNode())
return false;
}
- return testElement->getIdAttribute() == m_name || testElement->getNameAttribute() == m_name;
+ return matchesByIdOrName(testElement);
}
-bool RadioNodeList::nodeMatches(Element* testElement) const
+bool RadioNodeList::elementMatches(const Element& element) const
{
- if (!testElement->hasTagName(objectTag) && !testElement->isFormControlElement())
+ if (m_onlyMatchImgElements) {
+ if (!isHTMLImageElement(element))
+ return false;
+
+ if (toHTMLElement(element).formOwner() != ownerNode())
+ return false;
+
+ return matchesByIdOrName(element);
+ }
+
+ if (!isHTMLObjectElement(element) && !element.isFormControlElement())
return false;
- if (testElement->hasTagName(inputTag) && toHTMLInputElement(testElement)->isImageButton())
+ if (isHTMLInputElement(element) && toHTMLInputElement(element).isImageButton())
return false;
- return checkElementMatchesRadioNodeListFilter(testElement);
+ return checkElementMatchesRadioNodeListFilter(element);
}
-} // namspace
-
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.h b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.h
index b735b0c3377..5dbd7b6ce6b 100644
--- a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.h
+++ b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.h
@@ -34,10 +34,10 @@ namespace WebCore {
class RadioNodeList FINAL : public LiveNodeList {
public:
- static PassRefPtr<RadioNodeList> create(Node* ownerNode, CollectionType type, const AtomicString& name)
+ static PassRefPtrWillBeRawPtr<RadioNodeList> create(ContainerNode& ownerNode, CollectionType type, const AtomicString& name)
{
- ASSERT_UNUSED(type, type == RadioNodeListType);
- return adoptRef(new RadioNodeList(ownerNode, name));
+ ASSERT_UNUSED(type, type == RadioNodeListType || type == RadioImgNodeListType);
+ return adoptRefWillBeNoop(new RadioNodeList(ownerNode, name, type));
}
virtual ~RadioNodeList();
@@ -46,15 +46,18 @@ public:
void setValue(const String&);
private:
- RadioNodeList(Node*, const AtomicString& name);
- bool checkElementMatchesRadioNodeListFilter(Element*) const;
+ RadioNodeList(ContainerNode&, const AtomicString& name, CollectionType);
- virtual bool nodeMatches(Element*) const OVERRIDE;
+ bool checkElementMatchesRadioNodeListFilter(const Element&) const;
+
+ bool matchesByIdOrName(const Element&) const;
+
+ virtual bool elementMatches(const Element&) const OVERRIDE;
AtomicString m_name;
+ const bool m_onlyMatchImgElements;
};
-} // namepsace
+} // namespace
#endif
-
diff --git a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl
index 47beea06be2..057ad06c0ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl
+++ b/chromium/third_party/WebKit/Source/core/html/RadioNodeList.idl
@@ -24,8 +24,8 @@
*/
[
- NoInterfaceObject
+ NoInterfaceObject,
] interface RadioNodeList : NodeList {
attribute DOMString value;
- [ImplementedAs=item] getter Node(unsigned long index);
+ [ImplementedAs=item] getter Node (unsigned long index);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/TextDocument.cpp b/chromium/third_party/WebKit/Source/core/html/TextDocument.cpp
index acff1d92f70..742339679db 100644
--- a/chromium/third_party/WebKit/Source/core/html/TextDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/TextDocument.cpp
@@ -36,9 +36,9 @@ TextDocument::TextDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> TextDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> TextDocument::createParser()
{
- return TextDocumentParser::create(this);
+ return TextDocumentParser::create(*this);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/TextDocument.h b/chromium/third_party/WebKit/Source/core/html/TextDocument.h
index a36617db0bf..a7961f6fc8c 100644
--- a/chromium/third_party/WebKit/Source/core/html/TextDocument.h
+++ b/chromium/third_party/WebKit/Source/core/html/TextDocument.h
@@ -31,15 +31,15 @@ namespace WebCore {
class TextDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<TextDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<TextDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new TextDocument(initializer));
+ return adoptRefWillBeNoop(new TextDocument(initializer));
}
private:
TextDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser();
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/TextMetrics.h b/chromium/third_party/WebKit/Source/core/html/TextMetrics.h
index 9925831e009..f936067b7e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/TextMetrics.h
+++ b/chromium/third_party/WebKit/Source/core/html/TextMetrics.h
@@ -39,14 +39,72 @@ public:
float width() const { return m_width; }
void setWidth(float w) { m_width = w; }
+ float actualBoundingBoxLeft() const { return m_actualBoundingBoxLeft; }
+ void setActualBoundingBoxLeft(float actualBoundingBoxLeft) { m_actualBoundingBoxLeft = actualBoundingBoxLeft; }
+
+ float actualBoundingBoxRight() const { return m_actualBoundingBoxRight; }
+ void setActualBoundingBoxRight(float actualBoundingBoxRight) { m_actualBoundingBoxRight = actualBoundingBoxRight; }
+
+ float fontBoundingBoxAscent() const { return m_fontBoundingBoxAscent; }
+ void setFontBoundingBoxAscent(float fontBoundingBoxAscent) { m_fontBoundingBoxAscent = fontBoundingBoxAscent; }
+
+ float fontBoundingBoxDescent() const { return m_fontBoundingBoxDescent; }
+ void setFontBoundingBoxDescent(float fontBoundingBoxDescent) { m_fontBoundingBoxDescent = fontBoundingBoxDescent; }
+
+ float actualBoundingBoxAscent() const { return m_actualBoundingBoxAscent; }
+ void setActualBoundingBoxAscent(float actualBoundingBoxAscent) { m_actualBoundingBoxAscent = actualBoundingBoxAscent; }
+
+ float actualBoundingBoxDescent() const { return m_actualBoundingBoxDescent; }
+ void setActualBoundingBoxDescent(float actualBoundingBoxDescent) { m_actualBoundingBoxDescent = actualBoundingBoxDescent; }
+
+ float emHeightAscent() const { return m_emHeightAscent; }
+ void setEmHeightAscent(float emHeightAscent) { m_emHeightAscent = emHeightAscent; }
+
+ float emHeightDescent() const { return m_emHeightDescent; }
+ void setEmHeightDescent(float emHeightDescent) { m_emHeightDescent = emHeightDescent; }
+
+ float hangingBaseline() const { return m_hangingBaseline; }
+ void setHangingBaseline(float hangingBaseline) { m_hangingBaseline = hangingBaseline; }
+
+ float alphabeticBaseline() const { return m_alphabeticBaseline; }
+ void setAlphabeticBaseline(float alphabeticBaseline) { m_alphabeticBaseline = alphabeticBaseline; }
+
+ float ideographicBaseline() const { return m_ideographicBaseline; }
+ void setIdeographicBaseline(float ideographicBaseline) { m_ideographicBaseline = ideographicBaseline; }
+
private:
TextMetrics()
: m_width(0)
+ , m_actualBoundingBoxLeft(0)
+ , m_actualBoundingBoxRight(0)
+ , m_fontBoundingBoxAscent(0)
+ , m_fontBoundingBoxDescent(0)
+ , m_actualBoundingBoxAscent(0)
+ , m_actualBoundingBoxDescent(0)
+ , m_emHeightAscent(0)
+ , m_emHeightDescent(0)
+ , m_hangingBaseline(0)
+ , m_alphabeticBaseline(0)
+ , m_ideographicBaseline(0)
{
ScriptWrappable::init(this);
}
+ // x-direction
float m_width;
+ float m_actualBoundingBoxLeft;
+ float m_actualBoundingBoxRight;
+
+ // y-direction
+ float m_fontBoundingBoxAscent;
+ float m_fontBoundingBoxDescent;
+ float m_actualBoundingBoxAscent;
+ float m_actualBoundingBoxDescent;
+ float m_emHeightAscent;
+ float m_emHeightDescent;
+ float m_hangingBaseline;
+ float m_alphabeticBaseline;
+ float m_ideographicBaseline;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/TextMetrics.idl b/chromium/third_party/WebKit/Source/core/html/TextMetrics.idl
index fc37998bda6..14f11483dd2 100644
--- a/chromium/third_party/WebKit/Source/core/html/TextMetrics.idl
+++ b/chromium/third_party/WebKit/Source/core/html/TextMetrics.idl
@@ -24,6 +24,20 @@
*/
[
] interface TextMetrics {
+ // x-direction
readonly attribute float width;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxLeft;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxRight;
+
+ // y-direction
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float fontBoundingBoxAscent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float fontBoundingBoxDescent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxAscent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxDescent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float emHeightAscent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float emHeightDescent;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float hangingBaseline;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float alphabeticBaseline;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float ideographicBaseline;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp b/chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp
index 407ff32353b..c8fa279edad 100644
--- a/chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/TimeRanges.cpp
@@ -26,13 +26,13 @@
#include "config.h"
#include "core/html/TimeRanges.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/ExceptionCode.h"
#include <math.h>
using namespace WebCore;
-using namespace std;
TimeRanges::TimeRanges(double start, double end)
{
@@ -116,7 +116,7 @@ void TimeRanges::unionWith(const TimeRanges* other)
double TimeRanges::start(unsigned index, ExceptionState& exceptionState) const
{
if (index >= length()) {
- exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is not less than the object's length (" + String::number(length()) + ").");
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, length()));
return 0;
}
return m_ranges[index].m_start;
@@ -125,7 +125,7 @@ double TimeRanges::start(unsigned index, ExceptionState& exceptionState) const
double TimeRanges::end(unsigned index, ExceptionState& exceptionState) const
{
if (index >= length()) {
- exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is not less than the object's length (" + String::number(length()) + ").");
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, length()));
return 0;
}
return m_ranges[index].m_end;
@@ -134,7 +134,7 @@ double TimeRanges::end(unsigned index, ExceptionState& exceptionState) const
void TimeRanges::add(double start, double end)
{
ASSERT(start <= end);
- unsigned int overlappingArcIndex;
+ unsigned overlappingArcIndex;
Range addedRange(start, end);
// For each present range check if we need to:
@@ -193,9 +193,9 @@ double TimeRanges::nearest(double time) const
if (time >= startTime && time <= endTime)
return time;
if (fabs(startTime - time) < closest)
- closest = fabsf(startTime - time);
+ closest = fabs(startTime - time);
else if (fabs(endTime - time) < closest)
- closest = fabsf(endTime - time);
+ closest = fabs(endTime - time);
}
return closest;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/URLRegistry.h b/chromium/third_party/WebKit/Source/core/html/URLRegistry.h
index 660acb92852..f6f2c3bcbf0 100644
--- a/chromium/third_party/WebKit/Source/core/html/URLRegistry.h
+++ b/chromium/third_party/WebKit/Source/core/html/URLRegistry.h
@@ -52,8 +52,9 @@ public:
virtual void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*) = 0;
virtual void unregisterURL(const KURL&) = 0;
- // This is an optional API
+ // These are optional APIs
virtual URLRegistrable* lookup(const String&) { ASSERT_NOT_REACHED(); return 0; }
+ virtual bool contains(const String&) { ASSERT_NOT_REACHED(); return false; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ValidityState.h b/chromium/third_party/WebKit/Source/core/html/ValidityState.h
index 44d05b8cc8c..829cc4e97a4 100644
--- a/chromium/third_party/WebKit/Source/core/html/ValidityState.h
+++ b/chromium/third_party/WebKit/Source/core/html/ValidityState.h
@@ -30,16 +30,20 @@
namespace WebCore {
-class ValidityState : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(ValidityState); WTF_MAKE_FAST_ALLOCATED;
+class ValidityState : public NoBaseWillBeGarbageCollectedFinalized<ValidityState>, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(ValidityState);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<ValidityState> create(FormAssociatedElement* control)
+ static PassOwnPtrWillBeRawPtr<ValidityState> create(FormAssociatedElement* control)
{
- return adoptPtr(new ValidityState(control));
+ return adoptPtrWillBeNoop(new ValidityState(control));
}
+ void trace(Visitor* visitor) { visitor->trace(m_control); }
+#if !ENABLE(OILPAN)
void ref() { m_control->ref(); }
void deref() { m_control->deref(); }
+#endif
String validationMessage() const;
@@ -57,12 +61,12 @@ public:
bool valid() const;
private:
- ValidityState(FormAssociatedElement* control) : m_control(control)
+ explicit ValidityState(FormAssociatedElement* control) : m_control(control)
{
ScriptWrappable::init(this);
}
- FormAssociatedElement* m_control;
+ RawPtrWillBeMember<FormAssociatedElement> m_control;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ValidityState.idl b/chromium/third_party/WebKit/Source/core/html/ValidityState.idl
index 582baf9a4a3..d4f72538d3a 100644
--- a/chromium/third_party/WebKit/Source/core/html/ValidityState.idl
+++ b/chromium/third_party/WebKit/Source/core/html/ValidityState.idl
@@ -21,6 +21,7 @@
*/
[
+ WillBeGarbageCollected
] interface ValidityState {
readonly attribute boolean valueMissing;
readonly attribute boolean typeMismatch;
diff --git a/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.cpp b/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.cpp
new file mode 100644
index 00000000000..7321f853f29
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.cpp
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/WindowNameCollection.h"
+
+#include "core/html/HTMLImageElement.h"
+
+namespace WebCore {
+
+WindowNameCollection::WindowNameCollection(ContainerNode& document, const AtomicString& name)
+ : HTMLNameCollection(document, WindowNamedItems, name)
+{
+}
+
+bool WindowNameCollection::elementMatches(const Element& element) const
+{
+ // Match only images, forms, applets, embeds and objects by name,
+ // but anything by id
+ if (isHTMLImageElement(element)
+ || isHTMLFormElement(element)
+ || isHTMLAppletElement(element)
+ || isHTMLEmbedElement(element)
+ || isHTMLObjectElement(element)) {
+ if (element.getNameAttribute() == m_name)
+ return true;
+ }
+ return element.getIdAttribute() == m_name;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.h b/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.h
new file mode 100644
index 00000000000..fc9408707c1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/WindowNameCollection.h
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WindowNameCollection_h
+#define WindowNameCollection_h
+
+#include "core/html/HTMLNameCollection.h"
+
+namespace WebCore {
+
+class WindowNameCollection FINAL : public HTMLNameCollection {
+public:
+ static PassRefPtrWillBeRawPtr<WindowNameCollection> create(ContainerNode& document, CollectionType type, const AtomicString& name)
+ {
+ ASSERT_UNUSED(type, type == WindowNamedItems);
+ return adoptRefWillBeNoop(new WindowNameCollection(document, name));
+ }
+
+ bool elementMatches(const Element&) const;
+
+private:
+ WindowNameCollection(ContainerNode& document, const AtomicString& name);
+};
+
+DEFINE_TYPE_CASTS(WindowNameCollection, LiveNodeListBase, collection, collection->type() == WindowNamedItems, collection.type() == WindowNamedItems);
+
+} // namespace WebCore
+
+#endif // WindowNameCollection_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp
index c7e5c9301b6..bc7f5932d0f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.cpp
@@ -32,36 +32,34 @@
#include "core/html/canvas/ANGLEInstancedArrays.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
-#include "platform/graphics/Extensions3D.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContext* context)
+ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_ANGLE_instanced_arrays");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_ANGLE_instanced_arrays");
}
ANGLEInstancedArrays::~ANGLEInstancedArrays()
{
}
-WebGLExtension::ExtensionName ANGLEInstancedArrays::name() const
+WebGLExtensionName ANGLEInstancedArrays::name() const
{
return ANGLEInstancedArraysName;
}
-PassRefPtr<ANGLEInstancedArrays> ANGLEInstancedArrays::create(WebGLRenderingContext* context)
+PassRefPtr<ANGLEInstancedArrays> ANGLEInstancedArrays::create(WebGLRenderingContextBase* context)
{
return adoptRef(new ANGLEInstancedArrays(context));
}
-bool ANGLEInstancedArrays::supported(WebGLRenderingContext* context)
+bool ANGLEInstancedArrays::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_ANGLE_instanced_arrays");
+ return context->extensionsUtil()->supportsExtension("GL_ANGLE_instanced_arrays");
}
const char* ANGLEInstancedArrays::extensionName()
@@ -69,7 +67,7 @@ const char* ANGLEInstancedArrays::extensionName()
return "ANGLE_instanced_arrays";
}
-void ANGLEInstancedArrays::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
+void ANGLEInstancedArrays::drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
{
if (isLost())
return;
@@ -77,7 +75,7 @@ void ANGLEInstancedArrays::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first
m_context->drawArraysInstancedANGLE(mode, first, count, primcount);
}
-void ANGLEInstancedArrays::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount)
+void ANGLEInstancedArrays::drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount)
{
if (isLost())
return;
@@ -85,7 +83,7 @@ void ANGLEInstancedArrays::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei c
m_context->drawElementsInstancedANGLE(mode, count, type, offset, primcount);
}
-void ANGLEInstancedArrays::vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor)
+void ANGLEInstancedArrays::vertexAttribDivisorANGLE(GLuint index, GLuint divisor)
{
if (isLost())
return;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h
index 0b9f53119e0..7141e82de09 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.h
@@ -32,28 +32,27 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/WebGLExtension.h"
-#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
-class ANGLEInstancedArrays : public WebGLExtension, public ScriptWrappable {
+class ANGLEInstancedArrays FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<ANGLEInstancedArrays> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<ANGLEInstancedArrays> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~ANGLEInstancedArrays();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
- void drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
- void drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount);
- void vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor);
+ void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+ void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount);
+ void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
private:
- ANGLEInstancedArrays(WebGLRenderingContext*);
+ ANGLEInstancedArrays(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl
index 2d257cce1b9..4e63430ade0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/ANGLEInstancedArrays.idl
@@ -29,12 +29,13 @@
*/
[
+ DoNotCheckConstants,
NoInterfaceObject,
- DoNotCheckConstants
+ TypeChecking=Interface|Nullable,
] interface ANGLEInstancedArrays {
const unsigned long VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE;
- [StrictTypeChecking] void drawArraysInstancedANGLE(unsigned long mode, long first, long count, long primcount);
- [StrictTypeChecking] void drawElementsInstancedANGLE(unsigned long mode, long count, unsigned long type, long long offset, long primcount);
- [StrictTypeChecking] void vertexAttribDivisorANGLE(unsigned long index, long divisor);
+ void drawArraysInstancedANGLE(unsigned long mode, long first, long count, long primcount);
+ void drawElementsInstancedANGLE(unsigned long mode, long count, unsigned long type, long long offset, long primcount);
+ void vertexAttribDivisorANGLE(unsigned long index, long divisor);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp
index 66429f5af14..3ff9b1ac9ee 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.cpp
@@ -26,12 +26,15 @@
#include "config.h"
-#include "Canvas2DContextAttributes.h"
+#include "core/html/canvas/Canvas2DContextAttributes.h"
+
+#include "wtf/text/WTFString.h"
namespace WebCore {
Canvas2DContextAttributes::Canvas2DContextAttributes()
: m_alpha(true)
+ , m_storage(PersistentStorage)
{
ScriptWrappable::init(this);
}
@@ -55,4 +58,22 @@ void Canvas2DContextAttributes::setAlpha(bool alpha)
m_alpha = alpha;
}
+String Canvas2DContextAttributes::storage() const
+{
+ return m_storage == PersistentStorage ? "persistent" : "discardable";
+}
+
+void Canvas2DContextAttributes::setStorage(const String& storage)
+{
+ if (storage == "persistent")
+ m_storage = PersistentStorage;
+ else if (storage == "discardable")
+ m_storage = DiscardableStorage;
+}
+
+Canvas2DContextStorage Canvas2DContextAttributes::parsedStorage() const
+{
+ return m_storage;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h
index e777ef80778..dab44564297 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.h
@@ -33,6 +33,11 @@
namespace WebCore {
+enum Canvas2DContextStorage {
+ PersistentStorage,
+ DiscardableStorage
+};
+
class Canvas2DContextAttributes : public CanvasContextAttributes, public ScriptWrappable {
public:
virtual ~Canvas2DContextAttributes();
@@ -44,10 +49,15 @@ public:
bool alpha() const;
void setAlpha(bool);
+ String storage() const;
+ void setStorage(const String&);
+ Canvas2DContextStorage parsedStorage() const;
+
protected:
Canvas2DContextAttributes();
bool m_alpha;
+ Canvas2DContextStorage m_storage;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl
index 72e01914f14..f6017b3c86f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Canvas2DContextAttributes.idl
@@ -28,4 +28,5 @@
NoInterfaceObject
] interface Canvas2DContextAttributes {
attribute boolean alpha;
+ [RuntimeEnabled=ExperimentalCanvasFeatures] attribute DOMString storage;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp
index 07e62a07e10..c63aa7d85b0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.cpp
@@ -49,13 +49,13 @@ CanvasGradient::CanvasGradient(const FloatPoint& p0, float r0, const FloatPoint&
void CanvasGradient::addColorStop(float value, const String& color, ExceptionState& exceptionState)
{
if (!(value >= 0 && value <= 1.0f)) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The provided value (" + String::number(value) + ") is outside the range (0.0, 1.0).");
return;
}
RGBA32 rgba = 0;
if (!parseColorOrCurrentColor(rgba, color, 0 /*canvas*/)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + color + "') could not be parsed as a color.");
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl
index 35a4e2a31d0..3da025a744c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasGradient.idl
@@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
[
+ TypeChecking=Unrestricted,
] interface CanvasGradient {
[RaisesException] void addColorStop(float offset, DOMString color);
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
new file mode 100644
index 00000000000..10e3b958b6c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasImageSource.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasImageSource_h
+#define CanvasImageSource_h
+
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class Image;
+class SecurityOrigin;
+
+enum SourceImageMode {
+ CopySourceImageIfVolatile,
+ DontCopySourceImage
+};
+
+enum SourceImageStatus {
+ NormalSourceImageStatus,
+ ExternalSourceImageStatus, // Shared with another GPU context
+ UndecodableSourceImageStatus, // Image element with a 'broken' image
+ ZeroSizeCanvasSourceImageStatus, // Source is a canvas with width or heigh of zero
+ IncompleteSourceImageStatus, // Image element with no source media
+ InvalidSourceImageStatus,
+};
+
+class CanvasImageSource {
+public:
+ virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus* = 0) const = 0;
+
+ // IMPORTANT: Result must be independent of whether destinationContext is
+ // already tainted because this function may be used to determine whether
+ // a CanvasPattern is "origin clean", and that pattern may be used on
+ // another canvas, which may not be already tainted.
+ virtual bool wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const = 0;
+
+ virtual bool isVideoElement() const { return false; }
+
+ // Adjusts the source and destination rectangles for cases where the actual
+ // source image is a subregion of the image returned by getSourceImageForCanvas.
+ virtual void adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const { }
+
+ virtual FloatSize sourceSize() const = 0;
+ virtual FloatSize defaultDestinationSize() const { return sourceSize(); }
+ virtual const KURL& sourceURL() const { return blankURL(); }
+
+protected:
+ virtual ~CanvasImageSource() { }
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp
index 66a1ac99fa4..879487b14d3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.cpp
@@ -113,7 +113,7 @@ void CanvasPathMethods::arcTo(float x1, float y1, float x2, float y2, float r, E
return;
if (r < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The radius provided (" + String::number(r) + ") is negative.");
return;
}
@@ -135,7 +135,6 @@ namespace {
float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise)
{
- float twoPi = 2 * piFloat;
float newEndAngle = endAngle;
/* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arc
* If the anticlockwise argument is false and endAngle-startAngle is equal to or greater than 2pi, or,
@@ -143,10 +142,10 @@ float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise)
* then the arc is the whole circumference of this ellipse, and the point at startAngle along this circle's circumference,
* measured in radians clockwise from the ellipse's semi-major axis, acts as both the start point and the end point.
*/
- if (!anticlockwise && endAngle - startAngle >= twoPi)
- newEndAngle = startAngle + twoPi;
- else if (anticlockwise && startAngle - endAngle >= twoPi)
- newEndAngle = startAngle - twoPi;
+ if (!anticlockwise && endAngle - startAngle >= twoPiFloat)
+ newEndAngle = startAngle + twoPiFloat;
+ else if (anticlockwise && startAngle - endAngle >= twoPiFloat)
+ newEndAngle = startAngle - twoPiFloat;
/*
* Otherwise, the arc is the path along the circumference of this ellipse from the start point to the end point,
@@ -159,9 +158,9 @@ float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise)
* We preserve backward-compatibility.
*/
else if (!anticlockwise && startAngle > endAngle)
- newEndAngle = startAngle + (twoPi - fmodf(startAngle - endAngle, twoPi));
+ newEndAngle = startAngle + (twoPiFloat - fmodf(startAngle - endAngle, twoPiFloat));
else if (anticlockwise && startAngle < endAngle)
- newEndAngle = startAngle - (twoPi - fmodf(endAngle - startAngle, twoPi));
+ newEndAngle = startAngle - (twoPiFloat - fmodf(endAngle - startAngle, twoPiFloat));
ASSERT(ellipseIsRenderable(startAngle, newEndAngle));
return newEndAngle;
@@ -180,17 +179,16 @@ inline FloatPoint getPointOnEllipse(float radiusX, float radiusY, float theta)
void canonicalizeAngle(float* startAngle, float* endAngle)
{
// Make 0 <= startAngle < 2*PI
- float twoPi = 2 * piFloat;
float newStartAngle = *startAngle;
if (newStartAngle < 0)
- newStartAngle = twoPi + fmodf(newStartAngle, -twoPi);
+ newStartAngle = twoPiFloat + fmodf(newStartAngle, -twoPiFloat);
else
- newStartAngle = fmodf(newStartAngle, twoPi);
+ newStartAngle = fmodf(newStartAngle, twoPiFloat);
float delta = newStartAngle - *startAngle;
*startAngle = newStartAngle;
*endAngle = *endAngle + delta;
- ASSERT(newStartAngle >= 0 && newStartAngle < twoPi);
+ ASSERT(newStartAngle >= 0 && newStartAngle < twoPiFloat);
}
/*
@@ -227,25 +225,24 @@ void canonicalizeAngle(float* startAngle, float* endAngle)
void degenerateEllipse(CanvasPathMethods* path, float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise)
{
ASSERT(ellipseIsRenderable(startAngle, endAngle));
- ASSERT(startAngle >= 0 && startAngle < 2 * piFloat);
+ ASSERT(startAngle >= 0 && startAngle < twoPiFloat);
ASSERT((anticlockwise && (startAngle - endAngle) >= 0) || (!anticlockwise && (endAngle - startAngle) >= 0));
FloatPoint center(x, y);
AffineTransform rotationMatrix;
- rotationMatrix.rotate(rad2deg(rotation));
+ rotationMatrix.rotateRadians(rotation);
// First, if the object's path has any subpaths, then the method must add a straight line from the last point in the subpath to the start point of the arc.
lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, startAngle)));
if ((!radiusX && !radiusY) || startAngle == endAngle)
return;
- float halfPiFloat = piFloat * 0.5;
if (!anticlockwise) {
- // startAngle - fmodf(startAngle, halfPiFloat) + halfPiFloat is the one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi)
+ // startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat is the one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi)
// that is the closest to startAngle on the clockwise direction.
- for (float angle = startAngle - fmodf(startAngle, halfPiFloat) + halfPiFloat; angle < endAngle; angle += halfPiFloat)
+ for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat; angle < endAngle; angle += piOverTwoFloat)
lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, angle)));
} else {
- for (float angle = startAngle - fmodf(startAngle, halfPiFloat); angle > endAngle; angle -= halfPiFloat)
+ for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat); angle > endAngle; angle -= piOverTwoFloat)
lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, angle)));
}
@@ -260,7 +257,7 @@ void CanvasPathMethods::arc(float x, float y, float radius, float startAngle, fl
return;
if (radius < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The radius provided (" + String::number(radius) + ") is negative.");
return;
}
@@ -283,8 +280,12 @@ void CanvasPathMethods::ellipse(float x, float y, float radiusX, float radiusY,
if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radiusX) || !std::isfinite(radiusY) || !std::isfinite(rotation) || !std::isfinite(startAngle) || !std::isfinite(endAngle))
return;
- if (radiusX < 0 || radiusY < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ if (radiusX < 0) {
+ exceptionState.throwDOMException(IndexSizeError, "The major-axis radius provided (" + String::number(radiusX) + ") is negative.");
+ return;
+ }
+ if (radiusY < 0) {
+ exceptionState.throwDOMException(IndexSizeError, "The minor-axis radius provided (" + String::number(radiusY) + ") is negative.");
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h
index 100f95cf055..2f0160ea1bf 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.h
@@ -54,6 +54,7 @@ public:
protected:
CanvasPathMethods() { }
+ CanvasPathMethods(const Path& path) : m_path(path) { }
Path m_path;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.idl b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.idl
new file mode 100644
index 00000000000..2c37810cef7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPathMethods.idl
@@ -0,0 +1,20 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvaspathmethods
+
+[
+ NoInterfaceObject, // Always used on target of 'implements'
+] interface CanvasPathMethods {
+ // shared path API methods
+ void closePath();
+ void moveTo(unrestricted float x, unrestricted float y);
+ void lineTo(unrestricted float x, unrestricted float y);
+ void quadraticCurveTo(unrestricted float cpx, unrestricted float cpy, unrestricted float x, unrestricted float y);
+ void bezierCurveTo(unrestricted float cp1x, unrestricted float cp1y, unrestricted float cp2x, unrestricted float cp2y, unrestricted float x, unrestricted float y);
+ [RaisesException] void arcTo(unrestricted float x1, unrestricted float y1, unrestricted float x2, unrestricted float y2, unrestricted float radius);
+ void rect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RaisesException] void arc(unrestricted float x, unrestricted float y, unrestricted float radius, unrestricted float startAngle, unrestricted float endAngle, [Default=Undefined] optional boolean anticlockwise);
+ [RaisesException] void ellipse(unrestricted float x, unrestricted float y, unrestricted float radiusX, unrestricted float radiusY, unrestricted float rotation, unrestricted float startAngle, unrestricted float endAngle, [Default=Undefined] optional boolean anticlockwise);
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp
index f7ee0da4388..e011ff082a3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasPattern.cpp
@@ -54,7 +54,7 @@ void CanvasPattern::parseRepetitionType(const String& type, bool& repeatX, bool&
repeatY = true;
return;
}
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The provided type ('" + type + "') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'.");
}
CanvasPattern::CanvasPattern(PassRefPtr<Image> image, bool repeatX, bool repeatY, bool originClean)
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
index 47a0e616efb..9e5dd350d8f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -26,10 +26,7 @@
#include "config.h"
#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLImageElement.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/html/canvas/CanvasPattern.h"
+#include "core/html/canvas/CanvasImageSource.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace WebCore {
@@ -37,72 +34,30 @@ namespace WebCore {
CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas)
: m_canvas(canvas)
{
- ScriptWrappable::init(this);
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)
-{
- if (canvas()->originClean() && pattern && !pattern->originClean())
- return true;
- return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas)
-{
- if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
- return true;
- return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
-{
- if (!image || !canvas()->originClean())
- return false;
-
- ImageResource* cachedImage = image->cachedImage();
- if (!cachedImage->image()->currentFrameHasSingleSecurityOrigin())
- return true;
-
- return wouldTaintOrigin(cachedImage->response().url()) && !cachedImage->passesAccessControlCheck(canvas()->securityOrigin());
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
-{
- // FIXME: This check is likely wrong when a redirect is involved. We need
- // to test the finalURL. Please be careful when fixing this issue not to
- // make currentSrc be the final URL because then the
- // HTMLMediaElement.currentSrc DOM API would leak redirect destinations!
- if (!video || !canvas()->originClean())
- return false;
-
- if (!video->hasSingleSecurityOrigin())
- return true;
-
- if (!(video->player() && video->player()->didPassCORSAccessCheck()) && wouldTaintOrigin(video->currentSrc()))
- return true;
-
- return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url)
-{
- if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
- return false;
-
- if (canvas()->securityOrigin()->taintsCanvas(url))
- return true;
-
- if (url.protocolIsData())
- return false;
- m_cleanURLs.add(url.string());
- return false;
}
-void CanvasRenderingContext::checkOrigin(const KURL& url)
+bool CanvasRenderingContext::wouldTaintOrigin(CanvasImageSource* imageSource)
{
- if (wouldTaintOrigin(url))
- canvas()->setOriginTainted();
+ const KURL& sourceURL = imageSource->sourceURL();
+ bool hasURL = (sourceURL.isValid() && !sourceURL.isAboutBlankURL());
+
+ if (hasURL) {
+ if (sourceURL.protocolIsData() || m_cleanURLs.contains(sourceURL.string()))
+ return false;
+ if (m_dirtyURLs.contains(sourceURL.string()))
+ return true;
+ }
+
+ bool taintOrigin = imageSource->wouldTaintOrigin(canvas()->securityOrigin());
+
+ if (hasURL) {
+ if (taintOrigin)
+ m_dirtyURLs.add(sourceURL.string());
+ else
+ m_cleanURLs.add(sourceURL.string());
+ }
+ return taintOrigin;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
index 2f5cd637991..0999d334bf7 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.h
@@ -26,8 +26,8 @@
#ifndef CanvasRenderingContext_h
#define CanvasRenderingContext_h
-#include "bindings/v8/ScriptWrappable.h"
#include "core/html/HTMLCanvasElement.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
#include "wtf/Noncopyable.h"
#include "wtf/text/StringHash.h"
@@ -36,20 +36,22 @@ namespace blink { class WebLayer; }
namespace WebCore {
-class CanvasPattern;
+class CanvasImageSource;
class HTMLCanvasElement;
-class HTMLImageElement;
-class HTMLVideoElement;
class KURL;
class WebGLObject;
-class CanvasRenderingContext : public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(CanvasRenderingContext); WTF_MAKE_FAST_ALLOCATED;
+class CanvasRenderingContext : public NoBaseWillBeGarbageCollectedFinalized<CanvasRenderingContext> {
+ WTF_MAKE_NONCOPYABLE(CanvasRenderingContext);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
virtual ~CanvasRenderingContext() { }
+#if !ENABLE(OILPAN)
void ref() { m_canvas->ref(); }
void deref() { m_canvas->deref(); }
+#endif
+
HTMLCanvasElement* canvas() const { return m_canvas; }
virtual bool is2d() const { return false; }
@@ -61,24 +63,17 @@ public:
virtual blink::WebLayer* platformLayer() const { return 0; }
+ virtual void trace(Visitor* visitor) { visitor->trace(m_canvas); }
+
+ bool wouldTaintOrigin(CanvasImageSource*);
+
protected:
CanvasRenderingContext(HTMLCanvasElement*);
- bool wouldTaintOrigin(const CanvasPattern*);
- bool wouldTaintOrigin(const HTMLCanvasElement*);
- bool wouldTaintOrigin(const HTMLImageElement*);
- bool wouldTaintOrigin(const HTMLVideoElement*);
- bool wouldTaintOrigin(const KURL&);
-
- template<class T> void checkOrigin(const T* arg)
- {
- if (wouldTaintOrigin(arg))
- canvas()->setOriginTainted();
- }
- void checkOrigin(const KURL&);
private:
- HTMLCanvasElement* m_canvas;
+ RawPtrWillBeMember<HTMLCanvasElement> m_canvas;
HashSet<String> m_cleanURLs;
+ HashSet<String> m_dirtyURLs;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.idl b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.idl
deleted file mode 100644
index ae89a5fcd56..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext.idl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Custom=Wrap,
- NoInterfaceObject,
-] interface CanvasRenderingContext {
- readonly attribute HTMLCanvasElement canvas;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp
index 68f213b18ae..ccca4ddd03f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.cpp
@@ -33,16 +33,18 @@
#include "config.h"
#include "core/html/canvas/CanvasRenderingContext2D.h"
-#include "CSSPropertyNames.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/css/CSSFontSelector.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/StylePropertySet.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/ExceptionCode.h"
#include "core/fetch/ImageResource.h"
+#include "core/frame/ImageBitmap.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLMediaElement.h"
@@ -52,46 +54,52 @@
#include "core/html/canvas/CanvasGradient.h"
#include "core/html/canvas/CanvasPattern.h"
#include "core/html/canvas/CanvasStyle.h"
-#include "core/html/canvas/DOMPath.h"
-#include "core/frame/ImageBitmap.h"
+#include "core/html/canvas/Path2D.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderTheme.h"
#include "platform/fonts/FontCache.h"
#include "platform/geometry/FloatQuad.h"
+#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
-#include "platform/graphics/DrawLooper.h"
#include "platform/text/TextRun.h"
-#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/CheckedArithmetic.h"
#include "wtf/MathExtras.h"
#include "wtf/OwnPtr.h"
#include "wtf/Uint8ClampedArray.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
static const int defaultFontSize = 10;
static const char defaultFontFamily[] = "sans-serif";
static const char defaultFont[] = "10px sans-serif";
+static const double TryRestoreContextInterval = 0.5;
+static const unsigned MaxTryRestoreContextAttempts = 4;
+
+static bool contextLostRestoredEventsEnabled()
+{
+ return RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled();
+}
CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode)
: CanvasRenderingContext(canvas)
- , m_stateStack(1)
- , m_unrealizedSaveCount(0)
, m_usesCSSCompatibilityParseMode(usesCSSCompatibilityParseMode)
, m_hasAlpha(!attrs || attrs->alpha())
-{
+ , m_isContextLost(false)
+ , m_contextRestorable(true)
+ , m_storageMode(!attrs ? PersistentStorage : attrs->parsedStorage())
+ , m_tryRestoreContextAttemptCount(0)
+ , m_dispatchContextLostEventTimer(this, &CanvasRenderingContext2D::dispatchContextLostEvent)
+ , m_dispatchContextRestoredEventTimer(this, &CanvasRenderingContext2D::dispatchContextRestoredEvent)
+ , m_tryRestoreContextEventTimer(this, &CanvasRenderingContext2D::tryRestoreContextEvent)
+{
+ m_stateStack.append(adoptPtrWillBeNoop(new State()));
ScriptWrappable::init(this);
}
void CanvasRenderingContext2D::unwindStateStack()
{
- // Ensure that the state stack in the ImageBuffer's context
- // is cleared before destruction, to avoid assertions in the
- // GraphicsContext dtor.
if (size_t stackSize = m_stateStack.size()) {
if (GraphicsContext* context = canvas()->existingDrawingContext()) {
while (--stackSize)
@@ -102,8 +110,14 @@ void CanvasRenderingContext2D::unwindStateStack()
CanvasRenderingContext2D::~CanvasRenderingContext2D()
{
-#if !ASSERT_DISABLED
- unwindStateStack();
+}
+
+void CanvasRenderingContext2D::validateStateStack()
+{
+#if ASSERT_ENABLED
+ GraphicsContext* context = canvas()->existingDrawingContext();
+ if (context && !context->contextDisabled())
+ ASSERT(context->saveCount() == m_stateStack.size());
#endif
}
@@ -115,13 +129,108 @@ bool CanvasRenderingContext2D::isAccelerated() const
return context && context->isAccelerated();
}
+bool CanvasRenderingContext2D::isContextLost() const
+{
+ return m_isContextLost;
+}
+
+void CanvasRenderingContext2D::loseContext()
+{
+ if (m_isContextLost)
+ return;
+ m_isContextLost = true;
+ m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE);
+}
+
+void CanvasRenderingContext2D::restoreContext()
+{
+ if (!m_contextRestorable)
+ return;
+ // This code path is for restoring from an eviction
+ // Restoring from surface failure is handled internally
+ ASSERT(m_isContextLost && !canvas()->hasImageBuffer());
+
+ if (canvas()->buffer()) {
+ if (contextLostRestoredEventsEnabled()) {
+ m_dispatchContextRestoredEventTimer.startOneShot(0, FROM_HERE);
+ } else {
+ // legacy synchronous context restoration.
+ reset();
+ m_isContextLost = false;
+ }
+ }
+}
+
+void CanvasRenderingContext2D::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_stateStack);
+ visitor->trace(m_fetchedFonts);
+#endif
+ CanvasRenderingContext::trace(visitor);
+}
+
+void CanvasRenderingContext2D::dispatchContextLostEvent(Timer<CanvasRenderingContext2D>*)
+{
+ if (contextLostRestoredEventsEnabled()) {
+ RefPtrWillBeRawPtr<Event> event = Event::createCancelable(EventTypeNames::contextlost);
+ canvas()->dispatchEvent(event);
+ if (event->defaultPrevented()) {
+ m_contextRestorable = false;
+ }
+ }
+
+ // If an image buffer is present, it means the context was not lost due to
+ // an eviction, but rather due to a surface failure (gpu context lost?)
+ if (m_contextRestorable && canvas()->hasImageBuffer()) {
+ m_tryRestoreContextAttemptCount = 0;
+ m_tryRestoreContextEventTimer.startRepeating(TryRestoreContextInterval, FROM_HERE);
+ }
+}
+
+void CanvasRenderingContext2D::tryRestoreContextEvent(Timer<CanvasRenderingContext2D>* timer)
+{
+ if (!m_isContextLost) {
+ // Canvas was already restored (possibly thanks to a resize), so stop trying.
+ m_tryRestoreContextEventTimer.stop();
+ return;
+ }
+ if (canvas()->hasImageBuffer() && canvas()->buffer()->restoreSurface()) {
+ m_tryRestoreContextEventTimer.stop();
+ dispatchContextRestoredEvent(0);
+ }
+
+ if (++m_tryRestoreContextAttemptCount > MaxTryRestoreContextAttempts)
+ canvas()->discardImageBuffer();
+
+ if (!canvas()->hasImageBuffer()) {
+ // final attempt: allocate a brand new image buffer instead of restoring
+ timer->stop();
+ if (canvas()->buffer())
+ dispatchContextRestoredEvent(0);
+ }
+}
+
+void CanvasRenderingContext2D::dispatchContextRestoredEvent(Timer<CanvasRenderingContext2D>*)
+{
+ if (!m_isContextLost)
+ return;
+ reset();
+ m_isContextLost = false;
+ if (contextLostRestoredEventsEnabled()) {
+ RefPtrWillBeRawPtr<Event> event(Event::create(EventTypeNames::contextrestored));
+ canvas()->dispatchEvent(event);
+ }
+}
+
void CanvasRenderingContext2D::reset()
{
+ validateStateStack();
unwindStateStack();
m_stateStack.resize(1);
- m_stateStack.first() = State();
+ m_stateStack.first() = adoptPtrWillBeNoop(new State());
m_path.clear();
- m_unrealizedSaveCount = 0;
+ validateStateStack();
}
// Important: Several of these properties are also stored in GraphicsContext's
@@ -129,7 +238,8 @@ void CanvasRenderingContext2D::reset()
// that the canvas 2d spec specifies. Make sure to sync the initial state of the
// GraphicsContext in HTMLCanvasElement::createImageBuffer()!
CanvasRenderingContext2D::State::State()
- : m_strokeStyle(CanvasStyle::createFromRGBA(Color::black))
+ : m_unrealizedSaveCount(0)
+ , m_strokeStyle(CanvasStyle::createFromRGBA(Color::black))
, m_fillStyle(CanvasStyle::createFromRGBA(Color::black))
, m_lineWidth(1)
, m_lineCap(ButtCap)
@@ -151,7 +261,8 @@ CanvasRenderingContext2D::State::State()
}
CanvasRenderingContext2D::State::State(const State& other)
- : FontSelectorClient()
+ : CSSFontSelectorClient()
+ , m_unrealizedSaveCount(other.m_unrealizedSaveCount)
, m_unparsedStrokeColor(other.m_unparsedStrokeColor)
, m_unparsedFillColor(other.m_unparsedFillColor)
, m_strokeStyle(other.m_strokeStyle)
@@ -177,7 +288,7 @@ CanvasRenderingContext2D::State::State(const State& other)
, m_realizedFont(other.m_realizedFont)
{
if (m_realizedFont)
- m_font.fontSelector()->registerForInvalidationCallbacks(this);
+ static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalidationCallbacks(this);
}
CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(const State& other)
@@ -185,9 +296,12 @@ CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons
if (this == &other)
return *this;
+#if !ENABLE(OILPAN)
if (m_realizedFont)
- m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+ static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInvalidationCallbacks(this);
+#endif
+ m_unrealizedSaveCount = other.m_unrealizedSaveCount;
m_unparsedStrokeColor = other.m_unparsedStrokeColor;
m_unparsedFillColor = other.m_unparsedFillColor;
m_strokeStyle = other.m_strokeStyle;
@@ -212,18 +326,20 @@ CanvasRenderingContext2D::State& CanvasRenderingContext2D::State::operator=(cons
m_realizedFont = other.m_realizedFont;
if (m_realizedFont)
- m_font.fontSelector()->registerForInvalidationCallbacks(this);
+ static_cast<CSSFontSelector*>(m_font.fontSelector())->registerForInvalidationCallbacks(this);
return *this;
}
CanvasRenderingContext2D::State::~State()
{
+#if !ENABLE(OILPAN)
if (m_realizedFont)
- m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
+ static_cast<CSSFontSelector*>(m_font.fontSelector())->unregisterForInvalidationCallbacks(this);
+#endif
}
-void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
+void CanvasRenderingContext2D::State::fontsNeedUpdate(CSSFontSelector* fontSelector)
{
ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
ASSERT(m_realizedFont);
@@ -231,22 +347,33 @@ void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector
m_font.update(fontSelector);
}
-void CanvasRenderingContext2D::realizeSavesLoop()
-{
- ASSERT(m_unrealizedSaveCount);
- ASSERT(m_stateStack.size() >= 1);
- GraphicsContext* context = drawingContext();
- do {
- m_stateStack.append(state());
+void CanvasRenderingContext2D::realizeSaves()
+{
+ validateStateStack();
+ if (state().m_unrealizedSaveCount) {
+ ASSERT(m_stateStack.size() >= 1);
+ // Reduce the current state's unrealized count by one now,
+ // to reflect the fact we are saving one state.
+ m_stateStack.last()->m_unrealizedSaveCount--;
+ m_stateStack.append(adoptPtrWillBeNoop(new State(state())));
+ // Set the new state's unrealized count to 0, because it has no outstanding saves.
+ // We need to do this explicitly because the copy constructor and operator= used
+ // by the Vector operations copy the unrealized count from the previous state (in
+ // turn necessary to support correct resizing and unwinding of the stack).
+ m_stateStack.last()->m_unrealizedSaveCount = 0;
+ GraphicsContext* context = drawingContext();
if (context)
context->save();
- } while (--m_unrealizedSaveCount);
+ validateStateStack();
+ }
}
void CanvasRenderingContext2D::restore()
{
- if (m_unrealizedSaveCount) {
- --m_unrealizedSaveCount;
+ validateStateStack();
+ if (state().m_unrealizedSaveCount) {
+ // We never realized the save, so just record that it was unnecessary.
+ --m_stateStack.last()->m_unrealizedSaveCount;
return;
}
ASSERT(m_stateStack.size() >= 1);
@@ -256,9 +383,9 @@ void CanvasRenderingContext2D::restore()
m_stateStack.removeLast();
m_path.transform(state().m_transform.inverse());
GraphicsContext* c = drawingContext();
- if (!c)
- return;
- c->restore();
+ if (c)
+ c->restore();
+ validateStateStack();
}
CanvasStyle* CanvasRenderingContext2D::strokeStyle() const
@@ -281,8 +408,9 @@ void CanvasRenderingContext2D::setStrokeStyle(PassRefPtr<CanvasStyle> prpStyle)
style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
else
style = CanvasStyle::createFromRGBA(currentColor(canvas()));
- } else
- checkOrigin(style->canvasPattern());
+ } else if (canvas()->originClean() && style->canvasPattern() && !style->canvasPattern()->originClean()) {
+ canvas()->setOriginTainted();
+ }
realizeSaves();
modifiableState().m_strokeStyle = style.release();
@@ -313,8 +441,9 @@ void CanvasRenderingContext2D::setFillStyle(PassRefPtr<CanvasStyle> prpStyle)
style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
else
style = CanvasStyle::createFromRGBA(currentColor(canvas()));
- } else
- checkOrigin(style->canvasPattern());
+ } else if (canvas()->originClean() && style->canvasPattern() && !style->canvasPattern()->originClean()) {
+ canvas()->setOriginTainted();
+ }
realizeSaves();
modifiableState().m_fillStyle = style.release();
@@ -492,18 +621,7 @@ void CanvasRenderingContext2D::setLineDash(const Vector<float>& dash)
// Spec requires the concatenation of two copies the dash list when the
// number of elements is odd
if (dash.size() % 2)
- modifiableState().m_lineDash.append(dash);
-
- applyLineDash();
-}
-
-void CanvasRenderingContext2D::setWebkitLineDash(const Vector<float>& dash)
-{
- if (!lineDashSequenceIsValid(dash))
- return;
-
- realizeSaves();
- modifiableState().m_lineDash = dash;
+ modifiableState().m_lineDash.appendVector(dash);
applyLineDash();
}
@@ -523,16 +641,6 @@ void CanvasRenderingContext2D::setLineDashOffset(float offset)
applyLineDash();
}
-float CanvasRenderingContext2D::webkitLineDashOffset() const
-{
- return lineDashOffset();
-}
-
-void CanvasRenderingContext2D::setWebkitLineDashOffset(float offset)
-{
- setLineDashOffset(offset);
-}
-
void CanvasRenderingContext2D::applyLineDash() const
{
GraphicsContext* c = drawingContext();
@@ -560,7 +668,7 @@ void CanvasRenderingContext2D::setGlobalAlpha(float alpha)
GraphicsContext* c = drawingContext();
if (!c)
return;
- c->setAlpha(alpha);
+ c->setAlphaAsFloat(alpha);
}
String CanvasRenderingContext2D::globalCompositeOperation() const
@@ -585,9 +693,11 @@ void CanvasRenderingContext2D::setGlobalCompositeOperation(const String& operati
c->setCompositeOperation(op, blendMode);
}
-void CanvasRenderingContext2D::setCurrentTransform(const SVGMatrix& matrix)
+void CanvasRenderingContext2D::setCurrentTransform(PassRefPtr<SVGMatrixTearOff> passMatrixTearOff)
{
- setTransform(matrix.a(), matrix.b(), matrix.c(), matrix.d(), matrix.e(), matrix.f());
+ RefPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff;
+ const AffineTransform& transform = matrixTearOff->value();
+ setTransform(transform.a(), transform.b(), transform.c(), transform.d(), transform.e(), transform.f());
}
void CanvasRenderingContext2D::scale(float sx, float sy)
@@ -614,7 +724,7 @@ void CanvasRenderingContext2D::scale(float sx, float sy)
}
modifiableState().m_transform = newTransform;
- c->scale(FloatSize(sx, sy));
+ c->scale(sx, sy);
m_path.transform(AffineTransform().scaleNonUniform(1.0 / sx, 1.0 / sy));
}
@@ -630,7 +740,7 @@ void CanvasRenderingContext2D::rotate(float angleInRadians)
return;
AffineTransform newTransform = state().m_transform;
- newTransform.rotate(angleInRadians / piDouble * 180.0);
+ newTransform.rotateRadians(angleInRadians);
if (state().m_transform == newTransform)
return;
@@ -643,7 +753,7 @@ void CanvasRenderingContext2D::rotate(float angleInRadians)
modifiableState().m_transform = newTransform;
c->rotate(angleInRadians);
- m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
+ m_path.transform(AffineTransform().rotateRadians(-angleInRadians));
}
void CanvasRenderingContext2D::translate(float tx, float ty)
@@ -745,7 +855,7 @@ void CanvasRenderingContext2D::setStrokeColor(const String& color)
if (color == state().m_unparsedStrokeColor)
return;
realizeSaves();
- setStrokeStyle(CanvasStyle::createFromString(color, &canvas()->document()));
+ setStrokeStyle(CanvasStyle::createFromString(color));
modifiableState().m_unparsedStrokeColor = color;
}
@@ -787,7 +897,7 @@ void CanvasRenderingContext2D::setFillColor(const String& color)
if (color == state().m_unparsedFillColor)
return;
realizeSaves();
- setFillStyle(CanvasStyle::createFromString(color, &canvas()->document()));
+ setFillStyle(CanvasStyle::createFromString(color));
modifiableState().m_unparsedFillColor = color;
}
@@ -829,18 +939,6 @@ void CanvasRenderingContext2D::beginPath()
m_path.clear();
}
-PassRefPtr<DOMPath> CanvasRenderingContext2D::currentPath()
-{
- return DOMPath::create(m_path);
-}
-
-void CanvasRenderingContext2D::setCurrentPath(DOMPath* path)
-{
- if (!path)
- return;
- m_path = path->path();
-}
-
static bool validateRectForCanvas(float& x, float& y, float& width, float& height)
{
if (!std::isfinite(x) | !std::isfinite(y) | !std::isfinite(width) | !std::isfinite(height))
@@ -870,102 +968,157 @@ static bool isFullCanvasCompositeMode(CompositeOperator op)
return op == CompositeSourceIn || op == CompositeSourceOut || op == CompositeDestinationIn || op == CompositeDestinationAtop;
}
-static bool parseWinding(const String& windingRuleString, WindRule& windRule)
+static WindRule parseWinding(const String& windingRuleString)
{
if (windingRuleString == "nonzero")
- windRule = RULE_NONZERO;
- else if (windingRuleString == "evenodd")
- windRule = RULE_EVENODD;
- else
- return false;
+ return RULE_NONZERO;
+ if (windingRuleString == "evenodd")
+ return RULE_EVENODD;
- return true;
+ ASSERT_NOT_REACHED();
+ return RULE_EVENODD;
}
-void CanvasRenderingContext2D::fill(const String& windingRuleString)
+void CanvasRenderingContext2D::fillInternal(const Path& path, const String& windingRuleString)
{
+ if (path.isEmpty()) {
+ return;
+ }
GraphicsContext* c = drawingContext();
- if (!c)
+ if (!c) {
return;
- if (!state().m_invertibleCTM)
+ }
+ if (!state().m_invertibleCTM) {
return;
+ }
FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
+ if (!c->getTransformedClipBounds(&clipBounds)) {
return;
+ }
// If gradient size is zero, then paint nothing.
Gradient* gradient = c->fillGradient();
- if (gradient && gradient->isZeroSize())
+ if (gradient && gradient->isZeroSize()) {
return;
+ }
- if (!m_path.isEmpty()) {
- WindRule windRule = c->fillRule();
- WindRule newWindRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, newWindRule))
- return;
- c->setFillRule(newWindRule);
+ WindRule windRule = c->fillRule();
+ c->setFillRule(parseWinding(windingRuleString));
- if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedFill(m_path);
- didDraw(clipBounds);
- } else if (state().m_globalComposite == CompositeCopy) {
- clearCanvas();
- c->fillPath(m_path);
- didDraw(clipBounds);
- } else {
- FloatRect dirtyRect;
- if (computeDirtyRect(m_path.boundingRect(), clipBounds, &dirtyRect)) {
- c->fillPath(m_path);
- didDraw(dirtyRect);
- }
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedFill(path);
+ didDraw(clipBounds);
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->fillPath(path);
+ didDraw(clipBounds);
+ } else {
+ FloatRect dirtyRect;
+ if (computeDirtyRect(path.boundingRect(), clipBounds, &dirtyRect)) {
+ c->fillPath(path);
+ didDraw(dirtyRect);
}
-
- c->setFillRule(windRule);
}
+
+ c->setFillRule(windRule);
}
-void CanvasRenderingContext2D::stroke()
+void CanvasRenderingContext2D::fill(const String& windingRuleString)
+{
+ fillInternal(m_path, windingRuleString);
+}
+
+void CanvasRenderingContext2D::fill(Path2D* domPath, const String& windingRuleString)
{
+ fillInternal(domPath->path(), windingRuleString);
+}
+
+void CanvasRenderingContext2D::strokeInternal(const Path& path)
+{
+ if (path.isEmpty()) {
+ return;
+ }
GraphicsContext* c = drawingContext();
- if (!c)
+ if (!c) {
return;
- if (!state().m_invertibleCTM)
+ }
+ if (!state().m_invertibleCTM) {
+ return;
+ }
+ FloatRect clipBounds;
+ if (!c->getTransformedClipBounds(&clipBounds))
return;
// If gradient size is zero, then paint nothing.
Gradient* gradient = c->strokeGradient();
- if (gradient && gradient->isZeroSize())
+ if (gradient && gradient->isZeroSize()) {
return;
+ }
- if (!m_path.isEmpty()) {
- FloatRect bounds = m_path.boundingRect();
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedStroke(path);
+ didDraw(clipBounds);
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->strokePath(path);
+ didDraw(clipBounds);
+ } else {
+ FloatRect bounds = path.boundingRect();
inflateStrokeRect(bounds);
FloatRect dirtyRect;
- if (computeDirtyRect(bounds, &dirtyRect)) {
- c->strokePath(m_path);
+ if (computeDirtyRect(bounds, clipBounds, &dirtyRect)) {
+ c->strokePath(path);
didDraw(dirtyRect);
}
}
}
-void CanvasRenderingContext2D::clip(const String& windingRuleString)
+void CanvasRenderingContext2D::stroke()
+{
+ strokeInternal(m_path);
+}
+
+void CanvasRenderingContext2D::stroke(Path2D* domPath)
+{
+ strokeInternal(domPath->path());
+}
+
+void CanvasRenderingContext2D::clipInternal(const Path& path, const String& windingRuleString)
{
GraphicsContext* c = drawingContext();
- if (!c)
+ if (!c) {
return;
- if (!state().m_invertibleCTM)
- return;
-
- WindRule newWindRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, newWindRule))
+ }
+ if (!state().m_invertibleCTM) {
return;
+ }
realizeSaves();
- c->canvasClip(m_path, newWindRule);
+ c->canvasClip(path, parseWinding(windingRuleString));
+}
+
+void CanvasRenderingContext2D::clip(const String& windingRuleString)
+{
+ clipInternal(m_path, windingRuleString);
+}
+
+void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleString)
+{
+ clipInternal(domPath->path(), windingRuleString);
}
bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString)
{
+ return isPointInPathInternal(m_path, x, y, windingRuleString);
+}
+
+bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const float x, const float y, const String& windingRuleString)
+{
+ return isPointInPathInternal(domPath->path(), x, y, windingRuleString);
+}
+
+bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const float x, const float y, const String& windingRuleString)
+{
GraphicsContext* c = drawingContext();
if (!c)
return false;
@@ -978,15 +1131,20 @@ bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const
if (!std::isfinite(transformedPoint.x()) || !std::isfinite(transformedPoint.y()))
return false;
- WindRule windRule = RULE_NONZERO;
- if (!parseWinding(windingRuleString, windRule))
- return false;
+ return path.contains(transformedPoint, parseWinding(windingRuleString));
+}
- return m_path.contains(transformedPoint, windRule);
+bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
+{
+ return isPointInStrokeInternal(m_path, x, y);
}
+bool CanvasRenderingContext2D::isPointInStroke(Path2D* domPath, const float x, const float y)
+{
+ return isPointInStrokeInternal(domPath->path(), x, y);
+}
-bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
+bool CanvasRenderingContext2D::isPointInStrokeInternal(const Path& path, const float x, const float y)
{
GraphicsContext* c = drawingContext();
if (!c)
@@ -1006,7 +1164,46 @@ bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
strokeData.setLineJoin(getLineJoin());
strokeData.setMiterLimit(miterLimit());
strokeData.setLineDash(getLineDash(), lineDashOffset());
- return m_path.strokeContains(transformedPoint, strokeData);
+ return path.strokeContains(transformedPoint, strokeData);
+}
+
+void CanvasRenderingContext2D::scrollPathIntoView()
+{
+ scrollPathIntoViewInternal(m_path);
+}
+
+void CanvasRenderingContext2D::scrollPathIntoView(Path2D* path2d)
+{
+ scrollPathIntoViewInternal(path2d->path());
+}
+
+void CanvasRenderingContext2D::scrollPathIntoViewInternal(const Path& path)
+{
+ if (!state().m_invertibleCTM || path.isEmpty())
+ return;
+
+ canvas()->document().updateLayoutIgnorePendingStylesheets();
+
+ // Apply transformation and get the bounding rect
+ Path transformedPath = path;
+ transformedPath.transform(state().m_transform);
+ FloatRect boundingRect = transformedPath.boundingRect();
+
+ // Offset by the canvas rect (We should take border and padding into account).
+ RenderBoxModelObject* rbmo = canvas()->renderBoxModelObject();
+ IntRect canvasRect = canvas()->renderer()->absoluteBoundingBoxRect();
+ canvasRect.move(rbmo->borderLeft() + rbmo->paddingLeft(),
+ rbmo->borderTop() + rbmo->paddingTop());
+ LayoutRect pathRect = enclosingLayoutRect(boundingRect);
+ pathRect.moveBy(canvasRect.location());
+
+ if (canvas()->renderer()) {
+ canvas()->renderer()->scrollRectToVisible(
+ pathRect, ScrollAlignment::alignCenterAlways, ScrollAlignment::alignTopAlways);
+ }
+
+ // TODO: should implement "inform the user" that the caret and/or
+ // selection the specified rectangle of the canvas. See http://crbug.com/357987
}
void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
@@ -1035,7 +1232,7 @@ void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he
context->save();
saved = true;
}
- context->setAlpha(1);
+ context->setAlphaAsFloat(1);
}
if (state().m_globalComposite != CompositeSourceOver) {
if (!saved) {
@@ -1048,6 +1245,7 @@ void CanvasRenderingContext2D::clearRect(float x, float y, float width, float he
if (saved)
context->restore();
+ validateStateStack();
didDraw(dirtyRect);
}
@@ -1062,7 +1260,7 @@ void CanvasRenderingContext2D::fillRect(float x, float y, float width, float hei
if (!state().m_invertibleCTM)
return;
FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
+ if (!c->getTransformedClipBounds(&clipBounds))
return;
// from the HTML5 Canvas spec:
@@ -1105,6 +1303,9 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
return;
if (!state().m_invertibleCTM)
return;
+ FloatRect clipBounds;
+ if (!c->getTransformedClipBounds(&clipBounds))
+ return;
// If gradient size is zero, then paint nothing.
Gradient* gradient = c->strokeGradient();
@@ -1113,12 +1314,21 @@ void CanvasRenderingContext2D::strokeRect(float x, float y, float width, float h
FloatRect rect(x, y, width, height);
- FloatRect boundingRect = rect;
- boundingRect.inflate(state().m_lineWidth / 2);
- FloatRect dirtyRect;
- if (computeDirtyRect(boundingRect, &dirtyRect)) {
- c->strokeRect(rect, state().m_lineWidth);
- didDraw(dirtyRect);
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ fullCanvasCompositedStroke(rect);
+ didDraw(clipBounds);
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->strokeRect(rect);
+ didDraw(clipBounds);
+ } else {
+ FloatRect boundingRect = rect;
+ boundingRect.inflate(state().m_lineWidth / 2);
+ FloatRect dirtyRect;
+ if (computeDirtyRect(boundingRect, clipBounds, &dirtyRect)) {
+ c->strokeRect(rect);
+ didDraw(dirtyRect);
+ }
}
}
@@ -1190,7 +1400,7 @@ void CanvasRenderingContext2D::applyShadow()
if (shouldDrawShadows()) {
c->setShadow(state().m_shadowOffset, state().m_shadowBlur, state().m_shadowColor,
- DrawLooper::ShadowIgnoresTransforms);
+ DrawLooperBuilder::ShadowIgnoresTransforms);
} else {
c->clearShadow();
}
@@ -1201,37 +1411,12 @@ bool CanvasRenderingContext2D::shouldDrawShadows() const
return alphaChannel(state().m_shadowColor) && (state().m_shadowBlur || !state().m_shadowOffset.isZero());
}
-enum ImageSizeType {
- ImageSizeAfterDevicePixelRatio,
- ImageSizeBeforeDevicePixelRatio
-};
-
-static LayoutSize sizeFor(HTMLImageElement* image, ImageSizeType sizeType)
-{
- LayoutSize size;
- ImageResource* cachedImage = image->cachedImage();
- if (cachedImage) {
- size = cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this.
-
- if (sizeType == ImageSizeAfterDevicePixelRatio && image->renderer() && image->renderer()->isRenderImage() && cachedImage->image() && !cachedImage->image()->hasRelativeWidth())
- size.scale(toRenderImage(image->renderer())->imageDevicePixelRatio());
- }
- return size;
-}
-
-static IntSize sizeFor(HTMLVideoElement* video)
-{
- if (MediaPlayer* player = video->player())
- return player->naturalSize();
- return IntSize();
-}
-
static inline FloatRect normalizeRect(const FloatRect& rect)
{
- return FloatRect(min(rect.x(), rect.maxX()),
- min(rect.y(), rect.maxY()),
- max(rect.width(), -rect.width()),
- max(rect.height(), -rect.height()));
+ return FloatRect(std::min(rect.x(), rect.maxX()),
+ std::min(rect.y(), rect.maxY()),
+ std::max(rect.width(), -rect.width()),
+ std::max(rect.height(), -rect.height()));
}
static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* srcRect, FloatRect* dstRect)
@@ -1253,363 +1438,110 @@ static inline void clipRectsToImageRect(const FloatRect& imageRect, FloatRect* s
dstRect->move(offset);
}
-void CanvasRenderingContext2D::drawImageInternal(Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::WebBlendMode& blendMode)
-{
- if (!image)
- return;
-
- GraphicsContext* c = drawingContext();
- if (!c)
- return;
- if (!state().m_invertibleCTM)
- return;
- FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
- return;
-
- if (rectContainsTransformedRect(dstRect, clipBounds)) {
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(clipBounds);
- } else if (isFullCanvasCompositeMode(op)) {
- fullCanvasCompositedDrawImage(image, dstRect, srcRect, op);
- didDraw(clipBounds);
- } else if (op == CompositeCopy) {
- clearCanvas();
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(clipBounds);
- } else {
- FloatRect dirtyRect;
- if (computeDirtyRect(dstRect, &dirtyRect)) {
- c->drawImage(image, dstRect, srcRect, op, blendMode);
- didDraw(dirtyRect);
- }
- }
-}
-
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap, float x, float y, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, float x, float y, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- drawImage(bitmap, x, y, bitmap->width(), bitmap->height(), exceptionState);
+ FloatSize destRectSize = imageSource->defaultDestinationSize();
+ drawImage(imageSource, x, y, destRectSize.width(), destRectSize.height(), exceptionState);
}
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
float x, float y, float width, float height, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- if (!bitmap->bitmapRect().width() || !bitmap->bitmapRect().height())
- return;
-
- drawImage(bitmap, 0, 0, bitmap->width(), bitmap->height(), x, y, width, height, exceptionState);
+ FloatSize sourceRectSize = imageSource->sourceSize();
+ drawImage(imageSource, 0, 0, sourceRectSize.width(), sourceRectSize.height(), x, y, width, height, exceptionState);
}
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
float sx, float sy, float sw, float sh,
float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
{
- if (!bitmap) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- FloatRect srcRect(sx, sy, sw, sh);
- FloatRect dstRect(dx, dy, dw, dh);
- FloatRect bitmapRect = bitmap->bitmapRect();
-
- if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
- || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
- return;
-
- if (!dstRect.width() || !dstRect.height())
- return;
- if (!srcRect.width() || !srcRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return;
- }
-
- ASSERT(bitmap->height() && bitmap->width());
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- // Clip the rects to where the user thinks that the image is situated.
- clipRectsToImageRect(IntRect(IntPoint(), bitmap->size()), &normalizedSrcRect, &normalizedDstRect);
-
- FloatRect intersectRect = intersection(bitmapRect, normalizedSrcRect);
- FloatRect actualSrcRect(intersectRect);
-
- IntPoint bitmapOffset = bitmap->bitmapOffset();
- actualSrcRect.move(bitmapOffset - bitmapRect.location());
- FloatRect imageRect = FloatRect(bitmapOffset, bitmapRect.size());
-
- FloatRect actualDstRect(FloatPoint(intersectRect.location() - normalizedSrcRect.location()), bitmapRect.size());
- actualDstRect.scale(normalizedDstRect.width() / normalizedSrcRect.width() * intersectRect.width() / bitmapRect.width(),
- normalizedDstRect.height() / normalizedSrcRect.height() * intersectRect.height() / bitmapRect.height());
- actualDstRect.moveBy(normalizedDstRect.location());
-
- if (!imageRect.intersects(actualSrcRect))
- return;
-
- RefPtr<Image> imageForRendering = bitmap->bitmapImage();
- if (!imageForRendering)
- return;
-
- drawImageInternal(imageForRendering.get(), actualSrcRect, actualDstRect, state().m_globalComposite, state().m_globalBlend);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- LayoutSize destRectSize = sizeFor(image, ImageSizeAfterDevicePixelRatio);
- drawImage(image, x, y, destRectSize.width(), destRectSize.height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- LayoutSize sourceRectSize = sizeFor(image, ImageSizeBeforeDevicePixelRatio);
- drawImage(image, FloatRect(0, 0, sourceRectSize.width(), sourceRectSize.height()), FloatRect(x, y, width, height), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState)
-{
- drawImage(image, srcRect, dstRect, state().m_globalComposite, state().m_globalBlend, exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::WebBlendMode& blendMode, ExceptionState& exceptionState)
-{
- if (!image) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
- || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
- return;
-
- ImageResource* cachedImage = image->cachedImage();
- if (!cachedImage || !image->complete())
- return;
-
- LayoutSize size = sizeFor(image, ImageSizeBeforeDevicePixelRatio);
- if (!size.width() || !size.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- if (!dstRect.width() || !dstRect.height())
- return;
-
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- FloatRect imageRect = FloatRect(FloatPoint(), size);
- if (!srcRect.width() || !srcRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return;
- }
- if (!imageRect.intersects(normalizedSrcRect))
- return;
-
- clipRectsToImageRect(imageRect, &normalizedSrcRect, &normalizedDstRect);
-
- checkOrigin(image);
-
- Image* imageForRendering = cachedImage->imageForRenderer(image->renderer());
-
- // For images that depend on an unavailable container size, we need to fall back to the intrinsic
- // object size. http://www.w3.org/TR/2dcontext2/#dom-context-2d-drawimage
- // FIXME: Without a specified image size this should resolve against the canvas element's size, see: crbug.com/230163.
- if (!image->renderer() && imageForRendering->usesContainerSize())
- imageForRendering->setContainerSize(imageForRendering->size());
-
- drawImageInternal(imageForRendering, normalizedSrcRect, normalizedDstRect, op, blendMode);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, float x, float y, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, 0, 0, sourceCanvas->width(), sourceCanvas->height(), x, y, sourceCanvas->width(), sourceCanvas->height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, FloatRect(0, 0, sourceCanvas->width(), sourceCanvas->height()), FloatRect(x, y, width, height), exceptionState);
+ GraphicsContext* c = drawingContext(); // Do not exit yet if !c because we may need to throw exceptions first
+ CompositeOperator op = c ? c->compositeOperation() : CompositeSourceOver;
+ blink::WebBlendMode blendMode = c ? c->blendModeOperation() : blink::WebBlendModeNormal;
+ drawImageInternal(imageSource, sx, sy, sw, sh, dx, dy, dw, dh, exceptionState, op, blendMode);
}
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
+void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource,
float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(sourceCanvas, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const FloatRect& srcRect,
- const FloatRect& dstRect, ExceptionState& exceptionState)
-{
- if (!sourceCanvas) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- FloatRect srcCanvasRect = FloatRect(FloatPoint(), sourceCanvas->size());
-
- if (!srcCanvasRect.width() || !srcCanvasRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- if (!srcRect.width() || !srcRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return;
+ float dx, float dy, float dw, float dh, ExceptionState& exceptionState,
+ CompositeOperator op, blink::WebBlendMode blendMode)
+{
+ RefPtr<Image> image;
+ SourceImageStatus sourceImageStatus;
+ if (!imageSource->isVideoElement()) {
+ SourceImageMode mode = canvas() == imageSource ? CopySourceImageIfVolatile : DontCopySourceImage; // Thunking for ==
+ image = imageSource->getSourceImageForCanvas(mode, &sourceImageStatus);
+ if (sourceImageStatus == UndecodableSourceImageStatus)
+ exceptionState.throwDOMException(InvalidStateError, "The HTMLImageElement provided is in the 'broken' state.");
+ if (!image || !image->width() || !image->height())
+ return;
}
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- if (!srcCanvasRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
- return;
-
- clipRectsToImageRect(srcCanvasRect, &normalizedSrcRect, &normalizedDstRect);
-
GraphicsContext* c = drawingContext();
if (!c)
return;
+
if (!state().m_invertibleCTM)
return;
- // FIXME: Do this through platform-independent GraphicsContext API.
- ImageBuffer* buffer = sourceCanvas->buffer();
- if (!buffer)
+ if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dw) || !std::isfinite(dh)
+ || !std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)
+ || !dw || !dh || !sw || !sh)
return;
FloatRect clipBounds;
- if (!drawingContext()->getTransformedClipBounds(&clipBounds))
+ if (!c->getTransformedClipBounds(&clipBounds))
return;
- checkOrigin(sourceCanvas);
+ FloatRect srcRect = normalizeRect(FloatRect(sx, sy, sw, sh));
+ FloatRect dstRect = normalizeRect(FloatRect(dx, dy, dw, dh));
- // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable()
- // as that will do a readback to software.
- CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext();
- // FIXME: Implement an accelerated path for drawing from a WebGL canvas to a 2d canvas when possible.
- if (sourceContext && sourceContext->is3d())
- sourceContext->paintRenderingResultsToCanvas();
+ clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->sourceSize()), &srcRect, &dstRect);
- if (rectContainsTransformedRect(normalizedDstRect, clipBounds)) {
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(clipBounds);
- } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
- fullCanvasCompositedDrawImage(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite);
- didDraw(clipBounds);
- } else if (state().m_globalComposite == CompositeCopy) {
- clearCanvas();
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(clipBounds);
+ imageSource->adjustDrawRects(&srcRect, &dstRect);
+
+ if (srcRect.isEmpty())
+ return;
+
+ FloatRect dirtyRect = clipBounds;
+ if (imageSource->isVideoElement()) {
+ drawVideo(static_cast<HTMLVideoElement*>(imageSource), srcRect, dstRect);
+ computeDirtyRect(dstRect, clipBounds, &dirtyRect);
} else {
- FloatRect dirtyRect;
- if (computeDirtyRect(normalizedDstRect, clipBounds, &dirtyRect)) {
- c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
- didDraw(dirtyRect);
+ if (rectContainsTransformedRect(dstRect, clipBounds)) {
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
+ } else if (isFullCanvasCompositeMode(op)) {
+ fullCanvasCompositedDrawImage(image.get(), dstRect, srcRect, op);
+ } else if (op == CompositeCopy) {
+ clearCanvas();
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
+ } else {
+ FloatRect dirtyRect;
+ computeDirtyRect(dstRect, clipBounds, &dirtyRect);
+ c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
}
- }
-
- // Flush canvas's ImageBuffer when drawImage from WebGL to HW accelerated 2d canvas
- if (sourceContext && sourceContext->is3d() && is2d() && isAccelerated() && canvas()->buffer())
- canvas()->buffer()->flush();
-}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y, ExceptionState& exceptionState)
-{
- if (!video) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
+ if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && canvas()->buffer())
+ canvas()->buffer()->flush();
}
- IntSize size = sizeFor(video);
- drawImage(video, x, y, size.width(), size.height(), exceptionState);
-}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
- float x, float y, float width, float height, ExceptionState& exceptionState)
-{
- if (!video) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- IntSize size = sizeFor(video);
- drawImage(video, FloatRect(0, 0, size.width(), size.height()), FloatRect(x, y, width, height), exceptionState);
-}
+ if (canvas()->originClean() && wouldTaintOrigin(imageSource))
+ canvas()->setOriginTainted();
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
- float sx, float sy, float sw, float sh,
- float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
- drawImage(video, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
+ didDraw(dirtyRect);
}
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::drawVideo(HTMLVideoElement* video, FloatRect srcRect, FloatRect dstRect)
{
- if (!video) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
-
- if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readyState() == HTMLMediaElement::HAVE_METADATA)
- return;
-
- FloatRect videoRect = FloatRect(FloatPoint(), sizeFor(video));
- if (!srcRect.width() || !srcRect.height()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return;
- }
-
- FloatRect normalizedSrcRect = normalizeRect(srcRect);
- FloatRect normalizedDstRect = normalizeRect(dstRect);
-
- if (!videoRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
- return;
-
- clipRectsToImageRect(videoRect, &normalizedSrcRect, &normalizedDstRect);
-
GraphicsContext* c = drawingContext();
- if (!c)
- return;
- if (!state().m_invertibleCTM)
- return;
-
- checkOrigin(video);
-
- FloatRect dirtyRect;
- if (!computeDirtyRect(normalizedDstRect, &dirtyRect))
- return;
-
GraphicsContextStateSaver stateSaver(*c);
- c->clip(normalizedDstRect);
- c->translate(normalizedDstRect.x(), normalizedDstRect.y());
- c->scale(FloatSize(normalizedDstRect.width() / normalizedSrcRect.width(), normalizedDstRect.height() / normalizedSrcRect.height()));
- c->translate(-normalizedSrcRect.x(), -normalizedSrcRect.y());
- video->paintCurrentFrameInContext(c, IntRect(IntPoint(), sizeFor(video)));
+ c->clip(dstRect);
+ c->translate(dstRect.x(), dstRect.y());
+ c->scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height());
+ c->translate(-srcRect.x(), -srcRect.y());
+ video->paintCurrentFrameInContext(c, IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())));
stateSaver.restore();
-
- didDraw(dirtyRect);
+ validateStateStack();
}
void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
@@ -1617,12 +1549,14 @@ void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
float dx, float dy, float dw, float dh,
const String& compositeOperation)
{
+ if (!image)
+ return;
CompositeOperator op;
blink::WebBlendMode blendOp = blink::WebBlendModeNormal;
if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blendOp != blink::WebBlendModeNormal)
op = CompositeSourceOver;
- drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), op, blink::WebBlendModeNormal, IGNORE_EXCEPTION);
+ drawImageInternal(image, sx, sy, sw, sh, dx, dy, dw, dh, IGNORE_EXCEPTION, op, blendOp);
}
void CanvasRenderingContext2D::setAlpha(float alpha)
@@ -1660,18 +1594,14 @@ static void drawImageToContext(Image* image, GraphicsContext* context, const Flo
context->drawImage(image, dest, src, op);
}
-static void drawImageToContext(ImageBuffer* imageBuffer, GraphicsContext* context, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
-{
- context->drawImageBuffer(imageBuffer, dest, src, op);
-}
-
template<class T> void CanvasRenderingContext2D::fullCanvasCompositedDrawImage(T* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
{
ASSERT(isFullCanvasCompositeMode(op));
- drawingContext()->beginLayer(1, op);
- drawImageToContext(image, drawingContext(), dest, src, CompositeSourceOver);
- drawingContext()->endLayer();
+ GraphicsContext* c = drawingContext();
+ c->beginLayer(1, op);
+ drawImageToContext(image, c, dest, src, CompositeSourceOver);
+ c->endLayer();
}
static void fillPrimitive(const FloatRect& rect, GraphicsContext* context)
@@ -1698,78 +1628,82 @@ template<class T> void CanvasRenderingContext2D::fullCanvasCompositedFill(const
c->endLayer();
}
-PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1, ExceptionState& exceptionState)
+static void strokePrimitive(const FloatRect& rect, GraphicsContext* context)
{
- if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(x1) || !std::isfinite(y1)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
- }
+ context->strokeRect(rect);
+}
+
+static void strokePrimitive(const Path& path, GraphicsContext* context)
+{
+ context->strokePath(path);
+}
+template<class T> void CanvasRenderingContext2D::fullCanvasCompositedStroke(const T& area)
+{
+ ASSERT(isFullCanvasCompositeMode(state().m_globalComposite));
+
+ GraphicsContext* c = drawingContext();
+ ASSERT(c);
+ c->beginLayer(1, state().m_globalComposite);
+ CompositeOperator previousOperator = c->compositeOperation();
+ c->setCompositeOperation(CompositeSourceOver);
+ strokePrimitive(area, c);
+ c->setCompositeOperation(previousOperator);
+ c->endLayer();
+}
+
+PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createLinearGradient(float x0, float y0, float x1, float y1)
+{
RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
return gradient.release();
}
PassRefPtr<CanvasGradient> CanvasRenderingContext2D::createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionState& exceptionState)
{
- if (!std::isfinite(x0) || !std::isfinite(y0) || !std::isfinite(r0) || !std::isfinite(x1) || !std::isfinite(y1) || !std::isfinite(r1)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
- }
-
if (r0 < 0 || r1 < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return 0;
+ exceptionState.throwDOMException(IndexSizeError, String::format("The %s provided is less than 0.", r0 < 0 ? "r0" : "r1"));
+ return nullptr;
}
RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
return gradient.release();
}
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(CanvasImageSource* imageSource,
const String& repetitionType, ExceptionState& exceptionState)
{
- if (!image) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
- }
bool repeatX, repeatY;
CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
if (exceptionState.hadException())
- return 0;
-
- if (!image->complete())
- return 0;
-
- ImageResource* cachedImage = image->cachedImage();
- Image* imageForRendering = cachedImage ? cachedImage->imageForRenderer(image->renderer()) : 0;
- if (!imageForRendering)
- return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
+ return nullptr;
- // We need to synthesize a container size if a renderer is not available to provide one.
- if (!image->renderer() && imageForRendering->usesContainerSize())
- imageForRendering->setContainerSize(imageForRendering->size());
+ SourceImageStatus status;
+ RefPtr<Image> imageForRendering = imageSource->getSourceImageForCanvas(CopySourceImageIfVolatile, &status);
- bool originClean = cachedImage->isAccessAllowed(canvas()->securityOrigin());
- return CanvasPattern::create(imageForRendering, repeatX, repeatY, originClean);
-}
-
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
- const String& repetitionType, ExceptionState& exceptionState)
-{
- if (!canvas) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
- }
- if (!canvas->width() || !canvas->height()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return 0;
+ switch (status) {
+ case NormalSourceImageStatus:
+ break;
+ case ZeroSizeCanvasSourceImageStatus:
+ exceptionState.throwDOMException(InvalidStateError, String::format("The canvas %s is 0.", imageSource->sourceSize().width() ? "height" : "width"));
+ return nullptr;
+ case UndecodableSourceImageStatus:
+ exceptionState.throwDOMException(InvalidStateError, "Source image is in the 'broken' state.");
+ return nullptr;
+ case InvalidSourceImageStatus:
+ imageForRendering = Image::nullImage();
+ break;
+ case IncompleteSourceImageStatus:
+ return nullptr;
+ default:
+ case ExternalSourceImageStatus: // should not happen when mode is CopySourceImageIfVolatile
+ ASSERT_NOT_REACHED();
+ return nullptr;
}
+ ASSERT(imageForRendering);
- bool repeatX, repeatY;
- CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
- if (exceptionState.hadException())
- return 0;
- return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
+ bool originClean = !wouldTaintOrigin(imageSource);
+
+ return CanvasPattern::create(imageForRendering.release(), repeatX, repeatY, originClean);
}
bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, FloatRect* dirtyRect)
@@ -1822,46 +1756,36 @@ void CanvasRenderingContext2D::didDraw(const FloatRect& dirtyRect)
GraphicsContext* CanvasRenderingContext2D::drawingContext() const
{
+ if (isContextLost())
+ return 0;
return canvas()->drawingContext();
}
-static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
+static PassRefPtrWillBeRawPtr<ImageData> createEmptyImageData(const IntSize& size)
{
- Checked<int, RecordOverflow> dataSize = 4;
- dataSize *= size.width();
- dataSize *= size.height();
- if (dataSize.hasOverflowed())
- return 0;
+ if (RefPtrWillBeRawPtr<ImageData> data = ImageData::create(size)) {
+ data->data()->zeroFill();
+ return data.release();
+ }
- RefPtr<ImageData> data = ImageData::create(size);
- data->data()->zeroFill();
- return data.release();
+ return nullptr;
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtr<ImageData> imageData, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtrWillBeRawPtr<ImageData> imageData) const
{
- if (!imageData) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
- }
-
return createEmptyImageData(imageData->size());
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionState& exceptionState) const
{
if (!sw || !sh) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return 0;
- }
- if (!std::isfinite(sw) || !std::isfinite(sh)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
+ exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is 0.", sw ? "height" : "width"));
+ return nullptr;
}
FloatSize logicalSize(fabs(sw), fabs(sh));
if (!logicalSize.isExpressibleAsIntSize())
- return 0;
+ return nullptr;
IntSize size = expandedIntSize(logicalSize);
if (size.width() < 1)
@@ -1872,26 +1796,15 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float
return createEmptyImageData(size);
}
-PassRefPtr<ImageData> CanvasRenderingContext2D::webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionState& exceptionState) const
{
- return getImageData(sx, sy, sw, sh, exceptionState);
-}
-
-PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, float sw, float sh, ExceptionState& exceptionState) const
-{
- if (!canvas()->originClean()) {
+ if (!canvas()->originClean())
exceptionState.throwSecurityError("The canvas has been tainted by cross-origin data.");
- return 0;
- }
+ else if (!sw || !sh)
+ exceptionState.throwDOMException(IndexSizeError, String::format("The source %s is 0.", sw ? "height" : "width"));
- if (!sw || !sh) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return 0;
- }
- if (!std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return 0;
- }
+ if (exceptionState.hadException())
+ return nullptr;
if (sw < 0) {
sx += sw;
@@ -1908,41 +1821,27 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy,
if (logicalRect.height() < 1)
logicalRect.setHeight(1);
if (!logicalRect.isExpressibleAsIntRect())
- return 0;
+ return nullptr;
IntRect imageDataRect = enclosingIntRect(logicalRect);
ImageBuffer* buffer = canvas()->buffer();
- if (!buffer)
+ if (!buffer || isContextLost())
return createEmptyImageData(imageDataRect.size());
RefPtr<Uint8ClampedArray> byteArray = buffer->getUnmultipliedImageData(imageDataRect);
if (!byteArray)
- return 0;
+ return nullptr;
return ImageData::create(imageDataRect.size(), byteArray.release());
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy)
{
- if (!data) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- putImageData(data, dx, dy, 0, 0, data->width(), data->height(), exceptionState);
+ putImageData(data, dx, dy, 0, 0, data->width(), data->height());
}
-void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY,
- float dirtyWidth, float dirtyHeight, ExceptionState& exceptionState)
+void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight)
{
- if (!data) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return;
- }
- if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dirtyX) || !std::isfinite(dirtyY) || !std::isfinite(dirtyWidth) || !std::isfinite(dirtyHeight)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
-
ImageBuffer* buffer = canvas()->buffer();
if (!buffer)
return;
@@ -1981,11 +1880,11 @@ String CanvasRenderingContext2D::font() const
StringBuilder serializedFont;
const FontDescription& fontDescription = state().m_font.fontDescription();
- if (fontDescription.italic())
+ if (fontDescription.style() == FontStyleItalic)
serializedFont.appendLiteral("italic ");
if (fontDescription.weight() == FontWeightBold)
serializedFont.appendLiteral("bold ");
- if (fontDescription.smallCaps() == FontSmallCapsOn)
+ if (fontDescription.variant() == FontVariantSmallCaps)
serializedFont.appendLiteral("small-caps ");
serializedFont.appendNumber(fontDescription.computedPixelSize());
@@ -2012,13 +1911,17 @@ String CanvasRenderingContext2D::font() const
void CanvasRenderingContext2D::setFont(const String& newFont)
{
+ // The style resolution required for rendering text is not available in frame-less documents.
+ if (!canvas()->document().frame())
+ return;
+
MutableStylePropertyMap::iterator i = m_fetchedFonts.find(newFont);
- RefPtr<MutableStylePropertySet> parsedStyle = i != m_fetchedFonts.end() ? i->value : 0;
+ RefPtrWillBeRawPtr<MutableStylePropertySet> parsedStyle = i != m_fetchedFonts.end() ? i->value : nullptr;
if (!parsedStyle) {
parsedStyle = MutableStylePropertySet::create();
CSSParserMode mode = m_usesCSSCompatibilityParseMode ? HTMLQuirksMode : HTMLStandardMode;
- CSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, mode, 0);
+ BisonCSSParser::parseValue(parsedStyle.get(), CSSPropertyFont, newFont, true, mode, 0);
m_fetchedFonts.add(newFont, parsedStyle);
}
if (parsedStyle->isEmpty())
@@ -2039,9 +1942,12 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
// Map the <canvas> font into the text style. If the font uses keywords like larger/smaller, these will work
// relative to the canvas.
RefPtr<RenderStyle> newStyle = RenderStyle::create();
- if (RenderStyle* computedStyle = canvas()->computedStyle())
- newStyle->setFontDescription(computedStyle->fontDescription());
- else {
+ if (RenderStyle* computedStyle = canvas()->computedStyle()) {
+ FontDescription elementFontDescription(computedStyle->fontDescription());
+ // Reset the computed size to avoid inheriting the zoom factor from the <canvas> element.
+ elementFontDescription.setComputedSize(elementFontDescription.specifiedSize());
+ newStyle->setFontDescription(elementFontDescription);
+ } else {
FontFamily fontFamily;
fontFamily.setFamily(defaultFontFamily);
@@ -2068,8 +1974,10 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
StyleResolver& styleResolver = canvas()->document().ensureStyleResolver();
styleResolver.applyPropertiesToStyle(properties, WTF_ARRAY_LENGTH(properties), newStyle.get());
+#if !ENABLE(OILPAN)
if (state().m_realizedFont)
- state().m_font.fontSelector()->unregisterForInvalidationCallbacks(&modifiableState());
+ static_cast<CSSFontSelector*>(state().m_font.fontSelector())->unregisterForInvalidationCallbacks(&modifiableState());
+#endif
modifiableState().m_font = newStyle->font();
modifiableState().m_font.update(canvas()->document().styleEngine()->fontSelector());
modifiableState().m_realizedFont = true;
@@ -2128,31 +2036,84 @@ void CanvasRenderingContext2D::strokeText(const String& text, float x, float y,
drawTextInternal(text, x, y, false, maxWidth, true);
}
-PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+static inline bool isSpaceCharacter(UChar c)
{
- FontCachePurgePreventer fontCachePurgePreventer;
- RefPtr<TextMetrics> metrics = TextMetrics::create();
- canvas()->document().updateStyleIfNeeded();
- metrics->setWidth(accessFont().width(TextRun(text)));
- return metrics.release();
+ // According to specification all space characters should be replaced with 0x0020 space character.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#text-preparation-algorithm
+ // The space characters according to specification are : U+0020, U+0009, U+000A, U+000C, and U+000D.
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#space-character
+ // This function returns true for 0x000B also, so that this is backward compatible.
+ // Otherwise, the test LayoutTests/canvas/philip/tests/2d.text.draw.space.collapse.space.html will fail
+ return c == 0x0009 || c == 0x000A || c == 0x000B || c == 0x000C || c == 0x000D;
}
-static void replaceCharacterInString(String& text, WTF::CharacterMatchFunctionPtr matchFunction, const String& replacement)
+static String normalizeSpaces(const String& text)
{
- const size_t replacementLength = replacement.length();
- size_t index = 0;
- while ((index = text.find(matchFunction, index)) != kNotFound) {
- text.replace(index, 1, replacement);
- index += replacementLength;
+ unsigned textLength = text.length();
+ Vector<UChar> charVector(textLength);
+
+ for (unsigned i = 0; i < textLength; i++) {
+ if (isSpaceCharacter(text[i]))
+ charVector[i] = ' ';
+ else
+ charVector[i] = text[i];
}
+
+ return String(charVector);
+}
+
+PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
+{
+ RefPtr<TextMetrics> metrics = TextMetrics::create();
+
+ // The style resolution required for rendering text is not available in frame-less documents.
+ if (!canvas()->document().frame())
+ return metrics.release();
+
+ FontCachePurgePreventer fontCachePurgePreventer;
+ canvas()->document().updateRenderTreeIfNeeded();
+ const Font& font = accessFont();
+ String normalizedText = normalizeSpaces(text);
+ const TextRun textRun(normalizedText);
+ FloatRect textBounds = font.selectionRectForText(textRun, FloatPoint(), font.fontDescription().computedSize(), 0, -1, true);
+
+ // x direction
+ metrics->setWidth(font.width(textRun));
+ metrics->setActualBoundingBoxLeft(-textBounds.x());
+ metrics->setActualBoundingBoxRight(textBounds.maxX());
+
+ // y direction
+ const FontMetrics& fontMetrics = font.fontMetrics();
+ const float ascent = fontMetrics.floatAscent();
+ const float descent = fontMetrics.floatDescent();
+ const float baselineY = getFontBaseline(fontMetrics);
+
+ metrics->setFontBoundingBoxAscent(ascent - baselineY);
+ metrics->setFontBoundingBoxDescent(descent + baselineY);
+ metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY);
+ metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY);
+
+ // Note : top/bottom and ascend/descend are currently the same, so there's no difference
+ // between the EM box's top and bottom and the font's ascend and descend
+ metrics->setEmHeightAscent(0);
+ metrics->setEmHeightDescent(0);
+
+ metrics->setHangingBaseline(-0.8f * ascent + baselineY);
+ metrics->setAlphabeticBaseline(baselineY);
+ metrics->setIdeographicBaseline(descent + baselineY);
+ return metrics.release();
}
void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth, bool useMaxWidth)
{
+ // The style resolution required for rendering text is not available in frame-less documents.
+ if (!canvas()->document().frame())
+ return;
+
// accessFont needs the style to be up to date, but updating style can cause script to run,
// (e.g. due to autofocus) which can free the GraphicsContext, so update style before grabbing
// the GraphicsContext.
- canvas()->document().updateStyleIfNeeded();
+ canvas()->document().updateRenderTreeIfNeeded();
GraphicsContext* c = drawingContext();
if (!c)
@@ -2177,9 +2138,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
const Font& font = accessFont();
const FontMetrics& fontMetrics = font.fontMetrics();
- // According to spec, all the space characters must be replaced with U+0020 SPACE characters.
- String normalizedText = text;
- replaceCharacterInString(normalizedText, isSpaceOrNewline, " ");
+ String normalizedText = normalizeSpaces(text);
// FIXME: Need to turn off font smoothing.
@@ -2190,24 +2149,7 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override, true, TextRun::NoRounding);
// Draw the item text at the correct point.
- FloatPoint location(x, y);
- switch (state().m_textBaseline) {
- case TopTextBaseline:
- case HangingTextBaseline:
- location.setY(y + fontMetrics.ascent());
- break;
- case BottomTextBaseline:
- case IdeographicTextBaseline:
- location.setY(y - fontMetrics.descent());
- break;
- case MiddleTextBaseline:
- location.setY(y - fontMetrics.descent() + fontMetrics.height() / 2);
- break;
- case AlphabeticTextBaseline:
- default:
- // Do nothing.
- break;
- }
+ FloatPoint location(x, y + getFontBaseline(fontMetrics));
float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override));
@@ -2240,21 +2182,40 @@ void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, flo
if (!fill)
inflateStrokeRect(textRunPaintInfo.bounds);
- FloatRect dirtyRect;
- if (!computeDirtyRect(textRunPaintInfo.bounds, &dirtyRect))
- return;
-
c->setTextDrawingMode(fill ? TextModeFill : TextModeStroke);
+
+ GraphicsContextStateSaver stateSaver(*c);
if (useMaxWidth) {
- GraphicsContextStateSaver stateSaver(*c);
c->translate(location.x(), location.y());
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
- c->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
- c->drawBidiText(font, textRunPaintInfo, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady);
- } else
- c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady);
+ c->scale((fontWidth > 0 ? (width / fontWidth) : 0), 1);
+ location = FloatPoint();
+ }
- didDraw(dirtyRect);
+ FloatRect clipBounds;
+ if (!c->getTransformedClipBounds(&clipBounds)) {
+ return;
+ }
+
+ if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+ c->beginLayer(1, state().m_globalComposite);
+ CompositeOperator previousOperator = c->compositeOperation();
+ c->setCompositeOperation(CompositeSourceOver);
+ c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady);
+ c->setCompositeOperation(previousOperator);
+ c->endLayer();
+ didDraw(clipBounds);
+ } else if (state().m_globalComposite == CompositeCopy) {
+ clearCanvas();
+ c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady);
+ didDraw(clipBounds);
+ } else {
+ FloatRect dirtyRect;
+ if (computeDirtyRect(textRunPaintInfo.bounds, clipBounds, &dirtyRect)) {
+ c->drawBidiText(font, textRunPaintInfo, location, Font::UseFallbackIfFontNotReady);
+ didDraw(dirtyRect);
+ }
+ }
}
void CanvasRenderingContext2D::inflateStrokeRect(FloatRect& rect) const
@@ -2281,6 +2242,28 @@ const Font& CanvasRenderingContext2D::accessFont()
return state().m_font;
}
+int CanvasRenderingContext2D::getFontBaseline(const FontMetrics& fontMetrics) const
+{
+ switch (state().m_textBaseline) {
+ case TopTextBaseline:
+ return fontMetrics.ascent();
+ case HangingTextBaseline:
+ // According to http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
+ // "FOP (Formatting Objects Processor) puts the hanging baseline at 80% of the ascender height"
+ return (fontMetrics.ascent() * 4) / 5;
+ case BottomTextBaseline:
+ case IdeographicTextBaseline:
+ return -fontMetrics.descent();
+ case MiddleTextBaseline:
+ return -fontMetrics.descent() + fontMetrics.height() / 2;
+ case AlphabeticTextBaseline:
+ default:
+ // Do nothing.
+ break;
+ }
+ return 0;
+}
+
blink::WebLayer* CanvasRenderingContext2D::platformLayer() const
{
return canvas()->buffer() ? canvas()->buffer()->platformLayer() : 0;
@@ -2300,7 +2283,7 @@ void CanvasRenderingContext2D::setImageSmoothingEnabled(bool enabled)
modifiableState().m_imageSmoothingEnabled = enabled;
GraphicsContext* c = drawingContext();
if (c)
- c->setImageInterpolationQuality(enabled ? DefaultInterpolationQuality : InterpolationNone);
+ c->setImageInterpolationQuality(enabled ? CanvasDefaultInterpolationQuality : InterpolationNone);
}
PassRefPtr<Canvas2DContextAttributes> CanvasRenderingContext2D::getContextAttributes() const
@@ -2310,33 +2293,31 @@ PassRefPtr<Canvas2DContextAttributes> CanvasRenderingContext2D::getContextAttrib
return attributes.release();
}
-void CanvasRenderingContext2D::drawSystemFocusRing(Element* element)
+void CanvasRenderingContext2D::drawFocusIfNeeded(Element* element)
+{
+ drawFocusIfNeededInternal(m_path, element);
+}
+
+void CanvasRenderingContext2D::drawFocusIfNeeded(Path2D* path2d, Element* element)
{
- if (!focusRingCallIsValid(m_path, element))
+ drawFocusIfNeededInternal(path2d->path(), element);
+}
+
+void CanvasRenderingContext2D::drawFocusIfNeededInternal(const Path& path, Element* element)
+{
+ if (!focusRingCallIsValid(path, element))
return;
- updateFocusRingAccessibility(m_path, element);
// Note: we need to check document->focusedElement() rather than just calling
// element->focused(), because element->focused() isn't updated until after
// focus events fire.
if (element->document().focusedElement() == element)
- drawFocusRing(m_path);
-}
-
-bool CanvasRenderingContext2D::drawCustomFocusRing(Element* element)
-{
- if (!focusRingCallIsValid(m_path, element))
- return false;
-
- updateFocusRingAccessibility(m_path, element);
-
- // Return true if the application should draw the focus ring. The spec allows us to
- // override this for accessibility, but currently Blink doesn't take advantage of this.
- return element->focused();
+ drawFocusRing(path);
}
bool CanvasRenderingContext2D::focusRingCallIsValid(const Path& path, Element* element)
{
+ ASSERT(element);
if (!state().m_invertibleCTM)
return false;
if (path.isEmpty())
@@ -2347,62 +2328,32 @@ bool CanvasRenderingContext2D::focusRingCallIsValid(const Path& path, Element* e
return true;
}
-void CanvasRenderingContext2D::updateFocusRingAccessibility(const Path& path, Element* element)
-{
- if (!canvas()->renderer())
- return;
-
- // If accessibility is already enabled in this frame, associate this path's
- // bounding box with the accessible object. Do this even if the element
- // isn't focused because assistive technology might try to explore the object's
- // location before it gets focus.
- if (AXObjectCache* axObjectCache = element->document().existingAXObjectCache()) {
- if (AXObject* obj = axObjectCache->getOrCreate(element)) {
- // Get the bounding rect and apply transformations.
- FloatRect bounds = m_path.boundingRect();
- AffineTransform ctm = state().m_transform;
- FloatRect transformedBounds = ctm.mapRect(bounds);
- LayoutRect elementRect = LayoutRect(transformedBounds);
-
- // Offset by the canvas rect and set the bounds of the accessible element.
- IntRect canvasRect = canvas()->renderer()->absoluteBoundingBoxRect();
- elementRect.moveBy(canvasRect.location());
- obj->setElementRect(elementRect);
-
- // Set the bounds of any ancestor accessible elements, up to the canvas element,
- // otherwise this element will appear to not be within its parent element.
- obj = obj->parentObject();
- while (obj && obj->node() != canvas()) {
- obj->setElementRect(elementRect);
- obj = obj->parentObject();
- }
- }
- }
-}
-
void CanvasRenderingContext2D::drawFocusRing(const Path& path)
{
GraphicsContext* c = drawingContext();
if (!c)
return;
+ // These should match the style defined in html.css.
+ Color focusRingColor = RenderTheme::theme().focusRingColor();
+ const int focusRingWidth = 5;
+ const int focusRingOutline = 0;
+
+ // We need to add focusRingWidth to dirtyRect.
+ StrokeData strokeData;
+ strokeData.setThickness(focusRingWidth);
+
FloatRect dirtyRect;
- if (!computeDirtyRect(path.boundingRect(), &dirtyRect))
+ if (!computeDirtyRect(path.strokeBoundingRect(strokeData), &dirtyRect))
return;
c->save();
- c->setAlpha(1.0);
+ c->setAlphaAsFloat(1.0);
c->clearShadow();
c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal);
-
- // These should match the style defined in html.css.
- Color focusRingColor = RenderTheme::focusRingColor();
- const int focusRingWidth = 5;
- const int focusRingOutline = 0;
c->drawFocusRing(path, focusRingWidth, focusRingOutline, focusRingColor);
-
c->restore();
-
+ validateStateStack();
didDraw(dirtyRect);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h
index 8493b10b149..65d883d220c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.h
@@ -26,10 +26,12 @@
#ifndef CanvasRenderingContext2D_h
#define CanvasRenderingContext2D_h
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/css/CSSFontSelectorClient.h"
#include "core/html/canvas/Canvas2DContextAttributes.h"
#include "core/html/canvas/CanvasPathMethods.h"
#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/svg/SVGMatrix.h"
+#include "core/svg/SVGMatrixTearOff.h"
#include "platform/fonts/Font.h"
#include "platform/graphics/Color.h"
#include "platform/geometry/FloatSize.h"
@@ -45,10 +47,11 @@ namespace blink { class WebLayer; }
namespace WebCore {
+class CanvasImageSource;
class CanvasGradient;
class CanvasPattern;
class CanvasStyle;
-class DOMPath;
+class Path2D;
class Element;
class ExceptionState;
class FloatRect;
@@ -60,13 +63,13 @@ class ImageBitmap;
class ImageData;
class TextMetrics;
-typedef HashMap<String, RefPtr<MutableStylePropertySet> > MutableStylePropertyMap;
+typedef WillBeHeapHashMap<String, RefPtrWillBeMember<MutableStylePropertySet> > MutableStylePropertyMap;
-class CanvasRenderingContext2D : public CanvasRenderingContext, public CanvasPathMethods {
+class CanvasRenderingContext2D FINAL: public CanvasRenderingContext, public ScriptWrappable, public CanvasPathMethods {
public:
- static PassOwnPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode)
+ static PassOwnPtrWillBeRawPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode)
{
- return adoptPtr(new CanvasRenderingContext2D(canvas, attrs, usesCSSCompatibilityParseMode));
+ return adoptPtrWillBeNoop(new CanvasRenderingContext2D(canvas, attrs, usesCSSCompatibilityParseMode));
}
virtual ~CanvasRenderingContext2D();
@@ -90,12 +93,9 @@ public:
const Vector<float>& getLineDash() const;
void setLineDash(const Vector<float>&);
- void setWebkitLineDash(const Vector<float>&);
float lineDashOffset() const;
void setLineDashOffset(float);
- float webkitLineDashOffset() const;
- void setWebkitLineDashOffset(float);
float shadowOffsetX() const;
void setShadowOffsetX(float);
@@ -112,17 +112,19 @@ public:
float globalAlpha() const;
void setGlobalAlpha(float);
+ bool isContextLost() const;
+
String globalCompositeOperation() const;
void setGlobalCompositeOperation(const String&);
- void save() { ++m_unrealizedSaveCount; }
+ void save() { ++m_stateStack.last()->m_unrealizedSaveCount; }
void restore();
- SVGMatrix currentTransform() const
+ PassRefPtr<SVGMatrixTearOff> currentTransform() const
{
- return SVGMatrix(state().m_transform);
+ return SVGMatrixTearOff::create(state().m_transform);
}
- void setCurrentTransform(const SVGMatrix&);
+ void setCurrentTransform(PassRefPtr<SVGMatrixTearOff>);
void scale(float sx, float sy);
void rotate(float angleInRadians);
@@ -147,14 +149,20 @@ public:
void beginPath();
- PassRefPtr<DOMPath> currentPath();
- void setCurrentPath(DOMPath*);
void fill(const String& winding = "nonzero");
+ void fill(Path2D*, const String& winding = "nonzero");
void stroke();
+ void stroke(Path2D*);
void clip(const String& winding = "nonzero");
+ void clip(Path2D*, const String& winding = "nonzero");
bool isPointInPath(const float x, const float y, const String& winding = "nonzero");
+ bool isPointInPath(Path2D*, const float x, const float y, const String& winding = "nonzero");
bool isPointInStroke(const float x, const float y);
+ bool isPointInStroke(Path2D*, const float x, const float y);
+
+ void scrollPathIntoView();
+ void scrollPathIntoView(Path2D*);
void clearRect(float x, float y, float width, float height);
void fillRect(float x, float y, float width, float height);
@@ -170,22 +178,9 @@ public:
void clearShadow();
- void drawImage(ImageBitmap*, float x, float y, ExceptionState&);
- void drawImage(ImageBitmap*, float x, float y, float width, float height, ExceptionState&);
- void drawImage(ImageBitmap*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
- void drawImage(HTMLImageElement*, float x, float y, ExceptionState&);
- void drawImage(HTMLImageElement*, float x, float y, float width, float height, ExceptionState&);
- void drawImage(HTMLImageElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
- void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
- void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const blink::WebBlendMode&, ExceptionState&);
- void drawImage(HTMLCanvasElement*, float x, float y, ExceptionState&);
- void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionState&);
- void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
- void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
- void drawImage(HTMLVideoElement*, float x, float y, ExceptionState&);
- void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionState&);
- void drawImage(HTMLVideoElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
- void drawImage(HTMLVideoElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
+ void drawImage(CanvasImageSource*, float x, float y, ExceptionState&);
+ void drawImage(CanvasImageSource*, float x, float y, float width, float height, ExceptionState&);
+ void drawImage(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
void drawImageFromRect(HTMLImageElement*, float sx = 0, float sy = 0, float sw = 0, float sh = 0,
float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString());
@@ -194,22 +189,15 @@ public:
void setCompositeOperation(const String&);
- PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionState&);
+ PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1);
PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionState&);
- PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionState&);
- PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionState&);
+ PassRefPtr<CanvasPattern> createPattern(CanvasImageSource*, const String& repetitionType, ExceptionState&);
- PassRefPtr<ImageData> createImageData(PassRefPtr<ImageData>, ExceptionState&) const;
- PassRefPtr<ImageData> createImageData(float width, float height, ExceptionState&) const;
- PassRefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionState&) const;
- void putImageData(ImageData*, float dx, float dy, ExceptionState&);
- void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionState&);
-
- // Slated for deprecation:
- void webkitPutImageDataHD(ImageData* image, float dx, float dy, ExceptionState& e) { putImageData(image, dx, dy, e); }
- void webkitPutImageDataHD(ImageData* image, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionState& e) { putImageData(image, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight, e); }
- PassRefPtr<ImageData> webkitGetImageDataHD(float sx, float sy, float sw, float sh, ExceptionState&) const;
- float webkitBackingStorePixelRatio() const { return 1; }
+ PassRefPtrWillBeRawPtr<ImageData> createImageData(PassRefPtrWillBeRawPtr<ImageData>) const;
+ PassRefPtrWillBeRawPtr<ImageData> createImageData(float width, float height, ExceptionState&) const;
+ PassRefPtrWillBeRawPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionState&) const;
+ void putImageData(ImageData*, float dx, float dy);
+ void putImageData(ImageData*, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
void reset();
@@ -236,18 +224,29 @@ public:
PassRefPtr<Canvas2DContextAttributes> getContextAttributes() const;
- void drawSystemFocusRing(Element*);
- bool drawCustomFocusRing(Element*);
+ void drawFocusIfNeeded(Element*);
+ void drawFocusIfNeeded(Path2D*, Element*);
+
+ void loseContext();
+ void restoreContext();
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- struct State : FontSelectorClient {
+ class State FINAL : public CSSFontSelectorClient {
+ public:
State();
virtual ~State();
State(const State&);
State& operator=(const State&);
- virtual void fontsNeedUpdate(FontSelector*) OVERRIDE;
+ // CSSFontSelectorClient implementation
+ virtual void fontsNeedUpdate(CSSFontSelector*) OVERRIDE;
+
+ virtual void trace(Visitor* visitor) OVERRIDE { CSSFontSelectorClient::trace(visitor); }
+
+ unsigned m_unrealizedSaveCount;
String m_unparsedStrokeColor;
String m_unparsedFillColor;
@@ -280,15 +279,18 @@ private:
CanvasRenderingContext2D(HTMLCanvasElement*, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode);
- State& modifiableState() { ASSERT(!m_unrealizedSaveCount); return m_stateStack.last(); }
- const State& state() const { return m_stateStack.last(); }
+ State& modifiableState() { ASSERT(!state().m_unrealizedSaveCount); return *m_stateStack.last(); }
+ const State& state() const { return *m_stateStack.last(); }
void applyLineDash() const;
void setShadow(const FloatSize& offset, float blur, RGBA32 color);
void applyShadow();
bool shouldDrawShadows() const;
- void drawImageInternal(Image*, const FloatRect&, const FloatRect&, const CompositeOperator&, const blink::WebBlendMode&);
+ void dispatchContextLostEvent(Timer<CanvasRenderingContext2D>*);
+ void dispatchContextRestoredEvent(Timer<CanvasRenderingContext2D>*);
+ void tryRestoreContextEvent(Timer<CanvasRenderingContext2D>*);
+
bool computeDirtyRect(const FloatRect& localBounds, FloatRect*);
bool computeDirtyRect(const FloatRect& localBounds, const FloatRect& transformedClipBounds, FloatRect*);
void didDraw(const FloatRect&);
@@ -296,19 +298,27 @@ private:
GraphicsContext* drawingContext() const;
void unwindStateStack();
- void realizeSaves()
- {
- if (m_unrealizedSaveCount)
- realizeSavesLoop();
- }
- void realizeSavesLoop();
+ void realizeSaves();
void applyStrokePattern();
void applyFillPattern();
+ void drawImageInternal(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&, CompositeOperator, blink::WebBlendMode);
+ void drawVideo(HTMLVideoElement*, FloatRect srcRect, FloatRect dstRect);
+
+ void fillInternal(const Path&, const String& windingRuleString);
+ void strokeInternal(const Path&);
+ void clipInternal(const Path&, const String& windingRuleString);
+
+ bool isPointInPathInternal(const Path&, const float x, const float y, const String& windingRuleString);
+ bool isPointInStrokeInternal(const Path&, const float x, const float y);
+
+ void scrollPathIntoViewInternal(const Path&);
+
void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
const Font& accessFont();
+ int getFontBaseline(const FontMetrics&) const;
void clearCanvas();
bool rectContainsTransformedRect(const FloatRect&, const FloatRect&) const;
@@ -316,25 +326,34 @@ private:
void inflateStrokeRect(FloatRect&) const;
template<class T> void fullCanvasCompositedFill(const T&);
+ template<class T> void fullCanvasCompositedStroke(const T&);
template<class T> void fullCanvasCompositedDrawImage(T*, const FloatRect&, const FloatRect&, CompositeOperator);
+ void drawFocusIfNeededInternal(const Path&, Element*);
bool focusRingCallIsValid(const Path&, Element*);
- void updateFocusRingAccessibility(const Path&, Element*);
void drawFocusRing(const Path&);
+ void validateStateStack();
+
virtual bool is2d() const OVERRIDE { return true; }
virtual bool isAccelerated() const OVERRIDE;
virtual bool hasAlpha() const OVERRIDE { return m_hasAlpha; }
- virtual bool isTransformInvertible() const { return state().m_invertibleCTM; }
+ virtual bool isTransformInvertible() const OVERRIDE { return state().m_invertibleCTM; }
virtual blink::WebLayer* platformLayer() const OVERRIDE;
- Vector<State, 1> m_stateStack;
- unsigned m_unrealizedSaveCount;
+ WillBeHeapVector<OwnPtrWillBeMember<State> > m_stateStack;
bool m_usesCSSCompatibilityParseMode;
bool m_hasAlpha;
+ bool m_isContextLost;
+ bool m_contextRestorable;
+ Canvas2DContextStorage m_storageMode;
MutableStylePropertyMap m_fetchedFonts;
+ unsigned m_tryRestoreContextAttemptCount;
+ Timer<CanvasRenderingContext2D> m_dispatchContextLostEventTimer;
+ Timer<CanvasRenderingContext2D> m_dispatchContextRestoredEventTimer;
+ Timer<CanvasRenderingContext2D> m_tryRestoreContextEventTimer;
};
DEFINE_TYPE_CASTS(CanvasRenderingContext2D, CanvasRenderingContext, context, context->is2d(), context.is2d());
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl
index 1c243a6b4a0..1738af041a4 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasRenderingContext2D.idl
@@ -23,154 +23,160 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-enum CanvasWindingRule { "nonzero", "evenodd" };
-
-interface CanvasRenderingContext2D : CanvasRenderingContext {
-
- void save();
- void restore();
-
- [RuntimeEnabled=ExperimentalCanvasFeatures, Immutable] attribute SVGMatrix currentTransform;
- void scale(float sx, float sy);
- void rotate(float angle);
- void translate(float tx, float ty);
- void transform(float m11, float m12, float m21, float m22, float dx, float dy);
- void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#canvasrenderingcontext2d
+
+// FIXME: float => double throughout
+// FIXME: Use union type in drawImage and createPattern once supported:
+// http://crbug.com/372891
+typedef (HTMLImageElement or
+ HTMLVideoElement or
+ HTMLCanvasElement // or
+ // CanvasRenderingContext2D or
+ // ImageBitmap
+ ) CanvasImageSource;
+
+enum CanvasFillRule { "nonzero", "evenodd" };
+
+[
+ TypeChecking=Interface|Nullable|Unrestricted,
+ WillBeGarbageCollected,
+] interface CanvasRenderingContext2D {
+ // back-reference to the canvas
+ readonly attribute HTMLCanvasElement canvas;
+
+ // state
+ void save(); // push state on state stack
+ void restore(); // pop state stack and restore state
+
+ // transformations (default transform is the identity matrix)
+ [RuntimeEnabled=ExperimentalCanvasFeatures] attribute SVGMatrix currentTransform;
+ void scale(unrestricted float x, unrestricted float y);
+ void rotate(unrestricted float angle);
+ void translate(unrestricted float x, unrestricted float y);
+ void transform(unrestricted float a, unrestricted float b, unrestricted float c, unrestricted float d, unrestricted float e, unrestricted float f);
+ void setTransform(unrestricted float a, unrestricted float b, unrestricted float c, unrestricted float d, unrestricted float e, unrestricted float f);
void resetTransform();
- attribute float globalAlpha;
- [TreatNullAs=NullString] attribute DOMString globalCompositeOperation;
+ // compositing
+ attribute unrestricted float globalAlpha; // (default 1.0)
+ [TreatNullAs=NullString] attribute DOMString globalCompositeOperation; // (default source-over)
- [RaisesException] CanvasGradient createLinearGradient(float x0, float y0, float x1, float y1);
- [RaisesException] CanvasGradient createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
-
- attribute float lineWidth;
- [TreatNullAs=NullString] attribute DOMString lineCap;
- [TreatNullAs=NullString] attribute DOMString lineJoin;
- attribute float miterLimit;
+ // image smoothing
+ [ImplementedAs=imageSmoothingEnabled, MeasureAs=PrefixedImageSmoothingEnabled] attribute boolean webkitImageSmoothingEnabled;
+ [MeasureAs=UnprefixedImageSmoothingEnabled] attribute boolean imageSmoothingEnabled;
- attribute float shadowOffsetX;
- attribute float shadowOffsetY;
- attribute float shadowBlur;
+ // colors and styles (see also the CanvasDrawingStyles interface)
+ // FIXME: Use union types when supported: http://crbug.com/372891
+ [Custom] attribute object strokeStyle; // (default black)
+ [Custom] attribute object fillStyle; // (default black)
+ CanvasGradient createLinearGradient(float x0, float y0, float x1, float y1);
+ [RaisesException] CanvasGradient createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1);
+ [RaisesException] CanvasPattern createPattern(HTMLCanvasElement canvas, [TreatNullAs=NullString] DOMString repetitionType);
+ [RaisesException] CanvasPattern createPattern(HTMLImageElement image, [TreatNullAs=NullString] DOMString repetitionType);
+ [RaisesException] CanvasPattern createPattern(HTMLVideoElement image, [TreatNullAs=NullString] DOMString repetitionType);
+
+ // shadows
+ attribute unrestricted float shadowOffsetX;
+ attribute unrestricted float shadowOffsetY;
+ attribute unrestricted float shadowBlur;
[TreatNullAs=NullString] attribute DOMString shadowColor;
- void setLineDash(sequence<float> dash);
- sequence<float> getLineDash();
- attribute float lineDashOffset;
-
- // FIXME: These attributes should be implemented.
- // [Custom] attribute Array webkitLineDash;
- // attribute float webkitLineDashOffset;
-
- void clearRect(float x, float y, float width, float height);
- void fillRect(float x, float y, float width, float height);
+ // rects
+ void clearRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ void fillRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ void strokeRect(unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ // path API (see also CanvasPathMethods)
void beginPath();
-
- attribute Path currentPath;
-
- // FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
- void closePath();
- void moveTo(float x, float y);
- void lineTo(float x, float y);
- void quadraticCurveTo(float cpx, float cpy, float x, float y);
- void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
- [RaisesException] void arcTo(float x1, float y1, float x2, float y2, float radius);
- void rect(float x, float y, float width, float height);
- [RaisesException] void arc(float x, float y, float radius, float startAngle, float endAngle, [Default=Undefined] optional boolean anticlockwise);
- [RaisesException] void ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, boolean anticlockwise);
-
- void fill(optional CanvasWindingRule winding);
+ void fill(optional CanvasFillRule winding);
+ [RuntimeEnabled=Path2D] void fill(Path2D path, optional CanvasFillRule winding);
void stroke();
- void clip(optional CanvasWindingRule winding);
- boolean isPointInPath(float x, float y, optional CanvasWindingRule winding);
- boolean isPointInStroke(float x, float y);
-
- // text
- attribute DOMString font;
- attribute DOMString textAlign;
- attribute DOMString textBaseline;
-
+ [RuntimeEnabled=Path2D] void stroke(Path2D path);
+ // Focus rings
+ void drawFocusIfNeeded(Element element);
+ [RuntimeEnabled=Path2D] void drawFocusIfNeeded(Path2D path, Element element);
+
+ [RuntimeEnabled=ExperimentalCanvasFeatures] void scrollPathIntoView(optional Path2D path);
+ void clip(optional CanvasFillRule winding);
+ [RuntimeEnabled=Path2D] void clip(Path2D path, optional CanvasFillRule winding);
+ boolean isPointInPath(unrestricted float x, unrestricted float y, optional CanvasFillRule winding);
+ [RuntimeEnabled=Path2D] boolean isPointInPath(Path2D path, unrestricted float x, unrestricted float y, optional CanvasFillRule winding);
+ boolean isPointInStroke(unrestricted float x, unrestricted float y);
+ [RuntimeEnabled=Path2D] boolean isPointInStroke(Path2D path, unrestricted float x, unrestricted float y);
+
+ // text (see also the CanvasDrawingStyles interface)
+ void fillText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
+ void strokeText(DOMString text, unrestricted float x, unrestricted float y, optional unrestricted float maxWidth);
TextMetrics measureText(DOMString text);
- // other
-
- void setAlpha(float alpha);
- void setCompositeOperation(DOMString compositeOperation);
-
- void setLineWidth(float width);
- void setLineCap(DOMString cap);
- void setLineJoin(DOMString join);
- void setMiterLimit(float limit);
-
- void clearShadow();
-
- void fillText(DOMString text, float x, float y, optional float maxWidth);
- void strokeText(DOMString text, float x, float y, optional float maxWidth);
-
- void setStrokeColor([StrictTypeChecking] DOMString color, optional float alpha);
- void setStrokeColor(float grayLevel, optional float alpha);
- void setStrokeColor(float r, float g, float b, float a);
- void setStrokeColor(float c, float m, float y, float k, float a);
-
- void setFillColor([StrictTypeChecking] DOMString color, optional float alpha);
- void setFillColor(float grayLevel, optional float alpha);
- void setFillColor(float r, float g, float b, float a);
- void setFillColor(float c, float m, float y, float k, float a);
-
- void strokeRect(float x, float y, float width, float height);
-
- [RaisesException] void drawImage(HTMLImageElement? image, float x, float y);
- [RaisesException] void drawImage(HTMLImageElement? image, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLImageElement? image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float x, float y);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLCanvasElement? canvas, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
- [RaisesException] void drawImage(HTMLVideoElement? video, float x, float y);
- [RaisesException] void drawImage(HTMLVideoElement? video, float x, float y, float width, float height);
- [RaisesException] void drawImage(HTMLVideoElement? video, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
- [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap? imageBitmap, float x, float y);
- [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap? imageBitmap, float x, float y, float width, float height);
- [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap? imageBitmap, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh);
-
- void drawImageFromRect(HTMLImageElement image,
- optional float sx, optional float sy, optional float sw, optional float sh,
- optional float dx, optional float dy, optional float dw, optional float dh,
- optional DOMString compositeOperation);
-
- void setShadow(float width, float height, float blur, [StrictTypeChecking] optional DOMString color, optional float alpha);
- void setShadow(float width, float height, float blur, float grayLevel, optional float alpha);
- void setShadow(float width, float height, float blur, float r, float g, float b, float a);
- void setShadow(float width, float height, float blur, float c, float m, float y, float k, float a);
-
- [RaisesException] void putImageData(ImageData? imagedata, float dx, float dy);
- [RaisesException] void putImageData(ImageData? imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
-
- [RaisesException] void webkitPutImageDataHD(ImageData? imagedata, float dx, float dy);
- [RaisesException] void webkitPutImageDataHD(ImageData? imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
-
- [RaisesException] CanvasPattern createPattern(HTMLCanvasElement? canvas, [TreatNullAs=NullString] DOMString repetitionType);
- [RaisesException] CanvasPattern createPattern(HTMLImageElement? image, [TreatNullAs=NullString] DOMString repetitionType);
- [RaisesException] ImageData createImageData(ImageData? imagedata);
- [RaisesException] ImageData createImageData(float sw, float sh);
-
- [Custom] attribute object strokeStyle;
- [Custom] attribute object fillStyle;
+ // drawing images
+ [RaisesException] void drawImage(HTMLImageElement image, unrestricted float x, unrestricted float y);
+ [RaisesException] void drawImage(HTMLImageElement image, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RaisesException] void drawImage(HTMLImageElement image, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
+ [RaisesException] void drawImage(HTMLCanvasElement canvas, unrestricted float x, unrestricted float y);
+ [RaisesException] void drawImage(HTMLCanvasElement canvas, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RaisesException] void drawImage(HTMLCanvasElement canvas, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
+ [RaisesException] void drawImage(HTMLVideoElement video, unrestricted float x, unrestricted float y);
+ [RaisesException] void drawImage(HTMLVideoElement video, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RaisesException] void drawImage(HTMLVideoElement video, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
+ [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap imageBitmap, unrestricted float x, unrestricted float y);
+ [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap imageBitmap, unrestricted float x, unrestricted float y, unrestricted float width, unrestricted float height);
+ [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void drawImage(ImageBitmap imageBitmap, unrestricted float sx, unrestricted float sy, unrestricted float sw, unrestricted float sh, unrestricted float dx, unrestricted float dy, unrestricted float dw, unrestricted float dh);
// pixel manipulation
+ ImageData createImageData(ImageData imagedata);
+ [RaisesException] ImageData createImageData(float sw, float sh);
[RaisesException] ImageData getImageData(float sx, float sy, float sw, float sh);
+ void putImageData(ImageData imagedata, float dx, float dy);
+ void putImageData(ImageData imagedata, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight);
- [RaisesException] ImageData webkitGetImageDataHD(float sx, float sy, float sw, float sh);
+ // Context state
+ // Should be merged with WebGL counterpart in CanvasRenderingContext, once no-longer experimental
+ [RuntimeEnabled=ExperimentalCanvasFeatures] boolean isContextLost();
- // Focus rings
- [RuntimeEnabled=ExperimentalCanvasFeatures] void drawSystemFocusRing(Element element);
- [RuntimeEnabled=ExperimentalCanvasFeatures] boolean drawCustomFocusRing(Element element);
+ Canvas2DContextAttributes getContextAttributes();
- readonly attribute float webkitBackingStorePixelRatio;
+ // FIXME: factor out to CanvasDrawingStyles
+ // line caps/joins
+ attribute unrestricted float lineWidth; // (default 1)
+ [TreatNullAs=NullString] attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
+ [TreatNullAs=NullString] attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
+ attribute unrestricted float miterLimit; // (default 10)
- [ImplementedAs=imageSmoothingEnabled] attribute boolean webkitImageSmoothingEnabled;
- attribute boolean imageSmoothingEnabled;
+ // dashed lines
+ void setLineDash(sequence<unrestricted float> dash);
+ sequence<unrestricted float> getLineDash();
+ attribute unrestricted float lineDashOffset;
- Canvas2DContextAttributes getContextAttributes();
+ // text
+ attribute DOMString font; // (default 10px sans-serif)
+ attribute DOMString textAlign; // "start", "end", "left", "right", "center" (default: "start")
+ attribute DOMString textBaseline; // "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" (default: "alphabetic")
+
+ // Non-standard APIs. Candidates for deprecation
+ // https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D
+ [MeasureAs=CanvasRenderingContext2DSetAlpha] void setAlpha(unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetCompositeOperation] void setCompositeOperation(DOMString compositeOperation);
+ [MeasureAs=CanvasRenderingContext2DSetLineWidth] void setLineWidth(unrestricted float width);
+ [MeasureAs=CanvasRenderingContext2DSetLineCap] void setLineCap(DOMString cap);
+ [MeasureAs=CanvasRenderingContext2DSetLineJoin] void setLineJoin(DOMString join);
+ [MeasureAs=CanvasRenderingContext2DSetMiterLimit] void setMiterLimit(unrestricted float limit);
+ [MeasureAs=CanvasRenderingContext2DClearShadow] void clearShadow();
+ [MeasureAs=CanvasRenderingContext2DSetStrokeColor] void setStrokeColor(DOMString color, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetStrokeColor] void setStrokeColor(unrestricted float grayLevel, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetStrokeColor] void setStrokeColor(unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DSetStrokeColor] void setStrokeColor(unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DSetFillColor] void setFillColor(DOMString color, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetFillColor] void setFillColor(unrestricted float grayLevel, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetFillColor] void setFillColor(unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DSetFillColor] void setFillColor(unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DDrawImageFromRect] void drawImageFromRect(
+ HTMLImageElement? image, optional unrestricted float sx, optional unrestricted float sy, optional unrestricted float sw, optional unrestricted float sh,
+ optional unrestricted float dx, optional unrestricted float dy, optional unrestricted float dw, optional unrestricted float dh, optional DOMString compositeOperation);
+ [MeasureAs=CanvasRenderingContext2DSetShadow] void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, optional DOMString color, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetShadow] void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float grayLevel, optional unrestricted float alpha);
+ [MeasureAs=CanvasRenderingContext2DSetShadow] void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float r, unrestricted float g, unrestricted float b, unrestricted float a);
+ [MeasureAs=CanvasRenderingContext2DSetShadow] void setShadow(unrestricted float width, unrestricted float height, unrestricted float blur, unrestricted float c, unrestricted float m, unrestricted float y, unrestricted float k, unrestricted float a);
};
+CanvasRenderingContext2D implements CanvasPathMethods;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp
index b68421af1f6..ae7e6d41b70 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.cpp
@@ -29,8 +29,8 @@
#include "config.h"
#include "core/html/canvas/CanvasStyle.h"
-#include "CSSPropertyNames.h"
-#include "core/css/CSSParser.h"
+#include "core/CSSPropertyNames.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/StylePropertySet.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/html/canvas/CanvasGradient.h"
@@ -42,13 +42,14 @@ namespace WebCore {
enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParsedSystemColor, ParseFailed };
-static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString, Document* document = 0)
+static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString)
{
if (equalIgnoringCase(colorString, "currentcolor"))
return ParsedCurrentColor;
- if (CSSParser::parseColor(parsedColor, colorString))
+ const bool useStrictParsing = true;
+ if (BisonCSSParser::parseColor(parsedColor, colorString, useStrictParsing))
return ParsedRGBA;
- if (CSSParser::parseSystemColor(parsedColor, colorString, document))
+ if (BisonCSSParser::parseSystemColor(parsedColor, colorString))
return ParsedSystemColor;
return ParseFailed;
}
@@ -58,13 +59,13 @@ RGBA32 currentColor(HTMLCanvasElement* canvas)
if (!canvas || !canvas->inDocument() || !canvas->inlineStyle())
return Color::black;
RGBA32 rgba = Color::black;
- CSSParser::parseColor(rgba, canvas->inlineStyle()->getPropertyValue(CSSPropertyColor));
+ BisonCSSParser::parseColor(rgba, canvas->inlineStyle()->getPropertyValue(CSSPropertyColor));
return rgba;
}
bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement* canvas)
{
- ColorParseResult parseResult = parseColor(parsedColor, colorString, canvas ? &canvas->document() : 0);
+ ColorParseResult parseResult = parseColor(parsedColor, colorString);
switch (parseResult) {
case ParsedRGBA:
case ParsedSystemColor:
@@ -123,10 +124,10 @@ CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
{
}
-PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color, Document* document)
+PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color)
{
RGBA32 rgba;
- ColorParseResult parseResult = parseColor(rgba, color, document);
+ ColorParseResult parseResult = parseColor(rgba, color);
switch (parseResult) {
case ParsedRGBA:
case ParsedSystemColor:
@@ -134,10 +135,10 @@ PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color, Docum
case ParsedCurrentColor:
return adoptRef(new CanvasStyle(CurrentColor));
case ParseFailed:
- return 0;
+ return nullptr;
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
}
@@ -151,23 +152,24 @@ PassRefPtr<CanvasStyle> CanvasStyle::createFromStringWithOverrideAlpha(const Str
case ParsedCurrentColor:
return adoptRef(new CanvasStyle(CurrentColorWithOverrideAlpha, alpha));
case ParseFailed:
- return 0;
+ return nullptr;
default:
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
}
PassRefPtr<CanvasStyle> CanvasStyle::createFromGradient(PassRefPtr<CanvasGradient> gradient)
{
if (!gradient)
- return 0;
+ return nullptr;
return adoptRef(new CanvasStyle(gradient));
}
+
PassRefPtr<CanvasStyle> CanvasStyle::createFromPattern(PassRefPtr<CanvasPattern> pattern)
{
if (!pattern)
- return 0;
+ return nullptr;
return adoptRef(new CanvasStyle(pattern));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h
index 526ab716345..f939e3e8214 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/CanvasStyle.h
@@ -36,14 +36,13 @@ namespace WebCore {
class CanvasGradient;
class CanvasPattern;
- class Document;
class GraphicsContext;
class HTMLCanvasElement;
class CanvasStyle : public RefCounted<CanvasStyle> {
public:
static PassRefPtr<CanvasStyle> createFromRGBA(RGBA32 rgba) { return adoptRef(new CanvasStyle(rgba)); }
- static PassRefPtr<CanvasStyle> createFromString(const String& color, Document* = 0);
+ static PassRefPtr<CanvasStyle> createFromString(const String& color);
static PassRefPtr<CanvasStyle> createFromStringWithOverrideAlpha(const String& color, float alpha);
static PassRefPtr<CanvasStyle> createFromGrayLevelWithAlpha(float grayLevel, float alpha) { return adoptRef(new CanvasStyle(grayLevel, alpha)); }
static PassRefPtr<CanvasStyle> createFromRGBAChannels(float r, float g, float b, float a) { return adoptRef(new CanvasStyle(r, g, b, a)); }
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/DOMPath.h b/chromium/third_party/WebKit/Source/core/html/canvas/DOMPath.h
deleted file mode 100644
index 9ce2cba9512..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/canvas/DOMPath.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef DOMPath_h
-#define DOMPath_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/html/canvas/CanvasPathMethods.h"
-#include "core/svg/SVGPathUtilities.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-class DOMPath : public RefCounted<DOMPath>, public CanvasPathMethods, public ScriptWrappable {
- WTF_MAKE_NONCOPYABLE(DOMPath); WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassRefPtr<DOMPath> create() { return adoptRef(new DOMPath); }
- static PassRefPtr<DOMPath> create(const String& pathData) { return adoptRef(new DOMPath(pathData)); }
- static PassRefPtr<DOMPath> create(DOMPath* path) { return adoptRef(new DOMPath(path)); }
-
- static PassRefPtr<DOMPath> create(const Path& path) { return adoptRef(new DOMPath(path)); }
-
- const Path& path() const { return m_path; }
-
- virtual ~DOMPath() { }
-private:
- DOMPath() : CanvasPathMethods()
- {
- ScriptWrappable::init(this);
- }
-
- DOMPath(const Path& path)
- : CanvasPathMethods()
- {
- ScriptWrappable::init(this);
- m_path = path;
- }
-
- DOMPath(DOMPath* path)
- : CanvasPathMethods()
- {
- ScriptWrappable::init(this);
- m_path = path->path();
- }
-
- DOMPath(const String& pathData)
- : CanvasPathMethods()
- {
- ScriptWrappable::init(this);
- buildPathFromString(pathData, m_path);
- }
-};
-
-}
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp
index 5a28161937c..41b6cb3332d 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.cpp
@@ -47,19 +47,19 @@ PassRefPtr<DataView> DataView::create(unsigned length)
{
RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, sizeof(uint8_t));
if (!buffer.get())
- return 0;
+ return nullptr;
return create(buffer, 0, length);
}
PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
{
if (byteOffset > buffer->byteLength())
- return 0;
+ return nullptr;
CheckedInt<uint32_t> checkedOffset(byteOffset);
CheckedInt<uint32_t> checkedLength(byteLength);
CheckedInt<uint32_t> checkedMax = checkedOffset + checkedLength;
if (!checkedMax.isValid() || checkedMax.value() > buffer->byteLength())
- return 0;
+ return nullptr;
return adoptRef(new DataView(buffer, byteOffset, byteLength));
}
@@ -133,7 +133,7 @@ template<typename T>
T DataView::getData(unsigned byteOffset, bool littleEndian, ExceptionState& exceptionState) const
{
if (beyondRange<T>(byteOffset)) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The provided offset (" + String::number(byteOffset) + ") is outside the allowed range.");
return 0;
}
@@ -148,7 +148,7 @@ template<typename T>
void DataView::setData(unsigned byteOffset, T value, bool littleEndian, ExceptionState& exceptionState)
{
if (beyondRange<T>(byteOffset)) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The provided offset (" + String::number(byteOffset) + ") is outside the allowed range.");
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.h b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.h
index 4a9728d845e..d497eae2f97 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.h
@@ -34,14 +34,12 @@ namespace WebCore {
class ExceptionState;
-class DataView : public ArrayBufferView, public ScriptWrappable {
+class DataView FINAL : public ArrayBufferView, public ScriptWrappable {
public:
static PassRefPtr<DataView> create(unsigned length);
static PassRefPtr<DataView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
- virtual unsigned length() const { return m_byteLength; }
- virtual unsigned byteLength() const { return m_byteLength; }
- virtual PassRefPtr<ArrayBufferView> slice(int, int) const { return 0; }
+ virtual unsigned byteLength() const OVERRIDE { return m_byteLength; }
int8_t getInt8(unsigned byteOffset, ExceptionState&);
uint8_t getUint8(unsigned byteOffset, ExceptionState&);
@@ -73,13 +71,13 @@ public:
void setFloat64(unsigned byteOffset, double value, ExceptionState& ec) { setFloat64(byteOffset, value, false, ec); }
void setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionState&);
- virtual ViewType getType() const
+ virtual ViewType type() const OVERRIDE
{
return TypeDataView;
}
protected:
- virtual void neuter();
+ virtual void neuter() OVERRIDE;
private:
DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl
index a9b9facac3e..4fc89615027 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/DataView.idl
@@ -26,30 +26,30 @@
[
Custom=Wrap,
CustomConstructor(ArrayBuffer buffer, optional unsigned long byteOffset, optional unsigned long byteLength),
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker,
+ TypeChecking=Interface|Nullable,
] interface DataView : ArrayBufferView {
// All these methods raise an exception if they would read or write beyond the end of the view.
[RaisesException] byte getInt8(unsigned long byteOffset);
[RaisesException] octet getUint8(unsigned long byteOffset);
- [StrictTypeChecking, RaisesException] short getInt16(unsigned long byteOffset, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] unsigned short getUint16(unsigned long byteOffset, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] long getInt32(unsigned long byteOffset, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] unsigned long getUint32(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] short getInt16(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] unsigned short getUint16(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] long getInt32(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] unsigned long getUint32(unsigned long byteOffset, optional boolean littleEndian);
// Use custom code to handle NaN case for JSC.
- [StrictTypeChecking, RaisesException] float getFloat32(unsigned long byteOffset, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] double getFloat64(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] float getFloat32(unsigned long byteOffset, optional boolean littleEndian);
+ [RaisesException] double getFloat64(unsigned long byteOffset, optional boolean littleEndian);
[RaisesException] void setInt8(unsigned long byteOffset, byte value);
[RaisesException] void setUint8(unsigned long byteOffset, octet value);
- [StrictTypeChecking, RaisesException] void setInt16(unsigned long byteOffset, short value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setUint16(unsigned long byteOffset, unsigned short value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setInt32(unsigned long byteOffset, long value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setUint32(unsigned long byteOffset, unsigned long value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setFloat32(unsigned long byteOffset, float value, optional boolean littleEndian);
- [StrictTypeChecking, RaisesException] void setFloat64(unsigned long byteOffset, double value, optional boolean littleEndian);
+ [RaisesException] void setInt16(unsigned long byteOffset, short value, optional boolean littleEndian);
+ [RaisesException] void setUint16(unsigned long byteOffset, unsigned short value, optional boolean littleEndian);
+ [RaisesException] void setInt32(unsigned long byteOffset, long value, optional boolean littleEndian);
+ [RaisesException] void setUint32(unsigned long byteOffset, unsigned long value, optional boolean littleEndian);
+ [RaisesException] void setFloat32(unsigned long byteOffset, float value, optional boolean littleEndian);
+ [RaisesException] void setFloat64(unsigned long byteOffset, double value, optional boolean littleEndian);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.cpp
new file mode 100644
index 00000000000..8ded7388912
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.cpp
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/html/canvas/EXTBlendMinMax.h"
+
+namespace WebCore {
+
+EXTBlendMinMax::EXTBlendMinMax(WebGLRenderingContextBase* context)
+ : WebGLExtension(context)
+{
+ ScriptWrappable::init(this);
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_blend_minmax");
+}
+
+EXTBlendMinMax::~EXTBlendMinMax()
+{
+}
+
+WebGLExtensionName EXTBlendMinMax::name() const
+{
+ return EXTBlendMinMaxName;
+}
+
+PassRefPtr<EXTBlendMinMax> EXTBlendMinMax::create(WebGLRenderingContextBase* context)
+{
+ return adoptRef(new EXTBlendMinMax(context));
+}
+
+bool EXTBlendMinMax::supported(WebGLRenderingContextBase* context)
+{
+ return context->extensionsUtil()->supportsExtension("GL_EXT_blend_minmax");
+}
+
+const char* EXTBlendMinMax::extensionName()
+{
+ return "EXT_blend_minmax";
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.h b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.h
new file mode 100644
index 00000000000..4c6421760de
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTBlendMinMax_h
+#define EXTBlendMinMax_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/WebGLExtension.h"
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class EXTBlendMinMax FINAL : public WebGLExtension, public ScriptWrappable {
+public:
+ static PassRefPtr<EXTBlendMinMax> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
+ static const char* extensionName();
+
+ virtual ~EXTBlendMinMax();
+ virtual WebGLExtensionName name() const OVERRIDE;
+
+private:
+ EXTBlendMinMax(WebGLRenderingContextBase*);
+};
+
+} // namespace WebCore
+
+#endif // EXTBlendMinMax_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.idl b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.idl
new file mode 100644
index 00000000000..55baea7d615
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTBlendMinMax.idl
@@ -0,0 +1,12 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ DoNotCheckConstants,
+ NoInterfaceObject,
+ TypeChecking=Interface|Nullable,
+] interface EXTBlendMinMax {
+ const unsigned long MIN_EXT = 0x8007;
+ const unsigned long MAX_EXT = 0x8008;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp
index a2484d283d3..002deb3df74 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.cpp
@@ -27,35 +27,32 @@
#include "core/html/canvas/EXTFragDepth.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-EXTFragDepth::EXTFragDepth(WebGLRenderingContext* context)
+EXTFragDepth::EXTFragDepth(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_EXT_frag_depth");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_frag_depth");
}
EXTFragDepth::~EXTFragDepth()
{
}
-WebGLExtension::ExtensionName EXTFragDepth::name() const
+WebGLExtensionName EXTFragDepth::name() const
{
return EXTFragDepthName;
}
-PassRefPtr<EXTFragDepth> EXTFragDepth::create(WebGLRenderingContext* context)
+PassRefPtr<EXTFragDepth> EXTFragDepth::create(WebGLRenderingContextBase* context)
{
return adoptRef(new EXTFragDepth(context));
}
-bool EXTFragDepth::supported(WebGLRenderingContext* context)
+bool EXTFragDepth::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_EXT_frag_depth");
+ return context->extensionsUtil()->supportsExtension("GL_EXT_frag_depth");
}
const char* EXTFragDepth::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h b/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h
index fc8a9fa6f8e..eee90dcc021 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTFragDepth.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class EXTFragDepth : public WebGLExtension, public ScriptWrappable {
+class EXTFragDepth FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<EXTFragDepth> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<EXTFragDepth> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~EXTFragDepth();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- explicit EXTFragDepth(WebGLRenderingContext*);
+ explicit EXTFragDepth(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.cpp
new file mode 100644
index 00000000000..d258bef94cf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.cpp
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/html/canvas/EXTShaderTextureLOD.h"
+
+namespace WebCore {
+
+EXTShaderTextureLOD::EXTShaderTextureLOD(WebGLRenderingContextBase* context)
+ : WebGLExtension(context)
+{
+ ScriptWrappable::init(this);
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_shader_texture_lod");
+}
+
+EXTShaderTextureLOD::~EXTShaderTextureLOD()
+{
+}
+
+WebGLExtensionName EXTShaderTextureLOD::name() const
+{
+ return EXTShaderTextureLODName;
+}
+
+PassRefPtr<EXTShaderTextureLOD> EXTShaderTextureLOD::create(WebGLRenderingContextBase* context)
+{
+ return adoptRef(new EXTShaderTextureLOD(context));
+}
+
+bool EXTShaderTextureLOD::supported(WebGLRenderingContextBase* context)
+{
+ return context->extensionsUtil()->supportsExtension("GL_EXT_shader_texture_lod");
+}
+
+const char* EXTShaderTextureLOD::extensionName()
+{
+ return "EXT_shader_texture_lod";
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.h b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.h
new file mode 100644
index 00000000000..342d94d0965
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXTShaderTextureLOD_h
+#define EXTShaderTextureLOD_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/WebGLExtension.h"
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class EXTShaderTextureLOD FINAL : public WebGLExtension, public ScriptWrappable {
+public:
+ static PassRefPtr<EXTShaderTextureLOD> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
+ static const char* extensionName();
+
+ virtual ~EXTShaderTextureLOD();
+ virtual WebGLExtensionName name() const OVERRIDE;
+
+private:
+ EXTShaderTextureLOD(WebGLRenderingContextBase*);
+};
+
+} // namespace WebCore
+
+#endif // EXTShaderTextureLOD_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.idl b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.idl
new file mode 100644
index 00000000000..a2e18b616ad
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTShaderTextureLOD.idl
@@ -0,0 +1,8 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ NoInterfaceObject
+] interface EXTShaderTextureLOD {
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
index 231c3c58662..d98399a4ccc 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
@@ -26,35 +26,33 @@
#include "config.h"
#include "core/html/canvas/EXTTextureFilterAnisotropic.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContext* context)
+EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_EXT_texture_filter_anisotropic");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_texture_filter_anisotropic");
}
EXTTextureFilterAnisotropic::~EXTTextureFilterAnisotropic()
{
}
-WebGLExtension::ExtensionName EXTTextureFilterAnisotropic::name() const
+WebGLExtensionName EXTTextureFilterAnisotropic::name() const
{
return EXTTextureFilterAnisotropicName;
}
-PassRefPtr<EXTTextureFilterAnisotropic> EXTTextureFilterAnisotropic::create(WebGLRenderingContext* context)
+PassRefPtr<EXTTextureFilterAnisotropic> EXTTextureFilterAnisotropic::create(WebGLRenderingContextBase* context)
{
return adoptRef(new EXTTextureFilterAnisotropic(context));
}
-bool EXTTextureFilterAnisotropic::supported(WebGLRenderingContext* context)
+bool EXTTextureFilterAnisotropic::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_EXT_texture_filter_anisotropic");
+ return context->extensionsUtil()->supportsExtension("GL_EXT_texture_filter_anisotropic");
}
const char* EXTTextureFilterAnisotropic::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h b/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
index 727f00ee086..a69a9bc3ab2 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class EXTTextureFilterAnisotropic : public WebGLExtension, public ScriptWrappable {
+class EXTTextureFilterAnisotropic FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<EXTTextureFilterAnisotropic> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<EXTTextureFilterAnisotropic> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~EXTTextureFilterAnisotropic();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- EXTTextureFilterAnisotropic(WebGLRenderingContext*);
+ EXTTextureFilterAnisotropic(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp
index a4b0e29c94d..95fac41b58c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.cpp
@@ -26,35 +26,33 @@
#include "config.h"
#include "core/html/canvas/OESElementIndexUint.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESElementIndexUint::OESElementIndexUint(WebGLRenderingContext* context)
+OESElementIndexUint::OESElementIndexUint(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_element_index_uint");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_element_index_uint");
}
OESElementIndexUint::~OESElementIndexUint()
{
}
-WebGLExtension::ExtensionName OESElementIndexUint::name() const
+WebGLExtensionName OESElementIndexUint::name() const
{
return OESElementIndexUintName;
}
-PassRefPtr<OESElementIndexUint> OESElementIndexUint::create(WebGLRenderingContext* context)
+PassRefPtr<OESElementIndexUint> OESElementIndexUint::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESElementIndexUint(context));
}
-bool OESElementIndexUint::supported(WebGLRenderingContext* context)
+bool OESElementIndexUint::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_element_index_uint");
+ return context->extensionsUtil()->supportsExtension("GL_OES_element_index_uint");
}
const char* OESElementIndexUint::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h
index 0116c1ddcf1..f11ebd251ee 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESElementIndexUint.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESElementIndexUint : public WebGLExtension, public ScriptWrappable {
+class OESElementIndexUint FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESElementIndexUint> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESElementIndexUint> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESElementIndexUint();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESElementIndexUint(WebGLRenderingContext*);
+ OESElementIndexUint(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp
index aec473bc686..49b7adff0d8 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.cpp
@@ -26,35 +26,33 @@
#include "config.h"
#include "core/html/canvas/OESStandardDerivatives.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContext* context)
+OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_standard_derivatives");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_standard_derivatives");
}
OESStandardDerivatives::~OESStandardDerivatives()
{
}
-WebGLExtension::ExtensionName OESStandardDerivatives::name() const
+WebGLExtensionName OESStandardDerivatives::name() const
{
return OESStandardDerivativesName;
}
-PassRefPtr<OESStandardDerivatives> OESStandardDerivatives::create(WebGLRenderingContext* context)
+PassRefPtr<OESStandardDerivatives> OESStandardDerivatives::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESStandardDerivatives(context));
}
-bool OESStandardDerivatives::supported(WebGLRenderingContext* context)
+bool OESStandardDerivatives::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_standard_derivatives");
+ return context->extensionsUtil()->supportsExtension("GL_OES_standard_derivatives");
}
const char* OESStandardDerivatives::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h
index 327a15286d1..8eb7226eb20 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESStandardDerivatives.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESStandardDerivatives : public WebGLExtension, public ScriptWrappable {
+class OESStandardDerivatives FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESStandardDerivatives> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESStandardDerivatives> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESStandardDerivatives();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESStandardDerivatives(WebGLRenderingContext*);
+ OESStandardDerivatives(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp
index 99d1387376c..a949e5c54b0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.cpp
@@ -26,35 +26,37 @@
#include "config.h"
#include "core/html/canvas/OESTextureFloat.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESTextureFloat::OESTextureFloat(WebGLRenderingContext* context)
+OESTextureFloat::OESTextureFloat(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_texture_float");
+ if (context->extensionsUtil()->ensureExtensionEnabled("GL_OES_texture_float")) {
+ // Implicitly enable rendering to float textures
+ context->extensionsUtil()->ensureExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb");
+ }
}
OESTextureFloat::~OESTextureFloat()
{
}
-WebGLExtension::ExtensionName OESTextureFloat::name() const
+WebGLExtensionName OESTextureFloat::name() const
{
return OESTextureFloatName;
}
-PassRefPtr<OESTextureFloat> OESTextureFloat::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureFloat> OESTextureFloat::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESTextureFloat(context));
}
-bool OESTextureFloat::supported(WebGLRenderingContext* context)
+bool OESTextureFloat::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_texture_float");
+ return context->extensionsUtil()->supportsExtension("GL_OES_texture_float");
}
const char* OESTextureFloat::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h
index 255c6741b11..dfc59086c48 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloat.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESTextureFloat : public WebGLExtension, public ScriptWrappable {
+class OESTextureFloat FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESTextureFloat> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESTextureFloat> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESTextureFloat();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESTextureFloat(WebGLRenderingContext*);
+ OESTextureFloat(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp
index 1e8518d95d6..15a7cd356a4 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.cpp
@@ -27,35 +27,32 @@
#include "core/html/canvas/OESTextureFloatLinear.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContext* context)
+OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_texture_float_linear");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_texture_float_linear");
}
OESTextureFloatLinear::~OESTextureFloatLinear()
{
}
-WebGLExtension::ExtensionName OESTextureFloatLinear::name() const
+WebGLExtensionName OESTextureFloatLinear::name() const
{
return OESTextureFloatLinearName;
}
-PassRefPtr<OESTextureFloatLinear> OESTextureFloatLinear::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureFloatLinear> OESTextureFloatLinear::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESTextureFloatLinear(context));
}
-bool OESTextureFloatLinear::supported(WebGLRenderingContext* context)
+bool OESTextureFloatLinear::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_texture_float_linear");
+ return context->extensionsUtil()->supportsExtension("GL_OES_texture_float_linear");
}
const char* OESTextureFloatLinear::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h
index 4d7f8d1af53..a0646ccd3a7 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureFloatLinear.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESTextureFloatLinear : public WebGLExtension, public ScriptWrappable {
+class OESTextureFloatLinear FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESTextureFloatLinear> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESTextureFloatLinear> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESTextureFloatLinear();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESTextureFloatLinear(WebGLRenderingContext*);
+ OESTextureFloatLinear(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp
index 7253837aa42..dd7f119c947 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.cpp
@@ -26,35 +26,33 @@
#include "config.h"
#include "core/html/canvas/OESTextureHalfFloat.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContext* context)
+OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_texture_half_float");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_texture_half_float");
}
OESTextureHalfFloat::~OESTextureHalfFloat()
{
}
-WebGLExtension::ExtensionName OESTextureHalfFloat::name() const
+WebGLExtensionName OESTextureHalfFloat::name() const
{
return OESTextureHalfFloatName;
}
-PassRefPtr<OESTextureHalfFloat> OESTextureHalfFloat::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureHalfFloat> OESTextureHalfFloat::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESTextureHalfFloat(context));
}
-bool OESTextureHalfFloat::supported(WebGLRenderingContext* context)
+bool OESTextureHalfFloat::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_texture_half_float");
+ return context->extensionsUtil()->supportsExtension("GL_OES_texture_half_float");
}
const char* OESTextureHalfFloat::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h
index 953d3110f07..dc5d917a345 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloat.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESTextureHalfFloat : public WebGLExtension, public ScriptWrappable {
+class OESTextureHalfFloat FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESTextureHalfFloat> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESTextureHalfFloat> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESTextureHalfFloat();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESTextureHalfFloat(WebGLRenderingContext*);
+ OESTextureHalfFloat(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
index c7da9bd745b..37ceabe5197 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
@@ -27,35 +27,32 @@
#include "core/html/canvas/OESTextureHalfFloatLinear.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContext* context)
+OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_texture_half_float_linear");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_texture_half_float_linear");
}
OESTextureHalfFloatLinear::~OESTextureHalfFloatLinear()
{
}
-WebGLExtension::ExtensionName OESTextureHalfFloatLinear::name() const
+WebGLExtensionName OESTextureHalfFloatLinear::name() const
{
return OESTextureHalfFloatLinearName;
}
-PassRefPtr<OESTextureHalfFloatLinear> OESTextureHalfFloatLinear::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureHalfFloatLinear> OESTextureHalfFloatLinear::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESTextureHalfFloatLinear(context));
}
-bool OESTextureHalfFloatLinear::supported(WebGLRenderingContext* context)
+bool OESTextureHalfFloatLinear::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_texture_half_float_linear");
+ return context->extensionsUtil()->supportsExtension("GL_OES_texture_half_float_linear");
}
const char* OESTextureHalfFloatLinear::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h
index 17532033b45..421bbbca4d0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESTextureHalfFloatLinear.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class OESTextureHalfFloatLinear : public WebGLExtension, public ScriptWrappable {
+class OESTextureHalfFloatLinear FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESTextureHalfFloatLinear> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESTextureHalfFloatLinear> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESTextureHalfFloatLinear();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- OESTextureHalfFloatLinear(WebGLRenderingContext*);
+ OESTextureHalfFloatLinear(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp
index 848c85f5557..932195ed611 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.cpp
@@ -28,29 +28,28 @@
#include "core/html/canvas/OESVertexArrayObject.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "core/html/canvas/WebGLVertexArrayObjectOES.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContext* context)
+OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_OES_vertex_array_object");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_OES_vertex_array_object");
}
OESVertexArrayObject::~OESVertexArrayObject()
{
}
-WebGLExtension::ExtensionName OESVertexArrayObject::name() const
+WebGLExtensionName OESVertexArrayObject::name() const
{
return OESVertexArrayObjectName;
}
-PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContext* context)
+PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContextBase* context)
{
return adoptRef(new OESVertexArrayObject(context));
}
@@ -58,7 +57,7 @@ PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingCont
PassRefPtr<WebGLVertexArrayObjectOES> OESVertexArrayObject::createVertexArrayOES()
{
if (isLost())
- return 0;
+ return nullptr;
RefPtr<WebGLVertexArrayObjectOES> o = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::VaoTypeUser);
m_context->addContextObject(o.get());
@@ -71,12 +70,12 @@ void OESVertexArrayObject::deleteVertexArrayOES(WebGLVertexArrayObjectOES* array
return;
if (!arrayObject->isDefaultObject() && arrayObject == m_context->m_boundVertexArrayObject)
- m_context->setBoundVertexArrayObject(0);
+ m_context->setBoundVertexArrayObject(nullptr);
- arrayObject->deleteObject(m_context->graphicsContext3D());
+ arrayObject->deleteObject(m_context->webContext());
}
-GC3Dboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
+GLboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
{
if (!arrayObject || isLost())
return 0;
@@ -84,8 +83,7 @@ GC3Dboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* ar
if (!arrayObject->hasEverBeenBound())
return 0;
- Extensions3D* extensions = m_context->graphicsContext3D()->extensions();
- return extensions->isVertexArrayOES(arrayObject->object());
+ return m_context->webContext()->isVertexArrayOES(arrayObject->object());
}
void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
@@ -94,26 +92,24 @@ void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayOb
return;
if (arrayObject && (arrayObject->isDeleted() || !arrayObject->validate(0, context()))) {
- m_context->graphicsContext3D()->synthesizeGLError(GL_INVALID_OPERATION);
+ m_context->webContext()->synthesizeGLError(GL_INVALID_OPERATION);
return;
}
- Extensions3D* extensions = m_context->graphicsContext3D()->extensions();
if (arrayObject && !arrayObject->isDefaultObject() && arrayObject->object()) {
- extensions->bindVertexArrayOES(arrayObject->object());
+ m_context->webContext()->bindVertexArrayOES(arrayObject->object());
arrayObject->setHasEverBeenBound();
m_context->setBoundVertexArrayObject(arrayObject);
} else {
- extensions->bindVertexArrayOES(0);
- m_context->setBoundVertexArrayObject(0);
+ m_context->webContext()->bindVertexArrayOES(0);
+ m_context->setBoundVertexArrayObject(nullptr);
}
}
-bool OESVertexArrayObject::supported(WebGLRenderingContext* context)
+bool OESVertexArrayObject::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_OES_vertex_array_object");
+ return context->extensionsUtil()->supportsExtension("GL_OES_vertex_array_object");
}
const char* OESVertexArrayObject::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h
index 2fd0735f21a..3f616be0575 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.h
@@ -28,30 +28,29 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/WebGLExtension.h"
-#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
class WebGLVertexArrayObjectOES;
-class OESVertexArrayObject : public WebGLExtension, public ScriptWrappable {
+class OESVertexArrayObject FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<OESVertexArrayObject> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<OESVertexArrayObject> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~OESVertexArrayObject();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
PassRefPtr<WebGLVertexArrayObjectOES> createVertexArrayOES();
void deleteVertexArrayOES(WebGLVertexArrayObjectOES*);
- GC3Dboolean isVertexArrayOES(WebGLVertexArrayObjectOES*);
+ GLboolean isVertexArrayOES(WebGLVertexArrayObjectOES*);
void bindVertexArrayOES(WebGLVertexArrayObjectOES*);
private:
- OESVertexArrayObject(WebGLRenderingContext*);
+ OESVertexArrayObject(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl
index aa9a16d6377..5a21f238d79 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/OESVertexArrayObject.idl
@@ -24,13 +24,14 @@
*/
[
+ DoNotCheckConstants,
NoInterfaceObject,
- DoNotCheckConstants
+ TypeChecking=Interface|Nullable,
] interface OESVertexArrayObject {
const unsigned long VERTEX_ARRAY_BINDING_OES = 0x85B5;
- [StrictTypeChecking] WebGLVertexArrayObjectOES createVertexArrayOES();
- [StrictTypeChecking] void deleteVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
- [StrictTypeChecking] boolean isVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
- [StrictTypeChecking] void bindVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES arrayObject);
+ WebGLVertexArrayObjectOES createVertexArrayOES();
+ void deleteVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
+ boolean isVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
+ void bindVertexArrayOES([Default=Undefined] optional WebGLVertexArrayObjectOES? arrayObject);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Path.idl b/chromium/third_party/WebKit/Source/core/html/canvas/Path.idl
deleted file mode 100644
index 66435a5da46..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/canvas/Path.idl
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
- RuntimeEnabled=ExperimentalCanvasFeatures,
- Constructor,
- Constructor(Path path),
- Constructor(DOMString text),
- ImplementedAs=DOMPath
-] interface Path {
-
- // FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
- void closePath();
- void moveTo([Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void lineTo([Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void quadraticCurveTo([Default=Undefined] optional float cpx,
- [Default=Undefined] optional float cpy,
- [Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- void bezierCurveTo([Default=Undefined] optional float cp1x,
- [Default=Undefined] optional float cp1y,
- [Default=Undefined] optional float cp2x,
- [Default=Undefined] optional float cp2y,
- [Default=Undefined] optional float x,
- [Default=Undefined] optional float y);
- [RaisesException] void arcTo([Default=Undefined] optional float x1,
- [Default=Undefined] optional float y1,
- [Default=Undefined] optional float x2,
- [Default=Undefined] optional float y2,
- [Default=Undefined] optional float radius);
- void rect([Default=Undefined] optional float x,
- [Default=Undefined] optional float y,
- [Default=Undefined] optional float width,
- [Default=Undefined] optional float height);
- [RaisesException] void arc([Default=Undefined] optional float x,
- [Default=Undefined] optional float y,
- [Default=Undefined] optional float radius,
- [Default=Undefined] optional float startAngle,
- [Default=Undefined] optional float endAngle,
- [Default=Undefined] optional boolean anticlockwise);
-};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.h b/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.h
new file mode 100644
index 00000000000..f09839bb1e9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef Path2D_h
+#define Path2D_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/CanvasPathMethods.h"
+#include "core/svg/SVGMatrixTearOff.h"
+#include "core/svg/SVGPathUtilities.h"
+#include "platform/transforms/AffineTransform.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class Path2D FINAL : public RefCounted<Path2D>, public CanvasPathMethods, public ScriptWrappable {
+ WTF_MAKE_NONCOPYABLE(Path2D); WTF_MAKE_FAST_ALLOCATED;
+public:
+ static PassRefPtr<Path2D> create() { return adoptRef(new Path2D); }
+ static PassRefPtr<Path2D> create(const String& pathData) { return adoptRef(new Path2D(pathData)); }
+ static PassRefPtr<Path2D> create(Path2D* path) { return adoptRef(new Path2D(path)); }
+
+ static PassRefPtr<Path2D> create(const Path& path) { return adoptRef(new Path2D(path)); }
+
+ const Path& path() const { return m_path; }
+
+ void addPath(Path2D* path)
+ {
+ addPath(path, 0);
+ }
+
+ void addPath(Path2D* path, SVGMatrixTearOff* transform)
+ {
+ Path src = path->path();
+ m_path.addPath(src, transform ? transform->value() : AffineTransform(1, 0, 0, 1, 0, 0));
+ }
+ virtual ~Path2D() { }
+private:
+ Path2D() : CanvasPathMethods()
+ {
+ ScriptWrappable::init(this);
+ }
+
+ Path2D(const Path& path)
+ : CanvasPathMethods(path)
+ {
+ ScriptWrappable::init(this);
+ }
+
+ Path2D(Path2D* path)
+ : CanvasPathMethods(path->path())
+ {
+ ScriptWrappable::init(this);
+ }
+
+ Path2D(const String& pathData)
+ : CanvasPathMethods()
+ {
+ ScriptWrappable::init(this);
+ buildPathFromString(pathData, m_path);
+ }
+};
+
+}
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.idl b/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.idl
new file mode 100644
index 00000000000..262148560a2
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/Path2D.idl
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#path2d
+
+[
+ Constructor,
+ Constructor(Path2D path),
+ Constructor(DOMString text),
+ RuntimeEnabled=Path2D,
+] interface Path2D {
+
+ [RuntimeEnabled=ExperimentalCanvasFeatures, TypeChecking=Interface|Nullable] void addPath(Path2D path, optional SVGMatrix? transform);
+};
+
+Path2D implements CanvasPathMethods;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h
index 7571e3681ec..b1c983484b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLActiveInfo.h
@@ -27,7 +27,7 @@
#define WebGLActiveInfo_h
#include "bindings/v8/ScriptWrappable.h"
-#include "platform/graphics/GraphicsContext3D.h"
+#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -36,16 +36,16 @@ namespace WebCore {
class WebGLActiveInfo : public RefCounted<WebGLActiveInfo>, public ScriptWrappable {
public:
- static PassRefPtr<WebGLActiveInfo> create(const String& name, GC3Denum type, GC3Dint size)
+ static PassRefPtr<WebGLActiveInfo> create(const String& name, GLenum type, GLint size)
{
return adoptRef(new WebGLActiveInfo(name, type, size));
}
String name() const { return m_name; }
- GC3Denum type() const { return m_type; }
- GC3Dint size() const { return m_size; }
+ GLenum type() const { return m_type; }
+ GLint size() const { return m_size; }
private:
- WebGLActiveInfo(const String& name, GC3Denum type, GC3Dint size)
+ WebGLActiveInfo(const String& name, GLenum type, GLint size)
: m_name(name)
, m_type(type)
, m_size(size)
@@ -56,8 +56,8 @@ private:
ScriptWrappable::init(this);
}
String m_name;
- GC3Denum m_type;
- GC3Dint m_size;
+ GLenum m_type;
+ GLint m_size;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp
index 48bf88a1ab0..6308eccf192 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.cpp
@@ -27,21 +27,21 @@
#include "core/html/canvas/WebGLBuffer.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLBuffer(ctx));
}
-WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
+WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase* ctx)
: WebGLSharedObject(ctx)
, m_target(0)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createBuffer());
+ setObject(ctx->webContext()->createBuffer());
}
WebGLBuffer::~WebGLBuffer()
@@ -49,12 +49,12 @@ WebGLBuffer::~WebGLBuffer()
deleteObject(0);
}
-void WebGLBuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLBuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
context3d->deleteBuffer(object);
}
-void WebGLBuffer::setTarget(GC3Denum target)
+void WebGLBuffer::setTarget(GLenum target)
{
// In WebGL, a buffer is bound to one target in its lifetime
if (m_target)
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h
index 8483685f58c..9f596be4c8a 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLBuffer.h
@@ -33,26 +33,26 @@
namespace WebCore {
-class WebGLBuffer : public WebGLSharedObject, public ScriptWrappable {
+class WebGLBuffer FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
virtual ~WebGLBuffer();
- static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLBuffer> create(WebGLRenderingContextBase*);
- GC3Denum getTarget() const { return m_target; }
- void setTarget(GC3Denum);
+ GLenum getTarget() const { return m_target; }
+ void setTarget(GLenum);
bool hasEverBeenBound() const { return object() && m_target; }
protected:
- WebGLBuffer(WebGLRenderingContext*);
+ WebGLBuffer(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
- virtual bool isBuffer() const { return true; }
+ virtual bool isBuffer() const OVERRIDE { return true; }
- GC3Denum m_target;
+ GLenum m_target;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
index dad7ff49b05..3bfd7d8f0b1 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
@@ -27,37 +27,34 @@
#include "core/html/canvas/WebGLCompressedTextureATC.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContext* context)
+WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGB_AMD);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD);
+ context->addCompressedTextureFormat(GC3D_COMPRESSED_ATC_RGB_AMD);
+ context->addCompressedTextureFormat(GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD);
+ context->addCompressedTextureFormat(GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD);
}
WebGLCompressedTextureATC::~WebGLCompressedTextureATC()
{
}
-WebGLExtension::ExtensionName WebGLCompressedTextureATC::name() const
+WebGLExtensionName WebGLCompressedTextureATC::name() const
{
return WebGLCompressedTextureATCName;
}
-PassRefPtr<WebGLCompressedTextureATC> WebGLCompressedTextureATC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTextureATC> WebGLCompressedTextureATC::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLCompressedTextureATC(context));
}
-bool WebGLCompressedTextureATC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTextureATC::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_AMD_compressed_ATC_texture");
+ return context->extensionsUtil()->supportsExtension("GL_AMD_compressed_ATC_texture");
}
const char* WebGLCompressedTextureATC::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h
index eb49bc4bfe8..069fe145bd0 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureATC.h
@@ -34,17 +34,17 @@ namespace WebCore {
class WebGLTexture;
-class WebGLCompressedTextureATC : public WebGLExtension, public ScriptWrappable {
+class WebGLCompressedTextureATC FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLCompressedTextureATC> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLCompressedTextureATC> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLCompressedTextureATC();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLCompressedTextureATC(WebGLRenderingContext*);
+ WebGLCompressedTextureATC(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.cpp
new file mode 100644
index 00000000000..a2abde855a3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.cpp
@@ -0,0 +1,45 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/html/canvas/WebGLCompressedTextureETC1.h"
+
+#include "core/html/canvas/WebGLRenderingContextBase.h"
+
+namespace WebCore {
+
+WebGLCompressedTextureETC1::WebGLCompressedTextureETC1(WebGLRenderingContextBase* context)
+ : WebGLExtension(context)
+{
+ ScriptWrappable::init(this);
+ context->addCompressedTextureFormat(GL_ETC1_RGB8_OES);
+}
+
+WebGLCompressedTextureETC1::~WebGLCompressedTextureETC1()
+{
+}
+
+WebGLExtensionName WebGLCompressedTextureETC1::name() const
+{
+ return WebGLCompressedTextureETC1Name;
+}
+
+PassRefPtr<WebGLCompressedTextureETC1> WebGLCompressedTextureETC1::create(WebGLRenderingContextBase* context)
+{
+ return adoptRef(new WebGLCompressedTextureETC1(context));
+}
+
+bool WebGLCompressedTextureETC1::supported(WebGLRenderingContextBase* context)
+{
+ Extensions3DUtil* extensionsUtil = context->extensionsUtil();
+ return extensionsUtil->supportsExtension("GL_OES_compressed_ETC1_RGB8_texture");
+}
+
+const char* WebGLCompressedTextureETC1::extensionName()
+{
+ return "WEBGL_compressed_texture_etc1";
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.h
new file mode 100644
index 00000000000..4cf3a57ed74
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.h
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WebGLCompressedTextureETC1_h
+#define WebGLCompressedTextureETC1_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/WebGLExtension.h"
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class WebGLTexture;
+
+class WebGLCompressedTextureETC1 FINAL : public WebGLExtension, public ScriptWrappable {
+public:
+ static PassRefPtr<WebGLCompressedTextureETC1> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
+ static const char* extensionName();
+
+ virtual ~WebGLCompressedTextureETC1();
+ virtual WebGLExtensionName name() const OVERRIDE;
+
+private:
+ WebGLCompressedTextureETC1(WebGLRenderingContextBase*);
+};
+
+} // namespace WebCore
+
+#endif // WebGLCompressedTextureETC1_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.idl
new file mode 100644
index 00000000000..e37d990cb6d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureETC1.idl
@@ -0,0 +1,11 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ NoInterfaceObject,
+ DoNotCheckConstants
+] interface WebGLCompressedTextureETC1 {
+ /* Compressed Texture Formats */
+ const unsigned long COMPRESSED_RGB_ETC1_WEBGL = 0x8D64;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
index 8ae4acd2689..d1586ff22d6 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
@@ -27,39 +27,37 @@
#include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
-#include "platform/graphics/Extensions3D.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContext* context)
+WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG);
}
WebGLCompressedTexturePVRTC::~WebGLCompressedTexturePVRTC()
{
}
-WebGLExtension::ExtensionName WebGLCompressedTexturePVRTC::name() const
+WebGLExtensionName WebGLCompressedTexturePVRTC::name() const
{
return WebGLCompressedTexturePVRTCName;
}
-PassRefPtr<WebGLCompressedTexturePVRTC> WebGLCompressedTexturePVRTC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTexturePVRTC> WebGLCompressedTexturePVRTC::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLCompressedTexturePVRTC(context));
}
-bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_IMG_texture_compression_pvrtc");
+ return context->extensionsUtil()->supportsExtension("GL_IMG_texture_compression_pvrtc");
}
const char* WebGLCompressedTexturePVRTC::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
index dc28e5f9522..27cde75bca7 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class WebGLCompressedTexturePVRTC : public WebGLExtension, public ScriptWrappable {
+class WebGLCompressedTexturePVRTC FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLCompressedTexturePVRTC> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLCompressedTexturePVRTC> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLCompressedTexturePVRTC();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLCompressedTexturePVRTC(WebGLRenderingContext*);
+ WebGLCompressedTexturePVRTC(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
index 9d3f2543001..35834cc91ff 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
@@ -27,42 +27,41 @@
#include "core/html/canvas/WebGLCompressedTextureS3TC.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
-#include "platform/graphics/Extensions3D.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContext* context)
+WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT);
- context->addCompressedTextureFormat(Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
+ context->addCompressedTextureFormat(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
}
WebGLCompressedTextureS3TC::~WebGLCompressedTextureS3TC()
{
}
-WebGLExtension::ExtensionName WebGLCompressedTextureS3TC::name() const
+WebGLExtensionName WebGLCompressedTextureS3TC::name() const
{
return WebGLCompressedTextureS3TCName;
}
-PassRefPtr<WebGLCompressedTextureS3TC> WebGLCompressedTextureS3TC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTextureS3TC> WebGLCompressedTextureS3TC::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLCompressedTextureS3TC(context));
}
-bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_EXT_texture_compression_s3tc")
- || (extensions->supports("GL_EXT_texture_compression_dxt1")
- && extensions->supports("GL_CHROMIUM_texture_compression_dxt3")
- && extensions->supports("GL_CHROMIUM_texture_compression_dxt5"));
+ Extensions3DUtil* extensionsUtil = context->extensionsUtil();
+ return extensionsUtil->supportsExtension("GL_EXT_texture_compression_s3tc")
+ || (extensionsUtil->supportsExtension("GL_EXT_texture_compression_dxt1")
+ && extensionsUtil->supportsExtension("GL_CHROMIUM_texture_compression_dxt3")
+ && extensionsUtil->supportsExtension("GL_CHROMIUM_texture_compression_dxt5"));
}
const char* WebGLCompressedTextureS3TC::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
index 615f4f587fb..aaed4a7764c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
@@ -34,17 +34,17 @@ namespace WebCore {
class WebGLTexture;
-class WebGLCompressedTextureS3TC : public WebGLExtension, public ScriptWrappable {
+class WebGLCompressedTextureS3TC FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLCompressedTextureS3TC> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLCompressedTextureS3TC> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLCompressedTextureS3TC();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLCompressedTextureS3TC(WebGLRenderingContext*);
+ WebGLCompressedTextureS3TC(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp
index cb26556a731..385720617fd 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.cpp
@@ -28,6 +28,8 @@
#include "core/html/canvas/WebGLContextAttributes.h"
+#include "core/frame/Settings.h"
+
namespace WebCore {
PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create()
@@ -35,20 +37,28 @@ PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create()
return adoptRef(new WebGLContextAttributes());
}
-PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::create(GraphicsContext3D::Attributes attributes)
-{
- return adoptRef(new WebGLContextAttributes(attributes));
-}
-
WebGLContextAttributes::WebGLContextAttributes()
: CanvasContextAttributes()
+ , m_alpha(true)
+ , m_depth(true)
+ , m_stencil(false)
+ , m_antialias(true)
+ , m_premultipliedAlpha(true)
+ , m_preserveDrawingBuffer(false)
+ , m_failIfMajorPerformanceCaveat(false)
{
ScriptWrappable::init(this);
}
-WebGLContextAttributes::WebGLContextAttributes(GraphicsContext3D::Attributes attributes)
+WebGLContextAttributes::WebGLContextAttributes(const WebGLContextAttributes& attrs)
: CanvasContextAttributes()
- , m_attrs(attributes)
+ , m_alpha(attrs.m_alpha)
+ , m_depth(attrs.m_depth)
+ , m_stencil(attrs.m_stencil)
+ , m_antialias(attrs.m_antialias)
+ , m_premultipliedAlpha(attrs.m_premultipliedAlpha)
+ , m_preserveDrawingBuffer(attrs.m_preserveDrawingBuffer)
+ , m_failIfMajorPerformanceCaveat(attrs.m_failIfMajorPerformanceCaveat)
{
ScriptWrappable::init(this);
}
@@ -57,79 +67,104 @@ WebGLContextAttributes::~WebGLContextAttributes()
{
}
+PassRefPtr<WebGLContextAttributes> WebGLContextAttributes::clone() const
+{
+ return adoptRef(new WebGLContextAttributes(*this));
+}
+
bool WebGLContextAttributes::alpha() const
{
- return m_attrs.alpha;
+ return m_alpha;
}
void WebGLContextAttributes::setAlpha(bool alpha)
{
- m_attrs.alpha = alpha;
+ m_alpha = alpha;
}
bool WebGLContextAttributes::depth() const
{
- return m_attrs.depth;
+ return m_depth;
}
void WebGLContextAttributes::setDepth(bool depth)
{
- m_attrs.depth = depth;
+ m_depth = depth;
}
bool WebGLContextAttributes::stencil() const
{
- return m_attrs.stencil;
+ return m_stencil;
}
void WebGLContextAttributes::setStencil(bool stencil)
{
- m_attrs.stencil = stencil;
+ m_stencil = stencil;
}
bool WebGLContextAttributes::antialias() const
{
- return m_attrs.antialias;
+ return m_antialias;
}
void WebGLContextAttributes::setAntialias(bool antialias)
{
- m_attrs.antialias = antialias;
+ m_antialias = antialias;
}
bool WebGLContextAttributes::premultipliedAlpha() const
{
- return m_attrs.premultipliedAlpha;
+ return m_premultipliedAlpha;
}
void WebGLContextAttributes::setPremultipliedAlpha(bool premultipliedAlpha)
{
- m_attrs.premultipliedAlpha = premultipliedAlpha;
+ m_premultipliedAlpha = premultipliedAlpha;
}
bool WebGLContextAttributes::preserveDrawingBuffer() const
{
- return m_attrs.preserveDrawingBuffer;
+ return m_preserveDrawingBuffer;
}
void WebGLContextAttributes::setPreserveDrawingBuffer(bool preserveDrawingBuffer)
{
- m_attrs.preserveDrawingBuffer = preserveDrawingBuffer;
+ m_preserveDrawingBuffer = preserveDrawingBuffer;
}
bool WebGLContextAttributes::failIfMajorPerformanceCaveat() const
{
- return m_attrs.failIfMajorPerformanceCaveat;
+ return m_failIfMajorPerformanceCaveat;
}
void WebGLContextAttributes::setFailIfMajorPerformanceCaveat(bool failIfMajorPerformanceCaveat)
{
- m_attrs.failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat;
+ m_failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat;
}
-GraphicsContext3D::Attributes WebGLContextAttributes::attributes() const
+blink::WebGraphicsContext3D::Attributes WebGLContextAttributes::attributes(
+ const blink::WebString& topDocumentURL, Settings* settings) const
{
- return m_attrs;
+ blink::WebGraphicsContext3D::Attributes attrs;
+
+ attrs.alpha = m_alpha;
+ attrs.depth = m_depth;
+ attrs.stencil = m_stencil;
+ attrs.antialias = m_antialias;
+ if (m_antialias) {
+ if (settings && !settings->openGLMultisamplingEnabled())
+ attrs.antialias = false;
+ }
+ attrs.premultipliedAlpha = m_premultipliedAlpha;
+ attrs.failIfMajorPerformanceCaveat = m_failIfMajorPerformanceCaveat;
+
+ attrs.noExtensions = true;
+ attrs.shareResources = false;
+ attrs.preferDiscreteGPU = true;
+
+ attrs.topDocumentURL = topDocumentURL;
+
+ return attrs;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h
index 62a576ef736..eeee443e2fa 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextAttributes.h
@@ -29,42 +29,44 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/CanvasContextAttributes.h"
-#include "platform/graphics/GraphicsContext3D.h"
+#include "public/platform/WebGraphicsContext3D.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
-class WebGLContextAttributes : public CanvasContextAttributes, public ScriptWrappable {
+class Settings;
+
+class WebGLContextAttributes FINAL : public CanvasContextAttributes, public ScriptWrappable {
public:
virtual ~WebGLContextAttributes();
// Create a new attributes object
static PassRefPtr<WebGLContextAttributes> create();
- // Create a new attributes object initialized with preexisting attributes
- static PassRefPtr<WebGLContextAttributes> create(GraphicsContext3D::Attributes attributes);
+ // Create a copy of this object.
+ PassRefPtr<WebGLContextAttributes> clone() const;
// Whether or not the drawing buffer has an alpha channel; default=true
bool alpha() const;
- void setAlpha(bool alpha);
+ void setAlpha(bool);
// Whether or not the drawing buffer has a depth buffer; default=true
bool depth() const;
- void setDepth(bool depth);
+ void setDepth(bool);
- // Whether or not the drawing buffer has a stencil buffer; default=true
+ // Whether or not the drawing buffer has a stencil buffer; default=false
bool stencil() const;
- void setStencil(bool stencil);
+ void setStencil(bool);
// Whether or not the drawing buffer is antialiased; default=true
bool antialias() const;
- void setAntialias(bool antialias);
+ void setAntialias(bool);
// Whether or not to treat the values in the drawing buffer as
// though their alpha channel has already been multiplied into the
// color channels; default=true
bool premultipliedAlpha() const;
- void setPremultipliedAlpha(bool premultipliedAlpha);
+ void setPremultipliedAlpha(bool);
// Whether or not to preserve the drawing buffer after presentation to the
// screen; default=false
@@ -76,16 +78,23 @@ public:
bool failIfMajorPerformanceCaveat() const;
void setFailIfMajorPerformanceCaveat(bool);
- // Fetches a copy of the attributes stored in this object in a
- // form that can be used to initialize a GraphicsContext3D.
- GraphicsContext3D::Attributes attributes() const;
+ // Set up the attributes that can be used to initialize a WebGraphicsContext3D.
+ // It's mostly based on WebGLContextAttributes, but would be adjusted based
+ // on settings.
+ blink::WebGraphicsContext3D::Attributes attributes(const blink::WebString&, Settings*) const;
protected:
WebGLContextAttributes();
- WebGLContextAttributes(GraphicsContext3D::Attributes attributes);
+ WebGLContextAttributes(const WebGLContextAttributes&);
private:
- GraphicsContext3D::Attributes m_attrs;
+ bool m_alpha;
+ bool m_depth;
+ bool m_stencil;
+ bool m_antialias;
+ bool m_premultipliedAlpha;
+ bool m_preserveDrawingBuffer;
+ bool m_failIfMajorPerformanceCaveat;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp
index 7f4cf7c7576..f26e8441ea3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.cpp
@@ -26,8 +26,6 @@
#include "config.h"
#include "core/html/canvas/WebGLContextEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
WebGLContextEventInit::WebGLContextEventInit()
@@ -62,4 +60,9 @@ const AtomicString& WebGLContextEvent::interfaceName() const
return EventNames::WebGLContextEvent;
}
+void WebGLContextEvent::trace(Visitor* visitor)
+{
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h
index 18f4a4812f9..0bd83808671 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextEvent.h
@@ -36,25 +36,27 @@ struct WebGLContextEventInit : public EventInit {
String statusMessage;
};
-class WebGLContextEvent : public Event {
+class WebGLContextEvent FINAL : public Event {
public:
- static PassRefPtr<WebGLContextEvent> create()
+ static PassRefPtrWillBeRawPtr<WebGLContextEvent> create()
{
- return adoptRef(new WebGLContextEvent);
+ return adoptRefWillBeNoop(new WebGLContextEvent);
}
- static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
+ static PassRefPtrWillBeRawPtr<WebGLContextEvent> create(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage)
{
- return adoptRef(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
+ return adoptRefWillBeNoop(new WebGLContextEvent(type, canBubble, cancelable, statusMessage));
}
- static PassRefPtr<WebGLContextEvent> create(const AtomicString& type, const WebGLContextEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<WebGLContextEvent> create(const AtomicString& type, const WebGLContextEventInit& initializer)
{
- return adoptRef(new WebGLContextEvent(type, initializer));
+ return adoptRefWillBeNoop(new WebGLContextEvent(type, initializer));
}
virtual ~WebGLContextEvent();
const String& statusMessage() const { return m_statusMessage; }
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
WebGLContextEvent();
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp
index 93ff6f4f4f1..e9e3ebe267e 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.cpp
@@ -46,19 +46,19 @@ WebGLContextGroup::~WebGLContextGroup()
detachAndRemoveAllObjects();
}
-GraphicsContext3D* WebGLContextGroup::getAGraphicsContext3D()
+blink::WebGraphicsContext3D* WebGLContextGroup::getAWebGraphicsContext3D()
{
ASSERT(!m_contexts.isEmpty());
- HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin();
- return (*it)->graphicsContext3D();
+ HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin();
+ return (*it)->webContext();
}
-void WebGLContextGroup::addContext(WebGLRenderingContext* context)
+void WebGLContextGroup::addContext(WebGLRenderingContextBase* context)
{
m_contexts.add(context);
}
-void WebGLContextGroup::removeContext(WebGLRenderingContext* context)
+void WebGLContextGroup::removeContext(WebGLRenderingContextBase* context)
{
// We must call detachAndRemoveAllObjects before removing the last context.
if (m_contexts.size() == 1 && m_contexts.contains(context))
@@ -85,13 +85,13 @@ void WebGLContextGroup::detachAndRemoveAllObjects()
}
}
-void WebGLContextGroup::loseContextGroup(WebGLRenderingContext::LostContextMode mode)
+void WebGLContextGroup::loseContextGroup(WebGLRenderingContextBase::LostContextMode mode)
{
// Detach must happen before loseContextImpl, which destroys the GraphicsContext3D
// and prevents groupObjects from being properly deleted.
detachAndRemoveAllObjects();
- for (HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
+ for (HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
(*it)->loseContextImpl(mode);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h
index b1fece9111b..6c2f9953540 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextGroup.h
@@ -26,17 +26,20 @@
#ifndef WebGLContextGroup_h
#define WebGLContextGroup_h
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "wtf/HashSet.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
+namespace blink {
+class WebGraphicsContext3D;
+}
+
namespace WebCore {
-class GraphicsContext3D;
class WebGLExtension;
class WebGLSharedObject;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
typedef int ExceptionCode;
@@ -45,15 +48,15 @@ public:
static PassRefPtr<WebGLContextGroup> create();
~WebGLContextGroup();
- void addContext(WebGLRenderingContext*);
- void removeContext(WebGLRenderingContext*);
+ void addContext(WebGLRenderingContextBase*);
+ void removeContext(WebGLRenderingContextBase*);
void addObject(WebGLSharedObject*);
void removeObject(WebGLSharedObject*);
- GraphicsContext3D* getAGraphicsContext3D();
+ blink::WebGraphicsContext3D* getAWebGraphicsContext3D();
- void loseContextGroup(WebGLRenderingContext::LostContextMode);
+ void loseContextGroup(WebGLRenderingContextBase::LostContextMode);
private:
friend class WebGLObject;
@@ -62,7 +65,7 @@ public:
void detachAndRemoveAllObjects();
- HashSet<WebGLRenderingContext*> m_contexts;
+ HashSet<WebGLRenderingContextBase*> m_contexts;
HashSet<WebGLSharedObject*> m_groupObjects;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp
index ea718c51e7a..83441589def 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.cpp
@@ -27,11 +27,11 @@
#include "core/html/canvas/WebGLContextObject.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLContextObject::WebGLContextObject(WebGLRenderingContext* context)
+WebGLContextObject::WebGLContextObject(WebGLRenderingContextBase* context)
: WebGLObject(context)
, m_context(context)
{
@@ -47,15 +47,15 @@ void WebGLContextObject::detachContext()
{
detach();
if (m_context) {
- deleteObject(m_context->graphicsContext3D());
+ deleteObject(m_context->webContext());
m_context->removeContextObject(this);
m_context = 0;
}
}
-GraphicsContext3D* WebGLContextObject::getAGraphicsContext3D() const
+blink::WebGraphicsContext3D* WebGLContextObject::getAWebGraphicsContext3D() const
{
- return m_context ? m_context->graphicsContext3D() : 0;
+ return m_context ? m_context->webContext() : 0;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h
index 1e4d2965754..21be7a53d8a 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLContextObject.h
@@ -28,20 +28,23 @@
#include "core/html/canvas/WebGLObject.h"
+namespace blink {
+class WebGraphicsContext3D;
+}
+
namespace WebCore {
-class GraphicsContext3D;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
// WebGLContextObject the base class for objects that are owned by a specific
-// WebGLRenderingContext.
+// WebGLRenderingContextBase.
class WebGLContextObject : public WebGLObject {
public:
virtual ~WebGLContextObject();
- WebGLRenderingContext* context() const { return m_context; }
+ WebGLRenderingContextBase* context() const { return m_context; }
- virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext* context) const
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase* context) const OVERRIDE FINAL
{
return context == m_context;
}
@@ -49,17 +52,17 @@ public:
void detachContext();
protected:
- WebGLContextObject(WebGLRenderingContext*);
+ WebGLContextObject(WebGLRenderingContextBase*);
- virtual bool hasGroupOrContext() const
+ virtual bool hasGroupOrContext() const OVERRIDE FINAL
{
return m_context;
}
- virtual GraphicsContext3D* getAGraphicsContext3D() const;
+ virtual blink::WebGraphicsContext3D* getAWebGraphicsContext3D() const OVERRIDE FINAL;
private:
- WebGLRenderingContext* m_context;
+ WebGLRenderingContextBase* m_context;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
index bca809a7c0e..cc61d268de1 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContext* context)
+WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
@@ -39,17 +39,17 @@ WebGLDebugRendererInfo::~WebGLDebugRendererInfo()
{
}
-WebGLExtension::ExtensionName WebGLDebugRendererInfo::name() const
+WebGLExtensionName WebGLDebugRendererInfo::name() const
{
return WebGLDebugRendererInfoName;
}
-PassRefPtr<WebGLDebugRendererInfo> WebGLDebugRendererInfo::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDebugRendererInfo> WebGLDebugRendererInfo::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLDebugRendererInfo(context));
}
-bool WebGLDebugRendererInfo::supported(WebGLRenderingContext*)
+bool WebGLDebugRendererInfo::supported(WebGLRenderingContextBase*)
{
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h
index 2baa7abe337..8863aeb30f5 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugRendererInfo.h
@@ -32,22 +32,22 @@
namespace WebCore {
-class WebGLDebugRendererInfo : public WebGLExtension, public ScriptWrappable {
+class WebGLDebugRendererInfo FINAL : public WebGLExtension, public ScriptWrappable {
public:
enum EnumType {
UNMASKED_VENDOR_WEBGL = 0x9245,
UNMASKED_RENDERER_WEBGL = 0x9246
};
- static PassRefPtr<WebGLDebugRendererInfo> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLDebugRendererInfo> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLDebugRendererInfo();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLDebugRendererInfo(WebGLRenderingContext*);
+ WebGLDebugRendererInfo(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp
index 8ecb09379d2..2b4a0aa5037 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.cpp
@@ -27,13 +27,12 @@
#include "core/html/canvas/WebGLDebugShaders.h"
#include "bindings/v8/ExceptionState.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "core/html/canvas/WebGLShader.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
-WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContext* context)
+WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
@@ -43,12 +42,12 @@ WebGLDebugShaders::~WebGLDebugShaders()
{
}
-WebGLExtension::ExtensionName WebGLDebugShaders::name() const
+WebGLExtensionName WebGLDebugShaders::name() const
{
return WebGLDebugShadersName;
}
-PassRefPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLDebugShaders(context));
}
@@ -59,13 +58,12 @@ String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader)
return String();
if (!m_context->validateWebGLObject("getTranslatedShaderSource", shader))
return "";
- return m_context->graphicsContext3D()->extensions()->getTranslatedShaderSourceANGLE(shader->object());
+ return m_context->ensureNotNull(m_context->webContext()->getTranslatedShaderSourceANGLE(shader->object()));
}
-bool WebGLDebugShaders::supported(WebGLRenderingContext* context)
+bool WebGLDebugShaders::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return extensions->supports("GL_ANGLE_translated_shader_source");
+ return context->extensionsUtil()->supportsExtension("GL_ANGLE_translated_shader_source");
}
const char* WebGLDebugShaders::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h
index 1adbd3074c1..f1ae4f04b00 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.h
@@ -34,19 +34,19 @@ namespace WebCore {
class WebGLShader;
-class WebGLDebugShaders : public WebGLExtension, public ScriptWrappable {
+class WebGLDebugShaders FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLDebugShaders> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLDebugShaders> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLDebugShaders();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
String getTranslatedShaderSource(WebGLShader*);
private:
- WebGLDebugShaders(WebGLRenderingContext*);
+ WebGLDebugShaders(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl
index 55a6f3cb981..74851c7c226 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDebugShaders.idl
@@ -24,7 +24,8 @@
*/
[
- NoInterfaceObject
+ NoInterfaceObject,
+ TypeChecking=Interface|Nullable,
] interface WebGLDebugShaders {
- [StrictTypeChecking, TreatReturnedNullStringAs=Null] DOMString getTranslatedShaderSource(WebGLShader shader);
+ [TreatReturnedNullStringAs=Null] DOMString getTranslatedShaderSource(WebGLShader? shader);
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp
index d42019ff82f..eb2e41d905b 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.cpp
@@ -27,42 +27,40 @@
#include "core/html/canvas/WebGLDepthTexture.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContext* context)
+WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_CHROMIUM_depth_texture");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_CHROMIUM_depth_texture");
}
WebGLDepthTexture::~WebGLDepthTexture()
{
}
-WebGLExtension::ExtensionName WebGLDepthTexture::name() const
+WebGLExtensionName WebGLDepthTexture::name() const
{
return WebGLDepthTextureName;
}
-PassRefPtr<WebGLDepthTexture> WebGLDepthTexture::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDepthTexture> WebGLDepthTexture::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLDepthTexture(context));
}
-bool WebGLDepthTexture::supported(WebGLRenderingContext* context)
+bool WebGLDepthTexture::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
+ Extensions3DUtil* extensionsUtil = context->extensionsUtil();
// Emulating the UNSIGNED_INT_24_8_WEBGL texture internal format in terms
// of two separate texture objects is too difficult, so disable depth
// textures unless a packed depth/stencil format is available.
- if (!extensions->supports("GL_OES_packed_depth_stencil"))
+ if (!extensionsUtil->supportsExtension("GL_OES_packed_depth_stencil"))
return false;
- return extensions->supports("GL_CHROMIUM_depth_texture")
- || extensions->supports("GL_OES_depth_texture")
- || extensions->supports("GL_ARB_depth_texture");
+ return extensionsUtil->supportsExtension("GL_CHROMIUM_depth_texture")
+ || extensionsUtil->supportsExtension("GL_OES_depth_texture")
+ || extensionsUtil->supportsExtension("GL_ARB_depth_texture");
}
const char* WebGLDepthTexture::extensionName()
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h
index 34b052511b0..34017ee1801 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDepthTexture.h
@@ -32,17 +32,17 @@
namespace WebCore {
-class WebGLDepthTexture : public WebGLExtension, public ScriptWrappable {
+class WebGLDepthTexture FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLDepthTexture> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLDepthTexture> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLDepthTexture();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
private:
- WebGLDepthTexture(WebGLRenderingContext*);
+ WebGLDepthTexture(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp
index 20b21feb5fe..e5b6b48659f 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.cpp
@@ -27,36 +27,33 @@
#include "core/html/canvas/WebGLDrawBuffers.h"
-#include "platform/graphics/Extensions3D.h"
-
namespace WebCore {
-WebGLDrawBuffers::WebGLDrawBuffers(WebGLRenderingContext* context)
+WebGLDrawBuffers::WebGLDrawBuffers(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
- context->graphicsContext3D()->extensions()->ensureEnabled("GL_EXT_draw_buffers");
+ context->extensionsUtil()->ensureExtensionEnabled("GL_EXT_draw_buffers");
}
WebGLDrawBuffers::~WebGLDrawBuffers()
{
}
-WebGLExtension::ExtensionName WebGLDrawBuffers::name() const
+WebGLExtensionName WebGLDrawBuffers::name() const
{
- return WebGLExtension::WebGLDrawBuffersName;
+ return WebGLDrawBuffersName;
}
-PassRefPtr<WebGLDrawBuffers> WebGLDrawBuffers::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDrawBuffers> WebGLDrawBuffers::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLDrawBuffers(context));
}
// static
-bool WebGLDrawBuffers::supported(WebGLRenderingContext* context)
+bool WebGLDrawBuffers::supported(WebGLRenderingContextBase* context)
{
- Extensions3D* extensions = context->graphicsContext3D()->extensions();
- return (extensions->supports("GL_EXT_draw_buffers")
+ return (context->extensionsUtil()->supportsExtension("GL_EXT_draw_buffers")
&& satisfiesWebGLRequirements(context));
}
@@ -65,12 +62,12 @@ const char* WebGLDrawBuffers::extensionName()
return "WEBGL_draw_buffers";
}
-void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
+void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GLenum>& buffers)
{
if (isLost())
return;
- GC3Dsizei n = buffers.size();
- const GC3Denum* bufs = buffers.data();
+ GLsizei n = buffers.size();
+ const GLenum* bufs = buffers.data();
if (!m_context->m_framebufferBinding) {
if (n != 1) {
m_context->synthesizeGLError(GL_INVALID_VALUE, "drawBuffersWEBGL", "more than one buffer");
@@ -81,16 +78,16 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
return;
}
// Because the backbuffer is simulated on all current WebKit ports, we need to change BACK to COLOR_ATTACHMENT0.
- GC3Denum value = (bufs[0] == GL_BACK) ? GL_COLOR_ATTACHMENT0 : GL_NONE;
- m_context->graphicsContext3D()->extensions()->drawBuffersEXT(1, &value);
+ GLenum value = (bufs[0] == GL_BACK) ? GL_COLOR_ATTACHMENT0 : GL_NONE;
+ m_context->webContext()->drawBuffersEXT(1, &value);
m_context->setBackDrawBuffer(bufs[0]);
} else {
if (n > m_context->maxDrawBuffers()) {
m_context->synthesizeGLError(GL_INVALID_VALUE, "drawBuffersWEBGL", "more than max draw buffers");
return;
}
- for (GC3Dsizei i = 0; i < n; ++i) {
- if (bufs[i] != GL_NONE && bufs[i] != static_cast<GC3Denum>(Extensions3D::COLOR_ATTACHMENT0_EXT + i)) {
+ for (GLsizei i = 0; i < n; ++i) {
+ if (bufs[i] != GL_NONE && bufs[i] != static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT + i)) {
m_context->synthesizeGLError(GL_INVALID_OPERATION, "drawBuffersWEBGL", "COLOR_ATTACHMENTi_EXT or NONE");
return;
}
@@ -100,15 +97,16 @@ void WebGLDrawBuffers::drawBuffersWEBGL(const Vector<GC3Denum>& buffers)
}
// static
-bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglContext)
+bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContextBase* webglContext)
{
- GraphicsContext3D* context = webglContext->graphicsContext3D();
+ blink::WebGraphicsContext3D* context = webglContext->webContext();
+ Extensions3DUtil* extensionsUtil = webglContext->extensionsUtil();
// This is called after we make sure GL_EXT_draw_buffers is supported.
- GC3Dint maxDrawBuffers = 0;
- GC3Dint maxColorAttachments = 0;
- context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
- context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &maxColorAttachments);
+ GLint maxDrawBuffers = 0;
+ GLint maxColorAttachments = 0;
+ context->getIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &maxDrawBuffers);
+ context->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &maxColorAttachments);
if (maxDrawBuffers < 4 || maxColorAttachments < 4)
return false;
@@ -116,11 +114,11 @@ bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglCo
context->bindFramebuffer(GL_FRAMEBUFFER, fbo);
const unsigned char* buffer = 0; // Chromium doesn't allow init data for depth/stencil tetxures.
- bool supportsDepth = (context->extensions()->supports("GL_CHROMIUM_depth_texture")
- || context->extensions()->supports("GL_OES_depth_texture")
- || context->extensions()->supports("GL_ARB_depth_texture"));
- bool supportsDepthStencil = (context->extensions()->supports("GL_EXT_packed_depth_stencil")
- || context->extensions()->supports("GL_OES_packed_depth_stencil"));
+ bool supportsDepth = (extensionsUtil->supportsExtension("GL_CHROMIUM_depth_texture")
+ || extensionsUtil->supportsExtension("GL_OES_depth_texture")
+ || extensionsUtil->supportsExtension("GL_ARB_depth_texture"));
+ bool supportsDepthStencil = (extensionsUtil->supportsExtension("GL_EXT_packed_depth_stencil")
+ || extensionsUtil->supportsExtension("GL_OES_packed_depth_stencil"));
Platform3DObject depthStencil = 0;
if (supportsDepthStencil) {
depthStencil = context->createTexture();
@@ -136,8 +134,8 @@ bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglCo
Vector<Platform3DObject> colors;
bool ok = true;
- GC3Dint maxAllowedBuffers = std::min(maxDrawBuffers, maxColorAttachments);
- for (GC3Dint i = 0; i < maxAllowedBuffers; ++i) {
+ GLint maxAllowedBuffers = std::min(maxDrawBuffers, maxColorAttachments);
+ for (GLint i = 0; i < maxAllowedBuffers; ++i) {
Platform3DObject color = context->createTexture();
colors.append(color);
context->bindTexture(GL_TEXTURE_2D, color);
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h
index 58e14f12483..be66f91c99d 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLDrawBuffers.h
@@ -32,21 +32,21 @@
namespace WebCore {
-class WebGLDrawBuffers : public WebGLExtension, public ScriptWrappable {
+class WebGLDrawBuffers FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLDrawBuffers> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLDrawBuffers> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLDrawBuffers();
- virtual ExtensionName name() const;
+ virtual WebGLExtensionName name() const OVERRIDE;
- void drawBuffersWEBGL(const Vector<GC3Denum>& buffers);
+ void drawBuffersWEBGL(const Vector<GLenum>& buffers);
private:
- WebGLDrawBuffers(WebGLRenderingContext*);
+ WebGLDrawBuffers(WebGLRenderingContextBase*);
- static bool satisfiesWebGLRequirements(WebGLRenderingContext*);
+ static bool satisfiesWebGLRequirements(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp
index 9d3c9413c61..73efb94233b 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-WebGLExtension::WebGLExtension(WebGLRenderingContext* context)
+WebGLExtension::WebGLExtension(WebGLRenderingContextBase* context)
: m_context(context)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h
index 1bd4c8bcae9..66e072ed2de 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtension.h
@@ -26,7 +26,8 @@
#ifndef WebGLExtension_h
#define WebGLExtension_h
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLExtensionName.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "wtf/RefCounted.h"
namespace WebCore {
@@ -34,36 +35,14 @@ namespace WebCore {
class WebGLExtension : public RefCounted<WebGLExtension> {
WTF_MAKE_FAST_ALLOCATED;
public:
- // Extension names are needed to properly wrap instances in JavaScript objects.
- enum ExtensionName {
- ANGLEInstancedArraysName,
- EXTFragDepthName,
- EXTTextureFilterAnisotropicName,
- OESElementIndexUintName,
- OESStandardDerivativesName,
- OESTextureFloatLinearName,
- OESTextureFloatName,
- OESTextureHalfFloatLinearName,
- OESTextureHalfFloatName,
- OESVertexArrayObjectName,
- WebGLCompressedTextureATCName,
- WebGLCompressedTexturePVRTCName,
- WebGLCompressedTextureS3TCName,
- WebGLDebugRendererInfoName,
- WebGLDebugShadersName,
- WebGLDepthTextureName,
- WebGLDrawBuffersName,
- WebGLLoseContextName,
- };
-
- WebGLRenderingContext* context() { return m_context; }
+ WebGLRenderingContextBase* context() { return m_context; }
virtual ~WebGLExtension();
- virtual ExtensionName name() const = 0;
+ virtual WebGLExtensionName name() const = 0;
// Lose this extension. Passing true = force loss. Some extensions
// like WEBGL_lose_context are not normally lost when the context
- // is lost but must be lost when destroying their WebGLRenderingContext.
+ // is lost but must be lost when destroying their WebGLRenderingContextBase.
virtual void lose(bool)
{
m_context = 0;
@@ -75,9 +54,9 @@ public:
}
protected:
- WebGLExtension(WebGLRenderingContext*);
+ WebGLExtension(WebGLRenderingContextBase*);
- WebGLRenderingContext* m_context;
+ WebGLRenderingContextBase* m_context;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtensionName.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtensionName.h
new file mode 100644
index 00000000000..6946fb1cd96
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLExtensionName.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WebGLExtensionName_h
+#define WebGLExtensionName_h
+
+namespace WebCore {
+
+// Extension names are needed to properly wrap instances in JavaScript objects.
+enum WebGLExtensionName {
+ ANGLEInstancedArraysName,
+ EXTBlendMinMaxName,
+ EXTFragDepthName,
+ EXTShaderTextureLODName,
+ EXTTextureFilterAnisotropicName,
+ OESElementIndexUintName,
+ OESStandardDerivativesName,
+ OESTextureFloatLinearName,
+ OESTextureFloatName,
+ OESTextureHalfFloatLinearName,
+ OESTextureHalfFloatName,
+ OESVertexArrayObjectName,
+ WebGLCompressedTextureATCName,
+ WebGLCompressedTextureETC1Name,
+ WebGLCompressedTexturePVRTCName,
+ WebGLCompressedTextureS3TCName,
+ WebGLDebugRendererInfoName,
+ WebGLDebugShadersName,
+ WebGLDepthTextureName,
+ WebGLDrawBuffersName,
+ WebGLLoseContextName,
+ WebGLExtensionNameCount, // Must be the last entry
+};
+
+}
+
+#endif // WebGLExtensionName_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp
index 7ab97df91d1..e968a306e5d 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.cpp
@@ -27,9 +27,8 @@
#include "core/html/canvas/WebGLFramebuffer.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
#include "platform/NotImplemented.h"
-#include "platform/graphics/Extensions3D.h"
namespace WebCore {
@@ -40,24 +39,22 @@ namespace {
return object ? object->object() : 0;
}
- class WebGLRenderbufferAttachment : public WebGLFramebuffer::WebGLAttachment {
+ class WebGLRenderbufferAttachment FINAL : public WebGLFramebuffer::WebGLAttachment {
public:
static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLRenderbuffer*);
private:
WebGLRenderbufferAttachment(WebGLRenderbuffer*);
- virtual GC3Dsizei width() const;
- virtual GC3Dsizei height() const;
- virtual GC3Denum format() const;
- virtual GC3Denum type() const;
- virtual WebGLSharedObject* object() const;
- virtual bool isSharedObject(WebGLSharedObject*) const;
- virtual bool valid() const;
- virtual bool initialized() const;
- virtual void setInitialized();
- virtual void onDetached(GraphicsContext3D*);
- virtual void attach(GraphicsContext3D*, GC3Denum attachment);
- virtual void unattach(GraphicsContext3D*, GC3Denum attachment);
+ virtual GLsizei width() const OVERRIDE;
+ virtual GLsizei height() const OVERRIDE;
+ virtual GLenum format() const OVERRIDE;
+ virtual GLenum type() const OVERRIDE;
+ virtual WebGLSharedObject* object() const OVERRIDE;
+ virtual bool isSharedObject(WebGLSharedObject*) const OVERRIDE;
+ virtual bool valid() const OVERRIDE;
+ virtual void onDetached(blink::WebGraphicsContext3D*) OVERRIDE;
+ virtual void attach(blink::WebGraphicsContext3D*, GLenum attachment) OVERRIDE;
+ virtual void unattach(blink::WebGraphicsContext3D*, GLenum attachment) OVERRIDE;
WebGLRenderbufferAttachment() { };
@@ -74,19 +71,19 @@ namespace {
{
}
- GC3Dsizei WebGLRenderbufferAttachment::width() const
+ GLsizei WebGLRenderbufferAttachment::width() const
{
return m_renderbuffer->width();
}
- GC3Dsizei WebGLRenderbufferAttachment::height() const
+ GLsizei WebGLRenderbufferAttachment::height() const
{
return m_renderbuffer->height();
}
- GC3Denum WebGLRenderbufferAttachment::format() const
+ GLenum WebGLRenderbufferAttachment::format() const
{
- GC3Denum format = m_renderbuffer->internalFormat();
+ GLenum format = m_renderbuffer->internalFormat();
if (format == GL_DEPTH_STENCIL_OES
&& m_renderbuffer->emulatedStencilBuffer()
&& m_renderbuffer->emulatedStencilBuffer()->internalFormat() != GL_STENCIL_INDEX8) {
@@ -110,23 +107,12 @@ namespace {
return m_renderbuffer->object();
}
- bool WebGLRenderbufferAttachment::initialized() const
- {
- return m_renderbuffer->object() && m_renderbuffer->initialized();
- }
-
- void WebGLRenderbufferAttachment::setInitialized()
- {
- if (m_renderbuffer->object())
- m_renderbuffer->setInitialized();
- }
-
- void WebGLRenderbufferAttachment::onDetached(GraphicsContext3D* context)
+ void WebGLRenderbufferAttachment::onDetached(blink::WebGraphicsContext3D* context)
{
m_renderbuffer->onDetached(context);
}
- void WebGLRenderbufferAttachment::attach(GraphicsContext3D* context, GC3Denum attachment)
+ void WebGLRenderbufferAttachment::attach(blink::WebGraphicsContext3D* context, GLenum attachment)
{
Platform3DObject object = objectOrZero(m_renderbuffer.get());
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL && m_renderbuffer->emulatedStencilBuffer()) {
@@ -137,7 +123,7 @@ namespace {
}
}
- void WebGLRenderbufferAttachment::unattach(GraphicsContext3D* context, GC3Denum attachment)
+ void WebGLRenderbufferAttachment::unattach(blink::WebGraphicsContext3D* context, GLenum attachment)
{
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) {
context->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
@@ -147,61 +133,59 @@ namespace {
}
}
- GC3Denum WebGLRenderbufferAttachment::type() const
+ GLenum WebGLRenderbufferAttachment::type() const
{
notImplemented();
return 0;
}
- class WebGLTextureAttachment : public WebGLFramebuffer::WebGLAttachment {
+ class WebGLTextureAttachment FINAL : public WebGLFramebuffer::WebGLAttachment {
public:
- static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture*, GC3Denum target, GC3Dint level);
+ static PassRefPtr<WebGLFramebuffer::WebGLAttachment> create(WebGLTexture*, GLenum target, GLint level);
private:
- WebGLTextureAttachment(WebGLTexture*, GC3Denum target, GC3Dint level);
- virtual GC3Dsizei width() const;
- virtual GC3Dsizei height() const;
- virtual GC3Denum format() const;
- virtual GC3Denum type() const;
- virtual WebGLSharedObject* object() const;
- virtual bool isSharedObject(WebGLSharedObject*) const;
- virtual bool valid() const;
- virtual bool initialized() const;
- virtual void setInitialized();
- virtual void onDetached(GraphicsContext3D*);
- virtual void attach(GraphicsContext3D*, GC3Denum attachment);
- virtual void unattach(GraphicsContext3D*, GC3Denum attachment);
+ WebGLTextureAttachment(WebGLTexture*, GLenum target, GLint level);
+ virtual GLsizei width() const OVERRIDE;
+ virtual GLsizei height() const OVERRIDE;
+ virtual GLenum format() const OVERRIDE;
+ virtual GLenum type() const OVERRIDE;
+ virtual WebGLSharedObject* object() const OVERRIDE;
+ virtual bool isSharedObject(WebGLSharedObject*) const OVERRIDE;
+ virtual bool valid() const OVERRIDE;
+ virtual void onDetached(blink::WebGraphicsContext3D*) OVERRIDE;
+ virtual void attach(blink::WebGraphicsContext3D*, GLenum attachment) OVERRIDE;
+ virtual void unattach(blink::WebGraphicsContext3D*, GLenum attachment) OVERRIDE;
WebGLTextureAttachment() { };
RefPtr<WebGLTexture> m_texture;
- GC3Denum m_target;
- GC3Dint m_level;
+ GLenum m_target;
+ GLint m_level;
};
- PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create(WebGLTexture* texture, GC3Denum target, GC3Dint level)
+ PassRefPtr<WebGLFramebuffer::WebGLAttachment> WebGLTextureAttachment::create(WebGLTexture* texture, GLenum target, GLint level)
{
return adoptRef(new WebGLTextureAttachment(texture, target, level));
}
- WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GC3Denum target, GC3Dint level)
+ WebGLTextureAttachment::WebGLTextureAttachment(WebGLTexture* texture, GLenum target, GLint level)
: m_texture(texture)
, m_target(target)
, m_level(level)
{
}
- GC3Dsizei WebGLTextureAttachment::width() const
+ GLsizei WebGLTextureAttachment::width() const
{
return m_texture->getWidth(m_target, m_level);
}
- GC3Dsizei WebGLTextureAttachment::height() const
+ GLsizei WebGLTextureAttachment::height() const
{
return m_texture->getHeight(m_target, m_level);
}
- GC3Denum WebGLTextureAttachment::format() const
+ GLenum WebGLTextureAttachment::format() const
{
return m_texture->getInternalFormat(m_target, m_level);
}
@@ -221,29 +205,18 @@ namespace {
return m_texture->object();
}
- bool WebGLTextureAttachment::initialized() const
- {
- // Textures are assumed to be initialized.
- return true;
- }
-
- void WebGLTextureAttachment::setInitialized()
- {
- // Textures are assumed to be initialized.
- }
-
- void WebGLTextureAttachment::onDetached(GraphicsContext3D* context)
+ void WebGLTextureAttachment::onDetached(blink::WebGraphicsContext3D* context)
{
m_texture->onDetached(context);
}
- void WebGLTextureAttachment::attach(GraphicsContext3D* context, GC3Denum attachment)
+ void WebGLTextureAttachment::attach(blink::WebGraphicsContext3D* context, GLenum attachment)
{
Platform3DObject object = objectOrZero(m_texture.get());
context->framebufferTexture2D(GL_FRAMEBUFFER, attachment, m_target, object, m_level);
}
- void WebGLTextureAttachment::unattach(GraphicsContext3D* context, GC3Denum attachment)
+ void WebGLTextureAttachment::unattach(blink::WebGraphicsContext3D* context, GLenum attachment)
{
if (attachment == GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL) {
context->framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_target, 0, m_level);
@@ -253,12 +226,12 @@ namespace {
}
}
- GC3Denum WebGLTextureAttachment::type() const
+ GLenum WebGLTextureAttachment::type() const
{
return m_texture->getType(m_target, m_level);
}
- bool isColorRenderable(GC3Denum internalformat)
+ bool isColorRenderable(GLenum internalformat)
{
switch (internalformat) {
case GL_RGBA4:
@@ -280,17 +253,17 @@ WebGLFramebuffer::WebGLAttachment::~WebGLAttachment()
{
}
-PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLFramebuffer(ctx));
}
-WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
+WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx)
: WebGLContextObject(ctx)
, m_hasEverBeenBound(false)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createFramebuffer());
+ setObject(ctx->webContext()->createFramebuffer());
}
WebGLFramebuffer::~WebGLFramebuffer()
@@ -298,7 +271,7 @@ WebGLFramebuffer::~WebGLFramebuffer()
deleteObject(0);
}
-void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture* texture, GC3Dint level)
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum attachment, GLenum texTarget, WebGLTexture* texture, GLint level)
{
ASSERT(isBound());
removeAttachmentFromBoundFramebuffer(attachment);
@@ -311,7 +284,7 @@ void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3
}
}
-void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer* renderbuffer)
+void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GLenum attachment, WebGLRenderbuffer* renderbuffer)
{
ASSERT(isBound());
removeAttachmentFromBoundFramebuffer(attachment);
@@ -324,15 +297,15 @@ void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, Web
}
}
-void WebGLFramebuffer::attach(GC3Denum attachment, GC3Denum attachmentPoint)
+void WebGLFramebuffer::attach(GLenum attachment, GLenum attachmentPoint)
{
ASSERT(isBound());
WebGLAttachment* attachmentObject = getAttachment(attachment);
if (attachmentObject)
- attachmentObject->attach(context()->graphicsContext3D(), attachmentPoint);
+ attachmentObject->attach(context()->webContext(), attachmentPoint);
}
-WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GC3Denum attachment) const
+WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GLenum attachment) const
{
if (!object())
return 0;
@@ -340,12 +313,12 @@ WebGLSharedObject* WebGLFramebuffer::getAttachmentObject(GC3Denum attachment) co
return attachmentObject ? attachmentObject->object() : 0;
}
-bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3Denum attachment, const char** reason) const
+bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GLenum attachment, const char** reason) const
{
ASSERT(attachedObject && attachedObject->valid());
ASSERT(reason);
- GC3Denum internalformat = attachedObject->format();
+ GLenum internalformat = attachedObject->format();
WebGLSharedObject* object = attachedObject->object();
ASSERT(object && (object->isTexture() || object->isRenderbuffer()));
@@ -356,8 +329,8 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3
return false;
}
} else if (object->isTexture()) {
- GC3Denum type = attachedObject->type();
- if (!(context()->m_webglDepthTexture && internalformat == GL_DEPTH_COMPONENT
+ GLenum type = attachedObject->type();
+ if (!(context()->extensionEnabled(WebGLDepthTextureName) && internalformat == GL_DEPTH_COMPONENT
&& (type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT))) {
*reason = "the attached texture is not a depth texture";
return false;
@@ -379,23 +352,23 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3
return false;
}
} else if (object->isTexture()) {
- GC3Denum type = attachedObject->type();
- if (!(context()->m_webglDepthTexture && internalformat == GL_DEPTH_STENCIL_OES
+ GLenum type = attachedObject->type();
+ if (!(context()->extensionEnabled(WebGLDepthTextureName) && internalformat == GL_DEPTH_STENCIL_OES
&& type == GL_UNSIGNED_INT_24_8_OES)) {
*reason = "the attached texture is not a DEPTH_STENCIL texture";
return false;
}
}
} else if (attachment == GL_COLOR_ATTACHMENT0
- || (context()->m_webglDrawBuffers && attachment > GL_COLOR_ATTACHMENT0
- && attachment < static_cast<GC3Denum>(GL_COLOR_ATTACHMENT0 + context()->maxColorAttachments()))) {
+ || (context()->extensionEnabled(WebGLDrawBuffersName) && attachment > GL_COLOR_ATTACHMENT0
+ && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + context()->maxColorAttachments()))) {
if (object->isRenderbuffer()) {
if (!isColorRenderable(internalformat)) {
*reason = "the internalformat of the attached renderbuffer is not color-renderable";
return false;
}
} else if (object->isTexture()) {
- GC3Denum type = attachedObject->type();
+ GLenum type = attachedObject->type();
if (internalformat != GL_RGBA && internalformat != GL_RGB) {
*reason = "the internalformat of the attached texture is not color-renderable";
return false;
@@ -408,8 +381,8 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3
&& type != GL_UNSIGNED_SHORT_5_6_5
&& type != GL_UNSIGNED_SHORT_4_4_4_4
&& type != GL_UNSIGNED_SHORT_5_5_5_1
- && !(type == GL_FLOAT && context()->m_oesTextureFloat)
- && !(type == GL_HALF_FLOAT_OES && context()->m_oesTextureHalfFloat)) {
+ && !(type == GL_FLOAT && context()->extensionEnabled(OESTextureFloatName))
+ && !(type == GL_HALF_FLOAT_OES && context()->extensionEnabled(OESTextureHalfFloatName))) {
*reason = "unsupported type: The attached texture is not supported to be rendered to";
return false;
}
@@ -426,13 +399,13 @@ bool WebGLFramebuffer::isAttachmentComplete(WebGLAttachment* attachedObject, GC3
return true;
}
-WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
+WebGLFramebuffer::WebGLAttachment* WebGLFramebuffer::getAttachment(GLenum attachment) const
{
const AttachmentMap::const_iterator it = m_attachments.find(attachment);
return (it != m_attachments.end()) ? it->value.get() : 0;
}
-void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GLenum attachment)
{
ASSERT(isBound());
if (!object())
@@ -440,7 +413,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
WebGLAttachment* attachmentObject = getAttachment(attachment);
if (attachmentObject) {
- attachmentObject->onDetached(context()->graphicsContext3D());
+ attachmentObject->onDetached(context()->webContext());
m_attachments.remove(attachment);
drawBuffersIfNecessary(false);
switch (attachment) {
@@ -472,8 +445,8 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a
for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments.end(); ++it) {
WebGLAttachment* attachmentObject = it->value.get();
if (attachmentObject->isSharedObject(attachment)) {
- GC3Denum attachmentType = it->key;
- attachmentObject->unattach(context()->graphicsContext3D(), attachmentType);
+ GLenum attachmentType = it->key;
+ attachmentObject->unattach(context()->webContext(), attachmentType);
removeAttachmentFromBoundFramebuffer(attachmentType);
checkMore = true;
break;
@@ -482,29 +455,7 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* a
}
}
-GC3Dsizei WebGLFramebuffer::colorBufferWidth() const
-{
- if (!object())
- return 0;
- WebGLAttachment* attachment = getAttachment(GL_COLOR_ATTACHMENT0);
- if (!attachment)
- return 0;
-
- return attachment->width();
-}
-
-GC3Dsizei WebGLFramebuffer::colorBufferHeight() const
-{
- if (!object())
- return 0;
- WebGLAttachment* attachment = getAttachment(GL_COLOR_ATTACHMENT0);
- if (!attachment)
- return 0;
-
- return attachment->height();
-}
-
-GC3Denum WebGLFramebuffer::colorBufferFormat() const
+GLenum WebGLFramebuffer::colorBufferFormat() const
{
if (!object())
return 0;
@@ -514,10 +465,10 @@ GC3Denum WebGLFramebuffer::colorBufferFormat() const
return attachment->format();
}
-GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const
+GLenum WebGLFramebuffer::checkStatus(const char** reason) const
{
- unsigned int count = 0;
- GC3Dsizei width = 0, height = 0;
+ unsigned count = 0;
+ GLsizei width = 0, height = 0;
bool haveDepth = false;
bool haveStencil = false;
bool haveDepthStencil = false;
@@ -571,7 +522,7 @@ GC3Denum WebGLFramebuffer::checkStatus(const char** reason) const
return GL_FRAMEBUFFER_COMPLETE;
}
-bool WebGLFramebuffer::onAccess(GraphicsContext3D* context3d, const char** reason)
+bool WebGLFramebuffer::onAccess(blink::WebGraphicsContext3D* context3d, const char** reason)
{
if (checkStatus(reason) != GL_FRAMEBUFFER_COMPLETE)
return false;
@@ -586,7 +537,7 @@ bool WebGLFramebuffer::hasStencilBuffer() const
return attachment && attachment->valid();
}
-void WebGLFramebuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLFramebuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
for (AttachmentMap::iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
it->value->onDetached(context3d);
@@ -599,7 +550,7 @@ bool WebGLFramebuffer::isBound() const
return (context()->m_framebufferBinding.get() == this);
}
-void WebGLFramebuffer::drawBuffers(const Vector<GC3Denum>& bufs)
+void WebGLFramebuffer::drawBuffers(const Vector<GLenum>& bufs)
{
m_drawBuffers = bufs;
m_filteredDrawBuffers.resize(m_drawBuffers.size());
@@ -610,7 +561,7 @@ void WebGLFramebuffer::drawBuffers(const Vector<GC3Denum>& bufs)
void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
{
- if (!context()->m_webglDrawBuffers)
+ if (!context()->extensionEnabled(WebGLDrawBuffersName))
return;
bool reset = force;
// This filtering works around graphics driver bugs on Mac OS X.
@@ -628,18 +579,18 @@ void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
}
}
if (reset) {
- context()->graphicsContext3D()->extensions()->drawBuffersEXT(
+ context()->webContext()->drawBuffersEXT(
m_filteredDrawBuffers.size(), m_filteredDrawBuffers.data());
}
}
-GC3Denum WebGLFramebuffer::getDrawBuffer(GC3Denum drawBuffer)
+GLenum WebGLFramebuffer::getDrawBuffer(GLenum drawBuffer)
{
- int index = static_cast<int>(drawBuffer - Extensions3D::DRAW_BUFFER0_EXT);
+ int index = static_cast<int>(drawBuffer - GL_DRAW_BUFFER0_EXT);
ASSERT(index >= 0);
if (index < static_cast<int>(m_drawBuffers.size()))
return m_drawBuffers[index];
- if (drawBuffer == Extensions3D::DRAW_BUFFER0_EXT)
+ if (drawBuffer == GL_DRAW_BUFFER0_EXT)
return GL_COLOR_ATTACHMENT0;
return GL_NONE;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h
index 86e2aebf4e8..e8705e61187 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLFramebuffer.h
@@ -37,28 +37,26 @@ namespace WebCore {
class WebGLRenderbuffer;
class WebGLTexture;
-class WebGLFramebuffer : public WebGLContextObject, public ScriptWrappable {
+class WebGLFramebuffer FINAL : public WebGLContextObject, public ScriptWrappable {
public:
class WebGLAttachment : public RefCounted<WebGLAttachment> {
public:
virtual ~WebGLAttachment();
- virtual GC3Dsizei width() const = 0;
- virtual GC3Dsizei height() const = 0;
- virtual GC3Denum format() const = 0;
+ virtual GLsizei width() const = 0;
+ virtual GLsizei height() const = 0;
+ virtual GLenum format() const = 0;
// For texture attachment, type() returns the type of the attached texture.
// For renderbuffer attachment, the type of the renderbuffer may vary with GL implementation.
// To avoid confusion, it would be better to not implement type() for renderbuffer attachment and
// we should always use the internalformat of the renderbuffer and avoid using type() API.
- virtual GC3Denum type() const = 0;
+ virtual GLenum type() const = 0;
virtual WebGLSharedObject* object() const = 0;
virtual bool isSharedObject(WebGLSharedObject*) const = 0;
virtual bool valid() const = 0;
- virtual bool initialized() const = 0;
- virtual void setInitialized() = 0;
- virtual void onDetached(GraphicsContext3D*) = 0;
- virtual void attach(GraphicsContext3D*, GC3Denum attachment) = 0;
- virtual void unattach(GraphicsContext3D*, GC3Denum attachment) = 0;
+ virtual void onDetached(blink::WebGraphicsContext3D*) = 0;
+ virtual void attach(blink::WebGraphicsContext3D*, GLenum attachment) = 0;
+ virtual void unattach(blink::WebGraphicsContext3D*, GLenum attachment) = 0;
protected:
WebGLAttachment();
@@ -66,33 +64,29 @@ public:
virtual ~WebGLFramebuffer();
- static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContextBase*);
- void setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
- void setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer*);
+ void setAttachmentForBoundFramebuffer(GLenum attachment, GLenum texTarget, WebGLTexture*, GLint level);
+ void setAttachmentForBoundFramebuffer(GLenum attachment, WebGLRenderbuffer*);
// If an object is attached to the currently bound framebuffer, remove it.
void removeAttachmentFromBoundFramebuffer(WebGLSharedObject*);
// If a given attachment point for the currently bound framebuffer is not null, remove the attached object.
- void removeAttachmentFromBoundFramebuffer(GC3Denum);
- WebGLSharedObject* getAttachmentObject(GC3Denum) const;
+ void removeAttachmentFromBoundFramebuffer(GLenum);
+ WebGLSharedObject* getAttachmentObject(GLenum) const;
- GC3Denum colorBufferFormat() const;
- GC3Dsizei colorBufferWidth() const;
- GC3Dsizei colorBufferHeight() const;
+ GLenum colorBufferFormat() const;
// This should always be called before drawArray, drawElements, clear,
// readPixels, copyTexImage2D, copyTexSubImage2D if this framebuffer is
// currently bound.
- // Return false if the framebuffer is incomplete; otherwise initialize
- // the buffers if they haven't been initialized and
- // needToInitializeAttachments is true.
- bool onAccess(GraphicsContext3D*, const char** reason);
+ // Return false if the framebuffer is incomplete.
+ bool onAccess(blink::WebGraphicsContext3D*, const char** reason);
// Software version of glCheckFramebufferStatus(), except that when
// FRAMEBUFFER_COMPLETE is returned, it is still possible for
// glCheckFramebufferStatus() to return FRAMEBUFFER_UNSUPPORTED,
// depending on hardware implementation.
- GC3Denum checkStatus(const char** reason) const;
+ GLenum checkStatus(const char** reason) const;
bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
@@ -101,38 +95,36 @@ public:
bool hasStencilBuffer() const;
// Wrapper for drawBuffersEXT/drawBuffersARB to work around a driver bug.
- void drawBuffers(const Vector<GC3Denum>& bufs);
+ void drawBuffers(const Vector<GLenum>& bufs);
- GC3Denum getDrawBuffer(GC3Denum);
+ GLenum getDrawBuffer(GLenum);
protected:
- WebGLFramebuffer(WebGLRenderingContext*);
+ WebGLFramebuffer(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
- virtual bool isFramebuffer() const { return true; }
-
- WebGLAttachment* getAttachment(GC3Denum) const;
- bool isAttachmentComplete(WebGLAttachment* attachedObject, GC3Denum attachment, const char** reason) const;
+ WebGLAttachment* getAttachment(GLenum) const;
+ bool isAttachmentComplete(WebGLAttachment* attachedObject, GLenum attachment, const char** reason) const;
// Check if the framebuffer is currently bound.
bool isBound() const;
// attach 'attachment' at 'attachmentPoint'.
- void attach(GC3Denum attachment, GC3Denum attachmentPoint);
+ void attach(GLenum attachment, GLenum attachmentPoint);
// Check if a new drawBuffers call should be issued. This is called when we add or remove an attachment.
void drawBuffersIfNecessary(bool force);
- typedef WTF::HashMap<GC3Denum, RefPtr<WebGLAttachment> > AttachmentMap;
+ typedef WTF::HashMap<GLenum, RefPtr<WebGLAttachment> > AttachmentMap;
AttachmentMap m_attachments;
bool m_hasEverBeenBound;
- Vector<GC3Denum> m_drawBuffers;
- Vector<GC3Denum> m_filteredDrawBuffers;
+ Vector<GLenum> m_drawBuffers;
+ Vector<GLenum> m_filteredDrawBuffers;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp
index 55cead3c16f..d4f893bc0d2 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.cpp
@@ -90,7 +90,7 @@ WebGLGetInfo::WebGLGetInfo(const String& value)
{
}
-WebGLGetInfo::WebGLGetInfo(unsigned int value)
+WebGLGetInfo::WebGLGetInfo(unsigned value)
: m_type(kTypeUnsignedInt)
, m_bool(false)
, m_float(0)
@@ -234,7 +234,7 @@ const String& WebGLGetInfo::getString() const
return m_string;
}
-unsigned int WebGLGetInfo::getUnsignedInt() const
+unsigned WebGLGetInfo::getUnsignedInt() const
{
ASSERT(getType() == kTypeUnsignedInt);
return m_unsignedInt;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h
index d72e7f9c65a..4528bb4a2b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLGetInfo.h
@@ -78,7 +78,7 @@ public:
// Represents the null value and type.
WebGLGetInfo();
explicit WebGLGetInfo(const String& value);
- explicit WebGLGetInfo(unsigned int value);
+ explicit WebGLGetInfo(unsigned value);
explicit WebGLGetInfo(PassRefPtr<WebGLBuffer> value);
explicit WebGLGetInfo(PassRefPtr<Float32Array> value);
explicit WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value);
@@ -99,7 +99,7 @@ public:
float getFloat() const;
int getInt() const;
const String& getString() const;
- unsigned int getUnsignedInt() const;
+ unsigned getUnsignedInt() const;
PassRefPtr<WebGLBuffer> getWebGLBuffer() const;
PassRefPtr<Float32Array> getWebGLFloatArray() const;
PassRefPtr<WebGLFramebuffer> getWebGLFramebuffer() const;
@@ -120,7 +120,7 @@ private:
float m_float;
int m_int;
String m_string;
- unsigned int m_unsignedInt;
+ unsigned m_unsignedInt;
RefPtr<WebGLBuffer> m_webglBuffer;
RefPtr<Float32Array> m_webglFloatArray;
RefPtr<WebGLFramebuffer> m_webglFramebuffer;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp
index ca1226a9ba2..e2fe7bd738d 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.cpp
@@ -27,11 +27,11 @@
#include "core/html/canvas/WebGLLoseContext.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLLoseContext::WebGLLoseContext(WebGLRenderingContext* context)
+WebGLLoseContext::WebGLLoseContext(WebGLRenderingContextBase* context)
: WebGLExtension(context)
{
ScriptWrappable::init(this);
@@ -47,12 +47,12 @@ void WebGLLoseContext::lose(bool force)
WebGLExtension::lose(true);
}
-WebGLExtension::ExtensionName WebGLLoseContext::name() const
+WebGLExtensionName WebGLLoseContext::name() const
{
return WebGLLoseContextName;
}
-PassRefPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContextBase* context)
{
return adoptRef(new WebGLLoseContext(context));
}
@@ -60,7 +60,7 @@ PassRefPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContext* con
void WebGLLoseContext::loseContext()
{
if (!isLost())
- m_context->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
+ m_context->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext);
}
void WebGLLoseContext::restoreContext()
@@ -69,7 +69,7 @@ void WebGLLoseContext::restoreContext()
m_context->forceRestoreContext();
}
-bool WebGLLoseContext::supported(WebGLRenderingContext*)
+bool WebGLLoseContext::supported(WebGLRenderingContextBase*)
{
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h
index 23140d62632..cab49f34740 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.h
@@ -32,23 +32,23 @@
namespace WebCore {
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
-class WebGLLoseContext : public WebGLExtension, public ScriptWrappable {
+class WebGLLoseContext FINAL : public WebGLExtension, public ScriptWrappable {
public:
- static PassRefPtr<WebGLLoseContext> create(WebGLRenderingContext*);
- static bool supported(WebGLRenderingContext*);
+ static PassRefPtr<WebGLLoseContext> create(WebGLRenderingContextBase*);
+ static bool supported(WebGLRenderingContextBase*);
static const char* extensionName();
virtual ~WebGLLoseContext();
- virtual ExtensionName name() const;
- virtual void lose(bool);
+ virtual WebGLExtensionName name() const OVERRIDE;
+ virtual void lose(bool) OVERRIDE;
void loseContext();
void restoreContext();
private:
- WebGLLoseContext(WebGLRenderingContext*);
+ WebGLLoseContext(WebGLRenderingContextBase*);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl
index 1ac288f2489..117fcf221ec 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLLoseContext.idl
@@ -24,8 +24,9 @@
*/
[
- NoInterfaceObject
+ NoInterfaceObject,
+ TypeChecking=Interface|Nullable,
] interface WebGLLoseContext {
- [StrictTypeChecking] void loseContext();
- [StrictTypeChecking] void restoreContext();
+ void loseContext();
+ void restoreContext();
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp
index 3ffddaad3fd..14dd8ba5ee8 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
-WebGLObject::WebGLObject(WebGLRenderingContext*)
+WebGLObject::WebGLObject(WebGLRenderingContextBase*)
: m_object(0)
, m_attachmentCount(0)
, m_deleted(false)
@@ -47,7 +47,7 @@ void WebGLObject::setObject(Platform3DObject object)
m_object = object;
}
-void WebGLObject::deleteObject(GraphicsContext3D* context3d)
+void WebGLObject::deleteObject(blink::WebGraphicsContext3D* context3d)
{
m_deleted = true;
if (!m_object)
@@ -58,7 +58,7 @@ void WebGLObject::deleteObject(GraphicsContext3D* context3d)
if (!m_attachmentCount) {
if (!context3d)
- context3d = getAGraphicsContext3D();
+ context3d = getAWebGraphicsContext3D();
if (context3d)
deleteObjectImpl(context3d, m_object);
@@ -73,7 +73,7 @@ void WebGLObject::detach()
}
-void WebGLObject::onDetached(GraphicsContext3D* context3d)
+void WebGLObject::onDetached(blink::WebGraphicsContext3D* context3d)
{
if (m_attachmentCount)
--m_attachmentCount;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h
index 55a7d51e2da..ae5c439c8a6 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLObject.h
@@ -26,14 +26,17 @@
#ifndef WebGLObject_h
#define WebGLObject_h
-#include "platform/graphics/GraphicsContext3D.h"
+#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/RefCounted.h"
+namespace blink {
+class WebGraphicsContext3D;
+}
+
namespace WebCore {
-class GraphicsContext3D;
class WebGLContextGroup;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
class WebGLObject : public RefCounted<WebGLObject> {
public:
@@ -44,10 +47,10 @@ public:
// deleteObject may not always delete the OpenGL resource. For programs and
// shaders, deletion is delayed until they are no longer attached.
// FIXME: revisit this when resource sharing between contexts are implemented.
- void deleteObject(GraphicsContext3D*);
+ void deleteObject(blink::WebGraphicsContext3D*);
void onAttached() { ++m_attachmentCount; }
- void onDetached(GraphicsContext3D*);
+ void onDetached(blink::WebGraphicsContext3D*);
// This indicates whether the client side issue a delete call already, not
// whether the OpenGL resource is deleted.
@@ -55,22 +58,22 @@ public:
bool isDeleted() { return m_deleted; }
// True if this object belongs to the group or context.
- virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext*) const = 0;
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase*) const = 0;
protected:
- WebGLObject(WebGLRenderingContext*);
+ WebGLObject(WebGLRenderingContextBase*);
// setObject should be only called once right after creating a WebGLObject.
void setObject(Platform3DObject);
// deleteObjectImpl should be only called once to delete the OpenGL resource.
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) = 0;
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) = 0;
virtual bool hasGroupOrContext() const = 0;
virtual void detach();
- virtual GraphicsContext3D* getAGraphicsContext3D() const = 0;
+ virtual blink::WebGraphicsContext3D* getAWebGraphicsContext3D() const = 0;
private:
Platform3DObject m_object;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp
index 6a1539331f9..e1e49594139 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp
@@ -27,23 +27,23 @@
#include "core/html/canvas/WebGLProgram.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLProgram(ctx));
}
-WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
+WebGLProgram::WebGLProgram(WebGLRenderingContextBase* ctx)
: WebGLSharedObject(ctx)
, m_linkStatus(false)
, m_linkCount(0)
, m_infoValid(true)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createProgram());
+ setObject(ctx->webContext()->createProgram());
}
WebGLProgram::~WebGLProgram()
@@ -51,16 +51,16 @@ WebGLProgram::~WebGLProgram()
deleteObject(0);
}
-void WebGLProgram::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject obj)
+void WebGLProgram::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject obj)
{
context3d->deleteProgram(obj);
if (m_vertexShader) {
m_vertexShader->onDetached(context3d);
- m_vertexShader = 0;
+ m_vertexShader = nullptr;
}
if (m_fragmentShader) {
m_fragmentShader->onDetached(context3d);
- m_fragmentShader = 0;
+ m_fragmentShader = nullptr;
}
}
@@ -70,7 +70,7 @@ unsigned WebGLProgram::numActiveAttribLocations()
return m_activeAttribLocations.size();
}
-GC3Dint WebGLProgram::getActiveAttribLocation(GC3Duint index)
+GLint WebGLProgram::getActiveAttribLocation(GLuint index)
{
cacheInfoIfNeeded();
if (index >= numActiveAttribLocations())
@@ -94,19 +94,13 @@ bool WebGLProgram::linkStatus()
return m_linkStatus;
}
-void WebGLProgram::setLinkStatus(bool status)
-{
- cacheInfoIfNeeded();
- m_linkStatus = status;
-}
-
void WebGLProgram::increaseLinkCount()
{
++m_linkCount;
m_infoValid = false;
}
-WebGLShader* WebGLProgram::getAttachedShader(GC3Denum type)
+WebGLShader* WebGLProgram::getAttachedShader(GLenum type)
{
switch (type) {
case GL_VERTEX_SHADER:
@@ -146,29 +140,29 @@ bool WebGLProgram::detachShader(WebGLShader* shader)
case GL_VERTEX_SHADER:
if (m_vertexShader != shader)
return false;
- m_vertexShader = 0;
+ m_vertexShader = nullptr;
return true;
case GL_FRAGMENT_SHADER:
if (m_fragmentShader != shader)
return false;
- m_fragmentShader = 0;
+ m_fragmentShader = nullptr;
return true;
default:
return false;
}
}
-void WebGLProgram::cacheActiveAttribLocations(GraphicsContext3D* context3d)
+void WebGLProgram::cacheActiveAttribLocations(blink::WebGraphicsContext3D* context3d)
{
m_activeAttribLocations.clear();
- GC3Dint numAttribs = 0;
+ GLint numAttribs = 0;
context3d->getProgramiv(object(), GL_ACTIVE_ATTRIBUTES, &numAttribs);
m_activeAttribLocations.resize(static_cast<size_t>(numAttribs));
for (int i = 0; i < numAttribs; ++i) {
- ActiveInfo info;
+ blink::WebGraphicsContext3D::ActiveInfo info;
context3d->getActiveAttrib(object(), i, info);
- m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name);
+ m_activeAttribLocations[i] = context3d->getAttribLocation(object(), info.name.utf8().data());
}
}
@@ -180,10 +174,10 @@ void WebGLProgram::cacheInfoIfNeeded()
if (!object())
return;
- GraphicsContext3D* context = getAGraphicsContext3D();
+ blink::WebGraphicsContext3D* context = getAWebGraphicsContext3D();
if (!context)
return;
- GC3Dint linkStatus = 0;
+ GLint linkStatus = 0;
context->getProgramiv(object(), GL_LINK_STATUS, &linkStatus);
m_linkStatus = linkStatus;
if (m_linkStatus)
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h
index 5ba00e7cf70..f68b33048ae 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLProgram.h
@@ -34,19 +34,18 @@
namespace WebCore {
-class WebGLProgram : public WebGLSharedObject, public ScriptWrappable {
+class WebGLProgram FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
virtual ~WebGLProgram();
- static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLProgram> create(WebGLRenderingContextBase*);
unsigned numActiveAttribLocations();
- GC3Dint getActiveAttribLocation(GC3Duint index);
+ GLint getActiveAttribLocation(GLuint index);
bool isUsingVertexAttrib0();
bool linkStatus();
- void setLinkStatus(bool);
unsigned linkCount() const { return m_linkCount; }
@@ -56,24 +55,24 @@ public:
// Also, we invalidate the cached program info.
void increaseLinkCount();
- WebGLShader* getAttachedShader(GC3Denum);
+ WebGLShader* getAttachedShader(GLenum);
bool attachShader(WebGLShader*);
bool detachShader(WebGLShader*);
protected:
- WebGLProgram(WebGLRenderingContext*);
+ WebGLProgram(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
- virtual bool isProgram() const { return true; }
+ virtual bool isProgram() const OVERRIDE { return true; }
- void cacheActiveAttribLocations(GraphicsContext3D*);
+ void cacheActiveAttribLocations(blink::WebGraphicsContext3D*);
void cacheInfoIfNeeded();
- Vector<GC3Dint> m_activeAttribLocations;
+ Vector<GLint> m_activeAttribLocations;
- GC3Dint m_linkStatus;
+ GLint m_linkStatus;
// This is used to track whether a WebGLUniformLocation belongs to this
// program or not.
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp
index da27596f273..76ef482e037 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp
@@ -27,11 +27,11 @@
#include "core/html/canvas/WebGLRenderbuffer.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLRenderbuffer(ctx));
}
@@ -41,25 +41,24 @@ WebGLRenderbuffer::~WebGLRenderbuffer()
deleteObject(0);
}
-WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
+WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContextBase* ctx)
: WebGLSharedObject(ctx)
, m_internalFormat(GL_RGBA4)
- , m_initialized(false)
, m_width(0)
, m_height(0)
, m_hasEverBeenBound(false)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createRenderbuffer());
+ setObject(ctx->webContext()->createRenderbuffer());
}
-void WebGLRenderbuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLRenderbuffer::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
context3d->deleteRenderbuffer(object);
deleteEmulatedStencilBuffer(context3d);
}
-void WebGLRenderbuffer::deleteEmulatedStencilBuffer(GraphicsContext3D* context3d)
+void WebGLRenderbuffer::deleteEmulatedStencilBuffer(blink::WebGraphicsContext3D* context3d)
{
if (!m_emulatedStencilBuffer)
return;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h
index 95688a20d26..4c08712de63 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.h
@@ -32,29 +32,25 @@
namespace WebCore {
-class WebGLRenderbuffer : public WebGLSharedObject, public ScriptWrappable {
+class WebGLRenderbuffer FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
virtual ~WebGLRenderbuffer();
- static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContextBase*);
- void setInternalFormat(GC3Denum internalformat)
+ void setInternalFormat(GLenum internalformat)
{
m_internalFormat = internalformat;
- m_initialized = false;
}
- GC3Denum internalFormat() const { return m_internalFormat; }
+ GLenum internalFormat() const { return m_internalFormat; }
- void setSize(GC3Dsizei width, GC3Dsizei height)
+ void setSize(GLsizei width, GLsizei height)
{
m_width = width;
m_height = height;
}
- GC3Dsizei width() const { return m_width; }
- GC3Dsizei height() const { return m_height; }
-
- bool initialized() const { return m_initialized; }
- void setInitialized() { m_initialized = true; }
+ GLsizei width() const { return m_width; }
+ GLsizei height() const { return m_height; }
bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
@@ -62,19 +58,18 @@ public:
void setEmulatedStencilBuffer(PassRefPtr<WebGLRenderbuffer> buffer) { m_emulatedStencilBuffer = buffer; }
WebGLRenderbuffer* emulatedStencilBuffer() const { return m_emulatedStencilBuffer.get(); }
- void deleteEmulatedStencilBuffer(GraphicsContext3D* context3d);
+ void deleteEmulatedStencilBuffer(blink::WebGraphicsContext3D* context3d);
protected:
- WebGLRenderbuffer(WebGLRenderingContext*);
+ WebGLRenderbuffer(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
- virtual bool isRenderbuffer() const { return true; }
+ virtual bool isRenderbuffer() const OVERRIDE { return true; }
- GC3Denum m_internalFormat;
- bool m_initialized;
- GC3Dsizei m_width, m_height;
+ GLenum m_internalFormat;
+ GLsizei m_width, m_height;
bool m_hasEverBeenBound;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp
index ed0d58811ad..e1d1c070724 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp
@@ -26,17 +26,11 @@
#include "config.h"
#include "core/html/canvas/WebGLRenderingContext.h"
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLCanvasElement.h"
-#include "core/html/HTMLImageElement.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/html/ImageData.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/canvas/ANGLEInstancedArrays.h"
+#include "core/html/canvas/EXTBlendMinMax.h"
#include "core/html/canvas/EXTFragDepth.h"
+#include "core/html/canvas/EXTShaderTextureLOD.h"
#include "core/html/canvas/EXTTextureFilterAnisotropic.h"
#include "core/html/canvas/OESElementIndexUint.h"
#include "core/html/canvas/OESStandardDerivatives.h"
@@ -45,458 +39,36 @@
#include "core/html/canvas/OESTextureHalfFloat.h"
#include "core/html/canvas/OESTextureHalfFloatLinear.h"
#include "core/html/canvas/OESVertexArrayObject.h"
-#include "core/html/canvas/WebGLActiveInfo.h"
-#include "core/html/canvas/WebGLBuffer.h"
#include "core/html/canvas/WebGLCompressedTextureATC.h"
+#include "core/html/canvas/WebGLCompressedTextureETC1.h"
#include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
#include "core/html/canvas/WebGLCompressedTextureS3TC.h"
#include "core/html/canvas/WebGLContextAttributes.h"
#include "core/html/canvas/WebGLContextEvent.h"
-#include "core/html/canvas/WebGLContextGroup.h"
#include "core/html/canvas/WebGLDebugRendererInfo.h"
#include "core/html/canvas/WebGLDebugShaders.h"
#include "core/html/canvas/WebGLDepthTexture.h"
#include "core/html/canvas/WebGLDrawBuffers.h"
-#include "core/html/canvas/WebGLFramebuffer.h"
#include "core/html/canvas/WebGLLoseContext.h"
-#include "core/html/canvas/WebGLProgram.h"
-#include "core/html/canvas/WebGLRenderbuffer.h"
-#include "core/html/canvas/WebGLShader.h"
-#include "core/html/canvas/WebGLShaderPrecisionFormat.h"
-#include "core/html/canvas/WebGLTexture.h"
-#include "core/html/canvas/WebGLUniformLocation.h"
-#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
#include "core/frame/Settings.h"
#include "core/rendering/RenderBox.h"
#include "platform/CheckedInt.h"
#include "platform/NotImplemented.h"
-#include "platform/geometry/IntSize.h"
-#include "platform/graphics/Extensions3D.h"
-#include "platform/graphics/UnacceleratedImageBufferSurface.h"
#include "platform/graphics/gpu/DrawingBuffer.h"
-
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Uint32Array.h"
-#include "wtf/text/StringBuilder.h"
+#include "public/platform/Platform.h"
namespace WebCore {
-const double secondsBetweenRestoreAttempts = 1.0;
-const int maxGLErrorsAllowedToConsole = 256;
-const unsigned maxGLActiveContexts = 16;
-
-Vector<WebGLRenderingContext*>& WebGLRenderingContext::activeContexts()
-{
- DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, activeContexts, ());
- return activeContexts;
-}
-
-Vector<WebGLRenderingContext*>& WebGLRenderingContext::forciblyEvictedContexts()
-{
- DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, forciblyEvictedContexts, ());
- return forciblyEvictedContexts;
-}
-
-void WebGLRenderingContext::forciblyLoseOldestContext(const String& reason)
-{
- size_t candidateID = oldestContextIndex();
- if (candidateID >= activeContexts().size())
- return;
-
- WebGLRenderingContext* candidate = activeContexts()[candidateID];
-
- activeContexts().remove(candidateID);
-
- candidate->printWarningToConsole(reason);
- InspectorInstrumentation::didFireWebGLWarning(candidate->canvas());
-
- // This will call deactivateContext once the context has actually been lost.
- candidate->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
-}
-
-size_t WebGLRenderingContext::oldestContextIndex()
-{
- if (!activeContexts().size())
- return maxGLActiveContexts;
-
- WebGLRenderingContext* candidate = activeContexts().first();
- size_t candidateID = 0;
- for (size_t ii = 1; ii < activeContexts().size(); ++ii) {
- WebGLRenderingContext* context = activeContexts()[ii];
- if (context->graphicsContext3D() && candidate->graphicsContext3D() && context->graphicsContext3D()->lastFlushID() < candidate->graphicsContext3D()->lastFlushID()) {
- candidate = context;
- candidateID = ii;
- }
- }
-
- return candidateID;
-}
-
-IntSize WebGLRenderingContext::oldestContextSize()
-{
- IntSize size;
-
- size_t candidateID = oldestContextIndex();
- if (candidateID < activeContexts().size()) {
- WebGLRenderingContext* candidate = activeContexts()[candidateID];
- size.setWidth(candidate->drawingBufferWidth());
- size.setHeight(candidate->drawingBufferHeight());
- }
-
- return size;
-}
-
-void WebGLRenderingContext::activateContext(WebGLRenderingContext* context)
-{
- unsigned removedContexts = 0;
- while (activeContexts().size() >= maxGLActiveContexts && removedContexts < maxGLActiveContexts) {
- forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Oldest context will be lost.");
- removedContexts++;
- }
-
- if (!activeContexts().contains(context))
- activeContexts().append(context);
-}
-
-void WebGLRenderingContext::deactivateContext(WebGLRenderingContext* context, bool addToEvictedList)
-{
- size_t position = activeContexts().find(context);
- if (position != WTF::kNotFound)
- activeContexts().remove(position);
-
- if (addToEvictedList && !forciblyEvictedContexts().contains(context))
- forciblyEvictedContexts().append(context);
-}
-
-void WebGLRenderingContext::willDestroyContext(WebGLRenderingContext* context)
-{
- size_t position = forciblyEvictedContexts().find(context);
- if (position != WTF::kNotFound)
- forciblyEvictedContexts().remove(position);
-
- deactivateContext(context, false);
-
- // Try to re-enable the oldest inactive contexts.
- while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContexts().size()) {
- WebGLRenderingContext* evictedContext = forciblyEvictedContexts().first();
- if (!evictedContext->m_restoreAllowed) {
- forciblyEvictedContexts().remove(0);
- continue;
- }
-
- IntSize desiredSize = evictedContext->m_drawingBuffer->adjustSize(evictedContext->clampedCanvasSize());
-
- // If there's room in the pixel budget for this context, restore it.
- if (!desiredSize.isEmpty()) {
- forciblyEvictedContexts().remove(0);
- evictedContext->forceRestoreContext();
- activeContexts().append(evictedContext);
- }
- break;
- }
-}
-
-class WebGLRenderingContextEvictionManager : public ContextEvictionManager {
-public:
- void forciblyLoseOldestContext(const String& reason) {
- WebGLRenderingContext::forciblyLoseOldestContext(reason);
- };
- IntSize oldestContextSize() {
- return WebGLRenderingContext::oldestContextSize();
- };
-};
-
-namespace {
-
- class ScopedDrawingBufferBinder {
- public:
- ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
- : m_drawingBuffer(drawingBuffer)
- , m_framebufferBinding(framebufferBinding)
- {
- // Commit DrawingBuffer if needed (e.g., for multisampling)
- if (!m_framebufferBinding && m_drawingBuffer)
- m_drawingBuffer->commit();
- }
-
- ~ScopedDrawingBufferBinder()
- {
- // Restore DrawingBuffer if needed
- if (!m_framebufferBinding && m_drawingBuffer)
- m_drawingBuffer->bind();
- }
-
- private:
- DrawingBuffer* m_drawingBuffer;
- WebGLFramebuffer* m_framebufferBinding;
- };
-
- Platform3DObject objectOrZero(WebGLObject* object)
- {
- return object ? object->object() : 0;
- }
-
- GC3Dint clamp(GC3Dint value, GC3Dint min, GC3Dint max)
- {
- if (value < min)
- value = min;
- if (value > max)
- value = max;
- return value;
- }
-
- // Return true if a character belongs to the ASCII subset as defined in
- // GLSL ES 1.0 spec section 3.1.
- bool validateCharacter(unsigned char c)
- {
- // Printing characters are valid except " $ ` @ \ ' DEL.
- if (c >= 32 && c <= 126
- && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
- return true;
- // Horizontal tab, line feed, vertical tab, form feed, carriage return
- // are also valid.
- if (c >= 9 && c <= 13)
- return true;
- return false;
- }
-
- bool isPrefixReserved(const String& name)
- {
- if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
- return true;
- return false;
- }
-
- // Strips comments from shader text. This allows non-ASCII characters
- // to be used in comments without potentially breaking OpenGL
- // implementations not expecting characters outside the GLSL ES set.
- class StripComments {
- public:
- StripComments(const String& str)
- : m_parseState(BeginningOfLine)
- , m_sourceString(str)
- , m_length(str.length())
- , m_position(0)
- {
- parse();
- }
-
- String result()
- {
- return m_builder.toString();
- }
-
- private:
- bool hasMoreCharacters() const
- {
- return (m_position < m_length);
- }
-
- void parse()
- {
- while (hasMoreCharacters()) {
- process(current());
- // process() might advance the position.
- if (hasMoreCharacters())
- advance();
- }
- }
-
- void process(UChar);
-
- bool peek(UChar& character) const
- {
- if (m_position + 1 >= m_length)
- return false;
- character = m_sourceString[m_position + 1];
- return true;
- }
-
- UChar current()
- {
- ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
- return m_sourceString[m_position];
- }
-
- void advance()
- {
- ++m_position;
- }
-
- static bool isNewline(UChar character)
- {
- // Don't attempt to canonicalize newline related characters.
- return (character == '\n' || character == '\r');
- }
-
- void emit(UChar character)
- {
- m_builder.append(character);
- }
-
- enum ParseState {
- // Have not seen an ASCII non-whitespace character yet on
- // this line. Possible that we might see a preprocessor
- // directive.
- BeginningOfLine,
-
- // Have seen at least one ASCII non-whitespace character
- // on this line.
- MiddleOfLine,
-
- // Handling a preprocessor directive. Passes through all
- // characters up to the end of the line. Disables comment
- // processing.
- InPreprocessorDirective,
-
- // Handling a single-line comment. The comment text is
- // replaced with a single space.
- InSingleLineComment,
-
- // Handling a multi-line comment. Newlines are passed
- // through to preserve line numbers.
- InMultiLineComment
- };
-
- ParseState m_parseState;
- String m_sourceString;
- unsigned m_length;
- unsigned m_position;
- StringBuilder m_builder;
- };
-
- void StripComments::process(UChar c)
- {
- if (isNewline(c)) {
- // No matter what state we are in, pass through newlines
- // so we preserve line numbers.
- emit(c);
-
- if (m_parseState != InMultiLineComment)
- m_parseState = BeginningOfLine;
-
- return;
- }
-
- UChar temp = 0;
- switch (m_parseState) {
- case BeginningOfLine:
- if (WTF::isASCIISpace(c)) {
- emit(c);
- break;
- }
-
- if (c == '#') {
- m_parseState = InPreprocessorDirective;
- emit(c);
- break;
- }
-
- // Transition to normal state and re-handle character.
- m_parseState = MiddleOfLine;
- process(c);
- break;
-
- case MiddleOfLine:
- if (c == '/' && peek(temp)) {
- if (temp == '/') {
- m_parseState = InSingleLineComment;
- emit(' ');
- advance();
- break;
- }
-
- if (temp == '*') {
- m_parseState = InMultiLineComment;
- // Emit the comment start in case the user has
- // an unclosed comment and we want to later
- // signal an error.
- emit('/');
- emit('*');
- advance();
- break;
- }
- }
-
- emit(c);
- break;
-
- case InPreprocessorDirective:
- // No matter what the character is, just pass it
- // through. Do not parse comments in this state. This
- // might not be the right thing to do long term, but it
- // should handle the #error preprocessor directive.
- emit(c);
- break;
-
- case InSingleLineComment:
- // The newline code at the top of this function takes care
- // of resetting our state when we get out of the
- // single-line comment. Swallow all other characters.
- break;
-
- case InMultiLineComment:
- if (c == '*' && peek(temp) && temp == '/') {
- emit('*');
- emit('/');
- m_parseState = MiddleOfLine;
- advance();
- break;
- }
-
- // Swallow all other characters. Unclear whether we may
- // want or need to just emit a space per character to try
- // to preserve column numbers for debugging purposes.
- break;
- }
- }
-
- GraphicsContext3D::Attributes adjustAttributes(const GraphicsContext3D::Attributes& attributes, Settings* settings)
- {
- GraphicsContext3D::Attributes adjustedAttributes = attributes;
- if (adjustedAttributes.antialias) {
- if (settings && !settings->openGLMultisamplingEnabled())
- adjustedAttributes.antialias = false;
- }
-
- return adjustedAttributes;
- }
-} // namespace anonymous
-
-class WebGLRenderingContextLostCallback : public GraphicsContext3D::ContextLostCallback {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_context(cb) { }
- virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
- virtual ~WebGLRenderingContextLostCallback() {}
-private:
- WebGLRenderingContext* m_context;
-};
-
-class WebGLRenderingContextErrorMessageCallback : public GraphicsContext3D::ErrorMessageCallback {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContext* cb) : m_context(cb) { }
- virtual void onErrorMessage(const String& message, GC3Dint)
- {
- if (m_context->m_synthesizedErrorsToConsole)
- m_context->printGLErrorToConsole(message);
- InspectorInstrumentation::didFireWebGLErrorOrWarning(m_context->canvas(), message);
- }
- virtual ~WebGLRenderingContextErrorMessageCallback() { }
-private:
- WebGLRenderingContext* m_context;
-};
-
-PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
+PassOwnPtrWillBeRawPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
{
Document& document = canvas->document();
- Frame* frame = document.frame();
- if (!frame)
+ LocalFrame* frame = document.frame();
+ if (!frame) {
+ canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Web page was not allowed to create a WebGL context."));
return nullptr;
+ }
Settings* settings = frame->settings();
// The FrameLoaderClient might block creation of a new WebGL context despite the page settings; in
@@ -506,29 +78,30 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
return nullptr;
}
- GraphicsContext3D::Attributes requestedAttributes = attrs ? attrs->attributes() : GraphicsContext3D::Attributes();
- requestedAttributes.noExtensions = true;
- requestedAttributes.shareResources = true;
- requestedAttributes.preferDiscreteGPU = true;
- requestedAttributes.topDocumentURL = document.topDocument()->url();
-
- GraphicsContext3D::Attributes attributes = adjustAttributes(requestedAttributes, settings);
-
- RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(attributes));
-
+ // The only situation that attrs is null is through Document::getCSSCanvasContext().
+ RefPtr<WebGLContextAttributes> defaultAttrs;
+ if (!attrs) {
+ defaultAttrs = WebGLContextAttributes::create();
+ attrs = defaultAttrs.get();
+ }
+ blink::WebGraphicsContext3D::Attributes attributes = attrs->attributes(document.topDocument().url().string(), settings);
+ OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes, 0));
if (!context || !context->makeContextCurrent()) {
canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context."));
return nullptr;
}
- Extensions3D* extensions = context->extensions();
- if (extensions->supports("GL_EXT_debug_marker"))
- extensions->pushGroupMarkerEXT("WebGLRenderingContext");
+ OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get());
+ if (!extensionsUtil)
+ return nullptr;
+ if (extensionsUtil->supportsExtension("GL_EXT_debug_marker"))
+ context->pushGroupMarkerEXT("WebGLRenderingContext");
- OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context, attributes, requestedAttributes));
+ OwnPtrWillBeRawPtr<WebGLRenderingContext> renderingContext = adoptPtrWillBeNoop(new WebGLRenderingContext(canvas, context.release(), attrs));
+ renderingContext->registerContextExtensions();
renderingContext->suspendIfNeeded();
- if (renderingContext->m_drawingBuffer->isZeroSized()) {
+ if (!renderingContext->m_drawingBuffer) {
canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context."));
return nullptr;
}
@@ -536,53 +109,25 @@ PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElemen
return renderingContext.release();
}
-WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassRefPtr<GraphicsContext3D> context, GraphicsContext3D::Attributes attributes, GraphicsContext3D::Attributes requestedAttributes)
- : CanvasRenderingContext(passedCanvas)
- , ActiveDOMObject(&passedCanvas->document())
- , m_context(context)
- , m_drawingBuffer(0)
- , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
- , m_restoreAllowed(false)
- , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
- , m_generatedImageCache(4)
- , m_contextLost(false)
- , m_contextLostMode(SyntheticLostContext)
- , m_attributes(attributes)
- , m_requestedAttributes(requestedAttributes)
- , m_synthesizedErrorsToConsole(true)
- , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
- , m_multisamplingAllowed(false)
- , m_multisamplingObserverRegistered(false)
- , m_onePlusMaxEnabledAttribIndex(0)
- , m_onePlusMaxNonDefaultTextureUnit(0)
+WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassOwnPtr<blink::WebGraphicsContext3D> context, WebGLContextAttributes* requestedAttributes)
+ : WebGLRenderingContextBase(passedCanvas, context, requestedAttributes)
{
- ASSERT(m_context);
ScriptWrappable::init(this);
+}
- m_contextGroup = WebGLContextGroup::create();
- m_contextGroup->addContext(this);
-
- m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
- m_context->getIntegerv(GL_MAX_VIEWPORT_DIMS, m_maxViewportDims);
-
- RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
-
- // Create the DrawingBuffer and initialize the platform layer.
- DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawingBuffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
- m_drawingBuffer = DrawingBuffer::create(m_context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release());
+WebGLRenderingContext::~WebGLRenderingContext()
+{
- if (!m_drawingBuffer->isZeroSized()) {
- m_drawingBuffer->bind();
- setupFlags();
- initializeNewContext();
- }
+}
+void WebGLRenderingContext::registerContextExtensions()
+{
// Register extensions.
static const char* const webkitPrefix[] = { "WEBKIT_", 0, };
static const char* const bothPrefixes[] = { "", "WEBKIT_", 0, };
registerExtension<ANGLEInstancedArrays>(m_angleInstancedArrays);
- registerExtension<EXTTextureFilterAnisotropic>(m_extTextureFilterAnisotropic, PrefixedExtension, webkitPrefix);
+ registerExtension<EXTTextureFilterAnisotropic>(m_extTextureFilterAnisotropic, ApprovedExtension, bothPrefixes);
registerExtension<OESElementIndexUint>(m_oesElementIndexUint);
registerExtension<OESStandardDerivatives>(m_oesStandardDerivatives);
registerExtension<OESTextureFloat>(m_oesTextureFloat);
@@ -590,5046 +135,20 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
registerExtension<OESTextureHalfFloat>(m_oesTextureHalfFloat);
registerExtension<OESTextureHalfFloatLinear>(m_oesTextureHalfFloatLinear);
registerExtension<OESVertexArrayObject>(m_oesVertexArrayObject);
- registerExtension<WebGLCompressedTextureATC>(m_webglCompressedTextureATC, PrefixedExtension, webkitPrefix);
- registerExtension<WebGLCompressedTexturePVRTC>(m_webglCompressedTexturePVRTC, PrefixedExtension, webkitPrefix);
- registerExtension<WebGLCompressedTextureS3TC>(m_webglCompressedTextureS3TC, PrefixedExtension, bothPrefixes);
- registerExtension<WebGLDepthTexture>(m_webglDepthTexture, PrefixedExtension, bothPrefixes);
+ registerExtension<WebGLCompressedTextureATC>(m_webglCompressedTextureATC, EnabledDraftExtension, webkitPrefix);
+ registerExtension<WebGLCompressedTexturePVRTC>(m_webglCompressedTexturePVRTC, EnabledDraftExtension, webkitPrefix);
+ registerExtension<WebGLCompressedTextureS3TC>(m_webglCompressedTextureS3TC, ApprovedExtension, bothPrefixes);
+ registerExtension<WebGLDebugRendererInfo>(m_webglDebugRendererInfo);
+ registerExtension<WebGLDebugShaders>(m_webglDebugShaders);
+ registerExtension<WebGLDepthTexture>(m_webglDepthTexture, ApprovedExtension, bothPrefixes);
registerExtension<WebGLDrawBuffers>(m_webglDrawBuffers);
registerExtension<WebGLLoseContext>(m_webglLoseContext, ApprovedExtension, bothPrefixes);
// Register draft extensions.
+ registerExtension<EXTBlendMinMax>(m_extBlendMinMax, DraftExtension);
registerExtension<EXTFragDepth>(m_extFragDepth, DraftExtension);
-
- // Register privileged extensions.
- registerExtension<WebGLDebugRendererInfo>(m_webglDebugRendererInfo, WebGLDebugRendererInfoExtension);
- registerExtension<WebGLDebugShaders>(m_webglDebugShaders, PrivilegedExtension);
-}
-
-void WebGLRenderingContext::initializeNewContext()
-{
- ASSERT(!isContextLost());
- m_needsUpdate = true;
- m_markedCanvasDirty = false;
- m_activeTextureUnit = 0;
- m_packAlignment = 4;
- m_unpackAlignment = 4;
- m_unpackFlipY = false;
- m_unpackPremultiplyAlpha = false;
- m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL;
- m_boundArrayBuffer = 0;
- m_currentProgram = 0;
- m_framebufferBinding = 0;
- m_renderbufferBinding = 0;
- m_depthMask = true;
- m_stencilEnabled = false;
- m_stencilMask = 0xFFFFFFFF;
- m_stencilMaskBack = 0xFFFFFFFF;
- m_stencilFuncRef = 0;
- m_stencilFuncRefBack = 0;
- m_stencilFuncMask = 0xFFFFFFFF;
- m_stencilFuncMaskBack = 0xFFFFFFFF;
- m_layerCleared = false;
- m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
-
- m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
- m_scissorEnabled = false;
- m_clearDepth = 1;
- m_clearStencil = 0;
- m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
-
- GC3Dint numCombinedTextureImageUnits = 0;
- m_context->getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
- m_textureUnits.clear();
- m_textureUnits.resize(numCombinedTextureImageUnits);
-
- GC3Dint numVertexAttribs = 0;
- m_context->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribs);
- m_maxVertexAttribs = numVertexAttribs;
-
- m_maxTextureSize = 0;
- m_context->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
- m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
- m_maxCubeMapTextureSize = 0;
- m_context->getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
- m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
- m_maxRenderbufferSize = 0;
- m_context->getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
-
- // These two values from EXT_draw_buffers are lazily queried.
- m_maxDrawBuffers = 0;
- m_maxColorAttachments = 0;
-
- m_backDrawBuffer = GL_BACK;
-
- m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
- addContextObject(m_defaultVertexArrayObject.get());
- m_boundVertexArrayObject = m_defaultVertexArrayObject;
-
- m_vertexAttribValue.resize(m_maxVertexAttribs);
-
- createFallbackBlackTextures1x1();
-
- IntSize canvasSize = clampedCanvasSize();
- m_drawingBuffer->reset(canvasSize);
-
- m_context->viewport(0, 0, canvasSize.width(), canvasSize.height());
- m_context->scissor(0, 0, canvasSize.width(), canvasSize.height());
-
- m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this)));
- m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMessageCallback(this)));
-
- // This ensures that the context has a valid "lastFlushID" and won't be mistakenly identified as the "least recently used" context.
- m_context->flush();
-
- activateContext(this);
-}
-
-void WebGLRenderingContext::setupFlags()
-{
- ASSERT(m_context);
- if (Page* p = canvas()->document().page()) {
- m_synthesizedErrorsToConsole = p->settings().webGLErrorsToConsoleEnabled();
-
- if (!m_multisamplingObserverRegistered && m_requestedAttributes.antialias) {
- m_multisamplingAllowed = m_drawingBuffer->multisample();
- p->addMultisamplingChangedObserver(this);
- m_multisamplingObserverRegistered = true;
- }
- }
-
- m_isGLES2NPOTStrict = !m_context->extensions()->isEnabled("GL_OES_texture_npot");
- m_isDepthStencilSupported = m_context->extensions()->isEnabled("GL_OES_packed_depth_stencil");
-}
-
-bool WebGLRenderingContext::allowPrivilegedExtensions() const
-{
- if (Page* p = canvas()->document().page())
- return p->settings().privilegedWebGLExtensionsEnabled();
- return false;
-}
-
-bool WebGLRenderingContext::allowWebGLDebugRendererInfo() const
-{
- return true;
-}
-
-void WebGLRenderingContext::addCompressedTextureFormat(GC3Denum format)
-{
- if (!m_compressedTextureFormats.contains(format))
- m_compressedTextureFormats.append(format);
-}
-
-void WebGLRenderingContext::removeAllCompressedTextureFormats()
-{
- m_compressedTextureFormats.clear();
-}
-
-WebGLRenderingContext::~WebGLRenderingContext()
-{
- // Remove all references to WebGLObjects so if they are the last reference
- // they will be freed before the last context is removed from the context group.
- m_boundArrayBuffer = 0;
- m_defaultVertexArrayObject = 0;
- m_boundVertexArrayObject = 0;
- m_vertexAttrib0Buffer = 0;
- m_currentProgram = 0;
- m_framebufferBinding = 0;
- m_renderbufferBinding = 0;
-
- for (size_t i = 0; i < m_textureUnits.size(); ++i) {
- m_textureUnits[i].m_texture2DBinding = 0;
- m_textureUnits[i].m_textureCubeMapBinding = 0;
- }
-
- m_blackTexture2D = 0;
- m_blackTextureCubeMap = 0;
-
- detachAndRemoveAllObjects();
-
- // release all extensions
- for (size_t i = 0; i < m_extensions.size(); ++i)
- delete m_extensions[i];
-
- // Context must be removed from the group prior to the destruction of the
- // GraphicsContext3D, otherwise shared objects may not be properly deleted.
- m_contextGroup->removeContext(this);
-
- destroyGraphicsContext3D();
-
- if (m_multisamplingObserverRegistered) {
- Page* page = canvas()->document().page();
- if (page)
- page->removeMultisamplingChangedObserver(this);
- }
-
- willDestroyContext(this);
-}
-
-void WebGLRenderingContext::destroyGraphicsContext3D()
-{
- m_contextLost = true;
-
- // The drawing buffer holds a context reference. It must also be destroyed
- // in order for the context to be released.
- m_drawingBuffer->releaseResources();
-
- if (m_context) {
- m_context->setContextLostCallback(nullptr);
- m_context->setErrorMessageCallback(nullptr);
- m_context.clear();
- }
-}
-
-void WebGLRenderingContext::markContextChanged()
-{
- if (m_framebufferBinding || isContextLost())
- return;
-
- m_context->markContextChanged();
- m_drawingBuffer->markContentsChanged();
-
- m_layerCleared = false;
- RenderBox* renderBox = canvas()->renderBox();
- if (renderBox && renderBox->hasAcceleratedCompositing()) {
- m_markedCanvasDirty = true;
- canvas()->clearCopiedImage();
- renderBox->contentChanged(CanvasChanged);
- } else {
- if (!m_markedCanvasDirty) {
- m_markedCanvasDirty = true;
- canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
- }
- }
-}
-
-bool WebGLRenderingContext::clearIfComposited(GC3Dbitfield mask)
-{
- if (isContextLost())
- return false;
-
- if (!m_context->layerComposited() || m_layerCleared
- || m_attributes.preserveDrawingBuffer || (mask && m_framebufferBinding))
- return false;
-
- RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
-
- // Determine if it's possible to combine the clear the user asked for and this clear.
- bool combinedClear = mask && !m_scissorEnabled;
-
- m_context->disable(GL_SCISSOR_TEST);
- if (combinedClear && (mask & GL_COLOR_BUFFER_BIT))
- m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
- m_colorMask[1] ? m_clearColor[1] : 0,
- m_colorMask[2] ? m_clearColor[2] : 0,
- m_colorMask[3] ? m_clearColor[3] : 0);
- else
- m_context->clearColor(0, 0, 0, 0);
- m_context->colorMask(true, true, true, true);
- GC3Dbitfield clearMask = GL_COLOR_BUFFER_BIT;
- if (contextAttributes->depth()) {
- if (!combinedClear || !m_depthMask || !(mask & GL_DEPTH_BUFFER_BIT))
- m_context->clearDepth(1.0f);
- clearMask |= GL_DEPTH_BUFFER_BIT;
- m_context->depthMask(true);
- }
- if (contextAttributes->stencil()) {
- if (combinedClear && (mask & GL_STENCIL_BUFFER_BIT))
- m_context->clearStencil(m_clearStencil & m_stencilMask);
- else
- m_context->clearStencil(0);
- clearMask |= GL_STENCIL_BUFFER_BIT;
- m_context->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
- }
-
- m_drawingBuffer->clearFramebuffers(clearMask);
-
- restoreStateAfterClear();
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- m_layerCleared = true;
-
- return combinedClear;
-}
-
-void WebGLRenderingContext::restoreStateAfterClear()
-{
- if (isContextLost())
- return;
-
- // Restore the state that the context set.
- if (m_scissorEnabled)
- m_context->enable(GL_SCISSOR_TEST);
- m_context->clearColor(m_clearColor[0], m_clearColor[1],
- m_clearColor[2], m_clearColor[3]);
- m_context->colorMask(m_colorMask[0], m_colorMask[1],
- m_colorMask[2], m_colorMask[3]);
- m_context->clearDepth(m_clearDepth);
- m_context->clearStencil(m_clearStencil);
- m_context->stencilMaskSeparate(GL_FRONT, m_stencilMask);
- m_context->depthMask(m_depthMask);
-}
-
-void WebGLRenderingContext::markLayerComposited()
-{
- if (!isContextLost())
- m_context->markLayerComposited();
-}
-
-void WebGLRenderingContext::paintRenderingResultsToCanvas()
-{
- if (isContextLost()) {
- canvas()->clearPresentationCopy();
- return;
- }
-
- if (canvas()->document().printing())
- canvas()->clearPresentationCopy();
-
- // Until the canvas is written to by the application, the clear that
- // happened after it was composited should be ignored by the compositor.
- if (m_context->layerComposited() && !m_attributes.preserveDrawingBuffer) {
- m_drawingBuffer->paintCompositedResultsToCanvas(canvas()->buffer());
-
- canvas()->makePresentationCopy();
- } else
- canvas()->clearPresentationCopy();
- clearIfComposited();
-
- if (!m_markedCanvasDirty && !m_layerCleared)
- return;
-
- canvas()->clearCopiedImage();
- m_markedCanvasDirty = false;
-
- m_drawingBuffer->commit();
- if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get())) {
- canvas()->ensureUnacceleratedImageBuffer();
- if (canvas()->hasImageBuffer())
- m_context->paintRenderingResultsToCanvas(canvas()->buffer(), m_drawingBuffer.get());
- }
-
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- else
- m_drawingBuffer->bind();
-}
-
-PassRefPtr<ImageData> WebGLRenderingContext::paintRenderingResultsToImageData()
-{
- if (isContextLost())
- return 0;
-
- clearIfComposited();
- m_drawingBuffer->commit();
- int width, height;
- RefPtr<Uint8ClampedArray> imageDataPixels = m_context->paintRenderingResultsToImageData(m_drawingBuffer.get(), width, height);
- if (!imageDataPixels)
- return 0;
-
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
- else
- m_drawingBuffer->bind();
-
- return ImageData::create(IntSize(width, height), imageDataPixels);
-}
-
-void WebGLRenderingContext::reshape(int width, int height)
-{
- if (isContextLost())
- return;
-
- // This is an approximation because at WebGLRenderingContext level we don't
- // know if the underlying FBO uses textures or renderbuffers.
- GC3Dint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
- // Limit drawing buffer size to 4k to avoid memory exhaustion.
- const int sizeUpperLimit = 4096;
- maxSize = std::min(maxSize, sizeUpperLimit);
- GC3Dint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
- GC3Dint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
- width = clamp(width, 1, maxWidth);
- height = clamp(height, 1, maxHeight);
-
- if (m_needsUpdate) {
- RenderBox* renderBox = canvas()->renderBox();
- if (renderBox && renderBox->hasAcceleratedCompositing())
- renderBox->contentChanged(CanvasChanged);
- m_needsUpdate = false;
- }
-
- // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
- // clear (and this matches what reshape will do).
- m_drawingBuffer->reset(IntSize(width, height));
- restoreStateAfterClear();
-
- m_context->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get()));
- m_context->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
- if (m_framebufferBinding)
- m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
-}
-
-int WebGLRenderingContext::drawingBufferWidth() const
-{
- return m_drawingBuffer->size().width();
-}
-
-int WebGLRenderingContext::drawingBufferHeight() const
-{
- return m_drawingBuffer->size().height();
-}
-
-unsigned int WebGLRenderingContext::sizeInBytes(GC3Denum type)
-{
- switch (type) {
- case GL_BYTE:
- return sizeof(GC3Dbyte);
- case GL_UNSIGNED_BYTE:
- return sizeof(GC3Dubyte);
- case GL_SHORT:
- return sizeof(GC3Dshort);
- case GL_UNSIGNED_SHORT:
- return sizeof(GC3Dushort);
- case GL_INT:
- return sizeof(GC3Dint);
- case GL_UNSIGNED_INT:
- return sizeof(GC3Duint);
- case GL_FLOAT:
- return sizeof(GC3Dfloat);
- }
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-void WebGLRenderingContext::activeTexture(GC3Denum texture)
-{
- if (isContextLost())
- return;
- if (texture - GL_TEXTURE0 >= m_textureUnits.size()) {
- synthesizeGLError(GL_INVALID_ENUM, "activeTexture", "texture unit out of range");
- return;
- }
- m_activeTextureUnit = texture - GL_TEXTURE0;
- m_context->activeTexture(texture);
-
- m_drawingBuffer->setActiveTextureUnit(texture);
-
-}
-
-void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader)
-{
- if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
- return;
- if (!program->attachShader(shader)) {
- synthesizeGLError(GL_INVALID_OPERATION, "attachShader", "shader attachment already has shader");
- return;
- }
- m_context->attachShader(objectOrZero(program), objectOrZero(shader));
- shader->onAttached();
-}
-
-void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name)
-{
- if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
- return;
- if (!validateLocationLength("bindAttribLocation", name))
- return;
- if (!validateString("bindAttribLocation", name))
- return;
- if (isPrefixReserved(name)) {
- synthesizeGLError(GL_INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "bindAttribLocation", "index out of range");
- return;
- }
- m_context->bindAttribLocation(objectOrZero(program), index, name);
-}
-
-bool WebGLRenderingContext::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
-{
- deleted = false;
- if (isContextLost())
- return false;
- if (object) {
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "object not from this context");
- return false;
- }
- deleted = !object->object();
- }
- return true;
-}
-
-void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer)
-{
- bool deleted;
- if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
- return;
- if (deleted)
- buffer = 0;
- if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
- synthesizeGLError(GL_INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
- return;
- }
- if (target == GL_ARRAY_BUFFER)
- m_boundArrayBuffer = buffer;
- else if (target == GL_ELEMENT_ARRAY_BUFFER)
- m_boundVertexArrayObject->setElementArrayBuffer(buffer);
- else {
- synthesizeGLError(GL_INVALID_ENUM, "bindBuffer", "invalid target");
- return;
- }
-
- m_context->bindBuffer(target, objectOrZero(buffer));
- if (buffer)
- buffer->setTarget(target);
-}
-
-void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* buffer)
-{
- bool deleted;
- if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
- return;
- if (deleted)
- buffer = 0;
- if (target != GL_FRAMEBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target");
- return;
- }
- m_framebufferBinding = buffer;
- m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
- if (!m_framebufferBinding) {
- // Instead of binding fb 0, bind the drawing buffer.
- m_drawingBuffer->bind();
- } else
- m_context->bindFramebuffer(target, objectOrZero(buffer));
- if (buffer)
- buffer->setHasEverBeenBound();
- applyStencilTest();
-}
-
-void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer* renderBuffer)
-{
- bool deleted;
- if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
- return;
- if (deleted)
- renderBuffer = 0;
- if (target != GL_RENDERBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "bindRenderbuffer", "invalid target");
- return;
- }
- m_renderbufferBinding = renderBuffer;
- m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
- if (renderBuffer)
- renderBuffer->setHasEverBeenBound();
-}
-
-void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture)
-{
- bool deleted;
- if (!checkObjectToBeBound("bindTexture", texture, deleted))
- return;
- if (deleted)
- texture = 0;
- if (texture && texture->getTarget() && texture->getTarget() != target) {
- synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
- return;
- }
- GC3Dint maxLevel = 0;
- if (target == GL_TEXTURE_2D) {
- m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
- maxLevel = m_maxTextureLevel;
-
- if (!m_activeTextureUnit)
- m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
-
- } else if (target == GL_TEXTURE_CUBE_MAP) {
- m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
- maxLevel = m_maxCubeMapTextureLevel;
- } else {
- synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target");
- return;
- }
-
- m_context->bindTexture(target, objectOrZero(texture));
- if (texture) {
- texture->setTarget(target, maxLevel);
- m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit);
- } else {
- // If the disabled index is the current maximum, trace backwards to find the new max enabled texture index
- if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) {
- findNewMaxNonDefaultTextureUnit();
- }
- }
-
- // Note: previously we used to automatically set the TEXTURE_WRAP_R
- // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
- // ES 2.0 doesn't expose this flag (a bug in the specification) and
- // otherwise the application has no control over the seams in this
- // dimension. However, it appears that supporting this properly on all
- // platforms is fairly involved (will require a HashMap from texture ID
- // in all ports), and we have not had any complaints, so the logic has
- // been removed.
-
-}
-
-void WebGLRenderingContext::blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha)
-{
- if (isContextLost())
- return;
- m_context->blendColor(red, green, blue, alpha);
-}
-
-void WebGLRenderingContext::blendEquation(GC3Denum mode)
-{
- if (isContextLost() || !validateBlendEquation("blendEquation", mode))
- return;
- m_context->blendEquation(mode);
-}
-
-void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
-{
- if (isContextLost() || !validateBlendEquation("blendEquationSeparate", modeRGB) || !validateBlendEquation("blendEquationSeparate", modeAlpha))
- return;
- m_context->blendEquationSeparate(modeRGB, modeAlpha);
-}
-
-
-void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
-{
- if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
- return;
- m_context->blendFunc(sfactor, dfactor);
-}
-
-void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
-{
- // Note: Alpha does not have the same restrictions as RGB.
- if (isContextLost() || !validateBlendFuncFactors("blendFuncSeparate", srcRGB, dstRGB))
- return;
- m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, long long size, GC3Denum usage)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (size < 0) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size < 0");
- return;
- }
- if (!size) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size == 0");
- return;
- }
-
- m_context->bufferData(target, static_cast<GC3Dsizeiptr>(size), usage);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (!data) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
- return;
- }
- m_context->bufferData(target, data->byteLength(), data->data(), usage);
-}
-
-void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
- if (!buffer)
- return;
- if (!data) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
- return;
- }
-
- m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
-}
-
-void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GL_STATIC_DRAW);
- if (!buffer)
- return;
- if (offset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "offset < 0");
- return;
- }
- if (!data)
- return;
-
- m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->data());
-}
-
-void WebGLRenderingContext::bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data)
-{
- if (isContextLost())
- return;
- WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GL_STATIC_DRAW);
- if (!buffer)
- return;
- if (offset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "offset < 0");
- return;
- }
- if (!data)
- return;
-
- m_context->bufferSubData(target, static_cast<GC3Dintptr>(offset), data->byteLength(), data->baseAddress());
-}
-
-GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target)
-{
- if (isContextLost())
- return GL_FRAMEBUFFER_UNSUPPORTED;
- if (target != GL_FRAMEBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid target");
- return 0;
- }
- if (!m_framebufferBinding || !m_framebufferBinding->object())
- return GL_FRAMEBUFFER_COMPLETE;
- const char* reason = "framebuffer incomplete";
- GC3Denum result = m_framebufferBinding->checkStatus(&reason);
- if (result != GL_FRAMEBUFFER_COMPLETE) {
- emitGLWarning("checkFramebufferStatus", reason);
- return result;
- }
- result = m_context->checkFramebufferStatus(target);
- return result;
-}
-
-void WebGLRenderingContext::clear(GC3Dbitfield mask)
-{
- if (isContextLost())
- return;
- if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GL_INVALID_VALUE, "clear", "invalid mask");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
- return;
- }
- if (!clearIfComposited(mask))
- m_context->clear(mask);
- markContextChanged();
-}
-
-void WebGLRenderingContext::clearColor(GC3Dfloat r, GC3Dfloat g, GC3Dfloat b, GC3Dfloat a)
-{
- if (isContextLost())
- return;
- if (std::isnan(r))
- r = 0;
- if (std::isnan(g))
- g = 0;
- if (std::isnan(b))
- b = 0;
- if (std::isnan(a))
- a = 1;
- m_clearColor[0] = r;
- m_clearColor[1] = g;
- m_clearColor[2] = b;
- m_clearColor[3] = a;
- m_context->clearColor(r, g, b, a);
-}
-
-void WebGLRenderingContext::clearDepth(GC3Dfloat depth)
-{
- if (isContextLost())
- return;
- m_clearDepth = depth;
- m_context->clearDepth(depth);
-}
-
-void WebGLRenderingContext::clearStencil(GC3Dint s)
-{
- if (isContextLost())
- return;
- m_clearStencil = s;
- m_context->clearStencil(s);
-}
-
-void WebGLRenderingContext::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha)
-{
- if (isContextLost())
- return;
- m_colorMask[0] = red;
- m_colorMask[1] = green;
- m_colorMask[2] = blue;
- m_colorMask[3] = alpha;
- m_context->colorMask(red, green, blue, alpha);
-}
-
-void WebGLRenderingContext::compileShader(WebGLShader* shader)
-{
- if (isContextLost() || !validateWebGLObject("compileShader", shader))
- return;
- m_context->compileShader(objectOrZero(shader));
-}
-
-void WebGLRenderingContext::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, ArrayBufferView* data)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("compressedTexImage2D", target, level))
- return;
-
- if (!validateCompressedTexFormat(internalformat)) {
- synthesizeGLError(GL_INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
- return;
- }
- if (border) {
- synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0");
- return;
- }
- if (!validateCompressedTexDimensions("compressedTexImage2D", NotTexSubImage2D, target, level, width, height, internalformat))
- return;
- if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
- return;
-
- WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
- if (!tex)
- return;
- if (!isGLES2NPOTStrict()) {
- if (level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
- return;
- }
- }
- graphicsContext3D()->compressedTexImage2D(target, level, internalformat, width, height,
- border, data->byteLength(), data->baseAddress());
- tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
-}
-
-void WebGLRenderingContext::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
- return;
- if (!validateCompressedTexFormat(format)) {
- synthesizeGLError(GL_INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
- return;
- }
- if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
- return;
-
- WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
- if (!tex)
- return;
-
- if (format != tex->getInternalFormat(target, level)) {
- synthesizeGLError(GL_INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
- return;
- }
-
- if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
- return;
-
- graphicsContext3D()->compressedTexSubImage2D(target, level, xoffset, yoffset,
- width, height, format, data->byteLength(), data->baseAddress());
-}
-
-bool WebGLRenderingContext::validateSettableTexFormat(const char* functionName, GC3Denum format)
-{
- if (GraphicsContext3D::getClearBitsByFormat(format) & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "format can not be set, only rendered to");
- return false;
- }
- return true;
-}
-
-void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GL_UNSIGNED_BYTE))
- return;
- if (!validateSettableTexFormat("copyTexImage2D", internalformat))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
- if (!tex)
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
- synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
- return;
- }
- if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
- return;
- }
- clearIfComposited();
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
- // FIXME: if the framebuffer is not complete, none of the below should be executed.
- tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
-}
-
-void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
- return;
- WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
- if (!tex)
- return;
- if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
- return;
- // Before checking if it is in the range, check if overflow happens first.
- Checked<GC3Dint, RecordOverflow> maxX = xoffset;
- maxX += width;
- Checked<GC3Dint, RecordOverflow> maxY = yoffset;
- maxY += height;
-
- if (maxX.hasOverflowed() || maxY.hasOverflowed()) {
- synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
- return;
- }
- if (maxX.unsafeGet() > tex->getWidth(target, level) || maxY.unsafeGet() > tex->getHeight(target, level)) {
- synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
- return;
- }
- GC3Denum internalformat = tex->getInternalFormat(target, level);
- if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
- return;
- if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
- synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
- return;
- }
- clearIfComposited();
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
-}
-
-PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
- addContextObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLTexture> o = WebGLTexture::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLProgram> o = WebGLProgram::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
-{
- if (isContextLost())
- return 0;
- RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
- addSharedObject(o.get());
- return o;
-}
-
-WebGLRenderbuffer* WebGLRenderingContext::ensureEmulatedStencilBuffer(GC3Denum target, WebGLRenderbuffer* renderbuffer)
-{
- if (isContextLost())
- return 0;
- if (!renderbuffer->emulatedStencilBuffer()) {
- renderbuffer->setEmulatedStencilBuffer(createRenderbuffer());
- m_context->bindRenderbuffer(target, objectOrZero(renderbuffer->emulatedStencilBuffer()));
- m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
- }
- return renderbuffer->emulatedStencilBuffer();
-}
-
-PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(GC3Denum type)
-{
- if (isContextLost())
- return 0;
- if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) {
- synthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type");
- return 0;
- }
-
- RefPtr<WebGLShader> o = WebGLShader::create(this, type);
- addSharedObject(o.get());
- return o;
-}
-
-void WebGLRenderingContext::cullFace(GC3Denum mode)
-{
- if (isContextLost())
- return;
- switch (mode) {
- case GL_FRONT_AND_BACK:
- case GL_FRONT:
- case GL_BACK:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "cullFace", "invalid mode");
- return;
- }
- m_context->cullFace(mode);
-}
-
-bool WebGLRenderingContext::deleteObject(WebGLObject* object)
-{
- if (isContextLost() || !object)
- return false;
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, "delete", "object does not belong to this context");
- return false;
- }
- if (object->object())
- // We need to pass in context here because we want
- // things in this context unbound.
- object->deleteObject(graphicsContext3D());
- return true;
-}
-
-void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
-{
- if (!deleteObject(buffer))
- return;
- if (m_boundArrayBuffer == buffer)
- m_boundArrayBuffer = 0;
-
- m_boundVertexArrayObject->unbindBuffer(buffer);
-}
-
-void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
-{
- if (!deleteObject(framebuffer))
- return;
- if (framebuffer == m_framebufferBinding) {
- m_framebufferBinding = 0;
- m_drawingBuffer->setFramebufferBinding(0);
- // Have to call bindFramebuffer here to bind back to internal fbo.
- m_drawingBuffer->bind();
- }
-}
-
-void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
-{
- deleteObject(program);
- // We don't reset m_currentProgram to 0 here because the deletion of the
- // current program is delayed.
-}
-
-void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
- if (!deleteObject(renderbuffer))
- return;
- if (renderbuffer == m_renderbufferBinding)
- m_renderbufferBinding = 0;
- if (m_framebufferBinding)
- m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
-}
-
-void WebGLRenderingContext::deleteShader(WebGLShader* shader)
-{
- deleteObject(shader);
-}
-
-void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
-{
- if (!deleteObject(texture))
- return;
-
- int maxBoundTextureIndex = -1;
- for (size_t i = 0; i < m_onePlusMaxNonDefaultTextureUnit; ++i) {
- if (texture == m_textureUnits[i].m_texture2DBinding) {
- m_textureUnits[i].m_texture2DBinding = 0;
- maxBoundTextureIndex = i;
- if (!i)
- m_drawingBuffer->setTexture2DBinding(0);
- }
- if (texture == m_textureUnits[i].m_textureCubeMapBinding) {
- m_textureUnits[i].m_textureCubeMapBinding = 0;
- maxBoundTextureIndex = i;
- }
- }
- if (m_framebufferBinding)
- m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
-
- // If the deleted was bound to the the current maximum index, trace backwards to find the new max texture index
- if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBoundTextureIndex + 1)) {
- findNewMaxNonDefaultTextureUnit();
- }
-}
-
-void WebGLRenderingContext::depthFunc(GC3Denum func)
-{
- if (isContextLost())
- return;
- if (!validateStencilOrDepthFunc("depthFunc", func))
- return;
- m_context->depthFunc(func);
-}
-
-void WebGLRenderingContext::depthMask(GC3Dboolean flag)
-{
- if (isContextLost())
- return;
- m_depthMask = flag;
- m_context->depthMask(flag);
-}
-
-void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
-{
- if (isContextLost())
- return;
- if (zNear > zFar) {
- synthesizeGLError(GL_INVALID_OPERATION, "depthRange", "zNear > zFar");
- return;
- }
- m_context->depthRange(zNear, zFar);
-}
-
-void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader)
-{
- if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
- return;
- if (!program->detachShader(shader)) {
- synthesizeGLError(GL_INVALID_OPERATION, "detachShader", "shader not attached");
- return;
- }
- m_context->detachShader(objectOrZero(program), objectOrZero(shader));
- shader->onDetached(graphicsContext3D());
-}
-
-void WebGLRenderingContext::disable(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("disable", cap))
- return;
- if (cap == GL_STENCIL_TEST) {
- m_stencilEnabled = false;
- applyStencilTest();
- return;
- }
- if (cap == GL_SCISSOR_TEST) {
- m_scissorEnabled = false;
- m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
- }
- m_context->disable(cap);
-}
-
-void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index)
-{
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "disableVertexAttribArray", "index out of range");
- return;
- }
-
- WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
- state.enabled = false;
-
- // If the disabled index is the current maximum, trace backwards to find the new max enabled attrib index
- if (m_onePlusMaxEnabledAttribIndex == index + 1) {
- findNewMaxEnabledAttribIndex();
- }
-
- m_context->disableVertexAttribArray(index);
-}
-
-bool WebGLRenderingContext::validateRenderingState()
-{
- if (!m_currentProgram)
- return false;
-
- // Look in each enabled vertex attrib and check if they've been bound to a buffer.
- for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
- if (state.enabled
- && (!state.bufferBinding || !state.bufferBinding->object()))
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateWebGLObject(const char* functionName, WebGLObject* object)
-{
- if (!object || !object->object()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no object or object deleted");
- return false;
- }
- if (!object->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "object does not belong to this context");
- return false;
- }
- return true;
-}
-
-void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count)
-{
- if (!validateDrawArrays("drawArrays", mode, first, count))
- return;
-
- clearIfComposited();
-
- handleTextureCompleteness("drawArrays", true);
- m_context->drawArrays(mode, first, count);
- handleTextureCompleteness("drawArrays", false);
- markContextChanged();
-}
-
-void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset)
-{
- if (!validateDrawElements("drawElements", mode, count, type, offset))
- return;
-
- clearIfComposited();
-
- handleTextureCompleteness("drawElements", true);
- m_context->drawElements(mode, count, type, static_cast<GC3Dintptr>(offset));
- handleTextureCompleteness("drawElements", false);
- markContextChanged();
-}
-
-void WebGLRenderingContext::drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount)
-{
- if (!validateDrawArrays("drawArraysInstancedANGLE", mode, first, count))
- return;
-
- if (!validateDrawInstanced("drawArraysInstancedANGLE", primcount))
- return;
-
- clearIfComposited();
-
- handleTextureCompleteness("drawArraysInstancedANGLE", true);
- m_context->extensions()->drawArraysInstancedANGLE(mode, first, count, primcount);
- handleTextureCompleteness("drawArraysInstancedANGLE", false);
- markContextChanged();
-}
-
-void WebGLRenderingContext::drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount)
-{
- if (!validateDrawElements("drawElementsInstancedANGLE", mode, count, type, offset))
- return;
-
- if (!validateDrawInstanced("drawElementsInstancedANGLE", primcount))
- return;
-
- clearIfComposited();
-
- handleTextureCompleteness("drawElementsInstancedANGLE", true);
- m_context->extensions()->drawElementsInstancedANGLE(mode, count, type, static_cast<GC3Dintptr>(offset), primcount);
- handleTextureCompleteness("drawElementsInstancedANGLE", false);
- markContextChanged();
-}
-
-void WebGLRenderingContext::enable(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("enable", cap))
- return;
- if (cap == GL_STENCIL_TEST) {
- m_stencilEnabled = true;
- applyStencilTest();
- return;
- }
- if (cap == GL_SCISSOR_TEST) {
- m_scissorEnabled = true;
- m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
- }
- m_context->enable(cap);
-}
-
-void WebGLRenderingContext::enableVertexAttribArray(GC3Duint index)
-{
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "enableVertexAttribArray", "index out of range");
- return;
- }
-
- WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
- state.enabled = true;
-
- m_onePlusMaxEnabledAttribIndex = max(index + 1, m_onePlusMaxEnabledAttribIndex);
-
- m_context->enableVertexAttribArray(index);
-}
-
-void WebGLRenderingContext::finish()
-{
- if (isContextLost())
- return;
- m_context->flush(); // Intentionally a flush, not a finish.
-}
-
-void WebGLRenderingContext::flush()
-{
- if (isContextLost())
- return;
- m_context->flush();
-}
-
-void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer)
-{
- if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
- return;
- if (renderbuffertarget != GL_RENDERBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
- return;
- }
- if (buffer && !buffer->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
- return;
- }
- // Don't allow the default framebuffer to be mutated; all current
- // implementations use an FBO internally in place of the default
- // FBO.
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
- return;
- }
- Platform3DObject bufferObject = objectOrZero(buffer);
- switch (attachment) {
- case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
- if (isDepthStencilSupported() || !buffer) {
- m_context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
- m_context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
- } else {
- WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(renderbuffertarget, buffer);
- if (!emulatedStencilBuffer) {
- synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", "out of memory");
- return;
- }
- m_context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
- m_context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer));
- }
- break;
- default:
- m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
- }
- m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
- applyStencilTest();
-}
-
-void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level)
-{
- if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
- return;
- if (level) {
- synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0");
- return;
- }
- if (texture && !texture->validate(contextGroup(), this)) {
- synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
- return;
- }
- // Don't allow the default framebuffer to be mutated; all current
- // implementations use an FBO internally in place of the default
- // FBO.
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
- return;
- }
- Platform3DObject textureObject = objectOrZero(texture);
- switch (attachment) {
- case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
- m_context->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget, textureObject, level);
- m_context->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, textureObject, level);
- break;
- case GL_DEPTH_ATTACHMENT:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- break;
- case GL_STENCIL_ATTACHMENT:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- break;
- default:
- m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
- }
- m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
- applyStencilTest();
-}
-
-void WebGLRenderingContext::frontFace(GC3Denum mode)
-{
- if (isContextLost())
- return;
- switch (mode) {
- case GL_CW:
- case GL_CCW:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "frontFace", "invalid mode");
- return;
- }
- m_context->frontFace(mode);
-}
-
-void WebGLRenderingContext::generateMipmap(GC3Denum target)
-{
- if (isContextLost())
- return;
- WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
- if (!tex)
- return;
- if (!tex->canGenerateMipmaps()) {
- synthesizeGLError(GL_INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
- return;
- }
- if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
- return;
-
- // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
- // on Mac. Remove the hack once this driver bug is fixed.
-#if OS(MACOSX)
- bool needToResetMinFilter = false;
- if (tex->getMinFilter() != GL_NEAREST_MIPMAP_LINEAR) {
- m_context->texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
- needToResetMinFilter = true;
- }
-#endif
- m_context->generateMipmap(target);
-#if OS(MACOSX)
- if (needToResetMinFilter)
- m_context->texParameteri(target, GL_TEXTURE_MIN_FILTER, tex->getMinFilter());
-#endif
- tex->generateMipmapLevelInfo();
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, GC3Duint index)
-{
- if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
- return 0;
- ActiveInfo info;
- if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
- return 0;
- return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, GC3Duint index)
-{
- if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
- return 0;
- ActiveInfo info;
- if (!m_context->getActiveUniform(objectOrZero(program), index, info))
- return 0;
- return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader> >& shaderObjects)
-{
- shaderObjects.clear();
- if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
- return false;
-
- const GC3Denum shaderType[] = {
- GL_VERTEX_SHADER,
- GL_FRAGMENT_SHADER
- };
- for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GC3Denum); ++i) {
- WebGLShader* shader = program->getAttachedShader(shaderType[i]);
- if (shader)
- shaderObjects.append(shader);
- }
- return true;
-}
-
-GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
-{
- if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
- return -1;
- if (!validateLocationLength("getAttribLocation", name))
- return -1;
- if (!validateString("getAttribLocation", name))
- return -1;
- if (isPrefixReserved(name))
- return -1;
- if (!program->linkStatus()) {
- synthesizeGLError(GL_INVALID_OPERATION, "getAttribLocation", "program not linked");
- return 0;
- }
- return m_context->getAttribLocation(objectOrZero(program), name);
-}
-
-WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- if (target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid target");
- return WebGLGetInfo();
- }
-
- if (pname != GL_BUFFER_SIZE && pname != GL_BUFFER_USAGE) {
- synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-
- GC3Dint value = 0;
- m_context->getBufferParameteriv(target, pname, &value);
- if (pname == GL_BUFFER_SIZE)
- return WebGLGetInfo(value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
-}
-
-PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
-{
- if (isContextLost())
- return 0;
- // We always need to return a new WebGLContextAttributes object to
- // prevent the user from mutating any cached version.
-
- // Also, we need to enforce requested values of "false" for depth
- // and stencil, regardless of the properties of the underlying
- // GraphicsContext3D or DrawingBuffer.
- RefPtr<WebGLContextAttributes> attributes = WebGLContextAttributes::create(m_context->getContextAttributes());
- if (!m_attributes.depth)
- attributes->setDepth(false);
- if (!m_attributes.stencil)
- attributes->setStencil(false);
- // The DrawingBuffer obtains its parameters from GraphicsContext3D::getContextAttributes(),
- // but it makes its own determination of whether multisampling is supported.
- attributes->setAntialias(m_drawingBuffer->multisample());
- return attributes.release();
-}
-
-GC3Denum WebGLRenderingContext::getError()
-{
- if (lost_context_errors_.size()) {
- GC3Denum err = lost_context_errors_.first();
- lost_context_errors_.remove(0);
- return err;
- }
-
- if (isContextLost())
- return GL_NO_ERROR;
-
- return m_context->getError();
-}
-
-bool WebGLRenderingContext::ExtensionTracker::matchesNameWithPrefixes(const String& name) const
-{
- static const char* const unprefixed[] = { "", 0, };
-
- const char* const* prefixes = m_prefixes ? m_prefixes : unprefixed;
- for (; *prefixes; ++prefixes) {
- String prefixedName = String(*prefixes) + extensionName();
- if (equalIgnoringCase(prefixedName, name)) {
- return true;
- }
- }
- return false;
-}
-
-PassRefPtr<WebGLExtension> WebGLRenderingContext::getExtension(const String& name)
-{
- if (isContextLost())
- return 0;
-
- for (size_t i = 0; i < m_extensions.size(); ++i) {
- ExtensionTracker* tracker = m_extensions[i];
- if (tracker->matchesNameWithPrefixes(name)) {
- if (tracker->webglDebugRendererInfo() && !allowWebGLDebugRendererInfo())
- return 0;
- if (tracker->privileged() && !allowPrivilegedExtensions())
- return 0;
- if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
- return 0;
- if (!tracker->supported(this))
- return 0;
- return tracker->getExtension(this);
- }
- }
-
- return 0;
-}
-
-WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname)
-{
- if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
- return WebGLGetInfo();
-
- if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
- return WebGLGetInfo();
- }
-
- WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
- if (!object) {
- if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
- return WebGLGetInfo(GL_NONE);
- // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
- // specifies INVALID_OPERATION.
- synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-
- ASSERT(object->isTexture() || object->isRenderbuffer());
- if (object->isTexture()) {
- switch (pname) {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GL_TEXTURE);
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(static_cast<WebGLTexture*>(object)));
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
- case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
- {
- GC3Dint value = 0;
- m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
- return WebGLGetInfo(value);
- }
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
- return WebGLGetInfo();
- }
- } else {
- switch (pname) {
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
- return WebGLGetInfo(GL_RENDERBUFFER);
- case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(static_cast<WebGLRenderbuffer*>(object)));
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
- return WebGLGetInfo();
- }
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- const int intZero = 0;
- switch (pname) {
- case GL_ACTIVE_TEXTURE:
- return getUnsignedIntParameter(pname);
- case GL_ALIASED_LINE_WIDTH_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GL_ALIASED_POINT_SIZE_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GL_ALPHA_BITS:
- return getIntParameter(pname);
- case GL_ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
- case GL_BLEND:
- return getBooleanParameter(pname);
- case GL_BLEND_COLOR:
- return getWebGLFloatArrayParameter(pname);
- case GL_BLEND_DST_ALPHA:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_DST_RGB:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_EQUATION_ALPHA:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_EQUATION_RGB:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_SRC_ALPHA:
- return getUnsignedIntParameter(pname);
- case GL_BLEND_SRC_RGB:
- return getUnsignedIntParameter(pname);
- case GL_BLUE_BITS:
- return getIntParameter(pname);
- case GL_COLOR_CLEAR_VALUE:
- return getWebGLFloatArrayParameter(pname);
- case GL_COLOR_WRITEMASK:
- return getBooleanArrayParameter(pname);
- case GL_COMPRESSED_TEXTURE_FORMATS:
- return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()));
- case GL_CULL_FACE:
- return getBooleanParameter(pname);
- case GL_CULL_FACE_MODE:
- return getUnsignedIntParameter(pname);
- case GL_CURRENT_PROGRAM:
- return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
- case GL_DEPTH_BITS:
- if (!m_framebufferBinding && !m_attributes.depth)
- return WebGLGetInfo(intZero);
- return getIntParameter(pname);
- case GL_DEPTH_CLEAR_VALUE:
- return getFloatParameter(pname);
- case GL_DEPTH_FUNC:
- return getUnsignedIntParameter(pname);
- case GL_DEPTH_RANGE:
- return getWebGLFloatArrayParameter(pname);
- case GL_DEPTH_TEST:
- return getBooleanParameter(pname);
- case GL_DEPTH_WRITEMASK:
- return getBooleanParameter(pname);
- case GL_DITHER:
- return getBooleanParameter(pname);
- case GL_ELEMENT_ARRAY_BUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->boundElementArrayBuffer()));
- case GL_FRAMEBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
- case GL_FRONT_FACE:
- return getUnsignedIntParameter(pname);
- case GL_GENERATE_MIPMAP_HINT:
- return getUnsignedIntParameter(pname);
- case GL_GREEN_BITS:
- return getIntParameter(pname);
- case GL_LINE_WIDTH:
- return getFloatParameter(pname);
- case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
- return getIntParameter(pname);
- case GL_MAX_RENDERBUFFER_SIZE:
- return getIntParameter(pname);
- case GL_MAX_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GL_MAX_TEXTURE_SIZE:
- return getIntParameter(pname);
- case GL_MAX_VARYING_VECTORS:
- return getIntParameter(pname);
- case GL_MAX_VERTEX_ATTRIBS:
- return getIntParameter(pname);
- case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
- return getIntParameter(pname);
- case GL_MAX_VERTEX_UNIFORM_VECTORS:
- return getIntParameter(pname);
- case GL_MAX_VIEWPORT_DIMS:
- return getWebGLIntArrayParameter(pname);
- case GL_NUM_SHADER_BINARY_FORMATS:
- // FIXME: should we always return 0 for this?
- return getIntParameter(pname);
- case GL_PACK_ALIGNMENT:
- return getIntParameter(pname);
- case GL_POLYGON_OFFSET_FACTOR:
- return getFloatParameter(pname);
- case GL_POLYGON_OFFSET_FILL:
- return getBooleanParameter(pname);
- case GL_POLYGON_OFFSET_UNITS:
- return getFloatParameter(pname);
- case GL_RED_BITS:
- return getIntParameter(pname);
- case GL_RENDERBUFFER_BINDING:
- return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
- case GL_RENDERER:
- return WebGLGetInfo(String("WebKit WebGL"));
- case GL_SAMPLE_BUFFERS:
- return getIntParameter(pname);
- case GL_SAMPLE_COVERAGE_INVERT:
- return getBooleanParameter(pname);
- case GL_SAMPLE_COVERAGE_VALUE:
- return getFloatParameter(pname);
- case GL_SAMPLES:
- return getIntParameter(pname);
- case GL_SCISSOR_BOX:
- return getWebGLIntArrayParameter(pname);
- case GL_SCISSOR_TEST:
- return getBooleanParameter(pname);
- case GL_SHADING_LANGUAGE_VERSION:
- return WebGLGetInfo("WebGL GLSL ES 1.0 (" + m_context->getString(GL_SHADING_LANGUAGE_VERSION) + ")");
- case GL_STENCIL_BACK_FAIL:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_FUNC:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_PASS_DEPTH_PASS:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_REF:
- return getIntParameter(pname);
- case GL_STENCIL_BACK_VALUE_MASK:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BACK_WRITEMASK:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_BITS:
- if (!m_framebufferBinding && !m_attributes.stencil)
- return WebGLGetInfo(intZero);
- return getIntParameter(pname);
- case GL_STENCIL_CLEAR_VALUE:
- return getIntParameter(pname);
- case GL_STENCIL_FAIL:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_FUNC:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_PASS_DEPTH_FAIL:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_PASS_DEPTH_PASS:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_REF:
- return getIntParameter(pname);
- case GL_STENCIL_TEST:
- return getBooleanParameter(pname);
- case GL_STENCIL_VALUE_MASK:
- return getUnsignedIntParameter(pname);
- case GL_STENCIL_WRITEMASK:
- return getUnsignedIntParameter(pname);
- case GL_SUBPIXEL_BITS:
- return getIntParameter(pname);
- case GL_TEXTURE_BINDING_2D:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
- case GL_TEXTURE_BINDING_CUBE_MAP:
- return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
- case GL_UNPACK_ALIGNMENT:
- return getIntParameter(pname);
- case GC3D_UNPACK_FLIP_Y_WEBGL:
- return WebGLGetInfo(m_unpackFlipY);
- case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- return WebGLGetInfo(m_unpackPremultiplyAlpha);
- case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
- return WebGLGetInfo(m_unpackColorspaceConversion);
- case GL_VENDOR:
- return WebGLGetInfo(String("WebKit"));
- case GL_VERSION:
- return WebGLGetInfo("WebGL 1.0 (" + m_context->getString(GL_VERSION) + ")");
- case GL_VIEWPORT:
- return getWebGLIntArrayParameter(pname);
- case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
- if (m_oesStandardDerivatives)
- return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
- return WebGLGetInfo();
- case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
- if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GL_RENDERER));
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
- case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
- if (m_webglDebugRendererInfo)
- return WebGLGetInfo(m_context->getString(GL_VENDOR));
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
- return WebGLGetInfo();
- case Extensions3D::VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
- if (m_oesVertexArrayObject) {
- if (!m_boundVertexArrayObject->isDefaultObject())
- return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
- return WebGLGetInfo();
- }
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (m_extTextureFilterAnisotropic)
- return getUnsignedIntParameter(Extensions3D::MAX_TEXTURE_MAX_ANISOTROPY_EXT);
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
- if (m_webglDrawBuffers)
- return WebGLGetInfo(maxColorAttachments());
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
- return WebGLGetInfo();
- case Extensions3D::MAX_DRAW_BUFFERS_EXT:
- if (m_webglDrawBuffers)
- return WebGLGetInfo(maxDrawBuffers());
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
- return WebGLGetInfo();
- default:
- if (m_webglDrawBuffers
- && pname >= Extensions3D::DRAW_BUFFER0_EXT
- && pname < static_cast<GC3Denum>(Extensions3D::DRAW_BUFFER0_EXT + maxDrawBuffers())) {
- GC3Dint value = GL_NONE;
- if (m_framebufferBinding)
- value = m_framebufferBinding->getDrawBuffer(pname);
- else // emulated backbuffer
- value = m_backDrawBuffer;
- return WebGLGetInfo(value);
- }
- synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GC3Denum pname)
-{
- if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
- return WebGLGetInfo();
-
- GC3Dint value = 0;
- switch (pname) {
- case GL_DELETE_STATUS:
- return WebGLGetInfo(program->isDeleted());
- case GL_VALIDATE_STATUS:
- m_context->getProgramiv(objectOrZero(program), pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
- case GL_LINK_STATUS:
- return WebGLGetInfo(program->linkStatus());
- case GL_ATTACHED_SHADERS:
- case GL_ACTIVE_ATTRIBUTES:
- case GL_ACTIVE_UNIFORMS:
- m_context->getProgramiv(objectOrZero(program), pname, &value);
- return WebGLGetInfo(value);
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program)
-{
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getProgramInfoLog", program))
- return "";
- return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
-}
-
-WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- if (target != GL_RENDERBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid target");
- return WebGLGetInfo();
- }
- if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
- return WebGLGetInfo();
- }
-
- GC3Dint value = 0;
- switch (pname) {
- case GL_RENDERBUFFER_WIDTH:
- case GL_RENDERBUFFER_HEIGHT:
- case GL_RENDERBUFFER_RED_SIZE:
- case GL_RENDERBUFFER_GREEN_SIZE:
- case GL_RENDERBUFFER_BLUE_SIZE:
- case GL_RENDERBUFFER_ALPHA_SIZE:
- case GL_RENDERBUFFER_DEPTH_SIZE:
- m_context->getRenderbufferParameteriv(target, pname, &value);
- return WebGLGetInfo(value);
- case GL_RENDERBUFFER_STENCIL_SIZE:
- if (m_renderbufferBinding->emulatedStencilBuffer()) {
- m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding->emulatedStencilBuffer()));
- m_context->getRenderbufferParameteriv(target, pname, &value);
- m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
- } else {
- m_context->getRenderbufferParameteriv(target, pname, &value);
- }
- return WebGLGetInfo(value);
- case GL_RENDERBUFFER_INTERNAL_FORMAT:
- return WebGLGetInfo(m_renderbufferBinding->internalFormat());
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3Denum pname)
-{
- if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
- return WebGLGetInfo();
- GC3Dint value = 0;
- switch (pname) {
- case GL_DELETE_STATUS:
- return WebGLGetInfo(shader->isDeleted());
- case GL_COMPILE_STATUS:
- m_context->getShaderiv(objectOrZero(shader), pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
- case GL_SHADER_TYPE:
- m_context->getShaderiv(objectOrZero(shader), pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader)
-{
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getShaderInfoLog", shader))
- return "";
- return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
-}
-
-PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContext::getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType)
-{
- if (isContextLost())
- return 0;
- switch (shaderType) {
- case GL_VERTEX_SHADER:
- case GL_FRAGMENT_SHADER:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
- return 0;
- }
- switch (precisionType) {
- case GL_LOW_FLOAT:
- case GL_MEDIUM_FLOAT:
- case GL_HIGH_FLOAT:
- case GL_LOW_INT:
- case GL_MEDIUM_INT:
- case GL_HIGH_INT:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
- return 0;
- }
-
- GC3Dint range[2] = {0, 0};
- GC3Dint precision = 0;
- m_context->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
- return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
-}
-
-String WebGLRenderingContext::getShaderSource(WebGLShader* shader)
-{
- if (isContextLost())
- return String();
- if (!validateWebGLObject("getShaderSource", shader))
- return "";
- return ensureNotNull(shader->source());
-}
-
-Vector<String> WebGLRenderingContext::getSupportedExtensions()
-{
- Vector<String> result;
- if (isContextLost())
- return result;
-
- for (size_t i = 0; i < m_extensions.size(); ++i) {
- ExtensionTracker* tracker = m_extensions[i];
- if (tracker->webglDebugRendererInfo() && !allowWebGLDebugRendererInfo())
- continue;
- if (tracker->privileged() && !allowPrivilegedExtensions())
- continue;
- if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
- continue;
- if (tracker->supported(this))
- result.append(String(tracker->prefixed() ? "WEBKIT_" : "") + tracker->extensionName());
- }
-
- return result;
-}
-
-WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
- if (!tex)
- return WebGLGetInfo();
- GC3Dint value = 0;
- switch (pname) {
- case GL_TEXTURE_MAG_FILTER:
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- m_context->getTexParameteriv(target, pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (m_extTextureFilterAnisotropic) {
- m_context->getTexParameteriv(target, pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
- }
- synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
- return WebGLGetInfo();
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation)
-{
- if (isContextLost() || !validateWebGLObject("getUniform", program))
- return WebGLGetInfo();
- if (!uniformLocation || uniformLocation->program() != program) {
- synthesizeGLError(GL_INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
- return WebGLGetInfo();
- }
- GC3Dint location = uniformLocation->location();
-
- // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
- GC3Dint activeUniforms = 0;
- m_context->getProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORMS, &activeUniforms);
- for (GC3Dint i = 0; i < activeUniforms; i++) {
- ActiveInfo info;
- if (!m_context->getActiveUniform(objectOrZero(program), i, info))
- return WebGLGetInfo();
- // Strip "[0]" from the name if it's an array.
- if (info.size > 1 && info.name.endsWith("[0]"))
- info.name = info.name.left(info.name.length() - 3);
- // If it's an array, we need to iterate through each element, appending "[index]" to the name.
- for (GC3Dint index = 0; index < info.size; ++index) {
- String name = info.name;
- if (info.size > 1 && index >= 1) {
- name.append('[');
- name.append(String::number(index));
- name.append(']');
- }
- // Now need to look this up by name again to find its location
- GC3Dint loc = m_context->getUniformLocation(objectOrZero(program), name);
- if (loc == location) {
- // Found it. Use the type in the ActiveInfo to determine the return type.
- GC3Denum baseType;
- unsigned int length;
- switch (info.type) {
- case GL_BOOL:
- baseType = GL_BOOL;
- length = 1;
- break;
- case GL_BOOL_VEC2:
- baseType = GL_BOOL;
- length = 2;
- break;
- case GL_BOOL_VEC3:
- baseType = GL_BOOL;
- length = 3;
- break;
- case GL_BOOL_VEC4:
- baseType = GL_BOOL;
- length = 4;
- break;
- case GL_INT:
- baseType = GL_INT;
- length = 1;
- break;
- case GL_INT_VEC2:
- baseType = GL_INT;
- length = 2;
- break;
- case GL_INT_VEC3:
- baseType = GL_INT;
- length = 3;
- break;
- case GL_INT_VEC4:
- baseType = GL_INT;
- length = 4;
- break;
- case GL_FLOAT:
- baseType = GL_FLOAT;
- length = 1;
- break;
- case GL_FLOAT_VEC2:
- baseType = GL_FLOAT;
- length = 2;
- break;
- case GL_FLOAT_VEC3:
- baseType = GL_FLOAT;
- length = 3;
- break;
- case GL_FLOAT_VEC4:
- baseType = GL_FLOAT;
- length = 4;
- break;
- case GL_FLOAT_MAT2:
- baseType = GL_FLOAT;
- length = 4;
- break;
- case GL_FLOAT_MAT3:
- baseType = GL_FLOAT;
- length = 9;
- break;
- case GL_FLOAT_MAT4:
- baseType = GL_FLOAT;
- length = 16;
- break;
- case GL_SAMPLER_2D:
- case GL_SAMPLER_CUBE:
- baseType = GL_INT;
- length = 1;
- break;
- default:
- // Can't handle this type
- synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type");
- return WebGLGetInfo();
- }
- switch (baseType) {
- case GL_FLOAT: {
- GC3Dfloat value[16] = {0};
- m_context->getUniformfv(objectOrZero(program), location, value);
- if (length == 1)
- return WebGLGetInfo(value[0]);
- return WebGLGetInfo(Float32Array::create(value, length));
- }
- case GL_INT: {
- GC3Dint value[4] = {0};
- m_context->getUniformiv(objectOrZero(program), location, value);
- if (length == 1)
- return WebGLGetInfo(value[0]);
- return WebGLGetInfo(Int32Array::create(value, length));
- }
- case GL_BOOL: {
- GC3Dint value[4] = {0};
- m_context->getUniformiv(objectOrZero(program), location, value);
- if (length > 1) {
- bool boolValue[16] = {0};
- for (unsigned j = 0; j < length; j++)
- boolValue[j] = static_cast<bool>(value[j]);
- return WebGLGetInfo(boolValue, length);
- }
- return WebGLGetInfo(static_cast<bool>(value[0]));
- }
- default:
- notImplemented();
- }
- }
- }
- }
- // If we get here, something went wrong in our unfortunately complex logic above
- synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error");
- return WebGLGetInfo();
-}
-
-PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name)
-{
- if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
- return 0;
- if (!validateLocationLength("getUniformLocation", name))
- return 0;
- if (!validateString("getUniformLocation", name))
- return 0;
- if (isPrefixReserved(name))
- return 0;
- if (!program->linkStatus()) {
- synthesizeGLError(GL_INVALID_OPERATION, "getUniformLocation", "program not linked");
- return 0;
- }
- GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
- if (uniformLocation == -1)
- return 0;
- return WebGLUniformLocation::create(program, uniformLocation);
-}
-
-WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pname)
-{
- if (isContextLost())
- return WebGLGetInfo();
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range");
- return WebGLGetInfo();
- }
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
-
- if (m_angleInstancedArrays && pname == Extensions3D::VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
- return WebGLGetInfo(state.divisor);
-
- switch (pname) {
- case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- if (!state.bufferBinding || !state.bufferBinding->object())
- return WebGLGetInfo();
- return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
- case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
- return WebGLGetInfo(state.enabled);
- case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
- return WebGLGetInfo(state.normalized);
- case GL_VERTEX_ATTRIB_ARRAY_SIZE:
- return WebGLGetInfo(state.size);
- case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
- return WebGLGetInfo(state.originalStride);
- case GL_VERTEX_ATTRIB_ARRAY_TYPE:
- return WebGLGetInfo(state.type);
- case GL_CURRENT_VERTEX_ATTRIB:
- return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
- default:
- synthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
- return WebGLGetInfo();
- }
-}
-
-long long WebGLRenderingContext::getVertexAttribOffset(GC3Duint index, GC3Denum pname)
-{
- if (isContextLost())
- return 0;
- if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) {
- synthesizeGLError(GL_INVALID_ENUM, "getVertexAttribOffset", "invalid parameter name");
- return 0;
- }
- GC3Dsizeiptr result = m_context->getVertexAttribOffset(index, pname);
- return static_cast<long long>(result);
-}
-
-void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
-{
- if (isContextLost())
- return;
- bool isValid = false;
- switch (target) {
- case GL_GENERATE_MIPMAP_HINT:
- isValid = true;
- break;
- case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
- if (m_oesStandardDerivatives)
- isValid = true;
- break;
- }
- if (!isValid) {
- synthesizeGLError(GL_INVALID_ENUM, "hint", "invalid target");
- return;
- }
- m_context->hint(target, mode);
-}
-
-GC3Dboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
-{
- if (!buffer || isContextLost())
- return 0;
-
- if (!buffer->hasEverBeenBound())
- return 0;
-
- return m_context->isBuffer(buffer->object());
-}
-
-bool WebGLRenderingContext::isContextLost()
-{
- return m_contextLost;
-}
-
-GC3Dboolean WebGLRenderingContext::isEnabled(GC3Denum cap)
-{
- if (isContextLost() || !validateCapability("isEnabled", cap))
- return 0;
- if (cap == GL_STENCIL_TEST)
- return m_stencilEnabled;
- return m_context->isEnabled(cap);
-}
-
-GC3Dboolean WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
-{
- if (!framebuffer || isContextLost())
- return 0;
-
- if (!framebuffer->hasEverBeenBound())
- return 0;
-
- return m_context->isFramebuffer(framebuffer->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isProgram(WebGLProgram* program)
-{
- if (!program || isContextLost())
- return 0;
-
- return m_context->isProgram(program->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
- if (!renderbuffer || isContextLost())
- return 0;
-
- if (!renderbuffer->hasEverBeenBound())
- return 0;
-
- return m_context->isRenderbuffer(renderbuffer->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isShader(WebGLShader* shader)
-{
- if (!shader || isContextLost())
- return 0;
-
- return m_context->isShader(shader->object());
-}
-
-GC3Dboolean WebGLRenderingContext::isTexture(WebGLTexture* texture)
-{
- if (!texture || isContextLost())
- return 0;
-
- if (!texture->hasEverBeenBound())
- return 0;
-
- return m_context->isTexture(texture->object());
-}
-
-void WebGLRenderingContext::lineWidth(GC3Dfloat width)
-{
- if (isContextLost())
- return;
- m_context->lineWidth(width);
-}
-
-void WebGLRenderingContext::linkProgram(WebGLProgram* program)
-{
- if (isContextLost() || !validateWebGLObject("linkProgram", program))
- return;
-
- m_context->linkProgram(objectOrZero(program));
- program->increaseLinkCount();
-}
-
-void WebGLRenderingContext::pixelStorei(GC3Denum pname, GC3Dint param)
-{
- if (isContextLost())
- return;
- switch (pname) {
- case GC3D_UNPACK_FLIP_Y_WEBGL:
- m_unpackFlipY = param;
- break;
- case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
- m_unpackPremultiplyAlpha = param;
- break;
- case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
- if (static_cast<GC3Denum>(param) == GC3D_BROWSER_DEFAULT_WEBGL || param == GL_NONE)
- m_unpackColorspaceConversion = static_cast<GC3Denum>(param);
- else {
- synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
- return;
- }
- break;
- case GL_PACK_ALIGNMENT:
- case GL_UNPACK_ALIGNMENT:
- if (param == 1 || param == 2 || param == 4 || param == 8) {
- if (pname == GL_PACK_ALIGNMENT)
- m_packAlignment = param;
- else // GL_UNPACK_ALIGNMENT:
- m_unpackAlignment = param;
- m_context->pixelStorei(pname, param);
- } else {
- synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
- return;
- }
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "pixelStorei", "invalid parameter name");
- return;
- }
-}
-
-void WebGLRenderingContext::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
-{
- if (isContextLost())
- return;
- m_context->polygonOffset(factor, units);
-}
-
-void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels)
-{
- if (isContextLost())
- return;
- // Due to WebGL's same-origin restrictions, it is not possible to
- // taint the origin using the WebGL API.
- ASSERT(canvas()->originClean());
- // Validate input parameters.
- if (!pixels) {
- synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
- return;
- }
- switch (format) {
- case GL_ALPHA:
- case GL_RGB:
- case GL_RGBA:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid format");
- return;
- }
- switch (type) {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid type");
- return;
- }
- if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) {
- synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
- return;
- }
- // Validate array type against pixel type.
- if (pixels->getType() != ArrayBufferView::TypeUint8) {
- synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
- return;
- }
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
- return;
- }
- // Calculate array size, taking into consideration of PACK_ALIGNMENT.
- unsigned int totalBytesRequired = 0;
- unsigned int padding = 0;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
- if (error != GL_NO_ERROR) {
- synthesizeGLError(error, "readPixels", "invalid dimensions");
- return;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
- return;
- }
-
- clearIfComposited();
- void* data = pixels->baseAddress();
-
- {
- ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
- m_context->readPixels(x, y, width, height, format, type, data);
- }
-
-#if OS(MACOSX)
- // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
- // when alpha is off, readPixels should set alpha to 255 instead of 0.
- if (!m_framebufferBinding && !m_context->getContextAttributes().alpha) {
- unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
- for (GC3Dsizei iy = 0; iy < height; ++iy) {
- for (GC3Dsizei ix = 0; ix < width; ++ix) {
- pixels[3] = 255;
- pixels += 4;
- }
- pixels += padding;
- }
- }
-#endif
-}
-
-void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (target != GL_RENDERBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid target");
- return;
- }
- if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- synthesizeGLError(GL_INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
- return;
- }
- if (!validateSize("renderbufferStorage", width, height))
- return;
- switch (internalformat) {
- case GL_DEPTH_COMPONENT16:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGB565:
- case GL_STENCIL_INDEX8:
- m_context->renderbufferStorage(target, internalformat, width, height);
- m_renderbufferBinding->setInternalFormat(internalformat);
- m_renderbufferBinding->setSize(width, height);
- m_renderbufferBinding->deleteEmulatedStencilBuffer(m_context.get());
- break;
- case GL_DEPTH_STENCIL_OES:
- if (isDepthStencilSupported()) {
- m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
- } else {
- WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(target, m_renderbufferBinding.get());
- if (!emulatedStencilBuffer) {
- synthesizeGLError(GL_OUT_OF_MEMORY, "renderbufferStorage", "out of memory");
- return;
- }
- m_context->renderbufferStorage(target, GL_DEPTH_COMPONENT16, width, height);
- m_context->bindRenderbuffer(target, objectOrZero(emulatedStencilBuffer));
- m_context->renderbufferStorage(target, GL_STENCIL_INDEX8, width, height);
- m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
- emulatedStencilBuffer->setSize(width, height);
- emulatedStencilBuffer->setInternalFormat(GL_STENCIL_INDEX8);
- }
- m_renderbufferBinding->setSize(width, height);
- m_renderbufferBinding->setInternalFormat(internalformat);
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
- return;
- }
- applyStencilTest();
-}
-
-void WebGLRenderingContext::sampleCoverage(GC3Dfloat value, GC3Dboolean invert)
-{
- if (isContextLost())
- return;
- m_context->sampleCoverage(value, invert);
-}
-
-void WebGLRenderingContext::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateSize("scissor", width, height))
- return;
- m_context->scissor(x, y, width, height);
-}
-
-void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string)
-{
- if (isContextLost() || !validateWebGLObject("shaderSource", shader))
- return;
- String stringWithoutComments = StripComments(string).result();
- if (!validateString("shaderSource", stringWithoutComments))
- return;
- shader->setSource(string);
- m_context->shaderSource(objectOrZero(shader), stringWithoutComments);
-}
-
-void WebGLRenderingContext::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- if (isContextLost())
- return;
- if (!validateStencilOrDepthFunc("stencilFunc", func))
- return;
- m_stencilFuncRef = ref;
- m_stencilFuncRefBack = ref;
- m_stencilFuncMask = mask;
- m_stencilFuncMaskBack = mask;
- m_context->stencilFunc(func, ref, mask);
-}
-
-void WebGLRenderingContext::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask)
-{
- if (isContextLost())
- return;
- if (!validateStencilOrDepthFunc("stencilFuncSeparate", func))
- return;
- switch (face) {
- case GL_FRONT_AND_BACK:
- m_stencilFuncRef = ref;
- m_stencilFuncRefBack = ref;
- m_stencilFuncMask = mask;
- m_stencilFuncMaskBack = mask;
- break;
- case GL_FRONT:
- m_stencilFuncRef = ref;
- m_stencilFuncMask = mask;
- break;
- case GL_BACK:
- m_stencilFuncRefBack = ref;
- m_stencilFuncMaskBack = mask;
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "stencilFuncSeparate", "invalid face");
- return;
- }
- m_context->stencilFuncSeparate(face, func, ref, mask);
-}
-
-void WebGLRenderingContext::stencilMask(GC3Duint mask)
-{
- if (isContextLost())
- return;
- m_stencilMask = mask;
- m_stencilMaskBack = mask;
- m_context->stencilMask(mask);
-}
-
-void WebGLRenderingContext::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
-{
- if (isContextLost())
- return;
- switch (face) {
- case GL_FRONT_AND_BACK:
- m_stencilMask = mask;
- m_stencilMaskBack = mask;
- break;
- case GL_FRONT:
- m_stencilMask = mask;
- break;
- case GL_BACK:
- m_stencilMaskBack = mask;
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "stencilMaskSeparate", "invalid face");
- return;
- }
- m_context->stencilMaskSeparate(face, mask);
-}
-
-void WebGLRenderingContext::stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- if (isContextLost())
- return;
- m_context->stencilOp(fail, zfail, zpass);
-}
-
-void WebGLRenderingContext::stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass)
-{
- if (isContextLost())
- return;
- m_context->stencilOpSeparate(face, fail, zfail, zpass);
-}
-
-void WebGLRenderingContext::texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState& exceptionState)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- // FIXME: Handle errors.
- WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
- ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
- ASSERT(tex);
- ASSERT(!level || !WebGLTexture::isNPOT(width, height));
- ASSERT(!pixels || validateSettableTexFormat("texImage2D", internalformat));
- m_context->texImage2D(target, level, internalformat, width, height,
- border, format, type, pixels);
- tex->setLevelInfo(target, level, internalformat, width, height, type);
-}
-
-void WebGLRenderingContext::texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GL_UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GL_RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "packImage error");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, format, type, needConversion ? data.data() : imagePixelData, exceptionState);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-bool WebGLRenderingContext::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset)
-{
- if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
- return false;
-
- WebGLTexture* texture = validateTextureBinding(functionName, target, true);
- if (!texture)
- return false;
-
- if (functionType == NotTexSubImage2D) {
- if (level && WebGLTexture::isNPOT(width, height)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "level > 0 not power of 2");
- return false;
- }
- // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
- // by checking if the ArrayBufferView is null or not.
- if (sourceType != SourceArrayBufferView) {
- if (!validateSettableTexFormat(functionName, format))
- return false;
- }
- } else {
- if (!validateSettableTexFormat(functionName, format))
- return false;
- if (!validateSize(functionName, xoffset, yoffset))
- return false;
- // Before checking if it is in the range, check if overflow happens first.
- if (xoffset + width < 0 || yoffset + height < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions");
- return false;
- }
- if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range");
- return false;
- }
- if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type and format do not match texture");
- return false;
- }
- }
-
- return true;
-}
-
-PassRefPtr<Image> WebGLRenderingContext::drawImageIntoBuffer(Image* image, int width, int height)
-{
- IntSize size(width, height);
- ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
- if (!buf) {
- synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
- return 0;
- }
-
- IntRect srcRect(IntPoint(), image->size());
- IntRect destRect(0, 0, size.width(), size.height());
- buf->context()->drawImage(image, destRect, srcRect);
- return buf->copyImage(ImageBuffer::fastCopyImageMode());
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
- || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
- return;
- void* data = pixels ? pixels->baseAddress() : 0;
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, width, height, border, format, type, data, exceptionState);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionState& exceptionState)
-{
- if (isContextLost() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
- return;
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLImageElement("texImage2D", image, exceptionState))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height());
-
- if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
- return;
-
- texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, exceptionState) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
- return;
-
- WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
- // If possible, copy from the canvas element directly to the texture
- // via the GPU, without a read-back to system memory.
- if (GL_TEXTURE_2D == target && texture) {
- if (!canvas->is3D()) {
- ImageBuffer* buffer = canvas->buffer();
- if (buffer && buffer->copyToPlatformTexture(*m_context.get(), texture->object(), internalformat, type,
- level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
- return;
- }
- } else {
- WebGLRenderingContext* gl = toWebGLRenderingContext(canvas->renderingContext());
- if (gl && gl->m_drawingBuffer->copyToPlatformTexture(*m_context.get(), texture->object(), internalformat, type,
- level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
- return;
- }
- }
- }
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texImage2D(target, level, internalformat, format, type, imageData.get(), exceptionState);
- else
- texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
-{
- IntSize size(video->videoWidth(), video->videoHeight());
- ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
- if (!buf) {
- synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
- return 0;
- }
- IntRect destRect(0, 0, size.width(), size.height());
- // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
- video->paintCurrentFrameInContext(buf->context(), destRect);
- return buf->copyImage(backingStoreCopy);
-}
-
-void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, exceptionState)
- || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
- return;
-
- // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
- // Otherwise, it will fall back to the normal SW path.
- WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
- if (GL_TEXTURE_2D == target && texture) {
- if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
- texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
- return;
- }
- }
-
- // Normal pure SW path.
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
- if (!image)
- return;
- texImage2DImpl(target, level, internalformat, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat paramf, GC3Dint parami, bool isFloat)
-{
- if (isContextLost())
- return;
- WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
- if (!tex)
- return;
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_MAG_FILTER:
- break;
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- if ((isFloat && paramf != GL_CLAMP_TO_EDGE && paramf != GL_MIRRORED_REPEAT && paramf != GL_REPEAT)
- || (!isFloat && parami != GL_CLAMP_TO_EDGE && parami != GL_MIRRORED_REPEAT && parami != GL_REPEAT)) {
- synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter");
- return;
- }
- break;
- case Extensions3D::TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
- if (!m_extTextureFilterAnisotropic) {
- synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
- return;
- }
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter name");
- return;
- }
- if (isFloat) {
- tex->setParameterf(pname, paramf);
- m_context->texParameterf(target, pname, paramf);
- } else {
- tex->setParameteri(pname, parami);
- m_context->texParameteri(target, pname, parami);
- }
-}
-
-void WebGLRenderingContext::texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param)
-{
- texParameter(target, pname, param, 0, true);
-}
-
-void WebGLRenderingContext::texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param)
-{
- texParameter(target, pname, 0, param, false);
-}
-
-void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState& exceptionState)
-{
- // FIXME: Handle errors.
- ASSERT(!isContextLost());
- ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
- ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
- ASSERT(validateSettableTexFormat("texSubImage2D", format));
- WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
- if (!tex) {
- ASSERT_NOT_REACHED();
- return;
- }
- ASSERT((xoffset + width) >= 0);
- ASSERT((yoffset + height) >= 0);
- ASSERT(tex->getWidth(target, level) >= (xoffset + width));
- ASSERT(tex->getHeight(target, level) >= (yoffset + height));
- ASSERT(tex->getInternalFormat(target, level) == format);
- ASSERT(tex->getType(target, level) == type);
- m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image* image, GraphicsContext3D::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- Vector<uint8_t> data;
- GraphicsContext3D::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
- if (!imageExtractor.extractSucceeded()) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image");
- return;
- }
- GraphicsContext3D::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
- GraphicsContext3D::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
- const void* imagePixelData = imageExtractor.imagePixelData();
-
- bool needConversion = true;
- if (type == GL_UNSIGNED_BYTE && sourceDataFormat == GraphicsContext3D::DataFormatRGBA8 && format == GL_RGBA && alphaOp == GraphicsContext3D::AlphaDoNothing && !flipY)
- needConversion = false;
- else {
- if (!m_context->packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
- return;
- }
- }
-
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, type, needConversion ? data.data() : imagePixelData, exceptionState);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
- return;
- void* data = pixels->baseAddress();
- Vector<uint8_t> tempData;
- bool changeUnpackAlignment = false;
- if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
- if (!m_context->extractTextureData(width, height, format, type,
- m_unpackAlignment,
- m_unpackFlipY, m_unpackPremultiplyAlpha,
- data,
- tempData))
- return;
- data = tempData.data();
- changeUnpackAlignment = true;
- }
- if (changeUnpackAlignment)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, exceptionState);
- if (changeUnpackAlignment)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData* pixels, ExceptionState& exceptionState)
-{
- if (isContextLost() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
- return;
-
- Vector<uint8_t> data;
- bool needConversion = true;
- // The data from ImageData is always of format RGBA8.
- // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
- if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
- needConversion = false;
- else {
- if (!m_context->extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
- return;
- }
- }
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
- texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
- if (m_unpackAlignment != 1)
- m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement* image, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, exceptionState))
- return;
-
- RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
- if (imageForRender->isSVGImage())
- imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height());
-
- if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
- return;
-
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), GraphicsContext3D::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<ImageData> imageData = canvas->getImageData();
- if (imageData)
- texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), exceptionState);
- else
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), GraphicsContext3D::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
- if (isContextLost() || !validateHTMLVideoElement("texSubImage2D", video, exceptionState)
- || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
- return;
-
- RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
- if (!image)
- return;
- texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), GraphicsContext3D::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3Dfloat x)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for current program");
- return;
- }
-
- m_context->uniform1f(location->location(), x);
-}
-
-void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
- return;
-
- m_context->uniform1fv(location->location(), v->length(), v->data());
-}
-
-void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
- return;
-
- m_context->uniform1fv(location->location(), size, v);
-}
-
-void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3Dint x)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform1i", "location not for current program");
- return;
- }
-
- m_context->uniform1i(location->location(), x);
-}
-
-void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
- return;
-
- m_context->uniform1iv(location->location(), v->length(), v->data());
-}
-
-void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
- return;
-
- m_context->uniform1iv(location->location(), size, v);
-}
-
-void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform2f", "location not for current program");
- return;
- }
-
- m_context->uniform2f(location->location(), x, y);
-}
-
-void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
- return;
-
- m_context->uniform2fv(location->location(), v->length() / 2, v->data());
-}
-
-void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
- return;
-
- m_context->uniform2fv(location->location(), size / 2, v);
-}
-
-void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform2i", "location not for current program");
- return;
- }
-
- m_context->uniform2i(location->location(), x, y);
-}
-
-void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
- return;
-
- m_context->uniform2iv(location->location(), v->length() / 2, v->data());
-}
-
-void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
- return;
-
- m_context->uniform2iv(location->location(), size / 2, v);
-}
-
-void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform3f", "location not for current program");
- return;
- }
-
- m_context->uniform3f(location->location(), x, y, z);
-}
-
-void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
- return;
-
- m_context->uniform3fv(location->location(), v->length() / 3, v->data());
-}
-
-void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
- return;
-
- m_context->uniform3fv(location->location(), size / 3, v);
-}
-
-void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform3i", "location not for current program");
- return;
- }
-
- m_context->uniform3i(location->location(), x, y, z);
-}
-
-void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
- return;
-
- m_context->uniform3iv(location->location(), v->length() / 3, v->data());
-}
-
-void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
- return;
-
- m_context->uniform3iv(location->location(), size / 3, v);
-}
-
-void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform4f", "location not for current program");
- return;
- }
-
- m_context->uniform4f(location->location(), x, y, z, w);
-}
-
-void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
- return;
-
- m_context->uniform4fv(location->location(), v->length() / 4, v->data());
-}
-
-void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
- return;
-
- m_context->uniform4fv(location->location(), size / 4, v);
-}
-
-void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w)
-{
- if (isContextLost() || !location)
- return;
-
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, "uniform4i", "location not for current program");
- return;
- }
-
- m_context->uniform4i(location->location(), x, y, z, w);
-}
-
-void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v)
-{
- if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
- return;
-
- m_context->uniform4iv(location->location(), v->length() / 4, v->data());
-}
-
-void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
- return;
-
- m_context->uniform4iv(location->location(), size / 4, v);
-}
-
-void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
- return;
- m_context->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
- return;
- m_context->uniformMatrix2fv(location->location(), size / 4, transpose, v);
-}
-
-void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
- return;
- m_context->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
- return;
- m_context->uniformMatrix3fv(location->location(), size / 9, transpose, v);
-}
-
-void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
- return;
- m_context->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size)
-{
- if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
- return;
- m_context->uniformMatrix4fv(location->location(), size / 16, transpose, v);
-}
-
-void WebGLRenderingContext::useProgram(WebGLProgram* program)
-{
- bool deleted;
- if (!checkObjectToBeBound("useProgram", program, deleted))
- return;
- if (deleted)
- program = 0;
- if (program && !program->linkStatus()) {
- synthesizeGLError(GL_INVALID_OPERATION, "useProgram", "program not valid");
- return;
- }
- if (m_currentProgram != program) {
- if (m_currentProgram)
- m_currentProgram->onDetached(graphicsContext3D());
- m_currentProgram = program;
- m_context->useProgram(objectOrZero(program));
- if (program)
- program->onAttached();
- }
-}
-
-void WebGLRenderingContext::validateProgram(WebGLProgram* program)
-{
- if (isContextLost() || !validateWebGLObject("validateProgram", program))
- return;
- m_context->validateProgram(objectOrZero(program));
-}
-
-void WebGLRenderingContext::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
-{
- vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
-}
-
-void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
-}
-
-void WebGLRenderingContext::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
-{
- vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
-}
-
-void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
-}
-
-void WebGLRenderingContext::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
-{
- vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
-}
-
-void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
-}
-
-void WebGLRenderingContext::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
-{
- vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
-}
-
-void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, Float32Array* v)
-{
- vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
-}
-
-void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
-{
- vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
-}
-
-void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, long long offset)
-{
- if (isContextLost())
- return;
- switch (type) {
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_FLOAT:
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "index out of range");
- return;
- }
- if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
- return;
- }
- if (!m_boundArrayBuffer) {
- synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
- return;
- }
- // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
- unsigned int typeSize = sizeInBytes(type);
- if (!typeSize) {
- synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
- return;
- }
- if ((stride % typeSize) || (static_cast<GC3Dintptr>(offset) % typeSize)) {
- synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
- return;
- }
- GC3Dsizei bytesPerElement = size * typeSize;
-
- m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GC3Dintptr>(offset), m_boundArrayBuffer);
- m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GC3Dintptr>(offset));
-}
-
-void WebGLRenderingContext::vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor)
-{
- if (isContextLost())
- return;
-
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisorANGLE", "index out of range");
- return;
- }
-
- m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
- m_context->extensions()->vertexAttribDivisorANGLE(index, divisor);
-}
-
-void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height)
-{
- if (isContextLost())
- return;
- if (!validateSize("viewport", width, height))
- return;
- m_context->viewport(x, y, width, height);
-}
-
-void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
-{
- if (isContextLost()) {
- synthesizeGLError(GL_INVALID_OPERATION, "loseContext", "context already lost");
- return;
- }
-
- m_contextGroup->loseContextGroup(mode);
-}
-
-void WebGLRenderingContext::loseContextImpl(WebGLRenderingContext::LostContextMode mode)
-{
- if (isContextLost())
- return;
-
- m_contextLost = true;
- m_contextLostMode = mode;
-
- if (mode == RealLostContext) {
- // Inform the embedder that a lost context was received. In response, the embedder might
- // decide to take action such as asking the user for permission to use WebGL again.
- if (Frame* frame = canvas()->document().frame())
- frame->loader().client()->didLoseWebGLContext(m_context->extensions()->getGraphicsResetStatusARB());
- }
-
- // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
- m_drawingBuffer->setTexture2DBinding(0);
- m_drawingBuffer->setFramebufferBinding(0);
-
- detachAndRemoveAllObjects();
-
- // Lose all the extensions.
- for (size_t i = 0; i < m_extensions.size(); ++i) {
- ExtensionTracker* tracker = m_extensions[i];
- tracker->loseExtension();
- }
-
- removeAllCompressedTextureFormats();
-
- if (mode != RealLostContext)
- destroyGraphicsContext3D();
-
- ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
- synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
-
- // Don't allow restoration unless the context lost event has both been
- // dispatched and its default behavior prevented.
- m_restoreAllowed = false;
-
- // Always defer the dispatch of the context lost event, to implement
- // the spec behavior of queueing a task.
- m_dispatchContextLostEventTimer.startOneShot(0);
-}
-
-void WebGLRenderingContext::forceRestoreContext()
-{
- if (!isContextLost()) {
- synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not lost");
- return;
- }
-
- if (!m_restoreAllowed) {
- if (m_contextLostMode == SyntheticLostContext)
- synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context restoration not allowed");
- return;
- }
-
- if (!m_restoreTimer.isActive())
- m_restoreTimer.startOneShot(0);
-}
-
-blink::WebLayer* WebGLRenderingContext::platformLayer() const
-{
- return m_drawingBuffer->platformLayer();
-}
-
-void WebGLRenderingContext::removeSharedObject(WebGLSharedObject* object)
-{
- m_contextGroup->removeObject(object);
-}
-
-void WebGLRenderingContext::addSharedObject(WebGLSharedObject* object)
-{
- ASSERT(!isContextLost());
- m_contextGroup->addObject(object);
-}
-
-void WebGLRenderingContext::removeContextObject(WebGLContextObject* object)
-{
- m_contextObjects.remove(object);
-}
-
-void WebGLRenderingContext::addContextObject(WebGLContextObject* object)
-{
- ASSERT(!isContextLost());
- m_contextObjects.add(object);
-}
-
-void WebGLRenderingContext::detachAndRemoveAllObjects()
-{
- while (m_contextObjects.size() > 0) {
- HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
- (*it)->detachContext();
- }
-}
-
-bool WebGLRenderingContext::hasPendingActivity() const
-{
- return false;
-}
-
-void WebGLRenderingContext::stop()
-{
- if (!isContextLost()) {
- forceLostContext(SyntheticLostContext);
- destroyGraphicsContext3D();
- }
-}
-
-WebGLGetInfo WebGLRenderingContext::getBooleanParameter(GC3Denum pname)
-{
- GC3Dboolean value = 0;
- if (!isContextLost())
- m_context->getBooleanv(pname, &value);
- return WebGLGetInfo(static_cast<bool>(value));
-}
-
-WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(GC3Denum pname)
-{
- if (pname != GL_COLOR_WRITEMASK) {
- notImplemented();
- return WebGLGetInfo(0, 0);
- }
- GC3Dboolean value[4] = {0};
- if (!isContextLost())
- m_context->getBooleanv(pname, value);
- bool boolValue[4];
- for (int ii = 0; ii < 4; ++ii)
- boolValue[ii] = static_cast<bool>(value[ii]);
- return WebGLGetInfo(boolValue, 4);
-}
-
-WebGLGetInfo WebGLRenderingContext::getFloatParameter(GC3Denum pname)
-{
- GC3Dfloat value = 0;
- if (!isContextLost())
- m_context->getFloatv(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContext::getIntParameter(GC3Denum pname)
-{
- GC3Dint value = 0;
- if (!isContextLost())
- m_context->getIntegerv(pname, &value);
- return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContext::getUnsignedIntParameter(GC3Denum pname)
-{
- GC3Dint value = 0;
- if (!isContextLost())
- m_context->getIntegerv(pname, &value);
- return WebGLGetInfo(static_cast<unsigned int>(value));
-}
-
-WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(GC3Denum pname)
-{
- GC3Dfloat value[4] = {0};
- if (!isContextLost())
- m_context->getFloatv(pname, value);
- unsigned length = 0;
- switch (pname) {
- case GL_ALIASED_POINT_SIZE_RANGE:
- case GL_ALIASED_LINE_WIDTH_RANGE:
- case GL_DEPTH_RANGE:
- length = 2;
- break;
- case GL_BLEND_COLOR:
- case GL_COLOR_CLEAR_VALUE:
- length = 4;
- break;
- default:
- notImplemented();
- }
- return WebGLGetInfo(Float32Array::create(value, length));
-}
-
-WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(GC3Denum pname)
-{
- GC3Dint value[4] = {0};
- if (!isContextLost())
- m_context->getIntegerv(pname, value);
- unsigned length = 0;
- switch (pname) {
- case GL_MAX_VIEWPORT_DIMS:
- length = 2;
- break;
- case GL_SCISSOR_BOX:
- case GL_VIEWPORT:
- length = 4;
- break;
- default:
- notImplemented();
- }
- return WebGLGetInfo(Int32Array::create(value, length));
-}
-
-void WebGLRenderingContext::handleTextureCompleteness(const char* functionName, bool prepareToDraw)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- bool resetActiveUnit = false;
- WebGLTexture::TextureExtensionFlag flag = static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureFloatLinearExtensionEnabled : 0)
- | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureHalfFloatLinearExtensionEnabled : 0));
- for (unsigned ii = 0; ii < m_onePlusMaxNonDefaultTextureUnit; ++ii) {
- if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
- || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))) {
- if (ii != m_activeTextureUnit) {
- m_context->activeTexture(ii);
- resetActiveUnit = true;
- } else if (resetActiveUnit) {
- m_context->activeTexture(ii);
- resetActiveUnit = false;
- }
- WebGLTexture* tex2D;
- WebGLTexture* texCubeMap;
- if (prepareToDraw) {
- String msg(String("texture bound to texture unit ") + String::number(ii)
- + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'."
- + " Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.");
- emitGLWarning(functionName, msg.utf8().data());
- tex2D = m_blackTexture2D.get();
- texCubeMap = m_blackTextureCubeMap.get();
- } else {
- tex2D = m_textureUnits[ii].m_texture2DBinding.get();
- texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
- }
- if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
- m_context->bindTexture(GL_TEXTURE_2D, objectOrZero(tex2D));
- if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))
- m_context->bindTexture(GL_TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
- }
- }
- if (resetActiveUnit)
- m_context->activeTexture(m_activeTextureUnit);
-}
-
-void WebGLRenderingContext::createFallbackBlackTextures1x1()
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- unsigned char black[] = {0, 0, 0, 255};
- m_blackTexture2D = createTexture();
- m_context->bindTexture(GL_TEXTURE_2D, m_blackTexture2D->object());
- m_context->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->bindTexture(GL_TEXTURE_2D, 0);
- m_blackTextureCubeMap = createTexture();
- m_context->bindTexture(GL_TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 1, 1,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
- m_context->bindTexture(GL_TEXTURE_CUBE_MAP, 0);
-}
-
-bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
- GC3Denum colorBufferFormat)
-{
- unsigned need = GraphicsContext3D::getChannelBitsByFormat(texInternalFormat);
- unsigned have = GraphicsContext3D::getChannelBitsByFormat(colorBufferFormat);
- return (need & have) == need;
-}
-
-GC3Denum WebGLRenderingContext::boundFramebufferColorFormat()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->colorBufferFormat();
- if (m_attributes.alpha)
- return GL_RGBA;
- return GL_RGB;
-}
-
-int WebGLRenderingContext::boundFramebufferWidth()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->colorBufferWidth();
- return m_drawingBuffer->size().width();
-}
-
-int WebGLRenderingContext::boundFramebufferHeight()
-{
- if (m_framebufferBinding && m_framebufferBinding->object())
- return m_framebufferBinding->colorBufferHeight();
- return m_drawingBuffer->size().height();
-}
-
-WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap)
-{
- WebGLTexture* tex = 0;
- switch (target) {
- case GL_TEXTURE_2D:
- tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get();
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (!useSixEnumsForCubeMap) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
- return 0;
- }
- tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
- break;
- case GL_TEXTURE_CUBE_MAP:
- if (useSixEnumsForCubeMap) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
- return 0;
- }
- tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
- return 0;
- }
- if (!tex)
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "no texture");
- return tex;
-}
-
-bool WebGLRenderingContext::validateLocationLength(const char* functionName, const String& string)
-{
- const unsigned maxWebGLLocationLength = 256;
- if (string.length() > maxWebGLLocationLength) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "location length > 256");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateSize(const char* functionName, GC3Dint x, GC3Dint y)
-{
- if (x < 0 || y < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "size < 0");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateString(const char* functionName, const String& string)
-{
- for (size_t i = 0; i < string.length(); ++i) {
- if (!validateCharacter(string[i])) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "string not ASCII");
- return false;
- }
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level)
-{
- switch (format) {
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_RGB:
- case GL_RGBA:
- break;
- case GL_DEPTH_STENCIL_OES:
- case GL_DEPTH_COMPONENT:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "depth texture formats not enabled");
- return false;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture format");
- return false;
- }
-
- switch (type) {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- break;
- case GL_FLOAT:
- if (m_oesTextureFloat)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GL_HALF_FLOAT_OES:
- if (m_oesTextureHalfFloat)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
- return false;
- case GL_UNSIGNED_INT:
- case GL_UNSIGNED_INT_24_8_OES:
- case GL_UNSIGNED_SHORT:
- if (m_webglDepthTexture)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
- return false;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
- return false;
- }
-
- // Verify that the combination of format and type is supported.
- switch (format) {
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- if (type != GL_UNSIGNED_BYTE
- && type != GL_FLOAT
- && type != GL_HALF_FLOAT_OES) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for format");
- return false;
- }
- break;
- case GL_RGB:
- if (type != GL_UNSIGNED_BYTE
- && type != GL_UNSIGNED_SHORT_5_6_5
- && type != GL_FLOAT
- && type != GL_HALF_FLOAT_OES) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGB format");
- return false;
- }
- break;
- case GL_RGBA:
- if (type != GL_UNSIGNED_BYTE
- && type != GL_UNSIGNED_SHORT_4_4_4_4
- && type != GL_UNSIGNED_SHORT_5_5_5_1
- && type != GL_FLOAT
- && type != GL_HALF_FLOAT_OES) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGBA format");
- return false;
- }
- break;
- case GL_DEPTH_COMPONENT:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
- return false;
- }
- if (type != GL_UNSIGNED_SHORT
- && type != GL_UNSIGNED_INT) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
- return false;
- }
- if (level > 0) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
- return false;
- }
- break;
- case GL_DEPTH_STENCIL_OES:
- if (!m_webglDepthTexture) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
- return false;
- }
- if (type != GL_UNSIGNED_INT_24_8_OES) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
- return false;
- }
- if (level > 0) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
-{
- if (level < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "level < 0");
- return false;
- }
- switch (target) {
- case GL_TEXTURE_2D:
- if (level >= m_maxTextureLevel) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
- return false;
- }
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (level >= m_maxCubeMapTextureLevel) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
- return false;
- }
- break;
- }
- // This function only checks if level is legal, so we return true and don't
- // generate INVALID_ENUM if target is illegal.
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType functionType,
- GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height)
-{
- if (width < 0 || height < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- switch (target) {
- case GL_TEXTURE_2D:
- if (width > (m_maxTextureSize >> level) || height > (m_maxTextureSize >> level)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range");
- return false;
- }
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (functionType != TexSubImage2D && width != height) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width != height for cube map");
- return false;
- }
- // No need to check height here. For texImage width == height.
- // For texSubImage that will be checked when checking yoffset + height is in range.
- if (width > (m_maxCubeMapTextureSize >> level)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range for cube map");
- return false;
- }
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target,
- GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type)
-{
- // We absolutely have to validate the format and type combination.
- // The texImage2D entry points taking HTMLImage, etc. will produce
- // temporary data based on this combination, so it must be legal.
- if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
- return false;
-
- if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
- return false;
-
- if (format != internalformat) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "format != internalformat");
- return false;
- }
-
- if (border) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "border != 0");
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition disposition)
-{
- // All calling functions check isContextLost, so a duplicate check is not needed here.
- if (!pixels) {
- if (disposition == NullAllowed)
- return true;
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
- return false;
- }
-
- if (!validateTexFuncFormatAndType(functionName, format, type, level))
- return false;
- if (!validateSettableTexFormat(functionName, format))
- return false;
-
- switch (type) {
- case GL_UNSIGNED_BYTE:
- if (pixels->getType() != ArrayBufferView::TypeUint8) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
- return false;
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- if (pixels->getType() != ArrayBufferView::TypeUint16) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
- return false;
- }
- break;
- case GL_FLOAT: // OES_texture_float
- if (pixels->getType() != ArrayBufferView::TypeFloat32) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
- return false;
- }
- break;
- case GL_HALF_FLOAT_OES: // OES_texture_half_float
- // As per the specification, ArrayBufferView should be null when
- // OES_texture_half_float is enabled.
- if (pixels) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
- return false;
- }
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- unsigned int totalBytesRequired;
- GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
- if (error != GL_NO_ERROR) {
- synthesizeGLError(error, functionName, "invalid texture dimensions");
- return false;
- }
- if (pixels->byteLength() < totalBytesRequired) {
- if (m_unpackAlignment != 1) {
- error = m_context->computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
- if (pixels->byteLength() == totalBytesRequired) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
- return false;
- }
- }
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateCompressedTexFormat(GC3Denum format)
-{
- return m_compressedTextureFormats.contains(format);
-}
-
-bool WebGLRenderingContext::validateCompressedTexFuncData(const char* functionName,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels)
-{
- if (!pixels) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
- return false;
- }
- if (width < 0 || height < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
- return false;
- }
-
- unsigned int bytesRequired = 0;
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- const int kBlockSize = 8;
- int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
- int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
- int numBlocks = numBlocksAcross * numBlocksDown;
- bytesRequired = numBlocks * kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT:
- {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- const int kBlockSize = 16;
- int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
- int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
- int numBlocks = numBlocksAcross * numBlocksDown;
- bytesRequired = numBlocks * kBlockSize;
- }
- break;
- case Extensions3D::COMPRESSED_ATC_RGB_AMD:
- {
- bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 8;
- }
- break;
- case Extensions3D::COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
- case Extensions3D::COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
- {
- bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 16;
- }
- case Extensions3D::COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
- {
- bytesRequired = max(width, 8) * max(height, 8) / 2;
- }
- break;
- case Extensions3D::COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
- case Extensions3D::COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
- {
- bytesRequired = max(width, 8) * max(height, 8) / 4;
- }
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format");
- return false;
- }
-
- if (pixels->byteLength() != bytesRequired) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType functionType, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format)
-{
- if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
- return false;
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- bool widthValid = (level && width == 1) || (level && width == 2) || !(width % kBlockWidth);
- bool heightValid = (level && height == 1) || (level && height == 2) || !(height % kBlockHeight);
- if (!widthValid || !heightValid) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "width or height invalid for level");
- return false;
- }
- return true;
- }
- default:
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture* tex)
-{
- if (xoffset < 0 || yoffset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "xoffset or yoffset < 0");
- return false;
- }
-
- switch (format) {
- case Extensions3D::COMPRESSED_RGB_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case Extensions3D::COMPRESSED_RGBA_S3TC_DXT5_EXT: {
- const int kBlockWidth = 4;
- const int kBlockHeight = 4;
- if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
- return false;
- }
- if (width - xoffset > tex->getWidth(target, level)
- || height - yoffset > tex->getHeight(target, level)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range");
- return false;
- }
- return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
- }
- default:
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateDrawMode(const char* functionName, GC3Denum mode)
-{
- switch (mode) {
- case GL_POINTS:
- case GL_LINE_STRIP:
- case GL_LINE_LOOP:
- case GL_LINES:
- case GL_TRIANGLE_STRIP:
- case GL_TRIANGLE_FAN:
- case GL_TRIANGLES:
- return true;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid draw mode");
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateStencilSettings(const char* functionName)
-{
- if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "front and back stencils settings do not match");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateStencilOrDepthFunc(const char* functionName, GC3Denum func)
-{
- switch (func) {
- case GL_NEVER:
- case GL_LESS:
- case GL_LEQUAL:
- case GL_GREATER:
- case GL_GEQUAL:
- case GL_EQUAL:
- case GL_NOTEQUAL:
- case GL_ALWAYS:
- return true;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid function");
- return false;
- }
-}
-
-void WebGLRenderingContext::printGLErrorToConsole(const String& message)
-{
- if (!m_numGLErrorsToConsoleAllowed)
- return;
-
- --m_numGLErrorsToConsoleAllowed;
- printWarningToConsole(message);
-
- if (!m_numGLErrorsToConsoleAllowed)
- printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
-
- return;
-}
-
-void WebGLRenderingContext::printWarningToConsole(const String& message)
-{
- if (!canvas())
- return;
- canvas()->document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
-}
-
-bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
-{
- if (target != GL_FRAMEBUFFER) {
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
- return false;
- }
- switch (attachment) {
- case GL_COLOR_ATTACHMENT0:
- case GL_DEPTH_ATTACHMENT:
- case GL_STENCIL_ATTACHMENT:
- case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
- break;
- default:
- if (m_webglDrawBuffers
- && attachment > GL_COLOR_ATTACHMENT0
- && attachment < static_cast<GC3Denum>(GL_COLOR_ATTACHMENT0 + maxColorAttachments()))
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
-{
- switch (mode) {
- case GL_FUNC_ADD:
- case GL_FUNC_SUBTRACT:
- case GL_FUNC_REVERSE_SUBTRACT:
- return true;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid mode");
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst)
-{
- if (((src == GL_CONSTANT_COLOR || src == GL_ONE_MINUS_CONSTANT_COLOR)
- && (dst == GL_CONSTANT_ALPHA || dst == GL_ONE_MINUS_CONSTANT_ALPHA))
- || ((dst == GL_CONSTANT_COLOR || dst == GL_ONE_MINUS_CONSTANT_COLOR)
- && (src == GL_CONSTANT_ALPHA || src == GL_ONE_MINUS_CONSTANT_ALPHA))) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "incompatible src and dst");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denum cap)
-{
- switch (cap) {
- case GL_BLEND:
- case GL_CULL_FACE:
- case GL_DEPTH_TEST:
- case GL_DITHER:
- case GL_POLYGON_OFFSET_FILL:
- case GL_SAMPLE_ALPHA_TO_COVERAGE:
- case GL_SAMPLE_COVERAGE:
- case GL_SCISSOR_TEST:
- case GL_STENCIL_TEST:
- return true;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid capability");
- return false;
- }
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
-{
- return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize)
-{
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return false;
- }
- return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
-{
- if (!location)
- return false;
- if (location->program() != m_currentProgram) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "location is not from current program");
- return false;
- }
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return false;
- }
- if (transpose) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "transpose not FALSE");
- return false;
- }
- if (size < requiredMinSize || (size % requiredMinSize)) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
- return false;
- }
- return true;
-}
-
-WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
-{
- WebGLBuffer* buffer = 0;
- switch (target) {
- case GL_ELEMENT_ARRAY_BUFFER:
- buffer = m_boundVertexArrayObject->boundElementArrayBuffer().get();
- break;
- case GL_ARRAY_BUFFER:
- buffer = m_boundArrayBuffer.get();
- break;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
- return 0;
- }
- if (!buffer) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "no buffer");
- return 0;
- }
- switch (usage) {
- case GL_STREAM_DRAW:
- case GL_STATIC_DRAW:
- case GL_DYNAMIC_DRAW:
- return buffer;
- }
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid usage");
- return 0;
-}
-
-bool WebGLRenderingContext::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionState& exceptionState)
-{
- if (!image || !image->cachedImage()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no image");
- return false;
- }
- const KURL& url = image->cachedImage()->response().url();
- if (url.isNull() || url.isEmpty() || !url.isValid()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid image");
- return false;
- }
- if (wouldTaintOrigin(image)) {
- exceptionState.throwSecurityError("The cross-origin image at " + url.elidedString() + " may not be loaded.");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
- if (!canvas || !canvas->buffer()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no canvas");
- return false;
- }
- if (wouldTaintOrigin(canvas)) {
- exceptionState.throwSecurityError("Tainted canvases may not be loaded.");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
- if (!video || !video->videoWidth() || !video->videoHeight()) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no video");
- return false;
- }
- if (wouldTaintOrigin(video)) {
- exceptionState.throwSecurityError("The video element contains cross-origin data, and may not be loaded.");
- return false;
- }
- return true;
-}
-
-bool WebGLRenderingContext::validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count)
-{
- if (isContextLost() || !validateDrawMode(functionName, mode))
- return false;
-
- if (!validateStencilSettings(functionName))
- return false;
-
- if (first < 0 || count < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "first or count < 0");
- return false;
- }
-
- if (!count) {
- markContextChanged();
- return false;
- }
-
- if (!validateRenderingState()) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "attribs not setup correctly");
- return false;
- }
-
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
- return false;
- }
-
- return true;
-}
-
-bool WebGLRenderingContext::validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset)
-{
- if (isContextLost() || !validateDrawMode(functionName, mode))
- return false;
-
- if (!validateStencilSettings(functionName))
- return false;
-
- switch (type) {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT:
- break;
- case GL_UNSIGNED_INT:
- if (m_oesElementIndexUint)
- break;
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
- return false;
- default:
- synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
- return false;
- }
-
- if (count < 0 || offset < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "count or offset < 0");
- return false;
- }
-
- if (!count) {
- markContextChanged();
- return false;
- }
-
- if (!m_boundVertexArrayObject->boundElementArrayBuffer()) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
- return false;
- }
-
- if (!validateRenderingState()) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "attribs not setup correctly");
- return false;
- }
-
- const char* reason = "framebuffer incomplete";
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), &reason)) {
- synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
- return false;
- }
-
- return true;
-}
-
-// Helper function to validate draw*Instanced calls
-bool WebGLRenderingContext::validateDrawInstanced(const char* functionName, GC3Dsizei primcount)
-{
- if (primcount < 0) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "primcount < 0");
- return false;
- }
-
- // Ensure at least one enabled vertex attrib has a divisor of 0.
- for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
- const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
- if (state.enabled && !state.divisor)
- return true;
- }
-
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "at least one enabled attribute must have a divisor of 0");
- return false;
-}
-
-void WebGLRenderingContext::vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
-{
- if (isContextLost())
- return;
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
- return;
- }
- // In GL, we skip setting vertexAttrib0 values.
- switch (expectedSize) {
- case 1:
- m_context->vertexAttrib1f(index, v0);
- break;
- case 2:
- m_context->vertexAttrib2f(index, v0, v1);
- break;
- case 3:
- m_context->vertexAttrib3f(index, v0, v1, v2);
- break;
- case 4:
- m_context->vertexAttrib4f(index, v0, v1, v2, v3);
- break;
- }
- VertexAttribValue& attribValue = m_vertexAttribValue[index];
- attribValue.value[0] = v0;
- attribValue.value[1] = v1;
- attribValue.value[2] = v2;
- attribValue.value[3] = v3;
-}
-
-void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array* v, GC3Dsizei expectedSize)
-{
- if (isContextLost())
- return;
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return;
- }
- vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
-}
-
-void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize)
-{
- if (isContextLost())
- return;
- if (!v) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
- return;
- }
- if (size < expectedSize) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
- return;
- }
- if (index >= m_maxVertexAttribs) {
- synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
- return;
- }
- // In GL, we skip setting vertexAttrib0 values.
- switch (expectedSize) {
- case 1:
- m_context->vertexAttrib1fv(index, v);
- break;
- case 2:
- m_context->vertexAttrib2fv(index, v);
- break;
- case 3:
- m_context->vertexAttrib3fv(index, v);
- break;
- case 4:
- m_context->vertexAttrib4fv(index, v);
- break;
- }
- VertexAttribValue& attribValue = m_vertexAttribValue[index];
- attribValue.initValue();
- for (int ii = 0; ii < expectedSize; ++ii)
- attribValue.value[ii] = v[ii];
-}
-
-void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext>*)
-{
- RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(EventTypeNames::webglcontextlost, false, true, "");
- canvas()->dispatchEvent(event);
- m_restoreAllowed = event->defaultPrevented();
- deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAllowed);
- if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecoverSyntheticLostContext) && m_restoreAllowed)
- m_restoreTimer.startOneShot(0);
-}
-
-void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
-{
- ASSERT(isContextLost());
-
- // The rendering context is not restored unless the default behavior of the
- // webglcontextlost event was prevented earlier.
- //
- // Because of the way m_restoreTimer is set up for real vs. synthetic lost
- // context events, we don't have to worry about this test short-circuiting
- // the retry loop for real context lost events.
- if (!m_restoreAllowed)
- return;
-
- Frame* frame = canvas()->document().frame();
- if (!frame)
- return;
-
- Settings* settings = frame->settings();
-
- if (!frame->loader().client()->allowWebGL(settings && settings->webGLEnabled()))
- return;
-
- // Reset the context attributes back to the requested attributes and re-apply restrictions
- m_attributes = adjustAttributes(m_requestedAttributes, settings);
-
- RefPtr<GraphicsContext3D> context(GraphicsContext3D::create(m_attributes));
-
- if (!context) {
- if (m_contextLostMode == RealLostContext) {
- m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
- } else {
- // This likely shouldn't happen but is the best way to report it to the WebGL app.
- synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context");
- }
- return;
- }
-
- RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
-
- // Construct a new drawing buffer with the new GraphicsContext3D.
- m_drawingBuffer->releaseResources();
- DrawingBuffer::PreserveDrawingBuffer preserve = m_attributes.preserveDrawingBuffer ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
- m_drawingBuffer = DrawingBuffer::create(context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release());
-
- if (m_drawingBuffer->isZeroSized())
- return;
-
- m_drawingBuffer->bind();
-
- lost_context_errors_.clear();
-
- m_context = context;
- m_contextLost = false;
-
- setupFlags();
- initializeNewContext();
- canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextrestored, false, true, ""));
-}
-
-String WebGLRenderingContext::ensureNotNull(const String& text) const
-{
- if (text.isNull())
- return WTF::emptyString();
- return text;
-}
-
-WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
- : m_buffers(adoptArrayPtr(new OwnPtr<ImageBuffer>[capacity]))
- , m_capacity(capacity)
-{
-}
-
-ImageBuffer* WebGLRenderingContext::LRUImageBufferCache::imageBuffer(const IntSize& size)
-{
- int i;
- for (i = 0; i < m_capacity; ++i) {
- ImageBuffer* buf = m_buffers[i].get();
- if (!buf)
- break;
- if (buf->size() != size)
- continue;
- bubbleToFront(i);
- return buf;
- }
-
- OwnPtr<ImageBuffer> temp(ImageBuffer::create(size));
- if (!temp)
- return 0;
- i = std::min(m_capacity - 1, i);
- m_buffers[i] = temp.release();
-
- ImageBuffer* buf = m_buffers[i].get();
- bubbleToFront(i);
- return buf;
-}
-
-void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx)
-{
- for (int i = idx; i > 0; --i)
- m_buffers[i].swap(m_buffers[i-1]);
-}
-
-namespace {
-
- String GetErrorString(GC3Denum error)
- {
- switch (error) {
- case GL_INVALID_ENUM:
- return "INVALID_ENUM";
- case GL_INVALID_VALUE:
- return "INVALID_VALUE";
- case GL_INVALID_OPERATION:
- return "INVALID_OPERATION";
- case GL_OUT_OF_MEMORY:
- return "OUT_OF_MEMORY";
- case GL_INVALID_FRAMEBUFFER_OPERATION:
- return "INVALID_FRAMEBUFFER_OPERATION";
- case GC3D_CONTEXT_LOST_WEBGL:
- return "CONTEXT_LOST_WEBGL";
- default:
- return String::format("WebGL ERROR(0x%04X)", error);
- }
- }
-
-} // namespace anonymous
-
-void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
-{
- String errorType = GetErrorString(error);
- if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
- String message = String("WebGL: ") + errorType + ": " + String(functionName) + ": " + String(description);
- printGLErrorToConsole(message);
- }
- if (!isContextLost())
- m_context->synthesizeGLError(error);
- else {
- if (lost_context_errors_.find(error) == WTF::kNotFound)
- lost_context_errors_.append(error);
- }
- InspectorInstrumentation::didFireWebGLError(canvas(), errorType);
-}
-
-void WebGLRenderingContext::emitGLWarning(const char* functionName, const char* description)
-{
- if (m_synthesizedErrorsToConsole) {
- String message = String("WebGL: ") + String(functionName) + ": " + String(description);
- printGLErrorToConsole(message);
- }
- InspectorInstrumentation::didFireWebGLWarning(canvas());
-}
-
-void WebGLRenderingContext::applyStencilTest()
-{
- bool haveStencilBuffer = false;
-
- if (m_framebufferBinding)
- haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
- else {
- RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
- haveStencilBuffer = attributes->stencil();
- }
- enableOrDisable(GL_STENCIL_TEST,
- m_stencilEnabled && haveStencilBuffer);
-}
-
-void WebGLRenderingContext::enableOrDisable(GC3Denum capability, bool enable)
-{
- if (isContextLost())
- return;
- if (enable)
- m_context->enable(capability);
- else
- m_context->disable(capability);
-}
-
-IntSize WebGLRenderingContext::clampedCanvasSize()
-{
- return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
- clamp(canvas()->height(), 1, m_maxViewportDims[1]));
-}
-
-GC3Dint WebGLRenderingContext::maxDrawBuffers()
-{
- if (isContextLost() || !m_webglDrawBuffers)
- return 0;
- if (!m_maxDrawBuffers)
- m_context->getIntegerv(Extensions3D::MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
- return std::min(m_maxDrawBuffers, m_maxColorAttachments);
-}
-
-GC3Dint WebGLRenderingContext::maxColorAttachments()
-{
- if (isContextLost() || !m_webglDrawBuffers)
- return 0;
- if (!m_maxColorAttachments)
- m_context->getIntegerv(Extensions3D::MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
- return m_maxColorAttachments;
-}
-
-void WebGLRenderingContext::setBackDrawBuffer(GC3Denum buf)
-{
- m_backDrawBuffer = buf;
-}
-
-void WebGLRenderingContext::restoreCurrentFramebuffer()
-{
- bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get());
-}
-
-void WebGLRenderingContext::restoreCurrentTexture2D()
-{
- bindTexture(GL_TEXTURE_2D, m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get());
-}
-
-void WebGLRenderingContext::multisamplingChanged(bool enabled)
-{
- if (m_multisamplingAllowed != enabled) {
- m_multisamplingAllowed = enabled;
- forceLostContext(WebGLRenderingContext::AutoRecoverSyntheticLostContext);
- }
-}
-
-void WebGLRenderingContext::findNewMaxEnabledAttribIndex()
-{
- // Trace backwards from the current max to find the new max enabled attrib index
- int startIndex = m_onePlusMaxEnabledAttribIndex - 1;
- for (int i = startIndex; i >= 0; --i) {
- if (m_boundVertexArrayObject->getVertexAttribState(i).enabled) {
- m_onePlusMaxEnabledAttribIndex = i + 1;
- return;
- }
- }
- m_onePlusMaxEnabledAttribIndex = 0;
-}
-
-void WebGLRenderingContext::findNewMaxNonDefaultTextureUnit()
-{
- // Trace backwards from the current max to find the new max non-default texture unit
- int startIndex = m_onePlusMaxNonDefaultTextureUnit - 1;
- for (int i = startIndex; i >= 0; --i) {
- if (m_textureUnits[i].m_texture2DBinding
- || m_textureUnits[i].m_textureCubeMapBinding) {
- m_onePlusMaxNonDefaultTextureUnit = i + 1;
- return;
- }
- }
- m_onePlusMaxNonDefaultTextureUnit = 0;
+ registerExtension<EXTShaderTextureLOD>(m_extShaderTextureLOD, DraftExtension);
+ registerExtension<WebGLCompressedTextureETC1>(m_webglCompressedTextureETC1, DraftExtension);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h
index e1e3911e9f1..db0e651b39c 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.h
@@ -26,497 +26,28 @@
#ifndef WebGLRenderingContext_h
#define WebGLRenderingContext_h
-#include "core/dom/ActiveDOMObject.h"
-#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/html/canvas/WebGLGetInfo.h"
-#include "core/page/Page.h"
-#include "platform/Timer.h"
-#include "platform/graphics/GraphicsContext3D.h"
-#include "platform/graphics/ImageBuffer.h"
-
-#include "wtf/Float32Array.h"
-#include "wtf/Int32Array.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink { class WebLayer; }
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-class ANGLEInstancedArrays;
-class DrawingBuffer;
-class EXTFragDepth;
-class EXTTextureFilterAnisotropic;
-class ExceptionState;
-class HTMLImageElement;
-class HTMLVideoElement;
-class ImageBuffer;
-class ImageData;
-class IntSize;
-class OESElementIndexUint;
-class OESStandardDerivatives;
-class OESTextureFloat;
-class OESTextureFloatLinear;
-class OESTextureHalfFloat;
-class OESTextureHalfFloatLinear;
-class OESVertexArrayObject;
-class WebGLActiveInfo;
-class WebGLBuffer;
-class WebGLCompressedTextureATC;
-class WebGLCompressedTexturePVRTC;
-class WebGLCompressedTextureS3TC;
-class WebGLContextAttributes;
-class WebGLContextGroup;
-class WebGLContextObject;
-class WebGLDebugRendererInfo;
-class WebGLDebugShaders;
-class WebGLDepthTexture;
-class WebGLDrawBuffers;
-class WebGLExtension;
-class WebGLFramebuffer;
-class WebGLLoseContext;
-class WebGLObject;
-class WebGLProgram;
-class WebGLRenderbuffer;
-class WebGLShader;
-class WebGLShaderPrecisionFormat;
-class WebGLSharedObject;
-class WebGLTexture;
-class WebGLUniformLocation;
-class WebGLVertexArrayObjectOES;
-
-class WebGLRenderingContext : public CanvasRenderingContext, public ActiveDOMObject, private Page::MultisamplingChangedObserver {
+class WebGLRenderingContext FINAL : public WebGLRenderingContextBase, public ScriptWrappable {
public:
- static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
+ static PassOwnPtrWillBeRawPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
virtual ~WebGLRenderingContext();
- virtual bool is3d() const { return true; }
- virtual bool isAccelerated() const { return true; }
-
- int drawingBufferWidth() const;
- int drawingBufferHeight() const;
-
- void activeTexture(GC3Denum texture);
- void attachShader(WebGLProgram*, WebGLShader*);
- void bindAttribLocation(WebGLProgram*, GC3Duint index, const String& name);
- void bindBuffer(GC3Denum target, WebGLBuffer*);
- void bindFramebuffer(GC3Denum target, WebGLFramebuffer*);
- void bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*);
- void bindTexture(GC3Denum target, WebGLTexture*);
- void blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
- void blendEquation(GC3Denum mode);
- void blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha);
- void blendFunc(GC3Denum sfactor, GC3Denum dfactor);
- void blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha);
-
- void bufferData(GC3Denum target, long long size, GC3Denum usage);
- void bufferData(GC3Denum target, ArrayBuffer* data, GC3Denum usage);
- void bufferData(GC3Denum target, ArrayBufferView* data, GC3Denum usage);
- void bufferSubData(GC3Denum target, long long offset, ArrayBuffer* data);
- void bufferSubData(GC3Denum target, long long offset, ArrayBufferView* data);
-
- GC3Denum checkFramebufferStatus(GC3Denum target);
- void clear(GC3Dbitfield mask);
- void clearColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat blue, GC3Dfloat alpha);
- void clearDepth(GC3Dfloat);
- void clearStencil(GC3Dint);
- void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
- void compileShader(WebGLShader*);
-
- void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, ArrayBufferView* data);
- void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
-
- void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
- void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- PassRefPtr<WebGLBuffer> createBuffer();
- PassRefPtr<WebGLFramebuffer> createFramebuffer();
- PassRefPtr<WebGLProgram> createProgram();
- PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
- PassRefPtr<WebGLShader> createShader(GC3Denum type);
- PassRefPtr<WebGLTexture> createTexture();
-
- void cullFace(GC3Denum mode);
-
- void deleteBuffer(WebGLBuffer*);
- void deleteFramebuffer(WebGLFramebuffer*);
- void deleteProgram(WebGLProgram*);
- void deleteRenderbuffer(WebGLRenderbuffer*);
- void deleteShader(WebGLShader*);
- void deleteTexture(WebGLTexture*);
-
- void depthFunc(GC3Denum);
- void depthMask(GC3Dboolean);
- void depthRange(GC3Dfloat zNear, GC3Dfloat zFar);
- void detachShader(WebGLProgram*, WebGLShader*);
- void disable(GC3Denum cap);
- void disableVertexAttribArray(GC3Duint index);
- void drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei count);
- void drawElements(GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset);
-
- void drawArraysInstancedANGLE(GC3Denum mode, GC3Dint first, GC3Dsizei count, GC3Dsizei primcount);
- void drawElementsInstancedANGLE(GC3Denum mode, GC3Dsizei count, GC3Denum type, GC3Dintptr offset, GC3Dsizei primcount);
-
- void enable(GC3Denum cap);
- void enableVertexAttribArray(GC3Duint index);
- void finish();
- void flush();
- void framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer*);
- void framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture*, GC3Dint level);
- void frontFace(GC3Denum mode);
- void generateMipmap(GC3Denum target);
-
- PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GC3Duint index);
- PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GC3Duint index);
- bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader> >&);
- GC3Dint getAttribLocation(WebGLProgram*, const String& name);
- WebGLGetInfo getBufferParameter(GC3Denum target, GC3Denum pname);
- PassRefPtr<WebGLContextAttributes> getContextAttributes();
- GC3Denum getError();
- PassRefPtr<WebGLExtension> getExtension(const String& name);
- WebGLGetInfo getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname);
- WebGLGetInfo getParameter(GC3Denum pname);
- WebGLGetInfo getProgramParameter(WebGLProgram*, GC3Denum pname);
- String getProgramInfoLog(WebGLProgram*);
- WebGLGetInfo getRenderbufferParameter(GC3Denum target, GC3Denum pname);
- WebGLGetInfo getShaderParameter(WebGLShader*, GC3Denum pname);
- String getShaderInfoLog(WebGLShader*);
- PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GC3Denum shaderType, GC3Denum precisionType);
- String getShaderSource(WebGLShader*);
- Vector<String> getSupportedExtensions();
- WebGLGetInfo getTexParameter(GC3Denum target, GC3Denum pname);
- WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*);
- PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
- WebGLGetInfo getVertexAttrib(GC3Duint index, GC3Denum pname);
- long long getVertexAttribOffset(GC3Duint index, GC3Denum pname);
-
- void hint(GC3Denum target, GC3Denum mode);
- GC3Dboolean isBuffer(WebGLBuffer*);
- bool isContextLost();
- GC3Dboolean isEnabled(GC3Denum cap);
- GC3Dboolean isFramebuffer(WebGLFramebuffer*);
- GC3Dboolean isProgram(WebGLProgram*);
- GC3Dboolean isRenderbuffer(WebGLRenderbuffer*);
- GC3Dboolean isShader(WebGLShader*);
- GC3Dboolean isTexture(WebGLTexture*);
-
- void lineWidth(GC3Dfloat);
- void linkProgram(WebGLProgram*);
- void pixelStorei(GC3Denum pname, GC3Dint param);
- void polygonOffset(GC3Dfloat factor, GC3Dfloat units);
- void readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels);
- void renderbufferStorage(GC3Denum target, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height);
- void sampleCoverage(GC3Dfloat value, GC3Dboolean invert);
- void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
- void shaderSource(WebGLShader*, const String&);
- void stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilFuncSeparate(GC3Denum face, GC3Denum func, GC3Dint ref, GC3Duint mask);
- void stencilMask(GC3Duint);
- void stencilMaskSeparate(GC3Denum face, GC3Duint mask);
- void stencilOp(GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
- void stencilOpSeparate(GC3Denum face, GC3Denum fail, GC3Denum zfail, GC3Denum zpass);
-
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionState&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionState&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionState&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionState&);
- void texImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionState&);
-
- void texParameterf(GC3Denum target, GC3Denum pname, GC3Dfloat param);
- void texParameteri(GC3Denum target, GC3Denum pname, GC3Dint param);
-
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type, ArrayBufferView*, ExceptionState&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, ImageData*, ExceptionState&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLImageElement*, ExceptionState&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLCanvasElement*, ExceptionState&);
- void texSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Denum format, GC3Denum type, HTMLVideoElement*, ExceptionState&);
-
- void uniform1f(const WebGLUniformLocation*, GC3Dfloat x);
- void uniform1fv(const WebGLUniformLocation*, Float32Array* v);
- void uniform1fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
- void uniform1i(const WebGLUniformLocation*, GC3Dint x);
- void uniform1iv(const WebGLUniformLocation*, Int32Array* v);
- void uniform1iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
- void uniform2f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y);
- void uniform2fv(const WebGLUniformLocation*, Float32Array* v);
- void uniform2fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
- void uniform2i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y);
- void uniform2iv(const WebGLUniformLocation*, Int32Array* v);
- void uniform2iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
- void uniform3f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
- void uniform3fv(const WebGLUniformLocation*, Float32Array* v);
- void uniform3fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
- void uniform3i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z);
- void uniform3iv(const WebGLUniformLocation*, Int32Array* v);
- void uniform3iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
- void uniform4f(const WebGLUniformLocation*, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
- void uniform4fv(const WebGLUniformLocation*, Float32Array* v);
- void uniform4fv(const WebGLUniformLocation*, GC3Dfloat* v, GC3Dsizei);
- void uniform4i(const WebGLUniformLocation*, GC3Dint x, GC3Dint y, GC3Dint z, GC3Dint w);
- void uniform4iv(const WebGLUniformLocation*, Int32Array* v);
- void uniform4iv(const WebGLUniformLocation*, GC3Dint* v, GC3Dsizei);
- void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix2fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
- void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix3fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
- void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array* value);
- void uniformMatrix4fv(const WebGLUniformLocation*, GC3Dboolean transpose, GC3Dfloat* value, GC3Dsizei);
-
- void useProgram(WebGLProgram*);
- void validateProgram(WebGLProgram*);
-
- void vertexAttrib1f(GC3Duint index, GC3Dfloat x);
- void vertexAttrib1fv(GC3Duint index, Float32Array* values);
- void vertexAttrib1fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
- void vertexAttrib2f(GC3Duint index, GC3Dfloat x, GC3Dfloat y);
- void vertexAttrib2fv(GC3Duint index, Float32Array* values);
- void vertexAttrib2fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
- void vertexAttrib3f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z);
- void vertexAttrib3fv(GC3Duint index, Float32Array* values);
- void vertexAttrib3fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
- void vertexAttrib4f(GC3Duint index, GC3Dfloat x, GC3Dfloat y, GC3Dfloat z, GC3Dfloat w);
- void vertexAttrib4fv(GC3Duint index, Float32Array* values);
- void vertexAttrib4fv(GC3Duint index, GC3Dfloat* values, GC3Dsizei);
- void vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized,
- GC3Dsizei stride, long long offset);
-
- void vertexAttribDivisorANGLE(GC3Duint index, GC3Duint divisor);
-
- void viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
-
- // WEBKIT_lose_context support
- enum LostContextMode {
- // Lost context occurred at the graphics system level.
- RealLostContext,
-
- // Lost context provoked by WEBKIT_lose_context.
- SyntheticLostContext,
-
- // A synthetic lost context that should attempt to recover automatically
- AutoRecoverSyntheticLostContext
- };
- void forceLostContext(LostContextMode);
- void forceRestoreContext();
- void loseContextImpl(LostContextMode);
-
- GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
- WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
- virtual blink::WebLayer* platformLayer() const;
-
- void reshape(int width, int height);
-
- void markLayerComposited();
- virtual void paintRenderingResultsToCanvas();
- virtual PassRefPtr<ImageData> paintRenderingResultsToImageData();
-
- void removeSharedObject(WebGLSharedObject*);
- void removeContextObject(WebGLContextObject*);
-
- unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }
-
- // ActiveDOMObject notifications
- virtual bool hasPendingActivity() const;
- virtual void stop();
-
- private:
- friend class WebGLDrawBuffers;
- friend class WebGLFramebuffer;
- friend class WebGLObject;
- friend class OESVertexArrayObject;
- friend class WebGLDebugShaders;
- friend class WebGLCompressedTextureATC;
- friend class WebGLCompressedTexturePVRTC;
- friend class WebGLCompressedTextureS3TC;
- friend class WebGLRenderingContextErrorMessageCallback;
- friend class WebGLVertexArrayObjectOES;
-
- WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes, GraphicsContext3D::Attributes);
- void initializeNewContext();
- void setupFlags();
-
- void addSharedObject(WebGLSharedObject*);
- void addContextObject(WebGLContextObject*);
- void detachAndRemoveAllObjects();
-
- void destroyGraphicsContext3D();
- void markContextChanged();
+ virtual unsigned version() const OVERRIDE { return 1; }
+ virtual String contextName() const OVERRIDE { return "WebGLRenderingContext"; }
+ virtual void registerContextExtensions() OVERRIDE;
- // Query if the GL implementation is NPOT strict.
- bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
- // Query if depth_stencil buffer is supported.
- bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
-
- // Helper to return the size in bytes of OpenGL data types
- // like GL_FLOAT, GL_INT, etc.
- unsigned int sizeInBytes(GC3Denum type);
-
- // Check if each enabled vertex attribute is bound to a buffer.
- bool validateRenderingState();
-
- bool validateWebGLObject(const char*, WebGLObject*);
-
- // Adds a compressed texture format.
- void addCompressedTextureFormat(GC3Denum);
- void removeAllCompressedTextureFormats();
-
- PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height);
-
- PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
-
- WebGLRenderbuffer* ensureEmulatedStencilBuffer(GC3Denum target, WebGLRenderbuffer*);
-
- RefPtr<GraphicsContext3D> m_context;
- RefPtr<WebGLContextGroup> m_contextGroup;
-
- // Structure for rendering to a DrawingBuffer, instead of directly
- // to the back-buffer of m_context.
- RefPtr<DrawingBuffer> m_drawingBuffer;
-
- // Dispatches a context lost event once it is determined that one is needed.
- // This is used both for synthetic and real context losses. For real ones, it's
- // likely that there's no JavaScript on the stack, but that might be dependent
- // on how exactly the platform discovers that the context was lost. For better
- // portability we always defer the dispatch of the event.
- Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer;
- bool m_restoreAllowed;
- Timer<WebGLRenderingContext> m_restoreTimer;
-
- bool m_needsUpdate;
- bool m_markedCanvasDirty;
- HashSet<WebGLContextObject*> m_contextObjects;
-
- // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
- RefPtr<WebGLBuffer> m_boundArrayBuffer;
-
- RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
- RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
- void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
- {
- if (arrayObject)
- m_boundVertexArrayObject = arrayObject;
- else
- m_boundVertexArrayObject = m_defaultVertexArrayObject;
- }
-
- class VertexAttribValue {
- public:
- VertexAttribValue()
- {
- initValue();
- }
-
- void initValue()
- {
- value[0] = 0.0f;
- value[1] = 0.0f;
- value[2] = 0.0f;
- value[3] = 1.0f;
- }
-
- GC3Dfloat value[4];
- };
- Vector<VertexAttribValue> m_vertexAttribValue;
- unsigned m_maxVertexAttribs;
- RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
- long m_vertexAttrib0BufferSize;
- GC3Dfloat m_vertexAttrib0BufferValue[4];
- bool m_forceAttrib0BufferRefill;
- bool m_vertexAttrib0UsedBefore;
-
- RefPtr<WebGLProgram> m_currentProgram;
- RefPtr<WebGLFramebuffer> m_framebufferBinding;
- RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
- class TextureUnitState {
- public:
- RefPtr<WebGLTexture> m_texture2DBinding;
- RefPtr<WebGLTexture> m_textureCubeMapBinding;
- };
- Vector<TextureUnitState> m_textureUnits;
- unsigned long m_activeTextureUnit;
-
- RefPtr<WebGLTexture> m_blackTexture2D;
- RefPtr<WebGLTexture> m_blackTextureCubeMap;
-
- Vector<GC3Denum> m_compressedTextureFormats;
-
- // Fixed-size cache of reusable image buffers for video texImage2D calls.
- class LRUImageBufferCache {
- public:
- LRUImageBufferCache(int capacity);
- // The pointer returned is owned by the image buffer map.
- ImageBuffer* imageBuffer(const IntSize& size);
- private:
- void bubbleToFront(int idx);
- OwnPtr<OwnPtr<ImageBuffer>[]> m_buffers;
- int m_capacity;
- };
- LRUImageBufferCache m_generatedImageCache;
-
- GC3Dint m_maxTextureSize;
- GC3Dint m_maxCubeMapTextureSize;
- GC3Dint m_maxRenderbufferSize;
- GC3Dint m_maxViewportDims[2];
- GC3Dint m_maxTextureLevel;
- GC3Dint m_maxCubeMapTextureLevel;
-
- GC3Dint m_maxDrawBuffers;
- GC3Dint m_maxColorAttachments;
- GC3Denum m_backDrawBuffer;
- bool m_drawBuffersWebGLRequirementsChecked;
- bool m_drawBuffersSupported;
-
- GC3Dint m_packAlignment;
- GC3Dint m_unpackAlignment;
- bool m_unpackFlipY;
- bool m_unpackPremultiplyAlpha;
- GC3Denum m_unpackColorspaceConversion;
- bool m_contextLost;
- LostContextMode m_contextLostMode;
- GraphicsContext3D::Attributes m_attributes;
- GraphicsContext3D::Attributes m_requestedAttributes;
-
- bool m_layerCleared;
- GC3Dfloat m_clearColor[4];
- bool m_scissorEnabled;
- GC3Dfloat m_clearDepth;
- GC3Dint m_clearStencil;
- GC3Dboolean m_colorMask[4];
- GC3Dboolean m_depthMask;
-
- bool m_stencilEnabled;
- GC3Duint m_stencilMask, m_stencilMaskBack;
- GC3Dint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
- GC3Duint m_stencilFuncMask, m_stencilFuncMaskBack;
-
- bool m_isGLES2NPOTStrict;
- bool m_isDepthStencilSupported;
-
- bool m_synthesizedErrorsToConsole;
- int m_numGLErrorsToConsoleAllowed;
-
- bool m_multisamplingAllowed;
- bool m_multisamplingObserverRegistered;
-
- GC3Duint m_onePlusMaxEnabledAttribIndex;
- unsigned long m_onePlusMaxNonDefaultTextureUnit;
+private:
+ WebGLRenderingContext(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
// Enabled extension objects.
RefPtr<ANGLEInstancedArrays> m_angleInstancedArrays;
+ RefPtr<EXTBlendMinMax> m_extBlendMinMax;
RefPtr<EXTFragDepth> m_extFragDepth;
+ RefPtr<EXTShaderTextureLOD> m_extShaderTextureLOD;
RefPtr<EXTTextureFilterAnisotropic> m_extTextureFilterAnisotropic;
RefPtr<OESTextureFloat> m_oesTextureFloat;
RefPtr<OESTextureFloatLinear> m_oesTextureFloatLinear;
@@ -530,403 +61,15 @@ public:
RefPtr<WebGLDebugShaders> m_webglDebugShaders;
RefPtr<WebGLDrawBuffers> m_webglDrawBuffers;
RefPtr<WebGLCompressedTextureATC> m_webglCompressedTextureATC;
+ RefPtr<WebGLCompressedTextureETC1> m_webglCompressedTextureETC1;
RefPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
RefPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
RefPtr<WebGLDepthTexture> m_webglDepthTexture;
-
- enum ExtensionFlags {
- ApprovedExtension = 0x00,
- DraftExtension = 0x01,
- PrivilegedExtension = 0x02,
- PrefixedExtension = 0x04,
- WebGLDebugRendererInfoExtension = 0x08,
- };
-
- class ExtensionTracker {
- public:
- ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
- : m_privileged(flags & PrivilegedExtension)
- , m_draft(flags & DraftExtension)
- , m_prefixed(flags & PrefixedExtension)
- , m_webglDebugRendererInfo(flags & WebGLDebugRendererInfoExtension)
- , m_prefixes(prefixes)
- {
- }
-
- virtual ~ExtensionTracker()
- {
- }
-
- bool prefixed() const
- {
- return m_prefixed;
- }
-
- bool privileged() const
- {
- return m_privileged;
- }
-
- bool draft() const
- {
- return m_draft;
- }
-
- bool webglDebugRendererInfo() const
- {
- return m_webglDebugRendererInfo;
- }
-
- bool matchesNameWithPrefixes(const String&) const;
-
- virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext*) const = 0;
- virtual bool supported(WebGLRenderingContext*) const = 0;
- virtual const char* extensionName() const = 0;
- virtual void loseExtension() = 0;
-
- private:
- bool m_privileged;
- bool m_draft;
- bool m_prefixed;
- bool m_webglDebugRendererInfo;
- const char* const* m_prefixes;
- };
-
- template <typename T>
- class TypedExtensionTracker : public ExtensionTracker {
- public:
- TypedExtensionTracker(RefPtr<T>& extensionField, ExtensionFlags flags, const char* const* prefixes)
- : ExtensionTracker(flags, prefixes)
- , m_extensionField(extensionField)
- {
- }
-
- ~TypedExtensionTracker()
- {
- if (m_extensionField) {
- m_extensionField->lose(true);
- m_extensionField = 0;
- }
- }
-
- virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext* context) const
- {
- if (!m_extensionField)
- m_extensionField = T::create(context);
-
- return m_extensionField;
- }
-
- virtual bool supported(WebGLRenderingContext* context) const
- {
- return T::supported(context);
- }
-
- virtual const char* extensionName() const
- {
- return T::extensionName();
- }
-
- virtual void loseExtension()
- {
- if (m_extensionField) {
- m_extensionField->lose(false);
- if (m_extensionField->isLost())
- m_extensionField = 0;
- }
- }
-
- private:
- RefPtr<T>& m_extensionField;
- };
-
- Vector<ExtensionTracker*> m_extensions;
-
- template <typename T>
- void registerExtension(RefPtr<T>& extensionPtr, ExtensionFlags flags = ApprovedExtension, const char* const* prefixes = 0)
- {
- m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, flags, prefixes));
- }
-
- // Errors raised by synthesizeGLError() while the context is lost.
- Vector<GC3Denum> lost_context_errors_;
-
- // Helpers for getParameter and others
- WebGLGetInfo getBooleanParameter(GC3Denum);
- WebGLGetInfo getBooleanArrayParameter(GC3Denum);
- WebGLGetInfo getFloatParameter(GC3Denum);
- WebGLGetInfo getIntParameter(GC3Denum);
- WebGLGetInfo getUnsignedIntParameter(GC3Denum);
- WebGLGetInfo getWebGLFloatArrayParameter(GC3Denum);
- WebGLGetInfo getWebGLIntArrayParameter(GC3Denum);
-
- // Clear the backbuffer if it was composited since the last operation.
- // clearMask is set to the bitfield of any clear that would happen anyway at this time
- // and the function returns true if that clear is now unnecessary.
- bool clearIfComposited(GC3Dbitfield clearMask = 0);
-
- // Helper to restore state that clearing the framebuffer may destroy.
- void restoreStateAfterClear();
-
- void texImage2DBase(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&);
- void texImage2DImpl(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
- void texSubImage2DBase(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, const void* pixels, ExceptionState&);
- void texSubImage2DImpl(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Denum format, GC3Denum type, Image*, GraphicsContext3D::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
-
- void handleTextureCompleteness(const char*, bool);
- void createFallbackBlackTextures1x1();
-
- // Helper function for copyTex{Sub}Image, check whether the internalformat
- // and the color buffer format of the current bound framebuffer combination
- // is valid.
- bool isTexInternalFormatColorBufferCombinationValid(GC3Denum texInternalFormat,
- GC3Denum colorBufferFormat);
-
- // Helper function to get the bound framebuffer's color buffer format.
- GC3Denum boundFramebufferColorFormat();
-
- // Helper function to get the bound framebuffer's width.
- int boundFramebufferWidth();
-
- // Helper function to get the bound framebuffer's height.
- int boundFramebufferHeight();
-
- // Helper function to verify limits on the length of uniform and attribute locations.
- bool validateLocationLength(const char* functionName, const String&);
-
- // Helper function to check if size is non-negative.
- // Generate GL error and return false for negative inputs; otherwise, return true.
- bool validateSize(const char* functionName, GC3Dint x, GC3Dint y);
-
- // Helper function to check if all characters in the string belong to the
- // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
- bool validateString(const char* functionName, const String&);
-
- // Helper function to check target and texture bound to the target.
- // Generate GL errors and return 0 if target is invalid or texture bound is
- // null. Otherwise, return the texture bound to the target.
- WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
-
- // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type, GC3Dint level);
-
- // Helper function to check input level for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if level is invalid.
- bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
-
- enum TexFuncValidationFunctionType {
- NotTexSubImage2D,
- TexSubImage2D,
- };
-
- enum TexFuncValidationSourceType {
- SourceArrayBufferView,
- SourceImageData,
- SourceHTMLImageElement,
- SourceHTMLCanvasElement,
- SourceHTMLVideoElement,
- };
-
- // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
- // Otherwise, it would return quickly without doing other work.
- bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
- GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint xoffset, GC3Dint yoffset);
-
- // Helper function to check input width and height for functions {copy, compressed}Tex{Sub}Image.
- // Generates GL error and returns false if width or height is invalid.
- bool validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height);
-
- // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
- // Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncParameters(const char* functionName,
- TexFuncValidationFunctionType,
- GC3Denum target, GC3Dint level,
- GC3Denum internalformat,
- GC3Dsizei width, GC3Dsizei height, GC3Dint border,
- GC3Denum format, GC3Denum type);
-
- enum NullDisposition {
- NullAllowed,
- NullNotAllowed
- };
-
- // Helper function to validate that the given ArrayBufferView
- // is of the correct type and contains enough data for the texImage call.
- // Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncData(const char* functionName, GC3Dint level,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, GC3Denum type,
- ArrayBufferView* pixels,
- NullDisposition);
-
- // Helper function to validate a given texture format is settable as in
- // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
- // copyTexSubImage2D.
- // Generates GL error and returns false if the format is not settable.
- bool validateSettableTexFormat(const char* functionName, GC3Denum format);
-
- // Helper function to validate compressed texture data is correct size
- // for the given format and dimensions.
- bool validateCompressedTexFuncData(const char* functionName,
- GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels);
-
- // Helper function for validating compressed texture formats.
- bool validateCompressedTexFormat(GC3Denum format);
-
- // Helper function to validate compressed texture dimensions are valid for
- // the given format.
- bool validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType, GC3Denum target, GC3Dint level, GC3Dsizei width, GC3Dsizei height, GC3Denum format);
-
- // Helper function to validate compressed texture dimensions are valid for
- // the given format.
- bool validateCompressedTexSubDimensions(const char* functionName, GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
- GC3Dsizei width, GC3Dsizei height, GC3Denum format, WebGLTexture*);
-
- // Helper function to validate mode for draw{Arrays/Elements}.
- bool validateDrawMode(const char* functionName, GC3Denum);
-
- // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
- bool validateStencilSettings(const char* functionName);
-
- // Helper function to validate stencil or depth func.
- bool validateStencilOrDepthFunc(const char* functionName, GC3Denum);
-
- // Helper function for texParameterf and texParameteri.
- void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
-
- // Helper function to print GL errors to console.
- void printGLErrorToConsole(const String&);
-
- // Helper function to print warnings to console. Currently
- // used only to warn about use of obsolete functions.
- void printWarningToConsole(const String&);
-
- // Helper function to validate input parameters for framebuffer functions.
- // Generate GL error if parameters are illegal.
- bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment);
-
- // Helper function to validate blend equation mode.
- bool validateBlendEquation(const char* functionName, GC3Denum);
-
- // Helper function to validate blend func factors.
- bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
-
- // Helper function to validate a GL capability.
- bool validateCapability(const char* functionName, GC3Denum);
-
- // Helper function to validate input parameters for uniform functions.
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
-
- // Helper function to validate parameters for bufferData.
- // Return the current bound buffer to target, or 0 if parameters are invalid.
- WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
-
- // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
- bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&);
-
- // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
- bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&);
-
- // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
- bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&);
-
- // Helper function to validate drawArrays(Instanced) calls
- bool validateDrawArrays(const char* functionName, GC3Denum mode, GC3Dint first, GC3Dsizei count);
-
- // Helper function to validate drawElements(Instanced) calls
- bool validateDrawElements(const char* functionName, GC3Denum mode, GC3Dsizei count, GC3Denum type, long long offset);
-
- // Helper function to validate draw*Instanced calls
- bool validateDrawInstanced(const char* functionName, GC3Dsizei primcount);
-
- // Helper functions for vertexAttribNf{v}.
- void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
- void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
- void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize);
-
- // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
- // Return false if caller should return without further processing.
- bool deleteObject(WebGLObject*);
-
- // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
- // If the object has already been deleted, set deleted to true upon return.
- // Return false if caller should return without further processing.
- bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
-
- void dispatchContextLostEvent(Timer<WebGLRenderingContext>*);
- // Helper for restoration after context lost.
- void maybeRestoreContext(Timer<WebGLRenderingContext>*);
-
- // Determine if we are running privileged code in the browser, for example,
- // a Safari or Chrome extension.
- bool allowPrivilegedExtensions() const;
-
- // Determine if WEBGL_debug_renderer_info extension is enabled. For the
- // moment it can be enabled either through a chromium finch experiment
- // or for privileged code in the browser.
- bool allowWebGLDebugRendererInfo() const;
-
- enum ConsoleDisplayPreference {
- DisplayInConsole,
- DontDisplayInConsole
- };
-
- // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message
- // to the JavaScript console.
- void synthesizeGLError(GC3Denum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
- void emitGLWarning(const char* function, const char* reason);
-
- String ensureNotNull(const String&) const;
-
- // Enable or disable stencil test based on user setting and
- // whether the current FBO has a stencil buffer.
- void applyStencilTest();
-
- // Helper for enabling or disabling a capability.
- void enableOrDisable(GC3Denum capability, bool enable);
-
- // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
- IntSize clampedCanvasSize();
-
- // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
- // Later, return the cached value.
- GC3Dint maxDrawBuffers();
- GC3Dint maxColorAttachments();
-
- void setBackDrawBuffer(GC3Denum);
-
- void restoreCurrentFramebuffer();
- void restoreCurrentTexture2D();
-
- virtual void multisamplingChanged(bool);
-
- void findNewMaxEnabledAttribIndex();
- void findNewMaxNonDefaultTextureUnit();
-
- friend class WebGLStateRestorer;
- friend class WebGLRenderingContextEvictionManager;
-
- static Vector<WebGLRenderingContext*>& activeContexts();
- static Vector<WebGLRenderingContext*>& forciblyEvictedContexts();
-
- static void activateContext(WebGLRenderingContext*);
- static void deactivateContext(WebGLRenderingContext*, bool addToInactiveList);
- static void willDestroyContext(WebGLRenderingContext*);
- static void forciblyLoseOldestContext(const String& reason);
- // Return the least recently used context's position in the active context vector.
- // If the vector is empty, return the maximum allowed active context number.
- static size_t oldestContextIndex();
- static IntSize oldestContextSize();
};
-DEFINE_TYPE_CASTS(WebGLRenderingContext, CanvasRenderingContext, context, context->is3d(), context.is3d());
+DEFINE_TYPE_CASTS(WebGLRenderingContext, CanvasRenderingContext, context,
+ context->is3d() && WebGLRenderingContextBase::getWebGLVersion(context) == 1,
+ context.is3d() && WebGLRenderingContextBase::getWebGLVersion(&context) == 1);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl
index a006bae1c53..ce2d4837ff3 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.idl
@@ -23,640 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-typedef unsigned long GLenum;
-typedef boolean GLboolean;
-typedef unsigned long GLbitfield;
-typedef byte GLbyte; /* 'byte' should be a signed 8 bit type. */
-typedef short GLshort;
-typedef long GLint;
-typedef long GLsizei;
-typedef long long GLintptr;
-typedef long long GLsizeiptr;
-typedef octet GLubyte; /* 'octet' should be an unsigned 8 bit type. */
-typedef unsigned short GLushort;
-typedef unsigned long GLuint;
-typedef /*unrestricted*/ float GLfloat;
-typedef /*unrestricted*/ float GLclampf;
+// http://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContext
[
- DoNotCheckConstants
-] interface WebGLRenderingContext : CanvasRenderingContext {
-
- /* ClearBufferMask */
- const GLenum DEPTH_BUFFER_BIT = 0x00000100;
- const GLenum STENCIL_BUFFER_BIT = 0x00000400;
- const GLenum COLOR_BUFFER_BIT = 0x00004000;
-
- /* BeginMode */
- const GLenum POINTS = 0x0000;
- const GLenum LINES = 0x0001;
- const GLenum LINE_LOOP = 0x0002;
- const GLenum LINE_STRIP = 0x0003;
- const GLenum TRIANGLES = 0x0004;
- const GLenum TRIANGLE_STRIP = 0x0005;
- const GLenum TRIANGLE_FAN = 0x0006;
-
- /* AlphaFunction (not supported in ES20) */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* BlendingFactorDest */
- const GLenum ZERO = 0;
- const GLenum ONE = 1;
- const GLenum SRC_COLOR = 0x0300;
- const GLenum ONE_MINUS_SRC_COLOR = 0x0301;
- const GLenum SRC_ALPHA = 0x0302;
- const GLenum ONE_MINUS_SRC_ALPHA = 0x0303;
- const GLenum DST_ALPHA = 0x0304;
- const GLenum ONE_MINUS_DST_ALPHA = 0x0305;
-
- /* BlendingFactorSrc */
- /* ZERO */
- /* ONE */
- const GLenum DST_COLOR = 0x0306;
- const GLenum ONE_MINUS_DST_COLOR = 0x0307;
- const GLenum SRC_ALPHA_SATURATE = 0x0308;
- /* SRC_ALPHA */
- /* ONE_MINUS_SRC_ALPHA */
- /* DST_ALPHA */
- /* ONE_MINUS_DST_ALPHA */
-
- /* BlendEquationSeparate */
- const GLenum FUNC_ADD = 0x8006;
- const GLenum BLEND_EQUATION = 0x8009;
- const GLenum BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
- const GLenum BLEND_EQUATION_ALPHA = 0x883D;
-
- /* BlendSubtract */
- const GLenum FUNC_SUBTRACT = 0x800A;
- const GLenum FUNC_REVERSE_SUBTRACT = 0x800B;
-
- /* Separate Blend Functions */
- const GLenum BLEND_DST_RGB = 0x80C8;
- const GLenum BLEND_SRC_RGB = 0x80C9;
- const GLenum BLEND_DST_ALPHA = 0x80CA;
- const GLenum BLEND_SRC_ALPHA = 0x80CB;
- const GLenum CONSTANT_COLOR = 0x8001;
- const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002;
- const GLenum CONSTANT_ALPHA = 0x8003;
- const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004;
- const GLenum BLEND_COLOR = 0x8005;
-
- /* Buffer Objects */
- const GLenum ARRAY_BUFFER = 0x8892;
- const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;
- const GLenum ARRAY_BUFFER_BINDING = 0x8894;
- const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
-
- const GLenum STREAM_DRAW = 0x88E0;
- const GLenum STATIC_DRAW = 0x88E4;
- const GLenum DYNAMIC_DRAW = 0x88E8;
-
- const GLenum BUFFER_SIZE = 0x8764;
- const GLenum BUFFER_USAGE = 0x8765;
-
- const GLenum CURRENT_VERTEX_ATTRIB = 0x8626;
-
- /* CullFaceMode */
- const GLenum FRONT = 0x0404;
- const GLenum BACK = 0x0405;
- const GLenum FRONT_AND_BACK = 0x0408;
-
- /* DepthFunction */
- /* NEVER */
- /* LESS */
- /* EQUAL */
- /* LEQUAL */
- /* GREATER */
- /* NOTEQUAL */
- /* GEQUAL */
- /* ALWAYS */
-
- /* EnableCap */
- const GLenum TEXTURE_2D = 0x0DE1;
- const GLenum CULL_FACE = 0x0B44;
- const GLenum BLEND = 0x0BE2;
- const GLenum DITHER = 0x0BD0;
- const GLenum STENCIL_TEST = 0x0B90;
- const GLenum DEPTH_TEST = 0x0B71;
- const GLenum SCISSOR_TEST = 0x0C11;
- const GLenum POLYGON_OFFSET_FILL = 0x8037;
- const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
- const GLenum SAMPLE_COVERAGE = 0x80A0;
-
- /* ErrorCode */
- const GLenum NO_ERROR = 0;
- const GLenum INVALID_ENUM = 0x0500;
- const GLenum INVALID_VALUE = 0x0501;
- const GLenum INVALID_OPERATION = 0x0502;
- const GLenum OUT_OF_MEMORY = 0x0505;
-
- /* FrontFaceDirection */
- const GLenum CW = 0x0900;
- const GLenum CCW = 0x0901;
-
- /* GetPName */
- const GLenum LINE_WIDTH = 0x0B21;
- const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D;
- const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E;
- const GLenum CULL_FACE_MODE = 0x0B45;
- const GLenum FRONT_FACE = 0x0B46;
- const GLenum DEPTH_RANGE = 0x0B70;
- const GLenum DEPTH_WRITEMASK = 0x0B72;
- const GLenum DEPTH_CLEAR_VALUE = 0x0B73;
- const GLenum DEPTH_FUNC = 0x0B74;
- const GLenum STENCIL_CLEAR_VALUE = 0x0B91;
- const GLenum STENCIL_FUNC = 0x0B92;
- const GLenum STENCIL_FAIL = 0x0B94;
- const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95;
- const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96;
- const GLenum STENCIL_REF = 0x0B97;
- const GLenum STENCIL_VALUE_MASK = 0x0B93;
- const GLenum STENCIL_WRITEMASK = 0x0B98;
- const GLenum STENCIL_BACK_FUNC = 0x8800;
- const GLenum STENCIL_BACK_FAIL = 0x8801;
- const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
- const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
- const GLenum STENCIL_BACK_REF = 0x8CA3;
- const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4;
- const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5;
- const GLenum VIEWPORT = 0x0BA2;
- const GLenum SCISSOR_BOX = 0x0C10;
- /* SCISSOR_TEST */
- const GLenum COLOR_CLEAR_VALUE = 0x0C22;
- const GLenum COLOR_WRITEMASK = 0x0C23;
- const GLenum UNPACK_ALIGNMENT = 0x0CF5;
- const GLenum PACK_ALIGNMENT = 0x0D05;
- const GLenum MAX_TEXTURE_SIZE = 0x0D33;
- const GLenum MAX_VIEWPORT_DIMS = 0x0D3A;
- const GLenum SUBPIXEL_BITS = 0x0D50;
- const GLenum RED_BITS = 0x0D52;
- const GLenum GREEN_BITS = 0x0D53;
- const GLenum BLUE_BITS = 0x0D54;
- const GLenum ALPHA_BITS = 0x0D55;
- const GLenum DEPTH_BITS = 0x0D56;
- const GLenum STENCIL_BITS = 0x0D57;
- const GLenum POLYGON_OFFSET_UNITS = 0x2A00;
- /* POLYGON_OFFSET_FILL */
- const GLenum POLYGON_OFFSET_FACTOR = 0x8038;
- const GLenum TEXTURE_BINDING_2D = 0x8069;
- const GLenum SAMPLE_BUFFERS = 0x80A8;
- const GLenum SAMPLES = 0x80A9;
- const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA;
- const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB;
-
- /* GetTextureParameter */
- /* TEXTURE_MAG_FILTER */
- /* TEXTURE_MIN_FILTER */
- /* TEXTURE_WRAP_S */
- /* TEXTURE_WRAP_T */
-
- const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3;
-
- /* HintMode */
- const GLenum DONT_CARE = 0x1100;
- const GLenum FASTEST = 0x1101;
- const GLenum NICEST = 0x1102;
-
- /* HintTarget */
- const GLenum GENERATE_MIPMAP_HINT = 0x8192;
-
- /* DataType */
- const GLenum BYTE = 0x1400;
- const GLenum UNSIGNED_BYTE = 0x1401;
- const GLenum SHORT = 0x1402;
- const GLenum UNSIGNED_SHORT = 0x1403;
- const GLenum INT = 0x1404;
- const GLenum UNSIGNED_INT = 0x1405;
- const GLenum FLOAT = 0x1406;
-
- /* PixelFormat */
- const GLenum DEPTH_COMPONENT = 0x1902;
- const GLenum ALPHA = 0x1906;
- const GLenum RGB = 0x1907;
- const GLenum RGBA = 0x1908;
- const GLenum LUMINANCE = 0x1909;
- const GLenum LUMINANCE_ALPHA = 0x190A;
-
- /* PixelType */
- /* UNSIGNED_BYTE */
- const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033;
- const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034;
- const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363;
-
- /* Shaders */
- const GLenum FRAGMENT_SHADER = 0x8B30;
- const GLenum VERTEX_SHADER = 0x8B31;
- const GLenum MAX_VERTEX_ATTRIBS = 0x8869;
- const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
- const GLenum MAX_VARYING_VECTORS = 0x8DFC;
- const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
- const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
- const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872;
- const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
- const GLenum SHADER_TYPE = 0x8B4F;
- const GLenum DELETE_STATUS = 0x8B80;
- const GLenum LINK_STATUS = 0x8B82;
- const GLenum VALIDATE_STATUS = 0x8B83;
- const GLenum ATTACHED_SHADERS = 0x8B85;
- const GLenum ACTIVE_UNIFORMS = 0x8B86;
- const GLenum ACTIVE_ATTRIBUTES = 0x8B89;
- const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C;
- const GLenum CURRENT_PROGRAM = 0x8B8D;
-
- /* StencilFunction */
- const GLenum NEVER = 0x0200;
- const GLenum LESS = 0x0201;
- const GLenum EQUAL = 0x0202;
- const GLenum LEQUAL = 0x0203;
- const GLenum GREATER = 0x0204;
- const GLenum NOTEQUAL = 0x0205;
- const GLenum GEQUAL = 0x0206;
- const GLenum ALWAYS = 0x0207;
-
- /* StencilOp */
- /* ZERO */
- const GLenum KEEP = 0x1E00;
- const GLenum REPLACE = 0x1E01;
- const GLenum INCR = 0x1E02;
- const GLenum DECR = 0x1E03;
- const GLenum INVERT = 0x150A;
- const GLenum INCR_WRAP = 0x8507;
- const GLenum DECR_WRAP = 0x8508;
-
- /* StringName */
- const GLenum VENDOR = 0x1F00;
- const GLenum RENDERER = 0x1F01;
- const GLenum VERSION = 0x1F02;
-
- /* TextureMagFilter */
- const GLenum NEAREST = 0x2600;
- const GLenum LINEAR = 0x2601;
-
- /* TextureMinFilter */
- /* NEAREST */
- /* LINEAR */
- const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;
- const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;
- const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;
- const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;
-
- /* TextureParameterName */
- const GLenum TEXTURE_MAG_FILTER = 0x2800;
- const GLenum TEXTURE_MIN_FILTER = 0x2801;
- const GLenum TEXTURE_WRAP_S = 0x2802;
- const GLenum TEXTURE_WRAP_T = 0x2803;
-
- /* TextureTarget */
- /* TEXTURE_2D */
- const GLenum TEXTURE = 0x1702;
-
- const GLenum TEXTURE_CUBE_MAP = 0x8513;
- const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
- const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
- const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
- const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
-
- /* TextureUnit */
- const GLenum TEXTURE0 = 0x84C0;
- const GLenum TEXTURE1 = 0x84C1;
- const GLenum TEXTURE2 = 0x84C2;
- const GLenum TEXTURE3 = 0x84C3;
- const GLenum TEXTURE4 = 0x84C4;
- const GLenum TEXTURE5 = 0x84C5;
- const GLenum TEXTURE6 = 0x84C6;
- const GLenum TEXTURE7 = 0x84C7;
- const GLenum TEXTURE8 = 0x84C8;
- const GLenum TEXTURE9 = 0x84C9;
- const GLenum TEXTURE10 = 0x84CA;
- const GLenum TEXTURE11 = 0x84CB;
- const GLenum TEXTURE12 = 0x84CC;
- const GLenum TEXTURE13 = 0x84CD;
- const GLenum TEXTURE14 = 0x84CE;
- const GLenum TEXTURE15 = 0x84CF;
- const GLenum TEXTURE16 = 0x84D0;
- const GLenum TEXTURE17 = 0x84D1;
- const GLenum TEXTURE18 = 0x84D2;
- const GLenum TEXTURE19 = 0x84D3;
- const GLenum TEXTURE20 = 0x84D4;
- const GLenum TEXTURE21 = 0x84D5;
- const GLenum TEXTURE22 = 0x84D6;
- const GLenum TEXTURE23 = 0x84D7;
- const GLenum TEXTURE24 = 0x84D8;
- const GLenum TEXTURE25 = 0x84D9;
- const GLenum TEXTURE26 = 0x84DA;
- const GLenum TEXTURE27 = 0x84DB;
- const GLenum TEXTURE28 = 0x84DC;
- const GLenum TEXTURE29 = 0x84DD;
- const GLenum TEXTURE30 = 0x84DE;
- const GLenum TEXTURE31 = 0x84DF;
- const GLenum ACTIVE_TEXTURE = 0x84E0;
-
- /* TextureWrapMode */
- const GLenum REPEAT = 0x2901;
- const GLenum CLAMP_TO_EDGE = 0x812F;
- const GLenum MIRRORED_REPEAT = 0x8370;
-
- /* Uniform Types */
- const GLenum FLOAT_VEC2 = 0x8B50;
- const GLenum FLOAT_VEC3 = 0x8B51;
- const GLenum FLOAT_VEC4 = 0x8B52;
- const GLenum INT_VEC2 = 0x8B53;
- const GLenum INT_VEC3 = 0x8B54;
- const GLenum INT_VEC4 = 0x8B55;
- const GLenum BOOL = 0x8B56;
- const GLenum BOOL_VEC2 = 0x8B57;
- const GLenum BOOL_VEC3 = 0x8B58;
- const GLenum BOOL_VEC4 = 0x8B59;
- const GLenum FLOAT_MAT2 = 0x8B5A;
- const GLenum FLOAT_MAT3 = 0x8B5B;
- const GLenum FLOAT_MAT4 = 0x8B5C;
- const GLenum SAMPLER_2D = 0x8B5E;
- const GLenum SAMPLER_CUBE = 0x8B60;
-
- /* Vertex Arrays */
- const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
- const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
- const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
- const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
- const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
- const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
- const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
-
- /* Shader Source */
- const GLenum COMPILE_STATUS = 0x8B81;
-
- /* Shader Precision-Specified Types */
- const GLenum LOW_FLOAT = 0x8DF0;
- const GLenum MEDIUM_FLOAT = 0x8DF1;
- const GLenum HIGH_FLOAT = 0x8DF2;
- const GLenum LOW_INT = 0x8DF3;
- const GLenum MEDIUM_INT = 0x8DF4;
- const GLenum HIGH_INT = 0x8DF5;
-
- /* Framebuffer Object. */
- const GLenum FRAMEBUFFER = 0x8D40;
- const GLenum RENDERBUFFER = 0x8D41;
-
- const GLenum RGBA4 = 0x8056;
- const GLenum RGB5_A1 = 0x8057;
- const GLenum RGB565 = 0x8D62;
- const GLenum DEPTH_COMPONENT16 = 0x81A5;
- const GLenum STENCIL_INDEX = 0x1901;
- const GLenum STENCIL_INDEX8 = 0x8D48;
- const GLenum DEPTH_STENCIL = 0x84F9;
-
- const GLenum RENDERBUFFER_WIDTH = 0x8D42;
- const GLenum RENDERBUFFER_HEIGHT = 0x8D43;
- const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
- const GLenum RENDERBUFFER_RED_SIZE = 0x8D50;
- const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51;
- const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52;
- const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53;
- const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54;
- const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55;
-
- const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
- const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
- const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
-
- const GLenum COLOR_ATTACHMENT0 = 0x8CE0;
- const GLenum DEPTH_ATTACHMENT = 0x8D00;
- const GLenum STENCIL_ATTACHMENT = 0x8D20;
- const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
-
- const GLenum NONE = 0;
-
- const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5;
- const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
- const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
- const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
- const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
-
- const GLenum FRAMEBUFFER_BINDING = 0x8CA6;
- const GLenum RENDERBUFFER_BINDING = 0x8CA7;
- const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8;
-
- const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506;
-
- /* WebGL-specific enums */
- const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240;
- const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
- const GLenum CONTEXT_LOST_WEBGL = 0x9242;
- const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
- const GLenum BROWSER_DEFAULT_WEBGL = 0x9244;
-
- readonly attribute GLsizei drawingBufferWidth;
- readonly attribute GLsizei drawingBufferHeight;
-
- [StrictTypeChecking] void activeTexture(GLenum texture);
- [StrictTypeChecking] void attachShader(WebGLProgram program, WebGLShader shader);
- [StrictTypeChecking] void bindAttribLocation(WebGLProgram program, GLuint index, DOMString name);
- [StrictTypeChecking] void bindBuffer(GLenum target, WebGLBuffer buffer);
- [StrictTypeChecking] void bindFramebuffer(GLenum target, WebGLFramebuffer framebuffer);
- [StrictTypeChecking] void bindRenderbuffer(GLenum target, WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] void bindTexture(GLenum target, WebGLTexture texture);
- [StrictTypeChecking] void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- [StrictTypeChecking] void blendEquation(GLenum mode);
- [StrictTypeChecking] void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
- [StrictTypeChecking] void blendFunc(GLenum sfactor, GLenum dfactor);
- [StrictTypeChecking] void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
- [StrictTypeChecking] void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
- [StrictTypeChecking] void bufferData(GLenum target, ArrayBufferView? data, GLenum usage);
- [StrictTypeChecking] void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
- [StrictTypeChecking] void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
- [StrictTypeChecking] void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView? data);
-
- [StrictTypeChecking] GLenum checkFramebufferStatus(GLenum target);
- [StrictTypeChecking] void clear(GLbitfield mask);
- [StrictTypeChecking] void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
- [StrictTypeChecking] void clearDepth(GLclampf depth);
- [StrictTypeChecking] void clearStencil(GLint s);
- [StrictTypeChecking] void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
- [StrictTypeChecking] void compileShader(WebGLShader shader);
-
- [StrictTypeChecking] void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
- GLsizei width, GLsizei height, GLint border, ArrayBufferView data);
- [StrictTypeChecking] void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height, GLenum format, ArrayBufferView data);
-
- [StrictTypeChecking] void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
- [StrictTypeChecking] void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-
- [StrictTypeChecking] WebGLBuffer createBuffer();
- [StrictTypeChecking] WebGLFramebuffer createFramebuffer();
- [StrictTypeChecking] WebGLProgram createProgram();
- [StrictTypeChecking] WebGLRenderbuffer createRenderbuffer();
- [StrictTypeChecking] WebGLShader createShader(GLenum type);
- [StrictTypeChecking] WebGLTexture createTexture();
-
- [StrictTypeChecking] void cullFace(GLenum mode);
-
- [StrictTypeChecking] void deleteBuffer(WebGLBuffer buffer);
- [StrictTypeChecking] void deleteFramebuffer(WebGLFramebuffer framebuffer);
- [StrictTypeChecking] void deleteProgram(WebGLProgram program);
- [StrictTypeChecking] void deleteRenderbuffer(WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] void deleteShader(WebGLShader shader);
- [StrictTypeChecking] void deleteTexture(WebGLTexture texture);
-
- [StrictTypeChecking] void depthFunc(GLenum func);
- [StrictTypeChecking] void depthMask(GLboolean flag);
- [StrictTypeChecking] void depthRange(GLclampf zNear, GLclampf zFar);
- [StrictTypeChecking] void detachShader(WebGLProgram program, WebGLShader shader);
- [StrictTypeChecking] void disable(GLenum cap);
- [StrictTypeChecking] void disableVertexAttribArray(GLuint index);
- [StrictTypeChecking] void drawArrays(GLenum mode, GLint first, GLsizei count);
- [StrictTypeChecking] void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
-
- [StrictTypeChecking] void enable(GLenum cap);
- [StrictTypeChecking] void enableVertexAttribArray(GLuint index);
- [StrictTypeChecking] void finish();
- [StrictTypeChecking] void flush();
- [StrictTypeChecking] void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture texture, GLint level);
- [StrictTypeChecking] void frontFace(GLenum mode);
- [StrictTypeChecking] void generateMipmap(GLenum target);
-
- [StrictTypeChecking] WebGLActiveInfo getActiveAttrib(WebGLProgram program, GLuint index);
- [StrictTypeChecking] WebGLActiveInfo getActiveUniform(WebGLProgram program, GLuint index);
-
- [StrictTypeChecking, Custom] void getAttachedShaders(WebGLProgram program);
-
- [StrictTypeChecking] GLint getAttribLocation(WebGLProgram program, DOMString name);
-
- [StrictTypeChecking, Custom] any getBufferParameter(GLenum target, GLenum pname);
-
- [StrictTypeChecking] WebGLContextAttributes getContextAttributes();
-
- [StrictTypeChecking] GLenum getError();
-
- // object getExtension(DOMString name);
- [StrictTypeChecking, Custom] any getExtension(DOMString name);
-
- [StrictTypeChecking, Custom] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
- [StrictTypeChecking, Custom] any getParameter(GLenum pname);
- [StrictTypeChecking, Custom] any getProgramParameter(WebGLProgram program, GLenum pname);
- [StrictTypeChecking, TreatReturnedNullStringAs=Null] DOMString getProgramInfoLog(WebGLProgram program);
- [StrictTypeChecking, Custom] any getRenderbufferParameter(GLenum target, GLenum pname);
- [StrictTypeChecking, Custom] any getShaderParameter(WebGLShader shader, GLenum pname);
-
- [StrictTypeChecking, TreatReturnedNullStringAs=Null] DOMString getShaderInfoLog(WebGLShader shader);
-
- [StrictTypeChecking] WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
-
- [StrictTypeChecking, TreatReturnedNullStringAs=Null] DOMString getShaderSource(WebGLShader shader);
-
- [StrictTypeChecking, Custom] sequence<DOMString> getSupportedExtensions();
-
- [StrictTypeChecking, Custom] any getTexParameter(GLenum target, GLenum pname);
-
- [StrictTypeChecking, Custom] any getUniform(WebGLProgram program, WebGLUniformLocation location);
-
- [StrictTypeChecking] WebGLUniformLocation getUniformLocation(WebGLProgram program, DOMString name);
-
- [StrictTypeChecking, Custom] any getVertexAttrib(GLuint index, GLenum pname);
-
- [StrictTypeChecking] GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
-
- [StrictTypeChecking] void hint(GLenum target, GLenum mode);
- [StrictTypeChecking] GLboolean isBuffer(WebGLBuffer buffer);
- [StrictTypeChecking] GLboolean isContextLost();
- [StrictTypeChecking] GLboolean isEnabled(GLenum cap);
- [StrictTypeChecking] GLboolean isFramebuffer(WebGLFramebuffer framebuffer);
- [StrictTypeChecking] GLboolean isProgram(WebGLProgram program);
- [StrictTypeChecking] GLboolean isRenderbuffer(WebGLRenderbuffer renderbuffer);
- [StrictTypeChecking] GLboolean isShader(WebGLShader shader);
- [StrictTypeChecking] GLboolean isTexture(WebGLTexture texture);
- [StrictTypeChecking] void lineWidth(GLfloat width);
- [StrictTypeChecking] void linkProgram(WebGLProgram program);
- [StrictTypeChecking] void pixelStorei(GLenum pname, GLint param);
- [StrictTypeChecking] void polygonOffset(GLfloat factor, GLfloat units);
-
- [StrictTypeChecking] void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView pixels);
-
- [StrictTypeChecking] void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
- [StrictTypeChecking] void sampleCoverage(GLclampf value, GLboolean invert);
- [StrictTypeChecking] void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
- [StrictTypeChecking] void shaderSource(WebGLShader shader, DOMString string);
- [StrictTypeChecking] void stencilFunc(GLenum func, GLint ref, GLuint mask);
- [StrictTypeChecking] void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
- [StrictTypeChecking] void stencilMask(GLuint mask);
- [StrictTypeChecking] void stencilMaskSeparate(GLenum face, GLuint mask);
- [StrictTypeChecking] void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
- [StrictTypeChecking] void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-
- [StrictTypeChecking] void texParameterf(GLenum target, GLenum pname, GLfloat param);
- [StrictTypeChecking] void texParameteri(GLenum target, GLenum pname, GLint param);
-
- // Supported forms:
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
- GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, ImageData? pixels);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLImageElement? image);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLCanvasElement? canvas);
- [StrictTypeChecking, RaisesException] void texImage2D(GLenum target, GLint level, GLenum internalformat,
- GLenum format, GLenum type, HTMLVideoElement? video);
-
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type, ArrayBufferView? pixels);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, ImageData? pixels);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLImageElement? image);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLCanvasElement? canvas);
- [StrictTypeChecking, RaisesException] void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
- GLenum format, GLenum type, HTMLVideoElement? video);
-
- [StrictTypeChecking] void uniform1f(WebGLUniformLocation location, GLfloat x);
- [StrictTypeChecking, Custom] void uniform1fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking] void uniform1i(WebGLUniformLocation location, GLint x);
- [StrictTypeChecking, Custom] void uniform1iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking] void uniform2f(WebGLUniformLocation location, GLfloat x, GLfloat y);
- [StrictTypeChecking, Custom] void uniform2fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking] void uniform2i(WebGLUniformLocation location, GLint x, GLint y);
- [StrictTypeChecking, Custom] void uniform2iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking] void uniform3f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z);
- [StrictTypeChecking, Custom] void uniform3fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking] void uniform3i(WebGLUniformLocation location, GLint x, GLint y, GLint z);
- [StrictTypeChecking, Custom] void uniform3iv(WebGLUniformLocation location, Int32Array v);
- [StrictTypeChecking] void uniform4f(WebGLUniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- [StrictTypeChecking, Custom] void uniform4fv(WebGLUniformLocation location, Float32Array v);
- [StrictTypeChecking] void uniform4i(WebGLUniformLocation location, GLint x, GLint y, GLint z, GLint w);
- [StrictTypeChecking, Custom] void uniform4iv(WebGLUniformLocation location, Int32Array v);
-
- [StrictTypeChecking, Custom] void uniformMatrix2fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
- [StrictTypeChecking, Custom] void uniformMatrix3fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
- [StrictTypeChecking, Custom] void uniformMatrix4fv(WebGLUniformLocation location, GLboolean transpose, Float32Array array);
-
- [StrictTypeChecking] void useProgram(WebGLProgram program);
- [StrictTypeChecking] void validateProgram(WebGLProgram program);
-
- [StrictTypeChecking] void vertexAttrib1f(GLuint indx, GLfloat x);
- [StrictTypeChecking, Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
- [StrictTypeChecking, Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
- [StrictTypeChecking, Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
- [StrictTypeChecking, Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
- [StrictTypeChecking] void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
- GLsizei stride, GLintptr offset);
-
- [StrictTypeChecking] void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
-};
+ DoNotCheckConstants,
+ TypeChecking=Interface|Nullable,
+ WillBeGarbageCollected,
+] interface WebGLRenderingContext { };
+WebGLRenderingContext implements WebGLRenderingContextBase;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp
new file mode 100644
index 00000000000..b587a6899c1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp
@@ -0,0 +1,5728 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
+
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/fetch/ImageResource.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLCanvasElement.h"
+#include "core/html/HTMLImageElement.h"
+#include "core/html/HTMLVideoElement.h"
+#include "core/html/ImageData.h"
+#include "core/html/canvas/ANGLEInstancedArrays.h"
+#include "core/html/canvas/EXTBlendMinMax.h"
+#include "core/html/canvas/EXTFragDepth.h"
+#include "core/html/canvas/EXTShaderTextureLOD.h"
+#include "core/html/canvas/EXTTextureFilterAnisotropic.h"
+#include "core/html/canvas/OESElementIndexUint.h"
+#include "core/html/canvas/OESStandardDerivatives.h"
+#include "core/html/canvas/OESTextureFloat.h"
+#include "core/html/canvas/OESTextureFloatLinear.h"
+#include "core/html/canvas/OESTextureHalfFloat.h"
+#include "core/html/canvas/OESTextureHalfFloatLinear.h"
+#include "core/html/canvas/OESVertexArrayObject.h"
+#include "core/html/canvas/WebGLActiveInfo.h"
+#include "core/html/canvas/WebGLBuffer.h"
+#include "core/html/canvas/WebGLCompressedTextureATC.h"
+#include "core/html/canvas/WebGLCompressedTextureETC1.h"
+#include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
+#include "core/html/canvas/WebGLCompressedTextureS3TC.h"
+#include "core/html/canvas/WebGLContextAttributes.h"
+#include "core/html/canvas/WebGLContextEvent.h"
+#include "core/html/canvas/WebGLContextGroup.h"
+#include "core/html/canvas/WebGLDebugRendererInfo.h"
+#include "core/html/canvas/WebGLDebugShaders.h"
+#include "core/html/canvas/WebGLDepthTexture.h"
+#include "core/html/canvas/WebGLDrawBuffers.h"
+#include "core/html/canvas/WebGLFramebuffer.h"
+#include "core/html/canvas/WebGLLoseContext.h"
+#include "core/html/canvas/WebGLProgram.h"
+#include "core/html/canvas/WebGLRenderbuffer.h"
+#include "core/html/canvas/WebGLShader.h"
+#include "core/html/canvas/WebGLShaderPrecisionFormat.h"
+#include "core/html/canvas/WebGLTexture.h"
+#include "core/html/canvas/WebGLUniformLocation.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "core/rendering/RenderBox.h"
+#include "platform/CheckedInt.h"
+#include "platform/NotImplemented.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/geometry/IntSize.h"
+#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/UnacceleratedImageBufferSurface.h"
+#include "platform/graphics/gpu/DrawingBuffer.h"
+#include "public/platform/Platform.h"
+
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Uint32Array.h"
+#include "wtf/text/StringBuilder.h"
+
+namespace WebCore {
+
+const double secondsBetweenRestoreAttempts = 1.0;
+const int maxGLErrorsAllowedToConsole = 256;
+const unsigned maxGLActiveContexts = 16;
+
+Vector<WebGLRenderingContextBase*>& WebGLRenderingContextBase::activeContexts()
+{
+ DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContextBase*>, activeContexts, ());
+ return activeContexts;
+}
+
+Vector<WebGLRenderingContextBase*>& WebGLRenderingContextBase::forciblyEvictedContexts()
+{
+ DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContextBase*>, forciblyEvictedContexts, ());
+ return forciblyEvictedContexts;
+}
+
+void WebGLRenderingContextBase::forciblyLoseOldestContext(const String& reason)
+{
+ size_t candidateID = oldestContextIndex();
+ if (candidateID >= activeContexts().size())
+ return;
+
+ WebGLRenderingContextBase* candidate = activeContexts()[candidateID];
+
+ activeContexts().remove(candidateID);
+
+ candidate->printWarningToConsole(reason);
+ InspectorInstrumentation::didFireWebGLWarning(candidate->canvas());
+
+ // This will call deactivateContext once the context has actually been lost.
+ candidate->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext);
+}
+
+size_t WebGLRenderingContextBase::oldestContextIndex()
+{
+ if (!activeContexts().size())
+ return maxGLActiveContexts;
+
+ WebGLRenderingContextBase* candidate = activeContexts().first();
+ blink::WebGraphicsContext3D* candidateWGC3D = candidate->isContextLost() ? 0 : candidate->webContext();
+ size_t candidateID = 0;
+ for (size_t ii = 1; ii < activeContexts().size(); ++ii) {
+ WebGLRenderingContextBase* context = activeContexts()[ii];
+ blink::WebGraphicsContext3D* contextWGC3D = context->isContextLost() ? 0 : context->webContext();
+ if (contextWGC3D && candidateWGC3D && contextWGC3D->lastFlushID() < candidateWGC3D->lastFlushID()) {
+ candidate = context;
+ candidateID = ii;
+ }
+ }
+
+ return candidateID;
+}
+
+IntSize WebGLRenderingContextBase::oldestContextSize()
+{
+ IntSize size;
+
+ size_t candidateID = oldestContextIndex();
+ if (candidateID < activeContexts().size()) {
+ WebGLRenderingContextBase* candidate = activeContexts()[candidateID];
+ size.setWidth(candidate->drawingBufferWidth());
+ size.setHeight(candidate->drawingBufferHeight());
+ }
+
+ return size;
+}
+
+void WebGLRenderingContextBase::activateContext(WebGLRenderingContextBase* context)
+{
+ unsigned removedContexts = 0;
+ while (activeContexts().size() >= maxGLActiveContexts && removedContexts < maxGLActiveContexts) {
+ forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Oldest context will be lost.");
+ removedContexts++;
+ }
+
+ if (!activeContexts().contains(context))
+ activeContexts().append(context);
+}
+
+void WebGLRenderingContextBase::deactivateContext(WebGLRenderingContextBase* context, bool addToEvictedList)
+{
+ size_t position = activeContexts().find(context);
+ if (position != WTF::kNotFound)
+ activeContexts().remove(position);
+
+ if (addToEvictedList && !forciblyEvictedContexts().contains(context))
+ forciblyEvictedContexts().append(context);
+}
+
+void WebGLRenderingContextBase::willDestroyContext(WebGLRenderingContextBase* context)
+{
+ size_t position = forciblyEvictedContexts().find(context);
+ if (position != WTF::kNotFound)
+ forciblyEvictedContexts().remove(position);
+
+ deactivateContext(context, false);
+
+ // Try to re-enable the oldest inactive contexts.
+ while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContexts().size()) {
+ WebGLRenderingContextBase* evictedContext = forciblyEvictedContexts().first();
+ if (!evictedContext->m_restoreAllowed) {
+ forciblyEvictedContexts().remove(0);
+ continue;
+ }
+
+ IntSize desiredSize = DrawingBuffer::adjustSize(evictedContext->clampedCanvasSize(), IntSize(), evictedContext->m_maxTextureSize);
+
+ // If there's room in the pixel budget for this context, restore it.
+ if (!desiredSize.isEmpty()) {
+ forciblyEvictedContexts().remove(0);
+ evictedContext->forceRestoreContext();
+ activeContexts().append(evictedContext);
+ }
+ break;
+ }
+}
+
+class WebGLRenderingContextEvictionManager : public ContextEvictionManager {
+public:
+ void forciblyLoseOldestContext(const String& reason) {
+ WebGLRenderingContextBase::forciblyLoseOldestContext(reason);
+ };
+ IntSize oldestContextSize() {
+ return WebGLRenderingContextBase::oldestContextSize();
+ };
+};
+
+namespace {
+
+ class ScopedDrawingBufferBinder {
+ public:
+ ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
+ : m_drawingBuffer(drawingBuffer)
+ , m_framebufferBinding(framebufferBinding)
+ {
+ // Commit DrawingBuffer if needed (e.g., for multisampling)
+ if (!m_framebufferBinding && m_drawingBuffer)
+ m_drawingBuffer->commit();
+ }
+
+ ~ScopedDrawingBufferBinder()
+ {
+ // Restore DrawingBuffer if needed
+ if (!m_framebufferBinding && m_drawingBuffer)
+ m_drawingBuffer->bind();
+ }
+
+ private:
+ DrawingBuffer* m_drawingBuffer;
+ WebGLFramebuffer* m_framebufferBinding;
+ };
+
+ Platform3DObject objectOrZero(WebGLObject* object)
+ {
+ return object ? object->object() : 0;
+ }
+
+ GLint clamp(GLint value, GLint min, GLint max)
+ {
+ if (value < min)
+ value = min;
+ if (value > max)
+ value = max;
+ return value;
+ }
+
+ // Return true if a character belongs to the ASCII subset as defined in
+ // GLSL ES 1.0 spec section 3.1.
+ bool validateCharacter(unsigned char c)
+ {
+ // Printing characters are valid except " $ ` @ \ ' DEL.
+ if (c >= 32 && c <= 126
+ && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
+ return true;
+ // Horizontal tab, line feed, vertical tab, form feed, carriage return
+ // are also valid.
+ if (c >= 9 && c <= 13)
+ return true;
+ return false;
+ }
+
+ bool isPrefixReserved(const String& name)
+ {
+ if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
+ return true;
+ return false;
+ }
+
+ // Strips comments from shader text. This allows non-ASCII characters
+ // to be used in comments without potentially breaking OpenGL
+ // implementations not expecting characters outside the GLSL ES set.
+ class StripComments {
+ public:
+ StripComments(const String& str)
+ : m_parseState(BeginningOfLine)
+ , m_sourceString(str)
+ , m_length(str.length())
+ , m_position(0)
+ {
+ parse();
+ }
+
+ String result()
+ {
+ return m_builder.toString();
+ }
+
+ private:
+ bool hasMoreCharacters() const
+ {
+ return (m_position < m_length);
+ }
+
+ void parse()
+ {
+ while (hasMoreCharacters()) {
+ process(current());
+ // process() might advance the position.
+ if (hasMoreCharacters())
+ advance();
+ }
+ }
+
+ void process(UChar);
+
+ bool peek(UChar& character) const
+ {
+ if (m_position + 1 >= m_length)
+ return false;
+ character = m_sourceString[m_position + 1];
+ return true;
+ }
+
+ UChar current()
+ {
+ ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
+ return m_sourceString[m_position];
+ }
+
+ void advance()
+ {
+ ++m_position;
+ }
+
+ static bool isNewline(UChar character)
+ {
+ // Don't attempt to canonicalize newline related characters.
+ return (character == '\n' || character == '\r');
+ }
+
+ void emit(UChar character)
+ {
+ m_builder.append(character);
+ }
+
+ enum ParseState {
+ // Have not seen an ASCII non-whitespace character yet on
+ // this line. Possible that we might see a preprocessor
+ // directive.
+ BeginningOfLine,
+
+ // Have seen at least one ASCII non-whitespace character
+ // on this line.
+ MiddleOfLine,
+
+ // Handling a preprocessor directive. Passes through all
+ // characters up to the end of the line. Disables comment
+ // processing.
+ InPreprocessorDirective,
+
+ // Handling a single-line comment. The comment text is
+ // replaced with a single space.
+ InSingleLineComment,
+
+ // Handling a multi-line comment. Newlines are passed
+ // through to preserve line numbers.
+ InMultiLineComment
+ };
+
+ ParseState m_parseState;
+ String m_sourceString;
+ unsigned m_length;
+ unsigned m_position;
+ StringBuilder m_builder;
+ };
+
+ void StripComments::process(UChar c)
+ {
+ if (isNewline(c)) {
+ // No matter what state we are in, pass through newlines
+ // so we preserve line numbers.
+ emit(c);
+
+ if (m_parseState != InMultiLineComment)
+ m_parseState = BeginningOfLine;
+
+ return;
+ }
+
+ UChar temp = 0;
+ switch (m_parseState) {
+ case BeginningOfLine:
+ if (WTF::isASCIISpace(c)) {
+ emit(c);
+ break;
+ }
+
+ if (c == '#') {
+ m_parseState = InPreprocessorDirective;
+ emit(c);
+ break;
+ }
+
+ // Transition to normal state and re-handle character.
+ m_parseState = MiddleOfLine;
+ process(c);
+ break;
+
+ case MiddleOfLine:
+ if (c == '/' && peek(temp)) {
+ if (temp == '/') {
+ m_parseState = InSingleLineComment;
+ emit(' ');
+ advance();
+ break;
+ }
+
+ if (temp == '*') {
+ m_parseState = InMultiLineComment;
+ // Emit the comment start in case the user has
+ // an unclosed comment and we want to later
+ // signal an error.
+ emit('/');
+ emit('*');
+ advance();
+ break;
+ }
+ }
+
+ emit(c);
+ break;
+
+ case InPreprocessorDirective:
+ // No matter what the character is, just pass it
+ // through. Do not parse comments in this state. This
+ // might not be the right thing to do long term, but it
+ // should handle the #error preprocessor directive.
+ emit(c);
+ break;
+
+ case InSingleLineComment:
+ // The newline code at the top of this function takes care
+ // of resetting our state when we get out of the
+ // single-line comment. Swallow all other characters.
+ break;
+
+ case InMultiLineComment:
+ if (c == '*' && peek(temp) && temp == '/') {
+ emit('*');
+ emit('/');
+ m_parseState = MiddleOfLine;
+ advance();
+ break;
+ }
+
+ // Swallow all other characters. Unclear whether we may
+ // want or need to just emit a space per character to try
+ // to preserve column numbers for debugging purposes.
+ break;
+ }
+ }
+} // namespace anonymous
+
+class ScopedTexture2DRestorer {
+public:
+ ScopedTexture2DRestorer(WebGLRenderingContextBase* context)
+ : m_context(context)
+ {
+ }
+
+ ~ScopedTexture2DRestorer()
+ {
+ m_context->restoreCurrentTexture2D();
+ }
+
+private:
+ WebGLRenderingContextBase* m_context;
+};
+
+class WebGLRenderingContextLostCallback : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WebGLRenderingContextLostCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
+ virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingContextBase::RealLostContext); }
+ virtual ~WebGLRenderingContextLostCallback() {}
+private:
+ WebGLRenderingContextBase* m_context;
+};
+
+class WebGLRenderingContextErrorMessageCallback : public blink::WebGraphicsContext3D::WebGraphicsErrorMessageCallback {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
+ virtual void onErrorMessage(const blink::WebString& message, blink::WGC3Dint)
+ {
+ if (m_context->m_synthesizedErrorsToConsole)
+ m_context->printGLErrorToConsole(message);
+ InspectorInstrumentation::didFireWebGLErrorOrWarning(m_context->canvas(), message);
+ }
+ virtual ~WebGLRenderingContextErrorMessageCallback() { }
+private:
+ WebGLRenderingContextBase* m_context;
+};
+
+WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, PassOwnPtr<blink::WebGraphicsContext3D> context, WebGLContextAttributes* requestedAttributes)
+ : CanvasRenderingContext(passedCanvas)
+ , ActiveDOMObject(&passedCanvas->document())
+ , m_drawingBuffer(nullptr)
+ , m_dispatchContextLostEventTimer(this, &WebGLRenderingContextBase::dispatchContextLostEvent)
+ , m_restoreAllowed(false)
+ , m_restoreTimer(this, &WebGLRenderingContextBase::maybeRestoreContext)
+ , m_generatedImageCache(4)
+ , m_contextLost(false)
+ , m_contextLostMode(SyntheticLostContext)
+ , m_requestedAttributes(requestedAttributes->clone())
+ , m_synthesizedErrorsToConsole(true)
+ , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
+ , m_multisamplingAllowed(false)
+ , m_multisamplingObserverRegistered(false)
+ , m_onePlusMaxEnabledAttribIndex(0)
+ , m_onePlusMaxNonDefaultTextureUnit(0)
+ , m_savingImage(false)
+{
+ ASSERT(context);
+
+ m_contextGroup = WebGLContextGroup::create();
+ m_contextGroup->addContext(this);
+
+ m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
+ context->getIntegerv(GL_MAX_VIEWPORT_DIMS, m_maxViewportDims);
+
+ m_drawingBuffer = createDrawingBuffer(context);
+ if (!m_drawingBuffer)
+ return;
+
+ m_drawingBuffer->bind();
+ setupFlags();
+ initializeNewContext();
+}
+
+PassRefPtr<DrawingBuffer> WebGLRenderingContextBase::createDrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D> context)
+{
+ RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
+
+ blink::WebGraphicsContext3D::Attributes attrs;
+ attrs.alpha = m_requestedAttributes->alpha();
+ attrs.depth = m_requestedAttributes->depth();
+ attrs.stencil = m_requestedAttributes->stencil();
+ attrs.antialias = m_requestedAttributes->antialias();
+ attrs.premultipliedAlpha = m_requestedAttributes->premultipliedAlpha();
+ DrawingBuffer::PreserveDrawingBuffer preserve = m_requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
+ return DrawingBuffer::create(context, clampedCanvasSize(), preserve, attrs, contextEvictionManager.release());
+}
+
+void WebGLRenderingContextBase::initializeNewContext()
+{
+ ASSERT(!isContextLost());
+ m_needsUpdate = true;
+ m_markedCanvasDirty = false;
+ m_activeTextureUnit = 0;
+ m_packAlignment = 4;
+ m_unpackAlignment = 4;
+ m_unpackFlipY = false;
+ m_unpackPremultiplyAlpha = false;
+ m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL;
+ m_boundArrayBuffer = nullptr;
+ m_currentProgram = nullptr;
+ m_framebufferBinding = nullptr;
+ m_renderbufferBinding = nullptr;
+ m_depthMask = true;
+ m_stencilEnabled = false;
+ m_stencilMask = 0xFFFFFFFF;
+ m_stencilMaskBack = 0xFFFFFFFF;
+ m_stencilFuncRef = 0;
+ m_stencilFuncRefBack = 0;
+ m_stencilFuncMask = 0xFFFFFFFF;
+ m_stencilFuncMaskBack = 0xFFFFFFFF;
+ m_layerCleared = false;
+ m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
+
+ m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
+ m_scissorEnabled = false;
+ m_clearDepth = 1;
+ m_clearStencil = 0;
+ m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
+
+ GLint numCombinedTextureImageUnits = 0;
+ webContext()->getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
+ m_textureUnits.clear();
+ m_textureUnits.resize(numCombinedTextureImageUnits);
+
+ GLint numVertexAttribs = 0;
+ webContext()->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribs);
+ m_maxVertexAttribs = numVertexAttribs;
+
+ m_maxTextureSize = 0;
+ webContext()->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
+ m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
+ m_maxCubeMapTextureSize = 0;
+ webContext()->getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
+ m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
+ m_maxRenderbufferSize = 0;
+ webContext()->getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
+
+ // These two values from EXT_draw_buffers are lazily queried.
+ m_maxDrawBuffers = 0;
+ m_maxColorAttachments = 0;
+
+ m_backDrawBuffer = GL_BACK;
+
+ m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
+ addContextObject(m_defaultVertexArrayObject.get());
+ m_boundVertexArrayObject = m_defaultVertexArrayObject;
+
+ m_vertexAttribValue.resize(m_maxVertexAttribs);
+
+ createFallbackBlackTextures1x1();
+
+ webContext()->viewport(0, 0, drawingBufferWidth(), drawingBufferHeight());
+ webContext()->scissor(0, 0, drawingBufferWidth(), drawingBufferHeight());
+
+ m_contextLostCallbackAdapter = adoptPtr(new WebGLRenderingContextLostCallback(this));
+ m_errorMessageCallbackAdapter = adoptPtr(new WebGLRenderingContextErrorMessageCallback(this));
+
+ webContext()->setContextLostCallback(m_contextLostCallbackAdapter.get());
+ webContext()->setErrorMessageCallback(m_errorMessageCallbackAdapter.get());
+
+ // This ensures that the context has a valid "lastFlushID" and won't be mistakenly identified as the "least recently used" context.
+ webContext()->flush();
+
+ for (int i = 0; i < WebGLExtensionNameCount; ++i)
+ m_extensionEnabled[i] = false;
+
+ activateContext(this);
+}
+
+void WebGLRenderingContextBase::setupFlags()
+{
+ ASSERT(m_drawingBuffer);
+ if (Page* p = canvas()->document().page()) {
+ m_synthesizedErrorsToConsole = p->settings().webGLErrorsToConsoleEnabled();
+
+ if (!m_multisamplingObserverRegistered && m_requestedAttributes->antialias()) {
+ m_multisamplingAllowed = m_drawingBuffer->multisample();
+ p->addMultisamplingChangedObserver(this);
+ m_multisamplingObserverRegistered = true;
+ }
+ }
+
+ m_isGLES2NPOTStrict = !extensionsUtil()->isExtensionEnabled("GL_OES_texture_npot");
+ m_isDepthStencilSupported = extensionsUtil()->isExtensionEnabled("GL_OES_packed_depth_stencil");
+}
+
+void WebGLRenderingContextBase::addCompressedTextureFormat(GLenum format)
+{
+ if (!m_compressedTextureFormats.contains(format))
+ m_compressedTextureFormats.append(format);
+}
+
+void WebGLRenderingContextBase::removeAllCompressedTextureFormats()
+{
+ m_compressedTextureFormats.clear();
+}
+
+// Helper function for V8 bindings to identify what version of WebGL a CanvasRenderingContext supports.
+unsigned WebGLRenderingContextBase::getWebGLVersion(const CanvasRenderingContext* context)
+{
+ if (!context->is3d())
+ return 0;
+ return static_cast<const WebGLRenderingContextBase*>(context)->version();
+}
+
+WebGLRenderingContextBase::~WebGLRenderingContextBase()
+{
+ // Remove all references to WebGLObjects so if they are the last reference
+ // they will be freed before the last context is removed from the context group.
+ m_boundArrayBuffer = nullptr;
+ m_defaultVertexArrayObject = nullptr;
+ m_boundVertexArrayObject = nullptr;
+ m_vertexAttrib0Buffer = nullptr;
+ m_currentProgram = nullptr;
+ m_framebufferBinding = nullptr;
+ m_renderbufferBinding = nullptr;
+
+ for (size_t i = 0; i < m_textureUnits.size(); ++i) {
+ m_textureUnits[i].m_texture2DBinding = nullptr;
+ m_textureUnits[i].m_textureCubeMapBinding = nullptr;
+ }
+
+ m_blackTexture2D = nullptr;
+ m_blackTextureCubeMap = nullptr;
+
+ detachAndRemoveAllObjects();
+
+ // release all extensions
+ for (size_t i = 0; i < m_extensions.size(); ++i)
+ delete m_extensions[i];
+
+ // Context must be removed from the group prior to the destruction of the
+ // WebGraphicsContext3D, otherwise shared objects may not be properly deleted.
+ m_contextGroup->removeContext(this);
+
+ destroyContext();
+
+#if !ENABLE(OILPAN)
+ if (m_multisamplingObserverRegistered) {
+ Page* page = canvas()->document().page();
+ if (page)
+ page->removeMultisamplingChangedObserver(this);
+ }
+#endif
+
+ willDestroyContext(this);
+}
+
+void WebGLRenderingContextBase::destroyContext()
+{
+ m_contextLost = true;
+
+ if (!m_drawingBuffer)
+ return;
+
+ m_extensionsUtil.clear();
+
+ webContext()->setContextLostCallback(0);
+ webContext()->setErrorMessageCallback(0);
+
+ ASSERT(m_drawingBuffer);
+ m_drawingBuffer->beginDestruction();
+ m_drawingBuffer.clear();
+}
+
+void WebGLRenderingContextBase::markContextChanged(ContentChangeType changeType)
+{
+ if (m_framebufferBinding || isContextLost())
+ return;
+
+ m_drawingBuffer->markContentsChanged();
+
+ m_layerCleared = false;
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasAcceleratedCompositing()) {
+ m_markedCanvasDirty = true;
+ canvas()->clearCopiedImage();
+ renderBox->contentChanged(changeType);
+ } else {
+ if (!m_markedCanvasDirty) {
+ m_markedCanvasDirty = true;
+ canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
+ }
+ }
+}
+
+bool WebGLRenderingContextBase::clearIfComposited(GLbitfield mask)
+{
+ if (isContextLost())
+ return false;
+
+ if (!m_drawingBuffer->layerComposited() || m_layerCleared
+ || m_requestedAttributes->preserveDrawingBuffer() || (mask && m_framebufferBinding))
+ return false;
+
+ RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
+
+ // Determine if it's possible to combine the clear the user asked for and this clear.
+ bool combinedClear = mask && !m_scissorEnabled;
+
+ webContext()->disable(GL_SCISSOR_TEST);
+ if (combinedClear && (mask & GL_COLOR_BUFFER_BIT)) {
+ webContext()->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
+ m_colorMask[1] ? m_clearColor[1] : 0,
+ m_colorMask[2] ? m_clearColor[2] : 0,
+ m_colorMask[3] ? m_clearColor[3] : 0);
+ } else {
+ webContext()->clearColor(0, 0, 0, 0);
+ }
+ webContext()->colorMask(true, true, true, true);
+ GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
+ if (contextAttributes->depth()) {
+ if (!combinedClear || !m_depthMask || !(mask & GL_DEPTH_BUFFER_BIT))
+ webContext()->clearDepth(1.0f);
+ clearMask |= GL_DEPTH_BUFFER_BIT;
+ webContext()->depthMask(true);
+ }
+ if (contextAttributes->stencil()) {
+ if (combinedClear && (mask & GL_STENCIL_BUFFER_BIT))
+ webContext()->clearStencil(m_clearStencil & m_stencilMask);
+ else
+ webContext()->clearStencil(0);
+ clearMask |= GL_STENCIL_BUFFER_BIT;
+ webContext()->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
+ }
+
+ m_drawingBuffer->clearFramebuffers(clearMask);
+
+ restoreStateAfterClear();
+ if (m_framebufferBinding)
+ webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ m_layerCleared = true;
+
+ return combinedClear;
+}
+
+void WebGLRenderingContextBase::restoreStateAfterClear()
+{
+ if (isContextLost())
+ return;
+
+ // Restore the state that the context set.
+ if (m_scissorEnabled)
+ webContext()->enable(GL_SCISSOR_TEST);
+ webContext()->clearColor(m_clearColor[0], m_clearColor[1],
+ m_clearColor[2], m_clearColor[3]);
+ webContext()->colorMask(m_colorMask[0], m_colorMask[1],
+ m_colorMask[2], m_colorMask[3]);
+ webContext()->clearDepth(m_clearDepth);
+ webContext()->clearStencil(m_clearStencil);
+ webContext()->stencilMaskSeparate(GL_FRONT, m_stencilMask);
+ webContext()->depthMask(m_depthMask);
+}
+
+void WebGLRenderingContextBase::markLayerComposited()
+{
+ if (!isContextLost())
+ m_drawingBuffer->markLayerComposited();
+}
+
+void WebGLRenderingContextBase::paintRenderingResultsToCanvas()
+{
+ if (isContextLost()) {
+ canvas()->clearPresentationCopy();
+ return;
+ }
+
+ if (canvas()->document().printing())
+ canvas()->clearPresentationCopy();
+
+ // Until the canvas is written to by the application, the clear that
+ // happened after it was composited should be ignored by the compositor.
+ if (m_drawingBuffer->layerComposited() && !m_requestedAttributes->preserveDrawingBuffer()) {
+ m_drawingBuffer->paintCompositedResultsToCanvas(canvas()->buffer());
+
+ canvas()->makePresentationCopy();
+ } else
+ canvas()->clearPresentationCopy();
+
+ clearIfComposited();
+
+ if (!m_markedCanvasDirty && !m_layerCleared)
+ return;
+
+ canvas()->clearCopiedImage();
+ m_markedCanvasDirty = false;
+
+ ScopedTexture2DRestorer restorer(this);
+
+ m_drawingBuffer->commit();
+ if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get(), m_savingImage)) {
+ canvas()->ensureUnacceleratedImageBuffer();
+ if (canvas()->hasImageBuffer())
+ m_drawingBuffer->paintRenderingResultsToCanvas(canvas()->buffer());
+ }
+
+ if (m_framebufferBinding)
+ webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ else
+ m_drawingBuffer->bind();
+}
+
+PassRefPtrWillBeRawPtr<ImageData> WebGLRenderingContextBase::paintRenderingResultsToImageData()
+{
+ if (isContextLost())
+ return nullptr;
+
+ clearIfComposited();
+ m_drawingBuffer->commit();
+ int width, height;
+ RefPtr<Uint8ClampedArray> imageDataPixels = m_drawingBuffer->paintRenderingResultsToImageData(width, height);
+ if (!imageDataPixels)
+ return nullptr;
+
+ if (m_framebufferBinding)
+ webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+ else
+ m_drawingBuffer->bind();
+
+ return ImageData::create(IntSize(width, height), imageDataPixels);
+}
+
+void WebGLRenderingContextBase::reshape(int width, int height)
+{
+ if (isContextLost())
+ return;
+
+ // This is an approximation because at WebGLRenderingContextBase level we don't
+ // know if the underlying FBO uses textures or renderbuffers.
+ GLint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
+ // Limit drawing buffer size to 4k to avoid memory exhaustion.
+ const int sizeUpperLimit = 4096;
+ maxSize = std::min(maxSize, sizeUpperLimit);
+ GLint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
+ GLint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
+ width = clamp(width, 1, maxWidth);
+ height = clamp(height, 1, maxHeight);
+
+ if (m_needsUpdate) {
+ RenderBox* renderBox = canvas()->renderBox();
+ if (renderBox && renderBox->hasAcceleratedCompositing())
+ renderBox->contentChanged(CanvasChanged);
+ m_needsUpdate = false;
+ }
+
+ // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
+ // clear (and this matches what reshape will do).
+ m_drawingBuffer->reset(IntSize(width, height));
+ restoreStateAfterClear();
+
+ webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get()));
+ webContext()->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
+ if (m_framebufferBinding)
+ webContext()->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+}
+
+int WebGLRenderingContextBase::drawingBufferWidth() const
+{
+ return isContextLost() ? 0 : m_drawingBuffer->size().width();
+}
+
+int WebGLRenderingContextBase::drawingBufferHeight() const
+{
+ return isContextLost() ? 0 : m_drawingBuffer->size().height();
+}
+
+unsigned WebGLRenderingContextBase::sizeInBytes(GLenum type)
+{
+ switch (type) {
+ case GL_BYTE:
+ return sizeof(GLbyte);
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ case GL_SHORT:
+ return sizeof(GLshort);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+void WebGLRenderingContextBase::activeTexture(GLenum texture)
+{
+ if (isContextLost())
+ return;
+ if (texture - GL_TEXTURE0 >= m_textureUnits.size()) {
+ synthesizeGLError(GL_INVALID_ENUM, "activeTexture", "texture unit out of range");
+ return;
+ }
+ m_activeTextureUnit = texture - GL_TEXTURE0;
+ webContext()->activeTexture(texture);
+
+ m_drawingBuffer->setActiveTextureUnit(texture);
+
+}
+
+void WebGLRenderingContextBase::attachShader(WebGLProgram* program, WebGLShader* shader)
+{
+ if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
+ return;
+ if (!program->attachShader(shader)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "attachShader", "shader attachment already has shader");
+ return;
+ }
+ webContext()->attachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onAttached();
+}
+
+void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GLuint index, const String& name)
+{
+ if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
+ return;
+ if (!validateLocationLength("bindAttribLocation", name))
+ return;
+ if (!validateString("bindAttribLocation", name))
+ return;
+ if (isPrefixReserved(name)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "bindAttribLocation", "index out of range");
+ return;
+ }
+ webContext()->bindAttribLocation(objectOrZero(program), index, name.utf8().data());
+}
+
+bool WebGLRenderingContextBase::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
+{
+ deleted = false;
+ if (isContextLost())
+ return false;
+ if (object) {
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "object not from this context");
+ return false;
+ }
+ deleted = !object->object();
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::bindBuffer(GLenum target, WebGLBuffer* buffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
+ synthesizeGLError(GL_INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
+ return;
+ }
+ if (target == GL_ARRAY_BUFFER)
+ m_boundArrayBuffer = buffer;
+ else if (target == GL_ELEMENT_ARRAY_BUFFER)
+ m_boundVertexArrayObject->setElementArrayBuffer(buffer);
+ else {
+ synthesizeGLError(GL_INVALID_ENUM, "bindBuffer", "invalid target");
+ return;
+ }
+
+ webContext()->bindBuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setTarget(target);
+}
+
+void WebGLRenderingContextBase::bindFramebuffer(GLenum target, WebGLFramebuffer* buffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
+ return;
+ if (deleted)
+ buffer = 0;
+ if (target != GL_FRAMEBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target");
+ return;
+ }
+ m_framebufferBinding = buffer;
+ m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
+ if (!m_framebufferBinding) {
+ // Instead of binding fb 0, bind the drawing buffer.
+ m_drawingBuffer->bind();
+ } else {
+ webContext()->bindFramebuffer(target, objectOrZero(buffer));
+ }
+ if (buffer)
+ buffer->setHasEverBeenBound();
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::bindRenderbuffer(GLenum target, WebGLRenderbuffer* renderBuffer)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
+ return;
+ if (deleted)
+ renderBuffer = 0;
+ if (target != GL_RENDERBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "bindRenderbuffer", "invalid target");
+ return;
+ }
+ m_renderbufferBinding = renderBuffer;
+ webContext()->bindRenderbuffer(target, objectOrZero(renderBuffer));
+ if (renderBuffer)
+ renderBuffer->setHasEverBeenBound();
+}
+
+void WebGLRenderingContextBase::bindTexture(GLenum target, WebGLTexture* texture)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("bindTexture", texture, deleted))
+ return;
+ if (deleted)
+ texture = 0;
+ if (texture && texture->getTarget() && texture->getTarget() != target) {
+ synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
+ return;
+ }
+ GLint maxLevel = 0;
+ if (target == GL_TEXTURE_2D) {
+ m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
+ maxLevel = m_maxTextureLevel;
+
+ if (!m_activeTextureUnit)
+ m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
+
+ } else if (target == GL_TEXTURE_CUBE_MAP) {
+ m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
+ maxLevel = m_maxCubeMapTextureLevel;
+ } else {
+ synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target");
+ return;
+ }
+
+ webContext()->bindTexture(target, objectOrZero(texture));
+ if (texture) {
+ texture->setTarget(target, maxLevel);
+ m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit);
+ } else {
+ // If the disabled index is the current maximum, trace backwards to find the new max enabled texture index
+ if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) {
+ findNewMaxNonDefaultTextureUnit();
+ }
+ }
+
+ // Note: previously we used to automatically set the TEXTURE_WRAP_R
+ // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
+ // ES 2.0 doesn't expose this flag (a bug in the specification) and
+ // otherwise the application has no control over the seams in this
+ // dimension. However, it appears that supporting this properly on all
+ // platforms is fairly involved (will require a HashMap from texture ID
+ // in all ports), and we have not had any complaints, so the logic has
+ // been removed.
+
+}
+
+void WebGLRenderingContextBase::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+ if (isContextLost())
+ return;
+ webContext()->blendColor(red, green, blue, alpha);
+}
+
+void WebGLRenderingContextBase::blendEquation(GLenum mode)
+{
+ if (isContextLost() || !validateBlendEquation("blendEquation", mode))
+ return;
+ webContext()->blendEquation(mode);
+}
+
+void WebGLRenderingContextBase::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+ if (isContextLost() || !validateBlendEquation("blendEquationSeparate", modeRGB) || !validateBlendEquation("blendEquationSeparate", modeAlpha))
+ return;
+ webContext()->blendEquationSeparate(modeRGB, modeAlpha);
+}
+
+
+void WebGLRenderingContextBase::blendFunc(GLenum sfactor, GLenum dfactor)
+{
+ if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
+ return;
+ webContext()->blendFunc(sfactor, dfactor);
+}
+
+void WebGLRenderingContextBase::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+ // Note: Alpha does not have the same restrictions as RGB.
+ if (isContextLost() || !validateBlendFuncFactors("blendFuncSeparate", srcRGB, dstRGB))
+ return;
+ webContext()->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void WebGLRenderingContextBase::bufferDataImpl(GLenum target, long long size, const void* data, GLenum usage)
+{
+ WebGLBuffer* buffer = validateBufferDataTarget("bufferData", target);
+ if (!buffer)
+ return;
+
+ switch (usage) {
+ case GL_STREAM_DRAW:
+ case GL_STATIC_DRAW:
+ case GL_DYNAMIC_DRAW:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "bufferData", "invalid usage");
+ return;
+ }
+
+ if (!validateValueFitNonNegInt32("bufferData", "size", size))
+ return;
+
+ webContext()->bufferData(target, static_cast<GLsizeiptr>(size), data, usage);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, long long size, GLenum usage)
+{
+ if (isContextLost())
+ return;
+ if (!size) {
+ synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size == 0");
+ return;
+ }
+ bufferDataImpl(target, size, 0, usage);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, ArrayBuffer* data, GLenum usage)
+{
+ if (isContextLost())
+ return;
+ if (!data) {
+ synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
+ return;
+ }
+ bufferDataImpl(target, data->byteLength(), data->data(), usage);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, ArrayBufferView* data, GLenum usage)
+{
+ if (isContextLost())
+ return;
+ if (!data) {
+ synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
+ return;
+ }
+ bufferDataImpl(target, data->byteLength(), data->baseAddress(), usage);
+}
+
+void WebGLRenderingContextBase::bufferSubDataImpl(GLenum target, long long offset, GLsizeiptr size, const void* data)
+{
+ WebGLBuffer* buffer = validateBufferDataTarget("bufferSubData", target);
+ if (!buffer)
+ return;
+ if (!validateValueFitNonNegInt32("bufferSubData", "offset", offset))
+ return;
+ if (!data)
+ return;
+
+ webContext()->bufferSubData(target, static_cast<GLintptr>(offset), size, data);
+}
+
+void WebGLRenderingContextBase::bufferSubData(GLenum target, long long offset, ArrayBuffer* data)
+{
+ if (isContextLost())
+ return;
+ if (!data)
+ return;
+ bufferSubDataImpl(target, offset, data->byteLength(), data->data());
+}
+
+void WebGLRenderingContextBase::bufferSubData(GLenum target, long long offset, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!data)
+ return;
+ bufferSubDataImpl(target, offset, data->byteLength(), data->baseAddress());
+}
+
+GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target)
+{
+ if (isContextLost())
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ if (target != GL_FRAMEBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid target");
+ return 0;
+ }
+ if (!m_framebufferBinding || !m_framebufferBinding->object())
+ return GL_FRAMEBUFFER_COMPLETE;
+ const char* reason = "framebuffer incomplete";
+ GLenum result = m_framebufferBinding->checkStatus(&reason);
+ if (result != GL_FRAMEBUFFER_COMPLETE) {
+ emitGLWarning("checkFramebufferStatus", reason);
+ return result;
+ }
+ result = webContext()->checkFramebufferStatus(target);
+ return result;
+}
+
+void WebGLRenderingContextBase::clear(GLbitfield mask)
+{
+ if (isContextLost())
+ return;
+ if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
+ synthesizeGLError(GL_INVALID_VALUE, "clear", "invalid mask");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
+ return;
+ }
+ if (!clearIfComposited(mask))
+ webContext()->clear(mask);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::clearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
+{
+ if (isContextLost())
+ return;
+ if (std::isnan(r))
+ r = 0;
+ if (std::isnan(g))
+ g = 0;
+ if (std::isnan(b))
+ b = 0;
+ if (std::isnan(a))
+ a = 1;
+ m_clearColor[0] = r;
+ m_clearColor[1] = g;
+ m_clearColor[2] = b;
+ m_clearColor[3] = a;
+ webContext()->clearColor(r, g, b, a);
+}
+
+void WebGLRenderingContextBase::clearDepth(GLfloat depth)
+{
+ if (isContextLost())
+ return;
+ m_clearDepth = depth;
+ webContext()->clearDepth(depth);
+}
+
+void WebGLRenderingContextBase::clearStencil(GLint s)
+{
+ if (isContextLost())
+ return;
+ m_clearStencil = s;
+ webContext()->clearStencil(s);
+}
+
+void WebGLRenderingContextBase::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+ if (isContextLost())
+ return;
+ m_colorMask[0] = red;
+ m_colorMask[1] = green;
+ m_colorMask[2] = blue;
+ m_colorMask[3] = alpha;
+ webContext()->colorMask(red, green, blue, alpha);
+}
+
+void WebGLRenderingContextBase::compileShader(WebGLShader* shader)
+{
+ if (isContextLost() || !validateWebGLObject("compileShader", shader))
+ return;
+ webContext()->compileShader(objectOrZero(shader));
+}
+
+void WebGLRenderingContextBase::compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("compressedTexImage2D", target, level))
+ return;
+
+ if (!validateCompressedTexFormat(internalformat)) {
+ synthesizeGLError(GL_INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
+ return;
+ }
+ if (border) {
+ synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0");
+ return;
+ }
+ if (!validateCompressedTexDimensions("compressedTexImage2D", NotTexSubImage2D, target, level, width, height, internalformat))
+ return;
+ if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
+ return;
+
+ WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isGLES2NPOTStrict()) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ }
+ webContext()->compressedTexImage2D(target, level, internalformat, width, height,
+ border, data->byteLength(), data->baseAddress());
+ tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
+}
+
+void WebGLRenderingContextBase::compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
+ return;
+ if (!validateCompressedTexFormat(format)) {
+ synthesizeGLError(GL_INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
+ return;
+ }
+ if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
+ return;
+
+ WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
+ if (!tex)
+ return;
+
+ if (format != tex->getInternalFormat(target, level)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
+ return;
+ }
+
+ if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
+ return;
+
+ webContext()->compressedTexSubImage2D(target, level, xoffset, yoffset,
+ width, height, format, data->byteLength(), data->baseAddress());
+}
+
+bool WebGLRenderingContextBase::validateSettableTexFormat(const char* functionName, GLenum format)
+{
+ if (WebGLImageConversion::getClearBitsByFormat(format) & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "format can not be set, only rendered to");
+ return false;
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GL_UNSIGNED_BYTE))
+ return;
+ if (!validateSettableTexFormat("copyTexImage2D", internalformat))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
+ if (!tex)
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
+ synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ webContext()->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+ // FIXME: if the framebuffer is not complete, none of the below should be executed.
+ tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
+}
+
+void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
+ return;
+ WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
+ if (!tex)
+ return;
+ if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
+ return;
+ // Before checking if it is in the range, check if overflow happens first.
+ Checked<GLint, RecordOverflow> maxX = xoffset;
+ maxX += width;
+ Checked<GLint, RecordOverflow> maxY = yoffset;
+ maxY += height;
+ if (maxX.hasOverflowed() || maxY.hasOverflowed()) {
+ synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
+ return;
+ }
+ if (maxX.unsafeGet() > tex->getWidth(target, level) || maxY.unsafeGet() > tex->getHeight(target, level)) {
+ synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
+ return;
+ }
+ GLenum internalformat = tex->getInternalFormat(target, level);
+ if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
+ return;
+ if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
+ synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
+ return;
+ }
+ clearIfComposited();
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ webContext()->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+PassRefPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLFramebuffer> WebGLRenderingContextBase::createFramebuffer()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
+ addContextObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLTexture> WebGLRenderingContextBase::createTexture()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLTexture> o = WebGLTexture::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLProgram> WebGLRenderingContextBase::createProgram()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLProgram> o = WebGLProgram::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+PassRefPtr<WebGLRenderbuffer> WebGLRenderingContextBase::createRenderbuffer()
+{
+ if (isContextLost())
+ return nullptr;
+ RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
+ addSharedObject(o.get());
+ return o;
+}
+
+WebGLRenderbuffer* WebGLRenderingContextBase::ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer* renderbuffer)
+{
+ if (isContextLost())
+ return 0;
+ if (!renderbuffer->emulatedStencilBuffer()) {
+ renderbuffer->setEmulatedStencilBuffer(createRenderbuffer());
+ webContext()->bindRenderbuffer(target, objectOrZero(renderbuffer->emulatedStencilBuffer()));
+ webContext()->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+ }
+ return renderbuffer->emulatedStencilBuffer();
+}
+
+PassRefPtr<WebGLShader> WebGLRenderingContextBase::createShader(GLenum type)
+{
+ if (isContextLost())
+ return nullptr;
+ if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) {
+ synthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type");
+ return nullptr;
+ }
+
+ RefPtr<WebGLShader> o = WebGLShader::create(this, type);
+ addSharedObject(o.get());
+ return o;
+}
+
+void WebGLRenderingContextBase::cullFace(GLenum mode)
+{
+ if (isContextLost())
+ return;
+ switch (mode) {
+ case GL_FRONT_AND_BACK:
+ case GL_FRONT:
+ case GL_BACK:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "cullFace", "invalid mode");
+ return;
+ }
+ webContext()->cullFace(mode);
+}
+
+bool WebGLRenderingContextBase::deleteObject(WebGLObject* object)
+{
+ if (isContextLost() || !object)
+ return false;
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "delete", "object does not belong to this context");
+ return false;
+ }
+ if (object->object()) {
+ // We need to pass in context here because we want
+ // things in this context unbound.
+ object->deleteObject(webContext());
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::deleteBuffer(WebGLBuffer* buffer)
+{
+ if (!deleteObject(buffer))
+ return;
+ if (m_boundArrayBuffer == buffer)
+ m_boundArrayBuffer = nullptr;
+
+ m_boundVertexArrayObject->unbindBuffer(buffer);
+}
+
+void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!deleteObject(framebuffer))
+ return;
+ if (framebuffer == m_framebufferBinding) {
+ m_framebufferBinding = nullptr;
+ m_drawingBuffer->setFramebufferBinding(0);
+ // Have to call bindFramebuffer here to bind back to internal fbo.
+ m_drawingBuffer->bind();
+ }
+}
+
+void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program)
+{
+ deleteObject(program);
+ // We don't reset m_currentProgram to 0 here because the deletion of the
+ // current program is delayed.
+}
+
+void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!deleteObject(renderbuffer))
+ return;
+ if (renderbuffer == m_renderbufferBinding)
+ m_renderbufferBinding = nullptr;
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
+}
+
+void WebGLRenderingContextBase::deleteShader(WebGLShader* shader)
+{
+ deleteObject(shader);
+}
+
+void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture)
+{
+ if (!deleteObject(texture))
+ return;
+
+ int maxBoundTextureIndex = -1;
+ for (size_t i = 0; i < m_onePlusMaxNonDefaultTextureUnit; ++i) {
+ if (texture == m_textureUnits[i].m_texture2DBinding) {
+ m_textureUnits[i].m_texture2DBinding = nullptr;
+ maxBoundTextureIndex = i;
+ if (!i)
+ m_drawingBuffer->setTexture2DBinding(0);
+ }
+ if (texture == m_textureUnits[i].m_textureCubeMapBinding) {
+ m_textureUnits[i].m_textureCubeMapBinding = nullptr;
+ maxBoundTextureIndex = i;
+ }
+ }
+ if (m_framebufferBinding)
+ m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
+
+ // If the deleted was bound to the the current maximum index, trace backwards to find the new max texture index
+ if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBoundTextureIndex + 1)) {
+ findNewMaxNonDefaultTextureUnit();
+ }
+}
+
+void WebGLRenderingContextBase::depthFunc(GLenum func)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilOrDepthFunc("depthFunc", func))
+ return;
+ webContext()->depthFunc(func);
+}
+
+void WebGLRenderingContextBase::depthMask(GLboolean flag)
+{
+ if (isContextLost())
+ return;
+ m_depthMask = flag;
+ webContext()->depthMask(flag);
+}
+
+void WebGLRenderingContextBase::depthRange(GLfloat zNear, GLfloat zFar)
+{
+ if (isContextLost())
+ return;
+ if (zNear > zFar) {
+ synthesizeGLError(GL_INVALID_OPERATION, "depthRange", "zNear > zFar");
+ return;
+ }
+ webContext()->depthRange(zNear, zFar);
+}
+
+void WebGLRenderingContextBase::detachShader(WebGLProgram* program, WebGLShader* shader)
+{
+ if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
+ return;
+ if (!program->detachShader(shader)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "detachShader", "shader not attached");
+ return;
+ }
+ webContext()->detachShader(objectOrZero(program), objectOrZero(shader));
+ shader->onDetached(webContext());
+}
+
+void WebGLRenderingContextBase::disable(GLenum cap)
+{
+ if (isContextLost() || !validateCapability("disable", cap))
+ return;
+ if (cap == GL_STENCIL_TEST) {
+ m_stencilEnabled = false;
+ applyStencilTest();
+ return;
+ }
+ if (cap == GL_SCISSOR_TEST) {
+ m_scissorEnabled = false;
+ m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
+ }
+ webContext()->disable(cap);
+}
+
+void WebGLRenderingContextBase::disableVertexAttribArray(GLuint index)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "disableVertexAttribArray", "index out of range");
+ return;
+ }
+
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.enabled = false;
+
+ // If the disabled index is the current maximum, trace backwards to find the new max enabled attrib index
+ if (m_onePlusMaxEnabledAttribIndex == index + 1) {
+ findNewMaxEnabledAttribIndex();
+ }
+
+ webContext()->disableVertexAttribArray(index);
+}
+
+bool WebGLRenderingContextBase::validateRenderingState(const char* functionName)
+{
+ if (!m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "no valid shader program in use");
+ return false;
+ }
+
+ // Look in each enabled vertex attrib and check if they've been bound to a buffer.
+ for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
+ if (state.enabled
+ && (!state.bufferBinding || !state.bufferBinding->object())) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, String::format("attribute %d is enabled but has no buffer bound", i).utf8().data());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateWebGLObject(const char* functionName, WebGLObject* object)
+{
+ if (!object || !object->object()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no object or object deleted");
+ return false;
+ }
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "object does not belong to this context");
+ return false;
+ }
+ return true;
+}
+
+void WebGLRenderingContextBase::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ if (!validateDrawArrays("drawArrays", mode, first, count))
+ return;
+
+ clearIfComposited();
+
+ handleTextureCompleteness("drawArrays", true);
+ webContext()->drawArrays(mode, first, count);
+ handleTextureCompleteness("drawArrays", false);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawElements(GLenum mode, GLsizei count, GLenum type, long long offset)
+{
+ if (!validateDrawElements("drawElements", mode, count, type, offset))
+ return;
+
+ clearIfComposited();
+
+ handleTextureCompleteness("drawElements", true);
+ webContext()->drawElements(mode, count, type, static_cast<GLintptr>(offset));
+ handleTextureCompleteness("drawElements", false);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+ if (!validateDrawArrays("drawArraysInstancedANGLE", mode, first, count))
+ return;
+
+ if (!validateDrawInstanced("drawArraysInstancedANGLE", primcount))
+ return;
+
+ clearIfComposited();
+
+ handleTextureCompleteness("drawArraysInstancedANGLE", true);
+ webContext()->drawArraysInstancedANGLE(mode, first, count, primcount);
+ handleTextureCompleteness("drawArraysInstancedANGLE", false);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount)
+{
+ if (!validateDrawElements("drawElementsInstancedANGLE", mode, count, type, offset))
+ return;
+
+ if (!validateDrawInstanced("drawElementsInstancedANGLE", primcount))
+ return;
+
+ clearIfComposited();
+
+ handleTextureCompleteness("drawElementsInstancedANGLE", true);
+ webContext()->drawElementsInstancedANGLE(mode, count, type, static_cast<GLintptr>(offset), primcount);
+ handleTextureCompleteness("drawElementsInstancedANGLE", false);
+ markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::enable(GLenum cap)
+{
+ if (isContextLost() || !validateCapability("enable", cap))
+ return;
+ if (cap == GL_STENCIL_TEST) {
+ m_stencilEnabled = true;
+ applyStencilTest();
+ return;
+ }
+ if (cap == GL_SCISSOR_TEST) {
+ m_scissorEnabled = true;
+ m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
+ }
+ webContext()->enable(cap);
+}
+
+void WebGLRenderingContextBase::enableVertexAttribArray(GLuint index)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "enableVertexAttribArray", "index out of range");
+ return;
+ }
+
+ WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+ state.enabled = true;
+
+ m_onePlusMaxEnabledAttribIndex = max(index + 1, m_onePlusMaxEnabledAttribIndex);
+
+ webContext()->enableVertexAttribArray(index);
+}
+
+void WebGLRenderingContextBase::finish()
+{
+ if (isContextLost())
+ return;
+ webContext()->flush(); // Intentionally a flush, not a finish.
+}
+
+void WebGLRenderingContextBase::flush()
+{
+ if (isContextLost())
+ return;
+ webContext()->flush();
+}
+
+void WebGLRenderingContextBase::framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer* buffer)
+{
+ if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
+ return;
+ if (renderbuffertarget != GL_RENDERBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
+ return;
+ }
+ if (buffer && !buffer->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
+ return;
+ }
+ // Don't allow the default framebuffer to be mutated; all current
+ // implementations use an FBO internally in place of the default
+ // FBO.
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
+ return;
+ }
+ Platform3DObject bufferObject = objectOrZero(buffer);
+ switch (attachment) {
+ case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+ if (isDepthStencilSupported() || !buffer) {
+ webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+ webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
+ } else {
+ WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(renderbuffertarget, buffer);
+ if (!emulatedStencilBuffer) {
+ synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", "out of memory");
+ return;
+ }
+ webContext()->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+ webContext()->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer));
+ }
+ break;
+ default:
+ webContext()->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture* texture, GLint level)
+{
+ if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
+ return;
+ if (level) {
+ synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0");
+ return;
+ }
+ if (texture && !texture->validate(contextGroup(), this)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
+ return;
+ }
+ // Don't allow the default framebuffer to be mutated; all current
+ // implementations use an FBO internally in place of the default
+ // FBO.
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
+ return;
+ }
+ Platform3DObject textureObject = objectOrZero(texture);
+ switch (attachment) {
+ case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+ webContext()->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget, textureObject, level);
+ webContext()->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, textureObject, level);
+ break;
+ case GL_DEPTH_ATTACHMENT:
+ webContext()->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ break;
+ case GL_STENCIL_ATTACHMENT:
+ webContext()->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ break;
+ default:
+ webContext()->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+ }
+ m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::frontFace(GLenum mode)
+{
+ if (isContextLost())
+ return;
+ switch (mode) {
+ case GL_CW:
+ case GL_CCW:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "frontFace", "invalid mode");
+ return;
+ }
+ webContext()->frontFace(mode);
+}
+
+void WebGLRenderingContextBase::generateMipmap(GLenum target)
+{
+ if (isContextLost())
+ return;
+ WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
+ if (!tex)
+ return;
+ if (!tex->canGenerateMipmaps()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
+ return;
+ }
+ if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
+ return;
+
+ // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
+ // on Mac. Remove the hack once this driver bug is fixed.
+#if OS(MACOSX)
+ bool needToResetMinFilter = false;
+ if (tex->getMinFilter() != GL_NEAREST_MIPMAP_LINEAR) {
+ webContext()->texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
+ needToResetMinFilter = true;
+ }
+#endif
+ webContext()->generateMipmap(target);
+#if OS(MACOSX)
+ if (needToResetMinFilter)
+ webContext()->texParameteri(target, GL_TEXTURE_MIN_FILTER, tex->getMinFilter());
+#endif
+ tex->generateMipmapLevelInfo();
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveAttrib(WebGLProgram* program, GLuint index)
+{
+ if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
+ return nullptr;
+ blink::WebGraphicsContext3D::ActiveInfo info;
+ if (!webContext()->getActiveAttrib(objectOrZero(program), index, info))
+ return nullptr;
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveUniform(WebGLProgram* program, GLuint index)
+{
+ if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
+ return nullptr;
+ blink::WebGraphicsContext3D::ActiveInfo info;
+ if (!webContext()->getActiveUniform(objectOrZero(program), index, info))
+ return nullptr;
+ return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+bool WebGLRenderingContextBase::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader> >& shaderObjects)
+{
+ shaderObjects.clear();
+ if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
+ return false;
+
+ const GLenum shaderType[] = {
+ GL_VERTEX_SHADER,
+ GL_FRAGMENT_SHADER
+ };
+ for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GLenum); ++i) {
+ WebGLShader* shader = program->getAttachedShader(shaderType[i]);
+ if (shader)
+ shaderObjects.append(shader);
+ }
+ return true;
+}
+
+GLint WebGLRenderingContextBase::getAttribLocation(WebGLProgram* program, const String& name)
+{
+ if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
+ return -1;
+ if (!validateLocationLength("getAttribLocation", name))
+ return -1;
+ if (!validateString("getAttribLocation", name))
+ return -1;
+ if (isPrefixReserved(name))
+ return -1;
+ if (!program->linkStatus()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getAttribLocation", "program not linked");
+ return 0;
+ }
+ return webContext()->getAttribLocation(objectOrZero(program), name.utf8().data());
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBufferParameter(GLenum target, GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid target");
+ return WebGLGetInfo();
+ }
+
+ if (pname != GL_BUFFER_SIZE && pname != GL_BUFFER_USAGE) {
+ synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+
+ GLint value = 0;
+ webContext()->getBufferParameteriv(target, pname, &value);
+ if (pname == GL_BUFFER_SIZE)
+ return WebGLGetInfo(value);
+ return WebGLGetInfo(static_cast<unsigned>(value));
+}
+
+PassRefPtr<WebGLContextAttributes> WebGLRenderingContextBase::getContextAttributes()
+{
+ if (isContextLost())
+ return nullptr;
+ // We always need to return a new WebGLContextAttributes object to
+ // prevent the user from mutating any cached version.
+ blink::WebGraphicsContext3D::Attributes attrs = m_drawingBuffer->getActualAttributes();
+ RefPtr<WebGLContextAttributes> attributes = m_requestedAttributes->clone();
+ // Some requested attributes may not be honored, so we need to query the underlying
+ // context/drawing buffer and adjust accordingly.
+ if (m_requestedAttributes->depth() && !attrs.depth)
+ attributes->setDepth(false);
+ if (m_requestedAttributes->stencil() && !attrs.stencil)
+ attributes->setStencil(false);
+ attributes->setAntialias(m_drawingBuffer->multisample());
+ return attributes.release();
+}
+
+GLenum WebGLRenderingContextBase::getError()
+{
+ if (m_lostContextErrors.size()) {
+ GLenum err = m_lostContextErrors.first();
+ m_lostContextErrors.remove(0);
+ return err;
+ }
+
+ if (isContextLost())
+ return GL_NO_ERROR;
+
+ return webContext()->getError();
+}
+
+const char* const* WebGLRenderingContextBase::ExtensionTracker::prefixes() const
+{
+ static const char* const unprefixed[] = { "", 0, };
+ return m_prefixes ? m_prefixes : unprefixed;
+}
+
+bool WebGLRenderingContextBase::ExtensionTracker::matchesNameWithPrefixes(const String& name) const
+{
+ const char* const* prefixSet = prefixes();
+ for (; *prefixSet; ++prefixSet) {
+ String prefixedName = String(*prefixSet) + extensionName();
+ if (equalIgnoringCase(prefixedName, name)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool WebGLRenderingContextBase::extensionSupportedAndAllowed(const ExtensionTracker* tracker)
+{
+ if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
+ return false;
+ if (!tracker->supported(this))
+ return false;
+ return true;
+}
+
+
+PassRefPtr<WebGLExtension> WebGLRenderingContextBase::getExtension(const String& name)
+{
+ if (isContextLost())
+ return nullptr;
+
+ for (size_t i = 0; i < m_extensions.size(); ++i) {
+ ExtensionTracker* tracker = m_extensions[i];
+ if (tracker->matchesNameWithPrefixes(name)) {
+ if (!extensionSupportedAndAllowed(tracker))
+ return nullptr;
+
+ RefPtr<WebGLExtension> extension = tracker->getExtension(this);
+ if (extension)
+ m_extensionEnabled[extension->name()] = true;
+ return extension.release();
+ }
+ }
+
+ return nullptr;
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname)
+{
+ if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
+ return WebGLGetInfo();
+
+ if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
+ return WebGLGetInfo();
+ }
+
+ WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
+ if (!object) {
+ if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+ return WebGLGetInfo(GL_NONE);
+ // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
+ // specifies INVALID_OPERATION.
+ synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+
+ ASSERT(object->isTexture() || object->isRenderbuffer());
+ if (object->isTexture()) {
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(GL_TEXTURE);
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(static_cast<WebGLTexture*>(object)));
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+ case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+ {
+ GLint value = 0;
+ webContext()->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+ return WebGLGetInfo(value);
+ }
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
+ return WebGLGetInfo();
+ }
+ } else {
+ switch (pname) {
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+ return WebGLGetInfo(GL_RENDERBUFFER);
+ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(static_cast<WebGLRenderbuffer*>(object)));
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
+ return WebGLGetInfo();
+ }
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getParameter(GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ const int intZero = 0;
+ switch (pname) {
+ case GL_ACTIVE_TEXTURE:
+ return getUnsignedIntParameter(pname);
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_ALPHA_BITS:
+ return getIntParameter(pname);
+ case GL_ARRAY_BUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
+ case GL_BLEND:
+ return getBooleanParameter(pname);
+ case GL_BLEND_COLOR:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_BLEND_DST_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_DST_RGB:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_EQUATION_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_EQUATION_RGB:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_SRC_ALPHA:
+ return getUnsignedIntParameter(pname);
+ case GL_BLEND_SRC_RGB:
+ return getUnsignedIntParameter(pname);
+ case GL_BLUE_BITS:
+ return getIntParameter(pname);
+ case GL_COLOR_CLEAR_VALUE:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_COLOR_WRITEMASK:
+ return getBooleanArrayParameter(pname);
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()));
+ case GL_CULL_FACE:
+ return getBooleanParameter(pname);
+ case GL_CULL_FACE_MODE:
+ return getUnsignedIntParameter(pname);
+ case GL_CURRENT_PROGRAM:
+ return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
+ case GL_DEPTH_BITS:
+ if (!m_framebufferBinding && !m_requestedAttributes->depth())
+ return WebGLGetInfo(intZero);
+ return getIntParameter(pname);
+ case GL_DEPTH_CLEAR_VALUE:
+ return getFloatParameter(pname);
+ case GL_DEPTH_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GL_DEPTH_RANGE:
+ return getWebGLFloatArrayParameter(pname);
+ case GL_DEPTH_TEST:
+ return getBooleanParameter(pname);
+ case GL_DEPTH_WRITEMASK:
+ return getBooleanParameter(pname);
+ case GL_DITHER:
+ return getBooleanParameter(pname);
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->boundElementArrayBuffer()));
+ case GL_FRAMEBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
+ case GL_FRONT_FACE:
+ return getUnsignedIntParameter(pname);
+ case GL_GENERATE_MIPMAP_HINT:
+ return getUnsignedIntParameter(pname);
+ case GL_GREEN_BITS:
+ return getIntParameter(pname);
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
+ return getIntParameter(pname);
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE:
+ return getIntParameter(pname);
+ case GL_LINE_WIDTH:
+ return getFloatParameter(pname);
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+ return getIntParameter(pname);
+ case GL_MAX_RENDERBUFFER_SIZE:
+ return getIntParameter(pname);
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GL_MAX_TEXTURE_SIZE:
+ return getIntParameter(pname);
+ case GL_MAX_VARYING_VECTORS:
+ return getIntParameter(pname);
+ case GL_MAX_VERTEX_ATTRIBS:
+ return getIntParameter(pname);
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+ return getIntParameter(pname);
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
+ return getIntParameter(pname);
+ case GL_MAX_VIEWPORT_DIMS:
+ return getWebGLIntArrayParameter(pname);
+ case GL_NUM_SHADER_BINARY_FORMATS:
+ // FIXME: should we always return 0 for this?
+ return getIntParameter(pname);
+ case GL_PACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GL_POLYGON_OFFSET_FACTOR:
+ return getFloatParameter(pname);
+ case GL_POLYGON_OFFSET_FILL:
+ return getBooleanParameter(pname);
+ case GL_POLYGON_OFFSET_UNITS:
+ return getFloatParameter(pname);
+ case GL_RED_BITS:
+ return getIntParameter(pname);
+ case GL_RENDERBUFFER_BINDING:
+ return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
+ case GL_RENDERER:
+ return WebGLGetInfo(String("WebKit WebGL"));
+ case GL_SAMPLE_BUFFERS:
+ return getIntParameter(pname);
+ case GL_SAMPLE_COVERAGE_INVERT:
+ return getBooleanParameter(pname);
+ case GL_SAMPLE_COVERAGE_VALUE:
+ return getFloatParameter(pname);
+ case GL_SAMPLES:
+ return getIntParameter(pname);
+ case GL_SCISSOR_BOX:
+ return getWebGLIntArrayParameter(pname);
+ case GL_SCISSOR_TEST:
+ return getBooleanParameter(pname);
+ case GL_SHADING_LANGUAGE_VERSION:
+ return WebGLGetInfo("WebGL GLSL ES 1.0 (" + String(webContext()->getString(GL_SHADING_LANGUAGE_VERSION)) + ")");
+ case GL_STENCIL_BACK_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_REF:
+ return getIntParameter(pname);
+ case GL_STENCIL_BACK_VALUE_MASK:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BACK_WRITEMASK:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_BITS:
+ if (!m_framebufferBinding && !m_requestedAttributes->stencil())
+ return WebGLGetInfo(intZero);
+ return getIntParameter(pname);
+ case GL_STENCIL_CLEAR_VALUE:
+ return getIntParameter(pname);
+ case GL_STENCIL_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_FUNC:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_REF:
+ return getIntParameter(pname);
+ case GL_STENCIL_TEST:
+ return getBooleanParameter(pname);
+ case GL_STENCIL_VALUE_MASK:
+ return getUnsignedIntParameter(pname);
+ case GL_STENCIL_WRITEMASK:
+ return getUnsignedIntParameter(pname);
+ case GL_SUBPIXEL_BITS:
+ return getIntParameter(pname);
+ case GL_TEXTURE_BINDING_2D:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
+ case GL_TEXTURE_BINDING_CUBE_MAP:
+ return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
+ case GL_UNPACK_ALIGNMENT:
+ return getIntParameter(pname);
+ case GC3D_UNPACK_FLIP_Y_WEBGL:
+ return WebGLGetInfo(m_unpackFlipY);
+ case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ return WebGLGetInfo(m_unpackPremultiplyAlpha);
+ case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ return WebGLGetInfo(m_unpackColorspaceConversion);
+ case GL_VENDOR:
+ return WebGLGetInfo(String("WebKit"));
+ case GL_VERSION:
+ return WebGLGetInfo("WebGL 1.0 (" + String(webContext()->getString(GL_VERSION)) + ")");
+ case GL_VIEWPORT:
+ return getWebGLIntArrayParameter(pname);
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+ if (extensionEnabled(OESStandardDerivativesName))
+ return getUnsignedIntParameter(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
+ return WebGLGetInfo();
+ case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
+ if (extensionEnabled(WebGLDebugRendererInfoName))
+ return WebGLGetInfo(webContext()->getString(GL_RENDERER));
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+ return WebGLGetInfo();
+ case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
+ if (extensionEnabled(WebGLDebugRendererInfoName))
+ return WebGLGetInfo(webContext()->getString(GL_VENDOR));
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+ return WebGLGetInfo();
+ case GL_VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
+ if (extensionEnabled(OESVertexArrayObjectName)) {
+ if (!m_boundVertexArrayObject->isDefaultObject())
+ return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
+ return WebGLGetInfo();
+ }
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
+ return WebGLGetInfo();
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (extensionEnabled(EXTTextureFilterAnisotropicName))
+ return getUnsignedIntParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+ return WebGLGetInfo();
+ case GL_MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
+ if (extensionEnabled(WebGLDrawBuffersName))
+ return WebGLGetInfo(maxColorAttachments());
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
+ return WebGLGetInfo();
+ case GL_MAX_DRAW_BUFFERS_EXT:
+ if (extensionEnabled(WebGLDrawBuffersName))
+ return WebGLGetInfo(maxDrawBuffers());
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
+ return WebGLGetInfo();
+ default:
+ if (extensionEnabled(WebGLDrawBuffersName)
+ && pname >= GL_DRAW_BUFFER0_EXT
+ && pname < static_cast<GLenum>(GL_DRAW_BUFFER0_EXT + maxDrawBuffers())) {
+ GLint value = GL_NONE;
+ if (m_framebufferBinding)
+ value = m_framebufferBinding->getDrawBuffer(pname);
+ else // emulated backbuffer
+ value = m_backDrawBuffer;
+ return WebGLGetInfo(value);
+ }
+ synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getProgramParameter(WebGLProgram* program, GLenum pname)
+{
+ if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
+ return WebGLGetInfo();
+
+ GLint value = 0;
+ switch (pname) {
+ case GL_DELETE_STATUS:
+ return WebGLGetInfo(program->isDeleted());
+ case GL_VALIDATE_STATUS:
+ webContext()->getProgramiv(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+ case GL_LINK_STATUS:
+ return WebGLGetInfo(program->linkStatus());
+ case GL_ATTACHED_SHADERS:
+ case GL_ACTIVE_ATTRIBUTES:
+ case GL_ACTIVE_UNIFORMS:
+ webContext()->getProgramiv(objectOrZero(program), pname, &value);
+ return WebGLGetInfo(value);
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContextBase::getProgramInfoLog(WebGLProgram* program)
+{
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getProgramInfoLog", program))
+ return "";
+ return ensureNotNull(webContext()->getProgramInfoLog(objectOrZero(program)));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getRenderbufferParameter(GLenum target, GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (target != GL_RENDERBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid target");
+ return WebGLGetInfo();
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
+ return WebGLGetInfo();
+ }
+
+ GLint value = 0;
+ switch (pname) {
+ case GL_RENDERBUFFER_WIDTH:
+ case GL_RENDERBUFFER_HEIGHT:
+ case GL_RENDERBUFFER_RED_SIZE:
+ case GL_RENDERBUFFER_GREEN_SIZE:
+ case GL_RENDERBUFFER_BLUE_SIZE:
+ case GL_RENDERBUFFER_ALPHA_SIZE:
+ case GL_RENDERBUFFER_DEPTH_SIZE:
+ webContext()->getRenderbufferParameteriv(target, pname, &value);
+ return WebGLGetInfo(value);
+ case GL_RENDERBUFFER_STENCIL_SIZE:
+ if (m_renderbufferBinding->emulatedStencilBuffer()) {
+ webContext()->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding->emulatedStencilBuffer()));
+ webContext()->getRenderbufferParameteriv(target, pname, &value);
+ webContext()->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+ } else {
+ webContext()->getRenderbufferParameteriv(target, pname, &value);
+ }
+ return WebGLGetInfo(value);
+ case GL_RENDERBUFFER_INTERNAL_FORMAT:
+ return WebGLGetInfo(m_renderbufferBinding->internalFormat());
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getShaderParameter(WebGLShader* shader, GLenum pname)
+{
+ if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
+ return WebGLGetInfo();
+ GLint value = 0;
+ switch (pname) {
+ case GL_DELETE_STATUS:
+ return WebGLGetInfo(shader->isDeleted());
+ case GL_COMPILE_STATUS:
+ webContext()->getShaderiv(objectOrZero(shader), pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+ case GL_SHADER_TYPE:
+ webContext()->getShaderiv(objectOrZero(shader), pname, &value);
+ return WebGLGetInfo(static_cast<unsigned>(value));
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+String WebGLRenderingContextBase::getShaderInfoLog(WebGLShader* shader)
+{
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getShaderInfoLog", shader))
+ return "";
+ return ensureNotNull(webContext()->getShaderInfoLog(objectOrZero(shader)));
+}
+
+PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContextBase::getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType)
+{
+ if (isContextLost())
+ return nullptr;
+ switch (shaderType) {
+ case GL_VERTEX_SHADER:
+ case GL_FRAGMENT_SHADER:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
+ return nullptr;
+ }
+ switch (precisionType) {
+ case GL_LOW_FLOAT:
+ case GL_MEDIUM_FLOAT:
+ case GL_HIGH_FLOAT:
+ case GL_LOW_INT:
+ case GL_MEDIUM_INT:
+ case GL_HIGH_INT:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
+ return nullptr;
+ }
+
+ GLint range[2] = {0, 0};
+ GLint precision = 0;
+ webContext()->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
+ return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
+}
+
+String WebGLRenderingContextBase::getShaderSource(WebGLShader* shader)
+{
+ if (isContextLost())
+ return String();
+ if (!validateWebGLObject("getShaderSource", shader))
+ return "";
+ return ensureNotNull(shader->source());
+}
+
+Vector<String> WebGLRenderingContextBase::getSupportedExtensions()
+{
+ Vector<String> result;
+ if (isContextLost())
+ return result;
+
+ for (size_t i = 0; i < m_extensions.size(); ++i) {
+ ExtensionTracker* tracker = m_extensions[i];
+ if (extensionSupportedAndAllowed(tracker)) {
+ const char* const* prefixes = tracker->prefixes();
+ for (; *prefixes; ++prefixes) {
+ String prefixedName = String(*prefixes) + tracker->extensionName();
+ result.append(prefixedName);
+ }
+ }
+ }
+
+ return result;
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getTexParameter(GLenum target, GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
+ if (!tex)
+ return WebGLGetInfo();
+ switch (pname) {
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ {
+ GLint value = 0;
+ webContext()->getTexParameteriv(target, pname, &value);
+ return WebGLGetInfo(static_cast<unsigned>(value));
+ }
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (extensionEnabled(EXTTextureFilterAnisotropicName)) {
+ GLfloat value = 0.f;
+ webContext()->getTexParameterfv(target, pname, &value);
+ return WebGLGetInfo(value);
+ }
+ synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+ return WebGLGetInfo();
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation)
+{
+ if (isContextLost() || !validateWebGLObject("getUniform", program))
+ return WebGLGetInfo();
+ if (!uniformLocation || uniformLocation->program() != program) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
+ return WebGLGetInfo();
+ }
+ GLint location = uniformLocation->location();
+
+ // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
+ GLint activeUniforms = 0;
+ webContext()->getProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORMS, &activeUniforms);
+ for (GLint i = 0; i < activeUniforms; i++) {
+ blink::WebGraphicsContext3D::ActiveInfo info;
+ if (!webContext()->getActiveUniform(objectOrZero(program), i, info))
+ return WebGLGetInfo();
+ String name = info.name;
+ StringBuilder nameBuilder;
+ // Strip "[0]" from the name if it's an array.
+ if (info.size > 1 && name.endsWith("[0]"))
+ info.name = name.left(name.length() - 3);
+ // If it's an array, we need to iterate through each element, appending "[index]" to the name.
+ for (GLint index = 0; index < info.size; ++index) {
+ nameBuilder.clear();
+ nameBuilder.append(info.name);
+ if (info.size > 1 && index >= 1) {
+ nameBuilder.append('[');
+ nameBuilder.append(String::number(index));
+ nameBuilder.append(']');
+ }
+ // Now need to look this up by name again to find its location
+ GLint loc = webContext()->getUniformLocation(objectOrZero(program), nameBuilder.toString().utf8().data());
+ if (loc == location) {
+ // Found it. Use the type in the ActiveInfo to determine the return type.
+ GLenum baseType;
+ unsigned length;
+ switch (info.type) {
+ case GL_BOOL:
+ baseType = GL_BOOL;
+ length = 1;
+ break;
+ case GL_BOOL_VEC2:
+ baseType = GL_BOOL;
+ length = 2;
+ break;
+ case GL_BOOL_VEC3:
+ baseType = GL_BOOL;
+ length = 3;
+ break;
+ case GL_BOOL_VEC4:
+ baseType = GL_BOOL;
+ length = 4;
+ break;
+ case GL_INT:
+ baseType = GL_INT;
+ length = 1;
+ break;
+ case GL_INT_VEC2:
+ baseType = GL_INT;
+ length = 2;
+ break;
+ case GL_INT_VEC3:
+ baseType = GL_INT;
+ length = 3;
+ break;
+ case GL_INT_VEC4:
+ baseType = GL_INT;
+ length = 4;
+ break;
+ case GL_FLOAT:
+ baseType = GL_FLOAT;
+ length = 1;
+ break;
+ case GL_FLOAT_VEC2:
+ baseType = GL_FLOAT;
+ length = 2;
+ break;
+ case GL_FLOAT_VEC3:
+ baseType = GL_FLOAT;
+ length = 3;
+ break;
+ case GL_FLOAT_VEC4:
+ baseType = GL_FLOAT;
+ length = 4;
+ break;
+ case GL_FLOAT_MAT2:
+ baseType = GL_FLOAT;
+ length = 4;
+ break;
+ case GL_FLOAT_MAT3:
+ baseType = GL_FLOAT;
+ length = 9;
+ break;
+ case GL_FLOAT_MAT4:
+ baseType = GL_FLOAT;
+ length = 16;
+ break;
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
+ baseType = GL_INT;
+ length = 1;
+ break;
+ default:
+ // Can't handle this type
+ synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type");
+ return WebGLGetInfo();
+ }
+ switch (baseType) {
+ case GL_FLOAT: {
+ GLfloat value[16] = {0};
+ webContext()->getUniformfv(objectOrZero(program), location, value);
+ if (length == 1)
+ return WebGLGetInfo(value[0]);
+ return WebGLGetInfo(Float32Array::create(value, length));
+ }
+ case GL_INT: {
+ GLint value[4] = {0};
+ webContext()->getUniformiv(objectOrZero(program), location, value);
+ if (length == 1)
+ return WebGLGetInfo(value[0]);
+ return WebGLGetInfo(Int32Array::create(value, length));
+ }
+ case GL_BOOL: {
+ GLint value[4] = {0};
+ webContext()->getUniformiv(objectOrZero(program), location, value);
+ if (length > 1) {
+ bool boolValue[16] = {0};
+ for (unsigned j = 0; j < length; j++)
+ boolValue[j] = static_cast<bool>(value[j]);
+ return WebGLGetInfo(boolValue, length);
+ }
+ return WebGLGetInfo(static_cast<bool>(value[0]));
+ }
+ default:
+ notImplemented();
+ }
+ }
+ }
+ }
+ // If we get here, something went wrong in our unfortunately complex logic above
+ synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error");
+ return WebGLGetInfo();
+}
+
+PassRefPtr<WebGLUniformLocation> WebGLRenderingContextBase::getUniformLocation(WebGLProgram* program, const String& name)
+{
+ if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
+ return nullptr;
+ if (!validateLocationLength("getUniformLocation", name))
+ return nullptr;
+ if (!validateString("getUniformLocation", name))
+ return nullptr;
+ if (isPrefixReserved(name))
+ return nullptr;
+ if (!program->linkStatus()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "getUniformLocation", "program not linked");
+ return nullptr;
+ }
+ GLint uniformLocation = webContext()->getUniformLocation(objectOrZero(program), name.utf8().data());
+ if (uniformLocation == -1)
+ return nullptr;
+ return WebGLUniformLocation::create(program, uniformLocation);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getVertexAttrib(GLuint index, GLenum pname)
+{
+ if (isContextLost())
+ return WebGLGetInfo();
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range");
+ return WebGLGetInfo();
+ }
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+
+ if (extensionEnabled(ANGLEInstancedArraysName) && pname == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
+ return WebGLGetInfo(state.divisor);
+
+ switch (pname) {
+ case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+ if (!state.bufferBinding || !state.bufferBinding->object())
+ return WebGLGetInfo();
+ return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
+ case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+ return WebGLGetInfo(state.enabled);
+ case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+ return WebGLGetInfo(state.normalized);
+ case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+ return WebGLGetInfo(state.size);
+ case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+ return WebGLGetInfo(state.originalStride);
+ case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+ return WebGLGetInfo(state.type);
+ case GL_CURRENT_VERTEX_ATTRIB:
+ return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
+ return WebGLGetInfo();
+ }
+}
+
+long long WebGLRenderingContextBase::getVertexAttribOffset(GLuint index, GLenum pname)
+{
+ if (isContextLost())
+ return 0;
+ if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) {
+ synthesizeGLError(GL_INVALID_ENUM, "getVertexAttribOffset", "invalid parameter name");
+ return 0;
+ }
+ GLsizeiptr result = webContext()->getVertexAttribOffset(index, pname);
+ return static_cast<long long>(result);
+}
+
+void WebGLRenderingContextBase::hint(GLenum target, GLenum mode)
+{
+ if (isContextLost())
+ return;
+ bool isValid = false;
+ switch (target) {
+ case GL_GENERATE_MIPMAP_HINT:
+ isValid = true;
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+ if (extensionEnabled(OESStandardDerivativesName))
+ isValid = true;
+ break;
+ }
+ if (!isValid) {
+ synthesizeGLError(GL_INVALID_ENUM, "hint", "invalid target");
+ return;
+ }
+ webContext()->hint(target, mode);
+}
+
+GLboolean WebGLRenderingContextBase::isBuffer(WebGLBuffer* buffer)
+{
+ if (!buffer || isContextLost())
+ return 0;
+
+ if (!buffer->hasEverBeenBound())
+ return 0;
+
+ return webContext()->isBuffer(buffer->object());
+}
+
+bool WebGLRenderingContextBase::isContextLost() const
+{
+ return m_contextLost;
+}
+
+GLboolean WebGLRenderingContextBase::isEnabled(GLenum cap)
+{
+ if (isContextLost() || !validateCapability("isEnabled", cap))
+ return 0;
+ if (cap == GL_STENCIL_TEST)
+ return m_stencilEnabled;
+ return webContext()->isEnabled(cap);
+}
+
+GLboolean WebGLRenderingContextBase::isFramebuffer(WebGLFramebuffer* framebuffer)
+{
+ if (!framebuffer || isContextLost())
+ return 0;
+
+ if (!framebuffer->hasEverBeenBound())
+ return 0;
+
+ return webContext()->isFramebuffer(framebuffer->object());
+}
+
+GLboolean WebGLRenderingContextBase::isProgram(WebGLProgram* program)
+{
+ if (!program || isContextLost())
+ return 0;
+
+ return webContext()->isProgram(program->object());
+}
+
+GLboolean WebGLRenderingContextBase::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+ if (!renderbuffer || isContextLost())
+ return 0;
+
+ if (!renderbuffer->hasEverBeenBound())
+ return 0;
+
+ return webContext()->isRenderbuffer(renderbuffer->object());
+}
+
+GLboolean WebGLRenderingContextBase::isShader(WebGLShader* shader)
+{
+ if (!shader || isContextLost())
+ return 0;
+
+ return webContext()->isShader(shader->object());
+}
+
+GLboolean WebGLRenderingContextBase::isTexture(WebGLTexture* texture)
+{
+ if (!texture || isContextLost())
+ return 0;
+
+ if (!texture->hasEverBeenBound())
+ return 0;
+
+ return webContext()->isTexture(texture->object());
+}
+
+void WebGLRenderingContextBase::lineWidth(GLfloat width)
+{
+ if (isContextLost())
+ return;
+ webContext()->lineWidth(width);
+}
+
+void WebGLRenderingContextBase::linkProgram(WebGLProgram* program)
+{
+ if (isContextLost() || !validateWebGLObject("linkProgram", program))
+ return;
+
+ webContext()->linkProgram(objectOrZero(program));
+ program->increaseLinkCount();
+}
+
+void WebGLRenderingContextBase::pixelStorei(GLenum pname, GLint param)
+{
+ if (isContextLost())
+ return;
+ switch (pname) {
+ case GC3D_UNPACK_FLIP_Y_WEBGL:
+ m_unpackFlipY = param;
+ break;
+ case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+ m_unpackPremultiplyAlpha = param;
+ break;
+ case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
+ if (static_cast<GLenum>(param) == GC3D_BROWSER_DEFAULT_WEBGL || param == GL_NONE) {
+ m_unpackColorspaceConversion = static_cast<GLenum>(param);
+ } else {
+ synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
+ return;
+ }
+ break;
+ case GL_PACK_ALIGNMENT:
+ case GL_UNPACK_ALIGNMENT:
+ if (param == 1 || param == 2 || param == 4 || param == 8) {
+ if (pname == GL_PACK_ALIGNMENT) {
+ m_packAlignment = param;
+ m_drawingBuffer->setPackAlignment(param);
+ } else { // GL_UNPACK_ALIGNMENT:
+ m_unpackAlignment = param;
+ }
+ webContext()->pixelStorei(pname, param);
+ } else {
+ synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
+ return;
+ }
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "pixelStorei", "invalid parameter name");
+ return;
+ }
+}
+
+void WebGLRenderingContextBase::polygonOffset(GLfloat factor, GLfloat units)
+{
+ if (isContextLost())
+ return;
+ webContext()->polygonOffset(factor, units);
+}
+
+void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels)
+{
+ if (isContextLost())
+ return;
+ // Due to WebGL's same-origin restrictions, it is not possible to
+ // taint the origin using the WebGL API.
+ ASSERT(canvas()->originClean());
+ // Validate input parameters.
+ if (!pixels) {
+ synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
+ return;
+ }
+ switch (format) {
+ case GL_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid format");
+ return;
+ }
+
+ ArrayBufferView::ViewType expectedViewType;
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ expectedViewType = ArrayBufferView::TypeUint8;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ expectedViewType = ArrayBufferView::TypeUint16;
+ break;
+ case GL_FLOAT:
+ expectedViewType = ArrayBufferView::TypeFloat32;
+ break;
+ case GL_HALF_FLOAT_OES:
+ expectedViewType = ArrayBufferView::TypeUint16;
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid type");
+ return;
+ }
+ if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) {
+ // Check against the implementation color read format and type.
+ blink::WGC3Dint implFormat = 0, implType = 0;
+ webContext()->getIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &implFormat);
+ webContext()->getIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &implType);
+ if (!implFormat || !implType || format != static_cast<GLenum>(implFormat) || type != static_cast<GLenum>(implType)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format/type not RGBA/UNSIGNED_BYTE or implementation-defined values");
+ return;
+ }
+ }
+ // Validate array type against pixel type.
+ if (pixels->type() != expectedViewType) {
+ synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView was the wrong type for the pixel format");
+ return;
+ }
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
+ return;
+ }
+ // Calculate array size, taking into consideration of PACK_ALIGNMENT.
+ unsigned totalBytesRequired = 0;
+ unsigned padding = 0;
+ GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
+ if (error != GL_NO_ERROR) {
+ synthesizeGLError(error, "readPixels", "invalid dimensions");
+ return;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
+ return;
+ }
+
+ clearIfComposited();
+ void* data = pixels->baseAddress();
+
+ {
+ ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+ webContext()->readPixels(x, y, width, height, format, type, data);
+ }
+
+#if OS(MACOSX)
+ // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
+ // when alpha is off, readPixels should set alpha to 255 instead of 0.
+ if (!m_framebufferBinding && !m_drawingBuffer->getActualAttributes().alpha) {
+ unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
+ for (GLsizei iy = 0; iy < height; ++iy) {
+ for (GLsizei ix = 0; ix < width; ++ix) {
+ pixels[3] = 255;
+ pixels += 4;
+ }
+ pixels += padding;
+ }
+ }
+#endif
+}
+
+void WebGLRenderingContextBase::renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ if (isContextLost())
+ return;
+ if (target != GL_RENDERBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid target");
+ return;
+ }
+ if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
+ return;
+ }
+ if (!validateSize("renderbufferStorage", width, height))
+ return;
+ switch (internalformat) {
+ case GL_DEPTH_COMPONENT16:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ case GL_STENCIL_INDEX8:
+ webContext()->renderbufferStorage(target, internalformat, width, height);
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ m_renderbufferBinding->setSize(width, height);
+ m_renderbufferBinding->deleteEmulatedStencilBuffer(webContext());
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ if (isDepthStencilSupported()) {
+ webContext()->renderbufferStorage(target, GL_DEPTH24_STENCIL8_OES, width, height);
+ } else {
+ WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(target, m_renderbufferBinding.get());
+ if (!emulatedStencilBuffer) {
+ synthesizeGLError(GL_OUT_OF_MEMORY, "renderbufferStorage", "out of memory");
+ return;
+ }
+ webContext()->renderbufferStorage(target, GL_DEPTH_COMPONENT16, width, height);
+ webContext()->bindRenderbuffer(target, objectOrZero(emulatedStencilBuffer));
+ webContext()->renderbufferStorage(target, GL_STENCIL_INDEX8, width, height);
+ webContext()->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+ emulatedStencilBuffer->setSize(width, height);
+ emulatedStencilBuffer->setInternalFormat(GL_STENCIL_INDEX8);
+ }
+ m_renderbufferBinding->setSize(width, height);
+ m_renderbufferBinding->setInternalFormat(internalformat);
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
+ return;
+ }
+ applyStencilTest();
+}
+
+void WebGLRenderingContextBase::sampleCoverage(GLfloat value, GLboolean invert)
+{
+ if (isContextLost())
+ return;
+ webContext()->sampleCoverage(value, invert);
+}
+
+void WebGLRenderingContextBase::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateSize("scissor", width, height))
+ return;
+ webContext()->scissor(x, y, width, height);
+}
+
+void WebGLRenderingContextBase::shaderSource(WebGLShader* shader, const String& string)
+{
+ if (isContextLost() || !validateWebGLObject("shaderSource", shader))
+ return;
+ String stringWithoutComments = StripComments(string).result();
+ if (!validateString("shaderSource", stringWithoutComments))
+ return;
+ shader->setSource(string);
+ webContext()->shaderSource(objectOrZero(shader), stringWithoutComments.utf8().data());
+}
+
+void WebGLRenderingContextBase::stencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilOrDepthFunc("stencilFunc", func))
+ return;
+ m_stencilFuncRef = ref;
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMask = mask;
+ m_stencilFuncMaskBack = mask;
+ webContext()->stencilFunc(func, ref, mask);
+}
+
+void WebGLRenderingContextBase::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+ if (isContextLost())
+ return;
+ if (!validateStencilOrDepthFunc("stencilFuncSeparate", func))
+ return;
+ switch (face) {
+ case GL_FRONT_AND_BACK:
+ m_stencilFuncRef = ref;
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMask = mask;
+ m_stencilFuncMaskBack = mask;
+ break;
+ case GL_FRONT:
+ m_stencilFuncRef = ref;
+ m_stencilFuncMask = mask;
+ break;
+ case GL_BACK:
+ m_stencilFuncRefBack = ref;
+ m_stencilFuncMaskBack = mask;
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "stencilFuncSeparate", "invalid face");
+ return;
+ }
+ webContext()->stencilFuncSeparate(face, func, ref, mask);
+}
+
+void WebGLRenderingContextBase::stencilMask(GLuint mask)
+{
+ if (isContextLost())
+ return;
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ webContext()->stencilMask(mask);
+}
+
+void WebGLRenderingContextBase::stencilMaskSeparate(GLenum face, GLuint mask)
+{
+ if (isContextLost())
+ return;
+ switch (face) {
+ case GL_FRONT_AND_BACK:
+ m_stencilMask = mask;
+ m_stencilMaskBack = mask;
+ break;
+ case GL_FRONT:
+ m_stencilMask = mask;
+ break;
+ case GL_BACK:
+ m_stencilMaskBack = mask;
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "stencilMaskSeparate", "invalid face");
+ return;
+ }
+ webContext()->stencilMaskSeparate(face, mask);
+}
+
+void WebGLRenderingContextBase::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+ if (isContextLost())
+ return;
+ webContext()->stencilOp(fail, zfail, zpass);
+}
+
+void WebGLRenderingContextBase::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+ if (isContextLost())
+ return;
+ webContext()->stencilOpSeparate(face, fail, zfail, zpass);
+}
+
+GLenum WebGLRenderingContextBase::convertTexInternalFormat(GLenum internalformat, GLenum type)
+{
+ // Convert to sized internal formats that are renderable with GL_CHROMIUM_color_buffer_float_rgb(a).
+ if (type == GL_FLOAT && internalformat == GL_RGBA
+ && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"))
+ return GL_RGBA32F_EXT;
+ if (type == GL_FLOAT && internalformat == GL_RGB
+ && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"))
+ return GL_RGB32F_EXT;
+ return internalformat;
+}
+
+void WebGLRenderingContextBase::texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState& exceptionState)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ // FIXME: Handle errors.
+ WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
+ ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
+ ASSERT(tex);
+ ASSERT(!level || !WebGLTexture::isNPOT(width, height));
+ ASSERT(!pixels || validateSettableTexFormat("texImage2D", internalformat));
+ webContext()->texImage2D(target, level, convertTexInternalFormat(internalformat, type), width, height, border, format, type, pixels);
+ tex->setLevelInfo(target, level, internalformat, width, height, type);
+}
+
+void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ Vector<uint8_t> data;
+ WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "packImage error");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), 0, format, type, needConversion ? data.data() : imagePixelData, exceptionState);
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset)
+{
+ if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
+ return false;
+
+ WebGLTexture* texture = validateTextureBinding(functionName, target, true);
+ if (!texture)
+ return false;
+
+ if (functionType == NotTexSubImage2D) {
+ if (level && WebGLTexture::isNPOT(width, height)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "level > 0 not power of 2");
+ return false;
+ }
+ // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
+ // by checking if the ArrayBufferView is null or not.
+ if (sourceType != SourceArrayBufferView) {
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+ }
+ } else {
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+ if (!validateSize(functionName, xoffset, yoffset))
+ return false;
+ // Before checking if it is in the range, check if overflow happens first.
+ if (xoffset + width < 0 || yoffset + height < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions");
+ return false;
+ }
+ if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range");
+ return false;
+ }
+ if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type and format do not match texture");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateValueFitNonNegInt32(const char* functionName, const char* paramName, long long value)
+{
+ if (value < 0) {
+ String errorMsg = String(paramName) + " < 0";
+ synthesizeGLError(GL_INVALID_VALUE, functionName, errorMsg.ascii().data());
+ return false;
+ }
+ if (value > static_cast<long long>(std::numeric_limits<int>::max())) {
+ String errorMsg = String(paramName) + " more than 32-bit";
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, errorMsg.ascii().data());
+ return false;
+ }
+ return true;
+}
+
+PassRefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer(Image* image, int width, int height, const char* functionName)
+{
+ IntSize size(width, height);
+ ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+ if (!buf) {
+ synthesizeGLError(GL_OUT_OF_MEMORY, functionName, "out of memory");
+ return nullptr;
+ }
+
+ IntRect srcRect(IntPoint(), image->size());
+ IntRect destRect(0, 0, size.width(), size.height());
+ buf->context()->drawImage(image, destRect, srcRect);
+ return buf->copyImage(ImageBuffer::fastCopyImageMode());
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
+ || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
+ return;
+ void* data = pixels ? pixels->baseAddress() : 0;
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, width, height, border, format, type, data, exceptionState);
+ if (changeUnpackAlignment)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, ImageData* pixels, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
+ return;
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+ needConversion = false;
+ else {
+ if (!WebGLImageConversion::extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+ return;
+ }
+ }
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLImageElement("texImage2D", image, exceptionState))
+ return;
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), "texImage2D");
+
+ if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
+ return;
+
+ texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, exceptionState) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
+ return;
+
+ WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+
+ // If possible, copy from the canvas element directly to the texture
+ // via the GPU, without a read-back to system memory.
+ if (GL_TEXTURE_2D == target && texture) {
+ ScopedTexture2DRestorer restorer(this);
+
+ if (!canvas->is3D()) {
+ ImageBuffer* buffer = canvas->buffer();
+ if (buffer && buffer->copyToPlatformTexture(webContext(), texture->object(), internalformat, type,
+ level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+ return;
+ }
+ } else {
+ WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext());
+ ScopedTexture2DRestorer restorer(gl);
+ if (gl && gl->m_drawingBuffer->copyToPlatformTexture(webContext(), texture->object(), internalformat, type,
+ level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+ return;
+ }
+ }
+ }
+
+ RefPtrWillBeRawPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texImage2D(target, level, internalformat, format, type, imageData.get(), exceptionState);
+ else
+ texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
+{
+ IntSize size(video->videoWidth(), video->videoHeight());
+ ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+ if (!buf) {
+ synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
+ return nullptr;
+ }
+ IntRect destRect(0, 0, size.width(), size.height());
+ // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
+ video->paintCurrentFrameInContext(buf->context(), destRect);
+ return buf->copyImage(backingStoreCopy);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, exceptionState)
+ || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
+ return;
+
+ // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
+ // Otherwise, it will fall back to the normal SW path.
+ WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+ if (GL_TEXTURE_2D == target && texture) {
+ if (video->copyVideoTextureToPlatformTexture(webContext(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+ texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
+ return;
+ }
+ }
+
+ // Normal pure SW path.
+ RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
+ if (!image)
+ return;
+ texImage2DImpl(target, level, internalformat, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloat paramf, GLint parami, bool isFloat)
+{
+ if (isContextLost())
+ return;
+ WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
+ if (!tex)
+ return;
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ break;
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ if ((isFloat && paramf != GL_CLAMP_TO_EDGE && paramf != GL_MIRRORED_REPEAT && paramf != GL_REPEAT)
+ || (!isFloat && parami != GL_CLAMP_TO_EDGE && parami != GL_MIRRORED_REPEAT && parami != GL_REPEAT)) {
+ synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter");
+ return;
+ }
+ break;
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+ if (!extensionEnabled(EXTTextureFilterAnisotropicName)) {
+ synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
+ return;
+ }
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter name");
+ return;
+ }
+ if (isFloat) {
+ tex->setParameterf(pname, paramf);
+ webContext()->texParameterf(target, pname, paramf);
+ } else {
+ tex->setParameteri(pname, parami);
+ webContext()->texParameteri(target, pname, parami);
+ }
+}
+
+void WebGLRenderingContextBase::texParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+ texParameter(target, pname, param, 0, true);
+}
+
+void WebGLRenderingContextBase::texParameteri(GLenum target, GLenum pname, GLint param)
+{
+ texParameter(target, pname, 0, param, false);
+}
+
+void WebGLRenderingContextBase::texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState& exceptionState)
+{
+ // FIXME: Handle errors.
+ ASSERT(!isContextLost());
+ ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
+ ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
+ ASSERT(validateSettableTexFormat("texSubImage2D", format));
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+ if (!tex) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ ASSERT((xoffset + width) >= 0);
+ ASSERT((yoffset + height) >= 0);
+ ASSERT(tex->getWidth(target, level) >= (xoffset + width));
+ ASSERT(tex->getHeight(target, level) >= (yoffset + height));
+ ASSERT(tex->getInternalFormat(target, level) == format);
+ ASSERT(tex->getType(target, level) == type);
+ webContext()->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void WebGLRenderingContextBase::texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ Vector<uint8_t> data;
+ WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
+ if (!imageExtractor.extractSucceeded()) {
+ synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image");
+ return;
+ }
+ WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+ WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+ const void* imagePixelData = imageExtractor.imagePixelData();
+
+ bool needConversion = true;
+ if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY)
+ needConversion = false;
+ else {
+ if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+ synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
+ return;
+ }
+ }
+
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texSubImage2DBase(target, level, xoffset, yoffset, imageExtractor.imageWidth(), imageExtractor.imageHeight(), format, type, needConversion ? data.data() : imagePixelData, exceptionState);
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
+ return;
+ void* data = pixels->baseAddress();
+ Vector<uint8_t> tempData;
+ bool changeUnpackAlignment = false;
+ if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+ if (!WebGLImageConversion::extractTextureData(width, height, format, type,
+ m_unpackAlignment,
+ m_unpackFlipY, m_unpackPremultiplyAlpha,
+ data,
+ tempData))
+ return;
+ data = tempData.data();
+ changeUnpackAlignment = true;
+ }
+ if (changeUnpackAlignment)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, exceptionState);
+ if (changeUnpackAlignment)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, ImageData* pixels, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format, pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ Vector<uint8_t> data;
+ bool needConversion = true;
+ // The data from ImageData is always of format RGBA8.
+ // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+ if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
+ needConversion = false;
+ else {
+ if (!WebGLImageConversion::extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+ synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
+ return;
+ }
+ }
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
+ if (m_unpackAlignment != 1)
+ webContext()->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, exceptionState))
+ return;
+
+ RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+ if (imageForRender->isSVGImage())
+ imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), "texSubImage2D");
+
+ if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
+ return;
+
+ RefPtrWillBeRawPtr<ImageData> imageData = canvas->getImageData();
+ if (imageData)
+ texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), exceptionState);
+ else
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+ if (isContextLost() || !validateHTMLVideoElement("texSubImage2D", video, exceptionState)
+ || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
+ return;
+
+ RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
+ if (!image)
+ return;
+ texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform1f(location->location(), x);
+}
+
+void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
+ return;
+
+ webContext()->uniform1fv(location->location(), v->length(), v->data());
+}
+
+void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
+ return;
+
+ webContext()->uniform1fv(location->location(), size, v);
+}
+
+void WebGLRenderingContextBase::uniform1i(const WebGLUniformLocation* location, GLint x)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform1i", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform1i(location->location(), x);
+}
+
+void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
+ return;
+
+ webContext()->uniform1iv(location->location(), v->length(), v->data());
+}
+
+void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
+ return;
+
+ webContext()->uniform1iv(location->location(), size, v);
+}
+
+void WebGLRenderingContextBase::uniform2f(const WebGLUniformLocation* location, GLfloat x, GLfloat y)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform2f", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform2f(location->location(), x, y);
+}
+
+void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
+ return;
+
+ webContext()->uniform2fv(location->location(), v->length() / 2, v->data());
+}
+
+void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
+ return;
+
+ webContext()->uniform2fv(location->location(), size / 2, v);
+}
+
+void WebGLRenderingContextBase::uniform2i(const WebGLUniformLocation* location, GLint x, GLint y)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform2i", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform2i(location->location(), x, y);
+}
+
+void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
+ return;
+
+ webContext()->uniform2iv(location->location(), v->length() / 2, v->data());
+}
+
+void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
+ return;
+
+ webContext()->uniform2iv(location->location(), size / 2, v);
+}
+
+void WebGLRenderingContextBase::uniform3f(const WebGLUniformLocation* location, GLfloat x, GLfloat y, GLfloat z)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform3f", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform3f(location->location(), x, y, z);
+}
+
+void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
+ return;
+
+ webContext()->uniform3fv(location->location(), v->length() / 3, v->data());
+}
+
+void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
+ return;
+
+ webContext()->uniform3fv(location->location(), size / 3, v);
+}
+
+void WebGLRenderingContextBase::uniform3i(const WebGLUniformLocation* location, GLint x, GLint y, GLint z)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform3i", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform3i(location->location(), x, y, z);
+}
+
+void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
+ return;
+
+ webContext()->uniform3iv(location->location(), v->length() / 3, v->data());
+}
+
+void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
+ return;
+
+ webContext()->uniform3iv(location->location(), size / 3, v);
+}
+
+void WebGLRenderingContextBase::uniform4f(const WebGLUniformLocation* location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform4f", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform4f(location->location(), x, y, z, w);
+}
+
+void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
+ return;
+
+ webContext()->uniform4fv(location->location(), v->length() / 4, v->data());
+}
+
+void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
+ return;
+
+ webContext()->uniform4fv(location->location(), size / 4, v);
+}
+
+void WebGLRenderingContextBase::uniform4i(const WebGLUniformLocation* location, GLint x, GLint y, GLint z, GLint w)
+{
+ if (isContextLost() || !location)
+ return;
+
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, "uniform4i", "location not for current program");
+ return;
+ }
+
+ webContext()->uniform4i(location->location(), x, y, z, w);
+}
+
+void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+ if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
+ return;
+
+ webContext()->uniform4iv(location->location(), v->length() / 4, v->data());
+}
+
+void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
+ return;
+
+ webContext()->uniform4iv(location->location(), size / 4, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
+ return;
+ webContext()->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
+ return;
+ webContext()->uniformMatrix2fv(location->location(), size / 4, transpose, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
+ return;
+ webContext()->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
+ return;
+ webContext()->uniformMatrix3fv(location->location(), size / 9, transpose, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
+ return;
+ webContext()->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
+ return;
+ webContext()->uniformMatrix4fv(location->location(), size / 16, transpose, v);
+}
+
+void WebGLRenderingContextBase::useProgram(WebGLProgram* program)
+{
+ bool deleted;
+ if (!checkObjectToBeBound("useProgram", program, deleted))
+ return;
+ if (deleted)
+ program = 0;
+ if (program && !program->linkStatus()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "useProgram", "program not valid");
+ return;
+ }
+ if (m_currentProgram != program) {
+ if (m_currentProgram)
+ m_currentProgram->onDetached(webContext());
+ m_currentProgram = program;
+ webContext()->useProgram(objectOrZero(program));
+ if (program)
+ program->onAttached();
+ }
+}
+
+void WebGLRenderingContextBase::validateProgram(WebGLProgram* program)
+{
+ if (isContextLost() || !validateWebGLObject("validateProgram", program))
+ return;
+ webContext()->validateProgram(objectOrZero(program));
+}
+
+void WebGLRenderingContextBase::vertexAttrib1f(GLuint index, GLfloat v0)
+{
+ vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib1fv(GLuint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
+}
+
+void WebGLRenderingContextBase::vertexAttrib1fv(GLuint index, GLfloat* v, GLsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1)
+{
+ vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2fv(GLuint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2fv(GLuint index, GLfloat* v, GLsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3fv(GLuint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3fv(GLuint index, GLfloat* v, GLsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4fv(GLuint index, Float32Array* v)
+{
+ vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4fv(GLuint index, GLfloat* v, GLsizei size)
+{
+ vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
+}
+
+void WebGLRenderingContextBase::vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, long long offset)
+{
+ if (isContextLost())
+ return;
+ switch (type) {
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ case GL_FLOAT:
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "index out of range");
+ return;
+ }
+ if (size < 1 || size > 4 || stride < 0 || stride > 255) {
+ synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "bad size or stride");
+ return;
+ }
+ if (!validateValueFitNonNegInt32("vertexAttribPointer", "offset", offset))
+ return;
+ if (!m_boundArrayBuffer) {
+ synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
+ return;
+ }
+ // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
+ unsigned typeSize = sizeInBytes(type);
+ if (!typeSize) {
+ synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
+ return;
+ }
+ if ((stride % typeSize) || (static_cast<GLintptr>(offset) % typeSize)) {
+ synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
+ return;
+ }
+ GLsizei bytesPerElement = size * typeSize;
+
+ m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GLintptr>(offset), m_boundArrayBuffer);
+ webContext()->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GLintptr>(offset));
+}
+
+void WebGLRenderingContextBase::vertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+ if (isContextLost())
+ return;
+
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisorANGLE", "index out of range");
+ return;
+ }
+
+ m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
+ webContext()->vertexAttribDivisorANGLE(index, divisor);
+}
+
+void WebGLRenderingContextBase::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+ if (isContextLost())
+ return;
+ if (!validateSize("viewport", width, height))
+ return;
+ webContext()->viewport(x, y, width, height);
+}
+
+void WebGLRenderingContextBase::forceLostContext(WebGLRenderingContextBase::LostContextMode mode)
+{
+ if (isContextLost()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "loseContext", "context already lost");
+ return;
+ }
+
+ m_contextGroup->loseContextGroup(mode);
+}
+
+void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostContextMode mode)
+{
+#ifndef NDEBUG
+ printWarningToConsole("loseContextImpl(): begin");
+#endif
+
+ if (isContextLost())
+ return;
+
+ m_contextLost = true;
+ m_contextLostMode = mode;
+
+ if (mode == RealLostContext) {
+ // Inform the embedder that a lost context was received. In response, the embedder might
+ // decide to take action such as asking the user for permission to use WebGL again.
+ if (LocalFrame* frame = canvas()->document().frame())
+ frame->loader().client()->didLoseWebGLContext(webContext()->getGraphicsResetStatusARB());
+ }
+
+ // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
+ m_drawingBuffer->setTexture2DBinding(0);
+ m_drawingBuffer->setFramebufferBinding(0);
+
+ detachAndRemoveAllObjects();
+
+#ifndef NDEBUG
+ printWarningToConsole("loseContextImpl(): after detachAndRemoveAllObjects()");
+#endif
+
+ // Lose all the extensions.
+ for (size_t i = 0; i < m_extensions.size(); ++i) {
+ ExtensionTracker* tracker = m_extensions[i];
+ tracker->loseExtension();
+ }
+
+ for (size_t i = 0; i < WebGLExtensionNameCount; ++i)
+ m_extensionEnabled[i] = false;
+
+ removeAllCompressedTextureFormats();
+
+ if (mode != RealLostContext)
+ destroyContext();
+
+#ifndef NDEBUG
+ printWarningToConsole("loseContextImpl(): after destroyContext()");
+#endif
+
+ ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
+ synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
+
+ // Don't allow restoration unless the context lost event has both been
+ // dispatched and its default behavior prevented.
+ m_restoreAllowed = false;
+
+ // Always defer the dispatch of the context lost event, to implement
+ // the spec behavior of queueing a task.
+ m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE);
+
+#ifndef NDEBUG
+ printWarningToConsole("loseContextImpl(): end");
+#endif
+}
+
+void WebGLRenderingContextBase::forceRestoreContext()
+{
+ if (!isContextLost()) {
+ synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not lost");
+ return;
+ }
+
+ if (!m_restoreAllowed) {
+ if (m_contextLostMode == SyntheticLostContext)
+ synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context restoration not allowed");
+ return;
+ }
+
+ if (!m_restoreTimer.isActive())
+ m_restoreTimer.startOneShot(0, FROM_HERE);
+}
+
+blink::WebLayer* WebGLRenderingContextBase::platformLayer() const
+{
+ return isContextLost() ? 0 : m_drawingBuffer->platformLayer();
+}
+
+Extensions3DUtil* WebGLRenderingContextBase::extensionsUtil()
+{
+ ASSERT(!isContextLost());
+ if (!m_extensionsUtil)
+ m_extensionsUtil = Extensions3DUtil::create(webContext());
+ return m_extensionsUtil.get();
+}
+
+void WebGLRenderingContextBase::removeSharedObject(WebGLSharedObject* object)
+{
+ m_contextGroup->removeObject(object);
+}
+
+void WebGLRenderingContextBase::addSharedObject(WebGLSharedObject* object)
+{
+ ASSERT(!isContextLost());
+ m_contextGroup->addObject(object);
+}
+
+void WebGLRenderingContextBase::removeContextObject(WebGLContextObject* object)
+{
+ m_contextObjects.remove(object);
+}
+
+void WebGLRenderingContextBase::addContextObject(WebGLContextObject* object)
+{
+ ASSERT(!isContextLost());
+ m_contextObjects.add(object);
+}
+
+void WebGLRenderingContextBase::detachAndRemoveAllObjects()
+{
+ while (m_contextObjects.size() > 0) {
+ HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
+ (*it)->detachContext();
+ }
+}
+
+bool WebGLRenderingContextBase::hasPendingActivity() const
+{
+ return false;
+}
+
+void WebGLRenderingContextBase::stop()
+{
+ if (!isContextLost()) {
+ forceLostContext(SyntheticLostContext);
+ destroyContext();
+ }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBooleanParameter(GLenum pname)
+{
+ GLboolean value = 0;
+ if (!isContextLost())
+ webContext()->getBooleanv(pname, &value);
+ return WebGLGetInfo(static_cast<bool>(value));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBooleanArrayParameter(GLenum pname)
+{
+ if (pname != GL_COLOR_WRITEMASK) {
+ notImplemented();
+ return WebGLGetInfo(0, 0);
+ }
+ GLboolean value[4] = {0};
+ if (!isContextLost())
+ webContext()->getBooleanv(pname, value);
+ bool boolValue[4];
+ for (int ii = 0; ii < 4; ++ii)
+ boolValue[ii] = static_cast<bool>(value[ii]);
+ return WebGLGetInfo(boolValue, 4);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getFloatParameter(GLenum pname)
+{
+ GLfloat value = 0;
+ if (!isContextLost())
+ webContext()->getFloatv(pname, &value);
+ return WebGLGetInfo(value);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getIntParameter(GLenum pname)
+{
+ GLint value = 0;
+ if (!isContextLost())
+ webContext()->getIntegerv(pname, &value);
+ return WebGLGetInfo(value);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getUnsignedIntParameter(GLenum pname)
+{
+ GLint value = 0;
+ if (!isContextLost())
+ webContext()->getIntegerv(pname, &value);
+ return WebGLGetInfo(static_cast<unsigned>(value));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getWebGLFloatArrayParameter(GLenum pname)
+{
+ GLfloat value[4] = {0};
+ if (!isContextLost())
+ webContext()->getFloatv(pname, value);
+ unsigned length = 0;
+ switch (pname) {
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ case GL_DEPTH_RANGE:
+ length = 2;
+ break;
+ case GL_BLEND_COLOR:
+ case GL_COLOR_CLEAR_VALUE:
+ length = 4;
+ break;
+ default:
+ notImplemented();
+ }
+ return WebGLGetInfo(Float32Array::create(value, length));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getWebGLIntArrayParameter(GLenum pname)
+{
+ GLint value[4] = {0};
+ if (!isContextLost())
+ webContext()->getIntegerv(pname, value);
+ unsigned length = 0;
+ switch (pname) {
+ case GL_MAX_VIEWPORT_DIMS:
+ length = 2;
+ break;
+ case GL_SCISSOR_BOX:
+ case GL_VIEWPORT:
+ length = 4;
+ break;
+ default:
+ notImplemented();
+ }
+ return WebGLGetInfo(Int32Array::create(value, length));
+}
+
+void WebGLRenderingContextBase::handleTextureCompleteness(const char* functionName, bool prepareToDraw)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ bool resetActiveUnit = false;
+ WebGLTexture::TextureExtensionFlag flag = static_cast<WebGLTexture::TextureExtensionFlag>((extensionEnabled(OESTextureFloatLinearName) ? WebGLTexture::TextureFloatLinearExtensionEnabled : 0)
+ | (extensionEnabled(OESTextureHalfFloatLinearName) ? WebGLTexture::TextureHalfFloatLinearExtensionEnabled : 0));
+ for (unsigned ii = 0; ii < m_onePlusMaxNonDefaultTextureUnit; ++ii) {
+ if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
+ || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))) {
+ if (ii != m_activeTextureUnit) {
+ webContext()->activeTexture(ii);
+ resetActiveUnit = true;
+ } else if (resetActiveUnit) {
+ webContext()->activeTexture(ii);
+ resetActiveUnit = false;
+ }
+ WebGLTexture* tex2D;
+ WebGLTexture* texCubeMap;
+ if (prepareToDraw) {
+ String msg(String("texture bound to texture unit ") + String::number(ii)
+ + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'."
+ + " Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.");
+ emitGLWarning(functionName, msg.utf8().data());
+ tex2D = m_blackTexture2D.get();
+ texCubeMap = m_blackTextureCubeMap.get();
+ } else {
+ tex2D = m_textureUnits[ii].m_texture2DBinding.get();
+ texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
+ }
+ if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
+ webContext()->bindTexture(GL_TEXTURE_2D, objectOrZero(tex2D));
+ if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))
+ webContext()->bindTexture(GL_TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
+ }
+ }
+ if (resetActiveUnit)
+ webContext()->activeTexture(m_activeTextureUnit);
+}
+
+void WebGLRenderingContextBase::createFallbackBlackTextures1x1()
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ unsigned char black[] = {0, 0, 0, 255};
+ m_blackTexture2D = createTexture();
+ webContext()->bindTexture(GL_TEXTURE_2D, m_blackTexture2D->object());
+ webContext()->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->bindTexture(GL_TEXTURE_2D, 0);
+ m_blackTextureCubeMap = createTexture();
+ webContext()->bindTexture(GL_TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 1, 1,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+ webContext()->bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+}
+
+bool WebGLRenderingContextBase::isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat)
+{
+ unsigned need = WebGLImageConversion::getChannelBitsByFormat(texInternalFormat);
+ unsigned have = WebGLImageConversion::getChannelBitsByFormat(colorBufferFormat);
+ return (need & have) == need;
+}
+
+GLenum WebGLRenderingContextBase::boundFramebufferColorFormat()
+{
+ if (m_framebufferBinding && m_framebufferBinding->object())
+ return m_framebufferBinding->colorBufferFormat();
+ if (m_requestedAttributes->alpha())
+ return GL_RGBA;
+ return GL_RGB;
+}
+
+WebGLTexture* WebGLRenderingContextBase::validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap)
+{
+ WebGLTexture* tex = 0;
+ switch (target) {
+ case GL_TEXTURE_2D:
+ tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get();
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (!useSixEnumsForCubeMap) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+ return 0;
+ }
+ tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ if (useSixEnumsForCubeMap) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+ return 0;
+ }
+ tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+ return 0;
+ }
+ if (!tex)
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "no texture");
+ return tex;
+}
+
+bool WebGLRenderingContextBase::validateLocationLength(const char* functionName, const String& string)
+{
+ const unsigned maxWebGLLocationLength = 256;
+ if (string.length() > maxWebGLLocationLength) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "location length > 256");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateSize(const char* functionName, GLint x, GLint y)
+{
+ if (x < 0 || y < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "size < 0");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateString(const char* functionName, const String& string)
+{
+ for (size_t i = 0; i < string.length(); ++i) {
+ if (!validateCharacter(string[i])) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "string not ASCII");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level)
+{
+ switch (format) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGB:
+ case GL_RGBA:
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ case GL_DEPTH_COMPONENT:
+ if (extensionEnabled(WebGLDepthTextureName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "depth texture formats not enabled");
+ return false;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture format");
+ return false;
+ }
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ break;
+ case GL_FLOAT:
+ if (extensionEnabled(OESTextureFloatName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ case GL_HALF_FLOAT_OES:
+ if (extensionEnabled(OESTextureHalfFloatName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_24_8_OES:
+ case GL_UNSIGNED_SHORT:
+ if (extensionEnabled(WebGLDepthTextureName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+ return false;
+ }
+
+ // Verify that the combination of format and type is supported.
+ switch (format) {
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ if (type != GL_UNSIGNED_BYTE
+ && type != GL_FLOAT
+ && type != GL_HALF_FLOAT_OES) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for format");
+ return false;
+ }
+ break;
+ case GL_RGB:
+ if (type != GL_UNSIGNED_BYTE
+ && type != GL_UNSIGNED_SHORT_5_6_5
+ && type != GL_FLOAT
+ && type != GL_HALF_FLOAT_OES) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGB format");
+ return false;
+ }
+ break;
+ case GL_RGBA:
+ if (type != GL_UNSIGNED_BYTE
+ && type != GL_UNSIGNED_SHORT_4_4_4_4
+ && type != GL_UNSIGNED_SHORT_5_5_5_1
+ && type != GL_FLOAT
+ && type != GL_HALF_FLOAT_OES) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGBA format");
+ return false;
+ }
+ break;
+ case GL_DEPTH_COMPONENT:
+ if (!extensionEnabled(WebGLDepthTextureName)) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
+ return false;
+ }
+ if (type != GL_UNSIGNED_SHORT
+ && type != GL_UNSIGNED_INT) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
+ return false;
+ }
+ if (level > 0) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
+ return false;
+ }
+ break;
+ case GL_DEPTH_STENCIL_OES:
+ if (!extensionEnabled(WebGLDepthTextureName)) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
+ return false;
+ }
+ if (type != GL_UNSIGNED_INT_24_8_OES) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
+ return false;
+ }
+ if (level > 0) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, GLenum target, GLint level)
+{
+ if (level < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "level < 0");
+ return false;
+ }
+ switch (target) {
+ case GL_TEXTURE_2D:
+ if (level >= m_maxTextureLevel) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
+ return false;
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (level >= m_maxCubeMapTextureLevel) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
+ return false;
+ }
+ break;
+ }
+ // This function only checks if level is legal, so we return true and don't
+ // generate INVALID_ENUM if target is illegal.
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType functionType,
+ GLenum target, GLint level, GLsizei width, GLsizei height)
+{
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ switch (target) {
+ case GL_TEXTURE_2D:
+ if (width > (m_maxTextureSize >> level) || height > (m_maxTextureSize >> level)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range");
+ return false;
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (functionType != TexSubImage2D && width != height) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width != height for cube map");
+ return false;
+ }
+ // No need to check height here. For texImage width == height.
+ // For texSubImage that will be checked when checking yoffset + height is in range.
+ if (width > (m_maxCubeMapTextureSize >> level)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range for cube map");
+ return false;
+ }
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target,
+ GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type)
+{
+ // We absolutely have to validate the format and type combination.
+ // The texImage2D entry points taking HTMLImage, etc. will produce
+ // temporary data based on this combination, so it must be legal.
+ if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
+ return false;
+
+ if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
+ return false;
+
+ if (format != internalformat) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "format != internalformat");
+ return false;
+ }
+
+ if (border) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "border != 0");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition disposition)
+{
+ // All calling functions check isContextLost, so a duplicate check is not needed here.
+ if (!pixels) {
+ if (disposition == NullAllowed)
+ return true;
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
+ return false;
+ }
+
+ if (!validateTexFuncFormatAndType(functionName, format, type, level))
+ return false;
+ if (!validateSettableTexFormat(functionName, format))
+ return false;
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ if (pixels->type() != ArrayBufferView::TypeUint8) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
+ return false;
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ if (pixels->type() != ArrayBufferView::TypeUint16) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
+ return false;
+ }
+ break;
+ case GL_FLOAT: // OES_texture_float
+ if (pixels->type() != ArrayBufferView::TypeFloat32) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
+ return false;
+ }
+ break;
+ case GL_HALF_FLOAT_OES: // OES_texture_half_float
+ // As per the specification, ArrayBufferView should be null or a Uint16Array when
+ // OES_texture_half_float is enabled.
+ if (pixels && pixels->type() != ArrayBufferView::TypeUint16) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL and not Uint16Array");
+ return false;
+ }
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ unsigned totalBytesRequired;
+ GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
+ if (error != GL_NO_ERROR) {
+ synthesizeGLError(error, functionName, "invalid texture dimensions");
+ return false;
+ }
+ if (pixels->byteLength() < totalBytesRequired) {
+ if (m_unpackAlignment != 1) {
+ error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
+ if (pixels->byteLength() == totalBytesRequired) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
+ return false;
+ }
+ }
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexFormat(GLenum format)
+{
+ return m_compressedTextureFormats.contains(format);
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels)
+{
+ if (!pixels) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
+ return false;
+ }
+ if (width < 0 || height < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
+ return false;
+ }
+
+ unsigned bytesRequired = 0;
+
+ switch (format) {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ const int kBlockSize = 8;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ int numBlocks = numBlocksAcross * numBlocksDown;
+ bytesRequired = numBlocks * kBlockSize;
+ }
+ break;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ const int kBlockSize = 16;
+ int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+ int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+ int numBlocks = numBlocksAcross * numBlocksDown;
+ bytesRequired = numBlocks * kBlockSize;
+ }
+ break;
+ case GC3D_COMPRESSED_ATC_RGB_AMD:
+ case GL_ETC1_RGB8_OES:
+ {
+ bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 8;
+ }
+ break;
+ case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ {
+ bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 16;
+ }
+ break;
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ {
+ bytesRequired = (max(width, 8) * max(height, 8) * 4 + 7) / 8;
+ }
+ break;
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+ {
+ bytesRequired = (max(width, 16) * max(height, 8) * 2 + 7) / 8;
+ }
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format");
+ return false;
+ }
+
+ if (pixels->byteLength() != bytesRequired) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format)
+{
+ if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
+ return false;
+
+ bool widthValid = false;
+ bool heightValid = false;
+
+ switch (format) {
+ case GC3D_COMPRESSED_ATC_RGB_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ widthValid = (level && width == 1) || (level && width == 2) || !(width % kBlockWidth);
+ heightValid = (level && height == 1) || (level && height == 2) || !(height % kBlockHeight);
+ break;
+ }
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
+ // Must be a power of two
+ widthValid = (width & (width - 1)) == 0;
+ heightValid = (height & (height - 1)) == 0;
+ break;
+ }
+ case GL_ETC1_RGB8_OES: {
+ widthValid = true;
+ heightValid = true;
+ break;
+ }
+ default:
+ return false;
+ }
+
+ if (!widthValid || !heightValid) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "width or height invalid for level");
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture* tex)
+{
+ if (xoffset < 0 || yoffset < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "xoffset or yoffset < 0");
+ return false;
+ }
+
+ switch (format) {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+ const int kBlockWidth = 4;
+ const int kBlockHeight = 4;
+ if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
+ return false;
+ }
+ if (width - xoffset > tex->getWidth(target, level)
+ || height - yoffset > tex->getHeight(target, level)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range");
+ return false;
+ }
+ return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
+ }
+ case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+ case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+ case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: {
+ if ((xoffset != 0) || (yoffset != 0)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset and yoffset must be zero");
+ return false;
+ }
+ if (width != tex->getWidth(target, level)
+ || height != tex->getHeight(target, level)) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions must match existing level");
+ return false;
+ }
+ return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
+ }
+ case GC3D_COMPRESSED_ATC_RGB_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+ case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ case GL_ETC1_RGB8_OES: {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "unable to update sub-images with this format");
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateDrawMode(const char* functionName, GLenum mode)
+{
+ switch (mode) {
+ case GL_POINTS:
+ case GL_LINE_STRIP:
+ case GL_LINE_LOOP:
+ case GL_LINES:
+ case GL_TRIANGLE_STRIP:
+ case GL_TRIANGLE_FAN:
+ case GL_TRIANGLES:
+ return true;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid draw mode");
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateStencilSettings(const char* functionName)
+{
+ if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "front and back stencils settings do not match");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateStencilOrDepthFunc(const char* functionName, GLenum func)
+{
+ switch (func) {
+ case GL_NEVER:
+ case GL_LESS:
+ case GL_LEQUAL:
+ case GL_GREATER:
+ case GL_GEQUAL:
+ case GL_EQUAL:
+ case GL_NOTEQUAL:
+ case GL_ALWAYS:
+ return true;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid function");
+ return false;
+ }
+}
+
+void WebGLRenderingContextBase::printGLErrorToConsole(const String& message)
+{
+ if (!m_numGLErrorsToConsoleAllowed)
+ return;
+
+ --m_numGLErrorsToConsoleAllowed;
+ printWarningToConsole(message);
+
+ if (!m_numGLErrorsToConsoleAllowed)
+ printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
+
+ return;
+}
+
+void WebGLRenderingContextBase::printWarningToConsole(const String& message)
+{
+ if (!canvas())
+ return;
+ canvas()->document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
+}
+
+bool WebGLRenderingContextBase::validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment)
+{
+ if (target != GL_FRAMEBUFFER) {
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+ return false;
+ }
+ switch (attachment) {
+ case GL_COLOR_ATTACHMENT0:
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+ break;
+ default:
+ if (extensionEnabled(WebGLDrawBuffersName)
+ && attachment > GL_COLOR_ATTACHMENT0
+ && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + maxColorAttachments()))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateBlendEquation(const char* functionName, GLenum mode)
+{
+ switch (mode) {
+ case GL_FUNC_ADD:
+ case GL_FUNC_SUBTRACT:
+ case GL_FUNC_REVERSE_SUBTRACT:
+ return true;
+ case GL_MIN_EXT:
+ case GL_MAX_EXT:
+ if (extensionEnabled(EXTBlendMinMaxName))
+ return true;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid mode");
+ return false;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid mode");
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst)
+{
+ if (((src == GL_CONSTANT_COLOR || src == GL_ONE_MINUS_CONSTANT_COLOR)
+ && (dst == GL_CONSTANT_ALPHA || dst == GL_ONE_MINUS_CONSTANT_ALPHA))
+ || ((dst == GL_CONSTANT_COLOR || dst == GL_ONE_MINUS_CONSTANT_COLOR)
+ && (src == GL_CONSTANT_ALPHA || src == GL_ONE_MINUS_CONSTANT_ALPHA))) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "incompatible src and dst");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateCapability(const char* functionName, GLenum cap)
+{
+ switch (cap) {
+ case GL_BLEND:
+ case GL_CULL_FACE:
+ case GL_DEPTH_TEST:
+ case GL_DITHER:
+ case GL_POLYGON_OFFSET_FILL:
+ case GL_SAMPLE_ALPHA_TO_COVERAGE:
+ case GL_SAMPLE_COVERAGE:
+ case GL_SCISSOR_TEST:
+ case GL_STENCIL_TEST:
+ return true;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid capability");
+ return false;
+ }
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GLsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GLsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GLsizei size, GLsizei requiredMinSize)
+{
+ return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v, GLsizei requiredMinSize)
+{
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GLboolean transpose, void* v, GLsizei size, GLsizei requiredMinSize)
+{
+ if (!location)
+ return false;
+ if (location->program() != m_currentProgram) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "location is not from current program");
+ return false;
+ }
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return false;
+ }
+ if (transpose) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "transpose not FALSE");
+ return false;
+ }
+ if (size < requiredMinSize || (size % requiredMinSize)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
+ return false;
+ }
+ return true;
+}
+
+WebGLBuffer* WebGLRenderingContextBase::validateBufferDataTarget(const char* functionName, GLenum target)
+{
+ WebGLBuffer* buffer = 0;
+ switch (target) {
+ case GL_ELEMENT_ARRAY_BUFFER:
+ buffer = m_boundVertexArrayObject->boundElementArrayBuffer().get();
+ break;
+ case GL_ARRAY_BUFFER:
+ buffer = m_boundArrayBuffer.get();
+ break;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+ return 0;
+ }
+ if (!buffer) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "no buffer");
+ return 0;
+ }
+ return buffer;
+}
+
+bool WebGLRenderingContextBase::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+ if (!image || !image->cachedImage()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no image");
+ return false;
+ }
+ const KURL& url = image->cachedImage()->response().url();
+ if (url.isNull() || url.isEmpty() || !url.isValid()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid image");
+ return false;
+ }
+
+ if (wouldTaintOrigin(image)) {
+ exceptionState.throwSecurityError("The cross-origin image at " + url.elidedString() + " may not be loaded.");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+ if (!canvas || !canvas->buffer()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no canvas");
+ return false;
+ }
+ if (wouldTaintOrigin(canvas)) {
+ exceptionState.throwSecurityError("Tainted canvases may not be loaded.");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+ if (!video || !video->videoWidth() || !video->videoHeight()) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no video");
+ return false;
+ }
+
+ if (wouldTaintOrigin(video)) {
+ exceptionState.throwSecurityError("The video element contains cross-origin data, and may not be loaded.");
+ return false;
+ }
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count)
+{
+ if (isContextLost() || !validateDrawMode(functionName, mode))
+ return false;
+
+ if (!validateStencilSettings(functionName))
+ return false;
+
+ if (first < 0 || count < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "first or count < 0");
+ return false;
+ }
+
+ if (!count) {
+ markContextChanged(CanvasChanged);
+ return false;
+ }
+
+ if (!validateRenderingState(functionName)) {
+ return false;
+ }
+
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+ return false;
+ }
+
+ return true;
+}
+
+bool WebGLRenderingContextBase::validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset)
+{
+ if (isContextLost() || !validateDrawMode(functionName, mode))
+ return false;
+
+ if (!validateStencilSettings(functionName))
+ return false;
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT:
+ break;
+ case GL_UNSIGNED_INT:
+ if (extensionEnabled(OESElementIndexUintName))
+ break;
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
+ return false;
+ default:
+ synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
+ return false;
+ }
+
+ if (count < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "count < 0");
+ return false;
+ }
+ if (!validateValueFitNonNegInt32(functionName, "offset", offset))
+ return false;
+
+ if (!count) {
+ markContextChanged(CanvasChanged);
+ return false;
+ }
+
+ if (!m_boundVertexArrayObject->boundElementArrayBuffer()) {
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
+ return false;
+ }
+
+ if (!validateRenderingState(functionName)) {
+ return false;
+ }
+
+ const char* reason = "framebuffer incomplete";
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(webContext(), &reason)) {
+ synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+ return false;
+ }
+
+ return true;
+}
+
+// Helper function to validate draw*Instanced calls
+bool WebGLRenderingContextBase::validateDrawInstanced(const char* functionName, GLsizei primcount)
+{
+ if (primcount < 0) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "primcount < 0");
+ return false;
+ }
+
+ // Ensure at least one enabled vertex attrib has a divisor of 0.
+ for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
+ const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
+ if (state.enabled && !state.divisor)
+ return true;
+ }
+
+ synthesizeGLError(GL_INVALID_OPERATION, functionName, "at least one enabled attribute must have a divisor of 0");
+ return false;
+}
+
+void WebGLRenderingContextBase::vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+ if (isContextLost())
+ return;
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
+ return;
+ }
+ // In GL, we skip setting vertexAttrib0 values.
+ switch (expectedSize) {
+ case 1:
+ webContext()->vertexAttrib1f(index, v0);
+ break;
+ case 2:
+ webContext()->vertexAttrib2f(index, v0, v1);
+ break;
+ case 3:
+ webContext()->vertexAttrib3f(index, v0, v1, v2);
+ break;
+ case 4:
+ webContext()->vertexAttrib4f(index, v0, v1, v2, v3);
+ break;
+ }
+ VertexAttribValue& attribValue = m_vertexAttribValue[index];
+ attribValue.value[0] = v0;
+ attribValue.value[1] = v1;
+ attribValue.value[2] = v2;
+ attribValue.value[3] = v3;
+}
+
+void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array* v, GLsizei expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return;
+ }
+ vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
+}
+
+void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat* v, GLsizei size, GLsizei expectedSize)
+{
+ if (isContextLost())
+ return;
+ if (!v) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+ return;
+ }
+ if (size < expectedSize) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
+ return;
+ }
+ if (index >= m_maxVertexAttribs) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
+ return;
+ }
+ // In GL, we skip setting vertexAttrib0 values.
+ switch (expectedSize) {
+ case 1:
+ webContext()->vertexAttrib1fv(index, v);
+ break;
+ case 2:
+ webContext()->vertexAttrib2fv(index, v);
+ break;
+ case 3:
+ webContext()->vertexAttrib3fv(index, v);
+ break;
+ case 4:
+ webContext()->vertexAttrib4fv(index, v);
+ break;
+ }
+ VertexAttribValue& attribValue = m_vertexAttribValue[index];
+ attribValue.initValue();
+ for (int ii = 0; ii < expectedSize; ++ii)
+ attribValue.value[ii] = v[ii];
+}
+
+void WebGLRenderingContextBase::dispatchContextLostEvent(Timer<WebGLRenderingContextBase>*)
+{
+ RefPtrWillBeRawPtr<WebGLContextEvent> event = WebGLContextEvent::create(EventTypeNames::webglcontextlost, false, true, "");
+ canvas()->dispatchEvent(event);
+ m_restoreAllowed = event->defaultPrevented();
+ deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAllowed);
+ if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecoverSyntheticLostContext) && m_restoreAllowed)
+ m_restoreTimer.startOneShot(0, FROM_HERE);
+}
+
+void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextBase>*)
+{
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): begin");
+#endif
+ ASSERT(isContextLost());
+
+ // The rendering context is not restored unless the default behavior of the
+ // webglcontextlost event was prevented earlier.
+ //
+ // Because of the way m_restoreTimer is set up for real vs. synthetic lost
+ // context events, we don't have to worry about this test short-circuiting
+ // the retry loop for real context lost events.
+ if (!m_restoreAllowed)
+ return;
+
+ LocalFrame* frame = canvas()->document().frame();
+ if (!frame)
+ return;
+
+ Settings* settings = frame->settings();
+
+ if (!frame->loader().client()->allowWebGL(settings && settings->webGLEnabled()))
+ return;
+
+ // If the context was lost due to RealLostContext, we need to destroy the old DrawingBuffer before creating new DrawingBuffer to ensure resource budget enough.
+ if (m_drawingBuffer) {
+ m_drawingBuffer->beginDestruction();
+ m_drawingBuffer.clear();
+ }
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): destroyed old DrawingBuffer");
+#endif
+
+ blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes->attributes(canvas()->document().topDocument().url().string(), settings);
+ OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes, 0));
+ RefPtr<DrawingBuffer> drawingBuffer;
+ // Even if a non-null WebGraphicsContext3D is created, until it's made current, it isn't known whether the context is still lost.
+ if (context) {
+ // Construct a new drawing buffer with the new WebGraphicsContext3D.
+ drawingBuffer = createDrawingBuffer(context.release());
+ // If DrawingBuffer::create() fails to allocate a fbo, |drawingBuffer| is set to null.
+ }
+ if (!drawingBuffer) {
+ if (m_contextLostMode == RealLostContext) {
+ m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE);
+ } else {
+ // This likely shouldn't happen but is the best way to report it to the WebGL app.
+ synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context");
+ }
+ return;
+ }
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): created new DrawingBuffer");
+#endif
+
+ m_drawingBuffer = drawingBuffer.release();
+ m_drawingBuffer->bind();
+ m_lostContextErrors.clear();
+ m_contextLost = false;
+
+ setupFlags();
+ initializeNewContext();
+ markContextChanged(CanvasContextChanged);
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): before dispatchEvent");
+#endif
+ canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextrestored, false, true, ""));
+#ifndef NDEBUG
+ printWarningToConsole("maybeRestoreContext(): end");
+#endif
+}
+
+String WebGLRenderingContextBase::ensureNotNull(const String& text) const
+{
+ if (text.isNull())
+ return WTF::emptyString();
+ return text;
+}
+
+WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+ : m_buffers(adoptArrayPtr(new OwnPtr<ImageBuffer>[capacity]))
+ , m_capacity(capacity)
+{
+}
+
+ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size)
+{
+ int i;
+ for (i = 0; i < m_capacity; ++i) {
+ ImageBuffer* buf = m_buffers[i].get();
+ if (!buf)
+ break;
+ if (buf->size() != size)
+ continue;
+ bubbleToFront(i);
+ return buf;
+ }
+
+ OwnPtr<ImageBuffer> temp(ImageBuffer::create(size));
+ if (!temp)
+ return 0;
+ i = std::min(m_capacity - 1, i);
+ m_buffers[i] = temp.release();
+
+ ImageBuffer* buf = m_buffers[i].get();
+ bubbleToFront(i);
+ return buf;
+}
+
+void WebGLRenderingContextBase::LRUImageBufferCache::bubbleToFront(int idx)
+{
+ for (int i = idx; i > 0; --i)
+ m_buffers[i].swap(m_buffers[i-1]);
+}
+
+namespace {
+
+ String GetErrorString(GLenum error)
+ {
+ switch (error) {
+ case GL_INVALID_ENUM:
+ return "INVALID_ENUM";
+ case GL_INVALID_VALUE:
+ return "INVALID_VALUE";
+ case GL_INVALID_OPERATION:
+ return "INVALID_OPERATION";
+ case GL_OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ return "INVALID_FRAMEBUFFER_OPERATION";
+ case GC3D_CONTEXT_LOST_WEBGL:
+ return "CONTEXT_LOST_WEBGL";
+ default:
+ return String::format("WebGL ERROR(0x%04X)", error);
+ }
+ }
+
+} // namespace anonymous
+
+void WebGLRenderingContextBase::synthesizeGLError(GLenum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
+{
+ String errorType = GetErrorString(error);
+ if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
+ String message = String("WebGL: ") + errorType + ": " + String(functionName) + ": " + String(description);
+ printGLErrorToConsole(message);
+ }
+ if (!isContextLost())
+ webContext()->synthesizeGLError(error);
+ else {
+ if (m_lostContextErrors.find(error) == WTF::kNotFound)
+ m_lostContextErrors.append(error);
+ }
+ InspectorInstrumentation::didFireWebGLError(canvas(), errorType);
+}
+
+void WebGLRenderingContextBase::emitGLWarning(const char* functionName, const char* description)
+{
+ if (m_synthesizedErrorsToConsole) {
+ String message = String("WebGL: ") + String(functionName) + ": " + String(description);
+ printGLErrorToConsole(message);
+ }
+ InspectorInstrumentation::didFireWebGLWarning(canvas());
+}
+
+void WebGLRenderingContextBase::applyStencilTest()
+{
+ bool haveStencilBuffer = false;
+
+ if (m_framebufferBinding)
+ haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
+ else {
+ RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
+ haveStencilBuffer = attributes->stencil();
+ }
+ enableOrDisable(GL_STENCIL_TEST,
+ m_stencilEnabled && haveStencilBuffer);
+}
+
+void WebGLRenderingContextBase::enableOrDisable(GLenum capability, bool enable)
+{
+ if (isContextLost())
+ return;
+ if (enable)
+ webContext()->enable(capability);
+ else
+ webContext()->disable(capability);
+}
+
+IntSize WebGLRenderingContextBase::clampedCanvasSize()
+{
+ return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
+ clamp(canvas()->height(), 1, m_maxViewportDims[1]));
+}
+
+GLint WebGLRenderingContextBase::maxDrawBuffers()
+{
+ if (isContextLost() || !extensionEnabled(WebGLDrawBuffersName))
+ return 0;
+ if (!m_maxDrawBuffers)
+ webContext()->getIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
+ if (!m_maxColorAttachments)
+ webContext()->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
+ return std::min(m_maxDrawBuffers, m_maxColorAttachments);
+}
+
+GLint WebGLRenderingContextBase::maxColorAttachments()
+{
+ if (isContextLost() || !extensionEnabled(WebGLDrawBuffersName))
+ return 0;
+ if (!m_maxColorAttachments)
+ webContext()->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+ return m_maxColorAttachments;
+}
+
+void WebGLRenderingContextBase::setBackDrawBuffer(GLenum buf)
+{
+ m_backDrawBuffer = buf;
+}
+
+void WebGLRenderingContextBase::restoreCurrentFramebuffer()
+{
+ bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get());
+}
+
+void WebGLRenderingContextBase::restoreCurrentTexture2D()
+{
+ bindTexture(GL_TEXTURE_2D, m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get());
+}
+
+void WebGLRenderingContextBase::multisamplingChanged(bool enabled)
+{
+ if (m_multisamplingAllowed != enabled) {
+ m_multisamplingAllowed = enabled;
+ forceLostContext(WebGLRenderingContextBase::AutoRecoverSyntheticLostContext);
+ }
+}
+
+void WebGLRenderingContextBase::findNewMaxEnabledAttribIndex()
+{
+ // Trace backwards from the current max to find the new max enabled attrib index
+ int startIndex = m_onePlusMaxEnabledAttribIndex - 1;
+ for (int i = startIndex; i >= 0; --i) {
+ if (m_boundVertexArrayObject->getVertexAttribState(i).enabled) {
+ m_onePlusMaxEnabledAttribIndex = i + 1;
+ return;
+ }
+ }
+ m_onePlusMaxEnabledAttribIndex = 0;
+}
+
+void WebGLRenderingContextBase::findNewMaxNonDefaultTextureUnit()
+{
+ // Trace backwards from the current max to find the new max non-default texture unit
+ int startIndex = m_onePlusMaxNonDefaultTextureUnit - 1;
+ for (int i = startIndex; i >= 0; --i) {
+ if (m_textureUnits[i].m_texture2DBinding
+ || m_textureUnits[i].m_textureCubeMapBinding) {
+ m_onePlusMaxNonDefaultTextureUnit = i + 1;
+ return;
+ }
+ }
+ m_onePlusMaxNonDefaultTextureUnit = 0;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h
new file mode 100644
index 00000000000..ca08a621efc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.h
@@ -0,0 +1,914 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLRenderingContextBase_h
+#define WebGLRenderingContextBase_h
+
+#include "core/dom/ActiveDOMObject.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+#include "core/html/canvas/WebGLExtensionName.h"
+#include "core/html/canvas/WebGLGetInfo.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderBoxModelObject.h"
+#include "platform/Timer.h"
+#include "platform/graphics/GraphicsTypes3D.h"
+#include "platform/graphics/ImageBuffer.h"
+#include "platform/graphics/gpu/DrawingBuffer.h"
+#include "platform/graphics/gpu/Extensions3DUtil.h"
+#include "platform/graphics/gpu/WebGLImageConversion.h"
+#include "public/platform/WebGraphicsContext3D.h"
+#include "wtf/Float32Array.h"
+#include "wtf/Int32Array.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+class WebLayer;
+}
+
+namespace WebCore {
+
+class ANGLEInstancedArrays;
+class EXTBlendMinMax;
+class EXTFragDepth;
+class EXTShaderTextureLOD;
+class EXTTextureFilterAnisotropic;
+class ExceptionState;
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageBuffer;
+class ImageData;
+class IntSize;
+class OESElementIndexUint;
+class OESStandardDerivatives;
+class OESTextureFloat;
+class OESTextureFloatLinear;
+class OESTextureHalfFloat;
+class OESTextureHalfFloatLinear;
+class OESVertexArrayObject;
+class WebGLActiveInfo;
+class WebGLBuffer;
+class WebGLCompressedTextureATC;
+class WebGLCompressedTextureETC1;
+class WebGLCompressedTexturePVRTC;
+class WebGLCompressedTextureS3TC;
+class WebGLContextAttributes;
+class WebGLContextGroup;
+class WebGLContextObject;
+class WebGLDebugRendererInfo;
+class WebGLDebugShaders;
+class WebGLDepthTexture;
+class WebGLDrawBuffers;
+class WebGLExtension;
+class WebGLFramebuffer;
+class WebGLLoseContext;
+class WebGLObject;
+class WebGLProgram;
+class WebGLRenderbuffer;
+class WebGLShader;
+class WebGLShaderPrecisionFormat;
+class WebGLSharedObject;
+class WebGLTexture;
+class WebGLUniformLocation;
+class WebGLVertexArrayObjectOES;
+
+class WebGLRenderingContextLostCallback;
+class WebGLRenderingContextErrorMessageCallback;
+
+class WebGLRenderingContextBase: public CanvasRenderingContext, public ActiveDOMObject, public Page::MultisamplingChangedObserver {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WebGLRenderingContextBase);
+public:
+ virtual ~WebGLRenderingContextBase();
+
+ virtual bool is3d() const OVERRIDE { return true; }
+ virtual bool isAccelerated() const OVERRIDE { return true; }
+ virtual unsigned version() const = 0;
+ virtual String contextName() const = 0;
+ virtual void registerContextExtensions() = 0;
+
+ static unsigned getWebGLVersion(const CanvasRenderingContext*);
+
+ int drawingBufferWidth() const;
+ int drawingBufferHeight() const;
+
+ void activeTexture(GLenum texture);
+ void attachShader(WebGLProgram*, WebGLShader*);
+ void bindAttribLocation(WebGLProgram*, GLuint index, const String& name);
+ void bindBuffer(GLenum target, WebGLBuffer*);
+ void bindFramebuffer(GLenum target, WebGLFramebuffer*);
+ void bindRenderbuffer(GLenum target, WebGLRenderbuffer*);
+ void bindTexture(GLenum target, WebGLTexture*);
+ void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void blendEquation(GLenum mode);
+ void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ void blendFunc(GLenum sfactor, GLenum dfactor);
+ void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+ void bufferData(GLenum target, long long size, GLenum usage);
+ void bufferData(GLenum target, ArrayBuffer* data, GLenum usage);
+ void bufferData(GLenum target, ArrayBufferView* data, GLenum usage);
+ void bufferSubData(GLenum target, long long offset, ArrayBuffer* data);
+ void bufferSubData(GLenum target, long long offset, ArrayBufferView* data);
+
+ GLenum checkFramebufferStatus(GLenum target);
+ void clear(GLbitfield mask);
+ void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+ void clearDepth(GLfloat);
+ void clearStencil(GLint);
+ void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void compileShader(WebGLShader*);
+
+ void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data);
+ void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data);
+
+ void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+ PassRefPtr<WebGLBuffer> createBuffer();
+ PassRefPtr<WebGLFramebuffer> createFramebuffer();
+ PassRefPtr<WebGLProgram> createProgram();
+ PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
+ PassRefPtr<WebGLShader> createShader(GLenum type);
+ PassRefPtr<WebGLTexture> createTexture();
+
+ void cullFace(GLenum mode);
+
+ void deleteBuffer(WebGLBuffer*);
+ void deleteFramebuffer(WebGLFramebuffer*);
+ void deleteProgram(WebGLProgram*);
+ void deleteRenderbuffer(WebGLRenderbuffer*);
+ void deleteShader(WebGLShader*);
+ void deleteTexture(WebGLTexture*);
+
+ void depthFunc(GLenum);
+ void depthMask(GLboolean);
+ void depthRange(GLfloat zNear, GLfloat zFar);
+ void detachShader(WebGLProgram*, WebGLShader*);
+ void disable(GLenum cap);
+ void disableVertexAttribArray(GLuint index);
+ void drawArrays(GLenum mode, GLint first, GLsizei count);
+ void drawElements(GLenum mode, GLsizei count, GLenum type, long long offset);
+
+ void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+ void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, long long offset, GLsizei primcount);
+
+ void enable(GLenum cap);
+ void enableVertexAttribArray(GLuint index);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer*);
+ void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture*, GLint level);
+ void frontFace(GLenum mode);
+ void generateMipmap(GLenum target);
+
+ PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GLuint index);
+ PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GLuint index);
+ bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader> >&);
+ GLint getAttribLocation(WebGLProgram*, const String& name);
+ WebGLGetInfo getBufferParameter(GLenum target, GLenum pname);
+ PassRefPtr<WebGLContextAttributes> getContextAttributes();
+ GLenum getError();
+ PassRefPtr<WebGLExtension> getExtension(const String& name);
+ WebGLGetInfo getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
+ WebGLGetInfo getParameter(GLenum pname);
+ WebGLGetInfo getProgramParameter(WebGLProgram*, GLenum pname);
+ String getProgramInfoLog(WebGLProgram*);
+ WebGLGetInfo getRenderbufferParameter(GLenum target, GLenum pname);
+ WebGLGetInfo getShaderParameter(WebGLShader*, GLenum pname);
+ String getShaderInfoLog(WebGLShader*);
+ PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType);
+ String getShaderSource(WebGLShader*);
+ Vector<String> getSupportedExtensions();
+ WebGLGetInfo getTexParameter(GLenum target, GLenum pname);
+ WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*);
+ PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
+ WebGLGetInfo getVertexAttrib(GLuint index, GLenum pname);
+ long long getVertexAttribOffset(GLuint index, GLenum pname);
+
+ void hint(GLenum target, GLenum mode);
+ GLboolean isBuffer(WebGLBuffer*);
+ bool isContextLost() const;
+ GLboolean isEnabled(GLenum cap);
+ GLboolean isFramebuffer(WebGLFramebuffer*);
+ GLboolean isProgram(WebGLProgram*);
+ GLboolean isRenderbuffer(WebGLRenderbuffer*);
+ GLboolean isShader(WebGLShader*);
+ GLboolean isTexture(WebGLTexture*);
+
+ void lineWidth(GLfloat);
+ void linkProgram(WebGLProgram*);
+ void pixelStorei(GLenum pname, GLint param);
+ void polygonOffset(GLfloat factor, GLfloat units);
+ void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels);
+ void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void sampleCoverage(GLfloat value, GLboolean invert);
+ void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ void shaderSource(WebGLShader*, const String&);
+ void stencilFunc(GLenum func, GLint ref, GLuint mask);
+ void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void stencilMask(GLuint);
+ void stencilMaskSeparate(GLenum face, GLuint mask);
+ void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+ void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, ImageData*, ExceptionState&);
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
+ void texImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
+
+ void texParameterf(GLenum target, GLenum pname, GLfloat param);
+ void texParameteri(GLenum target, GLenum pname, GLint param);
+
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, ImageData*, ExceptionState&);
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
+ void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
+
+ void uniform1f(const WebGLUniformLocation*, GLfloat x);
+ void uniform1fv(const WebGLUniformLocation*, Float32Array* v);
+ void uniform1fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+ void uniform1i(const WebGLUniformLocation*, GLint x);
+ void uniform1iv(const WebGLUniformLocation*, Int32Array* v);
+ void uniform1iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+ void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
+ void uniform2fv(const WebGLUniformLocation*, Float32Array* v);
+ void uniform2fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+ void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
+ void uniform2iv(const WebGLUniformLocation*, Int32Array* v);
+ void uniform2iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+ void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
+ void uniform3fv(const WebGLUniformLocation*, Float32Array* v);
+ void uniform3fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+ void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
+ void uniform3iv(const WebGLUniformLocation*, Int32Array* v);
+ void uniform3iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+ void uniform4f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void uniform4fv(const WebGLUniformLocation*, Float32Array* v);
+ void uniform4fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+ void uniform4i(const WebGLUniformLocation*, GLint x, GLint y, GLint z, GLint w);
+ void uniform4iv(const WebGLUniformLocation*, Int32Array* v);
+ void uniform4iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+ void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+ void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+ void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+ void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+ void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+ void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+
+ void useProgram(WebGLProgram*);
+ void validateProgram(WebGLProgram*);
+
+ void vertexAttrib1f(GLuint index, GLfloat x);
+ void vertexAttrib1fv(GLuint index, Float32Array* values);
+ void vertexAttrib1fv(GLuint index, GLfloat* values, GLsizei);
+ void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
+ void vertexAttrib2fv(GLuint index, Float32Array* values);
+ void vertexAttrib2fv(GLuint index, GLfloat* values, GLsizei);
+ void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+ void vertexAttrib3fv(GLuint index, Float32Array* values);
+ void vertexAttrib3fv(GLuint index, GLfloat* values, GLsizei);
+ void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ void vertexAttrib4fv(GLuint index, Float32Array* values);
+ void vertexAttrib4fv(GLuint index, GLfloat* values, GLsizei);
+ void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, long long offset);
+
+ void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+
+ void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+
+ // WEBKIT_lose_context support
+ enum LostContextMode {
+ // Lost context occurred at the graphics system level.
+ RealLostContext,
+
+ // Lost context provoked by WEBKIT_lose_context.
+ SyntheticLostContext,
+
+ // A synthetic lost context that should attempt to recover automatically
+ AutoRecoverSyntheticLostContext
+ };
+ void forceLostContext(LostContextMode);
+ void forceRestoreContext();
+ void loseContextImpl(LostContextMode);
+
+ blink::WebGraphicsContext3D* webContext() const { return m_drawingBuffer->context(); }
+ WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
+ virtual blink::WebLayer* platformLayer() const OVERRIDE;
+ Extensions3DUtil* extensionsUtil();
+
+ void reshape(int width, int height);
+
+ void markLayerComposited();
+ virtual void paintRenderingResultsToCanvas() OVERRIDE;
+ PassRefPtrWillBeRawPtr<ImageData> paintRenderingResultsToImageData();
+
+ void removeSharedObject(WebGLSharedObject*);
+ void removeContextObject(WebGLContextObject*);
+
+ unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }
+
+ // ActiveDOMObject notifications
+ virtual bool hasPendingActivity() const OVERRIDE;
+ virtual void stop() OVERRIDE;
+
+ void setSavingImage(bool isSaving) { m_savingImage = isSaving; }
+protected:
+ friend class WebGLDrawBuffers;
+ friend class WebGLFramebuffer;
+ friend class WebGLObject;
+ friend class OESVertexArrayObject;
+ friend class WebGLDebugShaders;
+ friend class WebGLCompressedTextureATC;
+ friend class WebGLCompressedTextureETC1;
+ friend class WebGLCompressedTexturePVRTC;
+ friend class WebGLCompressedTextureS3TC;
+ friend class WebGLRenderingContextErrorMessageCallback;
+ friend class WebGLVertexArrayObjectOES;
+ friend class ScopedTexture2DRestorer;
+
+ WebGLRenderingContextBase(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
+ PassRefPtr<DrawingBuffer> createDrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D>);
+ void initializeNewContext();
+ void setupFlags();
+
+ void addSharedObject(WebGLSharedObject*);
+ void addContextObject(WebGLContextObject*);
+ void detachAndRemoveAllObjects();
+
+ void destroyContext();
+ void markContextChanged(ContentChangeType);
+
+ // Query if the GL implementation is NPOT strict.
+ bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
+ // Query if depth_stencil buffer is supported.
+ bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
+
+ // Helper to return the size in bytes of OpenGL data types
+ // like GL_FLOAT, GL_INT, etc.
+ unsigned sizeInBytes(GLenum type);
+
+ // Check if each enabled vertex attribute is bound to a buffer.
+ bool validateRenderingState(const char*);
+
+ bool validateWebGLObject(const char*, WebGLObject*);
+
+ // Adds a compressed texture format.
+ void addCompressedTextureFormat(GLenum);
+ void removeAllCompressedTextureFormats();
+
+ PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height, const char* functionName);
+
+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
+
+ WebGLRenderbuffer* ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer*);
+
+ // Structure for rendering to a DrawingBuffer, instead of directly
+ // to the back-buffer of m_context.
+ RefPtr<DrawingBuffer> m_drawingBuffer;
+ RefPtr<WebGLContextGroup> m_contextGroup;
+
+ // Dispatches a context lost event once it is determined that one is needed.
+ // This is used both for synthetic and real context losses. For real ones, it's
+ // likely that there's no JavaScript on the stack, but that might be dependent
+ // on how exactly the platform discovers that the context was lost. For better
+ // portability we always defer the dispatch of the event.
+ Timer<WebGLRenderingContextBase> m_dispatchContextLostEventTimer;
+ bool m_restoreAllowed;
+ Timer<WebGLRenderingContextBase> m_restoreTimer;
+
+ bool m_needsUpdate;
+ bool m_markedCanvasDirty;
+ HashSet<WebGLContextObject*> m_contextObjects;
+
+ OwnPtr<WebGLRenderingContextLostCallback> m_contextLostCallbackAdapter;
+ OwnPtr<WebGLRenderingContextErrorMessageCallback> m_errorMessageCallbackAdapter;
+
+ // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
+ RefPtr<WebGLBuffer> m_boundArrayBuffer;
+
+ RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
+ RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
+ void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
+ {
+ if (arrayObject)
+ m_boundVertexArrayObject = arrayObject;
+ else
+ m_boundVertexArrayObject = m_defaultVertexArrayObject;
+ }
+
+ class VertexAttribValue {
+ public:
+ VertexAttribValue()
+ {
+ initValue();
+ }
+
+ void initValue()
+ {
+ value[0] = 0.0f;
+ value[1] = 0.0f;
+ value[2] = 0.0f;
+ value[3] = 1.0f;
+ }
+
+ GLfloat value[4];
+ };
+ Vector<VertexAttribValue> m_vertexAttribValue;
+ unsigned m_maxVertexAttribs;
+ RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
+ long m_vertexAttrib0BufferSize;
+ GLfloat m_vertexAttrib0BufferValue[4];
+ bool m_forceAttrib0BufferRefill;
+ bool m_vertexAttrib0UsedBefore;
+
+ RefPtr<WebGLProgram> m_currentProgram;
+ RefPtr<WebGLFramebuffer> m_framebufferBinding;
+ RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
+ class TextureUnitState {
+ public:
+ RefPtr<WebGLTexture> m_texture2DBinding;
+ RefPtr<WebGLTexture> m_textureCubeMapBinding;
+ };
+ Vector<TextureUnitState> m_textureUnits;
+ unsigned long m_activeTextureUnit;
+
+ RefPtr<WebGLTexture> m_blackTexture2D;
+ RefPtr<WebGLTexture> m_blackTextureCubeMap;
+
+ Vector<GLenum> m_compressedTextureFormats;
+
+ // Fixed-size cache of reusable image buffers for video texImage2D calls.
+ class LRUImageBufferCache {
+ public:
+ LRUImageBufferCache(int capacity);
+ // The pointer returned is owned by the image buffer map.
+ ImageBuffer* imageBuffer(const IntSize& size);
+ private:
+ void bubbleToFront(int idx);
+ OwnPtr<OwnPtr<ImageBuffer>[]> m_buffers;
+ int m_capacity;
+ };
+ LRUImageBufferCache m_generatedImageCache;
+
+ GLint m_maxTextureSize;
+ GLint m_maxCubeMapTextureSize;
+ GLint m_maxRenderbufferSize;
+ GLint m_maxViewportDims[2];
+ GLint m_maxTextureLevel;
+ GLint m_maxCubeMapTextureLevel;
+
+ GLint m_maxDrawBuffers;
+ GLint m_maxColorAttachments;
+ GLenum m_backDrawBuffer;
+ bool m_drawBuffersWebGLRequirementsChecked;
+ bool m_drawBuffersSupported;
+
+ GLint m_packAlignment;
+ GLint m_unpackAlignment;
+ bool m_unpackFlipY;
+ bool m_unpackPremultiplyAlpha;
+ GLenum m_unpackColorspaceConversion;
+ bool m_contextLost;
+ LostContextMode m_contextLostMode;
+ RefPtr<WebGLContextAttributes> m_requestedAttributes;
+
+ bool m_layerCleared;
+ GLfloat m_clearColor[4];
+ bool m_scissorEnabled;
+ GLfloat m_clearDepth;
+ GLint m_clearStencil;
+ GLboolean m_colorMask[4];
+ GLboolean m_depthMask;
+
+ bool m_stencilEnabled;
+ GLuint m_stencilMask, m_stencilMaskBack;
+ GLint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
+ GLuint m_stencilFuncMask, m_stencilFuncMaskBack;
+
+ bool m_isGLES2NPOTStrict;
+ bool m_isDepthStencilSupported;
+
+ bool m_synthesizedErrorsToConsole;
+ int m_numGLErrorsToConsoleAllowed;
+
+ bool m_multisamplingAllowed;
+ bool m_multisamplingObserverRegistered;
+
+ GLuint m_onePlusMaxEnabledAttribIndex;
+ unsigned long m_onePlusMaxNonDefaultTextureUnit;
+
+ OwnPtr<Extensions3DUtil> m_extensionsUtil;
+
+ bool m_savingImage;
+
+ enum ExtensionFlags {
+ ApprovedExtension = 0x00,
+ // Extension that is behind the draft extensions runtime flag:
+ DraftExtension = 0x01,
+ // Extension that is still in draft state, but has been selectively enabled by default under a prefix. Do not use
+ // this for enabling new draft extensions; use the DraftExtension flag instead, and do not use vendor prefixes:
+ EnabledDraftExtension = 0x04,
+ };
+
+ class ExtensionTracker {
+ public:
+ ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
+ : m_draft(flags & DraftExtension)
+ , m_prefixes(prefixes)
+ {
+ }
+
+ virtual ~ExtensionTracker()
+ {
+ }
+
+ bool draft() const
+ {
+ return m_draft;
+ }
+
+ const char* const* prefixes() const;
+ bool matchesNameWithPrefixes(const String&) const;
+
+ virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContextBase*) = 0;
+ virtual bool supported(WebGLRenderingContextBase*) const = 0;
+ virtual const char* extensionName() const = 0;
+ virtual void loseExtension() = 0;
+
+ private:
+ bool m_draft;
+ const char* const* m_prefixes;
+ };
+
+ template <typename T>
+ class TypedExtensionTracker FINAL : public ExtensionTracker {
+ public:
+ TypedExtensionTracker(RefPtr<T>& extensionField, ExtensionFlags flags, const char* const* prefixes)
+ : ExtensionTracker(flags, prefixes)
+ , m_extensionField(extensionField)
+ , m_extension(nullptr)
+ {
+ }
+
+ virtual ~TypedExtensionTracker()
+ {
+ if (m_extension) {
+ m_extension->lose(true);
+ m_extension = nullptr;
+ }
+ }
+
+ virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContextBase* context) OVERRIDE
+ {
+ if (!m_extension) {
+ m_extension = T::create(context);
+ m_extensionField = m_extension;
+ }
+
+ return m_extension;
+ }
+
+ virtual bool supported(WebGLRenderingContextBase* context) const OVERRIDE
+ {
+ return T::supported(context);
+ }
+
+ virtual const char* extensionName() const OVERRIDE
+ {
+ return T::extensionName();
+ }
+
+ virtual void loseExtension() OVERRIDE
+ {
+ if (m_extension) {
+ m_extension->lose(false);
+ if (m_extension->isLost())
+ m_extension = nullptr;
+ }
+ }
+
+ private:
+ RefPtr<T>& m_extensionField;
+ // ExtensionTracker holds it's own reference to the extension to ensure
+ // that it is not deleted before this object's destructor is called
+ RefPtr<T> m_extension;
+ };
+
+ bool m_extensionEnabled[WebGLExtensionNameCount];
+ Vector<ExtensionTracker*> m_extensions;
+
+ template <typename T>
+ void registerExtension(RefPtr<T>& extensionPtr, ExtensionFlags flags = ApprovedExtension, const char* const* prefixes = 0)
+ {
+ m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, flags, prefixes));
+ }
+
+ bool extensionSupportedAndAllowed(const ExtensionTracker*);
+
+ inline bool extensionEnabled(WebGLExtensionName name)
+ {
+ return m_extensionEnabled[name];
+ }
+
+ // Errors raised by synthesizeGLError() while the context is lost.
+ Vector<GLenum> m_lostContextErrors;
+
+ // Helpers for getParameter and others
+ WebGLGetInfo getBooleanParameter(GLenum);
+ WebGLGetInfo getBooleanArrayParameter(GLenum);
+ WebGLGetInfo getFloatParameter(GLenum);
+ WebGLGetInfo getIntParameter(GLenum);
+ WebGLGetInfo getUnsignedIntParameter(GLenum);
+ WebGLGetInfo getWebGLFloatArrayParameter(GLenum);
+ WebGLGetInfo getWebGLIntArrayParameter(GLenum);
+
+ // Clear the backbuffer if it was composited since the last operation.
+ // clearMask is set to the bitfield of any clear that would happen anyway at this time
+ // and the function returns true if that clear is now unnecessary.
+ bool clearIfComposited(GLbitfield clearMask = 0);
+
+ // Helper to restore state that clearing the framebuffer may destroy.
+ void restoreStateAfterClear();
+
+ // Convert texture internal format.
+ GLenum convertTexInternalFormat(GLenum internalformat, GLenum type);
+
+ void texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState&);
+ void texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
+ void texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState&);
+ void texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
+
+ void handleTextureCompleteness(const char*, bool);
+ void createFallbackBlackTextures1x1();
+
+ // Helper function for copyTex{Sub}Image, check whether the internalformat
+ // and the color buffer format of the current bound framebuffer combination
+ // is valid.
+ bool isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat);
+
+ // Helper function to get the bound framebuffer's color buffer format.
+ GLenum boundFramebufferColorFormat();
+
+ // Helper function to verify limits on the length of uniform and attribute locations.
+ bool validateLocationLength(const char* functionName, const String&);
+
+ // Helper function to check if size is non-negative.
+ // Generate GL error and return false for negative inputs; otherwise, return true.
+ bool validateSize(const char* functionName, GLint x, GLint y);
+
+ // Helper function to check if all characters in the string belong to the
+ // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
+ bool validateString(const char* functionName, const String&);
+
+ // Helper function to check target and texture bound to the target.
+ // Generate GL errors and return 0 if target is invalid or texture bound is
+ // null. Otherwise, return the texture bound to the target.
+ WebGLTexture* validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap);
+
+ // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level);
+
+ // Helper function to check input level for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if level is invalid.
+ bool validateTexFuncLevel(const char* functionName, GLenum target, GLint level);
+
+ // Helper function to check if a 64-bit value is non-negative and can fit into a 32-bit integer.
+ // Generates GL error and returns false if not.
+ bool validateValueFitNonNegInt32(const char* functionName, const char* paramName, long long value);
+
+ enum TexFuncValidationFunctionType {
+ NotTexSubImage2D,
+ TexSubImage2D,
+ };
+
+ enum TexFuncValidationSourceType {
+ SourceArrayBufferView,
+ SourceImageData,
+ SourceHTMLImageElement,
+ SourceHTMLCanvasElement,
+ SourceHTMLVideoElement,
+ };
+
+ // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
+ // Otherwise, it would return quickly without doing other work.
+ bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset);
+
+ // Helper function to check input width and height for functions {copy, compressed}Tex{Sub}Image.
+ // Generates GL error and returns false if width or height is invalid.
+ bool validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height);
+
+ // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type);
+
+ enum NullDisposition {
+ NullAllowed,
+ NullNotAllowed
+ };
+
+ // Helper function to validate that the given ArrayBufferView
+ // is of the correct type and contains enough data for the texImage call.
+ // Generates GL error and returns false if parameters are invalid.
+ bool validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition);
+
+ // Helper function to validate a given texture format is settable as in
+ // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
+ // copyTexSubImage2D.
+ // Generates GL error and returns false if the format is not settable.
+ bool validateSettableTexFormat(const char* functionName, GLenum format);
+
+ // Helper function to validate compressed texture data is correct size
+ // for the given format and dimensions.
+ bool validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels);
+
+ // Helper function for validating compressed texture formats.
+ bool validateCompressedTexFormat(GLenum format);
+
+ // Helper function to validate compressed texture dimensions are valid for
+ // the given format.
+ bool validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format);
+
+ // Helper function to validate compressed texture dimensions are valid for
+ // the given format.
+ bool validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture*);
+
+ // Helper function to validate mode for draw{Arrays/Elements}.
+ bool validateDrawMode(const char* functionName, GLenum);
+
+ // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
+ bool validateStencilSettings(const char* functionName);
+
+ // Helper function to validate stencil or depth func.
+ bool validateStencilOrDepthFunc(const char* functionName, GLenum);
+
+ // Helper function for texParameterf and texParameteri.
+ void texParameter(GLenum target, GLenum pname, GLfloat parami, GLint paramf, bool isFloat);
+
+ // Helper function to print GL errors to console.
+ void printGLErrorToConsole(const String&);
+
+ // Helper function to print warnings to console. Currently
+ // used only to warn about use of obsolete functions.
+ void printWarningToConsole(const String&);
+
+ // Helper function to validate input parameters for framebuffer functions.
+ // Generate GL error if parameters are illegal.
+ bool validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment);
+
+ // Helper function to validate blend equation mode.
+ bool validateBlendEquation(const char* functionName, GLenum);
+
+ // Helper function to validate blend func factors.
+ bool validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst);
+
+ // Helper function to validate a GL capability.
+ bool validateCapability(const char* functionName, GLenum);
+
+ // Helper function to validate input parameters for uniform functions.
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GLsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GLsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GLsizei, GLsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, Float32Array*, GLsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, void*, GLsizei, GLsizei mod);
+
+ // Helper function to validate the target for bufferData.
+ // Return the current bound buffer to target, or 0 if the target is invalid.
+ WebGLBuffer* validateBufferDataTarget(const char* functionName, GLenum target);
+
+ // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
+ bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&);
+
+ // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
+ bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&);
+
+ // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
+ bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&);
+
+ // Helper function to validate drawArrays(Instanced) calls
+ bool validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count);
+
+ // Helper function to validate drawElements(Instanced) calls
+ bool validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset);
+
+ // Helper function to validate draw*Instanced calls
+ bool validateDrawInstanced(const char* functionName, GLsizei primcount);
+
+ // Helper functions for vertexAttribNf{v}.
+ void vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat, GLfloat, GLfloat, GLfloat);
+ void vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array*, GLsizei expectedSize);
+ void vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat*, GLsizei, GLsizei expectedSize);
+
+ // Helper functions to bufferData() and bufferSubData().
+ void bufferDataImpl(GLenum target, long long size, const void* data, GLenum usage);
+ void bufferSubDataImpl(GLenum target, long long offset, GLsizeiptr size, const void* data);
+
+ // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
+ // Return false if caller should return without further processing.
+ bool deleteObject(WebGLObject*);
+
+ // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
+ // If the object has already been deleted, set deleted to true upon return.
+ // Return false if caller should return without further processing.
+ bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
+
+ void dispatchContextLostEvent(Timer<WebGLRenderingContextBase>*);
+ // Helper for restoration after context lost.
+ void maybeRestoreContext(Timer<WebGLRenderingContextBase>*);
+
+ enum ConsoleDisplayPreference {
+ DisplayInConsole,
+ DontDisplayInConsole
+ };
+
+ // Wrapper for WebGraphicsContext3D::synthesizeGLError that sends a message
+ // to the JavaScript console.
+ void synthesizeGLError(GLenum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
+ void emitGLWarning(const char* function, const char* reason);
+
+ String ensureNotNull(const String&) const;
+
+ // Enable or disable stencil test based on user setting and
+ // whether the current FBO has a stencil buffer.
+ void applyStencilTest();
+
+ // Helper for enabling or disabling a capability.
+ void enableOrDisable(GLenum capability, bool enable);
+
+ // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
+ IntSize clampedCanvasSize();
+
+ // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
+ // Later, return the cached value.
+ GLint maxDrawBuffers();
+ GLint maxColorAttachments();
+
+ void setBackDrawBuffer(GLenum);
+
+ void restoreCurrentFramebuffer();
+ void restoreCurrentTexture2D();
+
+ virtual void multisamplingChanged(bool) OVERRIDE;
+
+ void findNewMaxEnabledAttribIndex();
+ void findNewMaxNonDefaultTextureUnit();
+
+ friend class WebGLStateRestorer;
+ friend class WebGLRenderingContextEvictionManager;
+
+ static Vector<WebGLRenderingContextBase*>& activeContexts();
+ static Vector<WebGLRenderingContextBase*>& forciblyEvictedContexts();
+
+ static void activateContext(WebGLRenderingContextBase*);
+ static void deactivateContext(WebGLRenderingContextBase*, bool addToInactiveList);
+ static void willDestroyContext(WebGLRenderingContextBase*);
+ static void forciblyLoseOldestContext(const String& reason);
+ // Return the least recently used context's position in the active context vector.
+ // If the vector is empty, return the maximum allowed active context number.
+ static size_t oldestContextIndex();
+ static IntSize oldestContextSize();
+};
+
+DEFINE_TYPE_CASTS(WebGLRenderingContextBase, CanvasRenderingContext, context, context->is3d(), context.is3d());
+
+} // namespace WebCore
+
+#endif // WebGLRenderingContextBase_h
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.idl b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.idl
new file mode 100644
index 00000000000..4f0de43de88
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.idl
@@ -0,0 +1,689 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// http://www.khronos.org/registry/webgl/specs/latest/1.0/#WebGLRenderingContextBase
+
+typedef unsigned long GLenum;
+typedef boolean GLboolean;
+typedef unsigned long GLbitfield;
+typedef byte GLbyte; // 'byte' should be a signed 8 bit type.
+typedef short GLshort;
+typedef long GLint;
+typedef long GLsizei;
+typedef long long GLintptr;
+typedef long long GLsizeiptr;
+typedef octet GLubyte; // 'octet' should be an unsigned 8 bit type.
+typedef unsigned short GLushort;
+typedef unsigned long GLuint;
+typedef unrestricted float GLfloat;
+typedef unrestricted float GLclampf;
+
+[
+ // FIXME: [DoNotCheckConstants] and [TypeChecking=Interface|Nullable] should be applied
+ // to members and not need to be put on implementing interface
+ // DoNotCheckConstants, // need to put on implementing interface
+ NoInterfaceObject, // Always used on target of 'implements'
+ // TypeChecking=Interface|Nullable|Unrestricted, // need to put on implementing interface
+] interface WebGLRenderingContextBase {
+
+ readonly attribute HTMLCanvasElement canvas;
+
+ /* ClearBufferMask */
+ const GLenum DEPTH_BUFFER_BIT = 0x00000100;
+ const GLenum STENCIL_BUFFER_BIT = 0x00000400;
+ const GLenum COLOR_BUFFER_BIT = 0x00004000;
+
+ /* BeginMode */
+ const GLenum POINTS = 0x0000;
+ const GLenum LINES = 0x0001;
+ const GLenum LINE_LOOP = 0x0002;
+ const GLenum LINE_STRIP = 0x0003;
+ const GLenum TRIANGLES = 0x0004;
+ const GLenum TRIANGLE_STRIP = 0x0005;
+ const GLenum TRIANGLE_FAN = 0x0006;
+
+ /* AlphaFunction (not supported in ES20) */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* BlendingFactorDest */
+ const GLenum ZERO = 0;
+ const GLenum ONE = 1;
+ const GLenum SRC_COLOR = 0x0300;
+ const GLenum ONE_MINUS_SRC_COLOR = 0x0301;
+ const GLenum SRC_ALPHA = 0x0302;
+ const GLenum ONE_MINUS_SRC_ALPHA = 0x0303;
+ const GLenum DST_ALPHA = 0x0304;
+ const GLenum ONE_MINUS_DST_ALPHA = 0x0305;
+
+ /* BlendingFactorSrc */
+ /* ZERO */
+ /* ONE */
+ const GLenum DST_COLOR = 0x0306;
+ const GLenum ONE_MINUS_DST_COLOR = 0x0307;
+ const GLenum SRC_ALPHA_SATURATE = 0x0308;
+ /* SRC_ALPHA */
+ /* ONE_MINUS_SRC_ALPHA */
+ /* DST_ALPHA */
+ /* ONE_MINUS_DST_ALPHA */
+
+ /* BlendEquationSeparate */
+ const GLenum FUNC_ADD = 0x8006;
+ const GLenum BLEND_EQUATION = 0x8009;
+ const GLenum BLEND_EQUATION_RGB = 0x8009; /* same as BLEND_EQUATION */
+ const GLenum BLEND_EQUATION_ALPHA = 0x883D;
+
+ /* BlendSubtract */
+ const GLenum FUNC_SUBTRACT = 0x800A;
+ const GLenum FUNC_REVERSE_SUBTRACT = 0x800B;
+
+ /* Separate Blend Functions */
+ const GLenum BLEND_DST_RGB = 0x80C8;
+ const GLenum BLEND_SRC_RGB = 0x80C9;
+ const GLenum BLEND_DST_ALPHA = 0x80CA;
+ const GLenum BLEND_SRC_ALPHA = 0x80CB;
+ const GLenum CONSTANT_COLOR = 0x8001;
+ const GLenum ONE_MINUS_CONSTANT_COLOR = 0x8002;
+ const GLenum CONSTANT_ALPHA = 0x8003;
+ const GLenum ONE_MINUS_CONSTANT_ALPHA = 0x8004;
+ const GLenum BLEND_COLOR = 0x8005;
+
+ /* Buffer Objects */
+ const GLenum ARRAY_BUFFER = 0x8892;
+ const GLenum ELEMENT_ARRAY_BUFFER = 0x8893;
+ const GLenum ARRAY_BUFFER_BINDING = 0x8894;
+ const GLenum ELEMENT_ARRAY_BUFFER_BINDING = 0x8895;
+
+ const GLenum STREAM_DRAW = 0x88E0;
+ const GLenum STATIC_DRAW = 0x88E4;
+ const GLenum DYNAMIC_DRAW = 0x88E8;
+
+ const GLenum BUFFER_SIZE = 0x8764;
+ const GLenum BUFFER_USAGE = 0x8765;
+
+ const GLenum CURRENT_VERTEX_ATTRIB = 0x8626;
+
+ /* CullFaceMode */
+ const GLenum FRONT = 0x0404;
+ const GLenum BACK = 0x0405;
+ const GLenum FRONT_AND_BACK = 0x0408;
+
+ /* DepthFunction */
+ /* NEVER */
+ /* LESS */
+ /* EQUAL */
+ /* LEQUAL */
+ /* GREATER */
+ /* NOTEQUAL */
+ /* GEQUAL */
+ /* ALWAYS */
+
+ /* EnableCap */
+ const GLenum TEXTURE_2D = 0x0DE1;
+ const GLenum CULL_FACE = 0x0B44;
+ const GLenum BLEND = 0x0BE2;
+ const GLenum DITHER = 0x0BD0;
+ const GLenum STENCIL_TEST = 0x0B90;
+ const GLenum DEPTH_TEST = 0x0B71;
+ const GLenum SCISSOR_TEST = 0x0C11;
+ const GLenum POLYGON_OFFSET_FILL = 0x8037;
+ const GLenum SAMPLE_ALPHA_TO_COVERAGE = 0x809E;
+ const GLenum SAMPLE_COVERAGE = 0x80A0;
+
+ /* ErrorCode */
+ const GLenum NO_ERROR = 0;
+ const GLenum INVALID_ENUM = 0x0500;
+ const GLenum INVALID_VALUE = 0x0501;
+ const GLenum INVALID_OPERATION = 0x0502;
+ const GLenum OUT_OF_MEMORY = 0x0505;
+
+ /* FrontFaceDirection */
+ const GLenum CW = 0x0900;
+ const GLenum CCW = 0x0901;
+
+ /* GetPName */
+ const GLenum LINE_WIDTH = 0x0B21;
+ const GLenum ALIASED_POINT_SIZE_RANGE = 0x846D;
+ const GLenum ALIASED_LINE_WIDTH_RANGE = 0x846E;
+ const GLenum CULL_FACE_MODE = 0x0B45;
+ const GLenum FRONT_FACE = 0x0B46;
+ const GLenum DEPTH_RANGE = 0x0B70;
+ const GLenum DEPTH_WRITEMASK = 0x0B72;
+ const GLenum DEPTH_CLEAR_VALUE = 0x0B73;
+ const GLenum DEPTH_FUNC = 0x0B74;
+ const GLenum STENCIL_CLEAR_VALUE = 0x0B91;
+ const GLenum STENCIL_FUNC = 0x0B92;
+ const GLenum STENCIL_FAIL = 0x0B94;
+ const GLenum STENCIL_PASS_DEPTH_FAIL = 0x0B95;
+ const GLenum STENCIL_PASS_DEPTH_PASS = 0x0B96;
+ const GLenum STENCIL_REF = 0x0B97;
+ const GLenum STENCIL_VALUE_MASK = 0x0B93;
+ const GLenum STENCIL_WRITEMASK = 0x0B98;
+ const GLenum STENCIL_BACK_FUNC = 0x8800;
+ const GLenum STENCIL_BACK_FAIL = 0x8801;
+ const GLenum STENCIL_BACK_PASS_DEPTH_FAIL = 0x8802;
+ const GLenum STENCIL_BACK_PASS_DEPTH_PASS = 0x8803;
+ const GLenum STENCIL_BACK_REF = 0x8CA3;
+ const GLenum STENCIL_BACK_VALUE_MASK = 0x8CA4;
+ const GLenum STENCIL_BACK_WRITEMASK = 0x8CA5;
+ const GLenum VIEWPORT = 0x0BA2;
+ const GLenum SCISSOR_BOX = 0x0C10;
+ /* SCISSOR_TEST */
+ const GLenum COLOR_CLEAR_VALUE = 0x0C22;
+ const GLenum COLOR_WRITEMASK = 0x0C23;
+ const GLenum UNPACK_ALIGNMENT = 0x0CF5;
+ const GLenum PACK_ALIGNMENT = 0x0D05;
+ const GLenum MAX_TEXTURE_SIZE = 0x0D33;
+ const GLenum MAX_VIEWPORT_DIMS = 0x0D3A;
+ const GLenum SUBPIXEL_BITS = 0x0D50;
+ const GLenum RED_BITS = 0x0D52;
+ const GLenum GREEN_BITS = 0x0D53;
+ const GLenum BLUE_BITS = 0x0D54;
+ const GLenum ALPHA_BITS = 0x0D55;
+ const GLenum DEPTH_BITS = 0x0D56;
+ const GLenum STENCIL_BITS = 0x0D57;
+ const GLenum POLYGON_OFFSET_UNITS = 0x2A00;
+ /* POLYGON_OFFSET_FILL */
+ const GLenum POLYGON_OFFSET_FACTOR = 0x8038;
+ const GLenum TEXTURE_BINDING_2D = 0x8069;
+ const GLenum SAMPLE_BUFFERS = 0x80A8;
+ const GLenum SAMPLES = 0x80A9;
+ const GLenum SAMPLE_COVERAGE_VALUE = 0x80AA;
+ const GLenum SAMPLE_COVERAGE_INVERT = 0x80AB;
+
+ /* GetTextureParameter */
+ /* TEXTURE_MAG_FILTER */
+ /* TEXTURE_MIN_FILTER */
+ /* TEXTURE_WRAP_S */
+ /* TEXTURE_WRAP_T */
+
+ const GLenum COMPRESSED_TEXTURE_FORMATS = 0x86A3;
+
+ /* HintMode */
+ const GLenum DONT_CARE = 0x1100;
+ const GLenum FASTEST = 0x1101;
+ const GLenum NICEST = 0x1102;
+
+ /* HintTarget */
+ const GLenum GENERATE_MIPMAP_HINT = 0x8192;
+
+ /* DataType */
+ const GLenum BYTE = 0x1400;
+ const GLenum UNSIGNED_BYTE = 0x1401;
+ const GLenum SHORT = 0x1402;
+ const GLenum UNSIGNED_SHORT = 0x1403;
+ const GLenum INT = 0x1404;
+ const GLenum UNSIGNED_INT = 0x1405;
+ const GLenum FLOAT = 0x1406;
+
+ /* PixelFormat */
+ const GLenum DEPTH_COMPONENT = 0x1902;
+ const GLenum ALPHA = 0x1906;
+ const GLenum RGB = 0x1907;
+ const GLenum RGBA = 0x1908;
+ const GLenum LUMINANCE = 0x1909;
+ const GLenum LUMINANCE_ALPHA = 0x190A;
+
+ /* PixelType */
+ /* UNSIGNED_BYTE */
+ const GLenum UNSIGNED_SHORT_4_4_4_4 = 0x8033;
+ const GLenum UNSIGNED_SHORT_5_5_5_1 = 0x8034;
+ const GLenum UNSIGNED_SHORT_5_6_5 = 0x8363;
+
+ /* Shaders */
+ const GLenum FRAGMENT_SHADER = 0x8B30;
+ const GLenum VERTEX_SHADER = 0x8B31;
+ const GLenum MAX_VERTEX_ATTRIBS = 0x8869;
+ const GLenum MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB;
+ const GLenum MAX_VARYING_VECTORS = 0x8DFC;
+ const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+ const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C;
+ const GLenum MAX_TEXTURE_IMAGE_UNITS = 0x8872;
+ const GLenum MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD;
+ const GLenum SHADER_TYPE = 0x8B4F;
+ const GLenum DELETE_STATUS = 0x8B80;
+ const GLenum LINK_STATUS = 0x8B82;
+ const GLenum VALIDATE_STATUS = 0x8B83;
+ const GLenum ATTACHED_SHADERS = 0x8B85;
+ const GLenum ACTIVE_UNIFORMS = 0x8B86;
+ const GLenum ACTIVE_ATTRIBUTES = 0x8B89;
+ const GLenum SHADING_LANGUAGE_VERSION = 0x8B8C;
+ const GLenum CURRENT_PROGRAM = 0x8B8D;
+
+ /* StencilFunction */
+ const GLenum NEVER = 0x0200;
+ const GLenum LESS = 0x0201;
+ const GLenum EQUAL = 0x0202;
+ const GLenum LEQUAL = 0x0203;
+ const GLenum GREATER = 0x0204;
+ const GLenum NOTEQUAL = 0x0205;
+ const GLenum GEQUAL = 0x0206;
+ const GLenum ALWAYS = 0x0207;
+
+ /* StencilOp */
+ /* ZERO */
+ const GLenum KEEP = 0x1E00;
+ const GLenum REPLACE = 0x1E01;
+ const GLenum INCR = 0x1E02;
+ const GLenum DECR = 0x1E03;
+ const GLenum INVERT = 0x150A;
+ const GLenum INCR_WRAP = 0x8507;
+ const GLenum DECR_WRAP = 0x8508;
+
+ /* StringName */
+ const GLenum VENDOR = 0x1F00;
+ const GLenum RENDERER = 0x1F01;
+ const GLenum VERSION = 0x1F02;
+
+ /* TextureMagFilter */
+ const GLenum NEAREST = 0x2600;
+ const GLenum LINEAR = 0x2601;
+
+ /* TextureMinFilter */
+ /* NEAREST */
+ /* LINEAR */
+ const GLenum NEAREST_MIPMAP_NEAREST = 0x2700;
+ const GLenum LINEAR_MIPMAP_NEAREST = 0x2701;
+ const GLenum NEAREST_MIPMAP_LINEAR = 0x2702;
+ const GLenum LINEAR_MIPMAP_LINEAR = 0x2703;
+
+ /* TextureParameterName */
+ const GLenum TEXTURE_MAG_FILTER = 0x2800;
+ const GLenum TEXTURE_MIN_FILTER = 0x2801;
+ const GLenum TEXTURE_WRAP_S = 0x2802;
+ const GLenum TEXTURE_WRAP_T = 0x2803;
+
+ /* TextureTarget */
+ /* TEXTURE_2D */
+ const GLenum TEXTURE = 0x1702;
+
+ const GLenum TEXTURE_CUBE_MAP = 0x8513;
+ const GLenum TEXTURE_BINDING_CUBE_MAP = 0x8514;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;
+ const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;
+ const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851A;
+ const GLenum MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C;
+
+ /* TextureUnit */
+ const GLenum TEXTURE0 = 0x84C0;
+ const GLenum TEXTURE1 = 0x84C1;
+ const GLenum TEXTURE2 = 0x84C2;
+ const GLenum TEXTURE3 = 0x84C3;
+ const GLenum TEXTURE4 = 0x84C4;
+ const GLenum TEXTURE5 = 0x84C5;
+ const GLenum TEXTURE6 = 0x84C6;
+ const GLenum TEXTURE7 = 0x84C7;
+ const GLenum TEXTURE8 = 0x84C8;
+ const GLenum TEXTURE9 = 0x84C9;
+ const GLenum TEXTURE10 = 0x84CA;
+ const GLenum TEXTURE11 = 0x84CB;
+ const GLenum TEXTURE12 = 0x84CC;
+ const GLenum TEXTURE13 = 0x84CD;
+ const GLenum TEXTURE14 = 0x84CE;
+ const GLenum TEXTURE15 = 0x84CF;
+ const GLenum TEXTURE16 = 0x84D0;
+ const GLenum TEXTURE17 = 0x84D1;
+ const GLenum TEXTURE18 = 0x84D2;
+ const GLenum TEXTURE19 = 0x84D3;
+ const GLenum TEXTURE20 = 0x84D4;
+ const GLenum TEXTURE21 = 0x84D5;
+ const GLenum TEXTURE22 = 0x84D6;
+ const GLenum TEXTURE23 = 0x84D7;
+ const GLenum TEXTURE24 = 0x84D8;
+ const GLenum TEXTURE25 = 0x84D9;
+ const GLenum TEXTURE26 = 0x84DA;
+ const GLenum TEXTURE27 = 0x84DB;
+ const GLenum TEXTURE28 = 0x84DC;
+ const GLenum TEXTURE29 = 0x84DD;
+ const GLenum TEXTURE30 = 0x84DE;
+ const GLenum TEXTURE31 = 0x84DF;
+ const GLenum ACTIVE_TEXTURE = 0x84E0;
+
+ /* TextureWrapMode */
+ const GLenum REPEAT = 0x2901;
+ const GLenum CLAMP_TO_EDGE = 0x812F;
+ const GLenum MIRRORED_REPEAT = 0x8370;
+
+ /* Uniform Types */
+ const GLenum FLOAT_VEC2 = 0x8B50;
+ const GLenum FLOAT_VEC3 = 0x8B51;
+ const GLenum FLOAT_VEC4 = 0x8B52;
+ const GLenum INT_VEC2 = 0x8B53;
+ const GLenum INT_VEC3 = 0x8B54;
+ const GLenum INT_VEC4 = 0x8B55;
+ const GLenum BOOL = 0x8B56;
+ const GLenum BOOL_VEC2 = 0x8B57;
+ const GLenum BOOL_VEC3 = 0x8B58;
+ const GLenum BOOL_VEC4 = 0x8B59;
+ const GLenum FLOAT_MAT2 = 0x8B5A;
+ const GLenum FLOAT_MAT3 = 0x8B5B;
+ const GLenum FLOAT_MAT4 = 0x8B5C;
+ const GLenum SAMPLER_2D = 0x8B5E;
+ const GLenum SAMPLER_CUBE = 0x8B60;
+
+ /* Vertex Arrays */
+ const GLenum VERTEX_ATTRIB_ARRAY_ENABLED = 0x8622;
+ const GLenum VERTEX_ATTRIB_ARRAY_SIZE = 0x8623;
+ const GLenum VERTEX_ATTRIB_ARRAY_STRIDE = 0x8624;
+ const GLenum VERTEX_ATTRIB_ARRAY_TYPE = 0x8625;
+ const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED = 0x886A;
+ const GLenum VERTEX_ATTRIB_ARRAY_POINTER = 0x8645;
+ const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+
+ /* Read Format */
+ const GLenum IMPLEMENTATION_COLOR_READ_TYPE = 0x8B9A;
+ const GLenum IMPLEMENTATION_COLOR_READ_FORMAT = 0x8B9B;
+
+ /* Shader Source */
+ const GLenum COMPILE_STATUS = 0x8B81;
+
+ /* Shader Precision-Specified Types */
+ const GLenum LOW_FLOAT = 0x8DF0;
+ const GLenum MEDIUM_FLOAT = 0x8DF1;
+ const GLenum HIGH_FLOAT = 0x8DF2;
+ const GLenum LOW_INT = 0x8DF3;
+ const GLenum MEDIUM_INT = 0x8DF4;
+ const GLenum HIGH_INT = 0x8DF5;
+
+ /* Framebuffer Object. */
+ const GLenum FRAMEBUFFER = 0x8D40;
+ const GLenum RENDERBUFFER = 0x8D41;
+
+ const GLenum RGBA4 = 0x8056;
+ const GLenum RGB5_A1 = 0x8057;
+ const GLenum RGB565 = 0x8D62;
+ const GLenum DEPTH_COMPONENT16 = 0x81A5;
+ const GLenum STENCIL_INDEX = 0x1901;
+ const GLenum STENCIL_INDEX8 = 0x8D48;
+ const GLenum DEPTH_STENCIL = 0x84F9;
+
+ const GLenum RENDERBUFFER_WIDTH = 0x8D42;
+ const GLenum RENDERBUFFER_HEIGHT = 0x8D43;
+ const GLenum RENDERBUFFER_INTERNAL_FORMAT = 0x8D44;
+ const GLenum RENDERBUFFER_RED_SIZE = 0x8D50;
+ const GLenum RENDERBUFFER_GREEN_SIZE = 0x8D51;
+ const GLenum RENDERBUFFER_BLUE_SIZE = 0x8D52;
+ const GLenum RENDERBUFFER_ALPHA_SIZE = 0x8D53;
+ const GLenum RENDERBUFFER_DEPTH_SIZE = 0x8D54;
+ const GLenum RENDERBUFFER_STENCIL_SIZE = 0x8D55;
+
+ const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE = 0x8CD0;
+ const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL = 0x8CD2;
+ const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+
+ const GLenum COLOR_ATTACHMENT0 = 0x8CE0;
+ const GLenum DEPTH_ATTACHMENT = 0x8D00;
+ const GLenum STENCIL_ATTACHMENT = 0x8D20;
+ const GLenum DEPTH_STENCIL_ATTACHMENT = 0x821A;
+
+ const GLenum NONE = 0;
+
+ const GLenum FRAMEBUFFER_COMPLETE = 0x8CD5;
+ const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6;
+ const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+ const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9;
+ const GLenum FRAMEBUFFER_UNSUPPORTED = 0x8CDD;
+
+ const GLenum FRAMEBUFFER_BINDING = 0x8CA6;
+ const GLenum RENDERBUFFER_BINDING = 0x8CA7;
+ const GLenum MAX_RENDERBUFFER_SIZE = 0x84E8;
+
+ const GLenum INVALID_FRAMEBUFFER_OPERATION = 0x0506;
+
+ /* WebGL-specific enums */
+ const GLenum UNPACK_FLIP_Y_WEBGL = 0x9240;
+ const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
+ const GLenum CONTEXT_LOST_WEBGL = 0x9242;
+ const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+ const GLenum BROWSER_DEFAULT_WEBGL = 0x9244;
+
+ readonly attribute GLsizei drawingBufferWidth;
+ readonly attribute GLsizei drawingBufferHeight;
+
+ void activeTexture(GLenum texture);
+ void attachShader(WebGLProgram? program, WebGLShader? shader);
+ void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name);
+ void bindBuffer(GLenum target, WebGLBuffer? buffer);
+ void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer);
+ void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer);
+ void bindTexture(GLenum target, WebGLTexture? texture);
+ void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void blendEquation(GLenum mode);
+ void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+ void blendFunc(GLenum sfactor, GLenum dfactor);
+ void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ // FIXME: should be union type
+ // https://www.khronos.org/bugzilla/show_bug.cgi?id=1172
+ void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+ void bufferData(GLenum target, ArrayBufferView data, GLenum usage);
+ void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
+ void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView data);
+ void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
+
+ GLenum checkFramebufferStatus(GLenum target);
+ void clear(GLbitfield mask);
+ void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+ void clearDepth(GLclampf depth);
+ void clearStencil(GLint s);
+ void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+ void compileShader(WebGLShader? shader);
+
+ void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border, ArrayBufferView? data);
+ void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, ArrayBufferView? data);
+
+ void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+ void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+ WebGLBuffer createBuffer();
+ WebGLFramebuffer createFramebuffer();
+ WebGLProgram createProgram();
+ WebGLRenderbuffer createRenderbuffer();
+ WebGLShader createShader(GLenum type);
+ WebGLTexture createTexture();
+
+ void cullFace(GLenum mode);
+
+ void deleteBuffer(WebGLBuffer? buffer);
+ void deleteFramebuffer(WebGLFramebuffer? framebuffer);
+ void deleteProgram(WebGLProgram? program);
+ void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
+ void deleteShader(WebGLShader? shader);
+ void deleteTexture(WebGLTexture? texture);
+
+ void depthFunc(GLenum func);
+ void depthMask(GLboolean flag);
+ void depthRange(GLclampf zNear, GLclampf zFar);
+ void detachShader(WebGLProgram? program, WebGLShader? shader);
+ void disable(GLenum cap);
+ void disableVertexAttribArray(GLuint index);
+ void drawArrays(GLenum mode, GLint first, GLsizei count);
+ void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
+
+ void enable(GLenum cap);
+ void enableVertexAttribArray(GLuint index);
+ void finish();
+ void flush();
+ void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer? renderbuffer);
+ void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture? texture, GLint level);
+ void frontFace(GLenum mode);
+ void generateMipmap(GLenum target);
+
+ WebGLActiveInfo getActiveAttrib(WebGLProgram? program, GLuint index);
+ WebGLActiveInfo getActiveUniform(WebGLProgram? program, GLuint index);
+
+ [Custom] void getAttachedShaders(WebGLProgram? program);
+
+ GLint getAttribLocation(WebGLProgram? program, DOMString name);
+
+ [Custom] any getBufferParameter(GLenum target, GLenum pname);
+
+ WebGLContextAttributes getContextAttributes();
+
+ GLenum getError();
+
+ // object getExtension(DOMString name);
+ [Custom] any getExtension(DOMString name);
+
+ [Custom] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
+ [Custom] any getParameter(GLenum pname);
+ [Custom] any getProgramParameter(WebGLProgram? program, GLenum pname);
+ [TreatReturnedNullStringAs=Null] DOMString getProgramInfoLog(WebGLProgram? program);
+ [Custom] any getRenderbufferParameter(GLenum target, GLenum pname);
+ [Custom] any getShaderParameter(WebGLShader? shader, GLenum pname);
+
+ [TreatReturnedNullStringAs=Null] DOMString getShaderInfoLog(WebGLShader? shader);
+
+ WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
+
+ [TreatReturnedNullStringAs=Null] DOMString getShaderSource(WebGLShader? shader);
+
+ [Custom] sequence<DOMString> getSupportedExtensions();
+
+ [Custom] any getTexParameter(GLenum target, GLenum pname);
+
+ [Custom] any getUniform(WebGLProgram? program, WebGLUniformLocation location);
+
+ WebGLUniformLocation getUniformLocation(WebGLProgram? program, DOMString name);
+
+ [Custom] any getVertexAttrib(GLuint index, GLenum pname);
+
+ GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
+
+ void hint(GLenum target, GLenum mode);
+ GLboolean isBuffer(WebGLBuffer? buffer);
+ GLboolean isContextLost();
+ GLboolean isEnabled(GLenum cap);
+ GLboolean isFramebuffer(WebGLFramebuffer? framebuffer);
+ GLboolean isProgram(WebGLProgram? program);
+ GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
+ GLboolean isShader(WebGLShader? shader);
+ GLboolean isTexture(WebGLTexture? texture);
+ void lineWidth(GLfloat width);
+ void linkProgram(WebGLProgram? program);
+ void pixelStorei(GLenum pname, GLint param);
+ void polygonOffset(GLfloat factor, GLfloat units);
+
+ void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView? pixels);
+
+ void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ void sampleCoverage(GLclampf value, GLboolean invert);
+ void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+ void shaderSource(WebGLShader? shader, DOMString string);
+ void stencilFunc(GLenum func, GLint ref, GLuint mask);
+ void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+ void stencilMask(GLuint mask);
+ void stencilMaskSeparate(GLenum face, GLuint mask);
+ void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+ void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+ void texParameterf(GLenum target, GLenum pname, GLfloat param);
+ void texParameteri(GLenum target, GLenum pname, GLint param);
+
+ // Supported forms:
+ // FIXME: should be union type
+ // https://www.khronos.org/bugzilla/show_bug.cgi?id=1172
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, ArrayBufferView? pixels);
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, ImageData? pixels);
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLImageElement image);
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLCanvasElement canvas);
+ [RaisesException] void texImage2D(
+ GLenum target, GLint level, GLenum internalformat,
+ GLenum format, GLenum type, HTMLVideoElement video);
+
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type, ArrayBufferView? pixels);
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, ImageData? pixels);
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLImageElement image);
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLCanvasElement canvas);
+ [RaisesException] void texSubImage2D(
+ GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLenum format, GLenum type, HTMLVideoElement video);
+
+ void uniform1f(WebGLUniformLocation? location, GLfloat x);
+ [Custom] void uniform1fv(WebGLUniformLocation? location, Float32Array v);
+ void uniform1i(WebGLUniformLocation? location, GLint x);
+ [Custom] void uniform1iv(WebGLUniformLocation? location, Int32Array v);
+ void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);
+ [Custom] void uniform2fv(WebGLUniformLocation? location, Float32Array v);
+ void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
+ [Custom] void uniform2iv(WebGLUniformLocation? location, Int32Array v);
+ void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);
+ [Custom] void uniform3fv(WebGLUniformLocation? location, Float32Array v);
+ void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);
+ [Custom] void uniform3iv(WebGLUniformLocation? location, Int32Array v);
+ void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ [Custom] void uniform4fv(WebGLUniformLocation? location, Float32Array v);
+ void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);
+ [Custom] void uniform4iv(WebGLUniformLocation? location, Int32Array v);
+
+ [Custom] void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+ [Custom] void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+ [Custom] void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+
+ void useProgram(WebGLProgram? program);
+ void validateProgram(WebGLProgram? program);
+
+ void vertexAttrib1f(GLuint indx, GLfloat x);
+ [Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
+ void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+ [Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
+ void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+ [Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
+ void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+ [Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
+ void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
+ GLsizei stride, GLintptr offset);
+
+ void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp
index 0920fc9043e..203041e85cf 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp
@@ -27,22 +27,22 @@
#include "core/html/canvas/WebGLShader.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GC3Denum type)
+PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContextBase* ctx, GLenum type)
{
return adoptRef(new WebGLShader(ctx, type));
}
-WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GC3Denum type)
+WebGLShader::WebGLShader(WebGLRenderingContextBase* ctx, GLenum type)
: WebGLSharedObject(ctx)
, m_type(type)
, m_source("")
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createShader(type));
+ setObject(ctx->webContext()->createShader(type));
}
WebGLShader::~WebGLShader()
@@ -50,7 +50,7 @@ WebGLShader::~WebGLShader()
deleteObject(0);
}
-void WebGLShader::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLShader::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
context3d->deleteShader(object);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h
index 6c776afc281..2d2fc23be20 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShader.h
@@ -29,28 +29,29 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/canvas/WebGLSharedObject.h"
#include "wtf/PassRefPtr.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
-class WebGLShader : public WebGLSharedObject, public ScriptWrappable {
+class WebGLShader FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
virtual ~WebGLShader();
- static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GC3Denum);
+ static PassRefPtr<WebGLShader> create(WebGLRenderingContextBase*, GLenum);
- GC3Denum type() const { return m_type; }
+ GLenum type() const { return m_type; }
const String& source() const { return m_source; }
void setSource(const String& source) { m_source = source; }
private:
- WebGLShader(WebGLRenderingContext*, GC3Denum);
+ WebGLShader(WebGLRenderingContextBase*, GLenum);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
- virtual bool isShader() const { return true; }
+ virtual bool isShader() const OVERRIDE { return true; }
- GC3Denum m_type;
+ GLenum m_type;
String m_source;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp
index 288468f37ce..8fb4bb1c9af 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp
@@ -31,27 +31,27 @@
namespace WebCore {
// static
-PassRefPtr<WebGLShaderPrecisionFormat> WebGLShaderPrecisionFormat::create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision)
+PassRefPtr<WebGLShaderPrecisionFormat> WebGLShaderPrecisionFormat::create(GLint rangeMin, GLint rangeMax, GLint precision)
{
return adoptRef(new WebGLShaderPrecisionFormat(rangeMin, rangeMax, precision));
}
-GC3Dint WebGLShaderPrecisionFormat::rangeMin() const
+GLint WebGLShaderPrecisionFormat::rangeMin() const
{
return m_rangeMin;
}
-GC3Dint WebGLShaderPrecisionFormat::rangeMax() const
+GLint WebGLShaderPrecisionFormat::rangeMax() const
{
return m_rangeMax;
}
-GC3Dint WebGLShaderPrecisionFormat::precision() const
+GLint WebGLShaderPrecisionFormat::precision() const
{
return m_precision;
}
-WebGLShaderPrecisionFormat::WebGLShaderPrecisionFormat(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision)
+WebGLShaderPrecisionFormat::WebGLShaderPrecisionFormat(GLint rangeMin, GLint rangeMax, GLint precision)
: m_rangeMin(rangeMin)
, m_rangeMax(rangeMax)
, m_precision(precision)
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h
index b59acc052a5..bd363bb232b 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.h
@@ -28,7 +28,7 @@
#define WebGLShaderPrecisionFormat_h
#include "bindings/v8/ScriptWrappable.h"
-#include "platform/graphics/GraphicsContext3D.h"
+#include "platform/graphics/GraphicsTypes3D.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -36,18 +36,18 @@ namespace WebCore {
class WebGLShaderPrecisionFormat : public RefCounted<WebGLShaderPrecisionFormat>, public ScriptWrappable {
public:
- static PassRefPtr<WebGLShaderPrecisionFormat> create(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision);
+ static PassRefPtr<WebGLShaderPrecisionFormat> create(GLint rangeMin, GLint rangeMax, GLint precision);
- GC3Dint rangeMin() const;
- GC3Dint rangeMax() const;
- GC3Dint precision() const;
+ GLint rangeMin() const;
+ GLint rangeMax() const;
+ GLint precision() const;
private:
- WebGLShaderPrecisionFormat(GC3Dint rangeMin, GC3Dint rangeMax, GC3Dint precision);
+ WebGLShaderPrecisionFormat(GLint rangeMin, GLint rangeMax, GLint precision);
- GC3Dint m_rangeMin;
- GC3Dint m_rangeMax;
- GC3Dint m_precision;
+ GLint m_rangeMin;
+ GLint m_rangeMax;
+ GLint m_precision;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp
index f5d63651ff5..94f1db80baf 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp
@@ -28,11 +28,11 @@
#include "core/html/canvas/WebGLSharedObject.h"
#include "core/html/canvas/WebGLContextGroup.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context)
+WebGLSharedObject::WebGLSharedObject(WebGLRenderingContextBase* context)
: WebGLObject(context),
m_contextGroup(context->contextGroup())
{
@@ -54,9 +54,9 @@ void WebGLSharedObject::detachContextGroup()
}
}
-GraphicsContext3D* WebGLSharedObject::getAGraphicsContext3D() const
+blink::WebGraphicsContext3D* WebGLSharedObject::getAWebGraphicsContext3D() const
{
- return m_contextGroup ? m_contextGroup->getAGraphicsContext3D() : 0;
+ return m_contextGroup ? m_contextGroup->getAWebGraphicsContext3D() : 0;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h
index 6c33471ba7f..990c8ae1565 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.h
@@ -30,9 +30,8 @@
namespace WebCore {
-class GraphicsContext3D;
class WebGLContextGroup;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
// WebGLSharedObject the base class for objects that can be shared by multiple
// WebGLRenderingContexts.
@@ -43,13 +42,12 @@ public:
WebGLContextGroup* contextGroup() const { return m_contextGroup; }
virtual bool isBuffer() const { return false; }
- virtual bool isFramebuffer() const { return false; }
virtual bool isProgram() const { return false; }
virtual bool isRenderbuffer() const { return false; }
virtual bool isShader() const { return false; }
virtual bool isTexture() const { return false; }
- virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContext*) const
+ virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContextBase*) const OVERRIDE FINAL
{
return contextGroup == m_contextGroup;
}
@@ -57,14 +55,14 @@ public:
void detachContextGroup();
protected:
- WebGLSharedObject(WebGLRenderingContext*);
+ WebGLSharedObject(WebGLRenderingContextBase*);
- virtual bool hasGroupOrContext() const
+ virtual bool hasGroupOrContext() const OVERRIDE FINAL
{
return m_contextGroup;
}
- virtual GraphicsContext3D* getAGraphicsContext3D() const;
+ virtual blink::WebGraphicsContext3D* getAWebGraphicsContext3D() const OVERRIDE FINAL;
private:
WebGLContextGroup* m_contextGroup;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp
index 804547e1b0e..292974230ea 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.cpp
@@ -27,16 +27,16 @@
#include "core/html/canvas/WebGLTexture.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContextBase* ctx)
{
return adoptRef(new WebGLTexture(ctx));
}
-WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
+WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx)
: WebGLSharedObject(ctx)
, m_target(0)
, m_minFilter(GL_NEAREST_MIPMAP_LINEAR)
@@ -51,7 +51,7 @@ WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
, m_isHalfFloatType(false)
{
ScriptWrappable::init(this);
- setObject(ctx->graphicsContext3D()->createTexture());
+ setObject(ctx->webContext()->createTexture());
}
WebGLTexture::~WebGLTexture()
@@ -59,7 +59,7 @@ WebGLTexture::~WebGLTexture()
deleteObject(0);
}
-void WebGLTexture::setTarget(GC3Denum target, GC3Dint maxLevel)
+void WebGLTexture::setTarget(GLenum target, GLint maxLevel)
{
if (!object())
return;
@@ -81,7 +81,7 @@ void WebGLTexture::setTarget(GC3Denum target, GC3Dint maxLevel)
}
}
-void WebGLTexture::setParameteri(GC3Denum pname, GC3Dint param)
+void WebGLTexture::setParameteri(GLenum pname, GLint param)
{
if (!object() || !m_target)
return;
@@ -130,15 +130,15 @@ void WebGLTexture::setParameteri(GC3Denum pname, GC3Dint param)
update();
}
-void WebGLTexture::setParameterf(GC3Denum pname, GC3Dfloat param)
+void WebGLTexture::setParameterf(GLenum pname, GLfloat param)
{
if (!object() || !m_target)
return;
- GC3Dint iparam = static_cast<GC3Dint>(param);
+ GLint iparam = static_cast<GLint>(param);
setParameteri(pname, iparam);
}
-void WebGLTexture::setLevelInfo(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Denum type)
+void WebGLTexture::setLevelInfo(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type)
{
if (!object() || !m_target)
return;
@@ -160,10 +160,10 @@ void WebGLTexture::generateMipmapLevelInfo()
if (!m_isComplete) {
for (size_t ii = 0; ii < m_info.size(); ++ii) {
const LevelInfo& info0 = m_info[ii][0];
- GC3Dsizei width = info0.width;
- GC3Dsizei height = info0.height;
- GC3Dint levelCount = computeLevelCount(width, height);
- for (GC3Dint level = 1; level < levelCount; ++level) {
+ GLsizei width = info0.width;
+ GLsizei height = info0.height;
+ GLint levelCount = computeLevelCount(width, height);
+ for (GLint level = 1; level < levelCount; ++level) {
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
LevelInfo& info = m_info[ii][level];
@@ -175,7 +175,7 @@ void WebGLTexture::generateMipmapLevelInfo()
m_needToUseBlackTexture = false;
}
-GC3Denum WebGLTexture::getInternalFormat(GC3Denum target, GC3Dint level) const
+GLenum WebGLTexture::getInternalFormat(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -183,7 +183,7 @@ GC3Denum WebGLTexture::getInternalFormat(GC3Denum target, GC3Dint level) const
return info->internalFormat;
}
-GC3Denum WebGLTexture::getType(GC3Denum target, GC3Dint level) const
+GLenum WebGLTexture::getType(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -191,7 +191,7 @@ GC3Denum WebGLTexture::getType(GC3Denum target, GC3Dint level) const
return info->type;
}
-GC3Dsizei WebGLTexture::getWidth(GC3Denum target, GC3Dint level) const
+GLsizei WebGLTexture::getWidth(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -199,7 +199,7 @@ GC3Dsizei WebGLTexture::getWidth(GC3Denum target, GC3Dint level) const
return info->width;
}
-GC3Dsizei WebGLTexture::getHeight(GC3Denum target, GC3Dint level) const
+GLsizei WebGLTexture::getHeight(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -207,7 +207,7 @@ GC3Dsizei WebGLTexture::getHeight(GC3Denum target, GC3Dint level) const
return info->height;
}
-bool WebGLTexture::isValid(GC3Denum target, GC3Dint level) const
+bool WebGLTexture::isValid(GLenum target, GLint level) const
{
const LevelInfo* info = getLevelInfo(target, level);
if (!info)
@@ -215,7 +215,7 @@ bool WebGLTexture::isValid(GC3Denum target, GC3Dint level) const
return info->valid;
}
-bool WebGLTexture::isNPOT(GC3Dsizei width, GC3Dsizei height)
+bool WebGLTexture::isNPOT(GLsizei width, GLsizei height)
{
ASSERT(width >= 0 && height >= 0);
if (!width || !height)
@@ -245,12 +245,12 @@ bool WebGLTexture::needToUseBlackTexture(TextureExtensionFlag flag) const
return false;
}
-void WebGLTexture::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLTexture::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
context3d->deleteTexture(object);
}
-int WebGLTexture::mapTargetToIndex(GC3Denum target) const
+int WebGLTexture::mapTargetToIndex(GLenum target) const
{
if (m_target == GL_TEXTURE_2D) {
if (target == GL_TEXTURE_2D)
@@ -290,17 +290,17 @@ bool WebGLTexture::canGenerateMipmaps()
return true;
}
-GC3Dint WebGLTexture::computeLevelCount(GC3Dsizei width, GC3Dsizei height)
+GLint WebGLTexture::computeLevelCount(GLsizei width, GLsizei height)
{
// return 1 + log2Floor(std::max(width, height));
- GC3Dsizei n = std::max(width, height);
+ GLsizei n = std::max(width, height);
if (n <= 0)
return 0;
- GC3Dint log = 0;
- GC3Dsizei value = n;
+ GLint log = 0;
+ GLsizei value = n;
for (int ii = 4; ii >= 0; --ii) {
int shift = (1 << ii);
- GC3Dsizei x = (value >> shift);
+ GLsizei x = (value >> shift);
if (x) {
value = x;
log += shift;
@@ -322,7 +322,7 @@ void WebGLTexture::update()
m_isComplete = true;
m_isCubeComplete = true;
const LevelInfo& first = m_info[0][0];
- GC3Dint levelCount = computeLevelCount(first.width, first.height);
+ GLint levelCount = computeLevelCount(first.width, first.height);
if (levelCount < 1)
m_isComplete = false;
else {
@@ -337,9 +337,9 @@ void WebGLTexture::update()
m_isComplete = false;
break;
}
- GC3Dsizei width = info0.width;
- GC3Dsizei height = info0.height;
- for (GC3Dint level = 1; level < levelCount; ++level) {
+ GLsizei width = info0.width;
+ GLsizei height = info0.height;
+ for (GLint level = 1; level < levelCount; ++level) {
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
const LevelInfo& info = m_info[ii][level];
@@ -369,14 +369,14 @@ void WebGLTexture::update()
m_needToUseBlackTexture = true;
}
-const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GC3Denum target, GC3Dint level) const
+const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(GLenum target, GLint level) const
{
if (!object() || !m_target)
return 0;
int targetIndex = mapTargetToIndex(target);
if (targetIndex < 0 || targetIndex >= static_cast<int>(m_info.size()))
return 0;
- if (level < 0 || level >= static_cast<GC3Dint>(m_info[targetIndex].size()))
+ if (level < 0 || level >= static_cast<GLint>(m_info[targetIndex].size()))
return 0;
return &(m_info[targetIndex][level]);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h
index 67f1fdce86c..bb086c08a10 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLTexture.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class WebGLTexture : public WebGLSharedObject, public ScriptWrappable {
+class WebGLTexture FINAL : public WebGLSharedObject, public ScriptWrappable {
public:
enum TextureExtensionFlag {
NoTextureExtensionEnabled = 0,
@@ -42,30 +42,30 @@ public:
};
virtual ~WebGLTexture();
- static PassRefPtr<WebGLTexture> create(WebGLRenderingContext*);
+ static PassRefPtr<WebGLTexture> create(WebGLRenderingContextBase*);
- void setTarget(GC3Denum target, GC3Dint maxLevel);
- void setParameteri(GC3Denum pname, GC3Dint param);
- void setParameterf(GC3Denum pname, GC3Dfloat param);
+ void setTarget(GLenum target, GLint maxLevel);
+ void setParameteri(GLenum pname, GLint param);
+ void setParameterf(GLenum pname, GLfloat param);
- GC3Denum getTarget() const { return m_target; }
+ GLenum getTarget() const { return m_target; }
int getMinFilter() const { return m_minFilter; }
- void setLevelInfo(GC3Denum target, GC3Dint level, GC3Denum internalFormat, GC3Dsizei width, GC3Dsizei height, GC3Denum type);
+ void setLevelInfo(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type);
bool canGenerateMipmaps();
// Generate all level information.
void generateMipmapLevelInfo();
- GC3Denum getInternalFormat(GC3Denum target, GC3Dint level) const;
- GC3Denum getType(GC3Denum target, GC3Dint level) const;
- GC3Dsizei getWidth(GC3Denum target, GC3Dint level) const;
- GC3Dsizei getHeight(GC3Denum target, GC3Dint level) const;
- bool isValid(GC3Denum target, GC3Dint level) const;
+ GLenum getInternalFormat(GLenum target, GLint level) const;
+ GLenum getType(GLenum target, GLint level) const;
+ GLsizei getWidth(GLenum target, GLint level) const;
+ GLsizei getHeight(GLenum target, GLint level) const;
+ bool isValid(GLenum target, GLint level) const;
// Whether width/height is NotPowerOfTwo.
- static bool isNPOT(GC3Dsizei, GC3Dsizei);
+ static bool isNPOT(GLsizei, GLsizei);
bool isNPOT() const;
// Determine if texture sampling should always return [0, 0, 0, 1] (OpenGL ES 2.0 Sec 3.8.2).
@@ -73,12 +73,12 @@ public:
bool hasEverBeenBound() const { return object() && m_target; }
- static GC3Dint computeLevelCount(GC3Dsizei width, GC3Dsizei height);
+ static GLint computeLevelCount(GLsizei width, GLsizei height);
protected:
- WebGLTexture(WebGLRenderingContext*);
+ WebGLTexture(WebGLRenderingContextBase*);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
private:
class LevelInfo {
@@ -92,7 +92,7 @@ private:
{
}
- void setInfo(GC3Denum internalFmt, GC3Dsizei w, GC3Dsizei h, GC3Denum tp)
+ void setInfo(GLenum internalFmt, GLsizei w, GLsizei h, GLenum tp)
{
valid = true;
internalFormat = internalFmt;
@@ -102,26 +102,26 @@ private:
}
bool valid;
- GC3Denum internalFormat;
- GC3Dsizei width;
- GC3Dsizei height;
- GC3Denum type;
+ GLenum internalFormat;
+ GLsizei width;
+ GLsizei height;
+ GLenum type;
};
- virtual bool isTexture() const { return true; }
+ virtual bool isTexture() const OVERRIDE { return true; }
void update();
- int mapTargetToIndex(GC3Denum) const;
+ int mapTargetToIndex(GLenum) const;
- const LevelInfo* getLevelInfo(GC3Denum target, GC3Dint level) const;
+ const LevelInfo* getLevelInfo(GLenum target, GLint level) const;
- GC3Denum m_target;
+ GLenum m_target;
- GC3Denum m_minFilter;
- GC3Denum m_magFilter;
- GC3Denum m_wrapS;
- GC3Denum m_wrapT;
+ GLenum m_minFilter;
+ GLenum m_magFilter;
+ GLenum m_wrapS;
+ GLenum m_wrapT;
Vector<Vector<LevelInfo> > m_info;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp
index 2790c7eb70c..cd1eb95593a 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.cpp
@@ -30,12 +30,12 @@
namespace WebCore {
-PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GC3Dint location)
+PassRefPtr<WebGLUniformLocation> WebGLUniformLocation::create(WebGLProgram* program, GLint location)
{
return adoptRef(new WebGLUniformLocation(program, location));
}
-WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program, GC3Dint location)
+WebGLUniformLocation::WebGLUniformLocation(WebGLProgram* program, GLint location)
: m_program(program)
, m_location(location)
{
@@ -53,7 +53,7 @@ WebGLProgram* WebGLUniformLocation::program() const
return m_program.get();
}
-GC3Dint WebGLUniformLocation::location() const
+GLint WebGLUniformLocation::location() const
{
// If the program has been linked again, then this UniformLocation is no
// longer valid.
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h
index 34e0480c126..76e98b3e359 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLUniformLocation.h
@@ -36,18 +36,18 @@ namespace WebCore {
class WebGLUniformLocation FINAL : public RefCounted<WebGLUniformLocation>, public ScriptWrappable {
public:
- static PassRefPtr<WebGLUniformLocation> create(WebGLProgram*, GC3Dint location);
+ static PassRefPtr<WebGLUniformLocation> create(WebGLProgram*, GLint location);
WebGLProgram* program() const;
- GC3Dint location() const;
+ GLint location() const;
protected:
- WebGLUniformLocation(WebGLProgram*, GC3Dint location);
+ WebGLUniformLocation(WebGLProgram*, GLint location);
private:
RefPtr<WebGLProgram> m_program;
- GC3Dint m_location;
+ GLint m_location;
unsigned m_linkCount;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
index 1d54886af8a..6c12bccb704 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
@@ -27,31 +27,29 @@
#include "core/html/canvas/WebGLVertexArrayObjectOES.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
-#include "platform/graphics/Extensions3D.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
namespace WebCore {
-PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContext* ctx, VaoType type)
+PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContextBase* ctx, VaoType type)
{
return adoptRef(new WebGLVertexArrayObjectOES(ctx, type));
}
-WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx, VaoType type)
+WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContextBase* ctx, VaoType type)
: WebGLContextObject(ctx)
, m_type(type)
, m_hasEverBeenBound(false)
- , m_boundElementArrayBuffer(0)
+ , m_boundElementArrayBuffer(nullptr)
{
ScriptWrappable::init(this);
m_vertexAttribState.resize(ctx->maxVertexAttribs());
- Extensions3D* extensions = context()->graphicsContext3D()->extensions();
switch (m_type) {
case VaoTypeDefault:
break;
default:
- setObject(extensions->createVertexArrayOES());
+ setObject(context()->webContext()->createVertexArrayOES());
break;
}
}
@@ -61,14 +59,13 @@ WebGLVertexArrayObjectOES::~WebGLVertexArrayObjectOES()
deleteObject(0);
}
-void WebGLVertexArrayObjectOES::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+void WebGLVertexArrayObjectOES::deleteObjectImpl(blink::WebGraphicsContext3D* context3d, Platform3DObject object)
{
- Extensions3D* extensions = context3d->extensions();
switch (m_type) {
case VaoTypeDefault:
break;
default:
- extensions->deleteVertexArrayOES(object);
+ context()->webContext()->deleteVertexArrayOES(object);
break;
}
@@ -87,22 +84,22 @@ void WebGLVertexArrayObjectOES::setElementArrayBuffer(PassRefPtr<WebGLBuffer> bu
if (buffer)
buffer->onAttached();
if (m_boundElementArrayBuffer)
- m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
+ m_boundElementArrayBuffer->onDetached(context()->webContext());
m_boundElementArrayBuffer = buffer;
}
void WebGLVertexArrayObjectOES::setVertexAttribState(
- GC3Duint index, GC3Dsizei bytesPerElement, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, PassRefPtr<WebGLBuffer> buffer)
+ GLuint index, GLsizei bytesPerElement, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset, PassRefPtr<WebGLBuffer> buffer)
{
- GC3Dsizei validatedStride = stride ? stride : bytesPerElement;
+ GLsizei validatedStride = stride ? stride : bytesPerElement;
VertexAttribState& state = m_vertexAttribState[index];
if (buffer)
buffer->onAttached();
if (state.bufferBinding)
- state.bufferBinding->onDetached(context()->graphicsContext3D());
+ state.bufferBinding->onDetached(context()->webContext());
state.bufferBinding = buffer;
state.bytesPerElement = bytesPerElement;
@@ -117,20 +114,20 @@ void WebGLVertexArrayObjectOES::setVertexAttribState(
void WebGLVertexArrayObjectOES::unbindBuffer(PassRefPtr<WebGLBuffer> buffer)
{
if (m_boundElementArrayBuffer == buffer) {
- m_boundElementArrayBuffer->onDetached(context()->graphicsContext3D());
- m_boundElementArrayBuffer = 0;
+ m_boundElementArrayBuffer->onDetached(context()->webContext());
+ m_boundElementArrayBuffer = nullptr;
}
for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
VertexAttribState& state = m_vertexAttribState[i];
if (state.bufferBinding == buffer) {
- buffer->onDetached(context()->graphicsContext3D());
- state.bufferBinding = 0;
+ buffer->onDetached(context()->webContext());
+ state.bufferBinding = nullptr;
}
}
}
-void WebGLVertexArrayObjectOES::setVertexAttribDivisor(GC3Duint index, GC3Duint divisor)
+void WebGLVertexArrayObjectOES::setVertexAttribDivisor(GLuint index, GLuint divisor)
{
VertexAttribState& state = m_vertexAttribState[index];
state.divisor = divisor;
diff --git a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
index 8b1fd6ee063..e54ef0a36a9 100644
--- a/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
+++ b/chromium/third_party/WebKit/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
@@ -33,7 +33,7 @@
namespace WebCore {
-class WebGLVertexArrayObjectOES : public WebGLContextObject, public ScriptWrappable {
+class WebGLVertexArrayObjectOES FINAL : public WebGLContextObject, public ScriptWrappable {
public:
enum VaoType {
VaoTypeDefault,
@@ -42,7 +42,7 @@ public:
virtual ~WebGLVertexArrayObjectOES();
- static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContext*, VaoType);
+ static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContextBase*, VaoType);
// Cached values for vertex attrib range checks
struct VertexAttribState {
@@ -61,14 +61,14 @@ public:
bool enabled;
RefPtr<WebGLBuffer> bufferBinding;
- GC3Dsizei bytesPerElement;
- GC3Dint size;
- GC3Denum type;
+ GLsizei bytesPerElement;
+ GLint size;
+ GLenum type;
bool normalized;
- GC3Dsizei stride;
- GC3Dsizei originalStride;
- GC3Dintptr offset;
- GC3Duint divisor;
+ GLsizei stride;
+ GLsizei originalStride;
+ GLintptr offset;
+ GLuint divisor;
};
bool isDefaultObject() const { return m_type == VaoTypeDefault; }
@@ -80,16 +80,14 @@ public:
void setElementArrayBuffer(PassRefPtr<WebGLBuffer>);
VertexAttribState& getVertexAttribState(int index) { return m_vertexAttribState[index]; }
- void setVertexAttribState(GC3Duint, GC3Dsizei, GC3Dint, GC3Denum, GC3Dboolean, GC3Dsizei, GC3Dintptr, PassRefPtr<WebGLBuffer>);
+ void setVertexAttribState(GLuint, GLsizei, GLint, GLenum, GLboolean, GLsizei, GLintptr, PassRefPtr<WebGLBuffer>);
void unbindBuffer(PassRefPtr<WebGLBuffer>);
- void setVertexAttribDivisor(GC3Duint index, GC3Duint divisor);
+ void setVertexAttribDivisor(GLuint index, GLuint divisor);
private:
- WebGLVertexArrayObjectOES(WebGLRenderingContext*, VaoType);
+ WebGLVertexArrayObjectOES(WebGLRenderingContextBase*, VaoType);
- virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
-
- virtual bool isVertexArray() const { return true; }
+ virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
VaoType m_type;
bool m_hasEverBeenBound;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp
index a41645c2428..63fed8c3512 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseButtonInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/BaseButtonInputType.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLInputElement.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp
index 7ffe40b29da..d40d965acb2 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/BaseCheckableInputType.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLInputElement.h"
@@ -111,4 +111,9 @@ bool BaseCheckableInputType::isCheckable()
return true;
}
+bool BaseCheckableInputType::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
+{
+ return oldValue != newValue;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h
index fdb2fa006ec..aeb6ee2e462 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseCheckableInputType.h
@@ -42,16 +42,17 @@ protected:
virtual void handleKeydownEvent(KeyboardEvent*);
private:
- virtual FormControlState saveFormControlState() const OVERRIDE;
- virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
- virtual bool appendFormData(FormDataList&, bool) const OVERRIDE;
- virtual void handleKeypressEvent(KeyboardEvent*) OVERRIDE;
- virtual bool canSetStringValue() const OVERRIDE;
- virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
- virtual String fallbackValue() const OVERRIDE;
- virtual bool storesValueSeparateFromAttribute() OVERRIDE;
- virtual void setValue(const String&, bool, TextFieldEventBehavior) OVERRIDE;
- virtual bool isCheckable() OVERRIDE;
+ virtual FormControlState saveFormControlState() const OVERRIDE FINAL;
+ virtual void restoreFormControlState(const FormControlState&) OVERRIDE FINAL;
+ virtual bool appendFormData(FormDataList&, bool) const OVERRIDE FINAL;
+ virtual void handleKeypressEvent(KeyboardEvent*) OVERRIDE FINAL;
+ virtual bool canSetStringValue() const OVERRIDE FINAL;
+ virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE FINAL;
+ virtual String fallbackValue() const OVERRIDE FINAL;
+ virtual bool storesValueSeparateFromAttribute() OVERRIDE FINAL;
+ virtual void setValue(const String&, bool, TextFieldEventBehavior) OVERRIDE FINAL;
+ virtual bool isCheckable() OVERRIDE FINAL;
+ virtual bool shouldDispatchFormControlChangeEvent(String&, String&) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
index 3967a8ac871..76f32aba3de 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
@@ -29,17 +29,16 @@
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/FrameHost.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/page/Chrome.h"
-#include "core/page/Page.h"
#include "platform/UserGestureIndicator.h"
namespace WebCore {
BaseChooserOnlyDateAndTimeInputType::~BaseChooserOnlyDateAndTimeInputType()
{
- closeDateTimeChooser();
}
void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event*)
@@ -54,25 +53,29 @@ void BaseChooserOnlyDateAndTimeInputType::handleDOMActivateEvent(Event*)
DateTimeChooserParameters parameters;
if (!element().setupDateTimeChooserParameters(parameters))
return;
- m_dateTimeChooser = element().document().page()->chrome().openDateTimeChooser(this, parameters);
+ m_dateTimeChooser = element().document().frameHost()->chrome().openDateTimeChooser(this, parameters);
}
void BaseChooserOnlyDateAndTimeInputType::createShadowSubtree()
{
DEFINE_STATIC_LOCAL(AtomicString, valueContainerPseudo, ("-webkit-date-and-time-value", AtomicString::ConstructFromLiteral));
- RefPtr<HTMLDivElement> valueContainer = HTMLDivElement::create(element().document());
- valueContainer->setPseudo(valueContainerPseudo);
+ RefPtrWillBeRawPtr<HTMLDivElement> valueContainer = HTMLDivElement::create(element().document());
+ valueContainer->setShadowPseudoId(valueContainerPseudo);
element().userAgentShadowRoot()->appendChild(valueContainer.get());
- updateAppearance();
+ updateView();
}
-void BaseChooserOnlyDateAndTimeInputType::updateAppearance()
+void BaseChooserOnlyDateAndTimeInputType::updateView()
{
Node* node = element().userAgentShadowRoot()->firstChild();
if (!node || !node->isHTMLElement())
return;
- String displayValue = visibleValue();
+ String displayValue;
+ if (!element().suggestedValue().isNull())
+ displayValue = element().suggestedValue();
+ else
+ displayValue = visibleValue();
if (displayValue.isEmpty()) {
// Need to put something to keep text baseline.
displayValue = " ";
@@ -84,7 +87,7 @@ void BaseChooserOnlyDateAndTimeInputType::setValue(const String& value, bool val
{
BaseDateAndTimeInputType::setValue(value, valueChanged, eventBehavior);
if (valueChanged)
- updateAppearance();
+ updateView();
}
void BaseChooserOnlyDateAndTimeInputType::closePopupView()
@@ -138,5 +141,12 @@ void BaseChooserOnlyDateAndTimeInputType::accessKeyAction(bool sendMouseEvents)
BaseClickableWithKeyInputType::accessKeyAction(element(), sendMouseEvents);
}
+void BaseChooserOnlyDateAndTimeInputType::trace(Visitor* visitor)
+{
+ visitor->trace(m_dateTimeChooser);
+ BaseDateAndTimeInputType::trace(visitor);
+ DateTimeChooserClient::trace(visitor);
+}
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
index 4ba1f878ce5..92e1764fb80 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
@@ -35,12 +35,14 @@
namespace WebCore {
class BaseChooserOnlyDateAndTimeInputType : public BaseDateAndTimeInputType, public DateTimeChooserClient {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(BaseChooserOnlyDateAndTimeInputType);
protected:
- BaseChooserOnlyDateAndTimeInputType(HTMLInputElement& element) : BaseDateAndTimeInputType(element) { }
+ explicit BaseChooserOnlyDateAndTimeInputType(HTMLInputElement& element) : BaseDateAndTimeInputType(element) { }
virtual ~BaseChooserOnlyDateAndTimeInputType();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- void updateAppearance();
void closeDateTimeChooser();
// InputType functions:
@@ -52,13 +54,14 @@ private:
virtual void handleKeypressEvent(KeyboardEvent*) OVERRIDE;
virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
+ virtual void updateView() OVERRIDE;
// DateTimeChooserClient functions:
virtual void didChooseValue(const String&) OVERRIDE;
virtual void didChooseValue(double) OVERRIDE;
virtual void didEndChooser() OVERRIDE;
- RefPtr<DateTimeChooser> m_dateTimeChooser;
+ RefPtrWillBeMember<DateTimeChooser> m_dateTimeChooser;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp
index bf87e948cc0..662f4e6a4cd 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.cpp
@@ -43,7 +43,6 @@ namespace WebCore {
using blink::WebLocalizedString;
using namespace HTMLNames;
-using namespace std;
static const int msecPerMinute = 60 * 1000;
static const int msecPerSecond = 1000;
@@ -64,9 +63,9 @@ double BaseDateAndTimeInputType::valueAsDouble() const
return value.isFinite() ? value.toDouble() : DateComponents::invalidMilliseconds();
}
-void BaseDateAndTimeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState&) const
+void BaseDateAndTimeInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- element().setValue(serialize(newValue), eventBehavior);
+ setValueAsDecimal(Decimal::fromDouble(newValue), eventBehavior, exceptionState);
}
bool BaseDateAndTimeInputType::typeMismatchFor(const String& value) const
@@ -177,7 +176,7 @@ bool BaseDateAndTimeInputType::supportsReadOnly() const
bool BaseDateAndTimeInputType::shouldRespectListAttribute()
{
- return InputType::themeSupportsDataListUI(this);
+ return true;
}
bool BaseDateAndTimeInputType::valueMissing(const String& value) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h
index 0bdf559b0f2..bf5c8bf895a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseDateAndTimeInputType.h
@@ -43,7 +43,11 @@ class BaseDateAndTimeInputType : public InputType {
protected:
BaseDateAndTimeInputType(HTMLInputElement& element) : InputType(element) { }
virtual Decimal parseToNumber(const String&, const Decimal&) const OVERRIDE;
- virtual bool parseToDateComponents(const String&, DateComponents*) const OVERRIDE;
+ // Parses the specified string for this InputType, and returns true if it
+ // is successfully parsed. An instance pointed by the DateComponents*
+ // parameter will have parsed values and be modified even if the parsing
+ // fails. The DateComponents* parameter may be 0.
+ bool parseToDateComponents(const String&, DateComponents*) const;
virtual String sanitizeValue(const String&) const OVERRIDE;
virtual String serialize(const Decimal&) const OVERRIDE;
String serializeWithComponents(const DateComponents&) const;
@@ -55,7 +59,7 @@ private:
virtual double valueAsDate() const OVERRIDE;
virtual void setValueAsDate(double, ExceptionState&) const OVERRIDE;
virtual double valueAsDouble() const OVERRIDE;
- virtual void setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionState&) const OVERRIDE;
+ virtual void setValueAsDouble(double, TextFieldEventBehavior, ExceptionState&) const OVERRIDE;
virtual bool typeMismatchFor(const String&) const OVERRIDE;
virtual bool typeMismatch() const OVERRIDE;
virtual bool valueMissing(const String&) const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
index 3fbe6236e7b..4f8b9eb59ce 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
@@ -32,10 +32,10 @@
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/CSSValueKeywords.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/KeyboardEvent.h"
+#include "core/events/ScopedEventQueue.h"
#include "core/html/HTMLDataListElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLOptionElement.h"
@@ -46,6 +46,7 @@
#include "core/page/Page.h"
#include "core/rendering/RenderTheme.h"
#include "platform/DateComponents.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/DateTimeFormat.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/DateMath.h"
@@ -158,9 +159,12 @@ void BaseMultipleFieldsDateAndTimeInputType::didBlurFromControl()
if (containsFocusedShadowElement())
return;
- RefPtr<HTMLInputElement> protector(element());
+ EventQueueScope scope;
+ RefPtrWillBeRawPtr<HTMLInputElement> protector(element());
// Remove focus ring by CSS "focus" pseudo class.
element().setFocus(false);
+ if (SpinButtonElement *spinButton = spinButtonElement())
+ spinButton->releaseCapture();
}
void BaseMultipleFieldsDateAndTimeInputType::didFocusOnControl()
@@ -177,7 +181,7 @@ void BaseMultipleFieldsDateAndTimeInputType::didFocusOnControl()
void BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged()
{
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
String oldValue = input->value();
String newValue = sanitizeValue(dateTimeEditElement()->value());
// Even if oldValue is null and newValue is "", we should assume they are same.
@@ -185,9 +189,8 @@ void BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged()
input->setNeedsValidityCheck();
} else {
input->setValueInternal(newValue, DispatchNoEvent);
- input->setNeedsStyleRecalc();
+ input->setNeedsStyleRecalc(SubtreeStyleChange);
input->dispatchFormControlInputEvent();
- input->dispatchFormControlChangeEvent();
}
input->notifyFormStateChanged();
input->updateClearButtonVisibility();
@@ -240,6 +243,12 @@ void BaseMultipleFieldsDateAndTimeInputType::spinButtonStepUp()
edit->stepUp();
}
+void BaseMultipleFieldsDateAndTimeInputType::spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch eventDispatch)
+{
+ if (eventDispatch == SpinButtonElement::EventDispatchAllowed)
+ element().dispatchFormControlChangeEvent();
+}
+
bool BaseMultipleFieldsDateAndTimeInputType::isPickerIndicatorOwnerDisabledOrReadOnly() const
{
return element().isDisabledOrReadOnly();
@@ -259,6 +268,7 @@ void BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorChooseValue(const St
unsigned end;
if (date.parseDate(value, 0, end) && end == value.length())
edit->setOnlyYearMonthDay(date);
+ element().dispatchFormControlChangeEvent();
}
void BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorChooseValue(double value)
@@ -285,6 +295,7 @@ BaseMultipleFieldsDateAndTimeInputType::BaseMultipleFieldsDateAndTimeInputType(H
BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType()
{
+#if !ENABLE(OILPAN)
if (SpinButtonElement* element = spinButtonElement())
element->removeSpinButtonOwner();
if (ClearButtonElement* element = clearButtonElement())
@@ -293,6 +304,7 @@ BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType(
element->removeEditControlOwner();
if (PickerIndicatorElement* element = pickerIndicatorElement())
element->removePickerIndicatorOwner();
+#endif
}
String BaseMultipleFieldsDateAndTimeInputType::badInputText() const
@@ -339,22 +351,15 @@ void BaseMultipleFieldsDateAndTimeInputType::createShadowSubtree()
ContainerNode* container = element().userAgentShadowRoot();
container->appendChild(DateTimeEditElement::create(document, *this));
- updateView();
+ element().updateView();
container->appendChild(ClearButtonElement::create(document, *this));
container->appendChild(SpinButtonElement::create(document, *this));
- bool shouldAddPickerIndicator = false;
- if (InputType::themeSupportsDataListUI(this))
- shouldAddPickerIndicator = true;
- if (RenderTheme::theme().supportsCalendarPicker(formControlType())) {
- shouldAddPickerIndicator = true;
+ if (RenderTheme::theme().supportsCalendarPicker(formControlType()))
m_pickerIndicatorIsAlwaysVisible = true;
- }
- if (shouldAddPickerIndicator) {
- container->appendChild(PickerIndicatorElement::create(document, *this));
- m_pickerIndicatorIsVisible = true;
- updatePickerIndicatorVisibility();
- }
+ container->appendChild(PickerIndicatorElement::create(document, *this));
+ m_pickerIndicatorIsVisible = true;
+ updatePickerIndicatorVisibility();
}
void BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree()
@@ -379,15 +384,15 @@ void BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree()
m_isDestroyingShadowSubtree = false;
}
-void BaseMultipleFieldsDateAndTimeInputType::handleFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void BaseMultipleFieldsDateAndTimeInputType::handleFocusEvent(Element* oldFocusedElement, FocusType type)
{
DateTimeEditElement* edit = dateTimeEditElement();
if (!edit || m_isDestroyingShadowSubtree)
return;
- if (direction == FocusDirectionBackward) {
+ if (type == FocusTypeBackward) {
if (element().document().page())
- element().document().page()->focusController().advanceFocus(direction);
- } else if (direction == FocusDirectionNone || direction == FocusDirectionMouse || direction == FocusDirectionPage) {
+ element().document().page()->focusController().advanceFocus(type);
+ } else if (type == FocusTypeNone || type == FocusTypeMouse || type == FocusTypePage) {
edit->focusByOwner(oldFocusedElement);
} else {
edit->focusByOwner();
@@ -443,6 +448,11 @@ AtomicString BaseMultipleFieldsDateAndTimeInputType::localeIdentifier() const
return element().computeInheritedLanguage();
}
+void BaseMultipleFieldsDateAndTimeInputType::editControlDidChangeValueByKeyboard()
+{
+ element().dispatchFormControlChangeEvent();
+}
+
void BaseMultipleFieldsDateAndTimeInputType::minOrMaxAttributeChanged()
{
updateView();
@@ -479,7 +489,7 @@ void BaseMultipleFieldsDateAndTimeInputType::setValue(const String& sanitizedVal
InputType::setValue(sanitizedValue, valueChanged, eventBehavior);
DateTimeEditElement* edit = dateTimeEditElement();
if (valueChanged || (sanitizedValue.isEmpty() && edit && edit->anyEditableFieldsHaveValues())) {
- updateView();
+ element().updateView();
element().setNeedsValidityCheck();
}
}
@@ -503,12 +513,18 @@ void BaseMultipleFieldsDateAndTimeInputType::updateView()
DateTimeEditElement::LayoutParameters layoutParameters(element().locale(), createStepRange(AnyIsDefaultStep));
DateComponents date;
- const bool hasValue = parseToDateComponents(element().value(), &date);
+ bool hasValue = false;
+ if (!element().suggestedValue().isNull())
+ hasValue = parseToDateComponents(element().suggestedValue(), &date);
+ else
+ hasValue = parseToDateComponents(element().value(), &date);
if (!hasValue)
setMillisecondToDateComponents(layoutParameters.stepRange.minimum().toDouble(), &date);
setupLayoutParameters(layoutParameters, date);
+ DEFINE_STATIC_LOCAL(AtomicString, datetimeformatAttr, ("datetimeformat", AtomicString::ConstructFromLiteral));
+ edit->setAttribute(datetimeformatAttr, AtomicString(layoutParameters.dateTimeFormat), ASSERT_NO_EXCEPTION);
const AtomicString pattern = edit->fastGetAttribute(HTMLNames::patternAttr);
if (!pattern.isEmpty())
layoutParameters.dateTimeFormat = pattern;
@@ -540,12 +556,10 @@ void BaseMultipleFieldsDateAndTimeInputType::updatePickerIndicatorVisibility()
showPickerIndicator();
return;
}
- if (RuntimeEnabledFeatures::dataListElementEnabled()) {
- if (element().hasValidDataListOptions())
- showPickerIndicator();
- else
- hidePickerIndicator();
- }
+ if (element().hasValidDataListOptions())
+ showPickerIndicator();
+ else
+ hidePickerIndicator();
}
void BaseMultipleFieldsDateAndTimeInputType::hidePickerIndicator()
@@ -586,7 +600,7 @@ bool BaseMultipleFieldsDateAndTimeInputType::shouldClearButtonRespondToMouseEven
void BaseMultipleFieldsDateAndTimeInputType::clearValue()
{
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
input->setValue("", DispatchInputAndChangeEvent);
input->updateClearButtonVisibility();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h
index 14a0a2c8171..4867175784d 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h
@@ -49,6 +49,8 @@ class BaseMultipleFieldsDateAndTimeInputType
, protected PickerIndicatorElement::PickerIndicatorOwner
, protected SpinButtonElement::SpinButtonOwner
, protected ClearButtonElement::ClearButtonOwner {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(BaseMultipleFieldsDateAndTimeInputType);
+
public:
virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const = 0;
@@ -67,6 +69,7 @@ private:
virtual bool isEditControlOwnerDisabled() const OVERRIDE FINAL;
virtual bool isEditControlOwnerReadOnly() const OVERRIDE FINAL;
virtual AtomicString localeIdentifier() const OVERRIDE FINAL;
+ virtual void editControlDidChangeValueByKeyboard() OVERRIDE FINAL;
// SpinButtonElement::SpinButtonOwner functions.
virtual void focusAndSelectSpinButtonOwner() OVERRIDE;
@@ -74,6 +77,7 @@ private:
virtual bool shouldSpinButtonRespondToWheelEvents() OVERRIDE;
virtual void spinButtonStepDown() OVERRIDE;
virtual void spinButtonStepUp() OVERRIDE;
+ virtual void spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch) OVERRIDE;
// PickerIndicatorElement::PickerIndicatorOwner functions
virtual bool isPickerIndicatorOwnerDisabledOrReadOnly() const OVERRIDE FINAL;
@@ -94,7 +98,7 @@ private:
virtual void destroyShadowSubtree() OVERRIDE FINAL;
virtual void disabledAttributeChanged() OVERRIDE FINAL;
virtual void forwardEvent(Event*) OVERRIDE FINAL;
- virtual void handleFocusEvent(Element* oldFocusedElement, FocusDirection) OVERRIDE;
+ virtual void handleFocusEvent(Element* oldFocusedElement, FocusType) OVERRIDE;
virtual void handleKeydownEvent(KeyboardEvent*) OVERRIDE FINAL;
virtual bool hasBadInput() const OVERRIDE;
virtual bool hasCustomFocusLogic() const OVERRIDE FINAL;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp
index d00d21e98cb..cc531a12091 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.cpp
@@ -24,8 +24,8 @@
#include "config.h"
#include "core/html/forms/BaseTextInputType.h"
-#include "HTMLNames.h"
#include "bindings/v8/ScriptRegexp.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLInputElement.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h
index 8c917a0b616..c2743688571 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/BaseTextInputType.h
@@ -42,9 +42,9 @@ protected:
BaseTextInputType(HTMLInputElement& element) : TextFieldInputType(element) { }
private:
- virtual bool isTextType() const OVERRIDE;
- virtual bool patternMismatch(const String&) const OVERRIDE;
- virtual bool supportsPlaceholder() const OVERRIDE;
+ virtual bool isTextType() const OVERRIDE FINAL;
+ virtual bool patternMismatch(const String&) const OVERRIDE FINAL;
+ virtual bool supportsPlaceholder() const OVERRIDE FINAL;
virtual bool supportsSelectionAPI() const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp
index 39e112c03fe..7ecf1cbf1d4 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.cpp
@@ -31,14 +31,14 @@
#include "config.h"
#include "core/html/forms/ButtonInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
-PassRefPtr<InputType> ButtonInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> ButtonInputType::create(HTMLInputElement& element)
{
- return adoptRef(new ButtonInputType(element));
+ return adoptRefWillBeNoop(new ButtonInputType(element));
}
const AtomicString& ButtonInputType::formControlType() const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h
index aa31135602b..5b187710d3a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ButtonInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class ButtonInputType : public BaseButtonInputType {
+class ButtonInputType FINAL : public BaseButtonInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
ButtonInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp
index 738f9d58b9b..9a77643e431 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/CheckboxInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/html/HTMLInputElement.h"
#include "platform/text/PlatformLocale.h"
@@ -40,9 +40,9 @@
namespace WebCore {
-PassRefPtr<InputType> CheckboxInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> CheckboxInputType::create(HTMLInputElement& element)
{
- return adoptRef(new CheckboxInputType(element));
+ return adoptRefWillBeNoop(new CheckboxInputType(element));
}
const AtomicString& CheckboxInputType::formControlType() const
@@ -68,12 +68,12 @@ void CheckboxInputType::handleKeyupEvent(KeyboardEvent* event)
dispatchSimulatedClickIfActive(event);
}
-PassOwnPtr<ClickHandlingState> CheckboxInputType::willDispatchClick()
+PassOwnPtrWillBeRawPtr<ClickHandlingState> CheckboxInputType::willDispatchClick()
{
// An event handler can use preventDefault or "return false" to reverse the checking we do here.
// The ClickHandlingState object contains what we need to undo what we did here in didDispatchClick.
- OwnPtr<ClickHandlingState> state = adoptPtr(new ClickHandlingState);
+ OwnPtrWillBeRawPtr<ClickHandlingState> state = adoptPtrWillBeNoop(new ClickHandlingState);
state->checked = element().checked();
state->indeterminate = element().indeterminate();
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h
index 9299018f6b5..06e4c516750 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/CheckboxInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class CheckboxInputType : public BaseCheckableInputType {
+class CheckboxInputType FINAL : public BaseCheckableInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
CheckboxInputType(HTMLInputElement& element) : BaseCheckableInputType(element) { }
@@ -45,7 +45,7 @@ private:
virtual bool valueMissing(const String&) const OVERRIDE;
virtual String valueMissingText() const OVERRIDE;
virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
- virtual PassOwnPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
+ virtual PassOwnPtrWillBeRawPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
virtual void didDispatchClick(Event*, const ClickHandlingState&) OVERRIDE;
virtual bool isCheckbox() const OVERRIDE;
virtual bool supportsIndeterminateAppearance() const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.cpp b/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.cpp
deleted file mode 100644
index 58850fb8e11..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/html/forms/CheckedRadioButtons.h"
-
-#include "core/html/HTMLInputElement.h"
-#include "wtf/HashSet.h"
-
-namespace WebCore {
-
-class RadioButtonGroup {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassOwnPtr<RadioButtonGroup> create();
- bool isEmpty() const { return m_members.isEmpty(); }
- bool isRequired() const { return m_requiredCount; }
- HTMLInputElement* checkedButton() const { return m_checkedButton; }
- void add(HTMLInputElement*);
- void updateCheckedState(HTMLInputElement*);
- void requiredAttributeChanged(HTMLInputElement*);
- void remove(HTMLInputElement*);
- bool contains(HTMLInputElement*) const;
-
-private:
- RadioButtonGroup();
- void setNeedsValidityCheckForAllButtons();
- bool isValid() const;
- void setCheckedButton(HTMLInputElement*);
-
- HashSet<HTMLInputElement*> m_members;
- HTMLInputElement* m_checkedButton;
- size_t m_requiredCount;
-};
-
-RadioButtonGroup::RadioButtonGroup()
- : m_checkedButton(0)
- , m_requiredCount(0)
-{
-}
-
-PassOwnPtr<RadioButtonGroup> RadioButtonGroup::create()
-{
- return adoptPtr(new RadioButtonGroup);
-}
-
-inline bool RadioButtonGroup::isValid() const
-{
- return !isRequired() || m_checkedButton;
-}
-
-void RadioButtonGroup::setCheckedButton(HTMLInputElement* button)
-{
- HTMLInputElement* oldCheckedButton = m_checkedButton;
- if (oldCheckedButton == button)
- return;
- m_checkedButton = button;
- if (oldCheckedButton)
- oldCheckedButton->setChecked(false);
-}
-
-void RadioButtonGroup::add(HTMLInputElement* button)
-{
- ASSERT(button->isRadioButton());
- if (!m_members.add(button).isNewEntry)
- return;
- bool groupWasValid = isValid();
- if (button->isRequired())
- ++m_requiredCount;
- if (button->checked())
- setCheckedButton(button);
-
- bool groupIsValid = isValid();
- if (groupWasValid != groupIsValid) {
- setNeedsValidityCheckForAllButtons();
- } else if (!groupIsValid) {
- // A radio button not in a group is always valid. We need to make it
- // invalid only if the group is invalid.
- button->setNeedsValidityCheck();
- }
-}
-
-void RadioButtonGroup::updateCheckedState(HTMLInputElement* button)
-{
- ASSERT(button->isRadioButton());
- ASSERT(m_members.contains(button));
- bool wasValid = isValid();
- if (button->checked()) {
- setCheckedButton(button);
- } else {
- if (m_checkedButton == button)
- m_checkedButton = 0;
- }
- if (wasValid != isValid())
- setNeedsValidityCheckForAllButtons();
-}
-
-void RadioButtonGroup::requiredAttributeChanged(HTMLInputElement* button)
-{
- ASSERT(button->isRadioButton());
- ASSERT(m_members.contains(button));
- bool wasValid = isValid();
- if (button->isRequired()) {
- ++m_requiredCount;
- } else {
- ASSERT(m_requiredCount);
- --m_requiredCount;
- }
- if (wasValid != isValid())
- setNeedsValidityCheckForAllButtons();
-}
-
-void RadioButtonGroup::remove(HTMLInputElement* button)
-{
- ASSERT(button->isRadioButton());
- HashSet<HTMLInputElement*>::iterator it = m_members.find(button);
- if (it == m_members.end())
- return;
- bool wasValid = isValid();
- m_members.remove(it);
- if (button->isRequired()) {
- ASSERT(m_requiredCount);
- --m_requiredCount;
- }
- if (m_checkedButton == button)
- m_checkedButton = 0;
-
- if (m_members.isEmpty()) {
- ASSERT(!m_requiredCount);
- ASSERT(!m_checkedButton);
- } else if (wasValid != isValid()) {
- setNeedsValidityCheckForAllButtons();
- }
- if (!wasValid) {
- // A radio button not in a group is always valid. We need to make it
- // valid only if the group was invalid.
- button->setNeedsValidityCheck();
- }
-}
-
-void RadioButtonGroup::setNeedsValidityCheckForAllButtons()
-{
- typedef HashSet<HTMLInputElement*>::const_iterator Iterator;
- Iterator end = m_members.end();
- for (Iterator it = m_members.begin(); it != end; ++it) {
- HTMLInputElement* button = *it;
- ASSERT(button->isRadioButton());
- button->setNeedsValidityCheck();
- }
-}
-
-bool RadioButtonGroup::contains(HTMLInputElement* button) const
-{
- return m_members.contains(button);
-}
-
-// ----------------------------------------------------------------
-
-// Explicity define empty constructor and destructor in order to prevent the
-// compiler from generating them as inlines. So we don't need to to define
-// RadioButtonGroup in the header.
-CheckedRadioButtons::CheckedRadioButtons()
-{
-}
-
-CheckedRadioButtons::~CheckedRadioButtons()
-{
-}
-
-void CheckedRadioButtons::addButton(HTMLInputElement* element)
-{
- ASSERT(element->isRadioButton());
- if (element->name().isEmpty())
- return;
-
- if (!m_nameToGroupMap)
- m_nameToGroupMap = adoptPtr(new NameToGroupMap);
-
- OwnPtr<RadioButtonGroup>& group = m_nameToGroupMap->add(element->name().impl(), PassOwnPtr<RadioButtonGroup>()).iterator->value;
- if (!group)
- group = RadioButtonGroup::create();
- group->add(element);
-}
-
-void CheckedRadioButtons::updateCheckedState(HTMLInputElement* element)
-{
- ASSERT(element->isRadioButton());
- if (element->name().isEmpty())
- return;
- ASSERT(m_nameToGroupMap);
- if (!m_nameToGroupMap)
- return;
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
- ASSERT(group);
- group->updateCheckedState(element);
-}
-
-void CheckedRadioButtons::requiredAttributeChanged(HTMLInputElement* element)
-{
- ASSERT(element->isRadioButton());
- if (element->name().isEmpty())
- return;
- ASSERT(m_nameToGroupMap);
- if (!m_nameToGroupMap)
- return;
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
- ASSERT(group);
- group->requiredAttributeChanged(element);
-}
-
-HTMLInputElement* CheckedRadioButtons::checkedButtonForGroup(const AtomicString& name) const
-{
- if (!m_nameToGroupMap)
- return 0;
- RadioButtonGroup* group = m_nameToGroupMap->get(name.impl());
- return group ? group->checkedButton() : 0;
-}
-
-bool CheckedRadioButtons::isInRequiredGroup(HTMLInputElement* element) const
-{
- ASSERT(element->isRadioButton());
- if (element->name().isEmpty())
- return false;
- if (!m_nameToGroupMap)
- return false;
- RadioButtonGroup* group = m_nameToGroupMap->get(element->name().impl());
- return group && group->isRequired() && group->contains(element);
-}
-
-void CheckedRadioButtons::removeButton(HTMLInputElement* element)
-{
- ASSERT(element->isRadioButton());
- if (element->name().isEmpty())
- return;
- if (!m_nameToGroupMap)
- return;
-
- NameToGroupMap::iterator it = m_nameToGroupMap->find(element->name().impl());
- if (it == m_nameToGroupMap->end())
- return;
- it->value->remove(element);
- if (it->value->isEmpty()) {
- // FIXME: We may skip deallocating the empty RadioButtonGroup for
- // performance improvement. If we do so, we need to change the key type
- // of m_nameToGroupMap from StringImpl* to AtomicString.
- m_nameToGroupMap->remove(it);
- if (m_nameToGroupMap->isEmpty())
- m_nameToGroupMap.clear();
- }
-}
-
-} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.h b/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.h
deleted file mode 100644
index 6a1585bd5aa..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/forms/CheckedRadioButtons.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef CheckedRadioButtons_h
-#define CheckedRadioButtons_h
-
-#include "wtf/Forward.h"
-#include "wtf/HashMap.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/text/StringHash.h"
-
-namespace WebCore {
-
-class HTMLInputElement;
-class RadioButtonGroup;
-
-// FIXME: Rename the class. The class was a simple map from a name to a checked
-// radio button. It manages RadioButtonGroup objects now.
-class CheckedRadioButtons {
-public:
- CheckedRadioButtons();
- ~CheckedRadioButtons();
- void addButton(HTMLInputElement*);
- void updateCheckedState(HTMLInputElement*);
- void requiredAttributeChanged(HTMLInputElement*);
- void removeButton(HTMLInputElement*);
- HTMLInputElement* checkedButtonForGroup(const AtomicString& groupName) const;
- bool isInRequiredGroup(HTMLInputElement*) const;
-
-private:
- typedef HashMap<StringImpl*, OwnPtr<RadioButtonGroup> > NameToGroupMap;
- OwnPtr<NameToGroupMap> m_nameToGroupMap;
-};
-
-} // namespace WebCore
-
-#endif // CheckedRadioButtons_h
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp
index 304504bdfc3..ae4bd2d7677 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.cpp
@@ -31,11 +31,10 @@
#include "config.h"
#include "core/html/forms/ColorInputType.h"
-#include "CSSPropertyNames.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptController.h"
+#include "core/CSSPropertyNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/MouseEvent.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLDataListElement.h"
@@ -44,6 +43,8 @@
#include "core/html/HTMLOptionElement.h"
#include "core/page/Chrome.h"
#include "core/rendering/RenderView.h"
+#include "platform/ColorChooser.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/UserGestureIndicator.h"
#include "platform/graphics/Color.h"
#include "wtf/PassOwnPtr.h"
@@ -68,13 +69,13 @@ static bool isValidColorString(const String& value)
// We don't accept #rgb and #aarrggbb formats.
if (value.length() != 7)
return false;
- Color color(value);
- return color.isValid() && !color.hasAlpha();
+ Color color;
+ return color.setFromString(value) && !color.hasAlpha();
}
-PassRefPtr<InputType> ColorInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> ColorInputType::create(HTMLInputElement& element)
{
- return adoptRef(new ColorInputType(element));
+ return adoptRefWillBeNoop(new ColorInputType(element));
}
ColorInputType::~ColorInputType()
@@ -117,7 +118,10 @@ String ColorInputType::sanitizeValue(const String& proposedValue) const
Color ColorInputType::valueAsColor() const
{
- return Color(element().value());
+ Color color;
+ bool success = color.setFromString(element().value());
+ ASSERT_UNUSED(success, success);
+ return color;
}
void ColorInputType::createShadowSubtree()
@@ -125,14 +129,14 @@ void ColorInputType::createShadowSubtree()
ASSERT(element().shadow());
Document& document = element().document();
- RefPtr<HTMLDivElement> wrapperElement = HTMLDivElement::create(document);
- wrapperElement->setPseudo(AtomicString("-webkit-color-swatch-wrapper", AtomicString::ConstructFromLiteral));
- RefPtr<HTMLDivElement> colorSwatch = HTMLDivElement::create(document);
- colorSwatch->setPseudo(AtomicString("-webkit-color-swatch", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<HTMLDivElement> wrapperElement = HTMLDivElement::create(document);
+ wrapperElement->setShadowPseudoId(AtomicString("-webkit-color-swatch-wrapper", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<HTMLDivElement> colorSwatch = HTMLDivElement::create(document);
+ colorSwatch->setShadowPseudoId(AtomicString("-webkit-color-swatch", AtomicString::ConstructFromLiteral));
wrapperElement->appendChild(colorSwatch.release());
element().userAgentShadowRoot()->appendChild(wrapperElement.release());
- updateColorSwatch();
+ element().updateView();
}
void ColorInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior)
@@ -142,7 +146,7 @@ void ColorInputType::setValue(const String& value, bool valueChanged, TextFieldE
if (!valueChanged)
return;
- updateColorSwatch();
+ element().updateView();
if (m_chooser)
m_chooser->setSelectedColor(valueAsColor());
}
@@ -157,7 +161,7 @@ void ColorInputType::handleDOMActivateEvent(Event* event)
Chrome* chrome = this->chrome();
if (chrome && !m_chooser)
- m_chooser = chrome->createColorChooser(this, valueAsColor());
+ m_chooser = chrome->createColorChooser(element().document().frame(), this, valueAsColor());
event->setDefaultHandled();
}
@@ -169,7 +173,7 @@ void ColorInputType::closePopupView()
bool ColorInputType::shouldRespectListAttribute()
{
- return InputType::themeSupportsDataListUI(this);
+ return true;
}
bool ColorInputType::typeMismatchFor(const String& value) const
@@ -182,7 +186,7 @@ void ColorInputType::didChooseColor(const Color& color)
if (element().isDisabledFormControl() || color == valueAsColor())
return;
element().setValueFromRenderer(color.serialized());
- updateColorSwatch();
+ element().updateView();
element().dispatchFormControlChangeEvent();
}
@@ -197,7 +201,7 @@ void ColorInputType::endColorChooser()
m_chooser->endChooser();
}
-void ColorInputType::updateColorSwatch()
+void ColorInputType::updateView()
{
HTMLElement* colorSwatch = shadowColorSwatch();
if (!colorSwatch)
@@ -224,30 +228,25 @@ Color ColorInputType::currentColor()
bool ColorInputType::shouldShowSuggestions() const
{
- if (RuntimeEnabledFeatures::dataListElementEnabled())
- return element().fastHasAttribute(listAttr);
-
- return false;
+ return element().fastHasAttribute(listAttr);
}
Vector<ColorSuggestion> ColorInputType::suggestions() const
{
Vector<ColorSuggestion> suggestions;
- if (RuntimeEnabledFeatures::dataListElementEnabled()) {
- HTMLDataListElement* dataList = element().dataList();
- if (dataList) {
- RefPtr<HTMLCollection> options = dataList->options();
- for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); i++) {
- if (!element().isValidValue(option->value()))
- continue;
- Color color(option->value());
- if (!color.isValid())
- continue;
- ColorSuggestion suggestion(color, option->label().left(maxSuggestionLabelLength));
- suggestions.append(suggestion);
- if (suggestions.size() >= maxSuggestions)
- break;
- }
+ HTMLDataListElement* dataList = element().dataList();
+ if (dataList) {
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
+ for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); i++) {
+ if (!element().isValidValue(option->value()))
+ continue;
+ Color color;
+ if (!color.setFromString(option->value()))
+ continue;
+ ColorSuggestion suggestion(color, option->label().left(maxSuggestionLabelLength));
+ suggestions.append(suggestion);
+ if (suggestions.size() >= maxSuggestions)
+ break;
}
}
return suggestions;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h
index b0f7ba3d02b..366451bddd2 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ColorInputType.h
@@ -36,9 +36,11 @@
namespace WebCore {
-class ColorInputType : public BaseClickableWithKeyInputType, public ColorChooserClient {
+class ColorChooser;
+
+class ColorInputType FINAL : public BaseClickableWithKeyInputType, public ColorChooserClient {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
virtual ~ColorInputType();
// ColorChooserClient implementation.
@@ -63,10 +65,10 @@ private:
virtual void closePopupView() OVERRIDE;
virtual bool shouldRespectListAttribute() OVERRIDE;
virtual bool typeMismatchFor(const String&) const OVERRIDE;
+ virtual void updateView() OVERRIDE;
Color valueAsColor() const;
void endColorChooser();
- void updateColorSwatch();
HTMLElement* shadowColorSwatch() const;
OwnPtr<ColorChooser> m_chooser;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp
index a820bc8f97b..6f3cbef7a8e 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/html/forms/DateInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -53,9 +53,9 @@ inline DateInputType::DateInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> DateInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> DateInputType::create(HTMLInputElement& element)
{
- return adoptRef(new DateInputType(element));
+ return adoptRefWillBeNoop(new DateInputType(element));
}
void DateInputType::countUsage()
@@ -72,7 +72,7 @@ StepRange DateInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateDefaultStep, dateDefaultStepBase, dateStepScaleFactor, StepRange::ParsedStepValueShouldBeInteger));
- return InputType::createStepRange(anyStepHandling, 0, Decimal::fromDouble(DateComponents::minimumDate()), Decimal::fromDouble(DateComponents::maximumDate()), stepDescription);
+ return InputType::createStepRange(anyStepHandling, dateDefaultStepBase, Decimal::fromDouble(DateComponents::minimumDate()), Decimal::fromDouble(DateComponents::maximumDate()), stepDescription);
}
bool DateInputType::parseToDateComponentsInternal(const String& string, DateComponents* out) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h
index 2688adf1d93..1583a2b46c5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/DateInputType.h
@@ -44,9 +44,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseDateInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseDateInputType;
#endif
-class DateInputType : public BaseDateInputType {
+class DateInputType FINAL : public BaseDateInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
DateInputType(HTMLInputElement&);
@@ -61,7 +61,7 @@ private:
// BaseMultipleFieldsDateAndTimeInputType functions
virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE;
virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE;
- virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const;
+ virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp
index 60c162dc247..76c733f43c2 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "core/html/forms/DateTimeLocalInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -50,9 +50,9 @@ static const int dateTimeLocalDefaultStep = 60;
static const int dateTimeLocalDefaultStepBase = 0;
static const int dateTimeLocalStepScaleFactor = 1000;
-PassRefPtr<InputType> DateTimeLocalInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> DateTimeLocalInputType::create(HTMLInputElement& element)
{
- return adoptRef(new DateTimeLocalInputType(element));
+ return adoptRefWillBeNoop(new DateTimeLocalInputType(element));
}
void DateTimeLocalInputType::countUsage()
@@ -81,7 +81,7 @@ StepRange DateTimeLocalInputType::createStepRange(AnyStepHandling anyStepHandlin
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (dateTimeLocalDefaultStep, dateTimeLocalDefaultStepBase, dateTimeLocalStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
- return InputType::createStepRange(anyStepHandling, 0, Decimal::fromDouble(DateComponents::minimumDateTime()), Decimal::fromDouble(DateComponents::maximumDateTime()), stepDescription);
+ return InputType::createStepRange(anyStepHandling, dateTimeLocalDefaultStepBase, Decimal::fromDouble(DateComponents::minimumDateTime()), Decimal::fromDouble(DateComponents::maximumDateTime()), stepDescription);
}
bool DateTimeLocalInputType::parseToDateComponentsInternal(const String& string, DateComponents* out) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h
index ade5ac0f8e4..8fb2f5e637b 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/DateTimeLocalInputType.h
@@ -44,9 +44,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseDateTimeLocalInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseDateTimeLocalInputType;
#endif
-class DateTimeLocalInputType : public BaseDateTimeLocalInputType {
+class DateTimeLocalInputType FINAL : public BaseDateTimeLocalInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
DateTimeLocalInputType(HTMLInputElement& element) : BaseDateTimeLocalInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp
index 20db60bf5f2..727bdb478e4 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.cpp
@@ -24,8 +24,8 @@
#include "config.h"
#include "core/html/forms/EmailInputType.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ScriptRegexp.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/page/Chrome.h"
@@ -34,7 +34,8 @@
#include "public/platform/Platform.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/StringBuilder.h"
-#include <unicode/uidna.h>
+#include <unicode/idna.h>
+#include <unicode/unistr.h>
namespace WebCore {
@@ -45,11 +46,13 @@ static const char localPartCharacters[] = "abcdefghijklmnopqrstuvwxyz0123456789!
static const char emailPattern[] =
"[a-z0-9!#$%&'*+/=?^_`{|}~.-]+" // local part
"@"
- "[a-z0-9-]+(\\.[a-z0-9-]+)*"; // domain part
+ "[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?" // domain part
+ "(?:\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*";
// RFC5321 says the maximum total length of a domain name is 255 octets.
-static const size_t maximumDomainNameLength = 255;
-static const int32_t idnaConversionOption = UIDNA_ALLOW_UNASSIGNED;
+static const int32_t maximumDomainNameLength = 255;
+// Use the same option as in url/url_canon_icu.cc
+static const int32_t idnaConversionOption = UIDNA_CHECK_BIDI;
static String convertEmailAddressToASCII(const String& address)
{
@@ -60,15 +63,24 @@ static String convertEmailAddressToASCII(const String& address)
if (atPosition == kNotFound)
return address;
- UErrorCode error = U_ZERO_ERROR;
- UChar domainNameBuffer[maximumDomainNameLength];
- int32_t domainNameLength = uidna_IDNToASCII(address.charactersWithNullTermination().data() + atPosition + 1, address.length() - atPosition - 1, domainNameBuffer, WTF_ARRAY_LENGTH(domainNameBuffer), idnaConversionOption, 0, &error);
- if (error != U_ZERO_ERROR || domainNameLength <= 0)
+ // UnicodeString ctor for copy-on-write does not work reliably (in debug
+ // build.) TODO(jshin): In an unlikely case this is a perf-issue, treat
+ // 8bit and non-8bit strings separately.
+ icu::UnicodeString idnDomainName(address.charactersWithNullTermination().data() + atPosition + 1, address.length() - atPosition - 1);
+ icu::UnicodeString domainName;
+
+ // Leak |idna| at the end.
+ UErrorCode errorCode = U_ZERO_ERROR;
+ static icu::IDNA *idna = icu::IDNA::createUTS46Instance(idnaConversionOption, errorCode);
+ ASSERT(idna);
+ icu::IDNAInfo idnaInfo;
+ idna->nameToASCII(idnDomainName, domainName, idnaInfo, errorCode);
+ if (U_FAILURE(errorCode) || idnaInfo.hasErrors() || domainName.length() > maximumDomainNameLength)
return address;
StringBuilder builder;
builder.append(address, 0, atPosition + 1);
- builder.append(domainNameBuffer, domainNameLength);
+ builder.append(domainName.getBuffer(), domainName.length());
return builder.toString();
}
@@ -133,9 +145,9 @@ static bool isValidEmailAddress(const String& address)
return !matchOffset && matchLength == addressLength;
}
-PassRefPtr<InputType> EmailInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> EmailInputType::create(HTMLInputElement& element)
{
- return adoptRef(new EmailInputType(element));
+ return adoptRefWillBeNoop(new EmailInputType(element));
}
void EmailInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h
index 82bd153a780..230586f9d47 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/EmailInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class EmailInputType : public BaseTextInputType {
+class EmailInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
EmailInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
index 64338a6849d..f63368f318d 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.cpp
@@ -22,10 +22,9 @@
#include "config.h"
#include "core/html/forms/FileInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/Event.h"
#include "core/fileapi/File.h"
@@ -37,6 +36,7 @@
#include "core/page/DragData.h"
#include "core/rendering/RenderFileUploadControl.h"
#include "platform/FileMetadata.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/UserGestureIndicator.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/PassOwnPtr.h"
@@ -54,9 +54,15 @@ inline FileInputType::FileInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> FileInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> FileInputType::create(HTMLInputElement& element)
{
- return adoptRef(new FileInputType(element));
+ return adoptRefWillBeNoop(new FileInputType(element));
+}
+
+void FileInputType::trace(Visitor* visitor)
+{
+ visitor->trace(m_fileList);
+ BaseClickableWithKeyInputType::trace(visitor);
}
Vector<FileChooserFileInfo> FileInputType::filesFromFormControlState(const FormControlState& state)
@@ -146,13 +152,13 @@ void FileInputType::handleDOMActivateEvent(Event* event)
if (Chrome* chrome = this->chrome()) {
FileChooserSettings settings;
HTMLInputElement& input = element();
- settings.allowsDirectoryUpload = RuntimeEnabledFeatures::directoryUploadEnabled() && input.fastHasAttribute(webkitdirectoryAttr);
+ settings.allowsDirectoryUpload = input.fastHasAttribute(webkitdirectoryAttr);
settings.allowsMultipleFiles = settings.allowsDirectoryUpload || input.fastHasAttribute(multipleAttr);
settings.acceptMIMETypes = input.acceptMIMETypes();
settings.acceptFileExtensions = input.acceptFileExtensions();
settings.selectedFiles = m_fileList->paths();
#if ENABLE(MEDIA_CAPTURE)
- settings.useMediaCapture = input.capture();
+ settings.useMediaCapture = input.isFileUpload() && input.fastHasAttribute(captureAttr);
#endif
chrome->runOpenPanel(input.document().frame(), newFileChooser(settings));
}
@@ -200,21 +206,25 @@ bool FileInputType::getTypeSpecificValue(String& value)
return true;
}
-void FileInputType::setValue(const String&, bool, TextFieldEventBehavior)
+void FileInputType::setValue(const String&, bool valueChanged, TextFieldEventBehavior)
{
+ if (!valueChanged)
+ return;
+
m_fileList->clear();
- element().setNeedsStyleRecalc();
+ element().setNeedsStyleRecalc(SubtreeStyleChange);
+ element().setNeedsValidityCheck();
}
-PassRefPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileInfo>& files) const
+PassRefPtrWillBeRawPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileInfo>& files) const
{
- RefPtr<FileList> fileList(FileList::create());
+ RefPtrWillBeRawPtr<FileList> fileList(FileList::create());
size_t size = files.size();
// If a directory is being selected, the UI allows a directory to be chosen
// and the paths provided here share a root directory somewhere up the tree;
// we want to store only the relative paths from that point.
- if (size && element().fastHasAttribute(webkitdirectoryAttr) && RuntimeEnabledFeatures::directoryUploadEnabled()) {
+ if (size && element().fastHasAttribute(webkitdirectoryAttr)) {
// Find the common root path.
String rootPath = directoryName(files[0].path);
for (size_t i = 1; i < size; i++) {
@@ -247,10 +257,10 @@ bool FileInputType::isFileUpload() const
void FileInputType::createShadowSubtree()
{
ASSERT(element().shadow());
- RefPtr<HTMLInputElement> button = HTMLInputElement::create(element().document(), 0, false);
+ RefPtrWillBeRawPtr<HTMLInputElement> button = HTMLInputElement::create(element().document(), 0, false);
button->setType(InputTypeNames::button);
- button->setAttribute(valueAttr, locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel));
- button->setPseudo(AtomicString("-webkit-file-upload-button", AtomicString::ConstructFromLiteral));
+ button->setAttribute(valueAttr, AtomicString(locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel)));
+ button->setShadowPseudoId(AtomicString("-webkit-file-upload-button", AtomicString::ConstructFromLiteral));
element().userAgentShadowRoot()->appendChild(button.release());
}
@@ -265,15 +275,15 @@ void FileInputType::multipleAttributeChanged()
{
ASSERT(element().shadow());
if (Element* button = toElement(element().userAgentShadowRoot()->firstChild()))
- button->setAttribute(valueAttr, locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel));
+ button->setAttribute(valueAttr, AtomicString(locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel)));
}
-void FileInputType::setFiles(PassRefPtr<FileList> files)
+void FileInputType::setFiles(PassRefPtrWillBeRawPtr<FileList> files)
{
if (!files)
return;
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
bool pathsChanged = false;
if (files->length() != m_fileList->length()) {
@@ -289,21 +299,16 @@ void FileInputType::setFiles(PassRefPtr<FileList> files)
m_fileList = files;
- input->setFormControlValueMatchesRenderer(true);
input->notifyFormStateChanged();
input->setNeedsValidityCheck();
- Vector<String> paths;
- for (unsigned i = 0; i < m_fileList->length(); ++i)
- paths.append(m_fileList->item(i)->path());
-
if (input->renderer())
- input->renderer()->repaint();
+ input->renderer()->paintInvalidationForWholeRenderer();
if (pathsChanged) {
// This call may cause destruction of this instance.
// input instance is safe since it is ref-counted.
- input->HTMLElement::dispatchChangeEvent();
+ input->dispatchChangeEvent();
}
input->setChangedSinceLastFormControlChangeEvent(false);
}
@@ -335,7 +340,7 @@ bool FileInputType::receiveDroppedFiles(const DragData* dragData)
return false;
HTMLInputElement& input = element();
- if (input.fastHasAttribute(webkitdirectoryAttr) && RuntimeEnabledFeatures::directoryUploadEnabled()) {
+ if (input.fastHasAttribute(webkitdirectoryAttr)) {
receiveDropForDirectoryUpload(paths);
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h
index a91ba75e2be..68fc3342045 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/FileInputType.h
@@ -34,6 +34,7 @@
#include "core/html/forms/BaseClickableWithKeyInputType.h"
#include "platform/FileChooser.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
@@ -41,9 +42,10 @@ namespace WebCore {
class DragData;
class FileList;
-class FileInputType : public BaseClickableWithKeyInputType, private FileChooserClient {
+class FileInputType FINAL : public BaseClickableWithKeyInputType, private FileChooserClient {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
+ virtual void trace(Visitor*) OVERRIDE;
static Vector<FileChooserFileInfo> filesFromFormControlState(const FormControlState&);
private:
@@ -58,7 +60,7 @@ private:
virtual RenderObject* createRenderer(RenderStyle*) const OVERRIDE;
virtual bool canSetStringValue() const OVERRIDE;
virtual FileList* files() OVERRIDE;
- virtual void setFiles(PassRefPtr<FileList>) OVERRIDE;
+ virtual void setFiles(PassRefPtrWillBeRawPtr<FileList>) OVERRIDE;
virtual bool canSetValue(const String&) OVERRIDE;
virtual bool getTypeSpecificValue(String&) OVERRIDE; // Checked first, before internal storage or the value attribute.
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) OVERRIDE;
@@ -73,10 +75,10 @@ private:
// FileChooserClient implementation.
virtual void filesChosen(const Vector<FileChooserFileInfo>&) OVERRIDE;
- PassRefPtr<FileList> createFileList(const Vector<FileChooserFileInfo>& files) const;
+ PassRefPtrWillBeRawPtr<FileList> createFileList(const Vector<FileChooserFileInfo>& files) const;
void receiveDropForDirectoryUpload(const Vector<String>&);
- RefPtr<FileList> m_fileList;
+ RefPtrWillBeMember<FileList> m_fileList;
String m_droppedFileSystemId;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp b/chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp
index a3cd9b02100..e4125bb7ed5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/FormController.cpp
@@ -221,7 +221,7 @@ PassOwnPtr<SavedFormState> SavedFormState::deserialize(const Vector<String>& sta
FormControlState state = FormControlState::deserialize(stateVector, index);
if (type.isEmpty() || type.find(isNotFormControlTypeCharacter) != kNotFound || state.isFailure())
return nullptr;
- savedFormState->appendControlState(name, type, state);
+ savedFormState->appendControlState(AtomicString(name), AtomicString(type), state);
}
return savedFormState.release();
}
@@ -288,19 +288,20 @@ Vector<String> SavedFormState::getReferencedFilePaths() const
// ----------------------------------------------------------------------------
-class FormKeyGenerator {
+class FormKeyGenerator FINAL : public NoBaseWillBeGarbageCollectedFinalized<FormKeyGenerator> {
WTF_MAKE_NONCOPYABLE(FormKeyGenerator);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<FormKeyGenerator> create() { return adoptPtr(new FormKeyGenerator); }
+ static PassOwnPtrWillBeRawPtr<FormKeyGenerator> create() { return adoptPtrWillBeNoop(new FormKeyGenerator); }
+ void trace(Visitor* visitor) { visitor->trace(m_formToKeyMap); }
const AtomicString& formKey(const HTMLFormControlElementWithState&);
void willDeleteForm(HTMLFormElement*);
private:
FormKeyGenerator() { }
- typedef HashMap<HTMLFormElement*, AtomicString> FormToKeyMap;
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<HTMLFormElement>, AtomicString> FormToKeyMap;
typedef HashMap<String, unsigned> FormSignatureToNextIndexMap;
FormToKeyMap m_formToKeyMap;
FormSignatureToNextIndexMap m_formSignatureToNextIndexMap;
@@ -310,7 +311,7 @@ static inline void recordFormStructure(const HTMLFormElement& form, StringBuilde
{
// 2 is enough to distinguish forms in webkit.org/b/91209#c0
const size_t namedControlsToBeRecorded = 2;
- const Vector<FormAssociatedElement*>& controls = form.associatedElements();
+ const FormAssociatedElement::List& controls = form.associatedElements();
builder.append(" [");
for (size_t i = 0, namedControls = 0; i < controls.size() && namedControls < namedControlsToBeRecorded; ++i) {
if (!controls[i]->isFormControlElementWithState())
@@ -333,7 +334,9 @@ static inline String formSignature(const HTMLFormElement& form)
KURL actionURL = form.getURLAttribute(actionAttr);
// Remove the query part because it might contain volatile parameters such
// as a session key.
- actionURL.setQuery(String());
+ if (!actionURL.isEmpty())
+ actionURL.setQuery(String());
+
StringBuilder builder;
if (!actionURL.isEmpty())
builder.append(actionURL.string());
@@ -356,14 +359,14 @@ const AtomicString& FormKeyGenerator::formKey(const HTMLFormControlElementWithSt
String signature = formSignature(*form);
ASSERT(!signature.isNull());
FormSignatureToNextIndexMap::AddResult result = m_formSignatureToNextIndexMap.add(signature, 0);
- unsigned nextIndex = result.iterator->value++;
+ unsigned nextIndex = result.storedValue->value++;
StringBuilder formKeyBuilder;
formKeyBuilder.append(signature);
formKeyBuilder.appendLiteral(" #");
formKeyBuilder.appendNumber(nextIndex);
FormToKeyMap::AddResult addFormKeyresult = m_formToKeyMap.add(form, formKeyBuilder.toAtomicString());
- return addFormKeyresult.iterator->value;
+ return addFormKeyresult.storedValue->value;
}
void FormKeyGenerator::willDeleteForm(HTMLFormElement* form)
@@ -374,12 +377,28 @@ void FormKeyGenerator::willDeleteForm(HTMLFormElement* form)
// ----------------------------------------------------------------------------
-FormController::FormController()
+PassRefPtrWillBeRawPtr<DocumentState> DocumentState::create()
{
+ return adoptRefWillBeNoop(new DocumentState);
}
-FormController::~FormController()
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentState)
+
+void DocumentState::trace(Visitor* visitor)
{
+ visitor->trace(m_formControls);
+}
+
+void DocumentState::addControl(HTMLFormControlElementWithState* control)
+{
+ ASSERT(!m_formControls.contains(control));
+ m_formControls.add(control);
+}
+
+void DocumentState::removeControl(HTMLFormControlElementWithState* control)
+{
+ RELEASE_ASSERT(m_formControls.contains(control));
+ m_formControls.remove(control);
}
static String formStateSignature()
@@ -391,28 +410,23 @@ static String formStateSignature()
return signature;
}
-PassOwnPtr<FormController::SavedFormStateMap> FormController::createSavedFormStateMap(const FormElementListHashSet& controlList)
+Vector<String> DocumentState::toStateVector()
{
- OwnPtr<FormKeyGenerator> keyGenerator = FormKeyGenerator::create();
+ OwnPtrWillBeRawPtr<FormKeyGenerator> keyGenerator = FormKeyGenerator::create();
OwnPtr<SavedFormStateMap> stateMap = adoptPtr(new SavedFormStateMap);
- for (FormElementListHashSet::const_iterator it = controlList.begin(); it != controlList.end(); ++it) {
- HTMLFormControlElementWithState* control = (*it).get();
+ for (FormElementListHashSet::const_iterator it = m_formControls.begin(); it != m_formControls.end(); ++it) {
+ HTMLFormControlElementWithState* control = it->get();
ASSERT(control->inDocument());
if (!control->shouldSaveAndRestoreFormControlState())
continue;
SavedFormStateMap::AddResult result = stateMap->add(keyGenerator->formKey(*control), nullptr);
if (result.isNewEntry)
- result.iterator->value = SavedFormState::create();
- result.iterator->value->appendControlState(control->name(), control->type(), control->saveFormControlState());
+ result.storedValue->value = SavedFormState::create();
+ result.storedValue->value->appendControlState(control->name(), control->type(), control->saveFormControlState());
}
- return stateMap.release();
-}
-Vector<String> FormController::formElementsState() const
-{
- OwnPtr<SavedFormStateMap> stateMap = createSavedFormStateMap(m_formElementsWithState);
Vector<String> stateVector;
- stateVector.reserveInitialCapacity(m_formElementsWithState.size() * 4);
+ stateVector.reserveInitialCapacity(m_formControls.size() * 4);
stateVector.append(formStateSignature());
for (SavedFormStateMap::const_iterator it = stateMap->begin(); it != stateMap->end(); ++it) {
stateVector.append(it->key);
@@ -424,6 +438,29 @@ Vector<String> FormController::formElementsState() const
return stateVector;
}
+// ----------------------------------------------------------------------------
+
+FormController::FormController()
+ : m_documentState(DocumentState::create())
+{
+}
+
+FormController::~FormController()
+{
+}
+
+void FormController::trace(Visitor* visitor)
+{
+ visitor->trace(m_radioButtonGroupScope);
+ visitor->trace(m_documentState);
+ visitor->trace(m_formKeyGenerator);
+}
+
+DocumentState* FormController::formElementsState() const
+{
+ return m_documentState.get();
+}
+
void FormController::setStateForNewFormElements(const Vector<String>& stateVector)
{
formStatesFromStateVector(stateVector, m_savedFormStateMap);
@@ -453,7 +490,7 @@ void FormController::formStatesFromStateVector(const Vector<String>& stateVector
return;
while (i + 1 < stateVector.size()) {
- AtomicString formKey = stateVector[i++];
+ AtomicString formKey = AtomicString(stateVector[i++]);
OwnPtr<SavedFormState> state = SavedFormState::deserialize(stateVector, i);
if (!state) {
i = 0;
@@ -487,7 +524,7 @@ void FormController::restoreControlStateFor(HTMLFormControlElementWithState& con
void FormController::restoreControlStateIn(HTMLFormElement& form)
{
- const Vector<FormAssociatedElement*>& elements = form.associatedElements();
+ const FormAssociatedElement::List& elements = form.associatedElements();
for (size_t i = 0; i < elements.size(); ++i) {
if (!elements[i]->isFormControlElementWithState())
continue;
@@ -508,20 +545,18 @@ Vector<String> FormController::getReferencedFilePaths(const Vector<String>& stat
SavedFormStateMap map;
formStatesFromStateVector(stateVector, map);
for (SavedFormStateMap::const_iterator it = map.begin(); it != map.end(); ++it)
- toReturn.append(it->value->getReferencedFilePaths());
+ toReturn.appendVector(it->value->getReferencedFilePaths());
return toReturn;
}
-void FormController::registerFormElementWithState(HTMLFormControlElementWithState* control)
+void FormController::registerStatefulFormControl(HTMLFormControlElementWithState& control)
{
- ASSERT(!m_formElementsWithState.contains(control));
- m_formElementsWithState.add(control);
+ m_documentState->addControl(&control);
}
-void FormController::unregisterFormElementWithState(HTMLFormControlElementWithState* control)
+void FormController::unregisterStatefulFormControl(HTMLFormControlElementWithState& control)
{
- RELEASE_ASSERT(m_formElementsWithState.contains(control));
- m_formElementsWithState.remove(control);
+ m_documentState->removeControl(&control);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/FormController.h b/chromium/third_party/WebKit/Source/core/html/forms/FormController.h
index 40799358d55..0671fe8a2b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/FormController.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/FormController.h
@@ -22,7 +22,8 @@
#ifndef FormController_h
#define FormController_h
-#include "core/html/forms/CheckedRadioButtons.h"
+#include "core/html/forms/RadioButtonGroupScope.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/ListHashSet.h"
#include "wtf/Vector.h"
@@ -71,21 +72,39 @@ inline void FormControlState::append(const String& value)
m_values.append(value);
}
-class FormController {
- WTF_MAKE_FAST_ALLOCATED;
+typedef HashMap<AtomicString, OwnPtr<SavedFormState> > SavedFormStateMap;
+
+class DocumentState FINAL : public RefCountedWillBeGarbageCollected<DocumentState> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DocumentState);
+public:
+ static PassRefPtrWillBeRawPtr<DocumentState> create();
+ void trace(Visitor*);
+
+ void addControl(HTMLFormControlElementWithState*);
+ void removeControl(HTMLFormControlElementWithState*);
+ Vector<String> toStateVector();
+
+private:
+ typedef WillBeHeapListHashSet<RefPtrWillBeMember<HTMLFormControlElementWithState>, 64> FormElementListHashSet;
+ FormElementListHashSet m_formControls;
+};
+
+class FormController FINAL : public NoBaseWillBeGarbageCollectedFinalized<FormController> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<FormController> create()
+ static PassOwnPtrWillBeRawPtr<FormController> create()
{
- return adoptPtr(new FormController);
+ return adoptPtrWillBeNoop(new FormController);
}
~FormController();
+ void trace(Visitor*);
- CheckedRadioButtons& checkedRadioButtons() { return m_checkedRadioButtons; }
+ RadioButtonGroupScope& radioButtonGroupScope() { return m_radioButtonGroupScope; }
- void registerFormElementWithState(HTMLFormControlElementWithState*);
- void unregisterFormElementWithState(HTMLFormControlElementWithState*);
+ void registerStatefulFormControl(HTMLFormControlElementWithState&);
+ void unregisterStatefulFormControl(HTMLFormControlElementWithState&);
// This should be callled only by Document::formElementsState().
- Vector<String> formElementsState() const;
+ DocumentState* formElementsState() const;
// This should be callled only by Document::setStateForNewFormElements().
void setStateForNewFormElements(const Vector<String>&);
void willDeleteForm(HTMLFormElement*);
@@ -95,18 +114,14 @@ public:
static Vector<String> getReferencedFilePaths(const Vector<String>& stateVector);
private:
- typedef ListHashSet<RefPtr<HTMLFormControlElementWithState>, 64> FormElementListHashSet;
- typedef HashMap<AtomicString, OwnPtr<SavedFormState> > SavedFormStateMap;
-
FormController();
- static PassOwnPtr<SavedFormStateMap> createSavedFormStateMap(const FormElementListHashSet&);
FormControlState takeStateForFormElement(const HTMLFormControlElementWithState&);
static void formStatesFromStateVector(const Vector<String>&, SavedFormStateMap&);
- CheckedRadioButtons m_checkedRadioButtons;
- FormElementListHashSet m_formElementsWithState;
+ RadioButtonGroupScope m_radioButtonGroupScope;
+ RefPtrWillBeMember<DocumentState> m_documentState;
SavedFormStateMap m_savedFormStateMap;
- OwnPtr<FormKeyGenerator> m_formKeyGenerator;
+ OwnPtrWillBeMember<FormKeyGenerator> m_formKeyGenerator;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp
index 7609742da68..abfbb551ab6 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.cpp
@@ -32,8 +32,8 @@
#include "config.h"
#include "core/html/forms/HiddenInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/FormController.h"
@@ -43,9 +43,9 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<InputType> HiddenInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> HiddenInputType::create(HTMLInputElement& element)
{
- return adoptRef(new HiddenInputType(element));
+ return adoptRefWillBeNoop(new HiddenInputType(element));
}
const AtomicString& HiddenInputType::formControlType() const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h
index a93b5c34fa7..70eeeb84e74 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/HiddenInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class HiddenInputType : public InputType {
+class HiddenInputType FINAL : public InputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
HiddenInputType(HTMLInputElement& element) : InputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
index a8a8d5143ca..e10beef9621 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.cpp
@@ -23,8 +23,8 @@
#include "config.h"
#include "core/html/forms/ImageInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/MouseEvent.h"
#include "core/fetch/ImageResource.h"
#include "core/html/FormDataList.h"
@@ -45,9 +45,9 @@ inline ImageInputType::ImageInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> ImageInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> ImageInputType::create(HTMLInputElement& element)
{
- return adoptRef(new ImageInputType(element));
+ return adoptRefWillBeNoop(new ImageInputType(element));
}
const AtomicString& ImageInputType::formControlType() const
@@ -107,7 +107,7 @@ static IntPoint extractClickLocation(Event* event)
void ImageInputType::handleDOMActivateEvent(Event* event)
{
- RefPtr<HTMLInputElement> element(this->element());
+ RefPtrWillBeRawPtr<HTMLInputElement> element(this->element());
if (element->isDisabledFormControl() || !element->form())
return;
element->setActivatedSubmit(true);
@@ -150,9 +150,6 @@ void ImageInputType::startResourceLoading()
if (!renderer)
return;
- if (imageLoader->hasPendingBeforeLoadEvent())
- return;
-
RenderImageResource* imageResource = renderer->imageResource();
imageResource->setImageResource(imageLoader->image());
@@ -189,7 +186,7 @@ bool ImageInputType::shouldRespectHeightAndWidthAttributes()
unsigned ImageInputType::height() const
{
- RefPtr<HTMLInputElement> element(this->element());
+ RefPtrWillBeRawPtr<HTMLInputElement> element(this->element());
if (!element->renderer()) {
// Check the attribute first for an explicit pixel value.
@@ -213,7 +210,7 @@ unsigned ImageInputType::height() const
unsigned ImageInputType::width() const
{
- RefPtr<HTMLInputElement> element(this->element());
+ RefPtrWillBeRawPtr<HTMLInputElement> element(this->element());
if (!element->renderer()) {
// Check the attribute first for an explicit pixel value.
@@ -235,4 +232,14 @@ unsigned ImageInputType::width() const
return box ? adjustForAbsoluteZoom(box->contentWidth(), box) : 0;
}
+bool ImageInputType::hasLegalLinkAttribute(const QualifiedName& name) const
+{
+ return name == srcAttr || BaseButtonInputType::hasLegalLinkAttribute(name);
+}
+
+const QualifiedName& ImageInputType::subResourceAttributeName() const
+{
+ return srcAttr;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h
index d033e2a61c2..a81356d09f4 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ImageInputType.h
@@ -38,9 +38,9 @@
namespace WebCore {
-class ImageInputType : public BaseButtonInputType {
+class ImageInputType FINAL : public BaseButtonInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
ImageInputType(HTMLInputElement&);
@@ -61,6 +61,8 @@ private:
virtual bool shouldRespectHeightAndWidthAttributes() OVERRIDE;
virtual unsigned height() const OVERRIDE;
virtual unsigned width() const OVERRIDE;
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const OVERRIDE;
+ virtual const QualifiedName& subResourceAttributeName() const OVERRIDE;
IntPoint m_clickLocation; // Valid only during HTMLFormElement::prepareForSubmission().
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp
index c443f6d2025..f06d4056f52 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/InputType.cpp
@@ -28,15 +28,18 @@
#include "config.h"
#include "core/html/forms/InputType.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/InputTypeNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/ScopedEventQueue.h"
#include "core/fileapi/FileList.h"
+#include "core/frame/FrameHost.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLInputElement.h"
+#include "core/html/HTMLShadowElement.h"
#include "core/html/forms/ButtonInputType.h"
#include "core/html/forms/CheckboxInputType.h"
#include "core/html/forms/ColorInputType.h"
@@ -61,9 +64,9 @@
#include "core/html/forms/URLInputType.h"
#include "core/html/forms/WeekInputType.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/html/shadow/HTMLShadowElement.h"
-#include "core/page/Page.h"
#include "core/rendering/RenderTheme.h"
+#include "platform/ColorChooser.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/PlatformLocale.h"
#include "platform/text/TextBreakIterator.h"
@@ -71,9 +74,8 @@ namespace WebCore {
using blink::WebLocalizedString;
using namespace HTMLNames;
-using namespace std;
-typedef PassRefPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement&);
+typedef PassRefPtrWillBeRawPtr<InputType> (*InputTypeFactoryFunction)(HTMLInputElement&);
typedef HashMap<AtomicString, InputTypeFactoryFunction, CaseFoldingHash> InputTypeFactoryMap;
static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
@@ -81,8 +83,7 @@ static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
OwnPtr<InputTypeFactoryMap> map = adoptPtr(new InputTypeFactoryMap);
map->add(InputTypeNames::button, ButtonInputType::create);
map->add(InputTypeNames::checkbox, CheckboxInputType::create);
- if (RuntimeEnabledFeatures::inputTypeColorEnabled())
- map->add(InputTypeNames::color, ColorInputType::create);
+ map->add(InputTypeNames::color, ColorInputType::create);
map->add(InputTypeNames::date, DateInputType::create);
map->add(InputTypeNames::datetime_local, DateTimeLocalInputType::create);
map->add(InputTypeNames::email, EmailInputType::create);
@@ -100,8 +101,7 @@ static PassOwnPtr<InputTypeFactoryMap> createInputTypeFactoryMap()
map->add(InputTypeNames::tel, TelephoneInputType::create);
map->add(InputTypeNames::time, TimeInputType::create);
map->add(InputTypeNames::url, URLInputType::create);
- if (RuntimeEnabledFeatures::inputTypeWeekEnabled())
- map->add(InputTypeNames::week, WeekInputType::create);
+ map->add(InputTypeNames::week, WeekInputType::create);
// No need to register "text" because it is the default type.
return map.release();
}
@@ -112,7 +112,7 @@ static const InputTypeFactoryMap* factoryMap()
return factoryMap;
}
-PassRefPtr<InputType> InputType::create(HTMLInputElement& element, const AtomicString& typeName)
+PassRefPtrWillBeRawPtr<InputType> InputType::create(HTMLInputElement& element, const AtomicString& typeName)
{
InputTypeFactoryFunction factory = typeName.isEmpty() ? 0 : factoryMap()->get(typeName);
if (!factory)
@@ -120,7 +120,7 @@ PassRefPtr<InputType> InputType::create(HTMLInputElement& element, const AtomicS
return factory(element);
}
-PassRefPtr<InputType> InputType::createText(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> InputType::createText(HTMLInputElement& element)
{
return TextInputType::create(element);
}
@@ -133,25 +133,10 @@ const AtomicString& InputType::normalizeTypeName(const AtomicString& typeName)
return it == factoryMap()->end() ? InputTypeNames::text : it->key;
}
-bool InputType::canChangeFromAnotherType(const AtomicString& normalizedTypeName)
-{
- // Don't allow the type to be changed to file after the first type change.
- // In other engines this might mean a JavaScript programmer could set a text
- // field's value to something like /etc/passwd and then change it to a file
- // input. I don't think this would actually occur in Blink, but this rule
- // still may be important for compatibility.
- return normalizedTypeName != InputTypeNames::file;
-}
-
InputType::~InputType()
{
}
-bool InputType::themeSupportsDataListUI(InputType* type)
-{
- return RenderTheme::theme().supportsDataListUI(type->formControlType());
-}
-
bool InputType::isTextField() const
{
return false;
@@ -210,22 +195,22 @@ double InputType::valueAsDate() const
void InputType::setValueAsDate(double, ExceptionState& exceptionState) const
{
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "This input element does not support Date values.");
}
double InputType::valueAsDouble() const
{
- return numeric_limits<double>::quiet_NaN();
+ return std::numeric_limits<double>::quiet_NaN();
}
void InputType::setValueAsDouble(double doubleValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- setValueAsDecimal(Decimal::fromDouble(doubleValue), eventBehavior, exceptionState);
+ exceptionState.throwDOMException(InvalidStateError, "This input element does not support Number values.");
}
-void InputType::setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionState& exceptionState) const
+void InputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState&) const
{
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ element().setValue(serialize(newValue), eventBehavior);
}
bool InputType::supportsValidation() const
@@ -437,12 +422,6 @@ Decimal InputType::parseToNumberOrNaN(const String& string) const
return parseToNumber(string, Decimal::nan());
}
-bool InputType::parseToDateComponents(const String&, DateComponents*) const
-{
- ASSERT_NOT_REACHED();
- return false;
-}
-
String InputType::serialize(const Decimal&) const
{
ASSERT_NOT_REACHED();
@@ -458,8 +437,8 @@ void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
Chrome* InputType::chrome() const
{
- if (Page* page = element().document().page())
- return &page->chrome();
+ if (FrameHost* host = element().document().frameHost())
+ return &host->chrome();
return 0;
}
@@ -534,7 +513,7 @@ FileList* InputType::files()
return 0;
}
-void InputType::setFiles(PassRefPtr<FileList>)
+void InputType::setFiles(PassRefPtrWillBeRawPtr<FileList>)
{
}
@@ -568,10 +547,15 @@ bool InputType::storesValueSeparateFromAttribute()
return true;
}
+bool InputType::shouldDispatchFormControlChangeEvent(String& oldValue, String& newValue)
+{
+ return !equalIgnoringNullity(oldValue, newValue);
+}
+
void InputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
{
element().setValueInternal(sanitizedValue, eventBehavior);
- element().setNeedsStyleRecalc();
+ element().setNeedsStyleRecalc(SubtreeStyleChange);
if (!valueChanged)
return;
switch (eventBehavior) {
@@ -619,11 +603,6 @@ String InputType::droppedFileSystemId()
return String();
}
-bool InputType::shouldResetOnDocumentActivation()
-{
- return false;
-}
-
bool InputType::shouldRespectListAttribute()
{
return false;
@@ -689,11 +668,6 @@ bool InputType::isNumberField() const
return false;
}
-bool InputType::isSubmitButton() const
-{
- return false;
-}
-
bool InputType::isTelephoneField() const
{
return false;
@@ -764,10 +738,6 @@ bool InputType::supportsReadOnly() const
return false;
}
-void InputType::updatePlaceholderText()
-{
-}
-
String InputType::defaultToolTip() const
{
return String();
@@ -783,6 +753,16 @@ void InputType::handleDOMActivateEvent(Event*)
{
}
+bool InputType::hasLegalLinkAttribute(const QualifiedName&) const
+{
+ return false;
+}
+
+const QualifiedName& InputType::subResourceAttributeName() const
+{
+ return QualifiedName::null();
+}
+
bool InputType::supportsIndeterminateAppearance() const
{
return false;
@@ -808,46 +788,64 @@ unsigned InputType::width() const
return 0;
}
-void InputType::applyStep(int count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState)
+void InputType::applyStep(const Decimal& current, int count, AnyStepHandling anyStepHandling, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState)
{
StepRange stepRange(createStepRange(anyStepHandling));
if (!stepRange.hasStep()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "This form element does not have an allowed value step.");
return;
}
- const Decimal current = parseToNumberOrNaN(element().value());
- if (!current.isFinite()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
- Decimal newValue = current + stepRange.step() * count;
- if (!newValue.isFinite()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
-
- const Decimal acceptableErrorValue = stepRange.acceptableError();
- if (newValue - stepRange.minimum() < -acceptableErrorValue) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
- if (newValue < stepRange.minimum())
- newValue = stepRange.minimum();
+ EventQueueScope scope;
+ const Decimal step = stepRange.step();
const AtomicString& stepString = element().fastGetAttribute(stepAttr);
- if (!equalIgnoringCase(stepString, "any"))
- newValue = stepRange.alignValueForStep(current, newValue);
+ if (!equalIgnoringCase(stepString, "any") && stepRange.stepMismatch(current)) {
+ // Snap-to-step / clamping steps
+ // If the current value is not matched to step value:
+ // - The value should be the larger matched value nearest to 0 if count > 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 5
+ // - The value should be the smaller matched value nearest to 0 if count < 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 2
+ //
+
+ ASSERT(!step.isZero());
+ Decimal newValue;
+ const Decimal base = stepRange.stepBase();
+ if (count < 0)
+ newValue = base + ((current - base) / step).floor() * step;
+ else if (count > 0)
+ newValue = base + ((current - base) / step).ceiling() * step;
+ else
+ newValue = current;
+
+ if (newValue < stepRange.minimum())
+ newValue = stepRange.minimum();
+ if (newValue > stepRange.maximum())
+ newValue = stepRange.maximum();
+
+ setValueAsDecimal(newValue, count == 1 || count == -1 ? DispatchChangeEvent : DispatchNoEvent, IGNORE_EXCEPTION);
+ if (count > 1) {
+ applyStep(newValue, count - 1, AnyIsDefaultStep, DispatchChangeEvent, IGNORE_EXCEPTION);
+ return;
+ }
+ if (count < -1) {
+ applyStep(newValue, count + 1, AnyIsDefaultStep, DispatchChangeEvent, IGNORE_EXCEPTION);
+ return;
+ }
+ } else {
+ Decimal newValue = current + stepRange.step() * count;
- if (newValue - stepRange.maximum() > acceptableErrorValue) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return;
- }
- if (newValue > stepRange.maximum())
- newValue = stepRange.maximum();
+ if (!equalIgnoringCase(stepString, "any"))
+ newValue = stepRange.alignValueForStep(current, newValue);
- setValueAsDecimal(newValue, eventBehavior, exceptionState);
+ if (newValue > stepRange.maximum())
+ newValue = newValue - stepRange.step();
+ else if (newValue < stepRange.minimum())
+ newValue = newValue + stepRange.step();
+ setValueAsDecimal(newValue, eventBehavior, exceptionState);
+ }
if (AXObjectCache* cache = element().document().existingAXObjectCache())
cache->postNotification(&element(), AXObjectCache::AXValueChanged, true);
}
@@ -868,17 +866,18 @@ StepRange InputType::createStepRange(AnyStepHandling) const
void InputType::stepUp(int n, ExceptionState& exceptionState)
{
if (!isSteppable()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
+ exceptionState.throwDOMException(InvalidStateError, "This form element is not steppable.");
return;
}
- applyStep(n, RejectAny, DispatchNoEvent, exceptionState);
+ const Decimal current = parseToNumber(element().value(), 0);
+ applyStep(current, n, RejectAny, DispatchNoEvent, exceptionState);
}
void InputType::stepUpFromRenderer(int n)
{
- // The differences from stepUp()/stepDown():
+ // The only difference from stepUp()/stepDown() is the extra treatment
+ // of the current value before applying the step:
//
- // Difference 1: the current value
// If the current value is not a number, including empty, the current value is assumed as 0.
// * If 0 is in-range, and matches to step value
// - The value should be the +step if n > 0
@@ -902,13 +901,6 @@ void InputType::stepUpFromRenderer(int n)
// - The value should be the maximum value if n < 0
// - Nothing should happen if n > 0
//
- // Difference 2: clamping steps
- // If the current value is not matched to step value:
- // - The value should be the larger matched value nearest to 0 if n > 0
- // e.g. <input type=number value=3 min=-100 step=3> -> 5
- // - The value should be the smaler matched value nearest to 0 if n < 0
- // e.g. <input type=number value=3 min=-100 step=3> -> 2
- //
// n is assumed as -n if step < 0.
ASSERT(isSteppable());
@@ -936,8 +928,7 @@ void InputType::stepUpFromRenderer(int n)
else
sign = 0;
- String currentStringValue = element().value();
- Decimal current = parseToNumberOrNaN(currentStringValue);
+ Decimal current = parseToNumberOrNaN(element().value());
if (!current.isFinite()) {
current = defaultValueForStepUp();
const Decimal nextDiff = step * n;
@@ -948,33 +939,10 @@ void InputType::stepUpFromRenderer(int n)
setValueAsDecimal(current, DispatchNoEvent, IGNORE_EXCEPTION);
}
if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > stepRange.maximum())) {
- setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
- } else {
- if (stepMismatch(element().value())) {
- ASSERT(!step.isZero());
- const Decimal base = stepRange.stepBase();
- Decimal newValue;
- if (sign < 0)
- newValue = base + ((current - base) / step).floor() * step;
- else if (sign > 0)
- newValue = base + ((current - base) / step).ceiling() * step;
- else
- newValue = current;
-
- if (newValue < stepRange.minimum())
- newValue = stepRange.minimum();
- if (newValue > stepRange.maximum())
- newValue = stepRange.maximum();
-
- setValueAsDecimal(newValue, n == 1 || n == -1 ? DispatchInputAndChangeEvent : DispatchNoEvent, IGNORE_EXCEPTION);
- if (n > 1)
- applyStep(n - 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
- else if (n < -1)
- applyStep(n + 1, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
- } else {
- applyStep(n, AnyIsDefaultStep, DispatchInputAndChangeEvent, IGNORE_EXCEPTION);
- }
+ setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchChangeEvent, IGNORE_EXCEPTION);
+ return;
}
+ applyStep(current, n, AnyIsDefaultStep, DispatchChangeEvent, IGNORE_EXCEPTION);
}
void InputType::countUsageIfVisible(UseCounter::Feature feature) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/InputType.h b/chromium/third_party/WebKit/Source/core/html/forms/InputType.h
index 207abd8f305..fe0f4d33311 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/InputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/InputType.h
@@ -55,17 +55,14 @@ class Node;
// FIXME: InputType should not inherit InputTypeView. It's conceptually wrong.
class InputType : public InputTypeView {
WTF_MAKE_NONCOPYABLE(InputType);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<InputType> create(HTMLInputElement&, const AtomicString&);
- static PassRefPtr<InputType> createText(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&, const AtomicString&);
+ static PassRefPtrWillBeRawPtr<InputType> createText(HTMLInputElement&);
static const AtomicString& normalizeTypeName(const AtomicString&);
virtual ~InputType();
- static bool canChangeFromAnotherType(const AtomicString& normalizedTypeName);
- static bool themeSupportsDataListUI(InputType*);
-
virtual const AtomicString& formControlType() const = 0;
// Type query functions
@@ -92,7 +89,6 @@ public:
virtual bool isRadioButton() const;
virtual bool isRangeControl() const;
virtual bool isSearchField() const;
- virtual bool isSubmitButton() const;
virtual bool isTelephoneField() const;
virtual bool isTextButton() const;
virtual bool isTextField() const;
@@ -172,7 +168,7 @@ public:
virtual void sanitizeValueInResponseToMinOrMaxAttributeChange();
virtual bool shouldRespectAlignAttribute();
virtual FileList* files();
- virtual void setFiles(PassRefPtr<FileList>);
+ virtual void setFiles(PassRefPtrWillBeRawPtr<FileList>);
// Should return true if the given DragData has more than one dropped files.
virtual bool receiveDroppedFiles(const DragData*);
virtual String droppedFileSystemId();
@@ -182,7 +178,6 @@ public:
virtual bool canSetValue(const String&);
virtual bool storesValueSeparateFromAttribute();
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior);
- virtual bool shouldResetOnDocumentActivation();
virtual bool shouldRespectListAttribute();
virtual bool shouldRespectSpeechAttribute();
virtual bool isEnumeratable();
@@ -191,10 +186,11 @@ public:
virtual bool shouldRespectHeightAndWidthAttributes();
virtual bool supportsPlaceholder() const;
virtual bool supportsReadOnly() const;
- virtual void updatePlaceholderText();
virtual String defaultToolTip() const;
virtual Decimal findClosestTickMarkValue(const Decimal&);
virtual void handleDOMActivateEvent(Event*);
+ virtual bool hasLegalLinkAttribute(const QualifiedName&) const;
+ virtual const QualifiedName& subResourceAttributeName() const;
// Parses the specified string for the type, and return
// the Decimal value for the parsing result if the parsing
@@ -202,12 +198,6 @@ public:
// return NaN or Infinity only if defaultValue is NaN or Infinity.
virtual Decimal parseToNumber(const String&, const Decimal& defaultValue) const;
- // Parses the specified string for this InputType, and returns true if it
- // is successfully parsed. An instance pointed by the DateComponents*
- // parameter will have parsed values and be modified even if the parsing
- // fails. The DateComponents* parameter may be 0.
- virtual bool parseToDateComponents(const String&, DateComponents*) const;
-
// Create a string representation of the specified Decimal value for the
// input type. If NaN or Infinity is specified, this returns an empty
// string. This should not be called for types without valueAsNumber.
@@ -230,6 +220,8 @@ public:
virtual bool shouldSubmitImplicitly(Event*) OVERRIDE;
virtual bool hasCustomFocusLogic() const OVERRIDE;
+ virtual bool shouldDispatchFormControlChangeEvent(String&, String&);
+
protected:
InputType(HTMLInputElement& element) : InputTypeView(element) { }
Chrome* chrome() const;
@@ -244,7 +236,7 @@ protected:
private:
// Helper for stepUp()/stepDown(). Adds step value * count to the current value.
- void applyStep(int count, AnyStepHandling, TextFieldEventBehavior, ExceptionState&);
+ void applyStep(const Decimal&, int count, AnyStepHandling, TextFieldEventBehavior, ExceptionState&);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp b/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp
index d8c49395104..8e8aee3e27f 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.cpp
@@ -35,15 +35,20 @@
namespace WebCore {
-PassRefPtr<InputTypeView> InputTypeView::create(HTMLInputElement& input)
+PassRefPtrWillBeRawPtr<InputTypeView> InputTypeView::create(HTMLInputElement& input)
{
- return adoptRef(new InputTypeView(input));
+ return adoptRefWillBeNoop(new InputTypeView(input));
}
InputTypeView::~InputTypeView()
{
}
+void InputTypeView::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+}
+
bool InputTypeView::sizeShouldIncludeDecoration(int, int& preferredSize) const
{
preferredSize = element().size();
@@ -87,7 +92,7 @@ bool InputTypeView::shouldSubmitImplicitly(Event* event)
return false;
}
-PassRefPtr<HTMLFormElement> InputTypeView::formForSubmission() const
+PassRefPtrWillBeRawPtr<HTMLFormElement> InputTypeView::formForSubmission() const
{
return element().form();
}
@@ -112,7 +117,7 @@ bool InputTypeView::hasCustomFocusLogic() const
return false;
}
-void InputTypeView::handleFocusEvent(Element*, FocusDirection)
+void InputTypeView::handleFocusEvent(Element*, FocusType)
{
}
@@ -154,7 +159,7 @@ void InputTypeView::stepAttributeChanged()
{
}
-PassOwnPtr<ClickHandlingState> InputTypeView::willDispatchClick()
+PassOwnPtrWillBeRawPtr<ClickHandlingState> InputTypeView::willDispatchClick()
{
return nullptr;
}
@@ -209,4 +214,13 @@ void InputTypeView::updateClearButtonVisibility()
{
}
+void InputTypeView::updatePlaceholderText()
+{
+}
+
+void ClickHandlingState::trace(Visitor* visitor)
+{
+ visitor->trace(checkedRadioButton);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h b/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h
index 1e4aec4f20a..808fde90803 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/InputTypeView.h
@@ -33,7 +33,8 @@
#ifndef InputTypeView_h
#define InputTypeView_h
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
+#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
@@ -53,30 +54,33 @@ class RenderObject;
class RenderStyle;
class TouchEvent;
-struct ClickHandlingState {
- WTF_MAKE_FAST_ALLOCATED;
+struct ClickHandlingState FINAL : public NoBaseWillBeGarbageCollected<ClickHandlingState> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
+ void trace(Visitor*);
+
bool checked;
bool indeterminate;
- RefPtr<HTMLInputElement> checkedRadioButton;
+ RefPtrWillBeMember<HTMLInputElement> checkedRadioButton;
};
// An InputTypeView object represents the UI-specific part of an
// HTMLInputElement. Do not expose instances of InputTypeView and classes
// derived from it to classes other than HTMLInputElement.
-class InputTypeView : public RefCounted<InputTypeView> {
+class InputTypeView : public RefCountedWillBeGarbageCollectedFinalized<InputTypeView> {
WTF_MAKE_NONCOPYABLE(InputTypeView);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassRefPtr<InputTypeView> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputTypeView> create(HTMLInputElement&);
virtual ~InputTypeView();
+ virtual void trace(Visitor*);
virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const;
virtual void handleClickEvent(MouseEvent*);
virtual void handleMouseDownEvent(MouseEvent*);
- virtual PassOwnPtr<ClickHandlingState> willDispatchClick();
+ virtual PassOwnPtrWillBeRawPtr<ClickHandlingState> willDispatchClick();
virtual void didDispatchClick(Event*, const ClickHandlingState&);
virtual void handleKeydownEvent(KeyboardEvent*);
virtual void handleKeypressEvent(KeyboardEvent*);
@@ -85,9 +89,9 @@ public:
virtual void handleTouchEvent(TouchEvent*);
virtual void forwardEvent(Event*);
virtual bool shouldSubmitImplicitly(Event*);
- virtual PassRefPtr<HTMLFormElement> formForSubmission() const;
+ virtual PassRefPtrWillBeRawPtr<HTMLFormElement> formForSubmission() const;
virtual bool hasCustomFocusLogic() const;
- virtual void handleFocusEvent(Element* oldFocusedElement, FocusDirection);
+ virtual void handleFocusEvent(Element* oldFocusedElement, FocusType);
virtual void handleBlurEvent();
virtual void subtreeHasChanged();
virtual bool hasTouchEventHandler() const;
@@ -111,15 +115,16 @@ public:
virtual void valueAttributeChanged();
virtual void listAttributeTargetChanged();
virtual void updateClearButtonVisibility();
+ virtual void updatePlaceholderText();
protected:
- InputTypeView(HTMLInputElement& element) : m_element(element) { }
- HTMLInputElement& element() const { return m_element; }
+ InputTypeView(HTMLInputElement& element) : m_element(&element) { }
+ HTMLInputElement& element() const { return *m_element; }
private:
// Not a RefPtr because the HTMLInputElement object owns this InputTypeView
// object.
- HTMLInputElement& m_element;
+ RawPtrWillBeMember<HTMLInputElement> m_element;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp
index 647ac351770..27800a016ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/html/forms/MonthInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -51,9 +51,9 @@ static const int monthDefaultStep = 1;
static const int monthDefaultStepBase = 0;
static const int monthStepScaleFactor = 1;
-PassRefPtr<InputType> MonthInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> MonthInputType::create(HTMLInputElement& element)
{
- return adoptRef(new MonthInputType(element));
+ return adoptRefWillBeNoop(new MonthInputType(element));
}
void MonthInputType::countUsage()
@@ -134,6 +134,11 @@ bool MonthInputType::isMonthField() const
return true;
}
+bool MonthInputType::canSetSuggestedValue()
+{
+ return true;
+}
+
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
String MonthInputType::formatDateTimeFieldsState(const DateTimeFieldsState& dateTimeFieldsState) const
{
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h
index ee2bbf2bf24..34fd57227a7 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/MonthInputType.h
@@ -42,9 +42,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseMonthInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseMonthInputType;
#endif
-class MonthInputType : public BaseMonthInputType {
+class MonthInputType FINAL : public BaseMonthInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
MonthInputType(HTMLInputElement& element) : BaseMonthInputType(element) { }
@@ -58,12 +58,13 @@ private:
virtual bool parseToDateComponentsInternal(const String&, DateComponents*) const OVERRIDE;
virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
virtual bool isMonthField() const OVERRIDE;
+ virtual bool canSetSuggestedValue() OVERRIDE;
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
// BaseMultipleFieldsDateAndTimeInputType functions
- virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE FINAL;
- virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE FINAL;
- virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const;
+ virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE;
+ virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE;
+ virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp
index e2d90015378..a1a3eed20a9 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.cpp
@@ -32,9 +32,9 @@
#include "config.h"
#include "core/html/forms/NumberInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/events/KeyboardEvent.h"
#include "core/html/HTMLInputElement.h"
@@ -49,7 +49,6 @@ namespace WebCore {
using blink::WebLocalizedString;
using namespace HTMLNames;
-using namespace std;
static const int numberDefaultStep = 1;
static const int numberDefaultStepBase = 0;
@@ -94,9 +93,9 @@ static RealNumberRenderSize calculateRenderSize(const Decimal& value)
return RealNumberRenderSize(sizeOfSign + sizeOfZero , numberOfZeroAfterDecimalPoint + sizeOfDigits);
}
-PassRefPtr<InputType> NumberInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> NumberInputType::create(HTMLInputElement& element)
{
- return adoptRef(new NumberInputType(element));
+ return adoptRefWillBeNoop(new NumberInputType(element));
}
void NumberInputType::countUsage()
@@ -111,8 +110,8 @@ const AtomicString& NumberInputType::formControlType() const
void NumberInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
{
- if (!valueChanged && sanitizedValue.isEmpty() && !element().innerTextValue().isEmpty())
- updateView();
+ if (!valueChanged && sanitizedValue.isEmpty() && !element().innerEditorValue().isEmpty())
+ element().updateView();
TextFieldInputType::setValue(sanitizedValue, valueChanged, eventBehavior);
}
@@ -123,23 +122,11 @@ double NumberInputType::valueAsDouble() const
void NumberInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- // FIXME: We should use numeric_limits<double>::max for number input type.
- const double floatMax = numeric_limits<float>::max();
- if (newValue < -floatMax || newValue > floatMax) {
- exceptionState.throwDOMException(InvalidStateError, "The value provided (" + String::number(newValue) + ") is outside the range (" + String::number(-floatMax) + ", " + String::number(floatMax) + ").");
- return;
- }
element().setValue(serializeForNumberType(newValue), eventBehavior);
}
void NumberInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- // FIXME: We should use numeric_limits<double>::max for number input type.
- const Decimal floatMax = Decimal::fromDouble(numeric_limits<float>::max());
- if (newValue < -floatMax || newValue > floatMax) {
- exceptionState.throwDOMException(InvalidStateError, "The value provided (" + newValue.toString() + ") is outside the range (-" + floatMax.toString() + ", " + floatMax.toString() + ").");
- return;
- }
element().setValue(serializeForNumberType(newValue), eventBehavior);
}
@@ -157,10 +144,8 @@ bool NumberInputType::typeMismatch() const
StepRange NumberInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (numberDefaultStep, numberDefaultStepBase, numberStepScaleFactor));
-
- // FIXME: We should use numeric_limits<double>::max for number input type.
- const Decimal floatMax = Decimal::fromDouble(numeric_limits<float>::max());
- return InputType::createStepRange(anyStepHandling, numberDefaultStepBase, -floatMax, floatMax, stepDescription);
+ const Decimal doubleMax = Decimal::fromDouble(std::numeric_limits<double>::max());
+ return InputType::createStepRange(anyStepHandling, numberDefaultStepBase, -doubleMax, doubleMax, stepDescription);
}
bool NumberInputType::sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const
@@ -252,7 +237,7 @@ String NumberInputType::sanitizeValue(const String& proposedValue) const
bool NumberInputType::hasBadInput() const
{
- String standardValue = convertFromVisibleValue(element().innerTextValue());
+ String standardValue = convertFromVisibleValue(element().innerEditorValue());
return !standardValue.isEmpty() && !std::isfinite(parseToDoubleForNumberType(standardValue));
}
@@ -291,7 +276,7 @@ void NumberInputType::minOrMaxAttributeChanged()
InputType::minOrMaxAttributeChanged();
if (element().renderer())
- element().renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ element().renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
void NumberInputType::stepAttributeChanged()
@@ -299,7 +284,7 @@ void NumberInputType::stepAttributeChanged()
InputType::stepAttributeChanged();
if (element().renderer())
- element().renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+ element().renderer()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
bool NumberInputType::supportsSelectionAPI() const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h
index 35711e3f9f6..be04ad8b53f 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/NumberInputType.h
@@ -37,9 +37,9 @@ namespace WebCore {
class ExceptionState;
-class NumberInputType : public TextFieldInputType {
+class NumberInputType FINAL : public TextFieldInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
NumberInputType(HTMLInputElement& element) : TextFieldInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp
index 6da205be0cc..4c974f03c21 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.cpp
@@ -32,24 +32,18 @@
#include "config.h"
#include "core/html/forms/PasswordInputType.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "InputTypeNames.h"
-#include "core/dom/shadow/ShadowRoot.h"
+#include "core/InputTypeNames.h"
+#include "core/dom/Document.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/FormController.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
#include "wtf/Assertions.h"
-#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
namespace WebCore {
-PassRefPtr<InputType> PasswordInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> PasswordInputType::create(HTMLInputElement& element)
{
- return adoptRef(new PasswordInputType(element));
+ return adoptRefWillBeNoop(new PasswordInputType(element));
}
void PasswordInputType::countUsage()
@@ -59,38 +53,6 @@ void PasswordInputType::countUsage()
countUsageIfVisible(UseCounter::InputTypePasswordMaxLength);
}
-bool PasswordInputType::isPasswordGenerationEnabled() const
-{
- if (isPasswordGenerationDecorationEnabled())
- return true;
- if (Page* page = element().document().page())
- return page->chrome().client().isPasswordGenerationEnabled();
- return false;
-}
-
-bool PasswordInputType::isPasswordGenerationDecorationEnabled() const
-{
- if (Page* page = element().document().page())
- return page->settings().passwordGenerationDecorationEnabled();
- return false;
-}
-
-bool PasswordInputType::needsContainer() const
-{
- return BaseTextInputType::needsContainer() || isPasswordGenerationEnabled();
-}
-
-void PasswordInputType::createShadowSubtree()
-{
- BaseTextInputType::createShadowSubtree();
- if (!isPasswordGenerationEnabled())
- return;
- RefPtr<PasswordGeneratorButtonElement> generatorButton = PasswordGeneratorButtonElement::create(element().document());
- if (!isPasswordGenerationDecorationEnabled())
- generatorButton->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
- containerElement()->appendChild(generatorButton.release());
-}
-
const AtomicString& PasswordInputType::formControlType() const
{
return InputTypeNames::password;
@@ -121,11 +83,6 @@ bool PasswordInputType::shouldUseInputMethod() const
return false;
}
-bool PasswordInputType::shouldResetOnDocumentActivation()
-{
- return true;
-}
-
bool PasswordInputType::shouldRespectListAttribute()
{
return false;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h
index 50f36691e0d..441cd99a171 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/PasswordInputType.h
@@ -32,34 +32,26 @@
#define PasswordInputType_h
#include "core/html/forms/BaseTextInputType.h"
-#include "core/html/shadow/PasswordGeneratorButtonElement.h"
namespace WebCore {
class PasswordInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
PasswordInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
- virtual bool needsContainer() const OVERRIDE;
- virtual void createShadowSubtree() OVERRIDE;
virtual void countUsage() OVERRIDE;
virtual const AtomicString& formControlType() const OVERRIDE;
virtual bool shouldSaveAndRestoreFormControlState() const OVERRIDE;
virtual FormControlState saveFormControlState() const OVERRIDE;
virtual void restoreFormControlState(const FormControlState&) OVERRIDE;
virtual bool shouldUseInputMethod() const OVERRIDE;
- virtual bool shouldResetOnDocumentActivation() OVERRIDE;
virtual bool shouldRespectListAttribute() OVERRIDE;
virtual bool shouldRespectSpeechAttribute() OVERRIDE;
virtual bool isPasswordField() const OVERRIDE;
virtual void enableSecureTextInput() OVERRIDE;
virtual void disableSecureTextInput() OVERRIDE;
-
- bool isPasswordGenerationEnabled() const;
- // For testing.
- bool isPasswordGenerationDecorationEnabled() const;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp b/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp
new file mode 100644
index 00000000000..92909e3a87a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.cpp
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/html/forms/RadioButtonGroupScope.h"
+
+#include "core/html/HTMLInputElement.h"
+#include "wtf/HashSet.h"
+
+namespace WebCore {
+
+class RadioButtonGroup : public NoBaseWillBeGarbageCollected<RadioButtonGroup> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+ static PassOwnPtrWillBeRawPtr<RadioButtonGroup> create();
+ bool isEmpty() const { return m_members.isEmpty(); }
+ bool isRequired() const { return m_requiredCount; }
+ HTMLInputElement* checkedButton() const { return m_checkedButton; }
+ void add(HTMLInputElement*);
+ void updateCheckedState(HTMLInputElement*);
+ void requiredAttributeChanged(HTMLInputElement*);
+ void remove(HTMLInputElement*);
+ bool contains(HTMLInputElement*) const;
+
+ void trace(Visitor*);
+
+private:
+ RadioButtonGroup();
+ void setNeedsValidityCheckForAllButtons();
+ bool isValid() const;
+ void setCheckedButton(HTMLInputElement*);
+
+ WillBeHeapHashSet<RawPtrWillBeMember<HTMLInputElement> > m_members;
+ RawPtrWillBeMember<HTMLInputElement> m_checkedButton;
+ size_t m_requiredCount;
+};
+
+RadioButtonGroup::RadioButtonGroup()
+ : m_checkedButton(nullptr)
+ , m_requiredCount(0)
+{
+}
+
+PassOwnPtrWillBeRawPtr<RadioButtonGroup> RadioButtonGroup::create()
+{
+ return adoptPtrWillBeNoop(new RadioButtonGroup);
+}
+
+inline bool RadioButtonGroup::isValid() const
+{
+ return !isRequired() || m_checkedButton;
+}
+
+void RadioButtonGroup::setCheckedButton(HTMLInputElement* button)
+{
+ HTMLInputElement* oldCheckedButton = m_checkedButton;
+ if (oldCheckedButton == button)
+ return;
+ m_checkedButton = button;
+ if (oldCheckedButton)
+ oldCheckedButton->setChecked(false);
+}
+
+void RadioButtonGroup::add(HTMLInputElement* button)
+{
+ ASSERT(button->isRadioButton());
+ if (!m_members.add(button).isNewEntry)
+ return;
+ bool groupWasValid = isValid();
+ if (button->isRequired())
+ ++m_requiredCount;
+ if (button->checked())
+ setCheckedButton(button);
+
+ bool groupIsValid = isValid();
+ if (groupWasValid != groupIsValid) {
+ setNeedsValidityCheckForAllButtons();
+ } else if (!groupIsValid) {
+ // A radio button not in a group is always valid. We need to make it
+ // invalid only if the group is invalid.
+ button->setNeedsValidityCheck();
+ }
+}
+
+void RadioButtonGroup::updateCheckedState(HTMLInputElement* button)
+{
+ ASSERT(button->isRadioButton());
+ ASSERT(m_members.contains(button));
+ bool wasValid = isValid();
+ if (button->checked()) {
+ setCheckedButton(button);
+ } else {
+ if (m_checkedButton == button)
+ m_checkedButton = nullptr;
+ }
+ if (wasValid != isValid())
+ setNeedsValidityCheckForAllButtons();
+}
+
+void RadioButtonGroup::requiredAttributeChanged(HTMLInputElement* button)
+{
+ ASSERT(button->isRadioButton());
+ ASSERT(m_members.contains(button));
+ bool wasValid = isValid();
+ if (button->isRequired()) {
+ ++m_requiredCount;
+ } else {
+ ASSERT(m_requiredCount);
+ --m_requiredCount;
+ }
+ if (wasValid != isValid())
+ setNeedsValidityCheckForAllButtons();
+}
+
+void RadioButtonGroup::remove(HTMLInputElement* button)
+{
+ ASSERT(button->isRadioButton());
+ WillBeHeapHashSet<RawPtrWillBeMember<HTMLInputElement> >::iterator it = m_members.find(button);
+ if (it == m_members.end())
+ return;
+ bool wasValid = isValid();
+ m_members.remove(it);
+ if (button->isRequired()) {
+ ASSERT(m_requiredCount);
+ --m_requiredCount;
+ }
+ if (m_checkedButton == button)
+ m_checkedButton = nullptr;
+
+ if (m_members.isEmpty()) {
+ ASSERT(!m_requiredCount);
+ ASSERT(!m_checkedButton);
+ } else if (wasValid != isValid()) {
+ setNeedsValidityCheckForAllButtons();
+ }
+ if (!wasValid) {
+ // A radio button not in a group is always valid. We need to make it
+ // valid only if the group was invalid.
+ button->setNeedsValidityCheck();
+ }
+}
+
+void RadioButtonGroup::setNeedsValidityCheckForAllButtons()
+{
+ typedef WillBeHeapHashSet<RawPtrWillBeMember<HTMLInputElement> >::const_iterator Iterator;
+ Iterator end = m_members.end();
+ for (Iterator it = m_members.begin(); it != end; ++it) {
+ HTMLInputElement* button = *it;
+ ASSERT(button->isRadioButton());
+ button->setNeedsValidityCheck();
+ }
+}
+
+bool RadioButtonGroup::contains(HTMLInputElement* button) const
+{
+ return m_members.contains(button);
+}
+
+void RadioButtonGroup::trace(Visitor* visitor)
+{
+ visitor->trace(m_members);
+ visitor->trace(m_checkedButton);
+}
+
+// ----------------------------------------------------------------
+
+// Explicity define empty constructor and destructor in order to prevent the
+// compiler from generating them as inlines. So we don't need to to define
+// RadioButtonGroup in the header.
+RadioButtonGroupScope::RadioButtonGroupScope()
+{
+}
+
+RadioButtonGroupScope::~RadioButtonGroupScope()
+{
+}
+
+void RadioButtonGroupScope::addButton(HTMLInputElement* element)
+{
+ ASSERT(element->isRadioButton());
+ if (element->name().isEmpty())
+ return;
+
+ if (!m_nameToGroupMap)
+ m_nameToGroupMap = adoptPtrWillBeNoop(new NameToGroupMap);
+
+ OwnPtrWillBeMember<RadioButtonGroup>& group = m_nameToGroupMap->add(element->name(), nullptr).storedValue->value;
+ if (!group)
+ group = RadioButtonGroup::create();
+ group->add(element);
+}
+
+void RadioButtonGroupScope::updateCheckedState(HTMLInputElement* element)
+{
+ ASSERT(element->isRadioButton());
+ if (element->name().isEmpty())
+ return;
+ ASSERT(m_nameToGroupMap);
+ if (!m_nameToGroupMap)
+ return;
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
+ ASSERT(group);
+ group->updateCheckedState(element);
+}
+
+void RadioButtonGroupScope::requiredAttributeChanged(HTMLInputElement* element)
+{
+ ASSERT(element->isRadioButton());
+ if (element->name().isEmpty())
+ return;
+ ASSERT(m_nameToGroupMap);
+ if (!m_nameToGroupMap)
+ return;
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
+ ASSERT(group);
+ group->requiredAttributeChanged(element);
+}
+
+HTMLInputElement* RadioButtonGroupScope::checkedButtonForGroup(const AtomicString& name) const
+{
+ if (!m_nameToGroupMap)
+ return 0;
+ RadioButtonGroup* group = m_nameToGroupMap->get(name);
+ return group ? group->checkedButton() : 0;
+}
+
+bool RadioButtonGroupScope::isInRequiredGroup(HTMLInputElement* element) const
+{
+ ASSERT(element->isRadioButton());
+ if (element->name().isEmpty())
+ return false;
+ if (!m_nameToGroupMap)
+ return false;
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
+ return group && group->isRequired() && group->contains(element);
+}
+
+void RadioButtonGroupScope::removeButton(HTMLInputElement* element)
+{
+ ASSERT(element->isRadioButton());
+ if (element->name().isEmpty())
+ return;
+ if (!m_nameToGroupMap)
+ return;
+
+ RadioButtonGroup* group = m_nameToGroupMap->get(element->name());
+ if (!group)
+ return;
+ group->remove(element);
+ if (group->isEmpty()) {
+ // We don't remove an empty RadioButtonGroup from m_nameToGroupMap for
+ // better performance.
+ ASSERT(!group->isRequired());
+ ASSERT_WITH_SECURITY_IMPLICATION(!group->checkedButton());
+ }
+}
+
+void RadioButtonGroupScope::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_nameToGroupMap);
+#endif
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.h b/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.h
new file mode 100644
index 00000000000..41f9bbc7696
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RadioButtonGroupScope.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RadioButtonGroupScope_h
+#define RadioButtonGroupScope_h
+
+#include "platform/heap/Handle.h"
+#include "wtf/Forward.h"
+#include "wtf/HashMap.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+class HTMLInputElement;
+class RadioButtonGroup;
+
+class RadioButtonGroupScope {
+ DISALLOW_ALLOCATION();
+public:
+ RadioButtonGroupScope();
+ ~RadioButtonGroupScope();
+ void trace(Visitor*);
+ void addButton(HTMLInputElement*);
+ void updateCheckedState(HTMLInputElement*);
+ void requiredAttributeChanged(HTMLInputElement*);
+ void removeButton(HTMLInputElement*);
+ HTMLInputElement* checkedButtonForGroup(const AtomicString& groupName) const;
+ bool isInRequiredGroup(HTMLInputElement*) const;
+
+private:
+ typedef WillBeHeapHashMap<AtomicString, OwnPtrWillBeMember<RadioButtonGroup>, CaseFoldingHash> NameToGroupMap;
+ OwnPtrWillBeMember<NameToGroupMap> m_nameToGroupMap;
+};
+
+} // namespace WebCore
+
+#endif // RadioButtonGroupScope_h
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
index fc6da4939fa..9a495ce2446 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.cpp
@@ -22,9 +22,10 @@
#include "config.h"
#include "core/html/forms/RadioInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
+#include "core/dom/Document.h"
+#include "core/dom/ElementTraversal.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
#include "core/html/HTMLInputElement.h"
@@ -36,9 +37,9 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<InputType> RadioInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> RadioInputType::create(HTMLInputElement& element)
{
- return adoptRef(new RadioInputType(element));
+ return adoptRefWillBeNoop(new RadioInputType(element));
}
const AtomicString& RadioInputType::formControlType() const
@@ -83,19 +84,19 @@ void RadioInputType::handleKeydownEvent(KeyboardEvent* event)
// We can only stay within the form's children if the form hasn't been demoted to a leaf because
// of malformed HTML.
- Node* node = &element();
- while ((node = (forward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)))) {
+ HTMLElement* htmlElement = &element();
+ while ((htmlElement = (forward ? Traversal<HTMLElement>::next(*htmlElement) : Traversal<HTMLElement>::previous(*htmlElement)))) {
// Once we encounter a form element, we know we're through.
- if (node->hasTagName(formTag))
+ if (isHTMLFormElement(*htmlElement))
break;
// Look for more radio buttons.
- if (!node->hasTagName(inputTag))
+ if (!isHTMLInputElement(*htmlElement))
continue;
- HTMLInputElement* inputElement = toHTMLInputElement(node);
+ HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
if (inputElement->form() != element().form())
break;
if (inputElement->isRadioButton() && inputElement->name() == element().name() && inputElement->isFocusable()) {
- RefPtr<HTMLInputElement> protector(inputElement);
+ RefPtrWillBeRawPtr<HTMLInputElement> protector(inputElement);
document.setFocusedElement(inputElement);
inputElement->dispatchSimulatedClick(event, SendNoEvents);
event->setDefaultHandled();
@@ -128,9 +129,9 @@ bool RadioInputType::isKeyboardFocusable() const
// Never allow keyboard tabbing to leave you in the same radio group. Always
// skip any other elements in the group.
Element* currentFocusedElement = element().document().focusedElement();
- if (currentFocusedElement && currentFocusedElement->hasTagName(inputTag)) {
- HTMLInputElement* focusedInput = toHTMLInputElement(currentFocusedElement);
- if (focusedInput->isRadioButton() && focusedInput->form() == element().form() && focusedInput->name() == element().name())
+ if (isHTMLInputElement(currentFocusedElement)) {
+ HTMLInputElement& focusedInput = toHTMLInputElement(*currentFocusedElement);
+ if (focusedInput.isRadioButton() && focusedInput.form() == element().form() && focusedInput.name() == element().name())
return false;
}
@@ -145,7 +146,7 @@ bool RadioInputType::shouldSendChangeEventAfterCheckedChanged()
return element().checked();
}
-PassOwnPtr<ClickHandlingState> RadioInputType::willDispatchClick()
+PassOwnPtrWillBeRawPtr<ClickHandlingState> RadioInputType::willDispatchClick()
{
// An event handler can use preventDefault or "return false" to reverse the selection we do here.
// The ClickHandlingState object contains what we need to undo what we did here in didDispatchClick.
@@ -154,7 +155,7 @@ PassOwnPtr<ClickHandlingState> RadioInputType::willDispatchClick()
// Therefore if nothing is currently selected, we won't allow the upcoming action to be "undone", since
// we want some object in the radio group to actually get selected.
- OwnPtr<ClickHandlingState> state = adoptPtr(new ClickHandlingState);
+ OwnPtrWillBeRawPtr<ClickHandlingState> state = adoptPtrWillBeNoop(new ClickHandlingState);
state->checked = element().checked();
state->checkedRadioButton = element().checkedRadioButtonForGroup();
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h
index 09788e2033a..2f965eeef20 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RadioInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class RadioInputType : public BaseCheckableInputType {
+class RadioInputType FINAL : public BaseCheckableInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
RadioInputType(HTMLInputElement& element) : BaseCheckableInputType(element) { }
@@ -49,7 +49,7 @@ private:
virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
virtual bool shouldSendChangeEventAfterCheckedChanged() OVERRIDE;
- virtual PassOwnPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
+ virtual PassOwnPtrWillBeRawPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
virtual void didDispatchClick(Event*, const ClickHandlingState&) OVERRIDE;
virtual bool isRadioButton() const OVERRIDE;
virtual bool supportsIndeterminateAppearance() const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
index 561a6504777..a6c0d34b3b9 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.cpp
@@ -32,9 +32,9 @@
#include "config.h"
#include "core/html/forms/RangeInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
@@ -61,7 +61,6 @@
namespace WebCore {
using namespace HTMLNames;
-using namespace std;
static const int rangeDefaultMinimum = 0;
static const int rangeDefaultMaximum = 100;
@@ -74,9 +73,9 @@ static Decimal ensureMaximum(const Decimal& proposedValue, const Decimal& minimu
return proposedValue >= minimum ? proposedValue : std::max(minimum, fallbackValue);
}
-PassRefPtr<InputType> RangeInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> RangeInputType::create(HTMLInputElement& element)
{
- return adoptRef(new RangeInputType(element));
+ return adoptRefWillBeNoop(new RangeInputType(element));
}
RangeInputType::RangeInputType(HTMLInputElement& element)
@@ -105,9 +104,9 @@ double RangeInputType::valueAsDouble() const
return parseToDoubleForNumberType(element().value());
}
-void RangeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState&) const
+void RangeInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
{
- element().setValue(serialize(newValue), eventBehavior);
+ setValueAsDecimal(Decimal::fromDouble(newValue), eventBehavior, exceptionState);
}
bool RangeInputType::typeMismatchFor(const String& value) const
@@ -124,17 +123,12 @@ StepRange RangeInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (rangeDefaultStep, rangeDefaultStepBase, rangeStepScaleFactor));
+ const Decimal stepBase = findStepBase(rangeDefaultStepBase);
const Decimal minimum = parseToNumber(element().fastGetAttribute(minAttr), rangeDefaultMinimum);
const Decimal maximum = ensureMaximum(parseToNumber(element().fastGetAttribute(maxAttr), rangeDefaultMaximum), minimum, rangeDefaultMaximum);
- const AtomicString& precisionValue = element().fastGetAttribute(precisionAttr);
- if (!precisionValue.isNull()) {
- const Decimal step = equalIgnoringCase(precisionValue, "float") ? Decimal::nan() : 1;
- return StepRange(minimum, minimum, maximum, step, stepDescription);
- }
-
const Decimal step = StepRange::parseStep(anyStepHandling, stepDescription, element().fastGetAttribute(stepAttr));
- return StepRange(minimum, minimum, maximum, step, stepDescription);
+ return StepRange(stepBase, minimum, maximum, step, stepDescription);
}
bool RangeInputType::isSteppable() const
@@ -165,6 +159,7 @@ void RangeInputType::handleTouchEvent(TouchEvent* event)
return;
if (event->type() == EventTypeNames::touchend) {
+ element().dispatchFormControlChangeEvent();
event->setDefaultHandled();
return;
}
@@ -197,12 +192,12 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
// FIXME: We can't use stepUp() for the step value "any". So, we increase
// or decrease the value by 1/100 of the value range. Is it reasonable?
const Decimal step = equalIgnoringCase(element().fastGetAttribute(stepAttr), "any") ? (stepRange.maximum() - stepRange.minimum()) / 100 : stepRange.step();
- const Decimal bigStep = max((stepRange.maximum() - stepRange.minimum()) / 10, step);
+ const Decimal bigStep = std::max((stepRange.maximum() - stepRange.minimum()) / 10, step);
bool isVertical = false;
if (element().renderer()) {
ControlPart part = element().renderer()->style()->appearance();
- isVertical = part == SliderVerticalPart || part == MediaVolumeSliderPart;
+ isVertical = part == SliderVerticalPart;
}
Decimal newValue;
@@ -229,12 +224,11 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent* event)
if (newValue != current) {
EventQueueScope scope;
- TextFieldEventBehavior eventBehavior = DispatchChangeEvent;
+ TextFieldEventBehavior eventBehavior = DispatchInputAndChangeEvent;
setValueAsDecimal(newValue, eventBehavior, IGNORE_EXCEPTION);
if (AXObjectCache* cache = element().document().existingAXObjectCache())
cache->postNotification(&element(), AXObjectCache::AXValueChanged, true);
- element().dispatchFormControlChangeEvent();
}
event->setDefaultHandled();
@@ -245,11 +239,11 @@ void RangeInputType::createShadowSubtree()
ASSERT(element().shadow());
Document& document = element().document();
- RefPtr<HTMLDivElement> track = HTMLDivElement::create(document);
- track->setPseudo(AtomicString("-webkit-slider-runnable-track", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<HTMLDivElement> track = HTMLDivElement::create(document);
+ track->setShadowPseudoId(AtomicString("-webkit-slider-runnable-track", AtomicString::ConstructFromLiteral));
track->setAttribute(idAttr, ShadowElementNames::sliderTrack());
track->appendChild(SliderThumbElement::create(document));
- RefPtr<HTMLElement> container = SliderContainerElement::create(document);
+ RefPtrWillBeRawPtr<HTMLElement> container = SliderContainerElement::create(document);
container->appendChild(track.release());
element().userAgentShadowRoot()->appendChild(container.release());
}
@@ -317,7 +311,7 @@ void RangeInputType::disabledAttributeChanged()
bool RangeInputType::shouldRespectListAttribute()
{
- return InputType::themeSupportsDataListUI(this);
+ return true;
}
inline SliderThumbElement* RangeInputType::sliderThumbElement() const
@@ -335,7 +329,7 @@ void RangeInputType::listAttributeTargetChanged()
m_tickMarkValuesDirty = true;
Element* sliderTrackElement = this->sliderTrackElement();
if (sliderTrackElement->renderer())
- sliderTrackElement->renderer()->setNeedsLayout();
+ sliderTrackElement->renderer()->setNeedsLayoutAndFullPaintInvalidation();
}
static bool decimalCompare(const Decimal& a, const Decimal& b)
@@ -352,13 +346,13 @@ void RangeInputType::updateTickMarkValues()
HTMLDataListElement* dataList = element().dataList();
if (!dataList)
return;
- RefPtr<HTMLCollection> options = dataList->options();
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
m_tickMarkValues.reserveCapacity(options->length());
for (unsigned i = 0; i < options->length(); ++i) {
- Node* node = options->item(i);
- HTMLOptionElement* optionElement = toHTMLOptionElement(node);
+ Element* element = options->item(i);
+ HTMLOptionElement* optionElement = toHTMLOptionElement(element);
String optionValue = optionElement->value();
- if (!element().isValidValue(optionValue))
+ if (!this->element().isValidValue(optionValue))
continue;
m_tickMarkValues.append(parseToNumber(optionValue, Decimal::nan()));
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h
index cb10f784e3e..2cd9f71892a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/RangeInputType.h
@@ -38,9 +38,9 @@ namespace WebCore {
class ExceptionState;
class SliderThumbElement;
-class RangeInputType : public InputType {
+class RangeInputType FINAL : public InputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
RangeInputType(HTMLInputElement&);
@@ -48,7 +48,7 @@ private:
virtual bool isRangeControl() const OVERRIDE;
virtual const AtomicString& formControlType() const OVERRIDE;
virtual double valueAsDouble() const OVERRIDE;
- virtual void setValueAsDecimal(const Decimal&, TextFieldEventBehavior, ExceptionState&) const OVERRIDE;
+ virtual void setValueAsDouble(double, TextFieldEventBehavior, ExceptionState&) const OVERRIDE;
virtual bool typeMismatchFor(const String&) const OVERRIDE;
virtual bool supportsRequired() const OVERRIDE;
virtual StepRange createStepRange(AnyStepHandling) const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp
index 6175a6c95e9..bb9de0774fc 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/ResetInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/Event.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLInputElement.h"
@@ -41,9 +41,9 @@
namespace WebCore {
-PassRefPtr<InputType> ResetInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> ResetInputType::create(HTMLInputElement& element)
{
- return adoptRef(new ResetInputType(element));
+ return adoptRefWillBeNoop(new ResetInputType(element));
}
const AtomicString& ResetInputType::formControlType() const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h
index 8837400b86e..e30b91cd6fc 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ResetInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class ResetInputType : public BaseButtonInputType {
+class ResetInputType FINAL : public BaseButtonInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
ResetInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp
index ba6e85aab40..a5563cee2d5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "core/html/forms/SearchInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/KeyboardEvent.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/html/HTMLInputElement.h"
@@ -52,9 +52,9 @@ inline SearchInputType::SearchInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> SearchInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> SearchInputType::create(HTMLInputElement& element)
{
- return adoptRef(new SearchInputType(element));
+ return adoptRefWillBeNoop(new SearchInputType(element));
}
void SearchInputType::countUsage()
@@ -108,7 +108,7 @@ void SearchInputType::handleKeydownEvent(KeyboardEvent* event)
const String& key = event->keyIdentifier();
if (key == "U+001B") {
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
input->setValueForUser("");
input->onSearch();
event->setDefaultHandled();
@@ -120,7 +120,7 @@ void SearchInputType::handleKeydownEvent(KeyboardEvent* event)
void SearchInputType::startSearchEventTimer()
{
ASSERT(element().renderer());
- unsigned length = element().innerTextValue().length();
+ unsigned length = element().innerEditorValue().length();
if (!length) {
stopSearchEventTimer();
@@ -130,7 +130,7 @@ void SearchInputType::startSearchEventTimer()
// After typing the first key, we wait 0.5 seconds.
// After the second key, 0.4 seconds, then 0.3, then 0.2 from then on.
- m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length));
+ m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length), FROM_HERE);
}
void SearchInputType::stopSearchEventTimer()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h
index d13c0f94c42..6687f6d6901 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/SearchInputType.h
@@ -39,9 +39,9 @@ namespace WebCore {
class SearchFieldCancelButtonElement;
class SearchFieldDecorationElement;
-class SearchInputType : public BaseTextInputType {
+class SearchInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
void stopSearchEventTimer();
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp b/chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp
index 0e10a5f162f..32761459cd1 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/StepRange.cpp
@@ -21,14 +21,12 @@
#include "config.h"
#include "core/html/forms/StepRange.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "wtf/MathExtras.h"
#include "wtf/text/WTFString.h"
#include <float.h>
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -84,12 +82,12 @@ Decimal StepRange::alignValueForStep(const Decimal& currentValue, const Decimal&
Decimal StepRange::clampValue(const Decimal& value) const
{
- const Decimal inRangeValue = max(m_minimum, min(value, m_maximum));
+ const Decimal inRangeValue = std::max(m_minimum, std::min(value, m_maximum));
if (!m_hasStep)
return inRangeValue;
- // Rounds inRangeValue to minimum + N * step.
- const Decimal roundedValue = roundByStep(inRangeValue, m_minimum);
- const Decimal clampedValue = roundedValue > m_maximum ? roundedValue - m_step : roundedValue;
+ // Rounds inRangeValue to stepBase + N * step.
+ const Decimal roundedValue = roundByStep(inRangeValue, m_stepBase);
+ const Decimal clampedValue = roundedValue > m_maximum ? roundedValue - m_step : (roundedValue < m_minimum ? roundedValue + m_step : roundedValue);
ASSERT(clampedValue >= m_minimum);
ASSERT(clampedValue <= m_maximum);
return clampedValue;
@@ -121,13 +119,13 @@ Decimal StepRange::parseStep(AnyStepHandling anyStepHandling, const StepDescript
break;
case ParsedStepValueShouldBeInteger:
// For date, month, and week, the parsed value should be an integer for some types.
- step = max(step.round(), Decimal(1));
+ step = std::max(step.round(), Decimal(1));
step *= stepDescription.stepScaleFactor;
break;
case ScaledStepValueShouldBeInteger:
// For datetime, datetime-local, time, the result should be an integer.
step *= stepDescription.stepScaleFactor;
- step = max(step.round(), Decimal(1));
+ step = std::max(step.round(), Decimal(1));
break;
default:
ASSERT_NOT_REACHED();
@@ -161,7 +159,7 @@ bool StepRange::stepMismatch(const Decimal& valueForCheck) const
// ... that number subtracted from the step base is not an integral multiple
// of the allowed value step, the element is suffering from a step mismatch.
const Decimal remainder = (value - m_step * (value / m_step).round()).abs();
- // Accepts erros in lower fractional part which IEEE 754 single-precision
+ // Accepts errors in lower fractional part which IEEE 754 single-precision
// can't represent.
const Decimal computedAcceptableError = acceptableError();
return computedAcceptableError < remainder && remainder < (m_step - computedAcceptableError);
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/StepRange.h b/chromium/third_party/WebKit/Source/core/html/forms/StepRange.h
index a31e264c281..f2fdbb2dfde 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/StepRange.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/StepRange.h
@@ -71,7 +71,6 @@ public:
StepRange();
StepRange(const StepRange&);
StepRange(const Decimal& stepBase, const Decimal& minimum, const Decimal& maximum, const Decimal& step, const StepDescription&);
- Decimal acceptableError() const;
Decimal alignValueForStep(const Decimal& currentValue, const Decimal& newValue) const;
Decimal clampValue(const Decimal& value) const;
bool hasStep() const { return m_hasStep; }
@@ -80,7 +79,6 @@ public:
static Decimal parseStep(AnyStepHandling, const StepDescription&, const String&);
Decimal step() const { return m_step; }
Decimal stepBase() const { return m_stepBase; }
- int stepScaleFactor() const { return m_stepDescription.stepScaleFactor; }
bool stepMismatch(const Decimal&) const;
// Clamp the middle value according to the step
@@ -106,6 +104,7 @@ public:
private:
StepRange& operator =(const StepRange&);
+ Decimal acceptableError() const;
Decimal roundByStep(const Decimal& value, const Decimal& base) const;
const Decimal m_maximum; // maximum must be >= minimum.
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp
index 3b25b468ec1..8ef131314a5 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.cpp
@@ -32,7 +32,7 @@
#include "config.h"
#include "core/html/forms/SubmitInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/events/Event.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLFormElement.h"
@@ -42,9 +42,9 @@
namespace WebCore {
-PassRefPtr<InputType> SubmitInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> SubmitInputType::create(HTMLInputElement& element)
{
- return adoptRef(new SubmitInputType(element));
+ return adoptRefWillBeNoop(new SubmitInputType(element));
}
const AtomicString& SubmitInputType::formControlType() const
@@ -67,7 +67,7 @@ bool SubmitInputType::supportsRequired() const
void SubmitInputType::handleDOMActivateEvent(Event* event)
{
- RefPtr<HTMLInputElement> element(this->element());
+ RefPtrWillBeRawPtr<HTMLInputElement> element(this->element());
if (element->isDisabledFormControl() || !element->form())
return;
element->setActivatedSubmit(true);
@@ -86,11 +86,6 @@ String SubmitInputType::defaultValue() const
return locale().queryString(blink::WebLocalizedString::SubmitButtonDefaultLabel);
}
-bool SubmitInputType::isSubmitButton() const
-{
- return true;
-}
-
bool SubmitInputType::isTextButton() const
{
return true;
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h
index ea88704fe9e..169117c2155 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/SubmitInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class SubmitInputType : public BaseButtonInputType {
+class SubmitInputType FINAL : public BaseButtonInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
SubmitInputType(HTMLInputElement& element) : BaseButtonInputType(element) { }
@@ -47,7 +47,6 @@ private:
virtual void handleDOMActivateEvent(Event*) OVERRIDE;
virtual bool canBeSuccessfulSubmitButton() OVERRIDE;
virtual String defaultValue() const OVERRIDE;
- virtual bool isSubmitButton() const OVERRIDE;
virtual bool isTextButton() const OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp
index 4b5e2edbd48..4d11d9e896a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.cpp
@@ -31,14 +31,14 @@
#include "config.h"
#include "core/html/forms/TelephoneInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
-PassRefPtr<InputType> TelephoneInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> TelephoneInputType::create(HTMLInputElement& element)
{
- return adoptRef(new TelephoneInputType(element));
+ return adoptRefWillBeNoop(new TelephoneInputType(element));
}
void TelephoneInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h
index d636ee2bff6..dca6c4fc39a 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TelephoneInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class TelephoneInputType : public BaseTextInputType {
+class TelephoneInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
TelephoneInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
index 0114adab3e8..2b61994d4a8 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.cpp
@@ -32,24 +32,23 @@
#include "config.h"
#include "core/html/forms/TextFieldInputType.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/events/BeforeTextInsertedEvent.h"
-#include "core/events/KeyboardEvent.h"
+#include "core/HTMLNames.h"
#include "core/dom/NodeRenderStyle.h"
-#include "core/events/TextEvent.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/TextIterator.h"
+#include "core/events/BeforeTextInsertedEvent.h"
+#include "core/events/KeyboardEvent.h"
+#include "core/events/TextEvent.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/FormDataList.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/html/shadow/TextControlInnerElements.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
#include "core/rendering/RenderDetailsMarker.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderTextControlSingleLine.h"
@@ -83,25 +82,26 @@ private:
virtual void defaultEventHandler(Event* event) OVERRIDE
{
+ ASSERT(document().isActive());
if (event->type() != EventTypeNames::click)
return;
HTMLInputElement* host = hostInput();
- if (host && !host->isDisabledOrReadOnly() && document().page()) {
- document().page()->chrome().openTextDataListChooser(*host);
+ if (host && !host->isDisabledOrReadOnly()) {
+ document().frameHost()->chrome().openTextDataListChooser(*host);
event->setDefaultHandled();
}
}
virtual bool willRespondToMouseClickEvents() OVERRIDE
{
- return hostInput() && !hostInput()->isDisabledOrReadOnly() && document().page();
+ return hostInput() && !hostInput()->isDisabledOrReadOnly() && document().isActive();
}
public:
- static PassRefPtr<DataListIndicatorElement> create(Document& document)
+ static PassRefPtrWillBeRawPtr<DataListIndicatorElement> create(Document& document)
{
- RefPtr<DataListIndicatorElement> element = adoptRef(new DataListIndicatorElement(document));
- element->setPseudo(AtomicString("-webkit-calendar-picker-indicator", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<DataListIndicatorElement> element = adoptRefWillBeNoop(new DataListIndicatorElement(document));
+ element->setShadowPseudoId(AtomicString("-webkit-calendar-picker-indicator", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::pickerIndicator());
return element.release();
}
@@ -115,8 +115,10 @@ TextFieldInputType::TextFieldInputType(HTMLInputElement& element)
TextFieldInputType::~TextFieldInputType()
{
+#if !ENABLE(OILPAN)
if (SpinButtonElement* spinButton = spinButtonElement())
spinButton->removeSpinButtonOwner();
+#endif
}
SpinButtonElement* TextFieldInputType::spinButtonElement() const
@@ -134,18 +136,9 @@ bool TextFieldInputType::isTextField() const
return true;
}
-static inline bool shouldIgnoreRequiredAttribute(const HTMLInputElement& input)
-{
- if (!input.document().settings() || !input.document().settings()->needsSiteSpecificQuirks())
- return false;
- if (!equalIgnoringCase(input.document().url().host(), "egov.uscis.gov"))
- return false;
- return input.fastGetAttribute(requiredAttr) == "no";
-}
-
bool TextFieldInputType::valueMissing(const String& value) const
{
- return !shouldIgnoreRequiredAttribute(element()) && element().isRequired() && value.isEmpty();
+ return element().isRequired() && value.isEmpty();
}
bool TextFieldInputType::canSetSuggestedValue()
@@ -157,14 +150,14 @@ void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChange
{
// Grab this input element to keep reference even if JS event handler
// changes input type.
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
// We don't ask InputType::setValue to dispatch events because
// TextFieldInputType dispatches events different way from InputType.
InputType::setValue(sanitizedValue, valueChanged, DispatchNoEvent);
if (valueChanged)
- updateView();
+ input->updateView();
unsigned max = visibleValue().length();
if (input->focused())
@@ -217,10 +210,11 @@ void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent* event)
const String& key = event->keyIdentifier();
if (key == "Up")
spinButtonStepUp();
- else if (key == "Down")
+ else if (key == "Down" && !event->altKey())
spinButtonStepDown();
else
return;
+ element().dispatchFormControlChangeEvent();
event->setDefaultHandled();
}
@@ -235,12 +229,13 @@ void TextFieldInputType::forwardEvent(Event* event)
if (element().renderer() && (event->isMouseEvent() || event->isDragEvent() || event->hasInterface(EventNames::WheelEvent) || event->type() == EventTypeNames::blur || event->type() == EventTypeNames::focus)) {
RenderTextControlSingleLine* renderTextControl = toRenderTextControlSingleLine(element().renderer());
if (event->type() == EventTypeNames::blur) {
- if (RenderBox* innerTextRenderer = element().innerTextElement()->renderBox()) {
+ if (RenderBox* innerEditorRenderer = element().innerEditorElement()->renderBox()) {
// FIXME: This class has no need to know about RenderLayer!
- if (RenderLayer* innerLayer = innerTextRenderer->layer()) {
- RenderLayerScrollableArea* innerScrollableArea = innerLayer->scrollableArea();
- IntSize scrollOffset(!renderTextControl->style()->isLeftToRightDirection() ? innerScrollableArea->scrollWidth() : 0, 0);
- innerScrollableArea->scrollToOffset(scrollOffset, ScrollOffsetClamped);
+ if (RenderLayer* innerLayer = innerEditorRenderer->layer()) {
+ if (RenderLayerScrollableArea* innerScrollableArea = innerLayer->scrollableArea()) {
+ IntSize scrollOffset(!renderTextControl->style()->isLeftToRightDirection() ? innerScrollableArea->scrollWidth().toInt() : 0, 0);
+ innerScrollableArea->scrollToOffset(scrollOffset, ScrollOffsetClamped);
+ }
}
}
@@ -253,9 +248,9 @@ void TextFieldInputType::forwardEvent(Event* event)
}
}
-void TextFieldInputType::handleFocusEvent(Element* oldFocusedNode, FocusDirection focusDirection)
+void TextFieldInputType::handleFocusEvent(Element* oldFocusedNode, FocusType focusType)
{
- InputType::handleFocusEvent(oldFocusedNode, focusDirection);
+ InputType::handleFocusEvent(oldFocusedNode, focusType);
element().beginEditing();
}
@@ -263,6 +258,8 @@ void TextFieldInputType::handleBlurEvent()
{
InputType::handleBlurEvent();
element().endEditing();
+ if (SpinButtonElement *spinButton = spinButtonElement())
+ spinButton->releaseCapture();
}
bool TextFieldInputType::shouldSubmitImplicitly(Event* event)
@@ -275,15 +272,6 @@ RenderObject* TextFieldInputType::createRenderer(RenderStyle*) const
return new RenderTextControlSingleLine(&element());
}
-bool TextFieldInputType::needsContainer() const
-{
-#if ENABLE(INPUT_SPEECH)
- return element().isSpeechEnabled();
-#else
- return false;
-#endif
-}
-
bool TextFieldInputType::shouldHaveSpinButton() const
{
return RenderTheme::theme().shouldHaveSpinButton(&element());
@@ -293,32 +281,27 @@ void TextFieldInputType::createShadowSubtree()
{
ASSERT(element().shadow());
ShadowRoot* shadowRoot = element().userAgentShadowRoot();
- ASSERT(!shadowRoot->hasChildNodes());
+ ASSERT(!shadowRoot->hasChildren());
Document& document = element().document();
bool shouldHaveSpinButton = this->shouldHaveSpinButton();
bool shouldHaveDataListIndicator = element().hasValidDataListOptions();
bool createsContainer = shouldHaveSpinButton || shouldHaveDataListIndicator || needsContainer();
- RefPtr<TextControlInnerTextElement> innerEditor = TextControlInnerTextElement::create(document);
+ RefPtrWillBeRawPtr<TextControlInnerEditorElement> innerEditor = TextControlInnerEditorElement::create(document);
if (!createsContainer) {
shadowRoot->appendChild(innerEditor.release());
return;
}
- RefPtr<TextControlInnerContainer> container = TextControlInnerContainer::create(document);
- container->setPseudo(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<TextControlInnerContainer> container = TextControlInnerContainer::create(document);
+ container->setShadowPseudoId(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
shadowRoot->appendChild(container);
- RefPtr<EditingViewPortElement> editingViewPort = EditingViewPortElement::create(document);
+ RefPtrWillBeRawPtr<EditingViewPortElement> editingViewPort = EditingViewPortElement::create(document);
editingViewPort->appendChild(innerEditor.release());
container->appendChild(editingViewPort.release());
-#if ENABLE(INPUT_SPEECH)
- if (element().isSpeechEnabled())
- container->appendChild(InputFieldSpeechButtonElement::create(document));
-#endif
-
if (shouldHaveDataListIndicator)
container->appendChild(DataListIndicatorElement::create(document));
// FIXME: Because of a special handling for a spin button in
@@ -357,14 +340,16 @@ void TextFieldInputType::listAttributeTargetChanged()
// FIXME: The following code is similar to createShadowSubtree(),
// but they are different. We should simplify the code by making
// containerElement mandatory.
- RefPtr<Element> rpContainer = TextControlInnerContainer::create(document);
- rpContainer->setPseudo(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
- RefPtr<Element> innerEditor = element().innerTextElement();
+ RefPtrWillBeRawPtr<Element> rpContainer = TextControlInnerContainer::create(document);
+ rpContainer->setShadowPseudoId(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<Element> innerEditor = element().innerEditorElement();
innerEditor->parentNode()->replaceChild(rpContainer.get(), innerEditor.get());
- RefPtr<Element> editingViewPort = EditingViewPortElement::create(document);
+ RefPtrWillBeRawPtr<Element> editingViewPort = EditingViewPortElement::create(document);
editingViewPort->appendChild(innerEditor.release());
rpContainer->appendChild(editingViewPort.release());
rpContainer->appendChild(DataListIndicatorElement::create(document));
+ if (element().document().focusedElement() == element())
+ element().updateFocusAppearance(true /* restore selection */);
}
} else {
picker->remove(ASSERT_NO_EXCEPTION);
@@ -408,15 +393,6 @@ static bool isASCIILineBreak(UChar c)
static String limitLength(const String& string, unsigned maxLength)
{
unsigned newLength = std::min(maxLength, string.length());
- // FIXME: We should not truncate the string at a control character. It's not
- // compatible with IE and Firefox.
- for (unsigned i = 0; i < newLength; ++i) {
- const UChar current = string[i];
- if (current < ' ' && current != '\t') {
- newLength = i;
- break;
- }
- }
if (newLength == string.length())
return string;
if (newLength > 0 && U16_IS_LEAD(string[newLength - 1]))
@@ -433,10 +409,10 @@ void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
{
// Make sure that the text to be inserted will not violate the maxLength.
- // We use HTMLInputElement::innerTextValue() instead of
+ // We use HTMLInputElement::innerEditorValue() instead of
// HTMLInputElement::value() because they can be mismatched by
// sanitizeValue() in HTMLInputElement::subtreeHasChanged() in some cases.
- unsigned oldLength = element().innerTextValue().length();
+ unsigned oldLength = element().innerEditorValue().length();
// selectionLength represents the selection length of this text field to be
// removed by this insertion.
@@ -466,7 +442,7 @@ void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*
bool TextFieldInputType::shouldRespectListAttribute()
{
- return InputType::themeSupportsDataListUI(this);
+ return true;
}
void TextFieldInputType::updatePlaceholderText()
@@ -481,12 +457,12 @@ void TextFieldInputType::updatePlaceholderText()
return;
}
if (!placeholder) {
- RefPtr<HTMLElement> newElement = HTMLDivElement::create(element().document());
+ RefPtrWillBeRawPtr<HTMLElement> newElement = HTMLDivElement::create(element().document());
placeholder = newElement.get();
- placeholder->setPseudo(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
+ placeholder->setShadowPseudoId(AtomicString("-webkit-input-placeholder", AtomicString::ConstructFromLiteral));
placeholder->setAttribute(idAttr, ShadowElementNames::placeholder());
Element* container = containerElement();
- Node* previous = container ? container : element().innerTextElement();
+ Node* previous = container ? container : element().innerEditorElement();
previous->parentNode()->insertBefore(placeholder, previous->nextSibling());
ASSERT_WITH_SECURITY_IMPLICATION(placeholder->parentNode() == previous->parentNode());
}
@@ -518,10 +494,10 @@ void TextFieldInputType::subtreeHasChanged()
// HTMLInputElement::handleBeforeTextInsertedEvent() has already called
// sanitizeUserInputValue().
// sanitizeValue() is needed because IME input doesn't dispatch BeforeTextInsertedEvent.
- element().setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element().innerTextValue())));
+ element().setValueFromRenderer(sanitizeValue(convertFromVisibleValue(element().innerEditorValue())));
element().updatePlaceholderVisibility(false);
// Recalc for :invalid change.
- element().setNeedsStyleRecalc();
+ element().setNeedsStyleRecalc(SubtreeStyleChange);
didSetValueByUserEdit(wasChanged ? ValueChangeStateChanged : ValueChangeStateNone);
}
@@ -547,19 +523,23 @@ void TextFieldInputType::spinButtonStepUp()
void TextFieldInputType::updateView()
{
if (!element().suggestedValue().isNull()) {
- element().setInnerTextValue(element().suggestedValue());
+ element().setInnerEditorValue(element().suggestedValue());
element().updatePlaceholderVisibility(false);
- } else if (!element().formControlValueMatchesRenderer()) {
- // Update the renderer value if the formControlValueMatchesRenderer() flag is false.
- // It protects an unacceptable renderer value from being overwritten with the DOM value.
- element().setInnerTextValue(visibleValue());
+ } else if (element().needsToUpdateViewValue()) {
+ // Update the view only if needsToUpdateViewValue is true. It protects
+ // an unacceptable view value from being overwritten with the DOM value.
+ //
+ // e.g. <input type=number> has a view value "abc", and input.max is
+ // updated. In this case, updateView() is called but we should not
+ // update the view value.
+ element().setInnerEditorValue(visibleValue());
element().updatePlaceholderVisibility(false);
}
}
void TextFieldInputType::focusAndSelectSpinButtonOwner()
{
- RefPtr<HTMLInputElement> input(element());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(element());
input->focus();
input->select();
}
@@ -574,4 +554,10 @@ bool TextFieldInputType::shouldSpinButtonRespondToWheelEvents()
return shouldSpinButtonRespondToMouseEvents() && element().focused();
}
+void TextFieldInputType::spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch eventDispatch)
+{
+ if (eventDispatch == SpinButtonElement::EventDispatchAllowed)
+ element().dispatchFormControlChangeEvent();
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h
index 38d5d9ed57f..0eb1fda2d4c 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TextFieldInputType.h
@@ -41,6 +41,7 @@ class FormDataList;
// The class represents types of which UI contain text fields.
// It supports not only the types for BaseTextInputType but also type=number.
class TextFieldInputType : public InputType, protected SpinButtonElement::SpinButtonOwner {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TextFieldInputType);
protected:
TextFieldInputType(HTMLInputElement&);
virtual ~TextFieldInputType();
@@ -49,16 +50,16 @@ protected:
void handleKeydownEventForSpinButton(KeyboardEvent*);
protected:
- virtual bool needsContainer() const;
- virtual bool shouldHaveSpinButton() const;
+ virtual bool needsContainer() const { return false; }
+ bool shouldHaveSpinButton() const;
virtual void createShadowSubtree() OVERRIDE;
virtual void destroyShadowSubtree() OVERRIDE;
virtual void attributeChanged() OVERRIDE;
virtual void disabledAttributeChanged() OVERRIDE;
virtual void readonlyAttributeChanged() OVERRIDE;
virtual bool supportsReadOnly() const OVERRIDE;
- virtual void handleFocusEvent(Element* oldFocusedNode, FocusDirection) OVERRIDE;
- virtual void handleBlurEvent() OVERRIDE;
+ virtual void handleFocusEvent(Element* oldFocusedNode, FocusType) OVERRIDE FINAL;
+ virtual void handleBlurEvent() OVERRIDE FINAL;
virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) OVERRIDE;
virtual void updateView() OVERRIDE;
@@ -72,27 +73,28 @@ protected:
Element* containerElement() const;
private:
- virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE;
- virtual bool isTextField() const OVERRIDE;
+ virtual bool shouldShowFocusRingOnMouseFocus() const OVERRIDE FINAL;
+ virtual bool isTextField() const OVERRIDE FINAL;
virtual bool valueMissing(const String&) const OVERRIDE;
virtual void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent*) OVERRIDE;
- virtual void forwardEvent(Event*) OVERRIDE;
- virtual bool shouldSubmitImplicitly(Event*) OVERRIDE;
+ virtual void forwardEvent(Event*) OVERRIDE FINAL;
+ virtual bool shouldSubmitImplicitly(Event*) OVERRIDE FINAL;
virtual RenderObject* createRenderer(RenderStyle*) const OVERRIDE;
virtual bool shouldUseInputMethod() const OVERRIDE;
virtual String sanitizeValue(const String&) const OVERRIDE;
virtual bool shouldRespectListAttribute() OVERRIDE;
virtual void listAttributeTargetChanged() OVERRIDE;
- virtual void updatePlaceholderText() OVERRIDE;
+ virtual void updatePlaceholderText() OVERRIDE FINAL;
virtual bool appendFormData(FormDataList&, bool multipart) const OVERRIDE;
- virtual void subtreeHasChanged() OVERRIDE;
+ virtual void subtreeHasChanged() OVERRIDE FINAL;
// SpinButtonElement::SpinButtonOwner functions.
- virtual void focusAndSelectSpinButtonOwner() OVERRIDE;
- virtual bool shouldSpinButtonRespondToMouseEvents() OVERRIDE;
- virtual bool shouldSpinButtonRespondToWheelEvents() OVERRIDE;
- virtual void spinButtonStepDown() OVERRIDE;
- virtual void spinButtonStepUp() OVERRIDE;
+ virtual void focusAndSelectSpinButtonOwner() OVERRIDE FINAL;
+ virtual bool shouldSpinButtonRespondToMouseEvents() OVERRIDE FINAL;
+ virtual bool shouldSpinButtonRespondToWheelEvents() OVERRIDE FINAL;
+ virtual void spinButtonStepDown() OVERRIDE FINAL;
+ virtual void spinButtonStepUp() OVERRIDE FINAL;
+ virtual void spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch) OVERRIDE FINAL;
SpinButtonElement* spinButtonElement() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp
index a5e9db19398..b39a4ccbcd0 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "core/html/forms/TextInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "wtf/PassOwnPtr.h"
@@ -39,9 +39,9 @@ namespace WebCore {
using namespace HTMLNames;
-PassRefPtr<InputType> TextInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> TextInputType::create(HTMLInputElement& element)
{
- return adoptRef(new TextInputType(element));
+ return adoptRefWillBeNoop(new TextInputType(element));
}
void TextInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h
index 8fb1e8c2447..75608bd2ee2 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TextInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class TextInputType : public BaseTextInputType {
+class TextInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
TextInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp
index 22d80ef7e1e..ae3203eabc8 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/html/forms/TimeInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -56,9 +56,9 @@ TimeInputType::TimeInputType(HTMLInputElement& element)
{
}
-PassRefPtr<InputType> TimeInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> TimeInputType::create(HTMLInputElement& element)
{
- return adoptRef(new TimeInputType(element));
+ return adoptRefWillBeNoop(new TimeInputType(element));
}
void TimeInputType::countUsage()
@@ -90,7 +90,7 @@ StepRange TimeInputType::createStepRange(AnyStepHandling anyStepHandling) const
{
DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (timeDefaultStep, timeDefaultStepBase, timeStepScaleFactor, StepRange::ScaledStepValueShouldBeInteger));
- return InputType::createStepRange(anyStepHandling, 0, Decimal::fromDouble(DateComponents::minimumTime()), Decimal::fromDouble(DateComponents::maximumTime()), stepDescription);
+ return InputType::createStepRange(anyStepHandling, timeDefaultStepBase, Decimal::fromDouble(DateComponents::minimumTime()), Decimal::fromDouble(DateComponents::maximumTime()), stepDescription);
}
bool TimeInputType::parseToDateComponentsInternal(const String& string, DateComponents* out) const
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h
index 82a540d52f6..b8d3f111ca3 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TimeInputType.h
@@ -42,9 +42,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseTimeInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseTimeInputType;
#endif
-class TimeInputType : public BaseTimeInputType {
+class TimeInputType FINAL : public BaseTimeInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
TimeInputType(HTMLInputElement&);
@@ -59,9 +59,9 @@ private:
virtual String localizeValue(const String&) const OVERRIDE;
// BaseMultipleFieldsDateAndTimeInputType functions
- virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE FINAL;
- virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE FINAL;
- virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const;
+ virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE;
+ virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE;
+ virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp b/chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp
index e9a0052edad..673b88956ce 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/TypeAhead.cpp
@@ -50,7 +50,7 @@ static String stripLeadingWhiteSpace(const String& string)
unsigned i;
for (i = 0; i < length; ++i) {
- if (string[i] != noBreakSpace && (string[i] <= 0x7F ? !isASCIISpace(string[i]) : (direction(string[i]) != WhiteSpaceNeutral)))
+ if (string[i] != noBreakSpace && !isSpaceOrNewline(string[i]))
break;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp
index 33017eb34c7..c39d40c5301 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.cpp
@@ -31,16 +31,16 @@
#include "config.h"
#include "core/html/forms/URLInputType.h"
-#include "InputTypeNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "platform/text/PlatformLocale.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
-PassRefPtr<InputType> URLInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> URLInputType::create(HTMLInputElement& element)
{
- return adoptRef(new URLInputType(element));
+ return adoptRefWillBeNoop(new URLInputType(element));
}
void URLInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h
index 98f53f21b38..e11143fc6c4 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/URLInputType.h
@@ -35,9 +35,9 @@
namespace WebCore {
-class URLInputType : public BaseTextInputType {
+class URLInputType FINAL : public BaseTextInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
URLInputType(HTMLInputElement& element) : BaseTextInputType(element) { }
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp b/chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp
index 57ee0eb6b8f..df7475f4c3e 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "core/html/forms/ValidationMessage.h"
+#include "core/dom/Document.h"
#include "core/html/HTMLFormControlElement.h"
#include "core/page/Page.h"
#include "core/page/ValidationMessageClient.h"
@@ -46,8 +47,6 @@ ALWAYS_INLINE ValidationMessage::ValidationMessage(HTMLFormControlElement* eleme
ValidationMessage::~ValidationMessage()
{
- if (ValidationMessageClient* client = validationMessageClient())
- client->hideValidationMessage(*m_element);
}
PassOwnPtr<ValidationMessage> ValidationMessage::create(HTMLFormControlElement* element)
@@ -60,9 +59,8 @@ ValidationMessageClient* ValidationMessage::validationMessageClient() const
Page* page = m_element->document().page();
if (!page)
return 0;
- // The form valdiation feature requires ValidationMessageClient.
- ASSERT(page->validationMessageClient());
- return page->validationMessageClient();
+
+ return &page->validationMessageClient();
}
void ValidationMessage::updateValidationMessage(const String& message)
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp b/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp
index 419b1603ddc..e49651ed71e 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/html/forms/WeekInputType.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/DateTimeFieldsState.h"
#include "platform/DateComponents.h"
@@ -48,9 +48,9 @@ static const int weekDefaultStepBase = -259200000; // The first day of 1970-W01.
static const int weekDefaultStep = 1;
static const int weekStepScaleFactor = 604800000;
-PassRefPtr<InputType> WeekInputType::create(HTMLInputElement& element)
+PassRefPtrWillBeRawPtr<InputType> WeekInputType::create(HTMLInputElement& element)
{
- return adoptRef(new WeekInputType(element));
+ return adoptRefWillBeNoop(new WeekInputType(element));
}
void WeekInputType::countUsage()
diff --git a/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h b/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h
index 9455039c61a..f3360f27404 100644
--- a/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h
+++ b/chromium/third_party/WebKit/Source/core/html/forms/WeekInputType.h
@@ -42,9 +42,9 @@ typedef BaseMultipleFieldsDateAndTimeInputType BaseWeekInputType;
typedef BaseChooserOnlyDateAndTimeInputType BaseWeekInputType;
#endif
-class WeekInputType : public BaseWeekInputType {
+class WeekInputType FINAL : public BaseWeekInputType {
public:
- static PassRefPtr<InputType> create(HTMLInputElement&);
+ static PassRefPtrWillBeRawPtr<InputType> create(HTMLInputElement&);
private:
WeekInputType(HTMLInputElement& element) : BaseWeekInputType(element) { }
@@ -57,9 +57,9 @@ private:
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
// BaseMultipleFieldsDateAndTimeInputType functions
- virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE FINAL;
- virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE FINAL;
- virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const;
+ virtual String formatDateTimeFieldsState(const DateTimeFieldsState&) const OVERRIDE;
+ virtual void setupLayoutParameters(DateTimeEditElement::LayoutParameters&, const DateComponents&) const OVERRIDE;
+ virtual bool isValidFormat(bool hasYear, bool hasMonth, bool hasWeek, bool hasDay, bool hasAMPM, bool hasHour, bool hasMinute, bool hasSecond) const OVERRIDE;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/Composition.cpp b/chromium/third_party/WebKit/Source/core/html/ime/Composition.cpp
deleted file mode 100644
index 17250b38ba6..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/ime/Composition.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/ime/Composition.h"
-
-#include "core/html/ime/InputMethodContext.h"
-
-namespace WebCore {
-
-Composition::~Composition()
-{
-}
-
-void Composition::ref()
-{
- m_inputMethodContext->ref();
-}
-
-void Composition::deref()
-{
- m_inputMethodContext->deref();
-}
-
-PassOwnPtr<Composition> Composition::create(InputMethodContext* context)
-{
- return adoptPtr(new Composition(context));
-}
-
-Composition::Composition(InputMethodContext* context)
- : m_inputMethodContext(context)
-{
- ScriptWrappable::init(this);
-}
-
-String Composition::text() const
-{
- return m_inputMethodContext->compositionText();
-}
-
-int Composition::selectionStart() const
-{
- return m_inputMethodContext->selectionStart();
-}
-
-int Composition::selectionEnd() const
-{
- return m_inputMethodContext->selectionEnd();
-}
-
-const Vector<unsigned>& Composition::getSegments() const
-{
- return m_inputMethodContext->segments();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/Composition.h b/chromium/third_party/WebKit/Source/core/html/ime/Composition.h
deleted file mode 100644
index 43054668f0d..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/ime/Composition.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef Composition_h
-#define Composition_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class InputMethodContext;
-
-class Composition : public ScriptWrappable {
-public:
- static PassOwnPtr<Composition> create(InputMethodContext*);
- ~Composition();
-
- void ref();
- void deref();
-
- String text() const;
- int selectionStart() const;
- int selectionEnd() const;
- const Vector<unsigned>& getSegments() const;
-
-private:
- explicit Composition(InputMethodContext*);
-
- InputMethodContext* m_inputMethodContext;
-};
-
-} // namespace WebCore
-
-#endif // Composition_h
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/Composition.idl b/chromium/third_party/WebKit/Source/core/html/ime/Composition.idl
deleted file mode 100644
index 494d2a06b75..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/ime/Composition.idl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// http://www.w3.org/TR/ime-api/
-[
- NoInterfaceObject
-] interface Composition {
- readonly attribute DOMString text;
- readonly attribute long selectionStart;
- readonly attribute long selectionEnd;
- sequence<unsigned long> getSegments();
-};
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp
index 74643ac6db0..e497b047ff3 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.cpp
@@ -31,16 +31,16 @@
#include "config.h"
#include "core/html/ime/InputMethodContext.h"
+#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/editing/InputMethodController.h"
-#include "core/html/ime/Composition.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
namespace WebCore {
-PassOwnPtr<InputMethodContext> InputMethodContext::create(HTMLElement* element)
+PassOwnPtrWillBeRawPtr<InputMethodContext> InputMethodContext::create(HTMLElement* element)
{
- return adoptPtr(new InputMethodContext(element));
+ return adoptPtrWillBeRefCountedGarbageCollected(new InputMethodContext(element));
}
InputMethodContext::InputMethodContext(HTMLElement* element)
@@ -53,13 +53,6 @@ InputMethodContext::~InputMethodContext()
{
}
-Composition* InputMethodContext::composition()
-{
- if (!m_composition)
- m_composition = Composition::create(this);
- return m_composition.get();
-}
-
String InputMethodContext::locale() const
{
// FIXME: Implement this.
@@ -93,7 +86,7 @@ void InputMethodContext::confirmComposition()
bool InputMethodContext::hasFocus() const
{
- Frame* frame = m_element->document().frame();
+ LocalFrame* frame = m_element->document().frame();
if (!frame)
return false;
@@ -193,4 +186,10 @@ void InputMethodContext::dispatchCandidateWindowHideEvent()
dispatchEvent(Event::create(EventTypeNames::candidatewindowhide));
}
+void InputMethodContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
+ EventTargetWithInlineData::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h
index 16bb6ffe17a..d2b7978bc40 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h
+++ b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.h
@@ -42,20 +42,21 @@
namespace WebCore {
-class Composition;
class ExecutionContext;
class InputMethodController;
class Node;
-class InputMethodContext : public ScriptWrappable, public EventTargetWithInlineData {
+class InputMethodContext FINAL : public NoBaseWillBeRefCountedGarbageCollected<InputMethodContext>, public ScriptWrappable, public EventTargetWithInlineData {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(InputMethodContext);
public:
- static PassOwnPtr<InputMethodContext> create(HTMLElement*);
- ~InputMethodContext();
+ static PassOwnPtrWillBeRawPtr<InputMethodContext> create(HTMLElement*);
+ virtual ~InputMethodContext();
+#if !ENABLE(OILPAN)
void ref() { m_element->ref(); }
void deref() { m_element->deref(); }
+#endif
- Composition* composition();
String locale() const;
HTMLElement* target() const;
unsigned compositionStartOffset();
@@ -78,17 +79,20 @@ public:
void dispatchCandidateWindowUpdateEvent();
void dispatchCandidateWindowHideEvent();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
InputMethodContext(HTMLElement*);
bool hasFocus() const;
CompositionUnderline selectedSegment() const;
InputMethodController& inputMethodController() const;
+#if !ENABLE(OILPAN)
virtual void refEventTarget() OVERRIDE { ref(); }
virtual void derefEventTarget() OVERRIDE { deref(); }
+#endif
- HTMLElement* m_element;
- OwnPtr<Composition> m_composition;
+ RawPtrWillBeMember<HTMLElement> m_element;
Vector<unsigned> m_segments;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl
index 8ce8c4a43d6..043feed06ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl
+++ b/chromium/third_party/WebKit/Source/core/html/ime/InputMethodContext.idl
@@ -30,7 +30,6 @@
// http://www.w3.org/TR/ime-api/
interface InputMethodContext : EventTarget {
- readonly attribute Composition composition;
readonly attribute DOMString locale;
readonly attribute HTMLElement target;
readonly attribute unsigned long compositionStartOffset;
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.cpp
new file mode 100644
index 00000000000..4726f713235
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImport.h"
+
+#include "core/dom/Document.h"
+#include "core/html/imports/HTMLImportStateResolver.h"
+
+namespace WebCore {
+
+HTMLImport* HTMLImport::root()
+{
+ HTMLImport* i = this;
+ while (i->parent())
+ i = i->parent();
+ return i;
+}
+
+bool HTMLImport::precedes(HTMLImport* import)
+{
+ for (HTMLImport* i = this; i; i = traverseNext(i)) {
+ if (i == import)
+ return true;
+ }
+
+ return false;
+}
+
+bool HTMLImport::formsCycle() const
+{
+ for (const HTMLImport* i = this->parent(); i; i = i->parent()) {
+ if (i->document() == this->document())
+ return true;
+ }
+
+ return false;
+
+}
+
+void HTMLImport::appendImport(HTMLImport* child)
+{
+ appendChild(child);
+
+ // This prevents HTML parser from going beyond the
+ // blockage line before the precise state is computed by recalcState().
+ if (child->isSync())
+ m_state = HTMLImportState::blockedState();
+
+ stateWillChange();
+}
+
+void HTMLImport::stateDidChange()
+{
+ if (!state().shouldBlockScriptExecution()) {
+ if (Document* document = this->document())
+ document->didLoadAllImports();
+ }
+}
+
+void HTMLImport::recalcTreeState(HTMLImport* root)
+{
+ HashMap<HTMLImport*, HTMLImportState> snapshot;
+ Vector<HTMLImport*> updated;
+
+ for (HTMLImport* i = root; i; i = traverseNext(i)) {
+ snapshot.add(i, i->state());
+ i->m_state = HTMLImportState::invalidState();
+ }
+
+ // The post-visit DFS order matters here because
+ // HTMLImportStateResolver in recalcState() Depends on
+ // |m_state| of its children and precedents of ancestors.
+ // Accidental cycle dependency of state computation is prevented
+ // by invalidateCachedState() and isStateCacheValid() check.
+ for (HTMLImport* i = traverseFirstPostOrder(root); i; i = traverseNextPostOrder(i)) {
+ ASSERT(!i->m_state.isValid());
+ i->m_state = HTMLImportStateResolver(i).resolve();
+
+ HTMLImportState newState = i->state();
+ HTMLImportState oldState = snapshot.get(i);
+ // Once the state reaches Ready, it shouldn't go back.
+ ASSERT(!oldState.isReady() || oldState <= newState);
+ if (newState != oldState)
+ updated.append(i);
+ }
+
+ for (size_t i = 0; i < updated.size(); ++i)
+ updated[i]->stateDidChange();
+}
+
+#if !defined(NDEBUG)
+void HTMLImport::show()
+{
+ root()->showTree(this, 0);
+}
+
+void HTMLImport::showTree(HTMLImport* highlight, unsigned depth)
+{
+ for (unsigned i = 0; i < depth*4; ++i)
+ fprintf(stderr, " ");
+
+ fprintf(stderr, "%s", this == highlight ? "*" : " ");
+ showThis();
+ fprintf(stderr, "\n");
+ for (HTMLImport* child = firstChild(); child; child = child->next())
+ child->showTree(highlight, depth + 1);
+}
+
+void HTMLImport::showThis()
+{
+ fprintf(stderr, "%p state=%d", this, m_state.peekValueForDebug());
+}
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.h
new file mode 100644
index 00000000000..0a7e35a7392
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImport.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLImport_h
+#define HTMLImport_h
+
+#include "core/html/imports/HTMLImportState.h"
+#include "platform/heap/Handle.h"
+#include "wtf/TreeNode.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class Document;
+class LocalFrame;
+class HTMLImportChild;
+class HTMLImportLoader;
+class HTMLImportsController;
+class KURL;
+
+//
+// # Basic Data Structure and Algorithms of HTML Imports implemenation.
+//
+// ## The Import Tree
+//
+// HTML Imports form a tree:
+//
+// * The root of the tree is HTMLImportTreeRoot.
+//
+// * The HTMLImportTreeRoot is owned HTMLImportsController, which is owned by the master
+// document as a DocumentSupplement.
+//
+// * The non-root nodes are HTMLImportChild. They are all owned by HTMLImporTreeRoot.
+// LinkStyle is wired into HTMLImportChild by implementing HTMLImportChildClient interface
+//
+// * Both HTMLImportTreeRoot and HTMLImportChild are derived from HTMLImport superclass
+// that models the tree data structure using WTF::TreeNode and provides a set of
+// virtual functions.
+//
+// HTMLImportsController also owns all loaders in the tree and manages their lifetime through it.
+// One assumption is that the tree is append-only and nodes are never inserted in the middle of the tree nor removed.
+//
+// Full diagram is here:
+// https://docs.google.com/drawings/d/1jFQrO0IupWrlykTNzQ3Nv2SdiBiSz4UE9-V3-vDgBb0/
+//
+// # Import Sharing and HTMLImportLoader
+//
+// The HTML Imports spec calls for de-dup mechanism to share already loaded imports.
+// To implement this, the actual loading machinery is split out from HTMLImportChild to
+// HTMLImportLoader, and each loader shares HTMLImportLoader with other loader if the URL is same.
+// Check around HTMLImportsController::findLink() for more detail.
+//
+// HTMLImportLoader can be shared by multiple imports.
+//
+// HTMLImportChild (1)-->(*) HTMLImportLoader
+//
+//
+// # Script Blocking
+//
+// - An import blocks the HTML parser of its own imported document from running <script>
+// until all of its children are loaded.
+// Note that dynamically added import won't block the parser.
+//
+// - An import under loading also blocks imported documents that follow from being created.
+// This is because an import can include another import that has same URLs of following ones.
+// In such case, the preceding import should be loaded and following ones should be de-duped.
+//
+
+// The superclass of HTMLImportTreeRoot and HTMLImportChild
+// This represents the import tree data structure.
+class HTMLImport : public NoBaseWillBeGarbageCollectedFinalized<HTMLImport>, public TreeNode<HTMLImport> {
+public:
+ enum SyncMode {
+ Sync = 0,
+ Async = 1
+ };
+
+ virtual ~HTMLImport() { }
+
+ // FIXME: Consider returning HTMLImportTreeRoot.
+ HTMLImport* root();
+ bool precedes(HTMLImport*);
+ bool isRoot() const { return !parent(); }
+ bool isSync() const { return SyncMode(m_sync) == Sync; }
+ bool formsCycle() const;
+ const HTMLImportState& state() const { return m_state; }
+
+ void appendImport(HTMLImport*);
+
+ virtual Document* document() const = 0;
+ virtual bool isDone() const = 0; // FIXME: Should be renamed to haveFinishedLoading()
+ virtual HTMLImportLoader* loader() const { return 0; }
+ virtual void stateWillChange() { }
+ virtual void stateDidChange();
+
+ virtual void trace(Visitor*) { }
+
+protected:
+ // Stating from most conservative state.
+ // It will be corrected through state update flow.
+ explicit HTMLImport(SyncMode sync)
+ : m_sync(sync)
+ { }
+
+ static void recalcTreeState(HTMLImport* root);
+
+#if !defined(NDEBUG)
+ void show();
+ void showTree(HTMLImport* highlight, unsigned depth);
+ virtual void showThis();
+#endif
+
+private:
+ HTMLImportState m_state;
+ unsigned m_sync : 1;
+};
+
+} // namespace WebCore
+
+#endif // HTMLImport_h
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp
new file mode 100644
index 00000000000..91b1b87f5ab
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImportChild.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/custom/CustomElement.h"
+#include "core/dom/custom/CustomElementMicrotaskDispatcher.h"
+#include "core/dom/custom/CustomElementMicrotaskImportStep.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+#include "core/html/imports/HTMLImportChildClient.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+#include "core/html/imports/HTMLImportsController.h"
+
+namespace WebCore {
+
+HTMLImportChild::HTMLImportChild(const KURL& url, HTMLImportLoader* loader, SyncMode sync)
+ : HTMLImport(sync)
+ , m_url(url)
+#if !ENABLE(OILPAN)
+ , m_weakFactory(this)
+#endif
+ , m_loader(loader)
+ , m_client(nullptr)
+{
+}
+
+HTMLImportChild::~HTMLImportChild()
+{
+#if !ENABLE(OILPAN)
+ // importDestroyed() should be called before the destruction.
+ ASSERT(!m_loader);
+
+ if (m_client)
+ m_client->importChildWasDestroyed(this);
+#endif
+}
+
+void HTMLImportChild::ownerInserted()
+{
+ if (!m_loader->isDone())
+ return;
+ root()->document()->styleResolverChanged();
+}
+
+void HTMLImportChild::didShareLoader()
+{
+ createCustomElementMicrotaskStepIfNeeded();
+ stateWillChange();
+}
+
+void HTMLImportChild::didStartLoading()
+{
+ createCustomElementMicrotaskStepIfNeeded();
+}
+
+void HTMLImportChild::didFinish()
+{
+ if (m_client)
+ m_client->didFinish();
+}
+
+void HTMLImportChild::didFinishLoading()
+{
+ stateWillChange();
+ if (m_customElementMicrotaskStep)
+ CustomElementMicrotaskDispatcher::instance().importDidFinish(m_customElementMicrotaskStep.get());
+}
+
+void HTMLImportChild::didFinishUpgradingCustomElements()
+{
+ stateWillChange();
+ m_customElementMicrotaskStep.clear();
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportChild::importDestroyed()
+{
+ if (parent())
+ parent()->removeChild(this);
+
+ ASSERT(m_loader);
+ m_loader->removeImport(this);
+ m_loader = nullptr;
+}
+#endif
+
+Document* HTMLImportChild::document() const
+{
+ ASSERT(m_loader);
+ return m_loader->document();
+}
+
+void HTMLImportChild::stateWillChange()
+{
+ toHTMLImportTreeRoot(root())->scheduleRecalcState();
+}
+
+void HTMLImportChild::stateDidChange()
+{
+ HTMLImport::stateDidChange();
+
+ if (state().isReady())
+ didFinish();
+}
+
+void HTMLImportChild::createCustomElementMicrotaskStepIfNeeded()
+{
+ // HTMLImportChild::normalize(), which is called from HTMLImportLoader::addImport(),
+ // can move import children to new parents. So their microtask steps should be updated as well,
+ // to let the steps be in the new parent queues.This method handles such migration.
+ // For implementation simplicity, outdated step objects that are owned by moved children
+ // aren't removed from the (now wrong) queues. Instead, each step invalidates its content so that
+ // it is removed from the wrong queue during the next traversal. See parentWasChanged() for the detail.
+
+ if (m_customElementMicrotaskStep) {
+ m_customElementMicrotaskStep->parentWasChanged();
+ m_customElementMicrotaskStep.clear();
+ }
+
+ if (!isDone() && !formsCycle()) {
+#if ENABLE(OILPAN)
+ m_customElementMicrotaskStep = CustomElement::didCreateImport(this);
+#else
+ m_customElementMicrotaskStep = CustomElement::didCreateImport(this)->weakPtr();
+#endif
+ }
+
+ for (HTMLImport* child = firstChild(); child; child = child->next())
+ toHTMLImportChild(child)->createCustomElementMicrotaskStepIfNeeded();
+}
+
+bool HTMLImportChild::isDone() const
+{
+ ASSERT(m_loader);
+
+ return m_loader->isDone() && m_loader->microtaskQueue()->isEmpty() && !m_customElementMicrotaskStep;
+}
+
+HTMLImportLoader* HTMLImportChild::loader() const
+{
+ // This should never be called after importDestroyed.
+ ASSERT(m_loader);
+ return m_loader;
+}
+
+void HTMLImportChild::setClient(HTMLImportChildClient* client)
+{
+ ASSERT(client);
+ ASSERT(!m_client);
+ m_client = client;
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportChild::clearClient()
+{
+ // Doesn't check m_client nullity because we allow
+ // clearClient() to reenter.
+ m_client = nullptr;
+}
+#endif
+
+HTMLLinkElement* HTMLImportChild::link() const
+{
+ if (!m_client)
+ return 0;
+ return m_client->link();
+}
+
+// Ensuring following invariants against the import tree:
+// - HTMLImportChild::firstImport() is the "first import" of the DFS order of the import tree.
+// - The "first import" manages all the children that is loaded by the document.
+void HTMLImportChild::normalize()
+{
+ if (!loader()->isFirstImport(this) && this->precedes(loader()->firstImport())) {
+ HTMLImportChild* oldFirst = loader()->firstImport();
+ loader()->moveToFirst(this);
+ takeChildrenFrom(oldFirst);
+ }
+
+ for (HTMLImport* child = firstChild(); child; child = child->next())
+ toHTMLImportChild(child)->normalize();
+}
+
+#if !defined(NDEBUG)
+void HTMLImportChild::showThis()
+{
+ bool isFirst = loader() ? loader()->isFirstImport(this) : false;
+ HTMLImport::showThis();
+ fprintf(stderr, " loader=%p first=%d, step=%p sync=%s url=%s",
+ m_loader.get(),
+ isFirst,
+ m_customElementMicrotaskStep.get(),
+ isSync() ? "Y" : "N",
+ url().string().utf8().data());
+}
+#endif
+
+void HTMLImportChild::trace(Visitor* visitor)
+{
+ visitor->trace(m_customElementMicrotaskStep);
+ visitor->trace(m_loader);
+ visitor->trace(m_client);
+ HTMLImport::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.h
new file mode 100644
index 00000000000..aafc6ebcec1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChild.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLImportChild_h
+#define HTMLImportChild_h
+
+#include "core/html/imports/HTMLImport.h"
+#include "platform/heap/Handle.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/Vector.h"
+#include "wtf/WeakPtr.h"
+
+namespace WebCore {
+
+class CustomElementMicrotaskImportStep;
+class HTMLImportLoader;
+class HTMLImportChildClient;
+class HTMLLinkElement;
+
+//
+// An import tree node subclas to encapsulate imported document
+// lifecycle. This class is owned by HTMLImportsController. The actual loading
+// is done by HTMLImportLoader, which can be shared among multiple
+// HTMLImportChild of same link URL.
+//
+class HTMLImportChild FINAL : public HTMLImport {
+public:
+ HTMLImportChild(const KURL&, HTMLImportLoader*, SyncMode);
+ virtual ~HTMLImportChild();
+
+ HTMLLinkElement* link() const;
+ const KURL& url() const { return m_url; }
+
+ void ownerInserted();
+ void didShareLoader();
+ void didStartLoading();
+#if !ENABLE(OILPAN)
+ void importDestroyed();
+ WeakPtr<HTMLImportChild> weakPtr() { return m_weakFactory.createWeakPtr(); }
+#endif
+
+ // HTMLImport
+ virtual Document* document() const OVERRIDE;
+ virtual bool isDone() const OVERRIDE;
+ virtual HTMLImportLoader* loader() const OVERRIDE;
+ virtual void stateWillChange() OVERRIDE;
+ virtual void stateDidChange() OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+
+#if !defined(NDEBUG)
+ virtual void showThis() OVERRIDE;
+#endif
+
+ void setClient(HTMLImportChildClient*);
+#if !ENABLE(OILPAN)
+ void clearClient();
+#endif
+
+ void didFinishLoading();
+ void didFinishUpgradingCustomElements();
+ void normalize();
+
+private:
+ void didFinish();
+ void shareLoader();
+ void createCustomElementMicrotaskStepIfNeeded();
+
+ KURL m_url;
+ WeakPtrWillBeWeakMember<CustomElementMicrotaskImportStep> m_customElementMicrotaskStep;
+#if !ENABLE(OILPAN)
+ WeakPtrFactory<HTMLImportChild> m_weakFactory;
+#endif
+ RawPtrWillBeMember<HTMLImportLoader> m_loader;
+ RawPtrWillBeMember<HTMLImportChildClient> m_client;
+};
+
+inline HTMLImportChild* toHTMLImportChild(HTMLImport* import)
+{
+ ASSERT(!import || !import->isRoot());
+ return static_cast<HTMLImportChild*>(import);
+}
+
+} // namespace WebCore
+
+#endif // HTMLImportChild_h
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChildClient.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChildClient.h
new file mode 100644
index 00000000000..67d0b65d4d3
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportChildClient.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLImportChildClient_h
+#define HTMLImportChildClient_h
+
+namespace WebCore {
+
+class HTMLImportChild;
+class HTMLLinkElement;
+
+class HTMLImportChildClient : public WillBeGarbageCollectedMixin {
+public:
+ virtual ~HTMLImportChildClient() { }
+ virtual void didFinish() = 0;
+#if !ENABLE(OILPAN)
+ virtual void importChildWasDestroyed(HTMLImportChild*) = 0;
+#endif
+ virtual bool isSync() const = 0;
+ virtual HTMLLinkElement* link() = 0;
+ virtual void trace(Visitor*) { }
+};
+
+} // namespace WebCore
+
+#endif // HTMLImportChildClient_h
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
new file mode 100644
index 00000000000..3b4d138babe
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImportLoader.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
+#include "core/dom/custom/CustomElementSyncMicrotaskQueue.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportsController.h"
+#include "core/loader/DocumentWriter.h"
+#include "platform/network/ContentSecurityPolicyResponseHeaders.h"
+
+
+namespace WebCore {
+
+HTMLImportLoader::HTMLImportLoader(HTMLImportsController* controller)
+ : m_controller(controller)
+ , m_state(StateLoading)
+ , m_microtaskQueue(CustomElementSyncMicrotaskQueue::create())
+{
+}
+
+HTMLImportLoader::~HTMLImportLoader()
+{
+#if !ENABLE(OILPAN)
+ clear();
+#endif
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportLoader::importDestroyed()
+{
+ clear();
+}
+
+void HTMLImportLoader::clear()
+{
+ m_controller = nullptr;
+ if (m_document) {
+ m_document->setImportsController(0);
+ m_document->cancelParsing();
+ m_document.clear();
+ }
+}
+#endif
+
+void HTMLImportLoader::startLoading(const ResourcePtr<RawResource>& resource)
+{
+ setResource(resource);
+}
+
+void HTMLImportLoader::responseReceived(Resource* resource, const ResourceResponse& response)
+{
+ // Resource may already have been loaded with the import loader
+ // being added as a client later & now being notified. Fail early.
+ if (resource->loadFailedOrCanceled() || response.httpStatusCode() >= 400) {
+ setState(StateError);
+ return;
+ }
+ setState(startWritingAndParsing(response));
+}
+
+void HTMLImportLoader::dataReceived(Resource*, const char* data, int length)
+{
+ RefPtrWillBeRawPtr<DocumentWriter> protectingWriter(m_writer.get());
+ m_writer->addData(data, length);
+}
+
+void HTMLImportLoader::notifyFinished(Resource* resource)
+{
+ // The writer instance indicates that a part of the document can be already loaded.
+ // We don't take such a case as an error because the partially-loaded document has been visible from script at this point.
+ if (resource->loadFailedOrCanceled() && !m_writer) {
+ setState(StateError);
+ return;
+ }
+
+ setState(finishWriting());
+}
+
+HTMLImportLoader::State HTMLImportLoader::startWritingAndParsing(const ResourceResponse& response)
+{
+ ASSERT(!m_imports.isEmpty());
+ DocumentInit init = DocumentInit(response.url(), 0, m_controller->master()->contextDocument(), m_controller)
+ .withRegistrationContext(m_controller->master()->registrationContext());
+ m_document = HTMLDocument::create(init);
+ m_writer = DocumentWriter::create(m_document.get(), response.mimeType(), "UTF-8");
+
+ return StateLoading;
+}
+
+HTMLImportLoader::State HTMLImportLoader::finishWriting()
+{
+ return StateWritten;
+}
+
+HTMLImportLoader::State HTMLImportLoader::finishParsing()
+{
+ return StateParsed;
+}
+
+HTMLImportLoader::State HTMLImportLoader::finishLoading()
+{
+ return StateLoaded;
+}
+
+void HTMLImportLoader::setState(State state)
+{
+ if (m_state == state)
+ return;
+
+ m_state = state;
+
+ if (m_state == StateParsed || m_state == StateError || m_state == StateWritten) {
+ if (RefPtrWillBeRawPtr<DocumentWriter> writer = m_writer.release())
+ writer->end();
+ }
+
+ // Since DocumentWriter::end() can let setState() reenter, we shouldn't refer to m_state here.
+ if (state == StateLoaded || state == StateError)
+ didFinishLoading();
+}
+
+void HTMLImportLoader::didFinishParsing()
+{
+ setState(finishParsing());
+ if (!hasPendingResources())
+ setState(finishLoading());
+}
+
+void HTMLImportLoader::didRemoveAllPendingStylesheet()
+{
+ if (m_state == StateParsed)
+ setState(finishLoading());
+}
+
+bool HTMLImportLoader::hasPendingResources() const
+{
+ return m_document && m_document->styleEngine()->hasPendingSheets();
+}
+
+void HTMLImportLoader::didFinishLoading()
+{
+ for (size_t i = 0; i < m_imports.size(); ++i)
+ m_imports[i]->didFinishLoading();
+
+ clearResource();
+
+ ASSERT(!m_document || !m_document->parsing());
+}
+
+void HTMLImportLoader::moveToFirst(HTMLImportChild* import)
+{
+ size_t position = m_imports.find(import);
+ ASSERT(kNotFound != position);
+ m_imports.remove(position);
+ m_imports.insert(0, import);
+}
+
+void HTMLImportLoader::addImport(HTMLImportChild* import)
+{
+ ASSERT(kNotFound == m_imports.find(import));
+
+ m_imports.append(import);
+ import->normalize();
+ if (isDone())
+ import->didFinishLoading();
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportLoader::removeImport(HTMLImportChild* client)
+{
+ ASSERT(kNotFound != m_imports.find(client));
+ m_imports.remove(m_imports.find(client));
+}
+#endif
+
+bool HTMLImportLoader::shouldBlockScriptExecution() const
+{
+ return firstImport()->state().shouldBlockScriptExecution();
+}
+
+PassRefPtrWillBeRawPtr<CustomElementSyncMicrotaskQueue> HTMLImportLoader::microtaskQueue() const
+{
+ return m_microtaskQueue;
+}
+
+void HTMLImportLoader::trace(Visitor* visitor)
+{
+ visitor->trace(m_controller);
+#if ENABLE(OILPAN)
+ visitor->trace(m_imports);
+#endif
+ visitor->trace(m_document);
+ visitor->trace(m_writer);
+ visitor->trace(m_microtaskQueue);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.h
new file mode 100644
index 00000000000..45d05e38469
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportLoader.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLImportLoader_h
+#define HTMLImportLoader_h
+
+#include "core/fetch/RawResource.h"
+#include "core/fetch/ResourceOwner.h"
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CustomElementSyncMicrotaskQueue;
+class Document;
+class DocumentWriter;
+class HTMLImportChild;
+class HTMLImportsController;
+
+
+//
+// Owning imported Document lifetime. It also implements ResourceClient through ResourceOwner
+// to feed fetched bytes to the DocumentWriter of the imported document.
+// HTMLImportLoader is owned by HTMLImportsController.
+//
+//
+class HTMLImportLoader FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLImportLoader>, public ResourceOwner<RawResource> {
+public:
+ enum State {
+ StateLoading,
+ StateWritten,
+ StateParsed,
+ StateLoaded,
+ StateError
+ };
+
+ static PassOwnPtrWillBeRawPtr<HTMLImportLoader> create(HTMLImportsController* controller)
+ {
+ return adoptPtrWillBeNoop(new HTMLImportLoader(controller));
+ }
+
+ virtual ~HTMLImportLoader();
+
+ Document* document() const { return m_document.get(); }
+ void addImport(HTMLImportChild*);
+#if !ENABLE(OILPAN)
+ void removeImport(HTMLImportChild*);
+#endif
+ void moveToFirst(HTMLImportChild*);
+ HTMLImportChild* firstImport() const { return m_imports[0]; }
+ bool isFirstImport(const HTMLImportChild* child) const { return m_imports.size() ? firstImport() == child : false; }
+
+ bool isDone() const { return m_state == StateLoaded || m_state == StateError; }
+ bool hasError() const { return m_state == StateError; }
+ bool shouldBlockScriptExecution() const;
+
+#if !ENABLE(OILPAN)
+ void importDestroyed();
+#endif
+ void startLoading(const ResourcePtr<RawResource>&);
+
+ // Tells the loader that the parser is done with this import.
+ // Called by Document::finishedParsing, after DOMContentLoaded was dispatched.
+ void didFinishParsing();
+ // Tells the loader that all of the import's stylesheets finished
+ // loading.
+ // Called by Document::didRemoveAllPendingStylesheet.
+ void didRemoveAllPendingStylesheet();
+
+ PassRefPtrWillBeRawPtr<CustomElementSyncMicrotaskQueue> microtaskQueue() const;
+
+ virtual void trace(Visitor*);
+
+private:
+ HTMLImportLoader(HTMLImportsController*);
+
+ // RawResourceClient
+ virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE;
+ virtual void dataReceived(Resource*, const char* data, int length) OVERRIDE;
+ virtual void notifyFinished(Resource*) OVERRIDE;
+
+ State startWritingAndParsing(const ResourceResponse&);
+ State finishWriting();
+ State finishParsing();
+ State finishLoading();
+
+ void setState(State);
+ void didFinishLoading();
+ bool hasPendingResources() const;
+#if !ENABLE(OILPAN)
+ void clear();
+#endif
+
+ RawPtrWillBeMember<HTMLImportsController> m_controller;
+ WillBeHeapVector<RawPtrWillBeMember<HTMLImportChild> > m_imports;
+ State m_state;
+ RefPtrWillBeMember<Document> m_document;
+ RefPtrWillBeMember<DocumentWriter> m_writer;
+ RefPtrWillBeMember<CustomElementSyncMicrotaskQueue> m_microtaskQueue;
+};
+
+} // namespace WebCore
+
+#endif // HTMLImportLoader_h
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportState.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportState.h
new file mode 100644
index 00000000000..356a40df39b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportState.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLImportState_h
+#define HTMLImportState_h
+
+#include "wtf/Assertions.h"
+
+namespace WebCore {
+
+class HTMLImportState {
+public:
+ enum Value {
+ BlockingScriptExecution = 0,
+ Active,
+ Ready,
+ Invalid
+ };
+
+ explicit HTMLImportState(Value value = BlockingScriptExecution)
+ : m_value(value)
+ { }
+
+ bool shouldBlockScriptExecution() const { return checkedValue() <= BlockingScriptExecution; }
+ bool isReady() const { return checkedValue() == Ready; }
+ bool isValid() const { return m_value != Invalid; }
+ bool operator==(const HTMLImportState& other) const { return m_value == other.m_value; }
+ bool operator!=(const HTMLImportState& other) const { return !(*this == other); }
+ bool operator<=(const HTMLImportState& other) const { return m_value <= other.m_value; }
+
+#if !defined(NDEBUG)
+ Value peekValueForDebug() const { return m_value; }
+#endif
+
+ static HTMLImportState invalidState() { return HTMLImportState(Invalid); }
+ static HTMLImportState blockedState() { return HTMLImportState(BlockingScriptExecution); }
+private:
+ Value checkedValue() const;
+ Value m_value;
+};
+
+inline HTMLImportState::Value HTMLImportState::checkedValue() const
+{
+ ASSERT(isValid());
+ return m_value;
+}
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp
new file mode 100644
index 00000000000..9a1f2bfa534
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImportStateResolver.h"
+
+#include "core/html/imports/HTMLImport.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportLoader.h"
+
+namespace WebCore {
+
+inline bool HTMLImportStateResolver::isBlockingFollowers(HTMLImport* import)
+{
+ if (!import->isSync())
+ return false;
+ HTMLImportChild* child = toHTMLImportChild(import);
+ if (!child->loader()->isFirstImport(child))
+ return false;
+ return !import->state().isReady();
+}
+
+inline bool HTMLImportStateResolver::shouldBlockScriptExecution() const
+{
+ // FIXME: Memoize to make this faster.
+ for (HTMLImport* ancestor = m_import; ancestor; ancestor = ancestor->parent()) {
+ for (HTMLImport* predecessor = ancestor->previous(); predecessor; predecessor = predecessor->previous()) {
+ if (isBlockingFollowers(predecessor))
+ return true;
+ }
+ }
+
+ for (HTMLImport* child = m_import->firstChild(); child; child = child->next()) {
+ if (isBlockingFollowers(child))
+ return true;
+ }
+
+ return false;
+}
+
+inline bool HTMLImportStateResolver::isActive() const
+{
+ return !m_import->isDone();
+}
+
+HTMLImportState HTMLImportStateResolver::resolve() const
+{
+ if (shouldBlockScriptExecution())
+ return HTMLImportState(HTMLImportState::BlockingScriptExecution);
+ if (isActive())
+ return HTMLImportState(HTMLImportState::Active);
+ return HTMLImportState(HTMLImportState::Ready);
+}
+
+}
+
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.h
new file mode 100644
index 00000000000..0850380bf62
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLImportStateResolver_h
+#define HTMLImportStateResolver_h
+
+#include "core/html/imports/HTMLImportState.h"
+
+namespace WebCore {
+
+class HTMLImport;
+
+class HTMLImportStateResolver {
+public:
+ explicit HTMLImportStateResolver(HTMLImport* import)
+ : m_import(import)
+ { }
+
+ HTMLImportState resolve() const;
+
+private:
+ static bool isBlockingFollowers(HTMLImport*);
+
+ bool shouldBlockScriptExecution() const;
+ bool isActive() const;
+
+ HTMLImport* m_import;
+};
+
+}
+
+#endif // HTMLImportStateResolver_h
+
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp
new file mode 100644
index 00000000000..bfe0beded33
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.cpp
@@ -0,0 +1,110 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/imports/HTMLImportChild.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<HTMLImportTreeRoot> HTMLImportTreeRoot::create(Document* document)
+{
+ return adoptPtrWillBeNoop(new HTMLImportTreeRoot(document));
+}
+
+HTMLImportTreeRoot::HTMLImportTreeRoot(Document* document)
+ : HTMLImport(HTMLImport::Sync)
+ , m_document(document)
+ , m_recalcTimer(this, &HTMLImportTreeRoot::recalcTimerFired)
+{
+ recalcTreeState(this); // This recomputes initial state.
+}
+
+HTMLImportTreeRoot::~HTMLImportTreeRoot()
+{
+#if !ENABLE(OILPAN)
+ for (size_t i = 0; i < m_imports.size(); ++i)
+ m_imports[i]->importDestroyed();
+ m_imports.clear();
+ m_document = nullptr;
+#endif
+}
+
+Document* HTMLImportTreeRoot::document() const
+{
+ return m_document;
+}
+
+bool HTMLImportTreeRoot::isDone() const
+{
+ return !m_document->parsing() && m_document->styleEngine()->haveStylesheetsLoaded();
+}
+
+void HTMLImportTreeRoot::stateWillChange()
+{
+ scheduleRecalcState();
+}
+
+void HTMLImportTreeRoot::stateDidChange()
+{
+ HTMLImport::stateDidChange();
+
+ if (!state().isReady())
+ return;
+ if (LocalFrame* frame = m_document->frame())
+ frame->loader().checkCompleted();
+}
+
+void HTMLImportTreeRoot::scheduleRecalcState()
+{
+#if ENABLE(OILPAN)
+ ASSERT(m_document);
+ if (m_recalcTimer.isActive() || !m_document->isActive())
+ return;
+#else
+ if (m_recalcTimer.isActive() || !m_document)
+ return;
+#endif
+ m_recalcTimer.startOneShot(0, FROM_HERE);
+}
+
+HTMLImportChild* HTMLImportTreeRoot::add(PassOwnPtrWillBeRawPtr<HTMLImportChild> child)
+{
+ m_imports.append(child);
+ return m_imports.last().get();
+}
+
+HTMLImportChild* HTMLImportTreeRoot::find(const KURL& url) const
+{
+ for (size_t i = 0; i < m_imports.size(); ++i) {
+ HTMLImportChild* candidate = m_imports[i].get();
+ if (equalIgnoringFragmentIdentifier(candidate->url(), url))
+ return candidate;
+ }
+
+ return 0;
+}
+
+void HTMLImportTreeRoot::recalcTimerFired(Timer<HTMLImportTreeRoot>*)
+{
+ ASSERT(m_document);
+
+ do {
+ m_recalcTimer.stop();
+ HTMLImport::recalcTreeState(this);
+ } while (m_recalcTimer.isActive());
+}
+
+void HTMLImportTreeRoot::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_imports);
+ HTMLImport::trace(visitor);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.h
new file mode 100644
index 00000000000..6cd31168fd0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportTreeRoot.h
@@ -0,0 +1,52 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef HTMLImportTreeRoot_h
+#define HTMLImportTreeRoot_h
+
+#include "core/html/imports/HTMLImport.h"
+#include "platform/Timer.h"
+#include "wtf/PassOwnPtr.h"
+
+namespace WebCore {
+
+class HTMLImportChild;
+
+class HTMLImportTreeRoot : public HTMLImport {
+public:
+ static PassOwnPtrWillBeRawPtr<HTMLImportTreeRoot> create(Document*);
+
+ virtual ~HTMLImportTreeRoot();
+
+ // HTMLImport
+ virtual Document* document() const OVERRIDE;
+ virtual bool isDone() const OVERRIDE;
+ virtual void stateWillChange() OVERRIDE;
+ virtual void stateDidChange() OVERRIDE;
+
+ void scheduleRecalcState();
+
+ HTMLImportChild* add(PassOwnPtrWillBeRawPtr<HTMLImportChild>);
+ HTMLImportChild* find(const KURL&) const;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit HTMLImportTreeRoot(Document*);
+
+ void recalcTimerFired(Timer<HTMLImportTreeRoot>*);
+
+ RawPtrWillBeMember<Document> m_document;
+ Timer<HTMLImportTreeRoot> m_recalcTimer;
+
+ // List of import which has been loaded or being loaded.
+ typedef WillBeHeapVector<OwnPtrWillBeMember<HTMLImportChild> > ImportList;
+ ImportList m_imports;
+};
+
+DEFINE_TYPE_CASTS(HTMLImportTreeRoot, HTMLImport, import, import->isRoot(), import.isRoot());
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp
new file mode 100644
index 00000000000..8afd0dd7449
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/HTMLImportsController.h"
+
+#include "core/dom/Document.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportChildClient.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+
+namespace WebCore {
+
+void HTMLImportsController::provideTo(Document& master)
+{
+ DEFINE_STATIC_LOCAL(const char*, name, ("HTMLImportsController"));
+ OwnPtrWillBeRawPtr<HTMLImportsController> controller = adoptPtrWillBeNoop(new HTMLImportsController(master));
+ master.setImportsController(controller.get());
+ DocumentSupplement::provideTo(master, name, controller.release());
+}
+
+HTMLImportsController::HTMLImportsController(Document& master)
+ : m_root(HTMLImportTreeRoot::create(&master))
+{
+ UseCounter::count(master, UseCounter::HTMLImports);
+}
+
+HTMLImportsController::~HTMLImportsController()
+{
+#if !ENABLE(OILPAN)
+ ASSERT(!m_root);
+#endif
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportsController::clear()
+{
+ Document* master = root()->document();
+ m_root.clear();
+
+ for (size_t i = 0; i < m_loaders.size(); ++i)
+ m_loaders[i]->importDestroyed();
+ m_loaders.clear();
+
+ if (master)
+ master->setImportsController(0);
+}
+#endif
+
+static bool makesCycle(HTMLImport* parent, const KURL& url)
+{
+ for (HTMLImport* ancestor = parent; ancestor; ancestor = ancestor->parent()) {
+ if (!ancestor->isRoot() && equalIgnoringFragmentIdentifier(toHTMLImportChild(parent)->url(), url))
+ return true;
+ }
+
+ return false;
+}
+
+HTMLImportChild* HTMLImportsController::createChild(const KURL& url, HTMLImportLoader* loader, HTMLImport* parent, HTMLImportChildClient* client)
+{
+ HTMLImport::SyncMode mode = client->isSync() && !makesCycle(parent, url) ? HTMLImport::Sync : HTMLImport::Async;
+ if (mode == HTMLImport::Async)
+ UseCounter::count(root()->document(), UseCounter::HTMLImportsAsyncAttribute);
+
+ OwnPtrWillBeRawPtr<HTMLImportChild> child = adoptPtrWillBeNoop(new HTMLImportChild(url, loader, mode));
+ child->setClient(client);
+ parent->appendImport(child.get());
+ loader->addImport(child.get());
+ return root()->add(child.release());
+}
+
+HTMLImportChild* HTMLImportsController::load(HTMLImport* parent, HTMLImportChildClient* client, FetchRequest request)
+{
+ ASSERT(!request.url().isEmpty() && request.url().isValid());
+ ASSERT(parent == root() || toHTMLImportChild(parent)->loader()->isFirstImport(toHTMLImportChild(parent)));
+
+ if (HTMLImportChild* childToShareWith = root()->find(request.url())) {
+ HTMLImportLoader* loader = childToShareWith->loader();
+ ASSERT(loader);
+ HTMLImportChild* child = createChild(request.url(), loader, parent, client);
+ child->didShareLoader();
+ return child;
+ }
+
+ bool sameOriginRequest = master()->securityOrigin()->canRequest(request.url());
+ request.setCrossOriginAccessControl(
+ master()->securityOrigin(), sameOriginRequest ? AllowStoredCredentials : DoNotAllowStoredCredentials,
+ ClientDidNotRequestCredentials);
+ ResourcePtr<RawResource> resource = parent->document()->fetcher()->fetchImport(request);
+ if (!resource)
+ return 0;
+
+ HTMLImportLoader* loader = createLoader();
+ HTMLImportChild* child = createChild(request.url(), loader, parent, client);
+ // We set resource after the import tree is built since
+ // Resource::addClient() immediately calls back to feed the bytes when the resource is cached.
+ loader->startLoading(resource);
+ child->didStartLoading();
+ return child;
+}
+
+Document* HTMLImportsController::master() const
+{
+ return root()->document();
+}
+
+bool HTMLImportsController::shouldBlockScriptExecution(const Document& document) const
+{
+ ASSERT(document.importsController() == this);
+ if (HTMLImportLoader* loader = loaderFor(document))
+ return loader->shouldBlockScriptExecution();
+ return root()->state().shouldBlockScriptExecution();
+}
+
+#if !ENABLE(OILPAN)
+void HTMLImportsController::wasDetachedFrom(const Document& document)
+{
+ ASSERT(document.importsController() == this);
+ if (master() == &document)
+ clear();
+}
+#endif
+
+HTMLImportLoader* HTMLImportsController::createLoader()
+{
+ m_loaders.append(HTMLImportLoader::create(this));
+ return m_loaders.last().get();
+}
+
+HTMLImportLoader* HTMLImportsController::loaderFor(const Document& document) const
+{
+ for (size_t i = 0; i < m_loaders.size(); ++i) {
+ if (m_loaders[i]->document() == &document)
+ return m_loaders[i].get();
+ }
+
+ return 0;
+}
+
+Document* HTMLImportsController::loaderDocumentAt(size_t i) const
+{
+ return loaderAt(i)->document();
+}
+
+void HTMLImportsController::trace(Visitor* visitor)
+{
+ visitor->trace(m_root);
+ visitor->trace(m_loaders);
+ DocumentSupplement::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.h b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.h
new file mode 100644
index 00000000000..414fe464396
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/HTMLImportsController.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLImportsController_h
+#define HTMLImportsController_h
+
+#include "core/dom/DocumentSupplementable.h"
+#include "core/fetch/RawResource.h"
+#include "core/html/LinkResource.h"
+#include "core/html/imports/HTMLImport.h"
+#include "platform/Supplementable.h"
+#include "platform/Timer.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class FetchRequest;
+class ExecutionContext;
+class ResourceFetcher;
+class HTMLImportChild;
+class HTMLImportChildClient;
+class HTMLImportLoader;
+class HTMLImportTreeRoot;
+
+class HTMLImportsController FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLImportsController>, public DocumentSupplement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLImportsController);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+ static void provideTo(Document&);
+
+ explicit HTMLImportsController(Document&);
+ virtual ~HTMLImportsController();
+
+ HTMLImportTreeRoot* root() const { return m_root.get(); }
+
+ bool shouldBlockScriptExecution(const Document&) const;
+#if !ENABLE(OILPAN)
+ void wasDetachedFrom(const Document&);
+#endif
+ HTMLImportChild* load(HTMLImport* parent, HTMLImportChildClient*, FetchRequest);
+
+ Document* master() const;
+
+ HTMLImportLoader* createLoader();
+
+ size_t loaderCount() const { return m_loaders.size(); }
+ HTMLImportLoader* loaderAt(size_t i) const { return m_loaders[i].get(); }
+ Document* loaderDocumentAt(size_t) const;
+ HTMLImportLoader* loaderFor(const Document&) const;
+
+ virtual void trace(Visitor*);
+
+private:
+ HTMLImportChild* createChild(const KURL&, HTMLImportLoader*, HTMLImport* parent, HTMLImportChildClient*);
+#if !ENABLE(OILPAN)
+ void clear();
+#endif
+
+ OwnPtrWillBeMember<HTMLImportTreeRoot> m_root;
+ typedef WillBeHeapVector<OwnPtrWillBeMember<HTMLImportLoader> > LoaderList;
+ LoaderList m_loaders;
+};
+
+} // namespace WebCore
+
+#endif // HTMLImportsController_h
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.cpp b/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.cpp
new file mode 100644
index 00000000000..0f5a9840211
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/imports/LinkImport.h"
+
+#include "core/dom/Document.h"
+#include "core/fetch/CrossOriginAccessControl.h"
+#include "core/html/HTMLLinkElement.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportTreeRoot.h"
+#include "core/html/imports/HTMLImportsController.h"
+
+namespace WebCore {
+
+PassOwnPtrWillBeRawPtr<LinkImport> LinkImport::create(HTMLLinkElement* owner)
+{
+ return adoptPtrWillBeNoop(new LinkImport(owner));
+}
+
+LinkImport::LinkImport(HTMLLinkElement* owner)
+ : LinkResource(owner)
+ , m_child(nullptr)
+{
+}
+
+LinkImport::~LinkImport()
+{
+#if !ENABLE(OILPAN)
+ if (m_child) {
+ m_child->clearClient();
+ m_child = nullptr;
+ }
+#endif
+}
+
+Document* LinkImport::importedDocument() const
+{
+ if (!m_child || !m_owner || !m_owner->inDocument())
+ return 0;
+ if (m_child->loader()->hasError())
+ return 0;
+ return m_child->document();
+}
+
+void LinkImport::process()
+{
+ if (m_child)
+ return;
+ if (!m_owner)
+ return;
+ if (!shouldLoadResource())
+ return;
+
+ if (!m_owner->document().importsController()) {
+ ASSERT(m_owner->document().frame()); // The document should be the master.
+ HTMLImportsController::provideTo(m_owner->document());
+ }
+
+ LinkRequestBuilder builder(m_owner);
+ if (!builder.isValid()) {
+ didFinish();
+ return;
+ }
+
+ HTMLImportsController* controller = m_owner->document().importsController();
+ HTMLImportLoader* loader = m_owner->document().importLoader();
+ HTMLImport* parent = loader ? static_cast<HTMLImport*>(loader->firstImport()) : static_cast<HTMLImport*>(controller->root());
+ m_child = controller->load(parent, this, builder.build(true));
+ if (!m_child) {
+ didFinish();
+ return;
+ }
+}
+
+void LinkImport::didFinish()
+{
+ if (!m_owner || !m_owner->inDocument())
+ return;
+ m_owner->scheduleEvent();
+}
+
+#if !ENABLE(OILPAN)
+void LinkImport::importChildWasDestroyed(HTMLImportChild* child)
+{
+ ASSERT(m_child == child);
+ m_child = nullptr;
+ m_owner = nullptr;
+}
+#endif
+
+bool LinkImport::isSync() const
+{
+ return m_owner && !m_owner->async();
+}
+
+HTMLLinkElement* LinkImport::link()
+{
+ return m_owner;
+}
+
+bool LinkImport::hasLoaded() const
+{
+ // Should never be called after importChildWasDestroyed was called.
+ ASSERT(m_owner);
+ return m_child && m_child->isDone() && !m_child->loader()->hasError();
+}
+
+void LinkImport::ownerInserted()
+{
+ if (m_child)
+ m_child->ownerInserted();
+}
+
+void LinkImport::trace(Visitor* visitor)
+{
+ visitor->trace(m_child);
+ HTMLImportChildClient::trace(visitor);
+ LinkResource::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.h b/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.h
new file mode 100644
index 00000000000..e56339f68dc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/imports/LinkImport.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LinkImport_h
+#define LinkImport_h
+
+#include "core/html/LinkResource.h"
+#include "core/html/imports/HTMLImportChildClient.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class Document;
+class HTMLImportChild;
+
+//
+// A LinkResource subclasss used for @rel=import.
+//
+class LinkImport FINAL : public LinkResource, public HTMLImportChildClient {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(LinkImport);
+public:
+
+ static PassOwnPtrWillBeRawPtr<LinkImport> create(HTMLLinkElement* owner);
+
+ explicit LinkImport(HTMLLinkElement* owner);
+ virtual ~LinkImport();
+
+ // LinkResource
+ virtual void process() OVERRIDE;
+ virtual Type type() const OVERRIDE { return Import; }
+ virtual bool hasLoaded() const OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+ virtual void ownerInserted() OVERRIDE;
+
+ // HTMLImportChildClient
+ virtual void didFinish() OVERRIDE;
+#if !ENABLE(OILPAN)
+ virtual void importChildWasDestroyed(HTMLImportChild*) OVERRIDE;
+#endif
+ virtual bool isSync() const OVERRIDE;
+ virtual HTMLLinkElement* link() OVERRIDE;
+
+ Document* importedDocument() const;
+
+private:
+ RawPtrWillBeMember<HTMLImportChild> m_child;
+};
+
+} // namespace WebCore
+
+#endif // LinkImport_h
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h b/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
index 63e8c0c86dc..7254ab88480 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/AtomicHTMLToken.h
@@ -26,7 +26,7 @@
#ifndef AtomicHTMLToken_h
#define AtomicHTMLToken_h
-#include "HTMLElementLookupTrie.h"
+#include "core/HTMLElementLookupTrie.h"
#include "core/dom/Attribute.h"
#include "core/html/parser/CompactHTMLToken.h"
#include "core/html/parser/HTMLToken.h"
@@ -150,7 +150,7 @@ public:
ASSERT_NOT_REACHED();
break;
case HTMLToken::DOCTYPE:
- m_name = token.data();
+ m_name = AtomicString(token.data());
m_doctypeData = adoptPtr(new DoctypeData());
m_doctypeData->m_hasPublicIdentifier = true;
append(m_doctypeData->m_publicIdentifier, token.publicIdentifier());
@@ -163,15 +163,15 @@ public:
case HTMLToken::StartTag:
m_attributes.reserveInitialCapacity(token.attributes().size());
for (Vector<CompactHTMLToken::Attribute>::const_iterator it = token.attributes().begin(); it != token.attributes().end(); ++it) {
- QualifiedName name(nullAtom, it->name, nullAtom);
+ QualifiedName name(nullAtom, AtomicString(it->name), nullAtom);
// FIXME: This is N^2 for the number of attributes.
if (!findAttributeInVector(m_attributes, name))
- m_attributes.append(Attribute(name, it->value));
+ m_attributes.append(Attribute(name, AtomicString(it->value)));
}
// Fall through!
case HTMLToken::EndTag:
m_selfClosing = token.selfClosing();
- m_name = token.data();
+ m_name = AtomicString(token.data());
break;
case HTMLToken::Character:
case HTMLToken::Comment:
@@ -233,9 +233,7 @@ inline void AtomicHTMLToken::initializeAttributes(const HTMLToken::AttributeList
if (attribute.name.isEmpty())
continue;
- // FIXME: We should be able to add the following ASSERT once we fix
- // https://bugs.webkit.org/show_bug.cgi?id=62971
- // ASSERT(attribute.nameRange.start);
+ ASSERT(attribute.nameRange.start);
ASSERT(attribute.nameRange.end);
ASSERT(attribute.valueRange.start);
ASSERT(attribute.valueRange.end);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
index b91dafd40b9..66a62b8d1e7 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp
@@ -27,7 +27,7 @@
#include "core/html/parser/BackgroundHTMLParser.h"
#include "core/html/parser/HTMLDocumentParser.h"
-#include "core/html/parser/HTMLParserThread.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/parser/XSSAuditor.h"
#include "wtf/MainThread.h"
#include "wtf/text/TextPosition.h"
@@ -76,6 +76,12 @@ static void checkThatXSSInfosAreSafeToSendToAnotherThread(const XSSInfoStream& i
#endif
+void BackgroundHTMLParser::start(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config)
+{
+ new BackgroundHTMLParser(reference, config);
+ // Caller must free by calling stop().
+}
+
BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config)
: m_weakFactory(reference, this)
, m_token(adoptPtr(new HTMLToken))
@@ -86,16 +92,62 @@ BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHT
, m_pendingTokens(adoptPtr(new CompactHTMLTokenStream))
, m_xssAuditor(config->xssAuditor.release())
, m_preloadScanner(config->preloadScanner.release())
+ , m_decoder(config->decoder.release())
+{
+}
+
+BackgroundHTMLParser::~BackgroundHTMLParser()
+{
+}
+
+void BackgroundHTMLParser::appendRawBytesFromParserThread(const char* data, int dataLength)
{
+ ASSERT(m_decoder);
+ updateDocument(m_decoder->decode(data, dataLength));
}
-void BackgroundHTMLParser::append(const String& input)
+void BackgroundHTMLParser::appendRawBytesFromMainThread(PassOwnPtr<Vector<char> > buffer)
+{
+ ASSERT(m_decoder);
+ updateDocument(m_decoder->decode(buffer->data(), buffer->size()));
+}
+
+void BackgroundHTMLParser::appendDecodedBytes(const String& input)
{
ASSERT(!m_input.current().isClosed());
m_input.append(input);
pumpTokenizer();
}
+void BackgroundHTMLParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
+{
+ ASSERT(decoder);
+ m_decoder = decoder;
+}
+
+void BackgroundHTMLParser::flush()
+{
+ ASSERT(m_decoder);
+ updateDocument(m_decoder->flush());
+}
+
+void BackgroundHTMLParser::updateDocument(const String& decodedData)
+{
+ DocumentEncodingData encodingData(*m_decoder.get());
+
+ if (encodingData != m_lastSeenEncodingData) {
+ m_lastSeenEncodingData = encodingData;
+
+ m_xssAuditor->setEncoding(encodingData.encoding());
+ callOnMainThread(bind(&HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser, m_parser, encodingData));
+ }
+
+ if (decodedData.isEmpty())
+ return;
+
+ appendDecodedBytes(decodedData);
+}
+
void BackgroundHTMLParser::resumeFrom(PassOwnPtr<Checkpoint> checkpoint)
{
m_parser = checkpoint->parser;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h
index b9b5a511c49..8d315a8f23e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.h
@@ -26,14 +26,14 @@
#ifndef BackgroundHTMLParser_h
#define BackgroundHTMLParser_h
+#include "core/dom/DocumentEncodingData.h"
#include "core/html/parser/BackgroundHTMLInputStream.h"
#include "core/html/parser/CompactHTMLToken.h"
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLPreloadScanner.h"
#include "core/html/parser/HTMLSourceTracker.h"
-#include "core/html/parser/HTMLToken.h"
-#include "core/html/parser/HTMLTokenizer.h"
#include "core/html/parser/HTMLTreeBuilderSimulator.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/parser/XSSAuditorDelegate.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/WeakPtr.h"
@@ -41,6 +41,7 @@
namespace WebCore {
class HTMLDocumentParser;
+class SharedBuffer;
class XSSAuditor;
class BackgroundHTMLParser {
@@ -51,13 +52,10 @@ public:
WeakPtr<HTMLDocumentParser> parser;
OwnPtr<XSSAuditor> xssAuditor;
OwnPtr<TokenPreloadScanner> preloadScanner;
+ OwnPtr<TextResourceDecoder> decoder;
};
- static void create(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config)
- {
- new BackgroundHTMLParser(reference, config);
- // Caller must free by calling stop().
- }
+ static void start(PassRefPtr<WeakReference<BackgroundHTMLParser> >, PassOwnPtr<Configuration>);
struct Checkpoint {
WeakPtr<HTMLDocumentParser> parser;
@@ -69,7 +67,11 @@ public:
String unparsedInput;
};
- void append(const String&);
+ void appendRawBytesFromParserThread(const char* data, int dataLength);
+
+ void appendRawBytesFromMainThread(PassOwnPtr<Vector<char> >);
+ void setDecoder(PassOwnPtr<TextResourceDecoder>);
+ void flush();
void resumeFrom(PassOwnPtr<Checkpoint>);
void startedChunkWithCheckpoint(HTMLInputCheckpoint);
void finish();
@@ -79,10 +81,13 @@ public:
private:
BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> >, PassOwnPtr<Configuration>);
+ ~BackgroundHTMLParser();
+ void appendDecodedBytes(const String&);
void markEndOfFile();
void pumpTokenizer();
void sendTokensToMainThread();
+ void updateDocument(const String& decodedData);
WeakPtrFactory<BackgroundHTMLParser> m_weakFactory;
BackgroundHTMLInputStream m_input;
@@ -99,6 +104,8 @@ private:
OwnPtr<XSSAuditor> m_xssAuditor;
OwnPtr<TokenPreloadScanner> m_preloadScanner;
+ OwnPtr<TextResourceDecoder> m_decoder;
+ DocumentEncodingData m_lastSeenEncodingData;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
index b1eea275aaa..042c52a86c8 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp
@@ -28,7 +28,7 @@
#include "config.h"
#include "core/html/parser/CSSPreloadScanner.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "platform/text/SegmentedString.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
index 7161a27434e..8c328997553 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.h
@@ -33,7 +33,6 @@
namespace WebCore {
-class HTMLIdentifier;
class SegmentedString;
class CSSPreloadScanner {
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
index 96dc2484b4b..71d5b6b14c8 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -25,19 +25,20 @@
*/
#include "config.h"
-#include "core/html/parser/HTMLTreeBuilder.h"
+#include "core/html/parser/HTMLConstructionSite.h"
-#include "HTMLElementFactory.h"
-#include "HTMLNames.h"
+#include "core/HTMLElementFactory.h"
+#include "core/HTMLNames.h"
#include "core/dom/Comment.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
#include "core/dom/ScriptLoader.h"
#include "core/dom/Text.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLOptGroupElement.h"
+#include "core/html/HTMLPlugInElement.h"
#include "core/html/HTMLScriptElement.h"
#include "core/html/HTMLTemplateElement.h"
#include "core/html/parser/AtomicHTMLToken.h"
@@ -46,7 +47,7 @@
#include "core/html/parser/HTMLToken.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
+#include "core/svg/SVGScriptElement.h"
#include "platform/NotImplemented.h"
#include "platform/text/TextBreakIterator.h"
#include <limits>
@@ -70,20 +71,20 @@ static bool hasImpliedEndTag(const HTMLStackItem* item)
|| item->hasTagName(dtTag)
|| item->hasTagName(liTag)
|| item->hasTagName(optionTag)
- || isHTMLOptGroupElement(item->node())
+ || item->hasTagName(optgroupTag)
|| item->hasTagName(pTag)
|| item->hasTagName(rpTag)
|| item->hasTagName(rtTag);
}
-static bool shouldUseLengthLimit(const ContainerNode* node)
+static bool shouldUseLengthLimit(const ContainerNode& node)
{
- return !node->hasTagName(scriptTag)
- && !node->hasTagName(styleTag)
- && !node->hasTagName(SVGNames::scriptTag);
+ return !isHTMLScriptElement(node)
+ && !isHTMLStyleElement(node)
+ && !isSVGScriptElement(node);
}
-static unsigned textLengthLimitForContainer(const ContainerNode* node)
+static unsigned textLengthLimitForContainer(const ContainerNode& node)
{
return shouldUseLengthLimit(node) ? Text::defaultLengthLimit : std::numeric_limits<unsigned>::max();
}
@@ -95,7 +96,7 @@ static inline bool isAllWhitespace(const String& string)
static inline void insert(HTMLConstructionSiteTask& task)
{
- if (task.parent->hasTagName(templateTag))
+ if (isHTMLTemplateElement(*task.parent))
task.parent = toHTMLTemplateElement(task.parent.get())->content();
if (ContainerNode* parent = task.child->parentNode())
@@ -113,10 +114,12 @@ static inline void executeInsertTask(HTMLConstructionSiteTask& task)
insert(task);
- task.child->beginParsingChildren();
-
- if (task.selfClosing)
- task.child->finishParsingChildren();
+ if (task.child->isElementNode()) {
+ Element& child = toElement(*task.child);
+ child.beginParsingChildren();
+ if (task.selfClosing)
+ child.finishParsingChildren();
+ }
}
static inline void executeInsertTextTask(HTMLConstructionSiteTask& task)
@@ -130,7 +133,7 @@ static inline void executeInsertTextTask(HTMLConstructionSiteTask& task)
Node* previousChild = task.nextChild ? task.nextChild->previousSibling() : task.parent->lastChild();
if (previousChild && previousChild->isTextNode()) {
Text* previousText = toText(previousChild);
- unsigned lengthLimit = textLengthLimitForContainer(task.parent.get());
+ unsigned lengthLimit = textLengthLimitForContainer(*task.parent);
if (previousText->length() + newText->length() < lengthLimit) {
previousText->parserAppendData(newText->data());
return;
@@ -238,7 +241,7 @@ void HTMLConstructionSite::flushPendingText()
// Splitting text nodes into smaller chunks contradicts HTML5 spec, but is necessary
// for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898
- unsigned lengthLimit = textLengthLimitForContainer(pendingText.parent.get());
+ unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent);
unsigned currentPosition = 0;
const StringBuilder& string = pendingText.stringBuilder;
@@ -269,10 +272,10 @@ void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task)
m_taskQueue.append(task);
}
-void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> prpChild, bool selfClosing)
+void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtrWillBeRawPtr<Node> prpChild, bool selfClosing)
{
ASSERT(scriptingContentIsAllowed(m_parserContentPolicy) || !prpChild.get()->isElementNode() || !toScriptLoaderIfPossible(toElement(prpChild.get())));
- ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || !prpChild->isPluginElement());
+ ASSERT(pluginContentIsAllowed(m_parserContentPolicy) || !isHTMLPlugInElement(prpChild));
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
task.parent = parent;
@@ -343,14 +346,26 @@ HTMLConstructionSite::~HTMLConstructionSite()
ASSERT(m_pendingText.isEmpty());
}
+void HTMLConstructionSite::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_attachmentRoot);
+ visitor->trace(m_head);
+ visitor->trace(m_form);
+ visitor->trace(m_openElements);
+ visitor->trace(m_activeFormattingElements);
+ visitor->trace(m_taskQueue);
+ visitor->trace(m_pendingText);
+}
+
void HTMLConstructionSite::detach()
{
// FIXME: We'd like to ASSERT here that we're canceling and not just discarding
// text that really should have made it into the DOM earlier, but there
// doesn't seem to be a nice way to do that.
m_pendingText.discard();
- m_document = 0;
- m_attachmentRoot = 0;
+ m_document = nullptr;
+ m_attachmentRoot = nullptr;
}
void HTMLConstructionSite::setForm(HTMLFormElement* form)
@@ -360,7 +375,7 @@ void HTMLConstructionSite::setForm(HTMLFormElement* form)
m_form = form;
}
-PassRefPtr<HTMLFormElement> HTMLConstructionSite::takeForm()
+PassRefPtrWillBeRawPtr<HTMLFormElement> HTMLConstructionSite::takeForm()
{
return m_form.release();
}
@@ -375,7 +390,7 @@ void HTMLConstructionSite::dispatchDocumentElementAvailableIfNeeded()
void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken* token)
{
ASSERT(m_document);
- RefPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(*m_document);
+ RefPtrWillBeRawPtr<HTMLHtmlElement> element = HTMLHtmlElement::create(*m_document);
setAttributes(element.get(), token, m_parserContentPolicy);
attachLater(m_attachmentRoot, element);
m_openElements.pushHTMLHtmlElement(HTMLStackItem::create(element, token));
@@ -392,7 +407,7 @@ void HTMLConstructionSite::mergeAttributesFromTokenIntoElement(AtomicHTMLToken*
for (unsigned i = 0; i < token->attributes().size(); ++i) {
const Attribute& tokenAttribute = token->attributes().at(i);
- if (!element->elementData() || !element->getAttributeItem(tokenAttribute.name()))
+ if (!element->elementData() || !element->findAttributeByName(tokenAttribute.name()))
element->setAttribute(tokenAttribute.name(), tokenAttribute.value());
}
}
@@ -416,8 +431,6 @@ void HTMLConstructionSite::setDefaultCompatibilityMode()
{
if (m_isParsingFragment)
return;
- if (m_document->isSrcdocDocument())
- return;
setCompatibilityMode(Document::QuirksMode);
}
@@ -536,7 +549,7 @@ void HTMLConstructionSite::insertDoctype(AtomicHTMLToken* token)
const String& publicId = StringImpl::create8BitIfPossible(token->publicIdentifier());
const String& systemId = StringImpl::create8BitIfPossible(token->systemIdentifier());
- RefPtr<DocumentType> doctype = DocumentType::create(m_document, token->name(), publicId, systemId);
+ RefPtrWillBeRawPtr<DocumentType> doctype = DocumentType::create(m_document, token->name(), publicId, systemId);
attachLater(m_attachmentRoot, doctype.release());
// DOCTYPE nodes are only processed when parsing fragments w/o contextElements, which
@@ -586,26 +599,26 @@ void HTMLConstructionSite::insertHTMLHeadElement(AtomicHTMLToken* token)
void HTMLConstructionSite::insertHTMLBodyElement(AtomicHTMLToken* token)
{
ASSERT(!shouldFosterParent());
- RefPtr<Element> body = createHTMLElement(token);
+ RefPtrWillBeRawPtr<Element> body = createHTMLElement(token);
attachLater(currentNode(), body);
m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.release(), token));
- if (Frame* frame = m_document->frame())
+ if (LocalFrame* frame = m_document->frame())
frame->loader().client()->dispatchWillInsertBody();
}
void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
{
- RefPtr<Element> element = createHTMLElement(token);
- ASSERT(element->hasTagName(formTag));
+ RefPtrWillBeRawPtr<Element> element = createHTMLElement(token);
+ ASSERT(isHTMLFormElement(element));
m_form = static_pointer_cast<HTMLFormElement>(element.release());
m_form->setDemoted(isDemoted);
- attachLater(currentNode(), m_form);
- m_openElements.push(HTMLStackItem::create(m_form, token));
+ attachLater(currentNode(), m_form.get());
+ m_openElements.push(HTMLStackItem::create(m_form.get(), token));
}
void HTMLConstructionSite::insertHTMLElement(AtomicHTMLToken* token)
{
- RefPtr<Element> element = createHTMLElement(token);
+ RefPtrWillBeRawPtr<Element> element = createHTMLElement(token);
attachLater(currentNode(), element);
m_openElements.push(HTMLStackItem::create(element.release(), token));
}
@@ -639,7 +652,7 @@ void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
// those flags or effects thereof.
const bool parserInserted = m_parserContentPolicy != AllowScriptingContentAndDoNotMarkAlreadyStarted;
const bool alreadyStarted = m_isParsingFragment && parserInserted;
- RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
+ RefPtrWillBeRawPtr<HTMLScriptElement> element = HTMLScriptElement::create(ownerDocumentForCurrentNode(), parserInserted, alreadyStarted);
setAttributes(element.get(), token, m_parserContentPolicy);
if (scriptingContentIsAllowed(m_parserContentPolicy))
attachLater(currentNode(), element);
@@ -651,7 +664,7 @@ void HTMLConstructionSite::insertForeignElement(AtomicHTMLToken* token, const At
ASSERT(token->type() == HTMLToken::StartTag);
notImplemented(); // parseError when xmlns or xmlns:xlink are wrong.
- RefPtr<Element> element = createElement(token, namespaceURI);
+ RefPtrWillBeRawPtr<Element> element = createElement(token, namespaceURI);
if (scriptingContentIsAllowed(m_parserContentPolicy) || !toScriptLoaderIfPossible(element.get()))
attachLater(currentNode(), element, token->selfClosing());
if (!token->selfClosing())
@@ -667,7 +680,7 @@ void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w
findFosterSite(dummyTask);
// FIXME: This probably doesn't need to be done both here and in insert(Task).
- if (dummyTask.parent->hasTagName(templateTag))
+ if (isHTMLTemplateElement(*dummyTask.parent))
dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->content();
// Unclear when parent != case occurs. Somehow we insert text into two separate nodes while processing the same Token.
@@ -715,22 +728,22 @@ void HTMLConstructionSite::takeAllChildren(HTMLStackItem* newParent, HTMLElement
queueTask(task);
}
-PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
+PassRefPtrWillBeRawPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
{
QualifiedName tagName(nullAtom, token->name(), namespaceURI);
- RefPtr<Element> element = ownerDocumentForCurrentNode().createElement(tagName, true);
+ RefPtrWillBeRawPtr<Element> element = ownerDocumentForCurrentNode().createElement(tagName, true);
setAttributes(element.get(), token, m_parserContentPolicy);
return element.release();
}
inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
{
- if (currentNode()->hasTagName(templateTag))
+ if (isHTMLTemplateElement(*currentNode()))
return toHTMLTemplateElement(currentElement())->content()->document();
return currentNode()->document();
}
-PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
+PassRefPtrWillBeRawPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
{
Document& document = ownerDocumentForCurrentNode();
// Only associate the element with the current form if we're creating the new element
@@ -739,15 +752,15 @@ PassRefPtr<Element> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* tok
// FIXME: This can't use HTMLConstructionSite::createElement because we
// have to pass the current form element. We should rework form association
// to occur after construction to allow better code sharing here.
- RefPtr<Element> element = HTMLElementFactory::createHTMLElement(token->name(), document, form, true);
+ RefPtrWillBeRawPtr<Element> element = HTMLElementFactory::createHTMLElement(token->name(), document, form, true);
setAttributes(element.get(), token, m_parserContentPolicy);
ASSERT(element->isHTMLElement());
return element.release();
}
-PassRefPtr<HTMLStackItem> HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item)
+PassRefPtrWillBeRawPtr<HTMLStackItem> HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item)
{
- RefPtr<Element> element;
+ RefPtrWillBeRawPtr<Element> element;
// NOTE: Moving from item -> token -> item copies the Attribute vector twice!
AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attributes());
if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI)
@@ -784,7 +797,7 @@ void HTMLConstructionSite::reconstructTheActiveFormattingElements()
ASSERT(unopenEntryIndex < m_activeFormattingElements.size());
for (; unopenEntryIndex < m_activeFormattingElements.size(); ++unopenEntryIndex) {
HTMLFormattingElementList::Entry& unopenedEntry = m_activeFormattingElements.at(unopenEntryIndex);
- RefPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem().get());
+ RefPtrWillBeRawPtr<HTMLStackItem> reconstructed = createElementFromSavedToken(unopenedEntry.stackItem().get());
attachLater(currentNode(), reconstructed->node());
m_openElements.push(reconstructed);
unopenedEntry.replaceElement(reconstructed.release());
@@ -847,7 +860,7 @@ bool HTMLConstructionSite::shouldFosterParent() const
&& currentStackItem()->causesFosterParenting();
}
-void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node)
+void HTMLConstructionSite::fosterParent(PassRefPtrWillBeRawPtr<Node> node)
{
HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert);
findFosterSite(task);
@@ -856,4 +869,11 @@ void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node)
queueTask(task);
}
+void HTMLConstructionSite::PendingText::trace(Visitor* visitor)
+{
+ visitor->trace(parent);
+ visitor->trace(nextChild);
+}
+
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
index d4d812eb109..0bd25a0fa62 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.h
@@ -27,6 +27,7 @@
#ifndef HTMLConstructionSite_h
#define HTMLConstructionSite_h
+#include "core/dom/Document.h"
#include "core/dom/ParserContentPolicy.h"
#include "core/html/parser/HTMLElementStack.h"
#include "core/html/parser/HTMLFormattingElementList.h"
@@ -39,6 +40,8 @@
namespace WebCore {
struct HTMLConstructionSiteTask {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
enum Operation {
Insert,
InsertText, // Handles possible merging of text nodes.
@@ -53,6 +56,13 @@ struct HTMLConstructionSiteTask {
{
}
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(parent);
+ visitor->trace(nextChild);
+ visitor->trace(child);
+ }
+
ContainerNode* oldParent()
{
// It's sort of ugly, but we store the |oldParent| in the |child| field
@@ -62,17 +72,15 @@ struct HTMLConstructionSiteTask {
}
Operation operation;
- RefPtr<ContainerNode> parent;
- RefPtr<Node> nextChild;
- RefPtr<Node> child;
+ RefPtrWillBeMember<ContainerNode> parent;
+ RefPtrWillBeMember<Node> nextChild;
+ RefPtrWillBeMember<Node> child;
bool selfClosing;
};
} // namespace WebCore
-namespace WTF {
-template<> struct VectorTraits<WebCore::HTMLConstructionSiteTask> : SimpleClassVectorTraits { };
-} // namespace WTF
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::HTMLConstructionSiteTask);
namespace WebCore {
@@ -89,12 +97,14 @@ class Document;
class Element;
class HTMLFormElement;
-class HTMLConstructionSite {
+class HTMLConstructionSite FINAL {
WTF_MAKE_NONCOPYABLE(HTMLConstructionSite);
+ DISALLOW_ALLOCATION();
public:
HTMLConstructionSite(Document*, ParserContentPolicy);
HTMLConstructionSite(DocumentFragment*, ParserContentPolicy);
~HTMLConstructionSite();
+ void trace(Visitor*);
void detach();
@@ -150,10 +160,10 @@ public:
void insertAlreadyParsedChild(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* child);
void takeAllChildren(HTMLStackItem* newParent, HTMLElementStack::ElementRecord* oldParent);
- PassRefPtr<HTMLStackItem> createElementFromSavedToken(HTMLStackItem*);
+ PassRefPtrWillBeRawPtr<HTMLStackItem> createElementFromSavedToken(HTMLStackItem*);
bool shouldFosterParent() const;
- void fosterParent(PassRefPtr<Node>);
+ void fosterParent(PassRefPtrWillBeRawPtr<Node>);
bool indexOfFirstUnopenFormattingElement(unsigned& firstUnopenElementIndex) const;
void reconstructTheActiveFormattingElements();
@@ -179,7 +189,7 @@ public:
void setForm(HTMLFormElement*);
HTMLFormElement* form() const { return m_form.get(); }
- PassRefPtr<HTMLFormElement> takeForm();
+ PassRefPtrWillBeRawPtr<HTMLFormElement> takeForm();
ParserContentPolicy parserContentPolicy() { return m_parserContentPolicy; }
@@ -206,17 +216,17 @@ public:
private:
// In the common case, this queue will have only one task because most
// tokens produce only one DOM mutation.
- typedef Vector<HTMLConstructionSiteTask, 1> TaskQueue;
+ typedef WillBeHeapVector<HTMLConstructionSiteTask, 1> TaskQueue;
void setCompatibilityMode(Document::CompatibilityMode);
void setCompatibilityModeFromDoctype(const String& name, const String& publicId, const String& systemId);
- void attachLater(ContainerNode* parent, PassRefPtr<Node> child, bool selfClosing = false);
+ void attachLater(ContainerNode* parent, PassRefPtrWillBeRawPtr<Node> child, bool selfClosing = false);
void findFosterSite(HTMLConstructionSiteTask&);
- PassRefPtr<Element> createHTMLElement(AtomicHTMLToken*);
- PassRefPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
+ PassRefPtrWillBeRawPtr<Element> createHTMLElement(AtomicHTMLToken*);
+ PassRefPtrWillBeRawPtr<Element> createElement(AtomicHTMLToken*, const AtomicString& namespaceURI);
void mergeAttributesFromTokenIntoElement(AtomicHTMLToken*, Element*);
void dispatchDocumentElementAvailableIfNeeded();
@@ -224,27 +234,29 @@ private:
void executeTask(HTMLConstructionSiteTask&);
void queueTask(const HTMLConstructionSiteTask&);
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
// This is the root ContainerNode to which the parser attaches all newly
// constructed nodes. It points to a DocumentFragment when parsing fragments
// and a Document in all other cases.
- ContainerNode* m_attachmentRoot;
+ RawPtrWillBeMember<ContainerNode> m_attachmentRoot;
- RefPtr<HTMLStackItem> m_head;
- RefPtr<HTMLFormElement> m_form;
+ RefPtrWillBeMember<HTMLStackItem> m_head;
+ RefPtrWillBeMember<HTMLFormElement> m_form;
mutable HTMLElementStack m_openElements;
mutable HTMLFormattingElementList m_activeFormattingElements;
TaskQueue m_taskQueue;
- struct PendingText {
+ class PendingText FINAL {
+ DISALLOW_ALLOCATION();
+ public:
PendingText()
: whitespaceMode(WhitespaceUnknown)
{
}
- void append(PassRefPtr<ContainerNode> newParent, PassRefPtr<Node> newNextChild, const String& newString, WhitespaceMode newWhitespaceMode)
+ void append(PassRefPtrWillBeRawPtr<ContainerNode> newParent, PassRefPtrWillBeRawPtr<Node> newNextChild, const String& newString, WhitespaceMode newWhitespaceMode)
{
ASSERT(!parent || parent == newParent);
parent = newParent;
@@ -277,8 +289,10 @@ private:
return stringBuilder.isEmpty();
}
- RefPtr<ContainerNode> parent;
- RefPtr<Node> nextChild;
+ void trace(Visitor*);
+
+ RefPtrWillBeMember<ContainerNode> parent;
+ RefPtrWillBeMember<Node> nextChild;
StringBuilder stringBuilder;
WhitespaceMode whitespaceMode;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
index 2008ae5f0e1..e5a4d251b1c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -26,9 +26,11 @@
#include "config.h"
#include "core/html/parser/HTMLDocumentParser.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/css/MediaValuesCached.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/Element.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLDocument.h"
#include "core/html/parser/AtomicHTMLToken.h"
#include "core/html/parser/BackgroundHTMLParser.h"
@@ -37,8 +39,11 @@
#include "core/html/parser/HTMLScriptRunner.h"
#include "core/html/parser/HTMLTreeBuilder.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
+#include "core/inspector/InspectorTraceEvents.h"
+#include "core/loader/DocumentLoader.h"
+#include "platform/SharedBuffer.h"
#include "platform/TraceEvent.h"
+#include "public/platform/WebThreadedDataReceiver.h"
#include "wtf/Functional.h"
namespace WebCore {
@@ -70,17 +75,44 @@ static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
return HTMLTokenizer::DataState;
}
-HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors)
+class ParserDataReceiver : public blink::WebThreadedDataReceiver {
+public:
+ explicit ParserDataReceiver(WeakPtr<BackgroundHTMLParser> backgroundParser)
+ : m_backgroundParser(backgroundParser)
+ {
+ }
+
+ // WebThreadedDataReceiver
+ virtual void acceptData(const char* data, int dataLength) OVERRIDE FINAL
+ {
+ ASSERT(backgroundThread() && backgroundThread()->isCurrentThread());
+ if (m_backgroundParser.get())
+ m_backgroundParser.get()->appendRawBytesFromParserThread(data, dataLength);
+ }
+
+ virtual blink::WebThread* backgroundThread() OVERRIDE FINAL
+ {
+ if (HTMLParserThread::shared())
+ return &HTMLParserThread::shared()->platformThread();
+
+ return 0;
+ }
+
+private:
+ WeakPtr<BackgroundHTMLParser> m_backgroundParser;
+};
+
+HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, bool reportErrors)
: ScriptableDocumentParser(document)
- , m_options(document)
+ , m_options(&document)
, m_token(m_options.useThreading ? nullptr : adoptPtr(new HTMLToken))
, m_tokenizer(m_options.useThreading ? nullptr : HTMLTokenizer::create(m_options))
- , m_scriptRunner(HTMLScriptRunner::create(document, this))
- , m_treeBuilder(HTMLTreeBuilder::create(this, document, parserContentPolicy(), reportErrors, m_options))
+ , m_scriptRunner(HTMLScriptRunner::create(&document, this))
+ , m_treeBuilder(HTMLTreeBuilder::create(this, &document, parserContentPolicy(), reportErrors, m_options))
, m_parserScheduler(HTMLParserScheduler::create(this))
- , m_xssAuditorDelegate(document)
+ , m_xssAuditorDelegate(&document)
, m_weakFactory(this)
- , m_preloader(adoptPtr(new HTMLResourcePreloader(document)))
+ , m_preloader(adoptPtr(new HTMLResourcePreloader(&document)))
, m_isPinnedToMainThread(false)
, m_endWasDelayed(false)
, m_haveBackgroundParser(false)
@@ -92,7 +124,7 @@ HTMLDocumentParser::HTMLDocumentParser(HTMLDocument* document, bool reportErrors
// FIXME: Member variables should be grouped into self-initializing structs to
// minimize code duplication between these constructors.
HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
- : ScriptableDocumentParser(&fragment->document(), parserContentPolicy)
+ : ScriptableDocumentParser(fragment->document(), parserContentPolicy)
, m_options(&fragment->document())
, m_token(adoptPtr(new HTMLToken))
, m_tokenizer(HTMLTokenizer::create(m_options))
@@ -112,6 +144,12 @@ HTMLDocumentParser::HTMLDocumentParser(DocumentFragment* fragment, Element* cont
HTMLDocumentParser::~HTMLDocumentParser()
{
+#if ENABLE(OILPAN)
+ if (m_haveBackgroundParser)
+ stopBackgroundParser();
+ // In Oilpan, HTMLDocumentParser can die together with Document, and
+ // detach() is not called in this case.
+#else
ASSERT(!m_parserScheduler);
ASSERT(!m_pumpSessionNestingLevel);
ASSERT(!m_preloadScanner);
@@ -120,6 +158,15 @@ HTMLDocumentParser::~HTMLDocumentParser()
// FIXME: We should be able to ASSERT(m_speculations.isEmpty()),
// but there are cases where that's not true currently. For example,
// we we're told to stop parsing before we've consumed all the input.
+#endif
+}
+
+void HTMLDocumentParser::trace(Visitor* visitor)
+{
+ visitor->trace(m_treeBuilder);
+ visitor->trace(m_scriptRunner);
+ ScriptableDocumentParser::trace(visitor);
+ HTMLScriptRunnerHost::trace(visitor);
}
void HTMLDocumentParser::pinToMainThread()
@@ -167,7 +214,7 @@ void HTMLDocumentParser::prepareToStopParsing()
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
// NOTE: This pump should only ever emit buffered character tokens,
// so ForceSynchronous vs. AllowYield should be meaningless.
@@ -230,7 +277,7 @@ void HTMLDocumentParser::resumeParsingAfterYield()
ASSERT(!m_isPinnedToMainThread);
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
if (m_haveBackgroundParser) {
pumpPendingSpeculations();
@@ -248,7 +295,7 @@ void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
ASSERT(scriptingContentIsAllowed(parserContentPolicy()));
TextPosition scriptStartPosition = TextPosition::belowRangePosition();
- RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
+ RefPtrWillBeRawPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
// We will not have a scriptRunner when parsing a DocumentFragment.
if (m_scriptRunner)
m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
@@ -263,7 +310,7 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
if (isWaitingForScripts()) {
if (mode == AllowYield)
- m_parserScheduler->checkForYieldBeforeScript(session);
+ session.didSeeScript = true;
// If we don't run the script, we cannot allow the next token to be taken.
if (session.needsYield)
@@ -278,7 +325,7 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
}
// FIXME: It's wrong for the HTMLDocumentParser to reach back to the
- // Frame, but this approach is how the old parser handled
+ // LocalFrame, but this approach is how the old parser handled
// stopping when the page assigns window.location. What really
// should happen is that assigning window.location causes the
// parser to stop parsing cleanly. The problem is we're not
@@ -308,7 +355,7 @@ void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa
// processParsedChunkFromBackgroundParser can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
ASSERT(m_speculations.isEmpty());
chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately.
@@ -316,6 +363,11 @@ void HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<Pa
pumpPendingSpeculations();
}
+void HTMLDocumentParser::didReceiveEncodingDataFromBackgroundParser(const DocumentEncodingData& data)
+{
+ document()->setEncodingData(data);
+}
+
void HTMLDocumentParser::validateSpeculations(PassOwnPtr<ParsedChunk> chunk)
{
ASSERT(chunk);
@@ -382,8 +434,10 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
ASSERT(!isParsingFragment());
ASSERT(!isWaitingForScripts());
ASSERT(!isStopped());
+#if !ENABLE(OILPAN)
// ASSERT that this object is both attached to the Document and protected.
ASSERT(refCount() >= 2);
+#endif
ASSERT(shouldUseThreading());
ASSERT(!m_tokenizer);
ASSERT(!m_token);
@@ -406,8 +460,7 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
for (Vector<CompactHTMLToken>::const_iterator it = tokens->begin(); it != tokens->end(); ++it) {
ASSERT(!isWaitingForScripts());
- if (!isParsingFragment()
- && document()->frame() && document()->frame()->navigationScheduler().locationChangePending()) {
+ if (document()->frame() && document()->frame()->navigationScheduler().locationChangePending()) {
// To match main-thread parser behavior (which never checks locationChangePending on the EOF path)
// we peek to see if this chunk has an EOF and process it anyway.
@@ -442,6 +495,10 @@ void HTMLDocumentParser::processParsedChunkFromBackgroundParser(PassOwnPtr<Parse
ASSERT(!m_tokenizer);
ASSERT(!m_token);
}
+
+ // Make sure any pending text nodes are emitted before returning.
+ if (!isStopped())
+ m_treeBuilder->flush();
}
void HTMLDocumentParser::pumpPendingSpeculations()
@@ -449,8 +506,10 @@ void HTMLDocumentParser::pumpPendingSpeculations()
// FIXME: Share this constant with the parser scheduler.
const double parserTimeLimit = 0.500;
+#if !ENABLE(OILPAN)
// ASSERT that this object is both attached to the Document and protected.
ASSERT(refCount() >= 2);
+#endif
// If this assert fails, you need to call validateSpeculations to make sure
// m_tokenizer and m_token don't have state that invalidates m_speculations.
ASSERT(!m_tokenizer);
@@ -460,6 +519,9 @@ void HTMLDocumentParser::pumpPendingSpeculations()
ASSERT(!isStopped());
// FIXME: Pass in current input length.
+ TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "beginData", InspectorParseHtmlEvent::beginData(document(), lineNumber().zeroBasedInt()));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), lineNumber().zeroBasedInt());
double startTime = currentTime();
@@ -467,11 +529,8 @@ void HTMLDocumentParser::pumpPendingSpeculations()
while (!m_speculations.isEmpty()) {
processParsedChunkFromBackgroundParser(m_speculations.takeFirst());
- // The order matters! If this isStopped(), isWaitingForScripts() can hit and ASSERT since
- // m_document can be null which is used to decide the readiness.
- if (isStopped())
- break;
- if (isWaitingForScripts())
+ // Always check isStopped first as m_document may be null.
+ if (isStopped() || isWaitingForScripts())
break;
if (currentTime() - startTime > parserTimeLimit && !m_speculations.isEmpty()) {
@@ -480,7 +539,10 @@ void HTMLDocumentParser::pumpPendingSpeculations()
}
}
+ TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "endLine", lineNumber().zeroBasedInt());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didWriteHTML(cookie, lineNumber().zeroBasedInt());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
}
void HTMLDocumentParser::forcePlaintextForTextDocument()
@@ -505,12 +567,22 @@ Document* HTMLDocumentParser::contextForParsingSession()
return document();
}
+static PassRefPtr<MediaValues> createMediaValues(Document* document)
+{
+ ASSERT(document);
+ RefPtr<MediaValues> mediaValues = MediaValuesCached::create(*document);
+ ASSERT(mediaValues->isSafeToSendToAnotherThread());
+ return mediaValues;
+}
+
void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
{
ASSERT(!isStopped());
ASSERT(!isScheduledForResume());
+#if !ENABLE(OILPAN)
// ASSERT that this object is both attached to the Document and protected.
ASSERT(refCount() >= 2);
+#endif
ASSERT(m_tokenizer);
ASSERT(m_token);
ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
@@ -522,6 +594,9 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
// FIXME: m_input.current().length() is only accurate if we
// end up parsing the whole buffer in this pump. We should pass how
// much we parsed as part of didWriteHTML instead of willWriteHTML.
+ TRACE_EVENT_BEGIN1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "beginData", InspectorParseHtmlEvent::beginData(document(), m_input.current().currentLine().zeroBasedInt()));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), m_input.current().currentLine().zeroBasedInt());
m_xssAuditor.init(document(), &m_xssAuditorDelegate);
@@ -546,9 +621,11 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
ASSERT(token().isUninitialized());
}
+#if !ENABLE(OILPAN)
// Ensure we haven't been totally deref'ed after pumping. Any caller of this
// function should be holding a RefPtr to this to ensure we weren't deleted.
ASSERT(refCount() >= 1);
+#endif
if (isStopped())
return;
@@ -565,12 +642,14 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
if (isWaitingForScripts()) {
ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
if (!m_preloadScanner) {
- m_preloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, document()->url(), document()->devicePixelRatio()));
+ m_preloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, document()->url(), createMediaValues(document())));
m_preloadScanner->appendToEnd(m_input.current());
}
m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
+ TRACE_EVENT_END1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ParseHTML", "endLine", m_input.current().currentLine().zeroBasedInt());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didWriteHTML(cookie, m_input.current().currentLine().zeroBasedInt());
}
@@ -620,11 +699,11 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
if (isStopped())
return;
- TRACE_EVENT0("webkit", "HTMLDocumentParser::insert");
+ TRACE_EVENT1("webkit", "HTMLDocumentParser::insert", "source_length", source.length());
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
if (!m_tokenizer) {
ASSERT(!inPumpSession());
@@ -642,7 +721,7 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
// Check the document.write() output with a separate preload scanner as
// the main scanner can't deal with insertions.
if (!m_insertionPreloadScanner)
- m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, document()->url(), document()->devicePixelRatio()));
+ m_insertionPreloadScanner = adoptPtr(new HTMLPreloadScanner(m_options, document()->url(), createMediaValues(document())));
m_insertionPreloadScanner->appendToEnd(source);
m_insertionPreloadScanner->scan(m_preloader.get(), document()->baseElementURL());
@@ -653,6 +732,7 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
void HTMLDocumentParser::startBackgroundParser()
{
+ ASSERT(!isStopped());
ASSERT(shouldUseThreading());
ASSERT(!m_haveBackgroundParser);
m_haveBackgroundParser = true;
@@ -660,16 +740,21 @@ void HTMLDocumentParser::startBackgroundParser()
RefPtr<WeakReference<BackgroundHTMLParser> > reference = WeakReference<BackgroundHTMLParser>::createUnbound();
m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference);
+ // TODO(oysteine): Disabled due to crbug.com/398076 until a full fix can be implemented.
+ if (RuntimeEnabledFeatures::threadedParserDataReceiverEnabled())
+ document()->loader()->attachThreadedDataReceiver(adoptPtr(new ParserDataReceiver(m_backgroundParser)));
+
OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new BackgroundHTMLParser::Configuration);
config->options = m_options;
config->parser = m_weakFactory.createWeakPtr();
config->xssAuditor = adoptPtr(new XSSAuditor);
config->xssAuditor->init(document(), &m_xssAuditorDelegate);
- config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url().copy(), document()->devicePixelRatio()));
+ config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url().copy(), createMediaValues(document())));
+ config->decoder = takeDecoder();
ASSERT(config->xssAuditor->isSafeToSendToAnotherThread());
ASSERT(config->preloadScanner->isSafeToSendToAnotherThread());
- HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::create, reference.release(), config.release()));
+ HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::start, reference.release(), config.release()));
}
void HTMLDocumentParser::stopBackgroundParser()
@@ -687,23 +772,13 @@ void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
if (isStopped())
return;
- if (shouldUseThreading()) {
- if (!m_haveBackgroundParser)
- startBackgroundParser();
-
- ASSERT(inputSource->hasOneRef());
- TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->length());
- // NOTE: Important that the String temporary is destroyed before we post the task
- // otherwise the String could call deref() on a StringImpl now owned by the background parser.
- // We would like to ASSERT(closure.arg3()->hasOneRef()) but sadly the args are private.
- Closure closure = bind(&BackgroundHTMLParser::append, m_backgroundParser, String(inputSource));
- HTMLParserThread::shared()->postTask(closure);
- return;
- }
+ // We should never reach this point if we're using a parser thread,
+ // as appendBytes() will directly ship the data to the thread.
+ ASSERT(!shouldUseThreading());
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
TRACE_EVENT1("net", "HTMLDocumentParser::append", "size", inputSource->length());
String source(inputSource);
@@ -876,7 +951,7 @@ void HTMLDocumentParser::resumeParsingAfterScriptExecution()
ASSERT(!m_lastChunkBeforeScript);
// processParsedChunkFromBackgroundParser can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
pumpPendingSpeculations();
return;
}
@@ -886,20 +961,6 @@ void HTMLDocumentParser::resumeParsingAfterScriptExecution()
endIfDelayed();
}
-void HTMLDocumentParser::watchForLoad(Resource* resource)
-{
- ASSERT(!resource->isLoaded());
- // addClient would call notifyFinished if the load were complete.
- // Callers do not expect to be re-entered from this call, so they should
- // not an already-loaded Resource.
- resource->addClient(this);
-}
-
-void HTMLDocumentParser::stopWatchingForLoad(Resource* resource)
-{
- resource->removeClient(this);
-}
-
void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan()
{
ASSERT(m_preloadScanner);
@@ -907,11 +968,11 @@ void HTMLDocumentParser::appendCurrentInputStreamToPreloadScannerAndScan()
m_preloadScanner->scan(m_preloader.get(), document()->baseElementURL());
}
-void HTMLDocumentParser::notifyFinished(Resource* cachedResource)
+void HTMLDocumentParser::notifyScriptLoaded(Resource* cachedResource)
{
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
ASSERT(m_scriptRunner);
ASSERT(!isExecutingScript());
@@ -938,7 +999,7 @@ void HTMLDocumentParser::executeScriptsWaitingForResources()
// pumpTokenizer can cause this parser to be detached from the Document,
// but we need to ensure it isn't deleted yet.
- RefPtr<HTMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> protect(this);
m_scriptRunner->executeScriptsWaitingForResources();
if (!isWaitingForScripts())
resumeParsingAfterScriptExecution();
@@ -946,7 +1007,7 @@ void HTMLDocumentParser::executeScriptsWaitingForResources()
void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
{
- RefPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
+ RefPtrWillBeRawPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
parser->insert(source); // Use insert() so that the parser will not yield.
parser->finish();
ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/3963151>
@@ -965,4 +1026,45 @@ void HTMLDocumentParser::resumeScheduledTasks()
m_parserScheduler->resume();
}
+void HTMLDocumentParser::appendBytes(const char* data, size_t length)
+{
+ if (!length || isStopped())
+ return;
+
+ if (shouldUseThreading()) {
+ if (!m_haveBackgroundParser)
+ startBackgroundParser();
+
+ OwnPtr<Vector<char> > buffer = adoptPtr(new Vector<char>(length));
+ memcpy(buffer->data(), data, length);
+ TRACE_EVENT1("net", "HTMLDocumentParser::appendBytes", "size", (unsigned)length);
+
+ HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::appendRawBytesFromMainThread, m_backgroundParser, buffer.release()));
+ return;
+ }
+
+ DecodedDataDocumentParser::appendBytes(data, length);
+}
+
+void HTMLDocumentParser::flush()
+{
+ // If we've got no decoder, we never received any data.
+ if (isDetached() || needsDecoder())
+ return;
+
+ if (m_haveBackgroundParser)
+ HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::flush, m_backgroundParser));
+ else
+ DecodedDataDocumentParser::flush();
+}
+
+void HTMLDocumentParser::setDecoder(PassOwnPtr<TextResourceDecoder> decoder)
+{
+ ASSERT(decoder);
+ DecodedDataDocumentParser::setDecoder(decoder);
+
+ if (m_haveBackgroundParser)
+ HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::setDecoder, m_backgroundParser, takeDecoder()));
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
index 40779561ad3..227cf522507 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.h
@@ -40,6 +40,7 @@
#include "core/html/parser/HTMLToken.h"
#include "core/html/parser/HTMLTokenizer.h"
#include "core/html/parser/HTMLTreeBuilderSimulator.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/parser/XSSAuditor.h"
#include "core/html/parser/XSSAuditorDelegate.h"
#include "platform/text/SegmentedString.h"
@@ -64,14 +65,16 @@ class ScriptSourceCode;
class PumpSession;
-class HTMLDocumentParser : public ScriptableDocumentParser, HTMLScriptRunnerHost, ResourceClient {
- WTF_MAKE_FAST_ALLOCATED;
+class HTMLDocumentParser : public ScriptableDocumentParser, private HTMLScriptRunnerHost {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(HTMLDocumentParser);
public:
- static PassRefPtr<HTMLDocumentParser> create(HTMLDocument* document, bool reportErrors)
+ static PassRefPtrWillBeRawPtr<HTMLDocumentParser> create(HTMLDocument& document, bool reportErrors)
{
- return adoptRef(new HTMLDocumentParser(document, reportErrors));
+ return adoptRefWillBeNoop(new HTMLDocumentParser(document, reportErrors));
}
virtual ~HTMLDocumentParser();
+ virtual void trace(Visitor*) OVERRIDE;
// Exposed for HTMLParserScheduler
void resumeParsingAfterYield();
@@ -80,11 +83,11 @@ public:
HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
- virtual TextPosition textPosition() const;
- virtual OrdinalNumber lineNumber() const;
+ virtual TextPosition textPosition() const OVERRIDE FINAL;
+ virtual OrdinalNumber lineNumber() const OVERRIDE FINAL;
- virtual void suspendScheduledTasks();
- virtual void resumeScheduledTasks();
+ virtual void suspendScheduledTasks() OVERRIDE FINAL;
+ virtual void resumeScheduledTasks() OVERRIDE FINAL;
struct ParsedChunk {
OwnPtr<CompactHTMLTokenStream> tokens;
@@ -96,15 +99,20 @@ public:
TokenPreloadScannerCheckpoint preloadScannerCheckpoint;
};
void didReceiveParsedChunkFromBackgroundParser(PassOwnPtr<ParsedChunk>);
+ void didReceiveEncodingDataFromBackgroundParser(const DocumentEncodingData&);
+
+ virtual void appendBytes(const char* bytes, size_t length) OVERRIDE;
+ virtual void flush() OVERRIDE FINAL;
+ virtual void setDecoder(PassOwnPtr<TextResourceDecoder>) OVERRIDE FINAL;
UseCounter* useCounter() { return UseCounter::getFrom(contextForParsingSession()); }
protected:
- virtual void insert(const SegmentedString&) OVERRIDE;
+ virtual void insert(const SegmentedString&) OVERRIDE FINAL;
virtual void append(PassRefPtr<StringImpl>) OVERRIDE;
- virtual void finish() OVERRIDE;
+ virtual void finish() OVERRIDE FINAL;
- HTMLDocumentParser(HTMLDocument*, bool reportErrors);
+ HTMLDocumentParser(HTMLDocument&, bool reportErrors);
HTMLDocumentParser(DocumentFragment*, Element* contextElement, ParserContentPolicy);
HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
@@ -112,31 +120,27 @@ protected:
void forcePlaintextForTextDocument();
private:
- static PassRefPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
+ static PassRefPtrWillBeRawPtr<HTMLDocumentParser> create(DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
{
- return adoptRef(new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
+ return adoptRefWillBeNoop(new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
}
// DocumentParser
- virtual void pinToMainThread() OVERRIDE;
- virtual void detach() OVERRIDE;
- virtual bool hasInsertionPoint() OVERRIDE;
- virtual bool processingData() const OVERRIDE;
- virtual void prepareToStopParsing() OVERRIDE;
- virtual void stopParsing() OVERRIDE;
- virtual bool isWaitingForScripts() const OVERRIDE;
- virtual bool isExecutingScript() const OVERRIDE;
- virtual void executeScriptsWaitingForResources() OVERRIDE;
+ virtual void pinToMainThread() OVERRIDE FINAL;
+ virtual void detach() OVERRIDE FINAL;
+ virtual bool hasInsertionPoint() OVERRIDE FINAL;
+ virtual bool processingData() const OVERRIDE FINAL;
+ virtual void prepareToStopParsing() OVERRIDE FINAL;
+ virtual void stopParsing() OVERRIDE FINAL;
+ virtual bool isWaitingForScripts() const OVERRIDE FINAL;
+ virtual bool isExecutingScript() const OVERRIDE FINAL;
+ virtual void executeScriptsWaitingForResources() OVERRIDE FINAL;
// HTMLScriptRunnerHost
- virtual void watchForLoad(Resource*) OVERRIDE;
- virtual void stopWatchingForLoad(Resource*) OVERRIDE;
- virtual HTMLInputStream& inputStream() { return m_input; }
- virtual bool hasPreloadScanner() const { return m_preloadScanner.get() && !shouldUseThreading(); }
- virtual void appendCurrentInputStreamToPreloadScannerAndScan() OVERRIDE;
-
- // ResourceClient
- virtual void notifyFinished(Resource*);
+ virtual void notifyScriptLoaded(Resource*) OVERRIDE FINAL;
+ virtual HTMLInputStream& inputStream() OVERRIDE FINAL { return m_input; }
+ virtual bool hasPreloadScanner() const OVERRIDE FINAL { return m_preloadScanner.get() && !shouldUseThreading(); }
+ virtual void appendCurrentInputStreamToPreloadScannerAndScan() OVERRIDE FINAL;
void startBackgroundParser();
void stopBackgroundParser();
@@ -179,8 +183,8 @@ private:
OwnPtr<HTMLToken> m_token;
OwnPtr<HTMLTokenizer> m_tokenizer;
- OwnPtr<HTMLScriptRunner> m_scriptRunner;
- OwnPtr<HTMLTreeBuilder> m_treeBuilder;
+ OwnPtrWillBeMember<HTMLScriptRunner> m_scriptRunner;
+ OwnPtrWillBeMember<HTMLTreeBuilder> m_treeBuilder;
OwnPtr<HTMLPreloadScanner> m_preloadScanner;
OwnPtr<HTMLPreloadScanner> m_insertionPreloadScanner;
OwnPtr<HTMLParserScheduler> m_parserScheduler;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
index 9adfdf1612c..5ea0549dbae 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.cpp
@@ -27,13 +27,11 @@
#include "config.h"
#include "core/html/parser/HTMLElementStack.h"
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Element.h"
-#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLOptGroupElement.h"
-#include "core/html/HTMLTableElement.h"
+#include "core/html/HTMLElement.h"
namespace WebCore {
@@ -45,7 +43,7 @@ namespace {
inline bool isRootNode(HTMLStackItem* item)
{
return item->isDocumentFragmentNode()
- || isHTMLHtmlElement(item->node());
+ || item->hasTagName(htmlTag);
}
inline bool isScopeMarker(HTMLStackItem* item)
@@ -54,7 +52,7 @@ inline bool isScopeMarker(HTMLStackItem* item)
|| item->hasTagName(captionTag)
|| item->hasTagName(marqueeTag)
|| item->hasTagName(objectTag)
- || isHTMLTableElement(item->node())
+ || item->hasTagName(tableTag)
|| item->hasTagName(tdTag)
|| item->hasTagName(thTag)
|| item->hasTagName(MathMLNames::miTag)
@@ -79,7 +77,7 @@ inline bool isListItemScopeMarker(HTMLStackItem* item)
inline bool isTableScopeMarker(HTMLStackItem* item)
{
- return isHTMLTableElement(item->node())
+ return item->hasTagName(tableTag)
|| item->hasTagName(templateTag)
|| isRootNode(item);
}
@@ -115,24 +113,26 @@ inline bool isButtonScopeMarker(HTMLStackItem* item)
inline bool isSelectScopeMarker(HTMLStackItem* item)
{
- return !isHTMLOptGroupElement(item->node())
+ return !item->hasTagName(optgroupTag)
&& !item->hasTagName(optionTag);
}
}
-HTMLElementStack::ElementRecord::ElementRecord(PassRefPtr<HTMLStackItem> item, PassOwnPtr<ElementRecord> next)
+HTMLElementStack::ElementRecord::ElementRecord(PassRefPtrWillBeRawPtr<HTMLStackItem> item, PassOwnPtrWillBeRawPtr<ElementRecord> next)
: m_item(item)
, m_next(next)
{
ASSERT(m_item);
}
+#if !ENABLE(OILPAN)
HTMLElementStack::ElementRecord::~ElementRecord()
{
}
+#endif
-void HTMLElementStack::ElementRecord::replaceElement(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::ElementRecord::replaceElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ASSERT(item);
ASSERT(!m_item || m_item->isElementNode());
@@ -149,10 +149,18 @@ bool HTMLElementStack::ElementRecord::isAbove(ElementRecord* other) const
return false;
}
+void HTMLElementStack::ElementRecord::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_item);
+ visitor->trace(m_next);
+#endif
+}
+
HTMLElementStack::HTMLElementStack()
- : m_rootNode(0)
- , m_headElement(0)
- , m_bodyElement(0)
+ : m_rootNode(nullptr)
+ , m_headElement(nullptr)
+ , m_bodyElement(nullptr)
, m_stackDepth(0)
{
}
@@ -181,25 +189,27 @@ bool HTMLElementStack::secondElementIsHTMLBodyElement() const
void HTMLElementStack::popHTMLHeadElement()
{
ASSERT(top() == m_headElement);
- m_headElement = 0;
+ m_headElement = nullptr;
popCommon();
}
void HTMLElementStack::popHTMLBodyElement()
{
ASSERT(top() == m_bodyElement);
- m_bodyElement = 0;
+ m_bodyElement = nullptr;
popCommon();
}
void HTMLElementStack::popAll()
{
- m_rootNode = 0;
- m_headElement = 0;
- m_bodyElement = 0;
+ m_rootNode = nullptr;
+ m_headElement = nullptr;
+ m_bodyElement = nullptr;
m_stackDepth = 0;
while (m_top) {
- topNode()->finishParsingChildren();
+ Node& node = *topNode();
+ if (node.isElementNode())
+ toElement(node).finishParsingChildren();
m_top = m_top->releaseNext();
}
}
@@ -301,19 +311,19 @@ void HTMLElementStack::popUntilForeignContentScopeMarker()
pop();
}
-void HTMLElementStack::pushRootNode(PassRefPtr<HTMLStackItem> rootItem)
+void HTMLElementStack::pushRootNode(PassRefPtrWillBeRawPtr<HTMLStackItem> rootItem)
{
ASSERT(rootItem->isDocumentFragmentNode());
pushRootNodeCommon(rootItem);
}
-void HTMLElementStack::pushHTMLHtmlElement(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::pushHTMLHtmlElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
- ASSERT(isHTMLHtmlElement(item->node()));
+ ASSERT(item->hasTagName(htmlTag));
pushRootNodeCommon(item);
}
-void HTMLElementStack::pushRootNodeCommon(PassRefPtr<HTMLStackItem> rootItem)
+void HTMLElementStack::pushRootNodeCommon(PassRefPtrWillBeRawPtr<HTMLStackItem> rootItem)
{
ASSERT(!m_top);
ASSERT(!m_rootNode);
@@ -321,7 +331,7 @@ void HTMLElementStack::pushRootNodeCommon(PassRefPtr<HTMLStackItem> rootItem)
pushCommon(rootItem);
}
-void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::pushHTMLHeadElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ASSERT(item->hasTagName(HTMLNames::headTag));
ASSERT(!m_headElement);
@@ -329,7 +339,7 @@ void HTMLElementStack::pushHTMLHeadElement(PassRefPtr<HTMLStackItem> item)
pushCommon(item);
}
-void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::pushHTMLBodyElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ASSERT(item->hasTagName(HTMLNames::bodyTag));
ASSERT(!m_bodyElement);
@@ -337,23 +347,23 @@ void HTMLElementStack::pushHTMLBodyElement(PassRefPtr<HTMLStackItem> item)
pushCommon(item);
}
-void HTMLElementStack::push(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::push(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
- ASSERT(!isHTMLHtmlElement(item->node()));
- ASSERT(!item->hasTagName(HTMLNames::headTag));
- ASSERT(!item->hasTagName(HTMLNames::bodyTag));
+ ASSERT(!item->hasTagName(htmlTag));
+ ASSERT(!item->hasTagName(headTag));
+ ASSERT(!item->hasTagName(bodyTag));
ASSERT(m_rootNode);
pushCommon(item);
}
-void HTMLElementStack::insertAbove(PassRefPtr<HTMLStackItem> item, ElementRecord* recordBelow)
+void HTMLElementStack::insertAbove(PassRefPtrWillBeRawPtr<HTMLStackItem> item, ElementRecord* recordBelow)
{
ASSERT(item);
ASSERT(recordBelow);
ASSERT(m_top);
- ASSERT(!isHTMLHtmlElement(item->node()));
- ASSERT(!item->hasTagName(HTMLNames::headTag));
- ASSERT(!item->hasTagName(HTMLNames::bodyTag));
+ ASSERT(!item->hasTagName(htmlTag));
+ ASSERT(!item->hasTagName(headTag));
+ ASSERT(!item->hasTagName(bodyTag));
ASSERT(m_rootNode);
if (recordBelow == m_top) {
push(item);
@@ -365,7 +375,7 @@ void HTMLElementStack::insertAbove(PassRefPtr<HTMLStackItem> item, ElementRecord
continue;
m_stackDepth++;
- recordAbove->setNext(adoptPtr(new ElementRecord(item, recordAbove->releaseNext())));
+ recordAbove->setNext(adoptPtrWillBeNoop(new ElementRecord(item, recordAbove->releaseNext())));
recordAbove->next()->element()->beginParsingChildren();
return;
}
@@ -395,13 +405,13 @@ void HTMLElementStack::removeHTMLHeadElement(Element* element)
popHTMLHeadElement();
return;
}
- m_headElement = 0;
+ m_headElement = nullptr;
removeNonTopCommon(element);
}
void HTMLElementStack::remove(Element* element)
{
- ASSERT(!element->hasTagName(HTMLNames::headTag));
+ ASSERT(!isHTMLHeadElement(element));
if (m_top->element() == element) {
pop();
return;
@@ -556,19 +566,19 @@ ContainerNode* HTMLElementStack::rootNode() const
return m_rootNode;
}
-void HTMLElementStack::pushCommon(PassRefPtr<HTMLStackItem> item)
+void HTMLElementStack::pushCommon(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ASSERT(m_rootNode);
m_stackDepth++;
- m_top = adoptPtr(new ElementRecord(item, m_top.release()));
+ m_top = adoptPtrWillBeNoop(new ElementRecord(item, m_top.release()));
}
void HTMLElementStack::popCommon()
{
- ASSERT(!isHTMLHtmlElement(topStackItem()->node()));
- ASSERT(!topStackItem()->hasTagName(HTMLNames::headTag) || !m_headElement);
- ASSERT(!topStackItem()->hasTagName(HTMLNames::bodyTag) || !m_bodyElement);
+ ASSERT(!topStackItem()->hasTagName(htmlTag));
+ ASSERT(!topStackItem()->hasTagName(headTag) || !m_headElement);
+ ASSERT(!topStackItem()->hasTagName(bodyTag) || !m_bodyElement);
top()->finishParsingChildren();
m_top = m_top->releaseNext();
@@ -578,7 +588,7 @@ void HTMLElementStack::popCommon()
void HTMLElementStack::removeNonTopCommon(Element* element)
{
ASSERT(!isHTMLHtmlElement(element));
- ASSERT(!element->hasTagName(HTMLNames::bodyTag));
+ ASSERT(!isHTMLBodyElement(element));
ASSERT(top() != element);
for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
if (pos->next()->element() == element) {
@@ -606,6 +616,14 @@ HTMLElementStack::ElementRecord* HTMLElementStack::furthestBlockForFormattingEle
return 0;
}
+void HTMLElementStack::trace(Visitor* visitor)
+{
+ visitor->trace(m_top);
+ visitor->trace(m_rootNode);
+ visitor->trace(m_headElement);
+ visitor->trace(m_bodyElement);
+}
+
#ifndef NDEBUG
void HTMLElementStack::show()
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h
index e63bbbc3e72..2afead5f97e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLElementStack.h
@@ -44,35 +44,40 @@ class QualifiedName;
// NOTE: The HTML5 spec uses a backwards (grows downward) stack. We're using
// more standard (grows upwards) stack terminology here.
class HTMLElementStack {
- WTF_MAKE_NONCOPYABLE(HTMLElementStack); WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(HTMLElementStack);
+ DISALLOW_ALLOCATION();
public:
HTMLElementStack();
~HTMLElementStack();
- class ElementRecord {
- WTF_MAKE_NONCOPYABLE(ElementRecord); WTF_MAKE_FAST_ALLOCATED;
+ class ElementRecord FINAL : public NoBaseWillBeGarbageCollected<ElementRecord> {
+ WTF_MAKE_NONCOPYABLE(ElementRecord); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
+#if !ENABLE(OILPAN)
~ElementRecord(); // Public for ~PassOwnPtr()
+#endif
Element* element() const { return m_item->element(); }
ContainerNode* node() const { return m_item->node(); }
const AtomicString& namespaceURI() const { return m_item->namespaceURI(); }
- PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
- void replaceElement(PassRefPtr<HTMLStackItem>);
+ PassRefPtrWillBeRawPtr<HTMLStackItem> stackItem() const { return m_item; }
+ void replaceElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
bool isAbove(ElementRecord*) const;
ElementRecord* next() const { return m_next.get(); }
+
+ void trace(Visitor*);
private:
friend class HTMLElementStack;
- ElementRecord(PassRefPtr<HTMLStackItem>, PassOwnPtr<ElementRecord>);
+ ElementRecord(PassRefPtrWillBeRawPtr<HTMLStackItem>, PassOwnPtrWillBeRawPtr<ElementRecord>);
- PassOwnPtr<ElementRecord> releaseNext() { return m_next.release(); }
- void setNext(PassOwnPtr<ElementRecord> next) { m_next = next; }
+ PassOwnPtrWillBeRawPtr<ElementRecord> releaseNext() { return m_next.release(); }
+ void setNext(PassOwnPtrWillBeRawPtr<ElementRecord> next) { m_next = next; }
- RefPtr<HTMLStackItem> m_item;
- OwnPtr<ElementRecord> m_next;
+ RefPtrWillBeMember<HTMLStackItem> m_item;
+ OwnPtrWillBeMember<ElementRecord> m_next;
};
unsigned stackDepth() const { return m_stackDepth; }
@@ -103,13 +108,13 @@ public:
ElementRecord* furthestBlockForFormattingElement(Element*) const;
ElementRecord* topmost(const AtomicString& tagName) const;
- void insertAbove(PassRefPtr<HTMLStackItem>, ElementRecord*);
+ void insertAbove(PassRefPtrWillBeRawPtr<HTMLStackItem>, ElementRecord*);
- void push(PassRefPtr<HTMLStackItem>);
- void pushRootNode(PassRefPtr<HTMLStackItem>);
- void pushHTMLHtmlElement(PassRefPtr<HTMLStackItem>);
- void pushHTMLHeadElement(PassRefPtr<HTMLStackItem>);
- void pushHTMLBodyElement(PassRefPtr<HTMLStackItem>);
+ void push(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushRootNode(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushHTMLHtmlElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushHTMLHeadElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushHTMLBodyElement(PassRefPtrWillBeRawPtr<HTMLStackItem>);
void pop();
void popUntil(const AtomicString& tagName);
@@ -159,26 +164,28 @@ public:
ContainerNode* rootNode() const;
+ void trace(Visitor*);
+
#ifndef NDEBUG
void show();
#endif
private:
- void pushCommon(PassRefPtr<HTMLStackItem>);
- void pushRootNodeCommon(PassRefPtr<HTMLStackItem>);
+ void pushCommon(PassRefPtrWillBeRawPtr<HTMLStackItem>);
+ void pushRootNodeCommon(PassRefPtrWillBeRawPtr<HTMLStackItem>);
void popCommon();
void removeNonTopCommon(Element*);
- OwnPtr<ElementRecord> m_top;
+ OwnPtrWillBeMember<ElementRecord> m_top;
// We remember the root node, <head> and <body> as they are pushed. Their
// ElementRecords keep them alive. The root node is never popped.
// FIXME: We don't currently require type-specific information about
// these elements so we haven't yet bothered to plumb the types all the
// way down through createElement, etc.
- ContainerNode* m_rootNode;
- Element* m_headElement;
- Element* m_bodyElement;
+ RawPtrWillBeMember<ContainerNode> m_rootNode;
+ RawPtrWillBeMember<Element> m_headElement;
+ RawPtrWillBeMember<Element> m_bodyElement;
unsigned m_stackDepth;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp
index 97cebee4383..9866313277d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityParser.cpp
@@ -115,7 +115,7 @@ static bool consumeNamedEntity(SegmentedString& source, DecodedHTMLEntity& decod
}
notEnoughCharacters = source.isEmpty();
if (notEnoughCharacters) {
- // We can't an entity because there might be a longer entity
+ // We can't decide on an entity because there might be a longer entity
// that we could match if we had more data.
unconsumeCharacters(source, consumedCharacters);
return false;
@@ -130,11 +130,12 @@ static bool consumeNamedEntity(SegmentedString& source, DecodedHTMLEntity& decod
// actual entity.
unconsumeCharacters(source, consumedCharacters);
consumedCharacters.clear();
- const int length = entitySearch.mostRecentMatch()->length;
- const UChar* reference = entitySearch.mostRecentMatch()->entity;
+ const HTMLEntityTableEntry* mostRecent = entitySearch.mostRecentMatch();
+ const int length = mostRecent->length;
+ const LChar* reference = HTMLEntityTable::entityString(*mostRecent);
for (int i = 0; i < length; ++i) {
cc = source.currentChar();
- ASSERT_UNUSED(reference, cc == *reference++);
+ ASSERT_UNUSED(reference, cc == static_cast<UChar>(*reference++));
consumedCharacters.append(cc);
source.advanceAndASSERT(cc);
ASSERT(!source.isEmpty());
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp
index c4ef2b0c92f..fe847e48038 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntitySearch.cpp
@@ -47,7 +47,8 @@ HTMLEntitySearch::CompareResult HTMLEntitySearch::compare(const HTMLEntityTableE
{
if (entry->length < m_currentLength + 1)
return Before;
- UChar entryNextCharacter = entry->entity[m_currentLength];
+ const LChar* entityString = HTMLEntityTable::entityString(*entry);
+ UChar entryNextCharacter = entityString[m_currentLength];
if (entryNextCharacter == nextCharacter)
return Prefix;
return entryNextCharacter < nextCharacter ? Before : After;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h
index f0d775efee7..1e465049b57 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLEntityTable.h
@@ -30,13 +30,14 @@
namespace WebCore {
+// Member order to optimize packing. There will be thousands of these objects.
struct HTMLEntityTableEntry {
- UChar lastCharacter() const { return entity[length - 1]; }
+ LChar lastCharacter() const;
- const UChar* entity;
- int length;
UChar32 firstValue;
- UChar32 secondValue;
+ UChar secondValue; // UChar since double char sequences only use BMP chars.
+ short entityOffset;
+ short length;
};
class HTMLEntityTable {
@@ -46,6 +47,8 @@ public:
static const HTMLEntityTableEntry* firstEntryStartingWith(UChar);
static const HTMLEntityTableEntry* lastEntryStartingWith(UChar);
+
+ static const LChar* entityString(const HTMLEntityTableEntry&);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp
index 34215d75e26..26418debc1c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.cpp
@@ -79,7 +79,7 @@ HTMLFormattingElementList::Bookmark HTMLFormattingElementList::bookmarkFor(Eleme
return Bookmark(&at(index));
}
-void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> newItem, const Bookmark& bookmark)
+void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtrWillBeRawPtr<HTMLStackItem> newItem, const Bookmark& bookmark)
{
ASSERT(contains(oldElement));
ASSERT(!contains(newItem->element()));
@@ -94,7 +94,7 @@ void HTMLFormattingElementList::swapTo(Element* oldElement, PassRefPtr<HTMLStack
remove(oldElement);
}
-void HTMLFormattingElementList::append(PassRefPtr<HTMLStackItem> item)
+void HTMLFormattingElementList::append(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
{
ensureNoahsArkCondition(item.get());
m_entries.append(item);
@@ -123,7 +123,7 @@ void HTMLFormattingElementList::clearToLastMarker()
}
}
-void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackItem* newItem, Vector<HTMLStackItem*>& remainingCandidates)
+void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackItem* newItem, WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> >& remainingCandidates)
{
ASSERT(remainingCandidates.isEmpty());
@@ -132,7 +132,7 @@ void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackIte
// Use a vector with inline capacity to avoid a malloc in the common case
// of a quickly ensuring the condition.
- Vector<HTMLStackItem*, 10> candidates;
+ WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem>, 10> candidates;
size_t newItemAttributeCount = newItem->attributes().size();
@@ -155,19 +155,19 @@ void HTMLFormattingElementList::tryToEnsureNoahsArkConditionQuickly(HTMLStackIte
if (candidates.size() < kNoahsArkCapacity)
return; // There's room for the new element in the ark. There's no need to copy out the remainingCandidates.
- remainingCandidates.append(candidates);
+ remainingCandidates.appendVector(candidates);
}
void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem)
{
- Vector<HTMLStackItem*> candidates;
+ WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> > candidates;
tryToEnsureNoahsArkConditionQuickly(newItem, candidates);
if (candidates.isEmpty())
return;
// We pre-allocate and re-use this second vector to save one malloc per
// attribute that we verify.
- Vector<HTMLStackItem*> remainingCandidates;
+ WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> > remainingCandidates;
remainingCandidates.reserveInitialCapacity(candidates.size());
const Vector<Attribute>& attributes = newItem->attributes();
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h
index 745dba1c771..cb7c0ce34fb 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLFormattingElementList.h
@@ -38,6 +38,7 @@ class Element;
// This may end up merged into HTMLElementStack.
class HTMLFormattingElementList {
WTF_MAKE_NONCOPYABLE(HTMLFormattingElementList);
+ DISALLOW_ALLOCATION();
public:
HTMLFormattingElementList();
~HTMLFormattingElementList();
@@ -46,22 +47,23 @@ public:
// between the HTMLFormattingElementList and HTMLElementStack and needs
// access to Entry::isMarker() and Entry::replaceElement() to do so.
class Entry {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
// Inline because they're hot and Vector<T> uses them.
- explicit Entry(PassRefPtr<HTMLStackItem> item)
+ explicit Entry(PassRefPtrWillBeRawPtr<HTMLStackItem> item)
: m_item(item)
{
}
enum MarkerEntryType { MarkerEntry };
explicit Entry(MarkerEntryType)
- : m_item(0)
+ : m_item(nullptr)
{
}
~Entry() {}
bool isMarker() const { return !m_item; }
- PassRefPtr<HTMLStackItem> stackItem() const { return m_item; }
+ PassRefPtrWillBeRawPtr<HTMLStackItem> stackItem() const { return m_item; }
Element* element() const
{
// The fact that !m_item == isMarker() is an implementation detail
@@ -69,14 +71,16 @@ public:
ASSERT(m_item);
return m_item->element();
}
- void replaceElement(PassRefPtr<HTMLStackItem> item) { m_item = item; }
+ void replaceElement(PassRefPtrWillBeRawPtr<HTMLStackItem> item) { m_item = item; }
// Needed for use with Vector. These are super-hot and must be inline.
bool operator==(Element* element) const { return !m_item ? !element : m_item->element() == element; }
bool operator!=(Element* element) const { return !m_item ? !!element : m_item->element() != element; }
+ void trace(Visitor* visitor) { visitor->trace(m_item); }
+
private:
- RefPtr<HTMLStackItem> m_item;
+ RefPtrWillBeMember<HTMLStackItem> m_item;
};
class Bookmark {
@@ -108,11 +112,11 @@ public:
Entry* find(Element*);
bool contains(Element*);
- void append(PassRefPtr<HTMLStackItem>);
+ void append(PassRefPtrWillBeRawPtr<HTMLStackItem>);
void remove(Element*);
Bookmark bookmarkFor(Element*);
- void swapTo(Element* oldElement, PassRefPtr<HTMLStackItem> newItem, const Bookmark&);
+ void swapTo(Element* oldElement, PassRefPtrWillBeRawPtr<HTMLStackItem> newItem, const Bookmark&);
void appendMarker();
// clearToLastMarker also clears the marker (per the HTML5 spec).
@@ -121,6 +125,8 @@ public:
const Entry& at(size_t i) const { return m_entries[i]; }
Entry& at(size_t i) { return m_entries[i]; }
+ void trace(Visitor* visitor) { visitor->trace(m_entries); }
+
#ifndef NDEBUG
void show();
#endif
@@ -130,12 +136,14 @@ private:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#list-of-active-formatting-elements
// These functions enforce the "Noah's Ark" condition, which removes redundant mis-nested elements.
- void tryToEnsureNoahsArkConditionQuickly(HTMLStackItem*, Vector<HTMLStackItem*>& remainingCandiates);
+ void tryToEnsureNoahsArkConditionQuickly(HTMLStackItem*, WillBeHeapVector<RawPtrWillBeMember<HTMLStackItem> >& remainingCandiates);
void ensureNoahsArkCondition(HTMLStackItem*);
- Vector<Entry> m_entries;
+ WillBeHeapVector<Entry> m_entries;
};
-}
+} // namespace WebCore
+
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::HTMLFormattingElementList::Entry);
#endif // HTMLFormattingElementList_h
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
index 038c8a1e5fb..5fa6d32e73d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/html/parser/HTMLMetaCharsetParser.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLTokenizer.h"
@@ -51,61 +51,12 @@ HTMLMetaCharsetParser::~HTMLMetaCharsetParser()
{
}
-static const char charsetString[] = "charset";
-static const size_t charsetLength = sizeof("charset") - 1;
-
-String HTMLMetaCharsetParser::extractCharset(const String& value)
-{
- size_t pos = 0;
- unsigned length = value.length();
-
- while (pos < length) {
- pos = value.find(charsetString, pos, false);
- if (pos == kNotFound)
- break;
-
- pos += charsetLength;
-
- // Skip whitespace.
- while (pos < length && value[pos] <= ' ')
- ++pos;
-
- if (value[pos] != '=')
- continue;
-
- ++pos;
-
- while (pos < length && value[pos] <= ' ')
- ++pos;
-
- char quoteMark = 0;
- if (pos < length && (value[pos] == '"' || value[pos] == '\'')) {
- quoteMark = static_cast<char>(value[pos++]);
- ASSERT(!(quoteMark & 0x80));
- }
-
- if (pos == length)
- break;
-
- unsigned end = pos;
- while (end < length && ((quoteMark && value[end] != quoteMark) || (!quoteMark && value[end] > ' ' && value[end] != '"' && value[end] != '\'' && value[end] != ';')))
- ++end;
-
- if (quoteMark && (end == length))
- break; // Close quote not found.
-
- return value.substring(pos, end - pos);
- }
-
- return "";
-}
-
bool HTMLMetaCharsetParser::processMeta()
{
const HTMLToken::AttributeList& tokenAttributes = m_token.attributes();
- AttributeList attributes;
+ HTMLAttributeList attributes;
for (HTMLToken::AttributeList::const_iterator iter = tokenAttributes.begin(); iter != tokenAttributes.end(); ++iter) {
- String attributeName = StringImpl::create8BitIfPossible(iter->name);
+ String attributeName = attemptStaticStringCreation(iter->name, Likely8Bit);
String attributeValue = StringImpl::create8BitIfPossible(iter->value);
attributes.append(std::make_pair(attributeName, attributeValue));
}
@@ -114,37 +65,6 @@ bool HTMLMetaCharsetParser::processMeta()
return m_encoding.isValid();
}
-WTF::TextEncoding HTMLMetaCharsetParser::encodingFromMetaAttributes(const AttributeList& attributes)
-{
- bool gotPragma = false;
- Mode mode = None;
- String charset;
-
- for (AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
- const AtomicString& attributeName = iter->first;
- const String& attributeValue = iter->second;
-
- if (attributeName == http_equivAttr) {
- if (equalIgnoringCase(attributeValue, "content-type"))
- gotPragma = true;
- } else if (charset.isEmpty()) {
- if (attributeName == charsetAttr) {
- charset = attributeValue;
- mode = Charset;
- } else if (attributeName == contentAttr) {
- charset = extractCharset(attributeValue);
- if (charset.length())
- mode = Pragma;
- }
- }
- }
-
- if (mode == Charset || (mode == Pragma && gotPragma))
- return WTF::TextEncoding(stripLeadingAndTrailingHTMLSpaces(charset));
-
- return WTF::TextEncoding();
-}
-
static const int bytesToCheckUnconditionally = 1024; // That many input bytes will be checked for meta charset even if <head> section is over.
bool HTMLMetaCharsetParser::checkForMetaCharset(const char* data, size_t length)
@@ -177,20 +97,20 @@ bool HTMLMetaCharsetParser::checkForMetaCharset(const char* data, size_t length)
while (m_tokenizer->nextToken(m_input, m_token)) {
bool end = m_token.type() == HTMLToken::EndTag;
if (end || m_token.type() == HTMLToken::StartTag) {
- AtomicString tagName(m_token.name());
+ String tagName = attemptStaticStringCreation(m_token.name(), Likely8Bit);
if (!end) {
m_tokenizer->updateStateFor(tagName);
- if (tagName == metaTag && processMeta()) {
+ if (threadSafeMatch(tagName, metaTag) && processMeta()) {
m_doneChecking = true;
return true;
}
}
- if (tagName != scriptTag && tagName != noscriptTag
- && tagName != styleTag && tagName != linkTag
- && tagName != metaTag && tagName != objectTag
- && tagName != titleTag && tagName != baseTag
- && (end || tagName != htmlTag) && (end || tagName != headTag)) {
+ if (!threadSafeMatch(tagName, scriptTag) && !threadSafeMatch(tagName, noscriptTag)
+ && !threadSafeMatch(tagName, styleTag) && !threadSafeMatch(tagName, linkTag)
+ && !threadSafeMatch(tagName, metaTag) && !threadSafeMatch(tagName, objectTag)
+ && !threadSafeMatch(tagName, titleTag) && !threadSafeMatch(tagName, baseTag)
+ && (end || !threadSafeMatch(tagName, htmlTag)) && (end || !threadSafeMatch(tagName, headTag))) {
m_inHeadSection = false;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
index 3393fca40d2..65d9517a2e0 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLMetaCharsetParser.h
@@ -48,22 +48,10 @@ public:
const WTF::TextEncoding& encoding() { return m_encoding; }
- typedef Vector<pair<String, String> > AttributeList;
- // The returned encoding might not be valid.
- static WTF::TextEncoding encodingFromMetaAttributes(const AttributeList&
-);
-
private:
HTMLMetaCharsetParser();
bool processMeta();
- static String extractCharset(const String&);
-
- enum Mode {
- None,
- Charset,
- Pragma,
- };
OwnPtr<HTMLTokenizer> m_tokenizer;
OwnPtr<TextCodec> m_assumedCodec;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
index f538c54cc5b..c0557a82281 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.cpp
@@ -25,14 +25,18 @@
#include "config.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/HTMLNames.h"
#include <limits>
#include "wtf/MathExtras.h"
#include "wtf/text/AtomicString.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/text/StringHash.h"
+#include "wtf/text/TextEncoding.h"
namespace WebCore {
+using namespace HTMLNames;
+
template <typename CharType>
static String stripLeadingAndTrailingHTMLSpaces(String string, const CharType* characters, unsigned length)
{
@@ -91,8 +95,7 @@ String serializeForNumberType(double number)
Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbackValue)
{
- // See HTML5 2.5.4.3 `Real numbers.' and parseToDoubleForNumberType
-
+ // http://www.whatwg.org/specs/web-apps/current-work/#floating-point-numbers and parseToDoubleForNumberType
// String::toDouble() accepts leading + and whitespace characters, which are not valid here.
const UChar firstCharacter = string[0];
if (firstCharacter != '-' && firstCharacter != '.' && !isASCIIDigit(firstCharacter))
@@ -102,11 +105,9 @@ Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbac
if (!value.isFinite())
return fallbackValue;
- // Numbers are considered finite IEEE 754 single-precision floating point values.
- // See HTML5 2.5.4.3 `Real numbers.'
- // FIXME: We should use numeric_limits<double>::max for number input type.
- const Decimal floatMax = Decimal::fromDouble(std::numeric_limits<float>::max());
- if (value < -floatMax || value > floatMax)
+ // Numbers are considered finite IEEE 754 Double-precision floating point values.
+ const Decimal doubleMax = Decimal::fromDouble(std::numeric_limits<double>::max());
+ if (value < -doubleMax || value > doubleMax)
return fallbackValue;
// We return +0 for -0 case.
@@ -115,8 +116,7 @@ Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbac
double parseToDoubleForNumberType(const String& string, double fallbackValue)
{
- // See HTML5 2.5.4.3 `Real numbers.'
-
+ // http://www.whatwg.org/specs/web-apps/current-work/#floating-point-numbers
// String::toDouble() accepts leading + and whitespace characters, which are not valid here.
UChar firstCharacter = string[0];
if (firstCharacter != '-' && firstCharacter != '.' && !isASCIIDigit(firstCharacter))
@@ -131,9 +131,8 @@ double parseToDoubleForNumberType(const String& string, double fallbackValue)
if (!std::isfinite(value))
return fallbackValue;
- // Numbers are considered finite IEEE 754 single-precision floating point values.
- // See HTML5 2.5.4.3 `Real numbers.'
- if (-std::numeric_limits<float>::max() > value || value > std::numeric_limits<float>::max())
+ // Numbers are considered finite IEEE 754 Double-precision floating point values.
+ if (-std::numeric_limits<double>::max() > value || value > std::numeric_limits<double>::max())
return fallbackValue;
// The following expression converts -0 to +0.
@@ -265,6 +264,92 @@ bool parseHTMLNonNegativeInteger(const String& input, unsigned& value)
return parseHTMLNonNegativeIntegerInternal(start, start + length, value);
}
+static const char charsetString[] = "charset";
+static const size_t charsetLength = sizeof("charset") - 1;
+
+String extractCharset(const String& value)
+{
+ size_t pos = 0;
+ unsigned length = value.length();
+
+ while (pos < length) {
+ pos = value.find(charsetString, pos, false);
+ if (pos == kNotFound)
+ break;
+
+ pos += charsetLength;
+
+ // Skip whitespace.
+ while (pos < length && value[pos] <= ' ')
+ ++pos;
+
+ if (value[pos] != '=')
+ continue;
+
+ ++pos;
+
+ while (pos < length && value[pos] <= ' ')
+ ++pos;
+
+ char quoteMark = 0;
+ if (pos < length && (value[pos] == '"' || value[pos] == '\'')) {
+ quoteMark = static_cast<char>(value[pos++]);
+ ASSERT(!(quoteMark & 0x80));
+ }
+
+ if (pos == length)
+ break;
+
+ unsigned end = pos;
+ while (end < length && ((quoteMark && value[end] != quoteMark) || (!quoteMark && value[end] > ' ' && value[end] != '"' && value[end] != '\'' && value[end] != ';')))
+ ++end;
+
+ if (quoteMark && (end == length))
+ break; // Close quote not found.
+
+ return value.substring(pos, end - pos);
+ }
+
+ return "";
+}
+
+enum Mode {
+ None,
+ Charset,
+ Pragma,
+};
+
+WTF::TextEncoding encodingFromMetaAttributes(const HTMLAttributeList& attributes)
+{
+ bool gotPragma = false;
+ Mode mode = None;
+ String charset;
+
+ for (HTMLAttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
+ const String& attributeName = iter->first;
+ const String& attributeValue = AtomicString(iter->second);
+
+ if (threadSafeMatch(attributeName, http_equivAttr)) {
+ if (equalIgnoringCase(attributeValue, "content-type"))
+ gotPragma = true;
+ } else if (charset.isEmpty()) {
+ if (threadSafeMatch(attributeName, charsetAttr)) {
+ charset = attributeValue;
+ mode = Charset;
+ } else if (threadSafeMatch(attributeName, contentAttr)) {
+ charset = extractCharset(attributeValue);
+ if (charset.length())
+ mode = Pragma;
+ }
+ }
+ }
+
+ if (mode == Charset || (mode == Pragma && gotPragma))
+ return WTF::TextEncoding(stripLeadingAndTrailingHTMLSpaces(charset));
+
+ return WTF::TextEncoding();
+}
+
static bool threadSafeEqual(const StringImpl* a, const StringImpl* b)
{
if (a == b)
@@ -284,7 +369,8 @@ bool threadSafeMatch(const String& localName, const QualifiedName& qName)
return threadSafeEqual(localName.impl(), qName.localName().impl());
}
-StringImpl* findStringIfStatic(const UChar* characters, unsigned length)
+template<typename CharType>
+inline StringImpl* findStringIfStatic(const CharType* characters, unsigned length)
{
// We don't need to try hashing if we know the string is too long.
if (length > StringImpl::highestStaticStringLength())
@@ -306,4 +392,27 @@ StringImpl* findStringIfStatic(const UChar* characters, unsigned length)
return it->value;
}
+String attemptStaticStringCreation(const LChar* characters, size_t size)
+{
+ String string(findStringIfStatic(characters, size));
+ if (string.impl())
+ return string;
+ return String(characters, size);
+}
+
+String attemptStaticStringCreation(const UChar* characters, size_t size, CharacterWidth width)
+{
+ String string(findStringIfStatic(characters, size));
+ if (string.impl())
+ return string;
+ if (width == Likely8Bit)
+ string = StringImpl::create8BitIfPossible(characters, size);
+ else if (width == Force8Bit)
+ string = String::make8BitFrom16BitSource(characters, size);
+ else
+ string = String(characters, size);
+
+ return string;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
index 16fd3eebe3c..d5ab2899638 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserIdioms.h
@@ -30,12 +30,11 @@
#include "wtf/Forward.h"
#include "wtf/text/WTFString.h"
-namespace WebCore {
+namespace WTF {
+class TextEncoding;
+}
-// Space characters as defined by the HTML specification.
-bool isHTMLSpace(UChar);
-bool isHTMLLineBreak(UChar);
-bool isNotHTMLSpace(UChar);
+namespace WebCore {
// Strip leading and trailing whitespace as defined by the HTML specification.
String stripLeadingAndTrailingHTMLSpaces(const String&);
@@ -59,10 +58,13 @@ double parseToDoubleForNumberType(const String&, double fallbackValue = std::num
bool parseHTMLInteger(const String&, int&);
// http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-non-negative-integers
-bool parseHTMLNonNegativeInteger(const String&, unsigned int&);
+bool parseHTMLNonNegativeInteger(const String&, unsigned&);
-// Inline implementations of some of the functions declared above.
+typedef Vector<pair<String, String> > HTMLAttributeList;
+// The returned encoding might not be valid.
+WTF::TextEncoding encodingFromMetaAttributes(const HTMLAttributeList&);
+// Space characters as defined by the HTML specification.
template<typename CharType>
inline bool isHTMLSpace(CharType character)
{
@@ -80,9 +82,15 @@ inline bool isHTMLSpace(CharType character)
}
template<typename CharType>
+inline bool isComma(CharType character)
+{
+ return character == ',';
+}
+
+template<typename CharType>
inline bool isHTMLSpaceOrComma(CharType character)
{
- return isHTMLSpace<CharType>(character) || character == ',';
+ return isComma(character) || isHTMLSpace(character);
}
inline bool isHTMLLineBreak(UChar character)
@@ -99,29 +107,29 @@ inline bool isNotHTMLSpace(CharType character)
bool threadSafeMatch(const QualifiedName&, const QualifiedName&);
bool threadSafeMatch(const String&, const QualifiedName&);
-StringImpl* findStringIfStatic(const UChar* characters, unsigned length);
-
enum CharacterWidth {
Likely8Bit,
Force8Bit,
Force16Bit
};
+String attemptStaticStringCreation(const LChar*, size_t);
+
+String attemptStaticStringCreation(const UChar*, size_t, CharacterWidth);
+
template<size_t inlineCapacity>
-static String attemptStaticStringCreation(const Vector<UChar, inlineCapacity>& vector, CharacterWidth width)
+inline static String attemptStaticStringCreation(const Vector<UChar, inlineCapacity>& vector, CharacterWidth width)
{
- String string(findStringIfStatic(vector.data(), vector.size()));
- if (string.impl())
- return string;
- if (width == Likely8Bit)
- string = StringImpl::create8BitIfPossible(vector);
- else if (width == Force8Bit)
- string = String::make8BitFrom16BitSource(vector);
- else
- string = String(vector);
-
- return string;
+ return attemptStaticStringCreation(vector.data(), vector.size(), width);
}
+inline static String attemptStaticStringCreation(const String str)
+{
+ if (!str.is8Bit())
+ return attemptStaticStringCreation(str.characters16(), str.length(), Force16Bit);
+ return attemptStaticStringCreation(str.characters8(), str.length());
+}
+
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
index 98ceb68461d..b08cf92994e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserOptions.cpp
@@ -28,23 +28,28 @@
#include "bindings/v8/ScriptController.h"
#include "core/dom/Document.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/loader/FrameLoader.h"
namespace WebCore {
HTMLParserOptions::HTMLParserOptions(Document* document)
{
- Frame* frame = document ? document->frame() : 0;
+ LocalFrame* frame = document ? document->frame() : 0;
scriptEnabled = frame && frame->script().canExecuteScripts(NotAboutToExecuteScript);
pluginsEnabled = frame && frame->loader().allowPlugins(NotAboutToInstantiatePlugin);
- Settings* settings = document ? document->settings() : 0;
- // We force the main-thread parser for about:blank, javascript: and data: urls for compatibility
- // with historical synchronous loading/parsing behavior of those schemes.
- useThreading = settings && settings->threadedHTMLParser() && !document->url().isBlankURL()
- && (settings->useThreadedHTMLParserForDataURLs() || !document->url().protocolIsData());
+ // We force the main-thread parser for two cases:
+ // - about:blank and javascript (which uses about:blank) for compatibility
+ // with historical synchronous loading/parsing behavior.
+ // - instances where the Document has no Frame (this happens sometimes for
+ // HTML imports, and possibly other cases).
+ // FIXME: We want to use the threaded parser for XHRs (where there is no
+ // frame) so the second case should go away eventually.
+ // FIXME: Gecko does not load javascript: urls synchronously, why do we?
+ // See LayoutTests/loader/iframe-sync-loads.html
+ useThreading = document && document->frame() && !document->url().isAboutBlankURL();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
index c74628479df..61cb172ccae 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.cpp
@@ -88,34 +88,14 @@ HTMLParserScheduler::~HTMLParserScheduler()
void HTMLParserScheduler::continueNextChunkTimerFired(Timer<HTMLParserScheduler>* timer)
{
ASSERT_UNUSED(timer, timer == &m_continueNextChunkTimer);
- // FIXME: The timer class should handle timer priorities instead of this code.
- // If a layout is scheduled, wait again to let the layout timer run first.
- // FIXME: We should fix this by reducing the max-parse-time instead of
- // artificially forcing the parser to yield agressively before first layout.
- if (m_parser->document()->shouldParserYieldAgressivelyBeforeScriptExecution()) {
- m_continueNextChunkTimer.startOneShot(0);
- return;
- }
m_parser->resumeParsingAfterYield();
}
-void HTMLParserScheduler::checkForYieldBeforeScript(PumpSession& session)
-{
- // If we've never painted before and a layout is pending, yield prior to running
- // scripts to give the page a chance to paint earlier.
- Document* document = m_parser->document();
- bool needsFirstPaint = document->view() && !document->view()->hasEverPainted();
- if (needsFirstPaint && document->shouldParserYieldAgressivelyBeforeScriptExecution())
- session.needsYield = true;
- session.didSeeScript = true;
-}
-
void HTMLParserScheduler::scheduleForResume()
{
- m_continueNextChunkTimer.startOneShot(0);
+ m_continueNextChunkTimer.startOneShot(0, FROM_HERE);
}
-
void HTMLParserScheduler::suspend()
{
ASSERT(!m_isSuspendedWithActiveTimer);
@@ -131,7 +111,7 @@ void HTMLParserScheduler::resume()
if (!m_isSuspendedWithActiveTimer)
return;
m_isSuspendedWithActiveTimer = false;
- m_continueNextChunkTimer.startOneShot(0);
+ m_continueNextChunkTimer.startOneShot(0, FROM_HERE);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
index e8bfe493085..4e3364edfbf 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserScheduler.h
@@ -38,15 +38,17 @@ class Document;
class HTMLDocumentParser;
class ActiveParserSession {
+ STACK_ALLOCATED();
public:
explicit ActiveParserSession(Document*);
~ActiveParserSession();
private:
- RefPtr<Document> m_document;
+ RefPtrWillBeMember<Document> m_document;
};
class PumpSession : public NestingLevelIncrementer, public ActiveParserSession {
+ STACK_ALLOCATED();
public:
PumpSession(unsigned& nestingLevel, Document*);
~PumpSession();
@@ -84,7 +86,6 @@ public:
}
++session.processedTokens;
}
- void checkForYieldBeforeScript(PumpSession&);
void scheduleForResume();
bool isScheduledForResume() const { return m_isSuspendedWithActiveTimer || m_continueNextChunkTimer.isActive(); }
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
index 5a0e30c3e67..5b5c6939714 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.cpp
@@ -32,13 +32,15 @@
#include "core/html/parser/HTMLParserThread.h"
#include "platform/Task.h"
+#include "platform/TaskSynchronizer.h"
#include "public/platform/Platform.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
+static HTMLParserThread* s_sharedThread = 0;
+
HTMLParserThread::HTMLParserThread()
- : m_thread(adoptPtr(blink::Platform::current()->createThread("HTMLParserThread")))
{
}
@@ -46,17 +48,66 @@ HTMLParserThread::~HTMLParserThread()
{
}
+void HTMLParserThread::init()
+{
+ ASSERT(!s_sharedThread);
+ s_sharedThread = new HTMLParserThread;
+}
+
+void HTMLParserThread::setupHTMLParserThread()
+{
+ m_pendingGCRunner = adoptPtr(new PendingGCRunner);
+ m_messageLoopInterruptor = adoptPtr(new MessageLoopInterruptor(&platformThread()));
+ platformThread().addTaskObserver(m_pendingGCRunner.get());
+ ThreadState::attach();
+ ThreadState::current()->addInterruptor(m_messageLoopInterruptor.get());
+}
+
+void HTMLParserThread::shutdown()
+{
+ ASSERT(s_sharedThread);
+ // currentThread will always be non-null in production, but can be null in Chromium unit tests.
+ if (blink::Platform::current()->currentThread() && s_sharedThread->isRunning()) {
+ TaskSynchronizer taskSynchronizer;
+ s_sharedThread->postTask(WTF::bind(&HTMLParserThread::cleanupHTMLParserThread, s_sharedThread, &taskSynchronizer));
+ taskSynchronizer.waitForTaskCompletion();
+ }
+ delete s_sharedThread;
+ s_sharedThread = 0;
+}
+
+void HTMLParserThread::cleanupHTMLParserThread(TaskSynchronizer* taskSynchronizer)
+{
+ ThreadState::current()->removeInterruptor(m_messageLoopInterruptor.get());
+ ThreadState::detach();
+ platformThread().removeTaskObserver(m_pendingGCRunner.get());
+ m_pendingGCRunner = nullptr;
+ m_messageLoopInterruptor = nullptr;
+ taskSynchronizer->taskCompleted();
+}
+
HTMLParserThread* HTMLParserThread::shared()
{
- static HTMLParserThread* thread;
- if (!thread)
- thread = new HTMLParserThread;
- return thread;
+ return s_sharedThread;
+}
+
+blink::WebThread& HTMLParserThread::platformThread()
+{
+ if (!isRunning()) {
+ m_thread = adoptPtr(blink::Platform::current()->createThread("HTMLParserThread"));
+ postTask(WTF::bind(&HTMLParserThread::setupHTMLParserThread, this));
+ }
+ return *m_thread;
+}
+
+bool HTMLParserThread::isRunning()
+{
+ return !!m_thread;
}
void HTMLParserThread::postTask(const Closure& closure)
{
- m_thread->postTask(new Task(closure));
+ platformThread().postTask(new Task(closure));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
index e0b85f9399c..42630f39cfa 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThread.h
@@ -31,22 +31,37 @@
#ifndef HTMLParserThread_h
#define HTMLParserThread_h
+#include "platform/heap/glue/MessageLoopInterruptor.h"
+#include "platform/heap/glue/PendingGCRunner.h"
+#include "public/platform/WebThread.h"
#include "wtf/Functional.h"
#include "wtf/OwnPtr.h"
-#include "public/platform/WebThread.h"
namespace WebCore {
+class TaskSynchronizer;
+
class HTMLParserThread {
public:
+ static void init();
+ static void shutdown();
+
+ // It is an error to call shared() before init() or after shutdown();
static HTMLParserThread* shared();
+
void postTask(const Closure&);
+ blink::WebThread& platformThread();
+ bool isRunning();
private:
HTMLParserThread();
~HTMLParserThread();
+ void setupHTMLParserThread();
+ void cleanupHTMLParserThread(TaskSynchronizer*);
OwnPtr<blink::WebThread> m_thread;
+ OwnPtr<PendingGCRunner> m_pendingGCRunner;
+ OwnPtr<MessageLoopInterruptor> m_messageLoopInterruptor;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThreadTest.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThreadTest.cpp
new file mode 100644
index 00000000000..8b742b86dc1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLParserThreadTest.cpp
@@ -0,0 +1,26 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/parser/HTMLParserThread.h"
+
+#include <gtest/gtest.h>
+
+namespace {
+
+using namespace WebCore;
+
+TEST(HTMLParserThread, Init)
+{
+ // The harness has already run init() for us, so tear down the parser first.
+ ASSERT_TRUE(HTMLParserThread::shared());
+ HTMLParserThread::shutdown();
+
+ // Make sure starting the parser thread brings it back to life.
+ ASSERT_FALSE(HTMLParserThread::shared());
+ HTMLParserThread::init();
+ ASSERT_TRUE(HTMLParserThread::shared());
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
index 0d1e0645ad7..6bea3f676a1 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -28,13 +28,17 @@
#include "config.h"
#include "core/html/parser/HTMLPreloadScanner.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
+#include "core/css/MediaList.h"
+#include "core/css/MediaQueryEvaluator.h"
+#include "core/css/MediaValues.h"
+#include "core/css/parser/SizesAttributeParser.h"
#include "core/html/LinkRelAttribute.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLSrcsetParser.h"
#include "core/html/parser/HTMLTokenizer.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "wtf/MainThread.h"
@@ -90,19 +94,33 @@ static String initiatorFor(const StringImpl* tagImpl)
return emptyString();
}
+static bool mediaAttributeMatches(const MediaValues& mediaValues, const String& attributeValue)
+{
+ RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::createOffMainThread(attributeValue);
+ MediaQueryEvaluator mediaQueryEvaluator("screen", mediaValues);
+ return mediaQueryEvaluator.eval(mediaQueries.get());
+}
+
class TokenPreloadScanner::StartTagScanner {
public:
- StartTagScanner(const StringImpl* tagImpl, float deviceScaleFactor)
+ StartTagScanner(const StringImpl* tagImpl, PassRefPtr<MediaValues> mediaValues)
: m_tagImpl(tagImpl)
, m_linkIsStyleSheet(false)
+ , m_matchedMediaAttribute(true)
, m_inputIsImage(false)
- , m_deviceScaleFactor(deviceScaleFactor)
- , m_encounteredImgSrc(false)
+ , m_sourceSize(0)
+ , m_sourceSizeSet(false)
, m_isCORSEnabled(false)
, m_allowCredentials(DoNotAllowStoredCredentials)
+ , m_mediaValues(mediaValues)
{
- if (!match(m_tagImpl, imgTag)
- && !match(m_tagImpl, inputTag)
+ if (match(m_tagImpl, imgTag)
+ || match(m_tagImpl, sourceTag)) {
+ if (RuntimeEnabledFeatures::pictureSizesEnabled())
+ m_sourceSize = SizesAttributeParser::findEffectiveSize(String(), m_mediaValues);
+ return;
+ }
+ if ( !match(m_tagImpl, inputTag)
&& !match(m_tagImpl, linkTag)
&& !match(m_tagImpl, scriptTag))
m_tagImpl = 0;
@@ -133,57 +151,122 @@ public:
processAttribute(iter->name, iter->value);
}
+ void handlePictureSourceURL(String& sourceURL)
+ {
+ if (match(m_tagImpl, sourceTag) && m_matchedMediaAttribute && sourceURL.isEmpty())
+ sourceURL = m_srcsetImageCandidate.toString();
+ else if (match(m_tagImpl, imgTag) && !sourceURL.isEmpty())
+ setUrlToLoad(sourceURL, AllowURLReplacement);
+ }
+
PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL, const SegmentedString& source)
{
- if (!shouldPreload())
+ if (!shouldPreload() || !m_matchedMediaAttribute)
return nullptr;
TRACE_EVENT_INSTANT1("net", "PreloadRequest", "url", m_urlToLoad.ascii());
TextPosition position = TextPosition(source.currentLine(), source.currentColumn());
- OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_tagImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute);
+ OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_tagImpl), position, m_urlToLoad, predictedBaseURL, resourceType());
if (isCORSEnabled())
- request->setCrossOriginEnabled(allowCredentials());
+ request->setCrossOriginEnabled(allowStoredCredentials());
request->setCharset(charset());
return request.release();
}
private:
template<typename NameType>
+ void processScriptAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ // FIXME - Don't set crossorigin multiple times.
+ if (match(attributeName, srcAttr))
+ setUrlToLoad(attributeValue, DisallowURLReplacement);
+ else if (match(attributeName, crossoriginAttr))
+ setCrossOriginAllowed(attributeValue);
+ }
+
+ template<typename NameType>
+ void processImgAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ if (match(attributeName, srcAttr) && m_imgSrcUrl.isNull()) {
+ m_imgSrcUrl = attributeValue;
+ setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue, m_srcsetImageCandidate), AllowURLReplacement);
+ } else if (match(attributeName, crossoriginAttr)) {
+ setCrossOriginAllowed(attributeValue);
+ } else if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetAttributeValue = attributeValue;
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue);
+ setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacement);
+ } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && match(attributeName, sizesAttr) && !m_sourceSizeSet) {
+ m_sourceSize = SizesAttributeParser::findEffectiveSize(attributeValue, m_mediaValues);
+ m_sourceSizeSet = true;
+ if (!m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue);
+ setUrlToLoad(bestFitSourceForImageAttributes(m_mediaValues->devicePixelRatio(), m_sourceSize, m_imgSrcUrl, m_srcsetImageCandidate), AllowURLReplacement);
+ }
+ }
+ }
+
+ template<typename NameType>
+ void processLinkAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ // FIXME - Don't set rel/media/crossorigin multiple times.
+ if (match(attributeName, hrefAttr))
+ setUrlToLoad(attributeValue, DisallowURLReplacement);
+ else if (match(attributeName, relAttr))
+ m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
+ else if (match(attributeName, mediaAttr))
+ m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attributeValue);
+ else if (match(attributeName, crossoriginAttr))
+ setCrossOriginAllowed(attributeValue);
+ }
+
+ template<typename NameType>
+ void processInputAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ // FIXME - Don't set type multiple times.
+ if (match(attributeName, srcAttr))
+ setUrlToLoad(attributeValue, DisallowURLReplacement);
+ else if (match(attributeName, typeAttr))
+ m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image);
+ }
+
+ template<typename NameType>
+ void processSourceAttribute(const NameType& attributeName, const String& attributeValue)
+ {
+ if (!RuntimeEnabledFeatures::pictureEnabled())
+ return;
+ if (match(attributeName, srcsetAttr) && m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetAttributeValue = attributeValue;
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, attributeValue);
+ } else if (match(attributeName, sizesAttr) && !m_sourceSizeSet) {
+ m_sourceSize = SizesAttributeParser::findEffectiveSize(attributeValue, m_mediaValues);
+ m_sourceSizeSet = true;
+ if (!m_srcsetImageCandidate.isEmpty()) {
+ m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_mediaValues->devicePixelRatio(), m_sourceSize, m_srcsetAttributeValue);
+ }
+ } else if (match(attributeName, mediaAttr)) {
+ // FIXME - Don't match media multiple times.
+ m_matchedMediaAttribute = mediaAttributeMatches(*m_mediaValues, attributeValue);
+ }
+
+ }
+
+ template<typename NameType>
void processAttribute(const NameType& attributeName, const String& attributeValue)
{
if (match(attributeName, charsetAttr))
m_charset = attributeValue;
- if (match(m_tagImpl, scriptTag)) {
- if (match(attributeName, srcAttr))
- setUrlToLoad(attributeValue, DisallowURLReplacement);
- else if (match(attributeName, crossoriginAttr))
- setCrossOriginAllowed(attributeValue);
- } else if (match(m_tagImpl, imgTag)) {
- if (match(attributeName, srcAttr) && !m_encounteredImgSrc) {
- m_encounteredImgSrc = true;
- setUrlToLoad(bestFitSourceForImageAttributes(m_deviceScaleFactor, attributeValue, m_srcsetImageCandidate), AllowURLReplacement);
- } else if (match(attributeName, crossoriginAttr)) {
- setCrossOriginAllowed(attributeValue);
- } else if (RuntimeEnabledFeatures::srcsetEnabled()
- && match(attributeName, srcsetAttr)
- && m_srcsetImageCandidate.isEmpty()) {
- m_srcsetImageCandidate = bestFitSourceForSrcsetAttribute(m_deviceScaleFactor, attributeValue);
- setUrlToLoad(bestFitSourceForImageAttributes(m_deviceScaleFactor, m_urlToLoad, m_srcsetImageCandidate), AllowURLReplacement);
- }
- } else if (match(m_tagImpl, linkTag)) {
- if (match(attributeName, hrefAttr))
- setUrlToLoad(attributeValue, DisallowURLReplacement);
- else if (match(attributeName, relAttr))
- m_linkIsStyleSheet = relAttributeIsStyleSheet(attributeValue);
- else if (match(attributeName, mediaAttr))
- m_mediaAttribute = attributeValue;
- } else if (match(m_tagImpl, inputTag)) {
- if (match(attributeName, srcAttr))
- setUrlToLoad(attributeValue, DisallowURLReplacement);
- else if (match(attributeName, typeAttr))
- m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image);
- }
+ if (match(m_tagImpl, scriptTag))
+ processScriptAttribute(attributeName, attributeValue);
+ else if (match(m_tagImpl, imgTag))
+ processImgAttribute(attributeName, attributeValue);
+ else if (match(m_tagImpl, linkTag))
+ processLinkAttribute(attributeName, attributeValue);
+ else if (match(m_tagImpl, inputTag))
+ processInputAttribute(attributeName, attributeValue);
+ else if (match(m_tagImpl, sourceTag))
+ processSourceAttribute(attributeName, attributeValue);
}
static bool relAttributeIsStyleSheet(const String& attributeValue)
@@ -240,7 +323,7 @@ private:
return m_isCORSEnabled;
}
- StoredCredentials allowCredentials() const
+ StoredCredentials allowStoredCredentials() const
{
return m_allowCredentials;
}
@@ -259,19 +342,23 @@ private:
ImageCandidate m_srcsetImageCandidate;
String m_charset;
bool m_linkIsStyleSheet;
- String m_mediaAttribute;
+ bool m_matchedMediaAttribute;
bool m_inputIsImage;
- float m_deviceScaleFactor;
- bool m_encounteredImgSrc;
+ String m_imgSrcUrl;
+ String m_srcsetAttributeValue;
+ unsigned m_sourceSize;
+ bool m_sourceSizeSet;
bool m_isCORSEnabled;
StoredCredentials m_allowCredentials;
+ RefPtr<MediaValues> m_mediaValues;
};
-TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, float deviceScaleFactor)
+TokenPreloadScanner::TokenPreloadScanner(const KURL& documentURL, PassRefPtr<MediaValues> mediaValues)
: m_documentURL(documentURL)
, m_inStyle(false)
- , m_deviceScaleFactor(deviceScaleFactor)
+ , m_inPicture(false)
, m_templateCount(0)
+ , m_mediaValues(mediaValues)
{
}
@@ -328,7 +415,10 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString&
if (m_inStyle)
m_cssScanner.reset();
m_inStyle = false;
+ return;
}
+ if (match(tagImpl, pictureTag))
+ m_inPicture = false;
return;
}
case HTMLToken::StartTag: {
@@ -350,9 +440,16 @@ void TokenPreloadScanner::scanCommon(const Token& token, const SegmentedString&
updatePredictedBaseURL(token);
return;
}
+ if (RuntimeEnabledFeatures::pictureEnabled() && (match(tagImpl, pictureTag))) {
+ m_inPicture = true;
+ m_pictureSourceURL = String();
+ return;
+ }
- StartTagScanner scanner(tagImpl, m_deviceScaleFactor);
+ StartTagScanner scanner(tagImpl, m_mediaValues);
scanner.processAttributes(token.attributes());
+ if (m_inPicture)
+ scanner.handlePictureSourceURL(m_pictureSourceURL);
OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predictedBaseElementURL, source);
if (request)
requests.append(request.release());
@@ -372,8 +469,8 @@ void TokenPreloadScanner::updatePredictedBaseURL(const Token& token)
m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute->value)).copy();
}
-HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const KURL& documentURL, float deviceScaleFactor)
- : m_scanner(documentURL, deviceScaleFactor)
+HTMLPreloadScanner::HTMLPreloadScanner(const HTMLParserOptions& options, const KURL& documentURL, PassRefPtr<MediaValues> mediaValues)
+ : m_scanner(documentURL, mediaValues)
, m_tokenizer(HTMLTokenizer::create(options))
{
}
@@ -391,6 +488,8 @@ void HTMLPreloadScanner::scan(HTMLResourcePreloader* preloader, const KURL& star
{
ASSERT(isMainThread()); // HTMLTokenizer::updateStateFor only works on the main thread.
+ TRACE_EVENT1("webkit", "HTMLPreloadScanner::scan", "source_length", m_source.length());
+
// When we start scanning, our best prediction of the baseElementURL is the real one!
if (!startingBaseElementURL.isEmpty())
m_scanner.setPredictedBaseElementURL(startingBaseElementURL);
@@ -399,7 +498,7 @@ void HTMLPreloadScanner::scan(HTMLResourcePreloader* preloader, const KURL& star
while (m_tokenizer->nextToken(m_source, m_token)) {
if (m_token.type() == HTMLToken::StartTag)
- m_tokenizer->updateStateFor(AtomicString(m_token.name()));
+ m_tokenizer->updateStateFor(attemptStaticStringCreation(m_token.name(), Likely8Bit));
m_scanner.scan(m_token, m_source, requests);
m_token.clear();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
index 956d30b3d28..96046e1259d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLPreloadScanner.h
@@ -40,11 +40,12 @@ typedef size_t TokenPreloadScannerCheckpoint;
class HTMLParserOptions;
class HTMLTokenizer;
class SegmentedString;
+class MediaValues;
class TokenPreloadScanner {
WTF_MAKE_NONCOPYABLE(TokenPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
public:
- TokenPreloadScanner(const KURL& documentURL, float deviceScaleFactor);
+ TokenPreloadScanner(const KURL& documentURL, PassRefPtr<MediaValues>);
~TokenPreloadScanner();
void scan(const HTMLToken&, const SegmentedString&, PreloadRequestStream& requests);
@@ -89,8 +90,10 @@ private:
const KURL m_documentURL;
KURL m_predictedBaseElementURL;
bool m_inStyle;
- float m_deviceScaleFactor;
+ bool m_inPicture;
+ String m_pictureSourceURL;
size_t m_templateCount;
+ RefPtr<MediaValues> m_mediaValues;
Vector<Checkpoint> m_checkpoints;
};
@@ -98,7 +101,7 @@ private:
class HTMLPreloadScanner {
WTF_MAKE_NONCOPYABLE(HTMLPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
public:
- HTMLPreloadScanner(const HTMLParserOptions&, const KURL& documentURL, float deviceScaleFactor);
+ HTMLPreloadScanner(const HTMLParserOptions&, const KURL& documentURL, PassRefPtr<MediaValues>);
~HTMLPreloadScanner();
void appendToEnd(const SegmentedString&);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
index 08e70a6a278..76857627141 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.cpp
@@ -29,9 +29,7 @@
#include "core/dom/Document.h"
#include "core/fetch/FetchInitiatorInfo.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/html/HTMLImport.h"
-#include "core/css/MediaList.h"
-#include "core/css/MediaQueryEvaluator.h"
+#include "core/html/imports/HTMLImport.h"
#include "core/rendering/RenderObject.h"
#include "public/platform/Platform.h"
@@ -42,20 +40,19 @@ bool PreloadRequest::isSafeToSendToAnotherThread() const
return m_initiatorName.isSafeToSendToAnotherThread()
&& m_charset.isSafeToSendToAnotherThread()
&& m_resourceURL.isSafeToSendToAnotherThread()
- && m_mediaAttribute.isSafeToSendToAnotherThread()
&& m_baseURL.isSafeToSendToAnotherThread();
}
KURL PreloadRequest::completeURL(Document* document)
{
- return document->completeURL(m_resourceURL, m_baseURL.isEmpty() ? document->url() : m_baseURL);
+ return document->completeURLWithOverride(m_resourceURL, m_baseURL.isEmpty() ? document->url() : m_baseURL);
}
FetchRequest PreloadRequest::resourceRequest(Document* document)
{
ASSERT(isMainThread());
FetchInitiatorInfo initiatorInfo;
- initiatorInfo.name = m_initiatorName;
+ initiatorInfo.name = AtomicString(m_initiatorName);
initiatorInfo.position = m_initiatorPosition;
FetchRequest request(ResourceRequest(completeURL(document)), initiatorInfo);
@@ -73,28 +70,11 @@ void HTMLResourcePreloader::takeAndPreload(PreloadRequestStream& r)
preload(it->release());
}
-static bool mediaAttributeMatches(Frame* frame, RenderStyle* renderStyle, const String& attributeValue)
-{
- RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(attributeValue);
- MediaQueryEvaluator mediaQueryEvaluator("screen", frame, renderStyle);
- return mediaQueryEvaluator.eval(mediaQueries.get());
-}
-
void HTMLResourcePreloader::preload(PassOwnPtr<PreloadRequest> preload)
{
- Document* executingDocument = m_document->import() ? m_document->import()->master() : m_document;
- Document* loadingDocument = m_document;
-
- ASSERT(executingDocument->frame());
- ASSERT(executingDocument->renderer());
- ASSERT(executingDocument->renderer()->style());
- if (!preload->media().isEmpty() && !mediaAttributeMatches(executingDocument->frame(), executingDocument->renderer()->style(), preload->media()))
- return;
-
FetchRequest request = preload->resourceRequest(m_document);
blink::Platform::current()->histogramCustomCounts("WebCore.PreloadDelayMs", static_cast<int>(1000 * (monotonicallyIncreasingTime() - preload->discoveryTime())), 0, 2000, 20);
- loadingDocument->fetcher()->preload(preload->resourceType(), request, preload->charset());
+ m_document->fetcher()->preload(preload->resourceType(), request, preload->charset());
}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
index 48686b6ca73..ee6868c143c 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLResourcePreloader.h
@@ -35,14 +35,9 @@ namespace WebCore {
class PreloadRequest {
public:
- static PassOwnPtr<PreloadRequest> create(const String& initiatorName, const TextPosition& initiatorPosition, const String& resourceURL, const KURL& baseURL, Resource::Type resourceType, const String& mediaAttribute)
- {
- return adoptPtr(new PreloadRequest(initiatorName, initiatorPosition, resourceURL, baseURL, resourceType, mediaAttribute));
- }
-
static PassOwnPtr<PreloadRequest> create(const String& initiatorName, const TextPosition& initiatorPosition, const String& resourceURL, const KURL& baseURL, Resource::Type resourceType)
{
- return adoptPtr(new PreloadRequest(initiatorName, initiatorPosition, resourceURL, baseURL, resourceType, ""));
+ return adoptPtr(new PreloadRequest(initiatorName, initiatorPosition, resourceURL, baseURL, resourceType));
}
bool isSafeToSendToAnotherThread() const;
@@ -50,7 +45,6 @@ public:
FetchRequest resourceRequest(Document*);
const String& charset() const { return m_charset; }
- const String& media() const { return m_mediaAttribute; }
double discoveryTime() const { return m_discoveryTime; }
void setCharset(const String& charset) { m_charset = charset.isolatedCopy(); }
void setCrossOriginEnabled(StoredCredentials allowCredentials)
@@ -62,13 +56,12 @@ public:
Resource::Type resourceType() const { return m_resourceType; }
private:
- PreloadRequest(const String& initiatorName, const TextPosition& initiatorPosition, const String& resourceURL, const KURL& baseURL, Resource::Type resourceType, const String& mediaAttribute)
+ PreloadRequest(const String& initiatorName, const TextPosition& initiatorPosition, const String& resourceURL, const KURL& baseURL, Resource::Type resourceType)
: m_initiatorName(initiatorName)
, m_initiatorPosition(initiatorPosition)
, m_resourceURL(resourceURL.isolatedCopy())
, m_baseURL(baseURL.copy())
, m_resourceType(resourceType)
- , m_mediaAttribute(mediaAttribute.isolatedCopy())
, m_isCORSEnabled(false)
, m_allowCredentials(DoNotAllowStoredCredentials)
, m_discoveryTime(monotonicallyIncreasingTime())
@@ -83,7 +76,6 @@ private:
KURL m_baseURL;
String m_charset;
Resource::Type m_resourceType;
- String m_mediaAttribute;
bool m_isCORSEnabled;
StoredCredentials m_allowCredentials;
double m_discoveryTime;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
index 1cb6555c243..70c4c25f3b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.cpp
@@ -33,10 +33,10 @@
#include "core/dom/Microtask.h"
#include "core/dom/ScriptLoader.h"
#include "core/fetch/ScriptResource.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/parser/HTMLInputStream.h"
#include "core/html/parser/HTMLScriptRunnerHost.h"
#include "core/html/parser/NestingLevelIncrementer.h"
-#include "core/frame/Frame.h"
#include "platform/NotImplemented.h"
namespace WebCore {
@@ -54,7 +54,23 @@ HTMLScriptRunner::HTMLScriptRunner(Document* document, HTMLScriptRunnerHost* hos
HTMLScriptRunner::~HTMLScriptRunner()
{
- // FIXME: Should we be passed a "done loading/parsing" callback sooner than destruction?
+#if ENABLE(OILPAN)
+ // If the document is destructed without having explicitly
+ // detached the parser (and this script runner object), perform
+ // detach steps now. This will happen if the Document, the parser
+ // and this script runner object are swept out in the same GC.
+ detach();
+#else
+ // Verify that detach() has been called.
+ ASSERT(!m_document);
+#endif
+}
+
+void HTMLScriptRunner::detach()
+{
+ if (!m_document)
+ return;
+
if (m_parserBlockingScript.resource() && m_parserBlockingScript.watchingForLoad())
stopWatchingForLoad(m_parserBlockingScript);
@@ -63,23 +79,25 @@ HTMLScriptRunner::~HTMLScriptRunner()
if (pendingScript.resource() && pendingScript.watchingForLoad())
stopWatchingForLoad(pendingScript);
}
-}
-
-void HTMLScriptRunner::detach()
-{
- m_document = 0;
+ m_document = nullptr;
}
static KURL documentURLForScriptExecution(Document* document)
{
- if (!document || !document->frame())
+ if (!document)
+ return KURL();
+
+ if (!document->frame()) {
+ if (document->importsController())
+ return document->url();
return KURL();
+ }
// Use the URL of the currently active document for this frame.
return document->frame()->document()->url();
}
-inline PassRefPtr<Event> createScriptLoadEvent()
+inline PassRefPtrWillBeRawPtr<Event> createScriptLoadEvent()
{
return Event::create(EventTypeNames::load);
}
@@ -97,7 +115,7 @@ ScriptSourceCode HTMLScriptRunner::sourceFromPendingScript(const PendingScript&
bool HTMLScriptRunner::isPendingScriptReady(const PendingScript& script)
{
- m_hasScriptsWaitingForResources = !m_document->haveStylesheetsAndImportsLoaded();
+ m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady();
if (m_hasScriptsWaitingForResources)
return false;
if (script.resource() && !script.resource()->isLoaded())
@@ -109,14 +127,14 @@ void HTMLScriptRunner::executeParsingBlockingScript()
{
ASSERT(m_document);
ASSERT(!isExecutingScript());
- ASSERT(m_document->haveStylesheetsAndImportsLoaded());
+ ASSERT(m_document->isScriptExecutionReady());
ASSERT(isPendingScriptReady(m_parserBlockingScript));
InsertionPointRecord insertionPointRecord(m_host->inputStream());
- executePendingScriptAndDispatchEvent(m_parserBlockingScript);
+ executePendingScriptAndDispatchEvent(m_parserBlockingScript, PendingScriptBlockingParser);
}
-void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendingScript)
+void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendingScript, PendingScriptType pendingScriptType)
{
bool errorOccurred = false;
ScriptSourceCode sourceCode = sourceFromPendingScript(pendingScript, errorOccurred);
@@ -125,11 +143,18 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
if (pendingScript.resource() && pendingScript.watchingForLoad())
stopWatchingForLoad(pendingScript);
- if (!isExecutingScript())
+ if (!isExecutingScript()) {
Microtask::performCheckpoint();
+ if (pendingScriptType == PendingScriptBlockingParser) {
+ m_hasScriptsWaitingForResources = !m_document->isScriptExecutionReady();
+ // The parser cannot be unblocked as a microtask requested another resource
+ if (m_hasScriptsWaitingForResources)
+ return;
+ }
+ }
// Clear the pending script before possible rentrancy from executeScript()
- RefPtr<Element> element = pendingScript.releaseElementAndClear();
+ RefPtrWillBeRawPtr<Element> element = pendingScript.releaseElementAndClear();
if (ScriptLoader* scriptLoader = toScriptLoaderIfPossible(element.get())) {
NestingLevelIncrementer nestingLevelIncrementer(m_scriptNestingLevel);
IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_document);
@@ -137,8 +162,8 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
scriptLoader->dispatchErrorEvent();
else {
ASSERT(isExecutingScript());
- if (scriptLoader->executePotentiallyCrossOriginScript(sourceCode))
- element->dispatchEvent(createScriptLoadEvent());
+ scriptLoader->executeScript(sourceCode);
+ element->dispatchEvent(createScriptLoadEvent());
}
}
ASSERT(!isExecutingScript());
@@ -147,20 +172,30 @@ void HTMLScriptRunner::executePendingScriptAndDispatchEvent(PendingScript& pendi
void HTMLScriptRunner::watchForLoad(PendingScript& pendingScript)
{
ASSERT(!pendingScript.watchingForLoad());
- m_host->watchForLoad(pendingScript.resource());
+ ASSERT(!pendingScript.resource()->isLoaded());
+ // addClient() will call notifyFinished() if the load is complete.
+ // Callers do not expect to be re-entered from this call, so they
+ // should not become a client of an already-loaded Resource.
+ pendingScript.resource()->addClient(this);
pendingScript.setWatchingForLoad(true);
}
void HTMLScriptRunner::stopWatchingForLoad(PendingScript& pendingScript)
{
ASSERT(pendingScript.watchingForLoad());
- m_host->stopWatchingForLoad(pendingScript.resource());
+ pendingScript.resource()->removeClient(this);
pendingScript.setWatchingForLoad(false);
}
-// This function should match 10.2.5.11 "An end tag whose tag name is 'script'"
-// Script handling lives outside the tree builder to keep the each class simple.
-void HTMLScriptRunner::execute(PassRefPtr<Element> scriptElement, const TextPosition& scriptStartPosition)
+void HTMLScriptRunner::notifyFinished(Resource* cachedResource)
+{
+ m_host->notifyScriptLoaded(cachedResource);
+}
+
+// Implements the steps for 'An end tag whose tag name is "script"'
+// http://whatwg.org/html#scriptEndTag
+// Script handling lives outside the tree builder to keep each class simple.
+void HTMLScriptRunner::execute(PassRefPtrWillBeRawPtr<Element> scriptElement, const TextPosition& scriptStartPosition)
{
ASSERT(scriptElement);
// FIXME: If scripting is disabled, always just return.
@@ -207,7 +242,7 @@ void HTMLScriptRunner::executeScriptsWaitingForResources()
// to prevent parser or script re-entry during </style> parsing.
ASSERT(hasScriptsWaitingForResources());
ASSERT(!isExecutingScript());
- ASSERT(m_document->haveStylesheetsAndImportsLoaded());
+ ASSERT(m_document->isScriptExecutionReady());
executeParsingBlockingScripts();
}
@@ -222,7 +257,7 @@ bool HTMLScriptRunner::executeScriptsWaitingForParsing()
return false;
}
PendingScript first = m_scriptsToExecuteAfterParsing.takeFirst();
- executePendingScriptAndDispatchEvent(first);
+ executePendingScriptAndDispatchEvent(first, PendingScriptDeferred);
// FIXME: What is this m_document check for?
if (!m_document)
return false;
@@ -268,8 +303,8 @@ bool HTMLScriptRunner::requestPendingScript(PendingScript& pendingScript, Elemen
return true;
}
-// This method is meant to match the HTML5 definition of "running a script"
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#running-a-script
+// Implements the initial steps for 'An end tag whose tag name is "script"'
+// http://whatwg.org/html#scriptEndTag
void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStartPosition)
{
ASSERT(m_document);
@@ -285,10 +320,8 @@ void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStar
if (!scriptLoader)
return;
- // FIXME: This may be too agressive as we always deliver mutations at
- // every script element, even if it's not ready to execute yet. There's
- // unfortuantely no obvious way to tell if prepareScript is going to
- // execute the script from out here.
+ ASSERT(scriptLoader->isParserInserted());
+
if (!isExecutingScript())
Microtask::performCheckpoint();
@@ -316,4 +349,12 @@ void HTMLScriptRunner::runScript(Element* script, const TextPosition& scriptStar
}
}
+void HTMLScriptRunner::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_host);
+ visitor->trace(m_parserBlockingScript);
+ visitor->trace(m_scriptsToExecuteAfterParsing);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h
index 82d8bc2568a..46f2979bca1 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunner.h
@@ -27,6 +27,8 @@
#define HTMLScriptRunner_h
#include "core/dom/PendingScript.h"
+#include "core/fetch/ResourceClient.h"
+#include "platform/heap/Handle.h"
#include "wtf/Deque.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/TextPosition.h"
@@ -37,23 +39,23 @@ class Resource;
class ScriptResource;
class Document;
class Element;
-class Frame;
+class LocalFrame;
class HTMLScriptRunnerHost;
class ScriptSourceCode;
-class HTMLScriptRunner {
- WTF_MAKE_NONCOPYABLE(HTMLScriptRunner); WTF_MAKE_FAST_ALLOCATED;
+class HTMLScriptRunner FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLScriptRunner>, private ResourceClient {
+ WTF_MAKE_NONCOPYABLE(HTMLScriptRunner); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<HTMLScriptRunner> create(Document* document, HTMLScriptRunnerHost* host)
+ static PassOwnPtrWillBeRawPtr<HTMLScriptRunner> create(Document* document, HTMLScriptRunnerHost* host)
{
- return adoptPtr(new HTMLScriptRunner(document, host));
+ return adoptPtrWillBeNoop(new HTMLScriptRunner(document, host));
}
~HTMLScriptRunner();
void detach();
// Processes the passed in script and any pending scripts if possible.
- void execute(PassRefPtr<Element> scriptToProcess, const TextPosition& scriptStartPosition);
+ void execute(PassRefPtrWillBeRawPtr<Element> scriptToProcess, const TextPosition& scriptStartPosition);
void executeScriptsWaitingForLoad(Resource*);
bool hasScriptsWaitingForResources() const { return m_hasScriptsWaitingForResources; }
@@ -63,13 +65,23 @@ public:
bool hasParserBlockingScript() const;
bool isExecutingScript() const { return !!m_scriptNestingLevel; }
+ // ResourceClient
+ virtual void notifyFinished(Resource*) OVERRIDE;
+
+ void trace(Visitor*);
+
private:
HTMLScriptRunner(Document*, HTMLScriptRunnerHost*);
- Frame* frame() const;
+ LocalFrame* frame() const;
+
+ enum PendingScriptType {
+ PendingScriptBlockingParser,
+ PendingScriptDeferred
+ };
void executeParsingBlockingScript();
- void executePendingScriptAndDispatchEvent(PendingScript&);
+ void executePendingScriptAndDispatchEvent(PendingScript&, PendingScriptType);
void executeParsingBlockingScripts();
void requestParsingBlockingScript(Element*);
@@ -84,8 +96,8 @@ private:
bool isPendingScriptReady(const PendingScript&);
ScriptSourceCode sourceFromPendingScript(const PendingScript&, bool& errorOccurred) const;
- Document* m_document;
- HTMLScriptRunnerHost* m_host;
+ RawPtrWillBeMember<Document> m_document;
+ RawPtrWillBeMember<HTMLScriptRunnerHost> m_host;
PendingScript m_parserBlockingScript;
Deque<PendingScript> m_scriptsToExecuteAfterParsing; // http://www.whatwg.org/specs/web-apps/current-work/#list-of-scripts-that-will-execute-when-the-document-has-finished-parsing
unsigned m_scriptNestingLevel;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h
index e5323a2c3ae..ec3a8b68925 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLScriptRunnerHost.h
@@ -30,20 +30,16 @@
namespace WebCore {
-class Resource;
-class Element;
class HTMLInputStream;
-class ScriptSourceCode;
+class Resource;
+class Visitor;
-class HTMLScriptRunnerHost {
+class HTMLScriptRunnerHost : public WillBeGarbageCollectedMixin {
public:
virtual ~HTMLScriptRunnerHost() { }
+ virtual void trace(Visitor*) { }
- // Implementors should call cachedResource->addClient() here or soon after.
- virtual void watchForLoad(Resource*) = 0;
- // Implementors must call cachedResource->removeClient() immediately.
- virtual void stopWatchingForLoad(Resource*) = 0;
-
+ virtual void notifyScriptLoaded(Resource*) = 0;
virtual HTMLInputStream& inputStream() = 0;
virtual bool hasPreloadScanner() const = 0;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
index 7002dffab3b..f1af160e354 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.cpp
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,50 +34,176 @@
#include "core/html/parser/HTMLParserIdioms.h"
#include "platform/ParsingUtilities.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
-static bool compareByScaleFactor(const ImageCandidate& first, const ImageCandidate& second)
+static bool compareByDensity(const ImageCandidate& first, const ImageCandidate& second)
{
- return first.scaleFactor() < second.scaleFactor();
+ return first.density() < second.density();
}
+enum DescriptorTokenizerState {
+ Start,
+ InParenthesis,
+ AfterToken,
+};
+
+struct DescriptorToken {
+ unsigned start;
+ unsigned length;
+
+ DescriptorToken(unsigned start, unsigned length)
+ : start(start)
+ , length(length)
+ {
+ }
+
+ unsigned lastIndex()
+ {
+ return start + length - 1;
+ }
+
+ template<typename CharType>
+ int toInt(const CharType* attribute, bool& isValid)
+ {
+ return charactersToInt(attribute + start, length - 1, &isValid);
+ }
+
+ template<typename CharType>
+ float toFloat(const CharType* attribute, bool& isValid)
+ {
+ return charactersToFloat(attribute + start, length - 1, &isValid);
+ }
+};
+
template<typename CharType>
-inline bool isComma(CharType character)
+static void appendDescriptorAndReset(const CharType* attributeStart, const CharType*& descriptorStart, const CharType* position, Vector<DescriptorToken>& descriptors)
{
- return character == ',';
+ if (position > descriptorStart)
+ descriptors.append(DescriptorToken(descriptorStart - attributeStart, position - descriptorStart));
+ descriptorStart = 0;
}
+// The following is called appendCharacter to match the spec's terminology.
template<typename CharType>
-static bool parseDescriptors(const CharType* descriptorsStart, const CharType* descriptorsEnd, float& imgScaleFactor)
+static void appendCharacter(const CharType* descriptorStart, const CharType* position)
{
- const CharType* position = descriptorsStart;
- bool isValid = true;
- bool isScaleFactorFound = false;
- while (position < descriptorsEnd) {
- // 13.1. Let descriptor list be the result of splitting unparsed descriptors on spaces.
- skipWhile<CharType, isHTMLSpace<CharType> >(position, descriptorsEnd);
- const CharType* currentDescriptorStart = position;
- skipWhile<CharType, isNotHTMLSpace<CharType> >(position, descriptorsEnd);
- const CharType* currentDescriptorEnd = position;
+ // Since we don't copy the tokens, this just set the point where the descriptor tokens start.
+ if (!descriptorStart)
+ descriptorStart = position;
+}
+template<typename CharType>
+static bool isEOF(const CharType* position, const CharType* end)
+{
+ return position >= end;
+}
+
+template<typename CharType>
+static void tokenizeDescriptors(const CharType* attributeStart,
+ const CharType*& position,
+ const CharType* attributeEnd,
+ Vector<DescriptorToken>& descriptors)
+{
+ DescriptorTokenizerState state = Start;
+ const CharType* descriptorsStart = position;
+ const CharType* currentDescriptorStart = descriptorsStart;
+ while (true) {
+ switch (state) {
+ case Start:
+ if (isEOF(position, attributeEnd)) {
+ appendDescriptorAndReset(attributeStart, currentDescriptorStart, attributeEnd, descriptors);
+ return;
+ }
+ if (isComma(*position)) {
+ appendDescriptorAndReset(attributeStart, currentDescriptorStart, position, descriptors);
+ ++position;
+ return;
+ }
+ if (isHTMLSpace(*position)) {
+ appendDescriptorAndReset(attributeStart, currentDescriptorStart, position, descriptors);
+ currentDescriptorStart = position + 1;
+ state = AfterToken;
+ } else if (*position == '(') {
+ appendCharacter(currentDescriptorStart, position);
+ state = InParenthesis;
+ } else {
+ appendCharacter(currentDescriptorStart, position);
+ }
+ break;
+ case InParenthesis:
+ if (isEOF(position, attributeEnd)) {
+ appendDescriptorAndReset(attributeStart, currentDescriptorStart, attributeEnd, descriptors);
+ return;
+ }
+ if (*position == ')') {
+ appendCharacter(currentDescriptorStart, position);
+ state = Start;
+ } else {
+ appendCharacter(currentDescriptorStart, position);
+ }
+ break;
+ case AfterToken:
+ if (isEOF(position, attributeEnd))
+ return;
+ if (!isHTMLSpace(*position)) {
+ state = Start;
+ currentDescriptorStart = position;
+ --position;
+ }
+ break;
+ }
++position;
- ASSERT(currentDescriptorEnd > currentDescriptorStart);
- --currentDescriptorEnd;
- unsigned descriptorLength = currentDescriptorEnd - currentDescriptorStart;
- if (*currentDescriptorEnd == 'x') {
- if (isScaleFactorFound)
- return false;
- imgScaleFactor = charactersToFloat(currentDescriptorStart, descriptorLength, &isValid);
- isScaleFactorFound = true;
- } else {
+ }
+}
+
+template<typename CharType>
+static bool parseDescriptors(const CharType* attribute, Vector<DescriptorToken>& descriptors, DescriptorParsingResult& result)
+{
+ for (Vector<DescriptorToken>::iterator it = descriptors.begin(); it != descriptors.end(); ++it) {
+ if (it->length == 0)
continue;
+ CharType c = attribute[it->lastIndex()];
+ bool isValid = false;
+ if (RuntimeEnabledFeatures::pictureSizesEnabled() && c == 'w') {
+ if (result.hasDensity() || result.hasWidth())
+ return false;
+ int resourceWidth = it->toInt(attribute, isValid);
+ if (!isValid || resourceWidth <= 0)
+ return false;
+ result.setResourceWidth(resourceWidth);
+ } else if (RuntimeEnabledFeatures::pictureSizesEnabled() && c == 'h') {
+ // This is here only for future compat purposes.
+ // The value of the 'h' descriptor is not used.
+ if (result.hasDensity() || result.hasHeight())
+ return false;
+ int resourceHeight = it->toInt(attribute, isValid);
+ if (!isValid || resourceHeight <= 0)
+ return false;
+ result.setResourceHeight(resourceHeight);
+ } else if (c == 'x') {
+ if (result.hasDensity() || result.hasHeight() || result.hasWidth())
+ return false;
+ float density = it->toFloat(attribute, isValid);
+ if (!isValid || density < 0)
+ return false;
+ result.setDensity(density);
}
}
- return isValid;
+ return true;
}
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#processing-the-image-candidates
+static bool parseDescriptors(const String& attribute, Vector<DescriptorToken>& descriptors, DescriptorParsingResult& result)
+{
+ // FIXME: See if StringView can't be extended to replace DescriptorToken here.
+ if (attribute.is8Bit()) {
+ return parseDescriptors(attribute.characters8(), descriptors, result);
+ }
+ return parseDescriptors(attribute.characters16(), descriptors, result);
+}
+
+// http://picture.responsiveimages.org/#parse-srcset-attr
template<typename CharType>
static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, const CharType* attributeStart, unsigned length, Vector<ImageCandidate>& imageCandidates)
{
@@ -84,37 +211,46 @@ static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, con
const CharType* attributeEnd = position + length;
while (position < attributeEnd) {
- float imgScaleFactor = 1.0;
-
- // 4. Splitting loop: Skip whitespace.
- skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd);
- if (position == attributeEnd)
+ // 4. Splitting loop: Collect a sequence of characters that are space characters or U+002C COMMA characters.
+ skipWhile<CharType, isHTMLSpaceOrComma<CharType> >(position, attributeEnd);
+ if (position == attributeEnd) {
+ // Contrary to spec language - descriptor parsing happens on each candidate, so when we reach the attributeEnd, we can exit.
break;
- const CharType* imageURLStart = position;
-
- // If The current candidate is either totally empty or only contains space, skipping.
- if (*position == ',') {
- ++position;
- continue;
}
+ const CharType* imageURLStart = position;
+ // 6. Collect a sequence of characters that are not space characters, and let that be url.
- // 5. Collect a sequence of characters that are not space characters, and let that be url.
skipUntil<CharType, isHTMLSpace<CharType> >(position, attributeEnd);
const CharType* imageURLEnd = position;
- if (position != attributeEnd && *(position - 1) == ',') {
- --imageURLEnd;
+ DescriptorParsingResult result;
+
+ // 8. If url ends with a U+002C COMMA character (,)
+ if (isComma(*(position - 1))) {
+ // Remove all trailing U+002C COMMA characters from url.
+ imageURLEnd = position - 1;
+ reverseSkipWhile<CharType, isComma>(imageURLEnd, imageURLStart);
+ ++imageURLEnd;
+ // If url is empty, then jump to the step labeled splitting loop.
+ if (imageURLStart == imageURLEnd)
+ continue;
} else {
- // 7. Collect a sequence of characters that are not "," (U+002C) characters, and let that be descriptors.
- skipWhile<CharType, isHTMLSpace<CharType> >(position, attributeEnd);
- const CharType* descriptorsStart = position;
- skipUntil<CharType, isComma<CharType> >(position, attributeEnd);
- const CharType* descriptorsEnd = position;
- if (!parseDescriptors(descriptorsStart, descriptorsEnd, imgScaleFactor))
+ // Advancing position here (contrary to spec) to avoid an useless extra state machine step.
+ // Filed a spec bug: https://github.com/ResponsiveImagesCG/picture-element/issues/189
+ ++position;
+ Vector<DescriptorToken> descriptorTokens;
+ tokenizeDescriptors(attributeStart, position, attributeEnd, descriptorTokens);
+ // Contrary to spec language - descriptor parsing happens on each candidate.
+ // This is a black-box equivalent, to avoid storing descriptor lists for each candidate.
+ if (!parseDescriptors(attribute, descriptorTokens, result))
continue;
}
- imageCandidates.append(ImageCandidate(attribute, imageURLStart - attributeStart, imageURLEnd - imageURLStart, imgScaleFactor));
+ ASSERT(imageURLEnd > attributeStart);
+ unsigned imageURLStartingPosition = imageURLStart - attributeStart;
+ ASSERT(imageURLEnd > imageURLStart);
+ unsigned imageURLLength = imageURLEnd - imageURLStart;
+ imageCandidates.append(ImageCandidate(attribute, imageURLStartingPosition, imageURLLength, result, ImageCandidate::SrcsetOrigin));
// 11. Return to the step labeled splitting loop.
}
}
@@ -130,36 +266,61 @@ static void parseImageCandidatesFromSrcsetAttribute(const String& attribute, Vec
parseImageCandidatesFromSrcsetAttribute<UChar>(attribute, attribute.characters16(), attribute.length(), imageCandidates);
}
-static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, Vector<ImageCandidate>& imageCandidates)
+static ImageCandidate pickBestImageCandidate(float deviceScaleFactor, unsigned sourceSize, Vector<ImageCandidate>& imageCandidates)
{
+ const float defaultDensityValue = 1.0;
+ bool ignoreSrc = false;
if (imageCandidates.isEmpty())
return ImageCandidate();
- std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByScaleFactor);
+ // http://picture.responsiveimages.org/#normalize-source-densities
+ for (Vector<ImageCandidate>::iterator it = imageCandidates.begin(); it != imageCandidates.end(); ++it) {
+ if (it->resourceWidth() > 0) {
+ it->setDensity((float)it->resourceWidth() / (float)sourceSize);
+ ignoreSrc = true;
+ } else if (it->density() < 0) {
+ it->setDensity(defaultDensityValue);
+ }
+ }
+
+ std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByDensity);
unsigned i;
for (i = 0; i < imageCandidates.size() - 1; ++i) {
- if (imageCandidates[i].scaleFactor() >= deviceScaleFactor)
+ if ((imageCandidates[i].density() >= deviceScaleFactor) && (!ignoreSrc || !imageCandidates[i].srcOrigin()))
break;
}
- return imageCandidates[i];
+
+ if (imageCandidates[i].srcOrigin() && ignoreSrc) {
+ ASSERT(i > 0);
+ --i;
+ }
+ float winningDensity = imageCandidates[i].density();
+
+ unsigned winner = i;
+ // 16. If an entry b in candidates has the same associated ... pixel density as an earlier entry a in candidates,
+ // then remove entry b
+ while ((i > 0) && (imageCandidates[--i].density() == winningDensity))
+ winner = i;
+
+ return imageCandidates[winner];
}
-ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const String& srcsetAttribute)
+ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, unsigned sourceSize, const String& srcsetAttribute)
{
Vector<ImageCandidate> imageCandidates;
parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates);
- return pickBestImageCandidate(deviceScaleFactor, imageCandidates);
+ return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates);
}
-ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute)
+ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, unsigned sourceSize, const String& srcAttribute, const String& srcsetAttribute)
{
if (srcsetAttribute.isNull()) {
if (srcAttribute.isNull())
return ImageCandidate();
- return ImageCandidate(srcAttribute, 0, srcAttribute.length(), 1);
+ return ImageCandidate(srcAttribute, 0, srcAttribute.length(), DescriptorParsingResult(), ImageCandidate::SrcOrigin);
}
Vector<ImageCandidate> imageCandidates;
@@ -167,12 +328,12 @@ ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const St
parseImageCandidatesFromSrcsetAttribute(srcsetAttribute, imageCandidates);
if (!srcAttribute.isEmpty())
- imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), 1.0));
+ imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), DescriptorParsingResult(), ImageCandidate::SrcOrigin));
- return pickBestImageCandidate(deviceScaleFactor, imageCandidates);
+ return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates);
}
-String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, ImageCandidate& srcsetImageCandidate)
+String bestFitSourceForImageAttributes(float deviceScaleFactor, unsigned sourceSize, const String& srcAttribute, ImageCandidate& srcsetImageCandidate)
{
if (srcsetImageCandidate.isEmpty())
return srcAttribute;
@@ -181,9 +342,9 @@ String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& sr
imageCandidates.append(srcsetImageCandidate);
if (!srcAttribute.isEmpty())
- imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), 1.0));
+ imageCandidates.append(ImageCandidate(srcAttribute, 0, srcAttribute.length(), DescriptorParsingResult(), ImageCandidate::SrcOrigin));
- return pickBestImageCandidate(deviceScaleFactor, imageCandidates).toString();
+ return pickBestImageCandidate(deviceScaleFactor, sourceSize, imageCandidates).toString();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
index 8964ffbcd5f..5ba5bff7f4f 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParser.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
* Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,27 +36,85 @@
namespace WebCore {
+enum { UninitializedDescriptor = -1 };
+
+class DescriptorParsingResult {
+public:
+ DescriptorParsingResult()
+ : m_density(UninitializedDescriptor)
+ , m_resourceWidth(UninitializedDescriptor)
+ , m_resourceHeight(UninitializedDescriptor)
+ {
+ }
+
+ bool hasDensity() const { return m_density >= 0; }
+ bool hasWidth() const { return m_resourceWidth >= 0; }
+ bool hasHeight() const { return m_resourceHeight >= 0; }
+
+ float density() const { ASSERT(hasDensity()); return m_density; }
+ unsigned resourceWidth() const { ASSERT(hasWidth()); return m_resourceWidth; }
+ unsigned resourceHeight() const { ASSERT(hasHeight()); return m_resourceHeight; }
+
+ void setResourceWidth(int width) { ASSERT(width >= 0); m_resourceWidth = (unsigned)width; }
+ void setResourceHeight(int height) { ASSERT(height >= 0); m_resourceHeight = (unsigned)height; }
+ void setDensity(float densityToSet) { ASSERT(densityToSet >= 0); m_density = densityToSet; }
+
+private:
+ float m_density;
+ int m_resourceWidth;
+ int m_resourceHeight;
+};
+
class ImageCandidate {
public:
+ enum OriginAttribute {
+ SrcsetOrigin,
+ SrcOrigin
+ };
+
ImageCandidate()
- : m_scaleFactor(1.0)
+ : m_density(1.0)
+ , m_resourceWidth(UninitializedDescriptor)
+ , m_originAttribute(SrcsetOrigin)
{
}
- ImageCandidate(const String& source, unsigned start, unsigned length, float scaleFactor)
+ ImageCandidate(const String& source, unsigned start, unsigned length, const DescriptorParsingResult& result, OriginAttribute originAttribute)
: m_string(source.createView(start, length))
- , m_scaleFactor(scaleFactor)
+ , m_density(result.hasDensity()?result.density():UninitializedDescriptor)
+ , m_resourceWidth(result.hasWidth()?result.resourceWidth():UninitializedDescriptor)
+ , m_originAttribute(originAttribute)
{
}
String toString() const
{
- return m_string.toString();
+ return String(m_string.toString());
+ }
+
+ AtomicString url() const
+ {
+ return AtomicString(m_string.toString());
+ }
+
+ void setDensity(float factor)
+ {
+ m_density = factor;
+ }
+
+ float density() const
+ {
+ return m_density;
+ }
+
+ int resourceWidth() const
+ {
+ return m_resourceWidth;
}
- inline float scaleFactor() const
+ bool srcOrigin() const
{
- return m_scaleFactor;
+ return (m_originAttribute == SrcOrigin);
}
inline bool isEmpty() const
@@ -65,14 +124,16 @@ public:
private:
StringView m_string;
- float m_scaleFactor;
+ float m_density;
+ int m_resourceWidth;
+ OriginAttribute m_originAttribute;
};
-ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const String& srcsetAttribute);
+ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, unsigned sourceSize, const String& srcsetAttribute);
-ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, const String& srcsetAttribute);
+ImageCandidate bestFitSourceForImageAttributes(float deviceScaleFactor, unsigned sourceSize, const String& srcAttribute, const String& srcsetAttribute);
-String bestFitSourceForImageAttributes(float deviceScaleFactor, const String& srcAttribute, ImageCandidate& srcsetImageCandidate);
+String bestFitSourceForImageAttributes(float deviceScaleFactor, unsigned sourceSize, const String& srcAttribute, ImageCandidate& srcsetImageCandidate);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParserTest.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParserTest.cpp
new file mode 100644
index 00000000000..76236102f90
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLSrcsetParserTest.cpp
@@ -0,0 +1,102 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/parser/HTMLSrcsetParser.h"
+
+#include <gtest/gtest.h>
+#include <limits.h>
+
+namespace WebCore {
+
+typedef struct {
+ float deviceScaleFactor;
+ int effectiveSize;
+ const char* srcInput;
+ const char* srcsetInput;
+ const char* outputURL;
+ float outputDensity;
+ int outputResourceWidth;
+} TestCase;
+
+TEST(ImageCandidateTest, Basic)
+{
+ ImageCandidate candidate;
+ ASSERT_EQ(candidate.density(), 1);
+ ASSERT_EQ(candidate.resourceWidth(), -1);
+ ASSERT_EQ(candidate.srcOrigin(), false);
+
+}
+
+TEST(HTMLSrcsetParserTest, Basic)
+{
+ TestCase testCases[] = {
+ {2.0, -1, "", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1q, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "", "1x.gif 1x 100h, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1x 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", "1x.gif 1x 100h 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.0, -1, "", "1x.gif 1x, 2x.gif -2x", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "0x.gif 0x", "0x.gif", 0.0, -1},
+ {2.0, -1, "", "0x.gif -0x", "0x.gif", 0.0, -1},
+ {2.0, -1, "", "neg.gif -2x", "", 1.0, -1},
+ {2.0, -1, "", "1x.gif 1x, 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "1x.gif, 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "", "1x.gif , 2x.gif 2q", "1x.gif", 1.0, -1},
+ {2.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "1x.gif 1x, 2x.gif 2x", "", "1x.gif 1x, 2x.gif 2x", 1.0, -1},
+ {2.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+ {2.0, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.5, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.5, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.5, -1, "src.gif", "2x.gif 2x, 3x.gif 3x", "3x.gif", 3.0, -1},
+ {2.0, -1, "", "1x,, , x ,2x ", "1x", 1.0, -1},
+ {2.0, -1, "", "1x,, , x ,2x ", "1x", 1.0, -1},
+ {2.0, -1, "", ",,1x,, , x ,2x ", "1x", 1.0, -1},
+ {2.0, -1, "", ",,1x,,", "1x", 1.0, -1},
+ {2.0, -1, "", ",1x,", "1x", 1.0, -1},
+ {2.0, -1, "", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {2.0, -1, "", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 2x, 1x.gif 1x", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg", 2.0, -1},
+ {2.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "2x.gif", 2.0, -1},
+ {4.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100h, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "2x.gif", 2.0, -1},
+ {4.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "4x.gif", 4.0, -1},
+ {1.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "1x", 1.0, -1},
+ {5.0, -1, "", "1x,, , x ,2x , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, 2x.gif 2x ,", "4x.gif", 4.0, -1},
+ {2.0, -1, "", "1x.gif 1x, data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4K 2x", "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4K", 2.0, -1 },
+ {2.0, -1, "1x.gif", "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4K 2x", "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncmVlbiIvPgo8L3N2Zz4K", 2.0, -1 },
+ {2.0, -1, "1x.svg#red", "1x.svg#green 2x", "1x.svg#green", 2.0, -1 },
+ {2.0, -1, "", "1x.svg#red 1x, 1x.svg#green 2x", "1x.svg#green", 2.0, -1 },
+ {1.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+ {1.0, 400, "", "400.gif 400w 400h, 6000.gif 6000w", "400.gif", 1.0, 400},
+ {2.0, 400, "", "400.gif 400w, 6000.gif 6000w", "6000.gif", 15.0, 6000},
+ {1.0, 400, "src.gif", "800.gif 800w", "800.gif", 2.0, 800},
+ {1.0, 400, "src.gif", "0.gif 0w, 800.gif 800w", "800.gif", 2.0, 800},
+ {1.0, 400, "src.gif", "0.gif 0w, 2x.gif 2x", "src.gif", 1.0, -1},
+ {1.0, 400, "src.gif", "800.gif 2x, 1600.gif 1600w", "800.gif", 2.0, -1},
+ {1.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
+ {2.0, 400, "", "400.gif 400w, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, 0, "", "400.gif 400w, 6000.gif 6000w", "400.gif", std::numeric_limits<float>::infinity(), 400},
+ {2.0, -1, "", ", 1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+ {1.0, -1, "", ",1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+ {1.2, -1, "", ",1x.gif 1x, 1.4x.gif 1.4x, 2x.gif 2x", "1.4x.gif", 1.4, -1},
+ {1.0, -1, "", "inf.gif 0.00000000001x", "inf.gif", 1e-11, -1},
+ {1.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x", "1x.gif", 1.0, -1},
+ {2.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x", "2x.gif", 2.0, -1},
+ {0, 0, 0, 0, 0, 0} // Do not remove the terminator line.
+ };
+
+ for (unsigned i = 0; testCases[i].srcInput; ++i) {
+ TestCase test = testCases[i];
+ ImageCandidate candidate = bestFitSourceForImageAttributes(test.deviceScaleFactor, test.effectiveSize, test.srcInput, test.srcsetInput);
+ ASSERT_EQ(test.outputDensity, candidate.density());
+ ASSERT_EQ(test.outputResourceWidth, candidate.resourceWidth());
+ ASSERT_STREQ(test.outputURL, candidate.toString().ascii().data());
+ }
+}
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h
index d3dd15ca269..e15c2c119cc 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLStackItem.h
@@ -26,9 +26,9 @@
#ifndef HTMLStackItem_h
#define HTMLStackItem_h
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Element.h"
#include "core/html/parser/AtomicHTMLToken.h"
#include "wtf/RefCounted.h"
@@ -39,7 +39,7 @@ namespace WebCore {
class ContainerNode;
-class HTMLStackItem : public RefCounted<HTMLStackItem> {
+class HTMLStackItem : public RefCountedWillBeGarbageCollectedFinalized<HTMLStackItem> {
public:
enum ItemType {
ItemForContextElement,
@@ -47,15 +47,15 @@ public:
};
// Used by document fragment node and context element.
- static PassRefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, ItemType type)
+ static PassRefPtrWillBeRawPtr<HTMLStackItem> create(PassRefPtrWillBeRawPtr<ContainerNode> node, ItemType type)
{
- return adoptRef(new HTMLStackItem(node, type));
+ return adoptRefWillBeNoop(new HTMLStackItem(node, type));
}
// Used by HTMLElementStack and HTMLFormattingElementList.
- static PassRefPtr<HTMLStackItem> create(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
+ static PassRefPtrWillBeRawPtr<HTMLStackItem> create(PassRefPtrWillBeRawPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
{
- return adoptRef(new HTMLStackItem(node, token, namespaceURI));
+ return adoptRefWillBeNoop(new HTMLStackItem(node, token, namespaceURI));
}
Element* element() const { return toElement(m_node.get()); }
@@ -172,7 +172,6 @@ public:
|| tagName == HTMLNames::iframeTag
|| tagName == HTMLNames::imgTag
|| tagName == HTMLNames::inputTag
- || tagName == HTMLNames::isindexTag
|| tagName == HTMLNames::liTag
|| tagName == HTMLNames::linkTag
|| tagName == HTMLNames::listingTag
@@ -208,8 +207,10 @@ public:
|| tagName == HTMLNames::xmpTag;
}
+ void trace(Visitor* visitor) { visitor->trace(m_node); }
+
private:
- HTMLStackItem(PassRefPtr<ContainerNode> node, ItemType type)
+ HTMLStackItem(PassRefPtrWillBeRawPtr<ContainerNode> node, ItemType type)
: m_node(node)
{
switch (type) {
@@ -224,7 +225,7 @@ private:
}
}
- HTMLStackItem(PassRefPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
+ HTMLStackItem(PassRefPtrWillBeRawPtr<ContainerNode> node, AtomicHTMLToken* token, const AtomicString& namespaceURI = HTMLNames::xhtmlNamespaceURI)
: m_node(node)
, m_tokenLocalName(token->name())
, m_tokenAttributes(token->attributes())
@@ -233,7 +234,7 @@ private:
{
}
- RefPtr<ContainerNode> m_node;
+ RefPtrWillBeMember<ContainerNode> m_node;
AtomicString m_tokenLocalName;
Vector<Attribute> m_tokenAttributes;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h
index 64f3044631b..e2b67fc33aa 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLToken.h
@@ -27,7 +27,6 @@
#define HTMLToken_h
#include "core/dom/Attribute.h"
-#include "core/html/parser/HTMLToken.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -104,7 +103,12 @@ public:
m_range.start = 0;
m_range.end = 0;
m_baseOffset = 0;
- m_data.clear();
+ // Don't call Vector::clear() as that would destroy the
+ // alloced VectorBuffer. If the innerHTML'd content has
+ // two 257 character text nodes in a row, we'll needlessly
+ // thrash malloc. When we finally finish the parse the
+ // HTMLToken will be destroyed and the VectorBuffer released.
+ m_data.shrink(0);
m_orAllData = 0;
}
@@ -326,9 +330,7 @@ public:
{
ASSERT(character);
ASSERT(m_type == StartTag || m_type == EndTag);
- // FIXME: We should be able to add the following ASSERT once we fix
- // https://bugs.webkit.org/show_bug.cgi?id=62971
- // ASSERT(m_currentAttribute->nameRange.start);
+ ASSERT(m_currentAttribute->nameRange.start);
m_currentAttribute->name.append(character);
}
@@ -426,6 +428,7 @@ public:
m_orAllData |= character;
}
+ // Only for XSSAuditor
void eraseCharacters()
{
ASSERT(m_type == Character);
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
index ed8c954a64b..8b03782d45e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.cpp
@@ -28,8 +28,10 @@
#include "config.h"
#include "core/html/parser/HTMLTokenizer.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/HTMLTokenizerNames.h"
#include "core/html/parser/HTMLEntityParser.h"
+#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLTreeBuilder.h"
#include "platform/NotImplemented.h"
#include "core/xml/parser/MarkupTokenizerInlines.h"
@@ -37,7 +39,9 @@
#include "wtf/text/AtomicString.h"
#include "wtf/unicode/Unicode.h"
-using namespace WTF;
+// Please don't use DEFINE_STATIC_LOCAL in this file. The HTMLTokenizer is used
+// from multiple threads and DEFINE_STATIC_LOCAL isn't threadsafe.
+#undef DEFINE_STATIC_LOCAL
namespace WebCore {
@@ -1071,11 +1075,8 @@ bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
END_STATE()
HTML_BEGIN_STATE(MarkupDeclarationOpenState) {
- DEFINE_STATIC_LOCAL(String, dashDashString, ("--"));
- DEFINE_STATIC_LOCAL(String, doctypeString, ("doctype"));
- DEFINE_STATIC_LOCAL(String, cdataString, ("[CDATA["));
if (cc == '-') {
- SegmentedString::LookAheadResult result = source.lookAhead(dashDashString);
+ SegmentedString::LookAheadResult result = source.lookAhead(HTMLTokenizerNames::dashDash);
if (result == SegmentedString::DidMatch) {
source.advanceAndASSERT('-');
source.advanceAndASSERT('-');
@@ -1084,14 +1085,14 @@ bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
} else if (result == SegmentedString::NotEnoughCharacters)
return haveBufferedCharacterToken();
} else if (cc == 'D' || cc == 'd') {
- SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(doctypeString);
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(HTMLTokenizerNames::doctype);
if (result == SegmentedString::DidMatch) {
advanceStringAndASSERTIgnoringCase(source, "doctype");
HTML_SWITCH_TO(DOCTYPEState);
} else if (result == SegmentedString::NotEnoughCharacters)
return haveBufferedCharacterToken();
} else if (cc == '[' && shouldAllowCDATA()) {
- SegmentedString::LookAheadResult result = source.lookAhead(cdataString);
+ SegmentedString::LookAheadResult result = source.lookAhead(HTMLTokenizerNames::cdata);
if (result == SegmentedString::DidMatch) {
advanceStringAndASSERT(source, "[CDATA[");
HTML_SWITCH_TO(CDATASectionState);
@@ -1274,17 +1275,15 @@ bool HTMLTokenizer::nextToken(SegmentedString& source, HTMLToken& token)
m_token->setForceQuirks();
return emitAndReconsumeIn(source, HTMLTokenizer::DataState);
} else {
- DEFINE_STATIC_LOCAL(String, publicString, ("public"));
- DEFINE_STATIC_LOCAL(String, systemString, ("system"));
if (cc == 'P' || cc == 'p') {
- SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(publicString);
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(HTMLTokenizerNames::publicString);
if (result == SegmentedString::DidMatch) {
advanceStringAndASSERTIgnoringCase(source, "public");
HTML_SWITCH_TO(AfterDOCTYPEPublicKeywordState);
} else if (result == SegmentedString::NotEnoughCharacters)
return haveBufferedCharacterToken();
} else if (cc == 'S' || cc == 's') {
- SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(systemString);
+ SegmentedString::LookAheadResult result = source.lookAheadIgnoringCase(HTMLTokenizerNames::system);
if (result == SegmentedString::DidMatch) {
advanceStringAndASSERTIgnoringCase(source, "system");
HTML_SWITCH_TO(AfterDOCTYPESystemKeywordState);
@@ -1596,20 +1595,20 @@ String HTMLTokenizer::bufferedCharacters() const
return characters.toString();
}
-void HTMLTokenizer::updateStateFor(const AtomicString& tagName)
+void HTMLTokenizer::updateStateFor(const String& tagName)
{
- if (tagName == textareaTag || tagName == titleTag)
+ if (threadSafeMatch(tagName, textareaTag) || threadSafeMatch(tagName, titleTag))
setState(HTMLTokenizer::RCDATAState);
- else if (tagName == plaintextTag)
+ else if (threadSafeMatch(tagName, plaintextTag))
setState(HTMLTokenizer::PLAINTEXTState);
- else if (tagName == scriptTag)
+ else if (threadSafeMatch(tagName, scriptTag))
setState(HTMLTokenizer::ScriptDataState);
- else if (tagName == styleTag
- || tagName == iframeTag
- || tagName == xmpTag
- || (tagName == noembedTag && m_options.pluginsEnabled)
- || tagName == noframesTag
- || (tagName == noscriptTag && m_options.scriptEnabled))
+ else if (threadSafeMatch(tagName, styleTag)
+ || threadSafeMatch(tagName, iframeTag)
+ || threadSafeMatch(tagName, xmpTag)
+ || (threadSafeMatch(tagName, noembedTag) && m_options.pluginsEnabled)
+ || threadSafeMatch(tagName, noframesTag)
+ || (threadSafeMatch(tagName, noscriptTag) && m_options.scriptEnabled))
setState(HTMLTokenizer::RAWTEXTState);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
index aa7c059bf78..3a4ca7f96a1 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizer.h
@@ -126,7 +126,6 @@ public:
State state;
UChar additionalAllowedCharacter;
bool skipNextNewLine;
- bool forceNullCharacterReplacement;
bool shouldAllowCDATA;
Checkpoint()
@@ -134,7 +133,6 @@ public:
, state()
, additionalAllowedCharacter('\0')
, skipNextNewLine(false)
- , forceNullCharacterReplacement(false)
, shouldAllowCDATA(false)
{
}
@@ -176,7 +174,7 @@ public:
// * CDATA sections in foreign content will be tokenized as bogus comments
// instead of as character tokens.
//
- void updateStateFor(const AtomicString& tagName);
+ void updateStateFor(const String& tagName);
bool forceNullCharacterReplacement() const { return m_forceNullCharacterReplacement; }
void setForceNullCharacterReplacement(bool value) { m_forceNullCharacterReplacement = value; }
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizerNames.in b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizerNames.in
new file mode 100644
index 00000000000..0eab51f4ea0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTokenizerNames.in
@@ -0,0 +1,8 @@
+namespace="HTMLTokenizer"
+
+-- Symbol=dashDash
+doctype
+[CDATA[ Symbol=cdata
+# The symbol "public" conflicts with the C++ keyword.
+public Symbol=publicString
+system
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
index 4196cde09f0..092240a2c3b 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
@@ -27,19 +27,17 @@
#include "config.h"
#include "core/html/parser/HTMLTreeBuilder.h"
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-#include "XMLNSNames.h"
-#include "XMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
+#include "core/XMLNSNames.h"
+#include "core/XMLNames.h"
#include "core/dom/DocumentFragment.h"
+#include "core/dom/ElementTraversal.h"
#include "core/html/HTMLDocument.h"
#include "core/html/HTMLFormElement.h"
-#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLOptGroupElement.h"
-#include "core/html/HTMLTableElement.h"
#include "core/html/parser/AtomicHTMLToken.h"
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -136,18 +134,10 @@ static bool isFormattingTag(const AtomicString& tagName)
return tagName == aTag || isNonAnchorFormattingTag(tagName);
}
-static HTMLFormElement* closestFormAncestor(Element* element)
+static HTMLFormElement* closestFormAncestor(Element& element)
{
ASSERT(isMainThread());
- while (element) {
- if (element->hasTagName(formTag))
- return toHTMLFormElement(element);
- ContainerNode* parent = element->parentNode();
- if (!parent || !parent->isElementNode())
- return 0;
- element = toElement(parent);
- }
- return 0;
+ return Traversal<HTMLFormElement>::firstAncestorOrSelf(element);
}
class HTMLTreeBuilder::CharacterTokenBuffer {
@@ -305,27 +295,33 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f
, m_options(options)
{
ASSERT(isMainThread());
- // FIXME: This assertion will become invalid if <http://webkit.org/b/60316> is fixed.
ASSERT(contextElement);
- if (contextElement) {
- // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
- // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
- // and instead use the DocumentFragment as a root node.
- m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStackItem::ItemForDocumentFragmentNode));
- if (contextElement->hasTagName(templateTag))
- m_templateInsertionModes.append(TemplateContentsMode);
+ // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
+ // For efficiency, we skip step 4.2 ("Let root be a new html element with no attributes")
+ // and instead use the DocumentFragment as a root node.
+ m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStackItem::ItemForDocumentFragmentNode));
- resetInsertionModeAppropriately();
- m_tree.setForm(closestFormAncestor(contextElement));
- }
+ if (isHTMLTemplateElement(*contextElement))
+ m_templateInsertionModes.append(TemplateContentsMode);
+
+ resetInsertionModeAppropriately();
+ m_tree.setForm(closestFormAncestor(*contextElement));
}
HTMLTreeBuilder::~HTMLTreeBuilder()
{
}
+void HTMLTreeBuilder::trace(Visitor* visitor)
+{
+ visitor->trace(m_fragmentContext);
+ visitor->trace(m_tree);
+ visitor->trace(m_parser);
+ visitor->trace(m_scriptToProcess);
+}
+
void HTMLTreeBuilder::detach()
{
#ifndef NDEBUG
@@ -339,14 +335,14 @@ void HTMLTreeBuilder::detach()
}
HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext()
- : m_fragment(0)
+ : m_fragment(nullptr)
{
}
HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement)
: m_fragment(fragment)
{
- ASSERT(!fragment->hasChildNodes());
+ ASSERT(!fragment->hasChildren());
m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackItem::ItemForContextElement);
}
@@ -354,7 +350,13 @@ HTMLTreeBuilder::FragmentParsingContext::~FragmentParsingContext()
{
}
-PassRefPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
+void HTMLTreeBuilder::FragmentParsingContext::trace(Visitor* visitor)
+{
+ visitor->trace(m_fragment);
+ visitor->trace(m_contextElementStackItem);
+}
+
+PassRefPtrWillBeRawPtr<Element> HTMLTreeBuilder::takeScriptToProcess(TextPosition& scriptStartPosition)
{
ASSERT(m_scriptToProcess);
ASSERT(!m_tree.hasPendingTasks());
@@ -461,13 +463,6 @@ void HTMLTreeBuilder::processFakeEndTag(const QualifiedName& tagName)
processFakeEndTag(tagName.localName());
}
-void HTMLTreeBuilder::processFakeCharacters(const String& characters)
-{
- ASSERT(!characters.isEmpty());
- CharacterTokenBuffer buffer(characters);
- processCharacterBuffer(buffer);
-}
-
void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
{
if (!m_tree.openElements()->inButtonScope(pTag.localName()))
@@ -476,49 +471,6 @@ void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
processEndTag(&endP);
}
-Vector<Attribute> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken* token)
-{
- Vector<Attribute> attributes = token->attributes();
- for (int i = attributes.size() - 1; i >= 0; --i) {
- const QualifiedName& name = attributes.at(i).name();
- if (name.matches(nameAttr) || name.matches(actionAttr) || name.matches(promptAttr))
- attributes.remove(i);
- }
-
- attributes.append(Attribute(nameAttr, isindexTag.localName()));
- return attributes;
-}
-
-void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
-{
- ASSERT(token->type() == HTMLToken::StartTag);
- ASSERT(token->name() == isindexTag);
-
- if (m_parser->useCounter())
- m_parser->useCounter()->count(UseCounter::IsIndexElement);
-
- parseError(token);
- if (m_tree.form())
- return;
- notImplemented(); // Acknowledge self-closing flag
- processFakeStartTag(formTag);
- Attribute* actionAttribute = token->getAttributeItem(actionAttr);
- if (actionAttribute)
- m_tree.form()->setAttribute(actionAttr, actionAttribute->value());
- processFakeStartTag(hrTag);
- processFakeStartTag(labelTag);
- Attribute* promptAttribute = token->getAttributeItem(promptAttr);
- if (promptAttribute)
- processFakeCharacters(promptAttribute->value());
- else
- processFakeCharacters(Locale::defaultLocale().queryString(blink::WebLocalizedString::SearchableIndexIntroduction));
- processFakeStartTag(inputTag, attributesForIsindexInput(token));
- notImplemented(); // This second set of characters may be needed by non-english locales.
- processFakeEndTag(labelTag);
- processFakeStartTag(hrTag);
- processFakeEndTag(formTag);
-}
-
namespace {
bool isLi(const HTMLStackItem* item)
@@ -540,7 +492,7 @@ void HTMLTreeBuilder::processCloseWhenNestedTag(AtomicHTMLToken* token)
m_framesetOk = false;
HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
while (1) {
- RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
+ RefPtrWillBeRawPtr<HTMLStackItem> item = nodeRecord->stackItem();
if (shouldClose(item.get())) {
ASSERT(item->isElementNode());
processFakeEndTag(item->localName());
@@ -572,8 +524,8 @@ static void adjustSVGTagNameCase(AtomicHTMLToken* token)
static PrefixedNameToQualifiedNameMap* caseMap = 0;
if (!caseMap) {
caseMap = new PrefixedNameToQualifiedNameMap;
- const QualifiedName* const* svgTags = SVGNames::getSVGTags();
- mapLoweredLocalNameToName(caseMap, svgTags, SVGNames::SVGTagsCount);
+ OwnPtr<const QualifiedName*[]> svgTags = SVGNames::getSVGTags();
+ mapLoweredLocalNameToName(caseMap, svgTags.get(), SVGNames::SVGTagsCount);
}
const QualifiedName& casedName = caseMap->get(token->name());
@@ -582,14 +534,14 @@ static void adjustSVGTagNameCase(AtomicHTMLToken* token)
token->setName(casedName.localName());
}
-template<const QualifiedName* const* getAttrs(), unsigned length>
+template<PassOwnPtr<const QualifiedName*[]> getAttrs(), unsigned length>
static void adjustAttributes(AtomicHTMLToken* token)
{
static PrefixedNameToQualifiedNameMap* caseMap = 0;
if (!caseMap) {
caseMap = new PrefixedNameToQualifiedNameMap;
- const QualifiedName* const* attrs = getAttrs();
- mapLoweredLocalNameToName(caseMap, attrs, length);
+ OwnPtr<const QualifiedName*[]> attrs = getAttrs();
+ mapLoweredLocalNameToName(caseMap, attrs.get(), length);
}
for (unsigned i = 0; i < token->attributes().size(); ++i) {
@@ -627,11 +579,11 @@ static void adjustForeignAttributes(AtomicHTMLToken* token)
if (!map) {
map = new PrefixedNameToQualifiedNameMap;
- const QualifiedName* const* attrs = XLinkNames::getXLinkAttrs();
- addNamesWithPrefix(map, xlinkAtom, attrs, XLinkNames::XLinkAttrsCount);
+ OwnPtr<const QualifiedName*[]> attrs = XLinkNames::getXLinkAttrs();
+ addNamesWithPrefix(map, xlinkAtom, attrs.get(), XLinkNames::XLinkAttrsCount);
- attrs = XMLNames::getXMLAttrs();
- addNamesWithPrefix(map, xmlAtom, attrs, XMLNames::XMLAttrsCount);
+ OwnPtr<const QualifiedName*[]> xmlAttrs = XMLNames::getXMLAttrs();
+ addNamesWithPrefix(map, xmlAtom, xmlAttrs.get(), XMLNames::XMLAttrsCount);
map->add(WTF::xmlnsAtom, XMLNSNames::xmlnsAttr);
map->add("xmlns:xlink", QualifiedName(xmlnsAtom, xlinkAtom, XMLNSNames::xmlnsNamespaceURI));
@@ -859,10 +811,6 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken* token)
m_framesetOk = false;
return;
}
- if (token->name() == isindexTag) {
- processIsindexStartTagForInBody(token);
- return;
- }
if (token->name() == textareaTag) {
m_tree.insertHTMLElement(token);
m_shouldSkipLeadingNewline = true;
@@ -969,7 +917,7 @@ bool HTMLTreeBuilder::processTemplateEndTag(AtomicHTMLToken* token)
{
ASSERT(token->name() == templateTag.localName());
if (!m_tree.openElements()->hasTemplateInHTMLScope()) {
- ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && m_fragmentContext.contextElement()->hasTagName(templateTag)));
+ ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && isHTMLTemplateElement(m_fragmentContext.contextElement())));
parseError(token);
return false;
}
@@ -995,7 +943,7 @@ bool HTMLTreeBuilder::processEndOfFileForInTemplateContents(AtomicHTMLToken* tok
bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
{
- if (m_tree.currentIsRootNode() || m_tree.currentNode()->hasTagName(templateTag)) {
+ if (m_tree.currentIsRootNode() || isHTMLTemplateElement(*m_tree.currentNode())) {
ASSERT(isParsingFragmentOrTemplateContents());
// FIXME: parse error
return false;
@@ -1396,7 +1344,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken* token)
AtomicHTMLToken endOption(HTMLToken::EndTag, optionTag.localName());
processEndTag(&endOption);
}
- if (isHTMLOptGroupElement(m_tree.currentStackItem()->node())) {
+ if (m_tree.currentStackItem()->hasTagName(optgroupTag)) {
AtomicHTMLToken endOptgroup(HTMLToken::EndTag, optgroupTag.localName());
processEndTag(&endOptgroup);
}
@@ -1505,7 +1453,7 @@ void HTMLTreeBuilder::processAnyOtherEndTagForInBody(AtomicHTMLToken* token)
ASSERT(token->type() == HTMLToken::EndTag);
HTMLElementStack::ElementRecord* record = m_tree.openElements()->topRecord();
while (1) {
- RefPtr<HTMLStackItem> item = record->stackItem();
+ RefPtrWillBeRawPtr<HTMLStackItem> item = record->stackItem();
if (item->matchesHTMLTag(token->name())) {
m_tree.generateImpliedEndTagsWithExclusion(token->name());
if (!m_tree.currentStackItem()->matchesHTMLTag(token->name()))
@@ -1564,7 +1512,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
}
// 7.
ASSERT(furthestBlock->isAbove(formattingElementRecord));
- RefPtr<HTMLStackItem> commonAncestor = formattingElementRecord->next()->stackItem();
+ RefPtrWillBeRawPtr<HTMLStackItem> commonAncestor = formattingElementRecord->next()->stackItem();
// 8.
HTMLFormattingElementList::Bookmark bookmark = m_tree.activeFormattingElements()->bookmarkFor(formattingElement);
// 9.
@@ -1587,7 +1535,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
if (node == formattingElementRecord)
break;
// 9.7
- RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(node->stackItem().get());
+ RefPtrWillBeRawPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(node->stackItem().get());
HTMLFormattingElementList::Entry* nodeEntry = m_tree.activeFormattingElements()->find(node->element());
nodeEntry->replaceElement(newItem);
@@ -1604,7 +1552,7 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken* token)
// 10.
m_tree.insertAlreadyParsedChild(commonAncestor.get(), lastNode);
// 11.
- RefPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(formattingElementRecord->stackItem().get());
+ RefPtrWillBeRawPtr<HTMLStackItem> newItem = m_tree.createElementFromSavedToken(formattingElementRecord->stackItem().get());
// 12.
m_tree.takeAllChildren(newItem.get(), furthestBlock);
// 13.
@@ -1623,7 +1571,7 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
bool last = false;
HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
while (1) {
- RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
+ RefPtrWillBeRawPtr<HTMLStackItem> item = nodeRecord->stackItem();
if (item->node() == m_tree.openElements()->rootNode()) {
last = true;
if (isParsingFragment())
@@ -1636,7 +1584,7 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
while (item->node() != m_tree.openElements()->rootNode() && !item->hasTagName(templateTag)) {
nodeRecord = nodeRecord->next();
item = nodeRecord->stackItem();
- if (isHTMLTableElement(item->node()))
+ if (item->hasTagName(tableTag))
return setInsertionMode(InSelectInTableMode);
}
}
@@ -1653,7 +1601,7 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
if (item->hasTagName(colgroupTag)) {
return setInsertionMode(InColumnGroupMode);
}
- if (isHTMLTableElement(item->node()))
+ if (item->hasTagName(tableTag))
return setInsertionMode(InTableMode);
if (item->hasTagName(headTag)) {
if (!m_fragmentContext.fragment() || m_fragmentContext.contextElement() != item->node())
@@ -1665,7 +1613,7 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
if (item->hasTagName(framesetTag)) {
return setInsertionMode(InFramesetMode);
}
- if (isHTMLHtmlElement(item->node())) {
+ if (item->hasTagName(htmlTag)) {
if (m_tree.headStackItem())
return setInsertionMode(AfterHeadMode);
@@ -1839,7 +1787,7 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken* token)
return;
}
if (token->name() == formTag) {
- RefPtr<Element> node = m_tree.takeForm();
+ RefPtrWillBeRawPtr<Element> node = m_tree.takeForm();
if (!node || !m_tree.openElements()->inScope(node.get())) {
parseError(token);
return;
@@ -2212,9 +2160,9 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken* token)
case InSelectMode:
ASSERT(insertionMode() == InSelectMode || insertionMode() == InSelectInTableMode);
if (token->name() == optgroupTag) {
- if (m_tree.currentStackItem()->hasTagName(optionTag) && m_tree.oneBelowTop() && isHTMLOptGroupElement(m_tree.oneBelowTop()->node()))
+ if (m_tree.currentStackItem()->hasTagName(optionTag) && m_tree.oneBelowTop() && m_tree.oneBelowTop()->hasTagName(optgroupTag))
processFakeEndTag(optionTag);
- if (isHTMLOptGroupElement(m_tree.currentStackItem()->node())) {
+ if (m_tree.currentStackItem()->hasTagName(optgroupTag)) {
m_tree.openElements()->pop();
return;
}
@@ -2366,11 +2314,11 @@ ReprocessBuffer:
ASSERT(insertionMode() == InTableMode || insertionMode() == InTableBodyMode || insertionMode() == InRowMode);
ASSERT(m_pendingTableCharacters.isEmpty());
if (m_tree.currentStackItem()->isElementNode()
- && (isHTMLTableElement(m_tree.currentStackItem()->node())
- || m_tree.currentStackItem()->hasTagName(HTMLNames::tbodyTag)
- || m_tree.currentStackItem()->hasTagName(HTMLNames::tfootTag)
- || m_tree.currentStackItem()->hasTagName(HTMLNames::theadTag)
- || m_tree.currentStackItem()->hasTagName(HTMLNames::trTag))) {
+ && (m_tree.currentStackItem()->hasTagName(tableTag)
+ || m_tree.currentStackItem()->hasTagName(tbodyTag)
+ || m_tree.currentStackItem()->hasTagName(tfootTag)
+ || m_tree.currentStackItem()->hasTagName(theadTag)
+ || m_tree.currentStackItem()->hasTagName(trTag))) {
m_originalInsertionMode = m_insertionMode;
setInsertionMode(InTableTextMode);
// Note that we fall through to the InTableTextMode case below.
@@ -2407,7 +2355,6 @@ ReprocessBuffer:
// FIXME: parse error
setInsertionMode(InBodyMode);
goto ReprocessBuffer;
- break;
}
case TextMode: {
ASSERT(insertionMode() == TextMode);
@@ -2423,7 +2370,6 @@ ReprocessBuffer:
return;
defaultForInHeadNoscript();
goto ReprocessBuffer;
- break;
}
case InFramesetMode:
case AfterFramesetMode: {
@@ -2514,7 +2460,7 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken* token)
ASSERT(isParsingFragment());
return; // FIXME: Should we break here instead of returning?
}
- ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || m_tree.currentNode()->hasTagName(templateTag));
+ ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || isHTMLTemplateElement(m_tree.currentNode()));
processColgroupEndTagForInColumnGroup();
// Fall through
case InFramesetMode:
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
index 60ead95f286..9c9dcdfae8d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.h
@@ -30,6 +30,7 @@
#include "core/html/parser/HTMLConstructionSite.h"
#include "core/html/parser/HTMLElementStack.h"
#include "core/html/parser/HTMLParserOptions.h"
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
@@ -44,24 +45,25 @@ class AtomicHTMLToken;
class Document;
class DocumentFragment;
class Element;
-class Frame;
+class LocalFrame;
class HTMLToken;
class HTMLDocument;
class Node;
class HTMLDocumentParser;
-class HTMLTreeBuilder {
- WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED;
+class HTMLTreeBuilder FINAL : public NoBaseWillBeGarbageCollectedFinalized<HTMLTreeBuilder> {
+ WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, ParserContentPolicy parserContentPolicy, bool reportErrors, const HTMLParserOptions& options)
+ static PassOwnPtrWillBeRawPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, HTMLDocument* document, ParserContentPolicy parserContentPolicy, bool reportErrors, const HTMLParserOptions& options)
{
- return adoptPtr(new HTMLTreeBuilder(parser, document, parserContentPolicy, reportErrors, options));
+ return adoptPtrWillBeNoop(new HTMLTreeBuilder(parser, document, parserContentPolicy, reportErrors, options));
}
- static PassOwnPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
+ static PassOwnPtrWillBeRawPtr<HTMLTreeBuilder> create(HTMLDocumentParser* parser, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
{
- return adoptPtr(new HTMLTreeBuilder(parser, fragment, contextElement, parserContentPolicy, options));
+ return adoptPtrWillBeNoop(new HTMLTreeBuilder(parser, fragment, contextElement, parserContentPolicy, options));
}
~HTMLTreeBuilder();
+ void trace(Visitor*);
const HTMLElementStack* openElements() const { return m_tree.openElements(); }
@@ -75,7 +77,7 @@ public:
bool hasParserBlockingScript() const { return !!m_scriptToProcess; }
// Must be called to take the parser-blocking script before calling the parser again.
- PassRefPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
+ PassRefPtrWillBeRawPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition);
// Done, close any open tags, etc.
void finished();
@@ -153,7 +155,6 @@ private:
void processFakeStartTag(const QualifiedName&, const Vector<Attribute>& attributes = Vector<Attribute>());
void processFakeEndTag(const QualifiedName&);
void processFakeEndTag(const AtomicString&);
- void processFakeCharacters(const String&);
void processFakePEndTagIfPInButtonScope();
void processGenericRCDATAStartTag(AtomicHTMLToken*);
@@ -195,6 +196,7 @@ private:
class FragmentParsingContext {
WTF_MAKE_NONCOPYABLE(FragmentParsingContext);
+ DISALLOW_ALLOCATION();
public:
FragmentParsingContext();
FragmentParsingContext(DocumentFragment*, Element* contextElement);
@@ -204,9 +206,11 @@ private:
Element* contextElement() const { ASSERT(m_fragment); return m_contextElementStackItem->element(); }
HTMLStackItem* contextElementStackItem() const { ASSERT(m_fragment); return m_contextElementStackItem.get(); }
+ void trace(Visitor*);
+
private:
- DocumentFragment* m_fragment;
- RefPtr<HTMLStackItem> m_contextElementStackItem;
+ RawPtrWillBeMember<DocumentFragment> m_fragment;
+ RefPtrWillBeMember<HTMLStackItem> m_contextElementStackItem;
};
bool m_framesetOk;
@@ -231,9 +235,9 @@ private:
// We access parser because HTML5 spec requires that we be able to change the state of the tokenizer
// from within parser actions. We also need it to track the current position.
- HTMLDocumentParser* m_parser;
+ RawPtrWillBeMember<HTMLDocumentParser> m_parser;
- RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
+ RefPtrWillBeMember<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser.
TextPosition m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing.
HTMLParserOptions m_options;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
index 37273cbaea0..2f369953c05 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilderSimulator.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "core/html/parser/HTMLTreeBuilderSimulator.h"
-#include "HTMLNames.h"
-#include "MathMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/MathMLNames.h"
+#include "core/SVGNames.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLTokenizer.h"
#include "core/html/parser/HTMLTreeBuilder.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
index b46ff5ad2e9..d504a4c5703 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.cpp
@@ -27,14 +27,16 @@
#include "core/html/parser/HTMLViewSourceParser.h"
#include "core/dom/DOMImplementation.h"
+#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/parser/HTMLParserOptions.h"
#include "core/html/parser/HTMLToken.h"
+#include "core/html/parser/XSSAuditorDelegate.h"
namespace WebCore {
-HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument* document, const String& mimeType)
+HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument& document, const String& mimeType)
: DecodedDataDocumentParser(document)
- , m_tokenizer(HTMLTokenizer::create(HTMLParserOptions(document)))
+ , m_tokenizer(HTMLTokenizer::create(HTMLParserOptions(&document)))
{
if (mimeType != "text/html" && !DOMImplementation::isXMLMIMEType(mimeType))
m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
@@ -42,17 +44,21 @@ HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument* document, con
void HTMLViewSourceParser::pumpTokenizer()
{
+ m_xssAuditor.init(document(), 0);
+
while (true) {
m_sourceTracker.start(m_input.current(), m_tokenizer.get(), m_token);
if (!m_tokenizer->nextToken(m_input.current(), m_token))
return;
m_sourceTracker.end(m_input.current(), m_tokenizer.get(), m_token);
- document()->addSource(m_sourceTracker.sourceForToken(m_token), m_token);
+ OwnPtr<XSSInfo> xssInfo = m_xssAuditor.filterToken(FilterTokenRequest(m_token, m_sourceTracker, m_tokenizer->shouldAllowCDATA()));
+ HTMLViewSourceDocument::SourceAnnotation annotation = xssInfo ? HTMLViewSourceDocument::AnnotateSourceAsXSS : HTMLViewSourceDocument::AnnotateSourceAsSafe;
+ document()->addSource(m_sourceTracker.sourceForToken(m_token), m_token, annotation);
// FIXME: The tokenizer should do this work for us.
if (m_token.type() == HTMLToken::StartTag)
- m_tokenizer->updateStateFor(AtomicString(m_token.name()));
+ m_tokenizer->updateStateFor(attemptStaticStringCreation(m_token.name(), Likely8Bit));
m_token.clear();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h
index d1f0bec23c8..853387be4ab 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/HTMLViewSourceParser.h
@@ -31,19 +31,20 @@
#include "core/html/parser/HTMLInputStream.h"
#include "core/html/parser/HTMLSourceTracker.h"
#include "core/html/parser/HTMLTokenizer.h"
+#include "core/html/parser/XSSAuditor.h"
namespace WebCore {
class HTMLViewSourceParser FINAL : public DecodedDataDocumentParser {
public:
- static PassRefPtr<HTMLViewSourceParser> create(HTMLViewSourceDocument* document, const String& mimeType)
+ static PassRefPtrWillBeRawPtr<HTMLViewSourceParser> create(HTMLViewSourceDocument& document, const String& mimeType)
{
- return adoptRef(new HTMLViewSourceParser(document, mimeType));
+ return adoptRefWillBeNoop(new HTMLViewSourceParser(document, mimeType));
}
virtual ~HTMLViewSourceParser() { }
private:
- HTMLViewSourceParser(HTMLViewSourceDocument*, const String& mimeType);
+ HTMLViewSourceParser(HTMLViewSourceDocument&, const String& mimeType);
// DocumentParser
virtual void insert(const SegmentedString&) OVERRIDE { ASSERT_NOT_REACHED(); }
@@ -59,6 +60,7 @@ private:
HTMLToken m_token;
HTMLSourceTracker m_sourceTracker;
OwnPtr<HTMLTokenizer> m_tokenizer;
+ XSSAuditor m_xssAuditor;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h b/chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h
index fa1d110bdf3..478210e394e 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/NestingLevelIncrementer.h
@@ -26,11 +26,13 @@
#ifndef NestingLevelIncrementer_h
#define NestingLevelIncrementer_h
+#include "platform/heap/Handle.h"
#include "wtf/Noncopyable.h"
namespace WebCore {
class NestingLevelIncrementer {
+ STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(NestingLevelIncrementer);
public:
explicit NestingLevelIncrementer(unsigned& nestingLevel)
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp
index 38175a0f6bf..b7fc5151e67 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.cpp
@@ -25,14 +25,14 @@
#include "config.h"
#include "core/html/parser/TextDocumentParser.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/parser/HTMLTreeBuilder.h"
namespace WebCore {
using namespace HTMLNames;
-TextDocumentParser::TextDocumentParser(HTMLDocument* document)
+TextDocumentParser::TextDocumentParser(HTMLDocument& document)
: HTMLDocumentParser(document, false)
, m_haveInsertedFakePreElement(false)
{
@@ -42,11 +42,11 @@ TextDocumentParser::~TextDocumentParser()
{
}
-void TextDocumentParser::append(PassRefPtr<StringImpl> text)
+void TextDocumentParser::appendBytes(const char* data, size_t length)
{
if (!m_haveInsertedFakePreElement)
insertFakePreElement();
- HTMLDocumentParser::append(text);
+ HTMLDocumentParser::appendBytes(data, length);
}
void TextDocumentParser::insertFakePreElement()
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h b/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h
index 6b5bb9e6a4c..d1de29543dc 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/TextDocumentParser.h
@@ -30,18 +30,18 @@
namespace WebCore {
-class TextDocumentParser : public HTMLDocumentParser {
+class TextDocumentParser FINAL : public HTMLDocumentParser {
public:
- static PassRefPtr<TextDocumentParser> create(HTMLDocument* document)
+ static PassRefPtrWillBeRawPtr<TextDocumentParser> create(HTMLDocument& document)
{
- return adoptRef(new TextDocumentParser(document));
+ return adoptRefWillBeNoop(new TextDocumentParser(document));
}
virtual ~TextDocumentParser();
private:
- explicit TextDocumentParser(HTMLDocument*);
+ explicit TextDocumentParser(HTMLDocument&);
- virtual void append(PassRefPtr<StringImpl>);
+ virtual void appendBytes(const char*, size_t) OVERRIDE;
void insertFakePreElement();
bool m_haveInsertedFakePreElement;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.cpp b/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.cpp
new file mode 100644
index 00000000000..1f21e244f2a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.cpp
@@ -0,0 +1,439 @@
+/*
+ Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
+ Copyright (C) 2005, 2006, 2007 Alexey Proskuryakov (ap@nypop.com)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+
+#include "config.h"
+#include "core/html/parser/TextResourceDecoder.h"
+
+#include "core/HTMLNames.h"
+#include "core/dom/DOMImplementation.h"
+#include "core/html/parser/HTMLMetaCharsetParser.h"
+#include "platform/text/TextEncodingDetector.h"
+#include "wtf/StringExtras.h"
+#include "wtf/text/TextCodec.h"
+#include "wtf/text/TextEncodingRegistry.h"
+
+using namespace WTF;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4)
+{
+ return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4;
+}
+
+static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5)
+{
+ return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5;
+}
+
+static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7)
+{
+ return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5 && p[6] == b6 && p[7] == b7;
+}
+
+static inline bool bytesEqual(const char* p, char b0, char b1, char b2, char b3, char b4, char b5, char b6, char b7, char b8, char b9)
+{
+ return p[0] == b0 && p[1] == b1 && p[2] == b2 && p[3] == b3 && p[4] == b4 && p[5] == b5 && p[6] == b6 && p[7] == b7 && p[8] == b8 && p[9] == b9;
+}
+
+// You might think we should put these find functions elsewhere, perhaps with the
+// similar functions that operate on UChar, but arguably only the decoder has
+// a reason to process strings of char rather than UChar.
+
+static int find(const char* subject, size_t subjectLength, const char* target)
+{
+ size_t targetLength = strlen(target);
+ if (targetLength > subjectLength)
+ return -1;
+ for (size_t i = 0; i <= subjectLength - targetLength; ++i) {
+ bool match = true;
+ for (size_t j = 0; j < targetLength; ++j) {
+ if (subject[i + j] != target[j]) {
+ match = false;
+ break;
+ }
+ }
+ if (match)
+ return i;
+ }
+ return -1;
+}
+
+static WTF::TextEncoding findTextEncoding(const char* encodingName, int length)
+{
+ Vector<char, 64> buffer(length + 1);
+ memcpy(buffer.data(), encodingName, length);
+ buffer[length] = '\0';
+ return buffer.data();
+}
+
+TextResourceDecoder::ContentType TextResourceDecoder::determineContentType(const String& mimeType)
+{
+ if (equalIgnoringCase(mimeType, "text/css"))
+ return CSSContent;
+ if (equalIgnoringCase(mimeType, "text/html"))
+ return HTMLContent;
+ if (DOMImplementation::isXMLMIMEType(mimeType))
+ return XMLContent;
+ return PlainTextContent;
+}
+
+const WTF::TextEncoding& TextResourceDecoder::defaultEncoding(ContentType contentType, const WTF::TextEncoding& specifiedDefaultEncoding)
+{
+ // Despite 8.5 "Text/xml with Omitted Charset" of RFC 3023, we assume UTF-8 instead of US-ASCII
+ // for text/xml. This matches Firefox.
+ if (contentType == XMLContent)
+ return UTF8Encoding();
+ if (!specifiedDefaultEncoding.isValid())
+ return Latin1Encoding();
+ return specifiedDefaultEncoding;
+}
+
+TextResourceDecoder::TextResourceDecoder(const String& mimeType, const WTF::TextEncoding& specifiedDefaultEncoding, bool usesEncodingDetector)
+ : m_contentType(determineContentType(mimeType))
+ , m_encoding(defaultEncoding(m_contentType, specifiedDefaultEncoding))
+ , m_source(DefaultEncoding)
+ , m_hintEncoding(0)
+ , m_checkedForBOM(false)
+ , m_checkedForCSSCharset(false)
+ , m_checkedForXMLCharset(false)
+ , m_checkedForMetaCharset(false)
+ , m_useLenientXMLDecoding(false)
+ , m_sawError(false)
+ , m_usesEncodingDetector(usesEncodingDetector)
+{
+}
+
+TextResourceDecoder::~TextResourceDecoder()
+{
+}
+
+void TextResourceDecoder::setEncoding(const WTF::TextEncoding& encoding, EncodingSource source)
+{
+ // In case the encoding didn't exist, we keep the old one (helps some sites specifying invalid encodings).
+ if (!encoding.isValid())
+ return;
+
+ // When encoding comes from meta tag (i.e. it cannot be XML files sent via XHR),
+ // treat x-user-defined as windows-1252 (bug 18270)
+ if (source == EncodingFromMetaTag && !strcasecmp(encoding.name(), "x-user-defined"))
+ m_encoding = "windows-1252";
+ else if (source == EncodingFromMetaTag || source == EncodingFromXMLHeader || source == EncodingFromCSSCharset)
+ m_encoding = encoding.closestByteBasedEquivalent();
+ else
+ m_encoding = encoding;
+
+ m_codec.clear();
+ m_source = source;
+}
+
+// Returns the position of the encoding string.
+static int findXMLEncoding(const char* str, int len, int& encodingLength)
+{
+ int pos = find(str, len, "encoding");
+ if (pos == -1)
+ return -1;
+ pos += 8;
+
+ // Skip spaces and stray control characters.
+ while (pos < len && str[pos] <= ' ')
+ ++pos;
+
+ // Skip equals sign.
+ if (pos >= len || str[pos] != '=')
+ return -1;
+ ++pos;
+
+ // Skip spaces and stray control characters.
+ while (pos < len && str[pos] <= ' ')
+ ++pos;
+
+ // Skip quotation mark.
+ if (pos >= len)
+ return - 1;
+ char quoteMark = str[pos];
+ if (quoteMark != '"' && quoteMark != '\'')
+ return -1;
+ ++pos;
+
+ // Find the trailing quotation mark.
+ int end = pos;
+ while (end < len && str[end] != quoteMark)
+ ++end;
+ if (end >= len)
+ return -1;
+
+ encodingLength = end - pos;
+ return pos;
+}
+
+size_t TextResourceDecoder::checkForBOM(const char* data, size_t len)
+{
+ // Check for UTF-16/32 or UTF-8 BOM mark at the beginning, which is a sure sign of a Unicode encoding.
+ // We let it override even a user-chosen encoding.
+ ASSERT(!m_checkedForBOM);
+
+ size_t lengthOfBOM = 0;
+
+ size_t bufferLength = m_buffer.size();
+
+ size_t buf1Len = bufferLength;
+ size_t buf2Len = len;
+ const unsigned char* buf1 = reinterpret_cast<const unsigned char*>(m_buffer.data());
+ const unsigned char* buf2 = reinterpret_cast<const unsigned char*>(data);
+ unsigned char c1 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c2 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c3 = buf1Len ? (--buf1Len, *buf1++) : buf2Len ? (--buf2Len, *buf2++) : 0;
+ unsigned char c4 = buf2Len ? (--buf2Len, *buf2++) : 0;
+
+ // Check for the BOM.
+ if (c1 == 0xFF && c2 == 0xFE) {
+ if (c3 || c4) {
+ setEncoding(UTF16LittleEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 2;
+ } else {
+ setEncoding(UTF32LittleEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 4;
+ }
+ } else if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) {
+ setEncoding(UTF8Encoding(), AutoDetectedEncoding);
+ lengthOfBOM = 3;
+ } else if (c1 == 0xFE && c2 == 0xFF) {
+ setEncoding(UTF16BigEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 2;
+ } else if (!c1 && !c2 && c3 == 0xFE && c4 == 0xFF) {
+ setEncoding(UTF32BigEndianEncoding(), AutoDetectedEncoding);
+ lengthOfBOM = 4;
+ }
+
+ if (lengthOfBOM || bufferLength + len >= 4)
+ m_checkedForBOM = true;
+
+ return lengthOfBOM;
+}
+
+bool TextResourceDecoder::checkForCSSCharset(const char* data, size_t len, bool& movedDataToBuffer)
+{
+ if (m_source != DefaultEncoding && m_source != EncodingFromParentFrame) {
+ m_checkedForCSSCharset = true;
+ return true;
+ }
+
+ size_t oldSize = m_buffer.size();
+ m_buffer.grow(oldSize + len);
+ memcpy(m_buffer.data() + oldSize, data, len);
+
+ movedDataToBuffer = true;
+
+ if (m_buffer.size() <= 13) // strlen('@charset "x";') == 13
+ return false;
+
+ const char* dataStart = m_buffer.data();
+ const char* dataEnd = dataStart + m_buffer.size();
+
+ if (bytesEqual(dataStart, '@', 'c', 'h', 'a', 'r', 's', 'e', 't', ' ', '"')) {
+ dataStart += 10;
+ const char* pos = dataStart;
+
+ while (pos < dataEnd && *pos != '"')
+ ++pos;
+ if (pos == dataEnd)
+ return false;
+
+ int encodingNameLength = pos - dataStart;
+
+ ++pos;
+ if (pos == dataEnd)
+ return false;
+
+ if (*pos == ';')
+ setEncoding(findTextEncoding(dataStart, encodingNameLength), EncodingFromCSSCharset);
+ }
+
+ m_checkedForCSSCharset = true;
+ return true;
+}
+
+bool TextResourceDecoder::checkForXMLCharset(const char* data, size_t len, bool& movedDataToBuffer)
+{
+ if (m_source != DefaultEncoding && m_source != EncodingFromParentFrame) {
+ m_checkedForXMLCharset = true;
+ return true;
+ }
+
+ // This is not completely efficient, since the function might go
+ // through the HTML head several times.
+
+ size_t oldSize = m_buffer.size();
+ m_buffer.grow(oldSize + len);
+ memcpy(m_buffer.data() + oldSize, data, len);
+
+ movedDataToBuffer = true;
+
+ const char* ptr = m_buffer.data();
+ const char* pEnd = ptr + m_buffer.size();
+
+ // Is there enough data available to check for XML declaration?
+ if (m_buffer.size() < 8)
+ return false;
+
+ // Handle XML declaration, which can have encoding in it. This encoding is honored even for HTML documents.
+ // It is an error for an XML declaration not to be at the start of an XML document, and it is ignored in HTML documents in such case.
+ if (bytesEqual(ptr, '<', '?', 'x', 'm', 'l')) {
+ const char* xmlDeclarationEnd = ptr;
+ while (xmlDeclarationEnd != pEnd && *xmlDeclarationEnd != '>')
+ ++xmlDeclarationEnd;
+ if (xmlDeclarationEnd == pEnd)
+ return false;
+ // No need for +1, because we have an extra "?" to lose at the end of XML declaration.
+ int len = 0;
+ int pos = findXMLEncoding(ptr, xmlDeclarationEnd - ptr, len);
+ if (pos != -1)
+ setEncoding(findTextEncoding(ptr + pos, len), EncodingFromXMLHeader);
+ // continue looking for a charset - it may be specified in an HTTP-Equiv meta
+ } else if (bytesEqual(ptr, '<', 0, '?', 0, 'x', 0)) {
+ setEncoding(UTF16LittleEndianEncoding(), AutoDetectedEncoding);
+ } else if (bytesEqual(ptr, 0, '<', 0, '?', 0, 'x')) {
+ setEncoding(UTF16BigEndianEncoding(), AutoDetectedEncoding);
+ } else if (bytesEqual(ptr, '<', 0, 0, 0, '?', 0, 0, 0)) {
+ setEncoding(UTF32LittleEndianEncoding(), AutoDetectedEncoding);
+ } else if (bytesEqual(ptr, 0, 0, 0, '<', 0, 0, 0, '?')) {
+ setEncoding(UTF32BigEndianEncoding(), AutoDetectedEncoding);
+ }
+
+ m_checkedForXMLCharset = true;
+ return true;
+}
+
+void TextResourceDecoder::checkForMetaCharset(const char* data, size_t length)
+{
+ if (m_source == UserChosenEncoding || m_source == EncodingFromHTTPHeader || m_source == AutoDetectedEncoding) {
+ m_checkedForMetaCharset = true;
+ return;
+ }
+
+ if (!m_charsetParser)
+ m_charsetParser = HTMLMetaCharsetParser::create();
+
+ if (!m_charsetParser->checkForMetaCharset(data, length))
+ return;
+
+ setEncoding(m_charsetParser->encoding(), EncodingFromMetaTag);
+ m_charsetParser.clear();
+ m_checkedForMetaCharset = true;
+ return;
+}
+
+// We use the encoding detector in two cases:
+// 1. Encoding detector is turned ON and no other encoding source is
+// available (that is, it's DefaultEncoding).
+// 2. Encoding detector is turned ON and the encoding is set to
+// the encoding of the parent frame, which is also auto-detected.
+// Note that condition #2 is NOT satisfied unless parent-child frame
+// relationship is compliant to the same-origin policy. If they're from
+// different domains, |m_source| would not be set to EncodingFromParentFrame
+// in the first place.
+bool TextResourceDecoder::shouldAutoDetect() const
+{
+ // Just checking m_hintEncoding suffices here because it's only set
+ // in setHintEncoding when the source is AutoDetectedEncoding.
+ return m_usesEncodingDetector
+ && (m_source == DefaultEncoding || (m_source == EncodingFromParentFrame && m_hintEncoding));
+}
+
+String TextResourceDecoder::decode(const char* data, size_t len)
+{
+ size_t lengthOfBOM = 0;
+ if (!m_checkedForBOM)
+ lengthOfBOM = checkForBOM(data, len);
+
+ bool movedDataToBuffer = false;
+
+ if (m_contentType == CSSContent && !m_checkedForCSSCharset) {
+ if (!checkForCSSCharset(data, len, movedDataToBuffer))
+ return emptyString();
+ }
+
+ if ((m_contentType == HTMLContent || m_contentType == XMLContent) && !m_checkedForXMLCharset) {
+ if (!checkForXMLCharset(data, len, movedDataToBuffer))
+ return emptyString();
+ }
+
+ const char* dataForDecode = data + lengthOfBOM;
+ size_t lengthForDecode = len - lengthOfBOM;
+
+ if (!m_buffer.isEmpty()) {
+ if (!movedDataToBuffer) {
+ size_t oldSize = m_buffer.size();
+ m_buffer.grow(oldSize + len);
+ memcpy(m_buffer.data() + oldSize, data, len);
+ }
+
+ dataForDecode = m_buffer.data() + lengthOfBOM;
+ lengthForDecode = m_buffer.size() - lengthOfBOM;
+ }
+
+ if (m_contentType == HTMLContent && !m_checkedForMetaCharset)
+ checkForMetaCharset(dataForDecode, lengthForDecode);
+
+ if (shouldAutoDetect()) {
+ WTF::TextEncoding detectedEncoding;
+ if (detectTextEncoding(data, len, m_hintEncoding, &detectedEncoding))
+ setEncoding(detectedEncoding, EncodingFromContentSniffing);
+ }
+
+ ASSERT(m_encoding.isValid());
+
+ if (!m_codec)
+ m_codec = newTextCodec(m_encoding);
+
+ String result = m_codec->decode(dataForDecode, lengthForDecode, DoNotFlush, m_contentType == XMLContent && !m_useLenientXMLDecoding, m_sawError);
+
+ m_buffer.clear();
+ return result;
+}
+
+String TextResourceDecoder::flush()
+{
+ // If we can not identify the encoding even after a document is completely
+ // loaded, we need to detect the encoding if other conditions for
+ // autodetection is satisfied.
+ if (m_buffer.size() && shouldAutoDetect()
+ && ((!m_checkedForXMLCharset && (m_contentType == HTMLContent || m_contentType == XMLContent)) || (!m_checkedForCSSCharset && (m_contentType == CSSContent)))) {
+ WTF::TextEncoding detectedEncoding;
+ if (detectTextEncoding(m_buffer.data(), m_buffer.size(), m_hintEncoding, &detectedEncoding))
+ setEncoding(detectedEncoding, EncodingFromContentSniffing);
+ }
+
+ if (!m_codec)
+ m_codec = newTextCodec(m_encoding);
+
+ String result = m_codec->decode(m_buffer.data(), m_buffer.size(), FetchEOF, m_contentType == XMLContent && !m_useLenientXMLDecoding, m_sawError);
+ m_buffer.clear();
+ m_codec.clear();
+ m_checkedForBOM = false; // Skip BOM again when re-decoding.
+ return result;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.h b/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.h
new file mode 100644
index 00000000000..5ad2ad561f8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/parser/TextResourceDecoder.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
+ Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
+ Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef TextResourceDecoder_h
+#define TextResourceDecoder_h
+
+#include "wtf/RefCounted.h"
+#include "wtf/text/TextEncoding.h"
+
+namespace WebCore {
+
+class DocumentEncodingData;
+class HTMLMetaCharsetParser;
+
+class TextResourceDecoder {
+public:
+ enum EncodingSource {
+ DefaultEncoding,
+ AutoDetectedEncoding,
+ EncodingFromContentSniffing,
+ EncodingFromXMLHeader,
+ EncodingFromMetaTag,
+ EncodingFromCSSCharset,
+ EncodingFromHTTPHeader,
+ UserChosenEncoding,
+ EncodingFromParentFrame
+ };
+
+ static PassOwnPtr<TextResourceDecoder> create(const String& mimeType, const WTF::TextEncoding& defaultEncoding = WTF::TextEncoding(), bool usesEncodingDetector = false)
+ {
+ return adoptPtr(new TextResourceDecoder(mimeType, defaultEncoding, usesEncodingDetector));
+ }
+ ~TextResourceDecoder();
+
+ void setEncoding(const WTF::TextEncoding&, EncodingSource);
+ const WTF::TextEncoding& encoding() const { return m_encoding; }
+ bool encodingWasDetectedHeuristically() const
+ {
+ return m_source == AutoDetectedEncoding
+ || m_source == EncodingFromContentSniffing;
+ }
+
+ String decode(const char* data, size_t length);
+ String flush();
+
+ void setHintEncoding(const WTF::TextEncoding& encoding)
+ {
+ m_hintEncoding = encoding.name();
+ }
+
+ void useLenientXMLDecoding() { m_useLenientXMLDecoding = true; }
+ bool sawError() const { return m_sawError; }
+
+private:
+ TextResourceDecoder(const String& mimeType, const WTF::TextEncoding& defaultEncoding, bool usesEncodingDetector);
+
+ enum ContentType { PlainTextContent, HTMLContent, XMLContent, CSSContent }; // PlainText only checks for BOM.
+ static ContentType determineContentType(const String& mimeType);
+ static const WTF::TextEncoding& defaultEncoding(ContentType, const WTF::TextEncoding& defaultEncoding);
+
+ size_t checkForBOM(const char*, size_t);
+ bool checkForCSSCharset(const char*, size_t, bool& movedDataToBuffer);
+ bool checkForXMLCharset(const char*, size_t, bool& movedDataToBuffer);
+ void checkForMetaCharset(const char*, size_t);
+ void detectJapaneseEncoding(const char*, size_t);
+ bool shouldAutoDetect() const;
+
+ ContentType m_contentType;
+ WTF::TextEncoding m_encoding;
+ OwnPtr<TextCodec> m_codec;
+ EncodingSource m_source;
+ const char* m_hintEncoding;
+ Vector<char> m_buffer;
+ bool m_checkedForBOM;
+ bool m_checkedForCSSCharset;
+ bool m_checkedForXMLCharset;
+ bool m_checkedForMetaCharset;
+ bool m_useLenientXMLDecoding; // Don't stop on XML decoding errors.
+ bool m_sawError;
+ bool m_usesEncodingDetector;
+
+ OwnPtr<HTMLMetaCharsetParser> m_charsetParser;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
index a43fca982b5..5189447af88 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.cpp
@@ -27,22 +27,23 @@
#include "config.h"
#include "core/html/parser/XSSAuditor.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Document.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLParamElement.h"
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/parser/XSSAuditorDelegate.h"
#include "core/loader/DocumentLoader.h"
#include "core/frame/Settings.h"
#include "platform/JSONValues.h"
#include "platform/network/FormData.h"
#include "platform/text/DecodeEscapeSequences.h"
+#include "wtf/ASCIICType.h"
#include "wtf/MainThread.h"
namespace {
@@ -63,14 +64,11 @@ static bool isNonCanonicalCharacter(UChar c)
// Note, we don't remove backslashes like PHP stripslashes(), which among other things converts "\\0" to the \0 character.
// Instead, we remove backslashes and zeros (since the string "\\0" =(remove backslashes)=> "0"). However, this has the
// adverse effect that we remove any legitimate zeros from a string.
+ // We also remove forward-slash, because it is common for some servers to collapse successive path components, eg,
+ // a//b becomes a/b.
//
- // For instance: new String("http://localhost:8000") => new String("http://localhost:8").
- return (c == '\\' || c == '0' || c == '\0' || c >= 127);
-}
-
-static String canonicalize(const String& string)
-{
- return string.removeCharacters(&isNonCanonicalCharacter);
+ // For instance: new String("http://localhost:8000") => new String("http:localhost:8").
+ return (c == '\\' || c == '0' || c == '\0' || c == '/' || c >= 127);
}
static bool isRequiredForInjection(UChar c)
@@ -96,17 +94,28 @@ static bool isJSNewline(UChar c)
static bool startsHTMLCommentAt(const String& string, size_t start)
{
- return (start + 3 < string.length() && string[start] == '<' && string[start+1] == '!' && string[start+2] == '-' && string[start+3] == '-');
+ return (start + 3 < string.length() && string[start] == '<' && string[start + 1] == '!' && string[start + 2] == '-' && string[start + 3] == '-');
}
static bool startsSingleLineCommentAt(const String& string, size_t start)
{
- return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '/');
+ return (start + 1 < string.length() && string[start] == '/' && string[start + 1] == '/');
}
static bool startsMultiLineCommentAt(const String& string, size_t start)
{
- return (start + 1 < string.length() && string[start] == '/' && string[start+1] == '*');
+ return (start + 1 < string.length() && string[start] == '/' && string[start + 1] == '*');
+}
+
+static bool startsOpeningScriptTagAt(const String& string, size_t start)
+{
+ return start + 6 < string.length() && string[start] == '<'
+ && WTF::toASCIILowerUnchecked(string[start + 1]) == 's'
+ && WTF::toASCIILowerUnchecked(string[start + 2]) == 'c'
+ && WTF::toASCIILowerUnchecked(string[start + 3]) == 'r'
+ && WTF::toASCIILowerUnchecked(string[start + 4]) == 'i'
+ && WTF::toASCIILowerUnchecked(string[start + 5]) == 'p'
+ && WTF::toASCIILowerUnchecked(string[start + 6]) == 't';
}
// If other files need this, we should move this to core/html/parser/HTMLParserIdioms.h
@@ -171,10 +180,60 @@ static String fullyDecodeString(const String& string, const WTF::TextEncoding& e
workingString = decode16BitUnicodeEscapeSequences(decodeStandardURLEscapeSequences(workingString, encoding));
} while (workingString.length() < oldWorkingStringLength);
workingString.replace('+', ' ');
- workingString = canonicalize(workingString);
return workingString;
}
+static void truncateForSrcLikeAttribute(String& decodedSnippet)
+{
+ // In HTTP URLs, characters following the first ?, #, or third slash may come from
+ // the page itself and can be merely ignored by an attacker's server when a remote
+ // script or script-like resource is requested. In DATA URLS, the payload starts at
+ // the first comma, and the the first /*, //, or <!-- may introduce a comment. Characters
+ // following this may come from the page itself and may be ignored when the script is
+ // executed. For simplicity, we don't differentiate based on URL scheme, and stop at
+ // the first # or ?, the third slash, or the first slash or < once a comma is seen.
+ int slashCount = 0;
+ bool commaSeen = false;
+ for (size_t currentLength = 0; currentLength < decodedSnippet.length(); ++currentLength) {
+ UChar currentChar = decodedSnippet[currentLength];
+ if (currentChar == '?'
+ || currentChar == '#'
+ || ((currentChar == '/' || currentChar == '\\') && (commaSeen || ++slashCount > 2))
+ || (currentChar == '<' && commaSeen)) {
+ decodedSnippet.truncate(currentLength);
+ return;
+ }
+ if (currentChar == ',')
+ commaSeen = true;
+ }
+}
+
+static void truncateForScriptLikeAttribute(String& decodedSnippet)
+{
+ // Beware of trailing characters which came from the page itself, not the
+ // injected vector. Excluding the terminating character covers common cases
+ // where the page immediately ends the attribute, but doesn't cover more
+ // complex cases where there is other page data following the injection.
+ // Generally, these won't parse as javascript, so the injected vector
+ // typically excludes them from consideration via a single-line comment or
+ // by enclosing them in a string literal terminated later by the page's own
+ // closing punctuation. Since the snippet has not been parsed, the vector
+ // may also try to introduce these via entities. As a result, we'd like to
+ // stop before the first "//", the first <!--, the first entity, or the first
+ // quote not immediately following the first equals sign (taking whitespace
+ // into consideration). To keep things simpler, we don't try to distinguish
+ // between entity-introducing amperands vs. other uses, nor do we bother to
+ // check for a second slash for a comment, nor do we bother to check for
+ // !-- following a less-than sign. We stop instead on any ampersand
+ // slash, or less-than sign.
+ size_t position = 0;
+ if ((position = decodedSnippet.find("=")) != kNotFound
+ && (position = decodedSnippet.find(isNotHTMLSpace<UChar>, position + 1)) != kNotFound
+ && (position = decodedSnippet.find(isTerminatingCharacter, isHTMLQuote(decodedSnippet[position]) ? position + 1 : position)) != kNotFound) {
+ decodedSnippet.truncate(position);
+ }
+}
+
static ReflectedXSSDisposition combineXSSProtectionHeaderAndCSP(ReflectedXSSDisposition xssProtection, ReflectedXSSDisposition reflectedXSS)
{
ReflectedXSSDisposition result = std::max(xssProtection, reflectedXSS);
@@ -190,15 +249,16 @@ static bool isSemicolonSeparatedAttribute(const HTMLToken::Attribute& attribute)
return threadSafeMatch(attribute.name, SVGNames::valuesAttr);
}
-static bool semicolonSeparatedValueContainsJavaScriptURL(const String& value)
+static String semicolonSeparatedValueContainingJavaScriptURL(const String& value)
{
Vector<String> valueList;
value.split(';', valueList);
for (size_t i = 0; i < valueList.size(); ++i) {
- if (protocolIsJavaScript(valueList[i]))
- return true;
+ String stripped = stripLeadingAndTrailingHTMLSpaces(valueList[i]);
+ if (protocolIsJavaScript(stripped))
+ return stripped;
}
- return false;
+ return emptyString();
}
XSSAuditor::XSSAuditor()
@@ -227,9 +287,6 @@ void XSSAuditor::initForFragment()
void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
{
- const size_t miniumLengthForSuffixTree = 512; // FIXME: Tune this parameter.
- const int suffixTreeDepth = 5;
-
ASSERT(isMainThread());
if (m_state != Uninitialized)
return;
@@ -243,7 +300,7 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
m_documentURL = document->url().copy();
- // In theory, the Document could have detached from the Frame after the
+ // In theory, the Document could have detached from the LocalFrame after the
// XSSAuditor was constructed.
if (!document->frame()) {
m_isEnabled = false;
@@ -264,11 +321,6 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
if (document->encoding().isValid())
m_encoding = document->encoding();
- m_decodedURL = fullyDecodeString(m_documentURL.string(), m_encoding);
- if (m_decodedURL.find(isRequiredForInjection) == kNotFound)
- m_decodedURL = String();
-
- String httpBodyAsString;
if (DocumentLoader* documentLoader = document->frame()->loader().documentLoader()) {
DEFINE_STATIC_LOCAL(const AtomicString, XSSProtectionHeader, ("X-XSS-Protection", AtomicString::ConstructFromLiteral));
const AtomicString& headerValue = documentLoader->response().httpHeaderField(XSSProtectionHeader);
@@ -298,23 +350,40 @@ void XSSAuditor::init(Document* document, XSSAuditorDelegate* auditorDelegate)
// FIXME: Combine the two report URLs in some reasonable way.
if (auditorDelegate)
auditorDelegate->setReportURL(xssProtectionReportURL.copy());
+
FormData* httpBody = documentLoader->request().httpBody();
- if (httpBody && !httpBody->isEmpty()) {
- httpBodyAsString = httpBody->flattenToString();
- if (!httpBodyAsString.isEmpty()) {
- m_decodedHTTPBody = fullyDecodeString(httpBodyAsString, m_encoding);
- if (m_decodedHTTPBody.find(isRequiredForInjection) == kNotFound)
- m_decodedHTTPBody = String();
- if (m_decodedHTTPBody.length() >= miniumLengthForSuffixTree)
- m_decodedHTTPBodySuffixTree = adoptPtr(new SuffixTree<ASCIICodebook>(m_decodedHTTPBody, suffixTreeDepth));
- }
- }
+ if (httpBody && !httpBody->isEmpty())
+ m_httpBodyAsString = httpBody->flattenToString();
}
- if (m_decodedURL.isEmpty() && m_decodedHTTPBody.isEmpty()) {
- m_isEnabled = false;
+ setEncoding(m_encoding);
+}
+
+void XSSAuditor::setEncoding(const WTF::TextEncoding& encoding)
+{
+ const size_t miniumLengthForSuffixTree = 512; // FIXME: Tune this parameter.
+ const int suffixTreeDepth = 5;
+
+ if (!encoding.isValid())
return;
+
+ m_encoding = encoding;
+
+ m_decodedURL = canonicalize(m_documentURL.string(), NoTruncation);
+ if (m_decodedURL.find(isRequiredForInjection) == kNotFound)
+ m_decodedURL = String();
+
+ if (!m_httpBodyAsString.isEmpty()) {
+ m_decodedHTTPBody = canonicalize(m_httpBodyAsString, NoTruncation);
+ m_httpBodyAsString = String();
+ if (m_decodedHTTPBody.find(isRequiredForInjection) == kNotFound)
+ m_decodedHTTPBody = String();
+ if (m_decodedHTTPBody.length() >= miniumLengthForSuffixTree)
+ m_decodedHTTPBodySuffixTree = adoptPtr(new SuffixTree<ASCIICodebook>(m_decodedHTTPBody, suffixTreeDepth));
}
+
+ if (m_decodedURL.isEmpty() && m_decodedHTTPBody.isEmpty())
+ m_isEnabled = false;
}
PassOwnPtr<XSSInfo> XSSAuditor::filterToken(const FilterTokenRequest& request)
@@ -392,7 +461,7 @@ bool XSSAuditor::filterCharacterToken(const FilterTokenRequest& request)
return false;
if ((m_state == SuppressingAdjacentCharacterTokens)
- || (m_scriptTagFoundInRequest && isContainedInRequest(decodedSnippetForJavaScript(request)))) {
+ || (m_scriptTagFoundInRequest && isContainedInRequest(canonicalizedSnippetForJavaScript(request)))) {
request.token.eraseCharacters();
request.token.appendToCharacter(' '); // Technically, character tokens can't be empty.
m_state = SuppressingAdjacentCharacterTokens;
@@ -409,10 +478,10 @@ bool XSSAuditor::filterScriptToken(const FilterTokenRequest& request)
ASSERT(hasName(request.token, scriptTag));
bool didBlockScript = false;
- m_scriptTagFoundInRequest = isContainedInRequest(decodedSnippetForName(request));
+ m_scriptTagFoundInRequest = isContainedInRequest(canonicalizedSnippetForTagName(request));
if (m_scriptTagFoundInRequest) {
- didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttribute);
- didBlockScript |= eraseAttributeIfInjected(request, XLinkNames::hrefAttr, blankURL().string(), SrcLikeAttribute);
+ didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttributeTruncation);
+ didBlockScript |= eraseAttributeIfInjected(request, XLinkNames::hrefAttr, blankURL().string(), SrcLikeAttributeTruncation);
}
return didBlockScript;
}
@@ -423,8 +492,8 @@ bool XSSAuditor::filterObjectToken(const FilterTokenRequest& request)
ASSERT(hasName(request.token, objectTag));
bool didBlockScript = false;
- if (isContainedInRequest(decodedSnippetForName(request))) {
- didBlockScript |= eraseAttributeIfInjected(request, dataAttr, blankURL().string(), SrcLikeAttribute);
+ if (isContainedInRequest(canonicalizedSnippetForTagName(request))) {
+ didBlockScript |= eraseAttributeIfInjected(request, dataAttr, blankURL().string(), SrcLikeAttributeTruncation);
didBlockScript |= eraseAttributeIfInjected(request, typeAttr);
didBlockScript |= eraseAttributeIfInjected(request, classidAttr);
}
@@ -444,7 +513,7 @@ bool XSSAuditor::filterParamToken(const FilterTokenRequest& request)
if (!HTMLParamElement::isURLParameter(String(nameAttribute.value)))
return false;
- return eraseAttributeIfInjected(request, valueAttr, blankURL().string(), SrcLikeAttribute);
+ return eraseAttributeIfInjected(request, valueAttr, blankURL().string(), SrcLikeAttributeTruncation);
}
bool XSSAuditor::filterEmbedToken(const FilterTokenRequest& request)
@@ -453,9 +522,9 @@ bool XSSAuditor::filterEmbedToken(const FilterTokenRequest& request)
ASSERT(hasName(request.token, embedTag));
bool didBlockScript = false;
- if (isContainedInRequest(decodedSnippetForName(request))) {
- didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttribute);
- didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttribute);
+ if (isContainedInRequest(canonicalizedSnippetForTagName(request))) {
+ didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttributeTruncation);
+ didBlockScript |= eraseAttributeIfInjected(request, srcAttr, blankURL().string(), SrcLikeAttributeTruncation);
didBlockScript |= eraseAttributeIfInjected(request, typeAttr);
}
return didBlockScript;
@@ -467,8 +536,8 @@ bool XSSAuditor::filterAppletToken(const FilterTokenRequest& request)
ASSERT(hasName(request.token, appletTag));
bool didBlockScript = false;
- if (isContainedInRequest(decodedSnippetForName(request))) {
- didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttribute);
+ if (isContainedInRequest(canonicalizedSnippetForTagName(request))) {
+ didBlockScript |= eraseAttributeIfInjected(request, codeAttr, String(), SrcLikeAttributeTruncation);
didBlockScript |= eraseAttributeIfInjected(request, objectAttr);
}
return didBlockScript;
@@ -479,9 +548,9 @@ bool XSSAuditor::filterFrameToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, iframeTag) || hasName(request.token, frameTag));
- bool didBlockScript = eraseAttributeIfInjected(request, srcdocAttr, String(), ScriptLikeAttribute);
- if (isContainedInRequest(decodedSnippetForName(request)))
- didBlockScript |= eraseAttributeIfInjected(request, srcAttr, String(), SrcLikeAttribute);
+ bool didBlockScript = eraseAttributeIfInjected(request, srcdocAttr, String(), ScriptLikeAttributeTruncation);
+ if (isContainedInRequest(canonicalizedSnippetForTagName(request)))
+ didBlockScript |= eraseAttributeIfInjected(request, srcAttr, String(), SrcLikeAttributeTruncation);
return didBlockScript;
}
@@ -515,7 +584,7 @@ bool XSSAuditor::filterInputToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, inputTag));
- return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttribute);
+ return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttributeTruncation);
}
bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request)
@@ -523,7 +592,7 @@ bool XSSAuditor::filterButtonToken(const FilterTokenRequest& request)
ASSERT(request.token.type() == HTMLToken::StartTag);
ASSERT(hasName(request.token, buttonTag));
- return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttribute);
+ return eraseAttributeIfInjected(request, formactionAttr, kURLWithUniqueOrigin, SrcLikeAttributeTruncation);
}
bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& request)
@@ -532,14 +601,24 @@ bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& re
bool didBlockScript = false;
for (size_t i = 0; i < request.token.attributes().size(); ++i) {
+ bool eraseAttribute = false;
+ bool valueContainsJavaScriptURL = false;
const HTMLToken::Attribute& attribute = request.token.attributes().at(i);
- bool isInlineEventHandler = isNameOfInlineEventHandler(attribute.name);
- // FIXME: It would be better if we didn't create a new String for every attribute in the document.
- String strippedValue = stripLeadingAndTrailingHTMLSpaces(String(attribute.value));
- bool valueContainsJavaScriptURL = (!isInlineEventHandler && protocolIsJavaScript(strippedValue)) || (isSemicolonSeparatedAttribute(attribute) && semicolonSeparatedValueContainsJavaScriptURL(strippedValue));
- if (!isInlineEventHandler && !valueContainsJavaScriptURL)
- continue;
- if (!isContainedInRequest(decodedSnippetForAttribute(request, attribute, ScriptLikeAttribute)))
+ // FIXME: Don't create a new String for every attribute.value in the document.
+ if (isNameOfInlineEventHandler(attribute.name)) {
+ eraseAttribute = isContainedInRequest(canonicalize(snippetFromAttribute(request, attribute), ScriptLikeAttributeTruncation));
+ } else if (isSemicolonSeparatedAttribute(attribute)) {
+ String subValue = semicolonSeparatedValueContainingJavaScriptURL(String(attribute.value));
+ if (!subValue.isEmpty()) {
+ valueContainsJavaScriptURL = true;
+ eraseAttribute = isContainedInRequest(canonicalize(nameFromAttribute(request, attribute), NoTruncation))
+ && isContainedInRequest(canonicalize(subValue, ScriptLikeAttributeTruncation));
+ }
+ } else if (protocolIsJavaScript(stripLeadingAndTrailingHTMLSpaces(String(attribute.value)))) {
+ valueContainsJavaScriptURL = true;
+ eraseAttribute = isContainedInRequest(canonicalize(snippetFromAttribute(request, attribute), ScriptLikeAttributeTruncation));
+ }
+ if (!eraseAttribute)
continue;
request.token.eraseValueOfAttribute(i);
if (valueContainsJavaScriptURL)
@@ -549,96 +628,79 @@ bool XSSAuditor::eraseDangerousAttributesIfInjected(const FilterTokenRequest& re
return didBlockScript;
}
-bool XSSAuditor::eraseAttributeIfInjected(const FilterTokenRequest& request, const QualifiedName& attributeName, const String& replacementValue, AttributeKind treatment)
+bool XSSAuditor::eraseAttributeIfInjected(const FilterTokenRequest& request, const QualifiedName& attributeName, const String& replacementValue, TruncationKind treatment)
{
size_t indexOfAttribute = 0;
- if (findAttributeWithName(request.token, attributeName, indexOfAttribute)) {
- const HTMLToken::Attribute& attribute = request.token.attributes().at(indexOfAttribute);
- if (isContainedInRequest(decodedSnippetForAttribute(request, attribute, treatment))) {
- if (threadSafeMatch(attributeName, srcAttr) && isLikelySafeResource(String(attribute.value)))
- return false;
- if (threadSafeMatch(attributeName, http_equivAttr) && !isDangerousHTTPEquiv(String(attribute.value)))
- return false;
- request.token.eraseValueOfAttribute(indexOfAttribute);
- if (!replacementValue.isEmpty())
- request.token.appendToAttributeValue(indexOfAttribute, replacementValue);
- return true;
- }
+ if (!findAttributeWithName(request.token, attributeName, indexOfAttribute))
+ return false;
+
+ const HTMLToken::Attribute& attribute = request.token.attributes().at(indexOfAttribute);
+ if (!isContainedInRequest(canonicalize(snippetFromAttribute(request, attribute), treatment)))
+ return false;
+
+ if (threadSafeMatch(attributeName, srcAttr)) {
+ if (isLikelySafeResource(String(attribute.value)))
+ return false;
+ } else if (threadSafeMatch(attributeName, http_equivAttr)) {
+ if (!isDangerousHTTPEquiv(String(attribute.value)))
+ return false;
}
- return false;
+
+ request.token.eraseValueOfAttribute(indexOfAttribute);
+ if (!replacementValue.isEmpty())
+ request.token.appendToAttributeValue(indexOfAttribute, replacementValue);
+
+ return true;
}
-String XSSAuditor::decodedSnippetForName(const FilterTokenRequest& request)
+String XSSAuditor::canonicalizedSnippetForTagName(const FilterTokenRequest& request)
{
// Grab a fixed number of characters equal to the length of the token's name plus one (to account for the "<").
- return fullyDecodeString(request.sourceTracker.sourceForToken(request.token), m_encoding).substring(0, request.token.name().size() + 1);
+ return canonicalize(request.sourceTracker.sourceForToken(request.token).substring(0, request.token.name().size() + 1), NoTruncation);
+}
+
+String XSSAuditor::nameFromAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute)
+{
+ // The range inlcudes the character which terminates the name. So,
+ // for an input of |name="value"|, the snippet is |name=|.
+ int start = attribute.nameRange.start - request.token.startIndex();
+ int end = attribute.valueRange.start - request.token.startIndex();
+ return request.sourceTracker.sourceForToken(request.token).substring(start, end - start);
}
-String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute, AttributeKind treatment)
+String XSSAuditor::snippetFromAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute)
{
- // The range doesn't inlcude the character which terminates the value. So,
+ // The range doesn't include the character which terminates the value. So,
// for an input of |name="value"|, the snippet is |name="value|. For an
// unquoted input of |name=value |, the snippet is |name=value|.
// FIXME: We should grab one character before the name also.
int start = attribute.nameRange.start - request.token.startIndex();
int end = attribute.valueRange.end - request.token.startIndex();
- String decodedSnippet = fullyDecodeString(request.sourceTracker.sourceForToken(request.token).substring(start, end - start), m_encoding);
- decodedSnippet.truncate(kMaximumFragmentLengthTarget);
- if (treatment == SrcLikeAttribute) {
- int slashCount = 0;
- bool commaSeen = false;
- // In HTTP URLs, characters following the first ?, #, or third slash may come from
- // the page itself and can be merely ignored by an attacker's server when a remote
- // script or script-like resource is requested. In DATA URLS, the payload starts at
- // the first comma, and the the first /*, //, or <!-- may introduce a comment. Characters
- // following this may come from the page itself and may be ignored when the script is
- // executed. For simplicity, we don't differentiate based on URL scheme, and stop at
- // the first # or ?, the third slash, or the first slash or < once a comma is seen.
- for (size_t currentLength = 0; currentLength < decodedSnippet.length(); ++currentLength) {
- UChar currentChar = decodedSnippet[currentLength];
- if (currentChar == '?'
- || currentChar == '#'
- || ((currentChar == '/' || currentChar == '\\') && (commaSeen || ++slashCount > 2))
- || (currentChar == '<' && commaSeen)) {
- decodedSnippet.truncate(currentLength);
- break;
- }
- if (currentChar == ',')
- commaSeen = true;
- }
- } else if (treatment == ScriptLikeAttribute) {
- // Beware of trailing characters which came from the page itself, not the
- // injected vector. Excluding the terminating character covers common cases
- // where the page immediately ends the attribute, but doesn't cover more
- // complex cases where there is other page data following the injection.
- // Generally, these won't parse as javascript, so the injected vector
- // typically excludes them from consideration via a single-line comment or
- // by enclosing them in a string literal terminated later by the page's own
- // closing punctuation. Since the snippet has not been parsed, the vector
- // may also try to introduce these via entities. As a result, we'd like to
- // stop before the first "//", the first <!--, the first entity, or the first
- // quote not immediately following the first equals sign (taking whitespace
- // into consideration). To keep things simpler, we don't try to distinguish
- // between entity-introducing amperands vs. other uses, nor do we bother to
- // check for a second slash for a comment, nor do we bother to check for
- // !-- following a less-than sign. We stop instead on any ampersand
- // slash, or less-than sign.
- size_t position = 0;
- if ((position = decodedSnippet.find("=")) != kNotFound
- && (position = decodedSnippet.find(isNotHTMLSpace<UChar>, position + 1)) != kNotFound
- && (position = decodedSnippet.find(isTerminatingCharacter, isHTMLQuote(decodedSnippet[position]) ? position + 1 : position)) != kNotFound) {
- decodedSnippet.truncate(position);
- }
+ return request.sourceTracker.sourceForToken(request.token).substring(start, end - start);
+}
+
+String XSSAuditor::canonicalize(String snippet, TruncationKind treatment)
+{
+ String decodedSnippet = fullyDecodeString(snippet, m_encoding);
+
+ if (treatment != NoTruncation) {
+ decodedSnippet.truncate(kMaximumFragmentLengthTarget);
+ if (treatment == SrcLikeAttributeTruncation)
+ truncateForSrcLikeAttribute(decodedSnippet);
+ else if (treatment == ScriptLikeAttributeTruncation)
+ truncateForScriptLikeAttribute(decodedSnippet);
}
- return decodedSnippet;
+
+ return decodedSnippet.removeCharacters(&isNonCanonicalCharacter);
}
-String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request)
+String XSSAuditor::canonicalizedSnippetForJavaScript(const FilterTokenRequest& request)
{
String string = request.sourceTracker.sourceForToken(request.token);
size_t startPosition = 0;
size_t endPosition = string.length();
size_t foundPosition = kNotFound;
+ size_t lastNonSpacePosition = kNotFound;
// Skip over initial comments to find start of code.
while (startPosition < endPosition) {
@@ -667,32 +729,40 @@ String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request
String result;
while (startPosition < endPosition && !result.length()) {
- // Stop at next comment (using the same rules as above for SVG/XML vs HTML), when we
- // encounter a comma, or when we exceed the maximum length target. The comma rule
- // covers a common parameter concatenation case performed by some webservers.
- // After hitting the length target, we can only stop at a point where we know we are
- // not in the middle of a %-escape sequence. For the sake of simplicity, approximate
- // not stopping inside a (possibly multiply encoded) %-esacpe sequence by breaking on
- // whitespace only. We should have enough text in these cases to avoid false positives.
+ // Stop at next comment (using the same rules as above for SVG/XML vs HTML), when we encounter a comma,
+ // when we hit an opening <script> tag, or when we exceed the maximum length target. The comma rule
+ // covers a common parameter concatenation case performed by some web servers.
+ lastNonSpacePosition = kNotFound;
for (foundPosition = startPosition; foundPosition < endPosition; foundPosition++) {
if (!request.shouldAllowCDATA) {
- if (startsSingleLineCommentAt(string, foundPosition) || startsMultiLineCommentAt(string, foundPosition)) {
- foundPosition += 2;
- break;
- }
- if (startsHTMLCommentAt(string, foundPosition)) {
- foundPosition += 4;
+ if (startsSingleLineCommentAt(string, foundPosition)
+ || startsMultiLineCommentAt(string, foundPosition)
+ || startsHTMLCommentAt(string, foundPosition)) {
break;
}
}
- if (string[foundPosition] == ',' || (foundPosition > startPosition + kMaximumFragmentLengthTarget && isHTMLSpace<UChar>(string[foundPosition]))) {
+ if (string[foundPosition] == ',')
+ break;
+
+ if (lastNonSpacePosition != kNotFound && startsOpeningScriptTagAt(string, foundPosition)) {
+ foundPosition = lastNonSpacePosition;
break;
}
+ if (foundPosition > startPosition + kMaximumFragmentLengthTarget) {
+ // After hitting the length target, we can only stop at a point where we know we are
+ // not in the middle of a %-escape sequence. For the sake of simplicity, approximate
+ // not stopping inside a (possibly multiply encoded) %-escape sequence by breaking on
+ // whitespace only. We should have enough text in these cases to avoid false positives.
+ if (isHTMLSpace<UChar>(string[foundPosition]))
+ break;
+ }
+ if (!isHTMLSpace<UChar>(string[foundPosition]))
+ lastNonSpacePosition = foundPosition;
}
-
- result = fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), m_encoding);
+ result = canonicalize(string.substring(startPosition, foundPosition - startPosition), NoTruncation);
startPosition = foundPosition + 1;
}
+
return result;
}
@@ -732,7 +802,8 @@ bool XSSAuditor::isSafeToSendToAnotherThread() const
{
return m_documentURL.isSafeToSendToAnotherThread()
&& m_decodedURL.isSafeToSendToAnotherThread()
- && m_decodedHTTPBody.isSafeToSendToAnotherThread();
+ && m_decodedHTTPBody.isSafeToSendToAnotherThread()
+ && m_httpBodyAsString.isSafeToSendToAnotherThread();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
index db2655f4a8a..53a38ac606d 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditor.h
@@ -64,6 +64,8 @@ public:
PassOwnPtr<XSSInfo> filterToken(const FilterTokenRequest&);
bool isSafeToSendToAnotherThread() const;
+ void setEncoding(const WTF::TextEncoding&);
+
private:
static const size_t kMaximumFragmentLengthTarget = 100;
@@ -74,10 +76,11 @@ private:
SuppressingAdjacentCharacterTokens
};
- enum AttributeKind {
- NormalAttribute,
- SrcLikeAttribute,
- ScriptLikeAttribute
+ enum TruncationKind {
+ NoTruncation,
+ NormalAttributeTruncation,
+ SrcLikeAttributeTruncation,
+ ScriptLikeAttributeTruncation
};
bool filterStartToken(const FilterTokenRequest&);
@@ -96,12 +99,13 @@ private:
bool filterButtonToken(const FilterTokenRequest&);
bool eraseDangerousAttributesIfInjected(const FilterTokenRequest&);
- bool eraseAttributeIfInjected(const FilterTokenRequest&, const QualifiedName&, const String& replacementValue = String(), AttributeKind treatment = NormalAttribute);
+ bool eraseAttributeIfInjected(const FilterTokenRequest&, const QualifiedName&, const String& replacementValue = String(), TruncationKind treatment = NormalAttributeTruncation);
- String decodedSnippetForToken(const HTMLToken&);
- String decodedSnippetForName(const FilterTokenRequest&);
- String decodedSnippetForAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&, AttributeKind treatment = NormalAttribute);
- String decodedSnippetForJavaScript(const FilterTokenRequest&);
+ String canonicalizedSnippetForTagName(const FilterTokenRequest&);
+ String canonicalizedSnippetForJavaScript(const FilterTokenRequest&);
+ String nameFromAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&);
+ String snippetFromAttribute(const FilterTokenRequest&, const HTMLToken::Attribute&);
+ String canonicalize(String, TruncationKind);
bool isContainedInRequest(const String&);
bool isLikelySafeResource(const String& url);
@@ -115,6 +119,7 @@ private:
String m_decodedURL;
String m_decodedHTTPBody;
+ String m_httpBodyAsString;
OwnPtr<SuffixTree<ASCIICodebook> > m_decodedHTTPBodySuffixTree;
State m_state;
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
index 5ea9b66ccf7..9b329e85ccd 100644
--- a/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/parser/XSSAuditorDelegate.cpp
@@ -27,7 +27,7 @@
#include "core/html/parser/XSSAuditorDelegate.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
@@ -100,8 +100,8 @@ void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, xssInfo.buildConsoleError());
- // stopAllLoaders can detach the Frame, so protect it.
- RefPtr<Frame> protect(m_document->frame());
+ // stopAllLoaders can detach the LocalFrame, so protect it.
+ RefPtr<LocalFrame> protect(m_document->frame());
FrameLoader& frameLoader = m_document->frame()->loader();
if (xssInfo.m_didBlockEntirePage)
frameLoader.stopAllLoaders();
@@ -116,7 +116,7 @@ void XSSAuditorDelegate::didBlockScript(const XSSInfo& xssInfo)
}
if (xssInfo.m_didBlockEntirePage)
- m_document->frame()->navigationScheduler().scheduleLocationChange(m_document, SecurityOrigin::urlWithUniqueSecurityOrigin(), String());
+ m_document->frame()->navigationScheduler().scheduleLocationChange(m_document, SecurityOrigin::urlWithUniqueSecurityOrigin(), Referrer());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table b/chromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table
index 8c408fead9a..587e8a8f5d1 100755
--- a/chromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table
+++ b/chromium/third_party/WebKit/Source/core/html/parser/create-html-entity-table
@@ -27,6 +27,11 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+"""This python script creates the raw data that is our entity
+database. The representation is one string database containing all
+strings we could need, and then a mapping from offset+length -> entity
+data. That is compact, easy to use and efficient."""
+
import csv
import os.path
import string
@@ -35,17 +40,6 @@ import sys
ENTITY = 0
VALUE = 1
-def convert_entity_to_cpp_name(entity):
- postfix = "EntityName"
- if entity[-1] == ";":
- return "%sSemicolon%s" % (entity[:-1], postfix)
- return "%s%s" % (entity, postfix)
-
-
-def convert_entity_to_uchar_array(entity):
- return "{'%s'}" % "', '".join(entity)
-
-
def convert_value_to_int(value):
if not value:
return "0";
@@ -67,9 +61,8 @@ if len(sys.argv) < 4 or sys.argv[1] != "-o":
output_path = sys.argv[2]
input_path = sys.argv[3]
-html_entity_names_file = open(input_path)
-entries = list(csv.reader(html_entity_names_file))
-html_entity_names_file.close()
+with open(input_path) as html_entity_names_file:
+ entries = list(csv.reader(html_entity_names_file))
entries.sort(key = lambda entry: entry[ENTITY])
entity_count = len(entries)
@@ -101,7 +94,7 @@ output_file.write("""/*
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-// THIS FILE IS GENERATED BY WebCore/html/parser/create-html-entity-table
+// THIS FILE IS GENERATED BY core/html/parser/create-html-entity-table
// DO NOT EDIT (unless you are a ninja)!
#include "config.h"
@@ -112,62 +105,126 @@ namespace WebCore {
namespace {
""")
+assert len(entries) > 0, "Code assumes a non-empty entity array."
+def check_ascii(entity_string):
+ for c in entity_string:
+ code = ord(c)
+ assert 0 <= code <= 127, (c + " is not ASCII. Need to change type " +
+ "of storage from LChar to UChar to support " +
+ "this entity.")
+
+output_file.write("static const LChar staticEntityStringStorage[] = {\n")
+output_file.write("'")
+all_data = ""
+entity_offset = 0
+first_output = True
+saved_by_reusing = 0
for entry in entries:
- output_file.write("static const UChar %s[] = %s;\n" % (
- convert_entity_to_cpp_name(entry[ENTITY]),
- convert_entity_to_uchar_array(entry[ENTITY])))
+ check_ascii(entry[ENTITY])
+ # Reuse substrings from earlier entries. This saves 1-2000
+ # characters, but it's O(n^2) and not very smart. The optimal
+ # solution has to solve the "Shortest Common Superstring" problem
+ # and that is NP-Complete or worse.
+ #
+ # This would be even more efficient if we didn't store the
+ # semi-colon in the array but as a bit in the entry.
+ entity = entry[ENTITY]
+ already_existing_offset = all_data.find(entity)
+ if already_existing_offset != -1:
+ # Reusing space.
+ this_offset = already_existing_offset
+ saved_by_reusing += len(entity)
+ else:
+ if not first_output:
+ output_file.write(",\n'")
+ first_output = False
+
+ # Try the end of the string and see if we can reuse that to
+ # fit the start of the new entity.
+ data_to_add = entity
+ this_offset = entity_offset
+ for truncated_len in range(len(entity) - 1, 0, -1):
+ if all_data.endswith(entity[:truncated_len]):
+ data_to_add = entity[truncated_len:]
+ this_offset = entity_offset - truncated_len
+ saved_by_reusing += truncated_len
+ break
+
+ output_file.write("', '".join(data_to_add))
+ all_data += data_to_add
+ output_file.write("'")
+ entity_offset += len(data_to_add)
+ assert len(entry) == 2, "We will use slot [2] in the list for the offset."
+ assert this_offset < 32768 # Stored in a 16 bit short.
+ entry.append(this_offset)
+
+output_file.write("};\n")
+
+index = {}
+for offset, entry in enumerate(entries):
+ starting_letter = entry[ENTITY][0]
+ if starting_letter not in index:
+ index[starting_letter] = offset
output_file.write("""
static const HTMLEntityTableEntry staticEntityTable[%s] = {\n""" % entity_count)
-index = {}
-offset = 0
for entry in entries:
- letter = entry[ENTITY][0]
- if letter not in index:
- index[letter] = offset
values = entry[VALUE].split(' ')
assert len(values) <= 2, values
- output_file.write(' { %s, %s, %s, %s },\n' % (
- convert_entity_to_cpp_name(entry[ENTITY]),
- len(entry[ENTITY]),
+ output_file.write(' { %s, %s, %s, %s }, // &%s\n' % (
convert_value_to_int(values[0]),
- convert_value_to_int(values[1] if len(values) >= 2 else "")))
- offset += 1
+ convert_value_to_int(values[1] if len(values) >= 2 else ""),
+ entry[2],
+ len(entry[ENTITY]),
+ entry[ENTITY],
+ ))
output_file.write("""};
""")
-output_file.write("static const HTMLEntityTableEntry* uppercaseOffset[] = {\n")
+output_file.write("""
+}
+""")
+
+output_file.write("static const short uppercaseOffset[] = {\n")
for letter in string.ascii_uppercase:
- output_file.write("%s\n" % offset_table_entry(index[letter]))
-output_file.write("%s\n" % offset_table_entry(index['a']))
+ output_file.write("%d,\n" % index[letter])
+output_file.write("%d\n" % index['a'])
output_file.write("""};
-static const HTMLEntityTableEntry* lowercaseOffset[] = {\n""")
+static const short lowercaseOffset[] = {\n""")
for letter in string.ascii_lowercase:
- output_file.write("%s\n" % offset_table_entry(index[letter]))
-output_file.write("%s\n" % offset_table_entry(entity_count))
+ output_file.write("%d,\n" % index[letter])
+output_file.write("%d\n" % entity_count)
output_file.write("""};
+const LChar* HTMLEntityTable::entityString(const HTMLEntityTableEntry& entry)
+{
+ return staticEntityStringStorage + entry.entityOffset;
+}
+
+LChar HTMLEntityTableEntry::lastCharacter() const
+{
+ return HTMLEntityTable::entityString(*this)[length - 1];
}
const HTMLEntityTableEntry* HTMLEntityTable::firstEntryStartingWith(UChar c)
{
if (c >= 'A' && c <= 'Z')
- return uppercaseOffset[c - 'A'];
+ return &staticEntityTable[uppercaseOffset[c - 'A']];
if (c >= 'a' && c <= 'z')
- return lowercaseOffset[c - 'a'];
+ return &staticEntityTable[lowercaseOffset[c - 'a']];
return 0;
}
const HTMLEntityTableEntry* HTMLEntityTable::lastEntryStartingWith(UChar c)
{
if (c >= 'A' && c <= 'Z')
- return uppercaseOffset[c - 'A' + 1] - 1;
+ return &staticEntityTable[uppercaseOffset[c - 'A' + 1]] - 1;
if (c >= 'a' && c <= 'z')
- return lowercaseOffset[c - 'a' + 1] - 1;
+ return &staticEntityTable[lowercaseOffset[c - 'a' + 1]] - 1;
return 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp
index cb928e81dce..adbd8f8adde 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.cpp
@@ -27,9 +27,9 @@
#include "core/html/shadow/ClearButtonElement.h"
#include "core/events/MouseEvent.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderView.h"
namespace WebCore {
@@ -43,10 +43,10 @@ inline ClearButtonElement::ClearButtonElement(Document& document, ClearButtonOwn
{
}
-PassRefPtr<ClearButtonElement> ClearButtonElement::create(Document& document, ClearButtonOwner& clearButtonOwner)
+PassRefPtrWillBeRawPtr<ClearButtonElement> ClearButtonElement::create(Document& document, ClearButtonOwner& clearButtonOwner)
{
- RefPtr<ClearButtonElement> element = adoptRef(new ClearButtonElement(document, clearButtonOwner));
- element->setPseudo(AtomicString("-webkit-clear-button", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<ClearButtonElement> element = adoptRefWillBeNoop(new ClearButtonElement(document, clearButtonOwner));
+ element->setShadowPseudoId(AtomicString("-webkit-clear-button", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::clearButton());
return element.release();
}
@@ -54,8 +54,8 @@ PassRefPtr<ClearButtonElement> ClearButtonElement::create(Document& document, Cl
void ClearButtonElement::detach(const AttachContext& context)
{
if (m_capturing) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
}
HTMLDivElement::detach(context);
}
@@ -65,8 +65,8 @@ void ClearButtonElement::releaseCapture()
if (!m_capturing)
return;
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_capturing = false;
}
}
@@ -87,7 +87,7 @@ void ClearButtonElement::defaultEventHandler(Event* event)
if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
if (renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
frame->eventHandler().setCapturingMouseEventsNode(this);
m_capturing = true;
}
@@ -97,8 +97,8 @@ void ClearButtonElement::defaultEventHandler(Event* event)
}
if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
if (m_capturing) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_capturing = false;
}
if (hovered()) {
@@ -117,4 +117,10 @@ bool ClearButtonElement::isClearButtonElement() const
return true;
}
+void ClearButtonElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_clearButtonOwner);
+ HTMLDivElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h
index 47c91115e31..eba5309fa30 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ClearButtonElement.h
@@ -33,7 +33,7 @@ namespace WebCore {
class ClearButtonElement FINAL : public HTMLDivElement {
public:
- class ClearButtonOwner {
+ class ClearButtonOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~ClearButtonOwner() { }
virtual void focusAndSelectClearButtonOwner() = 0;
@@ -41,18 +41,20 @@ public:
virtual void clearValue() = 0;
};
- static PassRefPtr<ClearButtonElement> create(Document&, ClearButtonOwner&);
+ static PassRefPtrWillBeRawPtr<ClearButtonElement> create(Document&, ClearButtonOwner&);
void releaseCapture();
- void removeClearButtonOwner() { m_clearButtonOwner = 0; }
+ void removeClearButtonOwner() { m_clearButtonOwner = nullptr; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
ClearButtonElement(Document&, ClearButtonOwner&);
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool isMouseFocusable() const { return false; }
- virtual void defaultEventHandler(Event*);
+ virtual bool isMouseFocusable() const OVERRIDE { return false; }
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool isClearButtonElement() const OVERRIDE;
- ClearButtonOwner* m_clearButtonOwner;
+ RawPtrWillBeMember<ClearButtonOwner> m_clearButtonOwner;
bool m_capturing;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp
index eb3508e9dc8..3b337ddf0f1 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp
@@ -27,8 +27,9 @@
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "core/html/shadow/DateTimeEditElement.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/events/MouseEvent.h"
#include "core/html/forms/DateTimeFieldsState.h"
@@ -147,7 +148,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
switch (fieldType) {
case DateTimeFormat::FieldTypeDayOfMonth: {
- RefPtr<DateTimeFieldElement> field = DateTimeDayFieldElement::create(document, m_editElement, m_parameters.placeholderForDay, m_dayRange);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeDayFieldElement::create(document, m_editElement, m_parameters.placeholderForDay, m_dayRange);
m_editElement.addField(field);
if (shouldDayOfMonthFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -158,7 +159,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeHour11: {
DateTimeNumericFieldElement::Step step = createStep(msPerHour, msPerHour * 12);
- RefPtr<DateTimeFieldElement> field = DateTimeHour11FieldElement::create(document, m_editElement, m_hour23Range, step);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeHour11FieldElement::create(document, m_editElement, m_hour23Range, step);
m_editElement.addField(field);
if (shouldHourFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -169,7 +170,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeHour12: {
DateTimeNumericFieldElement::Step step = createStep(msPerHour, msPerHour * 12);
- RefPtr<DateTimeFieldElement> field = DateTimeHour12FieldElement::create(document, m_editElement, m_hour23Range, step);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeHour12FieldElement::create(document, m_editElement, m_hour23Range, step);
m_editElement.addField(field);
if (shouldHourFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -180,7 +181,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeHour23: {
DateTimeNumericFieldElement::Step step = createStep(msPerHour, msPerDay);
- RefPtr<DateTimeFieldElement> field = DateTimeHour23FieldElement::create(document, m_editElement, m_hour23Range, step);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeHour23FieldElement::create(document, m_editElement, m_hour23Range, step);
m_editElement.addField(field);
if (shouldHourFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -191,7 +192,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeHour24: {
DateTimeNumericFieldElement::Step step = createStep(msPerHour, msPerDay);
- RefPtr<DateTimeFieldElement> field = DateTimeHour24FieldElement::create(document, m_editElement, m_hour23Range, step);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeHour24FieldElement::create(document, m_editElement, m_hour23Range, step);
m_editElement.addField(field);
if (shouldHourFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -202,7 +203,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeMinute: {
DateTimeNumericFieldElement::Step step = createStep(msPerMinute, msPerHour);
- RefPtr<DateTimeNumericFieldElement> field = DateTimeMinuteFieldElement::create(document, m_editElement, m_minuteRange, step);
+ RefPtrWillBeRawPtr<DateTimeNumericFieldElement> field = DateTimeMinuteFieldElement::create(document, m_editElement, m_minuteRange, step);
m_editElement.addField(field);
if (shouldMinuteFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -221,7 +222,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
minMonth = m_parameters.minimum.month();
maxMonth = m_parameters.maximum.month();
}
- RefPtr<DateTimeFieldElement> field;
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field;
switch (count) {
case countForNarrowMonth: // Fallthrough.
case countForAbbreviatedMonth:
@@ -243,7 +244,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
}
case DateTimeFormat::FieldTypePeriod: {
- RefPtr<DateTimeFieldElement> field = DateTimeAMPMFieldElement::create(document, m_editElement, m_parameters.locale.timeAMPMLabels());
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeAMPMFieldElement::create(document, m_editElement, m_parameters.locale.timeAMPMLabels());
m_editElement.addField(field);
if (shouldAMPMFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -254,7 +255,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeSecond: {
DateTimeNumericFieldElement::Step step = createStep(msPerSecond, msPerMinute);
- RefPtr<DateTimeNumericFieldElement> field = DateTimeSecondFieldElement::create(document, m_editElement, m_secondRange, step);
+ RefPtrWillBeRawPtr<DateTimeNumericFieldElement> field = DateTimeSecondFieldElement::create(document, m_editElement, m_secondRange, step);
m_editElement.addField(field);
if (shouldSecondFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -270,7 +271,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
case DateTimeFormat::FieldTypeFractionalSecond: {
DateTimeNumericFieldElement::Step step = createStep(1, msPerSecond);
- RefPtr<DateTimeNumericFieldElement> field = DateTimeMillisecondFieldElement::create(document, m_editElement, m_millisecondRange, step);
+ RefPtrWillBeRawPtr<DateTimeNumericFieldElement> field = DateTimeMillisecondFieldElement::create(document, m_editElement, m_millisecondRange, step);
m_editElement.addField(field);
if (shouldMillisecondFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -313,7 +314,7 @@ void DateTimeEditBuilder::visitField(DateTimeFormat::FieldType fieldType, int co
std::swap(yearParams.minIsSpecified, yearParams.maxIsSpecified);
}
yearParams.placeholder = m_parameters.placeholderForYear;
- RefPtr<DateTimeFieldElement> field = DateTimeYearFieldElement::create(document, m_editElement, yearParams);
+ RefPtrWillBeRawPtr<DateTimeFieldElement> field = DateTimeYearFieldElement::create(document, m_editElement, yearParams);
m_editElement.addField(field);
if (shouldYearFieldDisabled()) {
field->setValueAsDate(m_dateValue);
@@ -401,8 +402,8 @@ void DateTimeEditBuilder::visitLiteral(const String& text)
{
DEFINE_STATIC_LOCAL(AtomicString, textPseudoId, ("-webkit-datetime-edit-text", AtomicString::ConstructFromLiteral));
ASSERT(text.length());
- RefPtr<HTMLDivElement> element = HTMLDivElement::create(m_editElement.document());
- element->setPseudo(textPseudoId);
+ RefPtrWillBeRawPtr<HTMLDivElement> element = HTMLDivElement::create(m_editElement.document());
+ element->setShadowPseudoId(textPseudoId);
if (m_parameters.locale.isRTL() && text.length()) {
Direction dir = direction(text[0]);
if (dir == SegmentSeparator || dir == WhiteSpaceNeutral || dir == OtherNeutral)
@@ -448,8 +449,19 @@ DateTimeEditElement::DateTimeEditElement(Document& document, EditControlOwner& e
DateTimeEditElement::~DateTimeEditElement()
{
+#if !ENABLE(OILPAN)
for (size_t fieldIndex = 0; fieldIndex < m_fields.size(); ++fieldIndex)
m_fields[fieldIndex]->removeEventHandler();
+#endif
+}
+
+void DateTimeEditElement::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_fields);
+#endif
+ visitor->trace(m_editControlOwner);
+ HTMLDivElement::trace(visitor);
}
inline Element* DateTimeEditElement::fieldsWrapperElement() const
@@ -458,7 +470,7 @@ inline Element* DateTimeEditElement::fieldsWrapperElement() const
return toElement(firstChild());
}
-void DateTimeEditElement::addField(PassRefPtr<DateTimeFieldElement> field)
+void DateTimeEditElement::addField(PassRefPtrWillBeRawPtr<DateTimeFieldElement> field)
{
if (m_fields.size() == m_fields.capacity())
return;
@@ -481,10 +493,10 @@ void DateTimeEditElement::blurByOwner()
field->blur();
}
-PassRefPtr<DateTimeEditElement> DateTimeEditElement::create(Document& document, EditControlOwner& editControlOwner)
+PassRefPtrWillBeRawPtr<DateTimeEditElement> DateTimeEditElement::create(Document& document, EditControlOwner& editControlOwner)
{
- RefPtr<DateTimeEditElement> container = adoptRef(new DateTimeEditElement(document, editControlOwner));
- container->setPseudo(AtomicString("-webkit-datetime-edit", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<DateTimeEditElement> container = adoptRefWillBeNoop(new DateTimeEditElement(document, editControlOwner));
+ container->setShadowPseudoId(AtomicString("-webkit-datetime-edit", AtomicString::ConstructFromLiteral));
container->setAttribute(idAttr, ShadowElementNames::dateTimeEdit());
return container.release();
}
@@ -534,7 +546,7 @@ void DateTimeEditElement::disabledStateChanged()
DateTimeFieldElement* DateTimeEditElement::fieldAt(size_t fieldIndex) const
{
- return fieldIndex < m_fields.size() ? m_fields[fieldIndex] : 0;
+ return fieldIndex < m_fields.size() ? m_fields[fieldIndex].get() : 0;
}
size_t DateTimeEditElement::fieldIndexOf(const DateTimeFieldElement& field) const
@@ -651,8 +663,8 @@ void DateTimeEditElement::layout(const LayoutParameters& layoutParameters, const
{
DEFINE_STATIC_LOCAL(AtomicString, fieldsWrapperPseudoId, ("-webkit-datetime-edit-fields-wrapper", AtomicString::ConstructFromLiteral));
if (!firstChild()) {
- RefPtr<HTMLDivElement> element = HTMLDivElement::create(document());
- element->setPseudo(fieldsWrapperPseudoId);
+ RefPtrWillBeRawPtr<HTMLDivElement> element = HTMLDivElement::create(document());
+ element->setShadowPseudoId(fieldsWrapperPseudoId);
appendChild(element.get());
}
Element* fieldsWrapper = fieldsWrapperElement();
@@ -685,7 +697,7 @@ void DateTimeEditElement::layout(const LayoutParameters& layoutParameters, const
if (childNode == lastChildToBeRemoved)
break;
}
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
}
@@ -694,6 +706,12 @@ AtomicString DateTimeEditElement::localeIdentifier() const
return m_editControlOwner ? m_editControlOwner->localeIdentifier() : nullAtom;
}
+void DateTimeEditElement::fieldDidChangeValueByKeyboard()
+{
+ if (m_editControlOwner)
+ m_editControlOwner->editControlDidChangeValueByKeyboard();
+}
+
void DateTimeEditElement::readOnlyStateChanged()
{
updateUIState();
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h
index 87226cb136b..8621afdad8e 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.h
@@ -45,11 +45,12 @@ class StepRange;
// - Hour, Minute, Second, Millisecond, AM/PM
class DateTimeEditElement FINAL : public HTMLDivElement, public DateTimeFieldElement::FieldOwner {
WTF_MAKE_NONCOPYABLE(DateTimeEditElement);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DateTimeEditElement);
public:
// EditControlOwner implementer must call removeEditControlOwner when
// it doesn't handle event, e.g. at destruction.
- class EditControlOwner {
+ class EditControlOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~EditControlOwner();
virtual void didBlurFromControl() = 0;
@@ -59,6 +60,7 @@ public:
virtual bool isEditControlOwnerDisabled() const = 0;
virtual bool isEditControlOwnerReadOnly() const = 0;
virtual AtomicString localeIdentifier() const = 0;
+ virtual void editControlDidChangeValueByKeyboard() = 0;
};
struct LayoutParameters {
@@ -79,10 +81,12 @@ public:
}
};
- static PassRefPtr<DateTimeEditElement> create(Document&, EditControlOwner&);
+ static PassRefPtrWillBeRawPtr<DateTimeEditElement> create(Document&, EditControlOwner&);
virtual ~DateTimeEditElement();
- void addField(PassRefPtr<DateTimeFieldElement>);
+ virtual void trace(Visitor*) OVERRIDE;
+
+ void addField(PassRefPtrWillBeRawPtr<DateTimeFieldElement>);
bool anyEditableFieldsHaveValues() const;
void blurByOwner();
virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -94,7 +98,7 @@ public:
void focusByOwner(Element* oldFocusedElement = 0);
bool hasFocusedField();
void readOnlyStateChanged();
- void removeEditControlOwner() { m_editControlOwner = 0; }
+ void removeEditControlOwner() { m_editControlOwner = nullptr; }
void resetFields();
void setEmptyValue(const LayoutParameters&, const DateComponents& dateForReadOnlyField);
void setValueAsDate(const LayoutParameters&, const DateComponents&);
@@ -136,17 +140,18 @@ private:
virtual bool isDateTimeEditElement() const OVERRIDE;
// DateTimeFieldElement::FieldOwner functions.
- virtual void didBlurFromField() OVERRIDE FINAL;
- virtual void didFocusOnField() OVERRIDE FINAL;
- virtual void fieldValueChanged() OVERRIDE FINAL;
- virtual bool focusOnNextField(const DateTimeFieldElement&) OVERRIDE FINAL;
- virtual bool focusOnPreviousField(const DateTimeFieldElement&) OVERRIDE FINAL;
- virtual bool isFieldOwnerDisabled() const OVERRIDE FINAL;
- virtual bool isFieldOwnerReadOnly() const OVERRIDE FINAL;
- virtual AtomicString localeIdentifier() const OVERRIDE FINAL;
-
- Vector<DateTimeFieldElement*, maximumNumberOfFields> m_fields;
- EditControlOwner* m_editControlOwner;
+ virtual void didBlurFromField() OVERRIDE;
+ virtual void didFocusOnField() OVERRIDE;
+ virtual void fieldValueChanged() OVERRIDE;
+ virtual bool focusOnNextField(const DateTimeFieldElement&) OVERRIDE;
+ virtual bool focusOnPreviousField(const DateTimeFieldElement&) OVERRIDE;
+ virtual bool isFieldOwnerDisabled() const OVERRIDE;
+ virtual bool isFieldOwnerReadOnly() const OVERRIDE;
+ virtual AtomicString localeIdentifier() const OVERRIDE;
+ virtual void fieldDidChangeValueByKeyboard() OVERRIDE;
+
+ WillBeHeapVector<RawPtrWillBeMember<DateTimeFieldElement>, maximumNumberOfFields> m_fields;
+ RawPtrWillBeMember<EditControlOwner> m_editControlOwner;
};
DEFINE_TYPE_CASTS(DateTimeEditElement, Element, element, element->isDateTimeEditElement(), element.isDateTimeEditElement());
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp
index 31cdb06f9c4..e96cc7a4fb5 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.cpp
@@ -27,7 +27,8 @@
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "core/html/shadow/DateTimeFieldElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/dom/Document.h"
#include "core/dom/Text.h"
#include "core/events/KeyboardEvent.h"
#include "platform/text/PlatformLocale.h"
@@ -52,22 +53,27 @@ DateTimeFieldElement::DateTimeFieldElement(Document& document, FieldOwner& field
{
}
-void DateTimeFieldElement::defaultEventHandler(Event* event)
+void DateTimeFieldElement::trace(Visitor* visitor)
{
- if (event->type() == EventTypeNames::blur)
- didBlur();
-
- if (event->type() == EventTypeNames::focus)
- didFocus();
+ visitor->trace(m_fieldOwner);
+ HTMLSpanElement::trace(visitor);
+}
+void DateTimeFieldElement::defaultEventHandler(Event* event)
+{
if (event->isKeyboardEvent()) {
KeyboardEvent* keyboardEvent = toKeyboardEvent(event);
if (!isDisabled() && !isFieldOwnerDisabled() && !isFieldOwnerReadOnly()) {
handleKeyboardEvent(keyboardEvent);
- if (keyboardEvent->defaultHandled())
+ if (keyboardEvent->defaultHandled()) {
+ if (m_fieldOwner)
+ m_fieldOwner->fieldDidChangeValueByKeyboard();
return;
+ }
}
defaultKeyboardEventHandler(keyboardEvent);
+ if (m_fieldOwner)
+ m_fieldOwner->fieldDidChangeValueByKeyboard();
if (keyboardEvent->defaultHandled())
return;
}
@@ -129,16 +135,11 @@ void DateTimeFieldElement::defaultKeyboardEventHandler(KeyboardEvent* keyboardEv
}
}
-void DateTimeFieldElement::didBlur()
-{
- if (m_fieldOwner)
- m_fieldOwner->didBlurFromField();
-}
-
-void DateTimeFieldElement::didFocus()
+void DateTimeFieldElement::setFocus(bool value)
{
if (m_fieldOwner)
- m_fieldOwner->didFocusOnField();
+ value ? m_fieldOwner->didFocusOnField() : m_fieldOwner->didBlurFromField();
+ ContainerNode::setFocus(value);
}
void DateTimeFieldElement::focusOnNextField()
@@ -152,12 +153,12 @@ void DateTimeFieldElement::initialize(const AtomicString& pseudo, const String&
{
// On accessibility, DateTimeFieldElement acts like spin button.
setAttribute(roleAttr, AtomicString("spinbutton", AtomicString::ConstructFromLiteral));
- setAttribute(aria_valuetextAttr, emptyValueAXText());
- setAttribute(aria_valueminAttr, String::number(axMinimum));
- setAttribute(aria_valuemaxAttr, String::number(axMaximum));
+ setAttribute(aria_valuetextAttr, AtomicString(emptyValueAXText()));
+ setAttribute(aria_valueminAttr, AtomicString::number(axMinimum));
+ setAttribute(aria_valuemaxAttr, AtomicString::number(axMaximum));
- setAttribute(aria_helpAttr, axHelpText);
- setPseudo(pseudo);
+ setAttribute(aria_helpAttr, AtomicString(axHelpText));
+ setShadowPseudoId(pseudo);
appendChild(Text::create(document(), visibleValue()));
}
@@ -201,7 +202,7 @@ void DateTimeFieldElement::setDisabled()
{
// Set HTML attribute disabled to change apperance.
setBooleanAttribute(disabledAttr, true);
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
bool DateTimeFieldElement::supportsFocus() const
@@ -220,10 +221,10 @@ void DateTimeFieldElement::updateVisibleValue(EventBehavior eventBehavior)
textNode->replaceWholeText(newVisibleValue);
if (hasValue()) {
- setAttribute(aria_valuetextAttr, newVisibleValue);
- setAttribute(aria_valuenowAttr, String::number(valueForARIAValueNow()));
+ setAttribute(aria_valuetextAttr, AtomicString(newVisibleValue));
+ setAttribute(aria_valuenowAttr, AtomicString::number(valueForARIAValueNow()));
} else {
- setAttribute(aria_valuetextAttr, emptyValueAXText());
+ setAttribute(aria_valuetextAttr, AtomicString(emptyValueAXText()));
removeAttribute(aria_valuenowAttr);
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h
index a2e42a9599b..1fe32594769 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElement.h
@@ -48,7 +48,7 @@ public:
// FieldOwner implementer must call removeEventHandler when
// it doesn't handle event, e.g. at destruction.
- class FieldOwner {
+ class FieldOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~FieldOwner();
virtual void didBlurFromField() = 0;
@@ -59,6 +59,7 @@ public:
virtual bool isFieldOwnerDisabled() const = 0;
virtual bool isFieldOwnerReadOnly() const = 0;
virtual AtomicString localeIdentifier() const = 0;
+ virtual void fieldDidChangeValueByKeyboard() = 0;
};
virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -66,7 +67,7 @@ public:
bool isDisabled() const;
virtual float maximumWidth(const Font&);
virtual void populateDateTimeFieldsState(DateTimeFieldsState&) = 0;
- void removeEventHandler() { m_fieldOwner = 0; }
+ void removeEventHandler() { m_fieldOwner = nullptr; }
void setDisabled();
virtual void setEmptyValue(EventBehavior = DispatchNoEvent) = 0;
virtual void setValueAsDate(const DateComponents&) = 0;
@@ -76,11 +77,10 @@ public:
virtual void stepUp() = 0;
virtual String value() const = 0;
virtual String visibleValue() const = 0;
+ virtual void trace(Visitor*) OVERRIDE;
protected:
DateTimeFieldElement(Document&, FieldOwner&);
- virtual void didBlur();
- virtual void didFocus();
void focusOnNextField();
virtual void handleKeyboardEvent(KeyboardEvent*) = 0;
void initialize(const AtomicString& pseudo, const String& axHelpText, int axMinimum, int axMaximum);
@@ -90,14 +90,17 @@ protected:
virtual int valueAsInteger() const = 0;
virtual int valueForARIAValueNow() const;
+ // Node functions.
+ virtual void setFocus(bool) OVERRIDE;
+
private:
void defaultKeyboardEventHandler(KeyboardEvent*);
- virtual bool isDateTimeFieldElement() const OVERRIDE;
+ virtual bool isDateTimeFieldElement() const OVERRIDE FINAL;
bool isFieldOwnerDisabled() const;
bool isFieldOwnerReadOnly() const;
virtual bool supportsFocus() const OVERRIDE FINAL;
- FieldOwner* m_fieldOwner;
+ RawPtrWillBeMember<FieldOwner> m_fieldOwner;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp
index 5353c04ff2e..9479d9682ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.cpp
@@ -47,10 +47,10 @@ DateTimeAMPMFieldElement::DateTimeAMPMFieldElement(Document& document, FieldOwne
{
}
-PassRefPtr<DateTimeAMPMFieldElement> DateTimeAMPMFieldElement::create(Document& document, FieldOwner& fieldOwner, const Vector<String>& ampmLabels)
+PassRefPtrWillBeRawPtr<DateTimeAMPMFieldElement> DateTimeAMPMFieldElement::create(Document& document, FieldOwner& fieldOwner, const Vector<String>& ampmLabels)
{
DEFINE_STATIC_LOCAL(AtomicString, ampmPsuedoId, ("-webkit-datetime-edit-ampm-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeAMPMFieldElement> field = adoptRef(new DateTimeAMPMFieldElement(document, fieldOwner, ampmLabels));
+ RefPtrWillBeRawPtr<DateTimeAMPMFieldElement> field = adoptRefWillBeNoop(new DateTimeAMPMFieldElement(document, fieldOwner, ampmLabels));
field->initialize(ampmPsuedoId, queryString(WebLocalizedString::AXAMPMFieldText));
return field.release();
}
@@ -83,10 +83,10 @@ DateTimeDayFieldElement::DateTimeDayFieldElement(Document& document, FieldOwner&
{
}
-PassRefPtr<DateTimeDayFieldElement> DateTimeDayFieldElement::create(Document& document, FieldOwner& fieldOwner, const String& placeholder, const Range& range)
+PassRefPtrWillBeRawPtr<DateTimeDayFieldElement> DateTimeDayFieldElement::create(Document& document, FieldOwner& fieldOwner, const String& placeholder, const Range& range)
{
DEFINE_STATIC_LOCAL(AtomicString, dayPsuedoId, ("-webkit-datetime-edit-day-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeDayFieldElement> field = adoptRef(new DateTimeDayFieldElement(document, fieldOwner, placeholder.isEmpty() ? "--" : placeholder, range));
+ RefPtrWillBeRawPtr<DateTimeDayFieldElement> field = adoptRefWillBeNoop(new DateTimeDayFieldElement(document, fieldOwner, placeholder.isEmpty() ? "--" : placeholder, range));
field->initialize(dayPsuedoId, queryString(WebLocalizedString::AXDayOfMonthFieldText));
return field.release();
}
@@ -159,7 +159,7 @@ DateTimeHour11FieldElement::DateTimeHour11FieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeHour11FieldElement> DateTimeHour11FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeHour11FieldElement> DateTimeHour11FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
{
ASSERT(hour23Range.minimum >= 0);
ASSERT(hour23Range.maximum <= 23);
@@ -172,7 +172,7 @@ PassRefPtr<DateTimeHour11FieldElement> DateTimeHour11FieldElement::create(Docume
range.maximum = hour23Range.maximum - 12;
}
- RefPtr<DateTimeHour11FieldElement> field = adoptRef(new DateTimeHour11FieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeHour11FieldElement> field = adoptRefWillBeNoop(new DateTimeHour11FieldElement(document, fieldOwner, range, step));
field->initialize();
return field.release();
}
@@ -200,7 +200,7 @@ DateTimeHour12FieldElement::DateTimeHour12FieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeHour12FieldElement> DateTimeHour12FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeHour12FieldElement> DateTimeHour12FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
{
ASSERT(hour23Range.minimum >= 0);
ASSERT(hour23Range.maximum <= 23);
@@ -220,7 +220,7 @@ PassRefPtr<DateTimeHour12FieldElement> DateTimeHour12FieldElement::create(Docume
range.minimum = 1;
range.maximum = 12;
}
- RefPtr<DateTimeHour12FieldElement> field = adoptRef(new DateTimeHour12FieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeHour12FieldElement> field = adoptRefWillBeNoop(new DateTimeHour12FieldElement(document, fieldOwner, range, step));
field->initialize();
return field.release();
}
@@ -243,12 +243,12 @@ DateTimeHour23FieldElement::DateTimeHour23FieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeHour23FieldElement> DateTimeHour23FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeHour23FieldElement> DateTimeHour23FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
{
ASSERT(hour23Range.minimum >= 0);
ASSERT(hour23Range.maximum <= 23);
ASSERT(hour23Range.minimum <= hour23Range.maximum);
- RefPtr<DateTimeHour23FieldElement> field = adoptRef(new DateTimeHour23FieldElement(document, fieldOwner, hour23Range, step));
+ RefPtrWillBeRawPtr<DateTimeHour23FieldElement> field = adoptRefWillBeNoop(new DateTimeHour23FieldElement(document, fieldOwner, hour23Range, step));
field->initialize();
return field.release();
}
@@ -279,7 +279,7 @@ DateTimeHour24FieldElement::DateTimeHour24FieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeHour24FieldElement> DateTimeHour24FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeHour24FieldElement> DateTimeHour24FieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& hour23Range, const Step& step)
{
ASSERT(hour23Range.minimum >= 0);
ASSERT(hour23Range.maximum <= 23);
@@ -290,7 +290,7 @@ PassRefPtr<DateTimeHour24FieldElement> DateTimeHour24FieldElement::create(Docume
range.maximum = 24;
}
- RefPtr<DateTimeHour24FieldElement> field = adoptRef(new DateTimeHour24FieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeHour24FieldElement> field = adoptRefWillBeNoop(new DateTimeHour24FieldElement(document, fieldOwner, range, step));
field->initialize();
return field.release();
}
@@ -326,10 +326,10 @@ DateTimeMillisecondFieldElement::DateTimeMillisecondFieldElement(Document& docum
{
}
-PassRefPtr<DateTimeMillisecondFieldElement> DateTimeMillisecondFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeMillisecondFieldElement> DateTimeMillisecondFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
{
DEFINE_STATIC_LOCAL(AtomicString, millisecondPsuedoId, ("-webkit-datetime-edit-millisecond-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeMillisecondFieldElement> field = adoptRef(new DateTimeMillisecondFieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeMillisecondFieldElement> field = adoptRefWillBeNoop(new DateTimeMillisecondFieldElement(document, fieldOwner, range, step));
field->initialize(millisecondPsuedoId, queryString(WebLocalizedString::AXMillisecondFieldText));
return field.release();
}
@@ -367,10 +367,10 @@ DateTimeMinuteFieldElement::DateTimeMinuteFieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeMinuteFieldElement> DateTimeMinuteFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeMinuteFieldElement> DateTimeMinuteFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
{
DEFINE_STATIC_LOCAL(AtomicString, minutePsuedoId, ("-webkit-datetime-edit-minute-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeMinuteFieldElement> field = adoptRef(new DateTimeMinuteFieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeMinuteFieldElement> field = adoptRefWillBeNoop(new DateTimeMinuteFieldElement(document, fieldOwner, range, step));
field->initialize(minutePsuedoId, queryString(WebLocalizedString::AXMinuteFieldText));
return field.release();
}
@@ -408,10 +408,10 @@ DateTimeMonthFieldElement::DateTimeMonthFieldElement(Document& document, FieldOw
{
}
-PassRefPtr<DateTimeMonthFieldElement> DateTimeMonthFieldElement::create(Document& document, FieldOwner& fieldOwner, const String& placeholder, const Range& range)
+PassRefPtrWillBeRawPtr<DateTimeMonthFieldElement> DateTimeMonthFieldElement::create(Document& document, FieldOwner& fieldOwner, const String& placeholder, const Range& range)
{
DEFINE_STATIC_LOCAL(AtomicString, monthPsuedoId, ("-webkit-datetime-edit-month-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeMonthFieldElement> field = adoptRef(new DateTimeMonthFieldElement(document, fieldOwner, placeholder.isEmpty() ? "--" : placeholder, range));
+ RefPtrWillBeRawPtr<DateTimeMonthFieldElement> field = adoptRefWillBeNoop(new DateTimeMonthFieldElement(document, fieldOwner, placeholder.isEmpty() ? "--" : placeholder, range));
field->initialize(monthPsuedoId, queryString(WebLocalizedString::AXMonthFieldText));
return field.release();
}
@@ -449,10 +449,10 @@ DateTimeSecondFieldElement::DateTimeSecondFieldElement(Document& document, Field
{
}
-PassRefPtr<DateTimeSecondFieldElement> DateTimeSecondFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
+PassRefPtrWillBeRawPtr<DateTimeSecondFieldElement> DateTimeSecondFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range, const Step& step)
{
DEFINE_STATIC_LOCAL(AtomicString, secondPsuedoId, ("-webkit-datetime-edit-second-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeSecondFieldElement> field = adoptRef(new DateTimeSecondFieldElement(document, fieldOwner, range, step));
+ RefPtrWillBeRawPtr<DateTimeSecondFieldElement> field = adoptRefWillBeNoop(new DateTimeSecondFieldElement(document, fieldOwner, range, step));
field->initialize(secondPsuedoId, queryString(WebLocalizedString::AXSecondFieldText));
return field.release();
}
@@ -490,10 +490,10 @@ DateTimeSymbolicMonthFieldElement::DateTimeSymbolicMonthFieldElement(Document& d
{
}
-PassRefPtr<DateTimeSymbolicMonthFieldElement> DateTimeSymbolicMonthFieldElement::create(Document& document, FieldOwner& fieldOwner, const Vector<String>& labels, int minimum, int maximum)
+PassRefPtrWillBeRawPtr<DateTimeSymbolicMonthFieldElement> DateTimeSymbolicMonthFieldElement::create(Document& document, FieldOwner& fieldOwner, const Vector<String>& labels, int minimum, int maximum)
{
DEFINE_STATIC_LOCAL(AtomicString, monthPsuedoId, ("-webkit-datetime-edit-month-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeSymbolicMonthFieldElement> field = adoptRef(new DateTimeSymbolicMonthFieldElement(document, fieldOwner, labels, minimum, maximum));
+ RefPtrWillBeRawPtr<DateTimeSymbolicMonthFieldElement> field = adoptRefWillBeNoop(new DateTimeSymbolicMonthFieldElement(document, fieldOwner, labels, minimum, maximum));
field->initialize(monthPsuedoId, queryString(WebLocalizedString::AXMonthFieldText));
return field.release();
}
@@ -534,10 +534,10 @@ DateTimeWeekFieldElement::DateTimeWeekFieldElement(Document& document, FieldOwne
{
}
-PassRefPtr<DateTimeWeekFieldElement> DateTimeWeekFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range)
+PassRefPtrWillBeRawPtr<DateTimeWeekFieldElement> DateTimeWeekFieldElement::create(Document& document, FieldOwner& fieldOwner, const Range& range)
{
DEFINE_STATIC_LOCAL(AtomicString, weekPsuedoId, ("-webkit-datetime-edit-week-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeWeekFieldElement> field = adoptRef(new DateTimeWeekFieldElement(document, fieldOwner, range));
+ RefPtrWillBeRawPtr<DateTimeWeekFieldElement> field = adoptRefWillBeNoop(new DateTimeWeekFieldElement(document, fieldOwner, range));
field->initialize(weekPsuedoId, queryString(WebLocalizedString::AXWeekOfYearFieldText));
return field.release();
}
@@ -579,10 +579,10 @@ DateTimeYearFieldElement::DateTimeYearFieldElement(Document& document, FieldOwne
ASSERT(parameters.maximumYear <= DateComponents::maximumYear());
}
-PassRefPtr<DateTimeYearFieldElement> DateTimeYearFieldElement::create(Document& document, FieldOwner& fieldOwner, const DateTimeYearFieldElement::Parameters& parameters)
+PassRefPtrWillBeRawPtr<DateTimeYearFieldElement> DateTimeYearFieldElement::create(Document& document, FieldOwner& fieldOwner, const DateTimeYearFieldElement::Parameters& parameters)
{
DEFINE_STATIC_LOCAL(AtomicString, yearPsuedoId, ("-webkit-datetime-edit-year-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeYearFieldElement> field = adoptRef(new DateTimeYearFieldElement(document, fieldOwner, parameters));
+ RefPtrWillBeRawPtr<DateTimeYearFieldElement> field = adoptRefWillBeNoop(new DateTimeYearFieldElement(document, fieldOwner, parameters));
field->initialize(yearPsuedoId, queryString(WebLocalizedString::AXYearFieldText));
return field.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h
index fb8ef52b22e..19050dbf6dc 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeFieldElements.h
@@ -36,30 +36,30 @@ class DateTimeAMPMFieldElement FINAL : public DateTimeSymbolicFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeAMPMFieldElement);
public:
- static PassRefPtr<DateTimeAMPMFieldElement> create(Document&, FieldOwner&, const Vector<String>&);
+ static PassRefPtrWillBeRawPtr<DateTimeAMPMFieldElement> create(Document&, FieldOwner&, const Vector<String>&);
private:
DateTimeAMPMFieldElement(Document&, FieldOwner&, const Vector<String>&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeDayFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeDayFieldElement);
public:
- static PassRefPtr<DateTimeDayFieldElement> create(Document&, FieldOwner&, const String& placeholder, const Range&);
+ static PassRefPtrWillBeRawPtr<DateTimeDayFieldElement> create(Document&, FieldOwner&, const String& placeholder, const Range&);
private:
DateTimeDayFieldElement(Document&, FieldOwner&, const String& placeholder, const Range&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeHourFieldElementBase : public DateTimeNumericFieldElement {
@@ -71,154 +71,154 @@ protected:
private:
// DateTimeFieldElement functions.
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeHour11FieldElement FINAL : public DateTimeHourFieldElementBase {
WTF_MAKE_NONCOPYABLE(DateTimeHour11FieldElement);
public:
- static PassRefPtr<DateTimeHour11FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeHour11FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeHour11FieldElement(Document&, FieldOwner&, const Range& hour23Range, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE;
};
class DateTimeHour12FieldElement FINAL : public DateTimeHourFieldElementBase {
WTF_MAKE_NONCOPYABLE(DateTimeHour12FieldElement);
public:
- static PassRefPtr<DateTimeHour12FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeHour12FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeHour12FieldElement(Document&, FieldOwner&, const Range& hour23Range, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE;
};
class DateTimeHour23FieldElement FINAL : public DateTimeHourFieldElementBase {
WTF_MAKE_NONCOPYABLE(DateTimeHour23FieldElement);
public:
- static PassRefPtr<DateTimeHour23FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeHour23FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeHour23FieldElement(Document&, FieldOwner&, const Range& hour23Range, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE;
};
class DateTimeHour24FieldElement FINAL : public DateTimeHourFieldElementBase {
WTF_MAKE_NONCOPYABLE(DateTimeHour24FieldElement);
public:
- static PassRefPtr<DateTimeHour24FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeHour24FieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeHour24FieldElement(Document&, FieldOwner&, const Range& hour23Range, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsInteger(int, EventBehavior = DispatchNoEvent) OVERRIDE;
};
class DateTimeMillisecondFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeMillisecondFieldElement);
public:
- static PassRefPtr<DateTimeMillisecondFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeMillisecondFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeMillisecondFieldElement(Document&, FieldOwner&, const Range&, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeMinuteFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeMinuteFieldElement);
public:
- static PassRefPtr<DateTimeMinuteFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeMinuteFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeMinuteFieldElement(Document&, FieldOwner&, const Range&, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeMonthFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeMonthFieldElement);
public:
- static PassRefPtr<DateTimeMonthFieldElement> create(Document&, FieldOwner&, const String& placeholder, const Range&);
+ static PassRefPtrWillBeRawPtr<DateTimeMonthFieldElement> create(Document&, FieldOwner&, const String& placeholder, const Range&);
private:
DateTimeMonthFieldElement(Document&, FieldOwner&, const String& placeholder, const Range&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeSecondFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeSecondFieldElement);
public:
- static PassRefPtr<DateTimeSecondFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
+ static PassRefPtrWillBeRawPtr<DateTimeSecondFieldElement> create(Document&, FieldOwner&, const Range&, const Step&);
private:
DateTimeSecondFieldElement(Document&, FieldOwner&, const Range&, const Step&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeSymbolicMonthFieldElement FINAL : public DateTimeSymbolicFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeSymbolicMonthFieldElement);
public:
- static PassRefPtr<DateTimeSymbolicMonthFieldElement> create(Document&, FieldOwner&, const Vector<String>&, int minimum, int maximum);
+ static PassRefPtrWillBeRawPtr<DateTimeSymbolicMonthFieldElement> create(Document&, FieldOwner&, const Vector<String>&, int minimum, int maximum);
private:
DateTimeSymbolicMonthFieldElement(Document&, FieldOwner&, const Vector<String>&, int minimum, int maximum);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeWeekFieldElement FINAL : public DateTimeNumericFieldElement {
WTF_MAKE_NONCOPYABLE(DateTimeWeekFieldElement);
public:
- static PassRefPtr<DateTimeWeekFieldElement> create(Document&, FieldOwner&, const Range&);
+ static PassRefPtrWillBeRawPtr<DateTimeWeekFieldElement> create(Document&, FieldOwner&, const Range&);
private:
DateTimeWeekFieldElement(Document&, FieldOwner&, const Range&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
};
class DateTimeYearFieldElement FINAL : public DateTimeNumericFieldElement {
@@ -241,19 +241,19 @@ public:
}
};
- static PassRefPtr<DateTimeYearFieldElement> create(Document&, FieldOwner&, const Parameters&);
+ static PassRefPtrWillBeRawPtr<DateTimeYearFieldElement> create(Document&, FieldOwner&, const Parameters&);
private:
DateTimeYearFieldElement(Document&, FieldOwner&, const Parameters&);
// DateTimeFieldElement functions.
- virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
- virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
- virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE FINAL;
+ virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE;
+ virtual void setValueAsDate(const DateComponents&) OVERRIDE;
+ virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&) OVERRIDE;
// DateTimeNumericFieldElement functions.
- virtual int defaultValueForStepDown() const OVERRIDE FINAL;
- virtual int defaultValueForStepUp() const OVERRIDE FINAL;
+ virtual int defaultValueForStepDown() const OVERRIDE;
+ virtual int defaultValueForStepUp() const OVERRIDE;
bool m_minIsSpecified;
bool m_maxIsSpecified;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp
index 537416f7402..64b3e46b90c 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp
@@ -27,8 +27,8 @@
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
#include "core/html/shadow/DateTimeNumericFieldElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
#include "core/events/KeyboardEvent.h"
#include "platform/fonts/Font.h"
#include "platform/text/PlatformLocale.h"
@@ -91,13 +91,15 @@ int DateTimeNumericFieldElement::defaultValueForStepUp() const
return m_range.minimum;
}
-void DateTimeNumericFieldElement::didBlur()
+void DateTimeNumericFieldElement::setFocus(bool value)
{
- int value = typeAheadValue();
- m_typeAheadBuffer.clear();
- if (value >= 0)
- setValueAsInteger(value, DispatchEvent);
- DateTimeFieldElement::didBlur();
+ if (!value) {
+ int value = typeAheadValue();
+ m_typeAheadBuffer.clear();
+ if (value >= 0)
+ setValueAsInteger(value, DispatchEvent);
+ }
+ DateTimeFieldElement::setFocus(value);
}
String DateTimeNumericFieldElement::formatValue(int value) const
@@ -122,6 +124,13 @@ void DateTimeNumericFieldElement::handleKeyboardEvent(KeyboardEvent* keyboardEve
if (digit < 0 || digit > 9)
return;
+ unsigned maximumLength = DateTimeNumericFieldElement::formatValue(m_range.maximum).length();
+ if (m_typeAheadBuffer.length() >= maximumLength) {
+ String current = m_typeAheadBuffer.toString();
+ m_typeAheadBuffer.clear();
+ unsigned desiredLength = maximumLength - 1;
+ m_typeAheadBuffer.append(current, current.length() - desiredLength, desiredLength);
+ }
m_typeAheadBuffer.append(number);
int newValue = typeAheadValue();
if (newValue >= m_hardLimits.minimum)
@@ -131,7 +140,7 @@ void DateTimeNumericFieldElement::handleKeyboardEvent(KeyboardEvent* keyboardEve
updateVisibleValue(DispatchEvent);
}
- if (m_typeAheadBuffer.length() >= DateTimeNumericFieldElement::formatValue(m_range.maximum).length() || newValue * 10 > m_range.maximum)
+ if (m_typeAheadBuffer.length() >= maximumLength || newValue * 10 > m_range.maximum)
focusOnNextField();
keyboardEvent->setDefaultHandled();
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h
index 9b96fb54e3b..9a6272f8f01 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.h
@@ -80,13 +80,15 @@ protected:
private:
// DateTimeFieldElement functions.
- virtual void didBlur() OVERRIDE FINAL;
virtual void handleKeyboardEvent(KeyboardEvent*) OVERRIDE FINAL;
virtual float maximumWidth(const Font&) OVERRIDE;
virtual void stepDown() OVERRIDE FINAL;
virtual void stepUp() OVERRIDE FINAL;
virtual String value() const OVERRIDE FINAL;
+ // Node functions.
+ virtual void setFocus(bool) OVERRIDE FINAL;
+
String formatValue(int) const;
int roundUp(int) const;
int roundDown(int) const;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp
index f3f2adb3b8e..3da57cd08ea 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "core/html/shadow/DetailsMarkerControl.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLSummaryElement.h"
#include "core/rendering/RenderDetailsMarker.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h b/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h
index 118063ef090..62fe336a698 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.h
@@ -40,20 +40,20 @@ class HTMLSummaryElement;
class DetailsMarkerControl FINAL : public HTMLDivElement {
public:
- DetailsMarkerControl(Document&);
- static PassRefPtr<DetailsMarkerControl> create(Document&);
+ explicit DetailsMarkerControl(Document&);
+ static PassRefPtrWillBeRawPtr<DetailsMarkerControl> create(Document&);
private:
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
HTMLSummaryElement* summaryElement();
};
-inline PassRefPtr<DetailsMarkerControl> DetailsMarkerControl::create(Document& document)
+inline PassRefPtrWillBeRawPtr<DetailsMarkerControl> DetailsMarkerControl::create(Document& document)
{
- RefPtr<DetailsMarkerControl> element = adoptRef(new DetailsMarkerControl(document));
- element->setPseudo(AtomicString("-webkit-details-marker", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<DetailsMarkerControl> element = adoptRefWillBeNoop(new DetailsMarkerControl(document));
+ element->setShadowPseudoId(AtomicString("-webkit-details-marker", AtomicString::ConstructFromLiteral));
return element.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp
deleted file mode 100644
index 81691295e85..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/shadow/HTMLContentElement.h"
-
-#include "HTMLNames.h"
-#include "core/css/CSSParser.h"
-#include "core/css/SelectorChecker.h"
-#include "core/css/SiblingTraversalStrategies.h"
-#include "core/dom/QualifiedName.h"
-#include "core/dom/shadow/ElementShadow.h"
-#include "core/dom/shadow/ShadowRoot.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-PassRefPtr<HTMLContentElement> HTMLContentElement::create(Document& document)
-{
- return adoptRef(new HTMLContentElement(document));
-}
-
-HTMLContentElement::HTMLContentElement(Document& document)
- : InsertionPoint(contentTag, document)
- , m_shouldParseSelect(false)
- , m_isValidSelector(true)
-{
- ScriptWrappable::init(this);
-}
-
-HTMLContentElement::~HTMLContentElement()
-{
-}
-
-void HTMLContentElement::parseSelect()
-{
- ASSERT(m_shouldParseSelect);
-
- CSSParser parser(document());
- parser.parseSelector(m_select, m_selectorList);
- m_shouldParseSelect = false;
- m_isValidSelector = validateSelect();
- if (!m_isValidSelector) {
- CSSSelectorList emptyList;
- m_selectorList.adopt(emptyList);
- }
-}
-
-void HTMLContentElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
-{
- if (name == selectAttr) {
- if (ShadowRoot* root = containingShadowRoot())
- root->owner()->willAffectSelector();
- m_shouldParseSelect = true;
- m_select = value;
- } else
- InsertionPoint::parseAttribute(name, value);
-}
-
-bool HTMLContentElement::validateSelect() const
-{
- ASSERT(!m_shouldParseSelect);
-
- if (m_select.isNull() || m_select.isEmpty())
- return true;
-
- if (!m_selectorList.isValid())
- return false;
-
- for (const CSSSelector* selector = m_selectorList.first(); selector; selector = m_selectorList.next(selector)) {
- if (!selector->isCompound())
- return false;
- }
-
- return true;
-}
-
-static inline bool checkOneSelector(const CSSSelector* selector, const Vector<Node*, 32>& siblings, int nth)
-{
- Element* element = toElement(siblings[nth]);
- SelectorChecker selectorChecker(element->document(), SelectorChecker::CollectingCSSRules);
- SelectorChecker::SelectorCheckingContext context(selector, element, SelectorChecker::VisitedMatchEnabled);
- ShadowDOMSiblingTraversalStrategy strategy(siblings, nth);
- return selectorChecker.match(context, strategy) == SelectorChecker::SelectorMatches;
-}
-
-bool HTMLContentElement::matchSelector(const Vector<Node*, 32>& siblings, int nth) const
-{
- for (const CSSSelector* selector = selectorList().first(); selector; selector = CSSSelectorList::next(selector)) {
- if (checkOneSelector(selector, siblings, nth))
- return true;
- }
- return false;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.h
deleted file mode 100644
index b8f0f4fdd58..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLContentElement_h
-#define HTMLContentElement_h
-
-#include "core/css/CSSSelectorList.h"
-#include "core/dom/shadow/InsertionPoint.h"
-
-namespace WebCore {
-
-class HTMLContentElement FINAL : public InsertionPoint {
-public:
- static PassRefPtr<HTMLContentElement> create(Document&);
-
- virtual ~HTMLContentElement();
-
- virtual bool canAffectSelector() const OVERRIDE { return true; }
-
- bool canSelectNode(const Vector<Node*, 32>& siblings, int nth) const;
-
- const CSSSelectorList& selectorList() const;
- bool isSelectValid() const;
-
-private:
- explicit HTMLContentElement(Document&);
-
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
-
- bool validateSelect() const;
- void parseSelect();
-
- bool matchSelector(const Vector<Node*, 32>& siblings, int nth) const;
-
- bool m_shouldParseSelect;
- bool m_isValidSelector;
- AtomicString m_select;
- CSSSelectorList m_selectorList;
-};
-
-inline const CSSSelectorList& HTMLContentElement::selectorList() const
-{
- if (m_shouldParseSelect)
- const_cast<HTMLContentElement*>(this)->parseSelect();
- return m_selectorList;
-}
-
-inline bool HTMLContentElement::isSelectValid() const
-{
- if (m_shouldParseSelect)
- const_cast<HTMLContentElement*>(this)->parseSelect();
- return m_isValidSelector;
-}
-
-inline bool HTMLContentElement::canSelectNode(const Vector<Node*, 32>& siblings, int nth) const
-{
- if (m_select.isNull() || m_select.isEmpty())
- return true;
- if (!isSelectValid())
- return false;
- if (!siblings[nth]->isElementNode())
- return false;
- return matchSelector(siblings, nth);
-}
-
-inline bool isHTMLContentElement(const Node* node)
-{
- return node->hasTagName(HTMLNames::contentTag);
-}
-
-inline bool isHTMLContentElement(const Element* element)
-{
- return element->hasTagName(HTMLNames::contentTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLContentElement, hasTagName(HTMLNames::contentTag));
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.idl b/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.idl
deleted file mode 100644
index ab593425152..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLContentElement.idl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
-] interface HTMLContentElement : HTMLElement {
- [Reflect, TreatNullAs=NullString] attribute DOMString select;
- attribute boolean resetStyleInheritance;
- NodeList getDistributedNodes();
-};
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp
deleted file mode 100644
index edfba07e3e1..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/shadow/HTMLShadowElement.h"
-
-#include "HTMLNames.h"
-#include "core/dom/shadow/ShadowRoot.h"
-
-namespace WebCore {
-
-class Document;
-
-inline HTMLShadowElement::HTMLShadowElement(Document& document)
- : InsertionPoint(HTMLNames::shadowTag, document)
-{
- ScriptWrappable::init(this);
-}
-
-PassRefPtr<HTMLShadowElement> HTMLShadowElement::create(Document& document)
-{
- return adoptRef(new HTMLShadowElement(document));
-}
-
-HTMLShadowElement::~HTMLShadowElement()
-{
-}
-
-ShadowRoot* HTMLShadowElement::olderShadowRoot()
-{
- ShadowRoot* containingRoot = containingShadowRoot();
- if (!containingRoot)
- return 0;
-
- document().updateDistributionForNodeIfNeeded(this);
-
- ShadowRoot* older = containingRoot->olderShadowRoot();
- if (!older || !older->shouldExposeToBindings() || older->shadowInsertionPointOfYoungerShadowRoot() != this)
- return 0;
-
- ASSERT(older->shouldExposeToBindings());
- return older;
-}
-
-Node::InsertionNotificationRequest HTMLShadowElement::insertedInto(ContainerNode* insertionPoint)
-{
- if (insertionPoint->inDocument()) {
- // Warn if trying to reproject between user agent and author shadows.
- ShadowRoot* root = containingShadowRoot();
- if (root && root->olderShadowRoot() && root->type() != root->olderShadowRoot()->type()) {
- String message = String::format("<shadow> doesn't work for %s element host.", root->host()->tagName().utf8().data());
- document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
- }
- }
- return InsertionPoint::insertedInto(insertionPoint);
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.h
deleted file mode 100644
index 77741ecc588..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLShadowElement_h
-#define HTMLShadowElement_h
-
-#include "core/dom/shadow/InsertionPoint.h"
-#include "wtf/Forward.h"
-
-namespace WebCore {
-
-class HTMLShadowElement FINAL : public InsertionPoint {
-public:
- static PassRefPtr<HTMLShadowElement> create(Document&);
-
- virtual ~HTMLShadowElement();
-
- ShadowRoot* olderShadowRoot();
-
-private:
- explicit HTMLShadowElement(Document&);
- virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint) OVERRIDE;
-};
-
-inline bool isHTMLShadowElement(const Node* node)
-{
- ASSERT(node);
- return node->hasTagName(HTMLNames::shadowTag);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLShadowElement, hasTagName(HTMLNames::shadowTag));
-
-} // namespace WebCore
-
-#endif // HTMLShadowElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.idl b/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.idl
deleted file mode 100644
index faceace1458..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.idl
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-interface HTMLShadowElement : HTMLElement {
- attribute boolean resetStyleInheritance;
- [DeprecateAs=HTMLShadowElementOlderShadowRoot] readonly attribute ShadowRoot olderShadowRoot;
- [RuntimeEnabled=ShadowDOM] NodeList getDistributedNodes();
-};
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
index dc7f986e04e..989244d1bf8 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp
@@ -31,11 +31,13 @@
#include "core/html/shadow/MediaControlElementTypes.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
#include "core/css/StylePropertySet.h"
#include "core/events/MouseEvent.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/shadow/MediaControls.h"
namespace WebCore {
@@ -50,7 +52,7 @@ HTMLMediaElement* toParentMediaElement(Node* node)
Node* mediaNode = node->shadowHost();
if (!mediaNode)
mediaNode = node;
- if (!mediaNode || !mediaNode->isElementNode() || !toElement(mediaNode)->isMediaElement())
+ if (!isHTMLMediaElement(mediaNode))
return 0;
return toHTMLMediaElement(mediaNode);
@@ -60,18 +62,23 @@ MediaControlElementType mediaControlElementType(Node* node)
{
ASSERT_WITH_SECURITY_IMPLICATION(node->isMediaControlElement());
HTMLElement* element = toHTMLElement(node);
- if (element->hasTagName(inputTag))
+ if (isHTMLInputElement(*element))
return static_cast<MediaControlInputElement*>(element)->displayType();
return static_cast<MediaControlDivElement*>(element)->displayType();
}
-MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element)
- : m_mediaController(0)
+MediaControlElement::MediaControlElement(MediaControls& mediaControls, MediaControlElementType displayType, HTMLElement* element)
+ : m_mediaControls(mediaControls)
, m_displayType(displayType)
, m_element(element)
{
}
+HTMLMediaElement& MediaControlElement::mediaElement() const
+{
+ return mediaControls().mediaElement();
+}
+
void MediaControlElement::hide()
{
m_element->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
@@ -82,14 +89,6 @@ void MediaControlElement::show()
m_element->removeInlineStyleProperty(CSSPropertyDisplay);
}
-bool MediaControlElement::isShowing() const
-{
- const StylePropertySet* propertySet = m_element->inlineStyle();
- // Following the code from show() and hide() above, we only have
- // to check for the presense of inline display.
- return (!propertySet || !propertySet->getPropertyCSSValue(CSSPropertyDisplay));
-}
-
void MediaControlElement::setDisplayType(MediaControlElementType displayType)
{
if (displayType == m_displayType)
@@ -97,22 +96,22 @@ void MediaControlElement::setDisplayType(MediaControlElementType displayType)
m_displayType = displayType;
if (RenderObject* object = m_element->renderer())
- object->repaint();
+ object->paintInvalidationForWholeRenderer();
}
// ----------------------------
-MediaControlDivElement::MediaControlDivElement(Document& document, MediaControlElementType displayType)
- : HTMLDivElement(document)
- , MediaControlElement(displayType, this)
+MediaControlDivElement::MediaControlDivElement(MediaControls& mediaControls, MediaControlElementType displayType)
+ : HTMLDivElement(mediaControls.document())
+ , MediaControlElement(mediaControls, displayType, this)
{
}
// ----------------------------
-MediaControlInputElement::MediaControlInputElement(Document& document, MediaControlElementType displayType)
- : HTMLInputElement(document, 0, false)
- , MediaControlElement(displayType, this)
+MediaControlInputElement::MediaControlInputElement(MediaControls& mediaControls, MediaControlElementType displayType)
+ : HTMLInputElement(mediaControls.document(), 0, false)
+ , MediaControlElement(mediaControls, displayType, this)
{
}
@@ -123,8 +122,8 @@ bool MediaControlInputElement::isMouseFocusable() const
// ----------------------------
-MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document& document, MediaControlElementType displayType)
- : MediaControlDivElement(document, displayType)
+MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(MediaControls& mediaControls, MediaControlElementType displayType)
+ : MediaControlDivElement(mediaControls, displayType)
, m_currentValue(0)
{
}
@@ -134,87 +133,4 @@ void MediaControlTimeDisplayElement::setCurrentValue(double time)
m_currentValue = time;
}
-// ----------------------------
-
-MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document& document, MediaControlElementType displayType)
- : MediaControlInputElement(document, displayType)
-{
-}
-
-void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
-{
- if (event->type() == EventTypeNames::click) {
- mediaController()->setMuted(!mediaController()->muted());
- event->setDefaultHandled();
- }
-
- HTMLInputElement::defaultEventHandler(event);
-}
-
-void MediaControlMuteButtonElement::changedMute()
-{
- updateDisplayType();
-}
-
-void MediaControlMuteButtonElement::updateDisplayType()
-{
- setDisplayType(mediaController()->muted() ? MediaUnMuteButton : MediaMuteButton);
-}
-
-// ----------------------------
-
-MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document)
- : MediaControlInputElement(document, MediaVolumeSlider)
- , m_clearMutedOnUserInteraction(false)
-{
-}
-
-void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
-{
- // Left button is 0. Rejects mouse events not from left button.
- if (event->isMouseEvent() && toMouseEvent(event)->button())
- return;
-
- if (!inDocument() || !document().isActive())
- return;
-
- MediaControlInputElement::defaultEventHandler(event);
-
- if (event->type() == EventTypeNames::mouseover || event->type() == EventTypeNames::mouseout || event->type() == EventTypeNames::mousemove)
- return;
-
- double volume = value().toDouble();
- if (volume != mediaController()->volume())
- mediaController()->setVolume(volume, ASSERT_NO_EXCEPTION);
- if (m_clearMutedOnUserInteraction)
- mediaController()->setMuted(false);
-}
-
-bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
-{
- if (!inDocument() || !document().isActive())
- return false;
-
- return MediaControlInputElement::willRespondToMouseMoveEvents();
-}
-
-bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
-{
- if (!inDocument() || !document().isActive())
- return false;
-
- return MediaControlInputElement::willRespondToMouseClickEvents();
-}
-
-void MediaControlVolumeSliderElement::setVolume(double volume)
-{
- if (value().toDouble() != volume)
- setValue(String::number(volume));
-}
-
-void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute)
-{
- m_clearMutedOnUserInteraction = clearMute;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h
index 6293e6dac09..6213debb7b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.h
@@ -32,23 +32,19 @@
#include "core/html/HTMLDivElement.h"
#include "core/html/HTMLInputElement.h"
-#include "core/html/HTMLMediaElement.h"
-#include "core/html/MediaControllerInterface.h"
#include "core/rendering/RenderBlock.h"
namespace WebCore {
-// Must match WebKitSystemInterface.h
+class HTMLMediaElement;
+class MediaControls;
+
enum MediaControlElementType {
MediaEnterFullscreenButton = 0,
MediaMuteButton,
MediaPlayButton,
- MediaSeekBackButton,
- MediaSeekForwardButton,
MediaSlider,
MediaSliderThumb,
- MediaRewindButton,
- MediaReturnToRealtimeButton,
MediaShowClosedCaptionsButton,
MediaHideClosedCaptionsButton,
MediaUnMuteButton,
@@ -63,7 +59,6 @@ enum MediaControlElementType {
MediaVolumeSliderThumb,
MediaFullScreenVolumeSlider,
MediaFullScreenVolumeSliderThumb,
- MediaVolumeSliderMuteButton,
MediaTextTrackDisplayContainer,
MediaTextTrackDisplay,
MediaExitFullscreenButton,
@@ -77,27 +72,23 @@ MediaControlElementType mediaControlElementType(Node*);
// ----------------------------
-class MediaControlElement {
+class MediaControlElement : public WillBeGarbageCollectedMixin {
public:
- virtual void hide();
- virtual void show();
- virtual bool isShowing() const;
-
- virtual MediaControlElementType displayType() { return m_displayType; }
- virtual const AtomicString& pseudo() const = 0;
+ void hide();
+ void show();
- virtual void setMediaController(MediaControllerInterface* controller) { m_mediaController = controller; }
- virtual MediaControllerInterface* mediaController() const { return m_mediaController; }
+ MediaControlElementType displayType() { return m_displayType; }
protected:
- explicit MediaControlElement(MediaControlElementType, HTMLElement*);
- ~MediaControlElement() { }
+ MediaControlElement(MediaControls&, MediaControlElementType, HTMLElement*);
- virtual void setDisplayType(MediaControlElementType);
- virtual bool isMediaControlElement() const { return true; }
+ MediaControls& mediaControls() const { return m_mediaControls; }
+ HTMLMediaElement& mediaElement() const;
+
+ void setDisplayType(MediaControlElementType);
private:
- MediaControllerInterface* m_mediaController;
+ MediaControls& m_mediaControls;
MediaControlElementType m_displayType;
HTMLElement* m_element;
};
@@ -105,17 +96,21 @@ private:
// ----------------------------
class MediaControlDivElement : public HTMLDivElement, public MediaControlElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MediaControlDivElement);
+
protected:
- virtual bool isMediaControlElement() const OVERRIDE { return MediaControlElement::isMediaControlElement(); }
- explicit MediaControlDivElement(Document&, MediaControlElementType);
+ virtual bool isMediaControlElement() const OVERRIDE FINAL { return true; }
+ MediaControlDivElement(MediaControls&, MediaControlElementType);
};
// ----------------------------
class MediaControlInputElement : public HTMLInputElement, public MediaControlElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(MediaControlInputElement);
+
protected:
- virtual bool isMediaControlElement() const OVERRIDE { return MediaControlElement::isMediaControlElement(); }
- explicit MediaControlInputElement(Document&, MediaControlElementType);
+ virtual bool isMediaControlElement() const OVERRIDE FINAL { return true; }
+ MediaControlInputElement(MediaControls&, MediaControlElementType);
private:
virtual void updateDisplayType() { }
@@ -130,47 +125,12 @@ public:
double currentValue() const { return m_currentValue; }
protected:
- explicit MediaControlTimeDisplayElement(Document&, MediaControlElementType);
+ MediaControlTimeDisplayElement(MediaControls&, MediaControlElementType);
private:
double m_currentValue;
};
-// ----------------------------
-
-class MediaControlMuteButtonElement : public MediaControlInputElement {
-public:
- void changedMute();
-
- virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
-
-protected:
- explicit MediaControlMuteButtonElement(Document&, MediaControlElementType);
-
- virtual void defaultEventHandler(Event*) OVERRIDE;
-
-private:
- virtual void updateDisplayType() OVERRIDE;
-};
-
-// ----------------------------
-
-class MediaControlVolumeSliderElement : public MediaControlInputElement {
-public:
- virtual bool willRespondToMouseMoveEvents() OVERRIDE;
- virtual bool willRespondToMouseClickEvents() OVERRIDE;
- void setVolume(double);
- void setClearMutedOnUserInteraction(bool);
-
-protected:
- explicit MediaControlVolumeSliderElement(Document&);
-
- virtual void defaultEventHandler(Event*) OVERRIDE;
-
-private:
- bool m_clearMutedOnUserInteraction;
-};
-
} // namespace WebCore
#endif // MediaControlElementTypes_h
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
index 9c3aee249b1..674675fbff9 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp
@@ -30,24 +30,23 @@
#include "config.h"
#include "core/html/shadow/MediaControlElements.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/DOMTokenList.h"
#include "core/dom/FullscreenElementStack.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLVideoElement.h"
+#include "core/html/MediaController.h"
#include "core/html/shadow/MediaControls.h"
#include "core/html/track/TextTrack.h"
#include "core/html/track/vtt/VTTRegionList.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderMediaControlElements.h"
#include "core/rendering/RenderSlider.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderVideo.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -56,76 +55,39 @@ using namespace HTMLNames;
static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId();
static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId();
+// If you change any of the following fade durations, then also update the
+// corresponding values in LayoutTests/media/media-controls.js.
static const double fadeInDuration = 0.1;
static const double fadeOutDuration = 0.3;
-MediaControlPanelElement::MediaControlPanelElement(Document& document)
- : MediaControlDivElement(document, MediaControlsPanel)
- , m_canBeDragged(false)
- , m_isBeingDragged(false)
+MediaControlPanelElement::MediaControlPanelElement(MediaControls& mediaControls)
+ : MediaControlDivElement(mediaControls, MediaControlsPanel)
, m_isDisplayed(false)
, m_opaque(true)
, m_transitionTimer(this, &MediaControlPanelElement::transitionTimerFired)
{
}
-PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlPanelElement> MediaControlPanelElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlPanelElement(document));
+ return adoptRefWillBeNoop(new MediaControlPanelElement(mediaControls));
}
-const AtomicString& MediaControlPanelElement::pseudo() const
+const AtomicString& MediaControlPanelElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-panel", AtomicString::ConstructFromLiteral));
return id;
}
-void MediaControlPanelElement::startDrag(const LayoutPoint& eventLocation)
-{
- if (!m_canBeDragged)
- return;
-
- if (m_isBeingDragged)
- return;
-
- RenderObject* renderer = this->renderer();
- if (!renderer || !renderer->isBox())
- return;
-
- Frame* frame = document().frame();
- if (!frame)
- return;
-
- m_lastDragEventLocation = eventLocation;
-
- frame->eventHandler().setCapturingMouseEventsNode(this);
-
- m_isBeingDragged = true;
-}
-
-void MediaControlPanelElement::continueDrag(const LayoutPoint& eventLocation)
-{
- if (!m_isBeingDragged)
- return;
-
- LayoutSize distanceDragged = eventLocation - m_lastDragEventLocation;
- m_cumulativeDragOffset.move(distanceDragged);
- m_lastDragEventLocation = eventLocation;
- setPosition(m_cumulativeDragOffset);
-}
-
-void MediaControlPanelElement::endDrag()
+void MediaControlPanelElement::defaultEventHandler(Event* event)
{
- if (!m_isBeingDragged)
- return;
-
- m_isBeingDragged = false;
-
- Frame* frame = document().frame();
- if (!frame)
+ // Suppress the media element activation behavior (toggle play/pause) when
+ // any part of the control panel is clicked.
+ if (event->type() == EventTypeNames::click) {
+ event->setDefaultHandled();
return;
-
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ }
+ HTMLDivElement::defaultEventHandler(event);
}
void MediaControlPanelElement::startTimer()
@@ -136,7 +98,7 @@ void MediaControlPanelElement::startTimer()
// such that captions are correctly displayed at the bottom of the video
// at the end of the fadeout transition.
// FIXME: Racing a transition with a setTimeout like this is wrong.
- m_transitionTimer.startOneShot(fadeOutDuration);
+ m_transitionTimer.startOneShot(fadeOutDuration, FROM_HERE);
}
void MediaControlPanelElement::stopTimer()
@@ -153,34 +115,6 @@ void MediaControlPanelElement::transitionTimerFired(Timer<MediaControlPanelEleme
stopTimer();
}
-void MediaControlPanelElement::setPosition(const LayoutPoint& position)
-{
- double left = position.x();
- double top = position.y();
-
- // Set the left and top to control the panel's position; this depends on it being absolute positioned.
- // Set the margin to zero since the position passed in will already include the effect of the margin.
- setInlineStyleProperty(CSSPropertyLeft, left, CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyTop, top, CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyMarginLeft, 0.0, CSSPrimitiveValue::CSS_PX);
- setInlineStyleProperty(CSSPropertyMarginTop, 0.0, CSSPrimitiveValue::CSS_PX);
-
- classList()->add("dragged", IGNORE_EXCEPTION);
-}
-
-void MediaControlPanelElement::resetPosition()
-{
- removeInlineStyleProperty(CSSPropertyLeft);
- removeInlineStyleProperty(CSSPropertyTop);
- removeInlineStyleProperty(CSSPropertyMarginLeft);
- removeInlineStyleProperty(CSSPropertyMarginTop);
-
- classList()->remove("dragged", IGNORE_EXCEPTION);
-
- m_cumulativeDragOffset.setX(0);
- m_cumulativeDragOffset.setY(0);
-}
-
void MediaControlPanelElement::makeOpaque()
{
if (m_opaque)
@@ -209,36 +143,6 @@ void MediaControlPanelElement::makeTransparent()
startTimer();
}
-void MediaControlPanelElement::defaultEventHandler(Event* event)
-{
- MediaControlDivElement::defaultEventHandler(event);
-
- if (event->isMouseEvent()) {
- LayoutPoint location = toMouseEvent(event)->absoluteLocation();
- if (event->type() == EventTypeNames::mousedown && event->target() == this) {
- startDrag(location);
- event->setDefaultHandled();
- } else if (event->type() == EventTypeNames::mousemove && m_isBeingDragged)
- continueDrag(location);
- else if (event->type() == EventTypeNames::mouseup && m_isBeingDragged) {
- continueDrag(location);
- endDrag();
- event->setDefaultHandled();
- }
- }
-}
-
-void MediaControlPanelElement::setCanBeDragged(bool canBeDragged)
-{
- if (m_canBeDragged == canBeDragged)
- return;
-
- m_canBeDragged = canBeDragged;
-
- if (!canBeDragged)
- endDrag();
-}
-
void MediaControlPanelElement::setIsDisplayed(bool isDisplayed)
{
m_isDisplayed = isDisplayed;
@@ -246,18 +150,18 @@ void MediaControlPanelElement::setIsDisplayed(bool isDisplayed)
// ----------------------------
-MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(Document& document)
+MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(MediaControls& mediaControls)
// Mapping onto same MediaControlElementType as panel element, since it has similar properties.
- : MediaControlDivElement(document, MediaControlsPanel)
+ : MediaControlDivElement(mediaControls, MediaControlsPanel)
{
}
-PassRefPtr<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlPanelEnclosureElement(document));
+ return adoptRefWillBeNoop(new MediaControlPanelEnclosureElement(mediaControls));
}
-const AtomicString& MediaControlPanelEnclosureElement::pseudo() const
+const AtomicString& MediaControlPanelEnclosureElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-enclosure", AtomicString::ConstructFromLiteral));
return id;
@@ -265,18 +169,18 @@ const AtomicString& MediaControlPanelEnclosureElement::pseudo() const
// ----------------------------
-MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(Document& document)
+MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(MediaControls& mediaControls)
// Mapping onto same MediaControlElementType as panel element, since it has similar properties.
- : MediaControlDivElement(document, MediaControlsPanel)
+ : MediaControlDivElement(mediaControls, MediaControlsPanel)
{
}
-PassRefPtr<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlOverlayEnclosureElement(document));
+ return adoptRefWillBeNoop(new MediaControlOverlayEnclosureElement(mediaControls));
}
-const AtomicString& MediaControlOverlayEnclosureElement::pseudo() const
+const AtomicString& MediaControlOverlayEnclosureElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-overlay-enclosure", AtomicString::ConstructFromLiteral));
return id;
@@ -284,67 +188,50 @@ const AtomicString& MediaControlOverlayEnclosureElement::pseudo() const
// ----------------------------
-MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(Document& document, MediaControls* controls)
- : MediaControlMuteButtonElement(document, MediaMuteButton)
- , m_controls(controls)
+MediaControlMuteButtonElement::MediaControlMuteButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaMuteButton)
{
}
-PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls)
+PassRefPtrWillBeRawPtr<MediaControlMuteButtonElement> MediaControlMuteButtonElement::create(MediaControls& mediaControls)
{
- ASSERT(controls);
-
- RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(document, controls));
+ RefPtrWillBeRawPtr<MediaControlMuteButtonElement> button = adoptRefWillBeNoop(new MediaControlMuteButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
return button.release();
}
-void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
+void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
{
- if (event->type() == EventTypeNames::mouseover)
- m_controls->showVolumeSlider();
-
- MediaControlMuteButtonElement::defaultEventHandler(event);
-}
-
-const AtomicString& MediaControlPanelMuteButtonElement::pseudo() const
-{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral));
- return id;
-}
-
-// ----------------------------
+ if (event->type() == EventTypeNames::click) {
+ mediaElement().setMuted(!mediaElement().muted());
+ event->setDefaultHandled();
+ }
-MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(Document& document)
- : MediaControlMuteButtonElement(document, MediaMuteButton)
-{
+ HTMLInputElement::defaultEventHandler(event);
}
-PassRefPtr<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(Document& document)
+void MediaControlMuteButtonElement::updateDisplayType()
{
- RefPtr<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(new MediaControlVolumeSliderMuteButtonElement(document));
- button->ensureUserAgentShadowRoot();
- button->setType("button");
- return button.release();
+ setDisplayType(mediaElement().muted() ? MediaUnMuteButton : MediaMuteButton);
}
-const AtomicString& MediaControlVolumeSliderMuteButtonElement::pseudo() const
+const AtomicString& MediaControlMuteButtonElement::shadowPseudoId() const
{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider-mute-button", AtomicString::ConstructFromLiteral));
+ DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral));
return id;
}
// ----------------------------
-MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document& document)
- : MediaControlInputElement(document, MediaPlayButton)
+MediaControlPlayButtonElement::MediaControlPlayButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaPlayButton)
{
}
-PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(document));
+ RefPtrWillBeRawPtr<MediaControlPlayButtonElement> button = adoptRefWillBeNoop(new MediaControlPlayButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
return button.release();
@@ -353,10 +240,7 @@ PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(
void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == EventTypeNames::click) {
- if (mediaController()->canPlay())
- mediaController()->play();
- else
- mediaController()->pause();
+ mediaElement().togglePlayState();
updateDisplayType();
event->setDefaultHandled();
}
@@ -365,10 +249,10 @@ void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
void MediaControlPlayButtonElement::updateDisplayType()
{
- setDisplayType(mediaController()->canPlay() ? MediaPlayButton : MediaPauseButton);
+ setDisplayType(mediaElement().togglePlayStateWillPlay() ? MediaPlayButton : MediaPauseButton);
}
-const AtomicString& MediaControlPlayButtonElement::pseudo() const
+const AtomicString& MediaControlPlayButtonElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-play-button", AtomicString::ConstructFromLiteral));
return id;
@@ -376,14 +260,14 @@ const AtomicString& MediaControlPlayButtonElement::pseudo() const
// ----------------------------
-MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(Document& document)
- : MediaControlInputElement(document, MediaOverlayPlayButton)
+MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaOverlayPlayButton)
{
}
-PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlOverlayPlayButtonElement> button = adoptRef(new MediaControlOverlayPlayButtonElement(document));
+ RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> button = adoptRefWillBeNoop(new MediaControlOverlayPlayButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
return button.release();
@@ -391,23 +275,22 @@ PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonEl
void MediaControlOverlayPlayButtonElement::defaultEventHandler(Event* event)
{
- if (event->type() == EventTypeNames::click && mediaController()->canPlay()) {
- mediaController()->play();
+ if (event->type() == EventTypeNames::click && mediaElement().togglePlayStateWillPlay()) {
+ mediaElement().togglePlayState();
updateDisplayType();
event->setDefaultHandled();
}
- HTMLInputElement::defaultEventHandler(event);
}
void MediaControlOverlayPlayButtonElement::updateDisplayType()
{
- if (mediaController()->canPlay()) {
+ if (mediaElement().togglePlayStateWillPlay()) {
show();
} else
hide();
}
-const AtomicString& MediaControlOverlayPlayButtonElement::pseudo() const
+const AtomicString& MediaControlOverlayPlayButtonElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-overlay-play-button", AtomicString::ConstructFromLiteral));
return id;
@@ -416,16 +299,14 @@ const AtomicString& MediaControlOverlayPlayButtonElement::pseudo() const
// ----------------------------
-MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document& document, MediaControls*)
- : MediaControlInputElement(document, MediaShowClosedCaptionsButton)
+MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaShowClosedCaptionsButton)
{
}
-PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls)
+PassRefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(MediaControls& mediaControls)
{
- ASSERT(controls);
-
- RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document, controls));
+ RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRefWillBeNoop(new MediaControlToggleClosedCaptionsButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
button->hide();
@@ -434,7 +315,7 @@ PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClos
void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
{
- bool captionsVisible = mediaController()->closedCaptionsVisible();
+ bool captionsVisible = mediaElement().closedCaptionsVisible();
setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
setChecked(captionsVisible);
}
@@ -442,8 +323,8 @@ void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == EventTypeNames::click) {
- mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible());
- setChecked(mediaController()->closedCaptionsVisible());
+ mediaElement().setClosedCaptionsVisible(!mediaElement().closedCaptionsVisible());
+ setChecked(mediaElement().closedCaptionsVisible());
updateDisplayType();
event->setDefaultHandled();
}
@@ -451,7 +332,7 @@ void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* e
HTMLInputElement::defaultEventHandler(event);
}
-const AtomicString& MediaControlToggleClosedCaptionsButtonElement::pseudo() const
+const AtomicString& MediaControlToggleClosedCaptionsButtonElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral));
return id;
@@ -459,17 +340,14 @@ const AtomicString& MediaControlToggleClosedCaptionsButtonElement::pseudo() cons
// ----------------------------
-MediaControlTimelineElement::MediaControlTimelineElement(Document& document, MediaControls* controls)
- : MediaControlInputElement(document, MediaSlider)
- , m_controls(controls)
+MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaSlider)
{
}
-PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(Document& document, MediaControls* controls)
+PassRefPtrWillBeRawPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(MediaControls& mediaControls)
{
- ASSERT(controls);
-
- RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(document, controls));
+ RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = adoptRefWillBeNoop(new MediaControlTimelineElement(mediaControls));
timeline->ensureUserAgentShadowRoot();
timeline->setType("range");
timeline->setAttribute(stepAttr, "any");
@@ -478,18 +356,17 @@ PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(Docu
void MediaControlTimelineElement::defaultEventHandler(Event* event)
{
- // Left button is 0. Rejects mouse events not from left button.
- if (event->isMouseEvent() && toMouseEvent(event)->button())
+ if (event->isMouseEvent() && toMouseEvent(event)->button() != LeftButton)
return;
if (!inDocument() || !document().isActive())
return;
if (event->type() == EventTypeNames::mousedown)
- mediaController()->beginScrubbing();
+ mediaControls().beginScrubbing();
if (event->type() == EventTypeNames::mouseup)
- mediaController()->endScrubbing();
+ mediaControls().endScrubbing();
MediaControlInputElement::defaultEventHandler(event);
@@ -497,12 +374,18 @@ void MediaControlTimelineElement::defaultEventHandler(Event* event)
return;
double time = value().toDouble();
- if (event->type() == EventTypeNames::input && time != mediaController()->currentTime())
- mediaController()->setCurrentTime(time, IGNORE_EXCEPTION);
+ if (event->type() == EventTypeNames::input) {
+ // FIXME: This will need to take the timeline offset into consideration
+ // once that concept is supported, see https://crbug.com/312699
+ if (mediaElement().controller())
+ mediaElement().controller()->setCurrentTime(time, IGNORE_EXCEPTION);
+ else
+ mediaElement().setCurrentTime(time, IGNORE_EXCEPTION);
+ }
RenderSlider* slider = toRenderSlider(renderer());
if (slider && slider->inDragMode())
- m_controls->updateCurrentTimeDisplay();
+ mediaControls().updateCurrentTimeDisplay();
}
bool MediaControlTimelineElement::willRespondToMouseClickEvents()
@@ -521,7 +404,7 @@ void MediaControlTimelineElement::setDuration(double duration)
}
-const AtomicString& MediaControlTimelineElement::pseudo() const
+const AtomicString& MediaControlTimelineElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-timeline", AtomicString::ConstructFromLiteral));
return id;
@@ -529,14 +412,14 @@ const AtomicString& MediaControlTimelineElement::pseudo() const
// ----------------------------
-MediaControlPanelVolumeSliderElement::MediaControlPanelVolumeSliderElement(Document& document)
- : MediaControlVolumeSliderElement(document)
+MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaVolumeSlider)
{
}
-PassRefPtr<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlVolumeSliderElement> MediaControlVolumeSliderElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlPanelVolumeSliderElement> slider = adoptRef(new MediaControlPanelVolumeSliderElement(document));
+ RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = adoptRefWillBeNoop(new MediaControlVolumeSliderElement(mediaControls));
slider->ensureUserAgentShadowRoot();
slider->setType("range");
slider->setAttribute(stepAttr, "any");
@@ -544,7 +427,47 @@ PassRefPtr<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderEl
return slider.release();
}
-const AtomicString& MediaControlPanelVolumeSliderElement::pseudo() const
+void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
+{
+ if (event->isMouseEvent() && toMouseEvent(event)->button() != LeftButton)
+ return;
+
+ if (!inDocument() || !document().isActive())
+ return;
+
+ MediaControlInputElement::defaultEventHandler(event);
+
+ if (event->type() == EventTypeNames::mouseover || event->type() == EventTypeNames::mouseout || event->type() == EventTypeNames::mousemove)
+ return;
+
+ double volume = value().toDouble();
+ mediaElement().setVolume(volume, ASSERT_NO_EXCEPTION);
+ mediaElement().setMuted(false);
+}
+
+bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
+{
+ if (!inDocument() || !document().isActive())
+ return false;
+
+ return MediaControlInputElement::willRespondToMouseMoveEvents();
+}
+
+bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
+{
+ if (!inDocument() || !document().isActive())
+ return false;
+
+ return MediaControlInputElement::willRespondToMouseClickEvents();
+}
+
+void MediaControlVolumeSliderElement::setVolume(double volume)
+{
+ if (value().toDouble() != volume)
+ setValue(String::number(volume));
+}
+
+const AtomicString& MediaControlVolumeSliderElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider", AtomicString::ConstructFromLiteral));
return id;
@@ -552,14 +475,14 @@ const AtomicString& MediaControlPanelVolumeSliderElement::pseudo() const
// ----------------------------
-MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document& document)
- : MediaControlInputElement(document, MediaEnterFullscreenButton)
+MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(MediaControls& mediaControls)
+ : MediaControlInputElement(mediaControls, MediaEnterFullscreenButton)
{
}
-PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(document));
+ RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> button = adoptRefWillBeNoop(new MediaControlFullscreenButtonElement(mediaControls));
button->ensureUserAgentShadowRoot();
button->setType("button");
button->hide();
@@ -569,24 +492,16 @@ PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElem
void MediaControlFullscreenButtonElement::defaultEventHandler(Event* event)
{
if (event->type() == EventTypeNames::click) {
- // Only use the new full screen API if the fullScreenEnabled setting has
- // been explicitly enabled. Otherwise, use the old fullscreen API. This
- // allows apps which embed a WebView to retain the existing full screen
- // video implementation without requiring them to implement their own full
- // screen behavior.
- if (document().settings() && document().settings()->fullScreenEnabled()) {
- if (FullscreenElementStack::isActiveFullScreenElement(toParentMediaElement(this)))
- FullscreenElementStack::from(&document())->webkitCancelFullScreen();
- else
- FullscreenElementStack::from(&document())->requestFullScreenForElement(toParentMediaElement(this), 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
- } else
- mediaController()->enterFullscreen();
+ if (FullscreenElementStack::isActiveFullScreenElement(&mediaElement()))
+ FullscreenElementStack::from(document()).webkitCancelFullScreen();
+ else
+ FullscreenElementStack::from(document()).requestFullScreenForElement(&mediaElement(), 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
event->setDefaultHandled();
}
HTMLInputElement::defaultEventHandler(event);
}
-const AtomicString& MediaControlFullscreenButtonElement::pseudo() const
+const AtomicString& MediaControlFullscreenButtonElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-fullscreen-button", AtomicString::ConstructFromLiteral));
return id;
@@ -599,14 +514,14 @@ void MediaControlFullscreenButtonElement::setIsFullscreen(bool isFullscreen)
// ----------------------------
-MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(Document& document)
- : MediaControlTimeDisplayElement(document, MediaTimeRemainingDisplay)
+MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(MediaControls& mediaControls)
+ : MediaControlTimeDisplayElement(mediaControls, MediaTimeRemainingDisplay)
{
}
-PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlTimeRemainingDisplayElement(document));
+ return adoptRefWillBeNoop(new MediaControlTimeRemainingDisplayElement(mediaControls));
}
static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId()
@@ -615,21 +530,21 @@ static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseud
return id;
}
-const AtomicString& MediaControlTimeRemainingDisplayElement::pseudo() const
+const AtomicString& MediaControlTimeRemainingDisplayElement::shadowPseudoId() const
{
return getMediaControlTimeRemainingDisplayElementShadowPseudoId();
}
// ----------------------------
-MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(Document& document)
- : MediaControlTimeDisplayElement(document, MediaCurrentTimeDisplay)
+MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(MediaControls& mediaControls)
+ : MediaControlTimeDisplayElement(mediaControls, MediaCurrentTimeDisplay)
{
}
-PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(MediaControls& mediaControls)
{
- return adoptRef(new MediaControlCurrentTimeDisplayElement(document));
+ return adoptRefWillBeNoop(new MediaControlCurrentTimeDisplayElement(mediaControls));
}
static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId()
@@ -638,22 +553,22 @@ static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoI
return id;
}
-const AtomicString& MediaControlCurrentTimeDisplayElement::pseudo() const
+const AtomicString& MediaControlCurrentTimeDisplayElement::shadowPseudoId() const
{
return getMediaControlCurrentTimeDisplayElementShadowPseudoId();
}
// ----------------------------
-MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(Document& document)
- : MediaControlDivElement(document, MediaTextTrackDisplayContainer)
+MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(MediaControls& mediaControls)
+ : MediaControlDivElement(mediaControls, MediaTextTrackDisplayContainer)
, m_fontSize(0)
{
}
-PassRefPtr<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(MediaControls& mediaControls)
{
- RefPtr<MediaControlTextTrackContainerElement> element = adoptRef(new MediaControlTextTrackContainerElement(document));
+ RefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> element = adoptRefWillBeNoop(new MediaControlTextTrackContainerElement(mediaControls));
element->hide();
return element.release();
}
@@ -669,30 +584,28 @@ const AtomicString& MediaControlTextTrackContainerElement::textTrackContainerEle
return id;
}
-const AtomicString& MediaControlTextTrackContainerElement::pseudo() const
+const AtomicString& MediaControlTextTrackContainerElement::shadowPseudoId() const
{
return textTrackContainerElementShadowPseudoId();
}
void MediaControlTextTrackContainerElement::updateDisplay()
{
- if (!mediaController()->closedCaptionsVisible()) {
+ if (!mediaElement().closedCaptionsVisible()) {
removeChildren();
return;
}
- HTMLMediaElement* mediaElement = toParentMediaElement(this);
// 1. If the media element is an audio element, or is another playback
// mechanism with no rendering area, abort these steps. There is nothing to
// render.
- if (!mediaElement || !mediaElement->isVideo())
+ if (isHTMLAudioElement(mediaElement()))
return;
// 2. Let video be the media element or other playback mechanism.
- HTMLVideoElement* video = toHTMLVideoElement(mediaElement);
+ HTMLVideoElement& video = toHTMLVideoElement(mediaElement());
// 3. Let output be an empty list of absolutely positioned CSS block boxes.
- Vector<RefPtr<HTMLDivElement> > output;
// 4. If the user agent is exposing a user interface for video, add to
// output one or more completely transparent positioned CSS block boxes that
@@ -713,7 +626,7 @@ void MediaControlTextTrackContainerElement::updateDisplay()
// 7. Let cues be an empty list of text track cues.
// 8. For each track track in tracks, append to cues all the cues from
// track's list of cues that have their text track cue active flag set.
- CueList activeCues = video->currentlyActiveCues();
+ CueList activeCues = video.currentlyActiveCues();
// 9. If reset is false, then, for each text track cue cue in cues: if cue's
// text track cue display state has a set of CSS boxes, then add those boxes
@@ -737,28 +650,24 @@ void MediaControlTextTrackContainerElement::updateDisplay()
}
// 11. Return output.
- if (hasChildNodes())
+ if (hasChildren())
show();
else
hide();
}
-void MediaControlTextTrackContainerElement::updateSizes(bool forceUpdate)
+void MediaControlTextTrackContainerElement::updateSizes()
{
- HTMLMediaElement* mediaElement = toParentMediaElement(this);
- if (!mediaElement)
- return;
-
if (!document().isActive())
return;
IntRect videoBox;
- if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo())
+ if (!mediaElement().renderer() || !mediaElement().renderer()->isVideo())
return;
- videoBox = toRenderVideo(mediaElement->renderer())->videoBox();
+ videoBox = toRenderVideo(mediaElement().renderer())->videoBox();
- if (!forceUpdate && m_videoDisplaySize == videoBox)
+ if (m_videoDisplaySize == videoBox)
return;
m_videoDisplaySize = videoBox;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h
index 3d631dbb9b9..06c03206b75 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlElements.h
@@ -38,40 +38,25 @@ namespace WebCore {
class MediaControlPanelElement FINAL : public MediaControlDivElement {
public:
- static PassRefPtr<MediaControlPanelElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlPanelElement> create(MediaControls&);
- void setCanBeDragged(bool);
void setIsDisplayed(bool);
- void resetPosition();
void makeOpaque();
void makeTransparent();
- virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
- virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
-
private:
- explicit MediaControlPanelElement(Document&);
+ explicit MediaControlPanelElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
- void startDrag(const LayoutPoint& eventLocation);
- void continueDrag(const LayoutPoint& eventLocation);
- void endDrag();
-
void startTimer();
void stopTimer();
void transitionTimerFired(Timer<MediaControlPanelElement>*);
- void setPosition(const LayoutPoint&);
-
- bool m_canBeDragged;
- bool m_isBeingDragged;
bool m_isDisplayed;
bool m_opaque;
- LayoutPoint m_lastDragEventLocation;
- LayoutPoint m_cumulativeDragOffset;
Timer<MediaControlPanelElement> m_transitionTimer;
};
@@ -80,66 +65,53 @@ private:
class MediaControlPanelEnclosureElement FINAL : public MediaControlDivElement {
public:
- static PassRefPtr<MediaControlPanelEnclosureElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> create(MediaControls&);
private:
- explicit MediaControlPanelEnclosureElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlPanelEnclosureElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
// ----------------------------
class MediaControlOverlayEnclosureElement FINAL : public MediaControlDivElement {
public:
- static PassRefPtr<MediaControlOverlayEnclosureElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> create(MediaControls&);
private:
- explicit MediaControlOverlayEnclosureElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlOverlayEnclosureElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
// ----------------------------
-class MediaControlPanelMuteButtonElement FINAL : public MediaControlMuteButtonElement {
+class MediaControlMuteButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlPanelMuteButtonElement> create(Document&, MediaControls*);
+ static PassRefPtrWillBeRawPtr<MediaControlMuteButtonElement> create(MediaControls&);
- virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
+ virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
+ virtual void updateDisplayType() OVERRIDE;
private:
- explicit MediaControlPanelMuteButtonElement(Document&, MediaControls*);
+ explicit MediaControlMuteButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
-
- MediaControls* m_controls;
-};
-
-// ----------------------------
-
-class MediaControlVolumeSliderMuteButtonElement FINAL : public MediaControlMuteButtonElement {
-public:
- static PassRefPtr<MediaControlVolumeSliderMuteButtonElement> create(Document&);
-
-private:
- explicit MediaControlVolumeSliderMuteButtonElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
};
-
// ----------------------------
class MediaControlPlayButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlPlayButtonElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlPlayButtonElement> create(MediaControls&);
virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
virtual void updateDisplayType() OVERRIDE;
private:
- explicit MediaControlPlayButtonElement(Document&);
+ explicit MediaControlPlayButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
@@ -147,14 +119,14 @@ private:
class MediaControlOverlayPlayButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlOverlayPlayButtonElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> create(MediaControls&);
virtual void updateDisplayType() OVERRIDE;
private:
- explicit MediaControlOverlayPlayButtonElement(Document&);
+ explicit MediaControlOverlayPlayButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
@@ -162,16 +134,16 @@ private:
class MediaControlToggleClosedCaptionsButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(Document&, MediaControls*);
+ static PassRefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> create(MediaControls&);
virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
virtual void updateDisplayType() OVERRIDE;
private:
- explicit MediaControlToggleClosedCaptionsButtonElement(Document&, MediaControls*);
+ explicit MediaControlToggleClosedCaptionsButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
@@ -179,87 +151,93 @@ private:
class MediaControlTimelineElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlTimelineElement> create(Document&, MediaControls*);
+ static PassRefPtrWillBeRawPtr<MediaControlTimelineElement> create(MediaControls&);
virtual bool willRespondToMouseClickEvents() OVERRIDE;
+ // FIXME: An "earliest possible position" will be needed once that concept
+ // is supported by HTMLMediaElement, see https://crbug.com/137275
void setPosition(double);
void setDuration(double);
private:
- explicit MediaControlTimelineElement(Document&, MediaControls*);
+ explicit MediaControlTimelineElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
-
- MediaControls* m_controls;
};
// ----------------------------
class MediaControlFullscreenButtonElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlFullscreenButtonElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> create(MediaControls&);
virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
- virtual void setIsFullscreen(bool);
+ void setIsFullscreen(bool);
private:
- explicit MediaControlFullscreenButtonElement(Document&);
+ explicit MediaControlFullscreenButtonElement(MediaControls&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual void defaultEventHandler(Event*) OVERRIDE;
};
// ----------------------------
-class MediaControlPanelVolumeSliderElement FINAL : public MediaControlVolumeSliderElement {
+class MediaControlVolumeSliderElement FINAL : public MediaControlInputElement {
public:
- static PassRefPtr<MediaControlPanelVolumeSliderElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlVolumeSliderElement> create(MediaControls&);
+
+ virtual bool willRespondToMouseMoveEvents() OVERRIDE;
+ virtual bool willRespondToMouseClickEvents() OVERRIDE;
+ void setVolume(double);
private:
- explicit MediaControlPanelVolumeSliderElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlVolumeSliderElement(MediaControls&);
+
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
+ virtual void defaultEventHandler(Event*) OVERRIDE;
};
// ----------------------------
class MediaControlTimeRemainingDisplayElement FINAL : public MediaControlTimeDisplayElement {
public:
- static PassRefPtr<MediaControlTimeRemainingDisplayElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> create(MediaControls&);
private:
- explicit MediaControlTimeRemainingDisplayElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlTimeRemainingDisplayElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
// ----------------------------
class MediaControlCurrentTimeDisplayElement FINAL : public MediaControlTimeDisplayElement {
public:
- static PassRefPtr<MediaControlCurrentTimeDisplayElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> create(MediaControls&);
private:
- explicit MediaControlCurrentTimeDisplayElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlCurrentTimeDisplayElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
// ----------------------------
class MediaControlTextTrackContainerElement FINAL : public MediaControlDivElement {
public:
- static PassRefPtr<MediaControlTextTrackContainerElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> create(MediaControls&);
void updateDisplay();
- void updateSizes(bool forceUpdate = false);
+ void updateSizes();
static const AtomicString& textTrackContainerElementShadowPseudoId();
private:
- explicit MediaControlTextTrackContainerElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit MediaControlTextTrackContainerElement(MediaControls&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
IntRect m_videoDisplaySize;
float m_fontSize;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
index 0e2fa811fba..a82cf61a972 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
@@ -28,118 +28,162 @@
#include "core/html/shadow/MediaControls.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/events/MouseEvent.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/MediaController.h"
+#include "core/rendering/RenderTheme.h"
namespace WebCore {
-static const double timeWithoutMouseMovementBeforeHidingFullscreenControls = 3;
-
-MediaControls::MediaControls(Document& document)
- : HTMLDivElement(document)
- , m_mediaController(0)
- , m_panel(0)
- , m_textDisplayContainer(0)
- , m_playButton(0)
- , m_currentTimeDisplay(0)
- , m_timeline(0)
- , m_panelMuteButton(0)
- , m_volumeSlider(0)
- , m_toggleClosedCaptionsButton(0)
- , m_fullScreenButton(0)
- , m_hideFullscreenControlsTimer(this, &MediaControls::hideFullscreenControlsTimerFired)
- , m_isFullscreen(false)
+// If you change this value, then also update the corresponding value in
+// LayoutTests/media/media-controls.js.
+static const double timeWithoutMouseMovementBeforeHidingMediaControls = 3;
+
+MediaControls::MediaControls(HTMLMediaElement& mediaElement)
+ : HTMLDivElement(mediaElement.document())
+ , m_mediaElement(&mediaElement)
+ , m_panel(nullptr)
+ , m_textDisplayContainer(nullptr)
+ , m_overlayPlayButton(nullptr)
+ , m_overlayEnclosure(nullptr)
+ , m_playButton(nullptr)
+ , m_currentTimeDisplay(nullptr)
+ , m_timeline(nullptr)
+ , m_muteButton(nullptr)
+ , m_volumeSlider(nullptr)
+ , m_toggleClosedCaptionsButton(nullptr)
+ , m_fullScreenButton(nullptr)
+ , m_durationDisplay(nullptr)
+ , m_enclosure(nullptr)
+ , m_hideMediaControlsTimer(this, &MediaControls::hideMediaControlsTimerFired)
, m_isMouseOverControls(false)
+ , m_isPausedForScrubbing(false)
{
}
-void MediaControls::setMediaController(MediaControllerInterface* controller)
+PassRefPtrWillBeRawPtr<MediaControls> MediaControls::create(HTMLMediaElement& mediaElement)
{
- if (m_mediaController == controller)
- return;
- m_mediaController = controller;
+ RefPtrWillBeRawPtr<MediaControls> controls = adoptRefWillBeNoop(new MediaControls(mediaElement));
- if (m_panel)
- m_panel->setMediaController(controller);
- if (m_textDisplayContainer)
- m_textDisplayContainer->setMediaController(controller);
- if (m_playButton)
- m_playButton->setMediaController(controller);
- if (m_currentTimeDisplay)
- m_currentTimeDisplay->setMediaController(controller);
- if (m_timeline)
- m_timeline->setMediaController(controller);
- if (m_panelMuteButton)
- m_panelMuteButton->setMediaController(controller);
- if (m_volumeSlider)
- m_volumeSlider->setMediaController(controller);
- if (m_toggleClosedCaptionsButton)
- m_toggleClosedCaptionsButton->setMediaController(controller);
- if (m_fullScreenButton)
- m_fullScreenButton->setMediaController(controller);
+ if (controls->initializeControls())
+ return controls.release();
+
+ return nullptr;
}
-void MediaControls::reset()
+bool MediaControls::initializeControls()
{
- Page* page = document().page();
- if (!page)
- return;
+ TrackExceptionState exceptionState;
- m_playButton->updateDisplayType();
+ if (document().settings() && document().settings()->mediaControlsOverlayPlayButtonEnabled()) {
+ RefPtrWillBeRawPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(*this);
+ RefPtrWillBeRawPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(*this);
+ m_overlayPlayButton = overlayPlayButton.get();
+ overlayEnclosure->appendChild(overlayPlayButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
- updateCurrentTimeDisplay();
-
- double duration = m_mediaController->duration();
- if (std::isfinite(duration) || RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaSliderPart)) {
- m_timeline->setDuration(duration);
- m_timeline->setPosition(m_mediaController->currentTime());
+ m_overlayEnclosure = overlayEnclosure.get();
+ appendChild(overlayEnclosure.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
}
- if (m_mediaController->hasAudio() || RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaMuteButtonPart))
- m_panelMuteButton->show();
- else
- m_panelMuteButton->hide();
-
- if (m_volumeSlider) {
- if (!m_mediaController->hasAudio())
- m_volumeSlider->hide();
- else {
- m_volumeSlider->show();
- m_volumeSlider->setVolume(m_mediaController->volume());
- }
- }
+ // Create an enclosing element for the panel so we can visually offset the controls correctly.
+ RefPtrWillBeRawPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(*this);
- refreshClosedCaptionsButtonVisibility();
+ RefPtrWillBeRawPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(*this);
- if (m_fullScreenButton) {
- if (m_mediaController->supportsFullscreen() && m_mediaController->hasVideo())
- m_fullScreenButton->show();
- else
- m_fullScreenButton->hide();
- }
+ RefPtrWillBeRawPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(*this);
+ m_playButton = playButton.get();
+ panel->appendChild(playButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
- makeOpaque();
+ RefPtrWillBeRawPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(*this);
+ m_timeline = timeline.get();
+ panel->appendChild(timeline.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this);
+ m_currentTimeDisplay = currentTimeDisplay.get();
+ m_currentTimeDisplay->hide();
+ panel->appendChild(currentTimeDisplay.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this);
+ m_durationDisplay = durationDisplay.get();
+ panel->appendChild(durationDisplay.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlMuteButtonElement> muteButton = MediaControlMuteButtonElement::create(*this);
+ m_muteButton = muteButton.get();
+ panel->appendChild(muteButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(*this);
+ m_volumeSlider = slider.get();
+ panel->appendChild(slider.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this);
+ m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
+ panel->appendChild(toggleClosedCaptionsButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ RefPtrWillBeRawPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(*this);
+ m_fullScreenButton = fullscreenButton.get();
+ panel->appendChild(fullscreenButton.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ m_panel = panel.get();
+ enclosure->appendChild(panel.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ m_enclosure = enclosure.get();
+ appendChild(enclosure.release(), exceptionState);
+ if (exceptionState.hadException())
+ return false;
+
+ return true;
}
-void MediaControls::reportedError()
+void MediaControls::reset()
{
- Page* page = document().page();
- if (!page)
- return;
+ double duration = mediaElement().duration();
+ m_durationDisplay->setInnerText(RenderTheme::theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION);
+ m_durationDisplay->setCurrentValue(duration);
+
+ updatePlayState();
+
+ updateCurrentTimeDisplay();
- if (!RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaMuteButtonPart)) {
- m_panelMuteButton->hide();
+ m_timeline->setDuration(duration);
+ m_timeline->setPosition(mediaElement().currentTime());
+
+ if (!mediaElement().hasAudio())
m_volumeSlider->hide();
- }
+ else
+ m_volumeSlider->show();
+ updateVolume();
- if (m_toggleClosedCaptionsButton && !RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaToggleClosedCaptionsButtonPart))
- m_toggleClosedCaptionsButton->hide();
+ refreshClosedCaptionsButtonVisibility();
- if (m_fullScreenButton && !RenderTheme::theme().hasOwnDisabledStateHandlingFor(MediaEnterFullscreenButtonPart))
+ if (mediaElement().hasVideo())
+ m_fullScreenButton->show();
+ else
m_fullScreenButton->hide();
-}
-void MediaControls::loadedMetadata()
-{
- reset();
+ makeOpaque();
}
void MediaControls::show()
@@ -149,6 +193,12 @@ void MediaControls::show()
m_panel->show();
}
+void MediaControls::mediaElementFocused()
+{
+ show();
+ stopHideMediaControlsTimer();
+}
+
void MediaControls::hide()
{
m_panel->setIsDisplayed(false);
@@ -165,81 +215,118 @@ void MediaControls::makeTransparent()
m_panel->makeTransparent();
}
-bool MediaControls::shouldHideControls()
+bool MediaControls::shouldHideMediaControls(unsigned behaviorFlags) const
{
- return !m_panel->hovered();
-}
-
-void MediaControls::bufferingProgressed()
-{
- // We only need to update buffering progress when paused, during normal
- // playback playbackProgressed() will take care of it.
- if (m_mediaController->paused())
- m_timeline->setPosition(m_mediaController->currentTime());
+ // Never hide for a media element without visual representation.
+ if (!mediaElement().hasVideo())
+ return false;
+ // Don't hide if the controls are hovered or the mouse is over the video area.
+ const bool ignoreVideoHover = behaviorFlags & IgnoreVideoHover;
+ if (m_panel->hovered() || (!ignoreVideoHover && m_isMouseOverControls))
+ return false;
+ // Don't hide if focus is on the HTMLMediaElement or within the
+ // controls/shadow tree. (Perform the checks separately to avoid going
+ // through all the potential ancestor hosts for the focused element.)
+ const bool ignoreFocus = behaviorFlags & IgnoreFocus;
+ if (!ignoreFocus && (mediaElement().focused() || contains(document().focusedElement())))
+ return false;
+ return true;
}
void MediaControls::playbackStarted()
{
- m_playButton->updateDisplayType();
- m_timeline->setPosition(m_mediaController->currentTime());
+ m_currentTimeDisplay->show();
+ m_durationDisplay->hide();
+
+ updatePlayState();
+ m_timeline->setPosition(mediaElement().currentTime());
updateCurrentTimeDisplay();
- if (m_isFullscreen)
- startHideFullscreenControlsTimer();
+ startHideMediaControlsTimer();
}
void MediaControls::playbackProgressed()
{
- m_timeline->setPosition(m_mediaController->currentTime());
+ m_timeline->setPosition(mediaElement().currentTime());
updateCurrentTimeDisplay();
- if (!m_isMouseOverControls && m_mediaController->hasVideo())
+ if (shouldHideMediaControls())
makeTransparent();
}
void MediaControls::playbackStopped()
{
- m_playButton->updateDisplayType();
- m_timeline->setPosition(m_mediaController->currentTime());
+ updatePlayState();
+ m_timeline->setPosition(mediaElement().currentTime());
updateCurrentTimeDisplay();
makeOpaque();
- stopHideFullscreenControlsTimer();
+ stopHideMediaControlsTimer();
}
-void MediaControls::showVolumeSlider()
+void MediaControls::updatePlayState()
{
- if (!m_mediaController->hasAudio())
+ if (m_isPausedForScrubbing)
return;
- m_volumeSlider->show();
+ if (m_overlayPlayButton)
+ m_overlayPlayButton->updateDisplayType();
+ m_playButton->updateDisplayType();
}
-void MediaControls::changedMute()
+void MediaControls::beginScrubbing()
{
- m_panelMuteButton->changedMute();
+ if (!mediaElement().togglePlayStateWillPlay()) {
+ m_isPausedForScrubbing = true;
+ mediaElement().togglePlayState();
+ }
}
-void MediaControls::changedVolume()
+void MediaControls::endScrubbing()
{
- if (m_volumeSlider)
- m_volumeSlider->setVolume(m_mediaController->volume());
- if (m_panelMuteButton && m_panelMuteButton->renderer())
- m_panelMuteButton->renderer()->repaint();
+ if (m_isPausedForScrubbing) {
+ m_isPausedForScrubbing = false;
+ if (mediaElement().togglePlayStateWillPlay())
+ mediaElement().togglePlayState();
+ }
+}
+
+void MediaControls::updateCurrentTimeDisplay()
+{
+ double now = mediaElement().currentTime();
+ double duration = mediaElement().duration();
+
+ // After seek, hide duration display and show current time.
+ if (now > 0) {
+ m_currentTimeDisplay->show();
+ m_durationDisplay->hide();
+ }
+
+ // Allow the theme to format the time.
+ m_currentTimeDisplay->setInnerText(RenderTheme::theme().formatMediaControlsCurrentTime(now, duration), IGNORE_EXCEPTION);
+ m_currentTimeDisplay->setCurrentValue(now);
+}
+
+void MediaControls::updateVolume()
+{
+ m_muteButton->updateDisplayType();
+ if (m_muteButton->renderer())
+ m_muteButton->renderer()->paintInvalidationForWholeRenderer();
+
+ if (mediaElement().muted())
+ m_volumeSlider->setVolume(0);
+ else
+ m_volumeSlider->setVolume(mediaElement().volume());
}
void MediaControls::changedClosedCaptionsVisibility()
{
- if (m_toggleClosedCaptionsButton)
- m_toggleClosedCaptionsButton->updateDisplayType();
+ m_toggleClosedCaptionsButton->updateDisplayType();
}
void MediaControls::refreshClosedCaptionsButtonVisibility()
{
- if (!m_toggleClosedCaptionsButton)
- return;
-
- if (m_mediaController->hasClosedCaptions())
+ if (mediaElement().hasClosedCaptions())
m_toggleClosedCaptionsButton->show();
else
m_toggleClosedCaptionsButton->hide();
@@ -252,16 +339,16 @@ void MediaControls::closedCaptionTracksChanged()
void MediaControls::enteredFullscreen()
{
- m_isFullscreen = true;
m_fullScreenButton->setIsFullscreen(true);
- startHideFullscreenControlsTimer();
+ stopHideMediaControlsTimer();
+ startHideMediaControlsTimer();
}
void MediaControls::exitedFullscreen()
{
- m_isFullscreen = false;
m_fullScreenButton->setIsFullscreen(false);
- stopHideFullscreenControlsTimer();
+ stopHideMediaControlsTimer();
+ startHideMediaControlsTimer();
}
void MediaControls::defaultEventHandler(Event* event)
@@ -271,10 +358,10 @@ void MediaControls::defaultEventHandler(Event* event)
if (event->type() == EventTypeNames::mouseover) {
if (!containsRelatedTarget(event)) {
m_isMouseOverControls = true;
- if (!m_mediaController->canPlay()) {
+ if (!mediaElement().togglePlayStateWillPlay()) {
makeOpaque();
- if (shouldHideControls())
- startHideFullscreenControlsTimer();
+ if (shouldHideMediaControls())
+ startHideMediaControlsTimer();
}
}
return;
@@ -283,55 +370,43 @@ void MediaControls::defaultEventHandler(Event* event)
if (event->type() == EventTypeNames::mouseout) {
if (!containsRelatedTarget(event)) {
m_isMouseOverControls = false;
- stopHideFullscreenControlsTimer();
+ stopHideMediaControlsTimer();
}
return;
}
if (event->type() == EventTypeNames::mousemove) {
- if (m_isFullscreen) {
- // When we get a mouse move in fullscreen mode, show the media controls, and start a timer
- // that will hide the media controls after a 3 seconds without a mouse move.
- makeOpaque();
- if (shouldHideControls())
- startHideFullscreenControlsTimer();
- }
+ // When we get a mouse move, show the media controls, and start a timer
+ // that will hide the media controls after a 3 seconds without a mouse move.
+ makeOpaque();
+ if (shouldHideMediaControls(IgnoreVideoHover))
+ startHideMediaControlsTimer();
return;
}
}
-void MediaControls::hideFullscreenControlsTimerFired(Timer<MediaControls>*)
+void MediaControls::hideMediaControlsTimerFired(Timer<MediaControls>*)
{
- if (m_mediaController->paused())
+ if (mediaElement().togglePlayStateWillPlay())
return;
- if (!m_isFullscreen)
- return;
-
- if (!shouldHideControls())
+ if (!shouldHideMediaControls(IgnoreFocus | IgnoreVideoHover))
return;
makeTransparent();
}
-void MediaControls::startHideFullscreenControlsTimer()
+void MediaControls::startHideMediaControlsTimer()
{
- if (!m_isFullscreen)
- return;
-
- Page* page = document().page();
- if (!page)
- return;
-
- m_hideFullscreenControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingFullscreenControls);
+ m_hideMediaControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingMediaControls, FROM_HERE);
}
-void MediaControls::stopHideFullscreenControlsTimer()
+void MediaControls::stopHideMediaControlsTimer()
{
- m_hideFullscreenControlsTimer.stop();
+ m_hideMediaControlsTimer.stop();
}
-const AtomicString& MediaControls::pseudo() const
+const AtomicString& MediaControls::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls"));
return id;
@@ -352,14 +427,14 @@ void MediaControls::createTextTrackDisplay()
if (m_textDisplayContainer)
return;
- RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document());
+ RefPtrWillBeRawPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(*this);
m_textDisplayContainer = textDisplayContainer.get();
- if (m_mediaController)
- m_textDisplayContainer->setMediaController(m_mediaController);
-
- // Insert it before the first controller element so it always displays behind the controls.
- insertBefore(textDisplayContainer.release(), m_panel, IGNORE_EXCEPTION);
+ // Insert it before (behind) all other control elements.
+ if (m_overlayEnclosure && m_overlayPlayButton)
+ m_overlayEnclosure->insertBefore(textDisplayContainer.release(), m_overlayPlayButton);
+ else
+ insertBefore(textDisplayContainer.release(), m_enclosure);
}
void MediaControls::showTextTrackDisplay()
@@ -384,4 +459,23 @@ void MediaControls::updateTextTrackDisplay()
m_textDisplayContainer->updateDisplay();
}
+void MediaControls::trace(Visitor* visitor)
+{
+ visitor->trace(m_mediaElement);
+ visitor->trace(m_panel);
+ visitor->trace(m_textDisplayContainer);
+ visitor->trace(m_overlayPlayButton);
+ visitor->trace(m_overlayEnclosure);
+ visitor->trace(m_playButton);
+ visitor->trace(m_currentTimeDisplay);
+ visitor->trace(m_timeline);
+ visitor->trace(m_muteButton);
+ visitor->trace(m_volumeSlider);
+ visitor->trace(m_toggleClosedCaptionsButton);
+ visitor->trace(m_fullScreenButton);
+ visitor->trace(m_durationDisplay);
+ visitor->trace(m_enclosure);
+ HTMLDivElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h
index ea87254a8e2..7879662b3cb 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControls.h
@@ -27,106 +27,109 @@
#ifndef MediaControls_h
#define MediaControls_h
-#include "core/events/MouseEvent.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/shadow/MediaControlElements.h"
-#include "core/rendering/RenderTheme.h"
namespace WebCore {
class Document;
class Event;
-class MediaPlayer;
-class RenderBox;
-class RenderMedia;
+class MediaControls FINAL : public HTMLDivElement {
+public:
+ static PassRefPtrWillBeRawPtr<MediaControls> create(HTMLMediaElement&);
-// An abstract class with the media control elements that all ports support.
-class MediaControls : public HTMLDivElement {
- public:
- virtual ~MediaControls() {}
+ HTMLMediaElement& mediaElement() const { return *m_mediaElement; }
- // This function is to be implemented in your port-specific media
- // controls implementation since it will return a child instance.
- static PassRefPtr<MediaControls> create(Document&);
+ void reset();
- virtual void setMediaController(MediaControllerInterface*);
+ void show();
+ void hide();
- virtual void reset();
- virtual void reportedError();
- virtual void loadedMetadata();
+ void playbackStarted();
+ void playbackProgressed();
+ void playbackStopped();
- virtual void show();
- virtual void hide();
- virtual void makeOpaque();
- virtual void makeTransparent();
- virtual bool shouldHideControls();
+ void beginScrubbing();
+ void endScrubbing();
- virtual void bufferingProgressed();
- virtual void playbackStarted();
- virtual void playbackProgressed();
- virtual void playbackStopped();
+ void updateCurrentTimeDisplay();
- virtual void updateStatusDisplay() { };
- virtual void updateCurrentTimeDisplay() = 0;
- virtual void showVolumeSlider();
+ void updateVolume();
- virtual void changedMute();
- virtual void changedVolume();
+ void changedClosedCaptionsVisibility();
+ void refreshClosedCaptionsButtonVisibility();
+ void closedCaptionTracksChanged();
- virtual void changedClosedCaptionsVisibility();
- virtual void refreshClosedCaptionsButtonVisibility();
- virtual void closedCaptionTracksChanged();
+ void enteredFullscreen();
+ void exitedFullscreen();
- virtual void enteredFullscreen();
- virtual void exitedFullscreen();
+ void updateTextTrackDisplay();
- virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
+ void mediaElementFocused();
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ explicit MediaControls(HTMLMediaElement&);
+
+ bool initializeControls();
- virtual void hideFullscreenControlsTimerFired(Timer<MediaControls>*);
- virtual void startHideFullscreenControlsTimer();
- virtual void stopHideFullscreenControlsTimer();
+ void makeOpaque();
+ void makeTransparent();
- virtual void createTextTrackDisplay();
- virtual void showTextTrackDisplay();
- virtual void hideTextTrackDisplay();
- virtual void updateTextTrackDisplay();
+ void updatePlayState();
-protected:
- explicit MediaControls(Document&);
+ enum HideBehaviorFlags {
+ IgnoreVideoHover = 1 << 0,
+ IgnoreFocus = 1 << 1
+ };
- virtual void defaultEventHandler(Event*);
+ bool shouldHideMediaControls(unsigned behaviorFlags = 0) const;
+ void hideMediaControlsTimerFired(Timer<MediaControls>*);
+ void startHideMediaControlsTimer();
+ void stopHideMediaControlsTimer();
- virtual bool containsRelatedTarget(Event*);
+ void createTextTrackDisplay();
+ void showTextTrackDisplay();
+ void hideTextTrackDisplay();
- MediaControllerInterface* m_mediaController;
+ // Node
+ virtual bool isMediaControls() const OVERRIDE { return true; }
+ virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
+ virtual void defaultEventHandler(Event*) OVERRIDE;
+ bool containsRelatedTarget(Event*);
+
+ // Element
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
+
+ RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
// Container for the media control elements.
- MediaControlPanelElement* m_panel;
+ RawPtrWillBeMember<MediaControlPanelElement> m_panel;
// Container for the text track cues.
- MediaControlTextTrackContainerElement* m_textDisplayContainer;
+ RawPtrWillBeMember<MediaControlTextTrackContainerElement> m_textDisplayContainer;
// Media control elements.
- MediaControlPlayButtonElement* m_playButton;
- MediaControlCurrentTimeDisplayElement* m_currentTimeDisplay;
- MediaControlTimelineElement* m_timeline;
- MediaControlPanelMuteButtonElement* m_panelMuteButton;
- MediaControlPanelVolumeSliderElement* m_volumeSlider;
- MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
- MediaControlFullscreenButtonElement* m_fullScreenButton;
-
- Timer<MediaControls> m_hideFullscreenControlsTimer;
- bool m_isFullscreen;
- bool m_isMouseOverControls;
-
-private:
- virtual bool isMediaControls() const { return true; }
-
- virtual const AtomicString& pseudo() const;
+ RawPtrWillBeMember<MediaControlOverlayPlayButtonElement> m_overlayPlayButton;
+ RawPtrWillBeMember<MediaControlOverlayEnclosureElement> m_overlayEnclosure;
+ RawPtrWillBeMember<MediaControlPlayButtonElement> m_playButton;
+ RawPtrWillBeMember<MediaControlCurrentTimeDisplayElement> m_currentTimeDisplay;
+ RawPtrWillBeMember<MediaControlTimelineElement> m_timeline;
+ RawPtrWillBeMember<MediaControlMuteButtonElement> m_muteButton;
+ RawPtrWillBeMember<MediaControlVolumeSliderElement> m_volumeSlider;
+ RawPtrWillBeMember<MediaControlToggleClosedCaptionsButtonElement> m_toggleClosedCaptionsButton;
+ RawPtrWillBeMember<MediaControlFullscreenButtonElement> m_fullScreenButton;
+ RawPtrWillBeMember<MediaControlTimeRemainingDisplayElement> m_durationDisplay;
+ RawPtrWillBeMember<MediaControlPanelEnclosureElement> m_enclosure;
+
+ Timer<MediaControls> m_hideMediaControlsTimer;
+ bool m_isMouseOverControls : 1;
+ bool m_isPausedForScrubbing : 1;
};
-DEFINE_NODE_TYPE_CASTS(MediaControls, isMediaControls());
+DEFINE_ELEMENT_TYPE_CASTS(MediaControls, isMediaControls());
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.cpp
deleted file mode 100644
index d1d4ccbfd40..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/shadow/MediaControlsChromium.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-
-using namespace std;
-
-namespace WebCore {
-
-MediaControlsChromium::MediaControlsChromium(Document& document)
- : MediaControls(document)
- , m_durationDisplay(0)
- , m_enclosure(0)
-{
-}
-
-// MediaControls::create() for Android is defined in MediaControlsChromiumAndroid.cpp.
-#if !OS(ANDROID)
-PassRefPtr<MediaControls> MediaControls::create(Document& document)
-{
- return MediaControlsChromium::createControls(document);
-}
-#endif
-
-PassRefPtr<MediaControlsChromium> MediaControlsChromium::createControls(Document& document)
-{
- if (!document.page())
- return 0;
-
- RefPtr<MediaControlsChromium> controls = adoptRef(new MediaControlsChromium(document));
-
- if (controls->initializeControls(document))
- return controls.release();
-
- return 0;
-}
-
-bool MediaControlsChromium::initializeControls(Document& document)
-{
- // Create an enclosing element for the panel so we can visually offset the controls correctly.
- RefPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(document);
-
- RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(document);
-
- TrackExceptionState exceptionState;
-
- RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(document);
- m_playButton = playButton.get();
- panel->appendChild(playButton.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(document, this);
- m_timeline = timeline.get();
- panel->appendChild(timeline.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(document);
- m_currentTimeDisplay = currentTimeDisplay.get();
- m_currentTimeDisplay->hide();
- panel->appendChild(currentTimeDisplay.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(document);
- m_durationDisplay = durationDisplay.get();
- panel->appendChild(durationDisplay.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(document, this);
- m_panelMuteButton = panelMuteButton.get();
- panel->appendChild(panelMuteButton.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- RefPtr<MediaControlPanelVolumeSliderElement> slider = MediaControlPanelVolumeSliderElement::create(document);
- m_volumeSlider = slider.get();
- m_volumeSlider->setClearMutedOnUserInteraction(true);
- panel->appendChild(slider.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- if (RenderTheme::theme().supportsClosedCaptioning()) {
- RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, this);
- m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
- panel->appendChild(toggleClosedCaptionsButton.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
- }
-
- RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(document);
- m_fullScreenButton = fullscreenButton.get();
- panel->appendChild(fullscreenButton.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- m_panel = panel.get();
- enclosure->appendChild(panel.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- m_enclosure = enclosure.get();
- appendChild(enclosure.release(), exceptionState);
- if (exceptionState.hadException())
- return false;
-
- return true;
-}
-
-void MediaControlsChromium::setMediaController(MediaControllerInterface* controller)
-{
- if (m_mediaController == controller)
- return;
-
- MediaControls::setMediaController(controller);
-
- if (m_durationDisplay)
- m_durationDisplay->setMediaController(controller);
- if (m_enclosure)
- m_enclosure->setMediaController(controller);
-}
-
-void MediaControlsChromium::reset()
-{
- Page* page = document().page();
- if (!page)
- return;
-
- double duration = m_mediaController->duration();
- m_durationDisplay->setInnerText(RenderTheme::theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION);
- m_durationDisplay->setCurrentValue(duration);
-
- MediaControls::reset();
-}
-
-void MediaControlsChromium::playbackStarted()
-{
- m_currentTimeDisplay->show();
- m_durationDisplay->hide();
-
- MediaControls::playbackStarted();
-}
-
-void MediaControlsChromium::updateCurrentTimeDisplay()
-{
- double now = m_mediaController->currentTime();
- double duration = m_mediaController->duration();
-
- Page* page = document().page();
- if (!page)
- return;
-
- // After seek, hide duration display and show current time.
- if (now > 0) {
- m_currentTimeDisplay->show();
- m_durationDisplay->hide();
- }
-
- // Allow the theme to format the time.
- m_currentTimeDisplay->setInnerText(RenderTheme::theme().formatMediaControlsCurrentTime(now, duration), IGNORE_EXCEPTION);
- m_currentTimeDisplay->setCurrentValue(now);
-}
-
-void MediaControlsChromium::changedMute()
-{
- MediaControls::changedMute();
-
- if (m_mediaController->muted())
- m_volumeSlider->setVolume(0);
- else
- m_volumeSlider->setVolume(m_mediaController->volume());
-}
-
-void MediaControlsChromium::createTextTrackDisplay()
-{
- if (m_textDisplayContainer)
- return;
-
- RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document());
- m_textDisplayContainer = textDisplayContainer.get();
-
- if (m_mediaController)
- m_textDisplayContainer->setMediaController(m_mediaController);
-
- insertTextTrackContainer(textDisplayContainer.release());
-}
-
-void MediaControlsChromium::insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement> textTrackContainer)
-{
- // Insert it before the first controller element so it always displays behind the controls.
- // In the Chromium case, that's the enclosure element.
- insertBefore(textTrackContainer, m_enclosure);
-}
-
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.h
deleted file mode 100644
index 5e3c55e8512..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromium.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaControlsChromium_h
-#define MediaControlsChromium_h
-
-#include "core/html/shadow/MediaControls.h"
-
-namespace WebCore {
-
-class MediaControlsChromium : public MediaControls {
-public:
- // Called from port-specific parent create function to create custom controls.
- static PassRefPtr<MediaControlsChromium> createControls(Document&);
-
- virtual void setMediaController(MediaControllerInterface*) OVERRIDE;
-
- virtual void reset() OVERRIDE;
-
- virtual void playbackStarted() OVERRIDE;
-
- void changedMute() OVERRIDE;
-
- virtual void updateCurrentTimeDisplay() OVERRIDE;
-
- void createTextTrackDisplay() OVERRIDE;
-
- virtual void insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement>);
-
-protected:
- explicit MediaControlsChromium(Document&);
-
- bool initializeControls(Document&);
-
-private:
- MediaControlTimeRemainingDisplayElement* m_durationDisplay;
- MediaControlPanelEnclosureElement* m_enclosure;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.cpp
deleted file mode 100644
index f81c9309b37..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/shadow/MediaControlsChromiumAndroid.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-
-namespace WebCore {
-
-MediaControlsChromiumAndroid::MediaControlsChromiumAndroid(Document& document)
- : MediaControlsChromium(document)
- , m_overlayPlayButton(0)
- , m_overlayEnclosure(0)
-{
-}
-
-PassRefPtr<MediaControls> MediaControls::create(Document& document)
-{
- return MediaControlsChromiumAndroid::createControls(document);
-}
-
-PassRefPtr<MediaControlsChromiumAndroid> MediaControlsChromiumAndroid::createControls(Document& document)
-{
- if (!document.page())
- return 0;
-
- RefPtr<MediaControlsChromiumAndroid> controls = adoptRef(new MediaControlsChromiumAndroid(document));
-
- TrackExceptionState exceptionState;
-
- RefPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(document);
- RefPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(document);
- controls->m_overlayPlayButton = overlayPlayButton.get();
- overlayEnclosure->appendChild(overlayPlayButton.release(), exceptionState);
- if (exceptionState.hadException())
- return 0;
-
- controls->m_overlayEnclosure = overlayEnclosure.get();
- controls->appendChild(overlayEnclosure.release(), exceptionState);
- if (exceptionState.hadException())
- return 0;
-
- if (controls->initializeControls(document))
- return controls.release();
-
- return 0;
-}
-
-void MediaControlsChromiumAndroid::setMediaController(MediaControllerInterface* controller)
-{
- if (m_overlayPlayButton)
- m_overlayPlayButton->setMediaController(controller);
- if (m_overlayEnclosure)
- m_overlayEnclosure->setMediaController(controller);
- MediaControlsChromium::setMediaController(controller);
-}
-
-void MediaControlsChromiumAndroid::playbackStarted()
-{
- m_overlayPlayButton->updateDisplayType();
- MediaControlsChromium::playbackStarted();
-}
-
-void MediaControlsChromiumAndroid::playbackStopped()
-{
- m_overlayPlayButton->updateDisplayType();
- MediaControlsChromium::playbackStopped();
-}
-
-void MediaControlsChromiumAndroid::insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement> textTrackContainer)
-{
- // Insert it before the overlay play button so it always displays behind it.
- m_overlayEnclosure->insertBefore(textTrackContainer, m_overlayPlayButton);
-}
-}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.h b/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.h
deleted file mode 100644
index 8b8a90069f4..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MediaControlsChromiumAndroid.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaControlsChromiumAndroid_h
-#define MediaControlsChromiumAndroid_h
-
-#include "core/html/shadow/MediaControls.h"
-#include "core/html/shadow/MediaControlsChromium.h"
-
-namespace WebCore {
-
-class MediaControlsChromiumAndroid : public MediaControlsChromium {
-public:
- static PassRefPtr<MediaControlsChromiumAndroid> createControls(Document&);
-
- virtual void setMediaController(MediaControllerInterface*) OVERRIDE;
- virtual void playbackStarted() OVERRIDE;
- virtual void playbackStopped() OVERRIDE;
- virtual bool shouldHideControls() OVERRIDE { return true; }
-
- void insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement>) OVERRIDE;
-
-private:
- explicit MediaControlsChromiumAndroid(Document&);
-
- MediaControlOverlayPlayButtonElement* m_overlayPlayButton;
- MediaControlOverlayEnclosureElement* m_overlayEnclosure;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp
index a39c29cdb71..8f8f0cc4671 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp
@@ -32,8 +32,8 @@
#include "core/html/shadow/MeterShadowElement.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLMeterElement.h"
#include "core/rendering/RenderMeter.h"
#include "core/rendering/RenderTheme.h"
@@ -63,10 +63,10 @@ inline MeterInnerElement::MeterInnerElement(Document& document)
{
}
-PassRefPtr<MeterInnerElement> MeterInnerElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MeterInnerElement> MeterInnerElement::create(Document& document)
{
- RefPtr<MeterInnerElement> element = adoptRef(new MeterInnerElement(document));
- element->setPseudo(AtomicString("-webkit-meter-inner-element", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<MeterInnerElement> element = adoptRefWillBeNoop(new MeterInnerElement(document));
+ element->setShadowPseudoId(AtomicString("-webkit-meter-inner-element", AtomicString::ConstructFromLiteral));
return element.release();
}
@@ -89,10 +89,10 @@ inline MeterBarElement::MeterBarElement(Document& document)
{
}
-PassRefPtr<MeterBarElement> MeterBarElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MeterBarElement> MeterBarElement::create(Document& document)
{
- RefPtr<MeterBarElement> element = adoptRef(new MeterBarElement(document));
- element->setPseudo(AtomicString("-webkit-meter-bar", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<MeterBarElement> element = adoptRefWillBeNoop(new MeterBarElement(document));
+ element->setShadowPseudoId(AtomicString("-webkit-meter-bar", AtomicString::ConstructFromLiteral));
return element.release();
}
@@ -101,9 +101,9 @@ inline MeterValueElement::MeterValueElement(Document& document)
{
}
-PassRefPtr<MeterValueElement> MeterValueElement::create(Document& document)
+PassRefPtrWillBeRawPtr<MeterValueElement> MeterValueElement::create(Document& document)
{
- RefPtr<MeterValueElement> element = adoptRef(new MeterValueElement(document));
+ RefPtrWillBeRawPtr<MeterValueElement> element = adoptRefWillBeNoop(new MeterValueElement(document));
element->updatePseudo();
return element.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h
index c15bfdcbcb7..22847f7a8f7 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/MeterShadowElement.h
@@ -41,39 +41,39 @@ class RenderMeter;
class MeterShadowElement : public HTMLDivElement {
protected:
- MeterShadowElement(Document&);
+ explicit MeterShadowElement(Document&);
HTMLMeterElement* meterElement() const;
private:
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
};
class MeterInnerElement FINAL : public MeterShadowElement {
public:
- static PassRefPtr<MeterInnerElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MeterInnerElement> create(Document&);
private:
- MeterInnerElement(Document&);
+ explicit MeterInnerElement(Document&);
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
class MeterBarElement FINAL : public MeterShadowElement {
private:
- MeterBarElement(Document&);
+ explicit MeterBarElement(Document&);
public:
- static PassRefPtr<MeterBarElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MeterBarElement> create(Document&);
};
class MeterValueElement FINAL : public MeterShadowElement {
public:
- static PassRefPtr<MeterValueElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<MeterValueElement> create(Document&);
void setWidthPercentage(double);
- void updatePseudo() { setPseudo(valuePseudoId()); }
+ void updatePseudo() { setShadowPseudoId(valuePseudoId()); }
private:
- MeterValueElement(Document&);
+ explicit MeterValueElement(Document&);
const AtomicString& valuePseudoId() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp
deleted file mode 100644
index 238c3f41aee..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/shadow/PasswordGeneratorButtonElement.h"
-
-#include "core/events/Event.h"
-#include "core/dom/NodeRenderStyle.h"
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLInputElement.h"
-#include "core/html/shadow/ShadowElementNames.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/page/Page.h"
-#include "core/rendering/RenderImage.h"
-#include "platform/graphics/Image.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-PasswordGeneratorButtonElement::PasswordGeneratorButtonElement(Document& document)
- : HTMLDivElement(document)
- , m_isInHoverState(false)
-{
- setHasCustomStyleCallbacks();
-}
-
-PassRefPtr<PasswordGeneratorButtonElement> PasswordGeneratorButtonElement::create(Document& document)
-{
- RefPtr<PasswordGeneratorButtonElement> element = adoptRef(new PasswordGeneratorButtonElement(document));
- element->setAttribute(idAttr, ShadowElementNames::passwordGenerator());
- return element.release();
-}
-
-inline HTMLInputElement* PasswordGeneratorButtonElement::hostInput()
-{
- // PasswordGeneratorButtonElement is created only by C++ code, and it is always
- // in <input> shadow.
- return toHTMLInputElement(shadowHost());
-}
-
-void PasswordGeneratorButtonElement::updateImage()
-{
- if (!renderer() || !renderer()->isImage())
- return;
- RenderImageResource* resource = toRenderImage(renderer())->imageResource();
- ImageResource* image = m_isInHoverState ? imageForHoverState() : imageForNormalState();
- ASSERT(image);
- resource->setImageResource(image);
-}
-
-PassRefPtr<RenderStyle> PasswordGeneratorButtonElement::customStyleForRenderer()
-{
- RefPtr<RenderStyle> originalStyle = originalStyleForRenderer();
- RefPtr<RenderStyle> style = RenderStyle::clone(originalStyle.get());
- RenderStyle* inputStyle = hostInput()->renderStyle();
- ASSERT(inputStyle);
- style->setWidth(Length(inputStyle->fontSize(), Fixed));
- style->setHeight(Length(inputStyle->fontSize(), Fixed));
- style->setUnique();
- updateImage();
- return style.release();
-}
-
-RenderObject* PasswordGeneratorButtonElement::createRenderer(RenderStyle*)
-{
- RenderImage* image = new RenderImage(this);
- image->setImageResource(RenderImageResource::create());
- return image;
-}
-
-void PasswordGeneratorButtonElement::attach(const AttachContext& context)
-{
- HTMLDivElement::attach(context);
- updateImage();
-}
-
-ImageResource* PasswordGeneratorButtonElement::imageForNormalState()
-{
- if (!m_cachedImageForNormalState) {
- RefPtr<Image> image = Image::loadPlatformResource("generatePassword");
- m_cachedImageForNormalState = new ImageResource(image.get());
- }
- return m_cachedImageForNormalState.get();
-}
-
-ImageResource* PasswordGeneratorButtonElement::imageForHoverState()
-{
- if (!m_cachedImageForHoverState) {
- RefPtr<Image> image = Image::loadPlatformResource("generatePasswordHover");
- m_cachedImageForHoverState = new ImageResource(image.get());
- }
- return m_cachedImageForHoverState.get();
-}
-
-void PasswordGeneratorButtonElement::defaultEventHandler(Event* event)
-{
- RefPtr<HTMLInputElement> input = hostInput();
- if (!input || input->isDisabledOrReadOnly() || !event->isMouseEvent()) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- RefPtr<PasswordGeneratorButtonElement> protector(this);
- if (event->type() == EventTypeNames::click) {
- if (Page* page = document().page())
- page->chrome().client().openPasswordGenerator(input.get());
- event->setDefaultHandled();
- }
-
- if (event->type() == EventTypeNames::mouseover) {
- m_isInHoverState = true;
- updateImage();
- }
-
- if (event->type() == EventTypeNames::mouseout) {
- m_isInHoverState = false;
- updateImage();
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-bool PasswordGeneratorButtonElement::willRespondToMouseMoveEvents()
-{
- const HTMLInputElement* input = hostInput();
- if (!input->isDisabledOrReadOnly())
- return true;
-
- return HTMLDivElement::willRespondToMouseMoveEvents();
-}
-
-bool PasswordGeneratorButtonElement::willRespondToMouseClickEvents()
-{
- const HTMLInputElement* input = hostInput();
- if (!input->isDisabledOrReadOnly())
- return true;
-
- return HTMLDivElement::willRespondToMouseClickEvents();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.h
deleted file mode 100644
index 0d220f9c6b1..00000000000
--- a/chromium/third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PasswordGeneratorButtonElement_h
-#define PasswordGeneratorButtonElement_h
-
-#include "core/fetch/ResourcePtr.h"
-#include "core/html/HTMLDivElement.h"
-
-namespace WebCore {
-
-class ImageResource;
-class HTMLInputElement;
-class ShadowRoot;
-
-class PasswordGeneratorButtonElement FINAL : public HTMLDivElement {
-public:
- static PassRefPtr<PasswordGeneratorButtonElement> create(Document&);
-
- void decorate(HTMLInputElement*);
-
- virtual bool willRespondToMouseMoveEvents() OVERRIDE;
- virtual bool willRespondToMouseClickEvents() OVERRIDE;
-
-private:
- PasswordGeneratorButtonElement(Document&);
- virtual bool isPasswordGeneratorButtonElement() const OVERRIDE { return true; }
- virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool isMouseFocusable() const OVERRIDE { return false; }
- virtual void defaultEventHandler(Event*) OVERRIDE;
-
- ImageResource* imageForNormalState();
- ImageResource* imageForHoverState();
-
- HTMLInputElement* hostInput();
- void updateImage();
-
- ResourcePtr<ImageResource> m_cachedImageForNormalState;
- ResourcePtr<ImageResource> m_cachedImageForHoverState;
- bool m_isInHoverState;
-};
-
-}
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp
index 40aec28a852..1c838a2683a 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.cpp
@@ -37,6 +37,7 @@
#include "core/page/Chrome.h"
#include "core/page/Page.h"
#include "core/rendering/RenderDetailsMarker.h"
+#include "wtf/TemporaryChange.h"
using namespace WTF::Unicode;
@@ -47,21 +48,20 @@ using namespace HTMLNames;
inline PickerIndicatorElement::PickerIndicatorElement(Document& document, PickerIndicatorOwner& pickerIndicatorOwner)
: HTMLDivElement(document)
, m_pickerIndicatorOwner(&pickerIndicatorOwner)
+ , m_isInOpenPopup(false)
{
}
-PassRefPtr<PickerIndicatorElement> PickerIndicatorElement::create(Document& document, PickerIndicatorOwner& pickerIndicatorOwner)
+PassRefPtrWillBeRawPtr<PickerIndicatorElement> PickerIndicatorElement::create(Document& document, PickerIndicatorOwner& pickerIndicatorOwner)
{
- RefPtr<PickerIndicatorElement> element = adoptRef(new PickerIndicatorElement(document, pickerIndicatorOwner));
- element->setPseudo(AtomicString("-webkit-calendar-picker-indicator", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<PickerIndicatorElement> element = adoptRefWillBeNoop(new PickerIndicatorElement(document, pickerIndicatorOwner));
+ element->setShadowPseudoId(AtomicString("-webkit-calendar-picker-indicator", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::pickerIndicator());
return element.release();
}
PickerIndicatorElement::~PickerIndicatorElement()
{
- closePopup();
- ASSERT(!m_chooser);
}
RenderObject* PickerIndicatorElement::createRenderer(RenderStyle*)
@@ -113,6 +113,12 @@ void PickerIndicatorElement::didEndChooser()
void PickerIndicatorElement::openPopup()
{
+ // The m_isInOpenPopup flag is unnecessary in production.
+ // MockPagePopupDriver allows to execute JavaScript code in
+ // DateTimeChooserImpl constructor. It might create another DateTimeChooser.
+ if (m_isInOpenPopup)
+ return;
+ TemporaryChange<bool> reentrancyProtector(m_isInOpenPopup, true);
if (m_chooser)
return;
if (!document().page())
@@ -143,6 +149,14 @@ bool PickerIndicatorElement::isPickerIndicatorElement() const
return true;
}
+void PickerIndicatorElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_pickerIndicatorOwner);
+ visitor->trace(m_chooser);
+ HTMLDivElement::trace(visitor);
+ DateTimeChooserClient::trace(visitor);
+}
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h
index 8b7a5e3d740..914fd9887d3 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/PickerIndicatorElement.h
@@ -42,10 +42,11 @@ class HTMLInputElement;
class PagePopup;
class PickerIndicatorElement FINAL : public HTMLDivElement, public DateTimeChooserClient {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(PickerIndicatorElement);
public:
// PickerIndicatorOwner implementer must call removePickerIndicatorOwner when
// it doesn't handle event, e.g. at destruction.
- class PickerIndicatorOwner {
+ class PickerIndicatorOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~PickerIndicatorOwner() { }
virtual bool isPickerIndicatorOwnerDisabledOrReadOnly() const = 0;
@@ -55,12 +56,14 @@ public:
virtual bool setupDateTimeChooserParameters(DateTimeChooserParameters&) = 0;
};
- static PassRefPtr<PickerIndicatorElement> create(Document&, PickerIndicatorOwner&);
+ static PassRefPtrWillBeRawPtr<PickerIndicatorElement> create(Document&, PickerIndicatorOwner&);
virtual ~PickerIndicatorElement();
+ virtual void trace(Visitor*) OVERRIDE;
+
void openPopup();
void closePopup();
virtual bool willRespondToMouseClickEvents() OVERRIDE;
- void removePickerIndicatorOwner() { m_pickerIndicatorOwner = 0; }
+ void removePickerIndicatorOwner() { m_pickerIndicatorOwner = nullptr; }
// DateTimeChooserClient implementation.
virtual void didChooseValue(const String&) OVERRIDE;
@@ -76,8 +79,9 @@ private:
HTMLInputElement* hostInput();
- PickerIndicatorOwner* m_pickerIndicatorOwner;
- RefPtr<DateTimeChooser> m_chooser;
+ RawPtrWillBeMember<PickerIndicatorOwner> m_pickerIndicatorOwner;
+ RefPtrWillBeMember<DateTimeChooser> m_chooser;
+ bool m_isInOpenPopup;
};
DEFINE_TYPE_CASTS(PickerIndicatorElement, Element, element, element->isPickerIndicatorElement(), element.isPickerIndicatorElement());
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp
index 50c8d1dc9a4..0f8b72f069c 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp
@@ -32,7 +32,7 @@
#include "core/html/shadow/ProgressShadowElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLProgressElement.h"
#include "core/rendering/RenderProgress.h"
@@ -56,11 +56,13 @@ bool ProgressShadowElement::rendererIsNeeded(const RenderStyle& style)
return progressRenderer && !progressRenderer->style()->hasAppearance() && HTMLDivElement::rendererIsNeeded(style);
}
-ProgressInnerElement::ProgressInnerElement(Document& document)
+inline ProgressInnerElement::ProgressInnerElement(Document& document)
: ProgressShadowElement(document)
{
}
+DEFINE_NODE_FACTORY(ProgressInnerElement)
+
RenderObject* ProgressInnerElement::createRenderer(RenderStyle*)
{
return new RenderProgress(this);
@@ -75,11 +77,13 @@ bool ProgressInnerElement::rendererIsNeeded(const RenderStyle& style)
return progressRenderer && !progressRenderer->style()->hasAppearance() && HTMLDivElement::rendererIsNeeded(style);
}
-ProgressBarElement::ProgressBarElement(Document& document)
+inline ProgressBarElement::ProgressBarElement(Document& document)
: ProgressShadowElement(document)
{
}
+DEFINE_NODE_FACTORY(ProgressBarElement)
+
ProgressValueElement::ProgressValueElement(Document& document)
: ProgressShadowElement(document)
{
@@ -90,4 +94,6 @@ void ProgressValueElement::setWidthPercentage(double width)
setInlineStyleProperty(CSSPropertyWidth, width, CSSPrimitiveValue::CSS_PERCENTAGE);
}
+DEFINE_NODE_FACTORY(ProgressValueElement)
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h
index b375fcc88d7..825b0b68437 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.h
@@ -41,56 +41,41 @@ class HTMLProgressElement;
class ProgressShadowElement : public HTMLDivElement {
public:
- ProgressShadowElement(Document&);
+ explicit ProgressShadowElement(Document&);
HTMLProgressElement* progressElement() const;
protected:
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
};
class ProgressInnerElement FINAL : public ProgressShadowElement {
public:
- static PassRefPtr<ProgressInnerElement> create(Document&);
+ DECLARE_NODE_FACTORY(ProgressInnerElement);
private:
- ProgressInnerElement(Document&);
+ explicit ProgressInnerElement(Document&);
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
};
-inline PassRefPtr<ProgressInnerElement> ProgressInnerElement::create(Document& document)
-{
- return adoptRef(new ProgressInnerElement(document));
-}
-
class ProgressBarElement FINAL : public ProgressShadowElement {
public:
- static PassRefPtr<ProgressBarElement> create(Document&);
+ DECLARE_NODE_FACTORY(ProgressBarElement);
private:
- ProgressBarElement(Document&);
+ explicit ProgressBarElement(Document&);
};
-inline PassRefPtr<ProgressBarElement> ProgressBarElement::create(Document& document)
-{
- return adoptRef(new ProgressBarElement(document));
-}
-
class ProgressValueElement FINAL : public ProgressShadowElement {
public:
- static PassRefPtr<ProgressValueElement> create(Document&);
+ DECLARE_NODE_FACTORY(ProgressValueElement);
void setWidthPercentage(double);
private:
- ProgressValueElement(Document&);
+ explicit ProgressValueElement(Document&);
};
-inline PassRefPtr<ProgressValueElement> ProgressValueElement::create(Document& document)
-{
- return adoptRef(new ProgressValueElement(document));
-}
-
}
#endif // ProgressShadowElement_h
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp
index abe60e1d644..ad2f183effb 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.cpp
@@ -35,6 +35,18 @@ namespace WebCore {
namespace ShadowElementNames {
+const AtomicString& detailsContent()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("details-content", AtomicString::ConstructFromLiteral));
+ return name;
+}
+
+const AtomicString& detailsSummary()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, name, ("details-summary", AtomicString::ConstructFromLiteral));
+ return name;
+}
+
const AtomicString& dateTimeEdit()
{
DEFINE_STATIC_LOCAL(AtomicString, name, ("date-time-edit", AtomicString::ConstructFromLiteral));
@@ -65,12 +77,6 @@ const AtomicString& innerEditor()
return name;
}
-const AtomicString& passwordGenerator()
-{
- DEFINE_STATIC_LOCAL(AtomicString, name, ("password-generator", AtomicString::ConstructFromLiteral));
- return name;
-}
-
const AtomicString& pickerIndicator()
{
DEFINE_STATIC_LOCAL(AtomicString, name, ("picker", AtomicString::ConstructFromLiteral));
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h b/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h
index 46788a1cdfb..61ee1ca1680 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/ShadowElementNames.h
@@ -37,12 +37,13 @@ namespace WebCore {
namespace ShadowElementNames {
+const AtomicString& detailsContent();
+const AtomicString& detailsSummary();
const AtomicString& dateTimeEdit();
const AtomicString& spinButton();
const AtomicString& clearButton();
const AtomicString& editingViewPort();
const AtomicString& innerEditor();
-const AtomicString& passwordGenerator();
const AtomicString& pickerIndicator();
const AtomicString& placeholder();
const AtomicString& searchDecoration();
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
index dc7d5080591..3e9ab2fd281 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.cpp
@@ -36,18 +36,16 @@
#include "core/events/Event.h"
#include "core/events/MouseEvent.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/forms/StepRange.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderFlexibleBox.h"
#include "core/rendering/RenderSlider.h"
#include "core/rendering/RenderTheme.h"
-using namespace std;
-
namespace WebCore {
using namespace HTMLNames;
@@ -64,9 +62,6 @@ inline static bool hasVerticalAppearance(HTMLInputElement* input)
ASSERT(input->renderer());
RenderStyle* sliderStyle = input->renderer()->style();
- if (sliderStyle->appearance() == MediaVolumeSliderPart && RenderTheme::theme().usesVerticalVolumeSlider())
- return true;
-
return sliderStyle->appearance() == SliderVerticalPart;
}
@@ -131,11 +126,18 @@ void RenderSliderContainer::computeLogicalHeight(LayoutUnit logicalHeight, Layou
if (zoomFactor != 1.0)
trackHeight *= zoomFactor;
+ // FIXME: The trackHeight should have been added before updateLogicalHeight was called to avoid this hack.
+ updateIntrinsicContentLogicalHeight(trackHeight);
+
RenderBox::computeLogicalHeight(trackHeight, logicalTop, computedValues);
return;
}
if (isVertical)
logicalHeight = RenderSlider::defaultTrackLength;
+
+ // FIXME: The trackHeight should have been added before updateLogicalHeight was called to avoid this hack.
+ updateIntrinsicContentLogicalHeight(logicalHeight);
+
RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues);
}
@@ -157,7 +159,7 @@ void RenderSliderContainer::layout()
RenderBox* thumb = thumbElement ? thumbElement->renderBox() : 0;
RenderBox* track = trackElement ? trackElement->renderBox() : 0;
- SubtreeLayoutScope layoutScope(this);
+ SubtreeLayoutScope layoutScope(*this);
// Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place.
// FIXME: Make a custom Render class for the track and move the thumb positioning code there.
if (track)
@@ -182,14 +184,14 @@ void RenderSliderContainer::layout()
else
thumbLocation.setX(thumbLocation.x() - offset);
thumb->setLocation(thumbLocation);
- if (checkForRepaintDuringLayout() && parent()
+ if (checkForPaintInvalidationDuringLayout() && parent()
&& (parent()->style()->appearance() == MediaVolumeSliderPart || parent()->style()->appearance() == MediaSliderPart)) {
// This will sometimes repaint too much. However, it is necessary to
// correctly repaint media controls (volume and timeline sliders) -
// they have special painting code in RenderMediaControls.cpp:paintMediaVolumeSlider
// and paintMediaSlider that gets called via -webkit-appearance and RenderTheme,
// so nothing else would otherwise invalidate the slider.
- repaint();
+ paintInvalidationForWholeRenderer();
}
}
@@ -201,9 +203,9 @@ inline SliderThumbElement::SliderThumbElement(Document& document)
{
}
-PassRefPtr<SliderThumbElement> SliderThumbElement::create(Document& document)
+PassRefPtrWillBeRawPtr<SliderThumbElement> SliderThumbElement::create(Document& document)
{
- RefPtr<SliderThumbElement> element = adoptRef(new SliderThumbElement(document));
+ RefPtrWillBeRawPtr<SliderThumbElement> element = adoptRefWillBeNoop(new SliderThumbElement(document));
element->setAttribute(idAttr, ShadowElementNames::sliderThumb());
return element.release();
}
@@ -214,7 +216,7 @@ void SliderThumbElement::setPositionFromValue()
// path, we don't actually update the value here. Instead, we poke at the
// renderer directly to trigger layout.
if (renderer())
- renderer()->setNeedsLayout();
+ renderer()->setNeedsLayoutAndFullPaintInvalidation();
}
RenderObject* SliderThumbElement::createRenderer(RenderStyle*)
@@ -229,12 +231,12 @@ bool SliderThumbElement::isDisabledFormControl() const
bool SliderThumbElement::matchesReadOnlyPseudoClass() const
{
- return hostInput()->matchesReadOnlyPseudoClass();
+ return hostInput() && hostInput()->matchesReadOnlyPseudoClass();
}
bool SliderThumbElement::matchesReadWritePseudoClass() const
{
- return hostInput()->matchesReadWritePseudoClass();
+ return hostInput() && hostInput()->matchesReadWritePseudoClass();
}
Node* SliderThumbElement::focusDelegate()
@@ -244,14 +246,14 @@ Node* SliderThumbElement::focusDelegate()
void SliderThumbElement::dragFrom(const LayoutPoint& point)
{
- RefPtr<SliderThumbElement> protector(this);
+ RefPtrWillBeRawPtr<SliderThumbElement> protector(this);
startDragging();
setPositionFromPoint(point);
}
void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point)
{
- RefPtr<HTMLInputElement> input(hostInput());
+ RefPtrWillBeRawPtr<HTMLInputElement> input(hostInput());
Element* trackElement = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderTrack());
if (!input->renderer() || !renderBox() || !trackElement->renderBox())
@@ -281,7 +283,7 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point)
position -= isLeftToRightDirection ? renderBox()->marginLeft() : renderBox()->marginRight();
currentPosition = absoluteThumbOrigin.x() - absoluteSliderContentOrigin.x();
}
- position = max<LayoutUnit>(0, min(position, trackSize));
+ position = std::max<LayoutUnit>(0, std::min(position, trackSize));
const Decimal ratio = Decimal::fromDouble(static_cast<double>(position) / trackSize);
const Decimal fraction = isVertical || !isLeftToRightDirection ? Decimal(1) - ratio : ratio;
StepRange stepRange(input->createStepRange(RejectAny));
@@ -304,13 +306,12 @@ void SliderThumbElement::setPositionFromPoint(const LayoutPoint& point)
// FIXME: This is no longer being set from renderer. Consider updating the method name.
input->setValueFromRenderer(valueString);
if (renderer())
- renderer()->setNeedsLayout();
- input->dispatchFormControlChangeEvent();
+ renderer()->setNeedsLayoutAndFullPaintInvalidation();
}
void SliderThumbElement::startDragging()
{
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
frame->eventHandler().setCapturingMouseEventsNode(this);
m_inDragMode = true;
}
@@ -321,11 +322,13 @@ void SliderThumbElement::stopDragging()
if (!m_inDragMode)
return;
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_inDragMode = false;
if (renderer())
- renderer()->setNeedsLayout();
+ renderer()->setNeedsLayoutAndFullPaintInvalidation();
+ if (hostInput())
+ hostInput()->dispatchFormControlChangeEvent();
}
void SliderThumbElement::defaultEventHandler(Event* event)
@@ -387,8 +390,8 @@ bool SliderThumbElement::willRespondToMouseClickEvents()
void SliderThumbElement::detach(const AttachContext& context)
{
if (m_inDragMode) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
}
HTMLDivElement::detach(context);
}
@@ -412,10 +415,10 @@ static const AtomicString& mediaSliderThumbShadowPartId()
return mediaSliderThumb;
}
-const AtomicString& SliderThumbElement::pseudo() const
+const AtomicString& SliderThumbElement::shadowPseudoId() const
{
HTMLInputElement* input = hostInput();
- if (!input)
+ if (!input || !input->renderer())
return sliderThumbShadowPartId();
RenderStyle* sliderStyle = input->renderer()->style();
@@ -439,25 +442,22 @@ inline SliderContainerElement::SliderContainerElement(Document& document)
{
}
-PassRefPtr<SliderContainerElement> SliderContainerElement::create(Document& document)
-{
- return adoptRef(new SliderContainerElement(document));
-}
+DEFINE_NODE_FACTORY(SliderContainerElement)
RenderObject* SliderContainerElement::createRenderer(RenderStyle*)
{
return new RenderSliderContainer(this);
}
-const AtomicString& SliderContainerElement::pseudo() const
+const AtomicString& SliderContainerElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-media-slider-container", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-container", AtomicString::ConstructFromLiteral));
- if (!shadowHost()->hasTagName(inputTag))
+ if (!shadowHost() || !shadowHost()->renderer())
return sliderContainer;
- RenderStyle* sliderStyle = toHTMLInputElement(shadowHost())->renderer()->style();
+ RenderStyle* sliderStyle = shadowHost()->renderer()->style();
switch (sliderStyle->appearance()) {
case MediaSliderPart:
case MediaSliderThumbPart:
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h
index a7af7771fbd..efb41d65fa0 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/SliderThumbElement.h
@@ -32,7 +32,7 @@
#ifndef SliderThumbElement_h
#define SliderThumbElement_h
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLDivElement.h"
#include "core/rendering/RenderBlockFlow.h"
#include "wtf/Forward.h"
@@ -46,43 +46,40 @@ class FloatPoint;
class SliderThumbElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<SliderThumbElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<SliderThumbElement> create(Document&);
void setPositionFromValue();
void dragFrom(const LayoutPoint&);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool willRespondToMouseMoveEvents() OVERRIDE;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual const AtomicString& pseudo() const OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
HTMLInputElement* hostInput() const;
void setPositionFromPoint(const LayoutPoint&);
void stopDragging();
private:
SliderThumbElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
virtual bool isDisabledFormControl() const OVERRIDE;
virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
virtual bool matchesReadWritePseudoClass() const OVERRIDE;
- virtual Node* focusDelegate();
+ virtual Node* focusDelegate() OVERRIDE;
void startDragging();
bool m_inDragMode;
};
-inline PassRefPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren()
+inline PassRefPtrWillBeRawPtr<Element> SliderThumbElement::cloneElementWithoutAttributesAndChildren()
{
return create(document());
}
-inline SliderThumbElement* toSliderThumbElement(Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isHTMLElement());
- return static_cast<SliderThumbElement*>(node);
-}
+// FIXME: There are no ways to check if a node is a SliderThumbElement.
+DEFINE_ELEMENT_TYPE_CASTS(SliderThumbElement, isHTMLElement());
// --------------------------------
@@ -92,20 +89,19 @@ public:
void updateAppearance(RenderStyle* parentStyle);
private:
- virtual bool isSliderThumb() const;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual bool isSliderThumb() const OVERRIDE;
};
// --------------------------------
class SliderContainerElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<SliderContainerElement> create(Document&);
+ DECLARE_NODE_FACTORY(SliderContainerElement);
private:
- SliderContainerElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual const AtomicString& pseudo() const;
+ explicit SliderContainerElement(Document&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp
index 38303b5aca5..0671ee1beef 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.cpp
@@ -27,14 +27,13 @@
#include "config.h"
#include "core/html/shadow/SpinButtonElement.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/WheelEvent.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/page/Chrome.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/rendering/RenderBox.h"
#include "platform/scroll/ScrollbarTheme.h"
@@ -53,17 +52,17 @@ inline SpinButtonElement::SpinButtonElement(Document& document, SpinButtonOwner&
{
}
-PassRefPtr<SpinButtonElement> SpinButtonElement::create(Document& document, SpinButtonOwner& spinButtonOwner)
+PassRefPtrWillBeRawPtr<SpinButtonElement> SpinButtonElement::create(Document& document, SpinButtonOwner& spinButtonOwner)
{
- RefPtr<SpinButtonElement> element = adoptRef(new SpinButtonElement(document, spinButtonOwner));
- element->setPseudo(AtomicString("-webkit-inner-spin-button", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<SpinButtonElement> element = adoptRefWillBeNoop(new SpinButtonElement(document, spinButtonOwner));
+ element->setShadowPseudoId(AtomicString("-webkit-inner-spin-button", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::spinButton());
return element.release();
}
void SpinButtonElement::detach(const AttachContext& context)
{
- releaseCapture();
+ releaseCapture(EventDispatchDisallowed);
HTMLDivElement::detach(context);
}
@@ -95,7 +94,7 @@ void SpinButtonElement::defaultEventHandler(Event* event)
// The following functions of HTMLInputElement may run JavaScript
// code which detaches this shadow node. We need to take a reference
// and check renderer() after such function calls.
- RefPtr<Node> protector(this);
+ RefPtrWillBeRawPtr<Node> protector(this);
if (m_spinButtonOwner)
m_spinButtonOwner->focusAndSelectSpinButtonOwner();
if (renderer()) {
@@ -111,12 +110,12 @@ void SpinButtonElement::defaultEventHandler(Event* event)
}
event->setDefaultHandled();
}
- } else if (mouseEvent->type() == EventTypeNames::mouseup && mouseEvent->button() == LeftButton)
- stopRepeatingTimer();
- else if (event->type() == EventTypeNames::mousemove) {
+ } else if (mouseEvent->type() == EventTypeNames::mouseup && mouseEvent->button() == LeftButton) {
+ releaseCapture();
+ } else if (event->type() == EventTypeNames::mousemove) {
if (box->pixelSnappedBorderBoxRect().contains(local)) {
if (!m_capturing) {
- if (Frame* frame = document().frame()) {
+ if (LocalFrame* frame = document().frame()) {
frame->eventHandler().setCapturingMouseEventsNode(this);
m_capturing = true;
if (Page* page = document().page())
@@ -126,7 +125,7 @@ void SpinButtonElement::defaultEventHandler(Event* event)
UpDownState oldUpDownState = m_upDownState;
m_upDownState = (local.y() < box->height() / 2) ? Up : Down;
if (m_upDownState != oldUpDownState)
- renderer()->repaint();
+ renderer()->paintInvalidationForWholeRenderer();
} else {
releaseCapture();
m_upDownState = Indeterminate;
@@ -188,17 +187,20 @@ void SpinButtonElement::doStepAction(int amount)
m_spinButtonOwner->spinButtonStepDown();
}
-void SpinButtonElement::releaseCapture()
+void SpinButtonElement::releaseCapture(EventDispatch eventDispatch)
{
stopRepeatingTimer();
if (m_capturing) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame()) {
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
m_capturing = false;
if (Page* page = document().page())
page->chrome().unregisterPopupOpeningObserver(this);
}
}
+ if (m_spinButtonOwner)
+ m_spinButtonOwner->spinButtonDidReleaseMouseCapture(eventDispatch);
+
}
bool SpinButtonElement::matchesReadOnlyPseudoClass() const
@@ -215,7 +217,7 @@ void SpinButtonElement::startRepeatingTimer()
{
m_pressStartingState = m_upDownState;
ScrollbarTheme* theme = ScrollbarTheme::theme();
- m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay());
+ m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay(), FROM_HERE);
}
void SpinButtonElement::stopRepeatingTimer()
@@ -255,4 +257,10 @@ bool SpinButtonElement::shouldRespondToMouseEvents()
return !m_spinButtonOwner || m_spinButtonOwner->shouldSpinButtonRespondToMouseEvents();
}
+void SpinButtonElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_spinButtonOwner);
+ HTMLDivElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h b/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h
index 41de8fcdaee..25c0b30d8b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/SpinButtonElement.h
@@ -40,13 +40,17 @@ public:
Down,
Up,
};
-
- class SpinButtonOwner {
+ enum EventDispatch {
+ EventDispatchAllowed,
+ EventDispatchDisallowed,
+ };
+ class SpinButtonOwner : public WillBeGarbageCollectedMixin {
public:
virtual ~SpinButtonOwner() { }
virtual void focusAndSelectSpinButtonOwner() = 0;
virtual bool shouldSpinButtonRespondToMouseEvents() = 0;
virtual bool shouldSpinButtonRespondToWheelEvents() = 0;
+ virtual void spinButtonDidReleaseMouseCapture(EventDispatch) = 0;
virtual void spinButtonStepDown() = 0;
virtual void spinButtonStepUp() = 0;
};
@@ -54,10 +58,10 @@ public:
// The owner of SpinButtonElement must call removeSpinButtonOwner
// because SpinButtonElement can be outlive SpinButtonOwner
// implementation, e.g. during event handling.
- static PassRefPtr<SpinButtonElement> create(Document&, SpinButtonOwner&);
+ static PassRefPtrWillBeRawPtr<SpinButtonElement> create(Document&, SpinButtonOwner&);
UpDownState upDownState() const { return m_upDownState; }
- virtual void releaseCapture();
- void removeSpinButtonOwner() { m_spinButtonOwner = 0; }
+ void releaseCapture(EventDispatch = EventDispatchAllowed);
+ void removeSpinButtonOwner() { m_spinButtonOwner = nullptr; }
void step(int amount);
@@ -66,25 +70,27 @@ public:
void forwardEvent(Event*);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
SpinButtonElement(Document&, SpinButtonOwner&);
- virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual bool isSpinButtonElement() const { return true; }
+ virtual void detach(const AttachContext&) OVERRIDE;
+ virtual bool isSpinButtonElement() const OVERRIDE { return true; }
virtual bool isDisabledFormControl() const OVERRIDE { return shadowHost() && shadowHost()->isDisabledFormControl(); }
virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
virtual bool matchesReadWritePseudoClass() const OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual void willOpenPopup() OVERRIDE;
void doStepAction(int);
void startRepeatingTimer();
void stopRepeatingTimer();
void repeatingTimerFired(Timer<SpinButtonElement>*);
- virtual void setHovered(bool = true);
+ virtual void setHovered(bool = true) OVERRIDE;
bool shouldRespondToMouseEvents();
- virtual bool isMouseFocusable() const { return false; }
+ virtual bool isMouseFocusable() const OVERRIDE { return false; }
- SpinButtonOwner* m_spinButtonOwner;
+ RawPtrWillBeMember<SpinButtonOwner> m_spinButtonOwner;
bool m_capturing;
UpDownState m_upDownState;
UpDownState m_pressStartingState;
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp
index a19fef2c9e9..57c9fc665a6 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.cpp
@@ -27,21 +27,18 @@
#include "config.h"
#include "core/html/shadow/TextControlInnerElements.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/events/MouseEvent.h"
#include "core/events/TextEvent.h"
#include "core/events/TextEventInputType.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/rendering/RenderTextControlSingleLine.h"
#include "core/rendering/RenderView.h"
-#include "core/speech/SpeechInput.h"
-#include "core/speech/SpeechInputEvent.h"
#include "platform/UserGestureIndicator.h"
namespace WebCore {
@@ -53,9 +50,9 @@ TextControlInnerContainer::TextControlInnerContainer(Document& document)
{
}
-PassRefPtr<TextControlInnerContainer> TextControlInnerContainer::create(Document& document)
+PassRefPtrWillBeRawPtr<TextControlInnerContainer> TextControlInnerContainer::create(Document& document)
{
- RefPtr<TextControlInnerContainer> element = adoptRef(new TextControlInnerContainer(document));
+ RefPtrWillBeRawPtr<TextControlInnerContainer> element = adoptRefWillBeNoop(new TextControlInnerContainer(document));
element->setAttribute(idAttr, ShadowElementNames::textFieldContainer());
return element.release();
}
@@ -73,9 +70,9 @@ EditingViewPortElement::EditingViewPortElement(Document& document)
setHasCustomStyleCallbacks();
}
-PassRefPtr<EditingViewPortElement> EditingViewPortElement::create(Document& document)
+PassRefPtrWillBeRawPtr<EditingViewPortElement> EditingViewPortElement::create(Document& document)
{
- RefPtr<EditingViewPortElement> element = adoptRef(new EditingViewPortElement(document));
+ RefPtrWillBeRawPtr<EditingViewPortElement> element = adoptRefWillBeNoop(new EditingViewPortElement(document));
element->setAttribute(idAttr, ShadowElementNames::editingViewPort());
return element.release();
}
@@ -88,9 +85,6 @@ PassRefPtr<RenderStyle> EditingViewPortElement::customStyleForRenderer()
style->inheritFrom(shadowHost()->renderStyle());
style->setFlexGrow(1);
- // min-width: 0; is needed for correct shrinking.
- // FIXME: Remove this line when https://bugs.webkit.org/show_bug.cgi?id=111790 is fixed.
- style->setMinWidth(Length(0, Fixed));
style->setDisplay(BLOCK);
style->setDirection(LTR);
@@ -104,20 +98,20 @@ PassRefPtr<RenderStyle> EditingViewPortElement::customStyleForRenderer()
// ---------------------------
-inline TextControlInnerTextElement::TextControlInnerTextElement(Document& document)
+inline TextControlInnerEditorElement::TextControlInnerEditorElement(Document& document)
: HTMLDivElement(document)
{
setHasCustomStyleCallbacks();
}
-PassRefPtr<TextControlInnerTextElement> TextControlInnerTextElement::create(Document& document)
+PassRefPtrWillBeRawPtr<TextControlInnerEditorElement> TextControlInnerEditorElement::create(Document& document)
{
- RefPtr<TextControlInnerTextElement> element = adoptRef(new TextControlInnerTextElement(document));
+ RefPtrWillBeRawPtr<TextControlInnerEditorElement> element = adoptRefWillBeNoop(new TextControlInnerEditorElement(document));
element->setAttribute(idAttr, ShadowElementNames::innerEditor());
return element.release();
}
-void TextControlInnerTextElement::defaultEventHandler(Event* event)
+void TextControlInnerEditorElement::defaultEventHandler(Event* event)
{
// FIXME: In the future, we should add a way to have default event listeners.
// Then we would add one to the text field's inner div, and we wouldn't need this subclass.
@@ -136,18 +130,18 @@ void TextControlInnerTextElement::defaultEventHandler(Event* event)
HTMLDivElement::defaultEventHandler(event);
}
-RenderObject* TextControlInnerTextElement::createRenderer(RenderStyle*)
+RenderObject* TextControlInnerEditorElement::createRenderer(RenderStyle*)
{
return new RenderTextControlInnerBlock(this);
}
-PassRefPtr<RenderStyle> TextControlInnerTextElement::customStyleForRenderer()
+PassRefPtr<RenderStyle> TextControlInnerEditorElement::customStyleForRenderer()
{
RenderObject* parentRenderer = shadowHost()->renderer();
if (!parentRenderer || !parentRenderer->isTextControl())
return originalStyleForRenderer();
RenderTextControl* textControlRenderer = toRenderTextControl(parentRenderer);
- return textControlRenderer->createInnerTextStyle(textControlRenderer->style());
+ return textControlRenderer->createInnerEditorStyle(textControlRenderer->style());
}
// ----------------------------
@@ -157,21 +151,21 @@ inline SearchFieldDecorationElement::SearchFieldDecorationElement(Document& docu
{
}
-PassRefPtr<SearchFieldDecorationElement> SearchFieldDecorationElement::create(Document& document)
+PassRefPtrWillBeRawPtr<SearchFieldDecorationElement> SearchFieldDecorationElement::create(Document& document)
{
- RefPtr<SearchFieldDecorationElement> element = adoptRef(new SearchFieldDecorationElement(document));
+ RefPtrWillBeRawPtr<SearchFieldDecorationElement> element = adoptRefWillBeNoop(new SearchFieldDecorationElement(document));
element->setAttribute(idAttr, ShadowElementNames::searchDecoration());
return element.release();
}
-const AtomicString& SearchFieldDecorationElement::pseudo() const
+const AtomicString& SearchFieldDecorationElement::shadowPseudoId() const
{
DEFINE_STATIC_LOCAL(AtomicString, resultsDecorationId, ("-webkit-search-results-decoration", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, decorationId, ("-webkit-search-decoration", AtomicString::ConstructFromLiteral));
Element* host = shadowHost();
if (!host)
return resultsDecorationId;
- if (host->hasTagName(inputTag)) {
+ if (isHTMLInputElement(*host)) {
if (toHTMLInputElement(host)->maxResults() < 0)
return decorationId;
return resultsDecorationId;
@@ -206,10 +200,10 @@ inline SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(Document&
{
}
-PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document& document)
+PassRefPtrWillBeRawPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::create(Document& document)
{
- RefPtr<SearchFieldCancelButtonElement> element = adoptRef(new SearchFieldCancelButtonElement(document));
- element->setPseudo(AtomicString("-webkit-search-cancel-button", AtomicString::ConstructFromLiteral));
+ RefPtrWillBeRawPtr<SearchFieldCancelButtonElement> element = adoptRefWillBeNoop(new SearchFieldCancelButtonElement(document));
+ element->setShadowPseudoId(AtomicString("-webkit-search-cancel-button", AtomicString::ConstructFromLiteral));
element->setAttribute(idAttr, ShadowElementNames::clearButton());
return element.release();
}
@@ -217,8 +211,8 @@ PassRefPtr<SearchFieldCancelButtonElement> SearchFieldCancelButtonElement::creat
void SearchFieldCancelButtonElement::detach(const AttachContext& context)
{
if (m_capturing) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
+ if (LocalFrame* frame = document().frame())
+ frame->eventHandler().setCapturingMouseEventsNode(nullptr);
}
HTMLDivElement::detach(context);
}
@@ -227,136 +221,17 @@ void SearchFieldCancelButtonElement::detach(const AttachContext& context)
void SearchFieldCancelButtonElement::defaultEventHandler(Event* event)
{
// If the element is visible, on mouseup, clear the value, and set selection
- RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
+ RefPtrWillBeRawPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
if (!input || input->isDisabledOrReadOnly()) {
if (!event->defaultHandled())
HTMLDivElement::defaultEventHandler(event);
return;
}
- if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
- if (renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(this);
- m_capturing = true;
- }
- }
- input->focus();
- input->select();
- event->setDefaultHandled();
- }
- if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
- if (m_capturing) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- if (hovered()) {
- String oldValue = input->value();
- input->setValueForUser("");
- input->onSearch();
- event->setDefaultHandled();
- }
- }
- }
-
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
-}
-
-bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents()
-{
- const HTMLInputElement* input = toHTMLInputElement(shadowHost());
- if (input && !input->isDisabledOrReadOnly())
- return true;
-
- return HTMLDivElement::willRespondToMouseClickEvents();
-}
-
-// ----------------------------
-
-#if ENABLE(INPUT_SPEECH)
-
-inline InputFieldSpeechButtonElement::InputFieldSpeechButtonElement(Document& document)
- : HTMLDivElement(document)
- , m_capturing(false)
- , m_state(Idle)
- , m_listenerId(0)
-{
-}
-
-InputFieldSpeechButtonElement::~InputFieldSpeechButtonElement()
-{
- SpeechInput* speech = speechInput();
- if (speech && m_listenerId) { // Could be null when page is unloading.
- if (m_state != Idle)
- speech->cancelRecognition(m_listenerId);
- speech->unregisterListener(m_listenerId);
- }
-}
-
-PassRefPtr<InputFieldSpeechButtonElement> InputFieldSpeechButtonElement::create(Document& document)
-{
- RefPtr<InputFieldSpeechButtonElement> element = adoptRef(new InputFieldSpeechButtonElement(document));
- element->setPseudo(AtomicString("-webkit-input-speech-button", AtomicString::ConstructFromLiteral));
- element->setAttribute(idAttr, ShadowElementNames::speechButton());
- return element.release();
-}
-
-void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
-{
- // For privacy reasons, only allow clicks directly coming from the user.
- if (!UserGestureIndicator::processingUserGesture()) {
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
-
- // The call to focus() below dispatches a focus event, and an event handler in the page might
- // remove the input element from DOM. To make sure it remains valid until we finish our work
- // here, we take a temporary reference.
- RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
-
- if (!input || input->isDisabledOrReadOnly()) {
- if (!event->defaultHandled())
- HTMLDivElement::defaultEventHandler(event);
- return;
- }
- // On mouse down, select the text and set focus.
- if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
- if (renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(this);
- m_capturing = true;
- }
- }
- RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
- input->focus();
- input->select();
- event->setDefaultHandled();
- }
- // On mouse up, release capture cleanly.
- if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
- if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
- if (Frame* frame = document().frame()) {
- frame->eventHandler().setCapturingMouseEventsNode(0);
- m_capturing = false;
- }
- }
- }
-
- if (event->type() == EventTypeNames::click && m_listenerId) {
- switch (m_state) {
- case Idle:
- startSpeechInput();
- break;
- case Recording:
- stopSpeechInput();
- break;
- case Recognizing:
- // Nothing to do here, we will continue to wait for results.
- break;
- }
+ if (event->type() == EventTypeNames::click && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
+ input->setValueForUser("");
+ input->onSearch();
event->setDefaultHandled();
}
@@ -364,7 +239,7 @@ void InputFieldSpeechButtonElement::defaultEventHandler(Event* event)
HTMLDivElement::defaultEventHandler(event);
}
-bool InputFieldSpeechButtonElement::willRespondToMouseClickEvents()
+bool SearchFieldCancelButtonElement::willRespondToMouseClickEvents()
{
const HTMLInputElement* input = toHTMLInputElement(shadowHost());
if (input && !input->isDisabledOrReadOnly())
@@ -373,102 +248,4 @@ bool InputFieldSpeechButtonElement::willRespondToMouseClickEvents()
return HTMLDivElement::willRespondToMouseClickEvents();
}
-void InputFieldSpeechButtonElement::setState(SpeechInputState state)
-{
- if (m_state != state) {
- m_state = state;
- shadowHost()->renderer()->repaint();
- }
-}
-
-SpeechInput* InputFieldSpeechButtonElement::speechInput()
-{
- return SpeechInput::from(document().page());
-}
-
-void InputFieldSpeechButtonElement::didCompleteRecording(int)
-{
- setState(Recognizing);
-}
-
-void InputFieldSpeechButtonElement::didCompleteRecognition(int)
-{
- setState(Idle);
-}
-
-void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputResultArray& results)
-{
- m_results = results;
-
- // The call to setValue() below dispatches an event, and an event handler in the page might
- // remove the input element from DOM. To make sure it remains valid until we finish our work
- // here, we take a temporary reference.
- RefPtr<HTMLInputElement> input(toHTMLInputElement(shadowHost()));
- if (!input || input->isDisabledOrReadOnly())
- return;
-
- RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
- if (document().domWindow()) {
- // Call selectionChanged, causing the element to cache the selection,
- // so that the text event inserts the text in this element even if
- // focus has moved away from it.
- input->selectionChanged(false);
- input->dispatchEvent(TextEvent::create(document().domWindow(), results.isEmpty() ? "" : results[0]->utterance(), TextEventInputOther));
- }
-
- // This event is sent after the text event so the website can perform actions using the input field content immediately.
- // It provides alternative recognition hypotheses and notifies that the results come from speech input.
- input->dispatchEvent(SpeechInputEvent::create(EventTypeNames::webkitspeechchange, results));
-
- // Check before accessing the renderer as the above event could have potentially turned off
- // speech in the input element, hence removing this button and renderer from the hierarchy.
- if (renderer())
- renderer()->repaint();
-}
-
-void InputFieldSpeechButtonElement::attach(const AttachContext& context)
-{
- ASSERT(!m_listenerId);
- if (SpeechInput* input = SpeechInput::from(document().page()))
- m_listenerId = input->registerListener(this);
- HTMLDivElement::attach(context);
-}
-
-void InputFieldSpeechButtonElement::detach(const AttachContext& context)
-{
- if (m_capturing) {
- if (Frame* frame = document().frame())
- frame->eventHandler().setCapturingMouseEventsNode(0);
- }
-
- if (m_listenerId) {
- if (m_state != Idle)
- speechInput()->cancelRecognition(m_listenerId);
- speechInput()->unregisterListener(m_listenerId);
- m_listenerId = 0;
- }
-
- HTMLDivElement::detach(context);
-}
-
-void InputFieldSpeechButtonElement::startSpeechInput()
-{
- if (m_state != Idle)
- return;
-
- RefPtr<HTMLInputElement> input = toHTMLInputElement(shadowHost());
- AtomicString language = input->computeInheritedLanguage();
- String grammar = input->getAttribute(webkitgrammarAttr);
- IntRect rect = document().view()->contentsToRootView(pixelSnappedBoundingBox());
- if (speechInput()->startRecognition(m_listenerId, rect, language, grammar, document().securityOrigin()))
- setState(Recording);
-}
-
-void InputFieldSpeechButtonElement::stopSpeechInput()
-{
- if (m_state == Recording)
- speechInput()->stopRecording(m_listenerId);
-}
-#endif // ENABLE(INPUT_SPEECH)
-
}
diff --git a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h
index 6b6fb0ff6f4..65c994d7d2e 100644
--- a/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h
+++ b/chromium/third_party/WebKit/Source/core/html/shadow/TextControlInnerElements.h
@@ -28,119 +28,72 @@
#define TextControlInnerElements_h
#include "core/html/HTMLDivElement.h"
-#include "core/speech/SpeechInputListener.h"
#include "wtf/Forward.h"
namespace WebCore {
-class SpeechInput;
-
class TextControlInnerContainer FINAL : public HTMLDivElement {
public:
- static PassRefPtr<TextControlInnerContainer> create(Document&);
+ static PassRefPtrWillBeRawPtr<TextControlInnerContainer> create(Document&);
+
protected:
- TextControlInnerContainer(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ explicit TextControlInnerContainer(Document&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
class EditingViewPortElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<EditingViewPortElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<EditingViewPortElement> create(Document&);
protected:
- EditingViewPortElement(Document&);
+ explicit EditingViewPortElement(Document&);
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
private:
virtual bool supportsFocus() const OVERRIDE { return false; }
};
-class TextControlInnerTextElement FINAL : public HTMLDivElement {
+class TextControlInnerEditorElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<TextControlInnerTextElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<TextControlInnerEditorElement> create(Document&);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
private:
- TextControlInnerTextElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ explicit TextControlInnerEditorElement(Document&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
virtual bool supportsFocus() const OVERRIDE { return false; }
};
class SearchFieldDecorationElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<SearchFieldDecorationElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<SearchFieldDecorationElement> create(Document&);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
private:
- SearchFieldDecorationElement(Document&);
- virtual const AtomicString& pseudo() const OVERRIDE;
+ explicit SearchFieldDecorationElement(Document&);
+ virtual const AtomicString& shadowPseudoId() const OVERRIDE;
virtual bool supportsFocus() const OVERRIDE { return false; }
};
class SearchFieldCancelButtonElement FINAL : public HTMLDivElement {
public:
- static PassRefPtr<SearchFieldCancelButtonElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<SearchFieldCancelButtonElement> create(Document&);
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool willRespondToMouseClickEvents() OVERRIDE;
private:
- SearchFieldCancelButtonElement(Document&);
+ explicit SearchFieldCancelButtonElement(Document&);
virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
virtual bool supportsFocus() const OVERRIDE { return false; }
bool m_capturing;
};
-#if ENABLE(INPUT_SPEECH)
-
-class InputFieldSpeechButtonElement FINAL
- : public HTMLDivElement,
- public SpeechInputListener {
-public:
- enum SpeechInputState {
- Idle,
- Recording,
- Recognizing,
- };
-
- static PassRefPtr<InputFieldSpeechButtonElement> create(Document&);
- virtual ~InputFieldSpeechButtonElement();
-
- virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void defaultEventHandler(Event*);
- virtual bool willRespondToMouseClickEvents();
- virtual bool isInputFieldSpeechButtonElement() const { return true; }
- SpeechInputState state() const { return m_state; }
- void startSpeechInput();
- void stopSpeechInput();
-
- // SpeechInputListener methods.
- void didCompleteRecording(int);
- void didCompleteRecognition(int);
- void setRecognitionResult(int, const SpeechInputResultArray&);
-
-private:
- InputFieldSpeechButtonElement(Document&);
- SpeechInput* speechInput();
- void setState(SpeechInputState state);
- virtual bool isMouseFocusable() const { return false; }
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
-
- bool m_capturing;
- SpeechInputState m_state;
- int m_listenerId;
- SpeechInputResultArray m_results;
-};
-
-DEFINE_TYPE_CASTS(InputFieldSpeechButtonElement, Element, element, element->isInputFieldSpeechButtonElement(), element.isInputFieldSpeechButtonElement());
-
-#endif // ENABLE(INPUT_SPEECH)
-
} // namespace
#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.cpp
new file mode 100644
index 00000000000..cfa0de3f3f6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.cpp
@@ -0,0 +1,86 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/track/AudioTrack.h"
+
+#include "core/html/HTMLMediaElement.h"
+
+namespace WebCore {
+
+AudioTrack::AudioTrack(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool enabled)
+ : TrackBase(TrackBase::AudioTrack, label, language, id)
+ , m_enabled(enabled)
+{
+ ScriptWrappable::init(this);
+ setKind(kind);
+}
+
+AudioTrack::~AudioTrack()
+{
+}
+
+void AudioTrack::setEnabled(bool enabled)
+{
+ if (enabled == m_enabled)
+ return;
+
+ m_enabled = enabled;
+
+ if (mediaElement())
+ mediaElement()->audioTrackChanged();
+}
+
+const AtomicString& AudioTrack::alternativeKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("alternative", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::descriptionsKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("descriptions", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::mainKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("main", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::mainDescriptionsKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("main-desc", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::translationKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("translation", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& AudioTrack::commentaryKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("commentary", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+bool AudioTrack::isValidKind(const AtomicString& kind) const
+{
+ return (kind == alternativeKeyword())
+ || (kind == descriptionsKeyword())
+ || (kind == mainKeyword())
+ || (kind == mainDescriptionsKeyword())
+ || (kind == translationKeyword())
+ || (kind == commentaryKeyword());
+}
+
+AtomicString AudioTrack::defaultKind() const
+{
+ return emptyAtom;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.h b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.h
new file mode 100644
index 00000000000..dc690ca1dc6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.h
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AudioTrack_h
+#define AudioTrack_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/track/TrackBase.h"
+
+namespace WebCore {
+
+class AudioTrack FINAL : public TrackBase, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<AudioTrack> create(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool enabled)
+ {
+ return adoptRefWillBeRefCountedGarbageCollected(new AudioTrack(id, kind, label, language, enabled));
+ }
+ virtual ~AudioTrack();
+
+ bool enabled() const { return m_enabled; }
+ void setEnabled(bool);
+
+ // Valid kind keywords.
+ static const AtomicString& alternativeKeyword();
+ static const AtomicString& descriptionsKeyword();
+ static const AtomicString& mainKeyword();
+ static const AtomicString& mainDescriptionsKeyword();
+ static const AtomicString& translationKeyword();
+ static const AtomicString& commentaryKeyword();
+
+private:
+ AudioTrack(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool enabled);
+
+ // TrackBase
+ virtual bool isValidKind(const AtomicString&) const OVERRIDE;
+ virtual AtomicString defaultKind() const OVERRIDE;
+
+ bool m_enabled;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.idl b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.idl
new file mode 100644
index 00000000000..d5e0449c02e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrack.idl
@@ -0,0 +1,15 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=AudioVideoTracks,
+ SetWrapperReferenceFrom=owner,
+ WillBeGarbageCollected,
+] interface AudioTrack {
+ readonly attribute DOMString id;
+ readonly attribute DOMString kind;
+ readonly attribute DOMString label;
+ readonly attribute DOMString language;
+ attribute boolean enabled;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.cpp b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.cpp
new file mode 100644
index 00000000000..c4653cdf48b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.cpp
@@ -0,0 +1,40 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/track/AudioTrackList.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<AudioTrackList> AudioTrackList::create(HTMLMediaElement& mediaElement)
+{
+ return adoptRefWillBeRefCountedGarbageCollected(new AudioTrackList(mediaElement));
+}
+
+AudioTrackList::~AudioTrackList()
+{
+}
+
+AudioTrackList::AudioTrackList(HTMLMediaElement& mediaElement)
+ : TrackListBase<AudioTrack>(&mediaElement)
+{
+ ScriptWrappable::init(this);
+}
+
+bool AudioTrackList::hasEnabledTrack() const
+{
+ for (unsigned i = 0; i < length(); ++i) {
+ if (anonymousIndexedGetter(i)->enabled())
+ return true;
+ }
+
+ return false;
+}
+
+const AtomicString& AudioTrackList::interfaceName() const
+{
+ return EventTargetNames::AudioTrackList;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.h b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.h
new file mode 100644
index 00000000000..504de8be9cd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.h
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AudioTrackList_h
+#define AudioTrackList_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/track/AudioTrack.h"
+#include "core/html/track/TrackListBase.h"
+
+namespace WebCore {
+
+class AudioTrackList FINAL : public TrackListBase<AudioTrack>, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<AudioTrackList> create(HTMLMediaElement&);
+
+ virtual ~AudioTrackList();
+
+ bool hasEnabledTrack() const;
+
+ // EventTarget
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+private:
+ explicit AudioTrackList(HTMLMediaElement&);
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.idl b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.idl
new file mode 100644
index 00000000000..6bcd4736ce5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/AudioTrackList.idl
@@ -0,0 +1,16 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=AudioVideoTracks,
+ SetWrapperReferenceFrom=owner,
+] interface AudioTrackList : EventTarget {
+ readonly attribute unsigned long length;
+ getter AudioTrack (unsigned long index);
+ AudioTrack? getTrackById(DOMString id);
+
+ attribute EventHandler onchange;
+ attribute EventHandler onaddtrack;
+ attribute EventHandler onremovetrack;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp
index 925f84e7c9d..ce05095498b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.cpp
@@ -27,6 +27,7 @@
#include "core/html/track/InbandTextTrack.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/html/HTMLMediaElement.h"
#include "core/html/track/vtt/VTTCue.h"
#include "platform/Logging.h"
#include "public/platform/WebInbandTextTrack.h"
@@ -38,13 +39,13 @@ using blink::WebString;
namespace WebCore {
-PassRefPtr<InbandTextTrack> InbandTextTrack::create(Document& document, TextTrackClient* client, WebInbandTextTrack* webTrack)
+PassRefPtrWillBeRawPtr<InbandTextTrack> InbandTextTrack::create(Document& document, WebInbandTextTrack* webTrack)
{
- return adoptRef(new InbandTextTrack(document, client, webTrack));
+ return adoptRefWillBeRefCountedGarbageCollected(new InbandTextTrack(document, webTrack));
}
-InbandTextTrack::InbandTextTrack(Document& document, TextTrackClient* client, WebInbandTextTrack* webTrack)
- : TextTrack(document, client, emptyAtom, webTrack->label(), webTrack->language(), webTrack->id(), InBand)
+InbandTextTrack::InbandTextTrack(Document& document, WebInbandTextTrack* webTrack)
+ : TextTrack(document, emptyAtom, webTrack->label(), webTrack->language(), webTrack->id(), InBand)
, m_webTrack(webTrack)
{
m_webTrack->setClient(this);
@@ -74,8 +75,13 @@ InbandTextTrack::InbandTextTrack(Document& document, TextTrackClient* client, We
InbandTextTrack::~InbandTextTrack()
{
+#if ENABLE(OILPAN)
+ if (m_webTrack)
+ m_webTrack->setClient(0);
+#else
// Make sure m_webTrack was cleared by trackRemoved() before destruction.
ASSERT(!m_webTrack);
+#endif
}
size_t InbandTextTrack::inbandTrackIndex()
@@ -84,17 +90,22 @@ size_t InbandTextTrack::inbandTrackIndex()
return m_webTrack->textTrackIndex();
}
-void InbandTextTrack::trackRemoved()
+void InbandTextTrack::setTrackList(TextTrackList* trackList)
{
+ TextTrack::setTrackList(trackList);
+ if (trackList)
+ return;
+
ASSERT(m_webTrack);
m_webTrack->setClient(0);
m_webTrack = 0;
- clearClient();
}
void InbandTextTrack::addWebVTTCue(double start, double end, const WebString& id, const WebString& content, const WebString& settings)
{
- RefPtr<VTTCue> cue = VTTCue::create(document(), start, end, content);
+ HTMLMediaElement* owner = mediaElement();
+ ASSERT(owner);
+ RefPtrWillBeRawPtr<VTTCue> cue = VTTCue::create(owner->document(), start, end, content);
cue->setId(id);
cue->parseSettings(settings);
addCue(cue);
diff --git a/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h b/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h
index 83948f0e77a..47d39f39555 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/InbandTextTrack.h
@@ -27,6 +27,7 @@
#define InbandTextTrack_h
#include "core/html/track/TextTrack.h"
+#include "platform/heap/Handle.h"
#include "public/platform/WebInbandTextTrackClient.h"
#include "wtf/RefPtr.h"
@@ -41,16 +42,16 @@ class Document;
class MediaPlayer;
class TextTrackCue;
-class InbandTextTrack : public TextTrack, public blink::WebInbandTextTrackClient {
+class InbandTextTrack FINAL : public TextTrack, public blink::WebInbandTextTrackClient {
public:
- static PassRefPtr<InbandTextTrack> create(Document&, TextTrackClient*, blink::WebInbandTextTrack*);
+ static PassRefPtrWillBeRawPtr<InbandTextTrack> create(Document&, blink::WebInbandTextTrack*);
virtual ~InbandTextTrack();
size_t inbandTrackIndex();
- void trackRemoved();
+ virtual void setTrackList(TextTrackList*) OVERRIDE FINAL;
private:
- InbandTextTrack(Document&, TextTrackClient*, blink::WebInbandTextTrack*);
+ InbandTextTrack(Document&, blink::WebInbandTextTrack*);
virtual void addWebVTTCue(double, double, const blink::WebString&, const blink::WebString&, const blink::WebString&) OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp
index 588c06c79ff..288ec204df8 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.cpp
@@ -26,14 +26,18 @@
#include "config.h"
#include "core/html/track/LoadableTextTrack.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/html/HTMLMediaElement.h"
#include "core/html/HTMLTrackElement.h"
#include "core/html/track/TextTrackCueList.h"
#include "core/html/track/vtt/VTTRegionList.h"
namespace WebCore {
+using namespace HTMLNames;
+
LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track)
- : TextTrack(track->document(), track, emptyAtom, emptyAtom, emptyAtom, emptyAtom, TrackElement)
+ : TextTrack(track->document(), emptyAtom, emptyAtom, emptyAtom, emptyAtom, TrackElement)
, m_trackElement(track)
, m_loadTimer(this, &LoadableTextTrack::loadTimerFired)
, m_isDefault(false)
@@ -42,12 +46,26 @@ LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track)
LoadableTextTrack::~LoadableTextTrack()
{
+#if !ENABLE(OILPAN)
+ ASSERT(!m_trackElement);
+#endif
}
-void LoadableTextTrack::clearClient()
+#if !ENABLE(OILPAN)
+void LoadableTextTrack::clearTrackElement()
{
- m_trackElement = 0;
- TextTrack::clearClient();
+ m_trackElement = nullptr;
+}
+#endif
+
+void LoadableTextTrack::setMode(const AtomicString& mode)
+{
+ TextTrack::setMode(mode);
+ if (!m_trackElement)
+ return;
+
+ if (m_trackElement->readyState() == HTMLTrackElement::NONE)
+ m_trackElement->scheduleLoad();
}
void LoadableTextTrack::scheduleLoad(const KURL& url)
@@ -72,7 +90,7 @@ void LoadableTextTrack::scheduleLoad(const KURL& url)
// 3. Asynchronously run the remaining steps, while continuing with whatever task
// was responsible for creating the text track or changing the text track mode.
if (!m_loadTimer.isActive())
- m_loadTimer.startOneShot(0);
+ m_loadTimer.startOneShot(0, FROM_HERE);
}
void LoadableTextTrack::loadTimerFired(Timer<LoadableTextTrack>*)
@@ -97,7 +115,7 @@ void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader)
{
ASSERT_UNUSED(loader, m_loader == loader);
- Vector<RefPtr<VTTCue> > newCues;
+ WillBeHeapVector<RefPtrWillBeMember<VTTCue> > newCues;
m_loader->getNewCues(newCues);
if (!m_cues)
@@ -105,11 +123,11 @@ void LoadableTextTrack::newCuesAvailable(TextTrackLoader* loader)
for (size_t i = 0; i < newCues.size(); ++i) {
newCues[i]->setTrack(this);
- m_cues->add(newCues[i]);
+ m_cues->add(newCues[i].release());
}
- if (client())
- client()->textTrackAddCues(this, m_cues.get());
+ if (mediaElement())
+ mediaElement()->textTrackAddCues(this, m_cues.get());
}
void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadingFailed)
@@ -126,7 +144,7 @@ void LoadableTextTrack::newRegionsAvailable(TextTrackLoader* loader)
{
ASSERT_UNUSED(loader, m_loader == loader);
- Vector<RefPtr<VTTRegion> > newRegions;
+ WillBeHeapVector<RefPtrWillBeMember<VTTRegion> > newRegions;
m_loader->getNewRegions(newRegions);
for (size_t i = 0; i < newRegions.size(); ++i) {
@@ -141,10 +159,10 @@ size_t LoadableTextTrack::trackElementIndex()
ASSERT(m_trackElement->parentNode());
size_t index = 0;
- for (Node* node = m_trackElement->parentNode()->firstChild(); node; node = node->nextSibling()) {
- if (!node->hasTagName(trackTag) || !node->parentNode())
+ for (HTMLTrackElement* track = Traversal<HTMLTrackElement>::firstChild(*m_trackElement->parentNode()); track; track = Traversal<HTMLTrackElement>::nextSibling(*track)) {
+ if (!track->parentNode())
continue;
- if (node == m_trackElement)
+ if (track == m_trackElement)
return index;
++index;
}
@@ -153,5 +171,11 @@ size_t LoadableTextTrack::trackElementIndex()
return 0;
}
-} // namespace WebCore
+void LoadableTextTrack::trace(Visitor* visitor)
+{
+ visitor->trace(m_trackElement);
+ visitor->trace(m_loader);
+ TextTrack::trace(visitor);
+}
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h b/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h
index 487e7caab78..c99f4f1b3c6 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/LoadableTextTrack.h
@@ -28,6 +28,7 @@
#include "core/html/track/TextTrack.h"
#include "core/loader/TextTrackLoader.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
namespace WebCore {
@@ -35,25 +36,30 @@ namespace WebCore {
class HTMLTrackElement;
class LoadableTextTrack;
-class LoadableTextTrack : public TextTrack, private TextTrackLoaderClient {
+class LoadableTextTrack FINAL : public TextTrack, private TextTrackLoaderClient {
public:
- static PassRefPtr<LoadableTextTrack> create(HTMLTrackElement* track)
+ static PassRefPtrWillBeRawPtr<LoadableTextTrack> create(HTMLTrackElement* track)
{
- return adoptRef(new LoadableTextTrack(track));
+ return adoptRefWillBeRefCountedGarbageCollected(new LoadableTextTrack(track));
}
virtual ~LoadableTextTrack();
void scheduleLoad(const KURL&);
- // This shadows TextTrack::clearClient, but need not be virtual.
- void clearClient();
+ // TextTrack method.
+ virtual void setMode(const AtomicString&) OVERRIDE;
size_t trackElementIndex();
HTMLTrackElement* trackElement() { return m_trackElement; }
+#if !ENABLE(OILPAN)
+ void clearTrackElement();
+#endif
virtual bool isDefault() const OVERRIDE { return m_isDefault; }
virtual void setIsDefault(bool isDefault) OVERRIDE { m_isDefault = isDefault; }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
// TextTrackLoaderClient
virtual void newCuesAvailable(TextTrackLoader*) OVERRIDE;
@@ -64,9 +70,11 @@ private:
void loadTimerFired(Timer<LoadableTextTrack>*);
- HTMLTrackElement* m_trackElement;
+ // FIXME: Oilpan: This should be a strong pointer once Member pointers
+ // into the Node hierarchy can be used.
+ RawPtrWillBeWeakMember<HTMLTrackElement> m_trackElement;
Timer<LoadableTextTrack> m_loadTimer;
- OwnPtr<TextTrackLoader> m_loader;
+ OwnPtrWillBeMember<TextTrackLoader> m_loader;
KURL m_url;
bool m_isDefault;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp
index 84dea3e44a3..cf5b51248b9 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.cpp
@@ -32,7 +32,6 @@
#include "config.h"
#include "core/html/track/TextTrack.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/Document.h"
@@ -42,6 +41,7 @@
#include "core/html/track/TextTrackList.h"
#include "core/html/track/vtt/VTTRegion.h"
#include "core/html/track/vtt/VTTRegionList.h"
+#include "platform/RuntimeEnabledFeatures.h"
namespace WebCore {
@@ -95,17 +95,12 @@ const AtomicString& TextTrack::showingKeyword()
return ended;
}
-TextTrack::TextTrack(Document& document, TextTrackClient* client, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType type)
- : TrackBase(TrackBase::TextTrack)
- , m_cues(0)
- , m_regions(0)
- , m_document(&document)
- , m_mediaElement(0)
- , m_label(label)
- , m_language(language)
- , m_id(id)
+TextTrack::TextTrack(Document& document, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType type)
+ : TrackBase(TrackBase::TextTrack, label, language, id)
+ , m_cues(nullptr)
+ , m_regions(nullptr)
+ , m_trackList(nullptr)
, m_mode(disabledKeyword())
- , m_client(client)
, m_trackType(type)
, m_readinessState(NotLoaded)
, m_trackIndex(invalidTrackIndex)
@@ -118,19 +113,18 @@ TextTrack::TextTrack(Document& document, TextTrackClient* client, const AtomicSt
TextTrack::~TextTrack()
{
- if (m_cues) {
- if (m_client)
- m_client->textTrackRemoveCues(this, m_cues.get());
+#if !ENABLE(OILPAN)
+ ASSERT(!m_trackList);
+ if (m_cues) {
for (size_t i = 0; i < m_cues->length(); ++i)
m_cues->item(i)->setTrack(0);
}
-
if (m_regions) {
for (size_t i = 0; i < m_regions->length(); ++i)
m_regions->item(i)->setTrack(0);
}
- clearClient();
+#endif
}
bool TextTrack::isValidKindKeyword(const AtomicString& value)
@@ -149,17 +143,22 @@ bool TextTrack::isValidKindKeyword(const AtomicString& value)
return false;
}
-void TextTrack::setKind(const AtomicString& kind)
+void TextTrack::setTrackList(TextTrackList* trackList)
{
- String oldKind = m_kind;
+ if (!trackList && mediaElement() && m_cues)
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
+
+ m_trackList = trackList;
+ invalidateTrackIndex();
+}
- if (isValidKindKeyword(kind))
- m_kind = kind;
- else
- m_kind = subtitlesKeyword();
+void TextTrack::setKind(const AtomicString& newKind)
+{
+ AtomicString oldKind = kind();
+ TrackBase::setKind(newKind);
- if (m_client && oldKind != m_kind)
- m_client->textTrackKindChanged(this);
+ if (mediaElement() && oldKind != kind())
+ mediaElement()->textTrackKindChanged(this);
}
void TextTrack::setMode(const AtomicString& mode)
@@ -173,8 +172,8 @@ void TextTrack::setMode(const AtomicString& mode)
// If mode changes to disabled, remove this track's cues from the client
// because they will no longer be accessible from the cues() function.
- if (mode == disabledKeyword() && m_client && m_cues)
- m_client->textTrackRemoveCues(this, m_cues.get());
+ if (mode == disabledKeyword() && mediaElement() && m_cues)
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
if (mode != showingKeyword() && m_cues)
for (size_t i = 0; i < m_cues->length(); ++i)
@@ -182,8 +181,8 @@ void TextTrack::setMode(const AtomicString& mode)
m_mode = mode;
- if (m_client)
- m_client->textTrackModeChanged(this);
+ if (mediaElement())
+ mediaElement()->textTrackModeChanged(this);
}
TextTrackCueList* TextTrack::cues()
@@ -203,13 +202,13 @@ void TextTrack::removeAllCues()
if (!m_cues)
return;
- if (m_client)
- m_client->textTrackRemoveCues(this, m_cues.get());
+ if (mediaElement())
+ mediaElement()->textTrackRemoveCues(this, m_cues.get());
for (size_t i = 0; i < m_cues->length(); ++i)
m_cues->item(i)->setTrack(0);
- m_cues = 0;
+ m_cues = nullptr;
}
TextTrackCueList* TextTrack::activeCues() const
@@ -225,12 +224,12 @@ TextTrackCueList* TextTrack::activeCues() const
return 0;
}
-void TextTrack::addCue(PassRefPtr<TextTrackCue> prpCue)
+void TextTrack::addCue(PassRefPtrWillBeRawPtr<TextTrackCue> prpCue)
{
if (!prpCue)
return;
- RefPtr<TextTrackCue> cue = prpCue;
+ RefPtrWillBeRawPtr<TextTrackCue> cue = prpCue;
// TODO(93143): Add spec-compliant behavior for negative time values.
if (std::isnan(cue->startTime()) || std::isnan(cue->endTime()) || cue->startTime() < 0 || cue->endTime() < 0)
@@ -250,8 +249,8 @@ void TextTrack::addCue(PassRefPtr<TextTrackCue> prpCue)
cue->setTrack(this);
ensureTextTrackCueList()->add(cue);
- if (m_client)
- m_client->textTrackAddCue(this, cue.get());
+ if (mediaElement())
+ mediaElement()->textTrackAddCue(this, cue.get());
}
void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState)
@@ -277,8 +276,8 @@ void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState)
}
cue->setTrack(0);
- if (m_client)
- m_client->textTrackRemoveCue(this, cue);
+ if (mediaElement())
+ mediaElement()->textTrackRemoveCue(this, cue);
}
VTTRegionList* TextTrack::ensureVTTRegionList()
@@ -302,12 +301,12 @@ VTTRegionList* TextTrack::regions()
return 0;
}
-void TextTrack::addRegion(PassRefPtr<VTTRegion> prpRegion)
+void TextTrack::addRegion(PassRefPtrWillBeRawPtr<VTTRegion> prpRegion)
{
if (!prpRegion)
return;
- RefPtr<VTTRegion> region = prpRegion;
+ RefPtrWillBeRawPtr<VTTRegion> region = prpRegion;
VTTRegionList* regionList = ensureVTTRegionList();
// 1. If the given region is in a text track list of regions, then remove
@@ -354,32 +353,32 @@ void TextTrack::removeRegion(VTTRegion* region, ExceptionState &exceptionState)
void TextTrack::cueWillChange(TextTrackCue* cue)
{
- if (!m_client)
+ if (!mediaElement())
return;
// The cue may need to be repositioned in the media element's interval tree, may need to
// be re-rendered, etc, so remove it before the modification...
- m_client->textTrackRemoveCue(this, cue);
+ mediaElement()->textTrackRemoveCue(this, cue);
}
void TextTrack::cueDidChange(TextTrackCue* cue)
{
- if (!m_client)
+ if (!mediaElement())
return;
// Make sure the TextTrackCueList order is up-to-date.
ensureTextTrackCueList()->updateCueIndex(cue);
// ... and add it back again.
- m_client->textTrackAddCue(this, cue);
+ mediaElement()->textTrackAddCue(this, cue);
}
int TextTrack::trackIndex()
{
- ASSERT(m_mediaElement);
+ ASSERT(m_trackList);
if (m_trackIndex == invalidTrackIndex)
- m_trackIndex = m_mediaElement->textTracks()->getTrackIndex(this);
+ m_trackIndex = m_trackList->getTrackIndex(this);
return m_trackIndex;
}
@@ -392,7 +391,7 @@ void TextTrack::invalidateTrackIndex()
bool TextTrack::isRendered()
{
- if (m_kind != captionsKeyword() && m_kind != subtitlesKeyword())
+ if (kind() != captionsKeyword() && kind() != subtitlesKeyword())
return false;
if (m_mode != showingKeyword())
@@ -411,10 +410,10 @@ TextTrackCueList* TextTrack::ensureTextTrackCueList()
int TextTrack::trackIndexRelativeToRenderedTracks()
{
- ASSERT(m_mediaElement);
+ ASSERT(m_trackList);
if (m_renderedTrackIndex == invalidTrackIndex)
- m_renderedTrackIndex = m_mediaElement->textTracks()->getTrackIndexRelativeToRenderedTracks(this);
+ m_renderedTrackIndex = m_trackList->getTrackIndexRelativeToRenderedTracks(this);
return m_renderedTrackIndex;
}
@@ -426,8 +425,27 @@ const AtomicString& TextTrack::interfaceName() const
ExecutionContext* TextTrack::executionContext() const
{
- return m_document;
+ HTMLMediaElement* owner = mediaElement();
+ return owner ? owner->executionContext() : 0;
}
-} // namespace WebCore
+HTMLMediaElement* TextTrack::mediaElement() const
+{
+ return m_trackList ? m_trackList->owner() : 0;
+}
+
+Node* TextTrack::owner() const
+{
+ return mediaElement();
+}
+void TextTrack::trace(Visitor* visitor)
+{
+ visitor->trace(m_cues);
+ visitor->trace(m_regions);
+ visitor->trace(m_trackList);
+ TrackBase::trace(visitor);
+ EventTargetWithInlineData::trace(visitor);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.h b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.h
index 721c55566b0..3be6bdf469a 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.h
@@ -28,7 +28,9 @@
#define TextTrack_h
#include "bindings/v8/ScriptWrappable.h"
+#include "core/events/EventTarget.h"
#include "core/html/track/TrackBase.h"
+#include "platform/heap/Handle.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -39,33 +41,24 @@ class HTMLMediaElement;
class TextTrack;
class TextTrackCue;
class TextTrackCueList;
+class TextTrackList;
class VTTRegion;
class VTTRegionList;
-class TextTrackClient {
+class TextTrack : public TrackBase, public ScriptWrappable, public EventTargetWithInlineData {
+ REFCOUNTED_EVENT_TARGET(TrackBase);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TextTrack);
public:
- virtual ~TextTrackClient() { }
- virtual void textTrackKindChanged(TextTrack*) = 0;
- virtual void textTrackModeChanged(TextTrack*) = 0;
- virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) = 0;
- virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) = 0;
- virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) = 0;
- virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) = 0;
-};
-
-class TextTrack : public TrackBase, public ScriptWrappable {
-public:
- static PassRefPtr<TextTrack> create(Document& document, TextTrackClient* client, const AtomicString& kind, const AtomicString& label, const AtomicString& language)
+ static PassRefPtrWillBeRawPtr<TextTrack> create(Document& document, const AtomicString& kind, const AtomicString& label, const AtomicString& language)
{
- return adoptRef(new TextTrack(document, client, kind, label, language, emptyAtom, AddTrack));
+ return adoptRefWillBeRefCountedGarbageCollected(new TextTrack(document, kind, label, language, emptyAtom, AddTrack));
}
virtual ~TextTrack();
- void setMediaElement(HTMLMediaElement* element) { m_mediaElement = element; }
- HTMLMediaElement* mediaElement() { return m_mediaElement; }
+ virtual void setTrackList(TextTrackList*);
+ TextTrackList* trackList() { return m_trackList; }
- const AtomicString& kind() const { return m_kind; }
- void setKind(const AtomicString&);
+ virtual void setKind(const AtomicString&) OVERRIDE;
static const AtomicString& subtitlesKeyword();
static const AtomicString& captionsKeyword();
@@ -74,21 +67,12 @@ public:
static const AtomicString& metadataKeyword();
static bool isValidKindKeyword(const AtomicString&);
- AtomicString label() const { return m_label; }
- void setLabel(const AtomicString& label) { m_label = label; }
-
- AtomicString language() const { return m_language; }
- void setLanguage(const AtomicString& language) { m_language = language; }
-
- AtomicString id() const { return m_id; }
- void setId(const AtomicString& id) { m_id = id; }
-
static const AtomicString& disabledKeyword();
static const AtomicString& hiddenKeyword();
static const AtomicString& showingKeyword();
AtomicString mode() const { return m_mode; }
- void setMode(const AtomicString&);
+ virtual void setMode(const AtomicString&);
enum ReadinessState { NotLoaded = 0, Loading = 1, Loaded = 2, FailedToLoad = 3 };
ReadinessState readinessState() const { return m_readinessState; }
@@ -97,14 +81,14 @@ public:
TextTrackCueList* cues();
TextTrackCueList* activeCues() const;
- void clearClient() { m_client = 0; }
- TextTrackClient* client() { return m_client; }
+ HTMLMediaElement* mediaElement() const;
+ Node* owner() const;
- void addCue(PassRefPtr<TextTrackCue>);
+ void addCue(PassRefPtrWillBeRawPtr<TextTrackCue>);
void removeCue(TextTrackCue*, ExceptionState&);
VTTRegionList* regions();
- void addRegion(PassRefPtr<VTTRegion>);
+ void addRegion(PassRefPtrWillBeRawPtr<VTTRegion>);
void removeRegion(VTTRegion*, ExceptionState&);
void cueWillChange(TextTrackCue*);
@@ -129,33 +113,28 @@ public:
void removeAllCues();
- Document& document() const { return *m_document; }
-
// EventTarget methods
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ExecutionContext* executionContext() const OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
- TextTrack(Document&, TextTrackClient*, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType);
+ TextTrack(Document&, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType);
- RefPtr<TextTrackCueList> m_cues;
+ virtual bool isValidKind(const AtomicString& kind) const OVERRIDE { return isValidKindKeyword(kind); }
+ virtual AtomicString defaultKind() const OVERRIDE { return subtitlesKeyword(); }
+
+ RefPtrWillBeMember<TextTrackCueList> m_cues;
private:
VTTRegionList* ensureVTTRegionList();
- RefPtr<VTTRegionList> m_regions;
+ RefPtrWillBeMember<VTTRegionList> m_regions;
TextTrackCueList* ensureTextTrackCueList();
- // FIXME: Remove this pointer and get the Document from m_client
- Document* m_document;
-
- HTMLMediaElement* m_mediaElement;
- AtomicString m_kind;
- AtomicString m_label;
- AtomicString m_language;
- AtomicString m_id;
+ RawPtrWillBeMember<TextTrackList> m_trackList;
AtomicString m_mode;
- TextTrackClient* m_client;
TextTrackType m_trackType;
ReadinessState m_readinessState;
int m_trackIndex;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl
index a64462d028f..9a75f4b0def 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrack.idl
@@ -27,7 +27,8 @@ enum TextTrackMode { "disabled", "hidden", "showing" };
enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "metadata" };
[
- RuntimeEnabled=VideoTrack
+ SetWrapperReferenceFrom=owner,
+ WillBeGarbageCollected,
] interface TextTrack : EventTarget {
readonly attribute TextTrackKind kind;
readonly attribute DOMString label;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp
index cfb2effe24b..bdb32505bb7 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.cpp
@@ -42,20 +42,11 @@ namespace WebCore {
static const int invalidCueIndex = -1;
-bool TextTrackCue::isInfiniteOrNonNumber(double value, ExceptionState& exceptionState)
-{
- if (!std::isfinite(value)) {
- exceptionState.throwTypeError(ExceptionMessages::notAFiniteNumber(value));
- return true;
- }
- return false;
-}
-
TextTrackCue::TextTrackCue(double start, double end)
: m_startTime(start)
, m_endTime(end)
, m_cueIndex(invalidCueIndex)
- , m_track(0)
+ , m_track(nullptr)
, m_isActive(false)
, m_pauseOnExit(false)
{
@@ -83,7 +74,12 @@ void TextTrackCue::setTrack(TextTrack* track)
m_track = track;
}
-void TextTrackCue::setId(const String& id)
+Node* TextTrackCue::owner() const
+{
+ return m_track ? m_track->owner() : 0;
+}
+
+void TextTrackCue::setId(const AtomicString& id)
{
if (m_id == id)
return;
@@ -93,12 +89,8 @@ void TextTrackCue::setId(const String& id)
cueDidChange();
}
-void TextTrackCue::setStartTime(double value, ExceptionState& exceptionState)
+void TextTrackCue::setStartTime(double value)
{
- // NaN, Infinity and -Infinity values should trigger a TypeError.
- if (isInfiniteOrNonNumber(value, exceptionState))
- return;
-
// TODO(93143): Add spec-compliant behavior for negative time values.
if (m_startTime == value || value < 0)
return;
@@ -108,12 +100,8 @@ void TextTrackCue::setStartTime(double value, ExceptionState& exceptionState)
cueDidChange();
}
-void TextTrackCue::setEndTime(double value, ExceptionState& exceptionState)
+void TextTrackCue::setEndTime(double value)
{
- // NaN, Infinity and -Infinity values should trigger a TypeError.
- if (isInfiniteOrNonNumber(value, exceptionState))
- return;
-
// TODO(93143): Add spec-compliant behavior for negative time values.
if (m_endTime == value || value < 0)
return;
@@ -146,7 +134,7 @@ void TextTrackCue::invalidateCueIndex()
m_cueIndex = invalidCueIndex;
}
-bool TextTrackCue::dispatchEvent(PassRefPtr<Event> event)
+bool TextTrackCue::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
// When a TextTrack's mode is disabled: no cues are active, no events fired.
if (!track() || track()->mode() == TextTrack::disabledKeyword())
@@ -174,4 +162,10 @@ const AtomicString& TextTrackCue::interfaceName() const
return EventTargetNames::TextTrackCue;
}
+void TextTrackCue::trace(Visitor* visitor)
+{
+ visitor->trace(m_track);
+ EventTargetWithInlineData::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h
index 1779e37a7d1..dd2d235b732 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.h
@@ -34,17 +34,17 @@
#include "core/events/EventTarget.h"
#include "core/html/HTMLDivElement.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
namespace WebCore {
class ExceptionState;
-class TextTrackCue : public RefCounted<TextTrackCue>, public EventTargetWithInlineData {
+class TextTrackCue : public RefCountedWillBeRefCountedGarbageCollected<TextTrackCue>, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(TextTrackCue);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TextTrackCue);
public:
- static bool isInfiniteOrNonNumber(double value, ExceptionState&);
-
static const AtomicString& cueShadowPseudoId()
{
DEFINE_STATIC_LOCAL(const AtomicString, cue, ("cue", AtomicString::ConstructFromLiteral));
@@ -56,14 +56,16 @@ public:
TextTrack* track() const;
void setTrack(TextTrack*);
- const String& id() const { return m_id; }
- void setId(const String&);
+ Node* owner() const;
+
+ const AtomicString& id() const { return m_id; }
+ void setId(const AtomicString&);
double startTime() const { return m_startTime; }
- void setStartTime(double, ExceptionState&);
+ void setStartTime(double);
double endTime() const { return m_endTime; }
- void setEndTime(double, ExceptionState&);
+ void setEndTime(double);
bool pauseOnExit() const { return m_pauseOnExit; }
void setPauseOnExit(bool);
@@ -72,7 +74,7 @@ public:
void invalidateCueIndex();
using EventTarget::dispatchEvent;
- virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
+ virtual bool dispatchEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
bool isActive();
void setIsActive(bool);
@@ -94,6 +96,8 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(enter);
DEFINE_ATTRIBUTE_EVENT_LISTENER(exit);
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
TextTrackCue(double start, double end);
@@ -101,12 +105,12 @@ protected:
virtual void cueDidChange();
private:
- String m_id;
+ AtomicString m_id;
double m_startTime;
double m_endTime;
int m_cueIndex;
- TextTrack* m_track;
+ RawPtrWillBeMember<TextTrack> m_track;
bool m_isActive : 1;
bool m_pauseOnExit : 1;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl
index efc18e3e60a..d243c43edec 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCue.idl
@@ -23,18 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#texttrackcue
+
[
Custom=ToV8,
- CustomConstructor(double startTime, double endTime, DOMString text),
- RuntimeEnabled=VideoTrack,
+ SetWrapperReferenceFrom=owner,
+ TypeChecking=Unrestricted,
+ WillBeGarbageCollected,
] interface TextTrackCue : EventTarget {
- readonly attribute TextTrack track;
+ readonly attribute TextTrack track; // FIXME: should be nullable
- attribute DOMString id;
- [RaisesException=Setter] attribute double startTime;
- [RaisesException=Setter] attribute double endTime;
- attribute boolean pauseOnExit;
+ attribute DOMString id;
+ attribute double startTime;
+ attribute double endTime;
+ attribute boolean pauseOnExit;
- attribute EventHandler onenter;
- attribute EventHandler onexit;
+ attribute EventHandler onenter;
+ attribute EventHandler onexit;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp
index 43fa9b55c40..a3dba2dc76b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.cpp
@@ -51,7 +51,7 @@ TextTrackCue* TextTrackCueList::item(unsigned index) const
return 0;
}
-TextTrackCue* TextTrackCueList::getCueById(const String& id) const
+TextTrackCue* TextTrackCueList::getCueById(const AtomicString& id) const
{
for (size_t i = 0; i < m_list.size(); ++i) {
if (m_list[i]->id() == id)
@@ -67,14 +67,14 @@ TextTrackCueList* TextTrackCueList::activeCues()
m_activeCues->clear();
for (size_t i = 0; i < m_list.size(); ++i) {
- RefPtr<TextTrackCue> cue = m_list[i];
+ RefPtrWillBeRawPtr<TextTrackCue> cue = m_list[i];
if (cue->isActive())
m_activeCues->add(cue);
}
return m_activeCues.get();
}
-bool TextTrackCueList::add(PassRefPtr<TextTrackCue> cue)
+bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> cue)
{
ASSERT(cue->startTime() >= 0);
ASSERT(cue->endTime() >= 0);
@@ -82,14 +82,14 @@ bool TextTrackCueList::add(PassRefPtr<TextTrackCue> cue)
return add(cue, 0, m_list.size());
}
-bool TextTrackCueList::add(PassRefPtr<TextTrackCue> prpCue, size_t start, size_t end)
+bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> prpCue, size_t start, size_t end)
{
ASSERT_WITH_SECURITY_IMPLICATION(start <= m_list.size());
ASSERT_WITH_SECURITY_IMPLICATION(end <= m_list.size());
// Maintain text track cue order:
// http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-order
- RefPtr<TextTrackCue> cue = prpCue;
+ RefPtrWillBeRawPtr<TextTrackCue> cue = prpCue;
if (start == end) {
if (!m_list.isEmpty() && (start > 0) && (m_list[start - 1].get() == cue.get()))
return false;
@@ -142,5 +142,11 @@ void TextTrackCueList::invalidateCueIndexes(size_t start)
m_list[i]->invalidateCueIndex();
}
+void TextTrackCueList::trace(Visitor* visitor)
+{
+ visitor->trace(m_list);
+ visitor->trace(m_activeCues);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h
index b209fcf6e26..ace42e12f6b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.h
@@ -34,11 +34,11 @@
namespace WebCore {
-class TextTrackCueList : public RefCounted<TextTrackCueList>, public ScriptWrappable {
+class TextTrackCueList FINAL : public RefCountedWillBeGarbageCollectedFinalized<TextTrackCueList>, public ScriptWrappable {
public:
- static PassRefPtr<TextTrackCueList> create()
+ static PassRefPtrWillBeRawPtr<TextTrackCueList> create()
{
- return adoptRef(new TextTrackCueList);
+ return adoptRefWillBeNoop(new TextTrackCueList);
}
~TextTrackCueList() { }
@@ -47,23 +47,25 @@ public:
unsigned long getCueIndex(TextTrackCue*) const;
TextTrackCue* item(unsigned index) const;
- TextTrackCue* getCueById(const String&) const;
+ TextTrackCue* getCueById(const AtomicString&) const;
TextTrackCueList* activeCues();
- bool add(PassRefPtr<TextTrackCue>);
+ bool add(PassRefPtrWillBeRawPtr<TextTrackCue>);
bool remove(TextTrackCue*);
bool contains(TextTrackCue*) const;
bool updateCueIndex(TextTrackCue*);
+ void trace(Visitor*);
+
private:
TextTrackCueList();
- bool add(PassRefPtr<TextTrackCue>, size_t, size_t);
+ bool add(PassRefPtrWillBeRawPtr<TextTrackCue>, size_t, size_t);
void clear();
void invalidateCueIndexes(size_t);
- Vector<RefPtr<TextTrackCue> > m_list;
- RefPtr<TextTrackCueList> m_activeCues;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrackCue> > m_list;
+ RefPtrWillBeMember<TextTrackCueList> m_activeCues;
};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl
index a71d6875ddb..6ea59a645cd 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackCueList.idl
@@ -24,7 +24,7 @@
*/
[
- RuntimeEnabled=VideoTrack
+ WillBeGarbageCollected,
] interface TextTrackCueList {
readonly attribute unsigned long length;
getter TextTrackCue item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp
index 0d00ba33fee..0738c95e7ba 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.cpp
@@ -28,7 +28,6 @@
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/events/GenericEventQueue.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/track/InbandTextTrack.h"
#include "core/html/track/LoadableTextTrack.h"
@@ -46,7 +45,18 @@ TextTrackList::TextTrackList(HTMLMediaElement* owner)
TextTrackList::~TextTrackList()
{
+#if !ENABLE(OILPAN)
+ ASSERT(!m_owner);
+
+ // TextTrackList and m_asyncEventQueue always become unreachable
+ // together. So TextTrackList and m_asyncEventQueue are destructed in the
+ // same GC. We don't need to close it explicitly in Oilpan.
m_asyncEventQueue->close();
+
+ for (unsigned i = 0; i < length(); ++i) {
+ item(i)->setTrackList(0);
+ }
+#endif
}
unsigned TextTrackList::length() const
@@ -148,7 +158,7 @@ TextTrack* TextTrackList::getTrackById(const AtomicString& id)
void TextTrackList::invalidateTrackIndexesAfterTrack(TextTrack* track)
{
- Vector<RefPtr<TextTrack> >* tracks = 0;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement) {
tracks = &m_elementTracks;
@@ -173,9 +183,9 @@ void TextTrackList::invalidateTrackIndexesAfterTrack(TextTrack* track)
tracks->at(index)->invalidateTrackIndex();
}
-void TextTrackList::append(PassRefPtr<TextTrack> prpTrack)
+void TextTrackList::append(PassRefPtrWillBeRawPtr<TextTrack> prpTrack)
{
- RefPtr<TextTrack> track = prpTrack;
+ RefPtrWillBeRawPtr<TextTrack> track = prpTrack;
if (track->trackType() == TextTrack::AddTrack)
m_addTrackTracks.append(track);
@@ -192,16 +202,15 @@ void TextTrackList::append(PassRefPtr<TextTrack> prpTrack)
invalidateTrackIndexesAfterTrack(track.get());
- ASSERT(!track->mediaElement() || track->mediaElement() == m_owner);
- track->setMediaElement(m_owner);
+ ASSERT(!track->trackList());
+ track->setTrackList(this);
scheduleAddTrackEvent(track.release());
}
void TextTrackList::remove(TextTrack* track)
{
- Vector<RefPtr<TextTrack> >* tracks = 0;
- RefPtr<InbandTextTrack> inbandTrack;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement) {
tracks = &m_elementTracks;
@@ -209,7 +218,6 @@ void TextTrackList::remove(TextTrack* track)
tracks = &m_addTrackTracks;
} else if (track->trackType() == TextTrack::InBand) {
tracks = &m_inbandTracks;
- inbandTrack = static_cast<InbandTextTrack*>(track);
} else {
ASSERT_NOT_REACHED();
}
@@ -220,20 +228,25 @@ void TextTrackList::remove(TextTrack* track)
invalidateTrackIndexesAfterTrack(track);
- ASSERT(track->mediaElement() == m_owner);
- track->setMediaElement(0);
+ ASSERT(track->trackList() == this);
+ track->setTrackList(0);
tracks->remove(index);
- if (inbandTrack)
- inbandTrack->trackRemoved();
-
scheduleRemoveTrackEvent(track);
}
+void TextTrackList::removeAllInbandTracks()
+{
+ for (unsigned i = 0; i < m_inbandTracks.size(); ++i) {
+ m_inbandTracks[i]->setTrackList(0);
+ }
+ m_inbandTracks.clear();
+}
+
bool TextTrackList::contains(TextTrack* track) const
{
- const Vector<RefPtr<TextTrack> >* tracks = 0;
+ const WillBeHeapVector<RefPtrWillBeMember<TextTrack> >* tracks = 0;
if (track->trackType() == TextTrack::TrackElement)
tracks = &m_elementTracks;
@@ -254,11 +267,17 @@ const AtomicString& TextTrackList::interfaceName() const
ExecutionContext* TextTrackList::executionContext() const
{
- ASSERT(m_owner);
- return m_owner->executionContext();
+ return m_owner ? m_owner->executionContext() : 0;
+}
+
+#if !ENABLE(OILPAN)
+void TextTrackList::clearOwner()
+{
+ m_owner = nullptr;
}
+#endif
-void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtr<TextTrack> track)
+void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<TextTrack> track)
{
TrackEventInit initializer;
initializer.track = track;
@@ -268,7 +287,7 @@ void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtr
m_asyncEventQueue->enqueueEvent(TrackEvent::create(eventName, initializer));
}
-void TextTrackList::scheduleAddTrackEvent(PassRefPtr<TextTrack> track)
+void TextTrackList::scheduleAddTrackEvent(PassRefPtrWillBeRawPtr<TextTrack> track)
{
// 4.8.10.12.3 Sourcing out-of-band text tracks
// 4.8.10.12.4 Text track API
@@ -296,7 +315,7 @@ void TextTrackList::scheduleChangeEvent()
m_asyncEventQueue->enqueueEvent(Event::create(EventTypeNames::change, initializer));
}
-void TextTrackList::scheduleRemoveTrackEvent(PassRefPtr<TextTrack> track)
+void TextTrackList::scheduleRemoveTrackEvent(PassRefPtrWillBeRawPtr<TextTrack> track)
{
// 4.8.10.12.3 Sourcing out-of-band text tracks
// When a track element's parent element changes and the old parent was a
@@ -310,7 +329,17 @@ void TextTrackList::scheduleRemoveTrackEvent(PassRefPtr<TextTrack> track)
scheduleTrackEvent(EventTypeNames::removetrack, track);
}
-Node* TextTrackList::owner() const
+HTMLMediaElement* TextTrackList::owner() const
{
return m_owner;
}
+
+void TextTrackList::trace(Visitor* visitor)
+{
+ visitor->trace(m_owner);
+ visitor->trace(m_asyncEventQueue);
+ visitor->trace(m_addTrackTracks);
+ visitor->trace(m_elementTracks);
+ visitor->trace(m_inbandTracks);
+ EventTargetWithInlineData::trace(visitor);
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h
index 7c150b2c931..a544f24761c 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.h
@@ -29,7 +29,9 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/events/EventListener.h"
#include "core/events/EventTarget.h"
+#include "core/html/HTMLMediaElement.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -37,18 +39,17 @@
namespace WebCore {
class GenericEventQueue;
-class HTMLMediaElement;
class TextTrack;
-class TextTrackList;
-class TextTrackList : public RefCounted<TextTrackList>, public ScriptWrappable, public EventTargetWithInlineData {
+class TextTrackList FINAL : public RefCountedWillBeRefCountedGarbageCollected<TextTrackList>, public ScriptWrappable, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(TextTrackList);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TextTrackList);
public:
- static PassRefPtr<TextTrackList> create(HTMLMediaElement* owner)
+ static PassRefPtrWillBeRawPtr<TextTrackList> create(HTMLMediaElement* owner)
{
- return adoptRef(new TextTrackList(owner));
+ return adoptRefWillBeRefCountedGarbageCollected(new TextTrackList(owner));
}
- ~TextTrackList();
+ virtual ~TextTrackList();
unsigned length() const;
int getTrackIndex(TextTrack*);
@@ -57,7 +58,7 @@ public:
TextTrack* item(unsigned index);
TextTrack* getTrackById(const AtomicString& id);
- void append(PassRefPtr<TextTrack>);
+ void append(PassRefPtrWillBeRawPtr<TextTrack>);
void remove(TextTrack*);
// EventTarget
@@ -68,28 +69,33 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
- void clearOwner() { m_owner = 0; }
- Node* owner() const;
+#if !ENABLE(OILPAN)
+ void clearOwner();
+#endif
+ HTMLMediaElement* owner() const;
void scheduleChangeEvent();
+ void removeAllInbandTracks();
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit TextTrackList(HTMLMediaElement*);
- void scheduleTrackEvent(const AtomicString& eventName, PassRefPtr<TextTrack>);
+ void scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<TextTrack>);
- void scheduleAddTrackEvent(PassRefPtr<TextTrack>);
- void scheduleRemoveTrackEvent(PassRefPtr<TextTrack>);
+ void scheduleAddTrackEvent(PassRefPtrWillBeRawPtr<TextTrack>);
+ void scheduleRemoveTrackEvent(PassRefPtrWillBeRawPtr<TextTrack>);
void invalidateTrackIndexesAfterTrack(TextTrack*);
- HTMLMediaElement* m_owner;
+ RawPtrWillBeMember<HTMLMediaElement> m_owner;
- OwnPtr<GenericEventQueue> m_asyncEventQueue;
+ OwnPtrWillBeMember<GenericEventQueue> m_asyncEventQueue;
- Vector<RefPtr<TextTrack> > m_addTrackTracks;
- Vector<RefPtr<TextTrack> > m_elementTracks;
- Vector<RefPtr<TextTrack> > m_inbandTracks;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > m_addTrackTracks;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > m_elementTracks;
+ WillBeHeapVector<RefPtrWillBeMember<TextTrack> > m_inbandTracks;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl
index bbcd2d96499..8fbc775a993 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TextTrackList.idl
@@ -24,15 +24,13 @@
*/
[
- GenerateVisitDOMWrapper=owner,
- RuntimeEnabled=VideoTrack,
+ SetWrapperReferenceFrom=owner,
] interface TextTrackList : EventTarget {
readonly attribute unsigned long length;
getter TextTrack item(unsigned long index);
- TextTrack getTrackById(DOMString id);
+ TextTrack? getTrackById(DOMString id);
attribute EventHandler onaddtrack;
attribute EventHandler onchange;
attribute EventHandler onremovetrack;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackBase.cpp b/chromium/third_party/WebKit/Source/core/html/track/TrackBase.cpp
new file mode 100644
index 00000000000..a63849b253f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackBase.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/track/TrackBase.h"
+
+#include "core/html/HTMLMediaElement.h"
+
+namespace WebCore {
+
+static blink::WebMediaPlayer::TrackId nextTrackId()
+{
+ static blink::WebMediaPlayer::TrackId next = 0;
+ return ++next;
+}
+
+TrackBase::TrackBase(Type type, const AtomicString& label, const AtomicString& language, const String& id)
+ : m_trackId(nextTrackId())
+ , m_type(type)
+ , m_label(label)
+ , m_language(language)
+ , m_id(id)
+ , m_mediaElement(nullptr)
+{
+}
+
+TrackBase::~TrackBase()
+{
+#if !ENABLE(OILPAN)
+ ASSERT(!m_mediaElement);
+#endif
+}
+
+
+Node* TrackBase::owner() const
+{
+ return m_mediaElement;
+}
+
+void TrackBase::trace(Visitor* visitor)
+{
+ visitor->trace(m_mediaElement);
+}
+
+void TrackBase::setKind(const AtomicString& kind)
+{
+ if (isValidKind(kind))
+ m_kind = kind;
+ else
+ m_kind = defaultKind();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackBase.h b/chromium/third_party/WebKit/Source/core/html/track/TrackBase.h
index 38ead6489f0..cff2b8a6562 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TrackBase.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackBase.h
@@ -26,24 +26,56 @@
#ifndef TrackBase_h
#define TrackBase_h
-#include "core/events/EventTarget.h"
+#include "platform/heap/Handle.h"
+#include "public/platform/WebMediaPlayer.h"
#include "wtf/RefCounted.h"
+#include "wtf/text/AtomicString.h"
namespace WebCore {
-class TrackBase : public RefCounted<TrackBase>, public EventTargetWithInlineData {
- REFCOUNTED_EVENT_TARGET(TrackBase);
+class HTMLMediaElement;
+
+class TrackBase : public RefCountedWillBeRefCountedGarbageCollected<TrackBase> {
public:
- virtual ~TrackBase() { }
+ virtual ~TrackBase();
+
+ blink::WebMediaPlayer::TrackId trackId() const { return m_trackId; }
enum Type { TextTrack, AudioTrack, VideoTrack };
Type type() const { return m_type; }
+ const AtomicString& kind() const { return m_kind; }
+ virtual void setKind(const AtomicString&);
+
+ AtomicString label() const { return m_label; }
+ void setLabel(const AtomicString& label) { m_label = label; }
+
+ AtomicString language() const { return m_language; }
+ void setLanguage(const AtomicString& language) { m_language = language; }
+
+ String id() const { return m_id; }
+ void setId(const String& id) { m_id = id; }
+
+ void setMediaElement(HTMLMediaElement* mediaElement) { m_mediaElement = mediaElement; }
+ HTMLMediaElement* mediaElement() const { return m_mediaElement; }
+ Node* owner() const;
+
+ virtual void trace(Visitor*);
+
protected:
- explicit TrackBase(Type type) : m_type(type) { }
+ TrackBase(Type, const AtomicString& label, const AtomicString& language, const String& id);
+
+ virtual bool isValidKind(const AtomicString&) const = 0;
+ virtual AtomicString defaultKind() const = 0;
private:
+ blink::WebMediaPlayer::TrackId m_trackId;
Type m_type;
+ AtomicString m_kind;
+ AtomicString m_label;
+ AtomicString m_language;
+ String m_id;
+ RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp
index 39d70bd1961..12d9263eb33 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.cpp
@@ -27,8 +27,6 @@
#include "core/html/track/TrackEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-
namespace WebCore {
TrackEventInit::TrackEventInit()
@@ -57,5 +55,11 @@ const AtomicString& TrackEvent::interfaceName() const
return EventNames::TrackEvent;
}
+void TrackEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_track);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h
index 606bc1488cc..b77be6b7998 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.h
@@ -34,32 +34,34 @@ namespace WebCore {
struct TrackEventInit : public EventInit {
TrackEventInit();
- RefPtr<TrackBase> track;
+ RefPtrWillBeMember<TrackBase> track;
};
-class TrackEvent : public Event {
+class TrackEvent FINAL : public Event {
public:
virtual ~TrackEvent();
- static PassRefPtr<TrackEvent> create()
+ static PassRefPtrWillBeRawPtr<TrackEvent> create()
{
- return adoptRef(new TrackEvent);
+ return adoptRefWillBeNoop(new TrackEvent);
}
- static PassRefPtr<TrackEvent> create(const AtomicString& type, const TrackEventInit& initializer)
+ static PassRefPtrWillBeRawPtr<TrackEvent> create(const AtomicString& type, const TrackEventInit& initializer)
{
- return adoptRef(new TrackEvent(type, initializer));
+ return adoptRefWillBeNoop(new TrackEvent(type, initializer));
}
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
TrackBase* track() const { return m_track.get(); }
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
TrackEvent();
TrackEvent(const AtomicString& type, const TrackEventInit& initializer);
- RefPtr<TrackBase> m_track;
+ RefPtrWillBeMember<TrackBase> m_track;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl
index eed92389f38..38ad03dcdd8 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackEvent.idl
@@ -24,9 +24,7 @@
*/
[
- RuntimeEnabled=VideoTrack,
EventConstructor,
] interface TrackEvent : Event {
[InitializedByEventConstructor, Custom=Getter] readonly attribute object track;
-};
-
+}; \ No newline at end of file
diff --git a/chromium/third_party/WebKit/Source/core/html/track/TrackListBase.h b/chromium/third_party/WebKit/Source/core/html/track/TrackListBase.h
new file mode 100644
index 00000000000..24405a482d7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/TrackListBase.h
@@ -0,0 +1,139 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TrackListBase_h
+#define TrackListBase_h
+
+#include "core/events/EventTarget.h"
+
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/track/TrackEvent.h"
+
+namespace WebCore {
+
+template<class T>
+class TrackListBase : public RefCountedWillBeRefCountedGarbageCollected<TrackListBase<T> >, public EventTargetWithInlineData {
+ REFCOUNTED_EVENT_TARGET(TrackListBase);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(TrackListBase);
+public:
+ explicit TrackListBase(HTMLMediaElement* mediaElement)
+ : m_mediaElement(mediaElement)
+ {
+ }
+
+ virtual ~TrackListBase()
+ {
+#if !ENABLE(OILPAN)
+ ASSERT(m_tracks.isEmpty());
+ ASSERT(!m_mediaElement);
+#endif
+ }
+
+ unsigned length() const { return m_tracks.size(); }
+ T* anonymousIndexedGetter(unsigned index) const
+ {
+ if (index >= m_tracks.size())
+ return 0;
+ return m_tracks[index].get();
+ }
+
+ T* getTrackById(const String& id) const
+ {
+ for (unsigned i = 0; i < m_tracks.size(); ++i) {
+ if (m_tracks[i]->id() == id)
+ return m_tracks[i].get();
+ }
+
+ return 0;
+ }
+
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(addtrack);
+ DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
+
+ // EventTarget interface
+ virtual ExecutionContext* executionContext() const OVERRIDE
+ {
+ if (m_mediaElement)
+ return m_mediaElement->executionContext();
+ return 0;
+ }
+
+#if !ENABLE(OILPAN)
+ void shutdown()
+ {
+ removeAll();
+ m_mediaElement = nullptr;
+ }
+#endif
+
+ void add(PassRefPtrWillBeRawPtr<T> prpTrack)
+ {
+ RefPtrWillBeRawPtr<T> track = prpTrack;
+
+ track->setMediaElement(m_mediaElement);
+ m_tracks.append(track);
+ scheduleTrackEvent(EventTypeNames::addtrack, track.release());
+ }
+
+ void remove(blink::WebMediaPlayer::TrackId trackId)
+ {
+ for (unsigned i = 0; i < m_tracks.size(); ++i) {
+ if (m_tracks[i]->trackId() != trackId)
+ continue;
+
+ m_tracks[i]->setMediaElement(0);
+ scheduleTrackEvent(EventTypeNames::removetrack, m_tracks[i]);
+ m_tracks.remove(i);
+ return;
+ }
+ ASSERT_NOT_REACHED();
+ }
+
+ void removeAll()
+ {
+ for (unsigned i = 0; i < m_tracks.size(); ++i)
+ m_tracks[i]->setMediaElement(0);
+
+ m_tracks.clear();
+ }
+
+ void scheduleChangeEvent()
+ {
+ EventInit initializer;
+ initializer.bubbles = false;
+ initializer.cancelable = false;
+ RefPtrWillBeRawPtr<Event> event = Event::create(EventTypeNames::change, initializer);
+ event->setTarget(this);
+ m_mediaElement->scheduleEvent(event);
+ }
+
+ Node* owner() const { return m_mediaElement; }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_tracks);
+ visitor->trace(m_mediaElement);
+ EventTargetWithInlineData::trace(visitor);
+ }
+
+private:
+ void scheduleTrackEvent(const AtomicString& eventName, PassRefPtrWillBeRawPtr<T> track)
+ {
+ TrackEventInit initializer;
+ initializer.track = track;
+ initializer.bubbles = false;
+ initializer.cancelable = false;
+ RefPtrWillBeRawPtr<Event> event = TrackEvent::create(eventName, initializer);
+ event->setTarget(this);
+ m_mediaElement->scheduleEvent(event);
+ }
+
+ WillBeHeapVector<RefPtrWillBeMember<T> > m_tracks;
+ RawPtrWillBeMember<HTMLMediaElement> m_mediaElement;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.cpp b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.cpp
new file mode 100644
index 00000000000..5a93e6ed0f7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.cpp
@@ -0,0 +1,88 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/track/VideoTrack.h"
+
+#include "core/html/HTMLMediaElement.h"
+
+namespace WebCore {
+
+VideoTrack::VideoTrack(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool selected)
+ : TrackBase(TrackBase::VideoTrack, label, language, id)
+ , m_selected(selected)
+{
+ ScriptWrappable::init(this);
+ setKind(kind);
+}
+
+VideoTrack::~VideoTrack()
+{
+}
+
+void VideoTrack::setSelected(bool selected)
+{
+ if (selected == m_selected)
+ return;
+
+ m_selected = selected;
+
+ if (mediaElement()) {
+ blink::WebMediaPlayer::TrackId selectedTrackId = trackId();
+ mediaElement()->selectedVideoTrackChanged(selected ? &selectedTrackId : 0);
+ }
+}
+
+const AtomicString& VideoTrack::alternativeKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("alternative", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::captionsKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("captions", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::mainKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("main", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::signKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("sign", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::subtitlesKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("subtitles", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+const AtomicString& VideoTrack::commentaryKeyword()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, keyword, ("commentary", AtomicString::ConstructFromLiteral));
+ return keyword;
+}
+
+bool VideoTrack::isValidKind(const AtomicString& kind) const
+{
+ return (kind == alternativeKeyword())
+ || (kind == captionsKeyword())
+ || (kind == mainKeyword())
+ || (kind == signKeyword())
+ || (kind == subtitlesKeyword())
+ || (kind == commentaryKeyword());
+}
+
+AtomicString VideoTrack::defaultKind() const
+{
+ return emptyAtom;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.h b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.h
new file mode 100644
index 00000000000..8e405e4f2ab
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.h
@@ -0,0 +1,48 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VideoTrack_h
+#define VideoTrack_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/track/TrackBase.h"
+
+namespace WebCore {
+
+class VideoTrack FINAL : public TrackBase, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<VideoTrack> create(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool selected)
+ {
+ return adoptRefWillBeRefCountedGarbageCollected(new VideoTrack(id, kind, label, language, selected));
+ }
+ virtual ~VideoTrack();
+
+ bool selected() const { return m_selected; }
+ void setSelected(bool);
+
+ // Set selected to false without notifying the owner media element. Used when
+ // another video track is selected, implicitly deselecting this one.
+ void clearSelected() { m_selected = false; }
+
+ // Valid kind keywords.
+ static const AtomicString& alternativeKeyword();
+ static const AtomicString& captionsKeyword();
+ static const AtomicString& mainKeyword();
+ static const AtomicString& signKeyword();
+ static const AtomicString& subtitlesKeyword();
+ static const AtomicString& commentaryKeyword();
+
+private:
+ VideoTrack(const String& id, const AtomicString& kind, const AtomicString& label, const AtomicString& language, bool selected);
+
+ // TrackBase
+ virtual bool isValidKind(const AtomicString&) const OVERRIDE;
+ virtual AtomicString defaultKind() const OVERRIDE;
+
+ bool m_selected;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.idl b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.idl
new file mode 100644
index 00000000000..cc4efee29da
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrack.idl
@@ -0,0 +1,15 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=AudioVideoTracks,
+ SetWrapperReferenceFrom=owner,
+ WillBeGarbageCollected,
+] interface VideoTrack {
+ readonly attribute DOMString id;
+ readonly attribute DOMString kind;
+ readonly attribute DOMString label;
+ readonly attribute DOMString language;
+ attribute boolean selected;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.cpp b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.cpp
new file mode 100644
index 00000000000..e107717dfa4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.cpp
@@ -0,0 +1,60 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/html/track/VideoTrackList.h"
+
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/track/VideoTrack.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<VideoTrackList> VideoTrackList::create(HTMLMediaElement& mediaElement)
+{
+ return adoptRefWillBeRefCountedGarbageCollected(new VideoTrackList(mediaElement));
+}
+
+VideoTrackList::~VideoTrackList()
+{
+}
+
+VideoTrackList::VideoTrackList(HTMLMediaElement& mediaElement)
+ : TrackListBase<VideoTrack>(&mediaElement)
+{
+ ScriptWrappable::init(this);
+}
+
+const AtomicString& VideoTrackList::interfaceName() const
+{
+ return EventTargetNames::VideoTrackList;
+}
+
+int VideoTrackList::selectedIndex() const
+{
+ for (unsigned i = 0; i < length(); ++i) {
+ VideoTrack* track = anonymousIndexedGetter(i);
+
+ if (track->selected())
+ return i;
+ }
+
+ return -1;
+}
+
+void VideoTrackList::trackSelected(blink::WebMediaPlayer::TrackId selectedTrackId)
+{
+ // Clear the selected flag on the previously selected track, if any.
+ for (unsigned i = 0; i < length(); ++i) {
+ VideoTrack* track = anonymousIndexedGetter(i);
+
+ if (track->trackId() != selectedTrackId)
+ track->clearSelected();
+ else
+ ASSERT(track->selected());
+ }
+
+ scheduleChangeEvent();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.h b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.h
new file mode 100644
index 00000000000..5e60b3171cb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VideoTrackList_h
+#define VideoTrackList_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/html/track/TrackListBase.h"
+#include "core/html/track/VideoTrack.h"
+
+namespace WebCore {
+
+class VideoTrackList FINAL : public TrackListBase<VideoTrack>, public ScriptWrappable {
+public:
+ static PassRefPtrWillBeRawPtr<VideoTrackList> create(HTMLMediaElement&);
+
+ virtual ~VideoTrackList();
+
+ int selectedIndex() const;
+
+ // EventTarget
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ void trackSelected(blink::WebMediaPlayer::TrackId selectedTrackId);
+
+private:
+ explicit VideoTrackList(HTMLMediaElement&);
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.idl b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.idl
new file mode 100644
index 00000000000..f7663350649
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/VideoTrackList.idl
@@ -0,0 +1,17 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+ RuntimeEnabled=AudioVideoTracks,
+ SetWrapperReferenceFrom=owner,
+] interface VideoTrackList : EventTarget {
+ readonly attribute unsigned long length;
+ getter VideoTrack (unsigned long index);
+ VideoTrack? getTrackById(DOMString id);
+ readonly attribute long selectedIndex;
+
+ attribute EventHandler onchange;
+ attribute EventHandler onaddtrack;
+ attribute EventHandler onremovetrack;
+};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp
index 3a4aab74416..2c024bb3d9c 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/BufferedLineReader.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "BufferedLineReader.h"
+#include "core/html/track/vtt/BufferedLineReader.h"
#include "wtf/unicode/CharacterNames.h"
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp
index ab185dc3d67..8069c26ad2f 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.cpp
@@ -30,21 +30,23 @@
#include "config.h"
#include "core/html/track/vtt/VTTCue.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/NodeTraversal.h"
#include "core/events/Event.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/track/TextTrack.h"
#include "core/html/track/TextTrackCueList.h"
#include "core/html/track/vtt/VTTElement.h"
#include "core/html/track/vtt/VTTParser.h"
#include "core/html/track/vtt/VTTRegionList.h"
+#include "core/html/track/vtt/VTTScanner.h"
#include "core/rendering/RenderVTTCue.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/BidiResolver.h"
#include "platform/text/TextRunIterator.h"
#include "wtf/MathExtras.h"
@@ -53,6 +55,7 @@
namespace WebCore {
static const int undefinedPosition = -1;
+static const int undefinedSize = -1;
static const CSSValueID displayWritingModeMap[] = {
CSSValueHorizontalTb, CSSValueVerticalRl, CSSValueVerticalLr
@@ -113,12 +116,10 @@ static const String& verticalGrowingRightKeyword()
return verticallr;
}
-static bool isInvalidPercentage(double value, ExceptionState& exceptionState)
+static bool isInvalidPercentage(int value, ExceptionState& exceptionState)
{
- if (TextTrackCue::isInfiniteOrNonNumber(value, exceptionState))
- return true;
if (value < 0 || value > 100) {
- exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(value) + ") is not between 0 and 100.");
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("value", value, 0, ExceptionMessages::InclusiveBound, 100, ExceptionMessages::InclusiveBound));
return true;
}
return false;
@@ -128,7 +129,7 @@ VTTCueBox::VTTCueBox(Document& document, VTTCue* cue)
: HTMLDivElement(document)
, m_cue(cue)
{
- setPseudo(AtomicString("-webkit-media-text-track-display", AtomicString::ConstructFromLiteral));
+ setShadowPseudoId(AtomicString("-webkit-media-text-track-display", AtomicString::ConstructFromLiteral));
}
void VTTCueBox::applyCSSProperties(const IntSize&)
@@ -199,6 +200,12 @@ RenderObject* VTTCueBox::createRenderer(RenderStyle*)
return new RenderVTTCue(this);
}
+void VTTCueBox::trace(Visitor* visitor)
+{
+ visitor->trace(m_cue);
+ HTMLDivElement::trace(visitor);
+}
+
VTTCue::VTTCue(Document& document, double startTime, double endTime, const String& text)
: TextTrackCue(startTime, endTime)
, m_text(text)
@@ -208,19 +215,29 @@ VTTCue::VTTCue(Document& document, double startTime, double endTime, const Strin
, m_cueSize(100)
, m_writingDirection(Horizontal)
, m_cueAlignment(Middle)
- , m_vttNodeTree(0)
+ , m_vttNodeTree(nullptr)
, m_cueBackgroundBox(HTMLDivElement::create(document))
, m_displayDirection(CSSValueLtr)
+ , m_displaySize(undefinedSize)
, m_snapToLines(true)
, m_displayTreeShouldChange(true)
, m_notifyRegion(true)
{
ScriptWrappable::init(this);
+ UseCounter::count(document, UseCounter::VTTCue);
}
VTTCue::~VTTCue()
{
- displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
+ // Using oilpan, if m_displayTree is in the document it will strongly keep
+ // the cue alive. Thus, if the cue is dead, either m_displayTree is not in
+ // the document or the entire document is dead too.
+#if !ENABLE(OILPAN)
+ // FIXME: This is scary, we should make the life cycle smarter so the destructor
+ // doesn't need to do DOM mutations.
+ if (m_displayTree)
+ m_displayTree->remove(ASSERT_NO_EXCEPTION);
+#endif
}
#ifndef NDEBUG
@@ -230,11 +247,11 @@ String VTTCue::toString() const
}
#endif
-PassRefPtr<VTTCueBox> VTTCue::displayTreeInternal()
+VTTCueBox& VTTCue::ensureDisplayTree()
{
if (!m_displayTree)
m_displayTree = VTTCueBox::create(document(), this);
- return m_displayTree;
+ return *m_displayTree;
}
void VTTCue::cueDidChange()
@@ -258,14 +275,8 @@ const String& VTTCue::vertical() const
}
}
-void VTTCue::setVertical(const String& value, ExceptionState& exceptionState)
+void VTTCue::setVertical(const String& value)
{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-vertical
- // On setting, the text track cue writing direction must be set to the value given
- // in the first cell of the row in the table above whose second cell is a
- // case-sensitive match for the new value, if any. If none of the values match, then
- // the user agent must instead throw a SyntaxError exception.
-
WritingDirection direction = m_writingDirection;
if (value == horizontalKeyword())
direction = Horizontal;
@@ -274,7 +285,7 @@ void VTTCue::setVertical(const String& value, ExceptionState& exceptionState)
else if (value == verticalGrowingRightKeyword())
direction = VerticalGrowingRight;
else
- exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet("vertical", "TextTrackCue", "The value provided ('" + value + "') is invalid. Only 'rl', 'lr', and the empty string are accepted."));
+ ASSERT_NOT_REACHED();
if (direction == m_writingDirection)
return;
@@ -300,7 +311,7 @@ void VTTCue::setLine(int position, ExceptionState& exceptionState)
// On setting, if the text track cue snap-to-lines flag is not set, and the new
// value is negative or greater than 100, then throw an IndexSizeError exception.
if (!m_snapToLines && (position < 0 || position > 100)) {
- exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::failedToSet("line", "TextTrackCue", "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100."));
+ exceptionState.throwDOMException(IndexSizeError, "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100.");
return;
}
@@ -367,14 +378,8 @@ const String& VTTCue::align() const
}
}
-void VTTCue::setAlign(const String& value, ExceptionState& exceptionState)
+void VTTCue::setAlign(const String& value)
{
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-align
- // On setting, the text track cue alignment must be set to the value given in the
- // first cell of the row in the table above whose second cell is a case-sensitive
- // match for the new value, if any. If none of the values match, then the user
- // agent must instead throw a SyntaxError exception.
-
CueAlignment alignment = m_cueAlignment;
if (value == startKeyword())
alignment = Start;
@@ -387,7 +392,7 @@ void VTTCue::setAlign(const String& value, ExceptionState& exceptionState)
else if (value == rightKeyword())
alignment = Right;
else
- exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet("align", "TextTrackCue", "The value provided ('" + value + "') is invalid. Only 'start', 'middle', 'end', 'left', and 'right' are accepted."));
+ ASSERT_NOT_REACHED();
if (alignment == m_cueAlignment)
return;
@@ -405,7 +410,7 @@ void VTTCue::setText(const String& text)
cueWillChange();
// Clear the document fragment but don't bother to create it again just yet as we can do that
// when it is requested.
- m_vttNodeTree = 0;
+ m_vttNodeTree = nullptr;
m_text = text;
cueDidChange();
}
@@ -419,7 +424,7 @@ void VTTCue::createVTTNodeTree()
void VTTCue::copyVTTNodeToDOMTree(ContainerNode* vttNode, ContainerNode* parent)
{
for (Node* node = vttNode->firstChild(); node; node = node->nextSibling()) {
- RefPtr<Node> clonedNode;
+ RefPtrWillBeRawPtr<Node> clonedNode;
if (node->isVTTElement())
clonedNode = toVTTElement(node)->createEquivalentHTMLElement(document());
else
@@ -430,19 +435,18 @@ void VTTCue::copyVTTNodeToDOMTree(ContainerNode* vttNode, ContainerNode* parent)
}
}
-PassRefPtr<DocumentFragment> VTTCue::getCueAsHTML()
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTCue::getCueAsHTML()
{
createVTTNodeTree();
- RefPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
+ RefPtrWillBeRawPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
copyVTTNodeToDOMTree(m_vttNodeTree.get(), clonedFragment.get());
return clonedFragment.release();
}
-PassRefPtr<DocumentFragment> VTTCue::createCueRenderingTree()
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTCue::createCueRenderingTree()
{
- RefPtr<DocumentFragment> clonedFragment;
createVTTNodeTree();
- clonedFragment = DocumentFragment::create(document());
+ RefPtrWillBeRawPtr<DocumentFragment> clonedFragment = DocumentFragment::create(document());
m_vttNodeTree->cloneChildNodes(clonedFragment.get());
return clonedFragment.release();
}
@@ -550,6 +554,9 @@ void VTTCue::calculateDisplayParameters()
// Steps 10.2, 10.3
m_displayDirection = determineTextDirection(m_vttNodeTree.get());
+ if (m_displayDirection == CSSValueRtl)
+ UseCounter::count(document(), UseCounter::VTTCueRenderRtl);
+
// 10.4 If the text track cue writing direction is horizontal, then let
// block-flow be 'tb'. Otherwise, if the text track cue writing direction is
// vertical growing left, then let block-flow be 'lr'. Otherwise, the text
@@ -621,7 +628,7 @@ void VTTCue::calculateDisplayParameters()
else
m_displayPosition.first = 100 - m_textPosition - m_displaySize / 2;
break;
- case NumberOfAlignments:
+ default:
ASSERT_NOT_REACHED();
}
} else {
@@ -638,7 +645,7 @@ void VTTCue::calculateDisplayParameters()
case Middle:
m_displayPosition.second = m_textPosition - m_displaySize / 2;
break;
- case NumberOfAlignments:
+ default:
ASSERT_NOT_REACHED();
}
}
@@ -675,10 +682,8 @@ void VTTCue::markFutureAndPastNodes(ContainerNode* root, double previousTimestam
for (Node* child = root->firstChild(); child; child = NodeTraversal::next(*child, root)) {
if (child->nodeName() == timestampTag) {
- unsigned position = 0;
- String timestamp = child->nodeValue();
double currentTimestamp;
- bool check = VTTParser::collectTimeStamp(timestamp, &position, currentTimestamp);
+ bool check = VTTParser::collectTimeStamp(child->nodeValue(), currentTimestamp);
ASSERT_UNUSED(check, check);
if (currentTimestamp > movieTime)
@@ -706,16 +711,16 @@ void VTTCue::updateDisplayTree(double movieTime)
m_cueBackgroundBox->removeChildren();
// Update the two sets containing past and future WebVTT objects.
- RefPtr<DocumentFragment> referenceTree = createCueRenderingTree();
+ RefPtrWillBeRawPtr<DocumentFragment> referenceTree = createCueRenderingTree();
markFutureAndPastNodes(referenceTree.get(), startTime(), movieTime);
m_cueBackgroundBox->appendChild(referenceTree, ASSERT_NO_EXCEPTION);
}
-PassRefPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
+PassRefPtrWillBeRawPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
{
- RefPtr<VTTCueBox> displayTree = displayTreeInternal();
+ RefPtrWillBeRawPtr<VTTCueBox> displayTree(ensureDisplayTree());
if (!m_displayTreeShouldChange || !track()->isRendered())
- return displayTree;
+ return displayTree.release();
// 10.1 - 10.10
calculateDisplayParameters();
@@ -732,7 +737,7 @@ PassRefPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
// background box.
// Note: This is contained by default in m_cueBackgroundBox.
- m_cueBackgroundBox->setPseudo(cueShadowPseudoId());
+ m_cueBackgroundBox->setShadowPseudoId(cueShadowPseudoId());
displayTree->appendChild(m_cueBackgroundBox);
// FIXME(BUG 79916): Runs of children of WebVTT Ruby Objects that are not
@@ -752,7 +757,7 @@ PassRefPtr<VTTCueBox> VTTCue::getDisplayTree(const IntSize& videoSize)
// 10.15. Let cue's text track cue display state have the CSS boxes in
// boxes.
- return displayTree;
+ return displayTree.release();
}
void VTTCue::removeDisplayTree()
@@ -764,12 +769,33 @@ void VTTCue::removeDisplayTree()
region->willRemoveVTTCueBox(m_displayTree.get());
}
- displayTreeInternal()->remove(ASSERT_NO_EXCEPTION);
+ if (m_displayTree)
+ m_displayTree->remove(ASSERT_NO_EXCEPTION);
}
void VTTCue::updateDisplay(const IntSize& videoSize, HTMLDivElement& container)
{
- RefPtr<VTTCueBox> displayBox = getDisplayTree(videoSize);
+ UseCounter::count(document(), UseCounter::VTTCueRender);
+
+ if (m_writingDirection != Horizontal)
+ UseCounter::count(document(), UseCounter::VTTCueRenderVertical);
+
+ if (!m_snapToLines)
+ UseCounter::count(document(), UseCounter::VTTCueRenderSnapToLinesFalse);
+
+ if (m_linePosition != undefinedPosition)
+ UseCounter::count(document(), UseCounter::VTTCueRenderLineNotAuto);
+
+ if (m_textPosition != 50)
+ UseCounter::count(document(), UseCounter::VTTCueRenderPositionNot50);
+
+ if (m_cueSize != 100)
+ UseCounter::count(document(), UseCounter::VTTCueRenderSizeNot100);
+
+ if (m_cueAlignment != Middle)
+ UseCounter::count(document(), UseCounter::VTTCueRenderAlignNotMiddle);
+
+ RefPtrWillBeRawPtr<VTTCueBox> displayBox = getDisplayTree(videoSize);
VTTRegion* region = 0;
if (track()->regions())
region = track()->regions()->getRegionById(regionId());
@@ -778,14 +804,14 @@ void VTTCue::updateDisplay(const IntSize& videoSize, HTMLDivElement& container)
// If cue has an empty text track cue region identifier or there is no
// WebVTT region whose region identifier is identical to cue's text
// track cue region identifier, run the following substeps:
- if (displayBox->hasChildNodes() && !container.contains(displayBox.get())) {
+ if (displayBox->hasChildren() && !container.contains(displayBox.get())) {
// Note: the display tree of a cue is removed when the active flag of the cue is unset.
container.appendChild(displayBox);
}
} else {
// Let region be the WebVTT region whose region identifier
// matches the text track cue region identifier of cue.
- RefPtr<HTMLDivElement> regionNode = region->getDisplayTree(document());
+ RefPtrWillBeRawPtr<HTMLDivElement> regionNode = region->getDisplayTree(document());
// Append the region to the viewport, if it was not already.
if (!container.contains(regionNode.get()))
@@ -833,42 +859,65 @@ std::pair<double, double> VTTCue::getPositionCoordinates() const
return coordinates;
}
-VTTCue::CueSetting VTTCue::settingName(const String& name)
+VTTCue::CueSetting VTTCue::settingName(VTTScanner& input)
{
- DEFINE_STATIC_LOCAL(const String, verticalKeyword, ("vertical"));
- DEFINE_STATIC_LOCAL(const String, lineKeyword, ("line"));
- DEFINE_STATIC_LOCAL(const String, positionKeyword, ("position"));
- DEFINE_STATIC_LOCAL(const String, sizeKeyword, ("size"));
- DEFINE_STATIC_LOCAL(const String, alignKeyword, ("align"));
- DEFINE_STATIC_LOCAL(const String, regionIdKeyword, ("region"));
-
- if (name == verticalKeyword)
- return Vertical;
- if (name == lineKeyword)
- return Line;
- if (name == positionKeyword)
- return Position;
- if (name == sizeKeyword)
- return Size;
- if (name == alignKeyword)
- return Align;
- if (RuntimeEnabledFeatures::webVTTRegionsEnabled() && name == regionIdKeyword)
- return RegionId;
-
+ CueSetting parsedSetting = None;
+ if (input.scan("vertical"))
+ parsedSetting = Vertical;
+ else if (input.scan("line"))
+ parsedSetting = Line;
+ else if (input.scan("position"))
+ parsedSetting = Position;
+ else if (input.scan("size"))
+ parsedSetting = Size;
+ else if (input.scan("align"))
+ parsedSetting = Align;
+ else if (RuntimeEnabledFeatures::webVTTRegionsEnabled() && input.scan("region"))
+ parsedSetting = RegionId;
+ // Verify that a ':' follows.
+ if (parsedSetting != None && input.scan(':'))
+ return parsedSetting;
return None;
}
-void VTTCue::parseSettings(const String& input)
+// Used for 'position' and 'size'.
+static bool scanPercentage(VTTScanner& input, const VTTScanner::Run& valueRun, int& number)
{
- unsigned position = 0;
+ // 1. If value contains any characters other than U+0025 PERCENT SIGN
+ // characters (%) and characters in the range U+0030 DIGIT ZERO (0) to
+ // U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
+ // 2. If value does not contain at least one character in the range U+0030
+ // DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step
+ // labeled next setting.
+ if (!input.scanDigits(number))
+ return false;
+
+ // 3. If any character in value other than the last character is a U+0025
+ // PERCENT SIGN character (%), then jump to the step labeled next
+ // setting.
+ // 4. If the last character in value is not a U+0025 PERCENT SIGN character
+ // (%), then jump to the step labeled next setting.
+ if (!input.scan('%') || !input.isAt(valueRun.end()))
+ return false;
+
+ // 5. Ignoring the trailing percent sign, interpret value as an integer,
+ // and let number be that number.
+ // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step
+ // labeled next setting.
+ return number >= 0 && number <= 100;
+}
+
+void VTTCue::parseSettings(const String& inputString)
+{
+ VTTScanner input(inputString);
- while (position < input.length()) {
+ while (!input.isAtEnd()) {
// The WebVTT cue settings part of a WebVTT cue consists of zero or more of the following components, in any order,
// separated from each other by one or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
- while (position < input.length() && VTTParser::isValidSettingDelimiter(input[position]))
- position++;
- if (position >= input.length())
+ input.skipWhile<VTTParser::isValidSettingDelimiter>();
+
+ if (input.isAtEnd())
break;
// When the user agent is to parse the WebVTT settings given by a string input for a text track cue cue,
@@ -877,48 +926,38 @@ void VTTCue::parseSettings(const String& input)
// 2. For each token setting in the list settings, run the following substeps:
// 1. If setting does not contain a U+003A COLON character (:), or if the first U+003A COLON character (:)
// in setting is either the first or last character of setting, then jump to the step labeled next setting.
- unsigned endOfSetting = position;
- String setting = VTTParser::collectWord(input, &endOfSetting);
- CueSetting name;
- size_t colonOffset = setting.find(':', 1);
- if (colonOffset == kNotFound || !colonOffset || colonOffset == setting.length() - 1)
- goto NextSetting;
-
- // 2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
- name = settingName(setting.substring(0, colonOffset));
+ // 2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
+ CueSetting name = settingName(input);
// 3. Let value be the trailing substring of setting starting from the character immediately after the first U+003A COLON character (:) in that string.
- position += colonOffset + 1;
- if (position >= input.length())
- break;
+ VTTScanner::Run valueRun = input.collectUntil<VTTParser::isValidSettingDelimiter>();
// 4. Run the appropriate substeps that apply for the value of name, as follows:
switch (name) {
- case Vertical:
- {
+ case Vertical: {
// If name is a case-sensitive match for "vertical"
// 1. If value is a case-sensitive match for the string "rl", then let cue's text track cue writing direction
// be vertical growing left.
- String writingDirection = VTTParser::collectWord(input, &position);
- if (writingDirection == verticalGrowingLeftKeyword())
+ if (input.scanRun(valueRun, verticalGrowingLeftKeyword()))
m_writingDirection = VerticalGrowingLeft;
// 2. Otherwise, if value is a case-sensitive match for the string "lr", then let cue's text track cue writing
// direction be vertical growing right.
- else if (writingDirection == verticalGrowingRightKeyword())
+ else if (input.scanRun(valueRun, verticalGrowingRightKeyword()))
m_writingDirection = VerticalGrowingRight;
- }
break;
- case Line:
- {
+ }
+ case Line: {
// 1-2 - Collect chars that are either '-', '%', or a digit.
// 1. If value contains any characters other than U+002D HYPHEN-MINUS characters (-), U+0025 PERCENT SIGN
// characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump
// to the step labeled next setting.
- StringBuilder linePositionBuilder;
- while (position < input.length() && (input[position] == '-' || input[position] == '%' || isASCIIDigit(input[position])))
- linePositionBuilder.append(input[position++]);
- if (position < input.length() && !VTTParser::isValidSettingDelimiter(input[position]))
+ bool isNegative = input.scan('-');
+ int linePosition;
+ unsigned numDigits = input.scanDigits(linePosition);
+ bool isPercentage = input.scan('%');
+
+ if (!input.isAt(valueRun.end()))
break;
// 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
@@ -927,134 +966,83 @@ void VTTCue::parseSettings(const String& input)
// jump to the step labeled next setting.
// 4. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then
// jump to the step labeled next setting.
- String linePosition = linePositionBuilder.toString();
- if (linePosition.find('-', 1) != kNotFound || linePosition.reverseFind("%", linePosition.length() - 2) != kNotFound)
- break;
// 5. If the first character in value is a U+002D HYPHEN-MINUS character (-) and the last character in value is a
// U+0025 PERCENT SIGN character (%), then jump to the step labeled next setting.
- if (linePosition[0] == '-' && linePosition[linePosition.length() - 1] == '%')
+ if (!numDigits || (isPercentage && isNegative))
break;
// 6. Ignoring the trailing percent sign, if any, interpret value as a (potentially signed) integer, and
// let number be that number.
- // NOTE: toInt ignores trailing non-digit characters, such as '%'.
- bool validNumber;
- int number = linePosition.toInt(&validNumber);
- if (!validNumber)
- break;
-
// 7. If the last character in value is a U+0025 PERCENT SIGN character (%), but number is not in the range
// 0 ≤ number ≤ 100, then jump to the step labeled next setting.
// 8. Let cue's text track cue line position be number.
// 9. If the last character in value is a U+0025 PERCENT SIGN character (%), then let cue's text track cue
// snap-to-lines flag be false. Otherwise, let it be true.
- if (linePosition[linePosition.length() - 1] == '%') {
- if (number < 0 || number > 100)
+ if (isPercentage) {
+ if (linePosition < 0 || linePosition > 100)
break;
-
// 10 - If '%' then set snap-to-lines flag to false.
m_snapToLines = false;
+ } else {
+ if (isNegative)
+ linePosition = -linePosition;
+ m_snapToLines = true;
}
-
- m_linePosition = number;
- }
+ m_linePosition = linePosition;
break;
- case Position:
- {
- // 1. If value contains any characters other than U+0025 PERCENT SIGN characters (%) and characters in the range
- // U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
- // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9),
- // then jump to the step labeled next setting.
+ }
+ case Position: {
int number;
- if (!VTTParser::collectDigitsToInt(input, &position, number))
- break;
- if (position >= input.length())
- break;
-
- // 3. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then jump
- // to the step labeled next setting.
- // 4. If the last character in value is not a U+0025 PERCENT SIGN character (%), then jump to the step labeled
- // next setting.
- if (input[position++] != '%')
- break;
- if (position < input.length() && !VTTParser::isValidSettingDelimiter(input[position]))
- break;
-
- // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
- // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
- // NOTE: toInt ignores trailing non-digit characters, such as '%'.
- if (number < 0 || number > 100)
+ // Steps 1 - 6.
+ if (!scanPercentage(input, valueRun, number))
break;
// 7. Let cue's text track cue text position be number.
m_textPosition = number;
- }
break;
- case Size:
- {
- // 1. If value contains any characters other than U+0025 PERCENT SIGN characters (%) and characters in the
- // range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump to the step labeled next setting.
- // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
- // NINE (9), then jump to the step labeled next setting.
+ }
+ case Size: {
int number;
- if (!VTTParser::collectDigitsToInt(input, &position, number))
- break;
- if (position >= input.length())
- break;
-
- // 3. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%),
- // then jump to the step labeled next setting.
- // 4. If the last character in value is not a U+0025 PERCENT SIGN character (%), then jump to the step
- // labeled next setting.
- if (input[position++] != '%')
- break;
- if (position < input.length() && !VTTParser::isValidSettingDelimiter(input[position]))
- break;
-
- // 5. Ignoring the trailing percent sign, interpret value as an integer, and let number be that number.
- // 6. If number is not in the range 0 ≤ number ≤ 100, then jump to the step labeled next setting.
- if (number < 0 || number > 100)
+ // Steps 1 - 6.
+ if (!scanPercentage(input, valueRun, number))
break;
// 7. Let cue's text track cue size be number.
m_cueSize = number;
- }
break;
- case Align:
- {
- String cueAlignment = VTTParser::collectWord(input, &position);
-
+ }
+ case Align: {
// 1. If value is a case-sensitive match for the string "start", then let cue's text track cue alignment be start alignment.
- if (cueAlignment == startKeyword())
+ if (input.scanRun(valueRun, startKeyword()))
m_cueAlignment = Start;
// 2. If value is a case-sensitive match for the string "middle", then let cue's text track cue alignment be middle alignment.
- else if (cueAlignment == middleKeyword())
+ else if (input.scanRun(valueRun, middleKeyword()))
m_cueAlignment = Middle;
// 3. If value is a case-sensitive match for the string "end", then let cue's text track cue alignment be end alignment.
- else if (cueAlignment == endKeyword())
+ else if (input.scanRun(valueRun, endKeyword()))
m_cueAlignment = End;
// 4. If value is a case-sensitive match for the string "left", then let cue's text track cue alignment be left alignment.
- else if (cueAlignment == leftKeyword())
+ else if (input.scanRun(valueRun, leftKeyword()))
m_cueAlignment = Left;
// 5. If value is a case-sensitive match for the string "right", then let cue's text track cue alignment be right alignment.
- else if (cueAlignment == rightKeyword())
+ else if (input.scanRun(valueRun, rightKeyword()))
m_cueAlignment = Right;
- }
break;
+ }
case RegionId:
- m_regionId = VTTParser::collectWord(input, &position);
+ m_regionId = input.extractString(valueRun);
break;
case None:
break;
}
-NextSetting:
- position = endOfSetting;
+ // Make sure the entire run is consumed.
+ input.skipRun(valueRun);
}
// If cue's line position is not auto or cue's size is not 100 or cue's
@@ -1084,6 +1072,7 @@ CSSValueID VTTCue::getCSSWritingMode() const
int VTTCue::getCSSSize() const
{
+ ASSERT(m_displaySize != undefinedSize);
return m_displaySize;
}
@@ -1107,4 +1096,12 @@ Document& VTTCue::document() const
return m_cueBackgroundBox->document();
}
+void VTTCue::trace(Visitor* visitor)
+{
+ visitor->trace(m_vttNodeTree);
+ visitor->trace(m_cueBackgroundBox);
+ visitor->trace(m_displayTree);
+ TextTrackCue::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h
index 05e6f8ecf1b..a43112dce4b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.h
@@ -32,42 +32,46 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/html/track/TextTrackCue.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class Document;
class ExecutionContext;
class VTTCue;
+class VTTScanner;
class VTTCueBox FINAL : public HTMLDivElement {
public:
- static PassRefPtr<VTTCueBox> create(Document& document, VTTCue* cue)
+ static PassRefPtrWillBeRawPtr<VTTCueBox> create(Document& document, VTTCue* cue)
{
- return adoptRef(new VTTCueBox(document, cue));
+ return adoptRefWillBeNoop(new VTTCueBox(document, cue));
}
VTTCue* getCue() const { return m_cue; }
void applyCSSProperties(const IntSize& videoSize);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
VTTCueBox(Document&, VTTCue*);
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- VTTCue* m_cue;
+ RawPtrWillBeMember<VTTCue> m_cue;
};
class VTTCue FINAL : public TextTrackCue, public ScriptWrappable {
public:
- static PassRefPtr<VTTCue> create(Document& document, double startTime, double endTime, const String& text)
+ static PassRefPtrWillBeRawPtr<VTTCue> create(Document& document, double startTime, double endTime, const String& text)
{
- return adoptRef(new VTTCue(document, startTime, endTime, text));
+ return adoptRefWillBeRefCountedGarbageCollected(new VTTCue(document, startTime, endTime, text));
}
virtual ~VTTCue();
const String& vertical() const;
- void setVertical(const String&, ExceptionState&);
+ void setVertical(const String&);
bool snapToLines() const { return m_snapToLines; }
void setSnapToLines(bool);
@@ -82,15 +86,15 @@ public:
void setSize(int, ExceptionState&);
const String& align() const;
- void setAlign(const String&, ExceptionState&);
+ void setAlign(const String&);
const String& text() const { return m_text; }
void setText(const String&);
void parseSettings(const String&);
- PassRefPtr<DocumentFragment> getCueAsHTML();
- PassRefPtr<DocumentFragment> createCueRenderingTree();
+ PassRefPtrWillBeRawPtr<DocumentFragment> getCueAsHTML();
+ PassRefPtrWillBeRawPtr<DocumentFragment> createCueRenderingTree();
const String& regionId() const { return m_regionId; }
void setRegionId(const String&);
@@ -136,13 +140,15 @@ public:
virtual String toString() const OVERRIDE;
#endif
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
VTTCue(Document&, double startTime, double endTime, const String& text);
Document& document() const;
- PassRefPtr<VTTCueBox> displayTreeInternal();
- PassRefPtr<VTTCueBox> getDisplayTree(const IntSize& videoSize);
+ VTTCueBox& ensureDisplayTree();
+ PassRefPtrWillBeRawPtr<VTTCueBox> getDisplayTree(const IntSize& videoSize);
virtual void cueDidChange() OVERRIDE;
@@ -162,7 +168,7 @@ private:
Align,
RegionId
};
- CueSetting settingName(const String&);
+ CueSetting settingName(VTTScanner&);
String m_text;
int m_linePosition;
@@ -173,9 +179,9 @@ private:
CueAlignment m_cueAlignment;
String m_regionId;
- RefPtr<DocumentFragment> m_vttNodeTree;
- RefPtr<HTMLDivElement> m_cueBackgroundBox;
- RefPtr<VTTCueBox> m_displayTree;
+ RefPtrWillBeMember<DocumentFragment> m_vttNodeTree;
+ RefPtrWillBeMember<HTMLDivElement> m_cueBackgroundBox;
+ RefPtrWillBeMember<VTTCueBox> m_displayTree;
CSSValueID m_displayDirection;
int m_displaySize;
@@ -186,11 +192,8 @@ private:
bool m_notifyRegion : 1;
};
-inline VTTCue* toVTTCue(TextTrackCue* cue)
-{
- // VTTCue is currently the only TextTrackCue subclass.
- return static_cast<VTTCue*>(cue);
-}
+// VTTCue is currently the only TextTrackCue subclass.
+DEFINE_TYPE_CASTS(VTTCue, TextTrackCue, cue, true, true);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl
index 8b958174353..3ca0307dfa3 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTCue.idl
@@ -27,18 +27,21 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+enum DirectionSetting { "" /* horizontal */, "rl", "lr" };
+enum AlignSetting { "start", "middle", "end", "left", "right" };
+
[
Constructor(double startTime, double endTime, DOMString text),
ConstructorCallWith=Document,
- RuntimeEnabled=VideoTrack,
+ SetWrapperReferenceFrom=owner,
] interface VTTCue : TextTrackCue {
[RuntimeEnabled=WebVTTRegions] attribute DOMString regionId;
- [RaisesException=Setter] attribute DOMString vertical;
+ attribute DirectionSetting vertical;
attribute boolean snapToLines;
[RaisesException=Setter] attribute long line;
[RaisesException=Setter] attribute long position;
[RaisesException=Setter] attribute long size;
- [RaisesException=Setter] attribute DOMString align;
+ attribute AlignSetting align;
attribute DOMString text;
DocumentFragment getCueAsHTML();
};
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp
index e9b350a1304..c56084ce40e 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/html/track/vtt/VTTElement.h"
-#include "HTMLElementFactory.h"
+#include "core/HTMLElementFactory.h"
namespace WebCore {
@@ -71,21 +71,21 @@ VTTElement::VTTElement(VTTNodeType nodeType, Document* document)
{
}
-PassRefPtr<VTTElement> VTTElement::create(VTTNodeType nodeType, Document* document)
+PassRefPtrWillBeRawPtr<VTTElement> VTTElement::create(VTTNodeType nodeType, Document* document)
{
- return adoptRef(new VTTElement(nodeType, document));
+ return adoptRefWillBeNoop(new VTTElement(nodeType, document));
}
-PassRefPtr<Element> VTTElement::cloneElementWithoutAttributesAndChildren()
+PassRefPtrWillBeRawPtr<Element> VTTElement::cloneElementWithoutAttributesAndChildren()
{
- RefPtr<VTTElement> clone = create(static_cast<VTTNodeType>(m_webVTTNodeType), &document());
+ RefPtrWillBeRawPtr<VTTElement> clone = create(static_cast<VTTNodeType>(m_webVTTNodeType), &document());
clone->setLanguage(m_language);
- return clone;
+ return clone.release();
}
-PassRefPtr<HTMLElement> VTTElement::createEquivalentHTMLElement(Document& document)
+PassRefPtrWillBeRawPtr<HTMLElement> VTTElement::createEquivalentHTMLElement(Document& document)
{
- RefPtr<HTMLElement> htmlElement;
+ RefPtrWillBeRawPtr<HTMLElement> htmlElement = nullptr;
switch (m_webVTTNodeType) {
case VTTNodeTypeClass:
case VTTNodeTypeLanguage:
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h
index 2fe08c79abe..6705add645b 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTElement.h
@@ -41,11 +41,11 @@ enum VTTNodeType {
class VTTElement FINAL : public Element {
public:
- static PassRefPtr<VTTElement> create(const VTTNodeType, Document*);
- static PassRefPtr<VTTElement> create(const QualifiedName&, Document*);
- PassRefPtr<HTMLElement> createEquivalentHTMLElement(Document&);
+ static PassRefPtrWillBeRawPtr<VTTElement> create(const VTTNodeType, Document*);
+ static PassRefPtrWillBeRawPtr<VTTElement> create(const QualifiedName&, Document*);
+ PassRefPtrWillBeRawPtr<HTMLElement> createEquivalentHTMLElement(Document&);
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
void setVTTNodeType(VTTNodeType type) { m_webVTTNodeType = static_cast<unsigned>(type); }
VTTNodeType webVTTNodeType() const { return static_cast<VTTNodeType>(m_webVTTNodeType); }
@@ -79,7 +79,7 @@ private:
AtomicString m_language;
};
-DEFINE_NODE_TYPE_CASTS(VTTElement, isVTTElement());
+DEFINE_ELEMENT_TYPE_CASTS(VTTElement, isVTTElement());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
index e1b4b2a372d..ef09051af16 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.cpp
@@ -35,103 +35,45 @@
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/Text.h"
#include "core/html/track/vtt/VTTElement.h"
+#include "core/html/track/vtt/VTTScanner.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/text/SegmentedString.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
+using namespace HTMLNames;
+
const double secondsPerHour = 3600;
const double secondsPerMinute = 60;
const double secondsPerMillisecond = 0.001;
const unsigned fileIdentifierLength = 6;
-static unsigned scanDigits(const String& input, unsigned* position)
-{
- unsigned startPosition = *position;
- while (*position < input.length() && isASCIIDigit(input[*position]))
- (*position)++;
- return *position - startPosition;
-}
-
-unsigned VTTParser::collectDigitsToInt(const String& input, unsigned* position, int& number)
-{
- unsigned startPosition = *position;
- unsigned numDigits = scanDigits(input, position);
- if (!numDigits) {
- number = 0;
- return 0;
- }
- bool validNumber;
- if (input.is8Bit())
- number = charactersToInt(input.characters8() + startPosition, numDigits, &validNumber);
- else
- number = charactersToInt(input.characters16() + startPosition, numDigits, &validNumber);
-
- // Since we know that scanDigits only scanned valid (ASCII) digits (and
- // hence that's what got passed to charactersToInt()), the remaining
- // failure mode for charactersToInt() is overflow, so if |validNumber| is
- // not true, then set |number| to the maximum int value.
- if (!validNumber)
- number = std::numeric_limits<int>::max();
- return numDigits;
-}
-
-String VTTParser::collectWord(const String& input, unsigned* position)
+bool VTTParser::parseFloatPercentageValue(VTTScanner& valueScanner, float& percentage)
{
- StringBuilder string;
- while (*position < input.length() && !isASpace(input[*position]))
- string.append(input[(*position)++]);
- return string.toString();
-}
-
-void VTTParser::skipWhiteSpace(const String& line, unsigned* position)
-{
- while (*position < line.length() && isASpace(line[*position]))
- (*position)++;
-}
-
-bool VTTParser::parseFloatPercentageValue(const String& value, float& percentage)
-{
- // '%' must be present and at the end of the setting value.
- if (value.isEmpty() || value[value.length() - 1] != '%')
+ float number;
+ if (!valueScanner.scanFloat(number))
return false;
-
- unsigned position = 0;
- unsigned digitsBeforeDot = scanDigits(value, &position);
- unsigned digitsAfterDot = 0;
- if (value[position] == '.') {
- position++;
-
- digitsAfterDot = scanDigits(value, &position);
- }
-
- // At least one digit required.
- if (!digitsBeforeDot && !digitsAfterDot)
+ // '%' must be present and at the end of the setting value.
+ if (!valueScanner.scan('%'))
return false;
-
- float number = value.toFloat();
if (number < 0 || number > 100)
return false;
-
percentage = number;
return true;
}
-bool VTTParser::parseFloatPercentageValuePair(const String& value, char delimiter, FloatPoint& valuePair)
+bool VTTParser::parseFloatPercentageValuePair(VTTScanner& valueScanner, char delimiter, FloatPoint& valuePair)
{
- // The delimiter can't be the first or second value because a pair of
- // percentages (x%,y%) implies that at least the first two characters
- // are the first percentage value.
- size_t delimiterOffset = value.find(delimiter, 2);
- if (delimiterOffset == kNotFound || delimiterOffset == value.length() - 1)
+ float firstCoord;
+ if (!parseFloatPercentageValue(valueScanner, firstCoord))
return false;
- float firstCoord;
- if (!parseFloatPercentageValue(value.substring(0, delimiterOffset), firstCoord))
+ if (!valueScanner.scan(delimiter))
return false;
float secondCoord;
- if (!parseFloatPercentageValue(value.substring(delimiterOffset + 1, value.length() - 1), secondCoord))
+ if (!parseFloatPercentageValue(valueScanner, secondCoord))
return false;
valuePair = FloatPoint(firstCoord, secondCoord);
@@ -148,13 +90,13 @@ VTTParser::VTTParser(VTTParserClient* client, Document& document)
{
}
-void VTTParser::getNewCues(Vector<RefPtr<VTTCue> >& outputCues)
+void VTTParser::getNewCues(WillBeHeapVector<RefPtrWillBeMember<VTTCue> >& outputCues)
{
- outputCues = m_cuelist;
- m_cuelist.clear();
+ outputCues = m_cueList;
+ m_cueList.clear();
}
-void VTTParser::getNewRegions(Vector<RefPtr<VTTRegion> >& outputRegions)
+void VTTParser::getNewRegions(WillBeHeapVector<RefPtrWillBeMember<VTTRegion> >& outputRegions)
{
outputRegions = m_regionList;
m_regionList.clear();
@@ -301,41 +243,35 @@ VTTParser::ParseState VTTParser::collectCueId(const String& line)
{
if (line.contains("-->"))
return collectTimingsAndSettings(line);
- m_currentId = line;
+ m_currentId = AtomicString(line);
return TimingsAndSettings;
}
VTTParser::ParseState VTTParser::collectTimingsAndSettings(const String& line)
{
+ VTTScanner input(line);
+
// Collect WebVTT cue timings and settings. (5.3 WebVTT cue timings and settings parsing.)
// Steps 1 - 3 - Let input be the string being parsed and position be a pointer into input.
- unsigned position = 0;
- skipWhiteSpace(line, &position);
+ input.skipWhile<isASpace>();
// Steps 4 - 5 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue start time be the collected time.
- if (!collectTimeStamp(line, &position, m_currentStartTime))
- return BadCue;
- if (position >= line.length())
+ if (!collectTimeStamp(input, m_currentStartTime))
return BadCue;
-
- skipWhiteSpace(line, &position);
+ input.skipWhile<isASpace>();
// Steps 6 - 9 - If the next three characters are not "-->", abort and return failure.
- if (line.find("-->", position) == kNotFound)
+ if (!input.scan("-->"))
return BadCue;
- position += 3;
- if (position >= line.length())
- return BadCue;
-
- skipWhiteSpace(line, &position);
+ input.skipWhile<isASpace>();
// Steps 10 - 11 - Collect a WebVTT timestamp. If that fails, then abort and return failure. Otherwise, let cue's text track cue end time be the collected time.
- if (!collectTimeStamp(line, &position, m_currentEndTime))
+ if (!collectTimeStamp(input, m_currentEndTime))
return BadCue;
- skipWhiteSpace(line, &position);
+ input.skipWhile<isASpace>();
// Step 12 - Parse the WebVTT settings for the cue (conducted in TextTrackCue).
- m_currentSettings = line.substring(position, line.length()-1);
+ m_currentSettings = input.restOfInputAsString();
return CueText;
}
@@ -381,31 +317,33 @@ VTTParser::ParseState VTTParser::ignoreBadCue(const String& line)
// A helper class for the construction of a "cue fragment" from the cue text.
class VTTTreeBuilder {
+ STACK_ALLOCATED();
public:
- VTTTreeBuilder(Document& document)
- : m_document(document) { }
+ explicit VTTTreeBuilder(Document& document)
+ : m_document(&document) { }
- PassRefPtr<DocumentFragment> buildFromString(const String& cueText);
+ PassRefPtrWillBeRawPtr<DocumentFragment> buildFromString(const String& cueText);
private:
void constructTreeFromToken(Document&);
+ Document& document() const { return *m_document; }
VTTToken m_token;
- RefPtr<ContainerNode> m_currentNode;
+ RefPtrWillBeMember<ContainerNode> m_currentNode;
Vector<AtomicString> m_languageStack;
- Document& m_document;
+ RawPtrWillBeMember<Document> m_document;
};
-PassRefPtr<DocumentFragment> VTTTreeBuilder::buildFromString(const String& cueText)
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTTreeBuilder::buildFromString(const String& cueText)
{
// Cue text processing based on
// 5.4 WebVTT cue text parsing rules, and
// 5.5 WebVTT cue text DOM construction rules
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document());
if (cueText.isEmpty()) {
- fragment->parserAppendChild(Text::create(m_document, ""));
+ fragment->parserAppendChild(Text::create(document(), ""));
return fragment;
}
@@ -415,12 +353,12 @@ PassRefPtr<DocumentFragment> VTTTreeBuilder::buildFromString(const String& cueTe
m_languageStack.clear();
while (tokenizer.nextToken(m_token))
- constructTreeFromToken(m_document);
+ constructTreeFromToken(document());
return fragment.release();
}
-PassRefPtr<DocumentFragment> VTTParser::createDocumentFragmentFromCueText(Document& document, const String& cueText)
+PassRefPtrWillBeRawPtr<DocumentFragment> VTTParser::createDocumentFragmentFromCueText(Document& document, const String& cueText)
{
VTTTreeBuilder treeBuilder(document);
return treeBuilder.buildFromString(cueText);
@@ -428,18 +366,18 @@ PassRefPtr<DocumentFragment> VTTParser::createDocumentFragmentFromCueText(Docume
void VTTParser::createNewCue()
{
- RefPtr<VTTCue> cue = VTTCue::create(*m_document, m_currentStartTime, m_currentEndTime, m_currentContent.toString());
+ RefPtrWillBeRawPtr<VTTCue> cue = VTTCue::create(*m_document, m_currentStartTime, m_currentEndTime, m_currentContent.toString());
cue->setId(m_currentId);
cue->parseSettings(m_currentSettings);
- m_cuelist.append(cue);
+ m_cueList.append(cue);
if (m_client)
m_client->newCuesParsed();
}
void VTTParser::resetCueValues()
{
- m_currentId = emptyString();
+ m_currentId = emptyAtom;
m_currentSettings = emptyString();
m_currentStartTime = 0;
m_currentEndTime = 0;
@@ -452,7 +390,7 @@ void VTTParser::createNewRegion(const String& headerValue)
return;
// Steps 12.5.1 - 12.5.9 - Construct and initialize a WebVTT Region object.
- RefPtr<VTTRegion> region = VTTRegion::create();
+ RefPtrWillBeRawPtr<VTTRegion> region = VTTRegion::create();
region->setRegionSettings(headerValue);
// Step 12.5.10 If the text track list of regions regions contains a region
@@ -468,7 +406,13 @@ void VTTParser::createNewRegion(const String& headerValue)
m_regionList.append(region);
}
-bool VTTParser::collectTimeStamp(const String& line, unsigned* position, double& timeStamp)
+bool VTTParser::collectTimeStamp(const String& line, double& timeStamp)
+{
+ VTTScanner input(line);
+ return collectTimeStamp(input, timeStamp);
+}
+
+bool VTTParser::collectTimeStamp(VTTScanner& input, double& timeStamp)
{
// Collect a WebVTT timestamp (5.3 WebVTT cue timings and settings parsing.)
// Steps 1 - 4 - Initial checks, let most significant units be minutes.
@@ -478,25 +422,21 @@ bool VTTParser::collectTimeStamp(const String& line, unsigned* position, double&
// Steps 5 - 7 - Collect a sequence of characters that are 0-9.
// If not 2 characters or value is greater than 59, interpret as hours.
int value1;
- unsigned value1Digits = collectDigitsToInt(line, position, value1);
+ unsigned value1Digits = input.scanDigits(value1);
if (!value1Digits)
return false;
if (value1Digits != 2 || value1 > 59)
mode = Hours;
// Steps 8 - 11 - Collect the next sequence of 0-9 after ':' (must be 2 chars).
- if (*position >= line.length() || line[(*position)++] != ':')
- return false;
int value2;
- if (collectDigitsToInt(line, position, value2) != 2)
+ if (!input.scan(':') || input.scanDigits(value2) != 2)
return false;
// Step 12 - Detect whether this timestamp includes hours.
int value3;
- if (mode == Hours || (*position < line.length() && line[*position] == ':')) {
- if (*position >= line.length() || line[(*position)++] != ':')
- return false;
- if (collectDigitsToInt(line, position, value3) != 2)
+ if (mode == Hours || input.match(':')) {
+ if (!input.scan(':') || input.scanDigits(value3) != 2)
return false;
} else {
value3 = value2;
@@ -505,10 +445,8 @@ bool VTTParser::collectTimeStamp(const String& line, unsigned* position, double&
}
// Steps 13 - 17 - Collect next sequence of 0-9 after '.' (must be 3 chars).
- if (*position >= line.length() || line[(*position)++] != '.')
- return false;
int value4;
- if (collectDigitsToInt(line, position, value4) != 3)
+ if (!input.scan('.') || input.scanDigits(value4) != 3)
return false;
if (value2 > 59 || value3 > 59)
return false;
@@ -553,8 +491,7 @@ void VTTTreeBuilder::constructTreeFromToken(Document& document)
switch (m_token.type()) {
case VTTTokenTypes::Character: {
- RefPtr<Text> child = Text::create(document, m_token.characters());
- m_currentNode->parserAppendChild(child);
+ m_currentNode->parserAppendChild(Text::create(document, m_token.characters()));
break;
}
case VTTTokenTypes::StartTag: {
@@ -567,7 +504,7 @@ void VTTTreeBuilder::constructTreeFromToken(Document& document)
if (nodeType == VTTNodeTypeRubyText && currentType != VTTNodeTypeRuby)
break;
- RefPtr<VTTElement> child = VTTElement::create(nodeType, &document);
+ RefPtrWillBeRawPtr<VTTElement> child = VTTElement::create(nodeType, &document);
if (!m_token.classes().isEmpty())
child->setAttribute(classAttr, m_token.classes());
@@ -611,10 +548,9 @@ void VTTTreeBuilder::constructTreeFromToken(Document& document)
break;
}
case VTTTokenTypes::TimestampTag: {
- unsigned position = 0;
String charactersString = m_token.characters();
double parsedTimeStamp;
- if (VTTParser::collectTimeStamp(charactersString, &position, parsedTimeStamp))
+ if (VTTParser::collectTimeStamp(charactersString, parsedTimeStamp))
m_currentNode->parserAppendChild(ProcessingInstruction::create(document, "timestamp", charactersString));
break;
}
@@ -623,5 +559,11 @@ void VTTTreeBuilder::constructTreeFromToken(Document& document)
}
}
+void VTTParser::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_cueList);
+ visitor->trace(m_regionList);
}
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h
index df4e584cae9..3fca1af5e74 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTParser.h
@@ -31,22 +31,21 @@
#ifndef VTTParser_h
#define VTTParser_h
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
#include "core/dom/DocumentFragment.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/html/track/vtt/BufferedLineReader.h"
#include "core/html/track/vtt/VTTCue.h"
#include "core/html/track/vtt/VTTRegion.h"
#include "core/html/track/vtt/VTTTokenizer.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
-using namespace HTMLNames;
-
class Document;
+class VTTScanner;
class VTTParserClient {
public:
@@ -57,7 +56,7 @@ public:
virtual void fileFailedToParse() = 0;
};
-class VTTParser FINAL {
+class VTTParser FINAL : public NoBaseWillBeGarbageCollectedFinalized<VTTParser> {
public:
enum ParseState {
Initial,
@@ -68,54 +67,53 @@ public:
BadCue
};
- static PassOwnPtr<VTTParser> create(VTTParserClient* client, Document& document)
+ static PassOwnPtrWillBeRawPtr<VTTParser> create(VTTParserClient* client, Document& document)
{
- return adoptPtr(new VTTParser(client, document));
+ return adoptPtrWillBeNoop(new VTTParser(client, document));
}
static inline bool isRecognizedTag(const AtomicString& tagName)
{
- return tagName == iTag
- || tagName == bTag
- || tagName == uTag
- || tagName == rubyTag
- || tagName == rtTag;
+ return tagName == HTMLNames::iTag
+ || tagName == HTMLNames::bTag
+ || tagName == HTMLNames::uTag
+ || tagName == HTMLNames::rubyTag
+ || tagName == HTMLNames::rtTag;
}
-
- static inline bool isASpace(char c)
+ static inline bool isASpace(UChar c)
{
// WebVTT space characters are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).
return c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r';
}
- static inline bool isValidSettingDelimiter(char c)
+ static inline bool isValidSettingDelimiter(UChar c)
{
// ... a WebVTT cue consists of zero or more of the following components, in any order, separated from each other by one or more
// U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
return c == ' ' || c == '\t';
}
- static unsigned collectDigitsToInt(const String& input, unsigned* position, int& number);
- static String collectWord(const String&, unsigned*);
- static bool collectTimeStamp(const String&, unsigned*, double& timeStamp);
+ static bool collectTimeStamp(const String&, double& timeStamp);
// Useful functions for parsing percentage settings.
- static bool parseFloatPercentageValue(const String&, float&);
- static bool parseFloatPercentageValuePair(const String&, char, FloatPoint&);
+ static bool parseFloatPercentageValue(VTTScanner& valueScanner, float& percentage);
+ static bool parseFloatPercentageValuePair(VTTScanner&, char, FloatPoint&);
// Create the DocumentFragment representation of the WebVTT cue text.
- static PassRefPtr<DocumentFragment> createDocumentFragmentFromCueText(Document&, const String&);
+ static PassRefPtrWillBeRawPtr<DocumentFragment> createDocumentFragmentFromCueText(Document&, const String&);
// Input data to the parser to parse.
void parseBytes(const char* data, unsigned length);
void flush();
// Transfers ownership of last parsed cues to caller.
- void getNewCues(Vector<RefPtr<VTTCue> >&);
- void getNewRegions(Vector<RefPtr<VTTRegion> >&);
+ void getNewCues(WillBeHeapVector<RefPtrWillBeMember<VTTCue> >&);
+ void getNewRegions(WillBeHeapVector<RefPtrWillBeMember<VTTRegion> >&);
+
+ void trace(Visitor*);
private:
VTTParser(VTTParserClient*, Document&);
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
ParseState m_state;
void parse();
@@ -133,11 +131,11 @@ private:
void collectMetadataHeader(const String&);
void createNewRegion(const String& headerValue);
- static void skipWhiteSpace(const String&, unsigned*);
+ static bool collectTimeStamp(VTTScanner& input, double& timeStamp);
BufferedLineReader m_lineReader;
OwnPtr<TextResourceDecoder> m_decoder;
- String m_currentId;
+ AtomicString m_currentId;
double m_currentStartTime;
double m_currentEndTime;
StringBuilder m_currentContent;
@@ -145,9 +143,9 @@ private:
VTTParserClient* m_client;
- Vector<RefPtr<VTTCue> > m_cuelist;
+ WillBeHeapVector<RefPtrWillBeMember<VTTCue> > m_cueList;
- Vector<RefPtr<VTTRegion> > m_regionList;
+ WillBeHeapVector<RefPtrWillBeMember<VTTRegion> > m_regionList;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
index 4f39fb51cc9..26b32a39864 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
@@ -37,6 +37,7 @@
#include "core/dom/DOMTokenList.h"
#include "core/html/HTMLDivElement.h"
#include "core/html/track/vtt/VTTParser.h"
+#include "core/html/track/vtt/VTTScanner.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderObject.h"
#include "platform/Logging.h"
@@ -67,14 +68,10 @@ static const float lineHeight = 5.33;
// Default scrolling animation time period (s).
static const float scrollTime = 0.433;
-static bool isInfiniteOrNonNumberOrNonPercentage(double value, const char* method, ExceptionState& exceptionState)
+static bool isNonPercentage(double value, const char* method, ExceptionState& exceptionState)
{
- if (!std::isfinite(value)) {
- exceptionState.throwTypeError(ExceptionMessages::notAFiniteNumber(value));
- return true;
- }
if (value < 0 || value > 100) {
- exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(value) + ") is not between 0 and 100.");
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("value", value, 0.0, ExceptionMessages::InclusiveBound, 100.0, ExceptionMessages::InclusiveBound));
return true;
}
return false;
@@ -87,7 +84,7 @@ VTTRegion::VTTRegion()
, m_regionAnchor(FloatPoint(defaultAnchorPointX, defaultAnchorPointY))
, m_viewportAnchor(FloatPoint(defaultAnchorPointX, defaultAnchorPointY))
, m_scroll(defaultScroll)
- , m_track(0)
+ , m_track(nullptr)
, m_currentTop(0)
, m_scrollTimer(this, &VTTRegion::scrollTimerFired)
{
@@ -109,7 +106,7 @@ void VTTRegion::setId(const String& id)
void VTTRegion::setWidth(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "width", exceptionState))
+ if (isNonPercentage(value, "width", exceptionState))
return;
m_width = value;
@@ -127,7 +124,7 @@ void VTTRegion::setHeight(long value, ExceptionState& exceptionState)
void VTTRegion::setRegionAnchorX(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "regionAnchorX", exceptionState))
+ if (isNonPercentage(value, "regionAnchorX", exceptionState))
return;
m_regionAnchor.setX(value);
@@ -135,7 +132,7 @@ void VTTRegion::setRegionAnchorX(double value, ExceptionState& exceptionState)
void VTTRegion::setRegionAnchorY(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "regionAnchorY", exceptionState))
+ if (isNonPercentage(value, "regionAnchorY", exceptionState))
return;
m_regionAnchor.setY(value);
@@ -143,7 +140,7 @@ void VTTRegion::setRegionAnchorY(double value, ExceptionState& exceptionState)
void VTTRegion::setViewportAnchorX(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "viewportAnchorX", exceptionState))
+ if (isNonPercentage(value, "viewportAnchorX", exceptionState))
return;
m_viewportAnchor.setX(value);
@@ -151,7 +148,7 @@ void VTTRegion::setViewportAnchorX(double value, ExceptionState& exceptionState)
void VTTRegion::setViewportAnchorY(double value, ExceptionState& exceptionState)
{
- if (isInfiniteOrNonNumberOrNonPercentage(value, "viewportAnchorY", exceptionState))
+ if (isNonPercentage(value, "viewportAnchorY", exceptionState))
return;
m_viewportAnchor.setY(value);
@@ -190,83 +187,102 @@ void VTTRegion::updateParametersFromRegion(VTTRegion* region)
setScroll(region->scroll(), ASSERT_NO_EXCEPTION);
}
-void VTTRegion::setRegionSettings(const String& input)
+void VTTRegion::setRegionSettings(const String& inputString)
{
- m_settings = input;
- unsigned position = 0;
+ m_settings = inputString;
+
+ VTTScanner input(inputString);
- while (position < input.length()) {
- while (position < input.length() && VTTParser::isValidSettingDelimiter(input[position]))
- position++;
+ while (!input.isAtEnd()) {
+ input.skipWhile<VTTParser::isValidSettingDelimiter>();
- if (position >= input.length())
+ if (input.isAtEnd())
break;
- parseSetting(input, &position);
+ // Scan the name part.
+ RegionSetting name = scanSettingName(input);
+
+ // Verify that we're looking at a '='.
+ if (name == None || !input.scan('=')) {
+ input.skipUntil<VTTParser::isASpace>();
+ continue;
+ }
+
+ // Scan the value part.
+ parseSettingValue(name, input);
}
}
-VTTRegion::RegionSetting VTTRegion::getSettingFromString(const String& setting)
+VTTRegion::RegionSetting VTTRegion::scanSettingName(VTTScanner& input)
{
- DEFINE_STATIC_LOCAL(const AtomicString, idKeyword, ("id", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, heightKeyword, ("height", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, widthKeyword, ("width", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, regionAnchorKeyword, ("regionanchor", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, viewportAnchorKeyword, ("viewportanchor", AtomicString::ConstructFromLiteral));
- DEFINE_STATIC_LOCAL(const AtomicString, scrollKeyword, ("scroll", AtomicString::ConstructFromLiteral));
-
- if (setting == idKeyword)
+ if (input.scan("id"))
return Id;
- if (setting == heightKeyword)
+ if (input.scan("height"))
return Height;
- if (setting == widthKeyword)
+ if (input.scan("width"))
return Width;
- if (setting == viewportAnchorKeyword)
+ if (input.scan("viewportanchor"))
return ViewportAnchor;
- if (setting == regionAnchorKeyword)
+ if (input.scan("regionanchor"))
return RegionAnchor;
- if (setting == scrollKeyword)
+ if (input.scan("scroll"))
return Scroll;
return None;
}
-void VTTRegion::parseSettingValue(RegionSetting setting, const String& value)
+static inline bool parsedEntireRun(const VTTScanner& input, const VTTScanner::Run& run)
+{
+ return input.isAt(run.end());
+}
+
+void VTTRegion::parseSettingValue(RegionSetting setting, VTTScanner& input)
{
DEFINE_STATIC_LOCAL(const AtomicString, scrollUpValueKeyword, ("up", AtomicString::ConstructFromLiteral));
+ VTTScanner::Run valueRun = input.collectUntil<VTTParser::isASpace>();
+
switch (setting) {
- case Id:
- if (value.find("-->") == kNotFound)
- m_id = value;
+ case Id: {
+ String stringValue = input.extractString(valueRun);
+ if (stringValue.find("-->") == kNotFound)
+ m_id = stringValue;
break;
+ }
case Width: {
float floatWidth;
- if (VTTParser::parseFloatPercentageValue(value, floatWidth))
+ if (VTTParser::parseFloatPercentageValue(input, floatWidth) && parsedEntireRun(input, valueRun))
m_width = floatWidth;
else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid Width");
break;
}
case Height: {
- unsigned position = 0;
int number;
- if (VTTParser::collectDigitsToInt(value, &position, number) && position == value.length())
+ if (input.scanDigits(number) && parsedEntireRun(input, valueRun))
m_heightInLines = number;
else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid Height");
break;
}
- case RegionAnchor:
- if (!VTTParser::parseFloatPercentageValuePair(value, ',', m_regionAnchor))
+ case RegionAnchor: {
+ FloatPoint anchor;
+ if (VTTParser::parseFloatPercentageValuePair(input, ',', anchor) && parsedEntireRun(input, valueRun))
+ m_regionAnchor = anchor;
+ else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid RegionAnchor");
break;
- case ViewportAnchor:
- if (!VTTParser::parseFloatPercentageValuePair(value, ',', m_viewportAnchor))
+ }
+ case ViewportAnchor: {
+ FloatPoint anchor;
+ if (VTTParser::parseFloatPercentageValuePair(input, ',', anchor) && parsedEntireRun(input, valueRun))
+ m_viewportAnchor = anchor;
+ else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid ViewportAnchor");
break;
+ }
case Scroll:
- if (value == scrollUpValueKeyword)
+ if (input.scanRun(valueRun, scrollUpValueKeyword))
m_scroll = true;
else
WTF_LOG(Media, "VTTRegion::parseSettingValue, invalid Scroll");
@@ -274,20 +290,8 @@ void VTTRegion::parseSettingValue(RegionSetting setting, const String& value)
case None:
break;
}
-}
-
-void VTTRegion::parseSetting(const String& input, unsigned* position)
-{
- String setting = VTTParser::collectWord(input, position);
- size_t equalOffset = setting.find('=', 1);
- if (equalOffset == kNotFound || !equalOffset || equalOffset == setting.length() - 1)
- return;
-
- RegionSetting name = getSettingFromString(setting.substring(0, equalOffset));
- String value = setting.substring(equalOffset + 1, setting.length() - 1);
-
- parseSettingValue(name, value);
+ input.skipRun(valueRun);
}
const AtomicString& VTTRegion::textTrackCueContainerShadowPseudoId()
@@ -314,7 +318,7 @@ const AtomicString& VTTRegion::textTrackRegionShadowPseudoId()
return trackRegionShadowPseudoId;
}
-PassRefPtr<HTMLDivElement> VTTRegion::getDisplayTree(Document& document)
+PassRefPtrWillBeRawPtr<HTMLDivElement> VTTRegion::getDisplayTree(Document& document)
{
if (!m_regionDisplayTree) {
m_regionDisplayTree = HTMLDivElement::create(document);
@@ -331,13 +335,13 @@ void VTTRegion::willRemoveVTTCueBox(VTTCueBox* box)
double boxHeight = box->getBoundingClientRect()->bottom() - box->getBoundingClientRect()->top();
- m_cueContainer->classList()->remove(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
+ m_cueContainer->classList().remove(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
m_currentTop += boxHeight;
m_cueContainer->setInlineStyleProperty(CSSPropertyTop, m_currentTop, CSSPrimitiveValue::CSS_PX);
}
-void VTTRegion::appendVTTCueBox(PassRefPtr<VTTCueBox> displayBox)
+void VTTRegion::appendVTTCueBox(PassRefPtrWillBeRawPtr<VTTCueBox> displayBox)
{
ASSERT(m_cueContainer);
@@ -362,14 +366,14 @@ void VTTRegion::displayLastVTTCueBox()
// If it's a scrolling region, add the scrolling class.
if (isScrollingRegion())
- m_cueContainer->classList()->add(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
+ m_cueContainer->classList().add(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
float regionBottom = m_regionDisplayTree->getBoundingClientRect()->bottom();
// Find first cue that is not entirely displayed and scroll it upwards.
- for (size_t i = 0; i < m_cueContainer->childNodeCount() && !m_scrollTimer.isActive(); ++i) {
- float childTop = toHTMLDivElement(m_cueContainer->childNode(i))->getBoundingClientRect()->top();
- float childBottom = toHTMLDivElement(m_cueContainer->childNode(i))->getBoundingClientRect()->bottom();
+ for (Element* child = ElementTraversal::firstWithin(*m_cueContainer); child && !m_scrollTimer.isActive(); child = ElementTraversal::nextSibling(*child)) {
+ float childTop = toHTMLDivElement(child)->getBoundingClientRect()->top();
+ float childBottom = toHTMLDivElement(child)->getBoundingClientRect()->bottom();
if (regionBottom >= childBottom)
continue;
@@ -429,11 +433,11 @@ void VTTRegion::prepareRegionDisplayTree()
0.0,
CSSPrimitiveValue::CSS_PX);
- m_cueContainer->setPseudo(textTrackCueContainerShadowPseudoId());
+ m_cueContainer->setShadowPseudoId(textTrackCueContainerShadowPseudoId());
m_regionDisplayTree->appendChild(m_cueContainer);
// 7.5 Every WebVTT region object is initialised with the following CSS
- m_regionDisplayTree->setPseudo(textTrackRegionShadowPseudoId());
+ m_regionDisplayTree->setShadowPseudoId(textTrackRegionShadowPseudoId());
}
void VTTRegion::startTimer()
@@ -444,7 +448,7 @@ void VTTRegion::startTimer()
return;
double duration = isScrollingRegion() ? scrollTime : 0;
- m_scrollTimer.startOneShot(duration);
+ m_scrollTimer.startOneShot(duration, FROM_HERE);
}
void VTTRegion::stopTimer()
@@ -463,4 +467,11 @@ void VTTRegion::scrollTimerFired(Timer<VTTRegion>*)
displayLastVTTCueBox();
}
+void VTTRegion::trace(Visitor* visitor)
+{
+ visitor->trace(m_cueContainer);
+ visitor->trace(m_regionDisplayTree);
+ visitor->trace(m_track);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
index f9452c22498..ab2121eab97 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.h
@@ -35,6 +35,7 @@
#include "core/html/track/TextTrack.h"
#include "platform/Timer.h"
#include "platform/geometry/FloatPoint.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefCounted.h"
@@ -43,12 +44,13 @@ namespace WebCore {
class ExceptionState;
class HTMLDivElement;
class VTTCueBox;
+class VTTScanner;
-class VTTRegion : public RefCounted<VTTRegion> {
+class VTTRegion FINAL : public RefCountedWillBeGarbageCollectedFinalized<VTTRegion> {
public:
- static PassRefPtr<VTTRegion> create()
+ static PassRefPtrWillBeRawPtr<VTTRegion> create()
{
- return adoptRef(new VTTRegion());
+ return adoptRefWillBeNoop(new VTTRegion());
}
virtual ~VTTRegion();
@@ -87,12 +89,14 @@ public:
bool isScrollingRegion() { return m_scroll; }
- PassRefPtr<HTMLDivElement> getDisplayTree(Document&);
+ PassRefPtrWillBeRawPtr<HTMLDivElement> getDisplayTree(Document&);
- void appendVTTCueBox(PassRefPtr<VTTCueBox>);
+ void appendVTTCueBox(PassRefPtrWillBeRawPtr<VTTCueBox>);
void displayLastVTTCueBox();
void willRemoveVTTCueBox(VTTCueBox*);
+ void trace(Visitor*);
+
private:
VTTRegion();
@@ -112,9 +116,8 @@ private:
ViewportAnchor,
Scroll
};
- RegionSetting getSettingFromString(const String&);
- void parseSettingValue(RegionSetting, const String&);
- void parseSetting(const String&, unsigned*);
+ RegionSetting scanSettingName(VTTScanner&);
+ void parseSettingValue(RegionSetting, VTTScanner&);
static const AtomicString& textTrackCueContainerShadowPseudoId();
static const AtomicString& textTrackCueContainerScrollingClass();
@@ -130,14 +133,14 @@ private:
// The cue container is the container that is scrolled up to obtain the
// effect of scrolling cues when this is enabled for the regions.
- RefPtr<HTMLDivElement> m_cueContainer;
- RefPtr<HTMLDivElement> m_regionDisplayTree;
+ RefPtrWillBeMember<HTMLDivElement> m_cueContainer;
+ RefPtrWillBeMember<HTMLDivElement> m_regionDisplayTree;
// The member variable track can be a raw pointer as it will never
// reference a destroyed TextTrack, as this member variable
// is cleared in the TextTrack destructor and it is generally
// set/reset within the addRegion and removeRegion methods.
- TextTrack* m_track;
+ RawPtrWillBeMember<TextTrack> m_track;
// Keep track of the current numeric value of the css "top" property.
double m_currentTop;
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
index 398f7404b97..1a28e70b4da 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.idl
@@ -25,7 +25,9 @@
[
Constructor,
- RuntimeEnabled=WebVTTRegions
+ RuntimeEnabled=WebVTTRegions,
+ TypeChecking=Unrestricted,
+ WillBeGarbageCollected,
] interface VTTRegion {
readonly attribute TextTrack track;
@@ -38,4 +40,3 @@
[RaisesException=Setter] attribute double viewportAnchorY;
[RaisesException=Setter] attribute DOMString scroll;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp
index 914da521ae7..41bf33ad8b5 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.cpp
@@ -58,7 +58,7 @@ VTTRegion* VTTRegionList::getRegionById(const String& id) const
return 0;
}
-void VTTRegionList::add(PassRefPtr<VTTRegion> region)
+void VTTRegionList::add(PassRefPtrWillBeRawPtr<VTTRegion> region)
{
m_list.append(region);
}
@@ -73,9 +73,9 @@ bool VTTRegionList::remove(VTTRegion* region)
return true;
}
-void VTTRegionList::clear()
+void VTTRegionList::trace(Visitor* visitor)
{
- m_list.clear();
+ visitor->trace(m_list);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h
index 35e1b8e8d47..edb87d601b3 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.h
@@ -33,28 +33,27 @@
namespace WebCore {
-class VTTRegionList : public RefCounted<VTTRegionList> {
+class VTTRegionList FINAL : public RefCountedWillBeGarbageCollected<VTTRegionList> {
public:
- static PassRefPtr<VTTRegionList> create()
+ static PassRefPtrWillBeRawPtr<VTTRegionList> create()
{
- return adoptRef(new VTTRegionList());
+ return adoptRefWillBeNoop(new VTTRegionList());
}
- ~VTTRegionList() { }
-
unsigned long length() const;
VTTRegion* item(unsigned index) const;
VTTRegion* getRegionById(const String&) const;
- void add(PassRefPtr<VTTRegion>);
+ void add(PassRefPtrWillBeRawPtr<VTTRegion>);
bool remove(VTTRegion*);
+ void trace(Visitor*);
+
private:
VTTRegionList();
- void clear();
- Vector<RefPtr<VTTRegion> > m_list;
+ WillBeHeapVector<RefPtrWillBeMember<VTTRegion> > m_list;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl
index 4a06653bba0..cdd3d4dd131 100644
--- a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTRegionList.idl
@@ -24,7 +24,8 @@
*/
[
- RuntimeEnabled=WebVTTRegions
+ RuntimeEnabled=WebVTTRegions,
+ WillBeGarbageCollected,
] interface VTTRegionList {
readonly attribute unsigned long length;
getter VTTRegion item(unsigned long index);
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp
new file mode 100644
index 00000000000..590178f8864
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/track/vtt/VTTScanner.h"
+
+namespace WebCore {
+
+VTTScanner::VTTScanner(const String& line) : m_is8Bit(line.is8Bit())
+{
+ if (m_is8Bit) {
+ m_data.characters8 = line.characters8();
+ m_end.characters8 = m_data.characters8 + line.length();
+ } else {
+ m_data.characters16 = line.characters16();
+ m_end.characters16 = m_data.characters16 + line.length();
+ }
+}
+
+bool VTTScanner::scan(char c)
+{
+ if (!match(c))
+ return false;
+ advance();
+ return true;
+}
+
+bool VTTScanner::scan(const LChar* characters, size_t charactersCount)
+{
+ unsigned matchLength = m_is8Bit ? m_end.characters8 - m_data.characters8 : m_end.characters16 - m_data.characters16;
+ if (matchLength < charactersCount)
+ return false;
+ bool matched;
+ if (m_is8Bit)
+ matched = WTF::equal(m_data.characters8, characters, charactersCount);
+ else
+ matched = WTF::equal(m_data.characters16, characters, charactersCount);
+ if (matched)
+ advance(charactersCount);
+ return matched;
+}
+
+bool VTTScanner::scanRun(const Run& run, const String& toMatch)
+{
+ ASSERT(run.start() == position());
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= end());
+ size_t matchLength = run.length();
+ if (toMatch.length() > matchLength)
+ return false;
+ bool matched;
+ if (m_is8Bit)
+ matched = WTF::equal(toMatch.impl(), m_data.characters8, matchLength);
+ else
+ matched = WTF::equal(toMatch.impl(), m_data.characters16, matchLength);
+ if (matched)
+ seekTo(run.end());
+ return matched;
+}
+
+void VTTScanner::skipRun(const Run& run)
+{
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= end());
+ seekTo(run.end());
+}
+
+String VTTScanner::extractString(const Run& run)
+{
+ ASSERT(run.start() == position());
+ ASSERT(run.start() <= end());
+ ASSERT(run.end() >= run.start());
+ ASSERT(run.end() <= end());
+ String s;
+ if (m_is8Bit)
+ s = String(m_data.characters8, run.length());
+ else
+ s = String(m_data.characters16, run.length());
+ seekTo(run.end());
+ return s;
+}
+
+String VTTScanner::restOfInputAsString()
+{
+ Run rest(position(), end(), m_is8Bit);
+ return extractString(rest);
+}
+
+unsigned VTTScanner::scanDigits(int& number)
+{
+ Run runOfDigits = collectWhile<isASCIIDigit>();
+ if (runOfDigits.isEmpty()) {
+ number = 0;
+ return 0;
+ }
+ bool validNumber;
+ size_t numDigits = runOfDigits.length();
+ if (m_is8Bit)
+ number = charactersToInt(m_data.characters8, numDigits, &validNumber);
+ else
+ number = charactersToInt(m_data.characters16, numDigits, &validNumber);
+
+ // Since we know that scanDigits only scanned valid (ASCII) digits (and
+ // hence that's what got passed to charactersToInt()), the remaining
+ // failure mode for charactersToInt() is overflow, so if |validNumber| is
+ // not true, then set |number| to the maximum int value.
+ if (!validNumber)
+ number = std::numeric_limits<int>::max();
+ // Consume the digits.
+ seekTo(runOfDigits.end());
+ return numDigits;
+}
+
+bool VTTScanner::scanFloat(float& number)
+{
+ Run integerRun = collectWhile<isASCIIDigit>();
+ seekTo(integerRun.end());
+ Run decimalRun(position(), position(), m_is8Bit);
+ if (scan('.')) {
+ decimalRun = collectWhile<isASCIIDigit>();
+ seekTo(decimalRun.end());
+ }
+
+ // At least one digit required.
+ if (integerRun.isEmpty() && decimalRun.isEmpty()) {
+ // Restore to starting position.
+ seekTo(integerRun.start());
+ return false;
+ }
+
+ size_t lengthOfFloat = Run(integerRun.start(), position(), m_is8Bit).length();
+ bool validNumber;
+ if (m_is8Bit)
+ number = charactersToFloat(integerRun.start(), lengthOfFloat, &validNumber);
+ else
+ number = charactersToFloat(reinterpret_cast<const UChar*>(integerRun.start()), lengthOfFloat, &validNumber);
+
+ if (!validNumber)
+ number = std::numeric_limits<float>::max();
+ return true;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h
new file mode 100644
index 00000000000..aa097e780ec
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScanner.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef VTTScanner_h
+#define VTTScanner_h
+
+#include "platform/ParsingUtilities.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+// Helper class for "scanning" an input string and performing parsing of
+// "micro-syntax"-like constructs.
+//
+// There's two primary operations: match and scan.
+//
+// The 'match' operation matches an explicitly or implicitly specified sequence
+// against the characters ahead of the current input pointer, and returns true
+// if the sequence can be matched.
+//
+// The 'scan' operation performs a 'match', and if the match is successful it
+// advance the input pointer past the matched sequence.
+class VTTScanner {
+ WTF_MAKE_NONCOPYABLE(VTTScanner);
+public:
+ explicit VTTScanner(const String& line);
+
+ typedef const LChar* Position;
+
+ class Run {
+ public:
+ Run(Position start, Position end, bool is8Bit)
+ : m_start(start), m_end(end), m_is8Bit(is8Bit) { }
+
+ Position start() const { return m_start; }
+ Position end() const { return m_end; }
+
+ bool isEmpty() const { return m_start == m_end; }
+ size_t length() const;
+
+ private:
+ Position m_start;
+ Position m_end;
+ bool m_is8Bit;
+ };
+
+ // Check if the input pointer points at the specified position.
+ bool isAt(Position checkPosition) const { return position() == checkPosition; }
+ // Check if the input pointer points at the end of the input.
+ bool isAtEnd() const { return position() == end(); }
+ // Match the character |c| against the character at the input pointer (~lookahead).
+ bool match(char c) const { return !isAtEnd() && currentChar() == c; }
+ // Scan the character |c|.
+ bool scan(char);
+ // Scan the first |charactersCount| characters of the string |characters|.
+ bool scan(const LChar* characters, size_t charactersCount);
+
+ // Scan the literal |characters|.
+ template<unsigned charactersCount>
+ bool scan(const char (&characters)[charactersCount]);
+
+ // Skip (advance the input pointer) as long as the specified
+ // |characterPredicate| returns true, and the input pointer is not passed
+ // the end of the input.
+ template<bool characterPredicate(UChar)>
+ void skipWhile();
+
+ // Like skipWhile, but using a negated predicate.
+ template<bool characterPredicate(UChar)>
+ void skipUntil();
+
+ // Return the run of characters for which the specified
+ // |characterPredicate| returns true. The start of the run will be the
+ // current input pointer.
+ template<bool characterPredicate(UChar)>
+ Run collectWhile();
+
+ // Like collectWhile, but using a negated predicate.
+ template<bool characterPredicate(UChar)>
+ Run collectUntil();
+
+ // Scan the string |toMatch|, using the specified |run| as the sequence to
+ // match against.
+ bool scanRun(const Run&, const String& toMatch);
+
+ // Skip to the end of the specified |run|.
+ void skipRun(const Run&);
+
+ // Return the String made up of the characters in |run|, and advance the
+ // input pointer to the end of the run.
+ String extractString(const Run&);
+
+ // Return a String constructed from the rest of the input (between input
+ // pointer and end of input), and advance the input pointer accordingly.
+ String restOfInputAsString();
+
+ // Scan a set of ASCII digits from the input. Return the number of digits
+ // scanned, and set |number| to the computed value. If the digits make up a
+ // number that does not fit the 'int' type, |number| is set to INT_MAX.
+ // Note: Does not handle sign.
+ unsigned scanDigits(int& number);
+
+ // Scan a floating point value on one of the forms: \d+\.? \d+\.\d+ \.\d+
+ bool scanFloat(float& number);
+
+protected:
+ Position position() const { return m_data.characters8; }
+ Position end() const { return m_end.characters8; }
+ void seekTo(Position);
+ UChar currentChar() const;
+ void advance(unsigned amount = 1);
+ // Adapt a UChar-predicate to an LChar-predicate.
+ // (For use with skipWhile/Until from ParsingUtilities.h).
+ template<bool characterPredicate(UChar)>
+ static inline bool LCharPredicateAdapter(LChar c) { return characterPredicate(c); }
+ union {
+ const LChar* characters8;
+ const UChar* characters16;
+ } m_data;
+ union {
+ const LChar* characters8;
+ const UChar* characters16;
+ } m_end;
+ bool m_is8Bit;
+};
+
+inline size_t VTTScanner::Run::length() const
+{
+ if (m_is8Bit)
+ return m_end - m_start;
+ return reinterpret_cast<const UChar*>(m_end) - reinterpret_cast<const UChar*>(m_start);
+}
+
+template<unsigned charactersCount>
+inline bool VTTScanner::scan(const char (&characters)[charactersCount])
+{
+ return scan(reinterpret_cast<const LChar*>(characters), charactersCount - 1);
+}
+
+template<bool characterPredicate(UChar)>
+inline void VTTScanner::skipWhile()
+{
+ if (m_is8Bit)
+ ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8);
+ else
+ ::skipWhile<UChar, characterPredicate>(m_data.characters16, m_end.characters16);
+}
+
+template<bool characterPredicate(UChar)>
+inline void VTTScanner::skipUntil()
+{
+ if (m_is8Bit)
+ ::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(m_data.characters8, m_end.characters8);
+ else
+ ::skipUntil<UChar, characterPredicate>(m_data.characters16, m_end.characters16);
+}
+
+template<bool characterPredicate(UChar)>
+inline VTTScanner::Run VTTScanner::collectWhile()
+{
+ if (m_is8Bit) {
+ const LChar* current = m_data.characters8;
+ ::skipWhile<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8);
+ return Run(position(), current, m_is8Bit);
+ }
+ const UChar* current = m_data.characters16;
+ ::skipWhile<UChar, characterPredicate>(current, m_end.characters16);
+ return Run(position(), reinterpret_cast<Position>(current), m_is8Bit);
+}
+
+template<bool characterPredicate(UChar)>
+inline VTTScanner::Run VTTScanner::collectUntil()
+{
+ if (m_is8Bit) {
+ const LChar* current = m_data.characters8;
+ ::skipUntil<LChar, LCharPredicateAdapter<characterPredicate> >(current, m_end.characters8);
+ return Run(position(), current, m_is8Bit);
+ }
+ const UChar* current = m_data.characters16;
+ ::skipUntil<UChar, characterPredicate>(current, m_end.characters16);
+ return Run(position(), reinterpret_cast<Position>(current), m_is8Bit);
+}
+
+inline void VTTScanner::seekTo(Position position)
+{
+ ASSERT(position <= end());
+ m_data.characters8 = position;
+}
+
+inline UChar VTTScanner::currentChar() const
+{
+ ASSERT(position() < end());
+ return m_is8Bit ? *m_data.characters8 : *m_data.characters16;
+}
+
+inline void VTTScanner::advance(unsigned amount)
+{
+ ASSERT(position() < end());
+ if (m_is8Bit)
+ m_data.characters8 += amount;
+ else
+ m_data.characters16 += amount;
+}
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp
new file mode 100644
index 00000000000..d5bcfb8f52f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/html/track/vtt/VTTScannerTest.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2013, Opera Software ASA. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Opera Software ASA nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/track/vtt/VTTScanner.h"
+
+#include "wtf/text/WTFString.h"
+
+#include <gtest/gtest.h>
+
+using WebCore::VTTScanner;
+
+namespace {
+
+TEST(VTTScanner, Constructor)
+{
+ String data8("foo");
+ EXPECT_TRUE(data8.is8Bit());
+ VTTScanner scanner8(data8);
+ EXPECT_FALSE(scanner8.isAtEnd());
+
+ String data16(data8);
+ data16.ensure16Bit();
+ EXPECT_FALSE(data16.is8Bit());
+ VTTScanner scanner16(data16);
+ EXPECT_FALSE(scanner16.isAtEnd());
+
+ VTTScanner scannerEmpty(emptyString());
+ EXPECT_TRUE(scannerEmpty.isAtEnd());
+}
+
+void scanSequenceHelper1(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ EXPECT_TRUE(scanner.match('f'));
+ EXPECT_FALSE(scanner.match('o'));
+
+ EXPECT_TRUE(scanner.scan('f'));
+ EXPECT_FALSE(scanner.match('f'));
+ EXPECT_TRUE(scanner.match('o'));
+
+ EXPECT_FALSE(scanner.scan('e'));
+ EXPECT_TRUE(scanner.scan('o'));
+
+ EXPECT_TRUE(scanner.scan('e'));
+ EXPECT_FALSE(scanner.match('e'));
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Run TESTFUNC with DATA in Latin and then UTF-16. (Requires DATA being Latin.)
+#define TEST_WITH(TESTFUNC, DATA) do { \
+ String data8(DATA); \
+ EXPECT_TRUE(data8.is8Bit()); \
+ TESTFUNC(data8); \
+ \
+ String data16(data8); \
+ data16.ensure16Bit(); \
+ EXPECT_FALSE(data16.is8Bit()); \
+ TESTFUNC(data16); \
+} while (false)
+
+
+// Exercises match(c) and scan(c).
+TEST(VTTScanner, BasicOperations1)
+{
+ TEST_WITH(scanSequenceHelper1, "foe");
+}
+
+void scanSequenceHelper2(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ EXPECT_FALSE(scanner.scan("fe"));
+
+ EXPECT_TRUE(scanner.scan("fo"));
+ EXPECT_FALSE(scanner.isAtEnd());
+
+ EXPECT_FALSE(scanner.scan("ee"));
+
+ EXPECT_TRUE(scanner.scan('e'));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Exercises scan(<literal>[, length]).
+TEST(VTTScanner, BasicOperations2)
+{
+ TEST_WITH(scanSequenceHelper2, "foe");
+}
+
+bool lowerCaseAlpha(UChar c)
+{
+ return c >= 'a' && c <= 'z';
+}
+
+void scanWithPredicate(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ // Collect "bad".
+ VTTScanner::Run lcRun = scanner.collectWhile<lowerCaseAlpha>();
+ // collectWhile doesn't move the scan position.
+ EXPECT_TRUE(scanner.match('b'));
+ // Consume "bad".
+ scanner.skipWhile<lowerCaseAlpha>();
+ EXPECT_TRUE(scanner.match('A'));
+ EXPECT_TRUE(scanner.isAt(lcRun.end()));
+
+ // Consume "A".
+ EXPECT_TRUE(scanner.scan('A'));
+
+ // Collect "bing".
+ lcRun = scanner.collectWhile<lowerCaseAlpha>();
+ // collectWhile doesn't move the scan position.
+ EXPECT_FALSE(scanner.isAtEnd());
+ // Consume "bing".
+ scanner.skipWhile<lowerCaseAlpha>();
+ EXPECT_TRUE(scanner.isAt(lcRun.end()));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests skipWhile() and collectWhile().
+TEST(VTTScanner, PredicateScanning)
+{
+ TEST_WITH(scanWithPredicate, "badAbing");
+}
+
+void scanWithInvPredicate(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ // Collect "BAD".
+ VTTScanner::Run ucRun = scanner.collectUntil<lowerCaseAlpha>();
+ // collectUntil doesn't move the scan position.
+ EXPECT_TRUE(scanner.match('B'));
+ // Consume "BAD".
+ scanner.skipUntil<lowerCaseAlpha>();
+ EXPECT_TRUE(scanner.match('a'));
+ EXPECT_TRUE(scanner.isAt(ucRun.end()));
+
+ // Consume "a".
+ EXPECT_TRUE(scanner.scan('a'));
+
+ // Collect "BING".
+ ucRun = scanner.collectUntil<lowerCaseAlpha>();
+ // collectUntil doesn't move the scan position.
+ EXPECT_FALSE(scanner.isAtEnd());
+ // Consume "BING".
+ scanner.skipUntil<lowerCaseAlpha>();
+ EXPECT_TRUE(scanner.isAt(ucRun.end()));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests skipUntil() and collectUntil().
+TEST(VTTScanner, InversePredicateScanning)
+{
+ TEST_WITH(scanWithInvPredicate, "BADaBING");
+}
+
+void scanRuns(const String& input)
+{
+ String fooString("foo");
+ String barString("bar");
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ VTTScanner::Run word = scanner.collectWhile<lowerCaseAlpha>();
+ EXPECT_FALSE(scanner.scanRun(word, barString));
+ EXPECT_TRUE(scanner.scanRun(word, fooString));
+
+ EXPECT_TRUE(scanner.match(':'));
+ EXPECT_TRUE(scanner.scan(':'));
+
+ // Skip 'baz'.
+ scanner.skipRun(scanner.collectWhile<lowerCaseAlpha>());
+
+ EXPECT_TRUE(scanner.match(':'));
+ EXPECT_TRUE(scanner.scan(':'));
+
+ word = scanner.collectWhile<lowerCaseAlpha>();
+ EXPECT_FALSE(scanner.scanRun(word, fooString));
+ EXPECT_TRUE(scanner.scanRun(word, barString));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests scanRun/skipRun.
+TEST(VTTScanner, RunScanning)
+{
+ TEST_WITH(scanRuns, "foo:baz:bar");
+}
+
+void scanRunsToStrings(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_FALSE(scanner.isAtEnd());
+ VTTScanner::Run word = scanner.collectWhile<lowerCaseAlpha>();
+ String fooString = scanner.extractString(word);
+ EXPECT_EQ(fooString, "foo");
+ EXPECT_TRUE(scanner.isAt(word.end()));
+
+ EXPECT_TRUE(scanner.match(':'));
+ EXPECT_TRUE(scanner.scan(':'));
+
+ word = scanner.collectWhile<lowerCaseAlpha>();
+ String barString = scanner.extractString(word);
+ EXPECT_EQ(barString, "bar");
+ EXPECT_TRUE(scanner.isAt(word.end()));
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests extractString.
+TEST(VTTScanner, ExtractString)
+{
+ TEST_WITH(scanRunsToStrings, "foo:bar");
+}
+
+void tailStringExtract(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_TRUE(scanner.scan("foo"));
+ EXPECT_TRUE(scanner.scan(':'));
+ String barSuffix = scanner.restOfInputAsString();
+ EXPECT_EQ(barSuffix, "bar");
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests restOfInputAsString().
+TEST(VTTScanner, ExtractRestAsString)
+{
+ TEST_WITH(tailStringExtract, "foo:bar");
+}
+
+void scanDigits1(const String& input)
+{
+ VTTScanner scanner(input);
+ EXPECT_TRUE(scanner.scan("foo"));
+ int number;
+ EXPECT_EQ(scanner.scanDigits(number), 0u);
+ EXPECT_EQ(number, 0);
+ EXPECT_TRUE(scanner.scan(' '));
+ EXPECT_EQ(scanner.scanDigits(number), 3u);
+ EXPECT_TRUE(scanner.match(' '));
+ EXPECT_EQ(number, 123);
+
+ EXPECT_TRUE(scanner.scan(' '));
+ EXPECT_TRUE(scanner.scan("bar"));
+ EXPECT_TRUE(scanner.scan(' '));
+
+ EXPECT_EQ(scanner.scanDigits(number), 5u);
+ EXPECT_EQ(number, 45678);
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+void scanDigits2(const String& input)
+{
+ VTTScanner scanner(input);
+ int number;
+ EXPECT_EQ(scanner.scanDigits(number), 0u);
+ EXPECT_EQ(number, 0);
+ EXPECT_TRUE(scanner.scan('-'));
+ EXPECT_EQ(scanner.scanDigits(number), 3u);
+ EXPECT_EQ(number, 654);
+
+ EXPECT_TRUE(scanner.scan(' '));
+
+ EXPECT_EQ(scanner.scanDigits(number), 19u);
+ EXPECT_EQ(number, std::numeric_limits<int>::max());
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests scanDigits().
+TEST(VTTScanner, ScanDigits)
+{
+ TEST_WITH(scanDigits1, "foo 123 bar 45678");
+ TEST_WITH(scanDigits2, "-654 1000000000000000000");
+}
+
+void scanFloatValue(const String& input)
+{
+ VTTScanner scanner(input);
+ float value;
+ // "1."
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 1.0f);
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // "1.0"
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 1.0f);
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // ".0"
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 0.0f);
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // "." (invalid)
+ EXPECT_FALSE(scanner.scanFloat(value));
+ EXPECT_TRUE(scanner.match('.'));
+ EXPECT_TRUE(scanner.scan('.'));
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // "1.0000"
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 1.0f);
+ EXPECT_TRUE(scanner.scan(' '));
+
+ // "01.000"
+ EXPECT_TRUE(scanner.scanFloat(value));
+ EXPECT_EQ(value, 1.0f);
+
+ EXPECT_TRUE(scanner.isAtEnd());
+}
+
+// Tests scanFloat().
+TEST(VTTScanner, ScanFloat)
+{
+ TEST_WITH(scanFloatValue, "1. 1.0 .0 . 1.0000 01.000");
+}
+
+#undef TEST_WITH
+
+} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp b/chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp
index d3a1982af2b..6754ef218f1 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp
@@ -31,12 +31,29 @@
#include "config.h"
#include "core/inspector/AsyncCallStackTracker.h"
+#include "bindings/v8/V8RecursionScope.h"
#include "core/dom/ContextLifecycleObserver.h"
#include "core/dom/ExecutionContext.h"
+#include "core/events/EventTarget.h"
+#include "core/xml/XMLHttpRequest.h"
+#include "core/xml/XMLHttpRequestUpload.h"
+#include "wtf/text/AtomicStringHash.h"
+#include "wtf/text/StringBuilder.h"
+#include <v8.h>
+
+namespace {
+
+static const char setTimeoutName[] = "setTimeout";
+static const char setIntervalName[] = "setInterval";
+static const char requestAnimationFrameName[] = "requestAnimationFrame";
+static const char xhrSendName[] = "XMLHttpRequest.send";
+static const char enqueueMutationRecordName[] = "Mutation";
+
+}
namespace WebCore {
-class AsyncCallStackTracker::ExecutionContextData : public ContextLifecycleObserver {
+class AsyncCallStackTracker::ExecutionContextData FINAL : public ContextLifecycleObserver {
WTF_MAKE_FAST_ALLOCATED;
public:
ExecutionContextData(AsyncCallStackTracker* tracker, ExecutionContext* executionContext)
@@ -47,18 +64,33 @@ public:
virtual void contextDestroyed() OVERRIDE
{
- m_tracker->contextDestroyed(executionContext());
+ ASSERT(executionContext());
+ ExecutionContextData* self = m_tracker->m_executionContextDataMap.take(executionContext());
+ ASSERT(self == this);
ContextLifecycleObserver::contextDestroyed();
+ delete self;
}
-private:
- friend class AsyncCallStackTracker;
+public:
AsyncCallStackTracker* m_tracker;
HashSet<int> m_intervalTimerIds;
HashMap<int, RefPtr<AsyncCallChain> > m_timerCallChains;
HashMap<int, RefPtr<AsyncCallChain> > m_animationFrameCallChains;
+ HashMap<Event*, RefPtr<AsyncCallChain> > m_eventCallChains;
+ HashMap<EventTarget*, RefPtr<AsyncCallChain> > m_xhrCallChains;
+ HashMap<MutationObserver*, RefPtr<AsyncCallChain> > m_mutationObserverCallChains;
};
+static XMLHttpRequest* toXmlHttpRequest(EventTarget* eventTarget)
+{
+ const AtomicString& interfaceName = eventTarget->interfaceName();
+ if (interfaceName == EventTargetNames::XMLHttpRequest)
+ return static_cast<XMLHttpRequest*>(eventTarget);
+ if (interfaceName == EventTargetNames::XMLHttpRequestUpload)
+ return static_cast<XMLHttpRequestUpload*>(eventTarget)->xmlHttpRequest();
+ return 0;
+}
+
AsyncCallStackTracker::AsyncCallStack::AsyncCallStack(const String& description, const ScriptValue& callFrames)
: m_description(description)
, m_callFrames(callFrames)
@@ -93,9 +125,6 @@ const AsyncCallStackTracker::AsyncCallChain* AsyncCallStackTracker::currentAsync
void AsyncCallStackTracker::didInstallTimer(ExecutionContext* context, int timerId, bool singleShot, const ScriptValue& callFrames)
{
- DEFINE_STATIC_LOCAL(String, setTimeoutName, ("setTimeout"));
- DEFINE_STATIC_LOCAL(String, setIntervalName, ("setInterval"));
-
ASSERT(context);
ASSERT(isEnabled());
if (!validateCallFrames(callFrames))
@@ -110,7 +139,8 @@ void AsyncCallStackTracker::didInstallTimer(ExecutionContext* context, int timer
void AsyncCallStackTracker::didRemoveTimer(ExecutionContext* context, int timerId)
{
ASSERT(context);
- if (!isEnabled() || timerId <= 0)
+ ASSERT(isEnabled());
+ if (timerId <= 0)
return;
ExecutionContextData* data = m_executionContextDataMap.get(context);
if (!data)
@@ -122,23 +152,21 @@ void AsyncCallStackTracker::didRemoveTimer(ExecutionContext* context, int timerI
void AsyncCallStackTracker::willFireTimer(ExecutionContext* context, int timerId)
{
ASSERT(context);
- if (!isEnabled())
- return;
+ ASSERT(isEnabled());
ASSERT(timerId > 0);
ASSERT(!m_currentAsyncCallChain);
- ExecutionContextData* data = m_executionContextDataMap.get(context);
- if (!data)
- return;
- if (data->m_intervalTimerIds.contains(timerId))
- m_currentAsyncCallChain = data->m_timerCallChains.get(timerId);
- else
- m_currentAsyncCallChain = data->m_timerCallChains.take(timerId);
+ if (ExecutionContextData* data = m_executionContextDataMap.get(context)) {
+ if (data->m_intervalTimerIds.contains(timerId))
+ setCurrentAsyncCallChain(data->m_timerCallChains.get(timerId));
+ else
+ setCurrentAsyncCallChain(data->m_timerCallChains.take(timerId));
+ } else {
+ setCurrentAsyncCallChain(nullptr);
+ }
}
void AsyncCallStackTracker::didRequestAnimationFrame(ExecutionContext* context, int callbackId, const ScriptValue& callFrames)
{
- DEFINE_STATIC_LOCAL(String, requestAnimationFrameName, ("requestAnimationFrame"));
-
ASSERT(context);
ASSERT(isEnabled());
if (!validateCallFrames(callFrames))
@@ -151,7 +179,8 @@ void AsyncCallStackTracker::didRequestAnimationFrame(ExecutionContext* context,
void AsyncCallStackTracker::didCancelAnimationFrame(ExecutionContext* context, int callbackId)
{
ASSERT(context);
- if (!isEnabled() || callbackId <= 0)
+ ASSERT(isEnabled());
+ if (callbackId <= 0)
return;
if (ExecutionContextData* data = m_executionContextDataMap.get(context))
data->m_animationFrameCallChains.remove(callbackId);
@@ -160,28 +189,143 @@ void AsyncCallStackTracker::didCancelAnimationFrame(ExecutionContext* context, i
void AsyncCallStackTracker::willFireAnimationFrame(ExecutionContext* context, int callbackId)
{
ASSERT(context);
- if (!isEnabled())
- return;
+ ASSERT(isEnabled());
ASSERT(callbackId > 0);
ASSERT(!m_currentAsyncCallChain);
if (ExecutionContextData* data = m_executionContextDataMap.get(context))
- m_currentAsyncCallChain = data->m_animationFrameCallChains.take(callbackId);
+ setCurrentAsyncCallChain(data->m_animationFrameCallChains.take(callbackId));
+ else
+ setCurrentAsyncCallChain(nullptr);
+}
+
+void AsyncCallStackTracker::didEnqueueEvent(EventTarget* eventTarget, Event* event, const ScriptValue& callFrames)
+{
+ ASSERT(eventTarget->executionContext());
+ ASSERT(isEnabled());
+ if (!validateCallFrames(callFrames))
+ return;
+ ExecutionContextData* data = createContextDataIfNeeded(eventTarget->executionContext());
+ data->m_eventCallChains.set(event, createAsyncCallChain(event->type(), callFrames));
+}
+
+void AsyncCallStackTracker::didRemoveEvent(EventTarget* eventTarget, Event* event)
+{
+ ASSERT(eventTarget->executionContext());
+ ASSERT(isEnabled());
+ if (ExecutionContextData* data = m_executionContextDataMap.get(eventTarget->executionContext()))
+ data->m_eventCallChains.remove(event);
+}
+
+void AsyncCallStackTracker::willHandleEvent(EventTarget* eventTarget, Event* event, EventListener* listener, bool useCapture)
+{
+ ASSERT(eventTarget->executionContext());
+ ASSERT(isEnabled());
+ if (XMLHttpRequest* xhr = toXmlHttpRequest(eventTarget)) {
+ willHandleXHREvent(xhr, eventTarget, event);
+ } else {
+ if (ExecutionContextData* data = m_executionContextDataMap.get(eventTarget->executionContext()))
+ setCurrentAsyncCallChain(data->m_eventCallChains.get(event));
+ else
+ setCurrentAsyncCallChain(nullptr);
+ }
+}
+
+void AsyncCallStackTracker::willLoadXHR(XMLHttpRequest* xhr, const ScriptValue& callFrames)
+{
+ ASSERT(xhr->executionContext());
+ ASSERT(isEnabled());
+ if (!validateCallFrames(callFrames))
+ return;
+ ExecutionContextData* data = createContextDataIfNeeded(xhr->executionContext());
+ data->m_xhrCallChains.set(xhr, createAsyncCallChain(xhrSendName, callFrames));
+}
+
+void AsyncCallStackTracker::willHandleXHREvent(XMLHttpRequest* xhr, EventTarget* eventTarget, Event* event)
+{
+ ASSERT(xhr->executionContext());
+ ASSERT(isEnabled());
+ if (ExecutionContextData* data = m_executionContextDataMap.get(xhr->executionContext())) {
+ bool isXHRDownload = (xhr == eventTarget);
+ if (isXHRDownload && event->type() == EventTypeNames::loadend)
+ setCurrentAsyncCallChain(data->m_xhrCallChains.take(xhr));
+ else
+ setCurrentAsyncCallChain(data->m_xhrCallChains.get(xhr));
+ } else {
+ setCurrentAsyncCallChain(nullptr);
+ }
+}
+
+void AsyncCallStackTracker::didEnqueueMutationRecord(ExecutionContext* context, MutationObserver* observer, const ScriptValue& callFrames)
+{
+ ASSERT(context);
+ ASSERT(isEnabled());
+ if (!validateCallFrames(callFrames))
+ return;
+ ExecutionContextData* data = createContextDataIfNeeded(context);
+ data->m_mutationObserverCallChains.set(observer, createAsyncCallChain(enqueueMutationRecordName, callFrames));
+}
+
+bool AsyncCallStackTracker::hasEnqueuedMutationRecord(ExecutionContext* context, MutationObserver* observer)
+{
+ ASSERT(context);
+ ASSERT(isEnabled());
+ if (ExecutionContextData* data = m_executionContextDataMap.get(context))
+ return data->m_mutationObserverCallChains.contains(observer);
+ return false;
+}
+
+void AsyncCallStackTracker::didClearAllMutationRecords(ExecutionContext* context, MutationObserver* observer)
+{
+ ASSERT(context);
+ ASSERT(isEnabled());
+ if (ExecutionContextData* data = m_executionContextDataMap.get(context))
+ data->m_mutationObserverCallChains.remove(observer);
+}
+
+void AsyncCallStackTracker::willDeliverMutationRecords(ExecutionContext* context, MutationObserver* observer)
+{
+ ASSERT(context);
+ ASSERT(isEnabled());
+ if (ExecutionContextData* data = m_executionContextDataMap.get(context))
+ setCurrentAsyncCallChain(data->m_mutationObserverCallChains.take(observer));
+ else
+ setCurrentAsyncCallChain(nullptr);
}
void AsyncCallStackTracker::didFireAsyncCall()
{
- m_currentAsyncCallChain = 0;
+ clearCurrentAsyncCallChain();
}
PassRefPtr<AsyncCallStackTracker::AsyncCallChain> AsyncCallStackTracker::createAsyncCallChain(const String& description, const ScriptValue& callFrames)
{
- ASSERT(isEnabled());
RefPtr<AsyncCallChain> chain = adoptRef(m_currentAsyncCallChain ? new AsyncCallStackTracker::AsyncCallChain(*m_currentAsyncCallChain) : new AsyncCallStackTracker::AsyncCallChain());
ensureMaxAsyncCallChainDepth(chain.get(), m_maxAsyncCallStackDepth - 1);
chain->m_callStacks.prepend(adoptRef(new AsyncCallStackTracker::AsyncCallStack(description, callFrames)));
return chain.release();
}
+void AsyncCallStackTracker::setCurrentAsyncCallChain(PassRefPtr<AsyncCallChain> chain)
+{
+ if (V8RecursionScope::recursionLevel(v8::Isolate::GetCurrent())) {
+ if (m_currentAsyncCallChain)
+ ++m_nestedAsyncCallCount;
+ } else {
+ // Current AsyncCallChain corresponds to the bottommost JS call frame.
+ m_currentAsyncCallChain = chain;
+ m_nestedAsyncCallCount = m_currentAsyncCallChain ? 1 : 0;
+ }
+}
+
+void AsyncCallStackTracker::clearCurrentAsyncCallChain()
+{
+ if (!m_nestedAsyncCallCount)
+ return;
+ --m_nestedAsyncCallCount;
+ if (!m_nestedAsyncCallCount)
+ m_currentAsyncCallChain.clear();
+}
+
void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain, unsigned maxDepth)
{
while (chain->m_callStacks.size() > maxDepth)
@@ -190,14 +334,7 @@ void AsyncCallStackTracker::ensureMaxAsyncCallChainDepth(AsyncCallChain* chain,
bool AsyncCallStackTracker::validateCallFrames(const ScriptValue& callFrames)
{
- return !callFrames.hasNoValue();
-}
-
-void AsyncCallStackTracker::contextDestroyed(ExecutionContext* context)
-{
- ASSERT(context);
- if (ExecutionContextData* data = m_executionContextDataMap.take(context))
- delete data;
+ return !callFrames.isEmpty();
}
AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContextDataIfNeeded(ExecutionContext* context)
@@ -212,12 +349,12 @@ AsyncCallStackTracker::ExecutionContextData* AsyncCallStackTracker::createContex
void AsyncCallStackTracker::clear()
{
- m_currentAsyncCallChain = 0;
- Vector<ExecutionContextData*> contextsData;
- copyValuesToVector(m_executionContextDataMap, contextsData);
- m_executionContextDataMap.clear();
- for (Vector<ExecutionContextData*>::const_iterator it = contextsData.begin(); it != contextsData.end(); ++it)
- delete *it;
+ m_currentAsyncCallChain.clear();
+ m_nestedAsyncCallCount = 0;
+ ExecutionContextDataMap copy;
+ m_executionContextDataMap.swap(copy);
+ for (ExecutionContextDataMap::const_iterator it = copy.begin(); it != copy.end(); ++it)
+ delete it->value;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.h b/chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.h
index e032134eeda..d9ab45e97d6 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.h
@@ -41,7 +41,12 @@
namespace WebCore {
+class Event;
+class EventListener;
+class EventTarget;
class ExecutionContext;
+class MutationObserver;
+class XMLHttpRequest;
class AsyncCallStackTracker {
WTF_MAKE_NONCOPYABLE(AsyncCallStackTracker);
@@ -83,21 +88,36 @@ public:
void didCancelAnimationFrame(ExecutionContext*, int callbackId);
void willFireAnimationFrame(ExecutionContext*, int callbackId);
+ void didEnqueueEvent(EventTarget*, Event*, const ScriptValue& callFrames);
+ void didRemoveEvent(EventTarget*, Event*);
+ void willHandleEvent(EventTarget*, Event*, EventListener*, bool useCapture);
+ void willLoadXHR(XMLHttpRequest*, const ScriptValue& callFrames);
+
+ void didEnqueueMutationRecord(ExecutionContext*, MutationObserver*, const ScriptValue& callFrames);
+ bool hasEnqueuedMutationRecord(ExecutionContext*, MutationObserver*);
+ void didClearAllMutationRecords(ExecutionContext*, MutationObserver*);
+ void willDeliverMutationRecords(ExecutionContext*, MutationObserver*);
+
void didFireAsyncCall();
void clear();
private:
+ void willHandleXHREvent(XMLHttpRequest*, EventTarget*, Event*);
+
PassRefPtr<AsyncCallChain> createAsyncCallChain(const String& description, const ScriptValue& callFrames);
+ void setCurrentAsyncCallChain(PassRefPtr<AsyncCallChain>);
+ void clearCurrentAsyncCallChain();
static void ensureMaxAsyncCallChainDepth(AsyncCallChain*, unsigned);
static bool validateCallFrames(const ScriptValue& callFrames);
class ExecutionContextData;
- void contextDestroyed(ExecutionContext*);
ExecutionContextData* createContextDataIfNeeded(ExecutionContext*);
unsigned m_maxAsyncCallStackDepth;
RefPtr<AsyncCallChain> m_currentAsyncCallChain;
- HashMap<ExecutionContext*, ExecutionContextData*> m_executionContextDataMap;
+ unsigned m_nestedAsyncCallCount;
+ typedef HashMap<ExecutionContext*, ExecutionContextData*> ExecutionContextDataMap;
+ ExecutionContextDataMap m_executionContextDataMap;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/BUILD.gn b/chromium/third_party/WebKit/Source/core/inspector/BUILD.gn
new file mode 100644
index 00000000000..db6ac1ea4ba
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/BUILD.gn
@@ -0,0 +1,98 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//third_party/WebKit/Source/build/convert_file_to_header_with_character_array.gni")
+import("//third_party/WebKit/Source/bindings/bindings.gni")
+import("//third_party/WebKit/Source/core/core.gni")
+
+visibility = "//third_party/WebKit/Source/*"
+
+protocol_file = "../../devtools/protocol.json"
+
+action("protocol_sources") {
+ script = "CodeGeneratorInspector.py"
+
+ source_prereqs = [
+ # The helper script imported by CodeGeneratorInspector.py.
+ "CodeGeneratorInspectorStrings.py",
+ protocol_file,
+ ]
+ outputs = [
+ "$blink_core_output_dir/InspectorBackendDispatcher.cpp",
+ "$blink_core_output_dir/InspectorBackendDispatcher.h",
+ "$blink_core_output_dir/InspectorFrontend.cpp",
+ "$blink_core_output_dir/InspectorFrontend.h",
+ "$blink_core_output_dir/InspectorTypeBuilder.cpp",
+ "$blink_core_output_dir/InspectorTypeBuilder.h",
+ ]
+
+ args = [
+ rebase_path(protocol_file, root_build_dir),
+ "--output_dir", rebase_path(blink_core_output_dir, root_build_dir),
+ ]
+
+ deps = [
+ ":protocol_version",
+ ]
+}
+
+action("instrumentation_sources") {
+ script = "CodeGeneratorInstrumentation.py"
+
+ source_prereqs = [
+ # Input file for the script.
+ "InspectorInstrumentation.idl",
+ ]
+
+ outputs = [
+ "$blink_core_output_dir/InspectorCanvasInstrumentationInl.h",
+ "$blink_core_output_dir/InspectorConsoleInstrumentationInl.h",
+ "$blink_core_output_dir/InspectorInstrumentationInl.h",
+ "$blink_core_output_dir/InspectorOverridesInl.h",
+ "$blink_core_output_dir/InstrumentingAgentsInl.h",
+ "$blink_core_output_dir/InspectorInstrumentationImpl.cpp",
+ ]
+
+ args = [
+ rebase_path("InspectorInstrumentation.idl", root_build_dir),
+ "--output_dir", rebase_path(blink_core_output_dir, root_build_dir),
+ ]
+}
+
+action("protocol_version") {
+ script = "generate-inspector-protocol-version"
+
+ source_prereqs = [ protocol_file ]
+ output_file = "$blink_core_output_dir/InspectorProtocolVersion.h"
+ outputs = [ output_file ]
+
+ args = [
+ "-o", rebase_path(output_file, root_build_dir),
+ rebase_path(protocol_file, root_build_dir),
+ ]
+}
+
+convert_file_to_header_with_character_array("inspector_overlay_page") {
+ input_file_path = "InspectorOverlayPage.html"
+ output_file_path = "$blink_core_output_dir/InspectorOverlayPage.h"
+ character_array_name = "InspectorOverlayPage_html"
+}
+
+convert_file_to_header_with_character_array("injected_canvas_script_source") {
+ input_file_path = "InjectedScriptCanvasModuleSource.js"
+ output_file_path = "$blink_core_output_dir/InjectedScriptCanvasModuleSource.h"
+ character_array_name = "InjectedScriptCanvasModuleSource_js"
+}
+
+convert_file_to_header_with_character_array("injected_script_source") {
+ input_file_path = "InjectedScriptSource.js"
+ output_file_path = "$blink_core_output_dir/InjectedScriptSource.h"
+ character_array_name = "InjectedScriptSource_js"
+}
+
+convert_file_to_header_with_character_array("debugger_script_source") {
+ input_file_path = "$bindings_v8_dir/DebuggerScript.js"
+ output_file_path = "$blink_core_output_dir/DebuggerScriptSource.h"
+ character_array_name = "DebuggerScriptSource_js"
+}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/BindingVisitors.h b/chromium/third_party/WebKit/Source/core/inspector/BindingVisitors.h
index c885703ac75..9a51b0f6511 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/BindingVisitors.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/BindingVisitors.h
@@ -52,14 +52,6 @@ protected:
virtual ~ExternalStringVisitor() { }
};
-
-class ExternalArrayVisitor {
-public:
- virtual void visitJSExternalArray(WTF::ArrayBufferView*) = 0;
-protected:
- virtual ~ExternalArrayVisitor() { }
-};
-
} // namespace WebCore
#endif // BindingVisitors_h
diff --git a/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py b/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py
index 163ce99c1f9..ce6dae1d6a6 100755
--- a/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py
+++ b/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspector.py
@@ -49,11 +49,9 @@ TYPE_NAME_FIX_MAP = {
TYPES_WITH_RUNTIME_CAST_SET = frozenset(["Runtime.RemoteObject", "Runtime.PropertyDescriptor", "Runtime.InternalPropertyDescriptor",
"Debugger.FunctionDetails", "Debugger.CallFrame", "Debugger.Location",
- "Canvas.TraceLog", "Canvas.ResourceState",
- # This should be a temporary hack. TimelineEvent should be created via generated C++ API.
- "Timeline.TimelineEvent"])
+ "Canvas.TraceLog", "Canvas.ResourceState"])
-TYPES_WITH_OPEN_FIELD_LIST_SET = frozenset(["Timeline.TimelineEvent",
+TYPES_WITH_OPEN_FIELD_LIST_SET = frozenset([
# InspectorStyleSheet not only creates this property but wants to read it and modify it.
"CSS.CSSProperty",
# InspectorResourceAgent needs to update mime-type.
@@ -158,7 +156,7 @@ class Capitalizer:
ABBREVIATION = frozenset(["XHR", "DOM", "CSS"])
-VALIDATOR_IFDEF_NAME = "!ASSERT_DISABLED"
+VALIDATOR_IFDEF_NAME = "ASSERT_ENABLED"
class DomainNameFixes:
@@ -1195,6 +1193,18 @@ class TypeBindings:
writer.newline(" typedef TypeBuilder::StructItemTraits ItemTraits;\n")
+ for prop_data in resolve_data.main_properties:
+ prop_name = prop_data.p["name"]
+ param_type_binding = prop_data.param_type_binding
+ raw_type = param_type_binding.reduce_to_raw_type()
+ if isinstance(param_type_binding.get_type_model(), TypeModel.ValueType):
+ writer.append_multiline("\n void %s" % prop_name)
+ writer.append("(%s value)\n" % param_type_binding.get_type_model().get_command_return_pass_model().get_output_parameter_type())
+ writer.newline(" {\n")
+ writer.newline(" JSONObjectBase::get%s(\"%s\", value);\n"
+ % (param_type_binding.reduce_to_raw_type().get_setter_name(), prop_data.p["name"]))
+ writer.newline(" }\n")
+
for prop_data in resolve_data.optional_properties:
prop_name = prop_data.p["name"]
param_type_binding = prop_data.param_type_binding
@@ -1208,7 +1218,6 @@ class TypeBindings:
format_setter_value_expression(param_type_binding, "value")))
writer.newline(" }\n")
-
if setter_name in INSPECTOR_OBJECT_SETTER_NAMES:
writer.newline(" using JSONObjectBase::%s;\n\n" % setter_name)
@@ -1851,6 +1860,9 @@ class Generator:
@staticmethod
def process_event(json_event, domain_name, frontend_method_declaration_lines):
+ if (("handlers" in json_event) and (not ("renderer" in json_event["handlers"]))):
+ return
+
event_name = json_event["name"]
ad_hoc_type_output = []
@@ -1881,46 +1893,43 @@ class Generator:
@staticmethod
def process_command(json_command, domain_name, agent_field_name, agent_interface_name):
+ if (("handlers" in json_command) and (not ("renderer" in json_command["handlers"]))):
+ return
+
json_command_name = json_command["name"]
cmd_enum_name = "k%s_%sCmd" % (domain_name, json_command["name"])
Generator.method_name_enum_list.append(" %s," % cmd_enum_name)
Generator.method_handler_list.append(" &InspectorBackendDispatcherImpl::%s_%s," % (domain_name, json_command_name))
- Generator.backend_method_declaration_list.append(" void %s_%s(long callId, JSONObject* requestMessageObject);" % (domain_name, json_command_name))
+ Generator.backend_method_declaration_list.append(" void %s_%s(long callId, JSONObject* requestMessageObject, JSONArray* protocolErrors);" % (domain_name, json_command_name))
+
+ backend_agent_interface_list = [] if "redirect" in json_command else Generator.backend_agent_interface_list
ad_hoc_type_output = []
- Generator.backend_agent_interface_list.append(ad_hoc_type_output)
+ backend_agent_interface_list.append(ad_hoc_type_output)
ad_hoc_type_writer = Writer(ad_hoc_type_output, " ")
- Generator.backend_agent_interface_list.append(" virtual void %s(ErrorString*" % json_command_name)
+ backend_agent_interface_list.append(" virtual void %s(ErrorString*" % json_command_name)
method_in_code = ""
method_out_code = ""
- agent_call_param_list = []
+ result_object_declaration = ""
+ agent_call_param_list = ["&error"]
+ agent_call_params_declaration_list = [" ErrorString error;"]
+ send_response_call_params_list = ["error"]
request_message_param = ""
normal_response_cook_text = ""
- error_response_cook_text = ""
error_type_binding = None
if "error" in json_command:
json_error = json_command["error"]
error_type_binding = Generator.resolve_type_and_generate_ad_hoc(json_error, json_command_name + "Error", json_command_name, domain_name, ad_hoc_type_writer, agent_interface_name + "::")
error_type_model = error_type_binding.get_type_model().get_optional()
error_annotated_type = error_type_model.get_command_return_pass_model().get_output_parameter_type()
- agent_call_param_list.append(", %serrorData" % error_type_model.get_command_return_pass_model().get_output_argument_prefix())
- Generator.backend_agent_interface_list.append(", %s errorData" % error_annotated_type)
+ agent_call_param_list.append("%serrorData" % error_type_model.get_command_return_pass_model().get_output_argument_prefix())
+ backend_agent_interface_list.append(", %s errorData" % error_annotated_type)
method_in_code += " %s errorData;\n" % error_type_model.get_command_return_pass_model().get_return_var_type()
-
- setter_argument = error_type_model.get_command_return_pass_model().get_output_to_raw_expression() % "errorData"
- if error_type_binding.get_setter_value_expression_pattern():
- setter_argument = error_type_binding.get_setter_value_expression_pattern() % setter_argument
- error_assigment_value = error_type_binding.reduce_to_raw_type().get_constructor_pattern() % setter_argument
-
- cook = " resultErrorData = %s;\n" % error_assigment_value
-
- error_condition_pattern = error_type_model.get_command_return_pass_model().get_set_return_condition()
- cook = (" if (%s)\n " % (error_condition_pattern % "errorData")) + cook
- error_response_cook_text = " if (error.length()) {\n" + cook + " }\n"
+ send_response_call_params_list.append("errorData")
if "parameters" in json_command:
json_params = json_command["parameters"]
@@ -1945,15 +1954,15 @@ class Generator:
if optional:
code = (" bool %s_valueFound = false;\n"
- " %s in_%s = get%s(paramsContainerPtr, \"%s\", &%s_valueFound, protocolErrorsPtr);\n" %
+ " %s in_%s = get%s(paramsContainerPtr, \"%s\", &%s_valueFound, protocolErrors);\n" %
(json_param_name, non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name, getter_name, json_param_name, json_param_name))
- param = ", %s_valueFound ? &in_%s : 0" % (json_param_name, json_param_name)
+ param = "%s_valueFound ? &in_%s : 0" % (json_param_name, json_param_name)
# FIXME: pass optional refptr-values as PassRefPtr
formal_param_type_pattern = "const %s*"
else:
- code = (" %s in_%s = get%s(paramsContainerPtr, \"%s\", 0, protocolErrorsPtr);\n" %
+ code = (" %s in_%s = get%s(paramsContainerPtr, \"%s\", 0, protocolErrors);\n" %
(non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name, getter_name, json_param_name))
- param = ", in_%s" % json_param_name
+ param = "in_%s" % json_param_name
# FIXME: pass not-optional refptr-values as NonNullPassRefPtr
if param_raw_type.is_heavy_value():
formal_param_type_pattern = "const %s&"
@@ -1962,7 +1971,7 @@ class Generator:
method_in_code += code
agent_call_param_list.append(param)
- Generator.backend_agent_interface_list.append(", %s in_%s" % (formal_param_type_pattern % non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name))
+ backend_agent_interface_list.append(", %s in_%s" % (formal_param_type_pattern % non_optional_type_model.get_command_return_pass_model().get_return_var_type(), json_param_name))
if json_command.get("async") == True:
callback_name = Capitalizer.lower_camel_case_to_upper(json_command_name) + "Callback"
@@ -1998,19 +2007,19 @@ class Generator:
parameter=annotated_type + " errorData",
argument=assigment_value))
-
-
ad_hoc_type_output.append(callback_output)
method_out_code += " RefPtr<" + agent_interface_name + "::" + callback_name + "> callback = adoptRef(new " + agent_interface_name + "::" + callback_name + "(this, callId));\n"
- agent_call_param_list.append(", callback")
- normal_response_cook_text += " if (!error.length()) \n"
- normal_response_cook_text += " return;\n"
- normal_response_cook_text += " callback->disable();\n"
- Generator.backend_agent_interface_list.append(", PassRefPtr<%s> callback" % callback_name)
+ agent_call_param_list.append("callback")
+ normal_response_cook_text += " if (!error.length()) \n"
+ normal_response_cook_text += " return;\n"
+ normal_response_cook_text += " callback->disable();\n"
+ backend_agent_interface_list.append(", PassRefPtr<%s> callback" % callback_name)
else:
if "returns" in json_command:
method_out_code += "\n"
+ agent_call_params_declaration_list.append(" RefPtr<JSONObject> result = JSONObject::create();")
+ send_response_call_params_list.append("result")
response_cook_list = []
for json_return in json_command["returns"]:
@@ -2029,25 +2038,25 @@ class Generator:
type_model = type_model.get_optional()
code = " %s out_%s;\n" % (type_model.get_command_return_pass_model().get_return_var_type(), json_return_name)
- param = ", %sout_%s" % (type_model.get_command_return_pass_model().get_output_argument_prefix(), json_return_name)
+ param = "%sout_%s" % (type_model.get_command_return_pass_model().get_output_argument_prefix(), json_return_name)
var_name = "out_%s" % json_return_name
setter_argument = type_model.get_command_return_pass_model().get_output_to_raw_expression() % var_name
if return_type_binding.get_setter_value_expression_pattern():
setter_argument = return_type_binding.get_setter_value_expression_pattern() % setter_argument
- cook = " result->set%s(\"%s\", %s);\n" % (setter_type, json_return_name,
+ cook = " result->set%s(\"%s\", %s);\n" % (setter_type, json_return_name,
setter_argument)
set_condition_pattern = type_model.get_command_return_pass_model().get_set_return_condition()
if set_condition_pattern:
- cook = (" if (%s)\n " % (set_condition_pattern % var_name)) + cook
+ cook = (" if (%s)\n " % (set_condition_pattern % var_name)) + cook
annotated_type = type_model.get_command_return_pass_model().get_output_parameter_type()
param_name = var_name
if optional:
param_name = "opt_" + param_name
- Generator.backend_agent_interface_list.append(", %s %s" % (annotated_type, param_name))
+ backend_agent_interface_list.append(", %s %s" % (annotated_type, param_name))
response_cook_list.append(cook)
method_out_code += code
@@ -2056,24 +2065,30 @@ class Generator:
normal_response_cook_text += "".join(response_cook_list)
if len(normal_response_cook_text) != 0:
- normal_response_cook_text = " if (!error.length()) {\n" + normal_response_cook_text + " }"
+ normal_response_cook_text = " if (!error.length()) {\n" + normal_response_cook_text + " }"
+
+ # Redirect to another agent's implementation.
+ agent_field = "m_" + agent_field_name
+ if "redirect" in json_command:
+ domain_fixes = DomainNameFixes.get_fixed_data(json_command.get("redirect"))
+ agent_field = "m_" + domain_fixes.agent_field_name
Generator.backend_method_implementation_list.append(Templates.backend_method.substitute(None,
domainName=domain_name, methodName=json_command_name,
- agentField="m_" + agent_field_name,
- methodInCode=method_in_code,
- methodOutCode=method_out_code,
- agentCallParams="".join(agent_call_param_list),
+ agentField=agent_field,
+ methodCode="".join([method_in_code, method_out_code]),
+ agentCallParamsDeclaration="\n".join(agent_call_params_declaration_list),
+ agentCallParams=", ".join(agent_call_param_list),
requestMessageObject=request_message_param,
responseCook=normal_response_cook_text,
- errorCook=error_response_cook_text,
+ sendResponseCallParams=", ".join(send_response_call_params_list),
commandNameIndex=cmd_enum_name))
declaration_command_name = "%s.%s\\0" % (domain_name, json_command_name)
Generator.backend_method_name_declaration_list.append(" \"%s\"" % declaration_command_name)
Generator.backend_method_name_declaration_index_list.append(" %d," % Generator.backend_method_name_declaration_current_index)
Generator.backend_method_name_declaration_current_index += len(declaration_command_name) - 1
- Generator.backend_agent_interface_list.append(") = 0;\n")
+ backend_agent_interface_list.append(") = 0;\n")
class CallbackMethodStructTemplate:
@staticmethod
diff --git a/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspectorStrings.py b/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspectorStrings.py
index bc3bb739e19..f9b812769c4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspectorStrings.py
+++ b/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInspectorStrings.py
@@ -33,8 +33,8 @@ frontend_domain_class = (
""" class $domainClassName {
public:
$domainClassName(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }
-${frontendDomainMethodDeclarations} void setInspectorFrontendChannel(InspectorFrontendChannel* inspectorFrontendChannel) { m_inspectorFrontendChannel = inspectorFrontendChannel; }
- InspectorFrontendChannel* getInspectorFrontendChannel() { return m_inspectorFrontendChannel; }
+${frontendDomainMethodDeclarations}
+ void flush() { m_inspectorFrontendChannel->flush(); }
private:
InspectorFrontendChannel* m_inspectorFrontendChannel;
};
@@ -44,23 +44,19 @@ ${frontendDomainMethodDeclarations} void setInspectorFrontendChannel(Insp
""")
backend_method = (
-"""void InspectorBackendDispatcherImpl::${domainName}_$methodName(long callId, JSONObject*$requestMessageObject)
+"""void InspectorBackendDispatcherImpl::${domainName}_$methodName(long callId, JSONObject*$requestMessageObject, JSONArray* protocolErrors)
{
- RefPtr<JSONArray> protocolErrors = JSONArray::create();
-
if (!$agentField)
protocolErrors->pushString("${domainName} handler is not available.");
-$methodOutCode
-$methodInCode
- RefPtr<JSONObject> result = JSONObject::create();
- RefPtr<JSONValue> resultErrorData;
- ErrorString error;
- if (!protocolErrors->length()) {
- $agentField->$methodName(&error$agentCallParams);
-
-$errorCook${responseCook}
+$methodCode
+ if (protocolErrors->length()) {
+ reportProtocolError(&callId, InvalidParams, String::format(InvalidParamsFormatString, commandName($commandNameIndex)), protocolErrors);
+ return;
}
- sendResponse(callId, result, commandName($commandNameIndex), protocolErrors, error, resultErrorData);
+$agentCallParamsDeclaration
+ $agentField->$methodName($agentCallParams);
+$responseCook
+ sendResponse(callId, $sendResponseCallParams);
}
""")
@@ -69,7 +65,7 @@ frontend_method = ("""void InspectorFrontend::$domainName::$eventName($parameter
RefPtr<JSONObject> jsonMessage = JSONObject::create();
jsonMessage->setString("method", "$domainName.$eventName");
$code if (m_inspectorFrontendChannel)
- m_inspectorFrontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+ m_inspectorFrontendChannel->sendMessageToFrontend(jsonMessage.release());
}
""")
@@ -91,7 +87,7 @@ callback_failure_method = (
if (error) {
errorDataValue = $argument;
}
- sendIfActive(0, error, errorDataValue.release());
+ sendIfActive(nullptr, error, errorDataValue.release());
}
""")
@@ -101,23 +97,23 @@ frontend_h = (
#define InspectorFrontend_h
#include "InspectorTypeBuilder.h"
+#include "core/inspector/InspectorFrontendChannel.h"
#include "platform/JSONValues.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class InspectorFrontendChannel;
-
typedef String ErrorString;
class InspectorFrontend {
public:
InspectorFrontend(InspectorFrontendChannel*);
-
+ InspectorFrontendChannel* channel() { return m_inspectorFrontendChannel; }
$domainClassList
private:
+ InspectorFrontendChannel* m_inspectorFrontendChannel;
${fieldDeclarations}};
} // namespace WebCore
@@ -136,7 +132,6 @@ backend_h = (
namespace WebCore {
-class InspectorAgent;
class JSONObject;
class JSONArray;
class InspectorFrontendChannel;
@@ -215,7 +210,6 @@ backend_cpp = (
#include "config.h"
#include "InspectorBackendDispatcher.h"
-#include "core/inspector/InspectorAgent.h"
#include "core/inspector/InspectorFrontendChannel.h"
#include "core/inspector/JSONParser.h"
#include "platform/JSONValues.h"
@@ -249,7 +243,7 @@ $constructorInit
virtual void reportProtocolError(const long* const callId, CommonErrorCode, const String& errorMessage, PassRefPtr<JSONValue> data) const;
using InspectorBackendDispatcher::reportProtocolError;
- void sendResponse(long callId, PassRefPtr<JSONObject> result, const ErrorString&invocationError, PassRefPtr<JSONValue> errorData);
+ void sendResponse(long callId, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData, PassRefPtr<JSONObject> result);
bool isActive() { return m_inspectorFrontendChannel; }
$setters
@@ -260,19 +254,28 @@ $methodDeclarations
$fieldDeclarations
template<typename R, typename V, typename V0>
- static R getPropertyValueImpl(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name);
-
- static int getInt(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors);
- static double getDouble(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors);
- static String getString(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors);
- static bool getBoolean(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors);
- static PassRefPtr<JSONObject> getObject(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors);
- static PassRefPtr<JSONArray> getArray(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors);
+ static R getPropertyValueImpl(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name);
- void sendResponse(long callId, PassRefPtr<JSONObject> result, const char* commandName, PassRefPtr<JSONArray> protocolErrors, ErrorString invocationError, PassRefPtr<JSONValue> errorData);
+ static int getInt(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
+ static double getDouble(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
+ static String getString(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
+ static bool getBoolean(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
+ static PassRefPtr<JSONObject> getObject(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
+ static PassRefPtr<JSONArray> getArray(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors);
+ void sendResponse(long callId, ErrorString invocationError, PassRefPtr<JSONObject> result)
+ {
+ sendResponse(callId, invocationError, RefPtr<JSONValue>(), result);
+ }
+ void sendResponse(long callId, ErrorString invocationError)
+ {
+ sendResponse(callId, invocationError, RefPtr<JSONValue>(), JSONObject::create());
+ }
+ static const char InvalidParamsFormatString[];
};
+const char InspectorBackendDispatcherImpl::InvalidParamsFormatString[] = "Some arguments of method '%s' can't be processed";
+
$methods
PassRefPtr<InspectorBackendDispatcher> InspectorBackendDispatcher::create(InspectorFrontendChannel* inspectorFrontendChannel)
@@ -284,13 +287,13 @@ PassRefPtr<InspectorBackendDispatcher> InspectorBackendDispatcher::create(Inspec
void InspectorBackendDispatcherImpl::dispatch(const String& message)
{
RefPtr<InspectorBackendDispatcher> protect = this;
- typedef void (InspectorBackendDispatcherImpl::*CallHandler)(long callId, JSONObject* messageObject);
+ typedef void (InspectorBackendDispatcherImpl::*CallHandler)(long callId, JSONObject* messageObject, JSONArray* protocolErrors);
typedef HashMap<String, CallHandler> DispatchMap;
DEFINE_STATIC_LOCAL(DispatchMap, dispatchMap, );
long callId = 0;
if (dispatchMap.isEmpty()) {
- static CallHandler handlers[] = {
+ static const CallHandler handlers[] = {
$messageHandlers
};
for (size_t i = 0; i < kMethodNamesEnumSize; ++i)
@@ -338,20 +341,11 @@ $messageHandlers
return;
}
- ((*this).*it->value)(callId, messageObject.get());
-}
-
-void InspectorBackendDispatcherImpl::sendResponse(long callId, PassRefPtr<JSONObject> result, const char* commandName, PassRefPtr<JSONArray> protocolErrors, ErrorString invocationError, PassRefPtr<JSONValue> errorData)
-{
- if (protocolErrors->length()) {
- String errorMessage = String::format("Some arguments of method '%s' can't be processed", commandName);
- reportProtocolError(&callId, InvalidParams, errorMessage, protocolErrors);
- return;
- }
- sendResponse(callId, result, invocationError, errorData);
+ RefPtr<JSONArray> protocolErrors = JSONArray::create();
+ ((*this).*it->value)(callId, messageObject.get(), protocolErrors.get());
}
-void InspectorBackendDispatcherImpl::sendResponse(long callId, PassRefPtr<JSONObject> result, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData)
+void InspectorBackendDispatcherImpl::sendResponse(long callId, const ErrorString& invocationError, PassRefPtr<JSONValue> errorData, PassRefPtr<JSONObject> result)
{
if (invocationError.length()) {
reportProtocolError(&callId, ServerError, invocationError, errorData);
@@ -359,10 +353,10 @@ void InspectorBackendDispatcherImpl::sendResponse(long callId, PassRefPtr<JSONOb
}
RefPtr<JSONObject> responseMessage = JSONObject::create();
- responseMessage->setObject("result", result);
responseMessage->setNumber("id", callId);
+ responseMessage->setObject("result", result);
if (m_inspectorFrontendChannel)
- m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
+ m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage.release());
}
void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage) const
@@ -397,11 +391,11 @@ void InspectorBackendDispatcherImpl::reportProtocolError(const long* const callI
else
message->setValue("id", JSONValue::null());
if (m_inspectorFrontendChannel)
- m_inspectorFrontendChannel->sendMessageToFrontend(message->toJSONString());
+ m_inspectorFrontendChannel->sendMessageToFrontend(message.release());
}
template<typename R, typename V, typename V0>
-R InspectorBackendDispatcherImpl::getPropertyValueImpl(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name)
+R InspectorBackendDispatcherImpl::getPropertyValueImpl(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors, V0 initial_value, bool (*as_method)(JSONValue*, V*), const char* type_name)
{
ASSERT(protocolErrors);
@@ -413,7 +407,7 @@ R InspectorBackendDispatcherImpl::getPropertyValueImpl(JSONObject* object, const
if (!object) {
if (!valueFound) {
// Required parameter in missing params container.
- protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type '%s'.", name.utf8().data(), type_name));
+ protocolErrors->pushString(String::format("'params' object must contain required parameter '%s' with type '%s'.", name, type_name));
}
return value;
}
@@ -423,12 +417,12 @@ R InspectorBackendDispatcherImpl::getPropertyValueImpl(JSONObject* object, const
if (valueIterator == end) {
if (!valueFound)
- protocolErrors->pushString(String::format("Parameter '%s' with type '%s' was not found.", name.utf8().data(), type_name));
+ protocolErrors->pushString(String::format("Parameter '%s' with type '%s' was not found.", name, type_name));
return value;
}
if (!as_method(valueIterator->value.get(), &value))
- protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be '%s'.", name.utf8().data(), type_name));
+ protocolErrors->pushString(String::format("Parameter '%s' has wrong type. It must be '%s'.", name, type_name));
else
if (valueFound)
*valueFound = true;
@@ -444,32 +438,32 @@ struct AsMethodBridges {
static bool asArray(JSONValue* value, RefPtr<JSONArray>* output) { return value->asArray(output); }
};
-int InspectorBackendDispatcherImpl::getInt(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors)
+int InspectorBackendDispatcherImpl::getInt(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
{
return getPropertyValueImpl<int, int, int>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asInt, "Number");
}
-double InspectorBackendDispatcherImpl::getDouble(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors)
+double InspectorBackendDispatcherImpl::getDouble(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
{
return getPropertyValueImpl<double, double, double>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asDouble, "Number");
}
-String InspectorBackendDispatcherImpl::getString(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors)
+String InspectorBackendDispatcherImpl::getString(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
{
return getPropertyValueImpl<String, String, String>(object, name, valueFound, protocolErrors, "", AsMethodBridges::asString, "String");
}
-bool InspectorBackendDispatcherImpl::getBoolean(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors)
+bool InspectorBackendDispatcherImpl::getBoolean(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
{
return getPropertyValueImpl<bool, bool, bool>(object, name, valueFound, protocolErrors, false, AsMethodBridges::asBoolean, "Boolean");
}
-PassRefPtr<JSONObject> InspectorBackendDispatcherImpl::getObject(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors)
+PassRefPtr<JSONObject> InspectorBackendDispatcherImpl::getObject(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
{
return getPropertyValueImpl<PassRefPtr<JSONObject>, RefPtr<JSONObject>, JSONObject*>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asObject, "Object");
}
-PassRefPtr<JSONArray> InspectorBackendDispatcherImpl::getArray(JSONObject* object, const String& name, bool* valueFound, JSONArray* protocolErrors)
+PassRefPtr<JSONArray> InspectorBackendDispatcherImpl::getArray(JSONObject* object, const char* name, bool* valueFound, JSONArray* protocolErrors)
{
return getPropertyValueImpl<PassRefPtr<JSONArray>, RefPtr<JSONArray>, JSONArray*>(object, name, valueFound, protocolErrors, 0, AsMethodBridges::asArray, "Array");
}
@@ -498,7 +492,7 @@ InspectorBackendDispatcher::CallbackBase::~CallbackBase() {}
void InspectorBackendDispatcher::CallbackBase::sendFailure(const ErrorString& error)
{
ASSERT(error.length());
- sendIfActive(0, error, PassRefPtr<JSONValue>());
+ sendIfActive(nullptr, error, PassRefPtr<JSONValue>());
}
bool InspectorBackendDispatcher::CallbackBase::isActive()
@@ -510,7 +504,7 @@ void InspectorBackendDispatcher::CallbackBase::sendIfActive(PassRefPtr<JSONObjec
{
if (m_alreadySent)
return;
- m_backendImpl->sendResponse(m_id, partialMessage, invocationError, errorData);
+ m_backendImpl->sendResponse(m_id, invocationError, errorData, partialMessage);
m_alreadySent = true;
}
@@ -532,7 +526,9 @@ frontend_cpp = (
namespace WebCore {
InspectorFrontend::InspectorFrontend(InspectorFrontendChannel* inspectorFrontendChannel)
- : $constructorInit{
+ : m_inspectorFrontendChannel(inspectorFrontendChannel)
+ , $constructorInit
+{
}
$methods
@@ -663,6 +659,11 @@ public:
return static_cast<Array<T>*>(static_cast<JSONArrayBase*>(array.get()));
}
+ void concat(PassRefPtr<Array<T> > array)
+ {
+ return ArrayItemHelper<T>::Traits::concat(this->openAccessors(), array->openAccessors());
+ }
+
#if $validatorIfdefName
static void assertCorrectValue(JSONValue* value)
{
@@ -682,6 +683,12 @@ struct StructItemTraits {
array->pushValue(value);
}
+ static void concat(JSONArray* array, JSONArray* anotherArray)
+ {
+ for (JSONArray::iterator it = anotherArray->begin(); it != anotherArray->end(); ++it)
+ array->pushValue(*it);
+ }
+
#if $validatorIfdefName
template<typename T>
static void assertCorrectValue(JSONValue* value) {
@@ -890,7 +897,6 @@ $validatorCode
param_container_access_code = """
RefPtr<JSONObject> paramsContainer = requestMessageObject->getObject("params");
JSONObject* paramsContainerPtr = paramsContainer.get();
- JSONArray* protocolErrorsPtr = protocolErrors.get();
"""
class_binding_builder_part_1 = (
diff --git a/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py b/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
index ce639eba284..c3137176616 100644..100755
--- a/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
+++ b/chromium/third_party/WebKit/Source/core/inspector/CodeGeneratorInstrumentation.py
@@ -353,7 +353,7 @@ class Method:
agent_class=agent_class,
agent_fetch=agent_fetch,
maybe_return=maybe_return,
- params_agent=", ".join(map(Parameter.to_str_name, self.params_impl)[1:]))
+ params_agent=", ".join(map(Parameter.to_str_value, self.params_impl)[1:]))
class Parameter:
@@ -384,6 +384,12 @@ class Parameter:
self.type = param_decl
self.name = generate_param_name(self.type)
+ if re.match("PassRefPtr<", param_decl):
+ self.value = "%s.get()" % self.name
+ else:
+ self.value = self.name
+
+
def to_str_full(self):
if self.default_value is None:
return self.to_str_class_and_name()
@@ -398,6 +404,9 @@ class Parameter:
def to_str_name(self):
return self.name
+ def to_str_value(self):
+ return self.value
+
def generate_param_name(param_type):
base_name = re.match("(const |PassRefPtr<)?(\w*)", param_type).group(2)
@@ -405,7 +414,7 @@ def generate_param_name(param_type):
def agent_class_name(agent):
- custom_agent_names = ["Inspector", "PageDebugger", "PageRuntime", "WorkerRuntime"]
+ custom_agent_names = ["PageDebugger", "PageRuntime", "WorkerRuntime"]
if agent in custom_agent_names:
return "%sAgent" % agent
return "Inspector%sAgent" % agent
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp b/chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp
index 4e1dabc4619..c65f15cb30d 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp
@@ -35,6 +35,7 @@
#include "bindings/v8/ScriptCallStackFactory.h"
#include "bindings/v8/ScriptValue.h"
+#include "core/dom/ExecutionContext.h"
#include "core/inspector/IdentifiersFactory.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptManager.h"
@@ -50,40 +51,40 @@ ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source,
, m_type(type)
, m_level(level)
, m_message(message)
+ , m_scriptState(0)
, m_url()
, m_line(0)
, m_column(0)
- , m_repeatCount(1)
, m_requestId(IdentifiersFactory::requestId(0))
, m_timestamp(WTF::currentTime())
{
autogenerateMetadata(canGenerateCallStack);
}
-ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned line, unsigned column, ScriptState* state, unsigned long requestIdentifier)
+ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned line, unsigned column, ScriptState* scriptState, unsigned long requestIdentifier)
: m_source(source)
, m_type(type)
, m_level(level)
, m_message(message)
+ , m_scriptState(scriptState)
, m_url(url)
, m_line(line)
, m_column(column)
- , m_repeatCount(1)
, m_requestId(IdentifiersFactory::requestId(requestIdentifier))
, m_timestamp(WTF::currentTime())
{
- autogenerateMetadata(canGenerateCallStack, state);
+ autogenerateMetadata(canGenerateCallStack, scriptState);
}
-ConsoleMessage::ConsoleMessage(bool, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier)
+ConsoleMessage::ConsoleMessage(bool, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, unsigned long requestIdentifier)
: m_source(source)
, m_type(type)
, m_level(level)
, m_message(message)
- , m_arguments(0)
+ , m_scriptState(0)
+ , m_arguments(nullptr)
, m_line(0)
, m_column(0)
- , m_repeatCount(1)
, m_requestId(IdentifiersFactory::requestId(requestIdentifier))
, m_timestamp(WTF::currentTime())
{
@@ -96,33 +97,33 @@ ConsoleMessage::ConsoleMessage(bool, MessageSource source, MessageType type, Mes
m_callStack = callStack;
}
-ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptArguments> arguments, ScriptState* state, unsigned long requestIdentifier)
+ConsoleMessage::ConsoleMessage(bool canGenerateCallStack, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtrWillBeRawPtr<ScriptArguments> arguments, ScriptState* scriptState, unsigned long requestIdentifier)
: m_source(source)
, m_type(type)
, m_level(level)
, m_message(message)
+ , m_scriptState(scriptState)
, m_arguments(arguments)
, m_url()
, m_line(0)
, m_column(0)
- , m_repeatCount(1)
, m_requestId(IdentifiersFactory::requestId(requestIdentifier))
, m_timestamp(WTF::currentTime())
{
- autogenerateMetadata(canGenerateCallStack, state);
+ autogenerateMetadata(canGenerateCallStack, scriptState);
}
ConsoleMessage::~ConsoleMessage()
{
}
-void ConsoleMessage::autogenerateMetadata(bool canGenerateCallStack, ScriptState* state)
+void ConsoleMessage::autogenerateMetadata(bool canGenerateCallStack, ScriptState* scriptState)
{
if (m_type == EndGroupMessageType)
return;
- if (state)
- m_callStack = createScriptCallStackForConsole();
+ if (scriptState)
+ m_callStack = createScriptCallStackForConsole(scriptState);
else if (canGenerateCallStack)
m_callStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
else
@@ -198,12 +199,14 @@ void ConsoleMessage::addToFrontend(InspectorFrontend::Console* frontend, Injecte
jsonObj->setLine(static_cast<int>(m_line));
jsonObj->setColumn(static_cast<int>(m_column));
jsonObj->setUrl(m_url);
- jsonObj->setRepeatCount(static_cast<int>(m_repeatCount));
+ ScriptState* scriptState = m_scriptState.get();
+ if (scriptState && scriptState->executionContext()->isDocument())
+ jsonObj->setExecutionContextId(injectedScriptManager->injectedScriptIdFor(scriptState));
if (m_source == NetworkMessageSource && !m_requestId.isEmpty())
jsonObj->setNetworkRequestId(m_requestId);
if (m_arguments && m_arguments->argumentCount()) {
- InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(m_arguments->globalState());
- if (!injectedScript.hasNoValue()) {
+ InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(m_arguments->scriptState());
+ if (!injectedScript.isEmpty()) {
RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::RemoteObject> > jsonArgs = TypeBuilder::Array<TypeBuilder::Runtime::RemoteObject>::create();
if (m_type == TableMessageType && generatePreview && m_arguments->argumentCount()) {
ScriptValue table = m_arguments->argumentAt(0);
@@ -230,53 +233,17 @@ void ConsoleMessage::addToFrontend(InspectorFrontend::Console* frontend, Injecte
if (m_callStack)
jsonObj->setStackTrace(m_callStack->buildInspectorArray());
frontend->messageAdded(jsonObj);
+ frontend->flush();
}
-void ConsoleMessage::incrementCount()
+void ConsoleMessage::windowCleared(LocalDOMWindow* window)
{
- m_timestamp = WTF::currentTime();
- ++m_repeatCount;
-}
-
-void ConsoleMessage::updateRepeatCountInConsole(InspectorFrontend::Console* frontend)
-{
- frontend->messageRepeatCountUpdated(m_repeatCount, m_timestamp);
-}
+ if (m_scriptState.get() && m_scriptState.get()->domWindow() == window)
+ m_scriptState.clear();
-bool ConsoleMessage::isEqual(ConsoleMessage* msg) const
-{
- if (m_arguments) {
- if (!m_arguments->isEqual(msg->m_arguments.get()))
- return false;
- // Never treat objects as equal - their properties might change over time.
- for (size_t i = 0; i < m_arguments->argumentCount(); ++i) {
- if (m_arguments->argumentAt(i).isObject())
- return false;
- }
- } else if (msg->m_arguments)
- return false;
-
- if (m_callStack) {
- if (!m_callStack->isEqual(msg->m_callStack.get()))
- return false;
- } else if (msg->m_callStack)
- return false;
-
- return msg->m_source == m_source
- && msg->m_type == m_type
- && msg->m_level == m_level
- && msg->m_message == m_message
- && msg->m_line == m_line
- && msg->m_column == m_column
- && msg->m_url == m_url
- && msg->m_requestId == m_requestId;
-}
-
-void ConsoleMessage::windowCleared(DOMWindow* window)
-{
if (!m_arguments)
return;
- if (m_arguments->globalState()->domWindow() != window)
+ if (m_arguments->scriptState()->domWindow() != window)
return;
if (!m_message)
m_message = "<message collected>";
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.h b/chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.h
index f487f74bd95..de1abf60320 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/ConsoleMessage.h
@@ -31,15 +31,15 @@
#ifndef ConsoleMessage_h
#define ConsoleMessage_h
-#include "InspectorFrontend.h"
#include "bindings/v8/ScriptState.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/ConsoleAPITypes.h"
#include "core/frame/ConsoleTypes.h"
#include "wtf/Forward.h"
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class InjectedScriptManager;
class InspectorFrontend;
class ScriptArguments;
@@ -52,21 +52,16 @@ class ConsoleMessage {
public:
ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message);
ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, const String& url, unsigned line, unsigned column, ScriptState*, unsigned long requestIdentifier);
- ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier);
- ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptArguments>, ScriptState*, unsigned long requestIdentifier);
+ ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack>, unsigned long requestIdentifier);
+ ConsoleMessage(bool canGenerateCallStack, MessageSource, MessageType, MessageLevel, const String& message, PassRefPtrWillBeRawPtr<ScriptArguments>, ScriptState*, unsigned long requestIdentifier);
~ConsoleMessage();
void addToFrontend(InspectorFrontend::Console*, InjectedScriptManager*, bool generatePreview);
- void updateRepeatCountInConsole(InspectorFrontend::Console*);
- void incrementCount();
void setTimestamp(double timestamp) { m_timestamp = timestamp; }
- bool isEqual(ConsoleMessage* msg) const;
- MessageSource source() const { return m_source; }
- const String& message() const { return m_message; }
MessageType type() const { return m_type; }
- void windowCleared(DOMWindow*);
+ void windowCleared(LocalDOMWindow*);
unsigned argumentCount();
@@ -77,12 +72,12 @@ private:
MessageType m_type;
MessageLevel m_level;
String m_message;
- RefPtr<ScriptArguments> m_arguments;
- RefPtr<ScriptCallStack> m_callStack;
+ ScriptStateProtectingContext m_scriptState;
+ RefPtrWillBePersistent<ScriptArguments> m_arguments;
+ RefPtrWillBePersistent<ScriptCallStack> m_callStack;
String m_url;
unsigned m_line;
unsigned m_column;
- unsigned m_repeatCount;
String m_requestId;
double m_timestamp;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp b/chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp
index 9ed8568644c..cd20aeb7063 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp
@@ -33,8 +33,6 @@
#include "bindings/v8/ScriptRegexp.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
namespace ContentSearchUtils {
@@ -95,25 +93,6 @@ PassOwnPtr<ScriptRegexp> createSearchRegex(const String& query, bool caseSensiti
return adoptPtr(new ScriptRegexp(regexSource, caseSensitive ? TextCaseSensitive : TextCaseInsensitive));
}
-int countScriptRegexpMatches(const ScriptRegexp* regex, const String& content)
-{
- if (content.isEmpty())
- return 0;
-
- int result = 0;
- int position;
- unsigned start = 0;
- int matchLength;
- while ((position = regex->match(content, start, &matchLength)) != -1) {
- if (start >= content.length())
- break;
- if (matchLength > 0)
- ++result;
- start = position + 1;
- }
- return result;
-}
-
PassRefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> > searchInTextByLines(const String& text, const String& query, const bool caseSensitive, const bool isRegex)
{
RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> > result = TypeBuilder::Array<TypeBuilder::Page::SearchMatch>::create();
@@ -132,51 +111,65 @@ static String findMagicComment(const String& content, const String& name, MagicC
ASSERT(name.find("=") == kNotFound);
if (deprecated)
*deprecated = false;
- String pattern;
- String deprecatedPattern;
- switch (commentType) {
- case JavaScriptMagicComment:
- pattern = "//#[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s\'\"]*)[\040\t]*$";
- deprecatedPattern = "//@[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s\'\"]*)[\040\t]*$";
- break;
- case CSSMagicComment:
- pattern = "/\\*#[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s]*)[\040\t]*\\*/[\040\t]*$";
- deprecatedPattern = "/\\*@[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s]*)[\040\t]*\\*/[\040\t]*$";
+
+ unsigned length = content.length();
+ unsigned nameLength = name.length();
+
+ size_t pos = length;
+ size_t equalSignPos = 0;
+ size_t closingCommentPos = 0;
+ while (true) {
+ pos = content.reverseFind(name, pos);
+ if (pos == kNotFound)
+ return String();
+
+ // Check for a /\/[\/*][@#][ \t]/ regexp (length of 4) before found name.
+ if (pos < 4)
+ return String();
+ pos -= 4;
+ if (content[pos] != '/')
+ continue;
+ if ((content[pos + 1] != '/' || commentType != JavaScriptMagicComment)
+ && (content[pos + 1] != '*' || commentType != CSSMagicComment))
+ continue;
+ if (content[pos + 2] != '#' && content[pos + 2] != '@')
+ continue;
+ if (content[pos + 3] != ' ' && content[pos + 3] != '\t')
+ continue;
+ equalSignPos = pos + 4 + nameLength;
+ if (equalSignPos < length && content[equalSignPos] != '=')
+ continue;
+ if (commentType == CSSMagicComment) {
+ closingCommentPos = content.find("*/", equalSignPos + 1);
+ if (closingCommentPos == kNotFound)
+ return String();
+ }
+
break;
- default:
- ASSERT_NOT_REACHED();
- return String();
- }
- ScriptRegexp regex(pattern, TextCaseSensitive, MultilineEnabled);
- ScriptRegexp deprecatedRegex(deprecatedPattern, TextCaseSensitive, MultilineEnabled);
-
- int matchLength;
- int offset = regex.match(content, 0, &matchLength);
- if (offset == -1) {
- offset = deprecatedRegex.match(content, 0, &matchLength);
- if (offset != -1 && deprecated)
- *deprecated = true;
}
- if (offset == -1)
- return String();
-
- String match = content.substring(offset, matchLength);
- size_t separator = match.find("=");
- ASSERT(separator != kNotFound);
- match = match.substring(separator + 1);
-
- switch (commentType) {
- case JavaScriptMagicComment:
- return match.stripWhiteSpace();
- case CSSMagicComment: {
- size_t lastStarIndex = match.reverseFind('*');
- ASSERT(lastStarIndex != kNotFound);
- return match.substring(0, lastStarIndex).stripWhiteSpace();
- }
- default:
- ASSERT_NOT_REACHED();
- return String();
+
+ if (deprecated && content[pos + 2] == '@')
+ *deprecated = true;
+
+ ASSERT(equalSignPos);
+ ASSERT(commentType != CSSMagicComment || closingCommentPos);
+ size_t urlPos = equalSignPos + 1;
+ String match = commentType == CSSMagicComment
+ ? content.substring(urlPos, closingCommentPos - urlPos)
+ : content.substring(urlPos);
+
+ size_t newLine = match.find("\n");
+ if (newLine != kNotFound)
+ match = match.substring(0, newLine);
+ match = match.stripWhiteSpace();
+
+ String disallowedChars("\"' \t");
+ for (unsigned i = 0; i < match.length(); ++i) {
+ if (disallowedChars.find(match[i]) != kNotFound)
+ return "";
}
+
+ return match;
}
String findSourceURL(const String& content, MagicCommentType commentType, bool* deprecated)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.h b/chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.h
index 4ede1afb61a..4b5d9f25b6e 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/ContentSearchUtils.h
@@ -29,7 +29,7 @@
#ifndef ContentSearchUtils_h
#define ContentSearchUtils_h
-#include "InspectorTypeBuilder.h"
+#include "core/InspectorTypeBuilder.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/TextPosition.h"
@@ -47,7 +47,6 @@ enum MagicCommentType {
};
PassOwnPtr<ScriptRegexp> createSearchRegex(const String& query, bool caseSensitive, bool isRegex);
-int countScriptRegexpMatches(const ScriptRegexp*, const String&);
PassRefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> > searchInTextByLines(const String& text, const String& query, const bool caseSensitive, const bool isRegex);
String findSourceURL(const String& content, MagicCommentType, bool* deprecated);
diff --git a/chromium/third_party/WebKit/Source/core/inspector/DOMEditor.cpp b/chromium/third_party/WebKit/Source/core/inspector/DOMEditor.cpp
index cd3a1f5981d..9f00f7139a3 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/DOMEditor.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/DOMEditor.cpp
@@ -42,11 +42,9 @@
#include "core/inspector/InspectorHistory.h"
#include "wtf/RefPtr.h"
-using namespace std;
-
namespace WebCore {
-class DOMEditor::RemoveChildAction : public InspectorHistory::Action {
+class DOMEditor::RemoveChildAction FINAL : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(RemoveChildAction);
public:
RemoveChildAction(Node* parentNode, Node* node)
@@ -56,34 +54,42 @@ public:
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
m_anchorNode = m_node->nextSibling();
return redo(exceptionState);
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
m_parentNode->insertBefore(m_node.get(), m_anchorNode.get(), exceptionState);
return !exceptionState.hadException();
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
m_parentNode->removeChild(m_node.get(), exceptionState);
return !exceptionState.hadException();
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_parentNode);
+ visitor->trace(m_node);
+ visitor->trace(m_anchorNode);
+ InspectorHistory::Action::trace(visitor);
+ }
+
private:
- RefPtr<Node> m_parentNode;
- RefPtr<Node> m_node;
- RefPtr<Node> m_anchorNode;
+ RefPtrWillBeMember<Node> m_parentNode;
+ RefPtrWillBeMember<Node> m_node;
+ RefPtrWillBeMember<Node> m_anchorNode;
};
-class DOMEditor::InsertBeforeAction : public InspectorHistory::Action {
+class DOMEditor::InsertBeforeAction FINAL : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(InsertBeforeAction);
public:
- InsertBeforeAction(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode)
+ InsertBeforeAction(Node* parentNode, PassRefPtrWillBeRawPtr<Node> node, Node* anchorNode)
: InspectorHistory::Action("InsertBefore")
, m_parentNode(parentNode)
, m_node(node)
@@ -91,10 +97,10 @@ public:
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
if (m_node->parentNode()) {
- m_removeChildAction = adoptPtr(new RemoveChildAction(m_node->parentNode(), m_node.get()));
+ m_removeChildAction = adoptRefWillBeNoop(new RemoveChildAction(m_node->parentNode(), m_node.get()));
if (!m_removeChildAction->perform(exceptionState))
return false;
}
@@ -102,7 +108,7 @@ public:
return !exceptionState.hadException();
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
m_parentNode->removeChild(m_node.get(), exceptionState);
if (exceptionState.hadException())
@@ -112,7 +118,7 @@ public:
return true;
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
if (m_removeChildAction && !m_removeChildAction->redo(exceptionState))
return false;
@@ -120,14 +126,23 @@ public:
return !exceptionState.hadException();
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_parentNode);
+ visitor->trace(m_node);
+ visitor->trace(m_anchorNode);
+ visitor->trace(m_removeChildAction);
+ InspectorHistory::Action::trace(visitor);
+ }
+
private:
- RefPtr<Node> m_parentNode;
- RefPtr<Node> m_node;
- RefPtr<Node> m_anchorNode;
- OwnPtr<RemoveChildAction> m_removeChildAction;
+ RefPtrWillBeMember<Node> m_parentNode;
+ RefPtrWillBeMember<Node> m_node;
+ RefPtrWillBeMember<Node> m_anchorNode;
+ RefPtrWillBeMember<RemoveChildAction> m_removeChildAction;
};
-class DOMEditor::RemoveAttributeAction : public InspectorHistory::Action {
+class DOMEditor::RemoveAttributeAction FINAL : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(RemoveAttributeAction);
public:
RemoveAttributeAction(Element* element, const AtomicString& name)
@@ -137,31 +152,37 @@ public:
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
m_value = m_element->getAttribute(m_name);
return redo(exceptionState);
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
m_element->setAttribute(m_name, m_value, exceptionState);
return true;
}
- virtual bool redo(ExceptionState&)
+ virtual bool redo(ExceptionState&) OVERRIDE
{
m_element->removeAttribute(m_name);
return true;
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_element);
+ InspectorHistory::Action::trace(visitor);
+ }
+
private:
- RefPtr<Element> m_element;
+ RefPtrWillBeMember<Element> m_element;
AtomicString m_name;
AtomicString m_value;
};
-class DOMEditor::SetAttributeAction : public InspectorHistory::Action {
+class DOMEditor::SetAttributeAction FINAL : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(SetAttributeAction);
public:
SetAttributeAction(Element* element, const AtomicString& name, const AtomicString& value)
@@ -173,15 +194,16 @@ public:
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
- m_hadAttribute = m_element->hasAttribute(m_name);
+ const AtomicString& value = m_element->getAttribute(m_name);
+ m_hadAttribute = !value.isNull();
if (m_hadAttribute)
- m_oldValue = m_element->getAttribute(m_name);
+ m_oldValue = value;
return redo(exceptionState);
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
if (m_hadAttribute)
m_element->setAttribute(m_name, m_oldValue, exceptionState);
@@ -190,21 +212,27 @@ public:
return true;
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
m_element->setAttribute(m_name, m_value, exceptionState);
return true;
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_element);
+ InspectorHistory::Action::trace(visitor);
+ }
+
private:
- RefPtr<Element> m_element;
+ RefPtrWillBeMember<Element> m_element;
AtomicString m_name;
AtomicString m_value;
bool m_hadAttribute;
AtomicString m_oldValue;
};
-class DOMEditor::SetOuterHTMLAction : public InspectorHistory::Action {
+class DOMEditor::SetOuterHTMLAction FINAL : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(SetOuterHTMLAction);
public:
SetOuterHTMLAction(Node* node, const String& html)
@@ -212,13 +240,13 @@ public:
, m_node(node)
, m_nextSibling(node->nextSibling())
, m_html(html)
- , m_newNode(0)
- , m_history(adoptPtr(new InspectorHistory()))
- , m_domEditor(adoptPtr(new DOMEditor(m_history.get())))
+ , m_newNode(nullptr)
+ , m_history(adoptPtrWillBeNoop(new InspectorHistory()))
+ , m_domEditor(adoptPtrWillBeNoop(new DOMEditor(m_history.get())))
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
m_oldHTML = createMarkup(m_node.get());
ASSERT(m_node->ownerDocument());
@@ -227,12 +255,12 @@ public:
return !exceptionState.hadException();
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
return m_history->undo(exceptionState);
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
return m_history->redo(exceptionState);
}
@@ -242,17 +270,27 @@ public:
return m_newNode;
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_node);
+ visitor->trace(m_nextSibling);
+ visitor->trace(m_newNode);
+ visitor->trace(m_history);
+ visitor->trace(m_domEditor);
+ InspectorHistory::Action::trace(visitor);
+ }
+
private:
- RefPtr<Node> m_node;
- RefPtr<Node> m_nextSibling;
+ RefPtrWillBeMember<Node> m_node;
+ RefPtrWillBeMember<Node> m_nextSibling;
String m_html;
String m_oldHTML;
- Node* m_newNode;
- OwnPtr<InspectorHistory> m_history;
- OwnPtr<DOMEditor> m_domEditor;
+ RawPtrWillBeMember<Node> m_newNode;
+ OwnPtrWillBeMember<InspectorHistory> m_history;
+ OwnPtrWillBeMember<DOMEditor> m_domEditor;
};
-class DOMEditor::ReplaceWholeTextAction : public InspectorHistory::Action {
+class DOMEditor::ReplaceWholeTextAction FINAL : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(ReplaceWholeTextAction);
public:
ReplaceWholeTextAction(Text* textNode, const String& text)
@@ -262,34 +300,40 @@ public:
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
m_oldText = m_textNode->wholeText();
return redo(exceptionState);
}
- virtual bool undo(ExceptionState&)
+ virtual bool undo(ExceptionState&) OVERRIDE
{
m_textNode->replaceWholeText(m_oldText);
return true;
}
- virtual bool redo(ExceptionState&)
+ virtual bool redo(ExceptionState&) OVERRIDE
{
m_textNode->replaceWholeText(m_text);
return true;
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_textNode);
+ InspectorHistory::Action::trace(visitor);
+ }
+
private:
- RefPtr<Text> m_textNode;
+ RefPtrWillBeMember<Text> m_textNode;
String m_text;
String m_oldText;
};
-class DOMEditor::ReplaceChildNodeAction : public InspectorHistory::Action {
+class DOMEditor::ReplaceChildNodeAction FINAL : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(ReplaceChildNodeAction);
public:
- ReplaceChildNodeAction(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode)
+ ReplaceChildNodeAction(Node* parentNode, PassRefPtrWillBeRawPtr<Node> newNode, Node* oldNode)
: InspectorHistory::Action("ReplaceChildNode")
, m_parentNode(parentNode)
, m_newNode(newNode)
@@ -297,30 +341,38 @@ public:
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
return redo(exceptionState);
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
m_parentNode->replaceChild(m_oldNode, m_newNode.get(), exceptionState);
return !exceptionState.hadException();
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
m_parentNode->replaceChild(m_newNode, m_oldNode.get(), exceptionState);
return !exceptionState.hadException();
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_parentNode);
+ visitor->trace(m_newNode);
+ visitor->trace(m_oldNode);
+ InspectorHistory::Action::trace(visitor);
+ }
+
private:
- RefPtr<Node> m_parentNode;
- RefPtr<Node> m_newNode;
- RefPtr<Node> m_oldNode;
+ RefPtrWillBeMember<Node> m_parentNode;
+ RefPtrWillBeMember<Node> m_newNode;
+ RefPtrWillBeMember<Node> m_oldNode;
};
-class DOMEditor::SetNodeValueAction : public InspectorHistory::Action {
+class DOMEditor::SetNodeValueAction FINAL : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(SetNodeValueAction);
public:
SetNodeValueAction(Node* node, const String& value)
@@ -330,77 +382,80 @@ public:
{
}
- virtual bool perform(ExceptionState&)
+ virtual bool perform(ExceptionState&) OVERRIDE
{
m_oldValue = m_node->nodeValue();
return redo(IGNORE_EXCEPTION);
}
- virtual bool undo(ExceptionState&)
+ virtual bool undo(ExceptionState&) OVERRIDE
{
m_node->setNodeValue(m_oldValue);
return true;
}
- virtual bool redo(ExceptionState&)
+ virtual bool redo(ExceptionState&) OVERRIDE
{
m_node->setNodeValue(m_value);
return true;
}
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ visitor->trace(m_node);
+ InspectorHistory::Action::trace(visitor);
+ }
+
private:
- RefPtr<Node> m_node;
+ RefPtrWillBeMember<Node> m_node;
String m_value;
String m_oldValue;
};
DOMEditor::DOMEditor(InspectorHistory* history) : m_history(history) { }
-DOMEditor::~DOMEditor() { }
-
-bool DOMEditor::insertBefore(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode, ExceptionState& exceptionState)
+bool DOMEditor::insertBefore(Node* parentNode, PassRefPtrWillBeRawPtr<Node> node, Node* anchorNode, ExceptionState& exceptionState)
{
- return m_history->perform(adoptPtr(new InsertBeforeAction(parentNode, node, anchorNode)), exceptionState);
+ return m_history->perform(adoptRefWillBeNoop(new InsertBeforeAction(parentNode, node, anchorNode)), exceptionState);
}
bool DOMEditor::removeChild(Node* parentNode, Node* node, ExceptionState& exceptionState)
{
- return m_history->perform(adoptPtr(new RemoveChildAction(parentNode, node)), exceptionState);
+ return m_history->perform(adoptRefWillBeNoop(new RemoveChildAction(parentNode, node)), exceptionState);
}
bool DOMEditor::setAttribute(Element* element, const String& name, const String& value, ExceptionState& exceptionState)
{
- return m_history->perform(adoptPtr(new SetAttributeAction(element, name, value)), exceptionState);
+ return m_history->perform(adoptRefWillBeNoop(new SetAttributeAction(element, AtomicString(name), AtomicString(value))), exceptionState);
}
bool DOMEditor::removeAttribute(Element* element, const String& name, ExceptionState& exceptionState)
{
- return m_history->perform(adoptPtr(new RemoveAttributeAction(element, name)), exceptionState);
+ return m_history->perform(adoptRefWillBeNoop(new RemoveAttributeAction(element, AtomicString(name))), exceptionState);
}
bool DOMEditor::setOuterHTML(Node* node, const String& html, Node** newNode, ExceptionState& exceptionState)
{
- OwnPtr<SetOuterHTMLAction> action = adoptPtr(new SetOuterHTMLAction(node, html));
- SetOuterHTMLAction* rawAction = action.get();
- bool result = m_history->perform(action.release(), exceptionState);
+ RefPtrWillBeRawPtr<SetOuterHTMLAction> action = adoptRefWillBeNoop(new SetOuterHTMLAction(node, html));
+ bool result = m_history->perform(action, exceptionState);
if (result)
- *newNode = rawAction->newNode();
+ *newNode = action->newNode();
return result;
}
bool DOMEditor::replaceWholeText(Text* textNode, const String& text, ExceptionState& exceptionState)
{
- return m_history->perform(adoptPtr(new ReplaceWholeTextAction(textNode, text)), exceptionState);
+ return m_history->perform(adoptRefWillBeNoop(new ReplaceWholeTextAction(textNode, text)), exceptionState);
}
-bool DOMEditor::replaceChild(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode, ExceptionState& exceptionState)
+bool DOMEditor::replaceChild(Node* parentNode, PassRefPtrWillBeRawPtr<Node> newNode, Node* oldNode, ExceptionState& exceptionState)
{
- return m_history->perform(adoptPtr(new ReplaceChildNodeAction(parentNode, newNode, oldNode)), exceptionState);
+ return m_history->perform(adoptRefWillBeNoop(new ReplaceChildNodeAction(parentNode, newNode, oldNode)), exceptionState);
}
bool DOMEditor::setNodeValue(Node* node, const String& value, ExceptionState& exceptionState)
{
- return m_history->perform(adoptPtr(new SetNodeValueAction(node, value)), exceptionState);
+ return m_history->perform(adoptRefWillBeNoop(new SetNodeValueAction(node, value)), exceptionState);
}
static void populateErrorString(ExceptionState& exceptionState, ErrorString* errorString)
@@ -409,7 +464,7 @@ static void populateErrorString(ExceptionState& exceptionState, ErrorString* err
*errorString = DOMException::getErrorName(exceptionState.code());
}
-bool DOMEditor::insertBefore(Node* parentNode, PassRefPtr<Node> node, Node* anchorNode, ErrorString* errorString)
+bool DOMEditor::insertBefore(Node* parentNode, PassRefPtrWillBeRawPtr<Node> node, Node* anchorNode, ErrorString* errorString)
{
TrackExceptionState exceptionState;
bool result = insertBefore(parentNode, node, anchorNode, exceptionState);
@@ -457,5 +512,10 @@ bool DOMEditor::replaceWholeText(Text* textNode, const String& text, ErrorString
return result;
}
+void DOMEditor::trace(Visitor* visitor)
+{
+ visitor->trace(m_history);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/DOMEditor.h b/chromium/third_party/WebKit/Source/core/inspector/DOMEditor.h
index b0be0cf7d19..00528cb09ef 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/DOMEditor.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/DOMEditor.h
@@ -31,6 +31,7 @@
#ifndef DOMEditor_h
#define DOMEditor_h
+#include "platform/heap/Handle.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -43,22 +44,24 @@ class Text;
typedef String ErrorString;
-class DOMEditor {
- WTF_MAKE_NONCOPYABLE(DOMEditor); WTF_MAKE_FAST_ALLOCATED;
+class DOMEditor FINAL : public NoBaseWillBeGarbageCollected<DOMEditor> {
+ WTF_MAKE_NONCOPYABLE(DOMEditor);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
explicit DOMEditor(InspectorHistory*);
- ~DOMEditor();
- bool insertBefore(Node* parentNode, PassRefPtr<Node>, Node* anchorNode, ExceptionState&);
+ void trace(Visitor*);
+
+ bool insertBefore(Node* parentNode, PassRefPtrWillBeRawPtr<Node>, Node* anchorNode, ExceptionState&);
bool removeChild(Node* parentNode, Node*, ExceptionState&);
bool setAttribute(Element*, const String& name, const String& value, ExceptionState&);
bool removeAttribute(Element*, const String& name, ExceptionState&);
bool setOuterHTML(Node*, const String& html, Node** newNode, ExceptionState&);
bool replaceWholeText(Text*, const String& text, ExceptionState&);
- bool replaceChild(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode, ExceptionState&);
+ bool replaceChild(Node* parentNode, PassRefPtrWillBeRawPtr<Node> newNode, Node* oldNode, ExceptionState&);
bool setNodeValue(Node* parentNode, const String& value, ExceptionState&);
- bool insertBefore(Node* parentNode, PassRefPtr<Node>, Node* anchorNode, ErrorString*);
+ bool insertBefore(Node* parentNode, PassRefPtrWillBeRawPtr<Node>, Node* anchorNode, ErrorString*);
bool removeChild(Node* parentNode, Node*, ErrorString*);
bool setAttribute(Element*, const String& name, const String& value, ErrorString*);
bool removeAttribute(Element*, const String& name, ErrorString*);
@@ -76,7 +79,7 @@ private:
class ReplaceChildNodeAction;
class SetNodeValueAction;
- InspectorHistory* m_history;
+ RawPtrWillBeMember<InspectorHistory> m_history;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/DOMPatchSupport.cpp b/chromium/third_party/WebKit/Source/core/inspector/DOMPatchSupport.cpp
index d5c7cd5dccf..755816d541e 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/DOMPatchSupport.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/DOMPatchSupport.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "core/inspector/DOMPatchSupport.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/Attribute.h"
@@ -39,26 +38,24 @@
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/Node.h"
+#include "core/dom/XMLDocument.h"
+#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLDocument.h"
+#include "core/html/HTMLHeadElement.h"
#include "core/html/parser/HTMLDocumentParser.h"
#include "core/inspector/DOMEditor.h"
#include "core/inspector/InspectorHistory.h"
#include "core/xml/parser/XMLDocumentParser.h"
+#include "platform/Crypto.h"
+#include "public/platform/Platform.h"
#include "wtf/Deque.h"
#include "wtf/HashTraits.h"
#include "wtf/RefPtr.h"
-#include "wtf/SHA1.h"
#include "wtf/text/Base64.h"
#include "wtf/text/CString.h"
-using namespace std;
-
namespace WebCore {
-using HTMLNames::bodyTag;
-using HTMLNames::headTag;
-using HTMLNames::htmlTag;
-
struct DOMPatchSupport::Digest {
explicit Digest(Node* node) : m_node(node) { }
@@ -84,21 +81,21 @@ DOMPatchSupport::DOMPatchSupport(DOMEditor* domEditor, Document& document)
void DOMPatchSupport::patchDocument(const String& markup)
{
- RefPtr<Document> newDocument;
+ RefPtrWillBeRawPtr<Document> newDocument = nullptr;
if (m_document.isHTMLDocument())
newDocument = HTMLDocument::create();
else if (m_document.isXHTMLDocument())
- newDocument = HTMLDocument::createXHTML();
- else if (m_document.isSVGDocument())
- newDocument = Document::create();
+ newDocument = XMLDocument::createXHTML();
+ else if (m_document.isXMLDocument())
+ newDocument = XMLDocument::create();
ASSERT(newDocument);
newDocument->setContextFeatures(m_document.contextFeatures());
- RefPtr<DocumentParser> parser;
+ RefPtrWillBeRawPtr<DocumentParser> parser = nullptr;
if (m_document.isHTMLDocument())
- parser = HTMLDocumentParser::create(toHTMLDocument(newDocument.get()), false);
+ parser = HTMLDocumentParser::create(toHTMLDocument(*newDocument), false);
else
- parser = XMLDocumentParser::create(newDocument.get(), 0);
+ parser = XMLDocumentParser::create(*newDocument, 0);
parser->insert(markup); // Use insert() so that the parser will not yield.
parser->finish();
parser->detach();
@@ -122,12 +119,20 @@ Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionStat
}
Node* previousSibling = node->previousSibling();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
+ Node* targetNode = node->parentElementOrShadowRoot() ? node->parentElementOrShadowRoot() : m_document.documentElement();
+
+ // Use the document BODY as the context element when editing immediate shadow root children,
+ // as it provides an equivalent parsing context.
+ if (targetNode->isShadowRoot())
+ targetNode = m_document.body();
+ Element* targetElement = toElement(targetNode);
+
// FIXME: This code should use one of createFragment* in markup.h
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
if (m_document.isHTMLDocument())
- fragment->parseHTML(markup, node->parentElement() ? node->parentElement() : m_document.documentElement());
+ fragment->parseHTML(markup, targetElement);
else
- fragment->parseXML(markup, node->parentElement() ? node->parentElement() : m_document.documentElement());
+ fragment->parseXML(markup, targetElement);
// Compose the old list.
ContainerNode* parentNode = node->parentNode();
@@ -141,9 +146,9 @@ Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionStat
for (Node* child = parentNode->firstChild(); child != node; child = child->nextSibling())
newList.append(createDigest(child, 0));
for (Node* child = fragment->firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(headTag) && !child->firstChild() && markupCopy.find("</head>") == kNotFound)
+ if (isHTMLHeadElement(*child) && !child->firstChild() && markupCopy.find("</head>") == kNotFound)
continue; // HTML5 parser inserts empty <head> tag whenever it parses <body>
- if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.find("</body>") == kNotFound)
+ if (isHTMLBodyElement(*child) && !child->firstChild() && markupCopy.find("</body>") == kNotFound)
continue; // HTML5 parser inserts empty <body> tag whenever it parses </head>
newList.append(createDigest(child, &m_unusedNodesMap));
}
@@ -174,7 +179,7 @@ bool DOMPatchSupport::innerPatchNode(Digest* oldDigest, Digest* newDigest, Excep
return false;
}
- if (oldNode->nodeType() != Node::ELEMENT_NODE)
+ if (!oldNode->isElementNode())
return true;
// Patch attributes
@@ -184,18 +189,18 @@ bool DOMPatchSupport::innerPatchNode(Digest* oldDigest, Digest* newDigest, Excep
// FIXME: Create a function in Element for removing all properties. Take in account whether did/willModifyAttribute are important.
if (oldElement->hasAttributesWithoutUpdate()) {
while (oldElement->attributeCount()) {
- const Attribute* attribute = oldElement->attributeItem(0);
- if (!m_domEditor->removeAttribute(oldElement, attribute->localName(), exceptionState))
+ const Attribute& attribute = oldElement->attributeAt(0);
+ if (!m_domEditor->removeAttribute(oldElement, attribute.localName(), exceptionState))
return false;
}
}
// FIXME: Create a function in Element for copying properties. cloneDataFromElement() is close but not enough for this case.
if (newElement->hasAttributesWithoutUpdate()) {
- size_t numAttrs = newElement->attributeCount();
- for (size_t i = 0; i < numAttrs; ++i) {
- const Attribute* attribute = newElement->attributeItem(i);
- if (!m_domEditor->setAttribute(oldElement, attribute->name().localName(), attribute->value(), exceptionState))
+ AttributeCollection attributes = newElement->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (!m_domEditor->setAttribute(oldElement, it->name().localName(), it->value(), exceptionState))
return false;
}
}
@@ -243,13 +248,11 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt
DiffTable oldTable;
for (size_t i = 0; i < newList.size(); ++i) {
- DiffTable::iterator it = newTable.add(newList[i]->m_sha1, Vector<size_t>()).iterator;
- it->value.append(i);
+ newTable.add(newList[i]->m_sha1, Vector<size_t>()).storedValue->value.append(i);
}
for (size_t i = 0; i < oldList.size(); ++i) {
- DiffTable::iterator it = oldTable.add(oldList[i]->m_sha1, Vector<size_t>()).iterator;
- it->value.append(i);
+ oldTable.add(oldList[i]->m_sha1, Vector<size_t>()).storedValue->value.append(i);
}
for (DiffTable::iterator newIt = newTable.begin(); newIt != newTable.end(); ++newIt) {
@@ -260,8 +263,8 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt
if (oldIt == oldTable.end() || oldIt->value.size() != 1)
continue;
- newMap[newIt->value[0]] = make_pair(newList[newIt->value[0]].get(), oldIt->value[0]);
- oldMap[oldIt->value[0]] = make_pair(oldList[oldIt->value[0]].get(), newIt->value[0]);
+ newMap[newIt->value[0]] = std::make_pair(newList[newIt->value[0]].get(), oldIt->value[0]);
+ oldMap[oldIt->value[0]] = std::make_pair(oldList[oldIt->value[0]].get(), newIt->value[0]);
}
for (size_t i = 0; newList.size() > 0 && i < newList.size() - 1; ++i) {
@@ -270,8 +273,8 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt
size_t j = newMap[i].second + 1;
if (j < oldMap.size() && !oldMap[j].first && newList[i + 1]->m_sha1 == oldList[j]->m_sha1) {
- newMap[i + 1] = make_pair(newList[i + 1].get(), j);
- oldMap[j] = make_pair(oldList[j].get(), i + 1);
+ newMap[i + 1] = std::make_pair(newList[i + 1].get(), j);
+ oldMap[j] = std::make_pair(oldList[j].get(), i + 1);
}
}
@@ -281,8 +284,8 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt
size_t j = newMap[i].second - 1;
if (!oldMap[j].first && newList[i - 1]->m_sha1 == oldList[j]->m_sha1) {
- newMap[i - 1] = make_pair(newList[i - 1].get(), j);
- oldMap[j] = make_pair(oldList[j].get(), i - 1);
+ newMap[i - 1] = std::make_pair(newList[i - 1].get(), j);
+ oldMap[j] = std::make_pair(oldList[j].get(), i - 1);
}
}
@@ -291,7 +294,7 @@ DOMPatchSupport::diff(const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPt
dumpMap(newMap, "NEW");
#endif
- return make_pair(oldMap, newMap);
+ return std::make_pair(oldMap, newMap);
}
bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPtr<Digest> >& newList, ExceptionState& exceptionState)
@@ -316,11 +319,11 @@ bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector
// Always match <head> and <body> tags with each other - we can't remove them from the DOM
// upon patching.
- if (oldList[i]->m_node->hasTagName(headTag)) {
+ if (isHTMLHeadElement(*oldList[i]->m_node)) {
oldHead = oldList[i].get();
continue;
}
- if (oldList[i]->m_node->hasTagName(bodyTag)) {
+ if (isHTMLBodyElement(*oldList[i]->m_node)) {
oldBody = oldList[i].get();
continue;
}
@@ -360,9 +363,9 @@ bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector
// Mark <head> and <body> nodes for merge.
if (oldHead || oldBody) {
for (size_t i = 0; i < newList.size(); ++i) {
- if (oldHead && newList[i]->m_node->hasTagName(headTag))
+ if (oldHead && isHTMLHeadElement(*newList[i]->m_node))
merges.set(newList[i].get(), oldHead);
- if (oldBody && newList[i]->m_node->hasTagName(bodyTag))
+ if (oldBody && isHTMLBodyElement(*newList[i]->m_node))
merges.set(newList[i].get(), oldBody);
}
}
@@ -377,7 +380,7 @@ bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector
for (size_t i = 0; i < newMap.size(); ++i) {
if (newMap[i].first || merges.contains(newList[i].get()))
continue;
- if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode->childNode(i), exceptionState))
+ if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode->traverseToChildAt(i), exceptionState))
return false;
}
@@ -385,11 +388,11 @@ bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector
for (size_t i = 0; i < oldMap.size(); ++i) {
if (!oldMap[i].first)
continue;
- RefPtr<Node> node = oldMap[i].first->m_node;
- Node* anchorNode = parentNode->childNode(oldMap[i].second);
- if (node.get() == anchorNode)
+ RefPtrWillBeRawPtr<Node> node = oldMap[i].first->m_node;
+ Node* anchorNode = parentNode->traverseToChildAt(oldMap[i].second);
+ if (node == anchorNode)
continue;
- if (node->hasTagName(bodyTag) || node->hasTagName(headTag))
+ if (isHTMLBodyElement(*node) || isHTMLHeadElement(*node))
continue; // Never move head or body, move the rest of the nodes around them.
if (!m_domEditor->insertBefore(parentNode, node.release(), anchorNode, exceptionState))
@@ -398,51 +401,50 @@ bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector
return true;
}
-static void addStringToSHA1(SHA1& sha1, const String& string)
+static void addStringToDigestor(blink::WebCryptoDigestor* digestor, const String& string)
{
- CString cString = string.utf8();
- sha1.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.length());
+ digestor->consume(reinterpret_cast<const unsigned char*>(string.utf8().data()), string.length());
}
PassOwnPtr<DOMPatchSupport::Digest> DOMPatchSupport::createDigest(Node* node, UnusedNodesMap* unusedNodesMap)
{
Digest* digest = new Digest(node);
- SHA1 sha1;
+ OwnPtr<blink::WebCryptoDigestor> digestor = createDigestor(HashAlgorithmSha1);
+ DigestValue digestResult;
Node::NodeType nodeType = node->nodeType();
- sha1.addBytes(reinterpret_cast<const uint8_t*>(&nodeType), sizeof(nodeType));
- addStringToSHA1(sha1, node->nodeName());
- addStringToSHA1(sha1, node->nodeValue());
+ digestor->consume(reinterpret_cast<const unsigned char*>(&nodeType), sizeof(nodeType));
+ addStringToDigestor(digestor.get(), node->nodeName());
+ addStringToDigestor(digestor.get(), node->nodeValue());
- if (node->nodeType() == Node::ELEMENT_NODE) {
- Node* child = node->firstChild();
+ if (node->isElementNode()) {
+ Element& element = toElement(*node);
+ Node* child = element.firstChild();
while (child) {
OwnPtr<Digest> childInfo = createDigest(child, unusedNodesMap);
- addStringToSHA1(sha1, childInfo->m_sha1);
+ addStringToDigestor(digestor.get(), childInfo->m_sha1);
child = child->nextSibling();
digest->m_children.append(childInfo.release());
}
- Element* element = toElement(node);
-
- if (element->hasAttributesWithoutUpdate()) {
- size_t numAttrs = element->attributeCount();
- SHA1 attrsSHA1;
- for (size_t i = 0; i < numAttrs; ++i) {
- const Attribute* attribute = element->attributeItem(i);
- addStringToSHA1(attrsSHA1, attribute->name().toString());
- addStringToSHA1(attrsSHA1, attribute->value());
+
+ if (element.hasAttributesWithoutUpdate()) {
+ OwnPtr<blink::WebCryptoDigestor> attrsDigestor = createDigestor(HashAlgorithmSha1);
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ addStringToDigestor(attrsDigestor.get(), it->name().toString());
+ addStringToDigestor(attrsDigestor.get(), it->value().string());
}
- Vector<uint8_t, 20> attrsHash;
- attrsSHA1.computeHash(attrsHash);
- digest->m_attrsSHA1 = base64Encode(reinterpret_cast<const char*>(attrsHash.data()), 10);
- addStringToSHA1(sha1, digest->m_attrsSHA1);
+ finishDigestor(attrsDigestor.get(), digestResult);
+ digest->m_attrsSHA1 = base64Encode(reinterpret_cast<const char*>(digestResult.data()), 10);
+ addStringToDigestor(digestor.get(), digest->m_attrsSHA1);
+ digestResult.clear();
}
}
+ finishDigestor(digestor.get(), digestResult);
+ digest->m_sha1 = base64Encode(reinterpret_cast<const char*>(digestResult.data()), 10);
- Vector<uint8_t, 20> hash;
- sha1.computeHash(hash);
- digest->m_sha1 = base64Encode(reinterpret_cast<const char*>(hash.data()), 10);
if (unusedNodesMap)
unusedNodesMap->add(digest->m_sha1, digest);
return adoptPtr(digest);
@@ -457,7 +459,7 @@ bool DOMPatchSupport::insertBeforeAndMarkAsUsed(ContainerNode* parentNode, Diges
bool DOMPatchSupport::removeChildAndMoveToNew(Digest* oldDigest, ExceptionState& exceptionState)
{
- RefPtr<Node> oldNode = oldDigest->m_node;
+ RefPtrWillBeRawPtr<Node> oldNode = oldDigest->m_node;
if (!m_domEditor->removeChild(oldNode->parentNode(), oldNode.get(), exceptionState))
return false;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScript.cpp b/chromium/third_party/WebKit/Source/core/inspector/InjectedScript.cpp
index 9d46e69bdf5..b7a2e55c668 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScript.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScript.cpp
@@ -52,7 +52,7 @@ InjectedScript::InjectedScript()
{
}
-InjectedScript::InjectedScript(ScriptObject injectedScriptObject, InspectedStateAccessCheck accessCheck)
+InjectedScript::InjectedScript(ScriptValue injectedScriptObject, InspectedStateAccessCheck accessCheck)
: InjectedScriptBase("InjectedScript", injectedScriptObject, accessCheck)
{
}
@@ -79,10 +79,11 @@ void InjectedScript::callFunctionOn(ErrorString* errorString, const String& obje
makeEvalCall(errorString, function, result, wasThrown);
}
-void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const ScriptValue& callFrames, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown)
+void InjectedScript::evaluateOnCallFrame(ErrorString* errorString, const ScriptValue& callFrames, const Vector<ScriptValue>& asyncCallStacks, const String& callFrameId, const String& expression, const String& objectGroup, bool includeCommandLineAPI, bool returnByValue, bool generatePreview, RefPtr<RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown)
{
ScriptFunctionCall function(injectedScriptObject(), "evaluateOnCallFrame");
function.appendArgument(callFrames);
+ function.appendArgument(asyncCallStacks);
function.appendArgument(callFrameId);
function.appendArgument(expression);
function.appendArgument(objectGroup);
@@ -210,7 +211,7 @@ void InjectedScript::getInternalProperties(ErrorString* errorString, const Strin
Node* InjectedScript::nodeForObjectId(const String& objectId)
{
- if (hasNoValue() || !canAccessInspectedWindow())
+ if (isEmpty() || !canAccessInspectedWindow())
return 0;
ScriptFunctionCall function(injectedScriptObject(), "nodeForObjectId");
@@ -220,7 +221,7 @@ Node* InjectedScript::nodeForObjectId(const String& objectId)
ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException);
ASSERT(!hadException);
- return InjectedScriptHost::scriptValueAsNode(resultValue);
+ return InjectedScriptHost::scriptValueAsNode(scriptState(), resultValue);
}
void InjectedScript::releaseObject(const String& objectId)
@@ -231,23 +232,24 @@ void InjectedScript::releaseObject(const String& objectId)
makeCall(function, &result);
}
-PassRefPtr<Array<CallFrame> > InjectedScript::wrapCallFrames(const ScriptValue& callFrames)
+PassRefPtr<Array<CallFrame> > InjectedScript::wrapCallFrames(const ScriptValue& callFrames, int asyncOrdinal)
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
ScriptFunctionCall function(injectedScriptObject(), "wrapCallFrames");
function.appendArgument(callFrames);
+ function.appendArgument(asyncOrdinal);
bool hadException = false;
ScriptValue callFramesValue = callFunctionWithEvalEnabled(function, hadException);
ASSERT(!hadException);
RefPtr<JSONValue> result = callFramesValue.toJSONValue(scriptState());
- if (result->type() == JSONValue::TypeArray)
+ if (result && result->type() == JSONValue::TypeArray)
return Array<CallFrame>::runtimeCast(result);
return Array<CallFrame>::create();
}
PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapObject(const ScriptValue& value, const String& groupName, bool generatePreview) const
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
ScriptFunctionCall wrapFunction(injectedScriptObject(), "wrapObject");
wrapFunction.appendArgument(value);
wrapFunction.appendArgument(groupName);
@@ -256,25 +258,25 @@ PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapObject(const
bool hadException = false;
ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException);
if (hadException)
- return 0;
+ return nullptr;
RefPtr<JSONObject> rawResult = r.toJSONValue(scriptState())->asObject();
return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult);
}
PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapTable(const ScriptValue& table, const ScriptValue& columns) const
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
ScriptFunctionCall wrapFunction(injectedScriptObject(), "wrapTable");
wrapFunction.appendArgument(canAccessInspectedWindow());
wrapFunction.appendArgument(table);
- if (columns.hasNoValue())
+ if (columns.isEmpty())
wrapFunction.appendArgument(false);
else
wrapFunction.appendArgument(columns);
bool hadException = false;
ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException);
if (hadException)
- return 0;
+ return nullptr;
RefPtr<JSONObject> rawResult = r.toJSONValue(scriptState())->asObject();
return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult);
}
@@ -286,7 +288,7 @@ PassRefPtr<TypeBuilder::Runtime::RemoteObject> InjectedScript::wrapNode(Node* no
ScriptValue InjectedScript::findObjectById(const String& objectId) const
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
ScriptFunctionCall function(injectedScriptObject(), "findObjectById");
function.appendArgument(objectId);
@@ -296,24 +298,9 @@ ScriptValue InjectedScript::findObjectById(const String& objectId) const
return resultValue;
}
-ScriptValue InjectedScript::findCallFrameById(ErrorString* errorString, const ScriptValue& topCallFrame, const String& callFrameId)
-{
- ScriptFunctionCall function(injectedScriptObject(), "callFrameForId");
- function.appendArgument(topCallFrame);
- function.appendArgument(callFrameId);
- bool hadException = false;
- ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException);
- ASSERT(!hadException);
- if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) {
- *errorString = "Internal error";
- return ScriptValue();
- }
- return resultValue;
-}
-
void InjectedScript::inspectNode(Node* node)
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
ScriptFunctionCall function(injectedScriptObject(), "inspectNode");
function.appendArgument(nodeAsScriptValue(node));
RefPtr<JSONValue> result;
@@ -322,7 +309,7 @@ void InjectedScript::inspectNode(Node* node)
void InjectedScript::releaseObjectGroup(const String& objectGroup)
{
- ASSERT(!hasNoValue());
+ ASSERT(!isEmpty());
ScriptFunctionCall releaseFunction(injectedScriptObject(), "releaseObjectGroup");
releaseFunction.appendArgument(objectGroup);
bool hadException = false;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScript.h b/chromium/third_party/WebKit/Source/core/inspector/InjectedScript.h
index 05cfcf320fb..6523846fbe4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScript.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScript.h
@@ -31,12 +31,13 @@
#ifndef InjectedScript_h
#define InjectedScript_h
-#include "InspectorTypeBuilder.h"
-#include "bindings/v8/ScriptObject.h"
+#include "bindings/v8/ScriptValue.h"
+#include "core/InspectorTypeBuilder.h"
#include "core/inspector/InjectedScriptBase.h"
#include "core/inspector/InjectedScriptManager.h"
#include "core/inspector/ScriptArguments.h"
#include "wtf/Forward.h"
+#include "wtf/Vector.h"
namespace WebCore {
@@ -44,38 +45,41 @@ class InjectedScriptModule;
class Node;
class SerializedScriptValue;
-
-class InjectedScript : public InjectedScriptBase {
+class InjectedScript FINAL : public InjectedScriptBase {
public:
InjectedScript();
- ~InjectedScript() { }
+ virtual ~InjectedScript() { }
- void evaluate(ErrorString*,
- const String& expression,
- const String& objectGroup,
- bool includeCommandLineAPI,
- bool returnByValue,
- bool generatePreview,
- RefPtr<TypeBuilder::Runtime::RemoteObject>* result,
- TypeBuilder::OptOutput<bool>* wasThrown);
- void callFunctionOn(ErrorString*,
- const String& objectId,
- const String& expression,
- const String& arguments,
- bool returnByValue,
- bool generatePreview,
- RefPtr<TypeBuilder::Runtime::RemoteObject>* result,
- TypeBuilder::OptOutput<bool>* wasThrown);
- void evaluateOnCallFrame(ErrorString*,
- const ScriptValue& callFrames,
- const String& callFrameId,
- const String& expression,
- const String& objectGroup,
- bool includeCommandLineAPI,
- bool returnByValue,
- bool generatePreview,
- RefPtr<TypeBuilder::Runtime::RemoteObject>* result,
- TypeBuilder::OptOutput<bool>* wasThrown);
+ void evaluate(
+ ErrorString*,
+ const String& expression,
+ const String& objectGroup,
+ bool includeCommandLineAPI,
+ bool returnByValue,
+ bool generatePreview,
+ RefPtr<TypeBuilder::Runtime::RemoteObject>* result,
+ TypeBuilder::OptOutput<bool>* wasThrown);
+ void callFunctionOn(
+ ErrorString*,
+ const String& objectId,
+ const String& expression,
+ const String& arguments,
+ bool returnByValue,
+ bool generatePreview,
+ RefPtr<TypeBuilder::Runtime::RemoteObject>* result,
+ TypeBuilder::OptOutput<bool>* wasThrown);
+ void evaluateOnCallFrame(
+ ErrorString*,
+ const ScriptValue& callFrames,
+ const Vector<ScriptValue>& asyncCallStacks,
+ const String& callFrameId,
+ const String& expression,
+ const String& objectGroup,
+ bool includeCommandLineAPI,
+ bool returnByValue,
+ bool generatePreview,
+ RefPtr<TypeBuilder::Runtime::RemoteObject>* result,
+ TypeBuilder::OptOutput<bool>* wasThrown);
void restartFrame(ErrorString*, const ScriptValue& callFrames, const String& callFrameId, RefPtr<JSONObject>* result);
void getStepInPositions(ErrorString*, const ScriptValue& callFrames, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& positions);
void setVariableValue(ErrorString*, const ScriptValue& callFrames, const String* callFrameIdOpt, const String* functionObjectIdOpt, int scopeNumber, const String& variableName, const String& newValueStr);
@@ -85,13 +89,12 @@ public:
Node* nodeForObjectId(const String& objectId);
void releaseObject(const String& objectId);
- PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > wrapCallFrames(const ScriptValue&);
+ PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > wrapCallFrames(const ScriptValue&, int asyncOrdinal);
PassRefPtr<TypeBuilder::Runtime::RemoteObject> wrapObject(const ScriptValue&, const String& groupName, bool generatePreview = false) const;
PassRefPtr<TypeBuilder::Runtime::RemoteObject> wrapTable(const ScriptValue& table, const ScriptValue& columns) const;
PassRefPtr<TypeBuilder::Runtime::RemoteObject> wrapNode(Node*, const String& groupName);
ScriptValue findObjectById(const String& objectId) const;
- ScriptValue findCallFrameById(ErrorString*, const ScriptValue& topCallFrame, const String& callFrameId);
void inspectNode(Node*);
void releaseObjectGroup(const String&);
@@ -99,7 +102,7 @@ public:
private:
friend class InjectedScriptModule;
friend InjectedScript InjectedScriptManager::injectedScriptFor(ScriptState*);
- InjectedScript(ScriptObject, InspectedStateAccessCheck);
+ InjectedScript(ScriptValue, InspectedStateAccessCheck);
ScriptValue nodeAsScriptValue(Node*);
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.cpp b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.cpp
index 574ce40ec6e..af20da9aa9b 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.cpp
@@ -34,8 +34,8 @@
#include "core/inspector/InjectedScriptBase.h"
#include "bindings/v8/ScriptFunctionCall.h"
-#include "bindings/v8/ScriptState.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "platform/JSONValues.h"
#include "wtf/text/WTFString.h"
@@ -49,14 +49,14 @@ InjectedScriptBase::InjectedScriptBase(const String& name)
{
}
-InjectedScriptBase::InjectedScriptBase(const String& name, ScriptObject injectedScriptObject, InspectedStateAccessCheck accessCheck)
+InjectedScriptBase::InjectedScriptBase(const String& name, ScriptValue injectedScriptObject, InspectedStateAccessCheck accessCheck)
: m_name(name)
, m_injectedScriptObject(injectedScriptObject)
, m_inspectedStateAccessCheck(accessCheck)
{
}
-void InjectedScriptBase::initialize(ScriptObject injectedScriptObject, InspectedStateAccessCheck accessCheck)
+void InjectedScriptBase::initialize(ScriptValue injectedScriptObject, InspectedStateAccessCheck accessCheck)
{
m_injectedScriptObject = injectedScriptObject;
m_inspectedStateAccessCheck = accessCheck;
@@ -64,18 +64,23 @@ void InjectedScriptBase::initialize(ScriptObject injectedScriptObject, Inspected
bool InjectedScriptBase::canAccessInspectedWindow() const
{
+ ASSERT(!isEmpty());
return m_inspectedStateAccessCheck(m_injectedScriptObject.scriptState());
}
-const ScriptObject& InjectedScriptBase::injectedScriptObject() const
+const ScriptValue& InjectedScriptBase::injectedScriptObject() const
{
return m_injectedScriptObject;
}
ScriptValue InjectedScriptBase::callFunctionWithEvalEnabled(ScriptFunctionCall& function, bool& hadException) const
{
+ ASSERT(!isEmpty());
ExecutionContext* executionContext = m_injectedScriptObject.scriptState()->executionContext();
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willCallFunction(executionContext, name(), 1);
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FunctionCall", "data", InspectorFunctionCallEvent::data(executionContext, 0, name(), 1));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willCallFunction(executionContext, 0, name(), 1);
ScriptState* scriptState = m_injectedScriptObject.scriptState();
bool evalIsDisabled = false;
@@ -92,12 +97,13 @@ ScriptValue InjectedScriptBase::callFunctionWithEvalEnabled(ScriptFunctionCall&
scriptState->setEvalEnabled(false);
InspectorInstrumentation::didCallFunction(cookie);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
return resultValue;
}
void InjectedScriptBase::makeCall(ScriptFunctionCall& function, RefPtr<JSONValue>* result)
{
- if (hasNoValue() || !canAccessInspectedWindow()) {
+ if (isEmpty() || !canAccessInspectedWindow()) {
*result = JSONValue::null();
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.h b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.h
index 194d022a90c..22fe94647b0 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptBase.h
@@ -31,8 +31,9 @@
#ifndef InjectedScriptBase_h
#define InjectedScriptBase_h
-#include "InspectorTypeBuilder.h"
-#include "bindings/v8/ScriptObject.h"
+#include "bindings/v8/ScriptState.h"
+#include "bindings/v8/ScriptValue.h"
+#include "core/InspectorTypeBuilder.h"
#include "wtf/Forward.h"
namespace WebCore {
@@ -48,24 +49,28 @@ public:
virtual ~InjectedScriptBase() { }
const String& name() const { return m_name; }
- bool hasNoValue() const { return m_injectedScriptObject.hasNoValue(); }
- ScriptState* scriptState() const { return m_injectedScriptObject.scriptState(); }
+ bool isEmpty() const { return m_injectedScriptObject.isEmpty(); }
+ ScriptState* scriptState() const
+ {
+ ASSERT(!isEmpty());
+ return m_injectedScriptObject.scriptState();
+ }
protected:
typedef bool (*InspectedStateAccessCheck)(ScriptState*);
InjectedScriptBase(const String& name);
- InjectedScriptBase(const String& name, ScriptObject, InspectedStateAccessCheck);
+ InjectedScriptBase(const String& name, ScriptValue, InspectedStateAccessCheck);
- void initialize(ScriptObject, InspectedStateAccessCheck);
+ void initialize(ScriptValue, InspectedStateAccessCheck);
bool canAccessInspectedWindow() const;
- const ScriptObject& injectedScriptObject() const;
+ const ScriptValue& injectedScriptObject() const;
ScriptValue callFunctionWithEvalEnabled(ScriptFunctionCall&, bool& hadException) const;
void makeCall(ScriptFunctionCall&, RefPtr<JSONValue>* result);
void makeEvalCall(ErrorString*, ScriptFunctionCall&, RefPtr<TypeBuilder::Runtime::RemoteObject>* result, TypeBuilder::OptOutput<bool>* wasThrown);
private:
String m_name;
- ScriptObject m_injectedScriptObject;
+ ScriptValue m_injectedScriptObject;
InspectedStateAccessCheck m_inspectedStateAccessCheck;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.cpp b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.cpp
index 17710ccd74f..74546074c16 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "core/inspector/InjectedScriptCanvasModule.h"
-#include "InjectedScriptCanvasModuleSource.h"
#include "bindings/v8/ScriptFunctionCall.h"
-#include "bindings/v8/ScriptObject.h"
+#include "bindings/v8/ScriptValue.h"
+#include "core/InjectedScriptCanvasModuleSource.h"
using WebCore::TypeBuilder::Array;
using WebCore::TypeBuilder::Canvas::ResourceId;
@@ -61,27 +61,27 @@ String InjectedScriptCanvasModule::source() const
return String(reinterpret_cast<const char*>(InjectedScriptCanvasModuleSource_js), sizeof(InjectedScriptCanvasModuleSource_js));
}
-ScriptObject InjectedScriptCanvasModule::wrapCanvas2DContext(const ScriptObject& context)
+ScriptValue InjectedScriptCanvasModule::wrapCanvas2DContext(const ScriptValue& context)
{
return callWrapContextFunction("wrapCanvas2DContext", context);
}
-ScriptObject InjectedScriptCanvasModule::wrapWebGLContext(const ScriptObject& glContext)
+ScriptValue InjectedScriptCanvasModule::wrapWebGLContext(const ScriptValue& glContext)
{
return callWrapContextFunction("wrapWebGLContext", glContext);
}
-ScriptObject InjectedScriptCanvasModule::callWrapContextFunction(const String& functionName, const ScriptObject& context)
+ScriptValue InjectedScriptCanvasModule::callWrapContextFunction(const String& functionName, const ScriptValue& context)
{
ScriptFunctionCall function(injectedScriptObject(), functionName);
function.appendArgument(context);
bool hadException = false;
ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException);
- if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) {
+ if (hadException || resultValue.isEmpty() || !resultValue.isObject()) {
ASSERT_NOT_REACHED();
- return ScriptObject();
+ return ScriptValue();
}
- return ScriptObject(context.scriptState(), resultValue);
+ return resultValue;
}
void InjectedScriptCanvasModule::markFrameEnd()
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.h b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.h
index 9a675eb6601..e4f6709725f 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModule.h
@@ -38,19 +38,19 @@
namespace WebCore {
class InjectedScriptManager;
-class ScriptObject;
+class ScriptValue;
-class InjectedScriptCanvasModule : public InjectedScriptModule {
+class InjectedScriptCanvasModule FINAL : public InjectedScriptModule {
public:
InjectedScriptCanvasModule();
- virtual String source() const;
+ virtual String source() const OVERRIDE;
static InjectedScriptCanvasModule moduleForState(InjectedScriptManager*, ScriptState*);
- ScriptObject wrapCanvas2DContext(const ScriptObject&);
- ScriptObject wrapWebGLContext(const ScriptObject&);
+ ScriptValue wrapCanvas2DContext(const ScriptValue&);
+ ScriptValue wrapWebGLContext(const ScriptValue&);
void markFrameEnd();
void captureFrame(ErrorString*, TypeBuilder::Canvas::TraceLogId*);
@@ -63,7 +63,7 @@ public:
void evaluateTraceLogCallArgument(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, int, int, const String&, RefPtr<TypeBuilder::Runtime::RemoteObject>*, RefPtr<TypeBuilder::Canvas::ResourceState>*);
private:
- ScriptObject callWrapContextFunction(const String&, const ScriptObject&);
+ ScriptValue callWrapContextFunction(const String&, const ScriptValue&);
void callStartCapturingFunction(const String&, ErrorString*, String*);
void callVoidFunctionWithTraceLogIdArgument(const String&, ErrorString*, const String&);
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js
index c82ab2352ec..848ddcadcb8 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptCanvasModuleSource.js
@@ -29,6 +29,12 @@
*/
/**
+ * FIXME: ES5 strict mode check is suppressed due to multiple uses of arguments.callee.
+ * @fileoverview
+ * @suppress {es5Strict}
+ */
+
+/**
* @param {InjectedScriptHostClass} InjectedScriptHost
* @param {Window} inspectedWindow
* @param {number} injectedScriptId
@@ -40,7 +46,7 @@ var TypeUtils = {
/**
* http://www.khronos.org/registry/typedarray/specs/latest/#7
* @const
- * @type {!Array.<function(new:ArrayBufferView, ArrayBufferView)>}
+ * @type {!Array.<function(new:ArrayBufferView, (!ArrayBuffer|!ArrayBufferView), number=, number=)>}
*/
_typedArrayClasses: (function(typeNames) {
var result = [];
@@ -59,7 +65,7 @@ var TypeUtils = {
/**
* @param {*} array
- * @return {function(new:ArrayBufferView, ArrayBufferView)|null}
+ * @return {function(new:ArrayBufferView, (!ArrayBuffer|!ArrayBufferView), number=, number=)|null}
*/
typedArrayClass: function(array)
{
@@ -92,10 +98,10 @@ var TypeUtils = {
var typedArrayClass = TypeUtils.typedArrayClass(obj);
if (typedArrayClass)
- return new typedArrayClass(/** @type {ArrayBufferView} */ (obj));
+ return new typedArrayClass(/** @type {!ArrayBufferView} */ (obj));
if (obj instanceof HTMLImageElement) {
- var img = /** @type {HTMLImageElement} */ (obj);
+ var img = /** @type {!HTMLImageElement} */ (obj);
// Special case for Images with Blob URIs: cloneNode will fail if the Blob URI has already been revoked.
// FIXME: Maybe this is a bug in WebKit core?
if (/^blob:/.test(img.src))
@@ -131,24 +137,24 @@ var TypeUtils = {
},
/**
- * @param {HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} obj
+ * @param {!HTMLImageElement|!HTMLCanvasElement|!HTMLVideoElement} obj
* @param {number=} width
* @param {number=} height
- * @return {HTMLCanvasElement}
+ * @return {!HTMLCanvasElement}
*/
cloneIntoCanvas: function(obj, width, height)
{
- var canvas = /** @type {HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
+ var canvas = /** @type {!HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
canvas.width = width || +obj.width;
canvas.height = height || +obj.height;
- var context = /** @type {CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d")));
+ var context = /** @type {!CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d")));
context.drawImage(obj, 0, 0);
return canvas;
},
/**
- * @param {Object=} obj
- * @return {Object}
+ * @param {?Object=} obj
+ * @return {?Object}
*/
cloneObject: function(obj)
{
@@ -203,21 +209,21 @@ var TypeUtils = {
},
/**
- * @return {CanvasRenderingContext2D}
+ * @return {!CanvasRenderingContext2D}
*/
_dummyCanvas2dContext: function()
{
var context = TypeUtils._dummyCanvas2dContextInstance;
if (!context) {
- var canvas = /** @type {HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
- context = /** @type {CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d")));
+ var canvas = /** @type {!HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
+ context = /** @type {!CanvasRenderingContext2D} */ (Resource.wrappedObject(canvas.getContext("2d")));
TypeUtils._dummyCanvas2dContextInstance = context;
}
return context;
}
}
-/** @typedef {{name:string, valueIsEnum:(boolean|undefined), value:*, values:(!Array.<TypeUtils.InternalResourceStateDescriptor>|undefined), isArray:(boolean|undefined)}} */
+/** @typedef {{name:string, valueIsEnum:(boolean|undefined), value:*, values:(!Array.<!TypeUtils.InternalResourceStateDescriptor>|undefined), isArray:(boolean|undefined)}} */
TypeUtils.InternalResourceStateDescriptor;
/**
@@ -239,8 +245,8 @@ StackTrace.prototype = {
/**
* @param {number=} stackTraceLimit
- * @param {Function=} topMostFunctionToIgnore
- * @return {StackTrace}
+ * @param {?Function=} topMostFunctionToIgnore
+ * @return {?StackTrace}
*/
StackTrace.create = function(stackTraceLimit, topMostFunctionToIgnore)
{
@@ -254,21 +260,19 @@ StackTrace.create = function(stackTraceLimit, topMostFunctionToIgnore)
* @constructor
* @implements {StackTrace}
* @param {number=} stackTraceLimit
- * @param {Function=} topMostFunctionToIgnore
+ * @param {?Function=} topMostFunctionToIgnore
* @see http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
*/
function StackTraceV8(stackTraceLimit, topMostFunctionToIgnore)
{
- StackTrace.call(this);
-
var oldPrepareStackTrace = Error.prepareStackTrace;
var oldStackTraceLimit = Error.stackTraceLimit;
if (typeof stackTraceLimit === "number")
Error.stackTraceLimit = stackTraceLimit;
/**
- * @param {Object} error
- * @param {!Array.<CallSite>} structuredStackTrace
+ * @param {!Object} error
+ * @param {!Array.<!CallSite>} structuredStackTrace
* @return {!Array.<{sourceURL: string, lineNumber: number, columnNumber: number}>}
*/
Error.prepareStackTrace = function(error, structuredStackTrace)
@@ -299,9 +303,7 @@ StackTraceV8.prototype = {
callFrame: function(index)
{
return this._stackTrace[index];
- },
-
- __proto__: StackTrace.prototype
+ }
}
/**
@@ -362,11 +364,11 @@ Cache.prototype = {
/**
* @constructor
- * @param {Resource|Object} thisObject
+ * @param {?Resource|!Object} thisObject
* @param {string} functionName
- * @param {!Array|Arguments} args
- * @param {Resource|*=} result
- * @param {StackTrace=} stackTrace
+ * @param {!Array|!Arguments} args
+ * @param {!Resource|*=} result
+ * @param {?StackTrace=} stackTrace
*/
function Call(thisObject, functionName, args, result, stackTrace)
{
@@ -382,7 +384,7 @@ function Call(thisObject, functionName, args, result, stackTrace)
Call.prototype = {
/**
- * @return {Resource}
+ * @return {?Resource}
*/
resource: function()
{
@@ -422,7 +424,7 @@ Call.prototype = {
},
/**
- * @return {StackTrace}
+ * @return {?StackTrace}
*/
stackTrace: function()
{
@@ -430,7 +432,7 @@ Call.prototype = {
},
/**
- * @param {StackTrace} stackTrace
+ * @param {?StackTrace} stackTrace
*/
setStackTrace: function(stackTrace)
{
@@ -447,25 +449,26 @@ Call.prototype = {
/**
* @param {string} name
- * @param {Object} attachment
+ * @param {?Object} attachment
*/
setAttachment: function(name, attachment)
{
if (attachment) {
- /** @type {Object.<string, Object>} */
+ /** @type {?Object.<string, !Object>|undefined} */
this._attachments = this._attachments || Object.create(null);
this._attachments[name] = attachment;
- } else if (this._attachments)
+ } else if (this._attachments) {
delete this._attachments[name];
+ }
},
/**
* @param {string} name
- * @return {Object}
+ * @return {?Object}
*/
attachment: function(name)
{
- return this._attachments && this._attachments[name];
+ return this._attachments ? (this._attachments[name] || null) : null;
},
freeze: function()
@@ -481,13 +484,13 @@ Call.prototype = {
},
/**
- * @param {!Cache.<ReplayableResource>} cache
+ * @param {!Cache.<!ReplayableResource>} cache
* @return {!ReplayableCall}
*/
toReplayable: function(cache)
{
this.freeze();
- var thisObject = /** @type {ReplayableResource} */ (Resource.toReplayable(this._thisObject, cache));
+ var thisObject = /** @type {!ReplayableResource} */ (Resource.toReplayable(this._thisObject, cache));
var result = Resource.toReplayable(this._result, cache);
var args = this._args.map(function(obj) {
return Resource.toReplayable(obj, cache);
@@ -498,7 +501,7 @@ Call.prototype = {
/**
* @param {!ReplayableCall} replayableCall
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
* @return {!Call}
*/
replay: function(replayableCall, cache)
@@ -537,20 +540,19 @@ Call.prototype = {
this._stackTrace = replayableCall.stackTrace();
this._freezed = true;
var attachments = replayableCall.attachments();
- if (attachments)
- this._attachments = TypeUtils.cloneObject(attachments);
+ this._attachments = attachments ? TypeUtils.cloneObject(attachments) : null;
return this;
}
}
/**
* @constructor
- * @param {ReplayableResource} thisObject
+ * @param {!ReplayableResource} thisObject
* @param {string} functionName
- * @param {!Array.<ReplayableResource|*>} args
- * @param {ReplayableResource|*} result
- * @param {StackTrace} stackTrace
- * @param {Object.<string, Object>} attachments
+ * @param {!Array.<!ReplayableResource|*>} args
+ * @param {!ReplayableResource|*} result
+ * @param {?StackTrace} stackTrace
+ * @param {?Object.<string, !Object>} attachments
*/
function ReplayableCall(thisObject, functionName, args, result, stackTrace, attachments)
{
@@ -565,7 +567,7 @@ function ReplayableCall(thisObject, functionName, args, result, stackTrace, atta
ReplayableCall.prototype = {
/**
- * @return {ReplayableResource}
+ * @return {!ReplayableResource}
*/
replayableResource: function()
{
@@ -607,7 +609,7 @@ ReplayableCall.prototype = {
},
/**
- * @return {!Array.<ReplayableResource|*>}
+ * @return {!Array.<!ReplayableResource|*>}
*/
args: function()
{
@@ -615,7 +617,7 @@ ReplayableCall.prototype = {
},
/**
- * @return {ReplayableResource|*}
+ * @return {!ReplayableResource|*}
*/
result: function()
{
@@ -623,7 +625,7 @@ ReplayableCall.prototype = {
},
/**
- * @return {StackTrace}
+ * @return {?StackTrace}
*/
stackTrace: function()
{
@@ -631,7 +633,7 @@ ReplayableCall.prototype = {
},
/**
- * @return {Object.<string, Object>}
+ * @return {?Object.<string, !Object>}
*/
attachments: function()
{
@@ -640,7 +642,7 @@ ReplayableCall.prototype = {
/**
* @param {string} name
- * @return {Object}
+ * @return {!Object}
*/
attachment: function(name)
{
@@ -648,7 +650,7 @@ ReplayableCall.prototype = {
},
/**
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
* @return {!Call}
*/
replay: function(cache)
@@ -671,9 +673,9 @@ function Resource(wrappedObject, name)
this._name = name || "Resource";
/** @type {number} */
this._kindId = Resource._uniqueKindIds[this._name] = (Resource._uniqueKindIds[this._name] || 0) + 1;
- /** @type {ResourceTrackingManager} */
+ /** @type {?ResourceTrackingManager} */
this._resourceManager = null;
- /** @type {!Array.<Call>} */
+ /** @type {!Array.<!Call>} */
this._calls = [];
/**
* This is to prevent GC from collecting associated resources.
@@ -681,7 +683,7 @@ function Resource(wrappedObject, name)
* may return a recently created instance that is no longer bound to a
* Resource object (thus, no history to replay it later).
*
- * @type {!Object.<string, Resource>}
+ * @type {!Object.<string, !Resource>}
*/
this._boundResources = Object.create(null);
this.setWrappedObject(wrappedObject);
@@ -699,7 +701,7 @@ Resource._uniqueKindIds = {};
/**
* @param {*} obj
- * @return {Resource}
+ * @return {?Resource}
*/
Resource.forObject = function(obj)
{
@@ -713,7 +715,7 @@ Resource.forObject = function(obj)
}
/**
- * @param {Resource|*} obj
+ * @param {!Resource|*} obj
* @return {*}
*/
Resource.wrappedObject = function(obj)
@@ -723,9 +725,9 @@ Resource.wrappedObject = function(obj)
}
/**
- * @param {Resource|*} obj
- * @param {!Cache.<ReplayableResource>} cache
- * @return {ReplayableResource|*}
+ * @param {!Resource|*} obj
+ * @param {!Cache.<!ReplayableResource>} cache
+ * @return {!ReplayableResource|*}
*/
Resource.toReplayable = function(obj, cache)
{
@@ -759,7 +761,7 @@ Resource.prototype = {
},
/**
- * @return {Object}
+ * @return {!Object}
*/
wrappedObject: function()
{
@@ -778,7 +780,7 @@ Resource.prototype = {
},
/**
- * @return {Object}
+ * @return {!Object}
*/
proxyObject: function()
{
@@ -788,7 +790,7 @@ Resource.prototype = {
},
/**
- * @return {ResourceTrackingManager}
+ * @return {?ResourceTrackingManager}
*/
manager: function()
{
@@ -796,7 +798,7 @@ Resource.prototype = {
},
/**
- * @param {ResourceTrackingManager} value
+ * @param {!ResourceTrackingManager} value
*/
setManager: function(value)
{
@@ -812,12 +814,12 @@ Resource.prototype = {
},
/**
- * @return {ContextResource}
+ * @return {?ContextResource}
*/
contextResource: function()
{
if (this instanceof ContextResource)
- return /** @type {ContextResource} */ (this);
+ return /** @type {!ContextResource} */ (this);
if (this._calculatingContextResource)
return null;
@@ -835,7 +837,7 @@ Resource.prototype = {
},
/**
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
@@ -861,7 +863,7 @@ Resource.prototype = {
},
/**
- * @param {!Cache.<ReplayableResource>} cache
+ * @param {!Cache.<!ReplayableResource>} cache
* @return {!ReplayableResource}
*/
toReplayable: function(cache)
@@ -888,7 +890,7 @@ Resource.prototype = {
/**
* @param {!Object} data
- * @param {!Cache.<ReplayableResource>} cache
+ * @param {!Cache.<!ReplayableResource>} cache
*/
_populateReplayableData: function(data, cache)
{
@@ -897,7 +899,7 @@ Resource.prototype = {
/**
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
* @return {!Resource}
*/
replay: function(data, cache)
@@ -920,7 +922,7 @@ Resource.prototype = {
/**
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
*/
_doReplayCalls: function(data, cache)
{
@@ -972,7 +974,7 @@ Resource.prototype = {
},
/**
- * @return {Object}
+ * @return {?Object}
*/
_wrapObject: function()
{
@@ -987,6 +989,7 @@ Resource.prototype = {
/**
* @param {string} property
+ * @this {Resource}
*/
function processProperty(property)
{
@@ -1102,7 +1105,7 @@ Resource.prototype = {
},
/**
- * @return {!Object.<string, Function>}
+ * @return {!Object.<string, !Function>}
*/
_customWrapFunctions: function()
{
@@ -1112,10 +1115,10 @@ Resource.prototype = {
/**
* @constructor
- * @param {Object} originalObject
- * @param {Function} originalFunction
+ * @param {!Object} originalObject
+ * @param {!Function} originalFunction
* @param {string} functionName
- * @param {!Array|Arguments} args
+ * @param {!Array|!Arguments} args
*/
Resource.WrapFunction = function(originalObject, originalFunction, functionName, args)
{
@@ -1168,10 +1171,10 @@ Resource.WrapFunction.prototype = {
*/
Resource.WrapFunction.resourceFactoryMethod = function(resourceConstructor, resourceName)
{
- /** @this Resource.WrapFunction */
+ /** @this {Resource.WrapFunction} */
return function()
{
- var wrappedObject = /** @type {Object} */ (this.result());
+ var wrappedObject = /** @type {?Object} */ (this.result());
if (!wrappedObject)
return;
var resource = new resourceConstructor(wrappedObject, resourceName);
@@ -1228,7 +1231,7 @@ ReplayableResource.prototype = {
},
/**
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
* @return {!Resource}
*/
replay: function(cache)
@@ -1241,8 +1244,8 @@ ReplayableResource.prototype = {
}
/**
- * @param {ReplayableResource|*} obj
- * @param {!Cache.<Resource>} cache
+ * @param {!ReplayableResource|*} obj
+ * @param {!Cache.<!Resource>} cache
* @return {*}
*/
ReplayableResource.replay = function(obj, cache)
@@ -1279,7 +1282,7 @@ function LogEverythingResource(wrappedObject, name)
LogEverythingResource.prototype = {
/**
* @override
- * @return {!Object.<string, Function>}
+ * @return {!Object.<string, !Function>}
*/
_customWrapFunctions: function()
{
@@ -1287,7 +1290,7 @@ LogEverythingResource.prototype = {
var wrappedObject = this.wrappedObject();
if (wrappedObject) {
for (var property in wrappedObject) {
- /** @this Resource.WrapFunction */
+ /** @this {Resource.WrapFunction} */
wrapFunctions[property] = function()
{
this._resource.pushCall(this.call());
@@ -1321,7 +1324,7 @@ WebGLBoundResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<ReplayableResource>} cache
+ * @param {!Cache.<!ReplayableResource>} cache
*/
_populateReplayableData: function(data, cache)
{
@@ -1335,13 +1338,13 @@ WebGLBoundResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
*/
_doReplayCalls: function(data, cache)
{
var gl = this._replayContextResource(data, cache).wrappedObject();
- /** @type {!Object.<string, Array.<string>>} */
+ /** @type {!Object.<string, !Array.<string>>} */
var bindingsData = {
TEXTURE_2D: ["bindTexture", "TEXTURE_BINDING_2D"],
TEXTURE_CUBE_MAP: ["bindTexture", "TEXTURE_BINDING_CUBE_MAP"],
@@ -1371,12 +1374,12 @@ WebGLBoundResource.prototype = {
/**
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
- * @return {WebGLRenderingContextResource}
+ * @param {!Cache.<!Resource>} cache
+ * @return {?WebGLRenderingContextResource}
*/
_replayContextResource: function(data, cache)
{
- var calls = /** @type {!Array.<ReplayableCall>} */ (data.calls);
+ var calls = /** @type {!Array.<!ReplayableCall>} */ (data.calls);
for (var i = 0, n = calls.length; i < n; ++i) {
var resource = ReplayableResource.replay(calls[i].replayableResource(), cache);
var contextResource = WebGLRenderingContextResource.forObject(resource);
@@ -1415,7 +1418,7 @@ function WebGLTextureResource(wrappedObject, name)
WebGLTextureResource.prototype = {
/**
* @override (overrides @return type)
- * @return {WebGLTexture}
+ * @return {!WebGLTexture}
*/
wrappedObject: function()
{
@@ -1424,7 +1427,7 @@ WebGLTextureResource.prototype = {
/**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
@@ -1455,7 +1458,7 @@ WebGLTextureResource.prototype = {
}
result.push({ name: "target", value: target, valueIsEnum: true });
- var oldTexture = /** @type {WebGLTexture} */ (gl.getParameter(bindingParameter));
+ var oldTexture = /** @type {!WebGLTexture} */ (gl.getParameter(bindingParameter));
if (oldTexture !== texture)
gl.bindTexture(target, texture);
@@ -1476,7 +1479,7 @@ WebGLTextureResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
*/
_doReplayCalls: function(data, cache)
{
@@ -1539,7 +1542,7 @@ WebGLTextureResource.prototype = {
{
var glResource = WebGLRenderingContextResource.forObject(call.resource());
var gl = glResource.wrappedObject();
- var framebufferResource = /** @type {WebGLFramebufferResource} */ (glResource.currentBinding(gl.FRAMEBUFFER));
+ var framebufferResource = /** @type {!WebGLFramebufferResource} */ (glResource.currentBinding(gl.FRAMEBUFFER));
if (framebufferResource)
this.pushCall(new Call(glResource, "bindFramebuffer", [gl.FRAMEBUFFER, framebufferResource]));
else {
@@ -1566,7 +1569,7 @@ function WebGLProgramResource(wrappedObject, name)
WebGLProgramResource.prototype = {
/**
* @override (overrides @return type)
- * @return {WebGLProgram}
+ * @return {!WebGLProgram}
*/
wrappedObject: function()
{
@@ -1575,13 +1578,13 @@ WebGLProgramResource.prototype = {
/**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
/**
* @param {!Object} obj
- * @param {!Array.<TypeUtils.InternalResourceStateDescriptor>} output
+ * @param {!Array.<!TypeUtils.InternalResourceStateDescriptor>} output
*/
function convertToStateDescriptors(obj, output)
{
@@ -1675,7 +1678,7 @@ WebGLProgramResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<ReplayableResource>} cache
+ * @param {!Cache.<!ReplayableResource>} cache
*/
_populateReplayableData: function(data, cache)
{
@@ -1688,7 +1691,7 @@ WebGLProgramResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
*/
_doReplayCalls: function(data, cache)
{
@@ -1696,7 +1699,7 @@ WebGLProgramResource.prototype = {
var gl = WebGLRenderingContextResource.forObject(this).wrappedObject();
var program = this.wrappedObject();
- var originalProgram = /** @type {WebGLProgram} */ (gl.getParameter(gl.CURRENT_PROGRAM));
+ var originalProgram = /** @type {!WebGLProgram} */ (gl.getParameter(gl.CURRENT_PROGRAM));
var currentProgram = originalProgram;
data.uniforms.forEach(function(uniform) {
@@ -1719,7 +1722,7 @@ WebGLProgramResource.prototype = {
},
/**
- * @param {WebGLRenderingContext} gl
+ * @param {!WebGLRenderingContext} gl
* @param {number} type
* @return {string}
*/
@@ -1779,7 +1782,7 @@ function WebGLShaderResource(wrappedObject, name)
WebGLShaderResource.prototype = {
/**
* @override (overrides @return type)
- * @return {WebGLShader}
+ * @return {!WebGLShader}
*/
wrappedObject: function()
{
@@ -1800,7 +1803,7 @@ WebGLShaderResource.prototype = {
/**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
@@ -1856,7 +1859,7 @@ function WebGLBufferResource(wrappedObject, name)
WebGLBufferResource.prototype = {
/**
* @override (overrides @return type)
- * @return {WebGLBuffer}
+ * @return {!WebGLBuffer}
*/
wrappedObject: function()
{
@@ -1864,8 +1867,75 @@ WebGLBufferResource.prototype = {
},
/**
+ * @return {?ArrayBufferView}
+ */
+ cachedBufferData: function()
+ {
+ /**
+ * Creates a view to a given buffer, does NOT copy the buffer.
+ * @param {!ArrayBuffer|!ArrayBufferView} buffer
+ * @return {!Uint8Array}
+ */
+ function createUint8ArrayBufferView(buffer)
+ {
+ return buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
+ }
+
+ if (!this._cachedBufferData) {
+ for (var i = this._calls.length - 1; i >= 0; --i) {
+ var call = this._calls[i];
+ if (call.functionName() === "bufferData") {
+ var sizeOrData = /** @type {number|!ArrayBuffer|!ArrayBufferView} */ (call.args()[1]);
+ if (typeof sizeOrData === "number")
+ this._cachedBufferData = new ArrayBuffer(sizeOrData);
+ else
+ this._cachedBufferData = sizeOrData;
+ this._lastBufferSubDataIndex = i + 1;
+ break;
+ }
+ }
+ if (!this._cachedBufferData)
+ return null;
+ }
+
+ // Apply any "bufferSubData" calls that have not been applied yet.
+ var bufferDataView;
+ while (this._lastBufferSubDataIndex < this._calls.length) {
+ var call = this._calls[this._lastBufferSubDataIndex++];
+ if (call.functionName() !== "bufferSubData")
+ continue;
+ var offset = /** @type {number} */ (call.args()[1]);
+ var data = /** @type {!ArrayBuffer|!ArrayBufferView} */ (call.args()[2]);
+ var view = createUint8ArrayBufferView(data);
+ if (!bufferDataView)
+ bufferDataView = createUint8ArrayBufferView(this._cachedBufferData);
+ bufferDataView.set(view, offset);
+
+ var isFullReplacement = (offset === 0 && bufferDataView.length === view.length);
+ if (this._cachedBufferData instanceof ArrayBuffer) {
+ // The buffer data has no type yet. Try to guess from the "bufferSubData" call.
+ var typedArrayClass = TypeUtils.typedArrayClass(data);
+ if (typedArrayClass)
+ this._cachedBufferData = new typedArrayClass(this._cachedBufferData); // Does not copy the buffer.
+ } else if (isFullReplacement) {
+ var typedArrayClass = TypeUtils.typedArrayClass(data);
+ if (typedArrayClass) {
+ var typedArrayData = /** @type {!ArrayBufferView} */ (data);
+ this._cachedBufferData = new typedArrayClass(this._cachedBufferData.buffer, this._cachedBufferData.byteOffset, typedArrayData.length); // Does not copy the buffer.
+ }
+ }
+ }
+
+ if (this._cachedBufferData instanceof ArrayBuffer) {
+ // If we failed to guess the data type yet, use Uint8Array.
+ return new Uint8Array(this._cachedBufferData);
+ }
+ return this._cachedBufferData;
+ },
+
+ /**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
@@ -1896,7 +1966,7 @@ WebGLBufferResource.prototype = {
}
result.push({ name: "target", value: target, valueIsEnum: true });
- var oldBuffer = /** @type {WebGLBuffer} */ (gl.getParameter(bindingParameter));
+ var oldBuffer = /** @type {!WebGLBuffer} */ (gl.getParameter(bindingParameter));
if (oldBuffer !== buffer)
gl.bindBuffer(target, buffer);
@@ -1905,16 +1975,34 @@ WebGLBufferResource.prototype = {
if (oldBuffer !== buffer)
gl.bindBuffer(target, oldBuffer);
+
+ try {
+ var data = this.cachedBufferData();
+ if (data)
+ result.push({ name: "bufferData", value: data });
+ } catch (e) {
+ console.error("Exception while restoring bufferData", e);
+ }
+
return result;
},
/**
- * @override
* @param {!Call} call
*/
- pushCall: function(call)
+ pushCall_bufferData: function(call)
{
// FIXME: remove any older calls that no longer contribute to the resource state.
+ delete this._cachedBufferData;
+ delete this._lastBufferSubDataIndex;
+ WebGLBoundResource.prototype.pushCall.call(this, call);
+ },
+
+ /**
+ * @param {!Call} call
+ */
+ pushCall_bufferSubData: function(call)
+ {
// FIXME: Optimize memory for bufferSubData.
WebGLBoundResource.prototype.pushCall.call(this, call);
},
@@ -1936,7 +2024,7 @@ function WebGLFramebufferResource(wrappedObject, name)
WebGLFramebufferResource.prototype = {
/**
* @override (overrides @return type)
- * @return {WebGLFramebuffer}
+ * @return {!WebGLFramebuffer}
*/
wrappedObject: function()
{
@@ -1945,7 +2033,7 @@ WebGLFramebufferResource.prototype = {
/**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
@@ -1955,7 +2043,7 @@ WebGLFramebufferResource.prototype = {
return result;
var gl = WebGLRenderingContextResource.forObject(this).wrappedObject();
- var oldFramebuffer = /** @type {WebGLFramebuffer} */ (gl.getParameter(gl.FRAMEBUFFER_BINDING));
+ var oldFramebuffer = /** @type {!WebGLFramebuffer} */ (gl.getParameter(gl.FRAMEBUFFER_BINDING));
if (oldFramebuffer !== framebuffer)
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
@@ -2005,7 +2093,7 @@ function WebGLRenderbufferResource(wrappedObject, name)
WebGLRenderbufferResource.prototype = {
/**
* @override (overrides @return type)
- * @return {WebGLRenderbuffer}
+ * @return {!WebGLRenderbuffer}
*/
wrappedObject: function()
{
@@ -2014,7 +2102,7 @@ WebGLRenderbufferResource.prototype = {
/**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
@@ -2025,7 +2113,7 @@ WebGLRenderbufferResource.prototype = {
var glResource = WebGLRenderingContextResource.forObject(this);
var gl = glResource.wrappedObject();
- var oldRenderbuffer = /** @type {WebGLRenderbuffer} */ (gl.getParameter(gl.RENDERBUFFER_BINDING));
+ var oldRenderbuffer = /** @type {!WebGLRenderbuffer} */ (gl.getParameter(gl.RENDERBUFFER_BINDING));
if (oldRenderbuffer !== renderbuffer)
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
@@ -2066,7 +2154,7 @@ function WebGLUniformLocationResource(wrappedObject, name)
WebGLUniformLocationResource.prototype = {
/**
* @override (overrides @return type)
- * @return {WebGLUniformLocation}
+ * @return {!WebGLUniformLocation}
*/
wrappedObject: function()
{
@@ -2074,13 +2162,13 @@ WebGLUniformLocationResource.prototype = {
},
/**
- * @return {WebGLProgramResource}
+ * @return {?WebGLProgramResource}
*/
program: function()
{
var call = this._calls[0];
if (call && call.functionName() === "getUniformLocation")
- return /** @type {WebGLProgramResource} */ (Resource.forObject(call.args()[0]));
+ return /** @type {!WebGLProgramResource} */ (Resource.forObject(call.args()[0]));
console.error("ASSERT_NOT_REACHED: Failed to restore WebGLUniformLocation from the log.", call);
return null;
},
@@ -2099,7 +2187,7 @@ WebGLUniformLocationResource.prototype = {
/**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
@@ -2145,7 +2233,7 @@ WebGLUniformLocationResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<ReplayableResource>} cache
+ * @param {!Cache.<!ReplayableResource>} cache
*/
_populateReplayableData: function(data, cache)
{
@@ -2156,7 +2244,7 @@ WebGLUniformLocationResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
*/
_doReplayCalls: function(data, cache)
{
@@ -2176,7 +2264,7 @@ WebGLUniformLocationResource.prototype = {
function WebGLRenderingContextResource(glContext)
{
ContextResource.call(this, glContext, "WebGLRenderingContext");
- /** @type {Object.<number, boolean>} */
+ /** @type {?Object.<number, boolean>} */
this._customErrors = null;
/** @type {!Object.<string, string>} */
this._extensions = {};
@@ -2327,7 +2415,7 @@ WebGLRenderingContextResource.DrawingMethods = TypeUtils.createPrefixedPropertyN
/**
* @param {*} obj
- * @return {WebGLRenderingContextResource}
+ * @return {?WebGLRenderingContextResource}
*/
WebGLRenderingContextResource.forObject = function(obj)
{
@@ -2341,7 +2429,7 @@ WebGLRenderingContextResource.forObject = function(obj)
WebGLRenderingContextResource.prototype = {
/**
* @override (overrides @return type)
- * @return {WebGLRenderingContext}
+ * @return {!WebGLRenderingContext}
*/
wrappedObject: function()
{
@@ -2358,7 +2446,7 @@ WebGLRenderingContextResource.prototype = {
},
/**
- * @return {Array.<number>}
+ * @return {!Array.<number>}
*/
getAllErrors: function()
{
@@ -2384,7 +2472,7 @@ WebGLRenderingContextResource.prototype = {
},
/**
- * @param {Array.<number>} errors
+ * @param {!Array.<number>} errors
*/
restoreErrors: function(errors)
{
@@ -2432,7 +2520,7 @@ WebGLRenderingContextResource.prototype = {
/**
* @param {string} name
- * @param {Object} obj
+ * @param {?Object} obj
*/
registerWebGLExtension: function(name, obj)
{
@@ -2463,7 +2551,7 @@ WebGLRenderingContextResource.prototype = {
* @param {function(this:WebGLRenderingContext, T, number):*} func
* @param {T} targetOrWebGLObject
* @param {!Array.<string>} pnames
- * @param {!Array.<TypeUtils.InternalResourceStateDescriptor>} output
+ * @param {!Array.<!TypeUtils.InternalResourceStateDescriptor>} output
* @template T
*/
queryStateValues: function(func, targetOrWebGLObject, pnames, output)
@@ -2481,13 +2569,13 @@ WebGLRenderingContextResource.prototype = {
/**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
/**
* @param {!Object} obj
- * @param {!Array.<TypeUtils.InternalResourceStateDescriptor>} output
+ * @param {!Array.<!TypeUtils.InternalResourceStateDescriptor>} output
*/
function convertToStateDescriptors(obj, output)
{
@@ -2544,14 +2632,14 @@ WebGLRenderingContextResource.prototype = {
},
/**
- * @param {?Cache.<ReplayableResource>} cache
+ * @param {?Cache.<!ReplayableResource>} cache
* @return {!Object.<string, *>}
*/
_internalCurrentState: function(cache)
{
/**
- * @param {Resource|*} obj
- * @return {Resource|ReplayableResource|*}
+ * @param {!Resource|*} obj
+ * @return {!Resource|!ReplayableResource|*}
*/
function maybeToReplayable(obj)
{
@@ -2618,7 +2706,7 @@ WebGLRenderingContextResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<ReplayableResource>} cache
+ * @param {!Cache.<!ReplayableResource>} cache
*/
_populateReplayableData: function(data, cache)
{
@@ -2633,7 +2721,7 @@ WebGLRenderingContextResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
*/
_doReplayCalls: function(data, cache)
{
@@ -2660,8 +2748,8 @@ WebGLRenderingContextResource.prototype = {
gl.getExtension(name);
var glState = data.glState;
- gl.bindFramebuffer(gl.FRAMEBUFFER, /** @type {WebGLFramebuffer} */ (ReplayableResource.replay(glState.FRAMEBUFFER_BINDING, cache)));
- gl.bindRenderbuffer(gl.RENDERBUFFER, /** @type {WebGLRenderbuffer} */ (ReplayableResource.replay(glState.RENDERBUFFER_BINDING, cache)));
+ gl.bindFramebuffer(gl.FRAMEBUFFER, /** @type {!WebGLFramebuffer} */ (ReplayableResource.replay(glState.FRAMEBUFFER_BINDING, cache)));
+ gl.bindRenderbuffer(gl.RENDERBUFFER, /** @type {!WebGLRenderbuffer} */ (ReplayableResource.replay(glState.RENDERBUFFER_BINDING, cache)));
// Enable or disable server-side GL capabilities.
WebGLRenderingContextResource.GLCapabilities.forEach(function(parameter) {
@@ -2707,7 +2795,7 @@ WebGLRenderingContextResource.prototype = {
gl.scissor(glState.SCISSOR_BOX[0], glState.SCISSOR_BOX[1], glState.SCISSOR_BOX[2], glState.SCISSOR_BOX[3]);
gl.viewport(glState.VIEWPORT[0], glState.VIEWPORT[1], glState.VIEWPORT[2], glState.VIEWPORT[3]);
- gl.useProgram(/** @type {WebGLProgram} */ (ReplayableResource.replay(glState.CURRENT_PROGRAM, cache)));
+ gl.useProgram(/** @type {!WebGLProgram} */ (ReplayableResource.replay(glState.CURRENT_PROGRAM, cache)));
// VERTEX_ATTRIB_ARRAYS
var maxVertexAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
@@ -2719,22 +2807,22 @@ WebGLRenderingContextResource.prototype = {
gl.disableVertexAttribArray(i);
if (state.CURRENT_VERTEX_ATTRIB)
gl.vertexAttrib4fv(i, state.CURRENT_VERTEX_ATTRIB);
- var buffer = /** @type {WebGLBuffer} */ (ReplayableResource.replay(state.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, cache));
+ var buffer = /** @type {!WebGLBuffer} */ (ReplayableResource.replay(state.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, cache));
if (buffer) {
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.vertexAttribPointer(i, state.VERTEX_ATTRIB_ARRAY_SIZE, state.VERTEX_ATTRIB_ARRAY_TYPE, state.VERTEX_ATTRIB_ARRAY_NORMALIZED, state.VERTEX_ATTRIB_ARRAY_STRIDE, state.VERTEX_ATTRIB_ARRAY_POINTER);
}
}
- gl.bindBuffer(gl.ARRAY_BUFFER, /** @type {WebGLBuffer} */ (ReplayableResource.replay(glState.ARRAY_BUFFER_BINDING, cache)));
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, /** @type {WebGLBuffer} */ (ReplayableResource.replay(glState.ELEMENT_ARRAY_BUFFER_BINDING, cache)));
+ gl.bindBuffer(gl.ARRAY_BUFFER, /** @type {!WebGLBuffer} */ (ReplayableResource.replay(glState.ARRAY_BUFFER_BINDING, cache)));
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, /** @type {!WebGLBuffer} */ (ReplayableResource.replay(glState.ELEMENT_ARRAY_BUFFER_BINDING, cache)));
// TEXTURE_UNITS
var maxTextureImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
for (var i = 0; i < maxTextureImageUnits; ++i) {
gl.activeTexture(gl.TEXTURE0 + i);
var state = glState.TEXTURE_UNITS[i] || {};
- gl.bindTexture(gl.TEXTURE_2D, /** @type {WebGLTexture} */ (ReplayableResource.replay(state.TEXTURE_2D, cache)));
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, /** @type {WebGLTexture} */ (ReplayableResource.replay(state.TEXTURE_CUBE_MAP, cache)));
+ gl.bindTexture(gl.TEXTURE_2D, /** @type {!WebGLTexture} */ (ReplayableResource.replay(state.TEXTURE_2D, cache)));
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, /** @type {!WebGLTexture} */ (ReplayableResource.replay(state.TEXTURE_CUBE_MAP, cache)));
}
gl.activeTexture(glState.ACTIVE_TEXTURE);
@@ -2742,8 +2830,8 @@ WebGLRenderingContextResource.prototype = {
},
/**
- * @param {Object|number} target
- * @return {Resource}
+ * @param {!Object|number} target
+ * @return {?Resource}
*/
currentBinding: function(target)
{
@@ -2816,14 +2904,24 @@ WebGLRenderingContextResource.prototype = {
resource.pushBinding(args[0], functionName);
break;
case "getExtension":
- this.registerWebGLExtension(args[0], /** @type {Object} */ (call.result()));
+ this.registerWebGLExtension(args[0], /** @type {!Object} */ (call.result()));
+ break;
+ case "bufferData":
+ var resource = /** @type {!WebGLBufferResource} */ (this.currentBinding(args[0]));
+ if (resource)
+ resource.pushCall_bufferData(call);
+ break;
+ case "bufferSubData":
+ var resource = /** @type {!WebGLBufferResource} */ (this.currentBinding(args[0]));
+ if (resource)
+ resource.pushCall_bufferSubData(call);
break;
}
},
/**
* @override
- * @return {!Object.<string, Function>}
+ * @return {!Object.<string, !Function>}
*/
_customWrapFunctions: function()
{
@@ -2844,8 +2942,8 @@ WebGLRenderingContextResource.prototype = {
stateModifyingWrapFunction("detachShader");
stateModifyingWrapFunction("linkProgram");
stateModifyingWrapFunction("shaderSource");
- stateModifyingWrapFunction("bufferData");
- stateModifyingWrapFunction("bufferSubData");
+ stateModifyingWrapFunction("bufferData", WebGLBufferResource.prototype.pushCall_bufferData);
+ stateModifyingWrapFunction("bufferSubData", WebGLBufferResource.prototype.pushCall_bufferSubData);
stateModifyingWrapFunction("compressedTexImage2D");
stateModifyingWrapFunction("compressedTexSubImage2D");
stateModifyingWrapFunction("copyTexImage2D", WebGLTextureResource.prototype.pushCall_copyTexImage2D);
@@ -2857,10 +2955,10 @@ WebGLRenderingContextResource.prototype = {
stateModifyingWrapFunction("texParameteri", WebGLTextureResource.prototype.pushCall_texParameter);
stateModifyingWrapFunction("renderbufferStorage");
- /** @this Resource.WrapFunction */
+ /** @this {Resource.WrapFunction} */
wrapFunctions["getError"] = function()
{
- var gl = /** @type {WebGLRenderingContext} */ (this._originalObject);
+ var gl = /** @type {!WebGLRenderingContext} */ (this._originalObject);
var error = this.result();
if (error !== gl.NO_ERROR)
this._resource.clearError(error);
@@ -2873,7 +2971,7 @@ WebGLRenderingContextResource.prototype = {
/**
* @param {string} name
- * @this Resource.WrapFunction
+ * @this {Resource.WrapFunction}
*/
wrapFunctions["getExtension"] = function(name)
{
@@ -2885,16 +2983,16 @@ WebGLRenderingContextResource.prototype = {
//
/**
- * @param {WebGLProgram} program
- * @param {WebGLShader} shader
- * @this Resource.WrapFunction
+ * @param {!WebGLProgram} program
+ * @param {!WebGLShader} shader
+ * @this {Resource.WrapFunction}
*/
wrapFunctions["attachShader"] = function(program, shader)
{
var resource = this._resource.currentBinding(program);
if (resource) {
resource.pushCall(this.call());
- var shaderResource = /** @type {WebGLShaderResource} */ (Resource.forObject(shader));
+ var shaderResource = /** @type {!WebGLShaderResource} */ (Resource.forObject(shader));
if (shaderResource) {
var shaderType = shaderResource.type();
resource._registerBoundResource("__attachShader_" + shaderType, shaderResource);
@@ -2905,8 +3003,8 @@ WebGLRenderingContextResource.prototype = {
* @param {number} target
* @param {number} attachment
* @param {number} objectTarget
- * @param {WebGLRenderbuffer|WebGLTexture} obj
- * @this Resource.WrapFunction
+ * @param {!WebGLRenderbuffer|!WebGLTexture} obj
+ * @this {Resource.WrapFunction}
*/
wrapFunctions["framebufferRenderbuffer"] = wrapFunctions["framebufferTexture2D"] = function(target, attachment, objectTarget, obj)
{
@@ -2918,8 +3016,8 @@ WebGLRenderingContextResource.prototype = {
}
/**
* @param {number} target
- * @param {Object} obj
- * @this Resource.WrapFunction
+ * @param {!Object} obj
+ * @this {Resource.WrapFunction}
*/
wrapFunctions["bindBuffer"] = wrapFunctions["bindFramebuffer"] = wrapFunctions["bindRenderbuffer"] = function(target, obj)
{
@@ -2928,19 +3026,19 @@ WebGLRenderingContextResource.prototype = {
}
/**
* @param {number} target
- * @param {WebGLTexture} obj
- * @this Resource.WrapFunction
+ * @param {!WebGLTexture} obj
+ * @this {Resource.WrapFunction}
*/
wrapFunctions["bindTexture"] = function(target, obj)
{
this._resource.currentBinding(target); // To call WebGLBoundResource.prototype.pushBinding().
- var gl = /** @type {WebGLRenderingContext} */ (this._originalObject);
+ var gl = /** @type {!WebGLRenderingContext} */ (this._originalObject);
var currentTextureBinding = /** @type {number} */ (gl.getParameter(gl.ACTIVE_TEXTURE));
this._resource._registerBoundResource("__bindTexture_" + target + "_" + currentTextureBinding, obj);
}
/**
- * @param {WebGLProgram} program
- * @this Resource.WrapFunction
+ * @param {!WebGLProgram} program
+ * @this {Resource.WrapFunction}
*/
wrapFunctions["useProgram"] = function(program)
{
@@ -2948,11 +3046,11 @@ WebGLRenderingContextResource.prototype = {
}
/**
* @param {number} index
- * @this Resource.WrapFunction
+ * @this {Resource.WrapFunction}
*/
wrapFunctions["vertexAttribPointer"] = function(index)
{
- var gl = /** @type {WebGLRenderingContext} */ (this._originalObject);
+ var gl = /** @type {!WebGLRenderingContext} */ (this._originalObject);
this._resource._registerBoundResource("__vertexAttribPointer_" + index, gl.getParameter(gl.ARRAY_BUFFER_BINDING));
}
@@ -2967,8 +3065,8 @@ WebGLRenderingContextResource.prototype = {
{
if (pushCallFunc) {
/**
- * @param {Object|number} target
- * @this Resource.WrapFunction
+ * @param {!Object|number} target
+ * @this {Resource.WrapFunction}
*/
wrapFunctions[methodName] = function(target)
{
@@ -2978,8 +3076,8 @@ WebGLRenderingContextResource.prototype = {
}
} else {
/**
- * @param {Object|number} target
- * @this Resource.WrapFunction
+ * @param {!Object|number} target
+ * @this {Resource.WrapFunction}
*/
wrapFunctions[methodName] = function(target)
{
@@ -3032,7 +3130,6 @@ CanvasRenderingContext2DResource.AttributeProperties = [
"textBaseline",
"lineDashOffset",
"imageSmoothingEnabled",
- "webkitImageSmoothingEnabled",
"webkitLineDash",
"webkitLineDashOffset"
];
@@ -3074,7 +3171,7 @@ CanvasRenderingContext2DResource.DrawingMethods = TypeUtils.createPrefixedProper
"drawImage",
"drawImageFromRect",
"drawCustomFocusRing",
- "drawSystemFocusRing",
+ "drawFocusIfNeeded",
"fill",
"fillRect",
"fillText",
@@ -3088,7 +3185,7 @@ CanvasRenderingContext2DResource.DrawingMethods = TypeUtils.createPrefixedProper
CanvasRenderingContext2DResource.prototype = {
/**
* @override (overrides @return type)
- * @return {CanvasRenderingContext2D}
+ * @return {!CanvasRenderingContext2D}
*/
wrappedObject: function()
{
@@ -3106,7 +3203,7 @@ CanvasRenderingContext2DResource.prototype = {
/**
* @override
- * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
+ * @return {!Array.<!TypeUtils.InternalResourceStateDescriptor>}
*/
currentState: function()
{
@@ -3119,14 +3216,14 @@ CanvasRenderingContext2DResource.prototype = {
},
/**
- * @param {?Cache.<ReplayableResource>} cache
+ * @param {?Cache.<!ReplayableResource>} cache
* @return {!Object.<string, *>}
*/
_internalCurrentState: function(cache)
{
/**
- * @param {Resource|*} obj
- * @return {Resource|ReplayableResource|*}
+ * @param {!Resource|*} obj
+ * @return {!Resource|!ReplayableResource|*}
*/
function maybeToReplayable(obj)
{
@@ -3145,8 +3242,8 @@ CanvasRenderingContext2DResource.prototype = {
},
/**
- * @param {Object.<string, *>} state
- * @param {!Cache.<Resource>} cache
+ * @param {?Object.<string, *>} state
+ * @param {!Cache.<!Resource>} cache
*/
_applyAttributesState: function(state, cache)
{
@@ -3156,7 +3253,7 @@ CanvasRenderingContext2DResource.prototype = {
for (var attribute in state) {
if (attribute === "lineDash") {
if (ctx.setLineDash)
- ctx.setLineDash(/** @type {Array.<number>} */ (state[attribute]));
+ ctx.setLineDash(/** @type {!Array.<number>} */ (state[attribute]));
} else
ctx[attribute] = ReplayableResource.replay(state[attribute], cache);
}
@@ -3165,14 +3262,14 @@ CanvasRenderingContext2DResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<ReplayableResource>} cache
+ * @param {!Cache.<!ReplayableResource>} cache
*/
_populateReplayableData: function(data, cache)
{
var ctx = this.wrappedObject();
// FIXME: Convert resources in the state (CanvasGradient, CanvasPattern) to Replayable.
data.currentAttributes = this._internalCurrentState(null);
- data.originalCanvasCloned = TypeUtils.cloneIntoCanvas(ctx.canvas);
+ data.originalCanvasCloned = TypeUtils.cloneIntoCanvas(/** @type {!HTMLCanvasElement} */ (ctx.canvas));
if (ctx.getContextAttributes)
data.originalContextAttributes = ctx.getContextAttributes();
},
@@ -3180,7 +3277,7 @@ CanvasRenderingContext2DResource.prototype = {
/**
* @override
* @param {!Object} data
- * @param {!Cache.<Resource>} cache
+ * @param {!Cache.<!Resource>} cache
*/
_doReplayCalls: function(data, cache)
{
@@ -3189,7 +3286,7 @@ CanvasRenderingContext2DResource.prototype = {
this.setWrappedObject(ctx);
for (var i = 0, n = data.calls.length; i < n; ++i) {
- var replayableCall = /** @type {ReplayableCall} */ (data.calls[i]);
+ var replayableCall = /** @type {!ReplayableCall} */ (data.calls[i]);
if (replayableCall.functionName() === "save")
this._applyAttributesState(replayableCall.attachment("canvas2dAttributesState"), cache);
this._calls.push(replayableCall.replay(cache));
@@ -3372,7 +3469,7 @@ CanvasRenderingContext2DResource.prototype = {
/**
* @override
- * @return {!Object.<string, Function>}
+ * @return {!Object.<string, !Function>}
*/
_customWrapFunctions: function()
{
@@ -3403,13 +3500,13 @@ CanvasRenderingContext2DResource.prototype = {
function stateModifyingWrapFunction(methodName, func)
{
if (func) {
- /** @this Resource.WrapFunction */
+ /** @this {Resource.WrapFunction} */
wrapFunctions[methodName] = function()
{
func.call(this._resource, this.call());
}
} else {
- /** @this Resource.WrapFunction */
+ /** @this {Resource.WrapFunction} */
wrapFunctions[methodName] = function()
{
this._resource.pushCall(this.call());
@@ -3478,10 +3575,10 @@ CallFormatter.prototype = {
var result = {
description: description,
- type: /** @type {CanvasAgent.CallArgumentType} */ (remoteObject.type)
+ type: /** @type {!CanvasAgent.CallArgumentType} */ (remoteObject.type)
};
if (remoteObject.subtype)
- result.subtype = /** @type {CanvasAgent.CallArgumentSubtype} */ (remoteObject.subtype);
+ result.subtype = /** @type {!CanvasAgent.CallArgumentSubtype} */ (remoteObject.subtype);
if (remoteObject.objectId) {
if (objectGroup)
result.remoteObject = remoteObject;
@@ -3502,7 +3599,7 @@ CallFormatter.prototype = {
/**
* @param {number} value
- * @param {Array.<string>=} options
+ * @param {!Array.<string>=} options
* @return {?string}
*/
enumNameForValue: function(value, options)
@@ -3511,7 +3608,7 @@ CallFormatter.prototype = {
},
/**
- * @param {!Array.<TypeUtils.InternalResourceStateDescriptor>} descriptors
+ * @param {!Array.<!TypeUtils.InternalResourceStateDescriptor>} descriptors
* @param {string=} objectGroup
* @return {!Array.<!CanvasAgent.ResourceStateDescriptor>}
*/
@@ -3573,7 +3670,7 @@ CallFormatter.forResource = function(resource)
/**
* @param {number} resourceId
- * @return {CanvasAgent.ResourceId}
+ * @return {!CanvasAgent.ResourceId}
*/
CallFormatter.makeStringResourceId = function(resourceId)
{
@@ -3705,7 +3802,7 @@ WebGLCallFormatter.prototype = {
/**
* @override
* @param {number} value
- * @param {Array.<string>=} options
+ * @param {!Array.<string>=} options
* @return {?string}
*/
enumNameForValue: function(value, options)
@@ -3724,7 +3821,7 @@ WebGLCallFormatter.prototype = {
/**
* @param {!ReplayableCall} replayableCall
- * @return {Object}
+ * @return {?Object}
*/
_findEnumsInfo: function(replayableCall)
{
@@ -3757,7 +3854,7 @@ WebGLCallFormatter.prototype = {
/**
* @param {?CanvasAgent.CallArgument|undefined} callArgument
- * @param {Array.<string>=} options
+ * @param {!Array.<string>=} options
*/
_formatEnumValue: function(callArgument, options)
{
@@ -3772,7 +3869,7 @@ WebGLCallFormatter.prototype = {
/**
* @param {?CanvasAgent.CallArgument|undefined} callArgument
- * @param {Array.<string>=} options
+ * @param {!Array.<string>=} options
*/
_formatEnumBitmaskValue: function(callArgument, options)
{
@@ -3816,7 +3913,7 @@ WebGLCallFormatter.prototype = {
this._enumValueToNames = Object.create(null);
/**
- * @param {Object} obj
+ * @param {?Object} obj
* @this WebGLCallFormatter
*/
function iterateWebGLEnums(obj)
@@ -3864,31 +3961,32 @@ WebGLCallFormatter.prototype = {
// Sort to get rid of ambiguity.
for (var value in this._enumValueToNames) {
- var names = this._enumValueToNames[value];
+ var numericValue = Number(value);
+ var names = this._enumValueToNames[numericValue];
if (names.length > 1) {
// Choose one enum name if possible. For example:
// [BLEND_EQUATION, BLEND_EQUATION_RGB] => BLEND_EQUATION
// [COLOR_ATTACHMENT0, COLOR_ATTACHMENT0_WEBGL] => COLOR_ATTACHMENT0
var common = commonSubstring(names);
if (common)
- this._enumValueToNames[value] = [common];
+ this._enumValueToNames[numericValue] = [common];
else
- this._enumValueToNames[value] = names.sort();
+ this._enumValueToNames[numericValue] = names.sort();
}
}
},
/**
- * @return {WebGLRenderingContext}
+ * @return {?WebGLRenderingContext}
*/
_createUninstrumentedWebGLRenderingContext: function()
{
- var canvas = /** @type {HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
+ var canvas = /** @type {!HTMLCanvasElement} */ (inspectedWindow.document.createElement("canvas"));
var contextIds = ["experimental-webgl", "webkit-3d", "3d"];
for (var i = 0, contextId; contextId = contextIds[i]; ++i) {
var context = canvas.getContext(contextId);
if (context)
- return /** @type {WebGLRenderingContext} */ (Resource.wrappedObject(context));
+ return /** @type {!WebGLRenderingContext} */ (Resource.wrappedObject(context));
}
return null;
},
@@ -3906,7 +4004,7 @@ function TraceLog()
{
/** @type {!Array.<!ReplayableCall>} */
this._replayableCalls = [];
- /** @type {!Cache.<ReplayableResource>} */
+ /** @type {!Cache.<!ReplayableResource>} */
this._replayablesCache = new Cache();
/** @type {!Object.<number, boolean>} */
this._frameEndCallIndexes = {};
@@ -3933,7 +4031,7 @@ TraceLog.prototype = {
/**
* @param {number} id
- * @return {ReplayableResource|undefined}
+ * @return {!ReplayableResource|undefined}
*/
replayableResource: function(id)
{
@@ -3995,7 +4093,7 @@ function TraceLogPlayer(traceLog)
this._traceLog = traceLog;
/** @type {number} */
this._nextReplayStep = 0;
- /** @type {!Cache.<Resource>} */
+ /** @type {!Cache.<!Resource>} */
this._replayWorldCache = new Cache();
}
@@ -4010,7 +4108,7 @@ TraceLogPlayer.prototype = {
/**
* @param {number} id
- * @return {Resource|undefined}
+ * @return {!Resource|undefined}
*/
replayWorldResource: function(id)
{
@@ -4070,6 +4168,7 @@ TraceLogPlayer.prototype = {
{
/**
* @param {*} obj
+ * @this {TraceLogPlayer}
*/
function replayIfNotCreatedInThisTraceLog(obj)
{
@@ -4108,7 +4207,7 @@ ResourceTrackingManager.prototype = {
},
/**
- * @return {TraceLog}
+ * @return {?TraceLog}
*/
lastTraceLog: function()
{
@@ -4132,7 +4231,7 @@ ResourceTrackingManager.prototype = {
},
/**
- * @param {TraceLog=} traceLog
+ * @param {!TraceLog=} traceLog
*/
stopCapturing: function(traceLog)
{
@@ -4163,7 +4262,7 @@ ResourceTrackingManager.prototype = {
/**
* @param {!Resource} resource
- * @param {Array|Arguments} args
+ * @param {!Array|!Arguments} args
*/
captureArguments: function(resource, args)
{
@@ -4206,16 +4305,16 @@ var InjectedCanvasModule = function()
this._manager = new ResourceTrackingManager();
/** @type {number} */
this._lastTraceLogId = 0;
- /** @type {!Object.<string, TraceLog>} */
+ /** @type {!Object.<string, !TraceLog>} */
this._traceLogs = {};
- /** @type {!Object.<string, TraceLogPlayer>} */
+ /** @type {!Object.<string, !TraceLogPlayer>} */
this._traceLogPlayers = {};
}
InjectedCanvasModule.prototype = {
/**
* @param {!WebGLRenderingContext} glContext
- * @return {Object}
+ * @return {!Object}
*/
wrapWebGLContext: function(glContext)
{
@@ -4226,7 +4325,7 @@ InjectedCanvasModule.prototype = {
/**
* @param {!CanvasRenderingContext2D} context
- * @return {Object}
+ * @return {!Object}
*/
wrapCanvas2DContext: function(context)
{
@@ -4236,7 +4335,7 @@ InjectedCanvasModule.prototype = {
},
/**
- * @return {CanvasAgent.TraceLogId}
+ * @return {!CanvasAgent.TraceLogId}
*/
captureFrame: function()
{
@@ -4244,7 +4343,7 @@ InjectedCanvasModule.prototype = {
},
/**
- * @return {CanvasAgent.TraceLogId}
+ * @return {!CanvasAgent.TraceLogId}
*/
startCapturing: function()
{
@@ -4258,13 +4357,13 @@ InjectedCanvasModule.prototype = {
/**
* @param {function(this:ResourceTrackingManager)} func
- * @return {CanvasAgent.TraceLogId}
+ * @return {!CanvasAgent.TraceLogId}
*/
_callStartCapturingFunction: function(func)
{
var oldTraceLog = this._manager.lastTraceLog();
func.call(this._manager);
- var traceLog = this._manager.lastTraceLog();
+ var traceLog = /** @type {!TraceLog} */ (this._manager.lastTraceLog());
if (traceLog === oldTraceLog) {
for (var id in this._traceLogs) {
if (this._traceLogs[id] === traceLog)
@@ -4277,7 +4376,7 @@ InjectedCanvasModule.prototype = {
},
/**
- * @param {CanvasAgent.TraceLogId} id
+ * @param {!CanvasAgent.TraceLogId} id
*/
stopCapturing: function(id)
{
@@ -4287,7 +4386,7 @@ InjectedCanvasModule.prototype = {
},
/**
- * @param {CanvasAgent.TraceLogId} id
+ * @param {!CanvasAgent.TraceLogId} id
*/
dropTraceLog: function(id)
{
@@ -4300,7 +4399,7 @@ InjectedCanvasModule.prototype = {
},
/**
- * @param {CanvasAgent.TraceLogId} id
+ * @param {!CanvasAgent.TraceLogId} id
* @param {number=} startOffset
* @param {number=} maxLength
* @return {!CanvasAgent.TraceLog|string}
@@ -4358,7 +4457,7 @@ InjectedCanvasModule.prototype = {
},
/**
- * @param {CanvasAgent.TraceLogId} traceLogId
+ * @param {!CanvasAgent.TraceLogId} traceLogId
* @param {number} stepNo
* @return {{resourceState: !CanvasAgent.ResourceState, replayTime: number}|string}
*/
@@ -4384,8 +4483,8 @@ InjectedCanvasModule.prototype = {
},
/**
- * @param {CanvasAgent.TraceLogId} traceLogId
- * @param {CanvasAgent.ResourceId} stringResourceId
+ * @param {!CanvasAgent.TraceLogId} traceLogId
+ * @param {!CanvasAgent.ResourceId} stringResourceId
* @return {!CanvasAgent.ResourceState|string}
*/
resourceState: function(traceLogId, stringResourceId)
@@ -4409,7 +4508,7 @@ InjectedCanvasModule.prototype = {
},
/**
- * @param {CanvasAgent.TraceLogId} traceLogId
+ * @param {!CanvasAgent.TraceLogId} traceLogId
* @param {number} callIndex
* @param {number} argumentIndex
* @param {string} objectGroup
@@ -4449,7 +4548,7 @@ InjectedCanvasModule.prototype = {
},
/**
- * @return {CanvasAgent.TraceLogId}
+ * @return {!CanvasAgent.TraceLogId}
*/
_makeTraceLogId: function()
{
@@ -4458,8 +4557,8 @@ InjectedCanvasModule.prototype = {
/**
* @param {number} resourceId
- * @param {CanvasAgent.TraceLogId} traceLogId
- * @param {Resource|undefined} resource
+ * @param {!CanvasAgent.TraceLogId} traceLogId
+ * @param {?Resource=} resource
* @param {string=} overrideImageURL
* @return {!CanvasAgent.ResourceState}
*/
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptExterns.js b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptExterns.js
index b7d83a2a2d2..0ffea17ca7f 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptExterns.js
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptExterns.js
@@ -39,17 +39,20 @@ InjectedScriptHostClass.prototype.getInternalProperties = function(object) { }
*/
InjectedScriptHostClass.prototype.functionDetails = function(func) { }
/**
- * @param {*} object
+ * @param {!Object} receiver
+ * @param {!Function} func
+ * @param {...*} args
*/
-InjectedScriptHostClass.prototype.isHTMLAllCollection = function(object) { }
+InjectedScriptHostClass.prototype.suppressWarningsAndCall = function(receiver, func, args) { }
/**
* @param {*} object
*/
-InjectedScriptHostClass.prototype.internalConstructorName = function(object) { }
+InjectedScriptHostClass.prototype.isHTMLAllCollection = function(object) { }
/**
* @param {*} object
*/
-InjectedScriptHostClass.prototype.copyText = function(object) { }
+InjectedScriptHostClass.prototype.internalConstructorName = function(object) { }
+
InjectedScriptHostClass.prototype.clearConsoleMessages = function() { }
/**
* @param {number} index
@@ -157,8 +160,6 @@ function JavaScriptFunction()
this.rawScopes;
}
-var InspectorBackend = { };
-
// http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
/**
* @constructor
@@ -178,3 +179,14 @@ CallSite.prototype.getLineNumber = function() { }
* @return {number}
*/
CallSite.prototype.getColumnNumber = function() { }
+
+// FIXME: Remove once ES6 is supported natively by JS compiler.
+
+/** @typedef {string} */
+var symbol;
+
+/**
+ * @param {string} description
+ * @return {symbol}
+ */
+function Symbol(description) {}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.cpp b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.cpp
index 8354958f1ce..34774d87d25 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.cpp
@@ -31,20 +31,16 @@
#include "config.h"
#include "core/inspector/InjectedScriptHost.h"
-#include "core/inspector/InspectorAgent.h"
#include "core/inspector/InspectorConsoleAgent.h"
#include "core/inspector/InspectorDOMAgent.h"
-#include "core/inspector/InspectorDOMStorageAgent.h"
-#include "core/inspector/InspectorDatabaseAgent.h"
#include "core/inspector/InspectorDebuggerAgent.h"
+#include "core/inspector/InspectorInspectorAgent.h"
#include "core/inspector/InstrumentingAgents.h"
#include "platform/JSONValues.h"
#include "wtf/RefPtr.h"
#include "wtf/text/StringBuilder.h"
-using namespace std;
-
namespace WebCore {
PassRefPtr<InjectedScriptHost> InjectedScriptHost::create()
@@ -72,15 +68,15 @@ void InjectedScriptHost::disconnect()
void InjectedScriptHost::inspectImpl(PassRefPtr<JSONValue> object, PassRefPtr<JSONValue> hints)
{
- if (InspectorAgent* inspectorAgent = m_instrumentingAgents ? m_instrumentingAgents->inspectorAgent() : 0) {
+ if (InspectorInspectorAgent* inspectorAgent = m_instrumentingAgents ? m_instrumentingAgents->inspectorInspectorAgent() : 0) {
RefPtr<TypeBuilder::Runtime::RemoteObject> remoteObject = TypeBuilder::Runtime::RemoteObject::runtimeCast(object);
inspectorAgent->inspect(remoteObject, hints->asObject());
}
}
-void InjectedScriptHost::getEventListenersImpl(Node* node, Vector<EventListenerInfo>& listenersArray)
+void InjectedScriptHost::getEventListenersImpl(EventTarget* target, Vector<EventListenerInfo>& listenersArray)
{
- InspectorDOMAgent::getEventListeners(node, listenersArray, false);
+ InspectorDOMAgent::getEventListeners(target, listenersArray, false);
}
void InjectedScriptHost::clearConsoleMessages()
@@ -108,27 +104,13 @@ void InjectedScriptHost::clearInspectedObjects()
m_inspectedObjects.clear();
}
-InjectedScriptHost::InspectableObject* InjectedScriptHost::inspectedObject(unsigned int num)
+InjectedScriptHost::InspectableObject* InjectedScriptHost::inspectedObject(unsigned num)
{
if (num >= m_inspectedObjects.size())
return m_defaultInspectableObject.get();
return m_inspectedObjects[num].get();
}
-String InjectedScriptHost::databaseIdImpl(Database* database)
-{
- if (InspectorDatabaseAgent* databaseAgent = m_instrumentingAgents ? m_instrumentingAgents->inspectorDatabaseAgent() : 0)
- return databaseAgent->databaseId(database);
- return String();
-}
-
-String InjectedScriptHost::storageIdImpl(Storage* storage)
-{
- if (InspectorDOMStorageAgent* domStorageAgent = m_instrumentingAgents ? m_instrumentingAgents->inspectorDOMStorageAgent() : 0)
- return domStorageAgent->storageId(storage);
- return String();
-}
-
void InjectedScriptHost::debugFunction(const String& scriptId, int lineNumber, int columnNumber)
{
if (InspectorDebuggerAgent* debuggerAgent = m_instrumentingAgents ? m_instrumentingAgents->inspectorDebuggerAgent() : 0)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.h b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.h
index 2a95c7ab468..bde9ece0f1a 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.h
@@ -32,12 +32,15 @@
#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptWrappable.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
class Database;
+class EventTarget;
class InjectedScript;
class InstrumentingAgents;
class JSONValue;
@@ -64,7 +67,7 @@ public:
m_scriptDebugServer = scriptDebugServer;
}
- static Node* scriptValueAsNode(ScriptValue);
+ static Node* scriptValueAsNode(ScriptState*, ScriptValue);
static ScriptValue nodeAsScriptValue(ScriptState*, Node*);
void disconnect();
@@ -77,14 +80,12 @@ public:
};
void addInspectedObject(PassOwnPtr<InspectableObject>);
void clearInspectedObjects();
- InspectableObject* inspectedObject(unsigned int num);
+ InspectableObject* inspectedObject(unsigned num);
void inspectImpl(PassRefPtr<JSONValue> objectToInspect, PassRefPtr<JSONValue> hints);
- void getEventListenersImpl(Node*, Vector<EventListenerInfo>& listenersArray);
+ void getEventListenersImpl(EventTarget*, Vector<EventListenerInfo>& listenersArray);
void clearConsoleMessages();
- String databaseIdImpl(Database*);
- String storageIdImpl(Storage*);
void debugFunction(const String& scriptId, int lineNumber, int columnNumber);
void undebugFunction(const String& scriptId, int lineNumber, int columnNumber);
void monitorFunction(const String& scriptId, int lineNumber, int columnNumber, const String& functionName);
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.idl b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.idl
index 77e4cbe5cfa..5dec0fc5601 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.idl
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptHost.idl
@@ -41,16 +41,15 @@
[Custom] boolean isHTMLAllCollection(any obj);
[Custom] DOMString type(any obj);
[Custom] any functionDetails(any obj);
- [Custom] Array getInternalProperties(any obj);
- [Custom] Array getEventListeners(Node node);
+ [Custom] any[] getInternalProperties(any obj);
+ [Custom] EventListener[] getEventListeners(EventTarget target);
[Custom] any evaluate(DOMString text);
- [Custom] DOMString databaseId(any database);
- [Custom] DOMString storageId(any storage);
[Custom] void debugFunction(any fn);
[Custom] void undebugFunction(any fn);
[Custom] void monitorFunction(any fn);
[Custom] void unmonitorFunction(any fn);
+ [Custom] any suppressWarningsAndCall(any receiver, any fn, any param1, any param2);
// Only declarative scope (local, with and catch) is accepted. Returns undefined.
- [Custom] any setFunctionVariableValue(any functionObject, int scopeIndex, DOMString variableName, any newValue);
+ [Custom] any setFunctionVariableValue(any functionObject, long scopeIndex, DOMString variableName, any newValue);
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.cpp b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.cpp
index e425ee1b4f4..b0f9189e474 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/inspector/InjectedScriptManager.h"
-#include "InjectedScriptSource.h"
-#include "bindings/v8/ScriptObject.h"
+#include "bindings/v8/ScriptValue.h"
+#include "core/InjectedScriptSource.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptHost.h"
#include "core/inspector/JSONParser.h"
@@ -80,7 +80,7 @@ InjectedScript InjectedScriptManager::injectedScriptForId(int id)
return it->value;
for (ScriptStateToId::iterator it = m_scriptStateToId.begin(); it != m_scriptStateToId.end(); ++it) {
if (it->value == id)
- return injectedScriptFor(it->key);
+ return injectedScriptFor(it->key.get());
}
return InjectedScript();
}
@@ -113,7 +113,7 @@ void InjectedScriptManager::discardInjectedScripts()
m_scriptStateToId.clear();
}
-void InjectedScriptManager::discardInjectedScriptsFor(DOMWindow* window)
+void InjectedScriptManager::discardInjectedScriptsFor(LocalDOMWindow* window)
{
if (m_scriptStateToId.isEmpty())
return;
@@ -127,19 +127,16 @@ void InjectedScriptManager::discardInjectedScriptsFor(DOMWindow* window)
m_scriptStateToId.remove(scriptState);
idsToRemove.append(it->key);
}
-
- for (size_t i = 0; i < idsToRemove.size(); i++)
- m_idToInjectedScript.remove(idsToRemove[i]);
+ m_idToInjectedScript.removeAll(idsToRemove);
// Now remove script states that have id but no injected script.
Vector<ScriptState*> scriptStatesToRemove;
for (ScriptStateToId::iterator it = m_scriptStateToId.begin(); it != m_scriptStateToId.end(); ++it) {
- ScriptState* scriptState = it->key;
+ ScriptState* scriptState = it->key.get();
if (window == scriptState->domWindow())
scriptStatesToRemove.append(scriptState);
}
- for (size_t i = 0; i < scriptStatesToRemove.size(); i++)
- m_scriptStateToId.remove(scriptStatesToRemove[i]);
+ m_scriptStateToId.removeAll(scriptStatesToRemove);
}
bool InjectedScriptManager::canAccessInspectedWorkerGlobalScope(ScriptState*)
@@ -176,8 +173,8 @@ InjectedScript InjectedScriptManager::injectedScriptFor(ScriptState* inspectedSc
return InjectedScript();
int id = injectedScriptIdFor(inspectedScriptState);
- ScriptObject injectedScriptObject = createInjectedScript(injectedScriptSource(), inspectedScriptState, id);
- InjectedScript result(injectedScriptObject, m_inspectedStateAccessCheck);
+ ScriptValue injectedScriptValue = createInjectedScript(injectedScriptSource(), inspectedScriptState, id);
+ InjectedScript result(injectedScriptValue, m_inspectedStateAccessCheck);
m_idToInjectedScript.set(id, result);
return result;
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.h b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.h
index 83c5d2fb45f..99b42eac63e 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptManager.h
@@ -34,13 +34,14 @@
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/text/WTFString.h"
+#include <v8.h>
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class InjectedScript;
class InjectedScriptHost;
-class ScriptObject;
+class ScriptValue;
class InjectedScriptManager {
WTF_MAKE_NONCOPYABLE(InjectedScriptManager); WTF_MAKE_FAST_ALLOCATED;
@@ -58,7 +59,7 @@ public:
int injectedScriptIdFor(ScriptState*);
InjectedScript injectedScriptForObjectId(const String& objectId);
void discardInjectedScripts();
- void discardInjectedScriptsFor(DOMWindow*);
+ void discardInjectedScriptsFor(LocalDOMWindow*);
void releaseObjectGroup(const String& objectGroup);
typedef bool (*InspectedStateAccessCheck)(ScriptState*);
@@ -70,7 +71,7 @@ private:
explicit InjectedScriptManager(InspectedStateAccessCheck);
String injectedScriptSource();
- ScriptObject createInjectedScript(const String& source, ScriptState*, int id);
+ ScriptValue createInjectedScript(const String& source, ScriptState*, int id);
static bool canAccessInspectedWindow(ScriptState*);
static bool canAccessInspectedWorkerGlobalScope(ScriptState*);
@@ -80,7 +81,7 @@ private:
IdToInjectedScriptMap m_idToInjectedScript;
RefPtr<InjectedScriptHost> m_injectedScriptHost;
InspectedStateAccessCheck m_inspectedStateAccessCheck;
- typedef HashMap<ScriptState*, int> ScriptStateToId;
+ typedef HashMap<RefPtr<ScriptState>, int> ScriptStateToId;
ScriptStateToId m_scriptStateToId;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptModule.cpp b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptModule.cpp
index 401a05b1ad3..53410d9e1e4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptModule.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptModule.cpp
@@ -32,8 +32,7 @@
#include "core/inspector/InjectedScriptModule.h"
#include "bindings/v8/ScriptFunctionCall.h"
-#include "bindings/v8/ScriptObject.h"
-#include "bindings/v8/ScriptScope.h"
+#include "bindings/v8/ScriptValue.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptManager.h"
@@ -47,8 +46,8 @@ InjectedScriptModule::InjectedScriptModule(const String& name)
void InjectedScriptModule::ensureInjected(InjectedScriptManager* injectedScriptManager, ScriptState* scriptState)
{
InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(scriptState);
- ASSERT(!injectedScript.hasNoValue());
- if (injectedScript.hasNoValue())
+ ASSERT(!injectedScript.isEmpty());
+ if (injectedScript.isEmpty())
return;
// FIXME: Make the InjectedScript a module itself.
@@ -57,20 +56,19 @@ void InjectedScriptModule::ensureInjected(InjectedScriptManager* injectedScriptM
bool hadException = false;
ScriptValue resultValue = injectedScript.callFunctionWithEvalEnabled(function, hadException);
ASSERT(!hadException);
- ScriptScope scope(scriptState);
- if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) {
+ ScriptState::Scope scope(scriptState);
+ if (hadException || resultValue.isEmpty() || !resultValue.isObject()) {
ScriptFunctionCall function(injectedScript.injectedScriptObject(), "injectModule");
function.appendArgument(name());
function.appendArgument(source());
resultValue = injectedScript.callFunctionWithEvalEnabled(function, hadException);
- if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) {
+ if (hadException || resultValue.isEmpty() || !resultValue.isObject()) {
ASSERT_NOT_REACHED();
return;
}
}
- ScriptObject moduleObject(scriptState, resultValue);
- initialize(moduleObject, injectedScriptManager->inspectedStateAccessCheck());
+ initialize(resultValue, injectedScriptManager->inspectedStateAccessCheck());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptSource.js b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptSource.js
index 64c39f7c558..3cabdc116cb 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptSource.js
+++ b/chromium/third_party/WebKit/Source/core/inspector/InjectedScriptSource.js
@@ -41,15 +41,43 @@
var Object = /** @type {function(new:Object, *=)} */ ({}.constructor);
/**
- * @param {Arguments} array
+ * @param {!Array.<T>} array
+ * @param {...} var_args
+ * @template T
+ */
+function push(array, var_args)
+{
+ for (var i = 1; i < arguments.length; ++i)
+ array[array.length] = arguments[i];
+}
+
+/**
+ * @param {!Arguments.<T>} array
* @param {number=} index
- * @return {Array.<*>}
+ * @return {!Array.<T>}
+ * @template T
*/
function slice(array, index)
{
var result = [];
- for (var i = index || 0; i < array.length; ++i)
- result.push(array[i]);
+ for (var i = index || 0, j = 0; i < array.length; ++i, ++j)
+ result[j] = array[i];
+ return result;
+}
+
+/**
+ * @param {!Array.<T>} array1
+ * @param {!Array.<T>} array2
+ * @return {!Array.<T>}
+ * @template T
+ */
+function concat(array1, array2)
+{
+ var result = [];
+ for (var i = 0; i < array1.length; ++i)
+ push(result, array1[i]);
+ for (var i = 0; i < array2.length; ++i)
+ push(result, array2[i]);
return result;
}
@@ -77,52 +105,112 @@ function toStringDescription(obj)
/**
* Please use this bind, not the one from Function.prototype
* @param {function(...)} func
- * @param {Object} thisObject
- * @param {...number} var_args
+ * @param {?Object} thisObject
+ * @param {...} var_args
+ * @return {function(...)}
*/
function bind(func, thisObject, var_args)
{
var args = slice(arguments, 2);
/**
- * @param {...number} var_args
+ * @param {...} var_args
*/
function bound(var_args)
{
- return func.apply(thisObject, args.concat(slice(arguments)));
+ return func.apply(thisObject, concat(args, slice(arguments)));
}
- bound.toString = function() {
+ bound.toString = function()
+ {
return "bound: " + func;
};
return bound;
}
/**
+ * @param {T} obj
+ * @return {T}
+ * @template T
+ */
+function nullifyObjectProto(obj)
+{
+ if (obj && typeof obj === "object")
+ obj.__proto__ = null;
+ return obj;
+}
+
+/**
+ * FireBug's array detection.
+ * @param {*} obj
+ * @return {boolean}
+ */
+function isArrayLike(obj)
+{
+ try {
+ if (typeof obj !== "object")
+ return false;
+ if (typeof obj.splice === "function")
+ return isFinite(obj.length);
+ var str = Object.prototype.toString.call(obj);
+ if (str === "[object Array]" ||
+ str === "[object Arguments]" ||
+ str === "[object HTMLCollection]" ||
+ str === "[object NodeList]" ||
+ str === "[object DOMTokenList]")
+ return isFinite(obj.length);
+ } catch (e) {
+ }
+ return false;
+}
+
+/**
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+function max(a, b)
+{
+ return a > b ? a : b;
+}
+
+/**
+ * FIXME: Remove once ES6 is supported natively by JS compiler.
+ * @param {*} obj
+ * @return {boolean}
+ */
+function isSymbol(obj)
+{
+ var type = typeof obj;
+ return (type === "symbol");
+}
+
+/**
* @constructor
*/
var InjectedScript = function()
{
/** @type {number} */
this._lastBoundObjectId = 1;
- /** @type {!Object.<number, Object>} */
- this._idToWrappedObject = {};
+ /** @type {!Object.<number, (!Object|symbol)>} */
+ this._idToWrappedObject = { __proto__: null };
/** @type {!Object.<number, string>} */
- this._idToObjectGroupName = {};
- /** @type {!Object.<string, Array.<number>>} */
- this._objectGroups = {};
- /** @type {!Object.<string, Object>} */
- this._modules = {};
+ this._idToObjectGroupName = { __proto__: null };
+ /** @type {!Object.<string, !Array.<number>>} */
+ this._objectGroups = { __proto__: null };
+ /** @type {!Object.<string, !Object>} */
+ this._modules = { __proto__: null };
}
/**
- * @type {Object.<string, boolean>}
+ * @type {!Object.<string, boolean>}
* @const
*/
InjectedScript.primitiveTypes = {
- undefined: true,
- boolean: true,
- number: true,
- string: true
+ "undefined": true,
+ "boolean": true,
+ "number": true,
+ "string": true,
+ __proto__: null
}
InjectedScript.prototype = {
@@ -156,7 +244,7 @@ InjectedScript.prototype = {
*/
_fallbackWrapper: function(object)
{
- var result = {};
+ var result = { __proto__: null };
result.type = typeof object;
if (this.isPrimitiveValue(object))
result.value = object;
@@ -167,8 +255,8 @@ InjectedScript.prototype = {
/**
* @param {boolean} canAccessInspectedWindow
- * @param {Object} table
- * @param {Array.<string>|string|boolean} columns
+ * @param {!Object} table
+ * @param {!Array.<string>|string|boolean} columns
* @return {!RuntimeAgent.RemoteObject}
*/
wrapTable: function(canAccessInspectedWindow, table, columns)
@@ -181,7 +269,7 @@ InjectedScript.prototype = {
if (InjectedScriptHost.type(columns) == "array") {
columnNames = [];
for (var i = 0; i < columns.length; ++i)
- columnNames.push(toString(columns[i]));
+ columnNames[i] = toString(columns[i]);
}
return this._wrapObject(table, "console", false, true, columnNames, true);
},
@@ -204,20 +292,8 @@ InjectedScript.prototype = {
return;
var objectId = this._wrapObject(object, "");
- var hints = {};
+ var hints = { __proto__: null };
- switch (injectedScript._describe(object)) {
- case "Database":
- var databaseId = InjectedScriptHost.databaseId(object)
- if (databaseId)
- hints.databaseId = databaseId;
- break;
- case "Storage":
- var storageId = InjectedScriptHost.storageId(object)
- if (storageId)
- hints.domStorageId = InjectedScriptHost.evaluate("(" + storageId + ")");
- break;
- }
InjectedScriptHost.inspect(objectId, hints);
return object;
},
@@ -248,7 +324,7 @@ InjectedScript.prototype = {
},
/**
- * @param {Object} object
+ * @param {!Object|symbol} object
* @param {string=} objectGroupName
* @return {string}
*/
@@ -263,7 +339,7 @@ InjectedScript.prototype = {
group = [];
this._objectGroups[objectGroupName] = group;
}
- group.push(id);
+ push(group, id);
this._idToObjectGroupName[id] = objectGroupName;
}
return objectId;
@@ -271,11 +347,11 @@ InjectedScript.prototype = {
/**
* @param {string} objectId
- * @return {Object}
+ * @return {!Object}
*/
_parseObjectId: function(objectId)
{
- return InjectedScriptHost.evaluate("(" + objectId + ")");
+ return nullifyObjectProto(InjectedScriptHost.evaluate("(" + objectId + ")"));
},
/**
@@ -311,7 +387,7 @@ InjectedScript.prototype = {
* @param {string} objectId
* @param {boolean} ownProperties
* @param {boolean} accessorPropertiesOnly
- * @return {Array.<RuntimeAgent.PropertyDescriptor>|boolean}
+ * @return {!Array.<!RuntimeAgent.PropertyDescriptor>|boolean}
*/
getProperties: function(objectId, ownProperties, accessorPropertiesOnly)
{
@@ -319,8 +395,9 @@ InjectedScript.prototype = {
var object = this._objectForId(parsedObjectId);
var objectGroupName = this._idToObjectGroupName[parsedObjectId.id];
- if (!this._isDefined(object))
+ if (!this._isDefined(object) || isSymbol(object))
return false;
+ object = /** @type {!Object} */ (object);
var descriptors = this._propertyDescriptors(object, ownProperties, accessorPropertiesOnly);
// Go over properties, wrap object values.
@@ -336,21 +413,24 @@ InjectedScript.prototype = {
descriptor.configurable = false;
if (!("enumerable" in descriptor))
descriptor.enumerable = false;
+ if ("symbol" in descriptor)
+ descriptor.symbol = this._wrapObject(descriptor.symbol, objectGroupName);
}
return descriptors;
},
/**
* @param {string} objectId
- * @return {Array.<Object>|boolean}
+ * @return {!Array.<!Object>|boolean}
*/
- getInternalProperties: function(objectId, ownProperties)
+ getInternalProperties: function(objectId)
{
var parsedObjectId = this._parseObjectId(objectId);
var object = this._objectForId(parsedObjectId);
var objectGroupName = this._idToObjectGroupName[parsedObjectId.id];
- if (!this._isDefined(object))
+ if (!this._isDefined(object) || isSymbol(object))
return false;
+ object = /** @type {!Object} */ (object);
var descriptors = [];
var internalProperties = InjectedScriptHost.getInternalProperties(object);
if (internalProperties) {
@@ -358,9 +438,10 @@ InjectedScript.prototype = {
var property = internalProperties[i];
var descriptor = {
name: property.name,
- value: this._wrapObject(property.value, objectGroupName)
+ value: this._wrapObject(property.value, objectGroupName),
+ __proto__: null
};
- descriptors.push(descriptor);
+ push(descriptors, descriptor);
}
}
return descriptors;
@@ -376,14 +457,14 @@ InjectedScript.prototype = {
var func = this._objectForId(parsedFunctionId);
if (typeof func !== "function")
return "Cannot resolve function by id.";
- var details = InjectedScriptHost.functionDetails(func);
+ var details = nullifyObjectProto(InjectedScriptHost.functionDetails(func));
if ("rawScopes" in details) {
var objectGroupName = this._idToObjectGroupName[parsedFunctionId.id];
var rawScopes = details.rawScopes;
- var scopes = [];
delete details.rawScopes;
- for (var i = 0; i < rawScopes.length; i++)
- scopes.push(InjectedScript.CallFrameProxy._createScopeJson(rawScopes[i].type, rawScopes[i].object, objectGroupName));
+ var scopes = [];
+ for (var i = 0; i < rawScopes.length; ++i)
+ scopes[i] = InjectedScript.CallFrameProxy._createScopeJson(rawScopes[i].type, rawScopes[i].object, objectGroupName);
details.scopeChain = scopes;
}
return details;
@@ -408,30 +489,34 @@ InjectedScript.prototype = {
},
/**
- * @param {Object} object
+ * @param {!Object} object
* @param {boolean=} ownProperties
* @param {boolean=} accessorPropertiesOnly
- * @return {Array.<Object>}
+ * @return {!Array.<!Object>}
*/
_propertyDescriptors: function(object, ownProperties, accessorPropertiesOnly)
{
var descriptors = [];
- var nameProcessed = { __proto__: null };
+ var propertyProcessed = { __proto__: null };
/**
- * @param {Object} o
- * @param {Array.<string>} names
+ * @param {?Object} o
+ * @param {!Array.<string|symbol>} properties
*/
- function process(o, names)
+ function process(o, properties)
{
- for (var i = 0; i < names.length; ++i) {
- var name = names[i];
- if (nameProcessed[name])
+ for (var i = 0; i < properties.length; ++i) {
+ var property = properties[i];
+ if (propertyProcessed[property])
continue;
+ var name = property;
+ if (isSymbol(property))
+ name = injectedScript._describe(property);
+
try {
- nameProcessed[name] = true;
- var descriptor = Object.getOwnPropertyDescriptor(/** @type {!Object} */ (o), name);
+ propertyProcessed[property] = true;
+ var descriptor = nullifyObjectProto(InjectedScriptHost.suppressWarningsAndCall(Object, Object.getOwnPropertyDescriptor, o, property));
if (descriptor) {
if (accessorPropertiesOnly && !("get" in descriptor || "set" in descriptor))
continue;
@@ -440,10 +525,10 @@ InjectedScript.prototype = {
if (accessorPropertiesOnly)
continue;
try {
- descriptor = { name: name, value: o[name], writable: false, configurable: false, enumerable: false};
+ descriptor = { name: name, value: o[property], writable: false, configurable: false, enumerable: false, __proto__: null };
if (o === object)
descriptor.isOwn = true;
- descriptors.push(descriptor);
+ push(descriptors, descriptor);
} catch (e) {
// Silent catch.
}
@@ -452,7 +537,7 @@ InjectedScript.prototype = {
} catch (e) {
if (accessorPropertiesOnly)
continue;
- var descriptor = {};
+ var descriptor = { __proto__: null };
descriptor.value = e;
descriptor.wasThrown = true;
}
@@ -460,7 +545,9 @@ InjectedScript.prototype = {
descriptor.name = name;
if (o === object)
descriptor.isOwn = true;
- descriptors.push(descriptor);
+ if (isSymbol(property))
+ descriptor.symbol = property;
+ push(descriptors, descriptor);
}
}
@@ -468,10 +555,12 @@ InjectedScript.prototype = {
// First call Object.keys() to enforce ordering of the property descriptors.
process(o, Object.keys(/** @type {!Object} */ (o)));
process(o, Object.getOwnPropertyNames(/** @type {!Object} */ (o)));
+ if (Object.getOwnPropertySymbols)
+ process(o, Object.getOwnPropertySymbols(/** @type {!Object} */ (o)));
if (ownProperties) {
if (object.__proto__ && !accessorPropertiesOnly)
- descriptors.push({ name: "__proto__", value: object.__proto__, writable: true, configurable: true, enumerable: false, isOwn: true});
+ push(descriptors, { name: "__proto__", value: object.__proto__, writable: true, configurable: true, enumerable: false, isOwn: true, __proto__: null });
break;
}
}
@@ -495,8 +584,9 @@ InjectedScript.prototype = {
/**
* @param {string} objectId
* @param {string} expression
+ * @param {string} args
* @param {boolean} returnByValue
- * @return {Object|string}
+ * @return {!Object|string}
*/
callFunctionOn: function(objectId, expression, args, returnByValue)
{
@@ -509,13 +599,11 @@ InjectedScript.prototype = {
var resolvedArgs = [];
args = InjectedScriptHost.evaluate(args);
for (var i = 0; i < args.length; ++i) {
- var resolvedCallArgument;
try {
- resolvedCallArgument = this._resolveCallArgument(args[i]);
+ resolvedArgs[i] = this._resolveCallArgument(args[i]);
} catch (e) {
return toString(e);
}
- resolvedArgs.push(resolvedCallArgument)
}
}
@@ -526,7 +614,8 @@ InjectedScript.prototype = {
return "Given expression does not evaluate to a function";
return { wasThrown: false,
- result: this._wrapObject(func.apply(object, resolvedArgs), objectGroup, returnByValue) };
+ result: this._wrapObject(func.apply(object, resolvedArgs), objectGroup, returnByValue),
+ __proto__: null };
} catch (e) {
return this._createThrownValue(e, objectGroup);
}
@@ -534,11 +623,13 @@ InjectedScript.prototype = {
/**
* Resolves a value from CallArgument description.
- * @param {RuntimeAgent.CallArgument} callArgumentJson
+ * @param {!RuntimeAgent.CallArgument} callArgumentJson
* @return {*} resolved value
* @throws {string} error message
*/
- _resolveCallArgument: function(callArgumentJson) {
+ _resolveCallArgument: function(callArgumentJson)
+ {
+ callArgumentJson = nullifyObjectProto(callArgumentJson);
var objectId = callArgumentJson.objectId;
if (objectId) {
var parsedArgId = this._parseObjectId(objectId);
@@ -551,26 +642,32 @@ InjectedScript.prototype = {
return resolvedArg;
} else if ("value" in callArgumentJson) {
- return callArgumentJson.value;
+ var value = callArgumentJson.value;
+ if (callArgumentJson.type === "number" && typeof value !== "number")
+ value = Number(value);
+ return value;
}
return undefined;
},
/**
- * @param {Function} evalFunction
- * @param {Object} object
+ * @param {!Function} evalFunction
+ * @param {!Object} object
+ * @param {string} expression
* @param {string} objectGroup
* @param {boolean} isEvalOnCallFrame
* @param {boolean} injectCommandLineAPI
* @param {boolean} returnByValue
* @param {boolean} generatePreview
- * @return {*}
+ * @param {!Array.<!Object>=} scopeChain
+ * @return {!Object}
*/
- _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, injectCommandLineAPI, returnByValue, generatePreview)
+ _evaluateAndWrap: function(evalFunction, object, expression, objectGroup, isEvalOnCallFrame, injectCommandLineAPI, returnByValue, generatePreview, scopeChain)
{
try {
return { wasThrown: false,
- result: this._wrapObject(this._evaluateOn(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI), objectGroup, returnByValue, generatePreview) };
+ result: this._wrapObject(this._evaluateOn(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI, scopeChain), objectGroup, returnByValue, generatePreview),
+ __proto__: null };
} catch (e) {
return this._createThrownValue(e, objectGroup);
}
@@ -579,7 +676,7 @@ InjectedScript.prototype = {
/**
* @param {*} value
* @param {string} objectGroup
- * @return {Object}
+ * @return {!Object}
*/
_createThrownValue: function(value, objectGroup)
{
@@ -587,44 +684,67 @@ InjectedScript.prototype = {
try {
remoteObject.description = toStringDescription(value);
} catch (e) {}
- return { wasThrown: true, result: remoteObject };
+ return { wasThrown: true, result: remoteObject, __proto__: null };
},
/**
- * @param {Function} evalFunction
- * @param {Object} object
+ * @param {!Function} evalFunction
+ * @param {!Object} object
* @param {string} objectGroup
* @param {string} expression
* @param {boolean} isEvalOnCallFrame
* @param {boolean} injectCommandLineAPI
+ * @param {!Array.<!Object>=} scopeChain
* @return {*}
*/
- _evaluateOn: function(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI)
+ _evaluateOn: function(evalFunction, object, objectGroup, expression, isEvalOnCallFrame, injectCommandLineAPI, scopeChain)
{
// Only install command line api object for the time of evaluation.
// Surround the expression in with statements to inject our command line API so that
// the window object properties still take more precedent than our API functions.
+ injectCommandLineAPI = injectCommandLineAPI && !("__commandLineAPI" in inspectedWindow);
+ var injectScopeChain = scopeChain && scopeChain.length && !("__scopeChainForEval" in inspectedWindow);
+
try {
- if (injectCommandLineAPI && inspectedWindow.console) {
- inspectedWindow.console._commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
- expression = "with ((console && console._commandLineAPI) || {}) {\n" + expression + "\n}";
+ var prefix = "";
+ var suffix = "";
+ if (injectCommandLineAPI) {
+ inspectedWindow.__commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
+ prefix = "with (__commandLineAPI || { __proto__: null }) {";
+ suffix = "}";
}
+ if (injectScopeChain) {
+ inspectedWindow.__scopeChainForEval = scopeChain;
+ for (var i = 0; i < scopeChain.length; ++i) {
+ prefix = "with (__scopeChainForEval[" + i + "] || { __proto__: null }) {" + (suffix ? " " : "") + prefix;
+ if (suffix)
+ suffix += " }";
+ else
+ suffix = "}";
+ }
+ }
+
+ if (prefix)
+ expression = prefix + "\n" + expression + "\n" + suffix;
var result = evalFunction.call(object, expression);
if (objectGroup === "console")
this._lastResult = result;
return result;
} finally {
- if (injectCommandLineAPI && inspectedWindow.console)
- delete inspectedWindow.console._commandLineAPI;
+ if (injectCommandLineAPI)
+ delete inspectedWindow.__commandLineAPI;
+ if (injectScopeChain)
+ delete inspectedWindow.__scopeChainForEval;
}
},
/**
- * @param {Object} callFrame
- * @return {!Array.<InjectedScript.CallFrameProxy>|boolean}
+ * @param {?Object} callFrame
+ * @param {number} asyncOrdinal
+ * @return {!Array.<!InjectedScript.CallFrameProxy>|boolean}
*/
- wrapCallFrames: function(callFrame)
+ wrapCallFrames: function(callFrame, asyncOrdinal)
{
if (!callFrame)
return false;
@@ -632,14 +752,16 @@ InjectedScript.prototype = {
var result = [];
var depth = 0;
do {
- result.push(new InjectedScript.CallFrameProxy(depth++, callFrame));
+ result[depth] = new InjectedScript.CallFrameProxy(depth, callFrame, asyncOrdinal);
callFrame = callFrame.caller;
+ ++depth;
} while (callFrame);
return result;
},
/**
- * @param {Object} topCallFrame
+ * @param {!Object} topCallFrame
+ * @param {!Array.<!Object>} asyncCallStacks
* @param {string} callFrameId
* @param {string} expression
* @param {string} objectGroup
@@ -648,22 +770,25 @@ InjectedScript.prototype = {
* @param {boolean} generatePreview
* @return {*}
*/
- evaluateOnCallFrame: function(topCallFrame, callFrameId, expression, objectGroup, injectCommandLineAPI, returnByValue, generatePreview)
+ evaluateOnCallFrame: function(topCallFrame, asyncCallStacks, callFrameId, expression, objectGroup, injectCommandLineAPI, returnByValue, generatePreview)
{
- var callFrame = this.callFrameForId(topCallFrame, callFrameId);
+ var parsedCallFrameId = nullifyObjectProto(InjectedScriptHost.evaluate("(" + callFrameId + ")"));
+ var callFrame = this._callFrameForParsedId(topCallFrame, parsedCallFrameId, asyncCallStacks);
if (!callFrame)
return "Could not find call frame with given id";
+ if (parsedCallFrameId["asyncOrdinal"])
+ return this._evaluateAndWrap(InjectedScriptHost.evaluate, InjectedScriptHost, expression, objectGroup, false, injectCommandLineAPI, returnByValue, generatePreview, callFrame.scopeChain);
return this._evaluateAndWrap(callFrame.evaluate, callFrame, expression, objectGroup, true, injectCommandLineAPI, returnByValue, generatePreview);
},
/**
- * @param {Object} topCallFrame
+ * @param {!Object} topCallFrame
* @param {string} callFrameId
* @return {*}
*/
restartFrame: function(topCallFrame, callFrameId)
{
- var callFrame = this.callFrameForId(topCallFrame, callFrameId);
+ var callFrame = this._callFrameForId(topCallFrame, callFrameId);
if (!callFrame)
return "Could not find call frame with given id";
var result = callFrame.restart();
@@ -673,13 +798,13 @@ InjectedScript.prototype = {
},
/**
- * @param {Object} topCallFrame
+ * @param {!Object} topCallFrame
* @param {string} callFrameId
* @return {*} a stepIn position array ready for protocol JSON or a string error
*/
getStepInPositions: function(topCallFrame, callFrameId)
{
- var callFrame = this.callFrameForId(topCallFrame, callFrameId);
+ var callFrame = this._callFrameForId(topCallFrame, callFrameId);
if (!callFrame)
return "Could not find call frame with given id";
var stepInPositionsUnpacked = JSON.parse(callFrame.stepInPositions);
@@ -690,7 +815,7 @@ InjectedScript.prototype = {
/**
* Either callFrameId or functionObjectId must be specified.
- * @param {Object} topCallFrame
+ * @param {!Object} topCallFrame
* @param {string|boolean} callFrameId or false
* @param {string|boolean} functionObjectId or false
* @param {number} scopeNumber
@@ -702,16 +827,16 @@ InjectedScript.prototype = {
{
var setter;
if (typeof callFrameId === "string") {
- var callFrame = this.callFrameForId(topCallFrame, callFrameId);
+ var callFrame = this._callFrameForId(topCallFrame, callFrameId);
if (!callFrame)
return "Could not find call frame with given id";
- setter = callFrame.setVariableValue.bind(callFrame);
+ setter = bind(callFrame.setVariableValue, callFrame);
} else {
var parsedFunctionId = this._parseObjectId(/** @type {string} */ (functionObjectId));
var func = this._objectForId(parsedFunctionId);
if (typeof func !== "function")
return "Cannot resolve function by id.";
- setter = InjectedScriptHost.setFunctionVariableValue.bind(InjectedScriptHost, func);
+ setter = bind(InjectedScriptHost.setFunctionVariableValue, InjectedScriptHost, func);
}
var newValueJson;
try {
@@ -734,13 +859,27 @@ InjectedScript.prototype = {
},
/**
- * @param {Object} topCallFrame
+ * @param {!Object} topCallFrame
* @param {string} callFrameId
- * @return {Object}
+ * @return {?Object}
+ */
+ _callFrameForId: function(topCallFrame, callFrameId)
+ {
+ var parsedCallFrameId = nullifyObjectProto(InjectedScriptHost.evaluate("(" + callFrameId + ")"));
+ return this._callFrameForParsedId(topCallFrame, parsedCallFrameId, []);
+ },
+
+ /**
+ * @param {!Object} topCallFrame
+ * @param {!Object} parsedCallFrameId
+ * @param {!Array.<!Object>} asyncCallStacks
+ * @return {?Object}
*/
- callFrameForId: function(topCallFrame, callFrameId)
+ _callFrameForParsedId: function(topCallFrame, parsedCallFrameId, asyncCallStacks)
{
- var parsedCallFrameId = InjectedScriptHost.evaluate("(" + callFrameId + ")");
+ var asyncOrdinal = parsedCallFrameId["asyncOrdinal"]; // 1-based index
+ if (asyncOrdinal)
+ topCallFrame = asyncCallStacks[asyncOrdinal - 1];
var ordinal = parsedCallFrameId["ordinal"];
var callFrame = topCallFrame;
while (--ordinal >= 0 && callFrame)
@@ -749,8 +888,8 @@ InjectedScript.prototype = {
},
/**
- * @param {Object} objectId
- * @return {Object}
+ * @param {!Object} objectId
+ * @return {!Object|symbol}
*/
_objectForId: function(objectId)
{
@@ -759,7 +898,7 @@ InjectedScript.prototype = {
/**
* @param {string} objectId
- * @return {Object}
+ * @return {!Object|symbol}
*/
findObjectById: function(objectId)
{
@@ -769,19 +908,19 @@ InjectedScript.prototype = {
/**
* @param {string} objectId
- * @return {Node}
+ * @return {?Node}
*/
nodeForObjectId: function(objectId)
{
var object = this.findObjectById(objectId);
if (!object || this._subtype(object) !== "node")
return null;
- return /** @type {Node} */ (object);
+ return /** @type {!Node} */ (object);
},
/**
* @param {string} name
- * @return {Object}
+ * @return {!Object}
*/
module: function(name)
{
@@ -791,7 +930,7 @@ InjectedScript.prototype = {
/**
* @param {string} name
* @param {string} source
- * @return {Object}
+ * @return {?Object}
*/
injectModule: function(name, source)
{
@@ -827,7 +966,7 @@ InjectedScript.prototype = {
/**
* @param {*} obj
- * @return {string?}
+ * @return {?string}
*/
_subtype: function(obj)
{
@@ -844,14 +983,8 @@ InjectedScript.prototype = {
if (preciseType)
return preciseType;
- // FireBug's array detection.
- try {
- if (typeof obj.splice === "function" && isFinite(obj.length))
- return "array";
- if (Object.prototype.toString.call(obj) === "[object Arguments]" && isFinite(obj.length)) // arguments.
- return "array";
- } catch (e) {
- }
+ if (isArrayLike(obj))
+ return "array";
// If owning frame has navigated to somewhere else window properties will be undefined.
return null;
@@ -859,14 +992,13 @@ InjectedScript.prototype = {
/**
* @param {*} obj
- * @return {string?}
+ * @return {?string}
*/
_describe: function(obj)
{
if (this.isPrimitiveValue(obj))
return null;
- // Type is object, get subtype.
var subtype = this._subtype(obj);
if (subtype === "regexp")
@@ -901,6 +1033,14 @@ InjectedScript.prototype = {
if (typeof obj === "function")
return toString(obj);
+ if (isSymbol(obj)) {
+ try {
+ return Symbol.prototype.toString.call(obj) || "Symbol";
+ } catch (e) {
+ return "Symbol";
+ }
+ }
+
if (className === "Object") {
// In Chromium DOM wrapper prototypes will have Object as their constructor name,
// get the real DOM wrapper name from the constructor property.
@@ -940,36 +1080,48 @@ InjectedScript.RemoteObject = function(object, objectGroupName, forceValueType,
this.subtype = "null";
// Provide user-friendly number values.
- if (this.type === "number")
+ if (this.type === "number") {
this.description = toStringDescription(object);
+ // Override "value" property for values that can not be JSON-stringified.
+ switch (this.description) {
+ case "NaN":
+ case "Infinity":
+ case "-Infinity":
+ case "-0":
+ this.value = this.description;
+ break;
+ }
+ }
+
return;
}
- object = /** @type {Object} */ (object);
+ object = /** @type {!Object} */ (object);
this.objectId = injectedScript._bind(object, objectGroupName);
var subtype = injectedScript._subtype(object);
if (subtype)
this.subtype = subtype;
- this.className = InjectedScriptHost.internalConstructorName(object);
+ var className = InjectedScriptHost.internalConstructorName(object);
+ if (className)
+ this.className = className;
this.description = injectedScript._describe(object);
if (generatePreview && (this.type === "object" || injectedScript._isHTMLAllCollection(object)))
- this.preview = this._generatePreview(object, undefined, columnNames, isTable, false);
+ this.preview = this._generatePreview(object, undefined, columnNames, isTable);
}
InjectedScript.RemoteObject.prototype = {
/**
- * @param {Object} object
- * @param {Array.<string>=} firstLevelKeys
+ * @param {!Object} object
+ * @param {?Array.<string>=} firstLevelKeys
* @param {?Array.<string>=} secondLevelKeys
* @param {boolean=} isTable
- * @param {boolean=} isTableRow
* @return {!RuntimeAgent.ObjectPreview} preview
*/
- _generatePreview: function(object, firstLevelKeys, secondLevelKeys, isTable, isTableRow)
+ _generatePreview: function(object, firstLevelKeys, secondLevelKeys, isTable)
{
- var preview = {};
+ var preview = { __proto__: null };
preview.lossless = true;
preview.overflow = false;
preview.properties = [];
@@ -977,99 +1129,123 @@ InjectedScript.RemoteObject.prototype = {
var firstLevelKeysCount = firstLevelKeys ? firstLevelKeys.length : 0;
var propertiesThreshold = {
- properties: (isTable || isTableRow) ? 1000 : Math.max(5, firstLevelKeysCount),
- indexes: (isTable || isTableRow) ? 1000 : Math.max(100, firstLevelKeysCount)
+ properties: isTable ? 1000 : max(5, firstLevelKeysCount),
+ indexes: isTable ? 1000 : max(100, firstLevelKeysCount)
};
try {
var descriptors = injectedScript._propertyDescriptors(object);
if (firstLevelKeys) {
- var nameToDescriptors = {};
+ var nameToDescriptors = { __proto__: null };
for (var i = 0; i < descriptors.length; ++i) {
var descriptor = descriptors[i];
nameToDescriptors["#" + descriptor.name] = descriptor;
}
descriptors = [];
for (var i = 0; i < firstLevelKeys.length; ++i)
- descriptors.push(nameToDescriptors["#" + firstLevelKeys[i]]);
+ descriptors[i] = nameToDescriptors["#" + firstLevelKeys[i]];
}
- for (var i = 0; i < descriptors.length; ++i) {
- if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
- break;
-
- var descriptor = descriptors[i];
- if (!descriptor)
- continue;
- if (descriptor.wasThrown) {
- preview.lossless = false;
- continue;
- }
- if (!descriptor.enumerable && !descriptor.isOwn)
- continue;
+ this._appendPropertyDescriptors(preview, descriptors, propertiesThreshold, secondLevelKeys, isTable);
+ if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
+ return preview;
- var name = descriptor.name;
- if (name === "__proto__")
- continue;
- if (this.subtype === "array" && name === "length")
- continue;
+ // Add internal properties to preview.
+ var internalProperties = InjectedScriptHost.getInternalProperties(object) || [];
+ for (var i = 0; i < internalProperties.length; ++i) {
+ internalProperties[i] = nullifyObjectProto(internalProperties[i]);
+ internalProperties[i].enumerable = true;
+ }
+ this._appendPropertyDescriptors(preview, internalProperties, propertiesThreshold, secondLevelKeys, isTable);
- if (!("value" in descriptor)) {
- this._appendPropertyPreview(preview, { name: name, type: "accessor" }, propertiesThreshold);
- continue;
- }
+ } catch (e) {
+ preview.lossless = false;
+ }
- var value = descriptor.value;
- if (value === null) {
- this._appendPropertyPreview(preview, { name: name, type: "object", value: "null" }, propertiesThreshold);
- continue;
- }
+ return preview;
+ },
- const maxLength = 100;
- var type = typeof value;
- if (!descriptor.enumerable && type === "function")
- continue;
- if (type === "undefined" && injectedScript._isHTMLAllCollection(value))
- type = "object";
+ /**
+ * @param {!RuntimeAgent.ObjectPreview} preview
+ * @param {!Array.<Object>} descriptors
+ * @param {!Object} propertiesThreshold
+ * @param {?Array.<string>=} secondLevelKeys
+ * @param {boolean=} isTable
+ */
+ _appendPropertyDescriptors: function(preview, descriptors, propertiesThreshold, secondLevelKeys, isTable)
+ {
+ for (var i = 0; i < descriptors.length; ++i) {
+ if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0)
+ break;
- if (InjectedScript.primitiveTypes[type]) {
- if (type === "string" && value.length > maxLength) {
- value = this._abbreviateString(value, maxLength, true);
- preview.lossless = false;
- }
- this._appendPropertyPreview(preview, { name: name, type: type, value: toStringDescription(value) }, propertiesThreshold);
- continue;
- }
+ var descriptor = descriptors[i];
+ if (!descriptor)
+ continue;
+ if (descriptor.wasThrown) {
+ preview.lossless = false;
+ continue;
+ }
+ if (!descriptor.enumerable && !descriptor.isOwn)
+ continue;
- if (secondLevelKeys === null || secondLevelKeys) {
- var subPreview = this._generatePreview(value, secondLevelKeys || undefined, undefined, false, isTable);
- var property = { name: name, type: type, valuePreview: subPreview };
- this._appendPropertyPreview(preview, property, propertiesThreshold);
- if (!subPreview.lossless)
- preview.lossless = false;
- if (subPreview.overflow)
- preview.overflow = true;
- continue;
- }
+ var name = descriptor.name;
+ if (name === "__proto__")
+ continue;
+ if (this.subtype === "array" && name === "length")
+ continue;
+ if (!("value" in descriptor)) {
preview.lossless = false;
+ this._appendPropertyPreview(preview, { name: name, type: "accessor", __proto__: null }, propertiesThreshold);
+ continue;
+ }
+
+ var value = descriptor.value;
+ if (value === null) {
+ this._appendPropertyPreview(preview, { name: name, type: "object", value: "null", __proto__: null }, propertiesThreshold);
+ continue;
+ }
- var subtype = injectedScript._subtype(value);
- var description = "";
- if (type !== "function")
- description = this._abbreviateString(/** @type {string} */ (injectedScript._describe(value)), maxLength, subtype === "regexp");
+ const maxLength = 100;
+ var type = typeof value;
+ if (!descriptor.enumerable && type === "function")
+ continue;
+ if (type === "undefined" && injectedScript._isHTMLAllCollection(value))
+ type = "object";
+
+ if (InjectedScript.primitiveTypes[type]) {
+ if (type === "string" && value.length > maxLength) {
+ value = this._abbreviateString(value, maxLength, true);
+ preview.lossless = false;
+ }
+ this._appendPropertyPreview(preview, { name: name, type: type, value: toStringDescription(value), __proto__: null }, propertiesThreshold);
+ continue;
+ }
- var property = { name: name, type: type, value: description };
- if (subtype)
- property.subtype = subtype;
+ if (secondLevelKeys === null || secondLevelKeys) {
+ var subPreview = this._generatePreview(value, secondLevelKeys || undefined, undefined, isTable);
+ var property = { name: name, type: type, valuePreview: subPreview, __proto__: null };
this._appendPropertyPreview(preview, property, propertiesThreshold);
+ if (!subPreview.lossless)
+ preview.lossless = false;
+ if (subPreview.overflow)
+ preview.overflow = true;
+ continue;
}
- } catch (e) {
+
preview.lossless = false;
- }
- return preview;
+ var subtype = injectedScript._subtype(value);
+ var description = "";
+ if (type !== "function")
+ description = this._abbreviateString(/** @type {string} */ (injectedScript._describe(value)), maxLength, subtype === "regexp");
+
+ var property = { name: name, type: type, value: description, __proto__: null };
+ if (subtype)
+ property.subtype = subtype;
+ this._appendPropertyPreview(preview, property, propertiesThreshold);
+ }
},
/**
@@ -1087,7 +1263,7 @@ InjectedScript.RemoteObject.prototype = {
preview.overflow = true;
preview.lossless = false;
} else {
- preview.properties.push(property);
+ push(preview.properties, property);
}
},
@@ -1095,7 +1271,7 @@ InjectedScript.RemoteObject.prototype = {
* @param {string} string
* @param {number} maxLength
* @param {boolean=} middle
- * @returns
+ * @return {string}
*/
_abbreviateString: function(string, maxLength, middle)
{
@@ -1107,18 +1283,21 @@ InjectedScript.RemoteObject.prototype = {
return string.substr(0, leftHalf) + "\u2026" + string.substr(string.length - rightHalf, rightHalf);
}
return string.substr(0, maxLength) + "\u2026";
- }
+ },
+
+ __proto__: null
}
/**
* @constructor
* @param {number} ordinal
* @param {!Object} callFrame
+ * @param {number} asyncOrdinal
*/
-InjectedScript.CallFrameProxy = function(ordinal, callFrame)
+InjectedScript.CallFrameProxy = function(ordinal, callFrame, asyncOrdinal)
{
- this.callFrameId = "{\"ordinal\":" + ordinal + ",\"injectedScriptId\":" + injectedScriptId + "}";
+ this.callFrameId = "{\"ordinal\":" + ordinal + ",\"injectedScriptId\":" + injectedScriptId + (asyncOrdinal ? ",\"asyncOrdinal\":" + asyncOrdinal : "") + "}";
this.functionName = (callFrame.type === "function" ? callFrame.functionName : "");
- this.location = { scriptId: toString(callFrame.sourceID), lineNumber: callFrame.line, columnNumber: callFrame.column };
+ this.location = { scriptId: toString(callFrame.sourceID), lineNumber: callFrame.line, columnNumber: callFrame.column, __proto__: null };
this.scopeChain = this._wrapScopeChain(callFrame);
this.this = injectedScript._wrapObject(callFrame.thisObject, "backtrace");
if (callFrame.isAtReturn)
@@ -1127,19 +1306,19 @@ InjectedScript.CallFrameProxy = function(ordinal, callFrame)
InjectedScript.CallFrameProxy.prototype = {
/**
- * @param {Object} callFrame
- * @return {!Array.<DebuggerAgent.Scope>}
+ * @param {!Object} callFrame
+ * @return {!Array.<!DebuggerAgent.Scope>}
*/
_wrapScopeChain: function(callFrame)
{
var scopeChain = callFrame.scopeChain;
var scopeChainProxy = [];
- for (var i = 0; i < scopeChain.length; i++) {
- var scope = InjectedScript.CallFrameProxy._createScopeJson(callFrame.scopeType(i), scopeChain[i], "backtrace");
- scopeChainProxy.push(scope);
- }
+ for (var i = 0; i < scopeChain.length; ++i)
+ scopeChainProxy[i] = InjectedScript.CallFrameProxy._createScopeJson(callFrame.scopeType(i), scopeChain[i], "backtrace");
return scopeChainProxy;
- }
+ },
+
+ __proto__: null
}
/**
@@ -1148,7 +1327,8 @@ InjectedScript.CallFrameProxy.prototype = {
* @param {string} groupId
* @return {!DebuggerAgent.Scope}
*/
-InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeObject, groupId) {
+InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeObject, groupId)
+{
const GLOBAL_SCOPE = 0;
const LOCAL_SCOPE = 1;
const WITH_SCOPE = 2;
@@ -1156,7 +1336,7 @@ InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeOb
const CATCH_SCOPE = 4;
/** @type {!Object.<number, string>} */
- var scopeTypeNames = {};
+ var scopeTypeNames = { __proto__: null };
scopeTypeNames[GLOBAL_SCOPE] = "global";
scopeTypeNames[LOCAL_SCOPE] = "local";
scopeTypeNames[WITH_SCOPE] = "with";
@@ -1165,14 +1345,15 @@ InjectedScript.CallFrameProxy._createScopeJson = function(scopeTypeCode, scopeOb
return {
object: injectedScript._wrapObject(scopeObject, groupId),
- type: /** @type {DebuggerAgent.ScopeType} */ (scopeTypeNames[scopeTypeCode])
+ type: /** @type {!DebuggerAgent.ScopeType} */ (scopeTypeNames[scopeTypeCode]),
+ __proto__: null
};
}
/**
* @constructor
- * @param {CommandLineAPIImpl} commandLineAPIImpl
- * @param {Object} callFrame
+ * @param {!CommandLineAPIImpl} commandLineAPIImpl
+ * @param {?Object} callFrame
*/
function CommandLineAPI(commandLineAPIImpl, callFrame)
{
@@ -1233,12 +1414,14 @@ function CommandLineAPI(commandLineAPIImpl, callFrame)
}
this.$_ = injectedScript._lastResult;
+
+ this.__proto__ = null;
}
// NOTE: Please keep the list of API methods below snchronized to that in WebInspector.RuntimeModel!
// NOTE: Argument names of these methods will be printed in the console, so use pretty names!
/**
- * @type {Array.<string>}
+ * @type {!Array.<string>}
* @const
*/
CommandLineAPI.members_ = [
@@ -1257,7 +1440,8 @@ function CommandLineAPIImpl()
CommandLineAPIImpl.prototype = {
/**
* @param {string} selector
- * @param {Node=} opt_startNode
+ * @param {!Node=} opt_startNode
+ * @return {*}
*/
$: function (selector, opt_startNode)
{
@@ -1269,7 +1453,8 @@ CommandLineAPIImpl.prototype = {
/**
* @param {string} selector
- * @param {Node=} opt_startNode
+ * @param {!Node=} opt_startNode
+ * @return {*}
*/
$$: function (selector, opt_startNode)
{
@@ -1279,7 +1464,7 @@ CommandLineAPIImpl.prototype = {
},
/**
- * @param {Node=} node
+ * @param {!Node=} node
* @return {boolean}
*/
_canQuerySelectorOnNode: function(node)
@@ -1289,7 +1474,8 @@ CommandLineAPIImpl.prototype = {
/**
* @param {string} xpath
- * @param {Node=} opt_startNode
+ * @param {!Node=} opt_startNode
+ * @return {*}
*/
$x: function(xpath, opt_startNode)
{
@@ -1306,47 +1492,65 @@ CommandLineAPIImpl.prototype = {
var nodes = [];
var node;
while (node = result.iterateNext())
- nodes.push(node);
+ push(nodes, node);
return nodes;
}
},
+ /**
+ * @return {*}
+ */
dir: function(var_args)
{
return inspectedWindow.console.dir.apply(inspectedWindow.console, arguments)
},
+ /**
+ * @return {*}
+ */
dirxml: function(var_args)
{
return inspectedWindow.console.dirxml.apply(inspectedWindow.console, arguments)
},
+ /**
+ * @return {!Array.<string>}
+ */
keys: function(object)
{
return Object.keys(object);
},
+ /**
+ * @return {!Array.<*>}
+ */
values: function(object)
{
var result = [];
for (var key in object)
- result.push(object[key]);
+ push(result, object[key]);
return result;
},
+ /**
+ * @return {*}
+ */
profile: function(opt_title)
{
return inspectedWindow.console.profile.apply(inspectedWindow.console, arguments)
},
+ /**
+ * @return {*}
+ */
profileEnd: function(opt_title)
{
return inspectedWindow.console.profileEnd.apply(inspectedWindow.console, arguments)
},
/**
- * @param {Object} object
- * @param {Array.<string>|string=} opt_types
+ * @param {!Object} object
+ * @param {!Array.<string>|string=} opt_types
*/
monitorEvents: function(object, opt_types)
{
@@ -1360,8 +1564,8 @@ CommandLineAPIImpl.prototype = {
},
/**
- * @param {Object} object
- * @param {Array.<string>|string=} opt_types
+ * @param {!Object} object
+ * @param {!Array.<string>|string=} opt_types
*/
unmonitorEvents: function(object, opt_types)
{
@@ -1396,7 +1600,7 @@ CommandLineAPIImpl.prototype = {
}
}
- var hints = { copyToClipboard: true };
+ var hints = { copyToClipboard: true, __proto__: null };
var remoteObject = injectedScript._wrapObject(string, "")
InjectedScriptHost.inspect(remoteObject, hints);
},
@@ -1407,12 +1611,12 @@ CommandLineAPIImpl.prototype = {
},
/**
- * @param {Node} node
- * @return {{type: string, listener: function(), useCapture: boolean, remove: function()}|undefined}
+ * @param {!Node} node
+ * @return {!{type: string, listener: function(), useCapture: boolean, remove: function()}|undefined}
*/
getEventListeners: function(node)
{
- var result = InjectedScriptHost.getEventListeners(node);
+ var result = nullifyObjectProto(InjectedScriptHost.getEventListeners(node));
if (!result)
return result;
/** @this {{type: string, listener: function(), useCapture: boolean}} */
@@ -1445,7 +1649,8 @@ CommandLineAPIImpl.prototype = {
InjectedScriptHost.monitorFunction(fn);
},
- unmonitor: function(fn) {
+ unmonitor: function(fn)
+ {
InjectedScriptHost.unmonitorFunction(fn);
},
@@ -1463,34 +1668,34 @@ CommandLineAPIImpl.prototype = {
},
/**
- * @param {Array.<string>|string=} types
- * @return {Array.<string>}
+ * @param {!Array.<string>|string=} types
+ * @return {!Array.<string>}
*/
_normalizeEventTypes: function(types)
{
if (typeof types === "undefined")
- types = [ "mouse", "key", "touch", "control", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll", "search", "devicemotion", "deviceorientation" ];
+ types = ["mouse", "key", "touch", "control", "load", "unload", "abort", "error", "select", "change", "submit", "reset", "focus", "blur", "resize", "scroll", "search", "devicemotion", "deviceorientation"];
else if (typeof types === "string")
- types = [ types ];
+ types = [types];
var result = [];
- for (var i = 0; i < types.length; i++) {
+ for (var i = 0; i < types.length; ++i) {
if (types[i] === "mouse")
- result.splice(0, 0, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout", "mousewheel");
+ push(result, "mousedown", "mouseup", "click", "dblclick", "mousemove", "mouseover", "mouseout", "mousewheel");
else if (types[i] === "key")
- result.splice(0, 0, "keydown", "keyup", "keypress", "textInput");
+ push(result, "keydown", "keyup", "keypress", "textInput");
else if (types[i] === "touch")
- result.splice(0, 0, "touchstart", "touchmove", "touchend", "touchcancel");
+ push(result, "touchstart", "touchmove", "touchend", "touchcancel");
else if (types[i] === "control")
- result.splice(0, 0, "resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset");
+ push(result, "resize", "scroll", "zoom", "focus", "blur", "select", "change", "submit", "reset");
else
- result.push(types[i]);
+ push(result, types[i]);
}
return result;
},
/**
- * @param {Event} event
+ * @param {!Event} event
*/
_logEvent: function(event)
{
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorAgent.cpp
deleted file mode 100644
index 4ae9a6680e7..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorAgent.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/inspector/InspectorAgent.h"
-
-#include "InspectorFrontend.h"
-#include "bindings/v8/DOMWrapperWorld.h"
-#include "bindings/v8/ScriptController.h"
-#include "core/dom/Document.h"
-#include "core/inspector/InjectedScriptHost.h"
-#include "core/inspector/InjectedScriptManager.h"
-#include "core/inspector/InspectorController.h"
-#include "core/inspector/InspectorState.h"
-#include "core/inspector/InstrumentingAgents.h"
-#include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "wtf/text/StringBuilder.h"
-
-namespace WebCore {
-
-namespace InspectorAgentState {
-static const char inspectorAgentEnabled[] = "inspectorAgentEnabled";
-}
-
-InspectorAgent::InspectorAgent(Page* page, InjectedScriptManager* injectedScriptManager, InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state)
- : InspectorBaseAgent<InspectorAgent>("Inspector", instrumentingAgents, state)
- , m_inspectedPage(page)
- , m_frontend(0)
- , m_injectedScriptManager(injectedScriptManager)
-{
- ASSERT_ARG(page, page);
- m_instrumentingAgents->setInspectorAgent(this);
-}
-
-InspectorAgent::~InspectorAgent()
-{
- m_instrumentingAgents->setInspectorAgent(0);
-}
-
-void InspectorAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
-{
- if (world != mainThreadNormalWorld())
- return;
-
- if (m_injectedScriptForOrigin.isEmpty())
- return;
-
- String origin = frame->document()->securityOrigin()->toRawString();
- String script = m_injectedScriptForOrigin.get(origin);
- if (script.isEmpty())
- return;
- int injectedScriptId = m_injectedScriptManager->injectedScriptIdFor(mainWorldScriptState(frame));
- StringBuilder scriptSource;
- scriptSource.append(script);
- scriptSource.append("(");
- scriptSource.appendNumber(injectedScriptId);
- scriptSource.append(")");
- frame->script().executeScriptInMainWorld(scriptSource.toString());
-}
-
-void InspectorAgent::setFrontend(InspectorFrontend* inspectorFrontend)
-{
- m_frontend = inspectorFrontend;
-}
-
-void InspectorAgent::clearFrontend()
-{
- m_pendingEvaluateTestCommands.clear();
- m_frontend = 0;
- m_injectedScriptManager->discardInjectedScripts();
- ErrorString error;
- disable(&error);
-}
-
-void InspectorAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
-{
- if (loader->frame() != frame->page()->mainFrame())
- return;
-
- m_injectedScriptManager->discardInjectedScripts();
-}
-
-void InspectorAgent::enable(ErrorString*)
-{
- m_state->setBoolean(InspectorAgentState::inspectorAgentEnabled, true);
-
- if (m_pendingInspectData.first)
- inspect(m_pendingInspectData.first, m_pendingInspectData.second);
-
- for (Vector<pair<long, String> >::iterator it = m_pendingEvaluateTestCommands.begin(); m_frontend && it != m_pendingEvaluateTestCommands.end(); ++it)
- m_frontend->inspector()->evaluateForTestInFrontend(static_cast<int>((*it).first), (*it).second);
- m_pendingEvaluateTestCommands.clear();
-}
-
-void InspectorAgent::disable(ErrorString*)
-{
- m_state->setBoolean(InspectorAgentState::inspectorAgentEnabled, false);
-}
-
-void InspectorAgent::reset(ErrorString*)
-{
- m_inspectedPage->inspectorController().reconnectFrontend();
-}
-
-void InspectorAgent::domContentLoadedEventFired(Frame* frame)
-{
- if (frame->page()->mainFrame() != frame)
- return;
-
- m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
-}
-
-void InspectorAgent::evaluateForTestInFrontend(long callId, const String& script)
-{
- if (m_state->getBoolean(InspectorAgentState::inspectorAgentEnabled))
- m_frontend->inspector()->evaluateForTestInFrontend(static_cast<int>(callId), script);
- else
- m_pendingEvaluateTestCommands.append(pair<long, String>(callId, script));
-}
-
-void InspectorAgent::setInjectedScriptForOrigin(const String& origin, const String& source)
-{
- m_injectedScriptForOrigin.set(origin, source);
-}
-
-void InspectorAgent::inspect(PassRefPtr<TypeBuilder::Runtime::RemoteObject> objectToInspect, PassRefPtr<JSONObject> hints)
-{
- if (m_state->getBoolean(InspectorAgentState::inspectorAgentEnabled) && m_frontend) {
- m_frontend->inspector()->inspect(objectToInspect, hints);
- m_pendingInspectData.first = 0;
- m_pendingInspectData.second = 0;
- return;
- }
- m_pendingInspectData.first = objectToInspect;
- m_pendingInspectData.second = hints;
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorAgent.h
deleted file mode 100644
index 789e00220ea..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorAgent.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorAgent_h
-#define InspectorAgent_h
-
-#include "core/inspector/InspectorBaseAgent.h"
-#include "wtf/HashMap.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class DOMWrapperWorld;
-class DocumentLoader;
-class Frame;
-class InjectedScriptManager;
-class InspectorFrontend;
-class InstrumentingAgents;
-class JSONObject;
-class Page;
-
-typedef String ErrorString;
-
-class InspectorAgent : public InspectorBaseAgent<InspectorAgent>, public InspectorBackendDispatcher::InspectorCommandHandler {
- WTF_MAKE_NONCOPYABLE(InspectorAgent);
-public:
- static PassOwnPtr<InspectorAgent> create(Page* page, InjectedScriptManager* injectedScriptManager, InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state)
- {
- return adoptPtr(new InspectorAgent(page, injectedScriptManager, instrumentingAgents, state));
- }
-
- virtual ~InspectorAgent();
-
- // Inspector front-end API.
- void enable(ErrorString*);
- void disable(ErrorString*);
- void reset(ErrorString*);
-
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
-
- void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*);
-
- void didCommitLoad(Frame*, DocumentLoader*);
- void domContentLoadedEventFired(Frame*);
-
- bool hasFrontend() const { return m_frontend; }
-
- // Generic code called from custom implementations.
- void evaluateForTestInFrontend(long testCallId, const String& script);
-
- void setInjectedScriptForOrigin(const String& origin, const String& source);
-
- void inspect(PassRefPtr<TypeBuilder::Runtime::RemoteObject> objectToInspect, PassRefPtr<JSONObject> hints);
-
-private:
- InspectorAgent(Page*, InjectedScriptManager*, InstrumentingAgents*, InspectorCompositeState*);
-
- Page* m_inspectedPage;
- InspectorFrontend* m_frontend;
- InjectedScriptManager* m_injectedScriptManager;
-
- Vector<pair<long, String> > m_pendingEvaluateTestCommands;
- pair<RefPtr<TypeBuilder::Runtime::RemoteObject>, RefPtr<JSONObject> > m_pendingInspectData;
- typedef HashMap<String, String> InjectedScriptForOriginMap;
- InjectedScriptForOriginMap m_injectedScriptForOrigin;
-};
-
-} // namespace WebCore
-
-#endif // !defined(InspectorAgent_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp
index 954c28a71ac..6d8804cb23c 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.cpp
@@ -26,12 +26,12 @@
#include "config.h"
#include "core/inspector/InspectorApplicationCacheAgent.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/InspectorPageAgent.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/NetworkStateNotifier.h"
#include "wtf/text/StringBuilder.h"
@@ -41,8 +41,8 @@ namespace ApplicationCacheAgentState {
static const char applicationCacheAgentEnabled[] = "applicationCacheAgentEnabled";
}
-InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorPageAgent* pageAgent)
- : InspectorBaseAgent<InspectorApplicationCacheAgent>("ApplicationCache", instrumentingAgents, state)
+InspectorApplicationCacheAgent::InspectorApplicationCacheAgent(InspectorPageAgent* pageAgent)
+ : InspectorBaseAgent<InspectorApplicationCacheAgent>("ApplicationCache")
, m_pageAgent(pageAgent)
, m_frontend(0)
{
@@ -76,7 +76,7 @@ void InspectorApplicationCacheAgent::enable(ErrorString*)
networkStateChanged(networkStateNotifier().onLine());
}
-void InspectorApplicationCacheAgent::updateApplicationCacheStatus(Frame* frame)
+void InspectorApplicationCacheAgent::updateApplicationCacheStatus(LocalFrame* frame)
{
DocumentLoader* documentLoader = frame->loader().documentLoader();
if (!documentLoader)
@@ -99,9 +99,11 @@ void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString*, RefPtr
{
result = TypeBuilder::Array<TypeBuilder::ApplicationCache::FrameWithManifest>::create();
- Frame* mainFrame = m_pageAgent->mainFrame();
+ LocalFrame* mainFrame = m_pageAgent->mainFrame();
for (Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext(mainFrame)) {
- DocumentLoader* documentLoader = frame->loader().documentLoader();
+ if (!frame->isLocalFrame())
+ continue;
+ DocumentLoader* documentLoader = toLocalFrame(frame)->loader().documentLoader();
if (!documentLoader)
continue;
@@ -110,7 +112,7 @@ void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString*, RefPtr
String manifestURL = info.m_manifest.string();
if (!manifestURL.isEmpty()) {
RefPtr<TypeBuilder::ApplicationCache::FrameWithManifest> value = TypeBuilder::ApplicationCache::FrameWithManifest::create()
- .setFrameId(m_pageAgent->frameId(frame))
+ .setFrameId(m_pageAgent->frameId(toLocalFrame(frame)))
.setManifestURL(manifestURL)
.setStatus(static_cast<int>(host->status()));
result->addItem(value);
@@ -120,7 +122,7 @@ void InspectorApplicationCacheAgent::getFramesWithManifests(ErrorString*, RefPtr
DocumentLoader* InspectorApplicationCacheAgent::assertFrameWithDocumentLoader(ErrorString* errorString, String frameId)
{
- Frame* frame = m_pageAgent->assertFrame(errorString, frameId);
+ LocalFrame* frame = m_pageAgent->assertFrame(errorString, frameId);
if (!frame)
return 0;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h
index 8b9b9d5051d..c4608a22f36 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorApplicationCacheAgent.h
@@ -25,7 +25,7 @@
#ifndef InspectorApplicationCacheAgent_h
#define InspectorApplicationCacheAgent_h
-#include "InspectorFrontend.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "core/loader/appcache/ApplicationCacheHost.h"
#include "wtf/Noncopyable.h"
@@ -33,39 +33,39 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class InspectorFrontend;
class InspectorPageAgent;
class InstrumentingAgents;
typedef String ErrorString;
-class InspectorApplicationCacheAgent : public InspectorBaseAgent<InspectorApplicationCacheAgent>, public InspectorBackendDispatcher::ApplicationCacheCommandHandler {
+class InspectorApplicationCacheAgent FINAL : public InspectorBaseAgent<InspectorApplicationCacheAgent>, public InspectorBackendDispatcher::ApplicationCacheCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorApplicationCacheAgent); WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<InspectorApplicationCacheAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorPageAgent* pageAgent)
+ static PassOwnPtr<InspectorApplicationCacheAgent> create(InspectorPageAgent* pageAgent)
{
- return adoptPtr(new InspectorApplicationCacheAgent(instrumentingAgents, state, pageAgent));
+ return adoptPtr(new InspectorApplicationCacheAgent(pageAgent));
}
- ~InspectorApplicationCacheAgent() { }
+ virtual ~InspectorApplicationCacheAgent() { }
// InspectorBaseAgent
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
// InspectorInstrumentation API
- void updateApplicationCacheStatus(Frame*);
+ void updateApplicationCacheStatus(LocalFrame*);
void networkStateChanged(bool online);
// ApplicationCache API for InspectorFrontend
- virtual void enable(ErrorString*);
- virtual void getFramesWithManifests(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::ApplicationCache::FrameWithManifest> >& result);
- virtual void getManifestForFrame(ErrorString*, const String& frameId, String* manifestURL);
- virtual void getApplicationCacheForFrame(ErrorString*, const String& frameId, RefPtr<TypeBuilder::ApplicationCache::ApplicationCache>&);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void getFramesWithManifests(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::ApplicationCache::FrameWithManifest> >& result) OVERRIDE;
+ virtual void getManifestForFrame(ErrorString*, const String& frameId, String* manifestURL) OVERRIDE;
+ virtual void getApplicationCacheForFrame(ErrorString*, const String& frameId, RefPtr<TypeBuilder::ApplicationCache::ApplicationCache>&) OVERRIDE;
private:
- InspectorApplicationCacheAgent(InstrumentingAgents*, InspectorCompositeState*, InspectorPageAgent*);
+ InspectorApplicationCacheAgent(InspectorPageAgent*);
PassRefPtr<TypeBuilder::ApplicationCache::ApplicationCache> buildObjectForApplicationCache(const ApplicationCacheHost::ResourceInfoList&, const ApplicationCacheHost::CacheInfo&);
PassRefPtr<TypeBuilder::Array<TypeBuilder::ApplicationCache::ApplicationCacheResource> > buildArrayForApplicationCacheResources(const ApplicationCacheHost::ResourceInfoList&);
PassRefPtr<TypeBuilder::ApplicationCache::ApplicationCacheResource> buildObjectForApplicationCacheResource(const ApplicationCacheHost::ResourceInfo&);
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.cpp
index dd63adbc881..e1b4e8abba2 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.cpp
@@ -36,19 +36,31 @@
namespace WebCore {
-InspectorBaseAgentInterface::InspectorBaseAgentInterface(const String& name, InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState)
- : m_instrumentingAgents(instrumentingAgents)
- , m_state(inspectorState->createAgentState(name))
- , m_name(name)
+InspectorAgent::InspectorAgent(const String& name)
+ : m_name(name)
+{
+}
+
+InspectorAgent::~InspectorAgent()
+{
+}
+
+void InspectorAgent::appended(InstrumentingAgents* instrumentingAgents, InspectorState* inspectorState)
{
+ m_instrumentingAgents = instrumentingAgents;
+ m_state = inspectorState;
+ init();
}
-InspectorBaseAgentInterface::~InspectorBaseAgentInterface()
+InspectorAgentRegistry::InspectorAgentRegistry(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState)
+ : m_instrumentingAgents(instrumentingAgents)
+ , m_inspectorState(inspectorState)
{
}
-void InspectorAgentRegistry::append(PassOwnPtr<InspectorBaseAgentInterface> agent)
+void InspectorAgentRegistry::append(PassOwnPtr<InspectorAgent> agent)
{
+ agent->appended(m_instrumentingAgents, m_inspectorState->createAgentState(agent->name()));
m_agents.append(agent);
}
@@ -82,5 +94,11 @@ void InspectorAgentRegistry::discardAgents()
m_agents[i]->discardAgent();
}
+void InspectorAgentRegistry::flushPendingFrontendMessages()
+{
+ for (size_t i = 0; i < m_agents.size(); i++)
+ m_agents[i]->flushPendingFrontendMessages();
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h
index 0369e097887..3f7bbbf331b 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h
@@ -31,7 +31,7 @@
#ifndef InspectorBaseAgent_h
#define InspectorBaseAgent_h
-#include "InspectorBackendDispatcher.h"
+#include "core/InspectorBackendDispatcher.h"
#include "wtf/Forward.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
@@ -43,18 +43,22 @@ class InspectorCompositeState;
class InspectorState;
class InstrumentingAgents;
-class InspectorBaseAgentInterface {
+class InspectorAgent {
public:
- InspectorBaseAgentInterface(const String&, InstrumentingAgents*, InspectorCompositeState*);
- virtual ~InspectorBaseAgentInterface();
+ explicit InspectorAgent(const String&);
+ virtual ~InspectorAgent();
+ virtual void init() { }
virtual void setFrontend(InspectorFrontend*) { }
virtual void clearFrontend() { }
virtual void restore() { }
virtual void registerInDispatcher(InspectorBackendDispatcher*) = 0;
virtual void discardAgent() { }
+ virtual void didCommitLoadForMainFrame() { }
+ virtual void flushPendingFrontendMessages() { }
String name() { return m_name; }
+ void appended(InstrumentingAgents*, InspectorState*);
protected:
InstrumentingAgents* m_instrumentingAgents;
@@ -66,31 +70,34 @@ private:
class InspectorAgentRegistry {
public:
- void append(PassOwnPtr<InspectorBaseAgentInterface>);
+ InspectorAgentRegistry(InstrumentingAgents*, InspectorCompositeState*);
+ void append(PassOwnPtr<InspectorAgent>);
void setFrontend(InspectorFrontend*);
void clearFrontend();
void restore();
void registerInDispatcher(InspectorBackendDispatcher*);
void discardAgents();
+ void flushPendingFrontendMessages();
private:
- Vector<OwnPtr<InspectorBaseAgentInterface> > m_agents;
+ InstrumentingAgents* m_instrumentingAgents;
+ InspectorCompositeState* m_inspectorState;
+ Vector<OwnPtr<InspectorAgent> > m_agents;
};
template<typename T>
-class InspectorBaseAgent : public InspectorBaseAgentInterface {
+class InspectorBaseAgent : public InspectorAgent {
public:
virtual ~InspectorBaseAgent() { }
- virtual void registerInDispatcher(InspectorBackendDispatcher* dispatcher)
+ virtual void registerInDispatcher(InspectorBackendDispatcher* dispatcher) OVERRIDE FINAL
{
dispatcher->registerAgent(static_cast<T*>(this));
}
protected:
- InspectorBaseAgent(const String& name, InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState)
- : InspectorBaseAgentInterface(name, instrumentingAgents, inspectorState)
+ InspectorBaseAgent(const String& name) : InspectorAgent(name)
{
}
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
index d4bafdf24e2..849b91ad40f 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp
@@ -25,47 +25,42 @@
#include "config.h"
#include "core/inspector/InspectorCSSAgent.h"
-#include "CSSPropertyNames.h"
-#include "FetchInitiatorTypeNames.h"
-#include "InspectorTypeBuilder.h"
-#include "StylePropertyShorthand.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/InspectorTypeBuilder.h"
+#include "core/StylePropertyShorthand.h"
#include "core/css/CSSComputedStyleDeclaration.h"
+#include "core/css/CSSDefaultStyleSheets.h"
#include "core/css/CSSImportRule.h"
#include "core/css/CSSMediaRule.h"
-#include "core/css/CSSParser.h"
#include "core/css/CSSRule.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/MediaList.h"
+#include "core/css/MediaQuery.h"
+#include "core/css/MediaValues.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRule.h"
#include "core/css/StyleSheet.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/StyleSheetList.h"
#include "core/css/resolver/StyleResolver.h"
-#include "core/dom/NamedFlow.h"
-#include "core/dom/NamedFlowCollection.h"
#include "core/dom/Node.h"
-#include "core/dom/NodeList.h"
-#include "core/fetch/CSSStyleSheetResource.h"
-#include "core/fetch/ResourceClient.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/fetch/StyleSheetResourceClient.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLHeadElement.h"
+#include "core/html/VoidCallback.h"
#include "core/inspector/InspectorHistory.h"
#include "core/inspector/InspectorPageAgent.h"
#include "core/inspector/InspectorResourceAgent.h"
+#include "core/inspector/InspectorResourceContentLoader.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderObject.h"
-#include "core/rendering/RenderRegion.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/RenderTextFragment.h"
#include "platform/fonts/Font.h"
@@ -92,28 +87,6 @@ enum ForcePseudoClassFlags {
PseudoVisited = 1 << 3
};
-class StyleSheetAppender {
-public:
- StyleSheetAppender(Vector<CSSStyleSheet*>& result)
- : m_result(result) { }
-
- void run(CSSStyleSheet* styleSheet)
- {
- m_result.append(styleSheet);
- for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
- CSSRule* rule = styleSheet->item(i);
- if (rule->type() == CSSRule::IMPORT_RULE) {
- CSSStyleSheet* importedStyleSheet = toCSSImportRule(rule)->styleSheet();
- if (importedStyleSheet)
- run(importedStyleSheet);
- }
- }
- }
-
-private:
- Vector<CSSStyleSheet*>& m_result;
-};
-
static unsigned computePseudoClassMask(JSONArray* pseudoClassArray)
{
DEFINE_STATIC_LOCAL(String, active, ("active"));
@@ -143,209 +116,74 @@ static unsigned computePseudoClassMask(JSONArray* pseudoClassArray)
return result;
}
-class UpdateRegionLayoutTask {
-public:
- UpdateRegionLayoutTask(InspectorCSSAgent*);
- void scheduleFor(NamedFlow*, int documentNodeId);
- void unschedule(NamedFlow*);
- void reset();
- void onTimer(Timer<UpdateRegionLayoutTask>*);
-
-private:
- InspectorCSSAgent* m_cssAgent;
- Timer<UpdateRegionLayoutTask> m_timer;
- HashMap<NamedFlow*, int> m_namedFlows;
-};
-
-UpdateRegionLayoutTask::UpdateRegionLayoutTask(InspectorCSSAgent* cssAgent)
- : m_cssAgent(cssAgent)
- , m_timer(this, &UpdateRegionLayoutTask::onTimer)
-{
-}
-
-void UpdateRegionLayoutTask::scheduleFor(NamedFlow* namedFlow, int documentNodeId)
-{
- m_namedFlows.add(namedFlow, documentNodeId);
-
- if (!m_timer.isActive())
- m_timer.startOneShot(0);
-}
-
-void UpdateRegionLayoutTask::unschedule(NamedFlow* namedFlow)
-{
- m_namedFlows.remove(namedFlow);
-}
-
-void UpdateRegionLayoutTask::reset()
-{
- m_timer.stop();
- m_namedFlows.clear();
-}
-
-void UpdateRegionLayoutTask::onTimer(Timer<UpdateRegionLayoutTask>*)
-{
- // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed.
- Vector<std::pair<NamedFlow*, int> > namedFlows;
-
- for (HashMap<NamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it)
- namedFlows.append(std::make_pair(it->key, it->value));
-
- for (unsigned i = 0, size = namedFlows.size(); i < size; ++i) {
- NamedFlow* namedFlow = namedFlows.at(i).first;
- int documentNodeId = namedFlows.at(i).second;
-
- if (m_namedFlows.contains(namedFlow)) {
- m_cssAgent->regionLayoutUpdated(namedFlow, documentNodeId);
- m_namedFlows.remove(namedFlow);
- }
- }
-
- if (!m_namedFlows.isEmpty() && !m_timer.isActive())
- m_timer.startOneShot(0);
-}
-
-class ChangeRegionOversetTask {
-public:
- ChangeRegionOversetTask(InspectorCSSAgent*);
- void scheduleFor(NamedFlow*, int documentNodeId);
- void unschedule(NamedFlow*);
- void reset();
- void onTimer(Timer<ChangeRegionOversetTask>*);
-
-private:
- InspectorCSSAgent* m_cssAgent;
- Timer<ChangeRegionOversetTask> m_timer;
- HashMap<NamedFlow*, int> m_namedFlows;
-};
-
-ChangeRegionOversetTask::ChangeRegionOversetTask(InspectorCSSAgent* cssAgent)
- : m_cssAgent(cssAgent)
- , m_timer(this, &ChangeRegionOversetTask::onTimer)
-{
-}
-
-void ChangeRegionOversetTask::scheduleFor(NamedFlow* namedFlow, int documentNodeId)
-{
- m_namedFlows.add(namedFlow, documentNodeId);
-
- if (!m_timer.isActive())
- m_timer.startOneShot(0);
-}
-
-void ChangeRegionOversetTask::unschedule(NamedFlow* namedFlow)
-{
- m_namedFlows.remove(namedFlow);
-}
-
-void ChangeRegionOversetTask::reset()
-{
- m_timer.stop();
- m_namedFlows.clear();
-}
-
-void ChangeRegionOversetTask::onTimer(Timer<ChangeRegionOversetTask>*)
-{
- // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed.
- for (HashMap<NamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it)
- m_cssAgent->regionOversetChanged(it->key, it->value);
-
- m_namedFlows.clear();
-}
-
class InspectorCSSAgent::StyleSheetAction : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(StyleSheetAction);
public:
- StyleSheetAction(const String& name, InspectorStyleSheet* styleSheet)
+ StyleSheetAction(const String& name)
: InspectorHistory::Action(name)
- , m_styleSheet(styleSheet)
{
}
-
-protected:
- RefPtr<InspectorStyleSheet> m_styleSheet;
};
-class InspectorCSSAgent::EnableResourceClient : public StyleSheetResourceClient {
+class InspectorCSSAgent::InspectorResourceContentLoaderCallback FINAL : public VoidCallback {
public:
- EnableResourceClient(InspectorCSSAgent*, const Vector<InspectorStyleSheet*>&, PassRefPtr<EnableCallback>);
-
- virtual void setCSSStyleSheet(const String&, const KURL&, const String&, const CSSStyleSheetResource*) OVERRIDE;
+ InspectorResourceContentLoaderCallback(InspectorCSSAgent*, PassRefPtr<EnableCallback>);
+ virtual void handleEvent() OVERRIDE;
private:
- RefPtr<EnableCallback> m_callback;
InspectorCSSAgent* m_cssAgent;
- int m_pendingResources;
- Vector<InspectorStyleSheet*> m_styleSheets;
+ RefPtr<EnableCallback> m_callback;
};
-InspectorCSSAgent::EnableResourceClient::EnableResourceClient(InspectorCSSAgent* cssAgent, const Vector<InspectorStyleSheet*>& styleSheets, PassRefPtr<EnableCallback> callback)
- : m_callback(callback)
- , m_cssAgent(cssAgent)
- , m_pendingResources(styleSheets.size())
- , m_styleSheets(styleSheets)
+InspectorCSSAgent::InspectorResourceContentLoaderCallback::InspectorResourceContentLoaderCallback(InspectorCSSAgent* cssAgent, PassRefPtr<EnableCallback> callback)
+ : m_cssAgent(cssAgent)
+ , m_callback(callback)
{
- for (size_t i = 0; i < styleSheets.size(); ++i) {
- InspectorStyleSheet* styleSheet = styleSheets.at(i);
- Document* document = styleSheet->ownerDocument();
- FetchRequest request(ResourceRequest(styleSheet->finalURL()), FetchInitiatorTypeNames::internal);
- ResourcePtr<Resource> resource = document->fetcher()->fetchCSSStyleSheet(request);
- resource->addClient(this);
- }
}
-void InspectorCSSAgent::EnableResourceClient::setCSSStyleSheet(const String&, const KURL& url, const String&, const CSSStyleSheetResource* resource)
+void InspectorCSSAgent::InspectorResourceContentLoaderCallback::handleEvent()
{
- const_cast<CSSStyleSheetResource*>(resource)->removeClient(this);
- --m_pendingResources;
- if (m_pendingResources)
+ // enable always succeeds.
+ if (!m_callback->isActive())
return;
- // enable always succeeds.
- if (m_callback->isActive())
- m_cssAgent->wasEnabled(m_callback.release());
- delete this;
+ m_cssAgent->wasEnabled();
+ m_callback->sendSuccess();
}
-class InspectorCSSAgent::SetStyleSheetTextAction : public InspectorCSSAgent::StyleSheetAction {
+class InspectorCSSAgent::SetStyleSheetTextAction FINAL : public InspectorCSSAgent::StyleSheetAction {
WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction);
public:
- SetStyleSheetTextAction(InspectorStyleSheet* styleSheet, const String& text)
- : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText", styleSheet)
+ SetStyleSheetTextAction(InspectorStyleSheetBase* styleSheet, const String& text)
+ : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText")
+ , m_styleSheet(styleSheet)
, m_text(text)
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
if (!m_styleSheet->getText(&m_oldText))
return false;
return redo(exceptionState);
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
- if (m_styleSheet->setText(m_oldText, exceptionState)) {
- m_styleSheet->reparseStyleSheet(m_oldText);
- return true;
- }
- return false;
+ return m_styleSheet->setText(m_oldText, exceptionState);
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
- if (m_styleSheet->setText(m_text, exceptionState)) {
- m_styleSheet->reparseStyleSheet(m_text);
- return true;
- }
- return false;
+ return m_styleSheet->setText(m_text, exceptionState);
}
- virtual String mergeId()
+ virtual String mergeId() OVERRIDE
{
return String::format("SetStyleSheetText %s", m_styleSheet->id().utf8().data());
}
- virtual void merge(PassOwnPtr<Action> action)
+ virtual void merge(PassRefPtrWillBeRawPtr<Action> action) OVERRIDE
{
ASSERT(action->mergeId() == mergeId());
@@ -354,65 +192,17 @@ public:
}
private:
+ RefPtr<InspectorStyleSheetBase> m_styleSheet;
String m_text;
String m_oldText;
};
-class InspectorCSSAgent::SetStyleTextAction : public InspectorCSSAgent::StyleSheetAction {
- WTF_MAKE_NONCOPYABLE(SetStyleTextAction);
-public:
- SetStyleTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& text)
- : InspectorCSSAgent::StyleSheetAction("SetPropertyText", styleSheet)
- , m_cssId(cssId)
- , m_text(text)
- {
- }
-
- virtual String toString()
- {
- return mergeId() + ": " + m_oldText + " -> " + m_text;
- }
-
- virtual bool perform(ExceptionState& exceptionState)
- {
- return redo(exceptionState);
- }
-
- virtual bool undo(ExceptionState& exceptionState)
- {
- String placeholder;
- return m_styleSheet->setStyleText(m_cssId, m_oldText, &placeholder, exceptionState);
- }
-
- virtual bool redo(ExceptionState& exceptionState)
- {
- return m_styleSheet->setStyleText(m_cssId, m_text, &m_oldText, exceptionState);
- }
-
- virtual String mergeId()
- {
- return String::format("SetStyleText %s:%u", m_cssId.styleSheetId().utf8().data(), m_cssId.ordinal());
- }
-
- virtual void merge(PassOwnPtr<Action> action)
- {
- ASSERT(action->mergeId() == mergeId());
-
- SetStyleTextAction* other = static_cast<SetStyleTextAction*>(action.get());
- m_text = other->m_text;
- }
-
-private:
- InspectorCSSId m_cssId;
- String m_text;
- String m_oldText;
-};
-
-class InspectorCSSAgent::SetPropertyTextAction : public InspectorCSSAgent::StyleSheetAction {
+class InspectorCSSAgent::SetPropertyTextAction FINAL : public InspectorCSSAgent::StyleSheetAction {
WTF_MAKE_NONCOPYABLE(SetPropertyTextAction);
public:
- SetPropertyTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, const String& text, bool overwrite)
- : InspectorCSSAgent::StyleSheetAction("SetPropertyText", styleSheet)
+ SetPropertyTextAction(InspectorStyleSheetBase* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, const String& text, bool overwrite)
+ : InspectorCSSAgent::StyleSheetAction("SetPropertyText")
+ , m_styleSheet(styleSheet)
, m_cssId(cssId)
, m_propertyIndex(propertyIndex)
, m_text(text)
@@ -420,39 +210,36 @@ public:
{
}
- virtual String toString()
+ virtual String toString() OVERRIDE
{
- return mergeId() + ": " + m_oldText + " -> " + m_text;
+ return mergeId() + ": " + m_oldStyleText + " -> " + m_text;
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
return redo(exceptionState);
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
String placeholder;
- return m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_overwrite ? m_oldText : "", true, &placeholder, exceptionState);
+ return m_styleSheet->setStyleText(m_cssId, m_oldStyleText);
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
- String oldText;
- bool result = m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_text, m_overwrite, &oldText, exceptionState);
- m_oldText = oldText.stripWhiteSpace();
- // FIXME: remove this once the model handles this case.
- if (!m_oldText.endsWith(';'))
- m_oldText.append(';');
+ if (!m_styleSheet->getStyleText(m_cssId, &m_oldStyleText))
+ return false;
+ bool result = m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_text, m_overwrite, exceptionState);
return result;
}
- virtual String mergeId()
+ virtual String mergeId() OVERRIDE
{
return String::format("SetPropertyText %s:%u:%s", m_styleSheet->id().utf8().data(), m_propertyIndex, m_overwrite ? "true" : "false");
}
- virtual void merge(PassOwnPtr<Action> action)
+ virtual void merge(PassRefPtrWillBeRawPtr<Action> action) OVERRIDE
{
ASSERT(action->mergeId() == mergeId());
@@ -461,56 +248,26 @@ public:
}
private:
+ RefPtr<InspectorStyleSheetBase> m_styleSheet;
InspectorCSSId m_cssId;
unsigned m_propertyIndex;
String m_text;
- String m_oldText;
+ String m_oldStyleText;
bool m_overwrite;
};
-class InspectorCSSAgent::TogglePropertyAction : public InspectorCSSAgent::StyleSheetAction {
- WTF_MAKE_NONCOPYABLE(TogglePropertyAction);
-public:
- TogglePropertyAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, bool disable)
- : InspectorCSSAgent::StyleSheetAction("ToggleProperty", styleSheet)
- , m_cssId(cssId)
- , m_propertyIndex(propertyIndex)
- , m_disable(disable)
- {
- }
-
- virtual bool perform(ExceptionState& exceptionState)
- {
- return redo(exceptionState);
- }
-
- virtual bool undo(ExceptionState& exceptionState)
- {
- return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, !m_disable, exceptionState);
- }
-
- virtual bool redo(ExceptionState& exceptionState)
- {
- return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, m_disable, exceptionState);
- }
-
-private:
- InspectorCSSId m_cssId;
- unsigned m_propertyIndex;
- bool m_disable;
-};
-
-class InspectorCSSAgent::SetRuleSelectorAction : public InspectorCSSAgent::StyleSheetAction {
+class InspectorCSSAgent::SetRuleSelectorAction FINAL : public InspectorCSSAgent::StyleSheetAction {
WTF_MAKE_NONCOPYABLE(SetRuleSelectorAction);
public:
SetRuleSelectorAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& selector)
- : InspectorCSSAgent::StyleSheetAction("SetRuleSelector", styleSheet)
+ : InspectorCSSAgent::StyleSheetAction("SetRuleSelector")
+ , m_styleSheet(styleSheet)
, m_cssId(cssId)
, m_selector(selector)
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
m_oldSelector = m_styleSheet->ruleSelector(m_cssId, exceptionState);
if (exceptionState.hadException())
@@ -518,42 +275,44 @@ public:
return redo(exceptionState);
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
return m_styleSheet->setRuleSelector(m_cssId, m_oldSelector, exceptionState);
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
return m_styleSheet->setRuleSelector(m_cssId, m_selector, exceptionState);
}
private:
+ RefPtr<InspectorStyleSheet> m_styleSheet;
InspectorCSSId m_cssId;
String m_selector;
String m_oldSelector;
};
-class InspectorCSSAgent::AddRuleAction : public InspectorCSSAgent::StyleSheetAction {
+class InspectorCSSAgent::AddRuleAction FINAL : public InspectorCSSAgent::StyleSheetAction {
WTF_MAKE_NONCOPYABLE(AddRuleAction);
public:
AddRuleAction(InspectorStyleSheet* styleSheet, const String& selector)
- : InspectorCSSAgent::StyleSheetAction("AddRule", styleSheet)
+ : InspectorCSSAgent::StyleSheetAction("AddRule")
+ , m_styleSheet(styleSheet)
, m_selector(selector)
{
}
- virtual bool perform(ExceptionState& exceptionState)
+ virtual bool perform(ExceptionState& exceptionState) OVERRIDE
{
return redo(exceptionState);
}
- virtual bool undo(ExceptionState& exceptionState)
+ virtual bool undo(ExceptionState& exceptionState) OVERRIDE
{
return m_styleSheet->deleteRule(m_newId, exceptionState);
}
- virtual bool redo(ExceptionState& exceptionState)
+ virtual bool redo(ExceptionState& exceptionState) OVERRIDE
{
CSSStyleRule* cssStyleRule = m_styleSheet->addRule(m_selector, exceptionState);
if (exceptionState.hadException())
@@ -565,6 +324,7 @@ public:
InspectorCSSId newRuleId() { return m_newId; }
private:
+ RefPtr<InspectorStyleSheet> m_styleSheet;
InspectorCSSId m_newId;
String m_selector;
String m_oldSelector;
@@ -578,34 +338,8 @@ CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(CSSRule* rule)
return toCSSStyleRule(rule);
}
-template <typename CharType, size_t bufferLength>
-static size_t vendorPrefixLowerCase(const CharType* string, size_t stringLength, char (&buffer)[bufferLength])
-{
- static const char lowerCaseOffset = 'a' - 'A';
-
- if (string[0] != '-')
- return 0;
-
- for (size_t i = 0; i < stringLength - 1; i++) {
- CharType c = string[i + 1];
- if (c == '-')
- return i;
- if (i == bufferLength)
- break;
- if (c < 'A' || c > 'z')
- break;
- if (c >= 'a')
- buffer[i] = c;
- else if (c <= 'Z')
- buffer[i] = c + lowerCaseOffset;
- else
- break;
- }
- return 0;
-}
-
-InspectorCSSAgent::InspectorCSSAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorDOMAgent* domAgent, InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent)
- : InspectorBaseAgent<InspectorCSSAgent>("CSS", instrumentingAgents, state)
+InspectorCSSAgent::InspectorCSSAgent(InspectorDOMAgent* domAgent, InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent)
+ : InspectorBaseAgent<InspectorCSSAgent>("CSS")
, m_frontend(0)
, m_domAgent(domAgent)
, m_pageAgent(pageAgent)
@@ -634,6 +368,8 @@ void InspectorCSSAgent::setFrontend(InspectorFrontend* frontend)
void InspectorCSSAgent::clearFrontend()
{
ASSERT(m_frontend);
+ ErrorString error;
+ disable(&error);
m_frontend = 0;
resetNonPersistentData();
}
@@ -647,125 +383,76 @@ void InspectorCSSAgent::discardAgent()
void InspectorCSSAgent::restore()
{
if (m_state->getBoolean(CSSAgentState::cssAgentEnabled))
- wasEnabled(0);
+ wasEnabled();
+}
+
+void InspectorCSSAgent::flushPendingFrontendMessages()
+{
+ if (!m_invalidatedDocuments.size())
+ return;
+ HashSet<Document*> invalidatedDocuments;
+ m_invalidatedDocuments.swap(&invalidatedDocuments);
+ for (HashSet<Document*>::iterator it = invalidatedDocuments.begin(); it != invalidatedDocuments.end(); ++it)
+ updateActiveStyleSheets(*it, ExistingFrontendRefresh);
}
void InspectorCSSAgent::reset()
{
m_idToInspectorStyleSheet.clear();
+ m_idToInspectorStyleSheetForInlineStyle.clear();
m_cssStyleSheetToInspectorStyleSheet.clear();
+ m_documentToCSSStyleSheets.clear();
+ m_invalidatedDocuments.clear();
m_nodeToInspectorStyleSheet.clear();
- m_documentToInspectorStyleSheet.clear();
+ m_documentToViaInspectorStyleSheet.clear();
resetNonPersistentData();
}
void InspectorCSSAgent::resetNonPersistentData()
{
- m_namedFlowCollectionsRequested.clear();
- if (m_updateRegionLayoutTask)
- m_updateRegionLayoutTask->reset();
- if (m_changeRegionOversetTask)
- m_changeRegionOversetTask->reset();
resetPseudoStates();
}
void InspectorCSSAgent::enable(ErrorString*, PassRefPtr<EnableCallback> prpCallback)
{
m_state->setBoolean(CSSAgentState::cssAgentEnabled, true);
-
- Vector<InspectorStyleSheet*> styleSheets;
- collectAllStyleSheets(styleSheets);
-
- // Re-issue stylesheet requets for resources that are no longer in memory cache.
- Vector<InspectorStyleSheet*> styleSheetsToFetch;
- HashSet<String> urlsToFetch;
- for (size_t i = 0; i < styleSheets.size(); ++i) {
- InspectorStyleSheet* styleSheet = styleSheets.at(i);
- String url = styleSheet->finalURL();
- if (urlsToFetch.contains(url))
- continue;
- CSSStyleSheet* pageStyleSheet = styleSheet->pageStyleSheet();
- if (pageStyleSheet->isInline() || !pageStyleSheet->contents()->loadCompleted())
- continue;
- Document* document = styleSheet->ownerDocument();
- if (!document)
- continue;
- Resource* cachedResource = document->fetcher()->cachedResource(url);
- if (cachedResource)
- continue;
- urlsToFetch.add(styleSheet->finalURL());
- styleSheetsToFetch.append(styleSheet);
- }
-
- if (styleSheetsToFetch.isEmpty()) {
- wasEnabled(prpCallback);
+ if (!m_pageAgent->resourceContentLoader()) {
+ wasEnabled();
+ prpCallback->sendSuccess();
return;
}
- new EnableResourceClient(this, styleSheetsToFetch, prpCallback);
+ m_pageAgent->resourceContentLoader()->addListener(adoptPtr(new InspectorCSSAgent::InspectorResourceContentLoaderCallback(this, prpCallback)));
}
-void InspectorCSSAgent::wasEnabled(PassRefPtr<EnableCallback> callback)
+void InspectorCSSAgent::wasEnabled()
{
if (!m_state->getBoolean(CSSAgentState::cssAgentEnabled)) {
// We were disabled while fetching resources.
return;
}
- Vector<InspectorStyleSheet*> styleSheets;
- collectAllStyleSheets(styleSheets);
- for (size_t i = 0; i < styleSheets.size(); ++i)
- m_frontend->styleSheetAdded(styleSheets.at(i)->buildObjectForStyleSheetInfo());
-
- // More styleSheetAdded events will be generated below.
m_instrumentingAgents->setInspectorCSSAgent(this);
Vector<Document*> documents = m_domAgent->documents();
for (Vector<Document*>::iterator it = documents.begin(); it != documents.end(); ++it)
- (*it)->styleEngine()->updateActiveStyleSheets(FullStyleUpdate);
-
- if (callback)
- callback->sendSuccess();
+ updateActiveStyleSheets(*it, InitialFrontendLoad);
}
void InspectorCSSAgent::disable(ErrorString*)
{
+ reset();
m_instrumentingAgents->setInspectorCSSAgent(0);
m_state->setBoolean(CSSAgentState::cssAgentEnabled, false);
}
-void InspectorCSSAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorCSSAgent::didCommitLoadForMainFrame()
{
- if (loader->frame() != frame->page()->mainFrame())
- return;
-
reset();
}
void InspectorCSSAgent::mediaQueryResultChanged()
{
- if (m_frontend)
- m_frontend->mediaQueryResultChanged();
-}
-
-void InspectorCSSAgent::didCreateNamedFlow(Document* document, NamedFlow* namedFlow)
-{
- int documentNodeId = documentNodeWithRequestedFlowsId(document);
- if (!documentNodeId)
- return;
-
- ErrorString errorString;
- m_frontend->namedFlowCreated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
-}
-
-void InspectorCSSAgent::willRemoveNamedFlow(Document* document, NamedFlow* namedFlow)
-{
- int documentNodeId = documentNodeWithRequestedFlowsId(document);
- if (!documentNodeId)
- return;
-
- if (m_updateRegionLayoutTask)
- m_updateRegionLayoutTask->unschedule(namedFlow);
-
- m_frontend->namedFlowRemoved(documentNodeId, namedFlow->name().string());
+ flushPendingFrontendMessages();
+ m_frontend->mediaQueryResultChanged();
}
void InspectorCSSAgent::willMutateRules()
@@ -781,7 +468,7 @@ void InspectorCSSAgent::didMutateRules(CSSStyleSheet* styleSheet)
if (!styleSheetEditInProgress()) {
Document* owner = styleSheet->ownerDocument();
if (owner)
- owner->modifiedStyleSheet(styleSheet, RecalcStyleDeferred, FullStyleUpdate);
+ owner->modifiedStyleSheet(styleSheet, FullStyleUpdate);
}
}
@@ -798,109 +485,82 @@ void InspectorCSSAgent::didMutateStyle(CSSStyleDeclaration* style, bool isInline
CSSStyleSheet* parentSheet = style->parentStyleSheet();
Document* owner = parentSheet ? parentSheet->ownerDocument() : 0;
if (owner)
- owner->modifiedStyleSheet(parentSheet, RecalcStyleDeferred, FullStyleUpdate);
+ owner->modifiedStyleSheet(parentSheet, FullStyleUpdate);
}
}
-void InspectorCSSAgent::didUpdateRegionLayout(Document* document, NamedFlow* namedFlow)
-{
- int documentNodeId = documentNodeWithRequestedFlowsId(document);
- if (!documentNodeId)
- return;
-
- if (!m_updateRegionLayoutTask)
- m_updateRegionLayoutTask = adoptPtr(new UpdateRegionLayoutTask(this));
- m_updateRegionLayoutTask->scheduleFor(namedFlow, documentNodeId);
-}
-
-void InspectorCSSAgent::regionLayoutUpdated(NamedFlow* namedFlow, int documentNodeId)
-{
- if (namedFlow->flowState() == NamedFlow::FlowStateNull)
- return;
-
- ErrorString errorString;
- RefPtr<NamedFlow> protector(namedFlow);
-
- m_frontend->regionLayoutUpdated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
-}
-
-void InspectorCSSAgent::didChangeRegionOverset(Document* document, NamedFlow* namedFlow)
+void InspectorCSSAgent::activeStyleSheetsUpdated(Document* document)
{
- int documentNodeId = documentNodeWithRequestedFlowsId(document);
- if (!documentNodeId)
+ if (styleSheetEditInProgress())
return;
-
- if (!m_changeRegionOversetTask)
- m_changeRegionOversetTask = adoptPtr(new ChangeRegionOversetTask(this));
- m_changeRegionOversetTask->scheduleFor(namedFlow, documentNodeId);
+ m_invalidatedDocuments.add(document);
+ if (m_creatingViaInspectorStyleSheet)
+ flushPendingFrontendMessages();
}
-void InspectorCSSAgent::regionOversetChanged(NamedFlow* namedFlow, int documentNodeId)
+void InspectorCSSAgent::updateActiveStyleSheets(Document* document, StyleSheetsUpdateType styleSheetsUpdateType)
{
- if (namedFlow->flowState() == NamedFlow::FlowStateNull)
- return;
-
- ErrorString errorString;
- RefPtr<NamedFlow> protector(namedFlow);
-
- m_frontend->regionOversetChanged(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
+ Vector<CSSStyleSheet*> newSheetsVector;
+ InspectorCSSAgent::collectAllDocumentStyleSheets(document, newSheetsVector);
+ setActiveStyleSheets(document, newSheetsVector, styleSheetsUpdateType);
}
-void InspectorCSSAgent::activeStyleSheetsUpdated(Document* document, const StyleSheetVector& newSheets)
+void InspectorCSSAgent::setActiveStyleSheets(Document* document, const Vector<CSSStyleSheet*>& allSheetsVector, StyleSheetsUpdateType styleSheetsUpdateType)
{
- if (styleSheetEditInProgress())
- return;
+ bool isInitialFrontendLoad = styleSheetsUpdateType == InitialFrontendLoad;
- HashSet<CSSStyleSheet*> removedSheets;
- for (CSSStyleSheetToInspectorStyleSheet::iterator it = m_cssStyleSheetToInspectorStyleSheet.begin(); it != m_cssStyleSheetToInspectorStyleSheet.end(); ++it) {
- if (it->value->canBind() && (!it->key->ownerDocument() || it->key->ownerDocument() == document))
- removedSheets.add(it->key);
+ HashSet<CSSStyleSheet*>* documentCSSStyleSheets = m_documentToCSSStyleSheets.get(document);
+ if (!documentCSSStyleSheets) {
+ documentCSSStyleSheets = new HashSet<CSSStyleSheet*>();
+ OwnPtr<HashSet<CSSStyleSheet*> > documentCSSStyleSheetsPtr = adoptPtr(documentCSSStyleSheets);
+ m_documentToCSSStyleSheets.set(document, documentCSSStyleSheetsPtr.release());
}
- Vector<CSSStyleSheet*> newSheetsVector;
- for (size_t i = 0, size = newSheets.size(); i < size; ++i) {
- StyleSheet* newSheet = newSheets.at(i).get();
- if (newSheet->isCSSStyleSheet()) {
- StyleSheetAppender appender(newSheetsVector);
- appender.run(toCSSStyleSheet(newSheet));
+ HashSet<CSSStyleSheet*> removedSheets(*documentCSSStyleSheets);
+ Vector<CSSStyleSheet*> addedSheets;
+ for (Vector<CSSStyleSheet*>::const_iterator it = allSheetsVector.begin(); it != allSheetsVector.end(); ++it) {
+ CSSStyleSheet* cssStyleSheet = *it;
+ if (removedSheets.contains(cssStyleSheet)) {
+ removedSheets.remove(cssStyleSheet);
+ if (isInitialFrontendLoad)
+ addedSheets.append(cssStyleSheet);
+ } else {
+ addedSheets.append(cssStyleSheet);
}
}
- HashSet<CSSStyleSheet*> addedSheets;
- for (size_t i = 0; i < newSheetsVector.size(); ++i) {
- CSSStyleSheet* newCSSSheet = newSheetsVector.at(i);
- if (removedSheets.contains(newCSSSheet))
- removedSheets.remove(newCSSSheet);
- else
- addedSheets.add(newCSSSheet);
- }
-
for (HashSet<CSSStyleSheet*>::iterator it = removedSheets.begin(); it != removedSheets.end(); ++it) {
- RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(*it);
+ CSSStyleSheet* cssStyleSheet = *it;
+ RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(cssStyleSheet);
ASSERT(inspectorStyleSheet);
+
+ documentCSSStyleSheets->remove(cssStyleSheet);
if (m_idToInspectorStyleSheet.contains(inspectorStyleSheet->id())) {
String id = unbindStyleSheet(inspectorStyleSheet.get());
- if (m_frontend)
+ if (m_frontend && !isInitialFrontendLoad)
m_frontend->styleSheetRemoved(id);
}
}
- for (HashSet<CSSStyleSheet*>::iterator it = addedSheets.begin(); it != addedSheets.end(); ++it) {
- if (!m_cssStyleSheetToInspectorStyleSheet.contains(*it)) {
- InspectorStyleSheet* newStyleSheet = bindStyleSheet(*it);
+ for (Vector<CSSStyleSheet*>::iterator it = addedSheets.begin(); it != addedSheets.end(); ++it) {
+ CSSStyleSheet* cssStyleSheet = *it;
+ bool isNew = isInitialFrontendLoad || !m_cssStyleSheetToInspectorStyleSheet.contains(cssStyleSheet);
+ if (isNew) {
+ InspectorStyleSheet* newStyleSheet = bindStyleSheet(cssStyleSheet);
+ documentCSSStyleSheets->add(cssStyleSheet);
if (m_frontend)
m_frontend->styleSheetAdded(newStyleSheet->buildObjectForStyleSheetInfo());
}
}
+
+ if (documentCSSStyleSheets->isEmpty())
+ m_documentToCSSStyleSheets.remove(document);
}
-void InspectorCSSAgent::frameDetachedFromParent(Frame* frame)
+void InspectorCSSAgent::documentDetached(Document* document)
{
- Document* document = frame->document();
- if (!document)
- return;
- StyleSheetVector newSheets;
- activeStyleSheetsUpdated(document, newSheets);
+ m_invalidatedDocuments.remove(document);
+ setActiveStyleSheets(document, Vector<CSSStyleSheet*>(), ExistingFrontendRefresh);
}
bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoType)
@@ -931,16 +591,38 @@ bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoTy
}
}
+void InspectorCSSAgent::getMediaQueries(ErrorString* errorString, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> >& medias)
+{
+ medias = TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>::create();
+ for (IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.begin(); it != m_idToInspectorStyleSheet.end(); ++it) {
+ RefPtr<InspectorStyleSheet> styleSheet = it->value;
+ collectMediaQueriesFromStyleSheet(styleSheet->pageStyleSheet(), medias.get());
+ const CSSRuleVector& flatRules = styleSheet->flatRules();
+ for (unsigned i = 0; i < flatRules.size(); ++i) {
+ CSSRule* rule = flatRules.at(i).get();
+ if (rule->type() == CSSRule::MEDIA_RULE)
+ collectMediaQueriesFromRule(rule, medias.get());
+ }
+ }
+}
+
void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> >& pseudoIdMatches, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries)
{
Element* element = elementForId(errorString, nodeId);
- if (!element)
+ if (!element) {
+ *errorString = "Node not found";
return;
+ }
Element* originalElement = element;
PseudoId elementPseudoId = element->pseudoId();
- if (elementPseudoId)
+ if (elementPseudoId) {
element = element->parentOrShadowHostElement();
+ if (!element) {
+ *errorString = "Pseudo element has no parent";
+ return;
+ }
+ }
Document* ownerDocument = element->ownerDocument();
// A non-active document has no styles.
@@ -953,19 +635,19 @@ void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int no
// Matched rules.
StyleResolver& styleResolver = ownerDocument->ensureStyleResolver();
- // FIXME: This code should not pass DoNotIncludeStyleSheetInCSSOMWrapper. All CSSOMWrappers should always have a parent sheet or rule.
- RefPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules, DoNotIncludeStyleSheetInCSSOMWrapper);
- matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), styleResolver, originalElement);
+
+ RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules);
+ matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), originalElement);
// Pseudo elements.
if (!elementPseudoId && (!includePseudo || *includePseudo)) {
RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> > pseudoElements = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches>::create();
for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
- RefPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules, DoNotIncludeStyleSheetInCSSOMWrapper);
+ RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules);
if (matchedRules && matchedRules->length()) {
RefPtr<TypeBuilder::CSS::PseudoIdMatches> matches = TypeBuilder::CSS::PseudoIdMatches::create()
.setPseudoId(static_cast<int>(pseudoId))
- .setMatches(buildArrayForMatchedRuleList(matchedRules.get(), styleResolver, element));
+ .setMatches(buildArrayForMatchedRuleList(matchedRules.get(), element));
pseudoElements->addItem(matches.release());
}
}
@@ -979,9 +661,9 @@ void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int no
Element* parentElement = element->parentElement();
while (parentElement) {
StyleResolver& parentStyleResolver = parentElement->ownerDocument()->ensureStyleResolver();
- RefPtr<CSSRuleList> parentMatchedRules = parentStyleResolver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules, DoNotIncludeStyleSheetInCSSOMWrapper);
+ RefPtrWillBeRawPtr<CSSRuleList> parentMatchedRules = parentStyleResolver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules);
RefPtr<TypeBuilder::CSS::InheritedStyleEntry> entry = TypeBuilder::CSS::InheritedStyleEntry::create()
- .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules.get(), styleResolver, parentElement));
+ .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules.get(), parentElement));
if (parentElement->style() && parentElement->style()->length()) {
InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement);
if (styleSheet)
@@ -1008,7 +690,7 @@ void InspectorCSSAgent::getInlineStylesForNode(ErrorString* errorString, int nod
inlineStyle = styleSheet->buildObjectForStyle(element->style());
RefPtr<TypeBuilder::CSS::CSSStyle> attributes = buildObjectForAttributesStyle(element);
- attributesStyle = attributes ? attributes.release() : 0;
+ attributesStyle = attributes ? attributes.release() : nullptr;
}
void InspectorCSSAgent::getComputedStyleForNode(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >& style)
@@ -1017,7 +699,7 @@ void InspectorCSSAgent::getComputedStyleForNode(ErrorString* errorString, int no
if (!node)
return;
- RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(node, true);
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(node, true);
RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0);
style = inspectorStyle->buildArrayForComputedStyle();
}
@@ -1047,7 +729,7 @@ void InspectorCSSAgent::getPlatformFontsForNode(ErrorString* errorString, int no
if (!node)
return;
- RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(node, true);
+ RefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(node, true);
*cssFamilyName = computedStyleInfo->getPropertyValue(CSSPropertyFontFamily);
Vector<Node*> textNodes;
@@ -1068,8 +750,8 @@ void InspectorCSSAgent::getPlatformFontsForNode(ErrorString* errorString, int no
if (renderer->isTextFragment()) {
RenderTextFragment* textFragment = toRenderTextFragment(renderer);
if (textFragment->firstLetter()) {
- RenderObject* firstLetter = textFragment->firstLetter();
- for (RenderObject* current = firstLetter->firstChild(); current; current = current->nextSibling()) {
+ RenderBoxModelObject* firstLetter = textFragment->firstLetter();
+ for (RenderObject* current = firstLetter->slowFirstChild(); current; current = current->nextSibling()) {
if (current->isText())
collectPlatformFontsForRenderer(toRenderText(current), &fontStats);
}
@@ -1086,37 +768,9 @@ void InspectorCSSAgent::getPlatformFontsForNode(ErrorString* errorString, int no
}
}
-void InspectorCSSAgent::getAllStyleSheets(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSStyleSheetHeader> >& styleInfos)
-{
- styleInfos = TypeBuilder::Array<TypeBuilder::CSS::CSSStyleSheetHeader>::create();
- Vector<InspectorStyleSheet*> styleSheets;
- collectAllStyleSheets(styleSheets);
- for (size_t i = 0; i < styleSheets.size(); ++i)
- styleInfos->addItem(styleSheets.at(i)->buildObjectForStyleSheetInfo());
-}
-
-void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr<TypeBuilder::CSS::CSSStyleSheetBody>& styleSheetObject)
-{
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
- if (!inspectorStyleSheet)
- return;
-
- Document* doc = inspectorStyleSheet->pageStyleSheet() ? inspectorStyleSheet->pageStyleSheet()->ownerDocument() : 0;
- if (!doc)
- return;
-
- RefPtr<TypeBuilder::CSS::CSSStyleSheetBody> result = TypeBuilder::CSS::CSSStyleSheetBody::create()
- .setStyleSheetId(styleSheetId)
- .setRules(buildArrayForRuleList(inspectorStyleSheet->pageStyleSheet()->rules().get(), doc->ensureStyleResolver()));
-
- bool success = inspectorStyleSheet->fillObjectForStyleSheet(result);
- if (success)
- styleSheetObject = result;
-}
-
void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* result)
{
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
+ InspectorStyleSheetBase* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
if (!inspectorStyleSheet)
return;
@@ -1125,75 +779,97 @@ void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String
void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text)
{
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
- if (!inspectorStyleSheet)
+ InspectorStyleSheetBase* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
+ if (!inspectorStyleSheet) {
+ *errorString = "Style sheet with id " + styleSheetId + " not found";
return;
+ }
TrackExceptionState exceptionState;
- m_domAgent->history()->perform(adoptPtr(new SetStyleSheetTextAction(inspectorStyleSheet, text)), exceptionState);
+ m_domAgent->history()->perform(adoptRefWillBeNoop(new SetStyleSheetTextAction(inspectorStyleSheet, text)), exceptionState);
*errorString = InspectorDOMAgent::toErrorString(exceptionState);
}
-void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtr<JSONObject>& fullStyleId, const String& text, RefPtr<TypeBuilder::CSS::CSSStyle>& result)
+static bool extractRangeComponent(ErrorString* errorString, const RefPtr<JSONObject>& range, const String& component, unsigned& result)
{
- InspectorCSSId compoundId(fullStyleId);
- ASSERT(!compoundId.isEmpty());
-
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
- if (!inspectorStyleSheet)
- return;
-
- TrackExceptionState exceptionState;
- m_domAgent->history()->perform(adoptPtr(new SetStyleTextAction(inspectorStyleSheet, compoundId, text)), exceptionState);
- if (!exceptionState.hadException())
- result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
- *errorString = InspectorDOMAgent::toErrorString(exceptionState);
+ int parsedValue;
+ if (!range->getNumber(component, &parsedValue) || parsedValue < 0) {
+ *errorString = "range." + component + " must be a non-negative integer";
+ return false;
+ }
+ result = parsedValue;
+ return true;
}
-void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const RefPtr<JSONObject>& fullStyleId, int propertyIndex, const String& text, bool overwrite, RefPtr<TypeBuilder::CSS::CSSStyle>& result)
+static bool jsonRangeToSourceRange(ErrorString* errorString, InspectorStyleSheetBase* inspectorStyleSheet, const RefPtr<JSONObject>& range, SourceRange* sourceRange)
{
- InspectorCSSId compoundId(fullStyleId);
- ASSERT(!compoundId.isEmpty());
+ unsigned startLineNumber;
+ unsigned startColumn;
+ unsigned endLineNumber;
+ unsigned endColumn;
+ if (!extractRangeComponent(errorString, range, "startLine", startLineNumber)
+ || !extractRangeComponent(errorString, range, "startColumn", startColumn)
+ || !extractRangeComponent(errorString, range, "endLine", endLineNumber)
+ || !extractRangeComponent(errorString, range, "endColumn", endColumn))
+ return false;
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
- if (!inspectorStyleSheet)
- return;
+ unsigned startOffset;
+ unsigned endOffset;
+ bool success = inspectorStyleSheet->lineNumberAndColumnToOffset(startLineNumber, startColumn, &startOffset)
+ && inspectorStyleSheet->lineNumberAndColumnToOffset(endLineNumber, endColumn, &endOffset);
+ if (!success) {
+ *errorString = "Specified range is out of bounds";
+ return false;
+ }
- TrackExceptionState exceptionState;
- bool success = m_domAgent->history()->perform(adoptPtr(new SetPropertyTextAction(inspectorStyleSheet, compoundId, propertyIndex, text, overwrite)), exceptionState);
- if (success)
- result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
- *errorString = InspectorDOMAgent::toErrorString(exceptionState);
+ if (startOffset > endOffset) {
+ *errorString = "Range start must not succeed its end";
+ return false;
+ }
+ sourceRange->start = startOffset;
+ sourceRange->end = endOffset;
+ return true;
}
-void InspectorCSSAgent::toggleProperty(ErrorString* errorString, const RefPtr<JSONObject>& fullStyleId, int propertyIndex, bool disable, RefPtr<TypeBuilder::CSS::CSSStyle>& result)
+void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& text, RefPtr<TypeBuilder::CSS::CSSStyle>& result)
{
- InspectorCSSId compoundId(fullStyleId);
- ASSERT(!compoundId.isEmpty());
-
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
+ InspectorStyleSheetBase* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
if (!inspectorStyleSheet)
return;
+ SourceRange propertyRange;
+ if (!jsonRangeToSourceRange(errorString, inspectorStyleSheet, range, &propertyRange))
+ return;
+ InspectorCSSId compoundId;
+ unsigned propertyIndex;
+ bool overwrite;
+ if (!inspectorStyleSheet->findPropertyByRange(propertyRange, &compoundId, &propertyIndex, &overwrite)) {
+ *errorString = "Source range didn't match any existing property source range nor any property insertion point";
+ return;
+ }
TrackExceptionState exceptionState;
- bool success = m_domAgent->history()->perform(adoptPtr(new TogglePropertyAction(inspectorStyleSheet, compoundId, propertyIndex, disable)), exceptionState);
+ bool success = m_domAgent->history()->perform(adoptRefWillBeNoop(new SetPropertyTextAction(inspectorStyleSheet, compoundId, propertyIndex, text, overwrite)), exceptionState);
if (success)
result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
*errorString = InspectorDOMAgent::toErrorString(exceptionState);
}
-void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const RefPtr<JSONObject>& fullRuleId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result)
+void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result)
{
- InspectorCSSId compoundId(fullRuleId);
- ASSERT(!compoundId.isEmpty());
-
- InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
+ InspectorStyleSheet* inspectorStyleSheet = assertInspectorStyleSheetForId(errorString, styleSheetId);
if (!inspectorStyleSheet)
return;
+ SourceRange selectorRange;
+ if (!jsonRangeToSourceRange(errorString, inspectorStyleSheet, range, &selectorRange))
+ return;
+ InspectorCSSId compoundId;
+ if (!inspectorStyleSheet->findRuleBySelectorRange(selectorRange, &compoundId)) {
+ *errorString = "Source range didn't match any rule selector source range";
+ return;
+ }
TrackExceptionState exceptionState;
- bool success = m_domAgent->history()->perform(adoptPtr(new SetRuleSelectorAction(inspectorStyleSheet, compoundId, selector)), exceptionState);
-
+ bool success = m_domAgent->history()->perform(adoptRefWillBeNoop(new SetRuleSelectorAction(inspectorStyleSheet, compoundId, selector)), exceptionState);
if (success) {
CSSStyleRule* rule = inspectorStyleSheet->ruleForId(compoundId);
result = inspectorStyleSheet->buildObjectForRule(rule, buildMediaListChain(rule));
@@ -1201,56 +877,50 @@ void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const RefPtr<J
*errorString = InspectorDOMAgent::toErrorString(exceptionState);
}
-void InspectorCSSAgent::addRule(ErrorString* errorString, const int contextNodeId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result)
+void InspectorCSSAgent::createStyleSheet(ErrorString* errorString, const String& frameId, TypeBuilder::CSS::StyleSheetId* outStyleSheetId)
{
- Node* node = m_domAgent->assertNode(errorString, contextNodeId);
- if (!node)
+ LocalFrame* frame = m_pageAgent->frameForId(frameId);
+ if (!frame) {
+ *errorString = "Frame not found";
+ return;
+ }
+
+ Document* document = frame->document();
+ if (!document) {
+ *errorString = "Frame does not have a document";
return;
+ }
- InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(&node->document(), true);
+ InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(document, true);
if (!inspectorStyleSheet) {
*errorString = "No target stylesheet found";
return;
}
+ updateActiveStyleSheets(document, ExistingFrontendRefresh);
+
+ *outStyleSheetId = inspectorStyleSheet->id();
+}
+
+void InspectorCSSAgent::addRule(ErrorString* errorString, const String& styleSheetId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result)
+{
+ InspectorStyleSheet* inspectorStyleSheet = assertInspectorStyleSheetForId(errorString, styleSheetId);
+ if (!inspectorStyleSheet)
+ return;
+
TrackExceptionState exceptionState;
- OwnPtr<AddRuleAction> action = adoptPtr(new AddRuleAction(inspectorStyleSheet, selector));
- AddRuleAction* rawAction = action.get();
- bool success = m_domAgent->history()->perform(action.release(), exceptionState);
+ RefPtrWillBeRawPtr<AddRuleAction> action = adoptRefWillBeNoop(new AddRuleAction(inspectorStyleSheet, selector));
+ bool success = m_domAgent->history()->perform(action, exceptionState);
if (!success) {
*errorString = InspectorDOMAgent::toErrorString(exceptionState);
return;
}
- InspectorCSSId ruleId = rawAction->newRuleId();
+ InspectorCSSId ruleId = action->newRuleId();
CSSStyleRule* rule = inspectorStyleSheet->ruleForId(ruleId);
result = inspectorStyleSheet->buildObjectForRule(rule, buildMediaListChain(rule));
}
-void InspectorCSSAgent::getSupportedCSSProperties(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSPropertyInfo> >& cssProperties)
-{
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSPropertyInfo> > properties = TypeBuilder::Array<TypeBuilder::CSS::CSSPropertyInfo>::create();
- for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) {
- CSSPropertyID id = convertToCSSPropertyID(i);
- RefPtr<TypeBuilder::CSS::CSSPropertyInfo> property = TypeBuilder::CSS::CSSPropertyInfo::create()
- .setName(getPropertyNameString(id));
-
- const StylePropertyShorthand& shorthand = shorthandForProperty(id);
- if (!shorthand.length()) {
- properties->addItem(property.release());
- continue;
- }
- RefPtr<TypeBuilder::Array<String> > longhands = TypeBuilder::Array<String>::create();
- for (unsigned j = 0; j < shorthand.length(); ++j) {
- CSSPropertyID longhandID = shorthand.properties()[j];
- longhands->addItem(getPropertyNameString(longhandID));
- }
- property->setLonghands(longhands);
- properties->addItem(property.release());
- }
- cssProperties = properties.release();
-}
-
void InspectorCSSAgent::forcePseudoState(ErrorString* errorString, int nodeId, const RefPtr<JSONArray>& forcedPseudoClasses)
{
Element* element = m_domAgent->assertElement(errorString, nodeId);
@@ -1268,24 +938,7 @@ void InspectorCSSAgent::forcePseudoState(ErrorString* errorString, int nodeId, c
m_nodeIdToForcedPseudoState.set(nodeId, forcedPseudoState);
else
m_nodeIdToForcedPseudoState.remove(nodeId);
- element->ownerDocument()->setNeedsStyleRecalc();
-}
-
-void InspectorCSSAgent::getNamedFlowCollection(ErrorString* errorString, int documentNodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::NamedFlow> >& result)
-{
- Document* document = m_domAgent->assertDocument(errorString, documentNodeId);
- if (!document)
- return;
-
- m_namedFlowCollectionsRequested.add(documentNodeId);
-
- Vector<RefPtr<NamedFlow> > namedFlowsVector = document->namedFlows()->namedFlows();
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::NamedFlow> > namedFlows = TypeBuilder::Array<TypeBuilder::CSS::NamedFlow>::create();
-
- for (Vector<RefPtr<NamedFlow> >::iterator it = namedFlowsVector.begin(); it != namedFlowsVector.end(); ++it)
- namedFlows->addItem(buildObjectForNamedFlow(errorString, it->get(), documentNodeId));
-
- result = namedFlows.release();
+ element->ownerDocument()->setNeedsStyleRecalc(SubtreeStyleChange);
}
PassRefPtr<TypeBuilder::CSS::CSSMedia> InspectorCSSAgent::buildMediaObject(const MediaList* media, MediaListSource mediaListSource, const String& sourceURL, CSSStyleSheet* parentStyleSheet)
@@ -1307,14 +960,50 @@ PassRefPtr<TypeBuilder::CSS::CSSMedia> InspectorCSSAgent::buildMediaObject(const
break;
}
+ const MediaQuerySet* queries = media->queries();
+ const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& queryVector = queries->queryVector();
+ bool hasMediaQueryItems = false;
+ RefPtr<TypeBuilder::Array<TypeBuilder::Array<TypeBuilder::CSS::MediaQueryExpression> > > mediaListArray = TypeBuilder::Array<TypeBuilder::Array<TypeBuilder::CSS::MediaQueryExpression> >::create();
+ for (size_t i = 0; i < queryVector.size(); ++i) {
+ MediaQuery* query = queryVector.at(i).get();
+ const ExpressionHeapVector& expressions = query->expressions();
+ RefPtr<TypeBuilder::Array<TypeBuilder::CSS::MediaQueryExpression> > expressionArray = TypeBuilder::Array<TypeBuilder::CSS::MediaQueryExpression>::create();
+ bool hasExpressionItems = false;
+ for (size_t j = 0; j < expressions.size(); ++j) {
+ MediaQueryExp* mediaQueryExp = expressions.at(j).get();
+ MediaQueryExpValue expValue = mediaQueryExp->expValue();
+ if (!expValue.isValue)
+ continue;
+ const char* valueName = CSSPrimitiveValue::unitTypeToString(expValue.unit);
+ RefPtr<TypeBuilder::CSS::MediaQueryExpression> mediaQueryExpression = TypeBuilder::CSS::MediaQueryExpression::create()
+ .setValue(expValue.value)
+ .setUnit(String(valueName))
+ .setFeature(mediaQueryExp->mediaFeature());
+ RefPtr<MediaValues> mediaValues = MediaValues::createDynamicIfFrameExists(parentStyleSheet->ownerDocument()->frame());
+ int computedLength;
+ if (mediaValues->computeLength(expValue.value, expValue.unit, computedLength))
+ mediaQueryExpression->setComputedLength(computedLength);
+
+ expressionArray->addItem(mediaQueryExpression);
+ hasExpressionItems = true;
+ }
+ if (hasExpressionItems) {
+ mediaListArray->addItem(expressionArray);
+ hasMediaQueryItems = true;
+ }
+ }
+
RefPtr<TypeBuilder::CSS::CSSMedia> mediaObject = TypeBuilder::CSS::CSSMedia::create()
.setText(media->mediaText())
.setSource(source);
+ if (hasMediaQueryItems)
+ mediaObject->setMediaList(mediaListArray);
if (parentStyleSheet && mediaListSource != MediaListSourceLinkedSheet) {
if (InspectorStyleSheet* inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(parentStyleSheet))
mediaObject->setParentStyleSheetId(inspectorStyleSheet->id());
}
+
if (!sourceURL.isEmpty()) {
mediaObject->setSourceURL(sourceURL);
@@ -1329,61 +1018,75 @@ PassRefPtr<TypeBuilder::CSS::CSSMedia> InspectorCSSAgent::buildMediaObject(const
return mediaObject.release();
}
+bool InspectorCSSAgent::collectMediaQueriesFromStyleSheet(CSSStyleSheet* styleSheet, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray)
+{
+ bool addedItems = false;
+ MediaList* mediaList = styleSheet->media();
+ String sourceURL;
+ if (mediaList && mediaList->length()) {
+ Document* doc = styleSheet->ownerDocument();
+ if (doc)
+ sourceURL = doc->url();
+ else if (!styleSheet->contents()->baseURL().isEmpty())
+ sourceURL = styleSheet->contents()->baseURL();
+ else
+ sourceURL = "";
+ mediaArray->addItem(buildMediaObject(mediaList, styleSheet->ownerNode() ? MediaListSourceLinkedSheet : MediaListSourceInlineSheet, sourceURL, styleSheet));
+ addedItems = true;
+ }
+ return addedItems;
+}
+
+bool InspectorCSSAgent::collectMediaQueriesFromRule(CSSRule* rule, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray)
+{
+ MediaList* mediaList;
+ String sourceURL;
+ CSSStyleSheet* parentStyleSheet = 0;
+ bool isMediaRule = true;
+ bool addedItems = false;
+ if (rule->type() == CSSRule::MEDIA_RULE) {
+ CSSMediaRule* mediaRule = toCSSMediaRule(rule);
+ mediaList = mediaRule->media();
+ parentStyleSheet = mediaRule->parentStyleSheet();
+ } else if (rule->type() == CSSRule::IMPORT_RULE) {
+ CSSImportRule* importRule = toCSSImportRule(rule);
+ mediaList = importRule->media();
+ parentStyleSheet = importRule->parentStyleSheet();
+ isMediaRule = false;
+ } else {
+ mediaList = 0;
+ }
+
+ if (parentStyleSheet) {
+ sourceURL = parentStyleSheet->contents()->baseURL();
+ if (sourceURL.isEmpty())
+ sourceURL = InspectorDOMAgent::documentURLString(parentStyleSheet->ownerDocument());
+ } else {
+ sourceURL = "";
+ }
+
+ if (mediaList && mediaList->length()) {
+ mediaArray->addItem(buildMediaObject(mediaList, isMediaRule ? MediaListSourceMediaRule : MediaListSourceImportRule, sourceURL, parentStyleSheet));
+ addedItems = true;
+ }
+ return addedItems;
+}
+
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > InspectorCSSAgent::buildMediaListChain(CSSRule* rule)
{
if (!rule)
- return 0;
+ return nullptr;
RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > mediaArray = TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>::create();
bool hasItems = false;
- MediaList* mediaList;
CSSRule* parentRule = rule;
- String sourceURL;
while (parentRule) {
- CSSStyleSheet* parentStyleSheet = 0;
- bool isMediaRule = true;
- if (parentRule->type() == CSSRule::MEDIA_RULE) {
- CSSMediaRule* mediaRule = toCSSMediaRule(parentRule);
- mediaList = mediaRule->media();
- parentStyleSheet = mediaRule->parentStyleSheet();
- } else if (parentRule->type() == CSSRule::IMPORT_RULE) {
- CSSImportRule* importRule = toCSSImportRule(parentRule);
- mediaList = importRule->media();
- parentStyleSheet = importRule->parentStyleSheet();
- isMediaRule = false;
- } else {
- mediaList = 0;
- }
-
- if (parentStyleSheet) {
- sourceURL = parentStyleSheet->contents()->baseURL();
- if (sourceURL.isEmpty())
- sourceURL = InspectorDOMAgent::documentURLString(parentStyleSheet->ownerDocument());
- } else {
- sourceURL = "";
- }
-
- if (mediaList && mediaList->length()) {
- mediaArray->addItem(buildMediaObject(mediaList, isMediaRule ? MediaListSourceMediaRule : MediaListSourceImportRule, sourceURL, parentStyleSheet));
- hasItems = true;
- }
-
+ hasItems = collectMediaQueriesFromRule(parentRule, mediaArray.get()) || hasItems;
if (parentRule->parentRule()) {
parentRule = parentRule->parentRule();
} else {
CSSStyleSheet* styleSheet = parentRule->parentStyleSheet();
while (styleSheet) {
- mediaList = styleSheet->media();
- if (mediaList && mediaList->length()) {
- Document* doc = styleSheet->ownerDocument();
- if (doc)
- sourceURL = doc->url();
- else if (!styleSheet->contents()->baseURL().isEmpty())
- sourceURL = styleSheet->contents()->baseURL();
- else
- sourceURL = "";
- mediaArray->addItem(buildMediaObject(mediaList, styleSheet->ownerNode() ? MediaListSourceLinkedSheet : MediaListSourceInlineSheet, sourceURL, styleSheet));
- hasItems = true;
- }
+ hasItems = collectMediaQueriesFromStyleSheet(styleSheet, mediaArray.get()) || hasItems;
parentRule = styleSheet->ownerRule();
if (parentRule)
break;
@@ -1391,7 +1094,7 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > InspectorCSSAgent::b
}
}
}
- return hasItems ? mediaArray : 0;
+ return hasItems ? mediaArray : nullptr;
}
InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element)
@@ -1405,8 +1108,8 @@ InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Elem
return 0;
String newStyleSheetId = String::number(m_lastStyleSheetId++);
- RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(m_pageAgent, m_resourceAgent, newStyleSheetId, element, TypeBuilder::CSS::StyleSheetOrigin::Regular, this);
- m_idToInspectorStyleSheet.set(newStyleSheetId, inspectorStyleSheet);
+ RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(newStyleSheetId, element, this);
+ m_idToInspectorStyleSheetForInlineStyle.set(newStyleSheetId, inspectorStyleSheet);
m_nodeToInspectorStyleSheet.set(element, inspectorStyleSheet);
return inspectorStyleSheet.get();
}
@@ -1425,38 +1128,26 @@ Element* InspectorCSSAgent::elementForId(ErrorString* errorString, int nodeId)
return toElement(node);
}
-int InspectorCSSAgent::documentNodeWithRequestedFlowsId(Document* document)
-{
- int documentNodeId = m_domAgent->boundNodeId(document);
- if (!documentNodeId || !m_namedFlowCollectionsRequested.contains(documentNodeId))
- return 0;
-
- return documentNodeId;
-}
-
-void InspectorCSSAgent::collectAllStyleSheets(Vector<InspectorStyleSheet*>& result)
+// static
+void InspectorCSSAgent::collectAllDocumentStyleSheets(Document* document, Vector<CSSStyleSheet*>& result)
{
- Vector<Document*> documents = m_domAgent->documents();
- for (Vector<Document*>::iterator it = documents.begin(); it != documents.end(); ++it) {
- StyleSheetList* list = (*it)->styleSheets();
- for (unsigned i = 0; i < list->length(); ++i) {
- StyleSheet* styleSheet = list->item(i);
- if (styleSheet->isCSSStyleSheet())
- collectStyleSheets(toCSSStyleSheet(styleSheet), result);
- }
+ const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > activeStyleSheets = document->styleEngine()->activeStyleSheetsForInspector();
+ for (WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >::const_iterator it = activeStyleSheets.begin(); it != activeStyleSheets.end(); ++it) {
+ CSSStyleSheet* styleSheet = it->get();
+ InspectorCSSAgent::collectStyleSheets(styleSheet, result);
}
}
-void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Vector<InspectorStyleSheet*>& result)
+// static
+void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Vector<CSSStyleSheet*>& result)
{
- InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(styleSheet);
- result.append(inspectorStyleSheet);
+ result.append(styleSheet);
for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
CSSRule* rule = styleSheet->item(i);
if (rule->type() == CSSRule::IMPORT_RULE) {
CSSStyleSheet* importedStyleSheet = toCSSImportRule(rule)->styleSheet();
if (importedStyleSheet)
- collectStyleSheets(importedStyleSheet, result);
+ InspectorCSSAgent::collectStyleSheets(importedStyleSheet, result);
}
}
}
@@ -1471,7 +1162,7 @@ InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet
m_idToInspectorStyleSheet.set(id, inspectorStyleSheet);
m_cssStyleSheetToInspectorStyleSheet.set(styleSheet, inspectorStyleSheet);
if (m_creatingViaInspectorStyleSheet)
- m_documentToInspectorStyleSheet.add(document, inspectorStyleSheet);
+ m_documentToViaInspectorStyleSheet.add(document, inspectorStyleSheet);
}
return inspectorStyleSheet.get();
}
@@ -1495,12 +1186,12 @@ InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* documen
if (!document->isHTMLDocument() && !document->isSVGDocument())
return 0;
- RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_documentToInspectorStyleSheet.get(document);
+ RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_documentToViaInspectorStyleSheet.get(document);
if (inspectorStyleSheet || !createIfAbsent)
return inspectorStyleSheet.get();
TrackExceptionState exceptionState;
- RefPtr<Element> styleElement = document->createElement("style", exceptionState);
+ RefPtrWillBeRawPtr<Element> styleElement = document->createElement("style", exceptionState);
if (!exceptionState.hadException())
styleElement->setAttribute("type", "text/css", exceptionState);
if (!exceptionState.hadException()) {
@@ -1517,16 +1208,16 @@ InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* documen
m_creatingViaInspectorStyleSheet = true;
targetNode->appendChild(styleElement, exceptionState);
// At this point the added stylesheet will get bound through the updateActiveStyleSheets() invocation.
- // We just need to pick the respective InspectorStyleSheet from m_documentToInspectorStyleSheet.
+ // We just need to pick the respective InspectorStyleSheet from m_documentToViaInspectorStyleSheet.
m_creatingViaInspectorStyleSheet = false;
}
if (exceptionState.hadException())
return 0;
- return m_documentToInspectorStyleSheet.get(document);
+ return m_documentToViaInspectorStyleSheet.get(document);
}
-InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString* errorString, const String& styleSheetId)
+InspectorStyleSheet* InspectorCSSAgent::assertInspectorStyleSheetForId(ErrorString* errorString, const String& styleSheetId)
{
IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.find(styleSheetId);
if (it == m_idToInspectorStyleSheet.end()) {
@@ -1536,6 +1227,20 @@ InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString* error
return it->value.get();
}
+InspectorStyleSheetBase* InspectorCSSAgent::assertStyleSheetForId(ErrorString* errorString, const String& styleSheetId)
+{
+ String placeholder;
+ InspectorStyleSheetBase* result = assertInspectorStyleSheetForId(&placeholder, styleSheetId);
+ if (result)
+ return result;
+ IdToInspectorStyleSheetForInlineStyle::iterator it = m_idToInspectorStyleSheetForInlineStyle.find(styleSheetId);
+ if (it == m_idToInspectorStyleSheetForInlineStyle.end()) {
+ *errorString = "No style sheet with given id found";
+ return 0;
+ }
+ return it->value.get();
+}
+
TypeBuilder::CSS::StyleSheetOrigin::Enum InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument)
{
if (m_creatingViaInspectorStyleSheet)
@@ -1544,7 +1249,7 @@ TypeBuilder::CSS::StyleSheetOrigin::Enum InspectorCSSAgent::detectOrigin(CSSStyl
TypeBuilder::CSS::StyleSheetOrigin::Enum origin = TypeBuilder::CSS::StyleSheetOrigin::Regular;
if (pageStyleSheet && !pageStyleSheet->ownerNode() && pageStyleSheet->href().isEmpty())
origin = TypeBuilder::CSS::StyleSheetOrigin::User_agent;
- else if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document")
+ else if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->isDocumentNode())
origin = TypeBuilder::CSS::StyleSheetOrigin::User;
else {
InspectorStyleSheet* viaInspectorStyleSheetForOwner = viaInspectorStyleSheet(ownerDocument, false);
@@ -1554,42 +1259,21 @@ TypeBuilder::CSS::StyleSheetOrigin::Enum InspectorCSSAgent::detectOrigin(CSSStyl
return origin;
}
-PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule, StyleResolver& styleResolver)
+PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule)
{
if (!rule)
- return 0;
+ return nullptr;
- // CSSRules returned by StyleResolver::cssRulesForElement lack parent pointers since that infomation is not cheaply available.
- // Since the inspector wants to walk the parent chain, we construct the full wrappers here.
- // FIXME: This could be factored better. StyleResolver::cssRulesForElement should return a StyleRule vector, not a CSSRuleList.
+ // CSSRules returned by StyleResolver::pseudoCSSRulesForElement lack parent pointers if they are coming from
+ // user agent stylesheets. To work around this issue, we use CSSOM wrapper created by inspector.
if (!rule->parentStyleSheet()) {
- rule = styleResolver.inspectorCSSOMWrappers().getWrapperForRuleInSheets(rule->styleRule(), styleResolver.document().styleEngine());
- if (!rule)
- return 0;
+ if (!m_inspectorUserAgentStyleSheet)
+ m_inspectorUserAgentStyleSheet = CSSStyleSheet::create(CSSDefaultStyleSheets::instance().defaultStyleSheet());
+ rule->setParentStyleSheet(m_inspectorUserAgentStyleSheet.get());
}
return bindStyleSheet(rule->parentStyleSheet())->buildObjectForRule(rule, buildMediaListChain(rule));
}
-PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > InspectorCSSAgent::buildArrayForRuleList(CSSRuleList* ruleList, StyleResolver& styleResolver)
-{
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > result = TypeBuilder::Array<TypeBuilder::CSS::CSSRule>::create();
- if (!ruleList)
- return result.release();
-
- RefPtr<CSSRuleList> refRuleList = ruleList;
- CSSRuleVector rules;
- InspectorStyleSheet::collectFlatRules(refRuleList, &rules);
-
- for (unsigned i = 0, size = rules.size(); i < size; ++i) {
- CSSStyleRule* styleRule = asCSSStyleRule(rules.at(i).get());
- if (!styleRule)
- continue;
- result->addItem(buildObjectForRule(styleRule, styleResolver));
- }
-
- return result.release();
-}
-
static inline bool matchesPseudoElement(const CSSSelector* selector, PseudoId elementPseudoId)
{
// According to http://www.w3.org/TR/css3-selectors/#pseudo-elements, "Only one pseudo-element may appear per selector."
@@ -1602,7 +1286,7 @@ static inline bool matchesPseudoElement(const CSSSelector* selector, PseudoId el
return selectorPseudoId == elementPseudoId;
}
-PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::buildArrayForMatchedRuleList(CSSRuleList* ruleList, StyleResolver& styleResolver, Element* element)
+PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::buildArrayForMatchedRuleList(CSSRuleList* ruleList, Element* element)
{
RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > result = TypeBuilder::Array<TypeBuilder::CSS::RuleMatch>::create();
if (!ruleList)
@@ -1610,19 +1294,19 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::
for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i));
- RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule, styleResolver);
+ RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule);
if (!ruleObject)
continue;
RefPtr<TypeBuilder::Array<int> > matchingSelectors = TypeBuilder::Array<int>::create();
const CSSSelectorList& selectorList = rule->styleRule()->selectorList();
long index = 0;
PseudoId elementPseudoId = element->pseudoId();
- for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector)) {
const CSSSelector* firstTagHistorySelector = selector;
bool matched = false;
if (elementPseudoId)
matched = matchesPseudoElement(selector, elementPseudoId); // Modifies |selector|.
- matched |= element->webkitMatchesSelector(firstTagHistorySelector->selectorText(), IGNORE_EXCEPTION);
+ matched |= element->matches(firstTagHistorySelector->selectorText(), IGNORE_EXCEPTION);
if (matched)
matchingSelectors->addItem(index);
++index;
@@ -1639,12 +1323,12 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::
PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element)
{
if (!element->isStyledElement())
- return 0;
+ return nullptr;
// FIXME: Ugliness below.
StylePropertySet* attributeStyle = const_cast<StylePropertySet*>(element->presentationAttributeStyle());
if (!attributeStyle)
- return 0;
+ return nullptr;
MutableStylePropertySet* mutableAttributeStyle = toMutableStylePropertySet(attributeStyle);
@@ -1652,65 +1336,10 @@ PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttribut
return inspectorStyle->buildObjectForStyle();
}
-PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Region> > InspectorCSSAgent::buildArrayForRegions(ErrorString* errorString, PassRefPtr<NodeList> regionList, int documentNodeId)
-{
- RefPtr<TypeBuilder::Array<TypeBuilder::CSS::Region> > regions = TypeBuilder::Array<TypeBuilder::CSS::Region>::create();
-
- for (unsigned i = 0; i < regionList->length(); ++i) {
- TypeBuilder::CSS::Region::RegionOverset::Enum regionOverset;
-
- switch (toElement(regionList->item(i))->renderRegion()->regionOversetState()) {
- case RegionFit:
- regionOverset = TypeBuilder::CSS::Region::RegionOverset::Fit;
- break;
- case RegionEmpty:
- regionOverset = TypeBuilder::CSS::Region::RegionOverset::Empty;
- break;
- case RegionOverset:
- regionOverset = TypeBuilder::CSS::Region::RegionOverset::Overset;
- break;
- case RegionUndefined:
- continue;
- default:
- ASSERT_NOT_REACHED();
- continue;
- }
-
- RefPtr<TypeBuilder::CSS::Region> region = TypeBuilder::CSS::Region::create()
- .setRegionOverset(regionOverset)
- // documentNodeId was previously asserted
- .setNodeId(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, regionList->item(i)));
-
- regions->addItem(region);
- }
-
- return regions.release();
-}
-
-PassRefPtr<TypeBuilder::CSS::NamedFlow> InspectorCSSAgent::buildObjectForNamedFlow(ErrorString* errorString, NamedFlow* webkitNamedFlow, int documentNodeId)
-{
- RefPtr<NodeList> contentList = webkitNamedFlow->getContent();
- RefPtr<TypeBuilder::Array<int> > content = TypeBuilder::Array<int>::create();
-
- for (unsigned i = 0; i < contentList->length(); ++i) {
- // documentNodeId was previously asserted
- content->addItem(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, contentList->item(i)));
- }
-
- RefPtr<TypeBuilder::CSS::NamedFlow> namedFlow = TypeBuilder::CSS::NamedFlow::create()
- .setDocumentNodeId(documentNodeId)
- .setName(webkitNamedFlow->name().string())
- .setOverset(webkitNamedFlow->overset())
- .setContent(content)
- .setRegions(buildArrayForRegions(errorString, webkitNamedFlow->getRegions(), documentNodeId));
-
- return namedFlow.release();
-}
-
void InspectorCSSAgent::didRemoveDocument(Document* document)
{
if (document)
- m_documentToInspectorStyleSheet.remove(document);
+ m_documentToViaInspectorStyleSheet.remove(document);
}
void InspectorCSSAgent::didRemoveDOMNode(Node* node)
@@ -1726,7 +1355,7 @@ void InspectorCSSAgent::didRemoveDOMNode(Node* node)
if (it == m_nodeToInspectorStyleSheet.end())
return;
- m_idToInspectorStyleSheet.remove(it->value->id());
+ m_idToInspectorStyleSheetForInlineStyle.remove(it->value->id());
m_nodeToInspectorStyleSheet.remove(node);
}
@@ -1742,10 +1371,10 @@ void InspectorCSSAgent::didModifyDOMAttr(Element* element)
it->value->didModifyElementAttribute();
}
-void InspectorCSSAgent::styleSheetChanged(InspectorStyleSheet* styleSheet)
+void InspectorCSSAgent::styleSheetChanged(InspectorStyleSheetBase* styleSheet)
{
- if (m_frontend)
- m_frontend->styleSheetChanged(styleSheet->id());
+ flushPendingFrontendMessages();
+ m_frontend->styleSheetChanged(styleSheet->id());
}
void InspectorCSSAgent::willReparseStyleSheet()
@@ -1771,7 +1400,7 @@ void InspectorCSSAgent::resetPseudoStates()
m_nodeIdToForcedPseudoState.clear();
for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = documentsToChange.end(); it != end; ++it)
- (*it)->setNeedsStyleRecalc();
+ (*it)->setNeedsStyleRecalc(SubtreeStyleChange);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h
index aab88549865..9b59935ad06 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h
@@ -27,10 +27,10 @@
#include "core/css/CSSSelector.h"
#include "core/dom/SecurityContext.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "core/inspector/InspectorDOMAgent.h"
#include "core/inspector/InspectorStyleSheet.h"
-#include "core/frame/ContentSecurityPolicy.h"
#include "platform/JSONValues.h"
#include "wtf/HashCountedSet.h"
#include "wtf/HashMap.h"
@@ -42,7 +42,6 @@
namespace WebCore {
-class ChangeRegionOversetTask;
struct CSSParserString;
class CSSRule;
class CSSRuleList;
@@ -55,20 +54,15 @@ class InspectorResourceAgent;
class InstrumentingAgents;
class MediaList;
class Node;
-class NodeList;
class PlatformFontUsage;
class RenderText;
class StyleResolver;
-class UpdateRegionLayoutTask;
-typedef HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet> > CSSStyleSheetToInspectorStyleSheet;
-typedef Vector<RefPtr<StyleSheet> > StyleSheetVector;
-
-class InspectorCSSAgent
+class InspectorCSSAgent FINAL
: public InspectorBaseAgent<InspectorCSSAgent>
, public InspectorDOMAgent::DOMListener
, public InspectorBackendDispatcher::CSSCommandHandler
- , public InspectorStyleSheet::Listener {
+ , public InspectorStyleSheetBase::Listener {
WTF_MAKE_NONCOPYABLE(InspectorCSSAgent);
public:
enum MediaListSource {
@@ -78,6 +72,11 @@ public:
MediaListSourceImportRule
};
+ enum StyleSheetsUpdateType {
+ InitialFrontendLoad = 0,
+ ExistingFrontendRefresh,
+ };
+
class InlineStyleOverrideScope {
public:
InlineStyleOverrideScope(SecurityContext* context)
@@ -97,108 +96,100 @@ public:
static CSSStyleRule* asCSSStyleRule(CSSRule*);
- static PassOwnPtr<InspectorCSSAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorDOMAgent* domAgent, InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent)
+ static PassOwnPtr<InspectorCSSAgent> create(InspectorDOMAgent* domAgent, InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent)
{
- return adoptPtr(new InspectorCSSAgent(instrumentingAgents, state, domAgent, pageAgent, resourceAgent));
+ return adoptPtr(new InspectorCSSAgent(domAgent, pageAgent, resourceAgent));
}
- ~InspectorCSSAgent();
+
+ static void collectAllDocumentStyleSheets(Document*, Vector<CSSStyleSheet*>&);
+
+ virtual ~InspectorCSSAgent();
bool forcePseudoState(Element*, CSSSelector::PseudoType);
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void discardAgent();
- virtual void restore();
- virtual void enable(ErrorString*, PassRefPtr<EnableCallback>);
- virtual void disable(ErrorString*);
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void discardAgent() OVERRIDE;
+ virtual void didCommitLoadForMainFrame() OVERRIDE;
+ virtual void restore() OVERRIDE;
+ virtual void flushPendingFrontendMessages() OVERRIDE;
+ virtual void enable(ErrorString*, PassRefPtr<EnableCallback>) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
void reset();
- void didCommitLoad(Frame*, DocumentLoader*);
void mediaQueryResultChanged();
- void didCreateNamedFlow(Document*, NamedFlow*);
- void willRemoveNamedFlow(Document*, NamedFlow*);
void willMutateRules();
void didMutateRules(CSSStyleSheet*);
void willMutateStyle();
void didMutateStyle(CSSStyleDeclaration*, bool);
-private:
- void regionLayoutUpdated(NamedFlow*, int documentNodeId);
- void regionOversetChanged(NamedFlow*, int documentNodeId);
+ void activeStyleSheetsUpdated(Document*);
+ void documentDetached(Document*);
-public:
- void didUpdateRegionLayout(Document*, NamedFlow*);
- void didChangeRegionOverset(Document*, NamedFlow*);
-
- void activeStyleSheetsUpdated(Document*, const StyleSheetVector& newSheets);
- void frameDetachedFromParent(Frame*);
-
- virtual void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >&);
- virtual void getPlatformFontsForNode(ErrorString*, int nodeId, String* cssFamilyName, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PlatformFontUsage> >&);
- virtual void getInlineStylesForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<TypeBuilder::CSS::CSSStyle>& attributes);
- virtual void getMatchedStylesForNode(ErrorString*, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> >& pseudoIdMatches, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries);
- virtual void getAllStyleSheets(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSStyleSheetHeader> >& styleSheetInfos);
- virtual void getStyleSheet(ErrorString*, const String& styleSheetId, RefPtr<TypeBuilder::CSS::CSSStyleSheetBody>& result);
- virtual void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result);
- virtual void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text);
- virtual void setStyleText(ErrorString*, const RefPtr<JSONObject>& styleId, const String& text, RefPtr<TypeBuilder::CSS::CSSStyle>& result);
- virtual void setPropertyText(ErrorString*, const RefPtr<JSONObject>& styleId, int propertyIndex, const String& text, bool overwrite, RefPtr<TypeBuilder::CSS::CSSStyle>& result);
- virtual void toggleProperty(ErrorString*, const RefPtr<JSONObject>& styleId, int propertyIndex, bool disable, RefPtr<TypeBuilder::CSS::CSSStyle>& result);
- virtual void setRuleSelector(ErrorString*, const RefPtr<JSONObject>& ruleId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result);
- virtual void addRule(ErrorString*, int contextNodeId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result);
- virtual void getSupportedCSSProperties(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSPropertyInfo> >& result);
- virtual void forcePseudoState(ErrorString*, int nodeId, const RefPtr<JSONArray>& forcedPseudoClasses);
- virtual void getNamedFlowCollection(ErrorString*, int documentNodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::NamedFlow> >& result);
+ virtual void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >&) OVERRIDE;
+ virtual void getPlatformFontsForNode(ErrorString*, int nodeId, String* cssFamilyName, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PlatformFontUsage> >&) OVERRIDE;
+ virtual void getInlineStylesForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<TypeBuilder::CSS::CSSStyle>& attributes) OVERRIDE;
+ virtual void getMatchedStylesForNode(ErrorString*, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> >&, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries) OVERRIDE;
+ virtual void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result) OVERRIDE;
+ virtual void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text) OVERRIDE;
+ virtual void setPropertyText(ErrorString*, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& text, RefPtr<TypeBuilder::CSS::CSSStyle>& result) OVERRIDE;
+ virtual void setRuleSelector(ErrorString*, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result) OVERRIDE;
+ virtual void createStyleSheet(ErrorString*, const String& frameId, TypeBuilder::CSS::StyleSheetId* outStyleSheetId) OVERRIDE;
+ virtual void addRule(ErrorString*, const String& styleSheetId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result) OVERRIDE;
+ virtual void forcePseudoState(ErrorString*, int nodeId, const RefPtr<JSONArray>& forcedPseudoClasses) OVERRIDE;
+ virtual void getMediaQueries(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> >& medias) OVERRIDE;
+
+
+ bool collectMediaQueriesFromRule(CSSRule*, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray);
+ bool collectMediaQueriesFromStyleSheet(CSSStyleSheet*, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray);
PassRefPtr<TypeBuilder::CSS::CSSMedia> buildMediaObject(const MediaList*, MediaListSource, const String&, CSSStyleSheet*);
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > buildMediaListChain(CSSRule*);
private:
class StyleSheetAction;
class SetStyleSheetTextAction;
- class SetStyleTextAction;
class SetPropertyTextAction;
- class TogglePropertyAction;
class SetRuleSelectorAction;
class AddRuleAction;
- class EnableResourceClient;
+ class InspectorResourceContentLoaderCallback;
+
+ static void collectStyleSheets(CSSStyleSheet*, Vector<CSSStyleSheet*>&);
- InspectorCSSAgent(InstrumentingAgents*, InspectorCompositeState*, InspectorDOMAgent*, InspectorPageAgent*, InspectorResourceAgent*);
+ InspectorCSSAgent(InspectorDOMAgent*, InspectorPageAgent*, InspectorResourceAgent*);
typedef HashMap<String, RefPtr<InspectorStyleSheet> > IdToInspectorStyleSheet;
+ typedef HashMap<String, RefPtr<InspectorStyleSheetForInlineStyle> > IdToInspectorStyleSheetForInlineStyle;
typedef HashMap<Node*, RefPtr<InspectorStyleSheetForInlineStyle> > NodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline styles
- typedef HashMap<RefPtr<Document>, RefPtr<InspectorStyleSheet> > DocumentToViaInspectorStyleSheet; // "via inspector" stylesheets
typedef HashMap<int, unsigned> NodeIdToForcedPseudoState;
- void wasEnabled(PassRefPtr<EnableCallback>);
+ void wasEnabled();
void resetNonPersistentData();
InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element);
Element* elementForId(ErrorString*, int nodeId);
- int documentNodeWithRequestedFlowsId(Document*);
- void collectAllStyleSheets(Vector<InspectorStyleSheet*>&);
- void collectStyleSheets(CSSStyleSheet*, Vector<InspectorStyleSheet*>&);
+
+ void updateActiveStyleSheets(Document*, StyleSheetsUpdateType);
+ void setActiveStyleSheets(Document*, const Vector<CSSStyleSheet*>&, StyleSheetsUpdateType);
void collectPlatformFontsForRenderer(RenderText*, HashCountedSet<String>*);
InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*);
String unbindStyleSheet(InspectorStyleSheet*);
InspectorStyleSheet* viaInspectorStyleSheet(Document*, bool createIfAbsent);
- InspectorStyleSheet* assertStyleSheetForId(ErrorString*, const String&);
+ InspectorStyleSheet* assertInspectorStyleSheetForId(ErrorString*, const String&);
+ InspectorStyleSheetBase* assertStyleSheetForId(ErrorString*, const String&);
TypeBuilder::CSS::StyleSheetOrigin::Enum detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument);
bool styleSheetEditInProgress() const { return m_styleSheetsPendingMutation || m_styleDeclarationPendingMutation || m_isSettingStyleSheetText; }
- PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*, StyleResolver&);
- PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > buildArrayForRuleList(CSSRuleList*, StyleResolver&);
- PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > buildArrayForMatchedRuleList(CSSRuleList*, StyleResolver&, Element*);
+ PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*);
+ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > buildArrayForMatchedRuleList(CSSRuleList*, Element*);
PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForAttributesStyle(Element*);
- PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Region> > buildArrayForRegions(ErrorString*, PassRefPtr<NodeList>, int documentNodeId);
- PassRefPtr<TypeBuilder::CSS::NamedFlow> buildObjectForNamedFlow(ErrorString*, NamedFlow*, int documentNodeId);
// InspectorDOMAgent::DOMListener implementation
- virtual void didRemoveDocument(Document*);
- virtual void didRemoveDOMNode(Node*);
- virtual void didModifyDOMAttr(Element*);
+ virtual void didRemoveDocument(Document*) OVERRIDE;
+ virtual void didRemoveDOMNode(Node*) OVERRIDE;
+ virtual void didModifyDOMAttr(Element*) OVERRIDE;
// InspectorStyleSheet::Listener implementation
- virtual void styleSheetChanged(InspectorStyleSheet*) OVERRIDE;
+ virtual void styleSheetChanged(InspectorStyleSheetBase*) OVERRIDE;
virtual void willReparseStyleSheet() OVERRIDE;
virtual void didReparseStyleSheet() OVERRIDE;
@@ -210,13 +201,17 @@ private:
InspectorResourceAgent* m_resourceAgent;
IdToInspectorStyleSheet m_idToInspectorStyleSheet;
- CSSStyleSheetToInspectorStyleSheet m_cssStyleSheetToInspectorStyleSheet;
+ IdToInspectorStyleSheetForInlineStyle m_idToInspectorStyleSheetForInlineStyle;
+ HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet> > m_cssStyleSheetToInspectorStyleSheet;
+ typedef HashMap<Document*, OwnPtr<HashSet<CSSStyleSheet*> > > DocumentStyleSheets;
+ DocumentStyleSheets m_documentToCSSStyleSheets;
+ HashSet<Document*> m_invalidatedDocuments;
+
NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet;
- DocumentToViaInspectorStyleSheet m_documentToInspectorStyleSheet;
+ WillBePersistentHeapHashMap<RefPtrWillBeMember<Document>, RefPtr<InspectorStyleSheet> > m_documentToViaInspectorStyleSheet; // "via inspector" stylesheets
NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState;
- HashSet<int> m_namedFlowCollectionsRequested;
- OwnPtr<UpdateRegionLayoutTask> m_updateRegionLayoutTask;
- OwnPtr<ChangeRegionOversetTask> m_changeRegionOversetTask;
+
+ RefPtrWillBePersistent<CSSStyleSheet> m_inspectorUserAgentStyleSheet;
int m_lastStyleSheetId;
int m_styleSheetsPendingMutation;
@@ -224,10 +219,8 @@ private:
bool m_creatingViaInspectorStyleSheet;
bool m_isSettingStyleSheetText;
- friend class ChangeRegionOversetTask;
- friend class EnableResourceClient;
+ friend class InspectorResourceContentLoaderCallback;
friend class StyleSheetBinder;
- friend class UpdateRegionLayoutTask;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.cpp
index 5a03d88a17a..5511f4f6506 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.cpp
@@ -31,9 +31,8 @@
#include "config.h"
#include "core/inspector/InspectorCanvasAgent.h"
-#include "HTMLNames.h"
-#include "bindings/v8/ScriptObject.h"
#include "bindings/v8/ScriptProfiler.h"
+#include "bindings/v8/ScriptValue.h"
#include "core/html/HTMLCanvasElement.h"
#include "core/inspector/BindingVisitors.h"
#include "core/inspector/InjectedScript.h"
@@ -43,8 +42,8 @@
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/loader/DocumentLoader.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
using WebCore::TypeBuilder::Array;
using WebCore::TypeBuilder::Canvas::ResourceId;
@@ -60,8 +59,8 @@ namespace CanvasAgentState {
static const char canvasAgentEnabled[] = "canvasAgentEnabled";
};
-InspectorCanvasAgent::InspectorCanvasAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager)
- : InspectorBaseAgent<InspectorCanvasAgent>("Canvas", instrumentingAgents, state)
+InspectorCanvasAgent::InspectorCanvasAgent(InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager)
+ : InspectorBaseAgent<InspectorCanvasAgent>("Canvas")
, m_pageAgent(pageAgent)
, m_injectedScriptManager(injectedScriptManager)
, m_frontend(0)
@@ -116,7 +115,7 @@ void InspectorCanvasAgent::disable(ErrorString*)
void InspectorCanvasAgent::dropTraceLog(ErrorString* errorString, const TraceLogId& traceLogId)
{
InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId);
- if (!module.hasNoValue())
+ if (!module.isEmpty())
module.dropTraceLog(errorString, traceLogId);
}
@@ -135,85 +134,85 @@ void InspectorCanvasAgent::hasUninstrumentedCanvases(ErrorString* errorString, b
void InspectorCanvasAgent::captureFrame(ErrorString* errorString, const FrameId* frameId, TraceLogId* traceLogId)
{
- Frame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame();
+ LocalFrame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame();
if (!frame)
return;
- InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, mainWorldScriptState(frame));
- if (!module.hasNoValue())
+ InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, ScriptState::forMainWorld(frame));
+ if (!module.isEmpty())
module.captureFrame(errorString, traceLogId);
}
void InspectorCanvasAgent::startCapturing(ErrorString* errorString, const FrameId* frameId, TraceLogId* traceLogId)
{
- Frame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame();
+ LocalFrame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame();
if (!frame)
return;
- InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, mainWorldScriptState(frame));
- if (!module.hasNoValue())
+ InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, ScriptState::forMainWorld(frame));
+ if (!module.isEmpty())
module.startCapturing(errorString, traceLogId);
}
void InspectorCanvasAgent::stopCapturing(ErrorString* errorString, const TraceLogId& traceLogId)
{
InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId);
- if (!module.hasNoValue())
+ if (!module.isEmpty())
module.stopCapturing(errorString, traceLogId);
}
void InspectorCanvasAgent::getTraceLog(ErrorString* errorString, const TraceLogId& traceLogId, const int* startOffset, const int* maxLength, RefPtr<TraceLog>& traceLog)
{
InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId);
- if (!module.hasNoValue())
+ if (!module.isEmpty())
module.traceLog(errorString, traceLogId, startOffset, maxLength, &traceLog);
}
void InspectorCanvasAgent::replayTraceLog(ErrorString* errorString, const TraceLogId& traceLogId, int stepNo, RefPtr<ResourceState>& result, double* replayTime)
{
InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId);
- if (!module.hasNoValue())
+ if (!module.isEmpty())
module.replayTraceLog(errorString, traceLogId, stepNo, &result, replayTime);
}
void InspectorCanvasAgent::getResourceState(ErrorString* errorString, const TraceLogId& traceLogId, const ResourceId& resourceId, RefPtr<ResourceState>& result)
{
InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId);
- if (!module.hasNoValue())
+ if (!module.isEmpty())
module.resourceState(errorString, traceLogId, resourceId, &result);
}
void InspectorCanvasAgent::evaluateTraceLogCallArgument(ErrorString* errorString, const TraceLogId& traceLogId, int callIndex, int argumentIndex, const String* objectGroup, RefPtr<RemoteObject>& result, RefPtr<ResourceState>& resourceState)
{
InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, traceLogId);
- if (!module.hasNoValue())
+ if (!module.isEmpty())
module.evaluateTraceLogCallArgument(errorString, traceLogId, callIndex, argumentIndex, objectGroup ? *objectGroup : String(), &result, &resourceState);
}
-ScriptObject InspectorCanvasAgent::wrapCanvas2DRenderingContextForInstrumentation(const ScriptObject& context)
+ScriptValue InspectorCanvasAgent::wrapCanvas2DRenderingContextForInstrumentation(const ScriptValue& context)
{
ErrorString error;
InjectedScriptCanvasModule module = injectedScriptCanvasModule(&error, context);
- if (module.hasNoValue())
- return ScriptObject();
+ if (module.isEmpty())
+ return ScriptValue();
return notifyRenderingContextWasWrapped(module.wrapCanvas2DContext(context));
}
-ScriptObject InspectorCanvasAgent::wrapWebGLRenderingContextForInstrumentation(const ScriptObject& glContext)
+ScriptValue InspectorCanvasAgent::wrapWebGLRenderingContextForInstrumentation(const ScriptValue& glContext)
{
ErrorString error;
InjectedScriptCanvasModule module = injectedScriptCanvasModule(&error, glContext);
- if (module.hasNoValue())
- return ScriptObject();
+ if (module.isEmpty())
+ return ScriptValue();
return notifyRenderingContextWasWrapped(module.wrapWebGLContext(glContext));
}
-ScriptObject InspectorCanvasAgent::notifyRenderingContextWasWrapped(const ScriptObject& wrappedContext)
+ScriptValue InspectorCanvasAgent::notifyRenderingContextWasWrapped(const ScriptValue& wrappedContext)
{
ASSERT(m_frontend);
ScriptState* scriptState = wrappedContext.scriptState();
- DOMWindow* domWindow = 0;
+ LocalDOMWindow* domWindow = 0;
if (scriptState)
domWindow = scriptState->domWindow();
- Frame* frame = domWindow ? domWindow->frame() : 0;
+ LocalFrame* frame = domWindow ? domWindow->frame() : 0;
if (frame && !m_framesWithUninstrumentedCanvases.contains(frame))
m_framesWithUninstrumentedCanvases.set(frame, false);
String frameId = m_pageAgent->frameId(frame);
@@ -227,23 +226,23 @@ InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(Erro
if (!checkIsEnabled(errorString))
return InjectedScriptCanvasModule();
InjectedScriptCanvasModule module = InjectedScriptCanvasModule::moduleForState(m_injectedScriptManager, scriptState);
- if (module.hasNoValue()) {
+ if (module.isEmpty()) {
ASSERT_NOT_REACHED();
*errorString = "Internal error: no Canvas module";
}
return module;
}
-InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(ErrorString* errorString, const ScriptObject& scriptObject)
+InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(ErrorString* errorString, const ScriptValue& scriptValue)
{
if (!checkIsEnabled(errorString))
return InjectedScriptCanvasModule();
- if (scriptObject.hasNoValue()) {
+ if (scriptValue.isEmpty()) {
ASSERT_NOT_REACHED();
- *errorString = "Internal error: original ScriptObject has no value";
+ *errorString = "Internal error: original ScriptValue has no value";
return InjectedScriptCanvasModule();
}
- return injectedScriptCanvasModule(errorString, scriptObject.scriptState());
+ return injectedScriptCanvasModule(errorString, scriptValue.scriptState());
}
InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(ErrorString* errorString, const String& objectId)
@@ -251,7 +250,7 @@ InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(Erro
if (!checkIsEnabled(errorString))
return InjectedScriptCanvasModule();
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return InjectedScriptCanvasModule();
}
@@ -260,7 +259,7 @@ InjectedScriptCanvasModule InspectorCanvasAgent::injectedScriptCanvasModule(Erro
void InspectorCanvasAgent::findFramesWithUninstrumentedCanvases()
{
- class NodeVisitor : public WrappedNodeVisitor {
+ class NodeVisitor FINAL : public WrappedNodeVisitor {
public:
NodeVisitor(Page* page, FramesWithUninstrumentedCanvases& result)
: m_page(page)
@@ -270,10 +269,11 @@ void InspectorCanvasAgent::findFramesWithUninstrumentedCanvases()
virtual void visitNode(Node* node) OVERRIDE
{
- if (!node->hasTagName(HTMLNames::canvasTag) || !node->document().frame())
+ ASSERT(node);
+ if (!isHTMLCanvasElement(*node) || !node->document().frame())
return;
- Frame* frame = node->document().frame();
+ LocalFrame* frame = node->document().frame();
if (frame->page() != m_page)
return;
@@ -306,7 +306,7 @@ bool InspectorCanvasAgent::checkIsEnabled(ErrorString* errorString) const
return false;
}
-void InspectorCanvasAgent::didCommitLoad(Frame*, DocumentLoader* loader)
+void InspectorCanvasAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader)
{
if (!m_enabled)
return;
@@ -317,18 +317,21 @@ void InspectorCanvasAgent::didCommitLoad(Frame*, DocumentLoader* loader)
m_frontend->traceLogsRemoved(0, 0);
} else {
while (frame) {
- if (m_framesWithUninstrumentedCanvases.contains(frame))
- m_framesWithUninstrumentedCanvases.set(frame, false);
- if (m_pageAgent->hasIdForFrame(frame)) {
- String frameId = m_pageAgent->frameId(frame);
- m_frontend->traceLogsRemoved(&frameId, 0);
+ if (frame->isLocalFrame()) {
+ LocalFrame* localFrame = toLocalFrame(frame);
+ if (m_framesWithUninstrumentedCanvases.contains(localFrame))
+ m_framesWithUninstrumentedCanvases.set(localFrame, false);
+ if (m_pageAgent->hasIdForFrame(localFrame)) {
+ String frameId = m_pageAgent->frameId(localFrame);
+ m_frontend->traceLogsRemoved(&frameId, 0);
+ }
}
frame = frame->tree().traverseNext();
}
}
}
-void InspectorCanvasAgent::frameDetachedFromParent(Frame* frame)
+void InspectorCanvasAgent::frameDetachedFromParent(LocalFrame* frame)
{
if (m_enabled)
m_framesWithUninstrumentedCanvases.remove(frame);
@@ -340,8 +343,8 @@ void InspectorCanvasAgent::didBeginFrame()
return;
ErrorString error;
for (FramesWithUninstrumentedCanvases::const_iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) {
- InjectedScriptCanvasModule module = injectedScriptCanvasModule(&error, mainWorldScriptState(it->key));
- if (!module.hasNoValue())
+ InjectedScriptCanvasModule module = injectedScriptCanvasModule(&error, ScriptState::forMainWorld(it->key));
+ if (!module.isEmpty())
module.markFrameEnd();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.h
index 5d30d75ba22..0327021d557 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasAgent.h
@@ -32,9 +32,9 @@
#define InspectorCanvasAgent_h
-#include "InspectorFrontend.h"
-#include "InspectorTypeBuilder.h"
#include "bindings/v8/ScriptState.h"
+#include "core/InspectorFrontend.h"
+#include "core/InspectorTypeBuilder.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
@@ -42,66 +42,66 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class DocumentLoader;
class InjectedScriptCanvasModule;
class InjectedScriptManager;
class InspectorPageAgent;
class InstrumentingAgents;
-class ScriptObject;
+class ScriptValue;
typedef String ErrorString;
-class InspectorCanvasAgent : public InspectorBaseAgent<InspectorCanvasAgent>, public InspectorBackendDispatcher::CanvasCommandHandler {
+class InspectorCanvasAgent FINAL : public InspectorBaseAgent<InspectorCanvasAgent>, public InspectorBackendDispatcher::CanvasCommandHandler {
public:
- static PassOwnPtr<InspectorCanvasAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager)
+ static PassOwnPtr<InspectorCanvasAgent> create(InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager)
{
- return adoptPtr(new InspectorCanvasAgent(instrumentingAgents, state, pageAgent, injectedScriptManager));
+ return adoptPtr(new InspectorCanvasAgent(pageAgent, injectedScriptManager));
}
- ~InspectorCanvasAgent();
+ virtual ~InspectorCanvasAgent();
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
- void didCommitLoad(Frame*, DocumentLoader*);
- void frameDetachedFromParent(Frame*);
+ void didCommitLoad(LocalFrame*, DocumentLoader*);
+ void frameDetachedFromParent(LocalFrame*);
void didBeginFrame();
// Called from InspectorCanvasInstrumentation.
- ScriptObject wrapCanvas2DRenderingContextForInstrumentation(const ScriptObject&);
- ScriptObject wrapWebGLRenderingContextForInstrumentation(const ScriptObject&);
+ ScriptValue wrapCanvas2DRenderingContextForInstrumentation(const ScriptValue&);
+ ScriptValue wrapWebGLRenderingContextForInstrumentation(const ScriptValue&);
// Called from the front-end.
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void dropTraceLog(ErrorString*, const TypeBuilder::Canvas::TraceLogId&);
- virtual void hasUninstrumentedCanvases(ErrorString*, bool*);
- virtual void captureFrame(ErrorString*, const TypeBuilder::Page::FrameId*, TypeBuilder::Canvas::TraceLogId*);
- virtual void startCapturing(ErrorString*, const TypeBuilder::Page::FrameId*, TypeBuilder::Canvas::TraceLogId*);
- virtual void stopCapturing(ErrorString*, const TypeBuilder::Canvas::TraceLogId&);
- virtual void getTraceLog(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, const int*, const int*, RefPtr<TypeBuilder::Canvas::TraceLog>&);
- virtual void replayTraceLog(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, int, RefPtr<TypeBuilder::Canvas::ResourceState>&, double*);
- virtual void getResourceState(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, const TypeBuilder::Canvas::ResourceId&, RefPtr<TypeBuilder::Canvas::ResourceState>&);
- virtual void evaluateTraceLogCallArgument(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, int, int, const String*, RefPtr<TypeBuilder::Runtime::RemoteObject>&, RefPtr<TypeBuilder::Canvas::ResourceState>&);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void dropTraceLog(ErrorString*, const TypeBuilder::Canvas::TraceLogId&) OVERRIDE;
+ virtual void hasUninstrumentedCanvases(ErrorString*, bool*) OVERRIDE;
+ virtual void captureFrame(ErrorString*, const TypeBuilder::Page::FrameId*, TypeBuilder::Canvas::TraceLogId*) OVERRIDE;
+ virtual void startCapturing(ErrorString*, const TypeBuilder::Page::FrameId*, TypeBuilder::Canvas::TraceLogId*) OVERRIDE;
+ virtual void stopCapturing(ErrorString*, const TypeBuilder::Canvas::TraceLogId&) OVERRIDE;
+ virtual void getTraceLog(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, const int*, const int*, RefPtr<TypeBuilder::Canvas::TraceLog>&) OVERRIDE;
+ virtual void replayTraceLog(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, int, RefPtr<TypeBuilder::Canvas::ResourceState>&, double*) OVERRIDE;
+ virtual void getResourceState(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, const TypeBuilder::Canvas::ResourceId&, RefPtr<TypeBuilder::Canvas::ResourceState>&) OVERRIDE;
+ virtual void evaluateTraceLogCallArgument(ErrorString*, const TypeBuilder::Canvas::TraceLogId&, int, int, const String*, RefPtr<TypeBuilder::Runtime::RemoteObject>&, RefPtr<TypeBuilder::Canvas::ResourceState>&) OVERRIDE;
private:
- InspectorCanvasAgent(InstrumentingAgents*, InspectorCompositeState*, InspectorPageAgent*, InjectedScriptManager*);
+ InspectorCanvasAgent(InspectorPageAgent*, InjectedScriptManager*);
InjectedScriptCanvasModule injectedScriptCanvasModule(ErrorString*, ScriptState*);
- InjectedScriptCanvasModule injectedScriptCanvasModule(ErrorString*, const ScriptObject&);
+ InjectedScriptCanvasModule injectedScriptCanvasModule(ErrorString*, const ScriptValue&);
InjectedScriptCanvasModule injectedScriptCanvasModule(ErrorString*, const String&);
void findFramesWithUninstrumentedCanvases();
bool checkIsEnabled(ErrorString*) const;
- ScriptObject notifyRenderingContextWasWrapped(const ScriptObject&);
+ ScriptValue notifyRenderingContextWasWrapped(const ScriptValue&);
InspectorPageAgent* m_pageAgent;
InjectedScriptManager* m_injectedScriptManager;
InspectorFrontend::Canvas* m_frontend;
bool m_enabled;
// Contains all frames with canvases, value is true only for frames that have an uninstrumented canvas.
- typedef HashMap<Frame*, bool> FramesWithUninstrumentedCanvases;
+ typedef HashMap<LocalFrame*, bool> FramesWithUninstrumentedCanvases;
FramesWithUninstrumentedCanvases m_framesWithUninstrumentedCanvases;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasInstrumentation.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasInstrumentation.h
index fcdd1d9a3de..0b56b8b62c5 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasInstrumentation.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorCanvasInstrumentation.h
@@ -1 +1 @@
-#include "InspectorCanvasInstrumentationInl.h"
+#include "core/InspectorCanvasInstrumentationInl.h"
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorClient.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorClient.cpp
deleted file mode 100644
index bc0bcd7ef00..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorClient.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/inspector/InspectorClient.h"
-
-#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/ScriptSourceCode.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-
-namespace WebCore {
-
-bool InspectorClient::doDispatchMessageOnFrontendPage(Page* frontendPage, const String& message)
-{
- if (!frontendPage)
- return false;
-
- Frame* frame = frontendPage->mainFrame();
- if (!frame)
- return false;
-
- frame->script().executeScriptInMainWorld("InspectorFrontendAPI.dispatchMessageAsync(" + message + ");", ScriptController::ExecuteScriptWhenScriptsDisabled);
- return true;
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorClient.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorClient.h
index 4a69725f62f..181ba27d211 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorClient.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorClient.h
@@ -35,7 +35,6 @@
namespace WebCore {
class IntPoint;
-class Page;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
@@ -50,12 +49,17 @@ public:
typedef void (*TraceEventCallback)(char phase, const unsigned char*, const char* name, unsigned long long id,
int numArgs, const char* const* argNames, const unsigned char* argTypes, const unsigned long long* argValues,
unsigned char flags, double timestamp);
- virtual void setTraceEventCallback(TraceEventCallback) { }
+ virtual void setTraceEventCallback(const String& categoryFilter, TraceEventCallback) { }
+ virtual void resetTraceEventCallback() { }
+ virtual void enableTracing(const String& categoryFilter) { }
+ virtual void disableTracing() { }
virtual void startGPUEventsRecording() { }
virtual void stopGPUEventsRecording() { }
- virtual void overrideDeviceMetrics(int /*width*/, int /*height*/, float /*deviceScaleFactor*/, bool /*emulateViewport*/, bool /*fitWindow*/) { }
+ virtual void setDeviceMetricsOverride(int /*width*/, int /*height*/, float /*deviceScaleFactor*/, bool /*emulateViewport*/, bool /*fitWindow*/) { }
+ virtual void clearDeviceMetricsOverride() { }
+ virtual void setTouchEventEmulationEnabled(bool) { }
virtual bool overridesShowPaintRects() { return false; }
virtual void setShowPaintRects(bool) { }
@@ -71,8 +75,6 @@ public:
virtual void dispatchKeyEvent(const PlatformKeyboardEvent&) { }
virtual void dispatchMouseEvent(const PlatformMouseEvent&) { }
- static bool doDispatchMessageOnFrontendPage(Page* frontendPage, const String& message);
-
protected:
virtual ~InspectorClient() { }
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp
index 06f9e6a05c9..cd337b1dc86 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.cpp
@@ -28,9 +28,8 @@
#include "bindings/v8/ScriptCallStackFactory.h"
#include "bindings/v8/ScriptController.h"
-#include "bindings/v8/ScriptObject.h"
#include "bindings/v8/ScriptProfiler.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/ConsoleMessage.h"
#include "core/inspector/InjectedScriptHost.h"
#include "core/inspector/InjectedScriptManager.h"
@@ -62,16 +61,14 @@ static const char consoleMessagesEnabled[] = "consoleMessagesEnabled";
int InspectorConsoleAgent::s_enabledAgentCount = 0;
-InspectorConsoleAgent::InspectorConsoleAgent(InstrumentingAgents* instrumentingAgents, InspectorTimelineAgent* timelineAgent, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager)
- : InspectorBaseAgent<InspectorConsoleAgent>("Console", instrumentingAgents, state)
+InspectorConsoleAgent::InspectorConsoleAgent(InspectorTimelineAgent* timelineAgent, InjectedScriptManager* injectedScriptManager)
+ : InspectorBaseAgent<InspectorConsoleAgent>("Console")
, m_timelineAgent(timelineAgent)
, m_injectedScriptManager(injectedScriptManager)
, m_frontend(0)
- , m_previousMessage(0)
, m_expiredConsoleMessageCount(0)
, m_enabled(false)
{
- m_instrumentingAgents->setInspectorConsoleAgent(this);
}
InspectorConsoleAgent::~InspectorConsoleAgent()
@@ -82,6 +79,11 @@ InspectorConsoleAgent::~InspectorConsoleAgent()
m_injectedScriptManager = 0;
}
+void InspectorConsoleAgent::init()
+{
+ m_instrumentingAgents->setInspectorConsoleAgent(this);
+}
+
void InspectorConsoleAgent::enable(ErrorString*)
{
if (m_enabled)
@@ -118,7 +120,6 @@ void InspectorConsoleAgent::clearMessages(ErrorString*)
{
m_consoleMessages.clear();
m_expiredConsoleMessageCount = 0;
- m_previousMessage = 0;
m_injectedScriptManager->releaseObjectGroup("console");
if (m_frontend && m_enabled)
m_frontend->messagesCleared();
@@ -153,7 +154,7 @@ void InspectorConsoleAgent::clearFrontend()
disable(&errorString);
}
-void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier)
+void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, unsigned long requestIdentifier)
{
if (type == ClearMessageType) {
ErrorString error;
@@ -163,17 +164,17 @@ void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageTyp
addConsoleMessage(adoptPtr(new ConsoleMessage(!isWorkerAgent(), source, type, level, message, callStack, requestIdentifier)));
}
-void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, ScriptState* state, PassRefPtr<ScriptArguments> arguments, unsigned long requestIdentifier)
+void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments, unsigned long requestIdentifier)
{
if (type == ClearMessageType) {
ErrorString error;
clearMessages(&error);
}
- addConsoleMessage(adoptPtr(new ConsoleMessage(!isWorkerAgent(), source, type, level, message, arguments, state, requestIdentifier)));
+ addConsoleMessage(adoptPtr(new ConsoleMessage(!isWorkerAgent(), source, type, level, message, arguments, scriptState, requestIdentifier)));
}
-void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptId, unsigned lineNumber, unsigned columnNumber, ScriptState* state, unsigned long requestIdentifier)
+void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptId, unsigned lineNumber, unsigned columnNumber, ScriptState* scriptState, unsigned long requestIdentifier)
{
if (type == ClearMessageType) {
ErrorString error;
@@ -181,7 +182,7 @@ void InspectorConsoleAgent::addMessageToConsole(MessageSource source, MessageTyp
}
bool canGenerateCallStack = !isWorkerAgent() && m_frontend;
- addConsoleMessage(adoptPtr(new ConsoleMessage(canGenerateCallStack, source, type, level, message, scriptId, lineNumber, columnNumber, state, requestIdentifier)));
+ addConsoleMessage(adoptPtr(new ConsoleMessage(canGenerateCallStack, source, type, level, message, scriptId, lineNumber, columnNumber, scriptState, requestIdentifier)));
}
Vector<unsigned> InspectorConsoleAgent::consoleMessageArgumentCounts()
@@ -202,7 +203,7 @@ void InspectorConsoleAgent::consoleTime(ExecutionContext*, const String& title)
m_times.add(title, monotonicallyIncreasingTime());
}
-void InspectorConsoleAgent::consoleTimeEnd(ExecutionContext*, const String& title, ScriptState* state)
+void InspectorConsoleAgent::consoleTimeEnd(ExecutionContext*, const String& title, ScriptState* scriptState)
{
// Follow Firebug's behavior of requiring a title that is not null or
// undefined for timing functions
@@ -218,22 +219,22 @@ void InspectorConsoleAgent::consoleTimeEnd(ExecutionContext*, const String& titl
double elapsed = monotonicallyIncreasingTime() - startTime;
String message = title + String::format(": %.3fms", elapsed * 1000);
- addMessageToConsole(ConsoleAPIMessageSource, LogMessageType, DebugMessageLevel, message, String(), 0, 0, state);
+ addMessageToConsole(ConsoleAPIMessageSource, LogMessageType, DebugMessageLevel, message, String(), 0, 0, scriptState);
}
-void InspectorConsoleAgent::consoleTimeline(ExecutionContext* context, const String& title, ScriptState* state)
+void InspectorConsoleAgent::consoleTimeline(ExecutionContext* context, const String& title, ScriptState* scriptState)
{
- m_timelineAgent->consoleTimeline(context, title, state);
+ m_timelineAgent->consoleTimeline(context, title, scriptState);
}
-void InspectorConsoleAgent::consoleTimelineEnd(ExecutionContext* context, const String& title, ScriptState* state)
+void InspectorConsoleAgent::consoleTimelineEnd(ExecutionContext* context, const String& title, ScriptState* scriptState)
{
- m_timelineAgent->consoleTimelineEnd(context, title, state);
+ m_timelineAgent->consoleTimelineEnd(context, title, scriptState);
}
-void InspectorConsoleAgent::consoleCount(ScriptState* state, PassRefPtr<ScriptArguments> arguments)
+void InspectorConsoleAgent::consoleCount(ScriptState* scriptState, PassRefPtrWillBeRawPtr<ScriptArguments> arguments)
{
- RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole());
+ RefPtrWillBeRawPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(scriptState));
const ScriptCallFrame& lastCaller = callStack->at(0);
// Follow Firebug's behavior of counting with null and undefined title in
// the same bucket as no argument
@@ -243,11 +244,11 @@ void InspectorConsoleAgent::consoleCount(ScriptState* state, PassRefPtr<ScriptAr
: String(title + '@');
HashCountedSet<String>::AddResult result = m_counts.add(identifier);
- String message = title + ": " + String::number(result.iterator->value);
- addMessageToConsole(ConsoleAPIMessageSource, LogMessageType, DebugMessageLevel, message, callStack);
+ String message = title + ": " + String::number(result.storedValue->value);
+ addMessageToConsole(ConsoleAPIMessageSource, LogMessageType, DebugMessageLevel, message, callStack.get());
}
-void InspectorConsoleAgent::frameWindowDiscarded(DOMWindow* window)
+void InspectorConsoleAgent::frameWindowDiscarded(LocalDOMWindow* window)
{
size_t messageCount = m_consoleMessages.size();
for (size_t i = 0; i < messageCount; ++i)
@@ -255,22 +256,22 @@ void InspectorConsoleAgent::frameWindowDiscarded(DOMWindow* window)
m_injectedScriptManager->discardInjectedScriptsFor(window);
}
-void InspectorConsoleAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorConsoleAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
{
if (loader->frame() != frame->page()->mainFrame())
return;
reset();
}
-void InspectorConsoleAgent::didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient*, unsigned long requestIdentifier, ScriptString, const String& url, const String& sendURL, unsigned sendLineNumber)
+void InspectorConsoleAgent::didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient*, unsigned long requestIdentifier, ScriptString, const AtomicString& method, const String& url, const String& sendURL, unsigned sendLineNumber)
{
if (m_frontend && m_state->getBoolean(ConsoleAgentState::monitoringXHR)) {
- String message = "XHR finished loading: \"" + url + "\".";
+ String message = "XHR finished loading: " + method + " \"" + url + "\".";
addMessageToConsole(NetworkMessageSource, LogMessageType, DebugMessageLevel, message, sendURL, sendLineNumber, 0, 0, requestIdentifier);
}
}
-void InspectorConsoleAgent::didReceiveResourceResponse(Frame*, unsigned long requestIdentifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
+void InspectorConsoleAgent::didReceiveResourceResponse(LocalFrame*, unsigned long requestIdentifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
{
if (!loader)
return;
@@ -280,7 +281,7 @@ void InspectorConsoleAgent::didReceiveResourceResponse(Frame*, unsigned long req
}
}
-void InspectorConsoleAgent::didFailLoading(unsigned long requestIdentifier, DocumentLoader*, const ResourceError& error)
+void InspectorConsoleAgent::didFailLoading(unsigned long requestIdentifier, const ResourceError& error)
{
if (error.isCancellation()) // Report failures only.
return;
@@ -298,27 +299,14 @@ void InspectorConsoleAgent::setMonitoringXHREnabled(ErrorString*, bool enabled)
m_state->setBoolean(ConsoleAgentState::monitoringXHR, enabled);
}
-static bool isGroupMessage(MessageType type)
-{
- return type == StartGroupMessageType
- || type == StartGroupCollapsedMessageType
- || type == EndGroupMessageType;
-}
-
void InspectorConsoleAgent::addConsoleMessage(PassOwnPtr<ConsoleMessage> consoleMessage)
{
ASSERT_ARG(consoleMessage, consoleMessage);
- if (m_previousMessage && !isGroupMessage(m_previousMessage->type()) && m_previousMessage->isEqual(consoleMessage.get())) {
- m_previousMessage->incrementCount();
- if (m_frontend && m_enabled)
- m_previousMessage->updateRepeatCountInConsole(m_frontend);
- } else {
- m_previousMessage = consoleMessage.get();
- m_consoleMessages.append(consoleMessage);
- if (m_frontend && m_enabled)
- m_previousMessage->addToFrontend(m_frontend, m_injectedScriptManager, true);
- }
+ if (m_frontend && m_enabled)
+ consoleMessage->addToFrontend(m_frontend, m_injectedScriptManager, true);
+
+ m_consoleMessages.append(consoleMessage);
if (!m_frontend && m_consoleMessages.size() >= maximumConsoleMessages) {
m_expiredConsoleMessageCount += expireConsoleMessagesStep;
@@ -326,10 +314,10 @@ void InspectorConsoleAgent::addConsoleMessage(PassOwnPtr<ConsoleMessage> console
}
}
-class InspectableHeapObject : public InjectedScriptHost::InspectableObject {
+class InspectableHeapObject FINAL : public InjectedScriptHost::InspectableObject {
public:
explicit InspectableHeapObject(int heapObjectId) : m_heapObjectId(heapObjectId) { }
- virtual ScriptValue get(ScriptState*)
+ virtual ScriptValue get(ScriptState*) OVERRIDE
{
return ScriptProfiler::objectByHeapObjectId(m_heapObjectId);
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h
index 142728f5744..6bcfad433fa 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleAgent.h
@@ -25,9 +25,9 @@
#ifndef InspectorConsoleAgent_h
#define InspectorConsoleAgent_h
-#include "InspectorFrontend.h"
#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptString.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/ConsoleAPITypes.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "core/frame/ConsoleTypes.h"
@@ -42,8 +42,8 @@ namespace WebCore {
class ConsoleMessage;
class DocumentLoader;
-class DOMWindow;
-class Frame;
+class LocalDOMWindow;
+class LocalFrame;
class InspectorFrontend;
class InjectedScriptManager;
class InspectorTimelineAgent;
@@ -62,24 +62,25 @@ typedef String ErrorString;
class InspectorConsoleAgent : public InspectorBaseAgent<InspectorConsoleAgent>, public InspectorBackendDispatcher::ConsoleCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorConsoleAgent);
public:
- InspectorConsoleAgent(InstrumentingAgents*, InspectorTimelineAgent*, InspectorCompositeState*, InjectedScriptManager*);
+ InspectorConsoleAgent(InspectorTimelineAgent*, InjectedScriptManager*);
virtual ~InspectorConsoleAgent();
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void clearMessages(ErrorString*);
+ virtual void init() OVERRIDE;
+ virtual void enable(ErrorString*) OVERRIDE FINAL;
+ virtual void disable(ErrorString*) OVERRIDE FINAL;
+ virtual void clearMessages(ErrorString*) OVERRIDE;
bool enabled() { return m_enabled; }
void reset();
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE FINAL;
+ virtual void clearFrontend() OVERRIDE FINAL;
+ virtual void restore() OVERRIDE FINAL;
- void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, ScriptState*, PassRefPtr<ScriptArguments>, unsigned long requestIdentifier = 0);
+ void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>, unsigned long requestIdentifier = 0);
void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, const String& scriptId, unsigned lineNumber, unsigned columnNumber = 0, ScriptState* = 0, unsigned long requestIdentifier = 0);
// FIXME: Remove once we no longer generate stacks outside of Inspector.
- void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>, unsigned long requestIdentifier = 0);
+ void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack>, unsigned long requestIdentifier = 0);
Vector<unsigned> consoleMessageArgumentCounts();
@@ -88,19 +89,19 @@ public:
void consoleTimeline(ExecutionContext*, const String& title, ScriptState*);
void consoleTimelineEnd(ExecutionContext*, const String& title, ScriptState*);
- void consoleCount(ScriptState*, PassRefPtr<ScriptArguments>);
+ void consoleCount(ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>);
- void frameWindowDiscarded(DOMWindow*);
- void didCommitLoad(Frame*, DocumentLoader*);
+ void frameWindowDiscarded(LocalDOMWindow*);
+ void didCommitLoad(LocalFrame*, DocumentLoader*);
- void didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient*, unsigned long requestIdentifier, ScriptString, const String& url, const String& sendURL, unsigned sendLineNumber);
- void didReceiveResourceResponse(Frame*, unsigned long requestIdentifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
- void didFailLoading(unsigned long requestIdentifier, DocumentLoader*, const ResourceError&);
- void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
+ void didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient*, unsigned long requestIdentifier, ScriptString, const AtomicString& method, const String& url, const String& sendURL, unsigned sendLineNumber);
+ void didReceiveResourceResponse(LocalFrame*, unsigned long requestIdentifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+ void didFailLoading(unsigned long requestIdentifier, const ResourceError&);
+ void addProfileFinishedMessageToConsole(PassRefPtrWillBeRawPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL);
- virtual void setMonitoringXHREnabled(ErrorString*, bool enabled);
+ virtual void setMonitoringXHREnabled(ErrorString*, bool enabled) OVERRIDE;
virtual void addInspectedNode(ErrorString*, int nodeId) = 0;
- virtual void addInspectedHeapObject(ErrorString*, int inspectedHeapObjectId);
+ virtual void addInspectedHeapObject(ErrorString*, int inspectedHeapObjectId) OVERRIDE;
virtual bool isWorkerAgent() = 0;
@@ -110,7 +111,6 @@ protected:
InspectorTimelineAgent* m_timelineAgent;
InjectedScriptManager* m_injectedScriptManager;
InspectorFrontend::Console* m_frontend;
- ConsoleMessage* m_previousMessage;
Vector<OwnPtr<ConsoleMessage> > m_consoleMessages;
int m_expiredConsoleMessageCount;
HashCountedSet<String> m_counts;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleInstrumentation.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleInstrumentation.h
index 55a8ef8851b..c819ccf113d 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleInstrumentation.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorConsoleInstrumentation.h
@@ -1 +1 @@
-#include "InspectorConsoleInstrumentationInl.h"
+#include "core/InspectorConsoleInstrumentationInl.h"
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorController.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorController.cpp
index 0e3f017eb8c..3da18d975b1 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorController.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorController.cpp
@@ -31,13 +31,12 @@
#include "config.h"
#include "core/inspector/InspectorController.h"
-#include "InspectorBackendDispatcher.h"
-#include "InspectorFrontend.h"
#include "bindings/v8/DOMWrapperWorld.h"
+#include "core/InspectorBackendDispatcher.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/IdentifiersFactory.h"
#include "core/inspector/InjectedScriptHost.h"
#include "core/inspector/InjectedScriptManager.h"
-#include "core/inspector/InspectorAgent.h"
#include "core/inspector/InspectorApplicationCacheAgent.h"
#include "core/inspector/InspectorCSSAgent.h"
#include "core/inspector/InspectorCanvasAgent.h"
@@ -45,13 +44,11 @@
#include "core/inspector/InspectorDOMAgent.h"
#include "core/inspector/InspectorDOMDebuggerAgent.h"
#include "core/inspector/InspectorDOMStorageAgent.h"
-#include "core/inspector/InspectorDatabaseAgent.h"
#include "core/inspector/InspectorDebuggerAgent.h"
-#include "core/inspector/InspectorFileSystemAgent.h"
#include "core/inspector/InspectorFrontendClient.h"
#include "core/inspector/InspectorHeapProfilerAgent.h"
-#include "core/inspector/InspectorIndexedDBAgent.h"
#include "core/inspector/InspectorInputAgent.h"
+#include "core/inspector/InspectorInspectorAgent.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/InspectorLayerTreeAgent.h"
#include "core/inspector/InspectorMemoryAgent.h"
@@ -61,12 +58,14 @@
#include "core/inspector/InspectorResourceAgent.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InspectorTimelineAgent.h"
+#include "core/inspector/InspectorTracingAgent.h"
#include "core/inspector/InspectorWorkerAgent.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/inspector/PageConsoleAgent.h"
#include "core/inspector/PageDebuggerAgent.h"
#include "core/inspector/PageRuntimeAgent.h"
#include "core/page/Page.h"
+#include "core/rendering/RenderLayer.h"
#include "platform/PlatformMouseEvent.h"
namespace WebCore {
@@ -76,92 +75,123 @@ InspectorController::InspectorController(Page* page, InspectorClient* inspectorC
, m_injectedScriptManager(InjectedScriptManager::createForPage())
, m_state(adoptPtr(new InspectorCompositeState(inspectorClient)))
, m_overlay(InspectorOverlay::create(page, inspectorClient))
+ , m_layerTreeAgent(0)
, m_page(page)
, m_inspectorClient(inspectorClient)
+ , m_agents(m_instrumentingAgents.get(), m_state.get())
, m_isUnderTest(false)
+ , m_deferredAgentsInitialized(false)
{
- m_agents.append(InspectorAgent::create(page, m_injectedScriptManager.get(), m_instrumentingAgents.get(), m_state.get()));
+ InjectedScriptManager* injectedScriptManager = m_injectedScriptManager.get();
+ InspectorOverlay* overlay = m_overlay.get();
- OwnPtr<InspectorPageAgent> pageAgentPtr(InspectorPageAgent::create(m_instrumentingAgents.get(), page, m_state.get(), m_injectedScriptManager.get(), inspectorClient, m_overlay.get()));
- InspectorPageAgent* pageAgent = pageAgentPtr.get();
+ m_agents.append(InspectorInspectorAgent::create(m_page, injectedScriptManager));
+
+ OwnPtr<InspectorPageAgent> pageAgentPtr(InspectorPageAgent::create(m_page, injectedScriptManager, inspectorClient, overlay));
+ m_pageAgent = pageAgentPtr.get();
m_agents.append(pageAgentPtr.release());
- OwnPtr<InspectorDOMAgent> domAgentPtr(InspectorDOMAgent::create(m_instrumentingAgents.get(), pageAgent, m_state.get(), m_injectedScriptManager.get(), m_overlay.get(), inspectorClient));
- InspectorDOMAgent* domAgent = domAgentPtr.get();
+ OwnPtr<InspectorDOMAgent> domAgentPtr(InspectorDOMAgent::create(m_pageAgent, injectedScriptManager, overlay));
+ m_domAgent = domAgentPtr.get();
m_agents.append(domAgentPtr.release());
- OwnPtr<InspectorResourceAgent> resourceAgentPtr(InspectorResourceAgent::create(m_instrumentingAgents.get(), pageAgent, inspectorClient, m_state.get()));
- InspectorResourceAgent* resourceAgent = resourceAgentPtr.get();
- m_agents.append(resourceAgentPtr.release());
- m_agents.append(InspectorCSSAgent::create(m_instrumentingAgents.get(), m_state.get(), domAgent, pageAgent, resourceAgent));
+ OwnPtr<InspectorLayerTreeAgent> layerTreeAgentPtr(InspectorLayerTreeAgent::create(m_page));
+ m_layerTreeAgent = layerTreeAgentPtr.get();
+ m_agents.append(layerTreeAgentPtr.release());
- m_agents.append(InspectorDatabaseAgent::create(m_instrumentingAgents.get(), m_state.get()));
+ OwnPtr<InspectorTracingAgent> tracingAgentPtr = InspectorTracingAgent::create(inspectorClient);
+ m_tracingAgent = tracingAgentPtr.get();
+ m_agents.append(tracingAgentPtr.release());
- m_agents.append(InspectorIndexedDBAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get(), pageAgent));
+ OwnPtr<InspectorTimelineAgent> timelineAgentPtr(InspectorTimelineAgent::create(m_pageAgent, m_layerTreeAgent,
+ overlay, InspectorTimelineAgent::PageInspector, inspectorClient));
+ m_timelineAgent = timelineAgentPtr.get();
+ m_agents.append(timelineAgentPtr.release());
- m_agents.append(InspectorFileSystemAgent::create(m_instrumentingAgents.get(), pageAgent, m_state.get()));
+ PageScriptDebugServer* pageScriptDebugServer = &PageScriptDebugServer::shared();
- m_agents.append(InspectorDOMStorageAgent::create(m_instrumentingAgents.get(), pageAgent, m_state.get()));
+ m_agents.append(PageRuntimeAgent::create(injectedScriptManager, pageScriptDebugServer, m_page, m_pageAgent));
- OwnPtr<InspectorMemoryAgent> memoryAgentPtr(InspectorMemoryAgent::create(m_instrumentingAgents.get(), m_state.get()));
- m_memoryAgent = memoryAgentPtr.get();
- m_agents.append(memoryAgentPtr.release());
+ m_agents.append(PageConsoleAgent::create(injectedScriptManager, m_domAgent, m_timelineAgent));
- OwnPtr<InspectorTimelineAgent> timelineAgentPtr(InspectorTimelineAgent::create(m_instrumentingAgents.get(), pageAgent, m_memoryAgent, domAgent, m_overlay.get(), m_state.get(),
- InspectorTimelineAgent::PageInspector, inspectorClient));
- m_timelineAgent = timelineAgentPtr.get();
- m_agents.append(timelineAgentPtr.release());
+ m_agents.append(InspectorWorkerAgent::create());
- m_agents.append(InspectorApplicationCacheAgent::create(m_instrumentingAgents.get(), m_state.get(), pageAgent));
+ ASSERT_ARG(inspectorClient, inspectorClient);
+ m_injectedScriptManager->injectedScriptHost()->init(m_instrumentingAgents.get(), pageScriptDebugServer);
+}
- PageScriptDebugServer* pageScriptDebugServer = &PageScriptDebugServer::shared();
+InspectorController::~InspectorController()
+{
+}
- m_agents.append(PageRuntimeAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get(), pageScriptDebugServer, page, pageAgent));
+PassOwnPtr<InspectorController> InspectorController::create(Page* page, InspectorClient* client)
+{
+ return adoptPtr(new InspectorController(page, client));
+}
- m_agents.append(PageConsoleAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get(), domAgent, m_timelineAgent));
+void InspectorController::setTextAutosizingEnabled(bool enabled)
+{
+ m_pageAgent->setTextAutosizingEnabled(enabled);
+}
- OwnPtr<InspectorDebuggerAgent> debuggerAgentPtr(PageDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), pageScriptDebugServer, pageAgent, m_injectedScriptManager.get(), m_overlay.get()));
- InspectorDebuggerAgent* debuggerAgent = debuggerAgentPtr.get();
- m_agents.append(debuggerAgentPtr.release());
+void InspectorController::setDeviceScaleAdjustment(float deviceScaleAdjustment)
+{
+ m_pageAgent->setDeviceScaleAdjustment(deviceScaleAdjustment);
+}
- m_agents.append(InspectorDOMDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), domAgent, debuggerAgent));
+void InspectorController::initializeDeferredAgents()
+{
+ if (m_deferredAgentsInitialized)
+ return;
+ m_deferredAgentsInitialized = true;
- m_agents.append(InspectorProfilerAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get(), m_overlay.get()));
+ InjectedScriptManager* injectedScriptManager = m_injectedScriptManager.get();
+ InspectorOverlay* overlay = m_overlay.get();
- m_agents.append(InspectorHeapProfilerAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get()));
+ OwnPtr<InspectorResourceAgent> resourceAgentPtr(InspectorResourceAgent::create(m_pageAgent));
+ m_resourceAgent = resourceAgentPtr.get();
+ m_agents.append(resourceAgentPtr.release());
+ m_agents.append(InspectorCSSAgent::create(m_domAgent, m_pageAgent, m_resourceAgent));
- m_agents.append(InspectorWorkerAgent::create(m_instrumentingAgents.get(), m_state.get()));
+ m_agents.append(InspectorDOMStorageAgent::create(m_pageAgent));
- m_agents.append(InspectorCanvasAgent::create(m_instrumentingAgents.get(), m_state.get(), pageAgent, m_injectedScriptManager.get()));
+ m_agents.append(InspectorMemoryAgent::create());
- m_agents.append(InspectorInputAgent::create(m_instrumentingAgents.get(), m_state.get(), page, inspectorClient));
+ m_agents.append(InspectorApplicationCacheAgent::create(m_pageAgent));
- m_agents.append(InspectorLayerTreeAgent::create(m_instrumentingAgents.get(), m_state.get(), domAgent, page));
+ PageScriptDebugServer* pageScriptDebugServer = &PageScriptDebugServer::shared();
- ASSERT_ARG(inspectorClient, inspectorClient);
- m_injectedScriptManager->injectedScriptHost()->init(m_instrumentingAgents.get(), pageScriptDebugServer);
-}
+ OwnPtr<InspectorDebuggerAgent> debuggerAgentPtr(PageDebuggerAgent::create(pageScriptDebugServer, m_pageAgent, injectedScriptManager, overlay));
+ InspectorDebuggerAgent* debuggerAgent = debuggerAgentPtr.get();
+ m_agents.append(debuggerAgentPtr.release());
-InspectorController::~InspectorController()
-{
- m_instrumentingAgents->reset();
- m_agents.discardAgents();
- ASSERT(!m_inspectorClient);
-}
+ m_agents.append(InspectorDOMDebuggerAgent::create(m_domAgent, debuggerAgent));
-PassOwnPtr<InspectorController> InspectorController::create(Page* page, InspectorClient* client)
-{
- return adoptPtr(new InspectorController(page, client));
+ m_agents.append(InspectorProfilerAgent::create(injectedScriptManager, overlay));
+
+ m_agents.append(InspectorHeapProfilerAgent::create(injectedScriptManager));
+
+ m_agents.append(InspectorCanvasAgent::create(m_pageAgent, injectedScriptManager));
+
+ m_agents.append(InspectorInputAgent::create(m_page, m_inspectorClient));
}
-void InspectorController::inspectedPageDestroyed()
+void InspectorController::willBeDestroyed()
{
disconnectFrontend();
m_injectedScriptManager->disconnect();
m_inspectorClient = 0;
m_page = 0;
+ m_instrumentingAgents->reset();
+ m_agents.discardAgents();
+}
+
+void InspectorController::registerModuleAgent(PassOwnPtr<InspectorAgent> agent)
+{
+ m_moduleAgents.append(agent.get());
+ m_agents.append(agent);
}
void InspectorController::setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient> inspectorFrontendClient)
@@ -169,20 +199,21 @@ void InspectorController::setInspectorFrontendClient(PassOwnPtr<InspectorFronten
m_inspectorFrontendClient = inspectorFrontendClient;
}
-void InspectorController::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
+void InspectorController::didClearDocumentOfWindowObject(LocalFrame* frame)
{
- if (world != mainThreadNormalWorld())
- return;
-
// If the page is supposed to serve as InspectorFrontend notify inspector frontend
// client that it's cleared so that the client can expose inspector bindings.
if (m_inspectorFrontendClient && frame == m_page->mainFrame())
m_inspectorFrontendClient->windowObjectCleared();
}
-void InspectorController::connectFrontend(InspectorFrontendChannel* frontendChannel)
+void InspectorController::connectFrontend(const String& hostId, InspectorFrontendChannel* frontendChannel)
{
ASSERT(frontendChannel);
+ m_hostId = hostId;
+
+ initializeDeferredAgents();
+ m_resourceAgent->setHostId(hostId);
m_inspectorFrontend = adoptPtr(new InspectorFrontend(frontendChannel));
// We can reconnect to existing front-end -> unmute state.
@@ -218,21 +249,23 @@ void InspectorController::disconnectFrontend()
m_overlay->freePage();
InspectorInstrumentation::frontendDeleted();
InspectorInstrumentation::unregisterInstrumentingAgents(m_instrumentingAgents.get());
+ m_hostId = "";
}
void InspectorController::reconnectFrontend()
{
if (!m_inspectorFrontend)
return;
- InspectorFrontendChannel* frontendChannel = m_inspectorFrontend->inspector()->getInspectorFrontendChannel();
+ InspectorFrontendChannel* frontendChannel = m_inspectorFrontend->channel();
+ String hostId = m_hostId;
disconnectFrontend();
- connectFrontend(frontendChannel);
+ connectFrontend(hostId, frontendChannel);
}
-void InspectorController::reuseFrontend(InspectorFrontendChannel* frontendChannel, const String& inspectorStateCookie)
+void InspectorController::reuseFrontend(const String& hostId, InspectorFrontendChannel* frontendChannel, const String& inspectorStateCookie)
{
ASSERT(!m_inspectorFrontend);
- connectFrontend(frontendChannel);
+ connectFrontend(hostId, frontendChannel);
m_state->loadFromCookie(inspectorStateCookie);
m_agents.restore();
}
@@ -245,12 +278,7 @@ void InspectorController::setProcessId(long processId)
void InspectorController::setLayerTreeId(int id)
{
m_timelineAgent->setLayerTreeId(id);
-}
-
-void InspectorController::webViewResized(const IntSize& size)
-{
- if (InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent())
- pageAgent->webViewResized(size);
+ m_tracingAgent->setLayerTreeId(id);
}
bool InspectorController::isUnderTest()
@@ -261,7 +289,7 @@ bool InspectorController::isUnderTest()
void InspectorController::evaluateForTestInFrontend(long callId, const String& script)
{
m_isUnderTest = true;
- if (InspectorAgent* inspectorAgent = m_instrumentingAgents->inspectorAgent())
+ if (InspectorInspectorAgent* inspectorAgent = m_instrumentingAgents->inspectorInspectorAgent())
inspectorAgent->evaluateForTestInFrontend(callId, script);
}
@@ -270,11 +298,6 @@ void InspectorController::drawHighlight(GraphicsContext& context) const
m_overlay->paint(context);
}
-void InspectorController::getHighlight(Highlight* highlight) const
-{
- m_overlay->getHighlight(highlight);
-}
-
void InspectorController::inspect(Node* node)
{
if (!node)
@@ -282,22 +305,22 @@ void InspectorController::inspect(Node* node)
Document* document = node->ownerDocument();
if (!document)
return;
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
if (!frame)
return;
- if (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE)
+ if (!node->isElementNode() && !node->isDocumentNode())
node = node->parentNode();
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(mainWorldScriptState(frame));
- if (injectedScript.hasNoValue())
+ InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(ScriptState::forMainWorld(frame));
+ if (injectedScript.isEmpty())
return;
injectedScript.inspectNode(node);
}
void InspectorController::setInjectedScriptForOrigin(const String& origin, const String& source)
{
- if (InspectorAgent* inspectorAgent = m_instrumentingAgents->inspectorAgent())
+ if (InspectorInspectorAgent* inspectorAgent = m_instrumentingAgents->inspectorInspectorAgent())
inspectorAgent->setInjectedScriptForOrigin(origin, source);
}
@@ -307,17 +330,7 @@ void InspectorController::dispatchMessageFromFrontend(const String& message)
m_inspectorBackendDispatcher->dispatch(message);
}
-void InspectorController::hideHighlight()
-{
- m_overlay->hideHighlight();
-}
-
-Node* InspectorController::highlightedNode() const
-{
- return m_overlay->highlightedNode();
-}
-
-bool InspectorController::handleGestureEvent(Frame* frame, const PlatformGestureEvent& event)
+bool InspectorController::handleGestureEvent(LocalFrame* frame, const PlatformGestureEvent& event)
{
// Overlay should not consume events.
m_overlay->handleGestureEvent(event);
@@ -326,7 +339,7 @@ bool InspectorController::handleGestureEvent(Frame* frame, const PlatformGesture
return false;
}
-bool InspectorController::handleMouseEvent(Frame* frame, const PlatformMouseEvent& event)
+bool InspectorController::handleMouseEvent(LocalFrame* frame, const PlatformMouseEvent& event)
{
// Overlay should not consume events.
m_overlay->handleMouseEvent(event);
@@ -343,7 +356,7 @@ bool InspectorController::handleMouseEvent(Frame* frame, const PlatformMouseEven
return false;
}
-bool InspectorController::handleTouchEvent(Frame* frame, const PlatformTouchEvent& event)
+bool InspectorController::handleTouchEvent(LocalFrame* frame, const PlatformTouchEvent& event)
{
// Overlay should not consume events.
m_overlay->handleTouchEvent(event);
@@ -352,7 +365,7 @@ bool InspectorController::handleTouchEvent(Frame* frame, const PlatformTouchEven
return false;
}
-bool InspectorController::handleKeyboardEvent(Frame* frame, const PlatformKeyboardEvent& event)
+bool InspectorController::handleKeyboardEvent(LocalFrame* frame, const PlatformKeyboardEvent& event)
{
// Overlay should not consume events.
m_overlay->handleKeyboardEvent(event);
@@ -381,8 +394,8 @@ void InspectorController::resume()
void InspectorController::setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize)
{
- if (InspectorResourceAgent* resourceAgent = m_instrumentingAgents->inspectorResourceAgent())
- resourceAgent->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
+ if (m_resourceAgent)
+ m_resourceAgent->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
}
void InspectorController::willProcessTask()
@@ -403,6 +416,18 @@ void InspectorController::didProcessTask()
domDebuggerAgent->didProcessTask();
}
+void InspectorController::flushPendingFrontendMessages()
+{
+ m_agents.flushPendingFrontendMessages();
+}
+
+void InspectorController::didCommitLoadForMainFrame()
+{
+ Vector<InspectorAgent*> agents = m_moduleAgents;
+ for (size_t i = 0; i < agents.size(); i++)
+ agents[i]->didCommitLoadForMainFrame();
+}
+
void InspectorController::didBeginFrame(int frameId)
{
if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
@@ -429,10 +454,28 @@ void InspectorController::didComposite()
timelineAgent->didComposite();
}
-void InspectorController::processGPUEvent(double timestamp, int phase, bool foreign, size_t usedGPUMemoryBytes)
+void InspectorController::processGPUEvent(double timestamp, int phase, bool foreign, uint64_t usedGPUMemoryBytes, uint64_t limitGPUMemoryBytes)
{
if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
- timelineAgent->processGPUEvent(InspectorTimelineAgent::GPUEvent(timestamp, phase, foreign, usedGPUMemoryBytes));
+ timelineAgent->processGPUEvent(InspectorTimelineAgent::GPUEvent(timestamp, phase, foreign, usedGPUMemoryBytes, limitGPUMemoryBytes));
+}
+
+void InspectorController::scriptsEnabled(bool enabled)
+{
+ if (InspectorPageAgent* pageAgent = m_instrumentingAgents->inspectorPageAgent())
+ pageAgent->scriptsEnabled(enabled);
+}
+
+void InspectorController::willAddPageOverlay(const GraphicsLayer* layer)
+{
+ if (m_layerTreeAgent)
+ m_layerTreeAgent->willAddPageOverlay(layer);
+}
+
+void InspectorController::didRemovePageOverlay(const GraphicsLayer* layer)
+{
+ if (m_layerTreeAgent)
+ m_layerTreeAgent->didRemovePageOverlay(layer);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorController.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorController.h
index f8e9af7a29a..85932ae4a02 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorController.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorController.h
@@ -35,21 +35,28 @@
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
+#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
class DOMWrapperWorld;
-class Frame;
+class LocalFrame;
class GraphicsContext;
+class GraphicsLayer;
class InjectedScriptManager;
class InspectorBackendDispatcher;
+class InspectorAgent;
class InspectorClient;
+class InspectorDOMAgent;
class InspectorFrontend;
class InspectorFrontendChannel;
class InspectorFrontendClient;
-class InspectorMemoryAgent;
+class InspectorLayerTreeAgent;
+class InspectorPageAgent;
+class InspectorResourceAgent;
class InspectorTimelineAgent;
+class InspectorTracingAgent;
class InspectorOverlay;
class InspectorState;
class InstrumentingAgents;
@@ -60,11 +67,8 @@ class PlatformGestureEvent;
class PlatformKeyboardEvent;
class PlatformMouseEvent;
class PlatformTouchEvent;
-class PostWorkerNotificationToFrontendTask;
class Node;
-struct Highlight;
-
class InspectorController {
WTF_MAKE_NONCOPYABLE(InspectorController);
WTF_MAKE_FAST_ALLOCATED;
@@ -72,32 +76,34 @@ public:
~InspectorController();
static PassOwnPtr<InspectorController> create(Page*, InspectorClient*);
- void inspectedPageDestroyed();
+
+ // Settings overrides.
+ void setTextAutosizingEnabled(bool);
+ void setDeviceScaleAdjustment(float);
+
+ void willBeDestroyed();
+ void registerModuleAgent(PassOwnPtr<InspectorAgent>);
void setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient>);
- void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*);
+ void didClearDocumentOfWindowObject(LocalFrame*);
void setInjectedScriptForOrigin(const String& origin, const String& source);
void dispatchMessageFromFrontend(const String& message);
- void connectFrontend(InspectorFrontendChannel*);
+ void connectFrontend(const String& hostId, InspectorFrontendChannel*);
void disconnectFrontend();
void reconnectFrontend();
- void reuseFrontend(InspectorFrontendChannel*, const String& inspectorStateCookie);
+ void reuseFrontend(const String& hostId, InspectorFrontendChannel*, const String& inspectorStateCookie);
void setProcessId(long);
void setLayerTreeId(int);
- void webViewResized(const IntSize&);
void inspect(Node*);
void drawHighlight(GraphicsContext&) const;
- void getHighlight(Highlight*) const;
- void hideHighlight();
- Node* highlightedNode() const;
- bool handleGestureEvent(Frame*, const PlatformGestureEvent&);
- bool handleMouseEvent(Frame*, const PlatformMouseEvent&);
- bool handleTouchEvent(Frame*, const PlatformTouchEvent&);
- bool handleKeyboardEvent(Frame*, const PlatformKeyboardEvent&);
+ bool handleGestureEvent(LocalFrame*, const PlatformGestureEvent&);
+ bool handleMouseEvent(LocalFrame*, const PlatformMouseEvent&);
+ bool handleTouchEvent(LocalFrame*, const PlatformTouchEvent&);
+ bool handleKeyboardEvent(LocalFrame*, const PlatformKeyboardEvent&);
void requestPageScaleFactor(float scale, const IntPoint& origin);
bool deviceEmulationEnabled();
@@ -111,18 +117,26 @@ public:
void willProcessTask();
void didProcessTask();
+ void flushPendingFrontendMessages();
+ void didCommitLoadForMainFrame();
void didBeginFrame(int frameId);
void didCancelFrame();
void willComposite();
void didComposite();
- void processGPUEvent(double timestamp, int phase, bool foreign, size_t usedGPUMemoryBytes);
+ void processGPUEvent(double timestamp, int phase, bool foreign, uint64_t usedGPUMemoryBytes, uint64_t limitGPUMemoryBytes);
+
+ void scriptsEnabled(bool);
+
+ void willAddPageOverlay(const GraphicsLayer*);
+ void didRemovePageOverlay(const GraphicsLayer*);
private:
InspectorController(Page*, InspectorClient*);
- friend class PostWorkerNotificationToFrontendTask;
+ void initializeDeferredAgents();
+
friend InstrumentingAgents* instrumentationForPage(Page*);
RefPtr<InstrumentingAgents> m_instrumentingAgents;
@@ -130,8 +144,12 @@ private:
OwnPtr<InspectorCompositeState> m_state;
OwnPtr<InspectorOverlay> m_overlay;
- InspectorMemoryAgent* m_memoryAgent;
+ InspectorDOMAgent* m_domAgent;
+ InspectorPageAgent* m_pageAgent;
+ InspectorResourceAgent* m_resourceAgent;
InspectorTimelineAgent* m_timelineAgent;
+ InspectorLayerTreeAgent* m_layerTreeAgent;
+ InspectorTracingAgent* m_tracingAgent;
RefPtr<InspectorBackendDispatcher> m_inspectorBackendDispatcher;
OwnPtr<InspectorFrontendClient> m_inspectorFrontendClient;
@@ -139,7 +157,10 @@ private:
Page* m_page;
InspectorClient* m_inspectorClient;
InspectorAgentRegistry m_agents;
+ Vector<InspectorAgent*> m_moduleAgents;
bool m_isUnderTest;
+ bool m_deferredAgentsInitialized;
+ String m_hostId;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorCounters.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorCounters.h
index 93e8284ef1a..4b848dbd0b7 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorCounters.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorCounters.h
@@ -33,7 +33,7 @@
#include "wtf/FastAllocBase.h"
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
#include "wtf/MainThread.h"
#endif
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
index a8f12bb7446..89f4a0b317f 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.cpp
@@ -31,7 +31,6 @@
#include "config.h"
#include "core/inspector/InspectorDOMAgent.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ScriptEventListener.h"
#include "core/dom/Attr.h"
@@ -42,31 +41,35 @@
#include "core/dom/DocumentFragment.h"
#include "core/dom/DocumentType.h"
#include "core/dom/Element.h"
-#include "core/events/EventListener.h"
-#include "core/events/EventTarget.h"
#include "core/dom/Node.h"
-#include "core/dom/NodeList.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/PseudoElement.h"
+#include "core/dom/StaticNodeList.h"
#include "core/dom/Text.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/markup.h"
+#include "core/events/EventListener.h"
+#include "core/events/EventTarget.h"
#include "core/fileapi/File.h"
#include "core/fileapi/FileList.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLInputElement.h"
+#include "core/html/HTMLLinkElement.h"
#include "core/html/HTMLTemplateElement.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportLoader.h"
#include "core/inspector/DOMEditor.h"
#include "core/inspector/DOMPatchSupport.h"
#include "core/inspector/IdentifiersFactory.h"
#include "core/inspector/InspectorHistory.h"
+#include "core/inspector/InspectorNodeIds.h"
#include "core/inspector/InspectorOverlay.h"
#include "core/inspector/InspectorPageAgent.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/FrameTree.h"
#include "core/page/Page.h"
#include "core/rendering/HitTestResult.h"
@@ -85,7 +88,7 @@ namespace WebCore {
using namespace HTMLNames;
namespace DOMAgentState {
-static const char documentRequested[] = "documentRequested";
+static const char domAgentEnabled[] = "domAgentEnabled";
};
static const size_t maxTextSize = 10000;
@@ -145,7 +148,7 @@ static bool parseQuad(const RefPtr<JSONArray>& quadArray, FloatQuad* quad)
return true;
}
-static Node* hoveredNodeForPoint(Frame* frame, const IntPoint& point, bool ignorePointerEventsNone)
+static Node* hoveredNodeForPoint(LocalFrame* frame, const IntPoint& point, bool ignorePointerEventsNone)
{
HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent;
if (ignorePointerEventsNone)
@@ -159,22 +162,22 @@ static Node* hoveredNodeForPoint(Frame* frame, const IntPoint& point, bool ignor
return node;
}
-static Node* hoveredNodeForEvent(Frame* frame, const PlatformGestureEvent& event, bool ignorePointerEventsNone)
+static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformGestureEvent& event, bool ignorePointerEventsNone)
{
return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
}
-static Node* hoveredNodeForEvent(Frame* frame, const PlatformMouseEvent& event, bool ignorePointerEventsNone)
+static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformMouseEvent& event, bool ignorePointerEventsNone)
{
return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
}
-static Node* hoveredNodeForEvent(Frame* frame, const PlatformTouchEvent& event, bool ignorePointerEventsNone)
+static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformTouchEvent& event, bool ignorePointerEventsNone)
{
const Vector<PlatformTouchPoint>& points = event.touchPoints();
if (!points.size())
return 0;
- return hoveredNodeForPoint(frame, points[0].pos(), ignorePointerEventsNone);
+ return hoveredNodeForPoint(frame, roundedIntPoint(points[0].pos()), ignorePointerEventsNone);
}
class RevalidateStyleAttributeTask {
@@ -188,7 +191,7 @@ public:
private:
InspectorDOMAgent* m_domAgent;
Timer<RevalidateStyleAttributeTask> m_timer;
- HashSet<RefPtr<Element> > m_elements;
+ WillBePersistentHeapHashSet<RefPtrWillBeMember<Element> > m_elements;
};
RevalidateStyleAttributeTask::RevalidateStyleAttributeTask(InspectorDOMAgent* domAgent)
@@ -201,14 +204,14 @@ void RevalidateStyleAttributeTask::scheduleFor(Element* element)
{
m_elements.add(element);
if (!m_timer.isActive())
- m_timer.startOneShot(0);
+ m_timer.startOneShot(0, FROM_HERE);
}
void RevalidateStyleAttributeTask::onTimer(Timer<RevalidateStyleAttributeTask>*)
{
// The timer is stopped on m_domAgent destruction, so this method will never be called after m_domAgent has been destroyed.
- Vector<Element*> elements;
- for (HashSet<RefPtr<Element> >::iterator it = m_elements.begin(), end = m_elements.end(); it != end; ++it)
+ WillBeHeapVector<RawPtrWillBeMember<Element> > elements;
+ for (WillBePersistentHeapHashSet<RefPtrWillBeMember<Element> >::iterator it = m_elements.begin(), end = m_elements.end(); it != end; ++it)
elements.append(it->get());
m_domAgent->styleAttributeInvalidated(elements);
@@ -218,22 +221,22 @@ void RevalidateStyleAttributeTask::onTimer(Timer<RevalidateStyleAttributeTask>*)
String InspectorDOMAgent::toErrorString(ExceptionState& exceptionState)
{
if (exceptionState.hadException())
- return DOMException::getErrorName(exceptionState.code());
+ return DOMException::getErrorName(exceptionState.code()) + " " + exceptionState.message();
return "";
}
-InspectorDOMAgent::InspectorDOMAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay, InspectorClient* client)
- : InspectorBaseAgent<InspectorDOMAgent>("DOM", instrumentingAgents, inspectorState)
+InspectorDOMAgent::InspectorDOMAgent(InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
+ : InspectorBaseAgent<InspectorDOMAgent>("DOM")
, m_pageAgent(pageAgent)
, m_injectedScriptManager(injectedScriptManager)
, m_overlay(overlay)
- , m_client(client)
, m_frontend(0)
, m_domListener(0)
+ , m_documentNodeToIdMap(adoptPtrWillBeNoop(new NodeToIdMap()))
, m_lastNodeId(1)
- , m_lastBackendNodeId(-1)
, m_searchingForNode(NotSearching)
, m_suppressAttributeModifiedEvent(false)
+ , m_listener(0)
{
}
@@ -246,8 +249,8 @@ InspectorDOMAgent::~InspectorDOMAgent()
void InspectorDOMAgent::setFrontend(InspectorFrontend* frontend)
{
ASSERT(!m_frontend);
- m_history = adoptPtr(new InspectorHistory());
- m_domEditor = adoptPtr(new DOMEditor(m_history.get()));
+ m_history = adoptPtrWillBeNoop(new InspectorHistory());
+ m_domEditor = adoptPtrWillBeNoop(new DOMEditor(m_history.get()));
m_frontend = frontend->dom();
m_instrumentingAgents->setInspectorDOMAgent(this);
@@ -267,14 +270,14 @@ void InspectorDOMAgent::clearFrontend()
m_frontend = 0;
m_instrumentingAgents->setInspectorDOMAgent(0);
- m_state->setBoolean(DOMAgentState::documentRequested, false);
+ disable(0);
reset();
}
void InspectorDOMAgent::restore()
{
// Reset document to avoid early return from setDocument.
- m_document = 0;
+ m_document = nullptr;
setDocument(m_pageAgent->mainFrame()->document());
}
@@ -282,7 +285,9 @@ Vector<Document*> InspectorDOMAgent::documents()
{
Vector<Document*> result;
for (Frame* frame = m_document->frame(); frame; frame = frame->tree().traverseNext()) {
- Document* document = frame->document();
+ if (!frame->isLocalFrame())
+ continue;
+ Document* document = toLocalFrame(frame)->document();
if (!document)
continue;
result.append(document);
@@ -293,8 +298,7 @@ Vector<Document*> InspectorDOMAgent::documents()
void InspectorDOMAgent::reset()
{
discardFrontendBindings();
- discardBackendBindings();
- m_document = 0;
+ m_document = nullptr;
}
void InspectorDOMAgent::setDOMListener(DOMListener* listener)
@@ -311,7 +315,7 @@ void InspectorDOMAgent::setDocument(Document* doc)
m_document = doc;
- if (!m_state->getBoolean(DOMAgentState::documentRequested))
+ if (!enabled())
return;
// Immediately communicate 0 document or document that has finished loading.
@@ -343,6 +347,7 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap)
return;
m_idToNode.remove(id);
+ m_idToNodesMap.remove(id);
if (node->isFrameOwnerElement()) {
Document* contentDocument = toHTMLFrameOwnerElement(node)->contentDocument();
@@ -361,6 +366,12 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap)
unbind(element->pseudoElement(BEFORE), nodesMap);
if (element->pseudoElement(AFTER))
unbind(element->pseudoElement(AFTER), nodesMap);
+
+ if (isHTMLLinkElement(*element)) {
+ HTMLLinkElement& linkElement = toHTMLLinkElement(*element);
+ if (linkElement.isImport() && linkElement.import())
+ unbind(linkElement.import(), nodesMap);
+ }
}
nodesMap->remove(node);
@@ -377,6 +388,8 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap)
child = innerNextSibling(child);
}
}
+ if (nodesMap == m_documentNodeToIdMap.get())
+ m_cachedChildCount.remove(id);
}
Node* InspectorDOMAgent::assertNode(ErrorString* errorString, int nodeId)
@@ -408,13 +421,27 @@ Element* InspectorDOMAgent::assertElement(ErrorString* errorString, int nodeId)
if (!node)
return 0;
- if (node->nodeType() != Node::ELEMENT_NODE) {
+ if (!node->isElementNode()) {
*errorString = "Node is not an Element";
return 0;
}
return toElement(node);
}
+static ShadowRoot* userAgentShadowRoot(Node* node)
+{
+ if (!node || !node->isInShadowTree())
+ return 0;
+
+ Node* candidate = node;
+ while (candidate && !candidate->isShadowRoot())
+ candidate = candidate->parentOrShadowHostNode();
+ ASSERT(candidate);
+ ShadowRoot* shadowRoot = toShadowRoot(candidate);
+
+ return shadowRoot->type() == ShadowRoot::UserAgentShadowRoot ? shadowRoot : 0;
+}
+
Node* InspectorDOMAgent::assertEditableNode(ErrorString* errorString, int nodeId)
{
Node* node = assertNode(errorString, nodeId);
@@ -422,8 +449,14 @@ Node* InspectorDOMAgent::assertEditableNode(ErrorString* errorString, int nodeId
return 0;
if (node->isInShadowTree()) {
- *errorString = "Cannot edit nodes from shadow trees";
- return 0;
+ if (node->isShadowRoot()) {
+ *errorString = "Cannot edit shadow roots";
+ return 0;
+ }
+ if (userAgentShadowRoot(node)) {
+ *errorString = "Cannot edit nodes from user-agent shadow trees";
+ return 0;
+ }
}
if (node->isPseudoElement()) {
@@ -440,8 +473,8 @@ Element* InspectorDOMAgent::assertEditableElement(ErrorString* errorString, int
if (!element)
return 0;
- if (element->isInShadowTree()) {
- *errorString = "Cannot edit elements from shadow trees";
+ if (element->isInShadowTree() && userAgentShadowRoot(element)) {
+ *errorString = "Cannot edit elements from user-agent shadow trees";
return 0;
}
@@ -453,9 +486,34 @@ Element* InspectorDOMAgent::assertEditableElement(ErrorString* errorString, int
return element;
}
+void InspectorDOMAgent::enable(ErrorString*)
+{
+ if (enabled())
+ return;
+ m_state->setBoolean(DOMAgentState::domAgentEnabled, true);
+ if (m_listener)
+ m_listener->domAgentWasEnabled();
+}
+
+bool InspectorDOMAgent::enabled() const
+{
+ return m_state->getBoolean(DOMAgentState::domAgentEnabled);
+}
+
+void InspectorDOMAgent::disable(ErrorString*)
+{
+ if (!enabled())
+ return;
+ m_state->setBoolean(DOMAgentState::domAgentEnabled, false);
+ reset();
+ if (m_listener)
+ m_listener->domAgentWasDisabled();
+}
+
void InspectorDOMAgent::getDocument(ErrorString* errorString, RefPtr<TypeBuilder::DOM::Node>& root)
{
- m_state->setBoolean(DOMAgentState::documentRequested, true);
+ // Backward compatibility. Mark agent as enabled when it requests document.
+ enable(errorString);
if (!m_document) {
*errorString = "Document is not available";
@@ -464,13 +522,13 @@ void InspectorDOMAgent::getDocument(ErrorString* errorString, RefPtr<TypeBuilder
discardFrontendBindings();
- root = buildObjectForNode(m_document.get(), 2, &m_documentNodeToIdMap);
+ root = buildObjectForNode(m_document.get(), 2, m_documentNodeToIdMap.get());
}
void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth)
{
Node* node = nodeForId(nodeId);
- if (!node || (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE && node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE))
+ if (!node || (!node->isElementNode() && !node->isDocumentNode() && !node->isDocumentFragment()))
return;
NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId);
@@ -499,39 +557,22 @@ void InspectorDOMAgent::discardFrontendBindings()
if (m_history)
m_history->reset();
m_searchResults.clear();
- m_documentNodeToIdMap.clear();
+ m_documentNodeToIdMap->clear();
m_idToNode.clear();
+ m_idToNodesMap.clear();
releaseDanglingNodes();
m_childrenRequested.clear();
+ m_cachedChildCount.clear();
if (m_revalidateStyleAttrTask)
m_revalidateStyleAttrTask->reset();
}
-void InspectorDOMAgent::discardBackendBindings()
-{
- m_backendIdToNode.clear();
- m_nodeGroupToBackendIdMap.clear();
-}
-
-int InspectorDOMAgent::pushNodeToFrontend(ErrorString* errorString, int documentNodeId, Node* nodeToPush)
-{
- Document* document = assertDocument(errorString, documentNodeId);
- if (!document)
- return 0;
- if (nodeToPush->document() != document) {
- *errorString = "Node is not part of the document with given id";
- return 0;
- }
-
- return pushNodePathToFrontend(nodeToPush);
-}
-
Node* InspectorDOMAgent::nodeForId(int id)
{
if (!id)
return 0;
- HashMap<int, Node*>::iterator it = m_idToNode.find(id);
+ WillBeHeapHashMap<int, RawPtrWillBeMember<Node> >::iterator it = m_idToNode.find(id);
if (it != m_idToNode.end())
return it->value;
return 0;
@@ -559,11 +600,11 @@ void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, cons
{
*elementId = 0;
Node* node = assertNode(errorString, nodeId);
- if (!node)
+ if (!node || !node->isContainerNode())
return;
TrackExceptionState exceptionState;
- RefPtr<Element> element = node->querySelector(selectors, exceptionState);
+ RefPtrWillBeRawPtr<Element> element = toContainerNode(node)->querySelector(AtomicString(selectors), exceptionState);
if (exceptionState.hadException()) {
*errorString = "DOM Error while querying";
return;
@@ -576,11 +617,11 @@ void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, cons
void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, const String& selectors, RefPtr<TypeBuilder::Array<int> >& result)
{
Node* node = assertNode(errorString, nodeId);
- if (!node)
+ if (!node || !node->isContainerNode())
return;
TrackExceptionState exceptionState;
- RefPtr<NodeList> nodes = node->querySelectorAll(selectors, exceptionState);
+ RefPtrWillBeRawPtr<StaticNodeList> nodes = toContainerNode(node)->querySelectorAll(AtomicString(selectors), exceptionState);
if (exceptionState.hadException()) {
*errorString = "DOM Error while querying";
return;
@@ -598,11 +639,12 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
if (!m_document)
return 0;
- if (!m_documentNodeToIdMap.contains(m_document))
+ // FIXME: Oilpan: .get will be unnecessary if m_document is a Member<>.
+ if (!m_documentNodeToIdMap->contains(m_document.get()))
return 0;
// Return id in case the node is known.
- int result = m_documentNodeToIdMap.get(nodeToPush);
+ int result = m_documentNodeToIdMap->get(nodeToPush);
if (result)
return result;
@@ -614,7 +656,7 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
Node* parent = innerParentNode(node);
if (!parent) {
// Node being pushed is detached -> push subtree root.
- OwnPtr<NodeToIdMap> newMap = adoptPtr(new NodeToIdMap);
+ OwnPtrWillBeRawPtr<NodeToIdMap> newMap = adoptPtrWillBeNoop(new NodeToIdMap);
danglingMap = newMap.get();
m_danglingNodeToIdMaps.append(newMap.release());
RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
@@ -623,14 +665,13 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
break;
} else {
path.append(parent);
- if (m_documentNodeToIdMap.get(parent))
+ if (m_documentNodeToIdMap->get(parent))
break;
- else
- node = parent;
+ node = parent;
}
}
- NodeToIdMap* map = danglingMap ? danglingMap : &m_documentNodeToIdMap;
+ NodeToIdMap* map = danglingMap ? danglingMap : m_documentNodeToIdMap.get();
for (int i = path.size() - 1; i >= 0; --i) {
int nodeId = map->get(path.at(i));
ASSERT(nodeId);
@@ -641,38 +682,7 @@ int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
int InspectorDOMAgent::boundNodeId(Node* node)
{
- return m_documentNodeToIdMap.get(node);
-}
-
-BackendNodeId InspectorDOMAgent::backendNodeIdForNode(Node* node, const String& nodeGroup)
-{
- if (!node)
- return 0;
-
- if (!m_nodeGroupToBackendIdMap.contains(nodeGroup))
- m_nodeGroupToBackendIdMap.set(nodeGroup, NodeToBackendIdMap());
-
- NodeToBackendIdMap& map = m_nodeGroupToBackendIdMap.find(nodeGroup)->value;
- BackendNodeId id = map.get(node);
- if (!id) {
- id = --m_lastBackendNodeId;
- map.set(node, id);
- m_backendIdToNode.set(id, std::make_pair(node, nodeGroup));
- }
-
- return id;
-}
-
-void InspectorDOMAgent::releaseBackendNodeIds(ErrorString* errorString, const String& nodeGroup)
-{
- if (m_nodeGroupToBackendIdMap.contains(nodeGroup)) {
- NodeToBackendIdMap& map = m_nodeGroupToBackendIdMap.find(nodeGroup)->value;
- for (NodeToBackendIdMap::iterator it = map.begin(); it != map.end(); ++it)
- m_backendIdToNode.remove(it->value);
- m_nodeGroupToBackendIdMap.remove(nodeGroup);
- return;
- }
- *errorString = "Group name not found";
+ return m_documentNodeToIdMap->get(node);
}
void InspectorDOMAgent::setAttributeValue(ErrorString* errorString, int elementId, const String& name, const String& value)
@@ -691,14 +701,14 @@ void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elemen
return;
String markup = "<span " + text + "></span>";
- RefPtr<DocumentFragment> fragment = element->document().createDocumentFragment();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = element->document().createDocumentFragment();
bool shouldIgnoreCase = element->document().isHTMLDocument() && element->isHTMLElement();
// Not all elements can represent the context (i.e. IFRAME), hence using document.body.
if (shouldIgnoreCase && element->document().body())
- fragment->parseHTML(markup, element->document().body(), DisallowScriptingContent);
+ fragment->parseHTML(markup, element->document().body(), AllowScriptingContent);
else
- fragment->parseXML(markup, 0, DisallowScriptingContent);
+ fragment->parseXML(markup, 0, AllowScriptingContent);
Element* parsedElement = fragment->firstChild() && fragment->firstChild()->isElementNode() ? toElement(fragment->firstChild()) : 0;
if (!parsedElement) {
@@ -714,15 +724,15 @@ void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elemen
}
bool foundOriginalAttribute = false;
- unsigned numAttrs = parsedElement->attributeCount();
- for (unsigned i = 0; i < numAttrs; ++i) {
+ AttributeCollection attributes = parsedElement->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
// Add attribute pair
- const Attribute* attribute = parsedElement->attributeItem(i);
- String attributeName = attribute->name().toString();
+ String attributeName = it->name().toString();
if (shouldIgnoreCase)
attributeName = attributeName.lower();
foundOriginalAttribute |= name && attributeName == caseAdjustedName;
- if (!m_domEditor->setAttribute(element, attributeName, attribute->value(), errorString))
+ if (!m_domEditor->setAttribute(element, attributeName, it->value(), errorString))
return;
}
@@ -763,7 +773,7 @@ void InspectorDOMAgent::setNodeName(ErrorString* errorString, int nodeId, const
return;
TrackExceptionState exceptionState;
- RefPtr<Element> newElem = oldNode->document().createElement(tagName, exceptionState);
+ RefPtrWillBeRawPtr<Element> newElem = oldNode->document().createElement(AtomicString(tagName), exceptionState);
if (exceptionState.hadException())
return;
@@ -812,7 +822,7 @@ void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const
return;
Document* document = node->isDocumentNode() ? toDocument(node) : node->ownerDocument();
- if (!document || (!document->isHTMLDocument() && !document->isXHTMLDocument() && !document->isSVGDocument())) {
+ if (!document || (!document->isHTMLDocument() && !document->isXMLDocument())) {
*errorString = "Not an HTML/XML document";
return;
}
@@ -863,8 +873,11 @@ void InspectorDOMAgent::getEventListenersForNode(ErrorString* errorString, int n
const EventListenerVector& vector = info.eventListenerVector;
for (size_t j = 0; j < vector.size(); ++j) {
const RegisteredEventListener& listener = vector[j];
- if (listener.useCapture)
- listenersArray->addItem(buildObjectForEventListener(listener, info.eventType, info.node, objectGroup));
+ if (listener.useCapture) {
+ RefPtr<TypeBuilder::DOM::EventListener> listenerObject = buildObjectForEventListener(listener, info.eventType, info.eventTarget->toNode(), objectGroup);
+ if (listenerObject)
+ listenersArray->addItem(listenerObject);
+ }
}
}
@@ -874,31 +887,30 @@ void InspectorDOMAgent::getEventListenersForNode(ErrorString* errorString, int n
const EventListenerVector& vector = info.eventListenerVector;
for (size_t j = 0; j < vector.size(); ++j) {
const RegisteredEventListener& listener = vector[j];
- if (!listener.useCapture)
- listenersArray->addItem(buildObjectForEventListener(listener, info.eventType, info.node, objectGroup));
+ if (!listener.useCapture) {
+ RefPtr<TypeBuilder::DOM::EventListener> listenerObject = buildObjectForEventListener(listener, info.eventType, info.eventTarget->toNode(), objectGroup);
+ if (listenerObject)
+ listenersArray->addItem(listenerObject);
+ }
}
}
}
-void InspectorDOMAgent::getEventListeners(Node* node, Vector<EventListenerInfo>& eventInformation, bool includeAncestors)
+void InspectorDOMAgent::getEventListeners(EventTarget* target, Vector<EventListenerInfo>& eventInformation, bool includeAncestors)
{
// The Node's Ancestors including self.
- Vector<Node*> ancestors;
- // Push this node as the firs element.
- ancestors.append(node);
+ Vector<EventTarget*> ancestors;
+ ancestors.append(target);
if (includeAncestors) {
- for (ContainerNode* ancestor = node->parentOrShadowHostNode(); ancestor; ancestor = ancestor->parentOrShadowHostNode())
+ Node* node = target->toNode();
+ for (ContainerNode* ancestor = node ? node->parentOrShadowHostNode() : 0; ancestor; ancestor = ancestor->parentOrShadowHostNode())
ancestors.append(ancestor);
}
// Nodes and their Listeners for the concerned event types (order is top to bottom)
for (size_t i = ancestors.size(); i; --i) {
- Node* ancestor = ancestors[i - 1];
- EventTargetData* d = ancestor->eventTargetData();
- if (!d)
- continue;
- // Get the list of event types this Node is concerned with
- Vector<AtomicString> eventTypes = d->eventListenerMap.eventTypes();
+ EventTarget* ancestor = ancestors[i - 1];
+ Vector<AtomicString> eventTypes = ancestor->eventTypes();
for (size_t j = 0; j < eventTypes.size(); ++j) {
AtomicString& type = eventTypes[j];
const EventListenerVector& listeners = ancestor->getEventListeners(type);
@@ -972,17 +984,17 @@ void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrim
if (!element->hasAttributes())
break;
- unsigned numAttrs = element->attributeCount();
- for (unsigned i = 0; i < numAttrs; ++i) {
+ AttributeCollection attributes = element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
// Add attribute pair
- const Attribute* attribute = element->attributeItem(i);
- if (attribute->localName().find(whitespaceTrimmedQuery, 0, false) != kNotFound) {
+ if (it->localName().find(whitespaceTrimmedQuery, 0, false) != kNotFound) {
resultCollector.add(node);
break;
}
- size_t foundPosition = attribute->value().find(attributeQuery, 0, false);
+ size_t foundPosition = it->value().find(attributeQuery, 0, false);
if (foundPosition != kNotFound) {
- if (!exactAttributeMatch || (!foundPosition && attribute->value().length() == attributeQuery.length())) {
+ if (!exactAttributeMatch || (!foundPosition && it->value().length() == attributeQuery.length())) {
resultCollector.add(node);
break;
}
@@ -998,8 +1010,9 @@ void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrim
// XPath evaluation
for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
Document* document = *it;
+ ASSERT(document);
TrackExceptionState exceptionState;
- RefPtr<XPathResult> result = DocumentXPathEvaluator::evaluate(document, whitespaceTrimmedQuery, document, 0, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, 0, exceptionState);
+ RefPtrWillBeRawPtr<XPathResult> result = DocumentXPathEvaluator::evaluate(*document, whitespaceTrimmedQuery, document, nullptr, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, 0, exceptionState);
if (exceptionState.hadException() || !result)
continue;
@@ -1019,7 +1032,7 @@ void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrim
for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
Document* document = *it;
TrackExceptionState exceptionState;
- RefPtr<NodeList> nodeList = document->querySelectorAll(whitespaceTrimmedQuery, exceptionState);
+ RefPtrWillBeRawPtr<StaticNodeList> nodeList = document->querySelectorAll(AtomicString(whitespaceTrimmedQuery), exceptionState);
if (exceptionState.hadException() || !nodeList)
continue;
@@ -1030,12 +1043,12 @@ void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrim
}
*searchId = IdentifiersFactory::createIdentifier();
- SearchResults::iterator resultsIt = m_searchResults.add(*searchId, Vector<RefPtr<Node> >()).iterator;
+ WillBeHeapVector<RefPtrWillBeMember<Node> >* resultsIt = &m_searchResults.add(*searchId, WillBeHeapVector<RefPtrWillBeMember<Node> >()).storedValue->value;
for (ListHashSet<Node*>::iterator it = resultCollector.begin(); it != resultCollector.end(); ++it)
- resultsIt->value.append(*it);
+ resultsIt->append(*it);
- *resultCount = resultsIt->value.size();
+ *resultCount = resultsIt->size();
}
void InspectorDOMAgent::getSearchResults(ErrorString* errorString, const String& searchId, int fromIndex, int toIndex, RefPtr<TypeBuilder::Array<int> >& nodeIds)
@@ -1074,26 +1087,26 @@ bool InspectorDOMAgent::handleMousePress()
return false;
}
-bool InspectorDOMAgent::handleGestureEvent(Frame* frame, const PlatformGestureEvent& event)
+bool InspectorDOMAgent::handleGestureEvent(LocalFrame* frame, const PlatformGestureEvent& event)
{
if (m_searchingForNode == NotSearching || event.type() != PlatformEvent::GestureTap)
return false;
Node* node = hoveredNodeForEvent(frame, event, false);
if (node && m_inspectModeHighlightConfig) {
- m_overlay->highlightNode(node, 0 /* eventTarget */, *m_inspectModeHighlightConfig);
+ m_overlay->highlightNode(node, 0 /* eventTarget */, *m_inspectModeHighlightConfig, false);
inspect(node);
return true;
}
return false;
}
-bool InspectorDOMAgent::handleTouchEvent(Frame* frame, const PlatformTouchEvent& event)
+bool InspectorDOMAgent::handleTouchEvent(LocalFrame* frame, const PlatformTouchEvent& event)
{
if (m_searchingForNode == NotSearching)
return false;
Node* node = hoveredNodeForEvent(frame, event, false);
if (node && m_inspectModeHighlightConfig) {
- m_overlay->highlightNode(node, 0 /* eventTarget */, *m_inspectModeHighlightConfig);
+ m_overlay->highlightNode(node, 0 /* eventTarget */, *m_inspectModeHighlightConfig, false);
inspect(node);
return true;
}
@@ -1106,15 +1119,18 @@ void InspectorDOMAgent::inspect(Node* inspectedNode)
return;
Node* node = inspectedNode;
- if (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE)
- node = node->parentNode();
+ while (node && !node->isElementNode() && !node->isDocumentNode() && !node->isDocumentFragment())
+ node = node->parentOrShadowHostNode();
+
+ if (!node)
+ return;
int nodeId = pushNodePathToFrontend(node);
if (nodeId)
m_frontend->inspectNodeRequested(nodeId);
}
-void InspectorDOMAgent::handleMouseMove(Frame* frame, const PlatformMouseEvent& event)
+void InspectorDOMAgent::handleMouseMove(LocalFrame* frame, const PlatformMouseEvent& event)
{
if (m_searchingForNode == NotSearching)
return;
@@ -1123,15 +1139,26 @@ void InspectorDOMAgent::handleMouseMove(Frame* frame, const PlatformMouseEvent&
return;
Node* node = hoveredNodeForEvent(frame, event, event.shiftKey());
- while (m_searchingForNode != SearchingForShadow && node && node->isInShadowTree())
+ // Do not highlight within UA shadow root unless requested.
+ if (m_searchingForNode != SearchingForUAShadow) {
+ ShadowRoot* uaShadowRoot = userAgentShadowRoot(node);
+ if (uaShadowRoot)
+ node = uaShadowRoot->host();
+ }
+
+ // Shadow roots don't have boxes - use host element instead.
+ if (node && node->isShadowRoot())
node = node->parentOrShadowHostNode();
+ if (!node)
+ return;
+
Node* eventTarget = event.shiftKey() ? hoveredNodeForEvent(frame, event, false) : 0;
if (eventTarget == node)
eventTarget = 0;
if (node && m_inspectModeHighlightConfig)
- m_overlay->highlightNode(node, eventTarget, *m_inspectModeHighlightConfig);
+ m_overlay->highlightNode(node, eventTarget, *m_inspectModeHighlightConfig, event.ctrlKey() || event.metaKey());
}
void InspectorDOMAgent::setSearchingForNode(ErrorString* errorString, SearchMode searchMode, JSONObject* highlightInspectorObject)
@@ -1172,11 +1199,11 @@ PassOwnPtr<HighlightConfig> InspectorDOMAgent::highlightConfigFromInspectorObjec
return highlightConfig.release();
}
-void InspectorDOMAgent::setInspectModeEnabled(ErrorString* errorString, bool enabled, const bool* inspectShadowDOM, const RefPtr<JSONObject>* highlightConfig)
+void InspectorDOMAgent::setInspectModeEnabled(ErrorString* errorString, bool enabled, const bool* inspectUAShadowDOM, const RefPtr<JSONObject>* highlightConfig)
{
if (enabled && !pushDocumentUponHandlelessOperation(errorString))
return;
- SearchMode searchMode = enabled ? (inspectShadowDOM && *inspectShadowDOM ? SearchingForShadow : SearchingForNormal) : NotSearching;
+ SearchMode searchMode = enabled ? (inspectUAShadowDOM && *inspectUAShadowDOM ? SearchingForUAShadow : SearchingForNormal) : NotSearching;
setSearchingForNode(errorString, searchMode, highlightConfig ? highlightConfig->get() : 0);
}
@@ -1224,7 +1251,7 @@ void InspectorDOMAgent::highlightNode(ErrorString* errorString, const RefPtr<JSO
if (!highlightConfig)
return;
- m_overlay->highlightNode(node, 0 /* eventTarget */, *highlightConfig);
+ m_overlay->highlightNode(node, 0 /* eventTarget */, *highlightConfig, false);
}
void InspectorDOMAgent::highlightFrame(
@@ -1233,13 +1260,14 @@ void InspectorDOMAgent::highlightFrame(
const RefPtr<JSONObject>* color,
const RefPtr<JSONObject>* outlineColor)
{
- Frame* frame = m_pageAgent->frameForId(frameId);
- if (frame && frame->ownerElement()) {
+ LocalFrame* frame = m_pageAgent->frameForId(frameId);
+ // FIXME: Inspector doesn't currently work cross process.
+ if (frame && frame->deprecatedLocalOwner()) {
OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
highlightConfig->showInfo = true; // Always show tooltips for frames.
highlightConfig->content = parseColor(color);
highlightConfig->contentOutline = parseColor(outlineColor);
- m_overlay->highlightNode(frame->ownerElement(), 0 /* eventTarget */, *highlightConfig);
+ m_overlay->highlightNode(frame->deprecatedLocalOwner(), 0 /* eventTarget */, *highlightConfig, false);
}
}
@@ -1299,6 +1327,8 @@ void InspectorDOMAgent::focus(ErrorString* errorString, int nodeId)
Element* element = assertElement(errorString, nodeId);
if (!element)
return;
+
+ element->document().updateLayoutIgnorePendingStylesheets();
if (!element->isFocusable()) {
*errorString = "Element is not focusable";
return;
@@ -1311,12 +1341,12 @@ void InspectorDOMAgent::setFileInputFiles(ErrorString* errorString, int nodeId,
Node* node = assertNode(errorString, nodeId);
if (!node)
return;
- if (!node->hasTagName(inputTag) || !toHTMLInputElement(node)->isFileUpload()) {
+ if (!isHTMLInputElement(*node) || !toHTMLInputElement(*node).isFileUpload()) {
*errorString = "Node is not a file input element";
return;
}
- RefPtr<FileList> fileList = FileList::create();
+ RefPtrWillBeRawPtr<FileList> fileList = FileList::create();
for (JSONArray::const_iterator iter = files->begin(); iter != files->end(); ++iter) {
String path;
if (!(*iter)->asString(&path)) {
@@ -1356,11 +1386,12 @@ void InspectorDOMAgent::getBoxModel(ErrorString* errorString, int nodeId, RefPtr
}
RenderObject* renderer = node->renderer();
- Frame* frame = node->document().frame();
+ LocalFrame* frame = node->document().frame();
FrameView* view = frame->view();
IntRect boundingBox = pixelSnappedIntRect(view->contentsToRootView(renderer->absoluteBoundingBoxRect()));
RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0;
+ RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeOutsideInfo = m_overlay->buildObjectForShapeOutside(node);
model = TypeBuilder::DOM::BoxModel::create()
.setContent(buildArrayForQuad(quads.at(3)))
@@ -1369,6 +1400,8 @@ void InspectorDOMAgent::getBoxModel(ErrorString* errorString, int nodeId, RefPtr
.setMargin(buildArrayForQuad(quads.at(0)))
.setWidth(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetWidth(), modelObject) : boundingBox.width())
.setHeight(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetHeight(), modelObject) : boundingBox.height());
+ if (shapeOutsideInfo)
+ model->setShapeOutside(shapeOutsideInfo);
}
void InspectorDOMAgent::getNodeForLocation(ErrorString* errorString, int x, int y, int* nodeId)
@@ -1456,10 +1489,8 @@ PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* n
case Node::COMMENT_NODE:
case Node::CDATA_SECTION_NODE:
nodeValue = node->nodeValue();
- if (nodeValue.length() > maxTextSize) {
- nodeValue = nodeValue.left(maxTextSize);
- nodeValue.append(ellipsisUChar);
- }
+ if (nodeValue.length() > maxTextSize)
+ nodeValue = nodeValue.left(maxTextSize) + ellipsisUChar;
break;
case Node::ATTRIBUTE_NODE:
localName = node->localName();
@@ -1484,9 +1515,11 @@ PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* n
if (node->isElementNode()) {
Element* element = toElement(node);
value->setAttributes(buildArrayForElementAttributes(element));
+
if (node->isFrameOwnerElement()) {
HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(node);
- if (Frame* frame = frameOwner->contentFrame())
+ LocalFrame* frame = (frameOwner->contentFrame() && frameOwner->contentFrame()->isLocalFrame()) ? toLocalFrame(frameOwner->contentFrame()) : 0;
+ if (frame)
value->setFrameId(m_pageAgent->frameId(frame));
if (Document* doc = frameOwner->contentDocument())
value->setContentDocument(buildObjectForNode(doc, 0, nodesMap));
@@ -1501,8 +1534,15 @@ PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* n
forcePushChildren = true;
}
- if (element->hasTagName(templateTag)) {
- value->setTemplateContent(buildObjectForNode(toHTMLTemplateElement(element)->content(), 0, nodesMap));
+ if (isHTMLLinkElement(*element)) {
+ HTMLLinkElement& linkElement = toHTMLLinkElement(*element);
+ if (linkElement.isImport() && linkElement.import() && innerParentNode(linkElement.import()) == linkElement)
+ value->setImportedDocument(buildObjectForNode(linkElement.import(), 0, nodesMap));
+ forcePushChildren = true;
+ }
+
+ if (isHTMLTemplateElement(*element)) {
+ value->setTemplateContent(buildObjectForNode(toHTMLTemplateElement(*element).content(), 0, nodesMap));
forcePushChildren = true;
}
@@ -1527,11 +1567,10 @@ PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* n
value->setDocumentURL(documentURLString(document));
value->setBaseURL(documentBaseURLString(document));
value->setXmlVersion(document->xmlVersion());
- } else if (node->nodeType() == Node::DOCUMENT_TYPE_NODE) {
+ } else if (node->isDocumentTypeNode()) {
DocumentType* docType = toDocumentType(node);
value->setPublicId(docType->publicId());
value->setSystemId(docType->systemId());
- value->setInternalSubset(docType->internalSubset());
} else if (node->isAttributeNode()) {
Attr* attribute = toAttr(node);
value->setName(attribute->name());
@@ -1543,6 +1582,8 @@ PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* n
if (node->isContainerNode()) {
int nodeCount = innerChildNodeCount(node);
value->setChildNodeCount(nodeCount);
+ if (nodesMap == m_documentNodeToIdMap)
+ m_cachedChildCount.set(id, nodeCount);
if (forcePushChildren && !depth)
depth = 1;
RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = buildArrayForContainerChildren(node, depth, nodesMap);
@@ -1559,12 +1600,12 @@ PassRefPtr<TypeBuilder::Array<String> > InspectorDOMAgent::buildArrayForElementA
// Go through all attributes and serialize them.
if (!element->hasAttributes())
return attributesValue.release();
- unsigned numAttrs = element->attributeCount();
- for (unsigned i = 0; i < numAttrs; ++i) {
+ AttributeCollection attributes = element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
// Add attribute pair
- const Attribute* attribute = element->attributeItem(i);
- attributesValue->addItem(attribute->name().toString());
- attributesValue->addItem(attribute->value());
+ attributesValue->addItem(it->name().toString());
+ attributesValue->addItem(it->value());
}
return attributesValue.release();
}
@@ -1596,22 +1637,32 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > InspectorDOMAgent::build
PassRefPtr<TypeBuilder::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node, const String* objectGroupId)
{
RefPtr<EventListener> eventListener = registeredEventListener.listener;
+ String sourceName;
+ String scriptId;
+ int lineNumber;
+ if (!eventListenerHandlerLocation(&node->document(), eventListener.get(), sourceName, scriptId, lineNumber))
+ return nullptr;
+
Document& document = node->document();
+ RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
+ .setScriptId(scriptId)
+ .setLineNumber(lineNumber);
RefPtr<TypeBuilder::DOM::EventListener> value = TypeBuilder::DOM::EventListener::create()
.setType(eventType)
.setUseCapture(registeredEventListener.useCapture)
.setIsAttribute(eventListener->isAttribute())
.setNodeId(pushNodePathToFrontend(node))
- .setHandlerBody(eventListenerHandlerBody(&document, eventListener.get()));
+ .setHandlerBody(eventListenerHandlerBody(&document, eventListener.get()))
+ .setLocation(location);
if (objectGroupId) {
ScriptValue functionValue = eventListenerHandler(&document, eventListener.get());
- if (!functionValue.hasNoValue()) {
- Frame* frame = document.frame();
+ if (!functionValue.isEmpty()) {
+ LocalFrame* frame = document.frame();
if (frame) {
ScriptState* scriptState = eventListenerHandlerScriptState(frame, eventListener.get());
if (scriptState) {
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
- if (!injectedScript.hasNoValue()) {
+ if (!injectedScript.isEmpty()) {
RefPtr<TypeBuilder::Runtime::RemoteObject> valueJson = injectedScript.wrapObject(functionValue, *objectGroupId);
value->setHandler(valueJson);
}
@@ -1619,24 +1670,15 @@ PassRefPtr<TypeBuilder::DOM::EventListener> InspectorDOMAgent::buildObjectForEve
}
}
}
- String sourceName;
- String scriptId;
- int lineNumber;
- if (eventListenerHandlerLocation(&node->document(), eventListener.get(), sourceName, scriptId, lineNumber)) {
- RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
- .setScriptId(scriptId)
- .setLineNumber(lineNumber);
- value->setLocation(location);
- if (!sourceName.isEmpty())
- value->setSourceName(sourceName);
- }
+ if (!sourceName.isEmpty())
+ value->setSourceName(sourceName);
return value.release();
}
PassRefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > InspectorDOMAgent::buildArrayForPseudoElements(Element* element, NodeToIdMap* nodesMap)
{
if (!element->pseudoElement(BEFORE) && !element->pseudoElement(AFTER))
- return 0;
+ return nullptr;
RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > pseudoElements = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
if (element->pseudoElement(BEFORE))
@@ -1685,6 +1727,8 @@ Node* InspectorDOMAgent::innerParentNode(Node* node)
{
if (node->isDocumentNode()) {
Document* document = toDocument(node);
+ if (HTMLImportLoader* loader = document->importLoader())
+ return loader->firstImport()->link();
return document->ownerElement();
}
return node->parentOrShadowHostNode();
@@ -1696,44 +1740,46 @@ bool InspectorDOMAgent::isWhitespace(Node* node)
return node && node->nodeType() == Node::TEXT_NODE && node->nodeValue().stripWhiteSpace().length() == 0;
}
-void InspectorDOMAgent::domContentLoadedEventFired(Frame* frame)
+void InspectorDOMAgent::domContentLoadedEventFired(LocalFrame* frame)
{
if (!frame->isMainFrame())
return;
// Re-push document once it is loaded.
discardFrontendBindings();
- if (m_state->getBoolean(DOMAgentState::documentRequested))
+ if (enabled())
m_frontend->documentUpdated();
}
-void InspectorDOMAgent::invalidateFrameOwnerElement(Frame* frame)
+void InspectorDOMAgent::invalidateFrameOwnerElement(LocalFrame* frame)
{
Element* frameOwner = frame->document()->ownerElement();
if (!frameOwner)
return;
- int frameOwnerId = m_documentNodeToIdMap.get(frameOwner);
+ int frameOwnerId = m_documentNodeToIdMap->get(frameOwner);
if (!frameOwnerId)
return;
// Re-add frame owner element together with its new children.
- int parentId = m_documentNodeToIdMap.get(innerParentNode(frameOwner));
+ int parentId = m_documentNodeToIdMap->get(innerParentNode(frameOwner));
m_frontend->childNodeRemoved(parentId, frameOwnerId);
- unbind(frameOwner, &m_documentNodeToIdMap);
+ unbind(frameOwner, m_documentNodeToIdMap.get());
- RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(frameOwner, 0, &m_documentNodeToIdMap);
+ RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(frameOwner, 0, m_documentNodeToIdMap.get());
Node* previousSibling = innerPreviousSibling(frameOwner);
- int prevId = previousSibling ? m_documentNodeToIdMap.get(previousSibling) : 0;
+ int prevId = previousSibling ? m_documentNodeToIdMap->get(previousSibling) : 0;
m_frontend->childNodeInserted(parentId, prevId, value.release());
}
-void InspectorDOMAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorDOMAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
{
// FIXME: If "frame" is always guarenteed to be in the same Page as loader->frame()
// then all we need to check here is loader->frame()->isMainFrame()
// and we don't need "frame" at all.
- Frame* mainFrame = frame->page()->mainFrame();
+ if (!frame->page()->mainFrame()->isLocalFrame())
+ return;
+ LocalFrame* mainFrame = frame->page()->deprecatedLocalMainFrame();
if (loader->frame() != mainFrame) {
invalidateFrameOwnerElement(loader->frame());
return;
@@ -1748,25 +1794,26 @@ void InspectorDOMAgent::didInsertDOMNode(Node* node)
return;
// We could be attaching existing subtree. Forget the bindings.
- unbind(node, &m_documentNodeToIdMap);
+ unbind(node, m_documentNodeToIdMap.get());
ContainerNode* parent = node->parentNode();
if (!parent)
return;
-
- int parentId = m_documentNodeToIdMap.get(parent);
+ int parentId = m_documentNodeToIdMap->get(parent);
// Return if parent is not mapped yet.
if (!parentId)
return;
if (!m_childrenRequested.contains(parentId)) {
- // No children are mapped yet -> only notify on changes of hasChildren.
- m_frontend->childNodeCountUpdated(parentId, innerChildNodeCount(parent));
+ // No children are mapped yet -> only notify on changes of child count.
+ int count = m_cachedChildCount.get(parentId) + 1;
+ m_cachedChildCount.set(parentId, count);
+ m_frontend->childNodeCountUpdated(parentId, count);
} else {
// Children have been requested -> return value of a new child.
Node* prevSibling = innerPreviousSibling(node);
- int prevId = prevSibling ? m_documentNodeToIdMap.get(prevSibling) : 0;
- RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(node, 0, &m_documentNodeToIdMap);
+ int prevId = prevSibling ? m_documentNodeToIdMap->get(prevSibling) : 0;
+ RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(node, 0, m_documentNodeToIdMap.get());
m_frontend->childNodeInserted(parentId, prevId, value.release());
}
}
@@ -1779,18 +1826,20 @@ void InspectorDOMAgent::willRemoveDOMNode(Node* node)
ContainerNode* parent = node->parentNode();
// If parent is not mapped yet -> ignore the event.
- if (!m_documentNodeToIdMap.contains(parent))
+ if (!m_documentNodeToIdMap->contains(parent))
return;
- int parentId = m_documentNodeToIdMap.get(parent);
+ int parentId = m_documentNodeToIdMap->get(parent);
if (!m_childrenRequested.contains(parentId)) {
- // No children are mapped yet -> only notify on changes of hasChildren.
- if (innerChildNodeCount(parent) == 1)
- m_frontend->childNodeCountUpdated(parentId, 0);
- } else
- m_frontend->childNodeRemoved(parentId, m_documentNodeToIdMap.get(node));
- unbind(node, &m_documentNodeToIdMap);
+ // No children are mapped yet -> only notify on changes of child count.
+ int count = m_cachedChildCount.get(parentId) - 1;
+ m_cachedChildCount.set(parentId, count);
+ m_frontend->childNodeCountUpdated(parentId, count);
+ } else {
+ m_frontend->childNodeRemoved(parentId, m_documentNodeToIdMap->get(node));
+ }
+ unbind(node, m_documentNodeToIdMap.get());
}
void InspectorDOMAgent::willModifyDOMAttr(Element*, const AtomicString& oldValue, const AtomicString& newValue)
@@ -1829,7 +1878,7 @@ void InspectorDOMAgent::didRemoveDOMAttr(Element* element, const AtomicString& n
m_frontend->attributeRemoved(id, name);
}
-void InspectorDOMAgent::styleAttributeInvalidated(const Vector<Element*>& elements)
+void InspectorDOMAgent::styleAttributeInvalidated(const WillBeHeapVector<RawPtrWillBeMember<Element> >& elements)
{
RefPtr<TypeBuilder::Array<int> > nodeIds = TypeBuilder::Array<int>::create();
for (unsigned i = 0, size = elements.size(); i < size; ++i) {
@@ -1848,7 +1897,7 @@ void InspectorDOMAgent::styleAttributeInvalidated(const Vector<Element*>& elemen
void InspectorDOMAgent::characterDataModified(CharacterData* characterData)
{
- int id = m_documentNodeToIdMap.get(characterData);
+ int id = m_documentNodeToIdMap->get(characterData);
if (!id) {
// Push text node if it is being created.
didInsertDOMNode(characterData);
@@ -1859,7 +1908,7 @@ void InspectorDOMAgent::characterDataModified(CharacterData* characterData)
void InspectorDOMAgent::didInvalidateStyleAttr(Node* node)
{
- int id = m_documentNodeToIdMap.get(node);
+ int id = m_documentNodeToIdMap->get(node);
// If node is not mapped yet -> ignore the event.
if (!id)
return;
@@ -1874,12 +1923,12 @@ void InspectorDOMAgent::didPushShadowRoot(Element* host, ShadowRoot* root)
if (!host->ownerDocument())
return;
- int hostId = m_documentNodeToIdMap.get(host);
+ int hostId = m_documentNodeToIdMap->get(host);
if (!hostId)
return;
pushChildNodesToFrontend(hostId, 1);
- m_frontend->shadowRootPushed(hostId, buildObjectForNode(root, 0, &m_documentNodeToIdMap));
+ m_frontend->shadowRootPushed(hostId, buildObjectForNode(root, 0, m_documentNodeToIdMap.get()));
}
void InspectorDOMAgent::willPopShadowRoot(Element* host, ShadowRoot* root)
@@ -1887,13 +1936,13 @@ void InspectorDOMAgent::willPopShadowRoot(Element* host, ShadowRoot* root)
if (!host->ownerDocument())
return;
- int hostId = m_documentNodeToIdMap.get(host);
- int rootId = m_documentNodeToIdMap.get(root);
+ int hostId = m_documentNodeToIdMap->get(host);
+ int rootId = m_documentNodeToIdMap->get(root);
if (hostId && rootId)
m_frontend->shadowRootPopped(hostId, rootId);
}
-void InspectorDOMAgent::frameDocumentUpdated(Frame* frame)
+void InspectorDOMAgent::frameDocumentUpdated(LocalFrame* frame)
{
Document* document = frame->document();
if (!document)
@@ -1914,33 +1963,46 @@ void InspectorDOMAgent::pseudoElementCreated(PseudoElement* pseudoElement)
Element* parent = pseudoElement->parentOrShadowHostElement();
if (!parent)
return;
- int parentId = m_documentNodeToIdMap.get(parent);
+ int parentId = m_documentNodeToIdMap->get(parent);
if (!parentId)
return;
pushChildNodesToFrontend(parentId, 1);
- m_frontend->pseudoElementAdded(parentId, buildObjectForNode(pseudoElement, 0, &m_documentNodeToIdMap));
+ m_frontend->pseudoElementAdded(parentId, buildObjectForNode(pseudoElement, 0, m_documentNodeToIdMap.get()));
}
void InspectorDOMAgent::pseudoElementDestroyed(PseudoElement* pseudoElement)
{
- int pseudoElementId = m_documentNodeToIdMap.get(pseudoElement);
+ int pseudoElementId = m_documentNodeToIdMap->get(pseudoElement);
if (!pseudoElementId)
return;
// If a PseudoElement is bound, its parent element must be bound, too.
Element* parent = pseudoElement->parentOrShadowHostElement();
ASSERT(parent);
- int parentId = m_documentNodeToIdMap.get(parent);
+ int parentId = m_documentNodeToIdMap->get(parent);
ASSERT(parentId);
- unbind(pseudoElement, &m_documentNodeToIdMap);
+ unbind(pseudoElement, m_documentNodeToIdMap.get());
m_frontend->pseudoElementRemoved(parentId, pseudoElementId);
}
+static ShadowRoot* shadowRootForNode(Node* node, const String& type)
+{
+ if (!node->isElementNode())
+ return 0;
+ if (type == "a")
+ return toElement(node)->shadowRoot();
+ if (type == "u")
+ return toElement(node)->userAgentShadowRoot();
+ return 0;
+}
+
Node* InspectorDOMAgent::nodeForPath(const String& path)
{
- // The path is of form "1,HTML,2,BODY,1,DIV"
+ // The path is of form "1,HTML,2,BODY,1,DIV" (<index> and <nodeName> interleaved).
+ // <index> may also be "a" (author shadow root) or "u" (user-agent shadow root),
+ // in which case <nodeName> MUST be "#document-fragment".
if (!m_document)
return 0;
@@ -1951,13 +2013,17 @@ Node* InspectorDOMAgent::nodeForPath(const String& path)
return 0;
for (size_t i = 0; i < pathTokens.size() - 1; i += 2) {
bool success = true;
- unsigned childNumber = pathTokens[i].toUInt(&success);
- if (!success)
- return 0;
- if (childNumber >= innerChildNodeCount(node))
- return 0;
+ String& indexValue = pathTokens[i];
+ unsigned childNumber = indexValue.toUInt(&success);
+ Node* child;
+ if (!success) {
+ child = shadowRootForNode(node, indexValue);
+ } else {
+ if (childNumber >= innerChildNodeCount(node))
+ return 0;
- Node* child = innerFirstChild(node);
+ child = innerFirstChild(node);
+ }
String childName = pathTokens[i + 1];
for (size_t j = 0; child && j < childNumber; ++j)
child = innerNextSibling(child);
@@ -1977,20 +2043,22 @@ void InspectorDOMAgent::pushNodeByPathToFrontend(ErrorString* errorString, const
*errorString = "No node with given path found";
}
-void InspectorDOMAgent::pushNodeByBackendIdToFrontend(ErrorString* errorString, BackendNodeId backendNodeId, int* nodeId)
+void InspectorDOMAgent::pushNodesByBackendIdsToFrontend(ErrorString* errorString, const RefPtr<JSONArray>& backendNodeIds, RefPtr<TypeBuilder::Array<int> >& result)
{
- if (!m_backendIdToNode.contains(backendNodeId)) {
- *errorString = "No node with given backend id found";
- return;
- }
+ result = TypeBuilder::Array<int>::create();
+ for (JSONArray::const_iterator it = backendNodeIds->begin(); it != backendNodeIds->end(); ++it) {
+ int backendNodeId;
- Node* node = m_backendIdToNode.get(backendNodeId).first;
- String nodeGroup = m_backendIdToNode.get(backendNodeId).second;
- *nodeId = pushNodePathToFrontend(node);
+ if (!(*it)->asNumber(&backendNodeId)) {
+ *errorString = "Invalid argument type";
+ return;
+ }
- if (nodeGroup == "") {
- m_backendIdToNode.remove(backendNodeId);
- m_nodeGroupToBackendIdMap.find(nodeGroup)->value.remove(node);
+ Node* node = InspectorNodeIds::nodeForId(backendNodeId);
+ if (node && node->document().page() == m_pageAgent->page())
+ result->addItem(pushNodePathToFrontend(node));
+ else
+ result->addItem(0);
}
}
@@ -2004,7 +2072,7 @@ void InspectorDOMAgent::getRelayoutBoundary(ErrorString* errorString, int nodeId
*errorString = "No renderer for node, perhaps orphan or hidden node";
return;
}
- while (renderer && !renderer->isRoot() && !renderer->isRelayoutBoundaryForInspector())
+ while (renderer && !renderer->isDocumentElement() && !renderer->isRelayoutBoundaryForInspector())
renderer = renderer->container();
Node* resultNode = renderer ? renderer->generatingNode() : node->ownerDocument();
*relayoutBoundaryNodeId = pushNodePathToFrontend(resultNode);
@@ -2013,20 +2081,21 @@ void InspectorDOMAgent::getRelayoutBoundary(ErrorString* errorString, int nodeId
PassRefPtr<TypeBuilder::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
{
Document* document = node->isDocumentNode() ? &node->document() : node->ownerDocument();
- Frame* frame = document ? document->frame() : 0;
+ LocalFrame* frame = document ? document->frame() : 0;
if (!frame)
- return 0;
+ return nullptr;
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(mainWorldScriptState(frame));
- if (injectedScript.hasNoValue())
- return 0;
+ InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(ScriptState::forMainWorld(frame));
+ if (injectedScript.isEmpty())
+ return nullptr;
return injectedScript.wrapNode(node, objectGroup);
}
bool InspectorDOMAgent::pushDocumentUponHandlelessOperation(ErrorString* errorString)
{
- if (!m_documentNodeToIdMap.contains(m_document)) {
+ // FIXME: Oilpan: .get will be unnecessary if m_document is a Member<>.
+ if (!m_documentNodeToIdMap->contains(m_document.get())) {
RefPtr<TypeBuilder::DOM::Node> root;
getDocument(errorString, root);
return errorString->isEmpty();
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
index c1042f57b2e..fc8d3f3b263 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
@@ -30,7 +30,7 @@
#ifndef InspectorDOMAgent_h
#define InspectorDOMAgent_h
-#include "InspectorFrontend.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptManager.h"
#include "core/inspector/InspectorBaseAgent.h"
@@ -51,8 +51,8 @@ class CharacterData;
class DOMEditor;
class Document;
class Element;
+class EventTarget;
class ExceptionState;
-class InspectorClient;
class InspectorFrontend;
class InspectorHistory;
class InspectorOverlay;
@@ -68,23 +68,22 @@ class ShadowRoot;
struct HighlightConfig;
typedef String ErrorString;
-typedef int BackendNodeId;
struct EventListenerInfo {
- EventListenerInfo(Node* node, const AtomicString& eventType, const EventListenerVector& eventListenerVector)
- : node(node)
+ EventListenerInfo(EventTarget* eventTarget, const AtomicString& eventType, const EventListenerVector& eventListenerVector)
+ : eventTarget(eventTarget)
, eventType(eventType)
, eventListenerVector(eventListenerVector)
{
}
- Node* node;
+ EventTarget* eventTarget;
const AtomicString eventType;
const EventListenerVector eventListenerVector;
};
-class InspectorDOMAgent : public InspectorBaseAgent<InspectorDOMAgent>, public InspectorBackendDispatcher::DOMCommandHandler {
+class InspectorDOMAgent FINAL : public InspectorBaseAgent<InspectorDOMAgent>, public InspectorBackendDispatcher::DOMCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorDOMAgent);
public:
struct DOMListener {
@@ -96,98 +95,107 @@ public:
virtual void didModifyDOMAttr(Element*) = 0;
};
- static PassOwnPtr<InspectorDOMAgent> create(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay, InspectorClient* client)
+ static PassOwnPtr<InspectorDOMAgent> create(InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
{
- return adoptPtr(new InspectorDOMAgent(instrumentingAgents, pageAgent, inspectorState, injectedScriptManager, overlay, client));
+ return adoptPtr(new InspectorDOMAgent(pageAgent, injectedScriptManager, overlay));
}
static String toErrorString(ExceptionState&);
- ~InspectorDOMAgent();
+ virtual ~InspectorDOMAgent();
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
Vector<Document*> documents();
void reset();
// Methods called from the frontend for DOM nodes inspection.
- virtual void querySelector(ErrorString*, int nodeId, const String& selectors, int* elementId);
- virtual void querySelectorAll(ErrorString*, int nodeId, const String& selectors, RefPtr<TypeBuilder::Array<int> >& result);
- virtual void getDocument(ErrorString*, RefPtr<TypeBuilder::DOM::Node>& root);
- virtual void requestChildNodes(ErrorString*, int nodeId, const int* depth);
- virtual void setAttributeValue(ErrorString*, int elementId, const String& name, const String& value);
- virtual void setAttributesAsText(ErrorString*, int elementId, const String& text, const String* name);
- virtual void removeAttribute(ErrorString*, int elementId, const String& name);
- virtual void removeNode(ErrorString*, int nodeId);
- virtual void setNodeName(ErrorString*, int nodeId, const String& name, int* newId);
- virtual void getOuterHTML(ErrorString*, int nodeId, WTF::String* outerHTML);
- virtual void setOuterHTML(ErrorString*, int nodeId, const String& outerHTML);
- virtual void setNodeValue(ErrorString*, int nodeId, const String& value);
- virtual void getEventListenersForNode(ErrorString*, int nodeId, const WTF::String* objectGroup, RefPtr<TypeBuilder::Array<TypeBuilder::DOM::EventListener> >& listenersArray);
- virtual void performSearch(ErrorString*, const String& whitespaceTrimmedQuery, String* searchId, int* resultCount);
- virtual void getSearchResults(ErrorString*, const String& searchId, int fromIndex, int toIndex, RefPtr<TypeBuilder::Array<int> >&);
- virtual void discardSearchResults(ErrorString*, const String& searchId);
- virtual void resolveNode(ErrorString*, int nodeId, const String* objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& result);
- virtual void getAttributes(ErrorString*, int nodeId, RefPtr<TypeBuilder::Array<String> >& result);
- virtual void setInspectModeEnabled(ErrorString*, bool enabled, const bool* inspectShadowDOM, const RefPtr<JSONObject>* highlightConfig);
- virtual void requestNode(ErrorString*, const String& objectId, int* nodeId);
- virtual void pushNodeByPathToFrontend(ErrorString*, const String& path, int* nodeId);
- virtual void pushNodeByBackendIdToFrontend(ErrorString*, BackendNodeId, int* nodeId);
- virtual void releaseBackendNodeIds(ErrorString*, const String& nodeGroup);
- virtual void hideHighlight(ErrorString*);
- virtual void highlightRect(ErrorString*, int x, int y, int width, int height, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor);
- virtual void highlightQuad(ErrorString*, const RefPtr<JSONArray>& quad, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor);
- virtual void highlightNode(ErrorString*, const RefPtr<JSONObject>& highlightConfig, const int* nodeId, const String* objectId);
- virtual void highlightFrame(ErrorString*, const String& frameId, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor);
-
- virtual void moveTo(ErrorString*, int nodeId, int targetNodeId, const int* anchorNodeId, int* newNodeId);
- virtual void undo(ErrorString*);
- virtual void redo(ErrorString*);
- virtual void markUndoableState(ErrorString*);
- virtual void focus(ErrorString*, int nodeId);
- virtual void setFileInputFiles(ErrorString*, int nodeId, const RefPtr<JSONArray>& files);
- virtual void getBoxModel(ErrorString*, int nodeId, RefPtr<TypeBuilder::DOM::BoxModel>&);
- virtual void getNodeForLocation(ErrorString*, int x, int y, int* nodeId);
- virtual void getRelayoutBoundary(ErrorString*, int nodeId, int* relayoutBoundaryNodeId);
-
- static void getEventListeners(Node*, Vector<EventListenerInfo>& listenersArray, bool includeAncestors);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void querySelector(ErrorString*, int nodeId, const String& selectors, int* elementId) OVERRIDE;
+ virtual void querySelectorAll(ErrorString*, int nodeId, const String& selectors, RefPtr<TypeBuilder::Array<int> >& result) OVERRIDE;
+ virtual void getDocument(ErrorString*, RefPtr<TypeBuilder::DOM::Node>& root) OVERRIDE;
+ virtual void requestChildNodes(ErrorString*, int nodeId, const int* depth) OVERRIDE;
+ virtual void setAttributeValue(ErrorString*, int elementId, const String& name, const String& value) OVERRIDE;
+ virtual void setAttributesAsText(ErrorString*, int elementId, const String& text, const String* name) OVERRIDE;
+ virtual void removeAttribute(ErrorString*, int elementId, const String& name) OVERRIDE;
+ virtual void removeNode(ErrorString*, int nodeId) OVERRIDE;
+ virtual void setNodeName(ErrorString*, int nodeId, const String& name, int* newId) OVERRIDE;
+ virtual void getOuterHTML(ErrorString*, int nodeId, WTF::String* outerHTML) OVERRIDE;
+ virtual void setOuterHTML(ErrorString*, int nodeId, const String& outerHTML) OVERRIDE;
+ virtual void setNodeValue(ErrorString*, int nodeId, const String& value) OVERRIDE;
+ virtual void getEventListenersForNode(ErrorString*, int nodeId, const WTF::String* objectGroup, RefPtr<TypeBuilder::Array<TypeBuilder::DOM::EventListener> >& listenersArray) OVERRIDE;
+ virtual void performSearch(ErrorString*, const String& whitespaceTrimmedQuery, String* searchId, int* resultCount) OVERRIDE;
+ virtual void getSearchResults(ErrorString*, const String& searchId, int fromIndex, int toIndex, RefPtr<TypeBuilder::Array<int> >&) OVERRIDE;
+ virtual void discardSearchResults(ErrorString*, const String& searchId) OVERRIDE;
+ virtual void resolveNode(ErrorString*, int nodeId, const String* objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& result) OVERRIDE;
+ virtual void getAttributes(ErrorString*, int nodeId, RefPtr<TypeBuilder::Array<String> >& result) OVERRIDE;
+ virtual void setInspectModeEnabled(ErrorString*, bool enabled, const bool* inspectUAShadowDOM, const RefPtr<JSONObject>* highlightConfig) OVERRIDE;
+ virtual void requestNode(ErrorString*, const String& objectId, int* nodeId) OVERRIDE;
+ virtual void pushNodeByPathToFrontend(ErrorString*, const String& path, int* nodeId) OVERRIDE;
+ virtual void pushNodesByBackendIdsToFrontend(ErrorString*, const RefPtr<JSONArray>& nodeIds, RefPtr<TypeBuilder::Array<int> >&) OVERRIDE;
+ virtual void hideHighlight(ErrorString*) OVERRIDE;
+ virtual void highlightRect(ErrorString*, int x, int y, int width, int height, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor) OVERRIDE;
+ virtual void highlightQuad(ErrorString*, const RefPtr<JSONArray>& quad, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor) OVERRIDE;
+ virtual void highlightNode(ErrorString*, const RefPtr<JSONObject>& highlightConfig, const int* nodeId, const String* objectId) OVERRIDE;
+ virtual void highlightFrame(ErrorString*, const String& frameId, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor) OVERRIDE;
+
+ virtual void moveTo(ErrorString*, int nodeId, int targetNodeId, const int* anchorNodeId, int* newNodeId) OVERRIDE;
+ virtual void undo(ErrorString*) OVERRIDE;
+ virtual void redo(ErrorString*) OVERRIDE;
+ virtual void markUndoableState(ErrorString*) OVERRIDE;
+ virtual void focus(ErrorString*, int nodeId) OVERRIDE;
+ virtual void setFileInputFiles(ErrorString*, int nodeId, const RefPtr<JSONArray>& files) OVERRIDE;
+ virtual void getBoxModel(ErrorString*, int nodeId, RefPtr<TypeBuilder::DOM::BoxModel>&) OVERRIDE;
+ virtual void getNodeForLocation(ErrorString*, int x, int y, int* nodeId) OVERRIDE;
+ virtual void getRelayoutBoundary(ErrorString*, int nodeId, int* relayoutBoundaryNodeId) OVERRIDE;
+
+ static void getEventListeners(EventTarget*, Vector<EventListenerInfo>& listenersArray, bool includeAncestors);
+
+ class Listener {
+ public:
+ virtual ~Listener() { }
+ virtual void domAgentWasEnabled() = 0;
+ virtual void domAgentWasDisabled() = 0;
+ };
+ void setListener(Listener* listener) { m_listener = listener; }
+
+ bool enabled() const;
// Methods called from the InspectorInstrumentation.
void setDocument(Document*);
void releaseDanglingNodes();
- void domContentLoadedEventFired(Frame*);
- void didCommitLoad(Frame*, DocumentLoader*);
+ void domContentLoadedEventFired(LocalFrame*);
+ void didCommitLoad(LocalFrame*, DocumentLoader*);
void didInsertDOMNode(Node*);
void willRemoveDOMNode(Node*);
void willModifyDOMAttr(Element*, const AtomicString& oldValue, const AtomicString& newValue);
void didModifyDOMAttr(Element*, const AtomicString& name, const AtomicString& value);
void didRemoveDOMAttr(Element*, const AtomicString& name);
- void styleAttributeInvalidated(const Vector<Element*>& elements);
+ void styleAttributeInvalidated(const WillBeHeapVector<RawPtrWillBeMember<Element> >& elements);
void characterDataModified(CharacterData*);
void didInvalidateStyleAttr(Node*);
void didPushShadowRoot(Element* host, ShadowRoot*);
void willPopShadowRoot(Element* host, ShadowRoot*);
- void frameDocumentUpdated(Frame*);
+ void frameDocumentUpdated(LocalFrame*);
void pseudoElementCreated(PseudoElement*);
void pseudoElementDestroyed(PseudoElement*);
- int pushNodeToFrontend(ErrorString*, int documentNodeId, Node*);
Node* nodeForId(int nodeId);
int boundNodeId(Node*);
void setDOMListener(DOMListener*);
- BackendNodeId backendNodeIdForNode(Node*, const String& nodeGroup);
static String documentURLString(Document*);
PassRefPtr<TypeBuilder::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup);
bool handleMousePress();
- bool handleGestureEvent(Frame*, const PlatformGestureEvent&);
- bool handleTouchEvent(Frame*, const PlatformTouchEvent&);
- void handleMouseMove(Frame*, const PlatformMouseEvent&);
+ bool handleGestureEvent(LocalFrame*, const PlatformGestureEvent&);
+ bool handleTouchEvent(LocalFrame*, const PlatformTouchEvent&);
+ void handleMouseMove(LocalFrame*, const PlatformMouseEvent&);
InspectorHistory* history() { return m_history.get(); }
@@ -205,15 +213,15 @@ public:
Document* assertDocument(ErrorString*, int nodeId);
private:
- enum SearchMode { NotSearching, SearchingForNormal, SearchingForShadow };
+ enum SearchMode { NotSearching, SearchingForNormal, SearchingForUAShadow };
- InspectorDOMAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorCompositeState*, InjectedScriptManager*, InspectorOverlay*, InspectorClient*);
+ InspectorDOMAgent(InspectorPageAgent*, InjectedScriptManager*, InspectorOverlay*);
void setSearchingForNode(ErrorString*, SearchMode, JSONObject* highlightConfig);
PassOwnPtr<HighlightConfig> highlightConfigFromInspectorObject(ErrorString*, JSONObject* highlightInspectorObject);
// Node-related methods.
- typedef HashMap<RefPtr<Node>, int> NodeToIdMap;
+ typedef WillBeHeapHashMap<RefPtrWillBeMember<Node>, int> NodeToIdMap;
int bind(Node*, NodeToIdMap*);
void unbind(Node*, NodeToIdMap*);
@@ -225,7 +233,7 @@ private:
int pushNodePathToFrontend(Node*);
void pushChildNodesToFrontend(int nodeId, int depth = 1);
- void invalidateFrameOwnerElement(Frame*);
+ void invalidateFrameOwnerElement(LocalFrame*);
bool hasBreakpoint(Node*, int type);
void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
@@ -239,7 +247,6 @@ private:
Node* nodeForPath(const String& path);
- void discardBackendBindings();
void discardFrontendBindings();
void innerHighlightQuad(PassOwnPtr<FloatQuad>, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor);
@@ -249,29 +256,26 @@ private:
InspectorPageAgent* m_pageAgent;
InjectedScriptManager* m_injectedScriptManager;
InspectorOverlay* m_overlay;
- InspectorClient* m_client;
InspectorFrontend::DOM* m_frontend;
DOMListener* m_domListener;
- NodeToIdMap m_documentNodeToIdMap;
- typedef HashMap<RefPtr<Node>, BackendNodeId> NodeToBackendIdMap;
- HashMap<String, NodeToBackendIdMap> m_nodeGroupToBackendIdMap;
+ OwnPtrWillBePersistent<NodeToIdMap> m_documentNodeToIdMap;
// Owns node mappings for dangling nodes.
- Vector<OwnPtr<NodeToIdMap> > m_danglingNodeToIdMaps;
- HashMap<int, Node*> m_idToNode;
- HashMap<int, NodeToIdMap*> m_idToNodesMap;
+ WillBePersistentHeapVector<OwnPtrWillBeMember<NodeToIdMap> > m_danglingNodeToIdMaps;
+ WillBePersistentHeapHashMap<int, RawPtrWillBeMember<Node> > m_idToNode;
+ WillBePersistentHeapHashMap<int, RawPtrWillBeMember<NodeToIdMap> > m_idToNodesMap;
HashSet<int> m_childrenRequested;
- HashMap<BackendNodeId, std::pair<Node*, String> > m_backendIdToNode;
+ HashMap<int, int> m_cachedChildCount;
int m_lastNodeId;
- BackendNodeId m_lastBackendNodeId;
- RefPtr<Document> m_document;
- typedef HashMap<String, Vector<RefPtr<Node> > > SearchResults;
+ RefPtrWillBePersistent<Document> m_document;
+ typedef WillBePersistentHeapHashMap<String, WillBeHeapVector<RefPtrWillBeMember<Node> > > SearchResults;
SearchResults m_searchResults;
OwnPtr<RevalidateStyleAttributeTask> m_revalidateStyleAttrTask;
SearchMode m_searchingForNode;
OwnPtr<HighlightConfig> m_inspectModeHighlightConfig;
- OwnPtr<InspectorHistory> m_history;
- OwnPtr<DOMEditor> m_domEditor;
+ OwnPtrWillBePersistent<InspectorHistory> m_history;
+ OwnPtrWillBePersistent<DOMEditor> m_domEditor;
bool m_suppressAttributeModifiedEvent;
+ Listener* m_listener;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
index 1fe691875ab..00289f5381d 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
@@ -31,8 +31,7 @@
#include "config.h"
#include "core/inspector/InspectorDOMDebuggerAgent.h"
-#include "InspectorFrontend.h"
-#include "core/events/Event.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorDOMAgent.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
@@ -63,28 +62,31 @@ static const char animationFrameFiredEventName[] = "animationFrameFired";
static const char setTimerEventName[] = "setTimer";
static const char clearTimerEventName[] = "clearTimer";
static const char timerFiredEventName[] = "timerFired";
+static const char customElementCallbackName[] = "customElementCallback";
static const char webglErrorFiredEventName[] = "webglErrorFired";
static const char webglWarningFiredEventName[] = "webglWarningFired";
static const char webglErrorNameProperty[] = "webglErrorName";
namespace DOMDebuggerAgentState {
static const char eventListenerBreakpoints[] = "eventListenerBreakpoints";
+static const char eventTargetAny[] = "*";
static const char pauseOnAllXHRs[] = "pauseOnAllXHRs";
static const char xhrBreakpoints[] = "xhrBreakpoints";
}
-PassOwnPtr<InspectorDOMDebuggerAgent> InspectorDOMDebuggerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent)
+PassOwnPtr<InspectorDOMDebuggerAgent> InspectorDOMDebuggerAgent::create(InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent)
{
- return adoptPtr(new InspectorDOMDebuggerAgent(instrumentingAgents, inspectorState, domAgent, debuggerAgent));
+ return adoptPtr(new InspectorDOMDebuggerAgent(domAgent, debuggerAgent));
}
-InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent)
- : InspectorBaseAgent<InspectorDOMDebuggerAgent>("DOMDebugger", instrumentingAgents, inspectorState)
+InspectorDOMDebuggerAgent::InspectorDOMDebuggerAgent(InspectorDOMAgent* domAgent, InspectorDebuggerAgent* debuggerAgent)
+ : InspectorBaseAgent<InspectorDOMDebuggerAgent>("DOMDebugger")
, m_domAgent(domAgent)
, m_debuggerAgent(debuggerAgent)
, m_pauseInNextEventListener(false)
{
m_debuggerAgent->setListener(this);
+ m_domAgent->setListener(this);
}
InspectorDOMDebuggerAgent::~InspectorDOMDebuggerAgent()
@@ -96,7 +98,8 @@ InspectorDOMDebuggerAgent::~InspectorDOMDebuggerAgent()
// Browser debugger agent enabled only when JS debugger is enabled.
void InspectorDOMDebuggerAgent::debuggerWasEnabled()
{
- m_instrumentingAgents->setInspectorDOMDebuggerAgent(this);
+ if (m_domAgent->enabled() && m_debuggerAgent->enabled())
+ m_instrumentingAgents->setInspectorDOMDebuggerAgent(this);
}
void InspectorDOMDebuggerAgent::debuggerWasDisabled()
@@ -104,6 +107,17 @@ void InspectorDOMDebuggerAgent::debuggerWasDisabled()
disable();
}
+void InspectorDOMDebuggerAgent::domAgentWasEnabled()
+{
+ if (m_domAgent->enabled() && m_debuggerAgent->enabled())
+ m_instrumentingAgents->setInspectorDOMDebuggerAgent(this);
+}
+
+void InspectorDOMDebuggerAgent::domAgentWasDisabled()
+{
+ disable();
+}
+
void InspectorDOMDebuggerAgent::stepInto()
{
m_pauseInNextEventListener = true;
@@ -140,22 +154,28 @@ void InspectorDOMDebuggerAgent::discardAgent()
m_debuggerAgent = 0;
}
-void InspectorDOMDebuggerAgent::discardBindings()
+void InspectorDOMDebuggerAgent::setEventListenerBreakpoint(ErrorString* error, const String& eventName, const String* targetName)
{
- m_domBreakpoints.clear();
+ setBreakpoint(error, String(listenerEventCategoryType) + eventName, targetName);
}
-void InspectorDOMDebuggerAgent::setEventListenerBreakpoint(ErrorString* error, const String& eventName)
+void InspectorDOMDebuggerAgent::setInstrumentationBreakpoint(ErrorString* error, const String& eventName)
{
- setBreakpoint(error, String(listenerEventCategoryType) + eventName);
+ setBreakpoint(error, String(instrumentationEventCategoryType) + eventName, 0);
}
-void InspectorDOMDebuggerAgent::setInstrumentationBreakpoint(ErrorString* error, const String& eventName)
+static PassRefPtr<JSONObject> ensurePropertyObject(JSONObject* object, const String& propertyName)
{
- setBreakpoint(error, String(instrumentationEventCategoryType) + eventName);
+ JSONObject::iterator it = object->find(propertyName);
+ if (it != object->end())
+ return it->value->asObject();
+
+ RefPtr<JSONObject> result = JSONObject::create();
+ object->setObject(propertyName, result);
+ return result.release();
}
-void InspectorDOMDebuggerAgent::setBreakpoint(ErrorString* error, const String& eventName)
+void InspectorDOMDebuggerAgent::setBreakpoint(ErrorString* error, const String& eventName, const String* targetName)
{
if (eventName.isEmpty()) {
*error = "Event name is empty";
@@ -163,21 +183,25 @@ void InspectorDOMDebuggerAgent::setBreakpoint(ErrorString* error, const String&
}
RefPtr<JSONObject> eventListenerBreakpoints = m_state->getObject(DOMDebuggerAgentState::eventListenerBreakpoints);
- eventListenerBreakpoints->setBoolean(eventName, true);
- m_state->setObject(DOMDebuggerAgentState::eventListenerBreakpoints, eventListenerBreakpoints);
+ RefPtr<JSONObject> breakpointsByTarget = ensurePropertyObject(eventListenerBreakpoints.get(), eventName);
+ if (!targetName || targetName->isEmpty())
+ breakpointsByTarget->setBoolean(DOMDebuggerAgentState::eventTargetAny, true);
+ else
+ breakpointsByTarget->setBoolean(targetName->lower(), true);
+ m_state->setObject(DOMDebuggerAgentState::eventListenerBreakpoints, eventListenerBreakpoints.release());
}
-void InspectorDOMDebuggerAgent::removeEventListenerBreakpoint(ErrorString* error, const String& eventName)
+void InspectorDOMDebuggerAgent::removeEventListenerBreakpoint(ErrorString* error, const String& eventName, const String* targetName)
{
- removeBreakpoint(error, String(listenerEventCategoryType) + eventName);
+ removeBreakpoint(error, String(listenerEventCategoryType) + eventName, targetName);
}
void InspectorDOMDebuggerAgent::removeInstrumentationBreakpoint(ErrorString* error, const String& eventName)
{
- removeBreakpoint(error, String(instrumentationEventCategoryType) + eventName);
+ removeBreakpoint(error, String(instrumentationEventCategoryType) + eventName, 0);
}
-void InspectorDOMDebuggerAgent::removeBreakpoint(ErrorString* error, const String& eventName)
+void InspectorDOMDebuggerAgent::removeBreakpoint(ErrorString* error, const String& eventName, const String* targetName)
{
if (eventName.isEmpty()) {
*error = "Event name is empty";
@@ -185,8 +209,12 @@ void InspectorDOMDebuggerAgent::removeBreakpoint(ErrorString* error, const Strin
}
RefPtr<JSONObject> eventListenerBreakpoints = m_state->getObject(DOMDebuggerAgentState::eventListenerBreakpoints);
- eventListenerBreakpoints->remove(eventName);
- m_state->setObject(DOMDebuggerAgentState::eventListenerBreakpoints, eventListenerBreakpoints);
+ RefPtr<JSONObject> breakpointsByTarget = ensurePropertyObject(eventListenerBreakpoints.get(), eventName);
+ if (!targetName || targetName->isEmpty())
+ breakpointsByTarget->remove(DOMDebuggerAgentState::eventTargetAny);
+ else
+ breakpointsByTarget->remove(targetName->lower());
+ m_state->setObject(DOMDebuggerAgentState::eventListenerBreakpoints, eventListenerBreakpoints.release());
}
void InspectorDOMDebuggerAgent::didInvalidateStyleAttr(Node* node)
@@ -389,60 +417,75 @@ void InspectorDOMDebuggerAgent::pauseOnNativeEventIfNeeded(PassRefPtr<JSONObject
m_debuggerAgent->schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::EventListener, eventData);
}
-PassRefPtr<JSONObject> InspectorDOMDebuggerAgent::preparePauseOnNativeEventData(bool isDOMEvent, const String& eventName)
+PassRefPtr<JSONObject> InspectorDOMDebuggerAgent::preparePauseOnNativeEventData(const String& eventName, const AtomicString* targetName)
{
- String fullEventName = (isDOMEvent ? listenerEventCategoryType : instrumentationEventCategoryType) + eventName;
- if (m_pauseInNextEventListener)
+ String fullEventName = (targetName ? listenerEventCategoryType : instrumentationEventCategoryType) + eventName;
+ if (m_pauseInNextEventListener) {
m_pauseInNextEventListener = false;
- else {
+ } else {
RefPtr<JSONObject> eventListenerBreakpoints = m_state->getObject(DOMDebuggerAgentState::eventListenerBreakpoints);
- if (eventListenerBreakpoints->find(fullEventName) == eventListenerBreakpoints->end())
- return 0;
+ JSONObject::iterator it = eventListenerBreakpoints->find(fullEventName);
+ if (it == eventListenerBreakpoints->end())
+ return nullptr;
+ bool match = false;
+ RefPtr<JSONObject> breakpointsByTarget = it->value->asObject();
+ breakpointsByTarget->getBoolean(DOMDebuggerAgentState::eventTargetAny, &match);
+ if (!match && targetName)
+ breakpointsByTarget->getBoolean(targetName->lower(), &match);
+ if (!match)
+ return nullptr;
}
RefPtr<JSONObject> eventData = JSONObject::create();
eventData->setString("eventName", fullEventName);
+ if (targetName)
+ eventData->setString("targetName", *targetName);
return eventData.release();
}
-void InspectorDOMDebuggerAgent::didInstallTimer(ExecutionContext* context, int timerId, int timeout, bool singleShot)
+void InspectorDOMDebuggerAgent::didInstallTimer(ExecutionContext*, int, int, bool)
+{
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(setTimerEventName, 0), true);
+}
+
+void InspectorDOMDebuggerAgent::didRemoveTimer(ExecutionContext*, int)
{
- pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(false, setTimerEventName), true);
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(clearTimerEventName, 0), true);
}
-void InspectorDOMDebuggerAgent::didRemoveTimer(ExecutionContext* context, int timerId)
+void InspectorDOMDebuggerAgent::willFireTimer(ExecutionContext*, int)
{
- pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(false, clearTimerEventName), true);
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(timerFiredEventName, 0), false);
}
-void InspectorDOMDebuggerAgent::willFireTimer(ExecutionContext* context, int timerId)
+void InspectorDOMDebuggerAgent::didRequestAnimationFrame(Document*, int)
{
- pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(false, timerFiredEventName), false);
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(requestAnimationFrameEventName, 0), true);
}
-void InspectorDOMDebuggerAgent::didRequestAnimationFrame(Document* document, int callbackId)
+void InspectorDOMDebuggerAgent::didCancelAnimationFrame(Document*, int)
{
- pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(false, requestAnimationFrameEventName), true);
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(cancelAnimationFrameEventName, 0), true);
}
-void InspectorDOMDebuggerAgent::didCancelAnimationFrame(Document* document, int callbackId)
+void InspectorDOMDebuggerAgent::willFireAnimationFrame(Document*, int)
{
- pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(false, cancelAnimationFrameEventName), true);
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(animationFrameFiredEventName, 0), false);
}
-void InspectorDOMDebuggerAgent::willFireAnimationFrame(Document* document, int callbackId)
+void InspectorDOMDebuggerAgent::willHandleEvent(EventTarget* target, Event* event, EventListener*, bool)
{
- pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(false, animationFrameFiredEventName), false);
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(event->type(), &target->interfaceName()), false);
}
-void InspectorDOMDebuggerAgent::willHandleEvent(Event* event)
+void InspectorDOMDebuggerAgent::willExecuteCustomElementCallback(Element*)
{
- pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(true, event->type()), false);
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(customElementCallbackName, 0), false);
}
void InspectorDOMDebuggerAgent::didFireWebGLError(const String& errorName)
{
- RefPtr<JSONObject> eventData = preparePauseOnNativeEventData(false, webglErrorFiredEventName);
+ RefPtr<JSONObject> eventData = preparePauseOnNativeEventData(webglErrorFiredEventName, 0);
if (!eventData)
return;
if (!errorName.isEmpty())
@@ -452,7 +495,7 @@ void InspectorDOMDebuggerAgent::didFireWebGLError(const String& errorName)
void InspectorDOMDebuggerAgent::didFireWebGLWarning()
{
- pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(false, webglWarningFiredEventName), m_debuggerAgent->canBreakProgram());
+ pauseOnNativeEventIfNeeded(preparePauseOnNativeEventData(webglWarningFiredEventName, 0), m_debuggerAgent->canBreakProgram());
}
void InspectorDOMDebuggerAgent::didFireWebGLErrorOrWarning(const String& message)
@@ -472,7 +515,7 @@ void InspectorDOMDebuggerAgent::setXHRBreakpoint(ErrorString*, const String& url
RefPtr<JSONObject> xhrBreakpoints = m_state->getObject(DOMDebuggerAgentState::xhrBreakpoints);
xhrBreakpoints->setBoolean(url, true);
- m_state->setObject(DOMDebuggerAgentState::xhrBreakpoints, xhrBreakpoints);
+ m_state->setObject(DOMDebuggerAgentState::xhrBreakpoints, xhrBreakpoints.release());
}
void InspectorDOMDebuggerAgent::removeXHRBreakpoint(ErrorString*, const String& url)
@@ -484,7 +527,7 @@ void InspectorDOMDebuggerAgent::removeXHRBreakpoint(ErrorString*, const String&
RefPtr<JSONObject> xhrBreakpoints = m_state->getObject(DOMDebuggerAgentState::xhrBreakpoints);
xhrBreakpoints->remove(url);
- m_state->setObject(DOMDebuggerAgentState::xhrBreakpoints, xhrBreakpoints);
+ m_state->setObject(DOMDebuggerAgentState::xhrBreakpoints, xhrBreakpoints.release());
}
void InspectorDOMDebuggerAgent::willSendXMLHttpRequest(const String& url)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
index 2b0b87bfc94..08499866baa 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.h
@@ -33,6 +33,7 @@
#include "core/inspector/InspectorBaseAgent.h"
+#include "core/inspector/InspectorDOMAgent.h"
#include "core/inspector/InspectorDebuggerAgent.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
@@ -43,6 +44,8 @@ namespace WebCore {
class Document;
class Element;
class Event;
+class EventListener;
+class EventTarget;
class InspectorDOMAgent;
class InspectorDebuggerAgent;
class InspectorFrontend;
@@ -52,22 +55,26 @@ class Node;
typedef String ErrorString;
-class InspectorDOMDebuggerAgent : public InspectorBaseAgent<InspectorDOMDebuggerAgent>, public InspectorDebuggerAgent::Listener, public InspectorBackendDispatcher::DOMDebuggerCommandHandler {
+class InspectorDOMDebuggerAgent FINAL :
+ public InspectorBaseAgent<InspectorDOMDebuggerAgent>,
+ public InspectorDebuggerAgent::Listener,
+ public InspectorDOMAgent::Listener,
+ public InspectorBackendDispatcher::DOMDebuggerCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorDOMDebuggerAgent);
public:
- static PassOwnPtr<InspectorDOMDebuggerAgent> create(InstrumentingAgents*, InspectorCompositeState*, InspectorDOMAgent*, InspectorDebuggerAgent*);
+ static PassOwnPtr<InspectorDOMDebuggerAgent> create(InspectorDOMAgent*, InspectorDebuggerAgent*);
virtual ~InspectorDOMDebuggerAgent();
// DOMDebugger API for InspectorFrontend
- virtual void setXHRBreakpoint(ErrorString*, const String& url);
- virtual void removeXHRBreakpoint(ErrorString*, const String& url);
- virtual void setEventListenerBreakpoint(ErrorString*, const String& eventName);
- virtual void removeEventListenerBreakpoint(ErrorString*, const String& eventName);
- virtual void setInstrumentationBreakpoint(ErrorString*, const String& eventName);
- virtual void removeInstrumentationBreakpoint(ErrorString*, const String& eventName);
- virtual void setDOMBreakpoint(ErrorString*, int nodeId, const String& type);
- virtual void removeDOMBreakpoint(ErrorString*, int nodeId, const String& type);
+ virtual void setXHRBreakpoint(ErrorString*, const String& url) OVERRIDE;
+ virtual void removeXHRBreakpoint(ErrorString*, const String& url) OVERRIDE;
+ virtual void setEventListenerBreakpoint(ErrorString*, const String& eventName, const String* targetName) OVERRIDE;
+ virtual void removeEventListenerBreakpoint(ErrorString*, const String& eventName, const String* targetName) OVERRIDE;
+ virtual void setInstrumentationBreakpoint(ErrorString*, const String& eventName) OVERRIDE;
+ virtual void removeInstrumentationBreakpoint(ErrorString*, const String& eventName) OVERRIDE;
+ virtual void setDOMBreakpoint(ErrorString*, int nodeId, const String& type) OVERRIDE;
+ virtual void removeDOMBreakpoint(ErrorString*, int nodeId, const String& type) OVERRIDE;
// InspectorInstrumentation API
void willInsertDOMNode(Node* parent);
@@ -83,35 +90,39 @@ public:
void didRequestAnimationFrame(Document*, int callbackId);
void didCancelAnimationFrame(Document*, int callbackId);
void willFireAnimationFrame(Document*, int callbackId);
- void willHandleEvent(Event*);
+ void willHandleEvent(EventTarget*, Event*, EventListener*, bool useCapture);
void didFireWebGLError(const String& errorName);
void didFireWebGLWarning();
void didFireWebGLErrorOrWarning(const String& message);
+ void willExecuteCustomElementCallback(Element*);
void didProcessTask();
- virtual void clearFrontend();
- virtual void discardAgent();
+ virtual void clearFrontend() OVERRIDE;
+ virtual void discardAgent() OVERRIDE;
private:
- InspectorDOMDebuggerAgent(InstrumentingAgents*, InspectorCompositeState*, InspectorDOMAgent*, InspectorDebuggerAgent*);
+ InspectorDOMDebuggerAgent(InspectorDOMAgent*, InspectorDebuggerAgent*);
void pauseOnNativeEventIfNeeded(PassRefPtr<JSONObject> eventData, bool synchronous);
- PassRefPtr<JSONObject> preparePauseOnNativeEventData(bool isDOMEvent, const String& eventName);
+ PassRefPtr<JSONObject> preparePauseOnNativeEventData(const String& eventName, const AtomicString* targetName);
+
+ // InspectorDOMAgent::Listener implementation.
+ virtual void domAgentWasEnabled() OVERRIDE;
+ virtual void domAgentWasDisabled() OVERRIDE;
// InspectorDebuggerAgent::Listener implementation.
- virtual void debuggerWasEnabled();
- virtual void debuggerWasDisabled();
- virtual void stepInto();
- virtual void didPause();
+ virtual void debuggerWasEnabled() OVERRIDE;
+ virtual void debuggerWasDisabled() OVERRIDE;
+ virtual void stepInto() OVERRIDE;
+ virtual void didPause() OVERRIDE;
void disable();
void descriptionForDOMEvent(Node* target, int breakpointType, bool insertion, JSONObject* description);
void updateSubtreeBreakpoints(Node*, uint32_t rootMask, bool set);
bool hasBreakpoint(Node*, int type);
- void discardBindings();
- void setBreakpoint(ErrorString*, const String& eventName);
- void removeBreakpoint(ErrorString*, const String& eventName);
+ void setBreakpoint(ErrorString*, const String& eventName, const String* targetName);
+ void removeBreakpoint(ErrorString*, const String& eventName, const String* targetName);
void clear();
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.cpp
index 19e11e86701..bbf184e3506 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.cpp
@@ -30,18 +30,17 @@
#include "config.h"
#include "core/inspector/InspectorDOMStorageAgent.h"
-#include "InspectorFrontend.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/InspectorFrontend.h"
#include "core/dom/DOMException.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/inspector/InspectorPageAgent.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/Page.h"
-#include "core/page/PageGroup.h"
#include "core/storage/Storage.h"
#include "core/storage/StorageNamespace.h"
#include "platform/JSONValues.h"
@@ -68,8 +67,8 @@ static bool hadException(ExceptionState& exceptionState, ErrorString* errorStrin
}
}
-InspectorDOMStorageAgent::InspectorDOMStorageAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorCompositeState* state)
- : InspectorBaseAgent<InspectorDOMStorageAgent>("DOMStorage", instrumentingAgents, state)
+InspectorDOMStorageAgent::InspectorDOMStorageAgent(InspectorPageAgent* pageAgent)
+ : InspectorBaseAgent<InspectorDOMStorageAgent>("DOMStorage")
, m_pageAgent(pageAgent)
, m_frontend(0)
{
@@ -90,6 +89,12 @@ void InspectorDOMStorageAgent::clearFrontend()
disable(0);
}
+void InspectorDOMStorageAgent::restore()
+{
+ if (isEnabled())
+ enable(0);
+}
+
bool InspectorDOMStorageAgent::isEnabled() const
{
return m_state->getBoolean(DOMStorageAgentState::domStorageAgentEnabled);
@@ -109,8 +114,8 @@ void InspectorDOMStorageAgent::disable(ErrorString*)
void InspectorDOMStorageAgent::getDOMStorageItems(ErrorString* errorString, const RefPtr<JSONObject>& storageId, RefPtr<TypeBuilder::Array<TypeBuilder::Array<String> > >& items)
{
- Frame* frame;
- OwnPtr<StorageArea> storageArea = findStorageArea(errorString, storageId, frame);
+ LocalFrame* frame;
+ OwnPtrWillBeRawPtr<StorageArea> storageArea = findStorageArea(errorString, storageId, frame);
if (!storageArea)
return;
@@ -141,8 +146,8 @@ static String toErrorString(ExceptionState& exceptionState)
void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString* errorString, const RefPtr<JSONObject>& storageId, const String& key, const String& value)
{
- Frame* frame;
- OwnPtr<StorageArea> storageArea = findStorageArea(0, storageId, frame);
+ LocalFrame* frame;
+ OwnPtrWillBeRawPtr<StorageArea> storageArea = findStorageArea(0, storageId, frame);
if (!storageArea) {
*errorString = "Storage not found";
return;
@@ -155,8 +160,8 @@ void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString* errorString, const
void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString* errorString, const RefPtr<JSONObject>& storageId, const String& key)
{
- Frame* frame;
- OwnPtr<StorageArea> storageArea = findStorageArea(0, storageId, frame);
+ LocalFrame* frame;
+ OwnPtrWillBeRawPtr<StorageArea> storageArea = findStorageArea(0, storageId, frame);
if (!storageArea) {
*errorString = "Storage not found";
return;
@@ -167,18 +172,6 @@ void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString* errorString, co
*errorString = toErrorString(exceptionState);
}
-String InspectorDOMStorageAgent::storageId(Storage* storage)
-{
- ASSERT(storage);
- Document* document = storage->frame()->document();
- ASSERT(document);
- DOMWindow* window = document->domWindow();
- ASSERT(window);
- RefPtr<SecurityOrigin> securityOrigin = document->securityOrigin();
- bool isLocalStorage = window->optionalLocalStorage() == storage;
- return storageId(securityOrigin.get(), isLocalStorage)->toJSONString();
-}
-
PassRefPtr<TypeBuilder::DOMStorage::StorageId> InspectorDOMStorageAgent::storageId(SecurityOrigin* securityOrigin, bool isLocalStorage)
{
return TypeBuilder::DOMStorage::StorageId::create()
@@ -203,7 +196,7 @@ void InspectorDOMStorageAgent::didDispatchDOMStorageEvent(const String& key, con
m_frontend->domstorage()->domStorageItemUpdated(id, key, oldValue, newValue);
}
-PassOwnPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<JSONObject>& storageId, Frame*& targetFrame)
+PassOwnPtrWillBeRawPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<JSONObject>& storageId, LocalFrame*& targetFrame)
{
String securityOrigin;
bool isLocalStorage = false;
@@ -216,10 +209,10 @@ PassOwnPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* e
return nullptr;
}
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
+ LocalFrame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
if (!frame) {
if (errorString)
- *errorString = "Frame not found for the given security origin";
+ *errorString = "LocalFrame not found for the given security origin";
return nullptr;
}
targetFrame = frame;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.h
index 4c79cefe60e..1d213f45e33 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorDOMStorageAgent.h
@@ -36,7 +36,7 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class InspectorFrontend;
class InspectorPageAgent;
class InstrumentingAgents;
@@ -46,37 +46,35 @@ class StorageArea;
typedef String ErrorString;
-class InspectorDOMStorageAgent : public InspectorBaseAgent<InspectorDOMStorageAgent>, public InspectorBackendDispatcher::DOMStorageCommandHandler {
+class InspectorDOMStorageAgent FINAL : public InspectorBaseAgent<InspectorDOMStorageAgent>, public InspectorBackendDispatcher::DOMStorageCommandHandler {
public:
- static PassOwnPtr<InspectorDOMStorageAgent> create(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorCompositeState* state)
+ static PassOwnPtr<InspectorDOMStorageAgent> create(InspectorPageAgent* pageAgent)
{
- return adoptPtr(new InspectorDOMStorageAgent(instrumentingAgents, pageAgent, state));
+ return adoptPtr(new InspectorDOMStorageAgent(pageAgent));
}
- ~InspectorDOMStorageAgent();
+ virtual ~InspectorDOMStorageAgent();
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
// Called from the front-end.
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void getDOMStorageItems(ErrorString*, const RefPtr<JSONObject>& storageId, RefPtr<TypeBuilder::Array<TypeBuilder::Array<String> > >& items);
- virtual void setDOMStorageItem(ErrorString*, const RefPtr<JSONObject>& storageId, const String& key, const String& value);
- virtual void removeDOMStorageItem(ErrorString*, const RefPtr<JSONObject>& storageId, const String& key);
-
- // Called from the injected script.
- String storageId(Storage*);
- PassRefPtr<TypeBuilder::DOMStorage::StorageId> storageId(SecurityOrigin*, bool isLocalStorage);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void getDOMStorageItems(ErrorString*, const RefPtr<JSONObject>& storageId, RefPtr<TypeBuilder::Array<TypeBuilder::Array<String> > >& items) OVERRIDE;
+ virtual void setDOMStorageItem(ErrorString*, const RefPtr<JSONObject>& storageId, const String& key, const String& value) OVERRIDE;
+ virtual void removeDOMStorageItem(ErrorString*, const RefPtr<JSONObject>& storageId, const String& key) OVERRIDE;
// Called from InspectorInstrumentation
void didDispatchDOMStorageEvent(const String& key, const String& oldValue, const String& newValue, StorageType, SecurityOrigin*);
private:
- InspectorDOMStorageAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorCompositeState*);
+ InspectorDOMStorageAgent(InspectorPageAgent*);
bool isEnabled() const;
- PassOwnPtr<StorageArea> findStorageArea(ErrorString*, const RefPtr<JSONObject>&, Frame*&);
+ PassOwnPtrWillBeRawPtr<StorageArea> findStorageArea(ErrorString*, const RefPtr<JSONObject>&, LocalFrame*&);
+ PassRefPtr<TypeBuilder::DOMStorage::StorageId> storageId(SecurityOrigin*, bool isLocalStorage);
InspectorPageAgent* m_pageAgent;
InspectorFrontend* m_frontend;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseAgent.cpp
deleted file mode 100644
index 11960dfe0cf..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseAgent.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/inspector/InspectorDatabaseAgent.h"
-
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/inspector/InspectorDatabaseResource.h"
-#include "core/inspector/InspectorState.h"
-#include "core/inspector/InstrumentingAgents.h"
-#include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
-#include "core/html/VoidCallback.h"
-#include "core/page/Page.h"
-#include "modules/webdatabase/Database.h"
-#include "modules/webdatabase/SQLError.h"
-#include "modules/webdatabase/SQLResultSet.h"
-#include "modules/webdatabase/SQLResultSetRowList.h"
-#include "modules/webdatabase/SQLStatementCallback.h"
-#include "modules/webdatabase/SQLStatementErrorCallback.h"
-#include "modules/webdatabase/SQLTransaction.h"
-#include "modules/webdatabase/SQLTransactionCallback.h"
-#include "modules/webdatabase/SQLTransactionErrorCallback.h"
-#include "modules/webdatabase/sqlite/SQLValue.h"
-#include "platform/JSONValues.h"
-#include "wtf/Vector.h"
-
-typedef WebCore::InspectorBackendDispatcher::DatabaseCommandHandler::ExecuteSQLCallback ExecuteSQLCallback;
-
-namespace WebCore {
-
-namespace DatabaseAgentState {
-static const char databaseAgentEnabled[] = "databaseAgentEnabled";
-};
-
-namespace {
-
-void reportTransactionFailed(ExecuteSQLCallback* requestCallback, SQLError* error)
-{
- RefPtr<TypeBuilder::Database::Error> errorObject = TypeBuilder::Database::Error::create()
- .setMessage(error->message())
- .setCode(error->code());
- requestCallback->sendSuccess(0, 0, errorObject.release());
-}
-
-class StatementCallback : public SQLStatementCallback {
-public:
- static PassOwnPtr<StatementCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback)
- {
- return adoptPtr(new StatementCallback(requestCallback));
- }
-
- virtual ~StatementCallback() { }
-
- virtual bool handleEvent(SQLTransaction*, SQLResultSet* resultSet)
- {
- SQLResultSetRowList* rowList = resultSet->rows();
-
- RefPtr<TypeBuilder::Array<String> > columnNames = TypeBuilder::Array<String>::create();
- const Vector<String>& columns = rowList->columnNames();
- for (size_t i = 0; i < columns.size(); ++i)
- columnNames->addItem(columns[i]);
-
- RefPtr<TypeBuilder::Array<JSONValue> > values = TypeBuilder::Array<JSONValue>::create();
- const Vector<SQLValue>& data = rowList->values();
- for (size_t i = 0; i < data.size(); ++i) {
- const SQLValue& value = rowList->values()[i];
- switch (value.type()) {
- case SQLValue::StringValue: values->addItem(JSONString::create(value.string())); break;
- case SQLValue::NumberValue: values->addItem(JSONBasicValue::create(value.number())); break;
- case SQLValue::NullValue: values->addItem(JSONValue::null()); break;
- }
- }
- m_requestCallback->sendSuccess(columnNames.release(), values.release(), 0);
- return true;
- }
-
-private:
- StatementCallback(PassRefPtr<ExecuteSQLCallback> requestCallback)
- : m_requestCallback(requestCallback) { }
- RefPtr<ExecuteSQLCallback> m_requestCallback;
-};
-
-class StatementErrorCallback : public SQLStatementErrorCallback {
-public:
- static PassOwnPtr<StatementErrorCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback)
- {
- return adoptPtr(new StatementErrorCallback(requestCallback));
- }
-
- virtual ~StatementErrorCallback() { }
-
- virtual bool handleEvent(SQLTransaction*, SQLError* error)
- {
- reportTransactionFailed(m_requestCallback.get(), error);
- return true;
- }
-
-private:
- StatementErrorCallback(PassRefPtr<ExecuteSQLCallback> requestCallback)
- : m_requestCallback(requestCallback) { }
- RefPtr<ExecuteSQLCallback> m_requestCallback;
-};
-
-class TransactionCallback : public SQLTransactionCallback {
-public:
- static PassOwnPtr<TransactionCallback> create(const String& sqlStatement, PassRefPtr<ExecuteSQLCallback> requestCallback)
- {
- return adoptPtr(new TransactionCallback(sqlStatement, requestCallback));
- }
-
- virtual ~TransactionCallback() { }
-
- virtual bool handleEvent(SQLTransaction* transaction)
- {
- if (!m_requestCallback->isActive())
- return true;
-
- Vector<SQLValue> sqlValues;
- OwnPtr<SQLStatementCallback> callback(StatementCallback::create(m_requestCallback.get()));
- OwnPtr<SQLStatementErrorCallback> errorCallback(StatementErrorCallback::create(m_requestCallback.get()));
- transaction->executeSQL(m_sqlStatement, sqlValues, callback.release(), errorCallback.release(), IGNORE_EXCEPTION);
- return true;
- }
-private:
- TransactionCallback(const String& sqlStatement, PassRefPtr<ExecuteSQLCallback> requestCallback)
- : m_sqlStatement(sqlStatement)
- , m_requestCallback(requestCallback) { }
- String m_sqlStatement;
- RefPtr<ExecuteSQLCallback> m_requestCallback;
-};
-
-class TransactionErrorCallback : public SQLTransactionErrorCallback {
-public:
- static PassOwnPtr<TransactionErrorCallback> create(PassRefPtr<ExecuteSQLCallback> requestCallback)
- {
- return adoptPtr(new TransactionErrorCallback(requestCallback));
- }
-
- virtual ~TransactionErrorCallback() { }
-
- virtual bool handleEvent(SQLError* error)
- {
- reportTransactionFailed(m_requestCallback.get(), error);
- return true;
- }
-private:
- TransactionErrorCallback(PassRefPtr<ExecuteSQLCallback> requestCallback)
- : m_requestCallback(requestCallback) { }
- RefPtr<ExecuteSQLCallback> m_requestCallback;
-};
-
-class TransactionSuccessCallback : public VoidCallback {
-public:
- static PassOwnPtr<TransactionSuccessCallback> create()
- {
- return adoptPtr(new TransactionSuccessCallback());
- }
-
- virtual ~TransactionSuccessCallback() { }
-
- virtual void handleEvent() { }
-
-private:
- TransactionSuccessCallback() { }
-};
-
-} // namespace
-
-void InspectorDatabaseAgent::didOpenDatabase(PassRefPtr<Database> database, const String& domain, const String& name, const String& version)
-{
- if (InspectorDatabaseResource* resource = findByFileName(database->fileName())) {
- resource->setDatabase(database);
- return;
- }
-
- RefPtr<InspectorDatabaseResource> resource = InspectorDatabaseResource::create(database, domain, name, version);
- m_resources.set(resource->id(), resource);
- // Resources are only bound while visible.
- if (m_frontend && m_enabled)
- resource->bind(m_frontend);
-}
-
-void InspectorDatabaseAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
-{
- // FIXME: If "frame" is always guarenteed to be in the same Page as loader->frame()
- // then all we need to check here is loader->frame()->isMainFrame()
- // and we don't need "frame" at all.
- if (loader->frame() != frame->page()->mainFrame())
- return;
-
- m_resources.clear();
-}
-
-InspectorDatabaseAgent::InspectorDatabaseAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state)
- : InspectorBaseAgent<InspectorDatabaseAgent>("Database", instrumentingAgents, state)
- , m_frontend(0)
- , m_enabled(false)
-{
- m_instrumentingAgents->setInspectorDatabaseAgent(this);
-}
-
-InspectorDatabaseAgent::~InspectorDatabaseAgent()
-{
- m_instrumentingAgents->setInspectorDatabaseAgent(0);
-}
-
-void InspectorDatabaseAgent::setFrontend(InspectorFrontend* frontend)
-{
- m_frontend = frontend->database();
-}
-
-void InspectorDatabaseAgent::clearFrontend()
-{
- m_frontend = 0;
- disable(0);
-}
-
-void InspectorDatabaseAgent::enable(ErrorString*)
-{
- if (m_enabled)
- return;
- m_enabled = true;
- m_state->setBoolean(DatabaseAgentState::databaseAgentEnabled, m_enabled);
-
- DatabaseResourcesMap::iterator databasesEnd = m_resources.end();
- for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != databasesEnd; ++it)
- it->value->bind(m_frontend);
-}
-
-void InspectorDatabaseAgent::disable(ErrorString*)
-{
- if (!m_enabled)
- return;
- m_enabled = false;
- m_state->setBoolean(DatabaseAgentState::databaseAgentEnabled, m_enabled);
-}
-
-void InspectorDatabaseAgent::restore()
-{
- m_enabled = m_state->getBoolean(DatabaseAgentState::databaseAgentEnabled);
-}
-
-void InspectorDatabaseAgent::getDatabaseTableNames(ErrorString* error, const String& databaseId, RefPtr<TypeBuilder::Array<String> >& names)
-{
- if (!m_enabled) {
- *error = "Database agent is not enabled";
- return;
- }
-
- names = TypeBuilder::Array<String>::create();
-
- Database* database = databaseForId(databaseId);
- if (database) {
- Vector<String> tableNames = database->tableNames();
- unsigned length = tableNames.size();
- for (unsigned i = 0; i < length; ++i)
- names->addItem(tableNames[i]);
- }
-}
-
-void InspectorDatabaseAgent::executeSQL(ErrorString*, const String& databaseId, const String& query, PassRefPtr<ExecuteSQLCallback> prpRequestCallback)
-{
- RefPtr<ExecuteSQLCallback> requestCallback = prpRequestCallback;
-
- if (!m_enabled) {
- requestCallback->sendFailure("Database agent is not enabled");
- return;
- }
-
- Database* database = databaseForId(databaseId);
- if (!database) {
- requestCallback->sendFailure("Database not found");
- return;
- }
-
- OwnPtr<SQLTransactionCallback> callback(TransactionCallback::create(query, requestCallback.get()));
- OwnPtr<SQLTransactionErrorCallback> errorCallback(TransactionErrorCallback::create(requestCallback.get()));
- OwnPtr<VoidCallback> successCallback(TransactionSuccessCallback::create());
- database->transaction(callback.release(), errorCallback.release(), successCallback.release());
-}
-
-String InspectorDatabaseAgent::databaseId(Database* database)
-{
- for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) {
- if (it->value->database() == database)
- return it->key;
- }
- return String();
-}
-
-InspectorDatabaseResource* InspectorDatabaseAgent::findByFileName(const String& fileName)
-{
- for (DatabaseResourcesMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) {
- if (it->value->database()->fileName() == fileName)
- return it->value.get();
- }
- return 0;
-}
-
-Database* InspectorDatabaseAgent::databaseForId(const String& databaseId)
-{
- DatabaseResourcesMap::iterator it = m_resources.find(databaseId);
- if (it == m_resources.end())
- return 0;
- return it->value->database();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseAgent.h
deleted file mode 100644
index 1a937f9c7af..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseAgent.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorDatabaseAgent_h
-#define InspectorDatabaseAgent_h
-
-#include "InspectorFrontend.h"
-#include "core/inspector/InspectorBaseAgent.h"
-#include "wtf/HashMap.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class Database;
-class DocumentLoader;
-class Frame;
-class InspectorDatabaseResource;
-class InspectorFrontend;
-class InstrumentingAgents;
-
-typedef String ErrorString;
-
-class InspectorDatabaseAgent : public InspectorBaseAgent<InspectorDatabaseAgent>, public InspectorBackendDispatcher::DatabaseCommandHandler {
-public:
- static PassOwnPtr<InspectorDatabaseAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state)
- {
- return adoptPtr(new InspectorDatabaseAgent(instrumentingAgents, state));
- }
- ~InspectorDatabaseAgent();
-
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
-
- void didCommitLoad(Frame*, DocumentLoader*);
-
- // Called from the front-end.
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void getDatabaseTableNames(ErrorString*, const String& databaseId, RefPtr<TypeBuilder::Array<String> >& names);
- virtual void executeSQL(ErrorString*, const String& databaseId, const String& query, PassRefPtr<ExecuteSQLCallback>);
-
- // Called from the injected script.
- String databaseId(Database*);
-
- void didOpenDatabase(PassRefPtr<Database>, const String& domain, const String& name, const String& version);
-private:
- explicit InspectorDatabaseAgent(InstrumentingAgents*, InspectorCompositeState*);
-
- Database* databaseForId(const String& databaseId);
- InspectorDatabaseResource* findByFileName(const String& fileName);
-
- InspectorFrontend::Database* m_frontend;
- typedef HashMap<String, RefPtr<InspectorDatabaseResource> > DatabaseResourcesMap;
- DatabaseResourcesMap m_resources;
- bool m_enabled;
-};
-
-} // namespace WebCore
-
-#endif // !defined(InspectorDatabaseAgent_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseInstrumentation.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseInstrumentation.h
deleted file mode 100644
index 859cc6c5c0b..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseInstrumentation.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "InspectorDatabaseInstrumentationInl.h"
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseResource.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseResource.cpp
deleted file mode 100644
index d2196a062ab..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseResource.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/inspector/InspectorDatabaseResource.h"
-
-#include "modules/webdatabase/Database.h"
-
-namespace WebCore {
-
-static int nextUnusedId = 1;
-
-PassRefPtr<InspectorDatabaseResource> InspectorDatabaseResource::create(PassRefPtr<Database> database, const String& domain, const String& name, const String& version)
-{
- return adoptRef(new InspectorDatabaseResource(database, domain, name, version));
-}
-
-InspectorDatabaseResource::InspectorDatabaseResource(PassRefPtr<Database> database, const String& domain, const String& name, const String& version)
- : m_database(database)
- , m_id(String::number(nextUnusedId++))
- , m_domain(domain)
- , m_name(name)
- , m_version(version)
-{
-}
-
-void InspectorDatabaseResource::bind(InspectorFrontend::Database* frontend)
-{
- RefPtr<TypeBuilder::Database::Database> jsonObject = TypeBuilder::Database::Database::create()
- .setId(m_id)
- .setDomain(m_domain)
- .setName(m_name)
- .setVersion(m_version);
- frontend->addDatabase(jsonObject);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseResource.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseResource.h
deleted file mode 100644
index 24c1fd81da6..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDatabaseResource.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorDatabaseResource_h
-#define InspectorDatabaseResource_h
-
-#include "InspectorFrontend.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-class Database;
-class InspectorFrontend;
-
-class InspectorDatabaseResource : public RefCounted<InspectorDatabaseResource> {
-public:
- static PassRefPtr<InspectorDatabaseResource> create(PassRefPtr<Database> database, const String& domain, const String& name, const String& version);
-
- void bind(InspectorFrontend::Database*);
- Database* database() { return m_database.get(); }
- void setDatabase(PassRefPtr<Database> database) { m_database = database; }
- String id() const { return m_id; }
-
-private:
- InspectorDatabaseResource(PassRefPtr<Database>, const String& domain, const String& name, const String& version);
-
- RefPtr<Database> m_database;
- String m_id;
- String m_domain;
- String m_name;
- String m_version;
-};
-
-} // namespace WebCore
-
-#endif // InspectorDatabaseResource_h
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp
index aceaae4e39a..85423407fde 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2010-2011 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,9 +32,9 @@
#include "core/inspector/JavaScriptCallFrame.h"
#include "bindings/v8/ScriptDebugServer.h"
-#include "bindings/v8/ScriptObject.h"
#include "bindings/v8/ScriptRegexp.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "bindings/v8/ScriptValue.h"
#include "core/dom/Document.h"
#include "core/fetch/Resource.h"
#include "core/inspector/ContentSearchUtils.h"
@@ -50,6 +50,7 @@
using WebCore::TypeBuilder::Array;
using WebCore::TypeBuilder::Debugger::BreakpointId;
using WebCore::TypeBuilder::Debugger::CallFrame;
+using WebCore::TypeBuilder::Debugger::ExceptionDetails;
using WebCore::TypeBuilder::Debugger::FunctionDetails;
using WebCore::TypeBuilder::Debugger::ScriptId;
using WebCore::TypeBuilder::Debugger::StackTrace;
@@ -76,7 +77,7 @@ static const char skipAllPausesExpiresOnReload[] = "skipAllPausesExpiresOnReload
};
-static const int numberOfStepsBeforeStepOut = 10;
+static const int maxSkipStepInCount = 20;
const char InspectorDebuggerAgent::backtraceObjectGroup[] = "backtrace";
@@ -98,19 +99,18 @@ static String generateBreakpointId(const String& scriptId, int lineNumber, int c
return scriptId + ':' + String::number(lineNumber) + ':' + String::number(columnNumber) + breakpointIdSuffix(source);
}
-InspectorDebuggerAgent::InspectorDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager)
- : InspectorBaseAgent<InspectorDebuggerAgent>("Debugger", instrumentingAgents, inspectorState)
+InspectorDebuggerAgent::InspectorDebuggerAgent(InjectedScriptManager* injectedScriptManager)
+ : InspectorBaseAgent<InspectorDebuggerAgent>("Debugger")
, m_injectedScriptManager(injectedScriptManager)
, m_frontend(0)
- , m_pausedScriptState(0)
+ , m_pausedScriptState(nullptr)
, m_javaScriptPauseScheduled(false)
+ , m_debuggerStepScheduled(false)
+ , m_pausingOnNativeEvent(false)
, m_listener(0)
- , m_skipStepInCount(numberOfStepsBeforeStepOut)
+ , m_skippedStepInCount(0)
, m_skipAllPauses(false)
{
- // FIXME: make breakReason optional so that there was no need to init it with "other".
- clearBreakDetails();
- m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, ScriptDebugServer::DontPauseOnExceptions);
}
InspectorDebuggerAgent::~InspectorDebuggerAgent()
@@ -118,13 +118,20 @@ InspectorDebuggerAgent::~InspectorDebuggerAgent()
ASSERT(!m_instrumentingAgents->inspectorDebuggerAgent());
}
+void InspectorDebuggerAgent::init()
+{
+ // FIXME: make breakReason optional so that there was no need to init it with "other".
+ clearBreakDetails();
+ m_state->setLong(DebuggerAgentState::pauseOnExceptionsState, ScriptDebugServer::DontPauseOnExceptions);
+}
+
void InspectorDebuggerAgent::enable()
{
m_instrumentingAgents->setInspectorDebuggerAgent(this);
+ startListeningScriptDebugServer();
// FIXME(WK44513): breakpoints activated flag should be synchronized between all front-ends
scriptDebugServer().setBreakpointsActivated(true);
- startListeningScriptDebugServer();
if (m_listener)
m_listener->debuggerWasEnabled();
@@ -138,9 +145,9 @@ void InspectorDebuggerAgent::disable()
m_state->setLong(DebuggerAgentState::asyncCallStackDepth, 0);
m_instrumentingAgents->setInspectorDebuggerAgent(0);
- stopListeningScriptDebugServer();
scriptDebugServer().clearBreakpoints();
scriptDebugServer().clearCompiledScripts();
+ stopListeningScriptDebugServer();
clear();
if (m_listener)
@@ -256,25 +263,25 @@ bool InspectorDebuggerAgent::runningNestedMessageLoop()
void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type)
{
if (source == ConsoleAPIMessageSource && type == AssertMessageType && scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontPauseOnExceptions)
- breakProgram(InspectorFrontend::Debugger::Reason::Assert, 0);
+ breakProgram(InspectorFrontend::Debugger::Reason::Assert, nullptr);
}
-void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel, const String&, PassRefPtr<ScriptCallStack>, unsigned long)
+void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel, const String&, PassRefPtrWillBeRawPtr<ScriptCallStack>, unsigned long)
{
addMessageToConsole(source, type);
}
-void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel, const String&, ScriptState*, PassRefPtr<ScriptArguments>, unsigned long)
+void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel, const String&, ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>, unsigned long)
{
addMessageToConsole(source, type);
}
-String InspectorDebuggerAgent::preprocessEventListener(Frame* frame, const String& source, const String& url, const String& functionName)
+String InspectorDebuggerAgent::preprocessEventListener(LocalFrame* frame, const String& source, const String& url, const String& functionName)
{
return scriptDebugServer().preprocessEventListener(frame, source, url, functionName);
}
-PassOwnPtr<ScriptSourceCode> InspectorDebuggerAgent::preprocess(Frame* frame, const ScriptSourceCode& sourceCode)
+PassOwnPtr<ScriptSourceCode> InspectorDebuggerAgent::preprocess(LocalFrame* frame, const ScriptSourceCode& sourceCode)
{
return scriptDebugServer().preprocess(frame, sourceCode);
}
@@ -434,12 +441,12 @@ void InspectorDebuggerAgent::continueToLocation(ErrorString* errorString, const
void InspectorDebuggerAgent::getStepInPositions(ErrorString* errorString, const String& callFrameId, RefPtr<Array<TypeBuilder::Debugger::Location> >& positions)
{
- if (!isPaused() || m_currentCallStack.hasNoValue()) {
+ if (!isPaused() || m_currentCallStack.isEmpty()) {
*errorString = "Attempt to access callframe when debugger is not on pause";
return;
}
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return;
}
@@ -465,10 +472,11 @@ String InspectorDebuggerAgent::scriptURL(JavaScriptCallFrame* frame)
return it->value.url;
}
-ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptionPause(RefPtr<JavaScriptCallFrame>& topFrame)
+ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptionPause()
{
- if (m_skipAllPauses)
- return ScriptDebugListener::Continue;
+ // FIXME: Fast return: if (!m_cachedSkipStackRegExp && !has_any_anti_breakpoint) return ScriptDebugListener::NoSkip;
+
+ RefPtrWillBeRawPtr<JavaScriptCallFrame> topFrame = scriptDebugServer().topCallFrameNoScopes();
if (!topFrame)
return ScriptDebugListener::NoSkip;
@@ -516,56 +524,60 @@ ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipExceptio
return ScriptDebugListener::NoSkip;
}
-ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipBreakpointPause(RefPtr<JavaScriptCallFrame>& topFrame)
+ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPause()
{
- if (m_skipAllPauses)
- return ScriptDebugListener::Continue;
- if (!topFrame)
+ if (!m_cachedSkipStackRegExp)
return ScriptDebugListener::NoSkip;
- return ScriptDebugListener::NoSkip;
-}
-ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::shouldSkipStepPause(RefPtr<JavaScriptCallFrame>& topFrame)
-{
- if (m_skipAllPauses)
- return ScriptDebugListener::Continue;
- if (!topFrame)
+ RefPtrWillBeRawPtr<JavaScriptCallFrame> topFrame = scriptDebugServer().topCallFrameNoScopes();
+ String scriptUrl = scriptURL(topFrame.get());
+ if (scriptUrl.isEmpty() || m_cachedSkipStackRegExp->match(scriptUrl) == -1)
return ScriptDebugListener::NoSkip;
- if (m_cachedSkipStackRegExp) {
- String scriptUrl = scriptURL(topFrame.get());
- if (!scriptUrl.isEmpty() && m_cachedSkipStackRegExp->match(scriptUrl) != -1) {
- if (m_skipStepInCount > 0) {
- --m_skipStepInCount;
- return ScriptDebugListener::StepInto;
- }
- return ScriptDebugListener::StepOut;
+ if (m_skippedStepInCount == 0) {
+ m_minFrameCountForSkip = scriptDebugServer().frameCount();
+ m_skippedStepInCount = 1;
+ return ScriptDebugListener::StepInto;
+ }
+
+ if (m_skippedStepInCount < maxSkipStepInCount && topFrame->isAtReturn() && scriptDebugServer().frameCount() <= m_minFrameCountForSkip)
+ m_skippedStepInCount = maxSkipStepInCount;
+
+ if (m_skippedStepInCount >= maxSkipStepInCount) {
+ if (m_pausingOnNativeEvent) {
+ m_pausingOnNativeEvent = false;
+ m_skippedStepInCount = 0;
+ return ScriptDebugListener::Continue;
}
+ return ScriptDebugListener::StepOut;
}
- return ScriptDebugListener::NoSkip;
+
+ ++m_skippedStepInCount;
+ return ScriptDebugListener::StepInto;
}
PassRefPtr<TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint& breakpoint, BreakpointSource source)
{
ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
if (scriptIterator == m_scripts.end())
- return 0;
+ return nullptr;
Script& script = scriptIterator->value;
if (breakpoint.lineNumber < script.startLine || script.endLine < breakpoint.lineNumber)
- return 0;
+ return nullptr;
int actualLineNumber;
int actualColumnNumber;
String debugServerBreakpointId = scriptDebugServer().setBreakpoint(scriptId, breakpoint, &actualLineNumber, &actualColumnNumber, false);
if (debugServerBreakpointId.isEmpty())
- return 0;
+ return nullptr;
m_serverBreakpoints.set(debugServerBreakpointId, std::make_pair(breakpointId, source));
BreakpointIdToDebugServerBreakpointIdsMap::iterator debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.find(breakpointId);
if (debugServerBreakpointIdsIterator == m_breakpointIdToDebugServerBreakpointIds.end())
- debugServerBreakpointIdsIterator = m_breakpointIdToDebugServerBreakpointIds.set(breakpointId, Vector<String>()).iterator;
- debugServerBreakpointIdsIterator->value.append(debugServerBreakpointId);
+ m_breakpointIdToDebugServerBreakpointIds.set(breakpointId, Vector<String>()).storedValue->value.append(debugServerBreakpointId);
+ else
+ debugServerBreakpointIdsIterator->value.append(debugServerBreakpointId);
RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
.setScriptId(scriptId)
@@ -574,16 +586,6 @@ PassRefPtr<TypeBuilder::Debugger::Location> InspectorDebuggerAgent::resolveBreak
return location;
}
-static PassRefPtr<JSONObject> scriptToInspectorObject(ScriptObject scriptObject)
-{
- if (scriptObject.hasNoValue())
- return 0;
- RefPtr<JSONValue> value = scriptObject.toJSONValue(scriptObject.scriptState());
- if (!value)
- return 0;
- return value->asObject();
-}
-
void InspectorDebuggerAgent::searchInContent(ErrorString* error, const String& scriptId, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<Array<WebCore::TypeBuilder::Page::SearchMatch> >& results)
{
bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
@@ -599,24 +601,20 @@ void InspectorDebuggerAgent::searchInContent(ErrorString* error, const String& s
void InspectorDebuggerAgent::setScriptSource(ErrorString* error, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>& errorData, const String& scriptId, const String& newContent, const bool* const preview, RefPtr<Array<CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<StackTrace>& asyncStackTrace)
{
bool previewOnly = preview && *preview;
- ScriptObject resultObject;
- if (!scriptDebugServer().setScriptSource(scriptId, newContent, previewOnly, error, errorData, &m_currentCallStack, &resultObject))
+ if (!scriptDebugServer().setScriptSource(scriptId, newContent, previewOnly, error, errorData, &m_currentCallStack, &result))
return;
newCallFrames = currentCallFrames();
asyncStackTrace = currentAsyncStackTrace();
- RefPtr<JSONObject> object = scriptToInspectorObject(resultObject);
- if (object)
- result = object;
}
void InspectorDebuggerAgent::restartFrame(ErrorString* errorString, const String& callFrameId, RefPtr<Array<CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<StackTrace>& asyncStackTrace)
{
- if (!isPaused() || m_currentCallStack.hasNoValue()) {
+ if (!isPaused() || m_currentCallStack.isEmpty()) {
*errorString = "Attempt to access callframe when debugger is not on pause";
return;
}
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return;
}
@@ -639,7 +637,7 @@ void InspectorDebuggerAgent::getScriptSource(ErrorString* error, const String& s
void InspectorDebuggerAgent::getFunctionDetails(ErrorString* errorString, const String& functionId, RefPtr<FunctionDetails>& details)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(functionId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Function object id is obsolete";
return;
}
@@ -648,134 +646,174 @@ void InspectorDebuggerAgent::getFunctionDetails(ErrorString* errorString, const
void InspectorDebuggerAgent::schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data)
{
- if (m_javaScriptPauseScheduled)
+ if (m_javaScriptPauseScheduled || isPaused())
return;
m_breakReason = breakReason;
m_breakAuxData = data;
+ m_pausingOnNativeEvent = true;
scriptDebugServer().setPauseOnNextStatement(true);
}
void InspectorDebuggerAgent::cancelPauseOnNextStatement()
{
- if (m_javaScriptPauseScheduled)
+ if (m_javaScriptPauseScheduled || isPaused())
return;
clearBreakDetails();
+ m_pausingOnNativeEvent = false;
scriptDebugServer().setPauseOnNextStatement(false);
}
void InspectorDebuggerAgent::didInstallTimer(ExecutionContext* context, int timerId, int timeout, bool singleShot)
{
if (m_asyncCallStackTracker.isEnabled())
- m_asyncCallStackTracker.didInstallTimer(context, timerId, singleShot, scriptDebugServer().currentCallFrames());
+ m_asyncCallStackTracker.didInstallTimer(context, timerId, singleShot, scriptDebugServer().currentCallFramesForAsyncStack());
}
void InspectorDebuggerAgent::didRemoveTimer(ExecutionContext* context, int timerId)
{
- m_asyncCallStackTracker.didRemoveTimer(context, timerId);
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didRemoveTimer(context, timerId);
}
bool InspectorDebuggerAgent::willFireTimer(ExecutionContext* context, int timerId)
{
- m_asyncCallStackTracker.willFireTimer(context, timerId);
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.willFireTimer(context, timerId);
return true;
}
void InspectorDebuggerAgent::didFireTimer()
{
- m_asyncCallStackTracker.didFireAsyncCall();
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didFireAsyncCall();
cancelPauseOnNextStatement();
}
void InspectorDebuggerAgent::didRequestAnimationFrame(Document* document, int callbackId)
{
if (m_asyncCallStackTracker.isEnabled())
- m_asyncCallStackTracker.didRequestAnimationFrame(document, callbackId, scriptDebugServer().currentCallFrames());
+ m_asyncCallStackTracker.didRequestAnimationFrame(document, callbackId, scriptDebugServer().currentCallFramesForAsyncStack());
}
void InspectorDebuggerAgent::didCancelAnimationFrame(Document* document, int callbackId)
{
- m_asyncCallStackTracker.didCancelAnimationFrame(document, callbackId);
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didCancelAnimationFrame(document, callbackId);
}
bool InspectorDebuggerAgent::willFireAnimationFrame(Document* document, int callbackId)
{
- m_asyncCallStackTracker.willFireAnimationFrame(document, callbackId);
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.willFireAnimationFrame(document, callbackId);
return true;
}
void InspectorDebuggerAgent::didFireAnimationFrame()
{
- m_asyncCallStackTracker.didFireAsyncCall();
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didFireAsyncCall();
+}
+
+void InspectorDebuggerAgent::didEnqueueEvent(EventTarget* eventTarget, Event* event)
+{
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didEnqueueEvent(eventTarget, event, scriptDebugServer().currentCallFramesForAsyncStack());
+}
+
+void InspectorDebuggerAgent::didRemoveEvent(EventTarget* eventTarget, Event* event)
+{
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didRemoveEvent(eventTarget, event);
+}
+
+void InspectorDebuggerAgent::willHandleEvent(EventTarget* eventTarget, Event* event, EventListener* listener, bool useCapture)
+{
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.willHandleEvent(eventTarget, event, listener, useCapture);
}
void InspectorDebuggerAgent::didHandleEvent()
{
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didFireAsyncCall();
cancelPauseOnNextStatement();
}
+void InspectorDebuggerAgent::willLoadXHR(XMLHttpRequest* xhr, ThreadableLoaderClient*, const AtomicString&, const KURL&, bool async, FormData*, const HTTPHeaderMap&, bool)
+{
+ if (m_asyncCallStackTracker.isEnabled() && async)
+ m_asyncCallStackTracker.willLoadXHR(xhr, scriptDebugServer().currentCallFramesForAsyncStack());
+}
+
+void InspectorDebuggerAgent::didEnqueueMutationRecord(ExecutionContext* context, MutationObserver* observer)
+{
+ if (m_asyncCallStackTracker.isEnabled() && !m_asyncCallStackTracker.hasEnqueuedMutationRecord(context, observer))
+ m_asyncCallStackTracker.didEnqueueMutationRecord(context, observer, scriptDebugServer().currentCallFramesForAsyncStack());
+}
+
+void InspectorDebuggerAgent::didClearAllMutationRecords(ExecutionContext* context, MutationObserver* observer)
+{
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didClearAllMutationRecords(context, observer);
+}
+
+void InspectorDebuggerAgent::willDeliverMutationRecords(ExecutionContext* context, MutationObserver* observer)
+{
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.willDeliverMutationRecords(context, observer);
+}
+
+void InspectorDebuggerAgent::didDeliverMutationRecords()
+{
+ if (m_asyncCallStackTracker.isEnabled())
+ m_asyncCallStackTracker.didFireAsyncCall();
+}
+
void InspectorDebuggerAgent::pause(ErrorString*)
{
- if (m_javaScriptPauseScheduled)
+ if (m_javaScriptPauseScheduled || isPaused())
return;
clearBreakDetails();
- scriptDebugServer().setPauseOnNextStatement(true);
m_javaScriptPauseScheduled = true;
+ scriptDebugServer().setPauseOnNextStatement(true);
}
void InspectorDebuggerAgent::resume(ErrorString* errorString)
{
if (!assertPaused(errorString))
return;
+ m_debuggerStepScheduled = false;
m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
scriptDebugServer().continueProgram();
}
-ScriptValue InspectorDebuggerAgent::resolveCallFrame(ErrorString* errorString, const String* callFrameId)
-{
- if (!callFrameId)
- return ScriptValue();
- if (!isPaused() || m_currentCallStack.hasNoValue()) {
- *errorString = "Attempt to access callframe when debugger is not on pause";
- return ScriptValue();
- }
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*callFrameId);
- if (injectedScript.hasNoValue()) {
- *errorString = "Inspected frame has gone";
- return ScriptValue();
- }
- return injectedScript.findCallFrameById(errorString, m_currentCallStack, *callFrameId);
-}
-
-void InspectorDebuggerAgent::stepOver(ErrorString* errorString, const String* callFrameId)
+void InspectorDebuggerAgent::stepOver(ErrorString* errorString)
{
if (!assertPaused(errorString))
return;
- ScriptValue frame = resolveCallFrame(errorString, callFrameId);
- if (!errorString->isEmpty())
- return;
+ m_debuggerStepScheduled = true;
m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
- scriptDebugServer().stepOverStatement(frame);
+ scriptDebugServer().stepOverStatement();
}
void InspectorDebuggerAgent::stepInto(ErrorString* errorString)
{
if (!assertPaused(errorString))
return;
+ m_debuggerStepScheduled = true;
m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
scriptDebugServer().stepIntoStatement();
if (m_listener)
m_listener->stepInto();
}
-void InspectorDebuggerAgent::stepOut(ErrorString* errorString, const String* callFrameId)
+void InspectorDebuggerAgent::stepOut(ErrorString* errorString)
{
if (!assertPaused(errorString))
return;
- ScriptValue frame = resolveCallFrame(errorString, callFrameId);
- if (!errorString->isEmpty())
- return;
+ m_debuggerStepScheduled = true;
m_injectedScriptManager->releaseObjectGroup(InspectorDebuggerAgent::backtraceObjectGroup);
- scriptDebugServer().stepOutOfFunction(frame);
+ scriptDebugServer().stepOutOfFunction();
}
void InspectorDebuggerAgent::setPauseOnExceptions(ErrorString* errorString, const String& stringPauseState)
@@ -805,12 +843,12 @@ void InspectorDebuggerAgent::setPauseOnExceptionsImpl(ErrorString* errorString,
void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const String& callFrameId, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
{
- if (!isPaused() || m_currentCallStack.hasNoValue()) {
+ if (!isPaused() || m_currentCallStack.isEmpty()) {
*errorString = "Attempt to access callframe when debugger is not on pause";
return;
}
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(callFrameId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return;
}
@@ -822,7 +860,17 @@ void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const
muteConsole();
}
- injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, returnByValue ? *returnByValue : false, generatePreview ? *generatePreview : false, &result, wasThrown);
+ Vector<ScriptValue> asyncCallStacks;
+ const AsyncCallStackTracker::AsyncCallChain* asyncChain = m_asyncCallStackTracker.isEnabled() ? m_asyncCallStackTracker.currentAsyncCallChain() : 0;
+ if (asyncChain) {
+ const AsyncCallStackTracker::AsyncCallStackVector& callStacks = asyncChain->callStacks();
+ asyncCallStacks.resize(callStacks.size());
+ AsyncCallStackTracker::AsyncCallStackVector::const_iterator it = callStacks.begin();
+ for (size_t i = 0; it != callStacks.end(); ++it, ++i)
+ asyncCallStacks[i] = (*it)->callFrames();
+ }
+
+ injectedScript.evaluateOnCallFrame(errorString, m_currentCallStack, asyncCallStacks, callFrameId, expression, objectGroup ? *objectGroup : "", includeCommandLineAPI ? *includeCommandLineAPI : false, returnByValue ? *returnByValue : false, generatePreview ? *generatePreview : false, &result, wasThrown);
if (doNotPauseOnExceptionsAndMuteConsole ? *doNotPauseOnExceptionsAndMuteConsole : false) {
unmuteConsole();
@@ -831,29 +879,39 @@ void InspectorDebuggerAgent::evaluateOnCallFrame(ErrorString* errorString, const
}
}
-void InspectorDebuggerAgent::compileScript(ErrorString* errorString, const String& expression, const String& sourceURL, TypeBuilder::OptOutput<ScriptId>* scriptId, TypeBuilder::OptOutput<String>* syntaxErrorMessage)
+void InspectorDebuggerAgent::compileScript(ErrorString* errorString, const String& expression, const String& sourceURL, const int* executionContextId, TypeBuilder::OptOutput<ScriptId>* scriptId, RefPtr<ExceptionDetails>& exceptionDetails)
{
- InjectedScript injectedScript = injectedScriptForEval(errorString, 0);
- if (injectedScript.hasNoValue()) {
+ InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return;
}
String scriptIdValue;
- String exceptionMessage;
- scriptDebugServer().compileScript(injectedScript.scriptState(), expression, sourceURL, &scriptIdValue, &exceptionMessage);
- if (!scriptIdValue && !exceptionMessage) {
+ String exceptionDetailsText;
+ int lineNumberValue = 0;
+ int columnNumberValue = 0;
+ RefPtrWillBeRawPtr<ScriptCallStack> stackTraceValue;
+ scriptDebugServer().compileScript(injectedScript.scriptState(), expression, sourceURL, &scriptIdValue, &exceptionDetailsText, &lineNumberValue, &columnNumberValue, &stackTraceValue);
+ if (!scriptIdValue && !exceptionDetailsText) {
*errorString = "Script compilation failed";
return;
}
- *syntaxErrorMessage = exceptionMessage;
*scriptId = scriptIdValue;
+ if (!scriptIdValue.isEmpty())
+ return;
+
+ exceptionDetails = ExceptionDetails::create().setText(exceptionDetailsText);
+ exceptionDetails->setLine(lineNumberValue);
+ exceptionDetails->setColumn(columnNumberValue);
+ if (stackTraceValue && stackTraceValue->size() > 0)
+ exceptionDetails->setStackTrace(stackTraceValue->buildInspectorArray());
}
-void InspectorDebuggerAgent::runScript(ErrorString* errorString, const ScriptId& scriptId, const int* executionContextId, const String* const objectGroup, const bool* const doNotPauseOnExceptionsAndMuteConsole, RefPtr<RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
+void InspectorDebuggerAgent::runScript(ErrorString* errorString, const ScriptId& scriptId, const int* executionContextId, const String* const objectGroup, const bool* const doNotPauseOnExceptionsAndMuteConsole, RefPtr<RemoteObject>& result, RefPtr<ExceptionDetails>& exceptionDetails)
{
InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return;
}
@@ -867,16 +925,23 @@ void InspectorDebuggerAgent::runScript(ErrorString* errorString, const ScriptId&
ScriptValue value;
bool wasThrownValue;
- String exceptionMessage;
- scriptDebugServer().runScript(injectedScript.scriptState(), scriptId, &value, &wasThrownValue, &exceptionMessage);
- *wasThrown = wasThrownValue;
- if (value.hasNoValue()) {
+ String exceptionDetailsText;
+ int lineNumberValue = 0;
+ int columnNumberValue = 0;
+ RefPtrWillBeRawPtr<ScriptCallStack> stackTraceValue;
+ scriptDebugServer().runScript(injectedScript.scriptState(), scriptId, &value, &wasThrownValue, &exceptionDetailsText, &lineNumberValue, &columnNumberValue, &stackTraceValue);
+ if (value.isEmpty()) {
*errorString = "Script execution failed";
return;
}
result = injectedScript.wrapObject(value, objectGroup ? *objectGroup : "");
- if (wasThrownValue)
- result->setDescription(exceptionMessage);
+ if (wasThrownValue) {
+ exceptionDetails = ExceptionDetails::create().setText(exceptionDetailsText);
+ exceptionDetails->setLine(lineNumberValue);
+ exceptionDetails->setColumn(columnNumberValue);
+ if (stackTraceValue && stackTraceValue->size() > 0)
+ exceptionDetails->setStackTrace(stackTraceValue->buildInspectorArray());
+ }
if (doNotPauseOnExceptionsAndMuteConsole && *doNotPauseOnExceptionsAndMuteConsole) {
unmuteConsole();
@@ -893,18 +958,18 @@ void InspectorDebuggerAgent::setVariableValue(ErrorString* errorString, int scop
{
InjectedScript injectedScript;
if (callFrameId) {
- if (!isPaused() || m_currentCallStack.hasNoValue()) {
+ if (!isPaused() || m_currentCallStack.isEmpty()) {
*errorString = "Attempt to access callframe when debugger is not on pause";
return;
}
injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*callFrameId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return;
}
} else if (functionObjectId) {
injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*functionObjectId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Function object id cannot be resolved";
return;
}
@@ -949,35 +1014,36 @@ void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directive
PassRefPtr<Array<CallFrame> > InspectorDebuggerAgent::currentCallFrames()
{
- if (!m_pausedScriptState || m_currentCallStack.hasNoValue())
+ if (!m_pausedScriptState || m_currentCallStack.isEmpty())
return Array<CallFrame>::create();
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState);
- if (injectedScript.hasNoValue()) {
+ InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState.get());
+ if (injectedScript.isEmpty()) {
ASSERT_NOT_REACHED();
return Array<CallFrame>::create();
}
- return injectedScript.wrapCallFrames(m_currentCallStack);
+ return injectedScript.wrapCallFrames(m_currentCallStack, 0);
}
PassRefPtr<StackTrace> InspectorDebuggerAgent::currentAsyncStackTrace()
{
if (!m_pausedScriptState || !m_asyncCallStackTracker.isEnabled())
- return 0;
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState);
- if (injectedScript.hasNoValue()) {
+ return nullptr;
+ InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState.get());
+ if (injectedScript.isEmpty()) {
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
const AsyncCallStackTracker::AsyncCallChain* chain = m_asyncCallStackTracker.currentAsyncCallChain();
if (!chain)
- return 0;
+ return nullptr;
const AsyncCallStackTracker::AsyncCallStackVector& callStacks = chain->callStacks();
if (callStacks.isEmpty())
- return 0;
+ return nullptr;
RefPtr<StackTrace> result;
+ int asyncOrdinal = callStacks.size();
for (AsyncCallStackTracker::AsyncCallStackVector::const_reverse_iterator it = callStacks.rbegin(); it != callStacks.rend(); ++it) {
RefPtr<StackTrace> next = StackTrace::create()
- .setCallFrames(injectedScript.wrapCallFrames((*it)->callFrames()))
+ .setCallFrames(injectedScript.wrapCallFrames((*it)->callFrames(), asyncOrdinal--))
.release();
next->setDescription((*it)->description());
if (result)
@@ -1057,17 +1123,32 @@ void InspectorDebuggerAgent::failedToParseSource(const String& url, const String
m_frontend->scriptFailedToParse(url, data, firstLine, errorLine, errorMessage);
}
-void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints)
+ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints)
{
+ ScriptDebugListener::SkipPauseRequest result;
+ if (m_javaScriptPauseScheduled)
+ result = ScriptDebugListener::NoSkip; // Don't skip explicit pause requests from front-end.
+ else if (m_skipAllPauses)
+ result = ScriptDebugListener::Continue;
+ else if (!hitBreakpoints.isEmpty())
+ result = ScriptDebugListener::NoSkip; // Don't skip explicit breakpoints even if set in frameworks.
+ else if (!exception.isEmpty())
+ result = shouldSkipExceptionPause();
+ else if (m_debuggerStepScheduled || m_pausingOnNativeEvent)
+ result = shouldSkipStepPause();
+ else
+ result = ScriptDebugListener::NoSkip;
+
+ if (result != ScriptDebugListener::NoSkip)
+ return result;
+
ASSERT(scriptState && !m_pausedScriptState);
m_pausedScriptState = scriptState;
m_currentCallStack = callFrames;
- m_skipStepInCount = numberOfStepsBeforeStepOut;
-
- if (!exception.hasNoValue()) {
+ if (!exception.isEmpty()) {
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
- if (!injectedScript.hasNoValue()) {
+ if (!injectedScript.isEmpty()) {
m_breakReason = InspectorFrontend::Debugger::Reason::Exception;
m_breakAuxData = injectedScript.wrapObject(exception, InspectorDebuggerAgent::backtraceObjectGroup)->openAccessors();
// m_breakAuxData might be null after this.
@@ -1090,6 +1171,9 @@ void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValu
m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBreakpointIds, currentAsyncStackTrace());
m_javaScriptPauseScheduled = false;
+ m_debuggerStepScheduled = false;
+ m_pausingOnNativeEvent = false;
+ m_skippedStepInCount = 0;
if (!m_continueToLocationBreakpointId.isEmpty()) {
scriptDebugServer().removeBreakpoint(m_continueToLocationBreakpointId);
@@ -1097,11 +1181,12 @@ void InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValu
}
if (m_listener)
m_listener->didPause();
+ return result;
}
void InspectorDebuggerAgent::didContinue()
{
- m_pausedScriptState = 0;
+ m_pausedScriptState = nullptr;
m_currentCallStack = ScriptValue();
clearBreakDetails();
m_frontend->resumed();
@@ -1118,12 +1203,14 @@ void InspectorDebuggerAgent::breakProgram(InspectorFrontend::Debugger::Reason::E
return;
m_breakReason = breakReason;
m_breakAuxData = data;
+ m_debuggerStepScheduled = false;
+ m_pausingOnNativeEvent = false;
scriptDebugServer().breakProgram();
}
void InspectorDebuggerAgent::clear()
{
- m_pausedScriptState = 0;
+ m_pausedScriptState = nullptr;
m_currentCallStack = ScriptValue();
m_scripts.clear();
m_breakpointIdToDebugServerBreakpointIds.clear();
@@ -1131,6 +1218,8 @@ void InspectorDebuggerAgent::clear()
m_continueToLocationBreakpointId = String();
clearBreakDetails();
m_javaScriptPauseScheduled = false;
+ m_debuggerStepScheduled = false;
+ m_pausingOnNativeEvent = false;
ErrorString error;
setOverlayMessage(&error, 0);
}
@@ -1147,7 +1236,7 @@ bool InspectorDebuggerAgent::assertPaused(ErrorString* errorString)
void InspectorDebuggerAgent::clearBreakDetails()
{
m_breakReason = InspectorFrontend::Debugger::Reason::Other;
- m_breakAuxData = 0;
+ m_breakAuxData = nullptr;
}
void InspectorDebuggerAgent::setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource source, const String& condition)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h
index 718a0c24e93..ea959df9cf8 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorDebuggerAgent.h
@@ -30,15 +30,15 @@
#ifndef InspectorDebuggerAgent_h
#define InspectorDebuggerAgent_h
-#include "InspectorFrontend.h"
#include "bindings/v8/ScriptState.h"
+#include "core/InspectorFrontend.h"
+#include "core/frame/ConsoleTypes.h"
#include "core/inspector/AsyncCallStackTracker.h"
#include "core/inspector/ConsoleAPITypes.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "core/inspector/ScriptBreakpoint.h"
#include "core/inspector/ScriptDebugListener.h"
-#include "core/frame/ConsoleTypes.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/PassRefPtr.h"
@@ -48,16 +48,26 @@
namespace WebCore {
class Document;
+class Event;
+class EventListener;
+class EventTarget;
+class FormData;
+class HTTPHeaderMap;
class InjectedScriptManager;
class InspectorFrontend;
class InstrumentingAgents;
+class JavaScriptCallFrame;
class JSONObject;
+class KURL;
+class MutationObserver;
class ScriptArguments;
class ScriptCallStack;
class ScriptDebugServer;
+class ScriptRegexp;
class ScriptSourceCode;
class ScriptValue;
-class ScriptRegexp;
+class ThreadableLoaderClient;
+class XMLHttpRequest;
typedef String ErrorString;
@@ -74,60 +84,61 @@ public:
virtual ~InspectorDebuggerAgent();
- virtual void canSetScriptSource(ErrorString*, bool* result) { *result = true; }
+ virtual void canSetScriptSource(ErrorString*, bool* result) OVERRIDE FINAL { *result = true; }
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void init() OVERRIDE FINAL;
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE FINAL;
+ virtual void clearFrontend() OVERRIDE FINAL;
+ virtual void restore() OVERRIDE FINAL;
bool isPaused();
bool runningNestedMessageLoop();
- void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, PassRefPtr<ScriptCallStack>, unsigned long);
- void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, ScriptState*, PassRefPtr<ScriptArguments>, unsigned long);
+ void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, PassRefPtrWillBeRawPtr<ScriptCallStack>, unsigned long);
+ void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>, unsigned long);
- String preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName);
- PassOwnPtr<ScriptSourceCode> preprocess(Frame*, const ScriptSourceCode&);
+ String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName);
+ PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&);
// Part of the protocol.
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void setBreakpointsActive(ErrorString*, bool active);
- virtual void setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload);
-
- virtual void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const String* optionalCondition, const bool* isAntiBreakpoint, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& locations);
- virtual void setBreakpoint(ErrorString*, const RefPtr<JSONObject>& location, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Debugger::Location>& actualLocation);
- virtual void removeBreakpoint(ErrorString*, const String& breakpointId);
- virtual void continueToLocation(ErrorString*, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt);
- virtual void getStepInPositions(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& positions);
- virtual void getBacktrace(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >&, RefPtr<TypeBuilder::Debugger::StackTrace>&);
-
- virtual void searchInContent(ErrorString*, const String& scriptId, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&);
- virtual void setScriptSource(ErrorString*, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>&, const String& scriptId, const String& newContent, const bool* preview, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace);
- virtual void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace);
- virtual void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource);
- virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>&);
- virtual void pause(ErrorString*);
- virtual void resume(ErrorString*);
- virtual void stepOver(ErrorString*, const String* callFrameId);
- virtual void stepInto(ErrorString*);
- virtual void stepOut(ErrorString*, const String* callFrameId);
- virtual void setPauseOnExceptions(ErrorString*, const String& pauseState);
+ virtual void enable(ErrorString*) OVERRIDE FINAL;
+ virtual void disable(ErrorString*) OVERRIDE FINAL;
+ virtual void setBreakpointsActive(ErrorString*, bool active) OVERRIDE FINAL;
+ virtual void setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload) OVERRIDE FINAL;
+
+ virtual void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const String* optionalCondition, const bool* isAntiBreakpoint, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& locations) OVERRIDE FINAL;
+ virtual void setBreakpoint(ErrorString*, const RefPtr<JSONObject>& location, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Debugger::Location>& actualLocation) OVERRIDE FINAL;
+ virtual void removeBreakpoint(ErrorString*, const String& breakpointId) OVERRIDE FINAL;
+ virtual void continueToLocation(ErrorString*, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt) OVERRIDE FINAL;
+ virtual void getStepInPositions(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& positions) OVERRIDE FINAL;
+ virtual void getBacktrace(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >&, RefPtr<TypeBuilder::Debugger::StackTrace>&) OVERRIDE FINAL;
+
+ virtual void searchInContent(ErrorString*, const String& scriptId, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&) OVERRIDE FINAL;
+ virtual void setScriptSource(ErrorString*, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>&, const String& scriptId, const String& newContent, const bool* preview, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace) OVERRIDE FINAL;
+ virtual void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace) OVERRIDE FINAL;
+ virtual void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource) OVERRIDE FINAL;
+ virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>&) OVERRIDE FINAL;
+ virtual void pause(ErrorString*) OVERRIDE FINAL;
+ virtual void resume(ErrorString*) OVERRIDE FINAL;
+ virtual void stepOver(ErrorString*) OVERRIDE FINAL;
+ virtual void stepInto(ErrorString*) OVERRIDE FINAL;
+ virtual void stepOut(ErrorString*) OVERRIDE FINAL;
+ virtual void setPauseOnExceptions(ErrorString*, const String& pauseState) OVERRIDE FINAL;
virtual void evaluateOnCallFrame(ErrorString*,
- const String& callFrameId,
- const String& expression,
- const String* objectGroup,
- const bool* includeCommandLineAPI,
- const bool* doNotPauseOnExceptionsAndMuteConsole,
- const bool* returnByValue,
- const bool* generatePreview,
- RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
- TypeBuilder::OptOutput<bool>* wasThrown);
- void compileScript(ErrorString*, const String& expression, const String& sourceURL, TypeBuilder::OptOutput<TypeBuilder::Debugger::ScriptId>*, TypeBuilder::OptOutput<String>* syntaxErrorMessage);
- void runScript(ErrorString*, const TypeBuilder::Debugger::ScriptId&, const int* executionContextId, const String* objectGroup, const bool* doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown);
- virtual void setOverlayMessage(ErrorString*, const String*);
- virtual void setVariableValue(ErrorString*, int in_scopeNumber, const String& in_variableName, const RefPtr<JSONObject>& in_newValue, const String* in_callFrame, const String* in_functionObjectId);
- virtual void skipStackFrames(ErrorString*, const String* pattern);
- virtual void setAsyncCallStackDepth(ErrorString*, int depth);
+ const String& callFrameId,
+ const String& expression,
+ const String* objectGroup,
+ const bool* includeCommandLineAPI,
+ const bool* doNotPauseOnExceptionsAndMuteConsole,
+ const bool* returnByValue,
+ const bool* generatePreview,
+ RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
+ TypeBuilder::OptOutput<bool>* wasThrown) OVERRIDE FINAL;
+ virtual void compileScript(ErrorString*, const String& expression, const String& sourceURL, const int* executionContextId, TypeBuilder::OptOutput<TypeBuilder::Debugger::ScriptId>*, RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE;
+ virtual void runScript(ErrorString*, const TypeBuilder::Debugger::ScriptId&, const int* executionContextId, const String* objectGroup, const bool* doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE;
+ virtual void setOverlayMessage(ErrorString*, const String*) OVERRIDE;
+ virtual void setVariableValue(ErrorString*, int in_scopeNumber, const String& in_variableName, const RefPtr<JSONObject>& in_newValue, const String* in_callFrame, const String* in_functionObjectId) OVERRIDE FINAL;
+ virtual void skipStackFrames(ErrorString*, const String* pattern) OVERRIDE FINAL;
+ virtual void setAsyncCallStackDepth(ErrorString*, int depth) OVERRIDE FINAL;
void schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
void didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot);
@@ -138,10 +149,18 @@ public:
void didCancelAnimationFrame(Document*, int callbackId);
bool willFireAnimationFrame(Document*, int callbackId);
void didFireAnimationFrame();
+ void didEnqueueEvent(EventTarget*, Event*);
+ void didRemoveEvent(EventTarget*, Event*);
+ void willHandleEvent(EventTarget*, Event*, EventListener*, bool useCapture);
void didHandleEvent();
+ void willLoadXHR(XMLHttpRequest*, ThreadableLoaderClient*, const AtomicString& method, const KURL&, bool async, FormData* body, const HTTPHeaderMap& headers, bool includeCrendentials);
+ void didEnqueueMutationRecord(ExecutionContext*, MutationObserver*);
+ void didClearAllMutationRecords(ExecutionContext*, MutationObserver*);
+ void willDeliverMutationRecords(ExecutionContext*, MutationObserver*);
+ void didDeliverMutationRecords();
bool canBreakProgram();
void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
- virtual void scriptExecutionBlockedByCSP(const String& directiveText);
+ void scriptExecutionBlockedByCSP(const String& directiveText);
class Listener {
public:
@@ -153,17 +172,15 @@ public:
};
void setListener(Listener* listener) { m_listener = listener; }
+ bool enabled();
+
virtual ScriptDebugServer& scriptDebugServer() = 0;
void setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource, const String& condition = String());
void removeBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource);
- SkipPauseRequest shouldSkipExceptionPause(RefPtr<JavaScriptCallFrame>& topFrame);
- SkipPauseRequest shouldSkipBreakpointPause(RefPtr<JavaScriptCallFrame>& topFrame);
- SkipPauseRequest shouldSkipStepPause(RefPtr<JavaScriptCallFrame>& topFrame);
-
protected:
- InspectorDebuggerAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*);
+ explicit InspectorDebuggerAgent(InjectedScriptManager*);
virtual void startListeningScriptDebugServer() = 0;
virtual void stopListeningScriptDebugServer() = 0;
@@ -174,22 +191,23 @@ protected:
virtual void enable();
virtual void disable();
- virtual void didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints);
- virtual void didContinue();
+ virtual SkipPauseRequest didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints) OVERRIDE FINAL;
+ virtual void didContinue() OVERRIDE FINAL;
void reset();
void pageDidCommitLoad();
private:
+ SkipPauseRequest shouldSkipExceptionPause();
+ SkipPauseRequest shouldSkipStepPause();
+
void cancelPauseOnNextStatement();
void addMessageToConsole(MessageSource, MessageType);
- bool enabled();
-
PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > currentCallFrames();
PassRefPtr<TypeBuilder::Debugger::StackTrace> currentAsyncStackTrace();
- virtual void didParseSource(const String& scriptId, const Script&);
- virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage);
+ virtual void didParseSource(const String& scriptId, const Script&) OVERRIDE FINAL;
+ virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) OVERRIDE FINAL;
void setPauseOnExceptionsImpl(ErrorString*, int);
@@ -203,15 +221,13 @@ private:
String scriptURL(JavaScriptCallFrame*);
- ScriptValue resolveCallFrame(ErrorString*, const String* callFrameId);
-
typedef HashMap<String, Script> ScriptsMap;
typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap;
typedef HashMap<String, std::pair<String, BreakpointSource> > DebugServerBreakpointToBreakpointIdAndSourceMap;
InjectedScriptManager* m_injectedScriptManager;
InspectorFrontend::Debugger* m_frontend;
- ScriptState* m_pausedScriptState;
+ RefPtr<ScriptState> m_pausedScriptState;
ScriptValue m_currentCallStack;
ScriptsMap m_scripts;
BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds;
@@ -220,9 +236,12 @@ private:
InspectorFrontend::Debugger::Reason::Enum m_breakReason;
RefPtr<JSONObject> m_breakAuxData;
bool m_javaScriptPauseScheduled;
+ bool m_debuggerStepScheduled;
+ bool m_pausingOnNativeEvent;
Listener* m_listener;
- int m_skipStepInCount;
+ int m_skippedStepInCount;
+ int m_minFrameCountForSkip;
bool m_skipAllPauses;
OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp;
AsyncCallStackTracker m_asyncCallStackTracker;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorFileSystemAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorFileSystemAgent.cpp
deleted file mode 100644
index e406a22b8ee..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorFileSystemAgent.cpp
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/inspector/InspectorFileSystemAgent.h"
-
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/dom/DOMImplementation.h"
-#include "core/dom/Document.h"
-#include "core/events/Event.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/fileapi/File.h"
-#include "core/fileapi/FileError.h"
-#include "core/fileapi/FileReader.h"
-#include "core/frame/Frame.h"
-#include "core/html/VoidCallback.h"
-#include "core/inspector/InspectorPageAgent.h"
-#include "core/inspector/InspectorState.h"
-#include "modules/filesystem/DOMFileSystem.h"
-#include "modules/filesystem/DirectoryEntry.h"
-#include "modules/filesystem/DirectoryReader.h"
-#include "modules/filesystem/EntriesCallback.h"
-#include "modules/filesystem/Entry.h"
-#include "modules/filesystem/EntryCallback.h"
-#include "modules/filesystem/ErrorCallback.h"
-#include "modules/filesystem/FileCallback.h"
-#include "modules/filesystem/FileEntry.h"
-#include "modules/filesystem/FileSystemCallbacks.h"
-#include "modules/filesystem/LocalFileSystem.h"
-#include "modules/filesystem/Metadata.h"
-#include "modules/filesystem/MetadataCallback.h"
-#include "platform/MIMETypeRegistry.h"
-#include "platform/weborigin/KURL.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "wtf/ArrayBuffer.h"
-#include "wtf/text/Base64.h"
-#include "wtf/text/TextEncoding.h"
-
-using WebCore::TypeBuilder::Array;
-
-typedef WebCore::InspectorBackendDispatcher::FileSystemCommandHandler::RequestFileSystemRootCallback RequestFileSystemRootCallback;
-typedef WebCore::InspectorBackendDispatcher::FileSystemCommandHandler::RequestDirectoryContentCallback RequestDirectoryContentCallback;
-typedef WebCore::InspectorBackendDispatcher::FileSystemCommandHandler::RequestMetadataCallback RequestMetadataCallback;
-typedef WebCore::InspectorBackendDispatcher::FileSystemCommandHandler::RequestFileContentCallback RequestFileContentCallback;
-typedef WebCore::InspectorBackendDispatcher::FileSystemCommandHandler::DeleteEntryCallback DeleteEntryCallback;
-
-namespace WebCore {
-
-namespace FileSystemAgentState {
-static const char fileSystemAgentEnabled[] = "fileSystemAgentEnabled";
-}
-
-namespace {
-
-template<typename BaseCallback, typename Handler, typename Argument>
-class CallbackDispatcher : public BaseCallback {
-public:
- typedef bool (Handler::*HandlingMethod)(Argument);
-
- static PassOwnPtr<CallbackDispatcher> create(PassRefPtr<Handler> handler, HandlingMethod handlingMethod)
- {
- return adoptPtr(new CallbackDispatcher(handler, handlingMethod));
- }
-
- virtual void handleEvent(Argument argument) OVERRIDE
- {
- (m_handler.get()->*m_handlingMethod)(argument);
- }
-
-private:
- CallbackDispatcher(PassRefPtr<Handler> handler, HandlingMethod handlingMethod)
- : m_handler(handler)
- , m_handlingMethod(handlingMethod) { }
-
- RefPtr<Handler> m_handler;
- HandlingMethod m_handlingMethod;
-};
-
-template<typename BaseCallback>
-class CallbackDispatcherFactory {
-public:
- template<typename Handler, typename Argument>
- static PassOwnPtr<CallbackDispatcher<BaseCallback, Handler, Argument> > create(Handler* handler, bool (Handler::*handlingMethod)(Argument))
- {
- return CallbackDispatcher<BaseCallback, Handler, Argument>::create(PassRefPtr<Handler>(handler), handlingMethod);
- }
-};
-
-class FileSystemRootRequest : public RefCounted<FileSystemRootRequest> {
- WTF_MAKE_NONCOPYABLE(FileSystemRootRequest);
-public:
- static PassRefPtr<FileSystemRootRequest> create(PassRefPtr<RequestFileSystemRootCallback> requestCallback, const String& type)
- {
- return adoptRef(new FileSystemRootRequest(requestCallback, type));
- }
-
- void start(ExecutionContext*);
-
-private:
- bool didHitError(FileError* error)
- {
- reportResult(error->code());
- return true;
- }
-
- bool didGetEntry(Entry*);
-
- void reportResult(FileError::ErrorCode errorCode, PassRefPtr<TypeBuilder::FileSystem::Entry> entry = 0)
- {
- m_requestCallback->sendSuccess(static_cast<int>(errorCode), entry);
- }
-
- FileSystemRootRequest(PassRefPtr<RequestFileSystemRootCallback> requestCallback, const String& type)
- : m_requestCallback(requestCallback)
- , m_type(type) { }
-
- RefPtr<RequestFileSystemRootCallback> m_requestCallback;
- String m_type;
-};
-
-void FileSystemRootRequest::start(ExecutionContext* executionContext)
-{
- ASSERT(executionContext);
-
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &FileSystemRootRequest::didHitError);
-
- FileSystemType type;
- if (!DOMFileSystemBase::pathPrefixToFileSystemType(m_type, type)) {
- errorCallback->handleEvent(FileError::create(FileError::SYNTAX_ERR).get());
- return;
- }
-
- KURL rootURL = DOMFileSystemBase::createFileSystemRootURL(executionContext->securityOrigin()->toString(), type);
- if (!rootURL.isValid()) {
- errorCallback->handleEvent(FileError::create(FileError::SYNTAX_ERR).get());
- return;
- }
-
- OwnPtr<EntryCallback> successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &FileSystemRootRequest::didGetEntry);
- OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback.release(), errorCallback.release(), executionContext);
- LocalFileSystem::from(executionContext)->resolveURL(executionContext, rootURL, fileSystemCallbacks.release());
-}
-
-bool FileSystemRootRequest::didGetEntry(Entry* entry)
-{
- RefPtr<TypeBuilder::FileSystem::Entry> result = TypeBuilder::FileSystem::Entry::create()
- .setUrl(entry->toURL())
- .setName("/")
- .setIsDirectory(true);
- reportResult(static_cast<FileError::ErrorCode>(0), result);
- return true;
-}
-
-class DirectoryContentRequest : public RefCounted<DirectoryContentRequest> {
- WTF_MAKE_NONCOPYABLE(DirectoryContentRequest);
-public:
- static PassRefPtr<DirectoryContentRequest> create(PassRefPtr<RequestDirectoryContentCallback> requestCallback, const String& url)
- {
- return adoptRef(new DirectoryContentRequest(requestCallback, url));
- }
-
- virtual ~DirectoryContentRequest()
- {
- reportResult(FileError::ABORT_ERR);
- }
-
- void start(ExecutionContext*);
-
-private:
- bool didHitError(FileError* error)
- {
- reportResult(error->code());
- return true;
- }
-
- bool didGetEntry(Entry*);
- bool didReadDirectoryEntries(const EntryVector&);
-
- void reportResult(FileError::ErrorCode errorCode, PassRefPtr<Array<TypeBuilder::FileSystem::Entry> > entries = 0)
- {
- m_requestCallback->sendSuccess(static_cast<int>(errorCode), entries);
- }
-
- DirectoryContentRequest(PassRefPtr<RequestDirectoryContentCallback> requestCallback, const String& url)
- : m_requestCallback(requestCallback)
- , m_url(ParsedURLString, url) { }
-
- void readDirectoryEntries();
-
- RefPtr<RequestDirectoryContentCallback> m_requestCallback;
- KURL m_url;
- RefPtr<Array<TypeBuilder::FileSystem::Entry> > m_entries;
- RefPtr<DirectoryReader> m_directoryReader;
-};
-
-void DirectoryContentRequest::start(ExecutionContext* executionContext)
-{
- ASSERT(executionContext);
-
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &DirectoryContentRequest::didHitError);
- OwnPtr<EntryCallback> successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &DirectoryContentRequest::didGetEntry);
-
- OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback.release(), errorCallback.release(), executionContext);
-
- LocalFileSystem::from(executionContext)->resolveURL(executionContext, m_url, fileSystemCallbacks.release());
-}
-
-bool DirectoryContentRequest::didGetEntry(Entry* entry)
-{
- if (!entry->isDirectory()) {
- reportResult(FileError::TYPE_MISMATCH_ERR);
- return true;
- }
-
- m_directoryReader = toDirectoryEntry(entry)->createReader();
- m_entries = Array<TypeBuilder::FileSystem::Entry>::create();
- readDirectoryEntries();
- return true;
-}
-
-void DirectoryContentRequest::readDirectoryEntries()
-{
- if (!m_directoryReader->filesystem()->executionContext()) {
- reportResult(FileError::ABORT_ERR);
- return;
- }
-
- OwnPtr<EntriesCallback> successCallback = CallbackDispatcherFactory<EntriesCallback>::create(this, &DirectoryContentRequest::didReadDirectoryEntries);
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &DirectoryContentRequest::didHitError);
- m_directoryReader->readEntries(successCallback.release(), errorCallback.release());
-}
-
-bool DirectoryContentRequest::didReadDirectoryEntries(const EntryVector& entries)
-{
- if (entries.isEmpty()) {
- reportResult(static_cast<FileError::ErrorCode>(0), m_entries);
- return true;
- }
-
- for (size_t i = 0; i < entries.size(); ++i) {
- RefPtr<Entry> entry = entries[i];
- RefPtr<TypeBuilder::FileSystem::Entry> entryForFrontend = TypeBuilder::FileSystem::Entry::create()
- .setUrl(entry->toURL())
- .setName(entry->name())
- .setIsDirectory(entry->isDirectory());
-
- using TypeBuilder::Page::ResourceType;
- if (!entry->isDirectory()) {
- String mimeType = MIMETypeRegistry::getMIMETypeForPath(entry->name());
- ResourceType::Enum resourceType;
- if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) {
- resourceType = ResourceType::Image;
- entryForFrontend->setIsTextFile(false);
- } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType)) {
- resourceType = ResourceType::Script;
- entryForFrontend->setIsTextFile(true);
- } else if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) {
- resourceType = ResourceType::Document;
- entryForFrontend->setIsTextFile(true);
- } else {
- resourceType = ResourceType::Other;
- entryForFrontend->setIsTextFile(DOMImplementation::isXMLMIMEType(mimeType) || DOMImplementation::isTextMIMEType(mimeType));
- }
-
- entryForFrontend->setMimeType(mimeType);
- entryForFrontend->setResourceType(resourceType);
- }
-
- m_entries->addItem(entryForFrontend);
- }
- readDirectoryEntries();
- return true;
-}
-
-class MetadataRequest : public RefCounted<MetadataRequest> {
- WTF_MAKE_NONCOPYABLE(MetadataRequest);
-public:
- static PassRefPtr<MetadataRequest> create(PassRefPtr<RequestMetadataCallback> requestCallback, const String& url)
- {
- return adoptRef(new MetadataRequest(requestCallback, url));
- }
-
- virtual ~MetadataRequest()
- {
- reportResult(FileError::ABORT_ERR);
- }
-
- void start(ExecutionContext*);
-
-private:
- bool didHitError(FileError* error)
- {
- reportResult(error->code());
- return true;
- }
-
- bool didGetEntry(Entry*);
- bool didGetMetadata(Metadata*);
-
- void reportResult(FileError::ErrorCode errorCode, PassRefPtr<TypeBuilder::FileSystem::Metadata> metadata = 0)
- {
- m_requestCallback->sendSuccess(static_cast<int>(errorCode), metadata);
- }
-
- MetadataRequest(PassRefPtr<RequestMetadataCallback> requestCallback, const String& url)
- : m_requestCallback(requestCallback)
- , m_url(ParsedURLString, url) { }
-
- RefPtr<RequestMetadataCallback> m_requestCallback;
- KURL m_url;
- bool m_isDirectory;
-};
-
-void MetadataRequest::start(ExecutionContext* executionContext)
-{
- ASSERT(executionContext);
-
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &MetadataRequest::didHitError);
- OwnPtr<EntryCallback> successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &MetadataRequest::didGetEntry);
- OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback.release(), errorCallback.release(), executionContext);
- LocalFileSystem::from(executionContext)->resolveURL(executionContext, m_url, fileSystemCallbacks.release());
-}
-
-bool MetadataRequest::didGetEntry(Entry* entry)
-{
- if (!entry->filesystem()->executionContext()) {
- reportResult(FileError::ABORT_ERR);
- return true;
- }
-
- OwnPtr<MetadataCallback> successCallback = CallbackDispatcherFactory<MetadataCallback>::create(this, &MetadataRequest::didGetMetadata);
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &MetadataRequest::didHitError);
- entry->getMetadata(successCallback.release(), errorCallback.release());
- m_isDirectory = entry->isDirectory();
- return true;
-}
-
-bool MetadataRequest::didGetMetadata(Metadata* metadata)
-{
- using TypeBuilder::FileSystem::Metadata;
- RefPtr<Metadata> result = Metadata::create()
- .setModificationTime(metadata->modificationTime())
- .setSize(metadata->size());
- reportResult(static_cast<FileError::ErrorCode>(0), result);
- return true;
-}
-
-class FileContentRequest : public EventListener {
- WTF_MAKE_NONCOPYABLE(FileContentRequest);
-public:
- static PassRefPtr<FileContentRequest> create(PassRefPtr<RequestFileContentCallback> requestCallback, const String& url, bool readAsText, long long start, long long end, const String& charset)
- {
- return adoptRef(new FileContentRequest(requestCallback, url, readAsText, start, end, charset));
- }
-
- virtual ~FileContentRequest()
- {
- reportResult(FileError::ABORT_ERR);
- }
-
- void start(ExecutionContext*);
-
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
-
- virtual void handleEvent(ExecutionContext*, Event* event) OVERRIDE
- {
- if (event->type() == EventTypeNames::load)
- didRead();
- else if (event->type() == EventTypeNames::error)
- didHitError(m_reader->error().get());
- }
-
-private:
- bool didHitError(FileError* error)
- {
- reportResult(error->code());
- return true;
- }
-
- bool didGetEntry(Entry*);
- bool didGetFile(File*);
- void didRead();
-
- void reportResult(FileError::ErrorCode errorCode, const String* result = 0, const String* charset = 0)
- {
- m_requestCallback->sendSuccess(static_cast<int>(errorCode), result, charset);
- }
-
- FileContentRequest(PassRefPtr<RequestFileContentCallback> requestCallback, const String& url, bool readAsText, long long start, long long end, const String& charset)
- : EventListener(EventListener::CPPEventListenerType)
- , m_requestCallback(requestCallback)
- , m_url(ParsedURLString, url)
- , m_readAsText(readAsText)
- , m_start(start)
- , m_end(end)
- , m_charset(charset) { }
-
- RefPtr<RequestFileContentCallback> m_requestCallback;
- KURL m_url;
- bool m_readAsText;
- int m_start;
- long long m_end;
- String m_mimeType;
- String m_charset;
-
- RefPtr<FileReader> m_reader;
-};
-
-void FileContentRequest::start(ExecutionContext* executionContext)
-{
- ASSERT(executionContext);
-
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &FileContentRequest::didHitError);
- OwnPtr<EntryCallback> successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &FileContentRequest::didGetEntry);
-
- OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback.release(), errorCallback.release(), executionContext);
- LocalFileSystem::from(executionContext)->resolveURL(executionContext, m_url, fileSystemCallbacks.release());
-}
-
-bool FileContentRequest::didGetEntry(Entry* entry)
-{
- if (entry->isDirectory()) {
- reportResult(FileError::TYPE_MISMATCH_ERR);
- return true;
- }
-
- if (!entry->filesystem()->executionContext()) {
- reportResult(FileError::ABORT_ERR);
- return true;
- }
-
- OwnPtr<FileCallback> successCallback = CallbackDispatcherFactory<FileCallback>::create(this, &FileContentRequest::didGetFile);
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &FileContentRequest::didHitError);
- toFileEntry(entry)->file(successCallback.release(), errorCallback.release());
-
- m_reader = FileReader::create(entry->filesystem()->executionContext());
- m_mimeType = MIMETypeRegistry::getMIMETypeForPath(entry->name());
-
- return true;
-}
-
-bool FileContentRequest::didGetFile(File* file)
-{
- RefPtr<Blob> blob = file->slice(m_start, m_end);
- m_reader->setOnload(this);
- m_reader->setOnerror(this);
-
- m_reader->readAsArrayBuffer(blob.get(), IGNORE_EXCEPTION);
- return true;
-}
-
-void FileContentRequest::didRead()
-{
- RefPtr<ArrayBuffer> buffer = m_reader->arrayBufferResult();
-
- if (!m_readAsText) {
- String result = base64Encode(static_cast<char*>(buffer->data()), buffer->byteLength());
- reportResult(static_cast<FileError::ErrorCode>(0), &result, 0);
- return;
- }
-
- OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create(m_mimeType, m_charset, true);
- String result = decoder->decode(static_cast<char*>(buffer->data()), buffer->byteLength());
- result.append(decoder->flush());
- m_charset = decoder->encoding().name();
- reportResult(static_cast<FileError::ErrorCode>(0), &result, &m_charset);
-}
-
-class DeleteEntryRequest : public RefCounted<DeleteEntryRequest> {
-public:
- static PassRefPtr<DeleteEntryRequest> create(PassRefPtr<DeleteEntryCallback> requestCallback, const KURL& url)
- {
- return adoptRef(new DeleteEntryRequest(requestCallback, url));
- }
-
- virtual ~DeleteEntryRequest()
- {
- reportResult(FileError::ABORT_ERR);
- }
-
- void start(ExecutionContext*);
-
-private:
- // CallbackDispatcherFactory doesn't handle 0-arg handleEvent methods
- class VoidCallbackImpl : public VoidCallback {
- public:
- explicit VoidCallbackImpl(PassRefPtr<DeleteEntryRequest> handler)
- : m_handler(handler)
- {
- }
-
- virtual void handleEvent() OVERRIDE
- {
- m_handler->didDeleteEntry();
- }
-
- private:
- RefPtr<DeleteEntryRequest> m_handler;
- };
-
- bool didHitError(FileError* error)
- {
- reportResult(error->code());
- return true;
- }
-
- bool didGetEntry(Entry*);
- bool didDeleteEntry();
-
- void reportResult(FileError::ErrorCode errorCode)
- {
- m_requestCallback->sendSuccess(static_cast<int>(errorCode));
- }
-
- DeleteEntryRequest(PassRefPtr<DeleteEntryCallback> requestCallback, const KURL& url)
- : m_requestCallback(requestCallback)
- , m_url(url) { }
-
- RefPtr<DeleteEntryCallback> m_requestCallback;
- KURL m_url;
-};
-
-void DeleteEntryRequest::start(ExecutionContext* executionContext)
-{
- ASSERT(executionContext);
-
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &DeleteEntryRequest::didHitError);
-
- FileSystemType type;
- String path;
- if (!DOMFileSystemBase::crackFileSystemURL(m_url, type, path)) {
- errorCallback->handleEvent(FileError::create(FileError::SYNTAX_ERR).get());
- return;
- }
-
- if (path == "/") {
- OwnPtr<VoidCallback> successCallback = adoptPtr(new VoidCallbackImpl(this));
- OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = VoidCallbacks::create(successCallback.release(), errorCallback.release(), 0);
- LocalFileSystem::from(executionContext)->deleteFileSystem(executionContext, type, fileSystemCallbacks.release());
- } else {
- OwnPtr<EntryCallback> successCallback = CallbackDispatcherFactory<EntryCallback>::create(this, &DeleteEntryRequest::didGetEntry);
- OwnPtr<AsyncFileSystemCallbacks> fileSystemCallbacks = ResolveURICallbacks::create(successCallback.release(), errorCallback.release(), executionContext);
- LocalFileSystem::from(executionContext)->resolveURL(executionContext, m_url, fileSystemCallbacks.release());
- }
-}
-
-bool DeleteEntryRequest::didGetEntry(Entry* entry)
-{
- OwnPtr<VoidCallback> successCallback = adoptPtr(new VoidCallbackImpl(this));
- OwnPtr<ErrorCallback> errorCallback = CallbackDispatcherFactory<ErrorCallback>::create(this, &DeleteEntryRequest::didHitError);
- if (entry->isDirectory()) {
- DirectoryEntry* directoryEntry = toDirectoryEntry(entry);
- directoryEntry->removeRecursively(successCallback.release(), errorCallback.release());
- } else {
- entry->remove(successCallback.release(), errorCallback.release());
- }
- return true;
-}
-
-bool DeleteEntryRequest::didDeleteEntry()
-{
- reportResult(static_cast<FileError::ErrorCode>(0));
- return true;
-}
-
-} // anonymous namespace
-
-// static
-PassOwnPtr<InspectorFileSystemAgent> InspectorFileSystemAgent::create(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorCompositeState* state)
-{
- return adoptPtr(new InspectorFileSystemAgent(instrumentingAgents, pageAgent, state));
-}
-
-InspectorFileSystemAgent::~InspectorFileSystemAgent()
-{
-}
-
-void InspectorFileSystemAgent::enable(ErrorString*)
-{
- if (m_enabled)
- return;
- m_enabled = true;
- m_state->setBoolean(FileSystemAgentState::fileSystemAgentEnabled, m_enabled);
-}
-
-void InspectorFileSystemAgent::disable(ErrorString*)
-{
- if (!m_enabled)
- return;
- m_enabled = false;
- m_state->setBoolean(FileSystemAgentState::fileSystemAgentEnabled, m_enabled);
-}
-
-void InspectorFileSystemAgent::requestFileSystemRoot(ErrorString* error, const String& origin, const String& type, PassRefPtr<RequestFileSystemRootCallback> requestCallback)
-{
- if (!assertEnabled(error))
- return;
-
- ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::createFromString(origin).get());
- if (!executionContext)
- return;
-
- FileSystemRootRequest::create(requestCallback, type)->start(executionContext);
-}
-
-void InspectorFileSystemAgent::requestDirectoryContent(ErrorString* error, const String& url, PassRefPtr<RequestDirectoryContentCallback> requestCallback)
-{
- if (!assertEnabled(error))
- return;
-
- ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::createFromString(url).get());
- if (!executionContext)
- return;
-
- DirectoryContentRequest::create(requestCallback, url)->start(executionContext);
-}
-
-void InspectorFileSystemAgent::requestMetadata(ErrorString* error, const String& url, PassRefPtr<RequestMetadataCallback> requestCallback)
-{
- if (!assertEnabled(error))
- return;
-
- ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::createFromString(url).get());
- if (!executionContext)
- return;
-
- MetadataRequest::create(requestCallback, url)->start(executionContext);
-}
-
-void InspectorFileSystemAgent::requestFileContent(ErrorString* error, const String& url, bool readAsText, const int* start, const int* end, const String* charset, PassRefPtr<RequestFileContentCallback> requestCallback)
-{
- if (!assertEnabled(error))
- return;
-
- ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::createFromString(url).get());
- if (!executionContext)
- return;
-
- long long startPosition = start ? *start : 0;
- long long endPosition = end ? *end : std::numeric_limits<long long>::max();
- FileContentRequest::create(requestCallback, url, readAsText, startPosition, endPosition, charset ? *charset : "")->start(executionContext);
-}
-
-void InspectorFileSystemAgent::deleteEntry(ErrorString* error, const String& urlString, PassRefPtr<DeleteEntryCallback> requestCallback)
-{
- if (!assertEnabled(error))
- return;
-
- KURL url(ParsedURLString, urlString);
-
- ExecutionContext* executionContext = assertExecutionContextForOrigin(error, SecurityOrigin::create(url).get());
- if (!executionContext)
- return;
-
- DeleteEntryRequest::create(requestCallback, url)->start(executionContext);
-}
-
-void InspectorFileSystemAgent::clearFrontend()
-{
- m_enabled = false;
- m_state->setBoolean(FileSystemAgentState::fileSystemAgentEnabled, m_enabled);
-}
-
-void InspectorFileSystemAgent::restore()
-{
- m_enabled = m_state->getBoolean(FileSystemAgentState::fileSystemAgentEnabled);
-}
-
-InspectorFileSystemAgent::InspectorFileSystemAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorCompositeState* state)
- : InspectorBaseAgent<InspectorFileSystemAgent>("FileSystem", instrumentingAgents, state)
- , m_pageAgent(pageAgent)
- , m_enabled(false)
-{
- ASSERT(instrumentingAgents);
- ASSERT(state);
- ASSERT(m_pageAgent);
-}
-
-bool InspectorFileSystemAgent::assertEnabled(ErrorString* error)
-{
- if (!m_enabled) {
- *error = "FileSystem agent is not enabled.";
- return false;
- }
- return true;
-}
-
-ExecutionContext* InspectorFileSystemAgent::assertExecutionContextForOrigin(ErrorString* error, SecurityOrigin* origin)
-{
- for (Frame* frame = m_pageAgent->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document() && frame->document()->securityOrigin()->isSameSchemeHostPort(origin))
- return frame->document();
- }
-
- *error = "No frame is available for the request";
- return 0;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorFileSystemAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorFileSystemAgent.h
deleted file mode 100644
index 24e68ab0e33..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorFileSystemAgent.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorFileSystemAgent_h
-#define InspectorFileSystemAgent_h
-
-#include "core/inspector/InspectorBaseAgent.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-class InspectorPageAgent;
-class ExecutionContext;
-class SecurityOrigin;
-
-class InspectorFileSystemAgent : public InspectorBaseAgent<InspectorFileSystemAgent>, public InspectorBackendDispatcher::FileSystemCommandHandler {
-public:
- static PassOwnPtr<InspectorFileSystemAgent> create(InstrumentingAgents*, InspectorPageAgent*, InspectorCompositeState*);
- virtual ~InspectorFileSystemAgent();
-
- virtual void enable(ErrorString*) OVERRIDE;
- virtual void disable(ErrorString*) OVERRIDE;
-
- virtual void requestFileSystemRoot(ErrorString*, const String& origin, const String& typeString, PassRefPtr<RequestFileSystemRootCallback>) OVERRIDE;
- virtual void requestDirectoryContent(ErrorString*, const String& url, PassRefPtr<RequestDirectoryContentCallback>) OVERRIDE;
- virtual void requestMetadata(ErrorString*, const String& url, PassRefPtr<RequestMetadataCallback>) OVERRIDE;
- virtual void requestFileContent(ErrorString*, const String& url, bool readAsText, const int* start, const int* end, const String* charset, PassRefPtr<RequestFileContentCallback>) OVERRIDE;
- virtual void deleteEntry(ErrorString*, const String& url, PassRefPtr<DeleteEntryCallback>) OVERRIDE;
-
- virtual void clearFrontend() OVERRIDE;
- virtual void restore() OVERRIDE;
-
-private:
- InspectorFileSystemAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorCompositeState*);
- bool assertEnabled(ErrorString*);
- ExecutionContext* assertExecutionContextForOrigin(ErrorString*, SecurityOrigin*);
-
- InspectorPageAgent* m_pageAgent;
- bool m_enabled;
-};
-
-} // namespace WebCore
-
-#endif // InspectorFileSystemAgent_h
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendChannel.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendChannel.h
index 9505cb64762..4db34236385 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendChannel.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendChannel.h
@@ -26,6 +26,7 @@
#ifndef InspectorFrontendChannel_h
#define InspectorFrontendChannel_h
+#include "platform/JSONValues.h"
#include "wtf/Forward.h"
namespace WebCore {
@@ -33,7 +34,8 @@ namespace WebCore {
class InspectorFrontendChannel {
public:
virtual ~InspectorFrontendChannel() { }
- virtual bool sendMessageToFrontend(const String& message) = 0;
+ virtual void sendMessageToFrontend(PassRefPtr<JSONObject> message) = 0;
+ virtual void flush() = 0;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendClient.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendClient.h
index 00848e1e8b8..41e414d1f9a 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendClient.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendClient.h
@@ -42,8 +42,6 @@ public:
virtual void windowObjectCleared() = 0;
- virtual void inspectedURLChanged(const String&) = 0;
-
virtual void sendMessageToBackend(const String&) = 0;
virtual void sendMessageToEmbedder(const String&) = 0;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.cpp
index 20f2160f56f..a9ce1e479dc 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.cpp
@@ -32,21 +32,19 @@
#include "bindings/v8/ScriptFunctionCall.h"
#include "bindings/v8/ScriptState.h"
+#include "core/clipboard/Pasteboard.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorController.h"
#include "core/inspector/InspectorFrontendClient.h"
#include "core/loader/FrameLoader.h"
#include "core/page/ContextMenuController.h"
#include "core/page/ContextMenuProvider.h"
#include "core/page/Page.h"
-#include "core/platform/Pasteboard.h"
#include "core/rendering/RenderTheme.h"
-#include "modules/filesystem/DOMFileSystem.h"
#include "platform/ContextMenu.h"
#include "platform/ContextMenuItem.h"
-#include "platform/JSONValues.h"
#include "platform/SharedBuffer.h"
#include "platform/UserGestureIndicator.h"
#include "platform/network/ResourceError.h"
@@ -55,21 +53,21 @@
namespace WebCore {
-class FrontendMenuProvider : public ContextMenuProvider {
+class FrontendMenuProvider FINAL : public ContextMenuProvider {
public:
- static PassRefPtr<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items)
+ static PassRefPtr<FrontendMenuProvider> create(InspectorFrontendHost* frontendHost, ScriptValue frontendApiObject, const Vector<ContextMenuItem>& items)
{
return adoptRef(new FrontendMenuProvider(frontendHost, frontendApiObject, items));
}
void disconnect()
{
- m_frontendApiObject = ScriptObject();
+ m_frontendApiObject = ScriptValue();
m_frontendHost = 0;
}
private:
- FrontendMenuProvider(InspectorFrontendHost* frontendHost, ScriptObject frontendApiObject, const Vector<ContextMenuItem>& items)
+ FrontendMenuProvider(InspectorFrontendHost* frontendHost, ScriptValue frontendApiObject, const Vector<ContextMenuItem>& items)
: m_frontendHost(frontendHost)
, m_frontendApiObject(frontendApiObject)
, m_items(items)
@@ -81,13 +79,13 @@ private:
contextMenuCleared();
}
- virtual void populateContextMenu(ContextMenu* menu)
+ virtual void populateContextMenu(ContextMenu* menu) OVERRIDE
{
for (size_t i = 0; i < m_items.size(); ++i)
menu->appendItem(m_items[i]);
}
- virtual void contextMenuItemSelected(const ContextMenuItem* item)
+ virtual void contextMenuItemSelected(const ContextMenuItem* item) OVERRIDE
{
if (m_frontendHost) {
UserGestureIndicator gestureIndicator(DefinitelyProcessingNewUserGesture);
@@ -99,7 +97,7 @@ private:
}
}
- virtual void contextMenuCleared()
+ virtual void contextMenuCleared() OVERRIDE
{
if (m_frontendHost) {
ScriptFunctionCall function(m_frontendApiObject, "contextMenuCleared");
@@ -111,7 +109,7 @@ private:
}
InspectorFrontendHost* m_frontendHost;
- ScriptObject m_frontendApiObject;
+ ScriptValue m_frontendApiObject;
Vector<ContextMenuItem> m_items;
};
@@ -138,13 +136,12 @@ void InspectorFrontendHost::disconnectClient()
void InspectorFrontendHost::setZoomFactor(float zoom)
{
- m_frontendPage->mainFrame()->setPageAndTextZoomFactors(zoom, 1);
+ m_frontendPage->deprecatedLocalMainFrame()->setPageAndTextZoomFactors(zoom, 1);
}
-void InspectorFrontendHost::inspectedURLChanged(const String& newURL)
+float InspectorFrontendHost::zoomFactor()
{
- if (m_client)
- m_client->inspectedURLChanged(newURL);
+ return m_frontendPage->deprecatedLocalMainFrame()->pageZoomFactor();
}
void InspectorFrontendHost::setInjectedScriptForOrigin(const String& origin, const String& script)
@@ -157,16 +154,33 @@ void InspectorFrontendHost::copyText(const String& text)
Pasteboard::generalPasteboard()->writePlainText(text, Pasteboard::CannotSmartReplace);
}
+static String escapeUnicodeNonCharacters(const String& str)
+{
+ StringBuilder dst;
+ for (unsigned i = 0; i < str.length(); ++i) {
+ UChar c = str[i];
+ if (c >= 0xD800) {
+ unsigned symbol = static_cast<unsigned>(c);
+ String symbolCode = String::format("\\u%04X", symbol);
+ dst.append(symbolCode);
+ } else {
+ dst.append(c);
+ }
+
+ }
+ return dst.toString();
+}
+
void InspectorFrontendHost::sendMessageToBackend(const String& message)
{
if (m_client)
- m_client->sendMessageToBackend(message);
+ m_client->sendMessageToBackend(escapeUnicodeNonCharacters(message));
}
void InspectorFrontendHost::sendMessageToEmbedder(const String& message)
{
if (m_client)
- m_client->sendMessageToEmbedder(message);
+ m_client->sendMessageToEmbedder(escapeUnicodeNonCharacters(message));
}
void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMenuItem>& items)
@@ -175,12 +189,9 @@ void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMe
return;
ASSERT(m_frontendPage);
- ScriptState* frontendScriptState = mainWorldScriptState(m_frontendPage->mainFrame());
- ScriptObject frontendApiObject;
- if (!ScriptGlobalObject::get(frontendScriptState, "InspectorFrontendAPI", frontendApiObject)) {
- ASSERT_NOT_REACHED();
- return;
- }
+ ScriptState* frontendScriptState = ScriptState::forMainWorld(m_frontendPage->deprecatedLocalMainFrame());
+ ScriptValue frontendApiObject = frontendScriptState->getFromGlobalObject("InspectorFrontendAPI");
+ ASSERT(frontendApiObject.isObject());
RefPtr<FrontendMenuProvider> menuProvider = FrontendMenuProvider::create(this, frontendApiObject, items);
m_frontendPage->contextMenuController().showContextMenu(event, menuProvider);
m_menuProvider = menuProvider.get();
@@ -188,33 +199,12 @@ void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMe
String InspectorFrontendHost::getSelectionBackgroundColor()
{
- Color color = RenderTheme::theme().activeSelectionBackgroundColor();
- return color.isValid() ? color.serialized() : "";
+ return RenderTheme::theme().activeSelectionBackgroundColor().serialized();
}
String InspectorFrontendHost::getSelectionForegroundColor()
{
- Color color = RenderTheme::theme().activeSelectionForegroundColor();
- return color.isValid() ? color.serialized() : "";
-}
-
-PassRefPtr<DOMFileSystem> InspectorFrontendHost::isolatedFileSystem(const String& fileSystemName, const String& rootURL)
-{
- ExecutionContext* context = m_frontendPage->mainFrame()->document();
- return DOMFileSystem::create(context, fileSystemName, FileSystemTypeIsolated, KURL(ParsedURLString, rootURL));
-}
-
-void InspectorFrontendHost::upgradeDraggedFileSystemPermissions(DOMFileSystem* domFileSystem)
-{
- if (!m_client)
- return;
- RefPtr<JSONObject> message = JSONObject::create();
- message->setNumber("id", 0);
- message->setString("method", "upgradeDraggedFileSystemPermissions");
- RefPtr<JSONArray> params = JSONArray::create();
- message->setArray("params", params);
- params->pushString(domFileSystem->rootURL().string());
- sendMessageToEmbedder(message->toJSONString());
+ return RenderTheme::theme().activeSelectionForegroundColor().serialized();
}
bool InspectorFrontendHost::isUnderTest()
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.h
index 1bccdca379f..22fe21075b6 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.h
@@ -37,7 +37,6 @@
namespace WebCore {
class ContextMenuItem;
-class DOMFileSystem;
class Event;
class FrontendMenuProvider;
class InspectorFrontendClient;
@@ -54,7 +53,7 @@ public:
void disconnectClient();
void setZoomFactor(float);
- void inspectedURLChanged(const String&);
+ float zoomFactor();
void setInjectedScriptForOrigin(const String& origin, const String& script);
@@ -68,11 +67,10 @@ public:
String getSelectionBackgroundColor();
String getSelectionForegroundColor();
- PassRefPtr<DOMFileSystem> isolatedFileSystem(const String& fileSystemName, const String& rootURL);
- void upgradeDraggedFileSystemPermissions(DOMFileSystem*);
-
bool isUnderTest();
+ Page* frontendPage() { return m_frontendPage; }
+
private:
friend class FrontendMenuProvider;
InspectorFrontendHost(InspectorFrontendClient* client, Page* frontendPage);
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.idl b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.idl
index 467e7aa563e..058608a7114 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.idl
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorFrontendHost.idl
@@ -33,8 +33,9 @@
[
NoInterfaceObject
] interface InspectorFrontendHost {
+ // FIXME: setZoomFactor is here only for old frontends. Remove in M38.
void setZoomFactor(float zoom);
- void inspectedURLChanged(DOMString newURL);
+ float zoomFactor();
void setInjectedScriptForOrigin(DOMString origin, DOMString script);
@@ -48,13 +49,9 @@
[Custom] void recordActionTaken(unsigned long actionCode);
[Custom] void recordPanelShown(unsigned long panelCode);
- [Custom] void recordSettingChanged(unsigned long settingChanged);
DOMString getSelectionBackgroundColor();
DOMString getSelectionForegroundColor();
- DOMFileSystem isolatedFileSystem(DOMString fileSystemId, DOMString registeredName);
- void upgradeDraggedFileSystemPermissions(DOMFileSystem domFileSystem);
-
boolean isUnderTest();
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp
index fd67c240bc1..1e556282bd7 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.cpp
@@ -32,7 +32,6 @@
#include "core/inspector/InspectorHeapProfilerAgent.h"
#include "bindings/v8/ScriptProfiler.h"
-#include "bindings/v8/ScriptScope.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptHost.h"
#include "core/inspector/InspectorState.h"
@@ -41,8 +40,12 @@
namespace WebCore {
+typedef uint32_t SnapshotObjectId;
+
namespace HeapProfilerAgentState {
static const char heapProfilerEnabled[] = "heapProfilerEnabled";
+static const char heapObjectsTrackingEnabled[] = "heapObjectsTrackingEnabled";
+static const char allocationTrackingEnabled[] = "allocationTrackingEnabled";
}
class InspectorHeapProfilerAgent::HeapStatsUpdateTask {
@@ -57,13 +60,13 @@ private:
Timer<HeapStatsUpdateTask> m_timer;
};
-PassOwnPtr<InspectorHeapProfilerAgent> InspectorHeapProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager)
+PassOwnPtr<InspectorHeapProfilerAgent> InspectorHeapProfilerAgent::create(InjectedScriptManager* injectedScriptManager)
{
- return adoptPtr(new InspectorHeapProfilerAgent(instrumentingAgents, inspectorState, injectedScriptManager));
+ return adoptPtr(new InspectorHeapProfilerAgent(injectedScriptManager));
}
-InspectorHeapProfilerAgent::InspectorHeapProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager)
- : InspectorBaseAgent<InspectorHeapProfilerAgent>("HeapProfiler", instrumentingAgents, inspectorState)
+InspectorHeapProfilerAgent::InspectorHeapProfilerAgent(InjectedScriptManager* injectedScriptManager)
+ : InspectorBaseAgent<InspectorHeapProfilerAgent>("HeapProfiler")
, m_injectedScriptManager(injectedScriptManager)
, m_frontend(0)
, m_nextUserInitiatedHeapSnapshotNumber(1)
@@ -74,25 +77,6 @@ InspectorHeapProfilerAgent::~InspectorHeapProfilerAgent()
{
}
-void InspectorHeapProfilerAgent::clearProfiles(ErrorString*)
-{
- m_snapshots.clear();
- m_nextUserInitiatedHeapSnapshotNumber = 1;
- stopTrackingHeapObjectsInternal();
- resetFrontendProfiles();
- m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
-}
-
-void InspectorHeapProfilerAgent::resetFrontendProfiles()
-{
- if (!m_frontend)
- return;
- if (!m_state->getBoolean(HeapProfilerAgentState::heapProfilerEnabled))
- return;
- if (m_snapshots.isEmpty())
- m_frontend->resetProfiles();
-}
-
void InspectorHeapProfilerAgent::setFrontend(InspectorFrontend* frontend)
{
m_frontend = frontend->heapprofiler();
@@ -101,14 +85,21 @@ void InspectorHeapProfilerAgent::setFrontend(InspectorFrontend* frontend)
void InspectorHeapProfilerAgent::clearFrontend()
{
m_frontend = 0;
+
+ m_nextUserInitiatedHeapSnapshotNumber = 1;
+ stopTrackingHeapObjectsInternal();
+ m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
+
ErrorString error;
- clearProfiles(&error);
disable(&error);
}
void InspectorHeapProfilerAgent::restore()
{
- resetFrontendProfiles();
+ if (m_state->getBoolean(HeapProfilerAgentState::heapProfilerEnabled))
+ m_frontend->resetProfiles();
+ if (m_state->getBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled))
+ startTrackingHeapObjectsInternal(m_state->getBoolean(HeapProfilerAgentState::allocationTrackingEnabled));
}
void InspectorHeapProfilerAgent::collectGarbage(WebCore::ErrorString*)
@@ -116,15 +107,6 @@ void InspectorHeapProfilerAgent::collectGarbage(WebCore::ErrorString*)
ScriptProfiler::collectGarbage();
}
-PassRefPtr<TypeBuilder::HeapProfiler::ProfileHeader> InspectorHeapProfilerAgent::createSnapshotHeader(const ScriptHeapSnapshot& snapshot)
-{
- RefPtr<TypeBuilder::HeapProfiler::ProfileHeader> header = TypeBuilder::HeapProfiler::ProfileHeader::create()
- .setUid(snapshot.uid())
- .setTitle(snapshot.title());
- header->setMaxJSObjectId(snapshot.maxSnapshotJSObjectId());
- return header.release();
-}
-
InspectorHeapProfilerAgent::HeapStatsUpdateTask::HeapStatsUpdateTask(InspectorHeapProfilerAgent* heapProfilerAgent)
: m_heapProfilerAgent(heapProfilerAgent)
, m_timer(this, &HeapStatsUpdateTask::onTimer)
@@ -141,10 +123,10 @@ void InspectorHeapProfilerAgent::HeapStatsUpdateTask::onTimer(Timer<HeapStatsUpd
void InspectorHeapProfilerAgent::HeapStatsUpdateTask::startTimer()
{
ASSERT(!m_timer.isActive());
- m_timer.startRepeating(0.05);
+ m_timer.startRepeating(0.05, FROM_HERE);
}
-class InspectorHeapProfilerAgent::HeapStatsStream : public ScriptProfiler::OutputStream {
+class InspectorHeapProfilerAgent::HeapStatsStream FINAL : public ScriptProfiler::OutputStream {
public:
HeapStatsStream(InspectorHeapProfilerAgent* heapProfilerAgent)
: m_heapProfilerAgent(heapProfilerAgent)
@@ -161,13 +143,12 @@ private:
InspectorHeapProfilerAgent* m_heapProfilerAgent;
};
-void InspectorHeapProfilerAgent::startTrackingHeapObjects(ErrorString*)
+void InspectorHeapProfilerAgent::startTrackingHeapObjects(ErrorString*, const bool* trackAllocations)
{
- if (m_heapStatsUpdateTask)
- return;
- ScriptProfiler::startTrackingHeapObjects();
- m_heapStatsUpdateTask = adoptPtr(new HeapStatsUpdateTask(this));
- m_heapStatsUpdateTask->startTimer();
+ m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, true);
+ bool allocationTrackingEnabled = trackAllocations && *trackAllocations;
+ m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, allocationTrackingEnabled);
+ startTrackingHeapObjectsInternal(allocationTrackingEnabled);
}
void InspectorHeapProfilerAgent::requestHeapStatsUpdate()
@@ -200,6 +181,15 @@ void InspectorHeapProfilerAgent::stopTrackingHeapObjects(ErrorString* error, con
stopTrackingHeapObjectsInternal();
}
+void InspectorHeapProfilerAgent::startTrackingHeapObjectsInternal(bool trackAllocations)
+{
+ if (m_heapStatsUpdateTask)
+ return;
+ ScriptProfiler::startTrackingHeapObjects(trackAllocations);
+ m_heapStatsUpdateTask = adoptPtr(new HeapStatsUpdateTask(this));
+ m_heapStatsUpdateTask->startTimer();
+}
+
void InspectorHeapProfilerAgent::stopTrackingHeapObjectsInternal()
{
if (!m_heapStatsUpdateTask)
@@ -207,6 +197,8 @@ void InspectorHeapProfilerAgent::stopTrackingHeapObjectsInternal()
ScriptProfiler::stopTrackingHeapObjects();
m_heapStatsUpdateTask->resetTimer();
m_heapStatsUpdateTask.clear();
+ m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, false);
+ m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, false);
}
void InspectorHeapProfilerAgent::enable(ErrorString*)
@@ -217,59 +209,36 @@ void InspectorHeapProfilerAgent::enable(ErrorString*)
void InspectorHeapProfilerAgent::disable(ErrorString* error)
{
stopTrackingHeapObjectsInternal();
+ ScriptProfiler::clearHeapObjectIds();
m_state->setBoolean(HeapProfilerAgentState::heapProfilerEnabled, false);
}
-void InspectorHeapProfilerAgent::getHeapSnapshot(ErrorString* errorString, int rawUid)
+void InspectorHeapProfilerAgent::takeHeapSnapshot(ErrorString* errorString, const bool* reportProgress)
{
- class OutputStream : public ScriptHeapSnapshot::OutputStream {
- public:
- OutputStream(InspectorFrontend::HeapProfiler* frontend, unsigned uid)
- : m_frontend(frontend), m_uid(uid) { }
- void Write(const String& chunk) { m_frontend->addHeapSnapshotChunk(m_uid, chunk); }
- void Close() { }
- private:
- InspectorFrontend::HeapProfiler* m_frontend;
- int m_uid;
- };
-
- unsigned uid = static_cast<unsigned>(rawUid);
- IdToHeapSnapshotMap::iterator it = m_snapshots.find(uid);
- if (it == m_snapshots.end()) {
- *errorString = "Profile wasn't found";
- return;
- }
- RefPtr<ScriptHeapSnapshot> snapshot = it->value;
- if (m_frontend) {
- OutputStream stream(m_frontend, uid);
- snapshot->writeJSON(&stream);
- }
-}
-
-void InspectorHeapProfilerAgent::removeProfile(ErrorString*, int rawUid)
-{
- unsigned uid = static_cast<unsigned>(rawUid);
- if (m_snapshots.contains(uid))
- m_snapshots.remove(uid);
-}
-
-void InspectorHeapProfilerAgent::takeHeapSnapshot(ErrorString*, const bool* reportProgress)
-{
- class HeapSnapshotProgress: public ScriptProfiler::HeapSnapshotProgress {
+ class HeapSnapshotProgress FINAL : public ScriptProfiler::HeapSnapshotProgress {
public:
explicit HeapSnapshotProgress(InspectorFrontend::HeapProfiler* frontend)
: m_frontend(frontend) { }
- void Start(int totalWork)
+ virtual void Start(int totalWork) OVERRIDE
{
m_totalWork = totalWork;
}
- void Worked(int workDone)
+ virtual void Worked(int workDone) OVERRIDE
{
- if (m_frontend)
- m_frontend->reportHeapSnapshotProgress(workDone, m_totalWork);
+ if (m_frontend) {
+ m_frontend->reportHeapSnapshotProgress(workDone, m_totalWork, 0);
+ m_frontend->flush();
+ }
}
- void Done() { }
- bool isCanceled() { return false; }
+ virtual void Done() OVERRIDE
+ {
+ const bool finished = true;
+ if (m_frontend) {
+ m_frontend->reportHeapSnapshotProgress(m_totalWork, m_totalWork, &finished);
+ m_frontend->flush();
+ }
+ }
+ virtual bool isCanceled() OVERRIDE { return false; }
private:
InspectorFrontend::HeapProfiler* m_frontend;
int m_totalWork;
@@ -278,10 +247,28 @@ void InspectorHeapProfilerAgent::takeHeapSnapshot(ErrorString*, const bool* repo
String title = "Snapshot " + String::number(m_nextUserInitiatedHeapSnapshotNumber++);
HeapSnapshotProgress progress(reportProgress && *reportProgress ? m_frontend : 0);
RefPtr<ScriptHeapSnapshot> snapshot = ScriptProfiler::takeHeapSnapshot(title, &progress);
- if (snapshot) {
- m_snapshots.add(snapshot->uid(), snapshot);
- if (m_frontend)
- m_frontend->addProfileHeader(createSnapshotHeader(*snapshot));
+ if (!snapshot) {
+ *errorString = "Failed to take heap snapshot";
+ return;
+ }
+
+ class OutputStream : public ScriptHeapSnapshot::OutputStream {
+ public:
+ explicit OutputStream(InspectorFrontend::HeapProfiler* frontend)
+ : m_frontend(frontend) { }
+ void Write(const String& chunk)
+ {
+ m_frontend->addHeapSnapshotChunk(chunk);
+ m_frontend->flush();
+ }
+ void Close() { }
+ private:
+ InspectorFrontend::HeapProfiler* m_frontend;
+ };
+
+ if (m_frontend) {
+ OutputStream stream(m_frontend);
+ snapshot->writeJSON(&stream);
}
}
@@ -293,13 +280,13 @@ void InspectorHeapProfilerAgent::getObjectByHeapObjectId(ErrorString* error, con
*error = "Invalid heap snapshot object id";
return;
}
- ScriptObject heapObject = ScriptProfiler::objectByHeapObjectId(id);
- if (heapObject.hasNoValue()) {
+ ScriptValue heapObject = ScriptProfiler::objectByHeapObjectId(id);
+ if (heapObject.isEmpty()) {
*error = "Object is not available";
return;
}
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(heapObject.scriptState());
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*error = "Object is not available. Inspected context is gone";
return;
}
@@ -311,13 +298,13 @@ void InspectorHeapProfilerAgent::getObjectByHeapObjectId(ErrorString* error, con
void InspectorHeapProfilerAgent::getHeapObjectId(ErrorString* errorString, const String& objectId, String* heapSnapshotObjectId)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected context has gone";
return;
}
ScriptValue value = injectedScript.findObjectById(objectId);
- ScriptScope scope(injectedScript.scriptState());
- if (value.hasNoValue() || value.isUndefined()) {
+ ScriptState::Scope scope(injectedScript.scriptState());
+ if (value.isEmpty() || value.isUndefined()) {
*errorString = "Object with given id not found";
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h
index 65ea5266587..bff91db5b4f 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorHeapProfilerAgent.h
@@ -31,7 +31,7 @@
#ifndef InspectorHeapProfilerAgent_h
#define InspectorHeapProfilerAgent_h
-#include "InspectorFrontend.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
@@ -48,50 +48,43 @@ class ScriptHeapSnapshot;
typedef String ErrorString;
-class InspectorHeapProfilerAgent : public InspectorBaseAgent<InspectorHeapProfilerAgent>, public InspectorBackendDispatcher::HeapProfilerCommandHandler {
+class InspectorHeapProfilerAgent FINAL : public InspectorBaseAgent<InspectorHeapProfilerAgent>, public InspectorBackendDispatcher::HeapProfilerCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorHeapProfilerAgent); WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<InspectorHeapProfilerAgent> create(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*);
+ static PassOwnPtr<InspectorHeapProfilerAgent> create(InjectedScriptManager*);
virtual ~InspectorHeapProfilerAgent();
- virtual void collectGarbage(ErrorString*);
- virtual void clearProfiles(ErrorString*);
+ virtual void collectGarbage(ErrorString*) OVERRIDE;
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void getHeapSnapshot(ErrorString*, int uid);
- virtual void removeProfile(ErrorString*, int uid);
- virtual void startTrackingHeapObjects(ErrorString*);
- virtual void stopTrackingHeapObjects(ErrorString*, const bool* reportProgress);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void startTrackingHeapObjects(ErrorString*, const bool* trackAllocations) OVERRIDE;
+ virtual void stopTrackingHeapObjects(ErrorString*, const bool* reportProgress) OVERRIDE;
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
- virtual void takeHeapSnapshot(ErrorString*, const bool* reportProgress);
+ virtual void takeHeapSnapshot(ErrorString*, const bool* reportProgress) OVERRIDE;
- virtual void getObjectByHeapObjectId(ErrorString*, const String& heapSnapshotObjectId, const String* objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& result);
- virtual void getHeapObjectId(ErrorString*, const String& objectId, String* heapSnapshotObjectId);
+ virtual void getObjectByHeapObjectId(ErrorString*, const String& heapSnapshotObjectId, const String* objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& result) OVERRIDE;
+ virtual void getHeapObjectId(ErrorString*, const String& objectId, String* heapSnapshotObjectId) OVERRIDE;
private:
class HeapStatsStream;
class HeapStatsUpdateTask;
- InspectorHeapProfilerAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*);
+ explicit InspectorHeapProfilerAgent(InjectedScriptManager*);
- typedef HashMap<unsigned, RefPtr<ScriptHeapSnapshot> > IdToHeapSnapshotMap;
-
- void resetFrontendProfiles();
void requestHeapStatsUpdate();
void pushHeapStatsUpdate(const uint32_t* const data, const int size);
- PassRefPtr<TypeBuilder::HeapProfiler::ProfileHeader> createSnapshotHeader(const ScriptHeapSnapshot&);
+ void startTrackingHeapObjectsInternal(bool trackAllocations);
void stopTrackingHeapObjectsInternal();
InjectedScriptManager* m_injectedScriptManager;
InspectorFrontend::HeapProfiler* m_frontend;
unsigned m_nextUserInitiatedHeapSnapshotNumber;
- IdToHeapSnapshotMap m_snapshots;
OwnPtr<HeapStatsUpdateTask> m_heapStatsUpdateTask;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.cpp
index e882744b084..6597d2f405d 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.cpp
@@ -39,17 +39,17 @@ namespace WebCore {
namespace {
-class UndoableStateMark : public InspectorHistory::Action {
+class UndoableStateMark FINAL : public InspectorHistory::Action {
public:
UndoableStateMark() : InspectorHistory::Action("[UndoableState]") { }
- virtual bool perform(ExceptionState&) { return true; }
+ virtual bool perform(ExceptionState&) OVERRIDE { return true; }
- virtual bool undo(ExceptionState&) { return true; }
+ virtual bool undo(ExceptionState&) OVERRIDE { return true; }
- virtual bool redo(ExceptionState&) { return true; }
+ virtual bool redo(ExceptionState&) OVERRIDE { return true; }
- virtual bool isUndoableStateMark() { return true; }
+ virtual bool isUndoableStateMark() OVERRIDE { return true; }
};
}
@@ -62,6 +62,10 @@ InspectorHistory::Action::~Action()
{
}
+void InspectorHistory::Action::trace(Visitor* visitor)
+{
+}
+
String InspectorHistory::Action::toString()
{
return m_name;
@@ -77,13 +81,13 @@ String InspectorHistory::Action::mergeId()
return "";
}
-void InspectorHistory::Action::merge(PassOwnPtr<Action>)
+void InspectorHistory::Action::merge(PassRefPtrWillBeRawPtr<Action>)
{
}
InspectorHistory::InspectorHistory() : m_afterLastActionIndex(0) { }
-bool InspectorHistory::perform(PassOwnPtr<Action> action, ExceptionState& exceptionState)
+bool InspectorHistory::perform(PassRefPtrWillBeRawPtr<Action> action, ExceptionState& exceptionState)
{
if (!action->perform(exceptionState))
return false;
@@ -100,7 +104,7 @@ bool InspectorHistory::perform(PassOwnPtr<Action> action, ExceptionState& except
void InspectorHistory::markUndoableState()
{
- perform(adoptPtr(new UndoableStateMark()), IGNORE_EXCEPTION);
+ perform(adoptRefWillBeNoop(new UndoableStateMark()), IGNORE_EXCEPTION);
}
bool InspectorHistory::undo(ExceptionState& exceptionState)
@@ -146,5 +150,10 @@ void InspectorHistory::reset()
m_history.clear();
}
+void InspectorHistory::trace(Visitor* visitor)
+{
+ visitor->trace(m_history);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.h
index 049684efcca..1b8961c21c4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorHistory.h
@@ -31,7 +31,8 @@
#ifndef InspectorHistory_h
#define InspectorHistory_h
-#include "wtf/OwnPtr.h"
+#include "platform/heap/Handle.h"
+#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
@@ -39,18 +40,20 @@ namespace WebCore {
class ExceptionState;
-class InspectorHistory FINAL {
- WTF_MAKE_NONCOPYABLE(InspectorHistory); WTF_MAKE_FAST_ALLOCATED;
+class InspectorHistory FINAL : public NoBaseWillBeGarbageCollected<InspectorHistory> {
+ WTF_MAKE_NONCOPYABLE(InspectorHistory);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- class Action {
- WTF_MAKE_FAST_ALLOCATED;
+ class Action : public RefCountedWillBeGarbageCollectedFinalized<Action> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- Action(const String& name);
+ explicit Action(const String& name);
virtual ~Action();
+ virtual void trace(Visitor*);
virtual String toString();
virtual String mergeId();
- virtual void merge(PassOwnPtr<Action>);
+ virtual void merge(PassRefPtrWillBeRawPtr<Action>);
virtual bool perform(ExceptionState&) = 0;
@@ -63,8 +66,9 @@ public:
};
InspectorHistory();
+ void trace(Visitor*);
- bool perform(PassOwnPtr<Action>, ExceptionState&);
+ bool perform(PassRefPtrWillBeRawPtr<Action>, ExceptionState&);
void markUndoableState();
bool undo(ExceptionState&);
@@ -72,7 +76,7 @@ public:
void reset();
private:
- Vector<OwnPtr<Action> > m_history;
+ WillBeHeapVector<RefPtrWillBeMember<Action> > m_history;
size_t m_afterLastActionIndex;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorIndexedDBAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorIndexedDBAgent.cpp
deleted file mode 100644
index 9ef572c68c3..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorIndexedDBAgent.cpp
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/inspector/InspectorIndexedDBAgent.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "bindings/v8/ScriptController.h"
-#include "core/dom/DOMStringList.h"
-#include "core/dom/Document.h"
-#include "core/events/Event.h"
-#include "core/events/EventListener.h"
-#include "core/inspector/InjectedScript.h"
-#include "core/inspector/InspectorPageAgent.h"
-#include "core/inspector/InspectorState.h"
-#include "core/frame/Frame.h"
-#include "modules/indexeddb/DOMWindowIndexedDatabase.h"
-#include "modules/indexeddb/IDBCursor.h"
-#include "modules/indexeddb/IDBCursorWithValue.h"
-#include "modules/indexeddb/IDBDatabase.h"
-#include "modules/indexeddb/IDBFactory.h"
-#include "modules/indexeddb/IDBIndex.h"
-#include "modules/indexeddb/IDBKey.h"
-#include "modules/indexeddb/IDBKeyPath.h"
-#include "modules/indexeddb/IDBKeyRange.h"
-#include "modules/indexeddb/IDBMetadata.h"
-#include "modules/indexeddb/IDBObjectStore.h"
-#include "modules/indexeddb/IDBOpenDBRequest.h"
-#include "modules/indexeddb/IDBPendingTransactionMonitor.h"
-#include "modules/indexeddb/IDBRequest.h"
-#include "modules/indexeddb/IDBTransaction.h"
-#include "platform/JSONValues.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "wtf/Vector.h"
-
-using WebCore::TypeBuilder::Array;
-using WebCore::TypeBuilder::IndexedDB::DatabaseWithObjectStores;
-using WebCore::TypeBuilder::IndexedDB::DataEntry;
-using WebCore::TypeBuilder::IndexedDB::Key;
-using WebCore::TypeBuilder::IndexedDB::KeyPath;
-using WebCore::TypeBuilder::IndexedDB::KeyRange;
-using WebCore::TypeBuilder::IndexedDB::ObjectStore;
-using WebCore::TypeBuilder::IndexedDB::ObjectStoreIndex;
-
-typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDatabaseNamesCallback RequestDatabaseNamesCallback;
-typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDatabaseCallback RequestDatabaseCallback;
-typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::RequestDataCallback RequestDataCallback;
-typedef WebCore::InspectorBackendDispatcher::CallbackBase RequestCallback;
-typedef WebCore::InspectorBackendDispatcher::IndexedDBCommandHandler::ClearObjectStoreCallback ClearObjectStoreCallback;
-
-namespace WebCore {
-
-namespace IndexedDBAgentState {
-static const char indexedDBAgentEnabled[] = "indexedDBAgentEnabled";
-};
-
-namespace {
-
-class GetDatabaseNamesCallback : public EventListener {
- WTF_MAKE_NONCOPYABLE(GetDatabaseNamesCallback);
-public:
- static PassRefPtr<GetDatabaseNamesCallback> create(PassRefPtr<RequestDatabaseNamesCallback> requestCallback, const String& securityOrigin)
- {
- return adoptRef(new GetDatabaseNamesCallback(requestCallback, securityOrigin));
- }
-
- virtual ~GetDatabaseNamesCallback() { }
-
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
-
- virtual void handleEvent(ExecutionContext*, Event* event) OVERRIDE
- {
- if (!m_requestCallback->isActive())
- return;
- if (event->type() != EventTypeNames::success) {
- m_requestCallback->sendFailure("Unexpected event type.");
- return;
- }
-
- IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target());
- RefPtr<IDBAny> requestResult = idbRequest->resultAsAny();
- if (requestResult->type() != IDBAny::DOMStringListType) {
- m_requestCallback->sendFailure("Unexpected result type.");
- return;
- }
-
- RefPtr<DOMStringList> databaseNamesList = requestResult->domStringList();
- RefPtr<TypeBuilder::Array<String> > databaseNames = TypeBuilder::Array<String>::create();
- for (size_t i = 0; i < databaseNamesList->length(); ++i)
- databaseNames->addItem(databaseNamesList->item(i));
- m_requestCallback->sendSuccess(databaseNames.release());
- }
-
-private:
- GetDatabaseNamesCallback(PassRefPtr<RequestDatabaseNamesCallback> requestCallback, const String& securityOrigin)
- : EventListener(EventListener::CPPEventListenerType)
- , m_requestCallback(requestCallback)
- , m_securityOrigin(securityOrigin) { }
- RefPtr<RequestDatabaseNamesCallback> m_requestCallback;
- String m_securityOrigin;
-};
-
-class ExecutableWithDatabase : public RefCounted<ExecutableWithDatabase> {
-public:
- ExecutableWithDatabase(ExecutionContext* context)
- : m_context(context) { }
- virtual ~ExecutableWithDatabase() { };
- void start(IDBFactory*, SecurityOrigin*, const String& databaseName);
- virtual void execute(PassRefPtr<IDBDatabase>) = 0;
- virtual RequestCallback* requestCallback() = 0;
- ExecutionContext* context() { return m_context; };
-private:
- ExecutionContext* m_context;
-};
-
-class OpenDatabaseCallback : public EventListener {
-public:
- static PassRefPtr<OpenDatabaseCallback> create(ExecutableWithDatabase* executableWithDatabase)
- {
- return adoptRef(new OpenDatabaseCallback(executableWithDatabase));
- }
-
- virtual ~OpenDatabaseCallback() { }
-
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
-
- virtual void handleEvent(ExecutionContext*, Event* event) OVERRIDE
- {
- if (event->type() != EventTypeNames::success) {
- m_executableWithDatabase->requestCallback()->sendFailure("Unexpected event type.");
- return;
- }
-
- IDBOpenDBRequest* idbOpenDBRequest = static_cast<IDBOpenDBRequest*>(event->target());
- RefPtr<IDBAny> requestResult = idbOpenDBRequest->resultAsAny();
- if (requestResult->type() != IDBAny::IDBDatabaseType) {
- m_executableWithDatabase->requestCallback()->sendFailure("Unexpected result type.");
- return;
- }
-
- RefPtr<IDBDatabase> idbDatabase = requestResult->idbDatabase();
- m_executableWithDatabase->execute(idbDatabase);
- IDBPendingTransactionMonitor::deactivateNewTransactions();
- idbDatabase->close();
- }
-
-private:
- OpenDatabaseCallback(ExecutableWithDatabase* executableWithDatabase)
- : EventListener(EventListener::CPPEventListenerType)
- , m_executableWithDatabase(executableWithDatabase) { }
- RefPtr<ExecutableWithDatabase> m_executableWithDatabase;
-};
-
-void ExecutableWithDatabase::start(IDBFactory* idbFactory, SecurityOrigin*, const String& databaseName)
-{
- RefPtr<OpenDatabaseCallback> callback = OpenDatabaseCallback::create(this);
- TrackExceptionState exceptionState;
- RefPtr<IDBOpenDBRequest> idbOpenDBRequest = idbFactory->open(context(), databaseName, exceptionState);
- if (exceptionState.hadException()) {
- requestCallback()->sendFailure("Could not open database.");
- return;
- }
- idbOpenDBRequest->addEventListener(EventTypeNames::success, callback, false);
-}
-
-static PassRefPtr<IDBTransaction> transactionForDatabase(ExecutionContext* executionContext, IDBDatabase* idbDatabase, const String& objectStoreName, const String& mode = IDBTransaction::modeReadOnly())
-{
- TrackExceptionState exceptionState;
- RefPtr<IDBTransaction> idbTransaction = idbDatabase->transaction(executionContext, objectStoreName, mode, exceptionState);
- if (exceptionState.hadException())
- return 0;
- return idbTransaction;
-}
-
-static PassRefPtr<IDBObjectStore> objectStoreForTransaction(IDBTransaction* idbTransaction, const String& objectStoreName)
-{
- TrackExceptionState exceptionState;
- RefPtr<IDBObjectStore> idbObjectStore = idbTransaction->objectStore(objectStoreName, exceptionState);
- if (exceptionState.hadException())
- return 0;
- return idbObjectStore;
-}
-
-static PassRefPtr<IDBIndex> indexForObjectStore(IDBObjectStore* idbObjectStore, const String& indexName)
-{
- TrackExceptionState exceptionState;
- RefPtr<IDBIndex> idbIndex = idbObjectStore->index(indexName, exceptionState);
- if (exceptionState.hadException())
- return 0;
- return idbIndex;
-}
-
-static PassRefPtr<KeyPath> keyPathFromIDBKeyPath(const IDBKeyPath& idbKeyPath)
-{
- RefPtr<KeyPath> keyPath;
- switch (idbKeyPath.type()) {
- case IDBKeyPath::NullType:
- keyPath = KeyPath::create().setType(KeyPath::Type::Null);
- break;
- case IDBKeyPath::StringType:
- keyPath = KeyPath::create().setType(KeyPath::Type::String);
- keyPath->setString(idbKeyPath.string());
- break;
- case IDBKeyPath::ArrayType: {
- keyPath = KeyPath::create().setType(KeyPath::Type::Array);
- RefPtr<TypeBuilder::Array<String> > array = TypeBuilder::Array<String>::create();
- const Vector<String>& stringArray = idbKeyPath.array();
- for (size_t i = 0; i < stringArray.size(); ++i)
- array->addItem(stringArray[i]);
- keyPath->setArray(array);
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- }
-
- return keyPath.release();
-}
-
-class DatabaseLoader : public ExecutableWithDatabase {
-public:
- static PassRefPtr<DatabaseLoader> create(ExecutionContext* context, PassRefPtr<RequestDatabaseCallback> requestCallback)
- {
- return adoptRef(new DatabaseLoader(context, requestCallback));
- }
-
- virtual ~DatabaseLoader() { }
-
- virtual void execute(PassRefPtr<IDBDatabase> prpDatabase)
- {
- RefPtr<IDBDatabase> idbDatabase = prpDatabase;
- if (!requestCallback()->isActive())
- return;
-
- const IDBDatabaseMetadata databaseMetadata = idbDatabase->metadata();
-
- RefPtr<TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStore> > objectStores = TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStore>::create();
-
- for (IDBDatabaseMetadata::ObjectStoreMap::const_iterator it = databaseMetadata.objectStores.begin(); it != databaseMetadata.objectStores.end(); ++it) {
- const IDBObjectStoreMetadata& objectStoreMetadata = it->value;
-
- RefPtr<TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStoreIndex> > indexes = TypeBuilder::Array<TypeBuilder::IndexedDB::ObjectStoreIndex>::create();
-
- for (IDBObjectStoreMetadata::IndexMap::const_iterator it = objectStoreMetadata.indexes.begin(); it != objectStoreMetadata.indexes.end(); ++it) {
- const IDBIndexMetadata& indexMetadata = it->value;
-
- RefPtr<ObjectStoreIndex> objectStoreIndex = ObjectStoreIndex::create()
- .setName(indexMetadata.name)
- .setKeyPath(keyPathFromIDBKeyPath(indexMetadata.keyPath))
- .setUnique(indexMetadata.unique)
- .setMultiEntry(indexMetadata.multiEntry);
- indexes->addItem(objectStoreIndex);
- }
-
- RefPtr<ObjectStore> objectStore = ObjectStore::create()
- .setName(objectStoreMetadata.name)
- .setKeyPath(keyPathFromIDBKeyPath(objectStoreMetadata.keyPath))
- .setAutoIncrement(objectStoreMetadata.autoIncrement)
- .setIndexes(indexes);
- objectStores->addItem(objectStore);
- }
- RefPtr<DatabaseWithObjectStores> result = DatabaseWithObjectStores::create()
- .setName(databaseMetadata.name)
- .setIntVersion(databaseMetadata.intVersion)
- .setVersion(databaseMetadata.version)
- .setObjectStores(objectStores);
-
- m_requestCallback->sendSuccess(result);
- }
-
- virtual RequestCallback* requestCallback() { return m_requestCallback.get(); }
-private:
- DatabaseLoader(ExecutionContext* context, PassRefPtr<RequestDatabaseCallback> requestCallback)
- : ExecutableWithDatabase(context)
- , m_requestCallback(requestCallback) { }
- RefPtr<RequestDatabaseCallback> m_requestCallback;
-};
-
-static PassRefPtr<IDBKey> idbKeyFromInspectorObject(JSONObject* key)
-{
- RefPtr<IDBKey> idbKey;
-
- String type;
- if (!key->getString("type", &type))
- return 0;
-
- DEFINE_STATIC_LOCAL(String, number, ("number"));
- DEFINE_STATIC_LOCAL(String, string, ("string"));
- DEFINE_STATIC_LOCAL(String, date, ("date"));
- DEFINE_STATIC_LOCAL(String, array, ("array"));
-
- if (type == number) {
- double number;
- if (!key->getNumber("number", &number))
- return 0;
- idbKey = IDBKey::createNumber(number);
- } else if (type == string) {
- String string;
- if (!key->getString("string", &string))
- return 0;
- idbKey = IDBKey::createString(string);
- } else if (type == date) {
- double date;
- if (!key->getNumber("date", &date))
- return 0;
- idbKey = IDBKey::createDate(date);
- } else if (type == array) {
- IDBKey::KeyArray keyArray;
- RefPtr<JSONArray> array = key->getArray("array");
- for (size_t i = 0; i < array->length(); ++i) {
- RefPtr<JSONValue> value = array->get(i);
- RefPtr<JSONObject> object;
- if (!value->asObject(&object))
- return 0;
- keyArray.append(idbKeyFromInspectorObject(object.get()));
- }
- idbKey = IDBKey::createArray(keyArray);
- } else
- return 0;
-
- return idbKey.release();
-}
-
-static PassRefPtr<IDBKeyRange> idbKeyRangeFromKeyRange(JSONObject* keyRange)
-{
- RefPtr<JSONObject> lower = keyRange->getObject("lower");
- RefPtr<IDBKey> idbLower = lower ? idbKeyFromInspectorObject(lower.get()) : 0;
- if (lower && !idbLower)
- return 0;
-
- RefPtr<JSONObject> upper = keyRange->getObject("upper");
- RefPtr<IDBKey> idbUpper = upper ? idbKeyFromInspectorObject(upper.get()) : 0;
- if (upper && !idbUpper)
- return 0;
-
- bool lowerOpen;
- if (!keyRange->getBoolean("lowerOpen", &lowerOpen))
- return 0;
- IDBKeyRange::LowerBoundType lowerBoundType = lowerOpen ? IDBKeyRange::LowerBoundOpen : IDBKeyRange::LowerBoundClosed;
-
- bool upperOpen;
- if (!keyRange->getBoolean("upperOpen", &upperOpen))
- return 0;
- IDBKeyRange::UpperBoundType upperBoundType = upperOpen ? IDBKeyRange::UpperBoundOpen : IDBKeyRange::UpperBoundClosed;
-
- RefPtr<IDBKeyRange> idbKeyRange = IDBKeyRange::create(idbLower, idbUpper, lowerBoundType, upperBoundType);
- return idbKeyRange.release();
-}
-
-class DataLoader;
-
-class OpenCursorCallback : public EventListener {
-public:
- static PassRefPtr<OpenCursorCallback> create(InjectedScript injectedScript, PassRefPtr<RequestDataCallback> requestCallback, int skipCount, unsigned pageSize)
- {
- return adoptRef(new OpenCursorCallback(injectedScript, requestCallback, skipCount, pageSize));
- }
-
- virtual ~OpenCursorCallback() { }
-
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
-
- virtual void handleEvent(ExecutionContext* context, Event* event) OVERRIDE
- {
- if (event->type() != EventTypeNames::success) {
- m_requestCallback->sendFailure("Unexpected event type.");
- return;
- }
-
- IDBRequest* idbRequest = static_cast<IDBRequest*>(event->target());
- RefPtr<IDBAny> requestResult = idbRequest->resultAsAny();
- if (requestResult->type() == IDBAny::BufferType) {
- end(false);
- return;
- }
- if (requestResult->type() != IDBAny::IDBCursorWithValueType) {
- m_requestCallback->sendFailure("Unexpected result type.");
- return;
- }
-
- RefPtr<IDBCursorWithValue> idbCursor = requestResult->idbCursorWithValue();
-
- if (m_skipCount) {
- TrackExceptionState exceptionState;
- idbCursor->advance(m_skipCount, exceptionState);
- if (exceptionState.hadException())
- m_requestCallback->sendFailure("Could not advance cursor.");
- m_skipCount = 0;
- return;
- }
-
- if (m_result->length() == m_pageSize) {
- end(true);
- return;
- }
-
- // Continue cursor before making injected script calls, otherwise transaction might be finished.
- TrackExceptionState exceptionState;
- idbCursor->continueFunction(0, 0, exceptionState);
- if (exceptionState.hadException()) {
- m_requestCallback->sendFailure("Could not continue cursor.");
- return;
- }
-
- RefPtr<DataEntry> dataEntry = DataEntry::create()
- .setKey(m_injectedScript.wrapObject(idbCursor->key(context), String()))
- .setPrimaryKey(m_injectedScript.wrapObject(idbCursor->primaryKey(context), String()))
- .setValue(m_injectedScript.wrapObject(idbCursor->value(context), String()));
- m_result->addItem(dataEntry);
-
- }
-
- void end(bool hasMore)
- {
- if (!m_requestCallback->isActive())
- return;
- m_requestCallback->sendSuccess(m_result.release(), hasMore);
- }
-
-private:
- OpenCursorCallback(InjectedScript injectedScript, PassRefPtr<RequestDataCallback> requestCallback, int skipCount, unsigned pageSize)
- : EventListener(EventListener::CPPEventListenerType)
- , m_injectedScript(injectedScript)
- , m_requestCallback(requestCallback)
- , m_skipCount(skipCount)
- , m_pageSize(pageSize)
- {
- m_result = Array<DataEntry>::create();
- }
- InjectedScript m_injectedScript;
- RefPtr<RequestDataCallback> m_requestCallback;
- int m_skipCount;
- unsigned m_pageSize;
- RefPtr<Array<DataEntry> > m_result;
-};
-
-class DataLoader : public ExecutableWithDatabase {
-public:
- static PassRefPtr<DataLoader> create(ExecutionContext* context, PassRefPtr<RequestDataCallback> requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, PassRefPtr<IDBKeyRange> idbKeyRange, int skipCount, unsigned pageSize)
- {
- return adoptRef(new DataLoader(context, requestCallback, injectedScript, objectStoreName, indexName, idbKeyRange, skipCount, pageSize));
- }
-
- virtual ~DataLoader() { }
-
- virtual void execute(PassRefPtr<IDBDatabase> prpDatabase)
- {
- RefPtr<IDBDatabase> idbDatabase = prpDatabase;
- if (!requestCallback()->isActive())
- return;
- RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context(), idbDatabase.get(), m_objectStoreName);
- if (!idbTransaction) {
- m_requestCallback->sendFailure("Could not get transaction");
- return;
- }
- RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName);
- if (!idbObjectStore) {
- m_requestCallback->sendFailure("Could not get object store");
- return;
- }
-
- RefPtr<OpenCursorCallback> openCursorCallback = OpenCursorCallback::create(m_injectedScript, m_requestCallback, m_skipCount, m_pageSize);
-
- RefPtr<IDBRequest> idbRequest;
- if (!m_indexName.isEmpty()) {
- RefPtr<IDBIndex> idbIndex = indexForObjectStore(idbObjectStore.get(), m_indexName);
- if (!idbIndex) {
- m_requestCallback->sendFailure("Could not get index");
- return;
- }
-
- idbRequest = idbIndex->openCursor(context(), PassRefPtr<IDBKeyRange>(m_idbKeyRange), IndexedDB::CursorNext);
- } else {
- idbRequest = idbObjectStore->openCursor(context(), PassRefPtr<IDBKeyRange>(m_idbKeyRange), IndexedDB::CursorNext);
- }
- idbRequest->addEventListener(EventTypeNames::success, openCursorCallback, false);
- }
-
- virtual RequestCallback* requestCallback() { return m_requestCallback.get(); }
- DataLoader(ExecutionContext* executionContext, PassRefPtr<RequestDataCallback> requestCallback, const InjectedScript& injectedScript, const String& objectStoreName, const String& indexName, PassRefPtr<IDBKeyRange> idbKeyRange, int skipCount, unsigned pageSize)
- : ExecutableWithDatabase(executionContext)
- , m_requestCallback(requestCallback)
- , m_injectedScript(injectedScript)
- , m_objectStoreName(objectStoreName)
- , m_indexName(indexName)
- , m_idbKeyRange(idbKeyRange)
- , m_skipCount(skipCount)
- , m_pageSize(pageSize) { }
- RefPtr<RequestDataCallback> m_requestCallback;
- InjectedScript m_injectedScript;
- String m_objectStoreName;
- String m_indexName;
- RefPtr<IDBKeyRange> m_idbKeyRange;
- int m_skipCount;
- unsigned m_pageSize;
-};
-
-} // namespace
-
-InspectorIndexedDBAgent::InspectorIndexedDBAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, InspectorPageAgent* pageAgent)
- : InspectorBaseAgent<InspectorIndexedDBAgent>("IndexedDB", instrumentingAgents, state)
- , m_injectedScriptManager(injectedScriptManager)
- , m_pageAgent(pageAgent)
-{
-}
-
-InspectorIndexedDBAgent::~InspectorIndexedDBAgent()
-{
-}
-
-void InspectorIndexedDBAgent::clearFrontend()
-{
- disable(0);
-}
-
-void InspectorIndexedDBAgent::restore()
-{
- if (m_state->getBoolean(IndexedDBAgentState::indexedDBAgentEnabled)) {
- ErrorString error;
- enable(&error);
- }
-}
-
-void InspectorIndexedDBAgent::enable(ErrorString*)
-{
- m_state->setBoolean(IndexedDBAgentState::indexedDBAgentEnabled, true);
-}
-
-void InspectorIndexedDBAgent::disable(ErrorString*)
-{
- m_state->setBoolean(IndexedDBAgentState::indexedDBAgentEnabled, false);
-}
-
-static Document* assertDocument(ErrorString* errorString, Frame* frame)
-{
- Document* document = frame ? frame->document() : 0;
-
- if (!document)
- *errorString = "No document for given frame found";
-
- return document;
-}
-
-static IDBFactory* assertIDBFactory(ErrorString* errorString, Document* document)
-{
- DOMWindow* domWindow = document->domWindow();
- if (!domWindow) {
- *errorString = "No IndexedDB factory for given frame found";
- return 0;
- }
- IDBFactory* idbFactory = DOMWindowIndexedDatabase::indexedDB(domWindow);
-
- if (!idbFactory)
- *errorString = "No IndexedDB factory for given frame found";
-
- return idbFactory;
-}
-
-void InspectorIndexedDBAgent::requestDatabaseNames(ErrorString* errorString, const String& securityOrigin, PassRefPtr<RequestDatabaseNamesCallback> requestCallback)
-{
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
- Document* document = assertDocument(errorString, frame);
- if (!document)
- return;
- IDBFactory* idbFactory = assertIDBFactory(errorString, document);
- if (!idbFactory)
- return;
-
- // FIXME: This should probably use ScriptState/ScriptScope instead of V8 API
- v8::HandleScope handleScope(toIsolate(frame));
- v8::Handle<v8::Context> context = document->frame()->script().mainWorldContext();
- ASSERT(!context.IsEmpty());
- v8::Context::Scope contextScope(context);
-
- TrackExceptionState exceptionState;
- RefPtr<IDBRequest> idbRequest = idbFactory->getDatabaseNames(document, exceptionState);
- if (exceptionState.hadException()) {
- requestCallback->sendFailure("Could not obtain database names.");
- return;
- }
- idbRequest->addEventListener(EventTypeNames::success, GetDatabaseNamesCallback::create(requestCallback, document->securityOrigin()->toRawString()), false);
-}
-
-void InspectorIndexedDBAgent::requestDatabase(ErrorString* errorString, const String& securityOrigin, const String& databaseName, PassRefPtr<RequestDatabaseCallback> requestCallback)
-{
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
- Document* document = assertDocument(errorString, frame);
- if (!document)
- return;
- IDBFactory* idbFactory = assertIDBFactory(errorString, document);
- if (!idbFactory)
- return;
-
- // FIXME: This should probably use ScriptState/ScriptScope instead of V8 API
- v8::HandleScope handleScope(toIsolate(frame));
- v8::Handle<v8::Context> context = document->frame()->script().mainWorldContext();
- ASSERT(!context.IsEmpty());
- v8::Context::Scope contextScope(context);
-
- RefPtr<DatabaseLoader> databaseLoader = DatabaseLoader::create(document, requestCallback);
- databaseLoader->start(idbFactory, document->securityOrigin(), databaseName);
-}
-
-void InspectorIndexedDBAgent::requestData(ErrorString* errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const RefPtr<JSONObject>* keyRange, PassRefPtr<RequestDataCallback> requestCallback)
-{
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
- Document* document = assertDocument(errorString, frame);
- if (!document)
- return;
- IDBFactory* idbFactory = assertIDBFactory(errorString, document);
- if (!idbFactory)
- return;
-
- InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(mainWorldScriptState(frame));
-
- RefPtr<IDBKeyRange> idbKeyRange = keyRange ? idbKeyRangeFromKeyRange(keyRange->get()) : 0;
- if (keyRange && !idbKeyRange) {
- *errorString = "Can not parse key range.";
- return;
- }
-
- // FIXME: This should probably use ScriptState/ScriptScope instead of V8 API
- v8::HandleScope handleScope(toIsolate(frame));
- v8::Handle<v8::Context> context = document->frame()->script().mainWorldContext();
- ASSERT(!context.IsEmpty());
- v8::Context::Scope contextScope(context);
-
- RefPtr<DataLoader> dataLoader = DataLoader::create(document, requestCallback, injectedScript, objectStoreName, indexName, idbKeyRange, skipCount, pageSize);
- dataLoader->start(idbFactory, document->securityOrigin(), databaseName);
-}
-
-class ClearObjectStoreListener : public EventListener {
- WTF_MAKE_NONCOPYABLE(ClearObjectStoreListener);
-public:
- static PassRefPtr<ClearObjectStoreListener> create(PassRefPtr<ClearObjectStoreCallback> requestCallback)
- {
- return adoptRef(new ClearObjectStoreListener(requestCallback));
- }
-
- virtual ~ClearObjectStoreListener() { }
-
- virtual bool operator==(const EventListener& other) OVERRIDE
- {
- return this == &other;
- }
-
- virtual void handleEvent(ExecutionContext*, Event* event) OVERRIDE
- {
- if (!m_requestCallback->isActive())
- return;
- if (event->type() != EventTypeNames::complete) {
- m_requestCallback->sendFailure("Unexpected event type.");
- return;
- }
-
- m_requestCallback->sendSuccess();
- }
-private:
- ClearObjectStoreListener(PassRefPtr<ClearObjectStoreCallback> requestCallback)
- : EventListener(EventListener::CPPEventListenerType)
- , m_requestCallback(requestCallback)
- {
- }
-
- RefPtr<ClearObjectStoreCallback> m_requestCallback;
-};
-
-
-class ClearObjectStore : public ExecutableWithDatabase {
-public:
- static PassRefPtr<ClearObjectStore> create(ExecutionContext* context, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback)
- {
- return adoptRef(new ClearObjectStore(context, objectStoreName, requestCallback));
- }
-
- ClearObjectStore(ExecutionContext* context, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback)
- : ExecutableWithDatabase(context)
- , m_objectStoreName(objectStoreName)
- , m_requestCallback(requestCallback)
- {
- }
-
- virtual void execute(PassRefPtr<IDBDatabase> prpDatabase)
- {
- RefPtr<IDBDatabase> idbDatabase = prpDatabase;
- if (!requestCallback()->isActive())
- return;
- RefPtr<IDBTransaction> idbTransaction = transactionForDatabase(context(), idbDatabase.get(), m_objectStoreName, IDBTransaction::modeReadWrite());
- if (!idbTransaction) {
- m_requestCallback->sendFailure("Could not get transaction");
- return;
- }
- RefPtr<IDBObjectStore> idbObjectStore = objectStoreForTransaction(idbTransaction.get(), m_objectStoreName);
- if (!idbObjectStore) {
- m_requestCallback->sendFailure("Could not get object store");
- return;
- }
-
- TrackExceptionState exceptionState;
- RefPtr<IDBRequest> idbRequest = idbObjectStore->clear(context(), exceptionState);
- ASSERT(!exceptionState.hadException());
- if (exceptionState.hadException()) {
- ExceptionCode ec = exceptionState.code();
- m_requestCallback->sendFailure(String::format("Could not clear object store '%s': %d", m_objectStoreName.utf8().data(), ec));
- return;
- }
- idbTransaction->addEventListener(EventTypeNames::complete, ClearObjectStoreListener::create(m_requestCallback), false);
- }
-
- virtual RequestCallback* requestCallback() { return m_requestCallback.get(); }
-private:
- const String m_objectStoreName;
- RefPtr<ClearObjectStoreCallback> m_requestCallback;
-};
-
-void InspectorIndexedDBAgent::clearObjectStore(ErrorString* errorString, const String& securityOrigin, const String& databaseName, const String& objectStoreName, PassRefPtr<ClearObjectStoreCallback> requestCallback)
-{
- Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
- Document* document = assertDocument(errorString, frame);
- if (!document)
- return;
- IDBFactory* idbFactory = assertIDBFactory(errorString, document);
- if (!idbFactory)
- return;
-
- // FIXME: This should probably use ScriptState/ScriptScope instead of V8 API
- v8::HandleScope handleScope(toIsolate(frame));
- v8::Handle<v8::Context> context = document->frame()->script().mainWorldContext();
- ASSERT(!context.IsEmpty());
- v8::Context::Scope contextScope(context);
-
- RefPtr<ClearObjectStore> clearObjectStore = ClearObjectStore::create(document, objectStoreName, requestCallback);
- clearObjectStore->start(idbFactory, document->securityOrigin(), databaseName);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorIndexedDBAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorIndexedDBAgent.h
deleted file mode 100644
index 237af20aa55..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorIndexedDBAgent.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorIndexedDBAgent_h
-#define InspectorIndexedDBAgent_h
-
-#include "core/inspector/InspectorBaseAgent.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class InjectedScriptManager;
-class InspectorPageAgent;
-
-typedef String ErrorString;
-
-class InspectorIndexedDBAgent : public InspectorBaseAgent<InspectorIndexedDBAgent>, public InspectorBackendDispatcher::IndexedDBCommandHandler {
-public:
- static PassOwnPtr<InspectorIndexedDBAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, InspectorPageAgent* pageAgent)
- {
- return adoptPtr(new InspectorIndexedDBAgent(instrumentingAgents, state, injectedScriptManager, pageAgent));
- }
- ~InspectorIndexedDBAgent();
-
- virtual void clearFrontend();
- virtual void restore();
-
- // Called from the front-end.
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void requestDatabaseNames(ErrorString*, const String& securityOrigin, PassRefPtr<RequestDatabaseNamesCallback>);
- virtual void requestDatabase(ErrorString*, const String& securityOrigin, const String& databaseName, PassRefPtr<RequestDatabaseCallback>);
- virtual void requestData(ErrorString*, const String& securityOrigin, const String& databaseName, const String& objectStoreName, const String& indexName, int skipCount, int pageSize, const RefPtr<JSONObject>* keyRange, PassRefPtr<RequestDataCallback>);
- virtual void clearObjectStore(ErrorString*, const String& in_securityOrigin, const String& in_databaseName, const String& in_objectStoreName, PassRefPtr<ClearObjectStoreCallback>);
-
-private:
- InspectorIndexedDBAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*, InspectorPageAgent*);
-
- InjectedScriptManager* m_injectedScriptManager;
- InspectorPageAgent* m_pageAgent;
-};
-
-} // namespace WebCore
-
-#endif // !defined(InspectorIndexedDBAgent_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp
index 342f9adedb0..7a7b114d091 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp
@@ -31,17 +31,18 @@
#include "config.h"
#include "core/inspector/InspectorInputAgent.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/InspectorClient.h"
#include "core/page/Chrome.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "platform/JSONValues.h"
#include "platform/PlatformKeyboardEvent.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/PlatformTouchEvent.h"
#include "platform/PlatformTouchPoint.h"
+#include "platform/geometry/FloatSize.h"
#include "platform/geometry/IntPoint.h"
#include "platform/geometry/IntRect.h"
#include "platform/geometry/IntSize.h"
@@ -57,8 +58,7 @@ public:
m_screenPos = screenPos;
m_pos = pos;
m_state = state;
- m_radiusY = radiusY;
- m_radiusX = radiusX;
+ m_radius = WebCore::FloatSize(radiusX, radiusY);
m_rotationAngle = rotationAngle;
m_force = force;
}
@@ -81,7 +81,7 @@ public:
void ConvertInspectorPoint(WebCore::Page* page, const WebCore::IntPoint& point, WebCore::IntPoint* convertedPoint, WebCore::IntPoint* globalPoint)
{
- *convertedPoint = page->mainFrame()->view()->convertToContainingWindow(point);
+ *convertedPoint = page->deprecatedLocalMainFrame()->view()->convertToContainingWindow(point);
*globalPoint = page->chrome().rootViewToScreen(WebCore::IntRect(point, WebCore::IntSize(0, 0))).location();
}
@@ -89,8 +89,8 @@ void ConvertInspectorPoint(WebCore::Page* page, const WebCore::IntPoint& point,
namespace WebCore {
-InspectorInputAgent::InspectorInputAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, Page* page, InspectorClient* client)
- : InspectorBaseAgent<InspectorInputAgent>("Input", instrumentingAgents, inspectorState)
+InspectorInputAgent::InspectorInputAgent(Page* page, InspectorClient* client)
+ : InspectorBaseAgent<InspectorInputAgent>("Input")
, m_page(page), m_client(client)
{
}
@@ -99,7 +99,7 @@ InspectorInputAgent::~InspectorInputAgent()
{
}
-void InspectorInputAgent::dispatchKeyEvent(ErrorString* error, const String& type, const int* modifiers, const double* timestamp, const String* text, const String* unmodifiedText, const String* keyIdentifier, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const int* macCharCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey)
+void InspectorInputAgent::dispatchKeyEvent(ErrorString* error, const String& type, const int* modifiers, const double* timestamp, const String* text, const String* unmodifiedText, const String* keyIdentifier, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey)
{
PlatformEvent::Type convertedType;
if (type == "keyDown")
@@ -122,7 +122,6 @@ void InspectorInputAgent::dispatchKeyEvent(ErrorString* error, const String& typ
keyIdentifier ? *keyIdentifier : "",
windowsVirtualKeyCode ? *windowsVirtualKeyCode : 0,
nativeVirtualKeyCode ? *nativeVirtualKeyCode : 0,
- macCharCode ? *macCharCode : 0,
autoRepeat ? *autoRepeat : false,
isKeypad ? *isKeypad : false,
isSystemKey ? *isSystemKey : false,
@@ -268,12 +267,7 @@ void InspectorInputAgent::dispatchTouchEvent(ErrorString* error, const String& t
event.append(point);
}
- m_page->mainFrame()->eventHandler().handleTouchEvent(event);
-}
-
-void InspectorInputAgent::dispatchGestureEvent(ErrorString*, const String& type, int x, int y, const double* timestamp, const int* deltaX, const int* deltaY, const double* scale)
-{
- // Handled on the browser level.
+ m_page->deprecatedLocalMainFrame()->eventHandler().handleTouchEvent(event);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h
index 4ae8753a526..95543eccc94 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorInputAgent.h
@@ -42,23 +42,22 @@ class Page;
typedef String ErrorString;
-class InspectorInputAgent : public InspectorBaseAgent<InspectorInputAgent>, public InspectorBackendDispatcher::InputCommandHandler {
+class InspectorInputAgent FINAL : public InspectorBaseAgent<InspectorInputAgent>, public InspectorBackendDispatcher::InputCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorInputAgent);
public:
- static PassOwnPtr<InspectorInputAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, Page* page, InspectorClient* client)
+ static PassOwnPtr<InspectorInputAgent> create(Page* page, InspectorClient* client)
{
- return adoptPtr(new InspectorInputAgent(instrumentingAgents, inspectorState, page, client));
+ return adoptPtr(new InspectorInputAgent(page, client));
}
- ~InspectorInputAgent();
+ virtual ~InspectorInputAgent();
// Methods called from the frontend for simulating input.
- virtual void dispatchKeyEvent(ErrorString*, const String& type, const int* modifiers, const double* timestamp, const String* text, const String* unmodifiedText, const String* keyIdentifier, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const int* macCharCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey);
- virtual void dispatchMouseEvent(ErrorString*, const String& type, int x, int y, const int* modifiers, const double* timestamp, const String* button, const int* clickCount, const bool* deviceSpace);
- virtual void dispatchTouchEvent(ErrorString*, const String& type, const RefPtr<JSONArray>& touchPoints, const int* modifiers, const double* timestamp);
- virtual void dispatchGestureEvent(ErrorString*, const String& type, int x, int y, const double* timestamp, const int* deltaX, const int* deltaY, const double* scale);
+ virtual void dispatchKeyEvent(ErrorString*, const String& type, const int* modifiers, const double* timestamp, const String* text, const String* unmodifiedText, const String* keyIdentifier, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey) OVERRIDE;
+ virtual void dispatchMouseEvent(ErrorString*, const String& type, int x, int y, const int* modifiers, const double* timestamp, const String* button, const int* clickCount, const bool* deviceSpace) OVERRIDE;
+ virtual void dispatchTouchEvent(ErrorString*, const String& type, const RefPtr<JSONArray>& touchPoints, const int* modifiers, const double* timestamp) OVERRIDE;
private:
- InspectorInputAgent(InstrumentingAgents*, InspectorCompositeState*, Page*, InspectorClient*);
+ InspectorInputAgent(Page*, InspectorClient*);
Page* m_page;
InspectorClient* m_client;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorInspectorAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorInspectorAgent.cpp
new file mode 100644
index 00000000000..7520307e372
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorInspectorAgent.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/inspector/InspectorInspectorAgent.h"
+
+#include "bindings/v8/DOMWrapperWorld.h"
+#include "bindings/v8/ScriptController.h"
+#include "core/InspectorFrontend.h"
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/inspector/InjectedScriptHost.h"
+#include "core/inspector/InjectedScriptManager.h"
+#include "core/inspector/InspectorController.h"
+#include "core/inspector/InspectorState.h"
+#include "core/inspector/InstrumentingAgents.h"
+#include "core/loader/DocumentLoader.h"
+#include "core/page/Page.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "wtf/text/StringBuilder.h"
+
+namespace WebCore {
+
+namespace InspectorAgentState {
+static const char inspectorAgentEnabled[] = "inspectorAgentEnabled";
+}
+
+InspectorInspectorAgent::InspectorInspectorAgent(Page* page, InjectedScriptManager* injectedScriptManager)
+ : InspectorBaseAgent<InspectorInspectorAgent>("Inspector")
+ , m_inspectedPage(page)
+ , m_frontend(0)
+ , m_injectedScriptManager(injectedScriptManager)
+{
+ ASSERT_ARG(page, page);
+}
+
+InspectorInspectorAgent::~InspectorInspectorAgent()
+{
+ m_instrumentingAgents->setInspectorInspectorAgent(0);
+}
+
+void InspectorInspectorAgent::didClearDocumentOfWindowObject(LocalFrame* frame)
+{
+ if (m_injectedScriptForOrigin.isEmpty())
+ return;
+
+ String origin = frame->document()->securityOrigin()->toRawString();
+ String script = m_injectedScriptForOrigin.get(origin);
+ if (script.isEmpty())
+ return;
+ int injectedScriptId = m_injectedScriptManager->injectedScriptIdFor(ScriptState::forMainWorld(frame));
+ StringBuilder scriptSource;
+ scriptSource.append(script);
+ scriptSource.append("(");
+ scriptSource.appendNumber(injectedScriptId);
+ scriptSource.append(")");
+ frame->script().executeScriptInMainWorld(scriptSource.toString());
+}
+
+void InspectorInspectorAgent::init()
+{
+ m_instrumentingAgents->setInspectorInspectorAgent(this);
+}
+
+void InspectorInspectorAgent::setFrontend(InspectorFrontend* inspectorFrontend)
+{
+ m_frontend = inspectorFrontend;
+}
+
+void InspectorInspectorAgent::clearFrontend()
+{
+ m_pendingEvaluateTestCommands.clear();
+ m_frontend = 0;
+ m_injectedScriptManager->discardInjectedScripts();
+ ErrorString error;
+ disable(&error);
+}
+
+void InspectorInspectorAgent::enable(ErrorString*)
+{
+ m_state->setBoolean(InspectorAgentState::inspectorAgentEnabled, true);
+
+ if (m_pendingInspectData.first)
+ inspect(m_pendingInspectData.first, m_pendingInspectData.second);
+
+ for (Vector<pair<long, String> >::iterator it = m_pendingEvaluateTestCommands.begin(); m_frontend && it != m_pendingEvaluateTestCommands.end(); ++it)
+ m_frontend->inspector()->evaluateForTestInFrontend(static_cast<int>((*it).first), (*it).second);
+ m_pendingEvaluateTestCommands.clear();
+}
+
+void InspectorInspectorAgent::disable(ErrorString*)
+{
+ m_state->setBoolean(InspectorAgentState::inspectorAgentEnabled, false);
+}
+
+void InspectorInspectorAgent::reset(ErrorString*)
+{
+ m_inspectedPage->inspectorController().reconnectFrontend();
+}
+
+void InspectorInspectorAgent::domContentLoadedEventFired(LocalFrame* frame)
+{
+ if (frame->page()->mainFrame() != frame)
+ return;
+
+ m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
+}
+
+void InspectorInspectorAgent::evaluateForTestInFrontend(long callId, const String& script)
+{
+ if (m_state->getBoolean(InspectorAgentState::inspectorAgentEnabled))
+ m_frontend->inspector()->evaluateForTestInFrontend(static_cast<int>(callId), script);
+ else
+ m_pendingEvaluateTestCommands.append(pair<long, String>(callId, script));
+}
+
+void InspectorInspectorAgent::setInjectedScriptForOrigin(const String& origin, const String& source)
+{
+ m_injectedScriptForOrigin.set(origin, source);
+}
+
+void InspectorInspectorAgent::inspect(PassRefPtr<TypeBuilder::Runtime::RemoteObject> objectToInspect, PassRefPtr<JSONObject> hints)
+{
+ if (m_state->getBoolean(InspectorAgentState::inspectorAgentEnabled) && m_frontend) {
+ m_frontend->inspector()->inspect(objectToInspect, hints);
+ m_pendingInspectData.first = nullptr;
+ m_pendingInspectData.second = nullptr;
+ return;
+ }
+ m_pendingInspectData.first = objectToInspect;
+ m_pendingInspectData.second = hints;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorInspectorAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorInspectorAgent.h
new file mode 100644
index 00000000000..adfff181ded
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorInspectorAgent.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorInspectorAgent_h
+#define InspectorInspectorAgent_h
+
+#include "core/inspector/InspectorBaseAgent.h"
+#include "wtf/HashMap.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class DOMWrapperWorld;
+class DocumentLoader;
+class LocalFrame;
+class InjectedScriptManager;
+class InspectorFrontend;
+class InstrumentingAgents;
+class JSONObject;
+class Page;
+
+typedef String ErrorString;
+
+class InspectorInspectorAgent FINAL : public InspectorBaseAgent<InspectorInspectorAgent>, public InspectorBackendDispatcher::InspectorCommandHandler {
+ WTF_MAKE_NONCOPYABLE(InspectorInspectorAgent);
+public:
+ static PassOwnPtr<InspectorInspectorAgent> create(Page* page, InjectedScriptManager* injectedScriptManager)
+ {
+ return adoptPtr(new InspectorInspectorAgent(page, injectedScriptManager));
+ }
+
+ virtual ~InspectorInspectorAgent();
+
+ // Inspector front-end API.
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void reset(ErrorString*) OVERRIDE;
+
+ virtual void init() OVERRIDE;
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+
+ void didClearDocumentOfWindowObject(LocalFrame*);
+
+ void domContentLoadedEventFired(LocalFrame*);
+
+ bool hasFrontend() const { return m_frontend; }
+
+ // Generic code called from custom implementations.
+ void evaluateForTestInFrontend(long testCallId, const String& script);
+
+ void setInjectedScriptForOrigin(const String& origin, const String& source);
+
+ void inspect(PassRefPtr<TypeBuilder::Runtime::RemoteObject> objectToInspect, PassRefPtr<JSONObject> hints);
+
+private:
+ InspectorInspectorAgent(Page*, InjectedScriptManager*);
+
+ Page* m_inspectedPage;
+ InspectorFrontend* m_frontend;
+ InjectedScriptManager* m_injectedScriptManager;
+
+ Vector<pair<long, String> > m_pendingEvaluateTestCommands;
+ pair<RefPtr<TypeBuilder::Runtime::RemoteObject>, RefPtr<JSONObject> > m_pendingInspectData;
+ typedef HashMap<String, String> InjectedScriptForOriginMap;
+ InjectedScriptForOriginMap m_injectedScriptForOrigin;
+};
+
+} // namespace WebCore
+
+#endif // !defined(InspectorInspectorAgent_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
index bc982c73036..cf7068939ef 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.cpp
@@ -31,12 +31,13 @@
#include "config.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/events/EventTarget.h"
#include "core/fetch/FetchInitiatorInfo.h"
-#include "core/inspector/InspectorAgent.h"
#include "core/inspector/InspectorCSSAgent.h"
#include "core/inspector/InspectorConsoleAgent.h"
#include "core/inspector/InspectorController.h"
#include "core/inspector/InspectorDebuggerAgent.h"
+#include "core/inspector/InspectorInspectorAgent.h"
#include "core/inspector/InspectorProfilerAgent.h"
#include "core/inspector/InspectorResourceAgent.h"
#include "core/inspector/InspectorTimelineAgent.h"
@@ -55,7 +56,7 @@ int FrontendCounter::s_frontendCounter = 0;
}
InspectorInstrumentationCookie::InspectorInstrumentationCookie()
- : m_instrumentingAgents(0)
+ : m_instrumentingAgents(nullptr)
, m_timelineAgentId(0)
{
}
@@ -94,27 +95,22 @@ bool isDebuggerPausedImpl(InstrumentingAgents* instrumentingAgents)
return false;
}
-void continueAfterPingLoaderImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& response)
-{
- willSendRequestImpl(instrumentingAgents, identifier, loader, request, response, FetchInitiatorInfo());
-}
-
-void didReceiveResourceResponseButCanceledImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+void didReceiveResourceResponseButCanceledImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
{
didReceiveResourceResponse(frame, identifier, loader, r, 0);
}
-void continueAfterXFrameOptionsDeniedImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+void continueAfterXFrameOptionsDeniedImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
{
didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
}
-void continueWithPolicyDownloadImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+void continueWithPolicyDownloadImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
{
didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
}
-void continueWithPolicyIgnoreImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+void continueWithPolicyIgnoreImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
{
didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
}
@@ -133,19 +129,19 @@ void willDestroyResourceImpl(Resource* cachedResource)
bool collectingHTMLParseErrorsImpl(InstrumentingAgents* instrumentingAgents)
{
- if (InspectorAgent* inspectorAgent = instrumentingAgents->inspectorAgent())
+ if (InspectorInspectorAgent* inspectorAgent = instrumentingAgents->inspectorInspectorAgent())
return inspectorAgent->hasFrontend();
return false;
}
-PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, const ScriptSourceCode& sourceCode)
+PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents* instrumentingAgents, LocalFrame* frame, const ScriptSourceCode& sourceCode)
{
if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent())
return debuggerAgent->preprocess(frame, sourceCode);
return PassOwnPtr<ScriptSourceCode>();
}
-String preprocessEventListenerImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, const String& source, const String& url, const String& functionName)
+String preprocessEventListenerImpl(InstrumentingAgents* instrumentingAgents, LocalFrame* frame, const String& source, const String& url, const String& functionName)
{
if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent())
return debuggerAgent->preprocessEventListener(frame, source, url, functionName);
@@ -206,6 +202,13 @@ InstrumentingAgents* instrumentingAgentsFor(Page* page)
return instrumentationForPage(page);
}
+InstrumentingAgents* instrumentingAgentsFor(EventTarget* eventTarget)
+{
+ if (!eventTarget)
+ return 0;
+ return instrumentingAgentsFor(eventTarget->executionContext());
+}
+
InstrumentingAgents* instrumentingAgentsFor(RenderObject* renderer)
{
return instrumentingAgentsFor(renderer->frame());
@@ -232,8 +235,11 @@ const char PaintSetup[] = "PaintSetup";
const char RasterTask[] = "RasterTask";
const char Paint[] = "Paint";
const char Layer[] = "Layer";
+const char RequestMainThreadFrame[] = "RequestMainThreadFrame";
const char BeginFrame[] = "BeginFrame";
const char ActivateLayerTree[] = "ActivateLayerTree";
+const char DrawFrame[] = "DrawFrame";
+const char EmbedderCallback[] = "EmbedderCallback";
};
namespace InstrumentationEventArguments {
@@ -241,6 +247,7 @@ const char FrameId[] = "frameId";
const char LayerId[] = "layerId";
const char LayerTreeId[] = "layerTreeId";
const char PageId[] = "pageId";
+const char CallbackName[] = "callbackName";
};
InstrumentingAgents* instrumentationForPage(Page* page)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h
index 53fb8064411..beb8bc9b4b4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.h
@@ -38,14 +38,13 @@
#include "core/dom/CharacterData.h"
#include "core/dom/Element.h"
#include "core/dom/ExecutionContext.h"
-#include "core/events/EventContext.h"
-#include "core/frame/Frame.h"
+#include "core/events/NodeEventContext.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/ConsoleAPITypes.h"
#include "core/page/Page.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderImage.h"
#include "core/storage/StorageArea.h"
-#include "modules/websockets/WebSocketFrame.h"
#include "platform/network/FormData.h"
#include "platform/network/WebSocketHandshakeRequest.h"
#include "platform/network/WebSocketHandshakeResponse.h"
@@ -56,14 +55,13 @@ namespace WebCore {
struct CSSParserString;
class Document;
class Element;
-class DeviceOrientationData;
-class GeolocationPosition;
+class EventTarget;
+class ExecutionContext;
class GraphicsContext;
class GraphicsLayer;
class InspectorTimelineAgent;
class InstrumentingAgents;
class RenderLayer;
-class ExecutionContext;
class ThreadableLoaderClient;
class WorkerGlobalScope;
class WorkerGlobalScopeProxy;
@@ -97,8 +95,8 @@ private:
static int s_frontendCounter;
};
-inline void frontendCreated() { FrontendCounter::s_frontendCounter += 1; }
-inline void frontendDeleted() { FrontendCounter::s_frontendCounter -= 1; }
+inline void frontendCreated() { atomicIncrement(&FrontendCounter::s_frontendCounter); }
+inline void frontendDeleted() { atomicDecrement(&FrontendCounter::s_frontendCounter); }
inline bool hasFrontends() { return FrontendCounter::s_frontendCounter; }
void registerInstrumentingAgents(InstrumentingAgents*);
@@ -108,7 +106,8 @@ InspectorTimelineAgent* retrieveTimelineAgent(const InspectorInstrumentationCook
// Called from generated instrumentation code.
InstrumentingAgents* instrumentingAgentsFor(Page*);
-InstrumentingAgents* instrumentingAgentsFor(Frame*);
+InstrumentingAgents* instrumentingAgentsFor(LocalFrame*);
+InstrumentingAgents* instrumentingAgentsFor(EventTarget*);
InstrumentingAgents* instrumentingAgentsFor(ExecutionContext*);
InstrumentingAgents* instrumentingAgentsFor(Document&);
InstrumentingAgents* instrumentingAgentsFor(Document*);
@@ -126,8 +125,11 @@ extern const char PaintSetup[];
extern const char RasterTask[];
extern const char Paint[];
extern const char Layer[];
+extern const char RequestMainThreadFrame[];
extern const char BeginFrame[];
+extern const char DrawFrame[];
extern const char ActivateLayerTree[];
+extern const char EmbedderCallback[];
};
namespace InstrumentationEventArguments {
@@ -135,6 +137,7 @@ extern const char FrameId[];
extern const char LayerId[];
extern const char LayerTreeId[];
extern const char PageId[];
+extern const char CallbackName[];
};
namespace InspectorInstrumentation {
@@ -146,7 +149,7 @@ inline InstrumentingAgents* instrumentingAgentsFor(ExecutionContext* context)
return context->isDocument() ? instrumentingAgentsFor(*toDocument(context)) : instrumentingAgentsForNonDocumentContext(context);
}
-inline InstrumentingAgents* instrumentingAgentsFor(Frame* frame)
+inline InstrumentingAgents* instrumentingAgentsFor(LocalFrame* frame)
{
return frame ? instrumentingAgentsFor(frame->page()) : 0;
}
@@ -187,11 +190,10 @@ InstrumentingAgents* instrumentationForWorkerGlobalScope(WorkerGlobalScope*);
} // namespace WebCore
-// This file will soon be generated
-#include "InspectorInstrumentationInl.h"
+#include "core/InspectorInstrumentationInl.h"
-#include "InspectorInstrumentationCustomInl.h"
+#include "core/inspector/InspectorInstrumentationCustomInl.h"
-#include "InspectorOverridesInl.h"
+#include "core/InspectorOverridesInl.h"
#endif // !defined(InspectorInstrumentation_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl b/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
index 548af1f7977..f25f184a8f2 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentation.idl
@@ -58,6 +58,9 @@
*
* paramList: C++ parameter list with optional names. Names will be deduced from types if omitted but you have to
* specify explicit names for multiple parameters of the same type.
+*
+* Parameters with type PassRefPtr<T> are converted to raw pointers,
+* so reference will not be passed or released until all agents are notified.
*/
interface InspectorInstrumentation {
@@ -65,7 +68,7 @@ interface InspectorInstrumentation {
#include "core/dom/PseudoElement.h"
[Page, Inspector, PageDebugger, PageRuntime]
- void didClearWindowObjectInWorld([Keep] Frame*, DOMWrapperWorld*);
+ void didClearDocumentOfWindowObject([Keep] LocalFrame*);
[DOMDebugger, Inline=FastReturn]
void willInsertDOMNode([Keep] Node* parent);
@@ -91,6 +94,9 @@ interface InspectorInstrumentation {
[DOM, DOMDebugger, Inline=FastReturn]
void didInvalidateStyleAttr([Keep] Node*);
+ [CSS]
+ void documentDetached([Keep] Document*);
+
[CSS, Inline=FastReturn]
void willMutateRules(CSSStyleSheet*);
@@ -104,10 +110,10 @@ interface InspectorInstrumentation {
void didMutateStyle([Keep] CSSStyleDeclaration*, bool);
[CSS, Inline=FastReturn]
- void activeStyleSheetsUpdated([Keep] Document*, const Vector<RefPtr<StyleSheet> >& newSheets);
+ void activeStyleSheetsUpdated([Keep] Document*);
- [Console]
- void frameWindowDiscarded(Frame*, DOMWindow* domWindow);
+ [Console, PageRuntime]
+ void frameWindowDiscarded(LocalFrame*, LocalDOMWindow* domWindow);
[CSS, Inline=FastReturn]
void mediaQueryResultChanged(Document*);
@@ -118,18 +124,6 @@ interface InspectorInstrumentation {
[DOM, Inline=FastReturn]
void willPopShadowRoot([Keep] Element* host, ShadowRoot*);
- [CSS, Inline=FastReturn]
- void didCreateNamedFlow([Keep] Document*, NamedFlow*);
-
- [CSS, Inline=FastReturn]
- void willRemoveNamedFlow([Keep] Document*, NamedFlow*);
-
- [CSS, Inline=FastReturn]
- void didUpdateRegionLayout([Keep] Document*, NamedFlow*);
-
- [CSS, Inline=FastReturn]
- void didChangeRegionOverset([Keep] Document*, NamedFlow*);
-
[DOMDebugger, Inline=FastReturn]
void willSendXMLHttpRequest(ExecutionContext*, const String& url);
@@ -142,9 +136,6 @@ interface InspectorInstrumentation {
[DOMDebugger, Inline=FastReturn]
void didFireWebGLErrorOrWarning(Element*, const String& message);
- [Timeline, Inline=FastReturn]
- void didScheduleResourceRequest([Keep] Document*, const String& url);
-
[DOMDebugger, Debugger, Timeline, Inline=FastReturn]
void didInstallTimer([Keep] ExecutionContext*, int timerId, int timeout, bool singleShot);
@@ -152,7 +143,7 @@ interface InspectorInstrumentation {
void didRemoveTimer([Keep] ExecutionContext*, int timerId);
[Timeline, Inline=FastReturn]
- InspectorInstrumentationCookie willCallFunction([Keep] ExecutionContext*, const String& scriptName, int scriptLine);
+ InspectorInstrumentationCookie willCallFunction([Keep] ExecutionContext*, int scriptId, const String& scriptName, int scriptLine);
[Timeline, Inline=FastReturn]
void didCallFunction(const InspectorInstrumentationCookie&);
@@ -164,34 +155,49 @@ interface InspectorInstrumentation {
void didDispatchXHRReadyStateChangeEvent(const InspectorInstrumentationCookie&);
[Timeline, Inline=FastReturn]
- InspectorInstrumentationCookie willDispatchEvent([Keep] Document*, const Event&, DOMWindow*, Node*, const EventPath&);
+ InspectorInstrumentationCookie willDispatchEvent([Keep] Document*, const Event&, LocalDOMWindow*, Node*, const EventPath&);
[Timeline, Inline=FastReturn]
void didDispatchEvent(const InspectorInstrumentationCookie&);
- [DOMDebugger, Inline=FastReturn]
- InspectorInstrumentationCookie willHandleEvent(ExecutionContext*, Event*);
+ [Debugger, Inline=FastReturn]
+ void didEnqueueEvent([Keep] EventTarget*, Event*);
+
+ [Debugger, Inline=FastReturn]
+ void didRemoveEvent([Keep] EventTarget*, Event*);
+
+ [Debugger, DOMDebugger, Inline=FastReturn]
+ InspectorInstrumentationCookie willHandleEvent([Keep] EventTarget*, Event*, EventListener* listener, bool useCapture);
[Debugger, Inline=FastReturn]
void didHandleEvent(const InspectorInstrumentationCookie&);
[Timeline, Inline=FastReturn]
- InspectorInstrumentationCookie willDispatchEventOnWindow(Frame*, const Event&, DOMWindow*);
+ InspectorInstrumentationCookie willDispatchEventOnWindow(LocalFrame*, const Event&, LocalDOMWindow*);
[Timeline, Inline=FastReturn]
void didDispatchEventOnWindow(const InspectorInstrumentationCookie&);
+ [Debugger, Inline=FastReturn]
+ void didEnqueueMutationRecord([Keep] ExecutionContext*, MutationObserver*);
+
+ [Debugger, Inline=FastReturn]
+ void didClearAllMutationRecords([Keep] ExecutionContext*, MutationObserver*);
+
+ [Debugger, Inline=FastReturn]
+ void willDeliverMutationRecords([Keep] ExecutionContext*, MutationObserver*);
+
+ [Debugger, Inline=FastReturn]
+ void didDeliverMutationRecords(ExecutionContext*);
+
[Timeline, Inline=FastReturn]
- InspectorInstrumentationCookie willEvaluateScript([Keep] Frame*, const String& url, int lineNumber);
+ InspectorInstrumentationCookie willEvaluateScript([Keep] LocalFrame*, const String& url, int lineNumber);
[Timeline, Inline=FastReturn]
void didEvaluateScript(const InspectorInstrumentationCookie&);
- [Page, Inline=FastReturn]
- void scriptsEnabled(Page*, bool isEnabled);
-
[PageRuntime, Inline=FastReturn]
- void didCreateIsolatedContext([Keep] Frame*, ScriptState*, SecurityOrigin*);
+ void didCreateIsolatedContext([Keep] LocalFrame*, ScriptState*, SecurityOrigin*);
[DOMDebugger, Debugger, Timeline, Inline=FastReturn]
InspectorInstrumentationCookie willFireTimer([Keep] ExecutionContext*, int timerId);
@@ -200,20 +206,14 @@ interface InspectorInstrumentation {
void didFireTimer(const InspectorInstrumentationCookie&);
[Timeline, Inline=FastReturn]
- void didInvalidateLayout([Keep] Frame*);
+ void didInvalidateLayout([Keep] LocalFrame*);
[Timeline, Inline=FastReturn]
- InspectorInstrumentationCookie willLayout([Keep] Frame*);
+ InspectorInstrumentationCookie willLayout([Keep] LocalFrame*);
[Timeline, Page, Inline=FastReturn]
void didLayout(const InspectorInstrumentationCookie&, RenderObject* root);
- [Timeline, Inline=FastReturn]
- void willAutosizeText([Keep] RenderObject* root);
-
- [Timeline, Inline=FastReturn]
- void didAutosizeText([Keep] RenderObject* root);
-
[Page, Inline=FastReturn]
void didScroll(Page*);
@@ -248,72 +248,61 @@ interface InspectorInstrumentation {
InspectorInstrumentationCookie willRecalculateStyle([Keep] Document*);
[Timeline, Resource, Page, Inline=FastReturn]
- void didRecalculateStyle(const InspectorInstrumentationCookie&);
-
- [Timeline, Inline=FastReturn]
- void didRecalculateStyleForElement(Element*);
+ void didRecalculateStyle(const InspectorInstrumentationCookie&, int elementCount);
[Timeline, Resource, Inline=FastReturn]
void didScheduleStyleRecalculation([Keep] Document*);
[Resource, Inline=FastReturn]
- void applyUserAgentOverride(Frame*, String* userAgent);
+ void applyUserAgentOverride(LocalFrame*, String* userAgent);
[Page, Inline=FastReturn]
bool applyViewportStyleOverride(Document*, StyleResolver*);
[Page, Inline=FastReturn]
- void applyEmulatedMedia(Frame*, String* media);
+ void applyEmulatedMedia(LocalFrame*, String* media);
[Timeline, Resource]
- void willSendRequest(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&);
-
- void continueAfterPingLoader(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&);
+ void willSendRequest(LocalFrame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&);
[Resource]
void markResourceAsCached(Page*, unsigned long identifier);
- [Timeline, Inline=FastReturn]
- InspectorInstrumentationCookie willReceiveResourceData([Keep] Frame*, unsigned long identifier, int length);
-
- [Timeline, Inline=FastReturn]
- void didReceiveResourceData(const InspectorInstrumentationCookie&);
-
[Timeline, Resource, Console] // Console should come AFTER Resource notification, front-end relies on this.
- void didReceiveResourceResponse([Keep] Frame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+ void didReceiveResourceResponse([Keep] LocalFrame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
[Inline=Forward]
- void continueAfterXFrameOptionsDenied(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
+ void continueAfterXFrameOptionsDenied(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
[Inline=Forward]
- void continueWithPolicyDownload(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
+ void continueWithPolicyDownload(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
[Inline=Forward]
- void continueWithPolicyIgnore(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
+ void continueWithPolicyIgnore(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
- [Resource]
- void didReceiveData(Frame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
+ [Timeline, Resource, Inline=FastReturn]
+ void didReceiveData([Keep] LocalFrame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
[Timeline, Resource]
- void didFinishLoading(Frame* frame, unsigned long identifier, DocumentLoader*, double finishTime);
+ void didFinishLoading(LocalFrame* frame, unsigned long identifier, DocumentLoader*, double finishTime, int64_t encodedDataLength);
[Resource]
- void didReceiveCORSRedirectResponse([Keep] Frame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+ void didReceiveCORSRedirectResponse([Keep] LocalFrame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
[Timeline, Resource, Console] // Console should come AFTER Resource notification, front-end relies on this.
- void didFailLoading(Frame* frame, unsigned long identifier, DocumentLoader*, const ResourceError&);
+ void didFailLoading(LocalFrame* frame, unsigned long identifier, const ResourceError&);
[Resource]
void documentThreadableLoaderStartedLoadingForClient(ExecutionContext*, unsigned long identifier, ThreadableLoaderClient* client);
- [Resource]
+ [Debugger, Resource]
void willLoadXHR(ExecutionContext*, XMLHttpRequest* xhr, ThreadableLoaderClient* client, const AtomicString& method, const KURL& url, bool async, PassRefPtr<FormData>, const HTTPHeaderMap& headers, bool includeCredentials);
[Resource]
void didFailXHRLoading(ExecutionContext*, XMLHttpRequest* xhr, ThreadableLoaderClient* client);
[Console, Resource]
- void didFinishXHRLoading(ExecutionContext*, XMLHttpRequest* xhr, ThreadableLoaderClient* client, unsigned long identifier, ScriptString sourceString, const String& url, const String& sendURL, unsigned sendLineNumber);
+ void didFinishXHRLoading(ExecutionContext*, XMLHttpRequest* xhr, ThreadableLoaderClient* client, unsigned long identifier, ScriptString sourceString, const AtomicString& method, const String& url, const String& sendURL, unsigned sendLineNumber);
[Resource]
void scriptImported(ExecutionContext*, unsigned long identifier, const String& sourceString);
@@ -325,37 +314,37 @@ interface InspectorInstrumentation {
void didReceiveScriptResponse(ExecutionContext*, unsigned long identifier);
[Timeline, Inspector, DOM, Page]
- void domContentLoadedEventFired([Keep] Frame*);
+ void domContentLoadedEventFired([Keep] LocalFrame*);
[Timeline, Page]
- void loadEventFired([Keep] Frame*);
+ void loadEventFired([Keep] LocalFrame*);
[Page]
- void frameAttachedToParent([Keep] Frame*);
+ void frameAttachedToParent([Keep] LocalFrame*);
- [Canvas, Page, CSS]
- void frameDetachedFromParent([Keep] Frame*);
+ [Canvas, Page]
+ void frameDetachedFromParent([Keep] LocalFrame*);
- [Console, Resource, CSS, Database, DOM, Inspector, Canvas, Page, PageDebugger]
- void didCommitLoad([Keep] Frame*, DocumentLoader*);
+ [Console, Resource, DOM, Canvas, Page, PageDebugger]
+ void didCommitLoad([Keep] LocalFrame*, DocumentLoader*);
[DOM, Inline=FastReturn]
- void frameDocumentUpdated([Keep] Frame*);
+ void frameDocumentUpdated([Keep] LocalFrame*);
[Page]
- void loaderDetachedFromFrame(Frame*, DocumentLoader*);
+ void loaderDetachedFromFrame(LocalFrame*, DocumentLoader*);
[Page]
- void frameStartedLoading([Keep] Frame*);
+ void frameStartedLoading([Keep] LocalFrame*);
[Page]
- void frameStoppedLoading([Keep] Frame*);
+ void frameStoppedLoading([Keep] LocalFrame*);
[Page, Resource]
- void frameScheduledNavigation([Keep] Frame*, double delay);
+ void frameScheduledNavigation([Keep] LocalFrame*, double delay);
[Page, Resource]
- void frameClearedScheduledNavigation([Keep] Frame*);
+ void frameClearedScheduledNavigation([Keep] LocalFrame*);
[Page, Inline=FastReturn]
InspectorInstrumentationCookie willRunJavaScriptDialog(Page*, const String& message);
@@ -412,19 +401,19 @@ interface InspectorInstrumentation {
void didCreateWebSocket([Keep] Document*, unsigned long identifier, const KURL& requestURL, const String& protocol);
[Resource, Timeline]
- void willSendWebSocketHandshakeRequest([Keep] Document*, unsigned long identifier, const WebSocketHandshakeRequest& request);
+ void willSendWebSocketHandshakeRequest([Keep] Document*, unsigned long identifier, const WebSocketHandshakeRequest* request);
[Resource, Timeline]
- void didReceiveWebSocketHandshakeResponse([Keep] Document*, unsigned long identifier, const WebSocketHandshakeResponse& response);
+ void didReceiveWebSocketHandshakeResponse([Keep] Document*, unsigned long identifier, const WebSocketHandshakeRequest* request, const WebSocketHandshakeResponse* response);
[Resource, Timeline]
void didCloseWebSocket([Keep] Document*, unsigned long identifier);
[Resource]
- void didReceiveWebSocketFrame(Document*, unsigned long identifier, const WebSocketFrame& frame);
+ void didReceiveWebSocketFrame(Document*, unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength);
[Resource]
- void didSendWebSocketFrame(Document*, unsigned long identifier, const WebSocketFrame& frame);
+ void didSendWebSocketFrame(Document*, unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength);
[Resource]
void didReceiveWebSocketFrameError(Document*, unsigned long identifier, const String& errorMessage);
@@ -433,16 +422,23 @@ interface InspectorInstrumentation {
void networkStateChanged(Page*, bool online);
[ApplicationCache, Inline=FastReturn]
- void updateApplicationCacheStatus([Keep] Frame*);
+ void updateApplicationCacheStatus([Keep] LocalFrame*);
- [LayerTree]
- void layerTreeDidChange(Page*);
+ [Timeline, Inline=FastReturn]
+ void willUpdateLayerTree(LocalFrame*);
+ [Timeline, LayerTree, Inline=FastReturn]
+ void layerTreeDidChange(LocalFrame*);
+ [Timeline, Inline=FastReturn]
+ void didUpdateLayerTree(LocalFrame*);
[DOM, Inline=FastReturn]
void pseudoElementCreated([Keep] PseudoElement*);
[DOM, Inline=FastReturn]
void pseudoElementDestroyed([Keep] PseudoElement*);
+
+ [DOMDebugger, Inline=FastReturn]
+ void willExecuteCustomElementCallback([Keep] Element*);
}
interface InspectorConsoleInstrumentation {
@@ -453,17 +449,17 @@ interface InspectorConsoleInstrumentation {
// FIXME: Convert to ScriptArguments to match non-worker context.
// Use the same implementation as above as a similar method dispatched on Page.
[Console]
- void addMessageToConsole(ExecutionContext* context, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier = 0);
+ void addMessageToConsole(ExecutionContext* context, MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, unsigned long requestIdentifier = 0);
// Use the same implementation as above as a similar method dispatched on Page.
[Console]
void addMessageToConsole(ExecutionContext* context, MessageSource source, MessageType type, MessageLevel level, const String& message, const String& scriptId, unsigned lineNumber, unsigned columnNumber, ScriptState* state, unsigned long requestIdentifier = 0);
[Console, Debugger]
- void addMessageToConsole(ExecutionContext* context, MessageSource source, MessageType type, MessageLevel level, const String& message, ScriptState* state, PassRefPtr<ScriptArguments> arguments, unsigned long requestIdentifier = 0);
+ void addMessageToConsole(ExecutionContext* context, MessageSource source, MessageType type, MessageLevel level, const String& message, ScriptState* state, PassRefPtrWillBeRawPtr<ScriptArguments> arguments, unsigned long requestIdentifier = 0);
[Console]
- void consoleCount(ExecutionContext* context, ScriptState* state, PassRefPtr<ScriptArguments> arguments);
+ void consoleCount(ExecutionContext* context, ScriptState* state, PassRefPtrWillBeRawPtr<ScriptArguments> arguments);
[Timeline, Console]
void consoleTime([Keep] ExecutionContext* context, const String& title);
@@ -484,15 +480,7 @@ interface InspectorConsoleInstrumentation {
void consoleProfile(ExecutionContext* context, const String& title, ScriptState* state);
[Profiler, Inline=FastReturn]
- void consoleProfileEnd(ExecutionContext* context, const String& title);
-}
-
-interface InspectorDatabaseInstrumentation {
-
-#include "modules/webdatabase/Database.h"
-
- [Database]
- void didOpenDatabase(ExecutionContext* context, PassRefPtr<Database> database, const String& domain, const String& name, const String& version);
+ void consoleProfileEnd(ExecutionContext* context, const String& title, ScriptState* state);
}
interface InspectorOverrides {
@@ -501,25 +489,16 @@ interface InspectorOverrides {
[Worker, Inline=FastReturn]
bool shouldPauseDedicatedWorkerOnStart(ExecutionContext* context);
-
- [Page, Inline=FastReturn]
- GeolocationPosition* overrideGeolocationPosition(Page* page, [DefaultReturn] GeolocationPosition* position);
-
- [Page, Inline=FastReturn]
- float overrideFontScaleFactor(Page* page, [DefaultReturn] float fontScaleFactor);
-
- [Page, Inline=FastReturn]
- bool overrideTextAutosizing(Page* page, [DefaultReturn] bool textAutosizing);
}
interface InspectorCanvasInstrumentation {
-#include "bindings/v8/ScriptObject.h"
+#include "bindings/v8/ScriptValue.h"
[Canvas]
- ScriptObject wrapCanvas2DRenderingContextForInstrumentation(Document*, const ScriptObject&);
+ ScriptValue wrapCanvas2DRenderingContextForInstrumentation(Document*, const ScriptValue&);
[Canvas]
- ScriptObject wrapWebGLRenderingContextForInstrumentation(Document*, const ScriptObject&);
+ ScriptValue wrapWebGLRenderingContextForInstrumentation(Document*, const ScriptValue&);
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentationCustomInl.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentationCustomInl.h
index 2ff178d3d2a..8e6f9f4d142 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentationCustomInl.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorInstrumentationCustomInl.h
@@ -37,14 +37,14 @@ namespace InspectorInstrumentation {
bool isDebuggerPausedImpl(InstrumentingAgents*);
bool collectingHTMLParseErrorsImpl(InstrumentingAgents*);
-PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents*, Frame*, const ScriptSourceCode&);
-String preprocessEventListenerImpl(InstrumentingAgents*, Frame*, const String& source, const String& url, const String& functionName);
+PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents*, LocalFrame*, const ScriptSourceCode&);
+String preprocessEventListenerImpl(InstrumentingAgents*, LocalFrame*, const String& source, const String& url, const String& functionName);
bool canvasAgentEnabled(ExecutionContext*);
bool consoleAgentEnabled(ExecutionContext*);
bool timelineAgentEnabled(ExecutionContext*);
-inline bool isDebuggerPaused(Frame* frame)
+inline bool isDebuggerPaused(LocalFrame* frame)
{
FAST_RETURN_IF_NO_FRONTENDS(false);
if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(frame))
@@ -60,7 +60,7 @@ inline bool collectingHTMLParseErrors(Page* page)
return false;
}
-inline String preprocessEventListener(Frame* frame, const String& source, const String& url, const String& functionName)
+inline String preprocessEventListener(LocalFrame* frame, const String& source, const String& url, const String& functionName)
{
FAST_RETURN_IF_NO_FRONTENDS(source);
if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(frame))
@@ -68,7 +68,7 @@ inline String preprocessEventListener(Frame* frame, const String& source, const
return source;
}
-inline PassOwnPtr<ScriptSourceCode> preprocess(Frame* frame, const ScriptSourceCode& sourceCode)
+inline PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame* frame, const ScriptSourceCode& sourceCode)
{
FAST_RETURN_IF_NO_FRONTENDS(PassOwnPtr<ScriptSourceCode>());
if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(frame))
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
index 0c138c15774..43f7cf90a5f 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -33,57 +33,76 @@
#include "core/inspector/InspectorLayerTreeAgent.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/IdentifiersFactory.h"
-#include "core/inspector/InspectorDOMAgent.h"
+#include "core/inspector/InspectorNodeIds.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
-#include "core/rendering/CompositedLayerMapping.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/geometry/IntRect.h"
+#include "platform/graphics/CompositingReasons.h"
#include "platform/graphics/GraphicsContextRecorder.h"
#include "platform/transforms/TransformationMatrix.h"
-#include "public/platform/WebCompositingReasons.h"
+#include "public/platform/WebFloatPoint.h"
#include "public/platform/WebLayer.h"
+#include "wtf/text/Base64.h"
namespace WebCore {
unsigned InspectorLayerTreeAgent::s_lastSnapshotId;
-struct LayerSnapshot {
- LayerSnapshot()
- : layerId(0)
- {
- }
- LayerSnapshot(int layerId, PassRefPtr<GraphicsContextSnapshot> graphicsSnapshot)
- : layerId(layerId)
- , graphicsSnapshot(graphicsSnapshot)
- {
- }
- int layerId;
- RefPtr<GraphicsContextSnapshot> graphicsSnapshot;
-};
-
inline String idForLayer(const GraphicsLayer* graphicsLayer)
{
return String::number(graphicsLayer->platformLayer()->id());
}
+static PassRefPtr<TypeBuilder::LayerTree::ScrollRect> buildScrollRect(const blink::WebRect& rect, const TypeBuilder::LayerTree::ScrollRect::Type::Enum& type)
+{
+ RefPtr<TypeBuilder::DOM::Rect> rectObject = TypeBuilder::DOM::Rect::create()
+ .setX(rect.x)
+ .setY(rect.y)
+ .setHeight(rect.height)
+ .setWidth(rect.width);
+ RefPtr<TypeBuilder::LayerTree::ScrollRect> scrollRectObject = TypeBuilder::LayerTree::ScrollRect::create()
+ .setRect(rectObject.release())
+ .setType(type);
+ return scrollRectObject.release();
+}
+
+static PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect> > buildScrollRectsForLayer(GraphicsLayer* graphicsLayer)
+{
+ RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect> > scrollRects = TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect>::create();
+ blink::WebLayer* webLayer = graphicsLayer->platformLayer();
+ for (size_t i = 0; i < webLayer->nonFastScrollableRegion().size(); ++i) {
+ scrollRects->addItem(buildScrollRect(webLayer->nonFastScrollableRegion()[i], TypeBuilder::LayerTree::ScrollRect::Type::RepaintsOnScroll));
+ }
+ for (size_t i = 0; i < webLayer->touchEventHandlerRegion().size(); ++i) {
+ scrollRects->addItem(buildScrollRect(webLayer->touchEventHandlerRegion()[i], TypeBuilder::LayerTree::ScrollRect::Type::TouchEventHandler));
+ }
+ if (webLayer->haveWheelEventHandlers()) {
+ blink::WebRect webRect(webLayer->position().x, webLayer->position().y, webLayer->bounds().width, webLayer->bounds().height);
+ scrollRects->addItem(buildScrollRect(webRect, TypeBuilder::LayerTree::ScrollRect::Type::WheelEventHandler));
+ }
+ return scrollRects->length() ? scrollRects.release() : nullptr;
+}
+
static PassRefPtr<TypeBuilder::LayerTree::Layer> buildObjectForLayer(GraphicsLayer* graphicsLayer, int nodeId)
{
+ blink::WebLayer* webLayer = graphicsLayer->platformLayer();
RefPtr<TypeBuilder::LayerTree::Layer> layerObject = TypeBuilder::LayerTree::Layer::create()
.setLayerId(idForLayer(graphicsLayer))
- .setOffsetX(graphicsLayer->position().x())
- .setOffsetY(graphicsLayer->position().y())
- .setWidth(graphicsLayer->size().width())
- .setHeight(graphicsLayer->size().height())
+ .setOffsetX(webLayer->position().x)
+ .setOffsetY(webLayer->position().y)
+ .setWidth(webLayer->bounds().width)
+ .setHeight(webLayer->bounds().height)
.setPaintCount(graphicsLayer->paintCount());
if (nodeId)
- layerObject->setNodeId(nodeId);
+ layerObject->setBackendNodeId(nodeId);
GraphicsLayer* parent = graphicsLayer->parent();
if (!parent)
@@ -100,29 +119,28 @@ static PassRefPtr<TypeBuilder::LayerTree::Layer> buildObjectForLayer(GraphicsLay
for (size_t i = 0; i < WTF_ARRAY_LENGTH(flattenedMatrix); ++i)
transformArray->addItem(flattenedMatrix[i]);
layerObject->setTransform(transformArray);
- const FloatPoint3D& anchor = graphicsLayer->anchorPoint();
- layerObject->setAnchorX(anchor.x());
- layerObject->setAnchorY(anchor.y());
- layerObject->setAnchorZ(anchor.z());
+ const FloatPoint3D& transformOrigin = graphicsLayer->transformOrigin();
+ // FIXME: rename these to setTransformOrigin*
+ if (webLayer->bounds().width > 0)
+ layerObject->setAnchorX(transformOrigin.x() / webLayer->bounds().width);
+ else
+ layerObject->setAnchorX(0.0);
+ if (webLayer->bounds().height > 0)
+ layerObject->setAnchorY(transformOrigin.y() / webLayer->bounds().height);
+ else
+ layerObject->setAnchorY(0.0);
+ layerObject->setAnchorZ(transformOrigin.z());
}
+ RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::ScrollRect> > scrollRects = buildScrollRectsForLayer(graphicsLayer);
+ if (scrollRects)
+ layerObject->setScrollRects(scrollRects.release());
return layerObject;
}
-void gatherGraphicsLayers(GraphicsLayer* root, HashMap<int, int>& layerIdToNodeIdMap, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >& layers)
-{
- int layerId = root->platformLayer()->id();
- layers->addItem(buildObjectForLayer(root, layerIdToNodeIdMap.get(layerId)));
- if (GraphicsLayer* replica = root->replicaLayer())
- gatherGraphicsLayers(replica, layerIdToNodeIdMap, layers);
- for (size_t i = 0, size = root->children().size(); i < size; ++i)
- gatherGraphicsLayers(root->children()[i], layerIdToNodeIdMap, layers);
-}
-
-InspectorLayerTreeAgent::InspectorLayerTreeAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorDOMAgent* domAgent, Page* page)
- : InspectorBaseAgent<InspectorLayerTreeAgent>("LayerTree", instrumentingAgents, state)
+InspectorLayerTreeAgent::InspectorLayerTreeAgent(Page* page)
+ : InspectorBaseAgent<InspectorLayerTreeAgent>("LayerTree")
, m_frontend(0)
, m_page(page)
- , m_domAgent(domAgent)
{
}
@@ -151,13 +169,18 @@ void InspectorLayerTreeAgent::restore()
void InspectorLayerTreeAgent::enable(ErrorString*)
{
m_instrumentingAgents->setInspectorLayerTreeAgent(this);
- layerTreeDidChange();
+ if (LocalFrame* frame = m_page->deprecatedLocalMainFrame()) {
+ Document* document = frame->document();
+ if (document && document->lifecycle().state() >= DocumentLifecycle::CompositingClean)
+ layerTreeDidChange();
+ }
}
void InspectorLayerTreeAgent::disable(ErrorString*)
{
m_instrumentingAgents->setInspectorLayerTreeAgent(0);
m_snapshotById.clear();
+ ErrorString unused;
}
void InspectorLayerTreeAgent::layerTreeDidChange()
@@ -183,7 +206,8 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > InspectorLayerTre
{
RenderLayerCompositor* compositor = renderLayerCompositor();
if (!compositor || !compositor->inCompositingMode())
- return 0;
+ return nullptr;
+
LayerIdToNodeIdMap layerIdToNodeIdMap;
RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > layers = TypeBuilder::Array<TypeBuilder::LayerTree::Layer>::create();
buildLayerIdToNodeIdMap(compositor->rootRenderLayer(), layerIdToNodeIdMap);
@@ -210,19 +234,26 @@ void InspectorLayerTreeAgent::buildLayerIdToNodeIdMap(RenderLayer* root, LayerId
}
}
+void InspectorLayerTreeAgent::gatherGraphicsLayers(GraphicsLayer* root, HashMap<int, int>& layerIdToNodeIdMap, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >& layers)
+{
+ int layerId = root->platformLayer()->id();
+ if (m_pageOverlayLayerIds.find(layerId) != WTF::kNotFound)
+ return;
+ layers->addItem(buildObjectForLayer(root, layerIdToNodeIdMap.get(layerId)));
+ if (GraphicsLayer* replica = root->replicaLayer())
+ gatherGraphicsLayers(replica, layerIdToNodeIdMap, layers);
+ for (size_t i = 0, size = root->children().size(); i < size; ++i)
+ gatherGraphicsLayers(root->children()[i], layerIdToNodeIdMap, layers);
+}
+
int InspectorLayerTreeAgent::idForNode(Node* node)
{
- int nodeId = m_domAgent->boundNodeId(node);
- if (!nodeId) {
- ErrorString ignoredError;
- nodeId = m_domAgent->pushNodeToFrontend(&ignoredError, m_domAgent->boundNodeId(&node->document()), node);
- }
- return nodeId;
+ return InspectorNodeIds::idForNode(node);
}
RenderLayerCompositor* InspectorLayerTreeAgent::renderLayerCompositor()
{
- RenderView* renderView = m_page->mainFrame()->contentRenderer();
+ RenderView* renderView = m_page->deprecatedLocalMainFrame()->contentRenderer();
RenderLayerCompositor* compositor = renderView ? renderView->compositor() : 0;
return compositor;
}
@@ -262,60 +293,19 @@ GraphicsLayer* InspectorLayerTreeAgent::layerById(ErrorString* errorString, cons
return result;
}
-struct CompositingReasonToProtocolName {
- uint64_t mask;
- const char *protocolName;
-};
-
-
void InspectorLayerTreeAgent::compositingReasons(ErrorString* errorString, const String& layerId, RefPtr<TypeBuilder::Array<String> >& reasonStrings)
{
- static CompositingReasonToProtocolName compositingReasonNames[] = {
- { CompositingReason3DTransform, "transform3D" },
- { CompositingReasonVideo, "video" },
- { CompositingReasonCanvas, "canvas" },
- { CompositingReasonPlugin, "plugin" },
- { CompositingReasonIFrame, "iFrame" },
- { CompositingReasonBackfaceVisibilityHidden, "backfaceVisibilityHidden" },
- { CompositingReasonAnimation, "animation" },
- { CompositingReasonFilters, "filters" },
- { CompositingReasonPositionFixed, "positionFixed" },
- { CompositingReasonPositionSticky, "positionSticky" },
- { CompositingReasonOverflowScrollingTouch, "overflowScrollingTouch" },
- { CompositingReasonAssumedOverlap, "assumedOverlap" },
- { CompositingReasonOverlap, "overlap" },
- { CompositingReasonNegativeZIndexChildren, "negativeZIndexChildren" },
- { CompositingReasonTransformWithCompositedDescendants, "transformWithCompositedDescendants" },
- { CompositingReasonOpacityWithCompositedDescendants, "opacityWithCompositedDescendants" },
- { CompositingReasonMaskWithCompositedDescendants, "maskWithCompositedDescendants" },
- { CompositingReasonReflectionWithCompositedDescendants, "reflectionWithCompositedDescendants" },
- { CompositingReasonFilterWithCompositedDescendants, "filterWithCompositedDescendants" },
- { CompositingReasonBlendingWithCompositedDescendants, "blendingWithCompositedDescendants" },
- { CompositingReasonClipsCompositingDescendants, "clipsCompositingDescendants" },
- { CompositingReasonPerspective, "perspective" },
- { CompositingReasonPreserve3D, "preserve3D" },
- { CompositingReasonRoot, "root" },
- { CompositingReasonLayerForClip, "layerForClip" },
- { CompositingReasonLayerForScrollbar, "layerForScrollbar" },
- { CompositingReasonLayerForScrollingContainer, "layerForScrollingContainer" },
- { CompositingReasonLayerForForeground, "layerForForeground" },
- { CompositingReasonLayerForBackground, "layerForBackground" },
- { CompositingReasonLayerForMask, "layerForMask" },
- { CompositingReasonLayerForVideoOverlay, "layerForVideoOverlay" },
- { CompositingReasonIsolateCompositedDescendants, "isolateCompositedDescendants" }
- };
-
const GraphicsLayer* graphicsLayer = layerById(errorString, layerId);
if (!graphicsLayer)
return;
- blink::WebCompositingReasons reasonsBitmask = graphicsLayer->compositingReasons();
+ CompositingReasons reasonsBitmask = graphicsLayer->compositingReasons();
reasonStrings = TypeBuilder::Array<String>::create();
- for (size_t i = 0; i < WTF_ARRAY_LENGTH(compositingReasonNames); ++i) {
- if (!(reasonsBitmask & compositingReasonNames[i].mask))
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(compositingReasonStringMap); ++i) {
+ if (!(reasonsBitmask & compositingReasonStringMap[i].reason))
continue;
- reasonStrings->addItem(compositingReasonNames[i].protocolName);
+ reasonStrings->addItem(compositingReasonStringMap[i].shortName);
#ifndef _NDEBUG
- reasonsBitmask &= ~compositingReasonNames[i].mask;
+ reasonsBitmask &= ~compositingReasonStringMap[i].reason;
#endif
}
ASSERT(!reasonsBitmask);
@@ -333,7 +323,24 @@ void InspectorLayerTreeAgent::makeSnapshot(ErrorString* errorString, const Strin
layer->paint(*context, IntRect(IntPoint(0, 0), size));
RefPtr<GraphicsContextSnapshot> snapshot = recorder.stop();
*snapshotId = String::number(++s_lastSnapshotId);
- bool newEntry = m_snapshotById.add(*snapshotId, LayerSnapshot(layer->platformLayer()->id(), snapshot)).isNewEntry;
+ bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry;
+ ASSERT_UNUSED(newEntry, newEntry);
+}
+
+void InspectorLayerTreeAgent::loadSnapshot(ErrorString* errorString, const String& data, String* snapshotId)
+{
+ Vector<char> snapshotData;
+ if (!base64Decode(data, snapshotData)) {
+ *errorString = "Invalid base64 encoding";
+ return;
+ }
+ RefPtr<GraphicsContextSnapshot> snapshot = GraphicsContextSnapshot::load(snapshotData.data(), snapshotData.size());
+ if (!snapshot) {
+ *errorString = "Invalida snapshot format";
+ return;
+ }
+ *snapshotId = String::number(++s_lastSnapshotId);
+ bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry;
ASSERT_UNUSED(newEntry, newEntry);
}
@@ -347,31 +354,31 @@ void InspectorLayerTreeAgent::releaseSnapshot(ErrorString* errorString, const St
m_snapshotById.remove(it);
}
-const LayerSnapshot* InspectorLayerTreeAgent::snapshotById(ErrorString* errorString, const String& snapshotId)
+const GraphicsContextSnapshot* InspectorLayerTreeAgent::snapshotById(ErrorString* errorString, const String& snapshotId)
{
SnapshotById::iterator it = m_snapshotById.find(snapshotId);
if (it == m_snapshotById.end()) {
*errorString = "Snapshot not found";
return 0;
}
- return &it->value;
+ return it->value.get();
}
void InspectorLayerTreeAgent::replaySnapshot(ErrorString* errorString, const String& snapshotId, const int* fromStep, const int* toStep, String* dataURL)
{
- const LayerSnapshot* snapshot = snapshotById(errorString, snapshotId);
+ const GraphicsContextSnapshot* snapshot = snapshotById(errorString, snapshotId);
if (!snapshot)
return;
- OwnPtr<ImageBuffer> imageBuffer = snapshot->graphicsSnapshot->replay(fromStep ? *fromStep : 0, toStep ? *toStep : 0);
+ OwnPtr<ImageBuffer> imageBuffer = snapshot->replay(fromStep ? *fromStep : 0, toStep ? *toStep : 0);
*dataURL = imageBuffer->toDataURL("image/png");
}
void InspectorLayerTreeAgent::profileSnapshot(ErrorString* errorString, const String& snapshotId, const int* minRepeatCount, const double* minDuration, RefPtr<TypeBuilder::Array<TypeBuilder::Array<double> > >& outTimings)
{
- const LayerSnapshot* snapshot = snapshotById(errorString, snapshotId);
+ const GraphicsContextSnapshot* snapshot = snapshotById(errorString, snapshotId);
if (!snapshot)
return;
- OwnPtr<GraphicsContextSnapshot::Timings> timings = snapshot->graphicsSnapshot->profile(minRepeatCount ? *minRepeatCount : 1, minDuration ? *minDuration : 0);
+ OwnPtr<GraphicsContextSnapshot::Timings> timings = snapshot->profile(minRepeatCount ? *minRepeatCount : 1, minDuration ? *minDuration : 0);
outTimings = TypeBuilder::Array<TypeBuilder::Array<double> >::create();
for (size_t i = 0; i < timings->size(); ++i) {
const Vector<double>& row = (*timings)[i];
@@ -382,4 +389,26 @@ void InspectorLayerTreeAgent::profileSnapshot(ErrorString* errorString, const St
}
}
+void InspectorLayerTreeAgent::snapshotCommandLog(ErrorString* errorString, const String& snapshotId, RefPtr<TypeBuilder::Array<JSONObject> >& commandLog)
+{
+ const GraphicsContextSnapshot* snapshot = snapshotById(errorString, snapshotId);
+ if (!snapshot)
+ return;
+ commandLog = TypeBuilder::Array<JSONObject>::runtimeCast(snapshot->snapshotCommandLog());
+}
+
+void InspectorLayerTreeAgent::willAddPageOverlay(const GraphicsLayer* layer)
+{
+ m_pageOverlayLayerIds.append(layer->platformLayer()->id());
+}
+
+void InspectorLayerTreeAgent::didRemovePageOverlay(const GraphicsLayer* layer)
+{
+ size_t index = m_pageOverlayLayerIds.find(layer->platformLayer()->id());
+ if (index == WTF::kNotFound)
+ return;
+ m_pageOverlayLayerIds.remove(index);
+}
+
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h
index ffaeb481a53..4c7b721a926 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.h
@@ -31,8 +31,8 @@
#define InspectorLayerTreeAgent_h
-#include "InspectorFrontend.h"
-#include "InspectorTypeBuilder.h"
+#include "core/InspectorFrontend.h"
+#include "core/InspectorTypeBuilder.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "core/rendering/RenderLayer.h"
#include "platform/Timer.h"
@@ -42,59 +42,66 @@
namespace WebCore {
-class InspectorDOMAgent;
+class GraphicsContextSnapshot;
class InstrumentingAgents;
class Page;
class RenderLayerCompositor;
-struct LayerSnapshot;
-
typedef String ErrorString;
-class InspectorLayerTreeAgent : public InspectorBaseAgent<InspectorLayerTreeAgent>, public InspectorBackendDispatcher::LayerTreeCommandHandler {
+class InspectorLayerTreeAgent FINAL : public InspectorBaseAgent<InspectorLayerTreeAgent>, public InspectorBackendDispatcher::LayerTreeCommandHandler {
public:
- static PassOwnPtr<InspectorLayerTreeAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InspectorDOMAgent* domAgent, Page* page)
+ static PassOwnPtr<InspectorLayerTreeAgent> create(Page* page)
{
- return adoptPtr(new InspectorLayerTreeAgent(instrumentingAgents, state, domAgent, page));
+ return adoptPtr(new InspectorLayerTreeAgent(page));
}
- ~InspectorLayerTreeAgent();
+ virtual ~InspectorLayerTreeAgent();
+
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ // Called from InspectorController
+ void willAddPageOverlay(const GraphicsLayer*);
+ void didRemovePageOverlay(const GraphicsLayer*);
// Called from InspectorInstrumentation
void layerTreeDidChange();
void didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext*, const LayoutRect&);
// Called from the front-end.
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void compositingReasons(ErrorString*, const String& layerId, RefPtr<TypeBuilder::Array<String> >&);
- virtual void makeSnapshot(ErrorString*, const String& layerId, String* snapshotId);
- virtual void releaseSnapshot(ErrorString*, const String& snapshotId);
- virtual void replaySnapshot(ErrorString*, const String& snapshotId, const int* fromStep, const int* toStep, String* dataURL);
- virtual void profileSnapshot(ErrorString*, const String& snapshotId, const int* minRepeatCount, const double* minDuration, RefPtr<TypeBuilder::Array<TypeBuilder::Array<double> > >&);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void compositingReasons(ErrorString*, const String& layerId, RefPtr<TypeBuilder::Array<String> >&) OVERRIDE;
+ virtual void makeSnapshot(ErrorString*, const String& layerId, String* snapshotId) OVERRIDE;
+ virtual void loadSnapshot(ErrorString*, const String& data, String* snapshotId) OVERRIDE;
+ virtual void releaseSnapshot(ErrorString*, const String& snapshotId) OVERRIDE;
+ virtual void replaySnapshot(ErrorString*, const String& snapshotId, const int* fromStep, const int* toStep, String* dataURL) OVERRIDE;
+ virtual void profileSnapshot(ErrorString*, const String& snapshotId, const int* minRepeatCount, const double* minDuration, RefPtr<TypeBuilder::Array<TypeBuilder::Array<double> > >&) OVERRIDE;
+ virtual void snapshotCommandLog(ErrorString*, const String& snapshotId, RefPtr<TypeBuilder::Array<JSONObject> >&) OVERRIDE;
+
+ // Called by other agents.
+ PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > buildLayerTree();
private:
static unsigned s_lastSnapshotId;
- InspectorLayerTreeAgent(InstrumentingAgents*, InspectorCompositeState*, InspectorDOMAgent*, Page*);
+ explicit InspectorLayerTreeAgent(Page*);
RenderLayerCompositor* renderLayerCompositor();
GraphicsLayer* layerById(ErrorString*, const String& layerId);
- const LayerSnapshot* snapshotById(ErrorString*, const String& snapshotId);
- PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > buildLayerTree();
+ const GraphicsContextSnapshot* snapshotById(ErrorString*, const String& snapshotId);
typedef HashMap<int, int> LayerIdToNodeIdMap;
void buildLayerIdToNodeIdMap(RenderLayer*, LayerIdToNodeIdMap&);
+ void gatherGraphicsLayers(GraphicsLayer*, HashMap<int, int>& layerIdToNodeIdMap, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >&);
int idForNode(Node*);
InspectorFrontend::LayerTree* m_frontend;
Page* m_page;
- InspectorDOMAgent* m_domAgent;
+ Vector<int, 2> m_pageOverlayLayerIds;
- typedef HashMap<String, LayerSnapshot> SnapshotById;
+ typedef HashMap<String, RefPtr<GraphicsContextSnapshot> > SnapshotById;
SnapshotById m_snapshotById;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp
index c754aa09195..404018fbc70 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp
@@ -47,8 +47,8 @@ void InspectorMemoryAgent::getDOMCounters(ErrorString*, int* documents, int* nod
*jsEventListeners = InspectorCounters::counterValue(InspectorCounters::JSEventListenerCounter);
}
-InspectorMemoryAgent::InspectorMemoryAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state)
- : InspectorBaseAgent<InspectorMemoryAgent>("Memory", instrumentingAgents, state)
+InspectorMemoryAgent::InspectorMemoryAgent()
+ : InspectorBaseAgent<InspectorMemoryAgent>("Memory")
, m_frontend(0)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h
index 6b202a86d24..d026071bf5d 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h
@@ -31,7 +31,7 @@
#ifndef InspectorMemoryAgent_h
#define InspectorMemoryAgent_h
-#include "InspectorFrontend.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "wtf/PassOwnPtr.h"
@@ -41,22 +41,22 @@ class InstrumentingAgents;
typedef String ErrorString;
-class InspectorMemoryAgent : public InspectorBaseAgent<InspectorMemoryAgent>, public InspectorBackendDispatcher::MemoryCommandHandler {
+class InspectorMemoryAgent FINAL : public InspectorBaseAgent<InspectorMemoryAgent>, public InspectorBackendDispatcher::MemoryCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorMemoryAgent);
public:
- static PassOwnPtr<InspectorMemoryAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state)
+ static PassOwnPtr<InspectorMemoryAgent> create()
{
- return adoptPtr(new InspectorMemoryAgent(instrumentingAgents, state));
+ return adoptPtr(new InspectorMemoryAgent());
}
virtual ~InspectorMemoryAgent();
- virtual void getDOMCounters(ErrorString*, int* documents, int* nodes, int* jsEventListeners);
+ virtual void getDOMCounters(ErrorString*, int* documents, int* nodes, int* jsEventListeners) OVERRIDE;
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
private:
- InspectorMemoryAgent(InstrumentingAgents*, InspectorCompositeState*);
+ InspectorMemoryAgent();
InspectorFrontend::Memory* m_frontend;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorNodeIds.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorNodeIds.cpp
new file mode 100644
index 00000000000..81bb9e76fc6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorNodeIds.cpp
@@ -0,0 +1,35 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/inspector/InspectorNodeIds.h"
+
+#include "core/dom/WeakNodeMap.h"
+
+namespace WebCore {
+
+static WeakNodeMap& nodeIds()
+{
+ DEFINE_STATIC_LOCAL(WeakNodeMap, self, ());
+ return self;
+}
+
+int InspectorNodeIds::idForNode(Node* node)
+{
+ static int s_nextNodeId = 1;
+ WeakNodeMap& ids = nodeIds();
+ int result = ids.value(node);
+ if (!result) {
+ result = s_nextNodeId++;
+ ids.put(node, result);
+ }
+ return result;
+}
+
+Node* InspectorNodeIds::nodeForId(int id)
+{
+ return nodeIds().node(id);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorNodeIds.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorNodeIds.h
new file mode 100644
index 00000000000..50d3623270a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorNodeIds.h
@@ -0,0 +1,21 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef InspectorNodeIds_h
+#define InspectorNodeIds_h
+
+namespace WebCore {
+
+class Node;
+
+class InspectorNodeIds {
+public:
+ static int idForNode(Node*);
+ static Node* nodeForId(int);
+};
+
+} // namespace WebCore
+
+
+#endif // !defined(InspectorNodeIds_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.cpp
index c2b10d66da0..9c502b01e15 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.cpp
@@ -29,21 +29,21 @@
#include "config.h"
#include "core/inspector/InspectorOverlay.h"
-#include "InspectorOverlayPage.h"
-#include "V8InspectorOverlayHost.h"
+#include "bindings/core/v8/V8InspectorOverlayHost.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "core/InspectorOverlayPage.h"
#include "core/dom/Element.h"
#include "core/dom/Node.h"
#include "core/dom/PseudoElement.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/InspectorClient.h"
#include "core/inspector/InspectorOverlayHost.h"
-#include "core/loader/DocumentLoader.h"
#include "core/loader/EmptyClients.h"
+#include "core/loader/FrameLoadRequest.h"
#include "core/page/Chrome.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/rendering/RenderBoxModelObject.h"
@@ -54,39 +54,43 @@
#include "platform/PlatformMouseEvent.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "wtf/text/StringBuilder.h"
+#include <v8.h>
namespace WebCore {
namespace {
-class InspectorOverlayChromeClient: public EmptyChromeClient {
+struct PathApplyInfo {
+ FrameView* rootView;
+ FrameView* view;
+ TypeBuilder::Array<JSONValue>* array;
+ RenderObject* renderer;
+ const ShapeOutsideInfo* shapeOutsideInfo;
+};
+
+class InspectorOverlayChromeClient FINAL: public EmptyChromeClient {
public:
InspectorOverlayChromeClient(ChromeClient& client, InspectorOverlay* overlay)
: m_client(client)
, m_overlay(overlay)
{ }
- virtual void setCursor(const Cursor& cursor)
+ virtual void setCursor(const Cursor& cursor) OVERRIDE
{
m_client.setCursor(cursor);
}
- virtual void setToolTip(const String& tooltip, TextDirection direction)
+ virtual void setToolTip(const String& tooltip, TextDirection direction) OVERRIDE
{
m_client.setToolTip(tooltip, direction);
}
- virtual void invalidateRootView(const IntRect& rect)
+ virtual void invalidateContentsAndRootView(const IntRect&) OVERRIDE
{
m_overlay->invalidate();
}
- virtual void invalidateContentsAndRootView(const IntRect& rect)
- {
- m_overlay->invalidate();
- }
-
- virtual void invalidateContentsForSlowScroll(const IntRect& rect)
+ virtual void invalidateContentsForSlowScroll(const IntRect&) OVERRIDE
{
m_overlay->invalidate();
}
@@ -143,13 +147,13 @@ static void contentsQuadToPage(const FrameView* mainView, const FrameView* view,
static bool buildNodeQuads(Node* node, Vector<FloatQuad>& quads)
{
RenderObject* renderer = node->renderer();
- Frame* containingFrame = node->document().frame();
+ LocalFrame* containingFrame = node->document().frame();
if (!renderer || !containingFrame)
return false;
FrameView* containingView = containingFrame->view();
- FrameView* mainView = containingFrame->page()->mainFrame()->view();
+ FrameView* mainView = containingFrame->page()->deprecatedLocalMainFrame()->view();
IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect()));
boundingBox.move(mainView->scrollOffset());
@@ -218,7 +222,7 @@ static bool buildNodeQuads(Node* node, Vector<FloatQuad>& quads)
static void buildNodeHighlight(Node* node, const HighlightConfig& highlightConfig, Highlight* highlight)
{
RenderObject* renderer = node->renderer();
- Frame* containingFrame = node->document().frame();
+ LocalFrame* containingFrame = node->document().frame();
if (!renderer || !containingFrame)
return;
@@ -251,6 +255,7 @@ InspectorOverlay::InspectorOverlay(Page* page, InspectorClient* client)
, m_overlayHost(InspectorOverlayHost::create())
, m_drawViewSize(false)
, m_drawViewSizeWithGrid(false)
+ , m_omitTooltip(false)
, m_timer(this, &InspectorOverlay::onTimer)
, m_activeProfilerCount(0)
{
@@ -258,6 +263,7 @@ InspectorOverlay::InspectorOverlay(Page* page, InspectorClient* client)
InspectorOverlay::~InspectorOverlay()
{
+ ASSERT(!m_overlayPage);
}
void InspectorOverlay::paint(GraphicsContext& context)
@@ -265,7 +271,7 @@ void InspectorOverlay::paint(GraphicsContext& context)
if (isEmpty())
return;
GraphicsContextStateSaver stateSaver(context);
- FrameView* view = overlayPage()->mainFrame()->view();
+ FrameView* view = toLocalFrame(overlayPage()->mainFrame())->view();
ASSERT(!view->needsLayout());
view->paint(&context, IntRect(0, 0, view->width(), view->height()));
}
@@ -280,7 +286,7 @@ bool InspectorOverlay::handleGestureEvent(const PlatformGestureEvent& event)
if (isEmpty())
return false;
- return overlayPage()->mainFrame()->eventHandler().handleGestureEvent(event);
+ return toLocalFrame(overlayPage()->mainFrame())->eventHandler().handleGestureEvent(event);
}
bool InspectorOverlay::handleMouseEvent(const PlatformMouseEvent& event)
@@ -288,7 +294,7 @@ bool InspectorOverlay::handleMouseEvent(const PlatformMouseEvent& event)
if (isEmpty())
return false;
- EventHandler& eventHandler = overlayPage()->mainFrame()->eventHandler();
+ EventHandler& eventHandler = toLocalFrame(overlayPage()->mainFrame())->eventHandler();
bool result;
switch (event.type()) {
case PlatformEvent::MouseMoved:
@@ -304,7 +310,7 @@ bool InspectorOverlay::handleMouseEvent(const PlatformMouseEvent& event)
return false;
}
- overlayPage()->mainFrame()->document()->updateLayout();
+ toLocalFrame(overlayPage()->mainFrame())->document()->updateLayout();
return result;
}
@@ -313,7 +319,7 @@ bool InspectorOverlay::handleTouchEvent(const PlatformTouchEvent& event)
if (isEmpty())
return false;
- return overlayPage()->mainFrame()->eventHandler().handleTouchEvent(event);
+ return toLocalFrame(overlayPage()->mainFrame())->eventHandler().handleTouchEvent(event);
}
bool InspectorOverlay::handleKeyboardEvent(const PlatformKeyboardEvent& event)
@@ -321,7 +327,7 @@ bool InspectorOverlay::handleKeyboardEvent(const PlatformKeyboardEvent& event)
if (isEmpty())
return false;
- return overlayPage()->mainFrame()->eventHandler().keyEvent(event);
+ return toLocalFrame(overlayPage()->mainFrame())->eventHandler().keyEvent(event);
}
void InspectorOverlay::drawOutline(GraphicsContext* context, const LayoutRect& rect, const Color& color)
@@ -330,24 +336,6 @@ void InspectorOverlay::drawOutline(GraphicsContext* context, const LayoutRect& r
drawOutlinedQuad(context, outlineRect, Color(), color);
}
-void InspectorOverlay::getHighlight(Highlight* highlight) const
-{
- if (!m_highlightNode && !m_highlightQuad)
- return;
-
- highlight->type = HighlightTypeRects;
- if (m_highlightNode)
- buildNodeHighlight(m_highlightNode.get(), m_nodeHighlightConfig, highlight);
- else
- buildQuadHighlight(m_page, *m_highlightQuad, m_quadHighlightConfig, highlight);
-}
-
-void InspectorOverlay::resize(const IntSize& size)
-{
- m_size = size;
- update();
-}
-
void InspectorOverlay::setPausedInDebuggerMessage(const String* message)
{
m_pausedInDebuggerMessage = message ? *message : String();
@@ -368,11 +356,12 @@ void InspectorOverlay::hideHighlight()
update();
}
-void InspectorOverlay::highlightNode(Node* node, Node* eventTarget, const HighlightConfig& highlightConfig)
+void InspectorOverlay::highlightNode(Node* node, Node* eventTarget, const HighlightConfig& highlightConfig, bool omitTooltip)
{
m_nodeHighlightConfig = highlightConfig;
m_highlightNode = node;
m_eventTargetNode = eventTarget;
+ m_omitTooltip = omitTooltip;
update();
}
@@ -380,6 +369,7 @@ void InspectorOverlay::highlightQuad(PassOwnPtr<FloatQuad> quad, const Highlight
{
m_quadHighlightConfig = highlightConfig;
m_highlightQuad = quad;
+ m_omitTooltip = false;
update();
}
@@ -388,7 +378,7 @@ void InspectorOverlay::showAndHideViewSize(bool showGrid)
m_drawViewSize = true;
m_drawViewSizeWithGrid = showGrid;
update();
- m_timer.startOneShot(1);
+ m_timer.startOneShot(1, FROM_HERE);
}
Node* InspectorOverlay::highlightedNode() const
@@ -400,7 +390,7 @@ bool InspectorOverlay::isEmpty()
{
if (m_activeProfilerCount)
return true;
- bool hasAlwaysVisibleElements = m_highlightNode || m_eventTargetNode || m_highlightQuad || !m_size.isEmpty() || m_drawViewSize;
+ bool hasAlwaysVisibleElements = m_highlightNode || m_eventTargetNode || m_highlightQuad || m_drawViewSize;
bool hasInvisibleInInspectModeElements = !m_pausedInDebuggerMessage.isNull();
return !(hasAlwaysVisibleElements || (hasInvisibleInInspectModeElements && !m_inspectModeEnabled));
}
@@ -412,20 +402,17 @@ void InspectorOverlay::update()
return;
}
- FrameView* view = m_page->mainFrame()->view();
+ FrameView* view = m_page->deprecatedLocalMainFrame()->view();
if (!view)
return;
- IntRect viewRect = view->visibleContentRect();
- FrameView* overlayView = overlayPage()->mainFrame()->view();
// Include scrollbars to avoid masking them by the gutter.
- IntSize frameViewFullSize = view->visibleContentRect(ScrollableArea::IncludeScrollbars).size();
- IntSize size = m_size.isEmpty() ? frameViewFullSize : m_size;
- size.scale(m_page->pageScaleFactor());
- overlayView->resize(size);
+ IntSize size = view->unscaledVisibleContentSize(IncludeScrollbars);
+ toLocalFrame(overlayPage()->mainFrame())->view()->resize(size);
// Clear canvas and paint things.
- reset(size, m_size.isEmpty() ? IntSize() : frameViewFullSize, viewRect.x(), viewRect.y());
+ IntRect viewRect = view->visibleContentRect();
+ reset(size, viewRect.x(), viewRect.y());
drawNodeHighlight();
drawQuadHighlight();
@@ -434,9 +421,8 @@ void InspectorOverlay::update()
drawViewSize();
// Position DOM elements.
- overlayPage()->mainFrame()->document()->recalcStyle(Force);
- if (overlayView->needsLayout())
- overlayView->layout();
+ toLocalFrame(overlayPage()->mainFrame())->document()->setNeedsStyleRecalc(SubtreeStyleChange);
+ toLocalFrame(overlayPage()->mainFrame())->document()->updateLayout();
// Kick paint.
m_client->highlight();
@@ -449,7 +435,6 @@ void InspectorOverlay::hide()
m_eventTargetNode.clear();
m_highlightQuad.clear();
m_pausedInDebuggerMessage = String();
- m_size = IntSize();
m_drawViewSize = false;
m_drawViewSizeWithGrid = false;
update();
@@ -498,6 +483,151 @@ static PassRefPtr<JSONObject> buildObjectForSize(const IntSize& size)
return result.release();
}
+// CSS shapes
+static void appendPathCommandAndPoints(PathApplyInfo* info, const String& command, const FloatPoint points[], unsigned length)
+{
+ FloatPoint point;
+ info->array->addItem(JSONString::create(command));
+ for (unsigned i = 0; i < length; i++) {
+ point = info->shapeOutsideInfo->shapeToRendererPoint(points[i]);
+ point = info->view->contentsToRootView(roundedIntPoint(info->renderer->localToAbsolute(point))) + info->rootView->scrollOffset();
+ info->array->addItem(JSONBasicValue::create(point.x()));
+ info->array->addItem(JSONBasicValue::create(point.y()));
+ }
+}
+
+static void appendPathSegment(void* info, const PathElement* pathElement)
+{
+ PathApplyInfo* pathApplyInfo = static_cast<PathApplyInfo*>(info);
+ FloatPoint point;
+ switch (pathElement->type) {
+ // The points member will contain 1 value.
+ case PathElementMoveToPoint:
+ appendPathCommandAndPoints(pathApplyInfo, "M", pathElement->points, 1);
+ break;
+ // The points member will contain 1 value.
+ case PathElementAddLineToPoint:
+ appendPathCommandAndPoints(pathApplyInfo, "L", pathElement->points, 1);
+ break;
+ // The points member will contain 3 values.
+ case PathElementAddCurveToPoint:
+ appendPathCommandAndPoints(pathApplyInfo, "C", pathElement->points, 3);
+ break;
+ // The points member will contain 2 values.
+ case PathElementAddQuadCurveToPoint:
+ appendPathCommandAndPoints(pathApplyInfo, "Q", pathElement->points, 2);
+ break;
+ // The points member will contain no values.
+ case PathElementCloseSubpath:
+ appendPathCommandAndPoints(pathApplyInfo, "Z", 0, 0);
+ break;
+ }
+}
+
+static RefPtr<TypeBuilder::Array<double> > buildArrayForQuadTypeBuilder(const FloatQuad& quad)
+{
+ RefPtr<TypeBuilder::Array<double> > array = TypeBuilder::Array<double>::create();
+ array->addItem(quad.p1().x());
+ array->addItem(quad.p1().y());
+ array->addItem(quad.p2().x());
+ array->addItem(quad.p2().y());
+ array->addItem(quad.p3().x());
+ array->addItem(quad.p3().y());
+ array->addItem(quad.p4().x());
+ array->addItem(quad.p4().y());
+ return array.release();
+}
+
+PassRefPtr<TypeBuilder::DOM::ShapeOutsideInfo> InspectorOverlay::buildObjectForShapeOutside(Node* node)
+{
+ RenderObject* renderer = node->renderer();
+ if (!renderer || !renderer->isBox() || !toRenderBox(renderer)->shapeOutsideInfo())
+ return nullptr;
+
+ LocalFrame* containingFrame = node->document().frame();
+ RenderBox* renderBox = toRenderBox(renderer);
+ const ShapeOutsideInfo* shapeOutsideInfo = renderBox->shapeOutsideInfo();
+
+ LayoutRect shapeBounds = shapeOutsideInfo->computedShapePhysicalBoundingBox();
+ FloatQuad shapeQuad = renderBox->localToAbsoluteQuad(FloatRect(shapeBounds));
+ FrameView* mainView = containingFrame->page()->deprecatedLocalMainFrame()->view();
+ FrameView* containingView = containingFrame->view();
+ contentsQuadToPage(mainView, containingView, shapeQuad);
+
+ Shape::DisplayPaths paths;
+ shapeOutsideInfo->computedShape().buildDisplayPaths(paths);
+ RefPtr<TypeBuilder::Array<JSONValue> > shapePath = TypeBuilder::Array<JSONValue>::create();
+ RefPtr<TypeBuilder::Array<JSONValue> > marginShapePath = TypeBuilder::Array<JSONValue>::create();
+
+ if (paths.shape.length()) {
+ PathApplyInfo info;
+ info.rootView = mainView;
+ info.view = containingView;
+ info.array = shapePath.get();
+ info.renderer = renderBox;
+ info.shapeOutsideInfo = shapeOutsideInfo;
+ paths.shape.apply(&info, &appendPathSegment);
+
+ if (paths.marginShape.length()) {
+ info.array = marginShapePath.get();
+ paths.marginShape.apply(&info, &appendPathSegment);
+ }
+ }
+ RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeTypeBuilder = TypeBuilder::DOM::ShapeOutsideInfo::create()
+ .setBounds(buildArrayForQuadTypeBuilder(shapeQuad))
+ .setShape(shapePath)
+ .setMarginShape(marginShapePath);
+
+ return shapeTypeBuilder.release();
+}
+
+static void setElementInfo(RefPtr<JSONObject>& highlightObject, RefPtr<JSONObject>& shapeObject, Node* node)
+{
+ RefPtr<JSONObject> elementInfo = JSONObject::create();
+ Element* element = toElement(node);
+ Element* realElement = element;
+ PseudoElement* pseudoElement = 0;
+ if (element->isPseudoElement()) {
+ pseudoElement = toPseudoElement(element);
+ realElement = element->parentOrShadowHostElement();
+ }
+ bool isXHTML = realElement->document().isXHTMLDocument();
+ elementInfo->setString("tagName", isXHTML ? realElement->nodeName() : realElement->nodeName().lower());
+ elementInfo->setString("idValue", realElement->getIdAttribute());
+ StringBuilder classNames;
+ if (realElement->hasClass() && realElement->isStyledElement()) {
+ HashSet<AtomicString> usedClassNames;
+ const SpaceSplitString& classNamesString = realElement->classNames();
+ size_t classNameCount = classNamesString.size();
+ for (size_t i = 0; i < classNameCount; ++i) {
+ const AtomicString& className = classNamesString[i];
+ if (!usedClassNames.add(className).isNewEntry)
+ continue;
+ classNames.append('.');
+ classNames.append(className);
+ }
+ }
+ if (pseudoElement) {
+ if (pseudoElement->pseudoId() == BEFORE)
+ classNames.append("::before");
+ else if (pseudoElement->pseudoId() == AFTER)
+ classNames.append("::after");
+ }
+ if (!classNames.isEmpty())
+ elementInfo->setString("className", classNames.toString());
+
+ RenderObject* renderer = node->renderer();
+ LocalFrame* containingFrame = node->document().frame();
+ FrameView* containingView = containingFrame->view();
+ IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect()));
+ RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0;
+ elementInfo->setString("nodeWidth", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetWidth(), modelObject) : boundingBox.width()));
+ elementInfo->setString("nodeHeight", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetHeight(), modelObject) : boundingBox.height()));
+ if (renderer->isBox() && shapeObject)
+ elementInfo->setObject("shapeOutsideInfo", shapeObject.release());
+ highlightObject->setObject("elementInfo", elementInfo.release());
+}
+
void InspectorOverlay::drawNodeHighlight()
{
if (!m_highlightNode)
@@ -513,49 +643,10 @@ void InspectorOverlay::drawNodeHighlight()
RefPtr<JSONObject> highlightObject = buildObjectForHighlight(highlight);
Node* node = m_highlightNode.get();
- if (node->isElementNode() && m_nodeHighlightConfig.showInfo && node->renderer() && node->document().frame()) {
- RefPtr<JSONObject> elementInfo = JSONObject::create();
- Element* element = toElement(node);
- Element* realElement = element;
- PseudoElement* pseudoElement = 0;
- if (element->isPseudoElement()) {
- pseudoElement = toPseudoElement(element);
- realElement = element->parentOrShadowHostElement();
- }
- bool isXHTML = realElement->document().isXHTMLDocument();
- elementInfo->setString("tagName", isXHTML ? realElement->nodeName() : realElement->nodeName().lower());
- elementInfo->setString("idValue", realElement->getIdAttribute());
- StringBuilder classNames;
- if (realElement->hasClass() && realElement->isStyledElement()) {
- HashSet<AtomicString> usedClassNames;
- const SpaceSplitString& classNamesString = realElement->classNames();
- size_t classNameCount = classNamesString.size();
- for (size_t i = 0; i < classNameCount; ++i) {
- const AtomicString& className = classNamesString[i];
- if (!usedClassNames.add(className).isNewEntry)
- continue;
- classNames.append('.');
- classNames.append(className);
- }
- }
- if (pseudoElement) {
- if (pseudoElement->pseudoId() == BEFORE)
- classNames.append("::before");
- else if (pseudoElement->pseudoId() == AFTER)
- classNames.append("::after");
- }
- if (!classNames.isEmpty())
- elementInfo->setString("className", classNames.toString());
-
- RenderObject* renderer = node->renderer();
- Frame* containingFrame = node->document().frame();
- FrameView* containingView = containingFrame->view();
- IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect()));
- RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0;
- elementInfo->setString("nodeWidth", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetWidth(), modelObject) : boundingBox.width()));
- elementInfo->setString("nodeHeight", String::number(modelObject ? adjustForAbsoluteZoom(modelObject->pixelSnappedOffsetHeight(), modelObject) : boundingBox.height()));
- highlightObject->setObject("elementInfo", elementInfo.release());
- }
+ RefPtr<TypeBuilder::DOM::ShapeOutsideInfo> shapeObject = buildObjectForShapeOutside(node);
+ RefPtr<JSONObject> shapeObjectJSON = shapeObject ? shapeObject->asObject() : nullptr;
+ if (node->isElementNode() && !m_omitTooltip && m_nodeHighlightConfig.showInfo && node->renderer() && node->document().frame())
+ setElementInfo(highlightObject, shapeObjectJSON, node);
evaluateInOverlay("drawNodeHighlight", highlightObject);
}
@@ -592,7 +683,7 @@ Page* InspectorOverlay::overlayPage()
ASSERT(!m_overlayChromeClient);
m_overlayChromeClient = adoptPtr(new InspectorOverlayChromeClient(m_page->chrome().client(), this));
pageClients.chromeClient = m_overlayChromeClient.get();
- m_overlayPage = adoptPtr(new Page(pageClients));
+ m_overlayPage = adoptPtrWillBeNoop(new Page(pageClients));
Settings& settings = m_page->settings();
Settings& overlaySettings = m_overlayPage->settings();
@@ -605,27 +696,29 @@ Page* InspectorOverlay::overlayPage()
overlaySettings.genericFontFamilySettings().setPictograph(settings.genericFontFamilySettings().pictograph());
overlaySettings.setMinimumFontSize(settings.minimumFontSize());
overlaySettings.setMinimumLogicalFontSize(settings.minimumLogicalFontSize());
- overlaySettings.setMediaEnabled(false);
overlaySettings.setScriptEnabled(true);
overlaySettings.setPluginsEnabled(false);
overlaySettings.setLoadsImagesAutomatically(true);
+ // FIXME: http://crbug.com/363843. Inspector should probably create its
+ // own graphics layers and attach them to the tree rather than going
+ // through some non-composited paint function.
+ overlaySettings.setAcceleratedCompositingEnabled(false);
- RefPtr<Frame> frame = Frame::create(FrameInit::create(0, m_overlayPage.get(), dummyFrameLoaderClient));
+ RefPtr<LocalFrame> frame = LocalFrame::create(dummyFrameLoaderClient, &m_overlayPage->frameHost(), 0);
frame->setView(FrameView::create(frame.get()));
frame->init();
FrameLoader& loader = frame->loader();
frame->view()->setCanHaveScrollbars(false);
frame->view()->setTransparent(true);
- ASSERT(loader.activeDocumentLoader());
- DocumentWriter* writer = loader.activeDocumentLoader()->beginWriting("text/html", "UTF-8");
- writer->addData(reinterpret_cast<const char*>(InspectorOverlayPage_html), sizeof(InspectorOverlayPage_html));
- loader.activeDocumentLoader()->endWriting(writer);
+
+ RefPtr<SharedBuffer> data = SharedBuffer::create(reinterpret_cast<const char*>(InspectorOverlayPage_html), sizeof(InspectorOverlayPage_html));
+ loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad)));
v8::Isolate* isolate = toIsolate(frame.get());
- v8::HandleScope handleScope(isolate);
- v8::Handle<v8::Context> frameContext = frame->script().currentWorldContext();
- v8::Context::Scope contextScope(frameContext);
- v8::Handle<v8::Value> overlayHostObj = toV8(m_overlayHost.get(), v8::Handle<v8::Object>(), isolate);
- v8::Handle<v8::Object> global = frameContext->Global();
+ ScriptState* scriptState = ScriptState::forMainWorld(frame.get());
+ ASSERT(!scriptState->contextIsEmpty());
+ ScriptState::Scope scope(scriptState);
+ v8::Handle<v8::Object> global = scriptState->context()->Global();
+ v8::Handle<v8::Value> overlayHostObj = toV8(m_overlayHost.get(), global, isolate);
global->Set(v8::String::NewFromUtf8(isolate, "InspectorOverlayHost"), overlayHostObj);
#if OS(WIN)
@@ -639,14 +732,13 @@ Page* InspectorOverlay::overlayPage()
return m_overlayPage.get();
}
-void InspectorOverlay::reset(const IntSize& viewportSize, const IntSize& frameViewFullSize, int scrollX, int scrollY)
+void InspectorOverlay::reset(const IntSize& viewportSize, int scrollX, int scrollY)
{
RefPtr<JSONObject> resetData = JSONObject::create();
- resetData->setNumber("pageScaleFactor", m_page->pageScaleFactor());
+ resetData->setNumber("pageScaleFactor", m_page->settings().pinchVirtualViewportEnabled() ? 1 : m_page->pageScaleFactor());
resetData->setNumber("deviceScaleFactor", m_page->deviceScaleFactor());
resetData->setObject("viewportSize", buildObjectForSize(viewportSize));
- resetData->setObject("frameViewFullSize", buildObjectForSize(frameViewFullSize));
- resetData->setNumber("pageZoomFactor", m_page->mainFrame()->pageZoomFactor());
+ resetData->setNumber("pageZoomFactor", m_page->deprecatedLocalMainFrame()->pageZoomFactor());
resetData->setNumber("scrollX", scrollX);
resetData->setNumber("scrollY", scrollY);
evaluateInOverlay("reset", resetData.release());
@@ -657,7 +749,7 @@ void InspectorOverlay::evaluateInOverlay(const String& method, const String& arg
RefPtr<JSONArray> command = JSONArray::create();
command->pushString(method);
command->pushString(argument);
- overlayPage()->mainFrame()->script().executeScriptInMainWorld("dispatch(" + command->toJSONString() + ")", ScriptController::ExecuteScriptWhenScriptsDisabled);
+ toLocalFrame(overlayPage()->mainFrame())->script().executeScriptInMainWorld("dispatch(" + command->toJSONString() + ")", ScriptController::ExecuteScriptWhenScriptsDisabled);
}
void InspectorOverlay::evaluateInOverlay(const String& method, PassRefPtr<JSONValue> argument)
@@ -665,7 +757,7 @@ void InspectorOverlay::evaluateInOverlay(const String& method, PassRefPtr<JSONVa
RefPtr<JSONArray> command = JSONArray::create();
command->pushString(method);
command->pushValue(argument);
- overlayPage()->mainFrame()->script().executeScriptInMainWorld("dispatch(" + command->toJSONString() + ")", ScriptController::ExecuteScriptWhenScriptsDisabled);
+ toLocalFrame(overlayPage()->mainFrame())->script().executeScriptInMainWorld("dispatch(" + command->toJSONString() + ")", ScriptController::ExecuteScriptWhenScriptsDisabled);
}
void InspectorOverlay::onTimer(Timer<InspectorOverlay>*)
@@ -681,9 +773,15 @@ bool InspectorOverlay::getBoxModel(Node* node, Vector<FloatQuad>* quads)
void InspectorOverlay::freePage()
{
- m_overlayPage.clear();
+ if (m_overlayPage) {
+ m_overlayPage->willBeDestroyed();
+ m_overlayPage.clear();
+ }
m_overlayChromeClient.clear();
m_timer.stop();
+
+ // This will clear internal structures and issue update to the client. Safe to call last.
+ hideHighlight();
}
void InspectorOverlay::startedRecordingProfile()
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.h
index 609cf52cf8c..4196ba4eb14 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlay.h
@@ -29,10 +29,12 @@
#ifndef InspectorOverlay_h
#define InspectorOverlay_h
+#include "core/InspectorTypeBuilder.h"
#include "platform/Timer.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/LayoutRect.h"
#include "platform/graphics/Color.h"
+#include "platform/heap/Handle.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/RefPtr.h"
@@ -46,6 +48,7 @@ class EmptyChromeClient;
class GraphicsContext;
class InspectorClient;
class InspectorOverlayHost;
+class JSONObject;
class JSONValue;
class Node;
class Page;
@@ -118,8 +121,6 @@ public:
void hide();
void paint(GraphicsContext&);
void drawOutline(GraphicsContext*, const LayoutRect&, const Color&);
- void getHighlight(Highlight*) const;
- void resize(const IntSize&);
bool handleGestureEvent(const PlatformGestureEvent&);
bool handleMouseEvent(const PlatformMouseEvent&);
bool handleTouchEvent(const PlatformTouchEvent&);
@@ -129,12 +130,13 @@ public:
void setInspectModeEnabled(bool);
void hideHighlight();
- void highlightNode(Node*, Node* eventTarget, const HighlightConfig&);
+ void highlightNode(Node*, Node* eventTarget, const HighlightConfig&, bool omitTooltip);
void highlightQuad(PassOwnPtr<FloatQuad>, const HighlightConfig&);
void showAndHideViewSize(bool showGrid);
Node* highlightedNode() const;
bool getBoxModel(Node*, Vector<FloatQuad>*);
+ PassRefPtr<TypeBuilder::DOM::ShapeOutsideInfo> buildObjectForShapeOutside(Node*);
void freePage();
@@ -156,7 +158,7 @@ private:
void drawViewSize();
Page* overlayPage();
- void reset(const IntSize& viewportSize, const IntSize& frameViewFullSize, int scrollX, int scrollY);
+ void reset(const IntSize& viewportSize, int scrollX, int scrollY);
void evaluateInOverlay(const String& method, const String& argument);
void evaluateInOverlay(const String& method, PassRefPtr<JSONValue> argument);
void onTimer(Timer<InspectorOverlay>*);
@@ -165,17 +167,17 @@ private:
InspectorClient* m_client;
String m_pausedInDebuggerMessage;
bool m_inspectModeEnabled;
- RefPtr<Node> m_highlightNode;
- RefPtr<Node> m_eventTargetNode;
+ RefPtrWillBePersistent<Node> m_highlightNode;
+ RefPtrWillBePersistent<Node> m_eventTargetNode;
HighlightConfig m_nodeHighlightConfig;
OwnPtr<FloatQuad> m_highlightQuad;
- OwnPtr<Page> m_overlayPage;
+ OwnPtrWillBePersistent<Page> m_overlayPage;
OwnPtr<EmptyChromeClient> m_overlayChromeClient;
RefPtr<InspectorOverlayHost> m_overlayHost;
HighlightConfig m_quadHighlightConfig;
- IntSize m_size;
bool m_drawViewSize;
bool m_drawViewSizeWithGrid;
+ bool m_omitTooltip;
Timer<InspectorOverlay> m_timer;
int m_activeProfilerCount;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp
index 830dd54109a..7990a5454a0 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayHost.cpp
@@ -28,7 +28,7 @@
#include "config.h"
-#include "InspectorOverlayHost.h"
+#include "core/inspector/InspectorOverlayHost.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html b/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html
index c10cac7f9e5..2d99d2c74d1 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorOverlayPage.html
@@ -89,29 +89,30 @@ body.platform-linux {
box-sizing: border-box;
}
-.controls-line button {
+.controls-line .button {
width: 26px;
margin-left: -1px;
margin-right: 0;
padding: 0;
}
-.controls-line button:hover {
+.controls-line .button:hover {
cursor: pointer;
}
-.controls-line button .glyph {
+.controls-line .button .glyph {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.75);
opacity: 0.8;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: center;
+ position: relative;
}
-.controls-line button:active {
- border: 1px solid rgb(120, 120, 120);
- z-index: 1;
+.controls-line .button:active .glyph {
+ top: 1px;
+ left: 1px;
}
#resume-button .glyph {
@@ -155,6 +156,9 @@ const lightGridColor = "rgba(0,0,0,0.2)";
const darkGridColor = "rgba(0,0,0,0.7)";
const transparentColor = "rgba(0, 0, 0, 0)";
const gridBackgroundColor = "rgba(255, 255, 255, 0.8)";
+// CSS shapes
+const shapeHighlightColor = "rgba(96, 82, 127, 0.8)";
+const shapeMarginHighlightColor = "rgba(96, 82, 127, 0.6)";
function drawPausedInDebuggerMessage(message)
{
@@ -365,7 +369,7 @@ function drawViewSize(drawViewSizeWithGrid)
case "linux": context.font = "14px dejavu sans mono"; break;
}
- var frameWidth = frameViewFullSize.width || canvasWidth;
+ var frameWidth = canvasWidth;
var textWidth = context.measureText(text).width;
context.fillStyle = gridBackgroundColor;
context.fillRect(frameWidth - textWidth - 12, drawGridBoolean ? 15 : 0, frameWidth, 25);
@@ -379,7 +383,6 @@ function drawViewSize(drawViewSizeWithGrid)
function reset(resetData)
{
window.viewportSize = resetData.viewportSize;
- window.frameViewFullSize = resetData.frameViewFullSize;
window.deviceScaleFactor = resetData.deviceScaleFactor;
window.pageZoomFactor = resetData.pageZoomFactor;
window.pageScaleFactor = resetData.pageScaleFactor;
@@ -425,14 +428,15 @@ function _drawElementTitle(highlight)
var titleWidth = elementTitle.offsetWidth + 6;
var titleHeight = elementTitle.offsetHeight + 4;
- var anchorTop = marginQuad[0].y;
- var anchorBottom = marginQuad[3].y
+ var anchorTop = Math.min(marginQuad[0].y, marginQuad[1].y, marginQuad[2].y, marginQuad[3].y);
+ var anchorBottom = Math.max(marginQuad[0].y, marginQuad[1].y, marginQuad[2].y, marginQuad[3].y);
+ var anchorLeft = Math.min(marginQuad[0].x, marginQuad[1].x, marginQuad[2].x, marginQuad[3].x);
const arrowHeight = 7;
var renderArrowUp = false;
var renderArrowDown = false;
- var boxX = Math.max(2, marginQuad[0].x);
+ var boxX = Math.max(2, anchorLeft);
if (boxX + titleWidth > canvasWidth)
boxX = canvasWidth - titleWidth - 2;
@@ -541,6 +545,54 @@ function _drawRulers(highlight, rulerAtRight, rulerAtBottom)
context.restore();
}
+// CSS shapes
+function drawPath(commands, fillColor)
+{
+ context.save();
+ context.beginPath();
+
+ var commandsIndex = 0;
+ var commandsLength = commands.length;
+ while (commandsIndex < commandsLength) {
+ switch (commands[commandsIndex++]) {
+ case "M":
+ context.moveTo(commands[commandsIndex++], commands[commandsIndex++]);
+ break;
+ case "L":
+ context.lineTo(commands[commandsIndex++], commands[commandsIndex++]);
+ break;
+ case "C":
+ context.bezierCurveTo(commands[commandsIndex++], commands[commandsIndex++], commands[commandsIndex++],
+ commands[commandsIndex++], commands[commandsIndex++], commands[commandsIndex++]);
+ break;
+ case "Q":
+ context.quadraticCurveTo(commands[commandsIndex++], commands[commandsIndex++], commands[commandsIndex++],
+ commands[commandsIndex++]);
+ break;
+ case "Z":
+ context.closePath();
+ break;
+ }
+ }
+ context.closePath();
+ context.fillStyle = fillColor;
+ context.fill();
+
+ context.restore();
+}
+
+function drawShapeHighlight(shapeInfo)
+{
+ if (shapeInfo.marginShape)
+ drawPath(shapeInfo.marginShape, shapeMarginHighlightColor);
+ else
+ drawOutlinedQuad(shapeInfo.bounds, shapeHighlightColor, shapeHighlightColor);
+
+ if (shapeInfo.shape)
+ drawPath(shapeInfo.shape, shapeHighlightColor);
+ else
+ drawOutlinedQuad(shapeInfo.bounds, shapeHighlightColor, shapeHighlightColor);
+}
function drawNodeHighlight(highlight)
{
@@ -613,6 +665,8 @@ function drawNodeHighlight(highlight)
_drawGrid(rulerAtRight, rulerAtBottom);
_drawRulers(highlight, rulerAtRight, rulerAtBottom);
}
+ if (highlight.elementInfo && highlight.elementInfo.shapeOutsideInfo)
+ drawShapeHighlight(highlight.elementInfo.shapeOutsideInfo);
_drawElementTitle(highlight);
context.restore();
@@ -683,8 +737,8 @@ document.addEventListener("keydown", onDocumentKeyDown);
<body class="fill">
<div class="controls-line">
<div class="message-box"><div id="paused-in-debugger"></div></div>
- <button id="resume-button" title="Resume script execution (F8)."><div class="glyph"></div></button>
- <button id="step-over-button" title="Step over next function call (F10)."><div class="glyph"></div></button>
+ <div class="button" id="resume-button" title="Resume script execution (F8)."><div class="glyph"></div></div>
+ <div class="button" id="step-over-button" title="Step over next function call (F10)."><div class="glyph"></div></div>
</div>
</body>
<canvas id="canvas" class="fill"></canvas>
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
index 077d556cf77..e19034109d7 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -31,11 +31,11 @@
#include "config.h"
#include "core/inspector/InspectorPageAgent.h"
-#include "HTMLNames.h"
-#include "UserAgentStyleSheets.h"
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptRegexp.h"
+#include "core/HTMLNames.h"
+#include "core/UserAgentStyleSheets.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/ViewportStyleResolver.h"
#include "core/dom/DOMImplementation.h"
@@ -47,8 +47,14 @@
#include "core/fetch/Resource.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ScriptResource.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/html/imports/HTMLImport.h"
+#include "core/html/imports/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportsController.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/ContentSearchUtils.h"
#include "core/inspector/DOMPatchSupport.h"
#include "core/inspector/IdentifiersFactory.h"
@@ -56,20 +62,14 @@
#include "core/inspector/InspectorClient.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/InspectorOverlay.h"
+#include "core/inspector/InspectorResourceContentLoader.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/loader/CookieJar.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
-#include "core/frame/Settings.h"
-#include "modules/device_orientation/DeviceOrientationController.h"
-#include "modules/device_orientation/DeviceOrientationData.h"
-#include "modules/geolocation/GeolocationController.h"
#include "platform/Cookie.h"
#include "platform/JSONValues.h"
#include "platform/UserGestureIndicator.h"
@@ -86,6 +86,7 @@ namespace PageAgentState {
static const char pageAgentEnabled[] = "pageAgentEnabled";
static const char pageAgentScriptExecutionDisabled[] = "pageAgentScriptExecutionDisabled";
static const char pageAgentScriptsToEvaluateOnLoad[] = "pageAgentScriptsToEvaluateOnLoad";
+static const char deviceMetricsOverrideEnabled[] = "deviceMetricsOverrideEnabled";
static const char pageAgentScreenWidthOverride[] = "pageAgentScreenWidthOverride";
static const char pageAgentScreenHeightOverride[] = "pageAgentScreenHeightOverride";
static const char pageAgentDeviceScaleFactorOverride[] = "pageAgentDeviceScaleFactorOverride";
@@ -149,7 +150,7 @@ static bool prepareResourceBuffer(Resource* cachedResource, bool* hasZeroSize)
// FIXME: should we do something else in the case of a purged
// resource that informs the user why there is no data in the
// inspector?
- if (!cachedResource->makePurgeable(false))
+ if (!cachedResource->lock())
return false;
}
@@ -166,7 +167,7 @@ static PassOwnPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeTy
{
if (!textEncodingName.isEmpty())
return TextResourceDecoder::create("text/plain", textEncodingName);
- if (DOMImplementation::isXMLMIMEType(mimeType.lower())) {
+ if (DOMImplementation::isXMLMIMEType(mimeType)) {
OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
decoder->useLenientXMLDecoding();
return decoder.release();
@@ -242,13 +243,13 @@ bool InspectorPageAgent::dataContent(const char* data, unsigned size, const Stri
return decodeBuffer(data, size, textEncodingName, result);
}
-PassOwnPtr<InspectorPageAgent> InspectorPageAgent::create(InstrumentingAgents* instrumentingAgents, Page* page, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
+PassOwnPtr<InspectorPageAgent> InspectorPageAgent::create(Page* page, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
{
- return adoptPtr(new InspectorPageAgent(instrumentingAgents, page, state, injectedScriptManager, client, overlay));
+ return adoptPtr(new InspectorPageAgent(page, injectedScriptManager, client, overlay));
}
// static
-void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame, const KURL& url, String* result, bool* base64Encoded)
+void InspectorPageAgent::resourceContent(ErrorString* errorString, LocalFrame* frame, const KURL& url, String* result, bool* base64Encoded)
{
DocumentLoader* loader = assertDocumentLoader(errorString, frame);
if (!loader)
@@ -257,7 +258,7 @@ void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame,
*errorString = "No resource with given URL found";
}
-Resource* InspectorPageAgent::cachedResource(Frame* frame, const KURL& url)
+Resource* InspectorPageAgent::cachedResource(LocalFrame* frame, const KURL& url)
{
Resource* cachedResource = frame->document()->fetcher()->cachedResource(url);
if (!cachedResource)
@@ -270,14 +271,18 @@ TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::resourceTypeJson(Inspe
switch (resourceType) {
case DocumentResource:
return TypeBuilder::Page::ResourceType::Document;
+ case FontResource:
+ return TypeBuilder::Page::ResourceType::Font;
case ImageResource:
return TypeBuilder::Page::ResourceType::Image;
- case Font:
- return TypeBuilder::Page::ResourceType::Font;
- case StylesheetResource:
- return TypeBuilder::Page::ResourceType::Stylesheet;
+ case MediaResource:
+ return TypeBuilder::Page::ResourceType::Media;
case ScriptResource:
return TypeBuilder::Page::ResourceType::Script;
+ case StylesheetResource:
+ return TypeBuilder::Page::ResourceType::Stylesheet;
+ case TextTrackResource:
+ return TypeBuilder::Page::ResourceType::TextTrack;
case XHRResource:
return TypeBuilder::Page::ResourceType::XHR;
case WebSocketResource:
@@ -294,7 +299,11 @@ InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Re
case Resource::Image:
return InspectorPageAgent::ImageResource;
case Resource::Font:
- return InspectorPageAgent::Font;
+ return InspectorPageAgent::FontResource;
+ case Resource::Media:
+ return InspectorPageAgent::MediaResource;
+ case Resource::TextTrack:
+ return InspectorPageAgent::TextTrackResource;
case Resource::CSSStyleSheet:
// Fall through.
case Resource::XSLStyleSheet:
@@ -303,6 +312,8 @@ InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const Re
return InspectorPageAgent::ScriptResource;
case Resource::Raw:
return InspectorPageAgent::XHRResource;
+ case Resource::ImportResource:
+ // Fall through.
case Resource::MainResource:
return InspectorPageAgent::DocumentResource;
default:
@@ -316,8 +327,8 @@ TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::cachedResourceTypeJson
return resourceTypeJson(cachedResourceType(cachedResource));
}
-InspectorPageAgent::InspectorPageAgent(InstrumentingAgents* instrumentingAgents, Page* page, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
- : InspectorBaseAgent<InspectorPageAgent>("Page", instrumentingAgents, inspectorState)
+InspectorPageAgent::InspectorPageAgent(Page* page, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
+ : InspectorBaseAgent<InspectorPageAgent>("Page")
, m_page(page)
, m_injectedScriptManager(injectedScriptManager)
, m_client(client)
@@ -325,11 +336,30 @@ InspectorPageAgent::InspectorPageAgent(InstrumentingAgents* instrumentingAgents,
, m_overlay(overlay)
, m_lastScriptIdentifier(0)
, m_enabled(false)
- , m_geolocationOverridden(false)
, m_ignoreScriptsEnabledNotification(false)
, m_deviceMetricsOverridden(false)
, m_emulateViewportEnabled(false)
+ , m_touchEmulationEnabled(false)
+ , m_originalTouchEnabled(false)
+ , m_originalDeviceSupportsMouse(false)
+ , m_originalDeviceSupportsTouch(false)
+ , m_embedderTextAutosizingEnabled(m_page->settings().textAutosizingEnabled())
+ , m_embedderFontScaleFactor(m_page->settings().deviceScaleAdjustment())
+{
+}
+
+void InspectorPageAgent::setTextAutosizingEnabled(bool enabled)
{
+ m_embedderTextAutosizingEnabled = enabled;
+ if (!m_deviceMetricsOverridden)
+ m_page->settings().setTextAutosizingEnabled(enabled);
+}
+
+void InspectorPageAgent::setDeviceScaleAdjustment(float deviceScaleAdjustment)
+{
+ m_embedderFontScaleFactor = deviceScaleAdjustment;
+ if (!m_deviceMetricsOverridden)
+ m_page->settings().setDeviceScaleAdjustment(deviceScaleAdjustment);
}
void InspectorPageAgent::setFrontend(InspectorFrontend* frontend)
@@ -341,7 +371,6 @@ void InspectorPageAgent::clearFrontend()
{
ErrorString error;
disable(&error);
- updateTouchEventEmulationInPage(false);
m_frontend = 0;
}
@@ -365,27 +394,17 @@ void InspectorPageAgent::restore()
bool showScrollBottleneckRects = m_state->getBoolean(PageAgentState::pageAgentShowScrollBottleneckRects);
setShowScrollBottleneckRects(0, showScrollBottleneckRects);
- int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
- int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
- double currentDeviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride);
- bool currentEmulateViewport = m_state->getBoolean(PageAgentState::pageAgentEmulateViewport);
- bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
- updateViewMetrics(currentWidth, currentHeight, currentDeviceScaleFactor, currentEmulateViewport, currentFitWindow);
+ updateViewMetricsFromState();
updateTouchEventEmulationInPage(m_state->getBoolean(PageAgentState::touchEventEmulationEnabled));
}
}
-void InspectorPageAgent::webViewResized(const IntSize& size)
-{
- int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
- m_overlay->resize(currentWidth ? size : IntSize());
-}
-
void InspectorPageAgent::enable(ErrorString*)
{
m_enabled = true;
m_state->setBoolean(PageAgentState::pageAgentEnabled, true);
m_instrumentingAgents->setInspectorPageAgent(this);
+ m_inspectorResourceContentLoader = adoptPtr(new InspectorResourceContentLoader(m_page));
}
void InspectorPageAgent::disable(ErrorString*)
@@ -395,24 +414,31 @@ void InspectorPageAgent::disable(ErrorString*)
m_state->remove(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
m_overlay->hide();
m_instrumentingAgents->setInspectorPageAgent(0);
+ m_inspectorResourceContentLoader.clear();
m_deviceMetricsOverridden = false;
setShowPaintRects(0, false);
setShowDebugBorders(0, false);
setShowFPSCounter(0, false);
setEmulatedMedia(0, String());
- setContinuousPaintingEnabled(0, false);
+ if (m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled))
+ setContinuousPaintingEnabled(0, false);
setShowScrollBottleneckRects(0, false);
setShowViewportSizeOnResize(0, false, 0);
- if (!deviceMetricsChanged(0, 0, 1, false, false, 1, false))
+ if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled)) {
+ updateTouchEventEmulationInPage(false);
+ m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, false);
+ }
+
+ if (!deviceMetricsChanged(false, 0, 0, 0, false, false, 1, false))
return;
// When disabling the agent, reset the override values if necessary.
- updateViewMetrics(0, 0, 1, false, false);
+ updateViewMetrics(false, 0, 0, 0, false, false, m_embedderFontScaleFactor, m_embedderTextAutosizingEnabled);
m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, 0);
m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, 0);
- m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 1);
+ m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 0);
m_state->setBoolean(PageAgentState::pageAgentEmulateViewport, false);
m_state->setBoolean(PageAgentState::pageAgentFitWindow, false);
m_state->setDouble(PageAgentState::fontScaleFactor, 1);
@@ -451,23 +477,17 @@ void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCa
{
m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : "";
m_pendingScriptPreprocessor = optionalScriptPreprocessor ? *optionalScriptPreprocessor : "";
- m_page->mainFrame()->loader().reload(optionalIgnoreCache && *optionalIgnoreCache ? EndToEndReload : NormalReload);
+ m_page->deprecatedLocalMainFrame()->loader().reload(optionalIgnoreCache && *optionalIgnoreCache ? EndToEndReload : NormalReload);
}
void InspectorPageAgent::navigate(ErrorString*, const String& url)
{
UserGestureIndicator indicator(DefinitelyProcessingNewUserGesture);
- Frame* frame = m_page->mainFrame();
+ LocalFrame* frame = m_page->deprecatedLocalMainFrame();
FrameLoadRequest request(frame->document(), ResourceRequest(frame->document()->completeURL(url)));
frame->loader().load(request);
}
-void InspectorPageAgent::getNavigationHistory(ErrorString*, int*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::NavigationEntry> >&)
-{ }
-
-void InspectorPageAgent::navigateToHistoryEntry(ErrorString*, int)
-{ }
-
static PassRefPtr<TypeBuilder::Page::Cookie> buildObjectForCookie(const Cookie& cookie)
{
return TypeBuilder::Page::Cookie::create()
@@ -495,11 +515,9 @@ static PassRefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > buildArrayForC
return cookies;
}
-static Vector<Resource*> cachedResourcesForFrame(Frame* frame)
+static void cachedResourcesForDocument(Document* document, Vector<Resource*>& result)
{
- Vector<Resource*> result;
-
- const ResourceFetcher::DocumentResourceMap& allResources = frame->document()->fetcher()->allResources();
+ const ResourceFetcher::DocumentResourceMap& allResources = document->fetcher()->allResources();
ResourceFetcher::DocumentResourceMap::const_iterator end = allResources.end();
for (ResourceFetcher::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
Resource* cachedResource = it->value.get();
@@ -522,11 +540,38 @@ static Vector<Resource*> cachedResourcesForFrame(Frame* frame)
result.append(cachedResource);
}
+}
+
+// static
+Vector<Document*> InspectorPageAgent::importsForFrame(LocalFrame* frame)
+{
+ Vector<Document*> result;
+ Document* rootDocument = frame->document();
+
+ if (HTMLImportsController* controller = rootDocument->importsController()) {
+ for (size_t i = 0; i < controller->loaderCount(); ++i) {
+ if (Document* document = controller->loaderAt(i)->document())
+ result.append(document);
+ }
+ }
+
+ return result;
+}
+
+static Vector<Resource*> cachedResourcesForFrame(LocalFrame* frame)
+{
+ Vector<Resource*> result;
+ Document* rootDocument = frame->document();
+ Vector<Document*> loaders = InspectorPageAgent::importsForFrame(frame);
+
+ cachedResourcesForDocument(rootDocument, result);
+ for (size_t i = 0; i < loaders.size(); ++i)
+ cachedResourcesForDocument(loaders[i], result);
return result;
}
-static Vector<KURL> allResourcesURLsForFrame(Frame* frame)
+static Vector<KURL> allResourcesURLsForFrame(LocalFrame* frame)
{
Vector<KURL> result;
@@ -544,8 +589,10 @@ void InspectorPageAgent::getCookies(ErrorString*, RefPtr<TypeBuilder::Array<Type
ListHashSet<Cookie> rawCookiesList;
for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext(mainFrame())) {
- Document* document = frame->document();
- Vector<KURL> allURLs = allResourcesURLsForFrame(frame);
+ if (!frame->isLocalFrame())
+ continue;
+ Document* document = toLocalFrame(frame)->document();
+ Vector<KURL> allURLs = allResourcesURLsForFrame(toLocalFrame(frame));
for (Vector<KURL>::const_iterator it = allURLs.begin(); it != allURLs.end(); ++it) {
Vector<Cookie> docCookiesList;
getRawCookies(document, *it, docCookiesList);
@@ -563,18 +610,20 @@ void InspectorPageAgent::getCookies(ErrorString*, RefPtr<TypeBuilder::Array<Type
void InspectorPageAgent::deleteCookie(ErrorString*, const String& cookieName, const String& url)
{
KURL parsedURL(ParsedURLString, url);
- for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext(m_page->mainFrame()))
- WebCore::deleteCookie(frame->document(), parsedURL, cookieName);
+ for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext(m_page->mainFrame())) {
+ if (frame->isLocalFrame())
+ WebCore::deleteCookie(toLocalFrame(frame)->document(), parsedURL, cookieName);
+ }
}
void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>& object)
{
- object = buildObjectForFrameTree(m_page->mainFrame());
+ object = buildObjectForFrameTree(m_page->deprecatedLocalMainFrame());
}
void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, String* content, bool* base64Encoded)
{
- Frame* frame = assertFrame(errorString, frameId);
+ LocalFrame* frame = assertFrame(errorString, frameId);
if (!frame)
return;
resourceContent(errorString, frame, KURL(ParsedURLString, url), content, base64Encoded);
@@ -600,7 +649,7 @@ void InspectorPageAgent::searchInResource(ErrorString*, const String& frameId, c
bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false;
- Frame* frame = frameForId(frameId);
+ LocalFrame* frame = frameForId(frameId);
KURL kurl(ParsedURLString, url);
FrameLoader* frameLoader = frame ? &frame->loader() : 0;
@@ -622,7 +671,7 @@ void InspectorPageAgent::searchInResource(ErrorString*, const String& frameId, c
void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const String& frameId, const String& html)
{
- Frame* frame = assertFrame(errorString, frameId);
+ LocalFrame* frame = assertFrame(errorString, frameId);
if (!frame)
return;
@@ -646,13 +695,8 @@ void InspectorPageAgent::setDeviceMetricsOverride(ErrorString* errorString, int
return;
}
- if (!width ^ !height) {
- *errorString = "Both width and height must be either zero or non-zero at once";
- return;
- }
-
- if (deviceScaleFactor <= 0) {
- *errorString = "deviceScaleFactor must be positive";
+ if (deviceScaleFactor < 0) {
+ *errorString = "deviceScaleFactor must be non-negative";
return;
}
@@ -662,16 +706,16 @@ void InspectorPageAgent::setDeviceMetricsOverride(ErrorString* errorString, int
}
Settings& settings = m_page->settings();
- if (width && height && !settings.acceleratedCompositingEnabled()) {
+ if (!settings.acceleratedCompositingEnabled()) {
if (errorString)
*errorString = "Compositing mode is not supported";
return;
}
- if (!deviceMetricsChanged(width, height, deviceScaleFactor, emulateViewport, fitWindow, fontScaleFactor, textAutosizing))
+ if (!deviceMetricsChanged(true, width, height, deviceScaleFactor, emulateViewport, fitWindow, fontScaleFactor, textAutosizing))
return;
-
+ m_state->setBoolean(PageAgentState::deviceMetricsOverrideEnabled, true);
m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, width);
m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, height);
m_state->setDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, deviceScaleFactor);
@@ -679,22 +723,37 @@ void InspectorPageAgent::setDeviceMetricsOverride(ErrorString* errorString, int
m_state->setBoolean(PageAgentState::pageAgentFitWindow, fitWindow);
m_state->setDouble(PageAgentState::fontScaleFactor, fontScaleFactor);
m_state->setBoolean(PageAgentState::pageAgentTextAutosizingOverride, textAutosizing);
+ updateViewMetricsFromState();
+}
- updateViewMetrics(width, height, deviceScaleFactor, emulateViewport, fitWindow);
+void InspectorPageAgent::clearDeviceMetricsOverride(ErrorString*)
+{
+ if (m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled)) {
+ m_state->setBoolean(PageAgentState::deviceMetricsOverrideEnabled, false);
+ updateViewMetricsFromState();
+ }
}
-bool InspectorPageAgent::deviceMetricsChanged(int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizing)
+bool InspectorPageAgent::deviceMetricsChanged(bool enabled, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizing)
{
+ bool currentEnabled = m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled);
// These two always fit an int.
int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
- double currentDeviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 1);
+ double currentDeviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride, 0);
bool currentEmulateViewport = m_state->getBoolean(PageAgentState::pageAgentEmulateViewport);
bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
double currentFontScaleFactor = m_state->getDouble(PageAgentState::fontScaleFactor, 1);
bool currentTextAutosizing = m_state->getBoolean(PageAgentState::pageAgentTextAutosizingOverride);
- return width != currentWidth || height != currentHeight || deviceScaleFactor != currentDeviceScaleFactor || emulateViewport != currentEmulateViewport || fitWindow != currentFitWindow || fontScaleFactor != currentFontScaleFactor || textAutosizing != currentTextAutosizing;
+ return enabled != currentEnabled
+ || width != currentWidth
+ || height != currentHeight
+ || deviceScaleFactor != currentDeviceScaleFactor
+ || emulateViewport != currentEmulateViewport
+ || fitWindow != currentFitWindow
+ || fontScaleFactor != currentFontScaleFactor
+ || textAutosizing != currentTextAutosizing;
}
void InspectorPageAgent::setShowPaintRects(ErrorString*, bool show)
@@ -709,7 +768,7 @@ void InspectorPageAgent::setShowPaintRects(ErrorString*, bool show)
void InspectorPageAgent::setShowDebugBorders(ErrorString* errorString, bool show)
{
m_state->setBoolean(PageAgentState::pageAgentShowDebugBorders, show);
- if (show && !forceCompositingMode(errorString))
+ if (show && !compositingEnabled(errorString))
return;
m_client->setShowDebugBorders(show);
}
@@ -718,7 +777,7 @@ void InspectorPageAgent::setShowFPSCounter(ErrorString* errorString, bool show)
{
// FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
m_state->setBoolean(PageAgentState::pageAgentShowFPSCounter, show);
- if (show && !forceCompositingMode(errorString))
+ if (show && !compositingEnabled(errorString))
return;
m_client->setShowFPSCounter(show && !m_deviceMetricsOverridden);
}
@@ -726,7 +785,7 @@ void InspectorPageAgent::setShowFPSCounter(ErrorString* errorString, bool show)
void InspectorPageAgent::setContinuousPaintingEnabled(ErrorString* errorString, bool enabled)
{
m_state->setBoolean(PageAgentState::pageAgentContinuousPaintingEnabled, enabled);
- if (enabled && !forceCompositingMode(errorString))
+ if (enabled && !compositingEnabled(errorString))
return;
m_client->setContinuousPaintingEnabled(enabled && !m_deviceMetricsOverridden);
}
@@ -734,7 +793,7 @@ void InspectorPageAgent::setContinuousPaintingEnabled(ErrorString* errorString,
void InspectorPageAgent::setShowScrollBottleneckRects(ErrorString* errorString, bool show)
{
m_state->setBoolean(PageAgentState::pageAgentShowScrollBottleneckRects, show);
- if (show && !forceCompositingMode(errorString))
+ if (show && !compositingEnabled(errorString))
return;
m_client->setShowScrollBottleneckRects(show);
}
@@ -743,22 +802,20 @@ void InspectorPageAgent::getScriptExecutionStatus(ErrorString*, PageCommandHandl
{
bool disabledByScriptController = false;
bool disabledInSettings = false;
- Frame* frame = mainFrame();
+ LocalFrame* frame = mainFrame();
if (frame) {
disabledByScriptController = !frame->script().canExecuteScripts(NotAboutToExecuteScript);
if (frame->settings())
- disabledInSettings = !frame->settings()->isScriptEnabled();
- }
-
- if (!disabledByScriptController) {
- *status = PageCommandHandler::Result::Allowed;
- return;
+ disabledInSettings = !frame->settings()->scriptEnabled();
}
+ // Order is important.
if (disabledInSettings)
*status = PageCommandHandler::Result::Disabled;
- else
+ else if (disabledByScriptController)
*status = PageCommandHandler::Result::Forbidden;
+ else
+ *status = PageCommandHandler::Result::Allowed;
}
void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value)
@@ -775,11 +832,8 @@ void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value)
}
}
-void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
+void InspectorPageAgent::didClearDocumentOfWindowObject(LocalFrame* frame)
{
- if (world != mainThreadNormalWorld())
- return;
-
if (frame == m_page->mainFrame())
m_injectedScriptManager->discardInjectedScripts();
@@ -799,23 +853,23 @@ void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWor
frame->script().executeScriptInMainWorld(m_scriptToEvaluateOnLoadOnce);
}
-void InspectorPageAgent::domContentLoadedEventFired(Frame* frame)
+void InspectorPageAgent::domContentLoadedEventFired(LocalFrame* frame)
{
if (!frame->isMainFrame())
return;
m_frontend->domContentEventFired(currentTime());
}
-void InspectorPageAgent::loadEventFired(Frame* frame)
+void InspectorPageAgent::loadEventFired(LocalFrame* frame)
{
if (!frame->isMainFrame())
return;
m_frontend->loadEventFired(currentTime());
}
-void InspectorPageAgent::didCommitLoad(Frame*, DocumentLoader* loader)
+void InspectorPageAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader)
{
- // FIXME: If "frame" is always guarenteed to be in the same Page as loader->frame()
+ // FIXME: If "frame" is always guaranteed to be in the same Page as loader->frame()
// then all we need to check here is loader->frame()->isMainFrame()
// and we don't need "frame" at all.
if (loader->frame() == m_page->mainFrame()) {
@@ -823,18 +877,23 @@ void InspectorPageAgent::didCommitLoad(Frame*, DocumentLoader* loader)
m_scriptPreprocessorSource = m_pendingScriptPreprocessor;
m_pendingScriptToEvaluateOnLoadOnce = String();
m_pendingScriptPreprocessor = String();
+ if (m_inspectorResourceContentLoader)
+ m_inspectorResourceContentLoader->stop();
}
m_frontend->frameNavigated(buildObjectForFrame(loader->frame()));
}
-void InspectorPageAgent::frameAttachedToParent(Frame* frame)
+void InspectorPageAgent::frameAttachedToParent(LocalFrame* frame)
{
- m_frontend->frameAttached(frameId(frame), frameId(frame->tree().parent()));
+ Frame* parentFrame = frame->tree().parent();
+ if (!parentFrame->isLocalFrame())
+ parentFrame = 0;
+ m_frontend->frameAttached(frameId(frame), frameId(toLocalFrame(parentFrame)));
}
-void InspectorPageAgent::frameDetachedFromParent(Frame* frame)
+void InspectorPageAgent::frameDetachedFromParent(LocalFrame* frame)
{
- HashMap<Frame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
+ HashMap<LocalFrame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
if (iterator != m_frameToIdentifier.end()) {
m_frontend->frameDetached(iterator->value);
m_identifierToFrame.remove(iterator->value);
@@ -842,17 +901,17 @@ void InspectorPageAgent::frameDetachedFromParent(Frame* frame)
}
}
-Frame* InspectorPageAgent::mainFrame()
+LocalFrame* InspectorPageAgent::mainFrame()
{
- return m_page->mainFrame();
+ return m_page->deprecatedLocalMainFrame();
}
-Frame* InspectorPageAgent::frameForId(const String& frameId)
+LocalFrame* InspectorPageAgent::frameForId(const String& frameId)
{
return frameId.isEmpty() ? 0 : m_identifierToFrame.get(frameId);
}
-String InspectorPageAgent::frameId(Frame* frame)
+String InspectorPageAgent::frameId(LocalFrame* frame)
{
if (!frame)
return "";
@@ -865,7 +924,7 @@ String InspectorPageAgent::frameId(Frame* frame)
return identifier;
}
-bool InspectorPageAgent::hasIdForFrame(Frame* frame) const
+bool InspectorPageAgent::hasIdForFrame(LocalFrame* frame) const
{
return frame && m_frameToIdentifier.contains(frame);
}
@@ -882,19 +941,22 @@ String InspectorPageAgent::loaderId(DocumentLoader* loader)
return identifier;
}
-Frame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
+LocalFrame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
{
for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- RefPtr<SecurityOrigin> documentOrigin = frame->document()->securityOrigin();
+ // FIXME: RemoteFrame security origins are not yet available.
+ if (!frame->isLocalFrame())
+ continue;
+ RefPtr<SecurityOrigin> documentOrigin = toLocalFrame(frame)->document()->securityOrigin();
if (documentOrigin->toRawString() == originRawString)
- return frame;
+ return toLocalFrame(frame);
}
return 0;
}
-Frame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
+LocalFrame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
{
- Frame* frame = frameForId(frameId);
+ LocalFrame* frame = frameForId(frameId);
if (!frame)
*errorString = "No frame for given id found";
return frame;
@@ -906,7 +968,7 @@ const AtomicString& InspectorPageAgent::resourceSourceMapURL(const String& url)
DEFINE_STATIC_LOCAL(const AtomicString, deprecatedSourceMapHttpHeader, ("X-SourceMap", AtomicString::ConstructFromLiteral));
if (url.isEmpty())
return nullAtom;
- Frame* frame = mainFrame();
+ LocalFrame* frame = mainFrame();
if (!frame)
return nullAtom;
Resource* resource = cachedResource(frame, KURL(ParsedURLString, url));
@@ -926,7 +988,7 @@ bool InspectorPageAgent::deviceMetricsOverrideEnabled()
}
// static
-DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, Frame* frame)
+DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, LocalFrame* frame)
{
DocumentLoader* documentLoader = frame->loader().documentLoader();
if (!documentLoader)
@@ -941,22 +1003,22 @@ void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader)
m_loaderToIdentifier.remove(iterator);
}
-void InspectorPageAgent::frameStartedLoading(Frame* frame)
+void InspectorPageAgent::frameStartedLoading(LocalFrame* frame)
{
m_frontend->frameStartedLoading(frameId(frame));
}
-void InspectorPageAgent::frameStoppedLoading(Frame* frame)
+void InspectorPageAgent::frameStoppedLoading(LocalFrame* frame)
{
m_frontend->frameStoppedLoading(frameId(frame));
}
-void InspectorPageAgent::frameScheduledNavigation(Frame* frame, double delay)
+void InspectorPageAgent::frameScheduledNavigation(LocalFrame* frame, double delay)
{
m_frontend->frameScheduledNavigation(frameId(frame), delay);
}
-void InspectorPageAgent::frameClearedScheduledNavigation(Frame* frame)
+void InspectorPageAgent::frameClearedScheduledNavigation(LocalFrame* frame)
{
m_frontend->frameClearedScheduledNavigation(frameId(frame));
}
@@ -978,9 +1040,9 @@ void InspectorPageAgent::didPaint(RenderObject*, const GraphicsLayer*, GraphicsC
static int colorSelector = 0;
const Color colors[] = {
- Color(0xFF, 0, 0, 0x3F),
- Color(0xFF, 0, 0xFF, 0x3F),
- Color(0, 0, 0xFF, 0x3F),
+ Color(0, 0x5F, 0, 0x3F),
+ Color(0, 0xAF, 0, 0x3F),
+ Color(0, 0xFF, 0, 0x3F),
};
LayoutRect inflatedRect(rect);
@@ -1003,12 +1065,14 @@ void InspectorPageAgent::didScroll()
void InspectorPageAgent::didResizeMainFrame()
{
+#if !OS(ANDROID)
if (m_enabled && m_state->getBoolean(PageAgentState::showSizeOnResize))
m_overlay->showAndHideViewSize(m_state->getBoolean(PageAgentState::showGridOnResize));
+#endif
m_frontend->frameResized();
}
-void InspectorPageAgent::didRecalculateStyle()
+void InspectorPageAgent::didRecalculateStyle(int)
{
if (m_enabled)
m_overlay->update();
@@ -1022,7 +1086,7 @@ void InspectorPageAgent::scriptsEnabled(bool isEnabled)
m_frontend->scriptsEnabled(isEnabled);
}
-PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame)
+PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(LocalFrame* frame)
{
RefPtr<TypeBuilder::Page::Frame> frameObject = TypeBuilder::Page::Frame::create()
.setId(frameId(frame))
@@ -1030,19 +1094,21 @@ PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(Fra
.setUrl(urlWithoutFragment(frame->document()->url()).string())
.setMimeType(frame->loader().documentLoader()->responseMIMEType())
.setSecurityOrigin(frame->document()->securityOrigin()->toRawString());
- if (frame->tree().parent())
- frameObject->setParentId(frameId(frame->tree().parent()));
- if (frame->ownerElement()) {
- AtomicString name = frame->ownerElement()->getNameAttribute();
+ // FIXME: This doesn't work for OOPI.
+ Frame* parentFrame = frame->tree().parent();
+ if (parentFrame && parentFrame->isLocalFrame())
+ frameObject->setParentId(frameId(toLocalFrame(parentFrame)));
+ if (frame->deprecatedLocalOwner()) {
+ AtomicString name = frame->deprecatedLocalOwner()->getNameAttribute();
if (name.isEmpty())
- name = frame->ownerElement()->getAttribute(HTMLNames::idAttr);
+ name = frame->deprecatedLocalOwner()->getAttribute(HTMLNames::idAttr);
frameObject->setName(name);
}
return frameObject;
}
-PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(Frame* frame)
+PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(LocalFrame* frame)
{
RefPtr<TypeBuilder::Page::Frame> frameObject = buildObjectForFrame(frame);
RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources> > subresources = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources>::create();
@@ -1065,33 +1131,69 @@ PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObject
subresources->addItem(resourceObject);
}
+ Vector<Document*> allImports = InspectorPageAgent::importsForFrame(frame);
+ for (Vector<Document*>::const_iterator it = allImports.begin(); it != allImports.end(); ++it) {
+ Document* import = *it;
+ RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
+ .setUrl(urlWithoutFragment(import->url()).string())
+ .setType(resourceTypeJson(InspectorPageAgent::DocumentResource))
+ .setMimeType(import->suggestedMIMEType());
+ subresources->addItem(resourceObject);
+ }
+
RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree> > childrenArray;
for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (!child->isLocalFrame())
+ continue;
if (!childrenArray) {
childrenArray = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree>::create();
result->setChildFrames(childrenArray);
}
- childrenArray->addItem(buildObjectForFrameTree(child));
+ childrenArray->addItem(buildObjectForFrameTree(toLocalFrame(child)));
}
return result;
}
-void InspectorPageAgent::updateViewMetrics(int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow)
+void InspectorPageAgent::updateViewMetricsFromState()
+{
+ bool enabled = m_state->getBoolean(PageAgentState::deviceMetricsOverrideEnabled);
+ int width = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
+ int height = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
+ bool emulateViewport = m_state->getBoolean(PageAgentState::pageAgentEmulateViewport);
+ double deviceScaleFactor = m_state->getDouble(PageAgentState::pageAgentDeviceScaleFactorOverride);
+ bool fitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
+ double fontScaleFactor = m_state->getDouble(PageAgentState::fontScaleFactor);
+ bool textAutosizingEnabled = m_state->getBoolean(PageAgentState::pageAgentTextAutosizingOverride);
+ updateViewMetrics(enabled, width, height, deviceScaleFactor, emulateViewport, fitWindow, fontScaleFactor, textAutosizingEnabled);
+}
+
+void InspectorPageAgent::updateViewMetrics(bool enabled, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizingEnabled)
{
- if (width && height && !m_page->settings().acceleratedCompositingEnabled())
+ if (enabled && !m_page->settings().acceleratedCompositingEnabled())
return;
- m_deviceMetricsOverridden = width && height;
+ m_deviceMetricsOverridden = enabled;
m_emulateViewportEnabled = emulateViewport;
- m_client->overrideDeviceMetrics(width, height, static_cast<float>(deviceScaleFactor), emulateViewport, fitWindow);
+ if (enabled)
+ m_client->setDeviceMetricsOverride(width, height, static_cast<float>(deviceScaleFactor), emulateViewport, fitWindow);
+ else
+ m_client->clearDeviceMetricsOverride();
Document* document = mainFrame()->document();
if (document) {
- document->styleResolverChanged(RecalcStyleImmediately);
+ document->styleResolverChanged();
document->mediaQueryAffectingValueChanged();
}
InspectorInstrumentation::mediaQueryResultChanged(document);
+ if (m_deviceMetricsOverridden) {
+ m_page->settings().setTextAutosizingEnabled(textAutosizingEnabled);
+ m_page->settings().setDeviceScaleAdjustment(fontScaleFactor);
+ } else {
+ m_page->settings().setTextAutosizingEnabled(m_embedderTextAutosizingEnabled);
+ m_page->settings().setDeviceScaleAdjustment(m_embedderFontScaleFactor);
+ }
+
// FIXME: allow metrics override, fps counter and continuous painting at the same time: crbug.com/299837.
m_client->setShowFPSCounter(m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter) && !m_deviceMetricsOverridden);
m_client->setContinuousPaintingEnabled(m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled) && !m_deviceMetricsOverridden);
@@ -1099,88 +1201,38 @@ void InspectorPageAgent::updateViewMetrics(int width, int height, double deviceS
void InspectorPageAgent::updateTouchEventEmulationInPage(bool enabled)
{
- m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, enabled);
- if (mainFrame() && mainFrame()->settings())
- mainFrame()->settings()->setTouchEventEmulationEnabled(enabled);
-}
-
-void InspectorPageAgent::setGeolocationOverride(ErrorString* error, const double* latitude, const double* longitude, const double* accuracy)
-{
- GeolocationController* controller = GeolocationController::from(m_page);
- GeolocationPosition* position = 0;
- if (!controller) {
- *error = "Internal error: unable to override geolocation";
- return;
+ if (!m_touchEmulationEnabled) {
+ m_originalTouchEnabled = RuntimeEnabledFeatures::touchEnabled();
+ m_originalDeviceSupportsMouse = m_page->settings().deviceSupportsMouse();
+ m_originalDeviceSupportsTouch = m_page->settings().deviceSupportsTouch();
}
- position = controller->lastPosition();
- if (!m_geolocationOverridden && position)
- m_platformGeolocationPosition = position;
-
- m_geolocationOverridden = true;
- if (latitude && longitude && accuracy)
- m_geolocationPosition = GeolocationPosition::create(currentTimeMS(), *latitude, *longitude, *accuracy);
- else
- m_geolocationPosition.clear();
-
- controller->positionChanged(0); // Kick location update.
+ RuntimeEnabledFeatures::setTouchEnabled(enabled ? true : m_originalTouchEnabled);
+ m_page->settings().setDeviceSupportsMouse(enabled ? false : m_originalDeviceSupportsMouse);
+ m_page->settings().setDeviceSupportsTouch(enabled ? true : m_originalDeviceSupportsTouch);
+ m_touchEmulationEnabled = enabled;
+ m_client->setTouchEventEmulationEnabled(enabled);
+ m_page->deprecatedLocalMainFrame()->view()->layout();
}
-void InspectorPageAgent::clearGeolocationOverride(ErrorString*)
+void InspectorPageAgent::hasTouchInputs(ErrorString*, bool* result)
{
- if (!m_geolocationOverridden)
- return;
- m_geolocationOverridden = false;
- m_geolocationPosition.clear();
-
- GeolocationController* controller = GeolocationController::from(m_page);
- if (controller && m_platformGeolocationPosition.get())
- controller->positionChanged(m_platformGeolocationPosition.get());
+ *result = m_touchEmulationEnabled ? m_originalDeviceSupportsTouch : m_page->settings().deviceSupportsTouch();
}
-GeolocationPosition* InspectorPageAgent::overrideGeolocationPosition(GeolocationPosition* position)
+void InspectorPageAgent::setTouchEmulationEnabled(ErrorString* error, bool enabled)
{
- if (m_geolocationOverridden) {
- if (position)
- m_platformGeolocationPosition = position;
- return m_geolocationPosition.get();
- }
- return position;
-}
+ if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled) == enabled)
+ return;
-void InspectorPageAgent::setDeviceOrientationOverride(ErrorString* error, double alpha, double beta, double gamma)
-{
- DeviceOrientationController* controller = DeviceOrientationController::from(mainFrame()->document());
- if (!controller) {
- *error = "Internal error: unable to override device orientation";
+ bool hasTouch = false;
+ hasTouchInputs(error, &hasTouch);
+ if (enabled && hasTouch) {
+ if (error)
+ *error = "Device already supports touch input";
return;
}
- controller->didChangeDeviceOrientation(DeviceOrientationData::create(true, alpha, true, beta, true, gamma).get());
-}
-
-void InspectorPageAgent::clearDeviceOrientationOverride(ErrorString* error)
-{
- setDeviceOrientationOverride(error, 0, 0, 0);
-}
-
-bool InspectorPageAgent::overrideTextAutosizing(bool textAutosizing)
-{
- if (!m_deviceMetricsOverridden)
- return textAutosizing;
- return m_state->getBoolean(PageAgentState::pageAgentTextAutosizingOverride);
-}
-
-float InspectorPageAgent::overrideFontScaleFactor(float fontScaleFactor)
-{
- if (!m_deviceMetricsOverridden)
- return fontScaleFactor;
- return static_cast<float>(m_state->getDouble(PageAgentState::fontScaleFactor));
-}
-
-void InspectorPageAgent::setTouchEmulationEnabled(ErrorString*, bool enabled)
-{
- if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled) == enabled)
- return;
+ m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, enabled);
updateTouchEventEmulationInPage(enabled);
}
@@ -1193,10 +1245,10 @@ void InspectorPageAgent::setEmulatedMedia(ErrorString*, const String& media)
m_state->setString(PageAgentState::pageAgentEmulatedMedia, media);
Document* document = 0;
if (m_page->mainFrame())
- document = m_page->mainFrame()->document();
+ document = m_page->deprecatedLocalMainFrame()->document();
if (document) {
document->mediaQueryAffectingValueChanged();
- document->styleResolverChanged(RecalcStyleImmediately);
+ document->styleResolverChanged();
document->updateLayout();
}
}
@@ -1206,9 +1258,9 @@ bool InspectorPageAgent::applyViewportStyleOverride(StyleResolver* resolver)
if (!m_deviceMetricsOverridden || !m_emulateViewportEnabled)
return false;
- RefPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode));
+ RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
styleSheet->parseString(String(viewportAndroidUserAgentStyleSheet, sizeof(viewportAndroidUserAgentStyleSheet)));
- OwnPtr<RuleSet> ruleSet = RuleSet::create();
+ OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
ruleSet->addRulesFromSheet(styleSheet.get(), MediaQueryEvaluator("screen"));
resolver->viewportStyleResolver()->collectViewportRules(ruleSet.get(), ViewportStyleResolver::UserAgentOrigin);
return true;
@@ -1221,53 +1273,16 @@ void InspectorPageAgent::applyEmulatedMedia(String* media)
*media = emulatedMedia;
}
-bool InspectorPageAgent::forceCompositingMode(ErrorString* errorString)
+bool InspectorPageAgent::compositingEnabled(ErrorString* errorString)
{
- Settings& settings = m_page->settings();
- if (!settings.acceleratedCompositingEnabled()) {
+ if (!m_page->settings().acceleratedCompositingEnabled()) {
if (errorString)
*errorString = "Compositing mode is not supported";
return false;
}
- if (settings.forceCompositingMode())
- return true;
- settings.setForceCompositingMode(true);
- Frame* mainFrame = m_page->mainFrame();
- if (mainFrame)
- mainFrame->view()->updateCompositingLayersAfterStyleChange();
return true;
}
-void InspectorPageAgent::captureScreenshot(ErrorString*, const String*, const int*, const int*, const int*, String*, RefPtr<TypeBuilder::Page::ScreencastFrameMetadata>&)
-{
- // Handled on the browser level.
-}
-
-void InspectorPageAgent::canScreencast(ErrorString*, bool*)
-{
- // Handled on the browser level.
-}
-
-void InspectorPageAgent::startScreencast(ErrorString*, const String*, const int*, const int*, const int*)
-{
- // Handled on the browser level.
-}
-
-void InspectorPageAgent::stopScreencast(ErrorString*)
-{
- // Handled on the browser level.
-}
-
-void InspectorPageAgent::handleJavaScriptDialog(ErrorString* errorString, bool accept, const String* promptText)
-{
- // Handled on the browser level.
-}
-
-void InspectorPageAgent::queryUsageAndQuota(WebCore::ErrorString*, const WTF::String&, WTF::RefPtr<WebCore::TypeBuilder::Page::Quota>&, WTF::RefPtr<WebCore::TypeBuilder::Page::Usage>&)
-{
- // Handled on the browser level.
-}
-
void InspectorPageAgent::setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid)
{
m_state->setBoolean(PageAgentState::showSizeOnResize, show);
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
index 8a0dc8d52b2..4211d39e21e 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorPageAgent.h
@@ -32,9 +32,9 @@
#define InspectorPageAgent_h
-#include "InspectorFrontend.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorBaseAgent.h"
-#include "modules/geolocation/GeolocationPosition.h"
+#include "core/inspector/InspectorResourceContentLoader.h"
#include "wtf/HashMap.h"
#include "wtf/text/WTFString.h"
@@ -44,12 +44,13 @@ class Resource;
class DOMWrapperWorld;
class Document;
class DocumentLoader;
-class Frame;
+class LocalFrame;
class GraphicsContext;
class GraphicsLayer;
class InjectedScriptManager;
class InspectorClient;
class InspectorOverlay;
+class InspectorResourceContentLoader;
class InstrumentingAgents;
class IntSize;
class KURL;
@@ -61,88 +62,77 @@ class StyleResolver;
typedef String ErrorString;
-class InspectorPageAgent : public InspectorBaseAgent<InspectorPageAgent>, public InspectorBackendDispatcher::PageCommandHandler {
+class InspectorPageAgent FINAL : public InspectorBaseAgent<InspectorPageAgent>, public InspectorBackendDispatcher::PageCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorPageAgent);
public:
enum ResourceType {
DocumentResource,
StylesheetResource,
ImageResource,
- Font,
+ FontResource,
+ MediaResource,
ScriptResource,
+ TextTrackResource,
XHRResource,
WebSocketResource,
OtherResource
};
- static PassOwnPtr<InspectorPageAgent> create(InstrumentingAgents*, Page*, InspectorCompositeState*, InjectedScriptManager*, InspectorClient*, InspectorOverlay*);
+ static PassOwnPtr<InspectorPageAgent> create(Page*, InjectedScriptManager*, InspectorClient*, InspectorOverlay*);
+ // Settings overrides.
+ void setTextAutosizingEnabled(bool);
+ void setDeviceScaleAdjustment(float);
+
+ static Vector<Document*> importsForFrame(LocalFrame*);
static bool cachedResourceContent(Resource*, String* result, bool* base64Encoded);
static bool sharedBufferContent(PassRefPtr<SharedBuffer>, const String& textEncodingName, bool withBase64Encode, String* result);
- static PassRefPtr<SharedBuffer> resourceData(Frame*, const KURL&, String* textEncodingName);
- static Resource* cachedResource(Frame*, const KURL&);
+ static PassRefPtr<SharedBuffer> resourceData(LocalFrame*, const KURL&, String* textEncodingName);
+ static Resource* cachedResource(LocalFrame*, const KURL&);
static TypeBuilder::Page::ResourceType::Enum resourceTypeJson(ResourceType);
static ResourceType cachedResourceType(const Resource&);
static TypeBuilder::Page::ResourceType::Enum cachedResourceTypeJson(const Resource&);
// Page API for InspectorFrontend
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* result);
- virtual void removeScriptToEvaluateOnLoad(ErrorString*, const String& identifier);
- virtual void reload(ErrorString*, const bool* optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor);
- virtual void navigate(ErrorString*, const String& url);
- virtual void getNavigationHistory(ErrorString*, int*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::NavigationEntry> >&);
- virtual void navigateToHistoryEntry(ErrorString*, int);
- virtual void getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies);
- virtual void deleteCookie(ErrorString*, const String& cookieName, const String& url);
- virtual void getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>&);
- virtual void getResourceContent(ErrorString*, const String& frameId, const String& url, String* content, bool* base64Encoded);
- virtual void searchInResource(ErrorString*, const String& frameId, const String& url, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&);
- virtual void setDocumentContent(ErrorString*, const String& frameId, const String& html);
- virtual void setDeviceMetricsOverride(ErrorString*, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, const bool* optionalTextAutosizing, const double* optionalFontScaleFactor);
- virtual void setShowPaintRects(ErrorString*, bool show);
- virtual void setShowDebugBorders(ErrorString*, bool show);
- virtual void setShowFPSCounter(ErrorString*, bool show);
- virtual void setContinuousPaintingEnabled(ErrorString*, bool enabled);
- virtual void setShowScrollBottleneckRects(ErrorString*, bool show);
- virtual void getScriptExecutionStatus(ErrorString*, PageCommandHandler::Result::Enum*);
- virtual void setScriptExecutionDisabled(ErrorString*, bool);
- virtual void setGeolocationOverride(ErrorString*, const double*, const double*, const double*);
- virtual void clearGeolocationOverride(ErrorString*);
- virtual void setDeviceOrientationOverride(ErrorString*, double, double, double);
- virtual void clearDeviceOrientationOverride(ErrorString*);
- virtual void setTouchEmulationEnabled(ErrorString*, bool);
- virtual void setEmulatedMedia(ErrorString*, const String&);
- virtual void captureScreenshot(ErrorString*, const String* format, const int* quality, const int* maxWidth, const int* maxHeight, String* data, RefPtr<TypeBuilder::Page::ScreencastFrameMetadata>& out_metadata);
- virtual void canScreencast(ErrorString*, bool*);
- virtual void startScreencast(ErrorString*, const String* format, const int* quality, const int* maxWidth, const int* maxHeight);
- virtual void stopScreencast(ErrorString*);
- virtual void handleJavaScriptDialog(ErrorString*, bool accept, const String* promptText);
- virtual void queryUsageAndQuota(WebCore::ErrorString*, const WTF::String&, WTF::RefPtr<WebCore::TypeBuilder::Page::Quota>&, WTF::RefPtr<WebCore::TypeBuilder::Page::Usage>&);
- virtual void setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid);
-
- // Geolocation override helper.
- GeolocationPosition* overrideGeolocationPosition(GeolocationPosition*);
-
- // Text autosizing override helpers.
- bool overrideTextAutosizing(bool);
- // Note: This is used by Settings::deviceScaleAdjustment to calculate the overridden device scale adjustment.
- float overrideFontScaleFactor(float);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* result) OVERRIDE;
+ virtual void removeScriptToEvaluateOnLoad(ErrorString*, const String& identifier) OVERRIDE;
+ virtual void reload(ErrorString*, const bool* optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor) OVERRIDE;
+ virtual void navigate(ErrorString*, const String& url) OVERRIDE;
+ virtual void getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies) OVERRIDE;
+ virtual void deleteCookie(ErrorString*, const String& cookieName, const String& url) OVERRIDE;
+ virtual void getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>&) OVERRIDE;
+ virtual void getResourceContent(ErrorString*, const String& frameId, const String& url, String* content, bool* base64Encoded) OVERRIDE;
+ virtual void hasTouchInputs(ErrorString*, bool* result) OVERRIDE;
+ virtual void searchInResource(ErrorString*, const String& frameId, const String& url, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&) OVERRIDE;
+ virtual void setDocumentContent(ErrorString*, const String& frameId, const String& html) OVERRIDE;
+ virtual void setDeviceMetricsOverride(ErrorString*, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, const bool* optionalTextAutosizing, const double* optionalFontScaleFactor) OVERRIDE;
+ virtual void clearDeviceMetricsOverride(ErrorString*) OVERRIDE;
+ virtual void setShowPaintRects(ErrorString*, bool show) OVERRIDE;
+ virtual void setShowDebugBorders(ErrorString*, bool show) OVERRIDE;
+ virtual void setShowFPSCounter(ErrorString*, bool show) OVERRIDE;
+ virtual void setContinuousPaintingEnabled(ErrorString*, bool enabled) OVERRIDE;
+ virtual void setShowScrollBottleneckRects(ErrorString*, bool show) OVERRIDE;
+ virtual void getScriptExecutionStatus(ErrorString*, PageCommandHandler::Result::Enum*) OVERRIDE;
+ virtual void setScriptExecutionDisabled(ErrorString*, bool) OVERRIDE;
+ virtual void setTouchEmulationEnabled(ErrorString*, bool) OVERRIDE;
+ virtual void setEmulatedMedia(ErrorString*, const String&) OVERRIDE;
+ virtual void setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid) OVERRIDE;
// InspectorInstrumentation API
- void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*);
- void domContentLoadedEventFired(Frame*);
- void loadEventFired(Frame*);
- void didCommitLoad(Frame*, DocumentLoader*);
- void frameAttachedToParent(Frame*);
- void frameDetachedFromParent(Frame*);
+ void didClearDocumentOfWindowObject(LocalFrame*);
+ void domContentLoadedEventFired(LocalFrame*);
+ void loadEventFired(LocalFrame*);
+ void didCommitLoad(LocalFrame*, DocumentLoader*);
+ void frameAttachedToParent(LocalFrame*);
+ void frameDetachedFromParent(LocalFrame*);
void loaderDetachedFromFrame(DocumentLoader*);
- void frameStartedLoading(Frame*);
- void frameStoppedLoading(Frame*);
- void frameScheduledNavigation(Frame*, double delay);
- void frameClearedScheduledNavigation(Frame*);
+ void frameStartedLoading(LocalFrame*);
+ void frameStoppedLoading(LocalFrame*);
+ void frameScheduledNavigation(LocalFrame*, double delay);
+ void frameClearedScheduledNavigation(LocalFrame*);
void willRunJavaScriptDialog(const String& message);
void didRunJavaScriptDialog();
bool applyViewportStyleOverride(StyleResolver*);
@@ -151,44 +141,44 @@ public:
void didLayout(RenderObject*);
void didScroll();
void didResizeMainFrame();
- void didRecalculateStyle();
+ void didRecalculateStyle(int);
void scriptsEnabled(bool isEnabled);
// Inspector Controller API
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
-
- void webViewResized(const IntSize&);
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
// Cross-agents API
Page* page() { return m_page; }
- Frame* mainFrame();
+ LocalFrame* mainFrame();
String createIdentifier();
- Frame* frameForId(const String& frameId);
- String frameId(Frame*);
- bool hasIdForFrame(Frame*) const;
+ LocalFrame* frameForId(const String& frameId);
+ String frameId(LocalFrame*);
+ bool hasIdForFrame(LocalFrame*) const;
String loaderId(DocumentLoader*);
- Frame* findFrameWithSecurityOrigin(const String& originRawString);
- Frame* assertFrame(ErrorString*, const String& frameId);
+ LocalFrame* findFrameWithSecurityOrigin(const String& originRawString);
+ LocalFrame* assertFrame(ErrorString*, const String& frameId);
String scriptPreprocessorSource() { return m_scriptPreprocessorSource; }
const AtomicString& resourceSourceMapURL(const String& url);
bool deviceMetricsOverrideEnabled();
- static DocumentLoader* assertDocumentLoader(ErrorString*, Frame*);
+ static DocumentLoader* assertDocumentLoader(ErrorString*, LocalFrame*);
+ InspectorResourceContentLoader* resourceContentLoader() { return m_inspectorResourceContentLoader.get(); }
private:
- static void resourceContent(ErrorString*, Frame*, const KURL&, String* result, bool* base64Encoded);
+ static void resourceContent(ErrorString*, LocalFrame*, const KURL&, String* result, bool* base64Encoded);
- InspectorPageAgent(InstrumentingAgents*, Page*, InspectorCompositeState*, InjectedScriptManager*, InspectorClient*, InspectorOverlay*);
- bool deviceMetricsChanged(int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizing);
- void updateViewMetrics(int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow);
+ InspectorPageAgent(Page*, InjectedScriptManager*, InspectorClient*, InspectorOverlay*);
+ bool deviceMetricsChanged(bool enabled, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizing);
+ void updateViewMetricsFromState();
+ void updateViewMetrics(bool enabled, int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizingEnabled);
void updateTouchEventEmulationInPage(bool);
- bool forceCompositingMode(ErrorString*);
+ bool compositingEnabled(ErrorString*);
static bool dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result);
- PassRefPtr<TypeBuilder::Page::Frame> buildObjectForFrame(Frame*);
- PassRefPtr<TypeBuilder::Page::FrameResourceTree> buildObjectForFrameTree(Frame*);
+ PassRefPtr<TypeBuilder::Page::Frame> buildObjectForFrame(LocalFrame*);
+ PassRefPtr<TypeBuilder::Page::FrameResourceTree> buildObjectForFrameTree(LocalFrame*);
Page* m_page;
InjectedScriptManager* m_injectedScriptManager;
InspectorClient* m_client;
@@ -199,16 +189,23 @@ private:
String m_scriptToEvaluateOnLoadOnce;
String m_pendingScriptPreprocessor;
String m_scriptPreprocessorSource;
- HashMap<Frame*, String> m_frameToIdentifier;
- HashMap<String, Frame*> m_identifierToFrame;
+ HashMap<LocalFrame*, String> m_frameToIdentifier;
+ HashMap<String, LocalFrame*> m_identifierToFrame;
HashMap<DocumentLoader*, String> m_loaderToIdentifier;
bool m_enabled;
- bool m_geolocationOverridden;
bool m_ignoreScriptsEnabledNotification;
bool m_deviceMetricsOverridden;
bool m_emulateViewportEnabled;
- RefPtr<GeolocationPosition> m_geolocationPosition;
- RefPtr<GeolocationPosition> m_platformGeolocationPosition;
+
+ bool m_touchEmulationEnabled;
+ bool m_originalTouchEnabled;
+ bool m_originalDeviceSupportsMouse;
+ bool m_originalDeviceSupportsTouch;
+
+ bool m_embedderTextAutosizingEnabled;
+ double m_embedderFontScaleFactor;
+
+ OwnPtr<InspectorResourceContentLoader> m_inspectorResourceContentLoader;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp
index f7083a9cbf5..11e779b83d0 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.cpp
@@ -49,6 +49,7 @@ namespace ProfilerAgentState {
static const char samplingInterval[] = "samplingInterval";
static const char userInitiatedProfiling[] = "userInitiatedProfiling";
static const char profilerEnabled[] = "profilerEnabled";
+static const char nextProfileId[] = "nextProfileId";
}
static PassRefPtr<TypeBuilder::Profiler::CPUProfile> createCPUProfile(const ScriptProfile& scriptProfile)
@@ -58,12 +59,13 @@ static PassRefPtr<TypeBuilder::Profiler::CPUProfile> createCPUProfile(const Scri
.setStartTime(scriptProfile.startTime())
.setEndTime(scriptProfile.endTime());
profile->setSamples(scriptProfile.buildInspectorObjectForSamples());
+ profile->setTimestamps(scriptProfile.buildInspectorObjectForTimestamps());
return profile.release();
}
-static PassRefPtr<TypeBuilder::Debugger::Location> currentDebugLocation()
+static PassRefPtr<TypeBuilder::Debugger::Location> currentDebugLocation(ScriptState* scriptState)
{
- RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(1));
+ RefPtrWillBeRawPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(scriptState, 1));
const ScriptCallFrame& lastCaller = callStack->at(0);
RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
.setScriptId(lastCaller.scriptId())
@@ -81,17 +83,16 @@ public:
String m_title;
};
-PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
+PassOwnPtr<InspectorProfilerAgent> InspectorProfilerAgent::create(InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
{
- return adoptPtr(new InspectorProfilerAgent(instrumentingAgents, inspectorState, injectedScriptManager, overlay));
+ return adoptPtr(new InspectorProfilerAgent(injectedScriptManager, overlay));
}
-InspectorProfilerAgent::InspectorProfilerAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
- : InspectorBaseAgent<InspectorProfilerAgent>("Profiler", instrumentingAgents, inspectorState)
+InspectorProfilerAgent::InspectorProfilerAgent(InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
+ : InspectorBaseAgent<InspectorProfilerAgent>("Profiler")
, m_injectedScriptManager(injectedScriptManager)
, m_frontend(0)
, m_recordingCPUProfile(false)
- , m_nextProfileId(1)
, m_profileNameIdleTimeMap(ScriptProfiler::currentProfileNameIdleTimeMap())
, m_idleStartTime(0.0)
, m_overlay(overlay)
@@ -102,16 +103,16 @@ InspectorProfilerAgent::~InspectorProfilerAgent()
{
}
-void InspectorProfilerAgent::consoleProfile(const String& title, ScriptState* state)
+void InspectorProfilerAgent::consoleProfile(const String& title, ScriptState* scriptState)
{
ASSERT(m_frontend && enabled());
- String id = String::number(m_nextProfileId++);
+ String id = nextProfileId();
m_startedProfiles.append(ProfileDescriptor(id, title));
ScriptProfiler::start(id);
- m_frontend->consoleProfile(id, currentDebugLocation(), title.isNull() ? 0 : &title);
+ m_frontend->consoleProfileStarted(id, currentDebugLocation(scriptState), title.isNull() ? 0 : &title);
}
-void InspectorProfilerAgent::consoleProfileEnd(const String& title)
+void InspectorProfilerAgent::consoleProfileEnd(const String& title, ScriptState* scriptState)
{
ASSERT(m_frontend && enabled());
String id;
@@ -135,13 +136,11 @@ void InspectorProfilerAgent::consoleProfileEnd(const String& title)
if (id.isEmpty())
return;
}
- RefPtr<ScriptProfile> profile = ScriptProfiler::stop(id);
+ RefPtrWillBeRawPtr<ScriptProfile> profile = ScriptProfiler::stop(id);
if (!profile)
return;
- RefPtr<TypeBuilder::Debugger::Location> location = currentDebugLocation();
- if (!m_keepAliveProfile)
- m_keepAliveProfile = profile;
- m_frontend->addProfileHeader(id, location, createCPUProfile(*profile), resolvedTitle.isNull() ? 0 : &resolvedTitle);
+ RefPtr<TypeBuilder::Debugger::Location> location = currentDebugLocation(scriptState);
+ m_frontend->consoleProfileFinished(id, location, createCPUProfile(*profile), resolvedTitle.isNull() ? 0 : &resolvedTitle);
}
void InspectorProfilerAgent::enable(ErrorString*)
@@ -157,7 +156,11 @@ void InspectorProfilerAgent::doEnable()
void InspectorProfilerAgent::disable(ErrorString*)
{
- m_keepAliveProfile.clear();
+ for (Vector<ProfileDescriptor>::reverse_iterator it = m_startedProfiles.rbegin(); it != m_startedProfiles.rend(); ++it)
+ ScriptProfiler::stop(it->m_id);
+ m_startedProfiles.clear();
+ stop(0, 0);
+
m_instrumentingAgents->setInspectorProfilerAgent(0);
m_state->setBoolean(ProfilerAgentState::profilerEnabled, false);
}
@@ -185,22 +188,21 @@ void InspectorProfilerAgent::setFrontend(InspectorFrontend* frontend)
void InspectorProfilerAgent::clearFrontend()
{
m_frontend = 0;
- stop(0, 0);
- m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
ErrorString error;
disable(&error);
+ m_injectedScriptManager->injectedScriptHost()->clearInspectedObjects();
}
void InspectorProfilerAgent::restore()
{
- if (m_state->getBoolean(ProfilerAgentState::profilerEnabled)) {
+ if (m_state->getBoolean(ProfilerAgentState::profilerEnabled))
doEnable();
- m_frontend->resetProfiles();
- }
if (long interval = m_state->getLong(ProfilerAgentState::samplingInterval, 0))
ScriptProfiler::setSamplingInterval(interval);
- if (m_state->getBoolean(ProfilerAgentState::userInitiatedProfiling))
- start();
+ if (m_state->getBoolean(ProfilerAgentState::userInitiatedProfiling)) {
+ ErrorString error;
+ start(&error);
+ }
}
void InspectorProfilerAgent::start(ErrorString* error)
@@ -208,13 +210,13 @@ void InspectorProfilerAgent::start(ErrorString* error)
if (m_recordingCPUProfile)
return;
if (!enabled()) {
- ErrorString error;
- enable(&error);
+ *error = "Profiler is not enabled";
+ return;
}
m_recordingCPUProfile = true;
if (m_overlay)
m_overlay->startedRecordingProfile();
- m_frontendInitiatedProfileId = String::number(m_nextProfileId++);
+ m_frontendInitiatedProfileId = nextProfileId();
ScriptProfiler::start(m_frontendInitiatedProfileId);
m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, true);
}
@@ -234,18 +236,22 @@ void InspectorProfilerAgent::stop(ErrorString* errorString, RefPtr<TypeBuilder::
m_recordingCPUProfile = false;
if (m_overlay)
m_overlay->finishedRecordingProfile();
- RefPtr<ScriptProfile> scriptProfile = ScriptProfiler::stop(m_frontendInitiatedProfileId);
+ RefPtrWillBeRawPtr<ScriptProfile> scriptProfile = ScriptProfiler::stop(m_frontendInitiatedProfileId);
m_frontendInitiatedProfileId = String();
- if (scriptProfile && profile) {
+ if (scriptProfile && profile)
*profile = createCPUProfile(*scriptProfile);
- if (!m_keepAliveProfile)
- m_keepAliveProfile = scriptProfile;
- } else if (errorString) {
+ else if (errorString)
*errorString = "Profile wasn't found";
- }
m_state->setBoolean(ProfilerAgentState::userInitiatedProfiling, false);
}
+String InspectorProfilerAgent::nextProfileId()
+{
+ long nextId = m_state->getLong(ProfilerAgentState::nextProfileId, 1);
+ m_state->setLong(ProfilerAgentState::nextProfileId, nextId + 1);
+ return String::number(nextId);
+}
+
void InspectorProfilerAgent::idleFinished()
{
if (!m_profileNameIdleTimeMap || !m_profileNameIdleTimeMap->size())
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h
index feefe2fdc9e..2832f63876a 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorProfilerAgent.h
@@ -30,7 +30,7 @@
#ifndef InspectorProfilerAgent_h
#define InspectorProfilerAgent_h
-#include "InspectorFrontend.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
@@ -44,30 +44,31 @@ class InjectedScriptManager;
class InspectorFrontend;
class InspectorOverlay;
class InstrumentingAgents;
+class ScriptState;
class ScriptCallStack;
class ScriptProfile;
-class ScriptState;
+
typedef String ErrorString;
-class InspectorProfilerAgent : public InspectorBaseAgent<InspectorProfilerAgent>, public InspectorBackendDispatcher::ProfilerCommandHandler {
+class InspectorProfilerAgent FINAL : public InspectorBaseAgent<InspectorProfilerAgent>, public InspectorBackendDispatcher::ProfilerCommandHandler {
WTF_MAKE_NONCOPYABLE(InspectorProfilerAgent); WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<InspectorProfilerAgent> create(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*, InspectorOverlay*);
+ static PassOwnPtr<InspectorProfilerAgent> create(InjectedScriptManager*, InspectorOverlay*);
virtual ~InspectorProfilerAgent();
void consoleProfile(const String& title, ScriptState*);
- void consoleProfileEnd(const String& title);
+ void consoleProfileEnd(const String& title, ScriptState*);
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void setSamplingInterval(ErrorString*, int);
- virtual void start(ErrorString* = 0);
- virtual void stop(ErrorString*, RefPtr<TypeBuilder::Profiler::CPUProfile>&);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void setSamplingInterval(ErrorString*, int) OVERRIDE;
+ virtual void start(ErrorString*) OVERRIDE;
+ virtual void stop(ErrorString*, RefPtr<TypeBuilder::Profiler::CPUProfile>&) OVERRIDE;
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
void willProcessTask();
void didProcessTask();
@@ -75,18 +76,15 @@ public:
void didLeaveNestedRunLoop();
private:
- InspectorProfilerAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*, InspectorOverlay*);
+ InspectorProfilerAgent(InjectedScriptManager*, InspectorOverlay*);
bool enabled();
void doEnable();
void stop(ErrorString*, RefPtr<TypeBuilder::Profiler::CPUProfile>*);
+ String nextProfileId();
InjectedScriptManager* m_injectedScriptManager;
InspectorFrontend::Profiler* m_frontend;
- // This is a temporary workaround to make sure v8 doesn't stop profiling when
- // last finished profile is deleted (we keep at least one finished profile alive).
- RefPtr<ScriptProfile> m_keepAliveProfile;
bool m_recordingCPUProfile;
- int m_nextProfileId;
class ProfileDescriptor;
Vector<ProfileDescriptor> m_startedProfiles;
String m_frontendInitiatedProfileId;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
index d0e29e993d0..c5768606cfb 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.cpp
@@ -31,9 +31,9 @@
#include "config.h"
#include "core/inspector/InspectorResourceAgent.h"
-#include "FetchInitiatorTypeNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptCallStackFactory.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/Document.h"
#include "core/dom/ScriptableDocumentParser.h"
#include "core/fetch/FetchInitiatorInfo.h"
@@ -41,9 +41,8 @@
#include "core/fetch/Resource.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ResourceLoader.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/IdentifiersFactory.h"
-#include "core/inspector/InspectorClient.h"
#include "core/inspector/InspectorOverlay.h"
#include "core/inspector/InspectorPageAgent.h"
#include "core/inspector/InspectorState.h"
@@ -57,7 +56,6 @@
#include "core/loader/ThreadableLoaderClient.h"
#include "core/page/Page.h"
#include "core/xml/XMLHttpRequest.h"
-#include "modules/websockets/WebSocketFrame.h"
#include "platform/JSONValues.h"
#include "platform/network/HTTPHeaderMap.h"
#include "platform/network/ResourceError.h"
@@ -82,6 +80,10 @@ static const char userAgentOverride[] = "userAgentOverride";
namespace {
+// Keep in sync with kDevToolsRequestInitiator defined in devtools_network_controller.cc
+const char kDevToolsRequestInitiator[] = "X-DevTools-Request-Initiator";
+const char kDevToolsEmulateNetworkConditionsClientId[] = "X-DevTools-Emulate-Network-Conditions-Client-Id";
+
static PassRefPtr<JSONObject> buildObjectForHeaders(const HTTPHeaderMap& headers)
{
RefPtr<JSONObject> headersObject = JSONObject::create();
@@ -91,7 +93,7 @@ static PassRefPtr<JSONObject> buildObjectForHeaders(const HTTPHeaderMap& headers
return headersObject;
}
-class InspectorThreadableLoaderClient : public ThreadableLoaderClient {
+class InspectorThreadableLoaderClient FINAL : public ThreadableLoaderClient {
WTF_MAKE_NONCOPYABLE(InspectorThreadableLoaderClient);
public:
InspectorThreadableLoaderClient(PassRefPtr<LoadResourceForFrontendCallback> callback)
@@ -100,7 +102,7 @@ public:
virtual ~InspectorThreadableLoaderClient() { }
- virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
+ virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse& response) OVERRIDE
{
WTF::TextEncoding textEncoding(response.textEncodingName());
bool useDetector = false;
@@ -113,7 +115,7 @@ public:
m_responseHeaders = response.httpHeaderFields();
}
- virtual void didReceiveData(const char* data, int dataLength)
+ virtual void didReceiveData(const char* data, int dataLength) OVERRIDE
{
if (!dataLength)
return;
@@ -124,7 +126,7 @@ public:
m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, dataLength));
}
- virtual void didFinishLoading(unsigned long /*identifier*/, double /*finishTime*/)
+ virtual void didFinishLoading(unsigned long /*identifier*/, double /*finishTime*/) OVERRIDE
{
if (m_decoder)
m_responseText = m_responseText.concatenateWith(m_decoder->flush());
@@ -132,13 +134,13 @@ public:
dispose();
}
- virtual void didFail(const ResourceError&)
+ virtual void didFail(const ResourceError&) OVERRIDE
{
m_callback->sendFailure("Loading resource for inspector failed");
dispose();
}
- virtual void didFailRedirectCheck()
+ virtual void didFailRedirectCheck() OVERRIDE
{
m_callback->sendFailure("Loading resource for inspector failed redirect check");
dispose();
@@ -158,7 +160,7 @@ public:
private:
void dispose()
{
- m_loader = 0;
+ m_loader = nullptr;
delete this;
}
@@ -232,8 +234,7 @@ static PassRefPtr<TypeBuilder::Network::Request> buildObjectForResourceRequest(c
static PassRefPtr<TypeBuilder::Network::Response> buildObjectForResourceResponse(const ResourceResponse& response, DocumentLoader* loader)
{
if (response.isNull())
- return 0;
-
+ return nullptr;
double status;
String statusText;
@@ -245,11 +246,13 @@ static PassRefPtr<TypeBuilder::Network::Response> buildObjectForResourceResponse
statusText = response.httpStatusText();
}
RefPtr<JSONObject> headers;
- if (response.resourceLoadInfo())
+ if (response.resourceLoadInfo() && response.resourceLoadInfo()->responseHeaders.size())
headers = buildObjectForHeaders(response.resourceLoadInfo()->responseHeaders);
else
headers = buildObjectForHeaders(response.httpHeaderFields());
+ int64_t encodedDataLength = response.resourceLoadInfo() ? response.resourceLoadInfo()->encodedDataLength : -1;
+
RefPtr<TypeBuilder::Network::Response> responseObject = TypeBuilder::Network::Response::create()
.setUrl(urlWithoutFragment(response.url()).string())
.setStatus(status)
@@ -257,7 +260,8 @@ static PassRefPtr<TypeBuilder::Network::Response> buildObjectForResourceResponse
.setHeaders(headers)
.setMimeType(response.mimeType())
.setConnectionReused(response.connectionReused())
- .setConnectionId(response.connectionID());
+ .setConnectionId(response.connectionID())
+ .setEncodedDataLength(encodedDataLength);
responseObject->setFromDiskCache(response.wasCached());
if (response.resourceLoadTiming())
@@ -266,12 +270,18 @@ static PassRefPtr<TypeBuilder::Network::Response> buildObjectForResourceResponse
if (response.resourceLoadInfo()) {
if (!response.resourceLoadInfo()->responseHeadersText.isEmpty())
responseObject->setHeadersText(response.resourceLoadInfo()->responseHeadersText);
-
- responseObject->setRequestHeaders(buildObjectForHeaders(response.resourceLoadInfo()->requestHeaders));
+ if (response.resourceLoadInfo()->requestHeaders.size())
+ responseObject->setRequestHeaders(buildObjectForHeaders(response.resourceLoadInfo()->requestHeaders));
if (!response.resourceLoadInfo()->requestHeadersText.isEmpty())
responseObject->setRequestHeadersText(response.resourceLoadInfo()->requestHeadersText);
}
+ AtomicString remoteIPAddress = response.remoteIPAddress();
+ if (!remoteIPAddress.isEmpty()) {
+ responseObject->setRemoteIPAddress(remoteIPAddress);
+ responseObject->setRemotePort(response.remotePort());
+ }
+
return responseObject;
}
@@ -289,6 +299,10 @@ void InspectorResourceAgent::willSendRequest(unsigned long identifier, DocumentL
// Ignore the request initiated internally.
if (initiatorInfo.name == FetchInitiatorTypeNames::internal)
return;
+
+ if (!m_hostId.isEmpty())
+ request.addHTTPHeaderField(kDevToolsEmulateNetworkConditionsClientId, AtomicString(m_hostId));
+
String requestId = IdentifiersFactory::requestId(identifier);
m_resourcesData->resourceCreated(requestId, m_pageAgent->loaderId(loader));
@@ -299,18 +313,14 @@ void InspectorResourceAgent::willSendRequest(unsigned long identifier, DocumentL
for (JSONObject::const_iterator it = headers->begin(); it != end; ++it) {
String value;
if (it->value->asString(&value))
- request.setHTTPHeaderField(it->key, value);
+ request.setHTTPHeaderField(AtomicString(it->key), AtomicString(value));
}
}
- request.setReportLoadTiming(true);
request.setReportRawHeaders(true);
- if (m_state->getBoolean(ResourceAgentState::cacheDisabled)) {
- request.setHTTPHeaderField("Pragma", "no-cache");
- request.setCachePolicy(ReloadIgnoringCacheData);
- request.setHTTPHeaderField("Cache-Control", "no-cache");
- }
+ if (m_state->getBoolean(ResourceAgentState::cacheDisabled))
+ request.setCachePolicy(ReloadBypassingCache);
String frameId = m_pageAgent->frameId(loader->frame());
@@ -329,7 +339,19 @@ void InspectorResourceAgent::markResourceAsCached(unsigned long identifier)
m_frontend->requestServedFromCache(IdentifiersFactory::requestId(identifier));
}
-void InspectorResourceAgent::didReceiveResourceResponse(Frame*, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
+bool isResponseEmpty(PassRefPtr<TypeBuilder::Network::Response> response)
+{
+ if (!response)
+ return true;
+
+ RefPtr<JSONValue> status = response->get("status");
+ RefPtr<JSONValue> mimeType = response->get("mimeType");
+ RefPtr<JSONObject> headers = response->getObject("headers");
+
+ return !status && !mimeType && (!headers || !headers->size());
+}
+
+void InspectorResourceAgent::didReceiveResourceResponse(LocalFrame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
{
if (!loader)
return;
@@ -362,11 +384,13 @@ void InspectorResourceAgent::didReceiveResourceResponse(Frame*, unsigned long id
m_resourcesData->responseReceived(requestId, m_pageAgent->frameId(loader->frame()), response);
m_resourcesData->setResourceType(requestId, type);
- m_frontend->responseReceived(requestId, m_pageAgent->frameId(loader->frame()), m_pageAgent->loaderId(loader), currentTime(), InspectorPageAgent::resourceTypeJson(type), resourceResponse);
+
+ if (!isResponseEmpty(resourceResponse))
+ m_frontend->responseReceived(requestId, m_pageAgent->frameId(loader->frame()), m_pageAgent->loaderId(loader), currentTime(), InspectorPageAgent::resourceTypeJson(type), resourceResponse);
// If we revalidated the resource and got Not modified, send content length following didReceiveResponse
// as there will be no calls to didReceiveData from the network stack.
if (isNotModified && cachedResource && cachedResource->encodedSize())
- didReceiveData(identifier, 0, cachedResource->encodedSize(), 0);
+ didReceiveData(frame, identifier, 0, cachedResource->encodedSize(), 0);
}
static bool isErrorStatusCode(int statusCode)
@@ -374,7 +398,7 @@ static bool isErrorStatusCode(int statusCode)
return statusCode >= 400;
}
-void InspectorResourceAgent::didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength)
+void InspectorResourceAgent::didReceiveData(LocalFrame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength)
{
String requestId = IdentifiersFactory::requestId(identifier);
@@ -387,7 +411,7 @@ void InspectorResourceAgent::didReceiveData(unsigned long identifier, const char
m_frontend->dataReceived(requestId, currentTime(), dataLength, encodedDataLength);
}
-void InspectorResourceAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, double monotonicFinishTime)
+void InspectorResourceAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, double monotonicFinishTime, int64_t encodedDataLength)
{
double finishTime = 0.0;
// FIXME: Expose all of the timing details to inspector and have it calculate finishTime.
@@ -398,21 +422,21 @@ void InspectorResourceAgent::didFinishLoading(unsigned long identifier, Document
m_resourcesData->maybeDecodeDataToContent(requestId);
if (!finishTime)
finishTime = currentTime();
- m_frontend->loadingFinished(requestId, finishTime);
+ m_frontend->loadingFinished(requestId, finishTime, encodedDataLength);
}
-void InspectorResourceAgent::didReceiveCORSRedirectResponse(Frame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
+void InspectorResourceAgent::didReceiveCORSRedirectResponse(LocalFrame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
{
// Update the response and finish loading
didReceiveResourceResponse(frame, identifier, loader, response, resourceLoader);
- didFinishLoading(identifier, loader, 0);
+ didFinishLoading(identifier, loader, 0, blink::WebURLLoaderClient::kUnknownEncodedDataLength);
}
-void InspectorResourceAgent::didFailLoading(unsigned long identifier, DocumentLoader* loader, const ResourceError& error)
+void InspectorResourceAgent::didFailLoading(unsigned long identifier, const ResourceError& error)
{
String requestId = IdentifiersFactory::requestId(identifier);
bool canceled = error.isCancellation();
- m_frontend->loadingFailed(requestId, currentTime(), error.localizedDescription(), canceled ? &canceled : 0);
+ m_frontend->loadingFailed(requestId, currentTime(), InspectorPageAgent::resourceTypeJson(m_resourcesData->resourceType(requestId)), error.localizedDescription(), canceled ? &canceled : 0);
}
void InspectorResourceAgent::scriptImported(unsigned long identifier, const String& sourceString)
@@ -434,14 +458,16 @@ void InspectorResourceAgent::documentThreadableLoaderStartedLoadingForClient(uns
if (it == m_pendingXHRReplayData.end())
return;
+ m_resourcesData->setResourceType(IdentifiersFactory::requestId(identifier), InspectorPageAgent::XHRResource);
XHRReplayData* xhrReplayData = it->value.get();
String requestId = IdentifiersFactory::requestId(identifier);
m_resourcesData->setXHRReplayData(requestId, xhrReplayData);
}
-void InspectorResourceAgent::willLoadXHR(XMLHttpRequest*, ThreadableLoaderClient* client, const AtomicString& method, const KURL& url, bool async, PassRefPtr<FormData> formData, const HTTPHeaderMap& headers, bool includeCredentials)
+void InspectorResourceAgent::willLoadXHR(XMLHttpRequest* xhr, ThreadableLoaderClient* client, const AtomicString& method, const KURL& url, bool async, FormData* formData, const HTTPHeaderMap& headers, bool includeCredentials)
{
- RefPtr<XHRReplayData> xhrReplayData = XHRReplayData::create(method, urlWithoutFragment(url), async, formData, includeCredentials);
+ ASSERT(xhr);
+ RefPtr<XHRReplayData> xhrReplayData = XHRReplayData::create(xhr->executionContext(), method, urlWithoutFragment(url), async, formData, includeCredentials);
HTTPHeaderMap::const_iterator end = headers.end();
for (HTTPHeaderMap::const_iterator it = headers.begin(); it!= end; ++it)
xhrReplayData->addHeader(it->key, it->value);
@@ -453,7 +479,7 @@ void InspectorResourceAgent::didFailXHRLoading(XMLHttpRequest*, ThreadableLoader
m_pendingXHRReplayData.remove(client);
}
-void InspectorResourceAgent::didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient* client, unsigned long identifier, ScriptString sourceString, const String&, const String&, unsigned)
+void InspectorResourceAgent::didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient* client, unsigned long identifier, ScriptString sourceString, const AtomicString&, const String&, const String&, unsigned)
{
m_pendingXHRReplayData.remove(client);
}
@@ -485,7 +511,7 @@ void InspectorResourceAgent::willRecalculateStyle(Document*)
m_isRecalculatingStyle = true;
}
-void InspectorResourceAgent::didRecalculateStyle()
+void InspectorResourceAgent::didRecalculateStyle(int)
{
m_isRecalculatingStyle = false;
m_styleRecalculationInitiator = nullptr;
@@ -499,7 +525,7 @@ void InspectorResourceAgent::didScheduleStyleRecalculation(Document* document)
PassRefPtr<TypeBuilder::Network::Initiator> InspectorResourceAgent::buildInitiatorObject(Document* document, const FetchInitiatorInfo& initiatorInfo)
{
- RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
+ RefPtrWillBeRawPtr<ScriptCallStack> stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
if (stackTrace && stackTrace->size() > 0) {
RefPtr<TypeBuilder::Network::Initiator> initiatorObject = TypeBuilder::Network::Initiator::create()
.setType(TypeBuilder::Network::Initiator::Type::Script);
@@ -531,19 +557,29 @@ void InspectorResourceAgent::didCreateWebSocket(Document*, unsigned long identif
m_frontend->webSocketCreated(IdentifiersFactory::requestId(identifier), urlWithoutFragment(requestURL).string());
}
-void InspectorResourceAgent::willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest& request)
+void InspectorResourceAgent::willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest* request)
{
+ ASSERT(request);
RefPtr<TypeBuilder::Network::WebSocketRequest> requestObject = TypeBuilder::Network::WebSocketRequest::create()
- .setHeaders(buildObjectForHeaders(request.headerFields()));
+ .setHeaders(buildObjectForHeaders(request->headerFields()));
m_frontend->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), currentTime(), requestObject);
}
-void InspectorResourceAgent::didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeResponse& response)
+void InspectorResourceAgent::didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeRequest* request, const WebSocketHandshakeResponse* response)
{
+ ASSERT(response);
RefPtr<TypeBuilder::Network::WebSocketResponse> responseObject = TypeBuilder::Network::WebSocketResponse::create()
- .setStatus(response.statusCode())
- .setStatusText(response.statusText())
- .setHeaders(buildObjectForHeaders(response.headerFields()));
+ .setStatus(response->statusCode())
+ .setStatusText(response->statusText())
+ .setHeaders(buildObjectForHeaders(response->headerFields()));
+
+ if (!response->headersText().isEmpty())
+ responseObject->setHeadersText(response->headersText());
+ if (request) {
+ responseObject->setRequestHeaders(buildObjectForHeaders(request->headerFields()));
+ if (!request->headersText().isEmpty())
+ responseObject->setRequestHeadersText(request->headersText());
+ }
m_frontend->webSocketHandshakeResponseReceived(IdentifiersFactory::requestId(identifier), currentTime(), responseObject);
}
@@ -552,21 +588,21 @@ void InspectorResourceAgent::didCloseWebSocket(Document*, unsigned long identifi
m_frontend->webSocketClosed(IdentifiersFactory::requestId(identifier), currentTime());
}
-void InspectorResourceAgent::didReceiveWebSocketFrame(unsigned long identifier, const WebSocketFrame& frame)
+void InspectorResourceAgent::didReceiveWebSocketFrame(unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength)
{
RefPtr<TypeBuilder::Network::WebSocketFrame> frameObject = TypeBuilder::Network::WebSocketFrame::create()
- .setOpcode(frame.opCode)
- .setMask(frame.masked)
- .setPayloadData(String(frame.payload, frame.payloadLength));
+ .setOpcode(opCode)
+ .setMask(masked)
+ .setPayloadData(String(payload, payloadLength));
m_frontend->webSocketFrameReceived(IdentifiersFactory::requestId(identifier), currentTime(), frameObject);
}
-void InspectorResourceAgent::didSendWebSocketFrame(unsigned long identifier, const WebSocketFrame& frame)
+void InspectorResourceAgent::didSendWebSocketFrame(unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength)
{
RefPtr<TypeBuilder::Network::WebSocketFrame> frameObject = TypeBuilder::Network::WebSocketFrame::create()
- .setOpcode(frame.opCode)
- .setMask(frame.masked)
- .setPayloadData(String(frame.payload, frame.payloadLength));
+ .setOpcode(opCode)
+ .setMask(masked)
+ .setPayloadData(String(payload, payloadLength));
m_frontend->webSocketFrameSent(IdentifiersFactory::requestId(identifier), currentTime(), frameObject);
}
@@ -647,13 +683,20 @@ void InspectorResourceAgent::getResponseBody(ErrorString* errorString, const Str
void InspectorResourceAgent::replayXHR(ErrorString*, const String& requestId)
{
- RefPtr<XMLHttpRequest> xhr = XMLHttpRequest::create(m_pageAgent->mainFrame()->document());
String actualRequestId = requestId;
XHRReplayData* xhrReplayData = m_resourcesData->xhrReplayData(requestId);
if (!xhrReplayData)
return;
+ ExecutionContext* executionContext = xhrReplayData->executionContext();
+ if (!executionContext) {
+ m_resourcesData->setXHRReplayData(requestId, 0);
+ return;
+ }
+
+ RefPtrWillBeRawPtr<XMLHttpRequest> xhr = XMLHttpRequest::create(executionContext);
+
Resource* cachedResource = memoryCache()->resourceForURL(xhrReplayData->url());
if (cachedResource)
memoryCache()->remove(cachedResource);
@@ -670,32 +713,26 @@ void InspectorResourceAgent::canClearBrowserCache(ErrorString*, bool* result)
*result = true;
}
-void InspectorResourceAgent::clearBrowserCache(ErrorString*)
-{
- m_client->clearBrowserCache();
-}
-
void InspectorResourceAgent::canClearBrowserCookies(ErrorString*, bool* result)
{
*result = true;
}
-void InspectorResourceAgent::clearBrowserCookies(ErrorString*)
-{
- m_client->clearBrowserCookies();
-}
-
void InspectorResourceAgent::setCacheDisabled(ErrorString*, bool cacheDisabled)
{
m_state->setBoolean(ResourceAgentState::cacheDisabled, cacheDisabled);
if (cacheDisabled)
memoryCache()->evictResources();
+ for (Frame* frame = m_pageAgent->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->fetcher()->garbageCollectDocumentResources();
+ }
}
void InspectorResourceAgent::loadResourceForFrontend(ErrorString* errorString, const String& frameId, const String& url, const RefPtr<JSONObject>* requestHeaders, PassRefPtr<LoadResourceForFrontendCallback> prpCallback)
{
RefPtr<LoadResourceForFrontendCallback> callback = prpCallback;
- Frame* frame = m_pageAgent->assertFrame(errorString, frameId);
+ LocalFrame* frame = m_pageAgent->assertFrame(errorString, frameId);
if (!frame)
return;
@@ -716,17 +753,19 @@ void InspectorResourceAgent::loadResourceForFrontend(ErrorString* errorString, c
*errorString = "Request header \"" + it->key + "\" value is not a string";
return;
}
- request.addHTTPHeaderField(it->key, value);
+ request.addHTTPHeaderField(AtomicString(it->key), AtomicString(value));
}
}
+ request.addHTTPHeaderField(kDevToolsRequestInitiator, "frontend");
ThreadableLoaderOptions options;
- options.allowCredentials = AllowStoredCredentials;
options.crossOriginRequestPolicy = AllowCrossOriginRequests;
- options.sendLoadCallbacks = SendCallbacks;
+
+ ResourceLoaderOptions resourceLoaderOptions;
+ resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
InspectorThreadableLoaderClient* inspectorThreadableLoaderClient = new InspectorThreadableLoaderClient(callback);
- RefPtr<DocumentThreadableLoader> loader = DocumentThreadableLoader::create(document, inspectorThreadableLoaderClient, request, options);
+ RefPtr<DocumentThreadableLoader> loader = DocumentThreadableLoader::create(*document, inspectorThreadableLoaderClient, request, options, resourceLoaderOptions);
if (!loader) {
inspectorThreadableLoaderClient->didFailLoaderCreation();
return;
@@ -737,7 +776,7 @@ void InspectorResourceAgent::loadResourceForFrontend(ErrorString* errorString, c
inspectorThreadableLoaderClient->setLoader(loader.release());
}
-void InspectorResourceAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorResourceAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
{
if (loader->frame() != frame->page()->mainFrame())
return;
@@ -748,18 +787,23 @@ void InspectorResourceAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
m_resourcesData->clear(m_pageAgent->loaderId(loader));
}
-void InspectorResourceAgent::frameScheduledNavigation(Frame* frame, double)
+void InspectorResourceAgent::frameScheduledNavigation(LocalFrame* frame, double)
{
RefPtr<TypeBuilder::Network::Initiator> initiator = buildInitiatorObject(frame->document(), FetchInitiatorInfo());
m_frameNavigationInitiatorMap.set(m_pageAgent->frameId(frame), initiator);
}
-void InspectorResourceAgent::frameClearedScheduledNavigation(Frame* frame)
+void InspectorResourceAgent::frameClearedScheduledNavigation(LocalFrame* frame)
{
m_frameNavigationInitiatorMap.remove(m_pageAgent->frameId(frame));
}
-bool InspectorResourceAgent::fetchResourceContent(Frame* frame, const KURL& url, String* content, bool* base64Encoded)
+void InspectorResourceAgent::setHostId(const String& hostId)
+{
+ m_hostId = hostId;
+}
+
+bool InspectorResourceAgent::fetchResourceContent(LocalFrame* frame, const KURL& url, String* content, bool* base64Encoded)
{
// First try to fetch content from the cached resource.
Resource* cachedResource = frame->document()->fetcher()->cachedResource(url);
@@ -780,10 +824,9 @@ bool InspectorResourceAgent::fetchResourceContent(Frame* frame, const KURL& url,
return false;
}
-InspectorResourceAgent::InspectorResourceAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorClient* client, InspectorCompositeState* state)
- : InspectorBaseAgent<InspectorResourceAgent>("Network", instrumentingAgents, state)
+InspectorResourceAgent::InspectorResourceAgent(InspectorPageAgent* pageAgent)
+ : InspectorBaseAgent<InspectorResourceAgent>("Network")
, m_pageAgent(pageAgent)
- , m_client(client)
, m_frontend(0)
, m_resourcesData(adoptPtr(new NetworkResourcesData()))
, m_isRecalculatingStyle(false)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h
index e5eb8be79ec..8eafcc7ad50 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceAgent.h
@@ -31,8 +31,8 @@
#ifndef InspectorResourceAgent_h
#define InspectorResourceAgent_h
-#include "InspectorFrontend.h"
#include "bindings/v8/ScriptString.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/WTFString.h"
@@ -49,9 +49,8 @@ struct FetchInitiatorInfo;
class Document;
class DocumentLoader;
class FormData;
-class Frame;
+class LocalFrame;
class HTTPHeaderMap;
-class InspectorClient;
class InspectorFrontend;
class InspectorPageAgent;
class InstrumentingAgents;
@@ -67,43 +66,40 @@ class ThreadableLoaderClient;
class XHRReplayData;
class XMLHttpRequest;
-struct WebSocketFrame;
class WebSocketHandshakeRequest;
class WebSocketHandshakeResponse;
typedef String ErrorString;
-class InspectorResourceAgent : public InspectorBaseAgent<InspectorResourceAgent>, public InspectorBackendDispatcher::NetworkCommandHandler {
+class InspectorResourceAgent FINAL : public InspectorBaseAgent<InspectorResourceAgent>, public InspectorBackendDispatcher::NetworkCommandHandler {
public:
- static PassOwnPtr<InspectorResourceAgent> create(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorClient* client, InspectorCompositeState* state)
+ static PassOwnPtr<InspectorResourceAgent> create(InspectorPageAgent* pageAgent)
{
- return adoptPtr(new InspectorResourceAgent(instrumentingAgents, pageAgent, client, state));
+ return adoptPtr(new InspectorResourceAgent(pageAgent));
}
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
- static PassRefPtr<InspectorResourceAgent> restore(Page*, InspectorCompositeState*, InspectorFrontend*);
-
- ~InspectorResourceAgent();
+ virtual ~InspectorResourceAgent();
// Called from instrumentation.
void willSendRequest(unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&);
void markResourceAsCached(unsigned long identifier);
- void didReceiveResourceResponse(Frame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
- void didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
- void didFinishLoading(unsigned long identifier, DocumentLoader*, double monotonicFinishTime);
- void didReceiveCORSRedirectResponse(Frame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
- void didFailLoading(unsigned long identifier, DocumentLoader*, const ResourceError&);
- void didCommitLoad(Frame*, DocumentLoader*);
+ void didReceiveResourceResponse(LocalFrame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+ void didReceiveData(LocalFrame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
+ void didFinishLoading(unsigned long identifier, DocumentLoader*, double monotonicFinishTime, int64_t encodedDataLength);
+ void didReceiveCORSRedirectResponse(LocalFrame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+ void didFailLoading(unsigned long identifier, const ResourceError&);
+ void didCommitLoad(LocalFrame*, DocumentLoader*);
void scriptImported(unsigned long identifier, const String& sourceString);
void didReceiveScriptResponse(unsigned long identifier);
void documentThreadableLoaderStartedLoadingForClient(unsigned long identifier, ThreadableLoaderClient*);
- void willLoadXHR(XMLHttpRequest*, ThreadableLoaderClient*, const AtomicString& method, const KURL&, bool async, PassRefPtr<FormData> body, const HTTPHeaderMap& headers, bool includeCrendentials);
+ void willLoadXHR(XMLHttpRequest*, ThreadableLoaderClient*, const AtomicString& method, const KURL&, bool async, FormData* body, const HTTPHeaderMap& headers, bool includeCrendentials);
void didFailXHRLoading(XMLHttpRequest*, ThreadableLoaderClient*);
- void didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient*, unsigned long identifier, ScriptString sourceString, const String&, const String&, unsigned);
+ void didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient*, unsigned long identifier, ScriptString sourceString, const AtomicString&, const String&, const String&, unsigned);
void willDestroyResource(Resource*);
@@ -111,54 +107,53 @@ public:
// FIXME: InspectorResourceAgent should not be aware of style recalculation.
void willRecalculateStyle(Document*);
- void didRecalculateStyle();
+ void didRecalculateStyle(int);
void didScheduleStyleRecalculation(Document*);
- void frameScheduledNavigation(Frame*, double);
- void frameClearedScheduledNavigation(Frame*);
+ void frameScheduledNavigation(LocalFrame*, double);
+ void frameClearedScheduledNavigation(LocalFrame*);
PassRefPtr<TypeBuilder::Network::Initiator> buildInitiatorObject(Document*, const FetchInitiatorInfo&);
void didCreateWebSocket(Document*, unsigned long identifier, const KURL& requestURL, const String&);
- void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest&);
- void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeResponse&);
+ void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest*);
+ void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeRequest*, const WebSocketHandshakeResponse*);
void didCloseWebSocket(Document*, unsigned long identifier);
- void didReceiveWebSocketFrame(unsigned long identifier, const WebSocketFrame&);
- void didSendWebSocketFrame(unsigned long identifier, const WebSocketFrame&);
+ void didReceiveWebSocketFrame(unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength);
+ void didSendWebSocketFrame(unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength);
void didReceiveWebSocketFrameError(unsigned long identifier, const String&);
// called from Internals for layout test purposes.
void setResourcesDataSizeLimitsFromInternals(int maximumResourcesContentSize, int maximumSingleResourceContentSize);
// Called from frontend
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void setUserAgentOverride(ErrorString*, const String& userAgent);
- virtual void setExtraHTTPHeaders(ErrorString*, const RefPtr<JSONObject>&);
- virtual void getResponseBody(ErrorString*, const String& requestId, String* content, bool* base64Encoded);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void setUserAgentOverride(ErrorString*, const String& userAgent) OVERRIDE;
+ virtual void setExtraHTTPHeaders(ErrorString*, const RefPtr<JSONObject>&) OVERRIDE;
+ virtual void getResponseBody(ErrorString*, const String& requestId, String* content, bool* base64Encoded) OVERRIDE;
- virtual void replayXHR(ErrorString*, const String& requestId);
+ virtual void replayXHR(ErrorString*, const String& requestId) OVERRIDE;
- virtual void canClearBrowserCache(ErrorString*, bool*);
- virtual void clearBrowserCache(ErrorString*);
- virtual void canClearBrowserCookies(ErrorString*, bool*);
- virtual void clearBrowserCookies(ErrorString*);
- virtual void setCacheDisabled(ErrorString*, bool cacheDisabled);
+ virtual void canClearBrowserCache(ErrorString*, bool*) OVERRIDE;
+ virtual void canClearBrowserCookies(ErrorString*, bool*) OVERRIDE;
+ virtual void setCacheDisabled(ErrorString*, bool cacheDisabled) OVERRIDE;
- virtual void loadResourceForFrontend(ErrorString*, const String& frameId, const String& url, const RefPtr<JSONObject>* requestHeaders, PassRefPtr<LoadResourceForFrontendCallback>);
+ virtual void loadResourceForFrontend(ErrorString*, const String& frameId, const String& url, const RefPtr<JSONObject>* requestHeaders, PassRefPtr<LoadResourceForFrontendCallback>) OVERRIDE;
// Called from other agents.
- bool fetchResourceContent(Frame*, const KURL&, String* content, bool* base64Encoded);
+ void setHostId(const String&);
+ bool fetchResourceContent(LocalFrame*, const KURL&, String* content, bool* base64Encoded);
private:
- InspectorResourceAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorClient*, InspectorCompositeState*);
+ InspectorResourceAgent(InspectorPageAgent*);
void enable();
InspectorPageAgent* m_pageAgent;
- InspectorClient* m_client;
InspectorFrontend::Network* m_frontend;
String m_userAgentOverride;
+ String m_hostId;
OwnPtr<NetworkResourcesData> m_resourcesData;
typedef HashMap<ThreadableLoaderClient*, RefPtr<XHRReplayData> > PendingXHRReplayDataMap;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
new file mode 100644
index 00000000000..32ca861fba5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
@@ -0,0 +1,134 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/inspector/InspectorResourceContentLoader.h"
+
+#include "FetchInitiatorTypeNames.h"
+#include "core/css/CSSStyleSheet.h"
+#include "core/css/StyleSheetContents.h"
+#include "core/fetch/CSSStyleSheetResource.h"
+#include "core/fetch/Resource.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/fetch/ResourcePtr.h"
+#include "core/fetch/StyleSheetResourceClient.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/VoidCallback.h"
+#include "core/inspector/InspectorCSSAgent.h"
+#include "core/inspector/InspectorPageAgent.h"
+#include "core/page/Page.h"
+
+namespace WebCore {
+
+class InspectorResourceContentLoader::ResourceClient FINAL : private StyleSheetResourceClient {
+public:
+ ResourceClient(InspectorResourceContentLoader* loader)
+ : m_loader(loader)
+ {
+ }
+
+ void waitForResource(Resource* resource)
+ {
+ resource->addClient(this);
+ }
+
+private:
+ InspectorResourceContentLoader* m_loader;
+
+ virtual void setCSSStyleSheet(const String&, const KURL&, const String&, const CSSStyleSheetResource*) OVERRIDE;
+
+ friend class InspectorResourceContentLoader;
+};
+
+void InspectorResourceContentLoader::ResourceClient::setCSSStyleSheet(const String&, const KURL& url, const String&, const CSSStyleSheetResource* resource)
+{
+ if (m_loader)
+ m_loader->resourceFinished(this);
+ const_cast<CSSStyleSheetResource*>(resource)->removeClient(this);
+ delete this;
+}
+
+InspectorResourceContentLoader::InspectorResourceContentLoader(Page* page)
+ : m_allRequestsStarted(false)
+{
+ Vector<Document*> documents;
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ LocalFrame* localFrame = toLocalFrame(frame);
+ documents.append(localFrame->document());
+ documents.appendVector(InspectorPageAgent::importsForFrame(localFrame));
+ }
+ for (Vector<Document*>::const_iterator documentIt = documents.begin(); documentIt != documents.end(); ++documentIt) {
+ Document* document = *documentIt;
+
+ HashSet<String> urlsToFetch;
+ Vector<CSSStyleSheet*> styleSheets;
+ InspectorCSSAgent::collectAllDocumentStyleSheets(document, styleSheets);
+ for (Vector<CSSStyleSheet*>::const_iterator stylesheetIt = styleSheets.begin(); stylesheetIt != styleSheets.end(); ++stylesheetIt) {
+ CSSStyleSheet* styleSheet = *stylesheetIt;
+ if (styleSheet->isInline() || !styleSheet->contents()->loadCompleted())
+ continue;
+ String url = styleSheet->baseURL().string();
+ if (url.isEmpty() || urlsToFetch.contains(url))
+ continue;
+ urlsToFetch.add(url);
+ FetchRequest request(ResourceRequest(url), FetchInitiatorTypeNames::internal);
+ ResourcePtr<Resource> resource = document->fetcher()->fetchCSSStyleSheet(request);
+ // Prevent garbage collection by holding a reference to this resource.
+ m_resources.append(resource.get());
+ ResourceClient* resourceClient = new ResourceClient(this);
+ m_pendingResourceClients.add(resourceClient);
+ resourceClient->waitForResource(resource.get());
+ }
+ }
+
+ m_allRequestsStarted = true;
+ checkDone();
+}
+
+void InspectorResourceContentLoader::addListener(PassOwnPtr<VoidCallback> callback)
+{
+ m_callbacks.append(callback);
+ checkDone();
+}
+
+InspectorResourceContentLoader::~InspectorResourceContentLoader()
+{
+ stop();
+}
+
+void InspectorResourceContentLoader::stop()
+{
+ HashSet<ResourceClient*> pendingResourceClients;
+ m_pendingResourceClients.swap(pendingResourceClients);
+ for (HashSet<ResourceClient*>::const_iterator it = pendingResourceClients.begin(); it != pendingResourceClients.end(); ++it)
+ (*it)->m_loader = 0;
+ m_resources.clear();
+ // Make sure all callbacks are called to prevent infinite waiting time.
+ checkDone();
+}
+
+bool InspectorResourceContentLoader::hasFinished()
+{
+ return m_allRequestsStarted && m_pendingResourceClients.size() == 0;
+}
+
+void InspectorResourceContentLoader::checkDone()
+{
+ if (!hasFinished())
+ return;
+ Vector<OwnPtr<VoidCallback> > callbacks;
+ callbacks.swap(m_callbacks);
+ for (Vector<OwnPtr<VoidCallback> >::const_iterator it = callbacks.begin(); it != callbacks.end(); ++it)
+ (*it)->handleEvent();
+}
+
+void InspectorResourceContentLoader::resourceFinished(ResourceClient* client)
+{
+ m_pendingResourceClients.remove(client);
+ checkDone();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h
new file mode 100644
index 00000000000..c781e20d032
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.h
@@ -0,0 +1,47 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef InspectorResourceContentLoader_h
+#define InspectorResourceContentLoader_h
+
+#include "core/fetch/ResourcePtr.h"
+#include "wtf/HashSet.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CSSStyleSheetResource;
+class Page;
+class Resource;
+class VoidCallback;
+
+class InspectorResourceContentLoader FINAL {
+ WTF_MAKE_NONCOPYABLE(InspectorResourceContentLoader);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ InspectorResourceContentLoader(Page*);
+ void addListener(PassOwnPtr<VoidCallback>);
+ ~InspectorResourceContentLoader();
+ bool hasFinished();
+ void stop();
+
+private:
+ class ResourceClient;
+
+ void resourceFinished(ResourceClient*);
+ void checkDone();
+
+ Vector<OwnPtr<VoidCallback> > m_callbacks;
+ bool m_allRequestsStarted;
+ HashSet<ResourceClient*> m_pendingResourceClients;
+ Vector<ResourcePtr<Resource> > m_resources;
+
+ friend class ResourceClient;
+};
+
+} // namespace WebCore
+
+
+#endif // !defined(InspectorResourceContentLoader_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.cpp
index fcb3a274f56..c55ed207ddb 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.cpp
@@ -31,23 +31,30 @@
#include "config.h"
#include "core/inspector/InspectorRuntimeAgent.h"
+#include "bindings/v8/ScriptDebugServer.h"
+#include "bindings/v8/ScriptState.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptManager.h"
+#include "core/inspector/InspectorState.h"
#include "platform/JSONValues.h"
-
-#include "bindings/v8/ScriptDebugServer.h"
+using WebCore::TypeBuilder::Runtime::ExecutionContextDescription;
namespace WebCore {
+namespace InspectorRuntimeAgentState {
+static const char runtimeEnabled[] = "runtimeEnabled";
+};
+
static bool asBool(const bool* const b)
{
return b ? *b : false;
}
-InspectorRuntimeAgent::InspectorRuntimeAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer)
- : InspectorBaseAgent<InspectorRuntimeAgent>("Runtime", instrumentingAgents, state)
+InspectorRuntimeAgent::InspectorRuntimeAgent(InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer)
+ : InspectorBaseAgent<InspectorRuntimeAgent>("Runtime")
, m_enabled(false)
+ , m_frontend(0)
, m_injectedScriptManager(injectedScriptManager)
, m_scriptDebugServer(scriptDebugServer)
{
@@ -69,7 +76,7 @@ static ScriptDebugServer::PauseOnExceptionsState setPauseOnExceptionsState(Scrip
void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* const returnByValue, const bool* generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
{
InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
- if (injectedScript.hasNoValue())
+ if (injectedScript.isEmpty())
return;
ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = ScriptDebugServer::DontPauseOnExceptions;
if (asBool(doNotPauseOnExceptionsAndMuteConsole))
@@ -88,7 +95,7 @@ void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& exp
void InspectorRuntimeAgent::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const RefPtr<JSONArray>* const optionalArguments, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return;
}
@@ -113,7 +120,7 @@ void InspectorRuntimeAgent::callFunctionOn(ErrorString* errorString, const Strin
void InspectorRuntimeAgent::getProperties(ErrorString* errorString, const String& objectId, const bool* ownProperties, const bool* accessorPropertiesOnly, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::PropertyDescriptor> >& result, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::InternalPropertyDescriptor> >& internalProperties)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
- if (injectedScript.hasNoValue()) {
+ if (injectedScript.isEmpty()) {
*errorString = "Inspected frame has gone";
return;
}
@@ -134,7 +141,7 @@ void InspectorRuntimeAgent::getProperties(ErrorString* errorString, const String
void InspectorRuntimeAgent::releaseObject(ErrorString*, const String& objectId)
{
InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
- if (!injectedScript.hasNoValue())
+ if (!injectedScript.isEmpty())
injectedScript.releaseObject(objectId);
}
@@ -147,5 +154,63 @@ void InspectorRuntimeAgent::run(ErrorString*)
{
}
+void InspectorRuntimeAgent::isRunRequired(ErrorString*, bool* out_result)
+{
+ *out_result = false;
+}
+
+void InspectorRuntimeAgent::setFrontend(InspectorFrontend* frontend)
+{
+ m_frontend = frontend->runtime();
+}
+
+void InspectorRuntimeAgent::clearFrontend()
+{
+ m_frontend = 0;
+ String errorString;
+ disable(&errorString);
+}
+
+void InspectorRuntimeAgent::restore()
+{
+ if (m_state->getBoolean(InspectorRuntimeAgentState::runtimeEnabled)) {
+ m_scriptStateToId.clear();
+ m_frontend->executionContextsCleared();
+ String error;
+ enable(&error);
+ }
+}
+
+void InspectorRuntimeAgent::enable(ErrorString* errorString)
+{
+ if (m_enabled)
+ return;
+
+ m_enabled = true;
+ m_state->setBoolean(InspectorRuntimeAgentState::runtimeEnabled, true);
+}
+
+void InspectorRuntimeAgent::disable(ErrorString* errorString)
+{
+ if (!m_enabled)
+ return;
+
+ m_scriptStateToId.clear();
+ m_enabled = false;
+ m_state->setBoolean(InspectorRuntimeAgentState::runtimeEnabled, false);
+}
+
+void InspectorRuntimeAgent::addExecutionContextToFrontend(ScriptState* scriptState, bool isPageContext, const String& name, const String& frameId)
+{
+ int executionContextId = injectedScriptManager()->injectedScriptIdFor(scriptState);
+ m_scriptStateToId.set(scriptState, executionContextId);
+ m_frontend->executionContextCreated(ExecutionContextDescription::create()
+ .setId(executionContextId)
+ .setIsPageContext(isPageContext)
+ .setName(name)
+ .setFrameId(frameId)
+ .release());
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.h
index f719291b89f..82d4bcb75d4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorRuntimeAgent.h
@@ -31,7 +31,7 @@
#ifndef InspectorRuntimeAgent_h
#define InspectorRuntimeAgent_h
-
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
@@ -42,6 +42,7 @@ class InjectedScript;
class InjectedScriptManager;
class InstrumentingAgents;
class JSONArray;
+class ScriptState;
class ScriptDebugServer;
typedef String ErrorString;
@@ -52,18 +53,18 @@ public:
virtual ~InspectorRuntimeAgent();
// Part of the protocol.
- virtual void enable(ErrorString*) { m_enabled = true; }
- virtual void disable(ErrorString*) { m_enabled = false; }
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE FINAL;
virtual void evaluate(ErrorString*,
- const String& expression,
- const String* objectGroup,
- const bool* includeCommandLineAPI,
- const bool* doNotPauseOnExceptionsAndMuteConsole,
- const int* executionContextId,
- const bool* returnByValue,
- const bool* generatePreview,
- RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
- TypeBuilder::OptOutput<bool>* wasThrown);
+ const String& expression,
+ const String* objectGroup,
+ const bool* includeCommandLineAPI,
+ const bool* doNotPauseOnExceptionsAndMuteConsole,
+ const int* executionContextId,
+ const bool* returnByValue,
+ const bool* generatePreview,
+ RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
+ TypeBuilder::OptOutput<bool>* wasThrown) OVERRIDE FINAL;
virtual void callFunctionOn(ErrorString*,
const String& objectId,
const String& expression,
@@ -72,21 +73,32 @@ public:
const bool* returnByValue,
const bool* generatePreview,
RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
- TypeBuilder::OptOutput<bool>* wasThrown);
- virtual void releaseObject(ErrorString*, const String& objectId);
- virtual void getProperties(ErrorString*, const String& objectId, const bool* ownProperties, const bool* accessorPropertiesOnly, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::PropertyDescriptor> >& result, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::InternalPropertyDescriptor> >& internalProperties);
- virtual void releaseObjectGroup(ErrorString*, const String& objectGroup);
- virtual void run(ErrorString*);
+ TypeBuilder::OptOutput<bool>* wasThrown) OVERRIDE FINAL;
+ virtual void releaseObject(ErrorString*, const String& objectId) OVERRIDE FINAL;
+ virtual void getProperties(ErrorString*, const String& objectId, const bool* ownProperties, const bool* accessorPropertiesOnly, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::PropertyDescriptor> >& result, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::InternalPropertyDescriptor> >& internalProperties) OVERRIDE FINAL;
+ virtual void releaseObjectGroup(ErrorString*, const String& objectGroup) OVERRIDE FINAL;
+ virtual void run(ErrorString*) OVERRIDE;
+ virtual void isRunRequired(ErrorString*, bool* out_result) OVERRIDE;
+
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE FINAL;
+ virtual void clearFrontend() OVERRIDE FINAL;
+ virtual void restore() OVERRIDE FINAL;
protected:
- InspectorRuntimeAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*, ScriptDebugServer*);
+ InspectorRuntimeAgent(InjectedScriptManager*, ScriptDebugServer*);
virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0;
virtual void muteConsole() = 0;
virtual void unmuteConsole() = 0;
InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager; }
+ void addExecutionContextToFrontend(ScriptState*, bool isPageContext, const String& name, const String& frameId);
+
bool m_enabled;
+ InspectorFrontend::Runtime* m_frontend;
+
+ typedef HashMap<RefPtr<ScriptState>, int> ScriptStateToId;
+ ScriptStateToId m_scriptStateToId;
private:
InjectedScriptManager* m_injectedScriptManager;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorState.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorState.h
index d9faea7bdfe..353423e8bd2 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorState.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorState.h
@@ -84,7 +84,7 @@ private:
RefPtr<JSONObject> m_properties;
};
-class InspectorCompositeState : public InspectorStateUpdateListener {
+class InspectorCompositeState FINAL : public InspectorStateUpdateListener {
public:
InspectorCompositeState(InspectorStateClient* inspectorClient)
: m_client(inspectorClient)
@@ -104,7 +104,7 @@ private:
typedef HashMap<String, OwnPtr<InspectorState> > InspectorStateMap;
// From InspectorStateUpdateListener.
- virtual void inspectorStateUpdated();
+ virtual void inspectorStateUpdated() OVERRIDE;
InspectorStateClient* m_client;
RefPtr<JSONObject> m_stateObject;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.cpp
index 01f60ef60b1..256a1e4f934 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.cpp
@@ -25,16 +25,13 @@
#include "config.h"
#include "core/inspector/InspectorStyleSheet.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptRegexp.h"
+#include "core/CSSPropertyNames.h"
#include "core/css/CSSKeyframesRule.h"
#include "core/css/CSSMediaRule.h"
-#include "core/css/CSSParser.h"
-#include "core/css/CSSRule.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/CSSStyleSheet.h"
@@ -44,14 +41,13 @@
#include "core/css/StyleSheetContents.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
-#include "core/dom/Node.h"
+#include "core/html/HTMLStyleElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/inspector/ContentSearchUtils.h"
#include "core/inspector/InspectorCSSAgent.h"
#include "core/inspector/InspectorPageAgent.h"
#include "core/inspector/InspectorResourceAgent.h"
-#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
+#include "core/svg/SVGStyleElement.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/StringBuilder.h"
@@ -60,96 +56,25 @@
using WebCore::TypeBuilder::Array;
using WebCore::RuleSourceDataList;
using WebCore::CSSRuleSourceData;
+using WebCore::CSSStyleSheet;
-class ParsedStyleSheet {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- ParsedStyleSheet();
-
- const String& text() const { ASSERT(m_hasText); return m_text; }
- void setText(const String& text);
- bool hasText() const { return m_hasText; }
- void setSourceData(PassOwnPtr<RuleSourceDataList>);
- bool hasSourceData() const { return m_sourceData; }
- PassRefPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned) const;
-
-private:
- void flattenSourceData(RuleSourceDataList*);
-
- String m_text;
- bool m_hasText;
- OwnPtr<RuleSourceDataList> m_sourceData;
-};
-
-ParsedStyleSheet::ParsedStyleSheet()
- : m_hasText(false)
-{
-}
-
-void ParsedStyleSheet::setText(const String& text)
-{
- m_hasText = true;
- m_text = text;
- setSourceData(nullptr);
-}
-
-void ParsedStyleSheet::flattenSourceData(RuleSourceDataList* dataList)
-{
- for (size_t i = 0; i < dataList->size(); ++i) {
- RefPtr<CSSRuleSourceData>& data = dataList->at(i);
- if (data->type == CSSRuleSourceData::STYLE_RULE) {
- m_sourceData->append(data);
- } else if (data->type == CSSRuleSourceData::IMPORT_RULE) {
- m_sourceData->append(data);
- } else if (data->type == CSSRuleSourceData::MEDIA_RULE) {
- m_sourceData->append(data);
- flattenSourceData(&data->childRules);
- } else if (data->type == CSSRuleSourceData::SUPPORTS_RULE) {
- flattenSourceData(&data->childRules);
- }
- }
-}
-
-void ParsedStyleSheet::setSourceData(PassOwnPtr<RuleSourceDataList> sourceData)
-{
- if (!sourceData) {
- m_sourceData.clear();
- return;
- }
-
- m_sourceData = adoptPtr(new RuleSourceDataList());
+namespace {
- // FIXME: This is a temporary solution to retain the original flat sourceData structure
- // containing only style rules, even though CSSParser now provides the full rule source data tree.
- // Normally, we should just assign m_sourceData = sourceData;
- flattenSourceData(sourceData.get());
-}
+using namespace WebCore;
-PassRefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned index) const
+static CSSParserContext parserContextForDocument(Document *document)
{
- if (!hasSourceData() || index >= m_sourceData->size())
- return 0;
-
- return m_sourceData->at(index);
+ return document ? CSSParserContext(*document, 0) : strictCSSParserContext();
}
-namespace WebCore {
-
-static PassOwnPtr<CSSParser> createCSSParser(Document* document)
-{
- UseCounter* counter = 0;
- return adoptPtr(new CSSParser(document ? CSSParserContext(*document) : strictCSSParserContext(), counter));
-}
-
-namespace {
-
-class StyleSheetHandler : public CSSParser::SourceDataHandler {
+class StyleSheetHandler FINAL : public CSSParserObserver {
public:
StyleSheetHandler(const String& parsedText, Document* document, StyleSheetContents* styleSheetContents, RuleSourceDataList* result)
: m_parsedText(parsedText)
, m_document(document)
, m_styleSheetContents(styleSheetContents)
, m_result(result)
+ , m_commentParser(parserContextForDocument(document))
, m_propertyRangeStart(UINT_MAX)
, m_selectorRangeStart(UINT_MAX)
, m_commentRangeStart(UINT_MAX)
@@ -166,22 +91,22 @@ private:
virtual void endRuleBody(unsigned, bool) OVERRIDE;
virtual void startEndUnknownRule() OVERRIDE { addNewRuleToSourceTree(CSSRuleSourceData::createUnknown()); }
virtual void startProperty(unsigned) OVERRIDE;
- virtual void endProperty(bool, bool, unsigned, CSSParser::ErrorType) OVERRIDE;
+ virtual void endProperty(bool, bool, unsigned, CSSParserError) OVERRIDE;
virtual void startComment(unsigned) OVERRIDE;
virtual void endComment(unsigned) OVERRIDE;
- void addNewRuleToSourceTree(PassRefPtr<CSSRuleSourceData>);
- PassRefPtr<CSSRuleSourceData> popRuleData();
+ void addNewRuleToSourceTree(PassRefPtrWillBeRawPtr<CSSRuleSourceData>);
+ PassRefPtrWillBeRawPtr<CSSRuleSourceData> popRuleData();
template <typename CharacterType> inline void setRuleHeaderEnd(const CharacterType*, unsigned);
void fixUnparsedPropertyRanges(CSSRuleSourceData*);
const String& m_parsedText;
Document* m_document;
StyleSheetContents* m_styleSheetContents;
- RuleSourceDataList* m_result;
+ RawPtrWillBeMember<RuleSourceDataList> m_result;
RuleSourceDataList m_currentRuleDataStack;
- RefPtr<CSSRuleSourceData> m_currentRuleData;
- OwnPtr<CSSParser> m_commentParser;
+ RefPtrWillBeMember<CSSRuleSourceData> m_currentRuleData;
+ BisonCSSParser m_commentParser;
unsigned m_propertyRangeStart;
unsigned m_selectorRangeStart;
unsigned m_commentRangeStart;
@@ -193,7 +118,7 @@ void StyleSheetHandler::startRuleHeader(CSSRuleSourceData::Type type, unsigned o
if (m_currentRuleData)
m_currentRuleDataStack.removeLast();
- RefPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(type);
+ RefPtrWillBeRawPtr<CSSRuleSourceData> data = CSSRuleSourceData::create(type);
data->ruleHeaderRange.start = offset;
m_currentRuleData = data;
m_currentRuleDataStack.append(data.release());
@@ -250,7 +175,7 @@ void StyleSheetHandler::endRuleBody(unsigned offset, bool error)
ASSERT(!m_currentRuleDataStack.isEmpty());
m_currentRuleDataStack.last()->ruleBodyRange.end = offset;
m_propertyRangeStart = UINT_MAX;
- RefPtr<CSSRuleSourceData> rule = popRuleData();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> rule = popRuleData();
if (error)
return;
@@ -258,7 +183,7 @@ void StyleSheetHandler::endRuleBody(unsigned offset, bool error)
addNewRuleToSourceTree(rule.release());
}
-void StyleSheetHandler::addNewRuleToSourceTree(PassRefPtr<CSSRuleSourceData> rule)
+void StyleSheetHandler::addNewRuleToSourceTree(PassRefPtrWillBeRawPtr<CSSRuleSourceData> rule)
{
if (m_currentRuleDataStack.isEmpty())
m_result->append(rule);
@@ -266,11 +191,11 @@ void StyleSheetHandler::addNewRuleToSourceTree(PassRefPtr<CSSRuleSourceData> rul
m_currentRuleDataStack.last()->childRules.append(rule);
}
-PassRefPtr<CSSRuleSourceData> StyleSheetHandler::popRuleData()
+PassRefPtrWillBeRawPtr<CSSRuleSourceData> StyleSheetHandler::popRuleData()
{
ASSERT(!m_currentRuleDataStack.isEmpty());
m_currentRuleData.clear();
- RefPtr<CSSRuleSourceData> data = m_currentRuleDataStack.last();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> data = m_currentRuleDataStack.last();
m_currentRuleDataStack.removeLast();
return data.release();
}
@@ -278,7 +203,7 @@ PassRefPtr<CSSRuleSourceData> StyleSheetHandler::popRuleData()
template <typename CharacterType>
static inline void fixUnparsedProperties(const CharacterType* characters, CSSRuleSourceData* ruleData)
{
- Vector<CSSPropertySourceData>& propertyData = ruleData->styleSourceData->propertyData;
+ WillBeHeapVector<CSSPropertySourceData>& propertyData = ruleData->styleSourceData->propertyData;
unsigned size = propertyData.size();
if (!size)
return;
@@ -340,9 +265,10 @@ void StyleSheetHandler::startProperty(unsigned offset)
m_propertyRangeStart = offset;
}
-void StyleSheetHandler::endProperty(bool isImportant, bool isParsed, unsigned offset, CSSParser::ErrorType errorType)
+void StyleSheetHandler::endProperty(bool isImportant, bool isParsed, unsigned offset, CSSParserError errorType)
{
- if (errorType != CSSParser::NoError)
+ // FIXME: This is the only place CSSParserError is every read!?
+ if (errorType != NoCSSError)
m_propertyRangeStart = UINT_MAX;
if (m_propertyRangeStart == UINT_MAX || m_currentRuleDataStack.isEmpty() || !m_currentRuleDataStack.last()->styleSourceData)
@@ -407,16 +333,14 @@ void StyleSheetHandler::endComment(unsigned offset)
return;
// FIXME: Use the actual rule type rather than STYLE_RULE?
- if (!m_commentParser)
- m_commentParser = createCSSParser(m_document);
RuleSourceDataList sourceData;
- // FIXME: Use another subclass of CSSParser::SourceDataHandler and assert that
+ // FIXME: Use another subclass of BisonCSSParser::SourceDataHandler and assert that
// no comments are encountered (will not need m_document and m_styleSheetContents).
StyleSheetHandler handler(commentText, m_document, m_styleSheetContents, &sourceData);
- RefPtr<MutableStylePropertySet> tempMutableStyle = MutableStylePropertySet::create();
- m_commentParser->parseDeclaration(tempMutableStyle.get(), commentText, &handler, m_styleSheetContents);
- Vector<CSSPropertySourceData>& commentPropertyData = sourceData.first()->styleSourceData->propertyData;
+ RefPtrWillBeRawPtr<MutableStylePropertySet> tempMutableStyle = MutableStylePropertySet::create();
+ m_commentParser.parseDeclaration(tempMutableStyle.get(), commentText, &handler, m_styleSheetContents);
+ WillBeHeapVector<CSSPropertySourceData>& commentPropertyData = sourceData.first()->styleSourceData->propertyData;
if (commentPropertyData.size() != 1)
return;
CSSPropertySourceData& propertyData = commentPropertyData.at(0);
@@ -430,6 +354,100 @@ void StyleSheetHandler::endComment(unsigned offset)
} // namespace
+class ParsedStyleSheet {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ ParsedStyleSheet(CSSStyleSheet* pageStyleSheet);
+
+ const String& text() const { ASSERT(m_hasText); return m_text; }
+ void setText(const String&);
+ bool hasText() const { return m_hasText; }
+ bool ensureSourceData();
+ bool hasSourceData() const { return m_sourceData; }
+ PassRefPtrWillBeRawPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned) const;
+ unsigned ruleCount() { return m_sourceData->size(); }
+
+private:
+ void flattenSourceData(RuleSourceDataList*);
+ void setSourceData(PassOwnPtrWillBeRawPtr<RuleSourceDataList>);
+
+ String m_text;
+ bool m_hasText;
+ OwnPtrWillBePersistent<RuleSourceDataList> m_sourceData;
+ RefPtrWillBePersistent<CSSStyleSheet> m_pageStyleSheet;
+};
+
+ParsedStyleSheet::ParsedStyleSheet(CSSStyleSheet* pageStyleSheet)
+ : m_hasText(false)
+ , m_pageStyleSheet(pageStyleSheet)
+{
+}
+
+void ParsedStyleSheet::setText(const String& text)
+{
+ m_hasText = true;
+ m_text = text;
+ setSourceData(nullptr);
+}
+
+void ParsedStyleSheet::flattenSourceData(RuleSourceDataList* dataList)
+{
+ for (size_t i = 0; i < dataList->size(); ++i) {
+ RefPtrWillBeMember<CSSRuleSourceData>& data = dataList->at(i);
+ if (data->type == CSSRuleSourceData::STYLE_RULE) {
+ m_sourceData->append(data);
+ } else if (data->type == CSSRuleSourceData::IMPORT_RULE) {
+ m_sourceData->append(data);
+ } else if (data->type == CSSRuleSourceData::MEDIA_RULE) {
+ m_sourceData->append(data);
+ flattenSourceData(&data->childRules);
+ } else if (data->type == CSSRuleSourceData::SUPPORTS_RULE) {
+ flattenSourceData(&data->childRules);
+ }
+ }
+}
+
+bool ParsedStyleSheet::ensureSourceData()
+{
+ if (hasSourceData())
+ return true;
+
+ if (!hasText())
+ return false;
+
+ RefPtrWillBeRawPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::create(strictCSSParserContext());
+ OwnPtrWillBeRawPtr<RuleSourceDataList> result = adoptPtrWillBeNoop(new RuleSourceDataList());
+ StyleSheetHandler handler(text(), m_pageStyleSheet->ownerDocument(), newStyleSheet.get(), result.get());
+ BisonCSSParser(parserContextForDocument(m_pageStyleSheet->ownerDocument())).parseSheet(newStyleSheet.get(), text(), TextPosition::minimumPosition(), &handler);
+ setSourceData(result.release());
+ return hasSourceData();
+}
+
+void ParsedStyleSheet::setSourceData(PassOwnPtrWillBeRawPtr<RuleSourceDataList> sourceData)
+{
+ if (!sourceData) {
+ m_sourceData.clear();
+ return;
+ }
+
+ m_sourceData = adoptPtrWillBeNoop(new RuleSourceDataList());
+
+ // FIXME: This is a temporary solution to retain the original flat sourceData structure
+ // containing only style rules, even though BisonCSSParser now provides the full rule source data tree.
+ // Normally, we should just assign m_sourceData = sourceData;
+ flattenSourceData(sourceData.get());
+}
+
+PassRefPtrWillBeRawPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned index) const
+{
+ if (!hasSourceData() || index >= m_sourceData->size())
+ return nullptr;
+
+ return m_sourceData->at(index);
+}
+
+namespace WebCore {
+
enum MediaListSource {
MediaListSourceLinkedSheet,
MediaListSourceInlineSheet,
@@ -440,7 +458,7 @@ enum MediaListSource {
static PassRefPtr<TypeBuilder::CSS::SourceRange> buildSourceRangeObject(const SourceRange& range, Vector<unsigned>* lineEndings)
{
if (!lineEndings)
- return 0;
+ return nullptr;
TextPosition start = TextPosition::fromOffsetAndLineEndings(range.start, *lineEndings);
TextPosition end = TextPosition::fromOffsetAndLineEndings(range.end, *lineEndings);
@@ -452,13 +470,13 @@ static PassRefPtr<TypeBuilder::CSS::SourceRange> buildSourceRangeObject(const So
return result.release();
}
-static PassRefPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet)
+static PassRefPtrWillBeRawPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet)
{
if (!styleSheet)
- return 0;
+ return nullptr;
- RefPtr<StaticCSSRuleList> list = StaticCSSRuleList::create();
- Vector<RefPtr<CSSRule> >& listRules = list->rules();
+ RefPtrWillBeRawPtr<StaticCSSRuleList> list = StaticCSSRuleList::create();
+ WillBeHeapVector<RefPtrWillBeMember<CSSRule> >& listRules = list->rules();
for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
CSSRule* item = styleSheet->item(i);
if (item->type() == CSSRule::CHARSET_RULE)
@@ -468,10 +486,10 @@ static PassRefPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet)
return list.release();
}
-static PassRefPtr<CSSRuleList> asCSSRuleList(CSSRule* rule)
+static PassRefPtrWillBeRawPtr<CSSRuleList> asCSSRuleList(CSSRule* rule)
{
if (!rule)
- return 0;
+ return nullptr;
if (rule->type() == CSSRule::MEDIA_RULE)
return toCSSMediaRule(rule)->cssRules();
@@ -482,15 +500,15 @@ static PassRefPtr<CSSRuleList> asCSSRuleList(CSSRule* rule)
if (rule->type() == CSSRule::SUPPORTS_RULE)
return toCSSSupportsRule(rule)->cssRules();
- return 0;
+ return nullptr;
}
-PassRefPtr<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
+PassRefPtr<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, PassRefPtrWillBeRawPtr<CSSStyleDeclaration> style, InspectorStyleSheetBase* parentStyleSheet)
{
return adoptRef(new InspectorStyle(styleId, style, parentStyleSheet));
}
-InspectorStyle::InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
+InspectorStyle::InspectorStyle(const InspectorCSSId& styleId, PassRefPtrWillBeRawPtr<CSSStyleDeclaration> style, InspectorStyleSheetBase* parentStyleSheet)
: m_styleId(styleId)
, m_style(style)
, m_parentStyleSheet(parentStyleSheet)
@@ -503,12 +521,9 @@ PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyle::buildObjectForStyle() con
{
RefPtr<TypeBuilder::CSS::CSSStyle> result = styleWithProperties();
if (!m_styleId.isEmpty())
- result->setStyleId(m_styleId.asProtocolValue<TypeBuilder::CSS::CSSStyleId>());
-
- result->setWidth(m_style->getPropertyValue("width"));
- result->setHeight(m_style->getPropertyValue("height"));
+ result->setStyleSheetId(m_styleId.styleSheetId());
- RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = extractSourceData();
if (sourceData)
result->setRange(buildSourceRangeObject(sourceData->ruleBodyRange, m_parentStyleSheet->lineEndings().get()));
@@ -518,10 +533,10 @@ PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyle::buildObjectForStyle() con
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> > InspectorStyle::buildArrayForComputedStyle() const
{
RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> > result = TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty>::create();
- Vector<InspectorStyleProperty> properties;
+ WillBeHeapVector<InspectorStyleProperty> properties;
populateAllProperties(properties);
- for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) {
+ for (WillBeHeapVector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) {
const CSSPropertySourceData& propertyEntry = it->sourceData;
RefPtr<TypeBuilder::CSS::CSSComputedStyleProperty> entry = TypeBuilder::CSS::CSSComputedStyleProperty::create()
.setName(propertyEntry.name)
@@ -532,118 +547,78 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> > Insp
return result.release();
}
-// This method does the following preprocessing of |propertyText| with |overwrite| == false and |index| past the last active property:
-// - If the last property (if present) has no closing ";", the ";" is prepended to the current |propertyText| value.
-// - A heuristic formatting is attempted to retain the style structure.
-//
-// The propertyText (if not empty) is checked to be a valid style declaration (containing at least one property). If not,
-// the method returns false (denoting an error).
-bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, bool overwrite, String* oldText, ExceptionState& exceptionState)
+bool InspectorStyle::verifyPropertyText(const String& propertyText, bool canOmitSemicolon)
{
- ASSERT(m_parentStyleSheet);
DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee"));
+ RefPtrWillBeRawPtr<MutableStylePropertySet> tempMutableStyle = MutableStylePropertySet::create();
+ RuleSourceDataList sourceData;
+ RefPtrWillBeRawPtr<StyleSheetContents> styleSheetContents = StyleSheetContents::create(strictCSSParserContext());
+ String declarationText = propertyText + (canOmitSemicolon ? ";" : " ") + bogusPropertyName + ": none";
+ StyleSheetHandler handler(declarationText, ownerDocument(), styleSheetContents.get(), &sourceData);
+ BisonCSSParser(parserContextForDocument(ownerDocument())).parseDeclaration(tempMutableStyle.get(), declarationText, &handler, styleSheetContents.get());
+ WillBeHeapVector<CSSPropertySourceData>& propertyData = sourceData.first()->styleSourceData->propertyData;
+ unsigned propertyCount = propertyData.size();
+
+ // At least one property + the bogus property added just above should be present.
+ if (propertyCount < 2)
+ return false;
+
+ // Check for the proper propertyText termination (the parser could at least restore to the PROPERTY_NAME state).
+ if (propertyData.at(propertyCount - 1).name != bogusPropertyName)
+ return false;
+
+ return true;
+}
+
+bool InspectorStyle::setPropertyText(unsigned index, const String& propertyText, bool overwrite, ExceptionState& exceptionState)
+{
+ ASSERT(m_parentStyleSheet);
if (!m_parentStyleSheet->ensureParsedDataReady()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The parent style sheet's data hasn't been processed.");
return false;
}
if (!propertyText.stripWhiteSpace().isEmpty()) {
- RefPtr<MutableStylePropertySet> tempMutableStyle = MutableStylePropertySet::create();
- String declarationText = propertyText + " " + bogusPropertyName + ": none";
- RuleSourceDataList sourceData;
- StyleSheetHandler handler(declarationText, ownerDocument(), m_style->parentStyleSheet()->contents(), &sourceData);
- createCSSParser(ownerDocument())->parseDeclaration(tempMutableStyle.get(), declarationText, &handler, m_style->parentStyleSheet()->contents());
- Vector<CSSPropertySourceData>& propertyData = sourceData.first()->styleSourceData->propertyData;
- unsigned propertyCount = propertyData.size();
-
- // At least one property + the bogus property added just above should be present.
- if (propertyCount < 2) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return false;
- }
-
- // Check for the proper propertyText termination (the parser could at least restore to the PROPERTY_NAME state).
- if (propertyData.at(propertyCount - 1).name != bogusPropertyName) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ if (!verifyPropertyText(propertyText, false) && !verifyPropertyText(propertyText, true)) {
+ exceptionState.throwDOMException(SyntaxError, "The property '" + propertyText + "' could not be set.");
return false;
}
}
- RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = extractSourceData();
if (!sourceData) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The property '" + propertyText + "' could not be set.");
return false;
}
String text;
bool success = styleText(&text);
if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The property '" + propertyText + "' could not be set.");
return false;
}
- Vector<InspectorStyleProperty> allProperties;
+ WillBeHeapVector<InspectorStyleProperty> allProperties;
populateAllProperties(allProperties);
InspectorStyleTextEditor editor(&allProperties, text, newLineAndWhitespaceDelimiters());
if (overwrite) {
if (index >= allProperties.size()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is greater than or equal to the maximum bound (" + String::number(allProperties.size()) + ").");
return false;
}
- *oldText = allProperties.at(index).rawText;
editor.replaceProperty(index, propertyText);
- } else
+ } else {
editor.insertProperty(index, propertyText, sourceData->ruleBodyRange.length());
-
- return applyStyleText(editor.styleText());
-}
-
-bool InspectorStyle::toggleProperty(unsigned index, bool disable, ExceptionState& exceptionState)
-{
- ASSERT(m_parentStyleSheet);
- if (!m_parentStyleSheet->ensureParsedDataReady()) {
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
- return false;
- }
-
- RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
- if (!sourceData) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return false;
- }
-
- String text;
- bool success = styleText(&text);
- if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return false;
- }
-
- Vector<InspectorStyleProperty> allProperties;
- populateAllProperties(allProperties);
- if (index >= allProperties.size()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return false;
}
- InspectorStyleProperty& property = allProperties.at(index);
- if (property.sourceData.disabled == disable)
- return true; // Idempotent operation.
-
- InspectorStyleTextEditor editor(&allProperties, text, newLineAndWhitespaceDelimiters());
- if (disable)
- editor.disableProperty(index);
- else
- editor.enableProperty(index);
-
- return applyStyleText(editor.styleText());
+ return m_parentStyleSheet->setStyleText(m_styleId, editor.styleText());
}
bool InspectorStyle::styleText(String* result) const
{
- RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = extractSourceData();
if (!sourceData)
return false;
@@ -657,17 +632,17 @@ bool InspectorStyle::styleText(String* result) const
return true;
}
-void InspectorStyle::populateAllProperties(Vector<InspectorStyleProperty>& result) const
+void InspectorStyle::populateAllProperties(WillBeHeapVector<InspectorStyleProperty>& result) const
{
HashSet<String> sourcePropertyNames;
- RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = extractSourceData();
if (sourceData) {
String styleDeclaration;
bool isStyleTextKnown = styleText(&styleDeclaration);
ASSERT_UNUSED(isStyleTextKnown, isStyleTextKnown);
- Vector<CSSPropertySourceData>& sourcePropertyData = sourceData->styleSourceData->propertyData;
- for (Vector<CSSPropertySourceData>::const_iterator it = sourcePropertyData.begin(); it != sourcePropertyData.end(); ++it) {
+ WillBeHeapVector<CSSPropertySourceData>& sourcePropertyData = sourceData->styleSourceData->propertyData;
+ for (WillBeHeapVector<CSSPropertySourceData>::const_iterator it = sourcePropertyData.begin(); it != sourcePropertyData.end(); ++it) {
InspectorStyleProperty p(*it, true);
p.setRawTextFromStyleDeclaration(styleDeclaration);
result.append(p);
@@ -688,23 +663,17 @@ PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithProperties() con
{
RefPtr<Array<TypeBuilder::CSS::CSSProperty> > propertiesObject = Array<TypeBuilder::CSS::CSSProperty>::create();
RefPtr<Array<TypeBuilder::CSS::ShorthandEntry> > shorthandEntries = Array<TypeBuilder::CSS::ShorthandEntry>::create();
- HashMap<String, RefPtr<TypeBuilder::CSS::CSSProperty> > propertyNameToPreviousActiveProperty;
HashSet<String> foundShorthands;
- String previousPriority;
- String previousStatus;
OwnPtr<Vector<unsigned> > lineEndings(m_parentStyleSheet ? m_parentStyleSheet->lineEndings() : PassOwnPtr<Vector<unsigned> >());
- RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = extractSourceData();
unsigned ruleBodyRangeStart = sourceData ? sourceData->ruleBodyRange.start : 0;
- Vector<InspectorStyleProperty> properties;
+ WillBeHeapVector<InspectorStyleProperty> properties;
populateAllProperties(properties);
- for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) {
+ for (WillBeHeapVector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) {
const CSSPropertySourceData& propertyEntry = it->sourceData;
const String& name = propertyEntry.name;
- const bool disabled = it->sourceData.disabled;
-
- TypeBuilder::CSS::CSSProperty::Status::Enum status = disabled ? TypeBuilder::CSS::CSSProperty::Status::Disabled : TypeBuilder::CSS::CSSProperty::Status::Active;
RefPtr<TypeBuilder::CSS::CSSProperty> property = TypeBuilder::CSS::CSSProperty::create()
.setName(name)
@@ -717,9 +686,8 @@ PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithProperties() con
if (it->hasRawText())
property->setText(it->rawText);
- // Default "priority" == "".
if (propertyEntry.important)
- property->setPriority("important");
+ property->setImportant(true);
if (it->hasSource) {
// The property range is relative to the style body start.
// Should be converted into an absolute range (relative to the stylesheet start)
@@ -728,66 +696,27 @@ PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithProperties() con
absolutePropertyRange.start += ruleBodyRangeStart;
absolutePropertyRange.end += ruleBodyRangeStart;
property->setRange(buildSourceRangeObject(absolutePropertyRange, lineEndings.get()));
- }
- if (!disabled) {
- if (it->hasSource) {
+ if (!propertyEntry.disabled) {
ASSERT(sourceData);
property->setImplicit(false);
-
- // Parsed property overrides any property with the same name. Non-parsed property overrides
- // previous non-parsed property with the same name (if any).
- bool shouldInactivate = false;
- CSSPropertyID propertyId = cssPropertyID(name);
- // Canonicalize property names to treat non-prefixed and vendor-prefixed property names the same (opacity vs. -webkit-opacity).
- String canonicalPropertyName = propertyId ? getPropertyNameString(propertyId) : name;
- HashMap<String, RefPtr<TypeBuilder::CSS::CSSProperty> >::iterator activeIt = propertyNameToPreviousActiveProperty.find(canonicalPropertyName);
- if (activeIt != propertyNameToPreviousActiveProperty.end()) {
- if (propertyEntry.parsedOk) {
- bool successPriority = activeIt->value->getString(TypeBuilder::CSS::CSSProperty::Priority, &previousPriority);
- bool successStatus = activeIt->value->getString(TypeBuilder::CSS::CSSProperty::Status, &previousStatus);
- if (successStatus && previousStatus != "inactive") {
- if (propertyEntry.important || !successPriority) // Priority not set == "not important".
- shouldInactivate = true;
- else if (status == TypeBuilder::CSS::CSSProperty::Status::Active) {
- // Inactivate a non-important property following the same-named important property.
- status = TypeBuilder::CSS::CSSProperty::Status::Inactive;
- }
- }
- } else {
- bool previousParsedOk;
- bool success = activeIt->value->getBoolean(TypeBuilder::CSS::CSSProperty::ParsedOk, &previousParsedOk);
- if (success && !previousParsedOk)
- shouldInactivate = true;
- }
- } else
- propertyNameToPreviousActiveProperty.set(canonicalPropertyName, property);
-
- if (shouldInactivate) {
- activeIt->value->setStatus(TypeBuilder::CSS::CSSProperty::Status::Inactive);
- propertyNameToPreviousActiveProperty.set(canonicalPropertyName, property);
- }
- } else {
- bool implicit = m_style->isPropertyImplicit(name);
- // Default "implicit" == false.
- if (implicit)
- property->setImplicit(true);
- status = TypeBuilder::CSS::CSSProperty::Status::Style;
-
- String shorthand = m_style->getPropertyShorthand(name);
- if (!shorthand.isEmpty()) {
- if (foundShorthands.add(shorthand).isNewEntry) {
- RefPtr<TypeBuilder::CSS::ShorthandEntry> entry = TypeBuilder::CSS::ShorthandEntry::create()
- .setName(shorthand)
- .setValue(shorthandValue(shorthand));
- shorthandEntries->addItem(entry);
- }
+ }
+ property->setDisabled(propertyEntry.disabled);
+ } else if (!propertyEntry.disabled) {
+ bool implicit = m_style->isPropertyImplicit(name);
+ // Default "implicit" == false.
+ if (implicit)
+ property->setImplicit(true);
+
+ String shorthand = m_style->getPropertyShorthand(name);
+ if (!shorthand.isEmpty()) {
+ if (foundShorthands.add(shorthand).isNewEntry) {
+ RefPtr<TypeBuilder::CSS::ShorthandEntry> entry = TypeBuilder::CSS::ShorthandEntry::create()
+ .setName(shorthand)
+ .setValue(shorthandValue(shorthand));
+ shorthandEntries->addItem(entry);
}
}
}
-
- // Default "status" == "style".
- if (status != TypeBuilder::CSS::CSSProperty::Status::Style)
- property->setStatus(status);
}
RefPtr<TypeBuilder::CSS::CSSStyle> result = TypeBuilder::CSS::CSSStyle::create()
@@ -796,16 +725,11 @@ PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyle::styleWithProperties() con
return result.release();
}
-PassRefPtr<CSSRuleSourceData> InspectorStyle::extractSourceData() const
+PassRefPtrWillBeRawPtr<CSSRuleSourceData> InspectorStyle::extractSourceData() const
{
if (!m_parentStyleSheet || !m_parentStyleSheet->ensureParsedDataReady())
- return 0;
- return m_parentStyleSheet->ruleSourceDataFor(m_style.get());
-}
-
-bool InspectorStyle::applyStyleText(const String& text)
-{
- return m_parentStyleSheet->setStyleText(m_style.get(), text);
+ return nullptr;
+ return m_parentStyleSheet->ruleSourceDataAt(m_styleId.ordinal());
}
String InspectorStyle::shorthandValue(const String& shorthandProperty) const
@@ -833,36 +757,6 @@ String InspectorStyle::shorthandValue(const String& shorthandProperty) const
return value;
}
-String InspectorStyle::shorthandPriority(const String& shorthandProperty) const
-{
- String priority = m_style->getPropertyPriority(shorthandProperty);
- if (priority.isEmpty()) {
- for (unsigned i = 0; i < m_style->length(); ++i) {
- String individualProperty = m_style->item(i);
- if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
- continue;
- priority = m_style->getPropertyPriority(individualProperty);
- break;
- }
- }
- return priority;
-}
-
-Vector<String> InspectorStyle::longhandProperties(const String& shorthandProperty) const
-{
- Vector<String> properties;
- HashSet<String> foundProperties;
- for (unsigned i = 0; i < m_style->length(); ++i) {
- String individualProperty = m_style->item(i);
- if (foundProperties.contains(individualProperty) || m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
- continue;
-
- foundProperties.add(individualProperty);
- properties.append(individualProperty);
- }
- return properties;
-}
-
NewLineAndWhitespace& InspectorStyle::newLineAndWhitespaceDelimiters() const
{
DEFINE_STATIC_LOCAL(String, defaultPrefix, (" "));
@@ -870,8 +764,8 @@ NewLineAndWhitespace& InspectorStyle::newLineAndWhitespaceDelimiters() const
if (m_formatAcquired)
return m_format;
- RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
- Vector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : 0;
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = extractSourceData();
+ WillBeHeapVector<CSSPropertySourceData>* sourcePropertyData = sourceData ? &(sourceData->styleSourceData->propertyData) : 0;
int propertyCount;
if (!sourcePropertyData || !(propertyCount = sourcePropertyData->size())) {
m_format.first = "\n";
@@ -930,65 +824,152 @@ NewLineAndWhitespace& InspectorStyle::newLineAndWhitespaceDelimiters() const
Document* InspectorStyle::ownerDocument() const
{
- return m_parentStyleSheet->pageStyleSheet() ? m_parentStyleSheet->pageStyleSheet()->ownerDocument() : 0;
+ return m_parentStyleSheet->ownerDocument();
}
-PassRefPtr<InspectorStyleSheet> InspectorStyleSheet::create(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener)
+InspectorStyleSheetBase::InspectorStyleSheetBase(const String& id, Listener* listener)
+ : m_id(id)
+ , m_listener(listener)
{
- return adoptRef(new InspectorStyleSheet(pageAgent, resourceAgent, id, pageStyleSheet, origin, documentURL, listener));
}
-// static
-String InspectorStyleSheet::styleSheetURL(CSSStyleSheet* pageStyleSheet)
+bool InspectorStyleSheetBase::setPropertyText(const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite, ExceptionState& exceptionState)
{
- if (pageStyleSheet && !pageStyleSheet->contents()->baseURL().isEmpty())
- return pageStyleSheet->contents()->baseURL().string();
- return emptyString();
+ RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
+ if (!inspectorStyle) {
+ exceptionState.throwDOMException(NotFoundError, "No property could be found for the given ID.");
+ return false;
+ }
+ return inspectorStyle->setPropertyText(propertyIndex, text, overwrite, exceptionState);
}
-// static
-void InspectorStyleSheet::collectFlatRules(PassRefPtr<CSSRuleList> ruleList, CSSRuleVector* result)
+bool InspectorStyleSheetBase::getStyleText(const InspectorCSSId& id, String* text)
{
- if (!ruleList)
- return;
+ RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
+ if (!inspectorStyle)
+ return false;
+ return inspectorStyle->styleText(text);
+}
- for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
- CSSRule* rule = ruleList->item(i);
+void InspectorStyleSheetBase::fireStyleSheetChanged()
+{
+ if (listener())
+ listener()->styleSheetChanged(this);
+}
- // The result->append()'ed types should be exactly the same as in ParsedStyleSheet::flattenSourceData().
- switch (rule->type()) {
- case CSSRule::STYLE_RULE:
- result->append(rule);
+PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyleSheetBase::buildObjectForStyle(CSSStyleDeclaration* style)
+{
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = nullptr;
+ if (ensureParsedDataReady())
+ sourceData = ruleSourceDataAt(styleId(style).ordinal());
+
+ InspectorCSSId id = styleId(style);
+ if (id.isEmpty()) {
+ // Any rule coming from User Agent and not from DefaultStyleSheet will not have id.
+ // See InspectorCSSAgent::buildObjectForRule for details.
+ RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(id, style, this);
+ return inspectorStyle->buildObjectForStyle();
+ }
+ RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
+ RefPtr<TypeBuilder::CSS::CSSStyle> result = inspectorStyle->buildObjectForStyle();
+
+ // Style text cannot be retrieved without stylesheet, so set cssText here.
+ if (sourceData) {
+ String sheetText;
+ bool success = getText(&sheetText);
+ if (success) {
+ const SourceRange& bodyRange = sourceData->ruleBodyRange;
+ result->setCssText(sheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start));
+ }
+ }
+
+ return result.release();
+}
+
+PassOwnPtr<Vector<unsigned> > InspectorStyleSheetBase::lineEndings()
+{
+ String text;
+ if (!getText(&text))
+ return PassOwnPtr<Vector<unsigned> >();
+ return WTF::lineEndings(text);
+}
+
+bool InspectorStyleSheetBase::lineNumberAndColumnToOffset(unsigned lineNumber, unsigned columnNumber, unsigned* offset)
+{
+ OwnPtr<Vector<unsigned> > endings = lineEndings();
+ if (lineNumber >= endings->size())
+ return false;
+ unsigned charactersInLine = lineNumber > 0 ? endings->at(lineNumber) - endings->at(lineNumber - 1) - 1 : endings->at(0);
+ if (columnNumber > charactersInLine)
+ return false;
+ TextPosition position(OrdinalNumber::fromZeroBasedInt(lineNumber), OrdinalNumber::fromZeroBasedInt(columnNumber));
+ *offset = position.toOffset(*endings).zeroBasedInt();
+ return true;
+}
+
+bool InspectorStyleSheetBase::findPropertyByRange(const SourceRange& sourceRange, InspectorCSSId* ruleId, unsigned* propertyIndex, bool* overwrite)
+{
+ if (!ensureParsedDataReady())
+ return false;
+ for (size_t i = 0; i < ruleCount(); ++i) {
+ RefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceData = ruleSourceDataAt(i);
+ RefPtrWillBeRawPtr<CSSStyleSourceData> styleSourceData = ruleSourceData->styleSourceData;
+ if (!styleSourceData)
continue;
- case CSSRule::IMPORT_RULE:
- case CSSRule::MEDIA_RULE:
- result->append(rule);
- break;
- default:
- break;
+ if (ruleSourceData->ruleBodyRange.end < sourceRange.start || sourceRange.end < ruleSourceData->ruleBodyRange.start)
+ continue;
+ WillBeHeapVector<CSSPropertySourceData>& propertyData = styleSourceData->propertyData;
+ for (size_t j = 0; j < propertyData.size(); ++j) {
+ CSSPropertySourceData& property = propertyData.at(j);
+ unsigned styleStart = ruleSourceData->ruleBodyRange.start;
+ if (sourceRange.length() && property.range.start + styleStart == sourceRange.start && property.range.end + styleStart == sourceRange.end) {
+ *ruleId = InspectorCSSId(id(), i);
+ *propertyIndex = j;
+ *overwrite = true;
+ return true;
+ }
+ if (!sourceRange.length() && styleStart <= sourceRange.start && sourceRange.start <= property.range.start + styleStart) {
+ *ruleId = InspectorCSSId(id(), i);
+ *propertyIndex = j;
+ *overwrite = false;
+ return true;
+ }
+ }
+ if (!sourceRange.length() && ruleSourceData->ruleBodyRange.start <= sourceRange.start && sourceRange.start <= ruleSourceData->ruleBodyRange.end) {
+ *ruleId = InspectorCSSId(id(), i);
+ *propertyIndex = propertyData.size();
+ *overwrite = false;
+ return true;
}
- RefPtr<CSSRuleList> childRuleList = asCSSRuleList(rule);
- if (childRuleList)
- collectFlatRules(childRuleList, result);
}
+ return false;
+}
+
+PassRefPtr<InspectorStyleSheet> InspectorStyleSheet::create(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtrWillBeRawPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener)
+{
+ return adoptRef(new InspectorStyleSheet(pageAgent, resourceAgent, id, pageStyleSheet, origin, documentURL, listener));
}
-InspectorStyleSheet::InspectorStyleSheet(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener)
- : m_pageAgent(pageAgent)
+InspectorStyleSheet::InspectorStyleSheet(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtrWillBeRawPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener)
+ : InspectorStyleSheetBase(id, listener)
+ , m_pageAgent(pageAgent)
, m_resourceAgent(resourceAgent)
- , m_id(id)
, m_pageStyleSheet(pageStyleSheet)
, m_origin(origin)
, m_documentURL(documentURL)
- , m_isRevalidating(false)
- , m_listener(listener)
{
- m_parsedStyleSheet = new ParsedStyleSheet();
+ m_parsedStyleSheet = adoptPtr(new ParsedStyleSheet(m_pageStyleSheet.get()));
}
InspectorStyleSheet::~InspectorStyleSheet()
{
- delete m_parsedStyleSheet;
+}
+
+static String styleSheetURL(CSSStyleSheet* pageStyleSheet)
+{
+ if (pageStyleSheet && !pageStyleSheet->contents()->baseURL().isEmpty())
+ return pageStyleSheet->contents()->baseURL().string();
+ return emptyString();
}
String InspectorStyleSheet::finalURL() const
@@ -997,10 +978,13 @@ String InspectorStyleSheet::finalURL() const
return url.isEmpty() ? m_documentURL : url;
}
-void InspectorStyleSheet::reparseStyleSheet(const String& text)
+bool InspectorStyleSheet::setText(const String& text, ExceptionState& exceptionState)
{
- if (m_listener)
- m_listener->willReparseStyleSheet();
+ m_parsedStyleSheet->setText(text);
+ m_flatRules.clear();
+
+ if (listener())
+ listener()->willReparseStyleSheet();
{
// Have a separate scope for clearRules() (bug 95324).
@@ -1013,22 +997,10 @@ void InspectorStyleSheet::reparseStyleSheet(const String& text)
m_pageStyleSheet->contents()->parseString(text);
}
- if (m_listener)
- m_listener->didReparseStyleSheet();
+ if (listener())
+ listener()->didReparseStyleSheet();
fireStyleSheetChanged();
- m_pageStyleSheet->ownerDocument()->styleResolverChanged(RecalcStyleImmediately, FullStyleUpdate);
-}
-
-bool InspectorStyleSheet::setText(const String& text, ExceptionState& exceptionState)
-{
- if (!checkPageStyleSheet(exceptionState))
- return false;
- if (!m_parsedStyleSheet)
- return false;
-
- m_parsedStyleSheet->setText(text);
- m_flatRules.clear();
-
+ m_pageStyleSheet->ownerDocument()->styleResolverChanged(FullStyleUpdate);
return true;
}
@@ -1036,7 +1008,7 @@ String InspectorStyleSheet::ruleSelector(const InspectorCSSId& id, ExceptionStat
{
CSSStyleRule* rule = ruleForId(id);
if (!rule) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "No rule was found for the given ID.");
return "";
}
return rule->selectorText();
@@ -1044,23 +1016,21 @@ String InspectorStyleSheet::ruleSelector(const InspectorCSSId& id, ExceptionStat
bool InspectorStyleSheet::setRuleSelector(const InspectorCSSId& id, const String& selector, ExceptionState& exceptionState)
{
- if (!checkPageStyleSheet(exceptionState))
- return false;
CSSStyleRule* rule = ruleForId(id);
if (!rule) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "No rule was found for the given ID.");
return false;
}
CSSStyleSheet* styleSheet = rule->parentStyleSheet();
if (!styleSheet || !ensureParsedDataReady()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "No stylesheet could be found in which to set the selector.");
return false;
}
rule->setSelectorText(selector);
- RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(rule->style());
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = ruleSourceDataAt(id.ordinal());
if (!sourceData) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The selector '" + selector + "' could not be set.");
return false;
}
@@ -1074,23 +1044,21 @@ bool InspectorStyleSheet::setRuleSelector(const InspectorCSSId& id, const String
static bool checkStyleRuleSelector(Document* document, const String& selector)
{
CSSSelectorList selectorList;
- createCSSParser(document)->parseSelector(selector, selectorList);
+ BisonCSSParser(parserContextForDocument(document)).parseSelector(selector, selectorList);
return selectorList.isValid();
}
CSSStyleRule* InspectorStyleSheet::addRule(const String& selector, ExceptionState& exceptionState)
{
- if (!checkPageStyleSheet(exceptionState))
- return 0;
if (!checkStyleRuleSelector(m_pageStyleSheet->ownerDocument(), selector)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The selector '" + selector + "' could not be added.");
return 0;
}
String text;
bool success = getText(&text);
if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "The selector '" + selector + "' could not be added.");
return 0;
}
StringBuilder styleSheetText;
@@ -1109,7 +1077,7 @@ CSSStyleRule* InspectorStyleSheet::addRule(const String& selector, ExceptionStat
// What we just added has to be a CSSStyleRule - we cannot handle other types of rules yet.
// If it is not a style rule, pretend we never touched the stylesheet.
m_pageStyleSheet->deleteRule(lastRuleIndex, ASSERT_NO_EXCEPTION);
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The selector '" + selector + "' could not be added.");
return 0;
}
@@ -1118,8 +1086,8 @@ CSSStyleRule* InspectorStyleSheet::addRule(const String& selector, ExceptionStat
styleSheetText.append(selector);
styleSheetText.appendLiteral(" {}");
- // Using setText() as this operation changes the style sheet rule set.
- setText(styleSheetText.toString(), ASSERT_NO_EXCEPTION);
+ m_parsedStyleSheet->setText(styleSheetText.toString());
+ m_flatRules.clear();
fireStyleSheetChanged();
@@ -1128,22 +1096,20 @@ CSSStyleRule* InspectorStyleSheet::addRule(const String& selector, ExceptionStat
bool InspectorStyleSheet::deleteRule(const InspectorCSSId& id, ExceptionState& exceptionState)
{
- if (!checkPageStyleSheet(exceptionState))
- return false;
- RefPtr<CSSStyleRule> rule = ruleForId(id);
+ RefPtrWillBeRawPtr<CSSStyleRule> rule = ruleForId(id);
if (!rule) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "No style rule could be found for the provided ID.");
return false;
}
CSSStyleSheet* styleSheet = rule->parentStyleSheet();
if (!styleSheet || !ensureParsedDataReady()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "No parent stylesheet could be found.");
return false;
}
- RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(rule->style());
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = ruleSourceDataAt(id.ordinal());
if (!sourceData) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
+ exceptionState.throwDOMException(NotFoundError, "No style rule could be found for the provided ID.");
return false;
}
@@ -1155,44 +1121,27 @@ bool InspectorStyleSheet::deleteRule(const InspectorCSSId& id, ExceptionState& e
String sheetText = m_parsedStyleSheet->text();
sheetText.remove(sourceData->ruleHeaderRange.start, sourceData->ruleBodyRange.end - sourceData->ruleHeaderRange.start + 1);
- setText(sheetText, ASSERT_NO_EXCEPTION);
+ m_parsedStyleSheet->setText(sheetText);
+ m_flatRules.clear();
fireStyleSheetChanged();
return true;
}
CSSStyleRule* InspectorStyleSheet::ruleForId(const InspectorCSSId& id) const
{
- if (!m_pageStyleSheet)
- return 0;
-
ASSERT(!id.isEmpty());
ensureFlatRules();
return InspectorCSSAgent::asCSSStyleRule(id.ordinal() >= m_flatRules.size() ? 0 : m_flatRules.at(id.ordinal()).get());
}
-bool InspectorStyleSheet::fillObjectForStyleSheet(PassRefPtr<TypeBuilder::CSS::CSSStyleSheetBody> prpResult)
-{
- CSSStyleSheet* styleSheet = pageStyleSheet();
- if (!styleSheet)
- return false;
-
- RefPtr<TypeBuilder::CSS::CSSStyleSheetBody> result = prpResult;
-
- String styleSheetText;
- bool success = getText(&styleSheetText);
- if (success)
- result->setText(styleSheetText);
- return success;
-}
-
PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObjectForStyleSheetInfo() const
{
CSSStyleSheet* styleSheet = pageStyleSheet();
if (!styleSheet)
- return 0;
+ return nullptr;
Document* document = styleSheet->ownerDocument();
- Frame* frame = document ? document->frame() : 0;
+ LocalFrame* frame = document ? document->frame() : 0;
RefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> result = TypeBuilder::CSS::CSSStyleSheetHeader::create()
.setStyleSheetId(id())
@@ -1214,7 +1163,7 @@ PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObje
return result.release();
}
-PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > InspectorStyleSheet::selectorsFromSource(const CSSRuleSourceData* sourceData, const String& sheetText) const
+PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > InspectorStyleSheet::selectorsFromSource(const CSSRuleSourceData* sourceData, const String& sheetText)
{
ScriptRegexp comment("/\\*[^]*?\\*/", TextCaseSensitive, MultilineEnabled);
RefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > result = TypeBuilder::Array<TypeBuilder::CSS::Selector>::create();
@@ -1239,9 +1188,9 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > InspectorStyleSheet:
PassRefPtr<TypeBuilder::CSS::SelectorList> InspectorStyleSheet::buildObjectForSelectorList(CSSStyleRule* rule)
{
- RefPtr<CSSRuleSourceData> sourceData;
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = nullptr;
if (ensureParsedDataReady())
- sourceData = ruleSourceDataFor(rule->style());
+ sourceData = ruleSourceDataAt(styleId(rule->style()).ordinal());
RefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > selectors;
// This intentionally does not rely on the source data to avoid catching the trailing comments (before the declaration starting '{').
@@ -1252,7 +1201,7 @@ PassRefPtr<TypeBuilder::CSS::SelectorList> InspectorStyleSheet::buildObjectForSe
else {
selectors = TypeBuilder::Array<TypeBuilder::CSS::Selector>::create();
const CSSSelectorList& selectorList = rule->styleRule()->selectorList();
- for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector))
+ for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector))
selectors->addItem(TypeBuilder::CSS::Selector::create().setValue(selector->selectorText()).release());
}
RefPtr<TypeBuilder::CSS::SelectorList> result = TypeBuilder::CSS::SelectorList::create()
@@ -1262,114 +1211,34 @@ PassRefPtr<TypeBuilder::CSS::SelectorList> InspectorStyleSheet::buildObjectForSe
return result.release();
}
+static bool canBind(TypeBuilder::CSS::StyleSheetOrigin::Enum origin)
+{
+ return origin != TypeBuilder::CSS::StyleSheetOrigin::User_agent && origin != TypeBuilder::CSS::StyleSheetOrigin::User;
+}
+
PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule, PassRefPtr<Array<TypeBuilder::CSS::CSSMedia> > mediaStack)
{
CSSStyleSheet* styleSheet = pageStyleSheet();
if (!styleSheet)
- return 0;
+ return nullptr;
RefPtr<TypeBuilder::CSS::CSSRule> result = TypeBuilder::CSS::CSSRule::create()
.setSelectorList(buildObjectForSelectorList(rule))
.setOrigin(m_origin)
.setStyle(buildObjectForStyle(rule->style()));
- String url = this->url();
- if (!url.isEmpty())
- result->setSourceURL(url);
-
- if (canBind()) {
+ if (canBind(m_origin)) {
InspectorCSSId id(ruleId(rule));
if (!id.isEmpty())
- result->setRuleId(id.asProtocolValue<TypeBuilder::CSS::CSSRuleId>());
+ result->setStyleSheetId(id.styleSheetId());
}
- RefPtr<Array<TypeBuilder::CSS::CSSMedia> > mediaArray = Array<TypeBuilder::CSS::CSSMedia>::create();
-
if (mediaStack)
result->setMedia(mediaStack);
return result.release();
}
-PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorStyleSheet::buildObjectForStyle(CSSStyleDeclaration* style)
-{
- RefPtr<CSSRuleSourceData> sourceData;
- if (ensureParsedDataReady())
- sourceData = ruleSourceDataFor(style);
-
- InspectorCSSId id = ruleOrStyleId(style);
- if (id.isEmpty()) {
- RefPtr<TypeBuilder::CSS::CSSStyle> bogusStyle = TypeBuilder::CSS::CSSStyle::create()
- .setCssProperties(Array<TypeBuilder::CSS::CSSProperty>::create())
- .setShorthandEntries(Array<TypeBuilder::CSS::ShorthandEntry>::create());
- return bogusStyle.release();
- }
- RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
- RefPtr<TypeBuilder::CSS::CSSStyle> result = inspectorStyle->buildObjectForStyle();
-
- // Style text cannot be retrieved without stylesheet, so set cssText here.
- if (sourceData) {
- String sheetText;
- bool success = getText(&sheetText);
- if (success) {
- const SourceRange& bodyRange = sourceData->ruleBodyRange;
- result->setCssText(sheetText.substring(bodyRange.start, bodyRange.end - bodyRange.start));
- }
- }
-
- return result.release();
-}
-
-bool InspectorStyleSheet::setStyleText(const InspectorCSSId& id, const String& text, String* oldText, ExceptionState& exceptionState)
-{
- RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
- if (!inspectorStyle || !inspectorStyle->cssStyle()) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return false;
- }
-
- bool success = inspectorStyle->styleText(oldText);
- if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return false;
- }
-
- success = setStyleText(inspectorStyle->cssStyle(), text);
- if (success)
- fireStyleSheetChanged();
- else
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return success;
-}
-
-bool InspectorStyleSheet::setPropertyText(const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite, String* oldText, ExceptionState& exceptionState)
-{
- RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
- if (!inspectorStyle) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return false;
- }
-
- bool success = inspectorStyle->setPropertyText(propertyIndex, text, overwrite, oldText, exceptionState);
- if (success)
- fireStyleSheetChanged();
- return success;
-}
-
-bool InspectorStyleSheet::toggleProperty(const InspectorCSSId& id, unsigned propertyIndex, bool disable, ExceptionState& exceptionState)
-{
- RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
- if (!inspectorStyle) {
- exceptionState.throwUninformativeAndGenericDOMException(NotFoundError);
- return false;
- }
-
- bool success = inspectorStyle->toggleProperty(propertyIndex, disable, exceptionState);
- if (success)
- fireStyleSheetChanged();
- return success;
-}
-
bool InspectorStyleSheet::getText(String* result) const
{
if (!ensureText())
@@ -1387,20 +1256,19 @@ CSSStyleDeclaration* InspectorStyleSheet::styleForId(const InspectorCSSId& id) c
return rule->style();
}
-void InspectorStyleSheet::fireStyleSheetChanged()
-{
- if (m_listener)
- m_listener->styleSheetChanged(this);
-}
-
PassRefPtr<TypeBuilder::CSS::SourceRange> InspectorStyleSheet::ruleHeaderSourceRange(const CSSRule* rule)
{
if (!ensureParsedDataReady())
- return 0;
+ return nullptr;
- RefPtr<CSSRuleSourceData> sourceData = m_parsedStyleSheet->ruleSourceDataAt(ruleIndexByRule(rule));
- if (!sourceData)
- return 0;
+ ensureFlatRules();
+ size_t index = m_flatRules.find(rule);
+ // FIXME(lusnikov): m_flatRules are not always aligned with the m_parsedStyleSheet rule source
+ // datas due to the CSSOM operations that add/remove rules without changing source.
+ // This is a design issue. See crbug.com/178410
+ if (index == kNotFound || index >= m_parsedStyleSheet->ruleCount())
+ return nullptr;
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = m_parsedStyleSheet->ruleSourceDataAt(static_cast<unsigned>(index));
return buildSourceRangeObject(sourceData->ruleHeaderRange, lineEndings().get());
}
@@ -1408,11 +1276,16 @@ PassRefPtr<InspectorStyle> InspectorStyleSheet::inspectorStyleForId(const Inspec
{
CSSStyleDeclaration* style = styleForId(id);
if (!style)
- return 0;
+ return nullptr;
return InspectorStyle::create(id, style, this);
}
+unsigned InspectorStyleSheet::ruleCount()
+{
+ return m_parsedStyleSheet->ruleCount();
+}
+
String InspectorStyleSheet::sourceURL() const
{
if (!m_sourceURL.isNull())
@@ -1488,7 +1361,7 @@ String InspectorStyleSheet::sourceMapURL() const
return m_pageAgent->resourceSourceMapURL(finalURL());
}
-InspectorCSSId InspectorStyleSheet::ruleOrStyleId(CSSStyleDeclaration* style) const
+InspectorCSSId InspectorStyleSheet::styleId(CSSStyleDeclaration* style) const
{
unsigned index = ruleIndexByStyle(style);
if (index != UINT_MAX)
@@ -1496,21 +1369,36 @@ InspectorCSSId InspectorStyleSheet::ruleOrStyleId(CSSStyleDeclaration* style) co
return InspectorCSSId();
}
-Document* InspectorStyleSheet::ownerDocument() const
+bool InspectorStyleSheet::findRuleBySelectorRange(const SourceRange& sourceRange, InspectorCSSId* ruleId)
{
- return m_pageStyleSheet->ownerDocument();
+ if (!ensureParsedDataReady())
+ return false;
+ for (size_t i = 0; i < ruleCount(); ++i) {
+ RefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceData = ruleSourceDataAt(i);
+ if (!ruleSourceData->styleSourceData)
+ continue;
+ if (ruleSourceData->ruleHeaderRange.start == sourceRange.start && ruleSourceData->ruleHeaderRange.end == sourceRange.end) {
+ *ruleId = InspectorCSSId(id(), i);
+ return true;
+ }
+ }
+ return false;
}
-PassRefPtr<CSSRuleSourceData> InspectorStyleSheet::ruleSourceDataFor(CSSStyleDeclaration* style) const
+const CSSRuleVector& InspectorStyleSheet::flatRules()
{
- return m_parsedStyleSheet->ruleSourceDataAt(ruleIndexByStyle(style));
+ ensureFlatRules();
+ return m_flatRules;
}
-PassOwnPtr<Vector<unsigned> > InspectorStyleSheet::lineEndings() const
+Document* InspectorStyleSheet::ownerDocument() const
{
- if (!m_parsedStyleSheet->hasText())
- return PassOwnPtr<Vector<unsigned> >();
- return WTF::lineEndings(m_parsedStyleSheet->text());
+ return m_pageStyleSheet->ownerDocument();
+}
+
+PassRefPtrWillBeRawPtr<CSSRuleSourceData> InspectorStyleSheet::ruleSourceDataAt(unsigned ruleIndex) const
+{
+ return m_parsedStyleSheet->ruleSourceDataAt(ruleIndex);
}
unsigned InspectorStyleSheet::ruleIndexByStyle(CSSStyleDeclaration* pageStyle) const
@@ -1524,31 +1412,13 @@ unsigned InspectorStyleSheet::ruleIndexByStyle(CSSStyleDeclaration* pageStyle) c
return UINT_MAX;
}
-unsigned InspectorStyleSheet::ruleIndexByRule(const CSSRule* rule) const
-{
- ensureFlatRules();
- size_t index = m_flatRules.find(rule);
- return index == kNotFound ? UINT_MAX : static_cast<unsigned>(index);
-}
-
-bool InspectorStyleSheet::checkPageStyleSheet(ExceptionState& exceptionState) const
-{
- if (!m_pageStyleSheet) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return false;
- }
- return true;
-}
-
bool InspectorStyleSheet::ensureParsedDataReady()
{
- return ensureText() && ensureSourceData();
+ return ensureText() && m_parsedStyleSheet->ensureSourceData();
}
bool InspectorStyleSheet::ensureText() const
{
- if (!m_parsedStyleSheet)
- return false;
if (m_parsedStyleSheet->hasText())
return true;
@@ -1561,20 +1431,30 @@ bool InspectorStyleSheet::ensureText() const
return success;
}
-bool InspectorStyleSheet::ensureSourceData()
+static void collectFlatRules(PassRefPtrWillBeRawPtr<CSSRuleList> ruleList, CSSRuleVector* result)
{
- if (m_parsedStyleSheet->hasSourceData())
- return true;
+ if (!ruleList)
+ return;
- if (!m_parsedStyleSheet->hasText())
- return false;
+ for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
+ CSSRule* rule = ruleList->item(i);
- RefPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::create();
- OwnPtr<RuleSourceDataList> result = adoptPtr(new RuleSourceDataList());
- StyleSheetHandler handler(m_parsedStyleSheet->text(), m_pageStyleSheet->ownerDocument(), newStyleSheet.get(), result.get());
- createCSSParser(m_pageStyleSheet->ownerDocument())->parseSheet(newStyleSheet.get(), m_parsedStyleSheet->text(), TextPosition::minimumPosition(), &handler);
- m_parsedStyleSheet->setSourceData(result.release());
- return m_parsedStyleSheet->hasSourceData();
+ // The result->append()'ed types should be exactly the same as in ParsedStyleSheet::flattenSourceData().
+ switch (rule->type()) {
+ case CSSRule::STYLE_RULE:
+ result->append(rule);
+ continue;
+ case CSSRule::IMPORT_RULE:
+ case CSSRule::MEDIA_RULE:
+ result->append(rule);
+ break;
+ default:
+ break;
+ }
+ RefPtrWillBeRawPtr<CSSRuleList> childRuleList = asCSSRuleList(rule);
+ if (childRuleList)
+ collectFlatRules(childRuleList, result);
+ }
}
void InspectorStyleSheet::ensureFlatRules() const
@@ -1584,10 +1464,12 @@ void InspectorStyleSheet::ensureFlatRules() const
collectFlatRules(asCSSRuleList(pageStyleSheet()), &m_flatRules);
}
-bool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String& text)
+bool InspectorStyleSheet::setStyleText(const InspectorCSSId& id, const String& text)
{
- if (!m_pageStyleSheet)
+ CSSStyleDeclaration* style = styleForId(id);
+ if (!style)
return false;
+
if (!ensureParsedDataReady())
return false;
@@ -1596,14 +1478,12 @@ bool InspectorStyleSheet::setStyleText(CSSStyleDeclaration* style, const String&
if (!success)
return false;
- InspectorCSSId id = ruleOrStyleId(style);
- if (id.isEmpty())
- return false;
-
TrackExceptionState exceptionState;
style->setCSSText(text, exceptionState);
- if (!exceptionState.hadException())
+ if (!exceptionState.hadException()) {
m_parsedStyleSheet->setText(patchedStyleSheetText);
+ fireStyleSheetChanged();
+ }
return !exceptionState.hadException();
}
@@ -1612,11 +1492,10 @@ bool InspectorStyleSheet::styleSheetTextWithChangedStyle(CSSStyleDeclaration* st
{
if (!style)
return false;
-
if (!ensureParsedDataReady())
return false;
- RefPtr<CSSRuleSourceData> sourceData = ruleSourceDataFor(style);
+ RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = ruleSourceDataAt(styleId(style).ordinal());
unsigned bodyStart = sourceData->ruleBodyRange.start;
unsigned bodyEnd = sourceData->ruleBodyRange.end;
ASSERT(bodyStart <= bodyEnd);
@@ -1631,25 +1510,7 @@ bool InspectorStyleSheet::styleSheetTextWithChangedStyle(CSSStyleDeclaration* st
InspectorCSSId InspectorStyleSheet::ruleId(CSSStyleRule* rule) const
{
- return ruleOrStyleId(rule->style());
-}
-
-void InspectorStyleSheet::revalidateStyle(CSSStyleDeclaration* pageStyle)
-{
- if (m_isRevalidating)
- return;
-
- m_isRevalidating = true;
- ensureFlatRules();
- for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) {
- CSSStyleRule* parsedRule = InspectorCSSAgent::asCSSStyleRule(m_flatRules.at(i).get());
- if (parsedRule && parsedRule->style() == pageStyle) {
- if (parsedRule->styleRule()->properties()->asText() != pageStyle->cssText())
- setStyleText(pageStyle, pageStyle->cssText());
- break;
- }
- }
- m_isRevalidating = false;
+ return styleId(rule->style());
}
bool InspectorStyleSheet::originalStyleSheetText(String* result) const
@@ -1665,7 +1526,7 @@ bool InspectorStyleSheet::resourceStyleSheetText(String* result) const
if (m_origin == TypeBuilder::CSS::StyleSheetOrigin::User || m_origin == TypeBuilder::CSS::StyleSheetOrigin::User_agent)
return false;
- if (!m_pageStyleSheet || !ownerDocument() || !ownerDocument()->frame())
+ if (!ownerDocument() || !ownerDocument()->frame())
return false;
bool base64Encoded;
@@ -1675,29 +1536,26 @@ bool InspectorStyleSheet::resourceStyleSheetText(String* result) const
bool InspectorStyleSheet::inlineStyleSheetText(String* result) const
{
- if (!m_pageStyleSheet)
- return false;
-
Node* ownerNode = m_pageStyleSheet->ownerNode();
- if (!ownerNode || ownerNode->nodeType() != Node::ELEMENT_NODE)
+ if (!ownerNode || !ownerNode->isElementNode())
return false;
- Element* ownerElement = toElement(ownerNode);
+ Element& ownerElement = toElement(*ownerNode);
- if (!ownerElement->hasTagName(HTMLNames::styleTag) && !ownerElement->hasTagName(SVGNames::styleTag))
+ if (!isHTMLStyleElement(ownerElement) && !isSVGStyleElement(ownerElement))
return false;
- *result = ownerElement->textContent();
+ *result = ownerElement.textContent();
return true;
}
-PassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<Element> element, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, Listener* listener)
+PassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(const String& id, PassRefPtrWillBeRawPtr<Element> element, Listener* listener)
{
- return adoptRef(new InspectorStyleSheetForInlineStyle(pageAgent, resourceAgent, id, element, origin, listener));
+ return adoptRef(new InspectorStyleSheetForInlineStyle(id, element, listener));
}
-InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<Element> element, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, Listener* listener)
- : InspectorStyleSheet(pageAgent, resourceAgent, id, 0, origin, "", listener)
+InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(const String& id, PassRefPtrWillBeRawPtr<Element> element, Listener* listener)
+ : InspectorStyleSheetBase(id, listener)
, m_element(element)
- , m_ruleSourceData(0)
+ , m_ruleSourceData(nullptr)
, m_isStyleTextValid(false)
{
ASSERT(m_element);
@@ -1713,6 +1571,16 @@ void InspectorStyleSheetForInlineStyle::didModifyElementAttribute()
m_ruleSourceData.clear();
}
+bool InspectorStyleSheetForInlineStyle::setText(const String& text, ExceptionState& exceptionState)
+{
+ bool success = setStyleText(InspectorCSSId(id(), 0), text);
+ if (!success)
+ exceptionState.throwDOMException(SyntaxError, "Style sheet text is invalid.");
+ else
+ fireStyleSheetChanged();
+ return success;
+}
+
bool InspectorStyleSheetForInlineStyle::getText(String* result) const
{
if (!m_isStyleTextValid) {
@@ -1723,8 +1591,11 @@ bool InspectorStyleSheetForInlineStyle::getText(String* result) const
return true;
}
-bool InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style, const String& text)
+bool InspectorStyleSheetForInlineStyle::setStyleText(const InspectorCSSId& id, const String& text)
{
+ CSSStyleDeclaration* style = styleForId(id);
+ if (!style)
+ return false;
ASSERT_UNUSED(style, style == inlineStyle());
TrackExceptionState exceptionState;
@@ -1732,18 +1603,15 @@ bool InspectorStyleSheetForInlineStyle::setStyleText(CSSStyleDeclaration* style,
InspectorCSSAgent::InlineStyleOverrideScope overrideScope(m_element->ownerDocument());
m_element->setAttribute("style", AtomicString(text), exceptionState);
}
-
- m_styleText = text;
- m_isStyleTextValid = true;
- m_ruleSourceData.clear();
+ if (!exceptionState.hadException()) {
+ m_styleText = text;
+ m_isStyleTextValid = true;
+ m_ruleSourceData.clear();
+ fireStyleSheetChanged();
+ }
return !exceptionState.hadException();
}
-PassOwnPtr<Vector<unsigned> > InspectorStyleSheetForInlineStyle::lineEndings() const
-{
- return WTF::lineEndings(elementStyleText());
-}
-
Document* InspectorStyleSheetForInlineStyle::ownerDocument() const
{
return &m_element->document();
@@ -1789,22 +1657,22 @@ const String& InspectorStyleSheetForInlineStyle::elementStyleText() const
return m_element->getAttribute("style").string();
}
-PassRefPtr<CSSRuleSourceData> InspectorStyleSheetForInlineStyle::getStyleAttributeData() const
+PassRefPtrWillBeRawPtr<CSSRuleSourceData> InspectorStyleSheetForInlineStyle::getStyleAttributeData() const
{
if (!m_element->isStyledElement())
- return 0;
+ return nullptr;
if (m_styleText.isEmpty()) {
- RefPtr<CSSRuleSourceData> result = CSSRuleSourceData::create(CSSRuleSourceData::STYLE_RULE);
+ RefPtrWillBeRawPtr<CSSRuleSourceData> result = CSSRuleSourceData::create(CSSRuleSourceData::STYLE_RULE);
result->ruleBodyRange.start = 0;
result->ruleBodyRange.end = 0;
return result.release();
}
- RefPtr<MutableStylePropertySet> tempDeclaration = MutableStylePropertySet::create();
+ RefPtrWillBeRawPtr<MutableStylePropertySet> tempDeclaration = MutableStylePropertySet::create();
RuleSourceDataList ruleSourceDataResult;
- StyleSheetHandler handler(m_styleText, &m_element->document(), m_element->document().elementSheet()->contents(), &ruleSourceDataResult);
- createCSSParser(&m_element->document())->parseDeclaration(tempDeclaration.get(), m_styleText, &handler, m_element->document().elementSheet()->contents());
+ StyleSheetHandler handler(m_styleText, &m_element->document(), m_element->document().elementSheet().contents(), &ruleSourceDataResult);
+ BisonCSSParser(parserContextForDocument(&m_element->document())).parseDeclaration(tempDeclaration.get(), m_styleText, &handler, m_element->document().elementSheet().contents());
return ruleSourceDataResult.first().release();
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h
index 56a0ccafc32..87d06af3163 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h
@@ -25,11 +25,12 @@
#ifndef InspectorStyleSheet_h
#define InspectorStyleSheet_h
-#include "InspectorTypeBuilder.h"
+#include "core/InspectorTypeBuilder.h"
#include "core/css/CSSPropertySourceData.h"
#include "core/css/CSSStyleDeclaration.h"
#include "core/inspector/InspectorStyleTextEditor.h"
#include "platform/JSONValues.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -49,9 +50,9 @@ class Element;
class ExceptionState;
class InspectorPageAgent;
class InspectorResourceAgent;
-class InspectorStyleSheet;
+class InspectorStyleSheetBase;
-typedef Vector<RefPtr<CSSRule> > CSSRuleVector;
+typedef WillBePersistentHeapVector<RefPtrWillBeMember<CSSRule> > CSSRuleVector;
typedef String ErrorString;
class InspectorCSSId {
@@ -61,16 +62,6 @@ public:
{
}
- explicit InspectorCSSId(PassRefPtr<JSONObject> value)
- {
- if (!value->getString("styleSheetId", &m_styleSheetId))
- return;
-
- RefPtr<JSONValue> ordinalValue = value->get("ordinal");
- if (!ordinalValue || !ordinalValue->asNumber(&m_ordinal))
- m_styleSheetId = "";
- }
-
InspectorCSSId(const String& styleSheetId, unsigned ordinal)
: m_styleSheetId(styleSheetId)
, m_ordinal(ordinal)
@@ -82,25 +73,14 @@ public:
const String& styleSheetId() const { return m_styleSheetId; }
unsigned ordinal() const { return m_ordinal; }
- // ID type is either TypeBuilder::CSS::CSSStyleId or TypeBuilder::CSS::CSSRuleId.
- template<typename ID>
- PassRefPtr<ID> asProtocolValue() const
- {
- if (isEmpty())
- return 0;
-
- RefPtr<ID> result = ID::create()
- .setStyleSheetId(m_styleSheetId)
- .setOrdinal(m_ordinal);
- return result.release();
- }
-
private:
String m_styleSheetId;
unsigned m_ordinal;
};
struct InspectorStyleProperty {
+ ALLOW_ONLY_INLINE_ALLOCATION();
+public:
explicit InspectorStyleProperty(CSSPropertySourceData sourceData)
: sourceData(sourceData)
, hasSource(true)
@@ -124,6 +104,8 @@ struct InspectorStyleProperty {
bool hasRawText() const { return !rawText.isEmpty(); }
+ void trace(Visitor* visitor) { visitor->trace(sourceData); }
+
CSSPropertySourceData sourceData;
bool hasSource;
String rawText;
@@ -131,111 +113,137 @@ struct InspectorStyleProperty {
class InspectorStyle FINAL : public RefCounted<InspectorStyle> {
public:
- static PassRefPtr<InspectorStyle> create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
+ static PassRefPtr<InspectorStyle> create(const InspectorCSSId&, PassRefPtrWillBeRawPtr<CSSStyleDeclaration>, InspectorStyleSheetBase* parentStyleSheet);
CSSStyleDeclaration* cssStyle() const { return m_style.get(); }
PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForStyle() const;
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> > buildArrayForComputedStyle() const;
- bool setPropertyText(unsigned index, const String& text, bool overwrite, String* oldText, ExceptionState&);
- bool toggleProperty(unsigned index, bool disable, ExceptionState&);
+ bool setPropertyText(unsigned index, const String& text, bool overwrite, ExceptionState&);
bool styleText(String* result) const;
private:
- InspectorStyle(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet);
+ InspectorStyle(const InspectorCSSId&, PassRefPtrWillBeRawPtr<CSSStyleDeclaration>, InspectorStyleSheetBase* parentStyleSheet);
- void populateAllProperties(Vector<InspectorStyleProperty>& result) const;
+ bool verifyPropertyText(const String& propertyText, bool canOmitSemicolon);
+ void populateAllProperties(WillBeHeapVector<InspectorStyleProperty>& result) const;
PassRefPtr<TypeBuilder::CSS::CSSStyle> styleWithProperties() const;
- PassRefPtr<CSSRuleSourceData> extractSourceData() const;
+ PassRefPtrWillBeRawPtr<CSSRuleSourceData> extractSourceData() const;
bool applyStyleText(const String&);
String shorthandValue(const String& shorthandProperty) const;
- String shorthandPriority(const String& shorthandProperty) const;
- Vector<String> longhandProperties(const String& shorthandProperty) const;
NewLineAndWhitespace& newLineAndWhitespaceDelimiters() const;
inline Document* ownerDocument() const;
InspectorCSSId m_styleId;
- RefPtr<CSSStyleDeclaration> m_style;
- InspectorStyleSheet* m_parentStyleSheet;
+ RefPtrWillBePersistent<CSSStyleDeclaration> m_style;
+ InspectorStyleSheetBase* m_parentStyleSheet;
mutable std::pair<String, String> m_format;
mutable bool m_formatAcquired;
};
-class InspectorStyleSheet : public RefCounted<InspectorStyleSheet> {
+class InspectorStyleSheetBase : public RefCounted<InspectorStyleSheetBase> {
public:
class Listener {
public:
Listener() { }
virtual ~Listener() { }
- virtual void styleSheetChanged(InspectorStyleSheet*) = 0;
+ virtual void styleSheetChanged(InspectorStyleSheetBase*) = 0;
virtual void willReparseStyleSheet() = 0;
virtual void didReparseStyleSheet() = 0;
};
+ virtual ~InspectorStyleSheetBase() { }
+
+ String id() const { return m_id; }
+
+ virtual Document* ownerDocument() const = 0;
+ virtual bool setText(const String&, ExceptionState&) = 0;
+ virtual bool getText(String* result) const = 0;
+ bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite, ExceptionState&);
- typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle> > InspectorStyleMap;
- static PassRefPtr<InspectorStyleSheet> create(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
- static String styleSheetURL(CSSStyleSheet* pageStyleSheet);
- static void collectFlatRules(PassRefPtr<CSSRuleList>, CSSRuleVector* result);
+ virtual bool setStyleText(const InspectorCSSId&, const String&) = 0;
+ bool getStyleText(const InspectorCSSId&, String*);
+
+ virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const = 0;
+ virtual InspectorCSSId styleId(CSSStyleDeclaration*) const = 0;
+
+ PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForStyle(CSSStyleDeclaration*);
+ bool findPropertyByRange(const SourceRange&, InspectorCSSId*, unsigned* propertyIndex, bool* overwrite);
+ bool lineNumberAndColumnToOffset(unsigned lineNumber, unsigned columnNumber, unsigned* offset);
+
+protected:
+ InspectorStyleSheetBase(const String& id, Listener*);
+
+ Listener* listener() const { return m_listener; }
+ void fireStyleSheetChanged();
+ PassOwnPtr<Vector<unsigned> > lineEndings();
+
+ virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&) = 0;
+ virtual unsigned ruleCount() = 0;
+
+ // Also accessed by friend class InspectorStyle.
+ virtual PassRefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceDataAt(unsigned) const = 0;
+ virtual bool ensureParsedDataReady() = 0;
+
+private:
+ friend class InspectorStyle;
+
+ String m_id;
+ Listener* m_listener;
+};
+
+class InspectorStyleSheet : public InspectorStyleSheetBase {
+public:
+ static PassRefPtr<InspectorStyleSheet> create(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtrWillBeRawPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
virtual ~InspectorStyleSheet();
- String id() const { return m_id; }
String finalURL() const;
- virtual Document* ownerDocument() const;
- bool canBind() const { return m_origin != TypeBuilder::CSS::StyleSheetOrigin::User_agent && m_origin != TypeBuilder::CSS::StyleSheetOrigin::User; }
- CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); }
- void reparseStyleSheet(const String&);
- bool setText(const String&, ExceptionState&);
+ virtual Document* ownerDocument() const OVERRIDE;
+ virtual bool setText(const String&, ExceptionState&) OVERRIDE;
+ virtual bool getText(String* result) const OVERRIDE;
String ruleSelector(const InspectorCSSId&, ExceptionState&);
bool setRuleSelector(const InspectorCSSId&, const String& selector, ExceptionState&);
CSSStyleRule* addRule(const String& selector, ExceptionState&);
bool deleteRule(const InspectorCSSId&, ExceptionState&);
- CSSStyleRule* ruleForId(const InspectorCSSId&) const;
- bool fillObjectForStyleSheet(PassRefPtr<TypeBuilder::CSS::CSSStyleSheetBody>);
+
+ CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); }
+
PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> buildObjectForStyleSheetInfo() const;
PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*, PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> >);
- PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForStyle(CSSStyleDeclaration*);
- bool setStyleText(const InspectorCSSId&, const String& text, String* oldText, ExceptionState&);
- bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite, String* oldPropertyText, ExceptionState&);
- bool toggleProperty(const InspectorCSSId&, unsigned propertyIndex, bool disable, ExceptionState&);
- virtual TypeBuilder::CSS::StyleSheetOrigin::Enum origin() const { return m_origin; }
- virtual bool getText(String* result) const;
- virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
- void fireStyleSheetChanged();
PassRefPtr<TypeBuilder::CSS::SourceRange> ruleHeaderSourceRange(const CSSRule*);
InspectorCSSId ruleId(CSSStyleRule*) const;
- InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); }
+ CSSStyleRule* ruleForId(const InspectorCSSId&) const;
-protected:
- InspectorStyleSheet(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
+ virtual InspectorCSSId styleId(CSSStyleDeclaration*) const OVERRIDE;
+ virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const OVERRIDE;
+ virtual bool setStyleText(const InspectorCSSId&, const String&) OVERRIDE;
- InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const;
- virtual PassRefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration*) const;
- virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const;
- virtual unsigned ruleIndexByRule(const CSSRule*) const;
- virtual bool ensureParsedDataReady();
- virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
- virtual String sourceMapURL() const;
- virtual String sourceURL() const;
+ bool findRuleBySelectorRange(const SourceRange&, InspectorCSSId*);
+
+ const CSSRuleVector& flatRules();
+
+protected:
+ virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&) OVERRIDE;
+ virtual unsigned ruleCount() OVERRIDE;
// Also accessed by friend class InspectorStyle.
- virtual bool setStyleText(CSSStyleDeclaration*, const String&);
- virtual PassOwnPtr<Vector<unsigned> > lineEndings() const;
+ virtual PassRefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceDataAt(unsigned) const OVERRIDE;
+ virtual bool ensureParsedDataReady() OVERRIDE;
private:
- friend class InspectorStyle;
+ InspectorStyleSheet(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtrWillBeRawPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
- bool checkPageStyleSheet(ExceptionState&) const;
+ unsigned ruleIndexByStyle(CSSStyleDeclaration*) const;
+ String sourceMapURL() const;
+ String sourceURL() const;
bool ensureText() const;
- bool ensureSourceData();
void ensureFlatRules() const;
bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result);
- void revalidateStyle(CSSStyleDeclaration*);
bool originalStyleSheetText(String* result) const;
bool resourceStyleSheetText(String* result) const;
bool inlineStyleSheetText(String* result) const;
- PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > selectorsFromSource(const CSSRuleSourceData*, const String&) const;
+ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::Selector> > selectorsFromSource(const CSSRuleSourceData*, const String&);
PassRefPtr<TypeBuilder::CSS::SelectorList> buildObjectForSelectorList(CSSStyleRule*);
String url() const;
bool hasSourceURL() const;
@@ -243,48 +251,43 @@ private:
InspectorPageAgent* m_pageAgent;
InspectorResourceAgent* m_resourceAgent;
- String m_id;
- RefPtr<CSSStyleSheet> m_pageStyleSheet;
+ RefPtrWillBePersistent<CSSStyleSheet> m_pageStyleSheet;
TypeBuilder::CSS::StyleSheetOrigin::Enum m_origin;
String m_documentURL;
- bool m_isRevalidating;
- ParsedStyleSheet* m_parsedStyleSheet;
+ OwnPtr<ParsedStyleSheet> m_parsedStyleSheet;
mutable CSSRuleVector m_flatRules;
- Listener* m_listener;
mutable String m_sourceURL;
};
-class InspectorStyleSheetForInlineStyle : public InspectorStyleSheet {
+class InspectorStyleSheetForInlineStyle FINAL : public InspectorStyleSheetBase {
public:
- static PassRefPtr<InspectorStyleSheetForInlineStyle> create(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<Element>, TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*);
+ static PassRefPtr<InspectorStyleSheetForInlineStyle> create(const String& id, PassRefPtrWillBeRawPtr<Element>, Listener*);
void didModifyElementAttribute();
- virtual bool getText(String* result) const;
- virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
- virtual TypeBuilder::CSS::StyleSheetOrigin::Enum origin() const { return TypeBuilder::CSS::StyleSheetOrigin::Regular; }
+ virtual Document* ownerDocument() const OVERRIDE;
+ virtual bool setText(const String&, ExceptionState&) OVERRIDE;
+ virtual bool getText(String* result) const OVERRIDE;
-protected:
- InspectorStyleSheetForInlineStyle(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<Element>, TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*);
+ virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const OVERRIDE { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
+ virtual InspectorCSSId styleId(CSSStyleDeclaration* style) const OVERRIDE { return InspectorCSSId(id(), 0); }
+ virtual bool setStyleText(const InspectorCSSId&, const String&) OVERRIDE;
- virtual Document* ownerDocument() const;
- virtual PassRefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
- virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const { return 0; }
- virtual bool ensureParsedDataReady();
- virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&);
- virtual String sourceMapURL() const OVERRIDE { return String(); }
- virtual String sourceURL() const OVERRIDE { return String(); }
+protected:
+ virtual PassRefPtr<InspectorStyle> inspectorStyleForId(const InspectorCSSId&) OVERRIDE;
+ virtual unsigned ruleCount() OVERRIDE { return 1; }
// Also accessed by friend class InspectorStyle.
- virtual bool setStyleText(CSSStyleDeclaration*, const String&);
- virtual PassOwnPtr<Vector<unsigned> > lineEndings() const;
+ virtual bool ensureParsedDataReady() OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<CSSRuleSourceData> ruleSourceDataAt(unsigned ruleIndex) const OVERRIDE { ASSERT_UNUSED(ruleIndex, !ruleIndex); return m_ruleSourceData; }
private:
+ InspectorStyleSheetForInlineStyle(const String& id, PassRefPtrWillBeRawPtr<Element>, Listener*);
CSSStyleDeclaration* inlineStyle() const;
const String& elementStyleText() const;
- PassRefPtr<CSSRuleSourceData> getStyleAttributeData() const;
+ PassRefPtrWillBeRawPtr<CSSRuleSourceData> getStyleAttributeData() const;
- RefPtr<Element> m_element;
- RefPtr<CSSRuleSourceData> m_ruleSourceData;
+ RefPtrWillBePersistent<Element> m_element;
+ RefPtrWillBePersistent<CSSRuleSourceData> m_ruleSourceData;
RefPtr<InspectorStyle> m_inspectorStyle;
// Contains "style" attribute value.
@@ -295,4 +298,6 @@ private:
} // namespace WebCore
+WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(WebCore::InspectorStyleProperty);
+
#endif // !defined(InspectorStyleSheet_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.cpp
index 1c538ea1245..3bb615b8b7e 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.cpp
@@ -31,7 +31,7 @@
namespace WebCore {
-InspectorStyleTextEditor::InspectorStyleTextEditor(Vector<InspectorStyleProperty>* allProperties, const String& styleText, const NewLineAndWhitespace& format)
+InspectorStyleTextEditor::InspectorStyleTextEditor(WillBeHeapVector<InspectorStyleProperty>* allProperties, const String& styleText, const NewLineAndWhitespace& format)
: m_allProperties(allProperties)
, m_styleText(styleText)
, m_format(format)
@@ -93,11 +93,11 @@ void InspectorStyleTextEditor::insertProperty(unsigned index, const String& prop
textToSet.insert(formatLineFeed, formattingPrependOffset);
}
if (!isHTMLLineBreak(m_styleText[propertyStart]))
- textToSet.append(formatLineFeed);
+ textToSet = textToSet + formatLineFeed;
} else {
String fullPrefix = formatLineFeed + formatPropertyPrefix;
long fullPrefixLength = fullPrefix.length();
- textToSet.append(fullPrefix);
+ textToSet = textToSet + fullPrefix;
if (insertFirstInSource && (propertyStart < fullPrefixLength || m_styleText.substring(propertyStart - fullPrefixLength, fullPrefixLength) != fullPrefix))
textToSet.insert(fullPrefix, formattingPrependOffset);
}
@@ -110,29 +110,6 @@ void InspectorStyleTextEditor::replaceProperty(unsigned index, const String& new
internalReplaceProperty(m_allProperties->at(index), newText);
}
-void InspectorStyleTextEditor::removeProperty(unsigned index)
-{
- replaceProperty(index, "");
-}
-
-void InspectorStyleTextEditor::enableProperty(unsigned index)
-{
- InspectorStyleProperty& disabledProperty = m_allProperties->at(index);
- ASSERT(disabledProperty.sourceData.disabled);
- internalReplaceProperty(disabledProperty, disabledProperty.rawText.substring(2, disabledProperty.rawText.length() - 4).stripWhiteSpace());
-}
-
-void InspectorStyleTextEditor::disableProperty(unsigned index)
-{
- ASSERT(!m_allProperties->at(index).sourceData.disabled);
-
- InspectorStyleProperty& property = m_allProperties->at(index);
- property.setRawTextFromStyleDeclaration(m_styleText);
- property.sourceData.disabled = true;
-
- internalReplaceProperty(property, "/* " + property.rawText + " */");
-}
-
void InspectorStyleTextEditor::internalReplaceProperty(const InspectorStyleProperty& property, const String& newText)
{
const SourceRange& range = property.sourceData.range;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.h
index f5ac0ec1713..d4760e13e02 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorStyleTextEditor.h
@@ -25,6 +25,7 @@
#ifndef InspectorStyleTextEditor_h
#define InspectorStyleTextEditor_h
+#include "platform/heap/Handle.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
@@ -37,19 +38,17 @@ struct SourceRange;
typedef std::pair<String, String> NewLineAndWhitespace;
class InspectorStyleTextEditor {
+ STACK_ALLOCATED();
public:
- InspectorStyleTextEditor(Vector<InspectorStyleProperty>* allProperties,const String& styleText, const NewLineAndWhitespace& format);
+ InspectorStyleTextEditor(WillBeHeapVector<InspectorStyleProperty>* allProperties, const String& styleText, const NewLineAndWhitespace& format);
void insertProperty(unsigned index, const String& propertyText, unsigned styleBodyLength);
void replaceProperty(unsigned index, const String& newText);
- void removeProperty(unsigned index);
- void enableProperty(unsigned index);
- void disableProperty(unsigned index);
const String& styleText() const { return m_styleText; }
private:
void internalReplaceProperty(const InspectorStyleProperty&, const String& newText);
- Vector<InspectorStyleProperty>* m_allProperties;
+ WillBeHeapVector<InspectorStyleProperty>* m_allProperties;
String m_styleText;
const std::pair<String, String> m_format;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.cpp
index 2e73ed1e3c3..6c4330824a3 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.cpp
@@ -32,15 +32,17 @@
#include "core/inspector/InspectorTimelineAgent.h"
#include "core/events/Event.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/IdentifiersFactory.h"
#include "core/inspector/InspectorClient.h"
#include "core/inspector/InspectorCounters.h"
-#include "core/inspector/InspectorDOMAgent.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/inspector/InspectorMemoryAgent.h"
+#include "core/inspector/InspectorLayerTreeAgent.h"
+#include "core/inspector/InspectorNodeIds.h"
#include "core/inspector/InspectorOverlay.h"
#include "core/inspector/InspectorPageAgent.h"
#include "core/inspector/InspectorState.h"
@@ -49,7 +51,7 @@
#include "core/inspector/TimelineRecordFactory.h"
#include "core/inspector/TraceEventDispatcher.h"
#include "core/loader/DocumentLoader.h"
-#include "core/page/PageConsole.h"
+#include "core/page/Page.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderView.h"
#include "core/xml/XMLHttpRequest.h"
@@ -57,8 +59,8 @@
#include "platform/graphics/DeferredImageDecoder.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/network/ResourceRequest.h"
-
#include "wtf/CurrentTime.h"
+#include "wtf/DateMath.h"
namespace WebCore {
@@ -67,9 +69,10 @@ static const char enabled[] = "enabled";
static const char started[] = "started";
static const char startedFromProtocol[] = "startedFromProtocol";
static const char timelineMaxCallStackDepth[] = "timelineMaxCallStackDepth";
-static const char includeDomCounters[] = "includeDomCounters";
+static const char includeCounters[] = "includeCounters";
static const char includeGPUEvents[] = "includeGPUEvents";
static const char bufferEvents[] = "bufferEvents";
+static const char liveEvents[] = "liveEvents";
}
// Must be kept in sync with WebInspector.TimelineModel.RecordType in TimelineModel.js
@@ -81,7 +84,7 @@ static const char ScheduleStyleRecalculation[] = "ScheduleStyleRecalculation";
static const char RecalculateStyles[] = "RecalculateStyles";
static const char InvalidateLayout[] = "InvalidateLayout";
static const char Layout[] = "Layout";
-static const char AutosizeText[] = "AutosizeText";
+static const char UpdateLayerTree[] = "UpdateLayerTree";
static const char Paint[] = "Paint";
static const char ScrollLayer[] = "ScrollLayer";
static const char ResizeImage[] = "ResizeImage";
@@ -100,10 +103,8 @@ static const char MarkDOMContent[] = "MarkDOMContent";
static const char MarkFirstPaint[] = "MarkFirstPaint";
static const char TimeStamp[] = "TimeStamp";
-static const char Time[] = "Time";
-static const char TimeEnd[] = "TimeEnd";
+static const char ConsoleTime[] = "ConsoleTime";
-static const char ScheduleResourceRequest[] = "ScheduleResourceRequest";
static const char ResourceSendRequest[] = "ResourceSendRequest";
static const char ResourceReceiveResponse[] = "ResourceReceiveResponse";
static const char ResourceReceivedData[] = "ResourceReceivedData";
@@ -115,6 +116,8 @@ static const char XHRLoad[] = "XHRLoad";
static const char FunctionCall[] = "FunctionCall";
static const char GCEvent[] = "GCEvent";
+static const char UpdateCounters[] = "UpdateCounters";
+
static const char RequestAnimationFrame[] = "RequestAnimationFrame";
static const char CancelAnimationFrame[] = "CancelAnimationFrame";
static const char FireAnimationFrame[] = "FireAnimationFrame";
@@ -124,51 +127,62 @@ static const char WebSocketSendHandshakeRequest[] = "WebSocketSendHandshakeReque
static const char WebSocketReceiveHandshakeResponse[] = "WebSocketReceiveHandshakeResponse";
static const char WebSocketDestroy[] = "WebSocketDestroy";
-// Event names visible to other modules.
-const char ActivateLayerTree[] = "ActivateLayerTree";
-const char BeginFrame[] = "BeginFrame";
-const char DecodeImage[] = "DecodeImage";
-const char GPUTask[] = "GPUTask";
-const char Rasterize[] = "Rasterize";
-const char PaintSetup[] = "PaintSetup";
-}
+static const char RequestMainThreadFrame[] = "RequestMainThreadFrame";
+static const char ActivateLayerTree[] = "ActivateLayerTree";
+static const char DrawFrame[] = "DrawFrame";
+static const char BeginFrame[] = "BeginFrame";
+static const char DecodeImage[] = "DecodeImage";
+static const char GPUTask[] = "GPUTask";
+static const char Rasterize[] = "Rasterize";
+static const char PaintSetup[] = "PaintSetup";
-namespace {
-const char BackendNodeIdGroup[] = "timeline";
+static const char EmbedderCallback[] = "EmbedderCallback";
}
+using TypeBuilder::Timeline::TimelineEvent;
+
struct TimelineRecordEntry {
- TimelineRecordEntry(PassRefPtr<JSONObject> record, PassRefPtr<JSONObject> data, PassRefPtr<JSONArray> children, const String& type, size_t usedHeapSizeAtStart)
- : record(record), data(data), children(children), type(type), usedHeapSizeAtStart(usedHeapSizeAtStart)
+ TimelineRecordEntry(PassRefPtr<TimelineEvent> record, PassRefPtr<JSONObject> data, PassRefPtr<TypeBuilder::Array<TimelineEvent> > children, const String& type)
+ : record(record)
+ , data(data)
+ , children(children)
+ , type(type)
+ , skipWhenUnbalanced(false)
{
}
- RefPtr<JSONObject> record;
+ RefPtr<TimelineEvent> record;
RefPtr<JSONObject> data;
- RefPtr<JSONArray> children;
+ RefPtr<TypeBuilder::Array<TimelineEvent> > children;
String type;
- size_t usedHeapSizeAtStart;
+ bool skipWhenUnbalanced;
};
class TimelineRecordStack {
private:
struct Entry {
- Entry(PassRefPtr<JSONObject> record)
+ Entry(PassRefPtr<TimelineEvent> record, const String& type)
: record(record)
- , children(JSONArray::create())
+ , children(TypeBuilder::Array<TimelineEvent>::create())
+#ifndef NDEBUG
+ , type(type)
+#endif
{
}
- RefPtr<JSONObject> record;
- RefPtr<JSONArray> children;
+ RefPtr<TimelineEvent> record;
+ RefPtr<TypeBuilder::Array<TimelineEvent> > children;
+#ifndef NDEBUG
+ String type;
+#endif
};
public:
TimelineRecordStack() : m_timelineAgent(0) { }
TimelineRecordStack(InspectorTimelineAgent*);
- void addScopedRecord(PassRefPtr<JSONObject> record);
+ void addScopedRecord(PassRefPtr<TimelineEvent> record, const String& type);
void closeScopedRecord(double endTime);
- void addInstantRecord(PassRefPtr<JSONObject> record);
+ void addInstantRecord(PassRefPtr<TimelineEvent> record);
#ifndef NDEBUG
bool isOpenRecordOfType(const String& type);
@@ -196,16 +210,6 @@ struct TimelineThreadState {
unsigned long long decodedPixelRefId;
};
-struct TimelineGCEvent {
- TimelineGCEvent(double startTime, double endTime, size_t collectedBytes)
- : startTime(startTime), endTime(endTime), collectedBytes(collectedBytes)
- {
- }
- double startTime;
- double endTime;
- size_t collectedBytes;
-};
-
struct TimelineImageInfo {
int backendNodeId;
String url;
@@ -214,15 +218,15 @@ struct TimelineImageInfo {
TimelineImageInfo(int backendNodeId, String url) : backendNodeId(backendNodeId), url(url) { }
};
-static Frame* frameForExecutionContext(ExecutionContext* context)
+static LocalFrame* frameForExecutionContext(ExecutionContext* context)
{
- Frame* frame = 0;
+ LocalFrame* frame = 0;
if (context->isDocument())
frame = toDocument(context)->frame();
return frame;
}
-static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window, Node* node, const EventPath& eventPath)
+static bool eventHasListeners(const AtomicString& eventType, LocalDOMWindow* window, Node* node, const EventPath& eventPath)
{
if (window && window->hasEventListeners(eventType))
return true;
@@ -238,29 +242,19 @@ static bool eventHasListeners(const AtomicString& eventType, DOMWindow* window,
return false;
}
-void TimelineTimeConverter::reset()
-{
- m_startOffset = monotonicallyIncreasingTime() - currentTime();
-}
-
-void InspectorTimelineAgent::pushGCEventRecords()
-{
- if (!m_gcEvents.size())
- return;
-
- GCEvents events = m_gcEvents;
- m_gcEvents.clear();
- for (GCEvents::iterator i = events.begin(); i != events.end(); ++i) {
- RefPtr<JSONObject> record = TimelineRecordFactory::createGenericRecord(m_timeConverter.fromMonotonicallyIncreasingTime(i->startTime), m_maxCallStackDepth, TimelineRecordType::GCEvent);
- record->setObject("data", TimelineRecordFactory::createGCEventData(i->collectedBytes));
- record->setNumber("endTime", m_timeConverter.fromMonotonicallyIncreasingTime(i->endTime));
- addRecordToTimeline(record.release());
- }
-}
-
void InspectorTimelineAgent::didGC(double startTime, double endTime, size_t collectedBytesCount)
{
- m_gcEvents.append(TimelineGCEvent(startTime, endTime, collectedBytesCount));
+ RefPtr<TimelineEvent> record = TimelineRecordFactory::createGenericRecord(
+ startTime * msPerSecond,
+ 0,
+ TimelineRecordType::GCEvent,
+ TimelineRecordFactory::createGCEventData(collectedBytesCount));
+ record->setEndTime(endTime * msPerSecond);
+ double time = timestamp();
+ addRecordToTimeline(record.release(), time);
+ if (m_state->getBoolean(TimelineAgentState::includeCounters)) {
+ addRecordToTimeline(createCountersUpdate(), time);
+ }
}
InspectorTimelineAgent::~InspectorTimelineAgent()
@@ -275,10 +269,9 @@ void InspectorTimelineAgent::setFrontend(InspectorFrontend* frontend)
void InspectorTimelineAgent::clearFrontend()
{
ErrorString error;
- RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> > events;
+ RefPtr<TypeBuilder::Array<TimelineEvent> > events;
stop(&error, events);
disable(&error);
- releaseNodeIds();
m_frontend = 0;
}
@@ -286,7 +279,9 @@ void InspectorTimelineAgent::restore()
{
if (m_state->getBoolean(TimelineAgentState::startedFromProtocol)) {
if (m_state->getBoolean(TimelineAgentState::bufferEvents))
- m_bufferedEvents = TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent>::create();
+ m_bufferedEvents = TypeBuilder::Array<TimelineEvent>::create();
+
+ setLiveEvents(m_state->getString(TimelineAgentState::liveEvents));
innerStart();
} else if (isStarted()) {
// Timeline was started from console.timeline, it is not restored.
@@ -307,7 +302,7 @@ void InspectorTimelineAgent::disable(ErrorString*)
m_state->setBoolean(TimelineAgentState::enabled, false);
}
-void InspectorTimelineAgent::start(ErrorString* errorString, const int* maxCallStackDepth, const bool* bufferEvents, const bool* includeDomCounters, const bool* includeGPUEvents)
+void InspectorTimelineAgent::start(ErrorString* errorString, const int* maxCallStackDepth, const bool* bufferEvents, const String* liveEvents, const bool* includeCounters, const bool* includeGPUEvents)
{
if (!m_frontend)
return;
@@ -318,19 +313,24 @@ void InspectorTimelineAgent::start(ErrorString* errorString, const int* maxCallS
return;
}
- releaseNodeIds();
if (maxCallStackDepth && *maxCallStackDepth >= 0)
m_maxCallStackDepth = *maxCallStackDepth;
else
m_maxCallStackDepth = 5;
- if (bufferEvents && *bufferEvents)
- m_bufferedEvents = TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent>::create();
+ if (bufferEvents && *bufferEvents) {
+ m_bufferedEvents = TypeBuilder::Array<TimelineEvent>::create();
+ m_lastProgressTimestamp = timestamp();
+ }
+
+ if (liveEvents)
+ setLiveEvents(*liveEvents);
m_state->setLong(TimelineAgentState::timelineMaxCallStackDepth, m_maxCallStackDepth);
- m_state->setBoolean(TimelineAgentState::includeDomCounters, includeDomCounters && *includeDomCounters);
+ m_state->setBoolean(TimelineAgentState::includeCounters, includeCounters && *includeCounters);
m_state->setBoolean(TimelineAgentState::includeGPUEvents, includeGPUEvents && *includeGPUEvents);
m_state->setBoolean(TimelineAgentState::bufferEvents, bufferEvents && *bufferEvents);
+ m_state->setString(TimelineAgentState::liveEvents, liveEvents ? *liveEvents : "");
innerStart();
bool fromConsole = false;
@@ -347,7 +347,6 @@ void InspectorTimelineAgent::innerStart()
if (m_overlay)
m_overlay->startedRecordingProfile();
m_state->setBoolean(TimelineAgentState::started, true);
- m_timeConverter.reset();
m_instrumentingAgents->setInspectorTimelineAgent(this);
ScriptGCEvent::addEventListener(this);
if (m_client) {
@@ -358,13 +357,17 @@ void InspectorTimelineAgent::innerStart()
dispatcher->addListener(InstrumentationEvents::RasterTask, TRACE_EVENT_PHASE_BEGIN, this, &InspectorTimelineAgent::onRasterTaskBegin, m_client);
dispatcher->addListener(InstrumentationEvents::RasterTask, TRACE_EVENT_PHASE_END, this, &InspectorTimelineAgent::onRasterTaskEnd, m_client);
dispatcher->addListener(InstrumentationEvents::Layer, TRACE_EVENT_PHASE_DELETE_OBJECT, this, &InspectorTimelineAgent::onLayerDeleted, m_client);
+ dispatcher->addListener(InstrumentationEvents::RequestMainThreadFrame, TRACE_EVENT_PHASE_INSTANT, this, &InspectorTimelineAgent::onRequestMainThreadFrame, m_client);
dispatcher->addListener(InstrumentationEvents::ActivateLayerTree, TRACE_EVENT_PHASE_INSTANT, this, &InspectorTimelineAgent::onActivateLayerTree, m_client);
+ dispatcher->addListener(InstrumentationEvents::DrawFrame, TRACE_EVENT_PHASE_INSTANT, this, &InspectorTimelineAgent::onDrawFrame, m_client);
dispatcher->addListener(PlatformInstrumentation::ImageDecodeEvent, TRACE_EVENT_PHASE_BEGIN, this, &InspectorTimelineAgent::onImageDecodeBegin, m_client);
dispatcher->addListener(PlatformInstrumentation::ImageDecodeEvent, TRACE_EVENT_PHASE_END, this, &InspectorTimelineAgent::onImageDecodeEnd, m_client);
dispatcher->addListener(PlatformInstrumentation::DrawLazyPixelRefEvent, TRACE_EVENT_PHASE_INSTANT, this, &InspectorTimelineAgent::onDrawLazyPixelRef, m_client);
dispatcher->addListener(PlatformInstrumentation::DecodeLazyPixelRefEvent, TRACE_EVENT_PHASE_BEGIN, this, &InspectorTimelineAgent::onDecodeLazyPixelRefBegin, m_client);
dispatcher->addListener(PlatformInstrumentation::DecodeLazyPixelRefEvent, TRACE_EVENT_PHASE_END, this, &InspectorTimelineAgent::onDecodeLazyPixelRefEnd, m_client);
dispatcher->addListener(PlatformInstrumentation::LazyPixelRef, TRACE_EVENT_PHASE_DELETE_OBJECT, this, &InspectorTimelineAgent::onLazyPixelRefDeleted, m_client);
+ dispatcher->addListener(InstrumentationEvents::EmbedderCallback, TRACE_EVENT_PHASE_BEGIN, this, &InspectorTimelineAgent::onEmbedderCallbackBegin, m_client);
+ dispatcher->addListener(InstrumentationEvents::EmbedderCallback, TRACE_EVENT_PHASE_END, this, &InspectorTimelineAgent::onEmbedderCallbackEnd, m_client);
if (m_state->getBoolean(TimelineAgentState::includeGPUEvents)) {
m_pendingGPURecord.clear();
@@ -373,10 +376,11 @@ void InspectorTimelineAgent::innerStart()
}
}
-void InspectorTimelineAgent::stop(ErrorString* errorString, RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> >& events)
+void InspectorTimelineAgent::stop(ErrorString* errorString, RefPtr<TypeBuilder::Array<TimelineEvent> >& events)
{
m_state->setBoolean(TimelineAgentState::startedFromProtocol, false);
m_state->setBoolean(TimelineAgentState::bufferEvents, false);
+ m_state->setString(TimelineAgentState::liveEvents, "");
if (!isStarted()) {
*errorString = "Timeline was not started";
@@ -385,6 +389,7 @@ void InspectorTimelineAgent::stop(ErrorString* errorString, RefPtr<TypeBuilder::
innerStop(false);
if (m_bufferedEvents)
events = m_bufferedEvents.release();
+ m_liveEvents.clear();
}
void InspectorTimelineAgent::innerStop(bool fromConsole)
@@ -401,7 +406,6 @@ void InspectorTimelineAgent::innerStop(bool fromConsole)
clearRecordStack();
m_threadStates.clear();
- m_gcEvents.clear();
m_gpuTask.clear();
m_layerToNodeMap.clear();
m_pixelRefToImageInfo.clear();
@@ -411,7 +415,7 @@ void InspectorTimelineAgent::innerStop(bool fromConsole)
for (size_t i = 0; i < m_consoleTimelines.size(); ++i) {
String message = String::format("Timeline '%s' terminated.", m_consoleTimelines[i].utf8().data());
- page()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message);
+ mainFrame()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message);
}
m_consoleTimelines.clear();
@@ -423,8 +427,7 @@ void InspectorTimelineAgent::innerStop(bool fromConsole)
void InspectorTimelineAgent::didBeginFrame(int frameId)
{
TraceEventDispatcher::instance()->processBackgroundEvents();
- m_pendingFrameRecord = TimelineRecordFactory::createGenericRecord(timestamp(), 0, TimelineRecordType::BeginFrame);
- m_pendingFrameRecord->setObject("data", TimelineRecordFactory::createFrameData(frameId));
+ m_pendingFrameRecord = TimelineRecordFactory::createGenericRecord(timestamp(), 0, TimelineRecordType::BeginFrame, TimelineRecordFactory::createFrameData(frameId));
}
void InspectorTimelineAgent::didCancelFrame()
@@ -432,9 +435,9 @@ void InspectorTimelineAgent::didCancelFrame()
m_pendingFrameRecord.clear();
}
-bool InspectorTimelineAgent::willCallFunction(ExecutionContext* context, const String& scriptName, int scriptLine)
+bool InspectorTimelineAgent::willCallFunction(ExecutionContext* context, int scriptId, const String& scriptName, int scriptLine)
{
- pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptName, scriptLine), TimelineRecordType::FunctionCall, true, frameForExecutionContext(context));
+ pushCurrentRecord(TimelineRecordFactory::createFunctionCallData(scriptId, scriptName, scriptLine), TimelineRecordType::FunctionCall, true, frameForExecutionContext(context));
return true;
}
@@ -443,16 +446,16 @@ void InspectorTimelineAgent::didCallFunction()
didCompleteCurrentRecord(TimelineRecordType::FunctionCall);
}
-bool InspectorTimelineAgent::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath)
+bool InspectorTimelineAgent::willDispatchEvent(Document* document, const Event& event, LocalDOMWindow* window, Node* node, const EventPath& eventPath)
{
if (!eventHasListeners(event.type(), window, node, eventPath))
- return false;
+ return false;
pushCurrentRecord(TimelineRecordFactory::createEventDispatchData(event), TimelineRecordType::EventDispatch, false, document->frame());
return true;
}
-bool InspectorTimelineAgent::willDispatchEventOnWindow(const Event& event, DOMWindow* window)
+bool InspectorTimelineAgent::willDispatchEventOnWindow(const Event& event, LocalDOMWindow* window)
{
if (!window->hasEventListeners(event.type()))
return false;
@@ -470,27 +473,19 @@ void InspectorTimelineAgent::didDispatchEventOnWindow()
didDispatchEvent();
}
-void InspectorTimelineAgent::didInvalidateLayout(Frame* frame)
+void InspectorTimelineAgent::didInvalidateLayout(LocalFrame* frame)
{
appendRecord(JSONObject::create(), TimelineRecordType::InvalidateLayout, true, frame);
}
-bool InspectorTimelineAgent::willLayout(Frame* frame)
+bool InspectorTimelineAgent::willLayout(LocalFrame* frame)
{
- RenderObject* root = frame->view()->layoutRoot();
- bool partialLayout = !!root;
-
- if (!partialLayout)
- root = frame->contentRenderer();
+ bool isPartial;
+ unsigned needsLayoutObjects;
+ unsigned totalObjects;
+ frame->countObjectsNeedingLayout(needsLayoutObjects, totalObjects, isPartial);
- unsigned dirtyObjects = 0;
- unsigned totalObjects = 0;
- for (RenderObject* o = root; o; o = o->nextInPreOrder(root)) {
- ++totalObjects;
- if (o->needsLayout())
- ++dirtyObjects;
- }
- pushCurrentRecord(TimelineRecordFactory::createLayoutData(dirtyObjects, totalObjects, partialLayout), TimelineRecordType::Layout, true, frame);
+ pushCurrentRecord(TimelineRecordFactory::createLayoutData(needsLayoutObjects, totalObjects, isPartial), TimelineRecordType::Layout, true, frame);
return true;
}
@@ -503,25 +498,32 @@ void InspectorTimelineAgent::didLayout(RenderObject* root)
Vector<FloatQuad> quads;
root->absoluteQuads(quads);
if (quads.size() >= 1)
- TimelineRecordFactory::appendLayoutRoot(entry.data.get(), quads[0], nodeId(root));
+ TimelineRecordFactory::setLayoutRoot(entry.data.get(), quads[0], nodeId(root));
else
ASSERT_NOT_REACHED();
didCompleteCurrentRecord(TimelineRecordType::Layout);
}
-void InspectorTimelineAgent::willAutosizeText(RenderObject* renderer)
+void InspectorTimelineAgent::layerTreeDidChange()
{
- pushCurrentRecord(TimelineRecordFactory::createNodeData(nodeId(renderer)), TimelineRecordType::AutosizeText, false, renderer->frame());
+ ASSERT(!m_pendingLayerTreeData);
+ m_pendingLayerTreeData = m_layerTreeAgent->buildLayerTree();
}
-void InspectorTimelineAgent::didAutosizeText(RenderObject* renderer)
+void InspectorTimelineAgent::willUpdateLayerTree()
{
- if (renderer->needsLayout()) {
- TimelineRecordEntry& entry = m_recordStack.last();
- ASSERT(entry.type == TimelineRecordType::AutosizeText);
- entry.data->setBoolean("needsRelayout", true);
- }
- didCompleteCurrentRecord(TimelineRecordType::AutosizeText);
+ pushCurrentRecord(JSONObject::create(), TimelineRecordType::UpdateLayerTree, false, 0);
+}
+
+void InspectorTimelineAgent::didUpdateLayerTree()
+{
+ if (m_recordStack.isEmpty())
+ return;
+ TimelineRecordEntry& entry = m_recordStack.last();
+ ASSERT(entry.type == TimelineRecordType::UpdateLayerTree);
+ if (m_pendingLayerTreeData)
+ TimelineRecordFactory::setLayerTreeData(entry.data.get(), m_pendingLayerTreeData.release());
+ didCompleteCurrentRecord(TimelineRecordType::UpdateLayerTree);
}
void InspectorTimelineAgent::didScheduleStyleRecalculation(Document* document)
@@ -532,29 +534,22 @@ void InspectorTimelineAgent::didScheduleStyleRecalculation(Document* document)
bool InspectorTimelineAgent::willRecalculateStyle(Document* document)
{
pushCurrentRecord(JSONObject::create(), TimelineRecordType::RecalculateStyles, true, document->frame());
- ASSERT(!m_styleRecalcElementCounter);
return true;
}
-void InspectorTimelineAgent::didRecalculateStyle()
+void InspectorTimelineAgent::didRecalculateStyle(int elementCount)
{
if (m_recordStack.isEmpty())
return;
TimelineRecordEntry& entry = m_recordStack.last();
ASSERT(entry.type == TimelineRecordType::RecalculateStyles);
- TimelineRecordFactory::appendStyleRecalcDetails(entry.data.get(), m_styleRecalcElementCounter);
- m_styleRecalcElementCounter = 0;
+ TimelineRecordFactory::setStyleRecalcDetails(entry.data.get(), elementCount);
didCompleteCurrentRecord(TimelineRecordType::RecalculateStyles);
}
-void InspectorTimelineAgent::didRecalculateStyleForElement()
-{
- ++m_styleRecalcElementCounter;
-}
-
void InspectorTimelineAgent::willPaint(RenderObject* renderer, const GraphicsLayer* graphicsLayer)
{
- Frame* frame = renderer->frame();
+ LocalFrame* frame = renderer->frame();
TraceEventDispatcher::instance()->processBackgroundEvents();
double paintSetupStart = m_paintSetupStart;
@@ -565,10 +560,9 @@ void InspectorTimelineAgent::willPaint(RenderObject* renderer, const GraphicsLay
ASSERT(layerIdentifier && nodeIdentifier);
m_layerToNodeMap.set(layerIdentifier, nodeIdentifier);
if (paintSetupStart) {
- RefPtr<JSONObject> paintSetupRecord = TimelineRecordFactory::createGenericRecord(paintSetupStart, 0, TimelineRecordType::PaintSetup);
- paintSetupRecord->setNumber("endTime", m_paintSetupEnd);
- paintSetupRecord->setObject("data", TimelineRecordFactory::createLayerData(nodeIdentifier));
- addRecordToTimeline(paintSetupRecord);
+ RefPtr<TimelineEvent> paintSetupRecord = TimelineRecordFactory::createGenericRecord(paintSetupStart, 0, TimelineRecordType::PaintSetup, TimelineRecordFactory::createLayerData(nodeIdentifier));
+ paintSetupRecord->setEndTime(m_paintSetupEnd);
+ addRecordToTimeline(paintSetupRecord, paintSetupStart);
}
}
pushCurrentRecord(JSONObject::create(), TimelineRecordType::Paint, true, frame, true);
@@ -581,7 +575,7 @@ void InspectorTimelineAgent::didPaint(RenderObject* renderer, const GraphicsLaye
FloatQuad quad;
localToPageQuad(*renderer, clipRect, &quad);
int graphicsLayerId = graphicsLayer ? graphicsLayer->platformLayer()->id() : 0;
- entry.data = TimelineRecordFactory::createPaintData(quad, nodeId(renderer), graphicsLayerId);
+ TimelineRecordFactory::setPaintData(entry.data.get(), quad, nodeId(renderer), graphicsLayerId);
didCompleteCurrentRecord(TimelineRecordType::Paint);
if (m_mayEmitFirstPaint && !graphicsLayer) {
m_mayEmitFirstPaint = false;
@@ -659,7 +653,7 @@ bool InspectorTimelineAgent::willWriteHTML(Document* document, unsigned startLin
void InspectorTimelineAgent::didWriteHTML(unsigned endLine)
{
if (!m_recordStack.isEmpty()) {
- TimelineRecordEntry entry = m_recordStack.last();
+ TimelineRecordEntry& entry = m_recordStack.last();
entry.data->setNumber("endLine", endLine);
didCompleteCurrentRecord(TimelineRecordType::ParseHTML);
}
@@ -712,7 +706,7 @@ void InspectorTimelineAgent::didDispatchXHRLoadEvent()
didCompleteCurrentRecord(TimelineRecordType::XHRLoad);
}
-bool InspectorTimelineAgent::willEvaluateScript(Frame* frame, const String& url, int lineNumber)
+bool InspectorTimelineAgent::willEvaluateScript(LocalFrame* frame, const String& url, int lineNumber)
{
pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript, true, frame);
return true;
@@ -723,53 +717,37 @@ void InspectorTimelineAgent::didEvaluateScript()
didCompleteCurrentRecord(TimelineRecordType::EvaluateScript);
}
-void InspectorTimelineAgent::didScheduleResourceRequest(Document* document, const String& url)
-{
- appendRecord(TimelineRecordFactory::createScheduleResourceRequestData(url), TimelineRecordType::ScheduleResourceRequest, true, document->frame());
-}
-
void InspectorTimelineAgent::willSendRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse&, const FetchInitiatorInfo&)
{
String requestId = IdentifiersFactory::requestId(identifier);
appendRecord(TimelineRecordFactory::createResourceSendRequestData(requestId, request), TimelineRecordType::ResourceSendRequest, true, loader->frame());
}
-bool InspectorTimelineAgent::willReceiveResourceData(Frame* frame, unsigned long identifier, int length)
+void InspectorTimelineAgent::didReceiveData(LocalFrame* frame, unsigned long identifier, const char*, int, int encodedDataLength)
{
String requestId = IdentifiersFactory::requestId(identifier);
- pushCurrentRecord(TimelineRecordFactory::createReceiveResourceData(requestId, length), TimelineRecordType::ResourceReceivedData, false, frame);
- return true;
-}
-
-void InspectorTimelineAgent::didReceiveResourceData()
-{
- didCompleteCurrentRecord(TimelineRecordType::ResourceReceivedData);
+ appendRecord(TimelineRecordFactory::createReceiveResourceData(requestId, encodedDataLength), TimelineRecordType::ResourceReceivedData, false, frame);
}
-void InspectorTimelineAgent::didReceiveResourceResponse(Frame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
+void InspectorTimelineAgent::didReceiveResourceResponse(LocalFrame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
{
String requestId = IdentifiersFactory::requestId(identifier);
- appendRecord(TimelineRecordFactory::createResourceReceiveResponseData(requestId, response), TimelineRecordType::ResourceReceiveResponse, false, frame);
+ appendRecord(TimelineRecordFactory::createResourceReceiveResponseData(requestId, response), TimelineRecordType::ResourceReceiveResponse, false, 0);
}
-void InspectorTimelineAgent::didFinishLoadingResource(unsigned long identifier, bool didFail, double finishTime, Frame* frame)
+void InspectorTimelineAgent::didFinishLoadingResource(unsigned long identifier, bool didFail, double finishTime)
{
- appendRecord(TimelineRecordFactory::createResourceFinishData(IdentifiersFactory::requestId(identifier), didFail, finishTime * 1000), TimelineRecordType::ResourceFinish, false, frame);
+ appendRecord(TimelineRecordFactory::createResourceFinishData(IdentifiersFactory::requestId(identifier), didFail, finishTime), TimelineRecordType::ResourceFinish, false, 0);
}
-void InspectorTimelineAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, double monotonicFinishTime)
+void InspectorTimelineAgent::didFinishLoading(unsigned long identifier, DocumentLoader* loader, double monotonicFinishTime, int64_t)
{
- double finishTime = 0.0;
- // FIXME: Expose all of the timing details to inspector and have it calculate finishTime.
- if (monotonicFinishTime)
- finishTime = loader->timing()->monotonicTimeToPseudoWallTime(monotonicFinishTime);
-
- didFinishLoadingResource(identifier, false, finishTime, loader->frame());
+ didFinishLoadingResource(identifier, false, monotonicFinishTime * msPerSecond);
}
-void InspectorTimelineAgent::didFailLoading(unsigned long identifier, DocumentLoader* loader, const ResourceError& error)
+void InspectorTimelineAgent::didFailLoading(unsigned long identifier, const ResourceError& error)
{
- didFinishLoadingResource(identifier, true, 0, loader->frame());
+ didFinishLoadingResource(identifier, true, 0);
}
void InspectorTimelineAgent::consoleTimeStamp(ExecutionContext* context, const String& title)
@@ -779,21 +757,28 @@ void InspectorTimelineAgent::consoleTimeStamp(ExecutionContext* context, const S
void InspectorTimelineAgent::consoleTime(ExecutionContext* context, const String& message)
{
- appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::Time, true, frameForExecutionContext(context));
+ pushCurrentRecord(TimelineRecordFactory::createConsoleTimeData(message), TimelineRecordType::ConsoleTime, false, frameForExecutionContext(context));
+ m_recordStack.last().skipWhenUnbalanced = true;
}
void InspectorTimelineAgent::consoleTimeEnd(ExecutionContext* context, const String& message, ScriptState*)
{
- appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeEnd, true, frameForExecutionContext(context));
+ if (m_recordStack.last().type != TimelineRecordType::ConsoleTime)
+ return;
+ String originalMessage;
+ if (m_recordStack.last().data->getString("message", &originalMessage) && message != originalMessage)
+ return;
+ // Only complete console.time that is balanced.
+ didCompleteCurrentRecord(TimelineRecordType::ConsoleTime);
}
-void InspectorTimelineAgent::consoleTimeline(ExecutionContext* context, const String& title, ScriptState* state)
+void InspectorTimelineAgent::consoleTimeline(ExecutionContext* context, const String& title, ScriptState* scriptState)
{
if (!m_state->getBoolean(TimelineAgentState::enabled))
return;
String message = String::format("Timeline '%s' started.", title.utf8().data());
- page()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, 0, state);
+ mainFrame()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, nullptr, scriptState);
m_consoleTimelines.append(title);
if (!isStarted()) {
innerStart();
@@ -803,7 +788,7 @@ void InspectorTimelineAgent::consoleTimeline(ExecutionContext* context, const St
appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeStamp, true, frameForExecutionContext(context));
}
-void InspectorTimelineAgent::consoleTimelineEnd(ExecutionContext* context, const String& title, ScriptState* state)
+void InspectorTimelineAgent::consoleTimelineEnd(ExecutionContext* context, const String& title, ScriptState* scriptState)
{
if (!m_state->getBoolean(TimelineAgentState::enabled))
return;
@@ -811,7 +796,7 @@ void InspectorTimelineAgent::consoleTimelineEnd(ExecutionContext* context, const
size_t index = m_consoleTimelines.find(title);
if (index == kNotFound) {
String message = String::format("Timeline '%s' was not started.", title.utf8().data());
- page()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, 0, state);
+ mainFrame()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, nullptr, scriptState);
return;
}
@@ -822,10 +807,10 @@ void InspectorTimelineAgent::consoleTimelineEnd(ExecutionContext* context, const
unwindRecordStack();
innerStop(true);
}
- page()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, 0, state);
+ mainFrame()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, nullptr, scriptState);
}
-void InspectorTimelineAgent::domContentLoadedEventFired(Frame* frame)
+void InspectorTimelineAgent::domContentLoadedEventFired(LocalFrame* frame)
{
bool isMainFrame = frame && m_pageAgent && (frame == m_pageAgent->mainFrame());
appendRecord(TimelineRecordFactory::createMarkData(isMainFrame), TimelineRecordType::MarkDOMContent, false, frame);
@@ -833,7 +818,7 @@ void InspectorTimelineAgent::domContentLoadedEventFired(Frame* frame)
m_mayEmitFirstPaint = true;
}
-void InspectorTimelineAgent::loadEventFired(Frame* frame)
+void InspectorTimelineAgent::loadEventFired(LocalFrame* frame)
{
bool isMainFrame = frame && m_pageAgent && (frame == m_pageAgent->mainFrame());
appendRecord(TimelineRecordFactory::createMarkData(isMainFrame), TimelineRecordType::MarkLoad, false, frame);
@@ -880,12 +865,12 @@ void InspectorTimelineAgent::didCreateWebSocket(Document* document, unsigned lon
appendRecord(TimelineRecordFactory::createWebSocketCreateData(identifier, url, protocol), TimelineRecordType::WebSocketCreate, true, document->frame());
}
-void InspectorTimelineAgent::willSendWebSocketHandshakeRequest(Document* document, unsigned long identifier, const WebSocketHandshakeRequest&)
+void InspectorTimelineAgent::willSendWebSocketHandshakeRequest(Document* document, unsigned long identifier, const WebSocketHandshakeRequest*)
{
appendRecord(TimelineRecordFactory::createGenericWebSocketData(identifier), TimelineRecordType::WebSocketSendHandshakeRequest, true, document->frame());
}
-void InspectorTimelineAgent::didReceiveWebSocketHandshakeResponse(Document* document, unsigned long identifier, const WebSocketHandshakeResponse&)
+void InspectorTimelineAgent::didReceiveWebSocketHandshakeResponse(Document* document, unsigned long identifier, const WebSocketHandshakeRequest*, const WebSocketHandshakeResponse*)
{
appendRecord(TimelineRecordFactory::createGenericWebSocketData(identifier), TimelineRecordType::WebSocketReceiveHandshakeResponse, false, document->frame());
}
@@ -901,19 +886,19 @@ void InspectorTimelineAgent::onBeginImplSideFrame(const TraceEventDispatcher::Tr
if (layerTreeId != m_layerTreeId)
return;
TimelineThreadState& state = threadState(event.threadIdentifier());
- state.recordStack.addInstantRecord(createRecordForEvent(event, TimelineRecordType::BeginFrame));
+ state.recordStack.addInstantRecord(createRecordForEvent(event, TimelineRecordType::BeginFrame, JSONObject::create()));
}
void InspectorTimelineAgent::onPaintSetupBegin(const TraceEventDispatcher::TraceEvent& event)
{
ASSERT(!m_paintSetupStart);
- m_paintSetupStart = m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp());
+ m_paintSetupStart = event.timestamp() * msPerSecond;
}
void InspectorTimelineAgent::onPaintSetupEnd(const TraceEventDispatcher::TraceEvent& event)
{
ASSERT(m_paintSetupStart);
- m_paintSetupEnd = m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp());
+ m_paintSetupEnd = event.timestamp() * msPerSecond;
}
void InspectorTimelineAgent::onRasterTaskBegin(const TraceEventDispatcher::TraceEvent& event)
@@ -925,10 +910,10 @@ void InspectorTimelineAgent::onRasterTaskBegin(const TraceEventDispatcher::Trace
return;
ASSERT(!state.inKnownLayerTask);
state.inKnownLayerTask = true;
- double timeestamp = m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp());
+ double timestamp = event.timestamp() * msPerSecond;
RefPtr<JSONObject> data = TimelineRecordFactory::createLayerData(m_layerToNodeMap.get(layerId));
- RefPtr<JSONObject> record = TimelineRecordFactory::createBackgroundRecord(timeestamp, String::number(event.threadIdentifier()), TimelineRecordType::Rasterize, data);
- state.recordStack.addScopedRecord(record);
+ RefPtr<TimelineEvent> record = TimelineRecordFactory::createBackgroundRecord(timestamp, String::number(event.threadIdentifier()), TimelineRecordType::Rasterize, data);
+ state.recordStack.addScopedRecord(record, TimelineRecordType::Rasterize);
}
void InspectorTimelineAgent::onRasterTaskEnd(const TraceEventDispatcher::TraceEvent& event)
@@ -937,7 +922,7 @@ void InspectorTimelineAgent::onRasterTaskEnd(const TraceEventDispatcher::TraceEv
if (!state.inKnownLayerTask)
return;
ASSERT(state.recordStack.isOpenRecordOfType(TimelineRecordType::Rasterize));
- state.recordStack.closeScopedRecord(m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp()));
+ state.recordStack.closeScopedRecord(event.timestamp() * msPerSecond);
state.inKnownLayerTask = false;
}
@@ -955,9 +940,9 @@ void InspectorTimelineAgent::onImageDecodeBegin(const TraceEventDispatcher::Trac
ASSERT_NOT_REACHED();
}
RefPtr<JSONObject> data = JSONObject::create();
- TimelineRecordFactory::appendImageDetails(data.get(), imageInfo.backendNodeId, imageInfo.url);
- double timeestamp = m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp());
- state.recordStack.addScopedRecord(TimelineRecordFactory::createBackgroundRecord(timeestamp, String::number(event.threadIdentifier()), TimelineRecordType::DecodeImage, data));
+ TimelineRecordFactory::setImageDetails(data.get(), imageInfo.backendNodeId, imageInfo.url);
+ double timeestamp = event.timestamp() * msPerSecond;
+ state.recordStack.addScopedRecord(TimelineRecordFactory::createBackgroundRecord(timeestamp, String::number(event.threadIdentifier()), TimelineRecordType::DecodeImage, data), TimelineRecordType::DecodeImage);
}
void InspectorTimelineAgent::onImageDecodeEnd(const TraceEventDispatcher::TraceEvent& event)
@@ -966,7 +951,16 @@ void InspectorTimelineAgent::onImageDecodeEnd(const TraceEventDispatcher::TraceE
if (!state.decodedPixelRefId)
return;
ASSERT(state.recordStack.isOpenRecordOfType(TimelineRecordType::DecodeImage));
- state.recordStack.closeScopedRecord(m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp()));
+ state.recordStack.closeScopedRecord(event.timestamp() * msPerSecond);
+}
+
+void InspectorTimelineAgent::onRequestMainThreadFrame(const TraceEventDispatcher::TraceEvent& event)
+{
+ unsigned long long layerTreeId = event.asUInt(InstrumentationEventArguments::LayerTreeId);
+ if (layerTreeId != m_layerTreeId)
+ return;
+ TimelineThreadState& state = threadState(event.threadIdentifier());
+ state.recordStack.addInstantRecord(createRecordForEvent(event, TimelineRecordType::RequestMainThreadFrame, JSONObject::create()));
}
void InspectorTimelineAgent::onActivateLayerTree(const TraceEventDispatcher::TraceEvent& event)
@@ -979,6 +973,15 @@ void InspectorTimelineAgent::onActivateLayerTree(const TraceEventDispatcher::Tra
state.recordStack.addInstantRecord(createRecordForEvent(event, TimelineRecordType::ActivateLayerTree, TimelineRecordFactory::createFrameData(frameId)));
}
+void InspectorTimelineAgent::onDrawFrame(const TraceEventDispatcher::TraceEvent& event)
+{
+ unsigned long long layerTreeId = event.asUInt(InstrumentationEventArguments::LayerTreeId);
+ if (layerTreeId != m_layerTreeId)
+ return;
+ TimelineThreadState& state = threadState(event.threadIdentifier());
+ state.recordStack.addInstantRecord(createRecordForEvent(event, TimelineRecordType::DrawFrame, JSONObject::create()));
+}
+
void InspectorTimelineAgent::onLayerDeleted(const TraceEventDispatcher::TraceEvent& event)
{
unsigned long long id = event.id();
@@ -1020,30 +1023,56 @@ void InspectorTimelineAgent::onLazyPixelRefDeleted(const TraceEventDispatcher::T
void InspectorTimelineAgent::processGPUEvent(const GPUEvent& event)
{
- double timelineTimestamp = m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp);
+ double timelineTimestamp = event.timestamp * msPerSecond;
if (event.phase == GPUEvent::PhaseBegin) {
- m_pendingGPURecord = TimelineRecordFactory::createBackgroundRecord(timelineTimestamp, "gpu", TimelineRecordType::GPUTask, TimelineRecordFactory::createGPUTaskData(event.foreign, event.usedGPUMemoryBytes));
+ m_pendingGPURecord = TimelineRecordFactory::createBackgroundRecord(timelineTimestamp, "gpu", TimelineRecordType::GPUTask, TimelineRecordFactory::createGPUTaskData(event.foreign));
} else if (m_pendingGPURecord) {
- m_pendingGPURecord->setNumber("endTime", timelineTimestamp);
+ m_pendingGPURecord->setEndTime(timelineTimestamp);
sendEvent(m_pendingGPURecord.release());
+ if (!event.foreign && m_state->getBoolean(TimelineAgentState::includeCounters)) {
+ RefPtr<TypeBuilder::Timeline::Counters> counters = TypeBuilder::Timeline::Counters::create();
+ counters->setGpuMemoryUsedKB(static_cast<double>(event.usedGPUMemoryBytes / 1024));
+ counters->setGpuMemoryLimitKB(static_cast<double>(event.limitGPUMemoryBytes / 1024));
+ sendEvent(TimelineRecordFactory::createBackgroundRecord(timelineTimestamp, "gpu", TimelineRecordType::UpdateCounters, counters.release()->asObject()));
+ }
}
}
-void InspectorTimelineAgent::addRecordToTimeline(PassRefPtr<JSONObject> record)
+void InspectorTimelineAgent::onEmbedderCallbackBegin(const TraceEventDispatcher::TraceEvent& event)
+{
+ TimelineThreadState& state = threadState(event.threadIdentifier());
+ double timestamp = event.timestamp() * msPerSecond;
+ RefPtr<JSONObject> data = TimelineRecordFactory::createEmbedderCallbackData(event.asString(InstrumentationEventArguments::CallbackName));
+ RefPtr<TimelineEvent> record = TimelineRecordFactory::createGenericRecord(timestamp, 0, TimelineRecordType::EmbedderCallback, data);
+ state.recordStack.addScopedRecord(record, TimelineRecordType::EmbedderCallback);
+}
+
+void InspectorTimelineAgent::onEmbedderCallbackEnd(const TraceEventDispatcher::TraceEvent& event)
+{
+ TimelineThreadState& state = threadState(event.threadIdentifier());
+ state.recordStack.closeScopedRecord(event.timestamp() * msPerSecond);
+}
+
+void InspectorTimelineAgent::addRecordToTimeline(PassRefPtr<TimelineEvent> record, double ts)
{
commitFrameRecord();
innerAddRecordToTimeline(record);
+ if (m_bufferedEvents && ts - m_lastProgressTimestamp > 300) {
+ m_lastProgressTimestamp = ts;
+ m_frontend->progress(m_bufferedEvents->length());
+ }
}
-void InspectorTimelineAgent::innerAddRecordToTimeline(PassRefPtr<JSONObject> prpRecord)
+void InspectorTimelineAgent::innerAddRecordToTimeline(PassRefPtr<TimelineEvent> record)
{
- RefPtr<TypeBuilder::Timeline::TimelineEvent> record = TypeBuilder::Timeline::TimelineEvent::runtimeCast(prpRecord);
if (m_recordStack.isEmpty()) {
- sendEvent(record.release());
+ TraceEventDispatcher::instance()->processBackgroundEvents();
+ sendEvent(record);
} else {
- setDOMCounters(record.get());
- TimelineRecordEntry parent = m_recordStack.last();
- parent.children->pushObject(record.release());
+ TimelineRecordEntry& parent = m_recordStack.last();
+ parent.children->addItem(record);
+ if (m_state->getBoolean(TimelineAgentState::includeCounters))
+ parent.children->addItem(createCountersUpdate());
}
}
@@ -1054,64 +1083,58 @@ static size_t getUsedHeapSize()
return info.usedJSHeapSize;
}
-void InspectorTimelineAgent::setDOMCounters(TypeBuilder::Timeline::TimelineEvent* record)
+PassRefPtr<TypeBuilder::Timeline::TimelineEvent> InspectorTimelineAgent::createCountersUpdate()
{
- record->setUsedHeapSize(getUsedHeapSize());
-
- if (m_state->getBoolean(TimelineAgentState::includeDomCounters)) {
- int documentCount = 0;
- int nodeCount = 0;
- int listenerCount = 0;
- if (m_inspectorType == PageInspector) {
- documentCount = InspectorCounters::counterValue(InspectorCounters::DocumentCounter);
- nodeCount = InspectorCounters::counterValue(InspectorCounters::NodeCounter);
- listenerCount = InspectorCounters::counterValue(InspectorCounters::JSEventListenerCounter);
- }
- RefPtr<TypeBuilder::Timeline::DOMCounters> counters = TypeBuilder::Timeline::DOMCounters::create()
- .setDocuments(documentCount)
- .setNodes(nodeCount)
- .setJsEventListeners(listenerCount);
- record->setCounters(counters.release());
+ RefPtr<TypeBuilder::Timeline::Counters> counters = TypeBuilder::Timeline::Counters::create();
+ if (m_inspectorType == PageInspector) {
+ counters->setDocuments(InspectorCounters::counterValue(InspectorCounters::DocumentCounter));
+ counters->setNodes(InspectorCounters::counterValue(InspectorCounters::NodeCounter));
+ counters->setJsEventListeners(InspectorCounters::counterValue(InspectorCounters::JSEventListenerCounter));
}
+ counters->setJsHeapSizeUsed(static_cast<double>(getUsedHeapSize()));
+ return TimelineRecordFactory::createGenericRecord(timestamp(), 0, TimelineRecordType::UpdateCounters, counters.release()->asObject());
}
-void InspectorTimelineAgent::setFrameIdentifier(JSONObject* record, Frame* frame)
+void InspectorTimelineAgent::setFrameIdentifier(TimelineEvent* record, LocalFrame* frame)
{
if (!frame || !m_pageAgent)
return;
String frameId;
if (frame && m_pageAgent)
frameId = m_pageAgent->frameId(frame);
- record->setString("frameId", frameId);
+ record->setFrameId(frameId);
}
void InspectorTimelineAgent::populateImageDetails(JSONObject* data, const RenderImage& renderImage)
{
const ImageResource* resource = renderImage.cachedImage();
- TimelineRecordFactory::appendImageDetails(data, nodeId(renderImage.generatingNode()), resource ? resource->url().string() : "");
+ TimelineRecordFactory::setImageDetails(data, nodeId(renderImage.generatingNode()), resource ? resource->url().string() : "");
}
void InspectorTimelineAgent::didCompleteCurrentRecord(const String& type)
{
// An empty stack could merely mean that the timeline agent was turned on in the middle of
- // an event. Don't treat as an error.
+ // an event. Don't treat as an error.
if (!m_recordStack.isEmpty()) {
if (m_platformInstrumentationClientInstalledAtStackDepth == m_recordStack.size()) {
m_platformInstrumentationClientInstalledAtStackDepth = 0;
PlatformInstrumentation::setClient(0);
}
- pushGCEventRecords();
TimelineRecordEntry entry = m_recordStack.last();
m_recordStack.removeLast();
+ while (entry.type != type && entry.skipWhenUnbalanced && !m_recordStack.isEmpty()) {
+ // Discard pending skippable entry, paste its children inplace.
+ if (entry.children)
+ m_recordStack.last().children->concat(entry.children);
+ entry = m_recordStack.last();
+ m_recordStack.removeLast();
+ }
ASSERT(entry.type == type);
- entry.record->setObject("data", entry.data);
- entry.record->setArray("children", entry.children);
- entry.record->setNumber("endTime", timestamp());
- ptrdiff_t usedHeapSizeDelta = getUsedHeapSize() - entry.usedHeapSizeAtStart;
- if (usedHeapSizeDelta)
- entry.record->setNumber("usedHeapSizeDelta", usedHeapSizeDelta);
- addRecordToTimeline(entry.record);
+ entry.record->setChildren(entry.children);
+ double ts = timestamp();
+ entry.record->setEndTime(ts);
+ addRecordToTimeline(entry.record, ts);
}
}
@@ -1123,11 +1146,11 @@ void InspectorTimelineAgent::unwindRecordStack()
}
}
-InspectorTimelineAgent::InspectorTimelineAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorMemoryAgent* memoryAgent, InspectorDOMAgent* domAgent, InspectorOverlay* overlay, InspectorCompositeState* state, InspectorType type, InspectorClient* client)
- : InspectorBaseAgent<InspectorTimelineAgent>("Timeline", instrumentingAgents, state)
+InspectorTimelineAgent::InspectorTimelineAgent(InspectorPageAgent* pageAgent, InspectorLayerTreeAgent* layerTreeAgent,
+ InspectorOverlay* overlay, InspectorType type, InspectorClient* client)
+ : InspectorBaseAgent<InspectorTimelineAgent>("Timeline")
, m_pageAgent(pageAgent)
- , m_memoryAgent(memoryAgent)
- , m_domAgent(domAgent)
+ , m_layerTreeAgent(layerTreeAgent)
, m_frontend(0)
, m_client(client)
, m_overlay(overlay)
@@ -1138,38 +1161,36 @@ InspectorTimelineAgent::InspectorTimelineAgent(InstrumentingAgents* instrumentin
, m_platformInstrumentationClientInstalledAtStackDepth(0)
, m_imageBeingPainted(0)
, m_paintSetupStart(0)
- , m_styleRecalcElementCounter(0)
, m_mayEmitFirstPaint(false)
+ , m_lastProgressTimestamp(0)
{
}
-void InspectorTimelineAgent::appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame* frame)
+void InspectorTimelineAgent::appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame* frame)
{
- pushGCEventRecords();
- RefPtr<JSONObject> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0, type);
- record->setObject("data", data);
+ double ts = timestamp();
+ RefPtr<TimelineEvent> record = TimelineRecordFactory::createGenericRecord(ts, captureCallStack ? m_maxCallStackDepth : 0, type, data);
setFrameIdentifier(record.get(), frame);
- addRecordToTimeline(record.release());
+ addRecordToTimeline(record.release(), ts);
}
-void InspectorTimelineAgent::sendEvent(PassRefPtr<JSONObject> event)
+void InspectorTimelineAgent::sendEvent(PassRefPtr<TimelineEvent> record)
{
- // FIXME: runtimeCast is a hack. We do it because we can't build TimelineEvent directly now.
- RefPtr<TypeBuilder::Timeline::TimelineEvent> recordChecked = TypeBuilder::Timeline::TimelineEvent::runtimeCast(event);
+ RefPtr<TimelineEvent> retain = record;
if (m_bufferedEvents) {
- m_bufferedEvents->addItem(recordChecked.release());
- return;
+ m_bufferedEvents->addItem(retain);
+ if (!m_liveEvents.contains(TimelineRecordFactory::type(retain.get())))
+ return;
}
- m_frontend->eventRecorded(recordChecked.release());
+ m_frontend->eventRecorded(retain.release());
}
-void InspectorTimelineAgent::pushCurrentRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame* frame, bool hasLowLevelDetails)
+void InspectorTimelineAgent::pushCurrentRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame* frame, bool hasLowLevelDetails)
{
- pushGCEventRecords();
commitFrameRecord();
- RefPtr<JSONObject> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0, type);
+ RefPtr<TimelineEvent> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0, type, data.get());
setFrameIdentifier(record.get(), frame);
- m_recordStack.append(TimelineRecordEntry(record.release(), data, JSONArray::create(), type, getUsedHeapSize()));
+ m_recordStack.append(TimelineRecordEntry(record.release(), data, TypeBuilder::Array<TimelineEvent>::create(), type));
if (hasLowLevelDetails && !m_platformInstrumentationClientInstalledAtStackDepth && !PlatformInstrumentation::hasClient()) {
m_platformInstrumentationClientInstalledAtStackDepth = m_recordStack.size();
PlatformInstrumentation::setClient(this);
@@ -1181,7 +1202,7 @@ TimelineThreadState& InspectorTimelineAgent::threadState(ThreadIdentifier thread
ThreadStateMap::iterator it = m_threadStates.find(thread);
if (it != m_threadStates.end())
return it->value;
- return m_threadStates.add(thread, TimelineThreadState(this)).iterator->value;
+ return m_threadStates.add(thread, TimelineThreadState(this)).storedValue->value;
}
void InspectorTimelineAgent::commitFrameRecord()
@@ -1204,7 +1225,7 @@ void InspectorTimelineAgent::clearRecordStack()
void InspectorTimelineAgent::localToPageQuad(const RenderObject& renderer, const LayoutRect& rect, FloatQuad* quad)
{
- Frame* frame = renderer.frame();
+ LocalFrame* frame = renderer.frame();
FrameView* view = frame->view();
FloatQuad absolute = renderer.localToAbsoluteQuad(FloatQuad(rect));
quad->setP1(view->contentsToRootView(roundedIntPoint(absolute.p1())));
@@ -1215,35 +1236,41 @@ void InspectorTimelineAgent::localToPageQuad(const RenderObject& renderer, const
long long InspectorTimelineAgent::nodeId(Node* node)
{
- return m_domAgent && node ? m_domAgent->backendNodeIdForNode(node, BackendNodeIdGroup) : 0;
+ return node ? InspectorNodeIds::idForNode(node) : 0;
}
long long InspectorTimelineAgent::nodeId(RenderObject* renderer)
{
- return nodeId(renderer->generatingNode());
+ return InspectorNodeIds::idForNode(renderer->generatingNode());
}
-void InspectorTimelineAgent::releaseNodeIds()
+double InspectorTimelineAgent::timestamp()
{
- ErrorString unused;
- if (m_domAgent)
- m_domAgent->releaseBackendNodeIds(&unused, BackendNodeIdGroup);
+ return WTF::monotonicallyIncreasingTime() * msPerSecond;
}
-double InspectorTimelineAgent::timestamp()
+LocalFrame* InspectorTimelineAgent::mainFrame() const
{
- return m_timeConverter.fromMonotonicallyIncreasingTime(WTF::monotonicallyIncreasingTime());
+ if (!m_pageAgent)
+ return 0;
+ return m_pageAgent->mainFrame();
}
-Page* InspectorTimelineAgent::page()
+PassRefPtr<TimelineEvent> InspectorTimelineAgent::createRecordForEvent(const TraceEventDispatcher::TraceEvent& event, const String& type, PassRefPtr<JSONObject> data)
{
- return m_pageAgent ? m_pageAgent->page() : 0;
+ double timeestamp = event.timestamp() * msPerSecond;
+ return TimelineRecordFactory::createBackgroundRecord(timeestamp, String::number(event.threadIdentifier()), type, data);
}
-PassRefPtr<JSONObject> InspectorTimelineAgent::createRecordForEvent(const TraceEventDispatcher::TraceEvent& event, const String& type, PassRefPtr<JSONObject> data)
+void InspectorTimelineAgent::setLiveEvents(const String& liveEvents)
{
- double timeestamp = m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp());
- return TimelineRecordFactory::createBackgroundRecord(timeestamp, String::number(event.threadIdentifier()), type, data);
+ m_liveEvents.clear();
+ if (liveEvents.isNull() || liveEvents.isEmpty())
+ return;
+ Vector<String> eventList;
+ liveEvents.split(",", eventList);
+ for (Vector<String>::iterator it = eventList.begin(); it != eventList.end(); ++it)
+ m_liveEvents.add(*it);
}
TimelineRecordStack::TimelineRecordStack(InspectorTimelineAgent* timelineAgent)
@@ -1251,9 +1278,9 @@ TimelineRecordStack::TimelineRecordStack(InspectorTimelineAgent* timelineAgent)
{
}
-void TimelineRecordStack::addScopedRecord(PassRefPtr<JSONObject> record)
+void TimelineRecordStack::addScopedRecord(PassRefPtr<TimelineEvent> record, const String& type)
{
- m_stack.append(Entry(record));
+ m_stack.append(Entry(record, type));
}
void TimelineRecordStack::closeScopedRecord(double endTime)
@@ -1262,25 +1289,24 @@ void TimelineRecordStack::closeScopedRecord(double endTime)
return;
Entry last = m_stack.last();
m_stack.removeLast();
- last.record->setNumber("endTime", endTime);
+ last.record->setEndTime(endTime);
if (last.children->length())
- last.record->setArray("children", last.children);
+ last.record->setChildren(last.children);
addInstantRecord(last.record);
}
-void TimelineRecordStack::addInstantRecord(PassRefPtr<JSONObject> record)
+void TimelineRecordStack::addInstantRecord(PassRefPtr<TimelineEvent> record)
{
if (m_stack.isEmpty())
m_timelineAgent->sendEvent(record);
else
- m_stack.last().children->pushObject(record);
+ m_stack.last().children->addItem(record);
}
#ifndef NDEBUG
bool TimelineRecordStack::isOpenRecordOfType(const String& type)
{
- String lastRecordType;
- return m_stack.isEmpty() || (m_stack.last().record->getString("type", &lastRecordType) && type == lastRecordType);
+ return !m_stack.isEmpty() && m_stack.last().type == type;
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.h
index 10b1d948bfc..f74edb7937e 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorTimelineAgent.h
@@ -32,8 +32,9 @@
#define InspectorTimelineAgent_h
-#include "InspectorFrontend.h"
#include "bindings/v8/ScriptGCEvent.h"
+#include "core/InspectorFrontend.h"
+#include "core/InspectorTypeBuilder.h"
#include "core/events/EventPath.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "core/inspector/ScriptGCEventListener.h"
@@ -41,35 +42,37 @@
#include "platform/JSONValues.h"
#include "platform/PlatformInstrumentation.h"
#include "platform/geometry/LayoutRect.h"
+#include "wtf/HashMap.h"
+#include "wtf/HashSet.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/Vector.h"
#include "wtf/WeakPtr.h"
namespace WebCore {
struct FetchInitiatorInfo;
-struct TimelineGCEvent;
struct TimelineImageInfo;
struct TimelineThreadState;
struct TimelineRecordEntry;
-class DOMWindow;
+class LocalDOMWindow;
class Document;
class DocumentLoader;
class Event;
+class ExecutionContext;
class FloatQuad;
-class Frame;
+class LocalFrame;
+class FrameHost;
class GraphicsContext;
class GraphicsLayer;
class InspectorClient;
-class InspectorDOMAgent;
class InspectorFrontend;
-class InspectorMemoryAgent;
class InspectorOverlay;
class InspectorPageAgent;
+class InspectorLayerTreeAgent;
class InstrumentingAgents;
class KURL;
+class ScriptState;
class Node;
-class Page;
class RenderImage;
class RenderObject;
class ResourceError;
@@ -79,37 +82,13 @@ class ResourceResponse;
class ScriptArguments;
class ScriptCallStack;
class TimelineRecordStack;
-class ExecutionContext;
-class ScriptState;
class WebSocketHandshakeRequest;
class WebSocketHandshakeResponse;
class XMLHttpRequest;
typedef String ErrorString;
-namespace TimelineRecordType {
-extern const char ActivateLayerTree[];
-extern const char BeginFrame[];
-extern const char DecodeImage[];
-extern const char GPUTask[];
-extern const char PaintSetup[];
-extern const char Rasterize[];
-};
-
-class TimelineTimeConverter {
-public:
- TimelineTimeConverter()
- : m_startOffset(0)
- {
- }
- double fromMonotonicallyIncreasingTime(double time) const { return (time - m_startOffset) * 1000.0; }
- void reset();
-
-private:
- double m_startOffset;
-};
-
-class InspectorTimelineAgent
+class InspectorTimelineAgent FINAL
: public TraceEventTarget<InspectorTimelineAgent>
, public InspectorBaseAgent<InspectorTimelineAgent>
, public ScriptGCEventListener
@@ -122,32 +101,35 @@ public:
class GPUEvent {
public:
enum Phase { PhaseBegin, PhaseEnd };
- GPUEvent(double timestamp, int phase, bool foreign, size_t usedGPUMemoryBytes) :
+ GPUEvent(double timestamp, int phase, bool foreign, uint64_t usedGPUMemoryBytes, uint64_t limitGPUMemoryBytes) :
timestamp(timestamp),
phase(static_cast<Phase>(phase)),
foreign(foreign),
- usedGPUMemoryBytes(usedGPUMemoryBytes) { }
+ usedGPUMemoryBytes(usedGPUMemoryBytes),
+ limitGPUMemoryBytes(limitGPUMemoryBytes) { }
double timestamp;
Phase phase;
bool foreign;
- size_t usedGPUMemoryBytes;
+ uint64_t usedGPUMemoryBytes;
+ uint64_t limitGPUMemoryBytes;
};
- static PassOwnPtr<InspectorTimelineAgent> create(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorMemoryAgent* memoryAgent, InspectorDOMAgent* domAgent, InspectorOverlay* overlay, InspectorCompositeState* state, InspectorType type, InspectorClient* client)
+ static PassOwnPtr<InspectorTimelineAgent> create(InspectorPageAgent* pageAgent, InspectorLayerTreeAgent* layerTreeAgent,
+ InspectorOverlay* overlay, InspectorType type, InspectorClient* client)
{
- return adoptPtr(new InspectorTimelineAgent(instrumentingAgents, pageAgent, memoryAgent, domAgent, overlay, state, type, client));
+ return adoptPtr(new InspectorTimelineAgent(pageAgent, layerTreeAgent, overlay, type, client));
}
- ~InspectorTimelineAgent();
+ virtual ~InspectorTimelineAgent();
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
+ virtual void restore() OVERRIDE;
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void start(ErrorString*, const int* maxCallStackDepth, const bool* bufferEvents, const bool* includeDomCounters, const bool* includeGPUEvents);
- virtual void stop(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> >& events);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void start(ErrorString*, const int* maxCallStackDepth, const bool* bufferEvents, const String* liveEvents, const bool* includeCounters, const bool* includeGPUEvents) OVERRIDE;
+ virtual void stop(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> >& events) OVERRIDE;
void setLayerTreeId(int layerTreeId) { m_layerTreeId = layerTreeId; }
int id() const { return m_id; }
@@ -155,28 +137,28 @@ public:
void didCommitLoad();
// Methods called from WebCore.
- bool willCallFunction(ExecutionContext*, const String& scriptName, int scriptLine);
+ bool willCallFunction(ExecutionContext*, int scriptId, const String& scriptName, int scriptLine);
void didCallFunction();
- bool willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath);
- bool willDispatchEventOnWindow(const Event& event, DOMWindow* window);
+ bool willDispatchEvent(Document* document, const Event& event, LocalDOMWindow* window, Node* node, const EventPath& eventPath);
+ bool willDispatchEventOnWindow(const Event& event, LocalDOMWindow* window);
void didDispatchEvent();
void didDispatchEventOnWindow();
void didBeginFrame(int frameId);
void didCancelFrame();
- void didInvalidateLayout(Frame*);
- bool willLayout(Frame*);
+ void didInvalidateLayout(LocalFrame*);
+ bool willLayout(LocalFrame*);
void didLayout(RenderObject*);
- void willAutosizeText(RenderObject*);
- void didAutosizeText(RenderObject*);
+ void willUpdateLayerTree();
+ void layerTreeDidChange();
+ void didUpdateLayerTree();
void didScheduleStyleRecalculation(Document*);
bool willRecalculateStyle(Document*);
- void didRecalculateStyle();
- void didRecalculateStyleForElement();
+ void didRecalculateStyle(int elementCount);
void willPaint(RenderObject*, const GraphicsLayer*);
void didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext*, const LayoutRect&);
@@ -203,25 +185,23 @@ public:
bool willDispatchXHRLoadEvent(ExecutionContext*, XMLHttpRequest*);
void didDispatchXHRLoadEvent();
- bool willEvaluateScript(Frame*, const String&, int);
+ bool willEvaluateScript(LocalFrame*, const String&, int);
void didEvaluateScript();
void consoleTimeStamp(ExecutionContext*, const String& title);
- void domContentLoadedEventFired(Frame*);
- void loadEventFired(Frame*);
+ void domContentLoadedEventFired(LocalFrame*);
+ void loadEventFired(LocalFrame*);
void consoleTime(ExecutionContext*, const String&);
void consoleTimeEnd(ExecutionContext*, const String&, ScriptState*);
void consoleTimeline(ExecutionContext*, const String& title, ScriptState*);
void consoleTimelineEnd(ExecutionContext*, const String& title, ScriptState*);
- void didScheduleResourceRequest(Document*, const String& url);
void willSendRequest(unsigned long, DocumentLoader*, const ResourceRequest&, const ResourceResponse&, const FetchInitiatorInfo&);
- void didReceiveResourceResponse(Frame*, unsigned long, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
- void didFinishLoading(unsigned long, DocumentLoader*, double monotonicFinishTime);
- void didFailLoading(unsigned long identifier, DocumentLoader* loader, const ResourceError& error);
- bool willReceiveResourceData(Frame*, unsigned long identifier, int length);
- void didReceiveResourceData();
+ void didReceiveResourceResponse(LocalFrame*, unsigned long, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+ void didFinishLoading(unsigned long, DocumentLoader*, double monotonicFinishTime, int64_t);
+ void didFailLoading(unsigned long identifier, const ResourceError&);
+ void didReceiveData(LocalFrame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
void didRequestAnimationFrame(Document*, int callbackId);
void didCancelAnimationFrame(Document*, int callbackId);
@@ -232,14 +212,14 @@ public:
void didProcessTask();
void didCreateWebSocket(Document*, unsigned long identifier, const KURL&, const String& protocol);
- void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest&);
- void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeResponse&);
+ void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest*);
+ void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeRequest*, const WebSocketHandshakeResponse*);
void didCloseWebSocket(Document*, unsigned long identifier);
void processGPUEvent(const GPUEvent&);
// ScriptGCEventListener methods.
- virtual void didGC(double, double, size_t);
+ virtual void didGC(double, double, size_t) OVERRIDE;
// PlatformInstrumentationClient methods.
virtual void willDecodeImage(const String& imageType) OVERRIDE;
@@ -251,7 +231,7 @@ private:
friend class TimelineRecordStack;
- InspectorTimelineAgent(InstrumentingAgents*, InspectorPageAgent*, InspectorMemoryAgent*, InspectorDOMAgent*, InspectorOverlay*, InspectorCompositeState*, InspectorType, InspectorClient*);
+ InspectorTimelineAgent(InspectorPageAgent*, InspectorLayerTreeAgent*, InspectorOverlay*, InspectorType, InspectorClient*);
// Trace event handlers
void onBeginImplSideFrame(const TraceEventDispatcher::TraceEvent&);
@@ -265,47 +245,49 @@ private:
void onDrawLazyPixelRef(const TraceEventDispatcher::TraceEvent&);
void onDecodeLazyPixelRefBegin(const TraceEventDispatcher::TraceEvent&);
void onDecodeLazyPixelRefEnd(const TraceEventDispatcher::TraceEvent&);
+ void onRequestMainThreadFrame(const TraceEventDispatcher::TraceEvent&);
void onActivateLayerTree(const TraceEventDispatcher::TraceEvent&);
+ void onDrawFrame(const TraceEventDispatcher::TraceEvent&);
void onLazyPixelRefDeleted(const TraceEventDispatcher::TraceEvent&);
+ void onEmbedderCallbackBegin(const TraceEventDispatcher::TraceEvent&);
+ void onEmbedderCallbackEnd(const TraceEventDispatcher::TraceEvent&);
- void didFinishLoadingResource(unsigned long, bool didFail, double finishTime, Frame*);
+ void didFinishLoadingResource(unsigned long, bool didFail, double finishTime);
- void sendEvent(PassRefPtr<JSONObject>);
- void appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame*);
- void pushCurrentRecord(PassRefPtr<JSONObject>, const String& type, bool captureCallStack, Frame*, bool hasLowLevelDetails = false);
+ void sendEvent(PassRefPtr<TypeBuilder::Timeline::TimelineEvent>);
+ void appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame*);
+ void pushCurrentRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame*, bool hasLowLevelDetails = false);
TimelineThreadState& threadState(ThreadIdentifier);
- void setDOMCounters(TypeBuilder::Timeline::TimelineEvent*);
- void setFrameIdentifier(JSONObject* record, Frame*);
+ void setFrameIdentifier(TypeBuilder::Timeline::TimelineEvent* record, LocalFrame*);
void populateImageDetails(JSONObject* data, const RenderImage&);
- void pushGCEventRecords();
-
void didCompleteCurrentRecord(const String& type);
void unwindRecordStack();
void commitFrameRecord();
- void addRecordToTimeline(PassRefPtr<JSONObject>);
- void innerAddRecordToTimeline(PassRefPtr<JSONObject>);
+ void addRecordToTimeline(PassRefPtr<TypeBuilder::Timeline::TimelineEvent>, double ts);
+ void innerAddRecordToTimeline(PassRefPtr<TypeBuilder::Timeline::TimelineEvent>);
+ PassRefPtr<TypeBuilder::Timeline::TimelineEvent> createCountersUpdate();
void clearRecordStack();
- PassRefPtr<JSONObject> createRecordForEvent(const TraceEventDispatcher::TraceEvent&, const String& type, PassRefPtr<JSONObject> data = 0);
+ PassRefPtr<TypeBuilder::Timeline::TimelineEvent> createRecordForEvent(const TraceEventDispatcher::TraceEvent&, const String& type, PassRefPtr<JSONObject> data);
void localToPageQuad(const RenderObject& renderer, const LayoutRect&, FloatQuad*);
long long nodeId(Node*);
long long nodeId(RenderObject*);
- void releaseNodeIds();
double timestamp();
- Page* page();
+
+ LocalFrame* mainFrame() const;
bool isStarted();
void innerStart();
void innerStop(bool fromConsole);
+ void setLiveEvents(const String&);
InspectorPageAgent* m_pageAgent;
- InspectorMemoryAgent* m_memoryAgent;
- InspectorDOMAgent* m_domAgent;
+ InspectorLayerTreeAgent* m_layerTreeAgent;
InspectorFrontend::Timeline* m_frontend;
InspectorClient* m_client;
InspectorOverlay* m_overlay;
@@ -314,18 +296,15 @@ private:
int m_id;
unsigned long long m_layerTreeId;
- TimelineTimeConverter m_timeConverter;
int m_maxCallStackDepth;
Vector<TimelineRecordEntry> m_recordStack;
RefPtr<TypeBuilder::Array<TypeBuilder::Timeline::TimelineEvent> > m_bufferedEvents;
Vector<String> m_consoleTimelines;
- typedef Vector<TimelineGCEvent> GCEvents;
- GCEvents m_gcEvents;
unsigned m_platformInstrumentationClientInstalledAtStackDepth;
- RefPtr<JSONObject> m_pendingFrameRecord;
- RefPtr<JSONObject> m_pendingGPURecord;
+ RefPtr<TypeBuilder::Timeline::TimelineEvent> m_pendingFrameRecord;
+ RefPtr<TypeBuilder::Timeline::TimelineEvent> m_pendingGPURecord;
typedef HashMap<unsigned long long, TimelineImageInfo> PixelRefToImageInfoMap;
PixelRefToImageInfoMap m_pixelRefToImageInfo;
RenderImage* m_imageBeingPainted;
@@ -333,10 +312,12 @@ private:
double m_paintSetupStart;
double m_paintSetupEnd;
RefPtr<JSONObject> m_gpuTask;
- unsigned m_styleRecalcElementCounter;
+ RefPtr<JSONValue> m_pendingLayerTreeData;
typedef HashMap<ThreadIdentifier, TimelineThreadState> ThreadStateMap;
ThreadStateMap m_threadStates;
bool m_mayEmitFirstPaint;
+ HashSet<String> m_liveEvents;
+ double m_lastProgressTimestamp;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
new file mode 100644
index 00000000000..bd80f7ff573
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -0,0 +1,334 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/inspector/InspectorTraceEvents.h"
+
+#include "bindings/v8/ScriptCallStackFactory.h"
+#include "bindings/v8/ScriptGCEvent.h"
+#include "bindings/v8/ScriptSourceCode.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/inspector/IdentifiersFactory.h"
+#include "core/inspector/InspectorNodeIds.h"
+#include "core/inspector/ScriptCallStack.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderImage.h"
+#include "core/rendering/RenderObject.h"
+#include "core/xml/XMLHttpRequest.h"
+#include "platform/JSONValues.h"
+#include "platform/TracedValue.h"
+#include "platform/graphics/GraphicsLayer.h"
+#include "platform/network/ResourceRequest.h"
+#include "platform/network/ResourceResponse.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/Vector.h"
+#include <inttypes.h>
+
+namespace WebCore {
+
+namespace {
+
+class JSCallStack : public TraceEvent::ConvertableToTraceFormat {
+public:
+ explicit JSCallStack(PassRefPtrWillBeRawPtr<ScriptCallStack> callstack) : m_callstack(callstack) { }
+ virtual String asTraceFormat() const
+ {
+ if (!m_callstack)
+ return "null";
+ return m_callstack->buildInspectorArray()->toJSONString();
+ }
+
+private:
+ RefPtrWillBePersistent<ScriptCallStack> m_callstack;
+};
+
+String toHexString(void* p)
+{
+ return String::format("0x%" PRIx64, static_cast<uint64>(reinterpret_cast<intptr_t>(p)));
+}
+
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorLayoutEvent::beginData(FrameView* frameView)
+{
+ bool isPartial;
+ unsigned needsLayoutObjects;
+ unsigned totalObjects;
+ LocalFrame& frame = frameView->frame();
+ frame.countObjectsNeedingLayout(needsLayoutObjects, totalObjects, isPartial);
+
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("dirtyObjects", needsLayoutObjects);
+ data->setNumber("totalObjects", totalObjects);
+ data->setBoolean("partialLayout", isPartial);
+ data->setString("frame", toHexString(&frame));
+ return TracedValue::fromJSONValue(data);
+}
+
+static PassRefPtr<JSONArray> createQuad(const FloatQuad& quad)
+{
+ RefPtr<JSONArray> array = JSONArray::create();
+ array->pushNumber(quad.p1().x());
+ array->pushNumber(quad.p1().y());
+ array->pushNumber(quad.p2().x());
+ array->pushNumber(quad.p2().y());
+ array->pushNumber(quad.p3().x());
+ array->pushNumber(quad.p3().y());
+ array->pushNumber(quad.p4().x());
+ array->pushNumber(quad.p4().y());
+ return array.release();
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorLayoutEvent::endData(RenderObject* rootForThisLayout)
+{
+ Vector<FloatQuad> quads;
+ rootForThisLayout->absoluteQuads(quads);
+
+ RefPtr<JSONObject> data = JSONObject::create();
+ if (quads.size() >= 1) {
+ data->setArray("root", createQuad(quads[0]));
+ int rootNodeId = InspectorNodeIds::idForNode(rootForThisLayout->generatingNode());
+ data->setNumber("rootNode", rootNodeId);
+ } else {
+ ASSERT_NOT_REACHED();
+ }
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorSendRequestEvent::data(unsigned long identifier, LocalFrame* frame, const ResourceRequest& request)
+{
+ String requestId = IdentifiersFactory::requestId(identifier);
+
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("requestId", requestId);
+ data->setString("frame", toHexString(frame));
+ data->setString("url", request.url().string());
+ data->setString("requestMethod", request.httpMethod());
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorReceiveResponseEvent::data(unsigned long identifier, LocalFrame* frame, const ResourceResponse& response)
+{
+ String requestId = IdentifiersFactory::requestId(identifier);
+
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("requestId", requestId);
+ data->setString("frame", toHexString(frame));
+ data->setNumber("statusCode", response.httpStatusCode());
+ data->setString("mimeType", response.mimeType().string().isolatedCopy());
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorReceiveDataEvent::data(unsigned long identifier, LocalFrame* frame, int encodedDataLength)
+{
+ String requestId = IdentifiersFactory::requestId(identifier);
+
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("requestId", requestId);
+ data->setString("frame", toHexString(frame));
+ data->setNumber("encodedDataLength", encodedDataLength);
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorResourceFinishEvent::data(unsigned long identifier, double finishTime, bool didFail)
+{
+ String requestId = IdentifiersFactory::requestId(identifier);
+
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("requestId", requestId);
+ data->setBoolean("didFail", didFail);
+ if (finishTime)
+ data->setNumber("networkTime", finishTime);
+ return TracedValue::fromJSONValue(data);
+}
+
+static LocalFrame* frameForExecutionContext(ExecutionContext* context)
+{
+ LocalFrame* frame = 0;
+ if (context->isDocument())
+ frame = toDocument(context)->frame();
+ return frame;
+}
+
+static PassRefPtr<JSONObject> genericTimerData(ExecutionContext* context, int timerId)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("timerId", timerId);
+ if (LocalFrame* frame = frameForExecutionContext(context))
+ data->setString("frame", toHexString(frame));
+ return data.release();
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerInstallEvent::data(ExecutionContext* context, int timerId, int timeout, bool singleShot)
+{
+ RefPtr<JSONObject> data = genericTimerData(context, timerId);
+ data->setNumber("timeout", timeout);
+ data->setBoolean("singleShot", singleShot);
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerRemoveEvent::data(ExecutionContext* context, int timerId)
+{
+ return TracedValue::fromJSONValue(genericTimerData(context, timerId));
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorTimerFireEvent::data(ExecutionContext* context, int timerId)
+{
+ return TracedValue::fromJSONValue(genericTimerData(context, timerId));
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorAnimationFrameEvent::data(Document* document, int callbackId)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("id", callbackId);
+ data->setString("frame", toHexString(document->frame()));
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorWebSocketCreateEvent::data(Document* document, unsigned long identifier, const KURL& url, const String& protocol)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("identifier", identifier);
+ data->setString("url", url.string());
+ data->setString("frame", toHexString(document->frame()));
+ if (!protocol.isNull())
+ data->setString("webSocketProtocol", protocol);
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorWebSocketEvent::data(Document* document, unsigned long identifier)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("identifier", identifier);
+ data->setString("frame", toHexString(document->frame()));
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorParseHtmlEvent::beginData(Document* document, unsigned startLine)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("startLine", startLine);
+ data->setString("frame", toHexString(document->frame()));
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorXhrReadyStateChangeEvent::data(ExecutionContext* context, XMLHttpRequest* request)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("url", request->url().string());
+ data->setNumber("readyState", request->readyState());
+ if (LocalFrame* frame = frameForExecutionContext(context))
+ data->setString("frame", toHexString(frame));
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorXhrLoadEvent::data(ExecutionContext* context, XMLHttpRequest* request)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("url", request->url().string());
+ if (LocalFrame* frame = frameForExecutionContext(context))
+ data->setString("frame", toHexString(frame));
+ return TracedValue::fromJSONValue(data);
+}
+
+static void localToPageQuad(const RenderObject& renderer, const LayoutRect& rect, FloatQuad* quad)
+{
+ LocalFrame* frame = renderer.frame();
+ FrameView* view = frame->view();
+ FloatQuad absolute = renderer.localToAbsoluteQuad(FloatQuad(rect));
+ quad->setP1(view->contentsToRootView(roundedIntPoint(absolute.p1())));
+ quad->setP2(view->contentsToRootView(roundedIntPoint(absolute.p2())));
+ quad->setP3(view->contentsToRootView(roundedIntPoint(absolute.p3())));
+ quad->setP4(view->contentsToRootView(roundedIntPoint(absolute.p4())));
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorPaintEvent::data(RenderObject* renderer, const LayoutRect& clipRect, const GraphicsLayer* graphicsLayer)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("frame", toHexString(renderer->frame()));
+ FloatQuad quad;
+ localToPageQuad(*renderer, clipRect, &quad);
+ data->setArray("clip", createQuad(quad));
+ int nodeId = InspectorNodeIds::idForNode(renderer->generatingNode());
+ data->setNumber("nodeId", nodeId);
+ int graphicsLayerId = graphicsLayer ? graphicsLayer->platformLayer()->id() : 0;
+ data->setNumber("layerId", graphicsLayerId);
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorMarkLoadEvent::data(LocalFrame* frame)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("frame", toHexString(frame));
+ bool isMainFrame = frame && frame->page()->mainFrame() == frame;
+ data->setBoolean("isMainFrame", isMainFrame);
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorScrollLayerEvent::data(RenderObject* renderer)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("frame", toHexString(renderer->frame()));
+ int nodeId = InspectorNodeIds::idForNode(renderer->generatingNode());
+ data->setNumber("nodeId", nodeId);
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorEvaluateScriptEvent::data(LocalFrame* frame, const String& url, int lineNumber)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("frame", toHexString(frame));
+ data->setString("url", url);
+ data->setNumber("lineNumber", lineNumber);
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorFunctionCallEvent::data(ExecutionContext* context, int scriptId, const String& scriptName, int scriptLine)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("scriptId", String::number(scriptId));
+ data->setString("scriptName", scriptName);
+ data->setNumber("scriptLine", scriptLine);
+ if (LocalFrame* frame = frameForExecutionContext(context))
+ data->setString("frame", toHexString(frame));
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorPaintImageEvent::data(const RenderImage& renderImage)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("nodeId", InspectorNodeIds::idForNode(renderImage.generatingNode()));
+
+ if (const ImageResource* resource = renderImage.cachedImage())
+ data->setString("url", resource->url().string());
+
+ return TracedValue::fromJSONValue(data);
+}
+
+static size_t usedHeapSize()
+{
+ HeapInfo info;
+ ScriptGCEvent::getHeapSize(info);
+ return info.usedJSHeapSize;
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorUpdateCountersEvent::data()
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ if (isMainThread()) {
+ data->setNumber("documents", InspectorCounters::counterValue(InspectorCounters::DocumentCounter));
+ data->setNumber("nodes", InspectorCounters::counterValue(InspectorCounters::NodeCounter));
+ data->setNumber("jsEventListeners", InspectorCounters::counterValue(InspectorCounters::JSEventListenerCounter));
+ }
+ data->setNumber("jsHeapSizeUsed", static_cast<double>(usedHeapSize()));
+ return TracedValue::fromJSONValue(data);
+}
+
+PassRefPtr<TraceEvent::ConvertableToTraceFormat> InspectorCallStackEvent::currentCallStack()
+{
+ return adoptRef(new JSCallStack(createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true)));
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
new file mode 100644
index 00000000000..a977b2732ba
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
@@ -0,0 +1,144 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef InspectorTraceEvents_h
+#define InspectorTraceEvents_h
+
+#include "platform/EventTracer.h"
+#include "platform/TraceEvent.h"
+#include "wtf/Forward.h"
+
+namespace WebCore {
+
+class Document;
+class ExecutionContext;
+class FrameView;
+class GraphicsContext;
+class GraphicsLayer;
+class KURL;
+class LayoutRect;
+class LocalFrame;
+class RenderObject;
+class RenderImage;
+class ResourceRequest;
+class ResourceResponse;
+class ScriptSourceCode;
+class ScriptCallStack;
+class XMLHttpRequest;
+
+class InspectorLayoutEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> beginData(FrameView*);
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> endData(RenderObject* rootForThisLayout);
+};
+
+class InspectorSendRequestEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(unsigned long identifier, LocalFrame*, const ResourceRequest&);
+};
+
+class InspectorReceiveResponseEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(unsigned long identifier, LocalFrame*, const ResourceResponse&);
+};
+
+class InspectorReceiveDataEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(unsigned long identifier, LocalFrame*, int encodedDataLength);
+};
+
+class InspectorResourceFinishEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(unsigned long identifier, double finishTime, bool didFail);
+};
+
+class InspectorTimerInstallEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(ExecutionContext*, int timerId, int timeout, bool singleShot);
+};
+
+class InspectorTimerRemoveEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(ExecutionContext*, int timerId);
+};
+
+class InspectorTimerFireEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(ExecutionContext*, int timerId);
+};
+
+class InspectorAnimationFrameEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(Document*, int callbackId);
+};
+
+class InspectorWebSocketCreateEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(Document*, unsigned long identifier, const KURL&, const String& protocol);
+};
+
+class InspectorWebSocketEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(Document*, unsigned long identifier);
+};
+
+class InspectorParseHtmlEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> beginData(Document*, unsigned startLine);
+};
+
+class InspectorXhrReadyStateChangeEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(ExecutionContext*, XMLHttpRequest*);
+};
+
+class InspectorXhrLoadEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(ExecutionContext*, XMLHttpRequest*);
+};
+
+class InspectorPaintEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(RenderObject*, const LayoutRect& clipRect, const GraphicsLayer*);
+};
+
+class InspectorPaintImageEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(const RenderImage&);
+};
+
+class InspectorMarkLoadEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(LocalFrame*);
+};
+
+class InspectorScrollLayerEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(RenderObject*);
+};
+
+class InspectorEvaluateScriptEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(LocalFrame*, const String& url, int lineNumber);
+};
+
+class InspectorFunctionCallEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data(ExecutionContext*, int scriptId, const String& scriptName, int scriptLine);
+};
+
+class InspectorUpdateCountersEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> data();
+};
+
+class InspectorCallStackEvent {
+public:
+ static PassRefPtr<TraceEvent::ConvertableToTraceFormat> currentCallStack();
+};
+
+} // namespace WebCore
+
+
+#endif // !defined(InspectorTraceEvents_h)
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp
new file mode 100644
index 00000000000..9e2ee3d14de
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp
@@ -0,0 +1,64 @@
+//
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "config.h"
+
+#include "core/inspector/InspectorTracingAgent.h"
+
+#include "core/inspector/IdentifiersFactory.h"
+#include "core/inspector/InspectorClient.h"
+#include "core/inspector/InspectorState.h"
+#include "platform/TraceEvent.h"
+
+namespace WebCore {
+
+namespace TracingAgentState {
+const char sessionId[] = "sessionId";
+}
+
+namespace {
+const char devtoolsMetadataEventCategory[] = TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
+}
+
+InspectorTracingAgent::InspectorTracingAgent(InspectorClient* client)
+ : InspectorBaseAgent<InspectorTracingAgent>("Tracing")
+ , m_layerTreeId(0)
+ , m_client(client)
+{
+}
+
+void InspectorTracingAgent::restore()
+{
+ emitMetadataEvents();
+}
+
+void InspectorTracingAgent::start(ErrorString*, const String& categoryFilter, const String&, const double*, String* outSessionId)
+{
+ m_state->setString(TracingAgentState::sessionId, IdentifiersFactory::createIdentifier());
+ m_client->enableTracing(categoryFilter);
+ emitMetadataEvents();
+ *outSessionId = sessionId();
+}
+
+String InspectorTracingAgent::sessionId()
+{
+ return m_state->getString(TracingAgentState::sessionId);
+}
+
+void InspectorTracingAgent::emitMetadataEvents()
+{
+ TRACE_EVENT_INSTANT1(devtoolsMetadataEventCategory, "TracingStartedInPage", "sessionId", sessionId().utf8());
+ if (m_layerTreeId)
+ setLayerTreeId(m_layerTreeId);
+}
+
+void InspectorTracingAgent::setLayerTreeId(int layerTreeId)
+{
+ m_layerTreeId = layerTreeId;
+ TRACE_EVENT_INSTANT2(devtoolsMetadataEventCategory, "SetLayerTreeId", "sessionId", sessionId().utf8(), "layerTreeId", m_layerTreeId);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h
new file mode 100644
index 00000000000..307a2168374
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef InspectorTracingAgent_h
+#define InspectorTracingAgent_h
+
+#include "core/InspectorFrontend.h"
+#include "core/inspector/InspectorBaseAgent.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class InspectorClient;
+
+class InspectorTracingAgent FINAL
+ : public InspectorBaseAgent<InspectorTracingAgent>
+ , public InspectorBackendDispatcher::TracingCommandHandler {
+ WTF_MAKE_NONCOPYABLE(InspectorTracingAgent);
+public:
+ static PassOwnPtr<InspectorTracingAgent> create(InspectorClient* client)
+ {
+ return adoptPtr(new InspectorTracingAgent(client));
+ }
+
+ // Base agent methods.
+ virtual void restore() OVERRIDE;
+
+ // Protocol method implementations.
+ virtual void start(ErrorString*, const String& categoryFilter, const String&, const double*, String* sessionId) OVERRIDE;
+
+ // Methods for other agents to use.
+ void setLayerTreeId(int);
+
+private:
+ explicit InspectorTracingAgent(InspectorClient*);
+
+ void emitMetadataEvents();
+ String sessionId();
+
+ int m_layerTreeId;
+ InspectorClient* m_client;
+};
+
+}
+
+#endif // InspectorTracingAgent_h
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp
index c4b91911458..40d289958b4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.cpp
@@ -32,7 +32,7 @@
#include "core/inspector/InspectorWorkerAgent.h"
-#include "InspectorFrontend.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/inspector/JSONParser.h"
@@ -49,7 +49,7 @@ static const char workerInspectionEnabled[] = "workerInspectionEnabled";
static const char autoconnectToWorkers[] = "autoconnectToWorkers";
};
-class InspectorWorkerAgent::WorkerFrontendChannel : public WorkerGlobalScopeProxy::PageInspector {
+class InspectorWorkerAgent::WorkerFrontendChannel FINAL : public WorkerGlobalScopeProxy::PageInspector {
WTF_MAKE_FAST_ALLOCATED;
public:
explicit WorkerFrontendChannel(InspectorFrontend* frontend, WorkerGlobalScopeProxy* proxy)
@@ -85,7 +85,7 @@ public:
private:
// WorkerGlobalScopeProxy::PageInspector implementation
- virtual void dispatchMessageFromWorker(const String& message)
+ virtual void dispatchMessageFromWorker(const String& message) OVERRIDE
{
RefPtr<JSONValue> value = parseJSON(message);
if (!value)
@@ -105,16 +105,15 @@ private:
int InspectorWorkerAgent::WorkerFrontendChannel::s_nextId = 1;
-PassOwnPtr<InspectorWorkerAgent> InspectorWorkerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState)
+PassOwnPtr<InspectorWorkerAgent> InspectorWorkerAgent::create()
{
- return adoptPtr(new InspectorWorkerAgent(instrumentingAgents, inspectorState));
+ return adoptPtr(new InspectorWorkerAgent());
}
-InspectorWorkerAgent::InspectorWorkerAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState)
- : InspectorBaseAgent<InspectorWorkerAgent>("Worker", instrumentingAgents, inspectorState)
+InspectorWorkerAgent::InspectorWorkerAgent()
+ : InspectorBaseAgent<InspectorWorkerAgent>("Worker")
, m_inspectorFrontend(0)
{
- m_instrumentingAgents->setInspectorWorkerAgent(this);
}
InspectorWorkerAgent::~InspectorWorkerAgent()
@@ -122,6 +121,11 @@ InspectorWorkerAgent::~InspectorWorkerAgent()
m_instrumentingAgents->setInspectorWorkerAgent(0);
}
+void InspectorWorkerAgent::init()
+{
+ m_instrumentingAgents->setInspectorWorkerAgent(this);
+}
+
void InspectorWorkerAgent::setFrontend(InspectorFrontend* frontend)
{
m_inspectorFrontend = frontend;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h b/chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h
index 316f8546712..986439e6370 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InspectorWorkerAgent.h
@@ -44,14 +44,15 @@ class WorkerGlobalScopeProxy;
typedef String ErrorString;
-class InspectorWorkerAgent : public InspectorBaseAgent<InspectorWorkerAgent>, public InspectorBackendDispatcher::WorkerCommandHandler {
+class InspectorWorkerAgent FINAL : public InspectorBaseAgent<InspectorWorkerAgent>, public InspectorBackendDispatcher::WorkerCommandHandler {
public:
- static PassOwnPtr<InspectorWorkerAgent> create(InstrumentingAgents*, InspectorCompositeState*);
- ~InspectorWorkerAgent();
+ static PassOwnPtr<InspectorWorkerAgent> create();
+ virtual ~InspectorWorkerAgent();
- virtual void setFrontend(InspectorFrontend*);
- virtual void restore();
- virtual void clearFrontend();
+ virtual void init() OVERRIDE;
+ virtual void setFrontend(InspectorFrontend*) OVERRIDE;
+ virtual void restore() OVERRIDE;
+ virtual void clearFrontend() OVERRIDE;
// Called from InspectorInstrumentation
bool shouldPauseDedicatedWorkerOnStart();
@@ -59,16 +60,16 @@ public:
void workerGlobalScopeTerminated(WorkerGlobalScopeProxy*);
// Called from InspectorBackendDispatcher
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
- virtual void canInspectWorkers(ErrorString*, bool*);
- virtual void connectToWorker(ErrorString*, int workerId);
- virtual void disconnectFromWorker(ErrorString*, int workerId);
- virtual void sendMessageToWorker(ErrorString*, int workerId, const RefPtr<JSONObject>& message);
- virtual void setAutoconnectToWorkers(ErrorString*, bool value);
+ virtual void enable(ErrorString*) OVERRIDE;
+ virtual void disable(ErrorString*) OVERRIDE;
+ virtual void canInspectWorkers(ErrorString*, bool*) OVERRIDE;
+ virtual void connectToWorker(ErrorString*, int workerId) OVERRIDE;
+ virtual void disconnectFromWorker(ErrorString*, int workerId) OVERRIDE;
+ virtual void sendMessageToWorker(ErrorString*, int workerId, const RefPtr<JSONObject>& message) OVERRIDE;
+ virtual void setAutoconnectToWorkers(ErrorString*, bool value) OVERRIDE;
private:
- InspectorWorkerAgent(InstrumentingAgents*, InspectorCompositeState*);
+ InspectorWorkerAgent();
void createWorkerFrontendChannelsForExistingWorkers();
void createWorkerFrontendChannel(WorkerGlobalScopeProxy*, const String& url);
void destroyWorkerFrontendChannels();
diff --git a/chromium/third_party/WebKit/Source/core/inspector/InstrumentingAgents.h b/chromium/third_party/WebKit/Source/core/inspector/InstrumentingAgents.h
index fa6fb21c819..742afe6f71c 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/InstrumentingAgents.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/InstrumentingAgents.h
@@ -1 +1 @@
-#include "InstrumentingAgentsInl.h"
+#include "core/InstrumentingAgentsInl.h"
diff --git a/chromium/third_party/WebKit/Source/core/inspector/JSONParser.cpp b/chromium/third_party/WebKit/Source/core/inspector/JSONParser.cpp
index 58adb022e13..712781d9ec2 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/JSONParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/JSONParser.cpp
@@ -341,7 +341,7 @@ template<typename CharType>
PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, const CharType** valueTokenEnd, int depth)
{
if (depth > stackLimit)
- return 0;
+ return nullptr;
RefPtr<JSONValue> result;
const CharType* tokenStart;
@@ -349,7 +349,7 @@ PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, con
Token token = parseToken(start, end, &tokenStart, &tokenEnd);
switch (token) {
case InvalidToken:
- return 0;
+ return nullptr;
case NullToken:
result = JSONValue::null();
break;
@@ -363,7 +363,7 @@ PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, con
bool ok;
double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
if (!ok)
- return 0;
+ return nullptr;
result = JSONBasicValue::create(value);
break;
}
@@ -371,7 +371,7 @@ PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, con
String value;
bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
if (!ok)
- return 0;
+ return nullptr;
result = JSONString::create(value);
break;
}
@@ -382,7 +382,7 @@ PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, con
while (token != ArrayEnd) {
RefPtr<JSONValue> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
if (!arrayNode)
- return 0;
+ return nullptr;
array->pushValue(arrayNode);
// After a list value, we expect a comma or the end of the list.
@@ -392,14 +392,14 @@ PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, con
start = tokenEnd;
token = parseToken(start, end, &tokenStart, &tokenEnd);
if (token == ArrayEnd)
- return 0;
+ return nullptr;
} else if (token != ArrayEnd) {
// Unexpected value after list value. Bail out.
- return 0;
+ return nullptr;
}
}
if (token != ArrayEnd)
- return 0;
+ return nullptr;
result = array.release();
break;
}
@@ -409,20 +409,20 @@ PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, con
token = parseToken(start, end, &tokenStart, &tokenEnd);
while (token != ObjectEnd) {
if (token != StringLiteral)
- return 0;
+ return nullptr;
String key;
if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
- return 0;
+ return nullptr;
start = tokenEnd;
token = parseToken(start, end, &tokenStart, &tokenEnd);
if (token != ObjectPairSeparator)
- return 0;
+ return nullptr;
start = tokenEnd;
RefPtr<JSONValue> value = buildValue(start, end, &tokenEnd, depth + 1);
if (!value)
- return 0;
+ return nullptr;
object->setValue(key, value);
start = tokenEnd;
@@ -433,21 +433,21 @@ PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, con
start = tokenEnd;
token = parseToken(start, end, &tokenStart, &tokenEnd);
if (token == ObjectEnd)
- return 0;
+ return nullptr;
} else if (token != ObjectEnd) {
// Unexpected value after last object value. Bail out.
- return 0;
+ return nullptr;
}
}
if (token != ObjectEnd)
- return 0;
+ return nullptr;
result = object.release();
break;
}
default:
// We got a token that's not a value.
- return 0;
+ return nullptr;
}
*valueTokenEnd = tokenEnd;
return result.release();
@@ -460,7 +460,7 @@ PassRefPtr<JSONValue> parseJSONInternal(const CharType* start, unsigned length)
const CharType *tokenEnd;
RefPtr<JSONValue> value = buildValue(start, end, &tokenEnd, 0);
if (!value || tokenEnd != end)
- return 0;
+ return nullptr;
return value.release();
}
@@ -469,7 +469,7 @@ PassRefPtr<JSONValue> parseJSONInternal(const CharType* start, unsigned length)
PassRefPtr<JSONValue> parseJSON(const String& json)
{
if (json.isEmpty())
- return 0;
+ return nullptr;
if (json.is8Bit())
return parseJSONInternal(json.characters8(), json.length());
return parseJSONInternal(json.characters16(), json.length());
diff --git a/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.cpp b/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.cpp
index 6a669582b2d..148bb97b7dc 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.cpp
@@ -33,6 +33,7 @@
#include "bindings/v8/ScriptValue.h"
#include "bindings/v8/V8Binding.h"
+#include <v8-debug.h>
namespace WebCore {
@@ -62,47 +63,51 @@ JavaScriptCallFrame* JavaScriptCallFrame::caller()
return m_caller.get();
}
-int JavaScriptCallFrame::sourceID() const
+int JavaScriptCallFrame::callV8FunctionReturnInt(const char* name) const
{
v8::HandleScope handleScope(m_isolate);
- v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
- v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "sourceID"));
+ v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
+ v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, name)));
+ v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0);
if (result->IsInt32())
return result->Int32Value();
return 0;
}
-int JavaScriptCallFrame::line() const
+String JavaScriptCallFrame::callV8FunctionReturnString(const char* name) const
{
v8::HandleScope handleScope(m_isolate);
- v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
- v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "line"));
- if (result->IsInt32())
- return result->Int32Value();
- return 0;
+ v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
+ v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, name)));
+ v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0);
+ return toCoreStringWithUndefinedOrNullCheck(result);
+}
+
+int JavaScriptCallFrame::sourceID() const
+{
+ return callV8FunctionReturnInt("sourceID");
+}
+
+int JavaScriptCallFrame::line() const
+{
+ return callV8FunctionReturnInt("line");
}
int JavaScriptCallFrame::column() const
{
- v8::HandleScope handleScope(m_isolate);
- v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
- v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "column"));
- if (result->IsInt32())
- return result->Int32Value();
- return 0;
+ return callV8FunctionReturnInt("column");
}
String JavaScriptCallFrame::functionName() const
{
- v8::HandleScope handleScope(m_isolate);
- v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
- v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "functionName"));
- return toCoreStringWithUndefinedOrNullCheck(result);
+ return callV8FunctionReturnString("functionName");
}
v8::Handle<v8::Value> JavaScriptCallFrame::scopeChain() const
{
- v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "scopeChain")));
+ v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
+ v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "scopeChain")));
+ v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(func->Call(callFrame, 0, 0));
v8::Handle<v8::Array> result = v8::Array::New(m_isolate, scopeChain->Length());
for (uint32_t i = 0; i < scopeChain->Length(); i++)
result->Set(i, scopeChain->Get(i));
@@ -122,10 +127,7 @@ v8::Handle<v8::Value> JavaScriptCallFrame::thisObject() const
String JavaScriptCallFrame::stepInPositions() const
{
- v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
- v8::Handle<v8::Function> stepInPositions = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "stepInPositions")));
- v8::Handle<v8::Value> result = stepInPositions->Call(callFrame, 0, 0);
- return toCoreStringWithUndefinedOrNullCheck(result);
+ return callV8FunctionReturnString("stepInPositions");
}
bool JavaScriptCallFrame::isAtReturn() const
@@ -148,34 +150,35 @@ v8::Handle<v8::Value> JavaScriptCallFrame::evaluate(const String& expression)
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> evalFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "evaluate")));
v8::Handle<v8::Value> argv[] = { v8String(m_debuggerContext.newLocal(m_isolate)->GetIsolate(), expression) };
- return evalFunction->Call(callFrame, 1, argv);
+ return evalFunction->Call(callFrame, WTF_ARRAY_LENGTH(argv), argv);
}
v8::Handle<v8::Value> JavaScriptCallFrame::restart()
{
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> restartFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "restart")));
- v8::Debug::SetLiveEditEnabled(true);
+ v8::Debug::SetLiveEditEnabled(m_isolate, true);
v8::Handle<v8::Value> result = restartFunction->Call(callFrame, 0, 0);
- v8::Debug::SetLiveEditEnabled(false);
+ v8::Debug::SetLiveEditEnabled(m_isolate, false);
return result;
}
-v8::Handle<v8::Object> JavaScriptCallFrame::innerCallFrame()
-{
- return m_callFrame.newLocal(m_isolate);
-}
-
-ScriptValue JavaScriptCallFrame::setVariableValue(int scopeNumber, const String& variableName, const ScriptValue& newValue)
+ScriptValue JavaScriptCallFrame::setVariableValue(ScriptState* scriptState, int scopeNumber, const String& variableName, const ScriptValue& newValue)
{
+ ScriptState::Scope scriptScope(scriptState);
v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
v8::Handle<v8::Function> setVariableValueFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "setVariableValue")));
v8::Handle<v8::Value> argv[] = {
- v8::Handle<v8::Value>(v8::Integer::New(scopeNumber, m_isolate)),
+ v8::Handle<v8::Value>(v8::Integer::New(m_isolate, scopeNumber)),
v8String(m_isolate, variableName),
newValue.v8Value()
};
- return ScriptValue(setVariableValueFunction->Call(callFrame, 3, argv), m_isolate);
+ return ScriptValue(scriptState, setVariableValueFunction->Call(callFrame, WTF_ARRAY_LENGTH(argv), argv));
+}
+
+void JavaScriptCallFrame::trace(Visitor* visitor)
+{
+ visitor->trace(m_caller);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.h b/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.h
index ac0c0350b61..f72917026eb 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.h
@@ -33,22 +33,24 @@
#include "bindings/v8/ScopedPersistent.h"
+#include "bindings/v8/ScriptState.h"
#include "bindings/v8/ScriptWrappable.h"
-#include <v8-debug.h>
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
+#include <v8.h>
namespace WebCore {
class ScriptValue;
-class JavaScriptCallFrame : public RefCounted<JavaScriptCallFrame>, public ScriptWrappable {
+class JavaScriptCallFrame : public RefCountedWillBeGarbageCollectedFinalized<JavaScriptCallFrame>, public ScriptWrappable {
public:
- static PassRefPtr<JavaScriptCallFrame> create(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame)
+ static PassRefPtrWillBeRawPtr<JavaScriptCallFrame> create(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame)
{
- return adoptRef(new JavaScriptCallFrame(debuggerContext, callFrame));
+ return adoptRefWillBeNoop(new JavaScriptCallFrame(debuggerContext, callFrame));
}
~JavaScriptCallFrame();
+ void trace(Visitor*);
JavaScriptCallFrame* caller();
@@ -66,14 +68,16 @@ public:
v8::Handle<v8::Value> evaluate(const String& expression);
v8::Handle<v8::Value> restart();
- ScriptValue setVariableValue(int scopeNumber, const String& variableName, const ScriptValue& newValue);
- v8::Handle<v8::Object> innerCallFrame();
+ ScriptValue setVariableValue(ScriptState*, int scopeNumber, const String& variableName, const ScriptValue& newValue);
private:
JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame);
+ int callV8FunctionReturnInt(const char* name) const;
+ String callV8FunctionReturnString(const char* name) const;
+
v8::Isolate* m_isolate;
- RefPtr<JavaScriptCallFrame> m_caller;
+ RefPtrWillBeMember<JavaScriptCallFrame> m_caller;
ScopedPersistent<v8::Context> m_debuggerContext;
ScopedPersistent<v8::Object> m_callFrame;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.idl b/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.idl
index 1afad5a6d61..e4c4baa2474 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.idl
+++ b/chromium/third_party/WebKit/Source/core/inspector/JavaScriptCallFrame.idl
@@ -24,6 +24,7 @@
*/
[
+ WillBeGarbageCollected,
NoInterfaceObject,
DoNotCheckConstants
] interface JavaScriptCallFrame {
@@ -39,7 +40,7 @@
[Custom] any restart();
// Only declarative scope (local, with and catch) is accepted. Returns undefined.
- any setVariableValue([Default=Undefined] optional long scopeIndex, [TreatNullAs=NullString, TreatUndefinedAs=NullString, Default=Undefined] optional DOMString variableName, [Default=Undefined] optional any newValue);
+ [CallWith=ScriptState] any setVariableValue([Default=Undefined] optional long scopeIndex, [TreatNullAs=NullString, TreatUndefinedAs=NullString, Default=Undefined] optional DOMString variableName, [Default=Undefined] optional any newValue);
readonly attribute JavaScriptCallFrame caller;
readonly attribute long sourceID;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp b/chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp
index 3427421e4ac..3659bc05cc6 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp
@@ -31,6 +31,7 @@
#include "core/dom/DOMImplementation.h"
#include "core/fetch/Resource.h"
+#include "platform/MIMETypeRegistry.h"
#include "platform/SharedBuffer.h"
#include "platform/network/ResourceResponse.h"
@@ -45,9 +46,9 @@ static size_t maximumSingleResourceContentSize = 10 * 1000 * 1000;
namespace WebCore {
-PassRefPtr<XHRReplayData> XHRReplayData::create(const AtomicString& method, const KURL& url, bool async, PassRefPtr<FormData> formData, bool includeCredentials)
+PassRefPtr<XHRReplayData> XHRReplayData::create(ExecutionContext* executionContext, const AtomicString& method, const KURL& url, bool async, PassRefPtr<FormData> formData, bool includeCredentials)
{
- return adoptRef(new XHRReplayData(method, url, async, formData, includeCredentials));
+ return adoptRef(new XHRReplayData(executionContext, method, url, async, formData, includeCredentials));
}
void XHRReplayData::addHeader(const AtomicString& key, const AtomicString& value)
@@ -55,8 +56,9 @@ void XHRReplayData::addHeader(const AtomicString& key, const AtomicString& value
m_headers.set(key, value);
}
-XHRReplayData::XHRReplayData(const AtomicString& method, const KURL& url, bool async, PassRefPtr<FormData> formData, bool includeCredentials)
- : m_method(method)
+XHRReplayData::XHRReplayData(ExecutionContext* executionContext, const AtomicString& method, const KURL& url, bool async, PassRefPtr<FormData> formData, bool includeCredentials)
+ : ContextLifecycleObserver(executionContext)
+ , m_method(method)
, m_url(url)
, m_async(async)
, m_formData(formData)
@@ -130,7 +132,7 @@ size_t NetworkResourcesData::ResourceData::decodeDataToContent()
ASSERT(!hasContent());
size_t dataLength = m_dataBuffer->size();
m_content = m_decoder->decode(m_dataBuffer->data(), m_dataBuffer->size());
- m_content.append(m_decoder->flush());
+ m_content = m_content + m_decoder->flush();
m_dataBuffer = nullptr;
return contentSizeInBytes(m_content) - dataLength;
}
@@ -157,15 +159,18 @@ void NetworkResourcesData::resourceCreated(const String& requestId, const String
static PassOwnPtr<TextResourceDecoder> createOtherResourceTextDecoder(const String& mimeType, const String& textEncodingName)
{
OwnPtr<TextResourceDecoder> decoder;
- if (!textEncodingName.isEmpty())
+ if (!textEncodingName.isEmpty()) {
decoder = TextResourceDecoder::create("text/plain", textEncodingName);
- else if (DOMImplementation::isXMLMIMEType(mimeType.lower())) {
+ } else if (DOMImplementation::isXMLMIMEType(mimeType)) {
decoder = TextResourceDecoder::create("application/xml");
decoder->useLenientXMLDecoding();
- } else if (equalIgnoringCase(mimeType, "text/html"))
+ } else if (equalIgnoringCase(mimeType, "text/html")) {
decoder = TextResourceDecoder::create("text/html", "UTF-8");
- else if (mimeType == "text/plain")
+ } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || DOMImplementation::isJSONMIMEType(mimeType)) {
+ decoder = TextResourceDecoder::create("text/plain", "UTF-8");
+ } else if (DOMImplementation::isTextMIMEType(mimeType)) {
decoder = TextResourceDecoder::create("text/plain", "ISO-8859-1");
+ }
return decoder.release();
}
@@ -255,15 +260,6 @@ void NetworkResourcesData::addResource(const String& requestId, Resource* cached
resourceData->setResource(cachedResource);
}
-void NetworkResourcesData::addResourceSharedBuffer(const String& requestId, PassRefPtr<SharedBuffer> buffer, const String& textEncodingName)
-{
- ResourceData* resourceData = resourceDataForRequestId(requestId);
- if (!resourceData)
- return;
- resourceData->setBuffer(buffer);
- resourceData->setTextEncodingName(textEncodingName);
-}
-
NetworkResourcesData::ResourceData const* NetworkResourcesData::data(const String& requestId)
{
return resourceDataForRequestId(requestId);
@@ -297,18 +293,6 @@ void NetworkResourcesData::setXHRReplayData(const String& requestId, XHRReplayDa
resourceData->setXHRReplayData(xhrReplayData);
}
-void NetworkResourcesData::reuseXHRReplayData(const String& requestId, const String& reusedRequestId)
-{
- ResourceData* reusedResourceData = resourceDataForRequestId(reusedRequestId);
- ResourceData* resourceData = resourceDataForRequestId(requestId);
- if (!reusedResourceData || !resourceData) {
- m_reusedXHRReplayDataRequestIds.set(requestId, reusedRequestId);
- return;
- }
-
- resourceData->setXHRReplayData(reusedResourceData->xhrReplayData());
-}
-
Vector<NetworkResourcesData::ResourceData*> NetworkResourcesData::resources()
{
Vector<ResourceData*> result;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h b/chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h
index 672f588a081..9e00d64d5f2 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h
@@ -29,7 +29,8 @@
#ifndef NetworkResourcesData_h
#define NetworkResourcesData_h
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/dom/ContextLifecycleObserver.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorPageAgent.h"
#include "platform/network/HTTPHeaderMap.h"
#include "platform/weborigin/KURL.h"
@@ -41,15 +42,18 @@
namespace WebCore {
+class ExecutionContext;
class Resource;
class FormData;
class ResourceResponse;
class SharedBuffer;
class TextResourceDecoder;
-class XHRReplayData : public RefCounted<XHRReplayData> {
+class XHRReplayData
+ : public RefCounted<XHRReplayData>
+ , public ContextLifecycleObserver {
public:
- static PassRefPtr<XHRReplayData> create(const AtomicString& method, const KURL&, bool async, PassRefPtr<FormData>, bool includeCredentials);
+ static PassRefPtr<XHRReplayData> create(ExecutionContext*, const AtomicString& method, const KURL&, bool async, PassRefPtr<FormData>, bool includeCredentials);
void addHeader(const AtomicString& key, const AtomicString& value);
const AtomicString& method() const { return m_method; }
@@ -60,7 +64,7 @@ public:
bool includeCredentials() const { return m_includeCredentials; }
private:
- XHRReplayData(const AtomicString& method, const KURL&, bool async, PassRefPtr<FormData>, bool includeCredentials);
+ XHRReplayData(ExecutionContext*, const AtomicString& method, const KURL&, bool async, PassRefPtr<FormData>, bool includeCredentials);
AtomicString m_method;
KURL m_url;
@@ -156,14 +160,12 @@ public:
void maybeAddResourceData(const String& requestId, const char* data, size_t dataLength);
void maybeDecodeDataToContent(const String& requestId);
void addResource(const String& requestId, Resource*);
- void addResourceSharedBuffer(const String& requestId, PassRefPtr<SharedBuffer>, const String& textEncodingName);
ResourceData const* data(const String& requestId);
Vector<String> removeResource(Resource*);
void clear(const String& preservedLoaderId = String());
void setResourcesDataSizeLimits(size_t maximumResourcesContentSize, size_t maximumSingleResourceContentSize);
void setXHRReplayData(const String& requestId, XHRReplayData*);
- void reuseXHRReplayData(const String& requestId, const String& reusedRequestId);
XHRReplayData* xhrReplayData(const String& requestId);
Vector<ResourceData*> resources();
diff --git a/chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp
index 8418b37db3d..dfa5c70898f 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp
@@ -39,8 +39,8 @@
namespace WebCore {
-PageConsoleAgent::PageConsoleAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, InspectorDOMAgent* domAgent, InspectorTimelineAgent* timelineAgent)
- : InspectorConsoleAgent(instrumentingAgents, timelineAgent, state, injectedScriptManager)
+PageConsoleAgent::PageConsoleAgent(InjectedScriptManager* injectedScriptManager, InspectorDOMAgent* domAgent, InspectorTimelineAgent* timelineAgent)
+ : InspectorConsoleAgent(timelineAgent, injectedScriptManager)
, m_inspectorDOMAgent(domAgent)
{
}
@@ -56,10 +56,10 @@ void PageConsoleAgent::clearMessages(ErrorString* errorString)
InspectorConsoleAgent::clearMessages(errorString);
}
-class InspectableNode : public InjectedScriptHost::InspectableObject {
+class InspectableNode FINAL : public InjectedScriptHost::InspectableObject {
public:
explicit InspectableNode(Node* node) : m_node(node) { }
- virtual ScriptValue get(ScriptState* state)
+ virtual ScriptValue get(ScriptState* state) OVERRIDE
{
return InjectedScriptHost::nodeAsScriptValue(state, m_node);
}
@@ -75,11 +75,11 @@ void PageConsoleAgent::addInspectedNode(ErrorString* errorString, int nodeId)
return;
}
while (node->isInShadowTree()) {
- Node* ancestor = node->highestAncestor();
- if (!ancestor->isShadowRoot() || toShadowRoot(ancestor)->type() == ShadowRoot::AuthorShadowRoot)
+ Node& ancestor = node->highestAncestorOrSelf();
+ if (!ancestor.isShadowRoot() || toShadowRoot(ancestor).type() == ShadowRoot::AuthorShadowRoot)
break;
// User agent shadow root, keep climbing up.
- node = toShadowRoot(ancestor)->host();
+ node = toShadowRoot(ancestor).host();
}
m_injectedScriptManager->injectedScriptHost()->addInspectedObject(adoptPtr(new InspectableNode(node)));
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h b/chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h
index 4cca6952017..4dbf7f60975 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/PageConsoleAgent.h
@@ -38,21 +38,21 @@ namespace WebCore {
class InspectorDOMAgent;
-class PageConsoleAgent : public InspectorConsoleAgent {
+class PageConsoleAgent FINAL : public InspectorConsoleAgent {
WTF_MAKE_NONCOPYABLE(PageConsoleAgent);
public:
- static PassOwnPtr<PageConsoleAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, InspectorDOMAgent* domAgent, InspectorTimelineAgent* timelineAgent)
+ static PassOwnPtr<PageConsoleAgent> create(InjectedScriptManager* injectedScriptManager, InspectorDOMAgent* domAgent, InspectorTimelineAgent* timelineAgent)
{
- return adoptPtr(new PageConsoleAgent(instrumentingAgents, state, injectedScriptManager, domAgent, timelineAgent));
+ return adoptPtr(new PageConsoleAgent(injectedScriptManager, domAgent, timelineAgent));
}
virtual ~PageConsoleAgent();
virtual bool isWorkerAgent() OVERRIDE { return false; }
private:
- PageConsoleAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*, InspectorDOMAgent*, InspectorTimelineAgent*);
- virtual void clearMessages(ErrorString*);
- virtual void addInspectedNode(ErrorString*, int nodeId);
+ PageConsoleAgent(InjectedScriptManager*, InspectorDOMAgent*, InspectorTimelineAgent*);
+ virtual void clearMessages(ErrorString*) OVERRIDE;
+ virtual void addInspectedNode(ErrorString*, int nodeId) OVERRIDE;
InspectorDOMAgent* m_inspectorDOMAgent;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp
index 5e9323bfb91..9fa22372bd7 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp
@@ -34,23 +34,23 @@
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/InspectorOverlay.h"
#include "core/inspector/InspectorPageAgent.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
namespace WebCore {
-PassOwnPtr<PageDebuggerAgent> PageDebuggerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, PageScriptDebugServer* pageScriptDebugServer, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
+PassOwnPtr<PageDebuggerAgent> PageDebuggerAgent::create(PageScriptDebugServer* pageScriptDebugServer, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
{
- return adoptPtr(new PageDebuggerAgent(instrumentingAgents, inspectorState, pageScriptDebugServer, pageAgent, injectedScriptManager, overlay));
+ return adoptPtr(new PageDebuggerAgent(pageScriptDebugServer, pageAgent, injectedScriptManager, overlay));
}
-PageDebuggerAgent::PageDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, PageScriptDebugServer* pageScriptDebugServer, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
- : InspectorDebuggerAgent(instrumentingAgents, inspectorState, injectedScriptManager)
+PageDebuggerAgent::PageDebuggerAgent(PageScriptDebugServer* pageScriptDebugServer, InspectorPageAgent* pageAgent, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay)
+ : InspectorDebuggerAgent(injectedScriptManager)
, m_pageScriptDebugServer(pageScriptDebugServer)
, m_pageAgent(pageAgent)
, m_overlay(overlay)
@@ -91,12 +91,12 @@ PageScriptDebugServer& PageDebuggerAgent::scriptDebugServer()
void PageDebuggerAgent::muteConsole()
{
- PageConsole::mute();
+ FrameConsole::mute();
}
void PageDebuggerAgent::unmuteConsole()
{
- PageConsole::unmute();
+ FrameConsole::unmute();
}
void PageDebuggerAgent::overlayResumed()
@@ -108,17 +108,17 @@ void PageDebuggerAgent::overlayResumed()
void PageDebuggerAgent::overlaySteppedOver()
{
ErrorString error;
- stepOver(&error, 0);
+ stepOver(&error);
}
InjectedScript PageDebuggerAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId)
{
if (!executionContextId) {
- ScriptState* scriptState = mainWorldScriptState(m_pageAgent->mainFrame());
+ ScriptState* scriptState = ScriptState::forMainWorld(m_pageAgent->mainFrame());
return injectedScriptManager()->injectedScriptFor(scriptState);
}
InjectedScript injectedScript = injectedScriptManager()->injectedScriptForId(*executionContextId);
- if (injectedScript.hasNoValue())
+ if (injectedScript.isEmpty())
*errorString = "Execution context with given id not found.";
return injectedScript;
}
@@ -128,9 +128,9 @@ void PageDebuggerAgent::setOverlayMessage(ErrorString*, const String* message)
m_overlay->setPausedInDebuggerMessage(message);
}
-void PageDebuggerAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
+void PageDebuggerAgent::didClearDocumentOfWindowObject(LocalFrame* frame)
{
- if (world != mainThreadNormalWorld() || frame != m_pageAgent->mainFrame())
+ if (frame != m_pageAgent->mainFrame())
return;
reset();
@@ -141,23 +141,23 @@ void PageDebuggerAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorl
scriptDebugServer().setPreprocessorSource(m_pageAgent->scriptPreprocessorSource());
}
-String PageDebuggerAgent::preprocessEventListener(Frame* frame, const String& source, const String& url, const String& functionName)
+String PageDebuggerAgent::preprocessEventListener(LocalFrame* frame, const String& source, const String& url, const String& functionName)
{
ASSERT(frame);
ASSERT(m_pageScriptDebugServer);
return m_pageScriptDebugServer->preprocessEventListener(frame, source, url, functionName);
}
-PassOwnPtr<ScriptSourceCode> PageDebuggerAgent::preprocess(Frame* frame, const ScriptSourceCode& sourceCode)
+PassOwnPtr<ScriptSourceCode> PageDebuggerAgent::preprocess(LocalFrame* frame, const ScriptSourceCode& sourceCode)
{
ASSERT(m_pageScriptDebugServer);
ASSERT(frame);
return m_pageScriptDebugServer->preprocess(frame, sourceCode);
}
-void PageDebuggerAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void PageDebuggerAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
{
- Frame* mainFrame = frame->page()->mainFrame();
+ Frame* mainFrame = frame->page()->deprecatedLocalMainFrame();
if (loader->frame() == mainFrame)
pageDidCommitLoad();
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h b/chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h
index fa66819e519..97f2553dff7 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/PageDebuggerAgent.h
@@ -44,39 +44,39 @@ class Page;
class PageScriptDebugServer;
class ScriptSourceCode;
-class PageDebuggerAgent :
+class PageDebuggerAgent FINAL :
public InspectorDebuggerAgent,
public InspectorOverlayHost::Listener {
WTF_MAKE_NONCOPYABLE(PageDebuggerAgent);
WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<PageDebuggerAgent> create(InstrumentingAgents*, InspectorCompositeState*, PageScriptDebugServer*, InspectorPageAgent*, InjectedScriptManager*, InspectorOverlay*);
+ static PassOwnPtr<PageDebuggerAgent> create(PageScriptDebugServer*, InspectorPageAgent*, InjectedScriptManager*, InspectorOverlay*);
virtual ~PageDebuggerAgent();
- void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*);
- String preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName);
- PassOwnPtr<ScriptSourceCode> preprocess(Frame*, const ScriptSourceCode&);
- void didCommitLoad(Frame*, DocumentLoader*);
+ void didClearDocumentOfWindowObject(LocalFrame*);
+ String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName);
+ PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&);
+ void didCommitLoad(LocalFrame*, DocumentLoader*);
protected:
- virtual void enable();
- virtual void disable();
+ virtual void enable() OVERRIDE;
+ virtual void disable() OVERRIDE;
private:
- virtual void startListeningScriptDebugServer();
- virtual void stopListeningScriptDebugServer();
- virtual PageScriptDebugServer& scriptDebugServer();
- virtual void muteConsole();
- virtual void unmuteConsole();
+ virtual void startListeningScriptDebugServer() OVERRIDE;
+ virtual void stopListeningScriptDebugServer() OVERRIDE;
+ virtual PageScriptDebugServer& scriptDebugServer() OVERRIDE;
+ virtual void muteConsole() OVERRIDE;
+ virtual void unmuteConsole() OVERRIDE;
// InspectorOverlayHost::Listener implementation.
- virtual void overlayResumed();
- virtual void overlaySteppedOver();
+ virtual void overlayResumed() OVERRIDE;
+ virtual void overlaySteppedOver() OVERRIDE;
- virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId);
- virtual void setOverlayMessage(ErrorString*, const String*);
+ virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) OVERRIDE;
+ virtual void setOverlayMessage(ErrorString*, const String*) OVERRIDE;
- PageDebuggerAgent(InstrumentingAgents*, InspectorCompositeState*, PageScriptDebugServer*, InspectorPageAgent*, InjectedScriptManager*, InspectorOverlay*);
+ PageDebuggerAgent(PageScriptDebugServer*, InspectorPageAgent*, InjectedScriptManager*, InspectorOverlay*);
PageScriptDebugServer* m_pageScriptDebugServer;
InspectorPageAgent* m_pageAgent;
InspectorOverlay* m_overlay;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp
index 78d2bbc58b8..50929d05af3 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp
@@ -33,32 +33,24 @@
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScriptController.h"
+#include "bindings/v8/ScriptState.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/InjectedScript.h"
#include "core/inspector/InjectedScriptManager.h"
#include "core/inspector/InspectorPageAgent.h"
-#include "core/inspector/InspectorState.h"
#include "core/inspector/InstrumentingAgents.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
#include "platform/weborigin/SecurityOrigin.h"
-using WebCore::TypeBuilder::Runtime::ExecutionContextDescription;
-
namespace WebCore {
-namespace PageRuntimeAgentState {
-static const char runtimeEnabled[] = "runtimeEnabled";
-};
-
-PageRuntimeAgent::PageRuntimeAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer, Page* page, InspectorPageAgent* pageAgent)
- : InspectorRuntimeAgent(instrumentingAgents, state, injectedScriptManager, scriptDebugServer)
+PageRuntimeAgent::PageRuntimeAgent(InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer, Page* page, InspectorPageAgent* pageAgent)
+ : InspectorRuntimeAgent(injectedScriptManager, scriptDebugServer)
, m_inspectedPage(page)
, m_pageAgent(pageAgent)
- , m_frontend(0)
, m_mainWorldContextCreated(false)
{
- m_instrumentingAgents->setPageRuntimeAgent(this);
}
PageRuntimeAgent::~PageRuntimeAgent()
@@ -66,24 +58,9 @@ PageRuntimeAgent::~PageRuntimeAgent()
m_instrumentingAgents->setPageRuntimeAgent(0);
}
-void PageRuntimeAgent::setFrontend(InspectorFrontend* frontend)
-{
- m_frontend = frontend->runtime();
-}
-
-void PageRuntimeAgent::clearFrontend()
+void PageRuntimeAgent::init()
{
- m_frontend = 0;
- String errorString;
- disable(&errorString);
-}
-
-void PageRuntimeAgent::restore()
-{
- if (m_state->getBoolean(PageRuntimeAgentState::runtimeEnabled)) {
- String error;
- enable(&error);
- }
+ m_instrumentingAgents->setPageRuntimeAgent(this);
}
void PageRuntimeAgent::enable(ErrorString* errorString)
@@ -92,7 +69,7 @@ void PageRuntimeAgent::enable(ErrorString* errorString)
return;
InspectorRuntimeAgent::enable(errorString);
- m_state->setBoolean(PageRuntimeAgentState::runtimeEnabled, true);
+
// Only report existing contexts if the page did commit load, otherwise we may
// unintentionally initialize contexts in the frames which may trigger some listeners
// that are expected to be triggered only after the load is committed, see http://crbug.com/131623
@@ -100,94 +77,89 @@ void PageRuntimeAgent::enable(ErrorString* errorString)
reportExecutionContextCreation();
}
-void PageRuntimeAgent::disable(ErrorString* errorString)
+void PageRuntimeAgent::didClearDocumentOfWindowObject(LocalFrame* frame)
{
- if (!m_enabled)
- return;
-
- InspectorRuntimeAgent::disable(errorString);
- m_state->setBoolean(PageRuntimeAgentState::runtimeEnabled, false);
-}
-
-void PageRuntimeAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
-{
- if (world != mainThreadNormalWorld())
- return;
-
m_mainWorldContextCreated = true;
if (!m_enabled)
return;
ASSERT(m_frontend);
+
+ if (frame == m_inspectedPage->mainFrame()) {
+ m_scriptStateToId.clear();
+ m_frontend->executionContextsCleared();
+ }
String frameId = m_pageAgent->frameId(frame);
- ScriptState* scriptState = mainWorldScriptState(frame);
- notifyContextCreated(frameId, scriptState, 0, true);
+ addExecutionContextToFrontend(ScriptState::forMainWorld(frame), true, "", frameId);
}
-void PageRuntimeAgent::didCreateIsolatedContext(Frame* frame, ScriptState* scriptState, SecurityOrigin* origin)
+void PageRuntimeAgent::didCreateIsolatedContext(LocalFrame* frame, ScriptState* scriptState, SecurityOrigin* origin)
{
if (!m_enabled)
return;
ASSERT(m_frontend);
String frameId = m_pageAgent->frameId(frame);
- notifyContextCreated(frameId, scriptState, origin, false);
+ addExecutionContextToFrontend(scriptState, false, origin->toRawString(), frameId);
}
InjectedScript PageRuntimeAgent::injectedScriptForEval(ErrorString* errorString, const int* executionContextId)
{
if (!executionContextId) {
- ScriptState* scriptState = mainWorldScriptState(m_inspectedPage->mainFrame());
+ ScriptState* scriptState = ScriptState::forMainWorld(m_inspectedPage->deprecatedLocalMainFrame());
InjectedScript result = injectedScriptManager()->injectedScriptFor(scriptState);
- if (result.hasNoValue())
+ if (result.isEmpty())
*errorString = "Internal error: main world execution context not found.";
return result;
}
InjectedScript injectedScript = injectedScriptManager()->injectedScriptForId(*executionContextId);
- if (injectedScript.hasNoValue())
+ if (injectedScript.isEmpty())
*errorString = "Execution context with given id not found.";
return injectedScript;
}
void PageRuntimeAgent::muteConsole()
{
- PageConsole::mute();
+ FrameConsole::mute();
}
void PageRuntimeAgent::unmuteConsole()
{
- PageConsole::unmute();
+ FrameConsole::unmute();
}
void PageRuntimeAgent::reportExecutionContextCreation()
{
Vector<std::pair<ScriptState*, SecurityOrigin*> > isolatedContexts;
for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (!frame->script().canExecuteScripts(NotAboutToExecuteScript))
+ if (!frame->isLocalFrame())
+ continue;
+ LocalFrame* localFrame = toLocalFrame(frame);
+ if (!localFrame->script().canExecuteScripts(NotAboutToExecuteScript))
continue;
- String frameId = m_pageAgent->frameId(frame);
+ String frameId = m_pageAgent->frameId(localFrame);
- ScriptState* scriptState = mainWorldScriptState(frame);
- notifyContextCreated(frameId, scriptState, 0, true);
- frame->script().collectIsolatedContexts(isolatedContexts);
+ ScriptState* scriptState = ScriptState::forMainWorld(localFrame);
+ addExecutionContextToFrontend(scriptState, true, "", frameId);
+ localFrame->script().collectIsolatedContexts(isolatedContexts);
if (isolatedContexts.isEmpty())
continue;
for (size_t i = 0; i< isolatedContexts.size(); i++)
- notifyContextCreated(frameId, isolatedContexts[i].first, isolatedContexts[i].second, false);
+ addExecutionContextToFrontend(isolatedContexts[i].first, false, isolatedContexts[i].second->toRawString(), frameId);
isolatedContexts.clear();
}
}
-void PageRuntimeAgent::notifyContextCreated(const String& frameId, ScriptState* scriptState, SecurityOrigin* securityOrigin, bool isPageContext)
+void PageRuntimeAgent::frameWindowDiscarded(LocalDOMWindow* window)
{
- ASSERT(securityOrigin || isPageContext);
- int executionContextId = injectedScriptManager()->injectedScriptIdFor(scriptState);
- String name = securityOrigin ? securityOrigin->toRawString() : "";
- m_frontend->executionContextCreated(ExecutionContextDescription::create()
- .setId(executionContextId)
- .setIsPageContext(isPageContext)
- .setName(name)
- .setFrameId(frameId)
- .release());
+ Vector<RefPtr<ScriptState> > scriptStatesToRemove;
+ for (ScriptStateToId::iterator it = m_scriptStateToId.begin(); it != m_scriptStateToId.end(); ++it) {
+ RefPtr<ScriptState> scriptState = it->key;
+ if (scriptState->contextIsEmpty() || window == scriptState->domWindow()) {
+ scriptStatesToRemove.append(scriptState);
+ m_frontend->executionContextDestroyed(it->value);
+ }
+ }
+ m_scriptStateToId.removeAll(scriptStatesToRemove);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h b/chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h
index 27e635badc1..5e41bba1c64 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/PageRuntimeAgent.h
@@ -31,7 +31,6 @@
#ifndef PageRuntimeAgent_h
#define PageRuntimeAgent_h
-#include "InspectorFrontend.h"
#include "bindings/v8/ScriptState.h"
#include "core/inspector/InspectorRuntimeAgent.h"
#include "wtf/PassOwnPtr.h"
@@ -42,34 +41,30 @@ class InspectorPageAgent;
class Page;
class SecurityOrigin;
-class PageRuntimeAgent : public InspectorRuntimeAgent {
+class PageRuntimeAgent FINAL : public InspectorRuntimeAgent {
public:
- static PassOwnPtr<PageRuntimeAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer, Page* page, InspectorPageAgent* pageAgent)
+ static PassOwnPtr<PageRuntimeAgent> create(InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer, Page* page, InspectorPageAgent* pageAgent)
{
- return adoptPtr(new PageRuntimeAgent(instrumentingAgents, state, injectedScriptManager, scriptDebugServer, page, pageAgent));
+ return adoptPtr(new PageRuntimeAgent(injectedScriptManager, scriptDebugServer, page, pageAgent));
}
virtual ~PageRuntimeAgent();
- virtual void setFrontend(InspectorFrontend*);
- virtual void clearFrontend();
- virtual void restore();
- virtual void enable(ErrorString*);
- virtual void disable(ErrorString*);
+ virtual void init() OVERRIDE;
+ virtual void enable(ErrorString*) OVERRIDE;
- void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*);
- void didCreateIsolatedContext(Frame*, ScriptState*, SecurityOrigin*);
+ void didClearDocumentOfWindowObject(LocalFrame*);
+ void didCreateIsolatedContext(LocalFrame*, ScriptState*, SecurityOrigin*);
+ void frameWindowDiscarded(LocalDOMWindow*);
private:
- PageRuntimeAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*, ScriptDebugServer*, Page*, InspectorPageAgent*);
+ PageRuntimeAgent(InjectedScriptManager*, ScriptDebugServer*, Page*, InspectorPageAgent*);
- virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId);
- virtual void muteConsole();
- virtual void unmuteConsole();
+ virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) OVERRIDE;
+ virtual void muteConsole() OVERRIDE;
+ virtual void unmuteConsole() OVERRIDE;
void reportExecutionContextCreation();
- void notifyContextCreated(const String& frameId, ScriptState*, SecurityOrigin*, bool isPageContext);
Page* m_inspectedPage;
InspectorPageAgent* m_pageAgent;
- InspectorFrontend::Runtime* m_frontend;
bool m_mainWorldContextCreated;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.cpp b/chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.cpp
index 6c5ac58f57e..c5741d144cb 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.cpp
@@ -31,14 +31,17 @@
#include "config.h"
#include "core/inspector/ScriptArguments.h"
-#include "bindings/v8/ScriptScope.h"
#include "bindings/v8/ScriptValue.h"
+#include "bindings/v8/V8Binding.h"
+#include <v8.h>
namespace WebCore {
-PassRefPtr<ScriptArguments> ScriptArguments::create(ScriptState* scriptState, Vector<ScriptValue>& arguments)
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptArguments)
+
+PassRefPtrWillBeRawPtr<ScriptArguments> ScriptArguments::create(ScriptState* scriptState, Vector<ScriptValue>& arguments)
{
- return adoptRef(new ScriptArguments(scriptState, arguments));
+ return adoptRefWillBeNoop(new ScriptArguments(scriptState, arguments));
}
ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>& arguments)
@@ -47,54 +50,26 @@ ScriptArguments::ScriptArguments(ScriptState* scriptState, Vector<ScriptValue>&
m_arguments.swap(arguments);
}
-ScriptArguments::~ScriptArguments()
-{
-}
-
const ScriptValue &ScriptArguments::argumentAt(size_t index) const
{
ASSERT(m_arguments.size() > index);
return m_arguments[index];
}
-ScriptState* ScriptArguments::globalState() const
-{
- return m_scriptState.get();
-}
-
bool ScriptArguments::getFirstArgumentAsString(String& result, bool checkForNullOrUndefined)
{
if (!argumentCount())
return false;
const ScriptValue& value = argumentAt(0);
- ScriptScope scope(m_scriptState.get());
+ ScriptState::Scope scope(m_scriptState.get());
if (checkForNullOrUndefined && (value.isNull() || value.isUndefined()))
return false;
- if (!globalState()) {
- ASSERT_NOT_REACHED();
- return false;
- }
-
- result = value.toString();
- return true;
-}
-
-bool ScriptArguments::isEqual(ScriptArguments* other) const
-{
- if (!other)
- return false;
-
- if (m_arguments.size() != other->m_arguments.size())
- return false;
- if (!globalState() && m_arguments.size())
- return false;
-
- for (size_t i = 0; i < m_arguments.size(); ++i) {
- if (!m_arguments[i].isEqual(other->globalState(), other->m_arguments[i]))
- return false;
- }
+ // We intentionally ignore an exception that can be thrown in ToString().
+ v8::TryCatch block;
+ v8::Handle<v8::String> string = value.v8Value()->ToString();
+ result = string.IsEmpty() ? String() : toCoreString(string);
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.h b/chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.h
index 9d2185a03fe..c2266115547 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptArguments.h
@@ -41,24 +41,24 @@ namespace WebCore {
class ScriptValue;
-class ScriptArguments : public RefCounted<ScriptArguments> {
+class ScriptArguments : public RefCountedWillBeGarbageCollectedFinalized<ScriptArguments> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptArguments);
public:
- static PassRefPtr<ScriptArguments> create(ScriptState*, Vector<ScriptValue>& arguments);
-
- ~ScriptArguments();
+ static PassRefPtrWillBeRawPtr<ScriptArguments> create(ScriptState*, Vector<ScriptValue>& arguments);
const ScriptValue& argumentAt(size_t) const;
size_t argumentCount() const { return m_arguments.size(); }
- ScriptState* globalState() const;
+ ScriptState* scriptState() const { return m_scriptState.get(); }
bool getFirstArgumentAsString(WTF::String& result, bool checkForNullOrUndefined = false);
- bool isEqual(ScriptArguments*) const;
+
+ void trace(Visitor*) { }
private:
ScriptArguments(ScriptState*, Vector<ScriptValue>& arguments);
- ScriptStateProtectedPtr m_scriptState;
+ ScriptStateProtectingContext m_scriptState;
Vector<ScriptValue> m_arguments;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp b/chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp
index 4e5989eed04..73db181561a 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp
@@ -46,14 +46,6 @@ ScriptCallFrame::~ScriptCallFrame()
{
}
-bool ScriptCallFrame::isEqual(const ScriptCallFrame& o) const
-{
- return m_functionName == o.m_functionName
- && m_scriptId == o.m_scriptId
- && m_scriptName == o.m_scriptName
- && m_lineNumber == o.m_lineNumber;
-}
-
PassRefPtr<TypeBuilder::Console::CallFrame> ScriptCallFrame::buildInspectorObject() const
{
return TypeBuilder::Console::CallFrame::create()
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.h b/chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.h
index 021e66ddda9..5e86c50f491 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptCallFrame.h
@@ -31,7 +31,7 @@
#ifndef ScriptCallFrame_h
#define ScriptCallFrame_h
-#include "InspectorTypeBuilder.h"
+#include "core/InspectorTypeBuilder.h"
#include "wtf/Forward.h"
#include "wtf/text/WTFString.h"
@@ -48,8 +48,6 @@ public:
unsigned lineNumber() const { return m_lineNumber; }
unsigned columnNumber() const { return m_column; }
- bool isEqual(const ScriptCallFrame&) const;
-
PassRefPtr<TypeBuilder::Console::CallFrame> buildInspectorObject() const;
private:
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp b/chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp
index 0a23bb4fae5..641e6f36e33 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp
@@ -34,9 +34,11 @@
namespace WebCore {
-PassRefPtr<ScriptCallStack> ScriptCallStack::create(Vector<ScriptCallFrame>& frames)
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptCallStack);
+
+PassRefPtrWillBeRawPtr<ScriptCallStack> ScriptCallStack::create(Vector<ScriptCallFrame>& frames)
{
- return adoptRef(new ScriptCallStack(frames));
+ return adoptRefWillBeNoop(new ScriptCallStack(frames));
}
ScriptCallStack::ScriptCallStack(Vector<ScriptCallFrame>& frames)
@@ -44,10 +46,6 @@ ScriptCallStack::ScriptCallStack(Vector<ScriptCallFrame>& frames)
m_frames.swap(frames);
}
-ScriptCallStack::~ScriptCallStack()
-{
-}
-
const ScriptCallFrame &ScriptCallStack::at(size_t index) const
{
ASSERT(m_frames.size() > index);
@@ -59,23 +57,6 @@ size_t ScriptCallStack::size() const
return m_frames.size();
}
-bool ScriptCallStack::isEqual(ScriptCallStack* o) const
-{
- if (!o)
- return false;
-
- size_t frameCount = o->m_frames.size();
- if (frameCount != m_frames.size())
- return false;
-
- for (size_t i = 0; i < frameCount; ++i) {
- if (!m_frames[i].isEqual(o->m_frames[i]))
- return false;
- }
-
- return true;
-}
-
PassRefPtr<TypeBuilder::Array<TypeBuilder::Console::CallFrame> > ScriptCallStack::buildInspectorArray() const
{
RefPtr<TypeBuilder::Array<TypeBuilder::Console::CallFrame> > frames = TypeBuilder::Array<TypeBuilder::Console::CallFrame>::create();
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.h b/chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.h
index 9549db8b09a..5efe1554d81 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptCallStack.h
@@ -31,31 +31,31 @@
#ifndef ScriptCallStack_h
#define ScriptCallStack_h
-#include "InspectorTypeBuilder.h"
+#include "core/InspectorTypeBuilder.h"
#include "core/inspector/ScriptCallFrame.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
namespace WebCore {
-class ScriptCallStack : public RefCounted<ScriptCallStack> {
+class ScriptCallStack : public RefCountedWillBeGarbageCollectedFinalized<ScriptCallStack> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(ScriptCallStack);
public:
static const size_t maxCallStackSizeToCapture = 200;
- static PassRefPtr<ScriptCallStack> create(Vector<ScriptCallFrame>&);
-
- ~ScriptCallStack();
+ static PassRefPtrWillBeRawPtr<ScriptCallStack> create(Vector<ScriptCallFrame>&);
const ScriptCallFrame &at(size_t) const;
size_t size() const;
- bool isEqual(ScriptCallStack*) const;
-
PassRefPtr<TypeBuilder::Array<TypeBuilder::Console::CallFrame> > buildInspectorArray() const;
+ void trace(Visitor*) { }
+
private:
- ScriptCallStack(Vector<ScriptCallFrame>&);
+ explicit ScriptCallStack(Vector<ScriptCallFrame>&);
Vector<ScriptCallFrame> m_frames;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptDebugListener.h b/chromium/third_party/WebKit/Source/core/inspector/ScriptDebugListener.h
index f2e1ce7cc92..2128570cc08 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptDebugListener.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptDebugListener.h
@@ -38,7 +38,6 @@
namespace WebCore {
class ScriptValue;
-class JavaScriptCallFrame;
class ScriptDebugListener {
public:
@@ -63,13 +62,6 @@ public:
bool isContentScript;
};
- virtual ~ScriptDebugListener() { }
-
- virtual void didParseSource(const String& scriptId, const Script&) = 0;
- virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) = 0;
- virtual void didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints) = 0;
- virtual void didContinue() = 0;
-
enum SkipPauseRequest {
NoSkip,
Continue,
@@ -77,9 +69,12 @@ public:
StepOut
};
- virtual SkipPauseRequest shouldSkipExceptionPause(RefPtr<JavaScriptCallFrame>& topFrame) = 0;
- virtual SkipPauseRequest shouldSkipBreakpointPause(RefPtr<JavaScriptCallFrame>& topFrame) = 0;
- virtual SkipPauseRequest shouldSkipStepPause(RefPtr<JavaScriptCallFrame>& topFrame) = 0;
+ virtual ~ScriptDebugListener() { }
+
+ virtual void didParseSource(const String& scriptId, const Script&) = 0;
+ virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) = 0;
+ virtual SkipPauseRequest didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints) = 0;
+ virtual void didContinue() = 0;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp b/chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp
index 8eef1ea15ac..e0a06dd1b41 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.cpp
@@ -32,15 +32,15 @@
#include "core/inspector/ScriptProfile.h"
#include "bindings/v8/V8Binding.h"
-#include <v8-profiler.h>
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
+#include <v8.h>
namespace WebCore {
ScriptProfile::~ScriptProfile()
{
- const_cast<v8::CpuProfile*>(m_profile)->Delete();
+ m_profile->Delete();
}
String ScriptProfile::title() const
@@ -49,11 +49,6 @@ String ScriptProfile::title() const
return toCoreString(m_profile->GetTitle());
}
-unsigned int ScriptProfile::uid() const
-{
- return m_profile->GetUid();
-}
-
double ScriptProfile::idleTime() const
{
return m_idleTime;
@@ -89,8 +84,8 @@ static PassRefPtr<TypeBuilder::Profiler::CPUProfileNode> buildInspectorObjectFor
.setHitCount(node->GetHitCount())
.setCallUID(node->GetCallUid())
.setChildren(children.release())
- .setDeoptReason(node->GetBailoutReason());
- result->setId(node->GetNodeId());
+ .setDeoptReason(node->GetBailoutReason())
+ .setId(node->GetNodeId());
return result.release();
}
@@ -108,5 +103,13 @@ PassRefPtr<TypeBuilder::Array<int> > ScriptProfile::buildInspectorObjectForSampl
return array.release();
}
+PassRefPtr<TypeBuilder::Array<double> > ScriptProfile::buildInspectorObjectForTimestamps() const
+{
+ RefPtr<TypeBuilder::Array<double> > array = TypeBuilder::Array<double>::create();
+ int count = m_profile->GetSamplesCount();
+ for (int i = 0; i < count; i++)
+ array->addItem(m_profile->GetSampleTimestamp(i));
+ return array.release();
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.h b/chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.h
index 0a99d899854..0905ab14534 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/ScriptProfile.h
@@ -31,26 +31,24 @@
#ifndef ScriptProfile_h
#define ScriptProfile_h
-#include "InspectorTypeBuilder.h"
+#include "core/InspectorTypeBuilder.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
-
-namespace v8 {
-class CpuProfile;
-}
+#include <v8-profiler.h>
namespace WebCore {
-class ScriptProfile FINAL : public RefCounted<ScriptProfile> {
+class ScriptProfile FINAL : public RefCountedWillBeGarbageCollectedFinalized<ScriptProfile> {
public:
- static PassRefPtr<ScriptProfile> create(const v8::CpuProfile* profile, double idleTime)
+ static PassRefPtrWillBeRawPtr<ScriptProfile> create(v8::CpuProfile* profile, double idleTime)
{
- return adoptRef(new ScriptProfile(profile, idleTime));
+ return adoptRefWillBeNoop(new ScriptProfile(profile, idleTime));
}
~ScriptProfile();
+ void trace(Visitor*) { }
String title() const;
- unsigned int uid() const;
double idleTime() const;
double startTime() const;
@@ -58,15 +56,16 @@ public:
PassRefPtr<TypeBuilder::Profiler::CPUProfileNode> buildInspectorObjectForHead() const;
PassRefPtr<TypeBuilder::Array<int> > buildInspectorObjectForSamples() const;
+ PassRefPtr<TypeBuilder::Array<double> > buildInspectorObjectForTimestamps() const;
private:
- ScriptProfile(const v8::CpuProfile* profile, double idleTime)
+ ScriptProfile(v8::CpuProfile* profile, double idleTime)
: m_profile(profile)
, m_idleTime(idleTime)
{
}
- const v8::CpuProfile* m_profile;
+ v8::CpuProfile* m_profile;
double m_idleTime;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.cpp b/chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.cpp
index b0fd28a3b66..62145ca501d 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.cpp
@@ -42,27 +42,31 @@
namespace WebCore {
-PassRefPtr<JSONObject> TimelineRecordFactory::createGenericRecord(double startTime, int maxCallStackDepth, const String& type)
-{
- RefPtr<JSONObject> record = JSONObject::create();
- record->setNumber("startTime", startTime);
+using TypeBuilder::Timeline::TimelineEvent;
+PassRefPtr<TimelineEvent> TimelineRecordFactory::createGenericRecord(double startTime, int maxCallStackDepth, const String& type, PassRefPtr<JSONObject> data)
+{
+ ASSERT(data.get());
+ RefPtr<TimelineEvent> record = TimelineEvent::create()
+ .setType(type)
+ .setData(data)
+ .setStartTime(startTime);
if (maxCallStackDepth) {
- RefPtr<ScriptCallStack> stackTrace = createScriptCallStack(maxCallStackDepth, true);
+ RefPtrWillBeRawPtr<ScriptCallStack> stackTrace = createScriptCallStack(maxCallStackDepth, true);
if (stackTrace && stackTrace->size())
- record->setValue("stackTrace", stackTrace->buildInspectorArray());
+ record->setStackTrace(stackTrace->buildInspectorArray());
}
- record->setString("type", type);
return record.release();
}
-PassRefPtr<JSONObject> TimelineRecordFactory::createBackgroundRecord(double startTime, const String& threadName, const String& type, PassRefPtr<JSONObject> data)
+PassRefPtr<TimelineEvent> TimelineRecordFactory::createBackgroundRecord(double startTime, const String& threadName, const String& type, PassRefPtr<JSONObject> data)
{
- RefPtr<JSONObject> record = JSONObject::create();
- record->setNumber("startTime", startTime);
- record->setString("thread", threadName);
- record->setString("type", type);
- record->setObject("data", data ? data : JSONObject::create());
+ ASSERT(data.get());
+ RefPtr<TimelineEvent> record = TimelineEvent::create()
+ .setType(type)
+ .setData(data)
+ .setStartTime(startTime);
+ record->setThread(threadName);
return record.release();
}
@@ -73,9 +77,10 @@ PassRefPtr<JSONObject> TimelineRecordFactory::createGCEventData(size_t usedHeapS
return data.release();
}
-PassRefPtr<JSONObject> TimelineRecordFactory::createFunctionCallData(const String& scriptName, int scriptLine)
+PassRefPtr<JSONObject> TimelineRecordFactory::createFunctionCallData(int scriptId, const String& scriptName, int scriptLine)
{
RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("scriptId", String::number(scriptId));
data->setString("scriptName", scriptName);
data->setNumber("scriptLine", scriptLine);
return data.release();
@@ -127,17 +132,17 @@ PassRefPtr<JSONObject> TimelineRecordFactory::createEvaluateScriptData(const Str
return data.release();
}
-PassRefPtr<JSONObject> TimelineRecordFactory::createTimeStampData(const String& message)
+PassRefPtr<JSONObject> TimelineRecordFactory::createConsoleTimeData(const String& message)
{
RefPtr<JSONObject> data = JSONObject::create();
data->setString("message", message);
return data.release();
}
-PassRefPtr<JSONObject> TimelineRecordFactory::createScheduleResourceRequestData(const String& url)
+PassRefPtr<JSONObject> TimelineRecordFactory::createTimeStampData(const String& message)
{
RefPtr<JSONObject> data = JSONObject::create();
- data->setString("url", url);
+ data->setString("message", message);
return data.release();
}
@@ -221,12 +226,10 @@ PassRefPtr<JSONObject> TimelineRecordFactory::createAnimationFrameData(int callb
return data.release();
}
-PassRefPtr<JSONObject> TimelineRecordFactory::createGPUTaskData(bool foreign, size_t usedGPUMemoryBytes)
+PassRefPtr<JSONObject> TimelineRecordFactory::createGPUTaskData(bool foreign)
{
RefPtr<JSONObject> data = JSONObject::create();
data->setBoolean("foreign", foreign);
- if (!foreign)
- data->setNumber("usedGPUMemoryBytes", usedGPUMemoryBytes);
return data.release();
}
@@ -247,8 +250,7 @@ static PassRefPtr<JSONArray> createQuad(const FloatQuad& quad)
PassRefPtr<JSONObject> TimelineRecordFactory::createNodeData(long long nodeId)
{
RefPtr<JSONObject> data = JSONObject::create();
- if (nodeId)
- data->setNumber("rootNode", nodeId);
+ setNodeData(data.get(), nodeId);
return data.release();
}
@@ -257,12 +259,27 @@ PassRefPtr<JSONObject> TimelineRecordFactory::createLayerData(long long rootNode
return createNodeData(rootNodeId);
}
-PassRefPtr<JSONObject> TimelineRecordFactory::createPaintData(const FloatQuad& quad, long long layerRootNodeId, int graphicsLayerId)
+void TimelineRecordFactory::setLayerTreeData(JSONObject* data, PassRefPtr<JSONValue> layerTree)
+{
+ data->setValue("layerTree", layerTree);
+}
+
+void TimelineRecordFactory::setNodeData(JSONObject* data, long long nodeId)
+{
+ if (nodeId)
+ data->setNumber("backendNodeId", nodeId);
+}
+
+void TimelineRecordFactory::setLayerData(JSONObject* data, long long rootNodeId)
+{
+ setNodeData(data, rootNodeId);
+}
+
+void TimelineRecordFactory::setPaintData(JSONObject* data, const FloatQuad& quad, long long layerRootNodeId, int graphicsLayerId)
{
- RefPtr<JSONObject> data = TimelineRecordFactory::createLayerData(layerRootNodeId);
+ setLayerData(data, layerRootNodeId);
data->setArray("clip", createQuad(quad));
data->setNumber("layerId", graphicsLayerId);
- return data.release();
}
PassRefPtr<JSONObject> TimelineRecordFactory::createFrameData(int frameId)
@@ -272,25 +289,39 @@ PassRefPtr<JSONObject> TimelineRecordFactory::createFrameData(int frameId)
return data.release();
}
-void TimelineRecordFactory::appendLayoutRoot(JSONObject* data, const FloatQuad& quad, long long rootNodeId)
+void TimelineRecordFactory::setLayoutRoot(JSONObject* data, const FloatQuad& quad, long long rootNodeId)
{
data->setArray("root", createQuad(quad));
if (rootNodeId)
- data->setNumber("rootNode", rootNodeId);
+ data->setNumber("backendNodeId", rootNodeId);
}
-void TimelineRecordFactory::appendStyleRecalcDetails(JSONObject* data, unsigned elementCount)
+void TimelineRecordFactory::setStyleRecalcDetails(JSONObject* data, unsigned elementCount)
{
data->setNumber("elementCount", elementCount);
}
-void TimelineRecordFactory::appendImageDetails(JSONObject* data, long long imageElementId, const String& url)
+void TimelineRecordFactory::setImageDetails(JSONObject* data, long long imageElementId, const String& url)
{
if (imageElementId)
- data->setNumber("elementId", imageElementId);
+ data->setNumber("backendNodeId", imageElementId);
if (!url.isEmpty())
data->setString("url", url);
}
+PassRefPtr<JSONObject> TimelineRecordFactory::createEmbedderCallbackData(const String& callbackName)
+{
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setString("callbackName", callbackName);
+ return data.release();
+}
+
+String TimelineRecordFactory::type(TypeBuilder::Timeline::TimelineEvent* event)
+{
+ String type;
+ event->type(&type);
+ return type;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.h b/chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.h
index 67ac43f1993..871eec146c4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/TimelineRecordFactory.h
@@ -31,6 +31,7 @@
#ifndef TimelineRecordFactory_h
#define TimelineRecordFactory_h
+#include "core/InspectorTypeBuilder.h"
#include "platform/JSONValues.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
@@ -38,93 +39,74 @@
namespace WebCore {
- class Event;
- class FloatQuad;
- class InspectorFrontend;
- class IntRect;
- class ResourceRequest;
- class ResourceResponse;
-
- class TimelineRecordFactory {
- public:
- static PassRefPtr<JSONObject> createGenericRecord(double startTime, int maxCallStackDepth, const String& type);
- static PassRefPtr<JSONObject> createBackgroundRecord(double startTime, const String& thread, const String& type, PassRefPtr<JSONObject> data = 0);
-
- static PassRefPtr<JSONObject> createGCEventData(size_t usedHeapSizeDelta);
-
- static PassRefPtr<JSONObject> createFunctionCallData(const String& scriptName, int scriptLine);
-
- static PassRefPtr<JSONObject> createEventDispatchData(const Event&);
-
- static PassRefPtr<JSONObject> createGenericTimerData(int timerId);
-
- static PassRefPtr<JSONObject> createTimerInstallData(int timerId, int timeout, bool singleShot);
-
- static PassRefPtr<JSONObject> createXHRReadyStateChangeData(const String& url, int readyState);
-
- static PassRefPtr<JSONObject> createXHRLoadData(const String& url);
-
- static PassRefPtr<JSONObject> createEvaluateScriptData(const String&, double lineNumber);
-
- static PassRefPtr<JSONObject> createTimeStampData(const String&);
-
- static PassRefPtr<JSONObject> createResourceSendRequestData(const String& requestId, const ResourceRequest&);
-
- static PassRefPtr<JSONObject> createScheduleResourceRequestData(const String&);
-
- static PassRefPtr<JSONObject> createResourceReceiveResponseData(const String& requestId, const ResourceResponse&);
-
- static PassRefPtr<JSONObject> createReceiveResourceData(const String& requestId, int length);
-
- static PassRefPtr<JSONObject> createResourceFinishData(const String& requestId, bool didFail, double finishTime);
-
- static PassRefPtr<JSONObject> createLayoutData(unsigned dirtyObjects, unsigned totalObjects, bool partialLayout);
-
- static PassRefPtr<JSONObject> createDecodeImageData(const String& imageType);
-
- static PassRefPtr<JSONObject> createResizeImageData(bool shouldCache);
-
- static PassRefPtr<JSONObject> createMarkData(bool isMainFrame);
-
- static PassRefPtr<JSONObject> createParseHTMLData(unsigned startLine);
-
- static PassRefPtr<JSONObject> createAnimationFrameData(int callbackId);
-
- static PassRefPtr<JSONObject> createNodeData(long long nodeId);
-
- static PassRefPtr<JSONObject> createLayerData(long long layerRootNodeId);
-
- static PassRefPtr<JSONObject> createPaintData(const FloatQuad&, long long layerRootNodeId, int graphicsLayerId);
-
- static PassRefPtr<JSONObject> createFrameData(int frameId);
-
- static PassRefPtr<JSONObject> createGPUTaskData(bool foreign, size_t usedGPUMemoryBytes);
-
- static void appendLayoutRoot(JSONObject* data, const FloatQuad&, long long rootNodeId);
-
- static void appendStyleRecalcDetails(JSONObject* data, unsigned elementCount);
-
- static void appendImageDetails(JSONObject* data, long long imageElementId, const String& url);
-
- static inline PassRefPtr<JSONObject> createWebSocketCreateData(unsigned long identifier, const KURL& url, const String& protocol)
- {
- RefPtr<JSONObject> data = JSONObject::create();
- data->setNumber("identifier", identifier);
- data->setString("url", url.string());
- if (!protocol.isNull())
- data->setString("webSocketProtocol", protocol);
- return data.release();
- }
-
- static inline PassRefPtr<JSONObject> createGenericWebSocketData(unsigned long identifier)
- {
- RefPtr<JSONObject> data = JSONObject::create();
- data->setNumber("identifier", identifier);
- return data.release();
- }
- private:
- TimelineRecordFactory() { }
- };
+class Event;
+class FloatQuad;
+class InspectorFrontend;
+class IntRect;
+class ResourceRequest;
+class ResourceResponse;
+
+class TimelineRecordFactory {
+public:
+ static PassRefPtr<TypeBuilder::Timeline::TimelineEvent> createGenericRecord(double startTime, int maxCallStackDepth, const String& type, PassRefPtr<JSONObject> data);
+ static PassRefPtr<TypeBuilder::Timeline::TimelineEvent> createBackgroundRecord(double startTime, const String& thread, const String& type, PassRefPtr<JSONObject> data);
+
+ static PassRefPtr<JSONObject> createGCEventData(size_t usedHeapSizeDelta);
+ static PassRefPtr<JSONObject> createFunctionCallData(int scriptId, const String& scriptName, int scriptLine);
+ static PassRefPtr<JSONObject> createEventDispatchData(const Event&);
+ static PassRefPtr<JSONObject> createGenericTimerData(int timerId);
+ static PassRefPtr<JSONObject> createTimerInstallData(int timerId, int timeout, bool singleShot);
+ static PassRefPtr<JSONObject> createXHRReadyStateChangeData(const String& url, int readyState);
+ static PassRefPtr<JSONObject> createXHRLoadData(const String& url);
+ static PassRefPtr<JSONObject> createEvaluateScriptData(const String&, double lineNumber);
+ static PassRefPtr<JSONObject> createConsoleTimeData(const String&);
+ static PassRefPtr<JSONObject> createTimeStampData(const String&);
+ static PassRefPtr<JSONObject> createResourceSendRequestData(const String& requestId, const ResourceRequest&);
+ static PassRefPtr<JSONObject> createResourceReceiveResponseData(const String& requestId, const ResourceResponse&);
+ static PassRefPtr<JSONObject> createReceiveResourceData(const String& requestId, int length);
+ static PassRefPtr<JSONObject> createResourceFinishData(const String& requestId, bool didFail, double finishTime);
+ static PassRefPtr<JSONObject> createLayoutData(unsigned dirtyObjects, unsigned totalObjects, bool partialLayout);
+ static PassRefPtr<JSONObject> createDecodeImageData(const String& imageType);
+ static PassRefPtr<JSONObject> createResizeImageData(bool shouldCache);
+ static PassRefPtr<JSONObject> createMarkData(bool isMainFrame);
+ static PassRefPtr<JSONObject> createParseHTMLData(unsigned startLine);
+ static PassRefPtr<JSONObject> createAnimationFrameData(int callbackId);
+ static PassRefPtr<JSONObject> createNodeData(long long nodeId);
+ static PassRefPtr<JSONObject> createLayerData(long long layerRootNodeId);
+ static PassRefPtr<JSONObject> createFrameData(int frameId);
+ static PassRefPtr<JSONObject> createGPUTaskData(bool foreign);
+
+ static void setNodeData(JSONObject* data, long long nodeId);
+ static void setLayerData(JSONObject* data, long long layerRootNodeId);
+ static void setLayerTreeData(JSONObject* data, PassRefPtr<JSONValue> layerTree);
+ static void setPaintData(JSONObject* data, const FloatQuad&, long long layerRootNodeId, int graphicsLayerId);
+ static void setLayoutRoot(JSONObject* data, const FloatQuad&, long long rootNodeId);
+ static void setStyleRecalcDetails(JSONObject* data, unsigned elementCount);
+ static void setImageDetails(JSONObject* data, long long imageElementId, const String& url);
+
+ static inline PassRefPtr<JSONObject> createWebSocketCreateData(unsigned long identifier, const KURL& url, const String& protocol)
+ {
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("identifier", identifier);
+ data->setString("url", url.string());
+ if (!protocol.isNull())
+ data->setString("webSocketProtocol", protocol);
+ return data.release();
+ }
+
+ static inline PassRefPtr<JSONObject> createGenericWebSocketData(unsigned long identifier)
+ {
+ RefPtr<JSONObject> data = JSONObject::create();
+ data->setNumber("identifier", identifier);
+ return data.release();
+ }
+
+ static PassRefPtr<JSONObject> createEmbedderCallbackData(const String& callbackName);
+
+ static String type(TypeBuilder::Timeline::TimelineEvent*);
+private:
+ TimelineRecordFactory() { }
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.cpp b/chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.cpp
index bdfbea6fe58..4c077d2f136 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.cpp
@@ -100,14 +100,17 @@ void TraceEventDispatcher::processBackgroundEvents()
void TraceEventDispatcher::innerAddListener(const char* name, char phase, TraceEventTargetBase* instance, TraceEventHandlerMethod method, InspectorClient* client)
{
+ static const char CategoryFilter[] = "-*," TRACE_DISABLED_BY_DEFAULT("devtools.timeline") "," TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame");
+
ASSERT(isMainThread());
MutexLocker locker(m_mutex);
if (m_handlers.isEmpty())
- client->setTraceEventCallback(dispatchEventOnAnyThread);
+ client->setTraceEventCallback(CategoryFilter, dispatchEventOnAnyThread);
HandlersMap::iterator it = m_handlers.find(std::make_pair(name, phase));
if (it == m_handlers.end())
- it = m_handlers.add(std::make_pair(name, phase), Vector<BoundTraceEventHandler>()).iterator;
- it->value.append(BoundTraceEventHandler(instance, method));
+ m_handlers.add(std::make_pair(name, phase), Vector<BoundTraceEventHandler>()).storedValue->value.append(BoundTraceEventHandler(instance, method));
+ else
+ it->value.append(BoundTraceEventHandler(instance, method));
}
void TraceEventDispatcher::removeAllListeners(TraceEventTargetBase* instance, InspectorClient* client)
@@ -132,7 +135,7 @@ void TraceEventDispatcher::removeAllListeners(TraceEventTargetBase* instance, In
m_handlers.swap(remainingHandlers);
}
if (m_handlers.isEmpty())
- client->setTraceEventCallback(0);
+ client->resetTraceEventCallback();
}
size_t TraceEventDispatcher::TraceEvent::findParameter(const char* name) const
@@ -148,11 +151,12 @@ const TraceEvent::TraceValueUnion& TraceEventDispatcher::TraceEvent::parameter(c
{
static WebCore::TraceEvent::TraceValueUnion missingValue;
size_t index = findParameter(name);
+ ASSERT(isMainThread());
if (index == kNotFound || m_argumentTypes[index] != expectedType) {
ASSERT_NOT_REACHED();
return missingValue;
}
- return *reinterpret_cast<const WebCore::TraceEvent::TraceValueUnion*>(m_argumentValues + index);
+ return m_argumentValues[index];
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.h b/chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.h
index 22e14e750ee..5fae9a8602d 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/TraceEventDispatcher.h
@@ -74,8 +74,14 @@ public:
}
for (int i = 0; i < m_argumentCount; ++i) {
m_argumentNames[i] = argumentNames[i];
- m_argumentTypes[i] = argumentTypes[i];
- m_argumentValues[i] = argumentValues[i];
+ if (argumentTypes[i] == TRACE_VALUE_TYPE_COPY_STRING) {
+ m_stringArguments[i] = reinterpret_cast<const char*>(argumentValues[i]);
+ m_argumentValues[i].m_string = reinterpret_cast<const char*>(m_stringArguments[i].characters8());
+ m_argumentTypes[i] = TRACE_VALUE_TYPE_STRING;
+ } else {
+ m_argumentValues[i].m_int = argumentValues[i];
+ m_argumentTypes[i] = argumentTypes[i];
+ }
}
}
@@ -127,7 +133,11 @@ public:
int m_argumentCount;
const char* m_argumentNames[MaxArguments];
unsigned char m_argumentTypes[MaxArguments];
- unsigned long long m_argumentValues[MaxArguments];
+ WebCore::TraceEvent::TraceValueUnion m_argumentValues[MaxArguments];
+ // These are only used as buffers for TRACE_VALUE_TYPE_COPY_STRING.
+ // Consider allocating the entire vector of buffered trace events and their copied arguments out of a special arena
+ // to make things more compact.
+ String m_stringArguments[MaxArguments];
};
typedef void (TraceEventTargetBase::*TraceEventHandlerMethod)(const TraceEvent&);
diff --git a/chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp
index f6b912adfa4..754ddcfebdb 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.cpp
@@ -34,8 +34,8 @@
namespace WebCore {
-WorkerConsoleAgent::WorkerConsoleAgent(InstrumentingAgents* instrumentingAgents, InspectorTimelineAgent* timelineAgent, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager)
- : InspectorConsoleAgent(instrumentingAgents, timelineAgent, state, injectedScriptManager)
+WorkerConsoleAgent::WorkerConsoleAgent(InspectorTimelineAgent* timelineAgent, InjectedScriptManager* injectedScriptManager)
+ : InspectorConsoleAgent(timelineAgent, injectedScriptManager)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h b/chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h
index e886da70100..676a42aff79 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/WorkerConsoleAgent.h
@@ -36,20 +36,20 @@
namespace WebCore {
-class WorkerConsoleAgent : public InspectorConsoleAgent {
+class WorkerConsoleAgent FINAL : public InspectorConsoleAgent {
WTF_MAKE_NONCOPYABLE(WorkerConsoleAgent);
public:
- static PassOwnPtr<WorkerConsoleAgent> create(InstrumentingAgents* instrumentingAgents, InspectorTimelineAgent* timelineAgent, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager)
+ static PassOwnPtr<WorkerConsoleAgent> create(InspectorTimelineAgent* timelineAgent, InjectedScriptManager* injectedScriptManager)
{
- return adoptPtr(new WorkerConsoleAgent(instrumentingAgents, timelineAgent, state, injectedScriptManager));
+ return adoptPtr(new WorkerConsoleAgent(timelineAgent, injectedScriptManager));
}
virtual ~WorkerConsoleAgent();
virtual bool isWorkerAgent() OVERRIDE { return true; }
private:
- WorkerConsoleAgent(InstrumentingAgents*, InspectorTimelineAgent*, InspectorCompositeState*, InjectedScriptManager*);
- virtual void addInspectedNode(ErrorString*, int nodeId);
+ WorkerConsoleAgent(InspectorTimelineAgent*, InjectedScriptManager*);
+ virtual void addInspectedNode(ErrorString*, int nodeId) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.cpp
index 271c306e156..52d2b4d4f5c 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.cpp
@@ -55,36 +55,31 @@ WorkerDebuggerAgents& workerDebuggerAgents()
}
-class RunInspectorCommandsTask : public ScriptDebugServer::Task {
+class RunInspectorCommandsTask FINAL : public ScriptDebugServer::Task {
public:
- RunInspectorCommandsTask(WorkerThread* thread, WorkerGlobalScope* workerGlobalScope)
- : m_thread(thread)
- , m_workerGlobalScope(workerGlobalScope) { }
+ explicit RunInspectorCommandsTask(WorkerThread* thread)
+ : m_thread(thread) { }
virtual ~RunInspectorCommandsTask() { }
- virtual void run()
+ virtual void run() OVERRIDE
{
- // Process all queued debugger commands. It is safe to use m_workerGlobalScope here
- // because it is alive if RunWorkerLoop is not terminated, otherwise it will
- // just be ignored. WorkerThread is certainly alive if this task is being executed.
- while (MessageQueueMessageReceived == m_thread->runLoop().runInMode(m_workerGlobalScope, WorkerDebuggerAgent::debuggerTaskMode, WorkerRunLoop::DontWaitForMessage)) { }
+ // Process all queued debugger commands. WorkerThread is certainly
+ // alive if this task is being executed.
+ while (MessageQueueMessageReceived == m_thread->runLoop().runDebuggerTask(WorkerRunLoop::DontWaitForMessage)) { }
}
private:
WorkerThread* m_thread;
- WorkerGlobalScope* m_workerGlobalScope;
};
} // namespace
-const char WorkerDebuggerAgent::debuggerTaskMode[] = "debugger";
-
-PassOwnPtr<WorkerDebuggerAgent> WorkerDebuggerAgent::create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, WorkerScriptDebugServer* scriptDebugServer, WorkerGlobalScope* inspectedWorkerGlobalScope, InjectedScriptManager* injectedScriptManager)
+PassOwnPtr<WorkerDebuggerAgent> WorkerDebuggerAgent::create(WorkerScriptDebugServer* scriptDebugServer, WorkerGlobalScope* inspectedWorkerGlobalScope, InjectedScriptManager* injectedScriptManager)
{
- return adoptPtr(new WorkerDebuggerAgent(instrumentingAgents, inspectorState, scriptDebugServer, inspectedWorkerGlobalScope, injectedScriptManager));
+ return adoptPtr(new WorkerDebuggerAgent(scriptDebugServer, inspectedWorkerGlobalScope, injectedScriptManager));
}
-WorkerDebuggerAgent::WorkerDebuggerAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* inspectorState, WorkerScriptDebugServer* scriptDebugServer, WorkerGlobalScope* inspectedWorkerGlobalScope, InjectedScriptManager* injectedScriptManager)
- : InspectorDebuggerAgent(instrumentingAgents, inspectorState, injectedScriptManager)
+WorkerDebuggerAgent::WorkerDebuggerAgent(WorkerScriptDebugServer* scriptDebugServer, WorkerGlobalScope* inspectedWorkerGlobalScope, InjectedScriptManager* injectedScriptManager)
+ : InspectorDebuggerAgent(injectedScriptManager)
, m_scriptDebugServer(scriptDebugServer)
, m_inspectedWorkerGlobalScope(inspectedWorkerGlobalScope)
{
@@ -104,7 +99,7 @@ void WorkerDebuggerAgent::interruptAndDispatchInspectorCommands(WorkerThread* th
MutexLocker lock(workerDebuggerAgentsMutex());
WorkerDebuggerAgent* agent = workerDebuggerAgents().get(thread);
if (agent)
- agent->m_scriptDebugServer->interruptAndRunTask(adoptPtr(new RunInspectorCommandsTask(thread, agent->m_inspectedWorkerGlobalScope)));
+ agent->m_scriptDebugServer->interruptAndRunTask(adoptPtr(new RunInspectorCommandsTask(thread)));
}
void WorkerDebuggerAgent::startListeningScriptDebugServer()
@@ -128,8 +123,7 @@ InjectedScript WorkerDebuggerAgent::injectedScriptForEval(ErrorString* error, co
*error = "Execution context id is not supported for workers as there is only one execution context.";
return InjectedScript();
}
- ScriptState* scriptState = scriptStateFromWorkerGlobalScope(m_inspectedWorkerGlobalScope);
- return injectedScriptManager()->injectedScriptFor(scriptState);
+ return injectedScriptManager()->injectedScriptFor(m_inspectedWorkerGlobalScope->script()->scriptState());
}
void WorkerDebuggerAgent::muteConsole()
diff --git a/chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.h b/chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.h
index dee9dbf8e24..2383bfd13b3 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/WorkerDebuggerAgent.h
@@ -39,25 +39,24 @@ namespace WebCore {
class WorkerGlobalScope;
class WorkerThread;
-class WorkerDebuggerAgent : public InspectorDebuggerAgent {
+class WorkerDebuggerAgent FINAL : public InspectorDebuggerAgent {
WTF_MAKE_NONCOPYABLE(WorkerDebuggerAgent);
WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<WorkerDebuggerAgent> create(InstrumentingAgents*, InspectorCompositeState*, WorkerScriptDebugServer*, WorkerGlobalScope*, InjectedScriptManager*);
+ static PassOwnPtr<WorkerDebuggerAgent> create(WorkerScriptDebugServer*, WorkerGlobalScope*, InjectedScriptManager*);
virtual ~WorkerDebuggerAgent();
- static const char debuggerTaskMode[];
static void interruptAndDispatchInspectorCommands(WorkerThread*);
private:
- WorkerDebuggerAgent(InstrumentingAgents*, InspectorCompositeState*, WorkerScriptDebugServer*, WorkerGlobalScope*, InjectedScriptManager*);
+ WorkerDebuggerAgent(WorkerScriptDebugServer*, WorkerGlobalScope*, InjectedScriptManager*);
- virtual void startListeningScriptDebugServer();
- virtual void stopListeningScriptDebugServer();
- virtual WorkerScriptDebugServer& scriptDebugServer();
- virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId);
- virtual void muteConsole();
- virtual void unmuteConsole();
+ virtual void startListeningScriptDebugServer() OVERRIDE;
+ virtual void stopListeningScriptDebugServer() OVERRIDE;
+ virtual WorkerScriptDebugServer& scriptDebugServer() OVERRIDE;
+ virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) OVERRIDE;
+ virtual void muteConsole() OVERRIDE;
+ virtual void unmuteConsole() OVERRIDE;
WorkerScriptDebugServer* m_scriptDebugServer;
WorkerGlobalScope* m_inspectedWorkerGlobalScope;
diff --git a/chromium/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp b/chromium/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp
index 3fac1b3c6e2..1a62be87308 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp
@@ -32,13 +32,14 @@
#include "core/inspector/WorkerInspectorController.h"
-#include "InspectorBackendDispatcher.h"
-#include "InspectorFrontend.h"
+#include "core/InspectorBackendDispatcher.h"
+#include "core/InspectorFrontend.h"
#include "core/inspector/InjectedScriptHost.h"
#include "core/inspector/InjectedScriptManager.h"
#include "core/inspector/InspectorConsoleAgent.h"
#include "core/inspector/InspectorFrontendChannel.h"
#include "core/inspector/InspectorHeapProfilerAgent.h"
+#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/InspectorProfilerAgent.h"
#include "core/inspector/InspectorState.h"
#include "core/inspector/InspectorStateClient.h"
@@ -56,28 +57,28 @@ namespace WebCore {
namespace {
-class PageInspectorProxy : public InspectorFrontendChannel {
+class PageInspectorProxy FINAL : public InspectorFrontendChannel {
WTF_MAKE_FAST_ALLOCATED;
public:
explicit PageInspectorProxy(WorkerGlobalScope* workerGlobalScope) : m_workerGlobalScope(workerGlobalScope) { }
virtual ~PageInspectorProxy() { }
private:
- virtual bool sendMessageToFrontend(const String& message)
+ virtual void sendMessageToFrontend(PassRefPtr<JSONObject> message) OVERRIDE
{
- m_workerGlobalScope->thread()->workerReportingProxy().postMessageToPageInspector(message);
- return true;
+ m_workerGlobalScope->thread()->workerReportingProxy().postMessageToPageInspector(message->toJSONString());
}
+ virtual void flush() OVERRIDE { }
WorkerGlobalScope* m_workerGlobalScope;
};
-class WorkerStateClient : public InspectorStateClient {
+class WorkerStateClient FINAL : public InspectorStateClient {
WTF_MAKE_FAST_ALLOCATED;
public:
WorkerStateClient(WorkerGlobalScope* context) : m_workerGlobalScope(context) { }
virtual ~WorkerStateClient() { }
private:
- virtual void updateInspectorStateCookie(const String& cookie)
+ virtual void updateInspectorStateCookie(const String& cookie) OVERRIDE
{
m_workerGlobalScope->thread()->workerReportingProxy().updateInspectorStateCookie(cookie);
}
@@ -93,16 +94,17 @@ WorkerInspectorController::WorkerInspectorController(WorkerGlobalScope* workerGl
, m_state(adoptPtr(new InspectorCompositeState(m_stateClient.get())))
, m_instrumentingAgents(InstrumentingAgents::create())
, m_injectedScriptManager(InjectedScriptManager::createForWorker())
- , m_debugServer(adoptPtr(new WorkerScriptDebugServer(workerGlobalScope, WorkerDebuggerAgent::debuggerTaskMode)))
+ , m_debugServer(adoptPtr(new WorkerScriptDebugServer(workerGlobalScope)))
+ , m_agents(m_instrumentingAgents.get(), m_state.get())
{
- m_agents.append(WorkerRuntimeAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get(), m_debugServer.get(), workerGlobalScope));
+ m_agents.append(WorkerRuntimeAgent::create(m_injectedScriptManager.get(), m_debugServer.get(), workerGlobalScope));
- OwnPtr<InspectorTimelineAgent> timelineAgent = InspectorTimelineAgent::create(m_instrumentingAgents.get(), 0, 0, 0, 0, m_state.get(), InspectorTimelineAgent::WorkerInspector, 0);
- m_agents.append(WorkerDebuggerAgent::create(m_instrumentingAgents.get(), m_state.get(), m_debugServer.get(), workerGlobalScope, m_injectedScriptManager.get()));
+ OwnPtr<InspectorTimelineAgent> timelineAgent = InspectorTimelineAgent::create(0, 0, 0, InspectorTimelineAgent::WorkerInspector, 0);
+ m_agents.append(WorkerDebuggerAgent::create(m_debugServer.get(), workerGlobalScope, m_injectedScriptManager.get()));
- m_agents.append(InspectorProfilerAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get(), 0));
- m_agents.append(InspectorHeapProfilerAgent::create(m_instrumentingAgents.get(), m_state.get(), m_injectedScriptManager.get()));
- m_agents.append(WorkerConsoleAgent::create(m_instrumentingAgents.get(), timelineAgent.get(), m_state.get(), m_injectedScriptManager.get()));
+ m_agents.append(InspectorProfilerAgent::create(m_injectedScriptManager.get(), 0));
+ m_agents.append(InspectorHeapProfilerAgent::create(m_injectedScriptManager.get()));
+ m_agents.append(WorkerConsoleAgent::create(timelineAgent.get(), m_injectedScriptManager.get()));
m_agents.append(timelineAgent.release());
m_injectedScriptManager->injectedScriptHost()->init(m_instrumentingAgents.get(), m_debugServer.get());
@@ -123,6 +125,7 @@ void WorkerInspectorController::connectFrontend()
m_backendDispatcher = InspectorBackendDispatcher::create(m_frontendChannel.get());
m_agents.registerInDispatcher(m_backendDispatcher.get());
m_agents.setFrontend(m_frontend.get());
+ InspectorInstrumentation::frontendCreated();
}
void WorkerInspectorController::disconnectFrontend()
@@ -136,6 +139,7 @@ void WorkerInspectorController::disconnectFrontend()
m_state->mute();
m_agents.clearFrontend();
m_frontend.clear();
+ InspectorInstrumentation::frontendDeleted();
m_frontendChannel.clear();
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.cpp b/chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.cpp
index d3d0c3fdb8d..ff453d9e2b4 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.cpp
+++ b/chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.cpp
@@ -42,12 +42,11 @@
namespace WebCore {
-WorkerRuntimeAgent::WorkerRuntimeAgent(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer, WorkerGlobalScope* workerGlobalScope)
- : InspectorRuntimeAgent(instrumentingAgents, state, injectedScriptManager, scriptDebugServer)
+WorkerRuntimeAgent::WorkerRuntimeAgent(InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer, WorkerGlobalScope* workerGlobalScope)
+ : InspectorRuntimeAgent(injectedScriptManager, scriptDebugServer)
, m_workerGlobalScope(workerGlobalScope)
, m_paused(false)
{
- m_instrumentingAgents->setWorkerRuntimeAgent(this);
}
WorkerRuntimeAgent::~WorkerRuntimeAgent()
@@ -55,14 +54,29 @@ WorkerRuntimeAgent::~WorkerRuntimeAgent()
m_instrumentingAgents->setWorkerRuntimeAgent(0);
}
+void WorkerRuntimeAgent::init()
+{
+ m_instrumentingAgents->setWorkerRuntimeAgent(this);
+}
+
+void WorkerRuntimeAgent::enable(ErrorString* errorString)
+{
+ if (m_enabled)
+ return;
+
+ InspectorRuntimeAgent::enable(errorString);
+ addExecutionContextToFrontend(m_workerGlobalScope->script()->scriptState(), true, m_workerGlobalScope->url(), "");
+}
+
InjectedScript WorkerRuntimeAgent::injectedScriptForEval(ErrorString* error, const int* executionContextId)
{
- if (executionContextId) {
- *error = "Execution context id is not supported for workers as there is only one execution context.";
- return InjectedScript();
- }
- ScriptState* scriptState = scriptStateFromWorkerGlobalScope(m_workerGlobalScope);
- return injectedScriptManager()->injectedScriptFor(scriptState);
+ if (!executionContextId)
+ return injectedScriptManager()->injectedScriptFor(m_workerGlobalScope->script()->scriptState());
+
+ InjectedScript injectedScript = injectedScriptManager()->injectedScriptForId(*executionContextId);
+ if (injectedScript.isEmpty())
+ *error = "Execution context with given id not found.";
+ return injectedScript;
}
void WorkerRuntimeAgent::muteConsole()
@@ -80,6 +94,11 @@ void WorkerRuntimeAgent::run(ErrorString*)
m_paused = false;
}
+void WorkerRuntimeAgent::isRunRequired(ErrorString*, bool* out_result)
+{
+ *out_result = m_paused;
+}
+
void WorkerRuntimeAgent::willEvaluateWorkerScript(WorkerGlobalScope* context, int workerThreadStartMode)
{
if (workerThreadStartMode != PauseWorkerGlobalScopeOnStart)
@@ -88,7 +107,7 @@ void WorkerRuntimeAgent::willEvaluateWorkerScript(WorkerGlobalScope* context, in
m_paused = true;
MessageQueueWaitResult result;
do {
- result = context->thread()->runLoop().runInMode(context, WorkerDebuggerAgent::debuggerTaskMode);
+ result = context->thread()->runLoop().runDebuggerTask();
// Keep waiting until execution is resumed.
} while (result == MessageQueueMessageReceived && m_paused);
}
diff --git a/chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.h b/chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.h
index 745baf22115..2ad5f0ac522 100644
--- a/chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.h
+++ b/chromium/third_party/WebKit/Source/core/inspector/WorkerRuntimeAgent.h
@@ -38,24 +38,28 @@ namespace WebCore {
class WorkerGlobalScope;
-class WorkerRuntimeAgent : public InspectorRuntimeAgent {
+class WorkerRuntimeAgent FINAL : public InspectorRuntimeAgent {
public:
- static PassOwnPtr<WorkerRuntimeAgent> create(InstrumentingAgents* instrumentingAgents, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer, WorkerGlobalScope* context)
+ static PassOwnPtr<WorkerRuntimeAgent> create(InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer, WorkerGlobalScope* context)
{
- return adoptPtr(new WorkerRuntimeAgent(instrumentingAgents, state, injectedScriptManager, scriptDebugServer, context));
+ return adoptPtr(new WorkerRuntimeAgent(injectedScriptManager, scriptDebugServer, context));
}
virtual ~WorkerRuntimeAgent();
+ virtual void init() OVERRIDE;
+ virtual void enable(ErrorString*) OVERRIDE;
+
// Protocol commands.
- virtual void run(ErrorString*);
+ virtual void run(ErrorString*) OVERRIDE;
+ virtual void isRunRequired(ErrorString*, bool* out_result) OVERRIDE;
void willEvaluateWorkerScript(WorkerGlobalScope*, int workerThreadStartMode);
private:
- WorkerRuntimeAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*, ScriptDebugServer*, WorkerGlobalScope*);
- virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId);
- virtual void muteConsole();
- virtual void unmuteConsole();
+ WorkerRuntimeAgent(InjectedScriptManager*, ScriptDebugServer*, WorkerGlobalScope*);
+ virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) OVERRIDE;
+ virtual void muteConsole() OVERRIDE;
+ virtual void unmuteConsole() OVERRIDE;
WorkerGlobalScope* m_workerGlobalScope;
bool m_paused;
};
diff --git a/chromium/third_party/WebKit/Source/core/inspector/combine-javascript-resources.pl b/chromium/third_party/WebKit/Source/core/inspector/combine-javascript-resources.pl
deleted file mode 100755
index 428b6b7d005..00000000000
--- a/chromium/third_party/WebKit/Source/core/inspector/combine-javascript-resources.pl
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/usr/bin/perl -w
-
-# Copyright (C) 2008 Apple Inc. All Rights Reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
-# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# Script to combine multiple JavaScript files into one file, based on
-# the script tags in the head of an input HTML file.
-
-use strict;
-use Getopt::Long;
-use File::Basename;
-use File::Path;
-
-my $generatedScriptsDirectory;
-my $outputDirectory;
-my $scriptName;
-my $htmlFile;
-
-GetOptions('output-dir=s' => \$outputDirectory,
- 'output-script-name=s' => \$scriptName,
- 'generated-scripts-dir=s' => \$generatedScriptsDirectory,
- 'input-html=s' => \$htmlFile);
-
-unless (defined $htmlFile and defined $scriptName and defined $outputDirectory) {
- print "Usage: $0 --input-html <path> --output-dir path --output-script-name <name>\n";
- exit;
-}
-
-my $htmlDirectory = dirname($htmlFile);
-my $htmlContents;
-
-{
- local $/;
- open HTML, $htmlFile or die;
- $htmlContents = <HTML>;
- close HTML;
-}
-
-$htmlContents =~ m/<head>(.*)<\/head>/si;
-my $headContents = $1;
-
-mkpath $outputDirectory;
-open SCRIPT_OUT, ">", "$outputDirectory/$scriptName" or die "Can't open $outputDirectory/$scriptName: $!";
-
-while ($headContents =~ m/<script.*src="([^"]*)"[^>]*>/gi) {
- local $/;
- open SCRIPT_IN, "$generatedScriptsDirectory/$1" or open SCRIPT_IN, "$htmlDirectory/$1" or die "Can't open $htmlDirectory/$1: $!";
- print SCRIPT_OUT "/* $1 */\n\n";
- print SCRIPT_OUT <SCRIPT_IN>;
- close SCRIPT_IN;
-}
-
-close SCRIPT_OUT;
-
-$headContents =~ s/<script.*src="[^"]*"[^>]*><\/script>\s*//gi;
-$headContents .= "<script type=\"text/javascript\" src=\"$scriptName\"></script>\n";
-$htmlContents =~ s/<head>.*<\/head>/<head>$headContents<\/head>/si;
-
-open HTML, ">", "$outputDirectory/" . basename($htmlFile) or die "Can't open $outputDirectory/" . basename($htmlFile) . ": $!";
-print HTML $htmlContents;
-close HTML;
diff --git a/chromium/third_party/WebKit/Source/core/loader/BeaconLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/BeaconLoader.cpp
new file mode 100644
index 00000000000..f89cfdbe3b1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/BeaconLoader.cpp
@@ -0,0 +1,130 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/loader/BeaconLoader.h"
+
+#include "core/FetchInitiatorTypeNames.h"
+#include "core/dom/Document.h"
+#include "core/fetch/CrossOriginAccessControl.h"
+#include "core/fetch/FetchContext.h"
+#include "core/fileapi/File.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/DOMFormData.h"
+#include "platform/network/FormData.h"
+#include "platform/network/ParsedContentType.h"
+#include "platform/network/ResourceRequest.h"
+#include "wtf/ArrayBufferView.h"
+
+namespace WebCore {
+
+void BeaconLoader::prepareRequest(LocalFrame* frame, ResourceRequest& request)
+{
+ // NOTE: do not distinguish Beacon by target type.
+ request.setTargetType(ResourceRequest::TargetIsPing);
+ request.setHTTPMethod("POST");
+ request.setHTTPHeaderField("Cache-Control", "max-age=0");
+ request.setAllowStoredCredentials(true);
+ frame->loader().fetchContext().addAdditionalRequestHeaders(frame->document(), request, FetchSubresource);
+ frame->loader().fetchContext().setFirstPartyForCookies(request);
+}
+
+void BeaconLoader::issueRequest(LocalFrame* frame, ResourceRequest& request)
+{
+ FetchInitiatorInfo initiatorInfo;
+ initiatorInfo.name = FetchInitiatorTypeNames::beacon;
+
+ PingLoader::start(frame, request, initiatorInfo);
+}
+
+bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, const String& data, int& payloadLength)
+{
+ ResourceRequest request(beaconURL);
+ prepareRequest(frame, request);
+
+ RefPtr<FormData> entityBody = FormData::create(data.utf8());
+ unsigned long long entitySize = entityBody->sizeInBytes();
+ if (allowance > 0 && static_cast<unsigned>(allowance) < entitySize)
+ return false;
+
+ request.setHTTPBody(entityBody);
+ request.setHTTPContentType("text/plain;charset=UTF-8");
+
+ issueRequest(frame, request);
+ payloadLength = entitySize;
+ return true;
+}
+
+bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtr<ArrayBufferView>& data, int& payloadLength)
+{
+ ASSERT(data);
+ unsigned long long entitySize = data->byteLength();
+ if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
+ return false;
+
+ ResourceRequest request(beaconURL);
+ prepareRequest(frame, request);
+
+ RefPtr<FormData> entityBody = FormData::create(data->baseAddress(), data->byteLength());
+ request.setHTTPBody(entityBody.release());
+
+ // FIXME: a reasonable choice, but not in the spec; should it give a default?
+ AtomicString contentType = AtomicString("application/octet-stream");
+ request.setHTTPContentType(contentType);
+
+ issueRequest(frame, request);
+ payloadLength = entitySize;
+ return true;
+}
+
+bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtrWillBeRawPtr<Blob>& data, int& payloadLength)
+{
+ ASSERT(data);
+ unsigned long long entitySize = data->size();
+ if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
+ return false;
+
+ ResourceRequest request(beaconURL);
+ prepareRequest(frame, request);
+
+ RefPtr<FormData> entityBody = FormData::create();
+ if (data->hasBackingFile())
+ entityBody->appendFile(toFile(data.get())->path());
+ else
+ entityBody->appendBlob(data->uuid(), data->blobDataHandle());
+
+ request.setHTTPBody(entityBody.release());
+
+ AtomicString contentType;
+ const String& blobType = data->type();
+ if (!blobType.isEmpty() && isValidContentType(blobType))
+ request.setHTTPContentType(AtomicString(contentType));
+
+ issueRequest(frame, request);
+ payloadLength = entitySize;
+ return true;
+}
+
+bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, PassRefPtrWillBeRawPtr<DOMFormData>& data, int& payloadLength)
+{
+ ASSERT(data);
+ ResourceRequest request(beaconURL);
+ prepareRequest(frame, request);
+
+ RefPtr<FormData> entityBody = data->createMultiPartFormData();
+
+ unsigned long long entitySize = entityBody->sizeInBytes();
+ if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize)
+ return false;
+
+ AtomicString contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + entityBody->boundary().data();
+ request.setHTTPBody(entityBody.release());
+ request.setHTTPContentType(contentType);
+
+ issueRequest(frame, request);
+ payloadLength = entitySize;
+ return true;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/BeaconLoader.h b/chromium/third_party/WebKit/Source/core/loader/BeaconLoader.h
new file mode 100644
index 00000000000..9c403ae7641
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/BeaconLoader.h
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BeaconLoader_h
+#define BeaconLoader_h
+
+#include "core/loader/PingLoader.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+
+namespace WTF {
+class ArrayBufferView;
+}
+
+namespace WebCore {
+
+class Blob;
+class DOMFormData;
+class KURL;
+class LocalFrame;
+
+// Issue asynchronous beacon transmission loads independent of LocalFrame
+// staying alive. PingLoader providing the service.
+class BeaconLoader FINAL : public PingLoader {
+ WTF_MAKE_NONCOPYABLE(BeaconLoader);
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ virtual ~BeaconLoader() { }
+
+ static bool sendBeacon(LocalFrame*, int, const KURL&, const String&, int&);
+ static bool sendBeacon(LocalFrame*, int, const KURL&, PassRefPtr<WTF::ArrayBufferView>&, int&);
+ static bool sendBeacon(LocalFrame*, int, const KURL&, PassRefPtrWillBeRawPtr<Blob>&, int&);
+ static bool sendBeacon(LocalFrame*, int, const KURL&, PassRefPtrWillBeRawPtr<DOMFormData>&, int&);
+
+private:
+ static void prepareRequest(LocalFrame*, ResourceRequest&);
+ static void issueRequest(LocalFrame*, ResourceRequest&);
+};
+
+} // namespace WebCore
+
+#endif // BeaconLoader_h
diff --git a/chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp b/chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp
index 4ba0ca173d5..6fffb509612 100644
--- a/chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/CookieJar.cpp
@@ -32,8 +32,8 @@
#include "core/loader/CookieJar.h"
#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
#include "platform/Cookie.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCookie.h"
@@ -47,12 +47,7 @@ static blink::WebCookieJar* toCookieJar(const Document* document)
{
if (!document || !document->frame())
return 0;
- blink::WebCookieJar* cookieJar = document->frame()->loader().client()->cookieJar();
- // FIXME: DRT depends on being able to get a cookie jar from Platform rather than
- // FrameLoaderClient. Delete this when DRT is deleted.
- if (!cookieJar)
- cookieJar = blink::Platform::current()->cookieJar();
- return cookieJar;
+ return document->frame()->loader().client()->cookieJar();
}
String cookies(const Document* document, const KURL& url)
diff --git a/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp b/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp
index 460e2e9f826..d2a119b9aa9 100644
--- a/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.cpp
@@ -35,8 +35,6 @@
namespace WebCore {
-using namespace std;
-
// These values are at the discretion of the user agent.
static const unsigned defaultPreflightCacheTimeoutSeconds = 5;
static const unsigned maxPreflightCacheTimeoutSeconds = 600; // Should be short enough to minimize the risk of using a poisoned cache after switching to a secure network.
@@ -157,13 +155,13 @@ CrossOriginPreflightResultCache& CrossOriginPreflightResultCache::shared()
void CrossOriginPreflightResultCache::appendEntry(const String& origin, const KURL& url, PassOwnPtr<CrossOriginPreflightResultCacheItem> preflightResult)
{
ASSERT(isMainThread());
- m_preflightHashMap.set(make_pair(origin, url), preflightResult);
+ m_preflightHashMap.set(std::make_pair(origin, url), preflightResult);
}
bool CrossOriginPreflightResultCache::canSkipPreflight(const String& origin, const KURL& url, StoredCredentials includeCredentials, const String& method, const HTTPHeaderMap& requestHeaders)
{
ASSERT(isMainThread());
- CrossOriginPreflightResultHashMap::iterator cacheIt = m_preflightHashMap.find(make_pair(origin, url));
+ CrossOriginPreflightResultHashMap::iterator cacheIt = m_preflightHashMap.find(std::make_pair(origin, url));
if (cacheIt == m_preflightHashMap.end())
return false;
@@ -174,10 +172,4 @@ bool CrossOriginPreflightResultCache::canSkipPreflight(const String& origin, con
return false;
}
-void CrossOriginPreflightResultCache::empty()
-{
- ASSERT(isMainThread());
- m_preflightHashMap.clear();
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h b/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h
index 1c65c968c22..434555d85bc 100644
--- a/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h
+++ b/chromium/third_party/WebKit/Source/core/loader/CrossOriginPreflightResultCache.h
@@ -73,8 +73,6 @@ namespace WebCore {
void appendEntry(const String& origin, const KURL&, PassOwnPtr<CrossOriginPreflightResultCacheItem>);
bool canSkipPreflight(const String& origin, const KURL&, StoredCredentials, const String& method, const HTTPHeaderMap& requestHeaders);
- void empty();
-
private:
CrossOriginPreflightResultCache() { }
diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h b/chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h
index 28db5d55de3..56eb2beee4f 100644
--- a/chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h
+++ b/chromium/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h
@@ -30,7 +30,7 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class KURL;
class DocumentLoadTiming {
@@ -46,8 +46,6 @@ public:
void markUnloadEventStart() { m_unloadEventStart = monotonicallyIncreasingTime(); }
void markUnloadEventEnd() { m_unloadEventEnd = monotonicallyIncreasingTime(); }
- void markRedirectStart() { m_redirectStart = monotonicallyIncreasingTime(); }
- void markRedirectEnd() { m_redirectEnd = monotonicallyIncreasingTime(); }
void markFetchStart() { m_fetchStart = monotonicallyIncreasingTime(); }
void setResponseEnd(double monotonicTime) { m_responseEnd = monotonicTime; }
void markLoadEventStart() { m_loadEventStart = monotonicallyIncreasingTime(); }
diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
index 79122f88347..af913e35e44 100644
--- a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -30,24 +30,23 @@
#include "config.h"
#include "core/loader/DocumentLoader.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentParser.h"
#include "core/events/Event.h"
-#include "core/fetch/FetchContext.h"
#include "core/fetch/MemoryCache.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ResourceLoader.h"
-#include "core/fetch/TextResourceDecoder.h"
#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/loader/UniqueIdentifier.h"
#include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/page/FrameTree.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
@@ -60,6 +59,7 @@
#include "platform/weborigin/SecurityPolicy.h"
#include "public/platform/Platform.h"
#include "public/platform/WebMimeRegistry.h"
+#include "public/platform/WebThreadedDataReceiver.h"
#include "wtf/Assertions.h"
#include "wtf/text/WTFString.h"
@@ -70,21 +70,17 @@ static bool isArchiveMIMEType(const String& mimeType)
return mimeType == "multipart/related";
}
-DocumentLoader::DocumentLoader(const ResourceRequest& req, const SubstituteData& substituteData)
- : m_deferMainResourceDataLoad(true)
- , m_frame(0)
+DocumentLoader::DocumentLoader(LocalFrame* frame, const ResourceRequest& req, const SubstituteData& substituteData)
+ : m_frame(frame)
, m_fetcher(ResourceFetcher::create(this))
, m_originalRequest(req)
, m_substituteData(substituteData)
- , m_originalRequestCopy(req)
, m_request(req)
, m_committed(false)
, m_isClientRedirect(false)
, m_replacesCurrentHistoryItem(false)
, m_loadingMainResource(false)
, m_timeOfLastDataReceived(0.0)
- , m_identifierForLoadWithoutResourceLoader(0)
- , m_dataLoadTimer(this, &DocumentLoader::handleSubstituteDataLoadNow)
, m_applicationCacheHost(adoptPtr(new ApplicationCacheHost(this)))
{
}
@@ -103,24 +99,14 @@ ResourceLoader* DocumentLoader::mainResourceLoader() const
DocumentLoader::~DocumentLoader()
{
- ASSERT(!m_frame || frameLoader()->activeDocumentLoader() != this || !isLoading());
+ ASSERT(!m_frame || !isLoading());
m_fetcher->clearDocumentLoader();
clearMainResourceHandle();
}
-PassRefPtr<SharedBuffer> DocumentLoader::mainResourceData() const
-{
- ASSERT(isArchiveMIMEType(m_response.mimeType()));
- if (m_substituteData.isValid())
- return m_substituteData.content()->copy();
- if (m_mainResource)
- return m_mainResource->resourceBuffer();
- return 0;
-}
-
unsigned long DocumentLoader::mainResourceIdentifier() const
{
- return m_mainResource ? m_mainResource->identifier() : m_identifierForLoadWithoutResourceLoader;
+ return m_mainResource ? m_mainResource->identifier() : 0;
}
Document* DocumentLoader::document() const
@@ -135,59 +121,34 @@ const ResourceRequest& DocumentLoader::originalRequest() const
return m_originalRequest;
}
-const ResourceRequest& DocumentLoader::originalRequestCopy() const
-{
- return m_originalRequestCopy;
-}
-
const ResourceRequest& DocumentLoader::request() const
{
return m_request;
}
-ResourceRequest& DocumentLoader::request()
-{
- return m_request;
-}
-
const KURL& DocumentLoader::url() const
{
- return request().url();
+ return m_request.url();
}
-void DocumentLoader::updateForSameDocumentNavigation(const KURL& newURL)
+void DocumentLoader::updateForSameDocumentNavigation(const KURL& newURL, SameDocumentNavigationSource sameDocumentNavigationSource)
{
KURL oldURL = m_request.url();
- m_originalRequestCopy.setURL(newURL);
+ m_originalRequest.setURL(newURL);
m_request.setURL(newURL);
+ if (sameDocumentNavigationSource == SameDocumentNavigationHistoryApi) {
+ m_request.setHTTPMethod("GET");
+ m_request.setHTTPBody(nullptr);
+ }
clearRedirectChain();
if (m_isClientRedirect)
appendRedirect(oldURL);
appendRedirect(newURL);
}
-bool DocumentLoader::isURLValidForNewHistoryEntry() const
+const KURL& DocumentLoader::urlForHistory() const
{
- return !originalRequest().url().isEmpty() || !unreachableURL().isEmpty();
-}
-
-void DocumentLoader::setRequest(const ResourceRequest& req)
-{
- // Replacing an unreachable URL with alternate content looks like a server-side
- // redirect at this point, but we can replace a committed dataSource.
- bool handlingUnreachableURL = false;
-
- handlingUnreachableURL = m_substituteData.isValid() && !m_substituteData.failingURL().isEmpty();
-
- if (handlingUnreachableURL)
- m_committed = false;
-
- // We should never be getting a redirect callback after the data
- // source is committed, except in the unreachable URL case. It
- // would be a WebFoundation bug if it sent a redirect callback after commit.
- ASSERT(!m_committed);
-
- m_request = req;
+ return unreachableURL().isEmpty() ? url() : unreachableURL();
}
void DocumentLoader::setMainDocumentError(const ResourceError& error)
@@ -214,7 +175,7 @@ void DocumentLoader::mainReceivedError(const ResourceError& error)
// but not loads initiated by child frames' data sources -- that's the WebFrame's job.
void DocumentLoader::stopLoading()
{
- RefPtr<Frame> protectFrame(m_frame);
+ RefPtr<LocalFrame> protectFrame(m_frame);
RefPtr<DocumentLoader> protectLoader(this);
// In some rare cases, calling FrameLoader::stopLoading could cause isLoading() to return false.
@@ -231,12 +192,12 @@ void DocumentLoader::stopLoading()
m_frame->loader().stopLoading();
}
- clearArchiveResources();
-
- if (!loading)
+ if (!loading) {
+ m_fetcher->stopFetching();
return;
+ }
- if (isLoadingMainResource()) {
+ if (m_loadingMainResource) {
// Stop the main resource loader and let it send the cancelled message.
cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
} else if (m_fetcher->isFetching()) {
@@ -265,7 +226,7 @@ bool DocumentLoader::isLoading() const
if (document() && document()->hasActiveParser())
return true;
- return isLoadingMainResource() || m_fetcher->isFetching();
+ return m_loadingMainResource || m_fetcher->isFetching();
}
void DocumentLoader::notifyFinished(Resource* resource)
@@ -285,15 +246,10 @@ void DocumentLoader::notifyFinished(Resource* resource)
void DocumentLoader::finishedLoading(double finishTime)
{
- ASSERT(!m_frame->page()->defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame));
+ ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame));
RefPtr<DocumentLoader> protect(this);
- if (m_identifierForLoadWithoutResourceLoader) {
- m_frame->fetchContext().dispatchDidFinishLoading(this, m_identifierForLoadWithoutResourceLoader, finishTime);
- m_identifierForLoadWithoutResourceLoader = 0;
- }
-
double responseEndTime = finishTime;
if (!responseEndTime)
responseEndTime = m_timeOfLastDataReceived;
@@ -305,9 +261,7 @@ void DocumentLoader::finishedLoading(double finishTime)
if (!frameLoader())
return;
- if (isArchiveMIMEType(m_response.mimeType())) {
- createArchive();
- } else {
+ if (!maybeCreateArchive()) {
// If this is an empty document, it will not have actually been created yet. Commit dummy data so that
// DocumentWriter::begin() gets called and creates the Document.
if (!m_writer)
@@ -325,7 +279,7 @@ void DocumentLoader::finishedLoading(double finishTime)
// If the document specified an application cache manifest, it violates the author's intent if we store it in the memory cache
// and deny the appcache the chance to intercept it in the future, so remove from the memory cache.
if (m_frame) {
- if (m_mainResource && m_frame->document()->hasManifest())
+ if (m_mainResource && m_frame->document()->hasAppCacheManifest())
memoryCache()->remove(m_mainResource.get());
}
m_applicationCacheHost->finishedLoadingMainResource();
@@ -342,53 +296,31 @@ bool DocumentLoader::isRedirectAfterPost(const ResourceRequest& newRequest, cons
return false;
}
-void DocumentLoader::handleSubstituteDataLoadNow(DocumentLoaderTimer*)
-{
- RefPtr<DocumentLoader> protect(this);
- ResourceResponse response(m_request.url(), m_substituteData.mimeType(), m_substituteData.content()->size(), m_substituteData.textEncoding(), emptyString());
- responseReceived(0, response);
- if (m_substituteData.content()->size())
- dataReceived(0, m_substituteData.content()->data(), m_substituteData.content()->size());
- if (isLoadingMainResource())
- finishedLoading(0);
-}
-
-void DocumentLoader::startDataLoadTimer()
-{
- m_dataLoadTimer.startOneShot(0);
-}
-
-void DocumentLoader::handleSubstituteDataLoadSoon()
-{
- if (m_deferMainResourceDataLoad)
- startDataLoadTimer();
- else
- handleSubstituteDataLoadNow(0);
-}
-
-bool DocumentLoader::shouldContinueForNavigationPolicy(const ResourceRequest& request, PolicyCheckLoadType policyCheckLoadType)
+bool DocumentLoader::shouldContinueForNavigationPolicy(const ResourceRequest& request)
{
// Don't ask if we are loading an empty URL.
- if (request.url().isEmpty())
- return true;
-
- // We are always willing to show alternate content for unreachable URLs.
- if (m_substituteData.isValid() && !m_substituteData.failingURL().isEmpty())
+ if (request.url().isEmpty() || m_substituteData.isValid())
return true;
// If we're loading content into a subframe, check against the parent's Content Security Policy
// and kill the load if that check fails.
- if (m_frame->ownerElement() && !m_frame->ownerElement()->document().contentSecurityPolicy()->allowChildFrameFromSource(request.url()))
+ // FIXME: CSP checks are broken for OOPI. For now, this policy always allows frames with a remote parent...
+ if (m_frame->deprecatedLocalOwner() && !m_frame->deprecatedLocalOwner()->document().contentSecurityPolicy()->allowChildFrameFromSource(request.url())) {
+ // Fire a load event, as timing attacks would otherwise reveal that the
+ // frame was blocked. This way, it looks like every other cross-origin
+ // page load.
+ m_frame->document()->enforceSandboxFlags(SandboxOrigin);
+ m_frame->owner()->dispatchLoad();
return false;
+ }
NavigationPolicy policy = m_triggeringAction.policy();
- if (policyCheckLoadType != PolicyCheckFragment)
- policy = frameLoader()->client()->decidePolicyForNavigation(request, this, policy);
+ policy = frameLoader()->client()->decidePolicyForNavigation(request, this, policy);
if (policy == NavigationPolicyCurrentTab)
return true;
if (policy == NavigationPolicyIgnore)
return false;
- if (!DOMWindow::allowPopUp(m_frame) && !UserGestureIndicator::processingUserGesture())
+ if (!LocalDOMWindow::allowPopUp(*m_frame) && !UserGestureIndicator::processingUserGesture())
return false;
frameLoader()->client()->loadURLExternally(request, policy);
return false;
@@ -400,6 +332,12 @@ void DocumentLoader::redirectReceived(Resource* resource, ResourceRequest& reque
willSendRequest(request, redirectResponse);
}
+void DocumentLoader::updateRequest(Resource* resource, const ResourceRequest& request)
+{
+ ASSERT_UNUSED(resource, resource == m_mainResource);
+ m_request = request;
+}
+
static bool isFormSubmission(NavigationType type)
{
return type == NavigationTypeFormSubmitted || type == NavigationTypeFormResubmitted;
@@ -430,33 +368,30 @@ void DocumentLoader::willSendRequest(ResourceRequest& newRequest, const Resource
timing()->addRedirect(redirectResponse.url(), newRequest.url());
}
- // Update cookie policy base URL as URL changes, except for subframes, which use the
- // URL of the main frame which doesn't change when we redirect.
- if (frameLoader()->isLoadingMainFrame())
- newRequest.setFirstPartyForCookies(newRequest.url());
-
// If we're fielding a redirect in response to a POST, force a load from origin, since
// this is a common site technique to return to a page viewing some data that the POST
// just modified.
if (newRequest.cachePolicy() == UseProtocolCachePolicy && isRedirectAfterPost(newRequest, redirectResponse))
- newRequest.setCachePolicy(ReloadIgnoringCacheData);
+ newRequest.setCachePolicy(ReloadBypassingCache);
- Frame* parent = m_frame->tree().parent();
- if (parent) {
- if (!parent->loader().mixedContentChecker()->canRunInsecureContent(parent->document()->securityOrigin(), newRequest.url())) {
+ // If this is a sub-frame, check for mixed content blocking against the top frame.
+ if (m_frame->tree().parent()) {
+ // FIXME: This does not yet work with out-of-process iframes.
+ Frame* top = m_frame->tree().top();
+ if (top->isLocalFrame() && !toLocalFrame(top)->loader().mixedContentChecker()->canRunInsecureContent(toLocalFrame(top)->document()->securityOrigin(), newRequest.url())) {
cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url()));
return;
}
}
- setRequest(newRequest);
+ m_request = newRequest;
if (redirectResponse.isNull())
return;
appendRedirect(newRequest.url());
frameLoader()->client()->dispatchDidReceiveServerRedirectForProvisionalLoad();
- if (!shouldContinueForNavigationPolicy(newRequest, PolicyCheckStandard))
+ if (!shouldContinueForNavigationPolicy(newRequest))
cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
}
@@ -521,8 +456,8 @@ void DocumentLoader::responseReceived(Resource* resource, const ResourceResponse
String message = "Refused to display '" + response.url().elidedString() + "' in a frame because it set 'X-Frame-Options' to '" + content + "'.";
frame()->document()->addConsoleMessageWithRequestIdentifier(SecurityMessageSource, ErrorMessageLevel, message, identifier);
frame()->document()->enforceSandboxFlags(SandboxOrigin);
- if (HTMLFrameOwnerElement* ownerElement = frame()->ownerElement())
- ownerElement->dispatchEvent(Event::create(EventTypeNames::load));
+ if (FrameOwner* owner = frame()->owner())
+ owner->dispatchLoad();
// The load event might have detached this frame. In that case, the load will already have been cancelled during detach.
if (frameLoader())
@@ -538,9 +473,6 @@ void DocumentLoader::responseReceived(Resource* resource, const ResourceResponse
if (isArchiveMIMEType(m_response.mimeType()) && m_mainResource->dataBufferingPolicy() != BufferData)
m_mainResource->setDataBufferingPolicy(BufferData);
- if (m_identifierForLoadWithoutResourceLoader)
- m_frame->fetchContext().dispatchDidReceiveResponse(this, m_identifierForLoadWithoutResourceLoader, m_response, 0);
-
if (!shouldContinueForResponse()) {
InspectorInstrumentation::continueWithPolicyIgnore(m_frame, this, m_mainResource->identifier(), m_response);
cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
@@ -549,27 +481,27 @@ void DocumentLoader::responseReceived(Resource* resource, const ResourceResponse
if (m_response.isHTTP()) {
int status = m_response.httpStatusCode();
- if ((status < 200 || status >= 300) && m_frame->ownerElement() && m_frame->ownerElement()->isObjectElement()) {
- m_frame->ownerElement()->renderFallbackContent();
- // object elements are no longer rendered after we fallback, so don't
- // keep trying to process data from their load
- cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
+ // FIXME: Fallback content only works if the parent is in the same processs.
+ if ((status < 200 || status >= 300) && m_frame->owner()) {
+ if (!m_frame->deprecatedLocalOwner()) {
+ ASSERT_NOT_REACHED();
+ } else if (m_frame->deprecatedLocalOwner()->isObjectElement()) {
+ m_frame->deprecatedLocalOwner()->renderFallbackContent();
+ // object elements are no longer rendered after we fallback, so don't
+ // keep trying to process data from their load
+ cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
+ }
}
}
}
-void DocumentLoader::ensureWriter()
-{
- ensureWriter(m_response.mimeType());
-}
-
void DocumentLoader::ensureWriter(const AtomicString& mimeType, const KURL& overridingURL)
{
if (m_writer)
return;
const AtomicString& encoding = overrideEncoding().isNull() ? response().textEncodingName() : overrideEncoding();
- m_writer = createWriterFor(m_frame, 0, requestURL(), mimeType, encoding, false, false);
+ m_writer = createWriterFor(m_frame, 0, url(), mimeType, encoding, false, false);
m_writer->setDocumentWasLoadedAsPartOfNavigation();
// This should be set before receivedFirstData().
if (!overridingURL.isEmpty())
@@ -582,7 +514,7 @@ void DocumentLoader::ensureWriter(const AtomicString& mimeType, const KURL& over
void DocumentLoader::commitData(const char* bytes, size_t length)
{
- ensureWriter();
+ ensureWriter(m_response.mimeType());
ASSERT(m_frame->document()->parsing());
m_writer->addData(bytes, length);
}
@@ -597,12 +529,9 @@ void DocumentLoader::dataReceived(Resource* resource, const char* data, int leng
// Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
// by starting a new load, so retain temporarily.
- RefPtr<Frame> protectFrame(m_frame);
+ RefPtr<LocalFrame> protectFrame(m_frame);
RefPtr<DocumentLoader> protectLoader(this);
- if (m_identifierForLoadWithoutResourceLoader)
- frame()->fetchContext().dispatchDidReceiveData(this, m_identifierForLoadWithoutResourceLoader, data, length, -1);
-
m_applicationCacheHost->mainResourceDataReceived(data, length);
m_timeOfLastDataReceived = monotonicallyIncreasingTime();
@@ -619,16 +548,6 @@ void DocumentLoader::dataReceived(Resource* resource, const char* data, int leng
cancelMainResourceLoad(ResourceError::cancelledError(m_request.url()));
}
-void DocumentLoader::checkLoadComplete()
-{
- if (!m_frame || isLoading())
- return;
- // FIXME: This ASSERT is always triggered.
- // See https://bugs.webkit.org/show_bug.cgi?id=110937
- // ASSERT(this == frameLoader()->activeDocumentLoader())
- m_frame->domWindow()->finishedLoading();
-}
-
void DocumentLoader::clearRedirectChain()
{
m_redirectChain.clear();
@@ -639,19 +558,10 @@ void DocumentLoader::appendRedirect(const KURL& url)
m_redirectChain.append(url);
}
-void DocumentLoader::setFrame(Frame* frame)
-{
- if (m_frame == frame)
- return;
- ASSERT(frame && !m_frame);
- ASSERT(!m_writer);
- m_frame = frame;
-}
-
void DocumentLoader::detachFromFrame()
{
ASSERT(m_frame);
- RefPtr<Frame> protectFrame(m_frame);
+ RefPtr<LocalFrame> protectFrame(m_frame);
RefPtr<DocumentLoader> protectLoader(this);
// It never makes sense to have a document loader that is detached from its
@@ -666,8 +576,6 @@ void DocumentLoader::detachFromFrame()
void DocumentLoader::clearMainResourceLoader()
{
m_loadingMainResource = false;
- if (this == frameLoader()->activeDocumentLoader())
- checkLoadComplete();
}
void DocumentLoader::clearMainResourceHandle()
@@ -678,30 +586,23 @@ void DocumentLoader::clearMainResourceHandle()
m_mainResource = 0;
}
-bool DocumentLoader::isLoadingInAPISense() const
+bool DocumentLoader::maybeCreateArchive()
{
- // Once a frame has loaded, we no longer need to consider subresources,
- // but we still need to consider subframes.
- if (frameLoader()->state() != FrameStateComplete) {
- Document* doc = m_frame->document();
- if ((isLoadingMainResource() || !m_frame->document()->loadEventFinished()) && isLoading())
- return true;
- if (m_fetcher->requestCount())
- return true;
- if (doc->isDelayingLoadEvent() && !doc->loadEventFinished())
- return true;
- if (doc->processingLoadEvent())
- return true;
- if (doc->hasActiveParser())
- return true;
- }
- return frameLoader()->subframeIsLoading();
-}
+ // Only the top-frame can load MHTML.
+ if (m_frame->tree().parent())
+ return false;
-void DocumentLoader::createArchive()
-{
- m_archive = MHTMLArchive::create(m_response.url(), mainResourceData().get());
- RELEASE_ASSERT(m_archive);
+ // Give the archive machinery a crack at this document. If the MIME type is not an archive type, it will return 0.
+ if (!isArchiveMIMEType(m_response.mimeType()))
+ return false;
+
+ ASSERT(m_mainResource);
+ m_archive = MHTMLArchive::create(m_response.url(), m_mainResource->resourceBuffer());
+ // Invalid MHTML.
+ if (!m_archive || !m_archive->mainResource()) {
+ m_archive.clear();
+ return false;
+ }
addAllArchiveResources(m_archive.get());
ArchiveResource* mainResource = m_archive->mainResource();
@@ -710,7 +611,11 @@ void DocumentLoader::createArchive()
// relative URLs are resolved properly.
ensureWriter(mainResource->mimeType(), m_archive->mainResource()->url());
+ // The Document has now been created.
+ document()->enforceSandboxFlags(SandboxAll);
+
commitData(mainResource->data()->data(), mainResource->data()->size());
+ return true;
}
void DocumentLoader::addAllArchiveResources(MHTMLArchive* archive)
@@ -723,10 +628,10 @@ void DocumentLoader::addAllArchiveResources(MHTMLArchive* archive)
void DocumentLoader::prepareSubframeArchiveLoadIfNeeded()
{
- if (!m_frame->tree().parent())
+ if (!m_frame->tree().parent() || !m_frame->tree().parent()->isLocalFrame())
return;
- ArchiveResourceCollection* parentCollection = m_frame->tree().parent()->loader().documentLoader()->m_archiveResourceCollection.get();
+ ArchiveResourceCollection* parentCollection = toLocalFrame(m_frame->tree().parent())->loader().documentLoader()->m_archiveResourceCollection.get();
if (!parentCollection)
return;
@@ -740,11 +645,6 @@ void DocumentLoader::prepareSubframeArchiveLoadIfNeeded()
m_substituteData = SubstituteData(mainResource->data(), mainResource->mimeType(), mainResource->textEncoding(), KURL());
}
-void DocumentLoader::clearArchiveResources()
-{
- m_archiveResourceCollection.clear();
-}
-
bool DocumentLoader::scheduleArchiveLoad(Resource* cachedResource, const ResourceRequest& request)
{
if (!m_archive)
@@ -766,16 +666,6 @@ bool DocumentLoader::scheduleArchiveLoad(Resource* cachedResource, const Resourc
return true;
}
-const KURL& DocumentLoader::originalURL() const
-{
- return m_originalRequestCopy.url();
-}
-
-const KURL& DocumentLoader::requestURL() const
-{
- return request().url();
-}
-
const AtomicString& DocumentLoader::responseMIMEType() const
{
return m_response.mimeType();
@@ -827,27 +717,20 @@ void DocumentLoader::startLoadingMainResource()
timing()->markFetchStart();
willSendRequest(m_request, ResourceResponse());
- // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest.
+ // willSendRequest() may lead to our LocalFrame being detached or cancelling the load via nulling the ResourceRequest.
if (!m_frame || m_request.isNull())
return;
m_applicationCacheHost->willStartLoadingMainResource(m_request);
prepareSubframeArchiveLoadIfNeeded();
- if (m_substituteData.isValid()) {
- m_identifierForLoadWithoutResourceLoader = createUniqueIdentifier();
- frame()->fetchContext().dispatchWillSendRequest(this, m_identifierForLoadWithoutResourceLoader, m_request, ResourceResponse());
- handleSubstituteDataLoadSoon();
- return;
- }
-
ResourceRequest request(m_request);
DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions,
- (SendCallbacks, SniffContent, DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, AskClientForCrossOriginCredentials, SkipSecurityCheck, CheckContentSecurityPolicy, DocumentContext));
+ (SniffContent, DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, CheckContentSecurityPolicy, DocumentContext));
FetchRequest cachedResourceRequest(request, FetchInitiatorTypeNames::document, mainResourceLoadOptions);
- m_mainResource = m_fetcher->fetchMainResource(cachedResourceRequest);
+ m_mainResource = m_fetcher->fetchMainResource(cachedResourceRequest, m_substituteData);
if (!m_mainResource) {
- setRequest(ResourceRequest());
+ m_request = ResourceRequest();
// If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
// is now in a state where starting an empty load will be inconsistent. Replace it with
// a new ApplicationCacheHost.
@@ -864,7 +747,7 @@ void DocumentLoader::startLoadingMainResource()
// the fragment identifier, so add that back in.
if (equalIgnoringFragmentIdentifier(m_request.url(), request.url()))
request.setURL(m_request.url());
- setRequest(request);
+ m_request = request;
}
void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
@@ -872,17 +755,16 @@ void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
RefPtr<DocumentLoader> protect(this);
ResourceError error = resourceError.isNull() ? ResourceError::cancelledError(m_request.url()) : resourceError;
- m_dataLoadTimer.stop();
if (mainResourceLoader())
mainResourceLoader()->cancel(error);
mainReceivedError(error);
}
-DocumentWriter* DocumentLoader::beginWriting(const AtomicString& mimeType, const AtomicString& encoding, const KURL& url)
+void DocumentLoader::attachThreadedDataReceiver(PassOwnPtr<blink::WebThreadedDataReceiver> threadedDataReceiver)
{
- m_writer = createWriterFor(m_frame, 0, url, mimeType, encoding, false, true);
- return m_writer.get();
+ if (mainResourceLoader())
+ mainResourceLoader()->attachThreadedDataReceiver(threadedDataReceiver);
}
void DocumentLoader::endWriting(DocumentWriter* writer)
@@ -892,33 +774,31 @@ void DocumentLoader::endWriting(DocumentWriter* writer)
m_writer.clear();
}
-PassRefPtr<DocumentWriter> DocumentLoader::createWriterFor(Frame* frame, const Document* ownerDocument, const KURL& url, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch)
+PassRefPtrWillBeRawPtr<DocumentWriter> DocumentLoader::createWriterFor(LocalFrame* frame, const Document* ownerDocument, const KURL& url, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch)
{
// Create a new document before clearing the frame, because it may need to
// inherit an aliased security context.
DocumentInit init(url, frame);
+ init.withNewRegistrationContext();
- // In some rare cases, we'll re-used a DOMWindow for a new Document. For example,
+ // In some rare cases, we'll re-used a LocalDOMWindow for a new Document. For example,
// when a script calls window.open("..."), the browser gives JavaScript a window
// synchronously but kicks off the load in the window asynchronously. Web sites
// expect that modifications that they make to the window object synchronously
// won't be blown away when the network load commits. To make that happen, we
- // "securely transition" the existing DOMWindow to the Document that results from
+ // "securely transition" the existing LocalDOMWindow to the Document that results from
// the network load. See also SecurityContext::isSecureTransitionTo.
bool shouldReuseDefaultView = frame->loader().stateMachine()->isDisplayingInitialEmptyDocument() && frame->document()->isSecureTransitionTo(url);
- ClearOptions options = 0;
- if (!shouldReuseDefaultView)
- options = ClearWindowProperties | ClearScriptObjects;
- frame->loader().clear(options);
+ frame->loader().clear();
if (frame->document())
frame->document()->prepareForDestruction();
if (!shouldReuseDefaultView)
- frame->setDOMWindow(DOMWindow::create(frame));
+ frame->setDOMWindow(LocalDOMWindow::create(*frame));
- RefPtr<Document> document = frame->domWindow()->installNewDocument(mimeType, init);
+ RefPtrWillBeRawPtr<Document> document = frame->domWindow()->installNewDocument(mimeType, init);
if (ownerDocument) {
document->setCookieURL(ownerDocument->cookieURL());
document->setSecurityOrigin(ownerDocument->securityOrigin());
diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h
index d9b30f80232..3f9109805ab 100644
--- a/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -37,13 +37,16 @@
#include "core/loader/DocumentWriter.h"
#include "core/loader/NavigationAction.h"
#include "core/loader/SubstituteData.h"
-#include "platform/Timer.h"
#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"
#include "wtf/HashSet.h"
#include "wtf/RefPtr.h"
+namespace blink {
+class WebThreadedDataReceiver;
+}
+
namespace WTF {
class SchedulePair;
}
@@ -55,7 +58,7 @@ namespace WebCore {
class ResourceFetcher;
class ContentFilter;
class FormState;
- class Frame;
+ class LocalFrame;
class FrameLoader;
class MHTMLArchive;
class Page;
@@ -65,70 +68,54 @@ namespace WebCore {
class DocumentLoader : public RefCounted<DocumentLoader>, private RawResourceClient {
WTF_MAKE_FAST_ALLOCATED;
public:
- static PassRefPtr<DocumentLoader> create(const ResourceRequest& request, const SubstituteData& data)
+ static PassRefPtr<DocumentLoader> create(LocalFrame* frame, const ResourceRequest& request, const SubstituteData& data)
{
- return adoptRef(new DocumentLoader(request, data));
+ return adoptRef(new DocumentLoader(frame, request, data));
}
virtual ~DocumentLoader();
- void setFrame(Frame*);
- Frame* frame() const { return m_frame; }
+ LocalFrame* frame() const { return m_frame; }
void detachFromFrame();
- FrameLoader* frameLoader() const;
-
unsigned long mainResourceIdentifier() const;
void replaceDocument(const String& source, Document*);
- DocumentWriter* beginWriting(const AtomicString& mimeType, const AtomicString& encoding, const KURL& = KURL());
- void endWriting(DocumentWriter*);
const AtomicString& mimeType() const;
void setUserChosenEncoding(const String& charset);
const ResourceRequest& originalRequest() const;
- const ResourceRequest& originalRequestCopy() const;
const ResourceRequest& request() const;
- ResourceRequest& request();
ResourceFetcher* fetcher() const { return m_fetcher.get(); }
const SubstituteData& substituteData() const { return m_substituteData; }
- // FIXME: This is the same as requestURL(). We should remove one of them.
const KURL& url() const;
const KURL& unreachableURL() const;
- bool isURLValidForNewHistoryEntry() const;
+ const KURL& urlForHistory() const;
- const KURL& originalURL() const;
- const KURL& requestURL() const;
const AtomicString& responseMIMEType() const;
- void updateForSameDocumentNavigation(const KURL&);
+ void updateForSameDocumentNavigation(const KURL&, SameDocumentNavigationSource);
void stopLoading();
- void setCommitted(bool committed) { m_committed = committed; }
bool isCommitted() const { return m_committed; }
bool isLoading() const;
+ bool isLoadingMainResource() const { return m_loadingMainResource; }
const ResourceResponse& response() const { return m_response; }
const ResourceError& mainDocumentError() const { return m_mainDocumentError; }
bool isClientRedirect() const { return m_isClientRedirect; }
void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; }
bool replacesCurrentHistoryItem() const { return m_replacesCurrentHistoryItem; }
void setReplacesCurrentHistoryItem(bool replacesCurrentHistoryItem) { m_replacesCurrentHistoryItem = replacesCurrentHistoryItem; }
- bool isLoadingInAPISense() const;
const AtomicString& overrideEncoding() const { return m_overrideEncoding; }
bool scheduleArchiveLoad(Resource*, const ResourceRequest&);
- void cancelPendingSubstituteLoad(ResourceLoader*);
- enum PolicyCheckLoadType {
- PolicyCheckStandard,
- PolicyCheckFragment
- };
- bool shouldContinueForNavigationPolicy(const ResourceRequest&, PolicyCheckLoadType);
+ bool shouldContinueForNavigationPolicy(const ResourceRequest&);
const NavigationAction& triggeringAction() const { return m_triggeringAction; }
void setTriggeringAction(const NavigationAction& action) { m_triggeringAction = action; }
@@ -139,40 +126,28 @@ namespace WebCore {
void startLoadingMainResource();
void cancelMainResourceLoad(const ResourceError&);
- bool isLoadingMainResource() const { return m_loadingMainResource; }
-
- void stopLoadingSubresources();
-
- void subresourceLoaderFinishedLoadingOnePart(ResourceLoader*);
-
- void setDeferMainResourceDataLoad(bool defer) { m_deferMainResourceDataLoad = defer; }
-
+ void attachThreadedDataReceiver(PassOwnPtr<blink::WebThreadedDataReceiver>);
DocumentLoadTiming* timing() { return &m_documentLoadTiming; }
- void resetTiming() { m_documentLoadTiming = DocumentLoadTiming(); }
ApplicationCacheHost* applicationCacheHost() const { return m_applicationCacheHost.get(); }
- void checkLoadComplete();
-
bool isRedirect() const { return m_redirectChain.size() > 1; }
void clearRedirectChain();
void appendRedirect(const KURL&);
protected:
- DocumentLoader(const ResourceRequest&, const SubstituteData&);
+ DocumentLoader(LocalFrame*, const ResourceRequest&, const SubstituteData&);
- bool m_deferMainResourceDataLoad;
Vector<KURL> m_redirectChain;
private:
- static PassRefPtr<DocumentWriter> createWriterFor(Frame*, const Document* ownerDocument, const KURL&, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch);
+ static PassRefPtrWillBeRawPtr<DocumentWriter> createWriterFor(LocalFrame*, const Document* ownerDocument, const KURL&, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch);
- void ensureWriter();
void ensureWriter(const AtomicString& mimeType, const KURL& overridingURL = KURL());
+ void endWriting(DocumentWriter*);
Document* document() const;
-
- void setRequest(const ResourceRequest&);
+ FrameLoader* frameLoader() const;
void commitIfReady();
void commitData(const char* bytes, size_t length);
@@ -180,10 +155,8 @@ namespace WebCore {
void clearMainResourceLoader();
ResourceLoader* mainResourceLoader() const;
void clearMainResourceHandle();
- PassRefPtr<SharedBuffer> mainResourceData() const;
- void createArchive();
- void clearArchiveResources();
+ bool maybeCreateArchive();
void prepareSubframeArchiveLoadIfNeeded();
void addAllArchiveResources(MHTMLArchive*);
@@ -191,10 +164,11 @@ namespace WebCore {
void willSendRequest(ResourceRequest&, const ResourceResponse&);
void finishedLoading(double finishTime);
void mainReceivedError(const ResourceError&);
- virtual void redirectReceived(Resource*, ResourceRequest&, const ResourceResponse&) OVERRIDE;
- virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE;
- virtual void dataReceived(Resource*, const char* data, int length) OVERRIDE;
- virtual void notifyFinished(Resource*) OVERRIDE;
+ virtual void redirectReceived(Resource*, ResourceRequest&, const ResourceResponse&) OVERRIDE FINAL;
+ virtual void updateRequest(Resource*, const ResourceRequest&) OVERRIDE FINAL;
+ virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE FINAL;
+ virtual void dataReceived(Resource*, const char* data, int length) OVERRIDE FINAL;
+ virtual void notifyFinished(Resource*) OVERRIDE FINAL;
bool maybeLoadEmpty();
@@ -202,31 +176,20 @@ namespace WebCore {
bool shouldContinueForResponse() const;
- typedef Timer<DocumentLoader> DocumentLoaderTimer;
-
- void handleSubstituteDataLoadSoon();
- void handleSubstituteDataLoadNow(DocumentLoaderTimer*);
- void startDataLoadTimer();
-
- Frame* m_frame;
- RefPtr<ResourceFetcher> m_fetcher;
+ LocalFrame* m_frame;
+ RefPtrWillBePersistent<ResourceFetcher> m_fetcher;
ResourcePtr<RawResource> m_mainResource;
- RefPtr<DocumentWriter> m_writer;
+ RefPtrWillBePersistent<DocumentWriter> m_writer;
// A reference to actual request used to create the data source.
- // This should only be used by the resourceLoadDelegate's
- // identifierForInitialRequest:fromDatasource: method. It is
- // not guaranteed to remain unchanged, as requests are mutable.
+ // The only part of this request that should change is the url, and
+ // that only in the case of a same-document navigation.
ResourceRequest m_originalRequest;
SubstituteData m_substituteData;
- // A copy of the original request used to create the data source.
- // We have to copy the request because requests are mutable.
- ResourceRequest m_originalRequestCopy;
-
// The 'working' request. It may be mutated
// several times from the original request to include additional
// headers, cookie information, canonicalization and redirects.
@@ -253,9 +216,6 @@ namespace WebCore {
DocumentLoadTiming m_documentLoadTiming;
double m_timeOfLastDataReceived;
- unsigned long m_identifierForLoadWithoutResourceLoader;
-
- DocumentLoaderTimer m_dataLoadTimer;
friend class ApplicationCacheHost; // for substitute resource delivery
OwnPtr<ApplicationCacheHost> m_applicationCacheHost;
diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
index f34ee2e5b9e..9178bf34ce1 100644
--- a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -37,9 +37,10 @@
#include "core/fetch/FetchRequest.h"
#include "core/fetch/Resource.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/CrossOriginPreflightResultCache.h"
#include "core/loader/DocumentThreadableLoaderClient.h"
#include "core/loader/FrameLoader.h"
@@ -52,37 +53,48 @@
namespace WebCore {
-void DocumentThreadableLoader::loadResourceSynchronously(Document* document, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options)
+void DocumentThreadableLoader::loadResourceSynchronously(Document& document, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
{
// The loader will be deleted as soon as this function exits.
- RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, &client, LoadSynchronously, request, options));
+ RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, &client, LoadSynchronously, request, options, resourceLoaderOptions));
ASSERT(loader->hasOneRef());
}
-PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document* document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options)
+PassRefPtr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document& document, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
{
- RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options));
+ RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options, resourceLoaderOptions));
if (!loader->resource())
- loader = 0;
+ loader = nullptr;
return loader.release();
}
-DocumentThreadableLoader::DocumentThreadableLoader(Document* document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest& request, const ThreadableLoaderOptions& options)
+DocumentThreadableLoader::DocumentThreadableLoader(Document& document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ResourceRequest& request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
: m_client(client)
, m_document(document)
, m_options(options)
+ , m_resourceLoaderOptions(resourceLoaderOptions)
+ , m_forceDoNotAllowStoredCredentials(false)
+ , m_securityOrigin(m_resourceLoaderOptions.securityOrigin)
, m_sameOriginRequest(securityOrigin()->canRequest(request.url()))
, m_simpleRequest(true)
, m_async(blockingBehavior == LoadAsynchronously)
, m_timeoutTimer(this, &DocumentThreadableLoader::didTimeout)
{
- ASSERT(document);
ASSERT(client);
// Setting an outgoing referer is only supported in the async code path.
ASSERT(m_async || request.httpReferrer().isEmpty());
+ // Save any CORS simple headers on the request here. If this request redirects cross-origin, we cancel the old request
+ // create a new one, and copy these headers.
+ const HTTPHeaderMap& headerMap = request.httpHeaderFields();
+ HTTPHeaderMap::const_iterator end = headerMap.end();
+ for (HTTPHeaderMap::const_iterator it = headerMap.begin(); it != end; ++it) {
+ if (isOnAccessControlSimpleRequestHeaderWhitelist(it->key, it->value))
+ m_simpleRequestHeaders.add(it->key, it->value);
+ }
+
if (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossOriginRequests) {
- loadRequest(request, DoSecurityCheck);
+ loadRequest(request, m_resourceLoaderOptions);
return;
}
@@ -98,42 +110,37 @@ void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceReques
{
ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
- OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request));
+ if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight) {
+ // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
+ if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) {
+ m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP."));
+ return;
+ }
- if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight) {
- updateRequestForAccessControl(*crossOriginRequest, securityOrigin(), m_options.allowCredentials);
- makeSimpleCrossOriginAccessRequest(*crossOriginRequest);
+ ResourceRequest crossOriginRequest(request);
+ ResourceLoaderOptions crossOriginOptions(m_resourceLoaderOptions);
+ updateRequestForAccessControl(crossOriginRequest, securityOrigin(), effectiveAllowCredentials());
+ loadRequest(crossOriginRequest, crossOriginOptions);
} else {
m_simpleRequest = false;
+
+ OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request));
+ OwnPtr<ResourceLoaderOptions> crossOriginOptions = adoptPtr(new ResourceLoaderOptions(m_resourceLoaderOptions));
// Do not set the Origin header for preflight requests.
- updateRequestForAccessControl(*crossOriginRequest, 0, m_options.allowCredentials);
+ updateRequestForAccessControl(*crossOriginRequest, 0, effectiveAllowCredentials());
m_actualRequest = crossOriginRequest.release();
+ m_actualOptions = crossOriginOptions.release();
- if (CrossOriginPreflightResultCache::shared().canSkipPreflight(securityOrigin()->toString(), m_actualRequest->url(), m_options.allowCredentials, m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields()))
- preflightSuccess();
- else
- makeCrossOriginAccessRequestWithPreflight(*m_actualRequest);
- }
-}
-
-void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(const ResourceRequest& request)
-{
- ASSERT(m_options.preflightPolicy != ForcePreflight);
- ASSERT(m_options.preflightPolicy == PreventPreflight || isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()));
-
- // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
- if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) {
- m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP."));
- return;
+ if (CrossOriginPreflightResultCache::shared().canSkipPreflight(securityOrigin()->toString(), m_actualRequest->url(), effectiveAllowCredentials(), m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields())) {
+ loadActualRequest();
+ } else {
+ ResourceRequest preflightRequest = createAccessControlPreflightRequest(*m_actualRequest, securityOrigin());
+ // Create a ResourceLoaderOptions for preflight.
+ ResourceLoaderOptions preflightOptions = *m_actualOptions;
+ preflightOptions.allowCredentials = DoNotAllowStoredCredentials;
+ loadRequest(preflightRequest, preflightOptions);
+ }
}
-
- loadRequest(request, DoSecurityCheck);
-}
-
-void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(const ResourceRequest& request)
-{
- ResourceRequest preflightRequest = createAccessControlPreflightRequest(request, securityOrigin());
- loadRequest(preflightRequest, DoSecurityCheck);
}
DocumentThreadableLoader::~DocumentThreadableLoader()
@@ -157,7 +164,7 @@ void DocumentThreadableLoader::cancelWithError(const ResourceError& error)
errorForCallback = ResourceError(errorDomainBlinkInternal, 0, resource()->url().string(), "Load cancelled");
errorForCallback.setIsCancellation(true);
}
- didFail(resource()->identifier(), errorForCallback);
+ m_client->didFail(errorForCallback);
}
clearResource();
m_client = 0;
@@ -193,19 +200,21 @@ void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ
// original request was not same-origin.
if (m_options.crossOriginRequestPolicy == UseAccessControl) {
- InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document->frame(), resource->identifier(), m_document->frame()->loader().documentLoader(), redirectResponse, 0);
+ InspectorInstrumentation::didReceiveCORSRedirectResponse(m_document.frame(), resource->identifier(), m_document.frame()->loader().documentLoader(), redirectResponse, 0);
bool allowRedirect = false;
String accessControlErrorDescription;
if (m_simpleRequest) {
- allowRedirect = checkCrossOriginAccessRedirectionUrl(request.url(), accessControlErrorDescription)
- && (m_sameOriginRequest || passesAccessControlCheck(redirectResponse, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription));
+ allowRedirect = CrossOriginAccessControl::isLegalRedirectLocation(request.url(), accessControlErrorDescription)
+ && (m_sameOriginRequest || passesAccessControlCheck(redirectResponse, effectiveAllowCredentials(), securityOrigin(), accessControlErrorDescription));
} else {
accessControlErrorDescription = "The request was redirected to '"+ request.url().string() + "', which is disallowed for cross-origin requests that require preflight.";
}
if (allowRedirect) {
+ // FIXME: consider combining this with CORS redirect handling performed by
+ // CrossOriginAccessControl::handleRedirect().
clearResource();
RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(redirectResponse.url());
@@ -214,21 +223,24 @@ void DocumentThreadableLoader::redirectReceived(Resource* resource, ResourceRequ
// set the source origin to a globally unique identifier. (If the original request was same-origin, the origin of the new request
// should be the original URL origin.)
if (!m_sameOriginRequest && !originalOrigin->isSameSchemeHostPort(requestOrigin.get()))
- m_options.securityOrigin = SecurityOrigin::createUnique();
+ m_securityOrigin = SecurityOrigin::createUnique();
// Force any subsequent requests to use these checks.
m_sameOriginRequest = false;
// Since the request is no longer same-origin, if the user didn't request credentials in
// the first place, update our state so we neither request them nor expect they must be allowed.
- if (m_options.credentialsRequested == ClientDidNotRequestCredentials)
- m_options.allowCredentials = DoNotAllowStoredCredentials;
+ if (m_resourceLoaderOptions.credentialsRequested == ClientDidNotRequestCredentials)
+ m_forceDoNotAllowStoredCredentials = true;
// Remove any headers that may have been added by the network layer that cause access control to fail.
- request.clearHTTPContentType();
request.clearHTTPReferrer();
request.clearHTTPOrigin();
request.clearHTTPUserAgent();
- request.clearHTTPAccept();
+ // Add any CORS simple request headers which we previously saved from the original request.
+ HTTPHeaderMap::const_iterator end = m_simpleRequestHeaders.end();
+ for (HTTPHeaderMap::const_iterator it = m_simpleRequestHeaders.begin(); it != end; ++it) {
+ request.setHTTPHeaderField(it->key, it->value);
+ }
makeCrossOriginAccessRequest(request);
return;
}
@@ -260,66 +272,75 @@ void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength
void DocumentThreadableLoader::responseReceived(Resource* resource, const ResourceResponse& response)
{
ASSERT_UNUSED(resource, resource == this->resource());
- didReceiveResponse(resource->identifier(), response);
+ handleResponse(resource->identifier(), response);
}
-void DocumentThreadableLoader::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
+void DocumentThreadableLoader::handlePreflightResponse(unsigned long identifier, const ResourceResponse& response)
{
- ASSERT(m_client);
+ // Notifying the inspector here is necessary because a call to handlePreflightFailure() might synchronously
+ // cause the underlying ResourceLoader to be cancelled before it tells the inspector about the response.
+ // In that case, if we don't tell the inspector about the response now, the resource type in the inspector
+ // will default to "other" instead of something more descriptive.
+ DocumentLoader* loader = m_document.frame()->loader().documentLoader();
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceReceiveResponse", "data", InspectorReceiveResponseEvent::data(identifier, m_document.frame(), response));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didReceiveResourceResponse(m_document.frame(), identifier, loader, response, resource() ? resource()->loader() : 0);
String accessControlErrorDescription;
- if (m_actualRequest) {
- DocumentLoader* loader = m_document->frame()->loader().documentLoader();
- InspectorInstrumentation::didReceiveResourceResponse(m_document->frame(), identifier, loader, response, resource() ? resource()->loader() : 0);
- if (!passesAccessControlCheck(response, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)) {
- preflightFailure(identifier, response.url().string(), accessControlErrorDescription);
- return;
- }
+ if (!passesAccessControlCheck(response, effectiveAllowCredentials(), securityOrigin(), accessControlErrorDescription)) {
+ handlePreflightFailure(response.url().string(), accessControlErrorDescription);
+ return;
+ }
- if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) {
- preflightFailure(identifier, response.url().string(), accessControlErrorDescription);
- return;
- }
+ if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) {
+ handlePreflightFailure(response.url().string(), accessControlErrorDescription);
+ return;
+ }
- OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new CrossOriginPreflightResultCacheItem(m_options.allowCredentials));
- if (!preflightResult->parse(response, accessControlErrorDescription)
- || !preflightResult->allowsCrossOriginMethod(m_actualRequest->httpMethod(), accessControlErrorDescription)
- || !preflightResult->allowsCrossOriginHeaders(m_actualRequest->httpHeaderFields(), accessControlErrorDescription)) {
- preflightFailure(identifier, response.url().string(), accessControlErrorDescription);
- return;
- }
+ OwnPtr<CrossOriginPreflightResultCacheItem> preflightResult = adoptPtr(new CrossOriginPreflightResultCacheItem(effectiveAllowCredentials()));
+ if (!preflightResult->parse(response, accessControlErrorDescription)
+ || !preflightResult->allowsCrossOriginMethod(m_actualRequest->httpMethod(), accessControlErrorDescription)
+ || !preflightResult->allowsCrossOriginHeaders(m_actualRequest->httpHeaderFields(), accessControlErrorDescription)) {
+ handlePreflightFailure(response.url().string(), accessControlErrorDescription);
+ return;
+ }
- CrossOriginPreflightResultCache::shared().appendEntry(securityOrigin()->toString(), m_actualRequest->url(), preflightResult.release());
- } else {
- if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessControl) {
- if (!passesAccessControlCheck(response, m_options.allowCredentials, securityOrigin(), accessControlErrorDescription)) {
- m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, response.url().string(), accessControlErrorDescription));
- return;
- }
- }
+ CrossOriginPreflightResultCache::shared().appendEntry(securityOrigin()->toString(), m_actualRequest->url(), preflightResult.release());
+}
- m_client->didReceiveResponse(identifier, response);
+void DocumentThreadableLoader::handleResponse(unsigned long identifier, const ResourceResponse& response)
+{
+ ASSERT(m_client);
+
+ if (m_actualRequest) {
+ handlePreflightResponse(identifier, response);
+ return;
}
+
+ if (!m_sameOriginRequest && m_options.crossOriginRequestPolicy == UseAccessControl) {
+ String accessControlErrorDescription;
+ if (!passesAccessControlCheck(response, effectiveAllowCredentials(), securityOrigin(), accessControlErrorDescription)) {
+ m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, response.url().string(), accessControlErrorDescription));
+ return;
+ }
+ }
+
+ m_client->didReceiveResponse(identifier, response);
}
void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data, int dataLength)
{
- ASSERT(resource == this->resource());
- didReceiveData(resource->identifier(), data, dataLength);
+ ASSERT_UNUSED(resource, resource == this->resource());
+ handleReceivedData(data, dataLength);
}
-void DocumentThreadableLoader::didReceiveData(unsigned long identifier, const char* data, int dataLength)
+void DocumentThreadableLoader::handleReceivedData(const char* data, int dataLength)
{
ASSERT(m_client);
-
// Preflight data should be invisible to clients.
- if (m_actualRequest) {
- InspectorInstrumentation::didReceiveData(m_document->frame(), identifier, 0, 0, dataLength);
- return;
- }
-
- m_client->didReceiveData(data, dataLength);
+ if (!m_actualRequest)
+ m_client->didReceiveData(data, dataLength);
}
void DocumentThreadableLoader::notifyFinished(Resource* resource)
@@ -330,30 +351,21 @@ void DocumentThreadableLoader::notifyFinished(Resource* resource)
m_timeoutTimer.stop();
if (resource->errorOccurred())
- didFail(resource->identifier(), resource->resourceError());
+ m_client->didFail(resource->resourceError());
else
- didFinishLoading(resource->identifier(), resource->loadFinishTime());
+ handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime());
}
-void DocumentThreadableLoader::didFinishLoading(unsigned long identifier, double finishTime)
+void DocumentThreadableLoader::handleSuccessfulFinish(unsigned long identifier, double finishTime)
{
if (m_actualRequest) {
- InspectorInstrumentation::didFinishLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), finishTime);
ASSERT(!m_sameOriginRequest);
ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
- preflightSuccess();
+ loadActualRequest();
} else
m_client->didFinishLoading(identifier, finishTime);
}
-void DocumentThreadableLoader::didFail(unsigned long identifier, const ResourceError& error)
-{
- if (m_actualRequest)
- InspectorInstrumentation::didFailLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), error);
-
- m_client->didFail(error);
-}
-
void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer)
{
ASSERT_UNUSED(timer, timer == &m_timeoutTimer);
@@ -366,67 +378,70 @@ void DocumentThreadableLoader::didTimeout(Timer<DocumentThreadableLoader>* timer
cancelWithError(error);
}
-void DocumentThreadableLoader::preflightSuccess()
+void DocumentThreadableLoader::loadActualRequest()
{
OwnPtr<ResourceRequest> actualRequest;
actualRequest.swap(m_actualRequest);
+ OwnPtr<ResourceLoaderOptions> actualOptions;
+ actualOptions.swap(m_actualOptions);
- actualRequest->setHTTPOrigin(securityOrigin()->toString());
+ actualRequest->setHTTPOrigin(securityOrigin()->toAtomicString());
clearResource();
- // It should be ok to skip the security check since we already asked about the preflight request.
- loadRequest(*actualRequest, SkipSecurityCheck);
+ loadRequest(*actualRequest, *actualOptions);
}
-void DocumentThreadableLoader::preflightFailure(unsigned long identifier, const String& url, const String& errorDescription)
+void DocumentThreadableLoader::handlePreflightFailure(const String& url, const String& errorDescription)
{
ResourceError error(errorDomainBlinkInternal, 0, url, errorDescription);
- if (m_actualRequest)
- InspectorInstrumentation::didFailLoading(m_document->frame(), identifier, m_document->frame()->loader().documentLoader(), error);
- m_actualRequest = nullptr; // Prevent didFinishLoading() from bypassing access check.
+
+ // Prevent handleSuccessfulFinish() from bypassing access check.
+ m_actualRequest = nullptr;
+
m_client->didFailAccessControlCheck(error);
}
-void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, SecurityCheckPolicy securityCheck)
+void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, ResourceLoaderOptions resourceLoaderOptions)
{
// Any credential should have been removed from the cross-site requests.
const KURL& requestURL = request.url();
- m_options.securityCheck = securityCheck;
ASSERT(m_sameOriginRequest || requestURL.user().isEmpty());
ASSERT(m_sameOriginRequest || requestURL.pass().isEmpty());
- ThreadableLoaderOptions options = m_options;
+ // Update resourceLoaderOptions with enforced values.
+ if (m_forceDoNotAllowStoredCredentials)
+ resourceLoaderOptions.allowCredentials = DoNotAllowStoredCredentials;
+ resourceLoaderOptions.securityOrigin = m_securityOrigin;
if (m_async) {
- options.crossOriginCredentialPolicy = DoNotAskClientForCrossOriginCredentials;
if (m_actualRequest) {
- // Don't sniff content or send load callbacks for the preflight request.
- options.sendLoadCallbacks = DoNotSendCallbacks;
- options.sniffContent = DoNotSniffContent;
- // Keep buffering the data for the preflight request.
- options.dataBufferingPolicy = BufferData;
+ resourceLoaderOptions.sniffContent = DoNotSniffContent;
+ resourceLoaderOptions.dataBufferingPolicy = BufferData;
}
if (m_options.timeoutMilliseconds > 0)
- m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0);
+ m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0, FROM_HERE);
- FetchRequest newRequest(request, m_options.initiator, options);
+ FetchRequest newRequest(request, m_options.initiator, resourceLoaderOptions);
ASSERT(!resource());
- setResource(m_document->fetcher()->fetchRawResource(newRequest));
+ if (request.targetType() == ResourceRequest::TargetIsMedia)
+ setResource(m_document.fetcher()->fetchMedia(newRequest));
+ else
+ setResource(m_document.fetcher()->fetchRawResource(newRequest));
if (resource() && resource()->loader()) {
unsigned long identifier = resource()->identifier();
- InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client);
+ InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(&m_document, identifier, m_client);
}
return;
}
- FetchRequest fetchRequest(request, m_options.initiator, options);
- ResourcePtr<Resource> resource = m_document->fetcher()->fetchSynchronously(fetchRequest);
+ FetchRequest fetchRequest(request, m_options.initiator, resourceLoaderOptions);
+ ResourcePtr<Resource> resource = m_document.fetcher()->fetchSynchronously(fetchRequest);
ResourceResponse response = resource ? resource->response() : ResourceResponse();
unsigned long identifier = resource ? resource->identifier() : std::numeric_limits<unsigned long>::max();
ResourceError error = resource ? resource->resourceError() : ResourceError();
- InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(m_document, identifier, m_client);
+ InspectorInstrumentation::documentThreadableLoaderStartedLoadingForClient(&m_document, identifier, m_client);
if (!resource) {
m_client->didFail(error);
@@ -448,13 +463,13 @@ void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, Secur
return;
}
- didReceiveResponse(identifier, response);
+ handleResponse(identifier, response);
SharedBuffer* data = resource->resourceBuffer();
if (data)
- didReceiveData(identifier, data->data(), data->size());
+ handleReceivedData(data->data(), data->size());
- didFinishLoading(identifier, 0.0);
+ handleSuccessfulFinish(identifier, 0.0);
}
bool DocumentThreadableLoader::isAllowedRedirect(const KURL& url) const
@@ -469,27 +484,19 @@ bool DocumentThreadableLoader::isAllowedByPolicy(const KURL& url) const
{
if (m_options.contentSecurityPolicyEnforcement != EnforceConnectSrcDirective)
return true;
- return m_document->contentSecurityPolicy()->allowConnectToSource(url);
+ return m_document.contentSecurityPolicy()->allowConnectToSource(url);
}
-SecurityOrigin* DocumentThreadableLoader::securityOrigin() const
+StoredCredentials DocumentThreadableLoader::effectiveAllowCredentials() const
{
- return m_options.securityOrigin ? m_options.securityOrigin.get() : m_document->securityOrigin();
+ if (m_forceDoNotAllowStoredCredentials)
+ return DoNotAllowStoredCredentials;
+ return m_resourceLoaderOptions.allowCredentials;
}
-bool DocumentThreadableLoader::checkCrossOriginAccessRedirectionUrl(const KURL& requestUrl, String& errorDescription)
+SecurityOrigin* DocumentThreadableLoader::securityOrigin() const
{
- if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(requestUrl.protocol())) {
- errorDescription = "The request was redirected to a URL ('" + requestUrl.string() + "') which has a disallowed scheme for cross-origin requests.";
- return false;
- }
-
- if (!(requestUrl.user().isEmpty() && requestUrl.pass().isEmpty())) {
- errorDescription = "The request was redirected to a URL ('" + requestUrl.string() + "') containing userinfo, which is disallowed for cross-origin requests.";
- return false;
- }
-
- return true;
+ return m_securityOrigin ? m_securityOrigin.get() : m_document.securityOrigin();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h
index 3eadc624f31..54e8b2494bb 100644
--- a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h
@@ -36,11 +36,11 @@
#include "core/fetch/ResourceOwner.h"
#include "core/loader/ThreadableLoader.h"
#include "platform/Timer.h"
+#include "platform/network/HTTPHeaderMap.h"
#include "platform/network/ResourceError.h"
#include "wtf/Forward.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -51,22 +51,15 @@ class ResourceRequest;
class SecurityOrigin;
class ThreadableLoaderClient;
-class DocumentThreadableLoader : public RefCounted<DocumentThreadableLoader>, public ThreadableLoader, private ResourceOwner<RawResource> {
+class DocumentThreadableLoader FINAL : public ThreadableLoader, private ResourceOwner<RawResource> {
WTF_MAKE_FAST_ALLOCATED;
public:
- static void loadResourceSynchronously(Document*, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&);
- static PassRefPtr<DocumentThreadableLoader> create(Document*, ThreadableLoaderClient*, const ResourceRequest&, const ThreadableLoaderOptions&);
+ static void loadResourceSynchronously(Document&, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&);
+ static PassRefPtr<DocumentThreadableLoader> create(Document&, ThreadableLoaderClient*, const ResourceRequest&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&);
virtual ~DocumentThreadableLoader();
- virtual void cancel();
- virtual void setDefersLoading(bool);
-
- using RefCounted<DocumentThreadableLoader>::ref;
- using RefCounted<DocumentThreadableLoader>::deref;
-
- protected:
- virtual void refThreadableLoader() { ref(); }
- virtual void derefThreadableLoader() { deref(); }
+ virtual void cancel() OVERRIDE;
+ void setDefersLoading(bool);
private:
enum BlockingBehavior {
@@ -74,42 +67,67 @@ class DocumentThreadableLoader : public RefCounted<DocumentThreadableLoader>, pu
LoadAsynchronously
};
- DocumentThreadableLoader(Document*, ThreadableLoaderClient*, BlockingBehavior, const ResourceRequest&, const ThreadableLoaderOptions&);
+ DocumentThreadableLoader(Document&, ThreadableLoaderClient*, BlockingBehavior, const ResourceRequest&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&);
- // RawResourceClient
- virtual void dataSent(Resource*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
- virtual void responseReceived(Resource*, const ResourceResponse&);
- virtual void dataReceived(Resource*, const char* data, int dataLength);
- virtual void redirectReceived(Resource*, ResourceRequest&, const ResourceResponse&);
- virtual void notifyFinished(Resource*);
- virtual void dataDownloaded(Resource*, int);
+ // RawResourceClient implementation
+ virtual void dataSent(Resource*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
+ virtual void responseReceived(Resource*, const ResourceResponse&) OVERRIDE;
+ virtual void dataReceived(Resource*, const char* data, int dataLength) OVERRIDE;
+ virtual void redirectReceived(Resource*, ResourceRequest&, const ResourceResponse&) OVERRIDE;
+ virtual void notifyFinished(Resource*) OVERRIDE;
+ virtual void dataDownloaded(Resource*, int) OVERRIDE;
void cancelWithError(const ResourceError&);
- void didReceiveResponse(unsigned long identifier, const ResourceResponse&);
- void didReceiveData(unsigned long identifier, const char* data, int dataLength);
- void didFinishLoading(unsigned long identifier, double finishTime);
- void didFail(unsigned long identifier, const ResourceError&);
+
+ // Methods containing code to handle resource fetch results which is
+ // common to both sync and async mode.
+ void handleResponse(unsigned long identifier, const ResourceResponse&);
+ void handleReceivedData(const char* data, int dataLength);
+ void handleSuccessfulFinish(unsigned long identifier, double finishTime);
+
void didTimeout(Timer<DocumentThreadableLoader>*);
void makeCrossOriginAccessRequest(const ResourceRequest&);
- void makeSimpleCrossOriginAccessRequest(const ResourceRequest&);
- void makeCrossOriginAccessRequestWithPreflight(const ResourceRequest&);
- void preflightSuccess();
- void preflightFailure(unsigned long identifier, const String& url, const String& errorDescription);
-
- void loadRequest(const ResourceRequest&, SecurityCheckPolicy);
+ // Loads m_actualRequest.
+ void loadActualRequest();
+ // Clears m_actualRequest and reports access control check failure to
+ // m_client.
+ void handlePreflightFailure(const String& url, const String& errorDescription);
+ // Investigates the response for the preflight request. If successful,
+ // the actual request will be made later in handleSuccessfulFinish().
+ void handlePreflightResponse(unsigned long identifier, const ResourceResponse&);
+
+ void loadRequest(const ResourceRequest&, ResourceLoaderOptions);
bool isAllowedRedirect(const KURL&) const;
bool isAllowedByPolicy(const KURL&) const;
+ // Returns DoNotAllowStoredCredentials
+ // if m_forceDoNotAllowStoredCredentials is set. Otherwise, just
+ // returns allowCredentials value of m_resourceLoaderOptions.
+ StoredCredentials effectiveAllowCredentials() const;
SecurityOrigin* securityOrigin() const;
- bool checkCrossOriginAccessRedirectionUrl(const KURL&, String& errorDescription);
ThreadableLoaderClient* m_client;
- Document* m_document;
- ThreadableLoaderOptions m_options;
+ Document& m_document;
+
+ const ThreadableLoaderOptions m_options;
+ // Some items may be overridden by m_forceDoNotAllowStoredCredentials
+ // and m_securityOrigin. In such a case, build a ResourceLoaderOptions
+ // with up-to-date values from them and this variable, and use it.
+ const ResourceLoaderOptions m_resourceLoaderOptions;
+
+ bool m_forceDoNotAllowStoredCredentials;
+ RefPtr<SecurityOrigin> m_securityOrigin;
+
bool m_sameOriginRequest;
bool m_simpleRequest;
bool m_async;
- OwnPtr<ResourceRequest> m_actualRequest; // non-null during Access Control preflight checks
+
+ // Holds the original request and options for it during preflight
+ // request handling phase.
+ OwnPtr<ResourceRequest> m_actualRequest;
+ OwnPtr<ResourceLoaderOptions> m_actualOptions;
+
+ HTTPHeaderMap m_simpleRequestHeaders; // stores simple request headers in case of a cross-origin redirect.
Timer<DocumentThreadableLoader> m_timeoutTimer;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoaderClient.h b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoaderClient.h
index 325a841a345..d272a47c7a1 100644
--- a/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoaderClient.h
+++ b/chromium/third_party/WebKit/Source/core/loader/DocumentThreadableLoaderClient.h
@@ -42,7 +42,7 @@ class DocumentThreadableLoaderClient : public ThreadableLoaderClient {
WTF_MAKE_NONCOPYABLE(DocumentThreadableLoaderClient);
WTF_MAKE_FAST_ALLOCATED;
public:
- virtual bool isDocumentThreadableLoaderClient() { return true; }
+ virtual bool isDocumentThreadableLoaderClient() OVERRIDE FINAL { return true; }
virtual void willSendRequest(ResourceRequest& /*newRequest*/, const ResourceResponse& /*redirectResponse*/) { }
diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp b/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp
index 349da64347d..4e0b82465d1 100644
--- a/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.cpp
@@ -31,12 +31,12 @@
#include "core/dom/Document.h"
#include "core/dom/ScriptableDocumentParser.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderStateMachine.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/SecurityOrigin.h"
@@ -44,9 +44,9 @@
namespace WebCore {
-PassRefPtr<DocumentWriter> DocumentWriter::create(Document* document, const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen)
+PassRefPtrWillBeRawPtr<DocumentWriter> DocumentWriter::create(Document* document, const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen)
{
- return adoptRef(new DocumentWriter(document, mimeType, encoding, encodingUserChoosen));
+ return adoptRefWillBeNoop(new DocumentWriter(document, mimeType, encoding, encodingUserChoosen));
}
DocumentWriter::DocumentWriter(Document* document, const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen)
@@ -67,6 +67,12 @@ DocumentWriter::~DocumentWriter()
{
}
+void DocumentWriter::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_parser);
+}
+
void DocumentWriter::appendReplacingData(const String& source)
{
m_document->setCompatibilityMode(Document::NoQuirksMode);
@@ -78,7 +84,6 @@ void DocumentWriter::appendReplacingData(const String& source)
// Because we're pinned to the main thread we don't need to worry about
// passing ownership of the source string.
parser->append(source.impl());
- parser->setHasAppendedData();
}
}
@@ -90,7 +95,7 @@ void DocumentWriter::addData(const char* bytes, size_t length)
m_parser->setDecoder(decoder.release());
}
// appendBytes() can result replacing DocumentLoader::m_writer.
- RefPtr<DocumentWriter> protectingThis(this);
+ RefPtrWillBeRawPtr<DocumentWriter> protectingThis(this);
m_parser->appendBytes(bytes, length);
}
@@ -101,7 +106,7 @@ void DocumentWriter::end()
// http://bugs.webkit.org/show_bug.cgi?id=10854
// The frame's last ref may be removed and it can be deleted by checkCompleted(),
// so we'll add a protective refcount
- RefPtr<Frame> protector(m_document->frame());
+ RefPtr<LocalFrame> protector(m_document->frame());
if (!m_parser)
return;
@@ -111,15 +116,15 @@ void DocumentWriter::end()
m_parser->setDecoder(decoder.release());
}
// flush() can result replacing DocumentLoader::m_writer.
- RefPtr<DocumentWriter> protectingThis(this);
+ RefPtrWillBeRawPtr<DocumentWriter> protectingThis(this);
m_parser->flush();
if (!m_parser)
return;
m_parser->finish();
- m_parser = 0;
- m_document = 0;
+ m_parser = nullptr;
+ m_document = nullptr;
}
void DocumentWriter::setUserChosenEncoding(const String& charset)
diff --git a/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h b/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h
index 4e79045a1e9..42d7ee6a1c8 100644
--- a/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h
+++ b/chromium/third_party/WebKit/Source/core/loader/DocumentWriter.h
@@ -30,6 +30,7 @@
#define DocumentWriter_h
#include "core/loader/TextResourceDecoderBuilder.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -37,17 +38,18 @@ namespace WebCore {
class Document;
class DocumentParser;
-class Frame;
+class LocalFrame;
class KURL;
class SecurityOrigin;
class TextResourceDecoder;
-class DocumentWriter : public RefCounted<DocumentWriter> {
+class DocumentWriter : public RefCountedWillBeGarbageCollectedFinalized<DocumentWriter> {
WTF_MAKE_NONCOPYABLE(DocumentWriter);
public:
- static PassRefPtr<DocumentWriter> create(Document*, const AtomicString& mimeType = emptyAtom, const AtomicString& encoding = emptyAtom, bool encodingUserChoosen = false);
+ static PassRefPtrWillBeRawPtr<DocumentWriter> create(Document*, const AtomicString& mimeType = emptyAtom, const AtomicString& encoding = emptyAtom, bool encodingUserChoosen = false);
~DocumentWriter();
+ void trace(Visitor*);
void end();
@@ -71,12 +73,10 @@ public:
private:
DocumentWriter(Document*, const AtomicString& mimeType, const AtomicString& encoding, bool encodingUserChoosen);
- PassRefPtr<Document> createDocument(const KURL&);
-
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
TextResourceDecoderBuilder m_decoderBuilder;
- RefPtr<DocumentParser> m_parser;
+ RefPtrWillBeMember<DocumentParser> m_parser;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp b/chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp
index 78fbce00c1d..db5b8aa7068 100644
--- a/chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/EmptyClients.cpp
@@ -28,13 +28,14 @@
#include "config.h"
#include "core/loader/EmptyClients.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFormElement.h"
#include "core/loader/DocumentLoader.h"
-#include "core/loader/FormState.h"
-#include "core/frame/Frame.h"
+#include "core/storage/StorageNamespace.h"
#include "platform/ColorChooser.h"
#include "platform/DateTimeChooser.h"
#include "platform/FileChooser.h"
+#include "public/platform/WebApplicationCacheHost.h"
#include "public/platform/WebServiceWorkerProvider.h"
#include "public/platform/WebServiceWorkerProviderClient.h"
@@ -62,6 +63,9 @@ void fillWithEmptyClients(Page::PageClients& pageClients)
static SpellCheckerClient* dummySpellCheckerClient = adoptPtr(new EmptySpellCheckerClient).leakPtr();
pageClients.spellCheckerClient = dummySpellCheckerClient;
+
+ static StorageClient* dummyStorageClient = adoptPtr(new EmptyStorageClient).leakPtr();
+ pageClients.storageClient = dummyStorageClient;
}
class EmptyPopupMenu : public PopupMenu {
@@ -72,26 +76,26 @@ public:
virtual void disconnectClient() OVERRIDE { }
};
-PassRefPtr<PopupMenu> EmptyChromeClient::createPopupMenu(Frame&, PopupMenuClient*) const
+PassRefPtr<PopupMenu> EmptyChromeClient::createPopupMenu(LocalFrame&, PopupMenuClient*) const
{
return adoptRef(new EmptyPopupMenu());
}
-PassOwnPtr<ColorChooser> EmptyChromeClient::createColorChooser(ColorChooserClient*, const Color&)
+PassOwnPtr<ColorChooser> EmptyChromeClient::createColorChooser(LocalFrame*, ColorChooserClient*, const Color&)
{
return nullptr;
}
-PassRefPtr<DateTimeChooser> EmptyChromeClient::openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&)
+PassRefPtrWillBeRawPtr<DateTimeChooser> EmptyChromeClient::openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&)
{
- return PassRefPtr<DateTimeChooser>();
+ return nullptr;
}
void EmptyChromeClient::openTextDataListChooser(HTMLInputElement&)
{
}
-void EmptyChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser>)
+void EmptyChromeClient::runOpenPanel(LocalFrame*, PassRefPtr<FileChooser>)
{
}
@@ -105,43 +109,53 @@ NavigationPolicy EmptyFrameLoaderClient::decidePolicyForNavigation(const Resourc
return NavigationPolicyIgnore;
}
-void EmptyFrameLoaderClient::dispatchWillSendSubmitEvent(PassRefPtr<FormState>)
+void EmptyFrameLoaderClient::dispatchWillSendSubmitEvent(HTMLFormElement*)
{
}
-void EmptyFrameLoaderClient::dispatchWillSubmitForm(PassRefPtr<FormState>)
+void EmptyFrameLoaderClient::dispatchWillSubmitForm(HTMLFormElement*)
{
}
-PassRefPtr<DocumentLoader> EmptyFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
+PassRefPtr<DocumentLoader> EmptyFrameLoaderClient::createDocumentLoader(LocalFrame* frame, const ResourceRequest& request, const SubstituteData& substituteData)
{
- return DocumentLoader::create(request, substituteData);
+ return DocumentLoader::create(frame, request, substituteData);
}
-PassRefPtr<Frame> EmptyFrameLoaderClient::createFrame(const KURL&, const String&, const String&, HTMLFrameOwnerElement*)
+PassRefPtr<LocalFrame> EmptyFrameLoaderClient::createFrame(const KURL&, const AtomicString&, const Referrer&, HTMLFrameOwnerElement*)
{
- return 0;
+ return nullptr;
}
-PassRefPtr<Widget> EmptyFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool)
+PassRefPtr<Widget> EmptyFrameLoaderClient::createPlugin(HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool, DetachedPluginPolicy)
{
- return 0;
+ return nullptr;
}
-PassRefPtr<Widget> EmptyFrameLoaderClient::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&)
+PassRefPtr<Widget> EmptyFrameLoaderClient::createJavaAppletWidget(HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&)
{
- return 0;
+ return nullptr;
}
void EmptyTextCheckerClient::requestCheckingOfString(PassRefPtr<TextCheckingRequest>)
{
}
-void EmptyFrameLoaderClient::didRequestAutocomplete(PassRefPtr<FormState>)
+void EmptyFrameLoaderClient::didRequestAutocomplete(HTMLFormElement*)
{
}
-PassOwnPtr<blink::WebServiceWorkerProvider> EmptyFrameLoaderClient::createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>)
+PassOwnPtr<blink::WebServiceWorkerProvider> EmptyFrameLoaderClient::createServiceWorkerProvider()
+{
+ return nullptr;
+}
+
+PassOwnPtr<blink::WebApplicationCacheHost> EmptyFrameLoaderClient::createApplicationCacheHost(blink::WebApplicationCacheHostClient*)
+{
+ return nullptr;
+}
+
+PassOwnPtr<StorageNamespace> EmptyStorageClient::createSessionStorageNamespace()
{
return nullptr;
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/EmptyClients.h b/chromium/third_party/WebKit/Source/core/loader/EmptyClients.h
index ce31e022eaa..2da5eaaa47d 100644
--- a/chromium/third_party/WebKit/Source/core/loader/EmptyClients.h
+++ b/chromium/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -37,21 +37,21 @@
#include "core/page/ContextMenuClient.h"
#include "core/page/DragClient.h"
#include "core/page/EditorClient.h"
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
#include "core/page/Page.h"
#include "core/page/SpellCheckerClient.h"
-#include "core/platform/DragImage.h"
+#include "core/page/StorageClient.h"
+#include "platform/DragImage.h"
#include "platform/geometry/FloatRect.h"
#include "platform/network/ResourceError.h"
#include "platform/text/TextCheckerClient.h"
#include "public/platform/WebScreenInfo.h"
#include "wtf/Forward.h"
-
#include <v8.h>
/*
This file holds empty Client stubs for use by WebCore.
- Viewless element needs to create a dummy Page->Frame->FrameView tree for use in parsing or executing JavaScript.
+ Viewless element needs to create a dummy Page->LocalFrame->FrameView tree for use in parsing or executing JavaScript.
This tree depends heavily on Clients (usually provided by WebKit classes).
This file was first created for SVGImage as it had no way to access the current Page (nor should it,
@@ -64,8 +64,6 @@
namespace WebCore {
-class GraphicsContext3D;
-
class EmptyChromeClient : public ChromeClient {
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -79,13 +77,13 @@ public:
virtual FloatRect pageRect() OVERRIDE { return FloatRect(); }
virtual void focus() OVERRIDE { }
- virtual void unfocus() OVERRIDE { }
- virtual bool canTakeFocus(FocusDirection) OVERRIDE { return false; }
- virtual void takeFocus(FocusDirection) OVERRIDE { }
+ virtual bool canTakeFocus(FocusType) OVERRIDE { return false; }
+ virtual void takeFocus(FocusType) OVERRIDE { }
virtual void focusedNodeChanged(Node*) OVERRIDE { }
- virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) OVERRIDE { return 0; }
+ virtual void focusedFrameChanged(LocalFrame*) OVERRIDE { }
+ virtual Page* createWindow(LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) OVERRIDE { return 0; }
virtual void show(NavigationPolicy) OVERRIDE { }
virtual bool canRunModal() OVERRIDE { return false; }
@@ -106,21 +104,19 @@ public:
virtual void setResizable(bool) OVERRIDE { }
virtual bool shouldReportDetailedMessageForSource(const String&) OVERRIDE { return false; }
- virtual void addMessageToConsole(MessageSource, MessageLevel, const String&, unsigned, const String&, const String&) OVERRIDE { }
+ virtual void addMessageToConsole(LocalFrame*, MessageSource, MessageLevel, const String&, unsigned, const String&, const String&) OVERRIDE { }
virtual bool canRunBeforeUnloadConfirmPanel() OVERRIDE { return false; }
- virtual bool runBeforeUnloadConfirmPanel(const String&, Frame*) OVERRIDE { return true; }
+ virtual bool runBeforeUnloadConfirmPanel(const String&, LocalFrame*) OVERRIDE { return true; }
virtual void closeWindowSoon() OVERRIDE { }
- virtual void runJavaScriptAlert(Frame*, const String&) OVERRIDE { }
- virtual bool runJavaScriptConfirm(Frame*, const String&) OVERRIDE { return false; }
- virtual bool runJavaScriptPrompt(Frame*, const String&, const String&, String&) OVERRIDE { return false; }
+ virtual void runJavaScriptAlert(LocalFrame*, const String&) OVERRIDE { }
+ virtual bool runJavaScriptConfirm(LocalFrame*, const String&) OVERRIDE { return false; }
+ virtual bool runJavaScriptPrompt(LocalFrame*, const String&, const String&, String&) OVERRIDE { return false; }
virtual bool hasOpenedPopup() const OVERRIDE { return false; }
- virtual PassRefPtr<PopupMenu> createPopupMenu(Frame&, PopupMenuClient*) const OVERRIDE;
- virtual PagePopup* openPagePopup(PagePopupClient*, const IntRect&) OVERRIDE { return 0; }
- virtual void closePagePopup(PagePopup*) OVERRIDE { }
+ virtual PassRefPtr<PopupMenu> createPopupMenu(LocalFrame&, PopupMenuClient*) const OVERRIDE;
virtual void setPagePopupDriver(PagePopupDriver*) OVERRIDE { }
virtual void resetPagePopupDriver() OVERRIDE { }
@@ -135,63 +131,55 @@ public:
virtual void scroll(const IntSize&, const IntRect&, const IntRect&) OVERRIDE { }
virtual void scheduleAnimation() OVERRIDE { }
- virtual bool isCompositorFramePending() const OVERRIDE { return false; }
-
- virtual IntPoint screenToRootView(const IntPoint& p) const OVERRIDE { return p; }
virtual IntRect rootViewToScreen(const IntRect& r) const OVERRIDE { return r; }
virtual blink::WebScreenInfo screenInfo() const OVERRIDE { return blink::WebScreenInfo(); }
- virtual void contentsSizeChanged(Frame*, const IntSize&) const OVERRIDE { }
+ virtual void contentsSizeChanged(LocalFrame*, const IntSize&) const OVERRIDE { }
virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned) OVERRIDE { }
virtual void setToolTip(const String&, TextDirection) OVERRIDE { }
- virtual void print(Frame*) OVERRIDE { }
+ virtual void print(LocalFrame*) OVERRIDE { }
virtual void enumerateChosenDirectory(FileChooser*) OVERRIDE { }
- virtual PassOwnPtr<ColorChooser> createColorChooser(ColorChooserClient*, const Color&) OVERRIDE;
- virtual PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) OVERRIDE;
+ virtual PassOwnPtr<ColorChooser> createColorChooser(LocalFrame*, ColorChooserClient*, const Color&) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) OVERRIDE;
virtual void openTextDataListChooser(HTMLInputElement&) OVERRIDE;
- virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) OVERRIDE;
-
- virtual void formStateDidChange(const Node*) OVERRIDE { }
+ virtual void runOpenPanel(LocalFrame*, PassRefPtr<FileChooser>) OVERRIDE;
virtual void setCursor(const Cursor&) OVERRIDE { }
- virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) OVERRIDE { }
- virtual void scheduleCompositingLayerFlush() OVERRIDE { }
+ virtual void attachRootGraphicsLayer(GraphicsLayer*) OVERRIDE { }
virtual void needTouchEvents(bool) OVERRIDE { }
virtual void setTouchAction(TouchAction touchAction) OVERRIDE { };
- virtual void numWheelEventHandlersChanged(unsigned) OVERRIDE { }
-
- virtual bool shouldRubberBandInDirection(WebCore::ScrollDirection) const OVERRIDE { return false; }
-
- virtual bool isEmptyChromeClient() const OVERRIDE { return true; }
-
- virtual void didAssociateFormControls(const Vector<RefPtr<Element> >&) OVERRIDE { }
-
- virtual void popupOpened(PopupContainer* popupContainer, const IntRect& bounds,
- bool handleExternal) { }
- virtual void popupClosed(PopupContainer* popupContainer) OVERRIDE { }
+ virtual void didAssociateFormControls(const WillBeHeapVector<RefPtrWillBeMember<Element> >&) OVERRIDE { }
virtual void annotatedRegionsChanged() OVERRIDE { }
virtual bool paintCustomOverhangArea(GraphicsContext*, const IntRect&, const IntRect&, const IntRect&) OVERRIDE { return false; }
virtual String acceptLanguages() OVERRIDE;
};
-class EmptyFrameLoaderClient : public FrameLoaderClient {
+class EmptyFrameLoaderClient FINAL : public FrameLoaderClient {
WTF_MAKE_NONCOPYABLE(EmptyFrameLoaderClient); WTF_MAKE_FAST_ALLOCATED;
public:
EmptyFrameLoaderClient() { }
virtual ~EmptyFrameLoaderClient() { }
- virtual void frameLoaderDestroyed() OVERRIDE { }
virtual bool hasWebView() const OVERRIDE { return true; } // mainly for assertions
+ virtual Frame* opener() const OVERRIDE { return 0; }
+ virtual void setOpener(Frame*) OVERRIDE { }
+
+ virtual Frame* parent() const OVERRIDE { return 0; }
+ virtual Frame* top() const OVERRIDE { return 0; }
+ virtual Frame* previousSibling() const OVERRIDE { return 0; }
+ virtual Frame* nextSibling() const OVERRIDE { return 0; }
+ virtual Frame* firstChild() const OVERRIDE { return 0; }
+ virtual Frame* lastChild() const OVERRIDE { return 0; }
virtual void detachedFromParent() OVERRIDE { }
virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long, ResourceRequest&, const ResourceResponse&) OVERRIDE { }
@@ -205,25 +193,26 @@ public:
virtual void dispatchDidStartProvisionalLoad() OVERRIDE { }
virtual void dispatchDidReceiveTitle(const String&) OVERRIDE { }
virtual void dispatchDidChangeIcons(IconType) OVERRIDE { }
- virtual void dispatchDidCommitLoad(Frame*, HistoryItem*, NavigationHistoryPolicy) OVERRIDE { }
+ virtual void dispatchDidCommitLoad(LocalFrame*, HistoryItem*, HistoryCommitType) OVERRIDE { }
virtual void dispatchDidFailProvisionalLoad(const ResourceError&) OVERRIDE { }
virtual void dispatchDidFailLoad(const ResourceError&) OVERRIDE { }
virtual void dispatchDidFinishDocumentLoad() OVERRIDE { }
virtual void dispatchDidFinishLoad() OVERRIDE { }
virtual void dispatchDidFirstVisuallyNonEmptyLayout() OVERRIDE { }
+ virtual void dispatchDidChangeThemeColor() OVERRIDE { };
virtual NavigationPolicy decidePolicyForNavigation(const ResourceRequest&, DocumentLoader*, NavigationPolicy) OVERRIDE;
- virtual void dispatchWillSendSubmitEvent(PassRefPtr<FormState>) OVERRIDE;
- virtual void dispatchWillSubmitForm(PassRefPtr<FormState>) OVERRIDE;
+ virtual void dispatchWillSendSubmitEvent(HTMLFormElement*) OVERRIDE;
+ virtual void dispatchWillSubmitForm(HTMLFormElement*) OVERRIDE;
- virtual void postProgressStartedNotification() OVERRIDE { }
- virtual void postProgressEstimateChangedNotification() OVERRIDE { }
- virtual void postProgressFinishedNotification() OVERRIDE { }
+ virtual void didStartLoading(LoadStartType) OVERRIDE { }
+ virtual void progressEstimateChanged(double) OVERRIDE { }
+ virtual void didStopLoading() OVERRIDE { }
virtual void loadURLExternally(const ResourceRequest&, NavigationPolicy, const String& = String()) OVERRIDE { }
- virtual PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest&, const SubstituteData&) OVERRIDE;
+ virtual PassRefPtr<DocumentLoader> createDocumentLoader(LocalFrame*, const ResourceRequest&, const SubstituteData&) OVERRIDE;
virtual String userAgent(const KURL&) OVERRIDE { return ""; }
@@ -237,26 +226,29 @@ public:
virtual void didDetectXSS(const KURL&, bool) OVERRIDE { }
virtual void didDispatchPingLoader(const KURL&) OVERRIDE { }
virtual void selectorMatchChanged(const Vector<String>&, const Vector<String>&) OVERRIDE { }
- virtual PassRefPtr<Frame> createFrame(const KURL&, const String&, const String&, HTMLFrameOwnerElement*) OVERRIDE;
- virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool) OVERRIDE;
- virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&) OVERRIDE;
+ virtual PassRefPtr<LocalFrame> createFrame(const KURL&, const AtomicString&, const Referrer&, HTMLFrameOwnerElement*) OVERRIDE;
+ virtual PassRefPtr<Widget> createPlugin(HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool, DetachedPluginPolicy) OVERRIDE;
+ virtual bool canCreatePluginWithoutRenderer(const String& mimeType) const OVERRIDE { return false; }
+ virtual PassRefPtr<Widget> createJavaAppletWidget(HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&) OVERRIDE;
virtual ObjectContentType objectContentType(const KURL&, const String&, bool) OVERRIDE { return ObjectContentType(); }
- virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*) OVERRIDE { }
+ virtual void dispatchDidClearWindowObjectInMainWorld() OVERRIDE { }
virtual void documentElementAvailable() OVERRIDE { }
virtual void didCreateScriptContext(v8::Handle<v8::Context>, int extensionGroup, int worldId) OVERRIDE { }
virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId) OVERRIDE { }
virtual bool allowScriptExtension(const String& extensionName, int extensionGroup, int worldId) OVERRIDE { return false; }
- virtual blink::WebCookieJar* cookieJar() const { return 0; }
+ virtual blink::WebCookieJar* cookieJar() const OVERRIDE { return 0; }
+
+ virtual void didRequestAutocomplete(HTMLFormElement*) OVERRIDE;
- virtual void didRequestAutocomplete(PassRefPtr<FormState>) OVERRIDE;
- virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>) OVERRIDE;
+ virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider() OVERRIDE;
+ virtual PassOwnPtr<blink::WebApplicationCacheHost> createApplicationCacheHost(blink::WebApplicationCacheHostClient*) OVERRIDE;
};
-class EmptyTextCheckerClient : public TextCheckerClient {
+class EmptyTextCheckerClient FINAL : public TextCheckerClient {
public:
virtual bool shouldEraseMarkersAfterChangeSelection(TextCheckingType) const OVERRIDE { return true; }
virtual void checkSpellingOfString(const String&, int*, int*) OVERRIDE { }
@@ -265,7 +257,7 @@ public:
virtual void requestCheckingOfString(PassRefPtr<TextCheckingRequest>) OVERRIDE;
};
-class EmptySpellCheckerClient : public SpellCheckerClient {
+class EmptySpellCheckerClient FINAL : public SpellCheckerClient {
WTF_MAKE_NONCOPYABLE(EmptySpellCheckerClient); WTF_MAKE_FAST_ALLOCATED;
public:
EmptySpellCheckerClient() { }
@@ -275,7 +267,7 @@ public:
virtual void toggleContinuousSpellChecking() OVERRIDE { }
virtual bool isGrammarCheckingEnabled() OVERRIDE { return false; }
- TextCheckerClient& textChecker() { return m_textCheckerClient; }
+ virtual TextCheckerClient& textChecker() OVERRIDE { return m_textCheckerClient; }
virtual void updateSpellingUIWithMisspelledWord(const String&) OVERRIDE { }
virtual void showSpellingUI(bool) OVERRIDE { }
@@ -285,23 +277,22 @@ private:
EmptyTextCheckerClient m_textCheckerClient;
};
-class EmptyEditorClient : public EditorClient {
+class EmptyEditorClient FINAL : public EditorClient {
WTF_MAKE_NONCOPYABLE(EmptyEditorClient); WTF_MAKE_FAST_ALLOCATED;
public:
EmptyEditorClient() { }
virtual ~EmptyEditorClient() { }
virtual void respondToChangedContents() OVERRIDE { }
- virtual void respondToChangedSelection(SelectionType) OVERRIDE { }
+ virtual void respondToChangedSelection(LocalFrame*, SelectionType) OVERRIDE { }
- virtual bool canCopyCut(Frame*, bool defaultValue) const OVERRIDE { return defaultValue; }
- virtual bool canPaste(Frame*, bool defaultValue) const OVERRIDE { return defaultValue; }
+ virtual bool canCopyCut(LocalFrame*, bool defaultValue) const OVERRIDE { return defaultValue; }
+ virtual bool canPaste(LocalFrame*, bool defaultValue) const OVERRIDE { return defaultValue; }
- virtual void didExecuteCommand(String) OVERRIDE { }
virtual bool handleKeyboardEvent() OVERRIDE { return false; }
};
-class EmptyContextMenuClient : public ContextMenuClient {
+class EmptyContextMenuClient FINAL : public ContextMenuClient {
WTF_MAKE_NONCOPYABLE(EmptyContextMenuClient); WTF_MAKE_FAST_ALLOCATED;
public:
EmptyContextMenuClient() { }
@@ -310,16 +301,16 @@ public:
virtual void clearContextMenu() OVERRIDE { }
};
-class EmptyDragClient : public DragClient {
+class EmptyDragClient FINAL : public DragClient {
WTF_MAKE_NONCOPYABLE(EmptyDragClient); WTF_MAKE_FAST_ALLOCATED;
public:
EmptyDragClient() { }
virtual ~EmptyDragClient() {}
virtual DragDestinationAction actionMaskForDrag(DragData*) OVERRIDE { return DragDestinationActionNone; }
- virtual void startDrag(DragImage*, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool) OVERRIDE { }
+ virtual void startDrag(DragImage*, const IntPoint&, const IntPoint&, Clipboard*, LocalFrame*, bool) OVERRIDE { }
};
-class EmptyInspectorClient : public InspectorClient {
+class EmptyInspectorClient FINAL : public InspectorClient {
WTF_MAKE_NONCOPYABLE(EmptyInspectorClient); WTF_MAKE_FAST_ALLOCATED;
public:
EmptyInspectorClient() { }
@@ -329,13 +320,19 @@ public:
virtual void hideHighlight() OVERRIDE { }
};
-class EmptyBackForwardClient : public BackForwardClient {
+class EmptyBackForwardClient FINAL : public BackForwardClient {
public:
virtual int backListCount() OVERRIDE { return 0; }
virtual int forwardListCount() OVERRIDE { return 0; }
virtual int backForwardListCount() OVERRIDE { return 0; }
};
+class EmptyStorageClient FINAL : public StorageClient {
+public:
+ virtual PassOwnPtr<StorageNamespace> createSessionStorageNamespace() OVERRIDE;
+ virtual bool canAccessStorage(LocalFrame*, StorageType) const OVERRIDE { return false; }
+};
+
void fillWithEmptyClients(Page::PageClients&);
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/FormState.cpp b/chromium/third_party/WebKit/Source/core/loader/FormState.cpp
index 7bbea4323b7..a6d9f1e8da4 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FormState.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/FormState.cpp
@@ -34,17 +34,22 @@
namespace WebCore {
-inline FormState::FormState(PassRefPtr<HTMLFormElement> form, StringPairVector& textFieldValuesToAdopt, PassRefPtr<Document> sourceDocument, FormSubmissionTrigger formSubmissionTrigger)
+inline FormState::FormState(HTMLFormElement& form, FormSubmissionTrigger formSubmissionTrigger)
: m_form(form)
- , m_sourceDocument(sourceDocument)
+ , m_sourceDocument(form.document())
, m_formSubmissionTrigger(formSubmissionTrigger)
{
- m_textFieldValues.swap(textFieldValuesToAdopt);
}
-PassRefPtr<FormState> FormState::create(PassRefPtr<HTMLFormElement> form, StringPairVector& textFieldValuesToAdopt, PassRefPtr<Document> sourceDocument, FormSubmissionTrigger formSubmissionTrigger)
+PassRefPtrWillBeRawPtr<FormState> FormState::create(HTMLFormElement& form, FormSubmissionTrigger formSubmissionTrigger)
{
- return adoptRef(new FormState(form, textFieldValuesToAdopt, sourceDocument, formSubmissionTrigger));
+ return adoptRefWillBeNoop(new FormState(form, formSubmissionTrigger));
+}
+
+void FormState::trace(Visitor* visitor)
+{
+ visitor->trace(m_form);
+ visitor->trace(m_sourceDocument);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/FormState.h b/chromium/third_party/WebKit/Source/core/loader/FormState.h
index 058db51e6c4..6fd7d53610b 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FormState.h
+++ b/chromium/third_party/WebKit/Source/core/loader/FormState.h
@@ -29,8 +29,9 @@
#ifndef FormState_h
#define FormState_h
+#include "platform/heap/Handle.h"
#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
+#include "wtf/RefPtr.h"
namespace WebCore {
@@ -42,23 +43,20 @@ namespace WebCore {
NotSubmittedByJavaScript
};
- typedef Vector<std::pair<String, String> > StringPairVector;
-
- class FormState : public RefCounted<FormState> {
+ class FormState FINAL : public RefCountedWillBeGarbageCollected<FormState> {
public:
- static PassRefPtr<FormState> create(PassRefPtr<HTMLFormElement>, StringPairVector& textFieldValuesToAdopt, PassRefPtr<Document>, FormSubmissionTrigger);
+ static PassRefPtrWillBeRawPtr<FormState> create(HTMLFormElement&, FormSubmissionTrigger);
+ void trace(Visitor*);
HTMLFormElement* form() const { return m_form.get(); }
- const StringPairVector& textFieldValues() const { return m_textFieldValues; }
Document* sourceDocument() const { return m_sourceDocument.get(); }
FormSubmissionTrigger formSubmissionTrigger() const { return m_formSubmissionTrigger; }
private:
- FormState(PassRefPtr<HTMLFormElement>, StringPairVector& textFieldValuesToAdopt, PassRefPtr<Document>, FormSubmissionTrigger);
+ FormState(HTMLFormElement&, FormSubmissionTrigger);
- RefPtr<HTMLFormElement> m_form;
- StringPairVector m_textFieldValues;
- RefPtr<Document> m_sourceDocument;
+ RefPtrWillBeMember<HTMLFormElement> m_form;
+ RefPtrWillBeMember<Document> m_sourceDocument;
FormSubmissionTrigger m_formSubmissionTrigger;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp b/chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp
index 178a996bc76..b6503ab13ed 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/FormSubmission.cpp
@@ -31,8 +31,7 @@
#include "config.h"
#include "core/loader/FormSubmission.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/events/Event.h"
#include "core/html/DOMFormData.h"
@@ -42,9 +41,12 @@
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/loader/FrameLoader.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/heap/Handle.h"
#include "platform/network/FormData.h"
#include "platform/network/FormDataBuilder.h"
#include "wtf/CurrentTime.h"
+#include "wtf/text/StringBuilder.h"
#include "wtf/text/TextEncoding.h"
namespace WebCore {
@@ -73,26 +75,27 @@ static void appendMailtoPostFormDataToURL(KURL& url, const FormData& data, const
FormDataBuilder::encodeStringAsFormData(bodyData, body.utf8());
body = String(bodyData.data(), bodyData.size()).replaceWithLiteral('+', "%20");
- String query = url.query();
+ StringBuilder query;
+ query.append(url.query());
if (!query.isEmpty())
query.append('&');
query.append(body);
- url.setQuery(query);
+ url.setQuery(query.toString());
}
void FormSubmission::Attributes::parseAction(const String& action)
{
- // FIXME: Can we parse into a KURL?
+ // m_action cannot be converted to KURL (bug https://crbug.com/388664)
m_action = stripLeadingAndTrailingHTMLSpaces(action);
}
-String FormSubmission::Attributes::parseEncodingType(const String& type)
+AtomicString FormSubmission::Attributes::parseEncodingType(const String& type)
{
if (equalIgnoringCase(type, "multipart/form-data"))
- return "multipart/form-data";
+ return AtomicString("multipart/form-data", AtomicString::ConstructFromLiteral);
if (equalIgnoringCase(type, "text/plain"))
- return "text/plain";
- return "application/x-www-form-urlencoded";
+ return AtomicString("text/plain", AtomicString::ConstructFromLiteral);
+ return AtomicString("application/x-www-form-urlencoded", AtomicString::ConstructFromLiteral);
}
void FormSubmission::Attributes::updateEncodingType(const String& type)
@@ -140,7 +143,7 @@ void FormSubmission::Attributes::copyFrom(const Attributes& other)
m_acceptCharset = other.m_acceptCharset;
}
-inline FormSubmission::FormSubmission(Method method, const KURL& action, const String& target, const String& contentType, PassRefPtr<FormState> state, PassRefPtr<FormData> data, const String& boundary, PassRefPtr<Event> event)
+inline FormSubmission::FormSubmission(Method method, const KURL& action, const AtomicString& target, const AtomicString& contentType, PassRefPtrWillBeRawPtr<FormState> state, PassRefPtr<FormData> data, const String& boundary, PassRefPtrWillBeRawPtr<Event> event)
: m_method(method)
, m_action(action)
, m_target(target)
@@ -158,7 +161,7 @@ inline FormSubmission::FormSubmission(const String& result)
{
}
-PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtr<Event> event, FormSubmissionTrigger trigger)
+PassRefPtrWillBeRawPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const Attributes& attributes, PassRefPtrWillBeRawPtr<Event> event, FormSubmissionTrigger trigger)
{
ASSERT(form);
@@ -175,7 +178,7 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
FormSubmission::Attributes copiedAttributes;
copiedAttributes.copyFrom(attributes);
if (submitButton) {
- String attributeValue;
+ AtomicString attributeValue;
if (!(attributeValue = submitButton->fastGetAttribute(formactionAttr)).isNull())
copiedAttributes.parseAction(attributeValue);
if (!(attributeValue = submitButton->fastGetAttribute(formenctypeAttr)).isNull())
@@ -186,37 +189,38 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
copiedAttributes.setTarget(attributeValue);
}
- if (copiedAttributes.method() == DialogMethod)
- return adoptRef(new FormSubmission(submitButton->resultForDialogSubmit()));
+ if (copiedAttributes.method() == DialogMethod) {
+ if (submitButton)
+ return adoptRefWillBeNoop(new FormSubmission(submitButton->resultForDialogSubmit()));
+ return adoptRefWillBeNoop(new FormSubmission(""));
+ }
Document& document = form->document();
KURL actionURL = document.completeURL(copiedAttributes.action().isEmpty() ? document.url().string() : copiedAttributes.action());
bool isMailtoForm = actionURL.protocolIs("mailto");
bool isMultiPartForm = false;
- String encodingType = copiedAttributes.encodingType();
+ AtomicString encodingType = copiedAttributes.encodingType();
if (copiedAttributes.method() == PostMethod) {
isMultiPartForm = copiedAttributes.isMultiPartForm();
if (isMultiPartForm && isMailtoForm) {
- encodingType = "application/x-www-form-urlencoded";
+ encodingType = AtomicString("application/x-www-form-urlencoded", AtomicString::ConstructFromLiteral);
isMultiPartForm = false;
}
}
WTF::TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document.inputEncoding(), document.defaultCharset());
- RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission());
- Vector<pair<String, String> > formValues;
+ RefPtrWillBeRawPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission());
bool containsPasswordData = false;
for (unsigned i = 0; i < form->associatedElements().size(); ++i) {
FormAssociatedElement* control = form->associatedElements()[i];
- HTMLElement* element = toHTMLElement(control);
- if (!element->isDisabledFormControl())
+ ASSERT(control);
+ HTMLElement& element = toHTMLElement(*control);
+ if (!element.isDisabledFormControl())
control->appendFormData(*domFormData, isMultiPartForm);
- if (element->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(element);
- if (input->isTextField())
- formValues.append(pair<String, String>(input->name().string(), input->value()));
- if (input->isPasswordField() && !input->value().isEmpty())
+ if (isHTMLInputElement(element)) {
+ HTMLInputElement& input = toHTMLInputElement(element);
+ if (input.isPasswordField() && !input.value().isEmpty())
containsPasswordData = true;
}
}
@@ -225,10 +229,10 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
String boundary;
if (isMultiPartForm) {
- formData = domFormData->createMultiPartFormData(domFormData->encoding());
+ formData = domFormData->createMultiPartFormData();
boundary = formData->boundary().data();
} else {
- formData = domFormData->createFormData(domFormData->encoding(), attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType));
+ formData = domFormData->createFormData(attributes.method() == GetMethod ? FormData::FormURLEncoded : FormData::parseEncodingType(encodingType));
if (copiedAttributes.method() == PostMethod && isMailtoForm) {
// Convert the form data into a string that we put into the URL.
appendMailtoPostFormDataToURL(actionURL, *formData, encodingType);
@@ -238,9 +242,14 @@ PassRefPtr<FormSubmission> FormSubmission::create(HTMLFormElement* form, const A
formData->setIdentifier(generateFormDataIdentifier());
formData->setContainsPasswordData(containsPasswordData);
- String targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document.baseTarget() : copiedAttributes.target();
- RefPtr<FormState> formState = FormState::create(form, formValues, &document, trigger);
- return adoptRef(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, event));
+ AtomicString targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document.baseTarget() : copiedAttributes.target();
+ return adoptRefWillBeNoop(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, FormState::create(*form, trigger), formData.release(), boundary, event));
+}
+
+void FormSubmission::trace(Visitor* visitor)
+{
+ visitor->trace(m_formState);
+ visitor->trace(m_event);
}
KURL FormSubmission::requestURL() const
@@ -258,7 +267,7 @@ void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest)
if (!m_target.isEmpty())
frameRequest.setFrameName(m_target);
- if (!m_referrer.isEmpty())
+ if (!m_referrer.referrer.isEmpty())
frameRequest.resourceRequest().setHTTPReferrer(m_referrer);
if (m_method == FormSubmission::PostMethod) {
@@ -273,7 +282,7 @@ void FormSubmission::populateFrameLoadRequest(FrameLoadRequest& frameRequest)
}
frameRequest.resourceRequest().setURL(requestURL());
- FrameLoader::addHTTPOriginIfNeeded(frameRequest.resourceRequest(), m_origin);
+ FrameLoader::addHTTPOriginIfNeeded(frameRequest.resourceRequest(), AtomicString(m_origin));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/FormSubmission.h b/chromium/third_party/WebKit/Source/core/loader/FormSubmission.h
index d53b2e686ec..956c2b0dfcb 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FormSubmission.h
+++ b/chromium/third_party/WebKit/Source/core/loader/FormSubmission.h
@@ -32,7 +32,9 @@
#define FormSubmission_h
#include "core/loader/FormState.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/Referrer.h"
namespace WTF{
class TextEncoding;
@@ -46,7 +48,7 @@ class FormData;
struct FrameLoadRequest;
class HTMLFormElement;
-class FormSubmission : public RefCounted<FormSubmission> {
+class FormSubmission : public RefCountedWillBeGarbageCollectedFinalized<FormSubmission> {
public:
enum Method { GetMethod, PostMethod, DialogMethod };
@@ -56,7 +58,7 @@ public:
Attributes()
: m_method(GetMethod)
, m_isMultiPartForm(false)
- , m_encodingType("application/x-www-form-urlencoded")
+ , m_encodingType("application/x-www-form-urlencoded", AtomicString::ConstructFromLiteral)
{
}
@@ -68,11 +70,11 @@ public:
const String& action() const { return m_action; }
void parseAction(const String&);
- const String& target() const { return m_target; }
- void setTarget(const String& target) { m_target = target; }
+ const AtomicString& target() const { return m_target; }
+ void setTarget(const AtomicString& target) { m_target = target; }
- const String& encodingType() const { return m_encodingType; }
- static String parseEncodingType(const String&);
+ const AtomicString& encodingType() const { return m_encodingType; }
+ static AtomicString parseEncodingType(const String&);
void updateEncodingType(const String&);
bool isMultiPartForm() const { return m_isMultiPartForm; }
@@ -86,12 +88,13 @@ public:
bool m_isMultiPartForm;
String m_action;
- String m_target;
- String m_encodingType;
+ AtomicString m_target;
+ AtomicString m_encodingType;
String m_acceptCharset;
};
- static PassRefPtr<FormSubmission> create(HTMLFormElement*, const Attributes&, PassRefPtr<Event> event, FormSubmissionTrigger);
+ static PassRefPtrWillBeRawPtr<FormSubmission> create(HTMLFormElement*, const Attributes&, PassRefPtrWillBeRawPtr<Event>, FormSubmissionTrigger);
+ void trace(Visitor*);
void populateFrameLoadRequest(FrameLoadRequest&);
@@ -99,36 +102,32 @@ public:
Method method() const { return m_method; }
const KURL& action() const { return m_action; }
- const String& target() const { return m_target; }
- void clearTarget() { m_target = String(); }
- const String& contentType() const { return m_contentType; }
+ const AtomicString& target() const { return m_target; }
+ void clearTarget() { m_target = nullAtom; }
FormState* state() const { return m_formState.get(); }
FormData* data() const { return m_formData.get(); }
- const String boundary() const { return m_boundary; }
Event* event() const { return m_event.get(); }
- const String& referrer() const { return m_referrer; }
- void setReferrer(const String& referrer) { m_referrer = referrer; }
- const String& origin() const { return m_origin; }
+ void setReferrer(const Referrer& referrer) { m_referrer = referrer; }
void setOrigin(const String& origin) { m_origin = origin; }
const String& result() const { return m_result; }
private:
- FormSubmission(Method, const KURL& action, const String& target, const String& contentType, PassRefPtr<FormState>, PassRefPtr<FormData>, const String& boundary, PassRefPtr<Event>);
+ FormSubmission(Method, const KURL& action, const AtomicString& target, const AtomicString& contentType, PassRefPtrWillBeRawPtr<FormState>, PassRefPtr<FormData>, const String& boundary, PassRefPtrWillBeRawPtr<Event>);
// FormSubmission for DialogMethod
FormSubmission(const String& result);
// FIXME: Hold an instance of Attributes instead of individual members.
Method m_method;
KURL m_action;
- String m_target;
- String m_contentType;
- RefPtr<FormState> m_formState;
+ AtomicString m_target;
+ AtomicString m_contentType;
+ RefPtrWillBeMember<FormState> m_formState;
RefPtr<FormData> m_formData;
String m_boundary;
- RefPtr<Event> m_event;
- String m_referrer;
+ RefPtrWillBeMember<Event> m_event;
+ Referrer m_referrer;
String m_origin;
String m_result;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
index a74ad9be373..493bfcf05a5 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -32,19 +32,20 @@
#include "core/loader/FrameFetchContext.h"
#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/loader/ProgressTracker.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "platform/weborigin/SecurityPolicy.h"
namespace WebCore {
-FrameFetchContext::FrameFetchContext(Frame* frame)
+FrameFetchContext::FrameFetchContext(LocalFrame* frame)
: m_frame(frame)
{
}
@@ -54,29 +55,43 @@ void FrameFetchContext::reportLocalLoadFailed(const KURL& url)
FrameLoader::reportLocalLoadFailed(m_frame, url.elidedString());
}
-void FrameFetchContext::addAdditionalRequestHeaders(Document& document, ResourceRequest& request, Resource::Type type)
+void FrameFetchContext::addAdditionalRequestHeaders(Document* document, ResourceRequest& request, FetchResourceType type)
{
- if (type != Resource::MainResource) {
+ bool isMainResource = type == FetchMainResource;
+ if (!isMainResource) {
String outgoingReferrer;
String outgoingOrigin;
if (request.httpReferrer().isNull()) {
- outgoingReferrer = document.outgoingReferrer();
- outgoingOrigin = document.outgoingOrigin();
+ outgoingReferrer = document->outgoingReferrer();
+ outgoingOrigin = document->outgoingOrigin();
} else {
outgoingReferrer = request.httpReferrer();
outgoingOrigin = SecurityOrigin::createFromString(outgoingReferrer)->toString();
}
- outgoingReferrer = SecurityPolicy::generateReferrerHeader(document.referrerPolicy(), request.url(), outgoingReferrer);
+ outgoingReferrer = SecurityPolicy::generateReferrerHeader(document->referrerPolicy(), request.url(), outgoingReferrer);
if (outgoingReferrer.isEmpty())
request.clearHTTPReferrer();
else if (!request.httpReferrer())
- request.setHTTPReferrer(outgoingReferrer);
+ request.setHTTPReferrer(Referrer(outgoingReferrer, document->referrerPolicy()));
- FrameLoader::addHTTPOriginIfNeeded(request, outgoingOrigin);
+ FrameLoader::addHTTPOriginIfNeeded(request, AtomicString(outgoingOrigin));
}
- m_frame->loader().addExtraFieldsToRequest(request);
+ // The remaining modifications are only necessary for HTTP and HTTPS.
+ if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
+ return;
+
+ m_frame->loader().applyUserAgent(request);
+
+ // Default to sending an empty Origin header if one hasn't been set yet.
+ FrameLoader::addHTTPOriginIfNeeded(request, nullAtom);
+}
+
+void FrameFetchContext::setFirstPartyForCookies(ResourceRequest& request)
+{
+ if (m_frame->tree().top()->isLocalFrame())
+ request.setFirstPartyForCookies(toLocalFrame(m_frame->tree().top())->document()->firstPartyForCookies());
}
CachePolicy FrameFetchContext::cachePolicy(Document* document) const
@@ -88,8 +103,9 @@ CachePolicy FrameFetchContext::cachePolicy(Document* document) const
if (loadType == FrameLoadTypeReloadFromOrigin)
return CachePolicyReload;
- if (Frame* parentFrame = m_frame->tree().parent()) {
- CachePolicy parentCachePolicy = parentFrame->loader().fetchContext().cachePolicy(parentFrame->document());
+ Frame* parentFrame = m_frame->tree().parent();
+ if (parentFrame && parentFrame->isLocalFrame()) {
+ CachePolicy parentCachePolicy = toLocalFrame(parentFrame)->loader().fetchContext().cachePolicy(toLocalFrame(parentFrame)->document());
if (parentCachePolicy != CachePolicyVerify)
return parentCachePolicy;
}
@@ -110,18 +126,21 @@ CachePolicy FrameFetchContext::cachePolicy(Document* document) const
// cannot see imported documents.
inline DocumentLoader* FrameFetchContext::ensureLoader(DocumentLoader* loader)
{
- return loader ? loader : m_frame->loader().activeDocumentLoader();
+ return loader ? loader : m_frame->loader().documentLoader();
}
-void FrameFetchContext::dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority loadPriority)
+void FrameFetchContext::dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority loadPriority, int intraPriorityValue)
{
- m_frame->loader().client()->dispatchDidChangeResourcePriority(identifier, loadPriority);
+ m_frame->loader().client()->dispatchDidChangeResourcePriority(identifier, loadPriority, intraPriorityValue);
}
void FrameFetchContext::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& initiatorInfo)
{
m_frame->loader().applyUserAgent(request);
m_frame->loader().client()->dispatchWillSendRequest(loader, identifier, request, redirectResponse);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceSendRequest", "data", InspectorSendRequestEvent::data(identifier, m_frame, request));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::willSendRequest(m_frame, identifier, ensureLoader(loader), request, redirectResponse, initiatorInfo);
}
@@ -132,40 +151,45 @@ void FrameFetchContext::dispatchDidLoadResourceFromMemoryCache(const ResourceReq
void FrameFetchContext::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r, ResourceLoader* resourceLoader)
{
- if (Page* page = m_frame->page())
- page->progress().incrementProgress(identifier, r);
+ m_frame->loader().progress().incrementProgress(identifier, r);
m_frame->loader().client()->dispatchDidReceiveResponse(loader, identifier, r);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceReceiveResponse", "data", InspectorReceiveResponseEvent::data(identifier, m_frame, r));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didReceiveResourceResponse(m_frame, identifier, ensureLoader(loader), r, resourceLoader);
}
void FrameFetchContext::dispatchDidReceiveData(DocumentLoader*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength)
{
- if (Page* page = m_frame->page())
- page->progress().incrementProgress(identifier, data, dataLength);
+ m_frame->loader().progress().incrementProgress(identifier, data, dataLength);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceReceivedData", "data", InspectorReceiveDataEvent::data(identifier, m_frame, encodedDataLength));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didReceiveData(m_frame, identifier, data, dataLength, encodedDataLength);
}
void FrameFetchContext::dispatchDidDownloadData(DocumentLoader*, unsigned long identifier, int dataLength, int encodedDataLength)
{
- if (Page* page = m_frame->page())
- page->progress().incrementProgress(identifier, 0, dataLength);
+ m_frame->loader().progress().incrementProgress(identifier, 0, dataLength);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceReceivedData", "data", InspectorReceiveDataEvent::data(identifier, m_frame, encodedDataLength));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::didReceiveData(m_frame, identifier, 0, dataLength, encodedDataLength);
}
-void FrameFetchContext::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier, double finishTime)
+void FrameFetchContext::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier, double finishTime, int64_t encodedDataLength)
{
- if (Page* page = m_frame->page())
- page->progress().completeProgress(identifier);
+ m_frame->loader().progress().completeProgress(identifier);
m_frame->loader().client()->dispatchDidFinishLoading(loader, identifier);
- InspectorInstrumentation::didFinishLoading(m_frame, identifier, ensureLoader(loader), finishTime);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceFinish", "data", InspectorResourceFinishEvent::data(identifier, finishTime, false));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didFinishLoading(m_frame, identifier, ensureLoader(loader), finishTime, encodedDataLength);
}
void FrameFetchContext::dispatchDidFail(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
{
- if (Page* page = m_frame->page())
- page->progress().completeProgress(identifier);
- InspectorInstrumentation::didFailLoading(m_frame, identifier, ensureLoader(loader), error);
+ m_frame->loader().progress().completeProgress(identifier);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceFinish", "data", InspectorResourceFinishEvent::data(identifier, 0, true));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didFailLoading(m_frame, identifier, error);
}
void FrameFetchContext::sendRemainingDelegateMessages(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, int dataLength)
@@ -176,7 +200,7 @@ void FrameFetchContext::sendRemainingDelegateMessages(DocumentLoader* loader, un
if (dataLength > 0)
dispatchDidReceiveData(ensureLoader(loader), identifier, 0, dataLength, 0);
- dispatchDidFinishLoading(ensureLoader(loader), identifier, 0);
+ dispatchDidFinishLoading(ensureLoader(loader), identifier, 0, 0);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h b/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h
index f8a2050fd8d..8de3dfb2f49 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameFetchContext.h
@@ -39,35 +39,36 @@ namespace WebCore {
class Document;
class DocumentLoader;
-class Frame;
+class LocalFrame;
class Page;
class ResourceError;
class ResourceLoader;
class ResourceResponse;
class ResourceRequest;
-class FrameFetchContext : public FetchContext {
+class FrameFetchContext FINAL : public FetchContext {
public:
- static PassOwnPtr<FrameFetchContext> create(Frame* frame) { return adoptPtr(new FrameFetchContext(frame)); }
+ static PassOwnPtr<FrameFetchContext> create(LocalFrame* frame) { return adoptPtr(new FrameFetchContext(frame)); }
virtual void reportLocalLoadFailed(const KURL&) OVERRIDE;
- virtual void addAdditionalRequestHeaders(Document&, ResourceRequest&, Resource::Type) OVERRIDE;
+ virtual void addAdditionalRequestHeaders(Document*, ResourceRequest&, FetchResourceType) OVERRIDE;
+ virtual void setFirstPartyForCookies(ResourceRequest&) OVERRIDE;
virtual CachePolicy cachePolicy(Document*) const OVERRIDE;
- virtual void dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority);
+ virtual void dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority, int intraPriorityValue);
virtual void dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo& = FetchInitiatorInfo()) OVERRIDE;
virtual void dispatchDidLoadResourceFromMemoryCache(const ResourceRequest&, const ResourceResponse&) OVERRIDE;
virtual void dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, ResourceLoader* = 0) OVERRIDE;
virtual void dispatchDidReceiveData(DocumentLoader*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength) OVERRIDE;
virtual void dispatchDidDownloadData(DocumentLoader*, unsigned long identifier, int dataLength, int encodedDataLength) OVERRIDE;
- virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier, double finishTime) OVERRIDE;
+ virtual void dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier, double finishTime, int64_t encodedDataLength) OVERRIDE;
virtual void dispatchDidFail(DocumentLoader*, unsigned long identifier, const ResourceError&) OVERRIDE;
virtual void sendRemainingDelegateMessages(DocumentLoader*, unsigned long identifier, const ResourceResponse&, int dataLength) OVERRIDE;
private:
- explicit FrameFetchContext(Frame*);
+ explicit FrameFetchContext(LocalFrame*);
inline DocumentLoader* ensureLoader(DocumentLoader*);
- Frame* m_frame;
+ LocalFrame* m_frame;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h
index 5f854f83f6a..02ed5305385 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoadRequest.h
@@ -34,9 +34,10 @@
#include "platform/network/ResourceRequest.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
struct FrameLoadRequest {
+ STACK_ALLOCATED();
public:
explicit FrameLoadRequest(Document* originDocument)
: m_originDocument(originDocument)
@@ -55,7 +56,7 @@ public:
{
}
- FrameLoadRequest(Document* originDocument, const ResourceRequest& resourceRequest, const String& frameName)
+ FrameLoadRequest(Document* originDocument, const ResourceRequest& resourceRequest, const AtomicString& frameName)
: m_originDocument(originDocument)
, m_resourceRequest(resourceRequest)
, m_frameName(frameName)
@@ -80,8 +81,8 @@ public:
ResourceRequest& resourceRequest() { return m_resourceRequest; }
const ResourceRequest& resourceRequest() const { return m_resourceRequest; }
- const String& frameName() const { return m_frameName; }
- void setFrameName(const String& frameName) { m_frameName = frameName; }
+ const AtomicString& frameName() const { return m_frameName; }
+ void setFrameName(const AtomicString& frameName) { m_frameName = frameName; }
const SubstituteData& substituteData() const { return m_substituteData; }
@@ -92,23 +93,23 @@ public:
void setClientRedirect(ClientRedirectPolicy clientRedirect) { m_clientRedirect = clientRedirect; }
Event* triggeringEvent() const { return m_triggeringEvent.get(); }
- void setTriggeringEvent(PassRefPtr<Event> triggeringEvent) { m_triggeringEvent = triggeringEvent; }
+ void setTriggeringEvent(PassRefPtrWillBeRawPtr<Event> triggeringEvent) { m_triggeringEvent = triggeringEvent; }
FormState* formState() const { return m_formState.get(); }
- void setFormState(PassRefPtr<FormState> formState) { m_formState = formState; }
+ void setFormState(PassRefPtrWillBeRawPtr<FormState> formState) { m_formState = formState; }
ShouldSendReferrer shouldSendReferrer() const { return m_shouldSendReferrer; }
void setShouldSendReferrer(ShouldSendReferrer shouldSendReferrer) { m_shouldSendReferrer = shouldSendReferrer; }
private:
- RefPtr<Document> m_originDocument;
+ RefPtrWillBeMember<Document> m_originDocument;
ResourceRequest m_resourceRequest;
- String m_frameName;
+ AtomicString m_frameName;
SubstituteData m_substituteData;
bool m_lockBackForwardList;
ClientRedirectPolicy m_clientRedirect;
- RefPtr<Event> m_triggeringEvent;
- RefPtr<FormState> m_formState;
+ RefPtrWillBeMember<Event> m_triggeringEvent;
+ RefPtrWillBeMember<FormState> m_formState;
ShouldSendReferrer m_shouldSendReferrer;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index b32c0c08e3a..783f7c6b213 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -35,25 +35,25 @@
#include "config.h"
#include "core/loader/FrameLoader.h"
-#include "HTMLNames.h"
#include "bindings/v8/DOMWrapperWorld.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/SerializedScriptValue.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/dom/ViewportDescription.h"
#include "core/editing/Editor.h"
#include "core/editing/UndoStack.h"
-#include "core/events/Event.h"
#include "core/events/PageTransitionEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/FetchContext.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ResourceLoader.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/PinchViewport.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -80,10 +80,10 @@
#include "core/page/WindowFeatures.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
#include "core/xml/parser/XMLDocumentParser.h"
-#include "modules/webdatabase/DatabaseManager.h"
#include "platform/Logging.h"
#include "platform/UserGestureIndicator.h"
#include "platform/geometry/FloatRect.h"
+#include "platform/network/ContentSecurityPolicyResponseHeaders.h"
#include "platform/network/HTTPParsers.h"
#include "platform/network/ResourceRequest.h"
#include "platform/scroll/ScrollAnimator.h"
@@ -97,54 +97,20 @@ namespace WebCore {
using namespace HTMLNames;
-static const char defaultAcceptHeader[] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
-
bool isBackForwardLoadType(FrameLoadType type)
{
return type == FrameLoadTypeBackForward;
}
-class FrameLoader::FrameProgressTracker {
-public:
- static PassOwnPtr<FrameProgressTracker> create(Frame* frame) { return adoptPtr(new FrameProgressTracker(frame)); }
- ~FrameProgressTracker()
- {
- ASSERT(!m_inProgress || m_frame->page());
- if (m_inProgress)
- m_frame->page()->progress().progressCompleted(m_frame);
- }
-
- void progressStarted()
- {
- ASSERT(m_frame->page());
- if (!m_inProgress)
- m_frame->page()->progress().progressStarted(m_frame);
- m_inProgress = true;
- }
-
- void progressCompleted()
- {
- ASSERT(m_inProgress);
- ASSERT(m_frame->page());
- m_inProgress = false;
- m_frame->page()->progress().progressCompleted(m_frame);
- }
-
-private:
- FrameProgressTracker(Frame* frame)
- : m_frame(frame)
- , m_inProgress(false)
- {
- }
-
- Frame* m_frame;
- bool m_inProgress;
-};
+static bool needsHistoryItemRestore(FrameLoadType type)
+{
+ return type == FrameLoadTypeBackForward || type == FrameLoadTypeReload || type == FrameLoadTypeReloadFromOrigin;
+}
-FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
+FrameLoader::FrameLoader(LocalFrame* frame)
: m_frame(frame)
- , m_client(client)
, m_mixedContentChecker(frame)
+ , m_progressTracker(ProgressTracker::create(frame))
, m_state(FrameStateProvisional)
, m_loadType(FrameLoadTypeStandard)
, m_fetchContext(FrameFetchContext::create(frame))
@@ -152,33 +118,28 @@ FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
, m_isComplete(false)
, m_checkTimer(this, &FrameLoader::checkTimerFired)
, m_shouldCallCheckCompleted(false)
- , m_opener(0)
, m_didAccessInitialDocument(false)
, m_didAccessInitialDocumentTimer(this, &FrameLoader::didAccessInitialDocumentTimerFired)
, m_forcedSandboxFlags(SandboxNone)
+ , m_willDetachClient(false)
{
}
FrameLoader::~FrameLoader()
{
- setOpener(0);
-
- HashSet<Frame*>::iterator end = m_openedFrames.end();
- for (HashSet<Frame*>::iterator it = m_openedFrames.begin(); it != end; ++it)
- (*it)->loader().m_opener = 0;
-
- m_client->frameLoaderDestroyed();
}
void FrameLoader::init()
{
- // This somewhat odd set of steps gives the frame an initial empty document.
- m_provisionalDocumentLoader = m_client->createDocumentLoader(ResourceRequest(KURL(ParsedURLString, emptyString())), SubstituteData());
- m_provisionalDocumentLoader->setFrame(m_frame);
+ m_provisionalDocumentLoader = client()->createDocumentLoader(m_frame, ResourceRequest(KURL(ParsedURLString, emptyString())), SubstituteData());
m_provisionalDocumentLoader->startLoadingMainResource();
m_frame->document()->cancelParsing();
m_stateMachine.advanceTo(FrameLoaderStateMachine::DisplayingInitialEmptyDocument);
- m_progressTracker = FrameProgressTracker::create(m_frame);
+}
+
+FrameLoaderClient* FrameLoader::client() const
+{
+ return static_cast<FrameLoaderClient*>(m_frame->client());
}
void FrameLoader::setDefersLoading(bool defers)
@@ -191,6 +152,10 @@ void FrameLoader::setDefersLoading(bool defers)
m_policyDocumentLoader->setDefersLoading(defers);
if (!defers) {
+ if (m_deferredHistoryLoad.isValid()) {
+ loadHistoryItem(m_deferredHistoryLoad.m_item.get(), m_deferredHistoryLoad.m_type, m_deferredHistoryLoad.m_cachePolicy);
+ m_deferredHistoryLoad = DeferredHistoryLoad();
+ }
m_frame->navigationScheduler().startTimer();
startCheckCompleteTimer();
}
@@ -209,30 +174,32 @@ void FrameLoader::stopLoading()
// FIXME: HTML5 doesn't tell us to set the state to complete when aborting, but we do anyway to match legacy behavior.
// http://www.w3.org/Bugs/Public/show_bug.cgi?id=10537
doc->setReadyState(Document::Complete);
-
- // FIXME: Should the DatabaseManager watch for something like ActiveDOMObject::stop() rather than being special-cased here?
- DatabaseManager::manager().stopDatabases(doc, 0);
}
// FIXME: This will cancel redirection timer, which really needs to be restarted when restoring the frame from b/f cache.
m_frame->navigationScheduler().cancel();
}
-void FrameLoader::saveDocumentAndScrollState()
+void FrameLoader::saveScrollState()
{
- if (!m_currentItem)
+ if (!m_currentItem || !m_frame->view())
return;
- Document* document = m_frame->document();
- if (m_currentItem->isCurrentDocument(document) && document->isActive())
- m_currentItem->setDocumentState(document->formElementsState());
-
- if (!m_frame->view())
+ // Shouldn't clobber anything if we might still restore later.
+ if (needsHistoryItemRestore(m_loadType) && !m_frame->view()->wasScrolledByUser())
return;
m_currentItem->setScrollPoint(m_frame->view()->scrollPosition());
+
+ if (m_frame->settings()->pinchVirtualViewportEnabled())
+ m_currentItem->setPinchViewportScrollPoint(m_frame->host()->pinchViewport().visibleRect().location());
+ else
+ m_currentItem->setPinchViewportScrollPoint(FloatPoint(-1, -1));
+
if (m_frame->isMainFrame() && !m_frame->page()->inspectorController().deviceEmulationEnabled())
m_currentItem->setPageScaleFactor(m_frame->page()->pageScaleFactor());
+
+ client()->didUpdateCurrentHistoryItem();
}
void FrameLoader::clearScrollPositionAndViewState()
@@ -246,11 +213,7 @@ void FrameLoader::clearScrollPositionAndViewState()
bool FrameLoader::closeURL()
{
- // This is done when a back/forward navigation begins (and the current item
- // changes) in loadHistoryItem(). Saving now will save the state will save
- // to the wrong item if the navigation is back/forward.
- if (m_loadType != FrameLoadTypeBackForward)
- saveDocumentAndScrollState();
+ saveScrollState();
// Should only send the pagehide event here if the current document exists.
if (m_frame->document())
@@ -277,7 +240,7 @@ void FrameLoader::didExplicitOpen()
m_frame->navigationScheduler().cancel();
}
-void FrameLoader::clear(ClearOptions options)
+void FrameLoader::clear()
{
if (m_stateMachine.creatingInitialEmptyDocument())
return;
@@ -287,27 +250,11 @@ void FrameLoader::clear(ClearOptions options)
m_frame->document()->prepareForDestruction();
m_frame->document()->removeFocusedElementOfSubtree(m_frame->document());
- // Do this after detaching the document so that the unload event works.
- if (options & ClearWindowProperties) {
- InspectorInstrumentation::frameWindowDiscarded(m_frame, m_frame->domWindow());
- m_frame->domWindow()->reset();
- m_frame->script().clearWindowShell();
- }
-
m_frame->selection().prepareForDestruction();
m_frame->eventHandler().clear();
if (m_frame->view())
m_frame->view()->clear();
- if (options & ClearWindowObject) {
- // Do not drop the DOMWindow (and Document) before the ScriptController and view are cleared
- // as some destructors might still try to access the document.
- m_frame->setDOMWindow(0);
- }
-
- if (options & ClearScriptObjects)
- m_frame->script().clearScriptObjects();
-
m_frame->script().enableEval();
m_frame->navigationScheduler().clear();
@@ -319,44 +266,79 @@ void FrameLoader::clear(ClearOptions options)
m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedFirstRealLoad);
}
-void FrameLoader::setHistoryItemStateForCommit(HistoryItemPolicy historyItemPolicy)
+void FrameLoader::setHistoryItemStateForCommit(HistoryCommitType historyCommitType, bool isPushOrReplaceState, PassRefPtr<SerializedScriptValue> stateObject)
{
- if (!m_currentItem || historyItemPolicy == CreateNewHistoryItem || m_currentItem->url() != m_documentLoader->url()) {
- if (!m_currentItem || historyItemPolicy == CreateNewHistoryItem)
- m_currentItem = HistoryItem::create();
- else
- m_currentItem->reset();
- const KURL& unreachableURL = m_documentLoader->unreachableURL();
- const KURL& url = unreachableURL.isEmpty() ? m_documentLoader->requestURL() : unreachableURL;
- const KURL& originalURL = unreachableURL.isEmpty() ? m_documentLoader->originalURL() : unreachableURL;
- m_currentItem->setURL(url);
- m_currentItem->setTarget(m_frame->tree().uniqueName());
- m_currentItem->setTargetFrameID(m_frame->frameID());
- m_currentItem->setOriginalURLString(originalURL.string());
+ if (m_provisionalItem)
+ m_currentItem = m_provisionalItem.release();
+
+ if (!m_currentItem || historyCommitType == StandardCommit) {
+ m_currentItem = HistoryItem::create();
+ } else if (!isPushOrReplaceState && m_documentLoader->url() != m_currentItem->url()) {
+ m_currentItem->generateNewItemSequenceNumber();
+ if (!equalIgnoringFragmentIdentifier(m_documentLoader->url(), m_currentItem->url()))
+ m_currentItem->generateNewDocumentSequenceNumber();
}
+
+ m_currentItem->setURL(m_documentLoader->urlForHistory());
+ m_currentItem->setDocumentState(m_frame->document()->formElementsState());
+ m_currentItem->setTarget(m_frame->tree().uniqueName());
+ if (isPushOrReplaceState)
+ m_currentItem->setStateObject(stateObject);
+ m_currentItem->setReferrer(Referrer(m_documentLoader->request().httpReferrer(), m_documentLoader->request().referrerPolicy()));
m_currentItem->setFormInfoFromRequest(m_documentLoader->request());
}
+static HistoryCommitType loadTypeToCommitType(FrameLoadType type)
+{
+ switch (type) {
+ case FrameLoadTypeStandard:
+ return StandardCommit;
+ case FrameLoadTypeInitialInChildFrame:
+ return InitialCommitInChildFrame;
+ case FrameLoadTypeBackForward:
+ return BackForwardCommit;
+ default:
+ break;
+ }
+ return HistoryInertCommit;
+}
+
void FrameLoader::receivedFirstData()
{
if (m_stateMachine.creatingInitialEmptyDocument())
return;
- NavigationHistoryPolicy navigationHistoryPolicy = NavigationReusedHistoryEntry;
- if (m_loadType == FrameLoadTypeStandard && m_documentLoader->isURLValidForNewHistoryEntry())
- navigationHistoryPolicy = NavigationCreatedHistoryEntry;
- HistoryItemPolicy historyItemPolicy = DoNotCreateNewHistoryItem;
- if (m_loadType == FrameLoadTypeInitialInChildFrame || navigationHistoryPolicy == NavigationCreatedHistoryEntry)
- historyItemPolicy = CreateNewHistoryItem;
- setHistoryItemStateForCommit(historyItemPolicy);
-
- if (!m_stateMachine.committedMultipleRealLoads() && navigationHistoryPolicy == NavigationCreatedHistoryEntry)
+
+ HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType);
+ if (historyCommitType == StandardCommit && (m_documentLoader->urlForHistory().isEmpty() || (opener() && !m_currentItem && m_documentLoader->originalRequest().url().isEmpty())))
+ historyCommitType = HistoryInertCommit;
+ else if (historyCommitType == InitialCommitInChildFrame && (!m_frame->tree().top()->isLocalFrame() || MixedContentChecker::isMixedContent(toLocalFrame(m_frame->tree().top())->document()->securityOrigin(), m_documentLoader->url())))
+ historyCommitType = HistoryInertCommit;
+ setHistoryItemStateForCommit(historyCommitType);
+
+ if (!m_stateMachine.committedMultipleRealLoads() && m_loadType == FrameLoadTypeStandard)
m_stateMachine.advanceTo(FrameLoaderStateMachine::CommittedMultipleRealLoads);
- m_client->dispatchDidCommitLoad(m_frame, m_currentItem.get(), navigationHistoryPolicy);
+ client()->dispatchDidCommitLoad(m_frame, m_currentItem.get(), historyCommitType);
InspectorInstrumentation::didCommitLoad(m_frame, m_documentLoader.get());
m_frame->page()->didCommitLoad(m_frame);
- dispatchDidClearWindowObjectsInAllWorlds();
+ dispatchDidClearDocumentOfWindowObject();
+}
+
+static void didFailContentSecurityPolicyCheck(FrameLoader* loader)
+{
+ // load event and stopAllLoaders can detach the LocalFrame, so protect it.
+ RefPtr<LocalFrame> frame(loader->frame());
+
+ // Move the page to a unique origin, and cancel the load.
+ frame->document()->enforceSandboxFlags(SandboxOrigin);
+ loader->stopAllLoaders();
+
+ // Fire a load event, as timing attacks would otherwise reveal that the
+ // frame was blocked. This way, it looks like every other cross-origin
+ // page.
+ if (FrameOwner* frameOwner = frame->owner())
+ frameOwner->dispatchLoad();
}
void FrameLoader::didBeginDocument(bool dispatch)
@@ -364,14 +346,19 @@ void FrameLoader::didBeginDocument(bool dispatch)
m_isComplete = false;
m_frame->document()->setReadyState(Document::Loading);
- if (m_currentItem && m_loadType == FrameLoadTypeBackForward)
- m_frame->domWindow()->statePopped(m_currentItem->stateObject());
+ if (m_provisionalItem && m_loadType == FrameLoadTypeBackForward)
+ m_frame->domWindow()->statePopped(m_provisionalItem->stateObject());
if (dispatch)
- dispatchDidClearWindowObjectsInAllWorlds();
+ dispatchDidClearDocumentOfWindowObject();
m_frame->document()->initContentSecurityPolicy(m_documentLoader ? ContentSecurityPolicyResponseHeaders(m_documentLoader->response()) : ContentSecurityPolicyResponseHeaders());
+ if (!m_frame->document()->contentSecurityPolicy()->allowAncestors(m_frame)) {
+ didFailContentSecurityPolicyCheck(this);
+ return;
+ }
+
Settings* settings = m_frame->document()->settings();
if (settings) {
m_frame->document()->fetcher()->setImagesEnabled(settings->imagesEnabled());
@@ -393,8 +380,8 @@ void FrameLoader::didBeginDocument(bool dispatch)
}
}
- if (m_currentItem && m_loadType == FrameLoadTypeBackForward)
- m_frame->document()->setStateForNewFormElements(m_currentItem->documentState());
+ if (m_provisionalItem && m_loadType == FrameLoadTypeBackForward)
+ m_frame->document()->setStateForNewFormElements(m_provisionalItem->documentState());
}
void FrameLoader::finishedParsing()
@@ -402,12 +389,13 @@ void FrameLoader::finishedParsing()
if (m_stateMachine.creatingInitialEmptyDocument())
return;
- // This can be called from the Frame's destructor, in which case we shouldn't protect ourselves
+ // This can be called from the LocalFrame's destructor, in which case we shouldn't protect ourselves
// because doing so will cause us to re-enter the destructor when protector goes out of scope.
// Null-checking the FrameView indicates whether or not we're in the destructor.
- RefPtr<Frame> protector = m_frame->view() ? m_frame : 0;
+ RefPtr<LocalFrame> protector = m_frame->view() ? m_frame : 0;
- m_client->dispatchDidFinishDocumentLoad();
+ if (client())
+ client()->dispatchDidFinishDocumentLoad();
checkCompleted();
@@ -428,7 +416,7 @@ void FrameLoader::loadDone()
bool FrameLoader::allChildrenAreComplete() const
{
for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
- if (!child->loader().m_isComplete)
+ if (child->isLocalFrame() && !toLocalFrame(child)->loader().m_isComplete)
return false;
}
return true;
@@ -437,7 +425,7 @@ bool FrameLoader::allChildrenAreComplete() const
bool FrameLoader::allAncestorsAreComplete() const
{
for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree().parent()) {
- if (!ancestor->document()->loadEventFinished())
+ if (ancestor->isLocalFrame() && !toLocalFrame(ancestor)->document()->loadEventFinished())
return false;
}
return true;
@@ -445,7 +433,7 @@ bool FrameLoader::allAncestorsAreComplete() const
void FrameLoader::checkCompleted()
{
- RefPtr<Frame> protect(m_frame);
+ RefPtr<LocalFrame> protect(m_frame);
m_shouldCallCheckCompleted = false;
if (m_frame->view())
@@ -459,6 +447,10 @@ void FrameLoader::checkCompleted()
if (m_frame->document()->parsing())
return;
+ // Still waiting imports?
+ if (!m_frame->document()->haveImportsLoaded())
+ return;
+
// Still waiting for images/scripts?
if (m_frame->document()->fetcher()->requestCount())
return;
@@ -489,7 +481,7 @@ void FrameLoader::checkCompleted()
void FrameLoader::checkTimerFired(Timer<FrameLoader>*)
{
- RefPtr<Frame> protect(m_frame);
+ RefPtr<LocalFrame> protect(m_frame);
if (Page* page = m_frame->page()) {
if (page->defersLoading())
@@ -505,7 +497,7 @@ void FrameLoader::startCheckCompleteTimer()
return;
if (m_checkTimer.isActive())
return;
- m_checkTimer.startOneShot(0);
+ m_checkTimer.startOneShot(0, FROM_HERE);
}
void FrameLoader::scheduleCheckCompleted()
@@ -514,72 +506,67 @@ void FrameLoader::scheduleCheckCompleted()
startCheckCompleteTimer();
}
-Frame* FrameLoader::opener()
+LocalFrame* FrameLoader::opener()
{
- return m_opener;
+ // FIXME: Temporary hack to stage converting locations that really should be Frame.
+ return client() ? toLocalFrame(client()->opener()) : 0;
}
-void FrameLoader::setOpener(Frame* opener)
+void FrameLoader::setOpener(LocalFrame* opener)
{
- if (m_opener && !opener)
- m_client->didDisownOpener();
-
- if (m_opener)
- m_opener->loader().m_openedFrames.remove(m_frame);
- if (opener)
- opener->loader().m_openedFrames.add(m_frame);
- m_opener = opener;
-
- if (m_frame->document())
- m_frame->document()->initSecurityContext();
+ // If the frame is already detached, the opener has already been cleared.
+ if (client())
+ client()->setOpener(opener);
}
bool FrameLoader::allowPlugins(ReasonForCallingAllowPlugins reason)
{
Settings* settings = m_frame->settings();
- bool allowed = m_client->allowPlugins(settings && settings->pluginsEnabled());
+ bool allowed = client()->allowPlugins(settings && settings->pluginsEnabled());
if (!allowed && reason == AboutToInstantiatePlugin)
- m_client->didNotAllowPlugins();
+ client()->didNotAllowPlugins();
return allowed;
}
-void FrameLoader::updateForSameDocumentNavigation(const KURL& newURL, SameDocumentNavigationSource sameDocumentNavigationSource, PassRefPtr<SerializedScriptValue> data, UpdateBackForwardListPolicy updateBackForwardList)
+void FrameLoader::updateForSameDocumentNavigation(const KURL& newURL, SameDocumentNavigationSource sameDocumentNavigationSource, PassRefPtr<SerializedScriptValue> data, FrameLoadType type)
{
// Update the data source's request with the new URL to fake the URL change
m_frame->document()->setURL(newURL);
- documentLoader()->updateForSameDocumentNavigation(newURL);
+ documentLoader()->updateForSameDocumentNavigation(newURL, sameDocumentNavigationSource);
// Generate start and stop notifications only when loader is completed so that we
// don't fire them for fragment redirection that happens in window.onload handler.
// See https://bugs.webkit.org/show_bug.cgi?id=31838
if (m_frame->document()->loadEventFinished())
- m_client->postProgressStartedNotification();
+ client()->didStartLoading(NavigationWithinSameDocument);
- NavigationHistoryPolicy navigationHistoryPolicy = NavigationReusedHistoryEntry;
- if (updateBackForwardList == UpdateBackForwardList || (sameDocumentNavigationSource == SameDocumentNavigationPushState && m_currentItem)) {
- navigationHistoryPolicy = NavigationCreatedHistoryEntry;
- setHistoryItemStateForCommit(CreateNewHistoryItem);
- }
- m_client->dispatchDidNavigateWithinPage(navigationHistoryPolicy, m_currentItem.get());
- m_client->dispatchDidReceiveTitle(m_frame->document()->title());
-
- if (m_currentItem) {
- m_currentItem->setURL(newURL);
- if (sameDocumentNavigationSource != SameDocumentNavigationDefault) {
- m_currentItem->setStateObject(data);
- m_currentItem->setFormData(0);
- m_currentItem->setFormContentType(nullAtom);
- }
- }
+ HistoryCommitType historyCommitType = loadTypeToCommitType(type);
+ if (!m_currentItem)
+ historyCommitType = HistoryInertCommit;
+ setHistoryItemStateForCommit(historyCommitType, sameDocumentNavigationSource == SameDocumentNavigationHistoryApi, data);
+ client()->dispatchDidNavigateWithinPage(m_currentItem.get(), historyCommitType);
+ client()->dispatchDidReceiveTitle(m_frame->document()->title());
if (m_frame->document()->loadEventFinished())
- m_client->postProgressFinishedNotification();
+ client()->didStopLoading();
}
-void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation, ClientRedirectPolicy clientRedirect)
+void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScriptValue> stateObject, FrameLoadType type, ClientRedirectPolicy clientRedirect)
{
// If we have a state object, we cannot also be a new navigation.
- ASSERT(!stateObject || (stateObject && !isNewNavigation));
+ ASSERT(!stateObject || type == FrameLoadTypeBackForward);
+
+ // If we have a provisional request for a different document, a fragment scroll should cancel it.
+ if (m_provisionalDocumentLoader) {
+ m_provisionalDocumentLoader->stopLoading();
+ if (m_provisionalDocumentLoader)
+ m_provisionalDocumentLoader->detachFromFrame();
+ m_provisionalDocumentLoader = nullptr;
+ if (!m_frame->host())
+ return;
+ }
+ m_loadType = type;
+ saveScrollState();
KURL oldURL = m_frame->document()->url();
// If we were in the autoscroll/panScroll mode we want to stop it before following the link to the anchor
@@ -588,10 +575,11 @@ void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip
m_frame->eventHandler().stopAutoscroll();
m_frame->domWindow()->enqueueHashchangeEvent(oldURL, url);
}
- m_documentLoader->setIsClientRedirect((clientRedirect == ClientRedirect && !isNewNavigation) || !UserGestureIndicator::processingUserGesture());
- m_documentLoader->setReplacesCurrentHistoryItem(!isNewNavigation);
- UpdateBackForwardListPolicy updateBackForwardList = isNewNavigation && !shouldTreatURLAsSameAsCurrent(url) && !stateObject ? UpdateBackForwardList : DoNotUpdateBackForwardList;
- updateForSameDocumentNavigation(url, SameDocumentNavigationDefault, 0, updateBackForwardList);
+ m_documentLoader->setIsClientRedirect(clientRedirect == ClientRedirect);
+ m_documentLoader->setReplacesCurrentHistoryItem(m_loadType == FrameLoadTypeStandard);
+ updateForSameDocumentNavigation(url, SameDocumentNavigationDefault, nullptr, type);
+
+ m_frame->view()->setWasScrolledByUser(false);
// It's important to model this as a load that starts and immediately finishes.
// Otherwise, the parent frame may think we never finished loading.
@@ -609,13 +597,16 @@ void FrameLoader::loadInSameDocument(const KURL& url, PassRefPtr<SerializedScrip
void FrameLoader::completed()
{
- RefPtr<Frame> protect(m_frame);
+ RefPtr<LocalFrame> protect(m_frame);
- for (Frame* descendant = m_frame->tree().traverseNext(m_frame); descendant; descendant = descendant->tree().traverseNext(m_frame))
- descendant->navigationScheduler().startTimer();
+ for (Frame* descendant = m_frame->tree().traverseNext(m_frame); descendant; descendant = descendant->tree().traverseNext(m_frame)) {
+ if (descendant->isLocalFrame())
+ toLocalFrame(descendant)->navigationScheduler().startTimer();
+ }
- if (Frame* parent = m_frame->tree().parent())
- parent->loader().checkCompleted();
+ Frame* parent = m_frame->tree().parent();
+ if (parent && parent->isLocalFrame())
+ toLocalFrame(parent)->loader().checkCompleted();
if (m_frame->view())
m_frame->view()->maintainScrollPositionAtAnchor(0);
@@ -623,8 +614,10 @@ void FrameLoader::completed()
void FrameLoader::started()
{
- for (Frame* frame = m_frame; frame; frame = frame->tree().parent())
- frame->loader().m_isComplete = false;
+ for (Frame* frame = m_frame; frame; frame = frame->tree().parent()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->loader().m_isComplete = false;
+ }
}
void FrameLoader::setReferrerForFrameRequest(ResourceRequest& request, ShouldSendReferrer shouldSendReferrer, Document* originDocument)
@@ -642,9 +635,9 @@ void FrameLoader::setReferrerForFrameRequest(ResourceRequest& request, ShouldSen
argsReferrer = originDocument->outgoingReferrer();
String referrer = SecurityPolicy::generateReferrerHeader(originDocument->referrerPolicy(), request.url(), argsReferrer);
- request.setHTTPReferrer(referrer);
+ request.setHTTPReferrer(Referrer(referrer, originDocument->referrerPolicy()));
RefPtr<SecurityOrigin> referrerOrigin = SecurityOrigin::createFromString(referrer);
- addHTTPOriginIfNeeded(request, referrerOrigin->toString());
+ addHTTPOriginIfNeeded(request, referrerOrigin->toAtomicString());
}
bool FrameLoader::isScriptTriggeredFormSubmissionInChildFrame(const FrameLoadRequest& request) const
@@ -659,17 +652,21 @@ bool FrameLoader::isScriptTriggeredFormSubmissionInChildFrame(const FrameLoadReq
FrameLoadType FrameLoader::determineFrameLoadType(const FrameLoadRequest& request)
{
- if (m_frame->tree().parent() && !m_stateMachine.startedFirstRealLoad())
+ if (m_frame->tree().parent() && !m_stateMachine.committedFirstRealDocumentLoad())
return FrameLoadTypeInitialInChildFrame;
if (!m_frame->tree().parent() && !m_frame->page()->backForward().backForwardListCount())
return FrameLoadTypeStandard;
+ if (m_provisionalDocumentLoader && request.substituteData().failingURL() == m_provisionalDocumentLoader->url() && m_loadType == FrameLoadTypeBackForward)
+ return FrameLoadTypeBackForward;
if (request.resourceRequest().cachePolicy() == ReloadIgnoringCacheData)
return FrameLoadTypeReload;
+ if (request.resourceRequest().cachePolicy() == ReloadBypassingCache)
+ return FrameLoadTypeReloadFromOrigin;
if (request.lockBackForwardList() || isScriptTriggeredFormSubmissionInChildFrame(request))
return FrameLoadTypeRedirectWithLockedBackForwardList;
- if (!request.originDocument() && shouldTreatURLAsSameAsCurrent(request.resourceRequest().url()))
+ if (!request.originDocument() && request.resourceRequest().url() == m_documentLoader->urlForHistory())
return FrameLoadTypeSame;
- if (shouldTreatURLAsSameAsCurrent(request.substituteData().failingURL()) && m_loadType == FrameLoadTypeReload)
+ if (request.substituteData().failingURL() == m_documentLoader->urlForHistory() && m_loadType == FrameLoadTypeReload)
return FrameLoadTypeReload;
return FrameLoadTypeStandard;
}
@@ -696,12 +693,20 @@ bool FrameLoader::prepareRequestForThisFrame(FrameLoadRequest& request)
return true;
}
+static bool shouldOpenInNewWindow(LocalFrame* targetFrame, const FrameLoadRequest& request, const NavigationAction& action)
+{
+ if (!targetFrame && !request.frameName().isEmpty())
+ return true;
+ // FIXME: This case is a workaround for the fact that ctrl+clicking a form submission incorrectly
+ // sends as a GET rather than a POST if it creates a new window in a different process.
+ return request.formState() && action.shouldOpenInNewWindow();
+}
+
void FrameLoader::load(const FrameLoadRequest& passedRequest)
{
ASSERT(m_frame->document());
- // Protect frame from getting blown away inside dispatchBeforeLoadEvent in loadWithDocumentLoader.
- RefPtr<Frame> protect(m_frame);
+ RefPtr<LocalFrame> protect(m_frame);
if (m_inStopAllLoaders)
return;
@@ -710,7 +715,7 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
if (!prepareRequestForThisFrame(request))
return;
- RefPtr<Frame> targetFrame = request.formState() ? 0 : findFrameForNavigation(request.frameName(), request.formState() ? request.formState()->sourceDocument() : m_frame->document());
+ RefPtr<LocalFrame> targetFrame = request.formState() ? 0 : findFrameForNavigation(AtomicString(request.frameName()), request.formState() ? request.formState()->sourceDocument() : m_frame->document());
if (targetFrame && targetFrame != m_frame) {
request.setFrameName("_self");
targetFrame->loader().load(request);
@@ -721,19 +726,23 @@ void FrameLoader::load(const FrameLoadRequest& passedRequest)
FrameLoadType newLoadType = determineFrameLoadType(request);
NavigationAction action(request.resourceRequest(), newLoadType, request.formState(), request.triggeringEvent());
- if ((!targetFrame && !request.frameName().isEmpty()) || action.shouldOpenInNewWindow()) {
+ if (shouldOpenInNewWindow(targetFrame.get(), request, action)) {
if (action.policy() == NavigationPolicyDownload)
- m_client->loadURLExternally(action.resourceRequest(), NavigationPolicyDownload);
+ client()->loadURLExternally(action.resourceRequest(), NavigationPolicyDownload);
else
- createWindowForRequest(request, m_frame, action.policy(), request.shouldSendReferrer());
+ createWindowForRequest(request, *m_frame, action.policy(), request.shouldSendReferrer());
return;
}
- if (shouldPerformFragmentNavigation(request.formState(), request.resourceRequest().httpMethod(), newLoadType, request.resourceRequest().url())) {
- checkNavigationPolicyAndContinueFragmentScroll(action, newLoadType != FrameLoadTypeRedirectWithLockedBackForwardList, request.clientRedirect());
+ const KURL& url = request.resourceRequest().url();
+ if (!action.shouldOpenInNewWindow() && shouldPerformFragmentNavigation(request.formState(), request.resourceRequest().httpMethod(), newLoadType, url)) {
+ m_documentLoader->setTriggeringAction(action);
+ if (shouldTreatURLAsSameAsCurrent(url))
+ newLoadType = FrameLoadTypeRedirectWithLockedBackForwardList;
+ loadInSameDocument(url, nullptr, newLoadType, request.clientRedirect());
return;
}
- bool sameURL = shouldTreatURLAsSameAsCurrent(request.resourceRequest().url());
+ bool sameURL = url == m_documentLoader->urlForHistory();
loadWithNavigationAction(action, newLoadType, request.formState(), request.substituteData(), request.clientRedirect());
// Example of this case are sites that reload the same URL with a different cookie
// driving the generated content, or a master frame with links that drive a target
@@ -746,13 +755,13 @@ SubstituteData FrameLoader::defaultSubstituteDataForURL(const KURL& url)
{
if (!shouldTreatURLAsSrcdocDocument(url))
return SubstituteData();
- String srcdoc = m_frame->ownerElement()->fastGetAttribute(srcdocAttr);
+ String srcdoc = m_frame->deprecatedLocalOwner()->fastGetAttribute(srcdocAttr);
ASSERT(!srcdoc.isNull());
CString encodedSrcdoc = srcdoc.utf8();
return SubstituteData(SharedBuffer::create(encodedSrcdoc.data(), encodedSrcdoc.length()), "text/html", "UTF-8", KURL());
}
-void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url)
+void FrameLoader::reportLocalLoadFailed(LocalFrame* frame, const String& url)
{
ASSERT(!url.isEmpty());
if (!frame)
@@ -761,24 +770,35 @@ void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url)
frame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Not allowed to load local resource: " + url);
}
+static ResourceRequest requestFromHistoryItem(HistoryItem* item, ResourceRequestCachePolicy cachePolicy)
+{
+ RefPtr<FormData> formData = item->formData();
+ ResourceRequest request(item->url(), item->referrer());
+ request.setCachePolicy(cachePolicy);
+ if (formData) {
+ request.setHTTPMethod("POST");
+ request.setHTTPBody(formData);
+ request.setHTTPContentType(item->formContentType());
+ RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer().referrer);
+ FrameLoader::addHTTPOriginIfNeeded(request, securityOrigin->toAtomicString());
+ }
+ return request;
+}
+
void FrameLoader::reload(ReloadPolicy reloadPolicy, const KURL& overrideURL, const AtomicString& overrideEncoding)
{
- DocumentLoader* documentLoader = activeDocumentLoader();
- if (!documentLoader)
+ if (!m_currentItem)
return;
- ResourceRequest request = documentLoader->request();
- // FIXME: We need to reset cache policy to prevent it from being incorrectly propagted to the reload.
- // Do we need to propagate anything other than the url?
- request.setCachePolicy(UseProtocolCachePolicy);
- if (!overrideURL.isEmpty())
+ ResourceRequestCachePolicy cachePolicy = reloadPolicy == EndToEndReload ? ReloadBypassingCache : ReloadIgnoringCacheData;
+ ResourceRequest request = requestFromHistoryItem(m_currentItem.get(), cachePolicy);
+ if (!overrideURL.isEmpty()) {
request.setURL(overrideURL);
- else if (!documentLoader->unreachableURL().isEmpty())
- request.setURL(documentLoader->unreachableURL());
+ request.clearHTTPReferrer();
+ }
FrameLoadType type = reloadPolicy == EndToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload;
- NavigationAction action(request, type, request.httpMethod() == "POST");
- loadWithNavigationAction(action, type, 0, SubstituteData(), NotClientRedirect, overrideEncoding);
+ loadWithNavigationAction(NavigationAction(request, type), type, nullptr, SubstituteData(), NotClientRedirect, overrideEncoding);
}
void FrameLoader::stopAllLoaders()
@@ -792,12 +812,14 @@ void FrameLoader::stopAllLoaders()
// Calling stopLoading() on the provisional document loader can blow away
// the frame from underneath.
- RefPtr<Frame> protect(m_frame);
+ RefPtr<LocalFrame> protect(m_frame);
m_inStopAllLoaders = true;
- for (RefPtr<Frame> child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling())
- child->loader().stopAllLoaders();
+ for (RefPtr<Frame> child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ toLocalFrame(child.get())->loader().stopAllLoaders();
+ }
if (m_provisionalDocumentLoader)
m_provisionalDocumentLoader->stopLoading();
if (m_documentLoader)
@@ -805,20 +827,16 @@ void FrameLoader::stopAllLoaders()
if (m_provisionalDocumentLoader)
m_provisionalDocumentLoader->detachFromFrame();
- m_provisionalDocumentLoader = 0;
+ m_provisionalDocumentLoader = nullptr;
m_checkTimer.stop();
m_inStopAllLoaders = false;
- m_client->didStopAllLoaders();
-}
-
-DocumentLoader* FrameLoader::activeDocumentLoader() const
-{
- if (m_state == FrameStateProvisional)
- return m_provisionalDocumentLoader.get();
- return m_documentLoader.get();
+ // detachFromParent() can be called multiple times on same LocalFrame, which
+ // means we may no longer have a FrameLoaderClient to talk to.
+ if (client())
+ client()->didStopAllLoaders();
}
void FrameLoader::didAccessInitialDocument()
@@ -827,13 +845,13 @@ void FrameLoader::didAccessInitialDocument()
if (isLoadingMainFrame() && !m_didAccessInitialDocument) {
m_didAccessInitialDocument = true;
// Notify asynchronously, since this is called within a JavaScript security check.
- m_didAccessInitialDocumentTimer.startOneShot(0);
+ m_didAccessInitialDocumentTimer.startOneShot(0, FROM_HERE);
}
}
void FrameLoader::didAccessInitialDocumentTimerFired(Timer<FrameLoader>*)
{
- m_client->didAccessInitialDocument();
+ client()->didAccessInitialDocument();
}
void FrameLoader::notifyIfInitialDocumentAccessed()
@@ -846,20 +864,17 @@ void FrameLoader::notifyIfInitialDocumentAccessed()
bool FrameLoader::isLoading() const
{
- DocumentLoader* docLoader = activeDocumentLoader();
- if (!docLoader)
- return false;
- return docLoader->isLoading();
+ if (m_provisionalDocumentLoader)
+ return true;
+ return m_documentLoader && m_documentLoader->isLoading();
}
void FrameLoader::commitProvisionalLoad()
{
- ASSERT(m_client->hasWebView());
+ ASSERT(client()->hasWebView());
ASSERT(m_state == FrameStateProvisional);
RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
- RefPtr<Frame> protect(m_frame);
-
- closeOldDataSources();
+ RefPtr<LocalFrame> protect(m_frame);
// Check if the destination page is allowed to access the previous page's timing information.
if (m_frame->document()) {
@@ -871,8 +886,10 @@ void FrameLoader::commitProvisionalLoad()
// JavaScript. If the script initiates a new load, we need to abandon the current load,
// or the two will stomp each other.
// detachChildren will similarly trigger child frame unload event handlers.
- if (m_documentLoader)
+ if (m_documentLoader) {
+ client()->dispatchWillClose();
closeURL();
+ }
detachChildren();
if (pdl != m_provisionalDocumentLoader)
return;
@@ -884,7 +901,7 @@ void FrameLoader::commitProvisionalLoad()
if (isLoadingMainFrame())
m_frame->page()->chrome().client().needTouchEvents(false);
- m_client->transitionToCommittedForNewPage();
+ client()->transitionToCommittedForNewPage();
m_frame->navigationScheduler().cancel();
m_frame->editor().clearLastEditCommand();
@@ -892,76 +909,79 @@ void FrameLoader::commitProvisionalLoad()
// its frame is not in a consistent state for rendering, so avoid setJSStatusBarText
// since it may cause clients to attempt to render the frame.
if (!m_stateMachine.creatingInitialEmptyDocument()) {
- DOMWindow* window = m_frame->domWindow();
+ LocalDOMWindow* window = m_frame->domWindow();
window->setStatus(String());
window->setDefaultStatus(String());
}
started();
}
-void FrameLoader::closeOldDataSources()
-{
- // FIXME: Is it important for this traversal to be postorder instead of preorder?
- // If so, add helpers for postorder traversal, and use them. If not, then lets not
- // use a recursive algorithm here.
- for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling())
- child->loader().closeOldDataSources();
-
- if (m_documentLoader)
- m_client->dispatchWillClose();
-}
-
bool FrameLoader::isLoadingMainFrame() const
{
return m_frame->isMainFrame();
}
-bool FrameLoader::subframeIsLoading() const
+FrameLoadType FrameLoader::loadType() const
{
- // It's most likely that the last added frame is the last to load so we walk backwards.
- for (Frame* child = m_frame->tree().lastChild(); child; child = child->tree().previousSibling()) {
- const FrameLoader& childLoader = child->loader();
- DocumentLoader* documentLoader = childLoader.documentLoader();
- if (documentLoader && documentLoader->isLoadingInAPISense())
- return true;
- documentLoader = childLoader.provisionalDocumentLoader();
- if (documentLoader && documentLoader->isLoadingInAPISense())
- return true;
- documentLoader = childLoader.policyDocumentLoader();
- if (documentLoader)
- return true;
- }
- return false;
+ return m_loadType;
}
-FrameLoadType FrameLoader::loadType() const
+// This function is an incomprehensible mess and is only used in checkLoadCompleteForThisFrame.
+// If you're thinking of using it elsewhere, stop right now and reconsider your life.
+static bool isDocumentDoneLoading(Document* document)
{
- return m_loadType;
+ if (!document->loader())
+ return true;
+ if (document->loader()->isLoadingMainResource())
+ return false;
+ if (!document->loadEventFinished()) {
+ if (document->loader()->isLoading() || document->isDelayingLoadEvent())
+ return false;
+ }
+ if (document->fetcher()->requestCount())
+ return false;
+ if (document->processingLoadEvent())
+ return false;
+ if (document->hasActiveParser())
+ return false;
+ return true;
}
-void FrameLoader::checkLoadCompleteForThisFrame()
+bool FrameLoader::checkLoadCompleteForThisFrame()
{
- ASSERT(m_client->hasWebView());
+ ASSERT(client()->hasWebView());
+ RefPtr<LocalFrame> protect(m_frame);
+
+ bool allChildrenAreDoneLoading = true;
+ for (RefPtr<Frame> child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ allChildrenAreDoneLoading &= toLocalFrame(child.get())->loader().checkLoadCompleteForThisFrame();
+ }
if (m_state == FrameStateProvisional && m_provisionalDocumentLoader) {
const ResourceError& error = m_provisionalDocumentLoader->mainDocumentError();
if (error.isNull())
- return;
+ return false;
RefPtr<DocumentLoader> loader = m_provisionalDocumentLoader;
- m_client->dispatchDidFailProvisionalLoad(error);
+ client()->dispatchDidFailProvisionalLoad(error);
if (loader != m_provisionalDocumentLoader)
- return;
+ return false;
m_provisionalDocumentLoader->detachFromFrame();
- m_provisionalDocumentLoader = 0;
+ m_provisionalDocumentLoader = nullptr;
m_progressTracker->progressCompleted();
m_state = FrameStateComplete;
+ return true;
}
- if (m_state != FrameStateCommittedPage)
- return;
+ if (!allChildrenAreDoneLoading)
+ return false;
- if (!m_documentLoader || (m_documentLoader->isLoadingInAPISense() && !m_inStopAllLoaders))
- return;
+ if (m_state == FrameStateComplete)
+ return true;
+ if (m_provisionalDocumentLoader || !m_documentLoader)
+ return false;
+ if (!isDocumentDoneLoading(m_frame->document()) && !m_inStopAllLoaders)
+ return false;
m_state = FrameStateComplete;
@@ -969,136 +989,123 @@ void FrameLoader::checkLoadCompleteForThisFrame()
// Maybe there are bugs because of that, or extra work we can skip because
// the new page is ready.
- // If the user had a scroll point, scroll to it, overriding the anchor point if any.
+ // Retry restoring scroll offset since FrameStateComplete disables content
+ // size clamping.
restoreScrollPositionAndViewState();
if (!m_stateMachine.committedFirstRealDocumentLoad())
- return;
+ return true;
m_progressTracker->progressCompleted();
+ m_frame->domWindow()->finishedLoading();
const ResourceError& error = m_documentLoader->mainDocumentError();
- if (!error.isNull())
- m_client->dispatchDidFailLoad(error);
- else
- m_client->dispatchDidFinishLoad();
+ if (!error.isNull()) {
+ client()->dispatchDidFailLoad(error);
+ } else {
+ // Report mobile vs. desktop page statistics. This will only report on Android.
+ if (m_frame->isMainFrame())
+ m_frame->document()->viewportDescription().reportMobilePageStats(m_frame);
+
+ client()->dispatchDidFinishLoad();
+ }
m_loadType = FrameLoadTypeStandard;
+ return true;
}
-// There is a race condition between the layout and load completion that affects restoring the scroll position.
-// We try to restore the scroll position at both the first layout and upon load completion.
-// 1) If first layout happens before the load completes, we want to restore the scroll position then so that the
-// first time we draw the page is already scrolled to the right place, instead of starting at the top and later
-// jumping down. It is possible that the old scroll position is past the part of the doc laid out so far, in
-// which case the restore silent fails and we will fix it in when we try to restore on doc completion.
-// 2) If the layout happens after the load completes, the attempt to restore at load completion time silently
-// fails. We then successfully restore it when the layout happens.
-void FrameLoader::restoreScrollPositionAndViewState(RestorePolicy restorePolicy)
+void FrameLoader::restoreScrollPositionAndViewState()
{
- if (!isBackForwardLoadType(m_loadType) && m_loadType != FrameLoadTypeReload && m_loadType != FrameLoadTypeReloadFromOrigin && restorePolicy != ForcedRestoreForSameDocumentHistoryNavigation)
+ FrameView* view = m_frame->view();
+ if (!m_frame->page() || !view || !m_currentItem || !m_stateMachine.committedFirstRealDocumentLoad())
return;
- if (!m_frame->page() || !m_currentItem || !m_stateMachine.committedFirstRealDocumentLoad())
+
+ if (!needsHistoryItemRestore(m_loadType))
return;
- if (FrameView* view = m_frame->view()) {
- if (m_frame->isMainFrame()) {
- if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator())
- scrollingCoordinator->frameViewRootLayerDidChange(view);
- }
+ // This tries to balance 1. restoring as soon as possible, 2. detecting
+ // clamping to avoid repeatedly popping the scroll position down as the
+ // page height increases, 3. ignore clamp detection after load completes
+ // because that may be because the page will never reach its previous
+ // height.
+ float mainFrameScale = m_frame->settings()->pinchVirtualViewportEnabled() ? 1 : m_currentItem->pageScaleFactor();
+ bool canRestoreWithoutClamping = view->clampOffsetAtScale(m_currentItem->scrollPoint(), mainFrameScale) == m_currentItem->scrollPoint();
+ bool canRestoreWithoutAnnoyingUser = !view->wasScrolledByUser() && (canRestoreWithoutClamping || m_state == FrameStateComplete);
+ if (!canRestoreWithoutAnnoyingUser)
+ return;
+
+ if (m_frame->isMainFrame() && m_currentItem->pageScaleFactor()) {
+ FloatPoint pinchViewportOffset(m_currentItem->pinchViewportScrollPoint());
+ IntPoint frameScrollOffset(m_currentItem->scrollPoint());
+
+ m_frame->page()->setPageScaleFactor(m_currentItem->pageScaleFactor(), frameScrollOffset);
+
+ if (m_frame->settings()->pinchVirtualViewportEnabled()) {
+ // If the pinch viewport's offset is (-1, -1) it means the history item
+ // is an old version of HistoryItem so distribute the scroll between
+ // the main frame and the pinch viewport as best as we can.
+ // FIXME(bokan): This legacy distribution can be removed once the virtual viewport
+ // pinch path is enabled on all platforms for at least one release.
+ if (pinchViewportOffset.x() == -1 && pinchViewportOffset.y() == -1)
+ pinchViewportOffset = FloatPoint(frameScrollOffset - view->scrollPosition());
- if (!view->wasScrolledByUser() || restorePolicy == ForcedRestoreForSameDocumentHistoryNavigation) {
- if (m_frame->isMainFrame() && m_currentItem->pageScaleFactor())
- m_frame->page()->setPageScaleFactor(m_currentItem->pageScaleFactor(), m_currentItem->scrollPoint());
- else
- view->setScrollPositionNonProgrammatically(m_currentItem->scrollPoint());
+ m_frame->host()->pinchViewport().setLocation(pinchViewportOffset);
}
+ } else {
+ view->setScrollPositionNonProgrammatically(m_currentItem->scrollPoint());
}
-}
-void FrameLoader::didFirstLayout()
-{
- restoreScrollPositionAndViewState();
+ if (m_frame->isMainFrame()) {
+ if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator())
+ scrollingCoordinator->frameViewRootLayerDidChange(view);
+ }
}
void FrameLoader::detachChildren()
{
- typedef Vector<RefPtr<Frame> > FrameVector;
+ typedef Vector<RefPtr<LocalFrame> > FrameVector;
FrameVector childrenToDetach;
childrenToDetach.reserveCapacity(m_frame->tree().childCount());
- for (Frame* child = m_frame->tree().lastChild(); child; child = child->tree().previousSibling())
- childrenToDetach.append(child);
+ for (Frame* child = m_frame->tree().lastChild(); child; child = child->tree().previousSibling()) {
+ if (child->isLocalFrame())
+ childrenToDetach.append(toLocalFrame(child));
+ }
FrameVector::iterator end = childrenToDetach.end();
- for (FrameVector::iterator it = childrenToDetach.begin(); it != end; it++)
+ for (FrameVector::iterator it = childrenToDetach.begin(); it != end; ++it)
(*it)->loader().detachFromParent();
}
-void FrameLoader::closeAndRemoveChild(Frame* child)
-{
- child->tree().detachFromParent();
-
- child->setView(0);
- if (child->ownerElement() && child->page())
- child->page()->decrementSubframeCount();
- child->willDetachPage();
- child->detachFromPage();
-
- m_frame->tree().removeChild(child);
-}
-
// Called every time a resource is completely loaded or an error is received.
void FrameLoader::checkLoadComplete()
{
- ASSERT(m_client->hasWebView());
-
- // FIXME: Always traversing the entire frame tree is a bit inefficient, but
- // is currently needed in order to null out the previous history item for all frames.
+ ASSERT(client()->hasWebView());
if (Page* page = m_frame->page()) {
- Vector<RefPtr<Frame>, 10> frames;
- for (RefPtr<Frame> frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
- frames.append(frame);
- // To process children before their parents, iterate the vector backwards.
- for (size_t i = frames.size(); i; --i)
- frames[i - 1]->loader().checkLoadCompleteForThisFrame();
+ if (page->mainFrame()->isLocalFrame())
+ page->deprecatedLocalMainFrame()->loader().checkLoadCompleteForThisFrame();
}
}
-void FrameLoader::checkLoadComplete(DocumentLoader* documentLoader)
-{
- if (documentLoader)
- documentLoader->checkLoadComplete();
- checkLoadComplete();
-}
-
-int FrameLoader::numPendingOrLoadingRequests(bool recurse) const
-{
- if (!recurse)
- return m_frame->document()->fetcher()->requestCount();
-
- int count = 0;
- for (Frame* frame = m_frame; frame; frame = frame->tree().traverseNext(m_frame))
- count += frame->document()->fetcher()->requestCount();
- return count;
-}
-
String FrameLoader::userAgent(const KURL& url) const
{
- String userAgent = m_client->userAgent(url);
+ String userAgent = client()->userAgent(url);
InspectorInstrumentation::applyUserAgentOverride(m_frame, &userAgent);
return userAgent;
}
void FrameLoader::frameDetached()
{
- // stopAllLoaders can detach the Frame, so protect it.
- RefPtr<Frame> protect(m_frame);
+ // stopAllLoaders can detach the LocalFrame, so protect it.
+ RefPtr<LocalFrame> protect(m_frame);
stopAllLoaders();
detachFromParent();
}
void FrameLoader::detachFromParent()
{
- // stopAllLoaders can detach the Frame, so protect it.
- RefPtr<Frame> protect(m_frame);
+ // Temporary explosions. We should never re-enter this code when this condition is true.
+ RELEASE_ASSERT(!m_willDetachClient);
+
+ // stopAllLoaders can detach the LocalFrame, so protect it.
+ RefPtr<LocalFrame> protect(m_frame);
closeURL();
detachChildren();
@@ -1111,50 +1118,51 @@ void FrameLoader::detachFromParent()
if (m_documentLoader)
m_documentLoader->detachFromFrame();
- m_documentLoader = 0;
- m_client->detachedFromParent();
+ m_documentLoader = nullptr;
- m_progressTracker.clear();
+ if (!client())
+ return;
- if (Frame* parent = m_frame->tree().parent()) {
- parent->loader().closeAndRemoveChild(m_frame);
- parent->loader().scheduleCheckCompleted();
+ TemporaryChange<bool> willDetachClient(m_willDetachClient, true);
+
+ // FIXME: All this code belongs up in Page.
+ Frame* parent = m_frame->tree().parent();
+ if (parent && parent->isLocalFrame()) {
+ m_frame->setView(nullptr);
+ // FIXME: Shouldn't need to check if page() is null here.
+ if (m_frame->owner() && m_frame->page())
+ m_frame->page()->decrementSubframeCount();
+ m_frame->willDetachFrameHost();
+ detachClient();
+ toLocalFrame(parent)->loader().scheduleCheckCompleted();
} else {
- m_frame->setView(0);
- m_frame->willDetachPage();
- m_frame->detachFromPage();
+ m_frame->setView(nullptr);
+ m_frame->willDetachFrameHost();
+ detachClient();
}
+ m_frame->detachFromFrameHost();
}
-void FrameLoader::addExtraFieldsToRequest(ResourceRequest& request)
+void FrameLoader::detachClient()
{
- bool isMainResource = (request.targetType() == ResourceRequest::TargetIsMainFrame) || (request.targetType() == ResourceRequest::TargetIsSubframe);
-
- if (isMainResource && isLoadingMainFrame())
- request.setFirstPartyForCookies(request.url());
- else
- request.setFirstPartyForCookies(m_frame->document()->firstPartyForCookies());
+ ASSERT(client());
- // The remaining modifications are only necessary for HTTP and HTTPS.
- if (!request.url().isEmpty() && !request.url().protocolIsInHTTPFamily())
- return;
-
- applyUserAgent(request);
-
- if (request.cachePolicy() == ReloadIgnoringCacheData) {
- if (m_loadType == FrameLoadTypeReload)
- request.setHTTPHeaderField("Cache-Control", "max-age=0");
- else if (m_loadType == FrameLoadTypeReloadFromOrigin) {
- request.setHTTPHeaderField("Cache-Control", "no-cache");
- request.setHTTPHeaderField("Pragma", "no-cache");
- }
+ // Finish all cleanup work that might require talking to the embedder.
+ m_progressTracker.clear();
+ setOpener(0);
+ // Notify ScriptController that the frame is closing, since its cleanup ends up calling
+ // back to FrameLoaderClient via V8WindowShell.
+ m_frame->script().clearForClose();
+
+ // client() should never be null because that means we somehow re-entered
+ // the frame detach code... but it is sometimes.
+ // FIXME: Understand why this is happening so we can document this insanity.
+ if (client()) {
+ // After this, we must no longer talk to the client since this clears
+ // its owning reference back to our owning LocalFrame.
+ client()->detachedFromParent();
+ m_frame->clearClient();
}
-
- if (isMainResource)
- request.setHTTPAccept(defaultAcceptHeader);
-
- // Make sure we send the Origin header.
- addHTTPOriginIfNeeded(request, nullAtom);
}
void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const AtomicString& origin)
@@ -1177,66 +1185,44 @@ void FrameLoader::addHTTPOriginIfNeeded(ResourceRequest& request, const AtomicSt
if (origin.isEmpty()) {
// If we don't know what origin header to attach, we attach the value
// for an empty origin.
- request.setHTTPOrigin(SecurityOrigin::createUnique()->toString());
+ request.setHTTPOrigin(SecurityOrigin::createUnique()->toAtomicString());
return;
}
request.setHTTPOrigin(origin);
}
-const ResourceRequest& FrameLoader::originalRequest() const
-{
- return activeDocumentLoader()->originalRequestCopy();
-}
-
void FrameLoader::receivedMainResourceError(const ResourceError& error)
{
// Retain because the stop may release the last reference to it.
- RefPtr<Frame> protect(m_frame);
+ RefPtr<LocalFrame> protect(m_frame);
- RefPtr<DocumentLoader> loader = activeDocumentLoader();
if (m_frame->document()->parser())
m_frame->document()->parser()->stopParsing();
// FIXME: We really ought to be able to just check for isCancellation() here, but there are some
// ResourceErrors that setIsCancellation() but aren't created by ResourceError::cancelledError().
ResourceError c(ResourceError::cancelledError(KURL()));
- if ((error.errorCode() != c.errorCode() || error.domain() != c.domain()) && m_frame->ownerElement())
- m_frame->ownerElement()->renderFallbackContent();
+ if ((error.errorCode() != c.errorCode() || error.domain() != c.domain()) && m_frame->owner()) {
+ // FIXME: For now, fallback content doesn't work cross process.
+ ASSERT(m_frame->owner()->isLocal());
+ m_frame->deprecatedLocalOwner()->renderFallbackContent();
+ }
checkCompleted();
if (m_frame->page())
checkLoadComplete();
}
-void FrameLoader::checkNavigationPolicyAndContinueFragmentScroll(const NavigationAction& action, bool isNewNavigation, ClientRedirectPolicy clientRedirect)
-{
- m_documentLoader->setTriggeringAction(action);
-
- const ResourceRequest& request = action.resourceRequest();
- if (!m_documentLoader->shouldContinueForNavigationPolicy(request, DocumentLoader::PolicyCheckFragment))
- return;
-
- // If we have a provisional request for a different document, a fragment scroll should cancel it.
- if (m_provisionalDocumentLoader && !equalIgnoringFragmentIdentifier(m_provisionalDocumentLoader->request().url(), request.url())) {
- m_provisionalDocumentLoader->stopLoading();
- if (m_provisionalDocumentLoader)
- m_provisionalDocumentLoader->detachFromFrame();
- m_provisionalDocumentLoader = 0;
- }
- saveDocumentAndScrollState();
- loadInSameDocument(request.url(), 0, isNewNavigation, clientRedirect);
-}
-
bool FrameLoader::shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType loadType, const KURL& url)
{
- ASSERT(loadType != FrameLoadTypeBackForward);
ASSERT(loadType != FrameLoadTypeReloadFromOrigin);
// We don't do this if we are submitting a form with method other than "GET", explicitly reloading,
// currently displaying a frameset, or if the URL does not have a fragment.
return (!isFormSubmission || equalIgnoringCase(httpMethod, "GET"))
&& loadType != FrameLoadTypeReload
&& loadType != FrameLoadTypeSame
+ && loadType != FrameLoadTypeBackForward
&& url.hasFragmentIdentifier()
&& equalIgnoringFragmentIdentifier(m_frame->document()->url(), url)
// We don't want to just scroll if a link from within a
@@ -1251,7 +1237,7 @@ void FrameLoader::scrollToFragmentWithParentBoundary(const KURL& url)
return;
// Leaking scroll position to a cross-origin ancestor would permit the so-called "framesniffing" attack.
- RefPtr<Frame> boundaryFrame(url.hasFragmentIdentifier() ? m_frame->document()->findUnsafeParentScrollPropagationBoundary() : 0);
+ RefPtr<LocalFrame> boundaryFrame(url.hasFragmentIdentifier() ? m_frame->document()->findUnsafeParentScrollPropagationBoundary() : 0);
if (boundaryFrame)
boundaryFrame->view()->setSafeToPropagateScrollToParent(false);
@@ -1269,10 +1255,13 @@ bool FrameLoader::shouldClose()
return true;
// Store all references to each subframe in advance since beforeunload's event handler may modify frame
- Vector<RefPtr<Frame> > targetFrames;
+ Vector<RefPtr<LocalFrame> > targetFrames;
targetFrames.append(m_frame);
- for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().traverseNext(m_frame))
- targetFrames.append(child);
+ for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().traverseNext(m_frame)) {
+ // FIXME: There is not yet any way to dispatch events to out-of-process frames.
+ if (child->isLocalFrame())
+ targetFrames.append(toLocalFrame(child));
+ }
bool shouldClose = false;
{
@@ -1293,22 +1282,13 @@ bool FrameLoader::shouldClose()
return shouldClose;
}
-void FrameLoader::loadWithNavigationAction(const NavigationAction& action, FrameLoadType type, PassRefPtr<FormState> formState, const SubstituteData& substituteData, ClientRedirectPolicy clientRedirect, const AtomicString& overrideEncoding)
+void FrameLoader::loadWithNavigationAction(const NavigationAction& action, FrameLoadType type, PassRefPtrWillBeRawPtr<FormState> formState, const SubstituteData& substituteData, ClientRedirectPolicy clientRedirect, const AtomicString& overrideEncoding)
{
- ASSERT(m_client->hasWebView());
+ ASSERT(client()->hasWebView());
if (m_frame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
return;
- // We skip dispatching the beforeload event on the frame owner if we've already committed a real
- // document load because the event would leak subsequent activity by the frame which the parent
- // frame isn't supposed to learn. For example, if the child frame navigated to a new URL, the
- // parent frame shouldn't learn the URL.
const ResourceRequest& request = action.resourceRequest();
- if (!m_stateMachine.committedFirstRealDocumentLoad() && m_frame->ownerElement() && !m_frame->ownerElement()->dispatchBeforeLoadEvent(request.url().string()))
- return;
-
- if (!m_stateMachine.startedFirstRealLoad())
- m_stateMachine.advanceTo(FrameLoaderStateMachine::StartedFirstRealLoad);
// The current load should replace the history item if it is the first real
// load of the frame.
@@ -1318,29 +1298,34 @@ void FrameLoader::loadWithNavigationAction(const NavigationAction& action, Frame
replacesCurrentHistoryItem = true;
}
- m_policyDocumentLoader = m_client->createDocumentLoader(request, substituteData.isValid() ? substituteData : defaultSubstituteDataForURL(request.url()));
- m_policyDocumentLoader->setFrame(m_frame);
+ m_policyDocumentLoader = client()->createDocumentLoader(m_frame, request, substituteData.isValid() ? substituteData : defaultSubstituteDataForURL(request.url()));
m_policyDocumentLoader->setTriggeringAction(action);
m_policyDocumentLoader->setReplacesCurrentHistoryItem(replacesCurrentHistoryItem);
m_policyDocumentLoader->setIsClientRedirect(clientRedirect == ClientRedirect);
- if (Frame* parent = m_frame->tree().parent())
- m_policyDocumentLoader->setOverrideEncoding(parent->loader().documentLoader()->overrideEncoding());
+ Frame* parent = m_frame->tree().parent();
+ if (parent && parent->isLocalFrame())
+ m_policyDocumentLoader->setOverrideEncoding(toLocalFrame(parent)->loader().documentLoader()->overrideEncoding());
else if (!overrideEncoding.isEmpty())
m_policyDocumentLoader->setOverrideEncoding(overrideEncoding);
else if (m_documentLoader)
m_policyDocumentLoader->setOverrideEncoding(m_documentLoader->overrideEncoding());
- // stopAllLoaders can detach the Frame, so protect it.
- RefPtr<Frame> protect(m_frame);
- if ((!m_policyDocumentLoader->shouldContinueForNavigationPolicy(request, DocumentLoader::PolicyCheckStandard) || !shouldClose()) && m_policyDocumentLoader) {
+ // stopAllLoaders can detach the LocalFrame, so protect it.
+ RefPtr<LocalFrame> protect(m_frame);
+ if ((!m_policyDocumentLoader->shouldContinueForNavigationPolicy(request) || !shouldClose()) && m_policyDocumentLoader) {
m_policyDocumentLoader->detachFromFrame();
- m_policyDocumentLoader = 0;
+ m_policyDocumentLoader = nullptr;
return;
}
- // A new navigation is in progress, so don't clear the history's provisional item.
- stopAllLoaders();
+ if (m_provisionalDocumentLoader) {
+ m_provisionalDocumentLoader->stopLoading();
+ if (m_provisionalDocumentLoader)
+ m_provisionalDocumentLoader->detachFromFrame();
+ m_provisionalDocumentLoader = nullptr;
+ }
+ m_checkTimer.stop();
// <rdar://problem/6250856> - In certain circumstances on pages with multiple frames, stopAllLoaders()
// might detach the current FrameLoader, in which case we should bail on this newly defunct load.
@@ -1356,13 +1341,13 @@ void FrameLoader::loadWithNavigationAction(const NavigationAction& action, Frame
m_state = FrameStateProvisional;
if (formState)
- m_client->dispatchWillSubmitForm(formState);
+ client()->dispatchWillSubmitForm(formState->form());
m_progressTracker->progressStarted();
if (m_provisionalDocumentLoader->isClientRedirect())
m_provisionalDocumentLoader->appendRedirect(m_frame->document()->url());
m_provisionalDocumentLoader->appendRedirect(m_provisionalDocumentLoader->request().url());
- m_client->dispatchDidStartProvisionalLoad();
+ client()->dispatchDidStartProvisionalLoad();
ASSERT(m_provisionalDocumentLoader);
m_provisionalDocumentLoader->startLoadingMainResource();
}
@@ -1371,12 +1356,12 @@ void FrameLoader::applyUserAgent(ResourceRequest& request)
{
String userAgent = this->userAgent(request.url());
ASSERT(!userAgent.isNull());
- request.setHTTPUserAgent(userAgent);
+ request.setHTTPUserAgent(AtomicString(userAgent));
}
bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, const KURL& url, unsigned long requestIdentifier)
{
- UseCounter::count(m_frame->domWindow(), UseCounter::XFrameOptions);
+ UseCounter::count(m_frame->domWindow()->document(), UseCounter::XFrameOptions);
Frame* topFrame = m_frame->tree().top();
if (m_frame == topFrame)
@@ -1386,13 +1371,14 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con
switch (disposition) {
case XFrameOptionsSameOrigin: {
- UseCounter::count(m_frame->domWindow(), UseCounter::XFrameOptionsSameOrigin);
+ UseCounter::count(m_frame->domWindow()->document(), UseCounter::XFrameOptionsSameOrigin);
RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
- if (!origin->isSameSchemeHostPort(topFrame->document()->securityOrigin()))
+ // Out-of-process ancestors are always a different origin.
+ if (!topFrame->isLocalFrame() || !origin->isSameSchemeHostPort(toLocalFrame(topFrame)->document()->securityOrigin()))
return true;
for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) {
- if (!origin->isSameSchemeHostPort(frame->document()->securityOrigin())) {
- UseCounter::count(m_frame->domWindow(), UseCounter::XFrameOptionsSameOriginWithBadAncestorChain);
+ if (!frame->isLocalFrame() || !origin->isSameSchemeHostPort(toLocalFrame(frame)->document()->securityOrigin())) {
+ UseCounter::count(m_frame->domWindow()->document(), UseCounter::XFrameOptionsSameOriginWithBadAncestorChain);
break;
}
}
@@ -1416,112 +1402,81 @@ bool FrameLoader::shouldInterruptLoadForXFrameOptions(const String& content, con
bool FrameLoader::shouldTreatURLAsSameAsCurrent(const KURL& url) const
{
- if (!m_currentItem)
- return false;
- return url == m_currentItem->url() || url == m_currentItem->originalURL();
+ return m_currentItem && url == m_currentItem->url();
}
bool FrameLoader::shouldTreatURLAsSrcdocDocument(const KURL& url) const
{
if (!equalIgnoringCase(url.string(), "about:srcdoc"))
return false;
- HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement();
- if (!ownerElement)
- return false;
- if (!ownerElement->hasTagName(iframeTag))
+ HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
+ if (!isHTMLIFrameElement(ownerElement))
return false;
return ownerElement->fastHasAttribute(srcdocAttr);
}
-Frame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* activeDocument)
+LocalFrame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* activeDocument)
{
ASSERT(activeDocument);
Frame* frame = m_frame->tree().find(name);
-
- // From http://www.whatwg.org/specs/web-apps/current-work/#seamlessLinks:
- //
- // If the source browsing context is the same as the browsing context
- // being navigated, and this browsing context has its seamless browsing
- // context flag set, and the browsing context being navigated was not
- // chosen using an explicit self-navigation override, then find the
- // nearest ancestor browsing context that does not have its seamless
- // browsing context flag set, and continue these steps as if that
- // browsing context was the one that was going to be navigated instead.
- if (frame == m_frame && name != "_self" && m_frame->document()->shouldDisplaySeamlesslyWithParent()) {
- for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree().parent()) {
- if (!ancestor->document()->shouldDisplaySeamlesslyWithParent()) {
- frame = ancestor;
- break;
- }
- }
- ASSERT(frame != m_frame);
- }
-
- if (!activeDocument->canNavigate(frame))
+ if (!frame || !frame->isLocalFrame() || !activeDocument->canNavigate(toLocalFrame(*frame)))
return 0;
- return frame;
+ return toLocalFrame(frame);
}
-void FrameLoader::loadHistoryItem(HistoryItem* item, HistoryLoadType historyLoadType)
+void FrameLoader::loadHistoryItem(HistoryItem* item, HistoryLoadType historyLoadType, ResourceRequestCachePolicy cachePolicy)
{
- saveDocumentAndScrollState();
- m_currentItem = item;
- if (historyLoadType == HistorySameDocumentLoad) {
- loadInSameDocument(item->url(), item->stateObject(), false, NotClientRedirect);
- restoreScrollPositionAndViewState(ForcedRestoreForSameDocumentHistoryNavigation);
+ RefPtr<LocalFrame> protect(m_frame);
+ if (m_frame->page()->defersLoading()) {
+ m_deferredHistoryLoad = DeferredHistoryLoad(item, historyLoadType, cachePolicy);
return;
}
- RefPtr<FormData> formData = item->formData();
- ResourceRequest request(item->url());
- request.setHTTPReferrer(item->referrer());
- if (formData) {
- request.setHTTPMethod("POST");
- request.setHTTPBody(formData);
- request.setHTTPContentType(item->formContentType());
- RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer());
- addHTTPOriginIfNeeded(request, securityOrigin->toString());
+ m_provisionalItem = item;
+ if (historyLoadType == HistorySameDocumentLoad) {
+ loadInSameDocument(item->url(), item->stateObject(), FrameLoadTypeBackForward, NotClientRedirect);
+ restoreScrollPositionAndViewState();
+ return;
}
-
- loadWithNavigationAction(NavigationAction(request, FrameLoadTypeBackForward, formData), FrameLoadTypeBackForward, 0, SubstituteData());
+ loadWithNavigationAction(NavigationAction(requestFromHistoryItem(item, cachePolicy), FrameLoadTypeBackForward), FrameLoadTypeBackForward, nullptr, SubstituteData());
}
void FrameLoader::dispatchDocumentElementAvailable()
{
- m_client->documentElementAvailable();
+ client()->documentElementAvailable();
}
-void FrameLoader::dispatchDidClearWindowObjectsInAllWorlds()
+void FrameLoader::dispatchDidClearDocumentOfWindowObject()
{
if (!m_frame->script().canExecuteScripts(NotAboutToExecuteScript))
return;
- Vector<RefPtr<DOMWrapperWorld> > worlds;
- DOMWrapperWorld::getAllWorlds(worlds);
- for (size_t i = 0; i < worlds.size(); ++i)
- dispatchDidClearWindowObjectInWorld(worlds[i].get());
+ if (Page* page = m_frame->page())
+ page->inspectorController().didClearDocumentOfWindowObject(m_frame);
+ InspectorInstrumentation::didClearDocumentOfWindowObject(m_frame);
+
+ // We just cleared the document, not the entire window object, but for the
+ // embedder that's close enough.
+ client()->dispatchDidClearWindowObjectInMainWorld();
}
-void FrameLoader::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
+void FrameLoader::dispatchDidClearWindowObjectInMainWorld()
{
- if (!m_frame->script().canExecuteScripts(NotAboutToExecuteScript) || !m_frame->script().existingWindowShell(world))
+ if (!m_frame->script().canExecuteScripts(NotAboutToExecuteScript))
return;
- m_client->dispatchDidClearWindowObjectInWorld(world);
-
- if (Page* page = m_frame->page())
- page->inspectorController().didClearWindowObjectInWorld(m_frame, world);
-
- InspectorInstrumentation::didClearWindowObjectInWorld(m_frame, world);
+ client()->dispatchDidClearWindowObjectInMainWorld();
}
SandboxFlags FrameLoader::effectiveSandboxFlags() const
{
SandboxFlags flags = m_forcedSandboxFlags;
- if (Frame* parentFrame = m_frame->tree().parent())
- flags |= parentFrame->document()->sandboxFlags();
- if (HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement())
- flags |= ownerElement->sandboxFlags();
+ // FIXME: We need a way to propagate sandbox flags to out-of-process frames.
+ Frame* parentFrame = m_frame->tree().parent();
+ if (parentFrame && parentFrame->isLocalFrame())
+ flags |= toLocalFrame(parentFrame)->document()->sandboxFlags();
+ if (FrameOwner* frameOwner = m_frame->owner())
+ flags |= frameOwner->sandboxFlags();
return flags;
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.h
index 7bdedd6c85e..383a75d3f63 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoader.h
@@ -36,11 +36,12 @@
#include "core/dom/SandboxFlags.h"
#include "core/dom/SecurityContext.h"
#include "core/fetch/ResourceLoaderOptions.h"
-#include "core/history/HistoryItem.h"
#include "core/loader/FrameLoaderStateMachine.h"
#include "core/loader/FrameLoaderTypes.h"
+#include "core/loader/HistoryItem.h"
#include "core/loader/MixedContentChecker.h"
#include "platform/Timer.h"
+#include "platform/network/ResourceRequest.h"
#include "wtf/Forward.h"
#include "wtf/HashSet.h"
#include "wtf/OwnPtr.h"
@@ -59,8 +60,8 @@ class FrameLoaderClient;
class IconController;
class NavigationAction;
class Page;
+class ProgressTracker;
class ResourceError;
-class ResourceRequest;
class ResourceResponse;
class SecurityOrigin;
class SerializedScriptValue;
@@ -74,30 +75,31 @@ bool isBackForwardLoadType(FrameLoadType);
class FrameLoader {
WTF_MAKE_NONCOPYABLE(FrameLoader);
public:
- FrameLoader(Frame*, FrameLoaderClient*);
+ FrameLoader(LocalFrame*);
~FrameLoader();
void init();
- Frame* frame() const { return m_frame; }
+ LocalFrame* frame() const { return m_frame; }
MixedContentChecker* mixedContentChecker() const { return &m_mixedContentChecker; }
+ ProgressTracker& progress() const { return *m_progressTracker; }
// These functions start a load. All eventually call into loadWithNavigationAction() or loadInSameDocument().
void load(const FrameLoadRequest&); // The entry point for non-reload, non-history loads.
void reload(ReloadPolicy = NormalReload, const KURL& overrideURL = KURL(), const AtomicString& overrideEncoding = nullAtom);
- void loadHistoryItem(HistoryItem*, HistoryLoadType = HistoryDifferentDocumentLoad); // The entry point for all back/forward loads
+ void loadHistoryItem(HistoryItem*, HistoryLoadType = HistoryDifferentDocumentLoad, ResourceRequestCachePolicy = UseProtocolCachePolicy); // The entry point for all back/forward loads
- static void reportLocalLoadFailed(Frame*, const String& url);
+ static void reportLocalLoadFailed(LocalFrame*, const String& url);
// FIXME: These are all functions which stop loads. We have too many.
- // Warning: stopAllLoaders can and will detach the Frame out from under you. All callers need to either protect the Frame
- // or guarantee they won't in any way access the Frame after stopAllLoaders returns.
+ // Warning: stopAllLoaders can and will detach the LocalFrame out from under you. All callers need to either protect the LocalFrame
+ // or guarantee they won't in any way access the LocalFrame after stopAllLoaders returns.
void stopAllLoaders();
void stopLoading();
bool closeURL();
// FIXME: clear() is trying to do too many things. We should break it down into smaller functions.
- void clear(ClearOptions);
+ void clear();
// Sets a timer to notify the client that the initial empty document has
// been accessed, and thus it is no longer safe to show a provisional URL
@@ -111,39 +113,27 @@ public:
bool isLoading() const;
- int numPendingOrLoadingRequests(bool recurse) const;
-
- DocumentLoader* activeDocumentLoader() const;
DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); }
DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
FrameState state() const { return m_state; }
FetchContext& fetchContext() const { return *m_fetchContext; }
- const ResourceRequest& originalRequest() const;
void receivedMainResourceError(const ResourceError&);
bool isLoadingMainFrame() const;
- bool subframeIsLoading() const;
-
bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
bool shouldTreatURLAsSrcdocDocument(const KURL&) const;
FrameLoadType loadType() const;
void setLoadType(FrameLoadType loadType) { m_loadType = loadType; }
- void didFirstLayout();
-
- void checkLoadComplete(DocumentLoader*);
void checkLoadComplete();
- void detachFromParent();
-
- void addExtraFieldsToRequest(ResourceRequest&);
static void addHTTPOriginIfNeeded(ResourceRequest&, const AtomicString& origin);
- FrameLoaderClient* client() const { return m_client; }
+ FrameLoaderClient* client() const;
void setDefersLoading(bool);
@@ -156,8 +146,8 @@ public:
String userAgent(const KURL&) const;
- void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*);
- void dispatchDidClearWindowObjectsInAllWorlds();
+ void dispatchDidClearWindowObjectInMainWorld();
+ void dispatchDidClearDocumentOfWindowObject();
void dispatchDocumentElementAvailable();
// The following sandbox flags will be forced, regardless of changes to
@@ -165,8 +155,8 @@ public:
void forceSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags |= flags; }
SandboxFlags effectiveSandboxFlags() const;
- Frame* opener();
- void setOpener(Frame*);
+ LocalFrame* opener();
+ void setOpener(LocalFrame*);
void frameDetached();
@@ -178,7 +168,7 @@ public:
FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
- Frame* findFrameForNavigation(const AtomicString& name, Document* activeDocument);
+ LocalFrame* findFrameForNavigation(const AtomicString& name, Document* activeDocument);
void applyUserAgent(ResourceRequest&);
@@ -192,21 +182,13 @@ public:
bool allowPlugins(ReasonForCallingAllowPlugins);
- enum UpdateBackForwardListPolicy {
- UpdateBackForwardList,
- DoNotUpdateBackForwardList
- };
- void updateForSameDocumentNavigation(const KURL&, SameDocumentNavigationSource, PassRefPtr<SerializedScriptValue>, UpdateBackForwardListPolicy);
+ void updateForSameDocumentNavigation(const KURL&, SameDocumentNavigationSource, PassRefPtr<SerializedScriptValue>, FrameLoadType);
HistoryItem* currentItem() const { return m_currentItem.get(); }
- void saveDocumentAndScrollState();
+ void saveScrollState();
void clearScrollPositionAndViewState();
- enum RestorePolicy {
- StandardRestore,
- ForcedRestoreForSameDocumentHistoryNavigation
- };
- void restoreScrollPositionAndViewState(RestorePolicy = StandardRestore);
+ void restoreScrollPositionAndViewState();
private:
bool allChildrenAreComplete() const; // immediate children, not all descendants
@@ -223,35 +205,27 @@ private:
SubstituteData defaultSubstituteDataForURL(const KURL&);
- void checkNavigationPolicyAndContinueFragmentScroll(const NavigationAction&, bool isNewNavigation, ClientRedirectPolicy);
-
bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&);
void scrollToFragmentWithParentBoundary(const KURL&);
- void checkLoadCompleteForThisFrame();
-
- void closeOldDataSources();
+ bool checkLoadCompleteForThisFrame();
// Calls continueLoadAfterNavigationPolicy
- void loadWithNavigationAction(const NavigationAction&, FrameLoadType, PassRefPtr<FormState>,
+ void loadWithNavigationAction(const NavigationAction&, FrameLoadType, PassRefPtrWillBeRawPtr<FormState>,
const SubstituteData&, ClientRedirectPolicy = NotClientRedirect, const AtomicString& overrideEncoding = nullAtom);
+ void detachFromParent();
void detachChildren();
- void closeAndRemoveChild(Frame*);
+ void detachClient();
- enum HistoryItemPolicy {
- CreateNewHistoryItem,
- DoNotCreateNewHistoryItem
- };
- void setHistoryItemStateForCommit(HistoryItemPolicy);
+ void setHistoryItemStateForCommit(HistoryCommitType, bool isPushOrReplaceState = false, PassRefPtr<SerializedScriptValue> = nullptr);
- void loadInSameDocument(const KURL&, PassRefPtr<SerializedScriptValue> stateObject, bool isNewNavigation, ClientRedirectPolicy);
+ void loadInSameDocument(const KURL&, PassRefPtr<SerializedScriptValue> stateObject, FrameLoadType, ClientRedirectPolicy);
void scheduleCheckCompleted();
void startCheckCompleteTimer();
- Frame* m_frame;
- FrameLoaderClient* m_client;
+ LocalFrame* m_frame;
// FIXME: These should be OwnPtr<T> to reduce build times and simplify
// header dependencies unless performance testing proves otherwise.
@@ -259,8 +233,7 @@ private:
mutable FrameLoaderStateMachine m_stateMachine;
mutable MixedContentChecker m_mixedContentChecker;
- class FrameProgressTracker;
- OwnPtr<FrameProgressTracker> m_progressTracker;
+ OwnPtr<ProgressTracker> m_progressTracker;
FrameState m_state;
FrameLoadType m_loadType;
@@ -275,6 +248,24 @@ private:
OwnPtr<FetchContext> m_fetchContext;
RefPtr<HistoryItem> m_currentItem;
+ RefPtr<HistoryItem> m_provisionalItem;
+ struct DeferredHistoryLoad {
+ DeferredHistoryLoad(HistoryItem* item, HistoryLoadType type, ResourceRequestCachePolicy cachePolicy)
+ : m_item(item)
+ , m_type(type)
+ , m_cachePolicy(cachePolicy)
+ {
+ }
+
+ DeferredHistoryLoad() { }
+
+ bool isValid() { return m_item; }
+
+ RefPtr<HistoryItem> m_item;
+ HistoryLoadType m_type;
+ ResourceRequestCachePolicy m_cachePolicy;
+ };
+ DeferredHistoryLoad m_deferredHistoryLoad;
bool m_inStopAllLoaders;
@@ -284,13 +275,12 @@ private:
Timer<FrameLoader> m_checkTimer;
bool m_shouldCallCheckCompleted;
- Frame* m_opener;
- HashSet<Frame*> m_openedFrames;
-
bool m_didAccessInitialDocument;
Timer<FrameLoader> m_didAccessInitialDocumentTimer;
SandboxFlags m_forcedSandboxFlags;
+
+ bool m_willDetachClient;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
index ec3ca3ccfc5..55098fcc3e0 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderClient.h
@@ -31,23 +31,23 @@
#define FrameLoaderClient_h
#include "core/dom/IconURL.h"
+#include "core/frame/FrameClient.h"
#include "core/loader/FrameLoaderTypes.h"
#include "core/loader/NavigationPolicy.h"
#include "platform/network/ResourceLoadPriority.h"
+#include "platform/weborigin/Referrer.h"
#include "wtf/Forward.h"
#include "wtf/Vector.h"
-
-typedef class _jobject* jobject;
-
-namespace v8 {
-class Context;
-template<class T> class Handle;
-}
+#include <v8.h>
namespace blink {
class WebCookieJar;
+class WebRTCPeerConnectionHandler;
class WebServiceWorkerProvider;
class WebServiceWorkerProviderClient;
+class WebSocketHandle;
+class WebApplicationCacheHost;
+class WebApplicationCacheHostClient;
}
namespace WebCore {
@@ -57,18 +57,17 @@ namespace WebCore {
class DOMWrapperWorld;
class DocumentLoader;
class Element;
-class FetchRequest;
- class FormState;
- class Frame;
+ class FetchRequest;
class FrameLoader;
class FrameNetworkingContext;
- class HistoryItem;
class HTMLAppletElement;
class HTMLFormElement;
class HTMLFrameOwnerElement;
class HTMLPlugInElement;
+ class HistoryItem;
class IntSize;
class KURL;
+ class LocalFrame;
class MessageEvent;
class Page;
class PluginView;
@@ -76,24 +75,17 @@ class FetchRequest;
class ResourceHandle;
class ResourceRequest;
class ResourceResponse;
- class RTCPeerConnectionHandler;
class SecurityOrigin;
class SharedBuffer;
+ class SharedWorkerRepositoryClient;
class SocketStreamHandle;
class SubstituteData;
class Widget;
- enum NavigationHistoryPolicy {
- NavigationCreatedHistoryEntry,
- NavigationReusedHistoryEntry
- };
-
- class FrameLoaderClient {
+ class FrameLoaderClient : public FrameClient {
public:
virtual ~FrameLoaderClient() { }
- virtual void frameLoaderDestroyed() = 0;
-
virtual bool hasWebView() const = 0; // mainly for assertions
virtual void detachedFromParent() = 0;
@@ -106,29 +98,29 @@ class FetchRequest;
virtual void dispatchDidHandleOnloadEvents() = 0;
virtual void dispatchDidReceiveServerRedirectForProvisionalLoad() = 0;
- virtual void dispatchDidNavigateWithinPage(NavigationHistoryPolicy, HistoryItem*) { }
+ virtual void dispatchDidNavigateWithinPage(HistoryItem*, HistoryCommitType) { }
virtual void dispatchWillClose() = 0;
virtual void dispatchDidStartProvisionalLoad() = 0;
virtual void dispatchDidReceiveTitle(const String&) = 0;
virtual void dispatchDidChangeIcons(IconType) = 0;
- virtual void dispatchDidCommitLoad(Frame*, HistoryItem*, NavigationHistoryPolicy) = 0;
+ virtual void dispatchDidCommitLoad(LocalFrame*, HistoryItem*, HistoryCommitType) = 0;
virtual void dispatchDidFailProvisionalLoad(const ResourceError&) = 0;
virtual void dispatchDidFailLoad(const ResourceError&) = 0;
virtual void dispatchDidFinishDocumentLoad() = 0;
virtual void dispatchDidFinishLoad() = 0;
virtual void dispatchDidFirstVisuallyNonEmptyLayout() = 0;
+ virtual void dispatchDidChangeThemeColor() = 0;
virtual NavigationPolicy decidePolicyForNavigation(const ResourceRequest&, DocumentLoader*, NavigationPolicy) = 0;
virtual void dispatchWillRequestResource(FetchRequest*) { }
- virtual void dispatchWillSendSubmitEvent(PassRefPtr<FormState>) = 0;
- virtual void dispatchWillSubmitForm(PassRefPtr<FormState>) = 0;
+ virtual void dispatchWillSendSubmitEvent(HTMLFormElement*) = 0;
+ virtual void dispatchWillSubmitForm(HTMLFormElement*) = 0;
- // Maybe these should go into a ProgressTrackerClient some day
- virtual void postProgressStartedNotification() = 0;
- virtual void postProgressEstimateChangedNotification() = 0;
- virtual void postProgressFinishedNotification() = 0;
+ virtual void didStartLoading(LoadStartType) = 0;
+ virtual void progressEstimateChanged(double progressEstimate) = 0;
+ virtual void didStopLoading() = 0;
virtual void loadURLExternally(const ResourceRequest&, NavigationPolicy, const String& suggestedName = String()) = 0;
@@ -139,11 +131,6 @@ class FetchRequest;
// is now possible.
virtual void didAccessInitialDocument() { }
- // This frame has set its opener to null, disowning it for the lifetime of the frame.
- // See http://html.spec.whatwg.org/#dom-opener.
- // FIXME: JSC should allow disowning opener. - <https://bugs.webkit.org/show_bug.cgi?id=103913>.
- virtual void didDisownOpener() { }
-
// This frame has displayed inactive content (such as an image) from an
// insecure source. Inactive content cannot spread to other frames.
virtual void didDisplayInsecureContent() = 0;
@@ -159,7 +146,7 @@ class FetchRequest;
// that match any element on the frame.
virtual void selectorMatchChanged(const Vector<String>& addedSelectors, const Vector<String>& removedSelectors) = 0;
- virtual PassRefPtr<DocumentLoader> createDocumentLoader(const ResourceRequest&, const SubstituteData&) = 0;
+ virtual PassRefPtr<DocumentLoader> createDocumentLoader(LocalFrame*, const ResourceRequest&, const SubstituteData&) = 0;
virtual String userAgent(const KURL&) = 0;
@@ -167,23 +154,28 @@ class FetchRequest;
virtual void transitionToCommittedForNewPage() = 0;
- virtual PassRefPtr<Frame> createFrame(const KURL&, const String& name, const String& referrer, HTMLFrameOwnerElement*) = 0;
- virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool loadManually) = 0;
+ virtual PassRefPtr<LocalFrame> createFrame(const KURL&, const AtomicString& name, const Referrer&, HTMLFrameOwnerElement*) = 0;
+ // Whether or not plugin creation should fail if the HTMLPlugInElement isn't in the DOM after plugin initialization.
+ enum DetachedPluginPolicy {
+ FailOnDetachedPlugin,
+ AllowDetachedPlugin,
+ };
+ virtual bool canCreatePluginWithoutRenderer(const String& mimeType) const = 0;
+ virtual PassRefPtr<Widget> createPlugin(HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool loadManually, DetachedPluginPolicy) = 0;
- virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) = 0;
+ virtual PassRefPtr<Widget> createJavaAppletWidget(HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) = 0;
virtual ObjectContentType objectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages) = 0;
- virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*) = 0;
+ virtual void dispatchDidClearWindowObjectInMainWorld() = 0;
virtual void documentElementAvailable() = 0;
- virtual void didExhaustMemoryAvailableForScript() { };
-
virtual void didCreateScriptContext(v8::Handle<v8::Context>, int extensionGroup, int worldId) = 0;
virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId) = 0;
virtual bool allowScriptExtension(const String& extensionName, int extensionGroup, int worldId) = 0;
virtual void didChangeScrollOffset() { }
+ virtual void didUpdateCurrentHistoryItem() { }
virtual bool allowScript(bool enabledPerSettings) { return enabledPerSettings; }
virtual bool allowScriptFromSource(bool enabledPerSettings, const KURL&) { return enabledPerSettings; }
@@ -209,28 +201,32 @@ class FetchRequest;
virtual void didChangeName(const String&) { }
virtual void dispatchWillOpenSocketStream(SocketStreamHandle*) { }
+ virtual void dispatchWillOpenWebSocket(blink::WebSocketHandle*) { }
- virtual void dispatchWillStartUsingPeerConnectionHandler(RTCPeerConnectionHandler*) { }
+ virtual void dispatchWillStartUsingPeerConnectionHandler(blink::WebRTCPeerConnectionHandler*) { }
- virtual void didRequestAutocomplete(PassRefPtr<FormState>) = 0;
+ virtual void didRequestAutocomplete(HTMLFormElement*) = 0;
virtual bool allowWebGL(bool enabledPerSettings) { return enabledPerSettings; }
// Informs the embedder that a WebGL canvas inside this frame received a lost context
// notification with the given GL_ARB_robustness guilt/innocence code (see Extensions3D.h).
virtual void didLoseWebGLContext(int) { }
- // Returns true if WebGL extension WEBGL_debug_renderer_info is allowed.
- virtual bool allowWebGLDebugRendererInfo() { return false; }
-
// If an HTML document is being loaded, informs the embedder that the document will have its <body> attached soon.
virtual void dispatchWillInsertBody() { }
- virtual void dispatchDidChangeResourcePriority(unsigned long /*identifier*/, ResourceLoadPriority) { }
+ virtual void dispatchDidChangeResourcePriority(unsigned long identifier, ResourceLoadPriority, int intraPriorityValue) { }
- virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>) = 0;
+ virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider() = 0;
+
+ virtual SharedWorkerRepositoryClient* sharedWorkerRepositoryClient() { return 0; }
+
+ virtual PassOwnPtr<blink::WebApplicationCacheHost> createApplicationCacheHost(blink::WebApplicationCacheHostClient*) = 0;
virtual void didStopAllLoaders() { }
+ virtual void dispatchDidChangeManifest() { }
+
virtual bool isFrameLoaderClientImpl() const { return false; }
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp
index 61db0ef4cce..ebad28ba4d9 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.cpp
@@ -39,11 +39,6 @@ FrameLoaderStateMachine::FrameLoaderStateMachine()
{
}
-bool FrameLoaderStateMachine::startedFirstRealLoad() const
-{
- return m_state >= StartedFirstRealLoad;
-}
-
bool FrameLoaderStateMachine::committedFirstRealDocumentLoad() const
{
return m_state >= CommittedFirstRealLoad;
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h
index aa349a5d660..ee249fecca4 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderStateMachine.h
@@ -46,12 +46,10 @@ public:
enum State {
CreatingInitialEmptyDocument,
DisplayingInitialEmptyDocument,
- StartedFirstRealLoad,
CommittedFirstRealLoad,
CommittedMultipleRealLoads
};
- bool startedFirstRealLoad() const;
bool committedFirstRealDocumentLoad() const;
bool creatingInitialEmptyDocument() const;
bool isDisplayingInitialEmptyDocument() const;
diff --git a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h
index 5fe5d36da4f..26625b00145 100644
--- a/chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h
+++ b/chromium/third_party/WebKit/Source/core/loader/FrameLoaderTypes.h
@@ -66,13 +66,6 @@ enum ObjectContentType {
ObjectContentOtherPlugin
};
-enum ClearOption {
- ClearWindowProperties = 1 << 0,
- ClearScriptObjects = 1 << 1,
- ClearWindowObject = 1 << 2,
-};
-typedef int ClearOptions;
-
enum ShouldSendReferrer {
MaybeSendReferrer,
NeverSendReferrer
@@ -88,10 +81,14 @@ enum ReloadPolicy {
EndToEndReload
};
+enum LoadStartType {
+ NavigationToDifferentDocument,
+ NavigationWithinSameDocument
+};
+
enum SameDocumentNavigationSource {
SameDocumentNavigationDefault,
- SameDocumentNavigationPushState,
- SameDocumentNavigationReplaceState
+ SameDocumentNavigationHistoryApi,
};
enum ClientRedirectPolicy {
@@ -104,6 +101,13 @@ enum HistoryLoadType {
HistoryDifferentDocumentLoad
};
+enum HistoryCommitType {
+ StandardCommit,
+ BackForwardCommit,
+ InitialCommitInChildFrame,
+ HistoryInertCommit
+};
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/loader/HistoryController.cpp b/chromium/third_party/WebKit/Source/core/loader/HistoryController.cpp
deleted file mode 100644
index 033c7348ec0..00000000000
--- a/chromium/third_party/WebKit/Source/core/loader/HistoryController.cpp
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/loader/HistoryController.h"
-
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/page/FrameTree.h"
-#include "core/page/Page.h"
-#include "wtf/Deque.h"
-#include "wtf/text/StringHash.h"
-
-namespace WebCore {
-
-PassOwnPtr<HistoryNode> HistoryNode::create(HistoryEntry* entry, HistoryItem* value)
-{
- return adoptPtr(new HistoryNode(entry, value));
-}
-
-HistoryNode* HistoryNode::addChild(PassRefPtr<HistoryItem> item)
-{
- m_children.append(HistoryNode::create(m_entry, item.get()));
- return m_children.last().get();
-}
-
-PassOwnPtr<HistoryNode> HistoryNode::cloneAndReplace(HistoryEntry* newEntry, HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Frame* currentFrame)
-{
- bool isNodeBeingNavigated = targetFrame == currentFrame;
- HistoryItem* itemForCreate = isNodeBeingNavigated ? newItem : m_value.get();
- OwnPtr<HistoryNode> newHistoryNode = create(newEntry, itemForCreate);
-
- if (!clipAtTarget || !isNodeBeingNavigated) {
- for (Frame* child = currentFrame->tree().firstChild(); child; child = child->tree().nextSibling()) {
- HistoryNode* childHistoryNode = m_entry->historyNodeForFrame(child);
- if (!childHistoryNode)
- continue;
- newHistoryNode->m_children.append(childHistoryNode->cloneAndReplace(newEntry, newItem, clipAtTarget, targetFrame, child));
- }
- }
- return newHistoryNode.release();
-}
-
-HistoryNode::HistoryNode(HistoryEntry* entry, HistoryItem* value)
- : m_entry(entry)
- , m_value(value)
-{
- m_entry->m_framesToItems.add(value->targetFrameID(), this);
- String target = value->target();
- if (target.isNull())
- target = emptyString();
- m_entry->m_uniqueNamesToItems.add(target, this);
-}
-
-void HistoryNode::removeChildren()
-{
- // FIXME: This is inefficient. Figure out a cleaner way to ensure this HistoryNode isn't cached anywhere.
- for (unsigned i = 0; i < m_children.size(); i++) {
- m_children[i]->removeChildren();
-
- HashMap<uint64_t, HistoryNode*>::iterator framesEnd = m_entry->m_framesToItems.end();
- HashMap<String, HistoryNode*>::iterator uniqueNamesEnd = m_entry->m_uniqueNamesToItems.end();
- for (HashMap<uint64_t, HistoryNode*>::iterator it = m_entry->m_framesToItems.begin(); it != framesEnd; ++it) {
- if (it->value == m_children[i])
- m_entry->m_framesToItems.remove(it);
- }
- for (HashMap<String, HistoryNode*>::iterator it = m_entry->m_uniqueNamesToItems.begin(); it != uniqueNamesEnd; ++it) {
- if (it->value == m_children[i])
- m_entry->m_uniqueNamesToItems.remove(it);
- }
- }
- m_children.clear();
-}
-
-HistoryEntry::HistoryEntry(HistoryItem* root)
-{
- m_root = HistoryNode::create(this, root);
-}
-
-PassOwnPtr<HistoryEntry> HistoryEntry::create(HistoryItem* root)
-{
- return adoptPtr(new HistoryEntry(root));
-}
-
-PassOwnPtr<HistoryEntry> HistoryEntry::cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Page* page)
-{
- OwnPtr<HistoryEntry> newEntry = adoptPtr(new HistoryEntry());
- newEntry->m_root = m_root->cloneAndReplace(newEntry.get(), newItem, clipAtTarget, targetFrame, page->mainFrame());
- return newEntry.release();
-}
-
-HistoryNode* HistoryEntry::historyNodeForFrame(Frame* frame)
-{
- if (HistoryNode* historyNode = m_framesToItems.get(frame->frameID()))
- return historyNode;
- String target = frame->tree().uniqueName();
- if (target.isNull())
- target = emptyString();
- return m_uniqueNamesToItems.get(target);
-}
-
-HistoryItem* HistoryEntry::itemForFrame(Frame* frame)
-{
- if (HistoryNode* historyNode = historyNodeForFrame(frame))
- return historyNode->value();
- return 0;
-}
-
-HistoryController::HistoryController(Page* page)
- : m_page(page)
- , m_defersLoading(false)
-{
-}
-
-HistoryController::~HistoryController()
-{
-}
-
-void HistoryController::updateBackForwardListForFragmentScroll(Frame* frame, HistoryItem* item)
-{
- m_provisionalEntry.clear();
- createNewBackForwardItem(frame, item, false);
-}
-
-void HistoryController::goToEntry(PassOwnPtr<HistoryEntry> targetEntry)
-{
- ASSERT(m_sameDocumentLoadsInProgress.isEmpty());
- ASSERT(m_differentDocumentLoadsInProgress.isEmpty());
-
- m_provisionalEntry = targetEntry;
- if (m_currentEntry)
- recursiveGoToEntry(m_page->mainFrame());
- else
- m_differentDocumentLoadsInProgress.set(m_page->mainFrame(), m_provisionalEntry->root());
-
- if (m_sameDocumentLoadsInProgress.isEmpty() && m_differentDocumentLoadsInProgress.isEmpty())
- m_sameDocumentLoadsInProgress.set(m_page->mainFrame(), m_provisionalEntry->root());
-
- if (m_differentDocumentLoadsInProgress.isEmpty()) {
- m_previousEntry = m_currentEntry.release();
- m_currentEntry = m_provisionalEntry.release();
- } else {
- m_page->mainFrame()->loader().stopAllLoaders();
- }
-
- for (HistoryFrameLoadSet::iterator it = m_sameDocumentLoadsInProgress.begin(); it != m_sameDocumentLoadsInProgress.end(); ++it)
- it->key->loader().loadHistoryItem(it->value.get(), HistorySameDocumentLoad);
- for (HistoryFrameLoadSet::iterator it = m_differentDocumentLoadsInProgress.begin(); it != m_differentDocumentLoadsInProgress.end(); ++it)
- it->key->loader().loadHistoryItem(it->value.get(), HistoryDifferentDocumentLoad);
- m_sameDocumentLoadsInProgress.clear();
- m_differentDocumentLoadsInProgress.clear();
-}
-
-void HistoryController::recursiveGoToEntry(Frame* frame)
-{
- ASSERT(m_provisionalEntry);
- ASSERT(m_currentEntry);
- HistoryItem* newItem = m_provisionalEntry->itemForFrame(frame);
- HistoryItem* oldItem = m_currentEntry->itemForFrame(frame);
- if (!newItem)
- return;
-
- if (!oldItem || (newItem != oldItem && newItem->itemSequenceNumber() != oldItem->itemSequenceNumber())) {
- if (oldItem && newItem->documentSequenceNumber() == oldItem->documentSequenceNumber())
- m_sameDocumentLoadsInProgress.set(frame, newItem);
- else
- m_differentDocumentLoadsInProgress.set(frame, newItem);
- return;
- }
-
- for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
- recursiveGoToEntry(child);
-}
-
-void HistoryController::goToItem(HistoryItem* targetItem)
-{
- if (m_defersLoading) {
- m_deferredItem = targetItem;
- return;
- }
-
- OwnPtr<HistoryEntry> newEntry = HistoryEntry::create(targetItem);
- Deque<HistoryNode*> historyNodes;
- historyNodes.append(newEntry->rootHistoryNode());
- while (!historyNodes.isEmpty()) {
- // For each item, read the children (if any) off the HistoryItem,
- // create a new HistoryNode for each child and attach it,
- // then clear the children on the HistoryItem.
- HistoryNode* historyNode = historyNodes.takeFirst();
- const HistoryItemVector& children = historyNode->value()->children();
- for (size_t i = 0; i < children.size(); i++) {
- HistoryNode* childHistoryNode = historyNode->addChild(children[i].get());
- historyNodes.append(childHistoryNode);
- }
- historyNode->value()->clearChildren();
- }
- goToEntry(newEntry.release());
-}
-
-void HistoryController::setDefersLoading(bool defer)
-{
- m_defersLoading = defer;
- if (!defer && m_deferredItem) {
- goToItem(m_deferredItem.get());
- m_deferredItem = 0;
- }
-}
-
-void HistoryController::updateForInitialLoadInChildFrame(Frame* frame, HistoryItem* item)
-{
- ASSERT(frame->tree().parent());
- if (!m_currentEntry)
- return;
- if (HistoryNode* existingChildHistoryNode = m_currentEntry->historyNodeForFrame(frame))
- existingChildHistoryNode->updateValue(item);
- else if (HistoryNode* parentHistoryNode = m_currentEntry->historyNodeForFrame(frame->tree().parent()))
- parentHistoryNode->addChild(item);
-}
-
-// FIXME: This is a temporary hack designed to be mergeable to the 1750 branch.
-// As trunk stands currently, we should never clear the provisional entry, since it's
-// possible to clear based on a commit in an irrelevant frame. On trunk, the provisional entry is
-// an implementation detail of HistoryController and only used when we know that we're in
-// a back/forward navigation. Also, it is clobbered when a new history navigation begins,
-// so we can be sure that a stale provisional entry won't be confused with a new one.
-// On the branch, however, the provisional entry is observable because
-// WebFrameImpl::currentHistoryItem() will return data based on the provisional entry preferentially
-// over the current entry, so we can't leave a stale provisional entry around indefinitely.
-// Therefore, search the frame tree for any back/forward navigations in progress, and only clear
-// the provisional entry if none are found.
-// Once the fix is merged to the branch, this can be removed, along with all places that we clear
-// m_provisionalEntry.
-static bool shouldClearProvisionalEntry(Page* page)
-{
- for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->loader().loadType() == FrameLoadTypeBackForward)
- return false;
- }
- return true;
-}
-
-void HistoryController::updateForCommit(Frame* frame, HistoryItem* item)
-{
- FrameLoadType type = frame->loader().loadType();
- if (isBackForwardLoadType(type) && m_provisionalEntry) {
- // Once committed, we want to use current item for saving DocState, and
- // the provisional item for restoring state.
- // Note previousItem must be set before we close the URL, which will
- // happen when the data source is made non-provisional below
- m_previousEntry = m_currentEntry.release();
- ASSERT(m_provisionalEntry);
- m_currentEntry = m_provisionalEntry.release();
- } else if (type != FrameLoadTypeRedirectWithLockedBackForwardList && shouldClearProvisionalEntry(m_page)) {
- m_provisionalEntry.clear();
- }
-
- if (type == FrameLoadTypeStandard)
- createNewBackForwardItem(frame, item, true);
- else if (type == FrameLoadTypeInitialInChildFrame)
- updateForInitialLoadInChildFrame(frame, item);
-}
-
-static PassRefPtr<HistoryItem> itemForExport(HistoryNode* historyNode)
-{
- RefPtr<HistoryItem> item = historyNode->value()->copy();
- const Vector<OwnPtr<HistoryNode> >& childEntries = historyNode->children();
- for (size_t i = 0; i < childEntries.size(); i++)
- item->addChildItem(itemForExport(childEntries[i].get()));
- return item;
-}
-
-PassRefPtr<HistoryItem> HistoryController::currentItemForExport()
-{
- if (!m_currentEntry)
- return 0;
- return itemForExport(m_currentEntry->rootHistoryNode());
-}
-
-PassRefPtr<HistoryItem> HistoryController::previousItemForExport()
-{
- if (!m_previousEntry)
- return 0;
- return itemForExport(m_previousEntry->rootHistoryNode());
-}
-
-PassRefPtr<HistoryItem> HistoryController::provisionalItemForExport()
-{
- if (!m_provisionalEntry)
- return 0;
- return itemForExport(m_provisionalEntry->rootHistoryNode());
-}
-
-HistoryItem* HistoryController::itemForNewChildFrame(Frame* frame) const
-{
- return m_currentEntry ? m_currentEntry->itemForFrame(frame) : 0;
-}
-
-void HistoryController::removeChildrenForRedirect(Frame* frame)
-{
- if (!m_provisionalEntry)
- return;
- if (HistoryNode* node = m_provisionalEntry->historyNodeForFrame(frame))
- node->removeChildren();
-}
-
-void HistoryController::createNewBackForwardItem(Frame* targetFrame, HistoryItem* item, bool clipAtTarget)
-{
- RefPtr<HistoryItem> newItem = item;
- if (!m_currentEntry) {
- m_currentEntry = HistoryEntry::create(newItem.get());
- } else {
- HistoryItem* oldItem = m_currentEntry->itemForFrame(targetFrame);
- if (!clipAtTarget && oldItem)
- newItem->setDocumentSequenceNumber(oldItem->documentSequenceNumber());
- m_previousEntry = m_currentEntry.release();
- m_currentEntry = m_previousEntry->cloneAndReplace(newItem.get(), clipAtTarget, targetFrame, m_page);
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/HistoryController.h b/chromium/third_party/WebKit/Source/core/loader/HistoryController.h
deleted file mode 100644
index d9478c37554..00000000000
--- a/chromium/third_party/WebKit/Source/core/loader/HistoryController.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HistoryController_h
-#define HistoryController_h
-
-#include "core/history/HistoryItem.h"
-#include "core/loader/FrameLoaderTypes.h"
-#include "wtf/HashMap.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class Frame;
-class HistoryEntry;
-class Page;
-
-
-// A guide to history state in Blink:
-//
-// HistoryController: Owned by Page, is the entry point for interacting with history.
-// Handles most of the operations to modify history state, navigate to an existing
-// back/forward entry, etc.
-// HistoryEntry: Represents a single entry in the back/forward list, encapsulating
-// all frames in the page it represents. It provides access to each frame's
-// state via lookups by frame id or frame name.
-// HistoryNode: Represents a single frame in a HistoryEntry. Owned by a HistoryEntry. HistoryNodes
-// form a tree that mirrors the FrameTree in the corresponding page. HistoryNodes represent
-// the structure of the page, but don't hold any per-frame state except a list of child frames.
-// HistoryItem (lives in a separate file): The state for a given frame. Can persist across
-// navigations. HistoryItem is reference counted, and each HistoryNode holds a reference
-// to its single corresponding HistoryItem. Can be referenced by multiple HistoryNodes and
-// can therefore exist in multiple HistoryEntry instances.
-//
-// Suppose we have the following page, foo.com, which embeds foo.com/a in an iframe:
-//
-// HistoryEntry 0:
-// HistoryNode 0_0 (HistoryItem A (url: foo.com))
-// HistoryNode 0_1: (HistoryItem B (url: foo.com/a))
-//
-// Now we navigation the top frame to bar.com, which embeds bar.com/b and bar.com/c in iframes,
-// and bar.com/b in turn embeds bar.com/d. We will create a new HistoryEntry with a tree
-// containing 4 new HistoryNodes. The state will be:
-//
-// HistoryEntry 1:
-// HistoryNode 1_0 (HistoryItem C (url: bar.com))
-// HistoryNode 1_1: (HistoryItem D (url: bar.com/b))
-// HistoryNode 1_3: (HistoryItem F (url: bar.com/d))
-// HistoryNode 1_2: (HistoryItem E (url: bar.com/c))
-//
-//
-// Finally, we navigate the first subframe from bar.com/b to bar.com/e, which embeds bar.com/f.
-// We will create a new HistoryEntry and new HistoryNode for each frame. Any frame that
-// navigates (bar.com/e and its child, bar.com/f) will receive a new HistoryItem. However,
-// 2 frames were not navigated (bar.com and bar.com/c), so those two frames will reuse the
-// existing HistoryItem:
-//
-// HistoryEntry 2:
-// HistoryNode 2_0 (HistoryItem C (url: bar.com)) *REUSED*
-// HistoryNode 2_1: (HistoryItem G (url: bar.com/e))
-// HistoryNode 2_3: (HistoryItem H (url: bar.com/f))
-// HistoryNode 2_2: (HistoryItem E (url: bar.com/c)) *REUSED*
-//
-
-class HistoryNode {
-public:
- static PassOwnPtr<HistoryNode> create(HistoryEntry*, HistoryItem*);
- ~HistoryNode() { }
-
- HistoryNode* addChild(PassRefPtr<HistoryItem>);
- PassOwnPtr<HistoryNode> cloneAndReplace(HistoryEntry*, HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Frame* currentFrame);
- HistoryItem* value() { return m_value.get(); }
- void updateValue(PassRefPtr<HistoryItem> item) { m_value = item; }
- const Vector<OwnPtr<HistoryNode> >& children() const { return m_children; }
- void removeChildren();
-
-private:
- HistoryNode(HistoryEntry*, HistoryItem*);
-
- HistoryEntry* m_entry;
- Vector<OwnPtr<HistoryNode> > m_children;
- RefPtr<HistoryItem> m_value;
-};
-
-class HistoryEntry {
-public:
- static PassOwnPtr<HistoryEntry> create(HistoryItem* root);
- PassOwnPtr<HistoryEntry> cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Page*);
-
- HistoryNode* historyNodeForFrame(Frame*);
- HistoryItem* itemForFrame(Frame*);
- HistoryItem* root() const { return m_root->value(); }
- HistoryNode* rootHistoryNode() const { return m_root.get(); }
-
-private:
- friend class HistoryNode;
-
- HistoryEntry() { }
- explicit HistoryEntry(HistoryItem* root);
-
- OwnPtr<HistoryNode> m_root;
- HashMap<uint64_t, HistoryNode*> m_framesToItems;
- HashMap<String, HistoryNode*> m_uniqueNamesToItems;
-};
-
-class HistoryController {
- WTF_MAKE_NONCOPYABLE(HistoryController);
-public:
- explicit HistoryController(Page*);
- ~HistoryController();
-
- // Should only be called by embedder. To request a back/forward
- // navigation, call FrameLoaderClient::navigateBackForward().
- void goToItem(HistoryItem*);
-
- void updateBackForwardListForFragmentScroll(Frame*, HistoryItem*);
- void updateForCommit(Frame*, HistoryItem*);
-
- PassRefPtr<HistoryItem> currentItemForExport();
- PassRefPtr<HistoryItem> previousItemForExport();
- PassRefPtr<HistoryItem> provisionalItemForExport();
- HistoryItem* itemForNewChildFrame(Frame*) const;
- void removeChildrenForRedirect(Frame*);
-
- bool inSameDocumentLoad() const { return !m_sameDocumentLoadsInProgress.isEmpty() && m_differentDocumentLoadsInProgress.isEmpty(); }
-
- void setDefersLoading(bool);
-
-private:
- void goToEntry(PassOwnPtr<HistoryEntry>);
- void recursiveGoToEntry(Frame*);
-
- void updateForInitialLoadInChildFrame(Frame*, HistoryItem*);
- void createNewBackForwardItem(Frame*, HistoryItem*, bool doClip);
-
- Page* m_page;
-
- OwnPtr<HistoryEntry> m_currentEntry;
- OwnPtr<HistoryEntry> m_previousEntry;
- OwnPtr<HistoryEntry> m_provisionalEntry;
-
- typedef HashMap<Frame*, RefPtr<HistoryItem> > HistoryFrameLoadSet;
- HistoryFrameLoadSet m_sameDocumentLoadsInProgress;
- HistoryFrameLoadSet m_differentDocumentLoadsInProgress;
-
- bool m_defersLoading;
- RefPtr<HistoryItem> m_deferredItem;
-};
-
-} // namespace WebCore
-
-#endif // HistoryController_h
diff --git a/chromium/third_party/WebKit/Source/core/loader/HistoryItem.cpp b/chromium/third_party/WebKit/Source/core/loader/HistoryItem.cpp
new file mode 100644
index 00000000000..2be3ae2680b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/HistoryItem.cpp
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2005, 2006, 2008, 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/loader/HistoryItem.h"
+
+#include "core/dom/Document.h"
+#include "core/html/forms/FormController.h"
+#include "platform/network/ResourceRequest.h"
+#include "wtf/CurrentTime.h"
+#include "wtf/text/CString.h"
+
+namespace WebCore {
+
+static long long generateSequenceNumber()
+{
+ // Initialize to the current time to reduce the likelihood of generating
+ // identifiers that overlap with those from past/future browser sessions.
+ static long long next = static_cast<long long>(currentTime() * 1000000.0);
+ return ++next;
+}
+
+HistoryItem::HistoryItem()
+ : m_pageScaleFactor(0)
+ , m_itemSequenceNumber(generateSequenceNumber())
+ , m_documentSequenceNumber(generateSequenceNumber())
+{
+}
+
+HistoryItem::~HistoryItem()
+{
+}
+
+void HistoryItem::generateNewItemSequenceNumber()
+{
+ m_itemSequenceNumber = generateSequenceNumber();
+}
+
+void HistoryItem::generateNewDocumentSequenceNumber()
+{
+ m_documentSequenceNumber = generateSequenceNumber();
+}
+
+const String& HistoryItem::urlString() const
+{
+ return m_urlString;
+}
+
+KURL HistoryItem::url() const
+{
+ return KURL(ParsedURLString, m_urlString);
+}
+
+const Referrer& HistoryItem::referrer() const
+{
+ return m_referrer;
+}
+
+const String& HistoryItem::target() const
+{
+ return m_target;
+}
+
+void HistoryItem::setURLString(const String& urlString)
+{
+ if (m_urlString != urlString)
+ m_urlString = urlString;
+}
+
+void HistoryItem::setURL(const KURL& url)
+{
+ setURLString(url.string());
+}
+
+void HistoryItem::setReferrer(const Referrer& referrer)
+{
+ m_referrer = referrer;
+}
+
+void HistoryItem::setTarget(const String& target)
+{
+ m_target = target;
+}
+
+const FloatPoint& HistoryItem::pinchViewportScrollPoint() const
+{
+ return m_pinchViewportScrollPoint;
+}
+
+void HistoryItem::setPinchViewportScrollPoint(const FloatPoint& point)
+{
+ m_pinchViewportScrollPoint = point;
+}
+
+const IntPoint& HistoryItem::scrollPoint() const
+{
+ return m_scrollPoint;
+}
+
+void HistoryItem::setScrollPoint(const IntPoint& point)
+{
+ m_scrollPoint = point;
+}
+
+void HistoryItem::clearScrollPoint()
+{
+ m_scrollPoint = IntPoint();
+ m_pinchViewportScrollPoint = FloatPoint();
+}
+
+float HistoryItem::pageScaleFactor() const
+{
+ return m_pageScaleFactor;
+}
+
+void HistoryItem::setPageScaleFactor(float scaleFactor)
+{
+ m_pageScaleFactor = scaleFactor;
+}
+
+void HistoryItem::setDocumentState(const Vector<String>& state)
+{
+ ASSERT(!m_documentState);
+ m_documentStateVector = state;
+}
+
+void HistoryItem::setDocumentState(DocumentState* state)
+{
+ m_documentState = state;
+}
+
+const Vector<String>& HistoryItem::documentState()
+{
+ if (m_documentState)
+ m_documentStateVector = m_documentState->toStateVector();
+ return m_documentStateVector;
+}
+
+Vector<String> HistoryItem::getReferencedFilePaths()
+{
+ return FormController::getReferencedFilePaths(documentState());
+}
+
+void HistoryItem::clearDocumentState()
+{
+ m_documentState.clear();
+ m_documentStateVector.clear();
+}
+
+void HistoryItem::setStateObject(PassRefPtr<SerializedScriptValue> object)
+{
+ m_stateObject = object;
+}
+
+const AtomicString& HistoryItem::formContentType() const
+{
+ return m_formContentType;
+}
+
+void HistoryItem::setFormInfoFromRequest(const ResourceRequest& request)
+{
+ if (equalIgnoringCase(request.httpMethod(), "POST")) {
+ // FIXME: Eventually we have to make this smart enough to handle the case where
+ // we have a stream for the body to handle the "data interspersed with files" feature.
+ m_formData = request.httpBody();
+ m_formContentType = request.httpContentType();
+ } else {
+ m_formData = nullptr;
+ m_formContentType = nullAtom;
+ }
+}
+
+void HistoryItem::setFormData(PassRefPtr<FormData> formData)
+{
+ m_formData = formData;
+}
+
+void HistoryItem::setFormContentType(const AtomicString& formContentType)
+{
+ m_formContentType = formContentType;
+}
+
+FormData* HistoryItem::formData()
+{
+ return m_formData.get();
+}
+
+bool HistoryItem::isCurrentDocument(Document* doc) const
+{
+ // FIXME: We should find a better way to check if this is the current document.
+ return equalIgnoringFragmentIdentifier(url(), doc->url());
+}
+
+} // namespace WebCore
+
diff --git a/chromium/third_party/WebKit/Source/core/loader/HistoryItem.h b/chromium/third_party/WebKit/Source/core/loader/HistoryItem.h
new file mode 100644
index 00000000000..35307903a45
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/HistoryItem.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HistoryItem_h
+#define HistoryItem_h
+
+#include "bindings/v8/SerializedScriptValue.h"
+#include "platform/geometry/FloatPoint.h"
+#include "platform/geometry/IntPoint.h"
+#include "platform/weborigin/Referrer.h"
+#include "wtf/RefCounted.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class Document;
+class DocumentState;
+class FormData;
+class HistoryItem;
+class Image;
+class KURL;
+class ResourceRequest;
+
+typedef Vector<RefPtr<HistoryItem> > HistoryItemVector;
+
+class HistoryItem : public RefCounted<HistoryItem> {
+public:
+ static PassRefPtr<HistoryItem> create() { return adoptRef(new HistoryItem); }
+ ~HistoryItem();
+
+ // Used when the frame this item represents was navigated to a different
+ // url but a new item wasn't created.
+ void generateNewItemSequenceNumber();
+ void generateNewDocumentSequenceNumber();
+
+ const String& urlString() const;
+ KURL url() const;
+
+ const Referrer& referrer() const;
+ const String& target() const;
+
+ FormData* formData();
+ const AtomicString& formContentType() const;
+
+ const FloatPoint& pinchViewportScrollPoint() const;
+ void setPinchViewportScrollPoint(const FloatPoint&);
+ const IntPoint& scrollPoint() const;
+ void setScrollPoint(const IntPoint&);
+ void clearScrollPoint();
+
+ float pageScaleFactor() const;
+ void setPageScaleFactor(float);
+
+ Vector<String> getReferencedFilePaths();
+ const Vector<String>& documentState();
+ void setDocumentState(const Vector<String>&);
+ void setDocumentState(DocumentState*);
+ void clearDocumentState();
+
+ void setURL(const KURL&);
+ void setURLString(const String&);
+ void setReferrer(const Referrer&);
+ void setTarget(const String&);
+
+ void setStateObject(PassRefPtr<SerializedScriptValue>);
+ SerializedScriptValue* stateObject() const { return m_stateObject.get(); }
+
+ void setItemSequenceNumber(long long number) { m_itemSequenceNumber = number; }
+ long long itemSequenceNumber() const { return m_itemSequenceNumber; }
+
+ void setDocumentSequenceNumber(long long number) { m_documentSequenceNumber = number; }
+ long long documentSequenceNumber() const { return m_documentSequenceNumber; }
+
+ void setFormInfoFromRequest(const ResourceRequest&);
+ void setFormData(PassRefPtr<FormData>);
+ void setFormContentType(const AtomicString&);
+
+ bool isCurrentDocument(Document*) const;
+
+private:
+ HistoryItem();
+
+ String m_urlString;
+ Referrer m_referrer;
+ String m_target;
+
+ FloatPoint m_pinchViewportScrollPoint;
+ IntPoint m_scrollPoint;
+ float m_pageScaleFactor;
+ Vector<String> m_documentStateVector;
+ RefPtrWillBePersistent<DocumentState> m_documentState;
+
+ // If two HistoryItems have the same item sequence number, then they are
+ // clones of one another. Traversing history from one such HistoryItem to
+ // another is a no-op. HistoryItem clones are created for parent and
+ // sibling frames when only a subframe navigates.
+ int64_t m_itemSequenceNumber;
+
+ // If two HistoryItems have the same document sequence number, then they
+ // refer to the same instance of a document. Traversing history from one
+ // such HistoryItem to another preserves the document.
+ int64_t m_documentSequenceNumber;
+
+ // Support for HTML5 History
+ RefPtr<SerializedScriptValue> m_stateObject;
+
+ // info used to repost form data
+ RefPtr<FormData> m_formData;
+ AtomicString m_formContentType;
+
+}; // class HistoryItem
+
+} // namespace WebCore
+
+#endif // HISTORYITEM_H
diff --git a/chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp
index a8177ba48d5..fd13c3f47eb 100644
--- a/chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -22,15 +22,19 @@
#include "config.h"
#include "core/loader/ImageLoader.h"
-#include "HTMLNames.h"
+#include "bindings/v8/ScriptController.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/dom/IncrementLoadEventDelayCount.h"
+#include "core/dom/Microtask.h"
#include "core/events/Event.h"
#include "core/events/EventSender.h"
#include "core/fetch/CrossOriginAccessControl.h"
#include "core/fetch/FetchRequest.h"
+#include "core/fetch/MemoryCache.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/html/HTMLObjectElement.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLImageElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderVideo.h"
@@ -39,12 +43,6 @@
namespace WebCore {
-static ImageEventSender& beforeLoadEventSender()
-{
- DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::beforeload));
- return sender;
-}
-
static ImageEventSender& loadEventSender()
{
DEFINE_STATIC_LOCAL(ImageEventSender, sender, (EventTypeNames::load));
@@ -62,11 +60,44 @@ static inline bool pageIsBeingDismissed(Document* document)
return document->pageDismissalEventBeingDispatched() != Document::NoDismissal;
}
+class ImageLoader::Task : public blink::WebThread::Task {
+public:
+ Task(ImageLoader* loader)
+ : m_loader(loader)
+ , m_shouldBypassMainWorldContentSecurityPolicy(false)
+ , m_weakFactory(this)
+ {
+ LocalFrame* frame = loader->m_element->document().frame();
+ m_shouldBypassMainWorldContentSecurityPolicy = frame->script().shouldBypassMainWorldContentSecurityPolicy();
+ }
+
+ virtual void run() OVERRIDE
+ {
+ if (m_loader) {
+ m_loader->doUpdateFromElement(m_shouldBypassMainWorldContentSecurityPolicy);
+ }
+ }
+
+ void clearLoader()
+ {
+ m_loader = 0;
+ }
+
+ WeakPtr<Task> createWeakPtr()
+ {
+ return m_weakFactory.createWeakPtr();
+ }
+
+private:
+ ImageLoader* m_loader;
+ bool m_shouldBypassMainWorldContentSecurityPolicy;
+ WeakPtrFactory<Task> m_weakFactory;
+};
+
ImageLoader::ImageLoader(Element* element)
: m_element(element)
, m_image(0)
, m_derefElementTimer(this, &ImageLoader::timerFired)
- , m_hasPendingBeforeLoadEvent(false)
, m_hasPendingLoadEvent(false)
, m_hasPendingErrorEvent(false)
, m_imageComplete(true)
@@ -78,13 +109,12 @@ ImageLoader::ImageLoader(Element* element)
ImageLoader::~ImageLoader()
{
+ if (m_pendingTask)
+ m_pendingTask->clearLoader();
+
if (m_image)
m_image->removeClient(this);
- ASSERT(m_hasPendingBeforeLoadEvent || !beforeLoadEventSender().hasPendingEvents(this));
- if (m_hasPendingBeforeLoadEvent)
- beforeLoadEventSender().cancelEvent(this);
-
ASSERT(m_hasPendingLoadEvent || !loadEventSender().hasPendingEvents(this));
if (m_hasPendingLoadEvent)
loadEventSender().cancelEvent(this);
@@ -92,11 +122,11 @@ ImageLoader::~ImageLoader()
ASSERT(m_hasPendingErrorEvent || !errorEventSender().hasPendingEvents(this));
if (m_hasPendingErrorEvent)
errorEventSender().cancelEvent(this);
+}
- // If the ImageLoader is being destroyed but it is still protecting its image-loading Element,
- // remove that protection here.
- if (m_elementIsProtected)
- m_element->deref();
+void ImageLoader::trace(Visitor* visitor)
+{
+ visitor->trace(m_element);
}
void ImageLoader::setImage(ImageResource* newImage)
@@ -115,10 +145,6 @@ void ImageLoader::setImageWithoutConsideringPendingLoadEvent(ImageResource* newI
if (newImage != oldImage) {
sourceImageChanged();
m_image = newImage;
- if (m_hasPendingBeforeLoadEvent) {
- beforeLoadEventSender().cancelEvent(this);
- m_hasPendingBeforeLoadEvent = false;
- }
if (m_hasPendingLoadEvent) {
loadEventSender().cancelEvent(this);
m_hasPendingLoadEvent = false;
@@ -138,30 +164,32 @@ void ImageLoader::setImageWithoutConsideringPendingLoadEvent(ImageResource* newI
imageResource->resetAnimation();
}
-void ImageLoader::updateFromElement()
+void ImageLoader::doUpdateFromElement(bool bypassMainWorldCSP)
{
- // Don't load images for inactive documents. We don't want to slow down the
- // raw HTML parsing case by loading images we don't intend to display.
+ // We don't need to call clearLoader here: Either we were called from the
+ // task, or our caller updateFromElement cleared the task's loader (and set
+ // m_pendingTask to null).
+ m_pendingTask.clear();
+ // Make sure to only decrement the count when we exit this function
+ OwnPtr<IncrementLoadEventDelayCount> delayLoad;
+ delayLoad.swap(m_delayLoad);
+
Document& document = m_element->document();
if (!document.isActive())
return;
AtomicString attr = m_element->imageSourceURL();
- if (!m_failedLoadURL.isEmpty() && attr == m_failedLoadURL)
- return;
-
- // Do not load any image if the 'src' attribute is missing or if it is
- // an empty string.
+ KURL url = imageURL();
ResourcePtr<ImageResource> newImage = 0;
- if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) {
- FetchRequest request(ResourceRequest(document.completeURL(sourceURI(attr))), element()->localName());
+ if (!url.isNull()) {
+ FetchRequest request(ResourceRequest(url), element()->localName());
+ if (bypassMainWorldCSP)
+ request.setContentSecurityCheck(DoNotCheckContentSecurityPolicy);
AtomicString crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
- if (!crossOriginMode.isNull()) {
- StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- updateRequestForAccessControl(request.mutableResourceRequest(), document.securityOrigin(), allowCredentials);
- }
+ if (!crossOriginMode.isNull())
+ request.setCrossOriginAccessControl(document.securityOrigin(), crossOriginMode);
if (m_loadManually) {
bool autoLoadOtherImages = document.fetcher()->autoLoadImages();
@@ -194,10 +222,6 @@ void ImageLoader::updateFromElement()
if (newImage != oldImage) {
sourceImageChanged();
- if (m_hasPendingBeforeLoadEvent) {
- beforeLoadEventSender().cancelEvent(this);
- m_hasPendingBeforeLoadEvent = false;
- }
if (m_hasPendingLoadEvent) {
loadEventSender().cancelEvent(this);
m_hasPendingLoadEvent = false;
@@ -213,18 +237,11 @@ void ImageLoader::updateFromElement()
}
m_image = newImage;
- m_hasPendingBeforeLoadEvent = !m_element->document().isImageDocument() && newImage;
m_hasPendingLoadEvent = newImage;
m_imageComplete = !newImage;
if (newImage) {
- if (!m_element->document().isImageDocument()) {
- if (!m_element->document().hasListenerType(Document::BEFORELOAD_LISTENER))
- dispatchPendingBeforeLoadEvent();
- else
- beforeLoadEventSender().dispatchEventSoon(this);
- } else
- updateRenderer();
+ updateRenderer();
// If newImage is cached, addClient() will result in the load event
// being queued to fire. Ensure this happens after beforeload is
@@ -246,44 +263,100 @@ void ImageLoader::updateFromElement()
updatedHasPendingEvent();
}
+void ImageLoader::updateFromElement(LoadType loadType)
+{
+ AtomicString attr = m_element->imageSourceURL();
+
+ if (!m_failedLoadURL.isEmpty() && attr == m_failedLoadURL)
+ return;
+
+ // If we have a pending task, we have to clear it -- either we're
+ // now loading immediately, or we need to reset the task's state.
+ if (m_pendingTask) {
+ m_pendingTask->clearLoader();
+ m_pendingTask.clear();
+ }
+
+ KURL url = imageURL();
+ if (!attr.isNull() && !url.isNull()) {
+ bool loadImmediately = shouldLoadImmediately(url) || (loadType == ForceLoadImmediately);
+ if (loadImmediately) {
+ doUpdateFromElement(false);
+ } else {
+ OwnPtr<Task> task = adoptPtr(new Task(this));
+ m_pendingTask = task->createWeakPtr();
+ Microtask::enqueueMicrotask(task.release());
+ m_delayLoad = adoptPtr(new IncrementLoadEventDelayCount(m_element->document()));
+ return;
+ }
+ } else {
+ doUpdateFromElement(false);
+ }
+}
+
void ImageLoader::updateFromElementIgnoringPreviousError()
{
clearFailedLoadURL();
updateFromElement();
}
+KURL ImageLoader::imageURL() const
+{
+ KURL url;
+
+ // Don't load images for inactive documents. We don't want to slow down the
+ // raw HTML parsing case by loading images we don't intend to display.
+ Document& document = m_element->document();
+ if (!document.isActive())
+ return url;
+
+ AtomicString attr = m_element->imageSourceURL();
+
+ // Do not load any image if the 'src' attribute is missing or if it is
+ // an empty string.
+ if (!attr.isNull() && !stripLeadingAndTrailingHTMLSpaces(attr).isEmpty()) {
+ url = document.completeURL(sourceURI(attr));
+ }
+ return url;
+}
+
+bool ImageLoader::shouldLoadImmediately(const KURL& url) const
+{
+ if (m_loadManually)
+ return true;
+ if (isHTMLObjectElement(m_element) || isHTMLEmbedElement(m_element))
+ return true;
+
+ if (url.protocolIsData())
+ return true;
+ if (memoryCache()->resourceForURL(url))
+ return true;
+ return false;
+}
+
void ImageLoader::notifyFinished(Resource* resource)
{
ASSERT(m_failedLoadURL.isEmpty());
ASSERT(resource == m_image.get());
m_imageComplete = true;
- if (!hasPendingBeforeLoadEvent())
- updateRenderer();
+ updateRenderer();
if (!m_hasPendingLoadEvent)
return;
- if (m_element->fastHasAttribute(HTMLNames::crossoriginAttr)
- && !m_element->document().securityOrigin()->canRequest(image()->response().url())
- && !resource->passesAccessControlCheck(m_element->document().securityOrigin())) {
-
- setImageWithoutConsideringPendingLoadEvent(0);
+ if (resource->errorOccurred()) {
+ loadEventSender().cancelEvent(this);
+ m_hasPendingLoadEvent = false;
m_hasPendingErrorEvent = true;
errorEventSender().dispatchEventSoon(this);
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin image load denied by Cross-Origin Resource Sharing policy."));
- m_element->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage);
-
- ASSERT(!m_hasPendingLoadEvent);
-
// Only consider updating the protection ref-count of the Element immediately before returning
// from this function as doing so might result in the destruction of this ImageLoader.
updatedHasPendingEvent();
return;
}
-
if (resource->wasCanceled()) {
m_hasPendingLoadEvent = false;
// Only consider updating the protection ref-count of the Element immediately before returning
@@ -291,7 +364,6 @@ void ImageLoader::notifyFinished(Resource* resource)
updatedHasPendingEvent();
return;
}
-
loadEventSender().dispatchEventSoon(this);
}
@@ -346,59 +418,28 @@ void ImageLoader::updatedHasPendingEvent()
if (m_derefElementTimer.isActive())
m_derefElementTimer.stop();
else
- m_element->ref();
+ m_keepAlive = m_element;
} else {
ASSERT(!m_derefElementTimer.isActive());
- m_derefElementTimer.startOneShot(0);
+ m_derefElementTimer.startOneShot(0, FROM_HERE);
}
}
void ImageLoader::timerFired(Timer<ImageLoader>*)
{
- m_element->deref();
+ m_keepAlive.clear();
}
void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender)
{
- ASSERT(eventSender == &beforeLoadEventSender() || eventSender == &loadEventSender() || eventSender == &errorEventSender());
+ ASSERT(eventSender == &loadEventSender() || eventSender == &errorEventSender());
const AtomicString& eventType = eventSender->eventType();
- if (eventType == EventTypeNames::beforeload)
- dispatchPendingBeforeLoadEvent();
if (eventType == EventTypeNames::load)
dispatchPendingLoadEvent();
if (eventType == EventTypeNames::error)
dispatchPendingErrorEvent();
}
-void ImageLoader::dispatchPendingBeforeLoadEvent()
-{
- if (!m_hasPendingBeforeLoadEvent)
- return;
- if (!m_image)
- return;
- if (!m_element->document().frame())
- return;
- m_hasPendingBeforeLoadEvent = false;
- if (m_element->dispatchBeforeLoadEvent(m_image->url().string())) {
- updateRenderer();
- return;
- }
- if (m_image) {
- m_image->removeClient(this);
- m_image = 0;
- }
-
- loadEventSender().cancelEvent(this);
- m_hasPendingLoadEvent = false;
-
- if (m_element->hasTagName(HTMLNames::objectTag))
- toHTMLObjectElement(m_element)->renderFallbackContent();
-
- // Only consider updating the protection ref-count of the Element immediately before returning
- // from this function as doing so might result in the destruction of this ImageLoader.
- updatedHasPendingEvent();
-}
-
void ImageLoader::dispatchPendingLoadEvent()
{
if (!m_hasPendingLoadEvent)
@@ -419,6 +460,7 @@ void ImageLoader::dispatchPendingErrorEvent()
if (!m_hasPendingErrorEvent)
return;
m_hasPendingErrorEvent = false;
+
if (element()->document().frame())
element()->dispatchEvent(Event::create(EventTypeNames::error));
@@ -431,24 +473,29 @@ void ImageLoader::addClient(ImageLoaderClient* client)
{
if (client->requestsHighLiveResourceCachePriority()) {
if (m_image && !m_highPriorityClientCount++)
- m_image->setCacheLiveResourcePriority(Resource::CacheLiveResourcePriorityHigh);
+ memoryCache()->updateDecodedResource(m_image.get(), UpdateForPropertyChange, MemoryCacheLiveResourcePriorityHigh);
}
+#if ENABLE(OILPAN)
+ m_clients.add(client, adoptPtr(new ImageLoaderClientRemover(*this, *client)));
+#else
m_clients.add(client);
+#endif
}
-void ImageLoader::removeClient(ImageLoaderClient* client)
+
+void ImageLoader::willRemoveClient(ImageLoaderClient& client)
{
- if (client->requestsHighLiveResourceCachePriority()) {
+ if (client.requestsHighLiveResourceCachePriority()) {
ASSERT(m_highPriorityClientCount);
m_highPriorityClientCount--;
if (m_image && !m_highPriorityClientCount)
- m_image->setCacheLiveResourcePriority(Resource::CacheLiveResourcePriorityLow);
+ memoryCache()->updateDecodedResource(m_image.get(), UpdateForPropertyChange, MemoryCacheLiveResourcePriorityLow);
}
- m_clients.remove(client);
}
-void ImageLoader::dispatchPendingBeforeLoadEvents()
+void ImageLoader::removeClient(ImageLoaderClient* client)
{
- beforeLoadEventSender().dispatchPendingEvents();
+ willRemoveClient(*client);
+ m_clients.remove(client);
}
void ImageLoader::dispatchPendingLoadEvents()
@@ -463,17 +510,27 @@ void ImageLoader::dispatchPendingErrorEvents()
void ImageLoader::elementDidMoveToNewDocument()
{
+ if (m_delayLoad) {
+ m_delayLoad->documentChanged(m_element->document());
+ }
clearFailedLoadURL();
setImage(0);
}
void ImageLoader::sourceImageChanged()
{
+#if ENABLE(OILPAN)
+ PersistentHeapHashMap<WeakMember<ImageLoaderClient>, OwnPtr<ImageLoaderClientRemover> >::iterator end = m_clients.end();
+ for (PersistentHeapHashMap<WeakMember<ImageLoaderClient>, OwnPtr<ImageLoaderClientRemover> >::iterator it = m_clients.begin(); it != end; ++it) {
+ it->key->notifyImageSourceChanged();
+ }
+#else
HashSet<ImageLoaderClient*>::iterator end = m_clients.end();
for (HashSet<ImageLoaderClient*>::iterator it = m_clients.begin(); it != end; ++it) {
ImageLoaderClient* handle = *it;
handle->notifyImageSourceChanged();
}
+#endif
}
inline void ImageLoader::clearFailedLoadURL()
@@ -481,4 +538,11 @@ inline void ImageLoader::clearFailedLoadURL()
m_failedLoadURL = AtomicString();
}
+#if ENABLE(OILPAN)
+ImageLoader::ImageLoaderClientRemover::~ImageLoaderClientRemover()
+{
+ m_loader.willRemoveClient(m_client);
+}
+#endif
+
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/ImageLoader.h b/chromium/third_party/WebKit/Source/core/loader/ImageLoader.h
index 6c1274fd3a6..abe2c34a365 100644
--- a/chromium/third_party/WebKit/Source/core/loader/ImageLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/ImageLoader.h
@@ -26,18 +26,24 @@
#include "core/fetch/ImageResource.h"
#include "core/fetch/ImageResourceClient.h"
#include "core/fetch/ResourcePtr.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashSet.h"
+#include "wtf/WeakPtr.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
-class ImageLoaderClient {
+class IncrementLoadEventDelayCount;
+
+class ImageLoaderClient : public WillBeGarbageCollectedMixin {
public:
virtual void notifyImageSourceChanged() = 0;
// Determines whether the observed ImageResource should have higher priority in the decoded resources cache.
virtual bool requestsHighLiveResourceCachePriority() { return false; }
+ virtual void trace(Visitor*) { }
+
protected:
ImageLoaderClient() { }
};
@@ -49,14 +55,20 @@ class RenderImageResource;
template<typename T> class EventSender;
typedef EventSender<ImageLoader> ImageEventSender;
-class ImageLoader : public ImageResourceClient {
+class ImageLoader : public NoBaseWillBeGarbageCollectedFinalized<ImageLoader>, public ImageResourceClient {
public:
explicit ImageLoader(Element*);
virtual ~ImageLoader();
+ void trace(Visitor*);
+
+ enum LoadType {
+ LoadNormally,
+ ForceLoadImmediately
+ };
// This function should be called when the element is attached to a document; starts
// loading if a load hasn't already been started.
- void updateFromElement();
+ void updateFromElement(LoadType = LoadNormally);
// This function should be called whenever the 'src' attribute is set, even if its value
// doesn't change; starts new load unconditionally (matches Firefox and Opera behavior).
@@ -65,19 +77,23 @@ public:
void elementDidMoveToNewDocument();
Element* element() const { return m_element; }
- bool imageComplete() const { return m_imageComplete; }
+ bool imageComplete() const
+ {
+ return m_imageComplete && !m_pendingTask;
+ }
ImageResource* image() const { return m_image.get(); }
- void setImage(ImageResource*); // Cancels pending beforeload and load events, and doesn't dispatch new ones.
+ void setImage(ImageResource*); // Cancels pending load events, and doesn't dispatch new ones.
void setLoadManually(bool loadManually) { m_loadManually = loadManually; }
- bool hasPendingBeforeLoadEvent() const { return m_hasPendingBeforeLoadEvent; }
- bool hasPendingActivity() const { return m_hasPendingLoadEvent || m_hasPendingErrorEvent; }
+ bool hasPendingActivity() const
+ {
+ return m_hasPendingLoadEvent || m_hasPendingErrorEvent || m_pendingTask;
+ }
void dispatchPendingEvent(ImageEventSender*);
- static void dispatchPendingBeforeLoadEvents();
static void dispatchPendingLoadEvents();
static void dispatchPendingErrorEvents();
@@ -85,15 +101,19 @@ public:
void removeClient(ImageLoaderClient*);
protected:
- virtual void notifyFinished(Resource*);
+ virtual void notifyFinished(Resource*) OVERRIDE;
private:
+ class Task;
+
+ // Called from the task or from updateFromElement to initiate the load.
+ void doUpdateFromElement(bool bypassMainWorldCSP = false);
+
virtual void dispatchLoadEvent() = 0;
virtual String sourceURI(const AtomicString&) const = 0;
void updatedHasPendingEvent();
- void dispatchPendingBeforeLoadEvent();
void dispatchPendingLoadEvent();
void dispatchPendingErrorEvent();
@@ -106,12 +126,45 @@ private:
void timerFired(Timer<ImageLoader>*);
- Element* m_element;
+ KURL imageURL() const;
+
+ // Used to determine whether to immediately initiate the load
+ // or to schedule a microtask.
+ bool shouldLoadImmediately(const KURL&) const;
+
+ void willRemoveClient(ImageLoaderClient&);
+
+ RawPtrWillBeMember<Element> m_element;
ResourcePtr<ImageResource> m_image;
+ // FIXME: Oilpan: We might be able to remove this Persistent hack when
+ // ImageResourceClient is traceable.
+ GC_PLUGIN_IGNORE("http://crbug.com/383741")
+ RefPtrWillBePersistent<Element> m_keepAlive;
+#if ENABLE(OILPAN)
+ class ImageLoaderClientRemover {
+ public:
+ ImageLoaderClientRemover(ImageLoader& loader, ImageLoaderClient& client) : m_loader(loader), m_client(client) { }
+ ~ImageLoaderClientRemover();
+
+ private:
+ ImageLoader& m_loader;
+ ImageLoaderClient& m_client;
+ };
+ friend class ImageLoaderClientRemover;
+ // Oilpan: This ImageLoader object must outlive its clients because they
+ // need to call ImageLoader::willRemoveClient before they
+ // die. Non-Persistent HeapHashMap doesn't work well because weak processing
+ // for HeapHashMap is not triggered when both of ImageLoader and
+ // ImageLoaderClient are unreachable.
+ GC_PLUGIN_IGNORE("http://crbug.com/383742")
+ PersistentHeapHashMap<WeakMember<ImageLoaderClient>, OwnPtr<ImageLoaderClientRemover> > m_clients;
+#else
HashSet<ImageLoaderClient*> m_clients;
+#endif
Timer<ImageLoader> m_derefElementTimer;
AtomicString m_failedLoadURL;
- bool m_hasPendingBeforeLoadEvent : 1;
+ WeakPtr<Task> m_pendingTask; // owned by Microtask
+ OwnPtr<IncrementLoadEventDelayCount> m_delayLoad;
bool m_hasPendingLoadEvent : 1;
bool m_hasPendingErrorEvent : 1;
bool m_imageComplete : 1;
diff --git a/chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp
index 25c23488f04..6eb4380c3d0 100644
--- a/chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/LinkLoader.cpp
@@ -32,17 +32,29 @@
#include "config.h"
#include "core/loader/LinkLoader.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/Document.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
+#include "core/frame/Settings.h"
#include "core/html/LinkRelAttribute.h"
#include "core/loader/PrerenderHandle.h"
-#include "core/frame/Settings.h"
+#include "platform/Prerender.h"
#include "platform/network/DNS.h"
namespace WebCore {
+static unsigned prerenderRelTypesFromRelAttribute(const LinkRelAttribute& relAttribute)
+{
+ unsigned result = 0;
+ if (relAttribute.isLinkPrerender())
+ result |= PrerenderRelTypePrerender;
+ if (relAttribute.isLinkNext())
+ result |= PrerenderRelTypeNext;
+
+ return result;
+}
+
LinkLoader::LinkLoader(LinkLoaderClient* client)
: m_client(client)
, m_linkLoadTimer(this, &LinkLoader::linkLoadTimerFired)
@@ -71,9 +83,9 @@ void LinkLoader::notifyFinished(Resource* resource)
ASSERT(this->resource() == resource);
if (resource->errorOccurred())
- m_linkLoadingErrorTimer.startOneShot(0);
+ m_linkLoadingErrorTimer.startOneShot(0, FROM_HERE);
else
- m_linkLoadTimer.startOneShot(0);
+ m_linkLoadTimer.startOneShot(0, FROM_HERE);
clearResource();
}
@@ -98,7 +110,7 @@ void LinkLoader::didSendDOMContentLoadedForPrerender()
m_client->didSendDOMContentLoadedForLinkPrerender();
}
-bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const String& type, const KURL& href, Document& document)
+bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const AtomicString& crossOriginMode, const String& type, const KURL& href, Document& document)
{
if (relAttribute.isDNSPrefetch()) {
Settings* settings = document.settings();
@@ -109,21 +121,24 @@ bool LinkLoader::loadLink(const LinkRelAttribute& relAttribute, const String& ty
}
// FIXME(crbug.com/323096): Should take care of import.
- if ((relAttribute.isLinkPrefetch() || relAttribute.isLinkSubresource()) && href.isValid() && document.frame()) {
+ if ((relAttribute.isLinkPrefetch() || relAttribute.isLinkSubresource() || relAttribute.isTransitionExitingStylesheet()) && href.isValid() && document.frame()) {
if (!m_client->shouldLoadLink())
return false;
Resource::Type type = relAttribute.isLinkSubresource() ? Resource::LinkSubresource : Resource::LinkPrefetch;
FetchRequest linkRequest(ResourceRequest(document.completeURL(href)), FetchInitiatorTypeNames::link);
+ if (!crossOriginMode.isNull())
+ linkRequest.setCrossOriginAccessControl(document.securityOrigin(), crossOriginMode);
setResource(document.fetcher()->fetchLinkResource(type, linkRequest));
}
- if (relAttribute.isLinkPrerender()) {
+ if (const unsigned prerenderRelTypes = prerenderRelTypesFromRelAttribute(relAttribute)) {
if (!m_prerender) {
- m_prerender = PrerenderHandle::create(document, this, href);
+ m_prerender = PrerenderHandle::create(document, this, href, prerenderRelTypes);
} else if (m_prerender->url() != href) {
m_prerender->cancel();
- m_prerender = PrerenderHandle::create(document, this, href);
+ m_prerender = PrerenderHandle::create(document, this, href, prerenderRelTypes);
}
+ // TODO(gavinp): Handle changes to rel types of existing prerenders.
} else if (m_prerender) {
m_prerender->cancel();
m_prerender.clear();
diff --git a/chromium/third_party/WebKit/Source/core/loader/LinkLoader.h b/chromium/third_party/WebKit/Source/core/loader/LinkLoader.h
index 4d1f72d7c95..978f5adfa68 100644
--- a/chromium/third_party/WebKit/Source/core/loader/LinkLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/LinkLoader.h
@@ -46,14 +46,14 @@ class LinkRelAttribute;
class PrerenderHandle;
// The LinkLoader can load link rel types icon, dns-prefetch, subresource, prefetch and prerender.
-class LinkLoader : public ResourceOwner<Resource, ResourceClient>, public PrerenderClient {
+class LinkLoader FINAL : public ResourceOwner<Resource, ResourceClient>, public PrerenderClient {
public:
explicit LinkLoader(LinkLoaderClient*);
virtual ~LinkLoader();
// from ResourceClient
- virtual void notifyFinished(Resource*);
+ virtual void notifyFinished(Resource*) OVERRIDE;
// from PrerenderClient
virtual void didStartPrerender() OVERRIDE;
@@ -62,7 +62,7 @@ public:
virtual void didSendDOMContentLoadedForPrerender() OVERRIDE;
void released();
- bool loadLink(const LinkRelAttribute&, const String& type, const KURL&, Document&);
+ bool loadLink(const LinkRelAttribute&, const AtomicString& crossOriginMode, const String& type, const KURL&, Document&);
private:
void linkLoadTimerFired(Timer<LinkLoader>*);
diff --git a/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp b/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp
index 750f1308afc..75e9737cd51 100644
--- a/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.cpp
@@ -30,15 +30,16 @@
#include "core/loader/MixedContentChecker.h"
#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
#include "platform/weborigin/SecurityOrigin.h"
+#include "wtf/text/StringBuilder.h"
namespace WebCore {
-MixedContentChecker::MixedContentChecker(Frame* frame)
+MixedContentChecker::MixedContentChecker(LocalFrame* frame)
: m_frame(frame)
{
}
@@ -58,14 +59,14 @@ bool MixedContentChecker::isMixedContent(SecurityOrigin* securityOrigin, const K
return !SecurityOrigin::isSecure(url);
}
-bool MixedContentChecker::canDisplayInsecureContent(SecurityOrigin* securityOrigin, const KURL& url) const
+bool MixedContentChecker::canDisplayInsecureContentInternal(SecurityOrigin* securityOrigin, const KURL& url, const MixedContentType type) const
{
if (!isMixedContent(securityOrigin, url))
return true;
Settings* settings = m_frame->settings();
bool allowed = client()->allowDisplayingInsecureContent(settings && settings->allowDisplayOfInsecureContent(), securityOrigin, url);
- logWarning(allowed, "displayed", url);
+ logWarning(allowed, url, type);
if (allowed)
client()->didDisplayInsecureContent();
@@ -73,14 +74,15 @@ bool MixedContentChecker::canDisplayInsecureContent(SecurityOrigin* securityOrig
return allowed;
}
-bool MixedContentChecker::canRunInsecureContent(SecurityOrigin* securityOrigin, const KURL& url) const
+bool MixedContentChecker::canRunInsecureContentInternal(SecurityOrigin* securityOrigin, const KURL& url, const MixedContentType type) const
{
if (!isMixedContent(securityOrigin, url))
return true;
Settings* settings = m_frame->settings();
- bool allowed = client()->allowRunningInsecureContent(settings && settings->allowRunningOfInsecureContent(), securityOrigin, url);
- logWarning(allowed, "ran", url);
+ bool allowedPerSettings = settings && (settings->allowRunningOfInsecureContent() || ((type == WebSocket) && settings->allowConnectingInsecureWebSocket()));
+ bool allowed = client()->allowRunningInsecureContent(allowedPerSettings, securityOrigin, url);
+ logWarning(allowed, url, type);
if (allowed)
client()->didRunInsecureContent(securityOrigin, url);
@@ -88,11 +90,25 @@ bool MixedContentChecker::canRunInsecureContent(SecurityOrigin* securityOrigin,
return allowed;
}
-void MixedContentChecker::logWarning(bool allowed, const String& action, const KURL& target) const
+void MixedContentChecker::logWarning(bool allowed, const KURL& target, const MixedContentType type) const
{
- String message = String(allowed ? "" : "[blocked] ") + "The page at '" + m_frame->document()->url().elidedString() + "' was loaded over HTTPS, but " + action + " insecure content from '" + target.elidedString() + "': this content should also be loaded over HTTPS.\n";
+ StringBuilder message;
+ message.append((allowed ? "" : "[blocked] "));
+ message.append("The page at '" + m_frame->document()->url().elidedString() + "' was loaded over HTTPS, but ");
+ switch (type) {
+ case Display:
+ message.append("displayed insecure content from '" + target.elidedString() + "': this content should also be loaded over HTTPS.\n");
+ break;
+ case Execution:
+ case WebSocket:
+ message.append("ran insecure content from '" + target.elidedString() + "': this content should also be loaded over HTTPS.\n");
+ break;
+ case Submission:
+ message.append("is submitting data to an insecure location at '" + target.elidedString() + "': this content should also be submitted over HTTPS.\n");
+ break;
+ }
MessageLevel messageLevel = allowed ? WarningMessageLevel : ErrorMessageLevel;
- m_frame->document()->addConsoleMessage(SecurityMessageSource, messageLevel, message);
+ m_frame->document()->addConsoleMessage(SecurityMessageSource, messageLevel, message.toString());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.h b/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.h
index f4d6647031c..e749b679e60 100644
--- a/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.h
+++ b/chromium/third_party/WebKit/Source/core/loader/MixedContentChecker.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class FrameLoaderClient;
class KURL;
class SecurityOrigin;
@@ -43,22 +43,47 @@ class SecurityOrigin;
class MixedContentChecker {
WTF_MAKE_NONCOPYABLE(MixedContentChecker);
public:
- MixedContentChecker(Frame*);
+ MixedContentChecker(LocalFrame*);
- bool canDisplayInsecureContent(SecurityOrigin*, const KURL&) const;
- bool canRunInsecureContent(SecurityOrigin*, const KURL&) const;
+ bool canDisplayInsecureContent(SecurityOrigin* securityOrigin, const KURL& url) const
+ {
+ return canDisplayInsecureContentInternal(securityOrigin, url, MixedContentChecker::Display);
+ }
+ bool canSubmitToInsecureForm(SecurityOrigin* securityOrigin, const KURL& url) const
+ {
+ return canDisplayInsecureContentInternal(securityOrigin, url, MixedContentChecker::Submission);
+ }
+
+ bool canRunInsecureContent(SecurityOrigin* securityOrigin, const KURL& url) const
+ {
+ return canRunInsecureContentInternal(securityOrigin, url, MixedContentChecker::Execution);
+ }
+ bool canConnectInsecureWebSocket(SecurityOrigin* securityOrigin, const KURL& url) const
+ {
+ return canRunInsecureContentInternal(securityOrigin, url, MixedContentChecker::WebSocket);
+ }
static bool isMixedContent(SecurityOrigin*, const KURL&);
private:
+ enum MixedContentType {
+ Display,
+ Execution,
+ WebSocket,
+ Submission
+ };
+
// FIXME: This should probably have a separate client from FrameLoader.
FrameLoaderClient* client() const;
- void logWarning(bool allowed, const String& action, const KURL&) const;
+ bool canDisplayInsecureContentInternal(SecurityOrigin*, const KURL&, const MixedContentType) const;
+
+ bool canRunInsecureContentInternal(SecurityOrigin*, const KURL&, const MixedContentType) const;
- Frame* m_frame;
+ void logWarning(bool allowed, const KURL& i, const MixedContentType) const;
+
+ LocalFrame* m_frame;
};
} // namespace WebCore
#endif // MixedContentChecker_h
-
diff --git a/chromium/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp b/chromium/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp
new file mode 100644
index 00000000000..83dc24d4f48
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/MixedContentCheckerTest.cpp
@@ -0,0 +1,46 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/loader/MixedContentChecker.h"
+
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "wtf/RefPtr.h"
+
+#include <base/macros.h>
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+TEST(MixedContentCheckerTest, IsMixedContent)
+{
+ struct TestCase {
+ const char* origin;
+ const char* target;
+ bool expectation;
+ } cases[] = {
+ {"http://example.com/foo", "http://example.com/foo", false},
+ {"http://example.com/foo", "https://example.com/foo", false},
+ {"https://example.com/foo", "https://example.com/foo", false},
+ {"https://example.com/foo", "wss://example.com/foo", false},
+ {"https://example.com/foo", "http://example.com/foo", true},
+ {"https://example.com/foo", "http://google.com/foo", true},
+ {"https://example.com/foo", "ws://example.com/foo", true},
+ {"https://example.com/foo", "ws://google.com/foo", true},
+ };
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
+ const char* origin = cases[i].origin;
+ const char* target = cases[i].target;
+ bool expectation = cases[i].expectation;
+
+ KURL originUrl(KURL(), origin);
+ RefPtr<SecurityOrigin> securityOrigin(SecurityOrigin::create(originUrl));
+ KURL targetUrl(KURL(), target);
+ EXPECT_EQ(expectation, MixedContentChecker::isMixedContent(securityOrigin.get(), targetUrl)) << "Origin: " << origin << ", Target: " << target << ", Expectation: " << expectation;
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp b/chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp
index b0cffda86eb..c774000dcf3 100644
--- a/chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/NavigationAction.cpp
@@ -55,16 +55,21 @@ NavigationAction::NavigationAction()
}
NavigationAction::NavigationAction(const ResourceRequest& resourceRequest, FrameLoadType frameLoadType,
- bool isFormSubmission, PassRefPtr<Event> event)
+ bool isFormSubmission, PassRefPtrWillBeRawPtr<Event> passEvent)
: m_resourceRequest(resourceRequest)
- , m_type(navigationType(frameLoadType, isFormSubmission, event))
- , m_event(event)
{
+ RefPtrWillBeRawPtr<Event> event = passEvent;
+ m_type = navigationType(frameLoadType, isFormSubmission || resourceRequest.httpBody(), event);
+ m_eventTimeStamp = event ? event->timeStamp() : 0;
+
const MouseEvent* mouseEvent = 0;
- if (m_type == NavigationTypeLinkClicked && m_event->isMouseEvent())
- mouseEvent = toMouseEvent(m_event.get());
- else if (m_type == NavigationTypeFormSubmitted && m_event && m_event->underlyingEvent() && m_event->underlyingEvent()->isMouseEvent())
- mouseEvent = toMouseEvent(m_event->underlyingEvent());
+ if (m_type == NavigationTypeLinkClicked) {
+ ASSERT(event);
+ if (event->isMouseEvent())
+ mouseEvent = toMouseEvent(event.get());
+ } else if (m_type == NavigationTypeFormSubmitted && event && event->underlyingEvent() && event->underlyingEvent()->isMouseEvent()) {
+ mouseEvent = toMouseEvent(event->underlyingEvent());
+ }
if (!mouseEvent || !navigationPolicyFromMouseEvent(mouseEvent->button(), mouseEvent->ctrlKey(), mouseEvent->shiftKey(), mouseEvent->altKey(), mouseEvent->metaKey(), &m_policy))
m_policy = NavigationPolicyCurrentTab;
diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationAction.h b/chromium/third_party/WebKit/Source/core/loader/NavigationAction.h
index e50716bfe9c..2b199497617 100644
--- a/chromium/third_party/WebKit/Source/core/loader/NavigationAction.h
+++ b/chromium/third_party/WebKit/Source/core/loader/NavigationAction.h
@@ -29,6 +29,7 @@
#ifndef NavigationAction_h
#define NavigationAction_h
+#include "core/dom/DOMTimeStamp.h"
#include "core/events/Event.h"
#include "core/loader/FrameLoaderTypes.h"
#include "core/loader/NavigationPolicy.h"
@@ -41,18 +42,18 @@ namespace WebCore {
class NavigationAction {
public:
NavigationAction();
- NavigationAction(const ResourceRequest&, FrameLoadType = FrameLoadTypeStandard, bool isFormSubmission = false, PassRefPtr<Event> = 0);
+ NavigationAction(const ResourceRequest&, FrameLoadType = FrameLoadTypeStandard, bool isFormSubmission = false, PassRefPtrWillBeRawPtr<Event> = nullptr);
const ResourceRequest& resourceRequest() const { return m_resourceRequest; }
NavigationType type() const { return m_type; }
- Event* event() const { return m_event.get(); }
+ DOMTimeStamp eventTimeStamp() const { return m_eventTimeStamp; }
NavigationPolicy policy() const { return m_policy; }
bool shouldOpenInNewWindow() const { return m_policy != NavigationPolicyCurrentTab; }
private:
ResourceRequest m_resourceRequest;
NavigationType m_type;
- RefPtr<Event> m_event;
+ DOMTimeStamp m_eventTimeStamp;
NavigationPolicy m_policy;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.cpp b/chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.cpp
index e8494ff9daf..0a4dbe240ae 100644
--- a/chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "NavigationPolicy.h"
+#include "core/loader/NavigationPolicy.h"
#include "wtf/Assertions.h"
diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.h b/chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.h
index 63af6aa0f17..7e448628b6f 100644
--- a/chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.h
+++ b/chromium/third_party/WebKit/Source/core/loader/NavigationPolicy.h
@@ -36,6 +36,7 @@ namespace WebCore {
enum NavigationPolicy {
NavigationPolicyIgnore,
NavigationPolicyDownload,
+ NavigationPolicyDownloadTo,
NavigationPolicyCurrentTab,
NavigationPolicyNewBackgroundTab,
NavigationPolicyNewForegroundTab,
diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
index e47437cc842..0b0afb0d1f3 100644
--- a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.cpp
@@ -34,6 +34,7 @@
#include "bindings/v8/ScriptController.h"
#include "core/events/Event.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFormElement.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/DocumentLoader.h"
@@ -43,7 +44,6 @@
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/loader/FrameLoaderStateMachine.h"
-#include "core/frame/Frame.h"
#include "core/page/BackForwardClient.h"
#include "core/page/Page.h"
#include "platform/UserGestureIndicator.h"
@@ -67,9 +67,9 @@ public:
}
virtual ~ScheduledNavigation() { }
- virtual void fire(Frame*) = 0;
+ virtual void fire(LocalFrame*) = 0;
- virtual bool shouldStartTimer(Frame*) { return true; }
+ virtual bool shouldStartTimer(LocalFrame*) { return true; }
double delay() const { return m_delay; }
bool lockBackForwardList() const { return m_lockBackForwardList; }
@@ -96,7 +96,7 @@ private:
class ScheduledURLNavigation : public ScheduledNavigation {
protected:
- ScheduledURLNavigation(double delay, Document* originDocument, const String& url, const String& referrer, bool lockBackForwardList, bool isLocationChange)
+ ScheduledURLNavigation(double delay, Document* originDocument, const String& url, const Referrer& referrer, bool lockBackForwardList, bool isLocationChange)
: ScheduledNavigation(delay, lockBackForwardList, isLocationChange)
, m_originDocument(originDocument)
, m_url(url)
@@ -104,7 +104,7 @@ protected:
{
}
- virtual void fire(Frame* frame)
+ virtual void fire(LocalFrame* frame) OVERRIDE
{
OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
FrameLoadRequest request(m_originDocument.get(), ResourceRequest(KURL(ParsedURLString, m_url), m_referrer), "_self");
@@ -115,25 +115,25 @@ protected:
Document* originDocument() const { return m_originDocument.get(); }
String url() const { return m_url; }
- String referrer() const { return m_referrer; }
+ const Referrer& referrer() const { return m_referrer; }
private:
- RefPtr<Document> m_originDocument;
+ RefPtrWillBePersistent<Document> m_originDocument;
String m_url;
- String m_referrer;
+ Referrer m_referrer;
};
-class ScheduledRedirect : public ScheduledURLNavigation {
+class ScheduledRedirect FINAL : public ScheduledURLNavigation {
public:
ScheduledRedirect(double delay, Document* originDocument, const String& url, bool lockBackForwardList)
- : ScheduledURLNavigation(delay, originDocument, url, String(), lockBackForwardList, false)
+ : ScheduledURLNavigation(delay, originDocument, url, Referrer(), lockBackForwardList, false)
{
clearUserGesture();
}
- virtual bool shouldStartTimer(Frame* frame) { return frame->loader().allAncestorsAreComplete(); }
+ virtual bool shouldStartTimer(LocalFrame* frame) OVERRIDE { return frame->loader().allAncestorsAreComplete(); }
- virtual void fire(Frame* frame)
+ virtual void fire(LocalFrame* frame) OVERRIDE
{
OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
FrameLoadRequest request(originDocument(), ResourceRequest(KURL(ParsedURLString, url()), referrer()), "_self");
@@ -145,20 +145,20 @@ public:
}
};
-class ScheduledLocationChange : public ScheduledURLNavigation {
+class ScheduledLocationChange FINAL : public ScheduledURLNavigation {
public:
- ScheduledLocationChange(Document* originDocument, const String& url, const String& referrer, bool lockBackForwardList)
+ ScheduledLocationChange(Document* originDocument, const String& url, const Referrer& referrer, bool lockBackForwardList)
: ScheduledURLNavigation(0.0, originDocument, url, referrer, lockBackForwardList, true) { }
};
-class ScheduledRefresh : public ScheduledURLNavigation {
+class ScheduledRefresh FINAL : public ScheduledURLNavigation {
public:
- ScheduledRefresh(Document* originDocument, const String& url, const String& referrer)
+ ScheduledRefresh(Document* originDocument, const String& url, const Referrer& referrer)
: ScheduledURLNavigation(0.0, originDocument, url, referrer, true, true)
{
}
- virtual void fire(Frame* frame)
+ virtual void fire(LocalFrame* frame) OVERRIDE
{
OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
FrameLoadRequest request(originDocument(), ResourceRequest(KURL(ParsedURLString, url()), referrer(), ReloadIgnoringCacheData), "_self");
@@ -168,7 +168,7 @@ public:
}
};
-class ScheduledHistoryNavigation : public ScheduledNavigation {
+class ScheduledHistoryNavigation FINAL : public ScheduledNavigation {
public:
explicit ScheduledHistoryNavigation(int historySteps)
: ScheduledNavigation(0, false, true)
@@ -176,7 +176,7 @@ public:
{
}
- virtual void fire(Frame* frame)
+ virtual void fire(LocalFrame* frame) OVERRIDE
{
OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
@@ -190,23 +190,23 @@ public:
}
// go(i!=0) from a frame navigates into the history of the frame only,
// in both IE and NS (but not in Mozilla). We can't easily do that.
- frame->page()->mainFrame()->loader().client()->navigateBackForward(m_historySteps);
+ frame->page()->deprecatedLocalMainFrame()->loader().client()->navigateBackForward(m_historySteps);
}
private:
int m_historySteps;
};
-class ScheduledFormSubmission : public ScheduledNavigation {
+class ScheduledFormSubmission FINAL : public ScheduledNavigation {
public:
- ScheduledFormSubmission(PassRefPtr<FormSubmission> submission, bool lockBackForwardList)
+ ScheduledFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission> submission, bool lockBackForwardList)
: ScheduledNavigation(0, lockBackForwardList, true)
, m_submission(submission)
{
ASSERT(m_submission->state());
}
- virtual void fire(Frame* frame)
+ virtual void fire(LocalFrame* frame) OVERRIDE
{
OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
FrameLoadRequest frameRequest(m_submission->state()->sourceDocument());
@@ -217,14 +217,14 @@ public:
frame->loader().load(frameRequest);
}
- virtual bool isForm() const { return true; }
+ virtual bool isForm() const OVERRIDE { return true; }
FormSubmission* submission() const { return m_submission.get(); }
private:
- RefPtr<FormSubmission> m_submission;
+ RefPtrWillBePersistent<FormSubmission> m_submission;
};
-NavigationScheduler::NavigationScheduler(Frame* frame)
+NavigationScheduler::NavigationScheduler(LocalFrame* frame)
: m_frame(frame)
, m_timer(this, &NavigationScheduler::timerFired)
{
@@ -271,7 +271,7 @@ void NavigationScheduler::scheduleRedirect(double delay, const String& url)
schedule(adoptPtr(new ScheduledRedirect(delay, m_frame->document(), url, delay <= 1)));
}
-bool NavigationScheduler::mustLockBackForwardList(Frame* targetFrame)
+bool NavigationScheduler::mustLockBackForwardList(LocalFrame* targetFrame)
{
// Non-user navigation before the page has finished firing onload should not create a new back/forward item.
// See https://webkit.org/b/42861 for the original motivation for this.
@@ -289,10 +289,11 @@ bool NavigationScheduler::mustLockBackForwardList(Frame* targetFrame)
// Navigation of a subframe during loading of an ancestor frame does not create a new back/forward item.
// The definition of "during load" is any time before all handlers for the load event have been run.
// See https://bugs.webkit.org/show_bug.cgi?id=14957 for the original motivation for this.
- return targetFrame->tree().parent() && !targetFrame->tree().parent()->loader().allAncestorsAreComplete();
+ Frame* parentFrame = targetFrame->tree().parent();
+ return parentFrame && parentFrame->isLocalFrame() && !toLocalFrame(parentFrame)->loader().allAncestorsAreComplete();
}
-void NavigationScheduler::scheduleLocationChange(Document* originDocument, const String& url, const String& referrer, bool lockBackForwardList)
+void NavigationScheduler::scheduleLocationChange(Document* originDocument, const String& url, const Referrer& referrer, bool lockBackForwardList)
{
if (!shouldScheduleNavigation(url))
return;
@@ -310,7 +311,8 @@ void NavigationScheduler::scheduleLocationChange(Document* originDocument, const
if (parsedURL.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(m_frame->document()->url(), parsedURL)) {
FrameLoadRequest request(originDocument, ResourceRequest(m_frame->document()->completeURL(url), referrer), "_self");
request.setLockBackForwardList(lockBackForwardList);
- request.setClientRedirect(ClientRedirect);
+ if (lockBackForwardList)
+ request.setClientRedirect(ClientRedirect);
m_frame->loader().load(request);
return;
}
@@ -319,7 +321,7 @@ void NavigationScheduler::scheduleLocationChange(Document* originDocument, const
schedule(adoptPtr(new ScheduledLocationChange(originDocument, url, referrer, lockBackForwardList)));
}
-void NavigationScheduler::scheduleFormSubmission(PassRefPtr<FormSubmission> submission)
+void NavigationScheduler::scheduleFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission> submission)
{
ASSERT(m_frame->page());
schedule(adoptPtr(new ScheduledFormSubmission(submission, mustLockBackForwardList(m_frame))));
@@ -333,7 +335,7 @@ void NavigationScheduler::scheduleRefresh()
if (url.isEmpty())
return;
- schedule(adoptPtr(new ScheduledRefresh(m_frame->document(), url.string(), m_frame->document()->outgoingReferrer())));
+ schedule(adoptPtr(new ScheduledRefresh(m_frame->document(), url.string(), Referrer(m_frame->document()->outgoingReferrer(), m_frame->document()->referrerPolicy()))));
}
void NavigationScheduler::scheduleHistoryNavigation(int steps)
@@ -362,7 +364,7 @@ void NavigationScheduler::timerFired(Timer<NavigationScheduler>*)
return;
}
- RefPtr<Frame> protect(m_frame);
+ RefPtr<LocalFrame> protect(m_frame);
OwnPtr<ScheduledNavigation> redirect(m_redirect.release());
redirect->fire(m_frame);
@@ -372,6 +374,18 @@ void NavigationScheduler::timerFired(Timer<NavigationScheduler>*)
void NavigationScheduler::schedule(PassOwnPtr<ScheduledNavigation> redirect)
{
ASSERT(m_frame->page());
+
+ // In a back/forward navigation, we sometimes restore history state to iframes, even though the state was generated
+ // dynamically and JS will try to put something different in the iframe. In this case, we will load stale things
+ // and/or confuse the JS when it shortly thereafter tries to schedule a location change. Let the JS have its way.
+ // FIXME: This check seems out of place.
+ if (!m_frame->loader().stateMachine()->committedFirstRealDocumentLoad() && m_frame->loader().provisionalDocumentLoader()) {
+ RefPtr<Frame> protect(m_frame);
+ m_frame->loader().provisionalDocumentLoader()->stopLoading();
+ if (!m_frame->host())
+ return;
+ }
+
cancel();
m_redirect = redirect;
startTimer();
@@ -388,7 +402,7 @@ void NavigationScheduler::startTimer()
if (!m_redirect->shouldStartTimer(m_frame))
return;
- m_timer.startOneShot(m_redirect->delay());
+ m_timer.startOneShot(m_redirect->delay(), FROM_HERE);
InspectorInstrumentation::frameScheduledNavigation(m_frame, m_redirect->delay());
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h
index b10031e427c..84eec7c9347 100644
--- a/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h
+++ b/chromium/third_party/WebKit/Source/core/loader/NavigationScheduler.h
@@ -32,6 +32,7 @@
#define NavigationScheduler_h
#include "platform/Timer.h"
+#include "platform/weborigin/Referrer.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
@@ -44,7 +45,7 @@ namespace WebCore {
class Document;
class FormSubmission;
-class Frame;
+class LocalFrame;
class ScheduledNavigation;
class NavigationDisablerForBeforeUnload {
@@ -70,14 +71,14 @@ class NavigationScheduler {
WTF_MAKE_NONCOPYABLE(NavigationScheduler);
public:
- explicit NavigationScheduler(Frame*);
+ explicit NavigationScheduler(LocalFrame*);
~NavigationScheduler();
bool locationChangePending();
void scheduleRedirect(double delay, const String& url);
- void scheduleLocationChange(Document*, const String& url, const String& referrer, bool lockBackForwardList = true);
- void scheduleFormSubmission(PassRefPtr<FormSubmission>);
+ void scheduleLocationChange(Document*, const String& url, const Referrer& referrer, bool lockBackForwardList = true);
+ void scheduleFormSubmission(PassRefPtrWillBeRawPtr<FormSubmission>);
void scheduleRefresh();
void scheduleHistoryNavigation(int steps);
@@ -93,9 +94,9 @@ private:
void timerFired(Timer<NavigationScheduler>*);
void schedule(PassOwnPtr<ScheduledNavigation>);
- static bool mustLockBackForwardList(Frame* targetFrame);
+ static bool mustLockBackForwardList(LocalFrame* targetFrame);
- Frame* m_frame;
+ LocalFrame* m_frame;
Timer<NavigationScheduler> m_timer;
OwnPtr<ScheduledNavigation> m_redirect;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp
index 410143d86a4..99d5ee390a9 100644
--- a/chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/PingLoader.cpp
@@ -32,25 +32,30 @@
#include "config.h"
#include "core/loader/PingLoader.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/fetch/FetchContext.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
#include "core/loader/UniqueIdentifier.h"
+#include "core/page/Page.h"
#include "platform/exported/WrappedResourceRequest.h"
-#include "platform/network/FormData.h"
+#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "platform/weborigin/SecurityPolicy.h"
#include "public/platform/Platform.h"
#include "public/platform/WebURLLoader.h"
+#include "public/platform/WebURLResponse.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
-void PingLoader::loadImage(Frame* frame, const KURL& url)
+void PingLoader::loadImage(LocalFrame* frame, const KURL& url)
{
if (!frame->document()->securityOrigin()->canDisplay(url)) {
FrameLoader::reportLocalLoadFailed(frame, url.string());
@@ -60,18 +65,16 @@ void PingLoader::loadImage(Frame* frame, const KURL& url)
ResourceRequest request(url);
request.setTargetType(ResourceRequest::TargetIsPing);
request.setHTTPHeaderField("Cache-Control", "max-age=0");
- String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), request.url(), frame->document()->outgoingReferrer());
- if (!referrer.isEmpty())
- request.setHTTPReferrer(referrer);
- frame->loader().addExtraFieldsToRequest(request);
- OwnPtr<PingLoader> pingLoader = adoptPtr(new PingLoader(frame, request));
+ frame->loader().fetchContext().addAdditionalRequestHeaders(frame->document(), request, FetchSubresource);
+ frame->loader().fetchContext().setFirstPartyForCookies(request);
- // Leak the ping loader, since it will kill itself as soon as it receives a response.
- PingLoader* ALLOW_UNUSED leakedPingLoader = pingLoader.leakPtr();
+ FetchInitiatorInfo initiatorInfo;
+ initiatorInfo.name = FetchInitiatorTypeNames::ping;
+ PingLoader::start(frame, request, initiatorInfo);
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing
-void PingLoader::sendPing(Frame* frame, const KURL& pingURL, const KURL& destinationURL)
+void PingLoader::sendLinkAuditPing(LocalFrame* frame, const KURL& pingURL, const KURL& destinationURL)
{
ResourceRequest request(pingURL);
request.setTargetType(ResourceRequest::TargetIsPing);
@@ -79,61 +82,72 @@ void PingLoader::sendPing(Frame* frame, const KURL& pingURL, const KURL& destina
request.setHTTPContentType("text/ping");
request.setHTTPBody(FormData::create("PING"));
request.setHTTPHeaderField("Cache-Control", "max-age=0");
- frame->loader().addExtraFieldsToRequest(request);
+ frame->loader().fetchContext().addAdditionalRequestHeaders(frame->document(), request, FetchSubresource);
+ frame->loader().fetchContext().setFirstPartyForCookies(request);
- SecurityOrigin* sourceOrigin = frame->document()->securityOrigin();
RefPtr<SecurityOrigin> pingOrigin = SecurityOrigin::create(pingURL);
- FrameLoader::addHTTPOriginIfNeeded(request, sourceOrigin->toString());
- request.setHTTPHeaderField("Ping-To", destinationURL.string());
- if (!SecurityPolicy::shouldHideReferrer(pingURL, frame->document()->outgoingReferrer())) {
- request.setHTTPHeaderField("Ping-From", frame->document()->url().string());
- if (!sourceOrigin->isSameSchemeHostPort(pingOrigin.get())) {
- String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), pingURL, frame->document()->outgoingReferrer());
- if (!referrer.isEmpty())
- request.setHTTPReferrer(referrer);
- }
- }
- OwnPtr<PingLoader> pingLoader = adoptPtr(new PingLoader(frame, request));
+ // addAdditionalRequestHeaders() will have added a referrer for same origin requests,
+ // but the spec omits the referrer for same origin.
+ if (frame->document()->securityOrigin()->isSameSchemeHostPort(pingOrigin.get()))
+ request.clearHTTPReferrer();
- // Leak the ping loader, since it will kill itself as soon as it receives a response.
- PingLoader* ALLOW_UNUSED leakedPingLoader = pingLoader.leakPtr();
+ request.setHTTPHeaderField("Ping-To", AtomicString(destinationURL.string()));
+
+ // Ping-From follows the same rules as the default referrer beahavior for subresource requests.
+ // FIXME: Should Ping-From obey ReferrerPolicy?
+ if (!SecurityPolicy::shouldHideReferrer(pingURL, frame->document()->url().string()))
+ request.setHTTPHeaderField("Ping-From", AtomicString(frame->document()->url().string()));
+
+ FetchInitiatorInfo initiatorInfo;
+ initiatorInfo.name = FetchInitiatorTypeNames::ping;
+ PingLoader::start(frame, request, initiatorInfo);
}
-void PingLoader::sendViolationReport(Frame* frame, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType type)
+void PingLoader::sendViolationReport(LocalFrame* frame, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType type)
{
ResourceRequest request(reportURL);
request.setTargetType(ResourceRequest::TargetIsSubresource);
request.setHTTPMethod("POST");
request.setHTTPContentType(type == ContentSecurityPolicyViolationReport ? "application/csp-report" : "application/json");
request.setHTTPBody(report);
- frame->loader().addExtraFieldsToRequest(request);
+ frame->loader().fetchContext().addAdditionalRequestHeaders(frame->document(), request, FetchSubresource);
+ frame->loader().fetchContext().setFirstPartyForCookies(request);
+
+ FetchInitiatorInfo initiatorInfo;
+ initiatorInfo.name = FetchInitiatorTypeNames::violationreport;
+ PingLoader::start(frame, request, initiatorInfo, SecurityOrigin::create(reportURL)->isSameSchemeHostPort(frame->document()->securityOrigin()) ? AllowStoredCredentials : DoNotAllowStoredCredentials);
+}
- String referrer = SecurityPolicy::generateReferrerHeader(frame->document()->referrerPolicy(), reportURL, frame->document()->outgoingReferrer());
- if (!referrer.isEmpty())
- request.setHTTPReferrer(referrer);
- OwnPtr<PingLoader> pingLoader = adoptPtr(new PingLoader(frame, request, SecurityOrigin::create(reportURL)->isSameSchemeHostPort(frame->document()->securityOrigin()) ? AllowStoredCredentials : DoNotAllowStoredCredentials));
+void PingLoader::start(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed)
+{
+ OwnPtr<PingLoader> pingLoader = adoptPtr(new PingLoader(frame, request, initiatorInfo, credentialsAllowed));
// Leak the ping loader, since it will kill itself as soon as it receives a response.
- PingLoader* ALLOW_UNUSED leakedPingLoader = pingLoader.leakPtr();
+ PingLoader* leakedPingLoader ALLOW_UNUSED = pingLoader.leakPtr();
}
-PingLoader::PingLoader(Frame* frame, ResourceRequest& request, StoredCredentials credentialsAllowed)
- : m_timeout(this, &PingLoader::timeout)
+PingLoader::PingLoader(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed)
+ : PageLifecycleObserver(frame->page())
+ , m_timeout(this, &PingLoader::timeout)
+ , m_url(request.url())
+ , m_identifier(createUniqueIdentifier())
{
frame->loader().client()->didDispatchPingLoader(request.url());
- unsigned long identifier = createUniqueIdentifier();
m_loader = adoptPtr(blink::Platform::current()->createURLLoader());
ASSERT(m_loader);
blink::WrappedResourceRequest wrappedRequest(request);
wrappedRequest.setAllowStoredCredentials(credentialsAllowed == AllowStoredCredentials);
m_loader->loadAsynchronously(wrappedRequest, this);
- InspectorInstrumentation::continueAfterPingLoader(frame, identifier, frame->loader().activeDocumentLoader(), request, ResourceResponse());
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceSendRequest", "data", InspectorSendRequestEvent::data(m_identifier, frame, request));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::willSendRequest(frame, m_identifier, frame->loader().documentLoader(), request, ResourceResponse(), initiatorInfo);
// If the server never responds, FrameLoader won't be able to cancel this load and
// we'll sit here waiting forever. Set a very generous timeout, just in case.
- m_timeout.startOneShot(60000);
+ m_timeout.startOneShot(60000, FROM_HERE);
}
PingLoader::~PingLoader()
@@ -142,4 +156,54 @@ PingLoader::~PingLoader()
m_loader->cancel();
}
+void PingLoader::didReceiveResponse(blink::WebURLLoader*, const blink::WebURLResponse&)
+{
+ if (Page* page = this->page()) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceFinish", "data", InspectorResourceFinishEvent::data(m_identifier, 0, true));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didFailLoading(page->deprecatedLocalMainFrame(), m_identifier, ResourceError::cancelledError(m_url));
+ }
+ delete this;
+}
+
+void PingLoader::didReceiveData(blink::WebURLLoader*, const char*, int, int)
+{
+ if (Page* page = this->page()) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceFinish", "data", InspectorResourceFinishEvent::data(m_identifier, 0, true));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didFailLoading(page->deprecatedLocalMainFrame(), m_identifier, ResourceError::cancelledError(m_url));
+ }
+ delete this;
+}
+
+void PingLoader::didFinishLoading(blink::WebURLLoader*, double, int64_t)
+{
+ if (Page* page = this->page()) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceFinish", "data", InspectorResourceFinishEvent::data(m_identifier, 0, true));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didFailLoading(page->deprecatedLocalMainFrame(), m_identifier, ResourceError::cancelledError(m_url));
+ }
+ delete this;
+}
+
+void PingLoader::didFail(blink::WebURLLoader*, const blink::WebURLError& resourceError)
+{
+ if (Page* page = this->page()) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceFinish", "data", InspectorResourceFinishEvent::data(m_identifier, 0, true));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didFailLoading(page->deprecatedLocalMainFrame(), m_identifier, ResourceError(resourceError));
+ }
+ delete this;
+}
+
+void PingLoader::timeout(Timer<PingLoader>*)
+{
+ if (Page* page = this->page()) {
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ResourceFinish", "data", InspectorResourceFinishEvent::data(m_identifier, 0, true));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::didFailLoading(page->deprecatedLocalMainFrame(), m_identifier, ResourceError::cancelledError(m_url));
+ }
+ delete this;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/PingLoader.h b/chromium/third_party/WebKit/Source/core/loader/PingLoader.h
index e22f84caaf4..43e724a0e62 100644
--- a/chromium/third_party/WebKit/Source/core/loader/PingLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/PingLoader.h
@@ -33,6 +33,7 @@
#define PingLoader_h
#include "core/fetch/ResourceLoaderOptions.h"
+#include "core/page/PageLifecycleObserver.h"
#include "platform/Timer.h"
#include "public/platform/WebURLLoaderClient.h"
#include "wtf/Noncopyable.h"
@@ -41,45 +42,56 @@
namespace WebCore {
class FormData;
-class Frame;
+class LocalFrame;
class KURL;
class ResourceError;
class ResourceHandle;
class ResourceRequest;
class ResourceResponse;
-// This class triggers asynchronous loads independent of Frame staying alive (i.e., auditing pingbacks).
-// Since nothing depends on resources loaded through this class, we just want
-// to allow the load to live long enough to ensure the message was actually sent.
-// Therefore, as soon as a callback is received from the ResourceHandle, this class
-// will cancel the load and delete itself.
-class PingLoader : private blink::WebURLLoaderClient {
- WTF_MAKE_NONCOPYABLE(PingLoader); WTF_MAKE_FAST_ALLOCATED;
+// Issue an asynchronous, one-directional request at some resources, ignoring
+// any response. The request is made independent of any LocalFrame staying alive,
+// and must only stay alive until the transmission has completed successfully
+// (or not -- errors are not propagated back either.) Upon transmission, the
+// the load is cancelled and the loader cancels itself.
+//
+// The ping loader is used by audit pings, beacon transmissions and image loads
+// during page unloading.
+//
+class PingLoader : public PageLifecycleObserver, private blink::WebURLLoaderClient {
+ WTF_MAKE_NONCOPYABLE(PingLoader);
+ WTF_MAKE_FAST_ALLOCATED;
public:
+ virtual ~PingLoader();
+
enum ViolationReportType {
ContentSecurityPolicyViolationReport,
XSSAuditorViolationReport
};
- static void loadImage(Frame*, const KURL& url);
- static void sendPing(Frame*, const KURL& pingURL, const KURL& destinationURL);
- static void sendViolationReport(Frame*, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType);
+ static void loadImage(LocalFrame*, const KURL& url);
+ static void sendLinkAuditPing(LocalFrame*, const KURL& pingURL, const KURL& destinationURL);
+ static void sendViolationReport(LocalFrame*, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType);
- virtual ~PingLoader();
+protected:
+ PingLoader(LocalFrame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials);
+
+ static void start(LocalFrame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials = AllowStoredCredentials);
private:
- PingLoader(Frame*, ResourceRequest&, StoredCredentials = AllowStoredCredentials);
+ virtual void didReceiveResponse(blink::WebURLLoader*, const blink::WebURLResponse&) OVERRIDE;
+ virtual void didReceiveData(blink::WebURLLoader*, const char*, int, int) OVERRIDE;
+ virtual void didFinishLoading(blink::WebURLLoader*, double, int64_t) OVERRIDE;
+ virtual void didFail(blink::WebURLLoader*, const blink::WebURLError&) OVERRIDE;
- virtual void didReceiveResponse(blink::WebURLLoader*, const blink::WebURLResponse&) OVERRIDE { delete this; }
- virtual void didReceiveData(blink::WebURLLoader*, const char*, int, int) OVERRIDE { delete this; }
- virtual void didFinishLoading(blink::WebURLLoader*, double) OVERRIDE { delete this; }
- virtual void didFail(blink::WebURLLoader*, const blink::WebURLError&) OVERRIDE { delete this; }
- void timeout(Timer<PingLoader>*) { delete this; }
+ void timeout(Timer<PingLoader>*);
OwnPtr<blink::WebURLLoader> m_loader;
Timer<PingLoader> m_timeout;
+ String m_url;
+ unsigned long m_identifier;
};
}
-#endif
+#endif // PingLoader_h
diff --git a/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp b/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp
index 763506ab77a..21816709231 100644
--- a/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp
@@ -32,7 +32,7 @@
#include "core/loader/PrerenderHandle.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/PrerendererClient.h"
#include "platform/Prerender.h"
@@ -42,7 +42,7 @@
namespace WebCore {
// static
-PassOwnPtr<PrerenderHandle> PrerenderHandle::create(Document& document, PrerenderClient* client, const KURL& url)
+PassOwnPtr<PrerenderHandle> PrerenderHandle::create(Document& document, PrerenderClient* client, const KURL& url, const unsigned prerenderRelTypes)
{
// Prerenders are unlike requests in most ways (for instance, they pass down fragments, and they don't return data),
// but they do have referrers.
@@ -53,7 +53,7 @@ PassOwnPtr<PrerenderHandle> PrerenderHandle::create(Document& document, Prerende
const String referrer = SecurityPolicy::generateReferrerHeader(referrerPolicy, url, document.outgoingReferrer());
- RefPtr<Prerender> prerender = Prerender::create(client, url, referrer, referrerPolicy);
+ RefPtr<Prerender> prerender = Prerender::create(client, url, prerenderRelTypes, referrer, referrerPolicy);
PrerendererClient* prerendererClient = PrerendererClient::from(document.page());
if (prerendererClient)
diff --git a/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.h b/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.h
index 2adc058b85b..6c484af1ca0 100644
--- a/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.h
+++ b/chromium/third_party/WebKit/Source/core/loader/PrerenderHandle.h
@@ -43,10 +43,10 @@ class Document;
class Prerender;
class PrerenderClient;
-class PrerenderHandle : public DocumentLifecycleObserver {
+class PrerenderHandle FINAL : public DocumentLifecycleObserver {
WTF_MAKE_NONCOPYABLE(PrerenderHandle);
public:
- static PassOwnPtr<PrerenderHandle> create(Document&, PrerenderClient*, const KURL&);
+ static PassOwnPtr<PrerenderHandle> create(Document&, PrerenderClient*, const KURL&, unsigned prerenderRelTypes);
virtual ~PrerenderHandle();
diff --git a/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp b/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp
index 3db482676ec..8629bb3e094 100644
--- a/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.cpp
@@ -45,13 +45,13 @@ const char* PrerendererClient::supplementName()
// static
PrerendererClient* PrerendererClient::from(Page* page)
{
- PrerendererClient* supplement = static_cast<PrerendererClient*>(Supplement<Page>::from(page, supplementName()));
+ PrerendererClient* supplement = static_cast<PrerendererClient*>(WillBeHeapSupplement<Page>::from(page, supplementName()));
return supplement;
}
-void providePrerendererClientTo(Page* page, PrerendererClient* client)
+void providePrerendererClientTo(Page& page, PrerendererClient* client)
{
- PrerendererClient::provideTo(page, PrerendererClient::supplementName(), adoptPtr(client));
+ PrerendererClient::provideTo(page, PrerendererClient::supplementName(), adoptPtrWillBeNoop(client));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h b/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h
index 4c6a1952cc7..4d595f759d4 100644
--- a/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h
+++ b/chromium/third_party/WebKit/Source/core/loader/PrerendererClient.h
@@ -40,10 +40,8 @@ class Document;
class Page;
class Prerender;
-class PrerendererClient : public Supplement<Page> {
+class PrerendererClient : public WillBeHeapSupplement<Page> {
public:
- virtual ~PrerendererClient() { }
-
virtual void willAddPrerender(Prerender*) = 0;
static const char* supplementName();
@@ -53,7 +51,7 @@ protected:
PrerendererClient() { }
};
-void providePrerendererClientTo(Page*, PrerendererClient*);
+void providePrerendererClientTo(Page&, PrerendererClient*);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp b/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp
index df7477cb71f..f11a89f4211 100644
--- a/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.cpp
@@ -26,8 +26,9 @@
#include "config.h"
#include "core/loader/ProgressTracker.h"
-#include "core/frame/Frame.h"
+#include "core/fetch/ResourceFetcher.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/FrameLoaderClient.h"
@@ -61,8 +62,10 @@ public:
long long estimatedLength;
};
-ProgressTracker::ProgressTracker()
- : m_totalPageAndResourceBytesToLoad(0)
+ProgressTracker::ProgressTracker(LocalFrame* frame)
+ : m_frame(frame)
+ , m_inProgress(false)
+ , m_totalPageAndResourceBytesToLoad(0)
, m_totalBytesReceived(0)
, m_lastNotifiedProgressValue(0)
, m_lastNotifiedProgressTime(0)
@@ -70,17 +73,18 @@ ProgressTracker::ProgressTracker()
, m_progressNotificationTimeInterval(0.1)
, m_finalProgressChangedSent(false)
, m_progressValue(0)
- , m_numProgressTrackedFrames(0)
{
}
ProgressTracker::~ProgressTracker()
{
+ if (m_inProgress)
+ progressCompleted();
}
-PassOwnPtr<ProgressTracker> ProgressTracker::create()
+PassOwnPtr<ProgressTracker> ProgressTracker::create(LocalFrame* frame)
{
- return adoptPtr(new ProgressTracker);
+ return adoptPtr(new ProgressTracker(frame));
}
double ProgressTracker::estimatedProgress() const
@@ -98,59 +102,35 @@ void ProgressTracker::reset()
m_lastNotifiedProgressValue = 0;
m_lastNotifiedProgressTime = 0;
m_finalProgressChangedSent = false;
- m_numProgressTrackedFrames = 0;
- m_originatingProgressFrame = 0;
}
-void ProgressTracker::progressStarted(Frame* frame)
+void ProgressTracker::progressStarted()
{
- WTF_LOG(Progress, "Progress started (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree().uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
-
- if (m_numProgressTrackedFrames == 0 || m_originatingProgressFrame == frame) {
+ if (!m_inProgress) {
reset();
m_progressValue = initialProgressValue;
- m_originatingProgressFrame = frame;
-
- m_originatingProgressFrame->loader().client()->postProgressStartedNotification();
+ m_frame->loader().client()->didStartLoading(NavigationToDifferentDocument);
}
- m_numProgressTrackedFrames++;
- InspectorInstrumentation::frameStartedLoading(frame);
-}
-
-void ProgressTracker::progressCompleted(Frame* frame)
-{
- WTF_LOG(Progress, "Progress completed (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree().uniqueName().string().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
-
- if (m_numProgressTrackedFrames <= 0)
- return;
- m_numProgressTrackedFrames--;
- if (!m_numProgressTrackedFrames || m_originatingProgressFrame == frame)
- finalProgressComplete();
+ m_inProgress = true;
+ InspectorInstrumentation::frameStartedLoading(m_frame);
}
-void ProgressTracker::finalProgressComplete()
+void ProgressTracker::progressCompleted()
{
- WTF_LOG(Progress, "Final progress complete (%p)", this);
-
- RefPtr<Frame> frame = m_originatingProgressFrame.release();
-
- // Before resetting progress value be sure to send client a least one notification
- // with final progress value.
+ ASSERT(m_inProgress);
+ m_inProgress = false;
if (!m_finalProgressChangedSent) {
m_progressValue = 1;
- frame->loader().client()->postProgressEstimateChangedNotification();
+ m_frame->loader().client()->progressEstimateChanged(m_progressValue);
}
-
reset();
- frame->loader().client()->postProgressFinishedNotification();
- InspectorInstrumentation::frameStoppedLoading(frame.get());
+ m_frame->loader().client()->didStopLoading();
+ InspectorInstrumentation::frameStoppedLoading(m_frame);
}
void ProgressTracker::incrementProgress(unsigned long identifier, const ResourceResponse& response)
{
- WTF_LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d, originating frame %p", this, m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
-
- if (m_numProgressTrackedFrames <= 0)
+ if (!m_inProgress)
return;
long long estimatedLength = response.expectedContentLength();
@@ -174,8 +154,6 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i
if (!item)
return;
- RefPtr<Frame> frame = m_originatingProgressFrame;
-
unsigned bytesReceived = length;
double increment, percentOfRemainingBytes;
long long remainingBytes, estimatedBytesForPendingRequests;
@@ -186,7 +164,7 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i
item->estimatedLength = item->bytesReceived * 2;
}
- int numPendingOrLoadingRequests = frame->loader().numPendingOrLoadingRequests(true);
+ int numPendingOrLoadingRequests = m_frame->document()->fetcher()->requestCount();
estimatedBytesForPendingRequests = progressItemDefaultEstimatedLength * numPendingOrLoadingRequests;
remainingBytes = ((m_totalPageAndResourceBytesToLoad + estimatedBytesForPendingRequests) - m_totalBytesReceived);
if (remainingBytes > 0) // Prevent divide by 0.
@@ -195,7 +173,7 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i
percentOfRemainingBytes = 1.0;
// For documents that use WebCore's layout system, treat first layout as the half-way point.
- bool useClampedMaxProgress = !frame->view()->didFirstLayout();
+ bool useClampedMaxProgress = !m_frame->view()->didFirstLayout();
double maxProgressValue = useClampedMaxProgress ? 0.5 : finalProgressValue;
increment = (maxProgressValue - m_progressValue) * percentOfRemainingBytes;
m_progressValue += increment;
@@ -207,16 +185,13 @@ void ProgressTracker::incrementProgress(unsigned long identifier, const char*, i
double now = currentTime();
double notifiedProgressTimeDelta = now - m_lastNotifiedProgressTime;
- WTF_LOG(Progress, "Progress incremented (%p) - value %f, tracked frames %d", this, m_progressValue, m_numProgressTrackedFrames);
double notificationProgressDelta = m_progressValue - m_lastNotifiedProgressValue;
- if ((notificationProgressDelta >= m_progressNotificationInterval ||
- notifiedProgressTimeDelta >= m_progressNotificationTimeInterval) &&
- m_numProgressTrackedFrames > 0) {
+ if (notificationProgressDelta >= m_progressNotificationInterval || notifiedProgressTimeDelta >= m_progressNotificationTimeInterval) {
if (!m_finalProgressChangedSent) {
if (m_progressValue == 1)
m_finalProgressChangedSent = true;
- frame->loader().client()->postProgressEstimateChangedNotification();
+ m_frame->loader().client()->progressEstimateChanged(m_progressValue);
m_lastNotifiedProgressValue = m_progressValue;
m_lastNotifiedProgressTime = now;
diff --git a/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h b/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h
index fa7612f9dab..b92ed0651c1 100644
--- a/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h
+++ b/chromium/third_party/WebKit/Source/core/loader/ProgressTracker.h
@@ -26,6 +26,7 @@
#ifndef ProgressTracker_h
#define ProgressTracker_h
+#include "wtf/FastAllocBase.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
@@ -34,7 +35,7 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class ResourceResponse;
struct ProgressItem;
@@ -46,13 +47,12 @@ class ProgressTracker {
public:
~ProgressTracker();
- static PassOwnPtr<ProgressTracker> create();
- static unsigned long createUniqueIdentifier();
+ static PassOwnPtr<ProgressTracker> create(LocalFrame*);
double estimatedProgress() const;
- void progressStarted(Frame*);
- void progressCompleted(Frame*);
+ void progressStarted();
+ void progressCompleted();
void incrementProgress(unsigned long identifier, const ResourceResponse&);
void incrementProgress(unsigned long identifier, const char*, int);
@@ -62,11 +62,12 @@ public:
long long totalBytesReceived() const { return m_totalBytesReceived; }
private:
- ProgressTracker();
+ ProgressTracker(LocalFrame*);
void reset();
- void finalProgressComplete();
+ LocalFrame* m_frame;
+ bool m_inProgress;
long long m_totalPageAndResourceBytesToLoad;
long long m_totalBytesReceived;
double m_lastNotifiedProgressValue;
@@ -75,9 +76,7 @@ private:
double m_progressNotificationTimeInterval;
bool m_finalProgressChangedSent;
double m_progressValue;
- RefPtr<Frame> m_originatingProgressFrame;
- int m_numProgressTrackedFrames;
HashMap<unsigned long, OwnPtr<ProgressItem> > m_progressItems;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp b/chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp
index 990b71af0f4..213de49d270 100644
--- a/chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/SinkDocument.cpp
@@ -32,9 +32,9 @@ namespace WebCore {
class SinkDocumentParser : public RawDataDocumentParser {
public:
- static PassRefPtr<SinkDocumentParser> create(SinkDocument* document)
+ static PassRefPtrWillBeRawPtr<SinkDocumentParser> create(SinkDocument* document)
{
- return adoptRef(new SinkDocumentParser(document));
+ return adoptRefWillBeNoop(new SinkDocumentParser(document));
}
private:
@@ -54,7 +54,7 @@ SinkDocument::SinkDocument(const DocumentInit& initializer)
lockCompatibilityMode();
}
-PassRefPtr<DocumentParser> SinkDocument::createParser()
+PassRefPtrWillBeRawPtr<DocumentParser> SinkDocument::createParser()
{
return SinkDocumentParser::create(this);
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/SinkDocument.h b/chromium/third_party/WebKit/Source/core/loader/SinkDocument.h
index 3421775e603..dedb324edcb 100644
--- a/chromium/third_party/WebKit/Source/core/loader/SinkDocument.h
+++ b/chromium/third_party/WebKit/Source/core/loader/SinkDocument.h
@@ -32,15 +32,15 @@ namespace WebCore {
class SinkDocument FINAL : public HTMLDocument {
public:
- static PassRefPtr<SinkDocument> create(const DocumentInit& initializer = DocumentInit())
+ static PassRefPtrWillBeRawPtr<SinkDocument> create(const DocumentInit& initializer = DocumentInit())
{
- return adoptRef(new SinkDocument(initializer));
+ return adoptRefWillBeNoop(new SinkDocument(initializer));
}
private:
SinkDocument(const DocumentInit&);
- virtual PassRefPtr<DocumentParser> createParser();
+ virtual PassRefPtrWillBeRawPtr<DocumentParser> createParser() OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/SubstituteData.h b/chromium/third_party/WebKit/Source/core/loader/SubstituteData.h
index 48f19283a24..82a1398a28c 100644
--- a/chromium/third_party/WebKit/Source/core/loader/SubstituteData.h
+++ b/chromium/third_party/WebKit/Source/core/loader/SubstituteData.h
@@ -33,32 +33,42 @@
namespace WebCore {
- class SubstituteData {
- public:
- SubstituteData() { }
+enum SubstituteDataLoadPolicy {
+ LoadNormally,
+ ForceSynchronousLoad
+};
- SubstituteData(PassRefPtr<SharedBuffer> content, const AtomicString& mimeType, const AtomicString& textEncoding, const KURL& failingURL)
- : m_content(content)
- , m_mimeType(mimeType)
- , m_textEncoding(textEncoding)
- , m_failingURL(failingURL)
- {
- }
+class SubstituteData {
+public:
+ SubstituteData()
+ : m_substituteDataLoadPolicy(LoadNormally)
+ {
+ }
- bool isValid() const { return m_content != 0; }
+ SubstituteData(PassRefPtr<SharedBuffer> content, const AtomicString& mimeType, const AtomicString& textEncoding, const KURL& failingURL, SubstituteDataLoadPolicy substituteDataLoadPolicy = LoadNormally)
+ : m_content(content)
+ , m_mimeType(mimeType)
+ , m_textEncoding(textEncoding)
+ , m_failingURL(failingURL)
+ , m_substituteDataLoadPolicy(substituteDataLoadPolicy)
+ {
+ }
- const SharedBuffer* content() const { return m_content.get(); }
- const AtomicString& mimeType() const { return m_mimeType; }
- const AtomicString& textEncoding() const { return m_textEncoding; }
- const KURL& failingURL() const { return m_failingURL; }
+ bool isValid() const { return m_content; }
- private:
- RefPtr<SharedBuffer> m_content;
- AtomicString m_mimeType;
- AtomicString m_textEncoding;
- KURL m_failingURL;
- KURL m_responseURL;
- };
+ SharedBuffer* content() const { return m_content.get(); }
+ const AtomicString& mimeType() const { return m_mimeType; }
+ const AtomicString& textEncoding() const { return m_textEncoding; }
+ const KURL& failingURL() const { return m_failingURL; }
+ bool forceSynchronousLoad() const { return m_substituteDataLoadPolicy == ForceSynchronousLoad; }
+
+private:
+ RefPtr<SharedBuffer> m_content;
+ AtomicString m_mimeType;
+ AtomicString m_textEncoding;
+ KURL m_failingURL;
+ SubstituteDataLoadPolicy m_substituteDataLoadPolicy;
+};
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp b/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp
index ff4002adb3a..d6750fac4ad 100644
--- a/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.cpp
@@ -32,13 +32,13 @@
#include "core/loader/TextResourceDecoderBuilder.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace WebCore {
-static inline bool canReferToParentFrameEncoding(const Frame* frame, const Frame* parentFrame)
+static inline bool canReferToParentFrameEncoding(const LocalFrame* frame, const LocalFrame* parentFrame)
{
return parentFrame && parentFrame->document()->securityOrigin()->canAccess(frame->document()->securityOrigin());
}
@@ -58,7 +58,7 @@ TextResourceDecoderBuilder::~TextResourceDecoderBuilder()
inline PassOwnPtr<TextResourceDecoder> TextResourceDecoderBuilder::createDecoderInstance(Document* document)
{
- if (Frame* frame = document->frame()) {
+ if (LocalFrame* frame = document->frame()) {
if (Settings* settings = frame->settings())
return TextResourceDecoder::create(m_mimeType, settings->defaultTextEncodingName(), settings->usesEncodingDetector());
}
@@ -68,8 +68,10 @@ inline PassOwnPtr<TextResourceDecoder> TextResourceDecoderBuilder::createDecoder
inline void TextResourceDecoderBuilder::setupEncoding(TextResourceDecoder* decoder, Document* document)
{
- Frame* frame = document->frame();
- Frame* parentFrame = frame ? frame->tree().parent() : 0;
+ LocalFrame* frame = document->frame();
+ LocalFrame* parentFrame = 0;
+ if (frame && frame->tree().parent() && frame->tree().parent()->isLocalFrame())
+ parentFrame = toLocalFrame(frame->tree().parent());
if (!m_encoding.isEmpty())
decoder->setEncoding(m_encoding.string(), m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader);
diff --git a/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h b/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h
index b6c27c77464..8e89f3c0c9c 100644
--- a/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/loader/TextResourceDecoderBuilder.h
@@ -31,7 +31,7 @@
#ifndef TextResourceDecoderBuilder_h
#define TextResourceDecoderBuilder_h
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/WTFString.h"
diff --git a/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp
index 121a2b5c163..60fa74f9fb5 100644
--- a/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp
@@ -27,7 +27,7 @@
#include "core/loader/TextTrackLoader.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/Document.h"
#include "core/fetch/CrossOriginAccessControl.h"
#include "core/fetch/FetchRequest.h"
@@ -82,9 +82,9 @@ void TextTrackLoader::dataReceived(Resource* resource, const char* data, int len
m_cueParser->parseBytes(data, length);
}
-void TextTrackLoader::corsPolicyPreventedLoad()
+void TextTrackLoader::corsPolicyPreventedLoad(SecurityOrigin* securityOrigin, const KURL& url)
{
- DEFINE_STATIC_LOCAL(String, consoleMessage, ("Cross-origin text track load denied by Cross-Origin Resource Sharing policy."));
+ String consoleMessage("Text track from origin '" + SecurityOrigin::create(url)->toString() + "' has been blocked from loading: Not at same origin as the document, and parent of track element does not have a 'crossorigin' attribute. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.");
m_document.addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, consoleMessage);
m_state = Failed;
}
@@ -92,14 +92,6 @@ void TextTrackLoader::corsPolicyPreventedLoad()
void TextTrackLoader::notifyFinished(Resource* resource)
{
ASSERT(this->resource() == resource);
-
- if (!m_crossOriginMode.isNull()
- && !m_document.securityOrigin()->canRequest(resource->response().url())
- && !resource->passesAccessControlCheck(m_document.securityOrigin())) {
-
- corsPolicyPreventedLoad();
- }
-
if (m_state != Failed)
m_state = resource->errorOccurred() ? Failed : Finished;
@@ -107,31 +99,27 @@ void TextTrackLoader::notifyFinished(Resource* resource)
m_cueParser->flush();
if (!m_cueLoadTimer.isActive())
- m_cueLoadTimer.startOneShot(0);
+ m_cueLoadTimer.startOneShot(0, FROM_HERE);
cancelLoad();
}
-bool TextTrackLoader::load(const KURL& url, const String& crossOriginMode)
+bool TextTrackLoader::load(const KURL& url, const AtomicString& crossOriginMode)
{
cancelLoad();
FetchRequest cueRequest(ResourceRequest(m_document.completeURL(url)), FetchInitiatorTypeNames::texttrack);
if (!crossOriginMode.isNull()) {
- m_crossOriginMode = crossOriginMode;
- StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- updateRequestForAccessControl(cueRequest.mutableResourceRequest(), m_document.securityOrigin(), allowCredentials);
- } else {
- // Cross-origin resources that are not suitably CORS-enabled may not load.
- if (!m_document.securityOrigin()->canRequest(url)) {
- corsPolicyPreventedLoad();
- return false;
- }
+ cueRequest.setCrossOriginAccessControl(m_document.securityOrigin(), crossOriginMode);
+ } else if (!m_document.securityOrigin()->canRequest(url)) {
+ // Text track elements without 'crossorigin' set on the parent are "No CORS"; report error if not same-origin.
+ corsPolicyPreventedLoad(m_document.securityOrigin(), url);
+ return false;
}
ResourceFetcher* fetcher = m_document.fetcher();
- setResource(fetcher->fetchRawResource(cueRequest));
+ setResource(fetcher->fetchTextTrack(cueRequest));
return resource();
}
@@ -141,7 +129,7 @@ void TextTrackLoader::newCuesParsed()
return;
m_newCuesAvailable = true;
- m_cueLoadTimer.startOneShot(0);
+ m_cueLoadTimer.startOneShot(0, FROM_HERE);
}
void TextTrackLoader::newRegionsParsed()
@@ -156,23 +144,28 @@ void TextTrackLoader::fileFailedToParse()
m_state = Failed;
if (!m_cueLoadTimer.isActive())
- m_cueLoadTimer.startOneShot(0);
+ m_cueLoadTimer.startOneShot(0, FROM_HERE);
cancelLoad();
}
-void TextTrackLoader::getNewCues(Vector<RefPtr<VTTCue> >& outputCues)
+void TextTrackLoader::getNewCues(WillBeHeapVector<RefPtrWillBeMember<VTTCue> >& outputCues)
{
ASSERT(m_cueParser);
if (m_cueParser)
m_cueParser->getNewCues(outputCues);
}
-void TextTrackLoader::getNewRegions(Vector<RefPtr<VTTRegion> >& outputRegions)
+void TextTrackLoader::getNewRegions(WillBeHeapVector<RefPtrWillBeMember<VTTRegion> >& outputRegions)
{
ASSERT(m_cueParser);
if (m_cueParser)
m_cueParser->getNewRegions(outputRegions);
}
+void TextTrackLoader::trace(Visitor* visitor)
+{
+ visitor->trace(m_cueParser);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h b/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h
index 4ab8e95fd38..9ec2ba3106a 100644
--- a/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/TextTrackLoader.h
@@ -30,6 +30,7 @@
#include "core/fetch/ResourceOwner.h"
#include "core/html/track/vtt/VTTParser.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
@@ -46,24 +47,27 @@ public:
virtual void newRegionsAvailable(TextTrackLoader*) = 0;
};
-class TextTrackLoader : public ResourceOwner<RawResource>, private VTTParserClient {
+class TextTrackLoader FINAL : public NoBaseWillBeGarbageCollectedFinalized<TextTrackLoader>, public ResourceOwner<RawResource>, private VTTParserClient {
WTF_MAKE_NONCOPYABLE(TextTrackLoader);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<TextTrackLoader> create(TextTrackLoaderClient& client, Document& document)
+ static PassOwnPtrWillBeRawPtr<TextTrackLoader> create(TextTrackLoaderClient& client, Document& document)
{
- return adoptPtr(new TextTrackLoader(client, document));
+ return adoptPtrWillBeNoop(new TextTrackLoader(client, document));
}
virtual ~TextTrackLoader();
- bool load(const KURL&, const String& crossOriginMode);
+ bool load(const KURL&, const AtomicString& crossOriginMode);
void cancelLoad();
enum State { Idle, Loading, Finished, Failed };
State loadState() { return m_state; }
- void getNewCues(Vector<RefPtr<VTTCue> >& outputCues);
- void getNewRegions(Vector<RefPtr<VTTRegion> >& outputRegions);
+ void getNewCues(WillBeHeapVector<RefPtrWillBeMember<VTTCue> >& outputCues);
+ void getNewRegions(WillBeHeapVector<RefPtrWillBeMember<VTTRegion> >& outputRegions);
+
+ void trace(Visitor*);
+
private:
// RawResourceClient
@@ -78,14 +82,13 @@ private:
TextTrackLoader(TextTrackLoaderClient&, Document&);
void cueLoadTimerFired(Timer<TextTrackLoader>*);
- void corsPolicyPreventedLoad();
+ void corsPolicyPreventedLoad(SecurityOrigin*, const KURL&);
TextTrackLoaderClient& m_client;
- OwnPtr<VTTParser> m_cueParser;
+ OwnPtrWillBeMember<VTTParser> m_cueParser;
// FIXME: Remove this pointer and get the Document from m_client.
Document& m_document;
Timer<TextTrackLoader> m_cueLoadTimer;
- String m_crossOriginMode;
State m_state;
bool m_newCuesAvailable;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp
index 476f915fe9e..ed54bac70d6 100644
--- a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp
@@ -34,33 +34,37 @@
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
#include "core/loader/DocumentThreadableLoader.h"
+#include "core/loader/ThreadableLoaderClientWrapper.h"
+#include "core/loader/WorkerLoaderClientBridge.h"
#include "core/loader/WorkerThreadableLoader.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerRunLoop.h"
+#include "core/workers/WorkerThread.h"
namespace WebCore {
-PassRefPtr<ThreadableLoader> ThreadableLoader::create(ExecutionContext* context, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options)
+PassRefPtr<ThreadableLoader> ThreadableLoader::create(ExecutionContext& context, ThreadableLoaderClient* client, const ResourceRequest& request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
{
ASSERT(client);
- ASSERT(context);
- if (context->isWorkerGlobalScope())
- return WorkerThreadableLoader::create(toWorkerGlobalScope(context), client, WorkerRunLoop::defaultMode(), request, options);
+ if (context.isWorkerGlobalScope()) {
+ WorkerGlobalScope& workerGlobalScope = toWorkerGlobalScope(context);
+ RefPtr<ThreadableLoaderClientWrapper> clientWrapper(ThreadableLoaderClientWrapper::create(client));
+ OwnPtr<ThreadableLoaderClient> clientBridge(WorkerLoaderClientBridge::create(clientWrapper, workerGlobalScope.thread()->workerLoaderProxy()));
+ return WorkerThreadableLoader::create(workerGlobalScope, clientWrapper, clientBridge.release(), request, options, resourceLoaderOptions);
+ }
- return DocumentThreadableLoader::create(toDocument(context), client, request, options);
+ return DocumentThreadableLoader::create(toDocument(context), client, request, options, resourceLoaderOptions);
}
-void ThreadableLoader::loadResourceSynchronously(ExecutionContext* context, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options)
+void ThreadableLoader::loadResourceSynchronously(ExecutionContext& context, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
{
- ASSERT(context);
-
- if (context->isWorkerGlobalScope()) {
- WorkerThreadableLoader::loadResourceSynchronously(toWorkerGlobalScope(context), request, client, options);
+ if (context.isWorkerGlobalScope()) {
+ WorkerThreadableLoader::loadResourceSynchronously(toWorkerGlobalScope(context), request, client, options, resourceLoaderOptions);
return;
}
- DocumentThreadableLoader::loadResourceSynchronously(toDocument(context), request, client, options);
+ DocumentThreadableLoader::loadResourceSynchronously(toDocument(context), request, client, options, resourceLoaderOptions);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h
index a1092d24400..d3375043ae8 100644
--- a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoader.h
@@ -34,6 +34,7 @@
#include "core/fetch/ResourceLoaderOptions.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
namespace WebCore {
@@ -61,7 +62,7 @@ namespace WebCore {
DoNotEnforceContentSecurityPolicy,
};
- struct ThreadableLoaderOptions : public ResourceLoaderOptions {
+ struct ThreadableLoaderOptions {
ThreadableLoaderOptions()
: preflightPolicy(ConsiderPreflight)
, crossOriginRequestPolicy(DenyCrossOriginRequests)
@@ -77,21 +78,24 @@ namespace WebCore {
// Useful for doing loader operations from any thread (not threadsafe,
// just able to run on threads other than the main thread).
- class ThreadableLoader {
+ class ThreadableLoader : public RefCounted<ThreadableLoader> {
WTF_MAKE_NONCOPYABLE(ThreadableLoader);
public:
- static void loadResourceSynchronously(ExecutionContext*, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&);
- static PassRefPtr<ThreadableLoader> create(ExecutionContext*, ThreadableLoaderClient*, const ResourceRequest&, const ThreadableLoaderOptions&);
+ // ThreadableLoaderOptions argument configures this ThreadableLoader's
+ // behavior.
+ //
+ // ResourceLoaderOptions argument will be passed to the FetchRequest
+ // that this ThreadableLoader creates. It can be altered e.g. when
+ // redirect happens.
+ static void loadResourceSynchronously(ExecutionContext&, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&);
+ static PassRefPtr<ThreadableLoader> create(ExecutionContext&, ThreadableLoaderClient*, const ResourceRequest&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&);
virtual void cancel() = 0;
- void ref() { refThreadableLoader(); }
- void deref() { derefThreadableLoader(); }
+
+ virtual ~ThreadableLoader() { }
protected:
ThreadableLoader() { }
- virtual ~ThreadableLoader() { }
- virtual void refThreadableLoader() = 0;
- virtual void derefThreadableLoader() = 0;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h
index 152aa68371b..63aad5f4992 100644
--- a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h
+++ b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClient.h
@@ -31,6 +31,7 @@
#ifndef ThreadableLoaderClient_h
#define ThreadableLoaderClient_h
+#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
#include "wtf/Noncopyable.h"
@@ -40,7 +41,8 @@ namespace WebCore {
class ResourceResponse;
class ThreadableLoaderClient {
- WTF_MAKE_NONCOPYABLE(ThreadableLoaderClient); WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_NONCOPYABLE(ThreadableLoaderClient);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
virtual void didSendData(unsigned long long /*bytesSent*/, unsigned long long /*totalBytesToBeSent*/) { }
@@ -56,9 +58,10 @@ namespace WebCore {
virtual void didDownloadData(int /*dataLength*/) { }
+ virtual ~ThreadableLoaderClient() { }
+
protected:
ThreadableLoaderClient() { }
- virtual ~ThreadableLoaderClient() { }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClientWrapper.h b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClientWrapper.h
index 22a7e99a825..56da8f8e063 100644
--- a/chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClientWrapper.h
+++ b/chromium/third_party/WebKit/Source/core/loader/ThreadableLoaderClientWrapper.h
@@ -34,6 +34,7 @@
#include "core/loader/ThreadableLoaderClient.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassRefPtr.h"
+#include "wtf/ThreadSafeRefCounted.h"
#include "wtf/Threading.h"
namespace WebCore {
diff --git a/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridge.cpp b/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridge.cpp
new file mode 100644
index 00000000000..c73d1e6e083
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridge.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/loader/WorkerLoaderClientBridge.h"
+
+#include "core/dom/CrossThreadTask.h"
+#include "core/loader/ThreadableLoaderClientWrapper.h"
+#include "core/workers/WorkerGlobalScope.h"
+#include "core/workers/WorkerLoaderProxy.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+PassOwnPtr<ThreadableLoaderClient> WorkerLoaderClientBridge::create(PassRefPtr<ThreadableLoaderClientWrapper> client, WorkerLoaderProxy& loaderProxy)
+{
+ return adoptPtr(new WorkerLoaderClientBridge(client, loaderProxy));
+}
+
+WorkerLoaderClientBridge::~WorkerLoaderClientBridge()
+{
+}
+
+static void workerGlobalScopeDidSendData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ workerClientWrapper->didSendData(bytesSent, totalBytesToBeSent);
+}
+
+void WorkerLoaderClientBridge::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+{
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidSendData, m_workerClientWrapper, bytesSent, totalBytesToBeSent));
+}
+
+static void workerGlobalScopeDidReceiveResponse(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, PassOwnPtr<CrossThreadResourceResponseData> responseData)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData));
+ workerClientWrapper->didReceiveResponse(identifier, *response);
+}
+
+void WorkerLoaderClientBridge::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
+{
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveResponse, m_workerClientWrapper, identifier, response));
+}
+
+static void workerGlobalScopeDidReceiveData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ workerClientWrapper->didReceiveData(vectorData->data(), vectorData->size());
+}
+
+void WorkerLoaderClientBridge::didReceiveData(const char* data, int dataLength)
+{
+ OwnPtr<Vector<char> > vector = adoptPtr(new Vector<char>(dataLength)); // needs to be an OwnPtr for usage with createCallbackTask.
+ memcpy(vector->data(), data, dataLength);
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveData, m_workerClientWrapper, vector.release()));
+}
+
+static void workerGlobalScopeDidDownloadData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, int dataLength)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ workerClientWrapper->didDownloadData(dataLength);
+}
+
+void WorkerLoaderClientBridge::didDownloadData(int dataLength)
+{
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidDownloadData, m_workerClientWrapper, dataLength));
+}
+
+static void workerGlobalScopeDidReceiveCachedMetadata(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ workerClientWrapper->didReceiveCachedMetadata(vectorData->data(), vectorData->size());
+}
+
+void WorkerLoaderClientBridge::didReceiveCachedMetadata(const char* data, int dataLength)
+{
+ OwnPtr<Vector<char> > vector = adoptPtr(new Vector<char>(dataLength)); // needs to be an OwnPtr for usage with createCallbackTask.
+ memcpy(vector->data(), data, dataLength);
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveCachedMetadata, m_workerClientWrapper, vector.release()));
+}
+
+static void workerGlobalScopeDidFinishLoading(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, double finishTime)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ workerClientWrapper->didFinishLoading(identifier, finishTime);
+}
+
+void WorkerLoaderClientBridge::didFinishLoading(unsigned long identifier, double finishTime)
+{
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFinishLoading, m_workerClientWrapper, identifier, finishTime));
+}
+
+static void workerGlobalScopeDidFail(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ workerClientWrapper->didFail(error);
+}
+
+void WorkerLoaderClientBridge::didFail(const ResourceError& error)
+{
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFail, m_workerClientWrapper, error));
+}
+
+static void workerGlobalScopeDidFailAccessControlCheck(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ workerClientWrapper->didFailAccessControlCheck(error);
+}
+
+void WorkerLoaderClientBridge::didFailAccessControlCheck(const ResourceError& error)
+{
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFailAccessControlCheck, m_workerClientWrapper, error));
+}
+
+static void workerGlobalScopeDidFailRedirectCheck(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper)
+{
+ ASSERT_UNUSED(context, context->isWorkerGlobalScope());
+ workerClientWrapper->didFailRedirectCheck();
+}
+
+void WorkerLoaderClientBridge::didFailRedirectCheck()
+{
+ m_loaderProxy.postTaskToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFailRedirectCheck, m_workerClientWrapper));
+}
+
+WorkerLoaderClientBridge::WorkerLoaderClientBridge(PassRefPtr<ThreadableLoaderClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy)
+ : m_workerClientWrapper(clientWrapper)
+ , m_loaderProxy(loaderProxy)
+{
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridge.h b/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridge.h
new file mode 100644
index 00000000000..50242f445f9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridge.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerLoaderClientBridge_h
+#define WorkerLoaderClientBridge_h
+
+#include "core/loader/ThreadableLoaderClient.h"
+#include "wtf/Forward.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ThreadableLoaderClientWrapper;
+class WorkerLoaderProxy;
+
+// This bridge is created and destroyed on the worker thread, but is
+// passed to and used on the main thread. Each did* method relays the given
+// data to the client wrapper on the worker context thread.
+class WorkerLoaderClientBridge : public ThreadableLoaderClient {
+public:
+ static PassOwnPtr<ThreadableLoaderClient> create(PassRefPtr<ThreadableLoaderClientWrapper>, WorkerLoaderProxy&);
+ virtual ~WorkerLoaderClientBridge();
+
+ virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
+ virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) OVERRIDE;
+ virtual void didReceiveData(const char*, int dataLength) OVERRIDE;
+ virtual void didDownloadData(int dataLength) OVERRIDE;
+ virtual void didReceiveCachedMetadata(const char*, int dataLength) OVERRIDE;
+ virtual void didFinishLoading(unsigned long identifier, double finishTime) OVERRIDE;
+ virtual void didFail(const ResourceError&) OVERRIDE;
+ virtual void didFailAccessControlCheck(const ResourceError&) OVERRIDE;
+ virtual void didFailRedirectCheck() OVERRIDE;
+
+private:
+ WorkerLoaderClientBridge(PassRefPtr<ThreadableLoaderClientWrapper>, WorkerLoaderProxy&);
+
+ // Used on the worker context thread, while its refcounting is done on
+ // either thread.
+ RefPtr<ThreadableLoaderClientWrapper> m_workerClientWrapper;
+
+ WorkerLoaderProxy& m_loaderProxy;
+};
+
+} // namespace WebCore
+
+#endif // WorkerLoaderClientBridge_h
diff --git a/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp b/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp
new file mode 100644
index 00000000000..451442a2676
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/loader/WorkerLoaderClientBridgeSyncHelper.h"
+
+#include "core/workers/WorkerGlobalScope.h"
+#include "core/workers/WorkerLoaderProxy.h"
+#include "public/platform/WebWaitableEvent.h"
+#include "wtf/ArrayBuffer.h"
+#include "wtf/Functional.h"
+#include "wtf/MainThread.h"
+#include "wtf/OwnPtr.h"
+
+namespace WebCore {
+
+PassOwnPtr<WorkerLoaderClientBridgeSyncHelper> WorkerLoaderClientBridgeSyncHelper::create(ThreadableLoaderClient& client, PassOwnPtr<blink::WebWaitableEvent> event)
+{
+ return adoptPtr(new WorkerLoaderClientBridgeSyncHelper(client, event));
+}
+
+WorkerLoaderClientBridgeSyncHelper::~WorkerLoaderClientBridgeSyncHelper()
+{
+ ASSERT(isMainThread());
+ for (size_t i = 0; i < m_receivedData.size(); ++i)
+ delete m_receivedData[i];
+}
+
+void WorkerLoaderClientBridgeSyncHelper::run()
+{
+ // This must be called only after m_event is signalled.
+ ASSERT(m_done);
+ for (size_t i = 0; i < m_clientTasks.size(); ++i)
+ m_clientTasks[i]();
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
+{
+ ASSERT(isMainThread());
+ m_clientTasks.append(bind(&ThreadableLoaderClient::didSendData, &m_client, bytesSent, totalBytesToBeSent));
+}
+
+static void didReceiveResponseAdapter(ThreadableLoaderClient* client, unsigned long identifier, PassOwnPtr<CrossThreadResourceResponseData> responseData)
+{
+ OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData));
+ client->didReceiveResponse(identifier, *response);
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
+{
+ ASSERT(isMainThread());
+ m_clientTasks.append(bind(&didReceiveResponseAdapter, &m_client, identifier, response.copyData()));
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didReceiveData(const char* data, int dataLength)
+{
+ ASSERT(isMainThread());
+ Vector<char>* buffer = new Vector<char>(dataLength);
+ memcpy(buffer->data(), data, dataLength);
+ m_receivedData.append(buffer);
+ m_clientTasks.append(bind(&ThreadableLoaderClient::didReceiveData, &m_client, static_cast<const char*>(buffer->data()), dataLength));
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didDownloadData(int dataLength)
+{
+ ASSERT(isMainThread());
+ m_clientTasks.append(bind(&ThreadableLoaderClient::didDownloadData, &m_client, dataLength));
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didReceiveCachedMetadata(const char* data, int dataLength)
+{
+ ASSERT(isMainThread());
+ Vector<char>* buffer = new Vector<char>(dataLength);
+ memcpy(buffer->data(), data, dataLength);
+ m_receivedData.append(buffer);
+ m_clientTasks.append(bind(&ThreadableLoaderClient::didReceiveCachedMetadata, &m_client, static_cast<const char*>(buffer->data()), dataLength));
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didFinishLoading(unsigned long identifier, double finishTime)
+{
+ ASSERT(isMainThread());
+ m_clientTasks.append(bind(&ThreadableLoaderClient::didFinishLoading, &m_client, identifier, finishTime));
+ m_done = true;
+ m_event->signal();
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didFail(const ResourceError& error)
+{
+ ASSERT(isMainThread());
+ m_clientTasks.append(bind(&ThreadableLoaderClient::didFail, &m_client, error));
+ m_done = true;
+ m_event->signal();
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didFailAccessControlCheck(const ResourceError& error)
+{
+ ASSERT(isMainThread());
+ m_clientTasks.append(bind(&ThreadableLoaderClient::didFailAccessControlCheck, &m_client, error));
+ m_done = true;
+ m_event->signal();
+}
+
+void WorkerLoaderClientBridgeSyncHelper::didFailRedirectCheck()
+{
+ ASSERT(isMainThread());
+ m_clientTasks.append(bind(&ThreadableLoaderClient::didFailRedirectCheck, &m_client));
+ m_done = true;
+ m_event->signal();
+}
+
+WorkerLoaderClientBridgeSyncHelper::WorkerLoaderClientBridgeSyncHelper(ThreadableLoaderClient& client, PassOwnPtr<blink::WebWaitableEvent> event)
+ : m_done(false)
+ , m_client(client)
+ , m_event(event)
+{
+ ASSERT(m_event);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.h b/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.h
new file mode 100644
index 00000000000..7ab1cf6b365
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WorkerLoaderClientBridgeSyncHelper_h
+#define WorkerLoaderClientBridgeSyncHelper_h
+
+#include "core/loader/ThreadableLoaderClient.h"
+#include "wtf/Forward.h"
+#include "wtf/Functional.h"
+#include "wtf/Vector.h"
+
+namespace blink {
+class WebWaitableEvent;
+}
+
+namespace WebCore {
+
+// This bridge is created and destroyed on the worker thread, but is
+// passed to and used on the main thread. Each did* method records the given
+// data so that they can be run on the worker thread later (by run()).
+class WorkerLoaderClientBridgeSyncHelper : public ThreadableLoaderClient {
+public:
+ static PassOwnPtr<WorkerLoaderClientBridgeSyncHelper> create(ThreadableLoaderClient&, PassOwnPtr<blink::WebWaitableEvent>);
+ virtual ~WorkerLoaderClientBridgeSyncHelper();
+
+ // Called on the worker context thread.
+ void run();
+
+ // Called on the main thread.
+ virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
+ virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) OVERRIDE;
+ virtual void didReceiveData(const char*, int dataLength) OVERRIDE;
+ virtual void didDownloadData(int dataLength) OVERRIDE;
+ virtual void didReceiveCachedMetadata(const char*, int dataLength) OVERRIDE;
+ virtual void didFinishLoading(unsigned long identifier, double finishTime) OVERRIDE;
+ virtual void didFail(const ResourceError&) OVERRIDE;
+ virtual void didFailAccessControlCheck(const ResourceError&) OVERRIDE;
+ virtual void didFailRedirectCheck() OVERRIDE;
+
+private:
+ WorkerLoaderClientBridgeSyncHelper(ThreadableLoaderClient&, PassOwnPtr<blink::WebWaitableEvent>);
+
+ bool m_done;
+ ThreadableLoaderClient& m_client;
+ OwnPtr<blink::WebWaitableEvent> m_event;
+ Vector<Vector<char>*> m_receivedData;
+ Vector<Closure> m_clientTasks;
+};
+
+} // namespace WebCore
+
+#endif // WorkerLoaderClientBridgeSyncHelper_h
diff --git a/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp b/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
index ad16a0f36d0..b4ee50843c9 100644
--- a/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
@@ -35,26 +35,26 @@
#include "core/dom/CrossThreadTask.h"
#include "core/dom/Document.h"
#include "core/loader/DocumentThreadableLoader.h"
+#include "core/loader/WorkerLoaderClientBridgeSyncHelper.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerLoaderProxy.h"
#include "core/workers/WorkerThread.h"
#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
#include "platform/network/ResourceResponse.h"
+#include "platform/weborigin/Referrer.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebWaitableEvent.h"
#include "wtf/MainThread.h"
#include "wtf/OwnPtr.h"
#include "wtf/Vector.h"
-using namespace std;
-
namespace WebCore {
-static const char loadResourceSynchronouslyMode[] = "loadResourceSynchronouslyMode";
-
-WorkerThreadableLoader::WorkerThreadableLoader(WorkerGlobalScope* workerGlobalScope, ThreadableLoaderClient* client, const String& taskMode, const ResourceRequest& request, const ThreadableLoaderOptions& options)
- : m_workerGlobalScope(workerGlobalScope)
- , m_workerClientWrapper(ThreadableLoaderClientWrapper::create(client))
- , m_bridge(*(new MainThreadBridge(m_workerClientWrapper, m_workerGlobalScope->thread()->workerLoaderProxy(), taskMode, request, options, workerGlobalScope->url().strippedForUseAsReferrer())))
+WorkerThreadableLoader::WorkerThreadableLoader(WorkerGlobalScope& workerGlobalScope, PassRefPtr<ThreadableLoaderClientWrapper> clientWrapper, PassOwnPtr<ThreadableLoaderClient> clientBridge, const ResourceRequest& request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
+ : m_workerGlobalScope(&workerGlobalScope)
+ , m_workerClientWrapper(clientWrapper)
+ , m_bridge(*(new MainThreadBridge(m_workerClientWrapper, clientBridge, workerGlobalScope.thread()->workerLoaderProxy(), request, options, resourceLoaderOptions, workerGlobalScope.url().strippedForUseAsReferrer())))
{
}
@@ -63,21 +63,36 @@ WorkerThreadableLoader::~WorkerThreadableLoader()
m_bridge.destroy();
}
-void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope* workerGlobalScope, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options)
+void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope& workerGlobalScope, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
{
- WorkerRunLoop& runLoop = workerGlobalScope->thread()->runLoop();
+ blink::WebWaitableEvent* shutdownEvent =
+ workerGlobalScope.thread()->shutdownEvent();
+ OwnPtr<blink::WebWaitableEvent> loaderDone =
+ adoptPtr(blink::Platform::current()->createWaitableEvent());
+
+ Vector<blink::WebWaitableEvent*> events;
+ events.append(shutdownEvent);
+ events.append(loaderDone.get());
- // Create a unique mode just for this synchronous resource load.
- String mode = loadResourceSynchronouslyMode;
- mode.append(String::number(runLoop.createUniqueId()));
+ RefPtr<ThreadableLoaderClientWrapper> clientWrapper(ThreadableLoaderClientWrapper::create(&client));
+ OwnPtr<WorkerLoaderClientBridgeSyncHelper> clientBridge(WorkerLoaderClientBridgeSyncHelper::create(client, loaderDone.release()));
- RefPtr<WorkerThreadableLoader> loader = WorkerThreadableLoader::create(workerGlobalScope, &client, mode, request, options);
- MessageQueueWaitResult result = MessageQueueMessageReceived;
- while (!loader->done() && result != MessageQueueTerminated)
- result = runLoop.runInMode(workerGlobalScope, mode);
+ // This must be valid while loader is around.
+ WorkerLoaderClientBridgeSyncHelper* clientBridgePtr = clientBridge.get();
- if (!loader->done() && result == MessageQueueTerminated)
+ RefPtr<WorkerThreadableLoader> loader = WorkerThreadableLoader::create(workerGlobalScope, clientWrapper, clientBridge.release(), request, options, resourceLoaderOptions);
+
+ blink::WebWaitableEvent* signalled;
+ {
+ ThreadState::SafePointScope scope(ThreadState::HeapPointersOnStack);
+ signalled = blink::Platform::current()->waitMultipleEvents(events);
+ }
+ if (signalled == shutdownEvent) {
loader->cancel();
+ return;
+ }
+
+ clientBridgePtr->run();
}
void WorkerThreadableLoader::cancel()
@@ -85,31 +100,37 @@ void WorkerThreadableLoader::cancel()
m_bridge.cancel();
}
-WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, WorkerLoaderProxy& loaderProxy, const String& taskMode,
- const ResourceRequest& request, const ThreadableLoaderOptions& options, const String& outgoingReferrer)
- : m_workerClientWrapper(workerClientWrapper)
+WorkerThreadableLoader::MainThreadBridge::MainThreadBridge(
+ PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper,
+ PassOwnPtr<ThreadableLoaderClient> clientBridge,
+ WorkerLoaderProxy& loaderProxy,
+ const ResourceRequest& request,
+ const ThreadableLoaderOptions& options,
+ const ResourceLoaderOptions& resourceLoaderOptions,
+ const String& outgoingReferrer)
+ : m_clientBridge(clientBridge)
+ , m_workerClientWrapper(workerClientWrapper)
, m_loaderProxy(loaderProxy)
- , m_taskMode(taskMode.isolatedCopy())
{
ASSERT(m_workerClientWrapper.get());
+ ASSERT(m_clientBridge.get());
m_loaderProxy.postTaskToLoader(
- createCallbackTask(&MainThreadBridge::mainThreadCreateLoader,
- AllowCrossThreadAccess(this), request, options, outgoingReferrer));
+ createCallbackTask(&MainThreadBridge::mainThreadCreateLoader, AllowCrossThreadAccess(this), request, options, resourceLoaderOptions, outgoingReferrer));
}
WorkerThreadableLoader::MainThreadBridge::~MainThreadBridge()
{
}
-void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ExecutionContext* context, MainThreadBridge* thisPtr, PassOwnPtr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options, const String& outgoingReferrer)
+void WorkerThreadableLoader::MainThreadBridge::mainThreadCreateLoader(ExecutionContext* context, MainThreadBridge* thisPtr, PassOwnPtr<CrossThreadResourceRequestData> requestData, ThreadableLoaderOptions options, ResourceLoaderOptions resourceLoaderOptions, const String& outgoingReferrer)
{
ASSERT(isMainThread());
Document* document = toDocument(context);
OwnPtr<ResourceRequest> request(ResourceRequest::adopt(requestData));
- request->setHTTPReferrer(outgoingReferrer);
- options.requestInitiatorContext = WorkerContext;
- thisPtr->m_mainThreadLoader = DocumentThreadableLoader::create(document, thisPtr, *request, options);
+ request->setHTTPReferrer(Referrer(outgoingReferrer, ReferrerPolicyDefault));
+ resourceLoaderOptions.requestInitiatorContext = WorkerContext;
+ thisPtr->m_mainThreadLoader = DocumentThreadableLoader::create(*document, thisPtr, *request, options, resourceLoaderOptions);
if (!thisPtr->m_mainThreadLoader) {
// DocumentThreadableLoader::create may return 0 when the document loader has been already changed.
thisPtr->didFail(ResourceError(errorDomainBlinkInternal, 0, request->url().string(), "Can't create DocumentThreadableLoader"));
@@ -141,7 +162,7 @@ void WorkerThreadableLoader::MainThreadBridge::mainThreadCancel(ExecutionContext
if (!thisPtr->m_mainThreadLoader)
return;
thisPtr->m_mainThreadLoader->cancel();
- thisPtr->m_mainThreadLoader = 0;
+ thisPtr->m_mainThreadLoader = nullptr;
}
void WorkerThreadableLoader::MainThreadBridge::cancel()
@@ -164,108 +185,49 @@ void WorkerThreadableLoader::MainThreadBridge::clearClientWrapper()
m_workerClientWrapper->clearClient();
}
-static void workerGlobalScopeDidSendData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- workerClientWrapper->didSendData(bytesSent, totalBytesToBeSent);
-}
-
void WorkerThreadableLoader::MainThreadBridge::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
{
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidSendData, m_workerClientWrapper, bytesSent, totalBytesToBeSent), m_taskMode);
-}
-
-static void workerGlobalScopeDidReceiveResponse(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, PassOwnPtr<CrossThreadResourceResponseData> responseData)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- OwnPtr<ResourceResponse> response(ResourceResponse::adopt(responseData));
- workerClientWrapper->didReceiveResponse(identifier, *response);
+ m_clientBridge->didSendData(bytesSent, totalBytesToBeSent);
}
void WorkerThreadableLoader::MainThreadBridge::didReceiveResponse(unsigned long identifier, const ResourceResponse& response)
{
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveResponse, m_workerClientWrapper, identifier, response), m_taskMode);
-}
-
-static void workerGlobalScopeDidReceiveData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- workerClientWrapper->didReceiveData(vectorData->data(), vectorData->size());
+ m_clientBridge->didReceiveResponse(identifier, response);
}
void WorkerThreadableLoader::MainThreadBridge::didReceiveData(const char* data, int dataLength)
{
- OwnPtr<Vector<char> > vector = adoptPtr(new Vector<char>(dataLength)); // needs to be an OwnPtr for usage with createCallbackTask.
- memcpy(vector->data(), data, dataLength);
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveData, m_workerClientWrapper, vector.release()), m_taskMode);
-}
-
-static void workerGlobalScopeDidDownloadData(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, int dataLength)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- workerClientWrapper->didDownloadData(dataLength);
+ m_clientBridge->didReceiveData(data, dataLength);
}
void WorkerThreadableLoader::MainThreadBridge::didDownloadData(int dataLength)
{
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidDownloadData, m_workerClientWrapper, dataLength), m_taskMode);
-}
-
-static void workerGlobalScopeDidReceiveCachedMetadata(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, PassOwnPtr<Vector<char> > vectorData)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- workerClientWrapper->didReceiveCachedMetadata(vectorData->data(), vectorData->size());
+ m_clientBridge->didDownloadData(dataLength);
}
void WorkerThreadableLoader::MainThreadBridge::didReceiveCachedMetadata(const char* data, int dataLength)
{
- OwnPtr<Vector<char> > vector = adoptPtr(new Vector<char>(dataLength)); // needs to be an OwnPtr for usage with createCallbackTask.
- memcpy(vector->data(), data, dataLength);
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidReceiveCachedMetadata, m_workerClientWrapper, vector.release()), m_taskMode);
-}
-
-static void workerGlobalScopeDidFinishLoading(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, unsigned long identifier, double finishTime)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- workerClientWrapper->didFinishLoading(identifier, finishTime);
+ m_clientBridge->didReceiveCachedMetadata(data, dataLength);
}
void WorkerThreadableLoader::MainThreadBridge::didFinishLoading(unsigned long identifier, double finishTime)
{
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFinishLoading, m_workerClientWrapper, identifier, finishTime), m_taskMode);
-}
-
-static void workerGlobalScopeDidFail(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- workerClientWrapper->didFail(error);
+ m_clientBridge->didFinishLoading(identifier, finishTime);
}
void WorkerThreadableLoader::MainThreadBridge::didFail(const ResourceError& error)
{
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFail, m_workerClientWrapper, error), m_taskMode);
-}
-
-static void workerGlobalScopeDidFailAccessControlCheck(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper, const ResourceError& error)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- workerClientWrapper->didFailAccessControlCheck(error);
+ m_clientBridge->didFail(error);
}
void WorkerThreadableLoader::MainThreadBridge::didFailAccessControlCheck(const ResourceError& error)
{
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFailAccessControlCheck, m_workerClientWrapper, error), m_taskMode);
-}
-
-static void workerGlobalScopeDidFailRedirectCheck(ExecutionContext* context, PassRefPtr<ThreadableLoaderClientWrapper> workerClientWrapper)
-{
- ASSERT_UNUSED(context, context->isWorkerGlobalScope());
- workerClientWrapper->didFailRedirectCheck();
+ m_clientBridge->didFailAccessControlCheck(error);
}
void WorkerThreadableLoader::MainThreadBridge::didFailRedirectCheck()
{
- m_loaderProxy.postTaskForModeToWorkerGlobalScope(createCallbackTask(&workerGlobalScopeDidFailRedirectCheck, m_workerClientWrapper), m_taskMode);
+ m_clientBridge->didFailRedirectCheck();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h b/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h
index 369babe30cc..c074683acff 100644
--- a/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h
+++ b/chromium/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h
@@ -34,9 +34,9 @@
#include "core/loader/ThreadableLoader.h"
#include "core/loader/ThreadableLoaderClient.h"
#include "core/loader/ThreadableLoaderClientWrapper.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
#include "wtf/Threading.h"
#include "wtf/text/WTFString.h"
@@ -50,28 +50,21 @@ namespace WebCore {
struct CrossThreadResourceResponseData;
struct CrossThreadResourceRequestData;
- class WorkerThreadableLoader : public RefCounted<WorkerThreadableLoader>, public ThreadableLoader {
+ class WorkerThreadableLoader FINAL : public ThreadableLoader {
WTF_MAKE_FAST_ALLOCATED;
public:
- static void loadResourceSynchronously(WorkerGlobalScope*, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&);
- static PassRefPtr<WorkerThreadableLoader> create(WorkerGlobalScope* workerGlobalScope, ThreadableLoaderClient* client, const String& taskMode, const ResourceRequest& request, const ThreadableLoaderOptions& options)
+ static void loadResourceSynchronously(WorkerGlobalScope&, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&);
+ static PassRefPtr<WorkerThreadableLoader> create(WorkerGlobalScope& workerGlobalScope, PassRefPtr<ThreadableLoaderClientWrapper> clientWrapper, PassOwnPtr<ThreadableLoaderClient> clientBridge, const ResourceRequest& request, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions)
{
- return adoptRef(new WorkerThreadableLoader(workerGlobalScope, client, taskMode, request, options));
+ return adoptRef(new WorkerThreadableLoader(workerGlobalScope, clientWrapper, clientBridge, request, options, resourceLoaderOptions));
}
- ~WorkerThreadableLoader();
+ virtual ~WorkerThreadableLoader();
virtual void cancel() OVERRIDE;
bool done() const { return m_workerClientWrapper->done(); }
- using RefCounted<WorkerThreadableLoader>::ref;
- using RefCounted<WorkerThreadableLoader>::deref;
-
- protected:
- virtual void refThreadableLoader() OVERRIDE { ref(); }
- virtual void derefThreadableLoader() OVERRIDE { deref(); }
-
private:
// Creates a loader on the main thread and bridges communication between
// the main thread and the worker context's thread where WorkerThreadableLoader runs.
@@ -92,10 +85,10 @@ namespace WebCore {
// thread do "ThreadableLoaderClientWrapper::ref" (automatically inside of the cross thread copy
// done in createCallbackTask), so the ThreadableLoaderClientWrapper instance is there until all
// tasks are executed.
- class MainThreadBridge : public ThreadableLoaderClient {
+ class MainThreadBridge FINAL : public ThreadableLoaderClient {
public:
// All executed on the worker context's thread.
- MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper>, WorkerLoaderProxy&, const String& taskMode, const ResourceRequest&, const ThreadableLoaderOptions&, const String& outgoingReferrer);
+ MainThreadBridge(PassRefPtr<ThreadableLoaderClientWrapper>, PassOwnPtr<ThreadableLoaderClient>, WorkerLoaderProxy&, const ResourceRequest&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&, const String& outgoingReferrer);
void cancel();
void destroy();
@@ -105,9 +98,9 @@ namespace WebCore {
// All executed on the main thread.
static void mainThreadDestroy(ExecutionContext*, MainThreadBridge*);
- ~MainThreadBridge();
+ virtual ~MainThreadBridge();
- static void mainThreadCreateLoader(ExecutionContext*, MainThreadBridge*, PassOwnPtr<CrossThreadResourceRequestData>, ThreadableLoaderOptions, const String& outgoingReferrer);
+ static void mainThreadCreateLoader(ExecutionContext*, MainThreadBridge*, PassOwnPtr<CrossThreadResourceRequestData>, ThreadableLoaderOptions, ResourceLoaderOptions, const String& outgoingReferrer);
static void mainThreadCancel(ExecutionContext*, MainThreadBridge*);
virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) OVERRIDE;
@@ -121,21 +114,19 @@ namespace WebCore {
// Only to be used on the main thread.
RefPtr<ThreadableLoader> m_mainThreadLoader;
+ OwnPtr<ThreadableLoaderClient> m_clientBridge;
// ThreadableLoaderClientWrapper is to be used on the worker context thread.
// The ref counting is done on either thread.
RefPtr<ThreadableLoaderClientWrapper> m_workerClientWrapper;
- // May be used on either thread.
+ // Used on the worker context thread.
WorkerLoaderProxy& m_loaderProxy;
-
- // For use on the main thread.
- String m_taskMode;
};
- WorkerThreadableLoader(WorkerGlobalScope*, ThreadableLoaderClient*, const String& taskMode, const ResourceRequest&, const ThreadableLoaderOptions&);
+ WorkerThreadableLoader(WorkerGlobalScope&, PassRefPtr<ThreadableLoaderClientWrapper>, PassOwnPtr<ThreadableLoaderClient>, const ResourceRequest&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&);
- RefPtr<WorkerGlobalScope> m_workerGlobalScope;
+ RefPtrWillBePersistent<WorkerGlobalScope> m_workerGlobalScope;
RefPtr<ThreadableLoaderClientWrapper> m_workerClientWrapper;
MainThreadBridge& m_bridge;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp
index 862f37a668e..1cfe13403c5 100644
--- a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp
+++ b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp
@@ -30,13 +30,13 @@
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/events/EventListener.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
namespace WebCore {
-ApplicationCache::ApplicationCache(Frame* frame)
+ApplicationCache::ApplicationCache(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
diff --git a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h
index 405ad35b75e..3f2efec95d3 100644
--- a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h
+++ b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h
@@ -28,9 +28,9 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/events/EventTarget.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/loader/appcache/ApplicationCacheHost.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -38,14 +38,18 @@
namespace WebCore {
class ExceptionState;
-class Frame;
+class LocalFrame;
class KURL;
-class ApplicationCache : public ScriptWrappable, public RefCounted<ApplicationCache>, public EventTargetWithInlineData, public DOMWindowProperty {
+class ApplicationCache FINAL : public RefCountedWillBeRefCountedGarbageCollected<ApplicationCache>, public ScriptWrappable, public EventTargetWithInlineData, public DOMWindowProperty {
REFCOUNTED_EVENT_TARGET(ApplicationCache);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(ApplicationCache);
public:
- static PassRefPtr<ApplicationCache> create(Frame* frame) { return adoptRef(new ApplicationCache(frame)); }
- ~ApplicationCache() { ASSERT(!m_frame); }
+ static PassRefPtrWillBeRawPtr<ApplicationCache> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeRefCountedGarbageCollected(new ApplicationCache(frame));
+ }
+ virtual ~ApplicationCache() { ASSERT(!m_frame); }
virtual void willDestroyGlobalObjectInFrame() OVERRIDE;
@@ -71,7 +75,7 @@ public:
static const AtomicString& toEventType(ApplicationCacheHost::EventID);
private:
- explicit ApplicationCache(Frame*);
+ explicit ApplicationCache(LocalFrame*);
ApplicationCacheHost* applicationCacheHost() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.idl b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.idl
index 0082d60095f..7f8e07c8140 100644
--- a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.idl
+++ b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.idl
@@ -24,7 +24,8 @@
*/
[
- DoNotCheckConstants
+ DoNotCheckConstants,
+ WillBeGarbageCollected,
] interface ApplicationCache : EventTarget {
// update status
const unsigned short UNCACHED = 0;
diff --git a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp
new file mode 100644
index 00000000000..610649c1dd9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/loader/appcache/ApplicationCacheHost.h"
+
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/events/ApplicationCacheErrorEvent.h"
+#include "core/events/ProgressEvent.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/inspector/InspectorApplicationCacheAgent.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/loader/DocumentLoader.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "core/loader/appcache/ApplicationCache.h"
+#include "core/page/FrameTree.h"
+#include "core/page/Page.h"
+#include "platform/exported/WrappedResourceRequest.h"
+#include "platform/exported/WrappedResourceResponse.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/WebURL.h"
+#include "public/platform/WebURLError.h"
+#include "public/platform/WebURLResponse.h"
+#include "public/platform/WebVector.h"
+
+using namespace blink;
+
+namespace WebCore {
+
+// We provide a custom implementation of this class that calls out to the
+// embedding application instead of using WebCore's built in appcache system.
+// This file replaces webcore/appcache/ApplicationCacheHost.cpp in our build.
+
+ApplicationCacheHost::ApplicationCacheHost(DocumentLoader* documentLoader)
+ : m_domApplicationCache(0)
+ , m_documentLoader(documentLoader)
+ , m_defersEvents(true)
+{
+ ASSERT(m_documentLoader);
+}
+
+ApplicationCacheHost::~ApplicationCacheHost()
+{
+}
+
+void ApplicationCacheHost::willStartLoadingMainResource(ResourceRequest& request)
+{
+ // We defer creating the outer host object to avoid spurious creation/destruction
+ // around creating empty documents. At this point, we're initiating a main resource
+ // load for the document, so its for real.
+
+ if (!isApplicationCacheEnabled())
+ return;
+
+ ASSERT(m_documentLoader->frame());
+ LocalFrame& frame = *m_documentLoader->frame();
+ m_host = frame.loader().client()->createApplicationCacheHost(this);
+ if (m_host) {
+ WrappedResourceRequest wrapped(request);
+
+ const WebApplicationCacheHost* spawningHost = 0;
+ Frame* spawningFrame = frame.tree().parent();
+ if (!spawningFrame || !spawningFrame->isLocalFrame())
+ spawningFrame = frame.loader().opener();
+ if (!spawningFrame || !spawningFrame->isLocalFrame())
+ spawningFrame = &frame;
+ if (DocumentLoader* spawningDocLoader = toLocalFrame(spawningFrame)->loader().documentLoader())
+ spawningHost = spawningDocLoader->applicationCacheHost() ? spawningDocLoader->applicationCacheHost()->m_host.get() : 0;
+
+ m_host->willStartMainResourceRequest(wrapped, spawningHost);
+ }
+
+ // NOTE: The semantics of this method, and others in this interface, are subtly different
+ // than the method names would suggest. For example, in this method never returns an appcached
+ // response in the SubstituteData out argument, instead we return the appcached response thru
+ // the usual resource loading pipeline.
+}
+
+void ApplicationCacheHost::selectCacheWithoutManifest()
+{
+ if (m_host)
+ m_host->selectCacheWithoutManifest();
+}
+
+void ApplicationCacheHost::selectCacheWithManifest(const KURL& manifestURL)
+{
+ if (m_host && !m_host->selectCacheWithManifest(manifestURL)) {
+ // It's a foreign entry, restart the current navigation from the top
+ // of the navigation algorithm. The navigation will not result in the
+ // same resource being loaded, because "foreign" entries are never picked
+ // during navigation.
+ // see WebCore::ApplicationCacheGroup::selectCache()
+ LocalFrame* frame = m_documentLoader->frame();
+ frame->navigationScheduler().scheduleLocationChange(frame->document(), frame->document()->url(), Referrer(frame->document()->referrer(), frame->document()->referrerPolicy()));
+ }
+}
+
+void ApplicationCacheHost::didReceiveResponseForMainResource(const ResourceResponse& response)
+{
+ if (m_host) {
+ WrappedResourceResponse wrapped(response);
+ m_host->didReceiveResponseForMainResource(wrapped);
+ }
+}
+
+void ApplicationCacheHost::mainResourceDataReceived(const char* data, int length)
+{
+ if (m_host)
+ m_host->didReceiveDataForMainResource(data, length);
+}
+
+void ApplicationCacheHost::failedLoadingMainResource()
+{
+ if (m_host)
+ m_host->didFinishLoadingMainResource(false);
+}
+
+void ApplicationCacheHost::finishedLoadingMainResource()
+{
+ if (m_host)
+ m_host->didFinishLoadingMainResource(true);
+}
+
+void ApplicationCacheHost::willStartLoadingResource(ResourceRequest& request)
+{
+ if (m_host) {
+ WrappedResourceRequest wrapped(request);
+ m_host->willStartSubResourceRequest(wrapped);
+ }
+}
+
+void ApplicationCacheHost::setApplicationCache(ApplicationCache* domApplicationCache)
+{
+ ASSERT(!m_domApplicationCache || !domApplicationCache);
+ m_domApplicationCache = domApplicationCache;
+}
+
+void ApplicationCacheHost::notifyApplicationCache(EventID id, int progressTotal, int progressDone, blink::WebApplicationCacheHost::ErrorReason errorReason, const String& errorURL, int errorStatus, const String& errorMessage)
+{
+ if (id != PROGRESS_EVENT)
+ InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader->frame());
+
+ if (m_defersEvents) {
+ // Event dispatching is deferred until document.onload has fired.
+ m_deferredEvents.append(DeferredEvent(id, progressTotal, progressDone, errorReason, errorURL, errorStatus, errorMessage));
+ return;
+ }
+ dispatchDOMEvent(id, progressTotal, progressDone, errorReason, errorURL, errorStatus, errorMessage);
+}
+
+ApplicationCacheHost::CacheInfo ApplicationCacheHost::applicationCacheInfo()
+{
+ if (!m_host)
+ return CacheInfo(KURL(), 0, 0, 0);
+
+ blink::WebApplicationCacheHost::CacheInfo webInfo;
+ m_host->getAssociatedCacheInfo(&webInfo);
+ return CacheInfo(webInfo.manifestURL, webInfo.creationTime, webInfo.updateTime, webInfo.totalSize);
+}
+
+void ApplicationCacheHost::fillResourceList(ResourceInfoList* resources)
+{
+ if (!m_host)
+ return;
+
+ blink::WebVector<blink::WebApplicationCacheHost::ResourceInfo> webResources;
+ m_host->getResourceList(&webResources);
+ for (size_t i = 0; i < webResources.size(); ++i) {
+ resources->append(ResourceInfo(
+ webResources[i].url, webResources[i].isMaster, webResources[i].isManifest, webResources[i].isFallback,
+ webResources[i].isForeign, webResources[i].isExplicit, webResources[i].size));
+ }
+}
+
+void ApplicationCacheHost::stopDeferringEvents()
+{
+ RefPtr<DocumentLoader> protect(documentLoader());
+ for (unsigned i = 0; i < m_deferredEvents.size(); ++i) {
+ const DeferredEvent& deferred = m_deferredEvents[i];
+ dispatchDOMEvent(deferred.eventID, deferred.progressTotal, deferred.progressDone, deferred.errorReason, deferred.errorURL, deferred.errorStatus, deferred.errorMessage);
+ }
+ m_deferredEvents.clear();
+ m_defersEvents = false;
+}
+
+void ApplicationCacheHost::dispatchDOMEvent(EventID id, int progressTotal, int progressDone, blink::WebApplicationCacheHost::ErrorReason errorReason, const String& errorURL, int errorStatus, const String& errorMessage)
+{
+ if (m_domApplicationCache) {
+ const AtomicString& eventType = ApplicationCache::toEventType(id);
+ RefPtrWillBeRawPtr<Event> event = nullptr;
+ if (id == PROGRESS_EVENT)
+ event = ProgressEvent::create(eventType, true, progressDone, progressTotal);
+ else if (id == ERROR_EVENT)
+ event = ApplicationCacheErrorEvent::create(errorReason, errorURL, errorStatus, errorMessage);
+ else
+ event = Event::create(eventType);
+ m_domApplicationCache->dispatchEvent(event, ASSERT_NO_EXCEPTION);
+ }
+}
+
+ApplicationCacheHost::Status ApplicationCacheHost::status() const
+{
+ return m_host ? static_cast<Status>(m_host->status()) : UNCACHED;
+}
+
+bool ApplicationCacheHost::update()
+{
+ return m_host ? m_host->startUpdate() : false;
+}
+
+bool ApplicationCacheHost::swapCache()
+{
+ bool success = m_host ? m_host->swapCache() : false;
+ if (success)
+ InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader->frame());
+ return success;
+}
+
+void ApplicationCacheHost::abort()
+{
+ if (m_host)
+ m_host->abort();
+}
+
+bool ApplicationCacheHost::isApplicationCacheEnabled()
+{
+ ASSERT(m_documentLoader->frame());
+ return m_documentLoader->frame()->settings() && m_documentLoader->frame()->settings()->offlineWebApplicationCacheEnabled();
+}
+
+void ApplicationCacheHost::didChangeCacheAssociation()
+{
+ // FIXME: Prod the inspector to update its notion of what cache the page is using.
+}
+
+void ApplicationCacheHost::notifyEventListener(blink::WebApplicationCacheHost::EventID eventID)
+{
+ notifyApplicationCache(static_cast<ApplicationCacheHost::EventID>(eventID), 0, 0, blink::WebApplicationCacheHost::UnknownError, String(), 0, String());
+}
+
+void ApplicationCacheHost::notifyProgressEventListener(const blink::WebURL&, int progressTotal, int progressDone)
+{
+ notifyApplicationCache(PROGRESS_EVENT, progressTotal, progressDone, blink::WebApplicationCacheHost::UnknownError, String(), 0, String());
+}
+
+void ApplicationCacheHost::notifyErrorEventListener(blink::WebApplicationCacheHost::ErrorReason reason, const blink::WebURL& url, int status, const blink::WebString& message)
+{
+ notifyApplicationCache(ERROR_EVENT, 0, 0, reason, url.string(), status, message);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h
index 140558900e3..47ebab0182e 100644
--- a/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h
+++ b/chromium/third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.h
@@ -32,6 +32,7 @@
#define ApplicationCacheHost_h
#include "platform/weborigin/KURL.h"
+#include "public/platform/WebApplicationCacheHostClient.h"
#include "wtf/Deque.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassRefPtr.h"
@@ -41,16 +42,15 @@
namespace WebCore {
class ApplicationCache;
class DocumentLoader;
- class Frame;
+ class LocalFrame;
class ResourceLoader;
class ResourceError;
class ResourceRequest;
class ResourceResponse;
class SubstituteData;
- class ApplicationCacheHostInternal;
- class ApplicationCacheHost {
- WTF_MAKE_NONCOPYABLE(ApplicationCacheHost); WTF_MAKE_FAST_ALLOCATED;
+ class ApplicationCacheHost : public blink::WebApplicationCacheHostClient {
+ WTF_MAKE_NONCOPYABLE(ApplicationCacheHost);
public:
// The Status numeric values are specified in the HTML5 spec.
enum Status {
@@ -105,8 +105,8 @@ namespace WebCore {
typedef Vector<ResourceInfo> ResourceInfoList;
- ApplicationCacheHost(DocumentLoader*);
- ~ApplicationCacheHost();
+ explicit ApplicationCacheHost(DocumentLoader*);
+ virtual ~ApplicationCacheHost();
void selectCacheWithoutManifest();
void selectCacheWithManifest(const KURL& manifestURL);
@@ -125,7 +125,7 @@ namespace WebCore {
void abort();
void setApplicationCache(ApplicationCache*);
- void notifyApplicationCache(EventID, int progressTotal, int progressDone);
+ void notifyApplicationCache(EventID, int progressTotal, int progressDone, blink::WebApplicationCacheHost::ErrorReason, const String& errorURL, int errorStatus, const String& errorMessage);
void stopDeferringEvents(); // Also raises the events that have been queued up.
@@ -133,6 +133,12 @@ namespace WebCore {
CacheInfo applicationCacheInfo();
private:
+ // WebApplicationCacheHostClient implementation
+ virtual void didChangeCacheAssociation() OVERRIDE FINAL;
+ virtual void notifyEventListener(blink::WebApplicationCacheHost::EventID) OVERRIDE FINAL;
+ virtual void notifyProgressEventListener(const blink::WebURL&, int progressTotal, int progressDone) OVERRIDE FINAL;
+ virtual void notifyErrorEventListener(blink::WebApplicationCacheHost::ErrorReason, const blink::WebURL&, int status, const blink::WebString& message) OVERRIDE FINAL;
+
bool isApplicationCacheEnabled();
DocumentLoader* documentLoader() const { return m_documentLoader; }
@@ -140,7 +146,20 @@ namespace WebCore {
EventID eventID;
int progressTotal;
int progressDone;
- DeferredEvent(EventID id, int total, int done) : eventID(id), progressTotal(total), progressDone(done) { }
+ blink::WebApplicationCacheHost::ErrorReason errorReason;
+ String errorURL;
+ int errorStatus;
+ String errorMessage;
+ DeferredEvent(EventID id, int progressTotal, int progressDone, blink::WebApplicationCacheHost::ErrorReason errorReason, const String& errorURL, int errorStatus, const String& errorMessage)
+ : eventID(id)
+ , progressTotal(progressTotal)
+ , progressDone(progressDone)
+ , errorReason(errorReason)
+ , errorURL(errorURL)
+ , errorStatus(errorStatus)
+ , errorMessage(errorMessage)
+ {
+ }
};
ApplicationCache* m_domApplicationCache;
@@ -148,10 +167,9 @@ namespace WebCore {
bool m_defersEvents; // Events are deferred until after document onload.
Vector<DeferredEvent> m_deferredEvents;
- void dispatchDOMEvent(EventID, int progressTotal, int progressDone);
+ void dispatchDOMEvent(EventID, int progressTotal, int progressDone, blink::WebApplicationCacheHost::ErrorReason, const String& errorURL, int errorStatus, const String& errorMessage);
- friend class ApplicationCacheHostInternal;
- OwnPtr<ApplicationCacheHostInternal> m_internal;
+ OwnPtr<blink::WebApplicationCacheHost> m_host;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/make_core_derived_sources.xml b/chromium/third_party/WebKit/Source/core/make_core_derived_sources.xml
deleted file mode 100644
index c69aaa610bf..00000000000
--- a/chromium/third_party/WebKit/Source/core/make_core_derived_sources.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:transformCallback="Microsoft.Cpp.Dev10.ConvertPropertyCallback" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
- <Rule DisplayName="bison" Name="bison" Order="200" PageTemplate="tool">
- <Rule.DataSource>
- <DataSource ItemType="bison" Persistence="ProjectFile"/>
- </Rule.DataSource>
- <Rule.Categories>
- <Category Name="General">
- <Category.DisplayName>
- <sys:String>General</sys:String>
- </Category.DisplayName>
- </Category>
- <Category Name="Command Line" Subtype="CommandLine">
- <Category.DisplayName>
- <sys:String>Command Line</sys:String>
- </Category.DisplayName>
- </Category>
- </Rule.Categories>
- <StringListProperty Category="Command Line" IsRequired="true" Name="Inputs" Switch=" ">
- <StringListProperty.DataSource>
- <DataSource ItemType="bison" Persistence="ProjectFile" SourceType="Item"/>
- </StringListProperty.DataSource>
- </StringListProperty>
- <StringProperty DisplayName="Command Line" IncludeInCommandLine="False" Name="CommandLineTemplate" Visible="False"/>
- <DynamicEnumProperty Category="General" EnumProvider="Targets" IncludeInCommandLine="False" Name="bisonBeforeTargets">
- <DynamicEnumProperty.DisplayName>
- <sys:String>Execute Before</sys:String>
- </DynamicEnumProperty.DisplayName>
- <DynamicEnumProperty.Description>
- <sys:String>Specifies the targets for the build customization to run before.</sys:String>
- </DynamicEnumProperty.Description>
- <DynamicEnumProperty.ProviderSettings>
- <NameValuePair Name="Exclude" Value="^bisonBeforeTargets|^Compute"/>
- </DynamicEnumProperty.ProviderSettings>
- <DynamicEnumProperty.DataSource>
- <DataSource HasConfigurationCondition="true" Persistence="ProjectFile"/>
- </DynamicEnumProperty.DataSource>
- </DynamicEnumProperty>
- <DynamicEnumProperty Category="General" EnumProvider="Targets" IncludeInCommandLine="False" Name="bisonAfterTargets">
- <DynamicEnumProperty.DisplayName>
- <sys:String>Execute After</sys:String>
- </DynamicEnumProperty.DisplayName>
- <DynamicEnumProperty.Description>
- <sys:String>Specifies the targets for the build customization to run after.</sys:String>
- </DynamicEnumProperty.Description>
- <DynamicEnumProperty.ProviderSettings>
- <NameValuePair Name="Exclude" Value="^bisonAfterTargets|^Compute"/>
- </DynamicEnumProperty.ProviderSettings>
- <DynamicEnumProperty.DataSource>
- <DataSource HasConfigurationCondition="true" ItemType="" Persistence="ProjectFile"/>
- </DynamicEnumProperty.DataSource>
- </DynamicEnumProperty>
- <StringListProperty DisplayName="Outputs" IncludeInCommandLine="False" Name="Outputs" Visible="False"/>
- <StringProperty DisplayName="Execution Description" IncludeInCommandLine="False" Name="ExecutionDescription" Visible="False"/>
- <StringListProperty DisplayName="Additional Dependencies" IncludeInCommandLine="False" Name="AdditionalDependencies" Visible="false"/>
- <StringProperty Category="Command Line" Name="AdditionalOptions" Subtype="AdditionalOptions">
- <StringProperty.DisplayName>
- <sys:String>Additional Options</sys:String>
- </StringProperty.DisplayName>
- <StringProperty.Description>
- <sys:String>Additional Options</sys:String>
- </StringProperty.Description>
- </StringProperty>
- </Rule>
- <ItemType DisplayName="bison" Name="bison"/>
- <FileExtension ContentType="bison" Name="*.y"/>
- <ContentType DisplayName="" ItemType="bison" Name="bison"/>
-</ProjectSchemaDefinitions>
diff --git a/chromium/third_party/WebKit/Source/core/page/AutoscrollController.cpp b/chromium/third_party/WebKit/Source/core/page/AutoscrollController.cpp
index 6c460280b17..b168e004358 100644
--- a/chromium/third_party/WebKit/Source/core/page/AutoscrollController.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/AutoscrollController.cpp
@@ -29,13 +29,14 @@
#include "config.h"
#include "core/page/AutoscrollController.h"
-#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/Chrome.h"
+#include "core/page/EventHandler.h"
#include "core/page/Page.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderBox.h"
+#include "core/rendering/RenderListBox.h"
#include "wtf/CurrentTime.h"
namespace WebCore {
@@ -73,6 +74,8 @@ void AutoscrollController::startAutoscrollForSelection(RenderObject* renderer)
return;
RenderBox* scrollable = RenderBox::findAutoscrollable(renderer);
if (!scrollable)
+ scrollable = renderer->isListBox() ? toRenderListBox(renderer) : 0;
+ if (!scrollable)
return;
m_autoscrollType = AutoscrollForSelection;
m_autoscrollRenderer = scrollable;
@@ -169,7 +172,7 @@ void AutoscrollController::updateDragAndDrop(Node* dropTargetNode, const IntPoin
}
#if OS(WIN)
-void AutoscrollController::handleMouseReleaseForPanScrolling(Frame* frame, const PlatformMouseEvent& mouseEvent)
+void AutoscrollController::handleMouseReleaseForPanScrolling(LocalFrame* frame, const PlatformMouseEvent& mouseEvent)
{
if (!frame->isMainFrame())
return;
diff --git a/chromium/third_party/WebKit/Source/core/page/AutoscrollController.h b/chromium/third_party/WebKit/Source/core/page/AutoscrollController.h
index c66b3a06bc1..62f7fd6a3bb 100644
--- a/chromium/third_party/WebKit/Source/core/page/AutoscrollController.h
+++ b/chromium/third_party/WebKit/Source/core/page/AutoscrollController.h
@@ -32,7 +32,7 @@
namespace WebCore {
class EventHandler;
-class Frame;
+class LocalFrame;
class FrameView;
class Node;
class Page;
@@ -65,7 +65,7 @@ public:
void updateAutoscrollRenderer();
void updateDragAndDrop(Node* targetNode, const IntPoint& eventPosition, double eventTime);
#if OS(WIN)
- void handleMouseReleaseForPanScrolling(Frame*, const PlatformMouseEvent&);
+ void handleMouseReleaseForPanScrolling(LocalFrame*, const PlatformMouseEvent&);
void startPanScrolling(RenderBox*, const IntPoint&);
#endif
diff --git a/chromium/third_party/WebKit/Source/core/page/Chrome.cpp b/chromium/third_party/WebKit/Source/core/page/Chrome.cpp
index 15a47637eb9..296943b9371 100644
--- a/chromium/third_party/WebKit/Source/core/page/Chrome.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/Chrome.cpp
@@ -22,17 +22,16 @@
#include "config.h"
#include "core/page/Chrome.h"
-#include "public/platform/WebScreenInfo.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLInputElement.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
#include "core/page/FrameTree.h"
#include "core/page/Page.h"
-#include "core/page/PageGroupLoadDeferrer.h"
#include "core/page/PopupOpeningObserver.h"
+#include "core/page/ScopedPageLoadDeferrer.h"
#include "core/page/WindowFeatures.h"
#include "core/rendering/HitTestResult.h"
#include "platform/ColorChooser.h"
@@ -40,13 +39,13 @@
#include "platform/FileChooser.h"
#include "platform/geometry/FloatRect.h"
#include "platform/network/DNS.h"
+#include "public/platform/WebScreenInfo.h"
#include "wtf/PassRefPtr.h"
#include "wtf/Vector.h"
namespace WebCore {
using namespace HTMLNames;
-using namespace std;
Chrome::Chrome(Page* page, ChromeClient* client)
: m_page(page)
@@ -57,7 +56,6 @@ Chrome::Chrome(Page* page, ChromeClient* client)
Chrome::~Chrome()
{
- m_client->chromeDestroyed();
}
PassOwnPtr<Chrome> Chrome::create(Page* page, ChromeClient* client)
@@ -81,11 +79,6 @@ void Chrome::scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, con
InspectorInstrumentation::didScroll(m_page);
}
-IntPoint Chrome::screenToRootView(const IntPoint& point) const
-{
- return m_client->screenToRootView(point);
-}
-
IntRect Chrome::rootViewToScreen(const IntRect& rect) const
{
return m_client->rootViewToScreen(rect);
@@ -96,16 +89,11 @@ blink::WebScreenInfo Chrome::screenInfo() const
return m_client->screenInfo();
}
-void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const
+void Chrome::contentsSizeChanged(LocalFrame* frame, const IntSize& size) const
{
m_client->contentsSizeChanged(frame, size);
}
-void Chrome::layoutUpdated(Frame* frame) const
-{
- m_client->layoutUpdated(frame);
-}
-
void Chrome::setWindowRect(const FloatRect& rect) const
{
m_client->setWindowRect(rect);
@@ -126,19 +114,14 @@ void Chrome::focus() const
m_client->focus();
}
-void Chrome::unfocus() const
+bool Chrome::canTakeFocus(FocusType type) const
{
- m_client->unfocus();
+ return m_client->canTakeFocus(type);
}
-bool Chrome::canTakeFocus(FocusDirection direction) const
+void Chrome::takeFocus(FocusType type) const
{
- return m_client->canTakeFocus(direction);
-}
-
-void Chrome::takeFocus(FocusDirection direction) const
-{
- m_client->takeFocus(direction);
+ m_client->takeFocus(type);
}
void Chrome::focusedNodeChanged(Node* node) const
@@ -159,7 +142,9 @@ bool Chrome::canRunModal() const
static bool canRunModalIfDuringPageDismissal(Page* page, ChromeClient::DialogType dialog, const String& message)
{
for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- Document::PageDismissalType dismissal = frame->document()->pageDismissalEventBeingDispatched();
+ if (!frame->isLocalFrame())
+ continue;
+ Document::PageDismissalType dismissal = toLocalFrame(frame)->document()->pageDismissalEventBeingDispatched();
if (dismissal != Document::NoDismissal)
return page->chrome().client().shouldRunModalDialogDuringPageDismissal(dialog, message, dismissal);
}
@@ -173,9 +158,9 @@ bool Chrome::canRunModalNow() const
void Chrome::runModal() const
{
- // Defer callbacks in all the other pages in this group, so we don't try to run JavaScript
+ // Defer callbacks in all the other pages, so we don't try to run JavaScript
// in a way that could interact with this view.
- PageGroupLoadDeferrer deferrer(m_page, false);
+ ScopedPageLoadDeferrer deferrer(m_page);
TimerBase::fireTimersInNestedEventLoop();
m_client->runModal();
@@ -215,11 +200,11 @@ bool Chrome::canRunBeforeUnloadConfirmPanel()
return m_client->canRunBeforeUnloadConfirmPanel();
}
-bool Chrome::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
+bool Chrome::runBeforeUnloadConfirmPanel(const String& message, LocalFrame* frame)
{
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
- PageGroupLoadDeferrer deferrer(m_page, true);
+ ScopedPageLoadDeferrer deferrer;
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(m_page, message);
bool ok = m_client->runBeforeUnloadConfirmPanel(message, frame);
@@ -232,14 +217,14 @@ void Chrome::closeWindowSoon()
m_client->closeWindowSoon();
}
-void Chrome::runJavaScriptAlert(Frame* frame, const String& message)
+void Chrome::runJavaScriptAlert(LocalFrame* frame, const String& message)
{
if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::AlertDialog, message))
return;
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
- PageGroupLoadDeferrer deferrer(m_page, true);
+ ScopedPageLoadDeferrer deferrer;
ASSERT(frame);
notifyPopupOpeningObservers();
@@ -249,14 +234,14 @@ void Chrome::runJavaScriptAlert(Frame* frame, const String& message)
InspectorInstrumentation::didRunJavaScriptDialog(cookie);
}
-bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
+bool Chrome::runJavaScriptConfirm(LocalFrame* frame, const String& message)
{
if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::ConfirmDialog, message))
return false;
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
- PageGroupLoadDeferrer deferrer(m_page, true);
+ ScopedPageLoadDeferrer deferrer;
ASSERT(frame);
notifyPopupOpeningObservers();
@@ -267,14 +252,14 @@ bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
return ok;
}
-bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultValue, String& result)
+bool Chrome::runJavaScriptPrompt(LocalFrame* frame, const String& prompt, const String& defaultValue, String& result)
{
if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::PromptDialog, prompt))
return false;
// Defer loads in case the client method runs a new event loop that would
// otherwise cause the load to continue while we're in the middle of executing JavaScript.
- PageGroupLoadDeferrer deferrer(m_page, true);
+ ScopedPageLoadDeferrer deferrer;
ASSERT(frame);
notifyPopupOpeningObservers();
@@ -286,7 +271,7 @@ bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const Strin
return ok;
}
-void Chrome::setStatusbarText(Frame* frame, const String& status)
+void Chrome::setStatusbarText(LocalFrame* frame, const String& status)
{
ASSERT(frame);
m_client->setStatusbarText(status);
@@ -319,7 +304,7 @@ void Chrome::setToolTip(const HitTestResult& result)
// Lastly, for <input type="file"> that allow multiple files, we'll consider a tooltip for the selected filenames
if (toolTip.isEmpty()) {
if (Node* node = result.innerNonSharedNode()) {
- if (node->hasTagName(inputTag)) {
+ if (isHTMLInputElement(*node)) {
HTMLInputElement* input = toHTMLInputElement(node);
toolTip = input->defaultToolTip();
@@ -336,9 +321,12 @@ void Chrome::setToolTip(const HitTestResult& result)
m_client->setToolTip(toolTip, toolTipDirection);
}
-void Chrome::print(Frame* frame)
+void Chrome::print(LocalFrame* frame)
{
- // FIXME: This should have PageGroupLoadDeferrer, like runModal() or runJavaScriptAlert(), becasue it's no different from those.
+ // Defer loads in case the client method runs a new event loop that would
+ // otherwise cause the load to continue while we're in the middle of executing JavaScript.
+ ScopedPageLoadDeferrer deferrer;
+
m_client->print(frame);
}
@@ -347,13 +335,13 @@ void Chrome::enumerateChosenDirectory(FileChooser* fileChooser)
m_client->enumerateChosenDirectory(fileChooser);
}
-PassOwnPtr<ColorChooser> Chrome::createColorChooser(ColorChooserClient* client, const Color& initialColor)
+PassOwnPtr<ColorChooser> Chrome::createColorChooser(LocalFrame* frame, ColorChooserClient* client, const Color& initialColor)
{
notifyPopupOpeningObservers();
- return m_client->createColorChooser(client, initialColor);
+ return m_client->createColorChooser(frame, client, initialColor);
}
-PassRefPtr<DateTimeChooser> Chrome::openDateTimeChooser(DateTimeChooserClient* client, const DateTimeChooserParameters& parameters)
+PassRefPtrWillBeRawPtr<DateTimeChooser> Chrome::openDateTimeChooser(DateTimeChooserClient* client, const DateTimeChooserParameters& parameters)
{
notifyPopupOpeningObservers();
return m_client->openDateTimeChooser(client, parameters);
@@ -365,7 +353,7 @@ void Chrome::openTextDataListChooser(HTMLInputElement& input)
m_client->openTextDataListChooser(input);
}
-void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
+void Chrome::runOpenPanel(LocalFrame* frame, PassRefPtr<FileChooser> fileChooser)
{
notifyPopupOpeningObservers();
m_client->runOpenPanel(frame, fileChooser);
@@ -383,6 +371,7 @@ void Chrome::setCursor(const Cursor& cursor)
void Chrome::scheduleAnimation()
{
+ m_page->animator().setAnimationFramePending();
m_client->scheduleAnimation();
}
@@ -393,7 +382,7 @@ bool Chrome::hasOpenedPopup() const
return m_client->hasOpenedPopup();
}
-PassRefPtr<PopupMenu> Chrome::createPopupMenu(Frame& frame, PopupMenuClient* client) const
+PassRefPtr<PopupMenu> Chrome::createPopupMenu(LocalFrame& frame, PopupMenuClient* client) const
{
notifyPopupOpeningObservers();
return m_client->createPopupMenu(frame, client);
@@ -419,4 +408,9 @@ void Chrome::notifyPopupOpeningObservers() const
observers[i]->willOpenPopup();
}
+void Chrome::willBeDestroyed()
+{
+ m_client->chromeDestroyed();
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/Chrome.h b/chromium/third_party/WebKit/Source/core/page/Chrome.h
index 1c021f062d4..4474dd36726 100644
--- a/chromium/third_party/WebKit/Source/core/page/Chrome.h
+++ b/chromium/third_party/WebKit/Source/core/page/Chrome.h
@@ -23,9 +23,10 @@
#define Chrome_h
#include "core/loader/NavigationPolicy.h"
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
#include "platform/Cursor.h"
#include "platform/HostWindow.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
namespace WebCore {
@@ -37,8 +38,7 @@ class DateTimeChooser;
class DateTimeChooserClient;
class FileChooser;
class FloatRect;
-class Frame;
-class Geolocation;
+class LocalFrame;
class HTMLInputElement;
class HitTestResult;
class IntRect;
@@ -53,9 +53,9 @@ struct DateTimeChooserParameters;
struct ViewportDescription;
struct WindowFeatures;
-class Chrome : public HostWindow {
+class Chrome FINAL : public HostWindow {
public:
- ~Chrome();
+ virtual ~Chrome();
static PassOwnPtr<Chrome> create(Page*, ChromeClient*);
@@ -65,14 +65,12 @@ public:
virtual void invalidateContentsAndRootView(const IntRect&) OVERRIDE;
virtual void invalidateContentsForSlowScroll(const IntRect&) OVERRIDE;
virtual void scroll(const IntSize&, const IntRect&, const IntRect&) OVERRIDE;
- virtual IntPoint screenToRootView(const IntPoint&) const OVERRIDE;
virtual IntRect rootViewToScreen(const IntRect&) const OVERRIDE;
virtual blink::WebScreenInfo screenInfo() const OVERRIDE;
virtual void scheduleAnimation() OVERRIDE;
- void contentsSizeChanged(Frame*, const IntSize&) const;
- void layoutUpdated(Frame*) const;
+ void contentsSizeChanged(LocalFrame*, const IntSize&) const;
void setCursor(const Cursor&);
@@ -82,10 +80,9 @@ public:
FloatRect pageRect() const;
void focus() const;
- void unfocus() const;
- bool canTakeFocus(FocusDirection) const;
- void takeFocus(FocusDirection) const;
+ bool canTakeFocus(FocusType) const;
+ void takeFocus(FocusType) const;
void focusedNodeChanged(Node*) const;
@@ -103,14 +100,14 @@ public:
bool menubarVisible() const;
bool canRunBeforeUnloadConfirmPanel();
- bool runBeforeUnloadConfirmPanel(const String& message, Frame*);
+ bool runBeforeUnloadConfirmPanel(const String& message, LocalFrame*);
void closeWindowSoon();
- void runJavaScriptAlert(Frame*, const String&);
- bool runJavaScriptConfirm(Frame*, const String&);
- bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result);
- void setStatusbarText(Frame*, const String&);
+ void runJavaScriptAlert(LocalFrame*, const String&);
+ bool runJavaScriptConfirm(LocalFrame*, const String&);
+ bool runJavaScriptPrompt(LocalFrame*, const String& message, const String& defaultValue, String& result);
+ void setStatusbarText(LocalFrame*, const String&);
IntRect windowResizerRect() const;
@@ -118,23 +115,25 @@ public:
void setToolTip(const HitTestResult&);
- void print(Frame*);
+ void print(LocalFrame*);
- PassOwnPtr<ColorChooser> createColorChooser(ColorChooserClient*, const Color& initialColor);
- PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&);
+ PassOwnPtr<ColorChooser> createColorChooser(LocalFrame*, ColorChooserClient*, const Color& initialColor);
+ PassRefPtrWillBeRawPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&);
void openTextDataListChooser(HTMLInputElement&);
- void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
+ void runOpenPanel(LocalFrame*, PassRefPtr<FileChooser>);
void enumerateChosenDirectory(FileChooser*);
void dispatchViewportPropertiesDidChange(const ViewportDescription&) const;
bool hasOpenedPopup() const;
- PassRefPtr<PopupMenu> createPopupMenu(Frame&, PopupMenuClient*) const;
+ PassRefPtr<PopupMenu> createPopupMenu(LocalFrame&, PopupMenuClient*) const;
void registerPopupOpeningObserver(PopupOpeningObserver*);
void unregisterPopupOpeningObserver(PopupOpeningObserver*);
+ void willBeDestroyed();
+
private:
Chrome(Page*, ChromeClient*);
void notifyPopupOpeningObservers() const;
diff --git a/chromium/third_party/WebKit/Source/core/page/ChromeClient.h b/chromium/third_party/WebKit/Source/core/page/ChromeClient.h
index 13929c23fa4..96a246ea03a 100644
--- a/chromium/third_party/WebKit/Source/core/page/ChromeClient.h
+++ b/chromium/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -27,14 +27,13 @@
#include "core/loader/FrameLoader.h"
#include "core/loader/NavigationPolicy.h"
#include "core/frame/ConsoleTypes.h"
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
#include "core/rendering/RenderEmbeddedObject.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "platform/Cursor.h"
#include "platform/HostWindow.h"
#include "platform/PopupMenu.h"
#include "platform/PopupMenuClient.h"
-#include "platform/graphics/GraphicsContext.h"
#include "platform/scroll/ScrollTypes.h"
#include "wtf/Forward.h"
#include "wtf/PassOwnPtr.h"
@@ -57,19 +56,19 @@ class Element;
class FileChooser;
class FloatRect;
class Frame;
-class Geolocation;
-class GraphicsContext3D;
+class GraphicsContext;
class GraphicsLayer;
class GraphicsLayerFactory;
class HitTestResult;
+class HTMLFormControlElement;
class HTMLInputElement;
class IntRect;
+class LocalFrame;
class Node;
class Page;
class PagePopup;
class PagePopupClient;
class PagePopupDriver;
-class PopupContainer;
class PopupMenuClient;
class SecurityOrigin;
class Widget;
@@ -90,20 +89,21 @@ public:
virtual FloatRect pageRect() = 0;
virtual void focus() = 0;
- virtual void unfocus() = 0;
- virtual bool canTakeFocus(FocusDirection) = 0;
- virtual void takeFocus(FocusDirection) = 0;
+ virtual bool canTakeFocus(FocusType) = 0;
+ virtual void takeFocus(FocusType) = 0;
virtual void focusedNodeChanged(Node*) = 0;
- // The Frame pointer provides the ChromeClient with context about which
- // Frame wants to create the new Page. Also, the newly created window
+ virtual void focusedFrameChanged(LocalFrame*) = 0;
+
+ // The LocalFrame pointer provides the ChromeClient with context about which
+ // LocalFrame wants to create the new Page. Also, the newly created window
// should not be shown to the user until the ChromeClient of the newly
// created Page has its show method called.
// The FrameLoadRequest parameter is only for ChromeClient to check if the
// request could be fulfilled. The ChromeClient should not load the request.
- virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) = 0;
+ virtual Page* createWindow(LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) = 0;
virtual void show(NavigationPolicy) = 0;
virtual bool canRunModal() = 0;
@@ -124,16 +124,16 @@ public:
virtual void setResizable(bool) = 0;
virtual bool shouldReportDetailedMessageForSource(const String& source) = 0;
- virtual void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID, const String& stackTrace) = 0;
+ virtual void addMessageToConsole(LocalFrame*, MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID, const String& stackTrace) = 0;
virtual bool canRunBeforeUnloadConfirmPanel() = 0;
- virtual bool runBeforeUnloadConfirmPanel(const String& message, Frame*) = 0;
+ virtual bool runBeforeUnloadConfirmPanel(const String& message, LocalFrame*) = 0;
virtual void closeWindowSoon() = 0;
- virtual void runJavaScriptAlert(Frame*, const String&) = 0;
- virtual bool runJavaScriptConfirm(Frame*, const String&) = 0;
- virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result) = 0;
+ virtual void runJavaScriptAlert(LocalFrame*, const String&) = 0;
+ virtual bool runJavaScriptConfirm(LocalFrame*, const String&) = 0;
+ virtual bool runJavaScriptPrompt(LocalFrame*, const String& message, const String& defaultValue, String& result) = 0;
virtual void setStatusbarText(const String&) = 0;
virtual bool tabsToLinks() = 0;
@@ -145,33 +145,29 @@ public:
virtual void invalidateContentsAndRootView(const IntRect&) = 0;
virtual void invalidateContentsForSlowScroll(const IntRect&) = 0;
virtual void scroll(const IntSize&, const IntRect&, const IntRect&) = 0;
- virtual IntPoint screenToRootView(const IntPoint&) const = 0;
virtual IntRect rootViewToScreen(const IntRect&) const = 0;
virtual blink::WebScreenInfo screenInfo() const = 0;
virtual void setCursor(const Cursor&) = 0;
virtual void scheduleAnimation() = 0;
// End methods used by HostWindow.
- virtual bool isCompositorFramePending() const = 0;
-
virtual void dispatchViewportPropertiesDidChange(const ViewportDescription&) const { }
- virtual void contentsSizeChanged(Frame*, const IntSize&) const = 0;
+ virtual void contentsSizeChanged(LocalFrame*, const IntSize&) const = 0;
virtual void deviceOrPageScaleFactorChanged() const { }
- virtual void layoutUpdated(Frame*) const { }
+ virtual void layoutUpdated(LocalFrame*) const { }
virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) = 0;
virtual void setToolTip(const String&, TextDirection) = 0;
- virtual void print(Frame*) = 0;
- virtual bool shouldRubberBandInDirection(ScrollDirection) const = 0;
+ virtual void print(LocalFrame*) = 0;
virtual void annotatedRegionsChanged() = 0;
virtual bool paintCustomOverhangArea(GraphicsContext*, const IntRect&, const IntRect&, const IntRect&) = 0;
- virtual PassOwnPtr<ColorChooser> createColorChooser(ColorChooserClient*, const Color&) = 0;
+ virtual PassOwnPtr<ColorChooser> createColorChooser(LocalFrame*, ColorChooserClient*, const Color&) = 0;
// This function is used for:
// - Mandatory date/time choosers if !ENABLE(INPUT_MULTIPLE_FIELDS_UI)
@@ -179,45 +175,20 @@ public:
// returns true, if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
// - <datalist> UI for date/time input types regardless of
// ENABLE(INPUT_MULTIPLE_FIELDS_UI)
- virtual PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) = 0;
+ virtual PassRefPtrWillBeRawPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) = 0;
virtual void openTextDataListChooser(HTMLInputElement&) = 0;
- virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
+ virtual void runOpenPanel(LocalFrame*, PassRefPtr<FileChooser>) = 0;
// Asychronous request to enumerate all files in a directory chosen by the user.
virtual void enumerateChosenDirectory(FileChooser*) = 0;
- // Notification that the given form element has changed. This function
- // will be called frequently, so handling should be very fast.
- virtual void formStateDidChange(const Node*) = 0;
-
// Allows ports to customize the type of graphics layers created by this page.
virtual GraphicsLayerFactory* graphicsLayerFactory() const { return 0; }
// Pass 0 as the GraphicsLayer to detatch the root layer.
- virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) = 0;
- // Sets a flag to specify that the view needs to be updated, so we need
- // to do an eager layout before the drawing.
- virtual void scheduleCompositingLayerFlush() = 0;
- // Returns whether or not the client can render the composited layer,
- // regardless of the settings.
- virtual bool allowsAcceleratedCompositing() const { return true; }
-
- enum CompositingTrigger {
- ThreeDTransformTrigger = 1 << 0,
- VideoTrigger = 1 << 1,
- PluginTrigger = 1 << 2,
- CanvasTrigger = 1 << 3,
- AnimationTrigger = 1 << 4,
- FilterTrigger = 1 << 5,
- ScrollableInnerFrameTrigger = 1 << 6,
- AllTriggers = 0xFFFFFFFF
- };
- typedef unsigned CompositingTriggerFlags;
-
- // Returns a bitfield indicating conditions that can trigger the compositor.
- virtual CompositingTriggerFlags allowedCompositingTriggers() const { return static_cast<CompositingTriggerFlags>(AllTriggers); }
+ virtual void attachRootGraphicsLayer(GraphicsLayer*) = 0;
virtual void enterFullScreenForElement(Element*) { }
virtual void exitFullScreenForElement(Element*) { }
@@ -228,19 +199,11 @@ public:
// Checks if there is an opened popup, called by RenderMenuList::showPopup().
virtual bool hasOpenedPopup() const = 0;
- virtual PassRefPtr<PopupMenu> createPopupMenu(Frame&, PopupMenuClient*) const = 0;
- // Creates a PagePopup object, and shows it beside originBoundsInRootView.
- // The return value can be 0.
- virtual PagePopup* openPagePopup(PagePopupClient*, const IntRect& originBoundsInRootView) = 0;
- virtual void closePagePopup(PagePopup*) = 0;
+ virtual PassRefPtr<PopupMenu> createPopupMenu(LocalFrame&, PopupMenuClient*) const = 0;
// For testing.
virtual void setPagePopupDriver(PagePopupDriver*) = 0;
virtual void resetPagePopupDriver() = 0;
- // FIXME: Should these be on a different client interface?
- virtual bool isPasswordGenerationEnabled() const { return false; }
- virtual void openPasswordGenerator(HTMLInputElement*) { }
-
virtual void postAccessibilityNotification(AXObject*, AXObjectCache::AXNotification) { }
virtual String acceptLanguages() = 0;
@@ -252,37 +215,28 @@ public:
};
virtual bool shouldRunModalDialogDuringPageDismissal(const DialogType&, const String&, Document::PageDismissalType) const { return true; }
- virtual void numWheelEventHandlersChanged(unsigned) = 0;
-
virtual bool isSVGImageChromeClient() const { return false; }
virtual bool requestPointerLock() { return false; }
virtual void requestPointerUnlock() { }
- virtual bool isPointerLocked() { return false; }
virtual FloatSize minimumWindowSize() const { return FloatSize(100, 100); };
- virtual bool isEmptyChromeClient() const { return false; }
virtual bool isChromeClientImpl() const { return false; }
- virtual void didAssociateFormControls(const Vector<RefPtr<Element> >&) { };
- virtual void didChangeValueInTextField(HTMLInputElement&) { }
+ virtual void didAssociateFormControls(const WillBeHeapVector<RefPtrWillBeMember<Element> >&) { };
+ virtual void didChangeValueInTextField(HTMLFormControlElement&) { }
virtual void didEndEditingOnTextField(HTMLInputElement&) { }
virtual void handleKeyboardEventOnTextField(HTMLInputElement&, KeyboardEvent&) { }
+ // FIXME: Remove this method once we have input routing in the browser
+ // process. See http://crbug.com/339659.
+ virtual void forwardInputEvent(WebCore::Frame*, WebCore::Event*) { }
+
// Input mehtod editor related functions.
virtual void didCancelCompositionOnSelectionChange() { }
virtual void willSetInputMethodState() { }
-
- // Notifies the client of a new popup widget. The client should place
- // and size the widget with the given bounds, relative to the screen.
- // If handleExternal is true, then drawing and input handling for the
- // popup will be handled by the external embedder.
- virtual void popupOpened(PopupContainer* popupContainer, const IntRect& bounds,
- bool handleExternal) = 0;
-
- // Notifies the client a popup was closed.
- virtual void popupClosed(PopupContainer* popupContainer) = 0;
+ virtual void didUpdateTextOfFocusedElementByNonUserInput() { }
protected:
virtual ~ChromeClient() { }
diff --git a/chromium/third_party/WebKit/Source/core/page/ContextMenuController.cpp b/chromium/third_party/WebKit/Source/core/page/ContextMenuController.cpp
index cf5b8ba4e65..cd8b65b29a1 100644
--- a/chromium/third_party/WebKit/Source/core/page/ContextMenuController.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/ContextMenuController.cpp
@@ -31,10 +31,10 @@
#include "core/events/Event.h"
#include "core/events/MouseEvent.h"
#include "core/dom/Node.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/ContextMenuClient.h"
#include "core/page/ContextMenuProvider.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "platform/ContextMenu.h"
#include "platform/ContextMenuItem.h"
@@ -60,9 +60,9 @@ void ContextMenuController::clearContextMenu()
m_contextMenu.clear();
if (m_menuProvider)
m_menuProvider->contextMenuCleared();
- m_menuProvider = 0;
- m_hitTestResult = HitTestResult();
+ m_menuProvider = nullptr;
m_client->clearContextMenu();
+ m_hitTestResult = HitTestResult();
}
void ContextMenuController::documentDetached(Document* document)
@@ -107,7 +107,7 @@ PassOwnPtr<ContextMenu> ContextMenuController::createContextMenu(Event* event)
MouseEvent* mouseEvent = toMouseEvent(event);
HitTestResult result(mouseEvent->absoluteLocation());
- if (Frame* frame = event->target()->toNode()->document().frame())
+ if (LocalFrame* frame = event->target()->toNode()->document().frame())
result = frame->eventHandler().hitTestResultAtPoint(mouseEvent->absoluteLocation(), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
if (!result.innerNonSharedNode())
diff --git a/chromium/third_party/WebKit/Source/core/page/CreateWindow.cpp b/chromium/third_party/WebKit/Source/core/page/CreateWindow.cpp
index 6f588fa4430..0c7b8f7d1cf 100644
--- a/chromium/third_party/WebKit/Source/core/page/CreateWindow.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/CreateWindow.cpp
@@ -28,13 +28,14 @@
#include "core/page/CreateWindow.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
#include "core/page/FocusController.h"
#include "core/page/Page.h"
-#include "core/frame/Settings.h"
#include "core/page/WindowFeatures.h"
#include "platform/network/ResourceRequest.h"
#include "platform/weborigin/KURL.h"
@@ -43,12 +44,12 @@
namespace WebCore {
-static Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, bool& created)
+static LocalFrame* createWindow(LocalFrame& openerFrame, LocalFrame& lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, bool& created)
{
ASSERT(!features.dialog || request.frameName().isEmpty());
if (!request.frameName().isEmpty() && request.frameName() != "_blank" && policy == NavigationPolicyIgnore) {
- if (Frame* frame = lookupFrame->loader().findFrameForNavigation(request.frameName(), openerFrame->document())) {
+ if (LocalFrame* frame = lookupFrame.loader().findFrameForNavigation(request.frameName(), openerFrame.document())) {
if (request.frameName() != "_self")
frame->page()->focusController().setFocusedFrame(frame);
created = false;
@@ -57,40 +58,42 @@ static Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLo
}
// Sandboxed frames cannot open new auxiliary browsing contexts.
- if (openerFrame->document()->isSandboxed(SandboxPopups)) {
+ if (openerFrame.document()->isSandboxed(SandboxPopups)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
- openerFrame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
+ openerFrame.document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
return 0;
}
- if (openerFrame->settings() && !openerFrame->settings()->supportsMultipleWindows()) {
+ if (openerFrame.settings() && !openerFrame.settings()->supportsMultipleWindows()) {
created = false;
- return openerFrame->tree().top();
+ if (!openerFrame.tree().top()->isLocalFrame())
+ return 0;
+ return toLocalFrame(openerFrame.tree().top());
}
- Page* oldPage = openerFrame->page();
+ Page* oldPage = openerFrame.page();
if (!oldPage)
return 0;
- Page* page = oldPage->chrome().client().createWindow(openerFrame, request, features, policy, shouldSendReferrer);
- if (!page)
+ Page* page = oldPage->chrome().client().createWindow(&openerFrame, request, features, policy, shouldSendReferrer);
+ if (!page || !page->mainFrame()->isLocalFrame())
return 0;
+ FrameHost* host = &page->frameHost();
- Frame* frame = page->mainFrame();
-
- frame->loader().forceSandboxFlags(openerFrame->document()->sandboxFlags());
+ ASSERT(page->mainFrame());
+ LocalFrame& frame = *page->deprecatedLocalMainFrame();
if (request.frameName() != "_blank")
- frame->tree().setName(request.frameName());
+ frame.tree().setName(request.frameName());
- page->chrome().setWindowFeatures(features);
+ host->chrome().setWindowFeatures(features);
// 'x' and 'y' specify the location of the window, while 'width' and 'height'
// specify the size of the viewport. We can only resize the window, so adjust
// for the difference between the window size and the viewport size.
- FloatRect windowRect = page->chrome().windowRect();
- FloatSize viewportSize = page->chrome().pageRect().size();
+ FloatRect windowRect = host->chrome().windowRect();
+ FloatSize viewportSize = host->chrome().pageRect().size();
if (features.xSet)
windowRect.setX(features.x);
@@ -102,68 +105,71 @@ static Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLo
windowRect.setHeight(features.height + (windowRect.height() - viewportSize.height()));
// Ensure non-NaN values, minimum size as well as being within valid screen area.
- FloatRect newWindowRect = DOMWindow::adjustWindowRect(page, windowRect);
+ FloatRect newWindowRect = LocalDOMWindow::adjustWindowRect(frame, windowRect);
- page->chrome().setWindowRect(newWindowRect);
- page->chrome().show(policy);
+ host->chrome().setWindowRect(newWindowRect);
+ host->chrome().show(policy);
created = true;
- return frame;
+ return &frame;
}
-Frame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures,
- DOMWindow* activeWindow, Frame* firstFrame, Frame* openerFrame, DOMWindow::PrepareDialogFunction function, void* functionContext)
+LocalFrame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures,
+ LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame, LocalDOMWindow::PrepareDialogFunction function, void* functionContext)
{
- Frame* activeFrame = activeWindow->frame();
+ LocalFrame* activeFrame = callingWindow.frame();
+ ASSERT(activeFrame);
- KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString()) : firstFrame->document()->completeURL(urlString);
+ KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString()) : firstFrame.document()->completeURL(urlString);
if (!completedURL.isEmpty() && !completedURL.isValid()) {
// Don't expose client code to invalid URLs.
- activeWindow->printErrorMessage("Unable to open a window with invalid URL '" + completedURL.string() + "'.\n");
+ callingWindow.printErrorMessage("Unable to open a window with invalid URL '" + completedURL.string() + "'.\n");
return 0;
}
// For whatever reason, Firefox uses the first frame to determine the outgoingReferrer. We replicate that behavior here.
- String referrer = SecurityPolicy::generateReferrerHeader(firstFrame->document()->referrerPolicy(), completedURL, firstFrame->document()->outgoingReferrer());
+ Referrer referrer(SecurityPolicy::generateReferrerHeader(firstFrame.document()->referrerPolicy(), completedURL, firstFrame.document()->outgoingReferrer()), firstFrame.document()->referrerPolicy());
ResourceRequest request(completedURL, referrer);
- FrameLoader::addHTTPOriginIfNeeded(request, firstFrame->document()->outgoingOrigin());
- FrameLoadRequest frameRequest(activeWindow->document(), request, frameName);
+ FrameLoader::addHTTPOriginIfNeeded(request, AtomicString(firstFrame.document()->outgoingOrigin()));
+ FrameLoadRequest frameRequest(callingWindow.document(), request, frameName);
// We pass the opener frame for the lookupFrame in case the active frame is different from
// the opener frame, and the name references a frame relative to the opener frame.
bool created;
- Frame* newFrame = createWindow(activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, MaybeSendReferrer, created);
+ LocalFrame* newFrame = createWindow(*activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, MaybeSendReferrer, created);
if (!newFrame)
return 0;
- newFrame->loader().setOpener(openerFrame);
- newFrame->page()->setOpenedByDOM();
+ if (newFrame != &openerFrame && newFrame != openerFrame.tree().top())
+ newFrame->loader().forceSandboxFlags(openerFrame.document()->sandboxFlags());
+
+ newFrame->loader().setOpener(&openerFrame);
- if (newFrame->domWindow()->isInsecureScriptAccess(activeWindow, completedURL))
+ if (newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedURL))
return newFrame;
if (function)
function(newFrame->domWindow(), functionContext);
if (created) {
- FrameLoadRequest request(activeWindow->document(), ResourceRequest(completedURL, referrer));
+ FrameLoadRequest request(callingWindow.document(), ResourceRequest(completedURL, referrer));
newFrame->loader().load(request);
} else if (!urlString.isEmpty()) {
- newFrame->navigationScheduler().scheduleLocationChange(activeWindow->document(), completedURL.string(), referrer, false);
+ newFrame->navigationScheduler().scheduleLocationChange(callingWindow.document(), completedURL.string(), referrer, false);
}
return newFrame;
}
-void createWindowForRequest(const FrameLoadRequest& request, Frame* openerFrame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer)
+void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerFrame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer)
{
- if (openerFrame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
+ if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
return;
- if (openerFrame->document() && openerFrame->document()->isSandboxed(SandboxPopups))
+ if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPopups))
return;
- if (!DOMWindow::allowPopUp(openerFrame))
+ if (!LocalDOMWindow::allowPopUp(openerFrame))
return;
if (policy == NavigationPolicyCurrentTab)
@@ -171,13 +177,12 @@ void createWindowForRequest(const FrameLoadRequest& request, Frame* openerFrame,
WindowFeatures features;
bool created;
- Frame* newFrame = createWindow(openerFrame, openerFrame, request, features, policy, shouldSendReferrer, created);
+ LocalFrame* newFrame = createWindow(openerFrame, openerFrame, request, features, policy, shouldSendReferrer, created);
if (!newFrame)
return;
- newFrame->page()->setOpenedByDOM();
if (shouldSendReferrer == MaybeSendReferrer) {
- newFrame->loader().setOpener(openerFrame);
- newFrame->document()->setReferrerPolicy(openerFrame->document()->referrerPolicy());
+ newFrame->loader().setOpener(&openerFrame);
+ newFrame->document()->setReferrerPolicy(openerFrame.document()->referrerPolicy());
}
FrameLoadRequest newRequest(0, request.resourceRequest());
newRequest.setFormState(request.formState());
diff --git a/chromium/third_party/WebKit/Source/core/page/CreateWindow.h b/chromium/third_party/WebKit/Source/core/page/CreateWindow.h
index 1c2f3537a70..c75e7f5b3d0 100644
--- a/chromium/third_party/WebKit/Source/core/page/CreateWindow.h
+++ b/chromium/third_party/WebKit/Source/core/page/CreateWindow.h
@@ -27,20 +27,20 @@
#ifndef CreateWindow_h
#define CreateWindow_h
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/loader/FrameLoaderTypes.h"
#include "core/loader/NavigationPolicy.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
struct FrameLoadRequest;
struct WindowFeatures;
-Frame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&,
- DOMWindow* activeWindow, Frame* firstFrame, Frame* openerFrame, DOMWindow::PrepareDialogFunction = 0, void* functionContext = 0);
+LocalFrame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&,
+ LocalDOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame, LocalDOMWindow::PrepareDialogFunction = 0, void* functionContext = 0);
-void createWindowForRequest(const FrameLoadRequest&, Frame* openerFrame, NavigationPolicy, ShouldSendReferrer);
+void createWindowForRequest(const FrameLoadRequest&, LocalFrame& openerFrame, NavigationPolicy, ShouldSendReferrer);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/DOMSelection.cpp b/chromium/third_party/WebKit/Source/core/page/DOMSelection.cpp
index 4de89dec388..c4cc8aff203 100644
--- a/chromium/third_party/WebKit/Source/core/page/DOMSelection.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/DOMSelection.cpp
@@ -31,6 +31,7 @@
#include "config.h"
#include "core/page/DOMSelection.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/Document.h"
@@ -41,12 +42,12 @@
#include "core/editing/FrameSelection.h"
#include "core/editing/TextIterator.h"
#include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-static Node* selectionShadowAncestor(Frame* frame)
+static Node* selectionShadowAncestor(LocalFrame* frame)
{
Node* node = frame->selection().selection().base().anchorNode();
if (!node)
@@ -59,7 +60,7 @@ static Node* selectionShadowAncestor(Frame* frame)
}
DOMSelection::DOMSelection(const TreeScope* treeScope)
- : DOMWindowProperty(treeScope->rootNode()->document().frame())
+ : DOMWindowProperty(treeScope->rootNode().document().frame())
, m_treeScope(treeScope)
{
ScriptWrappable::init(this);
@@ -67,7 +68,7 @@ DOMSelection::DOMSelection(const TreeScope* treeScope)
void DOMSelection::clearTreeScope()
{
- m_treeScope = 0;
+ m_treeScope = nullptr;
}
const VisibleSelection& DOMSelection::visibleSelection() const
@@ -195,6 +196,7 @@ int DOMSelection::rangeCount() const
void DOMSelection::collapse(Node* node, int offset, ExceptionState& exceptionState)
{
+ ASSERT(node);
if (!m_frame)
return;
@@ -205,9 +207,19 @@ void DOMSelection::collapse(Node* node, int offset, ExceptionState& exceptionSta
if (!isValidForPosition(node))
return;
+ RefPtrWillBeRawPtr<Range> range = Range::create(node->document());
+ range->setStart(node, offset, exceptionState);
+ if (exceptionState.hadException())
+ return;
+ range->setEnd(node, offset, exceptionState);
+ if (exceptionState.hadException())
+ return;
+ m_frame->selection().setSelectedRange(range.get(), DOWNSTREAM, m_frame->selection().isDirectional() ? FrameSelection::Directional : FrameSelection::NonDirectional);
+}
- // FIXME: Eliminate legacy editing positions
- m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM));
+void DOMSelection::collapse(Node* node, ExceptionState& exceptionState)
+{
+ collapse(node, 0, exceptionState);
}
void DOMSelection::collapseToEnd(ExceptionState& exceptionState)
@@ -272,22 +284,6 @@ void DOMSelection::setBaseAndExtent(Node* baseNode, int baseOffset, Node* extent
m_frame->selection().moveTo(visibleBase, visibleExtent);
}
-void DOMSelection::setPosition(Node* node, int offset, ExceptionState& exceptionState)
-{
- if (!m_frame)
- return;
- if (offset < 0) {
- exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is not a valid offset.");
- return;
- }
-
- if (!isValidForPosition(node))
- return;
-
- // FIXME: Eliminate legacy editing positions
- m_frame->selection().moveTo(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM));
-}
-
void DOMSelection::modify(const String& alterString, const String& directionString, const String& granularityString)
{
if (!m_frame)
@@ -344,7 +340,7 @@ void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState
return;
if (!node) {
- exceptionState.throwDOMException(TypeMismatchError, "The node provided is invalid.");
+ exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return;
}
@@ -352,7 +348,7 @@ void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState
exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is not a valid offset.");
return;
}
- if (offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->childNodeCount())) {
+ if (offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->countChildren())) {
exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is larger than the given node's length.");
return;
}
@@ -364,14 +360,14 @@ void DOMSelection::extend(Node* node, int offset, ExceptionState& exceptionState
m_frame->selection().setExtent(VisiblePosition(createLegacyEditingPosition(node, offset), DOWNSTREAM));
}
-PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState& exceptionState)
{
if (!m_frame)
- return 0;
+ return nullptr;
if (index < 0 || index >= rangeCount()) {
exceptionState.throwDOMException(IndexSizeError, String::number(index) + " is not a valid index.");
- return 0;
+ return nullptr;
}
// If you're hitting this, you've added broken multi-range selection support
@@ -384,8 +380,7 @@ PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState& exceptionS
return Range::create(shadowAncestor->document(), container, offset, container, offset);
}
- const VisibleSelection& selection = m_frame->selection().selection();
- return selection.firstRange();
+ return m_frame->selection().firstRange();
}
void DOMSelection::removeAllRanges()
@@ -395,45 +390,56 @@ void DOMSelection::removeAllRanges()
m_frame->selection().clear();
}
-void DOMSelection::addRange(Range* r)
+void DOMSelection::addRange(Range* newRange)
{
if (!m_frame)
return;
- if (!r)
+
+ // FIXME: Should we throw DOMException for error cases below?
+ if (!newRange) {
+ addConsoleError("The given range is null.");
+ return;
+ }
+
+ if (!newRange->startContainer()) {
+ addConsoleError("The given range has no container. Perhaps 'detach()' has been invoked on it?");
return;
+ }
FrameSelection& selection = m_frame->selection();
if (selection.isNone()) {
- selection.setSelection(VisibleSelection(r));
+ selection.setSelectedRange(newRange, VP_DEFAULT_AFFINITY);
return;
}
- RefPtr<Range> range = selection.selection().toNormalizedRange();
- if (r->compareBoundaryPoints(Range::START_TO_START, range.get(), IGNORE_EXCEPTION) == -1) {
- // We don't support discontiguous selection. We don't do anything if r and range don't intersect.
- if (r->compareBoundaryPoints(Range::START_TO_END, range.get(), IGNORE_EXCEPTION) > -1) {
- if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), IGNORE_EXCEPTION) == -1) {
- // The original range and r intersect.
- selection.setSelection(VisibleSelection(r->startPosition(), range->endPosition(), DOWNSTREAM));
- } else {
- // r contains the original range.
- selection.setSelection(VisibleSelection(r));
- }
- }
- } else {
- // We don't support discontiguous selection. We don't do anything if r and range don't intersect.
- TrackExceptionState exceptionState;
- if (r->compareBoundaryPoints(Range::END_TO_START, range.get(), exceptionState) < 1 && !exceptionState.hadException()) {
- if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), IGNORE_EXCEPTION) == -1) {
- // The original range contains r.
- selection.setSelection(VisibleSelection(range.get()));
- } else {
- // The original range and r intersect.
- selection.setSelection(VisibleSelection(range->startPosition(), r->endPosition(), DOWNSTREAM));
- }
- }
+ RefPtrWillBeRawPtr<Range> originalRange = selection.firstRange();
+
+ if (originalRange->startContainer()->document() != newRange->startContainer()->document()) {
+ addConsoleError("The given range does not belong to the current selection's document.");
+ return;
}
+ if (originalRange->startContainer()->treeScope() != newRange->startContainer()->treeScope()) {
+ addConsoleError("The given range and the current selection belong to two different document fragments.");
+ return;
+ }
+
+ if (originalRange->compareBoundaryPoints(Range::START_TO_END, newRange, ASSERT_NO_EXCEPTION) < 0
+ || newRange->compareBoundaryPoints(Range::START_TO_END, originalRange.get(), ASSERT_NO_EXCEPTION) < 0) {
+ addConsoleError("Discontiguous selection is not supported.");
+ return;
+ }
+
+ // FIXME: "Merge the ranges if they intersect" is Blink-specific behavior; other browsers supporting discontiguous
+ // selection (obviously) keep each Range added and return it in getRangeAt(). But it's unclear if we can really
+ // do the same, since we don't support discontiguous selection. Further discussions at
+ // <https://code.google.com/p/chromium/issues/detail?id=353069>.
+
+ Range* start = originalRange->compareBoundaryPoints(Range::START_TO_START, newRange, ASSERT_NO_EXCEPTION) < 0 ? originalRange.get() : newRange;
+ Range* end = originalRange->compareBoundaryPoints(Range::END_TO_END, newRange, ASSERT_NO_EXCEPTION) < 0 ? newRange : originalRange.get();
+ RefPtrWillBeRawPtr<Range> merged = Range::create(originalRange->startContainer()->document(), start->startContainer(), start->startOffset(), end->endContainer(), end->endOffset());
+ EAffinity affinity = selection.selection().affinity();
+ selection.setSelectedRange(merged.get(), affinity);
}
void DOMSelection::deleteFromDocument()
@@ -446,16 +452,13 @@ void DOMSelection::deleteFromDocument()
if (selection.isNone())
return;
- if (isCollapsed())
- selection.modify(FrameSelection::AlterationExtend, DirectionBackward, CharacterGranularity);
-
- RefPtr<Range> selectedRange = selection.selection().toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> selectedRange = selection.selection().toNormalizedRange();
if (!selectedRange)
return;
selectedRange->deleteContents(ASSERT_NO_EXCEPTION);
- setBaseAndExtent(selectedRange->startContainer(ASSERT_NO_EXCEPTION), selectedRange->startOffset(), selectedRange->startContainer(), selectedRange->startOffset(), ASSERT_NO_EXCEPTION);
+ setBaseAndExtent(selectedRange->startContainer(), selectedRange->startOffset(), selectedRange->startContainer(), selectedRange->startOffset(), ASSERT_NO_EXCEPTION);
}
bool DOMSelection::containsNode(const Node* n, bool allowPartial) const
@@ -469,7 +472,7 @@ bool DOMSelection::containsNode(const Node* n, bool allowPartial) const
return false;
unsigned nodeIndex = n->nodeIndex();
- RefPtr<Range> selectedRange = selection.selection().toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> selectedRange = selection.selection().toNormalizedRange();
ContainerNode* parentNode = n->parentNode();
if (!parentNode)
@@ -478,7 +481,8 @@ bool DOMSelection::containsNode(const Node* n, bool allowPartial) const
TrackExceptionState exceptionState;
bool nodeFullySelected = Range::compareBoundaryPoints(parentNode, nodeIndex, selectedRange->startContainer(), selectedRange->startOffset(), exceptionState) >= 0 && !exceptionState.hadException()
&& Range::compareBoundaryPoints(parentNode, nodeIndex + 1, selectedRange->endContainer(), selectedRange->endOffset(), exceptionState) <= 0 && !exceptionState.hadException();
- ASSERT(!exceptionState.hadException());
+ if (exceptionState.hadException())
+ return false;
if (nodeFullySelected)
return true;
@@ -497,7 +501,7 @@ void DOMSelection::selectAllChildren(Node* n, ExceptionState& exceptionState)
return;
// This doesn't (and shouldn't) select text node characters.
- setBaseAndExtent(n, 0, n, n->childNodeCount(), exceptionState);
+ setBaseAndExtent(n, 0, n, n->countChildren(), exceptionState);
}
String DOMSelection::toString()
@@ -551,4 +555,10 @@ bool DOMSelection::isValidForPosition(Node* node) const
return node->document() == m_frame->document();
}
+void DOMSelection::addConsoleError(const String& message)
+{
+ if (m_treeScope)
+ m_treeScope->document().addConsoleMessage(JSMessageSource, ErrorMessageLevel, message);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/DOMSelection.h b/chromium/third_party/WebKit/Source/core/page/DOMSelection.h
index 0b4adfe0f98..d2502cee534 100644
--- a/chromium/third_party/WebKit/Source/core/page/DOMSelection.h
+++ b/chromium/third_party/WebKit/Source/core/page/DOMSelection.h
@@ -33,6 +33,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -40,16 +41,19 @@
namespace WebCore {
class ExceptionState;
-class Frame;
+class LocalFrame;
class Node;
class Position;
class Range;
class TreeScope;
class VisibleSelection;
-class DOMSelection : public RefCounted<DOMSelection>, public ScriptWrappable, public DOMWindowProperty {
+class DOMSelection FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMSelection>, public ScriptWrappable, public DOMWindowProperty {
public:
- static PassRefPtr<DOMSelection> create(const TreeScope* treeScope) { return adoptRef(new DOMSelection(treeScope)); }
+ static PassRefPtrWillBeRawPtr<DOMSelection> create(const TreeScope* treeScope)
+ {
+ return adoptRefWillBeNoop(new DOMSelection(treeScope));
+ }
void clearTreeScope();
@@ -61,7 +65,6 @@ public:
int extentOffset() const;
String type() const;
void setBaseAndExtent(Node* baseNode, int baseOffset, Node* extentNode, int extentOffset, ExceptionState&);
- void setPosition(Node*, int offset, ExceptionState&);
void modify(const String& alter, const String& direction, const String& granularity);
// Mozilla Selection Object API
@@ -77,10 +80,11 @@ public:
bool isCollapsed() const;
int rangeCount() const;
void collapse(Node*, int offset, ExceptionState&);
+ void collapse(Node*, ExceptionState&);
void collapseToEnd(ExceptionState&);
void collapseToStart(ExceptionState&);
void extend(Node*, int offset, ExceptionState&);
- PassRefPtr<Range> getRangeAt(int, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Range> getRangeAt(int, ExceptionState&);
void removeAllRanges();
void addRange(Range*);
void deleteFromDocument();
@@ -92,9 +96,9 @@ public:
// Microsoft Selection Object API
void empty();
-private:
- const TreeScope* m_treeScope;
+ void trace(Visitor* visitor) { visitor->trace(m_treeScope); }
+private:
explicit DOMSelection(const TreeScope*);
// Convenience method for accessors, does not check m_frame present.
@@ -104,6 +108,10 @@ private:
int shadowAdjustedOffset(const Position&) const;
bool isValidForPosition(Node*) const;
+
+ void addConsoleError(const String& message);
+
+ RawPtrWillBeMember<const TreeScope> m_treeScope;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.cpp b/chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.cpp
index 348c5895ea6..1be6d321876 100644
--- a/chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "core/page/DOMWindowPagePopup.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/page/PagePopupController.h"
namespace WebCore {
@@ -42,34 +42,36 @@ DOMWindowPagePopup::DOMWindowPagePopup(PagePopupClient* popupClient)
ASSERT(popupClient);
}
-DOMWindowPagePopup::~DOMWindowPagePopup()
-{
- m_controller->clearPagePopupClient();
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(DOMWindowPagePopup);
const char* DOMWindowPagePopup::supplementName()
{
return "DOMWindowPagePopup";
}
-PagePopupController* DOMWindowPagePopup::pagePopupController(DOMWindow* window)
+PagePopupController* DOMWindowPagePopup::pagePopupController(LocalDOMWindow& window)
{
- DOMWindowPagePopup* supplement = static_cast<DOMWindowPagePopup*>(from(window, supplementName()));
+ DOMWindowPagePopup* supplement = static_cast<DOMWindowPagePopup*>(from(&window, supplementName()));
ASSERT(supplement);
return supplement->m_controller.get();
}
-void DOMWindowPagePopup::install(DOMWindow* window, PagePopupClient* popupClient)
+void DOMWindowPagePopup::install(LocalDOMWindow& window, PagePopupClient* popupClient)
{
- ASSERT(window);
ASSERT(popupClient);
- provideTo(window, supplementName(), adoptPtr(new DOMWindowPagePopup(popupClient)));
+ provideTo(window, supplementName(), adoptPtrWillBeNoop(new DOMWindowPagePopup(popupClient)));
+}
+
+void DOMWindowPagePopup::uninstall(LocalDOMWindow& window)
+{
+ pagePopupController(window)->clearPagePopupClient();
+ window.removeSupplement(supplementName());
}
-void DOMWindowPagePopup::uninstall(DOMWindow* window)
+void DOMWindowPagePopup::trace(Visitor* visitor)
{
- ASSERT(window);
- window->removeSupplement(supplementName());
+ visitor->trace(m_controller);
+ WillBeHeapSupplement<LocalDOMWindow>::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.h b/chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.h
index aa401a47100..f2481460173 100644
--- a/chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.h
+++ b/chromium/third_party/WebKit/Source/core/page/DOMWindowPagePopup.h
@@ -32,25 +32,29 @@
#define DOMWindowPagePopup_h
#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
-class DOMWindow;
+class LocalDOMWindow;
class PagePopupClient;
class PagePopupController;
-class DOMWindowPagePopup : public Supplement<DOMWindow> {
+class DOMWindowPagePopup FINAL : public NoBaseWillBeGarbageCollected<DOMWindowPagePopup>, public WillBeHeapSupplement<LocalDOMWindow> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DOMWindowPagePopup);
public:
- static PagePopupController* pagePopupController(DOMWindow*);
- static void install(DOMWindow*, PagePopupClient*);
- static void uninstall(DOMWindow*);
- ~DOMWindowPagePopup();
+ static PagePopupController* pagePopupController(LocalDOMWindow&);
+ static void install(LocalDOMWindow&, PagePopupClient*);
+ static void uninstall(LocalDOMWindow&);
+ DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(DOMWindowPagePopup);
+
+ void trace(Visitor*);
private:
explicit DOMWindowPagePopup(PagePopupClient*);
static const char* supplementName();
- RefPtr<PagePopupController> m_controller;
+ RefPtrWillBeMember<PagePopupController> m_controller;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/page/DragActions.h b/chromium/third_party/WebKit/Source/core/page/DragActions.h
index ce42ab777d9..5f465fb21db 100644
--- a/chromium/third_party/WebKit/Source/core/page/DragActions.h
+++ b/chromium/third_party/WebKit/Source/core/page/DragActions.h
@@ -30,7 +30,6 @@
namespace WebCore {
- // WebCoreDragDestinationAction should be kept in sync with WebDragDestinationAction
typedef enum {
DragDestinationActionNone = 0,
DragDestinationActionDHTML = 1,
diff --git a/chromium/third_party/WebKit/Source/core/page/DragClient.h b/chromium/third_party/WebKit/Source/core/page/DragClient.h
index dcc2e41016c..c1e2e1aacfb 100644
--- a/chromium/third_party/WebKit/Source/core/page/DragClient.h
+++ b/chromium/third_party/WebKit/Source/core/page/DragClient.h
@@ -34,13 +34,13 @@ namespace WebCore {
class Clipboard;
class DragData;
class DragImage;
-class Frame;
+class LocalFrame;
class IntPoint;
class DragClient {
public:
virtual DragDestinationAction actionMaskForDrag(DragData*) = 0;
- virtual void startDrag(DragImage*, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, Frame*, bool linkDrag = false) = 0;
+ virtual void startDrag(DragImage*, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, LocalFrame*, bool linkDrag = false) = 0;
virtual ~DragClient() { }
};
diff --git a/chromium/third_party/WebKit/Source/core/page/DragController.cpp b/chromium/third_party/WebKit/Source/core/page/DragController.cpp
index b53c4ea6dc0..1878c210843 100644
--- a/chromium/third_party/WebKit/Source/core/page/DragController.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/DragController.cpp
@@ -27,10 +27,11 @@
#include "config.h"
#include "core/page/DragController.h"
-#include "HTMLNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/dom/Clipboard.h"
-#include "core/dom/ClipboardAccessPolicy.h"
+#include "core/HTMLNames.h"
+#include "core/clipboard/Clipboard.h"
+#include "core/clipboard/ClipboardAccessPolicy.h"
+#include "core/clipboard/DataObject.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/Element.h"
@@ -46,8 +47,8 @@
#include "core/events/TextEvent.h"
#include "core/fetch/ImageResource.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLInputElement.h"
@@ -61,13 +62,12 @@
#include "core/page/EventHandler.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
-#include "core/platform/DragImage.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
+#include "platform/DragImage.h"
#include "platform/geometry/FloatRect.h"
#include "platform/graphics/Image.h"
#include "platform/graphics/ImageOrientation.h"
@@ -91,7 +91,7 @@ static const int MaxOriginalImageArea = 1500 * 1500;
static const int LinkDragBorderInset = 2;
static const float DragImageAlpha = 0.75f;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
static bool dragTypeIsValid(DragSourceAction action)
{
switch (action) {
@@ -110,20 +110,18 @@ static bool dragTypeIsValid(DragSourceAction action)
static PlatformMouseEvent createMouseEvent(DragData* dragData)
{
- bool shiftKey, ctrlKey, altKey, metaKey;
- shiftKey = ctrlKey = altKey = metaKey = false;
int keyState = dragData->modifierKeyState();
- shiftKey = static_cast<bool>(keyState & PlatformEvent::ShiftKey);
- ctrlKey = static_cast<bool>(keyState & PlatformEvent::CtrlKey);
- altKey = static_cast<bool>(keyState & PlatformEvent::AltKey);
- metaKey = static_cast<bool>(keyState & PlatformEvent::MetaKey);
+ bool shiftKey = static_cast<bool>(keyState & PlatformEvent::ShiftKey);
+ bool ctrlKey = static_cast<bool>(keyState & PlatformEvent::CtrlKey);
+ bool altKey = static_cast<bool>(keyState & PlatformEvent::AltKey);
+ bool metaKey = static_cast<bool>(keyState & PlatformEvent::MetaKey);
return PlatformMouseEvent(dragData->clientPosition(), dragData->globalPosition(),
LeftButton, PlatformEvent::MouseMoved, 0, shiftKey, ctrlKey, altKey,
metaKey, currentTime());
}
-static PassRefPtr<Clipboard> createDraggingClipboard(ClipboardAccessPolicy policy, DragData* dragData)
+static PassRefPtrWillBeRawPtr<Clipboard> createDraggingClipboard(ClipboardAccessPolicy policy, DragData* dragData)
{
return Clipboard::create(Clipboard::DragAndDrop, policy, dragData->platformData());
}
@@ -131,9 +129,9 @@ static PassRefPtr<Clipboard> createDraggingClipboard(ClipboardAccessPolicy polic
DragController::DragController(Page* page, DragClient* client)
: m_page(page)
, m_client(client)
- , m_documentUnderMouse(0)
- , m_dragInitiator(0)
- , m_fileInputElementUnderMouse(0)
+ , m_documentUnderMouse(nullptr)
+ , m_dragInitiator(nullptr)
+ , m_fileInputElementUnderMouse(nullptr)
, m_documentIsHandlingDrag(false)
, m_dragDestinationAction(DragDestinationActionNone)
, m_didInitiateDrag(false)
@@ -145,28 +143,27 @@ DragController::~DragController()
{
}
-PassOwnPtr<DragController> DragController::create(Page* page, DragClient* client)
+PassOwnPtrWillBeRawPtr<DragController> DragController::create(Page* page, DragClient* client)
{
- return adoptPtr(new DragController(page, client));
+ return adoptPtrWillBeNoop(new DragController(page, client));
}
-static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragData, Frame* frame, RefPtr<Range> context,
- bool allowPlainText, bool& chosePlainText)
+static PassRefPtrWillBeRawPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragData, LocalFrame* frame, RefPtrWillBeRawPtr<Range> context, bool allowPlainText, bool& chosePlainText)
{
ASSERT(dragData);
chosePlainText = false;
Document& document = context->ownerDocument();
if (dragData->containsCompatibleContent()) {
- if (PassRefPtr<DocumentFragment> fragment = dragData->asFragment(frame, context, allowPlainText, chosePlainText))
+ if (PassRefPtrWillBeRawPtr<DocumentFragment> fragment = dragData->asFragment(frame, context, allowPlainText, chosePlainText))
return fragment;
if (dragData->containsURL(DragData::DoNotConvertFilenames)) {
String title;
String url = dragData->asURL(DragData::DoNotConvertFilenames, &title);
if (!url.isEmpty()) {
- RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(document);
- anchor->setHref(url);
+ RefPtrWillBeRawPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(document);
+ anchor->setHref(AtomicString(url));
if (title.isEmpty()) {
// Try the plain text first because the url might be normalized or escaped.
if (dragData->containsPlainText())
@@ -174,9 +171,9 @@ static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragD
if (title.isEmpty())
title = url;
}
- RefPtr<Node> anchorText = document.createTextNode(title);
+ RefPtrWillBeRawPtr<Node> anchorText = document.createTextNode(title);
anchor->appendChild(anchorText);
- RefPtr<DocumentFragment> fragment = document.createDocumentFragment();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = document.createDocumentFragment();
fragment->appendChild(anchor);
return fragment.release();
}
@@ -187,7 +184,7 @@ static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragD
return createFragmentFromText(context.get(), dragData->asPlainText()).get();
}
- return 0;
+ return nullptr;
}
bool DragController::dragIsMove(FrameSelection& selection, DragData* dragData)
@@ -203,7 +200,7 @@ void DragController::cancelDrag()
void DragController::dragEnded()
{
- m_dragInitiator = 0;
+ m_dragInitiator = nullptr;
m_didInitiateDrag = false;
m_page->dragCaretController().clear();
}
@@ -216,11 +213,11 @@ DragSession DragController::dragEntered(DragData* dragData)
void DragController::dragExited(DragData* dragData)
{
ASSERT(dragData);
- Frame* mainFrame = m_page->mainFrame();
+ LocalFrame* mainFrame = m_page->deprecatedLocalMainFrame();
if (RefPtr<FrameView> v = mainFrame->view()) {
ClipboardAccessPolicy policy = (!m_documentUnderMouse || m_documentUnderMouse->securityOrigin()->isLocal()) ? ClipboardReadable : ClipboardTypesReadable;
- RefPtr<Clipboard> clipboard = createDraggingClipboard(policy, dragData);
+ RefPtrWillBeRawPtr<Clipboard> clipboard = createDraggingClipboard(policy, dragData);
clipboard->setSourceOperation(dragData->draggingSourceOperationMask());
mainFrame->eventHandler().cancelDragAndDrop(createMouseEvent(dragData), clipboard.get());
clipboard->setAccessPolicy(ClipboardNumb); // invalidate clipboard here for security
@@ -228,7 +225,7 @@ void DragController::dragExited(DragData* dragData)
mouseMovedIntoDocument(0);
if (m_fileInputElementUnderMouse)
m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
- m_fileInputElementUnderMouse = 0;
+ m_fileInputElementUnderMouse = nullptr;
}
DragSession DragController::dragUpdated(DragData* dragData)
@@ -239,34 +236,35 @@ DragSession DragController::dragUpdated(DragData* dragData)
bool DragController::performDrag(DragData* dragData)
{
ASSERT(dragData);
- m_documentUnderMouse = m_page->mainFrame()->documentAtPoint(dragData->clientPosition());
+ m_documentUnderMouse = m_page->deprecatedLocalMainFrame()->documentAtPoint(dragData->clientPosition());
if ((m_dragDestinationAction & DragDestinationActionDHTML) && m_documentIsHandlingDrag) {
- RefPtr<Frame> mainFrame = m_page->mainFrame();
+ RefPtr<LocalFrame> mainFrame = m_page->deprecatedLocalMainFrame();
bool preventedDefault = false;
if (mainFrame->view()) {
// Sending an event can result in the destruction of the view and part.
- RefPtr<Clipboard> clipboard = createDraggingClipboard(ClipboardReadable, dragData);
+ RefPtrWillBeRawPtr<Clipboard> clipboard = createDraggingClipboard(ClipboardReadable, dragData);
clipboard->setSourceOperation(dragData->draggingSourceOperationMask());
preventedDefault = mainFrame->eventHandler().performDragAndDrop(createMouseEvent(dragData), clipboard.get());
clipboard->setAccessPolicy(ClipboardNumb); // Invalidate clipboard here for security
}
if (preventedDefault) {
- m_documentUnderMouse = 0;
+ m_documentUnderMouse = nullptr;
return true;
}
}
if ((m_dragDestinationAction & DragDestinationActionEdit) && concludeEditDrag(dragData)) {
- m_documentUnderMouse = 0;
+ m_documentUnderMouse = nullptr;
return true;
}
- m_documentUnderMouse = 0;
+ m_documentUnderMouse = nullptr;
if (operationForLoad(dragData) == DragOperationNone)
return false;
- m_page->mainFrame()->loader().load(FrameLoadRequest(0, ResourceRequest(dragData->asURL())));
+ if (m_page->settings().navigateOnDragDrop())
+ m_page->deprecatedLocalMainFrame()->loader().load(FrameLoadRequest(0, ResourceRequest(dragData->asURL())));
return true;
}
@@ -285,7 +283,7 @@ DragSession DragController::dragEnteredOrUpdated(DragData* dragData)
{
ASSERT(dragData);
ASSERT(m_page->mainFrame());
- mouseMovedIntoDocument(m_page->mainFrame()->documentAtPoint(dragData->clientPosition()));
+ mouseMovedIntoDocument(m_page->deprecatedLocalMainFrame()->documentAtPoint(dragData->clientPosition()));
m_dragDestinationAction = m_client->actionMaskForDrag(dragData);
if (m_dragDestinationAction == DragDestinationActionNone) {
@@ -304,7 +302,7 @@ static HTMLInputElement* asFileInput(Node* node)
{
ASSERT(node);
for (; node; node = node->shadowHost()) {
- if (node->hasTagName(HTMLNames::inputTag) && toHTMLInputElement(node)->isFileUpload())
+ if (isHTMLInputElement(*node) && toHTMLInputElement(node)->isFileUpload())
return toHTMLInputElement(node);
}
return 0;
@@ -313,7 +311,7 @@ static HTMLInputElement* asFileInput(Node* node)
// This can return null if an empty document is loaded.
static Element* elementUnderMouse(Document* documentUnderMouse, const IntPoint& p)
{
- Frame* frame = documentUnderMouse->frame();
+ LocalFrame* frame = documentUnderMouse->frame();
float zoomFactor = frame ? frame->pageZoomFactor() : 1;
LayoutPoint point = roundedLayoutPoint(FloatPoint(p.x() * zoomFactor, p.y() * zoomFactor));
@@ -379,7 +377,7 @@ bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction a
if (!m_fileInputElementUnderMouse)
m_page->dragCaretController().setCaretPosition(m_documentUnderMouse->frame()->visiblePositionForPoint(point));
- Frame* innerFrame = element->document().frame();
+ LocalFrame* innerFrame = element->document().frame();
dragSession.operation = dragIsMove(innerFrame->selection(), dragData) ? DragOperationMove : DragOperationCopy;
dragSession.mouseIsOverFileInput = m_fileInputElementUnderMouse;
dragSession.numberOfItemsToBeAccepted = 0;
@@ -411,36 +409,36 @@ bool DragController::tryDocumentDrag(DragData* dragData, DragDestinationAction a
m_page->dragCaretController().clear();
if (m_fileInputElementUnderMouse)
m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
- m_fileInputElementUnderMouse = 0;
+ m_fileInputElementUnderMouse = nullptr;
return false;
}
DragOperation DragController::operationForLoad(DragData* dragData)
{
ASSERT(dragData);
- Document* doc = m_page->mainFrame()->documentAtPoint(dragData->clientPosition());
+ Document* doc = m_page->deprecatedLocalMainFrame()->documentAtPoint(dragData->clientPosition());
if (doc && (m_didInitiateDrag || doc->isPluginDocument() || doc->rendererIsEditable()))
return DragOperationNone;
return dragOperation(dragData);
}
-static bool setSelectionToDragCaret(Frame* frame, VisibleSelection& dragCaret, RefPtr<Range>& range, const IntPoint& point)
+static bool setSelectionToDragCaret(LocalFrame* frame, VisibleSelection& dragCaret, RefPtrWillBeRawPtr<Range>& range, const IntPoint& point)
{
frame->selection().setSelection(dragCaret);
if (frame->selection().isNone()) {
- dragCaret = frame->visiblePositionForPoint(point);
+ dragCaret = VisibleSelection(frame->visiblePositionForPoint(point));
frame->selection().setSelection(dragCaret);
range = dragCaret.toNormalizedRange();
}
return !frame->selection().isNone() && frame->selection().isContentEditable();
}
-bool DragController::dispatchTextInputEventFor(Frame* innerFrame, DragData* dragData)
+bool DragController::dispatchTextInputEventFor(LocalFrame* innerFrame, DragData* dragData)
{
ASSERT(m_page->dragCaretController().hasCaret());
String text = m_page->dragCaretController().isContentRichlyEditable() ? "" : dragData->asPlainText();
- Node* target = innerFrame->editor().findEventTargetFrom(m_page->dragCaretController().caretPosition());
+ Node* target = innerFrame->editor().findEventTargetFrom(VisibleSelection(m_page->dragCaretController().caretPosition()));
return target->dispatchEvent(TextEvent::createForDrop(innerFrame->domWindow(), text), IGNORE_EXCEPTION);
}
@@ -448,10 +446,10 @@ bool DragController::concludeEditDrag(DragData* dragData)
{
ASSERT(dragData);
- RefPtr<HTMLInputElement> fileInput = m_fileInputElementUnderMouse;
+ RefPtrWillBeRawPtr<HTMLInputElement> fileInput = m_fileInputElementUnderMouse;
if (m_fileInputElementUnderMouse) {
m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
- m_fileInputElementUnderMouse = 0;
+ m_fileInputElementUnderMouse = nullptr;
}
if (!m_documentUnderMouse)
@@ -461,7 +459,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
Element* element = elementUnderMouse(m_documentUnderMouse.get(), point);
if (!element)
return false;
- RefPtr<Frame> innerFrame = element->ownerDocument()->frame();
+ RefPtr<LocalFrame> innerFrame = element->ownerDocument()->frame();
ASSERT(innerFrame);
if (m_page->dragCaretController().hasCaret() && !dispatchTextInputEventFor(innerFrame.get(), dragData))
@@ -482,10 +480,10 @@ bool DragController::concludeEditDrag(DragData* dragData)
return false;
}
- VisibleSelection dragCaret = m_page->dragCaretController().caretPosition();
+ VisibleSelection dragCaret(m_page->dragCaretController().caretPosition());
m_page->dragCaretController().clear();
- RefPtr<Range> range = dragCaret.toNormalizedRange();
- RefPtr<Element> rootEditableElement = innerFrame->selection().rootEditableElement();
+ RefPtrWillBeRawPtr<Range> range = dragCaret.toNormalizedRange();
+ RefPtrWillBeRawPtr<Element> rootEditableElement = innerFrame->selection().rootEditableElement();
// For range to be null a WebKit client must have done something bad while
// manually controlling drag behaviour
@@ -495,7 +493,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
ResourceCacheValidationSuppressor validationSuppressor(fetcher);
if (dragIsMove(innerFrame->selection(), dragData) || dragCaret.isContentRichlyEditable()) {
bool chosePlainText = false;
- RefPtr<DocumentFragment> fragment = documentFragmentFromDragData(dragData, innerFrame.get(), range, true, chosePlainText);
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = documentFragmentFromDragData(dragData, innerFrame.get(), range, true, chosePlainText);
if (!fragment)
return false;
@@ -528,7 +526,7 @@ bool DragController::concludeEditDrag(DragData* dragData)
}
if (rootEditableElement) {
- if (Frame* frame = rootEditableElement->document().frame())
+ if (LocalFrame* frame = rootEditableElement->document().frame())
frame->eventHandler().updateDragStateAfterEditDragIfNeeded(rootEditableElement.get());
}
@@ -542,12 +540,12 @@ bool DragController::canProcessDrag(DragData* dragData)
if (!dragData->containsCompatibleContent())
return false;
- IntPoint point = m_page->mainFrame()->view()->windowToContents(dragData->clientPosition());
+ IntPoint point = m_page->deprecatedLocalMainFrame()->view()->windowToContents(dragData->clientPosition());
HitTestResult result = HitTestResult(point);
- if (!m_page->mainFrame()->contentRenderer())
+ if (!m_page->deprecatedLocalMainFrame()->contentRenderer())
return false;
- result = m_page->mainFrame()->eventHandler().hitTestResultAtPoint(point);
+ result = m_page->deprecatedLocalMainFrame()->eventHandler().hitTestResultAtPoint(point);
if (!result.innerNonSharedNode())
return false;
@@ -555,7 +553,7 @@ bool DragController::canProcessDrag(DragData* dragData)
if (dragData->containsFiles() && asFileInput(result.innerNonSharedNode()))
return true;
- if (result.innerNonSharedNode()->isPluginElement()) {
+ if (isHTMLPlugInElement(*result.innerNonSharedNode())) {
HTMLPlugInElement* plugin = toHTMLPlugInElement(result.innerNonSharedNode());
if (!plugin->canProcessDrag() && !result.innerNonSharedNode()->rendererIsEditable())
return false;
@@ -591,13 +589,13 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
{
ASSERT(dragData);
ASSERT(m_documentUnderMouse);
- RefPtr<Frame> mainFrame = m_page->mainFrame();
+ RefPtr<LocalFrame> mainFrame = m_page->deprecatedLocalMainFrame();
RefPtr<FrameView> viewProtector = mainFrame->view();
if (!viewProtector)
return false;
ClipboardAccessPolicy policy = m_documentUnderMouse->securityOrigin()->isLocal() ? ClipboardReadable : ClipboardTypesReadable;
- RefPtr<Clipboard> clipboard = createDraggingClipboard(policy, dragData);
+ RefPtrWillBeRawPtr<Clipboard> clipboard = createDraggingClipboard(policy, dragData);
DragOperation srcOpMask = dragData->draggingSourceOperationMask();
clipboard->setSourceOperation(srcOpMask);
@@ -619,7 +617,7 @@ bool DragController::tryDHTMLDrag(DragData* dragData, DragOperation& operation)
return true;
}
-Node* DragController::draggableNode(const Frame* src, Node* startNode, const IntPoint& dragOrigin, SelectionDragPolicy selectionDragPolicy, DragSourceAction& dragType) const
+Node* DragController::draggableNode(const LocalFrame* src, Node* startNode, const IntPoint& dragOrigin, SelectionDragPolicy selectionDragPolicy, DragSourceAction& dragType) const
{
if (src->selection().contains(dragOrigin)) {
dragType = DragSourceActionSelection;
@@ -656,8 +654,7 @@ Node* DragController::draggableNode(const Frame* src, Node* startNode, const Int
return node;
}
// Other draggable elements are considered unselectable.
- if (isHTMLAnchorElement(node)
- && toHTMLAnchorElement(node)->isLiveLink()) {
+ if (isHTMLAnchorElement(*node) && toHTMLAnchorElement(node)->isLiveLink()) {
candidateDragType = DragSourceActionLink;
break;
}
@@ -713,17 +710,17 @@ static Image* getImage(Element* element)
cachedImage->image() : 0;
}
-static void prepareClipboardForImageDrag(Frame* source, Clipboard* clipboard, Element* node, const KURL& linkURL, const KURL& imageURL, const String& label)
+static void prepareClipboardForImageDrag(LocalFrame* source, Clipboard* clipboard, Element* node, const KURL& linkURL, const KURL& imageURL, const String& label)
{
if (node->isContentRichlyEditable()) {
- RefPtr<Range> range = source->document()->createRange();
+ RefPtrWillBeRawPtr<Range> range = source->document()->createRange();
range->selectNode(node, ASSERT_NO_EXCEPTION);
source->selection().setSelection(VisibleSelection(range.get(), DOWNSTREAM));
}
clipboard->declareAndWriteDragImage(node, !linkURL.isEmpty() ? linkURL : imageURL, label);
}
-bool DragController::populateDragClipboard(Frame* src, const DragState& state, const IntPoint& dragOrigin)
+bool DragController::populateDragClipboard(LocalFrame* src, const DragState& state, const IntPoint& dragOrigin)
{
ASSERT(dragTypeIsValid(state.m_dragType));
ASSERT(src);
@@ -749,7 +746,7 @@ bool DragController::populateDragClipboard(Frame* src, const DragState& state, c
if (enclosingTextFormControl(src->selection().start())) {
clipboard->writePlainText(src->selectedTextForClipboard());
} else {
- RefPtr<Range> selectionRange = src->selection().toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> selectionRange = src->selection().toNormalizedRange();
ASSERT(selectionRange);
clipboard->writeRange(selectionRange.get(), src);
@@ -781,7 +778,7 @@ static IntPoint dragLocationForDHTMLDrag(const IntPoint& mouseDraggedPoint, cons
return IntPoint(dragOrigin.x() - dragImageOffset.x(), dragOrigin.y() + yOffset);
}
-static IntPoint dragLocationForSelectionDrag(Frame* sourceFrame)
+static IntPoint dragLocationForSelectionDrag(LocalFrame* sourceFrame)
{
IntRect draggingRect = enclosingIntRect(sourceFrame->selection().bounds());
int xpos = draggingRect.maxX();
@@ -843,7 +840,7 @@ static PassOwnPtr<DragImage> dragImageForLink(const KURL& linkURL, const String&
return dragImage.release();
}
-bool DragController::startDrag(Frame* src, const DragState& state, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin)
+bool DragController::startDrag(LocalFrame* src, const DragState& state, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin)
{
ASSERT(dragTypeIsValid(state.m_dragType));
ASSERT(src);
@@ -925,12 +922,12 @@ bool DragController::startDrag(Frame* src, const DragState& state, const Platfor
return true;
}
-void DragController::doSystemDrag(DragImage* image, const IntPoint& dragLocation, const IntPoint& eventPos, Clipboard* clipboard, Frame* frame, bool forLink)
+void DragController::doSystemDrag(DragImage* image, const IntPoint& dragLocation, const IntPoint& eventPos, Clipboard* clipboard, LocalFrame* frame, bool forLink)
{
m_didInitiateDrag = true;
m_dragInitiator = frame->document();
// Protect this frame and view, as a load may occur mid drag and attempt to unload this frame
- RefPtr<Frame> frameProtector = m_page->mainFrame();
+ RefPtr<LocalFrame> frameProtector = m_page->deprecatedLocalMainFrame();
RefPtr<FrameView> viewProtector = frameProtector->view();
m_client->startDrag(image, viewProtector->rootViewToContents(frame->view()->contentsToRootView(dragLocation)),
viewProtector->rootViewToContents(frame->view()->contentsToRootView(eventPos)), clipboard, frameProtector.get(), forLink);
@@ -951,13 +948,14 @@ DragOperation DragController::dragOperation(DragData* dragData)
return dragData->containsURL() && !m_didInitiateDrag ? DragOperationCopy : DragOperationNone;
}
-bool DragController::isCopyKeyDown(DragData*)
+bool DragController::isCopyKeyDown(DragData* dragData)
{
- // FIXME: This should not be OS specific. Delegate to the embedder instead.
-#if OS(WIN)
- return ::GetAsyncKeyState(VK_CONTROL);
+ int keyState = dragData->modifierKeyState();
+
+#if OS(MACOSX)
+ return keyState & PlatformEvent::AltKey;
#else
- return false;
+ return keyState & PlatformEvent::CtrlKey;
#endif
}
@@ -965,5 +963,12 @@ void DragController::cleanupAfterSystemDrag()
{
}
-} // namespace WebCore
+void DragController::trace(Visitor* visitor)
+{
+ visitor->trace(m_page);
+ visitor->trace(m_documentUnderMouse);
+ visitor->trace(m_dragInitiator);
+ visitor->trace(m_fileInputElementUnderMouse);
+}
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/DragController.h b/chromium/third_party/WebKit/Source/core/page/DragController.h
index f109837df9b..4743ae91fa7 100644
--- a/chromium/third_party/WebKit/Source/core/page/DragController.h
+++ b/chromium/third_party/WebKit/Source/core/page/DragController.h
@@ -28,6 +28,7 @@
#include "core/page/DragActions.h"
#include "platform/geometry/IntPoint.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
@@ -39,9 +40,9 @@ namespace WebCore {
class DragData;
class DragImage;
struct DragSession;
- struct DragState;
+ class DragState;
class Element;
- class Frame;
+ class LocalFrame;
class FrameSelection;
class HTMLInputElement;
class Image;
@@ -51,12 +52,13 @@ namespace WebCore {
class PlatformMouseEvent;
class Range;
- class DragController {
- WTF_MAKE_NONCOPYABLE(DragController); WTF_MAKE_FAST_ALLOCATED;
+ class DragController FINAL : public NoBaseWillBeGarbageCollectedFinalized<DragController> {
+ WTF_MAKE_NONCOPYABLE(DragController);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
~DragController();
- static PassOwnPtr<DragController> create(Page*, DragClient*);
+ static PassOwnPtrWillBeRawPtr<DragController> create(Page*, DragClient*);
DragSession dragEntered(DragData*);
void dragExited(DragData*);
@@ -67,11 +69,13 @@ namespace WebCore {
ImmediateSelectionDragResolution,
DelayedSelectionDragResolution,
};
- Node* draggableNode(const Frame*, Node*, const IntPoint&, SelectionDragPolicy, DragSourceAction&) const;
+ Node* draggableNode(const LocalFrame*, Node*, const IntPoint&, SelectionDragPolicy, DragSourceAction&) const;
void dragEnded();
- bool populateDragClipboard(Frame* src, const DragState&, const IntPoint& dragOrigin);
- bool startDrag(Frame* src, const DragState&, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin);
+ bool populateDragClipboard(LocalFrame* src, const DragState&, const IntPoint& dragOrigin);
+ bool startDrag(LocalFrame* src, const DragState&, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin);
+
+ void trace(Visitor*);
static const int DragIconRightInset;
static const int DragIconBottomInset;
@@ -79,7 +83,7 @@ namespace WebCore {
private:
DragController(Page*, DragClient*);
- bool dispatchTextInputEventFor(Frame*, DragData*);
+ bool dispatchTextInputEventFor(LocalFrame*, DragData*);
bool canProcessDrag(DragData*);
bool concludeEditDrag(DragData*);
DragSession dragEnteredOrUpdated(DragData*);
@@ -93,15 +97,15 @@ namespace WebCore {
void mouseMovedIntoDocument(Document*);
- void doSystemDrag(DragImage*, const IntPoint& dragLocation, const IntPoint& dragOrigin, Clipboard*, Frame*, bool forLink);
+ void doSystemDrag(DragImage*, const IntPoint& dragLocation, const IntPoint& dragOrigin, Clipboard*, LocalFrame*, bool forLink);
void cleanupAfterSystemDrag();
- Page* m_page;
+ RawPtrWillBeMember<Page> m_page;
DragClient* m_client;
- RefPtr<Document> m_documentUnderMouse; // The document the mouse was last dragged over.
- RefPtr<Document> m_dragInitiator; // The Document (if any) that initiated the drag.
- RefPtr<HTMLInputElement> m_fileInputElementUnderMouse;
+ RefPtrWillBeMember<Document> m_documentUnderMouse; // The document the mouse was last dragged over.
+ RefPtrWillBeMember<Document> m_dragInitiator; // The Document (if any) that initiated the drag.
+ RefPtrWillBeMember<HTMLInputElement> m_fileInputElementUnderMouse;
bool m_documentIsHandlingDrag;
DragDestinationAction m_dragDestinationAction;
diff --git a/chromium/third_party/WebKit/Source/core/page/DragData.cpp b/chromium/third_party/WebKit/Source/core/page/DragData.cpp
index 79a22571264..fb7eb83fe10 100644
--- a/chromium/third_party/WebKit/Source/core/page/DragData.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/DragData.cpp
@@ -27,13 +27,12 @@
#include "config.h"
#include "core/page/DragData.h"
+#include "core/clipboard/DataObject.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/Range.h"
#include "core/editing/markup.h"
-#include "core/frame/Frame.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
-#include "modules/filesystem/DraggedIsolatedFileSystem.h"
+#include "core/frame/LocalFrame.h"
#include "platform/FileMetadata.h"
#include "platform/clipboard/ClipboardMimeTypes.h"
#include "platform/weborigin/KURL.h"
@@ -41,7 +40,7 @@
namespace WebCore {
-DragData::DragData(ChromiumDataObject* data, const IntPoint& clientPosition, const IntPoint& globalPosition,
+DragData::DragData(DataObject* data, const IntPoint& clientPosition, const IntPoint& globalPosition,
DragOperation sourceOperationMask, DragApplicationFlags flags)
: m_clientPosition(clientPosition)
, m_globalPosition(globalPosition)
@@ -61,7 +60,7 @@ DragData::DragData(const String&, const IntPoint& clientPosition, const IntPoint
{
}
-static bool containsHTML(const ChromiumDataObject* dropData)
+static bool containsHTML(const DataObject* dropData)
{
return dropData->types().contains(mimeTypeTextHTML);
}
@@ -132,7 +131,7 @@ bool DragData::containsCompatibleContent() const
|| containsFiles();
}
-PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const
+PassRefPtrWillBeRawPtr<DocumentFragment> DragData::asFragment(LocalFrame* frame, PassRefPtrWillBeRawPtr<Range>, bool, bool&) const
{
/*
* Order is richest format first. On OSX this is:
@@ -154,19 +153,16 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range
KURL baseURL;
m_platformDragData->htmlAndBaseURL(html, baseURL);
ASSERT(frame->document());
- if (RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(*frame->document(), html, baseURL, DisallowScriptingAndPluginContent))
+ if (RefPtrWillBeRawPtr<DocumentFragment> fragment = createFragmentFromMarkup(*frame->document(), html, baseURL, DisallowScriptingAndPluginContent))
return fragment.release();
}
- return 0;
+ return nullptr;
}
String DragData::droppedFileSystemId() const
{
- DraggedIsolatedFileSystem* filesystem = DraggedIsolatedFileSystem::from(m_platformDragData);
- if (!filesystem)
- return String();
- return filesystem->filesystemId();
+ return m_platformDragData->filesystemId();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/DragData.h b/chromium/third_party/WebKit/Source/core/page/DragData.h
index 33c108c5fe2..edcad891479 100644
--- a/chromium/third_party/WebKit/Source/core/page/DragData.h
+++ b/chromium/third_party/WebKit/Source/core/page/DragData.h
@@ -28,16 +28,16 @@
#include "core/page/DragActions.h"
#include "platform/geometry/IntPoint.h"
-
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/Vector.h"
namespace WebCore {
-class ChromiumDataObject;
+class DataObject;
class DocumentFragment;
-class Frame;
+class LocalFrame;
class KURL;
class Range;
@@ -54,12 +54,12 @@ public:
enum FilenameConversionPolicy { DoNotConvertFilenames, ConvertFilenames };
// clientPosition is taken to be the position of the drag event within the target window, with (0,0) at the top left
- DragData(ChromiumDataObject*, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation, DragApplicationFlags = DragApplicationNone);
+ DragData(DataObject*, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation, DragApplicationFlags = DragApplicationNone);
DragData(const String& dragStorageName, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation, DragApplicationFlags = DragApplicationNone);
const IntPoint& clientPosition() const { return m_clientPosition; }
const IntPoint& globalPosition() const { return m_globalPosition; }
DragApplicationFlags flags() const { return m_applicationFlags; }
- ChromiumDataObject* platformData() const { return m_platformDragData; }
+ DataObject* platformData() const { return m_platformDragData; }
DragOperation draggingSourceOperationMask() const { return m_draggingSourceOperationMask; }
bool containsURL(FilenameConversionPolicy filenamePolicy = ConvertFilenames) const;
bool containsPlainText() const;
@@ -67,7 +67,7 @@ public:
String asURL(FilenameConversionPolicy filenamePolicy = ConvertFilenames, String* title = 0) const;
String asPlainText() const;
void asFilenames(Vector<String>&) const;
- PassRefPtr<DocumentFragment> asFragment(Frame*, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) const;
+ PassRefPtrWillBeRawPtr<DocumentFragment> asFragment(LocalFrame*, PassRefPtrWillBeRawPtr<Range> context, bool allowPlainText, bool& chosePlainText) const;
bool canSmartReplace() const;
bool containsFiles() const;
unsigned numberOfFiles() const;
@@ -78,7 +78,7 @@ public:
private:
IntPoint m_clientPosition;
IntPoint m_globalPosition;
- ChromiumDataObject* m_platformDragData;
+ DataObject* m_platformDragData;
DragOperation m_draggingSourceOperationMask;
DragApplicationFlags m_applicationFlags;
};
diff --git a/chromium/third_party/WebKit/Source/core/page/DragState.h b/chromium/third_party/WebKit/Source/core/page/DragState.h
index 6b866577170..48a154d7be0 100644
--- a/chromium/third_party/WebKit/Source/core/page/DragState.h
+++ b/chromium/third_party/WebKit/Source/core/page/DragState.h
@@ -35,14 +35,20 @@ namespace WebCore {
class Clipboard;
class Node;
-struct DragState {
+class DragState : public NoBaseWillBeGarbageCollected<DragState> {
WTF_MAKE_NONCOPYABLE(DragState);
- WTF_MAKE_FAST_ALLOCATED;
public:
DragState() { }
- RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
+
+ RefPtrWillBeMember<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
DragSourceAction m_dragType;
- RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging
+ RefPtrWillBeMember<Clipboard> m_dragClipboard; // used on only the source side of dragging
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_dragSrc);
+ visitor->trace(m_dragClipboard);
+ }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/EditorClient.h b/chromium/third_party/WebKit/Source/core/page/EditorClient.h
index f7664b6ba73..bc0ced669d7 100644
--- a/chromium/third_party/WebKit/Source/core/page/EditorClient.h
+++ b/chromium/third_party/WebKit/Source/core/page/EditorClient.h
@@ -33,7 +33,7 @@
namespace WebCore {
class Element;
-class Frame;
+class LocalFrame;
class UndoStep;
class EditorClient {
@@ -41,12 +41,11 @@ public:
virtual ~EditorClient() { }
virtual void respondToChangedContents() = 0;
- virtual void respondToChangedSelection(SelectionType) = 0;
+ virtual void respondToChangedSelection(LocalFrame*, SelectionType) = 0;
- virtual bool canCopyCut(Frame*, bool defaultValue) const = 0;
- virtual bool canPaste(Frame*, bool defaultValue) const = 0;
+ virtual bool canCopyCut(LocalFrame*, bool defaultValue) const = 0;
+ virtual bool canPaste(LocalFrame*, bool defaultValue) const = 0;
- virtual void didExecuteCommand(String) = 0;
virtual bool handleKeyboardEvent() = 0;
};
diff --git a/chromium/third_party/WebKit/Source/core/page/EventHandler.cpp b/chromium/third_party/WebKit/Source/core/page/EventHandler.cpp
index 40b59aa8a56..bad7363a5a1 100644
--- a/chromium/third_party/WebKit/Source/core/page/EventHandler.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/EventHandler.cpp
@@ -28,11 +28,11 @@
#include "config.h"
#include "core/page/EventHandler.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/dom/Clipboard.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/clipboard/Clipboard.h"
+#include "core/clipboard/DataObject.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/FullscreenElementStack.h"
@@ -48,10 +48,11 @@
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
#include "core/events/TextEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/events/TouchEvent.h"
#include "core/events/WheelEvent.h"
#include "core/fetch/ImageResource.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLDialogElement.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/html/HTMLFrameSetElement.h"
@@ -66,36 +67,32 @@
#include "core/page/DragState.h"
#include "core/page/EditorClient.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
#include "core/page/FrameTree.h"
-#include "core/frame/FrameView.h"
#include "core/inspector/InspectorController.h"
#include "core/page/MouseEventWithHitTestResults.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/page/SpatialNavigation.h"
#include "core/page/TouchAdjustment.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderRegion.h"
#include "core/rendering/RenderTextControlSingleLine.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/RenderWidget.h"
-#include "core/rendering/style/CursorList.h"
#include "core/rendering/style/RenderStyle.h"
-#include "core/svg/SVGDocument.h"
-#include "core/svg/SVGElementInstance.h"
-#include "core/svg/SVGUseElement.h"
+#include "core/svg/SVGDocumentExtensions.h"
#include "platform/PlatformGestureEvent.h"
#include "platform/PlatformKeyboardEvent.h"
#include "platform/PlatformTouchEvent.h"
#include "platform/PlatformWheelEvent.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/TraceEvent.h"
#include "platform/WindowsKeyboardCodes.h"
#include "platform/geometry/FloatPoint.h"
#include "platform/graphics/Image.h"
+#include "platform/heap/Handle.h"
#include "platform/scroll/ScrollAnimator.h"
#include "platform/scroll/Scrollbar.h"
#include "wtf/Assertions.h"
@@ -106,7 +103,6 @@
namespace WebCore {
using namespace HTMLNames;
-using namespace SVGNames;
// The link drag hysteresis is much larger than the others because there
// needs to be enough space to cancel the link press without starting a link drag,
@@ -134,8 +130,8 @@ static const int maximumCursorSize = 128;
static const double minimumCursorScale = 0.001;
// The minimum amount of time an element stays active after a ShowPress
-// This is roughly 2 frames, which should be long enough to be noticeable.
-static const double minimumActiveInterval = 0.032;
+// This is roughly 9 frames, which should be long enough to be noticeable.
+static const double minimumActiveInterval = 0.15;
#if OS(MACOSX)
static const double TextDragDelay = 0.15;
@@ -176,71 +172,6 @@ private:
double m_start;
};
-class SyntheticTouchPoint : public PlatformTouchPoint {
-public:
-
- // The default values are based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
- explicit SyntheticTouchPoint(const PlatformMouseEvent& event)
- {
- const static int idDefaultValue = 0;
- const static int radiusYDefaultValue = 1;
- const static int radiusXDefaultValue = 1;
- const static float rotationAngleDefaultValue = 0.0f;
- const static float forceDefaultValue = 1.0f;
-
- m_id = idDefaultValue; // There is only one active TouchPoint.
- m_screenPos = event.globalPosition();
- m_pos = event.position();
- m_radiusY = radiusYDefaultValue;
- m_radiusX = radiusXDefaultValue;
- m_rotationAngle = rotationAngleDefaultValue;
- m_force = forceDefaultValue;
-
- PlatformEvent::Type type = event.type();
- ASSERT(type == PlatformEvent::MouseMoved || type == PlatformEvent::MousePressed || type == PlatformEvent::MouseReleased);
-
- switch (type) {
- case PlatformEvent::MouseMoved:
- m_state = TouchMoved;
- break;
- case PlatformEvent::MousePressed:
- m_state = TouchPressed;
- break;
- case PlatformEvent::MouseReleased:
- m_state = TouchReleased;
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
- }
-};
-
-class SyntheticSingleTouchEvent : public PlatformTouchEvent {
-public:
- explicit SyntheticSingleTouchEvent(const PlatformMouseEvent& event)
- {
- switch (event.type()) {
- case PlatformEvent::MouseMoved:
- m_type = TouchMove;
- break;
- case PlatformEvent::MousePressed:
- m_type = TouchStart;
- break;
- case PlatformEvent::MouseReleased:
- m_type = TouchEnd;
- break;
- default:
- ASSERT_NOT_REACHED();
- m_type = NoType;
- break;
- }
- m_timestamp = event.timestamp();
- m_modifiers = event.modifiers();
- m_touchPoints.append(SyntheticTouchPoint(event));
- }
-};
-
static inline ScrollGranularity wheelGranularityToScrollGranularity(unsigned deltaMode)
{
switch (deltaMode) {
@@ -255,43 +186,6 @@ static inline ScrollGranularity wheelGranularityToScrollGranularity(unsigned del
}
}
-static inline bool scrollNode(float delta, ScrollGranularity granularity, ScrollDirection direction, Node* node, Node** stopNode, IntPoint absolutePoint = IntPoint())
-{
- if (!delta)
- return false;
- if (!node->renderer())
- return false;
-
- RenderBox* curBox = node->renderer()->enclosingBox();
-
- while (curBox && !curBox->isRenderView()) {
- ScrollDirection physicalDirection = toPhysicalDirection(
- direction, curBox->isHorizontalWritingMode(), curBox->style()->isFlippedBlocksWritingMode());
-
- if (curBox->scroll(physicalDirection, granularity, delta)) {
- if (stopNode)
- *stopNode = curBox->node();
- return true;
- }
-
- if (stopNode && *stopNode && curBox->node() == *stopNode)
- return true;
-
- // FIXME: This should probably move to a virtual method on RenderBox, something like RenderBox::scrollAncestor, and specialized for RenderFlowThread
- curBox = curBox->containingBlock();
- if (curBox && curBox->isRenderNamedFlowThread()) {
- RenderBox* flowedBox = curBox;
-
- if (RenderBox* startBox = node->renderBox())
- flowedBox = startBox;
-
- curBox = toRenderFlowThread(curBox)->regionFromAbsolutePointAndBox(absolutePoint, flowedBox);
- }
- }
-
- return false;
-}
-
// Refetch the event target node if it is removed or currently is the shadow node inside an <input> element.
// If a mouse event handler changes the input element type to one that has a widget associated,
// we'd like to EventHandler::handleMousePressEvent to pass the event to the widget and thus the
@@ -301,10 +195,10 @@ static inline bool shouldRefetchEventTarget(const MouseEventWithHitTestResults&
Node* targetNode = mev.targetNode();
if (!targetNode || !targetNode->parentNode())
return true;
- return targetNode->isShadowRoot() && toShadowRoot(targetNode)->host()->hasTagName(inputTag);
+ return targetNode->isShadowRoot() && isHTMLInputElement(*toShadowRoot(targetNode)->host());
}
-EventHandler::EventHandler(Frame* frame)
+EventHandler::EventHandler(LocalFrame* frame)
: m_frame(frame)
, m_mousePressed(false)
, m_capturesDragging(false)
@@ -312,7 +206,6 @@ EventHandler::EventHandler(Frame* frame)
, m_mouseDownMayStartDrag(false)
, m_mouseDownWasSingleClickInSelection(false)
, m_selectionInitiationState(HaveNotStartedSelection)
- , m_panScrollButtonPressed(false)
, m_hoverTimer(this, &EventHandler::hoverTimerFired)
, m_cursorUpdateTimer(this, &EventHandler::cursorUpdateTimerFired)
, m_mouseDownMayStartAutoscroll(false)
@@ -326,15 +219,13 @@ EventHandler::EventHandler(Frame* frame)
, m_mousePositionIsUnknown(true)
, m_mouseDownTimestamp(0)
, m_widgetIsLatched(false)
- , m_originatingTouchPointTargetKey(0)
, m_touchPressed(false)
- , m_scrollGestureHandlingNode(0)
+ , m_scrollGestureHandlingNode(nullptr)
, m_lastHitTestResultOverWidget(false)
, m_maxMouseMovedDuration(0)
, m_baseEventType(PlatformEvent::NoType)
, m_didStartDrag(false)
, m_longTapShouldInvokeContextMenu(false)
- , m_syntheticPageScaleFactor(0)
, m_activeIntervalTimer(this, &EventHandler::activeIntervalTimerFired)
, m_lastShowPressTimestamp(0)
{
@@ -345,10 +236,33 @@ EventHandler::~EventHandler()
ASSERT(!m_fakeMouseMoveEventTimer.isActive());
}
+void EventHandler::trace(Visitor* visitor)
+{
+ visitor->trace(m_mousePressNode);
+ visitor->trace(m_capturingMouseEventsNode);
+ visitor->trace(m_nodeUnderMouse);
+ visitor->trace(m_lastNodeUnderMouse);
+ visitor->trace(m_clickNode);
+ visitor->trace(m_dragTarget);
+ visitor->trace(m_frameSetBeingResized);
+ visitor->trace(m_latchedWheelEventNode);
+ visitor->trace(m_previousWheelScrolledNode);
+ visitor->trace(m_targetForTouchID);
+ visitor->trace(m_touchSequenceDocument);
+ visitor->trace(m_scrollGestureHandlingNode);
+ visitor->trace(m_previousGestureScrolledNode);
+ visitor->trace(m_lastDeferredTapElement);
+}
+
DragState& EventHandler::dragState()
{
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<DragState>, state, (new DragState()));
+ return *state;
+#else
DEFINE_STATIC_LOCAL(DragState, state, ());
return state;
+#endif
}
void EventHandler::clear()
@@ -358,34 +272,32 @@ void EventHandler::clear()
m_fakeMouseMoveEventTimer.stop();
m_activeIntervalTimer.stop();
m_resizeScrollableArea = 0;
- m_nodeUnderMouse = 0;
- m_lastNodeUnderMouse = 0;
- m_instanceUnderMouse = 0;
- m_lastInstanceUnderMouse = 0;
- m_lastMouseMoveEventSubframe = 0;
- m_lastScrollbarUnderMouse = 0;
+ m_nodeUnderMouse = nullptr;
+ m_lastNodeUnderMouse = nullptr;
+ m_lastMouseMoveEventSubframe = nullptr;
+ m_lastScrollbarUnderMouse = nullptr;
m_clickCount = 0;
- m_clickNode = 0;
- m_frameSetBeingResized = 0;
- m_dragTarget = 0;
+ m_clickNode = nullptr;
+ m_frameSetBeingResized = nullptr;
+ m_dragTarget = nullptr;
m_shouldOnlyFireDragOverEvent = false;
m_mousePositionIsUnknown = true;
m_lastKnownMousePosition = IntPoint();
m_lastKnownMouseGlobalPosition = IntPoint();
m_lastMouseDownUserGestureToken.clear();
- m_mousePressNode = 0;
+ m_mousePressNode = nullptr;
m_mousePressed = false;
m_capturesDragging = false;
- m_capturingMouseEventsNode = 0;
- m_latchedWheelEventNode = 0;
- m_previousWheelScrolledNode = 0;
- m_originatingTouchPointTargets.clear();
- m_originatingTouchPointDocument.clear();
- m_originatingTouchPointTargetKey = 0;
- m_scrollGestureHandlingNode = 0;
+ m_capturingMouseEventsNode = nullptr;
+ m_latchedWheelEventNode = nullptr;
+ m_previousWheelScrolledNode = nullptr;
+ m_targetForTouchID.clear();
+ m_touchSequenceDocument.clear();
+ m_touchSequenceUserGestureToken.clear();
+ m_scrollGestureHandlingNode = nullptr;
m_lastHitTestResultOverWidget = false;
- m_previousGestureScrolledNode = 0;
- m_scrollbarHandlingScrollGesture = 0;
+ m_previousGestureScrolledNode = nullptr;
+ m_scrollbarHandlingScrollGesture = nullptr;
m_maxMouseMovedDuration = 0;
m_baseEventType = PlatformEvent::NoType;
m_didStartDrag = false;
@@ -393,7 +305,7 @@ void EventHandler::clear()
m_mouseDownMayStartSelect = false;
m_mouseDownMayStartDrag = false;
m_lastShowPressTimestamp = 0;
- m_lastDeferredTapElement = 0;
+ m_lastDeferredTapElement = nullptr;
}
void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
@@ -405,7 +317,7 @@ void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
} else {
// We don't dispatch click events if the mousedown node is removed
// before a mouseup event. It is compatible with IE and Firefox.
- m_clickNode = 0;
+ m_clickNode = nullptr;
}
}
@@ -485,7 +397,7 @@ void EventHandler::selectClosestMisspellingFromHitTestResult(const HitTestResult
Position start = pos.deepEquivalent();
Position end = pos.deepEquivalent();
if (pos.isNotNull()) {
- Vector<DocumentMarker*> markers = innerNode->document().markers()->markersInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
+ WillBeHeapVector<DocumentMarker*> markers = innerNode->document().markers().markersInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
if (markers.size() == 1) {
start.moveToOffset(markers[0]->startOffset());
end.moveToOffset(markers[0]->endOffset());
@@ -536,6 +448,8 @@ void EventHandler::selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHit
bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestResults& event)
{
+ TRACE_EVENT0("webkit", "EventHandler::handleMousePressEventDoubleClick");
+
if (event.event().button() != LeftButton)
return false;
@@ -554,6 +468,8 @@ bool EventHandler::handleMousePressEventDoubleClick(const MouseEventWithHitTestR
bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestResults& event)
{
+ TRACE_EVENT0("webkit", "EventHandler::handleMousePressEventTripleClick");
+
if (event.event().button() != LeftButton)
return false;
@@ -573,12 +489,14 @@ bool EventHandler::handleMousePressEventTripleClick(const MouseEventWithHitTestR
static int textDistance(const Position& start, const Position& end)
{
- RefPtr<Range> range = Range::create(*start.document(), start, end);
+ RefPtrWillBeRawPtr<Range> range = Range::create(*start.document(), start, end);
return TextIterator::rangeLength(range.get(), true);
}
bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestResults& event)
{
+ TRACE_EVENT0("webkit", "EventHandler::handleMousePressEventSingleClick");
+
m_frame->document()->updateLayoutIgnorePendingStylesheets();
Node* innerNode = event.targetNode();
if (!(innerNode && innerNode->renderer() && m_mouseDownMayStartSelect))
@@ -606,7 +524,7 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
TextGranularity granularity = CharacterGranularity;
if (extendSelection && newSelection.isCaretOrRange()) {
- VisibleSelection selectionInUserSelectAll = expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(pos));
+ VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(VisiblePosition(pos))));
if (selectionInUserSelectAll.isRange()) {
if (comparePositions(selectionInUserSelectAll.start(), newSelection.start()) < 0)
pos = selectionInUserSelectAll.start();
@@ -615,16 +533,18 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
}
if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()) {
- // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
- // was created right-to-left
- Position start = newSelection.start();
- Position end = newSelection.end();
- int distanceToStart = textDistance(start, pos);
- int distanceToEnd = textDistance(pos, end);
- if (distanceToStart <= distanceToEnd)
- newSelection = VisibleSelection(end, pos);
- else
- newSelection = VisibleSelection(start, pos);
+ if (pos.isNotNull()) {
+ // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
+ // was created right-to-left
+ Position start = newSelection.start();
+ Position end = newSelection.end();
+ int distanceToStart = textDistance(start, pos);
+ int distanceToEnd = textDistance(pos, end);
+ if (distanceToStart <= distanceToEnd)
+ newSelection = VisibleSelection(end, pos);
+ else
+ newSelection = VisibleSelection(start, pos);
+ }
} else
newSelection.setExtent(pos);
@@ -632,11 +552,13 @@ bool EventHandler::handleMousePressEventSingleClick(const MouseEventWithHitTestR
granularity = m_frame->selection().granularity();
newSelection.expandUsingGranularity(m_frame->selection().granularity());
}
- } else
- newSelection = expandSelectionToRespectUserSelectAll(innerNode, visiblePos);
+ } else {
+ newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(visiblePos));
+ }
- bool handled = updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, granularity);
- return handled;
+ // Updating the selection is considered side-effect of the event and so it doesn't impact the handled state.
+ updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, granularity);
+ return false;
}
static inline bool canMouseDownStartSelect(Node* node)
@@ -652,8 +574,10 @@ static inline bool canMouseDownStartSelect(Node* node)
bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event)
{
+ TRACE_EVENT0("webkit", "EventHandler::handleMousePressEvent");
+
// Reset drag state.
- dragState().m_dragSrc = 0;
+ dragState().m_dragSrc = nullptr;
cancelFakeMouseMoveEvent();
@@ -679,11 +603,10 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
if (event.isOverWidget() && passWidgetMouseDownEventToWidget(event))
return true;
- if (m_frame->document()->isSVGDocument()
- && toSVGDocument(m_frame->document())->zoomAndPanEnabled()) {
+ if (m_frame->document()->isSVGDocument() && m_frame->document()->accessSVGExtensions().zoomAndPanEnabled()) {
if (event.event().shiftKey() && singleClick) {
m_svgPan = true;
- toSVGDocument(m_frame->document())->startPan(m_frame->view()->windowToContents(event.event().position()));
+ m_frame->document()->accessSVGExtensions().startPan(m_frame->view()->windowToContents(event.event().position()));
return true;
}
}
@@ -717,6 +640,8 @@ bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& eve
bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& event)
{
+ TRACE_EVENT0("webkit", "EventHandler::handleMouseDraggedEvent");
+
if (!m_mousePressed)
return false;
@@ -729,7 +654,7 @@ bool EventHandler::handleMouseDraggedEvent(const MouseEventWithHitTestResults& e
RenderObject* renderer = targetNode->renderer();
if (!renderer) {
- Node* parent = EventPath::parent(targetNode);
+ Node* parent = NodeRenderingTraversal::parent(targetNode);
if (!parent)
return false;
@@ -916,11 +841,13 @@ bool EventHandler::panScrollInProgress() const
HitTestResult EventHandler::hitTestResultAtPoint(const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType, const LayoutSize& padding)
{
+ TRACE_EVENT0("webkit", "EventHandler::hitTestResultAtPoint");
+
// We always send hitTestResultAtPoint to the main frame if we have one,
// otherwise we might hit areas that are obscured by higher frames.
if (Page* page = m_frame->page()) {
- Frame* mainFrame = page->mainFrame();
- if (m_frame != mainFrame) {
+ LocalFrame* mainFrame = page->mainFrame()->isLocalFrame() ? page->deprecatedLocalMainFrame() : 0;
+ if (mainFrame && m_frame != mainFrame) {
FrameView* frameView = m_frame->view();
FrameView* mainView = mainFrame->view();
if (frameView && mainView) {
@@ -964,9 +891,12 @@ Node* EventHandler::mousePressNode() const
return m_mousePressNode.get();
}
-bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
+bool EventHandler::scroll(ScrollDirection direction, ScrollGranularity granularity, Node* startNode, Node** stopNode, float delta, IntPoint absolutePoint)
{
- Node* node = startingNode;
+ if (!delta)
+ return false;
+
+ Node* node = startNode;
if (!node)
node = m_frame->document()->focusedElement();
@@ -974,32 +904,48 @@ bool EventHandler::scrollOverflow(ScrollDirection direction, ScrollGranularity g
if (!node)
node = m_mousePressNode.get();
- if (node) {
- RenderObject* r = node->renderer();
- if (r && !r->isListBox() && scrollNode(1.0f, granularity, direction, node, 0)) {
+ if (!node || !node->renderer())
+ return false;
+
+ RenderBox* curBox = node->renderer()->enclosingBox();
+ while (curBox && !curBox->isRenderView()) {
+ ScrollDirection physicalDirection = toPhysicalDirection(
+ direction, curBox->isHorizontalWritingMode(), curBox->style()->isFlippedBlocksWritingMode());
+
+ // If we're at the stopNode, we should try to scroll it but we shouldn't bubble past it
+ bool shouldStopBubbling = stopNode && *stopNode && curBox->node() == *stopNode;
+ bool didScroll = curBox->scroll(physicalDirection, granularity, delta);
+
+ if (didScroll && stopNode)
+ *stopNode = curBox->node();
+
+ if (didScroll || shouldStopBubbling) {
setFrameWasScrolledByUser();
return true;
}
+
+ curBox = curBox->containingBlock();
}
return false;
}
-bool EventHandler::scrollRecursively(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
+bool EventHandler::bubblingScroll(ScrollDirection direction, ScrollGranularity granularity, Node* startingNode)
{
// The layout needs to be up to date to determine if we can scroll. We may be
// here because of an onLoad event, in which case the final layout hasn't been performed yet.
m_frame->document()->updateLayoutIgnorePendingStylesheets();
- if (scrollOverflow(direction, granularity, startingNode))
+ if (scroll(direction, granularity, startingNode))
return true;
- Frame* frame = m_frame;
+ LocalFrame* frame = m_frame;
FrameView* view = frame->view();
if (view && view->scroll(direction, granularity))
return true;
- frame = frame->tree().parent();
- if (!frame)
+ Frame* parentFrame = frame->tree().parent();
+ if (!parentFrame || !parentFrame->isLocalFrame())
return false;
- return frame->eventHandler().scrollRecursively(direction, granularity, m_frame->ownerElement());
+ // FIXME: Broken for OOPI.
+ return toLocalFrame(parentFrame)->eventHandler().bubblingScroll(direction, granularity, m_frame->deprecatedLocalOwner());
}
IntPoint EventHandler::lastKnownMousePosition() const
@@ -1007,7 +953,7 @@ IntPoint EventHandler::lastKnownMousePosition() const
return m_lastKnownMousePosition;
}
-static Frame* subframeForTargetNode(Node* node)
+static LocalFrame* subframeForTargetNode(Node* node)
{
if (!node)
return 0;
@@ -1016,6 +962,10 @@ static Frame* subframeForTargetNode(Node* node)
if (!renderer || !renderer->isWidget())
return 0;
+ // FIXME: This explicit check is needed only until RemoteFrames have RemoteFrameViews.
+ if (isHTMLFrameElementBase(node) && toHTMLFrameElementBase(node)->contentFrame() && toHTMLFrameElementBase(node)->contentFrame()->isRemoteFrameTemporary())
+ return 0;
+
Widget* widget = toRenderWidget(renderer)->widget();
if (!widget || !widget->isFrameView())
return 0;
@@ -1023,7 +973,7 @@ static Frame* subframeForTargetNode(Node* node)
return &toFrameView(widget)->frame();
}
-static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
+static LocalFrame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
{
if (!hitTestResult.isOverWidget())
return 0;
@@ -1032,48 +982,15 @@ static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTe
static bool isSubmitImage(Node* node)
{
- return node && node->hasTagName(inputTag) && toHTMLInputElement(node)->isImageButton();
-}
-
-// Returns true if the node's editable block is not current focused for editing
-static bool nodeIsNotBeingEdited(Node* node, Frame* frame)
-{
- return frame->selection().rootEditableElement() != node->rootEditableElement();
+ return isHTMLInputElement(node) && toHTMLInputElement(node)->isImageButton();
}
-bool EventHandler::useHandCursor(Node* node, bool isOverLink, bool shiftKey)
+bool EventHandler::useHandCursor(Node* node, bool isOverLink)
{
if (!node)
return false;
- bool editable = node->rendererIsEditable();
- bool editableLinkEnabled = false;
-
- // If the link is editable, then we need to check the settings to see whether or not the link should be followed
- if (editable) {
- ASSERT(m_frame->settings());
- switch (m_frame->settings()->editableLinkBehavior()) {
- default:
- case EditableLinkDefaultBehavior:
- case EditableLinkAlwaysLive:
- editableLinkEnabled = true;
- break;
-
- case EditableLinkNeverLive:
- editableLinkEnabled = false;
- break;
-
- case EditableLinkLiveWhenNotFocused:
- editableLinkEnabled = nodeIsNotBeingEdited(node, m_frame) || shiftKey;
- break;
-
- case EditableLinkOnlyLiveWithShiftKey:
- editableLinkEnabled = shiftKey;
- break;
- }
- }
-
- return ((isOverLink || isSubmitImage(node)) && (!editable || editableLinkEnabled));
+ return ((isOverLink || isSubmitImage(node)) && !node->rendererIsEditable());
}
void EventHandler::cursorUpdateTimerFired(Timer<EventHandler>*)
@@ -1097,26 +1014,20 @@ void EventHandler::updateCursor()
if (!renderView)
return;
- bool shiftKey;
- bool ctrlKey;
- bool altKey;
- bool metaKey;
- PlatformKeyboardEvent::getCurrentModifierState(shiftKey, ctrlKey, altKey, metaKey);
-
m_frame->document()->updateLayout();
HitTestRequest request(HitTestRequest::ReadOnly);
HitTestResult result(view->windowToContents(m_lastKnownMousePosition));
renderView->hitTest(request, result);
- OptionalCursor optionalCursor = selectCursor(result, shiftKey);
+ OptionalCursor optionalCursor = selectCursor(result);
if (optionalCursor.isCursorChange()) {
m_currentMouseCursor = optionalCursor.cursor();
view->setCursor(m_currentMouseCursor);
}
}
-OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shiftKey)
+OptionalCursor EventHandler::selectCursor(const HitTestResult& result)
{
if (m_resizeScrollableArea && m_resizeScrollableArea->inResizeMode())
return NoCursorChange;
@@ -1129,9 +1040,9 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
return NoCursorChange;
#endif
- Node* node = result.targetNode();
+ Node* node = result.innerPossiblyPseudoNode();
if (!node)
- return selectAutoCursor(result, node, iBeamCursor(), shiftKey);
+ return selectAutoCursor(result, node, iBeamCursor());
RenderObject* renderer = node->renderer();
RenderStyle* style = renderer ? renderer->style() : 0;
@@ -1182,7 +1093,7 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
case CURSOR_AUTO: {
bool horizontalText = !style || style->isHorizontalWritingMode();
const Cursor& iBeam = horizontalText ? iBeamCursor() : verticalTextCursor();
- return selectAutoCursor(result, node, iBeam, shiftKey);
+ return selectAutoCursor(result, node, iBeam);
}
case CURSOR_CROSS:
return crossCursor();
@@ -1246,9 +1157,9 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
return notAllowedCursor();
case CURSOR_DEFAULT:
return pointerCursor();
- case CURSOR_WEBKIT_ZOOM_IN:
+ case CURSOR_ZOOM_IN:
return zoomInCursor();
- case CURSOR_WEBKIT_ZOOM_OUT:
+ case CURSOR_ZOOM_OUT:
return zoomOutCursor();
case CURSOR_WEBKIT_GRAB:
return grabCursor();
@@ -1258,20 +1169,18 @@ OptionalCursor EventHandler::selectCursor(const HitTestResult& result, bool shif
return pointerCursor();
}
-OptionalCursor EventHandler::selectAutoCursor(const HitTestResult& result, Node* node, const Cursor& iBeam, bool shiftKey)
+OptionalCursor EventHandler::selectAutoCursor(const HitTestResult& result, Node* node, const Cursor& iBeam)
{
bool editable = (node && node->rendererIsEditable());
- if (useHandCursor(node, result.isOverLink(), shiftKey))
+ if (useHandCursor(node, result.isOverLink()))
return handCursor();
bool inResizer = false;
RenderObject* renderer = node ? node->renderer() : 0;
- if (renderer) {
- if (RenderLayer* layer = renderer->enclosingLayer()) {
- if (m_frame->view())
- inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointInResizeControl(result.roundedPointInMainFrame(), ResizerForPointer);
- }
+ if (renderer && m_frame->view()) {
+ RenderLayer* layer = renderer->enclosingLayer();
+ inResizer = layer->scrollableArea() && layer->scrollableArea()->isPointInResizeControl(result.roundedPointInMainFrame(), ResizerForPointer);
}
// During selection, use an I-beam no matter what we're over.
@@ -1288,7 +1197,7 @@ OptionalCursor EventHandler::selectAutoCursor(const HitTestResult& result, Node*
return pointerCursor();
}
-static LayoutPoint documentPointForWindowPoint(Frame* frame, const IntPoint& windowPoint)
+static LayoutPoint documentPointForWindowPoint(LocalFrame* frame, const IntPoint& windowPoint)
{
FrameView* view = frame->view();
// FIXME: Is it really OK to use the wrong coordinates here when view is 0?
@@ -1298,18 +1207,16 @@ static LayoutPoint documentPointForWindowPoint(Frame* frame, const IntPoint& win
bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
{
- RefPtr<FrameView> protector(m_frame->view());
+ TRACE_EVENT0("webkit", "EventHandler::handleMousePressEvent");
- bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
- if (defaultPrevented)
- return true;
+ RefPtr<FrameView> protector(m_frame->view());
UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
- m_frame->tree().top()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken();
+ m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken = gestureIndicator.currentToken();
cancelFakeMouseMoveEvent();
if (m_eventHandlerWillResetCapturingMouseEventsNode)
- m_capturingMouseEventsNode = 0;
+ m_capturingMouseEventsNode = nullptr;
m_mousePressed = true;
m_capturesDragging = true;
setLastKnownMousePosition(mouseEvent);
@@ -1341,7 +1248,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
m_mousePressNode = mev.targetNode();
- RefPtr<Frame> subframe = subframeForHitTestResult(mev);
+ RefPtr<LocalFrame> subframe = subframeForHitTestResult(mev);
if (subframe && passMousePressEventToSubframe(mev, subframe.get())) {
// Start capturing future events for this frame. We only do this if we didn't clear
// the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
@@ -1368,7 +1275,7 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
#endif
m_clickCount = mouseEvent.clickCount();
- m_clickNode = mev.targetNode()->isTextNode() ? mev.targetNode()->parentOrShadowHostNode() : mev.targetNode();
+ m_clickNode = mev.targetNode()->isTextNode() ? NodeRenderingTraversal::parent(mev.targetNode()) : mev.targetNode();
if (FrameView* view = m_frame->view()) {
RenderLayer* layer = mev.targetNode()->renderer() ? mev.targetNode()->renderer()->enclosingLayer() : 0;
@@ -1384,7 +1291,8 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
m_frame->selection().setCaretBlinkingSuspended(true);
- bool swallowEvent = !dispatchMouseEvent(EventTypeNames::mousedown, mev.targetNode(), true, m_clickCount, mouseEvent, true);
+ bool swallowEvent = !dispatchMouseEvent(EventTypeNames::mousedown, mev.targetNode(), m_clickCount, mouseEvent, true);
+ swallowEvent = swallowEvent || !handleMouseFocus(mouseEvent);
m_capturesDragging = !swallowEvent || mev.scrollbar();
// If the hit testing originally determined the event was in a scrollbar, refetch the MouseEventWithHitTestResults
@@ -1394,31 +1302,19 @@ bool EventHandler::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get())
- m_lastScrollbarUnderMouse = 0;
+ m_lastScrollbarUnderMouse = nullptr;
}
if (swallowEvent) {
// scrollbars should get events anyway, even disabled controls might be scrollable
- Scrollbar* scrollbar = mev.scrollbar();
-
- updateLastScrollbarUnderMouse(scrollbar, true);
-
- if (scrollbar)
- passMousePressEventToScrollbar(mev, scrollbar);
+ passMousePressEventToScrollbar(mev);
} else {
if (shouldRefetchEventTarget(mev)) {
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
}
- FrameView* view = m_frame->view();
- Scrollbar* scrollbar = view ? view->scrollbarAtPoint(mouseEvent.position()) : 0;
- if (!scrollbar)
- scrollbar = mev.scrollbar();
-
- updateLastScrollbarUnderMouse(scrollbar, true);
-
- if (scrollbar && passMousePressEventToScrollbar(mev, scrollbar))
+ if (passMousePressEventToScrollbar(mev))
swallowEvent = true;
else
swallowEvent = handleMousePressEvent(mev);
@@ -1445,13 +1341,9 @@ static RenderLayer* layerForNode(Node* node)
ScrollableArea* EventHandler::associatedScrollableArea(const RenderLayer* layer) const
{
- ScrollableArea* layerScrollableArea = layer->scrollableArea();
- if (!layerScrollableArea)
- return 0;
-
- if (FrameView* frameView = m_frame->view()) {
- if (frameView->containsScrollableArea(layerScrollableArea))
- return layerScrollableArea;
+ if (RenderLayerScrollableArea* scrollableArea = layer->scrollableArea()) {
+ if (scrollableArea->scrollsOverflow())
+ return scrollableArea;
}
return 0;
@@ -1459,6 +1351,8 @@ ScrollableArea* EventHandler::associatedScrollableArea(const RenderLayer* layer)
bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& event)
{
+ TRACE_EVENT0("webkit", "EventHandler::handleMouseMoveEvent");
+
RefPtr<FrameView> protector(m_frame->view());
MaximumDurationTracker maxDurationTracker(&m_maxMouseMovedDuration);
@@ -1486,27 +1380,17 @@ bool EventHandler::handleMouseMoveEvent(const PlatformMouseEvent& event)
void EventHandler::handleMouseLeaveEvent(const PlatformMouseEvent& event)
{
+ TRACE_EVENT0("webkit", "EventHandler::handleMouseLeaveEvent");
+
RefPtr<FrameView> protector(m_frame->view());
handleMouseMoveOrLeaveEvent(event);
}
-static Cursor& syntheticTouchCursor()
-{
- DEFINE_STATIC_LOCAL(Cursor, c, (Image::loadPlatformResource("syntheticTouchCursor").get(), IntPoint(10, 10)));
- return c;
-}
-
bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEvent, HitTestResult* hoveredNode, bool onlyUpdateScrollbars)
{
ASSERT(m_frame);
ASSERT(m_frame->view());
- bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
- if (defaultPrevented) {
- m_frame->view()->setCursor(syntheticTouchCursor());
- return true;
- }
-
setLastKnownMousePosition(mouseEvent);
if (m_hoverTimer.isActive())
@@ -1517,12 +1401,12 @@ bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv
cancelFakeMouseMoveEvent();
if (m_svgPan) {
- toSVGDocument(m_frame->document())->updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
+ m_frame->document()->accessSVGExtensions().updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
return true;
}
if (m_frameSetBeingResized)
- return !dispatchMouseEvent(EventTypeNames::mousemove, m_frameSetBeingResized.get(), false, 0, mouseEvent, false);
+ return !dispatchMouseEvent(EventTypeNames::mousemove, m_frameSetBeingResized.get(), 0, mouseEvent, false);
// Send events right to a scrollbar if the mouse is pressed.
if (m_lastScrollbarUnderMouse && m_mousePressed) {
@@ -1569,7 +1453,7 @@ bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv
}
bool swallowEvent = false;
- RefPtr<Frame> newSubframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
+ RefPtr<LocalFrame> newSubframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
// We want mouseouts to happen first, from the inside out. First send a move event to the last subframe so that it will fire mouseouts.
if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isDescendantOf(m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
@@ -1587,7 +1471,7 @@ bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv
if (scrollbar && !m_mousePressed)
scrollbar->mouseMoved(mouseEvent); // Handle hover effects on platforms that support visual feedback on scrollbar hovering.
if (FrameView* view = m_frame->view()) {
- OptionalCursor optionalCursor = selectCursor(mev.hitTestResult(), mouseEvent.shiftKey());
+ OptionalCursor optionalCursor = selectCursor(mev.hitTestResult());
if (optionalCursor.isCursorChange()) {
m_currentMouseCursor = optionalCursor.cursor();
view->setCursor(m_currentMouseCursor);
@@ -1600,7 +1484,7 @@ bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv
if (swallowEvent)
return true;
- swallowEvent = !dispatchMouseEvent(EventTypeNames::mousemove, mev.targetNode(), false, 0, mouseEvent, true);
+ swallowEvent = !dispatchMouseEvent(EventTypeNames::mousemove, mev.targetNode(), 0, mouseEvent, true);
if (!swallowEvent)
swallowEvent = handleMouseDraggedEvent(mev);
@@ -1610,7 +1494,7 @@ bool EventHandler::handleMouseMoveOrLeaveEvent(const PlatformMouseEvent& mouseEv
void EventHandler::invalidateClick()
{
m_clickCount = 0;
- m_clickNode = 0;
+ m_clickNode = nullptr;
}
static Node* parentForClickEvent(const Node& node)
@@ -1619,23 +1503,21 @@ static Node* parentForClickEvent(const Node& node)
// controls.
if (node.isHTMLElement() && toHTMLElement(node).isInteractiveContent())
return 0;
- return node.parentOrShadowHostNode();
+ return NodeRenderingTraversal::parent(&node);
}
bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
{
+ TRACE_EVENT0("webkit", "EventHandler::handleMouseReleaseEvent");
+
RefPtr<FrameView> protector(m_frame->view());
m_frame->selection().setCaretBlinkingSuspended(false);
- bool defaultPrevented = dispatchSyntheticTouchEventIfEnabled(mouseEvent);
- if (defaultPrevented)
- return true;
-
OwnPtr<UserGestureIndicator> gestureIndicator;
- if (m_frame->tree().top()->eventHandler().m_lastMouseDownUserGestureToken)
- gestureIndicator = adoptPtr(new UserGestureIndicator(m_frame->tree().top()->eventHandler().m_lastMouseDownUserGestureToken.release()));
+ if (m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken)
+ gestureIndicator = adoptPtr(new UserGestureIndicator(m_frame->localFrameRoot()->eventHandler().m_lastMouseDownUserGestureToken.release()));
else
gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessingUserGesture));
@@ -1649,19 +1531,18 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
if (m_svgPan) {
m_svgPan = false;
- toSVGDocument(m_frame->document())->updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
+ m_frame->document()->accessSVGExtensions().updatePan(m_frame->view()->windowToContents(m_lastKnownMousePosition));
return true;
}
if (m_frameSetBeingResized)
- return !dispatchMouseEvent(EventTypeNames::mouseup, m_frameSetBeingResized.get(), true, m_clickCount, mouseEvent, false);
+ return !dispatchMouseEvent(EventTypeNames::mouseup, m_frameSetBeingResized.get(), m_clickCount, mouseEvent, false);
if (m_lastScrollbarUnderMouse) {
invalidateClick();
m_lastScrollbarUnderMouse->mouseUp(mouseEvent);
- bool cancelable = true;
bool setUnder = false;
- return !dispatchMouseEvent(EventTypeNames::mouseup, m_lastNodeUnderMouse.get(), cancelable, m_clickCount, mouseEvent, setUnder);
+ return !dispatchMouseEvent(EventTypeNames::mouseup, m_lastNodeUnderMouse.get(), m_clickCount, mouseEvent, setUnder);
}
HitTestRequest::HitTestRequestType hitType = HitTestRequest::Release | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent;
@@ -1669,13 +1550,13 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
hitType |= HitTestRequest::ReadOnly;
HitTestRequest request(hitType);
MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
- Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
+ LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
if (m_eventHandlerWillResetCapturingMouseEventsNode)
- m_capturingMouseEventsNode = 0;
+ m_capturingMouseEventsNode = nullptr;
if (subframe && passMouseReleaseEventToSubframe(mev, subframe))
return true;
- bool swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, mev.targetNode(), true, m_clickCount, mouseEvent, false);
+ bool swallowMouseUpEvent = !dispatchMouseEvent(EventTypeNames::mouseup, mev.targetNode(), m_clickCount, mouseEvent, false);
bool contextMenuEvent = mouseEvent.button() == RightButton;
#if OS(MACOSX)
@@ -1687,7 +1568,7 @@ bool EventHandler::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
bool swallowClickEvent = false;
if (m_clickCount > 0 && !contextMenuEvent && mev.targetNode() && m_clickNode) {
if (Node* clickTargetNode = mev.targetNode()->commonAncestor(*m_clickNode, parentForClickEvent))
- swallowClickEvent = !dispatchMouseEvent(EventTypeNames::click, clickTargetNode, true, m_clickCount, mouseEvent, true);
+ swallowClickEvent = !dispatchMouseEvent(EventTypeNames::click, clickTargetNode, m_clickCount, mouseEvent, true);
}
if (m_resizeScrollableArea) {
@@ -1744,27 +1625,27 @@ bool EventHandler::dispatchDragEvent(const AtomicString& eventType, Node* dragTa
if (!view)
return false;
- view->resetDeferredRepaintDelay();
- RefPtr<MouseEvent> me = MouseEvent::create(eventType,
+ RefPtrWillBeRawPtr<MouseEvent> me = MouseEvent::create(eventType,
true, true, m_frame->document()->domWindow(),
0, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
event.movementDelta().x(), event.movementDelta().y(),
event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
- 0, 0, clipboard);
+ 0, nullptr, clipboard);
dragTarget->dispatchEvent(me.get(), IGNORE_EXCEPTION);
return me->defaultPrevented();
}
-static bool targetIsFrame(Node* target, Frame*& frame)
+static bool targetIsFrame(Node* target, LocalFrame*& frame)
{
- if (!target)
+ if (!isHTMLFrameElementBase(target))
return false;
- if (!target->hasTagName(frameTag) && !target->hasTagName(iframeTag))
+ // Cross-process drag and drop is not yet supported.
+ if (toHTMLFrameElementBase(target)->contentFrame() && !toHTMLFrameElementBase(target)->contentFrame()->isLocalFrame())
return false;
- frame = toHTMLFrameElementBase(target)->contentFrame();
+ frame = toLocalFrame(toHTMLFrameElementBase(target)->contentFrame());
return true;
}
@@ -1785,7 +1666,7 @@ static bool findDropZone(Node* target, Clipboard* clipboard)
continue;
DragOperation dragOperation = DragOperationNone;
- for (unsigned int i = 0; i < keywords.size(); i++) {
+ for (unsigned i = 0; i < keywords.size(); i++) {
DragOperation op = convertDropZoneOperationToDragOperation(keywords[i]);
if (op != DragOperationNone) {
if (dragOperation == DragOperationNone)
@@ -1815,9 +1696,9 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);
// Drag events should never go to text nodes (following IE, and proper mouseover/out dispatch)
- RefPtr<Node> newTarget = mev.targetNode();
+ RefPtrWillBeRawPtr<Node> newTarget = mev.targetNode();
if (newTarget && newTarget->isTextNode())
- newTarget = EventPath::parent(newTarget.get());
+ newTarget = NodeRenderingTraversal::parent(newTarget.get());
if (AutoscrollController* controller = autoscrollController())
controller->updateDragAndDrop(newTarget.get(), event.position(), event.timestamp());
@@ -1828,7 +1709,7 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
// LayoutTests/fast/events/drag-in-frames.html.
//
// Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <http://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>.
- Frame* targetFrame;
+ LocalFrame* targetFrame;
if (targetIsFrame(newTarget.get(), targetFrame)) {
if (targetFrame)
accept = targetFrame->eventHandler().updateDragAndDrop(event, clipboard);
@@ -1855,7 +1736,7 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
m_shouldOnlyFireDragOverEvent = true;
}
} else {
- Frame* targetFrame;
+ LocalFrame* targetFrame;
if (targetIsFrame(newTarget.get(), targetFrame)) {
if (targetFrame)
accept = targetFrame->eventHandler().updateDragAndDrop(event, clipboard);
@@ -1878,7 +1759,7 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard*
void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
{
- Frame* targetFrame;
+ LocalFrame* targetFrame;
if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
if (targetFrame)
targetFrame->eventHandler().cancelDragAndDrop(event, clipboard);
@@ -1892,7 +1773,7 @@ void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard*
bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
{
- Frame* targetFrame;
+ LocalFrame* targetFrame;
bool preventedDefault = false;
if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
if (targetFrame)
@@ -1906,12 +1787,12 @@ bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard
void EventHandler::clearDragState()
{
stopAutoscroll();
- m_dragTarget = 0;
- m_capturingMouseEventsNode = 0;
+ m_dragTarget = nullptr;
+ m_capturingMouseEventsNode = nullptr;
m_shouldOnlyFireDragOverEvent = false;
}
-void EventHandler::setCapturingMouseEventsNode(PassRefPtr<Node> n)
+void EventHandler::setCapturingMouseEventsNode(PassRefPtrWillBeRawPtr<Node> n)
{
m_capturingMouseEventsNode = n;
m_eventHandlerWillResetCapturingMouseEventsNode = false;
@@ -1925,22 +1806,6 @@ MouseEventWithHitTestResults EventHandler::prepareMouseEvent(const HitTestReques
return m_frame->document()->prepareMouseEvent(request, documentPointForWindowPoint(m_frame, mev.position()), mev);
}
-static inline SVGElementInstance* instanceAssociatedWithShadowTreeElement(Node* referenceNode)
-{
- if (!referenceNode || !referenceNode->isSVGElement())
- return 0;
-
- ShadowRoot* shadowRoot = referenceNode->containingShadowRoot();
- if (!shadowRoot)
- return 0;
-
- Element* shadowTreeParentElement = shadowRoot->host();
- if (!shadowTreeParentElement || !shadowTreeParentElement->hasTagName(useTag))
- return 0;
-
- return toSVGUseElement(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode);
-}
-
void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMouseEvent& mouseEvent, bool fireMouseOverOut)
{
Node* result = targetNode;
@@ -1951,41 +1816,9 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
else {
// If the target node is a text node, dispatch on the parent node - rdar://4196646
if (result && result->isTextNode())
- result = EventPath::parent(result);
+ result = NodeRenderingTraversal::parent(result);
}
m_nodeUnderMouse = result;
- m_instanceUnderMouse = instanceAssociatedWithShadowTreeElement(result);
-
- // <use> shadow tree elements may have been recloned, update node under mouse in any case
- if (m_lastInstanceUnderMouse) {
- SVGElement* lastCorrespondingElement = m_lastInstanceUnderMouse->correspondingElement();
- SVGElement* lastCorrespondingUseElement = m_lastInstanceUnderMouse->correspondingUseElement();
-
- if (lastCorrespondingElement && lastCorrespondingUseElement) {
- HashSet<SVGElementInstance*> instances = lastCorrespondingElement->instancesForElement();
-
- // Locate the recloned shadow tree element for our corresponding instance
- HashSet<SVGElementInstance*>::iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::iterator it = instances.begin(); it != end; ++it) {
- SVGElementInstance* instance = (*it);
- ASSERT(instance->correspondingElement() == lastCorrespondingElement);
-
- if (instance == m_lastInstanceUnderMouse)
- continue;
-
- if (instance->correspondingUseElement() != lastCorrespondingUseElement)
- continue;
-
- SVGElement* shadowTreeElement = instance->shadowTreeElement();
- if (!shadowTreeElement->inDocument() || m_lastNodeUnderMouse == shadowTreeElement)
- continue;
-
- m_lastNodeUnderMouse = shadowTreeElement;
- m_lastInstanceUnderMouse = instance;
- break;
- }
- }
- }
// Fire mouseout/mouseover if the mouse has shifted to a different node.
if (fireMouseOverOut) {
@@ -1995,7 +1828,7 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
if (m_lastNodeUnderMouse && (!m_nodeUnderMouse || m_nodeUnderMouse->document() != m_frame->document())) {
// The mouse has moved between frames.
- if (Frame* frame = m_lastNodeUnderMouse->document().frame()) {
+ if (LocalFrame* frame = m_lastNodeUnderMouse->document().frame()) {
if (FrameView* frameView = frame->view())
frameView->mouseExitedContentArea();
}
@@ -2007,7 +1840,7 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
if (m_nodeUnderMouse && (!m_lastNodeUnderMouse || m_lastNodeUnderMouse->document() != m_frame->document())) {
// The mouse has moved between frames.
- if (Frame* frame = m_nodeUnderMouse->document().frame()) {
+ if (LocalFrame* frame = m_nodeUnderMouse->document().frame()) {
if (FrameView* frameView = frame->view())
frameView->mouseEnteredContentArea();
}
@@ -2018,9 +1851,8 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
}
if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
- m_lastNodeUnderMouse = 0;
- m_lastScrollbarUnderMouse = 0;
- m_lastInstanceUnderMouse = 0;
+ m_lastNodeUnderMouse = nullptr;
+ m_lastScrollbarUnderMouse = nullptr;
}
if (m_lastNodeUnderMouse != m_nodeUnderMouse) {
@@ -2032,25 +1864,19 @@ void EventHandler::updateMouseEventTargetNode(Node* targetNode, const PlatformMo
m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, EventTypeNames::mouseover, 0, m_lastNodeUnderMouse.get());
}
m_lastNodeUnderMouse = m_nodeUnderMouse;
- m_lastInstanceUnderMouse = instanceAssociatedWithShadowTreeElement(m_nodeUnderMouse.get());
}
}
-bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, bool /*cancelable*/, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
+// The return value means 'continue default handling.'
+bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targetNode, int clickCount, const PlatformMouseEvent& mouseEvent, bool setUnder)
{
- if (FrameView* view = m_frame->view())
- view->resetDeferredRepaintDelay();
-
updateMouseEventTargetNode(targetNode, mouseEvent, setUnder);
+ return !m_nodeUnderMouse || m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount);
+}
- bool swallowEvent = false;
-
- if (m_nodeUnderMouse)
- swallowEvent = !(m_nodeUnderMouse->dispatchMouseEvent(mouseEvent, eventType, clickCount));
-
- if (swallowEvent || eventType != EventTypeNames::mousedown)
- return !swallowEvent;
-
+// The return value means 'continue default handling.'
+bool EventHandler::handleMouseFocus(const PlatformMouseEvent& mouseEvent)
+{
// If clicking on a frame scrollbar, do not mess up with content focus.
if (FrameView* view = m_frame->view()) {
if (view->scrollbarAtPoint(mouseEvent.position()))
@@ -2065,7 +1891,7 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
element = m_nodeUnderMouse->isElementNode() ? toElement(m_nodeUnderMouse) : m_nodeUnderMouse->parentOrShadowHostElement();
for (; element; element = element->parentOrShadowHostElement()) {
if (element->isFocusable() && element->focused())
- return !swallowEvent;
+ return true;
if (element->isMouseFocusable())
break;
}
@@ -2092,19 +1918,19 @@ bool EventHandler::dispatchMouseEvent(const AtomicString& eventType, Node* targe
// clear swallowEvent if the page already set it (e.g., by canceling
// default behavior).
if (element) {
- if (!page->focusController().setFocusedElement(element, m_frame, FocusDirectionMouse))
- swallowEvent = true;
+ if (!page->focusController().setFocusedElement(element, m_frame, FocusTypeMouse))
+ return false;
} else {
// We call setFocusedElement even with !element in order to blur
// current focus element when a link is clicked; this is expected by
// some sites that rely on onChange handlers running from form
// fields before the button click is processed.
if (!page->focusController().setFocusedElement(0, m_frame))
- swallowEvent = true;
+ return false;
}
}
- return !swallowEvent;
+ return true;
}
bool EventHandler::isInsideScrollbar(const IntPoint& windowPoint) const
@@ -2119,19 +1945,7 @@ bool EventHandler::isInsideScrollbar(const IntPoint& windowPoint) const
return false;
}
-bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult& result, const PlatformWheelEvent& event) const
-{
-#if OS(ANDROID) || OS(MACOSX) || OS(WIN)
- return false;
-#else
- // GTK+ must scroll horizontally if the mouse pointer is on top of the
- // horizontal scrollbar while scrolling with the wheel.
- // This code comes from gtk/EventHandlerGtk.cpp.
- return !event.hasPreciseScrollingDeltas() && result.scrollbar() && result.scrollbar()->orientation() == HorizontalScrollbar;
-#endif
-}
-
-bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
+bool EventHandler::handleWheelEvent(const PlatformWheelEvent& event)
{
#define RETURN_WHEEL_EVENT_HANDLED() \
{ \
@@ -2141,7 +1955,7 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
Document* doc = m_frame->document();
- if (!doc->renderer())
+ if (!doc->renderView())
return false;
RefPtr<FrameView> protector(m_frame->view());
@@ -2150,10 +1964,7 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
if (!view)
return false;
- if (handleWheelEventAsEmulatedGesture(e))
- return true;
-
- LayoutPoint vPoint = view->windowToContents(e.position());
+ LayoutPoint vPoint = view->windowToContents(event.position());
HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
HitTestResult result(vPoint);
@@ -2162,10 +1973,10 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
Node* node = result.innerNode();
// Wheel events should not dispatch to text nodes.
if (node && node->isTextNode())
- node = EventPath::parent(node);
+ node = NodeRenderingTraversal::parent(node);
bool isOverWidget;
- if (e.useLatchedEventNode()) {
+ if (event.useLatchedEventNode()) {
if (!m_latchedWheelEventNode) {
m_latchedWheelEventNode = node;
m_widgetIsLatched = result.isOverWidget();
@@ -2175,27 +1986,20 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
isOverWidget = m_widgetIsLatched;
} else {
if (m_latchedWheelEventNode)
- m_latchedWheelEventNode = 0;
+ m_latchedWheelEventNode = nullptr;
if (m_previousWheelScrolledNode)
- m_previousWheelScrolledNode = 0;
+ m_previousWheelScrolledNode = nullptr;
isOverWidget = result.isOverWidget();
}
- // FIXME: It should not be necessary to do this mutation here.
- // Instead, the handlers should know convert vertical scrolls
- // appropriately.
- PlatformWheelEvent event = e;
- if (m_baseEventType == PlatformEvent::NoType && shouldTurnVerticalTicksIntoHorizontal(result, e))
- event = event.copyTurningVerticalTicksIntoHorizontalTicks();
-
if (node) {
// Figure out which view to send the event to.
RenderObject* target = node->renderer();
if (isOverWidget && target && target->isWidget()) {
Widget* widget = toRenderWidget(target)->widget();
- if (widget && passWheelEventToWidget(e, widget))
+ if (widget && passWheelEventToWidget(event, widget))
RETURN_WHEEL_EVENT_HANDLED();
}
@@ -2203,7 +2007,6 @@ bool EventHandler::handleWheelEvent(const PlatformWheelEvent& e)
RETURN_WHEEL_EVENT_HANDLED();
}
-
// We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
view = m_frame->view();
if (!view || !view->wheelEvent(event))
@@ -2219,15 +2022,19 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv
if (!startNode || !wheelEvent)
return;
+ // Ctrl + scrollwheel is reserved for triggering zoom in/out actions in Chromium.
+ if (wheelEvent->ctrlKey())
+ return;
+
Node* stopNode = m_previousWheelScrolledNode.get();
ScrollGranularity granularity = wheelGranularityToScrollGranularity(wheelEvent->deltaMode());
// Break up into two scrolls if we need to. Diagonal movement on
// a MacBook pro is an example of a 2-dimensional mouse wheel event (where both deltaX and deltaY can be set).
- if (scrollNode(wheelEvent->deltaX(), granularity, ScrollRight, startNode, &stopNode, roundedIntPoint(wheelEvent->absoluteLocation())))
+ if (scroll(ScrollRight, granularity, startNode, &stopNode, wheelEvent->deltaX(), roundedIntPoint(wheelEvent->absoluteLocation())))
wheelEvent->setDefaultHandled();
- if (scrollNode(wheelEvent->deltaY(), granularity, ScrollDown, startNode, &stopNode, roundedIntPoint(wheelEvent->absoluteLocation())))
+ if (scroll(ScrollDown, granularity, startNode, &stopNode, wheelEvent->deltaY(), roundedIntPoint(wheelEvent->absoluteLocation())))
wheelEvent->setDefaultHandled();
if (!m_latchedWheelEventNode)
@@ -2258,7 +2065,7 @@ bool EventHandler::handleGestureShowPress()
bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
{
IntPoint adjustedPoint = gestureEvent.position();
- RefPtr<Frame> subframe = 0;
+ RefPtr<LocalFrame> subframe = nullptr;
switch (gestureEvent.type()) {
case PlatformEvent::GestureScrollBegin:
case PlatformEvent::GestureScrollUpdate:
@@ -2289,8 +2096,8 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
ASSERT_NOT_REACHED();
}
- Node* eventTarget = 0;
- Scrollbar* scrollbar = 0;
+ RefPtrWillBeRawPtr<Node> eventTarget = nullptr;
+ RefPtr<Scrollbar> scrollbar;
if (gestureEvent.type() == PlatformEvent::GestureScrollEnd
|| gestureEvent.type() == PlatformEvent::GestureScrollUpdate
|| gestureEvent.type() == PlatformEvent::GestureScrollUpdateWithoutPropagation
@@ -2308,12 +2115,13 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
} else if (gestureEvent.type() == PlatformEvent::GestureTapDownCancel) {
hitType |= HitTestRequest::Release;
// A TapDownCancel received when no element is active shouldn't really be changing hover state.
- if (!m_frame->document()->activeElement())
+ if (!m_frame->document()->activeHoverElement())
hitType |= HitTestRequest::ReadOnly;
} else if (gestureEvent.type() == PlatformEvent::GestureTap) {
hitType |= HitTestRequest::Release;
- // If the Tap is received very shortly after ShowPress, we want to delay clearing
- // of the active state so that it's visible to the user for at least one frame.
+ // If the Tap is received very shortly after ShowPress, we want to
+ // delay clearing of the active state so that it's visible to the user
+ // for at least a couple of frames.
activeInterval = WTF::currentTime() - m_lastShowPressTimestamp;
shouldKeepActiveForMinInterval = m_lastShowPressTimestamp && activeInterval < minimumActiveInterval;
if (shouldKeepActiveForMinInterval)
@@ -2328,7 +2136,7 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
if (shouldKeepActiveForMinInterval) {
m_lastDeferredTapElement = result.innerElement();
- m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterval);
+ m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterval, FROM_HERE);
}
eventTarget = result.targetNode();
@@ -2347,7 +2155,7 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
} else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd
|| gestureEvent.type() == PlatformEvent::GestureFlingStart
|| !eventSwallowed) {
- m_scrollbarHandlingScrollGesture = 0;
+ m_scrollbarHandlingScrollGesture = nullptr;
}
if (eventSwallowed)
@@ -2356,7 +2164,7 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
if (eventTarget) {
bool eventSwallowed = false;
- if (handleScrollGestureOnResizer(eventTarget, gestureEvent))
+ if (handleScrollGestureOnResizer(eventTarget.get(), gestureEvent))
eventSwallowed = true;
else
eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent);
@@ -2454,7 +2262,7 @@ bool EventHandler::handleGestureLongPress(const PlatformGestureEvent& gestureEve
MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragEvent);
m_didStartDrag = false;
m_mouseDownMayStartDrag = true;
- dragState().m_dragSrc = 0;
+ dragState().m_dragSrc = nullptr;
m_mouseDownPos = m_frame->view()->windowToContents(mouseDragEvent.position());
RefPtr<FrameView> protector(m_frame->view());
handleDrag(mev, DontCheckDragHysteresis);
@@ -2547,13 +2355,11 @@ bool EventHandler::passGestureEventToWidgetIfPossible(const PlatformGestureEvent
}
bool EventHandler::handleGestureScrollEnd(const PlatformGestureEvent& gestureEvent) {
- RefPtr<Node> node = m_scrollGestureHandlingNode;
+ RefPtrWillBeRawPtr<Node> node = m_scrollGestureHandlingNode;
clearGestureScrollNodes();
- if (node) {
- ASSERT(node->refCount() > 0);
+ if (node)
passGestureEventToWidgetIfPossible(gestureEvent, node->renderer());
- }
return false;
}
@@ -2575,7 +2381,7 @@ bool EventHandler::handleGestureScrollBegin(const PlatformGestureEvent& gestureE
m_lastHitTestResultOverWidget = result.isOverWidget();
m_scrollGestureHandlingNode = result.innerNode();
- m_previousGestureScrolledNode = 0;
+ m_previousGestureScrolledNode = nullptr;
// If there's no renderer on the node, send the event to the nearest ancestor with a renderer.
// Needed for <option> and <optgroup> elements so we can touch scroll <select>s
@@ -2626,8 +2432,8 @@ bool EventHandler::handleGestureScrollUpdate(const PlatformGestureEvent& gesture
// First try to scroll the closest scrollable RenderBox ancestor of |node|.
ScrollGranularity granularity = ScrollByPixel;
- bool horizontalScroll = scrollNode(delta.width(), granularity, ScrollLeft, node, &stopNode);
- bool verticalScroll = scrollNode(delta.height(), granularity, ScrollUp, node, &stopNode);
+ bool horizontalScroll = scroll(ScrollLeft, granularity, node, &stopNode, delta.width());
+ bool verticalScroll = scroll(ScrollUp, granularity, node, &stopNode, delta.height());
if (scrollShouldNotPropagate)
m_previousGestureScrolledNode = stopNode;
@@ -2664,7 +2470,7 @@ bool EventHandler::sendScrollEventToView(const PlatformGestureEvent& gestureEven
return scrolledFrame;
}
-Frame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent& gestureEvent)
+LocalFrame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent& gestureEvent)
{
PlatformMouseEvent mouseDown(touchAdjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, 1,
gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
@@ -2675,8 +2481,8 @@ Frame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoi
void EventHandler::clearGestureScrollNodes()
{
- m_scrollGestureHandlingNode = 0;
- m_previousGestureScrolledNode = 0;
+ m_scrollGestureHandlingNode = nullptr;
+ m_previousGestureScrolledNode = nullptr;
}
bool EventHandler::isScrollbarHandlingGestures() const
@@ -2691,7 +2497,6 @@ bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event)
return !event.area().isEmpty();
}
-
bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode)
{
IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
@@ -2704,7 +2509,7 @@ bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, c
return false;
IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
- Vector<RefPtr<Node>, 11> nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
copyToVector(result.rectBasedTestResult(), nodes);
// FIXME: Should be able to handle targetNode being a shadow DOM node to avoid performing uncessary hit tests
@@ -2712,9 +2517,10 @@ bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, c
// regression in touchadjustment/html-label.html. Some refinement is required to testing/internals to
// handle targetNode being a shadow DOM node.
- // FIXME: the explicit Vector conversion copies into a temporary and is
- // wasteful.
- bool success = findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, Vector<RefPtr<Node> > (nodes));
+ // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
+ // FIXME: targetNode and success are only used by Internals functions. We should
+ // instead have dedicated test methods so we only do this work in tests.
+ bool success = findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> > (nodes));
if (success && targetNode)
targetNode = targetNode->deprecatedShadowAncestorNode();
return success;
@@ -2726,12 +2532,11 @@ bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter,
HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active, touchRadius);
IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
- Vector<RefPtr<Node>, 11> nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
copyToVector(result.rectBasedTestResult(), nodes);
- // FIXME: the explicit Vector conversion copies into a temporary and is
- // wasteful.
- return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, touchRect, Vector<RefPtr<Node> >(nodes));
+ // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
+ return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
}
bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)
@@ -2740,18 +2545,17 @@ bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, co
HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent, touchRadius);
IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
- Vector<RefPtr<Node>, 11> nodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node>, 11> nodes;
copyToVector(result.rectBasedTestResult(), nodes);
- // FIXME: the explicit Vector conversion copies into a temporary and is
- // wasteful.
- return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, Vector<RefPtr<Node> >(nodes));
+ // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
+ return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, WillBeHeapVector<RefPtrWillBeMember<Node> >(nodes));
}
-bool EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEvent, IntPoint& adjustedPoint)
+void EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEvent, IntPoint& adjustedPoint)
{
if (!shouldApplyTouchAdjustment(gestureEvent))
- return false;
+ return;
Node* targetNode = 0;
switch (gestureEvent.type()) {
@@ -2770,7 +2574,6 @@ bool EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEven
// FIXME: Implement handling for other types as needed.
ASSERT_NOT_REACHED();
}
- return targetNode;
}
bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
@@ -2782,7 +2585,6 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
// Clear mouse press state to avoid initiating a drag while context menu is up.
m_mousePressed = false;
- bool swallowEvent;
LayoutPoint viewportPos = v->windowToContents(event.position());
HitTestRequest request(HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
MouseEventWithHitTestResults mev = doc->prepareMouseEvent(request, viewportPos, event);
@@ -2801,9 +2603,7 @@ bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
selectClosestWordOrLinkFromMouseEvent(mev);
}
- swallowEvent = !dispatchMouseEvent(EventTypeNames::contextmenu, mev.targetNode(), true, 0, event, false);
-
- return swallowEvent;
+ return !dispatchMouseEvent(EventTypeNames::contextmenu, mev.targetNode(), 0, event, false);
}
bool EventHandler::sendContextMenuEventForKey()
@@ -2831,9 +2631,10 @@ bool EventHandler::sendContextMenuEventForKey()
Element* focusedElement = doc->focusedElement();
FrameSelection& selection = m_frame->selection();
Position start = selection.selection().start();
+ bool shouldTranslateToRootView = true;
if (start.deprecatedNode() && (selection.rootEditableElement() || selection.isRange())) {
- RefPtr<Range> selectionRange = selection.toNormalizedRange();
+ RefPtrWillBeRawPtr<Range> selectionRange = selection.toNormalizedRange();
IntRect firstRect = m_frame->editor().firstRectForRange(selectionRange.get());
int x = rightAligned ? firstRect.maxX() : firstRect.x();
@@ -2841,20 +2642,18 @@ bool EventHandler::sendContextMenuEventForKey()
int y = firstRect.maxY() ? firstRect.maxY() - 1 : 0;
location = IntPoint(x, y);
} else if (focusedElement) {
- RenderBoxModelObject* box = focusedElement->renderBoxModelObject();
- if (!box)
- return false;
- IntRect clippedRect = box->pixelSnappedAbsoluteClippedOverflowRect();
- location = IntPoint(clippedRect.x(), clippedRect.maxY() - 1);
+ IntRect clippedRect = focusedElement->boundsInRootViewSpace();
+ location = IntPoint(clippedRect.center());
} else {
location = IntPoint(
rightAligned ? view->contentsWidth() - kContextMenuMargin : kContextMenuMargin,
kContextMenuMargin);
+ shouldTranslateToRootView = false;
}
m_frame->view()->setCursor(pointerCursor());
- IntPoint position = view->contentsToRootView(location);
+ IntPoint position = shouldTranslateToRootView ? view->contentsToRootView(location) : location;
IntPoint globalPosition = view->hostWindow()->rootViewToScreen(IntRect(position, IntSize())).location();
Node* targetNode = doc->focusedElement();
@@ -2877,7 +2676,8 @@ bool EventHandler::sendContextMenuEventForKey()
PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime());
- return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, true, 0, mouseEvent, false);
+ handleMousePressEvent(mouseEvent);
+ return sendContextMenuEvent(mouseEvent);
}
bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& event)
@@ -2902,13 +2702,13 @@ bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& ev
void EventHandler::scheduleHoverStateUpdate()
{
if (!m_hoverTimer.isActive())
- m_hoverTimer.startOneShot(0);
+ m_hoverTimer.startOneShot(0, FROM_HERE);
}
void EventHandler::scheduleCursorUpdate()
{
if (!m_cursorUpdateTimer.isActive())
- m_cursorUpdateTimer.startOneShot(cursorUpdateInterval);
+ m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, FROM_HERE);
}
void EventHandler::dispatchFakeMouseMoveEventSoon()
@@ -2930,10 +2730,10 @@ void EventHandler::dispatchFakeMouseMoveEventSoon()
if (m_maxMouseMovedDuration > fakeMouseMoveShortInterval) {
if (m_fakeMouseMoveEventTimer.isActive())
m_fakeMouseMoveEventTimer.stop();
- m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval);
+ m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval, FROM_HERE);
} else {
if (!m_fakeMouseMoveEventTimer.isActive())
- m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval);
+ m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval, FROM_HERE);
}
}
@@ -3028,7 +2828,7 @@ void EventHandler::activeIntervalTimerFired(Timer<EventHandler>*)
HitTestRequest request(HitTestRequest::TouchEvent | HitTestRequest::Release);
m_frame->document()->updateHoverActiveState(request, m_lastDeferredTapElement.get());
}
- m_lastDeferredTapElement = 0;
+ m_lastDeferredTapElement = nullptr;
}
void EventHandler::notifyElementActivated()
@@ -3036,7 +2836,7 @@ void EventHandler::notifyElementActivated()
// Since another element has been set to active, stop current timer and clear reference.
if (m_activeIntervalTimer.isActive())
m_activeIntervalTimer.stop();
- m_lastDeferredTapElement = 0;
+ m_lastDeferredTapElement = nullptr;
}
bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
@@ -3079,7 +2879,8 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
{
RefPtr<FrameView> protector(m_frame->view());
- if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(m_frame->document())) {
+ ASSERT(m_frame->document());
+ if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(*m_frame->document())) {
if (fullscreen->webkitIsFullScreen() && !isKeyEventAllowedInFullScreen(fullscreen, initialKeyEvent))
return false;
}
@@ -3100,15 +2901,12 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
// Check for cases where we are too early for events -- possible unmatched key up
// from pressing return in the location bar.
- RefPtr<Node> node = eventTargetNodeForDocument(m_frame->document());
+ RefPtrWillBeRawPtr<Node> node = eventTargetNodeForDocument(m_frame->document());
if (!node)
return false;
UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
- if (FrameView* view = m_frame->view())
- view->resetDeferredRepaintDelay();
-
// In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
// On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict
// with access keys. Then we dispatch keydown, but suppress its default handling.
@@ -3125,7 +2923,7 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
PlatformKeyboardEvent keyDownEvent = initialKeyEvent;
if (keyDownEvent.type() != PlatformEvent::RawKeyDown)
keyDownEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown);
- RefPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->domWindow());
+ RefPtrWillBeRawPtr<KeyboardEvent> keydown = KeyboardEvent::create(keyDownEvent, m_frame->document()->domWindow());
if (matchedAnAccessKey)
keydown->setDefaultPrevented(true);
keydown->setTarget(node);
@@ -3154,7 +2952,7 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
keyPressEvent.disambiguateKeyDownEvent(PlatformEvent::Char);
if (keyPressEvent.text().isEmpty())
return keydownResult;
- RefPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame->document()->domWindow());
+ RefPtrWillBeRawPtr<KeyboardEvent> keypress = KeyboardEvent::create(keyPressEvent, m_frame->document()->domWindow());
keypress->setTarget(node);
if (keydownResult)
keypress->setDefaultPrevented(true);
@@ -3163,23 +2961,23 @@ bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
}
-static FocusDirection focusDirectionForKey(const AtomicString& keyIdentifier)
+static FocusType focusDirectionForKey(const AtomicString& keyIdentifier)
{
DEFINE_STATIC_LOCAL(AtomicString, Down, ("Down", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, Up, ("Up", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, Left, ("Left", AtomicString::ConstructFromLiteral));
DEFINE_STATIC_LOCAL(AtomicString, Right, ("Right", AtomicString::ConstructFromLiteral));
- FocusDirection retVal = FocusDirectionNone;
+ FocusType retVal = FocusTypeNone;
if (keyIdentifier == Down)
- retVal = FocusDirectionDown;
+ retVal = FocusTypeDown;
else if (keyIdentifier == Up)
- retVal = FocusDirectionUp;
+ retVal = FocusTypeUp;
else if (keyIdentifier == Left)
- retVal = FocusDirectionLeft;
+ retVal = FocusTypeLeft;
else if (keyIdentifier == Right)
- retVal = FocusDirectionRight;
+ retVal = FocusTypeRight;
return retVal;
}
@@ -3197,9 +2995,9 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
else if (event->keyIdentifier() == "U+001B")
defaultEscapeEventHandler(event);
else {
- FocusDirection direction = focusDirectionForKey(event->keyIdentifier());
- if (direction != FocusDirectionNone)
- defaultArrowEventHandler(direction, event);
+ FocusType type = focusDirectionForKey(AtomicString(event->keyIdentifier()));
+ if (type != FocusTypeNone)
+ defaultArrowEventHandler(type, event);
}
}
if (event->type() == EventTypeNames::keypress) {
@@ -3211,18 +3009,17 @@ void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
}
}
-bool EventHandler::dragHysteresisExceeded(const IntPoint& floatDragViewportLocation) const
+bool EventHandler::dragHysteresisExceeded(const FloatPoint& floatDragViewportLocation) const
{
- FloatPoint dragViewportLocation(floatDragViewportLocation.x(), floatDragViewportLocation.y());
- return dragHysteresisExceeded(dragViewportLocation);
+ return dragHysteresisExceeded(flooredIntPoint(floatDragViewportLocation));
}
-bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation) const
+bool EventHandler::dragHysteresisExceeded(const IntPoint& dragViewportLocation) const
{
FrameView* view = m_frame->view();
if (!view)
return false;
- IntPoint dragLocation = view->windowToContents(flooredIntPoint(dragViewportLocation));
+ IntPoint dragLocation = view->windowToContents(dragViewportLocation);
IntSize delta = dragLocation - m_mouseDownPos;
int threshold = GeneralDragHysteresis;
@@ -3247,8 +3044,10 @@ bool EventHandler::dragHysteresisExceeded(const FloatPoint& dragViewportLocation
void EventHandler::freeClipboard()
{
- if (dragState().m_dragClipboard)
+ if (dragState().m_dragClipboard) {
+ dragState().m_dragClipboard->clearDragImage();
dragState().m_dragClipboard->setAccessPolicy(ClipboardNumb);
+ }
}
void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperation operation)
@@ -3263,7 +3062,7 @@ void EventHandler::dragSourceEndedAt(const PlatformMouseEvent& event, DragOperat
dispatchDragSrcEvent(EventTypeNames::dragend, event);
}
freeClipboard();
- dragState().m_dragSrc = 0;
+ dragState().m_dragSrc = nullptr;
// In case the drag was ended due to an escape key press we need to ensure
// that consecutive mousemove events don't reinitiate the drag and drop.
m_mouseDownMayStartDrag = false;
@@ -3312,7 +3111,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
: DragController::ImmediateSelectionDragResolution;
dragState().m_dragSrc = m_frame->page()->dragController().draggableNode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType);
} else {
- dragState().m_dragSrc = 0;
+ dragState().m_dragSrc = nullptr;
}
if (!dragState().m_dragSrc)
@@ -3335,7 +3134,7 @@ bool EventHandler::handleDrag(const MouseEventWithHitTestResults& event, CheckDr
if (!tryStartDrag(event)) {
// Something failed to start the drag, clean up.
freeClipboard();
- dragState().m_dragSrc = 0;
+ dragState().m_dragSrc = nullptr;
}
m_mouseDownMayStartDrag = false;
@@ -3353,8 +3152,7 @@ bool EventHandler::tryStartDrag(const MouseEventWithHitTestResults& event)
// image and offset
if (dragState().m_dragType == DragSourceActionDHTML) {
if (RenderObject* renderer = dragState().m_dragSrc->renderer()) {
- // FIXME: This doesn't work correctly with transforms.
- FloatPoint absPos = renderer->localToAbsolute();
+ FloatPoint absPos = renderer->localToAbsolute(FloatPoint(), UseTransforms);
IntSize delta = m_mouseDownPos - roundedIntPoint(absPos);
dragState().m_dragClipboard->setDragImageElement(dragState().m_dragSrc.get(), IntPoint(delta));
} else {
@@ -3406,10 +3204,7 @@ bool EventHandler::handleTextInputEvent(const String& text, Event* underlyingEve
if (!target)
return false;
- if (FrameView* view = m_frame->view())
- view->resetDeferredRepaintDelay();
-
- RefPtr<TextEvent> event = TextEvent::create(m_frame->domWindow(), text, inputType);
+ RefPtrWillBeRawPtr<TextEvent> event = TextEvent::create(m_frame->domWindow(), text, inputType);
event->setUnderlyingEvent(underlyingEvent);
target->dispatchEvent(event, IGNORE_EXCEPTION);
@@ -3430,7 +3225,7 @@ void EventHandler::defaultSpaceEventHandler(KeyboardEvent* event)
return;
ScrollDirection direction = event->shiftKey() ? ScrollBlockDirectionBackward : ScrollBlockDirectionForward;
- if (scrollOverflow(direction, ScrollByPage)) {
+ if (scroll(direction, ScrollByPage)) {
event->setDefaultHandled();
return;
}
@@ -3454,14 +3249,14 @@ void EventHandler::defaultBackspaceEventHandler(KeyboardEvent* event)
return;
Page* page = m_frame->page();
- if (!page)
+ if (!page || !page->mainFrame()->isLocalFrame())
return;
- bool handledEvent = page->mainFrame()->loader().client()->navigateBackForward(event->shiftKey() ? 1 : -1);
+ bool handledEvent = page->deprecatedLocalMainFrame()->loader().client()->navigateBackForward(event->shiftKey() ? 1 : -1);
if (handledEvent)
event->setDefaultHandled();
}
-void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, KeyboardEvent* event)
+void EventHandler::defaultArrowEventHandler(FocusType focusType, KeyboardEvent* event)
{
ASSERT(event->type() == EventTypeNames::keydown);
@@ -3480,7 +3275,7 @@ void EventHandler::defaultArrowEventHandler(FocusDirection focusDirection, Keybo
if (m_frame->document()->inDesignMode())
return;
- if (page->focusController().advanceFocus(focusDirection))
+ if (page->focusController().advanceFocus(focusType))
event->setDefaultHandled();
}
@@ -3498,13 +3293,13 @@ void EventHandler::defaultTabEventHandler(KeyboardEvent* event)
if (!page->tabKeyCyclesThroughElements())
return;
- FocusDirection focusDirection = event->shiftKey() ? FocusDirectionBackward : FocusDirectionForward;
+ FocusType focusType = event->shiftKey() ? FocusTypeBackward : FocusTypeForward;
// Tabs can be used in design mode editing.
if (m_frame->document()->inDesignMode())
return;
- if (page->focusController().advanceFocus(focusDirection))
+ if (page->focusController().advanceFocus(focusType))
event->setDefaultHandled();
}
@@ -3530,8 +3325,18 @@ void EventHandler::setFrameWasScrolledByUser()
view->setWasScrolledByUser(true);
}
-bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev, Scrollbar* scrollbar)
+bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& mev)
{
+ // First try to use the frame scrollbar.
+ FrameView* view = m_frame->view();
+ Scrollbar* scrollbar = view ? view->scrollbarAtPoint(mev.event().position()) : 0;
+
+ // Then try the scrollbar in the hit test.
+ if (!scrollbar)
+ scrollbar = mev.scrollbar();
+
+ updateLastScrollbarUnderMouse(scrollbar, true);
+
if (!scrollbar || !scrollbar->enabled())
return false;
setFrameWasScrolledByUser();
@@ -3575,7 +3380,7 @@ static const AtomicString& eventNameForTouchPointState(PlatformTouchPoint::State
}
}
-HitTestResult EventHandler::hitTestResultInFrame(Frame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
+HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
{
HitTestResult result(point);
@@ -3592,31 +3397,10 @@ HitTestResult EventHandler::hitTestResultInFrame(Frame* frame, const LayoutPoint
bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
{
- // First build up the lists to use for the 'touches', 'targetTouches' and 'changedTouches' attributes
- // in the JS event. See http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/
- // for an overview of how these lists fit together.
-
- // Holds the complete set of touches on the screen and will be used as the 'touches' list in the JS event.
- RefPtr<TouchList> touches = TouchList::create();
-
- // A different view on the 'touches' list above, filtered and grouped by event target. Used for the
- // 'targetTouches' list in the JS event.
- typedef HashMap<EventTarget*, RefPtr<TouchList> > TargetTouchesMap;
- TargetTouchesMap touchesByTarget;
-
- // Array of touches per state, used to assemble the 'changedTouches' list in the JS event.
- typedef HashSet<RefPtr<EventTarget> > EventTargetSet;
- struct {
- // The touches corresponding to the particular change state this struct instance represents.
- RefPtr<TouchList> m_touches;
- // Set of targets involved in m_touches.
- EventTargetSet m_targets;
- } changedTouches[PlatformTouchPoint::TouchStateEnd];
+ TRACE_EVENT0("webkit", "EventHandler::handleTouchEvent");
const Vector<PlatformTouchPoint>& points = event.touchPoints();
- UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
-
unsigned i;
bool freshTouchEvents = true;
bool allTouchReleased = true;
@@ -3627,50 +3411,48 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
allTouchReleased = false;
}
+ if (freshTouchEvents) {
+ // Ideally we'd ASSERT !m_touchSequenceDocument here since we should
+ // have cleared the active document when we saw the last release. But we
+ // have some tests that violate this, ClusterFuzz could trigger it, and
+ // there may be cases where the browser doesn't reliably release all
+ // touches. http://crbug.com/345372 tracks this.
+ m_touchSequenceDocument.clear();
+ m_touchSequenceUserGestureToken.clear();
+ }
+
+ OwnPtr<UserGestureIndicator> gestureIndicator;
+
+ if (m_touchSequenceUserGestureToken)
+ gestureIndicator = adoptPtr(new UserGestureIndicator(m_touchSequenceUserGestureToken.release()));
+ else
+ gestureIndicator = adoptPtr(new UserGestureIndicator(DefinitelyProcessingUserGesture));
+
+ m_touchSequenceUserGestureToken = gestureIndicator->currentToken();
+
+ ASSERT(m_frame->view());
+ if (m_touchSequenceDocument && (!m_touchSequenceDocument->frame() || !m_touchSequenceDocument->frame()->view())) {
+ // If the active touch document has no frame or view, it's probably being destroyed
+ // so we can't dispatch events.
+ return false;
+ }
+ // First do hit tests for any new touch points.
for (i = 0; i < points.size(); ++i) {
const PlatformTouchPoint& point = points[i];
- PlatformTouchPoint::State pointState = point.state();
- LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
-
- // Gesture events trigger the active state, not touch events,
- // so touch event hit tests can always be read only.
- HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | HitTestRequest::ReadOnly;
- // The HitTestRequest types used for mouse events map quite adequately
- // to touch events. Note that in addition to meaning that the hit test
- // should affect the active state of the current node if necessary,
- // HitTestRequest::Active signifies that the hit test is taking place
- // with the mouse (or finger in this case) being pressed.
- switch (pointState) {
- case PlatformTouchPoint::TouchPressed:
- hitType |= HitTestRequest::Active;
- break;
- case PlatformTouchPoint::TouchMoved:
- hitType |= HitTestRequest::Active | HitTestRequest::Move;
- break;
- case PlatformTouchPoint::TouchReleased:
- case PlatformTouchPoint::TouchCancelled:
- hitType |= HitTestRequest::Release;
- break;
- case PlatformTouchPoint::TouchStationary:
- hitType |= HitTestRequest::Active;
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
- }
- // Increment the platform touch id by 1 to avoid storing a key of 0 in the hashmap.
- unsigned touchPointTargetKey = point.id() + 1;
- RefPtr<EventTarget> touchTarget;
- if (pointState == PlatformTouchPoint::TouchPressed) {
+ // Touch events implicitly capture to the touched node, and don't change
+ // active/hover states themselves (Gesture events do). So we only need
+ // to hit-test on touchstart, and it can be read-only.
+ if (point.state() == PlatformTouchPoint::TouchPressed) {
+ HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent | HitTestRequest::ReadOnly | HitTestRequest::Active;
+ LayoutPoint pagePoint = roundedLayoutPoint(m_frame->view()->windowToContents(point.pos()));
HitTestResult result;
- if (freshTouchEvents) {
+ if (!m_touchSequenceDocument) {
result = hitTestResultAtPoint(pagePoint, hitType);
- m_originatingTouchPointTargetKey = touchPointTargetKey;
- } else if (m_originatingTouchPointDocument.get() && m_originatingTouchPointDocument->frame()) {
- LayoutPoint pagePointInOriginatingDocument = documentPointForWindowPoint(m_originatingTouchPointDocument->frame(), point.pos());
- result = hitTestResultInFrame(m_originatingTouchPointDocument->frame(), pagePointInOriginatingDocument, hitType);
+ } else if (m_touchSequenceDocument->frame()) {
+ LayoutPoint framePoint = roundedLayoutPoint(m_touchSequenceDocument->frame()->view()->windowToContents(point.pos()));
+ result = hitTestResultInFrame(m_touchSequenceDocument->frame(), framePoint, hitType);
} else
continue;
@@ -3680,66 +3462,138 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
// Touch events should not go to text nodes
if (node->isTextNode())
- node = EventPath::parent(node);
-
- Document& doc = node->document();
- // Record the originating touch document even if it does not have a touch listener.
- if (freshTouchEvents) {
- m_originatingTouchPointDocument = &doc;
- freshTouchEvents = false;
+ node = NodeRenderingTraversal::parent(node);
+
+ if (!m_touchSequenceDocument) {
+ // Keep track of which document should receive all touch events
+ // in the active sequence. This must be a single document to
+ // ensure we don't leak Nodes between documents.
+ m_touchSequenceDocument = &(result.innerNode()->document());
+ ASSERT(m_touchSequenceDocument->frame()->view());
}
- if (!doc.hasTouchEventHandlers())
- continue;
- m_originatingTouchPointTargets.set(touchPointTargetKey, node);
- touchTarget = node;
- // FIXME(rbyers): Should really be doing a second hit test that ignores inline elements - crbug.com/319479.
+ // Ideally we'd ASSERT(!m_targetForTouchID.contains(point.id())
+ // since we shouldn't get a touchstart for a touch that's already
+ // down. However EventSender allows this to be violated and there's
+ // some tests that take advantage of it. There may also be edge
+ // cases in the browser where this happens.
+ // See http://crbug.com/345372.
+ m_targetForTouchID.set(point.id(), node);
+
TouchAction effectiveTouchAction = computeEffectiveTouchAction(*node);
if (effectiveTouchAction != TouchActionAuto)
m_frame->page()->chrome().client().setTouchAction(effectiveTouchAction);
+ }
+ }
- } else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) {
- // The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel
- // we also remove it from the map.
- touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
- } else
- // No hittest is performed on move or stationary, since the target is not allowed to change anyway.
- touchTarget = m_originatingTouchPointTargets.get(touchPointTargetKey);
+ m_touchPressed = !allTouchReleased;
- if (!touchTarget.get())
- continue;
- Document& doc = touchTarget->toNode()->document();
- if (!doc.hasTouchEventHandlers())
- continue;
- Frame* targetFrame = doc.frame();
- if (!targetFrame)
- continue;
+ // If there's no document receiving touch events, or no handlers on the
+ // document set to receive the events, then we can skip all the rest of
+ // this work.
+ if (!m_touchSequenceDocument || !m_touchSequenceDocument->hasTouchEventHandlers() || !m_touchSequenceDocument->frame()) {
+ if (allTouchReleased) {
+ m_touchSequenceDocument.clear();
+ m_touchSequenceUserGestureToken.clear();
+ }
+ return false;
+ }
+
+ // Build up the lists to use for the 'touches', 'targetTouches' and
+ // 'changedTouches' attributes in the JS event. See
+ // http://www.w3.org/TR/touch-events/#touchevent-interface for how these
+ // lists fit together.
+
+ // Holds the complete set of touches on the screen.
+ RefPtrWillBeRawPtr<TouchList> touches = TouchList::create();
- if (m_frame != targetFrame) {
- // pagePoint should always be relative to the target elements containing frame.
- pagePoint = documentPointForWindowPoint(targetFrame, point.pos());
+ // A different view on the 'touches' list above, filtered and grouped by
+ // event target. Used for the 'targetTouches' list in the JS event.
+ typedef WillBeHeapHashMap<EventTarget*, RefPtrWillBeMember<TouchList> > TargetTouchesHeapMap;
+ TargetTouchesHeapMap touchesByTarget;
+
+ // Array of touches per state, used to assemble the 'changedTouches' list.
+ typedef WillBeHeapHashSet<RefPtrWillBeMember<EventTarget> > EventTargetSet;
+ struct {
+ // The touches corresponding to the particular change state this struct
+ // instance represents.
+ RefPtrWillBeMember<TouchList> m_touches;
+ // Set of targets involved in m_touches.
+ EventTargetSet m_targets;
+ } changedTouches[PlatformTouchPoint::TouchStateEnd];
+
+ for (i = 0; i < points.size(); ++i) {
+ const PlatformTouchPoint& point = points[i];
+ PlatformTouchPoint::State pointState = point.state();
+ RefPtrWillBeRawPtr<EventTarget> touchTarget = nullptr;
+
+ if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) {
+ // The target should be the original target for this touch, so get
+ // it from the hashmap. As it's a release or cancel we also remove
+ // it from the map.
+ touchTarget = m_targetForTouchID.take(point.id());
+ } else {
+ // No hittest is performed on move or stationary, since the target
+ // is not allowed to change anyway.
+ touchTarget = m_targetForTouchID.get(point.id());
+ }
+
+ LocalFrame* targetFrame = 0;
+ bool knownTarget = false;
+ if (touchTarget) {
+ Document& doc = touchTarget->toNode()->document();
+ // If the target node has moved to a new document while it was being touched,
+ // we can't send events to the new document because that could leak nodes
+ // from one document to another. See http://crbug.com/394339.
+ if (&doc == m_touchSequenceDocument.get()) {
+ targetFrame = doc.frame();
+ knownTarget = true;
+ }
}
+ if (!knownTarget) {
+ // If we don't have a target registered for the point it means we've
+ // missed our opportunity to do a hit test for it (due to some
+ // optimization that prevented blink from ever seeing the
+ // touchstart), or that the touch started outside the active touch
+ // sequence document. We should still include the touch in the
+ // Touches list reported to the application (eg. so it can
+ // differentiate between a one and two finger gesture), but we won't
+ // actually dispatch any events for it. Set the target to the
+ // Document so that there's some valid node here. Perhaps this
+ // should really be LocalDOMWindow, but in all other cases the target of
+ // a Touch is a Node so using the window could be a breaking change.
+ // Since we know there was no handler invoked, the specific target
+ // should be completely irrelevant to the application.
+ // FIXME: Oilpan: We can remove the following .get() if EventTarget
+ // is on-heap.
+ touchTarget = m_touchSequenceDocument.get();
+ targetFrame = m_touchSequenceDocument->frame();
+ }
+ ASSERT(targetFrame);
+
+ // pagePoint should always be relative to the target elements
+ // containing frame.
+ FloatPoint pagePoint = targetFrame->view()->windowToContents(point.pos());
- float scaleFactor = targetFrame->pageZoomFactor();
+ float scaleFactor = 1.0f / targetFrame->pageZoomFactor();
- int adjustedPageX = lroundf(pagePoint.x() / scaleFactor);
- int adjustedPageY = lroundf(pagePoint.y() / scaleFactor);
- int adjustedRadiusX = lroundf(point.radiusX() / scaleFactor);
- int adjustedRadiusY = lroundf(point.radiusY() / scaleFactor);
+ FloatPoint adjustedPagePoint = pagePoint.scaledBy(scaleFactor);
+ FloatSize adjustedRadius = point.radius().scaledBy(scaleFactor);
- RefPtr<Touch> touch = Touch::create(targetFrame, touchTarget.get(), point.id(),
- point.screenPos().x(), point.screenPos().y(),
- adjustedPageX, adjustedPageY,
- adjustedRadiusX, adjustedRadiusY,
- point.rotationAngle(), point.force());
+ RefPtrWillBeRawPtr<Touch> touch = Touch::create(
+ targetFrame, touchTarget.get(), point.id(), point.screenPos(), adjustedPagePoint, adjustedRadius, point.rotationAngle(), point.force());
- // Ensure this target's touch list exists, even if it ends up empty, so it can always be passed to TouchEvent::Create below.
- TargetTouchesMap::iterator targetTouchesIterator = touchesByTarget.find(touchTarget.get());
- if (targetTouchesIterator == touchesByTarget.end())
- targetTouchesIterator = touchesByTarget.set(touchTarget.get(), TouchList::create()).iterator;
+ // Ensure this target's touch list exists, even if it ends up empty, so
+ // it can always be passed to TouchEvent::Create below.
+ TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.find(touchTarget.get());
+ if (targetTouchesIterator == touchesByTarget.end()) {
+ touchesByTarget.set(touchTarget.get(), TouchList::create());
+ targetTouchesIterator = touchesByTarget.find(touchTarget.get());
+ }
- // touches and targetTouches should only contain information about touches still on the screen, so if this point is
- // released or cancelled it will only appear in the changedTouches list.
+ // touches and targetTouches should only contain information about
+ // touches still on the screen, so if this point is released or
+ // cancelled it will only appear in the changedTouches list.
if (pointState != PlatformTouchPoint::TouchReleased && pointState != PlatformTouchPoint::TouchCancelled) {
touches->append(touch);
targetTouchesIterator->value->append(touch);
@@ -3748,10 +3602,10 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
// Now build up the correct list for changedTouches.
// Note that any touches that are in the TouchStationary state (e.g. if
// the user had several points touched but did not move them all) should
- // never be in the changedTouches list so we do not handle them explicitly here.
- // See https://bugs.webkit.org/show_bug.cgi?id=37609 for further discussion
- // about the TouchStationary state.
- if (pointState != PlatformTouchPoint::TouchStationary) {
+ // never be in the changedTouches list so we do not handle them
+ // explicitly here. See https://bugs.webkit.org/show_bug.cgi?id=37609
+ // for further discussion about the TouchStationary state.
+ if (pointState != PlatformTouchPoint::TouchStationary && knownTarget) {
ASSERT(pointState < PlatformTouchPoint::TouchStateEnd);
if (!changedTouches[pointState].m_touches)
changedTouches[pointState].m_touches = TouchList::create();
@@ -3759,32 +3613,26 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
changedTouches[pointState].m_targets.add(touchTarget);
}
}
- m_touchPressed = touches->length() > 0;
- if (allTouchReleased)
- m_originatingTouchPointDocument.clear();
+ if (allTouchReleased) {
+ m_touchSequenceDocument.clear();
+ m_touchSequenceUserGestureToken.clear();
+ }
- // Now iterate the changedTouches list and m_targets within it, sending events to the targets as required.
+ // Now iterate the changedTouches list and m_targets within it, sending
+ // events to the targets as required.
bool swallowedEvent = false;
- RefPtr<TouchList> emptyList = TouchList::create();
for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
if (!changedTouches[state].m_touches)
continue;
- // When sending a touch cancel event, use empty touches and targetTouches lists.
- bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled);
- RefPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emptyList : touches);
const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
const EventTargetSet& targetsForState = changedTouches[state].m_targets;
-
for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
EventTarget* touchEventTarget = it->get();
- RefPtr<TouchList> targetTouches(isTouchCancelEvent ? emptyList : touchesByTarget.get(touchEventTarget));
- ASSERT(targetTouches);
-
- RefPtr<TouchEvent> touchEvent =
- TouchEvent::create(effectiveTouches.get(), targetTouches.get(), changedTouches[state].m_touches.get(),
- stateName, touchEventTarget->toNode()->document().domWindow(),
- 0, 0, 0, 0, event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey());
+ RefPtrWillBeRawPtr<TouchEvent> touchEvent = TouchEvent::create(
+ touches.get(), touchesByTarget.get(touchEventTarget), changedTouches[state].m_touches.get(),
+ stateName, touchEventTarget->toNode()->document().domWindow(),
+ event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.cancelable());
touchEventTarget->toNode()->dispatchTouchEvent(touchEvent.get());
swallowedEvent = swallowedEvent || touchEvent->defaultPrevented() || touchEvent->defaultHandled();
}
@@ -3793,123 +3641,17 @@ bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
return swallowedEvent;
}
-bool EventHandler::dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent& event)
+TouchAction EventHandler::intersectTouchAction(TouchAction action1, TouchAction action2)
{
- if (!m_frame || !m_frame->settings() || !m_frame->settings()->touchEventEmulationEnabled())
- return false;
-
- PlatformEvent::Type eventType = event.type();
- if (eventType != PlatformEvent::MouseMoved && eventType != PlatformEvent::MousePressed && eventType != PlatformEvent::MouseReleased)
- return false;
-
- HitTestRequest request(HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
- MouseEventWithHitTestResults mev = prepareMouseEvent(request, event);
- if (mev.scrollbar() || subframeForHitTestResult(mev))
- return false;
-
- // The order is important. This check should follow the subframe test: http://webkit.org/b/111292.
- if (eventType == PlatformEvent::MouseMoved && event.button() == NoButton)
- return true;
-
- SyntheticSingleTouchEvent touchEvent(event);
- if (handleTouchEvent(touchEvent))
- return true;
-
- return handleMouseEventAsEmulatedGesture(event);
-}
-
-bool EventHandler::handleMouseEventAsEmulatedGesture(const PlatformMouseEvent& event)
-{
- PlatformEvent::Type eventType = event.type();
- if (event.button() != LeftButton || !m_frame->isMainFrame())
- return false;
-
- // Simulate pinch / scroll gesture.
- const IntPoint& position = event.position();
- bool swallowEvent = false;
-
- FrameView* view = m_frame->view();
- if (event.shiftKey()) {
- // Shift pressed - consider it gesture.
- swallowEvent = true;
- Page* page = m_frame->page();
- float pageScaleFactor = page->pageScaleFactor();
- switch (eventType) {
- case PlatformEvent::MousePressed:
- m_lastSyntheticPinchAnchorCss = adoptPtr(new IntPoint(view->scrollPosition() + position));
- m_lastSyntheticPinchAnchorDip = adoptPtr(new IntPoint(position));
- m_lastSyntheticPinchAnchorDip->scale(pageScaleFactor, pageScaleFactor);
- m_syntheticPageScaleFactor = pageScaleFactor;
- break;
- case PlatformEvent::MouseMoved:
- {
- if (!m_lastSyntheticPinchAnchorCss)
- break;
-
- float dy = m_lastSyntheticPinchAnchorDip->y() - position.y() * pageScaleFactor;
- float magnifyDelta = exp(dy * 0.002f);
- float newPageScaleFactor = m_syntheticPageScaleFactor * magnifyDelta;
-
- IntPoint anchorCss(*m_lastSyntheticPinchAnchorDip.get());
- anchorCss.scale(1.f / newPageScaleFactor, 1.f / newPageScaleFactor);
- page->inspectorController().requestPageScaleFactor(newPageScaleFactor, *m_lastSyntheticPinchAnchorCss.get() - toIntSize(anchorCss));
- break;
- }
- case PlatformEvent::MouseReleased:
- m_lastSyntheticPinchAnchorCss.clear();
- m_lastSyntheticPinchAnchorDip.clear();
- default:
- break;
- }
- } else {
- switch (eventType) {
- case PlatformEvent::MouseMoved:
- {
- // Always consume move events.
- swallowEvent = true;
- int dx = m_lastSyntheticPanLocation ? position.x() - m_lastSyntheticPanLocation->x() : 0;
- int dy = m_lastSyntheticPanLocation ? position.y() - m_lastSyntheticPanLocation->y() : 0;
- if (dx || dy)
- view->scrollBy(IntSize(-dx, -dy));
- // Mouse dragged - consider it gesture.
- m_lastSyntheticPanLocation = adoptPtr(new IntPoint(position));
- break;
- }
- case PlatformEvent::MouseReleased:
- // There was a drag -> gesture.
- swallowEvent = !!m_lastSyntheticPanLocation;
- m_lastSyntheticPanLocation.clear();
- default:
- break;
- }
- }
-
- return swallowEvent;
-}
-
-bool EventHandler::handleWheelEventAsEmulatedGesture(const PlatformWheelEvent& event)
-{
- if (!m_frame || !m_frame->settings() || !m_frame->settings()->touchEventEmulationEnabled())
- return false;
-
- // Only convert vertical wheel w/ shift into pinch for touch-enabled device convenience.
- if (!event.shiftKey() || !event.deltaY())
- return false;
-
- Page* page = m_frame->page();
- FrameView* view = m_frame->view();
- float pageScaleFactor = page->pageScaleFactor();
- IntPoint anchorBeforeCss(view->scrollPosition() + event.position());
- IntPoint anchorBeforeDip(event.position());
- anchorBeforeDip.scale(pageScaleFactor, pageScaleFactor);
-
- float magnifyDelta = exp(event.deltaY() * 0.002f);
- float newPageScaleFactor = pageScaleFactor * magnifyDelta;
-
- IntPoint anchorAfterCss(anchorBeforeDip);
- anchorAfterCss.scale(1.f / newPageScaleFactor, 1.f / newPageScaleFactor);
- page->inspectorController().requestPageScaleFactor(newPageScaleFactor, anchorBeforeCss - toIntSize(anchorAfterCss));
- return true;
+ if (action1 == TouchActionNone || action2 == TouchActionNone)
+ return TouchActionNone;
+ if (action1 == TouchActionAuto)
+ return action2;
+ if (action2 == TouchActionAuto)
+ return action1;
+ if (!(action1 & action2))
+ return TouchActionNone;
+ return action1 & action2;
}
TouchAction EventHandler::computeEffectiveTouchAction(const Node& node)
@@ -3919,17 +3661,17 @@ TouchAction EventHandler::computeEffectiveTouchAction(const Node& node)
if (!RuntimeEnabledFeatures::cssTouchActionEnabled())
return TouchActionAuto;
- // Start by permitting all actions, then walk the block level elements from
- // the target node up to the nearest scrollable ancestor and exclude any
- // prohibited actions. For now this is trivial, but when we add more types
- // of actions it'll get a little more complex.
+ // Start by permitting all actions, then walk the elements supporting
+ // touch-action from the target node up to the nearest scrollable ancestor
+ // and exclude any prohibited actions.
+ TouchAction effectiveTouchAction = TouchActionAuto;
for (const Node* curNode = &node; curNode; curNode = NodeRenderingTraversal::parent(curNode)) {
- // The spec says only block and SVG elements get touch-action.
- // FIXME(rbyers): Add correct support for SVG, crbug.com/247396.
if (RenderObject* renderer = curNode->renderer()) {
- if (renderer->isRenderBlockFlow()) {
- if (renderer->style()->touchAction() == TouchActionNone)
- return TouchActionNone;
+ if (renderer->supportsTouchAction()) {
+ TouchAction action = renderer->style()->touchAction();
+ effectiveTouchAction = intersectTouchAction(action, effectiveTouchAction);
+ if (effectiveTouchAction == TouchActionNone)
+ break;
}
// If we've reached an ancestor that supports a touch action, search no further.
@@ -3937,7 +3679,7 @@ TouchAction EventHandler::computeEffectiveTouchAction(const Node& node)
break;
}
}
- return TouchActionAuto;
+ return effectiveTouchAction;
}
void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
@@ -3947,7 +3689,7 @@ void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
m_lastKnownMouseGlobalPosition = event.globalPosition();
}
-bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe)
{
// If we're clicking into a frame that is selected, the frame will appear
// greyed out even though we're clicking on the selection. This looks
@@ -3965,7 +3707,7 @@ bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& m
return true;
}
-bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode)
+bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe, HitTestResult* hoveredNode)
{
if (m_mouseDownMayStartDrag && !m_mouseDownWasInSubframe)
return false;
@@ -3973,7 +3715,7 @@ bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& me
return true;
}
-bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe)
{
subframe->eventHandler().handleMouseReleaseEvent(mev.event());
return true;
@@ -4002,9 +3744,9 @@ bool EventHandler::passWidgetMouseDownEventToWidget(const MouseEventWithHitTestR
return false;
}
-PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
+PassRefPtrWillBeRawPtr<Clipboard> EventHandler::createDraggingClipboard() const
{
- return Clipboard::create(Clipboard::DragAndDrop, ClipboardWritable, ChromiumDataObject::create());
+ return Clipboard::create(Clipboard::DragAndDrop, ClipboardWritable, DataObject::create());
}
void EventHandler::focusDocumentView()
@@ -4012,7 +3754,7 @@ void EventHandler::focusDocumentView()
Page* page = m_frame->page();
if (!page)
return;
- page->focusController().setFocusedFrame(m_frame);
+ page->focusController().focusDocumentView(m_frame);
}
unsigned EventHandler::accessKeyModifiers()
diff --git a/chromium/third_party/WebKit/Source/core/page/EventHandler.h b/chromium/third_party/WebKit/Source/core/page/EventHandler.h
index 183a4acb46c..c69275b5baa 100644
--- a/chromium/third_party/WebKit/Source/core/page/EventHandler.h
+++ b/chromium/third_party/WebKit/Source/core/page/EventHandler.h
@@ -29,7 +29,7 @@
#include "core/editing/TextGranularity.h"
#include "core/events/TextEventInputType.h"
#include "core/page/DragActions.h"
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "platform/Cursor.h"
@@ -37,9 +37,11 @@
#include "platform/Timer.h"
#include "platform/UserGestureIndicator.h"
#include "platform/geometry/LayoutPoint.h"
+#include "platform/heap/Handle.h"
#include "platform/scroll/ScrollTypes.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
+#include "wtf/HashTraits.h"
#include "wtf/RefPtr.h"
namespace WebCore {
@@ -53,7 +55,7 @@ class EventTarget;
class FloatPoint;
class FloatQuad;
class FullscreenElementStack;
-class Frame;
+class LocalFrame;
class HTMLFrameSetElement;
class HitTestRequest;
class HitTestResult;
@@ -69,7 +71,6 @@ class RenderLayer;
class RenderLayerScrollableArea;
class RenderObject;
class RenderWidget;
-class SVGElementInstance;
class ScrollableArea;
class Scrollbar;
class TextEvent;
@@ -78,16 +79,17 @@ class VisibleSelection;
class WheelEvent;
class Widget;
-struct DragState;
+class DragState;
enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
-class EventHandler {
+class EventHandler : public NoBaseWillBeGarbageCollectedFinalized<EventHandler> {
WTF_MAKE_NONCOPYABLE(EventHandler);
public:
- explicit EventHandler(Frame*);
+ explicit EventHandler(LocalFrame*);
~EventHandler();
+ void trace(Visitor*);
void clear();
void nodeWillBeRemoved(Node&);
@@ -112,7 +114,7 @@ public:
bool mousePressed() const { return m_mousePressed; }
void setMousePressed(bool pressed) { m_mousePressed = pressed; }
- void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
+ void setCapturingMouseEventsNode(PassRefPtrWillBeRawPtr<Node>); // A caller is responsible for resetting capturing node to 0.
bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
@@ -129,8 +131,9 @@ public:
IntPoint lastKnownMousePosition() const;
Cursor currentMouseCursor() const { return m_currentMouseCursor; }
- bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
- bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
+ // Attempts to scroll the DOM tree. If that fails, scrolls the view.
+ // If the view can't be scrolled either, recursively bubble to the parent frame.
+ bool bubblingScroll(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
bool handleMouseMoveEvent(const PlatformMouseEvent&);
void handleMouseLeaveEvent(const PlatformMouseEvent&);
@@ -148,7 +151,7 @@ public:
bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
- bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
+ void adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
bool sendContextMenuEvent(const PlatformMouseEvent&);
bool sendContextMenuEventForKey();
@@ -172,14 +175,16 @@ public:
bool handleTouchEvent(const PlatformTouchEvent&);
- bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
+ bool useHandCursor(Node*, bool isOverLink);
void notifyElementActivated();
+ PassRefPtr<UserGestureToken> takeLastMouseDownGestureToken() { return m_lastMouseDownUserGestureToken.release(); }
+
private:
static DragState& dragState();
- PassRefPtr<Clipboard> createDraggingClipboard() const;
+ PassRefPtrWillBeRawPtr<Clipboard> createDraggingClipboard() const;
bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
@@ -193,6 +198,7 @@ private:
bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
+ bool handleMouseFocus(const PlatformMouseEvent&);
bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
@@ -208,14 +214,13 @@ private:
bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
- OptionalCursor selectCursor(const HitTestResult&, bool shiftKey);
- OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam, bool shiftKey);
+ OptionalCursor selectCursor(const HitTestResult&);
+ OptionalCursor selectAutoCursor(const HitTestResult&, Node*, const Cursor& iBeam);
void hoverTimerFired(Timer<EventHandler>*);
void cursorUpdateTimerFired(Timer<EventHandler>*);
void activeIntervalTimerFired(Timer<EventHandler>*);
- bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
@@ -227,22 +232,31 @@ private:
ScrollableArea* associatedScrollableArea(const RenderLayer*) const;
- bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
+ // Scrolls the elements of the DOM tree. Returns true if a node was scrolled.
+ // False if we reached the root and couldn't scroll anything.
+ // direction - The direction to scroll in. If this is a logicl direction, it will be
+ // converted to the physical direction based on a node's writing mode.
+ // granularity - The units that the scroll delta parameter is in.
+ // startNode - The node to start bubbling the scroll from. If a node can't scroll,
+ // the scroll bubbles up to the containing block.
+ // stopNode - On input, if provided and non-null, the node at which we should stop bubbling on input.
+ // On output, if provided and a node was scrolled stopNode will point to that node.
+ // delta - The delta to scroll by, in the units of the granularity parameter. (e.g. pixels, lines, pages, etc.)
+ // absolutePoint - For wheel scrolls - the location, in absolute coordinates, where the event occured.
+ bool scroll(ScrollDirection, ScrollGranularity, Node* startNode = 0, Node** stopNode = 0, float delta = 1.0f, IntPoint absolutePoint = IntPoint());
+
+ TouchAction intersectTouchAction(const TouchAction, const TouchAction);
TouchAction computeEffectiveTouchAction(const Node&);
- bool handleMouseEventAsEmulatedGesture(const PlatformMouseEvent&);
- bool handleWheelEventAsEmulatedGesture(const PlatformWheelEvent&);
- HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
+ HitTestResult hitTestResultInFrame(LocalFrame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
void invalidateClick();
- Node* nodeUnderMouse() const;
-
void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
- bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
+ bool dispatchMouseEvent(const AtomicString& eventType, Node* target, int clickCount, const PlatformMouseEvent&, bool setUnder);
bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
void freeClipboard();
@@ -256,11 +270,11 @@ private:
bool dragHysteresisExceeded(const FloatPoint&) const;
bool dragHysteresisExceeded(const IntPoint&) const;
- bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
- bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
- bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
+ bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
+ bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe, HitTestResult* hoveredNode = 0);
+ bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
- bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
+ bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&);
bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
@@ -270,7 +284,7 @@ private:
void defaultBackspaceEventHandler(KeyboardEvent*);
void defaultTabEventHandler(KeyboardEvent*);
void defaultEscapeEventHandler(KeyboardEvent*);
- void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
+ void defaultArrowEventHandler(FocusType, KeyboardEvent*);
void updateSelectionForMouseDrag(const HitTestResult&);
@@ -289,17 +303,17 @@ private:
bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
- Frame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&);
+ LocalFrame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&);
AutoscrollController* autoscrollController() const;
bool panScrollInProgress() const;
void setLastKnownMousePosition(const PlatformMouseEvent&);
- Frame* const m_frame;
+ LocalFrame* const m_frame;
bool m_mousePressed;
bool m_capturesDragging;
- RefPtr<Node> m_mousePressNode;
+ RefPtrWillBeMember<Node> m_mousePressNode;
bool m_mouseDownMayStartSelect;
bool m_mouseDownMayStartDrag;
@@ -309,8 +323,6 @@ private:
LayoutPoint m_dragStartPos;
- bool m_panScrollButtonPressed;
-
Timer<EventHandler> m_hoverTimer;
Timer<EventHandler> m_cursorUpdateTimer;
@@ -320,27 +332,25 @@ private:
Timer<EventHandler> m_fakeMouseMoveEventTimer;
bool m_svgPan;
- RefPtr<SVGElementInstance> m_instanceUnderMouse;
- RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
RenderLayerScrollableArea* m_resizeScrollableArea;
- RefPtr<Node> m_capturingMouseEventsNode;
+ RefPtrWillBeMember<Node> m_capturingMouseEventsNode;
bool m_eventHandlerWillResetCapturingMouseEventsNode;
- RefPtr<Node> m_nodeUnderMouse;
- RefPtr<Node> m_lastNodeUnderMouse;
- RefPtr<Frame> m_lastMouseMoveEventSubframe;
+ RefPtrWillBeMember<Node> m_nodeUnderMouse;
+ RefPtrWillBeMember<Node> m_lastNodeUnderMouse;
+ RefPtr<LocalFrame> m_lastMouseMoveEventSubframe;
RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
Cursor m_currentMouseCursor;
int m_clickCount;
- RefPtr<Node> m_clickNode;
+ RefPtrWillBeMember<Node> m_clickNode;
- RefPtr<Node> m_dragTarget;
+ RefPtrWillBeMember<Node> m_dragTarget;
bool m_shouldOnlyFireDragOverEvent;
- RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
+ RefPtrWillBeMember<HTMLFrameSetElement> m_frameSetBeingResized;
LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeScrollableArea.
@@ -352,20 +362,24 @@ private:
PlatformMouseEvent m_mouseDown;
RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
- RefPtr<Node> m_latchedWheelEventNode;
+ RefPtrWillBeMember<Node> m_latchedWheelEventNode;
bool m_widgetIsLatched;
- RefPtr<Node> m_previousWheelScrolledNode;
+ RefPtrWillBeMember<Node> m_previousWheelScrolledNode;
+
+ // The target of each active touch point indexed by the touch ID.
+ typedef WillBeHeapHashMap<unsigned, RefPtrWillBeMember<EventTarget>, DefaultHash<unsigned>::Hash, WTF::UnsignedWithZeroKeyHashTraits<unsigned> > TouchTargetMap;
+ TouchTargetMap m_targetForTouchID;
+
+ // If set, the document of the active touch sequence. Unset if no touch sequence active.
+ RefPtrWillBeMember<Document> m_touchSequenceDocument;
+ RefPtr<UserGestureToken> m_touchSequenceUserGestureToken;
- typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
- TouchTargetMap m_originatingTouchPointTargets;
- RefPtr<Document> m_originatingTouchPointDocument;
- unsigned m_originatingTouchPointTargetKey;
bool m_touchPressed;
- RefPtr<Node> m_scrollGestureHandlingNode;
+ RefPtrWillBeMember<Node> m_scrollGestureHandlingNode;
bool m_lastHitTestResultOverWidget;
- RefPtr<Node> m_previousGestureScrolledNode;
+ RefPtrWillBeMember<Node> m_previousGestureScrolledNode;
RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
double m_maxMouseMovedDuration;
@@ -373,14 +387,10 @@ private:
bool m_didStartDrag;
bool m_longTapShouldInvokeContextMenu;
- OwnPtr<IntPoint> m_lastSyntheticPinchAnchorCss;
- OwnPtr<IntPoint> m_lastSyntheticPinchAnchorDip;
- OwnPtr<IntPoint> m_lastSyntheticPanLocation;
- float m_syntheticPageScaleFactor;
Timer<EventHandler> m_activeIntervalTimer;
double m_lastShowPressTimestamp;
- RefPtr<Element> m_lastDeferredTapElement;
+ RefPtrWillBeMember<Element> m_lastDeferredTapElement;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/EventSource.cpp b/chromium/third_party/WebKit/Source/core/page/EventSource.cpp
index 6a9600c5660..38e5d5deb38 100644
--- a/chromium/third_party/WebKit/Source/core/page/EventSource.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/EventSource.cpp
@@ -42,10 +42,10 @@
#include "core/dom/ExecutionContext.h"
#include "core/events/Event.h"
#include "core/events/MessageEvent.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/loader/ThreadableLoader.h"
#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
@@ -72,17 +72,17 @@ inline EventSource::EventSource(ExecutionContext* context, const KURL& url, cons
eventSourceInit.get("withCredentials", m_withCredentials);
}
-PassRefPtr<EventSource> EventSource::create(ExecutionContext* context, const String& url, const Dictionary& eventSourceInit, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<EventSource> EventSource::create(ExecutionContext* context, const String& url, const Dictionary& eventSourceInit, ExceptionState& exceptionState)
{
if (url.isEmpty()) {
exceptionState.throwDOMException(SyntaxError, "Cannot open an EventSource to an empty URL.");
- return 0;
+ return nullptr;
}
KURL fullURL = context->completeURL(url);
if (!fullURL.isValid()) {
exceptionState.throwDOMException(SyntaxError, "Cannot open an EventSource to '" + url + "'. The URL is invalid.");
- return 0;
+ return nullptr;
}
// FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved.
@@ -94,10 +94,10 @@ PassRefPtr<EventSource> EventSource::create(ExecutionContext* context, const Str
if (!shouldBypassMainWorldContentSecurityPolicy && !context->contentSecurityPolicy()->allowConnectToSource(fullURL)) {
// We can safely expose the URL to JavaScript, as this exception is generate synchronously before any redirects take place.
exceptionState.throwSecurityError("Refused to connect to '" + fullURL.elidedString() + "' because it violates the document's Content Security Policy.");
- return 0;
+ return nullptr;
}
- RefPtr<EventSource> source = adoptRef(new EventSource(context, fullURL, eventSourceInit));
+ RefPtrWillBeRawPtr<EventSource> source = adoptRefWillBeRefCountedGarbageCollected(new EventSource(context, fullURL, eventSourceInit));
source->setPendingActivity(source.get());
source->scheduleInitialConnect();
@@ -117,14 +117,16 @@ void EventSource::scheduleInitialConnect()
ASSERT(m_state == CONNECTING);
ASSERT(!m_requestInFlight);
- m_connectTimer.startOneShot(0);
+ m_connectTimer.startOneShot(0, FROM_HERE);
}
void EventSource::connect()
{
ASSERT(m_state == CONNECTING);
ASSERT(!m_requestInFlight);
+ ASSERT(executionContext());
+ ExecutionContext& executionContext = *this->executionContext();
ResourceRequest request(m_url);
request.setHTTPMethod("GET");
request.setHTTPHeaderField("Accept", "text/event-stream");
@@ -132,20 +134,20 @@ void EventSource::connect()
if (!m_lastEventId.isEmpty())
request.setHTTPHeaderField("Last-Event-ID", m_lastEventId);
- SecurityOrigin* origin = executionContext()->securityOrigin();
+ SecurityOrigin* origin = executionContext.securityOrigin();
ThreadableLoaderOptions options;
- options.sendLoadCallbacks = SendCallbacks;
- options.sniffContent = DoNotSniffContent;
- options.allowCredentials = (origin->canRequest(m_url) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- options.credentialsRequested = m_withCredentials ? ClientRequestedCredentials : ClientDidNotRequestCredentials;
options.preflightPolicy = PreventPreflight;
options.crossOriginRequestPolicy = UseAccessControl;
- options.dataBufferingPolicy = DoNotBufferData;
- options.securityOrigin = origin;
- options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) ? DoNotEnforceContentSecurityPolicy : EnforceConnectSrcDirective;
+ options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypassMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConnectSrcDirective;
- m_loader = ThreadableLoader::create(executionContext(), this, request, options);
+ ResourceLoaderOptions resourceLoaderOptions;
+ resourceLoaderOptions.allowCredentials = (origin->canRequest(m_url) || m_withCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+ resourceLoaderOptions.credentialsRequested = m_withCredentials ? ClientRequestedCredentials : ClientDidNotRequestCredentials;
+ resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
+ resourceLoaderOptions.securityOrigin = origin;
+
+ m_loader = ThreadableLoader::create(executionContext, this, request, options, resourceLoaderOptions);
if (m_loader)
m_requestInFlight = true;
@@ -167,7 +169,7 @@ void EventSource::networkRequestEnded()
void EventSource::scheduleReconnect()
{
m_state = CONNECTING;
- m_connectTimer.startOneShot(m_reconnectDelay / 1000.0);
+ m_connectTimer.startOneShot(m_reconnectDelay / 1000.0, FROM_HERE);
dispatchEvent(Event::create(EventTypeNames::error));
}
@@ -282,8 +284,8 @@ void EventSource::didFinishLoading(unsigned long, double)
// Discard everything that has not been dispatched by now.
m_receiveBuf.clear();
m_data.clear();
- m_eventName = "";
- m_currentlyParsedEventId = String();
+ m_eventName = emptyAtom;
+ m_currentlyParsedEventId = nullAtom;
}
networkRequestEnded();
}
@@ -328,8 +330,8 @@ void EventSource::abortConnectionAttempt()
void EventSource::parseEventStream()
{
- unsigned int bufPos = 0;
- unsigned int bufSize = m_receiveBuf.size();
+ unsigned bufPos = 0;
+ unsigned bufSize = m_receiveBuf.size();
while (bufPos < bufSize) {
if (m_discardTrailingNewline) {
if (m_receiveBuf[bufPos] == '\n')
@@ -339,7 +341,7 @@ void EventSource::parseEventStream()
int lineLength = -1;
int fieldLength = -1;
- for (unsigned int i = bufPos; lineLength < 0 && i < bufSize; i++) {
+ for (unsigned i = bufPos; lineLength < 0 && i < bufSize; i++) {
switch (m_receiveBuf[i]) {
case ':':
if (fieldLength < 0)
@@ -377,13 +379,13 @@ void EventSource::parseEventStreamLine(unsigned bufPos, int fieldLength, int lin
if (!m_data.isEmpty()) {
m_data.removeLast();
if (!m_currentlyParsedEventId.isNull()) {
- m_lastEventId.swap(m_currentlyParsedEventId);
- m_currentlyParsedEventId = String();
+ m_lastEventId = m_currentlyParsedEventId;
+ m_currentlyParsedEventId = nullAtom;
}
dispatchEvent(createMessageEvent());
}
if (!m_eventName.isEmpty())
- m_eventName = "";
+ m_eventName = emptyAtom;
} else if (fieldLength) {
bool noValue = fieldLength < 0;
@@ -402,11 +404,11 @@ void EventSource::parseEventStreamLine(unsigned bufPos, int fieldLength, int lin
if (valueLength)
m_data.append(&m_receiveBuf[bufPos], valueLength);
m_data.append('\n');
- } else if (field == "event")
- m_eventName = valueLength ? String(&m_receiveBuf[bufPos], valueLength) : "";
- else if (field == "id")
- m_currentlyParsedEventId = valueLength ? String(&m_receiveBuf[bufPos], valueLength) : "";
- else if (field == "retry") {
+ } else if (field == "event") {
+ m_eventName = valueLength ? AtomicString(&m_receiveBuf[bufPos], valueLength) : "";
+ } else if (field == "id") {
+ m_currentlyParsedEventId = valueLength ? AtomicString(&m_receiveBuf[bufPos], valueLength) : "";
+ } else if (field == "retry") {
if (!valueLength)
m_reconnectDelay = defaultReconnectDelay;
else {
@@ -425,10 +427,10 @@ void EventSource::stop()
close();
}
-PassRefPtr<MessageEvent> EventSource::createMessageEvent()
+PassRefPtrWillBeRawPtr<MessageEvent> EventSource::createMessageEvent()
{
- RefPtr<MessageEvent> event = MessageEvent::create();
- event->initMessageEvent(m_eventName.isEmpty() ? EventTypeNames::message : AtomicString(m_eventName), false, false, SerializedScriptValue::create(String(m_data)), m_eventStreamOrigin, m_lastEventId, 0, nullptr);
+ RefPtrWillBeRawPtr<MessageEvent> event = MessageEvent::create();
+ event->initMessageEvent(m_eventName.isEmpty() ? EventTypeNames::message : m_eventName, false, false, SerializedScriptValue::create(String(m_data)), m_eventStreamOrigin, m_lastEventId, 0, nullptr);
m_data.clear();
return event.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/page/EventSource.h b/chromium/third_party/WebKit/Source/core/page/EventSource.h
index 66ea83aa1b8..38b795fa2d6 100644
--- a/chromium/third_party/WebKit/Source/core/page/EventSource.h
+++ b/chromium/third_party/WebKit/Source/core/page/EventSource.h
@@ -37,6 +37,7 @@
#include "core/events/EventTarget.h"
#include "core/loader/ThreadableLoaderClient.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
@@ -50,11 +51,12 @@ class ResourceResponse;
class TextResourceDecoder;
class ThreadableLoader;
-class EventSource : public RefCounted<EventSource>, public ScriptWrappable, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject {
- WTF_MAKE_FAST_ALLOCATED;
+class EventSource FINAL : public RefCountedWillBeRefCountedGarbageCollected<EventSource>, public ScriptWrappable, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
REFCOUNTED_EVENT_TARGET(EventSource);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(EventSource);
public:
- static PassRefPtr<EventSource> create(ExecutionContext*, const String& url, const Dictionary&, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<EventSource> create(ExecutionContext*, const String& url, const Dictionary&, ExceptionState&);
virtual ~EventSource();
static const unsigned long long defaultReconnectDelay;
@@ -80,7 +82,7 @@ public:
// ActiveDOMObject
//
- // Note: suspend() is noop since PageGroupLoadDeferrer calls
+ // Note: suspend() is noop since ScopedPageLoadDeferrer calls
// Page::setDefersLoading() and it defers delivery of events from the
// loader, and therefore the methods of this class for receiving
// asynchronous events from the loader won't be invoked.
@@ -89,12 +91,12 @@ public:
private:
EventSource(ExecutionContext*, const KURL&, const Dictionary&);
- virtual void didReceiveResponse(unsigned long, const ResourceResponse&);
- virtual void didReceiveData(const char*, int);
- virtual void didFinishLoading(unsigned long, double);
- virtual void didFail(const ResourceError&);
- virtual void didFailAccessControlCheck(const ResourceError&);
- virtual void didFailRedirectCheck();
+ virtual void didReceiveResponse(unsigned long, const ResourceResponse&) OVERRIDE;
+ virtual void didReceiveData(const char*, int) OVERRIDE;
+ virtual void didFinishLoading(unsigned long, double) OVERRIDE;
+ virtual void didFail(const ResourceError&) OVERRIDE;
+ virtual void didFailAccessControlCheck(const ResourceError&) OVERRIDE;
+ virtual void didFailRedirectCheck() OVERRIDE;
void scheduleInitialConnect();
void connect();
@@ -104,7 +106,7 @@ private:
void abortConnectionAttempt();
void parseEventStream();
void parseEventStreamLine(unsigned pos, int fieldLength, int lineLength);
- PassRefPtr<MessageEvent> createMessageEvent();
+ PassRefPtrWillBeRawPtr<MessageEvent> createMessageEvent();
KURL m_url;
bool m_withCredentials;
@@ -117,10 +119,10 @@ private:
bool m_discardTrailingNewline;
bool m_requestInFlight;
- String m_eventName;
+ AtomicString m_eventName;
Vector<UChar> m_data;
- String m_currentlyParsedEventId;
- String m_lastEventId;
+ AtomicString m_currentlyParsedEventId;
+ AtomicString m_lastEventId;
unsigned long long m_reconnectDelay;
String m_eventStreamOrigin;
};
diff --git a/chromium/third_party/WebKit/Source/core/page/EventSource.idl b/chromium/third_party/WebKit/Source/core/page/EventSource.idl
index 3562791dd24..932fecee733 100644
--- a/chromium/third_party/WebKit/Source/core/page/EventSource.idl
+++ b/chromium/third_party/WebKit/Source/core/page/EventSource.idl
@@ -30,14 +30,15 @@
*/
[
+ WillBeGarbageCollected,
ActiveDOMObject,
Constructor(DOMString url, optional Dictionary eventSourceInit),
ConstructorCallWith=ExecutionContext,
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker,
RaisesException=Constructor,
] interface EventSource : EventTarget {
- readonly attribute DOMString URL; // Lowercased .url is the one in the spec, but leaving .URL for compatibility reasons.
+ [MeasureAs=EventSourceURL] readonly attribute DOMString URL; // Lowercased .url is the one in the spec, but leaving .URL for compatibility reasons.
readonly attribute DOMString url;
readonly attribute boolean withCredentials;
diff --git a/chromium/third_party/WebKit/Source/core/page/FocusController.cpp b/chromium/third_party/WebKit/Source/core/page/FocusController.cpp
index 686e013aa82..a637e983a91 100644
--- a/chromium/third_party/WebKit/Source/core/page/FocusController.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/FocusController.cpp
@@ -27,8 +27,7 @@
#include "config.h"
#include "core/page/FocusController.h"
-#include <limits>
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
@@ -41,14 +40,14 @@
#include "core/editing/FrameSelection.h"
#include "core/editing/htmlediting.h" // For firstPositionInOrBeforeNode
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAreaElement.h"
#include "core/html/HTMLImageElement.h"
-#include "core/html/HTMLTextAreaElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLPlugInElement.h"
+#include "core/html/HTMLShadowElement.h"
+#include "core/html/HTMLTextFormControlElement.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
#include "core/page/EventHandler.h"
@@ -57,11 +56,18 @@
#include "core/frame/Settings.h"
#include "core/page/SpatialNavigation.h"
#include "core/rendering/HitTestResult.h"
+#include "core/rendering/RenderLayer.h"
+#include <limits>
namespace WebCore {
using namespace HTMLNames;
+static inline bool isShadowInsertionPointFocusScopeOwner(Node& node)
+{
+ return isActiveShadowInsertionPoint(node) && toHTMLShadowElement(node).olderShadowRoot();
+}
+
// FIXME: Some of Node* return values and Node* arguments should be Element*.
FocusNavigationScope::FocusNavigationScope(TreeScope* treeScope)
@@ -72,7 +78,7 @@ FocusNavigationScope::FocusNavigationScope(TreeScope* treeScope)
Node* FocusNavigationScope::rootNode() const
{
- return m_rootTreeScope->rootNode();
+ return &m_rootTreeScope->rootNode();
}
Element* FocusNavigationScope::owner() const
@@ -82,8 +88,9 @@ Element* FocusNavigationScope::owner() const
ShadowRoot* shadowRoot = toShadowRoot(root);
return shadowRoot->isYoungest() ? shadowRoot->host() : shadowRoot->shadowInsertionPointOfYoungerShadowRoot();
}
+ // FIXME: Figure out the right thing for OOPI here.
if (Frame* frame = root->document().frame())
- return frame->ownerElement();
+ return frame->deprecatedLocalOwner();
return 0;
}
@@ -103,7 +110,7 @@ FocusNavigationScope FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(No
ASSERT(node);
if (isShadowHost(node))
return FocusNavigationScope::ownedByShadowHost(node);
- ASSERT(isActiveShadowInsertionPoint(*node));
+ ASSERT(isShadowInsertionPointFocusScopeOwner(*node));
return FocusNavigationScope::ownedByShadowInsertionPoint(toHTMLShadowElement(node));
}
@@ -115,13 +122,13 @@ FocusNavigationScope FocusNavigationScope::ownedByShadowHost(Node* node)
FocusNavigationScope FocusNavigationScope::ownedByIFrame(HTMLFrameOwnerElement* frame)
{
- ASSERT(frame && frame->contentFrame());
- return FocusNavigationScope(frame->contentFrame()->document());
+ ASSERT(frame && frame->contentFrame() && frame->contentFrame()->isLocalFrame());
+ return FocusNavigationScope(toLocalFrame(frame->contentFrame())->document());
}
FocusNavigationScope FocusNavigationScope::ownedByShadowInsertionPoint(HTMLShadowElement* shadowInsertionPoint)
{
- ASSERT(shadowInsertionPoint->isActive());
+ ASSERT(isShadowInsertionPointFocusScopeOwner(*shadowInsertionPoint));
return FocusNavigationScope(shadowInsertionPoint->olderShadowRoot());
}
@@ -138,7 +145,8 @@ static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool
}
if (!focused && document->focusedElement()) {
- RefPtr<Element> focusedElement(document->focusedElement());
+ RefPtrWillBeRawPtr<Element> focusedElement(document->focusedElement());
+ focusedElement->setFocus(false);
focusedElement->dispatchBlurEvent(0);
if (focusedElement == document->focusedElement()) {
focusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, 0);
@@ -147,11 +155,12 @@ static inline void dispatchEventsOnWindowAndFocusedNode(Document* document, bool
}
}
- if (DOMWindow* window = document->domWindow())
+ if (LocalDOMWindow* window = document->domWindow())
window->dispatchEvent(Event::create(focused ? EventTypeNames::focus : EventTypeNames::blur));
if (focused && document->focusedElement()) {
- RefPtr<Element> focusedElement(document->focusedElement());
- focusedElement->dispatchFocusEvent(0, FocusDirectionPage);
+ RefPtrWillBeRawPtr<Element> focusedElement(document->focusedElement());
+ focusedElement->setFocus(true);
+ focusedElement->dispatchFocusEvent(0, FocusTypePage);
if (focusedElement == document->focusedElement()) {
document->focusedElement()->dispatchFocusInEvent(EventTypeNames::focusin, 0);
if (focusedElement == document->focusedElement())
@@ -165,7 +174,7 @@ static inline bool hasCustomFocusLogic(Element* element)
return element->isHTMLElement() && toHTMLElement(element)->hasCustomFocusLogic();
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
static inline bool isNonFocusableShadowHost(Node* node)
{
ASSERT(node);
@@ -197,7 +206,7 @@ static inline bool isKeyboardFocusableShadowHost(Node* node)
static inline bool isNonFocusableFocusScopeOwner(Node* node)
{
ASSERT(node);
- return isNonKeyboardFocusableShadowHost(node) || isActiveShadowInsertionPoint(*node);
+ return isNonKeyboardFocusableShadowHost(node) || isShadowInsertionPointFocusScopeOwner(*node);
}
static inline int adjustedTabIndex(Node* node)
@@ -217,7 +226,6 @@ FocusController::FocusController(Page* page)
, m_isActive(false)
, m_isFocused(false)
, m_isChangingFocusedFrame(false)
- , m_containingWindowIsVisible(false)
{
}
@@ -234,10 +242,10 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
m_isChangingFocusedFrame = true;
- RefPtr<Frame> oldFrame = m_focusedFrame;
- RefPtr<Frame> newFrame = frame;
+ RefPtr<LocalFrame> oldFrame = (m_focusedFrame && m_focusedFrame->isLocalFrame()) ? toLocalFrame(m_focusedFrame.get()) : 0;
+ RefPtr<LocalFrame> newFrame = (frame && frame->isLocalFrame()) ? toLocalFrame(frame.get()) : 0;
- m_focusedFrame = newFrame;
+ m_focusedFrame = frame.get();
// Now that the frame is updated, fire events and update the selection focused states of both frames.
if (oldFrame && oldFrame->view()) {
@@ -251,6 +259,45 @@ void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
}
m_isChangingFocusedFrame = false;
+
+ m_page->chrome().client().focusedFrameChanged(newFrame.get());
+}
+
+void FocusController::focusDocumentView(PassRefPtr<Frame> frame)
+{
+ ASSERT(!frame || frame->page() == m_page);
+ if (m_focusedFrame == frame)
+ return;
+
+ RefPtr<LocalFrame> focusedFrame = (m_focusedFrame && m_focusedFrame->isLocalFrame()) ? toLocalFrame(m_focusedFrame.get()) : 0;
+ if (focusedFrame && focusedFrame->view()) {
+ RefPtrWillBeRawPtr<Document> document = focusedFrame->document();
+ Element* focusedElement = document ? document->focusedElement() : 0;
+ if (focusedElement) {
+ focusedElement->dispatchBlurEvent(0);
+ if (focusedElement == document->focusedElement()) {
+ focusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, 0);
+ if (focusedElement == document->focusedElement())
+ focusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, 0);
+ }
+ }
+ }
+
+ RefPtr<LocalFrame> newFocusedFrame = (frame && frame->isLocalFrame()) ? toLocalFrame(frame.get()) : 0;
+ if (newFocusedFrame && newFocusedFrame->view()) {
+ RefPtrWillBeRawPtr<Document> document = newFocusedFrame->document();
+ Element* focusedElement = document ? document->focusedElement() : 0;
+ if (focusedElement) {
+ focusedElement->dispatchFocusEvent(0, FocusTypePage);
+ if (focusedElement == document->focusedElement()) {
+ document->focusedElement()->dispatchFocusInEvent(EventTypeNames::focusin, 0);
+ if (focusedElement == document->focusedElement())
+ document->focusedElement()->dispatchFocusInEvent(EventTypeNames::DOMFocusIn, 0);
+ }
+ }
+ }
+
+ setFocusedFrame(frame);
}
Frame* FocusController::focusedOrMainFrame() const
@@ -267,28 +314,30 @@ void FocusController::setFocused(bool focused)
m_isFocused = focused;
- if (!m_isFocused)
- focusedOrMainFrame()->eventHandler().stopAutoscroll();
+ if (!m_isFocused && focusedOrMainFrame()->isLocalFrame())
+ toLocalFrame(focusedOrMainFrame())->eventHandler().stopAutoscroll();
if (!m_focusedFrame)
setFocusedFrame(m_page->mainFrame());
- if (m_focusedFrame->view()) {
- m_focusedFrame->selection().setFocused(focused);
- dispatchEventsOnWindowAndFocusedNode(m_focusedFrame->document(), focused);
+ // setFocusedFrame above might reject to update m_focusedFrame, or
+ // m_focusedFrame might be changed by blur/focus event handlers.
+ if (m_focusedFrame && m_focusedFrame->isLocalFrame() && toLocalFrame(m_focusedFrame.get())->view()) {
+ toLocalFrame(m_focusedFrame.get())->selection().setFocused(focused);
+ dispatchEventsOnWindowAndFocusedNode(toLocalFrame(m_focusedFrame.get())->document(), focused);
}
}
-Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(FocusDirection direction, Node* node)
+Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(FocusType type, Node* node)
{
// The node we found might be a HTMLFrameOwnerElement, so descend down the tree until we find either:
// 1) a focusable node, or
// 2) the deepest-nested HTMLFrameOwnerElement.
while (node && node->isFrameOwnerElement()) {
HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(node);
- if (!owner->contentFrame())
+ if (!owner->contentFrame() || !owner->contentFrame()->isLocalFrame())
break;
- Node* foundNode = findFocusableNode(direction, FocusNavigationScope::ownedByIFrame(owner), 0);
+ Node* foundNode = findFocusableNode(type, FocusNavigationScope::ownedByIFrame(owner), 0);
if (!foundNode)
break;
ASSERT(node != foundNode);
@@ -297,30 +346,33 @@ Node* FocusController::findFocusableNodeDecendingDownIntoFrameDocument(FocusDire
return node;
}
-bool FocusController::setInitialFocus(FocusDirection direction)
+bool FocusController::setInitialFocus(FocusType type)
{
- bool didAdvanceFocus = advanceFocus(direction, true);
+ bool didAdvanceFocus = advanceFocus(type, true);
// If focus is being set initially, accessibility needs to be informed that system focus has moved
// into the web area again, even if focus did not change within WebCore. PostNotification is called instead
// of handleFocusedUIElementChanged, because this will send the notification even if the element is the same.
- if (AXObjectCache* cache = focusedOrMainFrame()->document()->existingAXObjectCache())
- cache->postNotification(focusedOrMainFrame()->document(), AXObjectCache::AXFocusedUIElementChanged, true);
+ if (focusedOrMainFrame()->isLocalFrame()) {
+ Document* document = toLocalFrame(focusedOrMainFrame())->document();
+ if (AXObjectCache* cache = document->existingAXObjectCache())
+ cache->postNotification(document, AXObjectCache::AXFocusedUIElementChanged, true);
+ }
return didAdvanceFocus;
}
-bool FocusController::advanceFocus(FocusDirection direction, bool initialFocus)
+bool FocusController::advanceFocus(FocusType type, bool initialFocus)
{
- switch (direction) {
- case FocusDirectionForward:
- case FocusDirectionBackward:
- return advanceFocusInDocumentOrder(direction, initialFocus);
- case FocusDirectionLeft:
- case FocusDirectionRight:
- case FocusDirectionUp:
- case FocusDirectionDown:
- return advanceFocusDirectionally(direction);
+ switch (type) {
+ case FocusTypeForward:
+ case FocusTypeBackward:
+ return advanceFocusInDocumentOrder(type, initialFocus);
+ case FocusTypeLeft:
+ case FocusTypeRight:
+ case FocusTypeUp:
+ case FocusTypeDown:
+ return advanceFocusDirectionally(type);
default:
ASSERT_NOT_REACHED();
}
@@ -328,9 +380,13 @@ bool FocusController::advanceFocus(FocusDirection direction, bool initialFocus)
return false;
}
-bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, bool initialFocus)
+bool FocusController::advanceFocusInDocumentOrder(FocusType type, bool initialFocus)
{
- Frame* frame = focusedOrMainFrame();
+ // FIXME: Focus advancement won't work with externally rendered frames until after
+ // inter-frame focus control is moved out of Blink.
+ if (!focusedOrMainFrame()->isLocalFrame())
+ return false;
+ LocalFrame* frame = toLocalFrame(focusedOrMainFrame());
ASSERT(frame);
Document* document = frame->document();
@@ -343,20 +399,22 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, bool
document->updateLayoutIgnorePendingStylesheets();
- RefPtr<Node> node = findFocusableNodeAcrossFocusScope(direction, FocusNavigationScope::focusNavigationScopeOf(currentNode ? currentNode : document), currentNode);
+ RefPtrWillBeRawPtr<Node> node = findFocusableNodeAcrossFocusScope(type, FocusNavigationScope::focusNavigationScopeOf(currentNode ? currentNode : document), currentNode);
if (!node) {
// We didn't find a node to focus, so we should try to pass focus to Chrome.
- if (!initialFocus && m_page->chrome().canTakeFocus(direction)) {
- document->setFocusedElement(0);
- setFocusedFrame(0);
- m_page->chrome().takeFocus(direction);
+ if (!initialFocus && m_page->chrome().canTakeFocus(type)) {
+ document->setFocusedElement(nullptr);
+ setFocusedFrame(nullptr);
+ m_page->chrome().takeFocus(type);
return true;
}
// Chrome doesn't want focus, so we should wrap focus.
- node = findFocusableNodeRecursively(direction, FocusNavigationScope::focusNavigationScopeOf(m_page->mainFrame()->document()), 0);
- node = findFocusableNodeDecendingDownIntoFrameDocument(direction, node.get());
+ if (!m_page->mainFrame()->isLocalFrame())
+ return false;
+ node = findFocusableNodeRecursively(type, FocusNavigationScope::focusNavigationScopeOf(m_page->deprecatedLocalMainFrame()->document()), 0);
+ node = findFocusableNodeDecendingDownIntoFrameDocument(type, node.get());
if (!node)
return false;
@@ -373,14 +431,14 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, bool
return false;
Element* element = toElement(node);
- if (element->isFrameOwnerElement() && (!element->isPluginElement() || !element->isKeyboardFocusable())) {
+ if (element->isFrameOwnerElement() && (!isHTMLPlugInElement(*element) || !element->isKeyboardFocusable())) {
// We focus frames rather than frame owners.
// FIXME: We should not focus frames that have no scrollbars, as focusing them isn't useful to the user.
HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(element);
if (!owner->contentFrame())
return false;
- document->setFocusedElement(0);
+ document->setFocusedElement(nullptr);
setFocusedFrame(owner->contentFrame());
return true;
}
@@ -392,7 +450,7 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, bool
if (&newDocument != document) {
// Focus is going away from this document, so clear the focused node.
- document->setFocusedElement(0);
+ document->setFocusedElement(nullptr);
}
setFocusedFrame(newDocument.frame());
@@ -403,19 +461,19 @@ bool FocusController::advanceFocusInDocumentOrder(FocusDirection direction, bool
frame->selection().setSelection(newSelection);
}
- element->focus(false, direction);
+ element->focus(false, type);
return true;
}
-Node* FocusController::findFocusableNodeAcrossFocusScope(FocusDirection direction, FocusNavigationScope scope, Node* currentNode)
+Node* FocusController::findFocusableNodeAcrossFocusScope(FocusType type, FocusNavigationScope scope, Node* currentNode)
{
ASSERT(!currentNode || !isNonFocusableShadowHost(currentNode));
Node* found;
- if (currentNode && direction == FocusDirectionForward && isKeyboardFocusableShadowHost(currentNode)) {
- Node* foundInInnerFocusScope = findFocusableNodeRecursively(direction, FocusNavigationScope::ownedByShadowHost(currentNode), 0);
- found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNodeRecursively(direction, scope, currentNode);
+ if (currentNode && type == FocusTypeForward && isKeyboardFocusableShadowHost(currentNode)) {
+ Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusNavigationScope::ownedByShadowHost(currentNode), 0);
+ found = foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNodeRecursively(type, scope, currentNode);
} else {
- found = findFocusableNodeRecursively(direction, scope, currentNode);
+ found = findFocusableNodeRecursively(type, scope, currentNode);
}
// If there's no focusable node to advance to, move up the focus scopes until we find one.
@@ -424,51 +482,49 @@ Node* FocusController::findFocusableNodeAcrossFocusScope(FocusDirection directio
if (!owner)
break;
scope = FocusNavigationScope::focusNavigationScopeOf(owner);
- if (direction == FocusDirectionBackward && isKeyboardFocusableShadowHost(owner)) {
+ if (type == FocusTypeBackward && isKeyboardFocusableShadowHost(owner)) {
found = owner;
break;
}
- found = findFocusableNodeRecursively(direction, scope, owner);
+ found = findFocusableNodeRecursively(type, scope, owner);
}
- found = findFocusableNodeDecendingDownIntoFrameDocument(direction, found);
+ found = findFocusableNodeDecendingDownIntoFrameDocument(type, found);
return found;
}
-Node* FocusController::findFocusableNodeRecursively(FocusDirection direction, FocusNavigationScope scope, Node* start)
+Node* FocusController::findFocusableNodeRecursively(FocusType type, FocusNavigationScope scope, Node* start)
{
// Starting node is exclusive.
- Node* found = findFocusableNode(direction, scope, start);
+ Node* found = findFocusableNode(type, scope, start);
if (!found)
return 0;
- if (direction == FocusDirectionForward) {
+ if (type == FocusTypeForward) {
if (!isNonFocusableFocusScopeOwner(found))
return found;
- Node* foundInInnerFocusScope = findFocusableNodeRecursively(direction, FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(found), 0);
- return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNodeRecursively(direction, scope, found);
+ Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(found), 0);
+ return foundInInnerFocusScope ? foundInInnerFocusScope : findFocusableNodeRecursively(type, scope, found);
}
- ASSERT(direction == FocusDirectionBackward);
+ ASSERT(type == FocusTypeBackward);
if (isKeyboardFocusableShadowHost(found)) {
- Node* foundInInnerFocusScope = findFocusableNodeRecursively(direction, FocusNavigationScope::ownedByShadowHost(found), 0);
+ Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusNavigationScope::ownedByShadowHost(found), 0);
return foundInInnerFocusScope ? foundInInnerFocusScope : found;
}
if (isNonFocusableFocusScopeOwner(found)) {
- Node* foundInInnerFocusScope = findFocusableNodeRecursively(direction, FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(found), 0);
- return foundInInnerFocusScope ? foundInInnerFocusScope :findFocusableNodeRecursively(direction, scope, found);
+ Node* foundInInnerFocusScope = findFocusableNodeRecursively(type, FocusNavigationScope::ownedByNonFocusableFocusScopeOwner(found), 0);
+ return foundInInnerFocusScope ? foundInInnerFocusScope :findFocusableNodeRecursively(type, scope, found);
}
return found;
}
-Node* FocusController::findFocusableNode(FocusDirection direction, FocusNavigationScope scope, Node* node)
+Node* FocusController::findFocusableNode(FocusType type, FocusNavigationScope scope, Node* node)
{
- return (direction == FocusDirectionForward)
- ? nextFocusableNode(scope, node)
- : previousFocusableNode(scope, node);
+ return type == FocusTypeForward ? nextFocusableNode(scope, node) : previousFocusableNode(scope, node);
}
-Node* FocusController::findNodeWithExactTabIndex(Node* start, int tabIndex, FocusDirection direction)
+Node* FocusController::findNodeWithExactTabIndex(Node* start, int tabIndex, FocusType type)
{
// Search is inclusive of start
- for (Node* node = start; node; node = direction == FocusDirectionForward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)) {
+ for (Node* node = start; node; node = type == FocusTypeForward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)) {
if (shouldVisit(node) && adjustedTabIndex(node) == tabIndex)
return node;
}
@@ -518,7 +574,7 @@ Node* FocusController::nextFocusableNode(FocusNavigationScope scope, Node* start
}
// First try to find a node with the same tabindex as start that comes after start in the scope.
- if (Node* winner = findNodeWithExactTabIndex(NodeTraversal::next(*start), tabIndex, FocusDirectionForward))
+ if (Node* winner = findNodeWithExactTabIndex(NodeTraversal::next(*start), tabIndex, FocusTypeForward))
return winner;
if (!tabIndex)
@@ -534,7 +590,7 @@ Node* FocusController::nextFocusableNode(FocusNavigationScope scope, Node* start
// There are no nodes with a tabindex greater than start's tabindex,
// so find the first node with a tabindex of 0.
- return findNodeWithExactTabIndex(scope.rootNode(), 0, FocusDirectionForward);
+ return findNodeWithExactTabIndex(scope.rootNode(), 0, FocusTypeForward);
}
Node* FocusController::previousFocusableNode(FocusNavigationScope scope, Node* start)
@@ -564,7 +620,7 @@ Node* FocusController::previousFocusableNode(FocusNavigationScope scope, Node* s
}
}
- if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIndex, FocusDirectionBackward))
+ if (Node* winner = findNodeWithExactTabIndex(startingNode, startingTabIndex, FocusTypeBackward))
return winner;
// There are no nodes before start with the same tabindex as start, so look for a node that:
@@ -581,7 +637,7 @@ static bool relinquishesEditingFocus(Node *node)
return node->document().frame() && node->rootEditableElement();
}
-static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFrame, Node* newFocusedNode)
+static void clearSelectionIfNeeded(LocalFrame* oldFocusedFrame, LocalFrame* newFocusedFrame, Node* newFocusedNode)
{
if (!oldFocusedFrame || !newFocusedFrame)
return;
@@ -603,25 +659,20 @@ static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFram
if (Node* mousePressNode = newFocusedFrame->eventHandler().mousePressNode()) {
if (mousePressNode->renderer() && !mousePressNode->canStartSelection()) {
- // Don't clear the selection for contentEditable elements, but do clear it for input and textarea. See bug 38696.
- Node* root = selection.rootEditableElement();
- if (!root)
+ // Don't clear the selection for contentEditable elements, but do
+ // clear it for input and textarea. See bug 38696.
+ if (!enclosingTextFormControl(selection.start()))
return;
-
- if (Node* shadowAncestorNode = root->deprecatedShadowAncestorNode()) {
- if (!shadowAncestorNode->hasTagName(inputTag) && !isHTMLTextAreaElement(shadowAncestorNode))
- return;
- }
}
}
selection.clear();
}
-bool FocusController::setFocusedElement(Element* element, PassRefPtr<Frame> newFocusedFrame, FocusDirection direction)
+bool FocusController::setFocusedElement(Element* element, PassRefPtr<Frame> newFocusedFrame, FocusType type)
{
- RefPtr<Frame> oldFocusedFrame = focusedFrame();
- RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;
+ RefPtr<LocalFrame> oldFocusedFrame = toLocalFrame(focusedFrame());
+ RefPtrWillBeRawPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;
Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : 0;
if (element && oldFocusedElement == element)
@@ -633,30 +684,30 @@ bool FocusController::setFocusedElement(Element* element, PassRefPtr<Frame> newF
m_page->chrome().client().willSetInputMethodState();
- RefPtr<Document> newDocument;
+ RefPtrWillBeRawPtr<Document> newDocument = nullptr;
if (element)
newDocument = &element->document();
- else if (newFocusedFrame)
- newDocument = newFocusedFrame->document();
+ else if (newFocusedFrame && newFocusedFrame->isLocalFrame())
+ newDocument = toLocalFrame(newFocusedFrame.get())->document();
if (newDocument && oldDocument == newDocument && newDocument->focusedElement() == element)
return true;
- clearSelectionIfNeeded(oldFocusedFrame.get(), newFocusedFrame.get(), element);
+ clearSelectionIfNeeded(oldFocusedFrame.get(), toLocalFrame(newFocusedFrame.get()), element);
if (oldDocument && oldDocument != newDocument)
- oldDocument->setFocusedElement(0);
+ oldDocument->setFocusedElement(nullptr);
if (newFocusedFrame && !newFocusedFrame->page()) {
- setFocusedFrame(0);
+ setFocusedFrame(nullptr);
return false;
}
setFocusedFrame(newFocusedFrame);
// Setting the focused node can result in losing our last reft to node when JS event handlers fire.
- RefPtr<Element> protect = element;
+ RefPtrWillBeRawPtr<Element> protect ALLOW_UNUSED = element;
if (newDocument) {
- bool successfullyFocused = newDocument->setFocusedElement(element, direction);
+ bool successfullyFocused = newDocument->setFocusedElement(element, type);
if (!successfullyFocused)
return false;
}
@@ -671,54 +722,15 @@ void FocusController::setActive(bool active)
m_isActive = active;
- if (FrameView* view = m_page->mainFrame()->view()) {
- view->updateLayoutAndStyleIfNeededRecursive();
- view->updateControlTints();
+ if (m_page->mainFrame()->isLocalFrame()) {
+ if (FrameView* view = m_page->deprecatedLocalMainFrame()->view())
+ view->updateControlTints();
}
- focusedOrMainFrame()->selection().pageActivationChanged();
-}
-
-static void contentAreaDidShowOrHide(ScrollableArea* scrollableArea, bool didShow)
-{
- if (didShow)
- scrollableArea->contentAreaDidShow();
- else
- scrollableArea->contentAreaDidHide();
-}
-
-void FocusController::setContainingWindowIsVisible(bool containingWindowIsVisible)
-{
- if (m_containingWindowIsVisible == containingWindowIsVisible)
- return;
-
- m_containingWindowIsVisible = containingWindowIsVisible;
-
- FrameView* view = m_page->mainFrame()->view();
- if (!view)
- return;
-
- contentAreaDidShowOrHide(view, containingWindowIsVisible);
-
- for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- FrameView* frameView = frame->view();
- if (!frameView)
- continue;
-
- const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas();
- if (!scrollableAreas)
- continue;
-
- for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
- ScrollableArea* scrollableArea = *it;
- ASSERT(scrollableArea->scrollbarsCanBeActive());
-
- contentAreaDidShowOrHide(scrollableArea, containingWindowIsVisible);
- }
- }
+ toLocalFrame(focusedOrMainFrame())->selection().pageActivationChanged();
}
-static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCandidate& current, FocusCandidate& candidate, FocusCandidate& closest)
+static void updateFocusCandidateIfNeeded(FocusType type, const FocusCandidate& current, FocusCandidate& candidate, FocusCandidate& closest)
{
ASSERT(candidate.visibleNode->isElementNode());
ASSERT(candidate.visibleNode->renderer());
@@ -728,10 +740,10 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCa
return;
// Ignore off screen child nodes of containers that do not scroll (overflow:hidden)
- if (candidate.isOffscreen && !canBeScrolledIntoView(direction, candidate))
+ if (candidate.isOffscreen && !canBeScrolledIntoView(type, candidate))
return;
- distanceDataForNode(direction, current, candidate);
+ distanceDataForNode(type, current, candidate);
if (candidate.distance == maxDistance())
return;
@@ -744,11 +756,14 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCa
}
LayoutRect intersectionRect = intersection(candidate.rect, closest.rect);
- if (!intersectionRect.isEmpty() && !areElementsOnSameLine(closest, candidate)) {
+ if (!intersectionRect.isEmpty() && !areElementsOnSameLine(closest, candidate)
+ && intersectionRect == candidate.rect) {
// If 2 nodes are intersecting, do hit test to find which node in on top.
LayoutUnit x = intersectionRect.x() + intersectionRect.width() / 2;
LayoutUnit y = intersectionRect.y() + intersectionRect.height() / 2;
- HitTestResult result = candidate.visibleNode->document().page()->mainFrame()->eventHandler().hitTestResultAtPoint(IntPoint(x, y), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
+ if (!candidate.visibleNode->document().page()->mainFrame()->isLocalFrame())
+ return;
+ HitTestResult result = candidate.visibleNode->document().page()->deprecatedLocalMainFrame()->eventHandler().hitTestResultAtPoint(IntPoint(x, y), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
if (candidate.visibleNode->contains(result.innerNode())) {
closest = candidate;
return;
@@ -767,9 +782,9 @@ static void updateFocusCandidateIfNeeded(FocusDirection direction, const FocusCa
closest = candidate;
}
-void FocusController::findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, FocusDirection direction, FocusCandidate& closest)
+void FocusController::findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, FocusType type, FocusCandidate& closest)
{
- Element* focusedElement = (focusedFrame() && focusedFrame()->document()) ? focusedFrame()->document()->focusedElement() : 0;
+ Element* focusedElement = (focusedFrame() && toLocalFrame(focusedFrame())->document()) ? toLocalFrame(focusedFrame())->document()->focusedElement() : 0;
Element* element = ElementTraversal::firstWithin(container);
FocusCandidate current;
@@ -777,25 +792,25 @@ void FocusController::findFocusCandidateInContainer(Node& container, const Layou
current.focusableNode = focusedElement;
current.visibleNode = focusedElement;
- for (; element; element = (element->isFrameOwnerElement() || canScrollInDirection(element, direction))
+ for (; element; element = (element->isFrameOwnerElement() || canScrollInDirection(element, type))
? ElementTraversal::nextSkippingChildren(*element, &container)
: ElementTraversal::next(*element, &container)) {
if (element == focusedElement)
continue;
- if (!element->isKeyboardFocusable() && !element->isFrameOwnerElement() && !canScrollInDirection(element, direction))
+ if (!element->isKeyboardFocusable() && !element->isFrameOwnerElement() && !canScrollInDirection(element, type))
continue;
- FocusCandidate candidate = FocusCandidate(element, direction);
+ FocusCandidate candidate = FocusCandidate(element, type);
if (candidate.isNull())
continue;
candidate.enclosingScrollableBox = &container;
- updateFocusCandidateIfNeeded(direction, current, candidate, closest);
+ updateFocusCandidateIfNeeded(type, current, candidate, closest);
}
}
-bool FocusController::advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, FocusDirection direction)
+bool FocusController::advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, FocusType type)
{
if (!container)
return false;
@@ -803,57 +818,57 @@ bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons
LayoutRect newStartingRect = startingRect;
if (startingRect.isEmpty())
- newStartingRect = virtualRectForDirection(direction, nodeRectInAbsoluteCoordinates(container));
+ newStartingRect = virtualRectForDirection(type, nodeRectInAbsoluteCoordinates(container));
// Find the closest node within current container in the direction of the navigation.
FocusCandidate focusCandidate;
- findFocusCandidateInContainer(*container, newStartingRect, direction, focusCandidate);
+ findFocusCandidateInContainer(*container, newStartingRect, type, focusCandidate);
if (focusCandidate.isNull()) {
// Nothing to focus, scroll if possible.
// NOTE: If no scrolling is performed (i.e. scrollInDirection returns false), the
// spatial navigation algorithm will skip this container.
- return scrollInDirection(container, direction);
+ return scrollInDirection(container, type);
}
- if (HTMLFrameOwnerElement* frameElement = frameOwnerElement(focusCandidate)) {
- // If we have an iframe without the src attribute, it will not have a contentFrame().
- // We ASSERT here to make sure that
- // updateFocusCandidateIfNeeded() will never consider such an iframe as a candidate.
- ASSERT(frameElement->contentFrame());
-
+ HTMLFrameOwnerElement* frameElement = frameOwnerElement(focusCandidate);
+ // If we have an iframe without the src attribute, it will not have a contentFrame().
+ // We ASSERT here to make sure that
+ // updateFocusCandidateIfNeeded() will never consider such an iframe as a candidate.
+ ASSERT(!frameElement || frameElement->contentFrame());
+ if (frameElement && frameElement->contentFrame()->isLocalFrame()) {
if (focusCandidate.isOffscreenAfterScrolling) {
- scrollInDirection(&focusCandidate.visibleNode->document(), direction);
+ scrollInDirection(&focusCandidate.visibleNode->document(), type);
return true;
}
// Navigate into a new frame.
LayoutRect rect;
- Element* focusedElement = focusedOrMainFrame()->document()->focusedElement();
+ Element* focusedElement = toLocalFrame(focusedOrMainFrame())->document()->focusedElement();
if (focusedElement && !hasOffscreenRect(focusedElement))
rect = nodeRectInAbsoluteCoordinates(focusedElement, true /* ignore border */);
- frameElement->contentFrame()->document()->updateLayoutIgnorePendingStylesheets();
- if (!advanceFocusDirectionallyInContainer(frameElement->contentFrame()->document(), rect, direction)) {
+ toLocalFrame(frameElement->contentFrame())->document()->updateLayoutIgnorePendingStylesheets();
+ if (!advanceFocusDirectionallyInContainer(toLocalFrame(frameElement->contentFrame())->document(), rect, type)) {
// The new frame had nothing interesting, need to find another candidate.
- return advanceFocusDirectionallyInContainer(container, nodeRectInAbsoluteCoordinates(focusCandidate.visibleNode, true), direction);
+ return advanceFocusDirectionallyInContainer(container, nodeRectInAbsoluteCoordinates(focusCandidate.visibleNode, true), type);
}
return true;
}
- if (canScrollInDirection(focusCandidate.visibleNode, direction)) {
+ if (canScrollInDirection(focusCandidate.visibleNode, type)) {
if (focusCandidate.isOffscreenAfterScrolling) {
- scrollInDirection(focusCandidate.visibleNode, direction);
+ scrollInDirection(focusCandidate.visibleNode, type);
return true;
}
// Navigate into a new scrollable container.
LayoutRect startingRect;
- Element* focusedElement = focusedOrMainFrame()->document()->focusedElement();
+ Element* focusedElement = toLocalFrame(focusedOrMainFrame())->document()->focusedElement();
if (focusedElement && !hasOffscreenRect(focusedElement))
startingRect = nodeRectInAbsoluteCoordinates(focusedElement, true);
- return advanceFocusDirectionallyInContainer(focusCandidate.visibleNode, startingRect, direction);
+ return advanceFocusDirectionallyInContainer(focusCandidate.visibleNode, startingRect, type);
}
if (focusCandidate.isOffscreenAfterScrolling) {
Node* container = focusCandidate.enclosingScrollableBox;
- scrollInDirection(container, direction);
+ scrollInDirection(container, type);
return true;
}
@@ -861,13 +876,16 @@ bool FocusController::advanceFocusDirectionallyInContainer(Node* container, cons
Element* element = toElement(focusCandidate.focusableNode);
ASSERT(element);
- element->focus(false, direction);
+ element->focus(false, type);
return true;
}
-bool FocusController::advanceFocusDirectionally(FocusDirection direction)
+bool FocusController::advanceFocusDirectionally(FocusType type)
{
- Frame* curFrame = focusedOrMainFrame();
+ // FIXME: Directional focus changes don't yet work with RemoteFrames.
+ if (!focusedOrMainFrame()->isLocalFrame())
+ return false;
+ LocalFrame* curFrame = toLocalFrame(focusedOrMainFrame());
ASSERT(curFrame);
Document* focusedDocument = curFrame->document();
@@ -884,20 +902,20 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction)
LayoutRect startingRect;
if (focusedElement) {
if (!hasOffscreenRect(focusedElement)) {
- container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, focusedElement);
+ container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(type, focusedElement);
startingRect = nodeRectInAbsoluteCoordinates(focusedElement, true /* ignore border */);
- } else if (isHTMLAreaElement(focusedElement)) {
- HTMLAreaElement* area = toHTMLAreaElement(focusedElement);
- container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, area->imageElement());
- startingRect = virtualRectForAreaElementAndDirection(area, direction);
+ } else if (isHTMLAreaElement(*focusedElement)) {
+ HTMLAreaElement& area = toHTMLAreaElement(*focusedElement);
+ container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(type, area.imageElement());
+ startingRect = virtualRectForAreaElementAndDirection(area, type);
}
}
bool consumed = false;
do {
- consumed = advanceFocusDirectionallyInContainer(container, startingRect, direction);
+ consumed = advanceFocusDirectionallyInContainer(container, startingRect, type);
startingRect = nodeRectInAbsoluteCoordinates(container, true /* ignore border */);
- container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(direction, container);
+ container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(type, container);
if (container && container->isDocumentNode())
toDocument(container)->updateLayoutIgnorePendingStylesheets();
} while (!consumed && container);
diff --git a/chromium/third_party/WebKit/Source/core/page/FocusController.h b/chromium/third_party/WebKit/Source/core/page/FocusController.h
index 38069eb4919..f0e11935fa6 100644
--- a/chromium/third_party/WebKit/Source/core/page/FocusController.h
+++ b/chromium/third_party/WebKit/Source/core/page/FocusController.h
@@ -26,8 +26,9 @@
#ifndef FocusController_h
#define FocusController_h
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
#include "platform/geometry/LayoutRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
#include "wtf/RefPtr.h"
@@ -47,6 +48,7 @@ class Page;
class TreeScope;
class FocusNavigationScope {
+ STACK_ALLOCATED();
public:
Node* rootNode() const;
Element* owner() const;
@@ -58,7 +60,7 @@ public:
private:
explicit FocusNavigationScope(TreeScope*);
- TreeScope* m_rootTreeScope;
+ RawPtrWillBeMember<TreeScope> m_rootTreeScope;
};
class FocusController {
@@ -67,13 +69,14 @@ public:
static PassOwnPtr<FocusController> create(Page*);
void setFocusedFrame(PassRefPtr<Frame>);
+ void focusDocumentView(PassRefPtr<Frame>);
Frame* focusedFrame() const { return m_focusedFrame.get(); }
Frame* focusedOrMainFrame() const;
- bool setInitialFocus(FocusDirection);
- bool advanceFocus(FocusDirection direction) { return advanceFocus(direction, false); }
+ bool setInitialFocus(FocusType);
+ bool advanceFocus(FocusType type) { return advanceFocus(type, false); }
- bool setFocusedElement(Element*, PassRefPtr<Frame>, FocusDirection = FocusDirectionNone);
+ bool setFocusedElement(Element*, PassRefPtr<Frame>, FocusType = FocusTypeNone);
void setActive(bool);
bool isActive() const { return m_isActive; }
@@ -81,19 +84,16 @@ public:
void setFocused(bool);
bool isFocused() const { return m_isFocused; }
- void setContainingWindowIsVisible(bool);
- bool containingWindowIsVisible() const { return m_containingWindowIsVisible; }
-
private:
explicit FocusController(Page*);
- bool advanceFocus(FocusDirection, bool initialFocus);
- bool advanceFocusDirectionally(FocusDirection);
- bool advanceFocusInDocumentOrder(FocusDirection, bool initialFocus);
+ bool advanceFocus(FocusType, bool initialFocus);
+ bool advanceFocusDirectionally(FocusType);
+ bool advanceFocusInDocumentOrder(FocusType, bool initialFocus);
- Node* findFocusableNodeAcrossFocusScope(FocusDirection, FocusNavigationScope startScope, Node* start);
- Node* findFocusableNodeRecursively(FocusDirection, FocusNavigationScope, Node* start);
- Node* findFocusableNodeDecendingDownIntoFrameDocument(FocusDirection, Node*);
+ Node* findFocusableNodeAcrossFocusScope(FocusType, FocusNavigationScope startScope, Node* start);
+ Node* findFocusableNodeRecursively(FocusType, FocusNavigationScope, Node* start);
+ Node* findFocusableNodeDecendingDownIntoFrameDocument(FocusType, Node*);
// Searches through the given tree scope, starting from start node, for the next/previous selectable element that comes after/before start node.
// The order followed is as specified in section 17.11.1 of the HTML4 spec, which is elements with tab indexes
@@ -104,23 +104,21 @@ private:
// @return The focus node that comes after/before start node.
//
// See http://www.w3.org/TR/html4/interact/forms.html#h-17.11.1
- inline Node* findFocusableNode(FocusDirection, FocusNavigationScope, Node* start);
+ inline Node* findFocusableNode(FocusType, FocusNavigationScope, Node* start);
Node* nextFocusableNode(FocusNavigationScope, Node* start);
Node* previousFocusableNode(FocusNavigationScope, Node* start);
- Node* findNodeWithExactTabIndex(Node* start, int tabIndex, FocusDirection);
+ Node* findNodeWithExactTabIndex(Node* start, int tabIndex, FocusType);
- bool advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, FocusDirection);
- void findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, FocusDirection, FocusCandidate& closest);
+ bool advanceFocusDirectionallyInContainer(Node* container, const LayoutRect& startingRect, FocusType);
+ void findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, FocusType, FocusCandidate& closest);
Page* m_page;
RefPtr<Frame> m_focusedFrame;
bool m_isActive;
bool m_isFocused;
bool m_isChangingFocusedFrame;
- bool m_containingWindowIsVisible;
-
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/FocusDirection.h b/chromium/third_party/WebKit/Source/core/page/FocusDirection.h
deleted file mode 100644
index c972e117a21..00000000000
--- a/chromium/third_party/WebKit/Source/core/page/FocusDirection.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef FocusDirection_h
-#define FocusDirection_h
-
-namespace WebCore {
-// FIXME: Rename FocusDirection to FocusType or something.
- enum FocusDirection {
- // Element::focus(), etc.
- FocusDirectionNone = 0,
- // TAB, or Shift + TAB
- FocusDirectionForward,
- FocusDirectionBackward,
- // Spatial navigation.
- FocusDirectionUp,
- FocusDirectionDown,
- FocusDirectionLeft,
- FocusDirectionRight,
- // Mouse press
- FocusDirectionMouse,
- // Re-focus by a page focus
- FocusDirectionPage
- };
-}
-
-#endif // FocusDirection_h
diff --git a/chromium/third_party/WebKit/Source/core/page/FocusType.h b/chromium/third_party/WebKit/Source/core/page/FocusType.h
new file mode 100644
index 00000000000..ac2d81c0bd1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/FocusType.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FocusType_h
+#define FocusType_h
+
+namespace WebCore {
+
+enum FocusType {
+ // Element::focus(), etc.
+ FocusTypeNone = 0,
+ // Sequential navigation with TAB, or Shift + TAB.
+ FocusTypeForward,
+ FocusTypeBackward,
+ // Spatial navigation.
+ FocusTypeUp,
+ FocusTypeDown,
+ FocusTypeLeft,
+ FocusTypeRight,
+ // Mouse press
+ FocusTypeMouse,
+ // Re-focus by a page focus
+ FocusTypePage
+};
+
+}
+
+#endif // FocusType_h
diff --git a/chromium/third_party/WebKit/Source/core/page/FrameTree.cpp b/chromium/third_party/WebKit/Source/core/page/FrameTree.cpp
index b7e7dc1cc10..657e2bf349d 100644
--- a/chromium/third_party/WebKit/Source/core/page/FrameTree.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/FrameTree.cpp
@@ -22,10 +22,12 @@
#include "core/page/FrameTree.h"
#include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameClient.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/RemoteFrame.h"
+#include "core/frame/RemoteFrameView.h"
#include "core/page/Page.h"
-#include "core/page/PageGroup.h"
#include "wtf/Vector.h"
#include "wtf/text/CString.h"
#include "wtf/text/StringBuilder.h"
@@ -34,13 +36,30 @@ using std::swap;
namespace WebCore {
+namespace {
+
+const unsigned invalidChildCount = ~0;
+
+} // namespace
+
+FrameTree::FrameTree(Frame* thisFrame)
+ : m_thisFrame(thisFrame)
+ , m_scopedChildCount(invalidChildCount)
+{
+}
+
FrameTree::~FrameTree()
{
- for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
- child->setView(0);
+ // FIXME: Why is this here? Doesn't this parallel what we already do in ~LocalFrame?
+ for (Frame* child = firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ toLocalFrame(child)->setView(nullptr);
+ else if (child->isRemoteFrame())
+ toRemoteFrame(child)->setView(nullptr);
+ }
}
-void FrameTree::setName(const AtomicString& name)
+void FrameTree::setName(const AtomicString& name, const AtomicString& fallbackName)
{
m_name = name;
if (!parent()) {
@@ -48,55 +67,67 @@ void FrameTree::setName(const AtomicString& name)
return;
}
m_uniqueName = AtomicString(); // Remove our old frame name so it's not considered in uniqueChildName.
- m_uniqueName = parent()->tree().uniqueChildName(name);
+ m_uniqueName = parent()->tree().uniqueChildName(name.isEmpty() ? fallbackName : name);
}
Frame* FrameTree::parent() const
{
- return m_parent;
+ if (!m_thisFrame->client())
+ return 0;
+ return m_thisFrame->client()->parent();
}
-void FrameTree::appendChild(PassRefPtr<Frame> child)
+Frame* FrameTree::top() const
{
- ASSERT(child->page() == m_thisFrame->page());
- child->tree().m_parent = m_thisFrame;
- Frame* oldLast = m_lastChild;
- m_lastChild = child.get();
-
- if (oldLast) {
- child->tree().m_previousSibling = oldLast;
- oldLast->tree().m_nextSibling = child;
- } else
- m_firstChild = child;
-
- m_scopedChildCount = invalidCount;
-
- ASSERT(!m_lastChild->tree().m_nextSibling);
+ // FIXME: top() should never return null, so here are some hacks to deal
+ // with EmptyFrameLoaderClient and cases where the frame is detached
+ // already...
+ if (!m_thisFrame->client())
+ return m_thisFrame;
+ Frame* candidate = m_thisFrame->client()->top();
+ return candidate ? candidate : m_thisFrame;
}
-void FrameTree::removeChild(Frame* child)
+Frame* FrameTree::previousSibling() const
{
- child->tree().m_parent = 0;
+ if (!m_thisFrame->client())
+ return 0;
+ return m_thisFrame->client()->previousSibling();
+}
- // Slightly tricky way to prevent deleting the child until we are done with it, w/o
- // extra refs. These swaps leave the child in a circular list by itself. Clearing its
- // previous and next will then finally deref it.
+Frame* FrameTree::nextSibling() const
+{
+ if (!m_thisFrame->client())
+ return 0;
+ return m_thisFrame->client()->nextSibling();
+}
- RefPtr<Frame>& newLocationForNext = m_firstChild == child ? m_firstChild : child->tree().m_previousSibling->tree().m_nextSibling;
- Frame*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child->tree().m_nextSibling->tree().m_previousSibling;
- swap(newLocationForNext, child->tree().m_nextSibling);
- // For some inexplicable reason, the following line does not compile without the explicit std:: namespace
- std::swap(newLocationForPrevious, child->tree().m_previousSibling);
+Frame* FrameTree::firstChild() const
+{
+ if (!m_thisFrame->client())
+ return 0;
+ return m_thisFrame->client()->firstChild();
+}
- child->tree().m_previousSibling = 0;
- child->tree().m_nextSibling = 0;
+Frame* FrameTree::lastChild() const
+{
+ if (!m_thisFrame->client())
+ return 0;
+ return m_thisFrame->client()->lastChild();
+}
- m_scopedChildCount = invalidCount;
+bool FrameTree::uniqueNameExists(const AtomicString& name) const
+{
+ for (Frame* frame = top(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->tree().uniqueName() == name)
+ return true;
+ }
+ return false;
}
AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
{
- if (!requestedName.isEmpty() && !child(requestedName) && requestedName != "_blank")
+ if (!requestedName.isEmpty() && !uniqueNameExists(requestedName) && requestedName != "_blank")
return requestedName;
// Create a repeatable name for a child about to be added to us. The name must be
@@ -131,7 +162,7 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
}
name.appendLiteral("/<!--frame");
- name.appendNumber(childCount());
+ name.appendNumber(childCount() - 1);
name.appendLiteral("-->-->");
return name.toAtomicString();
@@ -139,13 +170,15 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
Frame* FrameTree::scopedChild(unsigned index) const
{
- TreeScope* scope = m_thisFrame->document();
+ if (!m_thisFrame->isLocalFrame())
+ return 0;
+ TreeScope* scope = toLocalFrame(m_thisFrame)->document();
if (!scope)
return 0;
unsigned scopedIndex = 0;
for (Frame* result = firstChild(); result; result = result->tree().nextSibling()) {
- if (result->inScope(scope)) {
+ if (result->isLocalFrame() && toLocalFrame(result)->inScope(scope)) {
if (scopedIndex == index)
return result;
scopedIndex++;
@@ -157,12 +190,15 @@ Frame* FrameTree::scopedChild(unsigned index) const
Frame* FrameTree::scopedChild(const AtomicString& name) const
{
- TreeScope* scope = m_thisFrame->document();
+ if (!m_thisFrame->isLocalFrame())
+ return 0;
+
+ TreeScope* scope = toLocalFrame(m_thisFrame)->document();
if (!scope)
return 0;
for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
- if (child->tree().uniqueName() == name && child->inScope(scope))
+ if (child->tree().name() == name && child->isLocalFrame() && toLocalFrame(child)->inScope(scope))
return child;
return 0;
}
@@ -174,7 +210,7 @@ inline unsigned FrameTree::scopedChildCount(TreeScope* scope) const
unsigned scopedCount = 0;
for (Frame* result = firstChild(); result; result = result->tree().nextSibling()) {
- if (result->inScope(scope))
+ if (result->isLocalFrame() && toLocalFrame(result)->inScope(scope))
scopedCount++;
}
@@ -183,11 +219,16 @@ inline unsigned FrameTree::scopedChildCount(TreeScope* scope) const
unsigned FrameTree::scopedChildCount() const
{
- if (m_scopedChildCount == invalidCount)
- m_scopedChildCount = scopedChildCount(m_thisFrame->document());
+ if (m_scopedChildCount == invalidChildCount)
+ m_scopedChildCount = scopedChildCount(toLocalFrame(m_thisFrame)->document());
return m_scopedChildCount;
}
+void FrameTree::invalidateScopedChildCount()
+{
+ m_scopedChildCount = invalidChildCount;
+}
+
unsigned FrameTree::childCount() const
{
unsigned count = 0;
@@ -199,7 +240,7 @@ unsigned FrameTree::childCount() const
Frame* FrameTree::child(const AtomicString& name) const
{
for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
- if (child->tree().uniqueName() == name)
+ if (child->tree().name() == name)
return child;
return 0;
}
@@ -221,7 +262,7 @@ Frame* FrameTree::find(const AtomicString& name) const
// Search subtree starting with this frame first.
for (Frame* frame = m_thisFrame; frame; frame = frame->tree().traverseNext(m_thisFrame))
- if (frame->tree().uniqueName() == name)
+ if (frame->tree().name() == name)
return frame;
// Search the entire tree for this page next.
@@ -232,18 +273,18 @@ Frame* FrameTree::find(const AtomicString& name) const
return 0;
for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
- if (frame->tree().uniqueName() == name)
+ if (frame->tree().name() == name)
return frame;
// Search the entire tree of each of the other pages in this namespace.
// FIXME: Is random order OK?
- const HashSet<Page*>& pages = page->group().pages();
+ const HashSet<Page*>& pages = Page::ordinaryPages();
HashSet<Page*>::const_iterator end = pages.end();
for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
Page* otherPage = *it;
if (otherPage != page) {
for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->tree().uniqueName() == name)
+ if (frame->tree().name() == name)
return frame;
}
}
@@ -336,14 +377,6 @@ Frame* FrameTree::deepLastChild() const
return result;
}
-Frame* FrameTree::top() const
-{
- Frame* frame = m_thisFrame;
- for (Frame* parent = m_thisFrame; parent; parent = parent->tree().parent())
- frame = parent;
- return frame;
-}
-
} // namespace WebCore
#ifndef NDEBUG
@@ -362,16 +395,16 @@ static void printFrames(const WebCore::Frame* frame, const WebCore::Frame* targe
} else
printIndent(indent);
- WebCore::FrameView* view = frame->view();
+ WebCore::FrameView* view = frame->isLocalFrame() ? toLocalFrame(frame)->view() : 0;
printf("Frame %p %dx%d\n", frame, view ? view->width() : 0, view ? view->height() : 0);
printIndent(indent);
- printf(" ownerElement=%p\n", frame->ownerElement());
+ printf(" owner=%p\n", frame->owner());
printIndent(indent);
printf(" frameView=%p\n", view);
printIndent(indent);
- printf(" document=%p\n", frame->document());
+ printf(" document=%p\n", frame->isLocalFrame() ? toLocalFrame(frame)->document() : 0);
printIndent(indent);
- printf(" uri=%s\n\n", frame->document()->documentURI().utf8().data());
+ printf(" uri=%s\n\n", frame->isLocalFrame() ? toLocalFrame(frame)->document()->url().string().utf8().data() : 0);
for (WebCore::Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
printFrames(child, targetFrame, indent + 1);
diff --git a/chromium/third_party/WebKit/Source/core/page/FrameTree.h b/chromium/third_party/WebKit/Source/core/page/FrameTree.h
index 9f7f842d03d..9def44b8d3d 100644
--- a/chromium/third_party/WebKit/Source/core/page/FrameTree.h
+++ b/chromium/third_party/WebKit/Source/core/page/FrameTree.h
@@ -24,73 +24,55 @@
namespace WebCore {
- class Frame;
- class TreeScope;
-
- class FrameTree {
- WTF_MAKE_NONCOPYABLE(FrameTree);
- public:
- const static unsigned invalidCount = static_cast<unsigned>(-1);
-
- FrameTree(Frame* thisFrame, Frame* parentFrame)
- : m_thisFrame(thisFrame)
- , m_parent(parentFrame)
- , m_previousSibling(0)
- , m_lastChild(0)
- , m_scopedChildCount(invalidCount)
- {
- }
-
- ~FrameTree();
-
- const AtomicString& name() const { return m_name; }
- const AtomicString& uniqueName() const { return m_uniqueName; }
- void setName(const AtomicString&);
- Frame* parent() const;
- void setParent(Frame* parent) { m_parent = parent; }
-
- Frame* nextSibling() const { return m_nextSibling.get(); }
- Frame* previousSibling() const { return m_previousSibling; }
- Frame* firstChild() const { return m_firstChild.get(); }
- Frame* lastChild() const { return m_lastChild; }
-
- bool isDescendantOf(const Frame* ancestor) const;
- Frame* traverseNext(const Frame* stayWithin = 0) const;
- Frame* traverseNextWithWrap(bool) const;
- Frame* traversePreviousWithWrap(bool) const;
-
- void appendChild(PassRefPtr<Frame>);
- void detachFromParent() { m_parent = 0; }
- void removeChild(Frame*);
-
- Frame* child(const AtomicString& name) const;
- Frame* find(const AtomicString& name) const;
- unsigned childCount() const;
-
- Frame* top() const;
-
- Frame* scopedChild(unsigned index) const;
- Frame* scopedChild(const AtomicString& name) const;
- unsigned scopedChildCount() const;
-
- private:
- Frame* deepLastChild() const;
- AtomicString uniqueChildName(const AtomicString& requestedName) const;
- unsigned scopedChildCount(TreeScope*) const;
-
- Frame* m_thisFrame;
-
- Frame* m_parent;
- AtomicString m_name; // The actual frame name (may be empty).
- AtomicString m_uniqueName;
-
- // FIXME: use ListRefPtr?
- RefPtr<Frame> m_nextSibling;
- Frame* m_previousSibling;
- RefPtr<Frame> m_firstChild;
- Frame* m_lastChild;
- mutable unsigned m_scopedChildCount;
- };
+class Frame;
+class TreeScope;
+
+class FrameTree {
+ WTF_MAKE_NONCOPYABLE(FrameTree);
+public:
+ explicit FrameTree(Frame* thisFrame);
+ ~FrameTree();
+
+ const AtomicString& name() const { return m_name; }
+ const AtomicString& uniqueName() const { return m_uniqueName; }
+ // If |name| is not empty, |fallbackName| is ignored. Otherwise,
+ // |fallbackName| is used as a source of uniqueName.
+ void setName(const AtomicString& name, const AtomicString& fallbackName = nullAtom);
+
+ Frame* parent() const;
+ Frame* top() const;
+ Frame* previousSibling() const;
+ Frame* nextSibling() const;
+ Frame* firstChild() const;
+ Frame* lastChild() const;
+
+ bool isDescendantOf(const Frame* ancestor) const;
+ Frame* traversePreviousWithWrap(bool) const;
+ Frame* traverseNext(const Frame* stayWithin = 0) const;
+ Frame* traverseNextWithWrap(bool) const;
+
+ Frame* child(const AtomicString& name) const;
+ Frame* find(const AtomicString& name) const;
+ unsigned childCount() const;
+
+ Frame* scopedChild(unsigned index) const;
+ Frame* scopedChild(const AtomicString& name) const;
+ unsigned scopedChildCount() const;
+ void invalidateScopedChildCount();
+
+private:
+ Frame* deepLastChild() const;
+ AtomicString uniqueChildName(const AtomicString& requestedName) const;
+ bool uniqueNameExists(const AtomicString& name) const;
+ unsigned scopedChildCount(TreeScope*) const;
+
+ Frame* m_thisFrame;
+
+ AtomicString m_name; // The actual frame name (may be empty).
+ AtomicString m_uniqueName;
+
+ mutable unsigned m_scopedChildCount;
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheet.h b/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheet.h
deleted file mode 100644
index cdee055660e..00000000000
--- a/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheet.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InjectedStyleSheet_h
-#define InjectedStyleSheet_h
-
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-enum StyleInjectionTarget { InjectStyleInAllFrames, InjectStyleInTopFrameOnly };
-
-class InjectedStyleSheet {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- InjectedStyleSheet(const String& source, const Vector<String>& whitelist, StyleInjectionTarget injectedFrames)
- : m_source(source)
- , m_whitelist(whitelist)
- , m_injectedFrames(injectedFrames)
- {
- }
-
- const String& source() const { return m_source; }
- const Vector<String>& whitelist() const { return m_whitelist; }
- StyleInjectionTarget injectedFrames() const { return m_injectedFrames; }
-
-private:
- String m_source;
- Vector<String> m_whitelist;
- StyleInjectionTarget m_injectedFrames;
-};
-
-typedef Vector<OwnPtr<InjectedStyleSheet> > InjectedStyleSheetVector;
-
-} // namespace WebCore
-
-#endif // InjectedStyleSheet_h
diff --git a/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheets.cpp b/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheets.cpp
new file mode 100644
index 00000000000..c5760054d6f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheets.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/page/InjectedStyleSheets.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
+#include "core/frame/LocalFrame.h"
+#include "core/page/Page.h"
+#include "wtf/HashSet.h"
+
+namespace WebCore {
+
+// static
+InjectedStyleSheets& InjectedStyleSheets::instance()
+{
+ DEFINE_STATIC_LOCAL(InjectedStyleSheets, instance, ());
+ return instance;
+}
+
+void InjectedStyleSheets::add(const String& source, const Vector<String>& whitelist, StyleInjectionTarget injectIn)
+{
+ m_entries.append(adoptPtr(new InjectedStyleSheetEntry(source, whitelist, injectIn)));
+ invalidateInjectedStyleSheetCacheInAllFrames();
+}
+
+void InjectedStyleSheets::removeAll()
+{
+ m_entries.clear();
+ invalidateInjectedStyleSheetCacheInAllFrames();
+}
+
+void InjectedStyleSheets::invalidateInjectedStyleSheetCacheInAllFrames()
+{
+ // Clear our cached sheets and have them just reparse.
+ const HashSet<Page*>& pages = Page::ordinaryPages();
+
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->styleEngine()->invalidateInjectedStyleSheetCache();
+ }
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheets.h b/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheets.h
new file mode 100644
index 00000000000..dbf728f8e01
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/InjectedStyleSheets.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InjectedStyleSheets_h
+#define InjectedStyleSheets_h
+
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+enum StyleInjectionTarget { InjectStyleInAllFrames, InjectStyleInTopFrameOnly };
+
+class InjectedStyleSheetEntry {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ InjectedStyleSheetEntry(const String& source, const Vector<String>& whitelist, StyleInjectionTarget injectedFrames)
+ : m_source(source)
+ , m_whitelist(whitelist)
+ , m_injectedFrames(injectedFrames)
+ {
+ }
+
+ const String& source() const { return m_source; }
+ const Vector<String>& whitelist() const { return m_whitelist; }
+ StyleInjectionTarget injectedFrames() const { return m_injectedFrames; }
+
+private:
+ String m_source;
+ Vector<String> m_whitelist;
+ StyleInjectionTarget m_injectedFrames;
+};
+
+typedef Vector<OwnPtr<InjectedStyleSheetEntry> > InjectedStyleSheetEntryVector;
+
+class InjectedStyleSheets {
+public:
+ static InjectedStyleSheets& instance();
+
+ void add(const String& source, const Vector<String>& whitelist, StyleInjectionTarget);
+ void removeAll();
+
+ const InjectedStyleSheetEntryVector& entries() const { return m_entries; }
+
+private:
+ InjectedStyleSheets() { }
+ void invalidateInjectedStyleSheetCacheInAllFrames();
+
+ InjectedStyleSheetEntryVector m_entries;
+};
+
+} // namespace WebCore
+
+#endif // InjectedStyleSheets_h
diff --git a/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp b/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp
index 02cc4615c96..5d15f876abf 100644
--- a/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp
@@ -26,8 +26,10 @@
#include "config.h"
#include "core/page/NetworkStateNotifier.h"
+#include "core/dom/ExecutionContext.h"
#include "core/page/Page.h"
#include "wtf/Assertions.h"
+#include "wtf/Functional.h"
#include "wtf/MainThread.h"
#include "wtf/StdLibExtras.h"
#include "wtf/Threading.h"
@@ -55,4 +57,124 @@ void NetworkStateNotifier::setOnLine(bool onLine)
Page::networkStateChanged(onLine);
}
+void NetworkStateNotifier::setWebConnectionType(blink::WebConnectionType type)
+{
+ ASSERT(isMainThread());
+ if (m_testUpdatesOnly)
+ return;
+
+ setWebConnectionTypeImpl(type);
+}
+
+void NetworkStateNotifier::setWebConnectionTypeImpl(blink::WebConnectionType type)
+{
+ ASSERT(isMainThread());
+
+ MutexLocker locker(m_mutex);
+ if (m_type == type)
+ return;
+ m_type = type;
+
+ for (ObserverListMap::iterator it = m_observers.begin(); it != m_observers.end(); ++it) {
+ ExecutionContext* context = it->key;
+ context->postTask(bind(&NetworkStateNotifier::notifyObserversOnContext, this, context, type));
+ }
+}
+
+void NetworkStateNotifier::addObserver(NetworkStateObserver* observer, ExecutionContext* context)
+{
+ ASSERT(context->isContextThread());
+ ASSERT(observer);
+
+ MutexLocker locker(m_mutex);
+ ObserverListMap::AddResult result = m_observers.add(context, nullptr);
+ if (result.isNewEntry)
+ result.storedValue->value = adoptPtr(new ObserverList);
+
+ ASSERT(result.storedValue->value->observers.find(observer) == kNotFound);
+ result.storedValue->value->observers.append(observer);
+}
+
+void NetworkStateNotifier::removeObserver(NetworkStateObserver* observer, ExecutionContext* context)
+{
+ ASSERT(context->isContextThread());
+ ASSERT(observer);
+
+ ObserverList* observerList = lockAndFindObserverList(context);
+ if (!observerList)
+ return;
+
+ Vector<NetworkStateObserver*>& observers = observerList->observers;
+ size_t index = observers.find(observer);
+ if (index != kNotFound) {
+ observers[index] = 0;
+ observerList->zeroedObservers.append(index);
+ }
+
+ if (!observerList->iterating && !observerList->zeroedObservers.isEmpty())
+ collectZeroedObservers(observerList, context);
+}
+
+void NetworkStateNotifier::setTestUpdatesOnly(bool updatesOnly)
+{
+ ASSERT(isMainThread());
+ m_testUpdatesOnly = updatesOnly;
}
+
+void NetworkStateNotifier::setWebConnectionTypeForTest(blink::WebConnectionType type)
+{
+ ASSERT(isMainThread());
+ ASSERT(m_testUpdatesOnly);
+ setWebConnectionTypeImpl(type);
+}
+
+void NetworkStateNotifier::notifyObserversOnContext(ExecutionContext* context, blink::WebConnectionType type)
+{
+ ObserverList* observerList = lockAndFindObserverList(context);
+
+ // The context could have been removed before the notification task got to run.
+ if (!observerList)
+ return;
+
+ ASSERT(context->isContextThread());
+
+ observerList->iterating = true;
+
+ for (size_t i = 0; i < observerList->observers.size(); ++i) {
+ // Observers removed during iteration are zeroed out, skip them.
+ if (observerList->observers[i])
+ observerList->observers[i]->connectionTypeChange(type);
+ }
+
+ observerList->iterating = false;
+
+ if (!observerList->zeroedObservers.isEmpty())
+ collectZeroedObservers(observerList, context);
+}
+
+NetworkStateNotifier::ObserverList* NetworkStateNotifier::lockAndFindObserverList(ExecutionContext* context)
+{
+ MutexLocker locker(m_mutex);
+ ObserverListMap::iterator it = m_observers.find(context);
+ return it == m_observers.end() ? 0 : it->value.get();
+}
+
+void NetworkStateNotifier::collectZeroedObservers(ObserverList* list, ExecutionContext* context)
+{
+ ASSERT(context->isContextThread());
+ ASSERT(!list->iterating);
+
+ // If any observers were removed during the iteration they will have
+ // 0 values, clean them up.
+ for (size_t i = 0; i < list->zeroedObservers.size(); ++i)
+ list->observers.remove(list->zeroedObservers[i]);
+
+ list->zeroedObservers.clear();
+
+ if (list->observers.isEmpty()) {
+ MutexLocker locker(m_mutex);
+ m_observers.remove(context); // deletes list
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.h b/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.h
index 7e5fb725d6e..138aaf52dd2 100644
--- a/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.h
+++ b/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifier.h
@@ -26,17 +26,32 @@
#ifndef NetworkStateNotifier_h
#define NetworkStateNotifier_h
+#include "public/platform/WebConnectionType.h"
#include "wtf/FastAllocBase.h"
+#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/ThreadingPrimitives.h"
+#include "wtf/Vector.h"
namespace WebCore {
+class ExecutionContext;
+
class NetworkStateNotifier {
WTF_MAKE_NONCOPYABLE(NetworkStateNotifier); WTF_MAKE_FAST_ALLOCATED;
public:
+ class NetworkStateObserver {
+ public:
+ // Will be called on the thread of the context passed in addObserver.
+ virtual void connectionTypeChange(blink::WebConnectionType) = 0;
+ };
+
NetworkStateNotifier()
- : m_isOnLine(true) { }
+ : m_isOnLine(true)
+ , m_type(blink::ConnectionTypeOther)
+ , m_testUpdatesOnly(false)
+ {
+ }
bool onLine() const
{
@@ -46,13 +61,62 @@ public:
void setOnLine(bool);
+ blink::WebConnectionType connectionType() const
+ {
+ MutexLocker locker(m_mutex);
+ return m_type;
+ }
+
+ void setWebConnectionType(blink::WebConnectionType);
+
+ // Must be called on the context's thread. An added observer must be removed
+ // before its ExecutionContext is deleted. It's possible for an observer to
+ // be called twice for the same event if it is first removed and then added
+ // during notification.
+ void addObserver(NetworkStateObserver*, ExecutionContext*);
+ void removeObserver(NetworkStateObserver*, ExecutionContext*);
+
+ // The following functions are for testing purposes.
+
+ // When true, setWebConnectionType calls are ignored and only setWebConnectionTypeForTest
+ // can update the connection type. This is used for layout tests (see crbug.com/377736).
+ void setTestUpdatesOnly(bool);
+ // Tests should call this as it will change the type regardless of the value of m_testUpdatesOnly.
+ void setWebConnectionTypeForTest(blink::WebConnectionType);
+
private:
+ struct ObserverList {
+ ObserverList()
+ : iterating(false)
+ {
+ }
+ bool iterating;
+ Vector<NetworkStateObserver*> observers;
+ Vector<size_t> zeroedObservers; // Indices in observers that are 0.
+ };
+
+ void setWebConnectionTypeImpl(blink::WebConnectionType);
+
+ typedef HashMap<ExecutionContext*, OwnPtr<ObserverList> > ObserverListMap;
+
+ void notifyObserversOnContext(ExecutionContext*, blink::WebConnectionType);
+
+ ObserverList* lockAndFindObserverList(ExecutionContext*);
+
+ // Removed observers are nulled out in the list in case the list is being
+ // iterated over. Once done iterating, call this to clean up nulled
+ // observers.
+ void collectZeroedObservers(ObserverList*, ExecutionContext*);
+
mutable Mutex m_mutex;
bool m_isOnLine;
+ blink::WebConnectionType m_type;
+ ObserverListMap m_observers;
+ bool m_testUpdatesOnly;
};
NetworkStateNotifier& networkStateNotifier();
-};
+} // namespace WebCore
#endif // NetworkStateNotifier_h
diff --git a/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifierTest.cpp b/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifierTest.cpp
new file mode 100644
index 00000000000..ab9627bc790
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/NetworkStateNotifierTest.cpp
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/page/NetworkStateNotifier.h"
+
+#include "core/dom/Document.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebConnectionType.h"
+#include "public/platform/WebThread.h"
+#include "wtf/Functional.h"
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class StateObserver : public NetworkStateNotifier::NetworkStateObserver {
+public:
+ StateObserver()
+ : m_observedType(blink::ConnectionTypeNone)
+ , m_callbackCount(0)
+ {
+ }
+
+ virtual void connectionTypeChange(blink::WebConnectionType type)
+ {
+ m_observedType = type;
+ m_callbackCount += 1;
+
+ if (!m_closure.isNull())
+ m_closure();
+ }
+
+ blink::WebConnectionType observedType() const
+ {
+ return m_observedType;
+ }
+
+ int callbackCount() const
+ {
+ return m_callbackCount;
+ }
+
+ void setNotificationCallback(const Closure& closure)
+ {
+ m_closure = closure;
+ }
+
+private:
+ Closure m_closure;
+ blink::WebConnectionType m_observedType;
+ int m_callbackCount;
+};
+
+class ExitTask
+ : public blink::WebThread::Task {
+public:
+ ExitTask(blink::WebThread* thread)
+ : m_thread(thread)
+ {
+ }
+ virtual void run() OVERRIDE
+ {
+ m_thread->exitRunLoop();
+ }
+
+private:
+ blink::WebThread* m_thread;
+};
+
+class NetworkStateNotifierTest : public testing::Test {
+public:
+ NetworkStateNotifierTest()
+ : m_document(Document::create())
+ , m_document2(Document::create())
+ {
+ }
+
+ ExecutionContext* executionContext()
+ {
+ return m_document.get();
+ }
+
+ ExecutionContext* executionContext2()
+ {
+ return m_document2.get();
+ }
+
+protected:
+ void setType(blink::WebConnectionType type)
+ {
+ m_notifier.setWebConnectionType(type);
+
+ blink::WebThread* thread = blink::Platform::current()->currentThread();
+ thread->postTask(new ExitTask(thread));
+ thread->enterRunLoop();
+ }
+
+ void addObserverOnNotification(StateObserver* observer, StateObserver* observerToAdd)
+ {
+ observer->setNotificationCallback(bind(&NetworkStateNotifier::addObserver, &m_notifier, observerToAdd, executionContext()));
+ }
+
+ void removeObserverOnNotification(StateObserver* observer, StateObserver* observerToRemove)
+ {
+ observer->setNotificationCallback(bind(&NetworkStateNotifier::removeObserver, &m_notifier, observerToRemove, executionContext()));
+ }
+
+ RefPtrWillBePersistent<Document> m_document;
+ RefPtrWillBePersistent<Document> m_document2;
+ NetworkStateNotifier m_notifier;
+};
+
+TEST_F(NetworkStateNotifierTest, AddObserver)
+{
+ StateObserver observer;
+ m_notifier.addObserver(&observer, executionContext());
+ EXPECT_EQ(observer.observedType(), blink::ConnectionTypeNone);
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer.callbackCount(), 1);
+}
+
+TEST_F(NetworkStateNotifierTest, RemoveObserver)
+{
+ StateObserver observer1, observer2;
+ m_notifier.addObserver(&observer1, executionContext());
+ m_notifier.removeObserver(&observer1, executionContext());
+ m_notifier.addObserver(&observer2, executionContext());
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeNone);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeBluetooth);
+}
+
+TEST_F(NetworkStateNotifierTest, RemoveSoleObserver)
+{
+ StateObserver observer1, observer2;
+ m_notifier.addObserver(&observer1, executionContext());
+ m_notifier.removeObserver(&observer1, executionContext());
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeNone);
+}
+
+TEST_F(NetworkStateNotifierTest, AddObserverWhileNotifying)
+{
+ StateObserver observer1, observer2;
+ m_notifier.addObserver(&observer1, executionContext());
+ addObserverOnNotification(&observer1, &observer2);
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeBluetooth);
+}
+
+TEST_F(NetworkStateNotifierTest, RemoveSoleObserverWhileNotifying)
+{
+ StateObserver observer1;
+ m_notifier.addObserver(&observer1, executionContext());
+ removeObserverOnNotification(&observer1, &observer1);
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+
+ setType(blink::ConnectionTypeEthernet);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+}
+
+TEST_F(NetworkStateNotifierTest, RemoveCurrentObserverWhileNotifying)
+{
+ StateObserver observer1, observer2;
+ m_notifier.addObserver(&observer1, executionContext());
+ m_notifier.addObserver(&observer2, executionContext());
+ removeObserverOnNotification(&observer1, &observer1);
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeBluetooth);
+
+ setType(blink::ConnectionTypeEthernet);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeEthernet);
+}
+
+TEST_F(NetworkStateNotifierTest, RemovePastObserverWhileNotifying)
+{
+ StateObserver observer1, observer2;
+ m_notifier.addObserver(&observer1, executionContext());
+ m_notifier.addObserver(&observer2, executionContext());
+ removeObserverOnNotification(&observer2, &observer1);
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeBluetooth);
+
+ setType(blink::ConnectionTypeEthernet);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeEthernet);
+}
+
+TEST_F(NetworkStateNotifierTest, RemoveFutureObserverWhileNotifying)
+{
+ StateObserver observer1, observer2, observer3;
+ m_notifier.addObserver(&observer1, executionContext());
+ m_notifier.addObserver(&observer2, executionContext());
+ m_notifier.addObserver(&observer3, executionContext());
+ removeObserverOnNotification(&observer1, &observer2);
+
+ setType(blink::ConnectionTypeBluetooth);
+
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeNone);
+ EXPECT_EQ(observer3.observedType(), blink::ConnectionTypeBluetooth);
+}
+
+TEST_F(NetworkStateNotifierTest, MultipleContextsAddObserver)
+{
+ StateObserver observer1, observer2;
+ m_notifier.addObserver(&observer1, executionContext());
+ m_notifier.addObserver(&observer2, executionContext2());
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeBluetooth);
+}
+
+TEST_F(NetworkStateNotifierTest, RemoveContext)
+{
+ StateObserver observer1, observer2;
+ m_notifier.addObserver(&observer1, executionContext());
+ m_notifier.addObserver(&observer2, executionContext2());
+ m_notifier.removeObserver(&observer2, executionContext2());
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeNone);
+}
+
+TEST_F(NetworkStateNotifierTest, RemoveAllContexts)
+{
+ StateObserver observer1, observer2;
+ m_notifier.addObserver(&observer1, executionContext());
+ m_notifier.addObserver(&observer2, executionContext2());
+ m_notifier.removeObserver(&observer1, executionContext());
+ m_notifier.removeObserver(&observer2, executionContext2());
+
+ setType(blink::ConnectionTypeBluetooth);
+ EXPECT_EQ(observer1.observedType(), blink::ConnectionTypeNone);
+ EXPECT_EQ(observer2.observedType(), blink::ConnectionTypeNone);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/Page.cpp b/chromium/third_party/WebKit/Source/core/page/Page.cpp
index 4f2de052953..b380701fdc0 100644
--- a/chromium/third_party/WebKit/Source/core/page/Page.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/Page.cpp
@@ -27,17 +27,20 @@
#include "core/editing/Caret.h"
#include "core/editing/UndoStack.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/frame/DOMTimer.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/EventHandlerRegistry.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
-#include "core/history/HistoryItem.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/RemoteFrame.h"
+#include "core/frame/RemoteFrameView.h"
+#include "core/frame/Settings.h"
#include "core/inspector/InspectorController.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/loader/FrameLoader.h"
-#include "core/loader/ProgressTracker.h"
+#include "core/loader/HistoryItem.h"
#include "core/page/AutoscrollController.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
@@ -45,17 +48,15 @@
#include "core/page/DragController.h"
#include "core/page/FocusController.h"
#include "core/page/FrameTree.h"
-#include "core/page/PageConsole.h"
-#include "core/page/PageGroup.h"
#include "core/page/PageLifecycleNotifier.h"
#include "core/page/PointerLockController.h"
-#include "core/frame/Settings.h"
+#include "core/page/StorageClient.h"
#include "core/page/ValidationMessageClient.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/TextAutosizer.h"
#include "core/storage/StorageNamespace.h"
-#include "core/workers/SharedWorkerRepositoryClient.h"
#include "platform/plugins/PluginData.h"
#include "wtf/HashMap.h"
#include "wtf/RefCountedLeakCounter.h"
@@ -64,22 +65,35 @@
namespace WebCore {
-static HashSet<Page*>* allPages;
-
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, pageCounter, ("Page"));
-void Page::networkStateChanged(bool online)
+// static
+HashSet<Page*>& Page::allPages()
{
- if (!allPages)
- return;
+ DEFINE_STATIC_LOCAL(HashSet<Page*>, allPages, ());
+ return allPages;
+}
- Vector<RefPtr<Frame> > frames;
+// static
+HashSet<Page*>& Page::ordinaryPages()
+{
+ DEFINE_STATIC_LOCAL(HashSet<Page*>, ordinaryPages, ());
+ return ordinaryPages;
+}
+
+
+void Page::networkStateChanged(bool online)
+{
+ Vector<RefPtr<LocalFrame> > frames;
// Get all the frames of all the pages in all the page groups
- HashSet<Page*>::iterator end = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
- for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
- frames.append(frame);
+ HashSet<Page*>::iterator end = allPages().end();
+ for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ // FIXME: There is currently no way to dispatch events to out-of-process frames.
+ if (frame->isLocalFrame())
+ frames.append(toLocalFrame(frame));
+ }
InspectorInstrumentation::networkStateChanged(*it, online);
}
@@ -88,7 +102,7 @@ void Page::networkStateChanged(bool online)
frames[i]->domWindow()->dispatchEvent(Event::create(eventName));
}
-float deviceScaleFactor(Frame* frame)
+float deviceScaleFactor(LocalFrame* frame)
{
if (!frame)
return 1;
@@ -100,6 +114,7 @@ float deviceScaleFactor(Frame* frame)
Page::Page(PageClients& pageClients)
: SettingsDelegate(Settings::create())
+ , m_animator(this)
, m_autoscrollController(AutoscrollController::create(*this))
, m_chrome(Chrome::create(this, pageClients.chromeClient))
, m_dragCaretController(DragCaretController::create())
@@ -108,36 +123,29 @@ Page::Page(PageClients& pageClients)
, m_contextMenuController(ContextMenuController::create(this, pageClients.contextMenuClient))
, m_inspectorController(InspectorController::create(this, pageClients.inspectorClient))
, m_pointerLockController(PointerLockController::create(this))
- , m_historyController(adoptPtr(new HistoryController(this)))
- , m_progress(ProgressTracker::create())
, m_undoStack(UndoStack::create())
+ , m_mainFrame(0)
, m_backForwardClient(pageClients.backForwardClient)
, m_editorClient(pageClients.editorClient)
- , m_validationMessageClient(0)
- , m_sharedWorkerRepositoryClient(0)
, m_spellCheckerClient(pageClients.spellCheckerClient)
+ , m_storageClient(pageClients.storageClient)
, m_subframeCount(0)
, m_openedByDOM(false)
, m_tabKeyCyclesThroughElements(true)
, m_defersLoading(false)
- , m_pageScaleFactor(1)
, m_deviceScaleFactor(1)
- , m_group(0)
, m_timerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval())
, m_visibilityState(PageVisibilityStateVisible)
, m_isCursorVisible(true)
#ifndef NDEBUG
, m_isPainting(false)
#endif
- , m_console(PageConsole::create(this))
+ , m_frameHost(FrameHost::create(*this))
{
ASSERT(m_editorClient);
- if (!allPages)
- allPages = new HashSet<Page*>;
-
- ASSERT(!allPages->contains(this));
- allPages->add(this);
+ ASSERT(!allPages().contains(this));
+ allPages().add(this);
#ifndef NDEBUG
pageCounter.increment();
@@ -146,33 +154,24 @@ Page::Page(PageClients& pageClients)
Page::~Page()
{
- m_mainFrame->setView(0);
- clearPageGroup();
- allPages->remove(this);
-
- for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
- frame->willDetachPage();
- frame->detachFromPage();
- }
-
- m_inspectorController->inspectedPageDestroyed();
-
- if (m_scrollingCoordinator)
- m_scrollingCoordinator->pageDestroyed();
+ // willBeDestroyed() must be called before Page destruction.
+ ASSERT(!m_mainFrame);
+}
-#ifndef NDEBUG
- pageCounter.decrement();
-#endif
+void Page::makeOrdinary()
+{
+ ASSERT(!ordinaryPages().contains(this));
+ ordinaryPages().add(this);
}
ViewportDescription Page::viewportDescription() const
{
- return mainFrame() && mainFrame()->document() ? mainFrame()->document()->viewportDescription() : ViewportDescription();
+ return mainFrame() && mainFrame()->isLocalFrame() && deprecatedLocalMainFrame()->document() ? deprecatedLocalMainFrame()->document()->viewportDescription() : ViewportDescription();
}
ScrollingCoordinator* Page::scrollingCoordinator()
{
- if (!m_scrollingCoordinator && m_settings->scrollingCoordinatorEnabled())
+ if (!m_scrollingCoordinator && m_settings->acceleratedCompositingEnabled())
m_scrollingCoordinator = ScrollingCoordinator::create(this);
return m_scrollingCoordinator.get();
@@ -186,10 +185,10 @@ String Page::mainThreadScrollingReasonsAsText()
return String();
}
-PassRefPtr<ClientRectList> Page::nonFastScrollableRects(const Frame* frame)
+PassRefPtrWillBeRawPtr<ClientRectList> Page::nonFastScrollableRects(const LocalFrame* frame)
{
- if (Document* document = m_mainFrame->document())
- document->updateLayout();
+ if (m_mainFrame->isLocalFrame() && deprecatedLocalMainFrame()->document())
+ deprecatedLocalMainFrame()->document()->updateLayout();
Vector<IntRect> rects;
if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
@@ -201,7 +200,7 @@ PassRefPtr<ClientRectList> Page::nonFastScrollableRects(const Frame* frame)
return ClientRectList::create(quads);
}
-void Page::setMainFrame(PassRefPtr<Frame> mainFrame)
+void Page::setMainFrame(Frame* mainFrame)
{
ASSERT(!m_mainFrame); // Should only be called during initialization
m_mainFrame = mainFrame;
@@ -209,12 +208,12 @@ void Page::setMainFrame(PassRefPtr<Frame> mainFrame)
void Page::documentDetached(Document* document)
{
+ m_multisamplingChangedObservers.clear();
m_pointerLockController->documentDetached(document);
m_contextMenuController->documentDetached(document);
if (m_validationMessageClient)
m_validationMessageClient->documentDetached(*document);
- if (m_sharedWorkerRepositoryClient)
- m_sharedWorkerRepositoryClient->documentDetached(document);
+ m_frameHost->eventHandlerRegistry().documentDetached(*document);
}
bool Page::openedByDOM() const
@@ -227,69 +226,59 @@ void Page::setOpenedByDOM()
m_openedByDOM = true;
}
-void Page::clearPageGroup()
+void Page::scheduleForcedStyleRecalcForAllPages()
{
- if (!m_group)
- return;
- m_group->removePage(this);
- m_group = 0;
+ HashSet<Page*>::iterator end = allPages().end();
+ for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it)
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->setNeedsStyleRecalc(SubtreeStyleChange);
+ }
}
-void Page::setGroupType(PageGroupType type)
+void Page::setNeedsRecalcStyleInAllFrames()
{
- clearPageGroup();
-
- switch (type) {
- case PrivatePageGroup:
- m_group = PageGroup::create();
- break;
- case SharedPageGroup:
- m_group = PageGroup::sharedGroup();
- break;
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->styleResolverChanged();
}
-
- m_group->addPage(this);
}
-void Page::scheduleForcedStyleRecalcForAllPages()
+void Page::setNeedsLayoutInAllFrames()
{
- if (!allPages)
- return;
- HashSet<Page*>::iterator end = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it)
- for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
- frame->document()->setNeedsStyleRecalc();
-}
-
-void Page::setNeedsRecalcStyleInAllFrames()
-{
- for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
- frame->document()->styleResolverChanged(RecalcStyleDeferred);
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (FrameView* view = toLocalFrame(frame)->view()) {
+ view->setNeedsLayout();
+ view->scheduleRelayout();
+ }
+ }
}
void Page::refreshPlugins(bool reload)
{
- if (!allPages)
+ if (allPages().isEmpty())
return;
PluginData::refresh();
- Vector<RefPtr<Frame> > framesNeedingReload;
+ Vector<RefPtr<LocalFrame> > framesNeedingReload;
- HashSet<Page*>::iterator end = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != end; ++it) {
+ HashSet<Page*>::iterator end = allPages().end();
+ for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
Page* page = *it;
// Clear out the page's plug-in data.
if (page->m_pluginData)
- page->m_pluginData = 0;
+ page->m_pluginData = nullptr;
if (!reload)
continue;
for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document()->containsPlugins())
- framesNeedingReload.append(frame);
+ if (frame->isLocalFrame() && toLocalFrame(frame)->document()->containsPlugins())
+ framesNeedingReload.append(toLocalFrame(frame));
}
}
@@ -299,7 +288,7 @@ void Page::refreshPlugins(bool reload)
PluginData* Page::pluginData() const
{
- if (!mainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
+ if (!deprecatedLocalMainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
return 0;
if (!m_pluginData)
m_pluginData = PluginData::create(this);
@@ -320,43 +309,63 @@ void Page::unmarkAllTextMatches()
Frame* frame = mainFrame();
do {
- frame->document()->markers()->removeMarkers(DocumentMarker::TextMatch);
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->markers().removeMarkers(DocumentMarker::TextMatch);
frame = incrementFrame(frame, true, false);
} while (frame);
}
+void Page::setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient> client)
+{
+ m_validationMessageClient = client;
+}
+
void Page::setDefersLoading(bool defers)
{
if (defers == m_defersLoading)
return;
m_defersLoading = defers;
- m_historyController->setDefersLoading(defers);
- for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
- frame->loader().setDefersLoading(defers);
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->loader().setDefersLoading(defers);
+ }
}
void Page::setPageScaleFactor(float scale, const IntPoint& origin)
{
- FrameView* view = mainFrame()->view();
+ if (!mainFrame()->isLocalFrame())
+ return;
- if (scale != m_pageScaleFactor) {
- m_pageScaleFactor = scale;
+ FrameView* view = deprecatedLocalMainFrame()->view();
+ PinchViewport& viewport = frameHost().pinchViewport();
- if (view)
+ if (scale != viewport.scale()) {
+ viewport.setScale(scale);
+
+ if (view && !settings().pinchVirtualViewportEnabled())
view->setVisibleContentScaleFactor(scale);
- mainFrame()->deviceOrPageScaleFactorChanged();
+ deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged();
m_chrome->client().deviceOrPageScaleFactorChanged();
+ // FIXME: In virtual-viewport pinch mode, scale doesn't change the fixed-pos viewport;
+ // remove once it's the only pinch mode in town.
if (view)
- view->setViewportConstrainedObjectsNeedLayout();
+ view->viewportConstrainedVisibleContentSizeChanged(true, true);
+
+ deprecatedLocalMainFrame()->loader().saveScrollState();
}
if (view && view->scrollPosition() != origin)
view->notifyScrollPositionChanged(origin);
}
+float Page::pageScaleFactor() const
+{
+ return frameHost().pinchViewport().scale();
+}
+
void Page::setDeviceScaleFactor(float scaleFactor)
{
if (m_deviceScaleFactor == scaleFactor)
@@ -365,58 +374,40 @@ void Page::setDeviceScaleFactor(float scaleFactor)
m_deviceScaleFactor = scaleFactor;
setNeedsRecalcStyleInAllFrames();
- if (mainFrame()) {
- mainFrame()->deviceOrPageScaleFactorChanged();
+ if (mainFrame() && mainFrame()->isLocalFrame()) {
+ deprecatedLocalMainFrame()->deviceOrPageScaleFactorChanged();
m_chrome->client().deviceOrPageScaleFactorChanged();
}
}
-void Page::setPagination(const Pagination& pagination)
+void Page::allVisitedStateChanged()
{
- if (m_pagination == pagination)
- return;
-
- m_pagination = pagination;
-
- setNeedsRecalcStyleInAllFrames();
-}
-
-void Page::allVisitedStateChanged(PageGroup* group)
-{
- ASSERT(group);
- if (!allPages)
- return;
-
- HashSet<Page*>::iterator pagesEnd = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
+ for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
Page* page = *it;
- if (page->m_group != group)
- continue;
- for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
- frame->document()->visitedLinkState().invalidateStyleForAllLinks();
+ for (Frame* frame = page->m_mainFrame; frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->visitedLinkState().invalidateStyleForAllLinks();
+ }
}
}
-void Page::visitedStateChanged(PageGroup* group, LinkHash linkHash)
+void Page::visitedStateChanged(LinkHash linkHash)
{
- ASSERT(group);
- if (!allPages)
- return;
-
- HashSet<Page*>::iterator pagesEnd = allPages->end();
- for (HashSet<Page*>::iterator it = allPages->begin(); it != pagesEnd; ++it) {
+ HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
+ for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
Page* page = *it;
- if (page->m_group != group)
- continue;
- for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
- frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
+ for (Frame* frame = page->m_mainFrame; frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->visitedLinkState().invalidateStyleForLink(linkHash);
+ }
}
}
StorageNamespace* Page::sessionStorage(bool optionalCreate)
{
if (!m_sessionStorage && optionalCreate)
- m_sessionStorage = StorageNamespace::sessionStorageNamespace(this);
+ m_sessionStorage = m_storageClient->createSessionStorageNamespace();
return m_sessionStorage.get();
}
@@ -427,8 +418,8 @@ void Page::setTimerAlignmentInterval(double interval)
m_timerAlignmentInterval = interval;
for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
- if (frame->document())
- frame->document()->didChangeTimerAlignmentInterval();
+ if (frame->isLocalFrame() && toLocalFrame(frame)->document())
+ toLocalFrame(frame)->document()->didChangeTimerAlignmentInterval();
}
}
@@ -437,7 +428,7 @@ double Page::timerAlignmentInterval() const
return m_timerAlignmentInterval;
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
void Page::checkSubframeCountConsistency() const
{
ASSERT(m_subframeCount >= 0);
@@ -464,8 +455,8 @@ void Page::setVisibilityState(PageVisibilityState visibilityState, bool isInitia
if (!isInitialState)
lifecycleNotifier().notifyPageVisibilityChanged();
- if (!isInitialState && m_mainFrame)
- m_mainFrame->dispatchVisibilityStateChangeEvent();
+ if (!isInitialState && m_mainFrame && m_mainFrame->isLocalFrame())
+ deprecatedLocalMainFrame()->didChangeVisibilityState();
}
PageVisibilityState Page::visibilityState() const
@@ -473,6 +464,11 @@ PageVisibilityState Page::visibilityState() const
return m_visibilityState;
}
+bool Page::isCursorVisible() const
+{
+ return m_isCursorVisible && settings().deviceSupportsMouse();
+}
+
void Page::addMultisamplingChangedObserver(MultisamplingChangedObserver* observer)
{
m_multisamplingChangedObservers.add(observer);
@@ -490,46 +486,100 @@ void Page::settingsChanged(SettingsDelegate::ChangeType changeType)
setNeedsRecalcStyleInAllFrames();
break;
case SettingsDelegate::ViewportDescriptionChange:
- if (mainFrame())
- mainFrame()->document()->updateViewportDescription();
+ if (mainFrame() && mainFrame()->isLocalFrame())
+ deprecatedLocalMainFrame()->document()->updateViewportDescription();
break;
case SettingsDelegate::MediaTypeChange:
- m_mainFrame->view()->setMediaType(settings().mediaTypeOverride());
- setNeedsRecalcStyleInAllFrames();
+ if (m_mainFrame->isLocalFrame()) {
+ deprecatedLocalMainFrame()->view()->setMediaType(AtomicString(settings().mediaTypeOverride()));
+ setNeedsRecalcStyleInAllFrames();
+ }
break;
case SettingsDelegate::DNSPrefetchingChange:
- for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
- frame->document()->initDNSPrefetch();
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->initDNSPrefetch();
+ }
break;
case SettingsDelegate::MultisamplingChange: {
- HashSet<MultisamplingChangedObserver*>::iterator stop = m_multisamplingChangedObservers.end();
- for (HashSet<MultisamplingChangedObserver*>::iterator it = m_multisamplingChangedObservers.begin(); it != stop; ++it)
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> >::iterator stop = m_multisamplingChangedObservers.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> >::iterator it = m_multisamplingChangedObservers.begin(); it != stop; ++it)
(*it)->multisamplingChanged(m_settings->openGLMultisamplingEnabled());
break;
}
case SettingsDelegate::ImageLoadingChange:
for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
- frame->document()->fetcher()->setImagesEnabled(settings().imagesEnabled());
- frame->document()->fetcher()->setAutoLoadImages(settings().loadsImagesAutomatically());
+ if (frame->isLocalFrame()) {
+ toLocalFrame(frame)->document()->fetcher()->setImagesEnabled(settings().imagesEnabled());
+ toLocalFrame(frame)->document()->fetcher()->setAutoLoadImages(settings().loadsImagesAutomatically());
+ }
}
break;
case SettingsDelegate::TextAutosizingChange:
- // FIXME: I wonder if this needs to traverse frames like in WebViewImpl::resize, or whether there is only one document per Settings instance?
+ if (!mainFrame() || !mainFrame()->isLocalFrame())
+ break;
+ if (FastTextAutosizer* textAutosizer = deprecatedLocalMainFrame()->document()->fastTextAutosizer()) {
+ textAutosizer->updatePageInfoInAllFrames();
+ } else {
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (TextAutosizer* textAutosizer = toLocalFrame(frame)->document()->textAutosizer())
+ textAutosizer->recalculateMultipliers();
+ }
+ // TextAutosizing updates RenderStyle during layout phase (via TextAutosizer::processSubtree).
+ // We should invoke setNeedsLayout here.
+ setNeedsLayoutInAllFrames();
+ }
+ break;
+ case SettingsDelegate::ScriptEnableChange:
+ m_inspectorController->scriptsEnabled(settings().scriptEnabled());
+ break;
+ case SettingsDelegate::FontFamilyChange:
for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
- TextAutosizer* textAutosizer = frame->document()->textAutosizer();
- if (textAutosizer)
- textAutosizer->recalculateMultipliers();
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->styleEngine()->updateGenericFontFamilySettings();
}
setNeedsRecalcStyleInAllFrames();
break;
+ case SettingsDelegate::AcceleratedCompositingChange:
+ updateAcceleratedCompositingSettings();
+ break;
}
}
-void Page::didCommitLoad(Frame* frame)
+void Page::updateAcceleratedCompositingSettings()
+{
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (FrameView* view = toLocalFrame(frame)->view())
+ view->updateAcceleratedCompositingSettings();
+ }
+}
+
+void Page::didCommitLoad(LocalFrame* frame)
{
lifecycleNotifier().notifyDidCommitLoad(frame);
- if (m_mainFrame == frame)
+ if (m_mainFrame == frame) {
useCounter().didCommitLoad();
+ m_inspectorController->didCommitLoadForMainFrame();
+ }
+}
+
+void Page::acceptLanguagesChanged()
+{
+ Vector< RefPtr<LocalFrame> > frames;
+
+ // Even though we don't fire an event from here, the LocalDOMWindow's will fire
+ // an event so we keep the frames alive until we are done.
+ for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ frames.append(toLocalFrame(frame));
+ }
+
+ for (unsigned i = 0; i < frames.size(); ++i)
+ frames[i]->domWindow()->acceptLanguagesChanged();
}
PageLifecycleNotifier& Page::lifecycleNotifier()
@@ -542,6 +592,53 @@ PassOwnPtr<LifecycleNotifier<Page> > Page::createLifecycleNotifier()
return PageLifecycleNotifier::create(this);
}
+void Page::trace(Visitor* visitor)
+{
+ visitor->trace(m_dragCaretController);
+ visitor->trace(m_dragController);
+ visitor->trace(m_pointerLockController);
+ visitor->trace(m_undoStack);
+ visitor->trace(m_validationMessageClient);
+ visitor->trace(m_multisamplingChangedObservers);
+ visitor->trace(m_frameHost);
+ WillBeHeapSupplementable<Page>::trace(visitor);
+}
+
+void Page::willBeDestroyed()
+{
+ RefPtr<Frame> mainFrame = m_mainFrame;
+
+ if (mainFrame->isLocalFrame())
+ toLocalFrame(mainFrame.get())->loader().frameDetached();
+
+ // Disable all agents prior to resetting the frame view.
+ m_inspectorController->willBeDestroyed();
+
+ if (mainFrame->isLocalFrame()) {
+ toLocalFrame(mainFrame.get())->setView(nullptr);
+ } else {
+ ASSERT(m_mainFrame->isRemoteFrame());
+ toRemoteFrame(mainFrame.get())->setView(nullptr);
+ }
+
+ allPages().remove(this);
+ if (ordinaryPages().contains(this))
+ ordinaryPages().remove(this);
+
+ if (m_scrollingCoordinator)
+ m_scrollingCoordinator->willBeDestroyed();
+
+#ifndef NDEBUG
+ pageCounter.decrement();
+#endif
+
+ m_chrome->willBeDestroyed();
+ m_mainFrame = 0;
+ if (m_validationMessageClient)
+ m_validationMessageClient->willBeDestroyed();
+ WillBeHeapSupplementable<Page>::willBeDestroyed();
+}
+
Page::PageClients::PageClients()
: chromeClient(0)
, contextMenuClient(0)
@@ -550,6 +647,7 @@ Page::PageClients::PageClients()
, inspectorClient(0)
, backForwardClient(0)
, spellCheckerClient(0)
+ , storageClient(0)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/page/Page.h b/chromium/third_party/WebKit/Source/core/page/Page.h
index 1104d156851..6408c7ff0ef 100644
--- a/chromium/third_party/WebKit/Source/core/page/Page.h
+++ b/chromium/third_party/WebKit/Source/core/page/Page.h
@@ -22,15 +22,16 @@
#define Page_h
#include "core/dom/ViewportDescription.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/SettingsDelegate.h"
#include "core/frame/UseCounter.h"
-#include "core/loader/HistoryController.h"
+#include "core/page/PageAnimator.h"
#include "core/page/PageVisibilityState.h"
-#include "core/rendering/Pagination.h"
#include "platform/LifecycleContext.h"
#include "platform/Supplementable.h"
#include "platform/geometry/LayoutRect.h"
#include "platform/geometry/Region.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/HashSet.h"
#include "wtf/Noncopyable.h"
@@ -52,28 +53,23 @@ class DragController;
class EditorClient;
class FocusController;
class Frame;
-class FrameSelection;
-class HaltablePlugin;
+class FrameHost;
class HistoryItem;
class InspectorClient;
class InspectorController;
-class Node;
-class PageConsole;
-class PageGroup;
class PageLifecycleNotifier;
class PlatformMouseEvent;
class PluginData;
class PointerLockController;
-class ProgressTracker;
class Range;
class RenderBox;
class RenderObject;
class RenderTheme;
+class StorageClient;
class VisibleSelection;
class ScrollableArea;
class ScrollingCoordinator;
class Settings;
-class SharedWorkerRepositoryClient;
class SpellCheckerClient;
class StorageNamespace;
class UndoStack;
@@ -81,9 +77,10 @@ class ValidationMessageClient;
typedef uint64_t LinkHash;
-float deviceScaleFactor(Frame*);
+float deviceScaleFactor(LocalFrame*);
-class Page : public Supplementable<Page>, public LifecycleContext<Page>, public SettingsDelegate {
+class Page FINAL : public NoBaseWillBeGarbageCollectedFinalized<Page>, public WillBeHeapSupplementable<Page>, public LifecycleContext<Page>, public SettingsDelegate {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Page);
WTF_MAKE_NONCOPYABLE(Page);
friend class Settings;
public:
@@ -103,12 +100,24 @@ public:
InspectorClient* inspectorClient;
BackForwardClient* backForwardClient;
SpellCheckerClient* spellCheckerClient;
+ StorageClient* storageClient;
};
explicit Page(PageClients&);
- ~Page();
+ virtual ~Page();
+
+ void makeOrdinary();
+
+ // This method returns all pages, incl. private ones associated with
+ // inspector overlay, popups, SVGImage, etc.
+ static HashSet<Page*>& allPages();
+ // This method returns all ordinary pages.
+ static HashSet<Page*>& ordinaryPages();
+
+ FrameHost& frameHost() const { return *m_frameHost; }
void setNeedsRecalcStyleInAllFrames();
+ void updateAcceleratedCompositingSettings();
ViewportDescription viewportDescription() const;
@@ -119,30 +128,25 @@ public:
SpellCheckerClient& spellCheckerClient() const { return *m_spellCheckerClient; }
UndoStack& undoStack() const { return *m_undoStack; }
- HistoryController& historyController() const { return *m_historyController; }
-
- void setMainFrame(PassRefPtr<Frame>);
- Frame* mainFrame() const { return m_mainFrame.get(); }
+ void setMainFrame(Frame*);
+ Frame* mainFrame() const { return m_mainFrame; }
+ // Escape hatch for existing code that assumes that the root frame is
+ // always a LocalFrame. With OOPI, this is not always the case. Code that
+ // depends on this will generally have to be rewritten to propagate any
+ // necessary state through all renderer processes for that page and/or
+ // coordinate/rely on the browser process to help dispatch/coordinate work.
+ LocalFrame* deprecatedLocalMainFrame() const { return toLocalFrame(m_mainFrame); }
void documentDetached(Document*);
bool openedByDOM() const;
void setOpenedByDOM();
- enum PageGroupType { PrivatePageGroup, SharedPageGroup };
- void setGroupType(PageGroupType);
- void clearPageGroup();
- PageGroup& group()
- {
- if (!m_group)
- setGroupType(PrivatePageGroup);
- return *m_group;
- }
-
void incrementSubframeCount() { ++m_subframeCount; }
void decrementSubframeCount() { ASSERT(m_subframeCount); --m_subframeCount; }
int subframeCount() const { checkSubframeCountConsistency(); return m_subframeCount; }
+ PageAnimator& animator() { return m_animator; }
Chrome& chrome() const { return *m_chrome; }
AutoscrollController& autoscrollController() const { return *m_autoscrollController; }
DragCaretController& dragCaretController() const { return *m_dragCaretController; }
@@ -151,18 +155,15 @@ public:
ContextMenuController& contextMenuController() const { return *m_contextMenuController; }
InspectorController& inspectorController() const { return *m_inspectorController; }
PointerLockController& pointerLockController() const { return *m_pointerLockController; }
- ValidationMessageClient* validationMessageClient() const { return m_validationMessageClient; }
- void setValidationMessageClient(ValidationMessageClient* client) { m_validationMessageClient = client; }
- SharedWorkerRepositoryClient* sharedWorkerRepositoryClient() { return m_sharedWorkerRepositoryClient; }
- void setSharedWorkerRepositoryClient(SharedWorkerRepositoryClient* client) { m_sharedWorkerRepositoryClient = client; }
+ ValidationMessageClient& validationMessageClient() const { return *m_validationMessageClient; }
+ void setValidationMessageClient(PassOwnPtrWillBeRawPtr<ValidationMessageClient>);
ScrollingCoordinator* scrollingCoordinator();
String mainThreadScrollingReasonsAsText();
- PassRefPtr<ClientRectList> nonFastScrollableRects(const Frame*);
+ PassRefPtrWillBeRawPtr<ClientRectList> nonFastScrollableRects(const LocalFrame*);
Settings& settings() const { return *m_settings; }
- ProgressTracker& progress() const { return *m_progress; }
BackForwardClient& backForward() const { return *m_backForwardClient; }
UseCounter& useCounter() { return m_useCounter; }
@@ -179,22 +180,16 @@ public:
bool defersLoading() const { return m_defersLoading; }
void setPageScaleFactor(float scale, const IntPoint& origin);
- float pageScaleFactor() const { return m_pageScaleFactor; }
+ float pageScaleFactor() const;
float deviceScaleFactor() const { return m_deviceScaleFactor; }
void setDeviceScaleFactor(float);
- // Page and FrameView both store a Pagination value. Page::pagination() is set only by API,
- // and FrameView::pagination() is set only by CSS. Page::pagination() will affect all
- // FrameViews in the page cache, but FrameView::pagination() only affects the current
- // FrameView.
- const Pagination& pagination() const { return m_pagination; }
- void setPagination(const Pagination&);
-
- static void allVisitedStateChanged(PageGroup*);
- static void visitedStateChanged(PageGroup*, LinkHash visitedHash);
+ static void allVisitedStateChanged();
+ static void visitedStateChanged(LinkHash visitedHash);
StorageNamespace* sessionStorage(bool optionalCreate = true);
+ StorageClient& storageClient() const { return *m_storageClient; }
// Don't allow more than a certain number of frames in a page.
// This seems like a reasonable upper bound, and otherwise mutually
@@ -205,7 +200,7 @@ public:
PageVisibilityState visibilityState() const;
void setVisibilityState(PageVisibilityState, bool);
- bool isCursorVisible() const { return m_isCursorVisible; }
+ bool isCursorVisible() const;
void setIsCursorVisible(bool isVisible) { m_isCursorVisible = isVisible; }
#ifndef NDEBUG
@@ -213,11 +208,9 @@ public:
bool isPainting() const { return m_isPainting; }
#endif
- PageConsole& console() { return *m_console; }
-
double timerAlignmentInterval() const;
- class MultisamplingChangedObserver {
+ class MultisamplingChangedObserver : public WillBeGarbageCollectedMixin {
public:
virtual void multisamplingChanged(bool) = 0;
};
@@ -225,52 +218,68 @@ public:
void addMultisamplingChangedObserver(MultisamplingChangedObserver*);
void removeMultisamplingChangedObserver(MultisamplingChangedObserver*);
- void didCommitLoad(Frame*);
+ void didCommitLoad(LocalFrame*);
+
+ void acceptLanguagesChanged();
static void networkStateChanged(bool online);
PassOwnPtr<LifecycleNotifier<Page> > createLifecycleNotifier();
+ void trace(Visitor*);
+ void willBeDestroyed();
+
protected:
PageLifecycleNotifier& lifecycleNotifier();
private:
void initGroup();
-#if ASSERT_DISABLED
- void checkSubframeCountConsistency() const { }
-#else
+#if ASSERT_ENABLED
void checkSubframeCountConsistency() const;
+#else
+ void checkSubframeCountConsistency() const { }
#endif
void setTimerAlignmentInterval(double);
+ void setNeedsLayoutInAllFrames();
+
// SettingsDelegate overrides.
- virtual Page* page() OVERRIDE { return this; }
virtual void settingsChanged(SettingsDelegate::ChangeType) OVERRIDE;
+ PageAnimator m_animator;
const OwnPtr<AutoscrollController> m_autoscrollController;
const OwnPtr<Chrome> m_chrome;
- const OwnPtr<DragCaretController> m_dragCaretController;
- const OwnPtr<DragController> m_dragController;
+ const OwnPtrWillBeMember<DragCaretController> m_dragCaretController;
+ const OwnPtrWillBeMember<DragController> m_dragController;
const OwnPtr<FocusController> m_focusController;
const OwnPtr<ContextMenuController> m_contextMenuController;
const OwnPtr<InspectorController> m_inspectorController;
- const OwnPtr<PointerLockController> m_pointerLockController;
- RefPtr<ScrollingCoordinator> m_scrollingCoordinator;
-
- const OwnPtr<HistoryController> m_historyController;
- const OwnPtr<ProgressTracker> m_progress;
- const OwnPtr<UndoStack> m_undoStack;
-
- RefPtr<Frame> m_mainFrame;
+ const OwnPtrWillBeMember<PointerLockController> m_pointerLockController;
+ OwnPtr<ScrollingCoordinator> m_scrollingCoordinator;
+ const OwnPtrWillBeMember<UndoStack> m_undoStack;
+
+ // Typically, the main frame and Page should both be owned by the embedder,
+ // which must call Page::willBeDestroyed() prior to destroying Page. This
+ // call detaches the main frame and clears this pointer, thus ensuring that
+ // this field only references a live main frame.
+ //
+ // However, there are several locations (InspectorOverlay, SVGImage, and
+ // WebPagePopupImpl) which don't hold a reference to the main frame at all
+ // after creating it. These are still safe because they always create a
+ // Frame with a FrameView. FrameView and Frame hold references to each
+ // other, thus keeping each other alive. The call to willBeDestroyed()
+ // breaks this cycle, so the frame is still properly destroyed once no
+ // longer needed.
+ Frame* m_mainFrame;
mutable RefPtr<PluginData> m_pluginData;
BackForwardClient* m_backForwardClient;
EditorClient* const m_editorClient;
- ValidationMessageClient* m_validationMessageClient;
- SharedWorkerRepositoryClient* m_sharedWorkerRepositoryClient;
SpellCheckerClient* const m_spellCheckerClient;
+ StorageClient* m_storageClient;
+ OwnPtrWillBeMember<ValidationMessageClient> m_validationMessageClient;
UseCounter m_useCounter;
@@ -280,13 +289,8 @@ private:
bool m_tabKeyCyclesThroughElements;
bool m_defersLoading;
- float m_pageScaleFactor;
float m_deviceScaleFactor;
- Pagination m_pagination;
-
- RefPtr<PageGroup> m_group;
-
OwnPtr<StorageNamespace> m_sessionStorage;
double m_timerAlignmentInterval;
@@ -299,9 +303,11 @@ private:
bool m_isPainting;
#endif
- const OwnPtr<PageConsole> m_console;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<MultisamplingChangedObserver> > m_multisamplingChangedObservers;
- HashSet<MultisamplingChangedObserver*> m_multisamplingChangedObservers;
+ // A pointer to all the interfaces provided to in-process Frames for this Page.
+ // FIXME: Most of the members of Page should move onto FrameHost.
+ OwnPtrWillBeMember<FrameHost> m_frameHost;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/PageAnimator.cpp b/chromium/third_party/WebKit/Source/core/page/PageAnimator.cpp
new file mode 100644
index 00000000000..f8cce06199d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/PageAnimator.cpp
@@ -0,0 +1,82 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/page/PageAnimator.h"
+
+#include "core/animation/DocumentAnimations.h"
+#include "core/dom/Document.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
+#include "core/svg/SVGDocumentExtensions.h"
+
+namespace WebCore {
+
+PageAnimator::PageAnimator(Page* page)
+ : m_page(page)
+ , m_animationFramePending(false)
+ , m_servicingAnimations(false)
+ , m_updatingLayoutAndStyleForPainting(false)
+{
+}
+
+void PageAnimator::serviceScriptedAnimations(double monotonicAnimationStartTime)
+{
+ m_animationFramePending = false;
+ TemporaryChange<bool> servicing(m_servicingAnimations, true);
+
+ for (RefPtr<Frame> frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame()) {
+ RefPtr<LocalFrame> localFrame = toLocalFrame(frame.get());
+ localFrame->view()->serviceScrollAnimations();
+
+ DocumentAnimations::updateAnimationTimingForAnimationFrame(*localFrame->document(), monotonicAnimationStartTime);
+ SVGDocumentExtensions::serviceOnAnimationFrame(*localFrame->document(), monotonicAnimationStartTime);
+ }
+ }
+
+ WillBeHeapVector<RefPtrWillBeMember<Document> > documents;
+ for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ documents.append(toLocalFrame(frame)->document());
+ }
+
+ for (size_t i = 0; i < documents.size(); ++i)
+ documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime);
+}
+
+void PageAnimator::scheduleVisualUpdate()
+{
+ // FIXME: also include m_animationFramePending here. It is currently not there due to crbug.com/353756.
+ if (m_servicingAnimations || m_updatingLayoutAndStyleForPainting)
+ return;
+ m_page->chrome().scheduleAnimation();
+}
+
+void PageAnimator::updateLayoutAndStyleForPainting()
+{
+ if (!m_page->mainFrame()->isLocalFrame())
+ return;
+
+ RefPtr<FrameView> view = m_page->deprecatedLocalMainFrame()->view();
+
+ TemporaryChange<bool> servicing(m_updatingLayoutAndStyleForPainting, true);
+
+ // In order for our child HWNDs (NativeWindowWidgets) to update properly,
+ // they need to be told that we are updating the screen. The problem is that
+ // the native widgets need to recalculate their clip region and not overlap
+ // any of our non-native widgets. To force the resizing, call
+ // setFrameRect(). This will be a quick operation for most frames, but the
+ // NativeWindowWidgets will update a proper clipping region.
+ view->setFrameRect(view->frameRect());
+
+ // setFrameRect may have the side-effect of causing existing page layout to
+ // be invalidated, so layout needs to be called last.
+ view->updateLayoutAndStyleForPainting();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/page/PageAnimator.h b/chromium/third_party/WebKit/Source/core/page/PageAnimator.h
new file mode 100644
index 00000000000..5c8d9e5c240
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/PageAnimator.h
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PageAnimator_h
+#define PageAnimator_h
+
+namespace WebCore {
+
+class Page;
+
+class PageAnimator {
+public:
+ explicit PageAnimator(Page*);
+
+ void scheduleVisualUpdate();
+ void serviceScriptedAnimations(double monotonicAnimationStartTime);
+
+ void setAnimationFramePending() { m_animationFramePending = true; }
+ bool isServicingAnimations() const { return m_servicingAnimations; }
+ void updateLayoutAndStyleForPainting();
+
+private:
+ Page* m_page;
+ bool m_animationFramePending;
+ bool m_servicingAnimations;
+ bool m_updatingLayoutAndStyleForPainting;
+};
+
+}
+
+#endif // PageAnimator_h
diff --git a/chromium/third_party/WebKit/Source/core/page/PageConsole.cpp b/chromium/third_party/WebKit/Source/core/page/PageConsole.cpp
deleted file mode 100644
index 763910a162c..00000000000
--- a/chromium/third_party/WebKit/Source/core/page/PageConsole.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/page/PageConsole.h"
-
-#include "core/dom/Document.h"
-#include "core/dom/ScriptableDocumentParser.h"
-#include "core/inspector/ConsoleAPITypes.h"
-#include "core/inspector/InspectorConsoleInstrumentation.h"
-#include "core/page/Chrome.h"
-#include "core/page/ChromeClient.h"
-#include "core/frame/ConsoleBase.h"
-#include "core/page/Page.h"
-#include "wtf/text/StringBuilder.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-namespace {
-
-int muteCount = 0;
-
-}
-
-PageConsole::PageConsole(Page* page)
- : m_page(page)
-{
-}
-
-void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message)
-{
- addMessage(source, level, message, String(), 0, 0, 0, 0, 0);
-}
-
-void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack)
-{
- addMessage(source, level, message, String(), 0, 0, callStack, 0);
-}
-
-void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber, PassRefPtr<ScriptCallStack> callStack, ScriptState* state, unsigned long requestIdentifier)
-{
- if (muteCount && source != ConsoleAPIMessageSource)
- return;
-
- ExecutionContext* context = m_page->mainFrame()->document();
- if (!context)
- return;
-
- String messageURL;
- if (callStack) {
- messageURL = callStack->at(0).sourceURL();
- InspectorInstrumentation::addMessageToConsole(context, source, LogMessageType, level, message, callStack, requestIdentifier);
- } else {
- messageURL = url;
- InspectorInstrumentation::addMessageToConsole(context, source, LogMessageType, level, message, url, lineNumber, columnNumber, state, requestIdentifier);
- }
-
- if (source == CSSMessageSource)
- return;
-
- String stackTrace;
- if (callStack && m_page->chrome().client().shouldReportDetailedMessageForSource(messageURL))
- stackTrace = PageConsole::formatStackTraceString(message, callStack);
-
- m_page->chrome().client().addMessageToConsole(source, level, message, lineNumber, messageURL, stackTrace);
-}
-
-String PageConsole::formatStackTraceString(const String& originalMessage, PassRefPtr<ScriptCallStack> callStack)
-{
- StringBuilder stackTrace;
- for (size_t i = 0; i < callStack->size(); ++i) {
- const ScriptCallFrame& frame = callStack->at(i);
- stackTrace.append("\n at " + (frame.functionName().length() ? frame.functionName() : "(anonymous function)"));
- stackTrace.append(" (");
- stackTrace.append(frame.sourceURL());
- stackTrace.append(':');
- stackTrace.append(String::number(frame.lineNumber()));
- stackTrace.append(':');
- stackTrace.append(String::number(frame.columnNumber()));
- stackTrace.append(')');
- }
-
- return stackTrace.toString();
-}
-
-void PageConsole::mute()
-{
- muteCount++;
-}
-
-void PageConsole::unmute()
-{
- ASSERT(muteCount > 0);
- muteCount--;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/PageConsole.h b/chromium/third_party/WebKit/Source/core/page/PageConsole.h
deleted file mode 100644
index b62d1922ed1..00000000000
--- a/chromium/third_party/WebKit/Source/core/page/PageConsole.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PageConsole_h
-#define PageConsole_h
-
-#include "bindings/v8/ScriptState.h"
-#include "core/inspector/ScriptCallStack.h"
-#include "core/frame/ConsoleTypes.h"
-#include "wtf/Forward.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace WebCore {
-
-class Page;
-
-class PageConsole FINAL {
-public:
- static PassOwnPtr<PageConsole> create(Page* page) { return adoptPtr(new PageConsole(page)); }
-
- void addMessage(MessageSource, MessageLevel, const String& message);
- void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber = 0, PassRefPtr<ScriptCallStack> = 0, ScriptState* = 0, unsigned long requestIdentifier = 0);
- void addMessage(MessageSource, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>);
- static String formatStackTraceString(const String& originalMessage, PassRefPtr<ScriptCallStack>);
-
- static void mute();
- static void unmute();
-
-private:
- explicit PageConsole(Page*);
-
- Page* m_page;
-};
-
-} // namespace WebCore
-
-#endif // PageConsole_h
diff --git a/chromium/third_party/WebKit/Source/core/page/PageGroup.cpp b/chromium/third_party/WebKit/Source/core/page/PageGroup.cpp
deleted file mode 100644
index b4a72714323..00000000000
--- a/chromium/third_party/WebKit/Source/core/page/PageGroup.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/page/PageGroup.h"
-
-#include "core/dom/Document.h"
-#include "core/dom/StyleEngine.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "wtf/StdLibExtras.h"
-
-namespace WebCore {
-
-PageGroup::PageGroup()
-{
-}
-
-PageGroup::~PageGroup()
-{
- removeInjectedStyleSheets();
-}
-
-PageGroup* PageGroup::sharedGroup()
-{
- DEFINE_STATIC_REF(PageGroup, staticSharedGroup, (create()));
- return staticSharedGroup;
-}
-
-void PageGroup::addPage(Page* page)
-{
- ASSERT(page);
- ASSERT(!m_pages.contains(page));
- m_pages.add(page);
-}
-
-void PageGroup::removePage(Page* page)
-{
- ASSERT(page);
- ASSERT(m_pages.contains(page));
- m_pages.remove(page);
-}
-
-void PageGroup::injectStyleSheet(const String& source, const Vector<String>& whitelist, StyleInjectionTarget injectIn)
-{
- m_injectedStyleSheets.append(adoptPtr(new InjectedStyleSheet(source, whitelist, injectIn)));
- invalidatedInjectedStyleSheetCacheInAllFrames();
-}
-
-void PageGroup::removeInjectedStyleSheets()
-{
- m_injectedStyleSheets.clear();
- invalidatedInjectedStyleSheetCacheInAllFrames();
-}
-
-void PageGroup::invalidatedInjectedStyleSheetCacheInAllFrames()
-{
- // Clear our cached sheets and have them just reparse.
- HashSet<Page*>::const_iterator end = m_pages.end();
- for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) {
- for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
- frame->document()->styleEngine()->invalidateInjectedStyleSheetCache();
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/PageGroup.h b/chromium/third_party/WebKit/Source/core/page/PageGroup.h
deleted file mode 100644
index 5293bde39bc..00000000000
--- a/chromium/third_party/WebKit/Source/core/page/PageGroup.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PageGroup_h
-#define PageGroup_h
-
-#include "core/page/InjectedStyleSheet.h"
-#include "platform/Supplementable.h"
-#include "wtf/HashSet.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
- class Page;
-
- // FIXME: This is really more of a "Settings Group" than a Page Group.
- // It has nothing to do with Page. There is one shared PageGroup
- // in the renderer process, which all normal Pages belong to. There are also
- // additional private PageGroups for SVGImage, Inspector Overlay, etc.
-
- // This really only exists to service InjectedStyleSheets at this point.
- // InjectedStyleSheets could instead just use a global, and StyleEngine
- // could be taught to look for InjectedStyleSheets when resolving style
- // for normal frames.
- class PageGroup : public Supplementable<PageGroup>, public RefCounted<PageGroup> {
- WTF_MAKE_NONCOPYABLE(PageGroup); WTF_MAKE_FAST_ALLOCATED;
- public:
- ~PageGroup();
-
- static PassRefPtr<PageGroup> create() { return adoptRef(new PageGroup()); }
- static PageGroup* sharedGroup();
-
- const HashSet<Page*>& pages() const { return m_pages; }
-
- void addPage(Page*);
- void removePage(Page*);
-
- void injectStyleSheet(const String& source, const Vector<String>& whitelist, StyleInjectionTarget);
- void removeInjectedStyleSheets();
-
- const InjectedStyleSheetVector& injectedStyleSheets() const { return m_injectedStyleSheets; }
-
- private:
- PageGroup();
-
- void invalidatedInjectedStyleSheetCacheInAllFrames();
-
- HashSet<Page*> m_pages;
- InjectedStyleSheetVector m_injectedStyleSheets;
- };
-
-} // namespace WebCore
-
-#endif // PageGroup_h
diff --git a/chromium/third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp b/chromium/third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp
deleted file mode 100644
index be7e7c24508..00000000000
--- a/chromium/third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/page/PageGroupLoadDeferrer.h"
-
-#include "core/dom/Document.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/PageGroup.h"
-#include "wtf/HashSet.h"
-
-namespace WebCore {
-
-using namespace std;
-
-PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
-{
- const HashSet<Page*>& pages = page->group().pages();
-
- HashSet<Page*>::const_iterator end = pages.end();
- for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
- Page* otherPage = *it;
- if ((deferSelf || otherPage != page)) {
- if (!otherPage->defersLoading()) {
- m_deferredFrames.append(otherPage->mainFrame());
-
- // Ensure that we notify the client if the initial empty document is accessed before showing anything
- // modal, to prevent spoofs while the modal window or sheet is visible.
- otherPage->mainFrame()->loader().notifyIfInitialDocumentAccessed();
-
- // This code is not logically part of load deferring, but we do not want JS code executed beneath modal
- // windows or sheets, which is exactly when PageGroupLoadDeferrer is used.
- for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree().traverseNext())
- frame->document()->suspendScheduledTasks();
- }
- }
- }
-
- size_t count = m_deferredFrames.size();
- for (size_t i = 0; i < count; ++i)
- if (Page* page = m_deferredFrames[i]->page())
- page->setDefersLoading(true);
-}
-
-PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
-{
- for (size_t i = 0; i < m_deferredFrames.size(); ++i) {
- if (Page* page = m_deferredFrames[i]->page()) {
- page->setDefersLoading(false);
-
- for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
- frame->document()->resumeScheduledTasks();
- }
- }
-}
-
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.h b/chromium/third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.h
deleted file mode 100644
index 180707ea61c..00000000000
--- a/chromium/third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef PageGroupLoadDeferrer_h
-#define PageGroupLoadDeferrer_h
-
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
- class Frame;
- class Page;
-
- class PageGroupLoadDeferrer {
- WTF_MAKE_NONCOPYABLE(PageGroupLoadDeferrer);
- public:
- PageGroupLoadDeferrer(Page*, bool deferSelf);
- ~PageGroupLoadDeferrer();
-
- private:
- Vector<RefPtr<Frame>, 16> m_deferredFrames;
- };
-}
-
-#endif // PageGroupLoadDeferrer_h
diff --git a/chromium/third_party/WebKit/Source/core/page/PageLifecycleNotifier.h b/chromium/third_party/WebKit/Source/core/page/PageLifecycleNotifier.h
index 5514101ac70..0048320e643 100644
--- a/chromium/third_party/WebKit/Source/core/page/PageLifecycleNotifier.h
+++ b/chromium/third_party/WebKit/Source/core/page/PageLifecycleNotifier.h
@@ -34,14 +34,14 @@
namespace WebCore {
class Page;
-class Frame;
+class LocalFrame;
-class PageLifecycleNotifier : public LifecycleNotifier<Page> {
+class PageLifecycleNotifier FINAL : public LifecycleNotifier<Page> {
public:
static PassOwnPtr<PageLifecycleNotifier> create(Page*);
void notifyPageVisibilityChanged();
- void notifyDidCommitLoad(Frame*);
+ void notifyDidCommitLoad(LocalFrame*);
virtual void addObserver(Observer*) OVERRIDE;
virtual void removeObserver(Observer*) OVERRIDE;
@@ -65,7 +65,7 @@ inline void PageLifecycleNotifier::notifyPageVisibilityChanged()
(*it)->pageVisibilityChanged();
}
-inline void PageLifecycleNotifier::notifyDidCommitLoad(Frame* frame)
+inline void PageLifecycleNotifier::notifyDidCommitLoad(LocalFrame* frame)
{
TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverPageObservers);
for (PageObserverSet::iterator it = m_pageObservers.begin(); it != m_pageObservers.end(); ++it)
diff --git a/chromium/third_party/WebKit/Source/core/page/PageLifecycleObserver.h b/chromium/third_party/WebKit/Source/core/page/PageLifecycleObserver.h
index 86c0eb0ff20..7b1133c15b2 100644
--- a/chromium/third_party/WebKit/Source/core/page/PageLifecycleObserver.h
+++ b/chromium/third_party/WebKit/Source/core/page/PageLifecycleObserver.h
@@ -31,7 +31,7 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class Page;
template<> void observerContext(Page*, LifecycleObserver<Page>*);
@@ -45,7 +45,7 @@ public:
Page* page() const;
virtual void pageVisibilityChanged() { }
- virtual void didCommitLoad(Frame*) { }
+ virtual void didCommitLoad(LocalFrame*) { }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/PagePopupClient.cpp b/chromium/third_party/WebKit/Source/core/page/PagePopupClient.cpp
index f3e792f48f5..c5e14a2e68f 100644
--- a/chromium/third_party/WebKit/Source/core/page/PagePopupClient.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/PagePopupClient.cpp
@@ -35,11 +35,11 @@
namespace WebCore {
-#define addLiteral(literal, writer) writer.addData(literal, sizeof(literal) - 1)
+#define addLiteral(literal, data) data->append(literal, sizeof(literal) - 1)
-void PagePopupClient::addJavaScriptString(const String& str, DocumentWriter& writer)
+void PagePopupClient::addJavaScriptString(const String& str, SharedBuffer* data)
{
- addLiteral("\"", writer);
+ addLiteral("\"", data);
StringBuilder builder;
builder.reserveCapacity(str.length());
for (unsigned i = 0; i < str.length(); ++i) {
@@ -47,66 +47,66 @@ void PagePopupClient::addJavaScriptString(const String& str, DocumentWriter& wri
builder.append('\\');
builder.append(str[i]);
}
- addString(builder.toString(), writer);
- addLiteral("\"", writer);
+ addString(builder.toString(), data);
+ addLiteral("\"", data);
}
-void PagePopupClient::addProperty(const char* name, const String& value, DocumentWriter& writer)
+void PagePopupClient::addProperty(const char* name, const String& value, SharedBuffer* data)
{
- writer.addData(name, strlen(name));
- addLiteral(": ", writer);
- addJavaScriptString(value, writer);
- addLiteral(",\n", writer);
+ data->append(name, strlen(name));
+ addLiteral(": ", data);
+ addJavaScriptString(value, data);
+ addLiteral(",\n", data);
}
-void PagePopupClient::addProperty(const char* name, int value, DocumentWriter& writer)
+void PagePopupClient::addProperty(const char* name, int value, SharedBuffer* data)
{
- writer.addData(name, strlen(name));
- addLiteral(": ", writer);
- addString(String::number(value), writer);
- addLiteral(",\n", writer);
+ data->append(name, strlen(name));
+ addLiteral(": ", data);
+ addString(String::number(value), data);
+ addLiteral(",\n", data);
}
-void PagePopupClient::addProperty(const char* name, unsigned value, DocumentWriter& writer)
+void PagePopupClient::addProperty(const char* name, unsigned value, SharedBuffer* data)
{
- writer.addData(name, strlen(name));
- addLiteral(": ", writer);
- addString(String::number(value), writer);
- addLiteral(",\n", writer);
+ data->append(name, strlen(name));
+ addLiteral(": ", data);
+ addString(String::number(value), data);
+ addLiteral(",\n", data);
}
-void PagePopupClient::addProperty(const char* name, bool value, DocumentWriter& writer)
+void PagePopupClient::addProperty(const char* name, bool value, SharedBuffer* data)
{
- writer.addData(name, strlen(name));
- addLiteral(": ", writer);
+ data->append(name, strlen(name));
+ addLiteral(": ", data);
if (value)
- addLiteral("true", writer);
+ addLiteral("true", data);
else
- addLiteral("false", writer);
- addLiteral(",\n", writer);
+ addLiteral("false", data);
+ addLiteral(",\n", data);
}
-void PagePopupClient::addProperty(const char* name, const Vector<String>& values, DocumentWriter& writer)
+void PagePopupClient::addProperty(const char* name, const Vector<String>& values, SharedBuffer* data)
{
- writer.addData(name, strlen(name));
- addLiteral(": [", writer);
+ data->append(name, strlen(name));
+ addLiteral(": [", data);
for (unsigned i = 0; i < values.size(); ++i) {
if (i)
- addLiteral(",", writer);
- addJavaScriptString(values[i], writer);
+ addLiteral(",", data);
+ addJavaScriptString(values[i], data);
}
- addLiteral("],\n", writer);
+ addLiteral("],\n", data);
}
-void PagePopupClient::addProperty(const char* name, const IntRect& rect, DocumentWriter& writer)
+void PagePopupClient::addProperty(const char* name, const IntRect& rect, SharedBuffer* data)
{
- writer.addData(name, strlen(name));
- addLiteral(": {", writer);
- addProperty("x", rect.x(), writer);
- addProperty("y", rect.y(), writer);
- addProperty("width", rect.width(), writer);
- addProperty("height", rect.height(), writer);
- addLiteral("},\n", writer);
+ data->append(name, strlen(name));
+ addLiteral(": {", data);
+ addProperty("x", rect.x(), data);
+ addProperty("y", rect.y(), data);
+ addProperty("width", rect.width(), data);
+ addProperty("height", rect.height(), data);
+ addLiteral("},\n", data);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/PagePopupClient.h b/chromium/third_party/WebKit/Source/core/page/PagePopupClient.h
index 812e973a5de..4f86eb61b4c 100644
--- a/chromium/third_party/WebKit/Source/core/page/PagePopupClient.h
+++ b/chromium/third_party/WebKit/Source/core/page/PagePopupClient.h
@@ -31,26 +31,25 @@
#ifndef PagePopupClient_h
#define PagePopupClient_h
-#include "core/loader/DocumentWriter.h"
+#include "platform/SharedBuffer.h"
#include "platform/geometry/IntRect.h"
#include "wtf/text/CString.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class DocumentWriter;
class Locale;
class PagePopupClient {
public:
virtual IntSize contentSize() = 0;
- // Provide an HTML source through the specified DocumentWriter. The HTML
+ // Provide an HTML source to the specified buffer. The HTML
// source is rendered in a PagePopup.
// The content HTML supports:
// - No <select> popups
// - window.setValueAndClosePopup(number, string).
- virtual void writeDocument(DocumentWriter&) = 0;
+ virtual void writeDocument(SharedBuffer*) = 0;
// Returns a Locale object associated to the client.
virtual Locale& locale() = 0;
@@ -71,20 +70,20 @@ public:
virtual ~PagePopupClient() { }
// Helper functions to be used in PagePopupClient::writeDocument().
- static void addString(const String&, DocumentWriter&);
- static void addJavaScriptString(const String&, DocumentWriter&);
- static void addProperty(const char* name, const String& value, DocumentWriter&);
- static void addProperty(const char* name, int value, DocumentWriter&);
- static void addProperty(const char* name, unsigned value, DocumentWriter&);
- static void addProperty(const char* name, bool value, DocumentWriter&);
- static void addProperty(const char* name, const Vector<String>& values, DocumentWriter&);
- static void addProperty(const char* name, const IntRect&, DocumentWriter&);
+ static void addString(const String&, SharedBuffer*);
+ static void addJavaScriptString(const String&, SharedBuffer*);
+ static void addProperty(const char* name, const String& value, SharedBuffer*);
+ static void addProperty(const char* name, int value, SharedBuffer*);
+ static void addProperty(const char* name, unsigned value, SharedBuffer*);
+ static void addProperty(const char* name, bool value, SharedBuffer*);
+ static void addProperty(const char* name, const Vector<String>& values, SharedBuffer*);
+ static void addProperty(const char* name, const IntRect&, SharedBuffer*);
};
-inline void PagePopupClient::addString(const String& str, DocumentWriter& writer)
+inline void PagePopupClient::addString(const String& str, SharedBuffer* data)
{
CString str8 = str.utf8();
- writer.addData(str8.data(), str8.length());
+ data->append(str8.data(), str8.length());
}
}
diff --git a/chromium/third_party/WebKit/Source/core/page/PagePopupController.cpp b/chromium/third_party/WebKit/Source/core/page/PagePopupController.cpp
index 961d96eee2d..d221c4251bb 100644
--- a/chromium/third_party/WebKit/Source/core/page/PagePopupController.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/PagePopupController.cpp
@@ -44,9 +44,9 @@ PagePopupController::PagePopupController(PagePopupClient* client)
ScriptWrappable::init(this);
}
-PassRefPtr<PagePopupController> PagePopupController::create(PagePopupClient* client)
+PassRefPtrWillBeRawPtr<PagePopupController> PagePopupController::create(PagePopupClient* client)
{
- return adoptRef(new PagePopupController(client));
+ return adoptRefWillBeNoop(new PagePopupController(client));
}
void PagePopupController::setValueAndClosePopup(int numValue, const String& stringValue)
diff --git a/chromium/third_party/WebKit/Source/core/page/PagePopupController.h b/chromium/third_party/WebKit/Source/core/page/PagePopupController.h
index 7a4846fb0aa..04abbfb0715 100644
--- a/chromium/third_party/WebKit/Source/core/page/PagePopupController.h
+++ b/chromium/third_party/WebKit/Source/core/page/PagePopupController.h
@@ -32,6 +32,7 @@
#define PagePopupController_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
@@ -39,9 +40,9 @@ namespace WebCore {
class PagePopupClient;
-class PagePopupController : public RefCounted<PagePopupController>, public ScriptWrappable {
+class PagePopupController : public RefCountedWillBeGarbageCollectedFinalized<PagePopupController>, public ScriptWrappable {
public:
- static PassRefPtr<PagePopupController> create(PagePopupClient*);
+ static PassRefPtrWillBeRawPtr<PagePopupController> create(PagePopupClient*);
void setValueAndClosePopup(int numValue, const String& stringValue);
void setValue(const String&);
void closePopup();
@@ -51,6 +52,8 @@ public:
void clearPagePopupClient();
void histogramEnumeration(const String& name, int sample, int boundaryValue);
+ void trace(Visitor*) { }
+
private:
explicit PagePopupController(PagePopupClient*);
diff --git a/chromium/third_party/WebKit/Source/core/page/PagePopupController.idl b/chromium/third_party/WebKit/Source/core/page/PagePopupController.idl
index 0a4fbd4f637..e2c88b2ffd5 100644
--- a/chromium/third_party/WebKit/Source/core/page/PagePopupController.idl
+++ b/chromium/third_party/WebKit/Source/core/page/PagePopupController.idl
@@ -29,6 +29,7 @@
*/
[
+ WillBeGarbageCollected,
NoInterfaceObject,
RuntimeEnabled=PagePopup
] interface PagePopupController {
diff --git a/chromium/third_party/WebKit/Source/core/page/PageSerializer.cpp b/chromium/third_party/WebKit/Source/core/page/PageSerializer.cpp
index d41f8719763..ac6978d8cae 100644
--- a/chromium/third_party/WebKit/Source/core/page/PageSerializer.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/PageSerializer.cpp
@@ -31,7 +31,7 @@
#include "config.h"
#include "core/page/PageSerializer.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/CSSFontFaceRule.h"
#include "core/css/CSSFontFaceSrcValue.h"
#include "core/css/CSSImageValue.h"
@@ -48,13 +48,14 @@
#include "core/editing/MarkupAccumulator.h"
#include "core/fetch/FontResource.h"
#include "core/fetch/ImageResource.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLMetaElement.h"
#include "core/html/HTMLStyleElement.h"
-#include "core/html/parser/HTMLMetaCharsetParser.h"
-#include "core/frame/Frame.h"
+#include "core/html/parser/HTMLParserIdioms.h"
#include "core/page/Page.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/style/StyleFetchedImage.h"
@@ -68,55 +69,54 @@
namespace WebCore {
-static bool isCharsetSpecifyingNode(Node* node)
+static bool isCharsetSpecifyingNode(const Node& node)
{
- if (!node->isHTMLElement())
+ if (!isHTMLMetaElement(node))
return false;
- HTMLElement* element = toHTMLElement(node);
- if (!element->hasTagName(HTMLNames::metaTag))
- return false;
- HTMLMetaCharsetParser::AttributeList attributes;
- if (element->hasAttributes()) {
- for (unsigned i = 0; i < element->attributeCount(); ++i) {
- const Attribute* attribute = element->attributeItem(i);
+ const HTMLMetaElement& element = toHTMLMetaElement(node);
+ HTMLAttributeList attributeList;
+ if (element.hasAttributes()) {
+ AttributeCollection attributes = element.attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
// FIXME: We should deal appropriately with the attribute if they have a namespace.
- attributes.append(std::make_pair(attribute->name().toString(), attribute->value().string()));
+ attributeList.append(std::make_pair(it->name().localName(), it->value().string()));
}
}
- WTF::TextEncoding textEncoding = HTMLMetaCharsetParser::encodingFromMetaAttributes(attributes);
+ WTF::TextEncoding textEncoding = encodingFromMetaAttributes(attributeList);
return textEncoding.isValid();
}
-static bool shouldIgnoreElement(Element* element)
+static bool shouldIgnoreElement(const Element& element)
{
- return element->hasTagName(HTMLNames::scriptTag) || element->hasTagName(HTMLNames::noscriptTag) || isCharsetSpecifyingNode(element);
+ return isHTMLScriptElement(element) || isHTMLNoScriptElement(element) || isCharsetSpecifyingNode(element);
}
static const QualifiedName& frameOwnerURLAttributeName(const HTMLFrameOwnerElement& frameOwner)
{
// FIXME: We should support all frame owners including applets.
- return frameOwner.hasTagName(HTMLNames::objectTag) ? HTMLNames::dataAttr : HTMLNames::srcAttr;
+ return isHTMLObjectElement(frameOwner) ? HTMLNames::dataAttr : HTMLNames::srcAttr;
}
-class SerializerMarkupAccumulator : public WebCore::MarkupAccumulator {
+class SerializerMarkupAccumulator FINAL : public MarkupAccumulator {
public:
- SerializerMarkupAccumulator(PageSerializer*, Document*, Vector<Node*>*);
+ SerializerMarkupAccumulator(PageSerializer*, const Document&, WillBeHeapVector<RawPtrWillBeMember<Node> >*);
virtual ~SerializerMarkupAccumulator();
protected:
- virtual void appendText(StringBuilder& out, Text*);
- virtual void appendElement(StringBuilder& out, Element*, Namespaces*);
- virtual void appendCustomAttributes(StringBuilder& out, Element*, Namespaces*);
- virtual void appendEndTag(Node*);
+ virtual void appendText(StringBuilder& out, Text&) OVERRIDE;
+ virtual void appendElement(StringBuilder& out, Element&, Namespaces*) OVERRIDE;
+ virtual void appendCustomAttributes(StringBuilder& out, const Element&, Namespaces*) OVERRIDE;
+ virtual void appendEndTag(const Node&) OVERRIDE;
private:
PageSerializer* m_serializer;
- Document* m_document;
+ const Document& m_document;
};
-SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* serializer, Document* document, Vector<Node*>* nodes)
- : MarkupAccumulator(nodes, ResolveAllURLs)
+SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* serializer, const Document& document, WillBeHeapVector<RawPtrWillBeMember<Node> >* nodes)
+ : MarkupAccumulator(nodes, ResolveAllURLs, nullptr)
, m_serializer(serializer)
, m_document(document)
{
@@ -126,49 +126,50 @@ SerializerMarkupAccumulator::~SerializerMarkupAccumulator()
{
}
-void SerializerMarkupAccumulator::appendText(StringBuilder& out, Text* text)
+void SerializerMarkupAccumulator::appendText(StringBuilder& out, Text& text)
{
- Element* parent = text->parentElement();
- if (parent && !shouldIgnoreElement(parent))
+ Element* parent = text.parentElement();
+ if (parent && !shouldIgnoreElement(*parent))
MarkupAccumulator::appendText(out, text);
}
-void SerializerMarkupAccumulator::appendElement(StringBuilder& out, Element* element, Namespaces* namespaces)
+void SerializerMarkupAccumulator::appendElement(StringBuilder& out, Element& element, Namespaces* namespaces)
{
if (!shouldIgnoreElement(element))
MarkupAccumulator::appendElement(out, element, namespaces);
- if (element->hasTagName(HTMLNames::headTag)) {
+ if (isHTMLHeadElement(element)) {
out.append("<meta charset=\"");
- out.append(m_document->charset());
+ out.append(m_document.charset());
out.append("\">");
}
// FIXME: For object (plugins) tags and video tag we could replace them by an image of their current contents.
}
-void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, Element* element, Namespaces* namespaces)
+void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, const Element& element, Namespaces* namespaces)
{
- if (!element->isFrameOwnerElement())
+ if (!element.isFrameOwnerElement())
return;
- HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(element);
- Frame* frame = frameOwner->contentFrame();
- if (!frame)
+ const HTMLFrameOwnerElement& frameOwner = toHTMLFrameOwnerElement(element);
+ Frame* frame = frameOwner.contentFrame();
+ // FIXME: RemoteFrames not currently supported here.
+ if (!frame || !frame->isLocalFrame())
return;
- KURL url = frame->document()->url();
- if (url.isValid() && !url.isBlankURL())
+ KURL url = toLocalFrame(frame)->document()->url();
+ if (url.isValid() && !url.protocolIsAbout())
return;
// We need to give a fake location to blank frames so they can be referenced by the serialized frame.
- url = m_serializer->urlForBlankFrame(frame);
- appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(*frameOwner), url.string()), namespaces);
+ url = m_serializer->urlForBlankFrame(toLocalFrame(frame));
+ appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(frameOwner), AtomicString(url.string())), namespaces);
}
-void SerializerMarkupAccumulator::appendEndTag(Node* node)
+void SerializerMarkupAccumulator::appendEndTag(const Node& node)
{
- if (node->isElementNode() && !shouldIgnoreElement(toElement(node)))
+ if (node.isElementNode() && !shouldIgnoreElement(toElement(node)))
MarkupAccumulator::appendEndTag(node);
}
@@ -180,14 +181,16 @@ PageSerializer::PageSerializer(Vector<SerializedResource>* resources)
void PageSerializer::serialize(Page* page)
{
- serializeFrame(page->mainFrame());
+ serializeFrame(page->deprecatedLocalMainFrame());
}
-void PageSerializer::serializeFrame(Frame* frame)
+void PageSerializer::serializeFrame(LocalFrame* frame)
{
- Document* document = frame->document();
- KURL url = document->url();
- if (!url.isValid() || url.isBlankURL()) {
+ ASSERT(frame->document());
+ Document& document = *frame->document();
+ KURL url = document.url();
+ // FIXME: This probably wants isAboutBlankURL? to exclude other about: urls (like about:srcdoc)?
+ if (!url.isValid() || url.protocolIsAbout()) {
// For blank frames we generate a fake URL so they can be referenced by their containing frame.
url = urlForBlankFrame(frame);
}
@@ -199,88 +202,93 @@ void PageSerializer::serializeFrame(Frame* frame)
return;
}
- Vector<Node*> nodes;
- SerializerMarkupAccumulator accumulator(this, document, &nodes);
- WTF::TextEncoding textEncoding(document->charset());
- CString data;
+ WTF::TextEncoding textEncoding(document.charset());
if (!textEncoding.isValid()) {
// FIXME: iframes used as images trigger this. We should deal with them correctly.
return;
}
+
+ WillBeHeapVector<RawPtrWillBeMember<Node> > serializedNodes;
+ SerializerMarkupAccumulator accumulator(this, document, &serializedNodes);
String text = accumulator.serializeNodes(document, IncludeNode);
CString frameHTML = textEncoding.normalizeAndEncode(text, WTF::EntitiesForUnencodables);
- m_resources->append(SerializedResource(url, document->suggestedMIMEType(), SharedBuffer::create(frameHTML.data(), frameHTML.length())));
+ m_resources->append(SerializedResource(url, document.suggestedMIMEType(), SharedBuffer::create(frameHTML.data(), frameHTML.length())));
m_resourceURLs.add(url);
- for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) {
- Node* node = *iter;
- if (!node->isElementNode())
+ for (WillBeHeapVector<RawPtrWillBeMember<Node> >::iterator iter = serializedNodes.begin(); iter != serializedNodes.end(); ++iter) {
+ ASSERT(*iter);
+ Node& node = **iter;
+ if (!node.isElementNode())
continue;
- Element* element = toElement(node);
+ Element& element = toElement(node);
// We have to process in-line style as it might contain some resources (typically background images).
- if (element->isStyledElement())
- retrieveResourcesForProperties(element->inlineStyle(), document);
-
- if (element->hasTagName(HTMLNames::imgTag)) {
- HTMLImageElement* imageElement = toHTMLImageElement(element);
- KURL url = document->completeURL(imageElement->getAttribute(HTMLNames::srcAttr));
- ImageResource* cachedImage = imageElement->cachedImage();
- addImageToResources(cachedImage, imageElement->renderer(), url);
- } else if (element->hasTagName(HTMLNames::inputTag)) {
- HTMLInputElement* inputElement = toHTMLInputElement(element);
- if (inputElement->isImageButton() && inputElement->hasImageLoader()) {
- KURL url = inputElement->src();
- ImageResource* cachedImage = inputElement->imageLoader()->image();
- addImageToResources(cachedImage, inputElement->renderer(), url);
+ if (element.isStyledElement())
+ retrieveResourcesForProperties(element.inlineStyle(), document);
+
+ if (isHTMLImageElement(element)) {
+ HTMLImageElement& imageElement = toHTMLImageElement(element);
+ KURL url = document.completeURL(imageElement.getAttribute(HTMLNames::srcAttr));
+ ImageResource* cachedImage = imageElement.cachedImage();
+ addImageToResources(cachedImage, imageElement.renderer(), url);
+ } else if (isHTMLInputElement(element)) {
+ HTMLInputElement& inputElement = toHTMLInputElement(element);
+ if (inputElement.isImageButton() && inputElement.hasImageLoader()) {
+ KURL url = inputElement.src();
+ ImageResource* cachedImage = inputElement.imageLoader()->image();
+ addImageToResources(cachedImage, inputElement.renderer(), url);
}
- } else if (element->hasTagName(HTMLNames::linkTag)) {
- HTMLLinkElement* linkElement = toHTMLLinkElement(element);
- if (CSSStyleSheet* sheet = linkElement->sheet()) {
- KURL url = document->completeURL(linkElement->getAttribute(HTMLNames::hrefAttr));
- serializeCSSStyleSheet(sheet, url);
+ } else if (isHTMLLinkElement(element)) {
+ HTMLLinkElement& linkElement = toHTMLLinkElement(element);
+ if (CSSStyleSheet* sheet = linkElement.sheet()) {
+ KURL url = document.completeURL(linkElement.getAttribute(HTMLNames::hrefAttr));
+ serializeCSSStyleSheet(*sheet, url);
ASSERT(m_resourceURLs.contains(url));
}
- } else if (element->hasTagName(HTMLNames::styleTag)) {
- HTMLStyleElement* styleElement = toHTMLStyleElement(element);
- if (CSSStyleSheet* sheet = styleElement->sheet())
- serializeCSSStyleSheet(sheet, KURL());
+ } else if (isHTMLStyleElement(element)) {
+ HTMLStyleElement& styleElement = toHTMLStyleElement(element);
+ if (CSSStyleSheet* sheet = styleElement.sheet())
+ serializeCSSStyleSheet(*sheet, KURL());
}
}
- for (Frame* childFrame = frame->tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling())
- serializeFrame(childFrame);
+ for (Frame* childFrame = frame->tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling()) {
+ if (childFrame->isLocalFrame())
+ serializeFrame(toLocalFrame(childFrame));
+ }
}
-void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const KURL& url)
+void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet& styleSheet, const KURL& url)
{
StringBuilder cssText;
- for (unsigned i = 0; i < styleSheet->length(); ++i) {
- CSSRule* rule = styleSheet->item(i);
+ for (unsigned i = 0; i < styleSheet.length(); ++i) {
+ CSSRule* rule = styleSheet.item(i);
String itemText = rule->cssText();
if (!itemText.isEmpty()) {
cssText.append(itemText);
- if (i < styleSheet->length() - 1)
+ if (i < styleSheet.length() - 1)
cssText.append("\n\n");
}
- Document* document = styleSheet->ownerDocument();
+ ASSERT(styleSheet.ownerDocument());
+ Document& document = *styleSheet.ownerDocument();
// Some rules have resources associated with them that we need to retrieve.
if (rule->type() == CSSRule::IMPORT_RULE) {
CSSImportRule* importRule = toCSSImportRule(rule);
- KURL importURL = document->completeURL(importRule->href());
+ KURL importURL = document.completeURL(importRule->href());
if (m_resourceURLs.contains(importURL))
continue;
- serializeCSSStyleSheet(importRule->styleSheet(), importURL);
+ if (importRule->styleSheet())
+ serializeCSSStyleSheet(*importRule->styleSheet(), importURL);
} else if (rule->type() == CSSRule::FONT_FACE_RULE) {
- retrieveResourcesForProperties(toCSSFontFaceRule(rule)->styleRule()->properties(), document);
+ retrieveResourcesForProperties(&toCSSFontFaceRule(rule)->styleRule()->properties(), document);
} else if (rule->type() == CSSRule::STYLE_RULE) {
- retrieveResourcesForProperties(toCSSStyleRule(rule)->styleRule()->properties(), document);
+ retrieveResourcesForProperties(&toCSSStyleRule(rule)->styleRule()->properties(), document);
}
}
if (url.isValid() && !m_resourceURLs.contains(url)) {
// FIXME: We should check whether a charset has been specified and if none was found add one.
- WTF::TextEncoding textEncoding(styleSheet->contents()->charset());
+ WTF::TextEncoding textEncoding(styleSheet.contents()->charset());
ASSERT(textEncoding.isValid());
String textString = cssText.toString();
CString text = textEncoding.normalizeAndEncode(textString, WTF::EntitiesForUnencodables);
@@ -311,7 +319,7 @@ void PageSerializer::addImageToResources(ImageResource* image, RenderObject* ima
if (!shouldAddURL(url))
return;
- if (!image || image->image() == Image::nullImage())
+ if (!image || image->image() == Image::nullImage() || image->errorOccurred())
return;
RefPtr<SharedBuffer> data = imageRenderer ? image->imageForRenderer(imageRenderer)->data() : 0;
@@ -331,7 +339,7 @@ void PageSerializer::addFontToResources(FontResource* font)
addToResources(font, data, font->url());
}
-void PageSerializer::retrieveResourcesForProperties(const StylePropertySet* styleDeclaration, Document* document)
+void PageSerializer::retrieveResourcesForProperties(const StylePropertySet* styleDeclaration, Document& document)
{
if (!styleDeclaration)
return;
@@ -341,12 +349,12 @@ void PageSerializer::retrieveResourcesForProperties(const StylePropertySet* styl
// image properties there might be.
unsigned propertyCount = styleDeclaration->propertyCount();
for (unsigned i = 0; i < propertyCount; ++i) {
- RefPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value();
+ RefPtrWillBeRawPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value();
retrieveResourcesForCSSValue(cssValue.get(), document);
}
}
-void PageSerializer::retrieveResourcesForCSSValue(CSSValue* cssValue, Document* document)
+void PageSerializer::retrieveResourcesForCSSValue(CSSValue* cssValue, Document& document)
{
if (cssValue->isImageValue()) {
CSSImageValue* imageValue = toCSSImageValue(cssValue);
@@ -362,7 +370,7 @@ void PageSerializer::retrieveResourcesForCSSValue(CSSValue* cssValue, Document*
return;
}
- addFontToResources(fontFaceSrcValue->fetch(document));
+ addFontToResources(fontFaceSrcValue->fetch(&document));
} else if (cssValue->isValueList()) {
CSSValueList* cssValueList = toCSSValueList(cssValue);
for (unsigned i = 0; i < cssValueList->length(); i++)
@@ -370,9 +378,9 @@ void PageSerializer::retrieveResourcesForCSSValue(CSSValue* cssValue, Document*
}
}
-KURL PageSerializer::urlForBlankFrame(Frame* frame)
+KURL PageSerializer::urlForBlankFrame(LocalFrame* frame)
{
- HashMap<Frame*, KURL>::iterator iter = m_blankFrameURLs.find(frame);
+ HashMap<LocalFrame*, KURL>::iterator iter = m_blankFrameURLs.find(frame);
if (iter != m_blankFrameURLs.end())
return iter->value;
String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++);
diff --git a/chromium/third_party/WebKit/Source/core/page/PageSerializer.h b/chromium/third_party/WebKit/Source/core/page/PageSerializer.h
index 745af7e72d2..866a182baf4 100644
--- a/chromium/third_party/WebKit/Source/core/page/PageSerializer.h
+++ b/chromium/third_party/WebKit/Source/core/page/PageSerializer.h
@@ -44,7 +44,7 @@ class ImageResource;
class CSSStyleSheet;
class CSSValue;
class Document;
-class Frame;
+class LocalFrame;
class Page;
class RenderObject;
class Resource;
@@ -66,14 +66,14 @@ public:
// vector is the top frame serialized content.
void serialize(Page*);
- KURL urlForBlankFrame(Frame*);
+ KURL urlForBlankFrame(LocalFrame*);
private:
- void serializeFrame(Frame*);
+ void serializeFrame(LocalFrame*);
// Serializes the stylesheet back to text and adds it to the resources if URL is not-empty.
// It also adds any resources included in that stylesheet (including any imported stylesheets and their own resources).
- void serializeCSSStyleSheet(CSSStyleSheet*, const KURL&);
+ void serializeCSSStyleSheet(CSSStyleSheet&, const KURL&);
bool shouldAddURL(const KURL&);
@@ -81,12 +81,12 @@ private:
void addImageToResources(ImageResource*, RenderObject*, const KURL&);
void addFontToResources(FontResource*);
- void retrieveResourcesForProperties(const StylePropertySet*, Document*);
- void retrieveResourcesForCSSValue(CSSValue*, Document*);
+ void retrieveResourcesForProperties(const StylePropertySet*, Document&);
+ void retrieveResourcesForCSSValue(CSSValue*, Document&);
Vector<SerializedResource>* m_resources;
ListHashSet<KURL> m_resourceURLs;
- HashMap<Frame*, KURL> m_blankFrameURLs;
+ HashMap<LocalFrame*, KURL> m_blankFrameURLs;
unsigned m_blankFrameCounter;
};
diff --git a/chromium/third_party/WebKit/Source/core/page/PointerLockController.cpp b/chromium/third_party/WebKit/Source/core/page/PointerLockController.cpp
index d83f7b4dc95..591f86419f8 100644
--- a/chromium/third_party/WebKit/Source/core/page/PointerLockController.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/PointerLockController.cpp
@@ -27,7 +27,7 @@
#include "core/dom/Element.h"
#include "core/events/Event.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
#include "core/page/Page.h"
@@ -37,17 +37,19 @@ namespace WebCore {
PointerLockController::PointerLockController(Page* page)
: m_page(page)
+ , m_lockPending(false)
{
}
-PassOwnPtr<PointerLockController> PointerLockController::create(Page* page)
+PassOwnPtrWillBeRawPtr<PointerLockController> PointerLockController::create(Page* page)
{
- return adoptPtr(new PointerLockController(page));
+ return adoptPtrWillBeNoop(new PointerLockController(page));
}
void PointerLockController::requestPointerLock(Element* target)
{
if (!target || !target->inDocument() || m_documentOfRemovedElementWhileWaitingForUnlock) {
+ enqueueEvent(EventTypeNames::pointerlockerror, target);
enqueueEvent(EventTypeNames::webkitpointerlockerror, target);
return;
}
@@ -55,21 +57,25 @@ void PointerLockController::requestPointerLock(Element* target)
if (target->document().isSandboxed(SandboxPointerLock)) {
// FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
target->document().addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked pointer lock on an element because the element's frame is sandboxed and the 'allow-pointer-lock' permission is not set.");
+ enqueueEvent(EventTypeNames::pointerlockerror, target);
enqueueEvent(EventTypeNames::webkitpointerlockerror, target);
return;
}
if (m_element) {
if (m_element->document() != target->document()) {
+ enqueueEvent(EventTypeNames::pointerlockerror, target);
enqueueEvent(EventTypeNames::webkitpointerlockerror, target);
return;
}
+ enqueueEvent(EventTypeNames::pointerlockchange, target);
enqueueEvent(EventTypeNames::webkitpointerlockchange, target);
m_element = target;
} else if (m_page->chrome().client().requestPointerLock()) {
m_lockPending = true;
m_element = target;
} else {
+ enqueueEvent(EventTypeNames::pointerlockerror, target);
enqueueEvent(EventTypeNames::webkitpointerlockerror, target);
}
}
@@ -110,21 +116,24 @@ Element* PointerLockController::element() const
void PointerLockController::didAcquirePointerLock()
{
+ enqueueEvent(EventTypeNames::pointerlockchange, m_element.get());
enqueueEvent(EventTypeNames::webkitpointerlockchange, m_element.get());
m_lockPending = false;
}
void PointerLockController::didNotAcquirePointerLock()
{
+ enqueueEvent(EventTypeNames::pointerlockerror, m_element.get());
enqueueEvent(EventTypeNames::webkitpointerlockerror, m_element.get());
clearElement();
}
void PointerLockController::didLosePointerLock()
{
+ enqueueEvent(EventTypeNames::pointerlockchange, m_element ? &m_element->document() : m_documentOfRemovedElementWhileWaitingForUnlock.get());
enqueueEvent(EventTypeNames::webkitpointerlockchange, m_element ? &m_element->document() : m_documentOfRemovedElementWhileWaitingForUnlock.get());
clearElement();
- m_documentOfRemovedElementWhileWaitingForUnlock = 0;
+ m_documentOfRemovedElementWhileWaitingForUnlock = nullptr;
}
void PointerLockController::dispatchLockedMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType)
@@ -142,7 +151,7 @@ void PointerLockController::dispatchLockedMouseEvent(const PlatformMouseEvent& e
void PointerLockController::clearElement()
{
m_lockPending = false;
- m_element = 0;
+ m_element = nullptr;
}
void PointerLockController::enqueueEvent(const AtomicString& type, Element* element)
@@ -157,4 +166,11 @@ void PointerLockController::enqueueEvent(const AtomicString& type, Document* doc
document->domWindow()->enqueueDocumentEvent(Event::create(type));
}
+void PointerLockController::trace(Visitor* visitor)
+{
+ visitor->trace(m_page);
+ visitor->trace(m_element);
+ visitor->trace(m_documentOfRemovedElementWhileWaitingForUnlock);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/PointerLockController.h b/chromium/third_party/WebKit/Source/core/page/PointerLockController.h
index 442633f92d2..dd24d638f29 100644
--- a/chromium/third_party/WebKit/Source/core/page/PointerLockController.h
+++ b/chromium/third_party/WebKit/Source/core/page/PointerLockController.h
@@ -25,6 +25,7 @@
#ifndef PointerLockController_h
#define PointerLockController_h
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
#include "wtf/text/AtomicString.h"
@@ -36,11 +37,11 @@ class Page;
class PlatformMouseEvent;
class VoidCallback;
-class PointerLockController {
+class PointerLockController FINAL : public NoBaseWillBeGarbageCollected<PointerLockController> {
WTF_MAKE_NONCOPYABLE(PointerLockController);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<PointerLockController> create(Page*);
+ static PassOwnPtrWillBeRawPtr<PointerLockController> create(Page*);
void requestPointerLock(Element* target);
void requestPointerUnlock();
@@ -54,15 +55,18 @@ public:
void didLosePointerLock();
void dispatchLockedMouseEvent(const PlatformMouseEvent&, const AtomicString& eventType);
+ void trace(Visitor*);
+
private:
explicit PointerLockController(Page*);
void clearElement();
void enqueueEvent(const AtomicString& type, Element*);
void enqueueEvent(const AtomicString& type, Document*);
- Page* m_page;
+
+ RawPtrWillBeMember<Page> m_page;
bool m_lockPending;
- RefPtr<Element> m_element;
- RefPtr<Document> m_documentOfRemovedElementWhileWaitingForUnlock;
+ RefPtrWillBeMember<Element> m_element;
+ RefPtrWillBeMember<Document> m_documentOfRemovedElementWhileWaitingForUnlock;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/PrintContext.cpp b/chromium/third_party/WebKit/Source/core/page/PrintContext.cpp
index 61a4f8adfd8..9ce40857b67 100644
--- a/chromium/third_party/WebKit/Source/core/page/PrintContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/PrintContext.cpp
@@ -21,8 +21,8 @@
#include "config.h"
#include "core/page/PrintContext.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/RenderView.h"
#include "platform/graphics/GraphicsContext.h"
@@ -41,7 +41,7 @@ const float printingMinimumShrinkFactor = 1.25f;
// behavior matches MacIE and Mozilla, at least)
const float printingMaximumShrinkFactor = 2;
-PrintContext::PrintContext(Frame* frame)
+PrintContext::PrintContext(LocalFrame* frame)
: m_frame(frame)
, m_isPrinting(false)
, m_linkedDestinationsValid(false)
@@ -168,25 +168,7 @@ void PrintContext::begin(float width, float height)
FloatSize minLayoutSize = m_frame->resizePageRectsKeepingRatio(originalPageSize, FloatSize(width * printingMinimumShrinkFactor, height * printingMinimumShrinkFactor));
// This changes layout, so callers need to make sure that they don't paint to screen while in printing mode.
- m_frame->setPrinting(true, minLayoutSize, originalPageSize, printingMaximumShrinkFactor / printingMinimumShrinkFactor, AdjustViewSize);
-}
-
-float PrintContext::computeAutomaticScaleFactor(const FloatSize& availablePaperSize)
-{
- if (!m_frame->view())
- return 1;
-
- bool useViewWidth = true;
- if (m_frame->document() && m_frame->document()->renderView())
- useViewWidth = m_frame->document()->renderView()->style()->isHorizontalWritingMode();
-
- float viewLogicalWidth = useViewWidth ? m_frame->view()->contentsWidth() : m_frame->view()->contentsHeight();
- if (viewLogicalWidth < 1)
- return 1;
-
- float maxShrinkToFitScaleFactor = 1 / printingMaximumShrinkFactor;
- float shrinkToFitScaleFactor = (useViewWidth ? availablePaperSize.width() : availablePaperSize.height()) / viewLogicalWidth;
- return max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor);
+ m_frame->setPrinting(true, minLayoutSize, originalPageSize, printingMaximumShrinkFactor / printingMinimumShrinkFactor);
}
void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
@@ -196,7 +178,7 @@ void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
float scale = width / pageRect.width();
ctx.save();
- ctx.scale(FloatSize(scale, scale));
+ ctx.scale(scale, scale);
ctx.translate(-pageRect.x(), -pageRect.y());
ctx.clip(pageRect);
m_frame->view()->paintContents(&ctx, pageRect);
@@ -205,21 +187,11 @@ void PrintContext::spoolPage(GraphicsContext& ctx, int pageNumber, float width)
ctx.restore();
}
-void PrintContext::spoolRect(GraphicsContext& ctx, const IntRect& rect)
-{
- // FIXME: Not correct for vertical text.
- ctx.save();
- ctx.translate(-rect.x(), -rect.y());
- ctx.clip(rect);
- m_frame->view()->paintContents(&ctx, rect);
- ctx.restore();
-}
-
void PrintContext::end()
{
ASSERT(m_isPrinting);
m_isPrinting = false;
- m_frame->setPrinting(false, FloatSize(), FloatSize(), 0, AdjustViewSize);
+ m_frame->setPrinting(false, FloatSize(), FloatSize(), 0);
m_linkedDestinations.clear();
m_linkedDestinationsValid = false;
}
@@ -237,14 +209,14 @@ static RenderBoxModelObject* enclosingBoxModelObject(RenderObject* object)
int PrintContext::pageNumberForElement(Element* element, const FloatSize& pageSizeInPixels)
{
// Make sure the element is not freed during the layout.
- RefPtr<Element> elementRef(element);
+ RefPtrWillBeRawPtr<Element> protect(element);
element->document().updateLayout();
RenderBoxModelObject* box = enclosingBoxModelObject(element->renderer());
if (!box)
return -1;
- Frame* frame = element->document().frame();
+ LocalFrame* frame = element->document().frame();
FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
PrintContext printContext(frame);
printContext.begin(pageRect.width(), pageRect.height());
@@ -305,7 +277,7 @@ void PrintContext::outputLinkedDestinations(GraphicsContext& graphicsContext, No
}
}
-String PrintContext::pageProperty(Frame* frame, const char* propertyName, int pageNumber)
+String PrintContext::pageProperty(LocalFrame* frame, const char* propertyName, int pageNumber)
{
Document* document = frame->document();
PrintContext printContext(frame);
@@ -331,12 +303,12 @@ String PrintContext::pageProperty(Frame* frame, const char* propertyName, int pa
return String("pageProperty() unimplemented for: ") + propertyName;
}
-bool PrintContext::isPageBoxVisible(Frame* frame, int pageNumber)
+bool PrintContext::isPageBoxVisible(LocalFrame* frame, int pageNumber)
{
return frame->document()->isPageBoxVisible(pageNumber);
}
-String PrintContext::pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
+String PrintContext::pageSizeAndMarginsInPixels(LocalFrame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
{
IntSize pageSize(width, height);
frame->document()->pageSizeAndMarginsInPixels(pageNumber, pageSize, marginTop, marginRight, marginBottom, marginLeft);
@@ -345,7 +317,7 @@ String PrintContext::pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, in
String::number(marginTop) + ' ' + String::number(marginRight) + ' ' + String::number(marginBottom) + ' ' + String::number(marginLeft);
}
-int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels)
+int PrintContext::numberOfPages(LocalFrame* frame, const FloatSize& pageSizeInPixels)
{
frame->document()->updateLayout();
@@ -359,9 +331,9 @@ int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels)
return printContext.pageCount();
}
-void PrintContext::spoolAllPagesWithBoundaries(Frame* frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
+void PrintContext::spoolAllPagesWithBoundaries(LocalFrame* frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
{
- if (!frame->document() || !frame->view() || !frame->document()->renderer())
+ if (!frame->document() || !frame->view() || !frame->document()->renderView())
return;
frame->document()->updateLayout();
@@ -382,7 +354,7 @@ void PrintContext::spoolAllPagesWithBoundaries(Frame* frame, GraphicsContext& gr
graphicsContext.save();
graphicsContext.translate(0, totalHeight);
- graphicsContext.scale(FloatSize(1, -1));
+ graphicsContext.scale(1, -1);
int currentHeight = 0;
for (size_t pageIndex = 0; pageIndex < pageRects.size(); pageIndex++) {
diff --git a/chromium/third_party/WebKit/Source/core/page/PrintContext.h b/chromium/third_party/WebKit/Source/core/page/PrintContext.h
index d71a4433025..6c99875598b 100644
--- a/chromium/third_party/WebKit/Source/core/page/PrintContext.h
+++ b/chromium/third_party/WebKit/Source/core/page/PrintContext.h
@@ -29,7 +29,7 @@
namespace WebCore {
class Element;
-class Frame;
+class LocalFrame;
class FloatRect;
class FloatSize;
class GraphicsContext;
@@ -38,10 +38,10 @@ class Node;
class PrintContext {
public:
- explicit PrintContext(Frame*);
+ explicit PrintContext(LocalFrame*);
~PrintContext();
- Frame* frame() const { return m_frame; }
+ LocalFrame* frame() const { return m_frame; }
// Break up a page into rects without relayout.
// FIXME: This means that CSS page breaks won't be on page boundary if the size is different than what was passed to begin(). That's probably not always desirable.
@@ -57,8 +57,6 @@ public:
const IntRect& pageRect(size_t pageNumber) const { return m_pageRects[pageNumber]; }
const Vector<IntRect>& pageRects() const { return m_pageRects; }
- float computeAutomaticScaleFactor(const FloatSize& availablePaperSize);
-
// Enter print mode, updating layout for new page size.
// This function can be called multiple times to apply new print options without going back to screen mode.
void begin(float width, float height = 0);
@@ -66,26 +64,24 @@ public:
// FIXME: eliminate width argument.
void spoolPage(GraphicsContext& ctx, int pageNumber, float width);
- void spoolRect(GraphicsContext& ctx, const IntRect&);
-
// Return to screen mode.
void end();
// Used by layout tests.
static int pageNumberForElement(Element*, const FloatSize& pageSizeInPixels); // Returns -1 if page isn't found.
- static String pageProperty(Frame* frame, const char* propertyName, int pageNumber);
- static bool isPageBoxVisible(Frame* frame, int pageNumber);
- static String pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft);
- static int numberOfPages(Frame*, const FloatSize& pageSizeInPixels);
+ static String pageProperty(LocalFrame* frame, const char* propertyName, int pageNumber);
+ static bool isPageBoxVisible(LocalFrame* frame, int pageNumber);
+ static String pageSizeAndMarginsInPixels(LocalFrame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft);
+ static int numberOfPages(LocalFrame*, const FloatSize& pageSizeInPixels);
// Draw all pages into a graphics context with lines which mean page boundaries.
// The height of the graphics context should be
// (pageSizeInPixels.height() + 1) * number-of-pages - 1
- static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels);
+ static void spoolAllPagesWithBoundaries(LocalFrame*, GraphicsContext&, const FloatSize& pageSizeInPixels);
protected:
void outputLinkedDestinations(GraphicsContext&, Node*, const IntRect& pageRect);
- Frame* m_frame;
+ LocalFrame* m_frame;
Vector<IntRect> m_pageRects;
private:
diff --git a/chromium/third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp b/chromium/third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp
new file mode 100644
index 00000000000..9ee79b638c1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/page/ScopedPageLoadDeferrer.h"
+
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/loader/FrameLoader.h"
+#include "core/page/Page.h"
+#include "wtf/HashSet.h"
+
+namespace WebCore {
+
+ScopedPageLoadDeferrer::ScopedPageLoadDeferrer(Page* exclusion)
+{
+ const HashSet<Page*>& pages = Page::ordinaryPages();
+
+ HashSet<Page*>::const_iterator end = pages.end();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
+ Page* page = *it;
+ if (page == exclusion || page->defersLoading())
+ continue;
+
+ if (page->mainFrame()->isLocalFrame()) {
+ m_deferredFrames.append(page->deprecatedLocalMainFrame());
+
+ // Ensure that we notify the client if the initial empty document is accessed before
+ // showing anything modal, to prevent spoofs while the modal window or sheet is visible.
+ page->deprecatedLocalMainFrame()->loader().notifyIfInitialDocumentAccessed();
+ }
+
+ // This code is not logically part of load deferring, but we do not want JS code executed
+ // beneath modal windows or sheets, which is exactly when ScopedPageLoadDeferrer is used.
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->suspendScheduledTasks();
+ }
+ }
+
+ size_t count = m_deferredFrames.size();
+ for (size_t i = 0; i < count; ++i) {
+ if (Page* page = m_deferredFrames[i]->page())
+ page->setDefersLoading(true);
+ }
+}
+
+ScopedPageLoadDeferrer::~ScopedPageLoadDeferrer()
+{
+ for (size_t i = 0; i < m_deferredFrames.size(); ++i) {
+ if (Page* page = m_deferredFrames[i]->page()) {
+ page->setDefersLoading(false);
+
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ if (frame->isLocalFrame())
+ toLocalFrame(frame)->document()->resumeScheduledTasks();
+ }
+ }
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.h b/chromium/third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.h
new file mode 100644
index 00000000000..3ec0f475bb0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef ScopedPageLoadDeferrer_h
+#define ScopedPageLoadDeferrer_h
+
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class LocalFrame;
+class Page;
+
+class ScopedPageLoadDeferrer {
+ WTF_MAKE_NONCOPYABLE(ScopedPageLoadDeferrer);
+public:
+ ScopedPageLoadDeferrer(Page* exclusion = 0);
+ ~ScopedPageLoadDeferrer();
+
+private:
+ Vector<RefPtr<LocalFrame>, 16> m_deferredFrames;
+};
+
+} // namespace WebCore
+
+#endif // ScopedPageLoadDeferrer_h
diff --git a/chromium/third_party/WebKit/Source/core/page/Selection.idl b/chromium/third_party/WebKit/Source/core/page/Selection.idl
index 8f03f8e45d3..53b0826171b 100644
--- a/chromium/third_party/WebKit/Source/core/page/Selection.idl
+++ b/chromium/third_party/WebKit/Source/core/page/Selection.idl
@@ -30,6 +30,7 @@
// This is based off of Mozilla's Selection interface
// https://developer.mozilla.org/En/DOM/Selection
[
+ WillBeGarbageCollected,
ImplementedAs=DOMSelection
] interface Selection {
readonly attribute Node anchorNode;
@@ -40,8 +41,8 @@
readonly attribute boolean isCollapsed;
readonly attribute long rangeCount;
- [RaisesException] void collapse([Default=Undefined] optional Node node,
- [Default=Undefined] optional long index);
+ [RaisesException, TypeChecking=Interface|Nullable] void collapse(Node node,
+ optional long offset);
[RaisesException] void collapseToEnd();
[RaisesException] void collapseToStart();
@@ -60,27 +61,27 @@
[NotEnumerable] DOMString toString();
// WebKit extensions
- readonly attribute Node baseNode;
- readonly attribute long baseOffset;
- readonly attribute Node extentNode;
- readonly attribute long extentOffset;
+ [MeasureAs=SelectionBaseNode] readonly attribute Node baseNode;
+ [MeasureAs=SelectionBaseOffset] readonly attribute long baseOffset;
+ [MeasureAs=SelectionExtentNode] readonly attribute Node extentNode;
+ [MeasureAs=SelectionExtentOffset] readonly attribute long extentOffset;
// WebKit's "type" accessor returns "None", "Range" and "Caret"
// IE's type accessor returns "none", "text" and "control"
- readonly attribute DOMString type;
+ [MeasureAs=SelectionType] readonly attribute DOMString type;
- void modify([Default=Undefined] optional DOMString alter,
- [Default=Undefined] optional DOMString direction,
- [Default=Undefined] optional DOMString granularity);
- [RaisesException] void setBaseAndExtent([Default=Undefined] optional Node baseNode,
- [Default=Undefined] optional long baseOffset,
- [Default=Undefined] optional Node extentNode,
- [Default=Undefined] optional long extentOffset);
- [RaisesException] void setPosition([Default=Undefined] optional Node node,
- [Default=Undefined] optional long offset);
+ [MeasureAs=SelectionModify] void modify([Default=Undefined] optional DOMString alter,
+ [Default=Undefined] optional DOMString direction,
+ [Default=Undefined] optional DOMString granularity);
+ [MeasureAs=SelectionSetBaseAndExtent, RaisesException] void setBaseAndExtent([Default=Undefined] optional Node baseNode,
+ [Default=Undefined] optional long baseOffset,
+ [Default=Undefined] optional Node extentNode,
+ [Default=Undefined] optional long extentOffset);
+ [ImplementedAs=collapse, MeasureAs=SelectionSetPosition, RaisesException, TypeChecking=Interface|Nullable] void setPosition(Node node,
+ optional long offset);
// IE extentions
// http://msdn.microsoft.com/en-us/library/ms535869(VS.85).aspx
- void empty();
+ [MeasureAs=SelectionEmpty] void empty();
};
diff --git a/chromium/third_party/WebKit/Source/core/page/SpatialNavigation.cpp b/chromium/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
index b3c5c869179..60e14b3ebd0 100644
--- a/chromium/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/SpatialNavigation.cpp
@@ -29,30 +29,32 @@
#include "config.h"
#include "core/page/SpatialNavigation.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLAreaElement.h"
+#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLImageElement.h"
-#include "core/frame/Frame.h"
#include "core/page/FrameTree.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
-#include "core/frame/Settings.h"
#include "core/rendering/RenderLayer.h"
#include "platform/geometry/IntRect.h"
namespace WebCore {
-static RectsAlignment alignmentForRects(FocusDirection, const LayoutRect&, const LayoutRect&, const LayoutSize& viewSize);
-static bool areRectsFullyAligned(FocusDirection, const LayoutRect&, const LayoutRect&);
-static bool areRectsPartiallyAligned(FocusDirection, const LayoutRect&, const LayoutRect&);
-static bool areRectsMoreThanFullScreenApart(FocusDirection, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize);
-static bool isRectInDirection(FocusDirection, const LayoutRect&, const LayoutRect&);
+using namespace HTMLNames;
+
+static RectsAlignment alignmentForRects(FocusType, const LayoutRect&, const LayoutRect&, const LayoutSize& viewSize);
+static bool areRectsFullyAligned(FocusType, const LayoutRect&, const LayoutRect&);
+static bool areRectsPartiallyAligned(FocusType, const LayoutRect&, const LayoutRect&);
+static bool areRectsMoreThanFullScreenApart(FocusType, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize);
+static bool isRectInDirection(FocusType, const LayoutRect&, const LayoutRect&);
static void deflateIfOverlapped(LayoutRect&, LayoutRect&);
-static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect&);
-static void entryAndExitPointsForDirection(FocusDirection, const LayoutRect& startingRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryPoint);
+static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const LayoutRect&);
static bool isScrollableNode(const Node*);
-FocusCandidate::FocusCandidate(Node* node, FocusDirection direction)
+FocusCandidate::FocusCandidate(Node* node, FocusType type)
: visibleNode(0)
, focusableNode(0)
, enclosingScrollableBox(0)
@@ -66,14 +68,14 @@ FocusCandidate::FocusCandidate(Node* node, FocusDirection direction)
ASSERT(node);
ASSERT(node->isElementNode());
- if (isHTMLAreaElement(node)) {
- HTMLAreaElement* area = toHTMLAreaElement(node);
- HTMLImageElement* image = area->imageElement();
+ if (isHTMLAreaElement(*node)) {
+ HTMLAreaElement& area = toHTMLAreaElement(*node);
+ HTMLImageElement* image = area.imageElement();
if (!image || !image->renderer())
return;
visibleNode = image;
- rect = virtualRectForAreaElementAndDirection(area, direction);
+ rect = virtualRectForAreaElementAndDirection(area, type);
} else {
if (!node->renderer())
return;
@@ -84,48 +86,48 @@ FocusCandidate::FocusCandidate(Node* node, FocusDirection direction)
focusableNode = node;
isOffscreen = hasOffscreenRect(visibleNode);
- isOffscreenAfterScrolling = hasOffscreenRect(visibleNode, direction);
+ isOffscreenAfterScrolling = hasOffscreenRect(visibleNode, type);
}
-bool isSpatialNavigationEnabled(const Frame* frame)
+bool isSpatialNavigationEnabled(const LocalFrame* frame)
{
return (frame && frame->settings() && frame->settings()->spatialNavigationEnabled());
}
-static RectsAlignment alignmentForRects(FocusDirection direction, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize)
+static RectsAlignment alignmentForRects(FocusType type, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize)
{
// If we found a node in full alignment, but it is too far away, ignore it.
- if (areRectsMoreThanFullScreenApart(direction, curRect, targetRect, viewSize))
+ if (areRectsMoreThanFullScreenApart(type, curRect, targetRect, viewSize))
return None;
- if (areRectsFullyAligned(direction, curRect, targetRect))
+ if (areRectsFullyAligned(type, curRect, targetRect))
return Full;
- if (areRectsPartiallyAligned(direction, curRect, targetRect))
+ if (areRectsPartiallyAligned(type, curRect, targetRect))
return Partial;
return None;
}
-static inline bool isHorizontalMove(FocusDirection direction)
+static inline bool isHorizontalMove(FocusType type)
{
- return direction == FocusDirectionLeft || direction == FocusDirectionRight;
+ return type == FocusTypeLeft || type == FocusTypeRight;
}
-static inline LayoutUnit start(FocusDirection direction, const LayoutRect& rect)
+static inline LayoutUnit start(FocusType type, const LayoutRect& rect)
{
- return isHorizontalMove(direction) ? rect.y() : rect.x();
+ return isHorizontalMove(type) ? rect.y() : rect.x();
}
-static inline LayoutUnit middle(FocusDirection direction, const LayoutRect& rect)
+static inline LayoutUnit middle(FocusType type, const LayoutRect& rect)
{
LayoutPoint center(rect.center());
- return isHorizontalMove(direction) ? center.y(): center.x();
+ return isHorizontalMove(type) ? center.y(): center.x();
}
-static inline LayoutUnit end(FocusDirection direction, const LayoutRect& rect)
+static inline LayoutUnit end(FocusType type, const LayoutRect& rect)
{
- return isHorizontalMove(direction) ? rect.maxY() : rect.maxX();
+ return isHorizontalMove(type) ? rect.maxY() : rect.maxX();
}
// This method checks if rects |a| and |b| are fully aligned either vertically or
@@ -135,24 +137,24 @@ static inline LayoutUnit end(FocusDirection direction, const LayoutRect& rect)
// operations.
// * a = Current focused node's rect.
// * b = Focus candidate node's rect.
-static bool areRectsFullyAligned(FocusDirection direction, const LayoutRect& a, const LayoutRect& b)
+static bool areRectsFullyAligned(FocusType type, const LayoutRect& a, const LayoutRect& b)
{
LayoutUnit aStart, bStart, aEnd, bEnd;
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
aStart = a.x();
- bEnd = b.maxX();
+ bEnd = b.x();
break;
- case FocusDirectionRight:
+ case FocusTypeRight:
aStart = b.x();
- bEnd = a.maxX();
+ bEnd = a.x();
break;
- case FocusDirectionUp:
+ case FocusTypeUp:
aStart = a.y();
bEnd = b.y();
break;
- case FocusDirectionDown:
+ case FocusTypeDown:
aStart = b.y();
bEnd = a.y();
break;
@@ -164,14 +166,14 @@ static bool areRectsFullyAligned(FocusDirection direction, const LayoutRect& a,
if (aStart < bEnd)
return false;
- aStart = start(direction, a);
- bStart = start(direction, b);
+ aStart = start(type, a);
+ bStart = start(type, b);
- LayoutUnit aMiddle = middle(direction, a);
- LayoutUnit bMiddle = middle(direction, b);
+ LayoutUnit aMiddle = middle(type, a);
+ LayoutUnit bMiddle = middle(type, b);
- aEnd = end(direction, a);
- bEnd = end(direction, b);
+ aEnd = end(type, a);
+ bEnd = end(type, b);
// Picture of the totally aligned logic:
//
@@ -186,34 +188,23 @@ static bool areRectsFullyAligned(FocusDirection direction, const LayoutRect& a,
// * * * * * *
// **************************** *****************************
- // Horizontal Vertical Horizontal Vertical
- // **************************** *****************************
- // * _......_ * _ _ _ _ * * _ * _ _ _ _ *
- // * |_| |_| * |_|_|_|_| * * |_| _ * |_|_|_|_| *
- // * |_| |_| * . * * |_| |_| * . *
- // * |_| (3) . * * |_|....|_| (4) . *
- // * * ._ _ * * * _ _. *
- // * * |_|_| * * * |_|_| *
- // * * * * * *
- // **************************** *****************************
-
- return ((bMiddle >= aStart && bMiddle <= aEnd) // (1)
- || (aMiddle >= bStart && aMiddle <= bEnd) // (2)
- || (bStart == aStart) // (3)
- || (bEnd == aEnd)); // (4)
+ return (bMiddle >= aStart && bMiddle <= aEnd) // (1)
+ || (aMiddle >= bStart && aMiddle <= bEnd); // (2)
}
-// This method checks if |start| and |dest| have a partial intersection, either
-// horizontally or vertically.
+// This method checks if rects |a| and |b| are partially aligned either vertically or
+// horizontally. In general, rects whose either of edges falls between the top or
+// bottom of each other are considered partially-aligned.
+// This is a separate set of conditions from "fully-aligned" and do not include cases
+// that satisfy the former.
// * a = Current focused node's rect.
// * b = Focus candidate node's rect.
-static bool areRectsPartiallyAligned(FocusDirection direction, const LayoutRect& a, const LayoutRect& b)
+static bool areRectsPartiallyAligned(FocusType type, const LayoutRect& a, const LayoutRect& b)
{
- LayoutUnit aStart = start(direction, a);
- LayoutUnit bStart = start(direction, b);
- LayoutUnit bMiddle = middle(direction, b);
- LayoutUnit aEnd = end(direction, a);
- LayoutUnit bEnd = end(direction, b);
+ LayoutUnit aStart = start(type, a);
+ LayoutUnit bStart = start(type, b);
+ LayoutUnit aEnd = end(type, a);
+ LayoutUnit bEnd = end(type, b);
// Picture of the partially aligned logic:
//
@@ -230,23 +221,22 @@ static bool areRectsPartiallyAligned(FocusDirection direction, const LayoutRect&
// ********************************
//
// ... and variants of the above cases.
- return ((bStart >= aStart && bStart <= aEnd)
- || (bEnd >= aStart && bEnd <= aEnd)
- || (bMiddle >= aStart && bMiddle <= aEnd));
+ return (bStart >= aStart && bStart <= aEnd)
+ || (bEnd >= aStart && bEnd <= aEnd);
}
-static bool areRectsMoreThanFullScreenApart(FocusDirection direction, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize)
+static bool areRectsMoreThanFullScreenApart(FocusType type, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize)
{
- ASSERT(isRectInDirection(direction, curRect, targetRect));
+ ASSERT(isRectInDirection(type, curRect, targetRect));
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
return curRect.x() - targetRect.maxX() > viewSize.width();
- case FocusDirectionRight:
+ case FocusTypeRight:
return targetRect.x() - curRect.maxX() > viewSize.width();
- case FocusDirectionUp:
+ case FocusTypeUp:
return curRect.y() - targetRect.maxY() > viewSize.height();
- case FocusDirectionDown:
+ case FocusTypeDown:
return targetRect.y() - curRect.maxY() > viewSize.height();
default:
ASSERT_NOT_REACHED();
@@ -255,28 +245,34 @@ static bool areRectsMoreThanFullScreenApart(FocusDirection direction, const Layo
}
// Return true if rect |a| is below |b|. False otherwise.
+// For overlapping rects, |a| is considered to be below |b|
+// if both edges of |a| are below the respective ones of |b|
static inline bool below(const LayoutRect& a, const LayoutRect& b)
{
- return a.y() > b.maxY();
+ return a.y() >= b.maxY()
+ || (a.y() >= b.y() && a.maxY() > b.maxY());
}
// Return true if rect |a| is on the right of |b|. False otherwise.
+// For overlapping rects, |a| is considered to be on the right of |b|
+// if both edges of |a| are on the right of the respective ones of |b|
static inline bool rightOf(const LayoutRect& a, const LayoutRect& b)
{
- return a.x() > b.maxX();
+ return a.x() >= b.maxX()
+ || (a.x() >= b.x() && a.maxX() > b.maxX());
}
-static bool isRectInDirection(FocusDirection direction, const LayoutRect& curRect, const LayoutRect& targetRect)
+static bool isRectInDirection(FocusType type, const LayoutRect& curRect, const LayoutRect& targetRect)
{
- switch (direction) {
- case FocusDirectionLeft:
- return targetRect.maxX() <= curRect.x();
- case FocusDirectionRight:
- return targetRect.x() >= curRect.maxX();
- case FocusDirectionUp:
- return targetRect.maxY() <= curRect.y();
- case FocusDirectionDown:
- return targetRect.y() >= curRect.maxY();
+ switch (type) {
+ case FocusTypeLeft:
+ return rightOf(curRect, targetRect);
+ case FocusTypeRight:
+ return rightOf(targetRect, curRect);
+ case FocusTypeUp:
+ return below(curRect, targetRect);
+ case FocusTypeDown:
+ return below(targetRect, curRect);
default:
ASSERT_NOT_REACHED();
return false;
@@ -286,7 +282,7 @@ static bool isRectInDirection(FocusDirection direction, const LayoutRect& curRec
// Checks if |node| is offscreen the visible area (viewport) of its container
// document. In case it is, one can scroll in direction or take any different
// desired action later on.
-bool hasOffscreenRect(Node* node, FocusDirection direction)
+bool hasOffscreenRect(Node* node, FocusType type)
{
// Get the FrameView in which |node| is (which means the current viewport if |node|
// is not in an inner document), so we can check if its content rect is visible
@@ -302,19 +298,19 @@ bool hasOffscreenRect(Node* node, FocusDirection direction)
// exposed after we scroll. Adjust the viewport to post-scrolling position.
// If the container has overflow:hidden, we cannot scroll, so we do not pass direction
// and we do not adjust for scrolling.
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
containerViewportRect.setX(containerViewportRect.x() - ScrollableArea::pixelsPerLineStep());
containerViewportRect.setWidth(containerViewportRect.width() + ScrollableArea::pixelsPerLineStep());
break;
- case FocusDirectionRight:
+ case FocusTypeRight:
containerViewportRect.setWidth(containerViewportRect.width() + ScrollableArea::pixelsPerLineStep());
break;
- case FocusDirectionUp:
+ case FocusTypeUp:
containerViewportRect.setY(containerViewportRect.y() - ScrollableArea::pixelsPerLineStep());
containerViewportRect.setHeight(containerViewportRect.height() + ScrollableArea::pixelsPerLineStep());
break;
- case FocusDirectionDown:
+ case FocusTypeDown:
containerViewportRect.setHeight(containerViewportRect.height() + ScrollableArea::pixelsPerLineStep());
break;
default:
@@ -332,24 +328,24 @@ bool hasOffscreenRect(Node* node, FocusDirection direction)
return !containerViewportRect.intersects(rect);
}
-bool scrollInDirection(Frame* frame, FocusDirection direction)
+bool scrollInDirection(LocalFrame* frame, FocusType type)
{
ASSERT(frame);
- if (frame && canScrollInDirection(frame->document(), direction)) {
+ if (frame && canScrollInDirection(frame->document(), type)) {
LayoutUnit dx = 0;
LayoutUnit dy = 0;
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
dx = - ScrollableArea::pixelsPerLineStep();
break;
- case FocusDirectionRight:
+ case FocusTypeRight:
dx = ScrollableArea::pixelsPerLineStep();
break;
- case FocusDirectionUp:
+ case FocusTypeUp:
dy = - ScrollableArea::pixelsPerLineStep();
break;
- case FocusDirectionDown:
+ case FocusTypeDown:
dy = ScrollableArea::pixelsPerLineStep();
break;
default:
@@ -363,30 +359,30 @@ bool scrollInDirection(Frame* frame, FocusDirection direction)
return false;
}
-bool scrollInDirection(Node* container, FocusDirection direction)
+bool scrollInDirection(Node* container, FocusType type)
{
ASSERT(container);
if (container->isDocumentNode())
- return scrollInDirection(toDocument(container)->frame(), direction);
+ return scrollInDirection(toDocument(container)->frame(), type);
if (!container->renderBox())
return false;
- if (canScrollInDirection(container, direction)) {
+ if (canScrollInDirection(container, type)) {
LayoutUnit dx = 0;
LayoutUnit dy = 0;
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
dx = - std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), container->renderBox()->scrollLeft());
break;
- case FocusDirectionRight:
+ case FocusTypeRight:
ASSERT(container->renderBox()->scrollWidth() > (container->renderBox()->scrollLeft() + container->renderBox()->clientWidth()));
dx = std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), container->renderBox()->scrollWidth() - (container->renderBox()->scrollLeft() + container->renderBox()->clientWidth()));
break;
- case FocusDirectionUp:
+ case FocusTypeUp:
dy = - std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), container->renderBox()->scrollTop());
break;
- case FocusDirectionDown:
+ case FocusTypeDown:
ASSERT(container->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + container->renderBox()->clientHeight()));
dy = std::min<LayoutUnit>(ScrollableArea::pixelsPerLineStep(), container->renderBox()->scrollHeight() - (container->renderBox()->scrollTop() + container->renderBox()->clientHeight()));
break;
@@ -425,42 +421,43 @@ bool isScrollableNode(const Node* node)
return false;
if (RenderObject* renderer = node->renderer())
- return renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea() && node->hasChildNodes();
+ return renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea() && node->hasChildren();
return false;
}
-Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection direction, Node* node)
+Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusType type, Node* node)
{
ASSERT(node);
Node* parent = node;
do {
+ // FIXME: Spatial navigation is broken for OOPI.
if (parent->isDocumentNode())
- parent = toDocument(parent)->document().frame()->ownerElement();
+ parent = toDocument(parent)->frame()->deprecatedLocalOwner();
else
parent = parent->parentOrShadowHostNode();
- } while (parent && !canScrollInDirection(parent, direction) && !parent->isDocumentNode());
+ } while (parent && !canScrollInDirection(parent, type) && !parent->isDocumentNode());
return parent;
}
-bool canScrollInDirection(const Node* container, FocusDirection direction)
+bool canScrollInDirection(const Node* container, FocusType type)
{
ASSERT(container);
if (container->isDocumentNode())
- return canScrollInDirection(toDocument(container)->frame(), direction);
+ return canScrollInDirection(toDocument(container)->frame(), type);
if (!isScrollableNode(container))
return false;
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
return (container->renderer()->style()->overflowX() != OHIDDEN && container->renderBox()->scrollLeft() > 0);
- case FocusDirectionUp:
+ case FocusTypeUp:
return (container->renderer()->style()->overflowY() != OHIDDEN && container->renderBox()->scrollTop() > 0);
- case FocusDirectionRight:
+ case FocusTypeRight:
return (container->renderer()->style()->overflowX() != OHIDDEN && container->renderBox()->scrollLeft() + container->renderBox()->clientWidth() < container->renderBox()->scrollWidth());
- case FocusDirectionDown:
+ case FocusTypeDown:
return (container->renderer()->style()->overflowY() != OHIDDEN && container->renderBox()->scrollTop() + container->renderBox()->clientHeight() < container->renderBox()->scrollHeight());
default:
ASSERT_NOT_REACHED();
@@ -468,29 +465,29 @@ bool canScrollInDirection(const Node* container, FocusDirection direction)
}
}
-bool canScrollInDirection(const Frame* frame, FocusDirection direction)
+bool canScrollInDirection(const LocalFrame* frame, FocusType type)
{
if (!frame->view())
return false;
ScrollbarMode verticalMode;
ScrollbarMode horizontalMode;
- frame->view()->calculateScrollbarModesForLayout(horizontalMode, verticalMode);
- if ((direction == FocusDirectionLeft || direction == FocusDirectionRight) && ScrollbarAlwaysOff == horizontalMode)
+ frame->view()->calculateScrollbarModesForLayoutAndSetViewportRenderer(horizontalMode, verticalMode);
+ if ((type == FocusTypeLeft || type == FocusTypeRight) && ScrollbarAlwaysOff == horizontalMode)
return false;
- if ((direction == FocusDirectionUp || direction == FocusDirectionDown) && ScrollbarAlwaysOff == verticalMode)
+ if ((type == FocusTypeUp || type == FocusTypeDown) && ScrollbarAlwaysOff == verticalMode)
return false;
LayoutSize size = frame->view()->contentsSize();
LayoutSize offset = frame->view()->scrollOffset();
- LayoutRect rect = frame->view()->visibleContentRect(ScrollableArea::IncludeScrollbars);
+ LayoutRect rect = frame->view()->visibleContentRect(IncludeScrollbars);
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
return offset.width() > 0;
- case FocusDirectionUp:
+ case FocusTypeUp:
return offset.height() > 0;
- case FocusDirectionRight:
+ case FocusTypeRight:
return rect.width() + offset.width() < size.width();
- case FocusDirectionDown:
+ case FocusTypeDown:
return rect.height() + offset.height() < size.height();
default:
ASSERT_NOT_REACHED();
@@ -498,15 +495,18 @@ bool canScrollInDirection(const Frame* frame, FocusDirection direction)
}
}
-static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect& initialRect)
+static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const LayoutRect& initialRect)
{
LayoutRect rect = initialRect;
for (Frame* frame = initialFrame; frame; frame = frame->tree().parent()) {
- if (Element* element = frame->ownerElement()) {
+ if (!frame->isLocalFrame())
+ continue;
+ // FIXME: Spatial navigation is broken for OOPI.
+ if (Element* element = frame->deprecatedLocalOwner()) {
do {
rect.move(element->offsetLeft(), element->offsetTop());
} while ((element = element->offsetParent()));
- rect.move((-frame->view()->scrollOffset()));
+ rect.move((-toLocalFrame(frame)->view()->scrollOffset()));
}
}
return rect;
@@ -530,58 +530,84 @@ LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder)
return rect;
}
-LayoutRect frameRectInAbsoluteCoordinates(Frame* frame)
+LayoutRect frameRectInAbsoluteCoordinates(LocalFrame* frame)
{
return rectToAbsoluteCoordinates(frame, frame->view()->visibleContentRect());
}
// This method calculates the exitPoint from the startingRect and the entryPoint into the candidate rect.
// The line between those 2 points is the closest distance between the 2 rects.
-void entryAndExitPointsForDirection(FocusDirection direction, const LayoutRect& startingRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryPoint)
+// Takes care of overlapping rects, defining points so that the distance between them
+// is zero where necessary
+void entryAndExitPointsForDirection(FocusType type, const LayoutRect& startingRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryPoint)
{
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
exitPoint.setX(startingRect.x());
- entryPoint.setX(potentialRect.maxX());
+ if (potentialRect.maxX() < startingRect.x())
+ entryPoint.setX(potentialRect.maxX());
+ else
+ entryPoint.setX(startingRect.x());
break;
- case FocusDirectionUp:
+ case FocusTypeUp:
exitPoint.setY(startingRect.y());
- entryPoint.setY(potentialRect.maxY());
+ if (potentialRect.maxY() < startingRect.y())
+ entryPoint.setY(potentialRect.maxY());
+ else
+ entryPoint.setY(startingRect.y());
break;
- case FocusDirectionRight:
+ case FocusTypeRight:
exitPoint.setX(startingRect.maxX());
- entryPoint.setX(potentialRect.x());
+ if (potentialRect.x() > startingRect.maxX())
+ entryPoint.setX(potentialRect.x());
+ else
+ entryPoint.setX(startingRect.maxX());
break;
- case FocusDirectionDown:
+ case FocusTypeDown:
exitPoint.setY(startingRect.maxY());
- entryPoint.setY(potentialRect.y());
+ if (potentialRect.y() > startingRect.maxY())
+ entryPoint.setY(potentialRect.y());
+ else
+ entryPoint.setY(startingRect.maxY());
break;
default:
ASSERT_NOT_REACHED();
}
- switch (direction) {
- case FocusDirectionLeft:
- case FocusDirectionRight:
+ switch (type) {
+ case FocusTypeLeft:
+ case FocusTypeRight:
if (below(startingRect, potentialRect)) {
exitPoint.setY(startingRect.y());
- entryPoint.setY(potentialRect.maxY());
+ if (potentialRect.maxY() < startingRect.y())
+ entryPoint.setY(potentialRect.maxY());
+ else
+ entryPoint.setY(startingRect.y());
} else if (below(potentialRect, startingRect)) {
exitPoint.setY(startingRect.maxY());
- entryPoint.setY(potentialRect.y());
+ if (potentialRect.y() > startingRect.maxY())
+ entryPoint.setY(potentialRect.y());
+ else
+ entryPoint.setY(startingRect.maxY());
} else {
exitPoint.setY(max(startingRect.y(), potentialRect.y()));
entryPoint.setY(exitPoint.y());
}
break;
- case FocusDirectionUp:
- case FocusDirectionDown:
+ case FocusTypeUp:
+ case FocusTypeDown:
if (rightOf(startingRect, potentialRect)) {
exitPoint.setX(startingRect.x());
- entryPoint.setX(potentialRect.maxX());
+ if (potentialRect.maxX() < startingRect.x())
+ entryPoint.setX(potentialRect.maxX());
+ else
+ entryPoint.setX(startingRect.x());
} else if (rightOf(potentialRect, startingRect)) {
exitPoint.setX(startingRect.maxX());
- entryPoint.setX(potentialRect.x());
+ if (potentialRect.x() > startingRect.maxX())
+ entryPoint.setX(potentialRect.x());
+ else
+ entryPoint.setX(startingRect.maxX());
} else {
exitPoint.setX(max(startingRect.x(), potentialRect.x()));
entryPoint.setX(exitPoint.x());
@@ -603,7 +629,7 @@ bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCand
if (!firstCandidate.rect.intersects(secondCandidate.rect))
return false;
- if (isHTMLAreaElement(firstCandidate.focusableNode) || isHTMLAreaElement(secondCandidate.focusableNode))
+ if (isHTMLAreaElement(*firstCandidate.focusableNode) || isHTMLAreaElement(*secondCandidate.focusableNode))
return false;
if (!firstCandidate.visibleNode->renderer()->isRenderInline() || !secondCandidate.visibleNode->renderer()->isRenderInline())
@@ -615,10 +641,10 @@ bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCand
return true;
}
-void distanceDataForNode(FocusDirection direction, const FocusCandidate& current, FocusCandidate& candidate)
+void distanceDataForNode(FocusType type, const FocusCandidate& current, FocusCandidate& candidate)
{
if (areElementsOnSameLine(current, candidate)) {
- if ((direction == FocusDirectionUp && current.rect.y() > candidate.rect.y()) || (direction == FocusDirectionDown && candidate.rect.y() > current.rect.y())) {
+ if ((type == FocusTypeUp && current.rect.y() > candidate.rect.y()) || (type == FocusTypeDown && candidate.rect.y() > current.rect.y())) {
candidate.distance = 0;
candidate.alignment = Full;
return;
@@ -629,64 +655,59 @@ void distanceDataForNode(FocusDirection direction, const FocusCandidate& current
LayoutRect currentRect = current.rect;
deflateIfOverlapped(currentRect, nodeRect);
- if (!isRectInDirection(direction, currentRect, nodeRect))
+ if (!isRectInDirection(type, currentRect, nodeRect))
return;
LayoutPoint exitPoint;
LayoutPoint entryPoint;
- LayoutUnit sameAxisDistance = 0;
- LayoutUnit otherAxisDistance = 0;
- entryAndExitPointsForDirection(direction, currentRect, nodeRect, exitPoint, entryPoint);
-
- switch (direction) {
- case FocusDirectionLeft:
- sameAxisDistance = exitPoint.x() - entryPoint.x();
- otherAxisDistance = absoluteValue(exitPoint.y() - entryPoint.y());
- break;
- case FocusDirectionUp:
- sameAxisDistance = exitPoint.y() - entryPoint.y();
- otherAxisDistance = absoluteValue(exitPoint.x() - entryPoint.x());
- break;
- case FocusDirectionRight:
- sameAxisDistance = entryPoint.x() - exitPoint.x();
- otherAxisDistance = absoluteValue(entryPoint.y() - exitPoint.y());
+ entryAndExitPointsForDirection(type, currentRect, nodeRect, exitPoint, entryPoint);
+
+ LayoutUnit xAxis = exitPoint.x() - entryPoint.x();
+ LayoutUnit yAxis = exitPoint.y() - entryPoint.y();
+
+ LayoutUnit navigationAxisDistance;
+ LayoutUnit orthogonalAxisDistance;
+
+ switch (type) {
+ case FocusTypeLeft:
+ case FocusTypeRight:
+ navigationAxisDistance = xAxis.abs();
+ orthogonalAxisDistance = yAxis.abs();
break;
- case FocusDirectionDown:
- sameAxisDistance = entryPoint.y() - exitPoint.y();
- otherAxisDistance = absoluteValue(entryPoint.x() - exitPoint.x());
+ case FocusTypeUp:
+ case FocusTypeDown:
+ navigationAxisDistance = yAxis.abs();
+ orthogonalAxisDistance = xAxis.abs();
break;
default:
ASSERT_NOT_REACHED();
return;
}
- float x = (entryPoint.x() - exitPoint.x()) * (entryPoint.x() - exitPoint.x());
- float y = (entryPoint.y() - exitPoint.y()) * (entryPoint.y() - exitPoint.y());
-
- float euclidianDistance = sqrt(x + y);
+ double euclidianDistancePow2 = (xAxis * xAxis + yAxis * yAxis).toDouble();
+ LayoutRect intersectionRect = intersection(currentRect, nodeRect);
+ double overlap = (intersectionRect.width() * intersectionRect.height()).toDouble();
- // Loosely based on http://www.w3.org/TR/WICD/#focus-handling
- // df = dotDist + dx + dy + 2 * (xdisplacement + ydisplacement) - sqrt(Overlap)
+ // Distance calculation is based on http://www.w3.org/TR/WICD/#focus-handling
+ candidate.distance = sqrt(euclidianDistancePow2) + navigationAxisDistance+ orthogonalAxisDistance * 2 - sqrt(overlap);
- float distance = euclidianDistance + sameAxisDistance + 2 * otherAxisDistance;
- candidate.distance = roundf(distance);
- LayoutSize viewSize = candidate.visibleNode->document().page()->mainFrame()->view()->visibleContentRect().size();
- candidate.alignment = alignmentForRects(direction, currentRect, nodeRect, viewSize);
+ LayoutSize viewSize = candidate.visibleNode->document().page()->deprecatedLocalMainFrame()->view()->visibleContentRect().size();
+ candidate.alignment = alignmentForRects(type, currentRect, nodeRect, viewSize);
}
-bool canBeScrolledIntoView(FocusDirection direction, const FocusCandidate& candidate)
+bool canBeScrolledIntoView(FocusType type, const FocusCandidate& candidate)
{
ASSERT(candidate.visibleNode && candidate.isOffscreen);
LayoutRect candidateRect = candidate.rect;
for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; parentNode = parentNode->parentNode()) {
LayoutRect parentRect = nodeRectInAbsoluteCoordinates(parentNode);
if (!candidateRect.intersects(parentRect)) {
- if (((direction == FocusDirectionLeft || direction == FocusDirectionRight) && parentNode->renderer()->style()->overflowX() == OHIDDEN)
- || ((direction == FocusDirectionUp || direction == FocusDirectionDown) && parentNode->renderer()->style()->overflowY() == OHIDDEN))
+ if (((type == FocusTypeLeft || type == FocusTypeRight) && parentNode->renderer()->style()->overflowX() == OHIDDEN)
+ || ((type == FocusTypeUp || type == FocusTypeDown) && parentNode->renderer()->style()->overflowY() == OHIDDEN))
return false;
}
if (parentNode == candidate.enclosingScrollableBox)
- return canScrollInDirection(parentNode, direction);
+ return canScrollInDirection(parentNode, type);
}
return true;
}
@@ -695,22 +716,22 @@ bool canBeScrolledIntoView(FocusDirection direction, const FocusCandidate& candi
// Compose a virtual starting rect if there is no focused node or if it is off screen.
// The virtual rect is the edge of the container or frame. We select which
// edge depending on the direction of the navigation.
-LayoutRect virtualRectForDirection(FocusDirection direction, const LayoutRect& startingRect, LayoutUnit width)
+LayoutRect virtualRectForDirection(FocusType type, const LayoutRect& startingRect, LayoutUnit width)
{
LayoutRect virtualStartingRect = startingRect;
- switch (direction) {
- case FocusDirectionLeft:
+ switch (type) {
+ case FocusTypeLeft:
virtualStartingRect.setX(virtualStartingRect.maxX() - width);
virtualStartingRect.setWidth(width);
break;
- case FocusDirectionUp:
+ case FocusTypeUp:
virtualStartingRect.setY(virtualStartingRect.maxY() - width);
virtualStartingRect.setHeight(width);
break;
- case FocusDirectionRight:
+ case FocusTypeRight:
virtualStartingRect.setWidth(width);
break;
- case FocusDirectionDown:
+ case FocusTypeDown:
virtualStartingRect.setHeight(width);
break;
default:
@@ -720,13 +741,12 @@ LayoutRect virtualRectForDirection(FocusDirection direction, const LayoutRect& s
return virtualStartingRect;
}
-LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement* area, FocusDirection direction)
+LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement& area, FocusType type)
{
- ASSERT(area);
- ASSERT(area->imageElement());
+ ASSERT(area.imageElement());
// Area elements tend to overlap more than other focusable elements. We flatten the rect of the area elements
// to minimize the effect of overlapping areas.
- LayoutRect rect = virtualRectForDirection(direction, rectToAbsoluteCoordinates(area->document().frame(), area->computeRect(area->imageElement()->renderer())), 1);
+ LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(area.document().frame(), area.computeRect(area.imageElement()->renderer())), 1);
return rect;
}
diff --git a/chromium/third_party/WebKit/Source/core/page/SpatialNavigation.h b/chromium/third_party/WebKit/Source/core/page/SpatialNavigation.h
index 1e2f56c40df..2fef4da6ab9 100644
--- a/chromium/third_party/WebKit/Source/core/page/SpatialNavigation.h
+++ b/chromium/third_party/WebKit/Source/core/page/SpatialNavigation.h
@@ -22,8 +22,7 @@
#define SpatialNavigation_h
#include "core/dom/Node.h"
-#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/page/FocusDirection.h"
+#include "core/page/FocusType.h"
#include "platform/geometry/LayoutRect.h"
#include <limits>
@@ -31,8 +30,9 @@
namespace WebCore {
class Element;
-class Frame;
+class LocalFrame;
class HTMLAreaElement;
+class HTMLFrameOwnerElement;
class IntRect;
class RenderObject;
@@ -46,7 +46,7 @@ inline int fudgeFactor()
return 2;
}
-bool isSpatialNavigationEnabled(const Frame*);
+bool isSpatialNavigationEnabled(const LocalFrame*);
// Spatially speaking, two given elements in a web page can be:
// 1) Fully aligned: There is a full intersection between the rects, either
@@ -111,8 +111,8 @@ struct FocusCandidate {
{
}
- FocusCandidate(Node* n, FocusDirection);
- explicit FocusCandidate(HTMLAreaElement* area, FocusDirection);
+ FocusCandidate(Node*, FocusType);
+ explicit FocusCandidate(HTMLAreaElement*, FocusType);
bool isNull() const { return !visibleNode; }
bool inScrollableContainer() const { return visibleNode && enclosingScrollableBox; }
bool isFrameOwnerElement() const { return visibleNode && visibleNode->isFrameOwnerElement(); }
@@ -133,19 +133,19 @@ struct FocusCandidate {
bool isOffscreenAfterScrolling;
};
-bool hasOffscreenRect(Node*, FocusDirection direction = FocusDirectionNone);
-bool scrollInDirection(Frame*, FocusDirection);
-bool scrollInDirection(Node* container, FocusDirection);
-bool canScrollInDirection(const Node* container, FocusDirection);
-bool canScrollInDirection(const Frame*, FocusDirection);
-bool canBeScrolledIntoView(FocusDirection, const FocusCandidate&);
+bool hasOffscreenRect(Node*, FocusType = FocusTypeNone);
+bool scrollInDirection(LocalFrame*, FocusType);
+bool scrollInDirection(Node* container, FocusType);
+bool canScrollInDirection(const Node* container, FocusType);
+bool canScrollInDirection(const LocalFrame*, FocusType);
+bool canBeScrolledIntoView(FocusType, const FocusCandidate&);
bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCandidate& secondCandidate);
-void distanceDataForNode(FocusDirection, const FocusCandidate& current, FocusCandidate& candidate);
-Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusDirection, Node*);
+void distanceDataForNode(FocusType, const FocusCandidate& current, FocusCandidate&);
+Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusType, Node*);
LayoutRect nodeRectInAbsoluteCoordinates(Node*, bool ignoreBorder = false);
-LayoutRect frameRectInAbsoluteCoordinates(Frame*);
-LayoutRect virtualRectForDirection(FocusDirection, const LayoutRect& startingRect, LayoutUnit width = 0);
-LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement*, FocusDirection);
+LayoutRect frameRectInAbsoluteCoordinates(LocalFrame*);
+LayoutRect virtualRectForDirection(FocusType, const LayoutRect& startingRect, LayoutUnit width = 0);
+LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement&, FocusType);
HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate&);
} // namspace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/StorageClient.h b/chromium/third_party/WebKit/Source/core/page/StorageClient.h
new file mode 100644
index 00000000000..7017df008ce
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/page/StorageClient.h
@@ -0,0 +1,25 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StorageClient_h
+#define StorageClient_h
+
+#include "core/storage/StorageArea.h"
+#include "wtf/PassOwnPtr.h"
+
+namespace WebCore {
+
+class StorageNamespace;
+
+class StorageClient {
+public:
+ virtual ~StorageClient() { }
+
+ virtual PassOwnPtr<StorageNamespace> createSessionStorageNamespace() = 0;
+ virtual bool canAccessStorage(LocalFrame*, StorageType) const = 0;
+};
+
+} // namespace WebCore
+
+#endif // StorageClient_h
diff --git a/chromium/third_party/WebKit/Source/core/page/TouchAdjustment.cpp b/chromium/third_party/WebKit/Source/core/page/TouchAdjustment.cpp
index be85ae4f143..89d396a8a24 100644
--- a/chromium/third_party/WebKit/Source/core/page/TouchAdjustment.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/TouchAdjustment.cpp
@@ -26,9 +26,9 @@
#include "core/dom/NodeRenderStyle.h"
#include "core/dom/Text.h"
#include "core/editing/Editor.h"
-#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLFrameOwnerElement.h"
#include "core/rendering/RenderBox.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderText.h"
@@ -46,22 +46,34 @@ const float zeroTolerance = 1e-6f;
// Class for remembering absolute quads of a target node and what node they represent.
class SubtargetGeometry {
+ ALLOW_ONLY_INLINE_ALLOCATION();
public:
SubtargetGeometry(Node* node, const FloatQuad& quad)
: m_node(node)
, m_quad(quad)
{ }
+ void trace(Visitor* visitor) { visitor->trace(m_node); }
Node* node() const { return m_node; }
FloatQuad quad() const { return m_quad; }
IntRect boundingBox() const { return m_quad.enclosingBoundingBox(); }
private:
- Node* m_node;
+ RawPtrWillBeMember<Node> m_node;
FloatQuad m_quad;
};
-typedef Vector<SubtargetGeometry> SubtargetGeometryList;
+}
+
+}
+
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::TouchAdjustment::SubtargetGeometry)
+
+namespace WebCore {
+
+namespace TouchAdjustment {
+
+typedef WillBeHeapVector<SubtargetGeometry> SubtargetGeometryList;
typedef bool (*NodeFilter)(Node*);
typedef void (*AppendSubtargetsForNode)(Node*, SubtargetGeometryList&);
typedef float (*DistanceFunction)(const IntPoint&, const IntRect&, const SubtargetGeometry&);
@@ -76,7 +88,7 @@ bool nodeRespondsToTapGesture(Node* node)
if (element->isMouseFocusable())
return true;
// Accept nodes that has a CSS effect when touched.
- if (element->childrenAffectedByActive() || element->childrenAffectedByHover())
+ if (element->childrenOrSiblingsAffectedByActive() || element->childrenOrSiblingsAffectedByHover())
return true;
}
if (RenderStyle* renderStyle = node->renderStyle()) {
@@ -229,20 +241,20 @@ static inline Node* parentShadowHostOrOwner(const Node* node)
}
// Compiles a list of subtargets of all the relevant target nodes.
-void compileSubtargetList(const Vector<RefPtr<Node> >& intersectedNodes, SubtargetGeometryList& subtargets, NodeFilter nodeFilter, AppendSubtargetsForNode appendSubtargetsForNode)
+void compileSubtargetList(const WillBeHeapVector<RefPtrWillBeMember<Node> >& intersectedNodes, SubtargetGeometryList& subtargets, NodeFilter nodeFilter, AppendSubtargetsForNode appendSubtargetsForNode)
{
// Find candidates responding to tap gesture events in O(n) time.
- HashMap<Node*, Node*> responderMap;
- HashSet<Node*> ancestorsToRespondersSet;
- Vector<Node*> candidates;
- HashSet<Node*> editableAncestors;
+ WillBeHeapHashMap<RawPtrWillBeMember<Node>, RawPtrWillBeMember<Node> > responderMap;
+ WillBeHeapHashSet<RawPtrWillBeMember<Node> > ancestorsToRespondersSet;
+ WillBeHeapVector<RawPtrWillBeMember<Node> > candidates;
+ WillBeHeapHashSet<RawPtrWillBeMember<Node> > editableAncestors;
// A node matching the NodeFilter is called a responder. Candidate nodes must either be a
// responder or have an ancestor that is a responder.
// This iteration tests all ancestors at most once by caching earlier results.
for (unsigned i = 0; i < intersectedNodes.size(); ++i) {
Node* node = intersectedNodes[i].get();
- Vector<Node*> visitedNodes;
+ WillBeHeapVector<RawPtrWillBeMember<Node> > visitedNodes;
Node* respondingNode = 0;
for (Node* visitedNode = node; visitedNode; visitedNode = visitedNode->parentOrShadowHostNode()) {
// Check if we already have a result for a common ancestor from another candidate.
@@ -255,7 +267,7 @@ void compileSubtargetList(const Vector<RefPtr<Node> >& intersectedNodes, Subtarg
respondingNode = visitedNode;
// Continue the iteration to collect the ancestors of the responder, which we will need later.
for (visitedNode = parentShadowHostOrOwner(visitedNode); visitedNode; visitedNode = parentShadowHostOrOwner(visitedNode)) {
- HashSet<Node*>::AddResult addResult = ancestorsToRespondersSet.add(visitedNode);
+ WillBeHeapHashSet<RawPtrWillBeMember<Node> >::AddResult addResult = ancestorsToRespondersSet.add(visitedNode);
if (!addResult.isNewEntry)
break;
}
@@ -304,7 +316,7 @@ void compileSubtargetList(const Vector<RefPtr<Node> >& intersectedNodes, Subtarg
}
// Compiles a list of zoomable subtargets.
-void compileZoomableSubtargets(const Vector<RefPtr<Node> >& intersectedNodes, SubtargetGeometryList& subtargets)
+void compileZoomableSubtargets(const WillBeHeapVector<RefPtrWillBeMember<Node> >& intersectedNodes, SubtargetGeometryList& subtargets)
{
for (unsigned i = 0; i < intersectedNodes.size(); ++i) {
Node* candidate = intersectedNodes[i].get();
@@ -469,7 +481,7 @@ bool findNodeWithLowestDistanceMetric(Node*& targetNode, IntPoint& targetPoint,
} // namespace TouchAdjustment
-bool findBestClickableCandidate(Node*& targetNode, IntPoint &targetPoint, const IntPoint &touchHotspot, const IntRect &touchArea, const Vector<RefPtr<Node> >& nodes)
+bool findBestClickableCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes)
{
IntRect targetArea;
TouchAdjustment::SubtargetGeometryList subtargets;
@@ -477,7 +489,7 @@ bool findBestClickableCandidate(Node*& targetNode, IntPoint &targetPoint, const
return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDistanceFunction);
}
-bool findBestContextMenuCandidate(Node*& targetNode, IntPoint &targetPoint, const IntPoint &touchHotspot, const IntRect &touchArea, const Vector<RefPtr<Node> >& nodes)
+bool findBestContextMenuCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes)
{
IntRect targetArea;
TouchAdjustment::SubtargetGeometryList subtargets;
@@ -485,7 +497,7 @@ bool findBestContextMenuCandidate(Node*& targetNode, IntPoint &targetPoint, cons
return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDistanceFunction);
}
-bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const Vector<RefPtr<Node> >& nodes)
+bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >& nodes)
{
IntPoint targetPoint;
TouchAdjustment::SubtargetGeometryList subtargets;
diff --git a/chromium/third_party/WebKit/Source/core/page/TouchAdjustment.h b/chromium/third_party/WebKit/Source/core/page/TouchAdjustment.h
index 2bd66d637d6..df2cd162cc8 100644
--- a/chromium/third_party/WebKit/Source/core/page/TouchAdjustment.h
+++ b/chromium/third_party/WebKit/Source/core/page/TouchAdjustment.h
@@ -22,6 +22,7 @@
#include "platform/geometry/IntPoint.h"
#include "platform/geometry/IntRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
@@ -29,9 +30,9 @@ namespace WebCore {
class Node;
-bool findBestClickableCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const Vector<RefPtr<Node> >&);
-bool findBestContextMenuCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const Vector<RefPtr<Node> >&);
-bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const Vector<RefPtr<Node> >&);
+bool findBestClickableCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >&);
+bool findBestContextMenuCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >&);
+bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const WillBeHeapVector<RefPtrWillBeMember<Node> >&);
// FIXME: Implement the similar functions for other gestures here as well.
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.cpp b/chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.cpp
index 5fda7d8dc93..6cd314dd0ba 100644
--- a/chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.cpp
@@ -32,20 +32,18 @@
#include "core/page/TouchDisambiguation.h"
-#include <algorithm>
-#include <cmath>
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/NodeTraversal.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/RenderBlock.h"
-
-using namespace std;
+#include <algorithm>
+#include <cmath>
namespace WebCore {
@@ -77,8 +75,8 @@ static float scoreTouchTarget(IntPoint touchPoint, int padding, IntRect bounding
float score = 1;
IntSize distance = boundingBox.differenceToPoint(touchPoint);
- score *= max((padding - abs(distance.width())) * reciprocalPadding, 0.f);
- score *= max((padding - abs(distance.height())) * reciprocalPadding, 0.f);
+ score *= std::max((padding - abs(distance.width())) * reciprocalPadding, 0.f);
+ score *= std::max((padding - abs(distance.height())) * reciprocalPadding, 0.f);
return score;
}
@@ -88,23 +86,23 @@ struct TouchTargetData {
float score;
};
-void findGoodTouchTargets(const IntRect& touchBox, Frame* mainFrame, Vector<IntRect>& goodTargets, Vector<Node*>& highlightNodes)
+void findGoodTouchTargets(const IntRect& touchBox, LocalFrame* mainFrame, Vector<IntRect>& goodTargets, WillBeHeapVector<RawPtrWillBeMember<Node> >& highlightNodes)
{
goodTargets.clear();
- int touchPointPadding = ceil(max(touchBox.width(), touchBox.height()) * 0.5);
+ int touchPointPadding = ceil(std::max(touchBox.width(), touchBox.height()) * 0.5);
IntPoint touchPoint = touchBox.center();
IntPoint contentsPoint = mainFrame->view()->windowToContents(touchPoint);
HitTestResult result = mainFrame->eventHandler().hitTestResultAtPoint(contentsPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent, IntSize(touchPointPadding, touchPointPadding));
- const ListHashSet<RefPtr<Node> >& hitResults = result.rectBasedTestResult();
+ const WillBeHeapListHashSet<RefPtrWillBeMember<Node> >& hitResults = result.rectBasedTestResult();
// Blacklist nodes that are container of disambiguated nodes.
// It is not uncommon to have a clickable <div> that contains other clickable objects.
// This heuristic avoids excessive disambiguation in that case.
- HashSet<Node*> blackList;
- for (ListHashSet<RefPtr<Node> >::const_iterator it = hitResults.begin(); it != hitResults.end(); ++it) {
+ WillBeHeapHashSet<RawPtrWillBeMember<Node> > blackList;
+ for (WillBeHeapListHashSet<RefPtrWillBeMember<Node> >::const_iterator it = hitResults.begin(); it != hitResults.end(); ++it) {
// Ignore any Nodes that can't be clicked on.
RenderObject* renderer = it->get()->renderer();
if (!renderer || !it->get()->willRespondToMouseClickEvents())
@@ -120,25 +118,25 @@ void findGoodTouchTargets(const IntRect& touchBox, Frame* mainFrame, Vector<IntR
}
}
- HashMap<Node*, TouchTargetData> touchTargets;
+ WillBeHeapHashMap<RawPtrWillBeMember<Node>, TouchTargetData> touchTargets;
float bestScore = 0;
- for (ListHashSet<RefPtr<Node> >::const_iterator it = hitResults.begin(); it != hitResults.end(); ++it) {
+ for (WillBeHeapListHashSet<RefPtrWillBeMember<Node> >::const_iterator it = hitResults.begin(); it != hitResults.end(); ++it) {
for (Node* node = it->get(); node; node = node->parentNode()) {
if (blackList.contains(node))
continue;
- if (node->isDocumentNode() || isHTMLHtmlElement(node) || node->hasTagName(HTMLNames::bodyTag))
+ if (node->isDocumentNode() || isHTMLHtmlElement(*node) || isHTMLBodyElement(*node))
break;
if (node->willRespondToMouseClickEvents()) {
- TouchTargetData& targetData = touchTargets.add(node, TouchTargetData()).iterator->value;
+ TouchTargetData& targetData = touchTargets.add(node, TouchTargetData()).storedValue->value;
targetData.windowBoundingBox = boundingBoxForEventNodes(node);
targetData.score = scoreTouchTarget(touchPoint, touchPointPadding, targetData.windowBoundingBox);
- bestScore = max(bestScore, targetData.score);
+ bestScore = std::max(bestScore, targetData.score);
break;
}
}
}
- for (HashMap<Node*, TouchTargetData>::iterator it = touchTargets.begin(); it != touchTargets.end(); ++it) {
+ for (WillBeHeapHashMap<RawPtrWillBeMember<Node>, TouchTargetData>::iterator it = touchTargets.begin(); it != touchTargets.end(); ++it) {
// Currently the scoring function uses the overlap area with the fat point as the score.
// We ignore the candidates that has less than 1/2 overlap (we consider not really ambiguous enough) than the best candidate to avoid excessive popups.
if (it->value.score < bestScore * 0.5)
diff --git a/chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.h b/chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.h
index 36352a96c3d..d20127ded6c 100644
--- a/chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.h
+++ b/chromium/third_party/WebKit/Source/core/page/TouchDisambiguation.h
@@ -31,15 +31,16 @@
#ifndef TouchDisambiguation_h
#define TouchDisambiguation_h
+#include "platform/heap/Handle.h"
#include "wtf/Vector.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
class IntRect;
class Node;
-void findGoodTouchTargets(const IntRect& touchBox, Frame* mainFrame, Vector<IntRect>& goodTargets, Vector<Node*>& highlightNodes);
+void findGoodTouchTargets(const IntRect& touchBox, LocalFrame* mainFrame, Vector<IntRect>& goodTargets, WillBeHeapVector<RawPtrWillBeMember<Node> >& highlightNodes);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/ValidationMessageClient.h b/chromium/third_party/WebKit/Source/core/page/ValidationMessageClient.h
index b61534426dd..ae2354cd578 100644
--- a/chromium/third_party/WebKit/Source/core/page/ValidationMessageClient.h
+++ b/chromium/third_party/WebKit/Source/core/page/ValidationMessageClient.h
@@ -26,6 +26,7 @@
#ifndef ValidationMessageClient_h
#define ValidationMessageClient_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
namespace WebCore {
@@ -33,7 +34,7 @@ namespace WebCore {
class Document;
class Element;
-class ValidationMessageClient {
+class ValidationMessageClient : public WillBeGarbageCollectedMixin {
public:
virtual ~ValidationMessageClient() { }
@@ -51,6 +52,10 @@ public:
virtual bool isValidationMessageVisible(const Element& anchor) = 0;
virtual void documentDetached(const Document&) = 0;
+
+ virtual void willBeDestroyed() = 0;
+
+ virtual void trace(Visitor*) { }
};
}
diff --git a/chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp b/chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp
index 3796f0bb496..85202c25154 100644
--- a/chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/WindowFeatures.cpp
@@ -37,10 +37,15 @@ static bool isWindowFeaturesSeparator(UChar c)
}
WindowFeatures::WindowFeatures(const String& features)
- : xSet(false)
+ : x(0)
+ , xSet(false)
+ , y(0)
, ySet(false)
+ , width(0)
, widthSet(false)
+ , height(0)
, heightSet(false)
+ , resizable(true)
, fullscreen(false)
, dialog(false)
{
@@ -53,13 +58,12 @@ WindowFeatures::WindowFeatures(const String& features)
We always allow a window to be resized, which is consistent with Firefox.
*/
- if (features.length() == 0) {
+ if (features.isEmpty()) {
menuBarVisible = true;
statusBarVisible = true;
toolBarVisible = true;
locationBarVisible = true;
scrollbarsVisible = true;
- resizable = true;
return;
}
@@ -68,46 +72,47 @@ WindowFeatures::WindowFeatures(const String& features)
toolBarVisible = false;
locationBarVisible = false;
scrollbarsVisible = false;
- resizable = true;
// Tread lightly in this code -- it was specifically designed to mimic Win IE's parsing behavior.
- int keyBegin, keyEnd;
- int valueBegin, valueEnd;
+ unsigned keyBegin, keyEnd;
+ unsigned valueBegin, valueEnd;
- int i = 0;
- int length = features.length();
String buffer = features.lower();
- while (i < length) {
+ unsigned length = buffer.length();
+ for (unsigned i = 0; i < length; ) {
// skip to first non-separator, but don't skip past the end of the string
- while (isWindowFeaturesSeparator(buffer[i])) {
- if (i >= length)
- break;
+ while (i < length && isWindowFeaturesSeparator(buffer[i]))
i++;
- }
keyBegin = i;
// skip to first separator
- while (!isWindowFeaturesSeparator(buffer[i]))
+ while (i < length && !isWindowFeaturesSeparator(buffer[i]))
i++;
keyEnd = i;
+ ASSERT_WITH_SECURITY_IMPLICATION(i <= length);
+
// skip to first '=', but don't skip past a ',' or the end of the string
- while (buffer[i] != '=') {
- if (buffer[i] == ',' || i >= length)
+ while (i < length && buffer[i] != '=') {
+ if (buffer[i] == ',')
break;
i++;
}
+ ASSERT_WITH_SECURITY_IMPLICATION(i <= length);
+
// skip to first non-separator, but don't skip past a ',' or the end of the string
- while (isWindowFeaturesSeparator(buffer[i])) {
- if (buffer[i] == ',' || i >= length)
+ while (i < length && isWindowFeaturesSeparator(buffer[i])) {
+ if (buffer[i] == ',')
break;
i++;
}
valueBegin = i;
+ ASSERT_WITH_SECURITY_IMPLICATION(i <= length);
+
// skip to first separator
- while (!isWindowFeaturesSeparator(buffer[i]))
+ while (i < length && !isWindowFeaturesSeparator(buffer[i]))
i++;
valueEnd = i;
diff --git a/chromium/third_party/WebKit/Source/core/page/WindowFeatures.h b/chromium/third_party/WebKit/Source/core/page/WindowFeatures.h
index 8605208e1ab..0f4fc6ce882 100644
--- a/chromium/third_party/WebKit/Source/core/page/WindowFeatures.h
+++ b/chromium/third_party/WebKit/Source/core/page/WindowFeatures.h
@@ -38,9 +38,13 @@ class FloatRect;
struct WindowFeatures {
WindowFeatures()
- : xSet(false)
+ : x(0.0f)
+ , xSet(false)
+ , y(0.0f)
, ySet(false)
+ , width(0.0f)
, widthSet(false)
+ , height(0.0f)
, heightSet(false)
, menuBarVisible(true)
, statusBarVisible(true)
diff --git a/chromium/third_party/WebKit/Source/core/page/WindowPagePopup.idl b/chromium/third_party/WebKit/Source/core/page/WindowPagePopup.idl
index e4b58393448..0b81785c63e 100644
--- a/chromium/third_party/WebKit/Source/core/page/WindowPagePopup.idl
+++ b/chromium/third_party/WebKit/Source/core/page/WindowPagePopup.idl
@@ -29,8 +29,9 @@
*/
[
+ ImplementedAs=DOMWindowPagePopup,
+ PerContextEnabled=PagePopup,
RuntimeEnabled=PagePopup,
- ImplementedAs=DOMWindowPagePopup
] partial interface Window {
- [PerContextEnabled=PagePopup] readonly attribute PagePopupController pagePopupController;
+ readonly attribute PagePopupController pagePopupController;
};
diff --git a/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingConstraints.h b/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingConstraints.h
index 993f2340734..857430e5a63 100644
--- a/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingConstraints.h
+++ b/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingConstraints.h
@@ -73,7 +73,7 @@ protected:
AnchorEdges m_anchorEdges;
};
-class FixedPositionViewportConstraints : public ViewportConstraints {
+class FixedPositionViewportConstraints FINAL : public ViewportConstraints {
public:
FixedPositionViewportConstraints()
: ViewportConstraints()
@@ -104,13 +104,13 @@ public:
bool operator!=(const FixedPositionViewportConstraints& other) const { return !(*this == other); }
private:
- virtual ConstraintType constraintType() const OVERRIDE { return FixedPositionConstaint; };
+ virtual ConstraintType constraintType() const OVERRIDE { return FixedPositionConstaint; }
FloatRect m_viewportRectAtLastLayout;
FloatPoint m_layerPositionAtLastLayout;
};
-class StickyPositionViewportConstraints : public ViewportConstraints {
+class StickyPositionViewportConstraints FINAL : public ViewportConstraints {
public:
StickyPositionViewportConstraints()
: m_leftOffset(0)
@@ -172,7 +172,7 @@ public:
bool operator!=(const StickyPositionViewportConstraints& other) const { return !(*this == other); }
private:
- virtual ConstraintType constraintType() const OVERRIDE { return StickyPositionConstraint; };
+ virtual ConstraintType constraintType() const OVERRIDE { return StickyPositionConstraint; }
float m_leftOffset;
float m_rightOffset;
diff --git a/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp b/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
index 51ecb5d055d..5dbf9982555 100644
--- a/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -27,15 +27,21 @@
#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/dom/Document.h"
+#include "core/dom/FullscreenElementStack.h"
#include "core/dom/Node.h"
-#include "core/dom/WheelController.h"
-#include "core/html/HTMLElement.h"
-#include "core/frame/Frame.h"
+#include "core/frame/EventHandlerRegistry.h"
#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/html/HTMLElement.h"
+#include "core/page/Page.h"
+#include "core/plugins/PluginView.h"
+#include "core/rendering/RenderGeometryMap.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "platform/exported/WebScrollbarImpl.h"
#include "platform/exported/WebScrollbarThemeGeometryNative.h"
@@ -47,11 +53,6 @@
#endif
#include "platform/scroll/ScrollAnimator.h"
#include "platform/scroll/ScrollbarTheme.h"
-#include "core/plugins/PluginView.h"
-#include "core/rendering/CompositedLayerMapping.h"
-#include "core/rendering/RenderGeometryMap.h"
-#include "core/rendering/RenderLayerCompositor.h"
-#include "core/rendering/RenderView.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCompositorSupport.h"
#include "public/platform/WebLayerPositionConstraint.h"
@@ -66,29 +67,27 @@ using blink::WebRect;
using blink::WebScrollbarLayer;
using blink::WebVector;
+namespace {
-namespace WebCore {
-
-static WebLayer* scrollingWebLayerForGraphicsLayer(GraphicsLayer* layer)
+WebLayer* toWebLayer(WebCore::GraphicsLayer* layer)
{
- return layer->platformLayer();
+ return layer ? layer->platformLayer() : 0;
}
-WebLayer* ScrollingCoordinator::scrollingWebLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
- GraphicsLayer* graphicsLayer = scrollLayerForScrollableArea(scrollableArea);
- return graphicsLayer ? scrollingWebLayerForGraphicsLayer(graphicsLayer) : 0;
-}
+} // namespace
+
+namespace WebCore {
-PassRefPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
+PassOwnPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
{
- return adoptRef(new ScrollingCoordinator(page));
+ return adoptPtr(new ScrollingCoordinator(page));
}
ScrollingCoordinator::ScrollingCoordinator(Page* page)
: m_page(page)
, m_scrollGestureRegionIsDirty(false)
, m_touchEventTargetRectsAreDirty(false)
+ , m_shouldScrollOnMainThreadDirty(false)
, m_wasFrameScrollable(false)
, m_lastMainThreadScrollingReasons(0)
{
@@ -96,24 +95,22 @@ ScrollingCoordinator::ScrollingCoordinator(Page* page)
ScrollingCoordinator::~ScrollingCoordinator()
{
- ASSERT(!m_page);
- for (ScrollbarMap::iterator it = m_horizontalScrollbars.begin(); it != m_horizontalScrollbars.end(); ++it)
- GraphicsLayer::unregisterContentsLayer(it->value->layer());
- for (ScrollbarMap::iterator it = m_verticalScrollbars.begin(); it != m_verticalScrollbars.end(); ++it)
- GraphicsLayer::unregisterContentsLayer(it->value->layer());
-
}
bool ScrollingCoordinator::touchHitTestingEnabled() const
{
- RenderView* contentRenderer = m_page->mainFrame()->contentRenderer();
- Settings* settings = m_page->mainFrame()->document()->settings();
+ if (!m_page->mainFrame()->isLocalFrame())
+ return false;
+ RenderView* contentRenderer = m_page->deprecatedLocalMainFrame()->contentRenderer();
+ Settings* settings = m_page->mainFrame()->settings();
return RuntimeEnabledFeatures::touchEnabled() && settings->compositorTouchHitTesting() && contentRenderer && contentRenderer->usesCompositing();
}
void ScrollingCoordinator::setShouldHandleScrollGestureOnMainThreadRegion(const Region& region)
{
- if (WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(m_page->mainFrame()->view())) {
+ if (!m_page->mainFrame()->isLocalFrame())
+ return;
+ if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) {
Vector<IntRect> rects = region.rects();
WebVector<WebRect> webRects(rects.size());
for (size_t i = 0; i < rects.size(); ++i)
@@ -124,14 +121,20 @@ void ScrollingCoordinator::setShouldHandleScrollGestureOnMainThreadRegion(const
void ScrollingCoordinator::notifyLayoutUpdated()
{
- // These computations need to happen after compositing is updated.
m_scrollGestureRegionIsDirty = true;
m_touchEventTargetRectsAreDirty = true;
+ m_shouldScrollOnMainThreadDirty = true;
}
-void ScrollingCoordinator::updateAfterCompositingChange()
+void ScrollingCoordinator::updateAfterCompositingChangeIfNeeded()
{
- TRACE_EVENT0("input", "ScrollingCoordinator::updateAfterCompositingChange");
+ if (!m_page->mainFrame()->isLocalFrame())
+ return;
+
+ if (!shouldUpdateAfterCompositingChange())
+ return;
+
+ TRACE_EVENT0("input", "ScrollingCoordinator::updateAfterCompositingChangeIfNeeded");
if (m_scrollGestureRegionIsDirty) {
// Compute the region of the page where we can't handle scroll gestures and mousewheel events
@@ -142,7 +145,7 @@ void ScrollingCoordinator::updateAfterCompositingChange()
// 2. Resize control areas, e.g. the small rect at the right bottom of div/textarea/iframe when
// CSS property "resize" is enabled.
// 3. Plugin areas.
- Region shouldHandleScrollGestureOnMainThreadRegion = computeShouldHandleScrollGestureOnMainThreadRegion(m_page->mainFrame(), IntPoint());
+ Region shouldHandleScrollGestureOnMainThreadRegion = computeShouldHandleScrollGestureOnMainThreadRegion(m_page->deprecatedLocalMainFrame(), IntPoint());
setShouldHandleScrollGestureOnMainThreadRegion(shouldHandleScrollGestureOnMainThreadRegion);
m_scrollGestureRegionIsDirty = false;
}
@@ -152,29 +155,46 @@ void ScrollingCoordinator::updateAfterCompositingChange()
m_touchEventTargetRectsAreDirty = false;
}
- FrameView* frameView = m_page->mainFrame()->view();
+ FrameView* frameView = m_page->deprecatedLocalMainFrame()->view();
bool frameIsScrollable = frameView && frameView->isScrollable();
- if (m_wasFrameScrollable != frameIsScrollable)
- updateShouldUpdateScrollLayerPositionOnMainThread();
+ if (m_shouldScrollOnMainThreadDirty || m_wasFrameScrollable != frameIsScrollable) {
+ setShouldUpdateScrollLayerPositionOnMainThread(mainThreadScrollingReasons());
+ m_shouldScrollOnMainThreadDirty = false;
+ }
m_wasFrameScrollable = frameIsScrollable;
+ // The mainFrame view doesn't get included in the FrameTree below, so we
+ // update its size separately.
+ if (WebLayer* scrollingWebLayer = frameView ? toWebLayer(frameView->layerForScrolling()) : 0) {
+ scrollingWebLayer->setBounds(frameView->contentsSize());
+ // If there is a fullscreen element, set the scroll clip layer to 0 so main frame won't scroll.
+ Document* mainFrameDocument = m_page->deprecatedLocalMainFrame()->document();
+ Element* fullscreenElement = FullscreenElementStack::fullscreenElementFrom(*mainFrameDocument);
+ if (fullscreenElement && fullscreenElement != mainFrameDocument->documentElement())
+ scrollingWebLayer->setScrollClipLayer(0);
+ else
+ scrollingWebLayer->setScrollClipLayer(toWebLayer(frameView->layerForContainer()));
+ }
+
const FrameTree& tree = m_page->mainFrame()->tree();
for (const Frame* child = tree.firstChild(); child; child = child->tree().nextSibling()) {
- if (WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(child->view()))
- scrollLayer->setBounds(child->view()->contentsSize());
+ if (!child->isLocalFrame())
+ continue;
+ if (WebLayer* scrollLayer = toWebLayer(toLocalFrame(child)->view()->layerForScrolling()))
+ scrollLayer->setBounds(toLocalFrame(child)->view()->contentsSize());
}
}
void ScrollingCoordinator::setLayerIsContainerForFixedPositionLayers(GraphicsLayer* layer, bool enable)
{
- if (WebLayer* scrollableLayer = scrollingWebLayerForGraphicsLayer(layer))
+ if (WebLayer* scrollableLayer = toWebLayer(layer))
scrollableLayer->setIsContainerForFixedPositionLayers(enable);
}
static void clearPositionConstraintExceptForLayer(GraphicsLayer* layer, GraphicsLayer* except)
{
- if (layer && layer != except && scrollingWebLayerForGraphicsLayer(layer))
- scrollingWebLayerForGraphicsLayer(layer)->setPositionConstraint(WebLayerPositionConstraint());
+ if (layer && layer != except && toWebLayer(layer))
+ toWebLayer(layer)->setPositionConstraint(WebLayerPositionConstraint());
}
static WebLayerPositionConstraint computePositionConstraint(const RenderLayer* layer)
@@ -200,13 +220,13 @@ void ScrollingCoordinator::updateLayerPositionConstraint(RenderLayer* layer)
{
ASSERT(layer->hasCompositedLayerMapping());
CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
- GraphicsLayer* mainLayer = compositedLayerMapping->childForSuperlayers();
+ GraphicsLayer* mainLayer = compositedLayerMapping->localRootForOwningLayer();
// Avoid unnecessary commits
clearPositionConstraintExceptForLayer(compositedLayerMapping->ancestorClippingLayer(), mainLayer);
clearPositionConstraintExceptForLayer(compositedLayerMapping->mainGraphicsLayer(), mainLayer);
- if (WebLayer* scrollableLayer = scrollingWebLayerForGraphicsLayer(mainLayer))
+ if (WebLayer* scrollableLayer = toWebLayer(mainLayer))
scrollableLayer->setPositionConstraint(computePositionConstraint(layer));
}
@@ -234,10 +254,10 @@ static PassOwnPtr<WebScrollbarLayer> createScrollbarLayer(Scrollbar* scrollbar)
return scrollbarLayer.release();
}
-PassOwnPtr<WebScrollbarLayer> ScrollingCoordinator::createSolidColorScrollbarLayer(ScrollbarOrientation orientation, int thumbThickness, bool isLeftSideVerticalScrollbar)
+PassOwnPtr<WebScrollbarLayer> ScrollingCoordinator::createSolidColorScrollbarLayer(ScrollbarOrientation orientation, int thumbThickness, int trackStart, bool isLeftSideVerticalScrollbar)
{
blink::WebScrollbar::Orientation webOrientation = (orientation == HorizontalScrollbar) ? blink::WebScrollbar::Horizontal : blink::WebScrollbar::Vertical;
- OwnPtr<WebScrollbarLayer> scrollbarLayer = adoptPtr(blink::Platform::current()->compositorSupport()->createSolidColorScrollbarLayer(webOrientation, thumbThickness, isLeftSideVerticalScrollbar));
+ OwnPtr<WebScrollbarLayer> scrollbarLayer = adoptPtr(blink::Platform::current()->compositorSupport()->createSolidColorScrollbarLayer(webOrientation, thumbThickness, trackStart, isLeftSideVerticalScrollbar));
GraphicsLayer::registerContentsLayer(scrollbarLayer->layer());
return scrollbarLayer.release();
}
@@ -250,7 +270,7 @@ static void detachScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer)
scrollbarGraphicsLayer->setDrawsContent(true);
}
-static void setupScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer, WebScrollbarLayer* scrollbarLayer, WebLayer* scrollLayer)
+static void setupScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer, WebScrollbarLayer* scrollbarLayer, WebLayer* scrollLayer, WebLayer* containerLayer)
{
ASSERT(scrollbarGraphicsLayer);
ASSERT(scrollbarLayer);
@@ -260,6 +280,7 @@ static void setupScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer, WebScroll
return;
}
scrollbarLayer->setScrollLayer(scrollLayer);
+ scrollbarLayer->setClipLayer(containerLayer);
scrollbarGraphicsLayer->setContentsToPlatformLayer(scrollbarLayer->layer());
scrollbarGraphicsLayer->setDrawsContent(false);
}
@@ -267,7 +288,7 @@ static void setupScrollbarLayer(GraphicsLayer* scrollbarGraphicsLayer, WebScroll
WebScrollbarLayer* ScrollingCoordinator::addWebScrollbarLayer(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, PassOwnPtr<blink::WebScrollbarLayer> scrollbarLayer)
{
ScrollbarMap& scrollbars = orientation == HorizontalScrollbar ? m_horizontalScrollbars : m_verticalScrollbars;
- return scrollbars.add(scrollableArea, scrollbarLayer).iterator->value.get();
+ return scrollbars.add(scrollableArea, scrollbarLayer).storedValue->value.get();
}
WebScrollbarLayer* ScrollingCoordinator::getWebScrollbarLayer(ScrollableArea* scrollableArea, ScrollbarOrientation orientation)
@@ -296,7 +317,10 @@ void ScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(ScrollableArea*
if (!isMainFrame && platformSupportsMainFrameOnly)
return;
- GraphicsLayer* scrollbarGraphicsLayer = orientation == HorizontalScrollbar ? horizontalScrollbarLayerForScrollableArea(scrollableArea) : verticalScrollbarLayerForScrollableArea(scrollableArea);
+ GraphicsLayer* scrollbarGraphicsLayer = orientation == HorizontalScrollbar
+ ? scrollableArea->layerForHorizontalScrollbar()
+ : scrollableArea->layerForVerticalScrollbar();
+
if (scrollbarGraphicsLayer) {
Scrollbar* scrollbar = orientation == HorizontalScrollbar ? scrollableArea->horizontalScrollbar() : scrollableArea->verticalScrollbar();
if (scrollbar->isCustomScrollbar()) {
@@ -306,12 +330,12 @@ void ScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(ScrollableArea*
WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, orientation);
if (!scrollbarLayer) {
- Settings* settings = m_page->mainFrame()->document()->settings();
+ Settings* settings = m_page->mainFrame()->settings();
OwnPtr<WebScrollbarLayer> webScrollbarLayer;
if (settings->useSolidColorScrollbars()) {
ASSERT(RuntimeEnabledFeatures::overlayScrollbarsEnabled());
- webScrollbarLayer = createSolidColorScrollbarLayer(orientation, scrollbar->theme()->thumbThickness(scrollbar), scrollableArea->shouldPlaceVerticalScrollbarOnLeft());
+ webScrollbarLayer = createSolidColorScrollbarLayer(orientation, scrollbar->theme()->thumbThickness(scrollbar), scrollbar->theme()->trackPosition(scrollbar), scrollableArea->shouldPlaceVerticalScrollbarOnLeft());
} else {
webScrollbarLayer = createScrollbarLayer(scrollbar);
}
@@ -325,64 +349,99 @@ void ScrollingCoordinator::scrollableAreaScrollbarLayerDidChange(ScrollableArea*
scrollbarGraphicsLayer->setContentsOpaque(isMainFrame && isOpaqueScrollbar);
scrollbarLayer->layer()->setOpaque(scrollbarGraphicsLayer->contentsOpaque());
- setupScrollbarLayer(scrollbarGraphicsLayer, scrollbarLayer, scrollingWebLayerForScrollableArea(scrollableArea));
+ WebLayer* scrollLayer = toWebLayer(scrollableArea->layerForScrolling());
+ WebLayer* containerLayer = toWebLayer(scrollableArea->layerForContainer());
+ setupScrollbarLayer(scrollbarGraphicsLayer, scrollbarLayer, scrollLayer, containerLayer);
} else
removeWebScrollbarLayer(scrollableArea, orientation);
}
bool ScrollingCoordinator::scrollableAreaScrollLayerDidChange(ScrollableArea* scrollableArea)
{
- GraphicsLayer* scrollLayer = scrollLayerForScrollableArea(scrollableArea);
+ GraphicsLayer* scrollLayer = scrollableArea->layerForScrolling();
+
if (scrollLayer) {
- bool isMainFrame = isForMainFrame(scrollableArea);
- scrollLayer->setScrollableArea(scrollableArea, isMainFrame);
+ ASSERT(m_page);
+ // With pinch virtual viewport we no longer need to special case the main frame.
+ bool pinchVirtualViewportEnabled = m_page->settings().pinchVirtualViewportEnabled();
+ bool layerScrollShouldFireGraphicsLayerDidScroll = isForMainFrame(scrollableArea) && !pinchVirtualViewportEnabled;
+ scrollLayer->setScrollableArea(scrollableArea, layerScrollShouldFireGraphicsLayerDidScroll);
}
- WebLayer* webLayer = scrollingWebLayerForScrollableArea(scrollableArea);
+ WebLayer* webLayer = toWebLayer(scrollableArea->layerForScrolling());
+ WebLayer* containerLayer = toWebLayer(scrollableArea->layerForContainer());
if (webLayer) {
- webLayer->setScrollable(true);
+ webLayer->setScrollClipLayer(containerLayer);
webLayer->setScrollPosition(IntPoint(scrollableArea->scrollPosition() - scrollableArea->minimumScrollPosition()));
- webLayer->setMaxScrollPosition(IntSize(scrollableArea->scrollSize(HorizontalScrollbar), scrollableArea->scrollSize(VerticalScrollbar)));
+ webLayer->setBounds(scrollableArea->contentsSize());
bool canScrollX = scrollableArea->userInputScrollable(HorizontalScrollbar);
bool canScrollY = scrollableArea->userInputScrollable(VerticalScrollbar);
webLayer->setUserScrollable(canScrollX, canScrollY);
}
if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, HorizontalScrollbar)) {
- GraphicsLayer* horizontalScrollbarLayer = horizontalScrollbarLayerForScrollableArea(scrollableArea);
+ GraphicsLayer* horizontalScrollbarLayer = scrollableArea->layerForHorizontalScrollbar();
if (horizontalScrollbarLayer)
- setupScrollbarLayer(horizontalScrollbarLayer, scrollbarLayer, webLayer);
+ setupScrollbarLayer(horizontalScrollbarLayer, scrollbarLayer, webLayer, containerLayer);
}
if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, VerticalScrollbar)) {
- GraphicsLayer* verticalScrollbarLayer = verticalScrollbarLayerForScrollableArea(scrollableArea);
+ GraphicsLayer* verticalScrollbarLayer = scrollableArea->layerForVerticalScrollbar();
if (verticalScrollbarLayer)
- setupScrollbarLayer(verticalScrollbarLayer, scrollbarLayer, webLayer);
+ setupScrollbarLayer(verticalScrollbarLayer, scrollbarLayer, webLayer, containerLayer);
}
return !!webLayer;
}
+typedef WTF::HashMap<const GraphicsLayer*, Vector<LayoutRect> > GraphicsLayerHitTestRects;
+
// In order to do a DFS cross-frame walk of the RenderLayer tree, we need to know which
// RenderLayers have child frames inside of them. This computes a mapping for the
// current frame which we can consult while walking the layers of that frame.
// Whenever we descend into a new frame, a new map will be created.
-typedef HashMap<const RenderLayer*, Vector<const Frame*> > LayerFrameMap;
-static void makeLayerChildFrameMap(const Frame* currentFrame, LayerFrameMap* map)
+typedef HashMap<const RenderLayer*, Vector<const LocalFrame*> > LayerFrameMap;
+static void makeLayerChildFrameMap(const LocalFrame* currentFrame, LayerFrameMap* map)
{
map->clear();
const FrameTree& tree = currentFrame->tree();
for (const Frame* child = tree.firstChild(); child; child = child->tree().nextSibling()) {
- const RenderLayer* containingLayer = child->ownerRenderer()->enclosingLayer();
+ if (!child->isLocalFrame())
+ continue;
+ const RenderObject* ownerRenderer = toLocalFrame(child)->ownerRenderer();
+ if (!ownerRenderer)
+ continue;
+ const RenderLayer* containingLayer = ownerRenderer->enclosingLayer();
LayerFrameMap::iterator iter = map->find(containingLayer);
if (iter == map->end())
- iter = map->add(containingLayer, Vector<const Frame*>()).iterator;
- iter->value.append(child);
+ map->add(containingLayer, Vector<const LocalFrame*>()).storedValue->value.append(toLocalFrame(child));
+ else
+ iter->value.append(toLocalFrame(child));
}
}
-static void convertLayerRectsToEnclosingCompositedLayerRecursive(
+// Return the enclosingCompositedLayerForRepaint for the given RenderLayer
+// including crossing frame boundaries.
+static const RenderLayer* enclosingCompositedLayer(const RenderLayer* layer)
+{
+ RenderLayer* compositedLayer = 0;
+ while (!compositedLayer) {
+ compositedLayer = layer->enclosingCompositingLayerForRepaint();
+ if (!compositedLayer) {
+ RenderObject* owner = layer->renderer()->frame()->ownerRenderer();
+ if (!owner)
+ break;
+ layer = owner->enclosingLayer();
+ }
+ }
+ // Since this machinery is used only when accelerated compositing is enabled, we expect
+ // that every layer should have an enclosing composited layer.
+ ASSERT(compositedLayer);
+ return compositedLayer;
+}
+
+static void projectRectsToGraphicsLayerSpaceRecursive(
const RenderLayer* curLayer,
const LayerHitTestRects& layerRects,
- LayerHitTestRects& compositorRects,
+ GraphicsLayerHitTestRects& graphicsRects,
RenderGeometryMap& geometryMap,
HashSet<const RenderLayer*>& layersWithRects,
LayerFrameMap& layerChildFrameMap)
@@ -391,27 +450,39 @@ static void convertLayerRectsToEnclosingCompositedLayerRecursive(
LayerHitTestRects::const_iterator layerIter = layerRects.find(curLayer);
if (layerIter != layerRects.end()) {
// Find the enclosing composited layer when it's in another document (for non-composited iframes).
- RenderLayer* compositedLayer = 0;
- for (const RenderLayer* layer = layerIter->key; !compositedLayer;) {
- compositedLayer = layer->enclosingCompositingLayerForRepaint();
- if (!compositedLayer) {
- RenderObject* owner = layer->renderer()->frame()->ownerRenderer();
- if (!owner)
- break;
- layer = owner->enclosingLayer();
- }
- }
- if (!compositedLayer) {
- // Since this machinery is used only when accelerated compositing is enabled, we expect
- // that every layer should have an enclosing composited layer.
- ASSERT_NOT_REACHED();
+ const RenderLayer* compositedLayer = enclosingCompositedLayer(layerIter->key);
+ if (!compositedLayer)
return;
+
+ // Find the appropriate GraphicsLayer for the composited RenderLayer.
+ GraphicsLayer* graphicsLayer;
+ LayoutSize extraOffset;
+ if (compositedLayer->compositingState() == PaintsIntoGroupedBacking) {
+ graphicsLayer = compositedLayer->groupedMapping()->squashingLayer();
+ extraOffset = -compositedLayer->offsetFromSquashingLayerOrigin();
+ } else {
+ ASSERT(compositedLayer->hasCompositedLayerMapping());
+ CompositedLayerMappingPtr compositedLayerMapping = compositedLayer->compositedLayerMapping();
+ // The origin for the graphics layer does not have to be the same
+ // as the composited layer (e.g. when a child layer has negative
+ // offset and paints into this layer), so when projecting rects to
+ // graphics layer space they have to be offset by the origin for
+ // the composited layer.
+ extraOffset = compositedLayerMapping->contentOffsetInCompositingLayer();
+ // If the layer is using composited scrolling, then it's the contents that these
+ // rects apply to.
+ graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
+ if (!graphicsLayer)
+ graphicsLayer = compositedLayerMapping->mainGraphicsLayer();
}
- LayerHitTestRects::iterator compIter = compositorRects.find(compositedLayer);
- if (compIter == compositorRects.end())
- compIter = compositorRects.add(compositedLayer, Vector<LayoutRect>()).iterator;
- // Transform each rect to the co-ordinate space of it's enclosing composited layer.
+ GraphicsLayerHitTestRects::iterator glIter = graphicsRects.find(graphicsLayer);
+ Vector<LayoutRect>* glRects;
+ if (glIter == graphicsRects.end())
+ glRects = &graphicsRects.add(graphicsLayer, Vector<LayoutRect>()).storedValue->value;
+ else
+ glRects = &glIter->value;
+ // Transform each rect to the co-ordinate space of the graphicsLayer.
for (size_t i = 0; i < layerIter->value.size(); ++i) {
LayoutRect rect = layerIter->value[i];
if (compositedLayer != curLayer) {
@@ -423,7 +494,8 @@ static void convertLayerRectsToEnclosingCompositedLayerRecursive(
if (compositedLayer->renderer()->hasOverflowClip())
rect.move(compositedLayer->renderBox()->scrolledContentOffset());
}
- compIter->value.append(rect);
+ rect.move(extraOffset);
+ glRects->append(rect);
}
}
@@ -431,7 +503,7 @@ static void convertLayerRectsToEnclosingCompositedLayerRecursive(
for (const RenderLayer* childLayer = curLayer->firstChild(); childLayer; childLayer = childLayer->nextSibling()) {
if (layersWithRects.contains(childLayer)) {
geometryMap.pushMappingsToAncestor(childLayer, curLayer);
- convertLayerRectsToEnclosingCompositedLayerRecursive(childLayer, layerRects, compositorRects, geometryMap, layersWithRects, layerChildFrameMap);
+ projectRectsToGraphicsLayerSpaceRecursive(childLayer, layerRects, graphicsRects, geometryMap, layersWithRects, layerChildFrameMap);
geometryMap.popMappingsToAncestor(curLayer);
}
}
@@ -440,22 +512,22 @@ static void convertLayerRectsToEnclosingCompositedLayerRecursive(
LayerFrameMap::iterator mapIter = layerChildFrameMap.find(curLayer);
if (mapIter != layerChildFrameMap.end()) {
for (size_t i = 0; i < mapIter->value.size(); i++) {
- const Frame* childFrame = mapIter->value[i];
+ const LocalFrame* childFrame = mapIter->value[i];
const RenderLayer* childLayer = childFrame->view()->renderView()->layer();
if (layersWithRects.contains(childLayer)) {
LayerFrameMap newLayerChildFrameMap;
makeLayerChildFrameMap(childFrame, &newLayerChildFrameMap);
geometryMap.pushMappingsToAncestor(childLayer, curLayer);
- convertLayerRectsToEnclosingCompositedLayerRecursive(childLayer, layerRects, compositorRects, geometryMap, layersWithRects, newLayerChildFrameMap);
+ projectRectsToGraphicsLayerSpaceRecursive(childLayer, layerRects, graphicsRects, geometryMap, layersWithRects, newLayerChildFrameMap);
geometryMap.popMappingsToAncestor(curLayer);
}
}
}
}
-static void convertLayerRectsToEnclosingCompositedLayer(Frame* mainFrame, const LayerHitTestRects& layerRects, LayerHitTestRects& compositorRects)
+static void projectRectsToGraphicsLayerSpace(LocalFrame* mainFrame, const LayerHitTestRects& layerRects, GraphicsLayerHitTestRects& graphicsRects)
{
- TRACE_EVENT0("input", "ScrollingCoordinator::convertLayerRectsToEnclosingCompositedLayer");
+ TRACE_EVENT0("input", "ScrollingCoordinator::projectRectsToGraphicsLayerSpace");
bool touchHandlerInChildFrame = false;
// We have a set of rects per RenderLayer, we need to map them to their bounding boxes in their
@@ -482,10 +554,12 @@ static void convertLayerRectsToEnclosingCompositedLayer(Frame* mainFrame, const
MapCoordinatesFlags flags = UseTransforms;
if (touchHandlerInChildFrame)
flags |= TraverseDocumentBoundaries;
+ RenderLayer* rootLayer = mainFrame->contentRenderer()->layer();
RenderGeometryMap geometryMap(flags);
+ geometryMap.pushMappingsToAncestor(rootLayer, 0);
LayerFrameMap layerChildFrameMap;
makeLayerChildFrameMap(mainFrame, &layerChildFrameMap);
- convertLayerRectsToEnclosingCompositedLayerRecursive(mainFrame->contentRenderer()->layer(), layerRects, compositorRects, geometryMap, layersWithRects, layerChildFrameMap);
+ projectRectsToGraphicsLayerSpaceRecursive(rootLayer, layerRects, graphicsRects, geometryMap, layersWithRects, layerChildFrameMap);
}
void ScrollingCoordinator::updateTouchEventTargetRectsIfNeeded()
@@ -502,6 +576,11 @@ void ScrollingCoordinator::updateTouchEventTargetRectsIfNeeded()
void ScrollingCoordinator::reset()
{
+ for (ScrollbarMap::iterator it = m_horizontalScrollbars.begin(); it != m_horizontalScrollbars.end(); ++it)
+ GraphicsLayer::unregisterContentsLayer(it->value->layer());
+ for (ScrollbarMap::iterator it = m_verticalScrollbars.begin(); it != m_verticalScrollbars.end(); ++it)
+ GraphicsLayer::unregisterContentsLayer(it->value->layer());
+
m_horizontalScrollbars.clear();
m_verticalScrollbars.clear();
m_layersWithTouchRects.clear();
@@ -514,63 +593,55 @@ void ScrollingCoordinator::reset()
// Note that in principle this could be called more often than computeTouchEventTargetRects, for
// example during a non-composited scroll (although that's not yet implemented - crbug.com/261307).
-void ScrollingCoordinator::setTouchEventTargetRects(const LayerHitTestRects& layerRects)
+void ScrollingCoordinator::setTouchEventTargetRects(LayerHitTestRects& layerRects)
{
TRACE_EVENT0("input", "ScrollingCoordinator::setTouchEventTargetRects");
- LayerHitTestRects compositorRects;
- convertLayerRectsToEnclosingCompositedLayer(m_page->mainFrame(), layerRects, compositorRects);
-
+ // Update the list of layers with touch hit rects.
HashSet<const RenderLayer*> oldLayersWithTouchRects;
m_layersWithTouchRects.swap(oldLayersWithTouchRects);
+ for (LayerHitTestRects::iterator it = layerRects.begin(); it != layerRects.end(); ++it) {
+ if (!it->value.isEmpty()) {
+ const RenderLayer* compositedLayer = enclosingCompositedLayer(it->key);
+ if (compositedLayer)
+ m_layersWithTouchRects.add(compositedLayer);
+ }
+ }
- for (LayerHitTestRects::const_iterator iter = compositorRects.begin(); iter != compositorRects.end(); ++iter) {
- const RenderLayer* layer = iter->key;
+ // Ensure we have an entry for each composited layer that previously had rects (so that old
+ // ones will get cleared out). Note that ideally we'd track this on GraphicsLayer instead of
+ // RenderLayer, but we have no good hook into the lifetime of a GraphicsLayer.
+ for (HashSet<const RenderLayer*>::iterator it = oldLayersWithTouchRects.begin(); it != oldLayersWithTouchRects.end(); ++it) {
+ if (!layerRects.contains(*it))
+ layerRects.add(*it, Vector<LayoutRect>());
+ }
+
+ GraphicsLayerHitTestRects graphicsLayerRects;
+ projectRectsToGraphicsLayerSpace(m_page->deprecatedLocalMainFrame(), layerRects, graphicsLayerRects);
+
+ for (GraphicsLayerHitTestRects::const_iterator iter = graphicsLayerRects.begin(); iter != graphicsLayerRects.end(); ++iter) {
+ const GraphicsLayer* graphicsLayer = iter->key;
WebVector<WebRect> webRects(iter->value.size());
for (size_t i = 0; i < iter->value.size(); ++i)
webRects[i] = enclosingIntRect(iter->value[i]);
- // This should be ensured by convertLayerRectsToEnclosingCompositedLayer above.
- ASSERT(layer->hasCompositedLayerMapping());
- CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
- // If the layer is using composited scrolling, then it's the contents that these
- // rects apply to.
- GraphicsLayer* graphicsLayer = compositedLayerMapping->scrollingContentsLayer();
- if (!graphicsLayer)
- graphicsLayer = compositedLayerMapping->mainGraphicsLayer();
graphicsLayer->platformLayer()->setTouchEventHandlerRegion(webRects);
- oldLayersWithTouchRects.remove(layer);
- m_layersWithTouchRects.add(layer);
- }
-
- // If there are any layers left that we haven't updated, clear them out.
- for (HashSet<const RenderLayer*>::iterator it = oldLayersWithTouchRects.begin(); it != oldLayersWithTouchRects.end(); ++it) {
- // FIXME: This is a bug. What's happening here is that we're clearing touch regions for
- // layers that we didn't visit above. That assumes a 1:1 mapping between RenderLayer and
- // the graphics layer that owns the touch rects. This is false in the case of
- // HasOwnBackingButPaintsIntoAncestor and will be extra-false in the world of squashing.
- if ((*it)->hasCompositedLayerMapping()) {
- GraphicsLayer* graphicsLayer = (*it)->compositedLayerMapping()->scrollingContentsLayer();
- if (!graphicsLayer)
- graphicsLayer = (*it)->compositedLayerMapping()->mainGraphicsLayer();
- graphicsLayer->platformLayer()->setTouchEventHandlerRegion(WebVector<WebRect>());
- }
}
}
-void ScrollingCoordinator::touchEventTargetRectsDidChange(const Document*)
+void ScrollingCoordinator::touchEventTargetRectsDidChange()
{
if (!touchHitTestingEnabled())
return;
// Wait until after layout to update.
- if (m_page->mainFrame()->view()->needsLayout())
+ if (!m_page->deprecatedLocalMainFrame()->view() || m_page->deprecatedLocalMainFrame()->view()->needsLayout())
return;
// FIXME: scheduleAnimation() is just a method of forcing the compositor to realize that it
// needs to commit here. We should expose a cleaner API for this.
- RenderView* renderView = m_page->mainFrame()->contentRenderer();
- if (renderView && renderView->compositor() && renderView->compositor()->inCompositingMode())
- m_page->mainFrame()->view()->scheduleAnimation();
+ RenderView* renderView = m_page->deprecatedLocalMainFrame()->contentRenderer();
+ if (renderView && renderView->compositor() && renderView->compositor()->staleInCompositingMode())
+ m_page->deprecatedLocalMainFrame()->view()->scheduleAnimation();
m_touchEventTargetRectsAreDirty = true;
}
@@ -579,7 +650,7 @@ void ScrollingCoordinator::updateScrollParentForGraphicsLayer(GraphicsLayer* chi
{
WebLayer* scrollParentWebLayer = 0;
if (parent && parent->hasCompositedLayerMapping())
- scrollParentWebLayer = scrollingWebLayerForGraphicsLayer(parent->compositedLayerMapping()->parentForSublayers());
+ scrollParentWebLayer = toWebLayer(parent->compositedLayerMapping()->scrollingContentsLayer());
child->setScrollParent(scrollParentWebLayer);
}
@@ -588,7 +659,7 @@ void ScrollingCoordinator::updateClipParentForGraphicsLayer(GraphicsLayer* child
{
WebLayer* clipParentWebLayer = 0;
if (parent && parent->hasCompositedLayerMapping())
- clipParentWebLayer = scrollingWebLayerForGraphicsLayer(parent->compositedLayerMapping()->parentForSublayers());
+ clipParentWebLayer = toWebLayer(parent->compositedLayerMapping()->parentForSublayers());
child->setClipParent(clipParentWebLayer);
}
@@ -598,29 +669,53 @@ void ScrollingCoordinator::willDestroyRenderLayer(RenderLayer* layer)
m_layersWithTouchRects.remove(layer);
}
-void ScrollingCoordinator::setWheelEventHandlerCount(unsigned count)
+void ScrollingCoordinator::updateHaveWheelEventHandlers()
{
- if (WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(m_page->mainFrame()->view()))
- scrollLayer->setHaveWheelEventHandlers(count > 0);
+ ASSERT(isMainThread());
+ ASSERT(m_page);
+ if (!m_page->mainFrame()->isLocalFrame() || !m_page->deprecatedLocalMainFrame()->view())
+ return;
+
+ if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) {
+ bool haveHandlers = m_page->frameHost().eventHandlerRegistry().hasEventHandlers(EventHandlerRegistry::WheelEvent);
+ scrollLayer->setHaveWheelEventHandlers(haveHandlers);
+ }
}
-void ScrollingCoordinator::recomputeWheelEventHandlerCountForFrameView(FrameView*)
+void ScrollingCoordinator::updateHaveScrollEventHandlers()
{
- setWheelEventHandlerCount(computeCurrentWheelEventHandlerCount());
+ ASSERT(isMainThread());
+ ASSERT(m_page);
+ if (!m_page->mainFrame()->isLocalFrame() || !m_page->deprecatedLocalMainFrame()->view())
+ return;
+
+ // Currently the compositor only cares whether there are scroll handlers anywhere on the page
+ // instead on a per-layer basis. We therefore only update this information for the root
+ // scrolling layer.
+ if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) {
+ bool haveHandlers = m_page->frameHost().eventHandlerRegistry().hasEventHandlers(EventHandlerRegistry::ScrollEvent);
+ scrollLayer->setHaveScrollEventHandlers(haveHandlers);
+ }
}
void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons reasons)
{
- if (WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(m_page->mainFrame()->view())) {
+ if (!m_page->mainFrame()->isLocalFrame())
+ return;
+ if (WebLayer* scrollLayer = toWebLayer(m_page->deprecatedLocalMainFrame()->view()->layerForScrolling())) {
m_lastMainThreadScrollingReasons = reasons;
scrollLayer->setShouldScrollOnMainThread(reasons);
}
}
-void ScrollingCoordinator::pageDestroyed()
+void ScrollingCoordinator::willBeDestroyed()
{
ASSERT(m_page);
m_page = 0;
+ for (ScrollbarMap::iterator it = m_horizontalScrollbars.begin(); it != m_horizontalScrollbars.end(); ++it)
+ GraphicsLayer::unregisterContentsLayer(it->value->layer());
+ for (ScrollbarMap::iterator it = m_verticalScrollbars.begin(); it != m_verticalScrollbars.end(); ++it)
+ GraphicsLayer::unregisterContentsLayer(it->value->layer());
}
bool ScrollingCoordinator::coordinatesScrollingForFrameView(FrameView* frameView) const
@@ -632,14 +727,17 @@ bool ScrollingCoordinator::coordinatesScrollingForFrameView(FrameView* frameView
if (&frameView->frame() != m_page->mainFrame())
return false;
+ if (!m_page->mainFrame()->isLocalFrame())
+ return false;
+
// We currently only support composited mode.
- RenderView* renderView = m_page->mainFrame()->contentRenderer();
+ RenderView* renderView = m_page->deprecatedLocalMainFrame()->contentRenderer();
if (!renderView)
return false;
return renderView->usesCompositing();
}
-Region ScrollingCoordinator::computeShouldHandleScrollGestureOnMainThreadRegion(const Frame* frame, const IntPoint& frameLocation) const
+Region ScrollingCoordinator::computeShouldHandleScrollGestureOnMainThreadRegion(const LocalFrame* frame, const IntPoint& frameLocation) const
{
Region shouldHandleScrollGestureOnMainThreadRegion;
FrameView* frameView = frame->view();
@@ -680,15 +778,17 @@ Region ScrollingCoordinator::computeShouldHandleScrollGestureOnMainThreadRegion(
if (!(*it)->isPluginView())
continue;
- PluginView* pluginView = toPluginView((*it).get());
+ PluginView* pluginView = toPluginView(it->get());
if (pluginView->wantsWheelEvents())
shouldHandleScrollGestureOnMainThreadRegion.unite(pluginView->frameRect());
}
}
const FrameTree& tree = frame->tree();
- for (Frame* subFrame = tree.firstChild(); subFrame; subFrame = subFrame->tree().nextSibling())
- shouldHandleScrollGestureOnMainThreadRegion.unite(computeShouldHandleScrollGestureOnMainThreadRegion(subFrame, offset));
+ for (Frame* subFrame = tree.firstChild(); subFrame; subFrame = subFrame->tree().nextSibling()) {
+ if (subFrame->isLocalFrame())
+ shouldHandleScrollGestureOnMainThreadRegion.unite(computeShouldHandleScrollGestureOnMainThreadRegion(toLocalFrame(subFrame), offset));
+ }
return shouldHandleScrollGestureOnMainThreadRegion;
}
@@ -705,13 +805,19 @@ static void accumulateDocumentTouchEventTargetRects(LayerHitTestRects& rects, co
// then we can quickly mark the entire document and skip looking at any other handlers.
// Note that technically a handler on the body doesn't cover the whole document, but it's
// reasonable to be conservative and report the whole document anyway.
- for (TouchEventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) {
- Node* target = iter->key;
- if (target == document || target == document->documentElement() || target == document->body()) {
- if (RenderObject* renderer = document->renderer()) {
- renderer->computeLayerHitTestRects(rects);
+ //
+ // Fullscreen HTML5 video when OverlayFullscreenVideo is enabled is implemented by replacing the
+ // root cc::layer with the video layer so doing this optimization causes the compositor to think
+ // that there are no handlers, therefore skip it.
+ if (!document->renderView()->compositor()->inOverlayFullscreenVideo()) {
+ for (TouchEventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter) {
+ Node* target = iter->key;
+ if (target == document || target == document->documentElement() || target == document->body()) {
+ if (RenderView* rendererView = document->renderView()) {
+ rendererView->computeLayerHitTestRects(rects);
+ }
+ return;
}
- return;
}
}
@@ -720,8 +826,7 @@ static void accumulateDocumentTouchEventTargetRects(LayerHitTestRects& rects, co
if (!target->inDocument())
continue;
- if (target->isDocumentNode()) {
- ASSERT(target != document);
+ if (target->isDocumentNode() && target != document) {
accumulateDocumentTouchEventTargetRects(rects, toDocument(target));
} else if (RenderObject* renderer = target->renderer()) {
// If the set also contains one of our ancestor nodes then processing
@@ -731,8 +836,24 @@ static void accumulateDocumentTouchEventTargetRects(LayerHitTestRects& rects, co
if (targets->contains(ancestor))
hasTouchEventTargetAncestor = true;
}
- if (!hasTouchEventTargetAncestor)
+ if (!hasTouchEventTargetAncestor) {
+ // Walk up the tree to the outermost non-composited scrollable layer.
+ RenderLayer* enclosingNonCompositedScrollLayer = 0;
+ for (RenderLayer* parent = renderer->enclosingLayer(); parent && parent->compositingState() == NotComposited; parent = parent->parent()) {
+ if (parent->scrollsOverflow())
+ enclosingNonCompositedScrollLayer = parent;
+ }
+
+ // Report the whole non-composited scroll layer as a touch hit rect because any
+ // rects inside of it may move around relative to their enclosing composited layer
+ // without causing the rects to be recomputed. Non-composited scrolling occurs on
+ // the main thread, so we're not getting much benefit from compositor touch hit
+ // testing in this case anyway.
+ if (enclosingNonCompositedScrollLayer)
+ enclosingNonCompositedScrollLayer->computeSelfHitTestRects(rects);
+
renderer->computeLayerHitTestRects(rects);
+ }
}
}
@@ -743,33 +864,13 @@ void ScrollingCoordinator::computeTouchEventTargetRects(LayerHitTestRects& rects
TRACE_EVENT0("input", "ScrollingCoordinator::computeTouchEventTargetRects");
ASSERT(touchHitTestingEnabled());
- Document* document = m_page->mainFrame()->document();
+ Document* document = m_page->deprecatedLocalMainFrame()->document();
if (!document || !document->view())
return;
accumulateDocumentTouchEventTargetRects(rects, document);
}
-unsigned ScrollingCoordinator::computeCurrentWheelEventHandlerCount()
-{
- unsigned wheelEventHandlerCount = 0;
-
- for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
- if (frame->document())
- wheelEventHandlerCount += WheelController::from(frame->document())->wheelEventHandlerCount();
- }
-
- return wheelEventHandlerCount;
-}
-
-void ScrollingCoordinator::frameViewWheelEventHandlerCountChanged(FrameView* frameView)
-{
- ASSERT(isMainThread());
- ASSERT(m_page);
-
- recomputeWheelEventHandlerCountForFrameView(frameView);
-}
-
void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView* frameView)
{
ASSERT(isMainThread());
@@ -778,7 +879,7 @@ void ScrollingCoordinator::frameViewHasSlowRepaintObjectsDidChange(FrameView* fr
if (!coordinatesScrollingForFrameView(frameView))
return;
- updateShouldUpdateScrollLayerPositionOnMainThread();
+ m_shouldScrollOnMainThreadDirty = true;
}
void ScrollingCoordinator::frameViewFixedObjectsDidChange(FrameView* frameView)
@@ -789,40 +890,12 @@ void ScrollingCoordinator::frameViewFixedObjectsDidChange(FrameView* frameView)
if (!coordinatesScrollingForFrameView(frameView))
return;
- updateShouldUpdateScrollLayerPositionOnMainThread();
-}
-
-GraphicsLayer* ScrollingCoordinator::scrollLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
- return scrollableArea->layerForScrolling();
-}
-
-GraphicsLayer* ScrollingCoordinator::horizontalScrollbarLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
- return scrollableArea->layerForHorizontalScrollbar();
-}
-
-GraphicsLayer* ScrollingCoordinator::verticalScrollbarLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
- return scrollableArea->layerForVerticalScrollbar();
+ m_shouldScrollOnMainThreadDirty = true;
}
bool ScrollingCoordinator::isForMainFrame(ScrollableArea* scrollableArea) const
{
- return scrollableArea == m_page->mainFrame()->view();
-}
-
-GraphicsLayer* ScrollingCoordinator::scrollLayerForFrameView(FrameView* frameView)
-{
- RenderView* renderView = frameView->frame().contentRenderer();
- if (!renderView)
- return 0;
- return renderView->compositor()->scrollLayer();
-}
-
-GraphicsLayer* ScrollingCoordinator::counterScrollingLayerForFrameView(FrameView*)
-{
- return 0;
+ return m_page->mainFrame()->isLocalFrame() ? scrollableArea == m_page->deprecatedLocalMainFrame()->view() : false;
}
void ScrollingCoordinator::frameViewRootLayerDidChange(FrameView* frameView)
@@ -834,8 +907,8 @@ void ScrollingCoordinator::frameViewRootLayerDidChange(FrameView* frameView)
return;
notifyLayoutUpdated();
- recomputeWheelEventHandlerCountForFrameView(frameView);
- updateShouldUpdateScrollLayerPositionOnMainThread();
+ updateHaveWheelEventHandlers();
+ updateHaveScrollEventHandlers();
}
#if OS(MACOSX)
@@ -846,7 +919,7 @@ void ScrollingCoordinator::handleWheelEventPhase(PlatformWheelEventPhase phase)
if (!m_page)
return;
- FrameView* frameView = m_page->mainFrame()->view();
+ FrameView* frameView = m_page->deprecatedLocalMainFrame()->view();
if (!frameView)
return;
@@ -882,7 +955,9 @@ MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() co
// The main thread scrolling reasons are applicable to scrolls of the main
// frame. If it does not exist or if it is not scrollable, there is no
// reason to force main thread scrolling.
- FrameView* frameView = m_page->mainFrame()->view();
+ if (!m_page->mainFrame()->isLocalFrame())
+ return static_cast<MainThreadScrollingReasons>(0);
+ FrameView* frameView = m_page->deprecatedLocalMainFrame()->view();
if (!frameView)
return static_cast<MainThreadScrollingReasons>(0);
@@ -896,11 +971,6 @@ MainThreadScrollingReasons ScrollingCoordinator::mainThreadScrollingReasons() co
return mainThreadScrollingReasons;
}
-void ScrollingCoordinator::updateShouldUpdateScrollLayerPositionOnMainThread()
-{
- setShouldUpdateScrollLayerPositionOnMainThread(mainThreadScrollingReasons());
-}
-
String ScrollingCoordinator::mainThreadScrollingReasonsAsText(MainThreadScrollingReasons reasons)
{
StringBuilder stringBuilder;
@@ -919,14 +989,20 @@ String ScrollingCoordinator::mainThreadScrollingReasonsAsText(MainThreadScrollin
String ScrollingCoordinator::mainThreadScrollingReasonsAsText() const
{
+ ASSERT(m_page->deprecatedLocalMainFrame()->document()->lifecycle().state() >= DocumentLifecycle::CompositingClean);
return mainThreadScrollingReasonsAsText(m_lastMainThreadScrollingReasons);
}
-bool ScrollingCoordinator::frameViewIsScrollableIsDirty() const
+bool ScrollingCoordinator::frameViewIsDirty() const
{
- FrameView* frameView = m_page->mainFrame()->view();
+ FrameView* frameView = m_page->mainFrame()->isLocalFrame() ? m_page->deprecatedLocalMainFrame()->view() : 0;
bool frameIsScrollable = frameView && frameView->isScrollable();
- return frameIsScrollable != m_wasFrameScrollable;
+ if (frameIsScrollable != m_wasFrameScrollable)
+ return true;
+
+ if (WebLayer* scrollLayer = frameView ? toWebLayer(frameView->layerForScrolling()) : 0)
+ return blink::WebSize(frameView->contentsSize()) != scrollLayer->bounds();
+ return false;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h b/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h
index 3acfe9ad895..7d5eea09d03 100644
--- a/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h
+++ b/chromium/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinator.h
@@ -42,7 +42,7 @@ namespace WebCore {
typedef unsigned MainThreadScrollingReasons;
class Document;
-class Frame;
+class LocalFrame;
class FrameView;
class GraphicsLayer;
class Page;
@@ -50,12 +50,13 @@ class Region;
class ScrollableArea;
class ViewportConstraints;
-class ScrollingCoordinator : public RefCounted<ScrollingCoordinator> {
+class ScrollingCoordinator {
public:
- static PassRefPtr<ScrollingCoordinator> create(Page*);
~ScrollingCoordinator();
- void pageDestroyed();
+ static PassOwnPtr<ScrollingCoordinator> create(Page*);
+
+ void willBeDestroyed();
// Return whether this scrolling coordinator handles scrolling for the given frame view.
bool coordinatesScrollingForFrameView(FrameView*) const;
@@ -63,14 +64,10 @@ public:
// Called when any frame has done its layout.
void notifyLayoutUpdated();
- // Should be called after compositing has been updated.
- void updateAfterCompositingChange();
-
- bool needsToUpdateAfterCompositingChange() const { return m_scrollGestureRegionIsDirty || m_touchEventTargetRectsAreDirty || frameViewIsScrollableIsDirty(); }
+ void updateAfterCompositingChangeIfNeeded();
- // Should be called whenever a wheel event handler is added or removed in the
- // frame view's underlying document.
- void frameViewWheelEventHandlerCountChanged(FrameView*);
+ void updateHaveWheelEventHandlers();
+ void updateHaveScrollEventHandlers();
// Should be called whenever the slow repaint objects counter changes between zero and one.
void frameViewHasSlowRepaintObjectsDidChange(FrameView*);
@@ -95,7 +92,7 @@ public:
MainThreadScrollingReasons mainThreadScrollingReasons() const;
bool shouldUpdateScrollLayerPositionOnMainThread() const { return mainThreadScrollingReasons() != 0; }
- PassOwnPtr<blink::WebScrollbarLayer> createSolidColorScrollbarLayer(ScrollbarOrientation, int thumbThickness, bool isLeftSideVerticalScrollbar);
+ PassOwnPtr<blink::WebScrollbarLayer> createSolidColorScrollbarLayer(ScrollbarOrientation, int thumbThickness, int trackStart, bool isLeftSideVerticalScrollbar);
void willDestroyScrollableArea(ScrollableArea*);
// Returns true if the coordinator handled this change.
@@ -103,7 +100,7 @@ public:
void scrollableAreaScrollbarLayerDidChange(ScrollableArea*, ScrollbarOrientation);
void setLayerIsContainerForFixedPositionLayers(GraphicsLayer*, bool);
void updateLayerPositionConstraint(RenderLayer*);
- void touchEventTargetRectsDidChange(const Document*);
+ void touchEventTargetRectsDidChange();
void willDestroyRenderLayer(RenderLayer*);
void updateScrollParentForGraphicsLayer(GraphicsLayer* child, RenderLayer* parent);
@@ -111,7 +108,7 @@ public:
static String mainThreadScrollingReasonsAsText(MainThreadScrollingReasons);
String mainThreadScrollingReasonsAsText() const;
- Region computeShouldHandleScrollGestureOnMainThreadRegion(const Frame*, const IntPoint& frameLocation) const;
+ Region computeShouldHandleScrollGestureOnMainThreadRegion(const LocalFrame*, const IntPoint& frameLocation) const;
void updateTouchEventTargetRectsIfNeeded();
@@ -122,41 +119,32 @@ public:
protected:
explicit ScrollingCoordinator(Page*);
- static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea*);
- static GraphicsLayer* horizontalScrollbarLayerForScrollableArea(ScrollableArea*);
- static GraphicsLayer* verticalScrollbarLayerForScrollableArea(ScrollableArea*);
bool isForMainFrame(ScrollableArea*) const;
- unsigned computeCurrentWheelEventHandlerCount();
- GraphicsLayer* scrollLayerForFrameView(FrameView*);
- GraphicsLayer* counterScrollingLayerForFrameView(FrameView*);
-
Page* m_page;
// Dirty flags used to idenfity what really needs to be computed after compositing is updated.
bool m_scrollGestureRegionIsDirty;
bool m_touchEventTargetRectsAreDirty;
+ bool m_shouldScrollOnMainThreadDirty;
private:
- void recomputeWheelEventHandlerCountForFrameView(FrameView*);
+ bool shouldUpdateAfterCompositingChange() const { return m_scrollGestureRegionIsDirty || m_touchEventTargetRectsAreDirty || frameViewIsDirty(); }
+
void setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons);
bool hasVisibleSlowRepaintViewportConstrainedObjects(FrameView*) const;
- void updateShouldUpdateScrollLayerPositionOnMainThread();
-
- static blink::WebLayer* scrollingWebLayerForScrollableArea(ScrollableArea*);
bool touchHitTestingEnabled() const;
void setShouldHandleScrollGestureOnMainThreadRegion(const Region&);
- void setTouchEventTargetRects(const LayerHitTestRects&);
+ void setTouchEventTargetRects(LayerHitTestRects&);
void computeTouchEventTargetRects(LayerHitTestRects&);
- void setWheelEventHandlerCount(unsigned);
blink::WebScrollbarLayer* addWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation, PassOwnPtr<blink::WebScrollbarLayer>);
blink::WebScrollbarLayer* getWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation);
void removeWebScrollbarLayer(ScrollableArea*, ScrollbarOrientation);
- bool frameViewIsScrollableIsDirty() const;
+ bool frameViewIsDirty() const;
typedef HashMap<ScrollableArea*, OwnPtr<blink::WebScrollbarLayer> > ScrollbarMap;
ScrollbarMap m_horizontalScrollbars;
diff --git a/chromium/third_party/WebKit/Source/core/platform/CryptoResult.h b/chromium/third_party/WebKit/Source/core/platform/CryptoResult.h
deleted file mode 100644
index 45aaef5945b..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/CryptoResult.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CryptoResult_h
-#define CryptoResult_h
-
-#include "public/platform/WebCrypto.h"
-#include "wtf/ThreadSafeRefCounted.h"
-
-namespace WebCore {
-
-// Receives notification of completion of the crypto operation.
-class CryptoResult : public ThreadSafeRefCounted<CryptoResult> {
-public:
- virtual ~CryptoResult() { }
-
- virtual void completeWithError() = 0;
- virtual void completeWithBuffer(const blink::WebArrayBuffer&) = 0;
- virtual void completeWithBoolean(bool) = 0;
- virtual void completeWithKey(const blink::WebCryptoKey&) = 0;
- virtual void completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink::WebCryptoKey& privateKey) = 0;
-
- blink::WebCryptoResult result()
- {
- return blink::WebCryptoResult(this);
- }
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/platform/DEPS b/chromium/third_party/WebKit/Source/core/platform/DEPS
deleted file mode 100644
index 8f464900d63..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/DEPS
+++ /dev/null
@@ -1,15 +0,0 @@
-# This file dictates which directories can be included in the source files of this folder.
-# Please run Tools/Scripts/check-blink-deps after modifying this file.
-
-include_rules = [
- "-core",
- "+core/platform",
- "+dl",
- "+skia",
- "+third_party",
- # platform/ shouldn't depends on core/ but unfortunately does (crbug.com/258901).
- # Please don't add anything to this list of exceptions.
- "!core/dom",
- "!core/fileapi",
- "!core/rendering",
-]
diff --git a/chromium/third_party/WebKit/Source/core/platform/DragImage.cpp b/chromium/third_party/WebKit/Source/core/platform/DragImage.cpp
deleted file mode 100644
index f8fe7734277..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/DragImage.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/DragImage.h"
-
-#include "platform/fonts/Font.h"
-#include "platform/fonts/FontCache.h"
-#include "platform/fonts/FontDescription.h"
-#include "platform/fonts/FontMetrics.h"
-#include "platform/geometry/FloatPoint.h"
-#include "platform/geometry/FloatRect.h"
-#include "platform/geometry/IntPoint.h"
-#include "platform/graphics/BitmapImage.h"
-#include "platform/graphics/Color.h"
-#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/Image.h"
-#include "platform/graphics/ImageBuffer.h"
-#include "platform/graphics/skia/NativeImageSkia.h"
-#include "platform/text/StringTruncator.h"
-#include "platform/text/TextRun.h"
-#include "platform/transforms/AffineTransform.h"
-#include "platform/weborigin/KURL.h"
-#include "skia/ext/image_operations.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkMatrix.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/WTFString.h"
-
-#include <algorithm>
-
-namespace WebCore {
-
-const float kDragLabelBorderX = 4;
-// Keep border_y in synch with DragController::LinkDragBorderInset.
-const float kDragLabelBorderY = 2;
-const float kLabelBorderYOffset = 2;
-
-const float kMaxDragLabelWidth = 300;
-const float kMaxDragLabelStringWidth = (kMaxDragLabelWidth - 2 * kDragLabelBorderX);
-
-const float kDragLinkLabelFontSize = 11;
-const float kDragLinkUrlFontSize = 10;
-
-PassOwnPtr<DragImage> DragImage::create(Image* image, RespectImageOrientationEnum shouldRespectImageOrientation, float deviceScaleFactor)
-{
- if (!image)
- return nullptr;
-
- RefPtr<NativeImageSkia> bitmap = image->nativeImageForCurrentFrame();
- if (!bitmap)
- return nullptr;
-
- if (image->isBitmapImage()) {
- ImageOrientation orientation = DefaultImageOrientation;
- BitmapImage* bitmapImage = toBitmapImage(image);
- IntSize sizeRespectingOrientation = bitmapImage->sizeRespectingOrientation();
-
- if (shouldRespectImageOrientation == RespectImageOrientation)
- orientation = bitmapImage->currentFrameOrientation();
-
- if (orientation != DefaultImageOrientation) {
- FloatRect destRect(FloatPoint(), sizeRespectingOrientation);
- if (orientation.usesWidthAsHeight())
- destRect = destRect.transposedRect();
-
- SkBitmap skBitmap;
- skBitmap.setConfig(
- SkBitmap::kARGB_8888_Config, sizeRespectingOrientation.width(), sizeRespectingOrientation.height());
- if (!skBitmap.allocPixels())
- return nullptr;
-
- SkCanvas canvas(skBitmap);
- canvas.concat(affineTransformToSkMatrix(orientation.transformFromDefault(sizeRespectingOrientation)));
- canvas.drawBitmapRect(bitmap->bitmap(), 0, destRect);
-
- return adoptPtr(new DragImage(skBitmap, deviceScaleFactor));
- }
- }
-
- SkBitmap skBitmap;
- if (!bitmap->bitmap().copyTo(&skBitmap, SkBitmap::kARGB_8888_Config))
- return nullptr;
- return adoptPtr(new DragImage(skBitmap, deviceScaleFactor));
-}
-
-static Font deriveDragLabelFont(int size, FontWeight fontWeight, const FontDescription& systemFont)
-{
- FontDescription description = systemFont;
- description.setWeight(fontWeight);
- description.setSpecifiedSize(size);
- description.setComputedSize(size);
- Font result(description, 0, 0);
- result.update(0);
- return result;
-}
-
-PassOwnPtr<DragImage> DragImage::create(const KURL& url, const String& inLabel, const FontDescription& systemFont, float deviceScaleFactor)
-{
- const Font labelFont = deriveDragLabelFont(kDragLinkLabelFontSize, FontWeightBold, systemFont);
- const Font urlFont = deriveDragLabelFont(kDragLinkUrlFontSize, FontWeightNormal, systemFont);
- FontCachePurgePreventer fontCachePurgePreventer;
-
- bool drawURLString = true;
- bool clipURLString = false;
- bool clipLabelString = false;
-
- String urlString = url.string();
- String label = inLabel;
- if (label.isEmpty()) {
- drawURLString = false;
- label = urlString;
- }
-
- // First step is drawing the link drag image width.
- TextRun labelRun(label.impl());
- TextRun urlRun(urlString.impl());
- IntSize labelSize(labelFont.width(labelRun), labelFont.fontMetrics().ascent() + labelFont.fontMetrics().descent());
-
- if (labelSize.width() > kMaxDragLabelStringWidth) {
- labelSize.setWidth(kMaxDragLabelStringWidth);
- clipLabelString = true;
- }
-
- IntSize urlStringSize;
- IntSize imageSize(labelSize.width() + kDragLabelBorderX * 2, labelSize.height() + kDragLabelBorderY * 2);
-
- if (drawURLString) {
- urlStringSize.setWidth(urlFont.width(urlRun));
- urlStringSize.setHeight(urlFont.fontMetrics().ascent() + urlFont.fontMetrics().descent());
- imageSize.setHeight(imageSize.height() + urlStringSize.height());
- if (urlStringSize.width() > kMaxDragLabelStringWidth) {
- imageSize.setWidth(kMaxDragLabelWidth);
- clipURLString = true;
- } else
- imageSize.setWidth(std::max(labelSize.width(), urlStringSize.width()) + kDragLabelBorderX * 2);
- }
-
- // We now know how big the image needs to be, so we create and
- // fill the background
- IntSize scaledImageSize = imageSize;
- scaledImageSize.scale(deviceScaleFactor);
- OwnPtr<ImageBuffer> buffer(ImageBuffer::create(scaledImageSize));
- if (!buffer)
- return nullptr;
- buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
-
- const float DragLabelRadius = 5;
- const IntSize radii(DragLabelRadius, DragLabelRadius);
- IntRect rect(IntPoint(), imageSize);
- const Color backgroundColor(140, 140, 140);
- buffer->context()->fillRoundedRect(rect, radii, radii, radii, radii, backgroundColor);
-
- // Draw the text
- if (drawURLString) {
- if (clipURLString)
- urlString = StringTruncator::centerTruncate(urlString, imageSize.width() - (kDragLabelBorderX * 2.0f), urlFont, StringTruncator::EnableRoundingHacks);
- IntPoint textPos(kDragLabelBorderX, imageSize.height() - (kLabelBorderYOffset + urlFont.fontMetrics().descent()));
- TextRun textRun(urlString);
- buffer->context()->drawText(urlFont, TextRunPaintInfo(textRun), textPos);
- }
-
- if (clipLabelString)
- label = StringTruncator::rightTruncate(label, imageSize.width() - (kDragLabelBorderX * 2.0f), labelFont, StringTruncator::EnableRoundingHacks);
-
- IntPoint textPos(kDragLabelBorderX, kDragLabelBorderY + labelFont.pixelSize());
- TextRun textRun(label);
- buffer->context()->drawText(urlFont, TextRunPaintInfo(textRun), textPos);
-
- RefPtr<Image> image = buffer->copyImage();
- return DragImage::create(image.get(), DoNotRespectImageOrientation, deviceScaleFactor);
-}
-
-DragImage::DragImage(const SkBitmap& bitmap, float resolutionScale)
- : m_bitmap(bitmap)
- , m_resolutionScale(resolutionScale)
-{
-}
-
-DragImage::~DragImage()
-{
-}
-
-void DragImage::fitToMaxSize(const IntSize& srcSize, const IntSize& maxSize)
-{
- float heightResizeRatio = 0.0f;
- float widthResizeRatio = 0.0f;
- float resizeRatio = -1.0f;
- IntSize originalSize = size();
-
- if (srcSize.width() > maxSize.width()) {
- widthResizeRatio = maxSize.width() / static_cast<float>(srcSize.width());
- resizeRatio = widthResizeRatio;
- }
-
- if (srcSize.height() > maxSize.height()) {
- heightResizeRatio = maxSize.height() / static_cast<float>(srcSize.height());
- if ((resizeRatio < 0.0f) || (resizeRatio > heightResizeRatio))
- resizeRatio = heightResizeRatio;
- }
-
- if (srcSize == originalSize) {
- if (resizeRatio > 0.0f)
- scale(resizeRatio, resizeRatio);
- return;
- }
-
- // The image was scaled in the webpage so at minimum we must account for that scaling
- float scaleX = srcSize.width() / static_cast<float>(originalSize.width());
- float scaleY = srcSize.height() / static_cast<float>(originalSize.height());
- if (resizeRatio > 0.0f) {
- scaleX *= resizeRatio;
- scaleY *= resizeRatio;
- }
-
- scale(scaleX, scaleY);
-}
-
-void DragImage::scale(float scaleX, float scaleY)
-{
- int imageWidth = scaleX * m_bitmap.width();
- int imageHeight = scaleY * m_bitmap.height();
- m_bitmap = skia::ImageOperations::Resize(
- m_bitmap, skia::ImageOperations::RESIZE_LANCZOS3, imageWidth, imageHeight);
-}
-
-void DragImage::dissolveToFraction(float fraction)
-{
- m_bitmap.setAlphaType(kPremul_SkAlphaType);
- SkAutoLockPixels lock(m_bitmap);
-
- for (int row = 0; row < m_bitmap.height(); ++row) {
- for (int column = 0; column < m_bitmap.width(); ++column) {
- uint32_t* pixel = m_bitmap.getAddr32(column, row);
- *pixel = SkPreMultiplyARGB(
- SkColorGetA(*pixel) * fraction,
- SkColorGetR(*pixel),
- SkColorGetG(*pixel),
- SkColorGetB(*pixel));
- }
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/DragImage.h b/chromium/third_party/WebKit/Source/core/platform/DragImage.h
deleted file mode 100644
index a350ad899d6..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/DragImage.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DragImage_h
-#define DragImage_h
-
-#include "platform/geometry/IntSize.h"
-#include "platform/graphics/ImageOrientation.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "wtf/Forward.h"
-
-namespace WebCore {
-
-class FontDescription;
-class Image;
-class KURL;
-
-class DragImage {
-public:
- static PassOwnPtr<DragImage> create(Image*, RespectImageOrientationEnum = DoNotRespectImageOrientation, float deviceScaleFactor = 1);
- static PassOwnPtr<DragImage> create(const KURL&, const String& label, const FontDescription& systemFont, float deviceScaleFactor);
- ~DragImage();
-
- const SkBitmap& bitmap() { return m_bitmap; }
- float resolutionScale() const { return m_resolutionScale; }
- IntSize size() const { return IntSize(m_bitmap.width(), m_bitmap.height()); }
-
- void fitToMaxSize(const IntSize& srcSize, const IntSize& maxSize);
- void scale(float scaleX, float scaleY);
- void dissolveToFraction(float fraction);
-
-private:
- DragImage(const SkBitmap&, float resolutionScale);
-
- SkBitmap m_bitmap;
- float m_resolutionScale;
-};
-
-}
-
-#endif // DragImage_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/Pasteboard.cpp b/chromium/third_party/WebKit/Source/core/platform/Pasteboard.cpp
deleted file mode 100644
index bcf42d5cf4b..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/Pasteboard.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/Pasteboard.h"
-
-#include "core/platform/chromium/ChromiumDataObject.h"
-#include "platform/clipboard/ClipboardUtilities.h"
-#include "platform/graphics/Image.h"
-#include "platform/graphics/skia/NativeImageSkia.h"
-#include "platform/weborigin/KURL.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebDragData.h"
-#include "public/platform/WebString.h"
-#include "public/platform/WebURL.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-Pasteboard* Pasteboard::generalPasteboard()
-{
- static Pasteboard* pasteboard = new Pasteboard;
- return pasteboard;
-}
-
-Pasteboard::Pasteboard()
- : m_buffer(blink::WebClipboard::BufferStandard)
-{
-}
-
-bool Pasteboard::isSelectionMode() const
-{
- return m_buffer == blink::WebClipboard::BufferSelection;
-}
-
-void Pasteboard::setSelectionMode(bool selectionMode)
-{
- m_buffer = selectionMode ? blink::WebClipboard::BufferSelection : blink::WebClipboard::BufferStandard;
-}
-
-void Pasteboard::writePlainText(const String& text, SmartReplaceOption)
-{
- // FIXME: add support for smart replace
-#if OS(WIN)
- String plainText(text);
- replaceNewlinesWithWindowsStyleNewlines(plainText);
- blink::Platform::current()->clipboard()->writePlainText(plainText);
-#else
- blink::Platform::current()->clipboard()->writePlainText(text);
-#endif
-}
-
-void Pasteboard::writeImage(Image* image, const KURL& url, const String& title)
-{
- ASSERT(image);
-
- RefPtr<NativeImageSkia> bitmap = image->nativeImageForCurrentFrame();
- if (!bitmap)
- return;
-
- blink::WebImage webImage = bitmap->bitmap();
- blink::Platform::current()->clipboard()->writeImage(webImage, blink::WebURL(url), blink::WebString(title));
-}
-
-void Pasteboard::writeDataObject(PassRefPtr<ChromiumDataObject> dataObject)
-{
- blink::Platform::current()->clipboard()->writeDataObject(dataObject);
-}
-
-bool Pasteboard::canSmartReplace()
-{
- return blink::Platform::current()->clipboard()->isFormatAvailable(blink::WebClipboard::FormatSmartPaste, m_buffer);
-}
-
-bool Pasteboard::isHTMLAvailable()
-{
- return blink::Platform::current()->clipboard()->isFormatAvailable(blink::WebClipboard::FormatHTML, m_buffer);
-}
-
-String Pasteboard::plainText()
-{
- return blink::Platform::current()->clipboard()->readPlainText(m_buffer);
-}
-
-String Pasteboard::readHTML(KURL& url, unsigned& fragmentStart, unsigned& fragmentEnd)
-{
- blink::WebURL webURL;
- blink::WebString markup = blink::Platform::current()->clipboard()->readHTML(m_buffer, &webURL, &fragmentStart, &fragmentEnd);
- if (!markup.isEmpty()) {
- url = webURL;
- // fragmentStart and fragmentEnd are populated by WebClipboard::readHTML.
- } else {
- url = KURL();
- fragmentStart = 0;
- fragmentEnd = 0;
- }
- return markup;
-}
-
-void Pasteboard::writeHTML(const String& markup, const KURL& documentURL, const String& plainText, bool canSmartCopyOrDelete)
-{
- String text = plainText;
-#if OS(WIN)
- replaceNewlinesWithWindowsStyleNewlines(text);
-#endif
- replaceNBSPWithSpace(text);
-
- blink::Platform::current()->clipboard()->writeHTML(markup, documentURL, text, canSmartCopyOrDelete);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/Pasteboard.h b/chromium/third_party/WebKit/Source/core/platform/Pasteboard.h
deleted file mode 100644
index f7fa5845c26..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/Pasteboard.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef Pasteboard_h
-#define Pasteboard_h
-
-#include "public/platform/WebClipboard.h"
-#include "wtf/Forward.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/text/WTFString.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class ChromiumDataObject;
-class Image;
-class KURL;
-
-class Pasteboard {
- WTF_MAKE_NONCOPYABLE(Pasteboard); WTF_MAKE_FAST_ALLOCATED;
-public:
- enum SmartReplaceOption {
- CanSmartReplace,
- CannotSmartReplace
- };
-
- static Pasteboard* generalPasteboard();
- void writePlainText(const String&, SmartReplaceOption);
- void writeImage(Image*, const KURL&, const String& title);
- void writeDataObject(PassRefPtr<ChromiumDataObject>);
- bool canSmartReplace();
- bool isHTMLAvailable();
- String plainText();
-
- // If no data is read, an empty string will be returned and all out parameters will be cleared.
- // If applicable, the page URL will be assigned to the KURL parameter.
- // fragmentStart and fragmentEnd are indexes into the returned markup that indicate
- // the start and end of the returned markup. If there is no additional context,
- // fragmentStart will be zero and fragmentEnd will be the same as the length of the markup.
- String readHTML(KURL&, unsigned& fragmentStart, unsigned& fragmentEnd);
-
- void writeHTML(const String& markup, const KURL& documentURL, const String& plainText, bool canSmartCopyOrDelete);
-
- bool isSelectionMode() const;
- void setSelectionMode(bool);
-
- blink::WebClipboard::Buffer buffer() const { return m_buffer; }
-
-private:
- Pasteboard();
-
- blink::WebClipboard::Buffer m_buffer;
-};
-
-} // namespace WebCore
-
-#endif // Pasteboard_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtil.cpp b/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtil.cpp
deleted file mode 100644
index cbb7c79f630..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtil.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/platform/animation/AnimationTranslationUtil.h"
-
-#include "core/platform/animation/CSSAnimationData.h"
-#include "core/platform/animation/KeyframeValueList.h"
-#include "platform/LengthFunctions.h"
-#include "platform/geometry/FloatSize.h"
-#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
-#include "platform/transforms/InterpolatedTransformOperation.h"
-#include "platform/transforms/Matrix3DTransformOperation.h"
-#include "platform/transforms/MatrixTransformOperation.h"
-#include "platform/transforms/PerspectiveTransformOperation.h"
-#include "platform/transforms/RotateTransformOperation.h"
-#include "platform/transforms/ScaleTransformOperation.h"
-#include "platform/transforms/SkewTransformOperation.h"
-#include "platform/transforms/TransformationMatrix.h"
-#include "platform/transforms/TranslateTransformOperation.h"
-
-#include "public/platform/Platform.h"
-#include "public/platform/WebAnimation.h"
-#include "public/platform/WebAnimationCurve.h"
-#include "public/platform/WebCompositorSupport.h"
-#include "public/platform/WebFilterAnimationCurve.h"
-#include "public/platform/WebFloatAnimationCurve.h"
-#include "public/platform/WebTransformAnimationCurve.h"
-
-#include "wtf/OwnPtr.h"
-#include "wtf/text/CString.h"
-
-using namespace std;
-using namespace blink;
-
-namespace WebCore {
-
-void toWebTransformOperations(const TransformOperations& transformOperations, const FloatSize& boxSize, WebTransformOperations* webTransformOperations)
-{
- // We need to do a deep copy the transformOperations may contain ref pointers to TransformOperation objects.
- for (size_t j = 0; j < transformOperations.size(); ++j) {
- switch (transformOperations.operations()[j]->type()) {
- case TransformOperation::ScaleX:
- case TransformOperation::ScaleY:
- case TransformOperation::ScaleZ:
- case TransformOperation::Scale3D:
- case TransformOperation::Scale: {
- ScaleTransformOperation* transform = static_cast<ScaleTransformOperation*>(transformOperations.operations()[j].get());
- webTransformOperations->appendScale(transform->x(), transform->y(), transform->z());
- break;
- }
- case TransformOperation::TranslateX:
- case TransformOperation::TranslateY:
- case TransformOperation::TranslateZ:
- case TransformOperation::Translate3D:
- case TransformOperation::Translate: {
- TranslateTransformOperation* transform = static_cast<TranslateTransformOperation*>(transformOperations.operations()[j].get());
- webTransformOperations->appendTranslate(floatValueForLength(transform->x(), boxSize.width()), floatValueForLength(transform->y(), boxSize.height()), floatValueForLength(transform->z(), 1));
- break;
- }
- case TransformOperation::RotateX:
- case TransformOperation::RotateY:
- case TransformOperation::Rotate3D:
- case TransformOperation::Rotate: {
- RotateTransformOperation* transform = static_cast<RotateTransformOperation*>(transformOperations.operations()[j].get());
- webTransformOperations->appendRotate(transform->x(), transform->y(), transform->z(), transform->angle());
- break;
- }
- case TransformOperation::SkewX:
- case TransformOperation::SkewY:
- case TransformOperation::Skew: {
- SkewTransformOperation* transform = static_cast<SkewTransformOperation*>(transformOperations.operations()[j].get());
- webTransformOperations->appendSkew(transform->angleX(), transform->angleY());
- break;
- }
- case TransformOperation::Matrix: {
- MatrixTransformOperation* transform = static_cast<MatrixTransformOperation*>(transformOperations.operations()[j].get());
- TransformationMatrix m = transform->matrix();
- webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
- break;
- }
- case TransformOperation::Matrix3D: {
- Matrix3DTransformOperation* transform = static_cast<Matrix3DTransformOperation*>(transformOperations.operations()[j].get());
- TransformationMatrix m = transform->matrix();
- webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
- break;
- }
- case TransformOperation::Perspective: {
- PerspectiveTransformOperation* transform = static_cast<PerspectiveTransformOperation*>(transformOperations.operations()[j].get());
- webTransformOperations->appendPerspective(floatValueForLength(transform->perspective(), 0));
- break;
- }
- case TransformOperation::Interpolated: {
- TransformationMatrix m;
- transformOperations.operations()[j]->apply(m, boxSize);
- webTransformOperations->appendMatrix(TransformationMatrix::toSkMatrix44(m));
- break;
- }
- case TransformOperation::Identity:
- webTransformOperations->appendIdentity();
- break;
- case TransformOperation::None:
- // Do nothing.
- break;
- } // switch
- } // for each operation
-}
-
-template <class Value, class Keyframe, class Curve>
-bool appendKeyframeWithStandardTimingFunction(Curve* curve, double keyTime, const Value* value, const Value* lastValue, blink::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize&)
-{
- curve->add(Keyframe(keyTime, value->value()), timingFunctionType);
- return true;
-}
-
-template <class Value, class Keyframe, class Curve>
-bool appendKeyframeWithCustomBezierTimingFunction(Curve* curve, double keyTime, const Value* value, const Value* lastValue, double x1, double y1, double x2, double y2, const FloatSize&)
-{
- curve->add(Keyframe(keyTime, value->value()), x1, y1, x2, y2);
- return true;
-}
-
-template <>
-bool appendKeyframeWithStandardTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, blink::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize& boxSize)
-{
- bool canBlend = !lastValue;
- OwnPtr<WebTransformOperations> operations = adoptPtr(Platform::current()->compositorSupport()->createTransformOperations());
- if (!operations)
- return false;
- toWebTransformOperations(*value->value(), boxSize, operations.get());
- if (!canBlend) {
- OwnPtr<WebTransformOperations> lastOperations = adoptPtr(Platform::current()->compositorSupport()->createTransformOperations());
- if (!lastOperations)
- return false;
- toWebTransformOperations(*lastValue->value(), boxSize, lastOperations.get());
- canBlend = lastOperations->canBlendWith(*operations);
- }
- if (canBlend) {
- curve->add(WebTransformKeyframe(keyTime, operations.release()), timingFunctionType);
- return true;
- }
- return false;
-}
-
-template <>
-bool appendKeyframeWithCustomBezierTimingFunction<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(WebTransformAnimationCurve* curve, double keyTime, const TransformAnimationValue* value, const TransformAnimationValue* lastValue, double x1, double y1, double x2, double y2, const FloatSize& boxSize)
-{
- bool canBlend = !lastValue;
- OwnPtr<WebTransformOperations> operations = adoptPtr(Platform::current()->compositorSupport()->createTransformOperations());
- if (!operations)
- return false;
- toWebTransformOperations(*value->value(), boxSize, operations.get());
- if (!canBlend) {
- OwnPtr<WebTransformOperations> lastOperations = adoptPtr(Platform::current()->compositorSupport()->createTransformOperations());
- if (!lastOperations)
- return false;
- toWebTransformOperations(*lastValue->value(), boxSize, lastOperations.get());
- canBlend = lastOperations->canBlendWith(*operations);
- }
- if (canBlend) {
- curve->add(WebTransformKeyframe(keyTime, operations.release()), x1, y1, x2, y2);
- return true;
- }
- return false;
-}
-
-bool toWebFilterOperations(const FilterOperations& inOperations, WebFilterOperations* outOperations)
-{
- SkiaImageFilterBuilder builder;
- FilterOutsets outsets = inOperations.outsets();
- builder.setCropOffset(FloatSize(outsets.left(), outsets.top()));
- return builder.buildFilterOperations(inOperations, outOperations);
-}
-
-template <>
-bool appendKeyframeWithStandardTimingFunction<FilterAnimationValue, WebFilterKeyframe, WebFilterAnimationCurve>(WebFilterAnimationCurve* curve, double keyTime, const FilterAnimationValue* value, const FilterAnimationValue* lastValue, blink::WebAnimationCurve::TimingFunctionType timingFunctionType, const FloatSize& boxSize)
-{
- // FIXME(ajuma): In order to animate pixel-moving filters on the compositor thread, we need
- // to update overlap testing to take into account the bounds within which the animation
- // will be contained, and we need the compositor to update layer bounds as the animation
- // progresses.
- if (value->value()->hasFilterThatMovesPixels())
- return false;
- OwnPtr<WebFilterOperations> operations = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations());
- if (!toWebFilterOperations(*(value->value()), operations.get()))
- return false;
- curve->add(WebFilterKeyframe(keyTime, operations.release()), timingFunctionType);
- return true;
-}
-
-template <>
-bool appendKeyframeWithCustomBezierTimingFunction<FilterAnimationValue, WebFilterKeyframe, WebFilterAnimationCurve>(WebFilterAnimationCurve* curve, double keyTime, const FilterAnimationValue* value, const FilterAnimationValue* lastValue, double x1, double y1, double x2, double y2, const FloatSize& boxSize)
-{
- // FIXME(ajuma): In order to animate pixel-moving filters on the compositor thread, we need
- // to update overlap testing to take into account the bounds within which the animation
- // will be contained, and we need the compositor to update layer bounds as the animation
- // progresses.
- if (value->value()->hasFilterThatMovesPixels())
- return false;
-
- OwnPtr<WebFilterOperations> operations = adoptPtr(Platform::current()->compositorSupport()->createFilterOperations());
- if (!toWebFilterOperations(*(value->value()), operations.get()))
- return false;
- curve->add(WebFilterKeyframe(keyTime, operations.release()), x1, y1, x2, y2);
- return true;
-}
-
-template <class Value, class Keyframe, class Curve>
-PassOwnPtr<blink::WebAnimation> createWebAnimation(const KeyframeValueList& valueList, const CSSAnimationData* animation, int animationId, double timeOffset, Curve* curve, blink::WebAnimation::TargetProperty targetProperty, const FloatSize& boxSize)
-{
- bool alternate = false;
- bool reverse = false;
- if (animation && animation->isDirectionSet()) {
- CSSAnimationData::AnimationDirection direction = animation->direction();
- if (direction == CSSAnimationData::AnimationDirectionAlternate || direction == CSSAnimationData::AnimationDirectionAlternateReverse)
- alternate = true;
- if (direction == CSSAnimationData::AnimationDirectionReverse || direction == CSSAnimationData::AnimationDirectionAlternateReverse)
- reverse = true;
- }
-
- for (size_t i = 0; i < valueList.size(); i++) {
- size_t index = reverse ? valueList.size() - i - 1 : i;
- const Value* originalValue = static_cast<const Value*>(valueList.at(index));
- const Value* lastOriginalValue = 0;
- if (valueList.size() > 1 && ((reverse && index + 1 < valueList.size()) || (!reverse && index > 0)))
- lastOriginalValue = static_cast<const Value*>(valueList.at(reverse ? index + 1 : index - 1));
-
- const TimingFunction* originalTimingFunction = originalValue->timingFunction();
-
- // If there hasn't been a timing function associated with this keyframe, use the
- // animation's timing function, if we have one.
- if (!originalTimingFunction && animation->isTimingFunctionSet())
- originalTimingFunction = animation->timingFunction();
-
- // Ease is the default timing function.
- blink::WebAnimationCurve::TimingFunctionType timingFunctionType = blink::WebAnimationCurve::TimingFunctionTypeEase;
-
- bool isUsingCustomBezierTimingFunction = false;
- double x1 = 0;
- double y1 = 0;
- double x2 = 1;
- double y2 = 1;
-
- if (originalTimingFunction) {
- switch (originalTimingFunction->type()) {
- case TimingFunction::StepsFunction:
- // FIXME: add support for steps timing function.
- return nullptr;
- case TimingFunction::LinearFunction:
- // This doesn't need to be flipped when the animation is reversed.
- timingFunctionType = blink::WebAnimationCurve::TimingFunctionTypeLinear;
- break;
- case TimingFunction::CubicBezierFunction:
- {
- const CubicBezierTimingFunction* originalBezierTimingFunction = toCubicBezierTimingFunction(originalTimingFunction);
- isUsingCustomBezierTimingFunction = true;
- x1 = originalBezierTimingFunction->x1();
- y1 = originalBezierTimingFunction->y1();
- x2 = originalBezierTimingFunction->x2();
- y2 = originalBezierTimingFunction->y2();
- if (reverse) {
- // When the animation is reversed, we need to swap the
- // start and end keyframes, and flip the timing
- // function in both x and y.
- double x1Old = x1;
- double y1Old = y1;
- x1 = 1 - x2;
- y1 = 1 - y2;
- x2 = 1 - x1Old;
- y2 = 1 - y1Old;
- }
- break;
- }
- default:
- ASSERT_NOT_REACHED();
- } // switch
- }
-
- double duration = (animation && animation->isDurationSet()) ? animation->duration() : 1;
- double keyTime = originalValue->keyTime() * duration;
-
- if (reverse)
- keyTime = duration - keyTime;
-
- bool addedKeyframe = false;
- if (isUsingCustomBezierTimingFunction)
- addedKeyframe = appendKeyframeWithCustomBezierTimingFunction<Value, Keyframe, Curve>(curve, keyTime, originalValue, lastOriginalValue, x1, y1, x2, y2, boxSize);
- else
- addedKeyframe = appendKeyframeWithStandardTimingFunction<Value, Keyframe, Curve>(curve, keyTime, originalValue, lastOriginalValue, timingFunctionType, boxSize);
-
- if (!addedKeyframe)
- return nullptr;
- }
-
- OwnPtr<blink::WebAnimation> webAnimation = adoptPtr(Platform::current()->compositorSupport()->createAnimation(*curve, targetProperty, animationId));
-
- int iterations = (animation && animation->isIterationCountSet()) ? animation->iterationCount() : 1;
- webAnimation->setIterations(iterations);
- webAnimation->setAlternatesDirection(alternate);
-
- // If timeOffset > 0, then the animation has started in the past.
- webAnimation->setTimeOffset(timeOffset);
-
- return webAnimation.release();
-}
-
-PassOwnPtr<blink::WebAnimation> createWebAnimation(const KeyframeValueList& values, const CSSAnimationData* animation, int animationId, double timeOffset, const FloatSize& boxSize)
-{
- switch (values.property()) {
- case AnimatedPropertyWebkitTransform: {
- OwnPtr<WebTransformAnimationCurve> curve = adoptPtr(Platform::current()->compositorSupport()->createTransformAnimationCurve());
- return createWebAnimation<TransformAnimationValue, WebTransformKeyframe, WebTransformAnimationCurve>(values, animation, animationId, timeOffset, curve.get(), blink::WebAnimation::TargetPropertyTransform, FloatSize(boxSize));
- }
-
- case AnimatedPropertyOpacity: {
- OwnPtr<WebFloatAnimationCurve> curve = adoptPtr(Platform::current()->compositorSupport()->createFloatAnimationCurve());
- return createWebAnimation<FloatAnimationValue, WebFloatKeyframe, WebFloatAnimationCurve>(values, animation, animationId, timeOffset, curve.get(), blink::WebAnimation::TargetPropertyOpacity, FloatSize());
- }
-
- case AnimatedPropertyWebkitFilter: {
- OwnPtr<WebFilterAnimationCurve> curve = adoptPtr(Platform::current()->compositorSupport()->createFilterAnimationCurve());
- return createWebAnimation<FilterAnimationValue, WebFilterKeyframe, WebFilterAnimationCurve>(values, animation, animationId, timeOffset, curve.get(), blink::WebAnimation::TargetPropertyFilter, FloatSize(boxSize));
- }
-
- case AnimatedPropertyBackgroundColor:
- case AnimatedPropertyInvalid:
- return nullptr;
- }
-
- return nullptr;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtil.h b/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtil.h
deleted file mode 100644
index 2c95cdfaac6..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtil.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AnimationTranslationUtil_h
-#define AnimationTranslationUtil_h
-
-#include "platform/graphics/filters/FilterOperations.h"
-#include "platform/transforms/TransformOperations.h"
-#include "public/platform/WebTransformOperations.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace blink {
-class WebAnimation;
-class WebFilterOperations;
-}
-
-namespace WebCore {
-
-class KeyframeValueList;
-class CSSAnimationData;
-class FloatSize;
-
-
-// Translates WebCore animation data into a WebAnimation. If we are unable
-// to perform this translation, we return nullptr. This can happen if
-// - a steps timing function is used,
-// - a property other than AnimatedPropertyWebkitTransform, or AnimatedPropertyOpacity is animated, or
-// - a transform animation involves a non-invertable transform.
-PassOwnPtr<blink::WebAnimation> createWebAnimation(const KeyframeValueList&, const CSSAnimationData*, int animationId, double timeOffset, const FloatSize& boxSize);
-
-void toWebTransformOperations(const TransformOperations& inOperations, const FloatSize& boxSize, blink::WebTransformOperations* outOperations);
-
-bool toWebFilterOperations(const FilterOperations& inOperations, blink::WebFilterOperations* outOperations);
-} // namespace WebCore
-
-#endif // AnimationTranslationUtil_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtilTest.cpp b/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtilTest.cpp
deleted file mode 100644
index 59dcbe91cea..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/AnimationTranslationUtilTest.cpp
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/platform/animation/AnimationTranslationUtil.h"
-
-#include "core/platform/animation/CSSAnimationData.h"
-#include "core/platform/animation/KeyframeValueList.h"
-#include "platform/geometry/IntSize.h"
-#include "platform/graphics/filters/FilterOperations.h"
-#include "platform/transforms/Matrix3DTransformOperation.h"
-#include "platform/transforms/RotateTransformOperation.h"
-#include "platform/transforms/ScaleTransformOperation.h"
-#include "platform/transforms/TransformOperations.h"
-#include "platform/transforms/TranslateTransformOperation.h"
-#include "public/platform/WebAnimation.h"
-#include "public/platform/WebFilterOperations.h"
-#include "wtf/RefPtr.h"
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-using namespace WebCore;
-using namespace blink;
-
-namespace {
-
-class WebTransformOperationsMock : public blink::WebTransformOperations {
-public:
- MOCK_CONST_METHOD1(canBlendWith, bool(const WebTransformOperations&));
- MOCK_METHOD3(appendTranslate, void(double, double, double));
- MOCK_METHOD4(appendRotate, void(double, double, double, double));
- MOCK_METHOD3(appendScale, void(double, double, double));
- MOCK_METHOD2(appendSkew, void(double, double));
- MOCK_METHOD1(appendPerspective, void(double));
- MOCK_METHOD1(appendMatrix, void(const SkMatrix44&));
- MOCK_METHOD0(appendIdentity, void());
- MOCK_CONST_METHOD0(isIdentity, bool());
-};
-
-class WebFilterOperationsMock : public blink::WebFilterOperations {
-public:
- MOCK_METHOD1(appendGrayscaleFilter, void(float));
- MOCK_METHOD1(appendSepiaFilter, void(float));
- MOCK_METHOD1(appendSaturateFilter, void(float));
- MOCK_METHOD1(appendHueRotateFilter, void(float));
- MOCK_METHOD1(appendInvertFilter, void(float));
- MOCK_METHOD1(appendBrightnessFilter, void(float));
- MOCK_METHOD1(appendContrastFilter, void(float));
- MOCK_METHOD1(appendOpacityFilter, void(float));
- MOCK_METHOD1(appendBlurFilter, void(float));
- MOCK_METHOD3(appendDropShadowFilter, void(WebPoint, float, WebColor));
- MOCK_METHOD1(appendColorMatrixFilter, void(SkScalar[20]));
- MOCK_METHOD2(appendZoomFilter, void(float, int));
- MOCK_METHOD1(appendSaturatingBrightnessFilter, void(float));
- MOCK_METHOD1(appendReferenceFilter, void(SkImageFilter*));
- MOCK_METHOD0(clear, void());
-};
-
-bool animationCanBeTranslated(const KeyframeValueList& values, CSSAnimationData* animation)
-{
- IntSize boxSize;
- return createWebAnimation(values, animation, 0, 0, boxSize);
-}
-
-TEST(AnimationTranslationUtilTest, createOpacityAnimation)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyOpacity);
- values.insert(adoptPtr(new FloatAnimationValue(0, 0)));
- values.insert(adoptPtr(new FloatAnimationValue(duration, 1)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createFilterAnimation)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitFilter);
-
- FilterOperations operations1;
- operations1.operations().append(BasicColorMatrixFilterOperation::create(0.5, FilterOperation::SATURATE));
- values.insert(adoptPtr(new FilterAnimationValue(0, &operations1)));
-
- FilterOperations operations2;
- operations2.operations().append(BasicColorMatrixFilterOperation::create(1.0, FilterOperation::SATURATE));
- values.insert(adoptPtr(new FilterAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createTransformAnimation)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(TranslateTransformOperation::create(Length(4, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createTransformAnimationWithBigRotation)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- operations1.operations().append(RotateTransformOperation::create(0, TransformOperation::Rotate));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(RotateTransformOperation::create(270, TransformOperation::Rotate));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createTransformAnimationWithBigRotationAndEmptyTransformOperationList)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(RotateTransformOperation::create(270, TransformOperation::Rotate));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createTransformAnimationWithRotationInvolvingNegativeAngles)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- operations1.operations().append(RotateTransformOperation::create(-330, TransformOperation::Rotate));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(RotateTransformOperation::create(-320, TransformOperation::Rotate));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createTransformAnimationWithSmallRotationInvolvingLargeAngles)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- operations1.operations().append(RotateTransformOperation::create(270, TransformOperation::Rotate));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(RotateTransformOperation::create(360, TransformOperation::Rotate));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createTransformAnimationWithNonDecomposableMatrix)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformationMatrix matrix1;
- TransformOperations operations1;
- operations1.operations().append(Matrix3DTransformOperation::create(matrix1));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformationMatrix matrix2;
- matrix2.setM11(0);
- TransformOperations operations2;
- operations2.operations().append(Matrix3DTransformOperation::create(matrix2));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_FALSE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createTransformAnimationWithNonInvertibleTransform)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- operations1.operations().append(ScaleTransformOperation::create(1, 1, 1, TransformOperation::Scale3D));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(ScaleTransformOperation::create(1, 0, 1, TransformOperation::Scale3D));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createReversedAnimation)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(TranslateTransformOperation::create(Length(4, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
- animation->setDirection(CSSAnimationData::AnimationDirectionReverse);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createAlternatingAnimation)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(TranslateTransformOperation::create(Length(4, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
- animation->setDirection(CSSAnimationData::AnimationDirectionAlternate);
- animation->setIterationCount(2);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, createReversedAlternatingAnimation)
-{
- const double duration = 1;
- WebCore::KeyframeValueList values(AnimatedPropertyWebkitTransform);
-
- TransformOperations operations1;
- operations1.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- values.insert(adoptPtr(new TransformAnimationValue(0, &operations1)));
-
- TransformOperations operations2;
- operations2.operations().append(TranslateTransformOperation::create(Length(4, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- values.insert(adoptPtr(new TransformAnimationValue(duration, &operations2)));
-
- RefPtr<CSSAnimationData> animation = CSSAnimationData::create();
- animation->setDuration(duration);
- animation->setDirection(CSSAnimationData::AnimationDirectionAlternateReverse);
- animation->setIterationCount(2);
-
- EXPECT_TRUE(animationCanBeTranslated(values, animation.get()));
-}
-
-TEST(AnimationTranslationUtilTest, transformsWork)
-{
- TransformOperations ops;
- FloatSize box(100, 200);
- WebTransformOperationsMock outOps;
-
- EXPECT_CALL(outOps, appendTranslate(2, 0, 0));
- EXPECT_CALL(outOps, appendTranslate(2, 60, 0));
- EXPECT_CALL(outOps, appendRotate(0.1, 0.2, 0.3, 200000.4));
- EXPECT_CALL(outOps, appendScale(50.2, 100, -4));
-
- ops.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(0, WebCore::Fixed), TransformOperation::TranslateX));
- ops.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Percent), Length(30, WebCore::Percent), TransformOperation::Translate));
- ops.operations().append(RotateTransformOperation::create(0.1, 0.2, 0.3, 200000.4, TransformOperation::Rotate3D));
- ops.operations().append(ScaleTransformOperation::create(50.2, 100, -4, TransformOperation::Scale3D));
- toWebTransformOperations(ops, box, &outOps);
-}
-
-TEST(AnimationTranslationUtilTest, filtersWork)
-{
- FilterOperations ops;
- WebFilterOperationsMock outOps;
-
- EXPECT_CALL(outOps, appendSaturateFilter(0.5));
- EXPECT_CALL(outOps, appendGrayscaleFilter(0.2f));
- EXPECT_CALL(outOps, appendSepiaFilter(0.8f));
- EXPECT_CALL(outOps, appendOpacityFilter(0.1f));
-
- ops.operations().append(BasicColorMatrixFilterOperation::create(0.5, FilterOperation::SATURATE));
- ops.operations().append(BasicColorMatrixFilterOperation::create(0.2, FilterOperation::GRAYSCALE));
- ops.operations().append(BasicColorMatrixFilterOperation::create(0.8, FilterOperation::SEPIA));
- ops.operations().append(BasicColorMatrixFilterOperation::create(0.1, FilterOperation::OPACITY));
- toWebFilterOperations(ops, &outOps);
-}
-
-}
-
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/AnimationValue.h b/chromium/third_party/WebKit/Source/core/platform/animation/AnimationValue.h
deleted file mode 100644
index cba337cbf2e..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/AnimationValue.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef AnimationValue_h
-#define AnimationValue_h
-
-#include "core/platform/animation/TimingFunction.h"
-#include "platform/graphics/filters/FilterOperations.h"
-#include "platform/transforms/TransformOperations.h"
-
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-// Base class for animation values (also used for transitions). Here to
-// represent values for properties being animated via the GraphicsLayer,
-// without pulling in style-related data from outside of the platform directory.
-class AnimationValue {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit AnimationValue(double keyTime, PassRefPtr<TimingFunction> timingFunction = 0)
- : m_keyTime(keyTime)
- , m_timingFunction(timingFunction)
- {
- }
-
- virtual ~AnimationValue() { }
-
- double keyTime() const { return m_keyTime; }
- const TimingFunction* timingFunction() const { return m_timingFunction.get(); }
- virtual PassOwnPtr<AnimationValue> clone() const = 0;
-
-private:
- double m_keyTime;
- RefPtr<TimingFunction> m_timingFunction;
-};
-
-// Used to store one float value of an animation.
-class FloatAnimationValue : public AnimationValue {
-public:
- FloatAnimationValue(double keyTime, float value, PassRefPtr<TimingFunction> timingFunction = 0)
- : AnimationValue(keyTime, timingFunction)
- , m_value(value)
- {
- }
- virtual PassOwnPtr<AnimationValue> clone() const OVERRIDE { return adoptPtr(new FloatAnimationValue(*this)); }
-
- float value() const { return m_value; }
-
-private:
- float m_value;
-};
-
-// Used to store one transform value in a keyframe list.
-class TransformAnimationValue : public AnimationValue {
-public:
- explicit TransformAnimationValue(double keyTime, const TransformOperations* value = 0, PassRefPtr<TimingFunction> timingFunction = 0)
- : AnimationValue(keyTime, timingFunction)
- {
- if (value)
- m_value = *value;
- }
- virtual PassOwnPtr<AnimationValue> clone() const OVERRIDE { return adoptPtr(new TransformAnimationValue(*this)); }
-
- const TransformOperations* value() const { return &m_value; }
-
-private:
- TransformOperations m_value;
-};
-
-// Used to store one filter value in a keyframe list.
-class FilterAnimationValue : public AnimationValue {
-public:
- explicit FilterAnimationValue(double keyTime, const FilterOperations* value = 0, PassRefPtr<TimingFunction> timingFunction = 0)
- : AnimationValue(keyTime, timingFunction)
- {
- if (value)
- m_value = *value;
- }
- virtual PassOwnPtr<AnimationValue> clone() const OVERRIDE { return adoptPtr(new FilterAnimationValue(*this)); }
-
- const FilterOperations* value() const { return &m_value; }
-
-private:
- FilterOperations m_value;
-};
-
-} // namespace WebCore
-
-#endif // AnimationValue_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationData.cpp b/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationData.cpp
deleted file mode 100644
index 277944ba1d3..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationData.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/platform/animation/CSSAnimationData.h"
-
-namespace WebCore {
-
-CSSAnimationData::CSSAnimationData()
- : m_name(initialAnimationName())
- , m_property(CSSPropertyInvalid)
- , m_mode(AnimateAll)
- , m_iterationCount(initialAnimationIterationCount())
- , m_delay(initialAnimationDelay())
- , m_duration(initialAnimationDuration())
- , m_timingFunction(initialAnimationTimingFunction())
- , m_direction(initialAnimationDirection())
- , m_fillMode(initialAnimationFillMode())
- , m_playState(initialAnimationPlayState())
- , m_delaySet(false)
- , m_directionSet(false)
- , m_durationSet(false)
- , m_fillModeSet(false)
- , m_iterationCountSet(false)
- , m_nameSet(false)
- , m_playStateSet(false)
- , m_propertySet(false)
- , m_timingFunctionSet(false)
- , m_isNone(false)
-{
-}
-
-CSSAnimationData::CSSAnimationData(const CSSAnimationData& o)
- : RefCounted<CSSAnimationData>()
- , m_name(o.m_name)
- , m_property(o.m_property)
- , m_mode(o.m_mode)
- , m_iterationCount(o.m_iterationCount)
- , m_delay(o.m_delay)
- , m_duration(o.m_duration)
- , m_timingFunction(o.m_timingFunction)
- , m_direction(o.m_direction)
- , m_fillMode(o.m_fillMode)
- , m_playState(o.m_playState)
- , m_delaySet(o.m_delaySet)
- , m_directionSet(o.m_directionSet)
- , m_durationSet(o.m_durationSet)
- , m_fillModeSet(o.m_fillModeSet)
- , m_iterationCountSet(o.m_iterationCountSet)
- , m_nameSet(o.m_nameSet)
- , m_playStateSet(o.m_playStateSet)
- , m_propertySet(o.m_propertySet)
- , m_timingFunctionSet(o.m_timingFunctionSet)
- , m_isNone(o.m_isNone)
-{
-}
-
-CSSAnimationData& CSSAnimationData::operator=(const CSSAnimationData& o)
-{
- m_name = o.m_name;
- m_property = o.m_property;
- m_mode = o.m_mode;
- m_iterationCount = o.m_iterationCount;
- m_delay = o.m_delay;
- m_duration = o.m_duration;
- m_timingFunction = o.m_timingFunction;
- m_direction = o.m_direction;
- m_fillMode = o.m_fillMode;
- m_playState = o.m_playState;
-
- m_delaySet = o.m_delaySet;
- m_directionSet = o.m_directionSet;
- m_durationSet = o.m_durationSet;
- m_fillModeSet = o.m_fillModeSet;
- m_iterationCountSet = o.m_iterationCountSet;
- m_nameSet = o.m_nameSet;
- m_playStateSet = o.m_playStateSet;
- m_propertySet = o.m_propertySet;
- m_timingFunctionSet = o.m_timingFunctionSet;
- m_isNone = o.m_isNone;
-
- return *this;
-}
-
-CSSAnimationData::~CSSAnimationData()
-{
-}
-
-bool CSSAnimationData::animationsMatchForStyleRecalc(const CSSAnimationData* o) const
-{
- if (!o)
- return false;
-
- return m_name == o->m_name
- && m_playState == o->m_playState
- && m_property == o->m_property
- && m_mode == o->m_mode
- && m_nameSet == o->m_nameSet
- && m_playStateSet == o->m_playStateSet
- && m_propertySet == o->m_propertySet
- && m_isNone == o->m_isNone;
-}
-
-const AtomicString& CSSAnimationData::initialAnimationName()
-{
- DEFINE_STATIC_LOCAL(const AtomicString, initialValue, ("none"));
- return initialValue;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationData.h b/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationData.h
deleted file mode 100644
index 7f6e79ab910..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationData.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * (C) 2000 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef CSSAnimationData_h
-#define CSSAnimationData_h
-
-#include "CSSPropertyNames.h"
-#include "core/platform/animation/TimingFunction.h"
-#include "core/rendering/style/RenderStyleConstants.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class CSSAnimationData : public RefCounted<CSSAnimationData> {
-public:
- ~CSSAnimationData();
-
- static PassRefPtr<CSSAnimationData> create() { return adoptRef(new CSSAnimationData); }
- static PassRefPtr<CSSAnimationData> create(const CSSAnimationData* o) { return adoptRef(new CSSAnimationData(*o)); }
-
- bool isDelaySet() const { return m_delaySet; }
- bool isDirectionSet() const { return m_directionSet; }
- bool isDurationSet() const { return m_durationSet; }
- bool isFillModeSet() const { return m_fillModeSet; }
- bool isIterationCountSet() const { return m_iterationCountSet; }
- bool isNameSet() const { return m_nameSet; }
- bool isPlayStateSet() const { return m_playStateSet; }
- bool isPropertySet() const { return m_propertySet; }
- bool isTimingFunctionSet() const { return m_timingFunctionSet; }
-
- // Flags this to be the special "none" animation (animation-name: none)
- bool isNoneAnimation() const { return m_isNone; }
- // We can make placeholder CSSAnimationData objects to keep the comma-separated lists
- // of properties in sync. isValidAnimation means this is not a placeholder.
- bool isValidAnimation() const { return !m_isNone && !m_name.isEmpty(); }
-
- bool isEmpty() const
- {
- return (!m_directionSet && !m_durationSet && !m_fillModeSet
- && !m_nameSet && !m_playStateSet && !m_iterationCountSet
- && !m_delaySet && !m_timingFunctionSet && !m_propertySet);
- }
-
- bool isEmptyOrZeroDuration() const
- {
- return isEmpty() || (m_duration == 0 && m_delay <= 0);
- }
-
- void clearDelay() { m_delaySet = false; }
- void clearDirection() { m_directionSet = false; }
- void clearDuration() { m_durationSet = false; }
- void clearFillMode() { m_fillModeSet = false; }
- void clearIterationCount() { m_iterationCountSet = false; }
- void clearName() { m_nameSet = false; }
- void clearPlayState() { m_playStateSet = AnimPlayStatePlaying; }
- void clearProperty() { m_propertySet = false; }
- void clearTimingFunction() { m_timingFunctionSet = false; }
-
- void clearAll()
- {
- clearDelay();
- clearDirection();
- clearDuration();
- clearFillMode();
- clearIterationCount();
- clearName();
- clearPlayState();
- clearProperty();
- clearTimingFunction();
- }
-
- double delay() const { return m_delay; }
-
- enum AnimationMode {
- AnimateAll,
- AnimateNone,
- AnimateSingleProperty
- };
-
- enum AnimationDirection {
- AnimationDirectionNormal,
- AnimationDirectionAlternate,
- AnimationDirectionReverse,
- AnimationDirectionAlternateReverse
- };
- AnimationDirection direction() const { return static_cast<AnimationDirection>(m_direction); }
- bool directionIsForwards() const { return m_direction == AnimationDirectionNormal || m_direction == AnimationDirectionAlternate; }
-
- unsigned fillMode() const { return m_fillMode; }
-
- double duration() const { return m_duration; }
-
- enum { IterationCountInfinite = -1 };
- double iterationCount() const { return m_iterationCount; }
- const AtomicString& name() const { return m_name; }
- EAnimPlayState playState() const { return static_cast<EAnimPlayState>(m_playState); }
- CSSPropertyID property() const { return m_property; }
- TimingFunction* timingFunction() const { return m_timingFunction.get(); }
- AnimationMode animationMode() const { return m_mode; }
-
- void setDelay(double c) { m_delay = c; m_delaySet = true; }
- void setDirection(AnimationDirection d) { m_direction = d; m_directionSet = true; }
- void setDuration(double d) { ASSERT(d >= 0); m_duration = d; m_durationSet = true; }
- void setFillMode(unsigned f) { m_fillMode = f; m_fillModeSet = true; }
- void setIterationCount(double c) { m_iterationCount = c; m_iterationCountSet = true; }
- void setName(const AtomicString& n) { m_name = n; m_nameSet = true; }
- void setPlayState(EAnimPlayState d) { m_playState = d; m_playStateSet = true; }
- void setProperty(CSSPropertyID t) { m_property = t; m_propertySet = true; }
- void setTimingFunction(PassRefPtr<TimingFunction> f) { m_timingFunction = f; m_timingFunctionSet = true; }
- void setAnimationMode(AnimationMode mode) { m_mode = mode; }
-
- void setIsNoneAnimation(bool n) { m_isNone = n; }
-
- CSSAnimationData& operator=(const CSSAnimationData& o);
-
- // return true every CSSAnimationData in the chain (defined by m_next) match
- bool operator==(const CSSAnimationData& o) const { return animationsMatchForStyleRecalc(&o); }
- bool operator!=(const CSSAnimationData& o) const { return !(*this == o); }
-
- bool fillsBackwards() const { return m_fillModeSet && (m_fillMode == AnimationFillModeBackwards || m_fillMode == AnimationFillModeBoth); }
- bool fillsForwards() const { return m_fillModeSet && (m_fillMode == AnimationFillModeForwards || m_fillMode == AnimationFillModeBoth); }
-
-private:
- CSSAnimationData();
- explicit CSSAnimationData(const CSSAnimationData&);
-
- // Return whether this object matches another CSSAnimationData object for
- // the purposes of style recalc. This excludes some properties.
- bool animationsMatchForStyleRecalc(const CSSAnimationData*) const;
-
- AtomicString m_name;
- CSSPropertyID m_property;
- AnimationMode m_mode;
- double m_iterationCount;
- double m_delay;
- double m_duration;
- RefPtr<TimingFunction> m_timingFunction;
- unsigned m_direction : 2; // AnimationDirection
- unsigned m_fillMode : 2;
-
- unsigned m_playState : 2;
-
- bool m_delaySet : 1;
- bool m_directionSet : 1;
- bool m_durationSet : 1;
- bool m_fillModeSet : 1;
- bool m_iterationCountSet : 1;
- bool m_nameSet : 1;
- bool m_playStateSet : 1;
- bool m_propertySet : 1;
- bool m_timingFunctionSet : 1;
-
- bool m_isNone : 1;
-
-public:
- static double initialAnimationDelay() { return 0; }
- static AnimationDirection initialAnimationDirection() { return AnimationDirectionNormal; }
- static double initialAnimationDuration() { return 0; }
- static unsigned initialAnimationFillMode() { return AnimationFillModeNone; }
- static double initialAnimationIterationCount() { return 1.0; }
- static const AtomicString& initialAnimationName();
- static EAnimPlayState initialAnimationPlayState() { return AnimPlayStatePlaying; }
- static CSSPropertyID initialAnimationProperty() { return CSSPropertyInvalid; }
- static const PassRefPtr<TimingFunction> initialAnimationTimingFunction() { return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease); }
-};
-
-} // namespace WebCore
-
-#endif // CSSAnimationData_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationDataList.cpp b/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationDataList.cpp
deleted file mode 100644
index 5170e7680f9..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationDataList.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/platform/animation/CSSAnimationDataList.h"
-
-namespace WebCore {
-
-#define FILL_UNSET_PROPERTY(test, propGet, propSet) \
-for (i = 0; i < size() && animation(i)->test(); ++i) { } \
-if (i < size() && i != 0) { \
- for (size_t j = 0; i < size(); ++i, ++j) \
- animation(i)->propSet(animation(j)->propGet()); \
-}
-
-CSSAnimationDataList::CSSAnimationDataList(const CSSAnimationDataList& o)
-{
- for (size_t i = 0; i < o.size(); ++i)
- m_animations.append(CSSAnimationData::create(o.animation(i)));
-}
-
-void CSSAnimationDataList::fillUnsetProperties()
-{
- size_t i;
- FILL_UNSET_PROPERTY(isDelaySet, delay, setDelay);
- FILL_UNSET_PROPERTY(isDirectionSet, direction, setDirection);
- FILL_UNSET_PROPERTY(isDurationSet, duration, setDuration);
- FILL_UNSET_PROPERTY(isFillModeSet, fillMode, setFillMode);
- FILL_UNSET_PROPERTY(isIterationCountSet, iterationCount, setIterationCount);
- FILL_UNSET_PROPERTY(isPlayStateSet, playState, setPlayState);
- FILL_UNSET_PROPERTY(isNameSet, name, setName);
- FILL_UNSET_PROPERTY(isTimingFunctionSet, timingFunction, setTimingFunction);
- FILL_UNSET_PROPERTY(isPropertySet, property, setProperty);
-}
-
-bool CSSAnimationDataList::operator==(const CSSAnimationDataList& o) const
-{
- if (size() != o.size())
- return false;
- for (size_t i = 0; i < size(); ++i)
- if (*animation(i) != *o.animation(i))
- return false;
- return true;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationDataList.h b/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationDataList.h
deleted file mode 100644
index 48d855674f0..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/CSSAnimationDataList.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * (C) 2000 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef CSSAnimationDataList_h
-#define CSSAnimationDataList_h
-
-#include "core/platform/animation/CSSAnimationData.h"
-#include "wtf/RefPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class CSSAnimationDataList {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- CSSAnimationDataList() { }
- explicit CSSAnimationDataList(const CSSAnimationDataList&);
-
- void fillUnsetProperties();
- bool operator==(const CSSAnimationDataList& o) const;
- bool operator!=(const CSSAnimationDataList& o) const
- {
- return !(*this == o);
- }
-
- size_t size() const { return m_animations.size(); }
- bool isEmpty() const { return m_animations.isEmpty(); }
-
- void resize(size_t n) { m_animations.resize(n); }
- void remove(size_t i) { m_animations.remove(i); }
- void append(PassRefPtr<CSSAnimationData> anim) { m_animations.append(anim); }
-
- CSSAnimationData* animation(size_t i) { return m_animations[i].get(); }
- const CSSAnimationData* animation(size_t i) const { return m_animations[i].get(); }
-
-private:
- CSSAnimationDataList& operator=(const CSSAnimationDataList&);
-
- Vector<RefPtr<CSSAnimationData> > m_animations;
-};
-
-
-} // namespace WebCore
-
-#endif // CSSAnimationDataList_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/KeyframeValueList.cpp b/chromium/third_party/WebKit/Source/core/platform/animation/KeyframeValueList.cpp
deleted file mode 100644
index 174172ccd5e..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/KeyframeValueList.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/platform/animation/KeyframeValueList.h"
-
-namespace WebCore {
-
-void KeyframeValueList::insert(PassOwnPtr<const AnimationValue> value)
-{
- for (size_t i = 0; i < m_values.size(); ++i) {
- const AnimationValue* curValue = m_values[i].get();
- if (curValue->keyTime() == value->keyTime()) {
- ASSERT_NOT_REACHED();
- // insert after
- m_values.insert(i + 1, value);
- return;
- }
- if (curValue->keyTime() > value->keyTime()) {
- // insert before
- m_values.insert(i, value);
- return;
- }
- }
-
- m_values.append(value);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/KeyframeValueList.h b/chromium/third_party/WebKit/Source/core/platform/animation/KeyframeValueList.h
deleted file mode 100644
index 86ffb0052f7..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/KeyframeValueList.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef KeyframeValueList_h
-#define KeyframeValueList_h
-
-#include "core/platform/animation/AnimationValue.h"
-
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-enum AnimatedPropertyID {
- AnimatedPropertyInvalid,
- AnimatedPropertyWebkitTransform,
- AnimatedPropertyOpacity,
- AnimatedPropertyBackgroundColor,
- AnimatedPropertyWebkitFilter
-};
-
-// Used to store a series of values in a keyframe list.
-// Values will all be of the same type, which can be inferred from the property.
-class KeyframeValueList {
-public:
- explicit KeyframeValueList(AnimatedPropertyID property)
- : m_property(property)
- {
- }
-
- KeyframeValueList(const KeyframeValueList& other)
- : m_property(other.property())
- {
- for (size_t i = 0; i < other.m_values.size(); ++i)
- m_values.append(other.m_values[i]->clone());
- }
-
- KeyframeValueList& operator=(const KeyframeValueList& other)
- {
- KeyframeValueList copy(other);
- swap(copy);
- return *this;
- }
-
- void swap(KeyframeValueList& other)
- {
- std::swap(m_property, other.m_property);
- m_values.swap(other.m_values);
- }
-
- AnimatedPropertyID property() const { return m_property; }
-
- size_t size() const { return m_values.size(); }
- const AnimationValue* at(size_t i) const { return m_values.at(i).get(); }
-
- // Insert, sorted by keyTime.
- void insert(PassOwnPtr<const AnimationValue>);
-
-protected:
- Vector<OwnPtr<const AnimationValue> > m_values;
- AnimatedPropertyID m_property;
-};
-
-} // namespace WebCore
-
-#endif // KeyframeValueList_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunction.h b/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunction.h
deleted file mode 100644
index 147d86b390b..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunction.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * (C) 2000 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef TimingFunction_h
-#define TimingFunction_h
-
-#include "RuntimeEnabledFeatures.h"
-#include "platform/animation/AnimationUtilities.h" // For blend()
-#include "platform/animation/UnitBezier.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/StdLibExtras.h"
-#include "wtf/Vector.h"
-#include <algorithm>
-
-
-namespace WebCore {
-
-class TimingFunction : public RefCounted<TimingFunction> {
-public:
-
- enum Type {
- LinearFunction, CubicBezierFunction, StepsFunction, ChainedFunction
- };
-
- virtual ~TimingFunction() { }
-
- Type type() const { return m_type; }
-
- // Evaluates the timing function at the given fraction. The accuracy parameter provides a hint as to the required
- // accuracy and is not guaranteed.
- virtual double evaluate(double fraction, double accuracy) const = 0;
-
-protected:
- TimingFunction(Type type)
- : m_type(type)
- {
- }
-
-private:
- Type m_type;
-};
-
-class LinearTimingFunction : public TimingFunction {
-public:
- static PassRefPtr<LinearTimingFunction> create()
- {
- return adoptRef(new LinearTimingFunction);
- }
-
- ~LinearTimingFunction() { }
-
- virtual double evaluate(double fraction, double) const
- {
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled() || (fraction >= 0 && fraction <= 1));
- ASSERT_WITH_MESSAGE(!RuntimeEnabledFeatures::webAnimationsCSSEnabled() || (fraction >= 0 && fraction <= 1), "Web Animations not yet implemented: Timing function behavior outside the range [0, 1] is not yet specified");
- return fraction;
- }
-
-private:
- LinearTimingFunction()
- : TimingFunction(LinearFunction)
- {
- }
-};
-
-
-// Forward declare so we can friend it below. Don't use in production code!
-class ChainedTimingFunctionTestHelper;
-
-class CubicBezierTimingFunction : public TimingFunction {
-public:
- enum SubType {
- Ease,
- EaseIn,
- EaseOut,
- EaseInOut,
- Custom
- };
-
- static PassRefPtr<CubicBezierTimingFunction> create(double x1, double y1, double x2, double y2)
- {
- return adoptRef(new CubicBezierTimingFunction(Custom, x1, y1, x2, y2));
- }
-
- static CubicBezierTimingFunction* preset(SubType subType)
- {
- switch (subType) {
- case Ease:
- {
- DEFINE_STATIC_REF(CubicBezierTimingFunction, ease, (adoptRef(new CubicBezierTimingFunction(Ease, 0.25, 0.1, 0.25, 1.0))));
- return ease;
- }
- case EaseIn:
- {
- DEFINE_STATIC_REF(CubicBezierTimingFunction, easeIn, (adoptRef(new CubicBezierTimingFunction(EaseIn, 0.42, 0.0, 1.0, 1.0))));
- return easeIn;
- }
- case EaseOut:
- {
- DEFINE_STATIC_REF(CubicBezierTimingFunction, easeOut, (adoptRef(new CubicBezierTimingFunction(EaseOut, 0.0, 0.0, 0.58, 1.0))));
- return easeOut;
- }
- case EaseInOut:
- {
- DEFINE_STATIC_REF(CubicBezierTimingFunction, easeInOut, (adoptRef(new CubicBezierTimingFunction(EaseInOut, 0.42, 0.0, 0.58, 1.0))));
- return easeInOut;
- }
- default:
- ASSERT_NOT_REACHED();
- return 0;
- }
- }
-
- ~CubicBezierTimingFunction() { }
-
- virtual double evaluate(double fraction, double accuracy) const
- {
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled() || (fraction >= 0 && fraction <= 1));
- ASSERT_WITH_MESSAGE(!RuntimeEnabledFeatures::webAnimationsCSSEnabled() || (fraction >= 0 && fraction <= 1), "Web Animations not yet implemented: Timing function behavior outside the range [0, 1] is not yet specified");
- if (!m_bezier)
- m_bezier = adoptPtr(new UnitBezier(m_x1, m_y1, m_x2, m_y2));
- return m_bezier->solve(fraction, accuracy);
- }
-
- double x1() const { return m_x1; }
- double y1() const { return m_y1; }
- double x2() const { return m_x2; }
- double y2() const { return m_y2; }
-
- SubType subType() const { return m_subType; }
-
-private:
- explicit CubicBezierTimingFunction(SubType subType, double x1, double y1, double x2, double y2)
- : TimingFunction(CubicBezierFunction)
- , m_x1(x1)
- , m_y1(y1)
- , m_x2(x2)
- , m_y2(y2)
- , m_subType(subType)
- {
- }
-
- double m_x1;
- double m_y1;
- double m_x2;
- double m_y2;
- SubType m_subType;
- mutable OwnPtr<UnitBezier> m_bezier;
-};
-
-class StepsTimingFunction : public TimingFunction {
-public:
- enum SubType {
- Start,
- End,
- Custom
- };
-
- static PassRefPtr<StepsTimingFunction> create(int steps, bool stepAtStart)
- {
- return adoptRef(new StepsTimingFunction(Custom, steps, stepAtStart));
- }
-
- static StepsTimingFunction* preset(SubType subType)
- {
- switch (subType) {
- case Start:
- {
- DEFINE_STATIC_REF(StepsTimingFunction, start, (adoptRef(new StepsTimingFunction(Start, 1, true))));
- return start;
- }
- case End:
- {
- DEFINE_STATIC_REF(StepsTimingFunction, end, (adoptRef(new StepsTimingFunction(End, 1, false))));
- return end;
- }
- default:
- ASSERT_NOT_REACHED();
- return 0;
- }
- }
-
-
- ~StepsTimingFunction() { }
-
- virtual double evaluate(double fraction, double) const
- {
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled() || (fraction >= 0 && fraction <= 1));
- ASSERT_WITH_MESSAGE(!RuntimeEnabledFeatures::webAnimationsCSSEnabled() || (fraction >= 0 && fraction <= 1), "Web Animations not yet implemented: Timing function behavior outside the range [0, 1] is not yet specified");
- return std::min(1.0, (floor(m_steps * fraction) + m_stepAtStart) / m_steps);
- }
-
- int numberOfSteps() const { return m_steps; }
- bool stepAtStart() const { return m_stepAtStart; }
-
- SubType subType() const { return m_subType; }
-
-private:
- StepsTimingFunction(SubType subType, int steps, bool stepAtStart)
- : TimingFunction(StepsFunction)
- , m_steps(steps)
- , m_stepAtStart(stepAtStart)
- , m_subType(subType)
- {
- }
-
- int m_steps;
- bool m_stepAtStart;
- SubType m_subType;
-};
-
-class ChainedTimingFunction : public TimingFunction {
-public:
- static PassRefPtr<ChainedTimingFunction> create()
- {
- return adoptRef(new ChainedTimingFunction);
- }
-
- void appendSegment(double upperBound, TimingFunction* timingFunction)
- {
- double max = m_segments.isEmpty() ? 0 : m_segments.last().max();
- ASSERT(upperBound > max);
- m_segments.append(Segment(max, upperBound, timingFunction));
- }
- virtual double evaluate(double fraction, double accuracy) const
- {
- ASSERT_WITH_MESSAGE(fraction >= 0 && fraction <= 1, "Web Animations not yet implemented: Timing function behavior outside the range [0, 1] is not yet specified");
- ASSERT(!m_segments.isEmpty());
- ASSERT(m_segments.last().max() == 1);
- size_t i = 0;
- const Segment* segment = &m_segments[i++];
- while (fraction >= segment->max() && i < m_segments.size()) {
- segment = &m_segments[i++];
- }
- return segment->evaluate(fraction, accuracy);
- }
-
-private:
- class Segment {
- public:
- Segment(double min, double max, TimingFunction* timingFunction)
- : m_min(min)
- , m_max(max)
- , m_timingFunction(timingFunction)
- { ASSERT(timingFunction); }
-
- double max() const { return m_max; }
- double evaluate(double fraction, double accuracy) const
- {
- return scaleFromLocal(m_timingFunction->evaluate(scaleToLocal(fraction), accuracy));
- }
-
- private:
- double scaleToLocal(double x) const { return (x - m_min) / (m_max - m_min); }
- double scaleFromLocal(double x) const { return blend(m_min, m_max, x); }
-
- double m_min;
- double m_max;
- RefPtr<TimingFunction> m_timingFunction;
-
- // FIXME: Come up with a public API for the segments and remove this.
- friend class CompositorAnimationsImpl;
- friend class CompositorAnimations;
-
- // Allow the compositor to reverse the timing function.
- friend class CompositorAnimationsTimingFunctionReverser;
-
- // Allow PrintTo/operator== of the segments. Can be removed once
- // ChainedTimingFunction has a public API for segments.
- friend class ChainedTimingFunctionTestHelper;
- };
-
- ChainedTimingFunction()
- : TimingFunction(ChainedFunction)
- {
- ASSERT(RuntimeEnabledFeatures::webAnimationsCSSEnabled());
- }
-
- Vector<Segment> m_segments;
-
- // FIXME: Come up with a public API for the segments and remove this.
- friend class CompositorAnimationsImpl;
- friend class CompositorAnimations;
-
- // Allow the compositor to reverse the timing function.
- friend class CompositorAnimationsTimingFunctionReverser;
-
- // Allow PrintTo/operator== of the segments. Can be removed once
- // ChainedTimingFunction has a public API for segments.
- friend class ChainedTimingFunctionTestHelper;
-};
-
-#define DEFINE_TIMING_FUNCTION_TYPE_CASTS(typeName) \
- DEFINE_TYPE_CASTS( \
- typeName##TimingFunction, TimingFunction, value, \
- value->type() == TimingFunction::typeName##Function, \
- value.type() == TimingFunction::typeName##Function)
-
-DEFINE_TIMING_FUNCTION_TYPE_CASTS(Linear);
-DEFINE_TIMING_FUNCTION_TYPE_CASTS(CubicBezier);
-DEFINE_TIMING_FUNCTION_TYPE_CASTS(Steps);
-DEFINE_TIMING_FUNCTION_TYPE_CASTS(Chained);
-
-} // namespace WebCore
-
-#endif // TimingFunction_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelper.cpp b/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelper.cpp
deleted file mode 100644
index f1eeb962374..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelper.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/animation/TimingFunctionTestHelper.h"
-
-
-namespace WebCore {
-
-// This class exists so that ChainedTimingFunction only needs to friend one thing.
-class ChainedTimingFunctionTestHelper {
- static void PrintTo(const ChainedTimingFunction& timingFunction, ::std::ostream* os)
- {
- // Forward declare the generic PrintTo function as ChainedTimingFunction needs to call it.
- void PrintTo(const TimingFunction&, ::std::ostream*);
-
- *os << "ChainedTimingFunction@" << &timingFunction << "(";
- for (size_t i = 0; i < timingFunction.m_segments.size(); i++) {
- ChainedTimingFunction::Segment segment = timingFunction.m_segments[i];
- PrintTo(*(segment.m_timingFunction.get()), os);
- *os << "[" << segment.m_min << " -> " << segment.m_max << "]";
- if (i+1 != timingFunction.m_segments.size()) {
- *os << ", ";
- }
- }
- *os << ")";
- }
-
- static bool equals(const ChainedTimingFunction& lhs, const TimingFunction& rhs)
- {
- if (rhs.type() != TimingFunction::ChainedFunction)
- return false;
-
- if (&lhs == &rhs)
- return true;
-
- const ChainedTimingFunction& ctf = toChainedTimingFunction(rhs);
- if (lhs.m_segments.size() != ctf.m_segments.size())
- return false;
-
- for (size_t i = 0; i < lhs.m_segments.size(); i++) {
- if (!equals(lhs.m_segments[i], ctf.m_segments[i]))
- return false;
- }
- return true;
- }
-
- static bool equals(const ChainedTimingFunction::Segment& lhs, const ChainedTimingFunction::Segment& rhs)
- {
- if (&lhs == &rhs)
- return true;
-
- if ((lhs.m_min != rhs.m_min) || (lhs.m_max != rhs.m_max))
- return false;
-
- if (lhs.m_timingFunction == rhs.m_timingFunction)
- return true;
-
- ASSERT(lhs.m_timingFunction);
- ASSERT(rhs.m_timingFunction);
-
- return (*(lhs.m_timingFunction.get())) == (*(rhs.m_timingFunction.get()));
- }
-
- friend void PrintTo(const ChainedTimingFunction&, ::std::ostream*);
- friend bool operator==(const ChainedTimingFunction& lhs, const TimingFunction& rhs);
-};
-
-void PrintTo(const LinearTimingFunction& timingFunction, ::std::ostream* os)
-{
- *os << "LinearTimingFunction@" << &timingFunction;
-}
-
-void PrintTo(const CubicBezierTimingFunction& timingFunction, ::std::ostream* os)
-{
- *os << "CubicBezierTimingFunction@" << &timingFunction << "(";
- switch (timingFunction.subType()) {
- case CubicBezierTimingFunction::Ease:
- *os << "Ease";
- break;
- case CubicBezierTimingFunction::EaseIn:
- *os << "EaseIn";
- break;
- case CubicBezierTimingFunction::EaseOut:
- *os << "EaseOut";
- break;
- case CubicBezierTimingFunction::EaseInOut:
- *os << "EaseInOut";
- break;
- case CubicBezierTimingFunction::Custom:
- *os << "Custom";
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- *os << ", " << timingFunction.x1();
- *os << ", " << timingFunction.y1();
- *os << ", " << timingFunction.x2();
- *os << ", " << timingFunction.y2();
- *os << ")";
-}
-
-void PrintTo(const StepsTimingFunction& timingFunction, ::std::ostream* os)
-{
- *os << "StepsTimingFunction@" << &timingFunction << "(";
- switch (timingFunction.subType()) {
- case StepsTimingFunction::Start:
- *os << "Start";
- break;
- case StepsTimingFunction::End:
- *os << "End";
- break;
- case StepsTimingFunction::Custom:
- *os << "Custom";
- break;
- default:
- ASSERT_NOT_REACHED();
- }
- *os << ", " << timingFunction.numberOfSteps();
- *os << ", " << (timingFunction.stepAtStart() ? "true" : "false");
- *os << ")";
-}
-
-void PrintTo(const ChainedTimingFunction& timingFunction, ::std::ostream* os)
-{
- ChainedTimingFunctionTestHelper::PrintTo(timingFunction, os);
-}
-
-// The generic PrintTo *must* come after the non-generic PrintTo otherwise it
-// will end up calling itself.
-void PrintTo(const TimingFunction& timingFunction, ::std::ostream* os)
-{
- switch (timingFunction.type()) {
- case TimingFunction::LinearFunction: {
- const LinearTimingFunction& linear = toLinearTimingFunction(timingFunction);
- PrintTo(linear, os);
- return;
- }
- case TimingFunction::CubicBezierFunction: {
- const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(timingFunction);
- PrintTo(cubic, os);
- return;
- }
- case TimingFunction::StepsFunction: {
- const StepsTimingFunction& step = toStepsTimingFunction(timingFunction);
- PrintTo(step, os);
- return;
- }
- case TimingFunction::ChainedFunction: {
- const ChainedTimingFunction& chained = toChainedTimingFunction(timingFunction);
- PrintTo(chained, os);
- return;
- }
- default:
- ASSERT_NOT_REACHED();
- }
-}
-
-bool operator==(const LinearTimingFunction& lhs, const TimingFunction& rhs)
-{
- return rhs.type() == TimingFunction::LinearFunction;
-}
-
-bool operator==(const CubicBezierTimingFunction& lhs, const TimingFunction& rhs)
-{
- if (rhs.type() != TimingFunction::CubicBezierFunction)
- return false;
-
- const CubicBezierTimingFunction& ctf = toCubicBezierTimingFunction(rhs);
- if ((lhs.subType() == CubicBezierTimingFunction::Custom) && (ctf.subType() == CubicBezierTimingFunction::Custom))
- return (lhs.x1() == ctf.x1()) && (lhs.y1() == ctf.y1()) && (lhs.x2() == ctf.x2()) && (lhs.y2() == ctf.y2());
-
- return lhs.subType() == ctf.subType();
-}
-
-bool operator==(const StepsTimingFunction& lhs, const TimingFunction& rhs)
-{
- if (rhs.type() != TimingFunction::StepsFunction)
- return false;
-
- const StepsTimingFunction& stf = toStepsTimingFunction(rhs);
- if ((lhs.subType() == StepsTimingFunction::Custom) && (stf.subType() == StepsTimingFunction::Custom))
- return (lhs.numberOfSteps() == stf.numberOfSteps()) && (lhs.stepAtStart() == stf.stepAtStart());
-
- return lhs.subType() == stf.subType();
-}
-
-bool operator==(const ChainedTimingFunction& lhs, const TimingFunction& rhs)
-{
- return ChainedTimingFunctionTestHelper::equals(lhs, rhs);
-}
-
-// Like in the PrintTo case, the generic operator== *must* come after the
-// non-generic operator== otherwise it will end up calling itself.
-bool operator==(const TimingFunction& lhs, const TimingFunction& rhs)
-{
- switch (lhs.type()) {
- case TimingFunction::LinearFunction: {
- const LinearTimingFunction& linear = toLinearTimingFunction(lhs);
- return (linear == rhs);
- }
- case TimingFunction::CubicBezierFunction: {
- const CubicBezierTimingFunction& cubic = toCubicBezierTimingFunction(lhs);
- return (cubic == rhs);
- }
- case TimingFunction::StepsFunction: {
- const StepsTimingFunction& step = toStepsTimingFunction(lhs);
- return (step == rhs);
- }
- case TimingFunction::ChainedFunction: {
- const ChainedTimingFunction& chained = toChainedTimingFunction(lhs);
- return (chained == rhs);
- }
- default:
- ASSERT_NOT_REACHED();
- }
- return false;
-}
-
-// No need to define specific operator!= as they can all come via this function.
-bool operator!=(const TimingFunction& lhs, const TimingFunction& rhs)
-{
- return !(lhs == rhs);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelper.h b/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelper.h
deleted file mode 100644
index 06eaf0604f6..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelper.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * Make testing with gtest and gmock nicer by adding pretty print and other
- * helper functions.
- */
-
-#ifndef TimingFunctionTestHelper_h
-#define TimingFunctionTestHelper_h
-
-#include "core/platform/animation/TimingFunction.h"
-
-#include <ostream> // NOLINT
-
-namespace WebCore {
-
-// PrintTo functions
-void PrintTo(const LinearTimingFunction&, ::std::ostream*);
-void PrintTo(const CubicBezierTimingFunction&, ::std::ostream*);
-void PrintTo(const StepsTimingFunction&, ::std::ostream*);
-void PrintTo(const ChainedTimingFunction&, ::std::ostream*);
-void PrintTo(const TimingFunction&, ::std::ostream*);
-
-// operator== functions
-bool operator==(const LinearTimingFunction&, const TimingFunction&);
-bool operator==(const CubicBezierTimingFunction&, const TimingFunction&);
-bool operator==(const StepsTimingFunction&, const TimingFunction&);
-bool operator==(const ChainedTimingFunction&, const TimingFunction&);
-
-bool operator==(const TimingFunction&, const TimingFunction&);
-bool operator!=(const TimingFunction&, const TimingFunction&);
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelperTest.cpp b/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelperTest.cpp
deleted file mode 100644
index 01059a6c3ac..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/animation/TimingFunctionTestHelperTest.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/platform/animation/TimingFunctionTestHelper.h"
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include <sstream>
-#include <string>
-
-// FIXME: Remove once https://codereview.chromium.org/50603011/ lands.
-#define EXPECT_REFV_EQ(a, b) EXPECT_EQ(*(a.get()), *(b.get()))
-#define EXPECT_REFV_NE(a, b) EXPECT_NE(*(a.get()), *(b.get()))
-
-// Couple of macros to quickly assert a bunch of timing functions are not
-// equal.
-#define NE_STRINGIZE(x) NE_STRINGIZE2(x)
-#define NE_STRINGIZE2(x) #x
-#define NE_HELPER(v) \
- Vector<std::pair<std::string, RefPtr<TimingFunction> > > v;
-#define NE_HELPER_APPEND(v, x) \
- v.append(std::make_pair(std::string("Line " NE_STRINGIZE(__LINE__) ":" # x), x))
-#define NE_HELPER_LOOP(v) \
- for (size_t i = 0; i != v.size(); ++i) { \
- for (size_t j = 0; j != v.size(); ++j) { \
- if (i == j) \
- continue; \
- EXPECT_REFV_NE(v[i].second, v[j].second) \
- << v[i].first \
- << " (" << ::testing::PrintToString(*v[i].second.get()) << ")" \
- << " == " \
- << v[j].first \
- << " (" << ::testing::PrintToString(*v[j].second.get()) << ")" \
- << "\n"; \
- } \
- }
-
-namespace {
-
-using namespace WebCore;
-
-class TimingFunctionTestHelperTest : public ::testing::Test {
-
-public:
- // Make sure that the CubicBezierTimingFunction call goes via the generic
- // TimingFunction PrintTo.
- ::std::string PrintToString(RefPtr<CubicBezierTimingFunction> timing)
- {
- RefPtr<TimingFunction> generic = timing;
- return PrintToString(generic.get());
- }
-
- ::std::string PrintToString(RefPtr<TimingFunction> timing)
- {
- return PrintToString(timing.get());
- }
-
- ::std::string PrintToString(const TimingFunction* timing)
- {
- return ::testing::PrintToString(*timing);
- }
-};
-
-TEST_F(TimingFunctionTestHelperTest, LinearPrintTo)
-{
- RefPtr<TimingFunction> linearTiming = LinearTimingFunction::create();
- EXPECT_THAT(
- PrintToString(linearTiming),
- ::testing::MatchesRegex("LinearTimingFunction@.*"));
-}
-
-TEST_F(TimingFunctionTestHelperTest, CubicPrintTo)
-{
- RefPtr<TimingFunction> cubicEaseTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
- EXPECT_THAT(
- PrintToString(cubicEaseTiming),
- ::testing::MatchesRegex("CubicBezierTimingFunction@.*\\(EaseIn, 0.42, 0, 1, 1\\)"));
-
- RefPtr<TimingFunction> cubicCustomTiming = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
- EXPECT_THAT(
- PrintToString(cubicCustomTiming),
- ::testing::MatchesRegex("CubicBezierTimingFunction@.*\\(Custom, 0.17, 0.67, 1, -1.73\\)"));
-}
-
-TEST_F(TimingFunctionTestHelperTest, StepPrintTo)
-{
- RefPtr<TimingFunction> stepTimingStart = StepsTimingFunction::preset(StepsTimingFunction::Start);
- EXPECT_THAT(
- PrintToString(stepTimingStart),
- ::testing::MatchesRegex("StepsTimingFunction@.*\\(Start, 1, true\\)"));
-
- RefPtr<TimingFunction> stepTimingCustom = StepsTimingFunction::create(5, false);
- EXPECT_THAT(
- PrintToString(stepTimingCustom),
- ::testing::MatchesRegex("StepsTimingFunction@.*\\(Custom, 5, false\\)"));
-}
-
-TEST_F(TimingFunctionTestHelperTest, ChainedPrintTo)
-{
- RefPtr<TimingFunction> linearTiming = LinearTimingFunction::create();
- RefPtr<ChainedTimingFunction> chainedLinearSingle = ChainedTimingFunction::create();
- chainedLinearSingle->appendSegment(1.0, linearTiming.get());
- EXPECT_THAT(
- PrintToString(chainedLinearSingle),
- ::testing::MatchesRegex(
- "ChainedTimingFunction@.*\\("
- "LinearTimingFunction@.*\\[0 -> 1\\]"
- "\\)"));
-
- RefPtr<TimingFunction> cubicCustomTiming = CubicBezierTimingFunction::create(1.0, 0.0, 1, -1);
-
- RefPtr<ChainedTimingFunction> chainedMixed = ChainedTimingFunction::create();
- chainedMixed->appendSegment(0.75, chainedLinearSingle.get());
- chainedMixed->appendSegment(1.0, cubicCustomTiming.get());
- EXPECT_THAT(
- PrintToString(chainedMixed),
- ::testing::MatchesRegex(
- "ChainedTimingFunction@.*\\("
- "ChainedTimingFunction@.*\\("
- "LinearTimingFunction@.*\\[0 -> 1\\]"
- "\\)\\[0 -> 0.75\\], "
- "CubicBezierTimingFunction@.*\\(Custom, 1, 0, 1, -1\\)\\[0.75 -> 1\\]"
- "\\)"));
-}
-
-TEST_F(TimingFunctionTestHelperTest, BaseOperatorEq)
-{
- RefPtr<TimingFunction> linearTiming = LinearTimingFunction::create();
- RefPtr<TimingFunction> cubicTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
- RefPtr<TimingFunction> cubicTiming2 = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
- RefPtr<TimingFunction> stepsTiming1 = StepsTimingFunction::preset(StepsTimingFunction::End);
- RefPtr<TimingFunction> stepsTiming2 = StepsTimingFunction::create(5, true);
-
- RefPtr<ChainedTimingFunction> chainedTiming1 = ChainedTimingFunction::create();
- chainedTiming1->appendSegment(1.0, linearTiming.get());
-
- RefPtr<ChainedTimingFunction> chainedTiming2 = ChainedTimingFunction::create();
- chainedTiming2->appendSegment(0.5, cubicTiming1.get());
- chainedTiming2->appendSegment(1.0, cubicTiming2.get());
-
- NE_HELPER(v);
- NE_HELPER_APPEND(v, linearTiming);
- NE_HELPER_APPEND(v, cubicTiming1);
- NE_HELPER_APPEND(v, cubicTiming2);
- NE_HELPER_APPEND(v, stepsTiming1);
- NE_HELPER_APPEND(v, stepsTiming2);
- NE_HELPER_APPEND(v, chainedTiming1);
- NE_HELPER_APPEND(v, chainedTiming2);
- NE_HELPER_LOOP(v);
-}
-
-TEST_F(TimingFunctionTestHelperTest, LinearOperatorEq)
-{
- RefPtr<TimingFunction> linearTiming1 = LinearTimingFunction::create();
- RefPtr<TimingFunction> linearTiming2 = LinearTimingFunction::create();
- EXPECT_REFV_EQ(linearTiming1, linearTiming1);
- EXPECT_REFV_EQ(linearTiming1, linearTiming2);
-}
-
-TEST_F(TimingFunctionTestHelperTest, CubicOperatorEq)
-{
- RefPtr<TimingFunction> cubicEaseInTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
- RefPtr<TimingFunction> cubicEaseInTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
- EXPECT_REFV_EQ(cubicEaseInTiming1, cubicEaseInTiming1);
- EXPECT_REFV_EQ(cubicEaseInTiming1, cubicEaseInTiming2);
-
- RefPtr<TimingFunction> cubicEaseOutTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
- RefPtr<TimingFunction> cubicEaseOutTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
- EXPECT_REFV_EQ(cubicEaseOutTiming1, cubicEaseOutTiming2);
-
- RefPtr<TimingFunction> cubicEaseInOutTiming1 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
- RefPtr<TimingFunction> cubicEaseInOutTiming2 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut);
- EXPECT_REFV_EQ(cubicEaseInOutTiming1, cubicEaseInOutTiming2);
-
- RefPtr<TimingFunction> cubicCustomTiming1 = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
- RefPtr<TimingFunction> cubicCustomTiming2 = CubicBezierTimingFunction::create(0.17, 0.67, 1, -1.73);
- EXPECT_REFV_EQ(cubicCustomTiming1, cubicCustomTiming2);
-
- NE_HELPER(v);
- NE_HELPER_APPEND(v, cubicEaseInTiming1);
- NE_HELPER_APPEND(v, cubicEaseOutTiming1);
- NE_HELPER_APPEND(v, cubicEaseInOutTiming1);
- NE_HELPER_APPEND(v, cubicCustomTiming1);
- NE_HELPER_LOOP(v);
-}
-
-TEST_F(TimingFunctionTestHelperTest, CubicOperatorEqReflectivity)
-{
- RefPtr<TimingFunction> cubicA = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
- RefPtr<TimingFunction> cubicB = CubicBezierTimingFunction::create(0.42, 0.0, 1.0, 1.0);
- EXPECT_REFV_NE(cubicA, cubicB);
- EXPECT_REFV_NE(cubicB, cubicA);
-}
-
-TEST_F(TimingFunctionTestHelperTest, StepsOperatorEq)
-{
- RefPtr<TimingFunction> stepsTimingStart1 = StepsTimingFunction::preset(StepsTimingFunction::Start);
- RefPtr<TimingFunction> stepsTimingStart2 = StepsTimingFunction::preset(StepsTimingFunction::Start);
- EXPECT_REFV_EQ(stepsTimingStart1, stepsTimingStart1);
- EXPECT_REFV_EQ(stepsTimingStart1, stepsTimingStart2);
-
- RefPtr<TimingFunction> stepsTimingEnd1 = StepsTimingFunction::preset(StepsTimingFunction::End);
- RefPtr<TimingFunction> stepsTimingEnd2 = StepsTimingFunction::preset(StepsTimingFunction::End);
- EXPECT_REFV_EQ(stepsTimingEnd1, stepsTimingEnd2);
-
- RefPtr<TimingFunction> stepsTimingCustom1 = StepsTimingFunction::create(5, true);
- RefPtr<TimingFunction> stepsTimingCustom2 = StepsTimingFunction::create(5, false);
- RefPtr<TimingFunction> stepsTimingCustom3 = StepsTimingFunction::create(7, true);
- RefPtr<TimingFunction> stepsTimingCustom4 = StepsTimingFunction::create(7, false);
-
- EXPECT_REFV_EQ(stepsTimingCustom1, StepsTimingFunction::create(5, true));
- EXPECT_REFV_EQ(stepsTimingCustom2, StepsTimingFunction::create(5, false));
- EXPECT_REFV_EQ(stepsTimingCustom3, StepsTimingFunction::create(7, true));
- EXPECT_REFV_EQ(stepsTimingCustom4, StepsTimingFunction::create(7, false));
-
- NE_HELPER(v);
- NE_HELPER_APPEND(v, stepsTimingStart1);
- NE_HELPER_APPEND(v, stepsTimingEnd1);
- NE_HELPER_APPEND(v, stepsTimingCustom1);
- NE_HELPER_APPEND(v, stepsTimingCustom2);
- NE_HELPER_APPEND(v, stepsTimingCustom3);
- NE_HELPER_APPEND(v, stepsTimingCustom4);
- NE_HELPER_LOOP(v);
-}
-
-TEST_F(TimingFunctionTestHelperTest, StepsOperatorEqReflectivity)
-{
- RefPtr<TimingFunction> stepsA = StepsTimingFunction::preset(StepsTimingFunction::Start);
- RefPtr<TimingFunction> stepsB = StepsTimingFunction::create(1, true);
- EXPECT_REFV_NE(stepsA, stepsB);
- EXPECT_REFV_NE(stepsB, stepsA);
-}
-
-TEST_F(TimingFunctionTestHelperTest, ChainedEq)
-{
- // Single item in chain
- RefPtr<TimingFunction> cubicTiming1 = CubicBezierTimingFunction::create(0.25, 0.1, 0.25, 1.0);
- RefPtr<TimingFunction> cubicTiming2 = CubicBezierTimingFunction::create(0.25, 0.1, 0.25, 1.0);
- RefPtr<TimingFunction> cubicTiming3 = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
-
- RefPtr<ChainedTimingFunction> chainedSingleCubic1 = ChainedTimingFunction::create();
- chainedSingleCubic1->appendSegment(1.0, cubicTiming1.get());
- EXPECT_REFV_EQ(chainedSingleCubic1, chainedSingleCubic1);
-
- RefPtr<ChainedTimingFunction> chainedSingleCubic2 = ChainedTimingFunction::create();
- chainedSingleCubic2->appendSegment(1.0, cubicTiming1.get()); // Same inner timing function
- EXPECT_REFV_EQ(chainedSingleCubic1, chainedSingleCubic2);
-
- RefPtr<ChainedTimingFunction> chainedSingleCubic3 = ChainedTimingFunction::create();
- chainedSingleCubic3->appendSegment(1.0, cubicTiming2.get()); // == inner timing function
- EXPECT_REFV_EQ(chainedSingleCubic1, chainedSingleCubic3);
-
- RefPtr<ChainedTimingFunction> chainedSingleCubic4 = ChainedTimingFunction::create();
- chainedSingleCubic4->appendSegment(0.5, cubicTiming1.get()); // Different offset
- EXPECT_REFV_NE(chainedSingleCubic1, chainedSingleCubic4);
- EXPECT_REFV_NE(chainedSingleCubic3, chainedSingleCubic4);
-
- RefPtr<ChainedTimingFunction> chainedSingleCubic5 = ChainedTimingFunction::create();
- chainedSingleCubic5->appendSegment(1.0, cubicTiming3.get()); // != inner timing function (same type)
- EXPECT_REFV_NE(chainedSingleCubic1, chainedSingleCubic5);
- EXPECT_REFV_NE(chainedSingleCubic2, chainedSingleCubic5);
- EXPECT_REFV_NE(chainedSingleCubic3, chainedSingleCubic5);
- EXPECT_REFV_NE(chainedSingleCubic4, chainedSingleCubic5);
-
- RefPtr<TimingFunction> linearTiming1 = LinearTimingFunction::create();
- RefPtr<ChainedTimingFunction> chainedSingleLinear1 = ChainedTimingFunction::create();
- chainedSingleLinear1->appendSegment(1.0, linearTiming1.get()); // != inner timing function (different type)
- EXPECT_REFV_NE(chainedSingleLinear1, chainedSingleCubic1);
- EXPECT_REFV_NE(chainedSingleLinear1, chainedSingleCubic2);
- EXPECT_REFV_NE(chainedSingleLinear1, chainedSingleCubic3);
- EXPECT_REFV_NE(chainedSingleLinear1, chainedSingleCubic4);
-
- // Multiple items in chain
- RefPtr<ChainedTimingFunction> chainedMixed1 = ChainedTimingFunction::create();
- chainedMixed1->appendSegment(0.25, chainedSingleLinear1.get());
- chainedMixed1->appendSegment(1.0, cubicTiming1.get());
-
- RefPtr<ChainedTimingFunction> chainedMixed2 = ChainedTimingFunction::create();
- chainedMixed2->appendSegment(0.25, chainedSingleLinear1.get());
- chainedMixed2->appendSegment(1.0, cubicTiming1.get());
-
- RefPtr<ChainedTimingFunction> chainedMixed3 = ChainedTimingFunction::create();
- chainedMixed3->appendSegment(0.25, chainedSingleLinear1.get());
- chainedMixed3->appendSegment(1.0, cubicTiming2.get());
-
- EXPECT_REFV_EQ(chainedMixed1, chainedMixed2);
- EXPECT_REFV_EQ(chainedMixed1, chainedMixed3);
- EXPECT_REFV_NE(chainedMixed1, chainedSingleCubic1);
- EXPECT_REFV_NE(chainedMixed1, chainedSingleLinear1);
-
- RefPtr<ChainedTimingFunction> chainedMixed4 = ChainedTimingFunction::create();
- chainedMixed4->appendSegment(0.20, chainedSingleLinear1.get()); // Different offset
- chainedMixed4->appendSegment(1.0, cubicTiming1.get());
- EXPECT_REFV_NE(chainedMixed1, chainedMixed4);
-}
-
-} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObject.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObject.cpp
deleted file mode 100644
index afbf866911b..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObject.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/chromium/ChromiumDataObject.h"
-
-#include "core/platform/Pasteboard.h"
-#include "platform/clipboard/ClipboardMimeTypes.h"
-#include "platform/clipboard/ClipboardUtilities.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebClipboard.h"
-
-namespace WebCore {
-
-PassRefPtr<ChromiumDataObject> ChromiumDataObject::createFromPasteboard(PasteMode pasteMode)
-{
- RefPtr<ChromiumDataObject> dataObject = create();
- blink::WebClipboard::Buffer buffer = Pasteboard::generalPasteboard()->buffer();
- uint64_t sequenceNumber = blink::Platform::current()->clipboard()->sequenceNumber(buffer);
- bool ignored;
- blink::WebVector<blink::WebString> webTypes = blink::Platform::current()->clipboard()->readAvailableTypes(buffer, &ignored);
- ListHashSet<String> types;
- for (size_t i = 0; i < webTypes.size(); ++i)
- types.add(webTypes[i]);
- for (ListHashSet<String>::const_iterator it = types.begin(); it != types.end(); ++it) {
- if (pasteMode == PlainTextOnly && *it != mimeTypeTextPlain)
- continue;
- dataObject->m_itemList.append(ChromiumDataObjectItem::createFromPasteboard(*it, sequenceNumber));
- }
- return dataObject.release();
-}
-
-PassRefPtr<ChromiumDataObject> ChromiumDataObject::create()
-{
- return adoptRef(new ChromiumDataObject());
-}
-
-PassRefPtr<ChromiumDataObject> ChromiumDataObject::copy() const
-{
- return adoptRef(new ChromiumDataObject(*this));
-}
-
-size_t ChromiumDataObject::length() const
-{
- return m_itemList.size();
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::item(unsigned long index)
-{
- if (index >= length())
- return 0;
- return m_itemList[index];
-}
-
-void ChromiumDataObject::deleteItem(unsigned long index)
-{
- if (index >= length())
- return;
- m_itemList.remove(index);
-}
-
-void ChromiumDataObject::clearAll()
-{
- m_itemList.clear();
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::add(const String& data, const String& type)
-{
- RefPtr<ChromiumDataObjectItem> item = ChromiumDataObjectItem::createFromString(type, data);
- if (!internalAddStringItem(item))
- return 0;
- return item;
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::add(PassRefPtr<File> file)
-{
- if (!file)
- return 0;
-
- RefPtr<ChromiumDataObjectItem> item = ChromiumDataObjectItem::createFromFile(file);
- m_itemList.append(item);
- return item;
-}
-
-void ChromiumDataObject::clearData(const String& type)
-{
- for (size_t i = 0; i < m_itemList.size(); ++i) {
- if (m_itemList[i]->kind() == ChromiumDataObjectItem::StringKind && m_itemList[i]->type() == type) {
- // Per the spec, type must be unique among all items of kind 'string'.
- m_itemList.remove(i);
- return;
- }
- }
-}
-
-void ChromiumDataObject::clearAllExceptFiles()
-{
- for (size_t i = 0; i < m_itemList.size(); ) {
- if (m_itemList[i]->kind() != ChromiumDataObjectItem::FileKind) {
- m_itemList.remove(i);
- continue;
- }
- ++i;
- }
-}
-
-ListHashSet<String> ChromiumDataObject::types() const
-{
- ListHashSet<String> results;
- bool containsFiles = false;
- for (size_t i = 0; i < m_itemList.size(); ++i) {
- switch (m_itemList[i]->kind()) {
- case ChromiumDataObjectItem::StringKind:
- results.add(m_itemList[i]->type());
- break;
- case ChromiumDataObjectItem::FileKind:
- containsFiles = true;
- break;
- }
- }
- if (containsFiles)
- results.add(mimeTypeFiles);
- return results;
-}
-
-String ChromiumDataObject::getData(const String& type) const
-{
- for (size_t i = 0; i < m_itemList.size(); ++i) {
- if (m_itemList[i]->kind() == ChromiumDataObjectItem::StringKind && m_itemList[i]->type() == type)
- return m_itemList[i]->internalGetAsString();
- }
- return String();
-}
-
-bool ChromiumDataObject::setData(const String& type, const String& data)
-{
- clearData(type);
- if (!add(data, type))
- ASSERT_NOT_REACHED();
- return true;
-}
-
-void ChromiumDataObject::urlAndTitle(String& url, String* title) const
-{
- RefPtr<ChromiumDataObjectItem> item = findStringItem(mimeTypeTextURIList);
- if (!item)
- return;
- url = convertURIListToURL(item->internalGetAsString());
- if (title)
- *title = item->title();
-}
-
-void ChromiumDataObject::setURLAndTitle(const String& url, const String& title)
-{
- clearData(mimeTypeTextURIList);
- internalAddStringItem(ChromiumDataObjectItem::createFromURL(url, title));
-}
-
-void ChromiumDataObject::htmlAndBaseURL(String& html, KURL& baseURL) const
-{
- RefPtr<ChromiumDataObjectItem> item = findStringItem(mimeTypeTextHTML);
- if (!item)
- return;
- html = item->internalGetAsString();
- baseURL = item->baseURL();
-}
-
-void ChromiumDataObject::setHTMLAndBaseURL(const String& html, const KURL& baseURL)
-{
- clearData(mimeTypeTextHTML);
- internalAddStringItem(ChromiumDataObjectItem::createFromHTML(html, baseURL));
-}
-
-bool ChromiumDataObject::containsFilenames() const
-{
- for (size_t i = 0; i < m_itemList.size(); ++i)
- if (m_itemList[i]->isFilename())
- return true;
- return false;
-}
-
-Vector<String> ChromiumDataObject::filenames() const
-{
- Vector<String> results;
- for (size_t i = 0; i < m_itemList.size(); ++i)
- if (m_itemList[i]->isFilename())
- results.append(static_cast<File*>(m_itemList[i]->getAsFile().get())->path());
- return results;
-}
-
-void ChromiumDataObject::addFilename(const String& filename, const String& displayName)
-{
- internalAddFileItem(ChromiumDataObjectItem::createFromFile(File::createWithName(filename, displayName, File::AllContentTypes)));
-}
-
-void ChromiumDataObject::addSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
-{
- internalAddFileItem(ChromiumDataObjectItem::createFromSharedBuffer(name, buffer));
-}
-
-ChromiumDataObject::ChromiumDataObject()
- : m_modifierKeyState(0)
-{
-}
-
-ChromiumDataObject::ChromiumDataObject(const ChromiumDataObject& other)
- : RefCounted<ChromiumDataObject>()
- , m_itemList(other.m_itemList)
- , m_modifierKeyState(0)
-{
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObject::findStringItem(const String& type) const
-{
- for (size_t i = 0; i < m_itemList.size(); ++i) {
- if (m_itemList[i]->kind() == ChromiumDataObjectItem::StringKind && m_itemList[i]->type() == type)
- return m_itemList[i];
- }
- return 0;
-}
-
-bool ChromiumDataObject::internalAddStringItem(PassRefPtr<ChromiumDataObjectItem> item)
-{
- ASSERT(item->kind() == ChromiumDataObjectItem::StringKind);
- for (size_t i = 0; i < m_itemList.size(); ++i)
- if (m_itemList[i]->kind() == ChromiumDataObjectItem::StringKind && m_itemList[i]->type() == item->type())
- return false;
-
- m_itemList.append(item);
- return true;
-}
-
-void ChromiumDataObject::internalAddFileItem(PassRefPtr<ChromiumDataObjectItem> item)
-{
- ASSERT(item->kind() == ChromiumDataObjectItem::FileKind);
- m_itemList.append(item);
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObject.h b/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObject.h
deleted file mode 100644
index 506952d0581..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObject.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ChromiumDataObject_h
-#define ChromiumDataObject_h
-
-#include "core/platform/chromium/ChromiumDataObjectItem.h"
-#include "platform/PasteMode.h"
-#include "platform/Supplementable.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/StringHash.h"
-#include "wtf/text/WTFString.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class KURL;
-class SharedBuffer;
-
-// A data object for holding data that would be in a clipboard or moved
-// during a drag-n-drop operation. This is the data that WebCore is aware
-// of and is not specific to a platform.
-class ChromiumDataObject : public RefCounted<ChromiumDataObject>, public Supplementable<ChromiumDataObject> {
-public:
- static PassRefPtr<ChromiumDataObject> createFromPasteboard(PasteMode);
- static PassRefPtr<ChromiumDataObject> create();
-
- PassRefPtr<ChromiumDataObject> copy() const;
-
- // DataTransferItemList support.
- size_t length() const;
- PassRefPtr<ChromiumDataObjectItem> item(unsigned long index);
- // FIXME: Implement V8DataTransferItemList::indexedPropertyDeleter to get this called.
- void deleteItem(unsigned long index);
- void clearAll();
- // Returns null if an item already exists with the provided type.
- PassRefPtr<ChromiumDataObjectItem> add(const String& data, const String& type);
- PassRefPtr<ChromiumDataObjectItem> add(PassRefPtr<File>);
-
- // WebCore helpers.
- void clearData(const String& type);
- void clearAllExceptFiles();
-
- ListHashSet<String> types() const;
- String getData(const String& type) const;
- bool setData(const String& type, const String& data);
-
- void urlAndTitle(String& url, String* title = 0) const;
- void setURLAndTitle(const String& url, const String& title);
- void htmlAndBaseURL(String& html, KURL& baseURL) const;
- void setHTMLAndBaseURL(const String& html, const KURL& baseURL);
-
- // Used for dragging in files from the desktop.
- bool containsFilenames() const;
- Vector<String> filenames() const;
- void addFilename(const String& filename, const String& displayName);
-
- // Used to handle files (images) being dragged out.
- void addSharedBuffer(const String& name, PassRefPtr<SharedBuffer>);
-
- int modifierKeyState() const { return m_modifierKeyState; }
- void setModifierKeyState(int modifierKeyState) { m_modifierKeyState = modifierKeyState; }
-
-private:
- ChromiumDataObject();
- explicit ChromiumDataObject(const ChromiumDataObject&);
-
- PassRefPtr<ChromiumDataObjectItem> findStringItem(const String& type) const;
- bool internalAddStringItem(PassRefPtr<ChromiumDataObjectItem>);
- void internalAddFileItem(PassRefPtr<ChromiumDataObjectItem>);
-
- Vector<RefPtr<ChromiumDataObjectItem> > m_itemList;
-
- // State of Shift/Ctrl/Alt/Meta keys.
- int m_modifierKeyState;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObjectItem.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObjectItem.cpp
deleted file mode 100644
index bae44138447..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObjectItem.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/chromium/ChromiumDataObjectItem.h"
-
-#include "core/dom/StringCallback.h"
-#include "core/fileapi/Blob.h"
-#include "core/platform/Pasteboard.h"
-#include "platform/clipboard/ClipboardMimeTypes.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebClipboard.h"
-
-namespace WebCore {
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObjectItem::createFromString(const String& type, const String& data)
-{
- RefPtr<ChromiumDataObjectItem> item = adoptRef(new ChromiumDataObjectItem(StringKind, type));
- item->m_data = data;
- return item.release();
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObjectItem::createFromFile(PassRefPtr<File> file)
-{
- RefPtr<ChromiumDataObjectItem> item = adoptRef(new ChromiumDataObjectItem(FileKind, file->type()));
- item->m_file = file;
- return item.release();
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObjectItem::createFromURL(const String& url, const String& title)
-{
- RefPtr<ChromiumDataObjectItem> item = adoptRef(new ChromiumDataObjectItem(StringKind, mimeTypeTextURIList));
- item->m_data = url;
- item->m_title = title;
- return item.release();
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObjectItem::createFromHTML(const String& html, const KURL& baseURL)
-{
- RefPtr<ChromiumDataObjectItem> item = adoptRef(new ChromiumDataObjectItem(StringKind, mimeTypeTextHTML));
- item->m_data = html;
- item->m_baseURL = baseURL;
- return item.release();
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObjectItem::createFromSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
-{
- RefPtr<ChromiumDataObjectItem> item = adoptRef(new ChromiumDataObjectItem(FileKind, String()));
- item->m_sharedBuffer = buffer;
- item->m_title = name;
- return item.release();
-}
-
-PassRefPtr<ChromiumDataObjectItem> ChromiumDataObjectItem::createFromPasteboard(const String& type, uint64_t sequenceNumber)
-{
- if (type == mimeTypeImagePng)
- return adoptRef(new ChromiumDataObjectItem(FileKind, type, sequenceNumber));
- return adoptRef(new ChromiumDataObjectItem(StringKind, type, sequenceNumber));
-}
-
-ChromiumDataObjectItem::ChromiumDataObjectItem(Kind kind, const String& type)
- : m_source(InternalSource)
- , m_kind(kind)
- , m_type(type)
- , m_sequenceNumber(0)
-{
-}
-
-ChromiumDataObjectItem::ChromiumDataObjectItem(Kind kind, const String& type, uint64_t sequenceNumber)
- : m_source(PasteboardSource)
- , m_kind(kind)
- , m_type(type)
- , m_sequenceNumber(sequenceNumber)
-{
-}
-
-void ChromiumDataObjectItem::getAsString(PassOwnPtr<StringCallback> callback, ExecutionContext* context) const
-{
- if (!callback || kind() != StringKind)
- return;
-
- StringCallback::scheduleCallback(callback, context, internalGetAsString());
-}
-
-PassRefPtr<Blob> ChromiumDataObjectItem::getAsFile() const
-{
- if (kind() != FileKind)
- return 0;
-
- if (m_source == InternalSource) {
- if (m_file)
- return m_file;
- ASSERT(m_sharedBuffer);
- // FIXME: This code is currently impossible--we never populate m_sharedBuffer when dragging
- // in. At some point though, we may need to support correctly converting a shared buffer
- // into a file.
- return 0;
- }
-
- ASSERT(m_source == PasteboardSource);
- if (type() == mimeTypeImagePng) {
- // FIXME: This is pretty inefficient. We copy the data from the browser
- // to the renderer. We then place it in a blob in WebKit, which
- // registers it and copies it *back* to the browser. When a consumer
- // wants to read the data, we then copy the data back into the renderer.
- // https://bugs.webkit.org/show_bug.cgi?id=58107 has been filed to track
- // improvements to this code (in particular, add a registerClipboardBlob
- // method to the blob registry; that way the data is only copied over
- // into the renderer when it's actually read, not when the blob is
- // initially constructed).
- RefPtr<SharedBuffer> data = static_cast<PassRefPtr<SharedBuffer> >(blink::Platform::current()->clipboard()->readImage(blink::WebClipboard::BufferStandard));
- RefPtr<RawData> rawData = RawData::create();
- rawData->mutableData()->append(data->data(), data->size());
- OwnPtr<BlobData> blobData = BlobData::create();
- blobData->appendData(rawData, 0, -1);
- blobData->setContentType(mimeTypeImagePng);
- return Blob::create(BlobDataHandle::create(blobData.release(), data->size()));
- }
-
- return 0;
-}
-
-String ChromiumDataObjectItem::internalGetAsString() const
-{
- ASSERT(m_kind == StringKind);
-
- if (m_source == InternalSource)
- return m_data;
-
- ASSERT(m_source == PasteboardSource);
-
- blink::WebClipboard::Buffer buffer = Pasteboard::generalPasteboard()->buffer();
- String data;
- // This is ugly but there's no real alternative.
- if (m_type == mimeTypeTextPlain)
- data = blink::Platform::current()->clipboard()->readPlainText(buffer);
- else if (m_type == mimeTypeTextHTML) {
- blink::WebURL ignoredSourceURL;
- unsigned ignored;
- data = blink::Platform::current()->clipboard()->readHTML(buffer, &ignoredSourceURL, &ignored, &ignored);
- } else
- data = blink::Platform::current()->clipboard()->readCustomData(buffer, m_type);
-
- return blink::Platform::current()->clipboard()->sequenceNumber(buffer) == m_sequenceNumber ? data : String();
-}
-
-bool ChromiumDataObjectItem::isFilename() const
-{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=81261: When we properly support File dragout,
- // we'll need to make sure this works as expected for DragDataChromium.
- return m_kind == FileKind && m_file;
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObjectItem.h b/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObjectItem.h
deleted file mode 100644
index ecd328d54ab..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/ChromiumDataObjectItem.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ChromiumDataObjectItem_h
-#define ChromiumDataObjectItem_h
-
-#include "core/fileapi/File.h"
-#include "platform/SharedBuffer.h"
-#include "platform/weborigin/KURL.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class Blob;
-class ExecutionContext;
-class StringCallback;
-
-class ChromiumDataObjectItem : public RefCounted<ChromiumDataObjectItem> {
-public:
- enum Kind {
- StringKind,
- FileKind
- };
-
- static PassRefPtr<ChromiumDataObjectItem> createFromString(const String& type, const String& data);
- static PassRefPtr<ChromiumDataObjectItem> createFromFile(PassRefPtr<File>);
- static PassRefPtr<ChromiumDataObjectItem> createFromURL(const String& url, const String& title);
- static PassRefPtr<ChromiumDataObjectItem> createFromHTML(const String& html, const KURL& baseURL);
- static PassRefPtr<ChromiumDataObjectItem> createFromSharedBuffer(const String& filename, PassRefPtr<SharedBuffer>);
- static PassRefPtr<ChromiumDataObjectItem> createFromPasteboard(const String& type, uint64_t sequenceNumber);
-
- Kind kind() const { return m_kind; }
- String type() const { return m_type; }
- void getAsString(PassOwnPtr<StringCallback>, ExecutionContext*) const;
- PassRefPtr<Blob> getAsFile() const;
-
- // Used to support legacy DataTransfer APIs and renderer->browser serialization.
- String internalGetAsString() const;
- PassRefPtr<SharedBuffer> sharedBuffer() const { return m_sharedBuffer; }
- String title() const { return m_title; }
- KURL baseURL() const { return m_baseURL; }
- bool isFilename() const;
-
-private:
- enum DataSource {
- PasteboardSource,
- InternalSource,
- };
-
- ChromiumDataObjectItem(Kind, const String& type);
- ChromiumDataObjectItem(Kind, const String& type, uint64_t sequenceNumber);
-
- DataSource m_source;
- Kind m_kind;
- String m_type;
-
- String m_data;
- RefPtr<File> m_file;
- RefPtr<SharedBuffer> m_sharedBuffer;
- // Optional metadata. Currently used for URL, HTML, and dragging files in.
- String m_title;
- KURL m_baseURL;
-
- uint64_t m_sequenceNumber; // Only valid when m_source == PasteboardSource
-};
-
-} // namespace WebCore
-
-#endif // ChromiumDataObjectItem_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversion.h b/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversion.h
deleted file mode 100644
index 0257f5b93a2..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversion.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef KeyCodeConversion_h
-#define KeyCodeConversion_h
-
-namespace WebCore {
-
- int windowsKeyCodeForKeyEvent(unsigned keycode);
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversionAndroid.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversionAndroid.cpp
deleted file mode 100644
index ae5a2869c9c..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversionAndroid.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright 2007, The Android Open Source Project
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
- * Copyright (C) 2007 Holger Hans Peter Freyther
- * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "platform/KeyboardCodes.h"
-
-#include <android/keycodes.h>
-
-namespace WebCore {
-
-// The Android NDK does not provide values for these yet:
-enum {
- AKEYCODE_ESCAPE = 111,
- AKEYCODE_FORWARD_DEL = 112,
- AKEYCODE_CTRL_LEFT = 113,
- AKEYCODE_CTRL_RIGHT = 114,
- AKEYCODE_CAPS_LOCK = 115,
- AKEYCODE_SCROLL_LOCK = 116,
- AKEYCODE_META_LEFT = 117,
- AKEYCODE_META_RIGHT = 118,
- AKEYCODE_BREAK = 121,
- AKEYCODE_INSERT = 124,
- AKEYCODE_MEDIA_PLAY = 126,
- AKEYCODE_MEDIA_PAUSE = 127,
- AKEYCODE_F1 = 131,
- AKEYCODE_F2 = 132,
- AKEYCODE_F3 = 133,
- AKEYCODE_F4 = 134,
- AKEYCODE_F5 = 135,
- AKEYCODE_F6 = 136,
- AKEYCODE_F7 = 137,
- AKEYCODE_F8 = 138,
- AKEYCODE_F9 = 139,
- AKEYCODE_F10 = 140,
- AKEYCODE_F11 = 141,
- AKEYCODE_F12 = 142,
- AKEYCODE_NUM_LOCK = 143,
- AKEYCODE_NUMPAD_0 = 144,
- AKEYCODE_NUMPAD_1 = 145,
- AKEYCODE_NUMPAD_2 = 146,
- AKEYCODE_NUMPAD_3 = 147,
- AKEYCODE_NUMPAD_4 = 148,
- AKEYCODE_NUMPAD_5 = 149,
- AKEYCODE_NUMPAD_6 = 150,
- AKEYCODE_NUMPAD_7 = 151,
- AKEYCODE_NUMPAD_8 = 152,
- AKEYCODE_NUMPAD_9 = 153,
- AKEYCODE_NUMPAD_DIVIDE = 154,
- AKEYCODE_NUMPAD_MULTIPLY = 155,
- AKEYCODE_NUMPAD_SUBTRACT = 156,
- AKEYCODE_NUMPAD_ADD = 157,
- AKEYCODE_NUMPAD_DOT = 158,
- AKEYCODE_VOLUME_MUTE = 164,
- AKEYCODE_CHANNEL_UP = 166,
- AKEYCODE_CHANNEL_DOWN = 167,
-};
-
-int windowsKeyCodeForKeyEvent(unsigned int keyCode)
-{
- // Does not provide all key codes, and does not handle all keys.
- switch (keyCode) {
- case AKEYCODE_DEL:
- return VKEY_BACK;
- case AKEYCODE_TAB:
- return VKEY_TAB;
- case AKEYCODE_CLEAR:
- return VKEY_CLEAR;
- case AKEYCODE_DPAD_CENTER:
- case AKEYCODE_ENTER:
- return VKEY_RETURN;
- case AKEYCODE_SHIFT_LEFT:
- return VKEY_LSHIFT;
- case AKEYCODE_SHIFT_RIGHT:
- return VKEY_RSHIFT;
- // Back will serve as escape, although we may not have access to it.
- case AKEYCODE_BACK:
- return VKEY_ESCAPE;
- case AKEYCODE_SPACE:
- return VKEY_SPACE;
- case AKEYCODE_HOME:
- return VKEY_HOME;
- case AKEYCODE_DPAD_LEFT:
- return VKEY_LEFT;
- case AKEYCODE_DPAD_UP:
- return VKEY_UP;
- case AKEYCODE_DPAD_RIGHT:
- return VKEY_RIGHT;
- case AKEYCODE_DPAD_DOWN:
- return VKEY_DOWN;
- case AKEYCODE_0:
- return VKEY_0;
- case AKEYCODE_1:
- return VKEY_1;
- case AKEYCODE_2:
- return VKEY_2;
- case AKEYCODE_3:
- return VKEY_3;
- case AKEYCODE_4:
- return VKEY_4;
- case AKEYCODE_5:
- return VKEY_5;
- case AKEYCODE_6:
- return VKEY_6;
- case AKEYCODE_7:
- return VKEY_7;
- case AKEYCODE_8:
- return VKEY_8;
- case AKEYCODE_9:
- return VKEY_9;
- case AKEYCODE_A:
- return VKEY_A;
- case AKEYCODE_B:
- return VKEY_B;
- case AKEYCODE_C:
- return VKEY_C;
- case AKEYCODE_D:
- return VKEY_D;
- case AKEYCODE_E:
- return VKEY_E;
- case AKEYCODE_F:
- return VKEY_F;
- case AKEYCODE_G:
- return VKEY_G;
- case AKEYCODE_H:
- return VKEY_H;
- case AKEYCODE_I:
- return VKEY_I;
- case AKEYCODE_J:
- return VKEY_J;
- case AKEYCODE_K:
- return VKEY_K;
- case AKEYCODE_L:
- return VKEY_L;
- case AKEYCODE_M:
- return VKEY_M;
- case AKEYCODE_N:
- return VKEY_N;
- case AKEYCODE_O:
- return VKEY_O;
- case AKEYCODE_P:
- return VKEY_P;
- case AKEYCODE_Q:
- return VKEY_Q;
- case AKEYCODE_R:
- return VKEY_R;
- case AKEYCODE_S:
- return VKEY_S;
- case AKEYCODE_T:
- return VKEY_T;
- case AKEYCODE_U:
- return VKEY_U;
- case AKEYCODE_V:
- return VKEY_V;
- case AKEYCODE_W:
- return VKEY_W;
- case AKEYCODE_X:
- return VKEY_X;
- case AKEYCODE_Y:
- return VKEY_Y;
- case AKEYCODE_Z:
- return VKEY_Z;
- case AKEYCODE_VOLUME_DOWN:
- return VKEY_VOLUME_DOWN;
- case AKEYCODE_VOLUME_UP:
- return VKEY_VOLUME_UP;
- case AKEYCODE_MEDIA_NEXT:
- return VKEY_MEDIA_NEXT_TRACK;
- case AKEYCODE_MEDIA_PREVIOUS:
- return VKEY_MEDIA_PREV_TRACK;
- case AKEYCODE_MEDIA_STOP:
- return VKEY_MEDIA_STOP;
- case AKEYCODE_MEDIA_PAUSE:
- return VKEY_MEDIA_PLAY_PAUSE;
- // Colon key.
- case AKEYCODE_SEMICOLON:
- return VKEY_OEM_1;
- case AKEYCODE_COMMA:
- return VKEY_OEM_COMMA;
- case AKEYCODE_MINUS:
- return VKEY_OEM_MINUS;
- case AKEYCODE_EQUALS:
- return VKEY_OEM_PLUS;
- case AKEYCODE_PERIOD:
- return VKEY_OEM_PERIOD;
- case AKEYCODE_SLASH:
- return VKEY_OEM_2;
- case AKEYCODE_LEFT_BRACKET:
- return VKEY_OEM_4;
- case AKEYCODE_BACKSLASH:
- return VKEY_OEM_5;
- case AKEYCODE_RIGHT_BRACKET:
- return VKEY_OEM_6;
- case AKEYCODE_MUTE:
- case AKEYCODE_VOLUME_MUTE:
- return VKEY_VOLUME_MUTE;
- case AKEYCODE_ESCAPE:
- return VKEY_ESCAPE;
- case AKEYCODE_MEDIA_PLAY:
- case AKEYCODE_MEDIA_PLAY_PAUSE:
- return VKEY_MEDIA_PLAY_PAUSE;
- case AKEYCODE_CALL:
- return VKEY_END;
- case AKEYCODE_ALT_LEFT:
- return VKEY_LMENU;
- case AKEYCODE_ALT_RIGHT:
- return VKEY_RMENU;
- case AKEYCODE_GRAVE:
- return VKEY_OEM_3;
- case AKEYCODE_APOSTROPHE:
- return VKEY_OEM_3;
- case AKEYCODE_MEDIA_REWIND:
- return VKEY_OEM_103;
- case AKEYCODE_MEDIA_FAST_FORWARD:
- return VKEY_OEM_104;
- case AKEYCODE_PAGE_UP:
- return VKEY_PRIOR;
- case AKEYCODE_PAGE_DOWN:
- return VKEY_NEXT;
- case AKEYCODE_FORWARD_DEL:
- return VKEY_DELETE;
- case AKEYCODE_CTRL_LEFT:
- return VKEY_LCONTROL;
- case AKEYCODE_CTRL_RIGHT:
- return VKEY_RCONTROL;
- case AKEYCODE_CAPS_LOCK:
- return VKEY_CAPITAL;
- case AKEYCODE_SCROLL_LOCK:
- return VKEY_SCROLL;
- case AKEYCODE_META_LEFT:
- return VKEY_LWIN;
- case AKEYCODE_META_RIGHT:
- return VKEY_RWIN;
- case AKEYCODE_BREAK:
- return VKEY_PAUSE;
- case AKEYCODE_INSERT:
- return VKEY_INSERT;
- case AKEYCODE_F1:
- return VKEY_F1;
- case AKEYCODE_F2:
- return VKEY_F2;
- case AKEYCODE_F3:
- return VKEY_F3;
- case AKEYCODE_F4:
- return VKEY_F4;
- case AKEYCODE_F5:
- return VKEY_F5;
- case AKEYCODE_F6:
- return VKEY_F6;
- case AKEYCODE_F7:
- return VKEY_F7;
- case AKEYCODE_F8:
- return VKEY_F8;
- case AKEYCODE_F9:
- return VKEY_F9;
- case AKEYCODE_F10:
- return VKEY_F10;
- case AKEYCODE_F11:
- return VKEY_F11;
- case AKEYCODE_F12:
- return VKEY_F12;
- case AKEYCODE_NUM_LOCK:
- return VKEY_NUMLOCK;
- case AKEYCODE_NUMPAD_0:
- return VKEY_NUMPAD0;
- case AKEYCODE_NUMPAD_1:
- return VKEY_NUMPAD1;
- case AKEYCODE_NUMPAD_2:
- return VKEY_NUMPAD2;
- case AKEYCODE_NUMPAD_3:
- return VKEY_NUMPAD3;
- case AKEYCODE_NUMPAD_4:
- return VKEY_NUMPAD4;
- case AKEYCODE_NUMPAD_5:
- return VKEY_NUMPAD5;
- case AKEYCODE_NUMPAD_6:
- return VKEY_NUMPAD6;
- case AKEYCODE_NUMPAD_7:
- return VKEY_NUMPAD7;
- case AKEYCODE_NUMPAD_8:
- return VKEY_NUMPAD8;
- case AKEYCODE_NUMPAD_9:
- return VKEY_NUMPAD9;
- case AKEYCODE_NUMPAD_DIVIDE:
- return VKEY_DIVIDE;
- case AKEYCODE_NUMPAD_MULTIPLY:
- return VKEY_MULTIPLY;
- case AKEYCODE_NUMPAD_SUBTRACT:
- return VKEY_SUBTRACT;
- case AKEYCODE_NUMPAD_ADD:
- return VKEY_ADD;
- case AKEYCODE_NUMPAD_DOT:
- return VKEY_DECIMAL;
- case AKEYCODE_CHANNEL_UP:
- return VKEY_PRIOR;
- case AKEYCODE_CHANNEL_DOWN:
- return VKEY_NEXT;
- default:
- return 0;
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversionGtk.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversionGtk.cpp
deleted file mode 100644
index e20dabd62a6..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/KeyCodeConversionGtk.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
- * Copyright (C) 2007 Holger Hans Peter Freyther
- * Copyright (C) 2008 Collabora, Ltd. All rights reserved.
- * Copyright (C) 2008, 2009 Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// windowsKeyCodeForKeyEvent is copied from platform/gtk/KeyEventGtk.cpp
-
-#include "config.h"
-#include "core/platform/chromium/KeyCodeConversion.h"
-
-#include "platform/KeyboardCodes.h"
-
-#include <gdk/gdkkeysyms.h>
-
-namespace WebCore {
-
-int windowsKeyCodeForKeyEvent(unsigned keycode)
-{
- switch (keycode) {
- case GDK_KP_0:
- return VKEY_NUMPAD0; // (60) Numeric keypad 0 key
- case GDK_KP_1:
- return VKEY_NUMPAD1; // (61) Numeric keypad 1 key
- case GDK_KP_2:
- return VKEY_NUMPAD2; // (62) Numeric keypad 2 key
- case GDK_KP_3:
- return VKEY_NUMPAD3; // (63) Numeric keypad 3 key
- case GDK_KP_4:
- return VKEY_NUMPAD4; // (64) Numeric keypad 4 key
- case GDK_KP_5:
- return VKEY_NUMPAD5; //(65) Numeric keypad 5 key
- case GDK_KP_6:
- return VKEY_NUMPAD6; // (66) Numeric keypad 6 key
- case GDK_KP_7:
- return VKEY_NUMPAD7; // (67) Numeric keypad 7 key
- case GDK_KP_8:
- return VKEY_NUMPAD8; // (68) Numeric keypad 8 key
- case GDK_KP_9:
- return VKEY_NUMPAD9; // (69) Numeric keypad 9 key
- case GDK_KP_Multiply:
- return VKEY_MULTIPLY; // (6A) Multiply key
- case GDK_KP_Add:
- return VKEY_ADD; // (6B) Add key
- case GDK_KP_Subtract:
- return VKEY_SUBTRACT; // (6D) Subtract key
- case GDK_KP_Decimal:
- return VKEY_DECIMAL; // (6E) Decimal key
- case GDK_KP_Divide:
- return VKEY_DIVIDE; // (6F) Divide key
-
- case GDK_KP_Page_Up:
- return VKEY_PRIOR; // (21) PAGE UP key
- case GDK_KP_Page_Down:
- return VKEY_NEXT; // (22) PAGE DOWN key
- case GDK_KP_End:
- return VKEY_END; // (23) END key
- case GDK_KP_Home:
- return VKEY_HOME; // (24) HOME key
- case GDK_KP_Left:
- return VKEY_LEFT; // (25) LEFT ARROW key
- case GDK_KP_Up:
- return VKEY_UP; // (26) UP ARROW key
- case GDK_KP_Right:
- return VKEY_RIGHT; // (27) RIGHT ARROW key
- case GDK_KP_Down:
- return VKEY_DOWN; // (28) DOWN ARROW key
- case GDK_KP_Begin:
- return VKEY_CLEAR; // (12) CLEAR key
- case GDK_KP_Insert:
- return VKEY_INSERT; // (45) INS key
- case GDK_KP_Delete:
- return VKEY_DELETE; // (46) DEL key
-
- case GDK_BackSpace:
- return VKEY_BACK; // (08) BACKSPACE key
- case GDK_ISO_Left_Tab:
- case GDK_3270_BackTab:
- case GDK_Tab:
- return VKEY_TAB; // (09) TAB key
- case GDK_Clear:
- return VKEY_CLEAR; // (0C) CLEAR key
- case GDK_ISO_Enter:
- case GDK_KP_Enter:
- case GDK_Return:
- return VKEY_RETURN; //(0D) Return key
- case GDK_Shift_L:
- return VKEY_LSHIFT; // (A0) Left SHIFT key
- case GDK_Shift_R:
- return VKEY_RSHIFT; // (A1) Right SHIFT key
- case GDK_Control_L:
- return VKEY_LCONTROL; // (A2) Left CTRL key
- case GDK_Control_R:
- return VKEY_RCONTROL; // (A3) Right CTRL key
- case GDK_Menu:
- return VKEY_APPS; // (5D) Applications key (Natural keyboard)
- case GDK_Alt_L:
- case GDK_Meta_L:
- return VKEY_LMENU; // (A4) Left ALT key
- case GDK_Alt_R:
- case GDK_Meta_R:
- case GDK_ISO_Level3_Shift:
- return VKEY_RMENU; // (A5) Right ALT key
-
- case GDK_Pause:
- return VKEY_PAUSE; // (13) PAUSE key
- case GDK_Caps_Lock:
- return VKEY_CAPITAL; // (14) CAPS LOCK key
- case GDK_Kana_Lock:
- case GDK_Kana_Shift:
- return VKEY_KANA; // (15) Input Method Editor (IME) Kana mode
- case GDK_Hangul:
- return VKEY_HANGUL; // VKEY_HANGUL (15) IME Hangul mode
- // VKEY_JUNJA (17) IME Junja mode
- // VKEY_FINAL (18) IME final mode
- case GDK_Hangul_Hanja:
- return VKEY_HANJA; // (19) IME Hanja mode
- case GDK_Kanji:
- return VKEY_KANJI; // (19) IME Kanji mode
- case GDK_Escape:
- return VKEY_ESCAPE; // (1B) ESC key
- // VKEY_CONVERT (1C) IME convert
- // VKEY_NONCONVERT (1D) IME nonconvert
- // VKEY_ACCEPT (1E) IME accept
- // VKEY_MODECHANGE (1F) IME mode change request
- case GDK_space:
- return VKEY_SPACE; // (20) SPACEBAR
- case GDK_Page_Up:
- return VKEY_PRIOR; // (21) PAGE UP key
- case GDK_Page_Down:
- return VKEY_NEXT; // (22) PAGE DOWN key
- case GDK_End:
- return VKEY_END; // (23) END key
- case GDK_Home:
- return VKEY_HOME; // (24) HOME key
- case GDK_Left:
- return VKEY_LEFT; // (25) LEFT ARROW key
- case GDK_Up:
- return VKEY_UP; // (26) UP ARROW key
- case GDK_Right:
- return VKEY_RIGHT; // (27) RIGHT ARROW key
- case GDK_Down:
- return VKEY_DOWN; // (28) DOWN ARROW key
- case GDK_Select:
- return VKEY_SELECT; // (29) SELECT key
- case GDK_Print:
- return VKEY_PRINT; // (2A) PRINT key
- case GDK_Execute:
- return VKEY_EXECUTE;// (2B) EXECUTE key
- //dunno on this
- //case GDK_PrintScreen:
- // return VKEY_SNAPSHOT; // (2C) PRINT SCREEN key
- case GDK_Insert:
- return VKEY_INSERT; // (2D) INS key
- case GDK_Delete:
- return VKEY_DELETE; // (2E) DEL key
- case GDK_Help:
- return VKEY_HELP; // (2F) HELP key
- case GDK_0:
- case GDK_parenright:
- return VKEY_0; // (30) 0) key
- case GDK_1:
- case GDK_exclam:
- return VKEY_1; // (31) 1 ! key
- case GDK_2:
- case GDK_at:
- return VKEY_2; // (32) 2 & key
- case GDK_3:
- case GDK_numbersign:
- return VKEY_3; //case '3': case '#';
- case GDK_4:
- case GDK_dollar: // (34) 4 key '$';
- return VKEY_4;
- case GDK_5:
- case GDK_percent:
- return VKEY_5; // (35) 5 key '%'
- case GDK_6:
- case GDK_asciicircum:
- return VKEY_6; // (36) 6 key '^'
- case GDK_7:
- case GDK_ampersand:
- return VKEY_7; // (37) 7 key case '&'
- case GDK_8:
- case GDK_asterisk:
- return VKEY_8; // (38) 8 key '*'
- case GDK_9:
- case GDK_parenleft:
- return VKEY_9; // (39) 9 key '('
- case GDK_a:
- case GDK_A:
- return VKEY_A; // (41) A key case 'a': case 'A': return 0x41;
- case GDK_b:
- case GDK_B:
- return VKEY_B; // (42) B key case 'b': case 'B': return 0x42;
- case GDK_c:
- case GDK_C:
- return VKEY_C; // (43) C key case 'c': case 'C': return 0x43;
- case GDK_d:
- case GDK_D:
- return VKEY_D; // (44) D key case 'd': case 'D': return 0x44;
- case GDK_e:
- case GDK_E:
- return VKEY_E; // (45) E key case 'e': case 'E': return 0x45;
- case GDK_f:
- case GDK_F:
- return VKEY_F; // (46) F key case 'f': case 'F': return 0x46;
- case GDK_g:
- case GDK_G:
- return VKEY_G; // (47) G key case 'g': case 'G': return 0x47;
- case GDK_h:
- case GDK_H:
- return VKEY_H; // (48) H key case 'h': case 'H': return 0x48;
- case GDK_i:
- case GDK_I:
- return VKEY_I; // (49) I key case 'i': case 'I': return 0x49;
- case GDK_j:
- case GDK_J:
- return VKEY_J; // (4A) J key case 'j': case 'J': return 0x4A;
- case GDK_k:
- case GDK_K:
- return VKEY_K; // (4B) K key case 'k': case 'K': return 0x4B;
- case GDK_l:
- case GDK_L:
- return VKEY_L; // (4C) L key case 'l': case 'L': return 0x4C;
- case GDK_m:
- case GDK_M:
- return VKEY_M; // (4D) M key case 'm': case 'M': return 0x4D;
- case GDK_n:
- case GDK_N:
- return VKEY_N; // (4E) N key case 'n': case 'N': return 0x4E;
- case GDK_o:
- case GDK_O:
- return VKEY_O; // (4F) O key case 'o': case 'O': return 0x4F;
- case GDK_p:
- case GDK_P:
- return VKEY_P; // (50) P key case 'p': case 'P': return 0x50;
- case GDK_q:
- case GDK_Q:
- return VKEY_Q; // (51) Q key case 'q': case 'Q': return 0x51;
- case GDK_r:
- case GDK_R:
- return VKEY_R; // (52) R key case 'r': case 'R': return 0x52;
- case GDK_s:
- case GDK_S:
- return VKEY_S; // (53) S key case 's': case 'S': return 0x53;
- case GDK_t:
- case GDK_T:
- return VKEY_T; // (54) T key case 't': case 'T': return 0x54;
- case GDK_u:
- case GDK_U:
- return VKEY_U; // (55) U key case 'u': case 'U': return 0x55;
- case GDK_v:
- case GDK_V:
- return VKEY_V; // (56) V key case 'v': case 'V': return 0x56;
- case GDK_w:
- case GDK_W:
- return VKEY_W; // (57) W key case 'w': case 'W': return 0x57;
- case GDK_x:
- case GDK_X:
- return VKEY_X; // (58) X key case 'x': case 'X': return 0x58;
- case GDK_y:
- case GDK_Y:
- return VKEY_Y; // (59) Y key case 'y': case 'Y': return 0x59;
- case GDK_z:
- case GDK_Z:
- return VKEY_Z; // (5A) Z key case 'z': case 'Z': return 0x5A;
- case GDK_Super_L:
- return VKEY_LWIN; // (5B) Left Windows key (Microsoft Natural keyboard)
- case GDK_Super_R:
- return VKEY_RWIN; // (5C) Right Windows key (Natural keyboard)
- // VKEY_SLEEP (5F) Computer Sleep key
- // VKEY_SEPARATOR (6C) Separator key
- // VKEY_SUBTRACT (6D) Subtract key
- // VKEY_DECIMAL (6E) Decimal key
- // VKEY_DIVIDE (6F) Divide key
- // handled by key code above
-
- case GDK_Num_Lock:
- return VKEY_NUMLOCK; // (90) NUM LOCK key
-
- case GDK_Scroll_Lock:
- return VKEY_SCROLL; // (91) SCROLL LOCK key
-
- // VKEY_LSHIFT (A0) Left SHIFT key
- // VKEY_RSHIFT (A1) Right SHIFT key
- // VKEY_LCONTROL (A2) Left CONTROL key
- // VKEY_RCONTROL (A3) Right CONTROL key
- // VKEY_LMENU (A4) Left MENU key
- // VKEY_RMENU (A5) Right MENU key
- case GDK_Back:
- return VKEY_BROWSER_BACK; // (A6) Windows 2000/XP: Browser Back key
- case GDK_Forward:
- return VKEY_BROWSER_FORWARD; // (A7) Windows 2000/XP: Browser Forward key
- case GDK_Refresh:
- return VKEY_BROWSER_REFRESH; // (A8) Windows 2000/XP: Browser Refresh key
- case GDK_Stop:
- return VKEY_BROWSER_STOP; // (A9) Windows 2000/XP: Browser Stop key
- case GDK_Search:
- return VKEY_BROWSER_SEARCH; // (AA) Windows 2000/XP: Browser Search key
- case GDK_Favorites:
- return VKEY_BROWSER_FAVORITES; // (AB) Windows 2000/XP: Browser Favorites key
- case GDK_HomePage:
- return VKEY_BROWSER_HOME; // (AC) Windows 2000/XP: Browser Start and Home key
- case GDK_AudioMute:
- return VKEY_VOLUME_MUTE; // (AD) Windows 2000/XP: Volume Mute key
- case GDK_AudioLowerVolume:
- return VKEY_VOLUME_DOWN; // (AE) Windows 2000/XP: Volume Down key
- case GDK_AudioRaiseVolume:
- return VKEY_VOLUME_UP; // (AF) Windows 2000/XP: Volume Up key
- case GDK_AudioNext:
- return VKEY_MEDIA_NEXT_TRACK; // (B0) Windows 2000/XP: Next Track key
- case GDK_AudioPrev:
- return VKEY_MEDIA_PREV_TRACK; // (B1) Windows 2000/XP: Previous Track key
- case GDK_AudioStop:
- return VKEY_MEDIA_STOP; // (B2) Windows 2000/XP: Stop Media key
- case GDK_AudioPlay:
- return VKEY_MEDIA_PLAY_PAUSE; // (B3) Windows 2000/XP: Play/Pause Media key
- case GDK_Mail:
- return VKEY_MEDIA_LAUNCH_MAIL; // (B4) Windows 2000/XP: Start Mail key
- // VKEY_LAUNCH_MEDIA_SELECT (B5) Windows 2000/XP: Select Media key
- case GDK_LaunchA:
- return VKEY_MEDIA_LAUNCH_APP1; // (B6) Windows 2000/XP: Start Application 1 key
- case GDK_LaunchB:
- return VKEY_MEDIA_LAUNCH_APP2; // (B7) Windows 2000/XP: Start Application 2 key
-
- // VKEY_OEM_1 (BA) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ';:' key
- case GDK_semicolon:
- case GDK_colon:
- return VKEY_OEM_1; //case ';': case ':': return 0xBA;
- // VKEY_OEM_PLUS (BB) Windows 2000/XP: For any country/region, the '+' key
- case GDK_plus:
- case GDK_equal:
- return VKEY_OEM_PLUS; //case '=': case '+': return 0xBB;
- // VKEY_OEM_COMMA (BC) Windows 2000/XP: For any country/region, the ',' key
- case GDK_comma:
- case GDK_less:
- return VKEY_OEM_COMMA; //case ',': case '<': return 0xBC;
- // VKEY_OEM_MINUS (BD) Windows 2000/XP: For any country/region, the '-' key
- case GDK_minus:
- case GDK_underscore:
- return VKEY_OEM_MINUS; //case '-': case '_': return 0xBD;
- // VKEY_OEM_PERIOD (BE) Windows 2000/XP: For any country/region, the '.' key
- case GDK_period:
- case GDK_greater:
- return VKEY_OEM_PERIOD; //case '.': case '>': return 0xBE;
- // VKEY_OEM_2 (BF) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '/?' key
- case GDK_slash:
- case GDK_question:
- return VKEY_OEM_2; //case '/': case '?': return 0xBF;
- // VKEY_OEM_3 (C0) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '`~' key
- case GDK_asciitilde:
- case GDK_quoteleft:
- return VKEY_OEM_3; //case '`': case '~': return 0xC0;
- // VKEY_OEM_4 (DB) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '[{' key
- case GDK_bracketleft:
- case GDK_braceleft:
- return VKEY_OEM_4; //case '[': case '{': return 0xDB;
- // VKEY_OEM_5 (DC) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the '\|' key
- case GDK_backslash:
- case GDK_bar:
- return VKEY_OEM_5; //case '\\': case '|': return 0xDC;
- // VKEY_OEM_6 (DD) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the ']}' key
- case GDK_bracketright:
- case GDK_braceright:
- return VKEY_OEM_6; // case ']': case '}': return 0xDD;
- // VKEY_OEM_7 (DE) Used for miscellaneous characters; it can vary by keyboard. Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
- case GDK_quoteright:
- case GDK_quotedbl:
- return VKEY_OEM_7; // case '\'': case '"': return 0xDE;
- // VKEY_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard.
- // VKEY_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
- // VKEY_PROCESSKEY (E5) Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key
- // VKEY_PACKET (E7) Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VKEY_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT,SendInput, WM_KEYDOWN, and WM_KEYUP
- // VKEY_ATTN (F6) Attn key
- // VKEY_CRSEL (F7) CrSel key
- // VKEY_EXSEL (F8) ExSel key
- // VKEY_EREOF (F9) Erase EOF key
- // VKEY_PLAY (FA) Play key
- // VKEY_ZOOM (FB) Zoom key
- // VKEY_NONAME (FC) Reserved for future use
- // VKEY_PA1 (FD) PA1 key
- // VKEY_OEM_CLEAR (FE) Clear key
- case GDK_F1:
- case GDK_F2:
- case GDK_F3:
- case GDK_F4:
- case GDK_F5:
- case GDK_F6:
- case GDK_F7:
- case GDK_F8:
- case GDK_F9:
- case GDK_F10:
- case GDK_F11:
- case GDK_F12:
- case GDK_F13:
- case GDK_F14:
- case GDK_F15:
- case GDK_F16:
- case GDK_F17:
- case GDK_F18:
- case GDK_F19:
- case GDK_F20:
- case GDK_F21:
- case GDK_F22:
- case GDK_F23:
- case GDK_F24:
- return VKEY_F1 + (keycode - GDK_F1);
- default:
- return 0;
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebArrayBuffer.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebArrayBuffer.cpp
deleted file mode 100644
index 05429fe8fa0..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebArrayBuffer.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "public/platform/WebArrayBuffer.h"
-
-#include "bindings/v8/custom/V8ArrayBufferCustom.h"
-#include "wtf/ArrayBuffer.h"
-#include "wtf/PassOwnPtr.h"
-
-using namespace WebCore;
-
-namespace blink {
-
-WebArrayBuffer WebArrayBuffer::create(unsigned numElements, unsigned elementByteSize)
-{
- RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(numElements, elementByteSize);
- return WebArrayBuffer(buffer);
-}
-
-void WebArrayBuffer::reset()
-{
- m_private.reset();
-}
-
-void WebArrayBuffer::assign(const WebArrayBuffer& other)
-{
- m_private = other.m_private;
-}
-
-void* WebArrayBuffer::data() const
-{
- if (!isNull())
- return const_cast<void*>(m_private->data());
- return 0;
-}
-
-unsigned WebArrayBuffer::byteLength() const
-{
- if (!isNull())
- return m_private->byteLength();
- return 0;
-}
-
-v8::Handle<v8::Value> WebArrayBuffer::toV8Value()
-{
- if (!m_private.get())
- return v8::Handle<v8::Value>();
- return toV8(m_private.get(), v8::Handle<v8::Object>(), v8::Isolate::GetCurrent());
-}
-
-WebArrayBuffer* WebArrayBuffer::createFromV8Value(v8::Handle<v8::Value> value)
-{
- if (!V8ArrayBuffer::hasInstanceInAnyWorld(value, v8::Isolate::GetCurrent()))
- return 0;
- WTF::ArrayBuffer* buffer = V8ArrayBuffer::toNative(value->ToObject());
- return new WebArrayBuffer(buffer);
-}
-
-WebArrayBuffer::WebArrayBuffer(const WTF::PassRefPtr<WTF::ArrayBuffer>& blob)
- : m_private(blob)
-{
-}
-
-WebArrayBuffer& WebArrayBuffer::operator=(const WTF::PassRefPtr<WTF::ArrayBuffer>& blob)
-{
- m_private = blob;
- return *this;
-}
-
-WebArrayBuffer::operator WTF::PassRefPtr<WTF::ArrayBuffer>() const
-{
- return m_private.get();
-}
-
-} // namespace blink
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebCrypto.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebCrypto.cpp
deleted file mode 100644
index 3fd68afd82a..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebCrypto.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "public/platform/WebCrypto.h"
-
-#include "core/platform/CryptoResult.h"
-#include "public/platform/WebArrayBuffer.h"
-#include <string.h>
-
-namespace blink {
-
-void WebCryptoResult::completeWithError()
-{
- m_impl->completeWithError();
- reset();
-}
-
-void WebCryptoResult::completeWithBuffer(const WebArrayBuffer& buffer)
-{
- RELEASE_ASSERT(!buffer.isNull());
- m_impl->completeWithBuffer(buffer);
- reset();
-}
-
-void WebCryptoResult::completeWithBuffer(const void* bytes, unsigned bytesSize)
-{
- WebArrayBuffer buffer = blink::WebArrayBuffer::create(bytesSize, 1);
- RELEASE_ASSERT(!buffer.isNull());
- memcpy(buffer.data(), bytes, bytesSize);
- completeWithBuffer(buffer);
-}
-
-void WebCryptoResult::completeWithBoolean(bool b)
-{
- m_impl->completeWithBoolean(b);
- reset();
-}
-
-void WebCryptoResult::completeWithKey(const WebCryptoKey& key)
-{
- ASSERT(!key.isNull());
- m_impl->completeWithKey(key);
- reset();
-}
-
-void WebCryptoResult::completeWithKeyPair(const WebCryptoKey& publicKey, const WebCryptoKey& privateKey)
-{
- ASSERT(!publicKey.isNull());
- ASSERT(!privateKey.isNull());
- m_impl->completeWithKeyPair(publicKey, privateKey);
- reset();
-}
-
-WebCryptoResult::WebCryptoResult(const WTF::PassRefPtr<WebCore::CryptoResult>& impl)
- : m_impl(impl)
-{
- ASSERT(m_impl.get());
-}
-
-void WebCryptoResult::reset()
-{
- m_impl.reset();
-}
-
-void WebCryptoResult::assign(const WebCryptoResult& o)
-{
- m_impl = o.m_impl;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebMediaStream.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebMediaStream.cpp
deleted file mode 100644
index 7572def9072..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebMediaStream.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "public/platform/WebMediaStream.h"
-
-#include "core/platform/mediastream/MediaStreamDescriptor.h"
-#include "platform/UUID.h"
-#include "platform/mediastream/MediaStreamComponent.h"
-#include "platform/mediastream/MediaStreamSource.h"
-#include "public/platform/WebMediaStreamSource.h"
-#include "public/platform/WebMediaStreamTrack.h"
-#include "public/platform/WebString.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
-
-using namespace WebCore;
-
-namespace blink {
-
-namespace {
-
-class ExtraDataContainer : public MediaStreamDescriptor::ExtraData {
-public:
- ExtraDataContainer(WebMediaStream::ExtraData* extraData) : m_extraData(adoptPtr(extraData)) { }
-
- WebMediaStream::ExtraData* extraData() { return m_extraData.get(); }
-
-private:
- OwnPtr<WebMediaStream::ExtraData> m_extraData;
-};
-
-} // namespace
-
-WebMediaStream::WebMediaStream(const PassRefPtr<WebCore::MediaStreamDescriptor>& mediaStreamDescriptor)
- : m_private(mediaStreamDescriptor)
-{
-}
-
-WebMediaStream::WebMediaStream(WebCore::MediaStreamDescriptor* mediaStreamDescriptor)
- : m_private(mediaStreamDescriptor)
-{
-}
-
-void WebMediaStream::reset()
-{
- m_private.reset();
-}
-
-WebString WebMediaStream::id() const
-{
- return m_private->id();
-}
-
-WebMediaStream::ExtraData* WebMediaStream::extraData() const
-{
- RefPtr<MediaStreamDescriptor::ExtraData> data = m_private->extraData();
- if (!data)
- return 0;
- return static_cast<ExtraDataContainer*>(data.get())->extraData();
-}
-
-void WebMediaStream::setExtraData(ExtraData* extraData)
-{
- m_private->setExtraData(adoptRef(new ExtraDataContainer(extraData)));
-}
-
-void WebMediaStream::audioTracks(WebVector<WebMediaStreamTrack>& webTracks) const
-{
- size_t numberOfTracks = m_private->numberOfAudioComponents();
- WebVector<WebMediaStreamTrack> result(numberOfTracks);
- for (size_t i = 0; i < numberOfTracks; ++i)
- result[i] = m_private->audioComponent(i);
- webTracks.swap(result);
-}
-
-void WebMediaStream::videoTracks(WebVector<WebMediaStreamTrack>& webTracks) const
-{
- size_t numberOfTracks = m_private->numberOfVideoComponents();
- WebVector<WebMediaStreamTrack> result(numberOfTracks);
- for (size_t i = 0; i < numberOfTracks; ++i)
- result[i] = m_private->videoComponent(i);
- webTracks.swap(result);
-}
-
-void WebMediaStream::addTrack(const WebMediaStreamTrack& track)
-{
- ASSERT(!isNull());
- m_private->addRemoteTrack(track);
-}
-
-void WebMediaStream::removeTrack(const WebMediaStreamTrack& track)
-{
- ASSERT(!isNull());
- m_private->removeRemoteTrack(track);
-}
-
-WebMediaStream& WebMediaStream::operator=(const PassRefPtr<WebCore::MediaStreamDescriptor>& mediaStreamDescriptor)
-{
- m_private = mediaStreamDescriptor;
- return *this;
-}
-
-WebMediaStream::operator PassRefPtr<WebCore::MediaStreamDescriptor>() const
-{
- return m_private.get();
-}
-
-WebMediaStream::operator WebCore::MediaStreamDescriptor*() const
-{
- return m_private.get();
-}
-
-void WebMediaStream::initialize(const WebVector<WebMediaStreamTrack>& audioTracks, const WebVector<WebMediaStreamTrack>& videoTracks)
-{
- initialize(createCanonicalUUIDString(), audioTracks, videoTracks);
-}
-
-void WebMediaStream::initialize(const WebString& label, const WebVector<WebMediaStreamTrack>& audioTracks, const WebVector<WebMediaStreamTrack>& videoTracks)
-{
- MediaStreamComponentVector audio, video;
- for (size_t i = 0; i < audioTracks.size(); ++i) {
- MediaStreamComponent* component = audioTracks[i];
- audio.append(component);
- }
- for (size_t i = 0; i < videoTracks.size(); ++i) {
- MediaStreamComponent* component = videoTracks[i];
- video.append(component);
- }
- m_private = MediaStreamDescriptor::create(label, audio, video);
-}
-
-void WebMediaStream::assign(const WebMediaStream& other)
-{
- m_private = other.m_private;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebMediaStreamTrack.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebMediaStreamTrack.cpp
deleted file mode 100644
index 39dabdfa8f3..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebMediaStreamTrack.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "public/platform/WebMediaStreamTrack.h"
-
-#include "platform/mediastream/MediaStreamComponent.h"
-#include "platform/mediastream/MediaStreamSource.h"
-#include "public/platform/WebAudioSourceProvider.h"
-#include "public/platform/WebMediaStream.h"
-#include "public/platform/WebMediaStreamSource.h"
-#include "public/platform/WebString.h"
-#include "wtf/Vector.h"
-
-using namespace WebCore;
-
-namespace blink {
-
-namespace {
-
-class ExtraDataContainer : public MediaStreamComponent::ExtraData {
-public:
- explicit ExtraDataContainer(PassOwnPtr<WebMediaStreamTrack::ExtraData> extraData) : m_extraData(extraData) { }
-
- WebMediaStreamTrack::ExtraData* extraData() { return m_extraData.get(); }
-
-private:
- OwnPtr<WebMediaStreamTrack::ExtraData> m_extraData;
-};
-
-} // namespace
-
-WebMediaStreamTrack::WebMediaStreamTrack(PassRefPtr<WebCore::MediaStreamComponent> mediaStreamComponent)
- : m_private(mediaStreamComponent)
-{
-}
-
-WebMediaStreamTrack::WebMediaStreamTrack(WebCore::MediaStreamComponent* mediaStreamComponent)
- : m_private(mediaStreamComponent)
-{
-}
-
-WebMediaStreamTrack& WebMediaStreamTrack::operator=(WebCore::MediaStreamComponent* mediaStreamComponent)
-{
- m_private = mediaStreamComponent;
- return *this;
-}
-
-void WebMediaStreamTrack::initialize(const WebMediaStreamSource& source)
-{
- m_private = MediaStreamComponent::create(source);
-}
-
-void WebMediaStreamTrack::initialize(const WebString& id, const WebMediaStreamSource& source)
-{
- m_private = MediaStreamComponent::create(id, source);
-}
-
-void WebMediaStreamTrack::reset()
-{
- m_private.reset();
-}
-
-WebMediaStreamTrack::operator PassRefPtr<MediaStreamComponent>() const
-{
- return m_private.get();
-}
-
-WebMediaStreamTrack::operator MediaStreamComponent*() const
-{
- return m_private.get();
-}
-
-bool WebMediaStreamTrack::isEnabled() const
-{
- ASSERT(!m_private.isNull());
- return m_private->enabled();
-}
-
-WebString WebMediaStreamTrack::id() const
-{
- ASSERT(!m_private.isNull());
- return m_private->id();
-}
-
-WebMediaStream WebMediaStreamTrack::stream() const
-{
- ASSERT(!m_private.isNull());
- return WebMediaStream(m_private->stream());
-}
-
-WebMediaStreamSource WebMediaStreamTrack::source() const
-{
- ASSERT(!m_private.isNull());
- return WebMediaStreamSource(m_private->source());
-}
-
-WebMediaStreamTrack::ExtraData* WebMediaStreamTrack::extraData() const
-{
- RefPtr<MediaStreamComponent::ExtraData> data = m_private->extraData();
- if (!data)
- return 0;
- return static_cast<ExtraDataContainer*>(data.get())->extraData();
-}
-
-void WebMediaStreamTrack::setExtraData(ExtraData* extraData)
-{
- m_private->setExtraData(adoptRef(new ExtraDataContainer(adoptPtr(extraData))));
-}
-
-void WebMediaStreamTrack::setSourceProvider(WebAudioSourceProvider* provider)
-{
-#if ENABLE(WEB_AUDIO)
- ASSERT(!m_private.isNull());
- m_private->setSourceProvider(provider);
-#endif // ENABLE(WEB_AUDIO)
-}
-
-void WebMediaStreamTrack::assign(const WebMediaStreamTrack& other)
-{
- m_private = other.m_private;
-}
-
-} // namespace blink
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCSessionDescription.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCSessionDescription.cpp
deleted file mode 100644
index 1fc0cafec96..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCSessionDescription.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "public/platform/WebRTCSessionDescription.h"
-
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "public/platform/WebString.h"
-
-namespace blink {
-
-class WebRTCSessionDescriptionPrivate FINAL : public RefCounted<WebRTCSessionDescriptionPrivate> {
-public:
- static PassRefPtr<WebRTCSessionDescriptionPrivate> create(const WebString& type, const WebString& sdp);
-
- WebString type() { return m_type; }
- void setType(const WebString& type) { m_type = type; }
-
- WebString sdp() { return m_sdp; }
- void setSdp(const WebString& sdp) { m_sdp = sdp; }
-
-private:
- WebRTCSessionDescriptionPrivate(const WebString& type, const WebString& sdp);
-
- WebString m_type;
- WebString m_sdp;
-};
-
-PassRefPtr<WebRTCSessionDescriptionPrivate> WebRTCSessionDescriptionPrivate::create(const WebString& type, const WebString& sdp)
-{
- return adoptRef(new WebRTCSessionDescriptionPrivate(type, sdp));
-}
-
-WebRTCSessionDescriptionPrivate::WebRTCSessionDescriptionPrivate(const WebString& type, const WebString& sdp)
- : m_type(type)
- , m_sdp(sdp)
-{
-}
-
-void WebRTCSessionDescription::assign(const WebRTCSessionDescription& other)
-{
- m_private = other.m_private;
-}
-
-void WebRTCSessionDescription::reset()
-{
- m_private.reset();
-}
-
-void WebRTCSessionDescription::initialize(const WebString& type, const WebString& sdp)
-{
- m_private = WebRTCSessionDescriptionPrivate::create(type, sdp);
-}
-
-WebString WebRTCSessionDescription::type() const
-{
- ASSERT(!m_private.isNull());
- return m_private->type();
-}
-
-void WebRTCSessionDescription::setType(const WebString& type)
-{
- ASSERT(!m_private.isNull());
- return m_private->setType(type);
-}
-
-WebString WebRTCSessionDescription::sdp() const
-{
- ASSERT(!m_private.isNull());
- return m_private->sdp();
-}
-
-void WebRTCSessionDescription::setSDP(const WebString& sdp)
-{
- ASSERT(!m_private.isNull());
- return m_private->setSdp(sdp);
-}
-
-} // namespace blink
-
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCSessionDescriptionRequest.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCSessionDescriptionRequest.cpp
deleted file mode 100644
index b35f305ff1f..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCSessionDescriptionRequest.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "public/platform/WebRTCSessionDescriptionRequest.h"
-
-#include "platform/mediastream/RTCSessionDescriptionRequest.h"
-#include "public/platform/WebRTCSessionDescription.h"
-#include "wtf/PassOwnPtr.h"
-
-using namespace WebCore;
-
-namespace blink {
-
-namespace {
-
-class ExtraDataContainer : public RTCSessionDescriptionRequest::ExtraData {
-public:
- ExtraDataContainer(WebRTCSessionDescriptionRequest::ExtraData* extraData) : m_extraData(adoptPtr(extraData)) { }
-
- WebRTCSessionDescriptionRequest::ExtraData* extraData() { return m_extraData.get(); }
-
-private:
- OwnPtr<WebRTCSessionDescriptionRequest::ExtraData> m_extraData;
-};
-
-} // namespace
-
-WebRTCSessionDescriptionRequest::WebRTCSessionDescriptionRequest(const PassRefPtr<RTCSessionDescriptionRequest>& constraints)
- : m_private(constraints)
-{
-}
-
-void WebRTCSessionDescriptionRequest::assign(const WebRTCSessionDescriptionRequest& other)
-{
- m_private = other.m_private;
-}
-
-void WebRTCSessionDescriptionRequest::reset()
-{
- m_private.reset();
-}
-
-void WebRTCSessionDescriptionRequest::requestSucceeded(const WebRTCSessionDescription& sessionDescription) const
-{
- ASSERT(m_private.get());
- m_private->requestSucceeded(sessionDescription);
-}
-
-void WebRTCSessionDescriptionRequest::requestFailed(const WebString& error) const
-{
- ASSERT(m_private.get());
- m_private->requestFailed(error);
-}
-
-WebRTCSessionDescriptionRequest::ExtraData* WebRTCSessionDescriptionRequest::extraData() const
-{
- RefPtr<RTCSessionDescriptionRequest::ExtraData> data = m_private->extraData();
- if (!data)
- return 0;
- return static_cast<ExtraDataContainer*>(data.get())->extraData();
-}
-
-void WebRTCSessionDescriptionRequest::setExtraData(ExtraData* extraData)
-{
- m_private->setExtraData(adoptRef(new ExtraDataContainer(extraData)));
-}
-
-} // namespace blink
-
diff --git a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCStatsRequest.cpp b/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCStatsRequest.cpp
deleted file mode 100644
index 617bd56256c..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/chromium/support/WebRTCStatsRequest.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "public/platform/WebRTCStatsRequest.h"
-
-#include "core/platform/mediastream/RTCStatsRequest.h"
-#include "modules/mediastream/RTCStatsResponse.h"
-#include "public/platform/WebMediaStream.h"
-#include "public/platform/WebMediaStreamTrack.h"
-#include "public/platform/WebRTCStatsResponse.h"
-#include "wtf/PassOwnPtr.h"
-
-using namespace WebCore;
-
-namespace blink {
-
-WebRTCStatsRequest::WebRTCStatsRequest(const PassRefPtr<RTCStatsRequest>& request)
- : m_private(request)
-{
-}
-
-void WebRTCStatsRequest::assign(const WebRTCStatsRequest& other)
-{
- m_private = other.m_private;
-}
-
-void WebRTCStatsRequest::reset()
-{
- m_private.reset();
-}
-
-WebRTCStatsResponse WebRTCStatsRequest::createResponse() const
-{
- return WebRTCStatsResponse(m_private->createResponse());
-}
-
-bool WebRTCStatsRequest::hasSelector() const
-{
- return m_private->hasSelector();
-}
-
-const WebMediaStream WebRTCStatsRequest::stream() const
-{
- return WebMediaStream(m_private->stream());
-}
-
-const WebMediaStreamTrack WebRTCStatsRequest::component() const
-{
- return WebMediaStreamTrack(m_private->component());
-}
-
-void WebRTCStatsRequest::requestSucceeded(const WebRTCStatsResponse& response) const
-{
- m_private->requestSucceeded(response);
-}
-
-} // namespace blink
diff --git a/chromium/third_party/WebKit/Source/core/platform/mac/ThemeMac.h b/chromium/third_party/WebKit/Source/core/platform/mac/ThemeMac.h
deleted file mode 100644
index 3e4d44b2934..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mac/ThemeMac.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ThemeMac_h
-#define ThemeMac_h
-
-#include "platform/Theme.h"
-
-@interface NSFont(WebCoreTheme)
-- (NSString*)webCoreFamilyName;
-@end
-
-namespace WebCore {
-
-class ThemeMac : public Theme {
-public:
- ThemeMac() { }
- virtual ~ThemeMac() { }
-
- virtual int baselinePositionAdjustment(ControlPart) const;
-
- virtual FontDescription controlFont(ControlPart, const FontDescription&, float zoomFactor) const;
-
- virtual LengthSize controlSize(ControlPart, const FontDescription&, const LengthSize&, float zoomFactor) const;
- virtual LengthSize minimumControlSize(ControlPart, const FontDescription&, float zoomFactor) const;
-
- virtual LengthBox controlPadding(ControlPart, const FontDescription&, const LengthBox& zoomedBox, float zoomFactor) const;
- virtual LengthBox controlBorder(ControlPart, const FontDescription&, const LengthBox& zoomedBox, float zoomFactor) const;
-
- virtual bool controlRequiresPreWhiteSpace(ControlPart part) const { return part == PushButtonPart; }
-
- virtual void paint(ControlPart, ControlStates, GraphicsContext*, const IntRect&, float zoomFactor, ScrollView*) const;
- virtual void inflateControlPaintRect(ControlPart, ControlStates, IntRect&, float zoomFactor) const;
-
- // FIXME: Once RenderThemeMac is converted over to use Theme then this can be internal to ThemeMac.
- static NSView* ensuredView(ScrollView*);
- static void setFocusRingClipRect(const FloatRect&);
-};
-
-} // namespace WebCore
-
-#endif // ThemeMac_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/mac/ThemeMac.mm b/chromium/third_party/WebKit/Source/core/platform/mac/ThemeMac.mm
deleted file mode 100644
index e24ee65a2ae..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mac/ThemeMac.mm
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Copyright (C) 2008, 2010, 2011, 2012 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-#import "core/platform/mac/ThemeMac.h"
-
-#import <Carbon/Carbon.h>
-#import "platform/graphics/GraphicsContextStateSaver.h"
-#import "platform/mac/BlockExceptions.h"
-#import "platform/mac/LocalCurrentGraphicsContext.h"
-#import "platform/mac/WebCoreNSCellExtras.h"
-#import "platform/scroll/ScrollView.h"
-#include "wtf/StdLibExtras.h"
-
-using namespace std;
-
-NSRect focusRingClipRect;
-
-// This is a view whose sole purpose is to tell AppKit that it's flipped.
-@interface WebCoreFlippedView : NSControl
-@end
-
-@implementation WebCoreFlippedView
-
-- (BOOL)isFlipped
-{
- return YES;
-}
-
-- (NSText *)currentEditor
-{
- return nil;
-}
-
-- (BOOL)_automaticFocusRingDisabled
-{
- return YES;
-}
-
-- (NSRect)_focusRingVisibleRect
-{
- if (NSIsEmptyRect(focusRingClipRect))
- return [self visibleRect];
-
- NSRect rect = focusRingClipRect;
- rect.origin.y = [self bounds].size.height - NSMaxY(rect);
-
- return rect;
-}
-
-- (NSView *)_focusRingClipAncestor
-{
- return self;
-}
-
-@end
-
-@implementation NSFont (WebCoreTheme)
-
-- (NSString*)webCoreFamilyName
-{
- if ([[self familyName] hasPrefix:@"."])
- return [self fontName];
-
- return [self familyName];
-}
-
-@end
-
-namespace WebCore {
-
-enum {
- topMargin,
- rightMargin,
- bottomMargin,
- leftMargin
-};
-
-Theme* platformTheme()
-{
- DEFINE_STATIC_LOCAL(ThemeMac, themeMac, ());
- return &themeMac;
-}
-
-// Helper functions used by a bunch of different control parts.
-
-static NSControlSize controlSizeForFont(const FontDescription& fontDescription)
-{
- int fontSize = fontDescription.computedPixelSize();
- if (fontSize >= 16)
- return NSRegularControlSize;
- if (fontSize >= 11)
- return NSSmallControlSize;
- return NSMiniControlSize;
-}
-
-static LengthSize sizeFromNSControlSize(NSControlSize nsControlSize, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
-{
- IntSize controlSize = sizes[nsControlSize];
- if (zoomFactor != 1.0f)
- controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.height() * zoomFactor);
- LengthSize result = zoomedSize;
- if (zoomedSize.width().isIntrinsicOrAuto() && controlSize.width() > 0)
- result.setWidth(Length(controlSize.width(), Fixed));
- if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0)
- result.setHeight(Length(controlSize.height(), Fixed));
- return result;
-}
-
-static LengthSize sizeFromFont(const FontDescription& fontDescription, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes)
-{
- return sizeFromNSControlSize(controlSizeForFont(fontDescription), zoomedSize, zoomFactor, sizes);
-}
-
-static ControlSize controlSizeFromPixelSize(const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor)
-{
- if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomFactor) &&
- minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomFactor))
- return NSRegularControlSize;
- if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomFactor) &&
- minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomFactor))
- return NSSmallControlSize;
- return NSMiniControlSize;
-}
-
-static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor)
-{
- ControlSize size = controlSizeFromPixelSize(sizes, minZoomedSize, zoomFactor);
- if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same.
- [cell setControlSize:(NSControlSize)size];
-}
-
-static void updateStates(NSCell* cell, ControlStates states)
-{
- // Hover state is not supported by Aqua.
-
- // Pressed state
- bool oldPressed = [cell isHighlighted];
- bool pressed = states & PressedState;
- if (pressed != oldPressed)
- [cell setHighlighted:pressed];
-
- // Enabled state
- bool oldEnabled = [cell isEnabled];
- bool enabled = states & EnabledState;
- if (enabled != oldEnabled)
- [cell setEnabled:enabled];
-
-#if BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
- // Focused state
- bool oldFocused = [cell showsFirstResponder];
- bool focused = states & FocusState;
- if (focused != oldFocused)
- [cell setShowsFirstResponder:focused];
-#endif
-
- // Checked and Indeterminate
- bool oldIndeterminate = [cell state] == NSMixedState;
- bool indeterminate = (states & IndeterminateState);
- bool checked = states & CheckedState;
- bool oldChecked = [cell state] == NSOnState;
- if (oldIndeterminate != indeterminate || checked != oldChecked)
- [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)];
-
- // Window inactive state does not need to be checked explicitly, since we paint parented to
- // a view in a window whose key state can be detected.
-}
-
-static ThemeDrawState convertControlStatesToThemeDrawState(ThemeButtonKind kind, ControlStates states)
-{
- if (states & ReadOnlyState)
- return kThemeStateUnavailableInactive;
- if (!(states & EnabledState))
- return kThemeStateUnavailableInactive;
-
- // Do not process PressedState if !EnabledState or ReadOnlyState.
- if (states & PressedState) {
- if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kind == kThemeIncDecButtonMini)
- return states & SpinUpState ? kThemeStatePressedUp : kThemeStatePressedDown;
- return kThemeStatePressed;
- }
- return kThemeStateActive;
-}
-
-static IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize, const int* margins, float zoomFactor)
-{
- // Only do the inflation if the available width/height are too small. Otherwise try to
- // fit the glow/check space into the available box's width/height.
- int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[leftMargin] * zoomFactor + margins[rightMargin] * zoomFactor);
- int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[topMargin] * zoomFactor + margins[bottomMargin] * zoomFactor);
- IntRect result(zoomedRect);
- if (widthDelta < 0) {
- result.setX(result.x() - margins[leftMargin] * zoomFactor);
- result.setWidth(result.width() - widthDelta);
- }
- if (heightDelta < 0) {
- result.setY(result.y() - margins[topMargin] * zoomFactor);
- result.setHeight(result.height() - heightDelta);
- }
- return result;
-}
-
-// Checkboxes
-
-static const IntSize* checkboxSizes()
-{
- static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) };
- return sizes;
-}
-
-static const int* checkboxMargins(NSControlSize controlSize)
-{
- static const int margins[3][4] =
- {
- { 3, 4, 4, 2 },
- { 4, 3, 3, 3 },
- { 4, 3, 3, 3 },
- };
- return margins[controlSize];
-}
-
-static LengthSize checkboxSize(const FontDescription& fontDescription, const LengthSize& zoomedSize, float zoomFactor)
-{
- // If the width and height are both specified, then we have nothing to do.
- if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto())
- return zoomedSize;
-
- // Use the font size to determine the intrinsic width of the control.
- return sizeFromFont(fontDescription, zoomedSize, zoomFactor, checkboxSizes());
-}
-
-static NSButtonCell *checkbox(ControlStates states, const IntRect& zoomedRect, float zoomFactor)
-{
- static NSButtonCell *checkboxCell;
- if (!checkboxCell) {
- checkboxCell = [[NSButtonCell alloc] init];
- [checkboxCell setButtonType:NSSwitchButton];
- [checkboxCell setTitle:nil];
- [checkboxCell setAllowsMixedState:YES];
- [checkboxCell setFocusRingType:NSFocusRingTypeExterior];
- }
-
- // Set the control size based off the rectangle we're painting into.
- setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor);
-
- // Update the various states we respond to.
- updateStates(checkboxCell, states);
-
- return checkboxCell;
-}
-
-// FIXME: Share more code with radio buttons.
-static void paintCheckbox(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView)
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- // Determine the width and height needed for the control and prepare the cell for painting.
- NSButtonCell *checkboxCell = checkbox(states, zoomedRect, zoomFactor);
- GraphicsContextStateSaver stateSaver(*context);
-
- NSControlSize controlSize = [checkboxCell controlSize];
- IntSize zoomedSize = checkboxSizes()[controlSize];
- zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
- zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
- IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor);
-
- if (zoomFactor != 1.0f) {
- inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
- inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
- context->translate(inflatedRect.x(), inflatedRect.y());
- context->scale(FloatSize(zoomFactor, zoomFactor));
- context->translate(-inflatedRect.x(), -inflatedRect.y());
- }
-
- LocalCurrentGraphicsContext localContext(context);
- NSView *view = ThemeMac::ensuredView(scrollView);
- [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:view];
-#if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
- if (states & FocusState)
- [checkboxCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view];
-#endif
- [checkboxCell setControlView:nil];
-
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-// Radio Buttons
-
-static const IntSize* radioSizes()
-{
- static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) };
- return sizes;
-}
-
-static const int* radioMargins(NSControlSize controlSize)
-{
- static const int margins[3][4] =
- {
- { 2, 2, 4, 2 },
- { 3, 2, 3, 2 },
- { 1, 0, 2, 0 },
- };
- return margins[controlSize];
-}
-
-static LengthSize radioSize(const FontDescription& fontDescription, const LengthSize& zoomedSize, float zoomFactor)
-{
- // If the width and height are both specified, then we have nothing to do.
- if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto())
- return zoomedSize;
-
- // Use the font size to determine the intrinsic width of the control.
- return sizeFromFont(fontDescription, zoomedSize, zoomFactor, radioSizes());
-}
-
-static NSButtonCell *radio(ControlStates states, const IntRect& zoomedRect, float zoomFactor)
-{
- static NSButtonCell *radioCell;
- if (!radioCell) {
- radioCell = [[NSButtonCell alloc] init];
- [radioCell setButtonType:NSRadioButton];
- [radioCell setTitle:nil];
- [radioCell setFocusRingType:NSFocusRingTypeExterior];
- }
-
- // Set the control size based off the rectangle we're painting into.
- setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor);
-
- // Update the various states we respond to.
- updateStates(radioCell, states);
-
- return radioCell;
-}
-
-static void paintRadio(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView)
-{
- // Determine the width and height needed for the control and prepare the cell for painting.
- NSButtonCell *radioCell = radio(states, zoomedRect, zoomFactor);
- GraphicsContextStateSaver stateSaver(*context);
-
- NSControlSize controlSize = [radioCell controlSize];
- IntSize zoomedSize = radioSizes()[controlSize];
- zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
- zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
- IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor);
-
- if (zoomFactor != 1.0f) {
- inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
- inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
- context->translate(inflatedRect.x(), inflatedRect.y());
- context->scale(FloatSize(zoomFactor, zoomFactor));
- context->translate(-inflatedRect.x(), -inflatedRect.y());
- }
-
- LocalCurrentGraphicsContext localContext(context);
- BEGIN_BLOCK_OBJC_EXCEPTIONS
- NSView *view = ThemeMac::ensuredView(scrollView);
- [radioCell drawWithFrame:NSRect(inflatedRect) inView:view];
-#if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
- if (states & FocusState)
- [radioCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view];
-#endif
- [radioCell setControlView:nil];
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-// Buttons
-
-// Buttons really only constrain height. They respect width.
-static const IntSize* buttonSizes()
-{
- static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) };
- return sizes;
-}
-
-static const int* buttonMargins(NSControlSize controlSize)
-{
- static const int margins[3][4] =
- {
- { 4, 6, 7, 6 },
- { 4, 5, 6, 5 },
- { 0, 1, 1, 1 },
- };
- return margins[controlSize];
-}
-
-static void setUpButtonCell(NSButtonCell *cell, ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor)
-{
- // Set the control size based off the rectangle we're painting into.
- const IntSize* sizes = buttonSizes();
- if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegularControlSize].height() * zoomFactor) {
- // Use the square button
- if ([cell bezelStyle] != NSShadowlessSquareBezelStyle)
- [cell setBezelStyle:NSShadowlessSquareBezelStyle];
- } else if ([cell bezelStyle] != NSRoundedBezelStyle)
- [cell setBezelStyle:NSRoundedBezelStyle];
-
- setControlSize(cell, sizes, zoomedRect.size(), zoomFactor);
-
- // Update the various states we respond to.
- updateStates(cell, states);
-}
-
-static NSButtonCell *button(ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor)
-{
- static NSButtonCell *cell = nil;
- if (!cell) {
- cell = [[NSButtonCell alloc] init];
- [cell setTitle:nil];
- [cell setButtonType:NSMomentaryPushInButton];
- }
- setUpButtonCell(cell, part, states, zoomedRect, zoomFactor);
- return cell;
-}
-
-static void paintButton(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView)
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS
-
- // Determine the width and height needed for the control and prepare the cell for painting.
- NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor);
- GraphicsContextStateSaver stateSaver(*context);
-
- NSControlSize controlSize = [buttonCell controlSize];
- IntSize zoomedSize = buttonSizes()[controlSize];
- zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored.
- zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
- IntRect inflatedRect = zoomedRect;
- if ([buttonCell bezelStyle] == NSRoundedBezelStyle) {
- // Center the button within the available space.
- if (inflatedRect.height() > zoomedSize.height()) {
- inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomedSize.height()) / 2);
- inflatedRect.setHeight(zoomedSize.height());
- }
-
- // Now inflate it to account for the shadow.
- inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(controlSize), zoomFactor);
-
- if (zoomFactor != 1.0f) {
- inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
- inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
- context->translate(inflatedRect.x(), inflatedRect.y());
- context->scale(FloatSize(zoomFactor, zoomFactor));
- context->translate(-inflatedRect.x(), -inflatedRect.y());
- }
- }
-
- LocalCurrentGraphicsContext localContext(context);
- NSView *view = ThemeMac::ensuredView(scrollView);
-
- [buttonCell drawWithFrame:NSRect(inflatedRect) inView:view];
-#if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
- if (states & FocusState)
- [buttonCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view];
-#endif
- [buttonCell setControlView:nil];
-
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-// Stepper
-
-static const IntSize* stepperSizes()
-{
- static const IntSize sizes[3] = { IntSize(19, 27), IntSize(15, 22), IntSize(13, 15) };
- return sizes;
-}
-
-// We don't use controlSizeForFont() for steppers because the stepper height
-// should be equal to or less than the corresponding text field height,
-static NSControlSize stepperControlSizeForFont(const FontDescription& fontDescription)
-{
- int fontSize = fontDescription.computedPixelSize();
- if (fontSize >= 18)
- return NSRegularControlSize;
- if (fontSize >= 13)
- return NSSmallControlSize;
- return NSMiniControlSize;
-}
-
-static void paintStepper(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView*)
-{
- // We don't use NSStepperCell because there are no ways to draw an
- // NSStepperCell with the up button highlighted.
-
- HIThemeButtonDrawInfo drawInfo;
- drawInfo.version = 0;
- drawInfo.state = convertControlStatesToThemeDrawState(kThemeIncDecButton, states);
- drawInfo.adornment = kThemeAdornmentDefault;
- ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor);
- if (controlSize == NSSmallControlSize)
- drawInfo.kind = kThemeIncDecButtonSmall;
- else if (controlSize == NSMiniControlSize)
- drawInfo.kind = kThemeIncDecButtonMini;
- else
- drawInfo.kind = kThemeIncDecButton;
-
- IntRect rect(zoomedRect);
- GraphicsContextStateSaver stateSaver(*context);
- if (zoomFactor != 1.0f) {
- rect.setWidth(rect.width() / zoomFactor);
- rect.setHeight(rect.height() / zoomFactor);
- context->translate(rect.x(), rect.y());
- context->scale(FloatSize(zoomFactor, zoomFactor));
- context->translate(-rect.x(), -rect.y());
- }
- CGRect bounds(rect);
- CGRect backgroundBounds;
- HIThemeGetButtonBackgroundBounds(&bounds, &drawInfo, &backgroundBounds);
- // Center the stepper rectangle in the specified area.
- backgroundBounds.origin.x = bounds.origin.x + (bounds.size.width - backgroundBounds.size.width) / 2;
- if (backgroundBounds.size.height < bounds.size.height) {
- int heightDiff = clampToInteger(bounds.size.height - backgroundBounds.size.height);
- backgroundBounds.origin.y = bounds.origin.y + (heightDiff / 2) + 1;
- }
-
- LocalCurrentGraphicsContext localContext(context);
- HIThemeDrawButton(&backgroundBounds, &drawInfo, localContext.cgContext(), kHIThemeOrientationNormal, 0);
-}
-
-// This will ensure that we always return a valid NSView, even if ScrollView doesn't have an associated document NSView.
-// If the ScrollView doesn't have an NSView, we will return a fake NSView whose sole purpose is to tell AppKit that it's flipped.
-NSView *ThemeMac::ensuredView(ScrollView* scrollView)
-{
-
- // Use a fake flipped view.
- static NSView *flippedView = [[WebCoreFlippedView alloc] init];
- [flippedView setFrameSize:NSSizeFromCGSize(scrollView->contentsSize())];
-
- return flippedView;
-}
-
-void ThemeMac::setFocusRingClipRect(const FloatRect& rect)
-{
- focusRingClipRect = rect;
-}
-
-// Theme overrides
-
-int ThemeMac::baselinePositionAdjustment(ControlPart part) const
-{
- if (part == CheckboxPart || part == RadioPart)
- return -2;
- return Theme::baselinePositionAdjustment(part);
-}
-
-FontDescription ThemeMac::controlFont(ControlPart part, const FontDescription& fontDescription, float zoomFactor) const
-{
- switch (part) {
- case PushButtonPart: {
- FontDescription result;
- result.setIsAbsoluteSize(true);
- result.setGenericFamily(FontDescription::SerifFamily);
-
- NSFont* nsFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSizeForFont(fontDescription)]];
- result.firstFamily().setFamily([nsFont webCoreFamilyName]);
- result.setComputedSize([nsFont pointSize] * zoomFactor);
- result.setSpecifiedSize([nsFont pointSize] * zoomFactor);
- return result;
- }
- default:
- return Theme::controlFont(part, fontDescription, zoomFactor);
- }
-}
-
-LengthSize ThemeMac::controlSize(ControlPart part, const FontDescription& fontDescription, const LengthSize& zoomedSize, float zoomFactor) const
-{
- switch (part) {
- case CheckboxPart:
- return checkboxSize(fontDescription, zoomedSize, zoomFactor);
- case RadioPart:
- return radioSize(fontDescription, zoomedSize, zoomFactor);
- case PushButtonPart:
- // Height is reset to auto so that specified heights can be ignored.
- return sizeFromFont(fontDescription, LengthSize(zoomedSize.width(), Length()), zoomFactor, buttonSizes());
- case InnerSpinButtonPart:
- if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto())
- return zoomedSize;
- return sizeFromNSControlSize(stepperControlSizeForFont(fontDescription), zoomedSize, zoomFactor, stepperSizes());
- default:
- return zoomedSize;
- }
-}
-
-LengthSize ThemeMac::minimumControlSize(ControlPart part, const FontDescription& fontDescription, float zoomFactor) const
-{
- switch (part) {
- case SquareButtonPart:
- case ButtonPart:
- return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed));
- case InnerSpinButtonPart:{
- IntSize base = stepperSizes()[NSMiniControlSize];
- return LengthSize(Length(static_cast<int>(base.width() * zoomFactor), Fixed),
- Length(static_cast<int>(base.height() * zoomFactor), Fixed));
- }
- default:
- return Theme::minimumControlSize(part, fontDescription, zoomFactor);
- }
-}
-
-LengthBox ThemeMac::controlBorder(ControlPart part, const FontDescription& fontDescription, const LengthBox& zoomedBox, float zoomFactor) const
-{
- switch (part) {
- case SquareButtonPart:
- case ButtonPart:
- return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().value());
- default:
- return Theme::controlBorder(part, fontDescription, zoomedBox, zoomFactor);
- }
-}
-
-LengthBox ThemeMac::controlPadding(ControlPart part, const FontDescription& fontDescription, const LengthBox& zoomedBox, float zoomFactor) const
-{
- switch (part) {
- case PushButtonPart: {
- // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large
- // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is
- // by definition constrained, since we select mini only for small cramped environments.
- // This also guarantees the HTML <button> will match our rendering by default, since we're using a consistent
- // padding.
- const int padding = 8 * zoomFactor;
- return LengthBox(0, padding, 0, padding);
- }
- default:
- return Theme::controlPadding(part, fontDescription, zoomedBox, zoomFactor);
- }
-}
-
-void ThemeMac::inflateControlPaintRect(ControlPart part, ControlStates states, IntRect& zoomedRect, float zoomFactor) const
-{
- BEGIN_BLOCK_OBJC_EXCEPTIONS
- switch (part) {
- case CheckboxPart: {
- // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox
- // shadow" and the check. We don't consider this part of the bounds of the control in WebKit.
- NSCell *cell = checkbox(states, zoomedRect, zoomFactor);
- NSControlSize controlSize = [cell controlSize];
- IntSize zoomedSize = checkboxSizes()[controlSize];
- zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
- zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
- zoomedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor);
- break;
- }
- case RadioPart: {
- // We inflate the rect as needed to account for padding included in the cell to accommodate the radio button
- // shadow". We don't consider this part of the bounds of the control in WebKit.
- NSCell *cell = radio(states, zoomedRect, zoomFactor);
- NSControlSize controlSize = [cell controlSize];
- IntSize zoomedSize = radioSizes()[controlSize];
- zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
- zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
- zoomedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor);
- break;
- }
- case PushButtonPart:
- case ButtonPart: {
- NSButtonCell *cell = button(part, states, zoomedRect, zoomFactor);
- NSControlSize controlSize = [cell controlSize];
-
- // We inflate the rect as needed to account for the Aqua button's shadow.
- if ([cell bezelStyle] == NSRoundedBezelStyle) {
- IntSize zoomedSize = buttonSizes()[controlSize];
- zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
- zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored.
- zoomedRect = inflateRect(zoomedRect, zoomedSize, buttonMargins(controlSize), zoomFactor);
- }
- break;
- }
- case InnerSpinButtonPart: {
- static const int stepperMargin[4] = { 0, 0, 0, 0 };
- ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor);
- IntSize zoomedSize = stepperSizes()[controlSize];
- zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
- zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
- zoomedRect = inflateRect(zoomedRect, zoomedSize, stepperMargin, zoomFactor);
- break;
- }
- default:
- break;
- }
- END_BLOCK_OBJC_EXCEPTIONS
-}
-
-void ThemeMac::paint(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) const
-{
- switch (part) {
- case CheckboxPart:
- paintCheckbox(states, context, zoomedRect, zoomFactor, scrollView);
- break;
- case RadioPart:
- paintRadio(states, context, zoomedRect, zoomFactor, scrollView);
- break;
- case PushButtonPart:
- case ButtonPart:
- case SquareButtonPart:
- paintButton(part, states, context, zoomedRect, zoomFactor, scrollView);
- break;
- case InnerSpinButtonPart:
- paintStepper(states, context, zoomedRect, zoomFactor, scrollView);
- break;
- default:
- break;
- }
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamCenter.cpp b/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamCenter.cpp
deleted file mode 100644
index 3baadb439b6..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamCenter.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Ericsson nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/platform/mediastream/MediaStreamCenter.h"
-
-#include "core/platform/mediastream/MediaStreamDescriptor.h"
-#include "modules/mediastream/MediaStreamTrackSourcesRequest.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebMediaStream.h"
-#include "public/platform/WebMediaStreamCenter.h"
-#include "public/platform/WebMediaStreamTrack.h"
-#include "public/platform/WebMediaStreamTrackSourcesRequest.h"
-#include "wtf/MainThread.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace WebCore {
-
-MediaStreamCenter& MediaStreamCenter::instance()
-{
- ASSERT(isMainThread());
- DEFINE_STATIC_LOCAL(MediaStreamCenter, center, ());
- return center;
-}
-
-MediaStreamCenter::MediaStreamCenter()
- : m_private(adoptPtr(blink::Platform::current()->createMediaStreamCenter(this)))
-{
-}
-
-MediaStreamCenter::~MediaStreamCenter()
-{
-}
-
-bool MediaStreamCenter::getMediaStreamTrackSources(PassRefPtr<MediaStreamTrackSourcesRequest> request)
-{
- return m_private && m_private->getMediaStreamTrackSources(request);
-}
-
-void MediaStreamCenter::didSetMediaStreamTrackEnabled(MediaStreamDescriptor* stream, MediaStreamComponent* component)
-{
- if (m_private) {
- if (component->enabled()) {
- m_private->didEnableMediaStreamTrack(stream, component);
- m_private->didEnableMediaStreamTrack(component);
- } else {
- m_private->didDisableMediaStreamTrack(stream, component);
- m_private->didDisableMediaStreamTrack(component);
- }
- }
-}
-
-bool MediaStreamCenter::didAddMediaStreamTrack(MediaStreamDescriptor* stream, MediaStreamComponent* component)
-{
- return m_private && m_private->didAddMediaStreamTrack(stream, component);
-}
-
-bool MediaStreamCenter::didRemoveMediaStreamTrack(MediaStreamDescriptor* stream, MediaStreamComponent* component)
-{
- return m_private && m_private->didRemoveMediaStreamTrack(stream, component);
-}
-
-void MediaStreamCenter::didStopLocalMediaStream(MediaStreamDescriptor* stream)
-{
- if (m_private)
- m_private->didStopLocalMediaStream(stream);
-}
-
-bool MediaStreamCenter::didStopMediaStreamTrack(MediaStreamComponent* track)
-{
- return m_private && m_private->didStopMediaStreamTrack(track);
-}
-
-void MediaStreamCenter::didCreateMediaStream(MediaStreamDescriptor* stream)
-{
- if (m_private) {
- blink::WebMediaStream webStream(stream);
- m_private->didCreateMediaStream(webStream);
- }
-}
-
-void MediaStreamCenter::didCreateMediaStreamTrack(MediaStreamComponent* track)
-{
- if (m_private)
- m_private->didCreateMediaStreamTrack(track);
-}
-
-void MediaStreamCenter::stopLocalMediaStream(const blink::WebMediaStream& webStream)
-{
- MediaStreamDescriptor* stream = webStream;
- MediaStreamDescriptorClient* client = stream->client();
- if (client)
- client->streamEnded();
- else
- stream->setEnded();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamCenter.h b/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamCenter.h
deleted file mode 100644
index 7a3630b1adb..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamCenter.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Ericsson nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaStreamCenter_h
-#define MediaStreamCenter_h
-
-#include "public/platform/WebMediaStreamCenterClient.h"
-#include "public/platform/WebVector.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-class WebMediaStream;
-class WebMediaStreamCenter;
-class WebMediaStreamTrack;
-}
-
-namespace WebCore {
-
-class MediaStreamComponent;
-class MediaStreamDescriptor;
-class MediaStreamTrackSourcesRequest;
-
-class MediaStreamCenter : public blink::WebMediaStreamCenterClient {
-public:
- ~MediaStreamCenter();
-
- static MediaStreamCenter& instance();
-
- bool getMediaStreamTrackSources(PassRefPtr<MediaStreamTrackSourcesRequest>);
-
- void didCreateMediaStreamTrack(MediaStreamComponent*);
- void didSetMediaStreamTrackEnabled(MediaStreamDescriptor*, MediaStreamComponent*);
- bool didStopMediaStreamTrack(MediaStreamComponent*);
-
- void didCreateMediaStream(MediaStreamDescriptor*);
- bool didAddMediaStreamTrack(MediaStreamDescriptor*, MediaStreamComponent*);
- bool didRemoveMediaStreamTrack(MediaStreamDescriptor*, MediaStreamComponent*);
- void didStopLocalMediaStream(MediaStreamDescriptor*);
-
- // blink::WebMediaStreamCenterClient
- virtual void stopLocalMediaStream(const blink::WebMediaStream&) OVERRIDE;
-
-private:
- MediaStreamCenter();
-
- OwnPtr<blink::WebMediaStreamCenter> m_private;
-};
-
-} // namespace WebCore
-
-#endif // MediaStreamCenter_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamDescriptor.cpp b/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamDescriptor.cpp
deleted file mode 100644
index 7ec27a3a3c7..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamDescriptor.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/platform/mediastream/MediaStreamDescriptor.h"
-
-#include "platform/UUID.h"
-
-namespace WebCore {
-
-PassRefPtr<MediaStreamDescriptor> MediaStreamDescriptor::create(const MediaStreamSourceVector& audioSources, const MediaStreamSourceVector& videoSources)
-{
- return adoptRef(new MediaStreamDescriptor(createCanonicalUUIDString(), audioSources, videoSources));
-}
-
-PassRefPtr<MediaStreamDescriptor> MediaStreamDescriptor::create(const String& id, const MediaStreamComponentVector& audioComponents, const MediaStreamComponentVector& videoComponents)
-{
- return adoptRef(new MediaStreamDescriptor(id, audioComponents, videoComponents));
-}
-
-void MediaStreamDescriptor::addComponent(PassRefPtr<MediaStreamComponent> component)
-{
- switch (component->source()->type()) {
- case MediaStreamSource::TypeAudio:
- if (m_audioComponents.find(component) == kNotFound)
- m_audioComponents.append(component);
- break;
- case MediaStreamSource::TypeVideo:
- if (m_videoComponents.find(component) == kNotFound)
- m_videoComponents.append(component);
- break;
- }
-}
-
-void MediaStreamDescriptor::removeComponent(PassRefPtr<MediaStreamComponent> component)
-{
- size_t pos = kNotFound;
- switch (component->source()->type()) {
- case MediaStreamSource::TypeAudio:
- pos = m_audioComponents.find(component);
- if (pos != kNotFound)
- m_audioComponents.remove(pos);
- break;
- case MediaStreamSource::TypeVideo:
- pos = m_videoComponents.find(component);
- if (pos != kNotFound)
- m_videoComponents.remove(pos);
- break;
- }
-}
-
-void MediaStreamDescriptor::addRemoteTrack(MediaStreamComponent* component)
-{
- if (m_client)
- m_client->addRemoteTrack(component);
- else
- addComponent(component);
-}
-
-void MediaStreamDescriptor::removeRemoteTrack(MediaStreamComponent* component)
-{
- if (m_client)
- m_client->removeRemoteTrack(component);
- else
- removeComponent(component);
-}
-
-MediaStreamDescriptor::MediaStreamDescriptor(const String& id, const MediaStreamSourceVector& audioSources, const MediaStreamSourceVector& videoSources)
- : m_client(0)
- , m_id(id)
- , m_ended(false)
-{
- ASSERT(m_id.length());
- for (size_t i = 0; i < audioSources.size(); i++)
- m_audioComponents.append(MediaStreamComponent::create(this, audioSources[i]));
-
- for (size_t i = 0; i < videoSources.size(); i++)
- m_videoComponents.append(MediaStreamComponent::create(this, videoSources[i]));
-}
-
-MediaStreamDescriptor::MediaStreamDescriptor(const String& id, const MediaStreamComponentVector& audioComponents, const MediaStreamComponentVector& videoComponents)
- : m_client(0)
- , m_id(id)
- , m_ended(false)
-{
- ASSERT(m_id.length());
- for (MediaStreamComponentVector::const_iterator iter = audioComponents.begin(); iter != audioComponents.end(); ++iter) {
- (*iter)->setStream(this);
- m_audioComponents.append((*iter));
- }
- for (MediaStreamComponentVector::const_iterator iter = videoComponents.begin(); iter != videoComponents.end(); ++iter) {
- (*iter)->setStream(this);
- m_videoComponents.append((*iter));
- }
-}
-
-MediaStreamDescriptor::~MediaStreamDescriptor()
-{
- for (MediaStreamComponentVector::iterator iter = m_audioComponents.begin(); iter != m_audioComponents.end(); ++iter)
- (*iter)->setStream(0);
-
- for (MediaStreamComponentVector::iterator iter = m_videoComponents.begin(); iter != m_videoComponents.end(); ++iter)
- (*iter)->setStream(0);
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamDescriptor.h b/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamDescriptor.h
deleted file mode 100644
index 383602b1f18..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/MediaStreamDescriptor.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2011 Ericsson AB. All rights reserved.
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Ericsson nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaStreamDescriptor_h
-#define MediaStreamDescriptor_h
-
-#include "platform/mediastream/MediaStreamComponent.h"
-#include "platform/mediastream/MediaStreamSource.h"
-#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class MediaStreamDescriptorClient {
-public:
- virtual ~MediaStreamDescriptorClient() { }
-
- virtual void trackEnded() = 0;
- virtual void streamEnded() = 0;
- virtual void addRemoteTrack(MediaStreamComponent*) = 0;
- virtual void removeRemoteTrack(MediaStreamComponent*) = 0;
-};
-
-class MediaStreamDescriptor FINAL : public RefCounted<MediaStreamDescriptor> {
-public:
- class ExtraData : public RefCounted<ExtraData> {
- public:
- virtual ~ExtraData() { }
- };
-
- static PassRefPtr<MediaStreamDescriptor> create(const MediaStreamSourceVector& audioSources, const MediaStreamSourceVector& videoSources);
-
- static PassRefPtr<MediaStreamDescriptor> create(const String& id, const MediaStreamComponentVector& audioComponents, const MediaStreamComponentVector& videoComponents);
-
- ~MediaStreamDescriptor();
-
- MediaStreamDescriptorClient* client() const { return m_client; }
- void setClient(MediaStreamDescriptorClient* client) { m_client = client; }
-
- String id() const { return m_id; }
-
- unsigned numberOfAudioComponents() const { return m_audioComponents.size(); }
- MediaStreamComponent* audioComponent(unsigned index) const { return m_audioComponents[index].get(); }
-
- unsigned numberOfVideoComponents() const { return m_videoComponents.size(); }
- MediaStreamComponent* videoComponent(unsigned index) const { return m_videoComponents[index].get(); }
-
- void addComponent(PassRefPtr<MediaStreamComponent>);
- void removeComponent(PassRefPtr<MediaStreamComponent>);
-
- void addRemoteTrack(MediaStreamComponent*);
- void removeRemoteTrack(MediaStreamComponent*);
-
- bool ended() const { return m_ended; }
- void setEnded() { m_ended = true; }
-
- PassRefPtr<ExtraData> extraData() const { return m_extraData; }
- void setExtraData(PassRefPtr<ExtraData> extraData) { m_extraData = extraData; }
-
-private:
- MediaStreamDescriptor(const String& id, const MediaStreamSourceVector& audioSources, const MediaStreamSourceVector& videoSources);
- MediaStreamDescriptor(const String& id, const MediaStreamComponentVector& audioComponents, const MediaStreamComponentVector& videoComponents);
-
- MediaStreamDescriptorClient* m_client;
- String m_id;
- Vector<RefPtr<MediaStreamComponent> > m_audioComponents;
- Vector<RefPtr<MediaStreamComponent> > m_videoComponents;
- bool m_ended;
-
- RefPtr<ExtraData> m_extraData;
-};
-
-typedef Vector<RefPtr<MediaStreamDescriptor> > MediaStreamDescriptorVector;
-
-} // namespace WebCore
-
-#endif // MediaStreamDescriptor_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandler.cpp b/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandler.cpp
deleted file mode 100644
index 7c91a118140..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandler.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/mediastream/RTCDataChannelHandler.h"
-
-namespace WebCore {
-
-PassOwnPtr<RTCDataChannelHandler> RTCDataChannelHandler::create(blink::WebRTCDataChannelHandler* webHandler)
-{
- return adoptPtr(new RTCDataChannelHandler(webHandler));
-}
-
-RTCDataChannelHandler::RTCDataChannelHandler(blink::WebRTCDataChannelHandler* webHandler)
- : m_webHandler(adoptPtr(webHandler))
- , m_client(0)
-{
-}
-
-RTCDataChannelHandler::~RTCDataChannelHandler()
-{
-}
-
-void RTCDataChannelHandler::setClient(RTCDataChannelHandlerClient* client)
-{
- m_client = client;
- m_webHandler->setClient(m_client ? this : 0);
-}
-
-String RTCDataChannelHandler::label() const
-{
- return m_webHandler->label();
-}
-
-bool RTCDataChannelHandler::isReliable() const
-{
- return m_webHandler->isReliable();
-}
-
-bool RTCDataChannelHandler::ordered() const
-{
- return m_webHandler->ordered();
-}
-
-unsigned short RTCDataChannelHandler::maxRetransmitTime() const
-{
- return m_webHandler->maxRetransmitTime();
-}
-
-unsigned short RTCDataChannelHandler::maxRetransmits() const
-{
- return m_webHandler->maxRetransmits();
-}
-
-String RTCDataChannelHandler::protocol() const
-{
- return m_webHandler->protocol();
-}
-
-bool RTCDataChannelHandler::negotiated() const
-{
- return m_webHandler->negotiated();
-}
-
-unsigned short RTCDataChannelHandler::id() const
-{
- return m_webHandler->id();
-}
-
-unsigned long RTCDataChannelHandler::bufferedAmount()
-{
- return m_webHandler->bufferedAmount();
-}
-
-bool RTCDataChannelHandler::sendStringData(const String& data)
-{
- return m_webHandler->sendStringData(data);
-}
-
-bool RTCDataChannelHandler::sendRawData(const char* data, size_t size)
-{
- return m_webHandler->sendRawData(data, size);
-}
-
-void RTCDataChannelHandler::close()
-{
- m_webHandler->close();
-}
-
-void RTCDataChannelHandler::didChangeReadyState(WebRTCDataChannelHandlerClient::ReadyState state) const
-{
- if (m_client)
- m_client->didChangeReadyState(static_cast<RTCDataChannelHandlerClient::ReadyState>(state));
-}
-
-void RTCDataChannelHandler::didReceiveStringData(const blink::WebString& data) const
-{
- if (m_client)
- m_client->didReceiveStringData(data);
-}
-
-void RTCDataChannelHandler::didReceiveRawData(const char* data, size_t size) const
-{
- if (m_client)
- m_client->didReceiveRawData(data, size);
-}
-
-void RTCDataChannelHandler::didDetectError() const
-{
- if (m_client)
- m_client->didDetectError();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandler.h b/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandler.h
deleted file mode 100644
index d860dad83bb..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandler.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCDataChannelHandler_h
-#define RTCDataChannelHandler_h
-
-#include "core/platform/mediastream/RTCDataChannelHandlerClient.h"
-#include "public/platform/WebRTCDataChannelHandler.h"
-#include "public/platform/WebRTCDataChannelHandlerClient.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace WebCore {
-
-class RTCDataChannelHandlerClient;
-
-class RTCDataChannelHandler : public blink::WebRTCDataChannelHandlerClient {
-public:
- static PassOwnPtr<RTCDataChannelHandler> create(blink::WebRTCDataChannelHandler*);
- virtual ~RTCDataChannelHandler();
-
- void setClient(RTCDataChannelHandlerClient*);
-
- String label() const;
-
- // DEPRECATED
- bool isReliable() const;
-
- bool ordered() const;
- unsigned short maxRetransmitTime() const;
- unsigned short maxRetransmits() const;
- String protocol() const;
- bool negotiated() const;
- unsigned short id() const;
-
- unsigned long bufferedAmount();
- bool sendStringData(const String&);
- bool sendRawData(const char*, size_t);
- void close();
-
- // blink::WebRTCDataChannelHandlerClient implementation.
- virtual void didChangeReadyState(ReadyState) const OVERRIDE;
- virtual void didReceiveStringData(const blink::WebString&) const OVERRIDE;
- virtual void didReceiveRawData(const char*, size_t) const OVERRIDE;
- virtual void didDetectError() const OVERRIDE;
-
-private:
- explicit RTCDataChannelHandler(blink::WebRTCDataChannelHandler*);
-
- OwnPtr<blink::WebRTCDataChannelHandler> m_webHandler;
- RTCDataChannelHandlerClient* m_client;
-};
-
-} // namespace WebCore
-
-#endif // RTCDataChannelHandler_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandlerClient.h b/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandlerClient.h
deleted file mode 100644
index ceaf13cfedc..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCDataChannelHandlerClient.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCDataChannelHandlerClient_h
-#define RTCDataChannelHandlerClient_h
-
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class RTCDataChannelHandlerClient {
-public:
- enum ReadyState {
- ReadyStateConnecting = 0,
- ReadyStateOpen = 1,
- ReadyStateClosing = 2,
- ReadyStateClosed = 3,
- };
-
- virtual ~RTCDataChannelHandlerClient() { }
-
- virtual void didChangeReadyState(ReadyState) = 0;
- virtual void didReceiveStringData(const String&) = 0;
- virtual void didReceiveRawData(const char*, size_t) = 0;
- virtual void didDetectError() = 0;
-};
-
-} // namespace WebCore
-
-#endif // RTCDataChannelHandlerClient_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandler.cpp b/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandler.cpp
deleted file mode 100644
index b27cabbe192..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandler.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/mediastream/RTCPeerConnectionHandler.h"
-
-#include "core/platform/mediastream/RTCDataChannelHandler.h"
-#include "core/platform/mediastream/RTCPeerConnectionHandlerClient.h"
-#include "core/platform/mediastream/RTCStatsRequest.h"
-#include "platform/mediastream/MediaConstraints.h"
-#include "platform/mediastream/MediaStreamComponent.h"
-#include "platform/mediastream/RTCConfiguration.h"
-#include "platform/mediastream/RTCDTMFSenderHandler.h"
-#include "platform/mediastream/RTCSessionDescriptionRequest.h"
-#include "platform/mediastream/RTCVoidRequest.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebMediaConstraints.h"
-#include "public/platform/WebMediaStream.h"
-#include "public/platform/WebMediaStreamTrack.h"
-#include "public/platform/WebRTCConfiguration.h"
-#include "public/platform/WebRTCDTMFSenderHandler.h"
-#include "public/platform/WebRTCDataChannelHandler.h"
-#include "public/platform/WebRTCICECandidate.h"
-#include "public/platform/WebRTCSessionDescription.h"
-#include "public/platform/WebRTCSessionDescriptionRequest.h"
-#include "public/platform/WebRTCStatsRequest.h"
-#include "public/platform/WebRTCVoidRequest.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace WebCore {
-
-blink::WebRTCPeerConnectionHandler* RTCPeerConnectionHandler::toWebRTCPeerConnectionHandler(RTCPeerConnectionHandler* handler)
-{
- return static_cast<RTCPeerConnectionHandler*>(handler)->m_webHandler.get();
-}
-
-PassOwnPtr<RTCPeerConnectionHandler> RTCPeerConnectionHandler::create(RTCPeerConnectionHandlerClient* client)
-{
- ASSERT(client);
- OwnPtr<RTCPeerConnectionHandler> handler = adoptPtr(new RTCPeerConnectionHandler(client));
-
- if (!handler->createWebHandler())
- return nullptr;
-
- return handler.release();
-}
-
-RTCPeerConnectionHandler::RTCPeerConnectionHandler(RTCPeerConnectionHandlerClient* client)
- : m_client(client)
-{
-}
-
-RTCPeerConnectionHandler::~RTCPeerConnectionHandler()
-{
-}
-
-bool RTCPeerConnectionHandler::createWebHandler()
-{
- m_webHandler = adoptPtr(blink::Platform::current()->createRTCPeerConnectionHandler(this));
- return m_webHandler;
-}
-
-bool RTCPeerConnectionHandler::initialize(PassRefPtr<RTCConfiguration> configuration, PassRefPtr<MediaConstraints> constraints)
-{
- return m_webHandler->initialize(configuration, constraints);
-}
-
-void RTCPeerConnectionHandler::createOffer(PassRefPtr<RTCSessionDescriptionRequest> request, PassRefPtr<MediaConstraints> constraints)
-{
- m_webHandler->createOffer(request, constraints);
-}
-
-void RTCPeerConnectionHandler::createAnswer(PassRefPtr<RTCSessionDescriptionRequest> request, PassRefPtr<MediaConstraints> constraints)
-{
- m_webHandler->createAnswer(request, constraints);
-}
-
-void RTCPeerConnectionHandler::setLocalDescription(PassRefPtr<RTCVoidRequest> request, blink::WebRTCSessionDescription sessionDescription)
-{
- m_webHandler->setLocalDescription(request, sessionDescription);
-}
-
-void RTCPeerConnectionHandler::setRemoteDescription(PassRefPtr<RTCVoidRequest> request, blink::WebRTCSessionDescription sessionDescription)
-{
- m_webHandler->setRemoteDescription(request, sessionDescription);
-}
-
-bool RTCPeerConnectionHandler::updateIce(PassRefPtr<RTCConfiguration> configuration, PassRefPtr<MediaConstraints> constraints)
-{
- return m_webHandler->updateICE(configuration, constraints);
-}
-
-bool RTCPeerConnectionHandler::addIceCandidate(blink::WebRTCICECandidate iceCandidate)
-{
- return m_webHandler->addICECandidate(iceCandidate);
-}
-
-bool RTCPeerConnectionHandler::addIceCandidate(PassRefPtr<RTCVoidRequest> request, blink::WebRTCICECandidate iceCandidate)
-{
- return m_webHandler->addICECandidate(request, iceCandidate);
-}
-
-blink::WebRTCSessionDescription RTCPeerConnectionHandler::localDescription()
-{
- return m_webHandler->localDescription();
-}
-
-blink::WebRTCSessionDescription RTCPeerConnectionHandler::remoteDescription()
-{
- return m_webHandler->remoteDescription();
-}
-
-bool RTCPeerConnectionHandler::addStream(PassRefPtr<MediaStreamDescriptor> mediaStream, PassRefPtr<MediaConstraints> constraints)
-{
- return m_webHandler->addStream(mediaStream, constraints);
-}
-
-void RTCPeerConnectionHandler::removeStream(PassRefPtr<MediaStreamDescriptor> mediaStream)
-{
- m_webHandler->removeStream(mediaStream);
-}
-
-void RTCPeerConnectionHandler::getStats(PassRefPtr<RTCStatsRequest> request)
-{
- m_webHandler->getStats(request);
-}
-
-PassOwnPtr<RTCDataChannelHandler> RTCPeerConnectionHandler::createDataChannel(const String& label, const blink::WebRTCDataChannelInit& init)
-{
- blink::WebRTCDataChannelHandler* webHandler = m_webHandler->createDataChannel(label, init);
- if (!webHandler)
- return nullptr;
-
- return RTCDataChannelHandler::create(webHandler);
-}
-
-PassOwnPtr<RTCDTMFSenderHandler> RTCPeerConnectionHandler::createDTMFSender(PassRefPtr<MediaStreamComponent> track)
-{
- blink::WebRTCDTMFSenderHandler* webHandler = m_webHandler->createDTMFSender(track);
- if (!webHandler)
- return nullptr;
-
- return RTCDTMFSenderHandler::create(webHandler);
-}
-
-void RTCPeerConnectionHandler::stop()
-{
- m_webHandler->stop();
-}
-
-void RTCPeerConnectionHandler::negotiationNeeded()
-{
- m_client->negotiationNeeded();
-}
-
-void RTCPeerConnectionHandler::didGenerateICECandidate(const blink::WebRTCICECandidate& iceCandidate)
-{
- m_client->didGenerateIceCandidate(iceCandidate);
-}
-
-void RTCPeerConnectionHandler::didChangeSignalingState(blink::WebRTCPeerConnectionHandlerClient::SignalingState state)
-{
- m_client->didChangeSignalingState(static_cast<RTCPeerConnectionHandlerClient::SignalingState>(state));
-}
-
-void RTCPeerConnectionHandler::didChangeICEGatheringState(blink::WebRTCPeerConnectionHandlerClient::ICEGatheringState state)
-{
- m_client->didChangeIceGatheringState(static_cast<RTCPeerConnectionHandlerClient::IceGatheringState>(state));
-}
-
-void RTCPeerConnectionHandler::didChangeICEConnectionState(blink::WebRTCPeerConnectionHandlerClient::ICEConnectionState state)
-{
- m_client->didChangeIceConnectionState(static_cast<RTCPeerConnectionHandlerClient::IceConnectionState>(state));
-}
-
-void RTCPeerConnectionHandler::didAddRemoteStream(const blink::WebMediaStream& webMediaStreamDescriptor)
-{
- m_client->didAddRemoteStream(webMediaStreamDescriptor);
-}
-
-void RTCPeerConnectionHandler::didRemoveRemoteStream(const blink::WebMediaStream& webMediaStreamDescriptor)
-{
- m_client->didRemoveRemoteStream(webMediaStreamDescriptor);
-}
-
-void RTCPeerConnectionHandler::didAddRemoteDataChannel(blink::WebRTCDataChannelHandler* webHandler)
-{
- ASSERT(webHandler);
- m_client->didAddRemoteDataChannel(RTCDataChannelHandler::create(webHandler));
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandler.h b/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandler.h
deleted file mode 100644
index 9510a60d297..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandler.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCPeerConnectionHandler_h
-#define RTCPeerConnectionHandler_h
-
-#include "core/platform/mediastream/MediaStreamDescriptor.h"
-#include "public/platform/WebRTCPeerConnectionHandler.h"
-#include "public/platform/WebRTCPeerConnectionHandlerClient.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassRefPtr.h"
-
-namespace blink {
-class WebMediaStream;
-class WebRTCICECandidate;
-class WebRTCSessionDescription;
-struct WebRTCDataChannelInit;
-}
-
-namespace WebCore {
-
-class MediaConstraints;
-class MediaStreamComponent;
-class RTCConfiguration;
-class RTCDTMFSenderHandler;
-class RTCDataChannelHandler;
-class RTCPeerConnectionHandlerClient;
-class RTCSessionDescriptionRequest;
-class RTCStatsRequest;
-class RTCVoidRequest;
-
-class RTCPeerConnectionHandler : public blink::WebRTCPeerConnectionHandlerClient {
-public:
- static PassOwnPtr<RTCPeerConnectionHandler> create(RTCPeerConnectionHandlerClient*);
- virtual ~RTCPeerConnectionHandler();
-
- bool createWebHandler();
-
- bool initialize(PassRefPtr<RTCConfiguration>, PassRefPtr<MediaConstraints>);
-
- void createOffer(PassRefPtr<RTCSessionDescriptionRequest>, PassRefPtr<MediaConstraints>);
- void createAnswer(PassRefPtr<RTCSessionDescriptionRequest>, PassRefPtr<MediaConstraints>);
- void setLocalDescription(PassRefPtr<RTCVoidRequest>, blink::WebRTCSessionDescription);
- void setRemoteDescription(PassRefPtr<RTCVoidRequest>, blink::WebRTCSessionDescription);
- blink::WebRTCSessionDescription localDescription();
- blink::WebRTCSessionDescription remoteDescription();
- bool updateIce(PassRefPtr<RTCConfiguration>, PassRefPtr<MediaConstraints>);
-
- // DEPRECATED
- bool addIceCandidate(blink::WebRTCICECandidate);
-
- bool addIceCandidate(PassRefPtr<RTCVoidRequest>, blink::WebRTCICECandidate);
- bool addStream(PassRefPtr<MediaStreamDescriptor>, PassRefPtr<MediaConstraints>);
- void removeStream(PassRefPtr<MediaStreamDescriptor>);
- void getStats(PassRefPtr<RTCStatsRequest>);
- PassOwnPtr<RTCDataChannelHandler> createDataChannel(const String& label, const blink::WebRTCDataChannelInit&);
- PassOwnPtr<RTCDTMFSenderHandler> createDTMFSender(PassRefPtr<MediaStreamComponent>);
- void stop();
-
- // blink::WebRTCPeerConnectionHandlerClient implementation.
- virtual void negotiationNeeded() OVERRIDE;
- virtual void didGenerateICECandidate(const blink::WebRTCICECandidate&) OVERRIDE;
- virtual void didChangeSignalingState(blink::WebRTCPeerConnectionHandlerClient::SignalingState) OVERRIDE;
- virtual void didChangeICEGatheringState(blink::WebRTCPeerConnectionHandlerClient::ICEGatheringState) OVERRIDE;
- virtual void didChangeICEConnectionState(blink::WebRTCPeerConnectionHandlerClient::ICEConnectionState) OVERRIDE;
- virtual void didAddRemoteStream(const blink::WebMediaStream&) OVERRIDE;
- virtual void didRemoveRemoteStream(const blink::WebMediaStream&) OVERRIDE;
- virtual void didAddRemoteDataChannel(blink::WebRTCDataChannelHandler*) OVERRIDE;
-
- static blink::WebRTCPeerConnectionHandler* toWebRTCPeerConnectionHandler(RTCPeerConnectionHandler*);
-
-private:
- explicit RTCPeerConnectionHandler(RTCPeerConnectionHandlerClient*);
-
- OwnPtr<blink::WebRTCPeerConnectionHandler> m_webHandler;
- RTCPeerConnectionHandlerClient* m_client;
-};
-
-} // namespace WebCore
-
-#endif // RTCPeerConnectionHandler_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandlerClient.h b/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandlerClient.h
deleted file mode 100644
index 46f276fb3bd..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCPeerConnectionHandlerClient.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2012 Google AB. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCPeerConnectionHandlerClient_h
-#define RTCPeerConnectionHandlerClient_h
-
-#include "wtf/PassRefPtr.h"
-
-namespace blink {
-class WebRTCICECandidate;
-}
-
-namespace WebCore {
-
-class MediaStreamDescriptor;
-class RTCDataChannelHandler;
-
-class RTCPeerConnectionHandlerClient {
-public:
- enum SignalingState {
- SignalingStateStable = 1,
- SignalingStateHaveLocalOffer = 2,
- SignalingStateHaveRemoteOffer = 3,
- SignalingStateHaveLocalPrAnswer = 4,
- SignalingStateHaveRemotePrAnswer = 5,
- SignalingStateClosed = 6,
- };
-
- enum IceConnectionState {
- IceConnectionStateNew = 1,
- IceConnectionStateChecking = 2,
- IceConnectionStateConnected = 3,
- IceConnectionStateCompleted = 4,
- IceConnectionStateFailed = 5,
- IceConnectionStateDisconnected = 6,
- IceConnectionStateClosed = 7
- };
-
- enum IceGatheringState {
- IceGatheringStateNew = 1,
- IceGatheringStateGathering = 2,
- IceGatheringStateComplete = 3
- };
-
- virtual ~RTCPeerConnectionHandlerClient() { }
-
- virtual void negotiationNeeded() = 0;
- virtual void didGenerateIceCandidate(blink::WebRTCICECandidate) = 0;
- virtual void didChangeSignalingState(SignalingState) = 0;
- virtual void didChangeIceGatheringState(IceGatheringState) = 0;
- virtual void didChangeIceConnectionState(IceConnectionState) = 0;
- virtual void didAddRemoteStream(PassRefPtr<MediaStreamDescriptor>) = 0;
- virtual void didRemoveRemoteStream(MediaStreamDescriptor*) = 0;
- virtual void didAddRemoteDataChannel(PassOwnPtr<RTCDataChannelHandler>) = 0;
-};
-
-} // namespace WebCore
-
-#endif // RTCPeerConnectionHandlerClient_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCStatsRequest.h b/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCStatsRequest.h
deleted file mode 100644
index 5f93fe0785a..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mediastream/RTCStatsRequest.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors
- * may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RTCStatsRequest_h
-#define RTCStatsRequest_h
-
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class MediaStreamComponent;
-class MediaStreamDescriptor;
-class RTCStatsResponseBase;
-
-class RTCStatsRequest : public RefCounted<RTCStatsRequest> {
-public:
- virtual ~RTCStatsRequest() { }
-
- virtual PassRefPtr<RTCStatsResponseBase> createResponse() = 0;
- virtual bool hasSelector() = 0;
- virtual MediaStreamDescriptor* stream() = 0;
- virtual MediaStreamComponent* component() = 0;
- virtual void requestSucceeded(PassRefPtr<RTCStatsResponseBase>) = 0;
-
-protected:
- RTCStatsRequest() { }
-};
-
-} // namespace WebCore
-
-#endif // RTCStatsRequest_h
diff --git a/chromium/third_party/WebKit/Source/core/platform/mock/GeolocationClientMock.cpp b/chromium/third_party/WebKit/Source/core/platform/mock/GeolocationClientMock.cpp
deleted file mode 100644
index 8b0be679be4..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mock/GeolocationClientMock.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2012 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/platform/mock/GeolocationClientMock.h"
-
-#include "modules/geolocation/GeolocationController.h"
-#include "modules/geolocation/GeolocationError.h"
-#include "modules/geolocation/GeolocationPosition.h"
-
-namespace WebCore {
-
-GeolocationClientMock::GeolocationClientMock()
- : m_controller(0)
- , m_hasError(false)
- , m_controllerTimer(this, &GeolocationClientMock::controllerTimerFired)
- , m_permissionTimer(this, &GeolocationClientMock::permissionTimerFired)
- , m_isActive(false)
- , m_permissionState(PermissionStateUnset)
-{
-}
-
-GeolocationClientMock::~GeolocationClientMock()
-{
- ASSERT(!m_isActive);
-}
-
-void GeolocationClientMock::setController(GeolocationController *controller)
-{
- ASSERT(controller && !m_controller);
- m_controller = controller;
-}
-
-void GeolocationClientMock::setPosition(PassRefPtr<GeolocationPosition> position)
-{
- m_lastPosition = position;
- clearError();
- asyncUpdateController();
-}
-
-void GeolocationClientMock::setPositionUnavailableError(const String& errorMessage)
-{
- m_hasError = true;
- m_errorMessage = errorMessage;
- m_lastPosition = nullptr;
- asyncUpdateController();
-}
-
-void GeolocationClientMock::setPermission(bool allowed)
-{
- m_permissionState = allowed ? PermissionStateAllowed : PermissionStateDenied;
- asyncUpdatePermission();
-}
-
-int GeolocationClientMock::numberOfPendingPermissionRequests() const
-{
- return m_pendingPermission.size();
-}
-
-void GeolocationClientMock::requestPermission(Geolocation* geolocation)
-{
- m_pendingPermission.add(geolocation);
- if (m_permissionState != PermissionStateUnset)
- asyncUpdatePermission();
-}
-
-void GeolocationClientMock::cancelPermissionRequest(Geolocation* geolocation)
-{
- // Called from Geolocation::disconnectFrame() in response to Frame destruction.
- m_pendingPermission.remove(geolocation);
- if (m_pendingPermission.isEmpty() && m_permissionTimer.isActive())
- m_permissionTimer.stop();
-}
-
-void GeolocationClientMock::asyncUpdatePermission()
-{
- ASSERT(m_permissionState != PermissionStateUnset);
- if (!m_permissionTimer.isActive())
- m_permissionTimer.startOneShot(0);
-}
-
-void GeolocationClientMock::permissionTimerFired(WebCore::Timer<GeolocationClientMock>* timer)
-{
- ASSERT_UNUSED(timer, timer == &m_permissionTimer);
- ASSERT(m_permissionState != PermissionStateUnset);
- bool allowed = m_permissionState == PermissionStateAllowed;
- GeolocationSet::iterator end = m_pendingPermission.end();
-
- // Once permission has been set (or denied) on a Geolocation object, there can be
- // no further requests for permission to the mock. Consequently the callbacks
- // which fire synchronously from Geolocation::setIsAllowed() cannot reentrantly modify
- // m_pendingPermission.
- for (GeolocationSet::iterator it = m_pendingPermission.begin(); it != end; ++it)
- (*it)->setIsAllowed(allowed);
- m_pendingPermission.clear();
-}
-
-void GeolocationClientMock::reset()
-{
- m_lastPosition = 0;
- clearError();
- m_permissionState = PermissionStateUnset;
-}
-
-void GeolocationClientMock::geolocationDestroyed()
-{
- ASSERT(!m_isActive);
-}
-
-void GeolocationClientMock::startUpdating()
-{
- ASSERT(!m_isActive);
- m_isActive = true;
- asyncUpdateController();
-}
-
-void GeolocationClientMock::stopUpdating()
-{
- ASSERT(m_isActive);
- m_isActive = false;
- m_controllerTimer.stop();
-}
-
-void GeolocationClientMock::setEnableHighAccuracy(bool)
-{
- // FIXME: We need to add some tests regarding "high accuracy" mode.
- // See https://bugs.webkit.org/show_bug.cgi?id=49438
-}
-
-GeolocationPosition* GeolocationClientMock::lastPosition()
-{
- return m_lastPosition.get();
-}
-
-void GeolocationClientMock::asyncUpdateController()
-{
- ASSERT(m_controller);
- if (m_isActive && !m_controllerTimer.isActive())
- m_controllerTimer.startOneShot(0);
-}
-
-void GeolocationClientMock::controllerTimerFired(Timer<GeolocationClientMock>* timer)
-{
- ASSERT_UNUSED(timer, timer == &m_controllerTimer);
- ASSERT(m_controller);
-
- if (m_lastPosition.get()) {
- ASSERT(!m_hasError);
- m_controller->positionChanged(m_lastPosition.get());
- } else if (m_hasError) {
- RefPtr<GeolocationError> geolocatioError = GeolocationError::create(GeolocationError::PositionUnavailable, m_errorMessage);
- m_controller->errorOccurred(geolocatioError.get());
- }
-}
-
-void GeolocationClientMock::clearError()
-{
- m_hasError = false;
- m_errorMessage = String();
-}
-
-} // WebCore
diff --git a/chromium/third_party/WebKit/Source/core/platform/mock/GeolocationClientMock.h b/chromium/third_party/WebKit/Source/core/platform/mock/GeolocationClientMock.h
deleted file mode 100644
index 884184d7741..00000000000
--- a/chromium/third_party/WebKit/Source/core/platform/mock/GeolocationClientMock.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- * Copyright (C) 2012 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef GeolocationClientMock_h
-#define GeolocationClientMock_h
-
-#include "modules/geolocation/GeolocationClient.h"
-#include "platform/Timer.h"
-#include "wtf/HashSet.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class GeolocationController;
-class GeolocationPosition;
-
-// FIXME: this should not be in WebCore. It should be moved to WebKit.
-// Provides a mock object for the geolocation client.
-class GeolocationClientMock : public GeolocationClient {
-public:
- GeolocationClientMock();
- virtual ~GeolocationClientMock();
-
- void reset();
- void setController(GeolocationController*);
-
- void setPosition(PassRefPtr<GeolocationPosition>);
- void setPositionUnavailableError(const String& errorMessage);
- void setPermission(bool allowed);
- int numberOfPendingPermissionRequests() const;
-
- // GeolocationClient
- virtual void geolocationDestroyed() OVERRIDE;
- virtual void startUpdating() OVERRIDE;
- virtual void stopUpdating() OVERRIDE;
- virtual void setEnableHighAccuracy(bool) OVERRIDE;
- virtual GeolocationPosition* lastPosition() OVERRIDE;
- virtual void requestPermission(Geolocation*) OVERRIDE;
- virtual void cancelPermissionRequest(Geolocation*) OVERRIDE;
-
-private:
- void asyncUpdateController();
- void controllerTimerFired(Timer<GeolocationClientMock>*);
-
- void asyncUpdatePermission();
- void permissionTimerFired(Timer<GeolocationClientMock>*);
-
- void clearError();
-
- GeolocationController* m_controller;
- RefPtr<GeolocationPosition> m_lastPosition;
- bool m_hasError;
- String m_errorMessage;
- Timer<GeolocationClientMock> m_controllerTimer;
- Timer<GeolocationClientMock> m_permissionTimer;
- bool m_isActive;
-
- enum PermissionState {
- PermissionStateUnset,
- PermissionStateAllowed,
- PermissionStateDenied,
- } m_permissionState;
- typedef WTF::HashSet<RefPtr<Geolocation> > GeolocationSet;
- GeolocationSet m_pendingPermission;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.cpp b/chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.cpp
index ecd812a262e..9ff14bd242d 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.cpp
+++ b/chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.cpp
@@ -19,15 +19,15 @@
#include "config.h"
#include "core/plugins/DOMMimeType.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/plugins/DOMPlugin.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
-DOMMimeType::DOMMimeType(PassRefPtr<PluginData> pluginData, Frame* frame, unsigned index)
+DOMMimeType::DOMMimeType(PassRefPtr<PluginData> pluginData, LocalFrame* frame, unsigned index)
: FrameDestructionObserver(frame)
, m_pluginData(pluginData)
, m_index(index)
@@ -62,13 +62,13 @@ const String &DOMMimeType::description() const
return mimeClassInfo().desc;
}
-PassRefPtr<DOMPlugin> DOMMimeType::enabledPlugin() const
+PassRefPtrWillBeRawPtr<DOMPlugin> DOMMimeType::enabledPlugin() const
{
// FIXME: allowPlugins is just a client call. We should not need
- // to bounce through the page or mainframe or loader to get there.
+ // to bounce through the loader to get there.
// Something like: m_frame->host()->client()->allowPlugins().
- if (!m_frame || !m_frame->page() || !m_frame->page()->mainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
- return 0;
+ if (!m_frame || !m_frame->loader().allowPlugins(NotAboutToInstantiatePlugin))
+ return nullptr;
return DOMPlugin::create(m_pluginData.get(), m_frame, m_pluginData->mimePluginIndices()[m_index]);
}
diff --git a/chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.h b/chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.h
index 8670725b717..3f7d2fa7fdc 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.h
+++ b/chromium/third_party/WebKit/Source/core/plugins/DOMMimeType.h
@@ -22,6 +22,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/FrameDestructionObserver.h"
+#include "platform/heap/Handle.h"
#include "platform/plugins/PluginData.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
@@ -31,22 +32,27 @@
namespace WebCore {
class DOMPlugin;
-class Frame;
+class LocalFrame;
-class DOMMimeType : public RefCounted<DOMMimeType>, public ScriptWrappable, public FrameDestructionObserver {
+class DOMMimeType FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMMimeType>, public ScriptWrappable, public FrameDestructionObserver {
public:
- static PassRefPtr<DOMMimeType> create(PassRefPtr<PluginData> pluginData, Frame* frame, unsigned index) { return adoptRef(new DOMMimeType(pluginData, frame, index)); }
- ~DOMMimeType();
+ static PassRefPtrWillBeRawPtr<DOMMimeType> create(PassRefPtr<PluginData> pluginData, LocalFrame* frame, unsigned index)
+ {
+ return adoptRefWillBeNoop(new DOMMimeType(pluginData, frame, index));
+ }
+ virtual ~DOMMimeType();
- const String &type() const;
+ const String& type() const;
String suffixes() const;
- const String &description() const;
- PassRefPtr<DOMPlugin> enabledPlugin() const;
+ const String& description() const;
+ PassRefPtrWillBeRawPtr<DOMPlugin> enabledPlugin() const;
+
+ void trace(Visitor*) { }
private:
const MimeClassInfo& mimeClassInfo() const { return m_pluginData->mimes()[m_index]; }
- DOMMimeType(PassRefPtr<PluginData>, Frame*, unsigned index);
+ DOMMimeType(PassRefPtr<PluginData>, LocalFrame*, unsigned index);
RefPtr<PluginData> m_pluginData;
unsigned m_index;
};
diff --git a/chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.cpp b/chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.cpp
index cddfa8326e2..23e7085b644 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.cpp
+++ b/chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.cpp
@@ -20,14 +20,14 @@
#include "config.h"
#include "core/plugins/DOMMimeTypeArray.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/Page.h"
#include "platform/plugins/PluginData.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
-DOMMimeTypeArray::DOMMimeTypeArray(Frame* frame)
+DOMMimeTypeArray::DOMMimeTypeArray(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
@@ -45,14 +45,14 @@ unsigned DOMMimeTypeArray::length() const
return data->mimes().size();
}
-PassRefPtr<DOMMimeType> DOMMimeTypeArray::item(unsigned index)
+PassRefPtrWillBeRawPtr<DOMMimeType> DOMMimeTypeArray::item(unsigned index)
{
PluginData* data = getPluginData();
if (!data)
- return 0;
+ return nullptr;
const Vector<MimeClassInfo>& mimes = data->mimes();
if (index >= mimes.size())
- return 0;
+ return nullptr;
return DOMMimeType::create(data, m_frame, index).get();
}
@@ -69,17 +69,17 @@ bool DOMMimeTypeArray::canGetItemsForName(const AtomicString& propertyName)
return false;
}
-PassRefPtr<DOMMimeType> DOMMimeTypeArray::namedItem(const AtomicString& propertyName)
+PassRefPtrWillBeRawPtr<DOMMimeType> DOMMimeTypeArray::namedItem(const AtomicString& propertyName)
{
PluginData *data = getPluginData();
if (!data)
- return 0;
+ return nullptr;
const Vector<MimeClassInfo>& mimes = data->mimes();
for (unsigned i = 0; i < mimes.size(); ++i) {
if (mimes[i].type == propertyName)
return DOMMimeType::create(data, m_frame, i).get();
}
- return 0;
+ return nullptr;
}
PluginData* DOMMimeTypeArray::getPluginData() const
diff --git a/chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.h b/chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.h
index 651edee0892..3bb52ea8214 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.h
+++ b/chromium/third_party/WebKit/Source/core/plugins/DOMMimeTypeArray.h
@@ -24,6 +24,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/DOMWindowProperty.h"
#include "core/plugins/DOMMimeType.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -31,21 +32,26 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class PluginData;
-class DOMMimeTypeArray : public ScriptWrappable, public RefCounted<DOMMimeTypeArray>, public DOMWindowProperty {
+class DOMMimeTypeArray FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMMimeTypeArray>, public ScriptWrappable, public DOMWindowProperty {
public:
- static PassRefPtr<DOMMimeTypeArray> create(Frame* frame) { return adoptRef(new DOMMimeTypeArray(frame)); }
- ~DOMMimeTypeArray();
+ static PassRefPtrWillBeRawPtr<DOMMimeTypeArray> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new DOMMimeTypeArray(frame));
+ }
+ virtual ~DOMMimeTypeArray();
unsigned length() const;
- PassRefPtr<DOMMimeType> item(unsigned index);
+ PassRefPtrWillBeRawPtr<DOMMimeType> item(unsigned index);
bool canGetItemsForName(const AtomicString& propertyName);
- PassRefPtr<DOMMimeType> namedItem(const AtomicString& propertyName);
+ PassRefPtrWillBeRawPtr<DOMMimeType> namedItem(const AtomicString& propertyName);
+
+ void trace(Visitor*) { }
private:
- explicit DOMMimeTypeArray(Frame*);
+ explicit DOMMimeTypeArray(LocalFrame*);
PluginData* getPluginData() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.cpp b/chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.cpp
index eb4b99c94e6..03fff43dbbd 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.cpp
+++ b/chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.cpp
@@ -24,7 +24,7 @@
namespace WebCore {
-DOMPlugin::DOMPlugin(PluginData* pluginData, Frame* frame, unsigned index)
+DOMPlugin::DOMPlugin(PluginData* pluginData, LocalFrame* frame, unsigned index)
: FrameDestructionObserver(frame)
, m_pluginData(pluginData)
, m_index(index)
@@ -56,10 +56,10 @@ unsigned DOMPlugin::length() const
return pluginInfo().mimes.size();
}
-PassRefPtr<DOMMimeType> DOMPlugin::item(unsigned index)
+PassRefPtrWillBeRawPtr<DOMMimeType> DOMPlugin::item(unsigned index)
{
if (index >= pluginInfo().mimes.size())
- return 0;
+ return nullptr;
const MimeClassInfo& mime = pluginInfo().mimes[index];
@@ -68,7 +68,7 @@ PassRefPtr<DOMMimeType> DOMPlugin::item(unsigned index)
if (mimes[i] == mime && m_pluginData->mimePluginIndices()[i] == m_index)
return DOMMimeType::create(m_pluginData.get(), m_frame, i).get();
}
- return 0;
+ return nullptr;
}
bool DOMPlugin::canGetItemsForName(const AtomicString& propertyName)
@@ -80,13 +80,13 @@ bool DOMPlugin::canGetItemsForName(const AtomicString& propertyName)
return false;
}
-PassRefPtr<DOMMimeType> DOMPlugin::namedItem(const AtomicString& propertyName)
+PassRefPtrWillBeRawPtr<DOMMimeType> DOMPlugin::namedItem(const AtomicString& propertyName)
{
const Vector<MimeClassInfo>& mimes = m_pluginData->mimes();
for (unsigned i = 0; i < mimes.size(); ++i)
if (mimes[i].type == propertyName)
return DOMMimeType::create(m_pluginData.get(), m_frame, i).get();
- return 0;
+ return nullptr;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.h b/chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.h
index 1cc0611a180..edb80e5de0f 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.h
+++ b/chromium/third_party/WebKit/Source/core/plugins/DOMPlugin.h
@@ -23,6 +23,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/FrameDestructionObserver.h"
#include "core/plugins/DOMMimeType.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -32,10 +33,13 @@ namespace WebCore {
class Plugin;
class PluginData;
-class DOMPlugin : public ScriptWrappable, public RefCounted<DOMPlugin>, public FrameDestructionObserver {
+class DOMPlugin FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMPlugin>, public ScriptWrappable, public FrameDestructionObserver {
public:
- static PassRefPtr<DOMPlugin> create(PluginData* pluginData, Frame* frame, unsigned index) { return adoptRef(new DOMPlugin(pluginData, frame, index)); }
- ~DOMPlugin();
+ static PassRefPtrWillBeRawPtr<DOMPlugin> create(PluginData* pluginData, LocalFrame* frame, unsigned index)
+ {
+ return adoptRefWillBeNoop(new DOMPlugin(pluginData, frame, index));
+ }
+ virtual ~DOMPlugin();
String name() const;
String filename() const;
@@ -43,14 +47,16 @@ public:
unsigned length() const;
- PassRefPtr<DOMMimeType> item(unsigned index);
+ PassRefPtrWillBeRawPtr<DOMMimeType> item(unsigned index);
bool canGetItemsForName(const AtomicString& propertyName);
- PassRefPtr<DOMMimeType> namedItem(const AtomicString& propertyName);
+ PassRefPtrWillBeRawPtr<DOMMimeType> namedItem(const AtomicString& propertyName);
+
+ void trace(Visitor*) { }
private:
const PluginInfo& pluginInfo() const { return m_pluginData->plugins()[m_index]; }
- DOMPlugin(PluginData*, Frame*, unsigned index);
+ DOMPlugin(PluginData*, LocalFrame*, unsigned index);
RefPtr<PluginData> m_pluginData;
unsigned m_index;
};
diff --git a/chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.cpp b/chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.cpp
index bb2b1695b13..997513177ab 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.cpp
+++ b/chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.cpp
@@ -20,14 +20,14 @@
#include "config.h"
#include "core/plugins/DOMPluginArray.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/Page.h"
#include "platform/plugins/PluginData.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
-DOMPluginArray::DOMPluginArray(Frame* frame)
+DOMPluginArray::DOMPluginArray(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
@@ -45,14 +45,14 @@ unsigned DOMPluginArray::length() const
return data->plugins().size();
}
-PassRefPtr<DOMPlugin> DOMPluginArray::item(unsigned index)
+PassRefPtrWillBeRawPtr<DOMPlugin> DOMPluginArray::item(unsigned index)
{
PluginData* data = pluginData();
if (!data)
- return 0;
+ return nullptr;
const Vector<PluginInfo>& plugins = data->plugins();
if (index >= plugins.size())
- return 0;
+ return nullptr;
return DOMPlugin::create(data, m_frame, index).get();
}
@@ -69,17 +69,17 @@ bool DOMPluginArray::canGetItemsForName(const AtomicString& propertyName)
return false;
}
-PassRefPtr<DOMPlugin> DOMPluginArray::namedItem(const AtomicString& propertyName)
+PassRefPtrWillBeRawPtr<DOMPlugin> DOMPluginArray::namedItem(const AtomicString& propertyName)
{
PluginData* data = pluginData();
if (!data)
- return 0;
+ return nullptr;
const Vector<PluginInfo>& plugins = data->plugins();
for (unsigned i = 0; i < plugins.size(); ++i) {
if (plugins[i].name == propertyName)
return DOMPlugin::create(data, m_frame, i).get();
}
- return 0;
+ return nullptr;
}
void DOMPluginArray::refresh(bool reload)
diff --git a/chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.h b/chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.h
index 922b777d925..be5196e5c5d 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.h
+++ b/chromium/third_party/WebKit/Source/core/plugins/DOMPluginArray.h
@@ -24,6 +24,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/DOMWindowProperty.h"
#include "core/plugins/DOMPlugin.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -31,23 +32,28 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class PluginData;
-class DOMPluginArray : public ScriptWrappable, public RefCounted<DOMPluginArray>, public DOMWindowProperty {
+class DOMPluginArray FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMPluginArray>, public ScriptWrappable, public DOMWindowProperty {
public:
- static PassRefPtr<DOMPluginArray> create(Frame* frame) { return adoptRef(new DOMPluginArray(frame)); }
- ~DOMPluginArray();
+ static PassRefPtrWillBeRawPtr<DOMPluginArray> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new DOMPluginArray(frame));
+ }
+ virtual ~DOMPluginArray();
unsigned length() const;
- PassRefPtr<DOMPlugin> item(unsigned index);
+ PassRefPtrWillBeRawPtr<DOMPlugin> item(unsigned index);
bool canGetItemsForName(const AtomicString& propertyName);
- PassRefPtr<DOMPlugin> namedItem(const AtomicString& propertyName);
+ PassRefPtrWillBeRawPtr<DOMPlugin> namedItem(const AtomicString& propertyName);
void refresh(bool reload);
+ void trace(Visitor*) { }
+
private:
- explicit DOMPluginArray(Frame*);
+ explicit DOMPluginArray(LocalFrame*);
PluginData* pluginData() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/plugins/MimeType.idl b/chromium/third_party/WebKit/Source/core/plugins/MimeType.idl
index 7af6fc1416d..26c6cc40fae 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/MimeType.idl
+++ b/chromium/third_party/WebKit/Source/core/plugins/MimeType.idl
@@ -19,6 +19,7 @@
*/
[
+ WillBeGarbageCollected,
ImplementedAs=DOMMimeType
] interface MimeType {
readonly attribute DOMString type;
diff --git a/chromium/third_party/WebKit/Source/core/plugins/MimeTypeArray.idl b/chromium/third_party/WebKit/Source/core/plugins/MimeTypeArray.idl
index ea11b6b5da3..0a33adace1f 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/MimeTypeArray.idl
+++ b/chromium/third_party/WebKit/Source/core/plugins/MimeTypeArray.idl
@@ -19,11 +19,12 @@
*/
[
+ WillBeGarbageCollected,
ImplementedAs=DOMMimeTypeArray
] interface MimeTypeArray {
readonly attribute unsigned long length;
getter MimeType item([Default=Undefined] optional unsigned long index);
MimeType namedItem([Default=Undefined] optional DOMString name);
- [NotEnumerable, ImplementedAs=namedItem] getter MimeType([Default=Undefined] optional DOMString name);
+ [NotEnumerable, ImplementedAs=namedItem] getter MimeType ([Default=Undefined] optional DOMString name);
};
diff --git a/chromium/third_party/WebKit/Source/core/plugins/Plugin.idl b/chromium/third_party/WebKit/Source/core/plugins/Plugin.idl
index c1259e15f07..689df505e60 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/Plugin.idl
+++ b/chromium/third_party/WebKit/Source/core/plugins/Plugin.idl
@@ -19,6 +19,7 @@
*/
[
+ WillBeGarbageCollected,
ImplementedAs=DOMPlugin
] interface Plugin {
readonly attribute DOMString name;
diff --git a/chromium/third_party/WebKit/Source/core/plugins/PluginArray.idl b/chromium/third_party/WebKit/Source/core/plugins/PluginArray.idl
index 47d9cc2d09a..dc2ab1d31a4 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/PluginArray.idl
+++ b/chromium/third_party/WebKit/Source/core/plugins/PluginArray.idl
@@ -19,6 +19,7 @@
*/
[
+ WillBeGarbageCollected,
ImplementedAs=DOMPluginArray
] interface PluginArray {
readonly attribute unsigned long length;
diff --git a/chromium/third_party/WebKit/Source/core/plugins/PluginOcclusionSupport.cpp b/chromium/third_party/WebKit/Source/core/plugins/PluginOcclusionSupport.cpp
index 3fab5dcda31..22a4169b548 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/PluginOcclusionSupport.cpp
+++ b/chromium/third_party/WebKit/Source/core/plugins/PluginOcclusionSupport.cpp
@@ -31,12 +31,12 @@
#include "config.h"
#include "core/plugins/PluginOcclusionSupport.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/rendering/RenderBox.h"
#include "core/rendering/RenderObject.h"
#include "platform/Widget.h"
@@ -100,7 +100,7 @@ static bool iframeIsAbovePlugin(const Vector<const RenderObject*>& iframeZstack,
return false;
ASSERT(parent == ro2->parent());
- for (const RenderObject* ro = parent->firstChild(); ro; ro = ro->nextSibling()) {
+ for (const RenderObject* ro = parent->slowFirstChild(); ro; ro = ro->nextSibling()) {
if (ro == ro1)
return false;
if (ro == ro2)
@@ -132,7 +132,7 @@ static void addTreeToOcclusions(const RenderObject* renderer, const IntRect& fra
return;
if (renderer->isBox() && intersectsRect(renderer, frameRect))
addToOcclusions(toRenderBox(renderer), occlusions);
- for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling())
+ for (RenderObject* child = renderer->slowFirstChild(); child; child = child->nextSibling())
addTreeToOcclusions(child, frameRect, occlusions);
}
@@ -173,13 +173,14 @@ void getPluginOcclusions(Element* element, Widget* parentWidget, const IntRect&
const FrameView* frameView = toFrameView((*it).get());
// Check to make sure we can get both the element and the RenderObject
// for this FrameView, if we can't just move on to the next object.
- HTMLElement* element = frameView->frame().ownerElement();
+ // FIXME: Plugin occlusion by remote frames is probably broken.
+ HTMLElement* element = frameView->frame().deprecatedLocalOwner();
if (!element || !element->renderer())
continue;
RenderObject* iframeRenderer = element->renderer();
- if (element->hasTagName(HTMLNames::iframeTag) && intersectsRect(iframeRenderer, frameRect)) {
+ if (isHTMLIFrameElement(*element) && intersectsRect(iframeRenderer, frameRect)) {
getObjectStack(iframeRenderer, &iframeZstack);
if (iframeIsAbovePlugin(iframeZstack, pluginZstack))
addToOcclusions(toRenderBox(iframeRenderer), occlusions);
@@ -193,7 +194,7 @@ void getPluginOcclusions(Element* element, Widget* parentWidget, const IntRect&
// as being in the top layer.
const Element* ancestor = topLayerAncestor(element);
Document* document = parentFrameView->frame().document();
- const Vector<RefPtr<Element> >& elements = document->topLayerElements();
+ const WillBeHeapVector<RefPtrWillBeMember<Element> >& elements = document->topLayerElements();
size_t start = ancestor ? elements.find(ancestor) + 1 : 0;
for (size_t i = start; i < elements.size(); ++i)
addTreeToOcclusions(elements[i]->renderer(), frameRect, occlusions);
diff --git a/chromium/third_party/WebKit/Source/core/plugins/PluginView.h b/chromium/third_party/WebKit/Source/core/plugins/PluginView.h
index 14938bdb907..7020f42cdd2 100644
--- a/chromium/third_party/WebKit/Source/core/plugins/PluginView.h
+++ b/chromium/third_party/WebKit/Source/core/plugins/PluginView.h
@@ -42,7 +42,7 @@ class Scrollbar;
class PluginView : public Widget {
public:
- virtual bool isPluginView() const { return true; }
+ virtual bool isPluginView() const OVERRIDE FINAL { return true; }
virtual blink::WebLayer* platformLayer() const { return 0; }
virtual NPObject* scriptableObject() { return 0; }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp
index a14b4a0e876..82c182e1d9c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp
@@ -41,7 +41,7 @@ AbstractInlineTextBox::InlineToAbstractInlineTextBoxHashMap* AbstractInlineTextB
PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::getOrCreate(RenderText* renderText, InlineTextBox* inlineTextBox)
{
if (!inlineTextBox)
- return 0;
+ return nullptr;
if (!gAbstractInlineTextBoxMap)
gAbstractInlineTextBoxMap = new InlineToAbstractInlineTextBoxHashMap();
@@ -76,7 +76,7 @@ void AbstractInlineTextBox::detach()
PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::nextInlineTextBox() const
{
if (!m_inlineTextBox)
- return 0;
+ return nullptr;
return getOrCreate(m_renderText, m_inlineTextBox->nextTextBox());
}
@@ -149,7 +149,7 @@ String AbstractInlineTextBox::text() const
unsigned start = m_inlineTextBox->start();
unsigned len = m_inlineTextBox->len();
if (Node* node = m_renderText->node()) {
- RefPtr<Range> range = Range::create(node->document());
+ RefPtrWillBeRawPtr<Range> range = Range::create(node->document());
range->setStart(node, start, IGNORE_EXCEPTION);
range->setEnd(node, start + len, IGNORE_EXCEPTION);
return plainText(range.get(), TextIteratorIgnoresStyleVisibility);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp b/chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp
index 2c290c68fb1..eec5a0cd9f6 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "core/rendering/AutoTableLayout.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/RenderTable.h"
#include "core/rendering/RenderTableCell.h"
#include "core/rendering/RenderTableCol.h"
@@ -65,7 +66,7 @@ void AutoTableLayout::recalcColumn(unsigned effCol)
if (current.inColSpan || !cell)
continue;
- bool cellHasContent = cell->children()->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding();
+ bool cellHasContent = cell->children()->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding() || cell->style()->hasBackground();
if (cellHasContent)
columnLayout.emptyCellsOnly = false;
@@ -207,6 +208,8 @@ static bool shouldScaleColumns(RenderTable* table)
void AutoTableLayout::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth)
{
+ FastTextAutosizer::TableLayoutScope fastTextAutosizerTableLayoutScope(m_table);
+
fullRecalc();
int spanMaxLogicalWidth = calcEffectiveLogicalWidth();
@@ -247,8 +250,22 @@ void AutoTableLayout::computeIntrinsicLogicalWidths(LayoutUnit& minWidth, Layout
void AutoTableLayout::applyPreferredLogicalWidthQuirks(LayoutUnit& minWidth, LayoutUnit& maxWidth) const
{
Length tableLogicalWidth = m_table->style()->logicalWidth();
- if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive())
+ if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) {
+ // |minWidth| is the result of measuring the intrinsic content's size. Keep it to
+ // make sure we are *never* smaller than the actual content.
+ LayoutUnit minContentWidth = minWidth;
+ // FIXME: This line looks REALLY suspicious as it could allow the minimum
+ // preferred logical width to be smaller than the table content. This has
+ // to be cross-checked against other browsers.
minWidth = maxWidth = max<int>(minWidth, tableLogicalWidth.value());
+
+ const Length& styleMaxLogicalWidth = m_table->style()->logicalMaxWidth();
+ if (styleMaxLogicalWidth.isFixed() && !styleMaxLogicalWidth.isNegative()) {
+ minWidth = min<int>(minWidth, styleMaxLogicalWidth.value());
+ minWidth = max(minWidth, minContentWidth);
+ maxWidth = minWidth;
+ }
+ }
}
/*
diff --git a/chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.h b/chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.h
index dfdd985d842..9336d0f15a5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/AutoTableLayout.h
@@ -34,7 +34,7 @@ class RenderTableCell;
class AutoTableLayout FINAL : public TableLayout {
public:
AutoTableLayout(RenderTable*);
- ~AutoTableLayout();
+ virtual ~AutoTableLayout();
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth) OVERRIDE;
virtual void applyPreferredLogicalWidthQuirks(LayoutUnit& minWidth, LayoutUnit& maxWidth) const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/BidiRun.cpp b/chromium/third_party/WebKit/Source/core/rendering/BidiRun.cpp
deleted file mode 100644
index 4af7881a87e..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/BidiRun.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-#include "core/rendering/BidiRun.h"
-#include "platform/Partitions.h"
-#include "wtf/RefCountedLeakCounter.h"
-
-using namespace WTF;
-
-namespace WebCore {
-
-DEFINE_DEBUG_ONLY_GLOBAL(RefCountedLeakCounter, bidiRunCounter, ("BidiRun"));
-
-void* BidiRun::operator new(size_t sz)
-{
-#ifndef NDEBUG
- bidiRunCounter.increment();
-#endif
- return partitionAlloc(Partitions::getRenderingPartition(), sz);
-}
-
-void BidiRun::operator delete(void* ptr)
-{
-#ifndef NDEBUG
- bidiRunCounter.decrement();
-#endif
- partitionFree(ptr);
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/BidiRun.h b/chromium/third_party/WebKit/Source/core/rendering/BidiRun.h
index 85f8f4a1a1c..cd743385c06 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/BidiRun.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/BidiRun.h
@@ -41,13 +41,8 @@ struct BidiRun : BidiCharacterRun {
{
// Stored in base class to save space.
m_hasHyphen = false;
- m_startsSegment = false;
}
- // BidiRuns are allocated out of the rendering partition.
- void* operator new(size_t);
- void operator delete(void*);
-
BidiRun* next() { return static_cast<BidiRun*>(m_next); }
RenderObject* object() { return m_object; }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ClipPathOperation.h b/chromium/third_party/WebKit/Source/core/rendering/ClipPathOperation.h
index 7d50a10e4fd..bf64113d848 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/ClipPathOperation.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/ClipPathOperation.h
@@ -63,15 +63,15 @@ protected:
OperationType m_type;
};
-class ReferenceClipPathOperation : public ClipPathOperation {
+class ReferenceClipPathOperation FINAL : public ClipPathOperation {
public:
- static PassRefPtr<ReferenceClipPathOperation> create(const String& url, const String& fragment)
+ static PassRefPtr<ReferenceClipPathOperation> create(const String& url, const AtomicString& fragment)
{
return adoptRef(new ReferenceClipPathOperation(url, fragment));
}
const String& url() const { return m_url; }
- const String& fragment() const { return m_fragment; }
+ const AtomicString& fragment() const { return m_fragment; }
private:
virtual bool operator==(const ClipPathOperation& o) const OVERRIDE
@@ -79,7 +79,7 @@ private:
return isSameType(o) && m_url == static_cast<const ReferenceClipPathOperation&>(o).m_url;
}
- ReferenceClipPathOperation(const String& url, const String& fragment)
+ ReferenceClipPathOperation(const String& url, const AtomicString& fragment)
: ClipPathOperation(REFERENCE)
, m_url(url)
, m_fragment(fragment)
@@ -87,12 +87,12 @@ private:
}
String m_url;
- String m_fragment;
+ AtomicString m_fragment;
};
DEFINE_TYPE_CASTS(ReferenceClipPathOperation, ClipPathOperation, op, op->type() == ClipPathOperation::REFERENCE, op.type() == ClipPathOperation::REFERENCE);
-class ShapeClipPathOperation : public ClipPathOperation {
+class ShapeClipPathOperation FINAL : public ClipPathOperation {
public:
static PassRefPtr<ShapeClipPathOperation> create(PassRefPtr<BasicShape> shape)
{
@@ -111,10 +111,7 @@ public:
}
private:
- virtual bool operator==(const ClipPathOperation& o) const OVERRIDE
- {
- return isSameType(o) && m_shape == static_cast<const ShapeClipPathOperation&>(o).m_shape;
- }
+ virtual bool operator==(const ClipPathOperation&) const OVERRIDE;
ShapeClipPathOperation(PassRefPtr<BasicShape> shape)
: ClipPathOperation(SHAPE)
@@ -128,6 +125,11 @@ private:
DEFINE_TYPE_CASTS(ShapeClipPathOperation, ClipPathOperation, op, op->type() == ClipPathOperation::SHAPE, op.type() == ClipPathOperation::SHAPE);
+inline bool ShapeClipPathOperation::operator==(const ClipPathOperation& o) const
+{
+ return isSameType(o) && *m_shape == *toShapeClipPathOperation(o).m_shape;
+}
+
}
#endif // ClipPathOperation_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ClipRect.h b/chromium/third_party/WebKit/Source/core/rendering/ClipRect.h
index 8fbcebf90a6..b0bed95bb77 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/ClipRect.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/ClipRect.h
@@ -179,6 +179,7 @@ private:
enum ClipRectsType {
PaintingClipRects, // Relative to painting ancestor. Used for painting.
RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing.
+ CompositingClipRects, // Relative to the compositing ancestor. Used for updating graphics layer geometry.
AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing.
NumCachedClipRectsTypes,
AllClipRectTypes,
@@ -195,19 +196,24 @@ struct ClipRectsCache {
public:
ClipRectsCache()
{
-#ifndef NDEBUG
for (int i = 0; i < NumCachedClipRectsTypes; ++i) {
m_clipRectsRoot[i] = 0;
+#ifndef NDEBUG
m_scrollbarRelevancy[i] = IgnoreOverlayScrollbarSize;
- }
#endif
+ }
}
PassRefPtr<ClipRects> getClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow) { return m_clipRects[getIndex(clipRectsType, respectOverflow)]; }
- void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, PassRefPtr<ClipRects> clipRects) { m_clipRects[getIndex(clipRectsType, respectOverflow)] = clipRects; }
+ void setClipRects(ClipRectsType clipRectsType, ShouldRespectOverflowClip respectOverflow, PassRefPtr<ClipRects> clipRects, const RenderLayer* root)
+ {
+ m_clipRects[getIndex(clipRectsType, respectOverflow)] = clipRects;
+ m_clipRectsRoot[clipRectsType] = root;
+ }
+
+ const RenderLayer* clipRectsRoot(ClipRectsType clipRectsType) const { return m_clipRectsRoot[clipRectsType]; }
#ifndef NDEBUG
- const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
OverlayScrollbarSizeRelevancy m_scrollbarRelevancy[NumCachedClipRectsTypes];
#endif
@@ -220,6 +226,7 @@ private:
return index;
}
+ const RenderLayer* m_clipRectsRoot[NumCachedClipRectsTypes];
RefPtr<ClipRects> m_clipRects[NumCachedClipRectsTypes * 2];
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ColumnInfo.h b/chromium/third_party/WebKit/Source/core/rendering/ColumnInfo.h
index 39722819249..ddad54e1593 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/ColumnInfo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/ColumnInfo.h
@@ -38,14 +38,12 @@ public:
: m_desiredColumnWidth(0)
, m_desiredColumnCount(1)
, m_progressionAxis(InlineAxis)
- , m_progressionIsReversed(false)
, m_columnCount(1)
, m_columnHeight(0)
, m_minimumColumnHeight(0)
, m_forcedBreaks(0)
, m_maximumDistanceBetweenForcedBreaks(0)
, m_forcedBreakOffset(0)
- , m_paginationUnit(Column)
{
}
@@ -60,9 +58,6 @@ public:
Axis progressionAxis() const { return m_progressionAxis; }
void setProgressionAxis(Axis progressionAxis) { m_progressionAxis = progressionAxis; }
- bool progressionIsReversed() const { return m_progressionIsReversed; }
- void setProgressionIsReversed(bool reversed) { m_progressionIsReversed = reversed; }
-
unsigned columnCount() const { return m_columnCount; }
LayoutUnit columnHeight() const { return m_columnHeight; }
@@ -98,15 +93,10 @@ public:
m_forcedBreakOffset = offsetFromFirstPage;
}
- enum PaginationUnit { Column, Page };
- PaginationUnit paginationUnit() const { return m_paginationUnit; }
- void setPaginationUnit(PaginationUnit paginationUnit) { m_paginationUnit = paginationUnit; }
-
private:
LayoutUnit m_desiredColumnWidth;
unsigned m_desiredColumnCount;
Axis m_progressionAxis;
- bool m_progressionIsReversed;
unsigned m_columnCount;
LayoutUnit m_columnHeight;
@@ -114,7 +104,6 @@ private:
int m_forcedBreaks; // FIXME: We will ultimately need to cache more information to balance around forced breaks properly.
LayoutUnit m_maximumDistanceBetweenForcedBreaks;
LayoutUnit m_forcedBreakOffset;
- PaginationUnit m_paginationUnit;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp b/chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp
deleted file mode 100644
index 3358f9b4ced..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp
+++ /dev/null
@@ -1,2228 +0,0 @@
-/*
- * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/rendering/CompositedLayerMapping.h"
-
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "core/animation/ActiveAnimations.h"
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLMediaElement.h"
-#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/page/Chrome.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/Settings.h"
-#include "core/frame/animation/AnimationController.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/plugins/PluginView.h"
-#include "core/rendering/FilterEffectRenderer.h"
-#include "core/rendering/RenderApplet.h"
-#include "core/rendering/RenderEmbeddedObject.h"
-#include "core/rendering/RenderIFrame.h"
-#include "core/rendering/RenderImage.h"
-#include "core/rendering/RenderLayerCompositor.h"
-#include "core/rendering/RenderLayerStackingNodeIterator.h"
-#include "core/rendering/RenderVideo.h"
-#include "core/rendering/RenderView.h"
-#include "core/rendering/animation/WebAnimationProvider.h"
-#include "core/rendering/style/KeyframeList.h"
-#include "platform/LengthFunctions.h"
-#include "platform/fonts/FontCache.h"
-#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/GraphicsContext3D.h"
-#include "platform/graphics/filters/custom/CustomFilterOperation.h"
-#include "wtf/CurrentTime.h"
-#include "wtf/text/StringBuilder.h"
-
-using namespace std;
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-static IntRect clipBox(RenderBox* renderer);
-
-static IntRect contentsRect(const RenderObject* renderer)
-{
- if (!renderer->isBox())
- return IntRect();
-
- return renderer->isVideo() ?
- toRenderVideo(renderer)->videoBox() :
- pixelSnappedIntRect(toRenderBox(renderer)->contentBoxRect());
-}
-
-static IntRect backgroundRect(const RenderObject* renderer)
-{
- if (!renderer->isBox())
- return IntRect();
-
- LayoutRect rect;
- const RenderBox* box = toRenderBox(renderer);
- EFillBox clip = box->style()->backgroundClip();
- switch (clip) {
- case BorderFillBox:
- rect = box->borderBoxRect();
- break;
- case PaddingFillBox:
- rect = box->paddingBoxRect();
- break;
- case ContentFillBox:
- rect = box->contentBoxRect();
- break;
- case TextFillBox:
- break;
- }
-
- return pixelSnappedIntRect(rect);
-}
-
-static inline bool isAcceleratedCanvas(const RenderObject* renderer)
-{
- if (renderer->isCanvas()) {
- HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
- if (CanvasRenderingContext* context = canvas->renderingContext())
- return context->isAccelerated();
- }
- return false;
-}
-
-static bool hasBoxDecorations(const RenderStyle* style)
-{
- return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
-}
-
-static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
-{
- return hasBoxDecorations(style) || style->hasBackgroundImage();
-}
-
-static bool contentLayerSupportsDirectBackgroundComposition(const RenderObject* renderer)
-{
- // No support for decorations - border, border-radius or outline.
- // Only simple background - solid color or transparent.
- if (hasBoxDecorationsOrBackgroundImage(renderer->style()))
- return false;
-
- // If there is no background, there is nothing to support.
- if (!renderer->style()->hasBackground())
- return true;
-
- // Simple background that is contained within the contents rect.
- return contentsRect(renderer).contains(backgroundRect(renderer));
-}
-
-static inline bool isAcceleratedContents(RenderObject* renderer)
-{
- return isAcceleratedCanvas(renderer)
- || (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
- || renderer->isVideo();
-}
-
-// Get the scrolling coordinator in a way that works inside CompositedLayerMapping's destructor.
-static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer* layer)
-{
- Page* page = layer->renderer()->frame()->page();
- if (!page)
- return 0;
-
- return page->scrollingCoordinator();
-}
-
-CompositedLayerMapping::CompositedLayerMapping(RenderLayer* layer)
- : m_owningLayer(layer)
- , m_animationProvider(adoptPtr(new WebAnimationProvider))
- , m_artificiallyInflatedBounds(false)
- , m_boundsConstrainedByClipping(false)
- , m_isMainFrameRenderViewLayer(false)
- , m_requiresOwnBackingStoreForIntrinsicReasons(true)
- , m_requiresOwnBackingStoreForAncestorReasons(true)
- , m_canCompositeFilters(false)
- , m_backgroundLayerPaintsFixedRootBackground(false)
-{
- if (layer->isRootLayer() && renderer()->frame()->isMainFrame())
- m_isMainFrameRenderViewLayer = true;
-
- createPrimaryGraphicsLayer();
-}
-
-CompositedLayerMapping::~CompositedLayerMapping()
-{
- // Do not leave the destroyed pointer dangling on any RenderLayers that painted to this mapping's squashing layer.
- for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
- if (m_squashedLayers[i].renderLayer->groupedMapping() == this)
- m_squashedLayers[i].renderLayer->setGroupedMapping(0);
- }
-
- updateClippingLayers(false, false);
- updateOverflowControlsLayers(false, false, false);
- updateForegroundLayer(false);
- updateBackgroundLayer(false);
- updateMaskLayer(false);
- updateClippingMaskLayers(false);
- updateScrollingLayers(false);
- updateSquashingLayers(false);
- destroyGraphicsLayers();
-}
-
-PassOwnPtr<GraphicsLayer> CompositedLayerMapping::createGraphicsLayer(CompositingReasons reasons)
-{
- GraphicsLayerFactory* graphicsLayerFactory = 0;
- if (Page* page = renderer()->frame()->page())
- graphicsLayerFactory = page->chrome().client().graphicsLayerFactory();
-
- OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this);
-
- graphicsLayer->setCompositingReasons(reasons);
-
- return graphicsLayer.release();
-}
-
-void CompositedLayerMapping::createPrimaryGraphicsLayer()
-{
- m_graphicsLayer = createGraphicsLayer(m_owningLayer->compositingReasons());
-
-#if !OS(ANDROID)
- if (m_isMainFrameRenderViewLayer)
- m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
-#endif
-
- updateOpacity(renderer()->style());
- updateTransform(renderer()->style());
- updateFilters(renderer()->style());
-
- if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
- updateLayerBlendMode(renderer()->style());
- updateIsRootForIsolatedGroup();
- }
-}
-
-void CompositedLayerMapping::destroyGraphicsLayers()
-{
- if (m_graphicsLayer)
- m_graphicsLayer->removeFromParent();
-
- m_ancestorClippingLayer = nullptr;
- m_graphicsLayer = nullptr;
- m_foregroundLayer = nullptr;
- m_backgroundLayer = nullptr;
- m_childContainmentLayer = nullptr;
- m_maskLayer = nullptr;
- m_childClippingMaskLayer = nullptr;
-
- m_scrollingLayer = nullptr;
- m_scrollingContentsLayer = nullptr;
-}
-
-void CompositedLayerMapping::updateOpacity(const RenderStyle* style)
-{
- m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
-}
-
-void CompositedLayerMapping::updateTransform(const RenderStyle* style)
-{
- // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin
- // baked into it, and we don't want that.
- TransformationMatrix t;
- if (m_owningLayer->hasTransform()) {
- style->applyTransform(t, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
- makeMatrixRenderable(t, compositor()->canRender3DTransforms());
- }
-
- m_graphicsLayer->setTransform(t);
-}
-
-void CompositedLayerMapping::updateFilters(const RenderStyle* style)
-{
- bool didCompositeFilters = m_canCompositeFilters;
- m_canCompositeFilters = m_graphicsLayer->setFilters(owningLayer()->computeFilterOperations(style));
- if (didCompositeFilters != m_canCompositeFilters) {
- //
- // If filters used to be painted in software and are now painted in the compositor, we need to:
- // (1) Remove the FilterEffectRenderer, which was used for painting filters in software.
- // (2) Repaint the layer contents to remove the software-applied filter because the compositor will apply it.
- //
- // Similarly, if filters used to be painted in the compositor and are now painted in software, we need to:
- // (1) Create a FilterEffectRenderer.
- // (2) Repaint the layer contents to apply a software filter because the compositor won't apply it.
- //
- m_owningLayer->updateOrRemoveFilterEffectRenderer();
- setContentsNeedDisplay();
- }
-}
-
-void CompositedLayerMapping::updateLayerBlendMode(const RenderStyle* style)
-{
- setBlendMode(style->blendMode());
-}
-
-void CompositedLayerMapping::updateIsRootForIsolatedGroup()
-{
- bool isolate = m_owningLayer->shouldIsolateCompositedDescendants();
-
- // non stacking context layers should never isolate
- ASSERT(m_owningLayer->stackingNode()->isStackingContext() || !isolate);
-
- m_graphicsLayer->setIsRootForIsolatedGroup(isolate);
-}
-
-void CompositedLayerMapping::updateContentsOpaque()
-{
- // For non-root layers, background is always painted by the primary graphics layer.
- ASSERT(m_isMainFrameRenderViewLayer || !m_backgroundLayer);
- if (m_backgroundLayer) {
- m_graphicsLayer->setContentsOpaque(false);
- m_backgroundLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
- } else {
- m_graphicsLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
- }
-}
-
-static bool hasNonZeroTransformOrigin(const RenderObject* renderer)
-{
- RenderStyle* style = renderer->style();
- return (style->transformOriginX().type() == Fixed && style->transformOriginX().value())
- || (style->transformOriginY().type() == Fixed && style->transformOriginY().value());
-}
-
-static bool layerOrAncestorIsTransformedOrUsingCompositedScrolling(RenderLayer* layer)
-{
- for (RenderLayer* curr = layer; curr; curr = curr->parent()) {
- if (curr->hasTransform() || curr->needsCompositedScrolling())
- return true;
- }
-
- return false;
-}
-
-bool CompositedLayerMapping::shouldClipCompositedBounds() const
-{
- // Scrollbar layers use this layer for relative positioning, so don't clip.
- if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
- return false;
-
- if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
- return false;
-
- // Scrolled composited layers are clipped by their ancestor clipping layer,
- // so don't clip these, either.
- bool hasAncestorClippingLayer = compositor()->clippedByAncestor(m_owningLayer);
- bool clippingAncestorIsScrollParent = m_owningLayer->renderer()->containingBlock()->enclosingLayer() == m_owningLayer->ancestorScrollingLayer();
- if (hasAncestorClippingLayer && clippingAncestorIsScrollParent)
- return false;
-
- return true;
-}
-
-void CompositedLayerMapping::updateCompositedBounds()
-{
- // We need to know if we draw content in order to update our bounds (this has an effect
- // on whether or not descendands will paint into our backing). Update this value now.
- updateDrawsContent(isSimpleContainerCompositingLayer());
-
- IntRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
-
- // Clip to the size of the document or enclosing overflow-scroll layer.
- // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
- // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
- if (shouldClipCompositedBounds()) {
- RenderView* view = m_owningLayer->renderer()->view();
- RenderLayer* rootLayer = view->layer();
-
- LayoutRect clippingBounds;
- if (renderer()->style()->position() == FixedPosition && renderer()->container() == view)
- clippingBounds = view->frameView()->viewportConstrainedVisibleContentRect();
- else
- clippingBounds = view->unscaledDocumentRect();
-
- if (m_owningLayer != rootLayer)
- clippingBounds.intersect(m_owningLayer->backgroundClipRect(ClipRectsContext(rootLayer, 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
-
- LayoutPoint delta;
- m_owningLayer->convertToLayerCoords(rootLayer, delta);
- clippingBounds.move(-delta.x(), -delta.y());
-
- layerBounds.intersect(pixelSnappedIntRect(clippingBounds));
- m_boundsConstrainedByClipping = true;
- } else {
- m_boundsConstrainedByClipping = false;
- }
-
- // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
- // then we need to ensure that the compositing layer has non-zero size so that we can apply
- // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
- if (layerBounds.isEmpty() && hasNonZeroTransformOrigin(renderer())) {
- layerBounds.setWidth(1);
- layerBounds.setHeight(1);
- m_artificiallyInflatedBounds = true;
- } else {
- m_artificiallyInflatedBounds = false;
- }
-
- setCompositedBounds(layerBounds);
-}
-
-void CompositedLayerMapping::updateAfterWidgetResize()
-{
- if (renderer()->isRenderPart()) {
- if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
- innerCompositor->frameViewDidChangeSize();
- innerCompositor->frameViewDidChangeLocation(contentsBox().location());
- }
- }
-}
-
-void CompositedLayerMapping::updateCompositingReasons()
-{
- // All other layers owned by this mapping will have the same compositing reason
- // for their lifetime, so they are initialized only when created.
- m_graphicsLayer->setCompositingReasons(m_owningLayer->compositingReasons());
-}
-
-void CompositedLayerMapping::updateAfterLayout(UpdateAfterLayoutFlags flags)
-{
- RenderLayerCompositor* layerCompositor = compositor();
- if (!layerCompositor->compositingLayersNeedRebuild()) {
- // Calling updateGraphicsLayerGeometry() here gives incorrect results, because the
- // position of this layer's GraphicsLayer depends on the position of our compositing
- // ancestor's GraphicsLayer. That cannot be determined until all the descendant
- // RenderLayers of that ancestor have been processed via updateLayerPositions().
- //
- // The solution is to update compositing children of this layer here,
- // via updateCompositingChildrenGeometry().
- updateCompositedBounds();
- layerCompositor->updateCompositingDescendantGeometry(m_owningLayer->stackingNode(), m_owningLayer, flags & CompositingChildrenOnly);
-
- if (flags & IsUpdateRoot) {
- updateGraphicsLayerGeometry();
- layerCompositor->updateRootLayerPosition();
- RenderLayerStackingNode* stackingContainer = m_owningLayer->stackingNode()->enclosingStackingContainerNode();
- if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer->stackingNode()))
- layerCompositor->updateCompositingDescendantGeometry(stackingContainer, stackingContainer->layer(), flags & CompositingChildrenOnly);
- }
- }
-
- if (flags & NeedsFullRepaint && !paintsIntoCompositedAncestor())
- setContentsNeedDisplay();
-}
-
-bool CompositedLayerMapping::updateGraphicsLayerConfiguration()
-{
- RenderLayerCompositor* compositor = this->compositor();
- RenderObject* renderer = this->renderer();
-
- m_owningLayer->updateDescendantDependentFlags();
- m_owningLayer->stackingNode()->updateZOrderLists();
-
- bool layerConfigChanged = false;
- setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(m_owningLayer));
-
- // The background layer is currently only used for fixed root backgrounds.
- if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
- layerConfigChanged = true;
-
- if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
- layerConfigChanged = true;
-
- bool needsDescendentsClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer);
-
- // Our scrolling layer will clip.
- if (m_owningLayer->needsCompositedScrolling())
- needsDescendentsClippingLayer = false;
-
- RenderLayer* scrollParent = m_owningLayer->scrollParent();
- bool needsAncestorClip = compositor->clippedByAncestor(m_owningLayer);
- if (scrollParent) {
- // If our containing block is our ancestor scrolling layer, then we'll already be clipped
- // to it via our scroll parent and we don't need an ancestor clipping layer.
- if (m_owningLayer->renderer()->containingBlock()->enclosingLayer() == m_owningLayer->ancestorCompositedScrollingLayer())
- needsAncestorClip = false;
- }
- if (updateClippingLayers(needsAncestorClip, needsDescendentsClippingLayer))
- layerConfigChanged = true;
-
- if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
- layerConfigChanged = true;
-
- if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling()))
- layerConfigChanged = true;
-
- updateScrollParent(scrollParent);
- updateClipParent(m_owningLayer->clipParent());
-
- if (updateSquashingLayers(!m_squashedLayers.isEmpty()))
- layerConfigChanged = true;
-
- if (layerConfigChanged)
- updateInternalHierarchy();
-
- if (updateMaskLayer(renderer->hasMask()))
- m_graphicsLayer->setMaskLayer(m_maskLayer.get());
-
- bool hasChildClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer) && (hasClippingLayer() || hasScrollingLayer());
- bool needsChildClippingMask = (renderer->style()->clipPath() || renderer->style()->hasBorderRadius()) && (hasChildClippingLayer || isAcceleratedContents(renderer));
- if (updateClippingMaskLayers(needsChildClippingMask)) {
- if (hasClippingLayer())
- clippingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
- else if (hasScrollingLayer())
- scrollingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
- else if (isAcceleratedContents(renderer))
- m_graphicsLayer->setContentsClippingMaskLayer(m_childClippingMaskLayer.get());
- }
-
- if (m_owningLayer->reflectionInfo()) {
- if (m_owningLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
- GraphicsLayer* reflectionLayer = m_owningLayer->reflectionInfo()->reflectionLayer()->compositedLayerMapping()->mainGraphicsLayer();
- m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
- }
- } else {
- m_graphicsLayer->setReplicatedByLayer(0);
- }
-
- updateBackgroundColor(isSimpleContainerCompositingLayer());
-
- if (isDirectlyCompositedImage())
- updateImageContents();
-
- if (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing()) {
- PluginView* pluginView = toPluginView(toRenderWidget(renderer)->widget());
- m_graphicsLayer->setContentsToPlatformLayer(pluginView->platformLayer());
- } else if (renderer->node() && renderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(renderer->node())->contentFrame()) {
- blink::WebLayer* layer = toHTMLFrameOwnerElement(renderer->node())->contentFrame()->remotePlatformLayer();
- if (layer)
- m_graphicsLayer->setContentsToPlatformLayer(layer);
- } else if (renderer->isVideo()) {
- HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer->node());
- m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer());
- } else if (isAcceleratedCanvas(renderer)) {
- HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
- if (CanvasRenderingContext* context = canvas->renderingContext())
- m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer());
- layerConfigChanged = true;
- }
- if (renderer->isRenderPart())
- layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
-
- return layerConfigChanged;
-}
-
-static IntRect clipBox(RenderBox* renderer)
-{
- LayoutRect result = PaintInfo::infiniteRect();
- if (renderer->hasOverflowClip())
- result = renderer->overflowClipRect(LayoutPoint(), 0); // FIXME: Incorrect for CSS regions.
-
- if (renderer->hasClip())
- result.intersect(renderer->clipRect(LayoutPoint(), 0)); // FIXME: Incorrect for CSS regions.
-
- return pixelSnappedIntRect(result);
-}
-
-void CompositedLayerMapping::updateGraphicsLayerGeometry()
-{
- // If we haven't built z-order lists yet, wait until later.
- if (m_owningLayer->stackingNode()->isStackingContainer() && m_owningLayer->stackingNode()->zOrderListsDirty())
- return;
-
- // Set transform property, if it is not animating. We have to do this here because the transform
- // is affected by the layer dimensions.
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()
- ? !hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyWebkitTransform)
- : !renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitTransform))
- updateTransform(renderer()->style());
-
- // Set opacity, if it is not animating.
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()
- ? !hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyOpacity)
- : !renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity))
- updateOpacity(renderer()->style());
-
- bool isSimpleContainer = isSimpleContainerCompositingLayer();
-
- m_owningLayer->updateDescendantDependentFlags();
-
- // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
- // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
- // non-compositing visible layers.
- bool contentsVisible = m_owningLayer->hasVisibleContent() || hasVisibleNonCompositingDescendantLayers();
- if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer()->isVideo()) {
- HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer()->node());
- if (mediaElement->isFullscreen())
- contentsVisible = false;
- }
- m_graphicsLayer->setContentsVisible(contentsVisible);
-
- RenderStyle* style = renderer()->style();
- // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
- bool preserves3D = style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection();
- m_graphicsLayer->setPreserves3D(preserves3D);
- m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
-
- RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
-
- // We compute everything relative to the enclosing compositing layer.
- IntRect ancestorCompositingBounds;
- if (compAncestor) {
- ASSERT(compAncestor->hasCompositedLayerMapping());
- ancestorCompositingBounds = pixelSnappedIntRect(compAncestor->compositedLayerMapping()->compositedBounds());
- }
-
- IntRect localCompositingBounds = pixelSnappedIntRect(compositedBounds());
-
- IntRect relativeCompositingBounds(localCompositingBounds);
- IntPoint delta;
- m_owningLayer->convertToPixelSnappedLayerCoords(compAncestor, delta);
- relativeCompositingBounds.moveBy(delta);
-
- IntPoint graphicsLayerParentLocation;
- if (compAncestor && compAncestor->compositedLayerMapping()->hasClippingLayer()) {
- // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
- // position relative to it.
- IntRect clippingBox = clipBox(toRenderBox(compAncestor->renderer()));
- graphicsLayerParentLocation = clippingBox.location();
- } else if (compAncestor) {
- graphicsLayerParentLocation = ancestorCompositingBounds.location();
- } else {
- graphicsLayerParentLocation = renderer()->view()->documentRect().location();
- }
-
- if (compAncestor && compAncestor->needsCompositedScrolling()) {
- RenderBox* renderBox = toRenderBox(compAncestor->renderer());
- IntSize scrollOffset = renderBox->scrolledContentOffset();
- IntPoint scrollOrigin(renderBox->borderLeft(), renderBox->borderTop());
- graphicsLayerParentLocation = scrollOrigin - scrollOffset;
- }
-
- if (compAncestor && m_ancestorClippingLayer) {
- // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
- // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
- // for a compositing layer, rootLayer is the layer itself.
- ClipRectsContext clipRectsContext(compAncestor, 0, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
- IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->backgroundClipRect(clipRectsContext).rect()); // FIXME: Incorrect for CSS regions.
- ASSERT(parentClipRect != PaintInfo::infiniteRect());
- m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
- m_ancestorClippingLayer->setSize(parentClipRect.size());
-
- // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
- m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - delta);
-
- // The primary layer is then parented in, and positioned relative to this clipping layer.
- graphicsLayerParentLocation = parentClipRect.location();
- }
-
- FloatSize contentsSize = relativeCompositingBounds.size();
-
- m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
- m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
-
- FloatSize oldSize = m_graphicsLayer->size();
- if (oldSize != contentsSize) {
- m_graphicsLayer->setSize(contentsSize);
- // Usually invalidation will happen via layout etc, but if we've affected the layer
- // size by constraining relative to a clipping ancestor or the viewport, we
- // have to invalidate to avoid showing stretched content.
- if (m_boundsConstrainedByClipping)
- m_graphicsLayer->setNeedsDisplay();
- }
-
- // If we have a layer that clips children, position it.
- IntRect clippingBox;
- if (GraphicsLayer* clipLayer = clippingLayer()) {
- clippingBox = clipBox(toRenderBox(renderer()));
- clipLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location()));
- clipLayer->setSize(clippingBox.size());
- clipLayer->setOffsetFromRenderer(toIntSize(clippingBox.location()));
- if (m_childClippingMaskLayer && !m_scrollingLayer) {
- m_childClippingMaskLayer->setPosition(clipLayer->position());
- m_childClippingMaskLayer->setSize(clipLayer->size());
- m_childClippingMaskLayer->setOffsetFromRenderer(clipLayer->offsetFromRenderer());
- }
- }
-
- if (m_maskLayer) {
- if (m_maskLayer->size() != m_graphicsLayer->size()) {
- m_maskLayer->setSize(m_graphicsLayer->size());
- m_maskLayer->setNeedsDisplay();
- }
- m_maskLayer->setPosition(FloatPoint());
- m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
- }
-
- if (m_owningLayer->hasTransform()) {
- const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
-
- // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
- IntRect layerBounds = IntRect(delta, borderBox.size());
-
- // Update properties that depend on layer dimensions
- FloatPoint3D transformOrigin = computeTransformOrigin(borderBox);
- // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
- FloatPoint3D anchor(relativeCompositingBounds.width() != 0.0f ? ((layerBounds.x() - relativeCompositingBounds.x()) + transformOrigin.x()) / relativeCompositingBounds.width() : 0.5f,
- relativeCompositingBounds.height() != 0.0f ? ((layerBounds.y() - relativeCompositingBounds.y()) + transformOrigin.y()) / relativeCompositingBounds.height() : 0.5f,
- transformOrigin.z());
- m_graphicsLayer->setAnchorPoint(anchor);
-
- RenderStyle* style = renderer()->style();
- GraphicsLayer* clipLayer = clippingLayer();
- if (style->hasPerspective()) {
- TransformationMatrix t = owningLayer()->perspectiveTransform();
-
- if (clipLayer) {
- clipLayer->setChildrenTransform(t);
- m_graphicsLayer->setChildrenTransform(TransformationMatrix());
- } else {
- m_graphicsLayer->setChildrenTransform(t);
- }
- } else {
- if (clipLayer)
- clipLayer->setChildrenTransform(TransformationMatrix());
- else
- m_graphicsLayer->setChildrenTransform(TransformationMatrix());
- }
- } else {
- m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
- }
-
- if (m_foregroundLayer) {
- FloatPoint foregroundPosition;
- FloatSize foregroundSize = contentsSize;
- IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
- if (hasClippingLayer()) {
- // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
- // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
- foregroundSize = FloatSize(clippingBox.size());
- foregroundOffset = toIntSize(clippingBox.location());
- }
-
- m_foregroundLayer->setPosition(foregroundPosition);
- if (foregroundSize != m_foregroundLayer->size()) {
- m_foregroundLayer->setSize(foregroundSize);
- m_foregroundLayer->setNeedsDisplay();
- }
- m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
- }
-
- if (m_backgroundLayer) {
- FloatPoint backgroundPosition;
- FloatSize backgroundSize = contentsSize;
- if (backgroundLayerPaintsFixedRootBackground()) {
- FrameView* frameView = toRenderView(renderer())->frameView();
- backgroundSize = frameView->visibleContentRect().size();
- }
- m_backgroundLayer->setPosition(backgroundPosition);
- if (backgroundSize != m_backgroundLayer->size()) {
- m_backgroundLayer->setSize(backgroundSize);
- m_backgroundLayer->setNeedsDisplay();
- }
- m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
- }
-
- if (m_owningLayer->reflectionInfo() && m_owningLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
- CompositedLayerMappingPtr reflectionCompositedLayerMapping = m_owningLayer->reflectionInfo()->reflectionLayer()->compositedLayerMapping();
- reflectionCompositedLayerMapping->updateGraphicsLayerGeometry();
-
- // The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
- // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
- FloatRect layerBounds = compositedBounds();
- FloatRect reflectionLayerBounds = reflectionCompositedLayerMapping->compositedBounds();
- reflectionCompositedLayerMapping->mainGraphicsLayer()->setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
- }
-
- if (m_scrollingLayer) {
- ASSERT(m_scrollingContentsLayer);
- RenderBox* renderBox = toRenderBox(renderer());
- IntRect clientBox = enclosingIntRect(renderBox->clientBoxRect());
- // FIXME: We should make RenderBox::clientBoxRect consider scrollbar placement.
- if (style->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- clientBox.move(renderBox->verticalScrollbarWidth(), 0);
-
- IntSize adjustedScrollOffset = m_owningLayer->scrollableArea()->adjustedScrollOffset();
- m_scrollingLayer->setPosition(FloatPoint(clientBox.location() - localCompositingBounds.location()));
- m_scrollingLayer->setSize(clientBox.size());
-
- IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
- m_scrollingLayer->setOffsetFromRenderer(-toIntSize(clientBox.location()));
-
- if (m_childClippingMaskLayer) {
- m_childClippingMaskLayer->setPosition(m_scrollingLayer->position());
- m_childClippingMaskLayer->setSize(m_scrollingLayer->size());
- m_childClippingMaskLayer->setOffsetFromRenderer(toIntSize(clientBox.location()));
- }
-
- bool clientBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
-
- IntSize scrollSize(renderBox->scrollWidth(), renderBox->scrollHeight());
- if (scrollSize != m_scrollingContentsLayer->size() || clientBoxOffsetChanged)
- m_scrollingContentsLayer->setNeedsDisplay();
-
- IntSize scrollingContentsOffset = toIntSize(clientBox.location() - adjustedScrollOffset);
- if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size()) {
- bool scrollingCoordinatorHandlesOffset = compositor()->scrollingLayerDidChange(m_owningLayer);
-
- if (scrollingCoordinatorHandlesOffset)
- m_scrollingContentsLayer->setPosition(-m_owningLayer->scrollableArea()->scrollOrigin());
- else
- m_scrollingContentsLayer->setPosition(FloatPoint(-adjustedScrollOffset));
- }
-
- m_scrollingContentsLayer->setSize(scrollSize);
- // FIXME: The paint offset and the scroll offset should really be separate concepts.
- m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
-
- if (m_foregroundLayer) {
- if (m_foregroundLayer->size() != m_scrollingContentsLayer->size())
- m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
- m_foregroundLayer->setNeedsDisplay();
- m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
- }
- }
-
- if (m_squashingLayer) {
- ASSERT(compositor()->layerSquashingEnabled());
-
- IntRect totalSquashBounds;
- for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
- IntRect squashedBounds = compositor()->calculateCompositedBounds(m_squashedLayers[i].renderLayer, m_squashedLayers[i].renderLayer);
-
- // Store the composited bounds before applying the offset.
- // FIXME: consider whether it is more efficient or clarifies the math to store the compositedBounds after applying the offset.
- m_squashedLayers[i].compositedBounds = squashedBounds;
-
- squashedBounds.move(m_squashedLayers[i].offsetFromBackingRoot);
- totalSquashBounds.unite(squashedBounds);
- }
-
- IntPoint squashLayerPosition;
- // FIXME: this logic needs to update depending on what "containment" layers are added to CompositedLayerMapping due to other changes
- if (m_ancestorClippingLayer) {
- squashLayerPosition = IntPoint(m_ancestorClippingLayer->position().x() + totalSquashBounds.location().x(),
- m_ancestorClippingLayer->position().y() + totalSquashBounds.location().y());
- } else {
- squashLayerPosition = IntPoint(m_graphicsLayer->position().x() + totalSquashBounds.location().x(),
- m_graphicsLayer->position().y() + totalSquashBounds.location().y());
- }
-
- m_squashingLayer->setPosition(squashLayerPosition);
- m_squashingLayer->setSize(totalSquashBounds.size());
-
- // Now that the position of the squashing layer is known, update the offsets for each squashed RenderLayer.
- for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
- m_squashedLayers[i].offsetFromRenderer = IntSize(-m_squashedLayers[i].offsetFromBackingRoot.width() - m_graphicsLayer->position().x() + m_squashingLayer->position().x(),
- -m_squashedLayers[i].offsetFromBackingRoot.height() - m_graphicsLayer->position().y() + m_squashingLayer->position().y());
-
- // FIXME: find a better design to avoid this redundant value - most likely it will make
- // sense to move the paint task info into RenderLayer's m_compositingProperties.
- m_squashedLayers[i].renderLayer->setOffsetFromSquashingLayerOrigin(m_squashedLayers[i].offsetFromRenderer);
- }
- }
-
- if (m_owningLayer->scrollableArea())
- m_owningLayer->scrollableArea()->positionOverflowControls();
-
- // We can't make this call in RenderLayerCompositor::allocateOrClearCompositedLayerMapping
- // since it depends on whether compAncestor draws content, which gets updated later.
- updateRequiresOwnBackingStoreForAncestorReasons(compAncestor);
-
- if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
- updateLayerBlendMode(style);
- updateIsRootForIsolatedGroup();
- }
-
- updateContentsRect(isSimpleContainer);
- updateBackgroundColor(isSimpleContainer);
- updateDrawsContent(isSimpleContainer);
- updateContentsOpaque();
- updateAfterWidgetResize();
- registerScrollingLayers();
-
- updateCompositingReasons();
-}
-
-void CompositedLayerMapping::registerScrollingLayers()
-{
- // Register fixed position layers and their containers with the scrolling coordinator.
- ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
- if (!scrollingCoordinator)
- return;
-
- compositor()->updateViewportConstraintStatus(m_owningLayer);
-
- scrollingCoordinator->updateLayerPositionConstraint(m_owningLayer);
-
- // Page scale is applied as a transform on the root render view layer. Because the scroll
- // layer is further up in the hierarchy, we need to avoid marking the root render view
- // layer as a container.
- bool isContainer = m_owningLayer->hasTransform() && !m_owningLayer->isRootLayer();
- // FIXME: we should make certain that childForSuperLayers will never be the m_squashingContainmentLayer here
- scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(childForSuperlayers(), isContainer);
-}
-
-void CompositedLayerMapping::updateInternalHierarchy()
-{
- // m_foregroundLayer has to be inserted in the correct order with child layers,
- // so it's not inserted here.
- if (m_ancestorClippingLayer)
- m_ancestorClippingLayer->removeAllChildren();
-
- m_graphicsLayer->removeFromParent();
-
- if (m_ancestorClippingLayer)
- m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
-
- if (m_childContainmentLayer) {
- m_childContainmentLayer->removeFromParent();
- m_graphicsLayer->addChild(m_childContainmentLayer.get());
- }
-
- if (m_scrollingLayer) {
- GraphicsLayer* superlayer = m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
- m_scrollingLayer->removeFromParent();
- superlayer->addChild(m_scrollingLayer.get());
- }
-
- // The clip for child layers does not include space for overflow controls, so they exist as
- // siblings of the clipping layer if we have one. Normal children of this layer are set as
- // children of the clipping layer.
- if (m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar->removeFromParent();
- m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
- }
- if (m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar->removeFromParent();
- m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
- }
- if (m_layerForScrollCorner) {
- m_layerForScrollCorner->removeFromParent();
- m_graphicsLayer->addChild(m_layerForScrollCorner.get());
- }
-
- // The squashing containment layer, if it exists, becomes a no-op parent.
- if (m_squashingLayer) {
- ASSERT(compositor()->layerSquashingEnabled());
- ASSERT(m_squashingContainmentLayer);
-
- m_squashingContainmentLayer->removeAllChildren();
-
- if (m_ancestorClippingLayer)
- m_squashingContainmentLayer->addChild(m_ancestorClippingLayer.get());
- else
- m_squashingContainmentLayer->addChild(m_graphicsLayer.get());
-
- m_squashingContainmentLayer->addChild(m_squashingLayer.get());
- }
-}
-
-void CompositedLayerMapping::updateContentsRect(bool isSimpleContainer)
-{
- IntRect contentsRect;
- if (isSimpleContainer && renderer()->hasBackground())
- contentsRect = backgroundBox();
- else
- contentsRect = contentsBox();
-
- m_graphicsLayer->setContentsRect(contentsRect);
-}
-
-void CompositedLayerMapping::updateDrawsContent(bool isSimpleContainer)
-{
- if (m_scrollingLayer) {
- // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
- // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
- // m_scrollingLayer never has backing store.
- // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
- bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent() && m_owningLayer->hasBoxDecorationsOrBackground();
- m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
-
- bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() && (renderer()->hasBackground() || paintsChildren());
- m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
- return;
- }
-
- bool hasPaintedContent = containsPaintedContent(isSimpleContainer);
- if (hasPaintedContent && isAcceleratedCanvas(renderer())) {
- CanvasRenderingContext* context = toHTMLCanvasElement(renderer()->node())->renderingContext();
- // Content layer may be null if context is lost.
- if (blink::WebLayer* contentLayer = context->platformLayer()) {
- Color bgColor;
- if (contentLayerSupportsDirectBackgroundComposition(renderer())) {
- bgColor = rendererBackgroundColor();
- hasPaintedContent = false;
- }
- contentLayer->setBackgroundColor(bgColor.rgb());
- }
- }
-
- // FIXME: we could refine this to only allocate backings for one of these layers if possible.
- m_graphicsLayer->setDrawsContent(hasPaintedContent);
- if (m_foregroundLayer)
- m_foregroundLayer->setDrawsContent(hasPaintedContent);
-
- if (m_backgroundLayer)
- m_backgroundLayer->setDrawsContent(hasPaintedContent);
-}
-
-// Return true if the layers changed.
-bool CompositedLayerMapping::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
-{
- bool layersChanged = false;
-
- if (needsAncestorClip) {
- if (!m_ancestorClippingLayer) {
- m_ancestorClippingLayer = createGraphicsLayer(CompositingReasonLayerForClip);
- m_ancestorClippingLayer->setMasksToBounds(true);
- layersChanged = true;
- }
- } else if (m_ancestorClippingLayer) {
- m_ancestorClippingLayer->removeFromParent();
- m_ancestorClippingLayer = nullptr;
- layersChanged = true;
- }
-
- if (needsDescendantClip) {
- // We don't need a child containment layer if we're the main frame render view
- // layer. It's redundant as the frame clip above us will handle this clipping.
- if (!m_childContainmentLayer && !m_isMainFrameRenderViewLayer) {
- m_childContainmentLayer = createGraphicsLayer(CompositingReasonLayerForClip);
- m_childContainmentLayer->setMasksToBounds(true);
- layersChanged = true;
- }
- } else if (hasClippingLayer()) {
- m_childContainmentLayer->removeFromParent();
- m_childContainmentLayer = nullptr;
- layersChanged = true;
- }
-
- return layersChanged;
-}
-
-void CompositedLayerMapping::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
-{
- m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
-}
-
-bool CompositedLayerMapping::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
-{
- bool horizontalScrollbarLayerChanged = false;
- if (needsHorizontalScrollbarLayer) {
- if (!m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar = createGraphicsLayer(CompositingReasonLayerForScrollbar);
- horizontalScrollbarLayerChanged = true;
- }
- } else if (m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar = nullptr;
- horizontalScrollbarLayerChanged = true;
- }
-
- bool verticalScrollbarLayerChanged = false;
- if (needsVerticalScrollbarLayer) {
- if (!m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar = createGraphicsLayer(CompositingReasonLayerForScrollbar);
- verticalScrollbarLayerChanged = true;
- }
- } else if (m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar = nullptr;
- verticalScrollbarLayerChanged = true;
- }
-
- bool scrollCornerLayerChanged = false;
- if (needsScrollCornerLayer) {
- if (!m_layerForScrollCorner) {
- m_layerForScrollCorner = createGraphicsLayer(CompositingReasonLayerForScrollbar);
- scrollCornerLayerChanged = true;
- }
- } else if (m_layerForScrollCorner) {
- m_layerForScrollCorner = nullptr;
- scrollCornerLayerChanged = true;
- }
-
- if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
- if (horizontalScrollbarLayerChanged)
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer->scrollableArea(), HorizontalScrollbar);
- if (verticalScrollbarLayerChanged)
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer->scrollableArea(), VerticalScrollbar);
- }
-
- return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
-}
-
-void CompositedLayerMapping::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
-{
- IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
- if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
- Scrollbar* hBar = m_owningLayer->scrollableArea()->horizontalScrollbar();
- if (hBar) {
- layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
- layer->setSize(hBar->frameRect().size());
- if (layer->hasContentsLayer())
- layer->setContentsRect(IntRect(IntPoint(), hBar->frameRect().size()));
- }
- layer->setDrawsContent(hBar && !layer->hasContentsLayer());
- }
-
- if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
- Scrollbar* vBar = m_owningLayer->scrollableArea()->verticalScrollbar();
- if (vBar) {
- layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
- layer->setSize(vBar->frameRect().size());
- if (layer->hasContentsLayer())
- layer->setContentsRect(IntRect(IntPoint(), vBar->frameRect().size()));
- }
- layer->setDrawsContent(vBar && !layer->hasContentsLayer());
- }
-
- if (GraphicsLayer* layer = layerForScrollCorner()) {
- const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollableArea()->scrollCornerAndResizerRect();
- layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
- layer->setSize(scrollCornerAndResizer.size());
- layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
- }
-}
-
-bool CompositedLayerMapping::hasUnpositionedOverflowControlsLayers() const
-{
- if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
- if (!layer->drawsContent())
- return true;
- }
-
- if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
- if (!layer->drawsContent())
- return true;
- }
-
- if (GraphicsLayer* layer = layerForScrollCorner()) {
- if (!layer->drawsContent())
- return true;
- }
-
- return false;
-}
-
-bool CompositedLayerMapping::updateForegroundLayer(bool needsForegroundLayer)
-{
- bool layerChanged = false;
- if (needsForegroundLayer) {
- if (!m_foregroundLayer) {
- m_foregroundLayer = createGraphicsLayer(CompositingReasonLayerForForeground);
- m_foregroundLayer->setDrawsContent(true);
- m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
- layerChanged = true;
- }
- } else if (m_foregroundLayer) {
- m_foregroundLayer->removeFromParent();
- m_foregroundLayer = nullptr;
- layerChanged = true;
- }
-
- if (layerChanged)
- m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
-
- return layerChanged;
-}
-
-bool CompositedLayerMapping::updateBackgroundLayer(bool needsBackgroundLayer)
-{
- bool layerChanged = false;
- if (needsBackgroundLayer) {
- if (!m_backgroundLayer) {
- m_backgroundLayer = createGraphicsLayer(CompositingReasonLayerForBackground);
- m_backgroundLayer->setDrawsContent(true);
- m_backgroundLayer->setAnchorPoint(FloatPoint3D());
- m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
-#if !OS(ANDROID)
- m_backgroundLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
- m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(false);
-#endif
- layerChanged = true;
- }
- } else {
- if (m_backgroundLayer) {
- m_backgroundLayer->removeFromParent();
- m_backgroundLayer = nullptr;
-#if !OS(ANDROID)
- m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
-#endif
- layerChanged = true;
- }
- }
-
- if (layerChanged && !m_owningLayer->renderer()->documentBeingDestroyed())
- compositor()->rootFixedBackgroundsChanged();
-
- return layerChanged;
-}
-
-bool CompositedLayerMapping::updateMaskLayer(bool needsMaskLayer)
-{
- bool layerChanged = false;
- if (needsMaskLayer) {
- if (!m_maskLayer) {
- m_maskLayer = createGraphicsLayer(CompositingReasonLayerForMask);
- m_maskLayer->setDrawsContent(true);
- m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
- layerChanged = true;
- }
- } else if (m_maskLayer) {
- m_maskLayer = nullptr;
- layerChanged = true;
- }
-
- if (layerChanged)
- m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
-
- return layerChanged;
-}
-
-bool CompositedLayerMapping::updateClippingMaskLayers(bool needsChildClippingMaskLayer)
-{
- bool layerChanged = false;
- if (needsChildClippingMaskLayer) {
- if (!m_childClippingMaskLayer) {
- m_childClippingMaskLayer = createGraphicsLayer(CompositingReasonLayerForMask);
- m_childClippingMaskLayer->setDrawsContent(true);
- m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask);
- layerChanged = true;
- }
- } else if (m_childClippingMaskLayer) {
- m_childClippingMaskLayer = nullptr;
- layerChanged = true;
- }
- return layerChanged;
-}
-
-bool CompositedLayerMapping::updateScrollingLayers(bool needsScrollingLayers)
-{
- ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
-
- bool layerChanged = false;
- if (needsScrollingLayers) {
- if (!m_scrollingLayer) {
- // Outer layer which corresponds with the scroll view.
- m_scrollingLayer = createGraphicsLayer(CompositingReasonLayerForClip);
- m_scrollingLayer->setDrawsContent(false);
- m_scrollingLayer->setMasksToBounds(true);
-
- // Inner layer which renders the content that scrolls.
- m_scrollingContentsLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContainer);
- m_scrollingContentsLayer->setDrawsContent(true);
- GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
- if (!m_foregroundLayer)
- paintPhase |= GraphicsLayerPaintForeground;
- m_scrollingContentsLayer->setPaintingPhase(paintPhase);
- m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
-
- layerChanged = true;
- if (scrollingCoordinator)
- scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer->scrollableArea());
- }
- } else if (m_scrollingLayer) {
- m_scrollingLayer = nullptr;
- m_scrollingContentsLayer = nullptr;
- layerChanged = true;
- if (scrollingCoordinator)
- scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer->scrollableArea());
- }
-
- if (layerChanged) {
- updateInternalHierarchy();
- m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
- m_graphicsLayer->setNeedsDisplay();
- if (renderer()->view())
- compositor()->scrollingLayerDidChange(m_owningLayer);
- }
-
- return layerChanged;
-}
-
-static void updateScrollParentForGraphicsLayer(GraphicsLayer* layer, GraphicsLayer* topmostLayer, RenderLayer* scrollParent, ScrollingCoordinator* scrollingCoordinator)
-{
- if (!layer)
- return;
-
- // Only the topmost layer has a scroll parent. All other layers have a null scroll parent.
- if (layer != topmostLayer)
- scrollParent = 0;
-
- scrollingCoordinator->updateScrollParentForGraphicsLayer(layer, scrollParent);
-}
-
-void CompositedLayerMapping::updateScrollParent(RenderLayer* scrollParent)
-{
-
- if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
- GraphicsLayer* topmostLayer = childForSuperlayers();
- updateScrollParentForGraphicsLayer(m_squashingContainmentLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
- updateScrollParentForGraphicsLayer(m_ancestorClippingLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
- updateScrollParentForGraphicsLayer(m_graphicsLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
- }
-}
-
-void CompositedLayerMapping::updateClipParent(RenderLayer* clipParent)
-{
- if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer))
- scrollingCoordinator->updateClipParentForGraphicsLayer(m_graphicsLayer.get(), clipParent);
-}
-
-bool CompositedLayerMapping::updateSquashingLayers(bool needsSquashingLayers)
-{
- bool layersChanged = false;
-
- if (needsSquashingLayers) {
- ASSERT(compositor()->layerSquashingEnabled());
-
- if (!m_squashingLayer) {
- ASSERT(!m_squashingContainmentLayer);
-
- m_squashingLayer = createGraphicsLayer(CompositingReasonOverlap);
- m_squashingLayer->setDrawsContent(true);
- m_squashingLayer->setNeedsDisplay();
- layersChanged = true;
-
- // FIXME: containment layer needs a new CompositingReason, CompositingReasonOverlap is not appropriate.
- m_squashingContainmentLayer = createGraphicsLayer(CompositingReasonOverlap);
- // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
- bool preserves3D = renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection();
- m_squashingContainmentLayer->setPreserves3D(preserves3D);
- layersChanged = true;
- }
-
- ASSERT(m_squashingLayer && m_squashingContainmentLayer);
- } else {
- if (m_squashingLayer) {
- m_squashingLayer->removeFromParent();
- m_squashingLayer = nullptr;
- layersChanged = true;
- // FIXME: do we need to invalidate something here?
-
- ASSERT(m_squashingContainmentLayer);
- m_squashingContainmentLayer->removeFromParent();
- m_squashingContainmentLayer = nullptr;
- layersChanged = true;
- }
-
- ASSERT(!m_squashingLayer && !m_squashingContainmentLayer);
- }
-
- return layersChanged;
-}
-
-GraphicsLayerPaintingPhase CompositedLayerMapping::paintingPhaseForPrimaryLayer() const
-{
- unsigned phase = 0;
- if (!m_backgroundLayer)
- phase |= GraphicsLayerPaintBackground;
- if (!m_foregroundLayer)
- phase |= GraphicsLayerPaintForeground;
- if (!m_maskLayer)
- phase |= GraphicsLayerPaintMask;
-
- if (m_scrollingContentsLayer) {
- phase &= ~GraphicsLayerPaintForeground;
- phase |= GraphicsLayerPaintCompositedScroll;
- }
-
- if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent)
- phase |= GraphicsLayerPaintCompositedScroll;
-
- return static_cast<GraphicsLayerPaintingPhase>(phase);
-}
-
-float CompositedLayerMapping::compositingOpacity(float rendererOpacity) const
-{
- float finalOpacity = rendererOpacity;
-
- for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
- // We only care about parents that are stacking contexts.
- // Recall that opacity creates stacking context.
- if (!curr->stackingNode()->isStackingContainer())
- continue;
-
- // If we found a composited layer, regardless of whether it actually
- // paints into it, we want to compute opacity relative to it. So we can
- // break here.
- //
- // FIXME: with grouped backings, a composited descendant will have to
- // continue past the grouped (squashed) layers that its parents may
- // contribute to. This whole confusion can be avoided by specifying
- // explicitly the composited ancestor where we would stop accumulating
- // opacity.
- if (curr->compositingState() == PaintsIntoOwnBacking || curr->compositingState() == HasOwnBackingButPaintsIntoAncestor)
- break;
-
- finalOpacity *= curr->renderer()->opacity();
- }
-
- return finalOpacity;
-}
-
-Color CompositedLayerMapping::rendererBackgroundColor() const
-{
- RenderObject* backgroundRenderer = renderer();
- if (backgroundRenderer->isRoot())
- backgroundRenderer = backgroundRenderer->rendererForRootBackground();
-
- return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor);
-}
-
-void CompositedLayerMapping::updateBackgroundColor(bool isSimpleContainer)
-{
- Color backgroundColor = rendererBackgroundColor();
- if (isSimpleContainer) {
- m_graphicsLayer->setContentsToSolidColor(backgroundColor);
- m_graphicsLayer->setBackgroundColor(Color());
- } else {
- // An unset (invalid) color will remove the solid color.
- m_graphicsLayer->setContentsToSolidColor(Color());
- m_graphicsLayer->setBackgroundColor(backgroundColor);
- }
-}
-
-static bool supportsDirectBoxDecorationsComposition(const RenderObject* renderer)
-{
- if (renderer->hasClip())
- return false;
-
- if (hasBoxDecorationsOrBackgroundImage(renderer->style()))
- return false;
-
- // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
- if (renderer->style()->backgroundComposite() != CompositeSourceOver)
- return false;
-
- if (renderer->style()->backgroundClip() == TextFillBox)
- return false;
-
- return true;
-}
-
-bool CompositedLayerMapping::paintsBoxDecorations() const
-{
- if (!m_owningLayer->hasVisibleBoxDecorations())
- return false;
-
- if (!supportsDirectBoxDecorationsComposition(renderer()))
- return true;
-
- return false;
-}
-
-bool CompositedLayerMapping::paintsChildren() const
-{
- if (m_owningLayer->hasVisibleContent() && m_owningLayer->hasNonEmptyChildRenderers())
- return true;
-
- if (hasVisibleNonCompositingDescendantLayers())
- return true;
-
- return false;
-}
-
-static bool isCompositedPlugin(RenderObject* renderer)
-{
- return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
-}
-
-// A "simple container layer" is a RenderLayer which has no visible content to render.
-// It may have no children, or all its children may be themselves composited.
-// This is a useful optimization, because it allows us to avoid allocating backing store.
-bool CompositedLayerMapping::isSimpleContainerCompositingLayer() const
-{
- RenderObject* renderObject = renderer();
- if (renderObject->hasMask()) // masks require special treatment
- return false;
-
- if (renderObject->isReplaced() && !isCompositedPlugin(renderObject))
- return false;
-
- if (paintsBoxDecorations() || paintsChildren())
- return false;
-
- if (renderObject->isRenderRegion())
- return false;
-
- if (renderObject->node() && renderObject->node()->isDocumentNode()) {
- // Look to see if the root object has a non-simple background
- RenderObject* rootObject = renderObject->document().documentElement() ? renderObject->document().documentElement()->renderer() : 0;
- if (!rootObject)
- return false;
-
- RenderStyle* style = rootObject->style();
-
- // Reject anything that has a border, a border-radius or outline,
- // or is not a simple background (no background, or solid color).
- if (hasBoxDecorationsOrBackgroundImage(style))
- return false;
-
- // Now look at the body's renderer.
- HTMLElement* body = renderObject->document().body();
- RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
- if (!bodyObject)
- return false;
-
- style = bodyObject->style();
-
- if (hasBoxDecorationsOrBackgroundImage(style))
- return false;
- }
-
- return true;
-}
-
-static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
-{
- // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
- parent->stackingNode()->updateLayerListsIfNeeded();
-
-#if !ASSERT_DISABLED
- LayerListMutationDetector mutationChecker(parent->stackingNode());
-#endif
-
- RenderLayerStackingNodeIterator normalFlowIterator(*parent->stackingNode(), NormalFlowChildren);
- while (RenderLayerStackingNode* curNode = normalFlowIterator.next()) {
- RenderLayer* curLayer = curNode->layer();
- if (!curLayer->hasCompositedLayerMapping()
- && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
- return true;
- }
-
- if (!parent->hasVisibleDescendant())
- return false;
-
- RenderLayerStackingNodeIterator zOrderIterator(*parent->stackingNode(), NegativeZOrderChildren | PositiveZOrderChildren);
- while (RenderLayerStackingNode* curNode = zOrderIterator.next()) {
- RenderLayer* curLayer = curNode->layer();
- if (!curLayer->hasCompositedLayerMapping()
- && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
- return true;
- }
-
- return false;
-}
-
-// FIXME: By name the implementation is correct. But the code that uses this function means something
-// very slightly different - the implementation needs to also include composited descendants that
-// don't paint into their own backing, and instead paint into this backing.
-bool CompositedLayerMapping::hasVisibleNonCompositingDescendantLayers() const
-{
- return hasVisibleNonCompositingDescendant(m_owningLayer);
-}
-
-bool CompositedLayerMapping::containsPaintedContent(bool isSimpleContainer) const
-{
- if (isSimpleContainer || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
- return false;
-
- if (isDirectlyCompositedImage())
- return false;
-
- // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
- // and set background color on the layer in that case, instead of allocating backing store and painting.
- if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
- return m_owningLayer->hasBoxDecorationsOrBackground();
-
- return true;
-}
-
-// An image can be directly compositing if it's the sole content of the layer, and has no box decorations
-// that require painting. Direct compositing saves backing store.
-bool CompositedLayerMapping::isDirectlyCompositedImage() const
-{
- RenderObject* renderObject = renderer();
-
- if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground() || renderObject->hasClip())
- return false;
-
- RenderImage* imageRenderer = toRenderImage(renderObject);
- if (ImageResource* cachedImage = imageRenderer->cachedImage()) {
- if (!cachedImage->hasImage())
- return false;
-
- Image* image = cachedImage->imageForRenderer(imageRenderer);
- return image->isBitmapImage();
- }
-
- return false;
-}
-
-void CompositedLayerMapping::contentChanged(ContentChangeType changeType)
-{
- if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
- updateImageContents();
- return;
- }
-
- if ((changeType == MaskImageChanged) && m_maskLayer) {
- // The composited layer bounds relies on box->maskClipRect(), which changes
- // when the mask image becomes available.
- updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
- }
-
- if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && isAcceleratedCanvas(renderer())) {
- m_graphicsLayer->setContentsNeedsDisplay();
- return;
- }
-}
-
-void CompositedLayerMapping::updateImageContents()
-{
- ASSERT(renderer()->isImage());
- RenderImage* imageRenderer = toRenderImage(renderer());
-
- ImageResource* cachedImage = imageRenderer->cachedImage();
- if (!cachedImage)
- return;
-
- Image* image = cachedImage->imageForRenderer(imageRenderer);
- if (!image)
- return;
-
- // We have to wait until the image is fully loaded before setting it on the layer.
- if (!cachedImage->isLoaded())
- return;
-
- // This is a no-op if the layer doesn't have an inner layer for the image.
- m_graphicsLayer->setContentsToImage(image);
- bool isSimpleContainer = false;
- updateDrawsContent(isSimpleContainer);
-
- // Image animation is "lazy", in that it automatically stops unless someone is drawing
- // the image. So we have to kick the animation each time; this has the downside that the
- // image will keep animating, even if its layer is not visible.
- image->startAnimation();
-}
-
-FloatPoint3D CompositedLayerMapping::computeTransformOrigin(const IntRect& borderBox) const
-{
- RenderStyle* style = renderer()->style();
-
- FloatPoint3D origin;
- origin.setX(floatValueForLength(style->transformOriginX(), borderBox.width()));
- origin.setY(floatValueForLength(style->transformOriginY(), borderBox.height()));
- origin.setZ(style->transformOriginZ());
-
- return origin;
-}
-
-FloatPoint CompositedLayerMapping::computePerspectiveOrigin(const IntRect& borderBox) const
-{
- RenderStyle* style = renderer()->style();
-
- float boxWidth = borderBox.width();
- float boxHeight = borderBox.height();
-
- FloatPoint origin;
- origin.setX(floatValueForLength(style->perspectiveOriginX(), boxWidth));
- origin.setY(floatValueForLength(style->perspectiveOriginY(), boxHeight));
-
- return origin;
-}
-
-// Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
-IntSize CompositedLayerMapping::contentOffsetInCompostingLayer() const
-{
- return IntSize(-m_compositedBounds.x(), -m_compositedBounds.y());
-}
-
-IntRect CompositedLayerMapping::contentsBox() const
-{
- IntRect contentsBox = contentsRect(renderer());
- contentsBox.move(contentOffsetInCompostingLayer());
- return contentsBox;
-}
-
-IntRect CompositedLayerMapping::backgroundBox() const
-{
- IntRect backgroundBox = backgroundRect(renderer());
- backgroundBox.move(contentOffsetInCompostingLayer());
- return backgroundBox;
-}
-
-GraphicsLayer* CompositedLayerMapping::parentForSublayers() const
-{
- if (m_scrollingContentsLayer)
- return m_scrollingContentsLayer.get();
-
- return m_childContainmentLayer ? m_childContainmentLayer.get() : m_graphicsLayer.get();
-}
-
-GraphicsLayer* CompositedLayerMapping::childForSuperlayers() const
-{
- if (m_squashingContainmentLayer)
- return m_squashingContainmentLayer.get();
-
- if (m_ancestorClippingLayer)
- return m_ancestorClippingLayer.get();
-
- return m_graphicsLayer.get();
-}
-
-bool CompositedLayerMapping::updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer* compositingAncestorLayer)
-{
- bool previousRequiresOwnBackingStoreForAncestorReasons = m_requiresOwnBackingStoreForAncestorReasons;
- bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
- bool canPaintIntoAncestor = compositingAncestorLayer
- && (compositingAncestorLayer->compositedLayerMapping()->mainGraphicsLayer()->drawsContent()
- || compositingAncestorLayer->compositedLayerMapping()->paintsIntoCompositedAncestor());
- m_requiresOwnBackingStoreForAncestorReasons = !canPaintIntoAncestor;
-
- if (paintsIntoCompositedAncestor() != previousPaintsIntoCompositedAncestor)
- paintsIntoCompositedAncestorChanged();
- return m_requiresOwnBackingStoreForAncestorReasons != previousRequiresOwnBackingStoreForAncestorReasons;
-}
-
-bool CompositedLayerMapping::updateRequiresOwnBackingStoreForIntrinsicReasons()
-{
- bool previousRequiresOwnBackingStoreForIntrinsicReasons = m_requiresOwnBackingStoreForIntrinsicReasons;
- bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
- RenderObject* renderer = m_owningLayer->renderer();
- m_requiresOwnBackingStoreForIntrinsicReasons = m_owningLayer->isRootLayer()
- || (m_owningLayer->compositingReasons() & CompositingReasonComboReasonsThatRequireOwnBacking)
- || m_owningLayer->transform()
- || m_owningLayer->clipsCompositingDescendantsWithBorderRadius() // FIXME: Revisit this if the paintsIntoCompositedAncestor state is removed.
- || renderer->isTransparent()
- || renderer->hasMask()
- || renderer->hasReflection()
- || renderer->hasFilter();
-
- if (paintsIntoCompositedAncestor() != previousPaintsIntoCompositedAncestor)
- paintsIntoCompositedAncestorChanged();
- return m_requiresOwnBackingStoreForIntrinsicReasons != previousRequiresOwnBackingStoreForIntrinsicReasons;
-}
-
-void CompositedLayerMapping::paintsIntoCompositedAncestorChanged()
-{
- // The answer to paintsIntoCompositedAncestor() affects cached clip rects, so when
- // it changes we have to clear clip rects on descendants.
- m_owningLayer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
- m_owningLayer->repainter().computeRepaintRectsIncludingDescendants();
-
- compositor()->repaintInCompositedAncestor(m_owningLayer, compositedBounds());
-}
-
-void CompositedLayerMapping::setBlendMode(blink::WebBlendMode blendMode)
-{
- if (m_ancestorClippingLayer) {
- m_ancestorClippingLayer->setBlendMode(blendMode);
- m_graphicsLayer->setBlendMode(blink::WebBlendModeNormal);
- } else {
- m_graphicsLayer->setBlendMode(blendMode);
- }
-}
-
-void CompositedLayerMapping::setContentsNeedDisplay()
-{
- ASSERT(!paintsIntoCompositedAncestor());
-
- if (m_graphicsLayer && m_graphicsLayer->drawsContent())
- m_graphicsLayer->setNeedsDisplay();
-
- if (m_foregroundLayer && m_foregroundLayer->drawsContent())
- m_foregroundLayer->setNeedsDisplay();
-
- if (m_backgroundLayer && m_backgroundLayer->drawsContent())
- m_backgroundLayer->setNeedsDisplay();
-
- if (m_maskLayer && m_maskLayer->drawsContent())
- m_maskLayer->setNeedsDisplay();
-
- if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent())
- m_childClippingMaskLayer->setNeedsDisplay();
-
- if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent())
- m_scrollingContentsLayer->setNeedsDisplay();
-}
-
-// r is in the coordinate space of the layer's render object
-void CompositedLayerMapping::setContentsNeedDisplayInRect(const IntRect& r)
-{
- ASSERT(!paintsIntoCompositedAncestor());
-
- if (m_graphicsLayer && m_graphicsLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_graphicsLayer->offsetFromRenderer());
- m_graphicsLayer->setNeedsDisplayInRect(layerDirtyRect);
- }
-
- if (m_foregroundLayer && m_foregroundLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_foregroundLayer->offsetFromRenderer());
- m_foregroundLayer->setNeedsDisplayInRect(layerDirtyRect);
- }
-
- // FIXME: need to split out repaints for the background.
- if (m_backgroundLayer && m_backgroundLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_backgroundLayer->offsetFromRenderer());
- m_backgroundLayer->setNeedsDisplayInRect(layerDirtyRect);
- }
-
- if (m_maskLayer && m_maskLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_maskLayer->offsetFromRenderer());
- m_maskLayer->setNeedsDisplayInRect(layerDirtyRect);
- }
-
- if (m_childClippingMaskLayer && m_childClippingMaskLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_childClippingMaskLayer->offsetFromRenderer());
- m_childClippingMaskLayer->setNeedsDisplayInRect(layerDirtyRect);
- }
-
- if (m_scrollingContentsLayer && m_scrollingContentsLayer->drawsContent()) {
- IntRect layerDirtyRect = r;
- layerDirtyRect.move(-m_scrollingContentsLayer->offsetFromRenderer());
- m_scrollingContentsLayer->setNeedsDisplayInRect(layerDirtyRect);
- }
-}
-
-void CompositedLayerMapping::doPaintTask(GraphicsLayerPaintInfo& paintInfo, GraphicsContext* context,
- const IntRect& clip) // In the coords of rootLayer.
-{
- if (paintsIntoCompositedAncestor()) {
- ASSERT_NOT_REACHED();
- return;
- }
-
- FontCachePurgePreventer fontCachePurgePreventer;
-
- PaintLayerFlags paintFlags = 0;
- if (paintInfo.paintingPhase & GraphicsLayerPaintBackground)
- paintFlags |= PaintLayerPaintingCompositingBackgroundPhase;
- if (paintInfo.paintingPhase & GraphicsLayerPaintForeground)
- paintFlags |= PaintLayerPaintingCompositingForegroundPhase;
- if (paintInfo.paintingPhase & GraphicsLayerPaintMask)
- paintFlags |= PaintLayerPaintingCompositingMaskPhase;
- if (paintInfo.paintingPhase & GraphicsLayerPaintChildClippingMask)
- paintFlags |= PaintLayerPaintingChildClippingMaskPhase;
- if (paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents)
- paintFlags |= PaintLayerPaintingOverflowContents;
- if (paintInfo.paintingPhase & GraphicsLayerPaintCompositedScroll)
- paintFlags |= PaintLayerPaintingCompositingScrollingPhase;
-
- if (paintInfo.isBackgroundLayer)
- paintFlags |= (PaintLayerPaintingRootBackgroundOnly | PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
- else if (compositor()->fixedRootBackgroundLayer())
- paintFlags |= PaintLayerPaintingSkipRootBackground;
-
- // Note carefully: in theory it is appropriate to invoke context->save() here
- // and restore the context after painting. For efficiency, we are assuming that
- // it is equivalent to manually undo this offset translation, which means we are
- // assuming that the context's space was not affected by the RenderLayer
- // painting code.
-
- LayoutSize offset = paintInfo.offsetFromRenderer;
- context->translate(-offset);
- LayoutRect relativeClip(clip);
- relativeClip.move(offset);
-
- // The dirtyRect is in the coords of the painting root.
- IntRect dirtyRect = pixelSnappedIntRect(relativeClip);
- if (!(paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents))
- dirtyRect.intersect(paintInfo.compositedBounds);
-
-#ifndef NDEBUG
- paintInfo.renderLayer->renderer()->assertSubtreeIsLaidOut();
-#endif
-
- if (paintInfo.renderLayer->compositingState() != PaintsIntoGroupedBacking) {
- // FIXME: GraphicsLayers need a way to split for RenderRegions.
- LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize());
- paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags);
-
- ASSERT(!paintInfo.isBackgroundLayer || paintFlags & PaintLayerPaintingRootBackgroundOnly);
-
- if (paintInfo.renderLayer->containsDirtyOverlayScrollbars())
- paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags | PaintLayerPaintingOverlayScrollbars);
- } else {
- ASSERT(compositor()->layerSquashingEnabled());
- LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, LayoutSize());
- paintInfo.renderLayer->paintLayer(context, paintingInfo, paintFlags);
- }
-
- ASSERT(!paintInfo.renderLayer->m_usedTransparency);
-
- // Manually restore the context to its original state by applying the opposite translation.
- context->translate(offset);
-}
-
-static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
-{
- if (!scrollbar)
- return;
-
- context.save();
- const IntRect& scrollbarRect = scrollbar->frameRect();
- context.translate(-scrollbarRect.x(), -scrollbarRect.y());
- IntRect transformedClip = clip;
- transformedClip.moveBy(scrollbarRect.location());
- scrollbar->paint(&context, transformedClip);
- context.restore();
-}
-
-// Up-call from compositing layer drawing callback.
-void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
-{
-#ifndef NDEBUG
- if (Page* page = renderer()->frame()->page())
- page->setIsPainting(true);
-#endif
- InspectorInstrumentation::willPaint(m_owningLayer->renderer(), graphicsLayer);
-
- if (graphicsLayer == m_graphicsLayer.get()
- || graphicsLayer == m_foregroundLayer.get()
- || graphicsLayer == m_backgroundLayer.get()
- || graphicsLayer == m_maskLayer.get()
- || graphicsLayer == m_childClippingMaskLayer.get()
- || graphicsLayer == m_scrollingContentsLayer.get()) {
-
- GraphicsLayerPaintInfo paintInfo;
- paintInfo.renderLayer = m_owningLayer;
- paintInfo.compositedBounds = compositedBounds();
- paintInfo.offsetFromRenderer = graphicsLayer->offsetFromRenderer();
- paintInfo.paintingPhase = paintingPhase;
- paintInfo.isBackgroundLayer = (graphicsLayer == m_backgroundLayer);
-
- // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
- doPaintTask(paintInfo, &context, clip);
- } else if (graphicsLayer == m_squashingLayer.get()) {
- ASSERT(compositor()->layerSquashingEnabled());
- for (size_t i = 0; i < m_squashedLayers.size(); ++i)
- doPaintTask(m_squashedLayers[i], &context, clip);
- } else if (graphicsLayer == layerForHorizontalScrollbar()) {
- paintScrollbar(m_owningLayer->scrollableArea()->horizontalScrollbar(), context, clip);
- } else if (graphicsLayer == layerForVerticalScrollbar()) {
- paintScrollbar(m_owningLayer->scrollableArea()->verticalScrollbar(), context, clip);
- } else if (graphicsLayer == layerForScrollCorner()) {
- const IntRect& scrollCornerAndResizer = m_owningLayer->scrollableArea()->scrollCornerAndResizerRect();
- context.save();
- context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
- IntRect transformedClip = clip;
- transformedClip.moveBy(scrollCornerAndResizer.location());
- m_owningLayer->scrollableArea()->paintScrollCorner(&context, IntPoint(), transformedClip);
- m_owningLayer->scrollableArea()->paintResizer(&context, IntPoint(), transformedClip);
- context.restore();
- }
- InspectorInstrumentation::didPaint(m_owningLayer->renderer(), graphicsLayer, &context, clip);
-#ifndef NDEBUG
- if (Page* page = renderer()->frame()->page())
- page->setIsPainting(false);
-#endif
-}
-
-void CompositedLayerMapping::didCommitChangesForLayer(const GraphicsLayer* layer) const
-{
-}
-
-bool CompositedLayerMapping::getCurrentTransform(const GraphicsLayer* graphicsLayer, TransformationMatrix& transform) const
-{
- if (graphicsLayer != m_graphicsLayer.get())
- return false;
-
- if (m_owningLayer->hasTransform()) {
- transform = m_owningLayer->currentTransform(RenderStyle::ExcludeTransformOrigin);
- return true;
- }
- return false;
-}
-
-bool CompositedLayerMapping::isTrackingRepaints() const
-{
- GraphicsLayerClient* client = compositor();
- return client ? client->isTrackingRepaints() : false;
-}
-
-static void collectTrackedRepaintRectsForGraphicsLayer(GraphicsLayer* graphicsLayer, Vector<FloatRect>& rects)
-{
- if (graphicsLayer)
- graphicsLayer->collectTrackedRepaintRects(rects);
-}
-
-PassOwnPtr<Vector<FloatRect> > CompositedLayerMapping::collectTrackedRepaintRects() const
-{
- OwnPtr<Vector<FloatRect> > rects = adoptPtr(new Vector<FloatRect>);
- collectTrackedRepaintRectsForGraphicsLayer(m_ancestorClippingLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_graphicsLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_childContainmentLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_scrollingLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_scrollingContentsLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_maskLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_childClippingMaskLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_foregroundLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_backgroundLayer.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_layerForHorizontalScrollbar.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_layerForVerticalScrollbar.get(), *rects);
- collectTrackedRepaintRectsForGraphicsLayer(m_layerForScrollCorner.get(), *rects);
- return rects.release();
-}
-
-#ifndef NDEBUG
-void CompositedLayerMapping::verifyNotPainting()
-{
- ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPainting());
-}
-#endif
-
-bool CompositedLayerMapping::startAnimation(double timeOffset, const CSSAnimationData* anim, const KeyframeList& keyframes)
-{
- bool hasTransform = renderer()->isBox() && keyframes.containsProperty(CSSPropertyWebkitTransform);
- IntSize boxSize;
- if (hasTransform)
- boxSize = toRenderBox(renderer())->pixelSnappedBorderBoxRect().size();
- WebAnimations animations(m_animationProvider->startAnimation(timeOffset, anim, keyframes, hasTransform, boxSize));
- if (animations.isEmpty())
- return false;
-
- bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
- bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
- int animationId = m_animationProvider->getWebAnimationId(keyframes.animationName());
-
- // Animating only some properties of the animation is not supported. So if the
- // GraphicsLayer rejects any property of the animation, we have to remove the
- // animation and return false to indicate un-accelerated animation is required.
- if (hasTransform) {
- if (!animations.m_transformAnimation || !m_graphicsLayer->addAnimation(animations.m_transformAnimation.release()))
- return false;
- }
- if (hasOpacity) {
- if (!animations.m_opacityAnimation || !m_graphicsLayer->addAnimation(animations.m_opacityAnimation.release())) {
- if (hasTransform)
- m_graphicsLayer->removeAnimation(animationId);
- return false;
- }
- }
- if (hasFilter) {
- if (!animations.m_filterAnimation || !m_graphicsLayer->addAnimation(animations.m_filterAnimation.release())) {
- if (hasTransform || hasOpacity)
- m_graphicsLayer->removeAnimation(animationId);
- return false;
- }
- }
- return true;
-}
-
-void CompositedLayerMapping::animationPaused(double timeOffset, const String& animationName)
-{
- int animationId = m_animationProvider->getWebAnimationId(animationName);
- ASSERT(animationId);
- m_graphicsLayer->pauseAnimation(animationId, timeOffset);
-}
-
-void CompositedLayerMapping::animationFinished(const String& animationName)
-{
- int animationId = m_animationProvider->getWebAnimationId(animationName);
- ASSERT(animationId);
- m_graphicsLayer->removeAnimation(animationId);
-}
-
-bool CompositedLayerMapping::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle)
-{
- ASSERT(property != CSSPropertyInvalid);
- IntSize boxSize;
- if (property == CSSPropertyWebkitTransform && m_owningLayer->hasTransform()) {
- ASSERT(renderer()->isBox());
- boxSize = toRenderBox(renderer())->pixelSnappedBorderBoxRect().size();
- }
- float fromOpacity = 0;
- float toOpacity = 0;
- if (property == CSSPropertyOpacity) {
- fromOpacity = compositingOpacity(fromStyle->opacity());
- toOpacity = compositingOpacity(toStyle->opacity());
- }
-
- // Although KeyframeAnimation can have multiple properties of the animation, ImplicitAnimation (= Transition) has only one animation property.
- WebAnimations animations(m_animationProvider->startTransition(timeOffset, property, fromStyle,
- toStyle, m_owningLayer->hasTransform(), m_owningLayer->hasFilter(), boxSize, fromOpacity, toOpacity));
- if (animations.m_transformAnimation && m_graphicsLayer->addAnimation(animations.m_transformAnimation.release())) {
- // To ensure that the correct transform is visible when the animation ends, also set the final transform.
- updateTransform(toStyle);
- return true;
- }
- if (animations.m_opacityAnimation && m_graphicsLayer->addAnimation(animations.m_opacityAnimation.release())) {
- // To ensure that the correct opacity is visible when the animation ends, also set the final opacity.
- updateOpacity(toStyle);
- return true;
- }
- if (animations.m_filterAnimation && m_graphicsLayer->addAnimation(animations.m_filterAnimation.release())) {
- // To ensure that the correct filter is visible when the animation ends, also set the final filter.
- updateFilters(toStyle);
- return true;
- }
-
- return false;
-}
-
-void CompositedLayerMapping::transitionPaused(double timeOffset, CSSPropertyID property)
-{
- int animationId = m_animationProvider->getWebAnimationId(property);
- ASSERT(animationId);
- m_graphicsLayer->pauseAnimation(animationId, timeOffset);
-}
-
-void CompositedLayerMapping::transitionFinished(CSSPropertyID property)
-{
- int animationId = m_animationProvider->getWebAnimationId(property);
- ASSERT(animationId);
- m_graphicsLayer->removeAnimation(animationId);
-}
-
-void CompositedLayerMapping::notifyAnimationStarted(const GraphicsLayer*, double wallClockTime, double monotonicTime)
-{
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- renderer()->node()->document().cssPendingAnimations().notifyCompositorAnimationStarted(monotonicTime);
- else
- renderer()->animation().notifyAnimationStarted(renderer(), wallClockTime);
-}
-
-IntRect CompositedLayerMapping::compositedBounds() const
-{
- return m_compositedBounds;
-}
-
-void CompositedLayerMapping::setCompositedBounds(const IntRect& bounds)
-{
- m_compositedBounds = bounds;
-}
-
-void CompositedLayerMapping::addRenderLayerToSquashingGraphicsLayer(RenderLayer* layer, IntSize offsetFromTargetBacking, size_t nextSquashedLayerIndex)
-{
- ASSERT(compositor()->layerSquashingEnabled());
-
- GraphicsLayerPaintInfo paintInfo;
- paintInfo.renderLayer = layer;
- // NOTE: composited bounds are updated elsewhere
- // NOTE: offsetFromRenderer is updated elsewhere
- paintInfo.offsetFromBackingRoot = offsetFromTargetBacking;
- paintInfo.paintingPhase = GraphicsLayerPaintAllWithOverflowClip;
- paintInfo.isBackgroundLayer = false;
-
- // Change tracking on squashing layers: at the first sign of something changed, just invalidate the layer.
- // FIXME: Perhaps we can find a tighter more clever mechanism later.
- if (nextSquashedLayerIndex < m_squashedLayers.size()) {
- if (m_squashedLayers[nextSquashedLayerIndex].renderLayer != layer) {
- m_squashedLayers[nextSquashedLayerIndex] = paintInfo;
- if (m_squashingLayer)
- m_squashingLayer->setNeedsDisplay();
- }
- } else {
- m_squashedLayers.append(paintInfo);
- if (m_squashingLayer)
- m_squashingLayer->setNeedsDisplay();
- }
- layer->setGroupedMapping(this);
-}
-
-void CompositedLayerMapping::finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex)
-{
- ASSERT(compositor()->layerSquashingEnabled());
-
- // Any additional squashed RenderLayers in the array no longer exist, and removing invalidates the squashingLayer contents.
- if (nextSquashedLayerIndex < m_squashedLayers.size()) {
- m_squashedLayers.remove(nextSquashedLayerIndex, m_squashedLayers.size() - nextSquashedLayerIndex);
- if (m_squashingLayer)
- m_squashingLayer->setNeedsDisplay();
- }
-}
-
-CompositingLayerType CompositedLayerMapping::compositingLayerType() const
-{
- if (m_graphicsLayer->hasContentsLayer())
- return MediaCompositingLayer;
-
- if (m_graphicsLayer->drawsContent())
- return NormalCompositingLayer;
-
- return ContainerCompositingLayer;
-}
-
-double CompositedLayerMapping::backingStoreMemoryEstimate() const
-{
- double backingMemory;
-
- // m_ancestorClippingLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
- backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
- if (m_foregroundLayer)
- backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
- if (m_backgroundLayer)
- backingMemory += m_backgroundLayer->backingStoreMemoryEstimate();
- if (m_maskLayer)
- backingMemory += m_maskLayer->backingStoreMemoryEstimate();
- if (m_childClippingMaskLayer)
- backingMemory += m_childClippingMaskLayer->backingStoreMemoryEstimate();
-
- if (m_scrollingContentsLayer)
- backingMemory += m_scrollingContentsLayer->backingStoreMemoryEstimate();
-
- if (m_layerForHorizontalScrollbar)
- backingMemory += m_layerForHorizontalScrollbar->backingStoreMemoryEstimate();
-
- if (m_layerForVerticalScrollbar)
- backingMemory += m_layerForVerticalScrollbar->backingStoreMemoryEstimate();
-
- if (m_layerForScrollCorner)
- backingMemory += m_layerForScrollCorner->backingStoreMemoryEstimate();
-
- return backingMemory;
-}
-
-String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer)
-{
- String name;
- if (graphicsLayer == m_graphicsLayer.get()) {
- name = m_owningLayer->debugName();
- } else if (graphicsLayer == m_ancestorClippingLayer.get()) {
- name = "Ancestor Clipping Layer";
- } else if (graphicsLayer == m_foregroundLayer.get()) {
- name = m_owningLayer->debugName() + " (foreground) Layer";
- } else if (graphicsLayer == m_backgroundLayer.get()) {
- name = m_owningLayer->debugName() + " (background) Layer";
- } else if (graphicsLayer == m_childContainmentLayer.get()) {
- name = "Child Containment Layer";
- } else if (graphicsLayer == m_maskLayer.get()) {
- name = "Mask Layer";
- } else if (graphicsLayer == m_childClippingMaskLayer.get()) {
- name = "Child Clipping Mask Layer";
- } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
- name = "Horizontal Scrollbar Layer";
- } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
- name = "Vertical Scrollbar Layer";
- } else if (graphicsLayer == m_layerForScrollCorner.get()) {
- name = "Scroll Corner Layer";
- } else if (graphicsLayer == m_scrollingLayer.get()) {
- name = "Scrolling Layer";
- } else if (graphicsLayer == m_scrollingContentsLayer.get()) {
- name = "Scrolling Contents Layer";
- } else {
- ASSERT_NOT_REACHED();
- }
-
- return name;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMapping.h b/chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMapping.h
deleted file mode 100644
index b0f85e44d0e..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMapping.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CompositedLayerMapping_h
-#define CompositedLayerMapping_h
-
-#include "core/rendering/RenderLayer.h"
-#include "platform/geometry/FloatPoint.h"
-#include "platform/geometry/FloatPoint3D.h"
-#include "platform/graphics/GraphicsLayer.h"
-#include "platform/graphics/GraphicsLayerClient.h"
-#include "platform/transforms/TransformationMatrix.h"
-
-namespace WebCore {
-
-class KeyframeList;
-class RenderLayerCompositor;
-class WebAnimationProvider;
-
-enum CompositingLayerType {
- NormalCompositingLayer, // non-tiled layer with backing store
- MediaCompositingLayer, // layer that contains an image, video, webGL or plugin
- ContainerCompositingLayer // layer with no backing store
-};
-
-
-// A GraphicsLayerPaintInfo contains all the info needed to paint a partial subtree of RenderLayers into a GraphicsLayer.
-struct GraphicsLayerPaintInfo {
- RenderLayer* renderLayer;
-
- IntRect compositedBounds;
-
- // A temporary offset used for squashing layers, when the origin of the
- // squashing layer is not yet known.
- IntSize offsetFromBackingRoot;
-
- IntSize offsetFromRenderer;
-
- GraphicsLayerPaintingPhase paintingPhase;
-
- bool isBackgroundLayer;
-};
-
-// CompositedLayerMapping keeps track of how RenderLayers of the render tree correspond to
-// GraphicsLayers of the composited layer tree. Each instance of CompositedLayerMapping
-// manages a small cluster of GraphicsLayers and the references to which RenderLayers
-// and paint phases contribute to each GraphicsLayer.
-//
-// Currently (Oct. 2013) there is one CompositedLayerMapping for each RenderLayer,
-// but this is likely to evolve soon.
-class CompositedLayerMapping : public GraphicsLayerClient {
- WTF_MAKE_NONCOPYABLE(CompositedLayerMapping); WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit CompositedLayerMapping(RenderLayer*);
- ~CompositedLayerMapping();
-
- RenderLayer* owningLayer() const { return m_owningLayer; }
-
- enum UpdateAfterLayoutFlag {
- CompositingChildrenOnly = 1 << 0,
- NeedsFullRepaint = 1 << 1,
- IsUpdateRoot = 1 << 2
- };
- typedef unsigned UpdateAfterLayoutFlags;
- void updateAfterLayout(UpdateAfterLayoutFlags);
-
- // Returns true if layer configuration changed.
- bool updateGraphicsLayerConfiguration();
- // Update graphics layer position and bounds.
- void updateGraphicsLayerGeometry(); // make private
- // Update whether layer needs blending.
- void updateContentsOpaque();
-
- GraphicsLayer* mainGraphicsLayer() const { return m_graphicsLayer.get(); }
-
- // Layer to clip children
- bool hasClippingLayer() const { return m_childContainmentLayer; }
- GraphicsLayer* clippingLayer() const { return m_childContainmentLayer.get(); }
-
- // Layer to get clipped by ancestor
- bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer; }
- GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer.get(); }
-
- bool hasContentsLayer() const { return m_foregroundLayer; }
- GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); }
-
- GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); }
- bool backgroundLayerPaintsFixedRootBackground() const { return m_backgroundLayerPaintsFixedRootBackground; }
-
- bool hasScrollingLayer() const { return m_scrollingLayer; }
- GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
- GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); }
-
- bool hasMaskLayer() const { return m_maskLayer; }
- bool hasChildClippingMaskLayer() const { return m_childClippingMaskLayer; }
-
- GraphicsLayer* parentForSublayers() const;
- GraphicsLayer* childForSuperlayers() const;
-
- GraphicsLayer* squashingLayer() const { return m_squashingLayer.get(); }
-
- // Returns true for a composited layer that has no backing store of its own, so
- // paints into some ancestor layer.
- bool paintsIntoCompositedAncestor() const { return !(m_requiresOwnBackingStoreForAncestorReasons || m_requiresOwnBackingStoreForIntrinsicReasons); }
-
- // Updates whether a backing store is needed based on the layer's compositing ancestor's
- // properties; returns true if the need for a backing store for ancestor reasons changed.
- bool updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer* compositingAncestor);
-
- // Updates whether a backing store is needed for intrinsic reasons (that is, based on the
- // layer's own properties or compositing reasons); returns true if the intrinsic need for
- // a backing store changed.
- bool updateRequiresOwnBackingStoreForIntrinsicReasons();
-
- void setContentsNeedDisplay();
- // r is in the coordinate space of the layer's render object
- void setContentsNeedDisplayInRect(const IntRect&);
-
- // Notification from the renderer that its content changed.
- void contentChanged(ContentChangeType);
-
- // Interface to start, finish, suspend and resume animations and transitions
- bool startTransition(double, CSSPropertyID, const RenderStyle* fromStyle, const RenderStyle* toStyle);
- void transitionPaused(double timeOffset, CSSPropertyID);
- void transitionFinished(CSSPropertyID);
-
- bool startAnimation(double timeOffset, const CSSAnimationData*, const KeyframeList& keyframes);
- void animationPaused(double timeOffset, const String& name);
- void animationFinished(const String& name);
-
- IntRect compositedBounds() const;
- void setCompositedBounds(const IntRect&);
- void updateCompositedBounds();
-
- void updateAfterWidgetResize();
- void positionOverflowControlsLayers(const IntSize& offsetFromRoot);
- bool hasUnpositionedOverflowControlsLayers() const;
-
- void addRenderLayerToSquashingGraphicsLayer(RenderLayer*, IntSize offsetFromTargetBacking, size_t nextSquashedLayerIndex);
- void finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex);
-
- // GraphicsLayerClient interface
- virtual void notifyAnimationStarted(const GraphicsLayer*, double wallClockTime, double monotonicTime) OVERRIDE;
-
- virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip) OVERRIDE;
-
- virtual void didCommitChangesForLayer(const GraphicsLayer*) const OVERRIDE;
- virtual bool getCurrentTransform(const GraphicsLayer*, TransformationMatrix&) const OVERRIDE;
-
- virtual bool isTrackingRepaints() const OVERRIDE;
-
- PassOwnPtr<Vector<FloatRect> > collectTrackedRepaintRects() const;
-
-#ifndef NDEBUG
- virtual void verifyNotPainting();
-#endif
-
- IntRect contentsBox() const;
- IntRect backgroundBox() const;
-
- // For informative purposes only.
- CompositingLayerType compositingLayerType() const;
-
- GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
- GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
- GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
-
- void updateFilters(const RenderStyle*);
- bool canCompositeFilters() const { return m_canCompositeFilters; }
-
- // Return an estimate of the backing store area (in pixels) allocated by this object's GraphicsLayers.
- double backingStoreMemoryEstimate() const;
-
- void setBlendMode(blink::WebBlendMode);
-
- virtual String debugName(const GraphicsLayer*) OVERRIDE;
-
-private:
- void createPrimaryGraphicsLayer();
- void destroyGraphicsLayers();
-
- PassOwnPtr<GraphicsLayer> createGraphicsLayer(CompositingReasons);
-
- RenderLayerModelObject* renderer() const { return m_owningLayer->renderer(); }
- RenderLayerCompositor* compositor() const { return m_owningLayer->compositor(); }
-
- void updateInternalHierarchy();
- bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
- bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer);
- bool updateForegroundLayer(bool needsForegroundLayer);
- bool updateBackgroundLayer(bool needsBackgroundLayer);
- bool updateMaskLayer(bool needsMaskLayer);
- bool updateClippingMaskLayers(bool needsChildClippingMaskLayer);
- bool requiresHorizontalScrollbarLayer() const { return m_owningLayer->scrollableArea() && m_owningLayer->scrollableArea()->horizontalScrollbar(); }
- bool requiresVerticalScrollbarLayer() const { return m_owningLayer->scrollableArea() && m_owningLayer->scrollableArea()->verticalScrollbar(); }
- bool requiresScrollCornerLayer() const { return m_owningLayer->scrollableArea() && !m_owningLayer->scrollableArea()->scrollCornerAndResizerRect().isEmpty(); }
- bool updateScrollingLayers(bool scrollingLayers);
- void updateScrollParent(RenderLayer*);
- void updateClipParent(RenderLayer*);
- bool updateSquashingLayers(bool needsSquashingLayers);
- void updateDrawsContent(bool isSimpleContainer);
- void registerScrollingLayers();
-
- void setBackgroundLayerPaintsFixedRootBackground(bool);
-
- GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const;
-
- IntSize contentOffsetInCompostingLayer() const;
- // Result is transform origin in pixels.
- FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const;
- // Result is perspective origin in pixels.
- FloatPoint computePerspectiveOrigin(const IntRect& borderBox) const;
-
- void updateOpacity(const RenderStyle*);
- void updateTransform(const RenderStyle*);
- void updateLayerBlendMode(const RenderStyle*);
- void updateIsRootForIsolatedGroup();
- // Return the opacity value that this layer should use for compositing.
- float compositingOpacity(float rendererOpacity) const;
-
- bool isMainFrameRenderViewLayer() const;
-
- bool paintsBoxDecorations() const;
- bool paintsChildren() const;
-
- // Returns true if this compositing layer has no visible content.
- bool isSimpleContainerCompositingLayer() const;
- // Returns true if this layer has content that needs to be rendered by painting into the backing store.
- bool containsPaintedContent(bool isSimpleContainer) const;
- // Returns true if the RenderLayer just contains an image that we can composite directly.
- bool isDirectlyCompositedImage() const;
- void updateImageContents();
-
- Color rendererBackgroundColor() const;
- void updateBackgroundColor(bool isSimpleContainer);
- void updateContentsRect(bool isSimpleContainer);
-
- void updateCompositingReasons();
-
- bool hasVisibleNonCompositingDescendantLayers() const;
-
- bool shouldClipCompositedBounds() const;
-
- void paintsIntoCompositedAncestorChanged();
-
- void doPaintTask(GraphicsLayerPaintInfo&, GraphicsContext*, const IntRect& clip);
-
- RenderLayer* m_owningLayer;
-
- // The hierarchy of layers that is maintained by the CompositedLayerMapping looks like this:
- //
- // + m_ancestorClippingLayer [OPTIONAL]
- // + m_graphicsLayer
- // + m_childContainmentLayer [OPTIONAL] <-OR-> m_scrollingLayer [OPTIONAL]
- // + m_scrollingContentsLayer [OPTIONAL]
- //
- // We need an ancestor clipping layer if our clipping ancestor is not our ancestor in the
- // clipping tree. Here's what that might look like.
- //
- // Let A = the clipping ancestor,
- // B = the clip descendant, and
- // SC = the stacking context that is the ancestor of A and B in the stacking tree.
- //
- // SC
- // + A = m_graphicsLayer
- // | + m_childContainmentLayer
- // | + ...
- // ...
- // |
- // + B = m_ancestorClippingLayer [+]
- // + m_graphicsLayer
- // + ...
- //
- // In this case B is clipped by another layer that doesn't happen to be its ancestor: A.
- // So we create an ancestor clipping layer for B, [+], which ensures that B is clipped
- // as if it had been A's descendant.
- OwnPtr<GraphicsLayer> m_ancestorClippingLayer; // Only used if we are clipped by an ancestor which is not a stacking context.
- OwnPtr<GraphicsLayer> m_graphicsLayer;
- OwnPtr<GraphicsLayer> m_childContainmentLayer; // Only used if we have clipping on a stacking context with compositing children.
- OwnPtr<GraphicsLayer> m_scrollingLayer; // Only used if the layer is using composited scrolling.
- OwnPtr<GraphicsLayer> m_scrollingContentsLayer; // Only used if the layer is using composited scrolling.
-
- // This layer is also added to the hierarchy by the RLB, but in a different way than
- // the layers above. It's added to m_graphicsLayer as its mask layer (naturally) if
- // we have a mask, and isn't part of the typical hierarchy (it has no children).
- OwnPtr<GraphicsLayer> m_maskLayer; // Only used if we have a mask.
- OwnPtr<GraphicsLayer> m_childClippingMaskLayer; // Only used if we have to clip child layers or accelerated contents with border radius or clip-path.
-
- // There are two other (optional) layers whose painting is managed by the CompositedLayerMapping,
- // but whose position in the hierarchy is maintained by the RenderLayerCompositor. These
- // are the foreground and background layers. The foreground layer exists if we have composited
- // descendants with negative z-order. We need the extra layer in this case because the layer
- // needs to draw both below (for the background, say) and above (for the normal flow content, say)
- // the negative z-order descendants and this is impossible with a single layer. The RLC handles
- // inserting m_foregroundLayer in the correct position in our descendant list for us (right after
- // the neg z-order dsecendants).
- //
- // The background layer is only created if this is the root layer and our background is entirely
- // fixed. In this case we want to put the background in a separate composited layer so that when
- // we scroll, we don't have to re-raster the background into position. This layer is also inserted
- // into the tree by the RLC as it gets a special home. This layer becomes a descendant of the
- // frame clipping layer. That is:
- // ...
- // + frame clipping layer
- // + m_backgroundLayer
- // + frame scrolling layer
- // + root content layer
- //
- // With the hierarchy set up like this, the root content layer is able to scroll without affecting
- // the background layer (or repainting).
- OwnPtr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately.
- OwnPtr<GraphicsLayer> m_backgroundLayer; // Only used in cases where we need to draw the background separately.
-
- OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
- OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
- OwnPtr<GraphicsLayer> m_layerForScrollCorner;
-
- OwnPtr<WebAnimationProvider> m_animationProvider;
-
- OwnPtr<GraphicsLayer> m_squashingContainmentLayer; // Only used if any squashed layers exist, to contain the squashed layers as siblings to the rest of the GraphicsLayer tree chunk.
- OwnPtr<GraphicsLayer> m_squashingLayer; // Only used if any squashed layers exist, this is the backing that squashed layers paint into.
- Vector<GraphicsLayerPaintInfo> m_squashedLayers;
-
- IntRect m_compositedBounds;
-
- bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
- bool m_boundsConstrainedByClipping;
- bool m_isMainFrameRenderViewLayer;
- bool m_requiresOwnBackingStoreForIntrinsicReasons;
- bool m_requiresOwnBackingStoreForAncestorReasons;
- bool m_canCompositeFilters;
- bool m_backgroundLayerPaintsFixedRootBackground;
-};
-
-} // namespace WebCore
-
-#endif // CompositedLayerMapping_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/CompositingReasons.h b/chromium/third_party/WebKit/Source/core/rendering/CompositingReasons.h
deleted file mode 100644
index 8b023a724f8..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/CompositingReasons.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CompositingReasons_h
-#define CompositingReasons_h
-
-#include "wtf/MathExtras.h"
-#include <stdint.h>
-
-namespace WebCore {
-
-const uint64_t CompositingReasonNone = 0;
-
-// Intrinsic reasons that can be known right away by the layer
-const uint64_t CompositingReason3DTransform = UINT64_C(1) << 0;
-const uint64_t CompositingReasonVideo = UINT64_C(1) << 1;
-const uint64_t CompositingReasonCanvas = UINT64_C(1) << 2;
-const uint64_t CompositingReasonPlugin = UINT64_C(1) << 3;
-const uint64_t CompositingReasonIFrame = UINT64_C(1) << 4;
-const uint64_t CompositingReasonBackfaceVisibilityHidden = UINT64_C(1) << 5;
-const uint64_t CompositingReasonAnimation = UINT64_C(1) << 6;
-const uint64_t CompositingReasonFilters = UINT64_C(1) << 7;
-const uint64_t CompositingReasonPositionFixed = UINT64_C(1) << 8;
-const uint64_t CompositingReasonPositionSticky = UINT64_C(1) << 9;
-const uint64_t CompositingReasonOverflowScrollingTouch = UINT64_C(1) << 10;
-
-// Overlap reasons that require knowing what's behind you in paint-order before knowing the answer
-const uint64_t CompositingReasonAssumedOverlap = UINT64_C(1) << 12;
-const uint64_t CompositingReasonOverlap = UINT64_C(1) << 13;
-const uint64_t CompositingReasonNegativeZIndexChildren = UINT64_C(1) << 14;
-
-// Subtree reasons that require knowing what the status of your subtree is before knowing the answer
-const uint64_t CompositingReasonTransformWithCompositedDescendants = UINT64_C(1) << 15;
-const uint64_t CompositingReasonOpacityWithCompositedDescendants = UINT64_C(1) << 16;
-const uint64_t CompositingReasonMaskWithCompositedDescendants = UINT64_C(1) << 17;
-const uint64_t CompositingReasonReflectionWithCompositedDescendants = UINT64_C(1) << 18;
-const uint64_t CompositingReasonFilterWithCompositedDescendants = UINT64_C(1) << 19;
-const uint64_t CompositingReasonBlendingWithCompositedDescendants = UINT64_C(1) << 20;
-const uint64_t CompositingReasonClipsCompositingDescendants = UINT64_C(1) << 21;
-const uint64_t CompositingReasonPerspective = UINT64_C(1) << 22;
-const uint64_t CompositingReasonPreserve3D = UINT64_C(1) << 23;
-const uint64_t CompositingReasonReflectionOfCompositedParent = UINT64_C(1) << 24;
-
-// The root layer is a special case that may be forced to be a layer, but also it needs to be
-// a layer if anything else in the subtree is composited.
-const uint64_t CompositingReasonRoot = UINT64_C(1) << 25;
-
-// CompositedLayerMapping internal hierarchy reasons
-const uint64_t CompositingReasonLayerForClip = UINT64_C(1) << 26;
-const uint64_t CompositingReasonLayerForScrollbar = UINT64_C(1) << 27;
-const uint64_t CompositingReasonLayerForScrollingContainer = UINT64_C(1) << 28;
-const uint64_t CompositingReasonLayerForForeground = UINT64_C(1) << 29;
-const uint64_t CompositingReasonLayerForBackground = UINT64_C(1) << 30;
-const uint64_t CompositingReasonLayerForMask = UINT64_C(1) << 31;
-
-// FIXME: the following compositing reasons need to be re-organized to fit with categories
-// used in all the other reasons above.
-const uint64_t CompositingReasonOverflowScrollingParent = UINT64_C(1) << 32;
-const uint64_t CompositingReasonOutOfFlowClipping = UINT64_C(1) << 33;
-
-const uint64_t CompositingReasonLayerForVideoOverlay = UINT64_C(1) << 34;
-const uint64_t CompositingReasonIsolateCompositedDescendants = UINT64_C(1) << 35;
-
-// Note: if you add more reasons here, you will need to update WebCompositingReasons as well.
-
-// Various combinations of compositing reasons are defined here also, for more intutive and faster bitwise logic.
-const uint64_t CompositingReasonComboAllDirectReasons =
- CompositingReason3DTransform
- | CompositingReasonVideo
- | CompositingReasonCanvas
- | CompositingReasonPlugin
- | CompositingReasonIFrame
- | CompositingReasonBackfaceVisibilityHidden
- | CompositingReasonAnimation
- | CompositingReasonFilters
- | CompositingReasonPositionFixed
- | CompositingReasonPositionSticky
- | CompositingReasonOverflowScrollingTouch
- | CompositingReasonOverflowScrollingParent
- | CompositingReasonOutOfFlowClipping;
-
-const uint64_t CompositingReasonComboReasonsThatRequireOwnBacking =
- CompositingReasonComboAllDirectReasons
- | CompositingReasonOverlap
- | CompositingReasonAssumedOverlap
- | CompositingReasonNegativeZIndexChildren
- | CompositingReasonTransformWithCompositedDescendants
- | CompositingReasonOpacityWithCompositedDescendants
- | CompositingReasonMaskWithCompositedDescendants
- | CompositingReasonFilterWithCompositedDescendants
- | CompositingReasonBlendingWithCompositedDescendants
- | CompositingReasonIsolateCompositedDescendants
- | CompositingReasonPreserve3D; // preserve-3d has to create backing store to ensure that 3d-transformed elements intersect.
-
-const uint64_t CompositingReasonComboAllOverlapReasons =
- CompositingReasonOverlap
- | CompositingReasonAssumedOverlap;
-
-typedef uint64_t CompositingReasons;
-
-
-} // namespace WebCore
-
-#endif // CompositingReasons_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.cpp
index 9051eb20342..9f3e0262827 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.cpp
@@ -27,7 +27,7 @@
#include "core/rendering/RootInlineBox.h"
#include "core/rendering/style/ShadowList.h"
#include "platform/fonts/Font.h"
-#include "platform/graphics/DrawLooper.h"
+#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/text/TextRun.h"
@@ -36,21 +36,20 @@ namespace WebCore {
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
{
GraphicsContext* context = paintInfo.context;
- RenderStyle* style = m_renderer->style(isFirstLineStyle());
+ RenderStyle* style = renderer().style(isFirstLineStyle());
const Font& font = style->font();
FloatPoint boxOrigin = locationIncludingFlipping();
- LayoutPoint adjustedPaintOffset = paintOffset;
+ boxOrigin.moveBy(FloatPoint(paintOffset));
if (!isHorizontal())
- adjustedPaintOffset.move(0, -virtualLogicalHeight());
- boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y());
+ boxOrigin.move(0, -virtualLogicalHeight());
FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight()));
GraphicsContextStateSaver stateSaver(*context);
if (!isHorizontal())
context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise));
FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent());
- Color styleTextColor = m_renderer->resolveColor(style, CSSPropertyWebkitTextFillColor);
+ Color styleTextColor = renderer().resolveColor(style, CSSPropertyWebkitTextFillColor);
if (styleTextColor != context->fillColor())
context->setFillColor(styleTextColor);
@@ -58,8 +57,8 @@ void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, La
paintSelection(context, boxOrigin, style, font);
// Select the correct color for painting the text.
- Color foreground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionForegroundColor();
- if (foreground.isValid() && foreground != styleTextColor)
+ Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor();
+ if (foreground != styleTextColor)
context->setFillColor(foreground);
}
@@ -67,21 +66,20 @@ void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, La
const ShadowList* shadowList = context->printing() ? 0 : style->textShadow();
bool hasShadow = shadowList;
if (hasShadow) {
- DrawLooper drawLooper;
+ OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
for (size_t i = shadowList->shadows().size(); i--; ) {
const ShadowData& shadow = shadowList->shadows()[i];
- int shadowX = isHorizontal() ? shadow.x() : shadow.y();
- int shadowY = isHorizontal() ? shadow.y() : -shadow.x();
+ float shadowX = isHorizontal() ? shadow.x() : shadow.y();
+ float shadowY = isHorizontal() ? shadow.y() : -shadow.x();
FloatSize offset(shadowX, shadowY);
- drawLooper.addShadow(offset, shadow.blur(), m_renderer->resolveColor(shadow.color()),
- DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
+ drawLooperBuilder->addShadow(offset, shadow.blur(), shadow.color(),
+ DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
}
- drawLooper.addUnmodifiedContent();
- context->setDrawLooper(drawLooper);
+ drawLooperBuilder->addUnmodifiedContent();
+ context->setDrawLooper(drawLooperBuilder.release());
}
- // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
- TextRun textRun = RenderBlockFlow::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion);
+ TextRun textRun = RenderBlockFlow::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion);
TextRunPaintInfo textRunPaintInfo(textRun);
textRunPaintInfo.bounds = boxRect;
context->drawText(font, textRunPaintInfo, textOrigin);
@@ -98,18 +96,18 @@ void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, La
InlineBox* EllipsisBox::markupBox() const
{
- if (!m_shouldPaintMarkupBox || !m_renderer->isRenderBlock())
+ if (!m_shouldPaintMarkupBox || !renderer().isRenderBlock())
return 0;
- RenderBlock* block = toRenderBlock(m_renderer);
- RootInlineBox* lastLine = block->lineAtIndex(block->lineCount() - 1);
+ RenderBlock& block = toRenderBlock(renderer());
+ RootInlineBox* lastLine = block.lineAtIndex(block.lineCount() - 1);
if (!lastLine)
return 0;
// If the last line-box on the last line of a block is a link, -webkit-line-clamp paints that box after the ellipsis.
// It does not actually move the link.
InlineBox* anchorBox = lastLine->lastChild();
- if (!anchorBox || !anchorBox->renderer()->style()->isLink())
+ if (!anchorBox || !anchorBox->renderer().style()->isLink())
return 0;
return anchorBox;
@@ -123,23 +121,22 @@ void EllipsisBox::paintMarkupBox(PaintInfo& paintInfo, const LayoutPoint& paintO
LayoutPoint adjustedPaintOffset = paintOffset;
adjustedPaintOffset.move(x() + m_logicalWidth - markupBox->x(),
- y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer()->style(isFirstLineStyle())->fontMetrics().ascent()));
+ y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer().style(isFirstLineStyle())->fontMetrics().ascent()));
markupBox->paint(paintInfo, adjustedPaintOffset, lineTop, lineBottom);
}
IntRect EllipsisBox::selectionRect()
{
- RenderStyle* style = m_renderer->style(isFirstLineStyle());
+ RenderStyle* style = renderer().style(isFirstLineStyle());
const Font& font = style->font();
- // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
- return enclosingIntRect(font.selectionRectForText(RenderBlockFlow::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(logicalLeft(), logicalTop() + root()->selectionTopAdjustedForPrecedingBlock()), root()->selectionHeightAdjustedForPrecedingBlock()));
+ return enclosingIntRect(font.selectionRectForText(RenderBlockFlow::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(logicalLeft(), logicalTop() + root().selectionTopAdjustedForPrecedingBlock()), root().selectionHeightAdjustedForPrecedingBlock()));
}
void EllipsisBox::paintSelection(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font)
{
- Color textColor = m_renderer->resolveColor(style, CSSPropertyColor);
- Color c = m_renderer->selectionBackgroundColor();
- if (!c.isValid() || !c.alpha())
+ Color textColor = renderer().resolveColor(style, CSSPropertyColor);
+ Color c = renderer().selectionBackgroundColor();
+ if (!c.alpha())
return;
// If the text color ends up being the same as the selection background, invert the selection
@@ -148,16 +145,15 @@ void EllipsisBox::paintSelection(GraphicsContext* context, const FloatPoint& box
c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
GraphicsContextStateSaver stateSaver(*context);
- LayoutUnit selectionBottom = root()->selectionBottom();
- LayoutUnit top = root()->selectionTop();
- LayoutUnit h = root()->selectionHeight();
- const int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - top);
+ LayoutUnit selectionBottom = root().selectionBottom();
+ LayoutUnit top = root().selectionTop();
+ LayoutUnit h = root().selectionHeight();
+ const int deltaY = roundToInt(renderer().style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - top);
const FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
- FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, h));
+ FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, h.toFloat()));
alignSelectionRectToDevicePixels(clipRect);
context->clip(clipRect);
- // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
- context->drawHighlightForText(font, RenderBlockFlow::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), localOrigin, h, c);
+ context->drawHighlightForText(font, RenderBlockFlow::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), localOrigin, h, c);
}
bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
@@ -166,11 +162,11 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Hit test the markup box.
if (InlineBox* markupBox = this->markupBox()) {
- RenderStyle* style = m_renderer->style(isFirstLineStyle());
+ RenderStyle* style = renderer().style(isFirstLineStyle());
LayoutUnit mtx = adjustedLocation.x() + m_logicalWidth - markupBox->x();
- LayoutUnit mty = adjustedLocation.y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer()->style(isFirstLineStyle())->fontMetrics().ascent());
+ LayoutUnit mty = adjustedLocation.y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer().style(isFirstLineStyle())->fontMetrics().ascent());
if (markupBox->nodeAtPoint(request, result, locationInContainer, LayoutPoint(mtx, mty), lineTop, lineBottom)) {
- renderer()->updateHitTestResult(result, locationInContainer.point() - LayoutSize(mtx, mty));
+ renderer().updateHitTestResult(result, locationInContainer.point() - LayoutSize(mtx, mty));
return true;
}
}
@@ -179,8 +175,8 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
boxOrigin.moveBy(accumulatedOffset);
FloatRect boundsRect(boxOrigin, size());
if (visibleToHitTestRequest(request) && boundsRect.intersects(HitTestLocation::rectForPoint(locationInContainer.point(), 0, 0, 0, 0))) {
- renderer()->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
- if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, locationInContainer, boundsRect))
+ renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
+ if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, boundsRect))
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.h b/chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.h
index ad8e61291f5..c97d375c54a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/EllipsisBox.h
@@ -29,7 +29,7 @@ class HitTestResult;
class EllipsisBox FINAL : public InlineBox {
public:
- EllipsisBox(RenderObject* obj, const AtomicString& ellipsisStr, InlineFlowBox* parent,
+ EllipsisBox(RenderObject& obj, const AtomicString& ellipsisStr, InlineFlowBox* parent,
int width, int height, int x, int y, bool firstLine, bool isVertical, InlineBox* markupBox)
: InlineBox(obj, FloatPoint(x, y), width, firstLine, true, false, false, isVertical, 0, 0, parent)
, m_shouldPaintMarkupBox(markupBox)
@@ -40,7 +40,7 @@ public:
setHasVirtualLogicalHeight();
}
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
void setSelectionState(RenderObject::SelectionState s) { m_selectionState = s; }
IntRect selectionRect();
@@ -48,8 +48,8 @@ public:
virtual float virtualLogicalHeight() const OVERRIDE { return m_height; }
private:
void paintMarkupBox(PaintInfo&, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom, RenderStyle*);
- virtual int height() const { return m_height; }
- virtual RenderObject::SelectionState selectionState() { return m_selectionState; }
+ int height() const { return m_height; }
+ virtual RenderObject::SelectionState selectionState() OVERRIDE { return m_selectionState; }
void paintSelection(GraphicsContext*, const FloatPoint&, RenderStyle*, const Font&);
InlineBox* markupBox() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp b/chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp
index cbdcafc68f0..43ec0362bf6 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp
@@ -32,108 +32,1100 @@
#include "core/rendering/FastTextAutosizer.h"
#include "core/dom/Document.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/html/HTMLTextAreaElement.h"
+#include "core/page/Page.h"
#include "core/rendering/InlineIterator.h"
#include "core/rendering/RenderBlock.h"
-#include "core/rendering/TextAutosizer.h"
+#include "core/rendering/RenderListItem.h"
+#include "core/rendering/RenderListMarker.h"
+#include "core/rendering/RenderTableCell.h"
+#include "core/rendering/RenderView.h"
+
+#ifdef AUTOSIZING_DOM_DEBUG_INFO
+#include "core/dom/ExecutionContextTask.h"
+#endif
+
+using namespace std;
namespace WebCore {
-FastTextAutosizer::FastTextAutosizer(Document* document)
+#ifdef AUTOSIZING_DOM_DEBUG_INFO
+class WriteDebugInfoTask : public ExecutionContextTask {
+public:
+ WriteDebugInfoTask(PassRefPtrWillBeRawPtr<Element> element, AtomicString value)
+ : m_element(element)
+ , m_value(value)
+ {
+ }
+
+ virtual void performTask(ExecutionContext*)
+ {
+ m_element->setAttribute("data-autosizing", m_value, ASSERT_NO_EXCEPTION);
+ }
+
+private:
+ RefPtrWillBePersistent<Element> m_element;
+ AtomicString m_value;
+};
+
+static void writeDebugInfo(RenderObject* renderer, const AtomicString& output)
+{
+ Node* node = renderer->node();
+ if (!node)
+ return;
+ if (node->isDocumentNode())
+ node = toDocument(node)->documentElement();
+ if (!node->isElementNode())
+ return;
+ node->document().postTask(adoptPtr(new WriteDebugInfoTask(toElement(node), output)));
+}
+
+void FastTextAutosizer::writeClusterDebugInfo(Cluster* cluster)
+{
+ String explanation = "";
+ if (cluster->m_flags & SUPPRESSING) {
+ explanation = "[suppressed]";
+ } else if (!(cluster->m_flags & (INDEPENDENT | WIDER_OR_NARROWER))) {
+ explanation = "[inherited]";
+ } else if (cluster->m_supercluster) {
+ explanation = "[supercluster]";
+ } else if (!clusterHasEnoughTextToAutosize(cluster)) {
+ explanation = "[insufficient-text]";
+ } else {
+ const RenderBlock* widthProvider = clusterWidthProvider(cluster->m_root);
+ if (cluster->m_hasTableAncestor && cluster->m_multiplier < multiplierFromBlock(widthProvider)) {
+ explanation = "[table-ancestor-limited]";
+ } else {
+ explanation = String::format("[from width %d of %s]",
+ static_cast<int>(widthFromBlock(widthProvider)), widthProvider->debugName().utf8().data());
+ }
+ }
+ String pageInfo = "";
+ if (cluster->m_root->isRenderView()) {
+ pageInfo = String::format("; pageinfo: bm %f * (lw %d / fw %d)",
+ m_pageInfo.m_baseMultiplier, m_pageInfo.m_layoutWidth, m_pageInfo.m_frameWidth);
+ }
+ float multiplier = cluster->m_flags & SUPPRESSING ? 1.0 : cluster->m_multiplier;
+ writeDebugInfo(const_cast<RenderBlock*>(cluster->m_root),
+ AtomicString(String::format("cluster: %f %s%s", multiplier,
+ explanation.utf8().data(), pageInfo.utf8().data())));
+}
+#endif
+
+static const RenderObject* parentElementRenderer(const RenderObject* renderer)
+{
+ // At style recalc, the renderer's parent may not be attached,
+ // so we need to obtain this from the DOM tree.
+ const Node* node = renderer->node();
+ if (!node)
+ return 0;
+
+ while ((node = node->parentNode())) {
+ if (node->isElementNode())
+ return node->renderer();
+ }
+ return 0;
+}
+
+static bool isNonTextAreaFormControl(const RenderObject* renderer)
+{
+ const Node* node = renderer ? renderer->node() : 0;
+ if (!node || !node->isElementNode())
+ return false;
+ const Element* element = toElement(node);
+
+ return (element->isFormControlElement() && !isHTMLTextAreaElement(element));
+}
+
+static bool isPotentialClusterRoot(const RenderObject* renderer)
+{
+ // "Potential cluster roots" are the smallest unit for which we can
+ // enable/disable text autosizing.
+ // - Must not be inline, as different multipliers on one line looks terrible.
+ // Exceptions are inline-block and alike elements (inline-table, -webkit-inline-*),
+ // as they often contain entire multi-line columns of text.
+ // - Must not be normal list items, as items in the same list should look
+ // consistent, unless they are floating or position:absolute/fixed.
+ Node* node = renderer->generatingNode();
+ if (node && !node->hasChildren())
+ return false;
+ if (!renderer->isRenderBlock())
+ return false;
+ if (renderer->isInline() && !renderer->style()->isDisplayReplacedType())
+ return false;
+ if (renderer->isListItem())
+ return (renderer->isFloating() || renderer->isOutOfFlowPositioned());
+
+ return true;
+}
+
+static bool isIndependentDescendant(const RenderBlock* renderer)
+{
+ ASSERT(isPotentialClusterRoot(renderer));
+
+ RenderBlock* containingBlock = renderer->containingBlock();
+ return renderer->isRenderView()
+ || renderer->isFloating()
+ || renderer->isOutOfFlowPositioned()
+ || renderer->isTableCell()
+ || renderer->isTableCaption()
+ || renderer->isFlexibleBoxIncludingDeprecated()
+ || renderer->hasColumns()
+ || (containingBlock && containingBlock->isHorizontalWritingMode() != renderer->isHorizontalWritingMode())
+ || renderer->style()->isDisplayReplacedType()
+ || renderer->isTextArea()
+ || renderer->style()->userModify() != READ_ONLY;
+}
+
+static bool blockIsRowOfLinks(const RenderBlock* block)
+{
+ // A "row of links" is a block for which:
+ // 1. It does not contain non-link text elements longer than 3 characters
+ // 2. It contains a minimum of 3 inline links and all links should
+ // have the same specified font size.
+ // 3. It should not contain <br> elements.
+ // 4. It should contain only inline elements unless they are containers,
+ // children of link elements or children of sub-containers.
+ int linkCount = 0;
+ RenderObject* renderer = block->firstChild();
+ float matchingFontSize = -1;
+
+ while (renderer) {
+ if (!isPotentialClusterRoot(renderer)) {
+ if (renderer->isText() && toRenderText(renderer)->text().impl()->stripWhiteSpace()->length() > 3)
+ return false;
+ if (!renderer->isInline() || renderer->isBR())
+ return false;
+ }
+ if (renderer->style()->isLink()) {
+ linkCount++;
+ if (matchingFontSize < 0)
+ matchingFontSize = renderer->style()->specifiedFontSize();
+ else if (matchingFontSize != renderer->style()->specifiedFontSize())
+ return false;
+
+ // Skip traversing descendants of the link.
+ renderer = renderer->nextInPreOrderAfterChildren(block);
+ continue;
+ }
+ renderer = renderer->nextInPreOrder(block);
+ }
+
+ return (linkCount >= 3);
+}
+
+static bool blockHeightConstrained(const RenderBlock* block)
+{
+ // FIXME: Propagate constrainedness down the tree, to avoid inefficiently walking back up from each box.
+ // FIXME: This code needs to take into account vertical writing modes.
+ // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in.
+ for (; block; block = block->containingBlock()) {
+ RenderStyle* style = block->style();
+ if (style->overflowY() >= OSCROLL)
+ return false;
+ if (style->height().isSpecified() || style->maxHeight().isSpecified() || block->isOutOfFlowPositioned()) {
+ // Some sites (e.g. wikipedia) set their html and/or body elements to height:100%,
+ // without intending to constrain the height of the content within them.
+ return !block->isDocumentElement() && !block->isBody();
+ }
+ if (block->isFloating())
+ return false;
+ }
+ return false;
+}
+
+static bool blockOrImmediateChildrenAreFormControls(const RenderBlock* block)
+{
+ if (isNonTextAreaFormControl(block))
+ return true;
+ const RenderObject* renderer = block->firstChild();
+ while (renderer) {
+ if (isNonTextAreaFormControl(renderer))
+ return true;
+ renderer = renderer->nextSibling();
+ }
+
+ return false;
+}
+
+// Some blocks are not autosized even if their parent cluster wants them to.
+static bool blockSuppressesAutosizing(const RenderBlock* block)
+{
+ if (blockOrImmediateChildrenAreFormControls(block))
+ return true;
+
+ if (blockIsRowOfLinks(block))
+ return true;
+
+ // Don't autosize block-level text that can't wrap (as it's likely to
+ // expand sideways and break the page's layout).
+ if (!block->style()->autoWrap())
+ return true;
+
+ if (blockHeightConstrained(block))
+ return true;
+
+ return false;
+}
+
+static bool hasExplicitWidth(const RenderBlock* block)
+{
+ // FIXME: This heuristic may need to be expanded to other ways a block can be wider or narrower
+ // than its parent containing block.
+ return block->style() && block->style()->width().isSpecified();
+}
+
+FastTextAutosizer::FastTextAutosizer(const Document* document)
: m_document(document)
+ , m_firstBlockToBeginLayout(0)
+#ifndef NDEBUG
+ , m_blocksThatHaveBegunLayout()
+#endif
+ , m_superclusters()
+ , m_clusterStack()
+ , m_fingerprintMapper()
+ , m_pageInfo()
+ , m_updatePageInfoDeferred(false)
{
}
void FastTextAutosizer::record(const RenderBlock* block)
{
- if (!m_document->settings()
- || !m_document->settings()->textAutosizingEnabled()
- || m_document->printing()
- || !m_document->page())
+ if (!m_pageInfo.m_settingEnabled)
return;
- if (!TextAutosizer::isAutosizingContainer(block))
+ ASSERT(!m_blocksThatHaveBegunLayout.contains(block));
+
+ if (!classifyBlock(block, INDEPENDENT | EXPLICIT_WIDTH))
return;
- AtomicString blockFingerprint = fingerprint(block);
- HashMap<AtomicString, OwnPtr<Cluster> >::AddResult result =
- m_clusterForFingerprint.add(blockFingerprint, PassOwnPtr<Cluster>());
+ if (Fingerprint fingerprint = computeFingerprint(block))
+ m_fingerprintMapper.addTentativeClusterRoot(block, fingerprint);
+}
- if (result.isNewEntry)
- result.iterator->value = adoptPtr(new Cluster(blockFingerprint));
+void FastTextAutosizer::destroy(const RenderBlock* block)
+{
+ if (!m_pageInfo.m_settingEnabled)
+ return;
- Cluster* cluster = result.iterator->value.get();
- cluster->m_blocks.add(block);
+ ASSERT(!m_blocksThatHaveBegunLayout.contains(block));
- m_clusterForBlock.set(block, cluster);
+ if (m_fingerprintMapper.remove(block) && m_firstBlockToBeginLayout) {
+ // RenderBlock with a fingerprint was destroyed during layout.
+ // Clear the cluster stack and the supercluster map to avoid stale pointers.
+ // Speculative fix for http://crbug.com/369485.
+ m_firstBlockToBeginLayout = 0;
+ m_clusterStack.clear();
+ m_superclusters.clear();
+ }
}
-void FastTextAutosizer::destroy(const RenderBlock* block)
+FastTextAutosizer::BeginLayoutBehavior FastTextAutosizer::prepareForLayout(const RenderBlock* block)
{
- Cluster* cluster = m_clusterForBlock.take(block);
- if (!cluster)
+#ifndef NDEBUG
+ m_blocksThatHaveBegunLayout.add(block);
+#endif
+
+ if (!m_firstBlockToBeginLayout) {
+ m_firstBlockToBeginLayout = block;
+ prepareClusterStack(block->parent());
+ } else if (block == currentCluster()->m_root) {
+ // Ignore beginLayout on the same block twice.
+ // This can happen with paginated overflow.
+ return StopLayout;
+ }
+
+ return ContinueLayout;
+}
+
+void FastTextAutosizer::prepareClusterStack(const RenderObject* renderer)
+{
+ if (!renderer)
return;
- cluster->m_blocks.remove(block);
- if (cluster->m_blocks.isEmpty()) {
- // This deletes the Cluster.
- m_clusterForFingerprint.remove(cluster->m_fingerprint);
+ prepareClusterStack(renderer->parent());
+
+ if (renderer->isRenderBlock()) {
+ const RenderBlock* block = toRenderBlock(renderer);
+#ifndef NDEBUG
+ m_blocksThatHaveBegunLayout.add(block);
+#endif
+ if (Cluster* cluster = maybeCreateCluster(block))
+ m_clusterStack.append(adoptPtr(cluster));
+ }
+}
+
+void FastTextAutosizer::beginLayout(RenderBlock* block)
+{
+ ASSERT(shouldHandleLayout());
+
+ if (prepareForLayout(block) == StopLayout)
+ return;
+
+ if (Cluster* cluster = maybeCreateCluster(block))
+ m_clusterStack.append(adoptPtr(cluster));
+
+ // Cells in auto-layout tables are handled separately by inflateAutoTable.
+ bool isAutoTableCell = block->isTableCell() && !toRenderTableCell(block)->table()->style()->isFixedTableLayout();
+ if (!isAutoTableCell && !m_clusterStack.isEmpty())
+ inflate(block);
+}
+
+void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMarker* listItemMarker)
+{
+ if (!shouldHandleLayout())
return;
+ ASSERT(listItem && listItemMarker);
+
+ if (prepareForLayout(listItem) == StopLayout)
+ return;
+
+ // Force the LI to be inside the DBCAT when computing the multiplier.
+ // This guarantees that the DBCAT has entered layout, so we can ask for its width.
+ // It also makes sense because the list marker is autosized like a text node.
+ float multiplier = clusterMultiplier(currentCluster());
+
+ applyMultiplier(listItem, multiplier);
+ applyMultiplier(listItemMarker, multiplier);
+}
+
+void FastTextAutosizer::inflateAutoTable(RenderTable* table)
+{
+ ASSERT(table);
+ ASSERT(!table->style()->isFixedTableLayout());
+ ASSERT(table->containingBlock());
+
+ Cluster* cluster = currentCluster();
+ if (cluster->m_root != table)
+ return;
+
+ // Pre-inflate cells that have enough text so that their inflated preferred widths will be used
+ // for column sizing.
+ for (RenderObject* section = table->firstChild(); section; section = section->nextSibling()) {
+ if (!section->isTableSection())
+ continue;
+ for (RenderTableRow* row = toRenderTableSection(section)->firstRow(); row; row = row->nextRow()) {
+ for (RenderTableCell* cell = row->firstCell(); cell; cell = cell->nextCell()) {
+ if (!cell->needsLayout())
+ continue;
+
+ beginLayout(cell);
+ inflate(cell, DescendToInnerBlocks);
+ endLayout(cell);
+ }
+ }
}
- cluster->m_multiplier = 0;
}
-static void applyMultiplier(RenderObject* renderer, float multiplier)
+void FastTextAutosizer::endLayout(RenderBlock* block)
{
- // We need to clone the render style to avoid breaking style sharing.
- RefPtr<RenderStyle> style = RenderStyle::clone(renderer->style());
- style->setTextAutosizingMultiplier(multiplier);
- style->setUnique();
- renderer->setStyleInternal(style.release());
+ ASSERT(shouldHandleLayout());
+
+ if (block == m_firstBlockToBeginLayout) {
+ m_firstBlockToBeginLayout = 0;
+ m_clusterStack.clear();
+ m_superclusters.clear();
+ m_stylesRetainedDuringLayout.clear();
+#ifndef NDEBUG
+ m_blocksThatHaveBegunLayout.clear();
+#endif
+ // Tables can create two layout scopes for the same block so the isEmpty
+ // check below is needed to guard against endLayout being called twice.
+ } else if (!m_clusterStack.isEmpty() && currentCluster()->m_root == block) {
+ m_clusterStack.removeLast();
+ }
}
-void FastTextAutosizer::inflate(RenderBlock* block)
+float FastTextAutosizer::inflate(RenderObject* parent, InflateBehavior behavior, float multiplier)
{
- Cluster* cluster = 0;
- for (const RenderObject* clusterBlock = block; clusterBlock && !cluster; clusterBlock = clusterBlock->parent()) {
- if (clusterBlock->isRenderBlock())
- cluster = m_clusterForBlock.get(toRenderBlock(clusterBlock));
+ Cluster* cluster = currentCluster();
+ bool hasTextChild = false;
+
+ RenderObject* child = 0;
+ if (parent->isRenderBlock() && (parent->childrenInline() || behavior == DescendToInnerBlocks))
+ child = toRenderBlock(parent)->firstChild();
+ else if (parent->isRenderInline())
+ child = toRenderInline(parent)->firstChild();
+
+ while (child) {
+ if (child->isText()) {
+ hasTextChild = true;
+ // We only calculate this multiplier on-demand to ensure the parent block of this text
+ // has entered layout.
+ if (!multiplier)
+ multiplier = cluster->m_flags & SUPPRESSING ? 1.0f : clusterMultiplier(cluster);
+ applyMultiplier(child, multiplier);
+ // FIXME: Investigate why MarkOnlyThis is sufficient.
+ if (parent->isRenderInline())
+ child->setPreferredLogicalWidthsDirty(MarkOnlyThis);
+ } else if (child->isRenderInline()) {
+ multiplier = inflate(child, behavior, multiplier);
+ } else if (child->isRenderBlock() && behavior == DescendToInnerBlocks
+ && !classifyBlock(child, INDEPENDENT | EXPLICIT_WIDTH | SUPPRESSING)) {
+ multiplier = inflate(child, behavior, multiplier);
+ }
+ child = child->nextSibling();
}
- if (!cluster)
- return;
- if (!cluster->m_multiplier)
- cluster->m_multiplier = computeMultiplier(cluster);
- if (cluster->m_multiplier == 1)
+
+ if (hasTextChild) {
+ applyMultiplier(parent, multiplier); // Parent handles line spacing.
+ } else if (!parent->isListItem()) {
+ // For consistency, a block with no immediate text child should always have a
+ // multiplier of 1 (except for list items which are handled in inflateListItem).
+ applyMultiplier(parent, 1);
+ }
+ return multiplier;
+}
+
+bool FastTextAutosizer::shouldHandleLayout() const
+{
+ return m_pageInfo.m_settingEnabled && m_pageInfo.m_pageNeedsAutosizing && !m_updatePageInfoDeferred;
+}
+
+void FastTextAutosizer::updatePageInfoInAllFrames()
+{
+ ASSERT(!m_document->frame() || m_document->frame()->isMainFrame());
+
+ for (Frame* frame = m_document->frame(); frame; frame = frame->tree().traverseNext()) {
+ if (!frame->isLocalFrame())
+ continue;
+ if (FastTextAutosizer* textAutosizer = toLocalFrame(frame)->document()->fastTextAutosizer())
+ textAutosizer->updatePageInfo();
+ }
+}
+
+void FastTextAutosizer::updatePageInfo()
+{
+ if (m_updatePageInfoDeferred || !m_document->page() || !m_document->settings())
return;
- applyMultiplier(block, cluster->m_multiplier);
- for (InlineWalker walker(block); !walker.atEnd(); walker.advance()) {
- RenderObject* inlineObj = walker.current();
- if (inlineObj->isRenderBlock() && m_clusterForBlock.contains(toRenderBlock(inlineObj)))
+ PageInfo previousPageInfo(m_pageInfo);
+ m_pageInfo.m_settingEnabled = m_document->settings()->textAutosizingEnabled();
+
+ if (!m_pageInfo.m_settingEnabled || m_document->printing()) {
+ m_pageInfo.m_pageNeedsAutosizing = false;
+ } else {
+ RenderView* renderView = m_document->renderView();
+ bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->writingMode());
+
+ LocalFrame* mainFrame = m_document->page()->deprecatedLocalMainFrame();
+ IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride();
+ if (frameSize.isEmpty())
+ frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollbars);
+ m_pageInfo.m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height();
+
+ IntSize layoutSize = mainFrame->view()->layoutSize();
+ m_pageInfo.m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.height();
+
+ // Compute the base font scale multiplier based on device and accessibility settings.
+ m_pageInfo.m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor();
+ // If the page has a meta viewport or @viewport, don't apply the device scale adjustment.
+ const ViewportDescription& viewportDescription = mainFrame->document()->viewportDescription();
+ if (!viewportDescription.isSpecifiedByAuthor()) {
+ float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustment();
+ m_pageInfo.m_baseMultiplier *= deviceScaleAdjustment;
+ }
+
+ m_pageInfo.m_pageNeedsAutosizing = !!m_pageInfo.m_frameWidth
+ && (m_pageInfo.m_baseMultiplier * (static_cast<float>(m_pageInfo.m_layoutWidth) / m_pageInfo.m_frameWidth) > 1.0f);
+ }
+
+ if (m_pageInfo.m_pageNeedsAutosizing) {
+ // If page info has changed, multipliers may have changed. Force a layout to recompute them.
+ if (m_pageInfo.m_frameWidth != previousPageInfo.m_frameWidth
+ || m_pageInfo.m_layoutWidth != previousPageInfo.m_layoutWidth
+ || m_pageInfo.m_baseMultiplier != previousPageInfo.m_baseMultiplier
+ || m_pageInfo.m_settingEnabled != previousPageInfo.m_settingEnabled)
+ setAllTextNeedsLayout();
+ } else if (previousPageInfo.m_hasAutosized) {
+ // If we are no longer autosizing the page, we won't do anything during the next layout.
+ // Set all the multipliers back to 1 now.
+ resetMultipliers();
+ m_pageInfo.m_hasAutosized = false;
+ }
+}
+
+void FastTextAutosizer::resetMultipliers()
+{
+ RenderObject* renderer = m_document->renderView();
+ while (renderer) {
+ if (RenderStyle* style = renderer->style()) {
+ if (style->textAutosizingMultiplier() != 1)
+ applyMultiplier(renderer, 1, LayoutNeeded);
+ }
+ renderer = renderer->nextInPreOrder();
+ }
+}
+
+void FastTextAutosizer::setAllTextNeedsLayout()
+{
+ RenderObject* renderer = m_document->renderView();
+ while (renderer) {
+ if (renderer->isText())
+ renderer->setNeedsLayoutAndFullPaintInvalidation();
+ renderer = renderer->nextInPreOrder();
+ }
+}
+
+FastTextAutosizer::BlockFlags FastTextAutosizer::classifyBlock(const RenderObject* renderer, BlockFlags mask)
+{
+ if (!renderer->isRenderBlock())
+ return 0;
+
+ const RenderBlock* block = toRenderBlock(renderer);
+ BlockFlags flags = 0;
+
+ if (isPotentialClusterRoot(block)) {
+ if (mask & POTENTIAL_ROOT)
+ flags |= POTENTIAL_ROOT;
+
+ if ((mask & INDEPENDENT) && (isIndependentDescendant(block) || block->isTable()))
+ flags |= INDEPENDENT;
+
+ if ((mask & EXPLICIT_WIDTH) && hasExplicitWidth(block))
+ flags |= EXPLICIT_WIDTH;
+
+ if ((mask & SUPPRESSING) && blockSuppressesAutosizing(block))
+ flags |= SUPPRESSING;
+ }
+ return flags;
+}
+
+bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider)
+{
+ Cluster hypotheticalCluster(root, classifyBlock(root), 0);
+ return clusterHasEnoughTextToAutosize(&hypotheticalCluster, widthProvider);
+}
+
+bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster, const RenderBlock* widthProvider)
+{
+ if (cluster->m_hasEnoughTextToAutosize != UnknownAmountOfText)
+ return cluster->m_hasEnoughTextToAutosize == HasEnoughText;
+
+ const RenderBlock* root = cluster->m_root;
+ if (!widthProvider)
+ widthProvider = clusterWidthProvider(root);
+
+ // TextAreas and user-modifiable areas get a free pass to autosize regardless of text content.
+ if (root->isTextArea() || (root->style() && root->style()->userModify() != READ_ONLY)) {
+ cluster->m_hasEnoughTextToAutosize = HasEnoughText;
+ return true;
+ }
+
+ if (cluster->m_flags & SUPPRESSING) {
+ cluster->m_hasEnoughTextToAutosize = NotEnoughText;
+ return false;
+ }
+
+ // 4 lines of text is considered enough to autosize.
+ float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4;
+
+ float length = 0;
+ RenderObject* descendant = root->firstChild();
+ while (descendant) {
+ if (descendant->isRenderBlock()) {
+ if (classifyBlock(descendant, INDEPENDENT | SUPPRESSING)) {
+ descendant = descendant->nextInPreOrderAfterChildren(root);
+ continue;
+ }
+ } else if (descendant->isText()) {
+ // Note: Using text().stripWhiteSpace().length() instead of renderedTextLength() because
+ // the lineboxes will not be built until layout. These values can be different.
+ // Note: This is an approximation assuming each character is 1em wide.
+ length += toRenderText(descendant)->text().stripWhiteSpace().length() * descendant->style()->specifiedFontSize();
+
+ if (length >= minimumTextLengthToAutosize) {
+ cluster->m_hasEnoughTextToAutosize = HasEnoughText;
+ return true;
+ }
+ }
+ descendant = descendant->nextInPreOrder(root);
+ }
+
+ cluster->m_hasEnoughTextToAutosize = NotEnoughText;
+ return false;
+}
+
+FastTextAutosizer::Fingerprint FastTextAutosizer::getFingerprint(const RenderObject* renderer)
+{
+ Fingerprint result = m_fingerprintMapper.get(renderer);
+ if (!result) {
+ result = computeFingerprint(renderer);
+ m_fingerprintMapper.add(renderer, result);
+ }
+ return result;
+}
+
+FastTextAutosizer::Fingerprint FastTextAutosizer::computeFingerprint(const RenderObject* renderer)
+{
+ Node* node = renderer->generatingNode();
+ if (!node || !node->isElementNode())
+ return 0;
+
+ FingerprintSourceData data;
+ if (const RenderObject* parent = parentElementRenderer(renderer))
+ data.m_parentHash = getFingerprint(parent);
+
+ data.m_qualifiedNameHash = QualifiedNameHash::hash(toElement(node)->tagQName());
+
+ if (RenderStyle* style = renderer->style()) {
+ data.m_packedStyleProperties = style->direction();
+ data.m_packedStyleProperties |= (style->position() << 1);
+ data.m_packedStyleProperties |= (style->floating() << 4);
+ data.m_packedStyleProperties |= (style->display() << 6);
+ data.m_packedStyleProperties |= (style->width().type() << 11);
+ // packedStyleProperties effectively using 15 bits now.
+
+ // consider for adding: writing mode, padding.
+
+ data.m_width = style->width().getFloatValue();
+ }
+
+ // Use nodeIndex as a rough approximation of column number
+ // (it's too early to call RenderTableCell::col).
+ // FIXME: account for colspan
+ if (renderer->isTableCell())
+ data.m_column = renderer->node()->nodeIndex();
+
+ return StringHasher::computeHash<UChar>(
+ static_cast<const UChar*>(static_cast<const void*>(&data)),
+ sizeof data / sizeof(UChar));
+}
+
+FastTextAutosizer::Cluster* FastTextAutosizer::maybeCreateCluster(const RenderBlock* block)
+{
+ BlockFlags flags = classifyBlock(block);
+ if (!(flags & POTENTIAL_ROOT))
+ return 0;
+
+ Cluster* parentCluster = m_clusterStack.isEmpty() ? 0 : currentCluster();
+ ASSERT(parentCluster || block->isRenderView());
+
+ // If a non-independent block would not alter the SUPPRESSING flag, it doesn't need to be a cluster.
+ bool parentSuppresses = parentCluster && (parentCluster->m_flags & SUPPRESSING);
+ if (!(flags & INDEPENDENT) && !(flags & EXPLICIT_WIDTH) && !!(flags & SUPPRESSING) == parentSuppresses)
+ return 0;
+
+ Cluster* cluster = new Cluster(block, flags, parentCluster, getSupercluster(block));
+#ifdef AUTOSIZING_DOM_DEBUG_INFO
+ // Non-SUPPRESSING clusters are annotated in clusterMultiplier.
+ if (flags & SUPPRESSING)
+ writeClusterDebugInfo(cluster);
+#endif
+ return cluster;
+}
+
+FastTextAutosizer::Supercluster* FastTextAutosizer::getSupercluster(const RenderBlock* block)
+{
+ Fingerprint fingerprint = m_fingerprintMapper.get(block);
+ if (!fingerprint)
+ return 0;
+
+ BlockSet* roots = &m_fingerprintMapper.getTentativeClusterRoots(fingerprint);
+ if (!roots || roots->size() < 2 || !roots->contains(block))
+ return 0;
+
+ SuperclusterMap::AddResult addResult = m_superclusters.add(fingerprint, PassOwnPtr<Supercluster>());
+ if (!addResult.isNewEntry)
+ return addResult.storedValue->value.get();
+
+ Supercluster* supercluster = new Supercluster(roots);
+ addResult.storedValue->value = adoptPtr(supercluster);
+ return supercluster;
+}
+
+float FastTextAutosizer::clusterMultiplier(Cluster* cluster)
+{
+ if (cluster->m_multiplier)
+ return cluster->m_multiplier;
+
+ // FIXME: why does isWiderOrNarrowerDescendant crash on independent clusters?
+ if (!(cluster->m_flags & INDEPENDENT) && isWiderOrNarrowerDescendant(cluster))
+ cluster->m_flags |= WIDER_OR_NARROWER;
+
+ if (cluster->m_flags & (INDEPENDENT | WIDER_OR_NARROWER)) {
+ if (cluster->m_supercluster)
+ cluster->m_multiplier = superclusterMultiplier(cluster);
+ else if (clusterHasEnoughTextToAutosize(cluster))
+ cluster->m_multiplier = multiplierFromBlock(clusterWidthProvider(cluster->m_root));
+ else
+ cluster->m_multiplier = 1.0f;
+ } else {
+ cluster->m_multiplier = cluster->m_parent ? clusterMultiplier(cluster->m_parent) : 1.0f;
+ }
+
+#ifdef AUTOSIZING_DOM_DEBUG_INFO
+ writeClusterDebugInfo(cluster);
+#endif
+
+ ASSERT(cluster->m_multiplier);
+ return cluster->m_multiplier;
+}
+
+bool FastTextAutosizer::superclusterHasEnoughTextToAutosize(Supercluster* supercluster, const RenderBlock* widthProvider)
+{
+ if (supercluster->m_hasEnoughTextToAutosize != UnknownAmountOfText)
+ return supercluster->m_hasEnoughTextToAutosize == HasEnoughText;
+
+ BlockSet::iterator end = supercluster->m_roots->end();
+ for (BlockSet::iterator it = supercluster->m_roots->begin(); it != end; ++it) {
+ if (clusterWouldHaveEnoughTextToAutosize(*it, widthProvider)) {
+ supercluster->m_hasEnoughTextToAutosize = HasEnoughText;
+ return true;
+ }
+ }
+ supercluster->m_hasEnoughTextToAutosize = NotEnoughText;
+ return false;
+}
+
+float FastTextAutosizer::superclusterMultiplier(Cluster* cluster)
+{
+ Supercluster* supercluster = cluster->m_supercluster;
+ if (!supercluster->m_multiplier) {
+ const RenderBlock* widthProvider = maxClusterWidthProvider(cluster->m_supercluster, cluster->m_root);
+ supercluster->m_multiplier = superclusterHasEnoughTextToAutosize(supercluster, widthProvider)
+ ? multiplierFromBlock(widthProvider) : 1.0f;
+ }
+ ASSERT(supercluster->m_multiplier);
+ return supercluster->m_multiplier;
+}
+
+const RenderBlock* FastTextAutosizer::clusterWidthProvider(const RenderBlock* root)
+{
+ if (root->isTable() || root->isTableCell())
+ return root;
+
+ return deepestBlockContainingAllText(root);
+}
+
+const RenderBlock* FastTextAutosizer::maxClusterWidthProvider(const Supercluster* supercluster, const RenderBlock* currentRoot)
+{
+ const RenderBlock* result = clusterWidthProvider(currentRoot);
+ float maxWidth = widthFromBlock(result);
+
+ const BlockSet* roots = supercluster->m_roots;
+ for (BlockSet::iterator it = roots->begin(); it != roots->end(); ++it) {
+ const RenderBlock* widthProvider = clusterWidthProvider(*it);
+ if (widthProvider->needsLayout())
continue;
+ float width = widthFromBlock(widthProvider);
+ if (width > maxWidth) {
+ maxWidth = width;
+ result = widthProvider;
+ }
+ }
+ RELEASE_ASSERT(result);
+ return result;
+}
+
+float FastTextAutosizer::widthFromBlock(const RenderBlock* block)
+{
+ RELEASE_ASSERT(block);
+ RELEASE_ASSERT(block->style());
+
+ if (!(block->isTable() || block->isTableCell() || block->isListItem()))
+ return block->contentLogicalWidth().toFloat();
+
+ if (!block->containingBlock())
+ return 0;
+
+ // Tables may be inflated before computing their preferred widths. Try several methods to
+ // obtain a width, and fall back on a containing block's width.
+ do {
+ float width;
+ Length specifiedWidth = block->isTableCell()
+ ? toRenderTableCell(block)->styleOrColLogicalWidth() : block->style()->logicalWidth();
+ if (specifiedWidth.isFixed()) {
+ if ((width = specifiedWidth.value()) > 0)
+ return width;
+ }
+ if (specifiedWidth.isPercent()) {
+ if (float containerWidth = block->containingBlock()->contentLogicalWidth().toFloat()) {
+ if ((width = floatValueForLength(specifiedWidth, containerWidth)) > 0)
+ return width;
+ }
+ }
+ if ((width = block->contentLogicalWidth().toFloat()) > 0)
+ return width;
+ } while ((block = block->containingBlock()));
+ return 0;
+}
+
+float FastTextAutosizer::multiplierFromBlock(const RenderBlock* block)
+{
+ // If block->needsLayout() is false, it does not need to be in m_blocksThatHaveBegunLayout.
+ // This can happen during layout of a positioned object if the cluster's DBCAT is deeper
+ // than the positioned object's containing block, and wasn't marked as needing layout.
+ ASSERT(m_blocksThatHaveBegunLayout.contains(block) || !block->needsLayout());
+
+ // Block width, in CSS pixels.
+ float blockWidth = widthFromBlock(block);
+ float multiplier = m_pageInfo.m_frameWidth ? min(blockWidth, static_cast<float>(m_pageInfo.m_layoutWidth)) / m_pageInfo.m_frameWidth : 1.0f;
+
+ return max(m_pageInfo.m_baseMultiplier * multiplier, 1.0f);
+}
+
+const RenderBlock* FastTextAutosizer::deepestBlockContainingAllText(Cluster* cluster)
+{
+ if (!cluster->m_deepestBlockContainingAllText)
+ cluster->m_deepestBlockContainingAllText = deepestBlockContainingAllText(cluster->m_root);
+
+ return cluster->m_deepestBlockContainingAllText;
+}
+
+// FIXME: Refactor this to look more like FastTextAutosizer::deepestCommonAncestor. This is copied
+// from TextAutosizer::findDeepestBlockContainingAllText.
+const RenderBlock* FastTextAutosizer::deepestBlockContainingAllText(const RenderBlock* root)
+{
+ size_t firstDepth = 0;
+ const RenderObject* firstTextLeaf = findTextLeaf(root, firstDepth, First);
+ if (!firstTextLeaf)
+ return root;
+
+ size_t lastDepth = 0;
+ const RenderObject* lastTextLeaf = findTextLeaf(root, lastDepth, Last);
+ ASSERT(lastTextLeaf);
+
+ // Equalize the depths if necessary. Only one of the while loops below will get executed.
+ const RenderObject* firstNode = firstTextLeaf;
+ const RenderObject* lastNode = lastTextLeaf;
+ while (firstDepth > lastDepth) {
+ firstNode = firstNode->parent();
+ --firstDepth;
+ }
+ while (lastDepth > firstDepth) {
+ lastNode = lastNode->parent();
+ --lastDepth;
+ }
+
+ // Go up from both nodes until the parent is the same. Both pointers will point to the LCA then.
+ while (firstNode != lastNode) {
+ firstNode = firstNode->parent();
+ lastNode = lastNode->parent();
+ }
+
+ if (firstNode->isRenderBlock())
+ return toRenderBlock(firstNode);
+
+ // containingBlock() should never leave the cluster, since it only skips ancestors when finding
+ // the container of position:absolute/fixed blocks, and those cannot exist between a cluster and
+ // its text node's lowest common ancestor as isAutosizingCluster would have made them into their
+ // own independent cluster.
+ const RenderBlock* containingBlock = firstNode->containingBlock();
+ if (!containingBlock)
+ return root;
+
+ ASSERT(containingBlock->isDescendantOf(root));
+ return containingBlock;
+}
+
+const RenderObject* FastTextAutosizer::findTextLeaf(const RenderObject* parent, size_t& depth, TextLeafSearch firstOrLast)
+{
+ // List items are treated as text due to the marker.
+ // The actual renderer for the marker (RenderListMarker) may not be in the tree yet since it is added during layout.
+ if (parent->isListItem())
+ return parent;
+
+ if (parent->isText())
+ return parent;
+
+ ++depth;
+ const RenderObject* child = (firstOrLast == First) ? parent->slowFirstChild() : parent->slowLastChild();
+ while (child) {
+ // Note: At this point clusters may not have been created for these blocks so we cannot rely
+ // on m_clusters. Instead, we use a best-guess about whether the block will become a cluster.
+ if (!classifyBlock(child, INDEPENDENT)) {
+ if (const RenderObject* leaf = findTextLeaf(child, depth, firstOrLast))
+ return leaf;
+ }
+ child = (firstOrLast == First) ? child->nextSibling() : child->previousSibling();
+ }
+ --depth;
+
+ return 0;
+}
+
+void FastTextAutosizer::applyMultiplier(RenderObject* renderer, float multiplier, RelayoutBehavior relayoutBehavior)
+{
+ ASSERT(renderer && renderer->style());
+ RenderStyle* currentStyle = renderer->style();
+ if (currentStyle->textAutosizingMultiplier() == multiplier)
+ return;
+
+ // We need to clone the render style to avoid breaking style sharing.
+ RefPtr<RenderStyle> style = RenderStyle::clone(currentStyle);
+ style->setTextAutosizingMultiplier(multiplier);
+ style->setUnique();
+
+ switch (relayoutBehavior) {
+ case AlreadyInLayout:
+ // Don't free currentStyle until the end of the layout pass. This allows other parts of the system
+ // to safely hold raw RenderStyle* pointers during layout, e.g. BreakingContext::m_currentStyle.
+ m_stylesRetainedDuringLayout.append(currentStyle);
+
+ renderer->setStyleInternal(style.release());
+ renderer->setNeedsLayoutAndFullPaintInvalidation();
+ break;
+
+ case LayoutNeeded:
+ renderer->setStyle(style.release());
+ break;
+ }
+
+ if (multiplier != 1)
+ m_pageInfo.m_hasAutosized = true;
+}
+
+bool FastTextAutosizer::isWiderOrNarrowerDescendant(Cluster* cluster)
+{
+ // FIXME: Why do we return true when hasExplicitWidth returns false??
+ if (!cluster->m_parent || !hasExplicitWidth(cluster->m_root))
+ return true;
+
+ const RenderBlock* parentDeepestBlockContainingAllText = deepestBlockContainingAllText(cluster->m_parent);
+ ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root));
+ ASSERT(m_blocksThatHaveBegunLayout.contains(parentDeepestBlockContainingAllText));
+
+ float contentWidth = cluster->m_root->contentLogicalWidth().toFloat();
+ float clusterTextWidth = parentDeepestBlockContainingAllText->contentLogicalWidth().toFloat();
+
+ // Clusters with a root that is wider than the deepestBlockContainingAllText of their parent
+ // autosize independently of their parent.
+ if (contentWidth > clusterTextWidth)
+ return true;
- applyMultiplier(inlineObj, cluster->m_multiplier);
+ // Clusters with a root that is significantly narrower than the deepestBlockContainingAllText of
+ // their parent autosize independently of their parent.
+ static float narrowWidthDifference = 200;
+ if (clusterTextWidth - contentWidth > narrowWidthDifference)
+ return true;
+
+ return false;
+}
+
+FastTextAutosizer::Cluster* FastTextAutosizer::currentCluster() const
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!m_clusterStack.isEmpty());
+ return m_clusterStack.last().get();
+}
+
+#ifndef NDEBUG
+void FastTextAutosizer::FingerprintMapper::assertMapsAreConsistent()
+{
+ // For each fingerprint -> block mapping in m_blocksForFingerprint we should have an associated
+ // map from block -> fingerprint in m_fingerprints.
+ ReverseFingerprintMap::iterator end = m_blocksForFingerprint.end();
+ for (ReverseFingerprintMap::iterator fingerprintIt = m_blocksForFingerprint.begin(); fingerprintIt != end; ++fingerprintIt) {
+ Fingerprint fingerprint = fingerprintIt->key;
+ BlockSet* blocks = fingerprintIt->value.get();
+ for (BlockSet::iterator blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) {
+ const RenderBlock* block = (*blockIt);
+ ASSERT(m_fingerprints.get(block) == fingerprint);
+ }
}
}
+#endif
+
+void FastTextAutosizer::FingerprintMapper::add(const RenderObject* renderer, Fingerprint fingerprint)
+{
+ remove(renderer);
+
+ m_fingerprints.set(renderer, fingerprint);
+#ifndef NDEBUG
+ assertMapsAreConsistent();
+#endif
+}
+
+void FastTextAutosizer::FingerprintMapper::addTentativeClusterRoot(const RenderBlock* block, Fingerprint fingerprint)
+{
+ add(block, fingerprint);
+
+ ReverseFingerprintMap::AddResult addResult = m_blocksForFingerprint.add(fingerprint, PassOwnPtr<BlockSet>());
+ if (addResult.isNewEntry)
+ addResult.storedValue->value = adoptPtr(new BlockSet);
+ addResult.storedValue->value->add(block);
+#ifndef NDEBUG
+ assertMapsAreConsistent();
+#endif
+}
+
+bool FastTextAutosizer::FingerprintMapper::remove(const RenderObject* renderer)
+{
+ Fingerprint fingerprint = m_fingerprints.take(renderer);
+ if (!fingerprint || !renderer->isRenderBlock())
+ return false;
+
+ ReverseFingerprintMap::iterator blocksIter = m_blocksForFingerprint.find(fingerprint);
+ if (blocksIter == m_blocksForFingerprint.end())
+ return false;
+
+ BlockSet& blocks = *blocksIter->value;
+ blocks.remove(toRenderBlock(renderer));
+ if (blocks.isEmpty())
+ m_blocksForFingerprint.remove(blocksIter);
+#ifndef NDEBUG
+ assertMapsAreConsistent();
+#endif
+ return true;
+}
-AtomicString FastTextAutosizer::fingerprint(const RenderBlock* block)
+FastTextAutosizer::Fingerprint FastTextAutosizer::FingerprintMapper::get(const RenderObject* renderer)
{
- // FIXME(crbug.com/322340): Implement a better fingerprinting algorithm.
- return String::number((unsigned long long) block);
+ return m_fingerprints.get(renderer);
}
-float FastTextAutosizer::computeMultiplier(const FastTextAutosizer::Cluster* cluster)
+FastTextAutosizer::BlockSet& FastTextAutosizer::FingerprintMapper::getTentativeClusterRoots(Fingerprint fingerprint)
{
- const WTF::HashSet<const RenderBlock*>& blocks = cluster->m_blocks;
+ return *m_blocksForFingerprint.get(fingerprint);
+}
+
+FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block)
+ : m_textAutosizer(block->document().fastTextAutosizer())
+ , m_block(block)
+{
+ if (!m_textAutosizer)
+ return;
- bool shouldAutosize = false;
- for (WTF::HashSet<const RenderBlock*>::iterator it = blocks.begin(); it != blocks.end(); ++it)
- shouldAutosize |= TextAutosizer::containerShouldBeAutosized(*it);
+ if (m_textAutosizer->shouldHandleLayout())
+ m_textAutosizer->beginLayout(m_block);
+ else
+ m_textAutosizer = 0;
+}
- if (!shouldAutosize)
- return 1.0f;
+FastTextAutosizer::LayoutScope::~LayoutScope()
+{
+ if (m_textAutosizer)
+ m_textAutosizer->endLayout(m_block);
+}
- // FIXME(crbug.com/322344): Implement multiplier computation.
- return 1.5f;
+
+FastTextAutosizer::TableLayoutScope::TableLayoutScope(RenderTable* table)
+ : LayoutScope(table)
+{
+ if (m_textAutosizer) {
+ ASSERT(m_textAutosizer->shouldHandleLayout());
+ m_textAutosizer->inflateAutoTable(table);
+ }
+}
+
+FastTextAutosizer::DeferUpdatePageInfo::DeferUpdatePageInfo(Page* page)
+ : m_mainFrame(page->deprecatedLocalMainFrame())
+{
+ if (FastTextAutosizer* textAutosizer = m_mainFrame->document()->fastTextAutosizer()) {
+ ASSERT(!textAutosizer->m_updatePageInfoDeferred);
+ textAutosizer->m_updatePageInfoDeferred = true;
+ }
+}
+
+FastTextAutosizer::DeferUpdatePageInfo::~DeferUpdatePageInfo()
+{
+ if (FastTextAutosizer* textAutosizer = m_mainFrame->document()->fastTextAutosizer()) {
+ ASSERT(textAutosizer->m_updatePageInfoDeferred);
+ textAutosizer->m_updatePageInfoDeferred = false;
+ textAutosizer->updatePageInfoInAllFrames();
+ }
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.h b/chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.h
index 16265fd899a..f3f5efb2eab 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/FastTextAutosizer.h
@@ -31,17 +31,20 @@
#ifndef FastTextAutosizer_h
#define FastTextAutosizer_h
+#include "core/rendering/RenderObject.h"
+#include "core/rendering/RenderTable.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
-#include "wtf/text/AtomicStringHash.h"
namespace WebCore {
class Document;
class RenderBlock;
+class RenderListItem;
+class RenderListMarker;
// Single-pass text autosizer (work in progress). Works in two stages:
// (1) record information about page elements during style recalc
@@ -52,38 +55,255 @@ class FastTextAutosizer FINAL {
WTF_MAKE_NONCOPYABLE(FastTextAutosizer);
public:
- static PassOwnPtr<FastTextAutosizer> create(Document* document)
+ static PassOwnPtr<FastTextAutosizer> create(const Document* document)
{
return adoptPtr(new FastTextAutosizer(document));
}
+ void updatePageInfoInAllFrames();
+ void updatePageInfo();
void record(const RenderBlock*);
void destroy(const RenderBlock*);
- void inflate(RenderBlock*);
+ void inflateListItem(RenderListItem*, RenderListMarker*);
+
+ class LayoutScope {
+ public:
+ explicit LayoutScope(RenderBlock*);
+ ~LayoutScope();
+ protected:
+ FastTextAutosizer* m_textAutosizer;
+ RenderBlock* m_block;
+ };
+
+ class TableLayoutScope : LayoutScope {
+ public:
+ explicit TableLayoutScope(RenderTable*);
+ };
+
+ class DeferUpdatePageInfo {
+ public:
+ explicit DeferUpdatePageInfo(Page*);
+ ~DeferUpdatePageInfo();
+ private:
+ RefPtr<LocalFrame> m_mainFrame;
+ };
private:
- // TODO: make a proper API for this class?
+ typedef HashSet<const RenderBlock*> BlockSet;
+
+ enum HasEnoughTextToAutosize {
+ UnknownAmountOfText,
+ HasEnoughText,
+ NotEnoughText
+ };
+
+ enum RelayoutBehavior {
+ AlreadyInLayout, // The default; appropriate if we are already in layout.
+ LayoutNeeded // Use this if changing a multiplier outside of layout.
+ };
+
+ enum BeginLayoutBehavior {
+ StopLayout,
+ ContinueLayout
+ };
+
+ enum InflateBehavior {
+ ThisBlockOnly,
+ DescendToInnerBlocks
+ };
+
+ enum BlockFlag {
+ // A block that is evaluated for becoming a cluster root.
+ POTENTIAL_ROOT = 1 << 0,
+ // A cluster root that establishes an independent multiplier.
+ INDEPENDENT = 1 << 1,
+ // A cluster root with an explicit width. These are likely to be independent.
+ EXPLICIT_WIDTH = 1 << 2,
+ // A cluster that is wider or narrower than its parent. These also create an
+ // independent multiplier, but this state cannot be determined until layout.
+ WIDER_OR_NARROWER = 1 << 3,
+ // A cluster that suppresses autosizing.
+ SUPPRESSING = 1 << 4
+ };
+
+ typedef unsigned BlockFlags;
+
+ // A supercluster represents autosizing information about a set of two or
+ // more blocks that all have the same fingerprint. Clusters whose roots
+ // belong to a supercluster will share a common multiplier and
+ // text-length-based autosizing status.
+ struct Supercluster {
+ explicit Supercluster(const BlockSet* roots)
+ : m_roots(roots)
+ , m_hasEnoughTextToAutosize(UnknownAmountOfText)
+ , m_multiplier(0)
+ {
+ }
+
+ const BlockSet* const m_roots;
+ HasEnoughTextToAutosize m_hasEnoughTextToAutosize;
+ float m_multiplier;
+ };
+
struct Cluster {
- explicit Cluster(AtomicString fingerprint)
- : m_fingerprint(fingerprint)
+ explicit Cluster(const RenderBlock* root, BlockFlags flags, Cluster* parent, Supercluster* supercluster = 0)
+ : m_root(root)
+ , m_flags(flags)
+ , m_deepestBlockContainingAllText(0)
+ , m_parent(parent)
, m_multiplier(0)
+ , m_hasEnoughTextToAutosize(UnknownAmountOfText)
+ , m_supercluster(supercluster)
+ , m_hasTableAncestor(root->isTableCell() || (m_parent && m_parent->m_hasTableAncestor))
{
}
- AtomicString m_fingerprint;
- WTF::HashSet<const RenderBlock*> m_blocks;
+ const RenderBlock* const m_root;
+ BlockFlags m_flags;
+ // The deepest block containing all text is computed lazily (see:
+ // deepestBlockContainingAllText). A value of 0 indicates the value has not been computed yet.
+ const RenderBlock* m_deepestBlockContainingAllText;
+ Cluster* m_parent;
+ // The multiplier is computed lazily (see: clusterMultiplier) because it must be calculated
+ // after the lowest block containing all text has entered layout (the
+ // m_blocksThatHaveBegunLayout assertions cover this). Note: the multiplier is still
+ // calculated when m_autosize is false because child clusters may depend on this multiplier.
float m_multiplier;
+ HasEnoughTextToAutosize m_hasEnoughTextToAutosize;
+ // A set of blocks that are similar to this block.
+ Supercluster* m_supercluster;
+ bool m_hasTableAncestor;
+ };
+
+ enum TextLeafSearch {
+ First,
+ Last
+ };
+
+ struct FingerprintSourceData {
+ FingerprintSourceData()
+ : m_parentHash(0)
+ , m_qualifiedNameHash(0)
+ , m_packedStyleProperties(0)
+ , m_column(0)
+ , m_width(0)
+ {
+ }
+
+ unsigned m_parentHash;
+ unsigned m_qualifiedNameHash;
+ // Style specific selection of signals
+ unsigned m_packedStyleProperties;
+ unsigned m_column;
+ float m_width;
+ };
+ // Ensures efficient hashing using StringHasher.
+ COMPILE_ASSERT(!(sizeof(FingerprintSourceData) % sizeof(UChar)),
+ Sizeof_FingerprintSourceData_must_be_multiple_of_UChar);
+
+ typedef unsigned Fingerprint;
+ typedef HashMap<Fingerprint, OwnPtr<Supercluster> > SuperclusterMap;
+ typedef Vector<OwnPtr<Cluster> > ClusterStack;
+
+ // Fingerprints are computed during style recalc, for (some subset of)
+ // blocks that will become cluster roots.
+ class FingerprintMapper {
+ public:
+ void add(const RenderObject*, Fingerprint);
+ void addTentativeClusterRoot(const RenderBlock*, Fingerprint);
+ // Returns true if any BlockSet was modified or freed by the removal.
+ bool remove(const RenderObject*);
+ Fingerprint get(const RenderObject*);
+ BlockSet& getTentativeClusterRoots(Fingerprint);
+ private:
+ typedef HashMap<const RenderObject*, Fingerprint> FingerprintMap;
+ typedef HashMap<Fingerprint, OwnPtr<BlockSet> > ReverseFingerprintMap;
+
+ FingerprintMap m_fingerprints;
+ ReverseFingerprintMap m_blocksForFingerprint;
+#ifndef NDEBUG
+ void assertMapsAreConsistent();
+#endif
+ };
+
+ struct PageInfo {
+ PageInfo()
+ : m_frameWidth(0)
+ , m_layoutWidth(0)
+ , m_baseMultiplier(0)
+ , m_pageNeedsAutosizing(false)
+ , m_hasAutosized(false)
+ , m_settingEnabled(false)
+ {
+ }
+
+ int m_frameWidth; // LocalFrame width in density-independent pixels (DIPs).
+ int m_layoutWidth; // Layout width in CSS pixels.
+ float m_baseMultiplier; // Includes accessibility font scale factor and device scale adjustment.
+ bool m_pageNeedsAutosizing;
+ bool m_hasAutosized;
+ bool m_settingEnabled;
};
- explicit FastTextAutosizer(Document*);
+ explicit FastTextAutosizer(const Document*);
- AtomicString fingerprint(const RenderBlock*);
- float computeMultiplier(const Cluster*);
+ void beginLayout(RenderBlock*);
+ void endLayout(RenderBlock*);
+ void inflateAutoTable(RenderTable*);
+ float inflate(RenderObject*, InflateBehavior = ThisBlockOnly, float multiplier = 0);
+ bool shouldHandleLayout() const;
+ void setAllTextNeedsLayout();
+ void resetMultipliers();
+ BeginLayoutBehavior prepareForLayout(const RenderBlock*);
+ void prepareClusterStack(const RenderObject*);
+ bool clusterHasEnoughTextToAutosize(Cluster*, const RenderBlock* widthProvider = 0);
+ bool superclusterHasEnoughTextToAutosize(Supercluster*, const RenderBlock* widthProvider = 0);
+ bool clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider = 0);
+ Fingerprint getFingerprint(const RenderObject*);
+ Fingerprint computeFingerprint(const RenderObject*);
+ Cluster* maybeCreateCluster(const RenderBlock*);
+ Supercluster* getSupercluster(const RenderBlock*);
+ float clusterMultiplier(Cluster*);
+ float superclusterMultiplier(Cluster*);
+ // A cluster's width provider is typically the deepest block containing all text.
+ // There are exceptions, such as tables and table cells which use the table itself for width.
+ const RenderBlock* clusterWidthProvider(const RenderBlock*);
+ const RenderBlock* maxClusterWidthProvider(const Supercluster*, const RenderBlock* currentRoot);
+ // Typically this returns a block's computed width. In the case of tables layout, this
+ // width is not yet known so the fixed width is used if it's available, or the containing
+ // block's width otherwise.
+ float widthFromBlock(const RenderBlock*);
+ float multiplierFromBlock(const RenderBlock*);
+ void applyMultiplier(RenderObject*, float, RelayoutBehavior = AlreadyInLayout);
+ bool isWiderOrNarrowerDescendant(Cluster*);
+ Cluster* currentCluster() const;
+ const RenderBlock* deepestBlockContainingAllText(Cluster*);
+ const RenderBlock* deepestBlockContainingAllText(const RenderBlock*);
+ // Returns the first text leaf that is in the current cluster. We attempt to not include text
+ // from descendant clusters but because descendant clusters may not exist, this is only an approximation.
+ // The TraversalDirection controls whether we return the first or the last text leaf.
+ const RenderObject* findTextLeaf(const RenderObject*, size_t&, TextLeafSearch);
+ BlockFlags classifyBlock(const RenderObject*, BlockFlags mask = UINT_MAX);
+#ifdef AUTOSIZING_DOM_DEBUG_INFO
+ void writeClusterDebugInfo(Cluster*);
+#endif
- Document* m_document;
+ const Document* m_document;
+ const RenderBlock* m_firstBlockToBeginLayout;
+#ifndef NDEBUG
+ BlockSet m_blocksThatHaveBegunLayout; // Used to ensure we don't compute properties of a block before beginLayout() is called on it.
+#endif
- WTF::HashMap<const RenderBlock*, Cluster*> m_clusterForBlock;
- WTF::HashMap<AtomicString, OwnPtr<Cluster> > m_clusterForFingerprint;
+ // Clusters are created and destroyed during layout. The map key is the
+ // cluster root. Clusters whose roots share the same fingerprint use the
+ // same multiplier.
+ SuperclusterMap m_superclusters;
+ ClusterStack m_clusterStack;
+ FingerprintMapper m_fingerprintMapper;
+ Vector<RefPtr<RenderStyle> > m_stylesRetainedDuringLayout;
+ // FIXME: All frames should share the same m_pageInfo instance.
+ PageInfo m_pageInfo;
+ bool m_updatePageInfoDeferred;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.cpp b/chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.cpp
index ff60e9b0d76..3774afb7ec5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.cpp
@@ -45,11 +45,6 @@
#include "platform/graphics/filters/FEComponentTransfer.h"
#include "platform/graphics/filters/FEDropShadow.h"
#include "platform/graphics/filters/FEGaussianBlur.h"
-#include "platform/graphics/filters/custom/CustomFilterGlobalContext.h"
-#include "platform/graphics/filters/custom/CustomFilterValidatedProgram.h"
-#include "platform/graphics/filters/custom/FECustomFilter.h"
-#include "platform/graphics/filters/custom/ValidatedCustomFilterOperation.h"
-#include "platform/graphics/gpu/AcceleratedImageBufferSurface.h"
#include "wtf/MathExtras.h"
#include <algorithm>
@@ -70,35 +65,11 @@ static inline void lastMatrixRow(Vector<float>& parameters)
parameters.append(0);
}
-inline bool isFilterSizeValid(FloatRect rect)
-{
- if (rect.width() < 0 || rect.width() > kMaxFilterSize
- || rect.height() < 0 || rect.height() > kMaxFilterSize)
- return false;
- return true;
-}
-
-static PassRefPtr<FECustomFilter> createCustomFilterEffect(Filter* filter, Document* document, ValidatedCustomFilterOperation* operation)
-{
- if (!document)
- return 0;
-
- CustomFilterGlobalContext* globalContext = document->renderView()->customFilterGlobalContext();
- globalContext->prepareContextIfNeeded();
- if (!globalContext->context())
- return 0;
-
- return FECustomFilter::create(filter, globalContext->context(), operation->validatedProgram(), operation->parameters(),
- operation->meshRows(), operation->meshColumns(), operation->meshType());
-}
-
FilterEffectRenderer::FilterEffectRenderer()
: Filter(AffineTransform())
, m_graphicsBufferAttached(false)
, m_hasFilterThatMovesPixels(false)
- , m_hasCustomShaderFilter(false)
{
- setFilterResolution(FloatSize(1, 1));
m_sourceGraphic = SourceGraphic::create(this);
}
@@ -113,14 +84,15 @@ GraphicsContext* FilterEffectRenderer::inputContext()
bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations& operations)
{
- m_hasCustomShaderFilter = false;
m_hasFilterThatMovesPixels = operations.hasFilterThatMovesPixels();
// Inverse zoom the pre-zoomed CSS shorthand filters, so that they are in the same zoom as the unzoomed reference filters.
const RenderStyle* style = renderer->style();
- // FIXME: The effects now contain high dpi information, but the software path doesn't (yet) scale its backing.
- // When the proper dpi dependant backing size is allocated, we should remove deviceScaleFactor(...) here.
+#ifdef BLINK_SCALE_FILTERS_AT_RECORD_TIME
float invZoom = 1.0f / ((style ? style->effectiveZoom() : 1.0f) * deviceScaleFactor(renderer->frame()));
+#else
+ float invZoom = style ? 1.0f / style->effectiveZoom() : 1.0f;
+#endif
RefPtr<FilterEffect> previousEffect = m_sourceGraphic;
for (size_t i = 0; i < operations.operations().size(); ++i) {
@@ -256,18 +228,6 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
effect = FEDropShadow::create(this, stdDeviation, stdDeviation, x, y, dropShadowOperation->color(), 1);
break;
}
- case FilterOperation::CUSTOM:
- // CUSTOM operations are always converted to VALIDATED_CUSTOM before getting here.
- // The conversion happens in RenderLayer::computeFilterOperations.
- ASSERT_NOT_REACHED();
- break;
- case FilterOperation::VALIDATED_CUSTOM: {
- Document* document = renderer ? &renderer->document() : 0;
- effect = createCustomFilterEffect(this, document, toValidatedCustomFilterOperation(filterOperation));
- if (effect)
- m_hasCustomShaderFilter = true;
- break;
- }
default:
break;
}
@@ -283,7 +243,7 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
}
}
- // We need to keep the old effects alive until this point, so that filters like FECustomFilter
+ // We need to keep the old effects alive until this point, so that SVG reference filters
// can share cached resources across frames.
m_lastEffect = previousEffect;
@@ -294,9 +254,10 @@ bool FilterEffectRenderer::build(RenderObject* renderer, const FilterOperations&
return true;
}
-bool FilterEffectRenderer::updateBackingStoreRect(const FloatRect& filterRect)
+bool FilterEffectRenderer::updateBackingStoreRect(const FloatRect& floatFilterRect)
{
- if (!filterRect.isZero() && isFilterSizeValid(filterRect)) {
+ IntRect filterRect = enclosingIntRect(floatFilterRect);
+ if (!filterRect.isEmpty() && FilterEffect::isFilterSizeValid(filterRect)) {
FloatRect currentSourceRect = sourceImageRect();
if (filterRect != currentSourceRect) {
setSourceImageRect(filterRect);
@@ -314,13 +275,7 @@ void FilterEffectRenderer::allocateBackingStoreIfNeeded()
if (!m_graphicsBufferAttached) {
IntSize logicalSize(m_sourceDrawingRegion.width(), m_sourceDrawingRegion.height());
if (!sourceImage() || sourceImage()->size() != logicalSize) {
- OwnPtr<ImageBufferSurface> surface;
- if (isAccelerated()) {
- surface = adoptPtr(new AcceleratedImageBufferSurface(logicalSize));
- }
- if (!surface || !surface->isValid()) {
- surface = adoptPtr(new UnacceleratedImageBufferSurface(logicalSize));
- }
+ OwnPtr<ImageBufferSurface> surface = adoptPtr(new UnacceleratedImageBufferSurface(logicalSize));
setSourceImage(ImageBuffer::create(surface.release()));
}
m_graphicsBufferAttached = true;
@@ -342,18 +297,11 @@ void FilterEffectRenderer::apply()
LayoutRect FilterEffectRenderer::computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect)
{
- if (hasCustomShaderFilter()) {
- // When we have at least a custom shader in the chain, we need to compute the whole source image, because the shader can
- // reference any pixel and we cannot control that.
- return filterBoxRect;
- }
// The result of this function is the area in the "filterBoxRect" that needs to be repainted, so that we fully cover the "dirtyRect".
FloatRect rectForRepaint = dirtyRect;
- rectForRepaint.move(-filterBoxRect.location().x(), -filterBoxRect.location().y());
float inf = std::numeric_limits<float>::infinity();
FloatRect clipRect = FloatRect(FloatPoint(-inf, -inf), FloatSize(inf, inf));
rectForRepaint = lastEffect()->getSourceRect(rectForRepaint, clipRect);
- rectForRepaint.move(filterBoxRect.location().x(), filterBoxRect.location().y());
rectForRepaint.intersect(filterBoxRect);
return LayoutRect(rectForRepaint);
}
@@ -364,8 +312,22 @@ bool FilterEffectRendererHelper::prepareFilterEffect(RenderLayer* renderLayer, c
m_renderLayer = renderLayer;
m_repaintRect = dirtyRect;
+ // Get the zoom factor to scale the filterSourceRect input
+ const RenderLayerModelObject* renderer = renderLayer->renderer();
+ const RenderStyle* style = renderer ? renderer->style() : 0;
+ float zoom = style ? style->effectiveZoom() : 1.0f;
+
+ // Prepare a transformation that brings the coordinates into the space
+ // filter coordinates are defined in.
+ AffineTransform absoluteTransform;
+ // FIXME: Should these really be upconverted to doubles and not rounded? crbug.com/350474
+ absoluteTransform.translate(filterBoxRect.x().toDouble(), filterBoxRect.y().toDouble());
+ absoluteTransform.scale(zoom, zoom);
+
FilterEffectRenderer* filter = renderLayer->filterRenderer();
- LayoutRect filterSourceRect = filter->computeSourceImageRectForDirtyRect(filterBoxRect, dirtyRect);
+ filter->setAbsoluteTransform(absoluteTransform);
+
+ IntRect filterSourceRect = pixelSnappedIntRect(filter->computeSourceImageRectForDirtyRect(filterBoxRect, dirtyRect));
if (filterSourceRect.isEmpty()) {
// The dirty rect is not in view, just bail out.
@@ -373,16 +335,7 @@ bool FilterEffectRendererHelper::prepareFilterEffect(RenderLayer* renderLayer, c
return false;
}
- // Get the zoom factor to scale the filterSourceRect input
- const RenderLayerModelObject* renderer = renderLayer->renderer();
- const RenderStyle* style = renderer ? renderer->style() : 0;
- float zoom = style ? style->effectiveZoom() : 1.0f;
-
- AffineTransform absoluteTransform;
- absoluteTransform.translate(filterBoxRect.x(), filterBoxRect.y());
- filter->setAbsoluteTransform(absoluteTransform);
- filter->setAbsoluteFilterRegion(AffineTransform().scale(zoom).mapRect(filterSourceRect));
- filter->setFilterRegion(absoluteTransform.inverse().mapRect(filterSourceRect));
+ filter->setFilterRegion(filter->mapAbsoluteRectToLocalRect(filterSourceRect));
filter->lastEffect()->determineFilterPrimitiveSubregion(MapRectForward);
bool hasUpdatedBackingStore = filter->updateBackingStoreRect(filterSourceRect);
@@ -405,7 +358,7 @@ GraphicsContext* FilterEffectRendererHelper::beginFilterEffect(GraphicsContext*
filter->allocateBackingStoreIfNeeded();
// Paint into the context that represents the SourceGraphic of the filter.
GraphicsContext* sourceGraphicsContext = filter->inputContext();
- if (!sourceGraphicsContext || !isFilterSizeValid(filter->absoluteFilterRegion())) {
+ if (!sourceGraphicsContext || !FilterEffect::isFilterSizeValid(filter->absoluteFilterRegion())) {
// Disable the filters and continue.
m_haveFilterEffect = false;
return oldContext;
@@ -434,7 +387,7 @@ GraphicsContext* FilterEffectRendererHelper::applyFilterEffect()
filter->apply();
// Get the filtered output and draw it in place.
- m_savedGraphicsContext->drawImageBuffer(filter->output(), filter->outputRect(), CompositeSourceOver);
+ m_savedGraphicsContext->drawImageBuffer(filter->output(), filter->outputRect());
filter->clearIntermediateResults();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.h b/chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.h
index 54f67f0ae8b..70c6909897e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/FilterEffectRenderer.h
@@ -30,7 +30,6 @@
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntRectExtent.h"
#include "platform/geometry/LayoutRect.h"
-#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/filters/Filter.h"
#include "platform/graphics/filters/FilterEffect.h"
@@ -42,9 +41,6 @@
namespace WebCore {
-class ShaderResource;
-class CustomFilterProgram;
-class Document;
class GraphicsContext;
class RenderLayer;
class RenderObject;
@@ -74,7 +70,7 @@ private:
bool m_haveFilterEffect;
};
-class FilterEffectRenderer : public Filter
+class FilterEffectRenderer FINAL : public Filter
{
WTF_MAKE_FAST_ALLOCATED;
public:
@@ -83,12 +79,12 @@ public:
return adoptRef(new FilterEffectRenderer());
}
- void setSourceImageRect(const FloatRect& sourceImageRect)
+ void setSourceImageRect(const IntRect& sourceImageRect)
{
m_sourceDrawingRegion = sourceImageRect;
m_graphicsBufferAttached = false;
}
- virtual FloatRect sourceImageRect() const { return m_sourceDrawingRegion; }
+ virtual IntRect sourceImageRect() const OVERRIDE { return m_sourceDrawingRegion; }
GraphicsContext* inputContext();
ImageBuffer* output() const { return lastEffect()->asImageBuffer(); }
@@ -104,7 +100,6 @@ public:
bool hasFilterThatMovesPixels() const { return m_hasFilterThatMovesPixels; }
LayoutRect computeSourceImageRectForDirtyRect(const LayoutRect& filterBoxRect, const LayoutRect& dirtyRect);
- bool hasCustomShaderFilter() const { return m_hasCustomShaderFilter; }
PassRefPtr<FilterEffect> lastEffect() const
{
return m_lastEffect;
@@ -114,7 +109,7 @@ private:
FilterEffectRenderer();
virtual ~FilterEffectRenderer();
- FloatRect m_sourceDrawingRegion;
+ IntRect m_sourceDrawingRegion;
RefPtr<SourceGraphic> m_sourceGraphic;
RefPtr<FilterEffect> m_lastEffect;
@@ -123,7 +118,6 @@ private:
bool m_graphicsBufferAttached;
bool m_hasFilterThatMovesPixels;
- bool m_hasCustomShaderFilter;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FixedTableLayout.cpp b/chromium/third_party/WebKit/Source/core/rendering/FixedTableLayout.cpp
index 83cc6cebe96..25e4b83ffd3 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FixedTableLayout.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/FixedTableLayout.cpp
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2002 Lars Knoll (knoll@kde.org)
* (C) 2002 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -137,18 +137,13 @@ int FixedTableLayout::calcWidthArray()
unsigned currentColumn = 0;
- RenderObject* firstRow = section->firstChild();
- for (RenderObject* child = firstRow->firstChild(); child; child = child->nextSibling()) {
- if (!child->isTableCell())
- continue;
-
- RenderTableCell* cell = toRenderTableCell(child);
-
+ RenderTableRow* firstRow = section->firstRow();
+ for (RenderTableCell* cell = firstRow->firstCell(); cell; cell = cell->nextCell()) {
Length logicalWidth = cell->styleOrColLogicalWidth();
unsigned span = cell->colSpan();
int fixedBorderBoxLogicalWidth = 0;
// FIXME: Support other length types. If the width is non-auto, it should probably just use
- // RenderBox::computeLogicalWidthInRegionUsing to compute the width.
+ // RenderBox::computeLogicalWidthUsing to compute the width.
if (logicalWidth.isFixed() && logicalWidth.isPositive()) {
fixedBorderBoxLogicalWidth = cell->adjustBorderBoxLogicalWidthForBoxSizing(logicalWidth.value());
logicalWidth.setValue(fixedBorderBoxLogicalWidth);
@@ -330,11 +325,8 @@ void FixedTableLayout::willChangeTableLayout()
RenderTableRow* row = section->rowRendererAt(i);
if (!row)
continue;
- for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
- if (!cell->isTableCell())
- continue;
+ for (RenderTableCell* cell = row->firstCell(); cell; cell = cell->nextCell())
cell->setPreferredLogicalWidthsDirty();
- }
}
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.cpp b/chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.cpp
index 152a3a329c6..d455f53c053 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.cpp
@@ -93,7 +93,6 @@ PassOwnPtr<FloatingObject> FloatingObject::copyToNewContainer(LayoutSize offset,
PassOwnPtr<FloatingObject> FloatingObject::unsafeClone() const
{
OwnPtr<FloatingObject> cloneObject = adoptPtr(new FloatingObject(renderer(), type(), m_frameRect, m_shouldPaint, m_isDescendant));
- cloneObject->m_originatingLine = m_originatingLine;
cloneObject->m_paginationStrut = m_paginationStrut;
cloneObject->m_isPlaced = m_isPlaced;
return cloneObject.release();
@@ -113,16 +112,16 @@ public:
{
}
+ virtual ~ComputeFloatOffsetAdapter() { }
+
int lowValue() const { return m_lineTop; }
int highValue() const { return m_lineBottom; }
void collectIfNeeded(const IntervalType&);
LayoutUnit offset() const { return m_offset; }
- LayoutUnit shapeOffset() const;
- LayoutUnit heightRemaining() const;
-private:
- bool updateOffsetIfNeeded(const FloatingObject*);
+protected:
+ virtual bool updateOffsetIfNeeded(const FloatingObject*) = 0;
const RenderBlockFlow* m_renderer;
int m_lineTop;
@@ -131,11 +130,39 @@ private:
const FloatingObject* m_outermostFloat;
};
+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetForFloatLayoutAdapter : public ComputeFloatOffsetAdapter<FloatTypeValue> {
+public:
+ ComputeFloatOffsetForFloatLayoutAdapter(const RenderBlockFlow* renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+ : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBottom, offset)
+ {
+ }
+
+ virtual ~ComputeFloatOffsetForFloatLayoutAdapter() { }
+
+ LayoutUnit heightRemaining() const;
+
+protected:
+ virtual bool updateOffsetIfNeeded(const FloatingObject*) OVERRIDE FINAL;
+};
+
+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetForLineLayoutAdapter : public ComputeFloatOffsetAdapter<FloatTypeValue> {
+public:
+ ComputeFloatOffsetForLineLayoutAdapter(const RenderBlockFlow* renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+ : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBottom, offset)
+ {
+ }
+
+ virtual ~ComputeFloatOffsetForLineLayoutAdapter() { }
+
+protected:
+ virtual bool updateOffsetIfNeeded(const FloatingObject*) OVERRIDE FINAL;
+};
+
FloatingObjects::~FloatingObjects()
{
- // FIXME: m_set should use OwnPtr instead.
- deleteAllValues(m_set);
}
void FloatingObjects::clearLineBoxTreePointers()
{
@@ -147,17 +174,6 @@ void FloatingObjects::clearLineBoxTreePointers()
}
}
-template<>
-inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
-{
- LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
- if (logicalRight > m_offset) {
- m_offset = logicalRight;
- return true;
- }
- return false;
-}
-
FloatingObjects::FloatingObjects(const RenderBlockFlow* renderer, bool horizontalWritingMode)
: m_placedFloatsTree(UninitializedTree)
, m_leftObjectsCount(0)
@@ -170,7 +186,6 @@ FloatingObjects::FloatingObjects(const RenderBlockFlow* renderer, bool horizonta
void FloatingObjects::clear()
{
- deleteAllValues(m_set);
m_set.clear();
m_placedFloatsTree.clear();
m_leftObjectsCount = 0;
@@ -198,7 +213,7 @@ LayoutUnit FloatingObjects::lowestFloatLogicalBottom(FloatingObject::Type floatT
LayoutUnit lowestFloatBottomLeft = 0;
LayoutUnit lowestFloatBottomRight = 0;
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (floatingObject->isPlaced()) {
FloatingObject::Type curType = floatingObject->type();
LayoutUnit curFloatLogicalBottom = m_renderer->logicalBottomForFloat(floatingObject);
@@ -213,7 +228,7 @@ LayoutUnit FloatingObjects::lowestFloatLogicalBottom(FloatingObject::Type floatT
setCachedLowestFloatLogicalBottom(isInHorizontalWritingMode, FloatingObject::FloatRight, lowestFloatBottomRight);
} else {
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (floatingObject->isPlaced() && floatingObject->type() == floatType)
lowestFloatBottom = max(lowestFloatBottom, m_renderer->logicalBottomForFloat(floatingObject));
}
@@ -257,13 +272,11 @@ void FloatingObjects::markLowestFloatLogicalBottomCacheAsDirty()
void FloatingObjects::moveAllToFloatInfoMap(RendererToFloatInfoMap& map)
{
- FloatingObjectSetIterator end = m_set.end();
- for (FloatingObjectSetIterator it = m_set.begin(); it != end; ++it)
- map.add((*it)->renderer(), *it);
-
- // clear set before clearing this because we don't want to delete all of
- // the objects we have just transferred.
- m_set.clear();
+ while (!m_set.isEmpty()) {
+ OwnPtr<FloatingObject> floatingObject = m_set.takeFirst();
+ RenderBox* renderer = floatingObject->renderer();
+ map.add(renderer, floatingObject.release());
+ }
clear();
}
@@ -324,23 +337,22 @@ FloatingObject* FloatingObjects::add(PassOwnPtr<FloatingObject> floatingObject)
{
FloatingObject* newObject = floatingObject.leakPtr();
increaseObjectsCount(newObject->type());
- m_set.add(newObject);
+ m_set.add(adoptPtr(newObject));
if (newObject->isPlaced())
addPlacedObject(newObject);
markLowestFloatLogicalBottomCacheAsDirty();
return newObject;
}
-void FloatingObjects::remove(FloatingObject* floatingObject)
+void FloatingObjects::remove(FloatingObject* toBeRemoved)
{
- decreaseObjectsCount(floatingObject->type());
- m_set.remove(floatingObject);
+ decreaseObjectsCount(toBeRemoved->type());
+ OwnPtr<FloatingObject> floatingObject = m_set.take(toBeRemoved);
ASSERT(floatingObject->isPlaced() || !floatingObject->isInPlacedTree());
if (floatingObject->isPlaced())
- removePlacedObject(floatingObject);
+ removePlacedObject(floatingObject.get());
markLowestFloatLogicalBottomCacheAsDirty();
ASSERT(!floatingObject->originatingLine());
- delete floatingObject;
}
void FloatingObjects::computePlacedFloatsTree()
@@ -352,46 +364,16 @@ void FloatingObjects::computePlacedFloatsTree()
FloatingObjectSetIterator it = m_set.begin();
FloatingObjectSetIterator end = m_set.end();
for (; it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (floatingObject->isPlaced())
m_placedFloatsTree.add(intervalForFloatingObject(floatingObject));
}
}
-static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject* floatingObject, const RenderBlockFlow* containingBlock, LayoutUnit lineTop, LayoutUnit lineBottom)
-{
- if (floatingObject) {
- if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer()->shapeOutsideInfo()) {
- shapeOutside->updateDeltasForContainingBlockLine(containingBlock, floatingObject, lineTop, lineBottom - lineTop);
- return shapeOutside;
- }
- }
-
- return 0;
-}
-
-template<>
-inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::shapeOffset() const
-{
- if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_renderer, m_lineTop, m_lineBottom))
- return m_offset + shapeOutside->rightMarginBoxDelta();
-
- return m_offset;
-}
-
-template<>
-inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::shapeOffset() const
-{
- if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_renderer, m_lineTop, m_lineBottom))
- return m_offset + shapeOutside->leftMarginBoxDelta();
-
- return m_offset;
-}
-
LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
{
int logicalTopAsInt = roundToInt(logicalTop);
- ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
+ ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
placedFloatsTree().allOverlapsWithAdapter(adapter);
if (heightRemaining)
@@ -403,7 +385,7 @@ LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe
LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
{
int logicalTopAsInt = roundToInt(logicalTop);
- ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
+ ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
placedFloatsTree().allOverlapsWithAdapter(adapter);
if (heightRemaining)
@@ -414,18 +396,18 @@ LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix
LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
{
- ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
+ ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
placedFloatsTree().allOverlapsWithAdapter(adapter);
- return adapter.shapeOffset();
+ return adapter.offset();
}
LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
{
- ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
+ ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
placedFloatsTree().allOverlapsWithAdapter(adapter);
- return min(fixedOffset, adapter.shapeOffset());
+ return min(fixedOffset, adapter.offset());
}
FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue()
@@ -455,7 +437,18 @@ inline static bool rangesIntersect(int floatTop, int floatBottom, int objectTop,
}
template<>
-inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+ LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
+ if (logicalRight > m_offset) {
+ m_offset = logicalRight;
+ return true;
+ }
+ return false;
+}
+
+template<>
+inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
{
LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject);
if (logicalLeft < m_offset) {
@@ -466,6 +459,12 @@ inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::updateOffsetI
}
template <FloatingObject::Type FloatTypeValue>
+LayoutUnit ComputeFloatOffsetForFloatLayoutAdapter<FloatTypeValue>::heightRemaining() const
+{
+ return this->m_outermostFloat ? this->m_renderer->logicalBottomForFloat(this->m_outermostFloat) - this->m_lineTop : LayoutUnit(1);
+}
+
+template <FloatingObject::Type FloatTypeValue>
inline void ComputeFloatOffsetAdapter<FloatTypeValue>::collectIfNeeded(const IntervalType& interval)
{
const FloatingObject* floatingObject = interval.data();
@@ -482,10 +481,52 @@ inline void ComputeFloatOffsetAdapter<FloatTypeValue>::collectIfNeeded(const Int
m_outermostFloat = floatingObject;
}
-template <FloatingObject::Type FloatTypeValue>
-LayoutUnit ComputeFloatOffsetAdapter<FloatTypeValue>::heightRemaining() const
+static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject& floatingObject, const RenderBlockFlow& containingBlock, LayoutUnit lineTop, LayoutUnit lineBottom)
+{
+ if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer()->shapeOutsideInfo()) {
+ shapeOutside->updateDeltasForContainingBlockLine(containingBlock, floatingObject, lineTop, lineBottom - lineTop);
+ return shapeOutside;
+ }
+
+ return 0;
+}
+
+template<>
+inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+ ASSERT(floatingObject);
+ LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
+ if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(*floatingObject, *m_renderer, m_lineTop, m_lineBottom)) {
+ if (!shapeOutside->lineOverlapsShape())
+ return false;
+
+ logicalRight += shapeOutside->rightMarginBoxDelta();
+ }
+ if (logicalRight > m_offset) {
+ m_offset = logicalRight;
+ return true;
+ }
+
+ return false;
+}
+
+template<>
+inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
{
- return m_outermostFloat ? m_renderer->logicalBottomForFloat(m_outermostFloat) - m_lineTop : LayoutUnit(1);
+ ASSERT(floatingObject);
+ LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject);
+ if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(*floatingObject, *m_renderer, m_lineTop, m_lineBottom)) {
+ if (!shapeOutside->lineOverlapsShape())
+ return false;
+
+ logicalLeft += shapeOutside->leftMarginBoxDelta();
+ }
+ if (logicalLeft < m_offset) {
+ m_offset = logicalLeft;
+ return true;
+ }
+
+ return false;
}
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.h b/chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.h
index ca3beb1a345..f7062249639 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/FloatingObjects.h
@@ -113,19 +113,25 @@ private:
struct FloatingObjectHashFunctions {
static unsigned hash(FloatingObject* key) { return DefaultHash<RenderBox*>::Hash::hash(key->renderer()); }
- static bool equal(FloatingObject* a, FloatingObject* b) { return a->renderer() == b->renderer(); }
+ static unsigned hash(const OwnPtr<FloatingObject>& key) { return hash(key.get()); }
+ static unsigned hash(const PassOwnPtr<FloatingObject>& key) { return hash(key.get()); }
+ static bool equal(OwnPtr<FloatingObject>& a, FloatingObject* b) { return a->renderer() == b->renderer(); }
+ static bool equal(OwnPtr<FloatingObject>& a, const OwnPtr<FloatingObject>& b) { return equal(a, b.get()); }
+ static bool equal(OwnPtr<FloatingObject>& a, const PassOwnPtr<FloatingObject>& b) { return equal(a, b.get()); }
+
static const bool safeToCompareToEmptyOrDeleted = true;
};
struct FloatingObjectHashTranslator {
static unsigned hash(RenderBox* key) { return DefaultHash<RenderBox*>::Hash::hash(key); }
static bool equal(FloatingObject* a, RenderBox* b) { return a->renderer() == b; }
+ static bool equal(const OwnPtr<WebCore::FloatingObject>& a, RenderBox* b) { return a->renderer() == b; }
};
-typedef ListHashSet<FloatingObject*, 4, FloatingObjectHashFunctions> FloatingObjectSet;
+typedef ListHashSet<OwnPtr<FloatingObject>, 4, FloatingObjectHashFunctions> FloatingObjectSet;
typedef FloatingObjectSet::const_iterator FloatingObjectSetIterator;
typedef PODInterval<int, FloatingObject*> FloatingObjectInterval;
typedef PODIntervalTree<int, FloatingObject*> FloatingObjectTree;
typedef PODFreeListArena<PODRedBlackTree<FloatingObjectInterval>::Node> IntervalArena;
-typedef HashMap<RenderBox*, FloatingObject*> RendererToFloatInfoMap;
+typedef HashMap<RenderBox*, OwnPtr<FloatingObject> > RendererToFloatInfoMap;
class FloatingObjects {
WTF_MAKE_NONCOPYABLE(FloatingObjects); WTF_MAKE_FAST_ALLOCATED;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.cpp b/chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.cpp
index 521085ee453..59e5cf1cbf6 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.cpp
@@ -31,218 +31,16 @@
#include "core/rendering/FlowThreadController.h"
-#include "core/dom/NamedFlowCollection.h"
-#include "core/rendering/RenderFlowThread.h"
-#include "core/rendering/RenderNamedFlowThread.h"
-#include "wtf/text/AtomicString.h"
-
namespace WebCore {
-PassOwnPtr<FlowThreadController> FlowThreadController::create(RenderView* view)
-{
- return adoptPtr(new FlowThreadController(view));
-}
-
-FlowThreadController::FlowThreadController(RenderView* view)
- : m_view(view)
- , m_currentRenderFlowThread(0)
- , m_isRenderNamedFlowThreadOrderDirty(false)
- , m_flowThreadsWithAutoLogicalHeightRegions(0)
-{
-}
-
-FlowThreadController::~FlowThreadController()
-{
-}
-
-RenderNamedFlowThread* FlowThreadController::ensureRenderFlowThreadWithName(const AtomicString& name)
-{
- if (!m_renderNamedFlowThreadList)
- m_renderNamedFlowThreadList = adoptPtr(new RenderNamedFlowThreadList());
- else {
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- if (flowRenderer->flowThreadName() == name)
- return flowRenderer;
- }
- }
-
- NamedFlowCollection* namedFlows = m_view->document().namedFlows();
-
- // Sanity check for the absence of a named flow in the "CREATED" state with the same name.
- ASSERT(!namedFlows->flowByName(name));
-
- RenderNamedFlowThread* flowRenderer = RenderNamedFlowThread::createAnonymous(&m_view->document(), namedFlows->ensureFlowWithName(name));
- flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(m_view->style()));
- m_renderNamedFlowThreadList->add(flowRenderer);
-
- // Keep the flow renderer as a child of RenderView.
- m_view->addChild(flowRenderer);
-
- setIsRenderNamedFlowThreadOrderDirty(true);
-
- return flowRenderer;
-}
-
-void FlowThreadController::styleDidChange()
+PassOwnPtr<FlowThreadController> FlowThreadController::create()
{
- RenderStyle* viewStyle = m_view->style();
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- flowRenderer->setStyle(RenderFlowThread::createFlowThreadStyle(viewStyle));
- }
-}
-
-void FlowThreadController::layoutRenderNamedFlowThreads()
-{
- updateFlowThreadsChainIfNecessary();
-
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- flowRenderer->layoutIfNeeded();
- }
+ return adoptPtr(new FlowThreadController);
}
-void FlowThreadController::registerNamedFlowContentNode(Node* contentNode, RenderNamedFlowThread* namedFlow)
+FlowThreadController::FlowThreadController()
+ : m_currentRenderFlowThread(0)
{
- ASSERT(contentNode && contentNode->isElementNode());
- ASSERT(namedFlow);
- ASSERT(!m_mapNamedFlowContentNodes.contains(contentNode));
- ASSERT(!namedFlow->hasContentNode(contentNode));
- m_mapNamedFlowContentNodes.add(contentNode, namedFlow);
- namedFlow->registerNamedFlowContentNode(contentNode);
-}
-
-void FlowThreadController::unregisterNamedFlowContentNode(Node* contentNode)
-{
- ASSERT(contentNode && contentNode->isElementNode());
- HashMap<const Node*, RenderNamedFlowThread*>::iterator it = m_mapNamedFlowContentNodes.find(contentNode);
- ASSERT_WITH_SECURITY_IMPLICATION(it != m_mapNamedFlowContentNodes.end());
- ASSERT(it->value);
- ASSERT(it->value->hasContentNode(contentNode));
- it->value->unregisterNamedFlowContentNode(contentNode);
- m_mapNamedFlowContentNodes.remove(contentNode);
-}
-
-void FlowThreadController::updateFlowThreadsChainIfNecessary()
-{
- ASSERT(m_renderNamedFlowThreadList);
- ASSERT(isAutoLogicalHeightRegionsCountConsistent());
-
- // Remove the left-over flow threads.
- RenderNamedFlowThreadList toRemoveList;
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- if (flowRenderer->isMarkedForDestruction())
- toRemoveList.add(flowRenderer);
- }
-
- if (toRemoveList.size() > 0)
- setIsRenderNamedFlowThreadOrderDirty(true);
-
- for (RenderNamedFlowThreadList::iterator iter = toRemoveList.begin(); iter != toRemoveList.end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- m_renderNamedFlowThreadList->remove(flowRenderer);
- flowRenderer->destroy();
- }
-
- if (isRenderNamedFlowThreadOrderDirty()) {
- // Arrange the thread list according to dependencies.
- RenderNamedFlowThreadList sortedList;
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- if (sortedList.contains(flowRenderer))
- continue;
- flowRenderer->pushDependencies(sortedList);
- sortedList.add(flowRenderer);
- }
- m_renderNamedFlowThreadList->swap(sortedList);
- setIsRenderNamedFlowThreadOrderDirty(false);
- }
-}
-
-bool FlowThreadController::updateFlowThreadsNeedingLayout()
-{
- bool needsTwoPassLayout = false;
-
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- ASSERT(!flowRenderer->needsTwoPhasesLayout());
- flowRenderer->setInConstrainedLayoutPhase(false);
- if (flowRenderer->needsLayout() && flowRenderer->hasAutoLogicalHeightRegions())
- needsTwoPassLayout = true;
- }
-
- if (needsTwoPassLayout)
- resetFlowThreadsWithAutoHeightRegions();
-
- return needsTwoPassLayout;
-}
-
-bool FlowThreadController::updateFlowThreadsNeedingTwoStepLayout()
-{
- bool needsTwoPassLayout = false;
-
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- if (flowRenderer->needsTwoPhasesLayout()) {
- needsTwoPassLayout = true;
- break;
- }
- }
-
- if (needsTwoPassLayout)
- resetFlowThreadsWithAutoHeightRegions();
-
- return needsTwoPassLayout;
-}
-
-void FlowThreadController::resetFlowThreadsWithAutoHeightRegions()
-{
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- if (flowRenderer->hasAutoLogicalHeightRegions()) {
- flowRenderer->markAutoLogicalHeightRegionsForLayout();
- flowRenderer->invalidateRegions();
- }
- }
-}
-
-void FlowThreadController::updateFlowThreadsIntoConstrainedPhase()
-{
- // Walk the flow chain in reverse order to update the auto-height regions and compute correct sizes for the containing regions. Only after this we can
- // set the flow in the constrained layout phase.
- for (RenderNamedFlowThreadList::reverse_iterator iter = m_renderNamedFlowThreadList->rbegin(); iter != m_renderNamedFlowThreadList->rend(); ++iter) {
- RenderNamedFlowThread* flowRenderer = *iter;
- ASSERT(!flowRenderer->hasRegions() || flowRenderer->hasValidRegionInfo());
- flowRenderer->layoutIfNeeded();
- if (flowRenderer->hasAutoLogicalHeightRegions()) {
- ASSERT(flowRenderer->needsTwoPhasesLayout());
- flowRenderer->markAutoLogicalHeightRegionsForLayout();
- }
- flowRenderer->setInConstrainedLayoutPhase(true);
- flowRenderer->clearNeedsTwoPhasesLayout();
- }
-}
-
-bool FlowThreadController::isContentNodeRegisteredWithAnyNamedFlow(const Node* contentNode) const
-{
- return m_mapNamedFlowContentNodes.contains(contentNode);
-}
-
-#ifndef NDEBUG
-bool FlowThreadController::isAutoLogicalHeightRegionsCountConsistent() const
-{
- if (!hasRenderNamedFlowThreads())
- return !hasFlowThreadsWithAutoLogicalHeightRegions();
-
- for (RenderNamedFlowThreadList::iterator iter = m_renderNamedFlowThreadList->begin(); iter != m_renderNamedFlowThreadList->end(); ++iter) {
- if (!(*iter)->isAutoLogicalHeightRegionsCountConsistent())
- return false;
- }
-
- return true;
}
-#endif
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.h b/chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.h
index 7f56615d7de..1b1372b29b1 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/FlowThreadController.h
@@ -30,69 +30,26 @@
#ifndef FlowThreadController_h
#define FlowThreadController_h
-#include "core/rendering/RenderView.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/OwnPtr.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/PassOwnPtr.h"
namespace WebCore {
class RenderFlowThread;
-class RenderNamedFlowThread;
-
-typedef ListHashSet<RenderNamedFlowThread*> RenderNamedFlowThreadList;
class FlowThreadController {
WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<FlowThreadController> create(RenderView*);
- ~FlowThreadController();
+ static PassOwnPtr<FlowThreadController> create();
RenderFlowThread* currentRenderFlowThread() const { return m_currentRenderFlowThread; }
void setCurrentRenderFlowThread(RenderFlowThread* flowThread) { m_currentRenderFlowThread = flowThread; }
- bool isRenderNamedFlowThreadOrderDirty() const { return m_isRenderNamedFlowThreadOrderDirty; }
- void setIsRenderNamedFlowThreadOrderDirty(bool dirty)
- {
- m_isRenderNamedFlowThreadOrderDirty = dirty;
- if (dirty)
- m_view->setNeedsLayout();
- }
-
- RenderNamedFlowThread* ensureRenderFlowThreadWithName(const AtomicString&);
- const RenderNamedFlowThreadList* renderNamedFlowThreadList() const { return m_renderNamedFlowThreadList.get(); }
- bool hasRenderNamedFlowThreads() const { return m_renderNamedFlowThreadList && !m_renderNamedFlowThreadList->isEmpty(); }
- void layoutRenderNamedFlowThreads();
- void styleDidChange();
-
- void registerNamedFlowContentNode(Node*, RenderNamedFlowThread*);
- void unregisterNamedFlowContentNode(Node*);
- bool isContentNodeRegisteredWithAnyNamedFlow(const Node*) const;
-
- bool hasFlowThreadsWithAutoLogicalHeightRegions() const { return m_flowThreadsWithAutoLogicalHeightRegions; }
- void incrementFlowThreadsWithAutoLogicalHeightRegions() { ++m_flowThreadsWithAutoLogicalHeightRegions; }
- void decrementFlowThreadsWithAutoLogicalHeightRegions() { ASSERT(m_flowThreadsWithAutoLogicalHeightRegions > 0); --m_flowThreadsWithAutoLogicalHeightRegions; }
-
- bool updateFlowThreadsNeedingLayout();
- bool updateFlowThreadsNeedingTwoStepLayout();
- void updateFlowThreadsIntoConstrainedPhase();
-
-#ifndef NDEBUG
- bool isAutoLogicalHeightRegionsCountConsistent() const;
-#endif
-
protected:
- FlowThreadController(RenderView*);
- void updateFlowThreadsChainIfNecessary();
- void resetFlowThreadsWithAutoHeightRegions();
+ FlowThreadController();
private:
- RenderView* m_view;
RenderFlowThread* m_currentRenderFlowThread;
- bool m_isRenderNamedFlowThreadOrderDirty;
- unsigned m_flowThreadsWithAutoLogicalHeightRegions;
- OwnPtr<RenderNamedFlowThreadList> m_renderNamedFlowThreadList;
- // maps a content node to its render flow thread.
- HashMap<const Node*, RenderNamedFlowThread*> m_mapNamedFlowContentNodes;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.cpp b/chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.cpp
index f532480df20..20d4ba557e9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.cpp
@@ -22,17 +22,10 @@
#include "config.h"
#include "core/rendering/HitTestLocation.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-
namespace WebCore {
-using namespace HTMLNames;
-
HitTestLocation::HitTestLocation()
- : m_region(0)
- , m_isRectBased(false)
+ : m_isRectBased(false)
, m_isRectilinear(true)
{
}
@@ -42,7 +35,6 @@ HitTestLocation::HitTestLocation(const LayoutPoint& point)
, m_boundingBox(rectForPoint(point, 0, 0, 0, 0))
, m_transformedPoint(point)
, m_transformedRect(m_boundingBox)
- , m_region(0)
, m_isRectBased(false)
, m_isRectilinear(true)
{
@@ -53,7 +45,6 @@ HitTestLocation::HitTestLocation(const FloatPoint& point)
, m_boundingBox(rectForPoint(m_point, 0, 0, 0, 0))
, m_transformedPoint(point)
, m_transformedRect(m_boundingBox)
- , m_region(0)
, m_isRectBased(false)
, m_isRectilinear(true)
{
@@ -62,7 +53,6 @@ HitTestLocation::HitTestLocation(const FloatPoint& point)
HitTestLocation::HitTestLocation(const FloatPoint& point, const FloatQuad& quad)
: m_transformedPoint(point)
, m_transformedRect(quad)
- , m_region(0)
, m_isRectBased(true)
{
m_point = flooredLayoutPoint(point);
@@ -74,19 +64,17 @@ HitTestLocation::HitTestLocation(const LayoutPoint& centerPoint, unsigned topPad
: m_point(centerPoint)
, m_boundingBox(rectForPoint(centerPoint, topPadding, rightPadding, bottomPadding, leftPadding))
, m_transformedPoint(centerPoint)
- , m_region(0)
, m_isRectBased(topPadding || rightPadding || bottomPadding || leftPadding)
, m_isRectilinear(true)
{
m_transformedRect = FloatQuad(m_boundingBox);
}
-HitTestLocation::HitTestLocation(const HitTestLocation& other, const LayoutSize& offset, RenderRegion* region)
+HitTestLocation::HitTestLocation(const HitTestLocation& other, const LayoutSize& offset)
: m_point(other.m_point)
, m_boundingBox(other.m_boundingBox)
, m_transformedPoint(other.m_transformedPoint)
, m_transformedRect(other.m_transformedRect)
- , m_region(region ? region : other.m_region)
, m_isRectBased(other.m_isRectBased)
, m_isRectilinear(other.m_isRectilinear)
{
@@ -98,7 +86,6 @@ HitTestLocation::HitTestLocation(const HitTestLocation& other)
, m_boundingBox(other.m_boundingBox)
, m_transformedPoint(other.m_transformedPoint)
, m_transformedRect(other.m_transformedRect)
- , m_region(other.m_region)
, m_isRectBased(other.m_isRectBased)
, m_isRectilinear(other.m_isRectilinear)
{
@@ -114,7 +101,6 @@ HitTestLocation& HitTestLocation::operator=(const HitTestLocation& other)
m_boundingBox = other.m_boundingBox;
m_transformedPoint = other.m_transformedPoint;
m_transformedRect = other.m_transformedRect;
- m_region = other.m_region;
m_isRectBased = other.m_isRectBased;
m_isRectilinear = other.m_isRectilinear;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.h b/chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.h
index 7edcd8e03bc..ff18d79c646 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/HitTestLocation.h
@@ -33,14 +33,6 @@
namespace WebCore {
-class Element;
-class Frame;
-class Image;
-class KURL;
-class Node;
-class RenderRegion;
-class Scrollbar;
-
class HitTestLocation {
public:
@@ -50,8 +42,7 @@ public:
HitTestLocation(const FloatPoint&, const FloatQuad&);
// Pass non-zero padding values to perform a rect-based hit test.
HitTestLocation(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding);
- // Make a copy the HitTestLocation in a new region by applying given offset to internal point and area.
- HitTestLocation(const HitTestLocation&, const LayoutSize& offset, RenderRegion* = 0);
+ HitTestLocation(const HitTestLocation&, const LayoutSize& offset);
HitTestLocation(const HitTestLocation&);
~HitTestLocation();
HitTestLocation& operator=(const HitTestLocation&);
@@ -59,8 +50,6 @@ public:
const LayoutPoint& point() const { return m_point; }
IntPoint roundedPoint() const { return roundedIntPoint(m_point); }
- RenderRegion* region() const { return m_region; }
-
// Rect-based hit test related methods.
bool isRectBasedTest() const { return m_isRectBased; }
bool isRectilinear() const { return m_isRectilinear; }
@@ -91,8 +80,6 @@ private:
FloatPoint m_transformedPoint;
FloatQuad m_transformedRect;
- RenderRegion* m_region; // The region we're inside.
-
bool m_isRectBased;
bool m_isRectilinear;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/HitTestRequest.h b/chromium/third_party/WebKit/Source/core/rendering/HitTestRequest.h
index 97dfa5165a7..c8a63ef9c49 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/HitTestRequest.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/HitTestRequest.h
@@ -40,7 +40,7 @@ public:
AllowFrameScrollbars = 1 << 9,
AllowChildFrameContent = 1 << 10,
ChildFrameHitTest = 1 << 11,
- IgnorePointerEventsNone = 1 << 12
+ IgnorePointerEventsNone = 1 << 12,
};
typedef unsigned HitTestRequestType;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/HitTestResult.cpp b/chromium/third_party/WebKit/Source/core/rendering/HitTestResult.cpp
index ad4e162801f..bce50193911 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/HitTestResult.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/HitTestResult.cpp
@@ -22,26 +22,23 @@
#include "config.h"
#include "core/rendering/HitTestResult.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
+#include "core/HTMLNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/NodeRenderingTraversal.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/FrameSelection.h"
#include "core/fetch/ImageResource.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAnchorElement.h"
-#include "core/html/HTMLAreaElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLMediaElement.h"
-#include "core/html/HTMLTextAreaElement.h"
-#include "core/html/HTMLVideoElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/Frame.h"
#include "core/page/FrameTree.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderTextFragment.h"
+#include "core/svg/SVGElement.h"
#include "platform/scroll/Scrollbar.h"
namespace WebCore {
@@ -91,7 +88,7 @@ HitTestResult::HitTestResult(const HitTestResult& other)
, m_isFirstLetter(other.m_isFirstLetter)
{
// Only copy the NodeSet in case of rect hit test.
- m_rectBasedTestResult = adoptPtr(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0);
+ m_rectBasedTestResult = adoptPtrWillBeNoop(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0);
}
HitTestResult::~HitTestResult()
@@ -112,7 +109,7 @@ HitTestResult& HitTestResult::operator=(const HitTestResult& other)
m_isOverWidget = other.isOverWidget();
// Only copy the NodeSet in case of rect hit test.
- m_rectBasedTestResult = adoptPtr(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0);
+ m_rectBasedTestResult = adoptPtrWillBeNoop(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0);
return *this;
}
@@ -182,7 +179,7 @@ void HitTestResult::setScrollbar(Scrollbar* s)
m_scrollbar = s;
}
-Frame* HitTestResult::innerNodeFrame() const
+LocalFrame* HitTestResult::innerNodeFrame() const
{
if (m_innerNonSharedNode)
return m_innerNonSharedNode->document().frame();
@@ -191,24 +188,12 @@ Frame* HitTestResult::innerNodeFrame() const
return 0;
}
-Frame* HitTestResult::targetFrame() const
-{
- if (!m_innerURLElement)
- return 0;
-
- Frame* frame = m_innerURLElement->document().frame();
- if (!frame)
- return 0;
-
- return frame->tree().find(m_innerURLElement->target());
-}
-
bool HitTestResult::isSelected() const
{
if (!m_innerNonSharedNode)
return false;
- if (Frame* frame = m_innerNonSharedNode->document().frame())
+ if (LocalFrame* frame = m_innerNonSharedNode->document().frame())
return frame->selection().contains(m_hitTestLocation.point());
return false;
}
@@ -221,7 +206,7 @@ String HitTestResult::spellingToolTip(TextDirection& dir) const
if (!m_innerNonSharedNode)
return String();
- DocumentMarker* marker = m_innerNonSharedNode->document().markers()->markerContainingPoint(m_hitTestLocation.point(), DocumentMarker::Grammar);
+ DocumentMarker* marker = m_innerNonSharedNode->document().markers().markerContainingPoint(m_hitTestLocation.point(), DocumentMarker::Grammar);
if (!marker)
return String();
@@ -253,14 +238,14 @@ const AtomicString& HitTestResult::altDisplayString() const
if (!m_innerNonSharedNode)
return nullAtom;
- if (m_innerNonSharedNode->hasTagName(imgTag)) {
- HTMLImageElement* image = toHTMLImageElement(m_innerNonSharedNode);
- return image->getAttribute(altAttr);
+ if (isHTMLImageElement(*m_innerNonSharedNode)) {
+ HTMLImageElement& image = toHTMLImageElement(*m_innerNonSharedNode);
+ return image.getAttribute(altAttr);
}
- if (m_innerNonSharedNode->hasTagName(inputTag)) {
- HTMLInputElement* input = toHTMLInputElement(m_innerNonSharedNode);
- return input->alt();
+ if (isHTMLInputElement(*m_innerNonSharedNode)) {
+ HTMLInputElement& input = toHTMLInputElement(*m_innerNonSharedNode);
+ return input.alt();
}
return nullAtom;
@@ -293,17 +278,19 @@ KURL HitTestResult::absoluteImageURL() const
if (!m_innerNonSharedNode)
return KURL();
- if (!(m_innerNonSharedNode->renderer() && m_innerNonSharedNode->renderer()->isImage()))
+ RenderObject* renderer = m_innerNonSharedNode->renderer();
+ if (!(renderer && (renderer->isImage() || renderer->isCanvas())))
return KURL();
AtomicString urlString;
- if (m_innerNonSharedNode->hasTagName(embedTag)
- || m_innerNonSharedNode->hasTagName(imgTag)
- || m_innerNonSharedNode->hasTagName(inputTag)
- || m_innerNonSharedNode->hasTagName(objectTag)
- || m_innerNonSharedNode->hasTagName(SVGNames::imageTag)
+ if (isHTMLCanvasElement(*m_innerNonSharedNode)
+ || isHTMLEmbedElement(*m_innerNonSharedNode)
+ || isHTMLImageElement(*m_innerNonSharedNode)
+ || isHTMLInputElement(*m_innerNonSharedNode)
+ || isHTMLObjectElement(*m_innerNonSharedNode)
+ || isSVGImageElement(*m_innerNonSharedNode)
) {
- urlString = toElement(m_innerNonSharedNode)->imageSourceURL();
+ urlString = toElement(*m_innerNonSharedNode).imageSourceURL();
} else
return KURL();
@@ -325,8 +312,8 @@ HTMLMediaElement* HitTestResult::mediaElement() const
if (!(m_innerNonSharedNode->renderer() && m_innerNonSharedNode->renderer()->isMedia()))
return 0;
- if (isHTMLVideoElement(m_innerNonSharedNode.get()) || m_innerNonSharedNode->hasTagName(HTMLNames::audioTag))
- return toHTMLMediaElement(m_innerNonSharedNode.get());
+ if (isHTMLMediaElement(*m_innerNonSharedNode))
+ return toHTMLMediaElement(m_innerNonSharedNode);
return 0;
}
@@ -336,9 +323,9 @@ KURL HitTestResult::absoluteLinkURL() const
return KURL();
AtomicString urlString;
- if (isHTMLAnchorElement(m_innerURLElement.get()) || isHTMLAreaElement(m_innerURLElement.get()) || m_innerURLElement->hasTagName(linkTag))
+ if (isHTMLAnchorElement(*m_innerURLElement) || isHTMLAreaElement(*m_innerURLElement) || isHTMLLinkElement(*m_innerURLElement))
urlString = m_innerURLElement->getAttribute(hrefAttr);
- else if (m_innerURLElement->hasTagName(SVGNames::aTag))
+ else if (isSVGAElement(*m_innerURLElement))
urlString = m_innerURLElement->getAttribute(XLinkNames::hrefAttr);
else
return KURL();
@@ -351,10 +338,10 @@ bool HitTestResult::isLiveLink() const
if (!m_innerURLElement)
return false;
- if (isHTMLAnchorElement(m_innerURLElement.get()))
+ if (isHTMLAnchorElement(*m_innerURLElement))
return toHTMLAnchorElement(m_innerURLElement)->isLiveLink();
- if (m_innerURLElement->hasTagName(SVGNames::aTag))
+ if (isSVGAElement(*m_innerURLElement))
return m_innerURLElement->isLink();
return false;
@@ -362,12 +349,12 @@ bool HitTestResult::isLiveLink() const
bool HitTestResult::isMisspelled() const
{
- if (!targetNode())
+ if (!targetNode() || !targetNode()->renderer())
return false;
VisiblePosition pos(targetNode()->renderer()->positionForPoint(localPoint()));
if (pos.isNull())
return false;
- return m_innerNonSharedNode->document().markers()->markersInRange(
+ return m_innerNonSharedNode->document().markers().markersInRange(
makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers()).size() > 0;
}
@@ -376,14 +363,6 @@ bool HitTestResult::isOverLink() const
return m_innerURLElement && m_innerURLElement->isLink();
}
-String HitTestResult::titleDisplayString() const
-{
- if (!m_innerURLElement)
- return String();
-
- return m_innerURLElement->title();
-}
-
String HitTestResult::textContent() const
{
if (!m_innerURLElement)
@@ -400,11 +379,11 @@ bool HitTestResult::isContentEditable() const
if (!m_innerNonSharedNode)
return false;
- if (isHTMLTextAreaElement(m_innerNonSharedNode.get()))
+ if (isHTMLTextAreaElement(*m_innerNonSharedNode))
return true;
- if (m_innerNonSharedNode->hasTagName(inputTag))
- return toHTMLInputElement(m_innerNonSharedNode)->isTextField();
+ if (isHTMLInputElement(*m_innerNonSharedNode))
+ return toHTMLInputElement(*m_innerNonSharedNode).isTextField();
return m_innerNonSharedNode->rendererIsEditable();
}
@@ -477,14 +456,14 @@ void HitTestResult::append(const HitTestResult& other)
const HitTestResult::NodeSet& HitTestResult::rectBasedTestResult() const
{
if (!m_rectBasedTestResult)
- m_rectBasedTestResult = adoptPtr(new NodeSet);
+ m_rectBasedTestResult = adoptPtrWillBeNoop(new NodeSet);
return *m_rectBasedTestResult;
}
HitTestResult::NodeSet& HitTestResult::mutableRectBasedTestResult()
{
if (!m_rectBasedTestResult)
- m_rectBasedTestResult = adoptPtr(new NodeSet);
+ m_rectBasedTestResult = adoptPtrWillBeNoop(new NodeSet);
return *m_rectBasedTestResult;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/HitTestResult.h b/chromium/third_party/WebKit/Source/core/rendering/HitTestResult.h
index 490596e4035..4db557a1fc1 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/HitTestResult.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/HitTestResult.h
@@ -27,6 +27,7 @@
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/LayoutRect.h"
+#include "platform/heap/Handle.h"
#include "platform/text/TextDirection.h"
#include "wtf/Forward.h"
#include "wtf/ListHashSet.h"
@@ -36,18 +37,17 @@
namespace WebCore {
class Element;
-class Frame;
+class LocalFrame;
class HTMLMediaElement;
class Image;
class KURL;
class Node;
class RenderObject;
-class RenderRegion;
class Scrollbar;
class HitTestResult {
public:
- typedef ListHashSet<RefPtr<Node> > NodeSet;
+ typedef WillBeHeapListHashSet<RefPtrWillBeMember<Node> > NodeSet;
HitTestResult();
HitTestResult(const LayoutPoint&);
@@ -76,7 +76,7 @@ public:
// The hit-tested point in the coordinates of the innerNode frame, the frame containing innerNode.
const LayoutPoint& pointInInnerNodeFrame() const { return m_pointInInnerNodeFrame; }
IntPoint roundedPointInInnerNodeFrame() const { return roundedIntPoint(pointInInnerNodeFrame()); }
- Frame* innerNodeFrame() const;
+ LocalFrame* innerNodeFrame() const;
// The hit-tested point in the coordinates of the inner node.
const LayoutPoint& localPoint() const { return m_localPoint; }
@@ -96,12 +96,10 @@ public:
void setIsFirstLetter(bool b) { m_isFirstLetter = b; }
void setIsOverWidget(bool b) { m_isOverWidget = b; }
- Frame* targetFrame() const;
bool isSelected() const;
String spellingToolTip(TextDirection&) const;
String title(TextDirection&) const;
const AtomicString& altDisplayString() const;
- String titleDisplayString() const;
Image* image() const;
IntRect imageRect() const;
KURL absoluteImageURL() const;
@@ -132,18 +130,18 @@ private:
HitTestLocation m_hitTestLocation;
- RefPtr<Node> m_innerNode;
- RefPtr<Node> m_innerPossiblyPseudoNode;
- RefPtr<Node> m_innerNonSharedNode;
+ RefPtrWillBePersistent<Node> m_innerNode;
+ RefPtrWillBePersistent<Node> m_innerPossiblyPseudoNode;
+ RefPtrWillBePersistent<Node> m_innerNonSharedNode;
LayoutPoint m_pointInInnerNodeFrame; // The hit-tested point in innerNode frame coordinates.
LayoutPoint m_localPoint; // A point in the local coordinate space of m_innerNonSharedNode's renderer. Allows us to efficiently
// determine where inside the renderer we hit on subsequent operations.
- RefPtr<Element> m_innerURLElement;
+ RefPtrWillBePersistent<Element> m_innerURLElement;
RefPtr<Scrollbar> m_scrollbar;
bool m_isOverWidget; // Returns true if we are over a widget (and not in the border/padding area of a RenderWidget for example).
bool m_isFirstLetter;
- mutable OwnPtr<NodeSet> m_rectBasedTestResult;
+ mutable OwnPtrWillBePersistent<NodeSet> m_rectBasedTestResult;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.cpp b/chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.cpp
index ef4c23b73c8..09751291106 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.cpp
@@ -31,8 +31,8 @@
#include "config.h"
#include "core/rendering/ImageQualityController.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "platform/graphics/GraphicsContext.h"
namespace WebCore {
@@ -60,6 +60,21 @@ void ImageQualityController::remove(RenderObject* renderer)
}
}
+InterpolationQuality ImageQualityController::chooseInterpolationQuality(GraphicsContext* context, RenderObject* object, Image* image, const void* layer, const LayoutSize& layoutSize)
+{
+ if (InterpolationDefault == InterpolationLow)
+ return InterpolationLow;
+
+ if (shouldPaintAtLowQuality(context, object, image, layer, layoutSize))
+ return InterpolationLow;
+
+ // For images that are potentially animated we paint them at medium quality.
+ if (image && image->maybeAnimated())
+ return InterpolationMedium;
+
+ return InterpolationDefault;
+}
+
ImageQualityController::~ImageQualityController()
{
// This will catch users of ImageQualityController that forget to call cleanUp.
@@ -109,14 +124,14 @@ void ImageQualityController::highQualityRepaintTimerFired(Timer<ImageQualityCont
m_animatedResizeIsActive = false;
for (ObjectLayerSizeMap::iterator it = m_objectLayerSizeMap.begin(); it != m_objectLayerSizeMap.end(); ++it) {
- if (Frame* frame = it->key->document().frame()) {
+ if (LocalFrame* frame = it->key->document().frame()) {
// If this renderer's containing FrameView is in live resize, punt the timer and hold back for now.
if (frame->view() && frame->view()->inLiveResize()) {
restartTimer();
return;
}
}
- it->key->repaint();
+ it->key->paintInvalidationForWholeRenderer();
}
m_liveResizeOptimizationIsActive = false;
@@ -124,7 +139,7 @@ void ImageQualityController::highQualityRepaintTimerFired(Timer<ImageQualityCont
void ImageQualityController::restartTimer()
{
- m_timer.startOneShot(cLowQualityTimeThreshold);
+ m_timer.startOneShot(cLowQualityTimeThreshold, FROM_HERE);
}
bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, RenderObject* object, Image* image, const void *layer, const LayoutSize& layoutSize)
@@ -159,7 +174,7 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
LayoutSize scaledLayoutSize = currentTransform.mapSize(roundedIntSize(layoutSize));
// If the containing FrameView is being resized, paint at low quality until resizing is finished.
- if (Frame* frame = object->document().frame()) {
+ if (LocalFrame* frame = object->document().frame()) {
bool frameViewIsCurrentlyInLiveResize = frame->view() && frame->view()->inLiveResize();
if (frameViewIsCurrentlyInLiveResize) {
set(object, innerMap, layer, scaledLayoutSize);
@@ -174,6 +189,9 @@ bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, R
}
}
+ // See crbug.com/382491. This test is insufficient to ensure that there is no scale
+ // applied in the compositor, but it is probably adequate here. In the worst case we
+ // draw at high quality when we need not.
if (!contextIsScaled && scaledLayoutSize == scaledImageSize) {
// There is no scale in effect. If we had a scale in effect before, we can just remove this object from the list.
removeLayer(object, innerMap, layer);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.h b/chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.h
index a9e8b108d88..71544283b8f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/ImageQualityController.h
@@ -53,11 +53,12 @@ public:
static void remove(RenderObject*);
- bool shouldPaintAtLowQuality(GraphicsContext*, RenderObject*, Image*, const void* layer, const LayoutSize&);
+ InterpolationQuality chooseInterpolationQuality(GraphicsContext*, RenderObject*, Image*, const void* layer, const LayoutSize&);
private:
ImageQualityController();
+ bool shouldPaintAtLowQuality(GraphicsContext*, RenderObject*, Image*, const void* layer, const LayoutSize&);
void removeLayer(RenderObject*, LayerSizeMap* innerMap, const void* layer);
void set(RenderObject*, LayerSizeMap* innerMap, const void* layer, const LayoutSize&);
void objectDestroyed(RenderObject*);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/InlineBox.cpp
index 0e1e21ea874..9ec715c6e63 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/InlineBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/InlineBox.cpp
@@ -58,10 +58,10 @@ InlineBox::~InlineBox()
#endif
-void InlineBox::remove()
+void InlineBox::remove(MarkLineBoxes markLineBoxes)
{
if (parent())
- parent()->removeChild(this);
+ parent()->removeChild(this, markLineBoxes);
}
void* InlineBox::operator new(size_t sz)
@@ -82,14 +82,12 @@ const char* InlineBox::boxName() const
void InlineBox::showTreeForThis() const
{
- if (m_renderer)
- m_renderer->showTreeForThis();
+ renderer().showTreeForThis();
}
void InlineBox::showLineTreeForThis() const
{
- if (m_renderer)
- m_renderer->containingBlock()->showLineTreeAndMark(this, "*");
+ renderer().containingBlock()->showLineTreeAndMark(this, "*");
}
void InlineBox::showLineTreeAndMark(const InlineBox* markedBox1, const char* markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const RenderObject* obj, int depth) const
@@ -99,7 +97,7 @@ void InlineBox::showLineTreeAndMark(const InlineBox* markedBox1, const char* mar
printedCharacters += fprintf(stderr, "%s", markedLabel1);
if (this == markedBox2)
printedCharacters += fprintf(stderr, "%s", markedLabel2);
- if (renderer() == obj)
+ if (&renderer() == obj)
printedCharacters += fprintf(stderr, "*");
for (; printedCharacters < depth * 2; printedCharacters++)
fputc(' ', stderr);
@@ -112,7 +110,10 @@ void InlineBox::showBox(int printedCharacters) const
printedCharacters += fprintf(stderr, "%s\t%p", boxName(), this);
for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
fputc(' ', stderr);
- fprintf(stderr, "\t%s %p\n", renderer() ? renderer()->renderName() : "No Renderer", renderer());
+ fprintf(stderr, "\t%s %p {pos=%g,%g size=%g,%g} baseline=%i/%i\n",
+ renderer().renderName(), &renderer(), x(), y(), width(), height(),
+ baselinePosition(AlphabeticBaseline),
+ baselinePosition(IdeographicBaseline));
}
#endif
@@ -121,14 +122,14 @@ float InlineBox::logicalHeight() const
if (hasVirtualLogicalHeight())
return virtualLogicalHeight();
- if (renderer()->isText())
- return m_bitfields.isText() ? renderer()->style(isFirstLineStyle())->fontMetrics().height() : 0;
- if (renderer()->isBox() && parent())
- return isHorizontal() ? toRenderBox(m_renderer)->height() : toRenderBox(m_renderer)->width();
+ if (renderer().isText())
+ return m_bitfields.isText() ? renderer().style(isFirstLineStyle())->fontMetrics().height() : 0;
+ if (renderer().isBox() && parent())
+ return isHorizontal() ? toRenderBox(renderer()).height().toFloat() : toRenderBox(renderer()).width().toFloat();
ASSERT(isInlineFlowBox());
RenderBoxModelObject* flowObject = boxModelObject();
- const FontMetrics& fontMetrics = renderer()->style(isFirstLineStyle())->fontMetrics();
+ const FontMetrics& fontMetrics = renderer().style(isFirstLineStyle())->fontMetrics();
float result = fontMetrics.height();
if (parent())
result += flowObject->borderAndPaddingLogicalHeight();
@@ -147,12 +148,12 @@ LayoutUnit InlineBox::lineHeight() const
int InlineBox::caretMinOffset() const
{
- return m_renderer->caretMinOffset();
+ return renderer().caretMinOffset();
}
int InlineBox::caretMaxOffset() const
{
- return m_renderer->caretMaxOffset();
+ return renderer().caretMaxOffset();
}
void InlineBox::dirtyLineBoxes()
@@ -164,43 +165,43 @@ void InlineBox::dirtyLineBoxes()
void InlineBox::deleteLine()
{
- if (!m_bitfields.extracted() && m_renderer->isBox())
- toRenderBox(m_renderer)->setInlineBoxWrapper(0);
+ if (!m_bitfields.extracted() && renderer().isBox())
+ toRenderBox(renderer()).setInlineBoxWrapper(0);
destroy();
}
void InlineBox::extractLine()
{
m_bitfields.setExtracted(true);
- if (m_renderer->isBox())
- toRenderBox(m_renderer)->setInlineBoxWrapper(0);
+ if (renderer().isBox())
+ toRenderBox(renderer()).setInlineBoxWrapper(0);
}
void InlineBox::attachLine()
{
m_bitfields.setExtracted(false);
- if (m_renderer->isBox())
- toRenderBox(m_renderer)->setInlineBoxWrapper(this);
+ if (renderer().isBox())
+ toRenderBox(renderer()).setInlineBoxWrapper(this);
}
void InlineBox::adjustPosition(float dx, float dy)
{
m_topLeft.move(dx, dy);
- if (m_renderer->isReplaced())
- toRenderBox(m_renderer)->move(dx, dy);
+ if (renderer().isReplaced())
+ toRenderBox(renderer()).move(dx, dy);
}
void InlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/)
{
- if (!paintInfo.shouldPaintWithinRoot(renderer()) || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
+ if (!paintInfo.shouldPaintWithinRoot(&renderer()) || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
return;
LayoutPoint childPoint = paintOffset;
- if (parent()->renderer()->style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
- childPoint = renderer()->containingBlock()->flipForWritingModeForChild(toRenderBox(renderer()), childPoint);
+ if (parent()->renderer().style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
+ childPoint = renderer().containingBlock()->flipForWritingModeForChild(&toRenderBox(renderer()), childPoint);
- RenderBlock::paintAsInlineBlock(renderer(), paintInfo, childPoint);
+ RenderBlock::paintAsInlineBlock(&renderer(), paintInfo, childPoint);
}
bool InlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/)
@@ -209,26 +210,26 @@ bool InlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
// own stacking context. (See Appendix E.2, section 6.4 on inline block/table elements in the CSS2.1
// specification.)
LayoutPoint childPoint = accumulatedOffset;
- if (parent()->renderer()->style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
- childPoint = renderer()->containingBlock()->flipForWritingModeForChild(toRenderBox(renderer()), childPoint);
+ if (parent()->renderer().style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
+ childPoint = renderer().containingBlock()->flipForWritingModeForChild(&toRenderBox(renderer()), childPoint);
- return renderer()->hitTest(request, result, locationInContainer, childPoint);
+ return renderer().hitTest(request, result, locationInContainer, childPoint);
}
-const RootInlineBox* InlineBox::root() const
+const RootInlineBox& InlineBox::root() const
{
if (m_parent)
return m_parent->root();
ASSERT(isRootInlineBox());
- return static_cast<const RootInlineBox*>(this);
+ return static_cast<const RootInlineBox&>(*this);
}
-RootInlineBox* InlineBox::root()
+RootInlineBox& InlineBox::root()
{
if (m_parent)
return m_parent->root();
ASSERT(isRootInlineBox());
- return static_cast<RootInlineBox*>(this);
+ return static_cast<RootInlineBox&>(*this);
}
bool InlineBox::nextOnLineExists() const
@@ -284,13 +285,13 @@ InlineBox* InlineBox::prevLeafChildIgnoringLineBreak() const
RenderObject::SelectionState InlineBox::selectionState()
{
- return renderer()->selectionState();
+ return renderer().selectionState();
}
bool InlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth) const
{
// Non-replaced elements can always accommodate an ellipsis.
- if (!m_renderer || !m_renderer->isReplaced())
+ if (!renderer().isReplaced())
return true;
IntRect boxRect(left(), 0, m_logicalWidth, 10);
@@ -314,41 +315,41 @@ void InlineBox::clearKnownToHaveNoOverflow()
FloatPoint InlineBox::locationIncludingFlipping()
{
- if (!renderer()->style()->isFlippedBlocksWritingMode())
+ if (!renderer().style()->isFlippedBlocksWritingMode())
return FloatPoint(x(), y());
- RenderBlockFlow* block = root()->block();
- if (block->style()->isHorizontalWritingMode())
- return FloatPoint(x(), block->height() - height() - y());
- else
- return FloatPoint(block->width() - width() - x(), y());
+ RenderBlockFlow& block = root().block();
+ if (block.style()->isHorizontalWritingMode())
+ return FloatPoint(x(), block.height() - height() - y());
+
+ return FloatPoint(block.width() - width() - x(), y());
}
void InlineBox::flipForWritingMode(FloatRect& rect)
{
- if (!renderer()->style()->isFlippedBlocksWritingMode())
+ if (!renderer().style()->isFlippedBlocksWritingMode())
return;
- root()->block()->flipForWritingMode(rect);
+ root().block().flipForWritingMode(rect);
}
FloatPoint InlineBox::flipForWritingMode(const FloatPoint& point)
{
- if (!renderer()->style()->isFlippedBlocksWritingMode())
+ if (!renderer().style()->isFlippedBlocksWritingMode())
return point;
- return root()->block()->flipForWritingMode(point);
+ return root().block().flipForWritingMode(point);
}
void InlineBox::flipForWritingMode(LayoutRect& rect)
{
- if (!renderer()->style()->isFlippedBlocksWritingMode())
+ if (!renderer().style()->isFlippedBlocksWritingMode())
return;
- root()->block()->flipForWritingMode(rect);
+ root().block().flipForWritingMode(rect);
}
LayoutPoint InlineBox::flipForWritingMode(const LayoutPoint& point)
{
- if (!renderer()->style()->isFlippedBlocksWritingMode())
+ if (!renderer().style()->isFlippedBlocksWritingMode())
return point;
- return root()->block()->flipForWritingMode(point);
+ return root().block().flipForWritingMode(point);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineBox.h b/chromium/third_party/WebKit/Source/core/rendering/InlineBox.h
index 5803cd17e2b..f319c846d5d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/InlineBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/InlineBox.h
@@ -30,11 +30,14 @@ class HitTestRequest;
class HitTestResult;
class RootInlineBox;
+enum MarkLineBoxes { MarkLineBoxesDirty, DontMarkLineBoxes };
+
// InlineBox represents a rectangle that occurs on a line. It corresponds to
// some RenderObject (i.e., it represents a portion of that RenderObject).
class InlineBox {
+ WTF_MAKE_NONCOPYABLE(InlineBox);
public:
- InlineBox(RenderObject* obj)
+ InlineBox(RenderObject& obj)
: m_next(0)
, m_prev(0)
, m_parent(0)
@@ -46,7 +49,7 @@ public:
{
}
- InlineBox(RenderObject* obj, FloatPoint topLeft, float logicalWidth, bool firstLine, bool constructed,
+ InlineBox(RenderObject& obj, FloatPoint topLeft, float logicalWidth, bool firstLine, bool constructed,
bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent)
: m_next(next)
, m_prev(prev)
@@ -146,7 +149,7 @@ public:
void setFirstLineStyleBit(bool firstLine) { m_bitfields.setFirstLine(firstLine); }
bool isFirstLineStyle() const { return m_bitfields.firstLine(); }
- void remove();
+ void remove(MarkLineBoxes = MarkLineBoxesDirty);
InlineBox* nextOnLine() const { return m_next; }
InlineBox* prevOnLine() const { return m_prev; }
@@ -173,7 +176,7 @@ public:
InlineBox* nextLeafChildIgnoringLineBreak() const;
InlineBox* prevLeafChildIgnoringLineBreak() const;
- RenderObject* renderer() const { return m_renderer; }
+ RenderObject& renderer() const { return m_renderer; }
InlineFlowBox* parent() const
{
@@ -182,8 +185,8 @@ public:
}
void setParent(InlineFlowBox* par) { m_parent = par; }
- const RootInlineBox* root() const;
- RootInlineBox* root();
+ const RootInlineBox& root() const;
+ RootInlineBox& root();
// x() is the left side of the box in the containing block's coordinate system.
void setX(float x) { m_topLeft.setX(x); }
@@ -254,7 +257,7 @@ public:
virtual void clearTruncation() { }
bool isDirty() const { return m_bitfields.dirty(); }
- virtual void markDirty(bool dirty = true) { m_bitfields.setDirty(dirty); }
+ virtual void markDirty() { m_bitfields.setDirty(true); }
virtual void dirtyLineBoxes();
@@ -270,15 +273,15 @@ public:
int expansion() const { return m_bitfields.expansion(); }
- bool visibleToHitTestRequest(const HitTestRequest& request) const { return renderer()->visibleToHitTestRequest(request); }
+ bool visibleToHitTestRequest(const HitTestRequest& request) const { return renderer().visibleToHitTestRequest(request); }
- EVerticalAlign verticalAlign() const { return renderer()->style(m_bitfields.firstLine())->verticalAlign(); }
+ EVerticalAlign verticalAlign() const { return renderer().style(m_bitfields.firstLine())->verticalAlign(); }
// Use with caution! The type is not checked!
RenderBoxModelObject* boxModelObject() const
{
- if (!m_renderer->isText())
- return toRenderBoxModelObject(m_renderer);
+ if (!renderer().isText())
+ return toRenderBoxModelObject(&renderer());
return 0;
}
@@ -377,6 +380,7 @@ private:
InlineBox* m_prev; // The previous element on the same line as us.
InlineFlowBox* m_parent; // The box that contains us.
+ RenderObject& m_renderer;
protected:
// For RootInlineBox
@@ -398,8 +402,6 @@ protected:
// For InlineFlowBox and InlineTextBox
bool extracted() const { return m_bitfields.extracted(); }
- RenderObject* m_renderer;
-
FloatPoint m_topLeft;
float m_logicalWidth;
@@ -427,6 +429,14 @@ inline void InlineBox::setHasBadParent()
#define DEFINE_INLINE_BOX_TYPE_CASTS(typeName) \
DEFINE_TYPE_CASTS(typeName, InlineBox, box, box->is##typeName(), box.is##typeName())
+// Allow equality comparisons of InlineBox's by reference or pointer, interchangeably.
+inline bool operator==(const InlineBox& a, const InlineBox& b) { return &a == &b; }
+inline bool operator==(const InlineBox& a, const InlineBox* b) { return &a == b; }
+inline bool operator==(const InlineBox* a, const InlineBox& b) { return a == &b; }
+inline bool operator!=(const InlineBox& a, const InlineBox& b) { return !(a == b); }
+inline bool operator!=(const InlineBox& a, const InlineBox* b) { return !(a == b); }
+inline bool operator!=(const InlineBox* a, const InlineBox& b) { return !(a == b); }
+
} // namespace WebCore
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.cpp
index 68952fc6e18..b3384b2e33c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.cpp
@@ -20,7 +20,7 @@
#include "config.h"
#include "core/rendering/InlineFlowBox.h"
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/dom/Document.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/InlineTextBox.h"
@@ -109,7 +109,7 @@ void InlineFlowBox::addToLine(InlineBox* child)
child->setFirstLineStyleBit(isFirstLineStyle());
child->setIsHorizontal(isHorizontal());
if (child->isText()) {
- if (child->renderer()->parent() == renderer())
+ if (child->renderer().parent() == renderer())
m_hasTextChildren = true;
setHasTextDescendantsOnAncestors(this);
} else if (child->isInlineFlowBox()) {
@@ -117,14 +117,14 @@ void InlineFlowBox::addToLine(InlineBox* child)
setHasTextDescendantsOnAncestors(this);
}
- if (descendantsHaveSameLineHeightAndBaseline() && !child->renderer()->isOutOfFlowPositioned()) {
- RenderStyle* parentStyle = renderer()->style(isFirstLineStyle());
- RenderStyle* childStyle = child->renderer()->style(isFirstLineStyle());
+ if (descendantsHaveSameLineHeightAndBaseline() && !child->renderer().isOutOfFlowPositioned()) {
+ RenderStyle* parentStyle = renderer().style(isFirstLineStyle());
+ RenderStyle* childStyle = child->renderer().style(isFirstLineStyle());
bool shouldClearDescendantsHaveSameLineHeightAndBaseline = false;
- if (child->renderer()->isReplaced())
+ if (child->renderer().isReplaced())
shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
else if (child->isText()) {
- if (child->renderer()->isBR() || child->renderer()->parent() != renderer()) {
+ if (child->renderer().isBR() || child->renderer().parent() != renderer()) {
if (!parentStyle->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle->font().fontMetrics())
|| parentStyle->lineHeight() != childStyle->lineHeight()
|| (parentStyle->verticalAlign() != BASELINE && !isRootInlineBox()) || childStyle->verticalAlign() != BASELINE)
@@ -133,7 +133,7 @@ void InlineFlowBox::addToLine(InlineBox* child)
if (childStyle->hasTextCombine() || childStyle->textEmphasisMark() != TextEmphasisMarkNone)
shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
} else {
- if (child->renderer()->isBR()) {
+ if (child->renderer().isBR()) {
// FIXME: This is dumb. We only turn off because current layout test results expect the <br> to be 0-height on the baseline.
// Other than making a zillion tests have to regenerate results, there's no reason to ditch the optimization here.
shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
@@ -154,19 +154,21 @@ void InlineFlowBox::addToLine(InlineBox* child)
clearDescendantsHaveSameLineHeightAndBaseline();
}
- if (!child->renderer()->isOutOfFlowPositioned()) {
+ if (!child->renderer().isOutOfFlowPositioned()) {
if (child->isText()) {
- RenderStyle* childStyle = child->renderer()->style(isFirstLineStyle());
+ RenderStyle* childStyle = child->renderer().style(isFirstLineStyle());
if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMarkNone || childStyle->textStrokeWidth())
child->clearKnownToHaveNoOverflow();
- } else if (child->renderer()->isReplaced()) {
- RenderBox* box = toRenderBox(child->renderer());
- if (box->hasRenderOverflow() || box->hasSelfPaintingLayer())
+ } else if (child->renderer().isReplaced()) {
+ RenderBox& box = toRenderBox(child->renderer());
+ if (box.hasRenderOverflow() || box.hasSelfPaintingLayer())
child->clearKnownToHaveNoOverflow();
- } else if (!child->renderer()->isBR() && (child->renderer()->style(isFirstLineStyle())->boxShadow() || child->boxModelObject()->hasSelfPaintingLayer()
- || (child->renderer()->isListMarker() && !toRenderListMarker(child->renderer())->isInside())
- || child->renderer()->style(isFirstLineStyle())->hasBorderImageOutsets()))
+ } else if (!child->renderer().isBR() && (child->renderer().style(isFirstLineStyle())->boxShadow() || child->boxModelObject()->hasSelfPaintingLayer()
+ || (child->renderer().isListMarker() && !toRenderListMarker(child->renderer()).isInside())
+ || child->renderer().style(isFirstLineStyle())->hasBorderImageOutsets()
+ || child->renderer().style(isFirstLineStyle())->hasOutline())) {
child->clearKnownToHaveNoOverflow();
+ }
if (knownToHaveNoOverflow() && child->isInlineFlowBox() && !toInlineFlowBox(child)->knownToHaveNoOverflow())
clearKnownToHaveNoOverflow();
@@ -175,14 +177,14 @@ void InlineFlowBox::addToLine(InlineBox* child)
checkConsistency();
}
-void InlineFlowBox::removeChild(InlineBox* child)
+void InlineFlowBox::removeChild(InlineBox* child, MarkLineBoxes markDirty)
{
checkConsistency();
- if (!isDirty())
+ if (markDirty == MarkLineBoxesDirty && !isDirty())
dirtyLineBoxes();
- root()->childRemoved(child);
+ root().childRemoved(child);
if (child == m_firstChild)
m_firstChild = child->nextOnLine();
@@ -222,7 +224,7 @@ void InlineFlowBox::deleteLine()
void InlineFlowBox::removeLineBoxFromRenderObject()
{
- toRenderInline(renderer())->lineBoxes()->removeLineBox(this);
+ rendererLineBoxes()->removeLineBox(this);
}
void InlineFlowBox::extractLine()
@@ -235,7 +237,7 @@ void InlineFlowBox::extractLine()
void InlineFlowBox::extractLineBoxFromRenderObject()
{
- toRenderInline(renderer())->lineBoxes()->extractLineBox(this);
+ rendererLineBoxes()->extractLineBox(this);
}
void InlineFlowBox::attachLine()
@@ -248,7 +250,7 @@ void InlineFlowBox::attachLine()
void InlineFlowBox::attachLineBoxToRenderObject()
{
- toRenderInline(renderer())->lineBoxes()->attachLineBox(this);
+ rendererLineBoxes()->attachLineBox(this);
}
void InlineFlowBox::adjustPosition(float dx, float dy)
@@ -262,7 +264,7 @@ void InlineFlowBox::adjustPosition(float dx, float dy)
RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const
{
- return toRenderInline(renderer())->lineBoxes();
+ return toRenderInline(renderer()).lineBoxes();
}
static inline bool isLastChildForRenderer(RenderObject* ancestor, RenderObject* child)
@@ -276,7 +278,7 @@ static inline bool isLastChildForRenderer(RenderObject* ancestor, RenderObject*
RenderObject* curr = child;
RenderObject* parent = curr->parent();
while (parent && (!parent->isRenderBlock() || parent->isInline())) {
- if (parent->lastChild() != curr)
+ if (parent->slowLastChild() != curr)
return false;
if (parent == ancestor)
return true;
@@ -308,13 +310,13 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, bool isLogically
// The root inline box never has borders/margins/padding.
if (parent()) {
- bool ltr = renderer()->style()->isLeftToRightDirection();
+ bool ltr = renderer().style()->isLeftToRightDirection();
// Check to see if all initial lines are unconstructed. If so, then
// we know the inline began on this line (unless we are a continuation).
RenderLineBoxList* lineBoxList = rendererLineBoxes();
- if (!lineBoxList->firstLineBox()->isConstructed() && !renderer()->isInlineElementContinuation()) {
- if (renderer()->style()->boxDecorationBreak() == DCLONE)
+ if (!lineBoxList->firstLineBox()->isConstructed() && !renderer().isInlineElementContinuation()) {
+ if (renderer().style()->boxDecorationBreak() == DCLONE)
includeLeftEdge = includeRightEdge = true;
else if (ltr && lineBoxList->firstLineBox() == this)
includeLeftEdge = true;
@@ -323,23 +325,23 @@ void InlineFlowBox::determineSpacingForFlowBoxes(bool lastLine, bool isLogically
}
if (!lineBoxList->lastLineBox()->isConstructed()) {
- RenderInline* inlineFlow = toRenderInline(renderer());
- bool isLastObjectOnLine = !isAnsectorAndWithinBlock(renderer(), logicallyLastRunRenderer) || (isLastChildForRenderer(renderer(), logicallyLastRunRenderer) && !isLogicallyLastRunWrapped);
+ RenderInline& inlineFlow = toRenderInline(renderer());
+ bool isLastObjectOnLine = !isAnsectorAndWithinBlock(&renderer(), logicallyLastRunRenderer) || (isLastChildForRenderer(&renderer(), logicallyLastRunRenderer) && !isLogicallyLastRunWrapped);
// We include the border under these conditions:
// (1) The next line was not created, or it is constructed. We check the previous line for rtl.
// (2) The logicallyLastRun is not a descendant of this renderer.
// (3) The logicallyLastRun is a descendant of this renderer, but it is the last child of this renderer and it does not wrap to the next line.
// (4) The decoration break is set to clone therefore there will be borders on every sides.
- if (renderer()->style()->boxDecorationBreak() == DCLONE)
+ if (renderer().style()->boxDecorationBreak() == DCLONE)
includeLeftEdge = includeRightEdge = true;
else if (ltr) {
if (!nextLineBox()
- && ((lastLine || isLastObjectOnLine) && !inlineFlow->continuation()))
+ && ((lastLine || isLastObjectOnLine) && !inlineFlow.continuation()))
includeRightEdge = true;
} else {
if ((!prevLineBox() || prevLineBox()->isConstructed())
- && ((lastLine || isLastObjectOnLine) && !inlineFlow->continuation()))
+ && ((lastLine || isLastObjectOnLine) && !inlineFlow.continuation()))
includeLeftEdge = true;
}
}
@@ -377,13 +379,13 @@ float InlineFlowBox::placeBoxesInInlineDirection(float logicalLeft, bool& needsW
float InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* firstChild, InlineBox* lastChild, float& logicalLeft, float& minLogicalLeft, float& maxLogicalRight, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
{
for (InlineBox* curr = firstChild; curr && curr != lastChild; curr = curr->nextOnLine()) {
- if (curr->renderer()->isText()) {
+ if (curr->renderer().isText()) {
InlineTextBox* text = toInlineTextBox(curr);
- RenderText* rt = toRenderText(text->renderer());
- if (rt->textLength()) {
- if (needsWordSpacing && isSpaceOrNewline(rt->characterAt(text->start())))
- logicalLeft += rt->style(isFirstLineStyle())->font().wordSpacing();
- needsWordSpacing = !isSpaceOrNewline(rt->characterAt(text->end()));
+ RenderText& rt = toRenderText(text->renderer());
+ if (rt.textLength()) {
+ if (needsWordSpacing && isSpaceOrNewline(rt.characterAt(text->start())))
+ logicalLeft += rt.style(isFirstLineStyle())->font().fontDescription().wordSpacing();
+ needsWordSpacing = !isSpaceOrNewline(rt.characterAt(text->end()));
}
text->setLogicalLeft(logicalLeft);
if (knownToHaveNoOverflow())
@@ -392,17 +394,18 @@ float InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* firstChild, Inlin
if (knownToHaveNoOverflow())
maxLogicalRight = max(logicalLeft, maxLogicalRight);
} else {
- if (curr->renderer()->isOutOfFlowPositioned()) {
- if (curr->renderer()->parent()->style()->isLeftToRightDirection())
+ if (curr->renderer().isOutOfFlowPositioned()) {
+ if (curr->renderer().parent()->style()->isLeftToRightDirection()) {
curr->setLogicalLeft(logicalLeft);
- else
+ } else {
// Our offset that we cache needs to be from the edge of the right border box and
// not the left border box. We have to subtract |x| from the width of the block
// (which can be obtained from the root line box).
- curr->setLogicalLeft(root()->block()->logicalWidth() - logicalLeft);
+ curr->setLogicalLeft(root().block().logicalWidth() - logicalLeft);
+ }
continue; // The positioned object has no effect on the width.
}
- if (curr->renderer()->isRenderInline()) {
+ if (curr->renderer().isRenderInline()) {
InlineFlowBox* flow = toInlineFlowBox(curr);
logicalLeft += flow->marginLogicalLeft();
if (knownToHaveNoOverflow())
@@ -411,7 +414,7 @@ float InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* firstChild, Inlin
if (knownToHaveNoOverflow())
maxLogicalRight = max(logicalLeft, maxLogicalRight);
logicalLeft += flow->marginLogicalRight();
- } else if (!curr->renderer()->isListMarker() || toRenderListMarker(curr->renderer())->isInside()) {
+ } else if (!curr->renderer().isListMarker() || toRenderListMarker(curr->renderer()).isInside()) {
// The box can have a different writing-mode than the overall line, so this is a bit complicated.
// Just get all the physical margin and overflow values by hand based off |isVertical|.
LayoutUnit logicalLeftMargin = isHorizontal() ? curr->boxModelObject()->marginLeft() : curr->boxModelObject()->marginTop();
@@ -438,19 +441,19 @@ bool InlineFlowBox::requiresIdeographicBaseline(const GlyphOverflowAndFallbackFo
if (isHorizontal())
return false;
- if (renderer()->style(isFirstLineStyle())->fontDescription().nonCJKGlyphOrientation() == NonCJKGlyphOrientationUpright
- || renderer()->style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())
+ if (renderer().style(isFirstLineStyle())->fontDescription().nonCJKGlyphOrientation() == NonCJKGlyphOrientationUpright
+ || renderer().style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())
return true;
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders don't affect calculations.
if (curr->isInlineFlowBox()) {
if (toInlineFlowBox(curr)->requiresIdeographicBaseline(textBoxDataMap))
return true;
} else {
- if (curr->renderer()->style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())
+ if (curr->renderer().style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())
return true;
const Vector<const SimpleFontData*>* usedFonts = 0;
@@ -476,7 +479,7 @@ void InlineFlowBox::adjustMaxAscentAndDescent(int& maxAscent, int& maxDescent, i
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
// The computed lineheight needs to be extended for the
// positioned elements
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders don't affect calculations.
if (curr->verticalAlign() == TOP || curr->verticalAlign() == BOTTOM) {
int lineHeight = curr->lineHeight();
@@ -543,7 +546,7 @@ void InlineFlowBox::computeLogicalBoxHeights(RootInlineBox* rootBox, LayoutUnit&
return;
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders don't affect calculations.
InlineFlowBox* inlineFlowBox = curr->isInlineFlowBox() ? toInlineFlowBox(curr) : 0;
@@ -554,7 +557,7 @@ void InlineFlowBox::computeLogicalBoxHeights(RootInlineBox* rootBox, LayoutUnit&
// The verticalPositionForBox function returns the distance between the child box's baseline
// and the root box's baseline. The value is negative if the child box's baseline is above the
// root box's baseline, and it is positive if the child box's baseline is below the root box's baseline.
- curr->setLogicalTop(rootBox->verticalPositionForBox(curr, verticalPositionCache));
+ curr->setLogicalTop(rootBox->verticalPositionForBox(curr, verticalPositionCache).toFloat());
int ascent = 0;
int descent = 0;
@@ -600,7 +603,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei
{
bool isRootBox = isRootInlineBox();
if (isRootBox) {
- const FontMetrics& fontMetrics = renderer()->style(isFirstLineStyle())->fontMetrics();
+ const FontMetrics& fontMetrics = renderer().style(isFirstLineStyle())->fontMetrics();
// RootInlineBoxes are always placed on at pixel boundaries in their logical y direction. Not doing
// so results in incorrect rendering of text decorations, most notably underlines.
setLogicalTop(roundToInt(top + maxAscent - fontMetrics.ascent(baselineType)));
@@ -614,20 +617,20 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei
}
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders don't affect calculations.
if (descendantsHaveSameLineHeightAndBaseline()) {
- curr->adjustBlockDirectionPosition(adjustmentForChildrenWithSameLineHeightAndBaseline);
+ curr->adjustBlockDirectionPosition(adjustmentForChildrenWithSameLineHeightAndBaseline.toFloat());
continue;
}
InlineFlowBox* inlineFlowBox = curr->isInlineFlowBox() ? toInlineFlowBox(curr) : 0;
bool childAffectsTopBottomPos = true;
if (curr->verticalAlign() == TOP)
- curr->setLogicalTop(top);
+ curr->setLogicalTop(top.toFloat());
else if (curr->verticalAlign() == BOTTOM)
- curr->setLogicalTop(top + maxHeight - curr->lineHeight());
+ curr->setLogicalTop((top + maxHeight - curr->lineHeight()).toFloat());
else {
if (!strictMode && inlineFlowBox && !inlineFlowBox->hasTextChildren() && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding()
&& !(inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowBox->hasTextDescendants()))
@@ -642,48 +645,48 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei
LayoutUnit boxHeightIncludingMargins = boxHeight;
if (curr->isText() || curr->isInlineFlowBox()) {
- const FontMetrics& fontMetrics = curr->renderer()->style(isFirstLineStyle())->fontMetrics();
+ const FontMetrics& fontMetrics = curr->renderer().style(isFirstLineStyle())->fontMetrics();
newLogicalTop += curr->baselinePosition(baselineType) - fontMetrics.ascent(baselineType);
if (curr->isInlineFlowBox()) {
- RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
- newLogicalTop -= boxObject->style(isFirstLineStyle())->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() :
- boxObject->borderRight() + boxObject->paddingRight();
+ RenderBoxModelObject& boxObject = toRenderBoxModelObject(curr->renderer());
+ newLogicalTop -= boxObject.style(isFirstLineStyle())->isHorizontalWritingMode() ? boxObject.borderTop() + boxObject.paddingTop() :
+ boxObject.borderRight() + boxObject.paddingRight();
}
newLogicalTopIncludingMargins = newLogicalTop;
- } else if (!curr->renderer()->isBR()) {
- RenderBox* box = toRenderBox(curr->renderer());
+ } else if (!curr->renderer().isBR()) {
+ RenderBox& box = toRenderBox(curr->renderer());
newLogicalTopIncludingMargins = newLogicalTop;
- LayoutUnit overSideMargin = curr->isHorizontal() ? box->marginTop() : box->marginRight();
- LayoutUnit underSideMargin = curr->isHorizontal() ? box->marginBottom() : box->marginLeft();
+ LayoutUnit overSideMargin = curr->isHorizontal() ? box.marginTop() : box.marginRight();
+ LayoutUnit underSideMargin = curr->isHorizontal() ? box.marginBottom() : box.marginLeft();
newLogicalTop += overSideMargin;
boxHeightIncludingMargins += overSideMargin + underSideMargin;
}
- curr->setLogicalTop(newLogicalTop);
+ curr->setLogicalTop(newLogicalTop.toFloat());
if (childAffectsTopBottomPos) {
- if (curr->renderer()->isRubyRun()) {
+ if (curr->renderer().isRubyRun()) {
// Treat the leading on the first and last lines of ruby runs as not being part of the overall lineTop/lineBottom.
// Really this is a workaround hack for the fact that ruby should have been done as line layout and not done using
// inline-block.
- if (renderer()->style()->isFlippedLinesWritingMode() == (curr->renderer()->style()->rubyPosition() == RubyPositionAfter))
+ if (renderer().style()->isFlippedLinesWritingMode() == (curr->renderer().style()->rubyPosition() == RubyPositionAfter))
hasAnnotationsBefore = true;
else
hasAnnotationsAfter = true;
- RenderRubyRun* rubyRun = toRenderRubyRun(curr->renderer());
- if (RenderRubyBase* rubyBase = rubyRun->rubyBase()) {
+ RenderRubyRun& rubyRun = toRenderRubyRun(curr->renderer());
+ if (RenderRubyBase* rubyBase = rubyRun.rubyBase()) {
LayoutUnit bottomRubyBaseLeading = (curr->logicalHeight() - rubyBase->logicalBottom()) + rubyBase->logicalHeight() - (rubyBase->lastRootBox() ? rubyBase->lastRootBox()->lineBottom() : LayoutUnit());
LayoutUnit topRubyBaseLeading = rubyBase->logicalTop() + (rubyBase->firstRootBox() ? rubyBase->firstRootBox()->lineTop() : LayoutUnit());
- newLogicalTop += !renderer()->style()->isFlippedLinesWritingMode() ? topRubyBaseLeading : bottomRubyBaseLeading;
+ newLogicalTop += !renderer().style()->isFlippedLinesWritingMode() ? topRubyBaseLeading : bottomRubyBaseLeading;
boxHeight -= (topRubyBaseLeading + bottomRubyBaseLeading);
}
}
if (curr->isInlineTextBox()) {
TextEmphasisPosition emphasisMarkPosition;
- if (toInlineTextBox(curr)->getEmphasisMarkPosition(curr->renderer()->style(isFirstLineStyle()), emphasisMarkPosition)) {
+ if (toInlineTextBox(curr)->getEmphasisMarkPosition(curr->renderer().style(isFirstLineStyle()), emphasisMarkPosition)) {
bool emphasisMarkIsOver = emphasisMarkPosition == TextEmphasisPositionOver;
- if (emphasisMarkIsOver != curr->renderer()->style(isFirstLineStyle())->isFlippedLinesWritingMode())
+ if (emphasisMarkIsOver != curr->renderer().style(isFirstLineStyle())->isFlippedLinesWritingMode())
hasAnnotationsBefore = true;
else
hasAnnotationsAfter = true;
@@ -723,7 +726,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei
lineBottomIncludingMargins = max(lineBottom, lineBottomIncludingMargins);
}
- if (renderer()->style()->isFlippedLinesWritingMode())
+ if (renderer().style()->isFlippedLinesWritingMode())
flipLinesInBlockDirection(lineTopIncludingMargins, lineBottomIncludingMargins);
}
}
@@ -731,7 +734,7 @@ void InlineFlowBox::placeBoxesInBlockDirection(LayoutUnit top, LayoutUnit maxHei
void InlineFlowBox::computeMaxLogicalTop(float& maxLogicalTop) const
{
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders don't affect calculations.
if (descendantsHaveSameLineHeightAndBaseline())
@@ -751,7 +754,7 @@ void InlineFlowBox::flipLinesInBlockDirection(LayoutUnit lineTop, LayoutUnit lin
setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight());
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders aren't affected here.
if (curr->isInlineFlowBox())
@@ -767,7 +770,7 @@ inline void InlineFlowBox::addBoxShadowVisualOverflow(LayoutRect& logicalVisualO
if (!parent())
return;
- RenderStyle* style = renderer()->style(isFirstLineStyle());
+ RenderStyle* style = renderer().style(isFirstLineStyle());
if (!style->boxShadow())
return;
@@ -800,7 +803,7 @@ inline void InlineFlowBox::addBorderOutsetVisualOverflow(LayoutRect& logicalVisu
if (!parent())
return;
- RenderStyle* style = renderer()->style(isFirstLineStyle());
+ RenderStyle* style = renderer().style(isFirstLineStyle());
if (!style->hasBorderImageOutsets())
return;
@@ -829,12 +832,25 @@ inline void InlineFlowBox::addBorderOutsetVisualOverflow(LayoutRect& logicalVisu
logicalRightVisualOverflow - logicalLeftVisualOverflow, logicalBottomVisualOverflow - logicalTopVisualOverflow);
}
+inline void InlineFlowBox::addOutlineVisualOverflow(LayoutRect& logicalVisualOverflow)
+{
+ // Outline on root line boxes is applied to the block and not to the lines.
+ if (!parent())
+ return;
+
+ RenderStyle* style = renderer().style(isFirstLineStyle());
+ if (!style->hasOutline())
+ return;
+
+ logicalVisualOverflow.inflate(style->outlineSize());
+}
+
inline void InlineFlowBox::addTextBoxVisualOverflow(InlineTextBox* textBox, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, LayoutRect& logicalVisualOverflow)
{
if (textBox->knownToHaveNoOverflow())
return;
- RenderStyle* style = textBox->renderer()->style(isFirstLineStyle());
+ RenderStyle* style = textBox->renderer().style(isFirstLineStyle());
GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(textBox);
GlyphOverflow* glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second;
@@ -862,7 +878,7 @@ inline void InlineFlowBox::addTextBoxVisualOverflow(InlineTextBox* textBox, Glyp
// If letter-spacing is negative, we should factor that into right layout overflow. (Even in RTL, letter-spacing is
// applied to the right, so this is not an issue with left overflow.
- rightGlyphOverflow -= min(0, (int)style->font().letterSpacing());
+ rightGlyphOverflow -= min(0, (int)style->font().fontDescription().letterSpacing());
LayoutUnit textShadowLogicalTop;
LayoutUnit textShadowLogicalBottom;
@@ -891,13 +907,13 @@ inline void InlineFlowBox::addTextBoxVisualOverflow(InlineTextBox* textBox, Glyp
inline void InlineFlowBox::addReplacedChildOverflow(const InlineBox* inlineBox, LayoutRect& logicalLayoutOverflow, LayoutRect& logicalVisualOverflow)
{
- RenderBox* box = toRenderBox(inlineBox->renderer());
+ RenderBox& box = toRenderBox(inlineBox->renderer());
// Visual overflow only propagates if the box doesn't have a self-painting layer. This rectangle does not include
// transforms or relative positioning (since those objects always have self-painting layers), but it does need to be adjusted
// for writing-mode differences.
- if (!box->hasSelfPaintingLayer()) {
- LayoutRect childLogicalVisualOverflow = box->logicalVisualOverflowRectForPropagation(renderer()->style());
+ if (!box.hasSelfPaintingLayer()) {
+ LayoutRect childLogicalVisualOverflow = box.logicalVisualOverflowRectForPropagation(renderer().style());
childLogicalVisualOverflow.move(inlineBox->logicalLeft(), inlineBox->logicalTop());
logicalVisualOverflow.unite(childLogicalVisualOverflow);
}
@@ -905,7 +921,7 @@ inline void InlineFlowBox::addReplacedChildOverflow(const InlineBox* inlineBox,
// Layout overflow internal to the child box only propagates if the child box doesn't have overflow clip set.
// Otherwise the child border box propagates as layout overflow. This rectangle must include transforms and relative positioning
// and be adjusted for writing-mode differences.
- LayoutRect childLogicalLayoutOverflow = box->logicalLayoutOverflowRectForPropagation(renderer()->style());
+ LayoutRect childLogicalLayoutOverflow = box.logicalLayoutOverflowRectForPropagation(renderer().style());
childLogicalLayoutOverflow.move(inlineBox->logicalLeft(), inlineBox->logicalTop());
logicalLayoutOverflow.unite(childLogicalLayoutOverflow);
}
@@ -913,8 +929,13 @@ inline void InlineFlowBox::addReplacedChildOverflow(const InlineBox* inlineBox,
void InlineFlowBox::computeOverflow(LayoutUnit lineTop, LayoutUnit lineBottom, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
{
// If we know we have no overflow, we can just bail.
- if (knownToHaveNoOverflow())
+ if (knownToHaveNoOverflow()) {
+ ASSERT(!m_overflow);
return;
+ }
+
+ if (m_overflow)
+ m_overflow.clear();
// Visual overflow just includes overflow for stuff we need to repaint ourselves. Self-painting layers are ignored.
// Layout overflow is used to determine scrolling extent, so it still includes child layers and also factors in
@@ -924,20 +945,21 @@ void InlineFlowBox::computeOverflow(LayoutUnit lineTop, LayoutUnit lineBottom, G
addBoxShadowVisualOverflow(logicalVisualOverflow);
addBorderOutsetVisualOverflow(logicalVisualOverflow);
+ addOutlineVisualOverflow(logicalVisualOverflow);
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders don't affect calculations.
- if (curr->renderer()->isText()) {
+ if (curr->renderer().isText()) {
InlineTextBox* text = toInlineTextBox(curr);
- RenderText* rt = toRenderText(text->renderer());
- if (rt->isBR())
+ RenderText& rt = toRenderText(text->renderer());
+ if (rt.isBR())
continue;
LayoutRect textBoxOverflow(enclosingLayoutRect(text->logicalFrameRect()));
addTextBoxVisualOverflow(text, textBoxDataMap, textBoxOverflow);
logicalVisualOverflow.unite(textBoxOverflow);
- } else if (curr->renderer()->isRenderInline()) {
+ } else if (curr->renderer().isRenderInline()) {
InlineFlowBox* flow = toInlineFlowBox(curr);
flow->computeOverflow(lineTop, lineBottom, textBoxDataMap);
if (!flow->boxModelObject()->hasSelfPaintingLayer())
@@ -945,16 +967,16 @@ void InlineFlowBox::computeOverflow(LayoutUnit lineTop, LayoutUnit lineBottom, G
LayoutRect childLayoutOverflow = flow->logicalLayoutOverflowRect(lineTop, lineBottom);
childLayoutOverflow.move(flow->boxModelObject()->relativePositionLogicalOffset());
logicalLayoutOverflow.unite(childLayoutOverflow);
- } else
+ } else {
addReplacedChildOverflow(curr, logicalLayoutOverflow, logicalVisualOverflow);
+ }
}
setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, lineTop, lineBottom);
}
-void InlineFlowBox::setLayoutOverflow(const LayoutRect& rect, LayoutUnit lineTop, LayoutUnit lineBottom)
+void InlineFlowBox::setLayoutOverflow(const LayoutRect& rect, const LayoutRect& frameBox)
{
- LayoutRect frameBox = enclosingLayoutRect(frameRectIncludingLineHeight(lineTop, lineBottom));
if (frameBox.contains(rect) || rect.isEmpty())
return;
@@ -964,9 +986,8 @@ void InlineFlowBox::setLayoutOverflow(const LayoutRect& rect, LayoutUnit lineTop
m_overflow->setLayoutOverflow(rect);
}
-void InlineFlowBox::setVisualOverflow(const LayoutRect& rect, LayoutUnit lineTop, LayoutUnit lineBottom)
+void InlineFlowBox::setVisualOverflow(const LayoutRect& rect, const LayoutRect& frameBox)
{
- LayoutRect frameBox = enclosingLayoutRect(frameRectIncludingLineHeight(lineTop, lineBottom));
if (frameBox.contains(rect) || rect.isEmpty())
return;
@@ -978,11 +999,13 @@ void InlineFlowBox::setVisualOverflow(const LayoutRect& rect, LayoutUnit lineTop
void InlineFlowBox::setOverflowFromLogicalRects(const LayoutRect& logicalLayoutOverflow, const LayoutRect& logicalVisualOverflow, LayoutUnit lineTop, LayoutUnit lineBottom)
{
+ LayoutRect frameBox = enclosingLayoutRect(frameRectIncludingLineHeight(lineTop, lineBottom));
+
LayoutRect layoutOverflow(isHorizontal() ? logicalLayoutOverflow : logicalLayoutOverflow.transposedRect());
- setLayoutOverflow(layoutOverflow, lineTop, lineBottom);
+ setLayoutOverflow(layoutOverflow, frameBox);
LayoutRect visualOverflow(isHorizontal() ? logicalVisualOverflow : logicalVisualOverflow.transposedRect());
- setVisualOverflow(visualOverflow, lineTop, lineBottom);
+ setVisualOverflow(visualOverflow, frameBox);
}
bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
@@ -997,11 +1020,11 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
// We need to account for culled inline parents of the hit-tested nodes, so that they may also get included in area-based hit-tests.
RenderObject* culledParent = 0;
for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) {
- if (curr->renderer()->isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) {
+ if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) {
RenderObject* newParent = 0;
// Culled parents are only relevant for area-based hit-tests, so ignore it in point-based ones.
if (locationInContainer.isRectBasedTest()) {
- newParent = curr->renderer()->parent();
+ newParent = curr->renderer().parent();
if (newParent == renderer())
newParent = 0;
}
@@ -1018,7 +1041,7 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
culledParent = newParent;
}
if (curr->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom)) {
- renderer()->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
+ renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
return true;
}
}
@@ -1038,13 +1061,13 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
LayoutUnit height = frameRect.height();
// Constrain our hit testing to the line top and bottom if necessary.
- bool noQuirksMode = renderer()->document().inNoQuirksMode();
+ bool noQuirksMode = renderer().document().inNoQuirksMode();
if (!noQuirksMode && !hasTextChildren() && !(descendantsHaveSameLineHeightAndBaseline() && hasTextDescendants())) {
- RootInlineBox* rootBox = root();
+ RootInlineBox& rootBox = root();
LayoutUnit& top = isHorizontal() ? minY : minX;
LayoutUnit& logicalHeight = isHorizontal() ? height : width;
- LayoutUnit bottom = min(rootBox->lineBottom(), top + logicalHeight);
- top = max(rootBox->lineTop(), top);
+ LayoutUnit bottom = min(rootBox.lineBottom(), top + logicalHeight);
+ top = max(rootBox.lineTop(), top);
logicalHeight = bottom - top;
}
@@ -1054,8 +1077,8 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
rect.moveBy(accumulatedOffset);
if (visibleToHitTestRequest(request) && locationInContainer.intersects(rect)) {
- renderer()->updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset))); // Don't add in m_x or m_y here, we want coords in the containing block's space.
- if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, locationInContainer, rect))
+ renderer().updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset))); // Don't add in m_x or m_y here, we want coords in the containing block's space.
+ if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, rect))
return true;
}
@@ -1065,7 +1088,6 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
{
LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom));
- overflowRect.inflate(renderer()->maximalOutlineSize(paintInfo.phase));
flipForWritingMode(overflowRect);
overflowRect.moveBy(paintOffset);
@@ -1076,16 +1098,16 @@ void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
// Add ourselves to the paint info struct's list of inlines that need to paint their
// outlines.
- if (renderer()->style()->visibility() == VISIBLE && renderer()->hasOutline() && !isRootInlineBox()) {
- RenderInline* inlineFlow = toRenderInline(renderer());
+ if (renderer().style()->visibility() == VISIBLE && renderer().hasOutline() && !isRootInlineBox()) {
+ RenderInline& inlineFlow = toRenderInline(renderer());
RenderBlock* cb = 0;
- bool containingBlockPaintsContinuationOutline = inlineFlow->continuation() || inlineFlow->isInlineElementContinuation();
+ bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isInlineElementContinuation();
if (containingBlockPaintsContinuationOutline) {
// FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
// after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
// anonymous blocks. In this case, it is better to bail out and paint it ourself.
- RenderBlock* enclosingAnonymousBlock = renderer()->containingBlock();
+ RenderBlock* enclosingAnonymousBlock = renderer().containingBlock();
if (!enclosingAnonymousBlock->isAnonymousBlock())
containingBlockPaintsContinuationOutline = false;
else {
@@ -1102,9 +1124,9 @@ void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
if (containingBlockPaintsContinuationOutline) {
// Add ourselves to the containing block of the entire continuation so that it can
// paint us atomically.
- cb->addContinuationWithOutline(toRenderInline(renderer()->node()->renderer()));
- } else if (!inlineFlow->isInlineElementContinuation()) {
- paintInfo.outlineObjects()->add(inlineFlow);
+ cb->addContinuationWithOutline(toRenderInline(renderer().node()->renderer()));
+ } else if (!inlineFlow.isInlineElementContinuation()) {
+ paintInfo.outlineObjects()->add(&inlineFlow);
}
}
} else if (paintInfo.phase == PaintPhaseMask) {
@@ -1120,14 +1142,19 @@ void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
return;
PaintPhase paintPhase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPhaseOutline : paintInfo.phase;
- PaintInfo childInfo(paintInfo);
- childInfo.phase = paintPhase;
- childInfo.updatePaintingRootForChildren(renderer());
// Paint our children.
if (paintPhase != PaintPhaseSelfOutline) {
+ PaintInfo childInfo(paintInfo);
+ childInfo.phase = paintPhase;
+
+ if (childInfo.paintingRoot && childInfo.paintingRoot->isDescendantOf(&renderer()))
+ childInfo.paintingRoot = 0;
+ else
+ childInfo.updatePaintingRootForChildren(&renderer());
+
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isText() || !curr->boxModelObject()->hasSelfPaintingLayer())
+ if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintingLayer())
curr->paint(childInfo, paintOffset, lineTop, lineBottom);
}
}
@@ -1146,17 +1173,17 @@ bool InlineFlowBox::boxShadowCanBeAppliedToBackground(const FillLayer& lastBackg
// The checks here match how paintFillLayer() decides whether to clip (if it does, the shadow
// would be clipped out, so it has to be drawn separately).
StyleImage* image = lastBackgroundLayer.image();
- bool hasFillImage = image && image->canRender(renderer(), renderer()->style()->effectiveZoom());
- return (!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent();
+ bool hasFillImage = image && image->canRender(renderer(), renderer().style()->effectiveZoom());
+ return (!hasFillImage && !renderer().style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent();
}
void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, const LayoutRect& rect, CompositeOperator op)
{
StyleImage* img = fillLayer->image();
- bool hasFillImage = img && img->canRender(renderer(), renderer()->style()->effectiveZoom());
- if ((!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent())
+ bool hasFillImage = img && img->canRender(renderer(), renderer().style()->effectiveZoom());
+ if ((!hasFillImage && !renderer().style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent()) {
boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, rect, BackgroundBleedNone, this, rect.size(), op);
- else if (renderer()->style()->boxDecorationBreak() == DCLONE) {
+ } else if (renderer().style()->boxDecorationBreak() == DCLONE) {
GraphicsContextStateSaver stateSaver(*paintInfo.context);
paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), width(), height()));
boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, rect, BackgroundBleedNone, this, rect.size(), op);
@@ -1169,7 +1196,7 @@ void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, c
// the previous line left off.
LayoutUnit logicalOffsetOnLine = 0;
LayoutUnit totalLogicalWidth;
- if (renderer()->style()->direction() == LTR) {
+ if (renderer().style()->direction() == LTR) {
for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
logicalOffsetOnLine += curr->logicalWidth();
totalLogicalWidth = logicalOffsetOnLine;
@@ -1206,13 +1233,13 @@ void InlineFlowBox::paintBoxShadow(const PaintInfo& info, RenderStyle* s, Shadow
void InlineFlowBox::constrainToLineTopAndBottomIfNeeded(LayoutRect& rect) const
{
- bool noQuirksMode = renderer()->document().inNoQuirksMode();
+ bool noQuirksMode = renderer().document().inNoQuirksMode();
if (!noQuirksMode && !hasTextChildren() && !(descendantsHaveSameLineHeightAndBaseline() && hasTextDescendants())) {
- const RootInlineBox* rootBox = root();
+ const RootInlineBox& rootBox = root();
LayoutUnit logicalTop = isHorizontal() ? rect.y() : rect.x();
LayoutUnit logicalHeight = isHorizontal() ? rect.height() : rect.width();
- LayoutUnit bottom = min(rootBox->lineBottom(), logicalTop + logicalHeight);
- logicalTop = max(rootBox->lineTop(), logicalTop);
+ LayoutUnit bottom = min(rootBox.lineBottom(), logicalTop + logicalHeight);
+ logicalTop = max(rootBox.lineTop(), logicalTop);
logicalHeight = bottom - logicalTop;
if (isHorizontal()) {
rect.setY(logicalTop);
@@ -1227,7 +1254,7 @@ void InlineFlowBox::constrainToLineTopAndBottomIfNeeded(LayoutRect& rect) const
static LayoutRect clipRectForNinePieceImageStrip(InlineFlowBox* box, const NinePieceImage& image, const LayoutRect& paintRect)
{
LayoutRect clipRect(paintRect);
- RenderStyle* style = box->renderer()->style();
+ RenderStyle* style = box->renderer().style();
LayoutBoxExtent outsets = style->imageOutsets(image);
if (box->isHorizontal()) {
clipRect.setY(paintRect.y() - outsets.top());
@@ -1253,7 +1280,7 @@ static LayoutRect clipRectForNinePieceImageStrip(InlineFlowBox* box, const NineP
void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
- if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
+ if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
return;
// Pixel snap background/border painting.
@@ -1270,21 +1297,21 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
// You can use p::first-line to specify a background. If so, the root line boxes for
// a line may actually have to paint a background.
- RenderStyle* styleToUse = renderer()->style(isFirstLineStyle());
- if ((!parent() && isFirstLineStyle() && styleToUse != renderer()->style()) || (parent() && renderer()->hasBoxDecorations())) {
+ RenderStyle* styleToUse = renderer().style(isFirstLineStyle());
+ if ((!parent() && isFirstLineStyle() && styleToUse != renderer().style()) || (parent() && renderer().hasBoxDecorations())) {
LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size());
// Shadow comes first and is behind the background and border.
if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, this))
paintBoxShadow(paintInfo, styleToUse, Normal, paintRect);
- Color c = renderer()->resolveColor(styleToUse, CSSPropertyBackgroundColor);
+ Color c = renderer().resolveColor(styleToUse, CSSPropertyBackgroundColor);
paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), paintRect);
paintBoxShadow(paintInfo, styleToUse, Inset, paintRect);
// :first-line cannot be used to put borders on a line. Always paint borders with our
// non-first-line style.
- if (parent() && renderer()->style()->hasBorder()) {
- const NinePieceImage& borderImage = renderer()->style()->borderImage();
+ if (parent() && renderer().style()->hasBorder()) {
+ const NinePieceImage& borderImage = renderer().style()->borderImage();
StyleImage* borderImageSource = borderImage.image();
bool hasBorderImage = borderImageSource && borderImageSource->canRender(renderer(), styleToUse->effectiveZoom());
if (hasBorderImage && !borderImageSource->isLoaded())
@@ -1293,7 +1320,7 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
// The simple case is where we either have no border image or we are the only box for this object. In those
// cases only a single call to draw is required.
if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
- boxModelObject()->paintBorder(paintInfo, paintRect, renderer()->style(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
+ boxModelObject()->paintBorder(paintInfo, paintRect, renderer().style(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
else {
// We have a border image that spans multiple lines.
// We need to adjust tx and ty by the width of all previous lines.
@@ -1317,7 +1344,7 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borderImage, paintRect);
GraphicsContextStateSaver stateSaver(*context);
context->clip(clipRect);
- boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer()->style(isFirstLineStyle()));
+ boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(isFirstLineStyle()));
}
}
}
@@ -1325,7 +1352,7 @@ void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&
void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
- if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
+ if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
return;
// Pixel snap mask painting.
@@ -1338,16 +1365,16 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffs
flipForWritingMode(localRect);
LayoutPoint adjustedPaintOffset = paintOffset + localRect.location();
- const NinePieceImage& maskNinePieceImage = renderer()->style()->maskBoxImage();
- StyleImage* maskBoxImage = renderer()->style()->maskBoxImage().image();
+ const NinePieceImage& maskNinePieceImage = renderer().style()->maskBoxImage();
+ StyleImage* maskBoxImage = renderer().style()->maskBoxImage().image();
// Figure out if we need to push a transparency layer to render our mask.
bool pushTransparencyLayer = false;
- bool compositedMask = renderer()->hasLayer() && boxModelObject()->layer()->hasCompositedMask();
- bool flattenCompositingLayers = renderer()->view()->frameView() && renderer()->view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
+ bool compositedMask = renderer().hasLayer() && boxModelObject()->layer()->hasCompositedMask();
+ bool flattenCompositingLayers = renderer().view()->frameView() && renderer().view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
CompositeOperator compositeOp = CompositeSourceOver;
if (!compositedMask || flattenCompositingLayers) {
- if ((maskBoxImage && renderer()->style()->maskLayers()->hasImage()) || renderer()->style()->maskLayers()->next())
+ if ((maskBoxImage && renderer().style()->maskLayers()->hasImage()) || renderer().style()->maskLayers()->next())
pushTransparencyLayer = true;
compositeOp = CompositeDestinationIn;
@@ -1359,9 +1386,9 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffs
}
LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size());
- paintFillLayers(paintInfo, Color(), renderer()->style()->maskLayers(), paintRect, compositeOp);
+ paintFillLayers(paintInfo, Color::transparent, renderer().style()->maskLayers(), paintRect, compositeOp);
- bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(renderer(), renderer()->style()->effectiveZoom());
+ bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(renderer(), renderer().style()->effectiveZoom());
if (!hasBoxImage || !maskBoxImage->isLoaded()) {
if (pushTransparencyLayer)
paintInfo.context->endLayer();
@@ -1371,7 +1398,7 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffs
// The simple case is where we are the only box for this object. In those
// cases only a single call to draw is required.
if (!prevLineBox() && !nextLineBox()) {
- boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(adjustedPaintOffset, frameRect.size()), renderer()->style(), maskNinePieceImage, compositeOp);
+ boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(adjustedPaintOffset, frameRect.size()), renderer().style(), maskNinePieceImage, compositeOp);
} else {
// We have a mask image that spans multiple lines.
// We need to adjust _tx and _ty by the width of all previous lines.
@@ -1389,7 +1416,7 @@ void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffs
LayoutRect clipRect = clipRectForNinePieceImageStrip(this, maskNinePieceImage, paintRect);
GraphicsContextStateSaver stateSaver(*paintInfo.context);
paintInfo.context->clip(clipRect);
- boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer()->style(), maskNinePieceImage, compositeOp);
+ boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(), maskNinePieceImage, compositeOp);
}
if (pushTransparencyLayer)
@@ -1466,19 +1493,19 @@ LayoutUnit InlineFlowBox::computeOverAnnotationAdjustment(LayoutUnit allowedPosi
{
LayoutUnit result = 0;
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders don't affect calculations.
if (curr->isInlineFlowBox())
result = max(result, toInlineFlowBox(curr)->computeOverAnnotationAdjustment(allowedPosition));
- if (curr->renderer()->isReplaced() && curr->renderer()->isRubyRun() && curr->renderer()->style()->rubyPosition() == RubyPositionBefore) {
- RenderRubyRun* rubyRun = toRenderRubyRun(curr->renderer());
- RenderRubyText* rubyText = rubyRun->rubyText();
+ if (curr->renderer().isReplaced() && curr->renderer().isRubyRun() && curr->renderer().style()->rubyPosition() == RubyPositionBefore) {
+ RenderRubyRun& rubyRun = toRenderRubyRun(curr->renderer());
+ RenderRubyText* rubyText = rubyRun.rubyText();
if (!rubyText)
continue;
- if (!rubyRun->style()->isFlippedLinesWritingMode()) {
+ if (!rubyRun.style()->isFlippedLinesWritingMode()) {
LayoutUnit topOfFirstRubyTextLine = rubyText->logicalTop() + (rubyText->firstRootBox() ? rubyText->firstRootBox()->lineTop() : LayoutUnit());
if (topOfFirstRubyTextLine >= 0)
continue;
@@ -1494,7 +1521,7 @@ LayoutUnit InlineFlowBox::computeOverAnnotationAdjustment(LayoutUnit allowedPosi
}
if (curr->isInlineTextBox()) {
- RenderStyle* style = curr->renderer()->style(isFirstLineStyle());
+ RenderStyle* style = curr->renderer().style(isFirstLineStyle());
TextEmphasisPosition emphasisMarkPosition;
if (style->textEmphasisMark() != TextEmphasisMarkNone && toInlineTextBox(curr)->getEmphasisMarkPosition(style, emphasisMarkPosition) && emphasisMarkPosition == TextEmphasisPositionOver) {
if (!style->isFlippedLinesWritingMode()) {
@@ -1514,19 +1541,19 @@ LayoutUnit InlineFlowBox::computeUnderAnnotationAdjustment(LayoutUnit allowedPos
{
LayoutUnit result = 0;
for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
- if (curr->renderer()->isOutOfFlowPositioned())
+ if (curr->renderer().isOutOfFlowPositioned())
continue; // Positioned placeholders don't affect calculations.
if (curr->isInlineFlowBox())
result = max(result, toInlineFlowBox(curr)->computeUnderAnnotationAdjustment(allowedPosition));
- if (curr->renderer()->isReplaced() && curr->renderer()->isRubyRun() && curr->renderer()->style()->rubyPosition() == RubyPositionAfter) {
- RenderRubyRun* rubyRun = toRenderRubyRun(curr->renderer());
- RenderRubyText* rubyText = rubyRun->rubyText();
+ if (curr->renderer().isReplaced() && curr->renderer().isRubyRun() && curr->renderer().style()->rubyPosition() == RubyPositionAfter) {
+ RenderRubyRun& rubyRun = toRenderRubyRun(curr->renderer());
+ RenderRubyText* rubyText = rubyRun.rubyText();
if (!rubyText)
continue;
- if (rubyRun->style()->isFlippedLinesWritingMode()) {
+ if (rubyRun.style()->isFlippedLinesWritingMode()) {
LayoutUnit topOfFirstRubyTextLine = rubyText->logicalTop() + (rubyText->firstRootBox() ? rubyText->firstRootBox()->lineTop() : LayoutUnit());
if (topOfFirstRubyTextLine >= 0)
continue;
@@ -1542,7 +1569,7 @@ LayoutUnit InlineFlowBox::computeUnderAnnotationAdjustment(LayoutUnit allowedPos
}
if (curr->isInlineTextBox()) {
- RenderStyle* style = curr->renderer()->style(isFirstLineStyle());
+ RenderStyle* style = curr->renderer().style(isFirstLineStyle());
if (style->textEmphasisMark() != TextEmphasisMarkNone && style->textEmphasisPosition() == TextEmphasisPositionUnder) {
if (!style->isFlippedLinesWritingMode()) {
LayoutUnit bottomOfEmphasisMark = curr->logicalBottom() + style->font().emphasisMarkHeight(style->textEmphasisMarkString());
@@ -1573,7 +1600,7 @@ void InlineFlowBox::collectLeafBoxesInLogicalOrder(Vector<InlineBox*>& leafBoxes
leafBoxesInLogicalOrder.append(leaf);
}
- if (renderer()->style()->rtlOrdering() == VisualOrder)
+ if (renderer().style()->rtlOrdering() == VisualOrder)
return;
// Reverse of reordering of the line (L2 according to Bidi spec):
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.h b/chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.h
index 066098fdac8..795cab50a45 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/InlineFlowBox.h
@@ -40,7 +40,7 @@ typedef HashMap<const InlineTextBox*, pair<Vector<const SimpleFontData*>, GlyphO
class InlineFlowBox : public InlineBox {
public:
- InlineFlowBox(RenderObject* obj)
+ InlineFlowBox(RenderObject& obj)
: InlineBox(obj)
, m_firstChild(0)
, m_lastChild(0)
@@ -52,6 +52,9 @@ public:
, m_baselineType(AlphabeticBaseline)
, m_hasAnnotationsBefore(false)
, m_hasAnnotationsAfter(false)
+ , m_lineBreakBidiStatusEor(WTF::Unicode::LeftToRight)
+ , m_lineBreakBidiStatusLastStrong(WTF::Unicode::LeftToRight)
+ , m_lineBreakBidiStatusLast(WTF::Unicode::LeftToRight)
#ifndef NDEBUG
, m_hasBadChildList(false)
#endif
@@ -61,15 +64,15 @@ public:
// an invisible marker exists. The side effect of having an invisible marker is that the quirks mode behavior of shrinking lines with no
// text children must not apply. This change also means that gaps will exist between image bullet list items. Even when the list bullet
// is an image, the line is still considered to be immune from the quirk.
- m_hasTextChildren = obj->style()->display() == LIST_ITEM;
+ m_hasTextChildren = obj.style()->display() == LIST_ITEM;
m_hasTextDescendants = m_hasTextChildren;
}
#ifndef NDEBUG
virtual ~InlineFlowBox();
- virtual void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0, int = 0) const;
- virtual const char* boxName() const;
+ virtual void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0, int = 0) const OVERRIDE;
+ virtual const char* boxName() const OVERRIDE;
#endif
InlineFlowBox* prevLineBox() const { return m_prevLineBox; }
@@ -99,7 +102,7 @@ public:
virtual void deleteLine() OVERRIDE FINAL;
virtual void extractLine() OVERRIDE FINAL;
virtual void attachLine() OVERRIDE FINAL;
- virtual void adjustPosition(float dx, float dy);
+ virtual void adjustPosition(float dx, float dy) OVERRIDE;
virtual void extractLineBoxFromRenderObject();
virtual void attachLineBoxToRenderObject();
@@ -114,7 +117,7 @@ public:
void paintFillLayers(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, CompositeOperator = CompositeSourceOver);
void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, CompositeOperator = CompositeSourceOver);
void paintBoxShadow(const PaintInfo&, RenderStyle*, ShadowStyle, const LayoutRect&);
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
bool boxShadowCanBeAppliedToBackground(const FillLayer&) const;
@@ -140,13 +143,13 @@ public:
{
if (!includeLogicalLeftEdge())
return 0;
- return isHorizontal() ? renderer()->style(isFirstLineStyle())->borderLeftWidth() : renderer()->style(isFirstLineStyle())->borderTopWidth();
+ return isHorizontal() ? renderer().style(isFirstLineStyle())->borderLeftWidth() : renderer().style(isFirstLineStyle())->borderTopWidth();
}
int borderLogicalRight() const
{
if (!includeLogicalRightEdge())
return 0;
- return isHorizontal() ? renderer()->style(isFirstLineStyle())->borderRightWidth() : renderer()->style(isFirstLineStyle())->borderBottomWidth();
+ return isHorizontal() ? renderer().style(isFirstLineStyle())->borderRightWidth() : renderer().style(isFirstLineStyle())->borderBottomWidth();
}
int paddingLogicalLeft() const
{
@@ -197,9 +200,9 @@ public:
void computeOverflow(LayoutUnit lineTop, LayoutUnit lineBottom, GlyphOverflowAndFallbackFontsMap&);
- void removeChild(InlineBox* child);
+ void removeChild(InlineBox* child, MarkLineBoxes);
- virtual RenderObject::SelectionState selectionState();
+ virtual RenderObject::SelectionState selectionState() OVERRIDE;
virtual bool canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth) const OVERRIDE FINAL;
virtual float placeEllipsisBox(bool ltr, float blockLeftEdge, float blockRightEdge, float ellipsisWidth, float &truncatedWidth, bool&) OVERRIDE;
@@ -244,7 +247,7 @@ public:
LayoutRect logicalLayoutOverflowRect(LayoutUnit lineTop, LayoutUnit lineBottom) const
{
LayoutRect result = layoutOverflowRect(lineTop, lineBottom);
- if (!renderer()->isHorizontalWritingMode())
+ if (!renderer().isHorizontalWritingMode())
result = result.transposedRect();
return result;
}
@@ -270,25 +273,23 @@ public:
LayoutRect logicalVisualOverflowRect(LayoutUnit lineTop, LayoutUnit lineBottom) const
{
LayoutRect result = visualOverflowRect(lineTop, lineBottom);
- if (!renderer()->isHorizontalWritingMode())
+ if (!renderer().isHorizontalWritingMode())
result = result.transposedRect();
return result;
}
void setOverflowFromLogicalRects(const LayoutRect& logicalLayoutOverflow, const LayoutRect& logicalVisualOverflow, LayoutUnit lineTop, LayoutUnit lineBottom);
- void setLayoutOverflow(const LayoutRect&, LayoutUnit lineTop, LayoutUnit lineBottom);
- void setVisualOverflow(const LayoutRect&, LayoutUnit lineTop, LayoutUnit lineBottom);
FloatRect frameRectIncludingLineHeight(LayoutUnit lineTop, LayoutUnit lineBottom) const
{
if (isHorizontal())
- return FloatRect(m_topLeft.x(), lineTop, width(), lineBottom - lineTop);
- return FloatRect(lineTop, m_topLeft.y(), lineBottom - lineTop, height());
+ return FloatRect(m_topLeft.x(), lineTop.toFloat(), width(), (lineBottom - lineTop).toFloat());
+ return FloatRect(lineTop.toFloat(), m_topLeft.y(), (lineBottom - lineTop).toFloat(), height());
}
FloatRect logicalFrameRectIncludingLineHeight(LayoutUnit lineTop, LayoutUnit lineBottom) const
{
- return FloatRect(logicalLeft(), lineTop, logicalWidth(), lineBottom - lineTop);
+ return FloatRect(logicalLeft(), lineTop.toFloat(), logicalWidth(), (lineBottom - lineTop).toFloat());
}
bool descendantsHaveSameLineHeightAndBaseline() const { return m_descendantsHaveSameLineHeightAndBaseline; }
@@ -302,10 +303,14 @@ public:
private:
void addBoxShadowVisualOverflow(LayoutRect& logicalVisualOverflow);
void addBorderOutsetVisualOverflow(LayoutRect& logicalVisualOverflow);
+ void addOutlineVisualOverflow(LayoutRect& logicalVisualOverflow);
void addTextBoxVisualOverflow(InlineTextBox*, GlyphOverflowAndFallbackFontsMap&, LayoutRect& logicalVisualOverflow);
void addReplacedChildOverflow(const InlineBox*, LayoutRect& logicalLayoutOverflow, LayoutRect& logicalVisualOverflow);
void constrainToLineTopAndBottomIfNeeded(LayoutRect&) const;
+ void setLayoutOverflow(const LayoutRect&, const LayoutRect&);
+ void setVisualOverflow(const LayoutRect&, const LayoutRect&);
+
protected:
OwnPtr<RenderOverflow> m_overflow;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h b/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h
index c0c30d9ad8a..e0ecc103241 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/InlineIterator.h
@@ -25,6 +25,7 @@
#include "core/rendering/BidiRun.h"
#include "core/rendering/RenderBlockFlow.h"
+#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderText.h"
#include "wtf/StdLibExtras.h"
@@ -43,16 +44,16 @@ public:
InlineIterator()
: m_root(0)
, m_obj(0)
- , m_pos(0)
, m_nextBreakablePosition(-1)
+ , m_pos(0)
{
}
InlineIterator(RenderObject* root, RenderObject* o, unsigned p)
: m_root(root)
, m_obj(o)
- , m_pos(p)
, m_nextBreakablePosition(-1)
+ , m_pos(p)
{
}
@@ -73,7 +74,11 @@ public:
RenderObject* object() const { return m_obj; }
void setObject(RenderObject* object) { m_obj = object; }
+ int nextBreakablePosition() const { return m_nextBreakablePosition; }
+ void setNextBreakablePosition(int position) { m_nextBreakablePosition = position; }
+
unsigned offset() const { return m_pos; }
+ void setOffset(unsigned position) { m_pos = position; }
RenderObject* root() const { return m_root; }
void fastIncrementInTextNode();
@@ -100,20 +105,18 @@ private:
RenderObject* m_root;
RenderObject* m_obj;
-// FIXME: These should be private.
-public:
- unsigned m_pos;
int m_nextBreakablePosition;
+ unsigned m_pos;
};
inline bool operator==(const InlineIterator& it1, const InlineIterator& it2)
{
- return it1.m_pos == it2.m_pos && it1.object() == it2.object();
+ return it1.offset() == it2.offset() && it1.object() == it2.object();
}
inline bool operator!=(const InlineIterator& it1, const InlineIterator& it2)
{
- return it1.m_pos != it2.m_pos || it1.object() != it2.object();
+ return it1.offset() != it2.offset() || it1.object() != it2.object();
}
static inline WTF::Unicode::Direction embedCharFromDirection(TextDirection dir, EUnicodeBidi unicodeBidi)
@@ -187,7 +190,7 @@ static bool isEmptyInline(RenderObject* object)
if (!object->isRenderInline())
return false;
- for (RenderObject* curr = object->firstChild(); curr; curr = curr->nextSibling()) {
+ for (RenderObject* curr = toRenderInline(object)->firstChild(); curr; curr = curr->nextSibling()) {
if (curr->isFloatingOrOutOfFlowPositioned())
continue;
if (curr->isText() && toRenderText(curr)->isAllCollapsibleWhitespace())
@@ -213,7 +216,7 @@ static inline RenderObject* bidiNextShared(RenderObject* root, RenderObject* cur
while (current) {
next = 0;
if (!oldEndOfInline && !isIteratorTarget(current)) {
- next = current->firstChild();
+ next = current->slowFirstChild();
notifyObserverEnteredObject(observer, next);
}
@@ -280,7 +283,7 @@ static inline RenderObject* bidiNextIncludingEmptyInlines(RenderObject* root, Re
return bidiNextShared(root, current, observer, IncludeEmptyInlines, endOfInlinePtr);
}
-static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderObject* root, InlineBidiResolver* resolver = 0)
+static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderBlockFlow* root, InlineBidiResolver* resolver = 0)
{
RenderObject* o = root->firstChild();
if (!o)
@@ -308,7 +311,7 @@ static inline RenderObject* bidiFirstSkippingEmptyInlines(RenderObject* root, In
}
// FIXME: This method needs to be renamed when bidiNext finds a good name.
-static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderObject* root)
+static inline RenderObject* bidiFirstIncludingEmptyInlines(RenderBlock* root)
{
RenderObject* o = root->firstChild();
// If either there are no children to walk, or the first one is correct
@@ -332,7 +335,7 @@ inline void InlineIterator::fastIncrementInTextNode()
// it shouldn't use functions called bidiFirst and bidiNext.
class InlineWalker {
public:
- InlineWalker(RenderObject* root)
+ InlineWalker(RenderBlock* root)
: m_root(root)
, m_current(0)
, m_atEndOfInline(false)
@@ -341,7 +344,7 @@ public:
m_current = bidiFirstIncludingEmptyInlines(m_root);
}
- RenderObject* root() { return m_root; }
+ RenderBlock* root() { return m_root; }
RenderObject* current() { return m_current; }
bool atEndOfInline() { return m_atEndOfInline; }
@@ -354,7 +357,7 @@ public:
return m_current;
}
private:
- RenderObject* m_root;
+ RenderBlock* m_root;
RenderObject* m_current;
bool m_atEndOfInline;
};
@@ -442,13 +445,74 @@ inline bool InlineBidiResolver::isEndOfLine(const InlineIterator& end)
{
bool inEndOfLine = m_current == end || m_current.atEnd() || (inIsolate() && m_current.object() == end.object());
if (inIsolate() && inEndOfLine) {
- m_current.moveTo(m_current.object(), end.m_pos, m_current.m_nextBreakablePosition);
+ m_current.moveTo(m_current.object(), end.offset(), m_current.nextBreakablePosition());
m_last = m_current;
updateStatusLastFromCurrentDirection(WTF::Unicode::OtherNeutral);
}
return inEndOfLine;
}
+static inline bool isCollapsibleSpace(UChar character, RenderText* renderer)
+{
+ if (character == ' ' || character == '\t' || character == softHyphen)
+ return true;
+ if (character == '\n')
+ return !renderer->style()->preserveNewline();
+ return false;
+}
+
+template <typename CharacterType>
+static inline int findFirstTrailingSpace(RenderText* lastText, const CharacterType* characters, int start, int stop)
+{
+ int firstSpace = stop;
+ while (firstSpace > start) {
+ UChar current = characters[firstSpace - 1];
+ if (!isCollapsibleSpace(current, lastText))
+ break;
+ firstSpace--;
+ }
+
+ return firstSpace;
+}
+
+template <>
+inline int InlineBidiResolver::findFirstTrailingSpaceAtRun(BidiRun* run)
+{
+ ASSERT(run);
+ RenderObject* lastObject = run->m_object;
+ if (!lastObject->isText())
+ return run->m_stop;
+
+ RenderText* lastText = toRenderText(lastObject);
+ int firstSpace;
+ if (lastText->is8Bit())
+ firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), run->start(), run->stop());
+ else
+ firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(), run->start(), run->stop());
+ return firstSpace;
+}
+
+template <>
+inline BidiRun* InlineBidiResolver::addTrailingRun(int start, int stop, BidiRun* run, BidiContext* context, TextDirection direction)
+{
+ BidiRun* newTrailingRun = new BidiRun(start, stop, run->m_object, context, WTF::Unicode::OtherNeutral);
+ if (direction == LTR)
+ m_runs.addRun(newTrailingRun);
+ else
+ m_runs.prependRun(newTrailingRun);
+
+ return newTrailingRun;
+}
+
+template <>
+inline bool InlineBidiResolver::needsToApplyL1Rule()
+{
+ if (!m_runs.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace()
+ || !m_runs.logicallyLastRun()->m_object->style()->autoWrap())
+ return false;
+ return true;
+}
+
static inline bool isIsolatedInline(RenderObject* object)
{
ASSERT(object);
@@ -569,18 +633,18 @@ static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns
return;
LineMidpointState& lineMidpointState = resolver.midpointState();
- bool haveNextMidpoint = (lineMidpointState.currentMidpoint < lineMidpointState.numMidpoints);
+ bool haveNextMidpoint = (lineMidpointState.currentMidpoint() < lineMidpointState.numMidpoints());
InlineIterator nextMidpoint;
if (haveNextMidpoint)
- nextMidpoint = lineMidpointState.midpoints[lineMidpointState.currentMidpoint];
- if (lineMidpointState.betweenMidpoints) {
+ nextMidpoint = lineMidpointState.midpoints()[lineMidpointState.currentMidpoint()];
+ if (lineMidpointState.betweenMidpoints()) {
if (!(haveNextMidpoint && nextMidpoint.object() == obj))
return;
// This is a new start point. Stop ignoring objects and
// adjust our start.
- lineMidpointState.betweenMidpoints = false;
- start = nextMidpoint.m_pos;
- lineMidpointState.currentMidpoint++;
+ lineMidpointState.setBetweenMidpoints(false);
+ start = nextMidpoint.offset();
+ lineMidpointState.incrementCurrentMidpoint();
if (start < end)
return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, start, end, resolver, behavior, tracker);
} else {
@@ -591,13 +655,13 @@ static void adjustMidpointsAndAppendRunsForObjectIfNeeded(RenderObject* obj, uns
// An end midpoint has been encountered within our object. We
// need to go ahead and append a run with our endpoint.
- if (nextMidpoint.m_pos + 1 <= end) {
- lineMidpointState.betweenMidpoints = true;
- lineMidpointState.currentMidpoint++;
- if (nextMidpoint.m_pos != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it.
- if (nextMidpoint.m_pos + 1 > start)
- appendRunObjectIfNecessary(obj, start, nextMidpoint.m_pos + 1, resolver, behavior, tracker);
- return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMidpoint.m_pos + 1, end, resolver, behavior, tracker);
+ if (nextMidpoint.offset() + 1 <= end) {
+ lineMidpointState.setBetweenMidpoints(true);
+ lineMidpointState.incrementCurrentMidpoint();
+ if (nextMidpoint.offset() != UINT_MAX) { // UINT_MAX means stop at the object and don't nclude any of it.
+ if (nextMidpoint.offset() + 1 > start)
+ appendRunObjectIfNecessary(obj, start, nextMidpoint.offset() + 1, resolver, behavior, tracker);
+ return adjustMidpointsAndAppendRunsForObjectIfNeeded(obj, nextMidpoint.offset() + 1, end, resolver, behavior, tracker);
}
} else {
appendRunObjectIfNecessary(obj, start, end, resolver, behavior, tracker);
@@ -619,7 +683,7 @@ inline void InlineBidiResolver::appendRun()
// Initialize our state depending on if we're starting in the middle of such an inline.
// FIXME: Could this initialize from this->inIsolate() instead of walking up the render tree?
IsolateTracker isolateTracker(numberOfIsolateAncestors(m_sor));
- int start = m_sor.m_pos;
+ int start = m_sor.offset();
RenderObject* obj = m_sor.object();
while (obj && obj != m_eor.object() && obj != m_endOfRunAtEndOfLine.object()) {
if (isolateTracker.inIsolate())
@@ -630,12 +694,12 @@ inline void InlineBidiResolver::appendRun()
start = 0;
obj = bidiNextSkippingEmptyInlines(m_sor.root(), obj, &isolateTracker);
}
- bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.m_pos;
+ bool isEndOfLine = obj == m_endOfLine.object() && !m_endOfLine.offset();
if (obj && !isEndOfLine) {
- unsigned pos = obj == m_eor.object() ? m_eor.m_pos : INT_MAX;
- if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.m_pos <= pos) {
+ unsigned pos = obj == m_eor.object() ? m_eor.offset() : INT_MAX;
+ if (obj == m_endOfRunAtEndOfLine.object() && m_endOfRunAtEndOfLine.offset() <= pos) {
m_reachedEndOfLine = true;
- pos = m_endOfRunAtEndOfLine.m_pos;
+ pos = m_endOfRunAtEndOfLine.offset();
}
// It's OK to add runs for zero-length RenderObjects, just don't make the run larger than it should be
int end = obj->length() ? pos + 1 : 0;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.cpp
index 60a35deccf1..af997333d2d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.cpp
@@ -27,9 +27,11 @@
#include "core/dom/DocumentMarkerController.h"
#include "core/dom/RenderedDocumentMarker.h"
#include "core/dom/Text.h"
+#include "core/editing/CompositionUnderline.h"
+#include "core/editing/CompositionUnderlineRangeFilter.h"
#include "core/editing/Editor.h"
#include "core/editing/InputMethodController.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/rendering/AbstractInlineTextBox.h"
@@ -45,13 +47,16 @@
#include "core/rendering/style/ShadowList.h"
#include "core/rendering/svg/SVGTextRunRenderingContext.h"
#include "platform/fonts/FontCache.h"
+#include "platform/fonts/GlyphBuffer.h"
#include "platform/fonts/WidthIterator.h"
-#include "platform/graphics/DrawLooper.h"
+#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "wtf/Vector.h"
#include "wtf/text/CString.h"
#include "wtf/text/StringBuilder.h"
+#include <algorithm>
+
using namespace std;
namespace WebCore {
@@ -78,13 +83,11 @@ void InlineTextBox::destroy()
InlineBox::destroy();
}
-void InlineTextBox::markDirty(bool dirty)
+void InlineTextBox::markDirty()
{
- if (dirty) {
- m_len = 0;
- m_start = 0;
- }
- InlineBox::markDirty(dirty);
+ m_len = 0;
+ m_start = 0;
+ InlineBox::markDirty();
}
LayoutRect InlineTextBox::logicalOverflowRect() const
@@ -106,35 +109,35 @@ int InlineTextBox::baselinePosition(FontBaseline baselineType) const
{
if (!isText() || !parent())
return 0;
- if (parent()->renderer() == renderer()->parent())
+ if (parent()->renderer() == renderer().parent())
return parent()->baselinePosition(baselineType);
- return toRenderBoxModelObject(renderer()->parent())->baselinePosition(baselineType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
+ return toRenderBoxModelObject(renderer().parent())->baselinePosition(baselineType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
}
LayoutUnit InlineTextBox::lineHeight() const
{
- if (!isText() || !renderer()->parent())
+ if (!isText() || !renderer().parent())
return 0;
- if (m_renderer->isBR())
- return toRenderBR(m_renderer)->lineHeight(isFirstLineStyle());
- if (parent()->renderer() == renderer()->parent())
+ if (renderer().isBR())
+ return toRenderBR(renderer()).lineHeight(isFirstLineStyle());
+ if (parent()->renderer() == renderer().parent())
return parent()->lineHeight();
- return toRenderBoxModelObject(renderer()->parent())->lineHeight(isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
+ return toRenderBoxModelObject(renderer().parent())->lineHeight(isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
}
LayoutUnit InlineTextBox::selectionTop()
{
- return root()->selectionTop();
+ return root().selectionTop();
}
LayoutUnit InlineTextBox::selectionBottom()
{
- return root()->selectionBottom();
+ return root().selectionBottom();
}
LayoutUnit InlineTextBox::selectionHeight()
{
- return root()->selectionHeight();
+ return root().selectionHeight();
}
bool InlineTextBox::isSelected(int startPos, int endPos) const
@@ -148,16 +151,16 @@ bool InlineTextBox::isSelected(int startPos, int endPos) const
RenderObject::SelectionState InlineTextBox::selectionState()
{
- RenderObject::SelectionState state = renderer()->selectionState();
+ RenderObject::SelectionState state = renderer().selectionState();
if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd || state == RenderObject::SelectionBoth) {
int startPos, endPos;
- renderer()->selectionStartEnd(startPos, endPos);
+ renderer().selectionStartEnd(startPos, endPos);
// The position after a hard line break is considered to be past its end.
// See the corresponding code in InlineTextBox::isSelected.
int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0);
// FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace.
- int endOfLineAdjustmentForCSSLineBreak = renderer()->style()->lineBreak() == LineBreakAfterWhiteSpace ? -1 : 0;
+ int endOfLineAdjustmentForCSSLineBreak = renderer().style()->lineBreak() == LineBreakAfterWhiteSpace ? -1 : 0;
bool start = (state != RenderObject::SelectionEnd && startPos >= m_start && startPos <= m_start + m_len + endOfLineAdjustmentForCSSLineBreak);
bool end = (state != RenderObject::SelectionStart && endPos > m_start && endPos <= lastSelectable);
if (start && end)
@@ -174,8 +177,8 @@ RenderObject::SelectionState InlineTextBox::selectionState()
}
// If there are ellipsis following, make sure their selection is updated.
- if (m_truncation != cNoTruncation && root()->ellipsisBox()) {
- EllipsisBox* ellipsis = root()->ellipsisBox();
+ if (m_truncation != cNoTruncation && root().ellipsisBox()) {
+ EllipsisBox* ellipsis = root().ellipsisBox();
if (state != RenderObject::SelectionNone) {
int start, end;
selectionStartEnd(start, end);
@@ -202,24 +205,21 @@ LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos)
FontCachePurgePreventer fontCachePurgePreventer;
- RenderText* textObj = textRenderer();
LayoutUnit selTop = selectionTop();
LayoutUnit selHeight = selectionHeight();
- RenderStyle* styleToUse = textObj->style(isFirstLineStyle());
+ RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle());
const Font& font = styleToUse->font();
StringBuilder charactersWithHyphen;
bool respectHyphen = ePos == m_len && hasHyphen();
TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charactersWithHyphen : 0);
- if (respectHyphen)
- endPos = textRun.length();
- FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop);
+ FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop.toFloat());
LayoutRect r;
if (sPos || ePos != static_cast<int>(m_len))
r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, selHeight, sPos, ePos));
else // Avoid computing the font width when the entire line box is selected as an optimization.
- r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth, selHeight)));
+ r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth, selHeight.toFloat())));
LayoutUnit logicalWidth = r.width();
if (r.x() > logicalRight())
@@ -236,7 +236,7 @@ LayoutRect InlineTextBox::localSelectionRect(int startPos, int endPos)
void InlineTextBox::deleteLine()
{
- toRenderText(renderer())->removeTextBox(this);
+ toRenderText(renderer()).removeTextBox(this);
destroy();
}
@@ -245,7 +245,7 @@ void InlineTextBox::extractLine()
if (extracted())
return;
- toRenderText(renderer())->extractTextBox(this);
+ toRenderText(renderer()).extractTextBox(this);
}
void InlineTextBox::attachLine()
@@ -253,7 +253,7 @@ void InlineTextBox::attachLine()
if (!extracted())
return;
- toRenderText(renderer())->attachTextBox(this);
+ toRenderText(renderer()).attachTextBox(this);
}
float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox)
@@ -307,7 +307,7 @@ float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, flo
// If we got here that means that we were only partially truncated and we need to return the pixel offset at which
// to place the ellipsis.
- float widthOfVisibleText = toRenderText(renderer())->width(m_start, offset, textPos(), isFirstLineStyle());
+ float widthOfVisibleText = toRenderText(renderer()).width(m_start, offset, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle());
// The ellipsis needs to be placed just after the last visible character.
// Where "after" is defined by the flow directionality, not the inline
@@ -369,7 +369,7 @@ void updateGraphicsContext(GraphicsContext* context, const Color& fillColor, con
bool InlineTextBox::isLineBreak() const
{
- return renderer()->isBR() || (renderer()->style()->preserveNewline() && len() == 1 && (*textRenderer()->text().impl())[start()] == '\n');
+ return renderer().isBR() || (renderer().style()->preserveNewline() && len() == 1 && (*textRenderer().text().impl())[start()] == '\n');
}
bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/)
@@ -381,15 +381,15 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
boxOrigin.moveBy(accumulatedOffset);
FloatRect rect(boxOrigin, size());
if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && locationInContainer.intersects(rect)) {
- renderer()->updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset)));
- if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, locationInContainer, rect))
+ renderer().updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset)));
+ if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, rect))
return true;
}
return false;
}
static void paintTextWithShadows(GraphicsContext* context,
- const RenderObject* renderer, const Font& font, const TextRun& textRun,
+ const RenderObject& renderer, const Font& font, const TextRun& textRun,
const AtomicString& emphasisMark, int emphasisMarkOffset,
int startOffset, int endOffset, int truncationPoint,
const FloatPoint& textOrigin, const FloatRect& boxRect,
@@ -399,17 +399,17 @@ static void paintTextWithShadows(GraphicsContext* context,
bool hasShadow = shadowList && !context->printing();
if (hasShadow) {
- DrawLooper drawLooper;
+ OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
for (size_t i = shadowList->shadows().size(); i--; ) {
const ShadowData& shadow = shadowList->shadows()[i];
- int shadowX = horizontal ? shadow.x() : shadow.y();
- int shadowY = horizontal ? shadow.y() : -shadow.x();
+ float shadowX = horizontal ? shadow.x() : shadow.y();
+ float shadowY = horizontal ? shadow.y() : -shadow.x();
FloatSize offset(shadowX, shadowY);
- drawLooper.addShadow(offset, shadow.blur(), renderer->resolveColor(shadow.color()),
- DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
+ drawLooperBuilder->addShadow(offset, shadow.blur(), shadow.color(),
+ DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
}
- drawLooper.addUnmodifiedContent();
- context->setDrawLooper(drawLooper);
+ drawLooperBuilder->addUnmodifiedContent();
+ context->setDrawLooper(drawLooperBuilder.release());
}
TextRunPaintInfo textRunPaintInfo(textRun);
@@ -454,7 +454,7 @@ bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
if (emphasisPosition == TextEmphasisPositionUnder)
return true; // Ruby text is always over, so it cannot suppress emphasis marks under.
- RenderBlock* containingBlock = renderer()->containingBlock();
+ RenderBlock* containingBlock = renderer().containingBlock();
if (!containingBlock->isRubyBase())
return true; // This text is not inside a ruby base, so it does not have ruby text over it.
@@ -469,8 +469,8 @@ bool InlineTextBox::getEmphasisMarkPosition(RenderStyle* style, TextEmphasisPosi
void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/)
{
- if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE ||
- m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline || !m_len)
+ if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE
+ || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline || !m_len)
return;
ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines);
@@ -483,12 +483,18 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
LayoutUnit paintEnd = isHorizontal() ? paintInfo.rect.maxX() : paintInfo.rect.maxY();
LayoutUnit paintStart = isHorizontal() ? paintInfo.rect.x() : paintInfo.rect.y();
- LayoutPoint adjustedPaintOffset = roundedIntPoint(paintOffset);
+ // When subpixel font scaling is enabled text runs are positioned at
+ // subpixel boundaries on the x-axis and thus there is no reason to
+ // snap the x value. We still round the y-axis to ensure consistent
+ // line heights.
+ LayoutPoint adjustedPaintOffset = RuntimeEnabledFeatures::subpixelFontScalingEnabled()
+ ? LayoutPoint(paintOffset.x(), paintOffset.y().round())
+ : roundedIntPoint(paintOffset);
if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart)
return;
- bool isPrinting = textRenderer()->document().printing();
+ bool isPrinting = textRenderer().document().printing();
// Determine whether or not we're selected.
bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone;
@@ -497,7 +503,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
return;
if (m_truncation != cNoTruncation) {
- if (renderer()->containingBlock()->style()->isLeftToRightDirection() != isLeftToRightDirection()) {
+ if (renderer().containingBlock()->style()->isLeftToRightDirection() != isLeftToRightDirection()) {
// Make the visible fragment of text hug the edge closest to the rest of the run by moving the origin
// at which we start drawing text.
// e.g. In the case of LTR text truncated in an RTL Context, the correct behavior is:
@@ -506,7 +512,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
// farther to the right.
// NOTE: WebKit's behavior differs from that of IE which appears to just overlay the ellipsis on top of the
// truncated string i.e. |Hello|CBA| -> |...lo|CBA|
- LayoutUnit widthOfVisibleText = toRenderText(renderer())->width(m_start, m_truncation, textPos(), isFirstLineStyle());
+ LayoutUnit widthOfVisibleText = toRenderText(renderer()).width(m_start, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
LayoutUnit widthOfHiddenText = m_logicalWidth - widthOfVisibleText;
// FIXME: The hit testing logic also needs to take this translation into account.
LayoutSize truncationOffset(isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText, 0);
@@ -516,24 +522,24 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
GraphicsContext* context = paintInfo.context;
- RenderObject* rendererToUse = renderer();
- RenderStyle* styleToUse = rendererToUse->style(isFirstLineStyle());
+ RenderObject& rendererToUse = renderer();
+ RenderStyle* styleToUse = rendererToUse.style(isFirstLineStyle());
adjustedPaintOffset.move(0, styleToUse->isHorizontalWritingMode() ? 0 : -logicalHeight());
FloatPoint boxOrigin = locationIncludingFlipping();
- boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y());
+ boxOrigin.move(adjustedPaintOffset.x().toFloat(), adjustedPaintOffset.y().toFloat());
FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight()));
- RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRenderer()->isCombineText() && toRenderCombineText(textRenderer())->isCombined() ? toRenderCombineText(textRenderer()) : 0;
+ RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRenderer().isCombineText() && toRenderCombineText(textRenderer()).isCombined() ? &toRenderCombineText(textRenderer()) : 0;
bool shouldRotate = !isHorizontal() && !combinedText;
if (shouldRotate)
context->concatCTM(rotation(boxRect, Clockwise));
// Determine whether or not we have composition underlines to draw.
- bool containsComposition = renderer()->node() && renderer()->frame()->inputMethodController().compositionNode() == renderer()->node();
- bool useCustomUnderlines = containsComposition && renderer()->frame()->inputMethodController().compositionUsesCustomUnderlines();
+ bool containsComposition = renderer().node() && renderer().frame()->inputMethodController().compositionNode() == renderer().node();
+ bool useCustomUnderlines = containsComposition && renderer().frame()->inputMethodController().compositionUsesCustomUnderlines();
// Determine the text colors and selection colors.
Color textFillColor;
@@ -549,13 +555,13 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
textStrokeColor = Color::black;
emphasisMarkColor = Color::black;
} else {
- textFillColor = rendererToUse->resolveColor(styleToUse, CSSPropertyWebkitTextFillColor);
+ textFillColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextFillColor);
bool forceBackgroundToWhite = false;
if (isPrinting) {
if (styleToUse->printColorAdjust() == PrintColorAdjustEconomy)
forceBackgroundToWhite = true;
- if (textRenderer()->document().settings() && textRenderer()->document().settings()->shouldPrintBackgrounds())
+ if (textRenderer().document().settings() && textRenderer().document().settings()->shouldPrintBackgrounds())
forceBackgroundToWhite = false;
}
@@ -563,13 +569,13 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
if (forceBackgroundToWhite)
textFillColor = correctedTextColor(textFillColor, Color::white);
- textStrokeColor = rendererToUse->resolveColor(styleToUse, CSSPropertyWebkitTextStrokeColor);
+ textStrokeColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextStrokeColor);
// Make the text stroke color legible against a white background
if (forceBackgroundToWhite)
textStrokeColor = correctedTextColor(textStrokeColor, Color::white);
- emphasisMarkColor = rendererToUse->resolveColor(styleToUse, CSSPropertyWebkitTextEmphasisColor);
+ emphasisMarkColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextEmphasisColor);
// Make the text stroke color legible against a white background
if (forceBackgroundToWhite)
@@ -586,21 +592,21 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
const ShadowList* selectionShadow = textShadow;
if (haveSelection) {
// Check foreground color first.
- Color foreground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionForegroundColor();
- if (foreground.isValid() && foreground != selectionFillColor && foreground != Color::transparent) {
+ Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor();
+ if (foreground != selectionFillColor) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionFillColor = foreground;
}
- Color emphasisMarkForeground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionEmphasisMarkColor();
- if (emphasisMarkForeground.isValid() && emphasisMarkForeground != selectionEmphasisMarkColor) {
+ Color emphasisMarkForeground = paintInfo.forceBlackText() ? Color::black : renderer().selectionEmphasisMarkColor();
+ if (emphasisMarkForeground != selectionEmphasisMarkColor) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
selectionEmphasisMarkColor = emphasisMarkForeground;
}
- if (RenderStyle* pseudoStyle = renderer()->getCachedPseudoStyle(SELECTION)) {
+ if (RenderStyle* pseudoStyle = renderer().getCachedPseudoStyle(SELECTION)) {
// Text shadows are disabled when printing. http://crbug.com/258321
const ShadowList* shadow = (context->printing() || paintInfo.forceBlackText()) ? 0 : pseudoStyle->textShadow();
if (shadow != selectionShadow) {
@@ -616,7 +622,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
selectionStrokeWidth = strokeWidth;
}
- Color stroke = paintInfo.forceBlackText() ? Color::black : rendererToUse->resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor);
+ Color stroke = paintInfo.forceBlackText() ? Color::black : rendererToUse.resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor);
if (stroke != selectionStrokeColor) {
if (!paintSelectedTextOnly)
paintSelectedTextSeparately = true;
@@ -634,13 +640,10 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
combinedText->adjustTextOrigin(textOrigin, boxRect);
// 1. Paint backgrounds behind text if needed. Examples of such backgrounds include selection
- // and composition underlines.
+ // and composition highlights.
if (paintInfo.phase != PaintPhaseSelection && paintInfo.phase != PaintPhaseTextClip && !isPrinting) {
-
- if (containsComposition && !useCustomUnderlines) {
- paintCompositionBackground(context, boxOrigin, styleToUse, font,
- renderer()->frame()->inputMethodController().compositionStart(),
- renderer()->frame()->inputMethodController().compositionEnd());
+ if (containsComposition) {
+ paintCompositionBackgrounds(context, boxOrigin, styleToUse, font, useCustomUnderlines);
}
paintDocumentMarkers(context, boxOrigin, styleToUse, font, true);
@@ -654,10 +657,10 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
int maximumLength;
StringView string;
if (!combinedText) {
- string = textRenderer()->text().createView();
+ string = textRenderer().text().createView();
if (static_cast<unsigned>(length) != string.length() || m_start)
string.narrow(m_start, length);
- maximumLength = textRenderer()->textLength() - m_start;
+ maximumLength = textRenderer().textLength() - m_start;
} else {
combinedText->getStringToRender(m_start, string, length);
maximumLength = length;
@@ -708,12 +711,19 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
if (combinedText)
context->concatCTM(rotation(boxRect, Clockwise));
- if (!paintSelectedTextSeparately || ePos <= sPos) {
- // FIXME: Truncate right-to-left text correctly.
- paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, 0, length, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
- } else {
- paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, ePos, sPos, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
+ int startOffset = 0;
+ int endOffset = length;
+ int paintRunLength = length;
+ if (combinedText) {
+ startOffset = 0;
+ endOffset = objectReplacementCharacterTextRun.length();
+ paintRunLength = endOffset;
+ } else if (paintSelectedTextSeparately && ePos > sPos) {
+ startOffset = ePos;
+ endOffset = sPos;
}
+ // FIXME: Truncate right-to-left text correctly.
+ paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, startOffset, endOffset, paintRunLength, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
if (combinedText)
context->concatCTM(rotation(boxRect, Counterclockwise));
@@ -735,7 +745,10 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
if (combinedText)
context->concatCTM(rotation(boxRect, Clockwise));
- paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, sPos, ePos, length, emphasisMarkTextOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal());
+ int startOffset = combinedText ? 0 : sPos;
+ int endOffset = combinedText ? objectReplacementCharacterTextRun.length() : ePos;
+ int paintRunLength = combinedText ? endOffset : length;
+ paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, startOffset, endOffset, paintRunLength, emphasisMarkTextOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal());
if (combinedText)
context->concatCTM(rotation(boxRect, Counterclockwise));
@@ -748,7 +761,7 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth);
if (combinedText)
context->concatCTM(rotation(boxRect, Clockwise));
- paintDecoration(context, boxOrigin, textDecorations, styleToUse->textDecorationStyle(), textShadow);
+ paintDecoration(context, boxOrigin, textDecorations, textShadow);
if (combinedText)
context->concatCTM(rotation(boxRect, Counterclockwise));
}
@@ -756,28 +769,14 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
if (paintInfo.phase == PaintPhaseForeground) {
paintDocumentMarkers(context, boxOrigin, styleToUse, font, false);
+ // Paint custom underlines for compositions.
if (useCustomUnderlines) {
- const Vector<CompositionUnderline>& underlines = renderer()->frame()->inputMethodController().customCompositionUnderlines();
- size_t numUnderlines = underlines.size();
-
- for (size_t index = 0; index < numUnderlines; ++index) {
- const CompositionUnderline& underline = underlines[index];
-
- if (underline.endOffset <= start())
- // underline is completely before this run. This might be an underline that sits
- // before the first run we draw, or underlines that were within runs we skipped
- // due to truncation.
+ const Vector<CompositionUnderline>& underlines = renderer().frame()->inputMethodController().customCompositionUnderlines();
+ CompositionUnderlineRangeFilter filter(underlines, start(), end());
+ for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begin(); it != filter.end(); ++it) {
+ if (it->color == Color::transparent)
continue;
-
- if (underline.startOffset <= end()) {
- // underline intersects this run. Paint it.
- paintCompositionUnderline(context, boxOrigin, underline);
- if (underline.endOffset > end() + 1)
- // underline also runs into the next run. Bail now, no more marker advancement.
- break;
- } else
- // underline is completely after this run, bail. A later run will paint it.
- break;
+ paintCompositionUnderline(context, boxOrigin, *it);
}
}
}
@@ -789,14 +788,14 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
{
int startPos, endPos;
- if (renderer()->selectionState() == RenderObject::SelectionInside) {
+ if (renderer().selectionState() == RenderObject::SelectionInside) {
startPos = 0;
- endPos = textRenderer()->textLength();
+ endPos = textRenderer().textLength();
} else {
- textRenderer()->selectionStartEnd(startPos, endPos);
- if (renderer()->selectionState() == RenderObject::SelectionStart)
- endPos = textRenderer()->textLength();
- else if (renderer()->selectionState() == RenderObject::SelectionEnd)
+ textRenderer().selectionStartEnd(startPos, endPos);
+ if (renderer().selectionState() == RenderObject::SelectionStart)
+ endPos = textRenderer().textLength();
+ else if (renderer().selectionState() == RenderObject::SelectionEnd)
startPos = 0;
}
@@ -822,8 +821,8 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b
if (sPos >= ePos)
return;
- Color c = renderer()->selectionBackgroundColor();
- if (!c.isValid() || !c.alpha())
+ Color c = renderer().selectionBackgroundColor();
+ if (!c.alpha())
return;
// If the text color ends up being the same as the selection background, invert the selection
@@ -837,21 +836,21 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b
// If the text is truncated, let the thing being painted in the truncation
// draw its own highlight.
int length = m_truncation != cNoTruncation ? m_truncation : m_len;
- StringView string = textRenderer()->text().createView();
+ StringView string = textRenderer().text().createView();
if (string.length() != static_cast<unsigned>(length) || m_start)
string.narrow(m_start, length);
StringBuilder charactersWithHyphen;
bool respectHyphen = ePos == length && hasHyphen();
- TextRun textRun = constructTextRun(style, font, string, textRenderer()->textLength() - m_start, respectHyphen ? &charactersWithHyphen : 0);
+ TextRun textRun = constructTextRun(style, font, string, textRenderer().textLength() - m_start, respectHyphen ? &charactersWithHyphen : 0);
if (respectHyphen)
ePos = textRun.length();
- LayoutUnit selectionBottom = root()->selectionBottom();
- LayoutUnit selectionTop = root()->selectionTopAdjustedForPrecedingBlock();
+ LayoutUnit selectionBottom = root().selectionBottom();
+ LayoutUnit selectionTop = root().selectionTopAdjustedForPrecedingBlock();
- int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - selectionTop);
+ int deltaY = roundToInt(renderer().style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - selectionTop);
int selHeight = max(0, roundToInt(selectionBottom - selectionTop));
FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
@@ -863,25 +862,34 @@ void InlineTextBox::paintSelection(GraphicsContext* context, const FloatPoint& b
context->drawHighlightForText(font, textRun, localOrigin, selHeight, c, sPos, ePos);
}
-void InlineTextBox::paintCompositionBackground(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, int startPos, int endPos)
+unsigned InlineTextBox::underlinePaintStart(const CompositionUnderline& underline)
+{
+ return std::max(static_cast<unsigned>(m_start), underline.startOffset);
+}
+
+unsigned InlineTextBox::underlinePaintEnd(const CompositionUnderline& underline)
{
- int offset = m_start;
- int sPos = max(startPos - offset, 0);
- int ePos = min(endPos - offset, (int)m_len);
+ unsigned paintEnd = std::min(end() + 1, underline.endOffset); // end() points at the last char, not past it.
+ if (m_truncation != cNoTruncation)
+ paintEnd = std::min(paintEnd, static_cast<unsigned>(m_start + m_truncation));
+ return paintEnd;
+}
+void InlineTextBox::paintSingleCompositionBackgroundRun(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, Color backgroundColor, int startPos, int endPos)
+{
+ int sPos = std::max(startPos - m_start, 0);
+ int ePos = std::min(endPos - m_start, static_cast<int>(m_len));
if (sPos >= ePos)
return;
GraphicsContextStateSaver stateSaver(*context);
- Color c = Color(225, 221, 85);
+ updateGraphicsContext(context, backgroundColor, backgroundColor, 0); // Don't draw text at all!
- updateGraphicsContext(context, c, c, 0); // Don't draw text at all!
-
- int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
+ int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
- context->drawHighlightForText(font, constructTextRun(style, font), localOrigin, selHeight, c, sPos, ePos);
+ context->drawHighlightForText(font, constructTextRun(style, font), localOrigin, selHeight, backgroundColor, sPos, ePos);
}
static StrokeStyle textDecorationStyleToStrokeStyle(TextDecorationStyle decorationStyle)
@@ -912,7 +920,18 @@ static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
{
// Compute the gap between the font and the underline. Use at least one
// pixel gap, if underline is thick then use a bigger gap.
- const int gap = std::max<int>(1, ceilf(textDecorationThickness / 2.f));
+ int gap = 0;
+
+ // Underline position of zero means draw underline on Baseline Position,
+ // in Blink we need at least 1-pixel gap to adding following check.
+ // Positive underline Position means underline should be drawn above baselin e
+ // and negative value means drawing below baseline, negating the value as in Blink
+ // downward Y-increases.
+
+ if (fontMetrics.underlinePosition())
+ gap = -fontMetrics.underlinePosition();
+ else
+ gap = std::max<int>(1, ceilf(textDecorationThickness / 2.f));
// FIXME: We support only horizontal text for now.
switch (underlinePosition) {
@@ -920,7 +939,7 @@ static int computeUnderlineOffset(const TextUnderlinePosition underlinePosition,
return fontMetrics.ascent() + gap; // Position underline near the alphabetic baseline.
case TextUnderlinePositionUnder: {
// Position underline relative to the under edge of the lowest element's content box.
- const float offset = inlineTextBox->root()->maxLogicalTop() - inlineTextBox->logicalTop();
+ const float offset = inlineTextBox->root().maxLogicalTop() - inlineTextBox->logicalTop();
if (offset > 0)
return inlineTextBox->logicalHeight() + gap + offset;
return inlineTextBox->logicalHeight() + gap;
@@ -976,7 +995,7 @@ static void adjustStepToDecorationLength(float& step, float& controlPointDistanc
* |-----------|
* step
*/
-static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint& p1, FloatPoint& p2, float strokeThickness)
+static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint p1, FloatPoint p2, float strokeThickness)
{
context->adjustLineToPixelBoundaries(p1, p2, strokeThickness, context->strokeStyle());
@@ -1053,7 +1072,39 @@ static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint& p1, F
context->strokePath(path);
}
-void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, TextDecorationStyle decorationStyle, const ShadowList* shadowList)
+static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle)
+{
+ return decorationStyle == TextDecorationStyleDotted || decorationStyle == TextDecorationStyleDashed;
+}
+
+static bool shouldSetDecorationAntialias(TextDecorationStyle underline, TextDecorationStyle overline, TextDecorationStyle linethrough)
+{
+ return shouldSetDecorationAntialias(underline) || shouldSetDecorationAntialias(overline) || shouldSetDecorationAntialias(linethrough);
+}
+
+static void paintAppliedDecoration(GraphicsContext* context, FloatPoint start, float width, float doubleOffset, int wavyOffsetFactor,
+ RenderObject::AppliedTextDecoration decoration, float thickness, bool antialiasDecoration, bool isPrinting)
+{
+ context->setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style));
+ context->setStrokeColor(decoration.color);
+
+ switch (decoration.style) {
+ case TextDecorationStyleWavy:
+ strokeWavyTextDecoration(context, start + FloatPoint(0, doubleOffset * wavyOffsetFactor), start + FloatPoint(width, doubleOffset * wavyOffsetFactor), thickness);
+ break;
+ case TextDecorationStyleDotted:
+ case TextDecorationStyleDashed:
+ context->setShouldAntialias(antialiasDecoration);
+ // Fall through
+ default:
+ context->drawLineForText(start, width, isPrinting);
+
+ if (decoration.style == TextDecorationStyleDouble)
+ context->drawLineForText(start + FloatPoint(0, doubleOffset), width, isPrinting);
+ }
+}
+
+void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, const ShadowList* shadowList)
{
GraphicsContextStateSaver stateSaver(*context);
@@ -1064,43 +1115,53 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
float width = m_logicalWidth;
if (m_truncation != cNoTruncation) {
- width = toRenderText(renderer())->width(m_start, m_truncation, textPos(), isFirstLineStyle());
+ width = toRenderText(renderer()).width(m_start, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
if (!isLeftToRightDirection())
localOrigin.move(m_logicalWidth - width, 0);
}
// Get the text decoration colors.
- Color underline, overline, linethrough;
- renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true);
+ RenderObject::AppliedTextDecoration underline, overline, linethrough;
+
+ renderer().getTextDecorations(deco, underline, overline, linethrough, true);
if (isFirstLineStyle())
- renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true, true);
+ renderer().getTextDecorations(deco, underline, overline, linethrough, true, true);
// Use a special function for underlines to get the positioning exactly right.
- bool isPrinting = textRenderer()->document().printing();
+ bool isPrinting = textRenderer().document().printing();
- bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || underline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255);
+ bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || underline.color.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.color.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.color.alpha() == 255);
- RenderStyle* styleToUse = renderer()->style(isFirstLineStyle());
+ RenderStyle* styleToUse = renderer().style(isFirstLineStyle());
int baseline = styleToUse->fontMetrics().ascent();
size_t shadowCount = shadowList ? shadowList->shadows().size() : 0;
// Set the thick of the line to be 10% (or something else ?)of the computed font size and not less than 1px.
// Using computedFontSize should take care of zoom as well.
- const float textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f);
+
+ // Update Underline thickness, in case we have Faulty Font Metrics calculating underline thickness by old method.
+ float textDecorationThickness = styleToUse->fontMetrics().underlineThickness();
+ int fontHeightInt = (int)(styleToUse->fontMetrics().floatHeight() + 0.5);
+ if ((textDecorationThickness == 0.f) || (textDecorationThickness >= (fontHeightInt >> 1)))
+ textDecorationThickness = std::max(1.f, styleToUse->computedFontSize() / 10.f);
+
context->setStrokeThickness(textDecorationThickness);
- int extraOffset = 0;
+ bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, underline.style, linethrough.style)
+ && RenderBoxModelObject::shouldAntialiasLines(context);
+
+ float extraOffset = 0;
if (!linesAreOpaque && shadowCount > 1) {
FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2));
for (size_t i = shadowCount; i--; ) {
const ShadowData& s = shadowList->shadows()[i];
FloatRect shadowRect(localOrigin, FloatSize(width, baseline + 2));
shadowRect.inflate(s.blur());
- int shadowX = isHorizontal() ? s.x() : s.y();
- int shadowY = isHorizontal() ? s.y() : -s.x();
+ float shadowX = isHorizontal() ? s.x() : s.y();
+ float shadowY = isHorizontal() ? s.y() : -s.x();
shadowRect.move(shadowX, shadowY);
clipRect.unite(shadowRect);
- extraOffset = max(extraOffset, max(0, shadowY) + s.blur());
+ extraOffset = max(extraOffset, max(0.0f, shadowY) + s.blur());
}
context->clip(clipRect);
extraOffset += baseline + 2;
@@ -1116,60 +1177,24 @@ void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint&
extraOffset = 0;
}
const ShadowData& shadow = shadowList->shadows()[i];
- int shadowX = isHorizontal() ? shadow.x() : shadow.y();
- int shadowY = isHorizontal() ? shadow.y() : -shadow.x();
+ float shadowX = isHorizontal() ? shadow.x() : shadow.y();
+ float shadowY = isHorizontal() ? shadow.y() : -shadow.x();
context->setShadow(FloatSize(shadowX, shadowY - extraOffset), shadow.blur(), shadow.color());
}
// Offset between lines - always non-zero, so lines never cross each other.
float doubleOffset = textDecorationThickness + 1.f;
- context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle));
+
if (deco & TextDecorationUnderline) {
- context->setStrokeColor(underline);
const int underlineOffset = computeUnderlineOffset(styleToUse->textUnderlinePosition(), styleToUse->fontMetrics(), this, textDecorationThickness);
- switch (decorationStyle) {
- case TextDecorationStyleWavy: {
- FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOffset + doubleOffset);
- FloatPoint end(localOrigin.x() + width, localOrigin.y() + underlineOffset + doubleOffset);
- strokeWavyTextDecoration(context, start, end, textDecorationThickness);
- break;
- }
- default:
- context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset), width, isPrinting);
-
- if (decorationStyle == TextDecorationStyleDouble)
- context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset + doubleOffset), width, isPrinting);
- }
+ paintAppliedDecoration(context, localOrigin + FloatPoint(0, underlineOffset), width, doubleOffset, 1, underline, textDecorationThickness, antialiasDecoration, isPrinting);
}
if (deco & TextDecorationOverline) {
- context->setStrokeColor(overline);
- switch (decorationStyle) {
- case TextDecorationStyleWavy: {
- FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset);
- FloatPoint end(localOrigin.x() + width, localOrigin.y() - doubleOffset);
- strokeWavyTextDecoration(context, start, end, textDecorationThickness);
- break;
- }
- default:
- context->drawLineForText(localOrigin, width, isPrinting);
- if (decorationStyle == TextDecorationStyleDouble)
- context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() - doubleOffset), width, isPrinting);
- }
+ paintAppliedDecoration(context, localOrigin, width, -doubleOffset, 1, overline, textDecorationThickness, antialiasDecoration, isPrinting);
}
if (deco & TextDecorationLineThrough) {
- context->setStrokeColor(linethrough);
- switch (decorationStyle) {
- case TextDecorationStyleWavy: {
- FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline / 3);
- FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * baseline / 3);
- strokeWavyTextDecoration(context, start, end, textDecorationThickness);
- break;
- }
- default:
- context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
- if (decorationStyle == TextDecorationStyleDouble)
- context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting);
- }
+ const float lineThroughOffset = 2 * baseline / 3;
+ paintAppliedDecoration(context, localOrigin + FloatPoint(0, lineThroughOffset), width, doubleOffset, 0, linethrough, textDecorationThickness, antialiasDecoration, isPrinting);
}
}
}
@@ -1190,7 +1215,7 @@ static GraphicsContext::DocumentMarkerLineStyle lineStyleForMarkerType(DocumentM
void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool grammar)
{
// Never print spelling/grammar markers (5327887)
- if (textRenderer()->document().printing())
+ if (textRenderer().document().printing())
return;
if (m_truncation == cFullTruncation)
@@ -1216,7 +1241,7 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
endPosition = min<int>(endPosition, m_truncation);
// Calculate start & width
- int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
+ int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
TextRun run = constructTextRun(style, font);
@@ -1230,7 +1255,7 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
// display a toolTip. We don't do this for misspelling markers.
if (grammar) {
markerRect.move(-boxOrigin.x(), -boxOrigin.y());
- markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
+ markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
}
}
@@ -1242,7 +1267,7 @@ void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& b
// So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so
// we pin to two pixels under the baseline.
int lineThickness = misspellingLineThickness;
- int baseline = renderer()->style(isFirstLineStyle())->fontMetrics().ascent();
+ int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent();
int descent = logicalHeight() - baseline;
int underlineOffset;
if (descent <= (2 + lineThickness)) {
@@ -1259,7 +1284,7 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint&
{
// Use same y positioning and height as for selection, so that when the selection and this highlight are on
// the same word there are no pieces sticking out.
- int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
+ int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
int selHeight = selectionHeight();
int sPos = max(marker->startOffset() - m_start, (unsigned)0);
@@ -1268,11 +1293,11 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint&
// Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(x(), selectionTop()), selHeight, sPos, ePos));
- markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
+ markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
// Optionally highlight the text
- if (renderer()->frame()->editor().markedTextMatchesAreHighlighted()) {
+ if (renderer().frame()->editor().markedTextMatchesAreHighlighted()) {
Color color = marker->activeMatch() ?
RenderTheme::theme().platformActiveTextSearchHighlightColor() :
RenderTheme::theme().platformInactiveTextSearchHighlightColor();
@@ -1283,17 +1308,36 @@ void InlineTextBox::paintTextMatchMarker(GraphicsContext* pt, const FloatPoint&
}
}
+void InlineTextBox::paintCompositionBackgrounds(GraphicsContext* pt, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, bool useCustomUnderlines)
+{
+ if (useCustomUnderlines) {
+ // Paint custom background highlights for compositions.
+ const Vector<CompositionUnderline>& underlines = renderer().frame()->inputMethodController().customCompositionUnderlines();
+ CompositionUnderlineRangeFilter filter(underlines, start(), end());
+ for (CompositionUnderlineRangeFilter::ConstIterator it = filter.begin(); it != filter.end(); ++it) {
+ if (it->backgroundColor == Color::transparent)
+ continue;
+ paintSingleCompositionBackgroundRun(pt, boxOrigin, style, font, it->backgroundColor, underlinePaintStart(*it), underlinePaintEnd(*it));
+ }
+
+ } else {
+ paintSingleCompositionBackgroundRun(pt, boxOrigin, style, font, RenderTheme::theme().platformDefaultCompositionBackgroundColor(),
+ renderer().frame()->inputMethodController().compositionStart(),
+ renderer().frame()->inputMethodController().compositionEnd());
+ }
+}
+
void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, bool background)
{
- if (!renderer()->node())
+ if (!renderer().node())
return;
- Vector<DocumentMarker*> markers = renderer()->document().markers()->markersFor(renderer()->node());
- Vector<DocumentMarker*>::const_iterator markerIt = markers.begin();
+ WillBeHeapVector<DocumentMarker*> markers = renderer().document().markers().markersFor(renderer().node());
+ WillBeHeapVector<DocumentMarker*>::const_iterator markerIt = markers.begin();
// Give any document markers that touch this run a chance to draw before the text has been drawn.
// Note end() points at the last char, not one past it like endOffset and ranges do.
- for ( ; markerIt != markers.end(); markerIt++) {
+ for ( ; markerIt != markers.end(); ++markerIt) {
DocumentMarker* marker = *markerIt;
// Paint either the background markers or the foreground markers, but not both
@@ -1343,33 +1387,21 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const FloatP
if (m_truncation == cFullTruncation)
return;
- float start = 0; // start of line to draw, relative to tx
- float width = m_logicalWidth; // how much line to draw
- bool useWholeWidth = true;
- unsigned paintStart = m_start;
- unsigned paintEnd = end() + 1; // end points at the last char, not past it
- if (paintStart <= underline.startOffset) {
- paintStart = underline.startOffset;
- useWholeWidth = false;
- start = toRenderText(renderer())->width(m_start, paintStart - m_start, textPos(), isFirstLineStyle());
- }
- if (paintEnd != underline.endOffset) { // end points at the last char, not past it
- paintEnd = min(paintEnd, (unsigned)underline.endOffset);
- useWholeWidth = false;
- }
- if (m_truncation != cNoTruncation) {
- paintEnd = min(paintEnd, (unsigned)m_start + m_truncation);
- useWholeWidth = false;
- }
- if (!useWholeWidth) {
- width = toRenderText(renderer())->width(paintStart, paintEnd - paintStart, textPos() + start, isFirstLineStyle());
- }
+ unsigned paintStart = underlinePaintStart(underline);
+ unsigned paintEnd = underlinePaintEnd(underline);
+
+ // start of line to draw, relative to paintOffset.
+ float start = paintStart == static_cast<unsigned>(m_start) ? 0 :
+ toRenderText(renderer()).width(m_start, paintStart - m_start, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
+ // how much line to draw
+ float width = (paintStart == static_cast<unsigned>(m_start) && paintEnd == static_cast<unsigned>(end()) + 1) ? m_logicalWidth :
+ toRenderText(renderer()).width(paintStart, paintEnd - paintStart, textPos() + start, isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
// Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline.
// All other marked text underlines are 1px thick.
// If there's not enough space the underline will touch or overlap characters.
int lineThickness = 1;
- int baseline = renderer()->style(isFirstLineStyle())->fontMetrics().ascent();
+ int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent();
if (underline.thick && logicalHeight() - baseline >= 2)
lineThickness = 2;
@@ -1380,7 +1412,7 @@ void InlineTextBox::paintCompositionUnderline(GraphicsContext* ctx, const FloatP
ctx->setStrokeColor(underline.color);
ctx->setStrokeThickness(lineThickness);
- ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer()->document().printing());
+ ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer().document().printing());
}
int InlineTextBox::caretMinOffset() const
@@ -1399,7 +1431,7 @@ float InlineTextBox::textPos() const
// from the containing block edge in its measurement. textPos() should be consistent so the text are rendered in the same width.
if (logicalLeft() == 0)
return 0;
- return logicalLeft() - root()->logicalLeft();
+ return logicalLeft() - root().logicalLeft();
}
int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs) const
@@ -1414,8 +1446,8 @@ int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs
FontCachePurgePreventer fontCachePurgePreventer;
- RenderText* text = toRenderText(renderer());
- RenderStyle* style = text->style(isFirstLineStyle());
+ RenderText& text = toRenderText(renderer());
+ RenderStyle* style = text.style(isFirstLineStyle());
const Font& font = style->font();
return font.offsetForPosition(constructTextRun(style, font), lineOffset - logicalLeft(), includePartialGlyphs);
}
@@ -1430,8 +1462,8 @@ float InlineTextBox::positionForOffset(int offset) const
FontCachePurgePreventer fontCachePurgePreventer;
- RenderText* text = toRenderText(renderer());
- RenderStyle* styleToUse = text->style(isFirstLineStyle());
+ RenderText& text = toRenderText(renderer());
+ RenderStyle* styleToUse = text.style(isFirstLineStyle());
ASSERT(styleToUse);
const Font& font = styleToUse->font();
int from = !isLeftToRightDirection() ? offset - m_start : 0;
@@ -1468,8 +1500,7 @@ void InlineTextBox::characterWidths(Vector<float>& widths) const
{
FontCachePurgePreventer fontCachePurgePreventer;
- RenderText* textObj = textRenderer();
- RenderStyle* styleToUse = textObj->style(isFirstLineStyle());
+ RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle());
const Font& font = styleToUse->font();
TextRun textRun = constructTextRun(styleToUse, font);
@@ -1488,28 +1519,22 @@ void InlineTextBox::characterWidths(Vector<float>& widths) const
TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, StringBuilder* charactersWithHyphen) const
{
ASSERT(style);
+ ASSERT(textRenderer().text());
- RenderText* textRenderer = this->textRenderer();
- ASSERT(textRenderer);
- ASSERT(textRenderer->text());
-
- StringView string = textRenderer->text().createView();
+ StringView string = textRenderer().text().createView();
unsigned startPos = start();
unsigned length = len();
if (string.length() != length || startPos)
string.narrow(startPos, length);
- return constructTextRun(style, font, string, textRenderer->textLength() - startPos, charactersWithHyphen);
+ return constructTextRun(style, font, string, textRenderer().textLength() - startPos, charactersWithHyphen);
}
TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, StringView string, int maximumLength, StringBuilder* charactersWithHyphen) const
{
ASSERT(style);
- RenderText* textRenderer = this->textRenderer();
- ASSERT(textRenderer);
-
if (charactersWithHyphen) {
const AtomicString& hyphenString = style->hyphenString();
charactersWithHyphen->reserveCapacity(string.length() + hyphenString.length());
@@ -1521,10 +1546,11 @@ TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, St
ASSERT(maximumLength >= static_cast<int>(string.length()));
- TextRun run(string, textPos(), expansion(), expansionBehavior(), direction(), dirOverride() || style->rtlOrdering() == VisualOrder, !textRenderer->canUseSimpleFontCodePath());
+ TextRun run(string, textPos(), expansion(), expansionBehavior(), direction(), dirOverride() || style->rtlOrdering() == VisualOrder, !textRenderer().canUseSimpleFontCodePath());
run.setTabSize(!style->collapseWhiteSpace(), style->tabSize());
+ run.setCharacterScanForCodePath(!textRenderer().canUseSimpleFontCodePath());
if (textRunNeedsRenderingContext(font))
- run.setRenderingContext(SVGTextRunRenderingContext::create(textRenderer));
+ run.setRenderingContext(SVGTextRunRenderingContext::create(&textRenderer()));
// Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring.
run.setCharactersLength(maximumLength);
@@ -1546,15 +1572,15 @@ const char* InlineTextBox::boxName() const
void InlineTextBox::showBox(int printedCharacters) const
{
- const RenderText* obj = toRenderText(renderer());
- String value = obj->text();
+ const RenderText& obj = toRenderText(renderer());
+ String value = obj.text();
value = value.substring(start(), len());
value.replaceWithLiteral('\\', "\\\\");
value.replaceWithLiteral('\n', "\\n");
printedCharacters += fprintf(stderr, "%s\t%p", boxName(), this);
for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
fputc(' ', stderr);
- printedCharacters = fprintf(stderr, "\t%s %p", obj->renderName(), obj);
+ printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj);
const int rendererCharacterOffset = 24;
for (; printedCharacters < rendererCharacterOffset; printedCharacters++)
fputc(' ', stderr);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.h b/chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.h
index 27579edf5cb..5c0a6f0f338 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/InlineTextBox.h
@@ -25,7 +25,6 @@
#include "core/rendering/InlineBox.h"
#include "core/rendering/RenderText.h" // so textRenderer() can be inline
-#include "platform/graphics/GraphicsContext.h"
#include "platform/text/TextRun.h"
#include "wtf/Forward.h"
@@ -33,6 +32,7 @@ namespace WebCore {
struct CompositionUnderline;
class DocumentMarker;
+class GraphicsContext;
const unsigned short cNoTruncation = USHRT_MAX;
const unsigned short cFullTruncation = USHRT_MAX - 1;
@@ -43,7 +43,7 @@ Color correctedTextColor(Color textColor, Color backgroundColor);
class InlineTextBox : public InlineBox {
public:
- InlineTextBox(RenderObject* obj)
+ InlineTextBox(RenderObject& obj)
: InlineBox(obj)
, m_prevTextBox(0)
, m_nextTextBox(0)
@@ -72,7 +72,7 @@ public:
unsigned short truncation() { return m_truncation; }
- virtual void markDirty(bool dirty = true) OVERRIDE FINAL;
+ virtual void markDirty() OVERRIDE FINAL;
using InlineBox::hasHyphen;
using InlineBox::setHasHyphen;
@@ -94,8 +94,8 @@ public:
LayoutUnit logicalRightVisualOverflow() const { return logicalOverflowRect().maxX(); }
#ifndef NDEBUG
- virtual void showBox(int = 0) const;
- virtual const char* boxName() const;
+ virtual void showBox(int = 0) const OVERRIDE;
+ virtual const char* boxName() const OVERRIDE;
#endif
enum RotationDirection { Counterclockwise, Clockwise };
@@ -111,18 +111,18 @@ private:
public:
TextRun constructTextRunForInspector(RenderStyle*, const Font&) const;
- virtual FloatRect calculateBoundaries() const { return FloatRect(x(), y(), width(), height()); }
+ virtual FloatRect calculateBoundaries() const OVERRIDE { return FloatRect(x(), y(), width(), height()); }
virtual LayoutRect localSelectionRect(int startPos, int endPos);
bool isSelected(int startPos, int endPos) const;
void selectionStartEnd(int& sPos, int& ePos);
protected:
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
public:
- RenderText* textRenderer() const;
+ RenderText& textRenderer() const;
private:
virtual void deleteLine() OVERRIDE FINAL;
@@ -175,16 +175,22 @@ private:
unsigned short m_truncation; // Where to truncate when text overflow is applied. We use special constants to
// denote no truncation (the whole run paints) and full truncation (nothing paints at all).
+ unsigned underlinePaintStart(const CompositionUnderline&);
+ unsigned underlinePaintEnd(const CompositionUnderline&);
+
protected:
- void paintCompositionBackground(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos);
+ void paintSingleCompositionBackgroundRun(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, Color backgroundColor, int startPos, int endPos);
+ void paintCompositionBackgrounds(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, bool useCustomUnderlines);
void paintDocumentMarkers(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, bool background);
void paintCompositionUnderline(GraphicsContext*, const FloatPoint& boxOrigin, const CompositionUnderline&);
+ // These functions both paint markers and update the DocumentMarker's renderedRect.
+ virtual void paintDocumentMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&, bool grammar);
+ virtual void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&);
+
private:
- void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, TextDecoration, TextDecorationStyle, const ShadowList*);
+ void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, TextDecoration, const ShadowList*);
void paintSelection(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, Color textColor);
- void paintDocumentMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&, bool grammar);
- void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&);
TextRun::ExpansionBehavior expansionBehavior() const
{
@@ -195,7 +201,7 @@ private:
DEFINE_INLINE_BOX_TYPE_CASTS(InlineTextBox);
-inline RenderText* InlineTextBox::textRenderer() const
+inline RenderText& InlineTextBox::textRenderer() const
{
return toRenderText(renderer());
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayerPaintingInfo.h b/chromium/third_party/WebKit/Source/core/rendering/LayerPaintingInfo.h
index b9af0314271..421e61b2f09 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/LayerPaintingInfo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/LayerPaintingInfo.h
@@ -74,13 +74,12 @@ typedef unsigned PaintLayerFlags;
struct LayerPaintingInfo {
LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect& inDirtyRect,
PaintBehavior inPaintBehavior, const LayoutSize& inSubPixelAccumulation,
- RenderObject* inPaintingRoot = 0, RenderRegion*inRegion = 0,
+ RenderObject* inPaintingRoot = 0,
OverlapTestRequestMap* inOverlapTestRequests = 0)
: rootLayer(inRootLayer)
, paintingRoot(inPaintingRoot)
, paintDirtyRect(inDirtyRect)
, subPixelAccumulation(inSubPixelAccumulation)
- , region(inRegion)
, overlapTestRequests(inOverlapTestRequests)
, paintBehavior(inPaintBehavior)
, clipToDirtyRect(true)
@@ -89,7 +88,6 @@ struct LayerPaintingInfo {
RenderObject* paintingRoot; // only paint descendants of this object
LayoutRect paintDirtyRect; // relative to rootLayer;
LayoutSize subPixelAccumulation;
- RenderRegion* region; // May be null.
OverlapTestRequestMap* overlapTestRequests; // May be null.
PaintBehavior paintBehavior;
bool clipToDirtyRect;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayoutIndicator.cpp b/chromium/third_party/WebKit/Source/core/rendering/LayoutIndicator.cpp
deleted file mode 100644
index a57c53c11d1..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/LayoutIndicator.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/LayoutIndicator.h"
-
-namespace WebCore {
-
-#ifndef NDEBUG
-
-size_t LayoutIndicator::s_inLayout = 0;
-
-#endif
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayoutIndicator.h b/chromium/third_party/WebKit/Source/core/rendering/LayoutIndicator.h
deleted file mode 100644
index 6337da949cf..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/LayoutIndicator.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LayoutIndicator_h
-#define LayoutIndicator_h
-
-#include "wtf/Assertions.h"
-
-namespace WebCore {
-
-#ifndef NDEBUG
-
-class LayoutIndicator {
-public:
- LayoutIndicator() { ++s_inLayout; }
- ~LayoutIndicator() { --s_inLayout; }
-
- static bool inLayout() { return s_inLayout; }
-
-private:
- static size_t s_inLayout;
-};
-
-#else
-
-class LayoutIndicator {
-public:
- LayoutIndicator() { }
- ~LayoutIndicator() { }
-};
-
-#endif
-
-}
-
-#endif // LayoutIndicator_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayoutRectRecorder.cpp b/chromium/third_party/WebKit/Source/core/rendering/LayoutRectRecorder.cpp
deleted file mode 100644
index 90c50d32884..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/LayoutRectRecorder.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/LayoutRectRecorder.h"
-
-#include "core/rendering/RenderObject.h"
-
-namespace WebCore {
-
-bool LayoutRectRecorder::shouldRecordLayoutRects()
-{
- bool isTracing;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("blink.debug.layout"), &isTracing);
- return RuntimeEnabledFeatures::repaintAfterLayoutEnabled() || isTracing;
-}
-
-LayoutRectRecorder::LayoutRectRecorder(RenderObject& object, bool skipRecording)
- : m_object(object)
- , m_skipRecording(skipRecording)
-{
- if (!shouldRecordLayoutRects())
- return;
- if (m_skipRecording)
- return;
-
- if (!m_object.layoutDidGetCalled())
- m_object.setOldRepaintRect(m_object.clippedOverflowRectForRepaint(m_object.containerForRepaint()));
-
- // If should do repaint was set previously make sure we don't accidentally unset it.
- if (!m_object.shouldDoFullRepaintAfterLayout())
- m_object.setShouldDoFullRepaintAfterLayout(m_object.selfNeedsLayout());
-
- m_object.setLayoutDidGetCalled(true);
-}
-
-LayoutRectRecorder::~LayoutRectRecorder()
-{
- if (!shouldRecordLayoutRects())
- return;
- if (m_skipRecording)
- return;
-
- // Note, we don't store the repaint container because it can change during layout.
- m_object.setNewRepaintRect(m_object.clippedOverflowRectForRepaint(m_object.containerForRepaint()));
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayoutRectRecorder.h b/chromium/third_party/WebKit/Source/core/rendering/LayoutRectRecorder.h
deleted file mode 100644
index c92eb5efc90..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/LayoutRectRecorder.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2013, Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LayoutRectRecorder_h
-#define LayoutRectRecorder_h
-
-#include "platform/geometry/LayoutRect.h"
-#include "wtf/Noncopyable.h"
-
-namespace WebCore {
-
-class RenderLayerModelObject;
-class RenderObject;
-
-class LayoutRectRecorder {
- WTF_MAKE_NONCOPYABLE(LayoutRectRecorder);
-public:
- LayoutRectRecorder(RenderObject&, bool skipRecording = false);
- ~LayoutRectRecorder();
-
- static bool shouldRecordLayoutRects();
-
-private:
- RenderObject& m_object;
- bool m_skipRecording;
-};
-
-} // namespace WebCore
-
-#endif // LayoutRectRecorder_h
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.cpp b/chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.cpp
index fc06e0b3b21..046222e8729 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "core/rendering/LayoutRepainter.h"
+#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderObject.h"
namespace WebCore {
@@ -39,9 +40,13 @@ LayoutRepainter::LayoutRepainter(RenderObject& object, bool checkForRepaint)
return;
if (m_checkForRepaint) {
- m_repaintContainer = m_object.containerForRepaint();
- m_oldBounds = m_object.clippedOverflowRectForRepaint(m_repaintContainer);
- m_oldOutlineBox = m_object.outlineBoundsForRepaint(m_repaintContainer);
+ m_repaintContainer = m_object.containerForPaintInvalidation();
+ {
+ // Hits in compositing/video/video-controls-layer-creation.html
+ DisableCompositingQueryAsserts disabler;
+ m_oldBounds = m_object.boundsRectForPaintInvalidation(m_repaintContainer);
+ m_oldOffset = RenderLayer::positionFromPaintInvalidationContainer(&m_object, m_repaintContainer);
+ }
}
}
@@ -50,7 +55,10 @@ bool LayoutRepainter::repaintAfterLayout()
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
return false;
- return m_checkForRepaint ? m_object.repaintAfterLayoutIfNeeded(m_repaintContainer, m_object.selfNeedsLayout(), m_oldBounds, m_oldOutlineBox) : false;
+ // Hits in compositing/video/video-controls-layer-creation.html
+ DisableCompositingQueryAsserts disabler;
+
+ return m_checkForRepaint ? m_object.invalidatePaintAfterLayoutIfNeeded(m_repaintContainer, m_object.selfNeedsLayout(), m_oldBounds, m_oldOffset) : false;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.h b/chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.h
index 55fdd1eb23a..30a3aef00c5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/LayoutRepainter.h
@@ -44,10 +44,10 @@ public:
private:
RenderObject& m_object;
- RenderLayerModelObject* m_repaintContainer;
+ const RenderLayerModelObject* m_repaintContainer;
// We store these values as LayoutRects, but the final invalidations will be pixel snapped
LayoutRect m_oldBounds;
- LayoutRect m_oldOutlineBox;
+ LayoutPoint m_oldOffset;
bool m_checkForRepaint;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayoutState.cpp b/chromium/third_party/WebKit/Source/core/rendering/LayoutState.cpp
index 940f21ccc16..45c0d76f1ac 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/LayoutState.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/LayoutState.cpp
@@ -33,27 +33,42 @@
namespace WebCore {
-LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo)
- : m_columnInfo(columnInfo)
- , m_lineGrid(0)
- , m_next(prev)
- , m_shapeInsideInfo(0)
-#ifndef NDEBUG
- , m_renderer(renderer)
+LayoutState::LayoutState(LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, RenderView& view)
+ : m_clipped(false)
+ , m_isPaginated(pageLogicalHeight)
+ , m_pageLogicalHeightChanged(pageLogicalHeightChanged)
+ , m_cachedOffsetsEnabled(true)
+#if ASSERT_ENABLED
+ , m_layoutDeltaXSaturated(false)
+ , m_layoutDeltaYSaturated(false)
#endif
+ , m_columnInfo(0)
+ , m_next(0)
+ , m_pageLogicalHeight(pageLogicalHeight)
+ , m_renderer(view)
{
- ASSERT(m_next);
+ ASSERT(!view.layoutState());
+ view.pushLayoutState(*this);
+}
- bool fixed = renderer->isOutOfFlowPositioned() && renderer->style()->position() == FixedPosition;
+LayoutState::LayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo)
+ : m_columnInfo(columnInfo)
+ , m_next(renderer.view()->layoutState())
+ , m_renderer(renderer)
+{
+ renderer.view()->pushLayoutState(*this);
+ m_cachedOffsetsEnabled = m_next->m_cachedOffsetsEnabled && renderer.supportsLayoutStateCachedOffsets();
+ bool fixed = renderer.isOutOfFlowPositioned() && renderer.style()->position() == FixedPosition;
if (fixed) {
// FIXME: This doesn't work correctly with transforms.
- FloatPoint fixedOffset = renderer->view()->localToAbsolute(FloatPoint(), IsFixed);
+ FloatPoint fixedOffset = renderer.view()->localToAbsolute(FloatPoint(), IsFixed);
m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset;
- } else
- m_paintOffset = prev->m_paintOffset + offset;
+ } else {
+ m_paintOffset = m_next->m_paintOffset + offset;
+ }
- if (renderer->isOutOfFlowPositioned() && !fixed) {
- if (RenderObject* container = renderer->container()) {
+ if (renderer.isOutOfFlowPositioned() && !fixed) {
+ if (RenderObject* container = renderer.container()) {
if (container->isInFlowPositioned() && container->isRenderInline())
m_paintOffset += toRenderInline(container)->offsetForInFlowPositionedInline(renderer);
}
@@ -61,15 +76,17 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
m_layoutOffset = m_paintOffset;
- if (renderer->isInFlowPositioned() && renderer->hasLayer())
- m_paintOffset += renderer->layer()->offsetForInFlowPosition();
+ if (renderer.isInFlowPositioned() && renderer.hasLayer())
+ m_paintOffset += renderer.layer()->offsetForInFlowPosition();
- m_clipped = !fixed && prev->m_clipped;
+ m_clipped = !fixed && m_next->m_clipped;
if (m_clipped)
- m_clipRect = prev->m_clipRect;
+ m_clipRect = m_next->m_clipRect;
+
+ if (renderer.hasOverflowClip()) {
+ LayoutSize deltaSize = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : renderer.view()->layoutDelta();
- if (renderer->hasOverflowClip()) {
- LayoutRect clipRect(toPoint(m_paintOffset) + renderer->view()->layoutDelta(), renderer->cachedSizeForOverflowClip());
+ LayoutRect clipRect(toPoint(m_paintOffset) + deltaSize, renderer.cachedSizeForOverflowClip());
if (m_clipped)
m_clipRect.intersect(clipRect);
else {
@@ -77,17 +94,18 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
m_clipped = true;
}
- m_paintOffset -= renderer->scrolledContentOffset();
+ m_paintOffset -= renderer.scrolledContentOffset();
}
// If we establish a new page height, then cache the offset to the top of the first page.
// We can compare this later on to figure out what part of the page we're actually on,
- if (pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread()) {
+ if (pageLogicalHeight || m_columnInfo || renderer.isRenderFlowThread()) {
m_pageLogicalHeight = pageLogicalHeight;
- bool isFlipped = renderer->style()->isFlippedBlocksWritingMode();
- m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? renderer->borderLeft() + renderer->paddingLeft() : renderer->borderRight() + renderer->paddingRight()),
- m_layoutOffset.height() + (!isFlipped ? renderer->borderTop() + renderer->paddingTop() : renderer->borderBottom() + renderer->paddingBottom()));
+ bool isFlipped = renderer.style()->isFlippedBlocksWritingMode();
+ m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? renderer.borderLeft() + renderer.paddingLeft() : renderer.borderRight() + renderer.paddingRight()),
+ m_layoutOffset.height() + (!isFlipped ? renderer.borderTop() + renderer.paddingTop() : renderer.borderBottom() + renderer.paddingBottom()));
m_pageLogicalHeightChanged = pageLogicalHeightChanged;
+ m_isPaginated = true;
} else {
// If we don't establish a new page height, then propagate the old page height and offset down.
m_pageLogicalHeight = m_next->m_pageLogicalHeight;
@@ -96,59 +114,62 @@ LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSiz
// Disable pagination for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and
// writing mode roots.
- if (renderer->isUnsplittableForPagination())
+ if (renderer.isUnsplittableForPagination()) {
m_pageLogicalHeight = 0;
+ m_isPaginated = false;
+ } else {
+ m_isPaginated = m_pageLogicalHeight || m_next->m_columnInfo || renderer.flowThreadContainingBlock();
+ }
}
- // Propagate line grid information.
- propagateLineGridInfo(renderer);
-
if (!m_columnInfo)
m_columnInfo = m_next->m_columnInfo;
- if (renderer->isRenderBlock()) {
- const RenderBlock* renderBlock = toRenderBlock(renderer);
- m_shapeInsideInfo = renderBlock->shapeInsideInfo();
- if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock->allowsShapeInsideInfoSharing(m_next->m_shapeInsideInfo->owner()))
- m_shapeInsideInfo = m_next->m_shapeInsideInfo;
- }
-
- m_layoutDelta = m_next->m_layoutDelta;
-#if !ASSERT_DISABLED
- m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated;
- m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated;
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ m_layoutDelta = m_next->m_layoutDelta;
+#if ASSERT_ENABLED
+ m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated;
+ m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated;
#endif
-
- m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread();
-
- if (lineGrid() && renderer->hasColumns() && renderer->style()->hasInlineColumnAxis())
- computeLineGridPaginationOrigin(renderer);
-
- // If we have a new grid to track, then add it to our set.
- if (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isRenderBlockFlow())
- establishLineGrid(toRenderBlockFlow(renderer));
+ }
// FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
}
-LayoutState::LayoutState(RenderObject* root)
+inline static bool shouldDisableLayoutStateForSubtree(RenderObject& renderer)
+{
+ RenderObject* object = &renderer;
+ while (object) {
+ if (object->supportsLayoutStateCachedOffsets())
+ return true;
+ object = object->container();
+ }
+ return false;
+}
+
+LayoutState::LayoutState(RenderObject& root)
: m_clipped(false)
, m_isPaginated(false)
, m_pageLogicalHeightChanged(false)
-#if !ASSERT_DISABLED
+ , m_cachedOffsetsEnabled(shouldDisableLayoutStateForSubtree(root))
+#if ASSERT_ENABLED
, m_layoutDeltaXSaturated(false)
, m_layoutDeltaYSaturated(false)
#endif
, m_columnInfo(0)
- , m_lineGrid(0)
- , m_next(0)
- , m_shapeInsideInfo(0)
+ , m_next(root.view()->layoutState())
, m_pageLogicalHeight(0)
-#ifndef NDEBUG
, m_renderer(root)
-#endif
{
- RenderObject* container = root->container();
+ // FIXME: Why does RenderTableSection create this wonky LayoutState?
+ ASSERT(!m_next || root.isTableSection());
+ // We'll end up pushing in RenderView itself, so don't bother adding it.
+ if (root.isRenderView())
+ return;
+
+ root.view()->pushLayoutState(*this);
+
+ RenderObject* container = root.container();
FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTransforms);
m_paintOffset = LayoutSize(absContentPoint.x(), absContentPoint.y());
@@ -160,14 +181,12 @@ LayoutState::LayoutState(RenderObject* root)
}
}
-void* LayoutState::operator new(size_t sz)
-{
- return partitionAlloc(Partitions::getRenderingPartition(), sz);
-}
-
-void LayoutState::operator delete(void* ptr)
+LayoutState::~LayoutState()
{
- partitionFree(ptr);
+ if (m_renderer.view()->layoutState()) {
+ ASSERT(m_renderer.view()->layoutState() == this);
+ m_renderer.view()->popLayoutState();
+ }
}
void LayoutState::clearPaginationInformation()
@@ -177,98 +196,18 @@ void LayoutState::clearPaginationInformation()
m_columnInfo = m_next->m_columnInfo;
}
-LayoutUnit LayoutState::pageLogicalOffset(RenderBox* child, LayoutUnit childLogicalOffset) const
+LayoutUnit LayoutState::pageLogicalOffset(const RenderBox& child, const LayoutUnit& childLogicalOffset) const
{
- if (child->isHorizontalWritingMode())
+ if (child.isHorizontalWritingMode())
return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.height();
return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width();
}
-void LayoutState::addForcedColumnBreak(RenderBox* child, LayoutUnit childLogicalOffset)
+void LayoutState::addForcedColumnBreak(const RenderBox& child, const LayoutUnit& childLogicalOffset)
{
if (!m_columnInfo || m_columnInfo->columnHeight())
return;
m_columnInfo->addForcedBreak(pageLogicalOffset(child, childLogicalOffset));
}
-void LayoutState::propagateLineGridInfo(RenderBox* renderer)
-{
- // Disable line grids for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and
- // writing mode roots.
- if (!m_next || renderer->isUnsplittableForPagination())
- return;
-
- m_lineGrid = m_next->m_lineGrid;
- m_lineGridOffset = m_next->m_lineGridOffset;
- m_lineGridPaginationOrigin = m_next->m_lineGridPaginationOrigin;
-}
-
-void LayoutState::establishLineGrid(RenderBlockFlow* block)
-{
- // First check to see if this grid has been established already.
- if (m_lineGrid) {
- if (m_lineGrid->style()->lineGrid() == block->style()->lineGrid())
- return;
- RenderBlockFlow* currentGrid = m_lineGrid;
- for (LayoutState* currentState = m_next; currentState; currentState = currentState->m_next) {
- if (currentState->m_lineGrid == currentGrid)
- continue;
- currentGrid = currentState->m_lineGrid;
- if (!currentGrid)
- break;
- if (currentGrid->style()->lineGrid() == block->style()->lineGrid()) {
- m_lineGrid = currentGrid;
- m_lineGridOffset = currentState->m_lineGridOffset;
- return;
- }
- }
- }
-
- // We didn't find an already-established grid with this identifier. Our render object establishes the grid.
- m_lineGrid = block;
- m_lineGridOffset = m_layoutOffset;
-}
-
-void LayoutState::computeLineGridPaginationOrigin(RenderBox* renderer)
-{
- // We need to cache a line grid pagination origin so that we understand how to reset the line grid
- // at the top of each column.
- // Get the current line grid and offset.
- if (!lineGrid() || lineGrid()->style()->writingMode() != renderer->style()->writingMode())
- return;
-
- // Get the hypothetical line box used to establish the grid.
- RootInlineBox* lineGridBox = lineGrid()->lineGridBox();
- if (!lineGridBox)
- return;
-
- bool isHorizontalWritingMode = lineGrid()->isHorizontalWritingMode();
-
- LayoutUnit lineGridBlockOffset = isHorizontalWritingMode ? lineGridOffset().height() : lineGridOffset().width();
-
- // Now determine our position on the grid. Our baseline needs to be adjusted to the nearest baseline multiple
- // as established by the line box.
- // FIXME: Need to handle crazy line-box-contain values that cause the root line box to not be considered. I assume
- // the grid should honor line-box-contain.
- LayoutUnit gridLineHeight = lineGridBox->lineBottomWithLeading() - lineGridBox->lineTopWithLeading();
- if (!gridLineHeight)
- return;
-
- LayoutUnit firstLineTopWithLeading = lineGridBlockOffset + lineGridBox->lineTopWithLeading();
-
- if (isPaginated() && pageLogicalHeight()) {
- LayoutUnit pageLogicalTop = renderer->isHorizontalWritingMode() ? m_pageOffset.height() : m_pageOffset.width();
- if (pageLogicalTop > firstLineTopWithLeading) {
- // Shift to the next highest line grid multiple past the page logical top. Cache the delta
- // between this new value and the page logical top as the pagination origin.
- LayoutUnit remainder = roundToInt(pageLogicalTop - firstLineTopWithLeading) % roundToInt(gridLineHeight);
- LayoutUnit paginationDelta = gridLineHeight - remainder;
- if (isHorizontalWritingMode)
- m_lineGridPaginationOrigin.setHeight(paginationDelta);
- else
- m_lineGridPaginationOrigin.setWidth(paginationDelta);
- }
- }
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LayoutState.h b/chromium/third_party/WebKit/Source/core/rendering/LayoutState.h
index 16aa5b6ef36..8279bd3995b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/LayoutState.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/LayoutState.h
@@ -33,89 +33,95 @@
namespace WebCore {
-class RenderBlockFlow;
+class ForceHorriblySlowRectMapping;
class RenderBox;
class RenderObject;
-class RenderFlowThread;
-class ShapeInsideInfo;
+class RenderView;
class LayoutState {
WTF_MAKE_NONCOPYABLE(LayoutState);
public:
- LayoutState()
- : m_clipped(false)
- , m_isPaginated(false)
- , m_pageLogicalHeightChanged(false)
-#if !ASSERT_DISABLED
- , m_layoutDeltaXSaturated(false)
- , m_layoutDeltaYSaturated(false)
-#endif
- , m_columnInfo(0)
- , m_lineGrid(0)
- , m_next(0)
- , m_shapeInsideInfo(0)
- , m_pageLogicalHeight(0)
-#ifndef NDEBUG
- , m_renderer(0)
-#endif
- {
- }
+ // Constructor for root LayoutState created by RenderView
+ LayoutState(LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, RenderView&);
+ // Constructor for sub-tree Layout and RenderTableSections
+ explicit LayoutState(RenderObject& root);
- LayoutState(LayoutState*, RenderBox*, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged, ColumnInfo*);
- LayoutState(RenderObject*);
+ LayoutState(RenderBox&, const LayoutSize& offset, LayoutUnit pageLogicalHeight = 0, bool pageHeightLogicalChanged = false, ColumnInfo* = 0);
- // LayoutState is allocated out of the rendering partition.
- void* operator new(size_t);
- void operator delete(void*);
+ ~LayoutState();
void clearPaginationInformation();
- bool isPaginatingColumns() const { return m_columnInfo && m_columnInfo->paginationUnit() == ColumnInfo::Column; }
+ bool isPaginatingColumns() const { return m_columnInfo; }
bool isPaginated() const { return m_isPaginated; }
+ bool isClipped() const { return m_clipped; }
// The page logical offset is the object's offset from the top of the page in the page progression
// direction (so an x-offset in vertical text and a y-offset for horizontal text).
- LayoutUnit pageLogicalOffset(RenderBox*, LayoutUnit childLogicalOffset) const;
+ LayoutUnit pageLogicalOffset(const RenderBox&, const LayoutUnit& childLogicalOffset) const;
- void addForcedColumnBreak(RenderBox*, LayoutUnit childLogicalOffset);
+ void addForcedColumnBreak(const RenderBox&, const LayoutUnit& childLogicalOffset);
+ void addLayoutDelta(const LayoutSize& delta)
+ {
+ m_layoutDelta += delta;
+#if ASSERT_ENABLED
+ m_layoutDeltaXSaturated |= m_layoutDelta.width() == LayoutUnit::max() || m_layoutDelta.width() == LayoutUnit::min();
+ m_layoutDeltaYSaturated |= m_layoutDelta.height() == LayoutUnit::max() || m_layoutDelta.height() == LayoutUnit::min();
+#endif
+ }
+
+ void setColumnInfo(ColumnInfo* columnInfo) { m_columnInfo = columnInfo; }
+
+ const LayoutSize& layoutOffset() const { return m_layoutOffset; }
+ const LayoutSize& layoutDelta() const { return m_layoutDelta; }
+ const LayoutSize& pageOffset() const { return m_pageOffset; }
LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; }
bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
- RenderBlockFlow* lineGrid() const { return m_lineGrid; }
- LayoutSize lineGridOffset() const { return m_lineGridOffset; }
- LayoutSize lineGridPaginationOrigin() const { return m_lineGridPaginationOrigin; }
+ LayoutState* next() const { return m_next; }
- LayoutSize layoutOffset() const { return m_layoutOffset; }
+ bool needsBlockDirectionLocationSetBeforeLayout() const { return m_isPaginated && m_pageLogicalHeight; }
- bool needsBlockDirectionLocationSetBeforeLayout() const { return m_lineGrid || (m_isPaginated && m_pageLogicalHeight); }
+ ColumnInfo* columnInfo() const { return m_columnInfo; }
- ShapeInsideInfo* shapeInsideInfo() const { return m_shapeInsideInfo; }
+ bool cachedOffsetsEnabled() const { return m_cachedOffsetsEnabled; }
-#ifndef NDEBUG
- RenderObject* renderer() const { return m_renderer; }
+ const LayoutRect& clipRect() const
+ {
+ ASSERT(m_cachedOffsetsEnabled);
+ return m_clipRect;
+ }
+ const LayoutSize& paintOffset() const
+ {
+ ASSERT(m_cachedOffsetsEnabled);
+ return m_paintOffset;
+ }
+
+
+ RenderObject& renderer() const { return m_renderer; }
+
+#if ASSERT_ENABLED
+ bool layoutDeltaXSaturated() const { return m_layoutDeltaXSaturated; }
+ bool layoutDeltaYSaturated() const { return m_layoutDeltaYSaturated; }
#endif
-private:
- void propagateLineGridInfo(RenderBox*);
- void establishLineGrid(RenderBlockFlow*);
- void computeLineGridPaginationOrigin(RenderBox*);
+private:
+ friend class ForceHorriblySlowRectMapping;
-public:
// Do not add anything apart from bitfields until after m_columnInfo. See https://bugs.webkit.org/show_bug.cgi?id=100173
bool m_clipped:1;
bool m_isPaginated:1;
// If our page height has changed, this will force all blocks to relayout.
bool m_pageLogicalHeightChanged:1;
-#if !ASSERT_DISABLED
+
+ bool m_cachedOffsetsEnabled:1;
+#if ASSERT_ENABLED
bool m_layoutDeltaXSaturated:1;
bool m_layoutDeltaYSaturated:1;
#endif
// If the enclosing pagination model is a column model, then this will store column information for easy retrieval/manipulation.
ColumnInfo* m_columnInfo;
- // The current line grid that we're snapping to and the offset of the start of the grid.
- RenderBlockFlow* m_lineGrid;
LayoutState* m_next;
- ShapeInsideInfo* m_shapeInsideInfo;
// FIXME: Distinguish between the layout clip rect and the paint clip rect which may be larger,
// e.g., because of composited scrolling.
@@ -134,12 +140,8 @@ public:
LayoutUnit m_pageLogicalHeight;
// The offset of the start of the first page in the nearest enclosing pagination model.
LayoutSize m_pageOffset;
- LayoutSize m_lineGridOffset;
- LayoutSize m_lineGridPaginationOrigin;
-#ifndef NDEBUG
- RenderObject* m_renderer;
-#endif
+ RenderObject& m_renderer;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LineWidth.cpp b/chromium/third_party/WebKit/Source/core/rendering/LineWidth.cpp
deleted file mode 100644
index ea720e2024e..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/LineWidth.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/LineWidth.h"
-
-#include "core/rendering/RenderBlock.h"
-#include "core/rendering/RenderRubyRun.h"
-
-namespace WebCore {
-
-LineWidth::LineWidth(RenderBlockFlow& block, bool isFirstLine, IndentTextOrNot shouldIndentText)
- : m_block(block)
- , m_uncommittedWidth(0)
- , m_committedWidth(0)
- , m_overhangWidth(0)
- , m_left(0)
- , m_right(0)
- , m_availableWidth(0)
- , m_segment(0)
- , m_isFirstLine(isFirstLine)
- , m_shouldIndentText(shouldIndentText)
-{
- updateCurrentShapeSegment();
- updateAvailableWidth();
-}
-
-void LineWidth::updateAvailableWidth(LayoutUnit replacedHeight)
-{
- LayoutUnit height = m_block.logicalHeight();
- LayoutUnit logicalHeight = m_block.minLineHeightForReplacedRenderer(m_isFirstLine, replacedHeight);
- m_left = m_block.logicalLeftOffsetForLine(height, shouldIndentText(), logicalHeight);
- m_right = m_block.logicalRightOffsetForLine(height, shouldIndentText(), logicalHeight);
-
- if (m_segment) {
- m_left = std::max<float>(m_segment->logicalLeft, m_left);
- m_right = std::min<float>(m_segment->logicalRight, m_right);
- }
-
- computeAvailableWidthFromLeftAndRight();
-}
-
-void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject* newFloat)
-{
- LayoutUnit height = m_block.logicalHeight();
- if (height < m_block.logicalTopForFloat(newFloat) || height >= m_block.logicalBottomForFloat(newFloat))
- return;
-
- // When floats with shape outside are stacked, the floats are positioned based on the margin box of the float,
- // not the shape's contour. Since we computed the width based on the shape contour when we added the float,
- // when we add a subsequent float on the same line, we need to undo the shape delta in order to position
- // based on the margin box. In order to do this, we need to walk back through the floating object list to find
- // the first previous float that is on the same side as our newFloat.
- ShapeOutsideInfo* previousShapeOutsideInfo = 0;
- const FloatingObjectSet& floatingObjectSet = m_block.m_floatingObjects->set();
- FloatingObjectSetIterator it = floatingObjectSet.end();
- FloatingObjectSetIterator begin = floatingObjectSet.begin();
- LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
- for (--it; it != begin; --it) {
- FloatingObject* previousFloat = *it;
- if (previousFloat != newFloat && previousFloat->type() == newFloat->type()) {
- previousShapeOutsideInfo = previousFloat->renderer()->shapeOutsideInfo();
- if (previousShapeOutsideInfo)
- previousShapeOutsideInfo->updateDeltasForContainingBlockLine(&m_block, previousFloat, m_block.logicalHeight(), lineHeight);
- break;
- }
- }
-
- ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer()->shapeOutsideInfo();
- if (shapeOutsideInfo)
- shapeOutsideInfo->updateDeltasForContainingBlockLine(&m_block, newFloat, m_block.logicalHeight(), lineHeight);
-
- if (newFloat->type() == FloatingObject::FloatLeft) {
- float newLeft = m_block.logicalRightForFloat(newFloat);
- if (previousShapeOutsideInfo)
- newLeft -= previousShapeOutsideInfo->rightMarginBoxDelta();
- if (shapeOutsideInfo)
- newLeft += shapeOutsideInfo->rightMarginBoxDelta();
-
- if (shouldIndentText() && m_block.style()->isLeftToRightDirection())
- newLeft += floorToInt(m_block.textIndentOffset());
- m_left = std::max<float>(m_left, newLeft);
- } else {
- float newRight = m_block.logicalLeftForFloat(newFloat);
- if (previousShapeOutsideInfo)
- newRight -= previousShapeOutsideInfo->leftMarginBoxDelta();
- if (shapeOutsideInfo)
- newRight += shapeOutsideInfo->leftMarginBoxDelta();
-
- if (shouldIndentText() && !m_block.style()->isLeftToRightDirection())
- newRight -= floorToInt(m_block.textIndentOffset());
- m_right = std::min<float>(m_right, newRight);
- }
-
- computeAvailableWidthFromLeftAndRight();
-}
-
-void LineWidth::commit()
-{
- m_committedWidth += m_uncommittedWidth;
- m_uncommittedWidth = 0;
-}
-
-void LineWidth::applyOverhang(RenderRubyRun* rubyRun, RenderObject* startRenderer, RenderObject* endRenderer)
-{
- int startOverhang;
- int endOverhang;
- rubyRun->getOverhang(m_isFirstLine, startRenderer, endRenderer, startOverhang, endOverhang);
-
- startOverhang = std::min<int>(startOverhang, m_committedWidth);
- m_availableWidth += startOverhang;
-
- endOverhang = std::max(std::min<int>(endOverhang, m_availableWidth - currentWidth()), 0);
- m_availableWidth += endOverhang;
- m_overhangWidth += startOverhang + endOverhang;
-}
-
-void LineWidth::fitBelowFloats()
-{
- ASSERT(!m_committedWidth);
- ASSERT(!fitsOnLine());
-
- LayoutUnit floatLogicalBottom;
- LayoutUnit lastFloatLogicalBottom = m_block.logicalHeight();
- float newLineWidth = m_availableWidth;
- float newLineLeft = m_left;
- float newLineRight = m_right;
- while (true) {
- floatLogicalBottom = m_block.nextFloatLogicalBottomBelow(lastFloatLogicalBottom, ShapeOutsideFloatShapeOffset);
- if (floatLogicalBottom <= lastFloatLogicalBottom)
- break;
-
- newLineLeft = m_block.logicalLeftOffsetForLine(floatLogicalBottom, shouldIndentText());
- newLineRight = m_block.logicalRightOffsetForLine(floatLogicalBottom, shouldIndentText());
- newLineWidth = max(0.0f, newLineRight - newLineLeft);
- lastFloatLogicalBottom = floatLogicalBottom;
-
- // FIXME: This code should be refactored to incorporate with the code above.
- ShapeInsideInfo* shapeInsideInfo = m_block.layoutShapeInsideInfo();
- if (shapeInsideInfo) {
- LayoutUnit logicalOffsetFromShapeContainer = m_block.logicalOffsetFromShapeAncestorContainer(shapeInsideInfo->owner()).height();
- LayoutUnit lineHeight = m_block.lineHeight(false, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
- shapeInsideInfo->updateSegmentsForLine(lastFloatLogicalBottom + logicalOffsetFromShapeContainer, lineHeight);
- updateCurrentShapeSegment();
- updateAvailableWidth();
- }
-
- if (newLineWidth >= m_uncommittedWidth)
- break;
- }
-
- if (newLineWidth > m_availableWidth) {
- m_block.setLogicalHeight(lastFloatLogicalBottom);
- m_availableWidth = newLineWidth + m_overhangWidth;
- m_left = newLineLeft;
- m_right = newLineRight;
- }
-}
-
-void LineWidth::updateCurrentShapeSegment()
-{
- if (ShapeInsideInfo* shapeInsideInfo = m_block.layoutShapeInsideInfo())
- m_segment = shapeInsideInfo->currentSegment();
-}
-
-void LineWidth::computeAvailableWidthFromLeftAndRight()
-{
- m_availableWidth = max(0.0f, m_right - m_left) + m_overhangWidth;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/LineWidth.h b/chromium/third_party/WebKit/Source/core/rendering/LineWidth.h
deleted file mode 100644
index 59e1442445e..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/LineWidth.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef LineWidth_h
-#define LineWidth_h
-
-#include "platform/LayoutUnit.h"
-
-namespace WebCore {
-
-class FloatingObject;
-class RenderBlock;
-class RenderObject;
-class RenderRubyRun;
-class RenderBlockFlow;
-
-struct LineSegment;
-
-enum IndentTextOrNot { DoNotIndentText, IndentText };
-
-class LineWidth {
-public:
- LineWidth(RenderBlockFlow&, bool isFirstLine, IndentTextOrNot shouldIndentText);
-
- bool fitsOnLine() const { return currentWidth() <= (m_availableWidth + LayoutUnit::epsilon()); }
- bool fitsOnLine(float extra) const { return currentWidth() + extra <= (m_availableWidth + LayoutUnit::epsilon()); }
-
- float currentWidth() const { return m_committedWidth + m_uncommittedWidth; }
- // FIXME: We should eventually replace these three functions by ones that work on a higher abstraction.
- float uncommittedWidth() const { return m_uncommittedWidth; }
- float committedWidth() const { return m_committedWidth; }
- float availableWidth() const { return m_availableWidth; }
-
- void updateAvailableWidth(LayoutUnit minimumHeight = 0);
- void shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject*);
- void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
- void commit();
- void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
- void fitBelowFloats();
-
- void updateCurrentShapeSegment();
-
- bool shouldIndentText() const { return m_shouldIndentText == IndentText; }
-
-private:
- void computeAvailableWidthFromLeftAndRight();
-
- RenderBlockFlow& m_block;
- float m_uncommittedWidth;
- float m_committedWidth;
- float m_overhangWidth; // The amount by which |m_availableWidth| has been inflated to account for possible contraction due to ruby overhang.
- float m_left;
- float m_right;
- float m_availableWidth;
- const LineSegment* m_segment;
- bool m_isFirstLine;
- IndentTextOrNot m_shouldIndentText;
-};
-
-}
-
-#endif // LineWidth_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/OrderIterator.cpp b/chromium/third_party/WebKit/Source/core/rendering/OrderIterator.cpp
index 20926a576d5..3dfe9b65afc 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/OrderIterator.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/OrderIterator.cpp
@@ -63,9 +63,9 @@ RenderBox* OrderIterator::next()
m_isReset = false;
}
- m_currentChild = firstChildBox();
+ m_currentChild = m_containerBox->firstChildBox();
} else {
- m_currentChild = nextSiblingBox();
+ m_currentChild = m_currentChild->nextSiblingBox();
}
} while (!m_currentChild || m_currentChild->style()->order() != *m_orderValuesIterator);
@@ -79,38 +79,11 @@ void OrderIterator::reset()
m_isReset = true;
}
-RenderBox* OrderIterator::firstChildBox()
-{
- if (m_children.isEmpty())
- return m_containerBox->firstChildBox();
-
- m_childIndex = 0;
- return m_children[0];
-}
-
-RenderBox* OrderIterator::nextSiblingBox()
-{
- if (m_children.isEmpty())
- return m_currentChild->nextSiblingBox();
-
- if (m_childIndex >= m_children.size() - 1)
- return 0;
-
- return m_children[++m_childIndex];
-}
-
OrderIteratorPopulator::~OrderIteratorPopulator()
{
m_iterator.reset();
}
-void OrderIteratorPopulator::storeChild(RenderBox* child)
-{
- m_iterator.m_children.append(child);
-
- collectChild(child);
-}
-
void OrderIteratorPopulator::collectChild(const RenderBox* child)
{
m_iterator.m_orderValues.insert(child->style()->order());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/OrderIterator.h b/chromium/third_party/WebKit/Source/core/rendering/OrderIterator.h
index 2a019150a6b..d0ef6c04c8e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/OrderIterator.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/OrderIterator.h
@@ -53,15 +53,9 @@ public:
void reset();
private:
- RenderBox* firstChildBox();
- RenderBox* nextSiblingBox();
-
- // If |m_children| is not empty, we will use it to iterate over this fixed subset.
const RenderBox* m_containerBox;
- Vector<RenderBox*> m_children;
RenderBox* m_currentChild;
- size_t m_childIndex;
typedef std::set<int> OrderValues;
OrderValues m_orderValues;
@@ -79,7 +73,6 @@ public:
~OrderIteratorPopulator();
- void storeChild(RenderBox*);
void collectChild(const RenderBox*);
private:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/Pagination.cpp b/chromium/third_party/WebKit/Source/core/rendering/Pagination.cpp
deleted file mode 100644
index 26822b03988..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/Pagination.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/rendering/Pagination.h"
-
-#include "core/rendering/style/RenderStyle.h"
-
-namespace WebCore {
-
-void Pagination::setStylesForPaginationMode(Mode paginationMode, RenderStyle* style)
-{
- if (paginationMode == Unpaginated)
- return;
-
- switch (paginationMode) {
- case LeftToRightPaginated:
- style->setColumnAxis(HorizontalColumnAxis);
- if (style->isHorizontalWritingMode())
- style->setColumnProgression(style->isLeftToRightDirection() ? NormalColumnProgression : ReverseColumnProgression);
- else
- style->setColumnProgression(style->isFlippedBlocksWritingMode() ? ReverseColumnProgression : NormalColumnProgression);
- break;
- case RightToLeftPaginated:
- style->setColumnAxis(HorizontalColumnAxis);
- if (style->isHorizontalWritingMode())
- style->setColumnProgression(style->isLeftToRightDirection() ? ReverseColumnProgression : NormalColumnProgression);
- else
- style->setColumnProgression(style->isFlippedBlocksWritingMode() ? NormalColumnProgression : ReverseColumnProgression);
- break;
- case TopToBottomPaginated:
- style->setColumnAxis(VerticalColumnAxis);
- if (style->isHorizontalWritingMode())
- style->setColumnProgression(style->isFlippedBlocksWritingMode() ? ReverseColumnProgression : NormalColumnProgression);
- else
- style->setColumnProgression(style->isLeftToRightDirection() ? NormalColumnProgression : ReverseColumnProgression);
- break;
- case BottomToTopPaginated:
- style->setColumnAxis(VerticalColumnAxis);
- if (style->isHorizontalWritingMode())
- style->setColumnProgression(style->isFlippedBlocksWritingMode() ? NormalColumnProgression : ReverseColumnProgression);
- else
- style->setColumnProgression(style->isLeftToRightDirection() ? ReverseColumnProgression : NormalColumnProgression);
- break;
- case Unpaginated:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/Pagination.h b/chromium/third_party/WebKit/Source/core/rendering/Pagination.h
deleted file mode 100644
index ce695f7bf14..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/Pagination.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef Pagination_h
-#define Pagination_h
-
-namespace WebCore {
-
-class RenderStyle;
-
-struct Pagination {
- enum Mode { Unpaginated, LeftToRightPaginated, RightToLeftPaginated, TopToBottomPaginated, BottomToTopPaginated };
-
- Pagination()
- : mode(Unpaginated)
- , behavesLikeColumns(false)
- , pageLength(0)
- , gap(0)
- {
- };
-
- bool operator==(const Pagination& other) const
- {
- return mode == other.mode && behavesLikeColumns == other.behavesLikeColumns && pageLength == other.pageLength && gap == other.gap;
- }
-
- bool operator!=(const Pagination& other) const
- {
- return mode != other.mode || behavesLikeColumns != other.behavesLikeColumns || pageLength != other.pageLength || gap != other.gap;
- }
-
- Mode mode;
- bool behavesLikeColumns;
- unsigned pageLength;
- unsigned gap;
-
- static void setStylesForPaginationMode(Mode, RenderStyle*);
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/rendering/PaintInfo.h b/chromium/third_party/WebKit/Source/core/rendering/PaintInfo.h
index be99ec39407..50b6463a1a4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/PaintInfo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/PaintInfo.h
@@ -40,7 +40,6 @@ namespace WebCore {
class RenderInline;
class RenderLayerModelObject;
class RenderObject;
-class RenderRegion;
class RenderWidget;
typedef HashMap<RenderWidget*, IntRect> OverlapTestRequestMap;
@@ -51,14 +50,13 @@ typedef HashMap<RenderWidget*, IntRect> OverlapTestRequestMap;
*/
struct PaintInfo {
PaintInfo(GraphicsContext* newContext, const IntRect& newRect, PaintPhase newPhase, PaintBehavior newPaintBehavior,
- RenderObject* newPaintingRoot = 0, RenderRegion* region = 0, ListHashSet<RenderInline*>* newOutlineObjects = 0,
+ RenderObject* newPaintingRoot = 0, ListHashSet<RenderInline*>* newOutlineObjects = 0,
OverlapTestRequestMap* overlapTestRequests = 0, const RenderLayerModelObject* newPaintContainer = 0)
: context(newContext)
, rect(newRect)
, phase(newPhase)
, paintBehavior(newPaintBehavior)
, paintingRoot(newPaintingRoot)
- , renderRegion(region)
, overlapTestRequests(overlapTestRequests)
, m_paintContainer(newPaintContainer)
, m_outlineObjects(newOutlineObjects)
@@ -87,9 +85,9 @@ struct PaintInfo {
bool skipRootBackground() const { return paintBehavior & PaintBehaviorSkipRootBackground; }
bool paintRootBackgroundOnly() const { return paintBehavior & PaintBehaviorRootBackgroundOnly; }
- void applyTransform(const AffineTransform& localToAncestorTransform)
+ void applyTransform(const AffineTransform& localToAncestorTransform, bool identityStatusUnknown = true)
{
- if (localToAncestorTransform.isIdentity())
+ if (identityStatusUnknown && localToAncestorTransform.isIdentity())
return;
context->concatCTM(localToAncestorTransform);
@@ -97,7 +95,10 @@ struct PaintInfo {
if (rect == infiniteRect())
return;
- rect = localToAncestorTransform.inverse().mapRect(rect);
+ if (localToAncestorTransform.isInvertible())
+ rect = localToAncestorTransform.inverse().mapRect(rect);
+ else
+ rect.setSize(IntSize(0, 0));
}
static IntRect infiniteRect() { return IntRect(LayoutRect::infiniteRect()); }
@@ -112,7 +113,6 @@ struct PaintInfo {
PaintPhase phase;
PaintBehavior paintBehavior;
RenderObject* paintingRoot; // used to draw just one element and its visual kids
- RenderRegion* renderRegion;
OverlapTestRequestMap* overlapTestRequests;
private:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/PartialLayoutState.h b/chromium/third_party/WebKit/Source/core/rendering/PartialLayoutState.h
deleted file mode 100644
index 1ac7a328f71..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/PartialLayoutState.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PartialLayoutState_h
-#define PartialLayoutState_h
-
-#include "core/rendering/RenderObject.h"
-
-namespace WebCore {
-
-class PartialLayoutState {
- friend class PartialLayoutDisabler;
-public:
- PartialLayoutState()
- : m_shouldStop(false)
- , m_stopAtRenderer(0)
- , m_disableCount(0)
- {
- }
-
- // True if we plan to do a partial layout, or are in the process of stopping a partial layout.
- bool isPartialLayout() const { return m_stopAtRenderer || m_shouldStop; }
-
- bool isStopping() const { return m_shouldStop; }
- bool checkPartialLayoutComplete(const RenderObject*);
- void setStopAtRenderer(const RenderObject* renderer) { m_stopAtRenderer = renderer; }
- void reset() { m_shouldStop = false; m_stopAtRenderer = 0; }
-
-private:
- void disable() { ASSERT(!m_shouldStop); m_disableCount++; }
- void enable() { ASSERT(m_disableCount > 0); m_disableCount--; }
- const RenderObject* stopAtRenderer() const { return m_disableCount > 0 ? 0 : m_stopAtRenderer; }
-
- bool m_shouldStop;
- const RenderObject* m_stopAtRenderer;
- int m_disableCount;
-};
-
-inline bool PartialLayoutState::checkPartialLayoutComplete(const RenderObject* renderer)
-{
- if (m_shouldStop)
- return true;
-
- if (renderer == stopAtRenderer()) {
- m_shouldStop = true;
- m_stopAtRenderer = 0;
- return true;
- }
-
- return false;
-}
-
-class PartialLayoutDisabler {
- WTF_MAKE_NONCOPYABLE(PartialLayoutDisabler);
-public:
- PartialLayoutDisabler(PartialLayoutState& partialLayout, bool disable = true)
- : m_partialLayout(partialLayout)
- , m_disable(disable)
- {
- if (m_disable)
- m_partialLayout.disable();
- }
-
- ~PartialLayoutDisabler()
- {
- if (m_disable)
- m_partialLayout.enable();
- }
-private:
- PartialLayoutState& m_partialLayout;
- bool m_disable;
-};
-
-} // namespace WebCore
-
-#endif // PartialLayoutState_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RegionOversetState.h b/chromium/third_party/WebKit/Source/core/rendering/RegionOversetState.h
deleted file mode 100644
index e29e370a20a..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RegionOversetState.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef RegionOversetState_h
-#define RegionOversetState_h
-
-namespace WebCore {
-
-enum RegionOversetState {
- RegionUndefined,
- RegionEmpty,
- RegionFit,
- RegionOverset
-};
-
-} // namespace WebCore
-
-#endif // RegionOversetState_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderApplet.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderApplet.cpp
index be4de73f89d..38d0e4c938f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderApplet.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderApplet.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "core/rendering/RenderApplet.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLAppletElement.h"
namespace WebCore {
@@ -30,6 +31,7 @@ RenderApplet::RenderApplet(HTMLAppletElement* applet)
: RenderEmbeddedObject(applet)
{
setInline(true);
+ UseCounter::count(document(), UseCounter::HTMLAppletElement);
}
RenderApplet::~RenderApplet()
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderApplet.h b/chromium/third_party/WebKit/Source/core/rendering/RenderApplet.h
index 3a0f7af28b2..9f740f404db 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderApplet.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderApplet.h
@@ -34,7 +34,7 @@ public:
virtual ~RenderApplet();
private:
- virtual const char* renderName() const { return "RenderApplet"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderApplet"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBR.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderBR.cpp
index ea74001d6a7..e928cceceb7 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBR.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBR.cpp
@@ -35,7 +35,6 @@ static PassRefPtr<StringImpl> newlineString()
RenderBR::RenderBR(Node* node)
: RenderText(node, newlineString())
- , m_lineHeight(-1)
{
}
@@ -45,22 +44,13 @@ RenderBR::~RenderBR()
int RenderBR::lineHeight(bool firstLine) const
{
- if (firstLine && document().styleEngine()->usesFirstLineRules()) {
- RenderStyle* s = style(firstLine);
- if (s != style())
- return s->computedLineHeight(view());
- }
-
- if (m_lineHeight == -1)
- m_lineHeight = style()->computedLineHeight(view());
-
- return m_lineHeight;
+ RenderStyle* s = style(firstLine && document().styleEngine()->usesFirstLineRules());
+ return s->computedLineHeight();
}
void RenderBR::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderText::styleDidChange(diff, oldStyle);
- m_lineHeight = -1;
}
int RenderBR::caretMinOffset() const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBR.h b/chromium/third_party/WebKit/Source/core/rendering/RenderBR.h
index 62d1a53479e..ff69d3a87a2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBR.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBR.h
@@ -29,35 +29,30 @@
*/
namespace WebCore {
-class Position;
-
class RenderBR FINAL : public RenderText {
public:
explicit RenderBR(Node*);
virtual ~RenderBR();
- virtual const char* renderName() const { return "RenderBR"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderBR"; }
- virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/) OVERRIDE { return LayoutRect(); }
+ virtual LayoutRect selectionRectForPaintInvalidation(const RenderLayerModelObject* /*paintInvalidationContainer*/, bool /*clipToVisibleContent*/) OVERRIDE { return LayoutRect(); }
- virtual float width(unsigned /*from*/, unsigned /*len*/, const Font&, float /*xPos*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/ , GlyphOverflow* = 0) const { return 0; }
- virtual float width(unsigned /*from*/, unsigned /*len*/, float /*xpos*/, bool = false /*firstLine*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/, GlyphOverflow* = 0) const { return 0; }
+ virtual float width(unsigned /*from*/, unsigned /*len*/, const Font&, float /*xPos*/, TextDirection, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/ , GlyphOverflow* = 0) const OVERRIDE { return 0; }
+ virtual float width(unsigned /*from*/, unsigned /*len*/, float /*xpos*/, TextDirection, bool = false /*firstLine*/, HashSet<const SimpleFontData*>* = 0 /*fallbackFonts*/, GlyphOverflow* = 0) const OVERRIDE { return 0; }
int lineHeight(bool firstLine) const;
// overrides
- virtual bool isBR() const { return true; }
+ virtual bool isBR() const OVERRIDE { return true; }
- virtual int caretMinOffset() const;
- virtual int caretMaxOffset() const;
+ virtual int caretMinOffset() const OVERRIDE;
+ virtual int caretMaxOffset() const OVERRIDE;
virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-
-private:
- mutable int m_lineHeight;
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBR, isBR());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBlock.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderBlock.cpp
index 84c790b6ab7..e7cf72c32b3 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBlock.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBlock.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "core/rendering/RenderBlock.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
@@ -33,8 +33,8 @@
#include "core/editing/Editor.h"
#include "core/editing/FrameSelection.h"
#include "core/fetch/ResourceLoadPriorityOptimizer.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/rendering/FastTextAutosizer.h"
@@ -43,18 +43,19 @@
#include "core/rendering/HitTestResult.h"
#include "core/rendering/InlineIterator.h"
#include "core/rendering/InlineTextBox.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderCombineText.h"
#include "core/rendering/RenderDeprecatedFlexibleBox.h"
#include "core/rendering/RenderFlexibleBox.h"
+#include "core/rendering/RenderFlowThread.h"
+#include "core/rendering/RenderGrid.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderMarquee.h"
-#include "core/rendering/RenderNamedFlowThread.h"
#include "core/rendering/RenderRegion.h"
#include "core/rendering/RenderTableCell.h"
+#include "core/rendering/RenderTextControl.h"
#include "core/rendering/RenderTextFragment.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
@@ -63,6 +64,7 @@
#include "core/rendering/style/RenderStyle.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/TransformState.h"
+#include "platform/graphics/GraphicsContextCullSaver.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "wtf/StdLibExtras.h"
#include "wtf/TemporaryChange.h"
@@ -82,7 +84,14 @@ struct SameSizeAsRenderBlock : public RenderBox {
uint32_t bitfields;
};
+struct SameSizeAsRenderBlockRareData {
+ int paginationStrut;
+ int pageLogicalOffset;
+ uint32_t bitfields;
+};
+
COMPILE_ASSERT(sizeof(RenderBlock) == sizeof(SameSizeAsRenderBlock), RenderBlock_should_stay_small);
+COMPILE_ASSERT(sizeof(RenderBlock::RenderBlockRareData) == sizeof(SameSizeAsRenderBlockRareData), RenderBlockRareData_should_stay_small);
typedef WTF::HashMap<const RenderBox*, OwnPtr<ColumnInfo> > ColumnInfoMap;
static ColumnInfoMap* gColumnInfoMap = 0;
@@ -108,6 +117,8 @@ class OverflowEventDispatcher {
public:
OverflowEventDispatcher(const RenderBlock* block)
: m_block(block)
+ , m_hadHorizontalLayoutOverflow(false)
+ , m_hadVerticalLayoutOverflow(false)
{
m_shouldDispatchEvent = !m_block->isAnonymous() && m_block->hasOverflowClip() && m_block->document().hasListenerType(Document::OVERFLOWCHANGED_LISTENER);
if (m_shouldDispatchEvent) {
@@ -130,7 +141,7 @@ public:
if (!horizontalLayoutOverflowChanged && !verticalLayoutOverflowChanged)
return;
- RefPtr<OverflowEvent> event = OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow);
+ RefPtrWillBeRawPtr<OverflowEvent> event = OverflowEvent::create(horizontalLayoutOverflowChanged, hasHorizontalLayoutOverflow, verticalLayoutOverflowChanged, hasVerticalLayoutOverflow);
event->setTarget(m_block->node());
m_block->document().enqueueAnimationFrameEvent(event.release());
}
@@ -144,12 +155,12 @@ private:
RenderBlock::RenderBlock(ContainerNode* node)
: RenderBox(node)
- , m_lineHeight(-1)
, m_hasMarginBeforeQuirk(false)
, m_hasMarginAfterQuirk(false)
, m_beingDestroyed(false)
, m_hasMarkupTruncation(false)
, m_hasBorderOrPaddingLogicalWidthChanged(false)
+ , m_hasOnlySelfCollapsingChildren(false)
{
setChildrenInline(true);
}
@@ -174,8 +185,11 @@ static void removeBlockFromDescendantAndContainerMaps(RenderBlock* block, Tracke
static void appendImageIfNotNull(Vector<ImageResource*>& imageResources, const StyleImage* styleImage)
{
- if (styleImage && styleImage->cachedImage())
- imageResources.append(styleImage->cachedImage());
+ if (styleImage && styleImage->cachedImage()) {
+ ImageResource* imageResource = styleImage->cachedImage();
+ if (imageResource && !imageResource->isLoaded())
+ imageResources.append(styleImage->cachedImage());
+ }
}
static void appendLayers(Vector<ImageResource*>& images, const FillLayer* styleLayer)
@@ -185,6 +199,25 @@ static void appendLayers(Vector<ImageResource*>& images, const FillLayer* styleL
}
}
+static void appendImagesFromStyle(Vector<ImageResource*>& images, RenderStyle& blockStyle)
+{
+ appendLayers(images, blockStyle.backgroundLayers());
+ appendLayers(images, blockStyle.maskLayers());
+
+ const ContentData* contentData = blockStyle.contentData();
+ if (contentData && contentData->isImage()) {
+ const ImageContentData* imageContentData = static_cast<const ImageContentData*>(contentData);
+ appendImageIfNotNull(images, imageContentData->image());
+ }
+ if (blockStyle.boxReflect())
+ appendImageIfNotNull(images, blockStyle.boxReflect()->mask().image());
+ appendImageIfNotNull(images, blockStyle.listStyleImage());
+ appendImageIfNotNull(images, blockStyle.borderImageSource());
+ appendImageIfNotNull(images, blockStyle.maskBoxImageSource());
+ if (blockStyle.shapeOutside())
+ appendImageIfNotNull(images, blockStyle.shapeOutside()->image());
+}
+
RenderBlock::~RenderBlock()
{
if (hasColumns())
@@ -240,25 +273,27 @@ void RenderBlock::willBeDestroyed()
if (UNLIKELY(gDelayedUpdateScrollInfoSet != 0))
gDelayedUpdateScrollInfoSet->remove(this);
- FastTextAutosizer* textAutosizer = document().fastTextAutosizer();
- if (textAutosizer)
+ if (FastTextAutosizer* textAutosizer = document().fastTextAutosizer())
textAutosizer->destroy(this);
RenderBox::willBeDestroyed();
}
-void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderBlock::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
RenderStyle* oldStyle = style();
- setReplaced(newStyle->isDisplayInlineType());
+ setReplaced(newStyle.isDisplayInlineType());
- if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle->position()) {
- if (newStyle->position() == StaticPosition)
+ if (oldStyle && parent()) {
+ bool oldStyleIsContainer = oldStyle->position() != StaticPosition || oldStyle->hasTransformRelatedProperty();
+ bool newStyleIsContainer = newStyle.position() != StaticPosition || newStyle.hasTransformRelatedProperty();
+
+ if (oldStyleIsContainer && !newStyleIsContainer) {
// Clear our positioned objects list. Our absolutely positioned descendants will be
// inserted into our containing block's positioned objects list during layout.
removePositionedObjects(0, NewContainingBlock);
- else if (oldStyle->position() == StaticPosition) {
+ } else if (!oldStyleIsContainer && newStyleIsContainer) {
// Remove our absolutely positioned descendants from their current containing block.
// They will be inserted into our positioned objects list during layout.
RenderObject* cb = parent();
@@ -298,8 +333,6 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
RenderStyle* newStyle = style();
- updateShapeInsideInfoAfterStyleChange(newStyle->resolvedShapeInside(), oldStyle ? oldStyle->resolvedShapeInside() : RenderStyle::initialShapeInside());
-
if (!isAnonymousBlock()) {
// Ensure that all of our continuation blocks pick up the new style.
for (RenderBlock* currCont = blockElementContinuation(); currCont; currCont = currCont->blockElementContinuation()) {
@@ -310,16 +343,63 @@ void RenderBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
}
}
- FastTextAutosizer* textAutosizer = document().fastTextAutosizer();
- if (textAutosizer)
+ if (FastTextAutosizer* textAutosizer = document().fastTextAutosizer())
textAutosizer->record(this);
propagateStyleToAnonymousChildren(true);
- m_lineHeight = -1;
// It's possible for our border/padding to change, but for the overall logical width of the block to
// end up being the same. We keep track of this change so in layoutBlock, we can know to set relayoutChildren=true.
- m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff == StyleDifferenceLayout && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle);
+ m_hasBorderOrPaddingLogicalWidthChanged = oldStyle && diff.needsFullLayout() && needsLayout() && borderOrPaddingLogicalWidthChanged(oldStyle, newStyle);
+
+ // If the style has unloaded images, want to notify the ResourceLoadPriorityOptimizer so that
+ // network priorities can be set.
+ Vector<ImageResource*> images;
+ appendImagesFromStyle(images, *newStyle);
+ if (images.isEmpty())
+ ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->removeRenderObject(this);
+ else
+ ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->addRenderObject(this);
+}
+
+void RenderBlock::invalidateTreeAfterLayout(const RenderLayerModelObject& invalidationContainer)
+{
+ // Note, we don't want to early out here using shouldCheckForInvalidationAfterLayout as
+ // we have to make sure we go through any positioned objects as they won't be seen in
+ // the normal tree walk.
+
+ if (shouldCheckForPaintInvalidationAfterLayout())
+ RenderBox::invalidateTreeAfterLayout(invalidationContainer);
+
+ // Take care of positioned objects. This is required as LayoutState keeps a single clip rect.
+ if (TrackedRendererListHashSet* positionedObjects = this->positionedObjects()) {
+ TrackedRendererListHashSet::iterator end = positionedObjects->end();
+ LayoutState state(*this, isTableRow() ? LayoutSize() : locationOffset());
+ for (TrackedRendererListHashSet::iterator it = positionedObjects->begin(); it != end; ++it) {
+ RenderBox* box = *it;
+
+ // One of the renderers we're skipping over here may be the child's repaint container,
+ // so we can't pass our own repaint container along.
+ const RenderLayerModelObject& repaintContainerForChild = *box->containerForPaintInvalidation();
+
+ // If the positioned renderer is absolutely positioned and it is inside
+ // a relatively positioend inline element, we need to account for
+ // the inline elements position in LayoutState.
+ if (box->style()->position() == AbsolutePosition) {
+ RenderObject* container = box->container(&repaintContainerForChild, 0);
+ if (container->isInFlowPositioned() && container->isRenderInline()) {
+ // FIXME: We should be able to use layout-state for this.
+ // Currently, we will place absolutly positioned elements inside
+ // relatively positioned inline blocks in the wrong location. crbug.com/371485
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
+ box->invalidateTreeAfterLayout(repaintContainerForChild);
+ continue;
+ }
+ }
+
+ box->invalidateTreeAfterLayout(repaintContainerForChild);
+ }
+ }
}
RenderBlock* RenderBlock::continuationBefore(RenderObject* beforeChild)
@@ -458,7 +538,7 @@ RenderBlockFlow* RenderBlock::containingColumnsBlock(bool allowAnonymousColumnBl
{
RenderBlock* firstChildIgnoringAnonymousWrappers = 0;
for (RenderObject* curr = this; curr; curr = curr->parent()) {
- if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isRoot() || curr->isRenderView() || curr->hasOverflowClip()
+ if (!curr->isRenderBlock() || curr->isFloatingOrOutOfFlowPositioned() || curr->isTableCell() || curr->isDocumentElement() || curr->isRenderView() || curr->hasOverflowClip()
|| curr->isInlineBlockOrInlineTable())
return 0;
@@ -622,9 +702,9 @@ void RenderBlock::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
// Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
// get deleted properly. Because objects moves from the pre block into the post block, we want to
// make new line boxes instead of leaving the old line boxes around.
- pre->setNeedsLayoutAndPrefWidthsRecalc();
- block->setNeedsLayoutAndPrefWidthsRecalc();
- post->setNeedsLayoutAndPrefWidthsRecalc();
+ pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlockFlow* newBlockBox, RenderObject* newChild)
@@ -672,10 +752,10 @@ void RenderBlock::makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, R
// get deleted properly. Because objects moved from the pre block into the post block, we want to
// make new line boxes instead of leaving the old line boxes around.
if (pre)
- pre->setNeedsLayoutAndPrefWidthsRecalc();
- block->setNeedsLayoutAndPrefWidthsRecalc();
+ pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
if (post)
- post->setNeedsLayoutAndPrefWidthsRecalc();
+ post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
RenderBlockFlow* RenderBlock::columnsBlockForSpanningElement(RenderObject* newChild)
@@ -725,7 +805,7 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
|| beforeChildAnonymousContainer->isRenderFullScreenPlaceholder()
) {
// Insert the child into the anonymous block box instead of here.
- if (newChild->isInline() || beforeChild->parent()->firstChild() != beforeChild)
+ if (newChild->isInline() || newChild->isFloatingOrOutOfFlowPositioned() || beforeChild->parent()->slowFirstChild() != beforeChild)
beforeChild->parent()->addChild(newChild, beforeChild);
else
addChild(newChild, beforeChild->parent());
@@ -751,7 +831,7 @@ void RenderBlock::addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild,
}
// Check for a spanning element in columns.
- if (gColumnFlowSplitEnabled) {
+ if (gColumnFlowSplitEnabled && !document().regionBasedColumnsEnabled()) {
RenderBlockFlow* columnsBlockAncestor = columnsBlockForSpanningElement(newChild);
if (columnsBlockAncestor) {
TemporaryChange<bool> columnFlowSplitEnabled(gColumnFlowSplitEnabled, false);
@@ -886,19 +966,6 @@ void RenderBlock::deleteLineBoxTree()
cache->recomputeIsIgnored(this);
}
-RootInlineBox* RenderBlock::createAndAppendRootInlineBox()
-{
- RootInlineBox* rootBox = createRootInlineBox();
- m_lineBoxes.appendLineBox(rootBox);
-
- if (UNLIKELY(AXObjectCache::accessibilityEnabled()) && m_lineBoxes.firstLineBox() == rootBox) {
- if (AXObjectCache* cache = document().existingAXObjectCache())
- cache->recomputeIsIgnored(this);
- }
-
- return rootBox;
-}
-
void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
{
// makeChildrenNonInline takes a block whose children are *all* inline and it
@@ -938,7 +1005,7 @@ void RenderBlock::makeChildrenNonInline(RenderObject *insertionPoint)
ASSERT(!c->isInline());
#endif
- repaint();
+ paintInvalidationForWholeRenderer();
}
void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
@@ -986,6 +1053,10 @@ void RenderBlock::removeLeftoverAnonymousBlock(RenderBlock* child)
// Remove all the information in the flow thread associated with the leftover anonymous block.
child->removeFromRenderFlowThread();
+ // RenderGrid keeps track of its children, we must notify it about changes in the tree.
+ if (child->parent()->isRenderGrid())
+ toRenderGrid(child->parent())->dirtyGrid();
+
child->setParent(0);
child->setPreviousSibling(0);
child->setNextSibling(0);
@@ -1021,7 +1092,7 @@ void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock*
// destroyed. See crbug.com/282088
if (child->beingDestroyed())
return;
- parent->setNeedsLayoutAndPrefWidthsRecalc();
+ parent->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
parent->setChildrenInline(child->childrenInline());
RenderObject* nextSibling = child->nextSibling();
@@ -1033,8 +1104,6 @@ void RenderBlock::collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock*
// Explicitly delete the child's line box tree, or the special anonymous
// block handling in willBeDestroyed will cause problems.
child->deleteLineBoxTree();
- if (childFlowThread && childFlowThread->isRenderNamedFlowThread())
- toRenderNamedFlowThread(childFlowThread)->removeFlowChildInfo(child);
child->destroy();
}
@@ -1057,9 +1126,9 @@ void RenderBlock::removeChild(RenderObject* oldChild)
RenderObject* next = oldChild->nextSibling();
bool canMergeAnonymousBlocks = canMergeContiguousAnonymousBlocks(oldChild, prev, next);
if (canMergeAnonymousBlocks && prev && next) {
- prev->setNeedsLayoutAndPrefWidthsRecalc();
- RenderBlock* nextBlock = toRenderBlock(next);
- RenderBlock* prevBlock = toRenderBlock(prev);
+ prev->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ RenderBlockFlow* nextBlock = toRenderBlockFlow(next);
+ RenderBlockFlow* prevBlock = toRenderBlockFlow(prev);
if (prev->childrenInline() != next->childrenInline()) {
RenderBlock* inlineChildrenBlock = prev->childrenInline() ? prevBlock : nextBlock;
@@ -1079,7 +1148,7 @@ void RenderBlock::removeChild(RenderObject* oldChild)
// Now just put the inlineChildrenBlock inside the blockChildrenBlock.
blockChildrenBlock->children()->insertChildNode(blockChildrenBlock, inlineChildrenBlock, prev == inlineChildrenBlock ? blockChildrenBlock->firstChild() : 0,
inlineChildrenBlockHasLayer || blockChildrenBlock->hasLayer());
- next->setNeedsLayoutAndPrefWidthsRecalc();
+ next->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
// inlineChildrenBlock got reparented to blockChildrenBlock, so it is no longer a child
// of "this". we null out prev or next so that is not used later in the function.
@@ -1128,7 +1197,7 @@ void RenderBlock::removeChild(RenderObject* oldChild)
// we need to remove ourself and fix the continuation chain.
if (!beingDestroyed() && isAnonymousBlockContinuation() && !oldChild->isListMarker()) {
RenderObject* containingBlockIgnoringAnonymous = containingBlock();
- while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymousBlock())
+ while (containingBlockIgnoringAnonymous && containingBlockIgnoringAnonymous->isAnonymous())
containingBlockIgnoringAnonymous = containingBlockIgnoringAnonymous->containingBlock();
for (RenderObject* curr = this; curr; curr = curr->previousInPreOrder(containingBlockIgnoringAnonymous)) {
if (curr->virtualContinuation() != this)
@@ -1160,6 +1229,20 @@ bool RenderBlock::isSelfCollapsingBlock() const
// (c) have border/padding,
// (d) have a min-height
// (e) have specified that one of our margins can't collapse using a CSS extension
+ // (f) establish a new block formatting context.
+
+ // The early exit must be done before we check for clean layout.
+ // We should be able to give a quick answer if the box is a relayout boundary.
+ // Being a relayout boundary implies a block formatting context, and also
+ // our internal layout shouldn't affect our container in any way.
+ if (createsBlockFormattingContext())
+ return false;
+
+ // Placeholder elements are not laid out until the dimensions of their parent text control are known, so they
+ // don't get layout until their parent has had layout - this is unique in the layout tree and means
+ // when we call isSelfCollapsingBlock on them we find that they still need layout.
+ ASSERT(!needsLayout() || (node() && node()->isElementNode() && toElement(node())->shadowPseudoId() == "-webkit-input-placeholder"));
+
if (logicalHeight() > 0
|| isTable() || borderAndPaddingLogicalHeight()
|| style()->logicalMinHeight().isPositive()
@@ -1186,6 +1269,8 @@ bool RenderBlock::isSelfCollapsingBlock() const
// Whether or not we collapse is dependent on whether all our normal flow children
// are also self-collapsing.
+ if (m_hasOnlySelfCollapsingChildren)
+ return true;
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
if (child->isFloatingOrOutOfFlowPositioned())
continue;
@@ -1248,7 +1333,6 @@ void RenderBlock::updateScrollInfoAfterLayout()
void RenderBlock::layout()
{
OverflowEventDispatcher dispatcher(this);
- LayoutRectRecorder recorder(*this);
// Update our first letter info now.
updateFirstLetter();
@@ -1257,9 +1341,6 @@ void RenderBlock::layout()
// layoutBlock().
layoutBlock(false);
- if (frameView()->partialLayout().isStopping())
- return;
-
// It's safe to check for control clip here, since controls can never be table cells.
// If we have a lightweight clip, there can never be any overflow from children.
if (hasControlClip() && m_overflow)
@@ -1268,42 +1349,13 @@ void RenderBlock::layout()
invalidateBackgroundObscurationStatus();
}
-void RenderBlock::didLayout(ResourceLoadPriorityOptimizer& optimizer)
-{
- RenderBox::didLayout(optimizer);
- updateStyleImageLoadingPriorities(optimizer);
-}
-
-void RenderBlock::didScroll(ResourceLoadPriorityOptimizer& optimizer)
-{
- RenderBox::didScroll(optimizer);
- updateStyleImageLoadingPriorities(optimizer);
-}
-
-void RenderBlock::updateStyleImageLoadingPriorities(ResourceLoadPriorityOptimizer& optimizer)
+bool RenderBlock::updateImageLoadingPriorities()
{
- RenderStyle* blockStyle = style();
- if (!blockStyle)
- return;
-
Vector<ImageResource*> images;
-
- appendLayers(images, blockStyle->backgroundLayers());
- appendLayers(images, blockStyle->maskLayers());
-
- const ContentData* contentData = blockStyle->contentData();
- if (contentData && contentData->isImage()) {
- const ImageContentData* imageContentData = static_cast<const ImageContentData*>(contentData);
- appendImageIfNotNull(images, imageContentData->image());
- }
- if (blockStyle->boxReflect())
- appendImageIfNotNull(images, blockStyle->boxReflect()->mask().image());
- appendImageIfNotNull(images, blockStyle->listStyleImage());
- appendImageIfNotNull(images, blockStyle->borderImageSource());
- appendImageIfNotNull(images, blockStyle->maskBoxImageSource());
+ appendImagesFromStyle(images, *style());
if (images.isEmpty())
- return;
+ return false;
LayoutRect viewBounds = viewRect();
LayoutRect objectBounds = absoluteContentBox();
@@ -1318,165 +1370,16 @@ void RenderBlock::updateStyleImageLoadingPriorities(ResourceLoadPriorityOptimize
ResourceLoadPriorityOptimizer::VisibilityStatus status = isVisible ?
ResourceLoadPriorityOptimizer::Visible : ResourceLoadPriorityOptimizer::NotVisible;
- for (Vector<ImageResource*>::iterator it = images.begin(), end = images.end(); it != end; ++it)
- optimizer.notifyImageResourceVisibility(*it, status);
-}
-
-void RenderBlock::relayoutShapeDescendantIfMoved(RenderBlock* child, LayoutSize offset)
-{
- LayoutUnit left = isHorizontalWritingMode() ? offset.width() : offset.height();
- if (!left || !child || child->shapeInsideInfo() || !layoutShapeInsideInfo())
- return;
- // Propagate layout markers only up to the child, as we are still in the middle
- // of a layout pass
- child->setNormalChildNeedsLayout(true);
- child->markShapeInsideDescendantsForLayout();
- child->layoutIfNeeded();
-}
-
-ShapeInsideInfo* RenderBlock::layoutShapeInsideInfo() const
-{
- if (ShapeInsideInfo* shapeInsideInfo = view()->layoutState()->shapeInsideInfo())
- return shapeInsideInfo;
-
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (allowsShapeInsideInfoSharing(flowThread)) {
- LayoutUnit lineHeight = this->lineHeight(false, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
- // regionAtBlockOffset returns regions like an array first={0,N-1}, second={N,M-1}, ...
- LayoutUnit offset = logicalHeight() + lineHeight - LayoutUnit(1);
- RenderRegion* region = regionAtBlockOffset(offset);
- if (region && region->logicalHeight())
- return region->shapeInsideInfo();
- }
-
- return 0;
-}
-
-LayoutSize RenderBlock::logicalOffsetFromShapeAncestorContainer(const RenderBlock* container) const
-{
- const RenderBlock* currentBlock = this;
- LayoutRect blockRect(currentBlock->borderBoxRect());
- while (currentBlock && !currentBlock->isRenderFlowThread() && currentBlock != container) {
- RenderBlock* containerBlock = currentBlock->containingBlock();
- ASSERT(containerBlock);
- if (!containerBlock)
- return LayoutSize();
-
- if (containerBlock->style()->writingMode() != currentBlock->style()->writingMode()) {
- // We have to put the block rect in container coordinates
- // and we have to take into account both the container and current block flipping modes
- // Bug: Flipping inline and block directions at the same time will not work,
- // as one of the flipped dimensions will not yet have been set to its final size
- if (containerBlock->style()->isFlippedBlocksWritingMode()) {
- if (containerBlock->isHorizontalWritingMode())
- blockRect.setY(currentBlock->height() - blockRect.maxY());
- else
- blockRect.setX(currentBlock->width() - blockRect.maxX());
- }
- currentBlock->flipForWritingMode(blockRect);
- }
-
- blockRect.moveBy(currentBlock->location());
- currentBlock = containerBlock;
- }
-
- LayoutSize result = isHorizontalWritingMode() ? LayoutSize(blockRect.x(), blockRect.y()) : LayoutSize(blockRect.y(), blockRect.x());
- return result;
-}
-
-void RenderBlock::imageChanged(WrappedImagePtr image, const IntRect*)
-{
- RenderBox::imageChanged(image);
-
- if (!parent() || !everHadLayout())
- return;
-
- ShapeValue* shapeValue = style()->shapeInside();
- if (shapeValue && shapeValue->image() && shapeValue->image()->data() == image) {
- ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
- shapeInsideInfo->dirtyShapeSize();
- markShapeInsideDescendantsForLayout();
- }
-
- ShapeValue* shapeOutsideValue = style()->shapeOutside();
- if (isFloating() && shapeOutsideValue && shapeOutsideValue->image() && shapeOutsideValue->image()->data() == image)
- parent()->setNeedsLayoutAndPrefWidthsRecalc();
-}
-
-void RenderBlock::updateShapeInsideInfoAfterStyleChange(const ShapeValue* shapeInside, const ShapeValue* oldShapeInside)
-{
- // FIXME: A future optimization would do a deep comparison for equality.
- if (shapeInside == oldShapeInside)
- return;
-
- if (shapeInside) {
- ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
- shapeInsideInfo->dirtyShapeSize();
- } else {
- setShapeInsideInfo(nullptr);
- markShapeInsideDescendantsForLayout();
- }
-}
-
-static inline bool shapeInfoRequiresRelayout(const RenderBlock* block)
-{
- ShapeInsideInfo* info = block->shapeInsideInfo();
- if (info)
- info->setNeedsLayout(info->shapeSizeDirty());
- else
- info = block->layoutShapeInsideInfo();
- return info && info->needsLayout();
-}
-
-bool RenderBlock::updateRegionsAndShapesLogicalSize(RenderFlowThread* flowThread)
-{
- if (!flowThread && !shapeInsideInfo())
- return shapeInfoRequiresRelayout(this);
-
- LayoutUnit oldHeight = logicalHeight();
- LayoutUnit oldTop = logicalTop();
-
- // Compute the maximum logical height content may cause this block to expand to
- // FIXME: These should eventually use the const computeLogicalHeight rather than updateLogicalHeight
- setLogicalHeight(RenderFlowThread::maxLogicalHeight());
- updateLogicalHeight();
-
- computeShapeSize();
-
- // Set our start and end regions. No regions above or below us will be considered by our children. They are
- // effectively clamped to our region range.
- computeRegionRangeForBlock(flowThread);
-
- setLogicalHeight(oldHeight);
- setLogicalTop(oldTop);
-
- return shapeInfoRequiresRelayout(this);
-}
-
-void RenderBlock::computeShapeSize()
-{
- ShapeInsideInfo* shapeInsideInfo = this->shapeInsideInfo();
- if (!shapeInsideInfo)
- return;
-
- if (isRenderNamedFlowFragment()) {
- ShapeInsideInfo* parentShapeInsideInfo = toRenderBlock(parent())->shapeInsideInfo();
- ASSERT(parentShapeInsideInfo);
- shapeInsideInfo->setShapeSize(parentShapeInsideInfo->shapeSize().width(), parentShapeInsideInfo->shapeSize().height());
- } else {
- bool percentageLogicalHeightResolvable = percentageLogicalHeightIsResolvableFromBlock(this, false);
- shapeInsideInfo->setShapeSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : LayoutUnit());
+ LayoutRect screenArea;
+ if (!objectBounds.isEmpty()) {
+ screenArea = viewBounds;
+ screenArea.intersect(objectBounds);
}
-}
-void RenderBlock::updateRegionsAndShapesAfterChildLayout(RenderFlowThread* flowThread, bool heightChanged)
-{
- // A previous sibling has changed dimension, so we need to relayout the shape with the content
- ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
- if (heightChanged && shapeInsideInfo)
- shapeInsideInfo->dirtyShapeSize();
+ for (Vector<ImageResource*>::iterator it = images.begin(), end = images.end(); it != end; ++it)
+ ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->notifyImageResourceVisibility(*it, status, screenArea);
- computeRegionRangeForBlock(flowThread);
+ return true;
}
void RenderBlock::computeRegionRangeForBlock(RenderFlowThread* flowThread)
@@ -1499,37 +1402,7 @@ bool RenderBlock::updateLogicalWidthAndColumnWidth()
return oldWidth != logicalWidth() || oldColumnWidth != desiredColumnWidth() || hasBorderOrPaddingLogicalWidthChanged;
}
-void RenderBlock::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight)
-{
- ColumnInfo* colInfo = columnInfo();
- if (hasColumns()) {
- if (!pageLogicalHeight) {
- // We need to go ahead and set our explicit page height if one exists, so that we can
- // avoid doing two layout passes.
- updateLogicalHeight();
- LayoutUnit columnHeight = contentLogicalHeight();
- if (columnHeight > 0) {
- pageLogicalHeight = columnHeight;
- hasSpecifiedPageLogicalHeight = true;
- }
- setLogicalHeight(0);
- }
- if (colInfo->columnHeight() != pageLogicalHeight && everHadLayout()) {
- colInfo->setColumnHeight(pageLogicalHeight);
- pageLogicalHeightChanged = true;
- }
-
- if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
- colInfo->clearForcedBreaks();
-
- colInfo->setPaginationUnit(paginationUnit());
- } else if (isRenderFlowThread()) {
- pageLogicalHeight = 1; // This is just a hack to always make sure we have a page logical height.
- pageLogicalHeightChanged = toRenderFlowThread(this)->pageLogicalSizeChanged();
- }
-}
-
-void RenderBlock::layoutBlock(bool, LayoutUnit)
+void RenderBlock::layoutBlock(bool)
{
ASSERT_NOT_REACHED();
clearNeedsLayout();
@@ -1577,14 +1450,9 @@ void RenderBlock::computeOverflow(LayoutUnit oldClientAfterEdge, bool)
m_overflow->setLayoutClientAfterEdge(oldClientAfterEdge);
}
- // Add visual overflow from box-shadow and border-image-outset.
addVisualEffectOverflow();
- // Add visual overflow from theme.
addVisualOverflowFromTheme();
-
- if (isRenderNamedFlowThread())
- toRenderNamedFlowThread(this)->computeOversetStateForRegions(oldClientAfterEdge);
}
void RenderBlock::addOverflowFromBlockChildren()
@@ -1622,79 +1490,10 @@ void RenderBlock::addVisualOverflowFromTheme()
addVisualOverflow(inflatedRect);
}
-bool RenderBlock::expandsToEncloseOverhangingFloats() const
+bool RenderBlock::createsBlockFormattingContext() const
{
- return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || (parent() && parent()->isFlexibleBoxIncludingDeprecated())
- || hasColumns() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isRoot();
-}
-
-LayoutUnit RenderBlock::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart, RenderRegion* region)
-{
- LayoutUnit startPosition = startOffsetForContent(region);
-
- // Add in our start margin.
- LayoutUnit oldPosition = startPosition + childMarginStart;
- LayoutUnit newPosition = oldPosition;
-
- LayoutUnit blockOffset = logicalTopForChild(child);
- if (region)
- blockOffset = max(blockOffset, blockOffset + (region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage()));
-
- LayoutUnit startOff = startOffsetForLineInRegion(blockOffset, false, region, logicalHeightForChild(child));
-
- if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
- if (childMarginStart < 0)
- startOff += childMarginStart;
- newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
- } else if (startOff != startPosition)
- newPosition = startOff + childMarginStart;
-
- return newPosition - oldPosition;
-}
-
-void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode applyDelta)
-{
- LayoutUnit startPosition = borderStart() + paddingStart();
- if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- startPosition -= verticalScrollbarWidth();
- LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
-
- // Add in our start margin.
- LayoutUnit childMarginStart = marginStartForChild(child);
- LayoutUnit newPosition = startPosition + childMarginStart;
-
- // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need
- // to shift over as necessary to dodge any floats that might get in the way.
- if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock())
- newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
-
- setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
-}
-
-void RenderBlock::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
-{
- if (isHorizontalWritingMode()) {
- if (applyDelta == ApplyLayoutDelta)
- view()->addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
- child->setX(logicalLeft);
- } else {
- if (applyDelta == ApplyLayoutDelta)
- view()->addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
- child->setY(logicalLeft);
- }
-}
-
-void RenderBlock::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
-{
- if (isHorizontalWritingMode()) {
- if (applyDelta == ApplyLayoutDelta)
- view()->addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
- child->setY(logicalTop);
- } else {
- if (applyDelta == ApplyLayoutDelta)
- view()->addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
- child->setX(logicalTop);
- }
+ return isInlineBlockOrInlineTable() || isFloatingOrOutOfFlowPositioned() || hasOverflowClip() || isFlexItemIncludingDeprecated()
+ || style()->specifiesColumns() || isRenderFlowThread() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isDocumentElement() || style()->columnSpan();
}
void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
@@ -1718,8 +1517,8 @@ void RenderBlock::simplifiedNormalFlowLayout()
if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating())) {
o->layoutIfNeeded();
if (toRenderBox(o)->inlineBoxWrapper()) {
- RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
- lineBoxes.add(box);
+ RootInlineBox& box = toRenderBox(o)->inlineBoxWrapper()->root();
+ lineBoxes.add(&box);
}
} else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
o->clearNeedsLayout();
@@ -1742,45 +1541,49 @@ void RenderBlock::simplifiedNormalFlowLayout()
bool RenderBlock::simplifiedLayout()
{
- if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
+ // Check if we need to do a full layout.
+ if (normalChildNeedsLayout() || selfNeedsLayout())
return false;
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
-
- if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
+ // Check that we actually need to do a simplified layout.
+ if (!posChildNeedsLayout() && !(needsSimplifiedNormalFlowLayout() || needsPositionedMovementLayout()))
return false;
- // Lay out positioned descendants or objects that just need to recompute overflow.
- if (needsSimplifiedNormalFlowLayout())
- simplifiedNormalFlowLayout();
-
- // Make sure a forced break is applied after the content if we are a flow thread in a simplified layout.
- // This ensures the size information is correctly computed for the last auto-height region receiving content.
- if (isRenderFlowThread())
- toRenderFlowThread(this)->applyBreakAfterContent(clientLogicalBottom());
-
- // Lay out our positioned objects if our positioned child bit is set.
- // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
- // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the
- // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
- // are statically positioned and thus need to move with their absolute ancestors.
- bool canContainFixedPosObjects = canContainFixedPositionObjects();
- if (posChildNeedsLayout() || canContainFixedPosObjects)
- layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects);
-
- // Recompute our overflow information.
- // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
- // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
- // For now just always recompute overflow. This is no worse performance-wise than the old code that called rightmostPosition and
- // lowestPosition on every relayout so it's not a regression.
- // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
- // simplifiedLayout, we cache the value in m_overflow.
- LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
- computeOverflow(oldClientAfterEdge, true);
- statePusher.pop();
+ {
+ // LayoutState needs this deliberate scope to pop before repaint
+ LayoutState state(*this, locationOffset());
+
+ if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
+ return false;
+
+ FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
- updateLayerTransform();
+ // Lay out positioned descendants or objects that just need to recompute overflow.
+ if (needsSimplifiedNormalFlowLayout())
+ simplifiedNormalFlowLayout();
+
+ // Lay out our positioned objects if our positioned child bit is set.
+ // Also, if an absolute position element inside a relative positioned container moves, and the absolute element has a fixed position
+ // child, neither the fixed element nor its container learn of the movement since posChildNeedsLayout() is only marked as far as the
+ // relative positioned container. So if we can have fixed pos objects in our positioned objects list check if any of them
+ // are statically positioned and thus need to move with their absolute ancestors.
+ bool canContainFixedPosObjects = canContainFixedPositionObjects();
+ if (posChildNeedsLayout() || needsPositionedMovementLayout() || canContainFixedPosObjects)
+ layoutPositionedObjects(false, needsPositionedMovementLayout() ? ForcedLayoutAfterContainingBlockMoved : (!posChildNeedsLayout() && canContainFixedPosObjects ? LayoutOnlyFixedPositionedObjects : DefaultLayout));
+
+ // Recompute our overflow information.
+ // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
+ // updating our overflow if we either used to have overflow or if the new temporary object has overflow.
+ // For now just always recompute overflow. This is no worse performance-wise than the old code that called rightmostPosition and
+ // lowestPosition on every relayout so it's not a regression.
+ // computeOverflow expects the bottom edge before we clamp our height. Since this information isn't available during
+ // simplifiedLayout, we cache the value in m_overflow.
+ LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
+ computeOverflow(oldClientAfterEdge, true);
+ }
+
+ updateLayerTransformAfterLayout();
updateScrollInfoAfterLayout();
@@ -1806,9 +1609,10 @@ void RenderBlock::markFixedPositionObjectForLayoutIfNeeded(RenderObject* child,
RenderBox* box = toRenderBox(child);
if (hasStaticInlinePosition) {
- LayoutUnit oldLeft = box->logicalLeft();
- box->updateLogicalWidth();
- if (box->logicalLeft() != oldLeft)
+ LogicalExtentComputedValues computedValues;
+ box->computeLogicalWidth(computedValues);
+ LayoutUnit newLeft = computedValues.m_position;
+ if (newLeft != box->logicalLeft())
layoutScope.setChildNeedsLayout(child);
} else if (hasStaticBlockPosition) {
LayoutUnit oldTop = box->logicalTop();
@@ -1833,7 +1637,7 @@ LayoutUnit RenderBlock::marginIntrinsicLogicalWidthForChild(RenderBox* child) co
return margin;
}
-void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly)
+void RenderBlock::layoutPositionedObjects(bool relayoutChildren, PositionedLayoutBehavior info)
{
TrackedRendererListHashSet* positionedDescendants = positionedObjects();
if (!positionedDescendants)
@@ -1847,12 +1651,15 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPosit
for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
r = *it;
- SubtreeLayoutScope layoutScope(r);
+ // FIXME: this should only be set from clearNeedsLayout crbug.com/361250
+ r->setLayoutDidGetCalled(true);
+
+ SubtreeLayoutScope layoutScope(*r);
// A fixed position element with an absolute positioned ancestor has no way of knowing if the latter has changed position. So
// if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e.
// it has static position.
markFixedPositionObjectForLayoutIfNeeded(r, layoutScope);
- if (fixedPositionObjectsOnly) {
+ if (info == LayoutOnlyFixedPositionedObjects) {
r->layoutIfNeeded();
continue;
}
@@ -1871,11 +1678,6 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPosit
if (!r->needsLayout())
r->markForPaginationRelayoutIfNeeded(layoutScope);
- // We don't have to do a full layout. We just have to update our position. Try that first. If we have shrink-to-fit width
- // and we hit the available width constraint, the layoutIfNeeded() will catch it and do a full layout.
- if (r->needsPositionedMovementLayoutOnly() && r->tryLayoutDoingPositionedMovementOnly())
- r->clearNeedsLayout();
-
// If we are paginated or in a line grid, go ahead and compute a vertical position for our object now.
// If it's wrong we'll lay out again.
LayoutUnit oldLogicalTop = 0;
@@ -1888,6 +1690,11 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPosit
oldLogicalTop = logicalTopForChild(r);
}
+ // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout() here instead of a full layout. Need
+ // to investigate why it does not trigger the correct invalidations in that case. crbug.com/350756
+ if (info == ForcedLayoutAfterContainingBlockMoved)
+ r->setNeedsLayoutAndFullPaintInvalidation();
+
r->layoutIfNeeded();
// Lay out again if our estimate was wrong.
@@ -1896,7 +1703,7 @@ void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPosit
}
if (hasColumns())
- view()->layoutState()->m_columnInfo = columnInfo(); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
+ view()->layoutState()->setColumnInfo(columnInfo()); // FIXME: Kind of gross. We just put this back into the layout state so that pop() will work.
}
void RenderBlock::markPositionedObjectsForLayout()
@@ -1918,7 +1725,7 @@ void RenderBlock::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutSc
if (needsLayout())
return;
- if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()))
+ if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(*this, logicalTop()) != pageLogicalOffset()))
layoutScope.setChildNeedsLayout(this);
}
@@ -1930,13 +1737,13 @@ void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
PaintPhase phase = paintInfo.phase;
+ LayoutRect overflowBox;
// Check if we need to do anything at all.
- // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
+ // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
// paints the root's background.
- if (!isRoot()) {
- LayoutRect overflowBox = overflowRectForPaintRejection();
+ if (!isDocumentElement()) {
+ overflowBox = overflowRectForPaintRejection();
flipForWritingMode(overflowBox);
- overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
overflowBox.moveBy(adjustedPaintOffset);
if (!overflowBox.intersects(paintInfo.rect))
return;
@@ -1949,7 +1756,16 @@ void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
contentsClipBehavior = SkipContentsClipIfPossible;
bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, contentsClipBehavior);
- paintObject(paintInfo, adjustedPaintOffset);
+ {
+ GraphicsContextCullSaver cullSaver(*paintInfo.context);
+ // Cull if we have more than one child and we didn't already clip.
+ bool shouldCull = document().settings()->containerCullingEnabled() && !pushedClip && !isDocumentElement()
+ && firstChild() && lastChild() && firstChild() != lastChild();
+ if (shouldCull)
+ cullSaver.cull(overflowBox);
+
+ paintObject(paintInfo, adjustedPaintOffset);
+ }
if (pushedClip)
popContentsClip(paintInfo, phase, adjustedPaintOffset);
@@ -1980,7 +1796,7 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain
bool antialias = shouldAntialiasLines(paintInfo.context);
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
- bool leftToRight = style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed();
+ bool leftToRight = style()->isLeftToRightDirection();
LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentLogicalWidth();
LayoutUnit ruleAdd = logicalLeftOffsetForContent();
LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogicalWidth();
@@ -2012,13 +1828,13 @@ void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& pain
ruleLogicalLeft = currLogicalLeftOffset;
}
} else {
- bool topToBottom = !style()->isFlippedBlocksWritingMode() ^ colInfo->progressionIsReversed();
+ bool topToBottom = !style()->isFlippedBlocksWritingMode();
LayoutUnit ruleLeft = isHorizontalWritingMode()
? borderLeft() + paddingLeft()
- : colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter());
+ : colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore();
LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
LayoutUnit ruleTop = isHorizontalWritingMode()
- ? colGap / 2 - colGap - ruleThickness / 2 + (!colInfo->progressionIsReversed() ? borderBefore() + paddingBefore() : borderAfter() + paddingAfter())
+ ? colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore()
: borderStart() + paddingStart();
LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
@@ -2072,7 +1888,7 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& p
}
colRect.moveBy(paintOffset);
PaintInfo info(paintInfo);
- info.rect.intersect(pixelSnappedIntRect(colRect));
+ info.rect.intersect(enclosingIntRect(colRect));
if (!info.rect.isEmpty()) {
GraphicsContextStateSaver stateSaver(*context);
@@ -2088,7 +1904,7 @@ void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& p
// like overflow:hidden.
// FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
// are clipped according to the 'overflow' property.
- context->clip(pixelSnappedIntRect(clipRect));
+ context->clip(enclosingIntRect(clipRect));
// Adjust our x and y when painting.
LayoutPoint adjustedPaintOffset = paintOffset + offset;
@@ -2173,31 +1989,42 @@ void RenderBlock::paintAsInlineBlock(RenderObject* renderer, PaintInfo& paintInf
}
}
-bool RenderBlock::hasCaret(CaretType type) const
+static inline bool caretBrowsingEnabled(const Frame* frame)
{
- // Paint the caret if the FrameSelection says so or if caret browsing is enabled
- bool caretBrowsing = frame()->settings() && frame()->settings()->caretBrowsingEnabled();
- RenderObject* caretPainter;
- bool isContentEditable;
- if (type == CursorCaret) {
- caretPainter = frame()->selection().caretRenderer();
- isContentEditable = frame()->selection().rendererIsEditable();
- } else {
- caretPainter = frame()->page()->dragCaretController().caretRenderer();
- isContentEditable = frame()->page()->dragCaretController().isContentEditable();
- }
- return caretPainter == this && (isContentEditable || caretBrowsing);
+ Settings* settings = frame->settings();
+ return settings && settings->caretBrowsingEnabled();
}
-void RenderBlock::paintCaret(PaintInfo& paintInfo, const LayoutPoint& paintOffset, CaretType type)
+static inline bool hasCursorCaret(const FrameSelection& selection, const RenderBlock* block, bool caretBrowsing)
{
- if (!hasCaret(type))
- return;
+ return selection.caretRenderer() == block && (selection.rendererIsEditable() || caretBrowsing);
+}
- if (type == CursorCaret)
- frame()->selection().paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
- else
- frame()->page()->dragCaretController().paintDragCaret(frame(), paintInfo.context, paintOffset, paintInfo.rect);
+static inline bool hasDragCaret(const DragCaretController& dragCaretController, const RenderBlock* block, bool caretBrowsing)
+{
+ return dragCaretController.caretRenderer() == block && (dragCaretController.isContentEditable() || caretBrowsing);
+}
+
+bool RenderBlock::hasCaret() const
+{
+ bool caretBrowsing = caretBrowsingEnabled(frame());
+ return hasCursorCaret(frame()->selection(), this, caretBrowsing)
+ || hasDragCaret(frame()->page()->dragCaretController(), this, caretBrowsing);
+}
+
+void RenderBlock::paintCarets(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
+ bool caretBrowsing = caretBrowsingEnabled(frame());
+
+ FrameSelection& selection = frame()->selection();
+ if (hasCursorCaret(selection, this, caretBrowsing)) {
+ selection.paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
+ }
+
+ DragCaretController& dragCaretController = frame()->page()->dragCaretController();
+ if (hasDragCaret(dragCaretController, this, caretBrowsing)) {
+ dragCaretController.paintDragCaret(frame(), paintInfo.context, paintOffset, paintInfo.rect);
+ }
}
void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -2287,8 +2114,7 @@ void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffs
// If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
// then paint the caret.
if (paintPhase == PaintPhaseForeground) {
- paintCaret(paintInfo, paintOffset, CursorCaret);
- paintCaret(paintInfo, paintOffset, DragCaret);
+ paintCarets(paintInfo, paintOffset);
}
}
@@ -2383,11 +2209,11 @@ bool RenderBlock::isSelectionRoot() const
if (isTable())
return false;
- if (isBody() || isRoot() || hasOverflowClip()
+ if (isBody() || isDocumentElement() || hasOverflowClip()
|| isPositioned() || isFloating()
|| isTableCell() || isInlineBlockOrInlineTable()
|| hasTransform() || hasReflection() || hasMask() || isWritingModeRoot()
- || isRenderFlowThread())
+ || isRenderFlowThread() || isFlexItemIncludingDeprecated())
return true;
if (view() && view()->selectionStart()) {
@@ -2430,17 +2256,16 @@ void RenderBlock::paintSelection(PaintInfo& paintInfo, const LayoutPoint& paintO
LayoutRect gapRectsBounds = selectionGaps(this, paintOffset, LayoutSize(), lastTop, lastLeft, lastRight, &paintInfo);
if (!gapRectsBounds.isEmpty()) {
- if (RenderLayer* layer = enclosingLayer()) {
- gapRectsBounds.moveBy(-paintOffset);
- if (!hasLayer()) {
- LayoutRect localBounds(gapRectsBounds);
- flipForWritingMode(localBounds);
- gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
- if (layer->renderer()->hasOverflowClip())
- gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
- }
- layer->addBlockSelectionGapsBounds(gapRectsBounds);
+ RenderLayer* layer = enclosingLayer();
+ gapRectsBounds.moveBy(-paintOffset);
+ if (!hasLayer()) {
+ LayoutRect localBounds(gapRectsBounds);
+ flipForWritingMode(localBounds);
+ gapRectsBounds = localToContainerQuad(FloatRect(localBounds), layer->renderer()).enclosingBoundingBox();
+ if (layer->renderer()->hasOverflowClip())
+ gapRectsBounds.move(layer->renderBox()->scrolledContentOffset());
}
+ layer->addBlockSelectionGapsBounds(gapRectsBounds);
}
}
}
@@ -2490,7 +2315,7 @@ GapRects RenderBlock::selectionGaps(RenderBlock* rootBlock, const LayoutPoint& r
rootBlock->flipForWritingMode(flippedBlockRect);
flippedBlockRect.moveBy(rootBlockPhysicalPosition);
clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects());
- if (isBody() || isRoot()) // The <body> must make sure to examine its containingBlock's positioned objects.
+ if (isBody() || isDocumentElement()) // The <body> must make sure to examine its containingBlock's positioned objects.
for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock())
clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes.
clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock);
@@ -2650,38 +2475,18 @@ void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool&
LayoutUnit RenderBlock::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
{
- LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false);
- if (logicalLeft == logicalLeftOffsetForContent()) {
- if (rootBlock != this)
- // The border can potentially be further extended by our containingBlock().
- return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
- return logicalLeft;
- } else {
- RenderBlock* cb = this;
- while (cb != rootBlock) {
- logicalLeft += cb->logicalLeft();
- cb = cb->containingBlock();
- }
- }
- return logicalLeft;
+ // The border can potentially be further extended by our containingBlock().
+ if (rootBlock != this)
+ return containingBlock()->logicalLeftSelectionOffset(rootBlock, position + logicalTop());
+ return logicalLeftOffsetForContent();
}
LayoutUnit RenderBlock::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
{
- LayoutUnit logicalRight = logicalRightOffsetForLine(position, false);
- if (logicalRight == logicalRightOffsetForContent()) {
- if (rootBlock != this)
- // The border can potentially be further extended by our containingBlock().
- return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
- return logicalRight;
- } else {
- RenderBlock* cb = this;
- while (cb != rootBlock) {
- logicalRight += cb->logicalLeft();
- cb = cb->containingBlock();
- }
- }
- return logicalRight;
+ // The border can potentially be further extended by our containingBlock().
+ if (rootBlock != this)
+ return containingBlock()->logicalRightSelectionOffset(rootBlock, position + logicalTop());
+ return logicalRightOffsetForContent();
}
RenderBlock* RenderBlock::blockBeforeWithinSelectionRoot(LayoutSize& offset) const
@@ -2900,7 +2705,7 @@ void RenderBlock::removePercentHeightDescendantIfNeeded(RenderBox* descendant)
void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent)
{
ASSERT(gPercentHeightContainerMap);
- for (RenderObject* curr = parent->firstChild(); curr; curr = curr->nextInPreOrder(parent)) {
+ for (RenderObject* curr = parent->slowFirstChild(); curr; curr = curr->nextInPreOrder(parent)) {
if (!curr->isBox())
continue;
@@ -2915,107 +2720,9 @@ void RenderBlock::clearPercentHeightDescendantsFrom(RenderBox* parent)
LayoutUnit RenderBlock::textIndentOffset() const
{
LayoutUnit cw = 0;
- RenderView* renderView = 0;
if (style()->textIndent().isPercent())
cw = containingBlock()->availableLogicalWidth();
- else if (style()->textIndent().isViewportPercentage())
- renderView = view();
- return minimumValueForLength(style()->textIndent(), cw, renderView);
-}
-
-LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region) const
-{
- LayoutUnit logicalLeftOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
- if (!region)
- return logicalLeftOffset;
- LayoutRect boxRect = borderBoxRectInRegion(region);
- return logicalLeftOffset + (isHorizontalWritingMode() ? boxRect.x() : boxRect.y());
-}
-
-LayoutUnit RenderBlock::logicalRightOffsetForContent(RenderRegion* region) const
-{
- LayoutUnit logicalRightOffset = style()->isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
- logicalRightOffset += availableLogicalWidth();
- if (!region)
- return logicalRightOffset;
- LayoutRect boxRect = borderBoxRectInRegion(region);
- return logicalRightOffset - (logicalWidth() - (isHorizontalWritingMode() ? boxRect.maxX() : boxRect.maxY()));
-}
-
-LayoutUnit RenderBlock::adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
-{
- LayoutUnit left = offsetFromFloats;
-
- if (applyTextIndent && style()->isLeftToRightDirection())
- left += textIndentOffset();
-
- if (style()->lineAlign() == LineAlignNone)
- return left;
-
- // Push in our left offset so that it is aligned with the character grid.
- LayoutState* layoutState = view()->layoutState();
- if (!layoutState)
- return left;
-
- RenderBlock* lineGrid = layoutState->lineGrid();
- if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode())
- return left;
-
- // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
- float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth();
- if (!maxCharWidth)
- return left;
-
- LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
- LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
-
- // Push in to the nearest character width.
- // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
- // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
- // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
- // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
- // (https://bugs.webkit.org/show_bug.cgi?id=79944)
- float remainder = fmodf(maxCharWidth - fmodf(left + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
- left += remainder;
- return left;
-}
-
-LayoutUnit RenderBlock::adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
-{
- LayoutUnit right = offsetFromFloats;
-
- if (applyTextIndent && !style()->isLeftToRightDirection())
- right -= textIndentOffset();
-
- if (style()->lineAlign() == LineAlignNone)
- return right;
-
- // Push in our right offset so that it is aligned with the character grid.
- LayoutState* layoutState = view()->layoutState();
- if (!layoutState)
- return right;
-
- RenderBlock* lineGrid = layoutState->lineGrid();
- if (!lineGrid || lineGrid->style()->writingMode() != style()->writingMode())
- return right;
-
- // FIXME: Should letter-spacing apply? This is complicated since it doesn't apply at the edge?
- float maxCharWidth = lineGrid->style()->font().primaryFont()->maxCharWidth();
- if (!maxCharWidth)
- return right;
-
- LayoutUnit lineGridOffset = lineGrid->isHorizontalWritingMode() ? layoutState->lineGridOffset().width(): layoutState->lineGridOffset().height();
- LayoutUnit layoutOffset = lineGrid->isHorizontalWritingMode() ? layoutState->layoutOffset().width() : layoutState->layoutOffset().height();
-
- // Push in to the nearest character width.
- // FIXME: This is wrong for RTL (https://bugs.webkit.org/show_bug.cgi?id=79945).
- // FIXME: This doesn't work with columns or regions (https://bugs.webkit.org/show_bug.cgi?id=79942).
- // FIXME: This doesn't work when the inline position of the object isn't set ahead of time.
- // FIXME: Dynamic changes to the font or to the inline position need to result in a deep relayout.
- // (https://bugs.webkit.org/show_bug.cgi?id=79944)
- float remainder = fmodf(fmodf(right + layoutOffset - lineGridOffset, maxCharWidth), maxCharWidth);
- right -= LayoutUnit::fromFloatCeil(remainder);
- return right;
+ return minimumValueForLength(style()->textIndent(), cw);
}
void RenderBlock::markLinesDirtyInBlockRange(LayoutUnit logicalTop, LayoutUnit logicalBottom, RootInlineBox* highest)
@@ -3042,22 +2749,6 @@ bool RenderBlock::avoidsFloats() const
return RenderBox::avoidsFloats() || !style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth();
}
-void RenderBlock::markShapeInsideDescendantsForLayout()
-{
- if (!everHadLayout())
- return;
- if (childrenInline()) {
- setNeedsLayout();
- return;
- }
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (!child->isRenderBlock())
- continue;
- RenderBlock* childBlock = toRenderBlock(child);
- childBlock->markShapeInsideDescendantsForLayout();
- }
-}
-
bool RenderBlock::isPointInOverflowControl(HitTestResult& result, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset)
{
if (!scrollsOverflow())
@@ -3081,24 +2772,53 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
if (!isRenderView()) {
// Check if we need to do anything at all.
- LayoutRect overflowBox = visualOverflowRect();
+ // If we have clipping, then we can't have any spillout.
+ LayoutRect overflowBox = hasOverflowClip() ? borderBoxRect() : visualOverflowRect();
flipForWritingMode(overflowBox);
overflowBox.moveBy(adjustedLocation);
if (!locationInContainer.intersects(overflowBox))
return false;
}
- if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, locationInContainer.point(), adjustedLocation)) {
+ if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground)
+ && visibleToHitTestRequest(request)
+ && isPointInOverflowControl(result, locationInContainer.point(), adjustedLocation)) {
updateHitTestResult(result, locationInContainer.point() - localOffset);
// FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
if (!result.addNodeToRectBasedTestResult(nodeForHitTest(), request, locationInContainer))
return true;
}
+ if (style()->clipPath()) {
+ switch (style()->clipPath()->type()) {
+ case ClipPathOperation::SHAPE: {
+ ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()->clipPath());
+ // FIXME: handle marginBox etc.
+ if (!clipPath->path(borderBoxRect()).contains(locationInContainer.point() - localOffset, clipPath->windRule()))
+ return false;
+ break;
+ }
+ case ClipPathOperation::REFERENCE:
+ // FIXME: handle REFERENCE
+ break;
+ }
+ }
+
// If we have clipping, then we can't have any spillout.
bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
bool useClip = (hasControlClip() || useOverflowClip);
- bool checkChildren = !useClip || (hasControlClip() ? locationInContainer.intersects(controlClipRect(adjustedLocation)) : locationInContainer.intersects(overflowClipRect(adjustedLocation, locationInContainer.region(), IncludeOverlayScrollbarSize)));
+ bool checkChildren = !useClip;
+ if (!checkChildren) {
+ if (hasControlClip()) {
+ checkChildren = locationInContainer.intersects(controlClipRect(adjustedLocation));
+ } else {
+ LayoutRect clipRect = overflowClipRect(adjustedLocation, IncludeOverlayScrollbarSize);
+ if (style()->hasBorderRadius())
+ checkChildren = locationInContainer.intersects(style()->getRoundedBorderFor(clipRect));
+ else
+ checkChildren = locationInContainer.intersects(clipRect);
+ }
+ }
if (checkChildren) {
// Hit test descendants first.
LayoutSize scrolledOffset(localOffset);
@@ -3120,10 +2840,10 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
// Check if the point is outside radii.
- if (!isRenderView() && style()->hasBorderRadius()) {
+ if (style()->hasBorderRadius()) {
LayoutRect borderRect = borderBoxRect();
borderRect.moveBy(adjustedLocation);
- RoundedRect border = style()->getRoundedBorderFor(borderRect, view());
+ RoundedRect border = style()->getRoundedBorderFor(borderRect);
if (!locationInContainer.intersects(border))
return false;
}
@@ -3239,9 +2959,6 @@ void RenderBlock::adjustForColumnRect(LayoutSize& offset, const LayoutPoint& loc
bool RenderBlock::hitTestContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
{
- if (isRenderRegion())
- return toRenderRegion(this)->hitTestFlowThreadContents(request, result, locationInContainer, accumulatedOffset, hitTestAction);
-
if (childrenInline() && !isTable()) {
// We have to hit-test our line boxes.
if (m_lineBoxes.hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction))
@@ -3266,14 +2983,14 @@ Position RenderBlock::positionForBox(InlineBox *box, bool start) const
if (!box)
return Position();
- if (!box->renderer()->nonPseudoNode())
+ if (!box->renderer().nonPseudoNode())
return createLegacyEditingPosition(nonPseudoNode(), start ? caretMinOffset() : caretMaxOffset());
if (!box->isInlineTextBox())
- return createLegacyEditingPosition(box->renderer()->nonPseudoNode(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
+ return createLegacyEditingPosition(box->renderer().nonPseudoNode(), start ? box->renderer().caretMinOffset() : box->renderer().caretMaxOffset());
InlineTextBox* textBox = toInlineTextBox(box);
- return createLegacyEditingPosition(box->renderer()->nonPseudoNode(), start ? textBox->start() : textBox->start() + textBox->len());
+ return createLegacyEditingPosition(box->renderer().nonPseudoNode(), start ? textBox->start() : textBox->start() + textBox->len());
}
static inline bool isEditingBoundary(RenderObject* ancestor, RenderObject* child)
@@ -3385,12 +3102,12 @@ PositionWithAffinity RenderBlock::positionForPointWithInlineChildren(const Layou
}
// pass the box a top position that is inside it
- LayoutPoint point(pointInLogicalContents.x(), closestBox->root()->blockDirectionPointInLine());
+ LayoutPoint point(pointInLogicalContents.x(), closestBox->root().blockDirectionPointInLine());
if (!isHorizontalWritingMode())
point = point.transposedPoint();
- if (closestBox->renderer()->isReplaced())
- return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
- return closestBox->renderer()->positionForPoint(point);
+ if (closestBox->renderer().isReplaced())
+ return positionForPointRespectingEditingBoundaries(this, &toRenderBox(closestBox->renderer()), point);
+ return closestBox->renderer().positionForPoint(point);
}
if (lastRootBoxWithChildren) {
@@ -3505,7 +3222,7 @@ void RenderBlock::calcColumnWidth()
LayoutUnit desiredColumnWidth = contentLogicalWidth();
// For now, we don't support multi-column layouts when printing, since we have to do a lot of work for proper pagination.
- if (document().paginated() || (style()->hasAutoColumnCount() && style()->hasAutoColumnWidth()) || !style()->hasInlineColumnAxis()) {
+ if (document().paginated() || !style()->specifiesColumns()) {
setDesiredColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
return;
}
@@ -3530,12 +3247,12 @@ void RenderBlock::calcColumnWidth()
bool RenderBlock::requiresColumns(int desiredColumnCount) const
{
- // If overflow-y is set to paged-x or paged-y on the body or html element, we'll handle the paginating
- // in the RenderView instead.
- bool isPaginated = (style()->overflowY() == OPAGEDX || style()->overflowY() == OPAGEDY) && !(isRoot() || isBody());
+ // Paged overflow is treated as multicol here, unless this element was the one that got its
+ // overflow propagated to the viewport.
+ bool isPaginated = style()->isOverflowPaged() && node() != document().viewportDefiningElement();
return firstChild()
- && (desiredColumnCount != 1 || !style()->hasAutoColumnWidth() || !style()->hasInlineColumnAxis() || isPaginated)
+ && (desiredColumnCount != 1 || !style()->hasAutoColumnWidth() || isPaginated)
&& !firstChild()->isAnonymousColumnsBlock()
&& !firstChild()->isAnonymousColumnSpanBlock();
}
@@ -3559,37 +3276,15 @@ void RenderBlock::setDesiredColumnCountAndWidth(int count, LayoutUnit width)
gColumnInfoMap->add(this, adoptPtr(info));
setHasColumns(true);
}
- info->setDesiredColumnCount(count);
info->setDesiredColumnWidth(width);
- info->setProgressionAxis(style()->hasInlineColumnAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis);
- info->setProgressionIsReversed(style()->columnProgression() == ReverseColumnProgression);
- }
-}
-
-void RenderBlock::updateColumnInfoFromStyle(RenderStyle* style)
-{
- if (!hasColumns())
- return;
-
- ColumnInfo* info = gColumnInfoMap->get(this);
-
- bool needsLayout = false;
- ColumnInfo::Axis oldAxis = info->progressionAxis();
- ColumnInfo::Axis newAxis = style->hasInlineColumnAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis;
- if (oldAxis != newAxis) {
- info->setProgressionAxis(newAxis);
- needsLayout = true;
- }
-
- bool oldProgressionIsReversed = info->progressionIsReversed();
- bool newProgressionIsReversed = style->columnProgression() == ReverseColumnProgression;
- if (oldProgressionIsReversed != newProgressionIsReversed) {
- info->setProgressionIsReversed(newProgressionIsReversed);
- needsLayout = true;
+ if (style()->isOverflowPaged()) {
+ info->setDesiredColumnCount(1);
+ info->setProgressionAxis(style()->hasInlinePaginationAxis() ? ColumnInfo::InlineAxis : ColumnInfo::BlockAxis);
+ } else {
+ info->setDesiredColumnCount(count);
+ info->setProgressionAxis(ColumnInfo::InlineAxis);
+ }
}
-
- if (needsLayout)
- setNeedsLayoutAndPrefWidthsRecalc();
}
LayoutUnit RenderBlock::desiredColumnWidth() const
@@ -3624,15 +3319,12 @@ LayoutRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
LayoutUnit colLogicalLeft = logicalLeftOffsetForContent();
LayoutUnit colGap = columnGap();
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
- if (style()->isLeftToRightDirection() ^ colInfo->progressionIsReversed())
+ if (style()->isLeftToRightDirection())
colLogicalLeft += index * (colLogicalWidth + colGap);
else
colLogicalLeft += contentLogicalWidth() - colLogicalWidth - index * (colLogicalWidth + colGap);
} else {
- if (!colInfo->progressionIsReversed())
- colLogicalTop += index * (colLogicalHeight + colGap);
- else
- colLogicalTop += contentLogicalHeight() - colLogicalHeight - index * (colLogicalHeight + colGap);
+ colLogicalTop += index * (colLogicalHeight + colGap);
}
if (isHorizontalWritingMode())
@@ -3640,17 +3332,6 @@ LayoutRect RenderBlock::columnRectAt(ColumnInfo* colInfo, unsigned index) const
return LayoutRect(colLogicalTop, colLogicalLeft, colLogicalHeight, colLogicalWidth);
}
-bool RenderBlock::relayoutToAvoidWidows(LayoutStateMaintainer& statePusher)
-{
- if (!shouldBreakAtLineToAvoidWidow())
- return false;
-
- statePusher.pop();
- setEverHadLayout(true);
- layoutBlock(false);
- return true;
-}
-
void RenderBlock::adjustPointToColumnContents(LayoutPoint& point) const
{
// Just bail if we have no columns.
@@ -3826,10 +3507,10 @@ void RenderBlock::adjustStartEdgeForWritingModeIncludingColumns(LayoutRect& rect
rect.setX(expandedLogicalHeight - rect.maxX());
}
-void RenderBlock::adjustForColumns(LayoutSize& offset, const LayoutPoint& point) const
+LayoutSize RenderBlock::columnOffset(const LayoutPoint& point) const
{
if (!hasColumns())
- return;
+ return LayoutSize();
ColumnInfo* colInfo = columnInfo();
@@ -3850,30 +3531,29 @@ void RenderBlock::adjustForColumns(LayoutSize& offset, const LayoutPoint& point)
if (isHorizontalWritingMode()) {
if (point.y() >= sliceRect.y() && point.y() < sliceRect.maxY()) {
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
- offset.expand(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
- else
- offset.expand(0, columnRectAt(colInfo, i).y() - logicalOffset - borderBefore() - paddingBefore());
- return;
+ return LayoutSize(columnRectAt(colInfo, i).x() - logicalLeft, -logicalOffset);
+ return LayoutSize(0, columnRectAt(colInfo, i).y() - logicalOffset - borderBefore() - paddingBefore());
}
} else {
if (point.x() >= sliceRect.x() && point.x() < sliceRect.maxX()) {
if (colInfo->progressionAxis() == ColumnInfo::InlineAxis)
- offset.expand(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
- else
- offset.expand(columnRectAt(colInfo, i).x() - logicalOffset - borderBefore() - paddingBefore(), 0);
- return;
+ return LayoutSize(-logicalOffset, columnRectAt(colInfo, i).y() - logicalLeft);
+ return LayoutSize(columnRectAt(colInfo, i).x() - logicalOffset - borderBefore() - paddingBefore(), 0);
}
}
}
+
+ return LayoutSize();
}
void RenderBlock::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
if (childrenInline()) {
// FIXME: Remove this const_cast.
- const_cast<RenderBlock*>(this)->computeInlinePreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
- } else
+ toRenderBlockFlow(const_cast<RenderBlock*>(this))->computeInlinePreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
+ } else {
computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
+ }
maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth);
@@ -3937,9 +3617,6 @@ void RenderBlock::computePreferredLogicalWidths()
void RenderBlock::adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
- // FIXME: make this method virtual and move the code to RenderMultiColumnBlock once the old
- // multicol code is gone.
-
if (!style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth()) {
// The min/max intrinsic widths calculated really tell how much space elements need when
// laid out inside the columns. In order to eventually end up with the desired column width,
@@ -3962,429 +3639,6 @@ void RenderBlock::adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalW
}
}
-struct InlineMinMaxIterator {
-/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
- inline min/max width calculations. Note the following about the way it walks:
- (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
- (2) We do not drill into the children of floats or replaced elements, since you can't break
- in the middle of such an element.
- (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
- distinct borders/margin/padding that contribute to the min/max width.
-*/
- RenderObject* parent;
- RenderObject* current;
- bool endOfInline;
-
- InlineMinMaxIterator(RenderObject* p, bool end = false)
- :parent(p), current(p), endOfInline(end) {}
-
- RenderObject* next();
-};
-
-RenderObject* InlineMinMaxIterator::next()
-{
- RenderObject* result = 0;
- bool oldEndOfInline = endOfInline;
- endOfInline = false;
- while (current || current == parent) {
- if (!oldEndOfInline &&
- (current == parent ||
- (!current->isFloating() && !current->isReplaced() && !current->isOutOfFlowPositioned())))
- result = current->firstChild();
- if (!result) {
- // We hit the end of our inline. (It was empty, e.g., <span></span>.)
- if (!oldEndOfInline && current->isRenderInline()) {
- result = current;
- endOfInline = true;
- break;
- }
-
- while (current && current != parent) {
- result = current->nextSibling();
- if (result) break;
- current = current->parent();
- if (current && current != parent && current->isRenderInline()) {
- result = current;
- endOfInline = true;
- break;
- }
- }
- }
-
- if (!result)
- break;
-
- if (!result->isOutOfFlowPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
- break;
-
- current = result;
- result = 0;
- }
-
- // Update our position.
- current = result;
- return current;
-}
-
-static LayoutUnit getBPMWidth(LayoutUnit childValue, Length cssUnit)
-{
- if (cssUnit.type() != Auto)
- return (cssUnit.isFixed() ? static_cast<LayoutUnit>(cssUnit.value()) : childValue);
- return 0;
-}
-
-static LayoutUnit getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
-{
- RenderStyle* childStyle = child->style();
- if (endOfInline)
- return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) +
- getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) +
- child->borderEnd();
- return getBPMWidth(child->marginStart(), childStyle->marginStart()) +
- getBPMWidth(child->paddingStart(), childStyle->paddingStart()) +
- child->borderStart();
-}
-
-static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
- RenderObject* trailingSpaceChild)
-{
- if (trailingSpaceChild && trailingSpaceChild->isText()) {
- // Collapse away the trailing space at the end of a block.
- RenderText* t = toRenderText(trailingSpaceChild);
- const UChar space = ' ';
- const Font& font = t->style()->font(); // FIXME: This ignores first-line.
- float spaceWidth = font.width(RenderBlockFlow::constructTextRun(t, font, &space, 1, t->style()));
- inlineMax -= spaceWidth + font.wordSpacing();
- if (inlineMin > inlineMax)
- inlineMin = inlineMax;
- }
-}
-
-static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
-{
- LayoutUnit snappedResult = LayoutUnit::fromFloatCeil(result);
- preferredWidth = max(snappedResult, preferredWidth);
-}
-
-// When converting between floating point and LayoutUnits we risk losing precision
-// with each conversion. When this occurs while accumulating our preferred widths,
-// we can wind up with a line width that's larger than our maxPreferredWidth due to
-// pure float accumulation.
-static inline LayoutUnit adjustFloatForSubPixelLayout(float value)
-{
- return LayoutUnit::fromFloatCeil(value);
-}
-
-
-void RenderBlock::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
-{
- float inlineMax = 0;
- float inlineMin = 0;
-
- RenderStyle* styleToUse = style();
- RenderBlock* containingBlock = this->containingBlock();
- LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
-
- // If we are at the start of a line, we want to ignore all white-space.
- // Also strip spaces if we previously had text that ended in a trailing space.
- bool stripFrontSpaces = true;
- RenderObject* trailingSpaceChild = 0;
-
- // Firefox and Opera will allow a table cell to grow to fit an image inside it under
- // very specific cirucumstances (in order to match common WinIE renderings).
- // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
- bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !styleToUse->logicalWidth().isIntrinsicOrAuto();
-
- bool autoWrap, oldAutoWrap;
- autoWrap = oldAutoWrap = styleToUse->autoWrap();
-
- InlineMinMaxIterator childIterator(this);
-
- // Only gets added to the max preffered width once.
- bool addedTextIndent = false;
- // Signals the text indent was more negative than the min preferred width
- bool hasRemainingNegativeTextIndent = false;
-
- LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw, view());
- RenderObject* prevFloat = 0;
- bool isPrevChildInlineFlow = false;
- bool shouldBreakLineAfterText = false;
- while (RenderObject* child = childIterator.next()) {
- autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
- child->style()->autoWrap();
-
- if (!child->isBR()) {
- // Step One: determine whether or not we need to go ahead and
- // terminate our current line. Each discrete chunk can become
- // the new min-width, if it is the widest chunk seen so far, and
- // it can also become the max-width.
-
- // Children fall into three categories:
- // (1) An inline flow object. These objects always have a min/max of 0,
- // and are included in the iteration solely so that their margins can
- // be added in.
- //
- // (2) An inline non-text non-flow object, e.g., an inline replaced element.
- // These objects can always be on a line by themselves, so in this situation
- // we need to go ahead and break the current line, and then add in our own
- // margins and min/max width on its own line, and then terminate the line.
- //
- // (3) A text object. Text runs can have breakable characters at the start,
- // the middle or the end. They may also lose whitespace off the front if
- // we're already ignoring whitespace. In order to compute accurate min-width
- // information, we need three pieces of information.
- // (a) the min-width of the first non-breakable run. Should be 0 if the text string
- // starts with whitespace.
- // (b) the min-width of the last non-breakable run. Should be 0 if the text string
- // ends with whitespace.
- // (c) the min/max width of the string (trimmed for whitespace).
- //
- // If the text string starts with whitespace, then we need to go ahead and
- // terminate our current line (unless we're already in a whitespace stripping
- // mode.
- //
- // If the text string has a breakable character in the middle, but didn't start
- // with whitespace, then we add the width of the first non-breakable run and
- // then end the current line. We then need to use the intermediate min/max width
- // values (if any of them are larger than our current min/max). We then look at
- // the width of the last non-breakable run and use that to start a new line
- // (unless we end in whitespace).
- RenderStyle* childStyle = child->style();
- float childMin = 0;
- float childMax = 0;
-
- if (!child->isText()) {
- // Case (1) and (2). Inline replaced and inline flow elements.
- if (child->isRenderInline()) {
- // Add in padding/border/margin from the appropriate side of
- // the element.
- float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
- childMin += bpm;
- childMax += bpm;
-
- inlineMin += childMin;
- inlineMax += childMax;
-
- child->clearPreferredLogicalWidthsDirty();
- } else {
- // Inline replaced elts add in their margins to their min/max values.
- LayoutUnit margins = 0;
- Length startMargin = childStyle->marginStart();
- Length endMargin = childStyle->marginEnd();
- if (startMargin.isFixed())
- margins += adjustFloatForSubPixelLayout(startMargin.value());
- if (endMargin.isFixed())
- margins += adjustFloatForSubPixelLayout(endMargin.value());
- childMin += margins.ceilToFloat();
- childMax += margins.ceilToFloat();
- }
- }
-
- if (!child->isRenderInline() && !child->isText()) {
- // Case (2). Inline replaced elements and floats.
- // Go ahead and terminate the current line as far as
- // minwidth is concerned.
- LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
- if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
- RenderBox* childBox = toRenderBox(child);
- LogicalExtentComputedValues computedValues;
- childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
- childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
- } else {
- childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
- childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
- }
- childMin += childMinPreferredLogicalWidth.ceilToFloat();
- childMax += childMaxPreferredLogicalWidth.ceilToFloat();
-
- bool clearPreviousFloat;
- if (child->isFloating()) {
- clearPreviousFloat = (prevFloat
- && ((prevFloat->style()->floating() == LeftFloat && (childStyle->clear() & CLEFT))
- || (prevFloat->style()->floating() == RightFloat && (childStyle->clear() & CRIGHT))));
- prevFloat = child;
- } else
- clearPreviousFloat = false;
-
- bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
- if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
- updatePreferredWidth(minLogicalWidth, inlineMin);
- inlineMin = 0;
- }
-
- // If we're supposed to clear the previous float, then terminate maxwidth as well.
- if (clearPreviousFloat) {
- updatePreferredWidth(maxLogicalWidth, inlineMax);
- inlineMax = 0;
- }
-
- // Add in text-indent. This is added in only once.
- if (!addedTextIndent && !child->isFloating()) {
- float ceiledTextIndent = textIndent.ceilToFloat();
- childMin += ceiledTextIndent;
- childMax += ceiledTextIndent;
-
- if (childMin < 0)
- textIndent = adjustFloatForSubPixelLayout(childMin);
- else
- addedTextIndent = true;
- }
-
- // Add our width to the max.
- inlineMax += max<float>(0, childMax);
-
- if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
- if (child->isFloating())
- updatePreferredWidth(minLogicalWidth, childMin);
- else
- inlineMin += childMin;
- } else {
- // Now check our line.
- updatePreferredWidth(minLogicalWidth, childMin);
-
- // Now start a new line.
- inlineMin = 0;
- }
-
- if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
- updatePreferredWidth(minLogicalWidth, inlineMin);
- inlineMin = 0;
- }
-
- // We are no longer stripping whitespace at the start of
- // a line.
- if (!child->isFloating()) {
- stripFrontSpaces = false;
- trailingSpaceChild = 0;
- }
- } else if (child->isText()) {
- // Case (3). Text.
- RenderText* t = toRenderText(child);
-
- if (t->isWordBreak()) {
- updatePreferredWidth(minLogicalWidth, inlineMin);
- inlineMin = 0;
- continue;
- }
-
- if (t->style()->hasTextCombine() && t->isCombineText())
- toRenderCombineText(t)->combineText();
-
- // Determine if we have a breakable character. Pass in
- // whether or not we should ignore any spaces at the front
- // of the string. If those are going to be stripped out,
- // then they shouldn't be considered in the breakable char
- // check.
- bool hasBreakableChar, hasBreak;
- float firstLineMinWidth, lastLineMinWidth;
- bool hasBreakableStart, hasBreakableEnd;
- float firstLineMaxWidth, lastLineMaxWidth;
- t->trimmedPrefWidths(inlineMax,
- firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasBreakableEnd,
- hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWidth,
- childMin, childMax, stripFrontSpaces);
-
- // This text object will not be rendered, but it may still provide a breaking opportunity.
- if (!hasBreak && childMax == 0) {
- if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
- updatePreferredWidth(minLogicalWidth, inlineMin);
- inlineMin = 0;
- }
- continue;
- }
-
- if (stripFrontSpaces)
- trailingSpaceChild = child;
- else
- trailingSpaceChild = 0;
-
- // Add in text-indent. This is added in only once.
- float ti = 0;
- if (!addedTextIndent || hasRemainingNegativeTextIndent) {
- ti = textIndent.ceilToFloat();
- childMin += ti;
- firstLineMinWidth += ti;
-
- // It the text indent negative and larger than the child minimum, we re-use the remainder
- // in future minimum calculations, but using the negative value again on the maximum
- // will lead to under-counting the max pref width.
- if (!addedTextIndent) {
- childMax += ti;
- firstLineMaxWidth += ti;
- addedTextIndent = true;
- }
-
- if (childMin < 0) {
- textIndent = childMin;
- hasRemainingNegativeTextIndent = true;
- }
- }
-
- // If we have no breakable characters at all,
- // then this is the easy case. We add ourselves to the current
- // min and max and continue.
- if (!hasBreakableChar) {
- inlineMin += childMin;
- } else {
- if (hasBreakableStart) {
- updatePreferredWidth(minLogicalWidth, inlineMin);
- } else {
- inlineMin += firstLineMinWidth;
- updatePreferredWidth(minLogicalWidth, inlineMin);
- childMin -= ti;
- }
-
- inlineMin = childMin;
-
- if (hasBreakableEnd) {
- updatePreferredWidth(minLogicalWidth, inlineMin);
- inlineMin = 0;
- shouldBreakLineAfterText = false;
- } else {
- updatePreferredWidth(minLogicalWidth, inlineMin);
- inlineMin = lastLineMinWidth;
- shouldBreakLineAfterText = true;
- }
- }
-
- if (hasBreak) {
- inlineMax += firstLineMaxWidth;
- updatePreferredWidth(maxLogicalWidth, inlineMax);
- updatePreferredWidth(maxLogicalWidth, childMax);
- inlineMax = lastLineMaxWidth;
- addedTextIndent = true;
- } else {
- inlineMax += max<float>(0, childMax);
- }
- }
-
- // Ignore spaces after a list marker.
- if (child->isListMarker())
- stripFrontSpaces = true;
- } else {
- updatePreferredWidth(minLogicalWidth, inlineMin);
- updatePreferredWidth(maxLogicalWidth, inlineMax);
- inlineMin = inlineMax = 0;
- stripFrontSpaces = true;
- trailingSpaceChild = 0;
- addedTextIndent = true;
- }
-
- if (!child->isText() && child->isRenderInline())
- isPrevChildInlineFlow = true;
- else
- isPrevChildInlineFlow = false;
-
- oldAutoWrap = autoWrap;
- }
-
- if (styleToUse->collapseWhiteSpace())
- stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
-
- updatePreferredWidth(minLogicalWidth, inlineMin);
- updatePreferredWidth(maxLogicalWidth, inlineMax);
-}
-
void RenderBlock::computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
RenderStyle* styleToUse = style();
@@ -4491,7 +3745,7 @@ bool RenderBlock::hasLineIfEmpty() const
if (node()->isRootEditableElement())
return true;
- if (node()->isShadowRoot() && toShadowRoot(node())->host()->hasTagName(inputTag))
+ if (node()->isShadowRoot() && isHTMLInputElement(*toShadowRoot(node())->host()))
return true;
return false;
@@ -4506,16 +3760,13 @@ LayoutUnit RenderBlock::lineHeight(bool firstLine, LineDirectionMode direction,
if (isReplaced() && linePositionMode == PositionOnContainingLine)
return RenderBox::lineHeight(firstLine, direction, linePositionMode);
- if (firstLine && document().styleEngine()->usesFirstLineRules()) {
- RenderStyle* s = style(firstLine);
- if (s != style())
- return s->computedLineHeight(view());
- }
-
- if (m_lineHeight == -1)
- m_lineHeight = style()->computedLineHeight(view());
+ RenderStyle* s = style(firstLine && document().styleEngine()->usesFirstLineRules());
+ return s->computedLineHeight();
+}
- return m_lineHeight;
+int RenderBlock::beforeMarginInLineDirection(LineDirectionMode direction) const
+{
+ return direction == HorizontalLine ? marginTop() : marginRight();
}
int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
@@ -4524,7 +3775,7 @@ int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, Lin
// the base class. If we're being queried as though we're the root line
// box, then the fact that we're an inline-block is irrelevant, and we behave
// just like a block.
- if (isReplaced() && linePositionMode == PositionOnContainingLine) {
+ if (isInline() && linePositionMode == PositionOnContainingLine) {
// For "leaf" theme objects, let the theme decide what the baseline position is.
// FIXME: Might be better to have a custom CSS property instead, so that if the theme
// is turned off, checkboxes/radios will still have decent baselines.
@@ -4553,7 +3804,7 @@ int RenderBlock::baselinePosition(FontBaseline baselineType, bool firstLine, Lin
baselinePos = -1;
}
if (baselinePos != -1)
- return direction == HorizontalLine ? marginTop() + baselinePos : marginRight() + baselinePos;
+ return beforeMarginInLineDirection(direction) + baselinePos;
return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
}
@@ -4603,7 +3854,7 @@ int RenderBlock::firstLineBoxBaseline() const
int RenderBlock::inlineBlockBaseline(LineDirectionMode direction) const
{
- if (style()->overflowY() != OVISIBLE) {
+ if (!style()->isOverflowVisible()) {
// We are not calling RenderBox::baselinePosition here because the caller should add the margin-top/margin-right, not us.
return direction == HorizontalLine ? height() + m_marginBox.bottom() : width() + m_marginBox.left();
}
@@ -4663,10 +3914,12 @@ RenderBlock* RenderBlock::firstLineBlock() const
// FIXME: Remove when buttons are implemented with align-items instead
// of flexbox.
if (firstLineBlock->isReplaced() || firstLineBlock->isFloating()
- || !parentBlock || parentBlock->firstChild() != firstLineBlock
+ || !parentBlock
|| (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButton()))
break;
ASSERT_WITH_SECURITY_IMPLICATION(parentBlock->isRenderBlock());
+ if (toRenderBlock(parentBlock)->firstChild() != firstLineBlock)
+ break;
firstLineBlock = toRenderBlock(parentBlock);
}
@@ -4699,9 +3952,9 @@ static inline bool isPunctuationForFirstLetter(UChar c)
|| charCategory == Punctuation_Other;
}
-static inline bool shouldSkipForFirstLetter(UChar c)
+static inline bool isSpaceForFirstLetter(UChar c)
{
- return isSpaceOrNewline(c) || c == noBreakSpace || isPunctuationForFirstLetter(c);
+ return isSpaceOrNewline(c) || c == noBreakSpace;
}
static inline RenderObject* findFirstLetterBlock(RenderBlock* start)
@@ -4721,8 +3974,12 @@ static inline RenderObject* findFirstLetterBlock(RenderBlock* start)
return firstLetterBlock;
RenderObject* parentBlock = firstLetterBlock->parent();
- if (firstLetterBlock->isReplaced() || !parentBlock || parentBlock->firstChild() != firstLetterBlock ||
- (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButton()))
+ if (firstLetterBlock->isReplaced() || !parentBlock
+ || (!parentBlock->isRenderBlockFlow() && !parentBlock->isRenderButton())) {
+ return 0;
+ }
+ ASSERT(parentBlock->isRenderBlock());
+ if (toRenderBlock(parentBlock)->firstChild() != firstLetterBlock)
return 0;
firstLetterBlock = parentBlock;
}
@@ -4737,7 +3994,9 @@ void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderO
RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
ASSERT(firstLetter->isFloating() || firstLetter->isInline());
- if (RenderStyle::compare(firstLetter->style(), pseudoStyle) == Reattach) {
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
+
+ if (RenderStyle::stylePropagationDiff(firstLetter->style(), pseudoStyle) == Reattach) {
// The first-letter renderer needs to be replaced. Create a new renderer of the right type.
RenderBoxModelObject* newFirstLetter;
if (pseudoStyle->display() == INLINE)
@@ -4747,8 +4006,7 @@ void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderO
newFirstLetter->setStyle(pseudoStyle);
// Move the first letter into the new renderer.
- LayoutStateDisabler layoutStateDisabler(view());
- while (RenderObject* child = firstLetter->firstChild()) {
+ while (RenderObject* child = firstLetter->slowFirstChild()) {
if (child->isText())
toRenderText(child)->removeAndDestroyTextBoxes();
firstLetter->removeChild(child);
@@ -4771,7 +4029,7 @@ void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderO
} else
firstLetter->setStyle(pseudoStyle);
- for (RenderObject* genChild = firstLetter->firstChild(); genChild; genChild = genChild->nextSibling()) {
+ for (RenderObject* genChild = firstLetter->slowFirstChild(); genChild; genChild = genChild->nextSibling()) {
if (genChild->isText())
genChild->setStyle(pseudoStyle);
}
@@ -4780,38 +4038,34 @@ void RenderBlock::updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderO
static inline unsigned firstLetterLength(const String& text)
{
unsigned length = 0;
- bool punctuationOpen = false;
+ unsigned textLength = text.length();
- // Account for leading spaces and punctuation.
- while (length < text.length() && shouldSkipForFirstLetter((text)[length])) {
- if (isPunctuationForFirstLetter((text)[length]))
- punctuationOpen = true;
+ // Account for leading spaces first.
+ while (length < textLength && isSpaceForFirstLetter(text[length]))
+ length++;
+ // Now account for leading punctuation.
+ while (length < textLength && isPunctuationForFirstLetter(text[length]))
length++;
- }
- // Bail if we didn't find a letter
- if (text.length() && length == text.length())
+ // Bail if we didn't find a letter before the end of the text or before a space.
+ if (isSpaceForFirstLetter(text[length]) || (textLength && length == textLength))
return 0;
- // Account for first letter.
+ // Account the next character for first letter.
length++;
- if (!punctuationOpen)
- return length;
-
- // Keep looking for whitespace and allowed punctuation, but avoid
- // accumulating just whitespace into the :first-letter.
- for (unsigned scanLength = length; scanLength < text.length(); ++scanLength) {
- UChar c = (text)[scanLength];
+ // Keep looking allowed punctuation for the :first-letter.
+ for (unsigned scanLength = length; scanLength < textLength; ++scanLength) {
+ UChar c = text[scanLength];
- if (!shouldSkipForFirstLetter(c))
+ if (!isPunctuationForFirstLetter(c))
break;
- if (isPunctuationForFirstLetter(c))
- length = scanLength + 1;
+ length = scanLength + 1;
}
+ // FIXME: If textLength is 0, length may still be 1!
return length;
}
@@ -4821,14 +4075,18 @@ void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend
RenderObject* firstLetterContainer = currentChild->parent();
RenderStyle* pseudoStyle = styleForFirstLetter(firstLetterBlock, firstLetterContainer);
- RenderObject* firstLetter = 0;
+ RenderBoxModelObject* firstLetter = 0;
if (pseudoStyle->display() == INLINE)
firstLetter = RenderInline::createAnonymous(&document());
else
firstLetter = RenderBlockFlow::createAnonymous(&document());
firstLetter->setStyle(pseudoStyle);
- firstLetterContainer->addChild(firstLetter, currentChild);
+ // FIXME: The first letter code should not modify the render tree during
+ // layout. crbug.com/370458
+ DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
+
+ firstLetterContainer->addChild(firstLetter, currentChild);
RenderText* textObj = toRenderText(currentChild);
// The original string is going to be either a generated content string or a DOM node's
@@ -4848,7 +4106,7 @@ void RenderBlock::createFirstLetterRenderer(RenderObject* firstLetterBlock, Rend
firstLetterContainer->addChild(remainingText, textObj);
firstLetterContainer->removeChild(textObj);
remainingText->setFirstLetter(firstLetter);
- toRenderBoxModelObject(firstLetter)->setFirstLetterRemainingText(remainingText);
+ firstLetter->setFirstLetterRemainingText(remainingText);
// construct text fragment for the first letter
RenderTextFragment* letter =
@@ -4874,7 +4132,7 @@ void RenderBlock::updateFirstLetter()
return;
// Drill into inlines looking for our first text child.
- RenderObject* currChild = firstLetterBlock->firstChild();
+ RenderObject* currChild = firstLetterBlock->slowFirstChild();
unsigned length = 0;
while (currChild) {
if (currChild->isText()) {
@@ -4888,18 +4146,19 @@ void RenderBlock::updateFirstLetter()
currChild = currChild->nextSibling();
} else if (currChild->isFloatingOrOutOfFlowPositioned()) {
if (currChild->style()->styleType() == FIRST_LETTER) {
- currChild = currChild->firstChild();
+ currChild = currChild->slowFirstChild();
break;
}
currChild = currChild->nextSibling();
- } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList())
+ } else if (currChild->isReplaced() || currChild->isRenderButton() || currChild->isMenuList()) {
break;
- else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->canHaveGeneratedChildren()) {
+ } else if (currChild->style()->hasPseudoStyle(FIRST_LETTER) && currChild->canHaveGeneratedChildren()) {
// We found a lower-level node with first-letter, which supersedes the higher-level style
firstLetterBlock = currChild;
- currChild = currChild->firstChild();
- } else
- currChild = currChild->firstChild();
+ currChild = currChild->slowFirstChild();
+ } else {
+ currChild = currChild->slowFirstChild();
+ }
}
if (!currChild)
@@ -4912,12 +4171,14 @@ void RenderBlock::updateFirstLetter()
return;
}
- if (!currChild->isText() || currChild->isBR())
+ // FIXME: This black-list of disallowed RenderText subclasses is fragile.
+ // Should counter be on this list? What about RenderTextFragment?
+ if (!currChild->isText() || currChild->isBR() || toRenderText(currChild)->isWordBreak())
return;
// Our layout state is not valid for the repaints we are going to trigger by
// adding and removing children of firstLetterContainer.
- LayoutStateDisabler layoutStateDisabler(view());
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
createFirstLetterRenderer(firstLetterBlock, currChild, length);
}
@@ -5059,7 +4320,7 @@ void RenderBlock::fitBorderToLinesIfNeeded()
LayoutUnit leftEdge = borderLeft() + paddingLeft();
LayoutUnit rightEdge = leftEdge + oldWidth;
left = min(rightEdge, max(leftEdge, left));
- right = max(leftEdge, min(rightEdge, right));
+ right = max(left, min(rightEdge, right));
LayoutUnit newContentWidth = right - left;
if (newContentWidth == oldWidth)
@@ -5168,17 +4429,18 @@ void RenderBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
if (isAnonymousBlockContinuation()) {
// FIXME: This is wrong for block-flows that are horizontal.
// https://bugs.webkit.org/show_bug.cgi?id=46781
- FloatRect localRect(0, -collapsedMarginBefore(),
- width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
+ FloatRect localRect(0, -collapsedMarginBefore().toFloat(),
+ width().toFloat(), (height() + collapsedMarginBefore() + collapsedMarginAfter()).toFloat());
quads.append(localToAbsoluteQuad(localRect, 0 /* mode */, wasFixed));
continuation()->absoluteQuads(quads, wasFixed);
- } else
- quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed));
+ } else {
+ quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width().toFloat(), height().toFloat()), 0 /* mode */, wasFixed));
+ }
}
-LayoutRect RenderBlock::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
+LayoutRect RenderBlock::rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth) const
{
- LayoutRect r(RenderBox::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
+ LayoutRect r(RenderBox::rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineWidth));
if (isAnonymousBlockContinuation())
r.inflateY(collapsedMarginBefore()); // FIXME: This is wrong for block-flows that are horizontal.
return r;
@@ -5196,7 +4458,7 @@ void RenderBlock::updateDragState(bool dragOn)
continuation()->updateDragState(dragOn);
}
-RenderStyle* RenderBlock::outlineStyleForRepaint() const
+RenderStyle* RenderBlock::outlineStyleForPaintInvalidation() const
{
return isAnonymousBlockContinuation() ? continuation()->style() : style();
}
@@ -5240,10 +4502,10 @@ LayoutRect RenderBlock::localCaretRect(InlineBox* inlineBox, int caretOffset, La
LayoutUnit myRight = caretRect.maxX();
// FIXME: why call localToAbsoluteForContent() twice here, too?
- FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
+ FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight.toFloat(), 0));
LayoutUnit containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
- FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
+ FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight.toFloat(), 0));
*extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
}
@@ -5264,8 +4526,8 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& a
// FIXME: This is wrong for block-flows that are horizontal.
// https://bugs.webkit.org/show_bug.cgi?id=46781
bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
- float topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
- float bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
+ LayoutUnit topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
+ LayoutUnit bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin, width(), height() + topMargin + bottomMargin);
if (!rect.isEmpty())
rects.append(pixelSnappedIntRect(rect));
@@ -5281,18 +4543,7 @@ void RenderBlock::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& a
rects.append(pixelSnappedIntRect(rect));
}
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
- if (!curr->isText() && !curr->isListMarker() && curr->isBox()) {
- RenderBox* box = toRenderBox(curr);
- FloatPoint pos;
- // FIXME: This doesn't work correctly with transforms.
- if (box->layer())
- pos = curr->localToContainerPoint(FloatPoint(), paintContainer);
- else
- pos = FloatPoint(additionalOffset.x() + box->x(), additionalOffset.y() + box->y());
- box->addFocusRingRects(rects, flooredLayoutPoint(pos), paintContainer);
- }
- }
+ addChildFocusRingRects(rects, additionalOffset, paintContainer);
}
if (inlineElementContinuation())
@@ -5324,25 +4575,6 @@ RenderBox* RenderBlock::createAnonymousBoxWithSameTypeAs(const RenderObject* par
return createAnonymousWithParentRendererAndDisplay(parent, style()->display());
}
-bool RenderBlock::hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
-{
- ASSERT(view()->layoutState() && view()->layoutState()->isPaginated());
-
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (!flowThread)
- return true; // Printing and multi-column both make new pages to accommodate content.
-
- // See if we're in the last region.
- LayoutUnit pageOffset = offsetFromLogicalTopOfFirstPage() + logicalOffset;
- RenderRegion* region = flowThread->regionAtBlockOffset(pageOffset, this);
- if (!region)
- return false;
- if (region->isLastRegion())
- return region->isRenderRegionSet() || region->style()->regionFragment() == BreakRegionFragment
- || (pageBoundaryRule == IncludePageBoundary && pageOffset == region->logicalTopForFlowThreadContent());
- return true;
-}
-
LayoutUnit RenderBlock::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule pageBoundaryRule) const
{
LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
@@ -5356,16 +4588,11 @@ LayoutUnit RenderBlock::nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundar
return logicalOffset + remainingLogicalHeight;
}
-ColumnInfo::PaginationUnit RenderBlock::paginationUnit() const
-{
- return ColumnInfo::Column;
-}
-
LayoutUnit RenderBlock::pageLogicalTopForOffset(LayoutUnit offset) const
{
RenderView* renderView = view();
- LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->m_pageOffset.height() : renderView->layoutState()->m_pageOffset.width();
- LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->m_layoutOffset.height() : renderView->layoutState()->m_layoutOffset.width();
+ LayoutUnit firstPageLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->pageOffset().height() : renderView->layoutState()->pageOffset().width();
+ LayoutUnit blockLogicalTop = isHorizontalWritingMode() ? renderView->layoutState()->layoutOffset().height() : renderView->layoutState()->layoutOffset().width();
LayoutUnit cumulativeOffset = offset + blockLogicalTop;
RenderFlowThread* flowThread = flowThreadContainingBlock();
@@ -5383,7 +4610,7 @@ LayoutUnit RenderBlock::pageLogicalHeightForOffset(LayoutUnit offset) const
RenderView* renderView = view();
RenderFlowThread* flowThread = flowThreadContainingBlock();
if (!flowThread)
- return renderView->layoutState()->m_pageLogicalHeight;
+ return renderView->layoutState()->pageLogicalHeight();
return flowThread->pageLogicalHeightForOffset(offset + offsetFromLogicalTopOfFirstPage());
}
@@ -5394,7 +4621,7 @@ LayoutUnit RenderBlock::pageRemainingLogicalHeightForOffset(LayoutUnit offset, P
RenderFlowThread* flowThread = flowThreadContainingBlock();
if (!flowThread) {
- LayoutUnit pageLogicalHeight = renderView->layoutState()->m_pageLogicalHeight;
+ LayoutUnit pageLogicalHeight = renderView->layoutState()->pageLogicalHeight();
LayoutUnit remainingHeight = pageLogicalHeight - intMod(offset, pageLogicalHeight);
if (pageBoundaryRule == IncludePageBoundary) {
// If includeBoundaryPoint is true the line exactly on the top edge of a
@@ -5409,46 +4636,23 @@ LayoutUnit RenderBlock::pageRemainingLogicalHeightForOffset(LayoutUnit offset, P
LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins)
{
- bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
- bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight;
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
+ bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns() || flowThreadContainingBlock();
+ bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogicalHeight();
bool isUnsplittable = child->isUnsplittableForPagination() || (checkColumnBreaks && child->style()->columnBreakInside() == PBAVOID)
- || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID)
- || (checkRegionBreaks && child->style()->regionBreakInside() == PBAVOID);
+ || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID);
if (!isUnsplittable)
return logicalOffset;
LayoutUnit childLogicalHeight = logicalHeightForChild(child) + (includeMargins ? marginBeforeForChild(child) + marginAfterForChild(child) : LayoutUnit());
LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset);
- bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
updateMinimumPageHeight(logicalOffset, childLogicalHeight);
- if (!pageLogicalHeight || (hasUniformPageLogicalHeight && childLogicalHeight > pageLogicalHeight)
- || !hasNextPage(logicalOffset))
+ if (!pageLogicalHeight || childLogicalHeight > pageLogicalHeight)
return logicalOffset;
LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(logicalOffset, ExcludePageBoundary);
- if (remainingLogicalHeight < childLogicalHeight) {
- if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, childLogicalHeight))
- return logicalOffset;
+ if (remainingLogicalHeight < childLogicalHeight)
return logicalOffset + remainingLogicalHeight;
- }
return logicalOffset;
}
-bool RenderBlock::pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const
-{
- bool checkRegion = false;
- for (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment); pageLogicalHeight;
- pageLogicalHeight = pageLogicalHeightForOffset(logicalOffset + adjustment)) {
- if (minimumLogicalHeight <= pageLogicalHeight)
- return true;
- if (!hasNextPage(logicalOffset + adjustment))
- return false;
- adjustment += pageLogicalHeight;
- checkRegion = true;
- }
- return !checkRegion;
-}
-
void RenderBlock::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
{
if (RenderFlowThread* flowThread = flowThreadContainingBlock())
@@ -5459,7 +4663,7 @@ void RenderBlock::updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeigh
{
if (RenderFlowThread* flowThread = flowThreadContainingBlock())
flowThread->updateMinimumPageHeight(offsetFromLogicalTopOfFirstPage() + offset, minHeight);
- else if (ColumnInfo* colInfo = view()->layoutState()->m_columnInfo)
+ else if (ColumnInfo* colInfo = view()->layoutState()->columnInfo())
colInfo->updateMinimumColumnHeight(minHeight);
}
@@ -5514,8 +4718,7 @@ void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, Layout
bool hasUniformPageLogicalHeight = !flowThread || flowThread->regionsHaveUniformLogicalHeight();
// If lineHeight is greater than pageLogicalHeight, but logicalVisualOverflow.height() still fits, we are
// still going to add a strut, so that the visible overflow fits on a single page.
- if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight)
- || !hasNextPage(logicalOffset))
+ if (!pageLogicalHeight || (hasUniformPageLogicalHeight && logicalVisualOverflow.height() > pageLogicalHeight))
// FIXME: In case the line aligns with the top of the page (or it's slightly shifted downwards) it will not be marked as the first line in the page.
// From here, the fix is not straightforward because it's not easy to always determine when the current line is the first in the page.
return;
@@ -5527,9 +4730,6 @@ void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, Layout
clearShouldBreakAtLineToAvoidWidow();
setDidBreakAtLineToAvoidWidow();
}
- // If we have a non-uniform page height, then we have to shift further possibly.
- if (!hasUniformPageLogicalHeight && !pushToNextPageWithMinimumLogicalHeight(remainingLogicalHeight, logicalOffset, lineHeight))
- return;
if (lineHeight > pageLogicalHeight) {
// Split the top margin in order to avoid splitting the visible part of the line.
remainingLogicalHeight -= min(lineHeight - pageLogicalHeight, max<LayoutUnit>(0, logicalVisualOverflow.y() - lineBox->lineTopWithLeading()));
@@ -5554,34 +4754,6 @@ void RenderBlock::adjustLinePositionForPagination(RootInlineBox* lineBox, Layout
}
}
-void RenderBlock::updateRegionForLine(RootInlineBox* lineBox) const
-{
- ASSERT(lineBox);
- lineBox->setContainingRegion(regionAtBlockOffset(lineBox->lineTopWithLeading()));
-
- RootInlineBox* prevLineBox = lineBox->prevRootBox();
- if (!prevLineBox)
- return;
-
- // This check is more accurate than the one in |adjustLinePositionForPagination| because it takes into
- // account just the container changes between lines. The before mentioned function doesn't set the flag
- // correctly if the line is positioned at the top of the last fragment container.
- if (lineBox->containingRegion() != prevLineBox->containingRegion())
- lineBox->setIsFirstAfterPageBreak(true);
-}
-
-bool RenderBlock::lineWidthForPaginatedLineChanged(RootInlineBox* rootBox, LayoutUnit lineDelta, RenderFlowThread* flowThread) const
-{
- if (!flowThread)
- return false;
-
- RenderRegion* currentRegion = regionAtBlockOffset(rootBox->lineTopWithLeading() + lineDelta);
- // Just bail if the region didn't change.
- if (rootBox->containingRegion() == currentRegion)
- return false;
- return rootBox->paginatedLineWidth() != availableLogicalWidthForContent(currentRegion);
-}
-
LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const
{
LayoutState* layoutState = view()->layoutState();
@@ -5595,7 +4767,7 @@ LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const
if (layoutState) {
ASSERT(layoutState->renderer() == this);
- LayoutSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->pageOffset();
return isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
}
@@ -5603,47 +4775,6 @@ LayoutUnit RenderBlock::offsetFromLogicalTopOfFirstPage() const
return 0;
}
-RenderRegion* RenderBlock::regionAtBlockOffset(LayoutUnit blockOffset) const
-{
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (!flowThread || !flowThread->hasValidRegionInfo())
- return 0;
-
- return flowThread->regionAtBlockOffset(offsetFromLogicalTopOfFirstPage() + blockOffset, true);
-}
-
-bool RenderBlock::logicalWidthChangedInRegions(RenderFlowThread* flowThread) const
-{
- if (!flowThread || !flowThread->hasValidRegionInfo())
- return false;
-
- return flowThread->logicalWidthChangedInRegionsForBlock(this);
-}
-
-RenderRegion* RenderBlock::clampToStartAndEndRegions(RenderRegion* region) const
-{
- RenderFlowThread* flowThread = flowThreadContainingBlock();
-
- ASSERT(isRenderView() || (region && flowThread));
- if (isRenderView())
- return region;
-
- // We need to clamp to the block, since we want any lines or blocks that overflow out of the
- // logical top or logical bottom of the block to size as though the border box in the first and
- // last regions extended infinitely. Otherwise the lines are going to size according to the regions
- // they overflow into, which makes no sense when this block doesn't exist in |region| at all.
- RenderRegion* startRegion;
- RenderRegion* endRegion;
- flowThread->getRegionRangeForBox(this, startRegion, endRegion);
-
- if (startRegion && region->logicalTopForFlowThreadContent() < startRegion->logicalTopForFlowThreadContent())
- return startRegion;
- if (endRegion && region->logicalTopForFlowThreadContent() > endRegion->logicalTopForFlowThreadContent())
- return endRegion;
-
- return region;
-}
-
LayoutUnit RenderBlock::collapsedMarginBeforeForChild(const RenderBox* child) const
{
// If the child has the same directionality as we do, then we can just return its
@@ -5781,6 +4912,91 @@ RenderBlockFlow* RenderBlock::createAnonymousColumnSpanWithParentRenderer(const
return newBox;
}
+static bool recalcNormalFlowChildOverflowIfNeeded(RenderObject* renderer)
+{
+ if (renderer->isOutOfFlowPositioned() || !renderer->needsOverflowRecalcAfterStyleChange())
+ return false;
+
+ ASSERT(renderer->isRenderBlock());
+ return toRenderBlock(renderer)->recalcOverflowAfterStyleChange();
+}
+
+bool RenderBlock::recalcChildOverflowAfterStyleChange()
+{
+ ASSERT(childNeedsOverflowRecalcAfterStyleChange());
+ setChildNeedsOverflowRecalcAfterStyleChange(false);
+
+ bool childrenOverflowChanged = false;
+
+ if (childrenInline()) {
+ ListHashSet<RootInlineBox*> lineBoxes;
+ for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
+ RenderObject* renderer = walker.current();
+ if (recalcNormalFlowChildOverflowIfNeeded(renderer)) {
+ childrenOverflowChanged = true;
+ if (InlineBox* inlineBoxWrapper = toRenderBlock(renderer)->inlineBoxWrapper())
+ lineBoxes.add(&inlineBoxWrapper->root());
+ }
+ }
+
+ // FIXME: Glyph overflow will get lost in this case, but not really a big deal.
+ GlyphOverflowAndFallbackFontsMap textBoxDataMap;
+ for (ListHashSet<RootInlineBox*>::const_iterator it = lineBoxes.begin(); it != lineBoxes.end(); ++it) {
+ RootInlineBox* box = *it;
+ box->computeOverflow(box->lineTop(), box->lineBottom(), textBoxDataMap);
+ }
+ } else {
+ for (RenderBox* box = firstChildBox(); box; box = box->nextSiblingBox()) {
+ if (recalcNormalFlowChildOverflowIfNeeded(box))
+ childrenOverflowChanged = true;
+ }
+ }
+
+ TrackedRendererListHashSet* positionedDescendants = positionedObjects();
+ if (!positionedDescendants)
+ return childrenOverflowChanged;
+
+ TrackedRendererListHashSet::iterator end = positionedDescendants->end();
+ for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
+ RenderBox* box = *it;
+
+ if (!box->needsOverflowRecalcAfterStyleChange())
+ continue;
+ RenderBlock* block = toRenderBlock(box);
+ if (!block->recalcOverflowAfterStyleChange() || box->style()->position() == FixedPosition)
+ continue;
+
+ childrenOverflowChanged = true;
+ }
+ return childrenOverflowChanged;
+}
+
+bool RenderBlock::recalcOverflowAfterStyleChange()
+{
+ ASSERT(needsOverflowRecalcAfterStyleChange());
+
+ bool childrenOverflowChanged = false;
+ if (childNeedsOverflowRecalcAfterStyleChange())
+ childrenOverflowChanged = recalcChildOverflowAfterStyleChange();
+
+ if (!selfNeedsOverflowRecalcAfterStyleChange() && !childrenOverflowChanged)
+ return false;
+
+ setSelfNeedsOverflowRecalcAfterStyleChange(false);
+ // If the current block needs layout, overflow will be recalculated during
+ // layout time anyway. We can safely exit here.
+ if (needsLayout())
+ return false;
+
+ LayoutUnit oldClientAfterEdge = hasRenderOverflow() ? m_overflow->layoutClientAfterEdge() : clientLogicalBottom();
+ computeOverflow(oldClientAfterEdge, true);
+
+ if (hasOverflowClip())
+ layer()->scrollableArea()->updateAfterOverflowRecalc();
+
+ return !hasOverflowClip();
+}
+
#ifndef NDEBUG
void RenderBlock::checkPositionedObjectsNeedLayout()
{
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBlock.h b/chromium/third_party/WebKit/Source/core/rendering/RenderBlock.h
index cd090231993..c3ce2fb32a9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBlock.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBlock.h
@@ -29,7 +29,6 @@
#include "core/rendering/RenderBox.h"
#include "core/rendering/RenderLineBoxList.h"
#include "core/rendering/RootInlineBox.h"
-#include "core/rendering/shapes/ShapeInsideInfo.h"
#include "core/rendering/style/ShapeValue.h"
#include "platform/text/TextBreakIterator.h"
#include "platform/text/TextRun.h"
@@ -38,32 +37,21 @@
namespace WebCore {
-class BasicShape;
-class BidiContext;
-class InlineIterator;
-class LayoutStateMaintainer;
class LineLayoutState;
class RenderInline;
-class RenderText;
-struct BidiRun;
struct PaintInfo;
+class WordMeasurement;
+
class LineInfo;
class RenderRubyRun;
-class TextLayout;
-class WordMeasurement;
-template <class Iterator, class Run> class BidiResolver;
template <class Run> class BidiRunList;
-template <class Iterator> struct MidpointState;
-typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
-typedef MidpointState<InlineIterator> LineMidpointState;
typedef WTF::ListHashSet<RenderBox*, 16> TrackedRendererListHashSet;
typedef WTF::HashMap<const RenderBlock*, OwnPtr<TrackedRendererListHashSet> > TrackedDescendantsMap;
typedef WTF::HashMap<const RenderBox*, OwnPtr<HashSet<RenderBlock*> > > TrackedContainerMap;
typedef Vector<WordMeasurement, 64> WordMeasurements;
-enum CaretType { CursorCaret, DragCaret };
enum ContainingBlockState { NewContainingBlock, SameContainingBlock };
enum TextRunFlag {
@@ -86,6 +74,10 @@ public:
RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
+ // If you have a RenderBlock, use firstChild or lastChild instead.
+ void slowFirstChild() const WTF_DELETED_FUNCTION;
+ void slowLastChild() const WTF_DELETED_FUNCTION;
+
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
@@ -93,7 +85,7 @@ public:
// These two functions are overridden for inline-block.
virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE FINAL;
- virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
LayoutUnit minLineHeightForReplacedRenderer(bool isFirstLine, LayoutUnit replacedHeight) const;
@@ -105,10 +97,10 @@ public:
// FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
virtual void deleteLineBoxTree();
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
- virtual void removeChild(RenderObject*);
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
+ virtual void removeChild(RenderObject*) OVERRIDE;
- virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0);
+ virtual void layoutBlock(bool relayoutChildren);
void insertPositionedObject(RenderBox*);
static void removePositionedObject(RenderBox*);
@@ -123,12 +115,18 @@ public:
void addPercentHeightDescendant(RenderBox*);
static void removePercentHeightDescendant(RenderBox*);
- TrackedRendererListHashSet* percentHeightDescendants() const;
static bool hasPercentHeightContainerMap();
static bool hasPercentHeightDescendant(RenderBox*);
static void clearPercentHeightDescendantsFrom(RenderBox*);
static void removePercentHeightDescendantIfNeeded(RenderBox*);
+ TrackedRendererListHashSet* percentHeightDescendants() const;
+ bool hasPercentHeightDescendants() const
+ {
+ TrackedRendererListHashSet* descendants = percentHeightDescendants();
+ return descendants && !descendants->isEmpty();
+ }
+
void setHasMarkupTruncation(bool b) { m_hasMarkupTruncation = b; }
bool hasMarkupTruncation() const { return m_hasMarkupTruncation; }
@@ -141,9 +139,6 @@ public:
bool hasMarginBeforeQuirk(const RenderBox* child) const;
bool hasMarginAfterQuirk(const RenderBox* child) const;
- RootInlineBox* createAndAppendRootInlineBox();
-
- void markShapeInsideDescendantsForLayout();
void markPositionedObjectsForLayout();
// FIXME: Do we really need this to be virtual? It's just so we can call this on
// RenderBoxes without needed to check whether they're RenderBlocks first.
@@ -152,67 +147,6 @@ public:
// FIXME-BLOCKFLOW: Remove virtualizaion when all of the line layout code has been moved out of RenderBlock
virtual bool containsFloats() const { return false; }
- // Versions that can compute line offsets with the region and page offset passed in. Used for speed to avoid having to
- // compute the region all over again when you already know it.
- LayoutUnit availableLogicalWidthForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
- {
- return max<LayoutUnit>(0, logicalRightOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight)
- - logicalLeftOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight));
- }
- LayoutUnit logicalRightOffsetForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
- {
- return logicalRightOffsetForLine(position, logicalRightOffsetForContent(region), shouldIndentText, logicalHeight);
- }
- LayoutUnit logicalLeftOffsetForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
- {
- return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(region), shouldIndentText, logicalHeight);
- }
- LayoutUnit startOffsetForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
- {
- return style()->isLeftToRightDirection() ? logicalLeftOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight)
- : logicalWidth() - logicalRightOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight);
- }
- LayoutUnit endOffsetForLineInRegion(LayoutUnit position, bool shouldIndentText, RenderRegion* region, LayoutUnit logicalHeight = 0) const
- {
- return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight)
- : logicalWidth() - logicalRightOffsetForLineInRegion(position, shouldIndentText, region, logicalHeight);
- }
-
- LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
- {
- return availableLogicalWidthForLineInRegion(position, shouldIndentText, regionAtBlockOffset(position), logicalHeight);
- }
- LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
- {
- return logicalRightOffsetForLine(position, logicalRightOffsetForContent(position), shouldIndentText, logicalHeight);
- }
- LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
- {
- return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(position), shouldIndentText, logicalHeight);
- }
- LayoutUnit pixelSnappedLogicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
- {
- return roundToInt(logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight));
- }
- LayoutUnit pixelSnappedLogicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
- {
- // FIXME: Multicolumn layouts break carrying over subpixel values to the logical right offset because the lines may be shifted
- // by a subpixel value for all but the first column. This can lead to the actual pixel snapped width of the column being off
- // by one pixel when rendered versus layed out, which can result in the line being clipped. For now, we have to floor.
- // https://bugs.webkit.org/show_bug.cgi?id=105461
- return floorToInt(logicalRightOffsetForLine(position, shouldIndentText, logicalHeight));
- }
- LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
- {
- return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
- : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
- }
- LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
- {
- return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
- : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
- }
-
LayoutUnit textIndentOffset() const;
virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
@@ -229,6 +163,7 @@ public:
RootInlineBox* firstRootBox() const { return static_cast<RootInlineBox*>(firstLineBox()); }
RootInlineBox* lastRootBox() const { return static_cast<RootInlineBox*>(lastLineBox()); }
+ virtual bool shouldPaintSelectionGaps() const OVERRIDE FINAL;
GapRects selectionGapRectsForRepaint(const RenderLayerModelObject* repaintContainer);
LayoutRect logicalLeftSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
RenderObject* selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo*);
@@ -246,7 +181,7 @@ public:
void clearTruncation();
void adjustRectForColumns(LayoutRect&) const;
- virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const OVERRIDE FINAL;
+ virtual LayoutSize columnOffset(const LayoutPoint&) const OVERRIDE;
void adjustForColumnRect(LayoutSize& offset, const LayoutPoint& locationInContainer) const;
void addContinuationWithOutline(RenderInline*);
@@ -272,8 +207,6 @@ public:
ColumnInfo* columnInfo() const;
int columnGap() const;
- void updateColumnInfoFromStyle(RenderStyle*);
-
// These two functions take the ColumnInfo* to avoid repeated lookups of the info in the global HashMap.
unsigned columnCount(ColumnInfo*) const;
LayoutRect columnRectAt(ColumnInfo*, unsigned) const;
@@ -295,12 +228,10 @@ public:
void setPageLogicalOffset(LayoutUnit);
// Accessors for logical width/height and margins in the containing block's block-flow direction.
- enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
LayoutUnit logicalWidthForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
LayoutUnit logicalHeightForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->height() : child->width(); }
+ LayoutSize logicalSizeForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->size() : child->size().transposedSize(); }
LayoutUnit logicalTopForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->y() : child->x(); }
- void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
- void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
LayoutUnit marginBeforeForChild(const RenderBoxModelObject* child) const { return child->marginBefore(style()); }
LayoutUnit marginAfterForChild(const RenderBoxModelObject* child) const { return child->marginAfter(style()); }
LayoutUnit marginStartForChild(const RenderBoxModelObject* child) const { return child->marginStart(style()); }
@@ -313,125 +244,67 @@ public:
LayoutUnit collapsedMarginAfterForChild(const RenderBox* child) const;
virtual void updateFirstLetter();
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
- virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { };
+ virtual void scrollbarsChanged(bool /*horizontalScrollbarChanged*/, bool /*verticalScrollbarChanged*/) { }
- LayoutUnit logicalLeftOffsetForContent(RenderRegion*) const;
- LayoutUnit logicalRightOffsetForContent(RenderRegion*) const;
- LayoutUnit availableLogicalWidthForContent(RenderRegion* region) const
- {
- return max<LayoutUnit>(0, logicalRightOffsetForContent(region) - logicalLeftOffsetForContent(region));
- }
- LayoutUnit startOffsetForContent(RenderRegion* region) const
- {
- return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region) : logicalWidth() - logicalRightOffsetForContent(region);
- }
- LayoutUnit endOffsetForContent(RenderRegion* region) const
- {
- return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent(region) : logicalWidth() - logicalRightOffsetForContent(region);
- }
- LayoutUnit logicalLeftOffsetForContent(LayoutUnit blockOffset) const
- {
- return logicalLeftOffsetForContent(regionAtBlockOffset(blockOffset));
- }
- LayoutUnit logicalRightOffsetForContent(LayoutUnit blockOffset) const
- {
- return logicalRightOffsetForContent(regionAtBlockOffset(blockOffset));
- }
- LayoutUnit availableLogicalWidthForContent(LayoutUnit blockOffset) const
- {
- return availableLogicalWidthForContent(regionAtBlockOffset(blockOffset));
- }
- LayoutUnit startOffsetForContent(LayoutUnit blockOffset) const
- {
- return startOffsetForContent(regionAtBlockOffset(blockOffset));
- }
- LayoutUnit endOffsetForContent(LayoutUnit blockOffset) const
- {
- return endOffsetForContent(regionAtBlockOffset(blockOffset));
- }
+ LayoutUnit availableLogicalWidthForContent() const { return max<LayoutUnit>(0, logicalRightOffsetForContent() - logicalLeftOffsetForContent()); }
LayoutUnit logicalLeftOffsetForContent() const { return isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop(); }
LayoutUnit logicalRightOffsetForContent() const { return logicalLeftOffsetForContent() + availableLogicalWidth(); }
LayoutUnit startOffsetForContent() const { return style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
LayoutUnit endOffsetForContent() const { return !style()->isLeftToRightDirection() ? logicalLeftOffsetForContent() : logicalWidth() - logicalRightOffsetForContent(); }
- LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart, RenderRegion* = 0);
-
#ifndef NDEBUG
void checkPositionedObjectsNeedLayout();
void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0) const;
#endif
- ShapeInsideInfo* ensureShapeInsideInfo()
- {
- if (!m_rareData || !m_rareData->m_shapeInsideInfo)
- setShapeInsideInfo(ShapeInsideInfo::createInfo(this));
- return m_rareData->m_shapeInsideInfo.get();
- }
- ShapeInsideInfo* shapeInsideInfo() const
- {
- return m_rareData && m_rareData->m_shapeInsideInfo && ShapeInsideInfo::isEnabledFor(this) ? m_rareData->m_shapeInsideInfo.get() : 0;
- }
- void setShapeInsideInfo(PassOwnPtr<ShapeInsideInfo> value)
- {
- if (!m_rareData)
- m_rareData = adoptPtr(new RenderBlockRareData());
- m_rareData->m_shapeInsideInfo = value;
- }
- ShapeInsideInfo* layoutShapeInsideInfo() const;
- bool allowsShapeInsideInfoSharing(const RenderBlock* other) const;
- LayoutSize logicalOffsetFromShapeAncestorContainer(const RenderBlock* container) const;
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
-
// inline-block elements paint all phases atomically. This function ensures that. Certain other elements
// (grid items, flex items) require this behavior as well, and this function exists as a helper for them.
// It is expected that the caller will call this function independent of the value of paintInfo.phase.
static void paintAsInlineBlock(RenderObject*, PaintInfo&, const LayoutPoint&);
+
+ bool recalcChildOverflowAfterStyleChange();
+ bool recalcOverflowAfterStyleChange();
+
protected:
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
void dirtyForLayoutFromPercentageHeightDescendants(SubtreeLayoutScope&);
- virtual void layout();
- virtual void didLayout(ResourceLoadPriorityOptimizer&);
- virtual void didScroll(ResourceLoadPriorityOptimizer&);
- void updateStyleImageLoadingPriorities(ResourceLoadPriorityOptimizer&);
+ virtual void layout() OVERRIDE;
+ virtual bool updateImageLoadingPriorities() OVERRIDE FINAL;
+
+ enum PositionedLayoutBehavior {
+ DefaultLayout,
+ LayoutOnlyFixedPositionedObjects,
+ ForcedLayoutAfterContainingBlockMoved
+ };
- void layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly = false);
+ void layoutPositionedObjects(bool relayoutChildren, PositionedLayoutBehavior = DefaultLayout);
void markFixedPositionObjectForLayoutIfNeeded(RenderObject* child, SubtreeLayoutScope&);
LayoutUnit marginIntrinsicLogicalWidthForChild(RenderBox* child) const;
- virtual bool supportsPartialLayout() const OVERRIDE { return true; };
+ int beforeMarginInLineDirection(LineDirectionMode) const;
- virtual void paint(PaintInfo&, const LayoutPoint&);
- virtual void paintObject(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
virtual void paintChildren(PaintInfo&, const LayoutPoint&);
void paintChild(RenderBox*, PaintInfo&, const LayoutPoint&);
void paintChildAsInlineBlock(RenderBox*, PaintInfo&, const LayoutPoint&);
- LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
- {
- return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
- }
- LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
- {
- return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
- }
-
- virtual void adjustInlineDirectionLineBounds(int /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }
-
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
+ virtual void adjustInlineDirectionLineBounds(unsigned /* expansionOpportunityCount */, float& /* logicalLeft */, float& /* logicalWidth */) const { }
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
virtual void computePreferredLogicalWidths() OVERRIDE;
void adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
- virtual int firstLineBoxBaseline() const;
+ virtual int firstLineBoxBaseline() const OVERRIDE;
virtual int inlineBlockBaseline(LineDirectionMode) const OVERRIDE;
int lastLineBoxBaseline(LineDirectionMode) const;
- virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
+ virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRIDE;
// Delay update scrollbar until finishDelayRepaint() will be
// called. This function is used when a flexbox is laying out its
@@ -443,8 +316,8 @@ protected:
void updateScrollInfoAfterLayout();
- virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
virtual bool hasLineIfEmpty() const;
@@ -465,32 +338,19 @@ protected:
virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE;
- bool updateRegionsAndShapesLogicalSize(RenderFlowThread*);
void computeRegionRangeForBlock(RenderFlowThread*);
void updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox*);
- virtual void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
-
virtual bool isInlineBlockOrInlineTable() const OVERRIDE FINAL { return isInline() && isReplaced(); }
-private:
- // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
- virtual LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit, LayoutUnit fixedOffset, LayoutUnit) const { return fixedOffset; }
- // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
- virtual LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit, LayoutUnit fixedOffset, LayoutUnit) const { return fixedOffset; }
- LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
- LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
-
- void computeShapeSize();
- void updateRegionsAndShapesAfterChildLayout(RenderFlowThread*, bool);
- void updateShapeInsideInfoAfterStyleChange(const ShapeValue*, const ShapeValue* oldShape);
- void relayoutShapeDescendantIfMoved(RenderBlock* child, LayoutSize offset);
+ virtual void invalidateTreeAfterLayout(const RenderLayerModelObject&) OVERRIDE;
+private:
virtual RenderObjectChildList* virtualChildren() OVERRIDE FINAL { return children(); }
virtual const RenderObjectChildList* virtualChildren() const OVERRIDE FINAL { return children(); }
- virtual const char* renderName() const;
+ virtual const char* renderName() const OVERRIDE;
virtual bool isRenderBlock() const OVERRIDE FINAL { return true; }
@@ -498,27 +358,20 @@ private:
virtual void removeLeftoverAnonymousBlock(RenderBlock* child);
static void collapseAnonymousBlockChild(RenderBlock* parent, RenderBlock* child);
- // FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
- virtual void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert) { moveAllChildrenTo(toBlock, fullRemoveInsert); }
virtual void dirtyLinesFromChangedChild(RenderObject* child) OVERRIDE FINAL { m_lineBoxes.dirtyLinesFromChangedChild(this, child); }
void addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild);
- void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild);
+ virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild) OVERRIDE;
void addChildToAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild);
void addChildIgnoringAnonymousColumnBlocks(RenderObject* newChild, RenderObject* beforeChild = 0);
- virtual bool isSelfCollapsingBlock() const OVERRIDE FINAL;
+ virtual bool isSelfCollapsingBlock() const OVERRIDE;
void insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
static void removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
- virtual RootInlineBox* createRootInlineBox() { return 0; } // Subclassed by RenderBlockFlow, SVG and Ruby.
-
- // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
- virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/, SubtreeLayoutScope&) { return 0; }
-
void createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild, unsigned length);
void updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer);
@@ -530,12 +383,11 @@ private:
void paintColumnContents(PaintInfo&, const LayoutPoint&, bool paintFloats = false);
void paintColumnRules(PaintInfo&, const LayoutPoint&);
void paintSelection(PaintInfo&, const LayoutPoint&);
- void paintCaret(PaintInfo&, const LayoutPoint&, CaretType);
+ void paintCarets(PaintInfo&, const LayoutPoint&);
- bool hasCaret() const { return hasCaret(CursorCaret) || hasCaret(DragCaret); }
- bool hasCaret(CaretType) const;
+ bool hasCaret() const;
- virtual bool avoidsFloats() const;
+ virtual bool avoidsFloats() const OVERRIDE;
bool hitTestColumns(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
bool hitTestContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
@@ -544,26 +396,23 @@ private:
virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
- // FIXME: Make this method const so we can remove the const_cast in computeIntrinsicLogicalWidths.
- void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
// Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
// children.
- virtual RenderBlock* firstLineBlock() const;
+ virtual RenderBlock* firstLineBlock() const OVERRIDE;
- virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const OVERRIDE FINAL;
- virtual RenderStyle* outlineStyleForRepaint() const OVERRIDE FINAL;
+ virtual LayoutRect rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth) const OVERRIDE FINAL;
+ virtual RenderStyle* outlineStyleForPaintInvalidation() const OVERRIDE FINAL;
virtual RenderObject* hoverAncestor() const OVERRIDE FINAL;
virtual void updateDragState(bool dragOn) OVERRIDE FINAL;
virtual void childBecameNonInline(RenderObject* child) OVERRIDE FINAL;
- virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool /*clipToVisibleContent*/) OVERRIDE FINAL
+ virtual LayoutRect selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, bool /*clipToVisibleContent*/) OVERRIDE FINAL
{
- return selectionGapRectsForRepaint(repaintContainer);
+ return selectionGapRectsForRepaint(paintInvalidationContainer);
}
- virtual bool shouldPaintSelectionGaps() const OVERRIDE FINAL;
bool isSelectionRoot() const;
GapRects selectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* = 0);
@@ -571,14 +420,14 @@ private:
LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
LayoutRect blockSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo*);
- LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
- LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
+ virtual LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
+ virtual LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position);
// FIXME-BLOCKFLOW: Remove virtualizaion when all callers have moved to RenderBlockFlow
virtual void clipOutFloatingObjects(RenderBlock*, const PaintInfo*, const LayoutPoint&, const LayoutSize&) { };
- virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
- virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
+ virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE;
+ virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE;
LayoutUnit desiredColumnWidth() const;
@@ -596,11 +445,9 @@ private:
Position positionForBox(InlineBox*, bool start = true) const;
PositionWithAffinity positionForPointWithInlineChildren(const LayoutPoint&);
- virtual void calcColumnWidth();
+ void calcColumnWidth();
void makeChildrenAnonymousColumnBlocks(RenderObject* beforeChild, RenderBlockFlow* newBlockBox, RenderObject* newChild);
- bool expandsToEncloseOverhangingFloats() const;
-
void splitBlocks(RenderBlock* fromBlock, RenderBlock* toBlock, RenderBlock* middleBlock,
RenderObject* beforeChild, RenderBoxModelObject* oldCont);
void splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox,
@@ -613,11 +460,6 @@ private:
// End helper functions and structs used by layoutBlockChildren.
protected:
- void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
-
- // Pagination routines.
- bool relayoutToAvoidWidows(LayoutStateMaintainer&);
-
// Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
// then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
// IncludePageBoundary set will not.
@@ -625,9 +467,8 @@ protected:
// For a page height of 800px, the first rule will return 800 if the value passed in is 0. The second rule will simply return 0.
enum PageBoundaryRule { ExcludePageBoundary, IncludePageBoundary };
LayoutUnit nextPageLogicalTop(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
- bool hasNextPage(LayoutUnit logicalOffset, PageBoundaryRule = ExcludePageBoundary) const;
- virtual ColumnInfo::PaginationUnit paginationUnit() const;
+ bool createsBlockFormattingContext() const;
public:
LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
@@ -635,8 +476,6 @@ public:
LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit offset, PageBoundaryRule = IncludePageBoundary) const;
protected:
- bool pushToNextPageWithMinimumLogicalHeight(LayoutUnit& adjustment, LayoutUnit logicalOffset, LayoutUnit minimumLogicalHeight) const;
-
// A page break is required at some offset due to space shortage in the current fragmentainer.
void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage);
@@ -647,19 +486,11 @@ protected:
LayoutUnit adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins = false); // If the child is unsplittable and can't fit on the current page, return the top of the next page/column.
void adjustLinePositionForPagination(RootInlineBox*, LayoutUnit& deltaOffset, RenderFlowThread*); // Computes a deltaOffset value that put a line at the top of the next page if it doesn't fit on the current page.
- void updateRegionForLine(RootInlineBox*) const;
// Adjust from painting offsets to the local coords of this renderer
void offsetForContents(LayoutPoint&) const;
- // This function is called to test a line box that has moved in the block direction to see if it has ended up in a new
- // region/page/column that has a different available line width than the old one. Used to know when you have to dirty a
- // line, i.e., that it can't be re-used.
- bool lineWidthForPaginatedLineChanged(RootInlineBox*, LayoutUnit lineDelta, RenderFlowThread*) const;
-
- bool logicalWidthChangedInRegions(RenderFlowThread*) const;
-
- virtual bool requiresColumns(int desiredColumnCount) const;
+ bool requiresColumns(int desiredColumnCount) const;
virtual bool updateLogicalWidthAndColumnWidth();
@@ -667,8 +498,6 @@ protected:
public:
virtual LayoutUnit offsetFromLogicalTopOfFirstPage() const OVERRIDE FINAL;
- RenderRegion* regionAtBlockOffset(LayoutUnit) const;
- RenderRegion* clampToStartAndEndRegions(RenderRegion*) const;
public:
@@ -687,9 +516,8 @@ public:
LayoutUnit m_paginationStrut;
LayoutUnit m_pageLogicalOffset;
- int m_lineBreakToAvoidWidow;
- OwnPtr<ShapeInsideInfo> m_shapeInsideInfo;
- bool m_didBreakAtLineToAvoidWidow : 1;
+ int m_lineBreakToAvoidWidow : 31;
+ unsigned m_didBreakAtLineToAvoidWidow : 1;
};
protected:
@@ -698,12 +526,13 @@ protected:
RenderObjectChildList m_children;
RenderLineBoxList m_lineBoxes; // All of the root line boxes created for this block flow. For example, <div>Hello<br>world.</div> will have two total lines for the <div>.
- mutable signed m_lineHeight : 27;
+ // WARNING: Don't add any bits here until we are comfortable that removing m_lineHeight has not regressed performance. See http://crrev.com/260073005 for more information.
unsigned m_hasMarginBeforeQuirk : 1; // Note these quirk values can't be put in RenderBlockRareData since they are set too frequently.
unsigned m_hasMarginAfterQuirk : 1;
unsigned m_beingDestroyed : 1;
unsigned m_hasMarkupTruncation : 1;
unsigned m_hasBorderOrPaddingLogicalWidthChanged : 1;
+ mutable unsigned m_hasOnlySelfCollapsingChildren : 1;
// RenderRubyBase objects need to be able to split and merge, moving their children around
// (calling moveChildTo, moveAllChildrenTo, and makeChildrenNonInline).
@@ -716,20 +545,6 @@ protected:
friend class RenderBlockFlow;
};
-
-inline bool RenderBlock::allowsShapeInsideInfoSharing(const RenderBlock* other) const
-{
- if (!other)
- return false;
- for (const RenderBlock* current = this; current && current != other && !current->isRenderFlowThread(); current = current->containingBlock()) {
- if (current->isInline() || current->isFloating())
- return false;
- if (current->parent() != current->containingBlock())
- return false;
- }
- return true;
-}
-
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBlock, isRenderBlock());
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.cpp
index 96725842afd..0a731d49857 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.cpp
@@ -31,19 +31,19 @@
#include "config.h"
#include "core/rendering/RenderBlockFlow.h"
+#include "core/accessibility/AXObjectCache.h"
#include "core/frame/FrameView.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/HitTestLocation.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
-#include "core/rendering/LineWidth.h"
+#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderNamedFlowFragment.h"
-#include "core/rendering/RenderNamedFlowThread.h"
+#include "core/rendering/RenderMultiColumnFlowThread.h"
#include "core/rendering/RenderText.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/line/LineWidth.h"
#include "core/rendering/svg/SVGTextRunRenderingContext.h"
-#include "platform/text/BidiResolver.h"
-#include "platform/text/TextRunIterator.h"
+#include "platform/text/BidiTextRun.h"
using namespace std;
@@ -63,6 +63,7 @@ class MarginInfo {
bool m_canCollapseWithChildren : 1;
bool m_canCollapseMarginBeforeWithChildren : 1;
bool m_canCollapseMarginAfterWithChildren : 1;
+ bool m_canCollapseMarginAfterWithLastChild: 1;
// Whether or not we are a quirky container, i.e., do we collapse away top and bottom
// margins in our container. Table cells and the body are the common examples. We
@@ -120,6 +121,7 @@ public:
void setMargin(LayoutUnit p, LayoutUnit n) { ASSERT(!m_discardMargin); m_positiveMargin = p; m_negativeMargin = n; }
void setCanCollapseMarginAfterWithChildren(bool collapse) { m_canCollapseMarginAfterWithChildren = collapse; }
+ void setCanCollapseMarginAfterWithLastChild(bool collapse) { m_canCollapseMarginAfterWithLastChild = collapse; }
void setDiscardMargin(bool value) { m_discardMargin = value; }
bool atBeforeSideOfBlock() const { return m_atBeforeSideOfBlock; }
@@ -127,6 +129,7 @@ public:
bool canCollapseWithMarginAfter() const { return m_atAfterSideOfBlock && m_canCollapseMarginAfterWithChildren; }
bool canCollapseMarginBeforeWithChildren() const { return m_canCollapseMarginBeforeWithChildren; }
bool canCollapseMarginAfterWithChildren() const { return m_canCollapseMarginAfterWithChildren; }
+ bool canCollapseMarginAfterWithLastChild() const { return m_canCollapseMarginAfterWithLastChild; }
bool quirkContainer() const { return m_quirkContainer; }
bool determinedMarginBeforeQuirk() const { return m_determinedMarginBeforeQuirk; }
bool hasMarginBeforeQuirk() const { return m_hasMarginBeforeQuirk; }
@@ -136,7 +139,6 @@ public:
bool discardMargin() const { return m_discardMargin; }
LayoutUnit margin() const { return m_positiveMargin - m_negativeMargin; }
};
-
static bool inNormalFlow(RenderBox* child)
{
RenderBlock* curr = child->containingBlock();
@@ -168,113 +170,187 @@ RenderBlockFlow* RenderBlockFlow::createAnonymous(Document* document)
return renderer;
}
-RenderBlockFlow* RenderBlockFlow::createAnonymousBlockFlow() const
+RenderObject* RenderBlockFlow::layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope& layoutScope)
{
- return toRenderBlockFlow(createAnonymousWithParentRendererAndDisplay(this, BLOCK));
+ RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread();
+ if (!flowThread)
+ return 0;
+ setLogicalTopForChild(flowThread, borderBefore() + paddingBefore());
+ flowThread->layoutColumns(relayoutChildren, layoutScope);
+ determineLogicalLeftPositionForChild(flowThread);
+ return flowThread;
}
-void RenderBlockFlow::willBeDestroyed()
+bool RenderBlockFlow::updateLogicalWidthAndColumnWidth()
{
- if (lineGridBox())
- lineGridBox()->destroy();
+ bool relayoutChildren = RenderBlock::updateLogicalWidthAndColumnWidth();
+ if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
+ if (flowThread->needsNewWidth())
+ return true;
+ }
+ return relayoutChildren;
+}
+
+void RenderBlockFlow::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight)
+{
+ if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
+ LogicalExtentComputedValues computedValues;
+ computeLogicalHeight(LayoutUnit(), logicalTop(), computedValues);
+ LayoutUnit columnHeight = computedValues.m_extent - borderAndPaddingLogicalHeight() - scrollbarLogicalHeight();
+ pageLogicalHeightChanged = columnHeight != flowThread->columnHeightAvailable();
+ flowThread->setColumnHeightAvailable(std::max<LayoutUnit>(columnHeight, 0));
+ } else if (hasColumns()) {
+ ColumnInfo* colInfo = columnInfo();
+
+ if (!pageLogicalHeight) {
+ LayoutUnit oldLogicalHeight = logicalHeight();
+ setLogicalHeight(0);
+ // We need to go ahead and set our explicit page height if one exists, so that we can
+ // avoid doing two layout passes.
+ updateLogicalHeight();
+ LayoutUnit columnHeight = contentLogicalHeight();
+ if (columnHeight > 0) {
+ pageLogicalHeight = columnHeight;
+ hasSpecifiedPageLogicalHeight = true;
+ }
+ setLogicalHeight(oldLogicalHeight);
+ }
+ if (colInfo->columnHeight() != pageLogicalHeight && everHadLayout()) {
+ colInfo->setColumnHeight(pageLogicalHeight);
+ pageLogicalHeightChanged = true;
+ }
- if (renderNamedFlowFragment())
- setRenderNamedFlowFragment(0);
+ if (!hasSpecifiedPageLogicalHeight && !pageLogicalHeight)
+ colInfo->clearForcedBreaks();
+ } else if (isRenderFlowThread()) {
+ RenderFlowThread* flowThread = toRenderFlowThread(this);
- RenderBlock::willBeDestroyed();
+ // FIXME: This is a hack to always make sure we have a page logical height, if said height
+ // is known. The page logical height thing in LayoutState is meaningless for flow
+ // thread-based pagination (page height isn't necessarily uniform throughout the flow
+ // thread), but as long as it is used universally as a means to determine whether page
+ // height is known or not, we need this. Page height is unknown when column balancing is
+ // enabled and flow thread height is still unknown (i.e. during the first layout pass). When
+ // it's unknown, we need to prevent the pagination code from assuming page breaks everywhere
+ // and thereby eating every top margin. It should be trivial to clean up and get rid of this
+ // hack once the old multicol implementation is gone.
+ pageLogicalHeight = flowThread->isPageLogicalHeightKnown() ? LayoutUnit(1) : LayoutUnit(0);
+
+ pageLogicalHeightChanged = flowThread->pageLogicalSizeChanged();
+ }
}
-bool RenderBlockFlow::relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer& statePusher)
+bool RenderBlockFlow::shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight, LayoutUnit layoutOverflowLogicalBottom) const
{
- if (!hasColumns())
- return false;
-
- OwnPtr<RenderOverflow> savedOverflow = m_overflow.release();
- if (childrenInline())
- addOverflowFromInlineChildren();
- else
- addOverflowFromBlockChildren();
- LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? layoutOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - paddingBefore();
-
// FIXME: We don't balance properly at all in the presence of forced page breaks. We need to understand what
// the distance between forced page breaks is so that we can avoid making the minimum column height too tall.
ColumnInfo* colInfo = columnInfo();
- if (!hasSpecifiedPageLogicalHeight) {
- LayoutUnit columnHeight = pageLogicalHeight;
- int minColumnCount = colInfo->forcedBreaks() + 1;
- int desiredColumnCount = colInfo->desiredColumnCount();
- if (minColumnCount >= desiredColumnCount) {
- // The forced page breaks are in control of the balancing. Just set the column height to the
- // maximum page break distance.
- if (!pageLogicalHeight) {
- LayoutUnit distanceBetweenBreaks = max<LayoutUnit>(colInfo->maximumDistanceBetweenForcedBreaks(),
- view()->layoutState()->pageLogicalOffset(this, borderBefore() + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset());
- columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
- }
- } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeight, desiredColumnCount)) {
- // Now that we know the intrinsic height of the columns, we have to rebalance them.
- columnHeight = max<LayoutUnit>(colInfo->minimumColumnHeight(), ceilf((float)layoutOverflowLogicalBottom / desiredColumnCount));
+ LayoutUnit columnHeight = pageLogicalHeight;
+ const int minColumnCount = colInfo->forcedBreaks() + 1;
+ const int desiredColumnCount = colInfo->desiredColumnCount();
+ if (minColumnCount >= desiredColumnCount) {
+ // The forced page breaks are in control of the balancing. Just set the column height to the
+ // maximum page break distance.
+ if (!pageLogicalHeight) {
+ LayoutUnit distanceBetweenBreaks = max<LayoutUnit>(colInfo->maximumDistanceBetweenForcedBreaks(),
+ view()->layoutState()->pageLogicalOffset(*this, borderBefore() + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset());
+ columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
}
+ } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeight, desiredColumnCount)) {
+ // Now that we know the intrinsic height of the columns, we have to rebalance them.
+ columnHeight = max<LayoutUnit>(colInfo->minimumColumnHeight(), ceilf(layoutOverflowLogicalBottom.toFloat() / desiredColumnCount));
+ }
- if (columnHeight && columnHeight != pageLogicalHeight) {
- statePusher.pop();
- setEverHadLayout(true);
- layoutBlock(false, columnHeight);
- return true;
- }
+ if (columnHeight && columnHeight != pageLogicalHeight) {
+ pageLogicalHeight = columnHeight;
+ return true;
}
+ return false;
+}
+
+void RenderBlockFlow::setColumnCountAndHeight(unsigned count, LayoutUnit pageLogicalHeight)
+{
+ ColumnInfo* colInfo = columnInfo();
if (pageLogicalHeight)
- colInfo->setColumnCountAndHeight(ceilf((float)layoutOverflowLogicalBottom / pageLogicalHeight), pageLogicalHeight);
+ colInfo->setColumnCountAndHeight(count, pageLogicalHeight);
if (columnCount(colInfo)) {
setLogicalHeight(borderBefore() + paddingBefore() + colInfo->columnHeight() + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
m_overflow.clear();
- } else {
- m_overflow = savedOverflow.release();
}
+}
- return false;
+bool RenderBlockFlow::isSelfCollapsingBlock() const
+{
+ m_hasOnlySelfCollapsingChildren = RenderBlock::isSelfCollapsingBlock();
+ return m_hasOnlySelfCollapsingChildren;
}
-void RenderBlockFlow::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
+void RenderBlockFlow::layoutBlock(bool relayoutChildren)
{
ASSERT(needsLayout());
+ ASSERT(isInlineBlockOrInlineTable() || !isInline());
- if (isInline() && !isInlineBlockOrInlineTable()) // Inline <form>s inside various table elements can cause us to come in here. Bail.
- return;
+ // If we are self-collapsing with self-collapsing descendants this will get set to save us burrowing through our
+ // descendants every time in |isSelfCollapsingBlock|. We reset it here so that |isSelfCollapsingBlock| attempts to burrow
+ // at least once and so that it always gives a reliable result reflecting the latest layout.
+ m_hasOnlySelfCollapsingChildren = false;
if (!relayoutChildren && simplifiedLayout())
return;
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+ SubtreeLayoutScope layoutScope(*this);
+
+ // Multiple passes might be required for column and pagination based layout
+ // In the case of the old column code the number of passes will only be two
+ // however, in the newer column code the number of passes could equal the
+ // number of columns.
+ bool done = false;
+ LayoutUnit pageLogicalHeight = 0;
+ LayoutRepainter repainter(*this, checkForPaintInvalidationDuringLayout());
+ while (!done)
+ done = layoutBlockFlow(relayoutChildren, pageLogicalHeight, layoutScope);
+
+ fitBorderToLinesIfNeeded();
+
+ RenderView* renderView = view();
+ if (renderView->layoutState()->pageLogicalHeight())
+ setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(*this, logicalTop()));
+
+ updateLayerTransformAfterLayout();
+
+ // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
+ // we overflow or not.
+ updateScrollInfoAfterLayout();
+
+ // Repaint with our new bounds if they are different from our old bounds.
+ bool didFullRepaint = repainter.repaintAfterLayout();
+ if (!didFullRepaint && m_repaintLogicalTop != m_repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ setShouldInvalidateOverflowForPaint(true);
+ else
+ invalidatePaintForOverflow();
+ }
+ clearNeedsLayout();
+}
+inline bool RenderBlockFlow::layoutBlockFlow(bool relayoutChildren, LayoutUnit &pageLogicalHeight, SubtreeLayoutScope& layoutScope)
+{
+ LayoutUnit oldLeft = logicalLeft();
if (updateLogicalWidthAndColumnWidth())
relayoutChildren = true;
rebuildFloatsFromIntruding();
- LayoutUnit previousHeight = logicalHeight();
- // FIXME: should this start out as borderAndPaddingLogicalHeight() + scrollbarLogicalHeight(),
- // for consistency with other render classes?
- setLogicalHeight(0);
-
bool pageLogicalHeightChanged = false;
bool hasSpecifiedPageLogicalHeight = false;
checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightChanged, hasSpecifiedPageLogicalHeight);
-
- RenderView* renderView = view();
- LayoutStateMaintainer statePusher(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo());
-
- // Regions changing widths can force us to relayout our children.
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (logicalWidthChangedInRegions(flowThread))
- relayoutChildren = true;
- if (updateRegionsAndShapesLogicalSize(flowThread))
- relayoutChildren = true;
- if (!relayoutChildren && isRenderNamedFlowFragmentContainer())
+ if (pageLogicalHeightChanged)
relayoutChildren = true;
+ LayoutState state(*this, locationOffset(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo());
+
// We use four values, maxTopPos, maxTopNeg, maxBottomPos, and maxBottomNeg, to track
// our current maximal positive and negative margins. These values are used when we
// are collapsed with adjacent blocks, so for example, if you have block A and B
@@ -285,62 +361,75 @@ void RenderBlockFlow::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalH
//
// Start out by setting our margin values to our current margins. Table cells have
// no margins, so we don't fill in the values for table cells.
- bool isCell = isTableCell();
- if (!isCell) {
+ if (!isTableCell()) {
initMaxMarginValues();
-
setHasMarginBeforeQuirk(style()->hasMarginBeforeQuirk());
setHasMarginAfterQuirk(style()->hasMarginAfterQuirk());
setPaginationStrut(0);
}
- SubtreeLayoutScope layoutScope(this);
+ LayoutUnit beforeEdge = borderBefore() + paddingBefore();
+ LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
+ LayoutUnit previousHeight = logicalHeight();
+ setLogicalHeight(beforeEdge);
m_repaintLogicalTop = 0;
m_repaintLogicalBottom = 0;
- LayoutUnit maxFloatLogicalBottom = 0;
if (!firstChild() && !isAnonymousBlock())
setChildrenInline(true);
+
+ FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
+
if (childrenInline())
- layoutInlineChildren(relayoutChildren, m_repaintLogicalTop, m_repaintLogicalBottom);
+ layoutInlineChildren(relayoutChildren, m_repaintLogicalTop, m_repaintLogicalBottom, afterEdge);
else
- layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom, layoutScope);
-
- if (frameView()->partialLayout().isStopping()) {
- statePusher.pop();
- return;
- }
+ layoutBlockChildren(relayoutChildren, layoutScope, beforeEdge, afterEdge);
// Expand our intrinsic height to encompass floats.
- LayoutUnit toAdd = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
- if (lowestFloatLogicalBottom() > (logicalHeight() - toAdd) && expandsToEncloseOverhangingFloats())
- setLogicalHeight(lowestFloatLogicalBottom() + toAdd);
+ if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsBlockFormattingContext())
+ setLogicalHeight(lowestFloatLogicalBottom() + afterEdge);
- if (relayoutForPagination(hasSpecifiedPageLogicalHeight, pageLogicalHeight, statePusher) || relayoutToAvoidWidows(statePusher)) {
- ASSERT(!shouldBreakAtLineToAvoidWidow());
- return;
+ if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
+ if (flowThread->recalculateColumnHeights()) {
+ setChildNeedsLayout(MarkOnlyThis);
+ return false;
+ }
+ } else if (hasColumns()) {
+ OwnPtr<RenderOverflow> savedOverflow = m_overflow.release();
+ if (childrenInline())
+ addOverflowFromInlineChildren();
+ else
+ addOverflowFromBlockChildren();
+ LayoutUnit layoutOverflowLogicalBottom = (isHorizontalWritingMode() ? layoutOverflowRect().maxY() : layoutOverflowRect().maxX()) - borderBefore() - paddingBefore();
+ m_overflow = savedOverflow.release();
+
+ if (!hasSpecifiedPageLogicalHeight && shouldRelayoutForPagination(pageLogicalHeight, layoutOverflowLogicalBottom)) {
+ setEverHadLayout(true);
+ return false;
+ }
+
+ setColumnCountAndHeight(ceilf(layoutOverflowLogicalBottom.toFloat() / pageLogicalHeight.toFloat()), pageLogicalHeight.toFloat());
+ }
+
+ if (shouldBreakAtLineToAvoidWidow()) {
+ setEverHadLayout(true);
+ return false;
}
// Calculate our new height.
LayoutUnit oldHeight = logicalHeight();
LayoutUnit oldClientAfterEdge = clientLogicalBottom();
- // Before updating the final size of the flow thread make sure a forced break is applied after the content.
- // This ensures the size information is correctly computed for the last auto-height region receiving content.
- if (isRenderFlowThread())
- toRenderFlowThread(this)->applyBreakAfterContent(oldClientAfterEdge);
-
updateLogicalHeight();
LayoutUnit newHeight = logicalHeight();
- if (oldHeight != newHeight) {
- if (oldHeight > newHeight && maxFloatLogicalBottom > newHeight && !childrenInline()) {
- // One of our children's floats may have become an overhanging float for us. We need to look for it.
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (child->isRenderBlockFlow() && !child->isFloatingOrOutOfFlowPositioned()) {
- RenderBlockFlow* block = toRenderBlockFlow(child);
- if (block->lowestFloatLogicalBottom() + block->logicalTop() > newHeight)
- addOverhangingFloats(block, false);
- }
+ if (oldHeight > newHeight && !childrenInline()) {
+ // One of our children's floats may have become an overhanging float for us.
+ for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
+ if (child->isRenderBlockFlow() && !child->isFloatingOrOutOfFlowPositioned()) {
+ RenderBlockFlow* block = toRenderBlockFlow(child);
+ if (block->lowestFloatLogicalBottom() + block->logicalTop() <= newHeight)
+ break;
+ addOverhangingFloats(block, false);
}
}
}
@@ -349,42 +438,62 @@ void RenderBlockFlow::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalH
if (heightChanged)
relayoutChildren = true;
- layoutPositionedObjects(relayoutChildren || isRoot());
+ layoutPositionedObjects(relayoutChildren || isDocumentElement(), oldLeft != logicalLeft() ? ForcedLayoutAfterContainingBlockMoved : DefaultLayout);
- updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged);
+ computeRegionRangeForBlock(flowThreadContainingBlock());
// Add overflow from children (unless we're multi-column, since in that case all our child overflow is clipped anyway).
computeOverflow(oldClientAfterEdge);
- statePusher.pop();
-
- fitBorderToLinesIfNeeded();
+ return true;
+}
- if (frameView()->partialLayout().isStopping())
- return;
+void RenderBlockFlow::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode applyDelta)
+{
+ LayoutUnit startPosition = borderStart() + paddingStart();
+ if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+ startPosition -= verticalScrollbarWidth();
+ LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
- if (renderView->layoutState()->m_pageLogicalHeight)
- setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop()));
+ // Add in our start margin.
+ LayoutUnit childMarginStart = marginStartForChild(child);
+ LayoutUnit newPosition = startPosition + childMarginStart;
- updateLayerTransform();
+ // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need
+ // to shift over as necessary to dodge any floats that might get in the way.
+ if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock())
+ newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
- // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
- // we overflow or not.
- updateScrollInfoAfterLayout();
+ setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
+}
- // Repaint with our new bounds if they are different from our old bounds.
- bool didFullRepaint = repainter.repaintAfterLayout();
- if (!didFullRepaint && m_repaintLogicalTop != m_repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
- if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
- setShouldRepaintOverflowIfNeeded(true);
- else
- repaintOverflow();
+void RenderBlockFlow::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
+{
+ if (isHorizontalWritingMode()) {
+ if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ view()->addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
+ child->setX(logicalLeft);
+ } else {
+ if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ view()->addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
+ child->setY(logicalLeft);
}
+}
- clearNeedsLayout();
+void RenderBlockFlow::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
+{
+ if (isHorizontalWritingMode()) {
+ if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ view()->addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
+ child->setY(logicalTop);
+ } else {
+ if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ view()->addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
+ child->setX(logicalTop);
+ }
}
-void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
+void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom)
{
LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
LayoutUnit oldNegMarginBefore = maxNegativeMarginBefore();
@@ -402,8 +511,8 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo,
LayoutRect oldRect = child->frameRect();
LayoutUnit oldLogicalTop = logicalTopForChild(child);
-#if !ASSERT_DISABLED
- LayoutSize oldLayoutDelta = view()->layoutDelta();
+#if ASSERT_ENABLED
+ LayoutSize oldLayoutDelta = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : view()->layoutDelta();
#endif
// Go ahead and position the child as though it didn't collapse with the top.
setLogicalTopForChild(child, logicalTopEstimate, ApplyLayoutDelta);
@@ -434,7 +543,7 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo,
previousFloatLogicalBottom = max(previousFloatLogicalBottom, oldLogicalTop + childRenderBlockFlow->lowestFloatLogicalBottom());
}
- SubtreeLayoutScope layoutScope(child);
+ SubtreeLayoutScope layoutScope(*child);
if (!child->needsLayout())
child->markForPaginationRelayoutIfNeeded(layoutScope);
@@ -443,18 +552,16 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo,
if (childNeededLayout)
child->layout();
- if (frameView()->partialLayout().isStopping())
- return;
-
// Cache if we are at the top of the block right now.
bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
+ bool childIsSelfCollapsing = child->isSelfCollapsingBlock();
// Now determine the correct ypos based off examination of collapsing margin
// values.
- LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo);
+ LayoutUnit logicalTopBeforeClear = collapseMargins(child, marginInfo, childIsSelfCollapsing);
// Now check for clear.
- LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear);
+ LayoutUnit logicalTopAfterClear = clearFloatsIfNeeded(child, marginInfo, oldPosMarginBefore, oldNegMarginBefore, logicalTopBeforeClear, childIsSelfCollapsing);
bool paginated = view()->layoutState()->isPaginated();
if (paginated) {
@@ -468,7 +575,7 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo,
// clearFloatsIfNeeded can also mark the child as needing a layout even though we didn't move. This happens
// when collapseMargins dynamically adds overhanging floats because of a child with negative margins.
if (logicalTopAfterClear != logicalTopEstimate || child->needsLayout() || (paginated && childRenderBlock && childRenderBlock->shouldBreakAtLineToAvoidWidow())) {
- SubtreeLayoutScope layoutScope(child);
+ SubtreeLayoutScope layoutScope(*child);
if (child->shrinkToAvoidFloats()) {
// The child's width depends on the line width.
// When the child shifts to clear an item, its width can
@@ -488,16 +595,22 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo,
child->layoutIfNeeded();
}
+ // If we previously encountered a self-collapsing sibling of this child that had clearance then
+ // we set this bit to ensure we would not collapse the child's margins, and those of any subsequent
+ // self-collapsing siblings, with our parent. If this child is not self-collapsing then it can
+ // collapse its margins with the parent so reset the bit.
+ if (!marginInfo.canCollapseMarginAfterWithLastChild() && !childIsSelfCollapsing)
+ marginInfo.setCanCollapseMarginAfterWithLastChild(true);
+
// We are no longer at the top of the block if we encounter a non-empty child.
// This has to be done after checking for clear, so that margins can be reset if a clear occurred.
- if (marginInfo.atBeforeSideOfBlock() && !child->isSelfCollapsingBlock())
+ if (marginInfo.atBeforeSideOfBlock() && !childIsSelfCollapsing)
marginInfo.setAtBeforeSideOfBlock(false);
// Now place the child in the correct left position
determineLogicalLeftPositionForChild(child, ApplyLayoutDelta);
LayoutSize childOffset = child->location() - oldRect.location();
- relayoutShapeDescendantIfMoved(childRenderBlock, childOffset);
// Update our height now that the child has been placed in the correct position.
setLogicalHeight(logicalHeight() + logicalHeightForChild(child));
@@ -507,24 +620,25 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo,
}
// If the child has overhanging floats that intrude into following siblings (or possibly out
// of this block), then the parent gets notified of the floats now.
- if (childRenderBlockFlow && childRenderBlockFlow->containsFloats())
- maxFloatLogicalBottom = max(maxFloatLogicalBottom, addOverhangingFloats(childRenderBlockFlow, !childNeededLayout));
+ if (childRenderBlockFlow)
+ addOverhangingFloats(childRenderBlockFlow, !childNeededLayout);
if (childOffset.width() || childOffset.height()) {
- view()->addLayoutDelta(childOffset);
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ view()->addLayoutDelta(childOffset);
// If the child moved, we have to repaint it as well as any floating/positioned
// descendants. An exception is if we need a layout. In this case, we know we're going to
// repaint ourselves (and the child) anyway.
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && childHadLayout && !selfNeedsLayout())
child->repaintOverhangingFloats(true);
- else if (childHadLayout && !selfNeedsLayout() && child->checkForRepaintDuringLayout())
+ else if (childHadLayout && !selfNeedsLayout() && child->checkForPaintInvalidationDuringLayout())
child->repaintDuringLayoutIfMoved(oldRect);
}
- if (!childHadLayout && child->checkForRepaintDuringLayout()) {
+ if (!childHadLayout && child->checkForPaintInvalidation()) {
if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
- child->repaint();
+ child->paintInvalidationForWholeRenderer();
child->repaintOverhangingFloats(true);
}
@@ -535,7 +649,9 @@ void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo,
setLogicalHeight(newHeight);
}
- ASSERT(view()->layoutDeltaMatches(oldLayoutDelta));
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ ASSERT(view()->layoutDeltaMatches(oldLayoutDelta));
+ }
}
LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopAfterClear, LayoutUnit estimateWithoutPagination, RenderBox* child, bool atBeforeSideOfBlock)
@@ -556,7 +672,7 @@ LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopA
child->setChildNeedsLayout(MarkOnlyThis);
}
- SubtreeLayoutScope layoutScope(child);
+ SubtreeLayoutScope layoutScope(*child);
if (childRenderBlock) {
if (!child->avoidsFloats() && childRenderBlock->containsFloats())
@@ -574,31 +690,19 @@ LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopA
// If the object has a page or column break value of "before", then we should shift to the top of the next page.
LayoutUnit result = applyBeforeBreak(child, logicalTopAfterClear);
- if (pageLogicalHeightForOffset(result)) {
- LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(result, ExcludePageBoundary);
- LayoutUnit spaceShortage = child->logicalHeight() - remainingLogicalHeight;
- if (spaceShortage > 0) {
- // If the child crosses a column boundary, report a break, in case nothing inside it has already
- // done so. The column balancer needs to know how much it has to stretch the columns to make more
- // content fit. If no breaks are reported (but do occur), the balancer will have no clue. FIXME:
- // This should be improved, though, because here we just pretend that the child is
- // unsplittable. A splittable child, on the other hand, has break opportunities at every position
- // where there's no child content, border or padding. In other words, we risk stretching more
- // than necessary.
- setPageBreak(result, spaceShortage);
- }
- }
-
// For replaced elements and scrolled elements, we want to shift them to the next page if they don't fit on the current one.
LayoutUnit logicalTopBeforeUnsplittableAdjustment = result;
LayoutUnit logicalTopAfterUnsplittableAdjustment = adjustForUnsplittableChild(child, result);
LayoutUnit paginationStrut = 0;
LayoutUnit unsplittableAdjustmentDelta = logicalTopAfterUnsplittableAdjustment - logicalTopBeforeUnsplittableAdjustment;
- if (unsplittableAdjustmentDelta)
+ LayoutUnit childLogicalHeight = child->logicalHeight();
+ if (unsplittableAdjustmentDelta) {
+ setPageBreak(result, childLogicalHeight - unsplittableAdjustmentDelta);
paginationStrut = unsplittableAdjustmentDelta;
- else if (childRenderBlock && childRenderBlock->paginationStrut())
+ } else if (childRenderBlock && childRenderBlock->paginationStrut()) {
paginationStrut = childRenderBlock->paginationStrut();
+ }
if (paginationStrut) {
// We are willing to propagate out to our parent block as long as we were at the top of the block prior
@@ -615,6 +719,27 @@ LayoutUnit RenderBlockFlow::adjustBlockChildForPagination(LayoutUnit logicalTopA
}
}
+ if (!unsplittableAdjustmentDelta) {
+ if (LayoutUnit pageLogicalHeight = pageLogicalHeightForOffset(result)) {
+ LayoutUnit remainingLogicalHeight = pageRemainingLogicalHeightForOffset(result, ExcludePageBoundary);
+ LayoutUnit spaceShortage = childLogicalHeight - remainingLogicalHeight;
+ if (spaceShortage > 0) {
+ // If the child crosses a column boundary, report a break, in case nothing inside it
+ // has already done so. The column balancer needs to know how much it has to stretch
+ // the columns to make more content fit. If no breaks are reported (but do occur),
+ // the balancer will have no clue. Only measure the space after the last column
+ // boundary, in case it crosses more than one.
+ LayoutUnit spaceShortageInLastColumn = intMod(spaceShortage, pageLogicalHeight);
+ setPageBreak(result, spaceShortageInLastColumn ? spaceShortageInLastColumn : spaceShortage);
+ } else if (remainingLogicalHeight == pageLogicalHeight && offsetFromLogicalTopOfFirstPage() + child->logicalTop()) {
+ // We're at the very top of a page or column, and it's not the first one. This child
+ // may turn out to be the smallest piece of content that causes a page break, so we
+ // need to report it.
+ setPageBreak(result, childLogicalHeight);
+ }
+ }
+ }
+
// Similar to how we apply clearance. Go ahead and boost height() to be the place where we're going to position the child.
setLogicalHeight(logicalHeight() + (result - oldTop));
@@ -632,14 +757,14 @@ void RenderBlockFlow::rebuildFloatsFromIntruding()
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (!floatingObject->isDescendant())
oldIntrudingFloatSet.add(floatingObject->renderer());
}
}
// Inline blocks are covered by the isReplaced() check in the avoidFloats method.
- if (avoidsFloats() || isRoot() || isRenderView() || isFloatingOrOutOfFlowPositioned() || isTableCell()) {
+ if (avoidsFloats() || isDocumentElement() || isRenderView() || isFloatingOrOutOfFlowPositioned() || isTableCell()) {
if (m_floatingObjects) {
m_floatingObjects->clear();
}
@@ -663,13 +788,13 @@ void RenderBlockFlow::rebuildFloatsFromIntruding()
if (!parent() || !parent()->isRenderBlockFlow())
return;
- // Attempt to locate a previous sibling with overhanging floats. We skip any elements that are
- // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted
- // to avoid floats.
+ // Attempt to locate a previous sibling with overhanging floats. We skip any elements that
+ // may have shifted to avoid floats, and any objects whose floats cannot interact with objects
+ // outside it (i.e. objects that create a new block formatting context).
RenderBlockFlow* parentBlockFlow = toRenderBlockFlow(parent());
bool parentHasFloats = false;
RenderObject* prev = previousSibling();
- while (prev && (prev->isFloatingOrOutOfFlowPositioned() || !prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats())) {
+ while (prev && (!prev->isBox() || !prev->isRenderBlock() || toRenderBlock(prev)->avoidsFloats() || toRenderBlock(prev)->createsBlockFormattingContext())) {
if (prev->isFloating())
parentHasFloats = true;
prev = prev->previousSibling();
@@ -678,22 +803,18 @@ void RenderBlockFlow::rebuildFloatsFromIntruding()
// First add in floats from the parent. Self-collapsing blocks let their parent track any floats that intrude into
// them (as opposed to floats they contain themselves) so check for those here too.
LayoutUnit logicalTopOffset = logicalTop();
- if (parentHasFloats || (prev && toRenderBlockFlow(prev)->isSelfCollapsingBlock() && parentBlockFlow->lowestFloatLogicalBottom() > logicalTopOffset))
+ bool parentHasIntrudingFloats = !parentHasFloats && (!prev || toRenderBlockFlow(prev)->isSelfCollapsingBlock()) && parentBlockFlow->lowestFloatLogicalBottom() > logicalTopOffset;
+ if (parentHasFloats || parentHasIntrudingFloats)
addIntrudingFloats(parentBlockFlow, parentBlockFlow->logicalLeftOffsetForContent(), logicalTopOffset);
- LayoutUnit logicalLeftOffset = 0;
+ // Add overhanging floats from the previous RenderBlockFlow, but only if it has a float that intrudes into our space.
if (prev) {
- logicalTopOffset -= toRenderBox(prev)->logicalTop();
- } else {
- prev = parentBlockFlow;
- logicalLeftOffset += parentBlockFlow->logicalLeftOffsetForContent();
+ RenderBlockFlow* blockFlow = toRenderBlockFlow(prev);
+ logicalTopOffset -= blockFlow->logicalTop();
+ if (blockFlow->lowestFloatLogicalBottom() > logicalTopOffset)
+ addIntrudingFloats(blockFlow, 0, logicalTopOffset);
}
- // Add overhanging floats from the previous RenderBlockFlow, but only if it has a float that intrudes into our space.
- RenderBlockFlow* blockFlow = toRenderBlockFlow(prev);
- if (blockFlow->m_floatingObjects && blockFlow->lowestFloatLogicalBottom() > logicalTopOffset)
- addIntrudingFloats(blockFlow, logicalLeftOffset, logicalTopOffset);
-
if (childrenInline()) {
LayoutUnit changeLogicalTop = LayoutUnit::max();
LayoutUnit changeLogicalBottom = LayoutUnit::min();
@@ -701,7 +822,7 @@ void RenderBlockFlow::rebuildFloatsFromIntruding()
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
FloatingObject* oldFloatingObject = floatMap.get(floatingObject->renderer());
LayoutUnit logicalBottom = logicalBottomForFloat(floatingObject);
if (oldFloatingObject) {
@@ -722,12 +843,12 @@ void RenderBlockFlow::rebuildFloatsFromIntruding()
}
}
- floatMap.remove(floatingObject->renderer());
if (oldFloatingObject->originatingLine() && !selfNeedsLayout()) {
ASSERT(oldFloatingObject->originatingLine()->renderer() == this);
oldFloatingObject->originatingLine()->markDirty();
}
- delete oldFloatingObject;
+
+ floatMap.remove(floatingObject->renderer());
} else {
changeLogicalTop = 0;
changeLogicalBottom = max(changeLogicalBottom, logicalBottom);
@@ -737,13 +858,12 @@ void RenderBlockFlow::rebuildFloatsFromIntruding()
RendererToFloatInfoMap::iterator end = floatMap.end();
for (RendererToFloatInfoMap::iterator it = floatMap.begin(); it != end; ++it) {
- FloatingObject* floatingObject = (*it).value;
+ OwnPtr<FloatingObject>& floatingObject = it->value;
if (!floatingObject->isDescendant()) {
changeLogicalTop = 0;
- changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject));
+ changeLogicalBottom = max(changeLogicalBottom, logicalBottomForFloat(floatingObject.get()));
}
}
- deleteAllValues(floatMap);
markLinesDirtyInBlockRange(changeLogicalTop, changeLogicalBottom);
} else if (!oldIntrudingFloatSet.isEmpty()) {
@@ -762,19 +882,10 @@ void RenderBlockFlow::rebuildFloatsFromIntruding()
}
}
-void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom, SubtreeLayoutScope& layoutScope)
+void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, SubtreeLayoutScope& layoutScope, LayoutUnit beforeEdge, LayoutUnit afterEdge)
{
dirtyForLayoutFromPercentageHeightDescendants(layoutScope);
- LayoutUnit beforeEdge = borderBefore() + paddingBefore();
- LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
-
- setLogicalHeight(beforeEdge);
-
- // Lay out our hypothetical grid line as though it occurs at the top of the block.
- if (view()->layoutState()->lineGrid() == this)
- layoutLineGridBox();
-
// The margin struct caches all our current margin collapsing state. The compact struct caches state when we encounter compacts,
MarginInfo marginInfo(this, beforeEdge, afterEdge);
@@ -784,15 +895,16 @@ void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& max
RenderObject* childToExclude = layoutSpecialExcludedChild(relayoutChildren, layoutScope);
LayoutUnit previousFloatLogicalBottom = 0;
- maxFloatLogicalBottom = 0;
RenderBox* next = firstChildBox();
+ RenderBox* lastNormalFlowChild = 0;
while (next) {
RenderBox* child = next;
next = child->nextSiblingBox();
- LayoutRectRecorder recorder(*child);
+ // FIXME: this should only be set from clearNeedsLayout crbug.com/361250
+ child->setLayoutDidGetCalled(true);
if (childToExclude == child)
continue; // Skip this child, since it will be positioned by the specialized subclass (fieldsets and ruby runs).
@@ -811,21 +923,19 @@ void RenderBlockFlow::layoutBlockChildren(bool relayoutChildren, LayoutUnit& max
}
// Lay out the child.
- layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
-
- // If doing a partial layout and the child was the target renderer, early exit here.
- if (frameView()->partialLayout().checkPartialLayoutComplete(child))
- break;
+ layoutBlockChild(child, marginInfo, previousFloatLogicalBottom);
+ lastNormalFlowChild = child;
}
// Now do the handling of the bottom of the block, adding in our bottom border/padding and
// determining the correct collapsed bottom margin information.
- handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
+ handleAfterSideOfBlock(lastNormalFlowChild, beforeEdge, afterEdge, marginInfo);
}
// Our MarginInfo state used when laying out block children.
MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPadding, LayoutUnit afterBorderPadding)
- : m_atBeforeSideOfBlock(true)
+ : m_canCollapseMarginAfterWithLastChild(true)
+ , m_atBeforeSideOfBlock(true)
, m_atAfterSideOfBlock(false)
, m_hasMarginBeforeQuirk(false)
, m_hasMarginAfterQuirk(false)
@@ -834,10 +944,7 @@ MarginInfo::MarginInfo(RenderBlockFlow* blockFlow, LayoutUnit beforeBorderPaddin
{
RenderStyle* blockStyle = blockFlow->style();
ASSERT(blockFlow->isRenderView() || blockFlow->parent());
- m_canCollapseWithChildren = !blockFlow->isRenderView() && !blockFlow->isRoot() && !blockFlow->isOutOfFlowPositioned()
- && !blockFlow->isFloating() && !blockFlow->isTableCell() && !blockFlow->hasOverflowClip() && !blockFlow->isInlineBlockOrInlineTable()
- && !blockFlow->isRenderFlowThread() && !blockFlow->isWritingModeRoot() && !blockFlow->parent()->isFlexibleBox()
- && blockStyle->hasAutoColumnCount() && blockStyle->hasAutoColumnWidth() && !blockStyle->columnSpan();
+ m_canCollapseWithChildren = !blockFlow->createsBlockFormattingContext() && !blockFlow->isRenderFlowThread() && !blockFlow->isRenderView();
m_canCollapseMarginBeforeWithChildren = m_canCollapseWithChildren && !beforeBorderPadding && blockStyle->marginBeforeCollapse() != MSEPARATE;
@@ -916,11 +1023,10 @@ RenderBlockFlow::MarginValues RenderBlockFlow::marginValuesForChild(RenderBox* c
return RenderBlockFlow::MarginValues(childBeforePositive, childBeforeNegative, childAfterPositive, childAfterNegative);
}
-LayoutUnit RenderBlockFlow::collapseMargins(RenderBox* child, MarginInfo& marginInfo)
+LayoutUnit RenderBlockFlow::collapseMargins(RenderBox* child, MarginInfo& marginInfo, bool childIsSelfCollapsing)
{
bool childDiscardMarginBefore = mustDiscardMarginBeforeForChild(child);
bool childDiscardMarginAfter = mustDiscardMarginAfterForChild(child);
- bool childIsSelfCollapsing = child->isSelfCollapsingBlock();
// The child discards the before margin when the the after margin has discard in the case of a self collapsing block.
childDiscardMarginBefore = childDiscardMarginBefore || (childDiscardMarginAfter && childIsSelfCollapsing);
@@ -988,11 +1094,12 @@ LayoutUnit RenderBlockFlow::collapseMargins(RenderBox* child, MarginInfo& margin
LayoutUnit clearanceForSelfCollapsingBlock;
RenderObject* prev = child->previousSibling();
+ RenderBlockFlow* previousBlockFlow = prev && prev->isRenderBlockFlow() && !prev->isFloatingOrOutOfFlowPositioned() ? toRenderBlockFlow(prev) : 0;
// If the child's previous sibling is a self-collapsing block that cleared a float then its top border edge has been set at the bottom border edge
// of the float. Since we want to collapse the child's top margin with the self-collapsing block's top and bottom margins we need to adjust our parent's height to match the
// margin top of the self-collapsing block. If the resulting collapsed margin leaves the child still intruding into the float then we will want to clear it.
- if (!marginInfo.canCollapseWithMarginBefore() && prev && prev->isRenderBlockFlow() && toRenderBlockFlow(prev)->isSelfCollapsingBlock()) {
- clearanceForSelfCollapsingBlock = toRenderBlockFlow(prev)->marginOffsetForSelfCollapsingBlock();
+ if (!marginInfo.canCollapseWithMarginBefore() && previousBlockFlow && previousBlockFlow->isSelfCollapsingBlock()) {
+ clearanceForSelfCollapsingBlock = previousBlockFlow->marginOffsetForSelfCollapsingBlock();
setLogicalHeight(logicalHeight() - clearanceForSelfCollapsingBlock);
}
@@ -1054,21 +1161,19 @@ LayoutUnit RenderBlockFlow::collapseMargins(RenderBox* child, MarginInfo& margin
// If margins would pull us past the top of the next page, then we need to pull back and pretend like the margins
// collapsed into the page edge.
LayoutState* layoutState = view()->layoutState();
- if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTop > beforeCollapseLogicalTop
- && hasNextPage(beforeCollapseLogicalTop)) {
+ if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTop > beforeCollapseLogicalTop) {
LayoutUnit oldLogicalTop = logicalTop;
logicalTop = min(logicalTop, nextPageLogicalTop(beforeCollapseLogicalTop));
setLogicalHeight(logicalHeight() + (logicalTop - oldLogicalTop));
}
- if (prev && prev->isRenderBlockFlow() && !prev->isFloatingOrOutOfFlowPositioned()) {
+ if (previousBlockFlow) {
// If |child| is a self-collapsing block it may have collapsed into a previous sibling and although it hasn't reduced the height of the parent yet
// any floats from the parent will now overhang.
- RenderBlockFlow* blockFlow = toRenderBlockFlow(prev);
LayoutUnit oldLogicalHeight = logicalHeight();
setLogicalHeight(logicalTop);
- if (blockFlow->containsFloats() && !blockFlow->avoidsFloats() && (blockFlow->logicalTop() + blockFlow->lowestFloatLogicalBottom()) > logicalTop)
- addOverhangingFloats(blockFlow, false);
+ if (!previousBlockFlow->avoidsFloats() && (previousBlockFlow->logicalTop() + previousBlockFlow->lowestFloatLogicalBottom()) > logicalTop)
+ addOverhangingFloats(previousBlockFlow, false);
setLogicalHeight(oldLogicalHeight);
// If |child|'s previous sibling is a self-collapsing block that cleared a float and margin collapsing resulted in |child| moving up
@@ -1076,7 +1181,7 @@ LayoutUnit RenderBlockFlow::collapseMargins(RenderBox* child, MarginInfo& margin
// floats in the parent that overhang |child|'s new logical top.
bool logicalTopIntrudesIntoFloat = clearanceForSelfCollapsingBlock > 0 && logicalTop < beforeCollapseLogicalTop;
if (logicalTopIntrudesIntoFloat && containsFloats() && !child->avoidsFloats() && lowestFloatLogicalBottom() > logicalTop)
- child->setNeedsLayout();
+ child->setNeedsLayoutAndFullPaintInvalidation();
}
return logicalTop;
@@ -1106,13 +1211,35 @@ void RenderBlockFlow::adjustPositionedBlock(RenderBox* child, const MarginInfo&
}
}
-LayoutUnit RenderBlockFlow::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos)
+LayoutUnit RenderBlockFlow::computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart)
+{
+ LayoutUnit startPosition = startOffsetForContent();
+
+ // Add in our start margin.
+ LayoutUnit oldPosition = startPosition + childMarginStart;
+ LayoutUnit newPosition = oldPosition;
+
+ LayoutUnit blockOffset = logicalTopForChild(child);
+ LayoutUnit startOff = startOffsetForLine(blockOffset, false, logicalHeightForChild(child));
+
+ if (style()->textAlign() != WEBKIT_CENTER && !child->style()->marginStartUsing(style()).isAuto()) {
+ if (childMarginStart < 0)
+ startOff += childMarginStart;
+ newPosition = max(newPosition, startOff); // Let the float sit in the child's margin if it can fit.
+ } else if (startOff != startPosition) {
+ newPosition = startOff + childMarginStart;
+ }
+
+ return newPosition - oldPosition;
+}
+
+LayoutUnit RenderBlockFlow::clearFloatsIfNeeded(RenderBox* child, MarginInfo& marginInfo, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos, bool childIsSelfCollapsing)
{
LayoutUnit heightIncrease = getClearDelta(child, yPos);
if (!heightIncrease)
return yPos;
- if (child->isSelfCollapsingBlock()) {
+ if (childIsSelfCollapsing) {
bool childDiscardMargin = mustDiscardMarginBeforeForChild(child) || mustDiscardMarginAfterForChild(child);
// For self-collapsing blocks that clear, they can still collapse their
@@ -1131,15 +1258,9 @@ LayoutUnit RenderBlockFlow::clearFloatsIfNeeded(RenderBox* child, MarginInfo& ma
// CSS2.1 states:
// "If the top and bottom margins of an element with clearance are adjoining, its margins collapse with
// the adjoining margins of following siblings but that resulting margin does not collapse with the bottom margin of the parent block."
- // So the parent's bottom margin cannot collapse through this block or any subsequent self-collapsing blocks. Check subsequent siblings
- // for a block with height - if none is found then don't allow the margins to collapse with the parent.
- bool wouldCollapseMarginsWithParent = marginInfo.canCollapseMarginAfterWithChildren();
- for (RenderBox* curr = child->nextSiblingBox(); curr && wouldCollapseMarginsWithParent; curr = curr->nextSiblingBox()) {
- if (!curr->isFloatingOrOutOfFlowPositioned() && !curr->isSelfCollapsingBlock())
- wouldCollapseMarginsWithParent = false;
- }
- if (wouldCollapseMarginsWithParent)
- marginInfo.setCanCollapseMarginAfterWithChildren(false);
+ // So the parent's bottom margin cannot collapse through this block or any subsequent self-collapsing blocks. Set a bit to ensure
+ // this happens; it will get reset if we encounter an in-flow sibling that is not self-collapsing.
+ marginInfo.setCanCollapseMarginAfterWithLastChild(false);
// For now set the border-top of |child| flush with the bottom border-edge of the float so it can layout any floating or positioned children of
// its own at the correct vertical position. If subsequent siblings attempt to collapse with |child|'s margins in |collapseMargins| we will
@@ -1157,9 +1278,6 @@ LayoutUnit RenderBlockFlow::clearFloatsIfNeeded(RenderBox* child, MarginInfo& ma
if (marginInfo.canCollapseWithMarginBefore()) {
// We can no longer collapse with the top of the block since a clear
// occurred. The empty blocks collapse into the cleared block.
- // FIXME: This isn't quite correct. Need clarification for what to do
- // if the height the cleared block is offset by is smaller than the
- // margins involved.
setMaxMarginBeforeValues(oldTopPosMargin, oldTopNegMargin);
marginInfo.setAtBeforeSideOfBlock(false);
@@ -1201,7 +1319,7 @@ void RenderBlockFlow::marginBeforeEstimateForChild(RenderBox* child, LayoutUnit&
// Give up if in quirks mode and we're a body/table cell and the top margin of the child box is quirky.
// Give up if the child specified -webkit-margin-collapse: separate that prevents collapsing.
// FIXME: Use writing mode independent accessor for marginBeforeCollapse.
- if ((document().inQuirksMode() && hasMarginAfterQuirk(child) && (isTableCell() || isBody())) || child->style()->marginBeforeCollapse() == MSEPARATE)
+ if ((document().inQuirksMode() && hasMarginBeforeQuirk(child) && (isTableCell() || isBody())) || child->style()->marginBeforeCollapse() == MSEPARATE)
return;
// The margins are discarded by a child that specified -webkit-margin-collapse: discard.
@@ -1281,8 +1399,7 @@ LayoutUnit RenderBlockFlow::estimateLogicalTopPosition(RenderBox* child, const M
// Adjust logicalTopEstimate down to the next page if the margins are so large that we don't fit on the current
// page.
LayoutState* layoutState = view()->layoutState();
- if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTopEstimate > logicalHeight()
- && hasNextPage(logicalHeight()))
+ if (layoutState->isPaginated() && layoutState->pageLogicalHeight() && logicalTopEstimate > logicalHeight())
logicalTopEstimate = min(logicalTopEstimate, nextPageLogicalTop(logicalHeight()));
logicalTopEstimate += getClearDelta(child, logicalTopEstimate);
@@ -1333,16 +1450,18 @@ void RenderBlockFlow::adjustFloatingBlock(const MarginInfo& marginInfo)
setLogicalHeight(logicalHeight() - marginOffset);
}
-void RenderBlockFlow::handleAfterSideOfBlock(LayoutUnit beforeSide, LayoutUnit afterSide, MarginInfo& marginInfo)
+void RenderBlockFlow::handleAfterSideOfBlock(RenderBox* lastChild, LayoutUnit beforeSide, LayoutUnit afterSide, MarginInfo& marginInfo)
{
marginInfo.setAtAfterSideOfBlock(true);
// If our last child was a self-collapsing block with clearance then our logical height is flush with the
// bottom edge of the float that the child clears. The correct vertical position for the margin-collapsing we want
// to perform now is at the child's margin-top - so adjust our height to that position.
- RenderObject* child = lastChild();
- if (child && child->isRenderBlockFlow() && toRenderBlockFlow(child)->isSelfCollapsingBlock())
- setLogicalHeight(logicalHeight() - toRenderBlockFlow(child)->marginOffsetForSelfCollapsingBlock());
+ if (lastChild && lastChild->isRenderBlockFlow() && lastChild->isSelfCollapsingBlock())
+ setLogicalHeight(logicalHeight() - toRenderBlockFlow(lastChild)->marginOffsetForSelfCollapsingBlock());
+
+ if (marginInfo.canCollapseMarginAfterWithChildren() && !marginInfo.canCollapseMarginAfterWithLastChild())
+ marginInfo.setCanCollapseMarginAfterWithChildren(false);
// If we can't collapse with children then go ahead and add in the bottom margin.
if (!marginInfo.discardMargin() && (!marginInfo.canCollapseWithMarginAfter() && !marginInfo.canCollapseWithMarginBefore()
@@ -1478,19 +1597,21 @@ bool RenderBlockFlow::mustSeparateMarginAfterForChild(const RenderBox* child) co
LayoutUnit RenderBlockFlow::applyBeforeBreak(RenderBox* child, LayoutUnit logicalOffset)
{
// FIXME: Add page break checking here when we support printing.
- bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
- bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
RenderFlowThread* flowThread = flowThreadContainingBlock();
- bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
- bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS)
- || (checkRegionBreaks && child->style()->regionBreakBefore() == PBALWAYS);
- if (checkBeforeAlways && inNormalFlow(child) && hasNextPage(logicalOffset, IncludePageBoundary)) {
- if (checkColumnBreaks)
- view()->layoutState()->addForcedColumnBreak(child, logicalOffset);
- if (checkRegionBreaks) {
- LayoutUnit offsetBreakAdjustment = 0;
- if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset, child, true, &offsetBreakAdjustment))
- return logicalOffset + offsetBreakAdjustment;
+ bool isInsideMulticolFlowThread = flowThread;
+ bool checkColumnBreaks = isInsideMulticolFlowThread || view()->layoutState()->isPaginatingColumns();
+ bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogicalHeight(); // FIXME: Once columns can print we have to check this.
+ bool checkBeforeAlways = (checkColumnBreaks && child->style()->columnBreakBefore() == PBALWAYS)
+ || (checkPageBreaks && child->style()->pageBreakBefore() == PBALWAYS);
+ if (checkBeforeAlways && inNormalFlow(child)) {
+ if (checkColumnBreaks) {
+ if (isInsideMulticolFlowThread) {
+ LayoutUnit offsetBreakAdjustment = 0;
+ if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset, child, true, &offsetBreakAdjustment))
+ return logicalOffset + offsetBreakAdjustment;
+ } else {
+ view()->layoutState()->addForcedColumnBreak(*child, logicalOffset);
+ }
}
return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
}
@@ -1500,24 +1621,26 @@ LayoutUnit RenderBlockFlow::applyBeforeBreak(RenderBox* child, LayoutUnit logica
LayoutUnit RenderBlockFlow::applyAfterBreak(RenderBox* child, LayoutUnit logicalOffset, MarginInfo& marginInfo)
{
// FIXME: Add page break checking here when we support printing.
- bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
- bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight; // FIXME: Once columns can print we have to check this.
RenderFlowThread* flowThread = flowThreadContainingBlock();
- bool checkRegionBreaks = flowThread && flowThread->isRenderNamedFlowThread();
- bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS) || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS)
- || (checkRegionBreaks && child->style()->regionBreakAfter() == PBALWAYS);
- if (checkAfterAlways && inNormalFlow(child) && hasNextPage(logicalOffset, IncludePageBoundary)) {
+ bool isInsideMulticolFlowThread = flowThread;
+ bool checkColumnBreaks = isInsideMulticolFlowThread || view()->layoutState()->isPaginatingColumns();
+ bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->pageLogicalHeight(); // FIXME: Once columns can print we have to check this.
+ bool checkAfterAlways = (checkColumnBreaks && child->style()->columnBreakAfter() == PBALWAYS)
+ || (checkPageBreaks && child->style()->pageBreakAfter() == PBALWAYS);
+ if (checkAfterAlways && inNormalFlow(child)) {
LayoutUnit marginOffset = marginInfo.canCollapseWithMarginBefore() ? LayoutUnit() : marginInfo.margin();
// So our margin doesn't participate in the next collapsing steps.
marginInfo.clearMargin();
- if (checkColumnBreaks)
- view()->layoutState()->addForcedColumnBreak(child, logicalOffset);
- if (checkRegionBreaks) {
- LayoutUnit offsetBreakAdjustment = 0;
- if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, child, false, &offsetBreakAdjustment))
- return logicalOffset + marginOffset + offsetBreakAdjustment;
+ if (checkColumnBreaks) {
+ if (isInsideMulticolFlowThread) {
+ LayoutUnit offsetBreakAdjustment = 0;
+ if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, child, false, &offsetBreakAdjustment))
+ return logicalOffset + marginOffset + offsetBreakAdjustment;
+ } else {
+ view()->layoutState()->addForcedColumnBreak(*child, logicalOffset);
+ }
}
return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
}
@@ -1532,7 +1655,7 @@ void RenderBlockFlow::addOverflowFromFloats()
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (floatingObject->isDescendant())
addOverflowFromChild(floatingObject->renderer(), IntSize(xPositionForFloatIncludingMargin(floatingObject), yPositionForFloatIncludingMargin(floatingObject)));
}
@@ -1541,10 +1664,23 @@ void RenderBlockFlow::addOverflowFromFloats()
void RenderBlockFlow::computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats)
{
RenderBlock::computeOverflow(oldClientAfterEdge, recomputeFloats);
- if (!hasColumns() && (recomputeFloats || isRoot() || expandsToEncloseOverhangingFloats() || hasSelfPaintingLayer()))
+ if (!hasColumns() && (recomputeFloats || createsBlockFormattingContext() || hasSelfPaintingLayer()))
addOverflowFromFloats();
}
+RootInlineBox* RenderBlockFlow::createAndAppendRootInlineBox()
+{
+ RootInlineBox* rootBox = createRootInlineBox();
+ m_lineBoxes.appendLineBox(rootBox);
+
+ if (UNLIKELY(AXObjectCache::accessibilityEnabled()) && m_lineBoxes.firstLineBox() == rootBox) {
+ if (AXObjectCache* cache = document().existingAXObjectCache())
+ cache->recomputeIsIgnored(this);
+ }
+
+ return rootBox;
+}
+
void RenderBlockFlow::deleteLineBoxTree()
{
if (containsFloats())
@@ -1633,11 +1769,10 @@ LayoutUnit RenderBlockFlow::getClearDelta(RenderBox* child, LayoutUnit logicalTo
LayoutUnit newLogicalTop = logicalTop;
while (true) {
LayoutUnit availableLogicalWidthAtNewLogicalTopOffset = availableLogicalWidthForLine(newLogicalTop, false, logicalHeightForChild(child));
- if (availableLogicalWidthAtNewLogicalTopOffset == availableLogicalWidthForContent(newLogicalTop))
+ if (availableLogicalWidthAtNewLogicalTopOffset == availableLogicalWidthForContent())
return newLogicalTop - logicalTop;
- RenderRegion* region = regionAtBlockOffset(logicalTopForChild(child));
- LayoutRect borderBox = child->borderBoxRectInRegion(region, DoNotCacheRenderBoxRegionInfo);
+ LayoutRect borderBox = child->borderBoxRect();
LayoutUnit childLogicalWidthAtOldLogicalTopOffset = isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
// FIXME: None of this is right for perpendicular writing-mode children.
@@ -1648,8 +1783,7 @@ LayoutUnit RenderBlockFlow::getClearDelta(RenderBox* child, LayoutUnit logicalTo
child->setLogicalTop(newLogicalTop);
child->updateLogicalWidth();
- region = regionAtBlockOffset(logicalTopForChild(child));
- borderBox = child->borderBoxRectInRegion(region, DoNotCacheRenderBoxRegionInfo);
+ borderBox = child->borderBoxRect();
LayoutUnit childLogicalWidthAtNewLogicalTopOffset = isHorizontalWritingMode() ? borderBox.width() : borderBox.height();
child->setLogicalTop(childOldLogicalTop);
@@ -1681,12 +1815,12 @@ void RenderBlockFlow::createFloatingObjects()
m_floatingObjects = adoptPtr(new FloatingObjects(this, isHorizontalWritingMode()));
}
-void RenderBlockFlow::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderBlockFlow::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
RenderStyle* oldStyle = style();
s_canPropagateFloatIntoSibling = oldStyle ? !isFloatingOrOutOfFlowPositioned() && !avoidsFloats() : false;
- if (oldStyle && parent() && diff == StyleDifferenceLayout && oldStyle->position() != newStyle->position()
- && containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newStyle->hasOutOfFlowPosition())
+ if (oldStyle && parent() && diff.needsFullLayout() && oldStyle->position() != newStyle.position()
+ && containsFloats() && !isFloating() && !isOutOfFlowPositioned() && newStyle.hasOutOfFlowPosition())
markAllDescendantsWithFloatsForLayout();
RenderBlock::styleWillChange(diff, newStyle);
@@ -1701,7 +1835,7 @@ void RenderBlockFlow::styleDidChange(StyleDifference diff, const RenderStyle* ol
// then mark its descendants with floats for layout and clear all floats from its next
// sibling blocks that exist in our floating objects list. See bug 56299 and 62875.
bool canPropagateFloatIntoSibling = !isFloatingOrOutOfFlowPositioned() && !avoidsFloats();
- if (diff == StyleDifferenceLayout && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
+ if (diff.needsFullLayout() && s_canPropagateFloatIntoSibling && !canPropagateFloatIntoSibling && hasOverhangingFloats()) {
RenderBlockFlow* parentBlockFlow = this;
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
@@ -1726,8 +1860,8 @@ void RenderBlockFlow::styleDidChange(StyleDifference diff, const RenderStyle* ol
parentBlockFlow->markSiblingsWithFloatsForLayout();
}
- if (renderNamedFlowFragment())
- renderNamedFlowFragment()->setStyleForNamedFlowFragment(style());
+ if (diff.needsFullLayout() || !oldStyle)
+ createOrDestroyMultiColumnFlowThreadIfNeeded();
}
void RenderBlockFlow::updateStaticInlinePositionForChild(RenderBox* child, LayoutUnit logicalTop)
@@ -1735,18 +1869,23 @@ void RenderBlockFlow::updateStaticInlinePositionForChild(RenderBox* child, Layou
if (child->style()->isOriginalDisplayInlineType())
setStaticInlinePositionForChild(child, logicalTop, startAlignedOffsetForLine(logicalTop, false));
else
- setStaticInlinePositionForChild(child, logicalTop, startOffsetForContent(logicalTop));
+ setStaticInlinePositionForChild(child, logicalTop, startOffsetForContent());
}
void RenderBlockFlow::setStaticInlinePositionForChild(RenderBox* child, LayoutUnit blockOffset, LayoutUnit inlinePosition)
{
- if (flowThreadContainingBlock()) {
- // Shift the inline position to exclude the region offset.
- inlinePosition += startOffsetForContent() - startOffsetForContent(blockOffset);
- }
child->layer()->setStaticInlinePosition(inlinePosition);
}
+void RenderBlockFlow::addChild(RenderObject* newChild, RenderObject* beforeChild)
+{
+ if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
+ flowThread->addChild(newChild, beforeChild);
+ return;
+ }
+ RenderBlock::addChild(newChild, beforeChild);
+}
+
void RenderBlockFlow::moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert)
{
RenderBlockFlow* toBlockFlow = toRenderBlockFlow(toBlock);
@@ -1777,7 +1916,7 @@ void RenderBlockFlow::moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, boo
FloatingObjectSetIterator end = fromFloatingObjectSet.end();
for (FloatingObjectSetIterator it = fromFloatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
// Don't insert the object again if it's already in the list
if (toBlockFlow->containsFloat(floatingObject->renderer()))
@@ -1798,11 +1937,11 @@ void RenderBlockFlow::repaintOverhangingFloats(bool paintAllDescendants)
// FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
// in this block. Better yet would be to push extra state for the containers of other floats.
- LayoutStateDisabler layoutStateDisabler(view());
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
// Only repaint the object if it is overhanging, is not in its own layer, and
// is our responsibility to paint (m_shouldPaint is set). When paintAllDescendants is true, the latter
// condition is replaced with being a descendant of us.
@@ -1811,18 +1950,17 @@ void RenderBlockFlow::repaintOverhangingFloats(bool paintAllDescendants)
&& (floatingObject->shouldPaint() || (paintAllDescendants && floatingObject->renderer()->isDescendantOf(this)))) {
RenderBox* floatingRenderer = floatingObject->renderer();
- LayoutRectRecorder recorder(*floatingRenderer);
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
- floatingRenderer->setShouldDoFullRepaintAfterLayout(true);
+ floatingRenderer->setShouldDoFullPaintInvalidationAfterLayout(true);
else
- floatingRenderer->repaint();
+ floatingRenderer->paintInvalidationForWholeRenderer();
floatingRenderer->repaintOverhangingFloats(false);
}
}
}
-void RenderBlockFlow::repaintOverflow()
+void RenderBlockFlow::invalidatePaintForOverflow()
{
// FIXME: We could tighten up the left and right invalidation points if we let layoutInlineChildren fill them in based off the particular lines
// it had to lay out. We wouldn't need the hasOverflowClip() hack in that case either.
@@ -1845,8 +1983,6 @@ void RenderBlockFlow::repaintOverflow()
// The repaint rect may be split across columns, in which case adjustRectForColumns() will return the union.
adjustRectForColumns(repaintRect);
- repaintRect.inflate(maximalOutlineSize(PaintPhaseOutline));
-
if (hasOverflowClip()) {
// Adjust repaint rect for scroll offset
repaintRect.move(-scrolledContentOffset());
@@ -1857,9 +1993,12 @@ void RenderBlockFlow::repaintOverflow()
// Make sure the rect is still non-empty after intersecting for overflow above
if (!repaintRect.isEmpty()) {
- repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
+ // Hits in media/event-attributes.html
+ DisableCompositingQueryAsserts disabler;
+
+ invalidatePaintRectangle(repaintRect); // We need to do a partial repaint of our content.
if (hasReflection())
- repaintRectangle(reflectedRect(repaintRect));
+ invalidatePaintRectangle(reflectedRect(repaintRect));
}
m_repaintLogicalTop = 0;
@@ -1874,7 +2013,7 @@ void RenderBlockFlow::paintFloats(PaintInfo& paintInfo, const LayoutPoint& paint
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
// Only paint the object if our m_shouldPaint flag is set.
if (floatingObject->shouldPaint() && !floatingObject->renderer()->hasSelfPaintingLayer()) {
PaintInfo currentPaintInfo(paintInfo);
@@ -1902,7 +2041,7 @@ void RenderBlockFlow::clipOutFloatingObjects(RenderBlock* rootBlock, const Paint
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
LayoutRect floatBox(offsetFromRootBlock.width() + xPositionForFloatIncludingMargin(floatingObject),
offsetFromRootBlock.height() + yPositionForFloatIncludingMargin(floatingObject),
floatingObject->renderer()->width(), floatingObject->renderer()->height());
@@ -1944,6 +2083,8 @@ void RenderBlockFlow::removeFloatingObjects()
if (!m_floatingObjects)
return;
+ markSiblingsWithFloatsForLayout();
+
m_floatingObjects->clear();
}
@@ -1976,34 +2117,32 @@ LayoutUnit RenderBlockFlow::logicalRightOffsetForPositioningFloat(LayoutUnit log
return adjustLogicalRightOffsetForLine(offset, applyTextIndent);
}
+LayoutUnit RenderBlockFlow::adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
+{
+ LayoutUnit left = offsetFromFloats;
+
+ if (applyTextIndent && style()->isLeftToRightDirection())
+ left += textIndentOffset();
+
+ return left;
+}
+
+LayoutUnit RenderBlockFlow::adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const
+{
+ LayoutUnit right = offsetFromFloats;
+
+ if (applyTextIndent && !style()->isLeftToRightDirection())
+ right -= textIndentOffset();
+
+ return right;
+}
+
LayoutPoint RenderBlockFlow::computeLogicalLocationForFloat(const FloatingObject* floatingObject, LayoutUnit logicalTopOffset) const
{
RenderBox* childBox = floatingObject->renderer();
- LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
+ LayoutUnit logicalLeftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
LayoutUnit logicalRightOffset; // Constant part of right offset.
- // FIXME Bug 102948: This only works for shape outside directly set on this block.
- ShapeInsideInfo* shapeInsideInfo = this->layoutShapeInsideInfo();
- // FIXME: Implement behavior for right floats.
- if (shapeInsideInfo) {
- LayoutSize floatLogicalSize = logicalSizeForFloat(floatingObject);
- // floatingObject's logicalSize doesn't contain the actual height at this point, so we need to calculate it
- floatLogicalSize.setHeight(logicalHeightForChild(childBox) + marginBeforeForChild(childBox) + marginAfterForChild(childBox));
-
- // FIXME: If the float doesn't fit in the shape we should push it under the content box
- logicalTopOffset = shapeInsideInfo->computeFirstFitPositionForFloat(floatLogicalSize);
- if (logicalHeight() > logicalTopOffset)
- logicalTopOffset = logicalHeight();
-
- SegmentList segments = shapeInsideInfo->computeSegmentsForLine(logicalTopOffset, floatLogicalSize.height());
- // FIXME: Add support for shapes with multiple segments.
- if (segments.size() == 1) {
- // The segment offsets are relative to the content box.
- logicalRightOffset = logicalLeftOffset + segments[0].logicalRight;
- logicalLeftOffset += segments[0].logicalLeft;
- }
- } else {
- logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset);
- }
+ logicalRightOffset = logicalRightOffsetForContent();
LayoutUnit floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset); // The width we look for.
@@ -2020,8 +2159,8 @@ LayoutPoint RenderBlockFlow::computeLogicalLocationForFloat(const FloatingObject
floatLogicalLeft = logicalLeftOffsetForPositioningFloat(logicalTopOffset, logicalLeftOffset, false, &heightRemainingLeft);
if (insideFlowThread) {
// Have to re-evaluate all of our offsets, since they may have changed.
- logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
- logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
+ logicalRightOffset = logicalRightOffsetForContent(); // Constant part of right offset.
+ logicalLeftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset);
}
}
@@ -2035,8 +2174,8 @@ LayoutPoint RenderBlockFlow::computeLogicalLocationForFloat(const FloatingObject
floatLogicalLeft = logicalRightOffsetForPositioningFloat(logicalTopOffset, logicalRightOffset, false, &heightRemainingRight);
if (insideFlowThread) {
// Have to re-evaluate all of our offsets, since they may have changed.
- logicalRightOffset = logicalRightOffsetForContent(logicalTopOffset); // Constant part of right offset.
- logicalLeftOffset = logicalLeftOffsetForContent(logicalTopOffset); // Constant part of left offset.
+ logicalRightOffset = logicalRightOffsetForContent(); // Constant part of right offset.
+ logicalLeftOffset = logicalLeftOffsetForContent(); // Constant part of left offset.
floatLogicalWidth = min(logicalWidthForFloat(floatingObject), logicalRightOffset - logicalLeftOffset);
}
}
@@ -2061,7 +2200,7 @@ FloatingObject* RenderBlockFlow::insertFloatingObject(RenderBox* floatBox)
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHashTranslator>(floatBox);
if (it != floatingObjectSet.end())
- return *it;
+ return it->get();
}
// Create the special object entry & append it to the list
@@ -2093,7 +2232,7 @@ void RenderBlockFlow::removeFloatingObject(RenderBox* floatBox)
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator it = floatingObjectSet.find<FloatingObjectHashTranslator>(floatBox);
if (it != floatingObjectSet.end()) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (childrenInline()) {
LayoutUnit logicalTop = logicalTopForFloat(floatingObject);
LayoutUnit logicalBottom = logicalBottomForFloat(floatingObject);
@@ -2112,7 +2251,7 @@ void RenderBlockFlow::removeFloatingObject(RenderBox* floatBox)
ASSERT(floatingObject->originatingLine()->renderer() == this);
floatingObject->originatingLine()->markDirty();
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
floatingObject->setOriginatingLine(0);
#endif
}
@@ -2129,12 +2268,12 @@ void RenderBlockFlow::removeFloatingObjectsBelow(FloatingObject* lastFloat, int
return;
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
- FloatingObject* curr = floatingObjectSet.last();
+ FloatingObject* curr = floatingObjectSet.last().get();
while (curr != lastFloat && (!curr->isPlaced() || logicalTopForFloat(curr) >= logicalOffset)) {
m_floatingObjects->remove(curr);
if (floatingObjectSet.isEmpty())
break;
- curr = floatingObjectSet.last();
+ curr = floatingObjectSet.last().get();
}
}
@@ -2161,7 +2300,7 @@ bool RenderBlockFlow::positionNewFloats()
while (it != begin) {
--it;
if ((*it)->isPlaced()) {
- lastPlacedFloatingObject = *it;
+ lastPlacedFloatingObject = it->get();
++it;
break;
}
@@ -2176,15 +2315,18 @@ bool RenderBlockFlow::positionNewFloats()
FloatingObjectSetIterator end = floatingObjectSet.end();
// Now walk through the set of unpositioned floats and place them.
for (; it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
// The containing block is responsible for positioning floats, so if we have floats in our
// list that come from somewhere else, do not attempt to position them.
if (floatingObject->renderer()->containingBlock() != this)
continue;
RenderBox* childBox = floatingObject->renderer();
- LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
+ // FIXME Investigate if this can be removed. crbug.com/370006
+ childBox->setMayNeedPaintInvalidation(true);
+
+ LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() ? marginStartForChild(childBox) : marginEndForChild(childBox);
LayoutRect oldRect = childBox->frameRect();
if (childBox->style()->clear() & CLEFT)
@@ -2199,7 +2341,7 @@ bool RenderBlockFlow::positionNewFloats()
setLogicalLeftForChild(childBox, floatLogicalLocation.x() + childLogicalLeftMargin);
setLogicalTopForChild(childBox, floatLogicalLocation.y() + marginBeforeForChild(childBox));
- SubtreeLayoutScope layoutScope(childBox);
+ SubtreeLayoutScope layoutScope(*childBox);
LayoutState* layoutState = view()->layoutState();
bool isPaginated = layoutState->isPaginated();
if (isPaginated && !childBox->needsLayout())
@@ -2243,10 +2385,11 @@ bool RenderBlockFlow::positionNewFloats()
m_floatingObjects->addPlacedObject(floatingObject);
if (ShapeOutsideInfo* shapeOutside = childBox->shapeOutsideInfo())
- shapeOutside->setShapeSize(logicalWidthForChild(childBox), logicalHeightForChild(childBox));
+ shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(childBox));
// If the child moved, we have to repaint it.
- if (childBox->checkForRepaintDuringLayout())
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()
+ && childBox->checkForPaintInvalidationDuringLayout())
childBox->repaintDuringLayoutIfMoved(oldRect);
}
return true;
@@ -2262,13 +2405,17 @@ bool RenderBlockFlow::hasOverhangingFloat(RenderBox* renderer)
if (it == floatingObjectSet.end())
return false;
- return logicalBottomForFloat(*it) > logicalHeight();
+ return logicalBottomForFloat(it->get()) > logicalHeight();
}
void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logicalLeftOffset, LayoutUnit logicalTopOffset)
{
ASSERT(!avoidsFloats());
+ // If we create our own block formatting context then our contents don't interact with floats outside it, even those from our parent.
+ if (createsBlockFormattingContext())
+ return;
+
// If the parent or previous sibling doesn't have any floats to add, don't bother.
if (!prev->m_floatingObjects)
return;
@@ -2278,7 +2425,7 @@ void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logic
const FloatingObjectSet& prevSet = prev->m_floatingObjects->set();
FloatingObjectSetIterator prevEnd = prevSet.end();
for (FloatingObjectSetIterator prevIt = prevSet.begin(); prevIt != prevEnd; ++prevIt) {
- FloatingObject* floatingObject = *prevIt;
+ FloatingObject* floatingObject = prevIt->get();
if (logicalBottomForFloat(floatingObject) > logicalTopOffset) {
if (!m_floatingObjects || !m_floatingObjects->set().contains(floatingObject)) {
// We create the floating object list lazily.
@@ -2300,24 +2447,22 @@ void RenderBlockFlow::addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit logic
}
}
-LayoutUnit RenderBlockFlow::addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats)
+void RenderBlockFlow::addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats)
{
// Prevent floats from being added to the canvas by the root element, e.g., <html>.
- if (child->hasOverflowClip() || !child->containsFloats() || child->isRoot() || child->hasColumns() || child->isWritingModeRoot())
- return 0;
+ if (!child->containsFloats() || child->isRenderRegion() || child->createsBlockFormattingContext())
+ return;
LayoutUnit childLogicalTop = child->logicalTop();
LayoutUnit childLogicalLeft = child->logicalLeft();
- LayoutUnit lowestFloatLogicalBottom = 0;
// Floats that will remain the child's responsibility to paint should factor into its
// overflow.
FloatingObjectSetIterator childEnd = child->m_floatingObjects->set().end();
for (FloatingObjectSetIterator childIt = child->m_floatingObjects->set().begin(); childIt != childEnd; ++childIt) {
- FloatingObject* floatingObject = *childIt;
+ FloatingObject* floatingObject = childIt->get();
LayoutUnit logicalBottomForFloat = min(this->logicalBottomForFloat(floatingObject), LayoutUnit::max() - childLogicalTop);
LayoutUnit logicalBottom = childLogicalTop + logicalBottomForFloat;
- lowestFloatLogicalBottom = max(lowestFloatLogicalBottom, logicalBottom);
if (logicalBottom > logicalHeight()) {
// If the object is not in the list, we add it now.
@@ -2356,7 +2501,6 @@ LayoutUnit RenderBlockFlow::addOverhangingFloats(RenderBlockFlow* child, bool ma
child->addOverflowFromChild(floatingObject->renderer(), LayoutSize(xPositionForFloatIncludingMargin(floatingObject), yPositionForFloatIncludingMargin(floatingObject)));
}
}
- return lowestFloatLogicalBottom;
}
LayoutUnit RenderBlockFlow::lowestFloatLogicalBottom(FloatingObject::Type floatType) const
@@ -2372,11 +2516,11 @@ LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight
if (!m_floatingObjects)
return logicalHeight;
- LayoutUnit logicalBottom = LayoutUnit::max();
+ LayoutUnit logicalBottom;
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
LayoutUnit floatLogicalBottom = logicalBottomForFloat(floatingObject);
ShapeOutsideInfo* shapeOutside = floatingObject->renderer()->shapeOutsideInfo();
if (shapeOutside && (offsetMode == ShapeOutsideFloatShapeOffset)) {
@@ -2386,10 +2530,10 @@ LayoutUnit RenderBlockFlow::nextFloatLogicalBottomBelow(LayoutUnit logicalHeight
floatLogicalBottom = shapeLogicalBottom;
}
if (floatLogicalBottom > logicalHeight)
- logicalBottom = min(floatLogicalBottom, logicalBottom);
+ logicalBottom = logicalBottom ? min(floatLogicalBottom, logicalBottom) : floatLogicalBottom;
}
- return logicalBottom == LayoutUnit::max() ? LayoutUnit() : logicalBottom;
+ return logicalBottom;
}
bool RenderBlockFlow::hitTestFloats(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset)
@@ -2406,7 +2550,7 @@ bool RenderBlockFlow::hitTestFloats(const HitTestRequest& request, HitTestResult
FloatingObjectSetIterator begin = floatingObjectSet.begin();
for (FloatingObjectSetIterator it = floatingObjectSet.end(); it != begin;) {
--it;
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (floatingObject->shouldPaint() && !floatingObject->renderer()->hasSelfPaintingLayer()) {
LayoutUnit xOffset = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->renderer()->x();
LayoutUnit yOffset = yPositionForFloatIncludingMargin(floatingObject) - floatingObject->renderer()->y();
@@ -2428,7 +2572,7 @@ void RenderBlockFlow::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutU
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
// Only examine the object if our m_shouldPaint flag is set.
if (floatingObject->shouldPaint()) {
LayoutUnit floatLeft = xPositionForFloatIncludingMargin(floatingObject) - floatingObject->renderer()->x();
@@ -2512,12 +2656,40 @@ GapRects RenderBlockFlow::inlineSelectionGaps(RenderBlock* rootBlock, const Layo
return result;
}
+LayoutUnit RenderBlockFlow::logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
+{
+ LayoutUnit logicalLeft = logicalLeftOffsetForLine(position, false);
+ if (logicalLeft == logicalLeftOffsetForContent())
+ return RenderBlock::logicalLeftSelectionOffset(rootBlock, position);
+
+ RenderBlock* cb = this;
+ while (cb != rootBlock) {
+ logicalLeft += cb->logicalLeft();
+ cb = cb->containingBlock();
+ }
+ return logicalLeft;
+}
+
+LayoutUnit RenderBlockFlow::logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position)
+{
+ LayoutUnit logicalRight = logicalRightOffsetForLine(position, false);
+ if (logicalRight == logicalRightOffsetForContent())
+ return RenderBlock::logicalRightSelectionOffset(rootBlock, position);
+
+ RenderBlock* cb = this;
+ while (cb != rootBlock) {
+ logicalRight += cb->logicalLeft();
+ cb = cb->containingBlock();
+ }
+ return logicalRight;
+}
+
template <typename CharacterType>
-static inline TextRun constructTextRunInternal(RenderObject* context, const Font& font, const CharacterType* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
+static inline TextRun constructTextRunInternal(RenderObject* context, const Font& font, const CharacterType* characters, int length, RenderStyle* style, TextDirection direction, TextRun::ExpansionBehavior expansion)
{
ASSERT(style);
- TextDirection textDirection = LTR;
+ TextDirection textDirection = direction;
bool directionalOverride = style->rtlOrdering() == VisualOrder;
TextRun run(characters, length, 0, 0, expansion, textDirection, directionalOverride);
@@ -2528,11 +2700,11 @@ static inline TextRun constructTextRunInternal(RenderObject* context, const Font
}
template <typename CharacterType>
-static inline TextRun constructTextRunInternal(RenderObject* context, const Font& font, const CharacterType* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
+static inline TextRun constructTextRunInternal(RenderObject* context, const Font& font, const CharacterType* characters, int length, RenderStyle* style, TextDirection direction, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
{
ASSERT(style);
- TextDirection textDirection = LTR;
+ TextDirection textDirection = direction;
bool directionalOverride = style->rtlOrdering() == VisualOrder;
if (flags != DefaultTextRunFlags) {
if (flags & RespectDirection)
@@ -2542,109 +2714,90 @@ static inline TextRun constructTextRunInternal(RenderObject* context, const Font
}
TextRun run(characters, length, 0, 0, expansion, textDirection, directionalOverride);
- if (!directionalOverride) {
- BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
- bidiResolver.setStatus(BidiStatus(run.direction(), run.directionalOverride()));
- bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&run, 0));
- bool hasStrongDirectionality;
- TextDirection direction = bidiResolver.determineParagraphDirectionality(&hasStrongDirectionality);
- if (hasStrongDirectionality)
- run.setDirection(direction);
- }
-
if (textRunNeedsRenderingContext(font))
run.setRenderingContext(SVGTextRunRenderingContext::create(context));
return run;
}
-TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const LChar* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
+TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const LChar* characters, int length, RenderStyle* style, TextDirection direction, TextRun::ExpansionBehavior expansion)
{
- return constructTextRunInternal(context, font, characters, length, style, expansion);
+ return constructTextRunInternal(context, font, characters, length, style, direction, expansion);
}
-TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const UChar* characters, int length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
+TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const UChar* characters, int length, RenderStyle* style, TextDirection direction, TextRun::ExpansionBehavior expansion)
{
- return constructTextRunInternal(context, font, characters, length, style, expansion);
+ return constructTextRunInternal(context, font, characters, length, style, direction, expansion);
}
-TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const RenderText* text, RenderStyle* style, TextRun::ExpansionBehavior expansion)
+TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const RenderText* text, RenderStyle* style, TextDirection direction, TextRun::ExpansionBehavior expansion)
{
if (text->is8Bit())
- return constructTextRunInternal(context, font, text->characters8(), text->textLength(), style, expansion);
- return constructTextRunInternal(context, font, text->characters16(), text->textLength(), style, expansion);
+ return constructTextRunInternal(context, font, text->characters8(), text->textLength(), style, direction, expansion);
+ return constructTextRunInternal(context, font, text->characters16(), text->textLength(), style, direction, expansion);
}
-TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, unsigned length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
+TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, unsigned length, RenderStyle* style, TextDirection direction, TextRun::ExpansionBehavior expansion)
{
ASSERT(offset + length <= text->textLength());
if (text->is8Bit())
- return constructTextRunInternal(context, font, text->characters8() + offset, length, style, expansion);
- return constructTextRunInternal(context, font, text->characters16() + offset, length, style, expansion);
+ return constructTextRunInternal(context, font, text->characters8() + offset, length, style, direction, expansion);
+ return constructTextRunInternal(context, font, text->characters16() + offset, length, style, direction, expansion);
}
-TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
+TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style, TextDirection direction, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
{
unsigned length = string.length();
if (!length)
- return constructTextRunInternal(context, font, static_cast<const LChar*>(0), length, style, expansion, flags);
+ return constructTextRunInternal(context, font, static_cast<const LChar*>(0), length, style, direction, expansion, flags);
if (string.is8Bit())
- return constructTextRunInternal(context, font, string.characters8(), length, style, expansion, flags);
- return constructTextRunInternal(context, font, string.characters16(), length, style, expansion, flags);
-}
-
-RootInlineBox* RenderBlockFlow::createRootInlineBox()
-{
- return new RootInlineBox(this);
-}
-
-void RenderBlockFlow::createRenderNamedFlowFragmentIfNeeded()
-{
- if (!RuntimeEnabledFeatures::cssRegionsEnabled()
- || renderNamedFlowFragment()
- || isRenderNamedFlowFragment())
- return;
-
- RenderStyle* styleToUse = style();
- if (styleToUse->isDisplayRegionType() && styleToUse->hasFlowFrom() && document().renderView()) {
- RenderNamedFlowFragment* flowFragment = RenderNamedFlowFragment::createAnonymous(&document());
- flowFragment->setStyleForNamedFlowFragment(styleToUse);
- setRenderNamedFlowFragment(flowFragment);
- addChild(flowFragment);
- }
+ return constructTextRunInternal(context, font, string.characters8(), length, style, direction, expansion, flags);
+ return constructTextRunInternal(context, font, string.characters16(), length, style, direction, expansion, flags);
}
-void RenderBlockFlow::insertedIntoTree()
+TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const String& string, RenderStyle* style, TextRun::ExpansionBehavior expansion, TextRunFlags flags)
{
- RenderBlock::insertedIntoTree();
-
- createRenderNamedFlowFragmentIfNeeded();
+ bool hasStrongDirectionality;
+ return constructTextRun(context, font, string, style,
+ determineDirectionality(string, hasStrongDirectionality),
+ expansion, flags);
}
-bool RenderBlockFlow::canHaveChildren() const
+TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, unsigned length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
{
- return !renderNamedFlowFragment() ? RenderBlock::canHaveChildren() : renderNamedFlowFragment()->canHaveChildren();
+ ASSERT(offset + length <= text->textLength());
+ TextRun run = text->is8Bit()
+ ? constructTextRunInternal(context, font, text->characters8() + offset, length, style, LTR, expansion)
+ : constructTextRunInternal(context, font, text->characters16() + offset, length, style, LTR, expansion);
+ bool hasStrongDirectionality;
+ run.setDirection(directionForRun(run, hasStrongDirectionality));
+ return run;
}
-bool RenderBlockFlow::canHaveGeneratedChildren() const
+RootInlineBox* RenderBlockFlow::createRootInlineBox()
{
- return !renderNamedFlowFragment() ? RenderBlock::canHaveGeneratedChildren() : renderNamedFlowFragment()->canHaveGeneratedChildren();
+ return new RootInlineBox(*this);
}
-void RenderBlockFlow::updateLogicalHeight()
+void RenderBlockFlow::createOrDestroyMultiColumnFlowThreadIfNeeded()
{
- RenderBlock::updateLogicalHeight();
-
- if (renderNamedFlowFragment())
- renderNamedFlowFragment()->setLogicalHeight(max<LayoutUnit>(0, logicalHeight() - borderAndPaddingLogicalHeight()));
-}
+ if (!document().regionBasedColumnsEnabled())
+ return;
-void RenderBlockFlow::setRenderNamedFlowFragment(RenderNamedFlowFragment* flowFragment)
-{
- RenderBlockFlow::RenderBlockFlowRareData& rareData = ensureRareData();
- if (rareData.m_renderNamedFlowFragment)
- rareData.m_renderNamedFlowFragment->destroy();
- rareData.m_renderNamedFlowFragment = flowFragment;
+ bool needsFlowThread = style()->specifiesColumns();
+ if (needsFlowThread != static_cast<bool>(multiColumnFlowThread())) {
+ if (needsFlowThread) {
+ RenderMultiColumnFlowThread* flowThread = RenderMultiColumnFlowThread::createAnonymous(document(), style());
+ addChild(flowThread);
+ flowThread->populate();
+ RenderBlockFlowRareData& rareData = ensureRareData();
+ ASSERT(!rareData.m_multiColumnFlowThread);
+ rareData.m_multiColumnFlowThread = flowThread;
+ } else {
+ multiColumnFlowThread()->evacuateAndDestroy();
+ ASSERT(!multiColumnFlowThread());
+ }
+ }
}
RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData()
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.h b/chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.h
index e68388194f5..2f94081d965 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBlockFlow.h
@@ -38,6 +38,7 @@
#include "core/rendering/FloatingObjects.h"
#include "core/rendering/RenderBlock.h"
+#include "core/rendering/line/TrailingObjects.h"
#include "core/rendering/style/RenderStyleConstants.h"
namespace WebCore {
@@ -45,7 +46,7 @@ namespace WebCore {
class MarginInfo;
class LineBreaker;
class LineWidth;
-class RenderNamedFlowFragment;
+class RenderMultiColumnFlowThread;
class RenderBlockFlow : public RenderBlock {
public:
@@ -53,15 +54,44 @@ public:
virtual ~RenderBlockFlow();
static RenderBlockFlow* createAnonymous(Document*);
- RenderBlockFlow* createAnonymousBlockFlow() const;
virtual bool isRenderBlockFlow() const OVERRIDE FINAL { return true; }
- virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
+ virtual void layoutBlock(bool relayoutChildren) OVERRIDE;
virtual void computeOverflow(LayoutUnit oldClientAfterEdge, bool recomputeFloats = false) OVERRIDE;
virtual void deleteLineBoxTree() OVERRIDE FINAL;
+ LayoutUnit availableLogicalWidthForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
+ {
+ return max<LayoutUnit>(0, logicalRightOffsetForLine(position, shouldIndentText, logicalHeight) - logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight));
+ }
+ LayoutUnit logicalRightOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
+ {
+ return logicalRightOffsetForLine(position, logicalRightOffsetForContent(), shouldIndentText, logicalHeight);
+ }
+ LayoutUnit logicalLeftOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
+ {
+ return logicalLeftOffsetForLine(position, logicalLeftOffsetForContent(), shouldIndentText, logicalHeight);
+ }
+ LayoutUnit startOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
+ {
+ return style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
+ : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
+ }
+ LayoutUnit endOffsetForLine(LayoutUnit position, bool shouldIndentText, LayoutUnit logicalHeight = 0) const
+ {
+ return !style()->isLeftToRightDirection() ? logicalLeftOffsetForLine(position, shouldIndentText, logicalHeight)
+ : logicalWidth() - logicalRightOffsetForLine(position, shouldIndentText, logicalHeight);
+ }
+
+ virtual LayoutUnit logicalLeftSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) OVERRIDE;
+ virtual LayoutUnit logicalRightSelectionOffset(RenderBlock* rootBlock, LayoutUnit position) OVERRIDE;
+
+ LayoutUnit computeStartPositionDeltaForChildAvoidingFloats(const RenderBox* child, LayoutUnit childMarginStart);
+
+ RootInlineBox* createAndAppendRootInlineBox();
+
void markAllDescendantsWithFloatsForLayout(RenderBox* floatToRemove = 0, bool inLayout = true);
void markSiblingsWithFloatsForLayout(RenderBox* floatToRemove = 0);
@@ -70,6 +100,10 @@ public:
void removeFloatingObjects();
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
+
+ void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert);
+
bool generatesLineBoxesForInlineChild(RenderObject*);
LayoutUnit logicalTopForFloat(const FloatingObject* floatingObject) const { return isHorizontalWritingMode() ? floatingObject->y() : floatingObject->x(); }
@@ -124,67 +158,82 @@ public:
return obj->isFloating() || (obj->isOutOfFlowPositioned() && !obj->style()->isOriginalDisplayInlineType() && !obj->container()->isRenderInline());
}
+ // Direction resolved from string value.
static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*,
TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
+ static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*,
+ TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
- static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, RenderStyle*,
+ // Explicit direction.
+ static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*, TextDirection,
+ TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
+
+ static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, RenderStyle*, TextDirection,
TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
- static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*,
+ static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*, TextDirection,
TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, RenderStyle*,
TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
- static TextRun constructTextRun(RenderObject* context, const Font&, const LChar* characters, int length, RenderStyle*,
+ static TextRun constructTextRun(RenderObject* context, const Font&, const LChar* characters, int length, RenderStyle*, TextDirection,
TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
- static TextRun constructTextRun(RenderObject* context, const Font&, const UChar* characters, int length, RenderStyle*,
+ static TextRun constructTextRun(RenderObject* context, const Font&, const UChar* characters, int length, RenderStyle*, TextDirection,
TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
- RootInlineBox* lineGridBox() const { return m_rareData ? m_rareData->m_lineGridBox : 0; }
- void setLineGridBox(RootInlineBox* box)
+ RenderMultiColumnFlowThread* multiColumnFlowThread() const { return m_rareData ? m_rareData->m_multiColumnFlowThread : 0; }
+ void resetMultiColumnFlowThread()
{
- RenderBlockFlow::RenderBlockFlowRareData& rareData = ensureRareData();
- if (rareData.m_lineGridBox)
- rareData.m_lineGridBox->destroy();
- rareData.m_lineGridBox = box;
+ if (m_rareData)
+ m_rareData->m_multiColumnFlowThread = 0;
}
- void layoutLineGridBox();
void addOverflowFromInlineChildren();
+ // FIXME: This should be const to avoid a const_cast, but can modify child dirty bits and RenderCombineText
+ void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
+
GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
protected:
- // Only used by RenderSVGText, which explicitly overrides RenderBlock::layoutBlock(), do NOT use for anything else.
- void forceLayoutInlineChildren()
- {
- LayoutUnit repaintLogicalTop = 0;
- LayoutUnit repaintLogicalBottom = 0;
- rebuildFloatsFromIntruding();
- layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
- }
+ void rebuildFloatsFromIntruding();
+ void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, LayoutUnit afterEdge);
void createFloatingObjects();
- virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE;
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
void addOverflowFromFloats();
- virtual void insertedIntoTree() OVERRIDE;
- virtual void willBeDestroyed() OVERRIDE;
+ LayoutUnit logicalRightOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
+ {
+ return adjustLogicalRightOffsetForLine(logicalRightFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
+ }
+ LayoutUnit logicalLeftOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit logicalHeight = 0) const
+ {
+ return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
+ }
+
+ virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/, SubtreeLayoutScope&);
+ virtual bool updateLogicalWidthAndColumnWidth() OVERRIDE;
+
+ // These functions optionally update LayoutState's layoutDelta, which is used to ensure they're repainted correctly when moved
+ enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
+ void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
+ void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
+ void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
+
private:
- void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom, SubtreeLayoutScope&);
- void layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
+ bool layoutBlockFlow(bool relayoutChildren, LayoutUnit& pageLogicalHeight, SubtreeLayoutScope&);
+ void layoutBlockChildren(bool relayoutChildren, SubtreeLayoutScope&, LayoutUnit beforeEdge, LayoutUnit afterEdge);
- void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom);
+ void layoutBlockChild(RenderBox* child, MarginInfo&, LayoutUnit& previousFloatLogicalBottom);
void adjustPositionedBlock(RenderBox* child, const MarginInfo&);
void adjustFloatingBlock(const MarginInfo&);
- void rebuildFloatsFromIntruding();
-
LayoutPoint flipFloatForWritingModeForChild(const FloatingObject*, const LayoutPoint&) const;
LayoutUnit xPositionForFloatIncludingMargin(const FloatingObject* child) const
@@ -218,32 +267,39 @@ private:
bool hasOverhangingFloats() { return parent() && !hasColumns() && containsFloats() && lowestFloatLogicalBottom() > logicalHeight(); }
bool hasOverhangingFloat(RenderBox*);
void addIntrudingFloats(RenderBlockFlow* prev, LayoutUnit xoffset, LayoutUnit yoffset);
- LayoutUnit addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats);
+ void addOverhangingFloats(RenderBlockFlow* child, bool makeChildPaintOtherFloats);
LayoutUnit lowestFloatLogicalBottom(FloatingObject::Type = FloatingObject::FloatLeftRight) const;
LayoutUnit nextFloatLogicalBottomBelow(LayoutUnit, ShapeOutsideFloatOffsetMode = ShapeOutsideFloatMarginBoxOffset) const;
virtual bool hitTestFloats(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) OVERRIDE FINAL;
- virtual void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert) OVERRIDE;
virtual void repaintOverhangingFloats(bool paintAllDescendants) OVERRIDE FINAL;
- virtual void repaintOverflow() OVERRIDE;
+ virtual void invalidatePaintForOverflow() OVERRIDE FINAL;
virtual void paintFloats(PaintInfo&, const LayoutPoint&, bool preservePhase = false) OVERRIDE FINAL;
virtual void clipOutFloatingObjects(RenderBlock*, const PaintInfo*, const LayoutPoint&, const LayoutSize&) OVERRIDE;
void clearFloats(EClear);
- virtual LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const OVERRIDE;
- virtual LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const OVERRIDE;
+ LayoutUnit logicalRightFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const;
+ LayoutUnit logicalLeftFloatOffsetForLine(LayoutUnit logicalTop, LayoutUnit fixedOffset, LayoutUnit logicalHeight) const;
LayoutUnit logicalRightOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
LayoutUnit logicalLeftOffsetForPositioningFloat(LayoutUnit logicalTop, LayoutUnit fixedOffset, bool applyTextIndent, LayoutUnit* heightRemaining) const;
+ LayoutUnit adjustLogicalRightOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
+ LayoutUnit adjustLogicalLeftOffsetForLine(LayoutUnit offsetFromFloats, bool applyTextIndent) const;
+
virtual void adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const OVERRIDE; // Helper function for borderFitAdjust
- virtual RootInlineBox* createRootInlineBox() OVERRIDE;
+ virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG
+
+ void createOrDestroyMultiColumnFlowThreadIfNeeded();
+
+ void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount);
+ void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
+ bool shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight, LayoutUnit layoutOverflowLogicalBottom) const;
+ void setColumnCountAndHeight(unsigned count, LayoutUnit pageLogicalHeight);
- void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount);
- virtual bool relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer&);
public:
struct FloatWithRect {
FloatWithRect(RenderBox* f)
@@ -285,18 +341,15 @@ public:
};
MarginValues marginValuesForChild(RenderBox* child) const;
- virtual void updateLogicalHeight() OVERRIDE;
-
// Allocated only when some of these fields have non-default values
struct RenderBlockFlowRareData {
WTF_MAKE_NONCOPYABLE(RenderBlockFlowRareData); WTF_MAKE_FAST_ALLOCATED;
public:
RenderBlockFlowRareData(const RenderBlockFlow* block)
: m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
- , m_lineGridBox(0)
+ , m_multiColumnFlowThread(0)
, m_discardMarginBefore(false)
, m_discardMarginAfter(false)
- , m_renderNamedFlowFragment(0)
{
}
@@ -319,17 +372,13 @@ public:
MarginValues m_margins;
- RootInlineBox* m_lineGridBox;
+ RenderMultiColumnFlowThread* m_multiColumnFlowThread;
bool m_discardMarginBefore : 1;
bool m_discardMarginAfter : 1;
- RenderNamedFlowFragment* m_renderNamedFlowFragment;
};
LayoutUnit marginOffsetForSelfCollapsingBlock();
- RenderNamedFlowFragment* renderNamedFlowFragment() const { return m_rareData ? m_rareData->m_renderNamedFlowFragment : 0; }
- void setRenderNamedFlowFragment(RenderNamedFlowFragment*);
-
protected:
LayoutUnit maxPositiveMarginBefore() const { return m_rareData ? m_rareData->m_margins.positiveMarginBefore() : RenderBlockFlowRareData::positiveMarginBeforeDefault(this); }
LayoutUnit maxNegativeMarginBefore() const { return m_rareData ? m_rareData->m_margins.negativeMarginBefore() : RenderBlockFlowRareData::negativeMarginBeforeDefault(this); }
@@ -367,11 +416,11 @@ private:
virtual LayoutUnit collapsedMarginBefore() const OVERRIDE FINAL { return maxPositiveMarginBefore() - maxNegativeMarginBefore(); }
virtual LayoutUnit collapsedMarginAfter() const OVERRIDE FINAL { return maxPositiveMarginAfter() - maxNegativeMarginAfter(); }
- LayoutUnit collapseMargins(RenderBox* child, MarginInfo&);
- LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos);
+ LayoutUnit collapseMargins(RenderBox* child, MarginInfo&, bool childIsSelfCollapsing);
+ LayoutUnit clearFloatsIfNeeded(RenderBox* child, MarginInfo&, LayoutUnit oldTopPosMargin, LayoutUnit oldTopNegMargin, LayoutUnit yPos, bool childIsSelfCollapsing);
LayoutUnit estimateLogicalTopPosition(RenderBox* child, const MarginInfo&, LayoutUnit& estimateWithoutPagination);
void marginBeforeEstimateForChild(RenderBox*, LayoutUnit&, LayoutUnit&, bool&) const;
- void handleAfterSideOfBlock(LayoutUnit top, LayoutUnit bottom, MarginInfo&);
+ void handleAfterSideOfBlock(RenderBox* lastChild, LayoutUnit top, LayoutUnit bottom, MarginInfo&);
void setCollapsedBottomMargin(const MarginInfo&);
LayoutUnit applyBeforeBreak(RenderBox* child, LayoutUnit logicalOffset); // If the child has a before break, then return a new yPos that shifts to the top of the next page/column.
@@ -382,16 +431,12 @@ private:
// Used to store state between styleWillChange and styleDidChange
static bool s_canPropagateFloatIntoSibling;
- virtual bool canHaveChildren() const OVERRIDE;
- virtual bool canHaveGeneratedChildren() const OVERRIDE;
-
- void createRenderNamedFlowFragmentIfNeeded();
-
RenderBlockFlowRareData& ensureRareData();
LayoutUnit m_repaintLogicalTop;
LayoutUnit m_repaintLogicalBottom;
+ virtual bool isSelfCollapsingBlock() const OVERRIDE;
protected:
OwnPtr<RenderBlockFlowRareData> m_rareData;
OwnPtr<FloatingObjects> m_floatingObjects;
@@ -406,7 +451,7 @@ protected:
// line layout code is separated from RenderBlock and RenderBlockFlow.
// START METHODS DEFINED IN RenderBlockLineLayout
private:
- InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox, bool startsNewSegment);
+ InlineFlowBox* createLineBoxes(RenderObject*, const LineInfo&, InlineBox* childBox);
RootInlineBox* constructLine(BidiRunList<BidiRun>&, const LineInfo&);
void setMarginsForRubyRun(BidiRun*, RenderRubyRun*, RenderObject*, const LineInfo&);
void computeInlineDirectionPositionsForLine(RootInlineBox*, const LineInfo&, BidiRun* firstRun, BidiRun* trailingSpaceRun, bool reachedEnd, GlyphOverflowAndFallbackFontsMap&, VerticalPositionCache&, WordMeasurements&);
@@ -417,12 +462,9 @@ private:
void appendFloatingObjectToLastLine(FloatingObject*);
// Helper function for layoutInlineChildren()
RootInlineBox* createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>&, const InlineIterator& end, LineInfo&, VerticalPositionCache&, BidiRun* trailingSpaceRun, WordMeasurements&);
- void layoutRunsAndFloats(LineLayoutState&, bool hasInlineChild);
+ void layoutRunsAndFloats(LineLayoutState&);
const InlineIterator& restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver&, const InlineIterator&);
void layoutRunsAndFloatsInRange(LineLayoutState&, InlineBidiResolver&, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines);
- void updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*&, const LayoutSize&, LineLayoutState&);
- void updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*&, LineLayoutState&);
- bool adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo*, LayoutUnit, LineLayoutState&, InlineBidiResolver&, FloatingObject*, InlineIterator&, WordMeasurements&);
void linkToEndLineIfNeeded(LineLayoutState&);
static void repaintDirtyFloats(Vector<FloatWithRect>& floats);
void checkFloatsInCleanLine(RootInlineBox*, Vector<FloatWithRect>&, size_t& floatIndex, bool& encounteredNewFloat, bool& dirtiedByFloat);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBlockLineLayout.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderBlockLineLayout.cpp
index 9c877c5d802..722299ed03c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBlockLineLayout.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBlockLineLayout.cpp
@@ -22,8 +22,7 @@
#include "config.h"
-#include "core/rendering/FastTextAutosizer.h"
-#include "core/rendering/LayoutRectRecorder.h"
+#include "core/accessibility/AXObjectCache.h"
#include "core/rendering/RenderCounter.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderLayer.h"
@@ -34,7 +33,12 @@
#include "core/rendering/TrailingFloatsRootInlineBox.h"
#include "core/rendering/VerticalPositionCache.h"
#include "core/rendering/line/BreakingContextInlineHeaders.h"
+#include "core/rendering/line/LineLayoutState.h"
+#include "core/rendering/line/LineWidth.h"
+#include "core/rendering/line/RenderTextInfo.h"
+#include "core/rendering/line/WordMeasurement.h"
#include "core/rendering/svg/SVGRootInlineBox.h"
+#include "platform/fonts/Character.h"
#include "platform/text/BidiResolver.h"
#include "wtf/RefCountedLeakCounter.h"
#include "wtf/StdLibExtras.h"
@@ -43,41 +47,8 @@
namespace WebCore {
-static IndentTextOrNot requiresIndent(bool isFirstLine, bool isAfterHardLineBreak, RenderStyle* style)
-{
- if (isFirstLine)
- return IndentText;
- if (isAfterHardLineBreak && style->textIndentLine() == TextIndentEachLine)
- return IndentText;
-
- return DoNotIndentText;
-}
-
-class LineBreaker {
-public:
- friend class BreakingContext;
- LineBreaker(RenderBlockFlow* block)
- : m_block(block)
- {
- reset();
- }
-
- InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
-
- bool lineWasHyphenated() { return m_hyphenated; }
- const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; }
- EClear clear() { return m_clear; }
-private:
- void reset();
-
- InlineIterator nextSegmentBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
- void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
-
- RenderBlockFlow* m_block;
- bool m_hyphenated;
- EClear m_clear;
- Vector<RenderBox*> m_positionedObjects;
-};
+using namespace std;
+using namespace WTF::Unicode;
static RenderObject* firstRenderObjectForDirectionalityDetermination(RenderObject* root, RenderObject* current = 0)
{
@@ -95,7 +66,7 @@ static RenderObject* firstRenderObjectForDirectionalityDetermination(RenderObjec
}
if (!current)
- current = root->firstChild();
+ current = root->slowFirstChild();
while (current) {
next = 0;
@@ -103,7 +74,7 @@ static RenderObject* firstRenderObjectForDirectionalityDetermination(RenderObjec
break;
if (!isIteratorTarget(current) && !isIsolated(current->style()->unicodeBidi()))
- next = current->firstChild();
+ next = current->slowFirstChild();
if (!next) {
while (current && current != root) {
@@ -135,7 +106,7 @@ static TextDirection determinePlaintextDirectionality(RenderObject* root, Render
static inline InlineBox* createInlineBoxForRenderer(RenderObject* obj, bool isRootLineBox, bool isOnlyRun = false)
{
if (isRootLineBox)
- return toRenderBlock(obj)->createAndAppendRootInlineBox();
+ return toRenderBlockFlow(obj)->createAndAppendRootInlineBox();
if (obj->isText()) {
InlineTextBox* textBox = toRenderText(obj)->createInlineTextBox();
@@ -171,7 +142,7 @@ static bool parentIsConstructedOrHaveNext(InlineFlowBox* parentBox)
return false;
}
-InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInfo& lineInfo, InlineBox* childBox, bool startNewSegment)
+InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInfo& lineInfo, InlineBox* childBox)
{
// See if we have an unconstructed line box for this object that is also
// the last item on the line.
@@ -194,8 +165,7 @@ InlineFlowBox* RenderBlockFlow::createLineBoxes(RenderObject* obj, const LineInf
// the same line (this can happen with very fancy language mixtures).
bool constructedNewBox = false;
bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow || inlineFlow->alwaysCreateLineBoxes();
- bool mustCreateBoxesToRoot = startNewSegment && !(parentBox && parentBox->isRootInlineBox());
- bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox) && !mustCreateBoxesToRoot;
+ bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox);
if (allowedToConstructNewBox && !canUseExistingParentBox) {
// We need to make a new box for this render object. Once
// made, we need to place it at the end of the current line.
@@ -287,19 +257,17 @@ RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, co
if (!box)
continue;
- if (!rootHasSelectedChildren && box->renderer()->selectionState() != RenderObject::SelectionNone)
+ if (!rootHasSelectedChildren && box->renderer().selectionState() != RenderObject::SelectionNone)
rootHasSelectedChildren = true;
// If we have no parent box yet, or if the run is not simply a sibling,
// then we need to construct inline boxes as necessary to properly enclose the
// run's inline box. Segments can only be siblings at the root level, as
// they are positioned separately.
- bool runStartsSegment = r->m_startsSegment;
-
- if (!parentBox || parentBox->renderer() != r->m_object->parent() || runStartsSegment)
+ if (!parentBox || parentBox->renderer() != r->m_object->parent()) {
// Create new inline boxes all the way back to the appropriate insertion point.
- parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box, runStartsSegment);
- else {
+ parentBox = createLineBoxes(r->m_object->parent(), lineInfo, box);
+ } else {
// Append the inline box to this line.
parentBox->addToLine(box);
}
@@ -314,6 +282,9 @@ RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, co
text->setDirOverride(r->dirOverride(visuallyOrdered));
if (r->m_hasHyphen)
text->setHasHyphen(true);
+
+ if (AXObjectCache* cache = document().existingAXObjectCache())
+ cache->inlineTextBoxesUpdated(r->m_object);
}
}
@@ -324,7 +295,7 @@ RootInlineBox* RenderBlockFlow::constructLine(BidiRunList<BidiRun>& bidiRuns, co
// Set the m_selectedChildren flag on the root inline box if one of the leaf inline box
// from the bidi runs walk above has a selection state.
if (rootHasSelectedChildren)
- lastLineBox()->root()->setHasSelectedChildren(true);
+ lastLineBox()->root().setHasSelectedChildren(true);
// Set bits on our inline flow boxes that indicate which sides should
// paint borders/margins/padding. This knowledge will ultimately be used when
@@ -466,11 +437,11 @@ static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
LayoutUnit hyphenWidth = 0;
if (toInlineTextBox(run->m_box)->hasHyphen()) {
const Font& font = renderer->style(lineInfo.isFirstLine())->font();
- hyphenWidth = measureHyphenWidth(renderer, font);
+ hyphenWidth = measureHyphenWidth(renderer, font, run->direction());
}
float measuredWidth = 0;
- bool kerningIsEnabled = font.typesettingFeatures() & Kerning;
+ bool kerningIsEnabled = font.fontDescription().typesettingFeatures() & Kerning;
#if OS(MACOSX)
// FIXME: Having any font feature settings enabled can lead to selection gaps on
@@ -495,7 +466,7 @@ static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
lastEndOffset = wordMeasurement.endOffset;
if (kerningIsEnabled && lastEndOffset == run->m_stop) {
int wordLength = lastEndOffset - wordMeasurement.startOffset;
- measuredWidth += renderer->width(wordMeasurement.startOffset, wordLength, xPos, lineInfo.isFirstLine());
+ measuredWidth += renderer->width(wordMeasurement.startOffset, wordLength, xPos, run->direction(), lineInfo.isFirstLine());
if (i > 0 && wordLength == 1 && renderer->characterAt(wordMeasurement.startOffset) == ' ')
measuredWidth += renderer->style()->wordSpacing();
} else
@@ -514,19 +485,19 @@ static inline void setLogicalWidthForTextRun(RootInlineBox* lineBox, BidiRun* ru
}
if (!measuredWidth)
- measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start, xPos, lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow);
+ measuredWidth = renderer->width(run->m_start, run->m_stop - run->m_start, xPos, run->direction(), lineInfo.isFirstLine(), &fallbackFonts, &glyphOverflow);
run->m_box->setLogicalWidth(measuredWidth + hyphenWidth);
if (!fallbackFonts.isEmpty()) {
ASSERT(run->m_box->isText());
- GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator;
+ GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).storedValue;
ASSERT(it->value.first.isEmpty());
copyToVector(fallbackFonts, it->value.first);
run->m_box->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
}
if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) {
ASSERT(run->m_box->isText());
- GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator;
+ GlyphOverflowAndFallbackFontsMap::ValueType* it = textBoxDataMap.add(toInlineTextBox(run->m_box), make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).storedValue;
it->value.second = glyphOverflow;
run->m_box->clearKnownToHaveNoOverflow();
}
@@ -539,9 +510,6 @@ static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun*
size_t i = 0;
for (BidiRun* r = firstRun; r; r = r->next()) {
- // This method is called once per segment, do not move past the current segment.
- if (r->m_startsSegment)
- break;
if (!r->m_box || r == trailingSpaceRun)
continue;
@@ -550,8 +518,8 @@ static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun*
ASSERT(opportunitiesInRun <= expansionOpportunityCount);
- // Only justify text if whitespace is collapsed.
- if (r->m_object->style()->collapseWhiteSpace()) {
+ // Don't justify for white-space: pre.
+ if (r->m_object->style()->whiteSpace() != PRE) {
InlineTextBox* textBox = toInlineTextBox(r->m_box);
int expansion = (availableLogicalWidth - totalLogicalWidth) * opportunitiesInRun / expansionOpportunityCount;
textBox->setExpansion(expansion);
@@ -564,10 +532,10 @@ static inline void computeExpansionForJustifiedText(BidiRun* firstRun, BidiRun*
}
}
-void RenderBlockFlow::updateLogicalWidthForAlignment(const ETextAlign& textAlign, const RootInlineBox* rootInlineBox, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount)
+void RenderBlockFlow::updateLogicalWidthForAlignment(const ETextAlign& textAlign, const RootInlineBox* rootInlineBox, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, unsigned expansionOpportunityCount)
{
TextDirection direction;
- if (rootInlineBox && rootInlineBox->renderer()->style()->unicodeBidi() == Plaintext)
+ if (rootInlineBox && rootInlineBox->renderer().style()->unicodeBidi() == Plaintext)
direction = rootInlineBox->direction();
else
direction = style()->direction();
@@ -612,15 +580,15 @@ void RenderBlockFlow::updateLogicalWidthForAlignment(const ETextAlign& textAlign
updateLogicalWidthForLeftAlignedBlock(style()->isLeftToRightDirection(), trailingSpaceRun, logicalLeft, totalLogicalWidth, availableLogicalWidth);
break;
}
+ if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+ logicalLeft += verticalScrollbarWidth();
}
static void updateLogicalInlinePositions(RenderBlockFlow* block, float& lineLogicalLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine, IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight)
{
LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedRenderer(firstLine, boxLogicalHeight);
- lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight);
- // FIXME: This shouldn't be pixel snapped once multicolumn layout has been updated to correctly carry over subpixel values.
- // https://bugs.webkit.org/show_bug.cgi?id=105461
- lineLogicalRight = block->pixelSnappedLogicalRightOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight);
+ lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight).toFloat();
+ lineLogicalRight = block->logicalRightOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight).toFloat();
availableLogicalWidth = lineLogicalRight - lineLogicalLeft;
}
@@ -633,7 +601,7 @@ void RenderBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* line
// box is only affected if it is the first child of its parent element."
// CSS3 "text-indent", "each-line" affects the first line of the block container as well as each line after a forced line break,
// but does not affect lines after a soft wrap break.
- bool isFirstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent()->firstChild() != this);
+ bool isFirstLine = lineInfo.isFirstLine() && !(isAnonymousBlock() && parent()->slowFirstChild() != this);
bool isAfterHardLineBreak = lineBox->prevRootBox() && lineBox->prevRootBox()->endsWithBreak();
IndentTextOrNot shouldIndentText = requiresIndent(isFirstLine, isAfterHardLineBreak, style());
float lineLogicalLeft;
@@ -641,35 +609,6 @@ void RenderBlockFlow::computeInlineDirectionPositionsForLine(RootInlineBox* line
float availableLogicalWidth;
updateLogicalInlinePositions(this, lineLogicalLeft, lineLogicalRight, availableLogicalWidth, isFirstLine, shouldIndentText, 0);
bool needsWordSpacing;
- ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
- if (shapeInsideInfo && shapeInsideInfo->hasSegments()) {
- BidiRun* segmentStart = firstRun;
- const SegmentList& segments = shapeInsideInfo->segments();
- float logicalLeft = max<float>(segments[0].logicalLeft, lineLogicalLeft);
- float logicalRight = min<float>(segments[0].logicalRight, lineLogicalRight);
- float startLogicalLeft = logicalLeft;
- float endLogicalRight = logicalLeft;
- float minLogicalLeft = logicalLeft;
- float maxLogicalRight = logicalLeft;
- lineBox->beginPlacingBoxRangesInInlineDirection(logicalLeft);
- for (size_t i = 0; i < segments.size(); i++) {
- if (i) {
- logicalLeft = max<float>(segments[i].logicalLeft, lineLogicalLeft);
- logicalRight = min<float>(segments[i].logicalRight, lineLogicalRight);
- }
- availableLogicalWidth = logicalRight - logicalLeft;
- BidiRun* newSegmentStart = computeInlineDirectionPositionsForSegment(lineBox, lineInfo, textAlign, logicalLeft, availableLogicalWidth, segmentStart, trailingSpaceRun, textBoxDataMap, verticalPositionCache, wordMeasurements);
- needsWordSpacing = false;
- endLogicalRight = lineBox->placeBoxRangeInInlineDirection(segmentStart->m_box, newSegmentStart ? newSegmentStart->m_box : 0, logicalLeft, minLogicalLeft, maxLogicalRight, needsWordSpacing, textBoxDataMap);
- if (!newSegmentStart || !newSegmentStart->next())
- break;
- ASSERT(newSegmentStart->m_startsSegment);
- // Discard the empty segment start marker bidi runs
- segmentStart = newSegmentStart->next();
- }
- lineBox->endPlacingBoxRangesInInlineDirection(startLogicalLeft, endLogicalRight, minLogicalLeft, maxLogicalRight);
- return;
- }
if (firstRun && firstRun->m_object->isReplaced()) {
RenderBox* renderBox = toRenderBox(firstRun->m_object);
@@ -687,8 +626,8 @@ BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBo
float& availableLogicalWidth, BidiRun* firstRun, BidiRun* trailingSpaceRun, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache,
WordMeasurements& wordMeasurements)
{
- bool needsWordSpacing = false;
- float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
+ bool needsWordSpacing = true;
+ float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth().toFloat();
unsigned expansionOpportunityCount = 0;
bool isAfterExpansion = true;
Vector<unsigned, 16> expansionOpportunities;
@@ -697,10 +636,6 @@ BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBo
BidiRun* r = firstRun;
for (; r; r = r->next()) {
- // Once we have reached the start of the next segment, we have finished
- // computing the positions for this segment's contents.
- if (r->m_startsSegment)
- break;
if (!r->m_box || r->m_object->isOutOfFlowPositioned() || r->m_box->isLineBreak())
continue; // Positioned objects are only participating to figure out their
// correct static x position. They have no effect on the width.
@@ -712,17 +647,17 @@ BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBo
toInlineTextBox(r->m_box)->setCanHaveLeadingExpansion(true);
unsigned opportunitiesInRun;
if (rt->is8Bit())
- opportunitiesInRun = Font::expansionOpportunityCount(rt->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
+ opportunitiesInRun = Character::expansionOpportunityCount(rt->characters8() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
else
- opportunitiesInRun = Font::expansionOpportunityCount(rt->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
+ opportunitiesInRun = Character::expansionOpportunityCount(rt->characters16() + r->m_start, r->m_stop - r->m_start, r->m_box->direction(), isAfterExpansion);
expansionOpportunities.append(opportunitiesInRun);
expansionOpportunityCount += opportunitiesInRun;
}
- if (int length = rt->textLength()) {
+ if (rt->textLength()) {
if (!r->m_start && needsWordSpacing && isSpaceOrNewline(rt->characterAt(r->m_start)))
- totalLogicalWidth += rt->style(lineInfo.isFirstLine())->font().wordSpacing();
- needsWordSpacing = !isSpaceOrNewline(rt->characterAt(r->m_stop - 1)) && r->m_stop == length;
+ totalLogicalWidth += rt->style(lineInfo.isFirstLine())->font().fontDescription().wordSpacing();
+ needsWordSpacing = !isSpaceOrNewline(rt->characterAt(r->m_stop - 1));
}
setLogicalWidthForTextRun(lineBox, r, rt, totalLogicalWidth, lineInfo, textBoxDataMap, verticalPositionCache, wordMeasurements);
@@ -732,7 +667,7 @@ BidiRun* RenderBlockFlow::computeInlineDirectionPositionsForSegment(RootInlineBo
RenderBox* renderBox = toRenderBox(r->m_object);
if (renderBox->isRubyRun())
setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previousObject, lineInfo);
- r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
+ r->m_box->setLogicalWidth(logicalWidthForChild(renderBox).toFloat());
totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
}
}
@@ -767,7 +702,7 @@ void RenderBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineB
// Align positioned boxes with the top of the line box. This is
// a reasonable approximation of an appropriate y position.
if (r->m_object->isOutOfFlowPositioned())
- r->m_box->setLogicalTop(logicalHeight());
+ r->m_box->setLogicalTop(logicalHeight().toFloat());
// Position is used to properly position both replaced elements and
// to update the static normal flow x/y of positioned elements.
@@ -776,83 +711,6 @@ void RenderBlockFlow::computeBlockDirectionPositionsForLine(RootInlineBox* lineB
else if (r->m_object->isBox())
toRenderBox(r->m_object)->positionLineBox(r->m_box);
}
- // Positioned objects and zero-length text nodes destroy their boxes in
- // position(), which unnecessarily dirties the line.
- lineBox->markDirty(false);
-}
-
-static inline bool isCollapsibleSpace(UChar character, RenderText* renderer)
-{
- if (character == ' ' || character == '\t' || character == softHyphen)
- return true;
- if (character == '\n')
- return !renderer->style()->preserveNewline();
- return false;
-}
-
-template <typename CharacterType>
-static inline int findFirstTrailingSpace(RenderText* lastText, const CharacterType* characters, int start, int stop)
-{
- int firstSpace = stop;
- while (firstSpace > start) {
- UChar current = characters[firstSpace - 1];
- if (!isCollapsibleSpace(current, lastText))
- break;
- firstSpace--;
- }
-
- return firstSpace;
-}
-
-inline BidiRun* RenderBlockFlow::handleTrailingSpaces(BidiRunList<BidiRun>& bidiRuns, BidiContext* currentContext)
-{
- if (!bidiRuns.runCount()
- || !bidiRuns.logicallyLastRun()->m_object->style()->breakOnlyAfterWhiteSpace()
- || !bidiRuns.logicallyLastRun()->m_object->style()->autoWrap())
- return 0;
-
- BidiRun* trailingSpaceRun = bidiRuns.logicallyLastRun();
- RenderObject* lastObject = trailingSpaceRun->m_object;
- if (!lastObject->isText())
- return 0;
-
- RenderText* lastText = toRenderText(lastObject);
- int firstSpace;
- if (lastText->is8Bit())
- firstSpace = findFirstTrailingSpace(lastText, lastText->characters8(), trailingSpaceRun->start(), trailingSpaceRun->stop());
- else
- firstSpace = findFirstTrailingSpace(lastText, lastText->characters16(), trailingSpaceRun->start(), trailingSpaceRun->stop());
-
- if (firstSpace == trailingSpaceRun->stop())
- return 0;
-
- TextDirection direction = style()->direction();
- bool shouldReorder = trailingSpaceRun != (direction == LTR ? bidiRuns.lastRun() : bidiRuns.firstRun());
- if (firstSpace != trailingSpaceRun->start()) {
- BidiContext* baseContext = currentContext;
- while (BidiContext* parent = baseContext->parent())
- baseContext = parent;
-
- BidiRun* newTrailingRun = new BidiRun(firstSpace, trailingSpaceRun->m_stop, trailingSpaceRun->m_object, baseContext, OtherNeutral);
- trailingSpaceRun->m_stop = firstSpace;
- if (direction == LTR)
- bidiRuns.addRun(newTrailingRun);
- else
- bidiRuns.prependRun(newTrailingRun);
- trailingSpaceRun = newTrailingRun;
- return trailingSpaceRun;
- }
- if (!shouldReorder)
- return trailingSpaceRun;
-
- if (direction == LTR) {
- bidiRuns.moveRunToEnd(trailingSpaceRun);
- trailingSpaceRun->m_level = 0;
- } else {
- bidiRuns.moveRunToBeginning(trailingSpaceRun);
- trailingSpaceRun->m_level = 1;
- }
- return trailingSpaceRun;
}
void RenderBlockFlow::appendFloatingObjectToLastLine(FloatingObject* floatingObject)
@@ -891,14 +749,14 @@ static void restoreIsolatedMidpointStates(InlineBidiResolver& topResolver, Inlin
}
// FIXME: BidiResolver should have this logic.
-static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfRuns, VisualDirectionOverride override, bool previousLineBrokeCleanly, bool isNewUBAParagraph)
+static inline void constructBidiRunsForLine(const RenderBlockFlow* block, InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, bool isNewUBAParagraph)
{
// FIXME: We should pass a BidiRunList into createBidiRunsForLine instead
// of the resolver owning the runs.
ASSERT(&topResolver.runs() == &bidiRuns);
- ASSERT(topResolver.position() != endOfRuns);
+ ASSERT(topResolver.position() != endOfLine);
RenderObject* currentRoot = topResolver.position().root();
- topResolver.createBidiRunsForLine(endOfRuns, override, previousLineBrokeCleanly);
+ topResolver.createBidiRunsForLine(endOfLine, override, previousLineBrokeCleanly);
while (!topResolver.isolatedRuns().isEmpty()) {
// It does not matter which order we resolve the runs as long as we resolve them all.
@@ -919,7 +777,7 @@ static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver,
LineMidpointState& isolatedLineMidpointState = isolatedResolver.midpointState();
isolatedLineMidpointState = topResolver.midpointStateForIsolatedRun(isolatedRun);
EUnicodeBidi unicodeBidi = isolatedInline->style()->unicodeBidi();
- TextDirection direction = isolatedInline->style()->direction();
+ TextDirection direction;
if (unicodeBidi == Plaintext) {
if (isNewUBAParagraph)
direction = determinePlaintextDirectionality(isolatedInline, startObj);
@@ -941,7 +799,7 @@ static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver,
// We stop at the next end of line; we may re-enter this isolate in the next call to constructBidiRuns().
// FIXME: What should end and previousLineBrokeCleanly be?
// rniwa says previousLineBrokeCleanly is just a WinIE hack and could always be false here?
- isolatedResolver.createBidiRunsForLine(endOfRuns, NoVisualOverride, previousLineBrokeCleanly);
+ isolatedResolver.createBidiRunsForLine(endOfLine, NoVisualOverride, previousLineBrokeCleanly);
ASSERT(isolatedResolver.runs().runCount());
if (isolatedResolver.runs().runCount())
@@ -950,49 +808,13 @@ static inline void constructBidiRunsForSegment(InlineBidiResolver& topResolver,
// If we encountered any nested isolate runs, just move them
// to the top resolver's list for later processing.
if (!isolatedResolver.isolatedRuns().isEmpty()) {
- topResolver.isolatedRuns().append(isolatedResolver.isolatedRuns());
+ topResolver.isolatedRuns().appendVector(isolatedResolver.isolatedRuns());
currentRoot = isolatedInline;
restoreIsolatedMidpointStates(topResolver, isolatedResolver);
}
}
}
-static inline bool segmentIsEmpty(const InlineIterator& segmentStart, const InlineIterator& segmentEnd)
-{
- return segmentStart == segmentEnd;
-}
-
-static inline void constructBidiRunsForLine(const RenderBlockFlow* block, InlineBidiResolver& topResolver, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& endOfLine, VisualDirectionOverride override, bool previousLineBrokeCleanly, bool isNewUBAParagraph)
-{
- ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo();
- if (!shapeInsideInfo || !shapeInsideInfo->hasSegments()) {
- constructBidiRunsForSegment(topResolver, bidiRuns, endOfLine, override, previousLineBrokeCleanly, isNewUBAParagraph);
- return;
- }
-
- const SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges();
- ASSERT(segmentRanges.size());
-
- for (size_t i = 0; i < segmentRanges.size(); i++) {
- LineSegmentIterator iterator = segmentRanges[i].start;
- InlineIterator segmentStart(iterator.root, iterator.object, iterator.offset);
- iterator = segmentRanges[i].end;
- InlineIterator segmentEnd(iterator.root, iterator.object, iterator.offset);
- if (i) {
- ASSERT(segmentStart.object());
- BidiRun* segmentMarker = createRun(segmentStart.m_pos, segmentStart.m_pos, segmentStart.object(), topResolver);
- segmentMarker->m_startsSegment = true;
- bidiRuns.addRun(segmentMarker);
- // Do not collapse midpoints between segments
- topResolver.midpointState().betweenMidpoints = false;
- }
- if (!segmentIsEmpty(segmentStart, segmentEnd)) {
- topResolver.setPosition(segmentStart, numberOfIsolateAncestors(segmentStart));
- constructBidiRunsForSegment(topResolver, bidiRuns, segmentEnd, override, previousLineBrokeCleanly, isNewUBAParagraph);
- }
- }
-}
-
// This function constructs line boxes for all of the text runs in the resolver and computes their position.
RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel, BidiRunList<BidiRun>& bidiRuns, const InlineIterator& end, LineInfo& lineInfo, VerticalPositionCache& verticalPositionCache, BidiRun* trailingSpaceRun, WordMeasurements& wordMeasurements)
{
@@ -1036,95 +858,6 @@ RootInlineBox* RenderBlockFlow::createLineBoxesFromBidiRuns(unsigned bidiLevel,
return lineBox;
}
-// Like LayoutState for layout(), LineLayoutState keeps track of global information
-// during an entire linebox tree layout pass (aka layoutInlineChildren).
-class LineLayoutState {
-public:
- LineLayoutState(bool fullLayout, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, RenderFlowThread* flowThread)
- : m_lastFloat(0)
- , m_endLine(0)
- , m_floatIndex(0)
- , m_endLineLogicalTop(0)
- , m_endLineMatched(false)
- , m_checkForFloatsFromLastLine(false)
- , m_isFullLayout(fullLayout)
- , m_repaintLogicalTop(repaintLogicalTop)
- , m_repaintLogicalBottom(repaintLogicalBottom)
- , m_adjustedLogicalLineTop(0)
- , m_usesRepaintBounds(false)
- , m_flowThread(flowThread)
- { }
-
- void markForFullLayout() { m_isFullLayout = true; }
- bool isFullLayout() const { return m_isFullLayout; }
-
- bool usesRepaintBounds() const { return m_usesRepaintBounds; }
-
- void setRepaintRange(LayoutUnit logicalHeight)
- {
- m_usesRepaintBounds = true;
- m_repaintLogicalTop = m_repaintLogicalBottom = logicalHeight;
- }
-
- void updateRepaintRangeFromBox(RootInlineBox* box, LayoutUnit paginationDelta = 0)
- {
- m_usesRepaintBounds = true;
- m_repaintLogicalTop = min(m_repaintLogicalTop, box->logicalTopVisualOverflow() + min<LayoutUnit>(paginationDelta, 0));
- m_repaintLogicalBottom = max(m_repaintLogicalBottom, box->logicalBottomVisualOverflow() + max<LayoutUnit>(paginationDelta, 0));
- }
-
- bool endLineMatched() const { return m_endLineMatched; }
- void setEndLineMatched(bool endLineMatched) { m_endLineMatched = endLineMatched; }
-
- bool checkForFloatsFromLastLine() const { return m_checkForFloatsFromLastLine; }
- void setCheckForFloatsFromLastLine(bool check) { m_checkForFloatsFromLastLine = check; }
-
- LineInfo& lineInfo() { return m_lineInfo; }
- const LineInfo& lineInfo() const { return m_lineInfo; }
-
- LayoutUnit endLineLogicalTop() const { return m_endLineLogicalTop; }
- void setEndLineLogicalTop(LayoutUnit logicalTop) { m_endLineLogicalTop = logicalTop; }
-
- RootInlineBox* endLine() const { return m_endLine; }
- void setEndLine(RootInlineBox* line) { m_endLine = line; }
-
- FloatingObject* lastFloat() const { return m_lastFloat; }
- void setLastFloat(FloatingObject* lastFloat) { m_lastFloat = lastFloat; }
-
- Vector<RenderBlockFlow::FloatWithRect>& floats() { return m_floats; }
-
- unsigned floatIndex() const { return m_floatIndex; }
- void setFloatIndex(unsigned floatIndex) { m_floatIndex = floatIndex; }
-
- LayoutUnit adjustedLogicalLineTop() const { return m_adjustedLogicalLineTop; }
- void setAdjustedLogicalLineTop(LayoutUnit value) { m_adjustedLogicalLineTop = value; }
-
- RenderFlowThread* flowThread() const { return m_flowThread; }
- void setFlowThread(RenderFlowThread* thread) { m_flowThread = thread; }
-
-private:
- Vector<RenderBlockFlow::FloatWithRect> m_floats;
- FloatingObject* m_lastFloat;
- RootInlineBox* m_endLine;
- LineInfo m_lineInfo;
- unsigned m_floatIndex;
- LayoutUnit m_endLineLogicalTop;
- bool m_endLineMatched;
- bool m_checkForFloatsFromLastLine;
-
- bool m_isFullLayout;
-
- // FIXME: Should this be a range object instead of two ints?
- LayoutUnit& m_repaintLogicalTop;
- LayoutUnit& m_repaintLogicalBottom;
-
- LayoutUnit m_adjustedLogicalLineTop;
-
- bool m_usesRepaintBounds;
-
- RenderFlowThread* m_flowThread;
-};
-
static void deleteLineRange(LineLayoutState& layoutState, RootInlineBox* startLine, RootInlineBox* stopLine = 0)
{
RootInlineBox* boxToDelete = startLine;
@@ -1138,7 +871,7 @@ static void deleteLineRange(LineLayoutState& layoutState, RootInlineBox* startLi
}
}
-void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState, bool hasInlineChild)
+void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState)
{
// We want to skip ahead to the first dirty line
InlineBidiResolver resolver;
@@ -1150,30 +883,8 @@ void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState, bool has
consecutiveHyphenatedLines++;
}
- // FIXME: This would make more sense outside of this function, but since
- // determineStartPosition can change the fullLayout flag we have to do this here. Failure to call
- // determineStartPosition first will break fast/repaint/line-flow-with-floats-9.html.
- if (layoutState.isFullLayout() && hasInlineChild && !selfNeedsLayout()) {
- // Mark as needing a full layout to force us to repaint. Allow regions
- // to reflow as needed.
- setNeedsLayout(MarkOnlyThis);
-
- if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
- setShouldDoFullRepaintAfterLayout(true);
- } else {
- RenderView* v = view();
- if (v && !v->doingFullRepaint() && hasLayer()) {
- // Because we waited until we were already inside layout to discover
- // that the block really needed a full layout, we missed our chance to repaint the layer
- // before layout started. Luckily the layer has cached the repaint rect for its original
- // position and size, and so we can use that to make a repaint happen now.
- repaintUsingContainer(containerForRepaint(), pixelSnappedIntRect(layer()->repainter().repaintRect()));
- }
- }
- }
-
if (containsFloats())
- layoutState.setLastFloat(m_floatingObjects->set().last());
+ layoutState.setLastFloat(m_floatingObjects->set().last().get());
// We also find the first clean line and extract these lines. We will add them back
// if we determine that we're able to synchronize after handling all our dirty lines.
@@ -1193,9 +904,9 @@ void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState, bool has
// adjust the height accordingly.
// A line break can be either the first or the last object on a line, depending on its direction.
if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
- RenderObject* lastObject = lastLeafChild->renderer();
+ RenderObject* lastObject = &lastLeafChild->renderer();
if (!lastObject->isBR())
- lastObject = lastRootBox()->firstLeafChild()->renderer();
+ lastObject = &lastRootBox()->firstLeafChild()->renderer();
if (lastObject->isBR()) {
EClear clear = lastObject->style()->clear();
if (clear != CNONE)
@@ -1209,16 +920,6 @@ void RenderBlockFlow::layoutRunsAndFloats(LineLayoutState& layoutState, bool has
repaintDirtyFloats(layoutState.floats());
}
-RenderTextInfo::RenderTextInfo()
- : m_text(0)
- , m_font(0)
-{
-}
-
-RenderTextInfo::~RenderTextInfo()
-{
-}
-
// Before restarting the layout loop with a new logicalHeight, remove all floats that were added and reset the resolver.
inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange(LayoutUnit oldLogicalHeight, LayoutUnit newLogicalHeight, FloatingObject* lastFloatFromPreviousLine, InlineBidiResolver& resolver, const InlineIterator& oldEnd)
{
@@ -1228,161 +929,6 @@ inline const InlineIterator& RenderBlockFlow::restartLayoutRunsAndFloatsInRange(
return oldEnd;
}
-static inline LayoutUnit adjustLogicalLineTop(ShapeInsideInfo* shapeInsideInfo, InlineIterator start, InlineIterator end, const WordMeasurements& wordMeasurements)
-{
- if (!shapeInsideInfo || end != start)
- return 0;
-
- float minWidth = firstPositiveWidth(wordMeasurements);
- ASSERT(minWidth || wordMeasurements.isEmpty());
- if (minWidth > 0 && shapeInsideInfo->adjustLogicalLineTop(minWidth))
- return shapeInsideInfo->logicalLineTop();
-
- return shapeInsideInfo->shapeLogicalBottom();
-}
-
-static inline void pushShapeContentOverflowBelowTheContentBox(RenderBlockFlow* block, ShapeInsideInfo* shapeInsideInfo, LayoutUnit lineTop, LayoutUnit lineHeight)
-{
- ASSERT(shapeInsideInfo);
-
- LayoutUnit logicalLineBottom = lineTop + lineHeight;
- LayoutUnit shapeLogicalBottom = shapeInsideInfo->shapeLogicalBottom();
- LayoutUnit shapeContainingBlockHeight = shapeInsideInfo->shapeContainingBlockHeight();
-
- bool isOverflowPositionedAlready = (shapeContainingBlockHeight - shapeInsideInfo->owner()->borderAndPaddingAfter() + lineHeight) <= lineTop;
-
- // If the last line overlaps with the shape, we don't need the segments anymore
- if (lineTop < shapeLogicalBottom && shapeLogicalBottom < logicalLineBottom)
- shapeInsideInfo->clearSegments();
- if (logicalLineBottom <= shapeLogicalBottom || !shapeContainingBlockHeight || isOverflowPositionedAlready)
- return;
-
- LayoutUnit newLogicalHeight = block->logicalHeight() + (shapeContainingBlockHeight - (lineTop + shapeInsideInfo->owner()->borderAndPaddingAfter()));
- block->setLogicalHeight(newLogicalHeight);
-}
-
-void RenderBlockFlow::updateShapeAndSegmentsForCurrentLine(ShapeInsideInfo*& shapeInsideInfo, const LayoutSize& logicalOffsetFromShapeContainer, LineLayoutState& layoutState)
-{
- if (layoutState.flowThread())
- return updateShapeAndSegmentsForCurrentLineInFlowThread(shapeInsideInfo, layoutState);
-
- if (!shapeInsideInfo)
- return;
-
- LayoutUnit lineTop = logicalHeight() + logicalOffsetFromShapeContainer.height();
- LayoutUnit lineLeft = logicalOffsetFromShapeContainer.width();
- LayoutUnit lineHeight = this->lineHeight(layoutState.lineInfo().isFirstLine(), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
-
- // FIXME: Bug 95361: It is possible for a line to grow beyond lineHeight, in which case these segments may be incorrect.
- shapeInsideInfo->updateSegmentsForLine(LayoutSize(lineLeft, lineTop), lineHeight);
-
- pushShapeContentOverflowBelowTheContentBox(this, shapeInsideInfo, lineTop, lineHeight);
-}
-
-void RenderBlockFlow::updateShapeAndSegmentsForCurrentLineInFlowThread(ShapeInsideInfo*& shapeInsideInfo, LineLayoutState& layoutState)
-{
- ASSERT(layoutState.flowThread());
-
- RenderRegion* currentRegion = regionAtBlockOffset(logicalHeight());
- if (!currentRegion || !currentRegion->logicalHeight())
- return;
-
- shapeInsideInfo = currentRegion->shapeInsideInfo();
-
- RenderRegion* nextRegion = 0;
- if (!currentRegion->isLastRegion()) {
- RenderRegionList regionList = layoutState.flowThread()->renderRegionList();
- RenderRegionList::const_iterator it = regionList.find(currentRegion);
- nextRegion = *(++it);
- }
-
- // We only want to deal regions with shapes, so we check if the next region has a shape
- if (!shapeInsideInfo && nextRegion && !nextRegion->shapeInsideInfo())
- return;
-
- LayoutUnit lineHeight = this->lineHeight(layoutState.lineInfo().isFirstLine(), isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
- LayoutUnit logicalLineTopInFlowThread = logicalHeight() + offsetFromLogicalTopOfFirstPage();
- LayoutUnit logicalLineBottomInFlowThread = logicalLineTopInFlowThread + lineHeight;
- LayoutUnit logicalRegionTopInFlowThread = currentRegion->logicalTopForFlowThreadContent();
- LayoutUnit logicalRegionBottomInFlowThread = logicalRegionTopInFlowThread + currentRegion->logicalHeight() - currentRegion->borderAndPaddingBefore() - currentRegion->borderAndPaddingAfter();
-
- LayoutUnit shapeBottomInFlowThread = LayoutUnit::max();
- if (shapeInsideInfo)
- shapeBottomInFlowThread = shapeInsideInfo->shapeLogicalBottom() + currentRegion->logicalTopForFlowThreadContent();
-
- bool lineOverLapsWithShapeBottom = shapeBottomInFlowThread < logicalLineBottomInFlowThread;
- bool lineOverLapsWithRegionBottom = logicalLineBottomInFlowThread > logicalRegionBottomInFlowThread;
- bool overFlowsToNextRegion = nextRegion && (lineOverLapsWithShapeBottom || lineOverLapsWithRegionBottom);
-
- // If the line is between two shapes/regions we position the line to the top of the next shape/region
- if (overFlowsToNextRegion) {
- ASSERT(currentRegion != nextRegion);
- LayoutUnit deltaToNextRegion = logicalRegionBottomInFlowThread - logicalLineTopInFlowThread;
- setLogicalHeight(logicalHeight() + deltaToNextRegion);
-
- currentRegion = nextRegion;
- shapeInsideInfo = currentRegion->shapeInsideInfo();
-
- logicalLineTopInFlowThread = logicalHeight() + offsetFromLogicalTopOfFirstPage();
- logicalLineBottomInFlowThread = logicalLineTopInFlowThread + lineHeight;
- logicalRegionTopInFlowThread = currentRegion->logicalTopForFlowThreadContent();
- logicalRegionBottomInFlowThread = logicalRegionTopInFlowThread + currentRegion->logicalHeight() - currentRegion->borderAndPaddingBefore() - currentRegion->borderAndPaddingAfter();
- }
-
- if (!shapeInsideInfo)
- return;
-
- bool isFirstLineInRegion = logicalLineBottomInFlowThread <= (logicalRegionTopInFlowThread + lineHeight);
- bool isFirstLineAdjusted = (logicalLineTopInFlowThread - logicalRegionTopInFlowThread) < (layoutState.adjustedLogicalLineTop() - currentRegion->borderAndPaddingBefore());
- // We position the first line to the top of the shape in the region or to the previously adjusted position in the shape
- if (isFirstLineInRegion || isFirstLineAdjusted) {
- LayoutUnit shapeTopOffset = layoutState.adjustedLogicalLineTop();
- if (!shapeTopOffset && (shapeInsideInfo->shapeLogicalTop() > 0))
- shapeTopOffset = shapeInsideInfo->shapeLogicalTop();
-
- LayoutUnit shapePositionInFlowThread = currentRegion->logicalTopForFlowThreadContent() + shapeTopOffset;
- LayoutUnit shapeTopLineTopDelta = shapePositionInFlowThread - logicalLineTopInFlowThread - currentRegion->borderAndPaddingBefore();
-
- setLogicalHeight(logicalHeight() + shapeTopLineTopDelta);
- logicalLineTopInFlowThread += shapeTopLineTopDelta;
- layoutState.setAdjustedLogicalLineTop(0);
- }
-
- LayoutUnit lineTop = logicalLineTopInFlowThread - currentRegion->logicalTopForFlowThreadContent() + currentRegion->borderAndPaddingBefore();
- // FIXME: Shape inside on a region does not yet take into account its padding for nested flow blocks
- shapeInsideInfo->updateSegmentsForLine(LayoutSize(0, lineTop), lineHeight);
-
- if (currentRegion->isLastRegion())
- pushShapeContentOverflowBelowTheContentBox(this, shapeInsideInfo, lineTop, lineHeight);
-}
-
-bool RenderBlockFlow::adjustLogicalLineTopAndLogicalHeightIfNeeded(ShapeInsideInfo* shapeInsideInfo, LayoutUnit absoluteLogicalTop, LineLayoutState& layoutState, InlineBidiResolver& resolver, FloatingObject* lastFloatFromPreviousLine, InlineIterator& end, WordMeasurements& wordMeasurements)
-{
- LayoutUnit adjustedLogicalLineTop = adjustLogicalLineTop(shapeInsideInfo, resolver.position(), end, wordMeasurements);
-
- if (shapeInsideInfo && containsFloats()) {
- lastFloatFromPreviousLine = m_floatingObjects->set().last();
- if (!wordMeasurements.size()) {
- LayoutUnit floatLogicalTopOffset = shapeInsideInfo->computeFirstFitPositionForFloat(logicalSizeForFloat(lastFloatFromPreviousLine));
- if (logicalHeight() < floatLogicalTopOffset)
- adjustedLogicalLineTop = floatLogicalTopOffset;
- }
- }
-
- if (!adjustedLogicalLineTop)
- return false;
-
- LayoutUnit newLogicalHeight = adjustedLogicalLineTop - absoluteLogicalTop;
-
- if (layoutState.flowThread()) {
- layoutState.setAdjustedLogicalLineTop(adjustedLogicalLineTop);
- newLogicalHeight = logicalHeight();
- }
-
- end = restartLayoutRunsAndFloatsInRange(logicalHeight(), newLogicalHeight, lastFloatFromPreviousLine, resolver, end);
- return true;
-}
-
void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, InlineBidiResolver& resolver, const InlineIterator& cleanLineStart, const BidiStatus& cleanLineBidiStatus, unsigned consecutiveHyphenatedLines)
{
RenderStyle* styleToUse = style();
@@ -1396,22 +942,6 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
LineBreaker lineBreaker(this);
LayoutSize logicalOffsetFromShapeContainer;
- ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
- if (shapeInsideInfo) {
- ASSERT(shapeInsideInfo->owner() == this || allowsShapeInsideInfoSharing(shapeInsideInfo->owner()));
- if (shapeInsideInfo != this->shapeInsideInfo()) {
- // FIXME Bug 100284: If subsequent LayoutStates are pushed, we will have to add
- // their offsets from the original shape-inside container.
- logicalOffsetFromShapeContainer = logicalOffsetFromShapeAncestorContainer(shapeInsideInfo->owner());
- }
- // Begin layout at the logical top of our shape inside.
- if (logicalHeight() + logicalOffsetFromShapeContainer.height() < shapeInsideInfo->shapeLogicalTop()) {
- LayoutUnit logicalHeight = shapeInsideInfo->shapeLogicalTop() - logicalOffsetFromShapeContainer.height();
- if (layoutState.flowThread())
- logicalHeight -= shapeInsideInfo->owner()->borderAndPaddingBefore();
- setLogicalHeight(logicalHeight);
- }
- }
while (!endOfLine.atEnd()) {
// FIXME: Is this check necessary before the first iteration or can it be moved to the end?
@@ -1430,9 +960,7 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
const InlineIterator previousEndofLine = endOfLine;
bool isNewUBAParagraph = layoutState.lineInfo().previousLineBrokeCleanly();
- FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_floatingObjects->set().last() : 0;
-
- updateShapeAndSegmentsForCurrentLine(shapeInsideInfo, logicalOffsetFromShapeContainer, layoutState);
+ FloatingObject* lastFloatFromPreviousLine = (containsFloats()) ? m_floatingObjects->set().last().get() : 0;
WordMeasurements wordMeasurements;
endOfLine = lineBreaker.nextLineBreak(resolver, layoutState.lineInfo(), renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
@@ -1447,18 +975,14 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
break;
}
- if (adjustLogicalLineTopAndLogicalHeightIfNeeded(shapeInsideInfo, logicalOffsetFromShapeContainer.height(), layoutState, resolver, lastFloatFromPreviousLine, endOfLine, wordMeasurements))
- continue;
-
ASSERT(endOfLine != resolver.position());
// This is a short-cut for empty lines.
if (layoutState.lineInfo().isEmpty()) {
if (lastRootBox())
- lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.m_pos, resolver.status());
+ lastRootBox()->setLineBreakInfo(endOfLine.object(), endOfLine.offset(), resolver.status());
} else {
VisualDirectionOverride override = (styleToUse->rtlOrdering() == VisualOrder ? (styleToUse->direction() == LTR ? VisualLeftToRightOverride : VisualRightToLeftOverride) : NoVisualOverride);
-
if (isNewUBAParagraph && styleToUse->unicodeBidi() == Plaintext && !resolver.context()->parent()) {
TextDirection direction = determinePlaintextDirectionality(resolver.position().root(), resolver.position().object(), resolver.position().offset());
resolver.setStatus(BidiStatus(direction, isOverride(styleToUse->unicodeBidi())));
@@ -1468,7 +992,7 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
constructBidiRunsForLine(this, resolver, bidiRuns, endOfLine, override, layoutState.lineInfo().previousLineBrokeCleanly(), isNewUBAParagraph);
ASSERT(resolver.position() == endOfLine);
- BidiRun* trailingSpaceRun = !layoutState.lineInfo().previousLineBrokeCleanly() ? handleTrailingSpaces(bidiRuns, resolver.context()) : 0;
+ BidiRun* trailingSpaceRun = resolver.trailingSpaceRun();
if (bidiRuns.runCount() && lineBreaker.lineWasHyphenated()) {
bidiRuns.logicallyLastRun()->m_hasHyphen = true;
@@ -1487,7 +1011,7 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
resolver.markCurrentRunEmpty(); // FIXME: This can probably be replaced by an ASSERT (or just removed).
if (lineBox) {
- lineBox->setLineBreakInfo(endOfLine.object(), endOfLine.m_pos, resolver.status());
+ lineBox->setLineBreakInfo(endOfLine.object(), endOfLine.offset(), resolver.status());
if (layoutState.usesRepaintBounds())
layoutState.updateRepaintRangeFromBox(lineBox);
@@ -1496,7 +1020,7 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
adjustLinePositionForPagination(lineBox, adjustment, layoutState.flowThread());
if (adjustment) {
LayoutUnit oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, layoutState.lineInfo().isFirstLine());
- lineBox->adjustBlockDirectionPosition(adjustment);
+ lineBox->adjustBlockDirectionPosition(adjustment.toFloat());
if (layoutState.usesRepaintBounds())
layoutState.updateRepaintRangeFromBox(lineBox);
@@ -1509,9 +1033,6 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
setLogicalHeight(lineBox->lineBottomWithLeading());
}
-
- if (layoutState.flowThread())
- updateRegionForLine(lineBox);
}
}
}
@@ -1535,7 +1056,7 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
it = lastFloatIterator;
}
for (; it != end; ++it) {
- FloatingObject* f = *it;
+ FloatingObject* f = it->get();
appendFloatingObjectToLastLine(f);
ASSERT(f->renderer() == layoutState.floats()[layoutState.floatIndex()].object);
// If a float's geometry has changed, give up on syncing with clean lines.
@@ -1543,7 +1064,7 @@ void RenderBlockFlow::layoutRunsAndFloatsInRange(LineLayoutState& layoutState, I
checkForEndLineMatch = false;
layoutState.setFloatIndex(layoutState.floatIndex() + 1);
}
- layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0);
+ layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : 0);
}
lineMidpointState.reset();
@@ -1628,10 +1149,8 @@ void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
}
if (delta) {
layoutState.updateRepaintRangeFromBox(line, delta);
- line->adjustBlockDirectionPosition(delta);
+ line->adjustBlockDirectionPosition(delta.toFloat());
}
- if (layoutState.flowThread())
- updateRegionForLine(line);
if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
Vector<RenderBox*>::iterator end = cleanLineFloats->end();
for (Vector<RenderBox*>::iterator f = cleanLineFloats->begin(); f != end; ++f) {
@@ -1657,7 +1176,7 @@ void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
if (layoutState.checkForFloatsFromLastLine()) {
LayoutUnit bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
LayoutUnit bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
- TrailingFloatsRootInlineBox* trailingFloatsLineBox = new TrailingFloatsRootInlineBox(this);
+ TrailingFloatsRootInlineBox* trailingFloatsLineBox = new TrailingFloatsRootInlineBox(*this);
m_lineBoxes.appendLineBox(trailingFloatsLineBox);
trailingFloatsLineBox->setConstructed();
GlyphOverflowAndFallbackFontsMap textBoxDataMap;
@@ -1665,12 +1184,10 @@ void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
LayoutUnit blockLogicalHeight = logicalHeight();
trailingFloatsLineBox->alignBoxesInBlockDirection(blockLogicalHeight, textBoxDataMap, verticalPositionCache);
trailingFloatsLineBox->setLineTopBottomPositions(blockLogicalHeight, blockLogicalHeight, blockLogicalHeight, blockLogicalHeight);
- trailingFloatsLineBox->setPaginatedLineWidth(availableLogicalWidthForContent(blockLogicalHeight));
+ trailingFloatsLineBox->setPaginatedLineWidth(availableLogicalWidthForContent());
LayoutRect logicalLayoutOverflow(0, blockLogicalHeight, 1, bottomLayoutOverflow - blockLogicalHeight);
LayoutRect logicalVisualOverflow(0, blockLogicalHeight, 1, bottomVisualOverflow - blockLogicalHeight);
trailingFloatsLineBox->setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, trailingFloatsLineBox->lineTop(), trailingFloatsLineBox->lineBottom());
- if (layoutState.flowThread())
- updateRegionForLine(trailingFloatsLineBox);
}
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
@@ -1683,42 +1200,460 @@ void RenderBlockFlow::linkToEndLineIfNeeded(LineLayoutState& layoutState)
it = lastFloatIterator;
}
for (; it != end; ++it)
- appendFloatingObjectToLastLine(*it);
- layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last() : 0);
+ appendFloatingObjectToLastLine(it->get());
+ layoutState.setLastFloat(!floatingObjectSet.isEmpty() ? floatingObjectSet.last().get() : 0);
}
}
void RenderBlockFlow::repaintDirtyFloats(Vector<FloatWithRect>& floats)
{
size_t floatCount = floats.size();
- // Floats that did not have layout did not repaint when we laid them out. They would have
+ // Floats that did not have layout did not paint invalidations when we laid them out. They would have
// painted by now if they had moved, but if they stayed at (0, 0), they still need to be
// painted.
for (size_t i = 0; i < floatCount; ++i) {
if (!floats[i].everHadLayout) {
RenderBox* f = floats[i].object;
- if (!f->x() && !f->y() && f->checkForRepaintDuringLayout()) {
+ if (!f->x() && !f->y() && f->checkForPaintInvalidation()) {
if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
- f->setShouldDoFullRepaintAfterLayout(true);
+ f->setShouldDoFullPaintInvalidationAfterLayout(true);
else
- f->repaint();
+ f->paintInvalidationForWholeRenderer();
}
}
}
}
-void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
+struct InlineMinMaxIterator {
+/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
+ inline min/max width calculations. Note the following about the way it walks:
+ (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
+ (2) We do not drill into the children of floats or replaced elements, since you can't break
+ in the middle of such an element.
+ (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
+ distinct borders/margin/padding that contribute to the min/max width.
+*/
+ RenderObject* parent;
+ RenderObject* current;
+ bool endOfInline;
+
+ InlineMinMaxIterator(RenderObject* p, bool end = false)
+ : parent(p), current(p), endOfInline(end)
+ {
+
+ }
+
+ RenderObject* next();
+};
+
+RenderObject* InlineMinMaxIterator::next()
{
- FastTextAutosizer* textAutosizer = document().fastTextAutosizer();
- if (textAutosizer)
- textAutosizer->inflate(this);
+ RenderObject* result = 0;
+ bool oldEndOfInline = endOfInline;
+ endOfInline = false;
+ while (current || current == parent) {
+ if (!oldEndOfInline && (current == parent || (!current->isFloating() && !current->isReplaced() && !current->isOutOfFlowPositioned())))
+ result = current->slowFirstChild();
+
+ if (!result) {
+ // We hit the end of our inline. (It was empty, e.g., <span></span>.)
+ if (!oldEndOfInline && current->isRenderInline()) {
+ result = current;
+ endOfInline = true;
+ break;
+ }
- setLogicalHeight(borderBefore() + paddingBefore());
+ while (current && current != parent) {
+ result = current->nextSibling();
+ if (result)
+ break;
+ current = current->parent();
+ if (current && current != parent && current->isRenderInline()) {
+ result = current;
+ endOfInline = true;
+ break;
+ }
+ }
+ }
+
+ if (!result)
+ break;
- // Lay out our hypothetical grid line as though it occurs at the top of the block.
- if (view()->layoutState() && view()->layoutState()->lineGrid() == this)
- layoutLineGridBox();
+ if (!result->isOutOfFlowPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
+ break;
+ current = result;
+ result = 0;
+ }
+
+ // Update our position.
+ current = result;
+ return current;
+}
+
+static LayoutUnit getBPMWidth(LayoutUnit childValue, Length cssUnit)
+{
+ if (cssUnit.type() != Auto)
+ return (cssUnit.isFixed() ? static_cast<LayoutUnit>(cssUnit.value()) : childValue);
+ return 0;
+}
+
+static LayoutUnit getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
+{
+ RenderStyle* childStyle = child->style();
+ if (endOfInline) {
+ return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) +
+ getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) +
+ child->borderEnd();
+ }
+ return getBPMWidth(child->marginStart(), childStyle->marginStart()) +
+ getBPMWidth(child->paddingStart(), childStyle->paddingStart()) +
+ child->borderStart();
+}
+
+static inline void stripTrailingSpace(float& inlineMax, float& inlineMin, RenderObject* trailingSpaceChild)
+{
+ if (trailingSpaceChild && trailingSpaceChild->isText()) {
+ // Collapse away the trailing space at the end of a block.
+ RenderText* t = toRenderText(trailingSpaceChild);
+ const UChar space = ' ';
+ const Font& font = t->style()->font(); // FIXME: This ignores first-line.
+ float spaceWidth = font.width(RenderBlockFlow::constructTextRun(t, font, &space, 1, t->style(), LTR));
+ inlineMax -= spaceWidth + font.fontDescription().wordSpacing();
+ if (inlineMin > inlineMax)
+ inlineMin = inlineMax;
+ }
+}
+
+static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
+{
+ LayoutUnit snappedResult = LayoutUnit::fromFloatCeil(result);
+ preferredWidth = max(snappedResult, preferredWidth);
+}
+
+// When converting between floating point and LayoutUnits we risk losing precision
+// with each conversion. When this occurs while accumulating our preferred widths,
+// we can wind up with a line width that's larger than our maxPreferredWidth due to
+// pure float accumulation.
+static inline LayoutUnit adjustFloatForSubPixelLayout(float value)
+{
+ return LayoutUnit::fromFloatCeil(value);
+}
+
+// FIXME: This function should be broken into something less monolithic.
+// FIXME: The main loop here is very similar to LineBreaker::nextSegmentBreak. They can probably reuse code.
+void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
+{
+ float inlineMax = 0;
+ float inlineMin = 0;
+
+ RenderStyle* styleToUse = style();
+ RenderBlock* containingBlock = this->containingBlock();
+ LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
+
+ // If we are at the start of a line, we want to ignore all white-space.
+ // Also strip spaces if we previously had text that ended in a trailing space.
+ bool stripFrontSpaces = true;
+ RenderObject* trailingSpaceChild = 0;
+
+ // Firefox and Opera will allow a table cell to grow to fit an image inside it under
+ // very specific cirucumstances (in order to match common WinIE renderings).
+ // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
+ bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !styleToUse->logicalWidth().isIntrinsicOrAuto();
+
+ bool autoWrap, oldAutoWrap;
+ autoWrap = oldAutoWrap = styleToUse->autoWrap();
+
+ InlineMinMaxIterator childIterator(this);
+
+ // Only gets added to the max preffered width once.
+ bool addedTextIndent = false;
+ // Signals the text indent was more negative than the min preferred width
+ bool hasRemainingNegativeTextIndent = false;
+
+ LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw);
+ RenderObject* prevFloat = 0;
+ bool isPrevChildInlineFlow = false;
+ bool shouldBreakLineAfterText = false;
+ while (RenderObject* child = childIterator.next()) {
+ autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
+ child->style()->autoWrap();
+
+ if (!child->isBR()) {
+ // Step One: determine whether or not we need to go ahead and
+ // terminate our current line. Each discrete chunk can become
+ // the new min-width, if it is the widest chunk seen so far, and
+ // it can also become the max-width.
+
+ // Children fall into three categories:
+ // (1) An inline flow object. These objects always have a min/max of 0,
+ // and are included in the iteration solely so that their margins can
+ // be added in.
+ //
+ // (2) An inline non-text non-flow object, e.g., an inline replaced element.
+ // These objects can always be on a line by themselves, so in this situation
+ // we need to go ahead and break the current line, and then add in our own
+ // margins and min/max width on its own line, and then terminate the line.
+ //
+ // (3) A text object. Text runs can have breakable characters at the start,
+ // the middle or the end. They may also lose whitespace off the front if
+ // we're already ignoring whitespace. In order to compute accurate min-width
+ // information, we need three pieces of information.
+ // (a) the min-width of the first non-breakable run. Should be 0 if the text string
+ // starts with whitespace.
+ // (b) the min-width of the last non-breakable run. Should be 0 if the text string
+ // ends with whitespace.
+ // (c) the min/max width of the string (trimmed for whitespace).
+ //
+ // If the text string starts with whitespace, then we need to go ahead and
+ // terminate our current line (unless we're already in a whitespace stripping
+ // mode.
+ //
+ // If the text string has a breakable character in the middle, but didn't start
+ // with whitespace, then we add the width of the first non-breakable run and
+ // then end the current line. We then need to use the intermediate min/max width
+ // values (if any of them are larger than our current min/max). We then look at
+ // the width of the last non-breakable run and use that to start a new line
+ // (unless we end in whitespace).
+ RenderStyle* childStyle = child->style();
+ float childMin = 0;
+ float childMax = 0;
+
+ if (!child->isText()) {
+ // Case (1) and (2). Inline replaced and inline flow elements.
+ if (child->isRenderInline()) {
+ // Add in padding/border/margin from the appropriate side of
+ // the element.
+ float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline).toFloat();
+ childMin += bpm;
+ childMax += bpm;
+
+ inlineMin += childMin;
+ inlineMax += childMax;
+
+ child->clearPreferredLogicalWidthsDirty();
+ } else {
+ // Inline replaced elts add in their margins to their min/max values.
+ LayoutUnit margins = 0;
+ Length startMargin = childStyle->marginStart();
+ Length endMargin = childStyle->marginEnd();
+ if (startMargin.isFixed())
+ margins += adjustFloatForSubPixelLayout(startMargin.value());
+ if (endMargin.isFixed())
+ margins += adjustFloatForSubPixelLayout(endMargin.value());
+ childMin += margins.ceilToFloat();
+ childMax += margins.ceilToFloat();
+ }
+ }
+
+ if (!child->isRenderInline() && !child->isText()) {
+ // Case (2). Inline replaced elements and floats.
+ // Go ahead and terminate the current line as far as
+ // minwidth is concerned.
+ LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
+ if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
+ RenderBox* childBox = toRenderBox(child);
+ LogicalExtentComputedValues computedValues;
+ childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
+ childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
+ } else {
+ childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
+ childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
+ }
+ childMin += childMinPreferredLogicalWidth.ceilToFloat();
+ childMax += childMaxPreferredLogicalWidth.ceilToFloat();
+
+ bool clearPreviousFloat;
+ if (child->isFloating()) {
+ clearPreviousFloat = (prevFloat
+ && ((prevFloat->style()->floating() == LeftFloat && (childStyle->clear() & CLEFT))
+ || (prevFloat->style()->floating() == RightFloat && (childStyle->clear() & CRIGHT))));
+ prevFloat = child;
+ } else {
+ clearPreviousFloat = false;
+ }
+
+ bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
+ if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ inlineMin = 0;
+ }
+
+ // If we're supposed to clear the previous float, then terminate maxwidth as well.
+ if (clearPreviousFloat) {
+ updatePreferredWidth(maxLogicalWidth, inlineMax);
+ inlineMax = 0;
+ }
+
+ // Add in text-indent. This is added in only once.
+ if (!addedTextIndent && !child->isFloating()) {
+ float ceiledTextIndent = textIndent.ceilToFloat();
+ childMin += ceiledTextIndent;
+ childMax += ceiledTextIndent;
+
+ if (childMin < 0)
+ textIndent = adjustFloatForSubPixelLayout(childMin);
+ else
+ addedTextIndent = true;
+ }
+
+ // Add our width to the max.
+ inlineMax += max<float>(0, childMax);
+
+ if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
+ if (child->isFloating())
+ updatePreferredWidth(minLogicalWidth, childMin);
+ else
+ inlineMin += childMin;
+ } else {
+ // Now check our line.
+ updatePreferredWidth(minLogicalWidth, childMin);
+
+ // Now start a new line.
+ inlineMin = 0;
+ }
+
+ if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ inlineMin = 0;
+ }
+
+ // We are no longer stripping whitespace at the start of
+ // a line.
+ if (!child->isFloating()) {
+ stripFrontSpaces = false;
+ trailingSpaceChild = 0;
+ }
+ } else if (child->isText()) {
+ // Case (3). Text.
+ RenderText* t = toRenderText(child);
+
+ if (t->isWordBreak()) {
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ inlineMin = 0;
+ continue;
+ }
+
+ if (t->style()->hasTextCombine() && t->isCombineText())
+ toRenderCombineText(t)->combineText();
+
+ // Determine if we have a breakable character. Pass in
+ // whether or not we should ignore any spaces at the front
+ // of the string. If those are going to be stripped out,
+ // then they shouldn't be considered in the breakable char
+ // check.
+ bool hasBreakableChar, hasBreak;
+ float firstLineMinWidth, lastLineMinWidth;
+ bool hasBreakableStart, hasBreakableEnd;
+ float firstLineMaxWidth, lastLineMaxWidth;
+ t->trimmedPrefWidths(inlineMax,
+ firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasBreakableEnd,
+ hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWidth,
+ childMin, childMax, stripFrontSpaces, styleToUse->direction());
+
+ // This text object will not be rendered, but it may still provide a breaking opportunity.
+ if (!hasBreak && !childMax) {
+ if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ inlineMin = 0;
+ }
+ continue;
+ }
+
+ if (stripFrontSpaces)
+ trailingSpaceChild = child;
+ else
+ trailingSpaceChild = 0;
+
+ // Add in text-indent. This is added in only once.
+ float ti = 0;
+ if (!addedTextIndent || hasRemainingNegativeTextIndent) {
+ ti = textIndent.ceilToFloat();
+ childMin += ti;
+ firstLineMinWidth += ti;
+
+ // It the text indent negative and larger than the child minimum, we re-use the remainder
+ // in future minimum calculations, but using the negative value again on the maximum
+ // will lead to under-counting the max pref width.
+ if (!addedTextIndent) {
+ childMax += ti;
+ firstLineMaxWidth += ti;
+ addedTextIndent = true;
+ }
+
+ if (childMin < 0) {
+ textIndent = childMin;
+ hasRemainingNegativeTextIndent = true;
+ }
+ }
+
+ // If we have no breakable characters at all,
+ // then this is the easy case. We add ourselves to the current
+ // min and max and continue.
+ if (!hasBreakableChar) {
+ inlineMin += childMin;
+ } else {
+ if (hasBreakableStart) {
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ } else {
+ inlineMin += firstLineMinWidth;
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ childMin -= ti;
+ }
+
+ inlineMin = childMin;
+
+ if (hasBreakableEnd) {
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ inlineMin = 0;
+ shouldBreakLineAfterText = false;
+ } else {
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ inlineMin = lastLineMinWidth;
+ shouldBreakLineAfterText = true;
+ }
+ }
+
+ if (hasBreak) {
+ inlineMax += firstLineMaxWidth;
+ updatePreferredWidth(maxLogicalWidth, inlineMax);
+ updatePreferredWidth(maxLogicalWidth, childMax);
+ inlineMax = lastLineMaxWidth;
+ addedTextIndent = true;
+ } else {
+ inlineMax += max<float>(0, childMax);
+ }
+ }
+
+ // Ignore spaces after a list marker.
+ if (child->isListMarker())
+ stripFrontSpaces = true;
+ } else {
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ updatePreferredWidth(maxLogicalWidth, inlineMax);
+ inlineMin = inlineMax = 0;
+ stripFrontSpaces = true;
+ trailingSpaceChild = 0;
+ addedTextIndent = true;
+ }
+
+ if (!child->isText() && child->isRenderInline())
+ isPrevChildInlineFlow = true;
+ else
+ isPrevChildInlineFlow = false;
+
+ oldAutoWrap = autoWrap;
+ }
+
+ if (styleToUse->collapseWhiteSpace())
+ stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
+
+ updatePreferredWidth(minLogicalWidth, inlineMin);
+ updatePreferredWidth(maxLogicalWidth, inlineMax);
+}
+
+void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, LayoutUnit afterEdge)
+{
RenderFlowThread* flowThread = flowThreadContainingBlock();
bool clearLinesForPagination = firstLineBox() && flowThread && !flowThread->hasRegions();
@@ -1752,25 +1687,17 @@ void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& re
// the replaced elements later. In partial layout mode, line boxes are not
// deleted and only dirtied. In that case, we can layout the replaced
// elements at the same time.
- bool hasInlineChild = false;
Vector<RenderBox*> replacedChildren;
for (InlineWalker walker(this); !walker.atEnd(); walker.advance()) {
RenderObject* o = walker.current();
- LayoutRectRecorder recorder(*o, !o->isText());
-
- if (!hasInlineChild && o->isInline())
- hasInlineChild = true;
+ if (!layoutState.hasInlineChild() && o->isInline())
+ layoutState.setHasInlineChild(true);
if (o->isReplaced() || o->isFloating() || o->isOutOfFlowPositioned()) {
RenderBox* box = toRenderBox(o);
- if (relayoutChildren || box->hasRelativeDimensions())
- o->setChildNeedsLayout(MarkOnlyThis);
-
- // If relayoutChildren is set and the child has percentage padding or an embedded content box, we also need to invalidate the childs pref widths.
- if (relayoutChildren && box->needsPreferredWidthsRecalculation())
- o->setPreferredLogicalWidthsDirty(MarkOnlyThis);
+ updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, box);
if (o->isOutOfFlowPositioned())
o->containingBlock()->insertPositionedObject(box);
@@ -1796,7 +1723,7 @@ void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& re
for (size_t i = 0; i < replacedChildren.size(); i++)
replacedChildren[i]->layoutIfNeeded();
- layoutRunsAndFloats(layoutState, hasInlineChild);
+ layoutRunsAndFloats(layoutState);
}
// Expand the last line to accommodate Ruby and emphasis marks.
@@ -1810,7 +1737,7 @@ void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& re
}
// Now add in the bottom border/padding.
- setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + borderAfter() + paddingAfter() + scrollbarLogicalHeight());
+ setLogicalHeight(logicalHeight() + lastLineAnnotationsAdjustment + afterEdge);
if (!firstLineBox() && hasLineIfEmpty())
setLogicalHeight(logicalHeight() + lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes));
@@ -1865,10 +1792,6 @@ RootInlineBox* RenderBlockFlow::determineStartPosition(LineLayoutState& layoutSt
size_t floatIndex = 0;
for (curr = firstRootBox(); curr && !curr->isDirty(); curr = curr->nextRootBox()) {
if (paginated) {
- if (lineWidthForPaginatedLineChanged(curr, 0, layoutState.flowThread())) {
- curr->markDirty();
- break;
- }
paginationDelta -= curr->paginationStrut();
adjustLinePositionForPagination(curr, paginationDelta, layoutState.flowThread());
if (paginationDelta) {
@@ -1879,10 +1802,8 @@ RootInlineBox* RenderBlockFlow::determineStartPosition(LineLayoutState& layoutSt
}
layoutState.updateRepaintRangeFromBox(curr, paginationDelta);
- curr->adjustBlockDirectionPosition(paginationDelta);
+ curr->adjustBlockDirectionPosition(paginationDelta.toFloat());
}
- if (layoutState.flowThread())
- updateRegionForLine(curr);
}
// If a new float has been inserted before this line or before its last known float, just do a full layout.
@@ -1900,6 +1821,13 @@ RootInlineBox* RenderBlockFlow::determineStartPosition(LineLayoutState& layoutSt
}
if (layoutState.isFullLayout()) {
+ // If we encountered a new float and have inline children, mark ourself to force us to issue paint invalidations.
+ if (layoutState.hasInlineChild() && !selfNeedsLayout()) {
+ setNeedsLayoutAndFullPaintInvalidation(MarkOnlyThis);
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ setShouldDoFullPaintInvalidationAfterLayout(true);
+ }
+
// FIXME: This should just call deleteLineBoxTree, but that causes
// crashes for fast/repaint tests.
curr = firstRootBox();
@@ -2028,8 +1956,6 @@ bool RenderBlockFlow::checkPaginationAndFloatsAtEndLine(LineLayoutState& layoutS
adjustLinePositionForPagination(lineBox, lineDelta, layoutState.flowThread());
lineBox->setPaginationStrut(oldPaginationStrut);
}
- if (lineWidthForPaginatedLineChanged(lineBox, lineDelta, layoutState.flowThread()))
- return false;
}
}
@@ -2048,7 +1974,7 @@ bool RenderBlockFlow::checkPaginationAndFloatsAtEndLine(LineLayoutState& layoutS
const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
FloatingObjectSetIterator end = floatingObjectSet.end();
for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (logicalBottomForFloat(floatingObject) >= logicalTop && logicalBottomForFloat(floatingObject) < logicalBottom)
return false;
}
@@ -2070,7 +1996,7 @@ bool RenderBlockFlow::matchedEndLine(LineLayoutState& layoutState, const InlineB
RootInlineBox* originalEndLine = layoutState.endLine();
RootInlineBox* line = originalEndLine;
for (int i = 0; i < numLines && line; i++, line = line->nextRootBox()) {
- if (line->lineBreakObj() == resolver.position().object() && line->lineBreakPos() == resolver.position().m_pos) {
+ if (line->lineBreakObj() == resolver.position().object() && line->lineBreakPos() == resolver.position().offset()) {
// We have a match.
if (line->lineBreakBidiStatus() != resolver.status())
return false; // ...but the bidi state doesn't match.
@@ -2105,139 +2031,6 @@ bool RenderBlockFlow::generatesLineBoxesForInlineChild(RenderObject* inlineObj)
return !it.atEnd();
}
-void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo,
- FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
-{
- while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
- RenderObject* object = resolver.position().object();
- if (object->isOutOfFlowPositioned()) {
- setStaticPositions(m_block, toRenderBox(object));
- if (object->style()->isOriginalDisplayInlineType()) {
- resolver.runs().addRun(createRun(0, 1, object, resolver));
- lineInfo.incrementRunsFromLeadingWhitespace();
- }
- } else if (object->isFloating())
- m_block->positionNewFloatOnLine(m_block->insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, lineInfo, width);
- else if (object->isText() && object->style()->hasTextCombine() && object->isCombineText() && !toRenderCombineText(object)->isCombined()) {
- toRenderCombineText(object)->combineText();
- if (toRenderCombineText(object)->isCombined())
- continue;
- }
- resolver.position().increment(&resolver);
- }
- resolver.commitExplicitEmbedding();
-}
-
-void LineBreaker::reset()
-{
- m_positionedObjects.clear();
- m_hyphenated = false;
- m_clear = CNONE;
-}
-
-InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements)
-{
- ShapeInsideInfo* shapeInsideInfo = m_block->layoutShapeInsideInfo();
-
- if (!shapeInsideInfo || !shapeInsideInfo->lineOverlapsShapeBounds())
- return nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
-
- InlineIterator end = resolver.position();
- InlineIterator oldEnd = end;
-
- if (!shapeInsideInfo->hasSegments()) {
- end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
- resolver.setPositionIgnoringNestedIsolates(oldEnd);
- return oldEnd;
- }
-
- const SegmentList& segments = shapeInsideInfo->segments();
- SegmentRangeList& segmentRanges = shapeInsideInfo->segmentRanges();
-
- for (unsigned i = 0; i < segments.size() && !end.atEnd(); i++) {
- const InlineIterator segmentStart = resolver.position();
- end = nextSegmentBreak(resolver, lineInfo, renderTextInfo, lastFloatFromPreviousLine, consecutiveHyphenatedLines, wordMeasurements);
-
- ASSERT(segmentRanges.size() == i);
- if (resolver.position().atEnd()) {
- segmentRanges.append(LineSegmentRange(segmentStart, end));
- break;
- }
- if (resolver.position() == end) {
- // Nothing fit this segment
- end = segmentStart;
- segmentRanges.append(LineSegmentRange(segmentStart, segmentStart));
- resolver.setPositionIgnoringNestedIsolates(segmentStart);
- } else {
- // Note that resolver.position is already skipping some of the white space at the beginning of the line,
- // so that's why segmentStart might be different than resolver.position().
- LineSegmentRange range(resolver.position(), end);
- segmentRanges.append(range);
- resolver.setPosition(end, numberOfIsolateAncestors(end));
-
- if (lineInfo.previousLineBrokeCleanly()) {
- // If we hit a new line break, just stop adding anything to this line.
- break;
- }
- }
- }
- resolver.setPositionIgnoringNestedIsolates(oldEnd);
- return end;
-}
-
-InlineIterator LineBreaker::nextSegmentBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements)
-{
- reset();
-
- ASSERT(resolver.position().root() == m_block);
-
- bool appliedStartWidth = resolver.position().m_pos > 0;
-
- LineWidth width(*m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isFirstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style()));
-
- skipLeadingWhitespace(resolver, lineInfo, lastFloatFromPreviousLine, width);
-
- if (resolver.position().atEnd())
- return resolver.position();
-
- BreakingContext context(resolver, lineInfo, width, renderTextInfo, lastFloatFromPreviousLine, appliedStartWidth, m_block);
-
- while (context.currentObject()) {
- context.initializeForCurrentObject();
- if (context.currentObject()->isBR()) {
- context.handleBR(m_clear);
- } else if (context.currentObject()->isOutOfFlowPositioned()) {
- context.handleOutOfFlowPositioned(m_positionedObjects);
- } else if (context.currentObject()->isFloating()) {
- context.handleFloat();
- } else if (context.currentObject()->isRenderInline()) {
- context.handleEmptyInline();
- } else if (context.currentObject()->isReplaced()) {
- context.handleReplaced();
- } else if (context.currentObject()->isText()) {
- if (context.handleText(wordMeasurements, m_hyphenated)) {
- // We've hit a hard text line break. Our line break iterator is updated, so go ahead and early return.
- return context.lineBreak();
- }
- } else {
- ASSERT_NOT_REACHED();
- }
-
- if (context.atEnd())
- return context.handleEndOfLine();
-
- context.commitAndUpdateLineBreakIfNeeded();
-
- if (context.atEnd())
- return context.handleEndOfLine();
-
- context.increment();
- }
-
- context.clearLineBreakIfFitsOnLine();
-
- return context.handleEndOfLine();
-}
void RenderBlockFlow::addOverflowFromInlineChildren()
{
@@ -2262,7 +2055,7 @@ void RenderBlockFlow::deleteEllipsisLineBoxes()
curr->clearTruncation();
// Shift the line back where it belongs if we cannot accomodate an ellipsis.
- float logicalLeft = pixelSnappedLogicalLeftOffsetForLine(curr->lineTop(), firstLine);
+ float logicalLeft = logicalLeftOffsetForLine(curr->lineTop(), firstLine).toFloat();
float availableLogicalWidth = logicalRightOffsetForLine(curr->lineTop(), false) - logicalLeft;
float totalLogicalWidth = curr->logicalWidth();
updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
@@ -2283,8 +2076,10 @@ void RenderBlockFlow::checkLinesForTextOverflow()
const Font& font = style()->font();
DEFINE_STATIC_LOCAL(AtomicString, ellipsisStr, (&horizontalEllipsis, 1));
const Font& firstLineFont = firstLineStyle()->font();
- int firstLineEllipsisWidth = firstLineFont.width(constructTextRun(this, firstLineFont, &horizontalEllipsis, 1, firstLineStyle()));
- int ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(constructTextRun(this, font, &horizontalEllipsis, 1, style()));
+ // FIXME: We should probably not hard-code the direction here. https://crbug.com/333004
+ TextDirection ellipsisDirection = LTR;
+ float firstLineEllipsisWidth = firstLineFont.width(constructTextRun(this, firstLineFont, &horizontalEllipsis, 1, firstLineStyle(), ellipsisDirection));
+ float ellipsisWidth = (font == firstLineFont) ? firstLineEllipsisWidth : font.width(constructTextRun(this, font, &horizontalEllipsis, 1, style(), ellipsisDirection));
// For LTR text truncation, we want to get the right edge of our padding box, and then we want to see
// if the right edge of a line box exceeds that. For RTL, we use the left edge of the padding box and
@@ -2294,12 +2089,10 @@ void RenderBlockFlow::checkLinesForTextOverflow()
ETextAlign textAlign = style()->textAlign();
bool firstLine = true;
for (RootInlineBox* curr = firstRootBox(); curr; curr = curr->nextRootBox()) {
- // FIXME: Use pixelSnappedLogicalRightOffsetForLine instead of snapping it ourselves once the column workaround in said method has been fixed.
- // https://bugs.webkit.org/show_bug.cgi?id=105461
float currLogicalLeft = curr->logicalLeft();
- int blockRightEdge = snapSizeToPixel(logicalRightOffsetForLine(curr->lineTop(), firstLine), currLogicalLeft);
- int blockLeftEdge = pixelSnappedLogicalLeftOffsetForLine(curr->lineTop(), firstLine);
- int lineBoxEdge = ltr ? snapSizeToPixel(currLogicalLeft + curr->logicalWidth(), currLogicalLeft) : snapSizeToPixel(currLogicalLeft, 0);
+ LayoutUnit blockRightEdge = logicalRightOffsetForLine(curr->lineTop(), firstLine);
+ LayoutUnit blockLeftEdge = logicalLeftOffsetForLine(curr->lineTop(), firstLine);
+ LayoutUnit lineBoxEdge = ltr ? currLogicalLeft + curr->logicalWidth() : currLogicalLeft;
if ((ltr && lineBoxEdge > blockRightEdge) || (!ltr && lineBoxEdge < blockLeftEdge)) {
// This line spills out of our box in the appropriate direction. Now we need to see if the line
// can be truncated. In order for truncation to be possible, the line must have sufficient space to
@@ -2309,15 +2102,15 @@ void RenderBlockFlow::checkLinesForTextOverflow()
LayoutUnit width = firstLine ? firstLineEllipsisWidth : ellipsisWidth;
LayoutUnit blockEdge = ltr ? blockRightEdge : blockLeftEdge;
if (curr->lineCanAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width)) {
- float totalLogicalWidth = curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge, blockRightEdge, width);
+ float totalLogicalWidth = curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge.toFloat(), blockRightEdge.toFloat(), width.toFloat());
float logicalLeft = 0; // We are only intersted in the delta from the base position.
- float truncatedWidth = pixelSnappedLogicalRightOffsetForLine(curr->lineTop(), firstLine);
- updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, truncatedWidth, 0);
+ float availableLogicalWidth = (blockRightEdge - blockLeftEdge).toFloat();
+ updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
if (ltr)
curr->adjustLogicalPosition(logicalLeft, 0);
else
- curr->adjustLogicalPosition(-(truncatedWidth - (logicalLeft + totalLogicalWidth)), 0);
+ curr->adjustLogicalPosition(logicalLeft - (availableLogicalWidth - totalLogicalWidth), 0);
}
}
firstLine = false;
@@ -2351,7 +2144,7 @@ bool RenderBlockFlow::positionNewFloatOnLine(FloatingObject* newFloat, FloatingO
FloatingObjectSetIterator begin = floatingObjectSet.begin();
while (it != begin) {
--it;
- FloatingObject* floatingObject = *it;
+ FloatingObject* floatingObject = it->get();
if (floatingObject == lastFloatFromPreviousLine)
break;
if (logicalTopForFloat(floatingObject) == logicalHeight() + lineInfo.floatPaginationStrut()) {
@@ -2386,7 +2179,7 @@ LayoutUnit RenderBlockFlow::startAlignedOffsetForLine(LayoutUnit position, bool
// updateLogicalWidthForAlignment() handles the direction of the block so no need to consider it here
float totalLogicalWidth = 0;
- float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false);
+ float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat();
float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), false) - logicalLeft;
updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
@@ -2395,27 +2188,4 @@ LayoutUnit RenderBlockFlow::startAlignedOffsetForLine(LayoutUnit position, bool
return logicalLeft;
}
-void RenderBlockFlow::layoutLineGridBox()
-{
- if (style()->lineGrid() == RenderStyle::initialLineGrid()) {
- setLineGridBox(0);
- return;
- }
-
- setLineGridBox(0);
-
- RootInlineBox* lineGridBox = new RootInlineBox(this);
- lineGridBox->setHasTextChildren(); // Needed to make the line ascent/descent actually be honored in quirks mode.
- lineGridBox->setConstructed();
- GlyphOverflowAndFallbackFontsMap textBoxDataMap;
- VerticalPositionCache verticalPositionCache;
- lineGridBox->alignBoxesInBlockDirection(logicalHeight(), textBoxDataMap, verticalPositionCache);
-
- setLineGridBox(lineGridBox);
-
- // FIXME: If any of the characteristics of the box change compared to the old one, then we need to do a deep dirtying
- // (similar to what happens when the page height changes). Ideally, though, we only do this if someone is actually snapping
- // to this grid.
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderBox.cpp
index 9c960358ed5..93d89283c7b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBox.cpp
@@ -26,40 +26,40 @@
#include "config.h"
#include "core/rendering/RenderBox.h"
-#include <math.h>
-#include <algorithm>
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/editing/htmlediting.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/PinchViewport.h"
+#include "core/frame/Settings.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/html/HTMLHtmlElement.h"
-#include "core/html/HTMLTextAreaElement.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/AutoscrollController.h"
#include "core/page/EventHandler.h"
#include "core/page/Page.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
-#include "core/rendering/RenderBoxRegionInfo.h"
+#include "core/rendering/RenderDeprecatedFlexibleBox.h"
#include "core/rendering/RenderFlexibleBox.h"
-#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderGrid.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
+#include "core/rendering/RenderListBox.h"
#include "core/rendering/RenderListMarker.h"
-#include "core/rendering/RenderRegion.h"
#include "core/rendering/RenderTableCell.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "platform/LengthFunctions.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/TransformState.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
+#include <algorithm>
+#include <math.h>
using namespace std;
@@ -69,10 +69,9 @@ using namespace HTMLNames;
// Used by flexible boxes when flexing this element and by table cells.
typedef WTF::HashMap<const RenderBox*, LayoutUnit> OverrideSizeMap;
-static OverrideSizeMap* gOverrideHeightMap = 0;
-static OverrideSizeMap* gOverrideWidthMap = 0;
// Used by grid elements to properly size their grid items.
+// FIXME: Move these into RenderBoxRareData.
static OverrideSizeMap* gOverrideContainingBlockLogicalHeightMap = 0;
static OverrideSizeMap* gOverrideContainingBlockLogicalWidthMap = 0;
@@ -95,64 +94,13 @@ static bool skipBodyBackground(const RenderBox* bodyElementRenderer)
RenderBox::RenderBox(ContainerNode* node)
: RenderBoxModelObject(node)
+ , m_intrinsicContentLogicalHeight(-1)
, m_minPreferredLogicalWidth(-1)
, m_maxPreferredLogicalWidth(-1)
- , m_intrinsicContentLogicalHeight(-1)
- , m_inlineBoxWrapper(0)
{
setIsBox();
}
-RenderBox::~RenderBox()
-{
-}
-
-LayoutRect RenderBox::borderBoxRectInRegion(RenderRegion* region, RenderBoxRegionInfoFlags cacheFlag) const
-{
- if (!region)
- return borderBoxRect();
-
- // Compute the logical width and placement in this region.
- RenderBoxRegionInfo* boxInfo = renderBoxRegionInfo(region, cacheFlag);
- if (!boxInfo)
- return borderBoxRect();
-
- // We have cached insets.
- LayoutUnit logicalWidth = boxInfo->logicalWidth();
- LayoutUnit logicalLeft = boxInfo->logicalLeft();
-
- // Now apply the parent inset since it is cumulative whenever anything in the containing block chain shifts.
- // FIXME: Doesn't work right with perpendicular writing modes.
- const RenderBlock* currentBox = containingBlock();
- RenderBoxRegionInfo* currentBoxInfo = currentBox->renderBoxRegionInfo(region);
- while (currentBoxInfo && currentBoxInfo->isShifted()) {
- if (currentBox->style()->direction() == LTR)
- logicalLeft += currentBoxInfo->logicalLeft();
- else
- logicalLeft -= (currentBox->logicalWidth() - currentBoxInfo->logicalWidth()) - currentBoxInfo->logicalLeft();
- currentBox = currentBox->containingBlock();
- region = currentBox->clampToStartAndEndRegions(region);
- currentBoxInfo = currentBox->renderBoxRegionInfo(region);
- }
-
- if (cacheFlag == DoNotCacheRenderBoxRegionInfo)
- delete boxInfo;
-
- if (isHorizontalWritingMode())
- return LayoutRect(logicalLeft, 0, logicalWidth, height());
- return LayoutRect(0, logicalLeft, width(), logicalWidth);
-}
-
-void RenderBox::clearRenderBoxRegionInfo()
-{
- if (isRenderFlowThread())
- return;
-
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (flowThread)
- flowThread->removeRenderBoxRegionInfo(this);
-}
-
void RenderBox::willBeDestroyed()
{
clearOverrideSize();
@@ -160,7 +108,7 @@ void RenderBox::willBeDestroyed()
RenderBlock::removePercentHeightDescendantIfNeeded(this);
- ShapeOutsideInfo::removeInfo(this);
+ ShapeOutsideInfo::removeInfo(*this);
RenderBoxModelObject::willBeDestroyed();
}
@@ -192,33 +140,36 @@ void RenderBox::removeFloatingOrPositionedChildFromBlockLists()
RenderBlock::removePositionedObject(this);
}
-void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderBox::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
RenderStyle* oldStyle = style();
if (oldStyle) {
// The background of the root element or the body element could propagate up to
// the canvas. Just dirty the entire canvas when our style changes substantially.
- if (diff >= StyleDifferenceRepaint && node() &&
- (isHTMLHtmlElement(node()) || node()->hasTagName(bodyTag))) {
- view()->repaint();
+ if ((diff.needsRepaint() || diff.needsLayout()) && node()
+ && (isHTMLHtmlElement(*node()) || isHTMLBodyElement(*node()))) {
+ view()->paintInvalidationForWholeRenderer();
- if (oldStyle->hasEntirelyFixedBackground() != newStyle->hasEntirelyFixedBackground())
- view()->compositor()->rootFixedBackgroundsChanged();
+ if (oldStyle->hasEntirelyFixedBackground() != newStyle.hasEntirelyFixedBackground())
+ view()->compositor()->setNeedsUpdateFixedBackground();
}
// When a layout hint happens and an object's position style changes, we have to do a layout
// to dirty the render tree using the old position value now.
- if (diff == StyleDifferenceLayout && parent() && oldStyle->position() != newStyle->position()) {
+ if (diff.needsFullLayout() && parent() && oldStyle->position() != newStyle.position()) {
markContainingBlocksForLayout();
if (oldStyle->position() == StaticPosition)
- repaint();
- else if (newStyle->hasOutOfFlowPosition())
+ paintInvalidationForWholeRenderer();
+ else if (newStyle.hasOutOfFlowPosition())
parent()->setChildNeedsLayout();
- if (isFloating() && !isOutOfFlowPositioned() && newStyle->hasOutOfFlowPosition())
+ if (isFloating() && !isOutOfFlowPositioned() && newStyle.hasOutOfFlowPosition())
removeFloatingOrPositionedChildFromBlockLists();
}
- } else if (newStyle && isBody())
- view()->repaint();
+ // FIXME: This branch runs when !oldStyle, which means that layout was never called
+ // so what's the point in invalidating the whole view that we never painted?
+ } else if (isBody()) {
+ view()->paintInvalidationForWholeRenderer();
+ }
RenderBoxModelObject::styleWillChange(diff, newStyle);
}
@@ -244,7 +195,7 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle
parent()->setChildNeedsLayout();
}
- if (RenderBlock::hasPercentHeightContainerMap() && firstChild()
+ if (RenderBlock::hasPercentHeightContainerMap() && slowFirstChild()
&& oldHorizontalWritingMode != isHorizontalWritingMode())
RenderBlock::clearPercentHeightDescendantsFrom(this);
@@ -262,7 +213,7 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle
}
// Our opaqueness might have changed without triggering layout.
- if (diff == StyleDifferenceRepaint || diff == StyleDifferenceRepaintIfTextOrColorChange || diff == StyleDifferenceRepaintLayer) {
+ if (diff.needsRepaint()) {
RenderObject* parentToInvalidate = parent();
for (unsigned i = 0; i < backgroundObscurationTestMaxDepth && parentToInvalidate; ++i) {
parentToInvalidate->invalidateBackgroundObscurationStatus();
@@ -270,7 +221,7 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle
}
}
- if (isRoot() || isBody())
+ if (isDocumentElement() || isBody())
document().view()->recalculateScrollbarOverlayStyle();
updateShapeOutsideInfoAfterStyleChange(*style(), oldStyle);
@@ -293,9 +244,9 @@ void RenderBox::updateShapeOutsideInfoAfterStyleChange(const RenderStyle& style,
return;
if (!shapeOutside)
- ShapeOutsideInfo::removeInfo(this);
+ ShapeOutsideInfo::removeInfo(*this);
else
- ShapeOutsideInfo::ensureInfo(this)->dirtyShapeSize();
+ ShapeOutsideInfo::ensureInfo(*this).markShapeAsDirty();
if (shapeOutside || shapeOutside != oldShapeOutside)
markShapeOutsideDependentsForLayout();
@@ -324,7 +275,7 @@ void RenderBox::updateFromStyle()
RenderBoxModelObject::updateFromStyle();
RenderStyle* styleToUse = style();
- bool isRootObject = isRoot();
+ bool isRootObject = isDocumentElement();
bool isViewObject = isRenderView();
// The root and the RenderView always paint their backgrounds/borders.
@@ -334,26 +285,26 @@ void RenderBox::updateFromStyle()
setFloating(!isOutOfFlowPositioned() && styleToUse->isFloating());
bool boxHasOverflowClip = false;
- // We also handle <body> and <html>, whose overflow applies to the viewport.
- // It's sufficient to just check one direction, since it's illegal to have visible on only one overflow value.
- if (styleToUse->overflowX() != OVISIBLE && !isRootObject && isRenderBlock()) {
- // Overflow on the body can propagate to the viewport under the following conditions.
- // (1) The root element is <html>.
- // (2) We are the primary <body> (can be checked by looking at document.body).
- // (3) The root element has visible overflow.
- if (isBody() && isHTMLHtmlElement(document().documentElement())
- && document().body() == node()
- && document().documentElement()->renderer()->style()->overflowX() == OVISIBLE) {
- boxHasOverflowClip = false;
- } else {
+ if (!styleToUse->isOverflowVisible() && isRenderBlock() && !isViewObject) {
+ // If overflow has been propagated to the viewport, it has no effect here.
+ if (node() != document().viewportDefiningElement()) {
boxHasOverflowClip = true;
if (!hasOverflowClip()) {
// If we are getting an overflow clip, preemptively erase any overflowing content.
// FIXME: This should probably consult RenderOverflow.
- repaint();
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ paintInvalidationForWholeRenderer();
}
}
}
+
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && (boxHasOverflowClip != hasOverflowClip())) {
+ // FIXME: This shouldn't be required if we tracked the visual overflow
+ // generated by positioned children or self painting layers. crbug.com/345403
+ for (RenderObject* child = slowFirstChild(); child; child = child->nextSibling())
+ child->setShouldDoFullPaintInvalidationIfSelfPaintingLayer(true);
+ }
+
setHasOverflowClip(boxHasOverflowClip);
setHasTransform(styleToUse->hasTransformRelatedProperty());
@@ -364,21 +315,18 @@ void RenderBox::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
-
- RenderObject* child = firstChild();
+ RenderObject* child = slowFirstChild();
if (!child) {
clearNeedsLayout();
return;
}
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
+ LayoutState state(*this, locationOffset());
while (child) {
child->layoutIfNeeded();
ASSERT(!child->needsLayout());
child = child->nextSibling();
}
- statePusher.pop();
invalidateBackgroundObscurationStatus();
clearNeedsLayout();
}
@@ -415,88 +363,65 @@ int RenderBox::pixelSnappedOffsetHeight() const
return snapSizeToPixel(offsetHeight(), y() + clientTop());
}
-bool RenderBox::canDetermineWidthWithoutLayout() const
-{
- // FIXME: This optimization is incorrect as written.
- // We need to be able to opt-in to this behavior only when
- // it's guarentted correct.
- // Until then disabling this optimization to be safe.
- return false;
-
- // FIXME: There are likely many subclasses of RenderBlockFlow which
- // cannot determine their layout just from style!
- // Perhaps we should create a "PlainRenderBlockFlow"
- // and move this optimization there?
- if (!isRenderBlockFlow()
- // Flexbox items can be expanded beyond their width.
- || isFlexItemIncludingDeprecated()
- // Table Layout controls cell size and can expand beyond width.
- || isTableCell())
- return false;
-
- RenderStyle* style = this->style();
- return style->width().isFixed()
- && style->minWidth().isFixed()
- && (style->maxWidth().isUndefined() || style->maxWidth().isFixed())
- && style->paddingLeft().isFixed()
- && style->paddingRight().isFixed()
- && style->boxSizing() == CONTENT_BOX;
-}
-
-LayoutUnit RenderBox::fixedOffsetWidth() const
-{
- ASSERT(canDetermineWidthWithoutLayout());
-
- RenderStyle* style = this->style();
-
- LayoutUnit width = std::max(LayoutUnit(style->minWidth().value()), LayoutUnit(style->width().value()));
- if (style->maxWidth().isFixed())
- width = std::min(LayoutUnit(style->maxWidth().value()), width);
-
- LayoutUnit borderLeft = style->borderLeft().nonZero() ? style->borderLeft().width() : 0;
- LayoutUnit borderRight = style->borderRight().nonZero() ? style->borderRight().width() : 0;
-
- return width + borderLeft + borderRight + style->paddingLeft().value() + style->paddingRight().value();
-}
-
-int RenderBox::scrollWidth() const
+LayoutUnit RenderBox::scrollWidth() const
{
if (hasOverflowClip())
return layer()->scrollableArea()->scrollWidth();
// For objects with visible overflow, this matches IE.
// FIXME: Need to work right with writing modes.
if (style()->isLeftToRightDirection())
- return snapSizeToPixel(max(clientWidth(), layoutOverflowRect().maxX() - borderLeft()), x() + clientLeft());
+ return max(clientWidth(), layoutOverflowRect().maxX() - borderLeft());
return clientWidth() - min<LayoutUnit>(0, layoutOverflowRect().x() - borderLeft());
}
-int RenderBox::scrollHeight() const
+LayoutUnit RenderBox::scrollHeight() const
{
if (hasOverflowClip())
return layer()->scrollableArea()->scrollHeight();
// For objects with visible overflow, this matches IE.
// FIXME: Need to work right with writing modes.
- return snapSizeToPixel(max(clientHeight(), layoutOverflowRect().maxY() - borderTop()), y() + clientTop());
+ return max(clientHeight(), layoutOverflowRect().maxY() - borderTop());
}
-int RenderBox::scrollLeft() const
+LayoutUnit RenderBox::scrollLeft() const
{
return hasOverflowClip() ? layer()->scrollableArea()->scrollXOffset() : 0;
}
-int RenderBox::scrollTop() const
+LayoutUnit RenderBox::scrollTop() const
{
return hasOverflowClip() ? layer()->scrollableArea()->scrollYOffset() : 0;
}
-void RenderBox::setScrollLeft(int newLeft)
+int RenderBox::pixelSnappedScrollWidth() const
+{
+ return snapSizeToPixel(scrollWidth(), x() + clientLeft());
+}
+
+int RenderBox::pixelSnappedScrollHeight() const
+{
+ if (hasOverflowClip())
+ return layer()->scrollableArea()->scrollHeight();
+ // For objects with visible overflow, this matches IE.
+ // FIXME: Need to work right with writing modes.
+ return snapSizeToPixel(scrollHeight(), y() + clientTop());
+}
+
+void RenderBox::setScrollLeft(LayoutUnit newLeft)
{
+ // This doesn't hit in any tests, but since the equivalent code in setScrollTop
+ // does, presumably this code does as well.
+ DisableCompositingQueryAsserts disabler;
+
if (hasOverflowClip())
layer()->scrollableArea()->scrollToXOffset(newLeft, ScrollOffsetClamped);
}
-void RenderBox::setScrollTop(int newTop)
+void RenderBox::setScrollTop(LayoutUnit newTop)
{
+ // Hits in compositing/overflow/do-not-assert-on-invisible-composited-layers.html
+ DisableCompositingQueryAsserts disabler;
+
if (hasOverflowClip())
layer()->scrollableArea()->scrollToYOffset(newTop, ScrollOffsetClamped);
}
@@ -504,6 +429,10 @@ void RenderBox::setScrollTop(int newTop)
void RenderBox::scrollToOffset(const IntSize& offset)
{
ASSERT(hasOverflowClip());
+
+ // This doesn't hit in any tests, but since the equivalent code in setScrollTop
+ // does, presumably this code does as well.
+ DisableCompositingQueryAsserts disabler;
layer()->scrollableArea()->scrollToOffset(offset, ScrollOffsetClamped);
}
@@ -527,6 +456,9 @@ static inline bool frameElementAndViewPermitScroll(HTMLFrameElementBase* frameEl
void RenderBox::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
{
+ // Presumably the same issue as in setScrollTop. See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
RenderBox* parentBox = 0;
LayoutRect newRect = rect;
@@ -547,7 +479,7 @@ void RenderBox::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignmen
if (ownerElement && ownerElement->renderer()) {
HTMLFrameElementBase* frameElementBase = 0;
- if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))
+ if (isHTMLFrameElement(*ownerElement) || isHTMLIFrameElement(*ownerElement))
frameElementBase = toHTMLFrameElementBase(ownerElement);
if (frameElementAndViewPermitScroll(frameElementBase, frameView)) {
@@ -572,9 +504,15 @@ void RenderBox::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignmen
}
}
} else {
- LayoutRect viewRect = frameView->visibleContentRect();
- LayoutRect r = ScrollAlignment::getRectToExpose(viewRect, rect, alignX, alignY);
- frameView->setScrollPosition(roundedIntPoint(r.location()));
+ if (frame()->settings()->pinchVirtualViewportEnabled()) {
+ PinchViewport& pinchViewport = frame()->page()->frameHost().pinchViewport();
+ LayoutRect r = ScrollAlignment::getRectToExpose(LayoutRect(pinchViewport.visibleRectInDocument()), rect, alignX, alignY);
+ pinchViewport.scrollIntoView(r);
+ } else {
+ LayoutRect viewRect = frameView->visibleContentRect();
+ LayoutRect r = ScrollAlignment::getRectToExpose(viewRect, rect, alignX, alignY);
+ frameView->setScrollPosition(roundedIntPoint(r.location()));
+ }
}
}
}
@@ -593,22 +531,22 @@ void RenderBox::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumul
void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
{
- quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed));
+ quads.append(localToAbsoluteQuad(FloatRect(0, 0, width().toFloat(), height().toFloat()), 0 /* mode */, wasFixed));
}
-void RenderBox::updateLayerTransform()
+void RenderBox::updateLayerTransformAfterLayout()
{
// Transform-origin depends on box size, so we need to update the layer transform after layout.
if (hasLayer())
- layer()->updateTransform();
+ layer()->updateTransformationMatrix();
}
-LayoutUnit RenderBox::constrainLogicalWidthInRegionByMinMax(LayoutUnit logicalWidth, LayoutUnit availableWidth, RenderBlock* cb, RenderRegion* region) const
+LayoutUnit RenderBox::constrainLogicalWidthByMinMax(LayoutUnit logicalWidth, LayoutUnit availableWidth, RenderBlock* cb) const
{
RenderStyle* styleToUse = style();
if (!styleToUse->logicalMaxWidth().isUndefined())
- logicalWidth = min(logicalWidth, computeLogicalWidthInRegionUsing(MaxSize, styleToUse->logicalMaxWidth(), availableWidth, cb, region));
- return max(logicalWidth, computeLogicalWidthInRegionUsing(MinSize, styleToUse->logicalMinWidth(), availableWidth, cb, region));
+ logicalWidth = min(logicalWidth, computeLogicalWidthUsing(MaxSize, styleToUse->logicalMaxWidth(), availableWidth, cb));
+ return max(logicalWidth, computeLogicalWidthUsing(MinSize, styleToUse->logicalMinWidth(), availableWidth, cb));
}
LayoutUnit RenderBox::constrainLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const
@@ -648,28 +586,6 @@ FloatQuad RenderBox::absoluteContentQuad() const
return localToAbsoluteQuad(FloatRect(rect));
}
-LayoutRect RenderBox::outlineBoundsForRepaint(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap) const
-{
- LayoutRect box = borderBoundingBox();
- adjustRectForOutlineAndShadow(box);
-
- if (repaintContainer != this) {
- FloatQuad containerRelativeQuad;
- if (geometryMap)
- containerRelativeQuad = geometryMap->mapToContainer(box, repaintContainer);
- else
- containerRelativeQuad = localToContainerQuad(FloatRect(box), repaintContainer);
-
- box = containerRelativeQuad.enclosingBoundingBox();
- }
-
- // FIXME: layoutDelta needs to be applied in parts before/after transforms and
- // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
- box.move(view()->layoutDelta());
-
- return box;
-}
-
void RenderBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject*)
{
if (!size().isEmpty())
@@ -696,38 +612,13 @@ void RenderBox::computeSelfHitTestRects(Vector<LayoutRect>& rects, const LayoutP
rects.append(LayoutRect(layerOffset, size()));
}
-LayoutRect RenderBox::reflectionBox() const
-{
- LayoutRect result;
- if (!style()->boxReflect())
- return result;
- LayoutRect box = borderBoxRect();
- result = box;
- switch (style()->boxReflect()->direction()) {
- case ReflectionBelow:
- result.move(0, box.height() + reflectionOffset());
- break;
- case ReflectionAbove:
- result.move(0, -box.height() - reflectionOffset());
- break;
- case ReflectionLeft:
- result.move(-box.width() - reflectionOffset(), 0);
- break;
- case ReflectionRight:
- result.move(box.width() + reflectionOffset(), 0);
- break;
- }
- return result;
-}
-
int RenderBox::reflectionOffset() const
{
if (!style()->boxReflect())
return 0;
- RenderView* renderView = view();
if (style()->boxReflect()->direction() == ReflectionLeft || style()->boxReflect()->direction() == ReflectionRight)
- return valueForLength(style()->boxReflect()->offset(), borderBoxRect().width(), renderView);
- return valueForLength(style()->boxReflect()->offset(), borderBoxRect().height(), renderView);
+ return valueForLength(style()->boxReflect()->offset(), borderBoxRect().width());
+ return valueForLength(style()->boxReflect()->offset(), borderBoxRect().height());
}
LayoutRect RenderBox::reflectedRect(const LayoutRect& r) const
@@ -788,20 +679,23 @@ int RenderBox::instrinsicScrollbarLogicalWidth() const
return 0;
}
-bool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
+bool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float delta)
{
+ // Presumably the same issue as in setScrollTop. See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
// Logical scroll is a higher level concept, all directions by here must be physical
ASSERT(!isLogical(direction));
if (!layer() || !layer()->scrollableArea())
return false;
- return layer()->scrollableArea()->scroll(direction, granularity, multiplier);
+ return layer()->scrollableArea()->scroll(direction, granularity, delta);
}
bool RenderBox::canBeScrolledAndHasScrollableArea() const
{
- return canBeProgramaticallyScrolled() && (scrollHeight() != clientHeight() || scrollWidth() != clientWidth());
+ return canBeProgramaticallyScrolled() && (pixelSnappedScrollHeight() != pixelSnappedClientHeight() || pixelSnappedScrollWidth() != pixelSnappedClientWidth());
}
bool RenderBox::canBeProgramaticallyScrolled() const
@@ -827,7 +721,7 @@ bool RenderBox::usesCompositedScrolling() const
void RenderBox::autoscroll(const IntPoint& position)
{
- Frame* frame = this->frame();
+ LocalFrame* frame = this->frame();
if (!frame)
return;
@@ -918,7 +812,7 @@ static inline IntSize adjustedScrollDelta(const IntSize& delta)
void RenderBox::panScroll(const IntPoint& sourcePoint)
{
- Frame* frame = this->frame();
+ LocalFrame* frame = this->frame();
if (!frame)
return;
@@ -960,7 +854,7 @@ void RenderBox::scrollByRecursively(const IntSize& delta, ScrollOffsetClamping c
if (RenderBox* scrollableBox = enclosingScrollableBox())
scrollableBox->scrollByRecursively(remainingScrollOffset, clamp);
- Frame* frame = this->frame();
+ LocalFrame* frame = this->frame();
if (frame && frame->page())
frame->page()->autoscrollController().updateAutoscrollRenderer();
}
@@ -995,17 +889,21 @@ LayoutSize RenderBox::cachedSizeForOverflowClip() const
void RenderBox::applyCachedClipAndScrollOffsetForRepaint(LayoutRect& paintRect) const
{
+ flipForWritingMode(paintRect);
paintRect.move(-scrolledContentOffset()); // For overflow:auto/scroll/hidden.
// Do not clip scroll layer contents to reduce the number of repaints while scrolling.
- if (usesCompositedScrolling())
+ if (usesCompositedScrolling()) {
+ flipForWritingMode(paintRect);
return;
+ }
// height() is inaccurate if we're in the middle of a layout of this RenderBox, so use the
// layer's size instead. Even if the layer's size is wrong, the layer itself will repaint
// anyway if its size does change.
LayoutRect clipRect(LayoutPoint(), cachedSizeForOverflowClip());
paintRect = intersection(paintRect, clipRect);
+ flipForWritingMode(paintRect);
}
void RenderBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
@@ -1018,7 +916,7 @@ LayoutUnit RenderBox::minPreferredLogicalWidth() const
{
if (preferredLogicalWidthsDirty()) {
#ifndef NDEBUG
- SetLayoutNeededForbiddenScope layoutForbiddenScope(const_cast<RenderBox*>(this));
+ SetLayoutNeededForbiddenScope layoutForbiddenScope(const_cast<RenderBox&>(*this));
#endif
const_cast<RenderBox*>(this)->computePreferredLogicalWidths();
}
@@ -1030,7 +928,7 @@ LayoutUnit RenderBox::maxPreferredLogicalWidth() const
{
if (preferredLogicalWidthsDirty()) {
#ifndef NDEBUG
- SetLayoutNeededForbiddenScope layoutForbiddenScope(const_cast<RenderBox*>(this));
+ SetLayoutNeededForbiddenScope layoutForbiddenScope(const_cast<RenderBox&>(*this));
#endif
const_cast<RenderBox*>(this)->computePreferredLogicalWidths();
}
@@ -1040,38 +938,36 @@ LayoutUnit RenderBox::maxPreferredLogicalWidth() const
bool RenderBox::hasOverrideHeight() const
{
- return gOverrideHeightMap && gOverrideHeightMap->contains(this);
+ return m_rareData && m_rareData->m_overrideLogicalContentHeight != -1;
}
bool RenderBox::hasOverrideWidth() const
{
- return gOverrideWidthMap && gOverrideWidthMap->contains(this);
+ return m_rareData && m_rareData->m_overrideLogicalContentWidth != -1;
}
void RenderBox::setOverrideLogicalContentHeight(LayoutUnit height)
{
- if (!gOverrideHeightMap)
- gOverrideHeightMap = new OverrideSizeMap();
- gOverrideHeightMap->set(this, height);
+ ASSERT(height >= 0);
+ ensureRareData().m_overrideLogicalContentHeight = height;
}
void RenderBox::setOverrideLogicalContentWidth(LayoutUnit width)
{
- if (!gOverrideWidthMap)
- gOverrideWidthMap = new OverrideSizeMap();
- gOverrideWidthMap->set(this, width);
+ ASSERT(width >= 0);
+ ensureRareData().m_overrideLogicalContentWidth = width;
}
void RenderBox::clearOverrideLogicalContentHeight()
{
- if (gOverrideHeightMap)
- gOverrideHeightMap->remove(this);
+ if (m_rareData)
+ m_rareData->m_overrideLogicalContentHeight = -1;
}
void RenderBox::clearOverrideLogicalContentWidth()
{
- if (gOverrideWidthMap)
- gOverrideWidthMap->remove(this);
+ if (m_rareData)
+ m_rareData->m_overrideLogicalContentWidth = -1;
}
void RenderBox::clearOverrideSize()
@@ -1083,13 +979,13 @@ void RenderBox::clearOverrideSize()
LayoutUnit RenderBox::overrideLogicalContentWidth() const
{
ASSERT(hasOverrideWidth());
- return gOverrideWidthMap->get(this);
+ return m_rareData->m_overrideLogicalContentWidth;
}
LayoutUnit RenderBox::overrideLogicalContentHeight() const
{
ASSERT(hasOverrideHeight());
- return gOverrideHeightMap->get(this);
+ return m_rareData->m_overrideLogicalContentHeight;
}
LayoutUnit RenderBox::overrideContainingBlockContentLogicalWidth() const
@@ -1177,8 +1073,8 @@ bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
LayoutPoint adjustedLocation = accumulatedOffset + location();
// Check kids first.
- for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
- if (!child->hasLayer() && child->nodeAtPoint(request, result, locationInContainer, adjustedLocation, action)) {
+ for (RenderObject* child = slowLastChild(); child; child = child->previousSibling()) {
+ if ((!child->hasLayer() || !toRenderLayerModelObject(child)->layer()->isSelfPaintingLayer()) && child->nodeAtPoint(request, result, locationInContainer, adjustedLocation, action)) {
updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
return true;
}
@@ -1186,7 +1082,7 @@ bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
// Check our bounds next. For this purpose always assume that we can only be hit in the
// foreground phase (which is true for replaced elements like images).
- LayoutRect boundsRect = borderBoxRectInRegion(locationInContainer.region());
+ LayoutRect boundsRect = borderBoxRect();
boundsRect.moveBy(adjustedLocation);
if (visibleToHitTestRequest(request) && action == HitTestForeground && locationInContainer.intersects(boundsRect)) {
updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
@@ -1205,7 +1101,7 @@ void RenderBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
// default implementation. Just pass paint through to the children
PaintInfo childInfo(paintInfo);
childInfo.updatePaintingRootForChildren(this);
- for (RenderObject* child = firstChild(); child; child = child->nextSibling())
+ for (RenderObject* child = slowFirstChild(); child; child = child->nextSibling())
child->paint(childInfo, adjustedPaintOffset);
}
@@ -1229,9 +1125,11 @@ BackgroundBleedAvoidance RenderBox::determineBackgroundBleedAvoidance(GraphicsCo
const RenderStyle* style = this->style();
- if (!style->hasBackground() || !style->hasBorder() || !style->hasBorderRadius() || borderImageIsLoadedAndCanBeRendered())
+ if (!style->hasBackground() || !style->hasBorder() || !style->hasBorderRadius() || canRenderBorderImage())
return BackgroundBleedNone;
+ // FIXME: See crbug.com/382491. getCTM does not accurately reflect the scale at the time content is
+ // rasterized, and should not be relied on to make decisions about bleeding.
AffineTransform ctm = context->getCTM();
FloatSize contextScaling(static_cast<float>(ctm.xScale()), static_cast<float>(ctm.yScale()));
@@ -1254,7 +1152,7 @@ BackgroundBleedAvoidance RenderBox::determineBackgroundBleedAvoidance(GraphicsCo
if (!style->hasAppearance() && borderObscuresBackground() && backgroundHasOpaqueTopLayer())
return BackgroundBleedBackgroundOverBorder;
- return BackgroundBleedUseTransparencyLayer;
+ return BackgroundBleedClipBackground;
}
void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -1262,7 +1160,7 @@ void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& pai
if (!paintInfo.shouldPaintWithinRoot(this))
return;
- LayoutRect paintRect = borderBoxRectInRegion(paintInfo.renderRegion);
+ LayoutRect paintRect = borderBoxRect();
paintRect.moveBy(paintOffset);
paintBoxDecorationsWithRect(paintInfo, paintOffset, paintRect);
}
@@ -1277,20 +1175,13 @@ void RenderBox::paintBoxDecorationsWithRect(PaintInfo& paintInfo, const LayoutPo
paintBoxShadow(paintInfo, paintRect, style(), Normal);
GraphicsContextStateSaver stateSaver(*paintInfo.context, false);
- if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) {
- // To avoid the background color bleeding out behind the border, we'll render background and border
- // into a transparency layer, and then clip that in one go (which requires setting up the clip before
- // beginning the layer).
- RoundedRect border = style()->getRoundedBorderFor(paintRect, view());
+ if (bleedAvoidance == BackgroundBleedClipBackground) {
stateSaver.save();
+ RoundedRect border = style()->getRoundedBorderFor(paintRect);
paintInfo.context->clipRoundedRect(border);
- paintInfo.context->beginTransparencyLayer(1);
}
paintBackgroundWithBorderAndBoxShadow(paintInfo, paintRect, bleedAvoidance);
-
- if (bleedAvoidance == BackgroundBleedUseTransparencyLayer)
- paintInfo.context->endLayer();
}
void RenderBox::paintBackgroundWithBorderAndBoxShadow(PaintInfo& paintInfo, const LayoutRect& paintRect, BackgroundBleedAvoidance bleedAvoidance)
@@ -1317,7 +1208,7 @@ void RenderBox::paintBackgroundWithBorderAndBoxShadow(PaintInfo& paintInfo, cons
void RenderBox::paintBackground(const PaintInfo& paintInfo, const LayoutRect& paintRect, BackgroundBleedAvoidance bleedAvoidance)
{
- if (isRoot()) {
+ if (isDocumentElement()) {
paintRootBoxFillLayers(paintInfo);
return;
}
@@ -1328,19 +1219,28 @@ void RenderBox::paintBackground(const PaintInfo& paintInfo, const LayoutRect& pa
paintFillLayers(paintInfo, resolveColor(CSSPropertyBackgroundColor), style()->backgroundLayers(), paintRect, bleedAvoidance);
}
-LayoutRect RenderBox::backgroundPaintedExtent() const
+bool RenderBox::getBackgroundPaintedExtent(LayoutRect& paintedExtent) const
{
ASSERT(hasBackground());
LayoutRect backgroundRect = pixelSnappedIntRect(borderBoxRect());
Color backgroundColor = resolveColor(CSSPropertyBackgroundColor);
- if (backgroundColor.isValid() && backgroundColor.alpha())
- return backgroundRect;
- if (!style()->backgroundLayers()->image() || style()->backgroundLayers()->next())
- return backgroundRect;
+ if (backgroundColor.alpha()) {
+ paintedExtent = backgroundRect;
+ return true;
+ }
+
+ if (!style()->backgroundLayers()->image() || style()->backgroundLayers()->next()) {
+ paintedExtent = backgroundRect;
+ return true;
+ }
+
BackgroundImageGeometry geometry;
- const_cast<RenderBox*>(this)->calculateBackgroundImageGeometry(style()->backgroundLayers(), backgroundRect, geometry);
- return geometry.destRect();
+ calculateBackgroundImageGeometry(0, style()->backgroundLayers(), backgroundRect, geometry);
+ if (geometry.hasNonLocalGeometry())
+ return false;
+ paintedExtent = geometry.destRect();
+ return true;
}
bool RenderBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
@@ -1349,7 +1249,7 @@ bool RenderBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) c
return false;
Color backgroundColor = resolveColor(CSSPropertyBackgroundColor);
- if (!backgroundColor.isValid() || backgroundColor.hasAlpha())
+ if (backgroundColor.hasAlpha())
return false;
// If the element has appearance, it might be painted by theme.
@@ -1411,7 +1311,7 @@ bool RenderBox::foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, u
{
if (!maxDepthToTest)
return false;
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = slowFirstChild(); child; child = child->nextSibling()) {
if (!child->isBox())
continue;
RenderBox* childBox = toRenderBox(child);
@@ -1445,12 +1345,14 @@ bool RenderBox::computeBackgroundIsKnownToBeObscured()
if (!hasBackground())
return false;
// Table and root background painting is special.
- if (isTable() || isRoot())
+ if (isTable() || isDocumentElement())
return false;
// FIXME: box-shadow is painted while background painting.
if (style()->boxShadow())
return false;
- LayoutRect backgroundRect = backgroundPaintedExtent();
+ LayoutRect backgroundRect;
+ if (!getBackgroundPaintedExtent(backgroundRect))
+ return false;
return foregroundIsKnownToBeOpaqueInRect(backgroundRect, backgroundObscurationTestMaxDepth);
}
@@ -1464,13 +1366,13 @@ bool RenderBox::backgroundHasOpaqueTopLayer() const
if (hasOverflowClip() && fillLayer->attachment() == LocalBackgroundAttachment)
return false;
- if (fillLayer->hasOpaqueImage(this) && fillLayer->hasRepeatXY() && fillLayer->image()->canRender(this, style()->effectiveZoom()))
+ if (fillLayer->hasOpaqueImage(this) && fillLayer->hasRepeatXY() && fillLayer->image()->canRender(*this, style()->effectiveZoom()))
return true;
// If there is only one layer and no image, check whether the background color is opaque
if (!fillLayer->next() && !fillLayer->hasImage()) {
Color bgColor = resolveColor(CSSPropertyBackgroundColor);
- if (bgColor.isValid() && bgColor.alpha() == 255)
+ if (bgColor.alpha() == 255)
return true;
}
@@ -1530,7 +1432,7 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, const LayoutRect& pa
}
if (allMaskImagesLoaded) {
- paintFillLayers(paintInfo, Color(), style()->maskLayers(), paintRect, BackgroundBleedNone, compositeOp);
+ paintFillLayers(paintInfo, Color::transparent, style()->maskLayers(), paintRect, BackgroundBleedNone, compositeOp);
paintNinePieceImage(paintInfo.context, paintRect, style(), style()->maskBoxImage(), compositeOp);
}
@@ -1538,29 +1440,6 @@ void RenderBox::paintMaskImages(const PaintInfo& paintInfo, const LayoutRect& pa
paintInfo.context->endLayer();
}
-LayoutRect RenderBox::maskClipRect()
-{
- const NinePieceImage& maskBoxImage = style()->maskBoxImage();
- if (maskBoxImage.image()) {
- LayoutRect borderImageRect = borderBoxRect();
-
- // Apply outsets to the border box.
- borderImageRect.expand(style()->maskBoxImageOutsets());
- return borderImageRect;
- }
-
- LayoutRect result;
- LayoutRect borderBox = borderBoxRect();
- for (const FillLayer* maskLayer = style()->maskLayers(); maskLayer; maskLayer = maskLayer->next()) {
- if (maskLayer->image()) {
- BackgroundImageGeometry geometry;
- calculateBackgroundImageGeometry(maskLayer, borderBox, geometry);
- result.unite(geometry.destRect());
- }
- }
- return result;
-}
-
void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, const LayoutRect& rect,
BackgroundBleedAvoidance bleedAvoidance, CompositeOperator op, RenderObject* backgroundObject)
{
@@ -1581,7 +1460,7 @@ void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, cons
shouldDrawBackgroundInSeparateBuffer = true;
// The clipOccludesNextLayers condition must be evaluated first to avoid short-circuiting.
- if (curLayer->clipOccludesNextLayers(curLayer == fillLayer) && curLayer->hasOpaqueImage(this) && curLayer->image()->canRender(this, style()->effectiveZoom()) && curLayer->hasRepeatXY() && curLayer->blendMode() == blink::WebBlendModeNormal && !boxShadowShouldBeAppliedToBackground(bleedAvoidance))
+ if (curLayer->clipOccludesNextLayers(curLayer == fillLayer) && curLayer->hasOpaqueImage(this) && curLayer->image()->canRender(*this, style()->effectiveZoom()) && curLayer->hasRepeatXY() && curLayer->blendMode() == blink::WebBlendModeNormal && !boxShadowShouldBeAppliedToBackground(bleedAvoidance))
break;
curLayer = curLayer->next();
}
@@ -1606,34 +1485,28 @@ void RenderBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const
paintFillLayerExtended(paintInfo, c, fillLayer, rect, bleedAvoidance, 0, LayoutSize(), op, backgroundObject);
}
-static bool layersUseImage(WrappedImagePtr image, const FillLayer* layers)
-{
- for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next()) {
- if (curLayer->image() && image == curLayer->image()->data())
- return true;
- }
-
- return false;
-}
-
void RenderBox::imageChanged(WrappedImagePtr image, const IntRect*)
{
if (!parent())
return;
+ AllowPaintInvalidationScope scoper(frameView());
+
if ((style()->borderImage().image() && style()->borderImage().image()->data() == image) ||
(style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image)) {
- repaint();
+ paintInvalidationForWholeRenderer();
return;
}
+ ShapeValue* shapeOutsideValue = style()->shapeOutside();
+ if (!frameView()->isInPerformLayout() && isFloating() && shapeOutsideValue && shapeOutsideValue->image() && shapeOutsideValue->image()->data() == image) {
+ ShapeOutsideInfo::ensureInfo(*this).markShapeAsDirty();
+ markShapeOutsideDependentsForLayout();
+ }
+
bool didFullRepaint = repaintLayerRectsForImage(image, style()->backgroundLayers(), true);
if (!didFullRepaint)
repaintLayerRectsForImage(image, style()->maskLayers(), false);
-
-
- if (hasLayer() && layer()->hasCompositedMask() && layersUseImage(image, style()->maskLayers()))
- layer()->contentChanged(MaskImageChanged);
}
bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer* layers, bool drawingBackground)
@@ -1642,11 +1515,10 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
RenderBox* layerRenderer = 0;
for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next()) {
- if (curLayer->image() && image == curLayer->image()->data() && curLayer->image()->canRender(this, style()->effectiveZoom())) {
- // Now that we know this image is being used, compute the renderer and the rect
- // if we haven't already
+ if (curLayer->image() && image == curLayer->image()->data() && curLayer->image()->canRender(*this, style()->effectiveZoom())) {
+ // Now that we know this image is being used, compute the renderer and the rect if we haven't already.
if (!layerRenderer) {
- bool drawingRootBackground = drawingBackground && (isRoot() || (isBody() && !document().documentElement()->renderer()->hasBackground()));
+ bool drawingRootBackground = drawingBackground && (isDocumentElement() || (isBody() && !document().documentElement()->renderer()->hasBackground()));
if (drawingRootBackground) {
layerRenderer = view();
@@ -1671,8 +1543,15 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
}
BackgroundImageGeometry geometry;
- layerRenderer->calculateBackgroundImageGeometry(curLayer, rendererRect, geometry);
- layerRenderer->repaintRectangle(geometry.destRect());
+ layerRenderer->calculateBackgroundImageGeometry(0, curLayer, rendererRect, geometry);
+ if (geometry.hasNonLocalGeometry()) {
+ // Rather than incur the costs of computing the paintContainer for renderers with fixed backgrounds
+ // in order to get the right destRect, just repaint the entire renderer.
+ layerRenderer->paintInvalidationForWholeRenderer();
+ return true;
+ }
+
+ layerRenderer->invalidatePaintRectangle(geometry.destRect());
if (geometry.destRect() == rendererRect)
return true;
}
@@ -1680,6 +1559,80 @@ bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer
return false;
}
+void RenderBox::invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer)
+{
+ // FIXME: Currently only using this logic for RenderBox and its ilk. Ideally, RenderBlockFlows with
+ // inline children should track a dirty rect in local coordinates for dirty lines instead of invalidating
+ // the world.
+ // FIXME: We should still be recursing through inline's children, as they can have boxes, but we don't
+ // appear to have tests for this?
+ // FIXME: SVG should probably also go through this unified paint invalidation system.
+
+ ASSERT(RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
+ ASSERT(!needsLayout());
+
+ if (!shouldCheckForPaintInvalidationAfterLayout())
+ return;
+
+ bool establishesNewPaintInvalidationContainer = isPaintInvalidationContainer();
+ const RenderLayerModelObject& newPaintInvalidationContainer = *adjustCompositedContainerForSpecialAncestors(establishesNewPaintInvalidationContainer ? this : &paintInvalidationContainer);
+ // FIXME: This assert should be re-enabled when we move paint invalidation to after compositing update. crbug.com/360286
+ // ASSERT(&newPaintInvalidationContainer == containerForPaintInvalidation());
+
+ const LayoutRect oldPaintInvalidationRect = previousPaintInvalidationRect();
+ const LayoutPoint oldPositionFromPaintInvalidationContainer = previousPositionFromPaintInvalidationContainer();
+ setPreviousPaintInvalidationRect(boundsRectForPaintInvalidation(&newPaintInvalidationContainer));
+ setPreviousPositionFromPaintInvalidationContainer(RenderLayer::positionFromPaintInvalidationContainer(this, &newPaintInvalidationContainer));
+
+ // If we are set to do a full paint invalidation that means the RenderView will be
+ // issue paint invalidations. We can then skip issuing of paint invalidations for the child
+ // renderers as they'll be covered by the RenderView.
+ if (view()->doingFullRepaint()) {
+ LayoutState state(*this, isTableRow() ? LayoutSize() : locationOffset());
+ RenderObject::invalidateTreeAfterLayout(newPaintInvalidationContainer);
+ return;
+ }
+
+ if ((onlyNeededPositionedMovementLayout() && compositingState() != PaintsIntoOwnBacking)
+ || (shouldDoFullPaintInvalidationIfSelfPaintingLayer()
+ && hasLayer()
+ && layer()->isSelfPaintingLayer())) {
+ setShouldDoFullPaintInvalidationAfterLayout(true);
+ }
+
+ const LayoutRect& newPaintInvalidationRect = previousPaintInvalidationRect();
+ const LayoutPoint& newPositionFromPaintInvalidationContainer = previousPositionFromPaintInvalidationContainer();
+ bool didFullPaintInvalidation = invalidatePaintAfterLayoutIfNeeded(&newPaintInvalidationContainer,
+ shouldDoFullPaintInvalidationAfterLayout(), oldPaintInvalidationRect, oldPositionFromPaintInvalidationContainer,
+ &newPaintInvalidationRect, &newPositionFromPaintInvalidationContainer);
+
+ if (!didFullPaintInvalidation)
+ invalidatePaintForOverflowIfNeeded();
+
+ // Issue paint invalidations for any scrollbars if there is a scrollable area for this renderer.
+ if (enclosingLayer()) {
+ if (RenderLayerScrollableArea* area = enclosingLayer()->scrollableArea()) {
+ if (area->hasVerticalBarDamage())
+ invalidatePaintRectangle(area->verticalBarDamage());
+ if (area->hasHorizontalBarDamage())
+ invalidatePaintRectangle(area->horizontalBarDamage());
+ area->resetScrollbarDamage();
+ }
+ }
+
+ // FIXME: LayoutState should be enabled for other paint invalidation containers than the RenderView. crbug.com/363834
+ if (establishesNewPaintInvalidationContainer && !isRenderView()) {
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
+ RenderObject::invalidateTreeAfterLayout(newPaintInvalidationContainer);
+ } else {
+ // FIXME: This concept of a tree walking state for fast lookups should be generalized away from
+ // just layout.
+ // FIXME: Table rows shouldn't be special-cased.
+ LayoutState state(*this, isTableRow() ? LayoutSize() : locationOffset());
+ RenderObject::invalidateTreeAfterLayout(newPaintInvalidationContainer);
+ }
+}
+
bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumulatedOffset, ContentsClipBehavior contentsClipBehavior)
{
if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseSelfOutline || paintInfo.phase == PaintPhaseMask)
@@ -1691,7 +1644,7 @@ bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu
if (!isControlClip && !isOverflowClip)
return false;
- LayoutRect clipRect = isControlClip ? controlClipRect(accumulatedOffset) : overflowClipRect(accumulatedOffset, paintInfo.renderRegion);
+ LayoutRect clipRect = isControlClip ? controlClipRect(accumulatedOffset) : overflowClipRect(accumulatedOffset);
RoundedRect clipRoundedRect(0, 0, 0, 0);
bool hasBorderRadius = style()->hasBorderRadius();
if (hasBorderRadius)
@@ -1702,11 +1655,6 @@ bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu
if (contentsVisualOverflow.isEmpty())
return false;
- // FIXME: Get rid of this slop from here and elsewhere.
- // Instead, properly include the outline in visual overflow.
- if (RenderView* view = this->view())
- contentsVisualOverflow.inflate(view->maximalOutlineSize());
-
LayoutRect conservativeClipRect = clipRect;
if (hasBorderRadius)
conservativeClipRect.intersect(clipRoundedRect.radiusCenterRect());
@@ -1744,11 +1692,11 @@ void RenderBox::popContentsClip(PaintInfo& paintInfo, PaintPhase originalPhase,
paintInfo.phase = originalPhase;
}
-LayoutRect RenderBox::overflowClipRect(const LayoutPoint& location, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy)
+LayoutRect RenderBox::overflowClipRect(const LayoutPoint& location, OverlayScrollbarSizeRelevancy relevancy)
{
// FIXME: When overflow-clip (CSS3) is implemented, we'll obtain the property
// here.
- LayoutRect clipRect = borderBoxRectInRegion(region);
+ LayoutRect clipRect = borderBoxRect();
clipRect.setLocation(location + clipRect.location() + LayoutSize(borderLeft(), borderTop()));
clipRect.setSize(clipRect.size() - LayoutSize(borderLeft() + borderRight(), borderTop() + borderBottom()));
@@ -1763,74 +1711,55 @@ LayoutRect RenderBox::overflowClipRect(const LayoutPoint& location, RenderRegion
return clipRect;
}
-LayoutRect RenderBox::clipRect(const LayoutPoint& location, RenderRegion* region)
+LayoutRect RenderBox::clipRect(const LayoutPoint& location)
{
- LayoutRect borderBoxRect = borderBoxRectInRegion(region);
+ LayoutRect borderBoxRect = this->borderBoxRect();
LayoutRect clipRect = LayoutRect(borderBoxRect.location() + location, borderBoxRect.size());
- RenderView* renderView = view();
if (!style()->clipLeft().isAuto()) {
- LayoutUnit c = valueForLength(style()->clipLeft(), borderBoxRect.width(), renderView);
+ LayoutUnit c = valueForLength(style()->clipLeft(), borderBoxRect.width());
clipRect.move(c, 0);
clipRect.contract(c, 0);
}
- // We don't use the region-specific border box's width and height since clip offsets are (stupidly) specified
- // from the left and top edges. Therefore it's better to avoid constraining to smaller widths and heights.
-
if (!style()->clipRight().isAuto())
- clipRect.contract(width() - valueForLength(style()->clipRight(), width(), renderView), 0);
+ clipRect.contract(width() - valueForLength(style()->clipRight(), width()), 0);
if (!style()->clipTop().isAuto()) {
- LayoutUnit c = valueForLength(style()->clipTop(), borderBoxRect.height(), renderView);
+ LayoutUnit c = valueForLength(style()->clipTop(), borderBoxRect.height());
clipRect.move(0, c);
clipRect.contract(0, c);
}
if (!style()->clipBottom().isAuto())
- clipRect.contract(0, height() - valueForLength(style()->clipBottom(), height(), renderView));
+ clipRect.contract(0, height() - valueForLength(style()->clipBottom(), height()));
return clipRect;
}
-LayoutUnit RenderBox::shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlockFlow* cb, RenderRegion* region) const
+static LayoutUnit portionOfMarginNotConsumedByFloat(LayoutUnit childMargin, LayoutUnit contentSide, LayoutUnit offset)
{
- RenderRegion* containingBlockRegion = 0;
- LayoutUnit logicalTopPosition = logicalTop();
- if (region) {
- LayoutUnit offsetFromLogicalTopOfRegion = region ? region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage() : LayoutUnit();
- logicalTopPosition = max(logicalTopPosition, logicalTopPosition + offsetFromLogicalTopOfRegion);
- containingBlockRegion = cb->clampToStartAndEndRegions(region);
- }
+ if (childMargin <= 0)
+ return 0;
+ LayoutUnit contentSideWithMargin = contentSide + childMargin;
+ if (offset > contentSideWithMargin)
+ return childMargin;
+ return offset - contentSide;
+}
- LayoutUnit result = cb->availableLogicalWidthForLineInRegion(logicalTopPosition, false, containingBlockRegion) - childMarginStart - childMarginEnd;
+LayoutUnit RenderBox::shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlockFlow* cb) const
+{
+ LayoutUnit logicalTopPosition = logicalTop();
+ LayoutUnit width = cb->availableLogicalWidthForLine(logicalTopPosition, false) - max<LayoutUnit>(0, childMarginStart) - max<LayoutUnit>(0, childMarginEnd);
// We need to see if margins on either the start side or the end side can contain the floats in question. If they can,
// then just using the line width is inaccurate. In the case where a float completely fits, we don't need to use the line
// offset at all, but can instead push all the way to the content edge of the containing block. In the case where the float
// doesn't fit, we can use the line offset, but we need to grow it by the margin to reflect the fact that the margin was
// "consumed" by the float. Negative margins aren't consumed by the float, and so we ignore them.
- if (childMarginStart > 0) {
- LayoutUnit startContentSide = cb->startOffsetForContent(containingBlockRegion);
- LayoutUnit startContentSideWithMargin = startContentSide + childMarginStart;
- LayoutUnit startOffset = cb->startOffsetForLineInRegion(logicalTopPosition, false, containingBlockRegion);
- if (startOffset > startContentSideWithMargin)
- result += childMarginStart;
- else
- result += startOffset - startContentSide;
- }
-
- if (childMarginEnd > 0) {
- LayoutUnit endContentSide = cb->endOffsetForContent(containingBlockRegion);
- LayoutUnit endContentSideWithMargin = endContentSide + childMarginEnd;
- LayoutUnit endOffset = cb->endOffsetForLineInRegion(logicalTopPosition, false, containingBlockRegion);
- if (endOffset > endContentSideWithMargin)
- result += childMarginEnd;
- else
- result += endOffset - endContentSide;
- }
-
- return result;
+ width += portionOfMarginNotConsumedByFloat(childMarginStart, cb->startOffsetForContent(), cb->startOffsetForLine(logicalTopPosition, false));
+ width += portionOfMarginNotConsumedByFloat(childMarginEnd, cb->endOffsetForContent(), cb->endOffsetForLine(logicalTopPosition, false));
+ return width;
}
LayoutUnit RenderBox::containingBlockLogicalWidthForContent() const
@@ -1851,33 +1780,12 @@ LayoutUnit RenderBox::containingBlockLogicalHeightForContent(AvailableLogicalHei
return cb->availableLogicalHeight(heightType);
}
-LayoutUnit RenderBox::containingBlockLogicalWidthForContentInRegion(RenderRegion* region) const
+LayoutUnit RenderBox::containingBlockAvailableLineWidth() const
{
- if (!region)
- return containingBlockLogicalWidthForContent();
-
RenderBlock* cb = containingBlock();
- RenderRegion* containingBlockRegion = cb->clampToStartAndEndRegions(region);
- // FIXME: It's unclear if a region's content should use the containing block's override logical width.
- // If it should, the following line should call containingBlockLogicalWidthForContent.
- LayoutUnit result = cb->availableLogicalWidth();
- RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(containingBlockRegion);
- if (!boxInfo)
- return result;
- return max<LayoutUnit>(0, result - (cb->logicalWidth() - boxInfo->logicalWidth()));
-}
-
-LayoutUnit RenderBox::containingBlockAvailableLineWidthInRegion(RenderRegion* region) const
-{
- RenderBlock* cb = containingBlock();
- RenderRegion* containingBlockRegion = 0;
- LayoutUnit logicalTopPosition = logicalTop();
- if (region) {
- LayoutUnit offsetFromLogicalTopOfRegion = region ? region->logicalTopForFlowThreadContent() - offsetFromLogicalTopOfFirstPage() : LayoutUnit();
- logicalTopPosition = max(logicalTopPosition, logicalTopPosition + offsetFromLogicalTopOfRegion);
- containingBlockRegion = cb->clampToStartAndEndRegions(region);
- }
- return cb->availableLogicalWidthForLineInRegion(logicalTopPosition, false, containingBlockRegion, availableLogicalHeight(IncludeMarginBorderPadding));
+ if (cb->isRenderBlockFlow())
+ return toRenderBlockFlow(cb)->availableLogicalWidthForLine(logicalTop(), false, availableLogicalHeight(IncludeMarginBorderPadding));
+ return 0;
}
LayoutUnit RenderBox::perpendicularContainingBlockLogicalHeight() const
@@ -1909,9 +1817,9 @@ void RenderBox::mapLocalToContainer(const RenderLayerModelObject* repaintContain
return;
if (RenderView* v = view()) {
- if (v->layoutStateEnabled() && !repaintContainer) {
+ if (v->canMapUsingLayoutStateForContainer(repaintContainer)) {
LayoutState* layoutState = v->layoutState();
- LayoutSize offset = layoutState->m_paintOffset + locationOffset();
+ LayoutSize offset = layoutState->paintOffset() + locationOffset();
if (style()->hasInFlowPosition() && layer())
offset += layer()->offsetForInFlowPosition();
transformState.move(offset);
@@ -1962,7 +1870,7 @@ void RenderBox::mapLocalToContainer(const RenderLayerModelObject* repaintContain
void RenderBox::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
{
// We don't expect to be called during layout.
- ASSERT(!view() || !view()->layoutStateEnabled());
+ ASSERT(!view() || !view()->layoutStateCachedOffsetsEnabled());
bool isFixedPos = style()->position() == FixedPosition;
bool hasTransform = hasLayer() && layer()->transform();
@@ -1976,13 +1884,9 @@ void RenderBox::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState
RenderBoxModelObject::mapAbsoluteToLocalPoint(mode, transformState);
}
-LayoutSize RenderBox::offsetFromContainer(RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
+LayoutSize RenderBox::offsetFromContainer(const RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
{
- // A region "has" boxes inside it without being their container.
- // FIXME: change container() / containingBlock() to count for boxes being positioned relative to the region, not the
- // FlowThread. This requires a separate patch as a simple test with such a change in container() causes 129 out of
- // 337 regions tests to fail.
- ASSERT(o == container() || o->isRenderRegion());
+ ASSERT(o == container());
LayoutSize offset;
if (isInFlowPositioned())
@@ -1990,46 +1894,55 @@ LayoutSize RenderBox::offsetFromContainer(RenderObject* o, const LayoutPoint& po
if (!isInline() || isReplaced()) {
if (!style()->hasOutOfFlowPosition() && o->hasColumns()) {
- RenderBlock* block = toRenderBlock(o);
+ const RenderBlock* block = toRenderBlock(o);
LayoutRect columnRect(frameRect());
block->adjustStartEdgeForWritingModeIncludingColumns(columnRect);
offset += toSize(columnRect.location());
LayoutPoint columnPoint = block->flipForWritingModeIncludingColumns(point + offset);
offset = toLayoutSize(block->flipForWritingModeIncludingColumns(toLayoutPoint(offset)));
- o->adjustForColumns(offset, columnPoint);
+ offset += o->columnOffset(columnPoint);
offset = block->flipForWritingMode(offset);
if (offsetDependsOnPoint)
*offsetDependsOnPoint = true;
- } else
+ } else {
offset += topLeftLocationOffset();
+ if (o->isRenderFlowThread()) {
+ // So far the point has been in flow thread coordinates (i.e. as if everything in
+ // the fragmentation context lived in one tall single column). Convert it to a
+ // visual point now.
+ LayoutPoint pointInContainer = point + offset;
+ offset += o->columnOffset(pointInContainer);
+ if (offsetDependsOnPoint)
+ *offsetDependsOnPoint = true;
+ }
+ }
}
if (o->hasOverflowClip())
offset -= toRenderBox(o)->scrolledContentOffset();
if (style()->position() == AbsolutePosition && o->isInFlowPositioned() && o->isRenderInline())
- offset += toRenderInline(o)->offsetForInFlowPositionedInline(this);
-
- if (offsetDependsOnPoint)
- *offsetDependsOnPoint |= o->isRenderFlowThread();
+ offset += toRenderInline(o)->offsetForInFlowPositionedInline(*this);
return offset;
}
InlineBox* RenderBox::createInlineBox()
{
- return new InlineBox(this);
+ return new InlineBox(*this);
}
void RenderBox::dirtyLineBoxes(bool fullLayout)
{
- if (m_inlineBoxWrapper) {
+ if (inlineBoxWrapper()) {
if (fullLayout) {
- m_inlineBoxWrapper->destroy();
- m_inlineBoxWrapper = 0;
- } else
- m_inlineBoxWrapper->dirtyLineBoxes();
+ inlineBoxWrapper()->destroy();
+ ASSERT(m_rareData);
+ m_rareData->m_inlineBoxWrapper = 0;
+ } else {
+ inlineBoxWrapper()->dirtyLineBoxes();
+ }
}
}
@@ -2042,8 +1955,8 @@ void RenderBox::positionLineBox(InlineBox* box)
// The value is cached in the xPos of the box. We only need this value if
// our object was inline originally, since otherwise it would have ended up underneath
// the inlines.
- RootInlineBox* root = box->root();
- root->block()->setStaticInlinePositionForChild(this, root->lineTopWithLeading(), LayoutUnit::fromFloatRound(box->logicalLeft()));
+ RootInlineBox& root = box->root();
+ root.block().setStaticInlinePositionForChild(this, root.lineTopWithLeading(), LayoutUnit::fromFloatRound(box->logicalLeft()));
if (style()->hasStaticInlinePosition(box->isHorizontal()))
setChildNeedsLayout(MarkOnlyThis); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
} else {
@@ -2057,7 +1970,7 @@ void RenderBox::positionLineBox(InlineBox* box)
}
// Nuke the box.
- box->remove();
+ box->remove(DontMarkLineBoxes);
box->destroy();
} else if (isReplaced()) {
setLocation(roundedLayoutPoint(box->topLeft()));
@@ -2067,42 +1980,34 @@ void RenderBox::positionLineBox(InlineBox* box)
void RenderBox::deleteLineBoxWrapper()
{
- if (m_inlineBoxWrapper) {
+ if (inlineBoxWrapper()) {
if (!documentBeingDestroyed())
- m_inlineBoxWrapper->remove();
- m_inlineBoxWrapper->destroy();
- m_inlineBoxWrapper = 0;
+ inlineBoxWrapper()->remove();
+ inlineBoxWrapper()->destroy();
+ ASSERT(m_rareData);
+ m_rareData->m_inlineBoxWrapper = 0;
}
}
-LayoutRect RenderBox::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+LayoutRect RenderBox::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
- if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
+ if (style()->visibility() != VISIBLE && enclosingLayer()->subtreeIsInvisible())
return LayoutRect();
LayoutRect r = visualOverflowRect();
RenderView* v = view();
- if (v) {
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && v) {
// FIXME: layoutDelta needs to be applied in parts before/after transforms and
// repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
r.move(v->layoutDelta());
}
- if (style()) {
- // We have to use maximalOutlineSize() because a child might have an outline
- // that projects outside of our overflowRect.
- if (v) {
- ASSERT(style()->outlineSize() <= v->maximalOutlineSize());
- r.inflate(v->maximalOutlineSize());
- }
- }
-
- computeRectForRepaint(repaintContainer, r);
+ mapRectToPaintInvalidationBacking(paintInvalidationContainer, r);
return r;
}
-void RenderBox::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
+void RenderBox::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, bool fixed) const
{
// The rect we compute at each step is shifted by our x/y offset in the parent container's coordinate space.
// Only when we cross a writing mode boundary will we have to possibly flipForWritingMode (to convert into a more appropriate
@@ -2110,12 +2015,12 @@ void RenderBox::computeRectForRepaint(const RenderLayerModelObject* repaintConta
// properly even during layout, since the rect remains flipped all the way until the end.
//
// RenderView::computeRectForRepaint then converts the rect to physical coordinates. We also convert to
- // physical when we hit a repaintContainer boundary. Therefore the final rect returned is always in the
- // physical coordinate space of the repaintContainer.
+ // physical when we hit a paintInvalidationContainer boundary. Therefore the final rect returned is always in the
+ // physical coordinate space of the paintInvalidationContainer.
RenderStyle* styleToUse = style();
if (RenderView* v = view()) {
// LayoutState is only valid for root-relative, non-fixed position repainting
- if (v->layoutStateEnabled() && !repaintContainer && styleToUse->position() != FixedPosition) {
+ if (v->canMapUsingLayoutStateForContainer(paintInvalidationContainer) && styleToUse->position() != FixedPosition) {
LayoutState* layoutState = v->layoutState();
if (layer() && layer()->transform())
@@ -2126,9 +2031,9 @@ void RenderBox::computeRectForRepaint(const RenderLayerModelObject* repaintConta
rect.move(layer()->offsetForInFlowPosition());
rect.moveBy(location());
- rect.move(layoutState->m_paintOffset);
- if (layoutState->m_clipped)
- rect.intersect(layoutState->m_clipRect);
+ rect.move(layoutState->paintOffset());
+ if (layoutState->isClipped())
+ rect.intersect(layoutState->clipRect());
return;
}
}
@@ -2136,14 +2041,14 @@ void RenderBox::computeRectForRepaint(const RenderLayerModelObject* repaintConta
if (hasReflection())
rect.unite(reflectedRect(rect));
- if (repaintContainer == this) {
- if (repaintContainer->style()->isFlippedBlocksWritingMode())
+ if (paintInvalidationContainer == this) {
+ if (paintInvalidationContainer->style()->isFlippedBlocksWritingMode())
flipForWritingMode(rect);
return;
}
bool containerSkipped;
- RenderObject* o = container(repaintContainer, &containerSkipped);
+ RenderObject* o = container(paintInvalidationContainer, &containerSkipped);
if (!o)
return;
@@ -2166,7 +2071,7 @@ void RenderBox::computeRectForRepaint(const RenderLayerModelObject* repaintConta
fixed = true;
if (position == AbsolutePosition && o->isInFlowPositioned() && o->isRenderInline()) {
- topLeft += toRenderInline(o)->offsetForInFlowPositionedInline(this);
+ topLeft += toRenderInline(o)->offsetForInFlowPositionedInline(*this);
} else if (styleToUse->hasInFlowPosition() && layer()) {
// Apply the relative position offset when invalidating a rectangle. The layer
// is translated, but the render box isn't, so we need to do this to get the
@@ -2193,13 +2098,13 @@ void RenderBox::computeRectForRepaint(const RenderLayerModelObject* repaintConta
}
if (containerSkipped) {
- // If the repaintContainer is below o, then we need to map the rect into repaintContainer's coordinates.
- LayoutSize containerOffset = repaintContainer->offsetFromAncestorContainer(o);
+ // If the paintInvalidationContainer is below o, then we need to map the rect into paintInvalidationContainer's coordinates.
+ LayoutSize containerOffset = paintInvalidationContainer->offsetFromAncestorContainer(o);
rect.move(-containerOffset);
return;
}
- o->computeRectForRepaint(repaintContainer, rect, fixed);
+ o->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, fixed);
}
void RenderBox::repaintDuringLayoutIfMoved(const LayoutRect& oldRect)
@@ -2209,10 +2114,10 @@ void RenderBox::repaintDuringLayoutIfMoved(const LayoutRect& oldRect)
// The child moved. Invalidate the object's old and new positions. We have to do this
// since the object may not have gotten a layout.
m_frameRect = oldRect;
- repaint();
+ paintInvalidationForWholeRenderer();
repaintOverhangingFloats(true);
m_frameRect = newRect;
- repaint();
+ paintInvalidationForWholeRenderer();
repaintOverhangingFloats(true);
}
}
@@ -2224,7 +2129,7 @@ void RenderBox::repaintOverhangingFloats(bool)
void RenderBox::updateLogicalWidth()
{
LogicalExtentComputedValues computedValues;
- computeLogicalWidthInRegion(computedValues);
+ computeLogicalWidth(computedValues);
setLogicalWidth(computedValues.m_extent);
setLogicalLeft(computedValues.m_position);
@@ -2238,25 +2143,22 @@ static float getMaxWidthListMarker(const RenderBox* renderer)
ASSERT(renderer);
Node* parentNode = renderer->generatingNode();
ASSERT(parentNode);
- ASSERT(parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag));
+ ASSERT(isHTMLOListElement(parentNode) || isHTMLUListElement(parentNode));
ASSERT(renderer->style()->textAutosizingMultiplier() != 1);
#endif
float maxWidth = 0;
- for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = renderer->slowFirstChild(); child; child = child->nextSibling()) {
if (!child->isListItem())
continue;
RenderBox* listItem = toRenderBox(child);
- for (RenderObject* itemChild = listItem->firstChild(); itemChild; itemChild = itemChild->nextSibling()) {
+ for (RenderObject* itemChild = listItem->slowFirstChild(); itemChild; itemChild = itemChild->nextSibling()) {
if (!itemChild->isListMarker())
continue;
RenderBox* itemMarker = toRenderBox(itemChild);
- // FIXME: canDetermineWidthWithoutLayout expects us to use fixedOffsetWidth, which this code
- // does not do! This check is likely wrong.
- if (!itemMarker->canDetermineWidthWithoutLayout() && itemMarker->needsLayout()) {
- // Make sure to compute the autosized width.
+ // Make sure to compute the autosized width.
+ if (itemMarker->needsLayout())
itemMarker->layout();
- }
maxWidth = max<float>(maxWidth, toRenderListMarker(itemMarker)->logicalWidth().toFloat());
break;
}
@@ -2264,7 +2166,7 @@ static float getMaxWidthListMarker(const RenderBox* renderer)
return maxWidth;
}
-void RenderBox::computeLogicalWidthInRegion(LogicalExtentComputedValues& computedValues, RenderRegion* region) const
+void RenderBox::computeLogicalWidth(LogicalExtentComputedValues& computedValues) const
{
computedValues.m_extent = logicalWidth();
computedValues.m_position = logicalLeft();
@@ -2274,7 +2176,7 @@ void RenderBox::computeLogicalWidthInRegion(LogicalExtentComputedValues& compute
if (isOutOfFlowPositioned()) {
// FIXME: This calculation is not patched for block-flow yet.
// https://bugs.webkit.org/show_bug.cgi?id=46500
- computePositionedLogicalWidth(computedValues, region);
+ computePositionedLogicalWidth(computedValues);
return;
}
@@ -2301,16 +2203,15 @@ void RenderBox::computeLogicalWidthInRegion(LogicalExtentComputedValues& compute
Length logicalWidthLength = treatAsReplaced ? Length(computeReplacedLogicalWidth(), Fixed) : styleToUse->logicalWidth();
RenderBlock* cb = containingBlock();
- LayoutUnit containerLogicalWidth = max<LayoutUnit>(0, containingBlockLogicalWidthForContentInRegion(region));
+ LayoutUnit containerLogicalWidth = max<LayoutUnit>(0, containingBlockLogicalWidthForContent());
bool hasPerpendicularContainingBlock = cb->isHorizontalWritingMode() != isHorizontalWritingMode();
if (isInline() && !isInlineBlockOrInlineTable()) {
// just calculate margins
- RenderView* renderView = view();
- computedValues.m_margins.m_start = minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth, renderView);
- computedValues.m_margins.m_end = minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth, renderView);
+ computedValues.m_margins.m_start = minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth);
+ computedValues.m_margins.m_end = minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth);
if (treatAsReplaced)
- computedValues.m_extent = max<LayoutUnit>(floatValueForLength(logicalWidthLength, 0, 0) + borderAndPaddingLogicalWidth(), minPreferredLogicalWidth());
+ computedValues.m_extent = max<LayoutUnit>(floatValueForLength(logicalWidthLength, 0) + borderAndPaddingLogicalWidth(), minPreferredLogicalWidth());
return;
}
@@ -2321,24 +2222,13 @@ void RenderBox::computeLogicalWidthInRegion(LogicalExtentComputedValues& compute
LayoutUnit containerWidthInInlineDirection = containerLogicalWidth;
if (hasPerpendicularContainingBlock)
containerWidthInInlineDirection = perpendicularContainingBlockLogicalHeight();
- LayoutUnit preferredWidth = computeLogicalWidthInRegionUsing(MainOrPreferredSize, styleToUse->logicalWidth(), containerWidthInInlineDirection, cb, region);
- computedValues.m_extent = constrainLogicalWidthInRegionByMinMax(preferredWidth, containerWidthInInlineDirection, cb, region);
+ LayoutUnit preferredWidth = computeLogicalWidthUsing(MainOrPreferredSize, styleToUse->logicalWidth(), containerWidthInInlineDirection, cb);
+ computedValues.m_extent = constrainLogicalWidthByMinMax(preferredWidth, containerWidthInInlineDirection, cb);
}
// Margin calculations.
- if (hasPerpendicularContainingBlock || isFloating() || isInline()) {
- RenderView* renderView = view();
- computedValues.m_margins.m_start = minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth, renderView);
- computedValues.m_margins.m_end = minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth, renderView);
- } else {
- LayoutUnit containerLogicalWidthForAutoMargins = containerLogicalWidth;
- if (avoidsFloats() && cb->containsFloats())
- containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidthInRegion(region);
- bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != style()->isLeftToRightDirection();
- computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, computedValues.m_extent,
- hasInvertedDirection ? computedValues.m_margins.m_end : computedValues.m_margins.m_start,
- hasInvertedDirection ? computedValues.m_margins.m_start : computedValues.m_margins.m_end);
- }
+ computeMarginsForDirection(InlineDirection, cb, containerLogicalWidth, computedValues.m_extent, computedValues.m_margins.m_start,
+ computedValues.m_margins.m_end, style()->marginStart(), style()->marginEnd());
if (!hasPerpendicularContainingBlock && containerLogicalWidth && containerLogicalWidth != (computedValues.m_extent + computedValues.m_margins.m_start + computedValues.m_margins.m_end)
&& !isFloating() && !isInline() && !cb->isFlexibleBoxIncludingDeprecated() && !cb->isRenderGrid()) {
@@ -2352,7 +2242,7 @@ void RenderBox::computeLogicalWidthInRegion(LogicalExtentComputedValues& compute
if (styleToUse->textAutosizingMultiplier() != 1 && styleToUse->marginStart().type() == Fixed) {
Node* parentNode = generatingNode();
- if (parentNode && (parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag))) {
+ if (parentNode && (isHTMLOListElement(*parentNode) || isHTMLUListElement(*parentNode))) {
// Make sure the markers in a list are properly positioned (i.e. not chopped off) when autosized.
const float adjustedMargin = (1 - 1.0 / styleToUse->textAutosizingMultiplier()) * getMaxWidthListMarker(this);
bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != style()->isLeftToRightDirection();
@@ -2373,13 +2263,12 @@ LayoutUnit RenderBox::fillAvailableMeasure(LayoutUnit availableLogicalWidth) con
LayoutUnit RenderBox::fillAvailableMeasure(LayoutUnit availableLogicalWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd) const
{
- RenderView* renderView = view();
- marginStart = minimumValueForLength(style()->marginStart(), availableLogicalWidth, renderView);
- marginEnd = minimumValueForLength(style()->marginEnd(), availableLogicalWidth, renderView);
+ marginStart = minimumValueForLength(style()->marginStart(), availableLogicalWidth);
+ marginEnd = minimumValueForLength(style()->marginEnd(), availableLogicalWidth);
return availableLogicalWidth - marginStart - marginEnd;
}
-LayoutUnit RenderBox::computeIntrinsicLogicalWidthUsing(Length logicalWidthLength, LayoutUnit availableLogicalWidth, LayoutUnit borderAndPadding) const
+LayoutUnit RenderBox::computeIntrinsicLogicalWidthUsing(const Length& logicalWidthLength, LayoutUnit availableLogicalWidth, LayoutUnit borderAndPadding) const
{
if (logicalWidthLength.type() == FillAvailable)
return fillAvailableMeasure(availableLogicalWidth);
@@ -2404,12 +2293,11 @@ LayoutUnit RenderBox::computeIntrinsicLogicalWidthUsing(Length logicalWidthLengt
return 0;
}
-LayoutUnit RenderBox::computeLogicalWidthInRegionUsing(SizeType widthType, Length logicalWidth, LayoutUnit availableLogicalWidth,
- const RenderBlock* cb, RenderRegion* region) const
+LayoutUnit RenderBox::computeLogicalWidthUsing(SizeType widthType, const Length& logicalWidth, LayoutUnit availableLogicalWidth, const RenderBlock* cb) const
{
if (!logicalWidth.isIntrinsicOrAuto()) {
// FIXME: If the containing block flow is perpendicular to our direction we need to use the available logical height instead.
- return adjustBorderBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, availableLogicalWidth, view()));
+ return adjustBorderBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, availableLogicalWidth));
}
if (logicalWidth.isIntrinsic())
@@ -2420,9 +2308,9 @@ LayoutUnit RenderBox::computeLogicalWidthInRegionUsing(SizeType widthType, Lengt
LayoutUnit logicalWidthResult = fillAvailableMeasure(availableLogicalWidth, marginStart, marginEnd);
if (shrinkToAvoidFloats() && cb->containsFloats())
- logicalWidthResult = min(logicalWidthResult, shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, toRenderBlockFlow(cb), region));
+ logicalWidthResult = min(logicalWidthResult, shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, toRenderBlockFlow(cb)));
- if (widthType == MainOrPreferredSize && sizesLogicalWidthToFitContent(widthType))
+ if (widthType == MainOrPreferredSize && sizesLogicalWidthToFitContent(logicalWidth))
return max(minPreferredLogicalWidth(), min(maxPreferredLogicalWidth(), logicalWidthResult));
return logicalWidthResult;
}
@@ -2435,7 +2323,7 @@ static bool columnFlexItemHasStretchAlignment(const RenderObject* flexitem)
ASSERT(parent->style()->isColumnFlexDirection());
if (flexitem->style()->marginStart().isAuto() || flexitem->style()->marginEnd().isAuto())
return false;
- return flexitem->style()->alignSelf() == AlignStretch || (flexitem->style()->alignSelf() == AlignAuto && parent->style()->alignItems() == AlignStretch);
+ return flexitem->style()->alignSelf() == ItemPositionStretch || (flexitem->style()->alignSelf() == ItemPositionAuto && parent->style()->alignItems() == ItemPositionStretch);
}
static bool isStretchingColumnFlexItem(const RenderObject* flexitem)
@@ -2450,16 +2338,13 @@ static bool isStretchingColumnFlexItem(const RenderObject* flexitem)
return false;
}
-bool RenderBox::sizesLogicalWidthToFitContent(SizeType widthType) const
+bool RenderBox::sizesLogicalWidthToFitContent(const Length& logicalWidth) const
{
// Marquees in WinIE are like a mixture of blocks and inline-blocks. They size as though they're blocks,
// but they allow text to sit on the same line as the marquee.
if (isFloating() || (isInlineBlockOrInlineTable() && !isMarquee()))
return true;
- // This code may look a bit strange. Basically width:intrinsic should clamp the size when testing both
- // min-width and width. max-width is only clamped if it is also intrinsic.
- Length logicalWidth = (widthType == MaxSize) ? style()->logicalMaxWidth() : style()->logicalWidth();
if (logicalWidth.type() == Intrinsic)
return true;
@@ -2496,7 +2381,7 @@ bool RenderBox::sizesLogicalWidthToFitContent(SizeType widthType) const
// stretching column flexbox.
// FIXME: Think about block-flow here.
// https://bugs.webkit.org/show_bug.cgi?id=46473
- if (logicalWidth.type() == Auto && !isStretchingColumnFlexItem(this) && autoWidthShouldFitContent())
+ if (logicalWidth.isAuto() && !isStretchingColumnFlexItem(this) && autoWidthShouldFitContent())
return true;
if (isHorizontalWritingMode() != containingBlock()->isHorizontalWritingMode())
@@ -2507,24 +2392,26 @@ bool RenderBox::sizesLogicalWidthToFitContent(SizeType widthType) const
bool RenderBox::autoWidthShouldFitContent() const
{
- if (node() && (node()->hasTagName(inputTag) || node()->hasTagName(selectTag) || node()->hasTagName(buttonTag)
- || isHTMLTextAreaElement(node()) || node()->hasTagName(legendTag)))
- return true;
-
- return false;
+ return node() && (isHTMLInputElement(*node()) || isHTMLSelectElement(*node()) || isHTMLButtonElement(*node())
+ || isHTMLTextAreaElement(*node()) || (isHTMLLegendElement(*node()) && !style()->hasOutOfFlowPosition()));
}
-void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd) const
+void RenderBox::computeMarginsForDirection(MarginDirection flowDirection, const RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd, Length marginStartLength, Length marginEndLength) const
{
- const RenderStyle* containingBlockStyle = containingBlock->style();
- Length marginStartLength = style()->marginStartUsing(containingBlockStyle);
- Length marginEndLength = style()->marginEndUsing(containingBlockStyle);
- RenderView* renderView = view();
+ if (flowDirection == BlockDirection || isFloating() || isInline()) {
+ if (isTableCell() && flowDirection == BlockDirection) {
+ // FIXME: Not right if we allow cells to have different directionality than the table. If we do allow this, though,
+ // we may just do it with an extra anonymous block inside the cell.
+ marginStart = 0;
+ marginEnd = 0;
+ return;
+ }
- if (isFloating() || isInline()) {
+ // Margins are calculated with respect to the logical width of
+ // the containing block (8.3)
// Inline blocks/tables and floats don't have their margins increased.
- marginStart = minimumValueForLength(marginStartLength, containerWidth, renderView);
- marginEnd = minimumValueForLength(marginEndLength, containerWidth, renderView);
+ marginStart = minimumValueForLength(marginStartLength, containerWidth);
+ marginEnd = minimumValueForLength(marginEndLength, containerWidth);
return;
}
@@ -2538,129 +2425,53 @@ void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, Layo
marginEndLength.setValue(0);
}
- // Case One: The object is being centered in the containing block's available logical width.
- if ((marginStartLength.isAuto() && marginEndLength.isAuto() && childWidth < containerWidth)
- || (!marginStartLength.isAuto() && !marginEndLength.isAuto() && containingBlock->style()->textAlign() == WEBKIT_CENTER)) {
+ LayoutUnit marginStartWidth = minimumValueForLength(marginStartLength, containerWidth);
+ LayoutUnit marginEndWidth = minimumValueForLength(marginEndLength, containerWidth);
+
+ LayoutUnit availableWidth = containerWidth;
+ if (avoidsFloats() && containingBlock->containsFloats()) {
+ availableWidth = containingBlockAvailableLineWidth();
+ if (shrinkToAvoidFloats() && availableWidth < containerWidth) {
+ marginStart = max<LayoutUnit>(0, marginStartWidth);
+ marginEnd = max<LayoutUnit>(0, marginEndWidth);
+ }
+ }
+
+ // CSS 2.1 (10.3.3): "If 'width' is not 'auto' and 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width'
+ // (plus any of 'margin-left' or 'margin-right' that are not 'auto') is larger than the width of the containing block, then any 'auto'
+ // values for 'margin-left' or 'margin-right' are, for the following rules, treated as zero.
+ LayoutUnit marginBoxWidth = childWidth + (!style()->width().isAuto() ? marginStartWidth + marginEndWidth : LayoutUnit());
+
+ // CSS 2.1: "If both 'margin-left' and 'margin-right' are 'auto', their used values are equal. This horizontally centers the element
+ // with respect to the edges of the containing block."
+ const RenderStyle* containingBlockStyle = containingBlock->style();
+ if ((marginStartLength.isAuto() && marginEndLength.isAuto() && marginBoxWidth < availableWidth)
+ || (!marginStartLength.isAuto() && !marginEndLength.isAuto() && containingBlockStyle->textAlign() == WEBKIT_CENTER)) {
// Other browsers center the margin box for align=center elements so we match them here.
- LayoutUnit marginStartWidth = minimumValueForLength(marginStartLength, containerWidth, renderView);
- LayoutUnit marginEndWidth = minimumValueForLength(marginEndLength, containerWidth, renderView);
- LayoutUnit centeredMarginBoxStart = max<LayoutUnit>(0, (containerWidth - childWidth - marginStartWidth - marginEndWidth) / 2);
+ LayoutUnit centeredMarginBoxStart = max<LayoutUnit>(0, (availableWidth - childWidth - marginStartWidth - marginEndWidth) / 2);
marginStart = centeredMarginBoxStart + marginStartWidth;
- marginEnd = containerWidth - childWidth - marginStart + marginEndWidth;
+ marginEnd = availableWidth - childWidth - marginStart + marginEndWidth;
return;
}
- // Case Two: The object is being pushed to the start of the containing block's available logical width.
- if (marginEndLength.isAuto() && childWidth < containerWidth) {
- marginStart = valueForLength(marginStartLength, containerWidth, renderView);
- marginEnd = containerWidth - childWidth - marginStart;
+ // CSS 2.1: "If there is exactly one value specified as 'auto', its used value follows from the equality."
+ if (marginEndLength.isAuto() && marginBoxWidth < availableWidth) {
+ marginStart = marginStartWidth;
+ marginEnd = availableWidth - childWidth - marginStart;
return;
}
- // Case Three: The object is being pushed to the end of the containing block's available logical width.
bool pushToEndFromTextAlign = !marginEndLength.isAuto() && ((!containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_LEFT)
|| (containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_RIGHT));
- if ((marginStartLength.isAuto() && childWidth < containerWidth) || pushToEndFromTextAlign) {
- marginEnd = valueForLength(marginEndLength, containerWidth, renderView);
- marginStart = containerWidth - childWidth - marginEnd;
+ if ((marginStartLength.isAuto() && marginBoxWidth < availableWidth) || pushToEndFromTextAlign) {
+ marginEnd = marginEndWidth;
+ marginStart = availableWidth - childWidth - marginEnd;
return;
}
- // Case Four: Either no auto margins, or our width is >= the container width (css2.1, 10.3.3). In that case
- // auto margins will just turn into 0.
- marginStart = minimumValueForLength(marginStartLength, containerWidth, renderView);
- marginEnd = minimumValueForLength(marginEndLength, containerWidth, renderView);
-}
-
-RenderBoxRegionInfo* RenderBox::renderBoxRegionInfo(RenderRegion* region, RenderBoxRegionInfoFlags cacheFlag) const
-{
- // Make sure nobody is trying to call this with a null region.
- if (!region)
- return 0;
-
- // If we have computed our width in this region already, it will be cached, and we can
- // just return it.
- RenderBoxRegionInfo* boxInfo = region->renderBoxRegionInfo(this);
- if (boxInfo && cacheFlag == CacheRenderBoxRegionInfo)
- return boxInfo;
-
- // No cached value was found, so we have to compute our insets in this region.
- // FIXME: For now we limit this computation to normal RenderBlocks. Future patches will expand
- // support to cover all boxes.
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (isRenderFlowThread() || !flowThread || !canHaveBoxInfoInRegion() || flowThread->style()->writingMode() != style()->writingMode())
- return 0;
-
- LogicalExtentComputedValues computedValues;
- computeLogicalWidthInRegion(computedValues, region);
-
- // Now determine the insets based off where this object is supposed to be positioned.
- RenderBlock* cb = containingBlock();
- RenderRegion* clampedContainingBlockRegion = cb->clampToStartAndEndRegions(region);
- RenderBoxRegionInfo* containingBlockInfo = cb->renderBoxRegionInfo(clampedContainingBlockRegion);
- LayoutUnit containingBlockLogicalWidth = cb->logicalWidth();
- LayoutUnit containingBlockLogicalWidthInRegion = containingBlockInfo ? containingBlockInfo->logicalWidth() : containingBlockLogicalWidth;
-
- LayoutUnit marginStartInRegion = computedValues.m_margins.m_start;
- LayoutUnit startMarginDelta = marginStartInRegion - marginStart();
- LayoutUnit logicalWidthInRegion = computedValues.m_extent;
- LayoutUnit logicalLeftInRegion = computedValues.m_position;
- LayoutUnit widthDelta = logicalWidthInRegion - logicalWidth();
- LayoutUnit logicalLeftDelta = isOutOfFlowPositioned() ? logicalLeftInRegion - logicalLeft() : startMarginDelta;
- LayoutUnit logicalRightInRegion = containingBlockLogicalWidthInRegion - (logicalLeftInRegion + logicalWidthInRegion);
- LayoutUnit oldLogicalRight = containingBlockLogicalWidth - (logicalLeft() + logicalWidth());
- LayoutUnit logicalRightDelta = isOutOfFlowPositioned() ? logicalRightInRegion - oldLogicalRight : startMarginDelta;
-
- LayoutUnit logicalLeftOffset = 0;
-
- if (!isOutOfFlowPositioned() && avoidsFloats() && cb->containsFloats()) {
- LayoutUnit startPositionDelta = cb->computeStartPositionDeltaForChildAvoidingFloats(this, marginStartInRegion, region);
- if (cb->style()->isLeftToRightDirection())
- logicalLeftDelta += startPositionDelta;
- else
- logicalRightDelta += startPositionDelta;
- }
-
- if (cb->style()->isLeftToRightDirection())
- logicalLeftOffset += logicalLeftDelta;
- else
- logicalLeftOffset -= (widthDelta + logicalRightDelta);
-
- LayoutUnit logicalRightOffset = logicalWidth() - (logicalLeftOffset + logicalWidthInRegion);
- bool isShifted = (containingBlockInfo && containingBlockInfo->isShifted())
- || (style()->isLeftToRightDirection() && logicalLeftOffset)
- || (!style()->isLeftToRightDirection() && logicalRightOffset);
-
- // FIXME: Although it's unlikely, these boxes can go outside our bounds, and so we will need to incorporate them into overflow.
- if (cacheFlag == CacheRenderBoxRegionInfo)
- return region->setRenderBoxRegionInfo(this, logicalLeftOffset, logicalWidthInRegion, isShifted);
- return new RenderBoxRegionInfo(logicalLeftOffset, logicalWidthInRegion, isShifted);
-}
-
-static bool shouldFlipBeforeAfterMargins(const RenderStyle* containingBlockStyle, const RenderStyle* childStyle)
-{
- ASSERT(containingBlockStyle->isHorizontalWritingMode() != childStyle->isHorizontalWritingMode());
- WritingMode childWritingMode = childStyle->writingMode();
- bool shouldFlip = false;
- switch (containingBlockStyle->writingMode()) {
- case TopToBottomWritingMode:
- shouldFlip = (childWritingMode == RightToLeftWritingMode);
- break;
- case BottomToTopWritingMode:
- shouldFlip = (childWritingMode == RightToLeftWritingMode);
- break;
- case RightToLeftWritingMode:
- shouldFlip = (childWritingMode == BottomToTopWritingMode);
- break;
- case LeftToRightWritingMode:
- shouldFlip = (childWritingMode == BottomToTopWritingMode);
- break;
- }
-
- if (!containingBlockStyle->isLeftToRightDirection())
- shouldFlip = !shouldFlip;
-
- return shouldFlip;
+ // Either no auto margins, or our margin box width is >= the container width, auto margins will just turn into 0.
+ marginStart = marginStartWidth;
+ marginEnd = marginEndWidth;
}
void RenderBox::updateLogicalHeight()
@@ -2690,23 +2501,20 @@ void RenderBox::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logica
computePositionedLogicalHeight(computedValues);
else {
RenderBlock* cb = containingBlock();
- bool hasPerpendicularContainingBlock = cb->isHorizontalWritingMode() != isHorizontalWritingMode();
- if (!hasPerpendicularContainingBlock) {
- bool shouldFlipBeforeAfter = cb->style()->writingMode() != style()->writingMode();
- computeBlockDirectionMargins(cb,
- shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
- shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
- }
+ // If we are perpendicular to our containing block then we need to resolve our block-start and block-end margins so that if they
+ // are 'auto' we are centred or aligned within the inline flow containing block: this is done by computing the margins as though they are inline.
+ // Note that as this is the 'sizing phase' we are using our own writing mode rather than the containing block's. We use the containing block's
+ // writing mode when figuring out the block-direction margins for positioning in |computeAndSetBlockDirectionMargins| (i.e. margin collapsing etc.).
+ // See http://www.w3.org/TR/2014/CR-css-writing-modes-3-20140320/#orthogonal-flows
+ MarginDirection flowDirection = isHorizontalWritingMode() != cb->isHorizontalWritingMode() ? InlineDirection : BlockDirection;
// For tables, calculate margins only.
if (isTable()) {
- if (hasPerpendicularContainingBlock) {
- bool shouldFlipBeforeAfter = shouldFlipBeforeAfterMargins(cb->style(), style());
- computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), computedValues.m_extent,
- shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
- shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
- }
+ // FIXME: RenderTable::layout() calls updateLogicalHeight() when an empty table has no height yet, so auto margins can come out wrong here when
+ // we are perpendicular to our containing block.
+ computeMarginsForDirection(flowDirection, cb, containingBlockLogicalWidthForContent(), computedValues.m_extent, computedValues.m_margins.m_before,
+ computedValues.m_margins.m_after, style()->marginBefore(), style()->marginAfter());
return;
}
@@ -2733,8 +2541,7 @@ void RenderBox::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logica
// Block children of horizontal flexible boxes fill the height of the box.
// FIXME: Account for block-flow in flexible boxes.
// https://bugs.webkit.org/show_bug.cgi?id=46418
- if (h.isAuto() && parent()->isDeprecatedFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL
- && parent()->isStretchingChildren()) {
+ if (h.isAuto() && inHorizontalBox && toRenderDeprecatedFlexibleBox(parent())->isStretchingChildren()) {
h = Length(parentBox()->contentLogicalHeight() - marginBefore() - marginAfter() - borderAndPaddingLogicalHeight(), Fixed);
checkMinMaxHeight = false;
}
@@ -2754,13 +2561,8 @@ void RenderBox::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logica
}
computedValues.m_extent = heightResult;
-
- if (hasPerpendicularContainingBlock) {
- bool shouldFlipBeforeAfter = shouldFlipBeforeAfterMargins(cb->style(), style());
- computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), heightResult,
- shouldFlipBeforeAfter ? computedValues.m_margins.m_after : computedValues.m_margins.m_before,
- shouldFlipBeforeAfter ? computedValues.m_margins.m_before : computedValues.m_margins.m_after);
- }
+ computeMarginsForDirection(flowDirection, cb, containingBlockLogicalWidthForContent(), computedValues.m_extent, computedValues.m_margins.m_before,
+ computedValues.m_margins.m_after, style()->marginBefore(), style()->marginAfter());
}
// WinIE quirk: The <html> block always fills the entire canvas in quirks mode. The <body> always fills the
@@ -2769,11 +2571,11 @@ void RenderBox::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logica
// height since we don't set a height in RenderView when we're printing. So without this quirk, the
// height has nothing to be a percentage of, and it ends up being 0. That is bad.
bool paginatedContentNeedsBaseHeight = document().printing() && h.isPercent()
- && (isRoot() || (isBody() && document().documentElement()->renderer()->style()->logicalHeight().isPercent())) && !isInline();
+ && (isDocumentElement() || (isBody() && document().documentElement()->renderer()->style()->logicalHeight().isPercent())) && !isInline();
if (stretchesToViewport() || paginatedContentNeedsBaseHeight) {
LayoutUnit margins = collapsedMarginBefore() + collapsedMarginAfter();
- LayoutUnit visibleHeight = viewLogicalHeightForPercentages();
- if (isRoot())
+ LayoutUnit visibleHeight = view()->viewLogicalHeightForPercentages();
+ if (isDocumentElement())
computedValues.m_extent = max(computedValues.m_extent, visibleHeight - margins);
else {
LayoutUnit marginsBordersPadding = margins + parentBox()->marginBefore() + parentBox()->marginAfter() + parentBox()->borderAndPaddingLogicalHeight();
@@ -2782,13 +2584,6 @@ void RenderBox::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logica
}
}
-LayoutUnit RenderBox::viewLogicalHeightForPercentages() const
-{
- if (document().printing())
- return static_cast<LayoutUnit>(view()->pageLogicalHeight());
- return view()->viewLogicalHeight();
-}
-
LayoutUnit RenderBox::computeLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const
{
LayoutUnit logicalHeight = computeContentAndScrollbarLogicalHeightUsing(height, intrinsicContentHeight);
@@ -2805,7 +2600,7 @@ LayoutUnit RenderBox::computeContentLogicalHeight(const Length& height, LayoutUn
return std::max<LayoutUnit>(0, adjustContentBoxLogicalHeightForBoxSizing(heightIncludingScrollbar) - scrollbarLogicalHeight());
}
-LayoutUnit RenderBox::computeIntrinsicLogicalContentHeightUsing(Length logicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPadding) const
+LayoutUnit RenderBox::computeIntrinsicLogicalContentHeightUsing(const Length& logicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPadding) const
{
// FIXME(cbiesinger): The css-sizing spec is considering changing what min-content/max-content should resolve to.
// If that happens, this code will have to change.
@@ -2835,13 +2630,16 @@ LayoutUnit RenderBox::computeContentAndScrollbarLogicalHeightUsing(const Length&
return height.value();
if (height.isPercent())
return computePercentageLogicalHeight(height);
- if (height.isViewportPercentage())
- return valueForLength(height, 0, view());
return -1;
}
bool RenderBox::skipContainingBlockForPercentHeightCalculation(const RenderBox* containingBlock) const
{
+ // Flow threads for multicol or paged overflow should be skipped. They are invisible to the DOM,
+ // and percent heights of children should be resolved against the multicol or paged container.
+ if (containingBlock->isRenderFlowThread())
+ return true;
+
// For quirks mode and anonymous blocks, we skip auto-height containingBlocks when computing percentages.
// For standards mode, we treat the percentage as auto if it has an auto-height containing block.
if (!document().inQuirksMode() && !containingBlock->isAnonymousBlock())
@@ -2858,13 +2656,13 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) const
const RenderBox* containingBlockChild = this;
LayoutUnit rootMarginBorderPaddingHeight = 0;
while (!cb->isRenderView() && skipContainingBlockForPercentHeightCalculation(cb)) {
- if (cb->isBody() || cb->isRoot())
+ if (cb->isBody() || cb->isDocumentElement())
rootMarginBorderPaddingHeight += cb->marginBefore() + cb->marginAfter() + cb->borderAndPaddingLogicalHeight();
skippedAutoHeightContainingBlock = true;
containingBlockChild = cb;
cb = cb->containingBlock();
- cb->addPercentHeightDescendant(const_cast<RenderBox*>(this));
}
+ cb->addPercentHeightDescendant(const_cast<RenderBox*>(this));
RenderStyle* cbstyle = cb->style();
@@ -2914,17 +2712,6 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) const
LayoutUnit contentBoxHeight = cb->constrainContentBoxLogicalHeightByMinMax(contentBoxHeightWithScrollbar - cb->scrollbarLogicalHeight(), -1);
availableHeight = max<LayoutUnit>(0, contentBoxHeight);
}
- } else if (cbstyle->logicalHeight().isViewportPercentage()) {
- LayoutUnit heightWithScrollbar = valueForLength(cbstyle->logicalHeight(), 0, view());
- if (heightWithScrollbar != -1) {
- LayoutUnit contentBoxHeightWithScrollbar = cb->adjustContentBoxLogicalHeightForBoxSizing(heightWithScrollbar);
- // We need to adjust for min/max height because this method does not
- // handle the min/max of the current block, its caller does. So the
- // return value from the recursive call will not have been adjusted
- // yet.
- LayoutUnit contentBoxHeight = cb->constrainContentBoxLogicalHeightByMinMax(contentBoxHeightWithScrollbar - cb->scrollbarLogicalHeight(), -1);
- availableHeight = max<LayoutUnit>(0, contentBoxHeight);
- }
} else if (isOutOfFlowPositionedWithSpecifiedHeight) {
// Don't allow this to affect the block' height() member variable, since this
// can get called while the block is still laying out its kids.
@@ -2932,7 +2719,7 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) const
cb->computeLogicalHeight(cb->logicalHeight(), 0, computedValues);
availableHeight = computedValues.m_extent - cb->borderAndPaddingLogicalHeight() - cb->scrollbarLogicalHeight();
} else if (cb->isRenderView())
- availableHeight = viewLogicalHeightForPercentages();
+ availableHeight = view()->viewLogicalHeightForPercentages();
if (availableHeight == -1)
return availableHeight;
@@ -2963,7 +2750,7 @@ LayoutUnit RenderBox::computeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUni
return max(minLogicalWidth, min(logicalWidth, maxLogicalWidth));
}
-LayoutUnit RenderBox::computeReplacedLogicalWidthUsing(Length logicalWidth) const
+LayoutUnit RenderBox::computeReplacedLogicalWidthUsing(const Length& logicalWidth) const
{
switch (logicalWidth.type()) {
case Fixed:
@@ -2974,11 +2761,6 @@ LayoutUnit RenderBox::computeReplacedLogicalWidthUsing(Length logicalWidth) cons
LayoutUnit availableLogicalWidth = 0;
return computeIntrinsicLogicalWidthUsing(logicalWidth, availableLogicalWidth, borderAndPaddingLogicalWidth()) - borderAndPaddingLogicalWidth();
}
- case ViewportPercentageWidth:
- case ViewportPercentageHeight:
- case ViewportPercentageMin:
- case ViewportPercentageMax:
- return adjustContentBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, 0, view()));
case FitContent:
case FillAvailable:
case Percent:
@@ -2994,14 +2776,17 @@ LayoutUnit RenderBox::computeReplacedLogicalWidthUsing(Length logicalWidth) cons
return computeIntrinsicLogicalWidthUsing(logicalWidth, cw, borderAndPaddingLogicalWidth()) - borderAndPaddingLogicalWidth();
if (cw > 0 || (!cw && (containerLogicalWidth.isFixed() || containerLogicalWidth.isPercent())))
return adjustContentBoxLogicalWidthForBoxSizing(minimumValueForLength(logicalWidth, cw));
+ return 0;
}
- // fall through
case Intrinsic:
case MinIntrinsic:
case Auto:
- case ExtendToZoom:
case Undefined:
return intrinsicLogicalWidth();
+ case ExtendToZoom:
+ case DeviceWidth:
+ case DeviceHeight:
+ break;
}
ASSERT_NOT_REACHED();
@@ -3020,7 +2805,7 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightRespectingMinMaxHeight(LayoutU
return max(minLogicalHeight, min(logicalHeight, maxLogicalHeight));
}
-LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) const
+LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(const Length& logicalHeight) const
{
switch (logicalHeight.type()) {
case Fixed:
@@ -3029,10 +2814,10 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) co
case Calculated:
{
RenderObject* cb = isOutOfFlowPositioned() ? container() : containingBlock();
- while (cb->isAnonymous()) {
+ while (cb->isAnonymous())
cb = cb->containingBlock();
+ if (cb->isRenderBlock())
toRenderBlock(cb)->addPercentHeightDescendant(const_cast<RenderBox*>(this));
- }
// FIXME: This calculation is not patched for block-flow yet.
// https://bugs.webkit.org/show_bug.cgi?id=46500
@@ -3072,11 +2857,6 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) co
}
return adjustContentBoxLogicalHeightForBoxSizing(valueForLength(logicalHeight, availableHeight));
}
- case ViewportPercentageWidth:
- case ViewportPercentageHeight:
- case ViewportPercentageMin:
- case ViewportPercentageMax:
- return adjustContentBoxLogicalHeightForBoxSizing(valueForLength(logicalHeight, 0, view()));
case MinContent:
case MaxContent:
case FitContent:
@@ -3135,35 +2915,20 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h, AvailableLogi
return availableHeight;
}
-void RenderBox::computeBlockDirectionMargins(const RenderBlock* containingBlock, LayoutUnit& marginBefore, LayoutUnit& marginAfter) const
-{
- if (isTableCell()) {
- // FIXME: Not right if we allow cells to have different directionality than the table. If we do allow this, though,
- // we may just do it with an extra anonymous block inside the cell.
- marginBefore = 0;
- marginAfter = 0;
- return;
- }
-
- // Margins are calculated with respect to the logical width of
- // the containing block (8.3)
- LayoutUnit cw = containingBlockLogicalWidthForContent();
- RenderView* renderView = view();
- RenderStyle* containingBlockStyle = containingBlock->style();
- marginBefore = minimumValueForLength(style()->marginBeforeUsing(containingBlockStyle), cw, renderView);
- marginAfter = minimumValueForLength(style()->marginAfterUsing(containingBlockStyle), cw, renderView);
-}
-
void RenderBox::computeAndSetBlockDirectionMargins(const RenderBlock* containingBlock)
{
LayoutUnit marginBefore;
LayoutUnit marginAfter;
- computeBlockDirectionMargins(containingBlock, marginBefore, marginAfter);
+ computeMarginsForDirection(BlockDirection, containingBlock, containingBlockLogicalWidthForContent(), logicalHeight(), marginBefore, marginAfter,
+ style()->marginBeforeUsing(containingBlock->style()),
+ style()->marginAfterUsing(containingBlock->style()));
+ // Note that in this 'positioning phase' of the layout we are using the containing block's writing mode rather than our own when calculating margins.
+ // See http://www.w3.org/TR/2014/CR-css-writing-modes-3-20140320/#orthogonal-flows
containingBlock->setMarginBeforeForChild(this, marginBefore);
containingBlock->setMarginAfterForChild(this, marginAfter);
}
-LayoutUnit RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, RenderRegion* region, bool checkForPerpendicularWritingMode) const
+LayoutUnit RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode) const
{
if (checkForPerpendicularWritingMode && containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode())
return containingBlockLogicalHeightForPositioned(containingBlock, false);
@@ -3177,30 +2942,8 @@ LayoutUnit RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxMo
}
}
- if (containingBlock->isBox()) {
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (!flowThread)
- return toRenderBox(containingBlock)->clientLogicalWidth();
-
- const RenderBlock* cb = toRenderBlock(containingBlock);
- RenderBoxRegionInfo* boxInfo = 0;
- if (!region) {
- if (containingBlock->isRenderFlowThread() && !checkForPerpendicularWritingMode)
- return toRenderFlowThread(containingBlock)->contentLogicalWidthOfFirstRegion();
- if (isWritingModeRoot()) {
- LayoutUnit cbPageOffset = cb->offsetFromLogicalTopOfFirstPage();
- RenderRegion* cbRegion = cb->regionAtBlockOffset(cbPageOffset);
- if (cbRegion) {
- cbRegion = cb->clampToStartAndEndRegions(cbRegion);
- boxInfo = cb->renderBoxRegionInfo(cbRegion);
- }
- }
- } else if (region && flowThread->isHorizontalWritingMode() == containingBlock->isHorizontalWritingMode()) {
- RenderRegion* containingBlockRegion = cb->clampToStartAndEndRegions(region);
- boxInfo = cb->renderBoxRegionInfo(containingBlockRegion);
- }
- return (boxInfo) ? max<LayoutUnit>(0, cb->clientLogicalWidth() - (cb->logicalWidth() - boxInfo->logicalWidth())) : cb->clientLogicalWidth();
- }
+ if (containingBlock->isBox())
+ return toRenderBox(containingBlock)->clientLogicalWidth();
ASSERT(containingBlock->isRenderInline() && containingBlock->isInFlowPositioned());
@@ -3228,7 +2971,7 @@ LayoutUnit RenderBox::containingBlockLogicalWidthForPositioned(const RenderBoxMo
LayoutUnit RenderBox::containingBlockLogicalHeightForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode) const
{
if (checkForPerpendicularWritingMode && containingBlock->isHorizontalWritingMode() != isHorizontalWritingMode())
- return containingBlockLogicalWidthForPositioned(containingBlock, 0, false);
+ return containingBlockLogicalWidthForPositioned(containingBlock, false);
// Use viewport as container for top-level fixed-position elements.
if (style()->position() == FixedPosition && containingBlock->isRenderView()) {
@@ -3240,12 +2983,9 @@ LayoutUnit RenderBox::containingBlockLogicalHeightForPositioned(const RenderBoxM
}
if (containingBlock->isBox()) {
- const RenderBlock* cb = toRenderBlock(containingBlock);
- LayoutUnit result = cb->clientLogicalHeight();
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (flowThread && containingBlock->isRenderFlowThread() && flowThread->isHorizontalWritingMode() == containingBlock->isHorizontalWritingMode())
- return toRenderFlowThread(containingBlock)->contentLogicalHeightOfFirstRegion();
- return result;
+ const RenderBlock* cb = containingBlock->isRenderBlock() ?
+ toRenderBlock(containingBlock) : containingBlock->containingBlock();
+ return cb->clientLogicalHeight();
}
ASSERT(containingBlock->isRenderInline() && containingBlock->isInFlowPositioned());
@@ -3268,7 +3008,7 @@ LayoutUnit RenderBox::containingBlockLogicalHeightForPositioned(const RenderBoxM
return heightResult;
}
-static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRight, const RenderBox* child, const RenderBoxModelObject* containerBlock, LayoutUnit containerLogicalWidth, RenderRegion* region)
+static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRight, const RenderBox* child, const RenderBoxModelObject* containerBlock, LayoutUnit containerLogicalWidth)
{
if (!logicalLeft.isAuto() || !logicalRight.isAuto())
return;
@@ -3281,13 +3021,6 @@ static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRigh
staticPosition += toRenderBox(curr)->logicalLeft();
if (toRenderBox(curr)->isRelPositioned())
staticPosition += toRenderBox(curr)->relativePositionOffset().width();
- if (region && curr->isRenderBlock()) {
- const RenderBlock* cb = toRenderBlock(curr);
- region = cb->clampToStartAndEndRegions(region);
- RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(region);
- if (boxInfo)
- staticPosition += boxInfo->logicalLeft();
- }
} else if (curr->isInline()) {
if (curr->isRelPositioned()) {
if (!curr->style()->logicalLeft().isAuto())
@@ -3310,17 +3043,6 @@ static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRigh
}
if (curr == enclosingBox)
staticPosition -= enclosingBox->logicalWidth();
- if (region && curr->isRenderBlock()) {
- const RenderBlock* cb = toRenderBlock(curr);
- region = cb->clampToStartAndEndRegions(region);
- RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(region);
- if (boxInfo) {
- if (curr != containerBlock)
- staticPosition -= cb->logicalWidth() - (boxInfo->logicalLeft() + boxInfo->logicalWidth());
- if (curr == enclosingBox)
- staticPosition += enclosingBox->logicalWidth() - boxInfo->logicalWidth();
- }
- }
} else if (curr->isInline()) {
if (curr->isRelPositioned()) {
if (!curr->style()->logicalLeft().isAuto())
@@ -3336,11 +3058,9 @@ static void computeInlineStaticDistance(Length& logicalLeft, Length& logicalRigh
}
}
-void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& computedValues, RenderRegion* region) const
+void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& computedValues) const
{
if (isReplaced()) {
- // FIXME: Positioned replaced elements inside a flow thread are not working properly
- // with variable width regions (see https://bugs.webkit.org/show_bug.cgi?id=69896 ).
computePositionedLogicalWidthReplaced(computedValues);
return;
}
@@ -3365,7 +3085,7 @@ void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& compu
// relative positioned inline.
const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
- const LayoutUnit containerLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, region);
+ const LayoutUnit containerLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock);
// Use the container block's direction except when calculating the static distance
// This conforms with the reference results for abspos-replaced-width-margin-000.htm
@@ -3406,7 +3126,7 @@ void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& compu
// see FIXME 1
// Calculate the static distance if needed.
- computeInlineStaticDistance(logicalLeftLength, logicalRightLength, this, containerBlock, containerLogicalWidth, region);
+ computeInlineStaticDistance(logicalLeftLength, logicalRightLength, this, containerBlock, containerLogicalWidth);
// Calculate constraint equation values for 'width' case.
computePositionedLogicalWidthUsing(style()->logicalWidth(), containerBlock, containerDirection,
@@ -3449,25 +3169,6 @@ void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& compu
}
computedValues.m_extent += bordersPlusPadding;
-
- // Adjust logicalLeft if we need to for the flipped version of our writing mode in regions.
- // FIXME: Add support for other types of objects as containerBlock, not only RenderBlock.
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (flowThread && !region && isWritingModeRoot() && isHorizontalWritingMode() == containerBlock->isHorizontalWritingMode() && containerBlock->isRenderBlock()) {
- ASSERT(containerBlock->canHaveBoxInfoInRegion());
- LayoutUnit logicalLeftPos = computedValues.m_position;
- const RenderBlock* cb = toRenderBlock(containerBlock);
- LayoutUnit cbPageOffset = cb->offsetFromLogicalTopOfFirstPage();
- RenderRegion* cbRegion = cb->regionAtBlockOffset(cbPageOffset);
- if (cbRegion) {
- cbRegion = cb->clampToStartAndEndRegions(cbRegion);
- RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(cbRegion);
- if (boxInfo) {
- logicalLeftPos += boxInfo->logicalLeft();
- computedValues.m_position = logicalLeftPos;
- }
- }
- }
}
static void computeLogicalLeftPositionedOffset(LayoutUnit& logicalLeftPos, const RenderBox* child, LayoutUnit logicalWidthValue, const RenderBoxModelObject* containerBlock, LayoutUnit containerLogicalWidth)
@@ -3477,8 +3178,9 @@ static void computeLogicalLeftPositionedOffset(LayoutUnit& logicalLeftPos, const
if (containerBlock->isHorizontalWritingMode() != child->isHorizontalWritingMode() && containerBlock->style()->isFlippedBlocksWritingMode()) {
logicalLeftPos = containerLogicalWidth - logicalWidthValue - logicalLeftPos;
logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->borderRight() : containerBlock->borderBottom());
- } else
+ } else {
logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->borderLeft() : containerBlock->borderTop());
+ }
}
void RenderBox::shrinkToFitWidth(const LayoutUnit availableSpace, const LayoutUnit logicalLeftValue, const LayoutUnit bordersPlusPadding, LogicalExtentComputedValues& computedValues) const
@@ -3492,8 +3194,8 @@ void RenderBox::shrinkToFitWidth(const LayoutUnit availableSpace, const LayoutUn
void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
LayoutUnit containerLogicalWidth, LayoutUnit bordersPlusPadding,
- Length logicalLeft, Length logicalRight, Length marginLogicalLeft, Length marginLogicalRight,
- LogicalExtentComputedValues& computedValues) const
+ const Length& logicalLeft, const Length& logicalRight, const Length& marginLogicalLeft,
+ const Length& marginLogicalRight, LogicalExtentComputedValues& computedValues) const
{
if (logicalWidth.isIntrinsic())
logicalWidth = Length(computeIntrinsicLogicalWidthUsing(logicalWidth, containerLogicalWidth, bordersPlusPadding) - bordersPlusPadding, Fixed);
@@ -3504,12 +3206,11 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
LayoutUnit logicalLeftValue = 0;
- const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, 0, false);
+ const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, false);
bool logicalWidthIsAuto = logicalWidth.isIntrinsicOrAuto();
bool logicalLeftIsAuto = logicalLeft.isAuto();
bool logicalRightIsAuto = logicalRight.isAuto();
- RenderView* renderView = view();
LayoutUnit& marginLogicalLeftValue = style()->isLeftToRightDirection() ? computedValues.m_margins.m_start : computedValues.m_margins.m_end;
LayoutUnit& marginLogicalRightValue = style()->isLeftToRightDirection() ? computedValues.m_margins.m_end : computedValues.m_margins.m_start;
if (!logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
@@ -3528,10 +3229,10 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
// NOTE: It is not necessary to solve for 'right' in the over constrained
// case because the value is not used for any further calculations.
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
- computedValues.m_extent = adjustContentBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, containerLogicalWidth, renderView));
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
+ computedValues.m_extent = adjustContentBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, containerLogicalWidth));
- const LayoutUnit availableSpace = containerLogicalWidth - (logicalLeftValue + computedValues.m_extent + valueForLength(logicalRight, containerLogicalWidth, renderView) + bordersPlusPadding);
+ const LayoutUnit availableSpace = containerLogicalWidth - (logicalLeftValue + computedValues.m_extent + valueForLength(logicalRight, containerLogicalWidth) + bordersPlusPadding);
// Margins are now the only unknown
if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
@@ -3552,16 +3253,16 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
}
} else if (marginLogicalLeft.isAuto()) {
// Solve for left margin
- marginLogicalRightValue = valueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
+ marginLogicalRightValue = valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
marginLogicalLeftValue = availableSpace - marginLogicalRightValue;
} else if (marginLogicalRight.isAuto()) {
// Solve for right margin
- marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
+ marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
marginLogicalRightValue = availableSpace - marginLogicalLeftValue;
} else {
// Over-constrained, solve for left if direction is RTL
- marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
- marginLogicalRightValue = valueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
+ marginLogicalLeftValue = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
+ marginLogicalRightValue = valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
// Use the containing block's direction rather than the parent block's
// per CSS 2.1 reference test abspos-non-replaced-width-margin-000.
@@ -3611,8 +3312,8 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- marginLogicalLeftValue = minimumValueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
- marginLogicalRightValue = minimumValueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
+ marginLogicalLeftValue = minimumValueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
+ marginLogicalRightValue = minimumValueForLength(marginLogicalRight, containerRelativeLogicalWidth);
const LayoutUnit availableSpace = containerLogicalWidth - (marginLogicalLeftValue + marginLogicalRightValue + bordersPlusPadding);
@@ -3620,7 +3321,7 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
// Use rule/case that applies.
if (logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 1: (use shrink-to-fit for width, and solve of left)
- LayoutUnit logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
+ LayoutUnit logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);
// FIXME: would it be better to have shrink-to-fit in one step?
LayoutUnit preferredWidth = maxPreferredLogicalWidth() - bordersPlusPadding;
@@ -3630,24 +3331,24 @@ void RenderBox::computePositionedLogicalWidthUsing(Length logicalWidth, const Re
logicalLeftValue = availableSpace - (computedValues.m_extent + logicalRightValue);
} else if (!logicalLeftIsAuto && logicalWidthIsAuto && logicalRightIsAuto) {
// RULE 3: (use shrink-to-fit for width, and no need solve of right)
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
shrinkToFitWidth(availableSpace, logicalLeftValue, bordersPlusPadding, computedValues);
} else if (logicalLeftIsAuto && !logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 4: (solve for left)
- computedValues.m_extent = adjustContentBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, containerLogicalWidth, renderView));
- logicalLeftValue = availableSpace - (computedValues.m_extent + valueForLength(logicalRight, containerLogicalWidth, renderView));
+ computedValues.m_extent = adjustContentBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, containerLogicalWidth));
+ logicalLeftValue = availableSpace - (computedValues.m_extent + valueForLength(logicalRight, containerLogicalWidth));
} else if (!logicalLeftIsAuto && logicalWidthIsAuto && !logicalRightIsAuto) {
// RULE 5: (solve for width)
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
if (autoWidthShouldFitContent())
shrinkToFitWidth(availableSpace, logicalLeftValue, bordersPlusPadding, computedValues);
else
- computedValues.m_extent = availableSpace - (logicalLeftValue + valueForLength(logicalRight, containerLogicalWidth, renderView));
+ computedValues.m_extent = availableSpace - (logicalLeftValue + valueForLength(logicalRight, containerLogicalWidth));
} else if (!logicalLeftIsAuto && !logicalWidthIsAuto && logicalRightIsAuto) {
// RULE 6: (no need solve for right)
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
- computedValues.m_extent = adjustContentBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, containerLogicalWidth, renderView));
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
+ computedValues.m_extent = adjustContentBoxLogicalWidthForBoxSizing(valueForLength(logicalWidth, containerLogicalWidth));
}
}
@@ -3779,25 +3480,6 @@ void RenderBox::computePositionedLogicalHeight(LogicalExtentComputedValues& comp
// Set final height value.
computedValues.m_extent += bordersPlusPadding;
-
- // Adjust logicalTop if we need to for perpendicular writing modes in regions.
- // FIXME: Add support for other types of objects as containerBlock, not only RenderBlock.
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (flowThread && isHorizontalWritingMode() != containerBlock->isHorizontalWritingMode() && containerBlock->isRenderBlock()) {
- ASSERT(containerBlock->canHaveBoxInfoInRegion());
- LayoutUnit logicalTopPos = computedValues.m_position;
- const RenderBlock* cb = toRenderBlock(containerBlock);
- LayoutUnit cbPageOffset = cb->offsetFromLogicalTopOfFirstPage() - logicalLeft();
- RenderRegion* cbRegion = cb->regionAtBlockOffset(cbPageOffset);
- if (cbRegion) {
- cbRegion = cb->clampToStartAndEndRegions(cbRegion);
- RenderBoxRegionInfo* boxInfo = cb->renderBoxRegionInfo(cbRegion);
- if (boxInfo) {
- logicalTopPos += boxInfo->logicalLeft();
- computedValues.m_position = logicalTopPos;
- }
- }
- }
}
static void computeLogicalTopPositionedOffset(LayoutUnit& logicalTopPos, const RenderBox* child, LayoutUnit logicalHeightValue, const RenderBoxModelObject* containerBlock, LayoutUnit containerLogicalHeight)
@@ -3824,8 +3506,8 @@ static void computeLogicalTopPositionedOffset(LayoutUnit& logicalTopPos, const R
void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength, const RenderBoxModelObject* containerBlock,
LayoutUnit containerLogicalHeight, LayoutUnit bordersPlusPadding, LayoutUnit logicalHeight,
- Length logicalTop, Length logicalBottom, Length marginBefore, Length marginAfter,
- LogicalExtentComputedValues& computedValues) const
+ const Length& logicalTop, const Length& logicalBottom, const Length& marginBefore,
+ const Length& marginAfter, LogicalExtentComputedValues& computedValues) const
{
// 'top' and 'bottom' cannot both be 'auto' because 'top would of been
// converted to the static position in computePositionedLogicalHeight()
@@ -3834,14 +3516,13 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
LayoutUnit logicalHeightValue;
LayoutUnit contentLogicalHeight = logicalHeight - bordersPlusPadding;
- const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, 0, false);
+ const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, false);
LayoutUnit logicalTopValue = 0;
bool logicalHeightIsAuto = logicalHeightLength.isAuto();
bool logicalTopIsAuto = logicalTop.isAuto();
bool logicalBottomIsAuto = logicalBottom.isAuto();
- RenderView* renderView = view();
LayoutUnit resolvedLogicalHeight;
// Height is never unsolved for tables.
@@ -3852,7 +3533,7 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
if (logicalHeightLength.isIntrinsic())
resolvedLogicalHeight = computeIntrinsicLogicalContentHeightUsing(logicalHeightLength, contentLogicalHeight, bordersPlusPadding);
else
- resolvedLogicalHeight = adjustContentBoxLogicalHeightForBoxSizing(valueForLength(logicalHeightLength, containerLogicalHeight, renderView));
+ resolvedLogicalHeight = adjustContentBoxLogicalHeightForBoxSizing(valueForLength(logicalHeightLength, containerLogicalHeight));
}
if (!logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) {
@@ -3868,9 +3549,9 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
// case because the value is not used for any further calculations.
logicalHeightValue = resolvedLogicalHeight;
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
- const LayoutUnit availableSpace = containerLogicalHeight - (logicalTopValue + logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight, renderView) + bordersPlusPadding);
+ const LayoutUnit availableSpace = containerLogicalHeight - (logicalTopValue + logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight) + bordersPlusPadding);
// Margins are now the only unknown
if (marginBefore.isAuto() && marginAfter.isAuto()) {
@@ -3880,16 +3561,16 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
computedValues.m_margins.m_after = availableSpace - computedValues.m_margins.m_before; // account for odd valued differences
} else if (marginBefore.isAuto()) {
// Solve for top margin
- computedValues.m_margins.m_after = valueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
+ computedValues.m_margins.m_after = valueForLength(marginAfter, containerRelativeLogicalWidth);
computedValues.m_margins.m_before = availableSpace - computedValues.m_margins.m_after;
} else if (marginAfter.isAuto()) {
// Solve for bottom margin
- computedValues.m_margins.m_before = valueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
+ computedValues.m_margins.m_before = valueForLength(marginBefore, containerRelativeLogicalWidth);
computedValues.m_margins.m_after = availableSpace - computedValues.m_margins.m_before;
} else {
// Over-constrained, (no need solve for bottom)
- computedValues.m_margins.m_before = valueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
- computedValues.m_margins.m_after = valueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
+ computedValues.m_margins.m_before = valueForLength(marginBefore, containerRelativeLogicalWidth);
+ computedValues.m_margins.m_after = valueForLength(marginAfter, containerRelativeLogicalWidth);
}
} else {
/*--------------------------------------------------------------------*\
@@ -3918,8 +3599,8 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
// because the value is not used for any further calculations.
// Calculate margins, 'auto' margins are ignored.
- computedValues.m_margins.m_before = minimumValueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
- computedValues.m_margins.m_after = minimumValueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
+ computedValues.m_margins.m_before = minimumValueForLength(marginBefore, containerRelativeLogicalWidth);
+ computedValues.m_margins.m_after = minimumValueForLength(marginAfter, containerRelativeLogicalWidth);
const LayoutUnit availableSpace = containerLogicalHeight - (computedValues.m_margins.m_before + computedValues.m_margins.m_after + bordersPlusPadding);
@@ -3927,23 +3608,23 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
if (logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 1: (height is content based, solve of top)
logicalHeightValue = contentLogicalHeight;
- logicalTopValue = availableSpace - (logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight, renderView));
+ logicalTopValue = availableSpace - (logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight));
} else if (!logicalTopIsAuto && logicalHeightIsAuto && logicalBottomIsAuto) {
// RULE 3: (height is content based, no need solve of bottom)
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
logicalHeightValue = contentLogicalHeight;
} else if (logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 4: (solve of top)
logicalHeightValue = resolvedLogicalHeight;
- logicalTopValue = availableSpace - (logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight, renderView));
+ logicalTopValue = availableSpace - (logicalHeightValue + valueForLength(logicalBottom, containerLogicalHeight));
} else if (!logicalTopIsAuto && logicalHeightIsAuto && !logicalBottomIsAuto) {
// RULE 5: (solve of height)
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
- logicalHeightValue = max<LayoutUnit>(0, availableSpace - (logicalTopValue + valueForLength(logicalBottom, containerLogicalHeight, renderView)));
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
+ logicalHeightValue = max<LayoutUnit>(0, availableSpace - (logicalTopValue + valueForLength(logicalBottom, containerLogicalHeight)));
} else if (!logicalTopIsAuto && !logicalHeightIsAuto && logicalBottomIsAuto) {
// RULE 6: (no need solve of bottom)
logicalHeightValue = resolvedLogicalHeight;
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
}
}
computedValues.m_extent = logicalHeightValue;
@@ -3966,7 +3647,7 @@ void RenderBox::computePositionedLogicalWidthReplaced(LogicalExtentComputedValue
const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const LayoutUnit containerLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock);
- const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, 0, false);
+ const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, false);
// To match WinIE, in quirks mode use the parent's 'direction' property
// instead of the the container block's.
@@ -3998,7 +3679,7 @@ void RenderBox::computePositionedLogicalWidthReplaced(LogicalExtentComputedValue
* else if 'direction' is 'rtl', set 'right' to the static position.
\*-----------------------------------------------------------------------*/
// see FIXME 1
- computeInlineStaticDistance(logicalLeft, logicalRight, this, containerBlock, containerLogicalWidth, 0); // FIXME: Pass the region.
+ computeInlineStaticDistance(logicalLeft, logicalRight, this, containerBlock, containerLogicalWidth);
/*-----------------------------------------------------------------------*\
* 3. If 'left' or 'right' are 'auto', replace any 'auto' on 'margin-left'
@@ -4021,14 +3702,13 @@ void RenderBox::computePositionedLogicalWidthReplaced(LogicalExtentComputedValue
\*-----------------------------------------------------------------------*/
LayoutUnit logicalLeftValue = 0;
LayoutUnit logicalRightValue = 0;
- RenderView* renderView = view();
if (marginLogicalLeft.isAuto() && marginLogicalRight.isAuto()) {
// 'left' and 'right' cannot be 'auto' due to step 3
ASSERT(!(logicalLeft.isAuto() && logicalRight.isAuto()));
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
- logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);
LayoutUnit difference = availableSpace - (logicalLeftValue + logicalRightValue);
if (difference > 0) {
@@ -4051,39 +3731,39 @@ void RenderBox::computePositionedLogicalWidthReplaced(LogicalExtentComputedValue
* that value.
\*-----------------------------------------------------------------------*/
} else if (logicalLeft.isAuto()) {
- marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
- marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
- logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
+ marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
+ marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);
// Solve for 'left'
logicalLeftValue = availableSpace - (logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias);
} else if (logicalRight.isAuto()) {
- marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
- marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
+ marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
// Solve for 'right'
logicalRightValue = availableSpace - (logicalLeftValue + marginLogicalLeftAlias + marginLogicalRightAlias);
} else if (marginLogicalLeft.isAuto()) {
- marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
- logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
+ marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);
// Solve for 'margin-left'
marginLogicalLeftAlias = availableSpace - (logicalLeftValue + logicalRightValue + marginLogicalRightAlias);
} else if (marginLogicalRight.isAuto()) {
- marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
- logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
+ marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);
// Solve for 'margin-right'
marginLogicalRightAlias = availableSpace - (logicalLeftValue + logicalRightValue + marginLogicalLeftAlias);
} else {
// Nothing is 'auto', just calculate the values.
- marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth, renderView);
- marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRelativeLogicalWidth, renderView);
- logicalRightValue = valueForLength(logicalRight, containerLogicalWidth, renderView);
- logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth, renderView);
+ marginLogicalLeftAlias = valueForLength(marginLogicalLeft, containerRelativeLogicalWidth);
+ marginLogicalRightAlias = valueForLength(marginLogicalRight, containerRelativeLogicalWidth);
+ logicalRightValue = valueForLength(logicalRight, containerLogicalWidth);
+ logicalLeftValue = valueForLength(logicalLeft, containerLogicalWidth);
// If the containing block is right-to-left, then push the left position as far to the right as possible
if (containerDirection == RTL) {
int totalLogicalWidth = computedValues.m_extent + logicalLeftValue + logicalRightValue + marginLogicalLeftAlias + marginLogicalRightAlias;
@@ -4135,7 +3815,7 @@ void RenderBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValu
const RenderBoxModelObject* containerBlock = toRenderBoxModelObject(container());
const LayoutUnit containerLogicalHeight = containingBlockLogicalHeightForPositioned(containerBlock);
- const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, 0, false);
+ const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, false);
// Variables to solve.
Length marginBefore = style()->marginBefore();
@@ -4145,7 +3825,6 @@ void RenderBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValu
Length logicalTop = style()->logicalTop();
Length logicalBottom = style()->logicalBottom();
- RenderView* renderView = view();
/*-----------------------------------------------------------------------*\
* 1. The used value of 'height' is determined as for inline replaced
@@ -4189,8 +3868,8 @@ void RenderBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValu
// 'top' and 'bottom' cannot be 'auto' due to step 2 and 3 combined.
ASSERT(!(logicalTop.isAuto() || logicalBottom.isAuto()));
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
- logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight, renderView);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
+ logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight);
LayoutUnit difference = availableSpace - (logicalTopValue + logicalBottomValue);
// NOTE: This may result in negative values.
@@ -4202,39 +3881,39 @@ void RenderBox::computePositionedLogicalHeightReplaced(LogicalExtentComputedValu
* for that value.
\*-----------------------------------------------------------------------*/
} else if (logicalTop.isAuto()) {
- marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
- marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
- logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight, renderView);
+ marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogicalWidth);
+ marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalWidth);
+ logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight);
// Solve for 'top'
logicalTopValue = availableSpace - (logicalBottomValue + marginBeforeAlias + marginAfterAlias);
} else if (logicalBottom.isAuto()) {
- marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
- marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogicalWidth);
+ marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalWidth);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
// Solve for 'bottom'
// NOTE: It is not necessary to solve for 'bottom' because we don't ever
// use the value.
} else if (marginBefore.isAuto()) {
- marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
- logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight, renderView);
+ marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalWidth);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
+ logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight);
// Solve for 'margin-top'
marginBeforeAlias = availableSpace - (logicalTopValue + logicalBottomValue + marginAfterAlias);
} else if (marginAfter.isAuto()) {
- marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
- logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight, renderView);
+ marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogicalWidth);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
+ logicalBottomValue = valueForLength(logicalBottom, containerLogicalHeight);
// Solve for 'margin-bottom'
marginAfterAlias = availableSpace - (logicalTopValue + logicalBottomValue + marginBeforeAlias);
} else {
// Nothing is 'auto', just calculate the values.
- marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogicalWidth, renderView);
- marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalWidth, renderView);
- logicalTopValue = valueForLength(logicalTop, containerLogicalHeight, renderView);
+ marginBeforeAlias = valueForLength(marginBefore, containerRelativeLogicalWidth);
+ marginAfterAlias = valueForLength(marginAfter, containerRelativeLogicalWidth);
+ logicalTopValue = valueForLength(logicalTop, containerLogicalHeight);
// NOTE: It is not necessary to solve for 'bottom' because we don't ever
// use the value.
}
@@ -4267,10 +3946,10 @@ LayoutRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit
rect.move(LayoutSize(width() - caretWidth, 0));
if (box) {
- RootInlineBox* rootBox = box->root();
- LayoutUnit top = rootBox->lineTop();
+ RootInlineBox& rootBox = box->root();
+ LayoutUnit top = rootBox.lineTop();
rect.setY(top);
- rect.setHeight(rootBox->lineBottom() - top);
+ rect.setHeight(rootBox.lineBottom() - top);
}
// If height of box is smaller than font height, use the latter one,
@@ -4308,7 +3987,8 @@ LayoutRect RenderBox::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit
PositionWithAffinity RenderBox::positionForPoint(const LayoutPoint& point)
{
// no children...return this render object's element, if there is one, and offset 0
- if (!firstChild())
+ RenderObject* firstChild = slowFirstChild();
+ if (!firstChild)
return createPositionWithAffinity(nonPseudoNode() ? firstPositionInOrBeforeNode(nonPseudoNode()) : Position());
if (isTable() && nonPseudoNode()) {
@@ -4329,8 +4009,8 @@ PositionWithAffinity RenderBox::positionForPoint(const LayoutPoint& point)
if (isTableRow())
adjustedPoint.moveBy(location());
- for (RenderObject* renderObject = firstChild(); renderObject; renderObject = renderObject->nextSibling()) {
- if ((!renderObject->firstChild() && !renderObject->isInline() && !renderObject->isRenderBlockFlow() )
+ for (RenderObject* renderObject = firstChild; renderObject; renderObject = renderObject->nextSibling()) {
+ if ((!renderObject->slowFirstChild() && !renderObject->isInline() && !renderObject->isRenderBlockFlow() )
|| renderObject->style()->visibility() != VISIBLE)
continue;
@@ -4403,9 +4083,18 @@ bool RenderBox::avoidsFloats() const
return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isFlexItemIncludingDeprecated();
}
+void RenderBox::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutScope)
+{
+ ASSERT(!needsLayout());
+ // If fragmentation height has changed, we need to lay out. No need to enter the renderer if it
+ // is childless, though.
+ if (view()->layoutState()->pageLogicalHeightChanged() && slowFirstChild())
+ layoutScope.setChildNeedsLayout(this);
+}
+
void RenderBox::addVisualEffectOverflow()
{
- if (!style()->boxShadow() && !style()->hasBorderImageOutsets())
+ if (!style()->boxShadow() && !style()->hasBorderImageOutsets() && !style()->hasOutline())
return;
bool isFlipped = style()->isFlippedBlocksWritingMode();
@@ -4444,7 +4133,16 @@ void RenderBox::addVisualEffectOverflow()
overflowMaxY = max(overflowMaxY, borderBox.maxY() + ((!isFlipped || !isHorizontal) ? borderOutsets.bottom() : borderOutsets.top()));
}
- // Add in the final overflow with shadows and outsets combined.
+ if (style()->hasOutline()) {
+ LayoutUnit outlineSize = style()->outlineSize();
+
+ overflowMinX = min(overflowMinX, borderBox.x() - outlineSize);
+ overflowMaxX = max(overflowMaxX, borderBox.maxX() + outlineSize);
+ overflowMinY = min(overflowMinY, borderBox.y() - outlineSize);
+ overflowMaxY = max(overflowMaxY, borderBox.maxY() + outlineSize);
+ }
+
+ // Add in the final overflow with shadows, outsets and outline combined.
LayoutRect visualEffectOverflow(overflowMinX, overflowMinY, overflowMaxX - overflowMinX, overflowMaxY - overflowMinY);
addVisualOverflow(visualEffectOverflow);
}
@@ -4494,13 +4192,6 @@ void RenderBox::addLayoutOverflow(const LayoutRect& rect)
hasTopOverflow = true;
}
- if (hasColumns() && style()->columnProgression() == ReverseColumnProgression) {
- if (isHorizontalWritingMode() ^ !style()->hasInlineColumnAxis())
- hasLeftOverflow = !hasLeftOverflow;
- else
- hasTopOverflow = !hasTopOverflow;
- }
-
if (!hasTopOverflow)
overflowRect.shiftYEdgeTo(max(overflowRect.y(), clientBox.y()));
else
@@ -4542,7 +4233,7 @@ void RenderBox::addContentsVisualOverflow(const LayoutRect& rect)
}
if (!m_overflow)
- m_overflow = adoptPtr(new RenderOverflow(clientBoxRect(), borderBoxRect()));
+ m_overflow = adoptPtr(new RenderOverflow(noOverflowRect(), borderBoxRect()));
m_overflow->addContentsVisualOverflow(rect);
}
@@ -4599,7 +4290,7 @@ bool RenderBox::percentageLogicalHeightIsResolvableFromBlock(const RenderBlock*
return percentageLogicalHeightIsResolvableFromBlock(cb->containingBlock(), cb->isOutOfFlowPositioned());
if (cb->isRenderView() || inQuirksMode || isOutOfFlowPositionedWithSpecifiedHeight)
return true;
- if (cb->isRoot() && isOutOfFlowPositioned) {
+ if (cb->isDocumentElement() && isOutOfFlowPositioned) {
// Match the positioned objects behavior, which is that positioned objects will fill their viewport
// always. Note we could only hit this case by recurring into computePercentageLogicalHeight on a positioned containing block.
return true;
@@ -4742,14 +4433,16 @@ LayoutRect RenderBox::layoutOverflowRectForPropagation(RenderStyle* parentStyle)
LayoutRect RenderBox::noOverflowRect() const
{
- // Because of the special coodinate system used for overflow rectangles and many other
+ // Because of the special coordinate system used for overflow rectangles and many other
// rectangles (not quite logical, not quite physical), we need to flip the block progression
// coordinate in vertical-rl and horizontal-bt writing modes. In other words, the rectangle
// returned is physical, except for the block direction progression coordinate (y in horizontal
// writing modes, x in vertical writing modes), which is always "logical top". Apart from the
// flipping, this method does the same as clientBoxRect().
- LayoutUnit left = borderLeft() + (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? verticalScrollbarWidth() : 0);
+ const int scrollBarWidth = verticalScrollbarWidth();
+ const int scrollBarHeight = horizontalScrollbarHeight();
+ LayoutUnit left = borderLeft() + (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? scrollBarWidth : 0);
LayoutUnit top = borderTop();
LayoutUnit right = borderRight();
LayoutUnit bottom = borderBottom();
@@ -4765,9 +4458,9 @@ LayoutRect RenderBox::noOverflowRect() const
// clientBoxRect() or paddingBoxRect() in this method, rather than fiddling with the edges on
// our own.
if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- rect.contract(0, horizontalScrollbarHeight());
+ rect.contract(0, scrollBarHeight);
else
- rect.contract(verticalScrollbarWidth(), horizontalScrollbarHeight());
+ rect.contract(scrollBarWidth, scrollBarHeight);
return rect;
}
@@ -4880,22 +4573,11 @@ LayoutSize RenderBox::topLeftLocationOffset() const
return LayoutSize(rect.x(), rect.y());
}
-bool RenderBox::hasRelativeDimensions() const
-{
- // FIXME: This should probably include viewport percentage heights as well.
- return style()->height().isPercent() || style()->width().isPercent()
- || style()->maxHeight().isPercent() || style()->maxWidth().isPercent()
- || style()->minHeight().isPercent() || style()->minWidth().isPercent();
-}
-
bool RenderBox::hasRelativeLogicalHeight() const
{
return style()->logicalHeight().isPercent()
|| style()->logicalMinHeight().isPercent()
- || style()->logicalMaxHeight().isPercent()
- || style()->logicalHeight().isViewportPercentage()
- || style()->logicalMinHeight().isViewportPercentage()
- || style()->logicalMaxHeight().isViewportPercentage();
+ || style()->logicalMaxHeight().isPercent();
}
static void markBoxForRelayoutAfterSplit(RenderBox* box)
@@ -4909,7 +4591,7 @@ static void markBoxForRelayoutAfterSplit(RenderBox* box)
} else if (box->isTableSection())
toRenderTableSection(box)->setNeedsCellRecalc();
- box->setNeedsLayoutAndPrefWidthsRecalc();
+ box->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
RenderObject* RenderBox::splitAnonymousBoxesAroundChild(RenderObject* beforeChild)
@@ -4918,7 +4600,7 @@ RenderObject* RenderBox::splitAnonymousBoxesAroundChild(RenderObject* beforeChil
while (beforeChild->parent() != this) {
RenderBox* boxToSplit = toRenderBox(beforeChild->parent());
- if (boxToSplit->firstChild() != beforeChild && boxToSplit->isAnonymous()) {
+ if (boxToSplit->slowFirstChild() != beforeChild && boxToSplit->isAnonymous()) {
didSplitParentAnonymousBoxes = true;
// We have to split the parent box into two boxes and move children
@@ -4928,7 +4610,7 @@ RenderObject* RenderBox::splitAnonymousBoxesAroundChild(RenderObject* beforeChil
RenderBox* parentBox = toRenderBox(boxToSplit->parent());
// We need to invalidate the |parentBox| before inserting the new node
// so that the table repainting logic knows the structure is dirty.
- // See for example RenderTableCell:clippedOverflowRectForRepaint.
+ // See for example RenderTableCell:clippedOverflowRectForPaintInvalidation.
markBoxForRelayoutAfterSplit(parentBox);
parentBox->virtualChildren()->insertChildNode(parentBox, postBox, boxToSplit->nextSibling());
boxToSplit->moveChildrenTo(postBox, beforeChild, 0, true);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBox.h b/chromium/third_party/WebKit/Source/core/rendering/RenderBox.h
index 350b640d75c..c9d967df7a5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBox.h
@@ -23,6 +23,7 @@
#ifndef RenderBox_h
#define RenderBox_h
+#include "core/animation/ActiveAnimations.h"
#include "core/rendering/RenderBoxModelObject.h"
#include "core/rendering/RenderOverflow.h"
#include "core/rendering/shapes/ShapeOutsideInfo.h"
@@ -30,13 +31,12 @@
namespace WebCore {
-class RenderBoxRegionInfo;
-class RenderRegion;
struct PaintInfo;
enum SizeType { MainOrPreferredSize, MinSize, MaxSize };
enum AvailableLogicalHeightType { ExcludeMarginBorderPadding, IncludeMarginBorderPadding };
enum OverlayScrollbarSizeRelevancy { IgnoreOverlayScrollbarSize, IncludeOverlayScrollbarSize };
+enum MarginDirection { BlockDirection, InlineDirection };
enum ShouldComputePreferred { ComputeActual, ComputePreferred };
@@ -47,14 +47,39 @@ enum ScrollOffsetClamping {
ScrollOffsetClamped
};
+struct RenderBoxRareData {
+ WTF_MAKE_NONCOPYABLE(RenderBoxRareData); WTF_MAKE_FAST_ALLOCATED;
+public:
+ RenderBoxRareData()
+ : m_inlineBoxWrapper(0)
+ , m_overrideLogicalContentHeight(-1)
+ , m_overrideLogicalContentWidth(-1)
+ {
+ }
+
+ // For inline replaced elements, the inline box that owns us.
+ InlineBox* m_inlineBoxWrapper;
+
+ LayoutUnit m_overrideLogicalContentHeight;
+ LayoutUnit m_overrideLogicalContentWidth;
+};
+
+
class RenderBox : public RenderBoxModelObject {
public:
explicit RenderBox(ContainerNode*);
- virtual ~RenderBox();
// hasAutoZIndex only returns true if the element is positioned or a flex-item since
// position:static elements that are not flex-items get their z-index coerced to auto.
- virtual bool requiresLayer() const OVERRIDE { return isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasOverflowClip() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns() || !style()->hasAutoZIndex(); }
+ virtual LayerType layerTypeRequired() const OVERRIDE
+ {
+ if (isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns() || !style()->hasAutoZIndex() || style()->shouldCompositeForCurrentAnimations())
+ return NormalLayer;
+ if (hasOverflowClip())
+ return OverflowClipLayer;
+
+ return NoLayer;
+ }
virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const OVERRIDE;
@@ -87,7 +112,7 @@ public:
LayoutUnit logicalWidth() const { return style()->isHorizontalWritingMode() ? width() : height(); }
LayoutUnit logicalHeight() const { return style()->isHorizontalWritingMode() ? height() : width(); }
- LayoutUnit constrainLogicalWidthInRegionByMinMax(LayoutUnit, LayoutUnit, RenderBlock*, RenderRegion* = 0) const;
+ LayoutUnit constrainLogicalWidthByMinMax(LayoutUnit, LayoutUnit, RenderBlock*) const;
LayoutUnit constrainLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const;
LayoutUnit constrainContentBoxLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const;
@@ -167,8 +192,6 @@ public:
// does include the intrinsic padding in the content box as this is what some callers expect (like getComputedStyle).
LayoutRect computedCSSContentBoxRect() const { return LayoutRect(borderLeft() + computedCSSPaddingLeft(), borderTop() + computedCSSPaddingTop(), clientWidth() - computedCSSPaddingLeft() - computedCSSPaddingRight(), clientHeight() - computedCSSPaddingTop() - computedCSSPaddingBottom()); }
- // Bounds of the outline box in absolute coords. Respects transforms
- virtual LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* /*repaintContainer*/, const RenderGeometryMap*) const OVERRIDE FINAL;
virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
// Use this with caution! No type checking is done!
@@ -207,8 +230,9 @@ public:
void addOverflowFromChild(RenderBox* child) { addOverflowFromChild(child, child->locationOffset()); }
void addOverflowFromChild(RenderBox* child, const LayoutSize& delta);
void clearLayoutOverflow();
+ void clearAllOverflows() { m_overflow.clear(); }
- void updateLayerTransform();
+ void updateLayerTransformAfterLayout();
LayoutUnit contentWidth() const { return clientWidth() - paddingLeft() - paddingRight(); }
LayoutUnit contentHeight() const { return clientHeight() - paddingTop() - paddingBottom(); }
@@ -217,18 +241,15 @@ public:
// IE extensions. Used to calculate offsetWidth/Height. Overridden by inlines (RenderFlow)
// to return the remaining width on a given line (and the height of a single line).
- virtual LayoutUnit offsetWidth() const { return width(); }
- virtual LayoutUnit offsetHeight() const { return height(); }
+ virtual LayoutUnit offsetWidth() const OVERRIDE { return width(); }
+ virtual LayoutUnit offsetHeight() const OVERRIDE { return height(); }
virtual int pixelSnappedOffsetWidth() const OVERRIDE FINAL;
virtual int pixelSnappedOffsetHeight() const OVERRIDE FINAL;
- bool canDetermineWidthWithoutLayout() const;
- LayoutUnit fixedOffsetWidth() const;
-
// More IE extensions. clientWidth and clientHeight represent the interior of an object
// excluding border and scrollbar. clientLeft/Top are just the borderLeftWidth and borderTopWidth.
- LayoutUnit clientLeft() const { return borderLeft(); }
+ LayoutUnit clientLeft() const { return borderLeft() + (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? verticalScrollbarWidth() : 0); }
LayoutUnit clientTop() const { return borderTop(); }
LayoutUnit clientWidth() const;
LayoutUnit clientHeight() const;
@@ -245,12 +266,14 @@ public:
// scrollLeft/Top return the current scroll position. These methods are virtual so that objects like
// textareas can scroll shadow content (but pretend that they are the objects that are
// scrolling).
- virtual int scrollLeft() const;
- virtual int scrollTop() const;
- virtual int scrollWidth() const;
- virtual int scrollHeight() const;
- virtual void setScrollLeft(int);
- virtual void setScrollTop(int);
+ virtual LayoutUnit scrollLeft() const;
+ virtual LayoutUnit scrollTop() const;
+ virtual LayoutUnit scrollWidth() const;
+ virtual LayoutUnit scrollHeight() const;
+ int pixelSnappedScrollWidth() const;
+ int pixelSnappedScrollHeight() const;
+ virtual void setScrollLeft(LayoutUnit);
+ virtual void setScrollTop(LayoutUnit);
void scrollToOffset(const IntSize&);
void scrollByRecursively(const IntSize& delta, ScrollOffsetClamping = ScrollOffsetUnclamped);
@@ -304,20 +327,19 @@ public:
virtual LayoutUnit collapsedMarginBefore() const { return marginBefore(); }
virtual LayoutUnit collapsedMarginAfter() const { return marginAfter(); }
- virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
- virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
+ virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE;
+ virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE;
- LayoutRect reflectionBox() const;
int reflectionOffset() const;
// Given a rect in the object's coordinate space, returns the corresponding rect in the reflection.
LayoutRect reflectedRect(const LayoutRect&) const;
- virtual void layout();
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void layout() OVERRIDE;
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
- virtual LayoutUnit minPreferredLogicalWidth() const;
- virtual LayoutUnit maxPreferredLogicalWidth() const;
+ virtual LayoutUnit minPreferredLogicalWidth() const OVERRIDE;
+ virtual LayoutUnit maxPreferredLogicalWidth() const OVERRIDE;
// FIXME: We should rename these back to overrideLogicalHeight/Width and have them store
// the border-box height/width like the regular height/width accessors on RenderBox.
@@ -342,7 +364,7 @@ public:
void clearContainingBlockOverrideSize();
void clearOverrideContainingBlockContentLogicalHeight();
- virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
+ virtual LayoutSize offsetFromContainer(const RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const OVERRIDE;
LayoutUnit adjustBorderBoxLogicalWidthForBoxSizing(LayoutUnit width) const;
LayoutUnit adjustBorderBoxLogicalHeightForBoxSizing(LayoutUnit height) const;
@@ -364,17 +386,13 @@ public:
LayoutUnit m_position;
ComputedMarginValues m_margins;
};
- // Resolve auto margins in the inline direction of the containing block so that objects can be pushed to the start, middle or end
+ // Resolve auto margins in the chosen direction of the containing block so that objects can be pushed to the start, middle or end
// of the containing block.
- void computeInlineDirectionMargins(RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd) const;
+ void computeMarginsForDirection(MarginDirection forDirection, const RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd, Length marginStartLength, Length marginStartEnd) const;
// Used to resolve margins in the containing block's block-flow direction.
- void computeBlockDirectionMargins(const RenderBlock* containingBlock, LayoutUnit& marginBefore, LayoutUnit& marginAfter) const;
void computeAndSetBlockDirectionMargins(const RenderBlock* containingBlock);
- enum RenderBoxRegionInfoFlags { CacheRenderBoxRegionInfo, DoNotCacheRenderBoxRegionInfo };
- LayoutRect borderBoxRectInRegion(RenderRegion*, RenderBoxRegionInfoFlags = CacheRenderBoxRegionInfo) const;
- void clearRenderBoxRegionInfo();
virtual LayoutUnit offsetFromLogicalTopOfFirstPage() const;
void positionLineBox(InlineBox*);
@@ -385,51 +403,50 @@ public:
// For inline replaced elements, this function returns the inline box that owns us. Enables
// the replaced RenderObject to quickly determine what line it is contained on and to easily
// iterate over structures on the line.
- InlineBox* inlineBoxWrapper() const { return m_inlineBoxWrapper; }
+ InlineBox* inlineBoxWrapper() const { return m_rareData ? m_rareData->m_inlineBoxWrapper : 0; }
void setInlineBoxWrapper(InlineBox*);
void deleteLineBoxWrapper();
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE;
+ virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
void repaintDuringLayoutIfMoved(const LayoutRect&);
virtual void repaintOverhangingFloats(bool paintAllDescendants);
- virtual LayoutUnit containingBlockLogicalWidthForContent() const;
+ virtual LayoutUnit containingBlockLogicalWidthForContent() const OVERRIDE;
LayoutUnit containingBlockLogicalHeightForContent(AvailableLogicalHeightType) const;
- LayoutUnit containingBlockLogicalWidthForContentInRegion(RenderRegion*) const;
- LayoutUnit containingBlockAvailableLineWidthInRegion(RenderRegion*) const;
+ LayoutUnit containingBlockAvailableLineWidth() const;
LayoutUnit perpendicularContainingBlockLogicalHeight() const;
virtual void updateLogicalWidth();
virtual void updateLogicalHeight();
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const;
- RenderBoxRegionInfo* renderBoxRegionInfo(RenderRegion*, RenderBoxRegionInfoFlags = CacheRenderBoxRegionInfo) const;
- void computeLogicalWidthInRegion(LogicalExtentComputedValues&, RenderRegion* = 0) const;
+ void computeLogicalWidth(LogicalExtentComputedValues&) const;
bool stretchesToViewport() const
{
- return document().inQuirksMode() && style()->logicalHeight().isAuto() && !isFloatingOrOutOfFlowPositioned() && (isRoot() || isBody()) && !document().shouldDisplaySeamlesslyWithParent() && !isInline();
+ return document().inQuirksMode() && style()->logicalHeight().isAuto() && !isFloatingOrOutOfFlowPositioned() && (isDocumentElement() || isBody()) && !isInline();
}
virtual LayoutSize intrinsicSize() const { return LayoutSize(); }
LayoutUnit intrinsicLogicalWidth() const { return style()->isHorizontalWritingMode() ? intrinsicSize().width() : intrinsicSize().height(); }
LayoutUnit intrinsicLogicalHeight() const { return style()->isHorizontalWritingMode() ? intrinsicSize().height() : intrinsicSize().width(); }
+ virtual LayoutUnit intrinsicContentLogicalHeight() const { return m_intrinsicContentLogicalHeight; }
// Whether or not the element shrinks to its intrinsic width (rather than filling the width
// of a containing block). HTML4 buttons, <select>s, <input>s, legends, and floating/compact elements do this.
- bool sizesLogicalWidthToFitContent(SizeType) const;
+ bool sizesLogicalWidthToFitContent(const Length& logicalWidth) const;
- LayoutUnit shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlockFlow* cb, RenderRegion*) const;
+ LayoutUnit shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlockFlow* cb) const;
- LayoutUnit computeLogicalWidthInRegionUsing(SizeType, Length logicalWidth, LayoutUnit availableLogicalWidth, const RenderBlock* containingBlock, RenderRegion*) const;
+ LayoutUnit computeLogicalWidthUsing(SizeType, const Length& logicalWidth, LayoutUnit availableLogicalWidth, const RenderBlock* containingBlock) const;
LayoutUnit computeLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const;
LayoutUnit computeContentLogicalHeight(const Length& height, LayoutUnit intrinsicContentHeight) const;
LayoutUnit computeContentAndScrollbarLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const;
- LayoutUnit computeReplacedLogicalWidthUsing(Length width) const;
+ LayoutUnit computeReplacedLogicalWidthUsing(const Length& width) const;
LayoutUnit computeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUnit logicalWidth, ShouldComputePreferred = ComputeActual) const;
- LayoutUnit computeReplacedLogicalHeightUsing(Length height) const;
+ LayoutUnit computeReplacedLogicalHeightUsing(const Length& height) const;
LayoutUnit computeReplacedLogicalHeightRespectingMinMaxHeight(LayoutUnit logicalHeight) const;
virtual LayoutUnit computeReplacedLogicalWidth(ShouldComputePreferred = ComputeActual) const;
@@ -452,7 +469,7 @@ public:
int horizontalScrollbarHeight() const;
int instrinsicScrollbarLogicalWidth() const;
int scrollbarLogicalHeight() const { return style()->isHorizontalWritingMode() ? horizontalScrollbarHeight() : verticalScrollbarWidth(); }
- virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1);
+ virtual bool scroll(ScrollDirection, ScrollGranularity, float delta = 1);
bool canBeScrolledAndHasScrollableArea() const;
virtual bool canBeProgramaticallyScrolled() const;
virtual void autoscroll(const IntPoint&);
@@ -467,8 +484,8 @@ public:
bool hasAutoHorizontalScrollbar() const { return hasOverflowClip() && (style()->overflowX() == OAUTO || style()->overflowX() == OOVERLAY); }
bool scrollsOverflow() const { return scrollsOverflowX() || scrollsOverflowY(); }
- bool hasScrollableOverflowX() const { return scrollsOverflowX() && scrollWidth() != clientWidth(); }
- bool hasScrollableOverflowY() const { return scrollsOverflowY() && scrollHeight() != clientHeight(); }
+ bool hasScrollableOverflowX() const { return scrollsOverflowX() && pixelSnappedScrollWidth() != pixelSnappedClientWidth(); }
+ bool hasScrollableOverflowY() const { return scrollsOverflowY() && pixelSnappedScrollHeight() != pixelSnappedClientHeight(); }
virtual bool scrollsOverflowX() const { return hasOverflowClip() && (style()->overflowX() == OSCROLL || hasAutoHorizontalScrollbar()); }
virtual bool scrollsOverflowY() const { return hasOverflowClip() && (style()->overflowY() == OSCROLL || hasAutoVerticalScrollbar()); }
bool usesCompositedScrolling() const;
@@ -480,10 +497,10 @@ public:
bool hasUnsplittableScrollingOverflow() const;
bool isUnsplittableForPagination() const;
- virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0);
+ virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) OVERRIDE;
- virtual LayoutRect overflowClipRect(const LayoutPoint& location, RenderRegion*, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
- LayoutRect clipRect(const LayoutPoint& location, RenderRegion*);
+ virtual LayoutRect overflowClipRect(const LayoutPoint& location, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
+ LayoutRect clipRect(const LayoutPoint& location);
virtual bool hasControlClip() const { return false; }
virtual LayoutRect controlClipRect(const LayoutPoint&) const { return LayoutRect(); }
bool pushContentsClip(PaintInfo&, const LayoutPoint& accumulatedOffset, ContentsClipBehavior);
@@ -493,7 +510,7 @@ public:
virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
virtual void paintMask(PaintInfo&, const LayoutPoint&);
virtual void paintClippingMask(PaintInfo&, const LayoutPoint&);
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
// Called when a positioned object moves but doesn't necessarily change size. A simplified layout is attempted
// that just updates the object's position. If the size does change, the object remains dirty.
@@ -508,8 +525,6 @@ public:
return true;
}
- LayoutRect maskClipRect();
-
virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
void removeFloatingOrPositionedChildFromBlockLists();
@@ -522,14 +537,14 @@ public:
bool shrinkToAvoidFloats() const;
virtual bool avoidsFloats() const;
- virtual void markForPaginationRelayoutIfNeeded(SubtreeLayoutScope&) { }
+ virtual void markForPaginationRelayoutIfNeeded(SubtreeLayoutScope&);
bool isWritingModeRoot() const { return !parent() || parent()->style()->writingMode() != style()->writingMode(); }
bool isDeprecatedFlexItem() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isDeprecatedFlexibleBox(); }
bool isFlexItemIncludingDeprecated() const { return !isInline() && !isFloatingOrOutOfFlowPositioned() && parent() && parent()->isFlexibleBoxIncludingDeprecated(); }
- virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
virtual LayoutUnit offsetLeft() const OVERRIDE;
@@ -557,13 +572,12 @@ public:
bool hasVisualOverflow() const { return m_overflow && !borderBoxRect().contains(m_overflow->visualOverflowRect()); }
virtual bool needsPreferredWidthsRecalculation() const;
- virtual void computeIntrinsicRatioInformation(FloatSize& /* intrinsicSize */, double& /* intrinsicRatio */, bool& /* isPercentageIntrinsicSize */) const { }
+ virtual void computeIntrinsicRatioInformation(FloatSize& /* intrinsicSize */, double& /* intrinsicRatio */) const { }
IntSize scrolledContentOffset() const;
LayoutSize cachedSizeForOverflowClip() const;
void applyCachedClipAndScrollOffsetForRepaint(LayoutRect& paintRect) const;
- virtual bool hasRelativeDimensions() const;
virtual bool hasRelativeLogicalHeight() const;
bool hasHorizontalLayoutOverflow() const
@@ -596,7 +610,7 @@ public:
ShapeOutsideInfo* shapeOutsideInfo() const
{
- return ShapeOutsideInfo::isEnabledFor(this) ? ShapeOutsideInfo::info(this) : 0;
+ return ShapeOutsideInfo::isEnabledFor(*this) ? ShapeOutsideInfo::info(*this) : 0;
}
void markShapeOutsideDependentsForLayout()
@@ -605,18 +619,21 @@ public:
removeFloatingOrPositionedChildFromBlockLists();
}
+ virtual void invalidateTreeAfterLayout(const RenderLayerModelObject&) OVERRIDE;
+
protected:
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
- virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
virtual void updateFromStyle() OVERRIDE;
- LayoutRect backgroundPaintedExtent() const;
+ // Returns false if it could not cheaply compute the extent (e.g. fixed background), in which case the returned rect may be incorrect.
+ bool getBackgroundPaintedExtent(LayoutRect&) const;
virtual bool foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, unsigned maxDepthToTest) const;
virtual bool computeBackgroundIsKnownToBeObscured() OVERRIDE;
- virtual void paintBackgroundWithBorderAndBoxShadow(PaintInfo&, const LayoutRect&, BackgroundBleedAvoidance);
+ void paintBackgroundWithBorderAndBoxShadow(PaintInfo&, const LayoutRect&, BackgroundBleedAvoidance);
void paintBackground(const PaintInfo&, const LayoutRect&, BackgroundBleedAvoidance = BackgroundBleedNone);
void paintFillLayer(const PaintInfo&, const Color&, const FillLayer*, const LayoutRect&, BackgroundBleedAvoidance, CompositeOperator, RenderObject* backgroundObject);
@@ -628,15 +645,15 @@ protected:
BackgroundBleedAvoidance determineBackgroundBleedAvoidance(GraphicsContext*) const;
bool backgroundHasOpaqueTopLayer() const;
- void computePositionedLogicalWidth(LogicalExtentComputedValues&, RenderRegion* = 0) const;
+ void computePositionedLogicalWidth(LogicalExtentComputedValues&) const;
- LayoutUnit computeIntrinsicLogicalWidthUsing(Length logicalWidthLength, LayoutUnit availableLogicalWidth, LayoutUnit borderAndPadding) const;
- LayoutUnit computeIntrinsicLogicalContentHeightUsing(Length logicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPadding) const;
+ LayoutUnit computeIntrinsicLogicalWidthUsing(const Length& logicalWidthLength, LayoutUnit availableLogicalWidth, LayoutUnit borderAndPadding) const;
+ LayoutUnit computeIntrinsicLogicalContentHeightUsing(const Length& logicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPadding) const;
virtual bool shouldComputeSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); }
virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
- virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const;
+ virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE;
void paintRootBoxFillLayers(const PaintInfo&);
@@ -645,6 +662,8 @@ protected:
virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const OVERRIDE;
virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE;
+ void updateIntrinsicContentLogicalHeight(LayoutUnit intrinsicContentLogicalHeight) const { m_intrinsicContentLogicalHeight = intrinsicContentLogicalHeight; }
+
private:
void updateShapeOutsideInfoAfterStyleChange(const RenderStyle&, const RenderStyle* oldStyle);
void updateGridPositionAfterStyleChange(const RenderStyle*);
@@ -657,20 +676,18 @@ private:
bool skipContainingBlockForPercentHeightCalculation(const RenderBox* containingBlock) const;
- LayoutUnit containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, RenderRegion* = 0, bool checkForPerpendicularWritingMode = true) const;
+ LayoutUnit containingBlockLogicalWidthForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode = true) const;
LayoutUnit containingBlockLogicalHeightForPositioned(const RenderBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode = true) const;
- LayoutUnit viewLogicalHeightForPercentages() const;
-
void computePositionedLogicalHeight(LogicalExtentComputedValues&) const;
void computePositionedLogicalWidthUsing(Length logicalWidth, const RenderBoxModelObject* containerBlock, TextDirection containerDirection,
LayoutUnit containerLogicalWidth, LayoutUnit bordersPlusPadding,
- Length logicalLeft, Length logicalRight, Length marginLogicalLeft, Length marginLogicalRight,
- LogicalExtentComputedValues&) const;
+ const Length& logicalLeft, const Length& logicalRight, const Length& marginLogicalLeft,
+ const Length& marginLogicalRight, LogicalExtentComputedValues&) const;
void computePositionedLogicalHeightUsing(Length logicalHeightLength, const RenderBoxModelObject* containerBlock,
LayoutUnit containerLogicalHeight, LayoutUnit bordersPlusPadding, LayoutUnit logicalHeight,
- Length logicalTop, Length logicalBottom, Length marginLogicalTop, Length marginLogicalBottom,
- LogicalExtentComputedValues&) const;
+ const Length& logicalTop, const Length& logicalBottom, const Length& marginLogicalTop,
+ const Length& marginLogicalBottom, LogicalExtentComputedValues&) const;
void computePositionedLogicalHeightReplaced(LogicalExtentComputedValues&) const;
void computePositionedLogicalWidthReplaced(LogicalExtentComputedValues&) const;
@@ -687,10 +704,22 @@ private:
virtual LayoutRect frameRectForStickyPositioning() const OVERRIDE FINAL { return frameRect(); }
+ RenderBoxRareData& ensureRareData()
+ {
+ if (!m_rareData)
+ m_rareData = adoptPtr(new RenderBoxRareData());
+ return *m_rareData.get();
+ }
+
private:
// The width/height of the contents + borders + padding. The x/y location is relative to our container (which is not always our parent).
LayoutRect m_frameRect;
+ // Our intrinsic height, used for min-height: min-content etc. Maintained by
+ // updateLogicalHeight. This is logicalHeight() before it is clamped to
+ // min/max.
+ mutable LayoutUnit m_intrinsicContentLogicalHeight;
+
protected:
LayoutBoxExtent m_marginBox;
@@ -700,16 +729,11 @@ protected:
// The preferred logical width of the element if it never breaks any lines at all.
LayoutUnit m_maxPreferredLogicalWidth;
- // Our intrinsic height, used for min-height: min-content etc. Maintained by
- // updateLogicalHeight. This is logicalHeight() before it is clamped to
- // min/max.
- LayoutUnit m_intrinsicContentLogicalHeight;
-
- // For inline replaced elements, the inline box that owns us.
- InlineBox* m_inlineBoxWrapper;
-
// Our overflow information.
OwnPtr<RenderOverflow> m_overflow;
+
+private:
+ OwnPtr<RenderBoxRareData> m_rareData;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderBox, isBox());
@@ -731,27 +755,27 @@ inline RenderBox* RenderBox::parentBox() const
inline RenderBox* RenderBox::firstChildBox() const
{
- return toRenderBox(firstChild());
+ return toRenderBox(slowFirstChild());
}
inline RenderBox* RenderBox::lastChildBox() const
{
- return toRenderBox(lastChild());
+ return toRenderBox(slowLastChild());
}
inline void RenderBox::setInlineBoxWrapper(InlineBox* boxWrapper)
{
if (boxWrapper) {
- ASSERT(!m_inlineBoxWrapper);
+ ASSERT(!inlineBoxWrapper());
// m_inlineBoxWrapper should already be 0. Deleting it is a safeguard against security issues.
// Otherwise, there will two line box wrappers keeping the reference to this renderer, and
// only one will be notified when the renderer is getting destroyed. The second line box wrapper
// will keep a stale reference.
- if (UNLIKELY(m_inlineBoxWrapper != 0))
+ if (UNLIKELY(inlineBoxWrapper() != 0))
deleteLineBoxWrapper();
}
- m_inlineBoxWrapper = boxWrapper;
+ ensureRareData().m_inlineBoxWrapper = boxWrapper;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.cpp
index caef81861c4..5e56efce625 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.cpp
@@ -26,23 +26,23 @@
#include "config.h"
#include "core/rendering/RenderBoxModelObject.h"
-#include "HTMLNames.h"
-#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/HTMLNames.h"
#include "core/frame/Settings.h"
+#include "core/html/HTMLFrameOwnerElement.h"
#include "core/page/scrolling/ScrollingConstraints.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/ImageQualityController.h"
#include "core/rendering/RenderBlock.h"
+#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
-#include "core/rendering/RenderNamedFlowThread.h"
#include "core/rendering/RenderRegion.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/rendering/style/ShadowList.h"
#include "platform/geometry/TransformState.h"
-#include "platform/graphics/DrawLooper.h"
+#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/graphics/Path.h"
#include "wtf/CurrentTime.h"
@@ -100,51 +100,9 @@ bool RenderBoxModelObject::hasAcceleratedCompositing() const
return view()->compositor()->hasAcceleratedCompositing();
}
-bool RenderBoxModelObject::startTransition(double timeOffset, CSSPropertyID propertyId, const RenderStyle* fromStyle, const RenderStyle* toStyle)
-{
- ASSERT(hasLayer());
- ASSERT(compositingState() == PaintsIntoOwnBacking);
- return layer()->compositedLayerMapping()->startTransition(timeOffset, propertyId, fromStyle, toStyle);
-}
-
-void RenderBoxModelObject::transitionPaused(double timeOffset, CSSPropertyID propertyId)
-{
- ASSERT(hasLayer());
- ASSERT(compositingState() == PaintsIntoOwnBacking);
- layer()->compositedLayerMapping()->transitionPaused(timeOffset, propertyId);
-}
-
-void RenderBoxModelObject::transitionFinished(CSSPropertyID propertyId)
-{
- ASSERT(hasLayer());
- ASSERT(compositingState() == PaintsIntoOwnBacking);
- layer()->compositedLayerMapping()->transitionFinished(propertyId);
-}
-
-bool RenderBoxModelObject::startAnimation(double timeOffset, const CSSAnimationData* animation, const KeyframeList& keyframes)
-{
- ASSERT(hasLayer());
- ASSERT(compositingState() == PaintsIntoOwnBacking);
- return layer()->compositedLayerMapping()->startAnimation(timeOffset, animation, keyframes);
-}
-
-void RenderBoxModelObject::animationPaused(double timeOffset, const String& name)
-{
- ASSERT(hasLayer());
- ASSERT(compositingState() == PaintsIntoOwnBacking);
- layer()->compositedLayerMapping()->animationPaused(timeOffset, name);
-}
-
-void RenderBoxModelObject::animationFinished(const String& name)
+InterpolationQuality RenderBoxModelObject::chooseInterpolationQuality(GraphicsContext* context, Image* image, const void* layer, const LayoutSize& size)
{
- ASSERT(hasLayer());
- ASSERT(compositingState() == PaintsIntoOwnBacking);
- layer()->compositedLayerMapping()->animationFinished(name);
-}
-
-bool RenderBoxModelObject::shouldPaintAtLowQuality(GraphicsContext* context, Image* image, const void* layer, const LayoutSize& size)
-{
- return ImageQualityController::imageQualityController()->shouldPaintAtLowQuality(context, this, image, layer, size);
+ return ImageQualityController::imageQualityController()->chooseInterpolationQuality(context, this, image, layer, size);
}
RenderBoxModelObject::RenderBoxModelObject(ContainerNode* node)
@@ -170,12 +128,19 @@ void RenderBoxModelObject::willBeDestroyed()
RenderLayerModelObject::willBeDestroyed();
}
+bool RenderBoxModelObject::calculateHasBoxDecorations() const
+{
+ RenderStyle* styleToUse = style();
+ ASSERT(styleToUse);
+ return hasBackground() || styleToUse->hasBorder() || styleToUse->hasAppearance() || styleToUse->boxShadow();
+}
+
void RenderBoxModelObject::updateFromStyle()
{
RenderLayerModelObject::updateFromStyle();
RenderStyle* styleToUse = style();
- setHasBoxDecorations(hasBackground() || styleToUse->hasBorder() || styleToUse->hasAppearance() || styleToUse->boxShadow());
+ setHasBoxDecorations(calculateHasBoxDecorations());
setInline(styleToUse->isDisplayInlineType());
setPositionState(styleToUse->position());
setHorizontalWritingMode(styleToUse->isHorizontalWritingMode());
@@ -222,6 +187,11 @@ bool RenderBoxModelObject::hasAutoHeightOrContainingBlockWithAutoHeight() const
if (cb->isTableCell())
return false;
+ // Match RenderBox::availableLogicalHeightUsing by special casing
+ // the render view. The available height is taken from the frame.
+ if (cb->isRenderView())
+ return false;
+
if (!cb->style()->logicalHeight().isAuto() || (!cb->style()->logicalTop().isAuto() && !cb->style()->logicalBottom().isAuto()))
return false;
@@ -240,11 +210,11 @@ LayoutSize RenderBoxModelObject::relativePositionOffset() const
// call availableWidth on our containing block.
if (!style()->left().isAuto()) {
if (!style()->right().isAuto() && !containingBlock->style()->isLeftToRightDirection())
- offset.setWidth(-valueForLength(style()->right(), containingBlock->availableWidth(), view()));
+ offset.setWidth(-valueForLength(style()->right(), containingBlock->availableWidth()));
else
- offset.expand(valueForLength(style()->left(), containingBlock->availableWidth(), view()), 0);
+ offset.expand(valueForLength(style()->left(), containingBlock->availableWidth()), 0);
} else if (!style()->right().isAuto()) {
- offset.expand(-valueForLength(style()->right(), containingBlock->availableWidth(), view()), 0);
+ offset.expand(-valueForLength(style()->right(), containingBlock->availableWidth()), 0);
}
// If the containing block of a relatively positioned element does not
@@ -257,13 +227,13 @@ LayoutSize RenderBoxModelObject::relativePositionOffset() const
&& (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
|| !style()->top().isPercent()
|| containingBlock->stretchesToViewport()))
- offset.expand(0, valueForLength(style()->top(), containingBlock->availableHeight(), view()));
+ offset.expand(0, valueForLength(style()->top(), containingBlock->availableHeight()));
else if (!style()->bottom().isAuto()
&& (!containingBlock->hasAutoHeightOrContainingBlockWithAutoHeight()
|| !style()->bottom().isPercent()
|| containingBlock->stretchesToViewport()))
- offset.expand(0, -valueForLength(style()->bottom(), containingBlock->availableHeight(), view()));
+ offset.expand(0, -valueForLength(style()->bottom(), containingBlock->availableHeight()));
return offset;
}
@@ -276,7 +246,7 @@ LayoutPoint RenderBoxModelObject::adjustedPositionRelativeToOffsetParent(const L
return LayoutPoint();
LayoutPoint referencePoint = startPoint;
- referencePoint.move(parent()->offsetForColumns(referencePoint));
+ referencePoint.move(parent()->columnOffset(referencePoint));
// If the offsetParent of the element is null, or is the HTML body element,
// return the distance between the canvas origin and the left border edge
@@ -294,24 +264,17 @@ LayoutPoint RenderBoxModelObject::adjustedPositionRelativeToOffsetParent(const L
else if (isStickyPositioned())
referencePoint.move(stickyPositionOffset());
- // CSS regions specification says that region flows should return the body element as their offsetParent.
- // Since we will bypass the body’s renderer anyway, just end the loop if we encounter a region flow (named flow thread).
- // See http://dev.w3.org/csswg/css-regions/#cssomview-offset-attributes
RenderObject* current;
- for (current = parent(); current != offsetParent && !current->isRenderNamedFlowThread() && current->parent(); current = current->parent()) {
+ for (current = parent(); current != offsetParent && current->parent(); current = current->parent()) {
// FIXME: What are we supposed to do inside SVG content?
if (!isOutOfFlowPositioned()) {
if (current->isBox() && !current->isTableRow())
referencePoint.moveBy(toRenderBox(current)->topLeftLocation());
- referencePoint.move(current->parent()->offsetForColumns(referencePoint));
+ referencePoint.move(current->parent()->columnOffset(referencePoint));
}
}
- // Compute the offset position for elements inside named flow threads for which the offsetParent was the body.
- // See https://code.google.com/p/chromium/issues/detail?id=242168
- if (current->isRenderNamedFlowThread())
- referencePoint = toRenderNamedFlowThread(current)->adjustedPositionRelativeToOffsetParent(*this, referencePoint);
- else if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent->isPositioned())
+ if (offsetParent->isBox() && offsetParent->isBody() && !offsetParent->isPositioned())
referencePoint.moveBy(toRenderBox(offsetParent)->topLeftLocation());
}
}
@@ -319,7 +282,7 @@ LayoutPoint RenderBoxModelObject::adjustedPositionRelativeToOffsetParent(const L
return referencePoint;
}
-void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewportConstraints& constraints, const FloatRect& viewportRect) const
+void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewportConstraints& constraints, const FloatRect& constrainingRect) const
{
RenderBlock* containingBlock = this->containingBlock();
@@ -328,10 +291,10 @@ void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo
// Sticky positioned element ignore any override logical width on the containing block (as they don't call
// containingBlockLogicalWidthForContent). It's unclear whether this is totally fine.
- LayoutBoxExtent minMargin(minimumValueForLength(style()->marginTop(), maxWidth, view()),
- minimumValueForLength(style()->marginRight(), maxWidth, view()),
- minimumValueForLength(style()->marginBottom(), maxWidth, view()),
- minimumValueForLength(style()->marginLeft(), maxWidth, view()));
+ LayoutBoxExtent minMargin(minimumValueForLength(style()->marginTop(), maxWidth),
+ minimumValueForLength(style()->marginRight(), maxWidth),
+ minimumValueForLength(style()->marginBottom(), maxWidth),
+ minimumValueForLength(style()->marginLeft(), maxWidth));
// Compute the container-relative area within which the sticky element is allowed to move.
containerContentRect.contract(minMargin);
@@ -347,40 +310,81 @@ void RenderBoxModelObject::computeStickyPositionConstraints(StickyPositionViewpo
// Map to the view to avoid including page scale factor.
FloatRect absContainerFrame = containingBlock->localToContainerQuad(FloatRect(FloatPoint(), containingBlock->size()), view()).boundingBox();
+ if (containingBlock->hasOverflowClip()) {
+ IntSize scrollOffset = containingBlock->layer()->scrollableArea()->adjustedScrollOffset();
+ stickyLocation -= scrollOffset;
+ }
+
// We can't call localToAbsolute on |this| because that will recur. FIXME: For now, assume that |this| is not transformed.
FloatRect absoluteStickyBoxRect(absContainerFrame.location() + stickyLocation, flippedStickyBoxRect.size());
constraints.setAbsoluteStickyBoxRect(absoluteStickyBoxRect);
- if (!style()->left().isAuto()) {
- constraints.setLeftOffset(valueForLength(style()->left(), viewportRect.width(), view()));
+ float horizontalOffsets = constraints.rightOffset() + constraints.leftOffset();
+ bool skipRight = false;
+ bool skipLeft = false;
+ if (!style()->left().isAuto() && !style()->right().isAuto()) {
+ if (horizontalOffsets > containerContentRect.width().toFloat()
+ || horizontalOffsets + containerContentRect.width().toFloat() > constrainingRect.width()) {
+ skipRight = style()->isLeftToRightDirection();
+ skipLeft = !skipRight;
+ }
+ }
+
+ if (!style()->left().isAuto() && !skipLeft) {
+ constraints.setLeftOffset(floatValueForLength(style()->left(), constrainingRect.width()));
constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
}
- if (!style()->right().isAuto()) {
- constraints.setRightOffset(valueForLength(style()->right(), viewportRect.width(), view()));
+ if (!style()->right().isAuto() && !skipRight) {
+ constraints.setRightOffset(floatValueForLength(style()->right(), constrainingRect.width()));
constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);
}
+ bool skipBottom = false;
+ // FIXME(ostap): Exclude top or bottom edge offset depending on the writing mode when related
+ // sections are fixed in spec: http://lists.w3.org/Archives/Public/www-style/2014May/0286.html
+ float verticalOffsets = constraints.topOffset() + constraints.bottomOffset();
+ if (!style()->top().isAuto() && !style()->bottom().isAuto()) {
+ if (verticalOffsets > containerContentRect.height().toFloat()
+ || verticalOffsets + containerContentRect.height().toFloat() > constrainingRect.height()) {
+ skipBottom = true;
+ }
+ }
+
if (!style()->top().isAuto()) {
- constraints.setTopOffset(valueForLength(style()->top(), viewportRect.height(), view()));
+ constraints.setTopOffset(floatValueForLength(style()->top(), constrainingRect.height()));
constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
}
- if (!style()->bottom().isAuto()) {
- constraints.setBottomOffset(valueForLength(style()->bottom(), viewportRect.height(), view()));
+ if (!style()->bottom().isAuto() && !skipBottom) {
+ constraints.setBottomOffset(floatValueForLength(style()->bottom(), constrainingRect.height()));
constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);
}
}
LayoutSize RenderBoxModelObject::stickyPositionOffset() const
{
- LayoutRect viewportRect = view()->frameView()->viewportConstrainedVisibleContentRect();
+ FloatRect constrainingRect;
+
+ ASSERT(hasLayer());
+ RenderLayer* enclosingClippingLayer = layer()->enclosingOverflowClipLayer(ExcludeSelf);
+ if (enclosingClippingLayer) {
+ RenderBox* enclosingClippingBox = toRenderBox(enclosingClippingLayer->renderer());
+ LayoutRect clipRect = enclosingClippingBox->overflowClipRect(LayoutPoint());
+ clipRect.move(enclosingClippingBox->paddingLeft(), enclosingClippingBox->paddingTop());
+ clipRect.contract(LayoutSize(enclosingClippingBox->paddingLeft() + enclosingClippingBox->paddingRight(),
+ enclosingClippingBox->paddingTop() + enclosingClippingBox->paddingBottom()));
+ constrainingRect = enclosingClippingBox->localToContainerQuad(FloatRect(clipRect), view()).boundingBox();
+ } else {
+ LayoutRect viewportRect = view()->frameView()->viewportConstrainedVisibleContentRect();
+ constrainingRect = viewportRect;
+ }
StickyPositionViewportConstraints constraints;
- computeStickyPositionConstraints(constraints, viewportRect);
+ computeStickyPositionConstraints(constraints, constrainingRect);
// The sticky offset is physical, so we can just return the delta computed in absolute coords (though it may be wrong with transforms).
- return LayoutSize(constraints.computeStickyOffset(viewportRect));
+ return LayoutSize(constraints.computeStickyOffset(constrainingRect));
}
LayoutSize RenderBoxModelObject::offsetForInFlowPosition() const
@@ -418,24 +422,20 @@ int RenderBoxModelObject::pixelSnappedOffsetHeight() const
return snapSizeToPixel(offsetHeight(), offsetTop());
}
-LayoutUnit RenderBoxModelObject::computedCSSPadding(Length padding) const
+LayoutUnit RenderBoxModelObject::computedCSSPadding(const Length& padding) const
{
LayoutUnit w = 0;
- RenderView* renderView = 0;
if (padding.isPercent())
w = containingBlockLogicalWidthForContent();
- else if (padding.isViewportPercentage())
- renderView = view();
- return minimumValueForLength(padding, w, renderView);
+ return minimumValueForLength(padding, w);
}
RoundedRect RenderBoxModelObject::getBackgroundRoundedRect(const LayoutRect& borderRect, InlineFlowBox* box, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
{
- RenderView* renderView = view();
- RoundedRect border = style()->getRoundedBorderFor(borderRect, renderView, includeLogicalLeftEdge, includeLogicalRightEdge);
+ RoundedRect border = style()->getRoundedBorderFor(borderRect, includeLogicalLeftEdge, includeLogicalRightEdge);
if (box && (box->nextLineBox() || box->prevLineBox())) {
- RoundedRect segmentBorder = style()->getRoundedBorderFor(LayoutRect(0, 0, inlineBoxWidth, inlineBoxHeight), renderView, includeLogicalLeftEdge, includeLogicalRightEdge);
+ RoundedRect segmentBorder = style()->getRoundedBorderFor(LayoutRect(0, 0, inlineBoxWidth, inlineBoxHeight), includeLogicalLeftEdge, includeLogicalRightEdge);
border.setRadii(segmentBorder.radii());
}
@@ -474,6 +474,8 @@ void RenderBoxModelObject::clipRoundedInnerRect(GraphicsContext * context, const
}
}
+// FIXME: See crbug.com/382491. The use of getCTM in this context is incorrect because the matrix returned does not
+// include scales applied at raster time, such as the device zoom.
static LayoutRect shrinkRectByOnePixel(GraphicsContext* context, const LayoutRect& rect)
{
LayoutRect shrunkRect = rect;
@@ -510,8 +512,8 @@ static void applyBoxShadowForBackground(GraphicsContext* context, const RenderOb
if (boxShadow.style() != Normal)
continue;
FloatSize shadowOffset(boxShadow.x(), boxShadow.y());
- context->setShadow(shadowOffset, boxShadow.blur(), renderer->resolveColor(boxShadow.color()),
- DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
+ context->setShadow(shadowOffset, boxShadow.blur(), boxShadow.color(),
+ DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
return;
}
}
@@ -529,11 +531,11 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
bool hasRoundedBorder = style()->hasBorderRadius() && (includeLeftEdge || includeRightEdge);
bool clippedWithLocalScrolling = hasOverflowClip() && bgLayer->attachment() == LocalBackgroundAttachment;
bool isBorderFill = bgLayer->clip() == BorderFillBox;
- bool isRoot = this->isRoot();
+ bool isRoot = this->isDocumentElement();
Color bgColor = color;
StyleImage* bgImage = bgLayer->image();
- bool shouldPaintBackgroundImage = bgImage && bgImage->canRender(this, style()->effectiveZoom());
+ bool shouldPaintBackgroundImage = bgImage && bgImage->canRender(*this, style()->effectiveZoom());
bool forceBackgroundToWhite = false;
if (document().printing()) {
@@ -552,14 +554,14 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
// while rendering.)
if (forceBackgroundToWhite) {
// Note that we can't reuse this variable below because the bgColor might be changed
- bool shouldPaintBackgroundColor = !bgLayer->next() && bgColor.isValid() && bgColor.alpha();
+ bool shouldPaintBackgroundColor = !bgLayer->next() && bgColor.alpha();
if (shouldPaintBackgroundImage || shouldPaintBackgroundColor) {
bgColor = Color::white;
shouldPaintBackgroundImage = false;
}
}
- bool colorVisible = bgColor.isValid() && bgColor.alpha();
+ bool colorVisible = bgColor.alpha();
// Fast path for drawing simple color backgrounds.
if (!isRoot && !clippedWithLocalScrolling && !shouldPaintBackgroundImage && isBorderFill && !bgLayer->next()) {
@@ -571,7 +573,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
if (boxShadowShouldBeAppliedToBackground)
applyBoxShadowForBackground(context, this);
- if (hasRoundedBorder && bleedAvoidance != BackgroundBleedUseTransparencyLayer) {
+ if (hasRoundedBorder && bleedAvoidance != BackgroundBleedClipBackground) {
RoundedRect border = backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge);
if (border.isRenderable())
context->fillRoundedRect(border, bgColor);
@@ -588,8 +590,8 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
return;
}
- // BorderFillBox radius clipping is taken care of by BackgroundBleedUseTransparencyLayer
- bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidance == BackgroundBleedUseTransparencyLayer);
+ // BorderFillBox radius clipping is taken care of by BackgroundBleedClipBackground
+ bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidance == BackgroundBleedClipBackground);
GraphicsContextStateSaver clipToBorderStateSaver(*context, clipToBorderRadius);
if (clipToBorderRadius) {
RoundedRect border = isBorderFill ? backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge) : getBackgroundRoundedRect(rect, box, boxSize.width(), boxSize.height(), includeLeftEdge, includeRightEdge);
@@ -614,7 +616,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
if (clippedWithLocalScrolling) {
// Clip to the overflow area.
RenderBox* thisBox = toRenderBox(this);
- context->clip(thisBox->overflowClipRect(rect.location(), paintInfo.renderRegion));
+ context->clip(thisBox->overflowClipRect(rect.location()));
// Adjust the paint rect to reflect a scrolled content box with borders at the ends.
IntSize offset = thisBox->scrolledContentOffset();
@@ -669,10 +671,10 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
bool isOpaqueRoot = false;
if (isRoot) {
isOpaqueRoot = true;
- if (!bgLayer->next() && !(bgColor.isValid() && bgColor.alpha() == 255) && view()->frameView()) {
+ if (!bgLayer->next() && bgColor.hasAlpha() && view()->frameView()) {
Element* ownerElement = document().ownerElement();
if (ownerElement) {
- if (!ownerElement->hasTagName(frameTag)) {
+ if (!isHTMLFrameElement(*ownerElement)) {
// Locate the <body> element using the DOM. This is easier than trying
// to crawl around a render tree with potential :before/:after content and
// anonymous blocks created by inline <body> tags etc. We can locate the <body>
@@ -698,7 +700,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
if (!bgLayer->next()) {
IntRect backgroundRect(pixelSnappedIntRect(scrolledPaintRect));
bool boxShadowShouldBeAppliedToBackground = this->boxShadowShouldBeAppliedToBackground(bleedAvoidance, box);
- if (boxShadowShouldBeAppliedToBackground || !shouldPaintBackgroundImage || !bgLayer->hasOpaqueImage(this) || !bgLayer->hasRepeatXY()) {
+ if (boxShadowShouldBeAppliedToBackground || !shouldPaintBackgroundImage || !bgLayer->hasOpaqueImage(this) || !bgLayer->hasRepeatXY() || (isOpaqueRoot && !toRenderBox(this)->height())) {
if (!boxShadowShouldBeAppliedToBackground)
backgroundRect.intersect(paintInfo.rect);
@@ -730,17 +732,20 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
// no progressive loading of the background image
if (shouldPaintBackgroundImage) {
BackgroundImageGeometry geometry;
- calculateBackgroundImageGeometry(bgLayer, scrolledPaintRect, geometry, backgroundObject);
+ calculateBackgroundImageGeometry(paintInfo.paintContainer(), bgLayer, scrolledPaintRect, geometry, backgroundObject);
geometry.clip(paintInfo.rect);
if (!geometry.destRect().isEmpty()) {
CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
RefPtr<Image> image = bgImage->image(clientForBackgroundImage, geometry.tileSize());
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), bgLayer, geometry.tileSize());
+ InterpolationQuality interpolationQuality = chooseInterpolationQuality(context, image.get(), bgLayer, geometry.tileSize());
if (bgLayer->maskSourceType() == MaskLuminance)
context->setColorFilter(ColorFilterLuminanceToAlpha);
+ InterpolationQuality previousInterpolationQuality = context->imageInterpolationQuality();
+ context->setImageInterpolationQuality(interpolationQuality);
context->drawTiledImage(image.get(), geometry.destRect(), geometry.relativePhase(), geometry.tileSize(),
- compositeOp, useLowQualityScaling, bgLayer->blendMode(), geometry.spaceSize());
+ compositeOp, bgLayer->blendMode(), geometry.spaceSize());
+ context->setImageInterpolationQuality(previousInterpolationQuality);
}
}
@@ -754,11 +759,11 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
// Now draw the text into the mask. We do this by painting using a special paint phase that signals to
// InlineTextBoxes that they should just add their contents to the clip.
- PaintInfo info(context, maskRect, PaintPhaseTextClip, PaintBehaviorForceBlackText, 0, paintInfo.renderRegion);
+ PaintInfo info(context, maskRect, PaintPhaseTextClip, PaintBehaviorForceBlackText, 0);
context->setCompositeOperation(CompositeSourceOver);
if (box) {
- RootInlineBox* root = box->root();
- box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrolledPaintRect.y() - box->y()), root->lineTop(), root->lineBottom());
+ RootInlineBox& root = box->root();
+ box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrolledPaintRect.y() - box->y()), root.lineTop(), root.lineBottom());
} else {
LayoutSize localOffset = isBox() ? toRenderBox(this)->locationOffset() : LayoutSize();
paint(info, scrolledPaintRect.location() - localOffset);
@@ -829,18 +834,10 @@ IntSize RenderBoxModelObject::calculateImageIntrinsicDimensions(StyleImage* imag
FloatSize intrinsicRatio;
image->computeIntrinsicDimensions(this, intrinsicWidth, intrinsicHeight, intrinsicRatio);
- // Intrinsic dimensions expressed as percentages must be resolved relative to the dimensions of the rectangle
- // that establishes the coordinate system for the 'background-position' property.
+ ASSERT(!intrinsicWidth.isPercent());
+ ASSERT(!intrinsicHeight.isPercent());
- // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656
- if (intrinsicWidth.isPercent() && intrinsicHeight.isPercent() && intrinsicRatio.isEmpty()) {
- // Resolve width/height percentages against positioningAreaSize, only if no intrinsic ratio is provided.
- int resolvedWidth = static_cast<int>(round(positioningAreaSize.width() * intrinsicWidth.percent() / 100));
- int resolvedHeight = static_cast<int>(round(positioningAreaSize.height() * intrinsicHeight.percent() / 100));
- return IntSize(resolvedWidth, resolvedHeight);
- }
-
- IntSize resolvedSize(intrinsicWidth.isFixed() ? intrinsicWidth.value() : 0, intrinsicHeight.isFixed() ? intrinsicHeight.value() : 0);
+ IntSize resolvedSize(intrinsicWidth.value(), intrinsicHeight.value());
IntSize minimumSize(resolvedSize.width() > 0 ? 1 : 0, resolvedSize.height() > 0 ? 1 : 0);
if (shouldScaleOrNot == ScaleByEffectiveZoom)
resolvedSize.scale(style()->effectiveZoom());
@@ -880,7 +877,6 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
IntSize imageIntrinsicSize = calculateImageIntrinsicDimensions(image, positioningAreaSize, ScaleByEffectiveZoom);
imageIntrinsicSize.scale(1 / image->imageScaleFactor(), 1 / image->imageScaleFactor());
- RenderView* renderView = view();
switch (type) {
case SizeLength: {
LayoutSize tileSize = positioningAreaSize;
@@ -890,13 +886,13 @@ IntSize RenderBoxModelObject::calculateFillTileSize(const FillLayer* fillLayer,
if (layerWidth.isFixed())
tileSize.setWidth(layerWidth.value());
- else if (layerWidth.isPercent() || layerWidth.isViewportPercentage())
- tileSize.setWidth(valueForLength(layerWidth, positioningAreaSize.width(), renderView));
+ else if (layerWidth.isPercent())
+ tileSize.setWidth(valueForLength(layerWidth, positioningAreaSize.width()));
if (layerHeight.isFixed())
tileSize.setHeight(layerHeight.value());
- else if (layerHeight.isPercent() || layerHeight.isViewportPercentage())
- tileSize.setHeight(valueForLength(layerHeight, positioningAreaSize.height(), renderView));
+ else if (layerHeight.isPercent())
+ tileSize.setHeight(valueForLength(layerHeight, positioningAreaSize.height()));
applySubPixelHeuristicForTileSize(tileSize, positioningAreaSize);
@@ -972,7 +968,7 @@ IntPoint RenderBoxModelObject::BackgroundImageGeometry::relativePhase() const
bool RenderBoxModelObject::fixedBackgroundPaintsInLocalCoordinates() const
{
- if (!isRoot())
+ if (!isDocumentElement())
return false;
if (view()->frameView() && view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers)
@@ -996,8 +992,8 @@ static inline int getSpace(int areaSize, int tileSize)
return space;
}
-void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fillLayer, const LayoutRect& paintRect,
- BackgroundImageGeometry& geometry, RenderObject* backgroundObject)
+void RenderBoxModelObject::calculateBackgroundImageGeometry(const RenderLayerModelObject* paintContainer, const FillLayer* fillLayer, const LayoutRect& paintRect,
+ BackgroundImageGeometry& geometry, RenderObject* backgroundObject) const
{
LayoutUnit left = 0;
LayoutUnit top = 0;
@@ -1006,17 +1002,18 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
// Determine the background positioning area and set destRect to the background painting area.
// destRect will be adjusted later if the background is non-repeating.
+ // FIXME: transforms spec says that fixed backgrounds behave like scroll inside transforms.
bool fixedAttachment = fillLayer->attachment() == FixedBackgroundAttachment;
-#if ENABLE(FAST_MOBILE_SCROLLING)
- if (view()->frameView() && view()->frameView()->canBlitOnScroll()) {
+ if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()
+ && view()->frameView()
+ && view()->frameView()->shouldAttemptToScrollUsingFastPath()) {
// As a side effect of an optimization to blit on scroll, we do not honor the CSS
// property "background-attachment: fixed" because it may result in rendering
// artifacts. Note, these artifacts only appear if we are blitting on scroll of
// a page that has fixed background images.
fixedAttachment = false;
}
-#endif
if (!fixedAttachment) {
geometry.setDestRect(snappedPaintRect);
@@ -1040,35 +1037,41 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
// The background of the box generated by the root element covers the entire canvas including
// its margins. Since those were added in already, we have to factor them out when computing
// the background positioning area.
- if (isRoot()) {
+ if (isDocumentElement()) {
positioningAreaSize = pixelSnappedIntSize(toRenderBox(this)->size() - LayoutSize(left + right, top + bottom), toRenderBox(this)->location());
left += marginLeft();
top += marginTop();
} else
positioningAreaSize = pixelSnappedIntSize(paintRect.size() - LayoutSize(left + right, top + bottom), paintRect.location());
} else {
+ geometry.setHasNonLocalGeometry();
+
IntRect viewportRect = pixelSnappedIntRect(viewRect());
if (fixedBackgroundPaintsInLocalCoordinates())
viewportRect.setLocation(IntPoint());
else if (FrameView* frameView = view()->frameView())
viewportRect.setLocation(IntPoint(frameView->scrollOffsetForFixedPosition()));
+ if (paintContainer) {
+ IntPoint absoluteContainerOffset = roundedIntPoint(paintContainer->localToAbsolute(FloatPoint()));
+ viewportRect.moveBy(-absoluteContainerOffset);
+ }
+
geometry.setDestRect(pixelSnappedIntRect(viewportRect));
positioningAreaSize = geometry.destRect().size();
}
- RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
+ const RenderObject* clientForBackgroundImage = backgroundObject ? backgroundObject : this;
IntSize fillTileSize = calculateFillTileSize(fillLayer, positioningAreaSize);
fillLayer->image()->setContainerSizeForRenderer(clientForBackgroundImage, fillTileSize, style()->effectiveZoom());
geometry.setTileSize(fillTileSize);
EFillRepeat backgroundRepeatX = fillLayer->repeatX();
EFillRepeat backgroundRepeatY = fillLayer->repeatY();
- RenderView* renderView = view();
int availableWidth = positioningAreaSize.width() - geometry.tileSize().width();
int availableHeight = positioningAreaSize.height() - geometry.tileSize().height();
- LayoutUnit computedXPosition = minimumValueForLength(fillLayer->xPosition(), availableWidth, renderView, true);
+ LayoutUnit computedXPosition = roundedMinimumValueForLength(fillLayer->xPosition(), availableWidth);
if (backgroundRepeatX == RoundFill && positioningAreaSize.width() > 0 && fillTileSize.width() > 0) {
long nrTiles = max(1l, lroundf((float)positioningAreaSize.width() / fillTileSize.width()));
@@ -1082,7 +1085,7 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
geometry.setSpaceSize(IntSize());
}
- LayoutUnit computedYPosition = minimumValueForLength(fillLayer->yPosition(), availableHeight, renderView, true);
+ LayoutUnit computedYPosition = roundedMinimumValueForLength(fillLayer->yPosition(), availableHeight);
if (backgroundRepeatY == RoundFill && positioningAreaSize.height() > 0 && fillTileSize.height() > 0) {
long nrTiles = max(1l, lroundf((float)positioningAreaSize.height() / fillTileSize.height()));
@@ -1104,7 +1107,7 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
int actualWidth = geometry.tileSize().width() + space;
if (space >= 0) {
- computedXPosition = minimumValueForLength(Length(), availableWidth, renderView, true);
+ computedXPosition = roundedMinimumValueForLength(Length(), availableWidth);
geometry.setSpaceSize(IntSize(space, 0));
geometry.setPhaseX(actualWidth ? actualWidth - roundToInt(computedXPosition + left) % actualWidth : 0);
} else {
@@ -1125,7 +1128,7 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
int actualHeight = geometry.tileSize().height() + space;
if (space >= 0) {
- computedYPosition = minimumValueForLength(Length(), availableHeight, renderView, true);
+ computedYPosition = roundedMinimumValueForLength(Length(), availableHeight);
geometry.setSpaceSize(IntSize(geometry.spaceSize().width(), space));
geometry.setPhaseY(actualHeight ? actualHeight - roundToInt(computedYPosition + top) % actualHeight : 0);
} else {
@@ -1145,13 +1148,13 @@ void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fil
geometry.setDestOrigin(geometry.destRect().location());
}
-static LayoutUnit computeBorderImageSide(const BorderImageLength& borderSlice, LayoutUnit borderSide, LayoutUnit imageSide, LayoutUnit boxExtent, RenderView* renderView)
+static LayoutUnit computeBorderImageSide(const BorderImageLength& borderSlice, LayoutUnit borderSide, LayoutUnit imageSide, LayoutUnit boxExtent)
{
if (borderSlice.isNumber())
return borderSlice.number() * borderSide;
if (borderSlice.length().isAuto())
return imageSide;
- return valueForLength(borderSlice.length(), boxExtent, renderView);
+ return valueForLength(borderSlice.length(), boxExtent);
}
bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext, const LayoutRect& rect, const RenderStyle* style,
@@ -1164,7 +1167,7 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
if (!styleImage->isLoaded())
return true; // Never paint a nine-piece image incrementally, but don't paint the fallback borders either.
- if (!styleImage->canRender(this, style->effectiveZoom()))
+ if (!styleImage->canRender(*this, style->effectiveZoom()))
return false;
// FIXME: border-image is broken with full page zooming when tiling has to happen, since the tiling function
@@ -1180,21 +1183,20 @@ bool RenderBoxModelObject::paintNinePieceImage(GraphicsContext* graphicsContext,
int imageWidth = imageSize.width();
int imageHeight = imageSize.height();
- RenderView* renderView = view();
float imageScaleFactor = styleImage->imageScaleFactor();
- int topSlice = min<int>(imageHeight, valueForLength(ninePieceImage.imageSlices().top(), imageHeight, renderView)) * imageScaleFactor;
- int rightSlice = min<int>(imageWidth, valueForLength(ninePieceImage.imageSlices().right(), imageWidth, renderView)) * imageScaleFactor;
- int bottomSlice = min<int>(imageHeight, valueForLength(ninePieceImage.imageSlices().bottom(), imageHeight, renderView)) * imageScaleFactor;
- int leftSlice = min<int>(imageWidth, valueForLength(ninePieceImage.imageSlices().left(), imageWidth, renderView)) * imageScaleFactor;
+ int topSlice = min<int>(imageHeight, valueForLength(ninePieceImage.imageSlices().top(), imageHeight)) * imageScaleFactor;
+ int rightSlice = min<int>(imageWidth, valueForLength(ninePieceImage.imageSlices().right(), imageWidth)) * imageScaleFactor;
+ int bottomSlice = min<int>(imageHeight, valueForLength(ninePieceImage.imageSlices().bottom(), imageHeight)) * imageScaleFactor;
+ int leftSlice = min<int>(imageWidth, valueForLength(ninePieceImage.imageSlices().left(), imageWidth)) * imageScaleFactor;
ENinePieceImageRule hRule = ninePieceImage.horizontalRule();
ENinePieceImageRule vRule = ninePieceImage.verticalRule();
- int topWidth = computeBorderImageSide(ninePieceImage.borderSlices().top(), style->borderTopWidth(), topSlice, borderImageRect.height(), renderView);
- int rightWidth = computeBorderImageSide(ninePieceImage.borderSlices().right(), style->borderRightWidth(), rightSlice, borderImageRect.width(), renderView);
- int bottomWidth = computeBorderImageSide(ninePieceImage.borderSlices().bottom(), style->borderBottomWidth(), bottomSlice, borderImageRect.height(), renderView);
- int leftWidth = computeBorderImageSide(ninePieceImage.borderSlices().left(), style->borderLeftWidth(), leftSlice, borderImageRect.width(), renderView);
+ int topWidth = computeBorderImageSide(ninePieceImage.borderSlices().top(), style->borderTopWidth(), topSlice, borderImageRect.height());
+ int rightWidth = computeBorderImageSide(ninePieceImage.borderSlices().right(), style->borderRightWidth(), rightSlice, borderImageRect.width());
+ int bottomWidth = computeBorderImageSide(ninePieceImage.borderSlices().bottom(), style->borderBottomWidth(), bottomSlice, borderImageRect.height());
+ int leftWidth = computeBorderImageSide(ninePieceImage.borderSlices().left(), style->borderLeftWidth(), leftSlice, borderImageRect.width());
// Reduce the widths if they're too large.
// The spec says: Given Lwidth as the width of the border image area, Lheight as its height, and Wside as the border image width
@@ -1744,14 +1746,18 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
BorderEdge edges[4];
getBorderEdgeInfo(edges, style, includeLogicalLeftEdge, includeLogicalRightEdge);
- RoundedRect outerBorder = style->getRoundedBorderFor(rect, view(), includeLogicalLeftEdge, includeLogicalRightEdge);
+ RoundedRect outerBorder = style->getRoundedBorderFor(rect, includeLogicalLeftEdge, includeLogicalRightEdge);
RoundedRect innerBorder = style->getRoundedInnerBorderFor(borderInnerRectAdjustedForBleedAvoidance(graphicsContext, rect, bleedAvoidance), includeLogicalLeftEdge, includeLogicalRightEdge);
+ if (outerBorder.rect().isEmpty())
+ return;
+
bool haveAlphaColor = false;
bool haveAllSolidEdges = true;
bool haveAllDoubleEdges = true;
int numEdgesVisible = 4;
bool allEdgesShareColor = true;
+ bool allEdgesShareWidth = true;
int firstVisibleEdge = -1;
BorderEdgeFlags edgesToDraw = 0;
@@ -1764,18 +1770,23 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
if (currEdge.presentButInvisible()) {
--numEdgesVisible;
allEdgesShareColor = false;
+ allEdgesShareWidth = false;
continue;
}
- if (!currEdge.width) {
+ if (!currEdge.shouldRender()) {
--numEdgesVisible;
continue;
}
- if (firstVisibleEdge == -1)
+ if (firstVisibleEdge == -1) {
firstVisibleEdge = i;
- else if (currEdge.color != edges[firstVisibleEdge].color)
- allEdgesShareColor = false;
+ } else {
+ if (currEdge.color != edges[firstVisibleEdge].color)
+ allEdgesShareColor = false;
+ if (currEdge.width != edges[firstVisibleEdge].width)
+ allEdgesShareWidth = false;
+ }
if (currEdge.color.hasAlpha())
haveAlphaColor = true;
@@ -1795,11 +1806,19 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
// isRenderable() check avoids issue described in https://bugs.webkit.org/show_bug.cgi?id=38787
if ((haveAllSolidEdges || haveAllDoubleEdges) && allEdgesShareColor && innerBorder.isRenderable()) {
// Fast path for drawing all solid edges and all unrounded double edges
+
if (numEdgesVisible == 4 && (outerBorder.isRounded() || haveAlphaColor)
&& (haveAllSolidEdges || (!outerBorder.isRounded() && !innerBorder.isRounded()))) {
Path path;
- if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+ if (outerBorder.isRounded() && allEdgesShareWidth) {
+
+ // Very fast path for single stroked round rect with circular corners
+
+ graphicsContext->fillBetweenRoundedRects(outerBorder, innerBorder, edges[firstVisibleEdge].color);
+ return;
+ }
+ if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedClipBackground)
path.addRoundedRect(outerBorder);
else
path.addRect(outerBorder.rect());
@@ -1832,12 +1851,12 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
innerThird.setRect(innerThirdRect);
outerThird.setRect(outerThirdRect);
- if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+ if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedClipBackground)
path.addRoundedRect(outerThird);
else
path.addRect(outerThird.rect());
- if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+ if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedClipBackground)
path.addRoundedRect(innerThird);
else
path.addRect(innerThird.rect());
@@ -1876,7 +1895,7 @@ void RenderBoxModelObject::paintBorder(const PaintInfo& info, const LayoutRect&
GraphicsContextStateSaver stateSaver(*graphicsContext, clipToOuterBorder);
if (clipToOuterBorder) {
// Clip to the inner and outer radii rects.
- if (bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+ if (bleedAvoidance != BackgroundBleedClipBackground)
graphicsContext->clipRoundedRect(outerBorder);
// isRenderable() check avoids issue described in https://bugs.webkit.org/show_bug.cgi?id=38787
// The inside will be clipped out later (in clipBorderSideForComplexInnerPath)
@@ -1982,7 +2001,7 @@ void RenderBoxModelObject::drawBoxSideFromPath(GraphicsContext* graphicsContext,
{
GraphicsContextStateSaver stateSaver(*graphicsContext);
LayoutRect outerRect = borderRect;
- if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) {
+ if (bleedAvoidance == BackgroundBleedClipBackground) {
outerRect.inflate(1);
++outerBorderTopWidth;
++outerBorderBottomWidth;
@@ -2054,7 +2073,7 @@ void RenderBoxModelObject::clipBorderSidePolygon(GraphicsContext* graphicsContex
const LayoutRect& outerRect = outerBorder.rect();
const LayoutRect& innerRect = innerBorder.rect();
- FloatPoint centerPoint(innerRect.location().x() + static_cast<float>(innerRect.width()) / 2, innerRect.location().y() + static_cast<float>(innerRect.height()) / 2);
+ FloatPoint centerPoint(innerRect.location().x().toFloat() + innerRect.width().toFloat() / 2, innerRect.location().y().toFloat() + innerRect.height().toFloat() / 2);
// For each side, create a quad that encompasses all parts of that side that may draw,
// including areas inside the innerBorder.
@@ -2446,7 +2465,7 @@ bool RenderBoxModelObject::boxShadowShouldBeAppliedToBackground(BackgroundBleedA
return false;
Color backgroundColor = resolveColor(CSSPropertyBackgroundColor);
- if (!backgroundColor.isValid() || backgroundColor.hasAlpha())
+ if (backgroundColor.hasAlpha())
return false;
const FillLayer* lastBackgroundLayer = style()->backgroundLayers();
@@ -2476,11 +2495,11 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
return;
RoundedRect border = (shadowStyle == Inset) ? s->getRoundedInnerBorderFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge)
- : s->getRoundedBorderFor(paintRect, view(), includeLogicalLeftEdge, includeLogicalRightEdge);
+ : s->getRoundedBorderFor(paintRect, includeLogicalLeftEdge, includeLogicalRightEdge);
bool hasBorderRadius = s->hasBorderRadius();
bool isHorizontal = s->isHorizontalWritingMode();
- bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundColor).isValid() && s->visitedDependentColor(CSSPropertyBackgroundColor).alpha() == 255;
+ bool hasOpaqueBackground = s->visitedDependentColor(CSSPropertyBackgroundColor).alpha() == 255;
GraphicsContextStateSaver stateSaver(*context, false);
@@ -2490,22 +2509,22 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
if (shadow.style() != shadowStyle)
continue;
- IntSize shadowOffset(shadow.x(), shadow.y());
- int shadowBlur = shadow.blur();
- int shadowSpread = shadow.spread();
+ FloatSize shadowOffset(shadow.x(), shadow.y());
+ float shadowBlur = shadow.blur();
+ float shadowSpread = shadow.spread();
if (shadowOffset.isZero() && !shadowBlur && !shadowSpread)
continue;
- const Color& shadowColor = resolveColor(shadow.color());
+ const Color& shadowColor = shadow.color();
if (shadow.style() == Normal) {
- RoundedRect fillRect = border;
+ FloatRect fillRect = border.rect();
fillRect.inflate(shadowSpread);
if (fillRect.isEmpty())
continue;
- IntRect shadowRect(border.rect());
+ FloatRect shadowRect(border.rect());
shadowRect.inflate(shadowBlur + shadowSpread);
shadowRect.move(shadowOffset);
@@ -2526,6 +2545,8 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
context->clipOutRoundedRect(rectToClipOut);
}
} else {
+ // This IntRect is correct even with fractional shadows, because it is used for the rectangle
+ // of the box itself, which is always pixel-aligned.
IntRect rectToClipOut = border.rect();
// If the box is opaque, it is unnecessary to clip it out. However, doing so saves time
@@ -2535,6 +2556,8 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
if (hasOpaqueBackground) {
// FIXME: The function to decide on the policy based on the transform should be a named function.
// FIXME: It's not clear if this check is right. What about integral scale factors?
+ // FIXME: See crbug.com/382491. The use of getCTM may also be wrong because it does not include
+ // device zoom applied at raster time.
AffineTransform transform = context->getCTM();
if (transform.a() != 1 || (transform.d() != 1 && transform.d() != -1) || transform.b() || transform.c())
rectToClipOut.inflate(-1);
@@ -2547,26 +2570,31 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
}
// Draw only the shadow.
- DrawLooper drawLooper;
- drawLooper.addShadow(shadowOffset, shadowBlur, shadowColor,
- DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
- context->setDrawLooper(drawLooper);
+ OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
+ drawLooperBuilder->addShadow(shadowOffset, shadowBlur, shadowColor,
+ DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
+ context->setDrawLooper(drawLooperBuilder.release());
if (hasBorderRadius) {
- RoundedRect influenceRect(shadowRect, border.radii());
+ RoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(shadowRect)), border.radii());
influenceRect.expandRadii(2 * shadowBlur + shadowSpread);
if (allCornersClippedOut(influenceRect, info.rect))
- context->fillRect(fillRect.rect(), Color::black);
+ context->fillRect(fillRect, Color::black);
else {
- fillRect.expandRadii(shadowSpread);
- if (!fillRect.isRenderable())
- fillRect.adjustRadii();
- context->fillRoundedRect(fillRect, Color::black);
+ // TODO: support non-integer shadows - crbug.com/334829
+ RoundedRect roundedFillRect = border;
+ roundedFillRect.inflate(shadowSpread);
+
+ roundedFillRect.expandRadii(shadowSpread);
+ if (!roundedFillRect.isRenderable())
+ roundedFillRect.adjustRadii();
+ context->fillRoundedRect(roundedFillRect, Color::black);
}
} else {
- context->fillRect(fillRect.rect(), Color::black);
+ context->fillRect(fillRect, Color::black);
}
} else {
+ // The inset shadow case.
GraphicsContext::Edges clippedEdges = GraphicsContext::NoEdge;
if (!includeLogicalLeftEdge) {
if (isHorizontal)
@@ -2580,7 +2608,8 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec
else
clippedEdges |= GraphicsContext::BottomEdge;
}
- context->drawInnerShadow(border, shadowColor, shadowOffset, shadowBlur, shadowSpread, clippedEdges);
+ // TODO: support non-integer shadows - crbug.com/334828
+ context->drawInnerShadow(border, shadowColor, flooredIntSize(shadowOffset), shadowBlur, shadowSpread, clippedEdges);
}
}
}
@@ -2640,7 +2669,7 @@ void RenderBoxModelObject::setFirstLetterRemainingText(RenderTextFragment* remai
LayoutRect RenderBoxModelObject::localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset)
{
- ASSERT(!firstChild());
+ ASSERT(!slowFirstChild());
// FIXME: This does not take into account either :first-line or :first-letter
// However, as soon as some content is entered, the line boxes will be
@@ -2708,30 +2737,22 @@ bool RenderBoxModelObject::shouldAntialiasLines(GraphicsContext* context)
{
// FIXME: We may want to not antialias when scaled by an integral value,
// and we may want to antialias when translated by a non-integral value.
+ // FIXME: See crbug.com/382491. getCTM does not include scale factors applied at raster time, such
+ // as device zoom.
return !context->getCTM().isIdentityOrTranslationOrFlipped();
}
void RenderBoxModelObject::mapAbsoluteToLocalPoint(MapCoordinatesFlags mode, TransformState& transformState) const
{
// We don't expect to be called during layout.
- ASSERT(!view() || !view()->layoutStateEnabled());
+ ASSERT(!view() || !view()->layoutStateCachedOffsetsEnabled());
RenderObject* o = container();
if (!o)
return;
- // The point inside a box that's inside a region has its coordinates relative to the region,
- // not the FlowThread that is its container in the RenderObject tree.
- if (o->isRenderFlowThread() && isRenderBlock()) {
- // FIXME: switch to Box instead of Block when we'll have range information for boxes as well, not just for blocks.
- RenderRegion* startRegion;
- RenderRegion* ignoredEndRegion;
- toRenderFlowThread(o)->getRegionRangeForBox(toRenderBlock(this), startRegion, ignoredEndRegion);
- // If there is no region to use the FlowThread, then there's no region range for the content in that FlowThread.
- // An API like elementFromPoint might crash without this check.
- if (startRegion)
- o = startRegion;
- }
+ if (o->isRenderFlowThread())
+ transformState.move(o->columnOffset(LayoutPoint(transformState.mappedPoint())));
o->mapAbsoluteToLocalPoint(mode, transformState);
@@ -2780,7 +2801,7 @@ const RenderObject* RenderBoxModelObject::pushMappingToContainer(const RenderLay
if (shouldUseTransformFromContainer(container)) {
TransformationMatrix t;
getTransformFromContainer(container, containerOffset, t);
- t.translateRight(adjustmentForSkippedAncestor.width(), adjustmentForSkippedAncestor.height());
+ t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustmentForSkippedAncestor.height().toFloat());
geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPos, hasTransform);
} else {
containerOffset += adjustmentForSkippedAncestor;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.h b/chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.h
index 31b318612b8..f308aec7ca8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderBoxModelObject.h
@@ -24,6 +24,7 @@
#ifndef RenderBoxModelObject_h
#define RenderBoxModelObject_h
+#include "core/animation/ActiveAnimations.h"
#include "core/rendering/RenderLayerModelObject.h"
#include "core/rendering/style/ShadowData.h"
#include "platform/geometry/LayoutRect.h"
@@ -38,20 +39,17 @@ typedef unsigned BorderEdgeFlags;
enum BackgroundBleedAvoidance {
BackgroundBleedNone,
BackgroundBleedShrinkBackground,
- BackgroundBleedUseTransparencyLayer,
+ BackgroundBleedClipBackground,
BackgroundBleedBackgroundOverBorder
};
enum ContentChangeType {
ImageChanged,
- MaskImageChanged,
CanvasChanged,
CanvasPixelsChanged,
- VideoChanged,
- FullScreenChanged
+ CanvasContextChanged
};
-class KeyframeList;
class RenderTextFragment;
class StickyPositionViewportConstraints;
@@ -66,7 +64,7 @@ public:
LayoutSize relativePositionOffset() const;
LayoutSize relativePositionLogicalOffset() const { return style()->isHorizontalWritingMode() ? relativePositionOffset() : relativePositionOffset().transposedSize(); }
- void computeStickyPositionConstraints(StickyPositionViewportConstraints&, const FloatRect& viewportRect) const;
+ void computeStickyPositionConstraints(StickyPositionViewportConstraints&, const FloatRect& constrainingRect) const;
LayoutSize stickyPositionOffset() const;
LayoutSize stickyPositionLogicalOffset() const { return style()->isHorizontalWritingMode() ? stickyPositionOffset() : stickyPositionOffset().transposedSize(); }
@@ -86,8 +84,6 @@ public:
virtual void updateFromStyle() OVERRIDE;
- virtual bool requiresLayer() const OVERRIDE { return isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns(); }
-
// This will work on inlines to return the bounding box of all of the lines' border boxes.
virtual IntRect borderBoundingBox() const = 0;
@@ -121,6 +117,9 @@ public:
virtual int borderStart() const { return style()->borderStartWidth(); }
virtual int borderEnd() const { return style()->borderEndWidth(); }
+ int borderWidth() const { return borderLeft() + borderRight(); }
+ int borderHeight() const { return borderTop() + borderBottom(); }
+
LayoutUnit borderAndPaddingStart() const { return borderStart() + paddingStart(); }
LayoutUnit borderAndPaddingBefore() const { return borderBefore() + paddingBefore(); }
LayoutUnit borderAndPaddingAfter() const { return borderAfter() + paddingAfter(); }
@@ -176,30 +175,22 @@ public:
virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
- void highQualityRepaintTimerFired(Timer<RenderBoxModelObject>*);
-
- virtual void setSelectionState(SelectionState s);
-
- bool canHaveBoxInfoInRegion() const { return !isFloating() && !isReplaced() && !isInline() && !hasColumns() && !isTableCell() && isRenderBlock() && !isRenderSVGBlock(); }
+ virtual void setSelectionState(SelectionState) OVERRIDE;
void contentChanged(ContentChangeType);
bool hasAcceleratedCompositing() const;
- bool startTransition(double, CSSPropertyID, const RenderStyle* fromStyle, const RenderStyle* toStyle);
- void transitionPaused(double timeOffset, CSSPropertyID);
- void transitionFinished(CSSPropertyID);
-
- bool startAnimation(double timeOffset, const CSSAnimationData*, const KeyframeList& keyframes);
- void animationPaused(double timeOffset, const String& name);
- void animationFinished(const String& name);
-
virtual void computeLayerHitTestRects(LayerHitTestRects&) const OVERRIDE;
protected:
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
class BackgroundImageGeometry {
public:
+ BackgroundImageGeometry()
+ : m_hasNonLocalGeometry(false)
+ { }
+
IntPoint destOrigin() const { return m_destOrigin; }
void setDestOrigin(const IntPoint& destOrigin)
{
@@ -244,37 +235,43 @@ protected:
void useFixedAttachment(const IntPoint& attachmentPoint);
void clip(const IntRect&);
+
+ void setHasNonLocalGeometry(bool hasNonLocalGeometry = true) { m_hasNonLocalGeometry = hasNonLocalGeometry; }
+ bool hasNonLocalGeometry() const { return m_hasNonLocalGeometry; }
+
private:
IntRect m_destRect;
IntPoint m_destOrigin;
IntPoint m_phase;
IntSize m_tileSize;
IntSize m_repeatSpacing;
+ bool m_hasNonLocalGeometry; // Has background-attachment: fixed. Implies that we can't always cheaply compute destRect.
};
LayoutPoint adjustedPositionRelativeToOffsetParent(const LayoutPoint&) const;
- void calculateBackgroundImageGeometry(const FillLayer*, const LayoutRect& paintRect, BackgroundImageGeometry&, RenderObject* = 0);
+ bool calculateHasBoxDecorations() const;
+ void calculateBackgroundImageGeometry(const RenderLayerModelObject* paintContainer, const FillLayer*, const LayoutRect& paintRect, BackgroundImageGeometry&, RenderObject* = 0) const;
void getBorderEdgeInfo(class BorderEdge[], const RenderStyle*, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const;
bool borderObscuresBackgroundEdge(const FloatSize& contextScale) const;
bool borderObscuresBackground() const;
RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(GraphicsContext*, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox*, const LayoutSize&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
LayoutRect borderInnerRectAdjustedForBleedAvoidance(GraphicsContext*, const LayoutRect&, BackgroundBleedAvoidance) const;
- bool shouldPaintAtLowQuality(GraphicsContext*, Image*, const void*, const LayoutSize&);
+ InterpolationQuality chooseInterpolationQuality(GraphicsContext*, Image*, const void*, const LayoutSize&);
RenderBoxModelObject* continuation() const;
void setContinuation(RenderBoxModelObject*);
LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset);
- static bool shouldAntialiasLines(GraphicsContext*);
-
static void clipRoundedInnerRect(GraphicsContext*, const LayoutRect&, const RoundedRect& clipRect);
bool hasAutoHeightOrContainingBlockWithAutoHeight() const;
public:
+ static bool shouldAntialiasLines(GraphicsContext*);
+
// For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments
RenderTextFragment* firstLetterRemainingText() const;
void setFirstLetterRemainingText(RenderTextFragment*);
@@ -293,7 +290,7 @@ public:
}
void moveAllChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* beforeChild, bool fullRemoveInsert = false)
{
- moveChildrenTo(toBoxModelObject, firstChild(), 0, beforeChild, fullRemoveInsert);
+ moveChildrenTo(toBoxModelObject, slowFirstChild(), 0, beforeChild, fullRemoveInsert);
}
// Move all of the kids from |startChild| up to but excluding |endChild|. 0 can be passed as the |endChild| to denote
// that all the kids from |startChild| onwards should be moved.
@@ -303,17 +300,17 @@ public:
}
void moveChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false);
+ enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom };
+ IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const;
+
private:
- LayoutUnit computedCSSPadding(Length) const;
+ LayoutUnit computedCSSPadding(const Length&) const;
virtual bool isBoxModelObject() const OVERRIDE FINAL { return true; }
virtual LayoutRect frameRectForStickyPositioning() const = 0;
IntSize calculateFillTileSize(const FillLayer*, const IntSize& scaledPositioningAreaSize) const;
- enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom };
- IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const;
-
RoundedRect getBackgroundRoundedRect(const LayoutRect&, InlineFlowBox*, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderBoxRegionInfo.h b/chromium/third_party/WebKit/Source/core/rendering/RenderBoxRegionInfo.h
deleted file mode 100644
index 3bde47e9477..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderBoxRegionInfo.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef RenderBoxRegionInfo_h
-#define RenderBoxRegionInfo_h
-
-#include "platform/LayoutUnit.h"
-#include "wtf/FastAllocBase.h"
-
-namespace WebCore {
-
-class RenderBoxRegionInfo {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- RenderBoxRegionInfo(LayoutUnit logicalLeft, LayoutUnit logicalWidth, bool isShifted)
- : m_logicalLeft(logicalLeft)
- , m_logicalWidth(logicalWidth)
- , m_isShifted(isShifted)
- { }
-
- LayoutUnit logicalLeft() const { return m_logicalLeft; }
- LayoutUnit logicalWidth() const { return m_logicalWidth; }
-
- void shiftLogicalLeft(LayoutUnit delta) { m_logicalLeft += delta; m_isShifted = true; }
-
- bool isShifted() const { return m_isShifted; }
-
-private:
- LayoutUnit m_logicalLeft;
- LayoutUnit m_logicalWidth;
- bool m_isShifted;
-};
-
-} // namespace WebCore
-
-#endif // RenderBoxRegionInfo_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderButton.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderButton.cpp
index ce1bec473ce..9b16c4af8a0 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderButton.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderButton.cpp
@@ -63,7 +63,7 @@ void RenderButton::removeChild(RenderObject* oldChild)
m_inner->removeChild(oldChild);
}
-void RenderButton::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderButton::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
if (m_inner) {
// RenderBlock::setStyle is going to apply a new style to the inner block, which
@@ -71,9 +71,9 @@ void RenderButton::styleWillChange(StyleDifference diff, const RenderStyle* newS
// it right below. Here we change it back to 0 to avoid getting a spurious layout hint
// because of the difference. Same goes for the other properties.
// FIXME: Make this hack unnecessary.
- m_inner->style()->setFlexGrow(newStyle->initialFlexGrow());
- m_inner->style()->setMarginTop(newStyle->initialMargin());
- m_inner->style()->setMarginBottom(newStyle->initialMargin());
+ m_inner->style()->setFlexGrow(newStyle.initialFlexGrow());
+ m_inner->style()->setMarginTop(newStyle.initialMargin());
+ m_inner->style()->setMarginBottom(newStyle.initialMargin());
}
RenderBlock::styleWillChange(diff, newStyle);
}
@@ -97,6 +97,10 @@ void RenderButton::setupInnerStyle(RenderStyle* innerStyle)
innerStyle->setMarginTop(Length());
innerStyle->setMarginBottom(Length());
innerStyle->setFlexDirection(style()->flexDirection());
+ innerStyle->setJustifyContent(style()->justifyContent());
+ innerStyle->setFlexWrap(style()->flexWrap());
+ innerStyle->setAlignItems(style()->alignItems());
+ innerStyle->setAlignContent(style()->alignContent());
}
bool RenderButton::canHaveGeneratedChildren() const
@@ -104,7 +108,7 @@ bool RenderButton::canHaveGeneratedChildren() const
// Input elements can't have generated children, but button elements can. We'll
// write the code assuming any other button types that might emerge in the future
// can also have children.
- return !node()->hasTagName(inputTag);
+ return !isHTMLInputElement(*node());
}
LayoutRect RenderButton::controlClipRect(const LayoutPoint& additionalOffset) const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderButton.h b/chromium/third_party/WebKit/Source/core/rendering/RenderButton.h
index 33df32be802..8aaed6266c9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderButton.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderButton.h
@@ -21,13 +21,11 @@
#ifndef RenderButton_h
#define RenderButton_h
-#include "HTMLNames.h"
+#include "core/html/HTMLInputElement.h"
#include "core/rendering/RenderFlexibleBox.h"
namespace WebCore {
-class RenderTextFragment;
-
// RenderButtons are just like normal flexboxes except that they will generate an anonymous block child.
// For inputs, they will also generate an anonymous RenderText and keep its style and content up
// to date as the button changes.
@@ -36,15 +34,16 @@ public:
explicit RenderButton(Element*);
virtual ~RenderButton();
- virtual const char* renderName() const { return "RenderButton"; }
- virtual bool isRenderButton() const { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderButton"; }
+ virtual bool isRenderButton() const OVERRIDE { return true; }
virtual bool canBeSelectionLeaf() const OVERRIDE { return node() && node()->rendererIsEditable(); }
+ virtual bool canCollapseAnonymousBlockChild() const OVERRIDE { return true; }
- virtual void addChild(RenderObject* newChild, RenderObject *beforeChild = 0);
- virtual void removeChild(RenderObject*);
- virtual void removeLeftoverAnonymousBlock(RenderBlock*) { }
- virtual bool createsAnonymousWrapper() const { return true; }
+ virtual void addChild(RenderObject* newChild, RenderObject *beforeChild = 0) OVERRIDE;
+ virtual void removeChild(RenderObject*) OVERRIDE;
+ virtual void removeLeftoverAnonymousBlock(RenderBlock*) OVERRIDE { }
+ virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
void setupInnerStyle(RenderStyle*);
@@ -52,16 +51,16 @@ public:
virtual bool canHaveWhitespaceChildren() const OVERRIDE { return true; }
virtual bool canHaveGeneratedChildren() const OVERRIDE;
- virtual bool hasControlClip() const { return true; }
- virtual LayoutRect controlClipRect(const LayoutPoint&) const;
+ virtual bool hasControlClip() const OVERRIDE { return true; }
+ virtual LayoutRect controlClipRect(const LayoutPoint&) const OVERRIDE;
virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode) const OVERRIDE;
private:
- virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
- virtual bool hasLineIfEmpty() const { return node() && node()->hasTagName(HTMLNames::inputTag); }
+ virtual bool hasLineIfEmpty() const OVERRIDE { return isHTMLInputElement(node()); }
RenderBlock* m_inner;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.cpp
index 75ae66dec91..2e58c5f995b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.cpp
@@ -55,28 +55,31 @@ void RenderCombineText::setTextInternal(PassRefPtr<StringImpl> text)
m_needsFontUpdate = true;
}
-float RenderCombineText::width(unsigned from, unsigned length, const Font& font, float xPosition, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderCombineText::width(unsigned from, unsigned length, const Font& font, float xPosition, TextDirection direction, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
+ if (!length)
+ return 0;
+
if (hasEmptyText())
return 0;
if (m_isCombined)
- return font.size();
+ return font.fontDescription().computedSize();
- return RenderText::width(from, length, font, xPosition, fallbackFonts, glyphOverflow);
+ return RenderText::width(from, length, font, xPosition, direction, fallbackFonts, glyphOverflow);
}
void RenderCombineText::adjustTextOrigin(FloatPoint& textOrigin, const FloatRect& boxRect) const
{
if (m_isCombined)
- textOrigin.move(boxRect.height() / 2 - ceilf(m_combinedTextWidth) / 2, style()->font().pixelSize());
+ textOrigin.move(boxRect.height() / 2 - ceilf(m_combinedTextWidth) / 2, style()->font().fontDescription().computedPixelSize());
}
void RenderCombineText::getStringToRender(int start, StringView& string, int& length) const
{
ASSERT(start >= 0);
if (m_isCombined) {
- string = StringView(originalText());
+ string = StringView(m_renderingText.impl());
length = string.length();
return;
}
@@ -96,7 +99,7 @@ void RenderCombineText::combineText()
if (style()->isHorizontalWritingMode())
return;
- TextRun run = RenderBlockFlow::constructTextRun(this, originalFont(), this, style());
+ TextRun run = RenderBlockFlow::constructTextRun(this, originalFont(), this, style(), style()->direction());
FontDescription description = originalFont().fontDescription();
float emWidth = description.computedSize() * textCombineMargin;
bool shouldUpdateFont = false;
@@ -114,7 +117,7 @@ void RenderCombineText::combineText()
static const FontWidthVariant widthVariants[] = { HalfWidth, ThirdWidth, QuarterWidth };
for (size_t i = 0 ; i < WTF_ARRAY_LENGTH(widthVariants) ; ++i) {
description.setWidthVariant(widthVariants[i]);
- Font compressedFont = Font(description, style()->font().letterSpacing(), style()->font().wordSpacing());
+ Font compressedFont = Font(description);
compressedFont.update(fontSelector);
float runWidth = compressedFont.width(run);
if (runWidth <= emWidth) {
@@ -136,6 +139,7 @@ void RenderCombineText::combineText()
if (m_isCombined) {
DEFINE_STATIC_LOCAL(String, objectReplacementCharacterString, (&objectReplacementCharacter, 1));
+ m_renderingText = text();
RenderText::setTextInternal(objectReplacementCharacterString.impl());
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.h b/chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.h
index ce196d4c360..d15bdd75447 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderCombineText.h
@@ -34,17 +34,18 @@ public:
void adjustTextOrigin(FloatPoint& textOrigin, const FloatRect& boxRect) const;
void getStringToRender(int, StringView&, int& length) const;
bool isCombined() const { return m_isCombined; }
- float combinedTextWidth(const Font& font) const { return font.size(); }
+ float combinedTextWidth(const Font& font) const { return font.fontDescription().computedSize(); }
const Font& originalFont() const { return parent()->style()->font(); }
private:
- virtual bool isCombineText() const { return true; }
- virtual float width(unsigned from, unsigned length, const Font&, float xPosition, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
- virtual const char* renderName() const { return "RenderCombineText"; }
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual void setTextInternal(PassRefPtr<StringImpl>);
+ virtual bool isCombineText() const OVERRIDE { return true; }
+ virtual float width(unsigned from, unsigned length, const Font&, float xPosition, TextDirection, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const OVERRIDE;
+ virtual const char* renderName() const OVERRIDE { return "RenderCombineText"; }
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+ virtual void setTextInternal(PassRefPtr<StringImpl>) OVERRIDE;
float m_combinedTextWidth;
+ String m_renderingText;
bool m_isCombined : 1;
bool m_needsFontUpdate : 1;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderCounter.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderCounter.cpp
index 5aac629a947..6451d43ea54 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderCounter.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderCounter.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "core/rendering/RenderCounter.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/ElementTraversal.h"
@@ -148,12 +148,12 @@ static bool planCounter(RenderObject& object, const AtomicString& identifier, bo
return true;
}
if (Node* e = object.node()) {
- if (e->hasTagName(olTag)) {
+ if (isHTMLOListElement(*e)) {
value = toHTMLOListElement(e)->start();
isReset = true;
return true;
}
- if (e->hasTagName(ulTag) || e->hasTagName(menuTag) || e->hasTagName(dirTag)) {
+ if (isHTMLUListElement(*e) || isHTMLMenuElement(*e) || isHTMLDirectoryElement(*e)) {
value = 0;
isReset = true;
return true;
@@ -189,8 +189,8 @@ static bool findPlaceForCounter(RenderObject& counterOwner, const AtomicString&
// towards the begining of the document for counters with the same identifier as the one
// we are trying to find a place for. This is the next renderer to be checked.
RenderObject* currentRenderer = previousInPreOrder(counterOwner);
- previousSibling = 0;
- RefPtr<CounterNode> previousSiblingProtector = 0;
+ previousSibling = nullptr;
+ RefPtr<CounterNode> previousSiblingProtector = nullptr;
while (currentRenderer) {
CounterNode* currentCounter = makeCounterNode(*currentRenderer, identifier, false);
@@ -216,7 +216,7 @@ static bool findPlaceForCounter(RenderObject& counterOwner, const AtomicString&
// In these cases the identified previousSibling will be invalid as its parent is different from
// our identified parent.
if (previousSiblingProtector->parent() != currentCounter)
- previousSiblingProtector = 0;
+ previousSiblingProtector = nullptr;
previousSibling = previousSiblingProtector.get();
return true;
@@ -307,8 +307,8 @@ static CounterNode* makeCounterNode(RenderObject& object, const AtomicString& id
if (!planCounter(object, identifier, isReset, value) && !alwaysCreateCounter)
return 0;
- RefPtr<CounterNode> newParent = 0;
- RefPtr<CounterNode> newPreviousSibling = 0;
+ RefPtr<CounterNode> newParent = nullptr;
+ RefPtr<CounterNode> newPreviousSibling = nullptr;
RefPtr<CounterNode> newNode = CounterNode::create(object, isReset, value);
if (findPlaceForCounter(object, identifier, isReset, newParent, newPreviousSibling))
newParent->insertAfter(newNode.get(), newPreviousSibling.get(), identifier);
@@ -385,9 +385,9 @@ PassRefPtr<StringImpl> RenderCounter::originalText() const
RenderObject* beforeAfterContainer = parent();
while (true) {
if (!beforeAfterContainer)
- return 0;
+ return nullptr;
if (!beforeAfterContainer->isAnonymous() && !beforeAfterContainer->isPseudoElement())
- return 0; // RenderCounters are restricted to before and after pseudo elements
+ return nullptr; // RenderCounters are restricted to before and after pseudo elements
PseudoId containerStyle = beforeAfterContainer->style()->styleType();
if ((containerStyle == BEFORE) || (containerStyle == AFTER))
break;
@@ -425,7 +425,7 @@ void RenderCounter::invalidate()
ASSERT(!m_counterNode);
if (documentBeingDestroyed())
return;
- setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
static void destroyCounterNodeWithoutMapRemoval(const AtomicString& identifier, CounterNode* node)
@@ -515,8 +515,8 @@ static void updateCounters(RenderObject& renderer)
makeCounterNode(renderer, it->key, false);
continue;
}
- RefPtr<CounterNode> newParent = 0;
- RefPtr<CounterNode> newPreviousSibling = 0;
+ RefPtr<CounterNode> newParent = nullptr;
+ RefPtr<CounterNode> newPreviousSibling = nullptr;
findPlaceForCounter(renderer, it->key, node->hasResetType(), newParent, newPreviousSibling);
if (node != counterMap->get(it->key))
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderCounter.h b/chromium/third_party/WebKit/Source/core/rendering/RenderCounter.h
index 85cdff3b643..15d2b518cbb 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderCounter.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderCounter.h
@@ -43,12 +43,12 @@ public:
void updateCounter();
protected:
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
private:
- virtual const char* renderName() const;
- virtual bool isCounter() const;
- virtual PassRefPtr<StringImpl> originalText() const;
+ virtual const char* renderName() const OVERRIDE;
+ virtual bool isCounter() const OVERRIDE;
+ virtual PassRefPtr<StringImpl> originalText() const OVERRIDE;
// Removes the reference to the CounterNode associated with this renderer.
// This is used to cause a counter display update when the CounterNode tree changes.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
index 9babdc2aae7..6a4ca48a297 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
@@ -26,6 +26,7 @@
#include "core/rendering/RenderDeprecatedFlexibleBox.h"
#include "core/frame/UseCounter.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
@@ -182,10 +183,10 @@ static LayoutUnit contentHeightForChild(RenderBox* child)
return child->logicalHeight() - child->borderAndPaddingLogicalHeight();
}
-void RenderDeprecatedFlexibleBox::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderDeprecatedFlexibleBox::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
RenderStyle* oldStyle = style();
- if (oldStyle && !oldStyle->lineClamp().isNone() && newStyle->lineClamp().isNone())
+ if (oldStyle && !oldStyle->lineClamp().isNone() && newStyle.lineClamp().isNone())
clearLineClamp();
RenderBlock::styleWillChange(diff, newStyle);
@@ -228,19 +229,21 @@ void RenderDeprecatedFlexibleBox::computePreferredLogicalWidths()
ASSERT(preferredLogicalWidthsDirty());
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0;
- if (style()->width().isFixed() && style()->width().value() > 0)
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
+ RenderStyle* styleToUse = style();
+
+ if (styleToUse->width().isFixed() && styleToUse->width().value() > 0)
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->width().value());
else
computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
- if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
- m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
- m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
+ if (styleToUse->minWidth().isFixed() && styleToUse->minWidth().value() > 0) {
+ m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
+ m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
}
- if (style()->maxWidth().isFixed()) {
- m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
- m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
+ if (styleToUse->maxWidth().isFixed()) {
+ m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
+ m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
}
LayoutUnit borderAndPadding = borderAndPaddingLogicalWidth();
@@ -250,60 +253,57 @@ void RenderDeprecatedFlexibleBox::computePreferredLogicalWidths()
clearPreferredLogicalWidthsDirty();
}
-void RenderDeprecatedFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit)
+void RenderDeprecatedFlexibleBox::layoutBlock(bool relayoutChildren)
{
ASSERT(needsLayout());
if (!relayoutChildren && simplifiedLayout())
return;
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+ LayoutRepainter repainter(*this, checkForPaintInvalidationDuringLayout());
- // Regions changing widths can force us to relayout our children.
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (logicalWidthChangedInRegions(flowThread))
- relayoutChildren = true;
- if (updateRegionsAndShapesLogicalSize(flowThread))
- relayoutChildren = true;
+ {
+ // LayoutState needs this deliberate scope to pop before repaint
+ LayoutState state(*this, locationOffset());
- LayoutSize previousSize = size();
+ LayoutSize previousSize = size();
- updateLogicalWidth();
- updateLogicalHeight();
+ updateLogicalWidth();
+ updateLogicalHeight();
- if (previousSize != size()
- || (parent()->isDeprecatedFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL
- && parent()->style()->boxAlign() == BSTRETCH))
- relayoutChildren = true;
+ FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
- setHeight(0);
+ if (previousSize != size()
+ || (parent()->isDeprecatedFlexibleBox() && parent()->style()->boxOrient() == HORIZONTAL
+ && parent()->style()->boxAlign() == BSTRETCH))
+ relayoutChildren = true;
- m_stretchingChildren = false;
+ setHeight(0);
- if (isHorizontal())
- layoutHorizontalBox(relayoutChildren);
- else
- layoutVerticalBox(relayoutChildren);
+ m_stretchingChildren = false;
- LayoutUnit oldClientAfterEdge = clientLogicalBottom();
- updateLogicalHeight();
+ if (isHorizontal())
+ layoutHorizontalBox(relayoutChildren);
+ else
+ layoutVerticalBox(relayoutChildren);
- if (previousSize.height() != height())
- relayoutChildren = true;
+ LayoutUnit oldClientAfterEdge = clientLogicalBottom();
+ updateLogicalHeight();
- layoutPositionedObjects(relayoutChildren || isRoot());
+ if (previousSize.height() != height())
+ relayoutChildren = true;
- computeRegionRangeForBlock(flowThread);
+ layoutPositionedObjects(relayoutChildren || isDocumentElement());
- computeOverflow(oldClientAfterEdge);
+ computeRegionRangeForBlock(flowThreadContainingBlock());
- statePusher.pop();
+ computeOverflow(oldClientAfterEdge);
+ }
- updateLayerTransform();
+ updateLayerTransformAfterLayout();
if (view()->layoutState()->pageLogicalHeight())
- setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(this, logicalTop()));
+ setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(*this, logicalTop()));
// Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not.
@@ -374,7 +374,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
if (child->isOutOfFlowPositioned())
continue;
- SubtreeLayoutScope layoutScope(child);
+ SubtreeLayoutScope layoutScope(*child);
if (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent())))
layoutScope.setChildNeedsLayout(child);
@@ -426,7 +426,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
if (child->isOutOfFlowPositioned()) {
child->containingBlock()->insertPositionedObject(child);
RenderLayer* childLayer = child->layer();
- childLayer->setStaticInlinePosition(xPos); // FIXME: Not right for regions.
+ childLayer->setStaticInlinePosition(xPos);
if (childLayer->staticBlockPosition() != yPos) {
childLayer->setStaticBlockPosition(yPos);
if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
@@ -442,7 +442,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
continue;
}
- SubtreeLayoutScope layoutScope(child);
+ SubtreeLayoutScope layoutScope(*child);
// We need to see if this child's height has changed, since we make block elements
// fill the height of a containing box by default.
@@ -501,7 +501,7 @@ void RenderDeprecatedFlexibleBox::layoutHorizontalBox(bool relayoutChildren)
bool expanding = remainingSpace > 0;
unsigned int start = expanding ? lowestFlexGroup : highestFlexGroup;
unsigned int end = expanding? highestFlexGroup : lowestFlexGroup;
- for (unsigned int i = start; i <= end && remainingSpace; i++) {
+ for (unsigned i = start; i <= end && remainingSpace; i++) {
// Always start off by assuming the group can get all the remaining space.
LayoutUnit groupRemainingSpace = remainingSpace;
do {
@@ -664,7 +664,7 @@ void RenderDeprecatedFlexibleBox::layoutVerticalBox(bool relayoutChildren)
if (child->isOutOfFlowPositioned()) {
child->containingBlock()->insertPositionedObject(child);
RenderLayer* childLayer = child->layer();
- childLayer->setStaticInlinePosition(borderStart() + paddingStart()); // FIXME: Not right for regions.
+ childLayer->setStaticInlinePosition(borderStart() + paddingStart());
if (childLayer->staticBlockPosition() != height()) {
childLayer->setStaticBlockPosition(height());
if (child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
@@ -673,7 +673,7 @@ void RenderDeprecatedFlexibleBox::layoutVerticalBox(bool relayoutChildren)
continue;
}
- SubtreeLayoutScope layoutScope(child);
+ SubtreeLayoutScope layoutScope(*child);
if (!haveLineClamp && (relayoutChildren || (child->isReplaced() && (child->style()->width().isPercent() || child->style()->height().isPercent()))))
layoutScope.setChildNeedsLayout(child);
@@ -755,7 +755,7 @@ void RenderDeprecatedFlexibleBox::layoutVerticalBox(bool relayoutChildren)
bool expanding = remainingSpace > 0;
unsigned int start = expanding ? lowestFlexGroup : highestFlexGroup;
unsigned int end = expanding? highestFlexGroup : lowestFlexGroup;
- for (unsigned int i = start; i <= end && remainingSpace; i++) {
+ for (unsigned i = start; i <= end && remainingSpace; i++) {
// Always start off by assuming the group can get all the remaining space.
LayoutUnit groupRemainingSpace = remainingSpace;
do {
@@ -945,36 +945,36 @@ void RenderDeprecatedFlexibleBox::applyLineClamp(FlexBoxIterator& iterator, bool
const Font& font = style(numVisibleLines == 1)->font();
// Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too
- LayoutUnit totalWidth;
+ float totalWidth;
InlineBox* anchorBox = lastLine->lastChild();
- if (anchorBox && anchorBox->renderer()->style()->isLink())
- totalWidth = anchorBox->logicalWidth() + font.width(RenderBlockFlow::constructTextRun(this, font, ellipsisAndSpace, 2, style()));
+ if (anchorBox && anchorBox->renderer().style()->isLink())
+ totalWidth = anchorBox->logicalWidth() + font.width(RenderBlockFlow::constructTextRun(this, font, ellipsisAndSpace, 2, style(), style()->direction()));
else {
anchorBox = 0;
- totalWidth = font.width(RenderBlockFlow::constructTextRun(this, font, &horizontalEllipsis, 1, style()));
+ totalWidth = font.width(RenderBlockFlow::constructTextRun(this, font, &horizontalEllipsis, 1, style(), style()->direction()));
}
// See if this width can be accommodated on the last visible line
- RenderBlock* destBlock = toRenderBlock(lastVisibleLine->renderer());
- RenderBlock* srcBlock = toRenderBlock(lastLine->renderer());
+ RenderBlockFlow& destBlock = lastVisibleLine->block();
+ RenderBlockFlow& srcBlock = lastLine->block();
// FIXME: Directions of src/destBlock could be different from our direction and from one another.
- if (!srcBlock->style()->isLeftToRightDirection())
+ if (!srcBlock.style()->isLeftToRightDirection())
continue;
- bool leftToRight = destBlock->style()->isLeftToRightDirection();
+ bool leftToRight = destBlock.style()->isLeftToRightDirection();
if (!leftToRight)
continue;
- LayoutUnit blockRightEdge = destBlock->logicalRightOffsetForLine(lastVisibleLine->y(), false);
+ LayoutUnit blockRightEdge = destBlock.logicalRightOffsetForLine(lastVisibleLine->y(), false);
if (!lastVisibleLine->lineCanAccommodateEllipsis(leftToRight, blockRightEdge, lastVisibleLine->x() + lastVisibleLine->logicalWidth(), totalWidth))
continue;
// Let the truncation code kick in.
// FIXME: the text alignment should be recomputed after the width changes due to truncation.
- LayoutUnit blockLeftEdge = destBlock->logicalLeftOffsetForLine(lastVisibleLine->y(), false);
- lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, leftToRight, blockLeftEdge, blockRightEdge, totalWidth, anchorBox);
- destBlock->setHasMarkupTruncation(true);
+ LayoutUnit blockLeftEdge = destBlock.logicalLeftOffsetForLine(lastVisibleLine->y(), false);
+ lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, leftToRight, blockLeftEdge.toFloat(), blockRightEdge.toFloat(), totalWidth, anchorBox);
+ destBlock.setHasMarkupTruncation(true);
}
}
@@ -1002,13 +1002,16 @@ void RenderDeprecatedFlexibleBox::placeChild(RenderBox* child, const LayoutPoint
{
LayoutRect oldRect = child->frameRect();
+ // FIXME Investigate if this can be removed based on other flags. crbug.com/370010
+ child->setMayNeedPaintInvalidation(true);
+
// Place the child.
child->setLocation(location);
// If the child moved, we have to repaint it as well as any floating/positioned
// descendants. An exception is if we need a layout. In this case, we know we're going to
// repaint ourselves (and the child) anyway.
- if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
+ if (!selfNeedsLayout() && child->checkForPaintInvalidationDuringLayout())
child->repaintDuringLayoutIfMoved(oldRect);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.h b/chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.h
index ff039dacb2b..f6576ab2c95 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderDeprecatedFlexibleBox.h
@@ -36,17 +36,17 @@ public:
static RenderDeprecatedFlexibleBox* createAnonymous(Document*);
- virtual const char* renderName() const;
+ virtual const char* renderName() const OVERRIDE;
- virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE;
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
- virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageHeight = 0);
+ virtual void layoutBlock(bool relayoutChildren) OVERRIDE;
void layoutHorizontalBox(bool relayoutChildren);
void layoutVerticalBox(bool relayoutChildren);
- virtual bool avoidsFloats() const { return true; }
- virtual bool isDeprecatedFlexibleBox() const { return true; }
- virtual bool isStretchingChildren() const { return m_stretchingChildren; }
+ virtual bool avoidsFloats() const OVERRIDE { return true; }
+ virtual bool isDeprecatedFlexibleBox() const OVERRIDE { return true; }
+ bool isStretchingChildren() const { return m_stretchingChildren; }
virtual bool canCollapseAnonymousBlockChild() const OVERRIDE { return false; }
void placeChild(RenderBox* child, const LayoutPoint& location);
@@ -64,12 +64,12 @@ protected:
bool m_stretchingChildren;
private:
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
void applyLineClamp(FlexBoxIterator&, bool relayoutChildren);
void clearLineClamp();
};
+DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderDeprecatedFlexibleBox, isDeprecatedFlexibleBox());
+
} // namespace WebCore
#endif // RenderDeprecatedFlexibleBox_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.cpp
index 68e6083489c..a793c342fa4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.cpp
@@ -21,8 +21,9 @@
#include "config.h"
#include "core/rendering/RenderDetailsMarker.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Element.h"
+#include "core/html/HTMLElement.h"
#include "core/rendering/PaintInfo.h"
#include "platform/graphics/GraphicsContext.h"
@@ -106,8 +107,8 @@ Path RenderDetailsMarker::getCanonicalPath() const
Path RenderDetailsMarker::getPath(const LayoutPoint& origin) const
{
Path result = getCanonicalPath();
- result.transform(AffineTransform().scale(contentWidth(), contentHeight()));
- result.translate(FloatSize(origin.x(), origin.y()));
+ result.transform(AffineTransform().scale(contentWidth().toFloat(), contentHeight().toFloat()));
+ result.translate(FloatSize(origin.x().toFloat(), origin.y().toFloat()));
return result;
}
@@ -121,7 +122,6 @@ void RenderDetailsMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOf
LayoutPoint boxOrigin(paintOffset + location());
LayoutRect overflowRect(visualOverflowRect());
overflowRect.moveBy(boxOrigin);
- overflowRect.inflate(maximalOutlineSize(paintInfo.phase));
if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect)))
return;
@@ -141,9 +141,9 @@ bool RenderDetailsMarker::isOpen() const
for (RenderObject* renderer = parent(); renderer; renderer = renderer->parent()) {
if (!renderer->node())
continue;
- if (renderer->node()->hasTagName(detailsTag))
+ if (isHTMLDetailsElement(*renderer->node()))
return !toElement(renderer->node())->getAttribute(openAttr).isNull();
- if (renderer->node()->hasTagName(inputTag))
+ if (isHTMLInputElement(*renderer->node()))
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.h b/chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.h
index aa996c818a2..5b20924b5bc 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderDetailsMarker.h
@@ -34,10 +34,9 @@ public:
Orientation orientation() const;
private:
- virtual const char* renderName() const { return "RenderDetailsMarker"; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
- virtual bool isDetailsMarker() const { return true; }
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual const char* renderName() const OVERRIDE { return "RenderDetailsMarker"; }
+ virtual bool isDetailsMarker() const OVERRIDE { return true; }
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
bool isOpen() const;
Path getCanonicalPath() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.cpp
index 376aab5c5d8..fdd906df36b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.cpp
@@ -24,14 +24,14 @@
#include "config.h"
#include "core/rendering/RenderEmbeddedObject.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/frame/Frame.h"
+#include "core/html/HTMLPlugInElement.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/plugins/PluginView.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
@@ -54,7 +54,6 @@ static const float replacementTextTextOpacity = 0.55f;
RenderEmbeddedObject::RenderEmbeddedObject(Element* element)
: RenderPart(element)
- , m_hasFallbackContent(false)
, m_showsUnavailablePluginIndicator(false)
{
view()->frameView()->setIsVisuallyNonEmpty();
@@ -64,17 +63,16 @@ RenderEmbeddedObject::~RenderEmbeddedObject()
{
}
-bool RenderEmbeddedObject::requiresLayer() const
+LayerType RenderEmbeddedObject::layerTypeRequired() const
{
- if (RenderPart::requiresLayer())
- return true;
-
- return allowsAcceleratedCompositing();
-}
-
-bool RenderEmbeddedObject::allowsAcceleratedCompositing() const
-{
- return widget() && widget()->isPluginView() && toPluginView(widget())->platformLayer();
+ // This can't just use RenderPart::layerTypeRequired, because RenderLayerCompositor
+ // doesn't loop through RenderEmbeddedObjects the way it does frames in order
+ // to update the self painting bit on their RenderLayer.
+ // Also, unlike iframes, embeds don't used the usesCompositing bit on RenderView
+ // in requiresAcceleratedCompositing.
+ if (requiresAcceleratedCompositing())
+ return NormalLayer;
+ return RenderPart::layerTypeRequired();
}
static String unavailablePluginReplacementText(Node* node, RenderEmbeddedObject::PluginUnavailabilityReason pluginUnavailabilityReason)
@@ -108,7 +106,7 @@ bool RenderEmbeddedObject::showsUnavailablePluginIndicator() const
void RenderEmbeddedObject::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
Element* element = toElement(node());
- if (!element || !element->isPluginElement())
+ if (!isHTMLPlugInElement(element))
return;
RenderPart::paintContents(paintInfo, paintOffset);
@@ -147,7 +145,7 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint
GraphicsContextStateSaver stateSaver(*context);
context->clip(contentRect);
- context->setAlpha(replacementTextRoundedRectOpacity);
+ context->setAlphaAsFloat(replacementTextRoundedRectOpacity);
context->setFillColor(Color::white);
context->fillPath(path);
@@ -156,7 +154,7 @@ void RenderEmbeddedObject::paintReplaced(PaintInfo& paintInfo, const LayoutPoint
float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent());
TextRunPaintInfo runInfo(run);
runInfo.bounds = replacementTextRect;
- context->setAlpha(replacementTextTextOpacity);
+ context->setAlphaAsFloat(replacementTextTextOpacity);
context->setFillColor(Color::black);
context->drawBidiText(font, runInfo, FloatPoint(labelX, labelY));
}
@@ -174,8 +172,8 @@ bool RenderEmbeddedObject::getReplacementTextGeometry(const LayoutPoint& accumul
if (!settings)
return false;
fontDescription.setComputedSize(fontDescription.specifiedSize());
- font = Font(fontDescription, 0, 0);
- font.update(0);
+ font = Font(fontDescription);
+ font.update(nullptr);
run = TextRun(m_unavailablePluginReplacementText);
textWidth = font.width(run);
@@ -194,83 +192,37 @@ void RenderEmbeddedObject::layout()
{
ASSERT(needsLayout());
- LayoutSize oldSize = contentBoxRect().size();
- LayoutRectRecorder recorder(*this);
-
updateLogicalWidth();
updateLogicalHeight();
- RenderPart::layout();
-
m_overflow.clear();
addVisualEffectOverflow();
- updateLayerTransform();
+ updateLayerTransformAfterLayout();
if (!widget() && frameView())
frameView()->addWidgetToUpdate(*this);
clearNeedsLayout();
-
- if (!canHaveChildren())
- return;
-
- // This code copied from RenderMedia::layout().
- RenderObject* child = m_children.firstChild();
-
- if (!child)
- return;
-
- RenderBox* childBox = toRenderBox(child);
-
- if (!childBox)
- return;
-
- LayoutSize newSize = contentBoxRect().size();
- if (newSize == oldSize && !childBox->needsLayout())
- return;
-
- // When calling layout() on a child node, a parent must either push a LayoutStateMaintainter, or
- // instantiate LayoutStateDisabler. Since using a LayoutStateMaintainer is slightly more efficient,
- // and this method will be called many times per second during playback, use a LayoutStateMaintainer:
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
-
- childBox->setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
- childBox->style()->setHeight(Length(newSize.height(), Fixed));
- childBox->style()->setWidth(Length(newSize.width(), Fixed));
- childBox->forceLayout();
- clearNeedsLayout();
-
- statePusher.pop();
}
-void RenderEmbeddedObject::viewCleared()
+bool RenderEmbeddedObject::scroll(ScrollDirection direction, ScrollGranularity granularity, float)
{
- // This is required for <object> elements whose contents are rendered by WebCore (e.g. src="foo.html").
- if (node() && widget() && widget()->isFrameView()) {
- FrameView* view = toFrameView(widget());
- int marginWidth = -1;
- int marginHeight = -1;
- if (node()->hasTagName(iframeTag)) {
- HTMLIFrameElement* frame = toHTMLIFrameElement(node());
- marginWidth = frame->marginWidth();
- marginHeight = frame->marginHeight();
- }
- if (marginWidth != -1)
- view->setMarginWidth(marginWidth);
- if (marginHeight != -1)
- view->setMarginHeight(marginHeight);
- }
+ return false;
}
-bool RenderEmbeddedObject::scroll(ScrollDirection direction, ScrollGranularity granularity, float)
+CompositingReasons RenderEmbeddedObject::additionalCompositingReasons(CompositingTriggerFlags triggers) const
{
- return false;
+ if (requiresAcceleratedCompositing())
+ return CompositingReasonPlugin;
+ return CompositingReasonNone;
}
-bool RenderEmbeddedObject::canHaveChildren() const
+RenderBox* RenderEmbeddedObject::embeddedContentBox() const
{
- return false;
+ if (!node() || !widget() || !widget()->isFrameView())
+ return 0;
+ return toFrameView(widget())->embeddedContentBox();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.h b/chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.h
index 679658ec445..a33e28300b9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderEmbeddedObject.h
@@ -27,7 +27,6 @@
namespace WebCore {
-class MouseEvent;
class TextRun;
// Renderer for embeds and objects, often, but not always, rendered via plug-ins.
@@ -44,47 +43,32 @@ public:
void setPluginUnavailabilityReason(PluginUnavailabilityReason);
bool showsUnavailablePluginIndicator() const;
- // FIXME: This belongs on HTMLObjectElement.
- bool hasFallbackContent() const { return m_hasFallbackContent; }
- void setHasFallbackContent(bool hasFallbackContent) { m_hasFallbackContent = hasFallbackContent; }
-
- bool allowsAcceleratedCompositing() const;
-
protected:
virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE FINAL;
virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE FINAL;
- const RenderObjectChildList* children() const { return &m_children; }
- RenderObjectChildList* children() { return &m_children; }
-
protected:
virtual void layout() OVERRIDE FINAL;
private:
- virtual const char* renderName() const { return "RenderEmbeddedObject"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderEmbeddedObject"; }
virtual bool isEmbeddedObject() const OVERRIDE FINAL { return true; }
+ virtual RenderBox* embeddedContentBox() const OVERRIDE FINAL;
void paintSnapshotImage(PaintInfo&, const LayoutPoint&, Image*);
virtual void paintContents(PaintInfo&, const LayoutPoint&) OVERRIDE FINAL;
- virtual bool requiresLayer() const OVERRIDE FINAL;
-
- virtual void viewCleared() OVERRIDE FINAL;
+ virtual LayerType layerTypeRequired() const OVERRIDE FINAL;
virtual bool scroll(ScrollDirection, ScrollGranularity, float multiplier) OVERRIDE FINAL;
bool getReplacementTextGeometry(const LayoutPoint& accumulatedOffset, FloatRect& contentRect, Path&, FloatRect& replacementTextRect, Font&, TextRun&, float& textWidth) const;
- virtual bool canHaveChildren() const OVERRIDE FINAL;
- virtual RenderObjectChildList* virtualChildren() OVERRIDE FINAL { return children(); }
- virtual const RenderObjectChildList* virtualChildren() const OVERRIDE FINAL { return children(); }
-
- bool m_hasFallbackContent; // FIXME: This belongs on HTMLObjectElement.
+ virtual CompositingReasons additionalCompositingReasons(CompositingTriggerFlags) const OVERRIDE;
bool m_showsUnavailablePluginIndicator;
PluginUnavailabilityReason m_pluginUnavailabilityReason;
String m_unavailablePluginReplacementText;
- RenderObjectChildList m_children;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderEmbeddedObject, isEmbeddedObject());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.cpp
index b3962cf6f0a..bf1de947644 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.cpp
@@ -24,8 +24,9 @@
#include "config.h"
#include "core/rendering/RenderFieldset.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
+#include "core/html/HTMLLegendElement.h"
#include "core/rendering/PaintInfo.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
@@ -43,7 +44,7 @@ RenderFieldset::RenderFieldset(Element* element)
void RenderFieldset::computePreferredLogicalWidths()
{
- RenderBlock::computePreferredLogicalWidths();
+ RenderBlockFlow::computePreferredLogicalWidths();
if (RenderBox* legend = findLegend()) {
int legendMinWidth = legend->minPreferredLogicalWidth();
@@ -65,7 +66,7 @@ RenderObject* RenderFieldset::layoutSpecialExcludedChild(bool relayoutChildren,
RenderBox* legend = findLegend();
if (legend) {
if (relayoutChildren)
- legend->setNeedsLayout();
+ legend->setNeedsLayoutAndFullPaintInvalidation();
legend->layoutIfNeeded();
LayoutUnit logicalLeft;
@@ -129,7 +130,7 @@ RenderBox* RenderFieldset::findLegend(FindLegendOption option) const
if (option == IgnoreFloatingOrOutOfFlow && legend->isFloatingOrOutOfFlowPositioned())
continue;
- if (legend->node() && (legend->node()->hasTagName(legendTag)))
+ if (isHTMLLegendElement(legend->node()))
return toRenderBox(legend);
}
return 0;
@@ -143,7 +144,7 @@ void RenderFieldset::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint
LayoutRect paintRect(paintOffset, size());
RenderBox* legend = findLegend();
if (!legend)
- return RenderBlock::paintBoxDecorations(paintInfo, paintOffset);
+ return RenderBlockFlow::paintBoxDecorations(paintInfo, paintOffset);
// FIXME: We need to work with "rl" and "bt" block flow directions. In those
// cases the legend is embedded in the right and bottom borders respectively.
@@ -194,7 +195,7 @@ void RenderFieldset::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOff
LayoutRect paintRect = LayoutRect(paintOffset, size());
RenderBox* legend = findLegend();
if (!legend)
- return RenderBlock::paintMask(paintInfo, paintOffset);
+ return RenderBlockFlow::paintMask(paintInfo, paintOffset);
// FIXME: We need to work with "rl" and "bt" block flow directions. In those
// cases the legend is embedded in the right and bottom borders respectively.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.h b/chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.h
index 944ab4c1dc6..0ebc486eca2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFieldset.h
@@ -36,18 +36,16 @@ public:
RenderBox* findLegend(FindLegendOption = IgnoreFloatingOrOutOfFlow) const;
private:
- virtual const char* renderName() const { return "RenderFieldSet"; }
- virtual bool isFieldset() const { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderFieldSet"; }
+ virtual bool isFieldset() const OVERRIDE { return true; }
- virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&);
+ virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&) OVERRIDE;
- virtual void computePreferredLogicalWidths();
- virtual bool avoidsFloats() const { return true; }
+ virtual void computePreferredLogicalWidths() OVERRIDE;
+ virtual bool avoidsFloats() const OVERRIDE { return true; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
- virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
- virtual void paintMask(PaintInfo&, const LayoutPoint&);
+ virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void paintMask(PaintInfo&, const LayoutPoint&) OVERRIDE;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderFieldset, isFieldset());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.cpp
index 80a822fe74c..9fd7784719c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.cpp
@@ -21,8 +21,7 @@
#include "config.h"
#include "core/rendering/RenderFileUploadControl.h"
-#include <math.h>
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/fileapi/FileList.h"
@@ -34,6 +33,7 @@
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/text/PlatformLocale.h"
#include "platform/text/TextRun.h"
+#include <math.h>
using namespace std;
@@ -73,7 +73,7 @@ void RenderFileUploadControl::updateFromElement()
FileList* files = input->files();
ASSERT(files);
if (files && files->isEmpty())
- repaint();
+ paintInvalidationForWholeRenderer();
}
static int nodeWidth(Node* node)
@@ -131,10 +131,9 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, const LayoutPoin
else
textY = baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
TextRunPaintInfo textRunPaintInfo(textRun);
- textRunPaintInfo.bounds = FloatRect(textX,
- textY - style()->fontMetrics().ascent(),
- textWidth,
- style()->fontMetrics().height());
+ // FIXME: Shouldn't these offsets be rounded? crbug.com/350474
+ textRunPaintInfo.bounds = FloatRect(textX.toFloat(), textY.toFloat() - style()->fontMetrics().ascent(),
+ textWidth, style()->fontMetrics().height());
paintInfo.context->setFillColor(resolveColor(CSSPropertyColor));
@@ -143,7 +142,7 @@ void RenderFileUploadControl::paintObject(PaintInfo& paintInfo, const LayoutPoin
}
// Paint the children.
- RenderBlock::paintObject(paintInfo, paintOffset);
+ RenderBlockFlow::paintObject(paintInfo, paintOffset);
}
void RenderFileUploadControl::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
@@ -174,20 +173,21 @@ void RenderFileUploadControl::computePreferredLogicalWidths()
m_minPreferredLogicalWidth = 0;
m_maxPreferredLogicalWidth = 0;
+ RenderStyle* styleToUse = style();
- if (style()->width().isFixed() && style()->width().value() > 0)
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
+ if (styleToUse->width().isFixed() && styleToUse->width().value() > 0)
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->width().value());
else
computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
- if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
- m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
- m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
+ if (styleToUse->minWidth().isFixed() && styleToUse->minWidth().value() > 0) {
+ m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
+ m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
}
- if (style()->maxWidth().isFixed()) {
- m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
- m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
+ if (styleToUse->maxWidth().isFixed()) {
+ m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
+ m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
}
int toAdd = borderAndPaddingWidth();
@@ -207,7 +207,7 @@ HTMLInputElement* RenderFileUploadControl::uploadButton() const
// FIXME: This should be on HTMLInputElement as an API like innerButtonElement().
HTMLInputElement* input = toHTMLInputElement(node());
Node* buttonNode = input->userAgentShadowRoot()->firstChild();
- return buttonNode && buttonNode->isHTMLElement() && buttonNode->hasTagName(inputTag) ? toHTMLInputElement(buttonNode) : 0;
+ return isHTMLInputElement(buttonNode) ? toHTMLInputElement(buttonNode) : 0;
}
String RenderFileUploadControl::buttonValue()
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.h b/chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.h
index f83bb2a585d..5e2f70410a2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFileUploadControl.h
@@ -36,24 +36,22 @@ public:
RenderFileUploadControl(HTMLInputElement*);
virtual ~RenderFileUploadControl();
- virtual bool isFileUploadControl() const { return true; }
+ virtual bool isFileUploadControl() const OVERRIDE { return true; }
String buttonValue();
String fileTextValue() const;
private:
- virtual const char* renderName() const { return "RenderFileUploadControl"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderFileUploadControl"; }
- virtual void updateFromElement();
+ virtual void updateFromElement() OVERRIDE;
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
- virtual void computePreferredLogicalWidths();
- virtual void paintObject(PaintInfo&, const LayoutPoint&);
-
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual void computePreferredLogicalWidths() OVERRIDE;
+ virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
int maxFilenameWidth() const;
- virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
HTMLInputElement* uploadButton() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.cpp
index 65c82221b62..6114d5654cd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.cpp
@@ -31,11 +31,13 @@
#include "config.h"
#include "core/rendering/RenderFlexibleBox.h"
-#include <limits>
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
+#include "platform/LengthFunctions.h"
#include "wtf/MathExtras.h"
+#include <limits>
namespace WebCore {
@@ -141,8 +143,7 @@ int RenderFlexibleBox::baselinePosition(FontBaseline, bool, LineDirectionMode di
if (baseline == -1)
baseline = synthesizedBaselineFromContentBox(this, direction);
- int marginAscent = direction == HorizontalLine ? marginTop() : marginRight();
- return baseline + marginAscent;
+ return beforeMarginInLineDirection(direction) + baseline;
}
int RenderFlexibleBox::firstLineBoxBaseline() const
@@ -154,7 +155,7 @@ int RenderFlexibleBox::firstLineBoxBaseline() const
for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) {
if (child->isOutOfFlowPositioned())
continue;
- if (alignmentForChild(child) == AlignBaseline && !hasAutoMarginsInCrossAxis(child)) {
+ if (alignmentForChild(child) == ItemPositionBaseline && !hasAutoMarginsInCrossAxis(child)) {
baselineChild = child;
break;
}
@@ -195,37 +196,43 @@ int RenderFlexibleBox::inlineBlockBaseline(LineDirectionMode direction) const
return synthesizedBaselineFromContentBox(this, direction) + marginAscent;
}
-static EAlignItems resolveAlignment(const RenderStyle* parentStyle, const RenderStyle* childStyle)
+static ItemPosition resolveAlignment(const RenderStyle* parentStyle, const RenderStyle* childStyle)
{
- EAlignItems align = childStyle->alignSelf();
- if (align == AlignAuto)
+ ItemPosition align = childStyle->alignSelf();
+ if (align == ItemPositionAuto)
align = parentStyle->alignItems();
return align;
}
+void RenderFlexibleBox::removeChild(RenderObject* child)
+{
+ RenderBlock::removeChild(child);
+ m_intrinsicSizeAlongMainAxis.remove(child);
+}
+
void RenderFlexibleBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderBlock::styleDidChange(diff, oldStyle);
- if (oldStyle && oldStyle->alignItems() == AlignStretch && diff == StyleDifferenceLayout) {
+ if (oldStyle && oldStyle->alignItems() == ItemPositionStretch && diff.needsFullLayout()) {
// Flex items that were previously stretching need to be relayed out so we can compute new available cross axis space.
// This is only necessary for stretching since other alignment values don't change the size of the box.
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
- EAlignItems previousAlignment = resolveAlignment(oldStyle, child->style());
- if (previousAlignment == AlignStretch && previousAlignment != resolveAlignment(style(), child->style()))
+ ItemPosition previousAlignment = resolveAlignment(oldStyle, child->style());
+ if (previousAlignment == ItemPositionStretch && previousAlignment != resolveAlignment(style(), child->style()))
child->setChildNeedsLayout(MarkOnlyThis);
}
}
}
-void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit)
+void RenderFlexibleBox::layoutBlock(bool relayoutChildren)
{
ASSERT(needsLayout());
if (!relayoutChildren && simplifiedLayout())
return;
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+ LayoutRepainter repainter(*this, checkForPaintInvalidationDuringLayout());
if (updateLogicalWidthAndColumnWidth())
relayoutChildren = true;
@@ -233,45 +240,36 @@ void RenderFlexibleBox::layoutBlock(bool relayoutChildren, LayoutUnit)
LayoutUnit previousHeight = logicalHeight();
setLogicalHeight(borderAndPaddingLogicalHeight() + scrollbarLogicalHeight());
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
-
- // Regions changing widths can force us to relayout our children.
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (logicalWidthChangedInRegions(flowThread))
- relayoutChildren = true;
- if (updateRegionsAndShapesLogicalSize(flowThread))
- relayoutChildren = true;
-
- m_numberOfInFlowChildrenOnFirstLine = -1;
+ {
+ FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
+ LayoutState state(*this, locationOffset());
- RenderBlock::startDelayUpdateScrollInfo();
+ m_numberOfInFlowChildrenOnFirstLine = -1;
- prepareOrderIteratorAndMargins();
+ RenderBlock::startDelayUpdateScrollInfo();
- ChildFrameRects oldChildRects;
- appendChildFrameRects(oldChildRects);
+ prepareOrderIteratorAndMargins();
- Vector<LineContext> lineContexts;
- layoutFlexItems(relayoutChildren, lineContexts);
+ ChildFrameRects oldChildRects;
+ appendChildFrameRects(oldChildRects);
- updateLogicalHeight();
- repositionLogicalHeightDependentFlexItems(lineContexts);
+ layoutFlexItems(relayoutChildren);
- RenderBlock::finishDelayUpdateScrollInfo();
+ RenderBlock::finishDelayUpdateScrollInfo();
- if (logicalHeight() != previousHeight)
- relayoutChildren = true;
+ if (logicalHeight() != previousHeight)
+ relayoutChildren = true;
- layoutPositionedObjects(relayoutChildren || isRoot());
+ layoutPositionedObjects(relayoutChildren || isDocumentElement());
- computeRegionRangeForBlock(flowThread);
+ computeRegionRangeForBlock(flowThreadContainingBlock());
- repaintChildrenDuringLayoutIfMoved(oldChildRects);
- // FIXME: css3/flexbox/repaint-rtl-column.html seems to repaint more overflow than it needs to.
- computeOverflow(clientLogicalBottomAfterRepositioning());
- statePusher.pop();
+ repaintChildrenDuringLayoutIfMoved(oldChildRects);
+ // FIXME: css3/flexbox/repaint-rtl-column.html seems to repaint more overflow than it needs to.
+ computeOverflow(clientLogicalBottomAfterRepositioning());
+ }
- updateLayerTransform();
+ updateLayerTransformAfterLayout();
// Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not.
@@ -300,7 +298,7 @@ void RenderFlexibleBox::repaintChildrenDuringLayoutIfMoved(const ChildFrameRects
// If the child moved, we have to repaint it as well as any floating/positioned
// descendants. An exception is if we need a layout. In this case, we know we're going to
// repaint ourselves (and the child) anyway.
- if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
+ if (!selfNeedsLayout() && child->checkForPaintInvalidationDuringLayout())
child->repaintDuringLayoutIfMoved(oldChildRects[childIndex]);
++childIndex;
}
@@ -318,10 +316,6 @@ void RenderFlexibleBox::repositionLogicalHeightDependentFlexItems(Vector<LineCon
LayoutUnit crossAxisStartEdge = lineContexts.isEmpty() ? LayoutUnit() : lineContexts[0].crossAxisOffset;
alignFlexLines(lineContexts);
- // If we have a single line flexbox, the line height is all the available space.
- // For flex-direction: row, this means we need to use the height, so we do this after calling updateLogicalHeight.
- if (!isMultiline() && lineContexts.size() == 1)
- lineContexts[0].crossAxisExtent = crossAxisContentExtent();
alignChildren(lineContexts);
if (style()->flexWrap() == FlexWrapReverse)
@@ -340,7 +334,7 @@ LayoutUnit RenderFlexibleBox::clientLogicalBottomAfterRepositioning()
LayoutUnit childLogicalBottom = logicalTopForChild(child) + logicalHeightForChild(child) + marginAfterForChild(child);
maxChildLogicalBottom = std::max(maxChildLogicalBottom, childLogicalBottom);
}
- return std::max(clientLogicalBottom(), maxChildLogicalBottom);
+ return std::max(clientLogicalBottom(), maxChildLogicalBottom + paddingAfter());
}
bool RenderFlexibleBox::hasOrthogonalFlow(RenderBox* child) const
@@ -381,17 +375,34 @@ Length RenderFlexibleBox::flexBasisForChild(RenderBox* child) const
return flexLength;
}
-void RenderFlexibleBox::setCrossAxisExtent(LayoutUnit extent)
+LayoutUnit RenderFlexibleBox::crossAxisExtentForChild(RenderBox* child) const
{
- if (isHorizontalFlow())
- setHeight(extent);
- else
- setWidth(extent);
+ return isHorizontalFlow() ? child->height() : child->width();
}
-LayoutUnit RenderFlexibleBox::crossAxisExtentForChild(RenderBox* child) const
+static inline LayoutUnit constrainedChildIntrinsicContentLogicalHeight(RenderBox* child)
{
- return isHorizontalFlow() ? child->height() : child->width();
+ LayoutUnit childIntrinsicContentLogicalHeight = child->intrinsicContentLogicalHeight();
+ return child->constrainLogicalHeightByMinMax(childIntrinsicContentLogicalHeight + child->borderAndPaddingLogicalHeight(), childIntrinsicContentLogicalHeight);
+}
+
+LayoutUnit RenderFlexibleBox::childIntrinsicHeight(RenderBox* child) const
+{
+ if (child->isHorizontalWritingMode() && needToStretchChildLogicalHeight(child))
+ return constrainedChildIntrinsicContentLogicalHeight(child);
+ return child->height();
+}
+
+LayoutUnit RenderFlexibleBox::childIntrinsicWidth(RenderBox* child) const
+{
+ if (!child->isHorizontalWritingMode() && needToStretchChildLogicalHeight(child))
+ return constrainedChildIntrinsicContentLogicalHeight(child);
+ return child->width();
+}
+
+LayoutUnit RenderFlexibleBox::crossAxisIntrinsicExtentForChild(RenderBox* child) const
+{
+ return isHorizontalFlow() ? childIntrinsicHeight(child) : childIntrinsicWidth(child);
}
LayoutUnit RenderFlexibleBox::mainAxisExtentForChild(RenderBox* child) const
@@ -439,9 +450,7 @@ LayoutUnit RenderFlexibleBox::computeMainAxisExtentForChild(RenderBox* child, Si
child->layoutIfNeeded();
return child->computeContentLogicalHeight(size, child->logicalHeight() - child->borderAndPaddingLogicalHeight());
}
- // FIXME: Figure out how this should work for regions and pass in the appropriate values.
- RenderRegion* region = 0;
- return child->computeLogicalWidthInRegionUsing(sizeType, size, contentLogicalWidth(), this, region) - child->borderAndPaddingLogicalWidth();
+ return child->computeLogicalWidthUsing(sizeType, size, contentLogicalWidth(), this) - child->borderAndPaddingLogicalWidth();
}
WritingMode RenderFlexibleBox::transformedWritingMode() const
@@ -584,22 +593,6 @@ LayoutUnit RenderFlexibleBox::flowAwareMarginBeforeForChild(RenderBox* child) co
return marginTop();
}
-LayoutUnit RenderFlexibleBox::flowAwareMarginAfterForChild(RenderBox* child) const
-{
- switch (transformedWritingMode()) {
- case TopToBottomWritingMode:
- return child->marginBottom();
- case BottomToTopWritingMode:
- return child->marginTop();
- case LeftToRightWritingMode:
- return child->marginRight();
- case RightToLeftWritingMode:
- return child->marginLeft();
- }
- ASSERT_NOT_REACHED();
- return marginBottom();
-}
-
LayoutUnit RenderFlexibleBox::crossAxisMarginExtentForChild(RenderBox* child) const
{
return isHorizontalFlow() ? child->marginHeight() : child->marginWidth();
@@ -628,54 +621,66 @@ LayoutUnit RenderFlexibleBox::mainAxisBorderAndPaddingExtentForChild(RenderBox*
return isHorizontalFlow() ? child->borderAndPaddingWidth() : child->borderAndPaddingHeight();
}
-LayoutUnit RenderFlexibleBox::mainAxisScrollbarExtentForChild(RenderBox* child) const
+static inline bool preferredMainAxisExtentDependsOnLayout(const Length& flexBasis, bool hasInfiniteLineLength)
+{
+ return flexBasis.isAuto() || (flexBasis.isFixed() && !flexBasis.value() && hasInfiniteLineLength);
+}
+
+bool RenderFlexibleBox::childPreferredMainAxisContentExtentRequiresLayout(RenderBox* child, bool hasInfiniteLineLength) const
{
- return isHorizontalFlow() ? child->verticalScrollbarWidth() : child->horizontalScrollbarHeight();
+ return preferredMainAxisExtentDependsOnLayout(flexBasisForChild(child), hasInfiniteLineLength) && hasOrthogonalFlow(child);
}
-LayoutUnit RenderFlexibleBox::preferredMainAxisContentExtentForChild(RenderBox* child, bool hasInfiniteLineLength)
+LayoutUnit RenderFlexibleBox::preferredMainAxisContentExtentForChild(RenderBox* child, bool hasInfiniteLineLength, bool relayoutChildren)
{
- bool hasOverrideSize = child->hasOverrideWidth() || child->hasOverrideHeight();
- if (hasOverrideSize)
- child->clearOverrideSize();
+ child->clearOverrideSize();
Length flexBasis = flexBasisForChild(child);
- if (flexBasis.isAuto() || (flexBasis.isFixed() && !flexBasis.value() && hasInfiniteLineLength)) {
+ if (preferredMainAxisExtentDependsOnLayout(flexBasis, hasInfiniteLineLength)) {
+ LayoutUnit mainAxisExtent;
if (hasOrthogonalFlow(child)) {
- if (hasOverrideSize)
- child->setChildNeedsLayout(MarkOnlyThis);
- child->layoutIfNeeded();
+ if (child->needsLayout() || relayoutChildren) {
+ m_intrinsicSizeAlongMainAxis.remove(child);
+ child->forceChildLayout();
+ m_intrinsicSizeAlongMainAxis.set(child, child->logicalHeight());
+ }
+ ASSERT(m_intrinsicSizeAlongMainAxis.contains(child));
+ mainAxisExtent = m_intrinsicSizeAlongMainAxis.get(child);
+ } else {
+ mainAxisExtent = child->maxPreferredLogicalWidth();
}
- LayoutUnit mainAxisExtent = hasOrthogonalFlow(child) ? child->logicalHeight() : child->maxPreferredLogicalWidth();
ASSERT(mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child) >= 0);
return mainAxisExtent - mainAxisBorderAndPaddingExtentForChild(child);
}
return std::max(LayoutUnit(0), computeMainAxisExtentForChild(child, MainOrPreferredSize, flexBasis));
}
-void RenderFlexibleBox::layoutFlexItems(bool relayoutChildren, Vector<LineContext>& lineContexts)
+void RenderFlexibleBox::layoutFlexItems(bool relayoutChildren)
{
+ Vector<LineContext> lineContexts;
OrderedFlexItemList orderedChildren;
LayoutUnit sumFlexBaseSize;
double totalFlexGrow;
double totalWeightedFlexShrink;
LayoutUnit sumHypotheticalMainSize;
+ Vector<LayoutUnit, 16> childSizes;
+
m_orderIterator.first();
LayoutUnit crossAxisOffset = flowAwareBorderBefore() + flowAwarePaddingBefore();
bool hasInfiniteLineLength = false;
- while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalWeightedFlexShrink, sumHypotheticalMainSize, hasInfiniteLineLength)) {
+ while (computeNextFlexLine(orderedChildren, sumFlexBaseSize, totalFlexGrow, totalWeightedFlexShrink, sumHypotheticalMainSize, hasInfiniteLineLength, relayoutChildren)) {
LayoutUnit containerMainInnerSize = mainAxisContentExtent(sumHypotheticalMainSize);
LayoutUnit availableFreeSpace = containerMainInnerSize - sumFlexBaseSize;
FlexSign flexSign = (sumHypotheticalMainSize < containerMainInnerSize) ? PositiveFlexibility : NegativeFlexibility;
InflexibleFlexItemSize inflexibleItems;
- Vector<LayoutUnit> childSizes;
+ childSizes.reserveCapacity(orderedChildren.size());
while (!resolveFlexibleLengths(flexSign, orderedChildren, availableFreeSpace, totalFlexGrow, totalWeightedFlexShrink, inflexibleItems, childSizes, hasInfiniteLineLength)) {
ASSERT(totalFlexGrow >= 0 && totalWeightedFlexShrink >= 0);
ASSERT(inflexibleItems.size() > 0);
}
- layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace, relayoutChildren, lineContexts);
+ layoutAndPlaceChildren(crossAxisOffset, orderedChildren, childSizes, availableFreeSpace, relayoutChildren, lineContexts, hasInfiniteLineLength);
}
if (hasLineIfEmpty()) {
// Even if computeNextFlexLine returns true, the flexbox might not have
@@ -688,6 +693,9 @@ void RenderFlexibleBox::layoutFlexItems(bool relayoutChildren, Vector<LineContex
if (height() < minHeight)
setLogicalHeight(minHeight);
}
+
+ updateLogicalHeight();
+ repositionLogicalHeightDependentFlexItems(lineContexts);
}
LayoutUnit RenderFlexibleBox::autoMarginOffsetInMainAxis(const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace)
@@ -752,6 +760,13 @@ LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChild(LayoutUnit lineCro
return lineCrossAxisExtent - childCrossExtent;
}
+LayoutUnit RenderFlexibleBox::availableAlignmentSpaceForChildBeforeStretching(LayoutUnit lineCrossAxisExtent, RenderBox* child)
+{
+ ASSERT(!child->isOutOfFlowPositioned());
+ LayoutUnit childCrossExtent = crossAxisMarginExtentForChild(child) + crossAxisIntrinsicExtentForChild(child);
+ return lineCrossAxisExtent - childCrossExtent;
+}
+
bool RenderFlexibleBox::updateAutoMarginsInCrossAxis(RenderBox* child, LayoutUnit availableAlignmentSpace)
{
ASSERT(!child->isOutOfFlowPositioned());
@@ -814,17 +829,16 @@ LayoutUnit RenderFlexibleBox::marginBoxAscentForChild(RenderBox* child)
return ascent + flowAwareMarginBeforeForChild(child);
}
-LayoutUnit RenderFlexibleBox::computeChildMarginValue(Length margin, RenderView* view)
+LayoutUnit RenderFlexibleBox::computeChildMarginValue(Length margin)
{
// When resolving the margins, we use the content size for resolving percent and calc (for percents in calc expressions) margins.
// Fortunately, percent margins are always computed with respect to the block's width, even for margin-top and margin-bottom.
LayoutUnit availableSize = contentLogicalWidth();
- return minimumValueForLength(margin, availableSize, view);
+ return minimumValueForLength(margin, availableSize);
}
void RenderFlexibleBox::prepareOrderIteratorAndMargins()
{
- RenderView* renderView = view();
OrderIteratorPopulator populator(m_orderIterator);
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
@@ -836,11 +850,11 @@ void RenderFlexibleBox::prepareOrderIteratorAndMargins()
// Before running the flex algorithm, 'auto' has a margin of 0.
// Also, if we're not auto sizing, we don't do a layout that computes the start/end margins.
if (isHorizontalFlow()) {
- child->setMarginLeft(computeChildMarginValue(child->style()->marginLeft(), renderView));
- child->setMarginRight(computeChildMarginValue(child->style()->marginRight(), renderView));
+ child->setMarginLeft(computeChildMarginValue(child->style()->marginLeft()));
+ child->setMarginRight(computeChildMarginValue(child->style()->marginRight()));
} else {
- child->setMarginTop(computeChildMarginValue(child->style()->marginTop(), renderView));
- child->setMarginBottom(computeChildMarginValue(child->style()->marginBottom(), renderView));
+ child->setMarginTop(computeChildMarginValue(child->style()->marginTop()));
+ child->setMarginBottom(computeChildMarginValue(child->style()->marginBottom()));
}
}
}
@@ -861,7 +875,7 @@ LayoutUnit RenderFlexibleBox::adjustChildSizeForMinAndMax(RenderBox* child, Layo
return std::max(childSize, minExtent);
}
-bool RenderFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool& hasInfiniteLineLength)
+bool RenderFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool& hasInfiniteLineLength, bool relayoutChildren)
{
orderedChildren.clear();
sumFlexBaseSize = 0;
@@ -882,7 +896,7 @@ bool RenderFlexibleBox::computeNextFlexLine(OrderedFlexItemList& orderedChildren
continue;
}
- LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild(child, hasInfiniteLineLength);
+ LayoutUnit childMainAxisExtent = preferredMainAxisContentExtentForChild(child, hasInfiniteLineLength, relayoutChildren);
LayoutUnit childMainAxisMarginBorderPadding = mainAxisBorderAndPaddingExtentForChild(child)
+ (isHorizontalFlow() ? child->marginWidth() : child->marginHeight());
LayoutUnit childFlexBaseSize = childMainAxisExtent + childMainAxisMarginBorderPadding;
@@ -916,9 +930,9 @@ void RenderFlexibleBox::freezeViolations(const Vector<Violation>& violations, La
}
// Returns true if we successfully ran the algorithm and sized the flex items.
-bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit>& childSizes, bool hasInfiniteLineLength)
+bool RenderFlexibleBox::resolveFlexibleLengths(FlexSign flexSign, const OrderedFlexItemList& children, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize& inflexibleItems, Vector<LayoutUnit, 16>& childSizes, bool hasInfiniteLineLength)
{
- childSizes.clear();
+ childSizes.resize(0);
LayoutUnit totalViolation = 0;
LayoutUnit usedFreeSpace = 0;
Vector<Violation> minViolations;
@@ -1006,7 +1020,7 @@ void RenderFlexibleBox::prepareChildForPositionedLayout(RenderBox* child, Layout
LayoutUnit inlinePosition = isColumnFlow() ? crossAxisOffset : mainAxisOffset;
if (layoutMode == FlipForRowReverse && style()->flexDirection() == FlowRowReverse)
inlinePosition = mainAxisExtent() - mainAxisOffset;
- childLayer->setStaticInlinePosition(inlinePosition); // FIXME: Not right for regions.
+ childLayer->setStaticInlinePosition(inlinePosition);
LayoutUnit staticBlockPosition = isColumnFlow() ? mainAxisOffset : crossAxisOffset;
if (childLayer->staticBlockPosition() != staticBlockPosition) {
@@ -1016,18 +1030,18 @@ void RenderFlexibleBox::prepareChildForPositionedLayout(RenderBox* child, Layout
}
}
-EAlignItems RenderFlexibleBox::alignmentForChild(RenderBox* child) const
+ItemPosition RenderFlexibleBox::alignmentForChild(RenderBox* child) const
{
- EAlignItems align = resolveAlignment(style(), child->style());
+ ItemPosition align = resolveAlignment(style(), child->style());
- if (align == AlignBaseline && hasOrthogonalFlow(child))
- align = AlignFlexStart;
+ if (align == ItemPositionBaseline && hasOrthogonalFlow(child))
+ align = ItemPositionFlexStart;
if (style()->flexWrap() == FlexWrapReverse) {
- if (align == AlignFlexStart)
- align = AlignFlexEnd;
- else if (align == AlignFlexEnd)
- align = AlignFlexStart;
+ if (align == ItemPositionFlexStart)
+ align = ItemPositionFlexEnd;
+ else if (align == ItemPositionFlexEnd)
+ align = ItemPositionFlexStart;
}
return align;
@@ -1044,22 +1058,33 @@ size_t RenderFlexibleBox::numberOfInFlowPositionedChildren(const OrderedFlexItem
return count;
}
-bool RenderFlexibleBox::needToStretchChild(RenderBox* child)
+void RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis(RenderBox* child)
{
- if (alignmentForChild(child) != AlignStretch)
- return false;
-
- Length crossAxisLength = isHorizontalFlow() ? child->style()->height() : child->style()->width();
- return crossAxisLength.isAuto();
+ if (hasAutoMarginsInCrossAxis(child)) {
+ child->updateLogicalHeight();
+ if (isHorizontalFlow()) {
+ if (child->style()->marginTop().isAuto())
+ child->setMarginTop(0);
+ if (child->style()->marginBottom().isAuto())
+ child->setMarginBottom(0);
+ } else {
+ if (child->style()->marginLeft().isAuto())
+ child->setMarginLeft(0);
+ if (child->style()->marginRight().isAuto())
+ child->setMarginRight(0);
+ }
+ }
}
-void RenderFlexibleBox::resetAutoMarginsAndLogicalTopInCrossAxis(RenderBox* child)
+bool RenderFlexibleBox::needToStretchChildLogicalHeight(RenderBox* child) const
{
- if (hasAutoMarginsInCrossAxis(child))
- child->updateLogicalHeight();
+ if (alignmentForChild(child) != ItemPositionStretch)
+ return false;
+
+ return isHorizontalFlow() && child->style()->height().isAuto();
}
-void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>& lineContexts)
+void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList& children, const Vector<LayoutUnit, 16>& childSizes, LayoutUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>& lineContexts, bool hasInfiniteLineLength)
{
ASSERT(childSizes.size() == children.size());
@@ -1077,27 +1102,32 @@ void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons
bool shouldFlipMainAxis = !isColumnFlow() && !isLeftToRightFlow();
for (size_t i = 0; i < children.size(); ++i) {
RenderBox* child = children[i];
+
if (child->isOutOfFlowPositioned()) {
prepareChildForPositionedLayout(child, mainAxisOffset, crossAxisOffset, FlipForRowReverse);
continue;
}
+ // FIXME Investigate if this can be removed based on other flags. crbug.com/370010
+ child->setMayNeedPaintInvalidation(true);
+
LayoutUnit childPreferredSize = childSizes[i] + mainAxisBorderAndPaddingExtentForChild(child);
setLogicalOverrideSize(child, childPreferredSize);
- // FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905.
- if (needToStretchChild(child) || childPreferredSize != mainAxisExtentForChild(child))
+ if (childPreferredSize != mainAxisExtentForChild(child)) {
child->setChildNeedsLayout(MarkOnlyThis);
- else {
+ } else {
// To avoid double applying margin changes in updateAutoMarginsInCrossAxis, we reset the margins here.
resetAutoMarginsAndLogicalTopInCrossAxis(child);
}
- updateBlockChildDirtyBitsBeforeLayout(relayoutChildren, child);
+ // We may have already forced relayout for orthogonal flowing children in preferredMainAxisContentExtentForChild.
+ bool forceChildRelayout = relayoutChildren && !childPreferredMainAxisContentExtentRequiresLayout(child, hasInfiniteLineLength);
+ updateBlockChildDirtyBitsBeforeLayout(forceChildRelayout, child);
child->layoutIfNeeded();
updateAutoMarginsInMainAxis(child, autoMarginOffset);
LayoutUnit childCrossAxisMarginBoxExtent;
- if (alignmentForChild(child) == AlignBaseline && !hasAutoMarginsInCrossAxis(child)) {
+ if (alignmentForChild(child) == ItemPositionBaseline && !hasAutoMarginsInCrossAxis(child)) {
LayoutUnit ascent = marginBoxAscentForChild(child);
LayoutUnit descent = (crossAxisMarginExtentForChild(child) + crossAxisExtentForChild(child)) - ascent;
@@ -1105,8 +1135,9 @@ void RenderFlexibleBox::layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, cons
maxDescent = std::max(maxDescent, descent);
childCrossAxisMarginBoxExtent = maxAscent + maxDescent;
- } else
- childCrossAxisMarginBoxExtent = crossAxisExtentForChild(child) + crossAxisMarginExtentForChild(child);
+ } else {
+ childCrossAxisMarginBoxExtent = crossAxisIntrinsicExtentForChild(child) + crossAxisMarginExtentForChild(child);
+ }
if (!isColumnFlow())
setLogicalHeight(std::max(logicalHeight(), crossAxisOffset + flowAwareBorderAfter() + flowAwarePaddingAfter() + childCrossAxisMarginBoxExtent + crossAxisScrollbarExtent()));
maxChildCrossAxisExtent = std::max(maxChildCrossAxisExtent, childCrossAxisMarginBoxExtent);
@@ -1157,6 +1188,7 @@ void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children,
size_t seenInFlowPositionedChildren = 0;
for (size_t i = 0; i < children.size(); ++i) {
RenderBox* child = children[i];
+
if (child->isOutOfFlowPositioned()) {
child->layer()->setStaticBlockPosition(mainAxisOffset);
continue;
@@ -1175,6 +1207,8 @@ void RenderFlexibleBox::layoutColumnReverse(const OrderedFlexItemList& children,
static LayoutUnit initialAlignContentOffset(LayoutUnit availableFreeSpace, EAlignContent alignContent, unsigned numberOfLines)
{
+ if (numberOfLines <= 1)
+ return 0;
if (alignContent == AlignContentFlexEnd)
return availableFreeSpace;
if (alignContent == AlignContentCenter)
@@ -1201,7 +1235,15 @@ static LayoutUnit alignContentSpaceBetweenChildren(LayoutUnit availableFreeSpace
void RenderFlexibleBox::alignFlexLines(Vector<LineContext>& lineContexts)
{
- if (!isMultiline() || style()->alignContent() == AlignContentFlexStart)
+ // If we have a single line flexbox or a multiline line flexbox with only one flex line,
+ // the line height is all the available space.
+ // For flex-direction: row, this means we need to use the height, so we do this after calling updateLogicalHeight.
+ if (lineContexts.size() == 1) {
+ lineContexts[0].crossAxisExtent = crossAxisContentExtent();
+ return;
+ }
+
+ if (style()->alignContent() == AlignContentFlexStart)
return;
LayoutUnit availableCrossAxisSpace = crossAxisContentExtent();
@@ -1260,25 +1302,25 @@ void RenderFlexibleBox::alignChildren(const Vector<LineContext>& lineContexts)
continue;
switch (alignmentForChild(child)) {
- case AlignAuto:
+ case ItemPositionAuto:
ASSERT_NOT_REACHED();
break;
- case AlignStretch: {
+ case ItemPositionStretch: {
applyStretchAlignmentToChild(child, lineCrossAxisExtent);
// Since wrap-reverse flips cross start and cross end, strech children should be aligned with the cross end.
if (style()->flexWrap() == FlexWrapReverse)
adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
break;
}
- case AlignFlexStart:
+ case ItemPositionFlexStart:
break;
- case AlignFlexEnd:
+ case ItemPositionFlexEnd:
adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child));
break;
- case AlignCenter:
+ case ItemPositionCenter:
adjustAlignmentForChild(child, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) / 2);
break;
- case AlignBaseline: {
+ case ItemPositionBaseline: {
// FIXME: If we get here in columns, we want the use the descent, except we currently can't get the ascent/descent of orthogonal children.
// https://bugs.webkit.org/show_bug.cgi?id=98076
LayoutUnit ascent = marginBoxAscentForChild(child);
@@ -1289,6 +1331,16 @@ void RenderFlexibleBox::alignChildren(const Vector<LineContext>& lineContexts)
minMarginAfterBaseline = std::min(minMarginAfterBaseline, availableAlignmentSpaceForChild(lineCrossAxisExtent, child) - startOffset);
break;
}
+ case ItemPositionSelfStart:
+ case ItemPositionSelfEnd:
+ case ItemPositionStart:
+ case ItemPositionEnd:
+ case ItemPositionLeft:
+ case ItemPositionRight:
+ // FIXME: File a bug about implementing that. The extended grammar
+ // is not enabled by default so we shouldn't hit this codepath.
+ ASSERT_NOT_REACHED();
+ break;
}
}
minMarginAfterBaselines.append(minMarginAfterBaseline);
@@ -1304,7 +1356,7 @@ void RenderFlexibleBox::alignChildren(const Vector<LineContext>& lineContexts)
LayoutUnit minMarginAfterBaseline = minMarginAfterBaselines[lineNumber];
for (size_t childNumber = 0; childNumber < lineContexts[lineNumber].numberOfChildren; ++childNumber, child = m_orderIterator.next()) {
ASSERT(child);
- if (alignmentForChild(child) == AlignBaseline && !hasAutoMarginsInCrossAxis(child) && minMarginAfterBaseline)
+ if (alignmentForChild(child) == ItemPositionBaseline && !hasAutoMarginsInCrossAxis(child) && minMarginAfterBaseline)
adjustAlignmentForChild(child, minMarginAfterBaseline);
}
}
@@ -1315,9 +1367,10 @@ void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox* child, LayoutUni
if (!isColumnFlow() && child->style()->logicalHeight().isAuto()) {
// FIXME: If the child has orthogonal flow, then it already has an override height set, so use it.
if (!hasOrthogonalFlow(child)) {
- LayoutUnit stretchedLogicalHeight = child->logicalHeight() + availableAlignmentSpaceForChild(lineCrossAxisExtent, child);
+ LayoutUnit heightBeforeStretching = needToStretchChildLogicalHeight(child) ? constrainedChildIntrinsicContentLogicalHeight(child) : child->logicalHeight();
+ LayoutUnit stretchedLogicalHeight = heightBeforeStretching + availableAlignmentSpaceForChildBeforeStretching(lineCrossAxisExtent, child);
ASSERT(!child->needsLayout());
- LayoutUnit desiredLogicalHeight = child->constrainLogicalHeightByMinMax(stretchedLogicalHeight, child->logicalHeight() - child->borderAndPaddingLogicalHeight());
+ LayoutUnit desiredLogicalHeight = child->constrainLogicalHeightByMinMax(stretchedLogicalHeight, heightBeforeStretching - child->borderAndPaddingLogicalHeight());
// FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905.
if (desiredLogicalHeight != child->logicalHeight()) {
@@ -1330,7 +1383,7 @@ void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox* child, LayoutUni
// FIXME: If the child doesn't have orthogonal flow, then it already has an override width set, so use it.
if (hasOrthogonalFlow(child)) {
LayoutUnit childWidth = std::max<LayoutUnit>(0, lineCrossAxisExtent - crossAxisMarginExtentForChild(child));
- childWidth = child->constrainLogicalWidthInRegionByMinMax(childWidth, childWidth, this);
+ childWidth = child->constrainLogicalWidthByMinMax(childWidth, childWidth, this);
if (childWidth != child->logicalWidth()) {
child->setOverrideLogicalContentWidth(childWidth - child->borderAndPaddingLogicalWidth());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.h b/chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.h
index c9297da7001..6a34e899c34 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFlexibleBox.h
@@ -47,8 +47,8 @@ public:
virtual bool isFlexibleBox() const OVERRIDE FINAL { return true; }
virtual bool avoidsFloats() const OVERRIDE FINAL { return true; }
- virtual bool canCollapseAnonymousBlockChild() const OVERRIDE FINAL { return false; }
- virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE FINAL;
+ virtual bool canCollapseAnonymousBlockChild() const OVERRIDE { return false; }
+ virtual void layoutBlock(bool relayoutChildren) OVERRIDE FINAL;
virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
virtual int firstLineBoxBaseline() const OVERRIDE;
@@ -61,9 +61,8 @@ public:
protected:
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+ virtual void removeChild(RenderObject*) OVERRIDE;
private:
enum FlexSign {
@@ -90,8 +89,10 @@ private:
bool isLeftToRightFlow() const;
bool isMultiline() const;
Length flexBasisForChild(RenderBox* child) const;
- void setCrossAxisExtent(LayoutUnit);
LayoutUnit crossAxisExtentForChild(RenderBox* child) const;
+ LayoutUnit crossAxisIntrinsicExtentForChild(RenderBox* child) const;
+ LayoutUnit childIntrinsicHeight(RenderBox* child) const;
+ LayoutUnit childIntrinsicWidth(RenderBox* child) const;
LayoutUnit mainAxisExtentForChild(RenderBox* child) const;
LayoutUnit crossAxisExtent() const;
LayoutUnit mainAxisExtent() const;
@@ -110,19 +111,19 @@ private:
LayoutUnit flowAwareMarginStartForChild(RenderBox* child) const;
LayoutUnit flowAwareMarginEndForChild(RenderBox* child) const;
LayoutUnit flowAwareMarginBeforeForChild(RenderBox* child) const;
- LayoutUnit flowAwareMarginAfterForChild(RenderBox* child) const;
LayoutUnit crossAxisMarginExtentForChild(RenderBox* child) const;
LayoutUnit crossAxisScrollbarExtent() const;
LayoutPoint flowAwareLocationForChild(RenderBox* child) const;
// FIXME: Supporting layout deltas.
void setFlowAwareLocationForChild(RenderBox* child, const LayoutPoint&);
void adjustAlignmentForChild(RenderBox* child, LayoutUnit);
- EAlignItems alignmentForChild(RenderBox* child) const;
+ ItemPosition alignmentForChild(RenderBox* child) const;
LayoutUnit mainAxisBorderAndPaddingExtentForChild(RenderBox* child) const;
- LayoutUnit mainAxisScrollbarExtentForChild(RenderBox* child) const;
- LayoutUnit preferredMainAxisContentExtentForChild(RenderBox* child, bool hasInfiniteLineLength);
+ LayoutUnit preferredMainAxisContentExtentForChild(RenderBox* child, bool hasInfiniteLineLength, bool relayoutChildren = false);
+ bool childPreferredMainAxisContentExtentRequiresLayout(RenderBox* child, bool hasInfiniteLineLength) const;
+ bool needToStretchChildLogicalHeight(RenderBox* child) const;
- void layoutFlexItems(bool relayoutChildren, Vector<LineContext>&);
+ void layoutFlexItems(bool relayoutChildren);
LayoutUnit autoMarginOffsetInMainAxis(const OrderedFlexItemList&, LayoutUnit& availableFreeSpace);
void updateAutoMarginsInMainAxis(RenderBox* child, LayoutUnit autoMarginOffset);
bool hasAutoMarginsInCrossAxis(RenderBox* child) const;
@@ -133,23 +134,23 @@ private:
void repaintChildrenDuringLayoutIfMoved(const ChildFrameRects&);
LayoutUnit availableAlignmentSpaceForChild(LayoutUnit lineCrossAxisExtent, RenderBox*);
+ LayoutUnit availableAlignmentSpaceForChildBeforeStretching(LayoutUnit lineCrossAxisExtent, RenderBox*);
LayoutUnit marginBoxAscentForChild(RenderBox*);
- LayoutUnit computeChildMarginValue(Length margin, RenderView*);
+ LayoutUnit computeChildMarginValue(Length margin);
void prepareOrderIteratorAndMargins();
LayoutUnit adjustChildSizeForMinAndMax(RenderBox*, LayoutUnit childSize);
// The hypothetical main size of an item is the flex base size clamped according to its min and max main size properties
- bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool& hasInfiniteLineLength);
+ bool computeNextFlexLine(OrderedFlexItemList& orderedChildren, LayoutUnit& sumFlexBaseSize, double& totalFlexGrow, double& totalWeightedFlexShrink, LayoutUnit& sumHypotheticalMainSize, bool& hasInfiniteLineLength, bool relayoutChildren);
- bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, Vector<LayoutUnit>& childSizes, bool hasInfiniteLineLength);
+ bool resolveFlexibleLengths(FlexSign, const OrderedFlexItemList&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, Vector<LayoutUnit, 16>& childSizes, bool hasInfiniteLineLength);
void freezeViolations(const Vector<Violation>&, LayoutUnit& availableFreeSpace, double& totalFlexGrow, double& totalWeightedFlexShrink, InflexibleFlexItemSize&, bool hasInfiniteLineLength);
void resetAutoMarginsAndLogicalTopInCrossAxis(RenderBox*);
- bool needToStretchChild(RenderBox*);
void setLogicalOverrideSize(RenderBox* child, LayoutUnit childPreferredSize);
void prepareChildForPositionedLayout(RenderBox* child, LayoutUnit mainAxisOffset, LayoutUnit crossAxisOffset, PositionedLayoutMode);
size_t numberOfInFlowPositionedChildren(const OrderedFlexItemList&) const;
- void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const Vector<LayoutUnit>& childSizes, LayoutUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>&);
+ void layoutAndPlaceChildren(LayoutUnit& crossAxisOffset, const OrderedFlexItemList&, const Vector<LayoutUnit, 16>& childSizes, LayoutUnit availableFreeSpace, bool relayoutChildren, Vector<LineContext>&, bool hasInfiniteLineLength);
void layoutColumnReverse(const OrderedFlexItemList&, LayoutUnit crossAxisOffset, LayoutUnit availableFreeSpace);
void alignFlexLines(Vector<LineContext>&);
void alignChildren(const Vector<LineContext>&);
@@ -157,6 +158,9 @@ private:
void flipForRightToLeftColumn();
void flipForWrapReverse(const Vector<LineContext>&, LayoutUnit crossAxisStartEdge);
+ // This is used to cache the preferred size for orthogonal flow children so we don't have to relayout to get it
+ HashMap<const RenderObject*, LayoutUnit> m_intrinsicSizeAlongMainAxis;
+
mutable OrderIterator m_orderIterator;
int m_numberOfInFlowChildrenOnFirstLine;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.cpp
index 2e9bb88992a..f239e9e5467 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.cpp
@@ -35,9 +35,7 @@
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
-#include "core/rendering/RenderBoxRegionInfo.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderRegion.h"
@@ -49,59 +47,13 @@ namespace WebCore {
RenderFlowThread::RenderFlowThread()
: RenderBlockFlow(0)
- , m_previousRegionCount(0)
- , m_autoLogicalHeightRegionsCount(0)
, m_regionsInvalidated(false)
- , m_regionsHaveUniformLogicalWidth(true)
, m_regionsHaveUniformLogicalHeight(true)
- , m_hasRegionsWithStyling(false)
- , m_dispatchRegionLayoutUpdateEvent(false)
- , m_dispatchRegionOversetChangeEvent(false)
, m_pageLogicalSizeChanged(false)
- , m_inConstrainedLayoutPhase(false)
- , m_needsTwoPhasesLayout(false)
{
setFlowThreadState(InsideOutOfFlowThread);
}
-PassRefPtr<RenderStyle> RenderFlowThread::createFlowThreadStyle(RenderStyle* parentStyle)
-{
- RefPtr<RenderStyle> newStyle(RenderStyle::create());
- newStyle->inheritFrom(parentStyle);
- newStyle->setDisplay(BLOCK);
- newStyle->setPosition(AbsolutePosition);
- newStyle->setZIndex(0);
- newStyle->setLeft(Length(0, Fixed));
- newStyle->setTop(Length(0, Fixed));
- newStyle->setWidth(Length(100, Percent));
- newStyle->setHeight(Length(100, Percent));
- newStyle->font().update(0);
-
- return newStyle.release();
-}
-
-void RenderFlowThread::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderBlock::styleDidChange(diff, oldStyle);
-
- if (oldStyle && oldStyle->writingMode() != style()->writingMode())
- invalidateRegions();
-}
-
-void RenderFlowThread::removeFlowChildInfo(RenderObject* child)
-{
- if (child->isBox())
- removeRenderBoxRegionInfo(toRenderBox(child));
- clearRenderObjectCustomStyle(child);
-}
-
-void RenderFlowThread::addRegionToThread(RenderRegion* renderRegion)
-{
- ASSERT(renderRegion);
- m_regionList.add(renderRegion);
- renderRegion->setIsValid(true);
-}
-
void RenderFlowThread::removeRegionFromThread(RenderRegion* renderRegion)
{
ASSERT(renderRegion);
@@ -116,9 +68,7 @@ void RenderFlowThread::invalidateRegions()
}
m_regionRangeMap.clear();
- m_breakBeforeToRegionMap.clear();
- m_breakAfterToRegionMap.clear();
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
m_regionsInvalidated = true;
}
@@ -148,42 +98,24 @@ void RenderFlowThread::validateRegions()
{
if (m_regionsInvalidated) {
m_regionsInvalidated = false;
- m_regionsHaveUniformLogicalWidth = true;
m_regionsHaveUniformLogicalHeight = true;
if (hasRegions()) {
- LayoutUnit previousRegionLogicalWidth = 0;
LayoutUnit previousRegionLogicalHeight = 0;
bool firstRegionVisited = false;
for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
RenderRegion* region = *iter;
- ASSERT(!region->needsLayout() || region->isRenderRegionSet());
-
- region->deleteAllRenderBoxRegionInfo();
-
- // In the normal layout phase we need to initialize the computedAutoHeight for auto-height regions.
- // See initializeRegionsComputedAutoHeight for the explanation.
- // Also, if we have auto-height regions we can't assume m_regionsHaveUniformLogicalHeight to be true in the first phase
- // because the auto-height regions don't have their height computed yet.
- if (!inConstrainedLayoutPhase() && region->hasAutoLogicalHeight()) {
- region->setComputedAutoHeight(region->maxPageLogicalHeight());
- m_regionsHaveUniformLogicalHeight = false;
- }
-
- LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
LayoutUnit regionLogicalHeight = region->pageLogicalHeight();
if (!firstRegionVisited) {
firstRegionVisited = true;
} else {
- if (m_regionsHaveUniformLogicalWidth && previousRegionLogicalWidth != regionLogicalWidth)
- m_regionsHaveUniformLogicalWidth = false;
if (m_regionsHaveUniformLogicalHeight && previousRegionLogicalHeight != regionLogicalHeight)
m_regionsHaveUniformLogicalHeight = false;
}
- previousRegionLogicalWidth = regionLogicalWidth;
+ previousRegionLogicalHeight = regionLogicalHeight;
}
}
}
@@ -194,54 +126,12 @@ void RenderFlowThread::validateRegions()
void RenderFlowThread::layout()
{
- LayoutRectRecorder recorder(*this);
m_pageLogicalSizeChanged = m_regionsInvalidated && everHadLayout();
- // In case this is the second pass of the normal phase we need to update the auto-height regions to their initial value.
- // If the region chain was invalidated this will happen anyway.
- if (!m_regionsInvalidated && !inConstrainedLayoutPhase())
- initializeRegionsComputedAutoHeight();
-
- validateRegions();
-
- // This is the first phase of the layout and because we have auto-height regions we'll need a second
- // pass to update the flow with the computed auto-height regions.
- m_needsTwoPhasesLayout = !inConstrainedLayoutPhase() && hasAutoLogicalHeightRegions();
-
CurrentRenderFlowThreadMaintainer currentFlowThreadSetter(this);
RenderBlockFlow::layout();
m_pageLogicalSizeChanged = false;
-
- if (lastRegion())
- lastRegion()->expandToEncompassFlowThreadContentsIfNeeded();
-
- if (shouldDispatchRegionLayoutUpdateEvent())
- dispatchRegionLayoutUpdateEvent();
-
- if (shouldDispatchRegionOversetChangeEvent())
- dispatchRegionOversetChangeEvent();
-}
-
-void RenderFlowThread::updateLogicalWidth()
-{
- LayoutUnit logicalWidth = initialLogicalWidth();
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- ASSERT(!region->needsLayout() || region->isRenderRegionSet());
- logicalWidth = max(region->pageLogicalWidth(), logicalWidth);
- }
- setLogicalWidth(logicalWidth);
-
- // If the regions have non-uniform logical widths, then insert inset information for the RenderFlowThread.
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
- if (regionLogicalWidth != logicalWidth) {
- LayoutUnit logicalLeft = style()->direction() == LTR ? LayoutUnit() : logicalWidth - regionLogicalWidth;
- region->setRenderBoxRegionInfo(this, logicalLeft, regionLogicalWidth, false);
- }
- }
}
void RenderFlowThread::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
@@ -251,104 +141,15 @@ void RenderFlowThread::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, L
for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
RenderRegion* region = *iter;
- ASSERT(!region->needsLayout() || region->isRenderRegionSet());
-
computedValues.m_extent += region->logicalHeightOfAllFlowThreadContent();
}
}
-LayoutRect RenderFlowThread::computeRegionClippingRect(const LayoutPoint& offset, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect) const
-{
- LayoutRect regionClippingRect(offset + (flowThreadPortionOverflowRect.location() - flowThreadPortionRect.location()), flowThreadPortionOverflowRect.size());
- if (style()->isFlippedBlocksWritingMode())
- regionClippingRect.move(flowThreadPortionRect.size() - flowThreadPortionOverflowRect.size());
- return regionClippingRect;
-}
-
-void RenderFlowThread::paintFlowThreadPortionInRegion(PaintInfo& paintInfo, RenderRegion* region, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& paintOffset) const
-{
- GraphicsContext* context = paintInfo.context;
- if (!context)
- return;
-
- // RenderFlowThread should start painting its content in a position that is offset
- // from the region rect's current position. The amount of offset is equal to the location of
- // the flow thread portion in the flow thread's local coordinates.
- // Note that we have to pixel snap the location at which we're going to paint, since this is necessary
- // to minimize the amount of incorrect snapping that would otherwise occur.
- // If we tried to paint by applying a non-integral translation, then all the
- // layout code that attempted to pixel snap would be incorrect.
- IntPoint adjustedPaintOffset;
- LayoutPoint portionLocation;
- if (style()->isFlippedBlocksWritingMode()) {
- LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect);
- flipForWritingMode(flippedFlowThreadPortionRect);
- portionLocation = flippedFlowThreadPortionRect.location();
- } else {
- portionLocation = flowThreadPortionRect.location();
- }
- adjustedPaintOffset = roundedIntPoint(paintOffset - portionLocation);
-
- // The clipping rect for the region is set up by assuming the flowThreadPortionRect is going to paint offset from adjustedPaintOffset.
- // Remember that we pixel snapped and moved the paintOffset and stored the snapped result in adjustedPaintOffset. Now we add back in
- // the flowThreadPortionRect's location to get the spot where we expect the portion to actually paint. This can be non-integral and
- // that's ok. We then pixel snap the resulting clipping rect to account for snapping that will occur when the flow thread paints.
- IntRect regionClippingRect = pixelSnappedIntRect(computeRegionClippingRect(adjustedPaintOffset + portionLocation, flowThreadPortionRect, flowThreadPortionOverflowRect));
-
- PaintInfo info(paintInfo);
- info.rect.intersect(regionClippingRect);
-
- if (!info.rect.isEmpty()) {
- context->save();
-
- context->clip(regionClippingRect);
-
- context->translate(adjustedPaintOffset.x(), adjustedPaintOffset.y());
- info.rect.moveBy(-adjustedPaintOffset);
-
- if (info.phase == PaintPhaseTextClip)
- info.paintBehavior = PaintBehaviorForceBlackText;
-
- layer()->paint(context, info.rect, info.paintBehavior, 0, region, PaintLayerTemporaryClipRects);
-
- context->restore();
- }
-}
-
bool RenderFlowThread::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
{
if (hitTestAction == HitTestBlockBackground)
return false;
- return RenderBlock::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction);
-}
-
-bool RenderFlowThread::hitTestFlowThreadPortionInRegion(RenderRegion* region, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const
-{
- LayoutRect regionClippingRect = computeRegionClippingRect(accumulatedOffset, flowThreadPortionRect, flowThreadPortionOverflowRect);
- if (!regionClippingRect.contains(locationInContainer.point()))
- return false;
-
- LayoutSize renderFlowThreadOffset;
- if (style()->isFlippedBlocksWritingMode()) {
- LayoutRect flippedFlowThreadPortionRect(flowThreadPortionRect);
- flipForWritingMode(flippedFlowThreadPortionRect);
- renderFlowThreadOffset = accumulatedOffset - flippedFlowThreadPortionRect.location();
- } else {
- renderFlowThreadOffset = accumulatedOffset - flowThreadPortionRect.location();
- }
-
- // Always ignore clipping, since the RenderFlowThread has nothing to do with the bounds of the FrameView.
- HitTestRequest newRequest(request.type() | HitTestRequest::IgnoreClipping | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
-
- // Make a new temporary HitTestLocation in the new region.
- HitTestLocation newHitTestLocation(locationInContainer, -renderFlowThreadOffset, region);
-
- bool isPointInsideFlowThread = layer()->hitTest(newRequest, newHitTestLocation, result);
-
- // FIXME: Should we set result.m_localPoint back to the RenderRegion's coordinate space or leave it in the RenderFlowThread's coordinate
- // space? Right now it's staying in the RenderFlowThread's coordinate space, which may end up being ok. We will know more when we get around to
- // patching positionForPoint.
- return isPointInsideFlowThread;
+ return RenderBlockFlow::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction);
}
bool RenderFlowThread::shouldRepaint(const LayoutRect& r) const
@@ -364,7 +165,7 @@ void RenderFlowThread::repaintRectangleInRegions(const LayoutRect& repaintRect)
if (!shouldRepaint(repaintRect) || !hasValidRegionInfo())
return;
- LayoutStateDisabler layoutStateDisabler(view()); // We can't use layout state to repaint, since the regions are somewhere else.
+ ForceHorriblySlowRectMapping slowRectMapping(*this); // We can't use layout state to repaint, since the regions are somewhere else.
// We can't use currentFlowThread as it is possible to have interleaved flow threads and the wrong one could be used.
// Let each region figure out the proper enclosing flow thread.
@@ -377,13 +178,10 @@ void RenderFlowThread::repaintRectangleInRegions(const LayoutRect& repaintRect)
}
}
-RenderRegion* RenderFlowThread::regionAtBlockOffset(LayoutUnit offset, bool extendLastRegion, RegionAutoGenerationPolicy autoGenerationPolicy)
+RenderRegion* RenderFlowThread::regionAtBlockOffset(LayoutUnit offset) const
{
ASSERT(!m_regionsInvalidated);
- if (autoGenerationPolicy == AllowRegionAutoGeneration)
- autoGenerateRegionsToBlockOffset(offset);
-
if (offset <= 0)
return m_regionList.isEmpty() ? 0 : m_regionList.first();
@@ -391,38 +189,12 @@ RenderRegion* RenderFlowThread::regionAtBlockOffset(LayoutUnit offset, bool exte
m_regionIntervalTree.allOverlapsWithAdapter<RegionSearchAdapter>(adapter);
// If no region was found, the offset is in the flow thread overflow.
- // The last region will contain the offset if extendLastRegion is set or if the last region is a set.
- if (!adapter.result() && !m_regionList.isEmpty() && (extendLastRegion || m_regionList.last()->isRenderRegionSet()))
+ if (!adapter.result() && !m_regionList.isEmpty())
return m_regionList.last();
return adapter.result();
}
-RenderRegion* RenderFlowThread::regionFromAbsolutePointAndBox(IntPoint absolutePoint, const RenderBox* flowedBox)
-{
- if (!flowedBox)
- return 0;
-
- RenderRegion* startRegion = 0;
- RenderRegion* endRegion = 0;
- getRegionRangeForBox(flowedBox, startRegion, endRegion);
-
- if (!startRegion)
- return 0;
-
- for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- IntRect regionAbsoluteRect(roundedIntPoint(region->localToAbsolute()), roundedIntSize(region->frameRect().size()));
- if (regionAbsoluteRect.contains(absolutePoint))
- return region;
-
- if (region == endRegion)
- break;
- }
-
- return 0;
-}
-
LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const RenderBoxModelObject& boxModelObject, const LayoutPoint& startPoint)
{
LayoutPoint referencePoint = startPoint;
@@ -430,9 +202,8 @@ LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const Rende
// FIXME: This needs to be adapted for different writing modes inside the flow thread.
RenderRegion* startRegion = regionAtBlockOffset(referencePoint.y());
if (startRegion) {
- RenderBoxModelObject* startRegionBox = startRegion->isRenderNamedFlowFragment() ? toRenderBoxModelObject(startRegion->parent()) : startRegion;
// Take into account the offset coordinates of the region.
- RenderObject* currObject = startRegionBox;
+ RenderObject* currObject = startRegion;
RenderObject* currOffsetParentRenderer;
Element* currOffsetParentElement;
while ((currOffsetParentElement = currObject->offsetParent()) && (currOffsetParentRenderer = currOffsetParentElement->renderer())) {
@@ -452,7 +223,7 @@ LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const Rende
// and is no longer valid) and recompute it using the region in which it flows as reference.
bool wasComputedRelativeToOtherRegion = false;
const RenderBlock* objContainingBlock = boxModelObject.containingBlock();
- while (objContainingBlock && !objContainingBlock->isRenderNamedFlowThread()) {
+ while (objContainingBlock) {
// Check if this object is in a different region.
RenderRegion* parentStartRegion = 0;
RenderRegion* parentEndRegion = 0;
@@ -465,12 +236,6 @@ LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const Rende
}
if (wasComputedRelativeToOtherRegion) {
- if (boxModelObject.isBox()) {
- // Use borderBoxRectInRegion to account for variations such as percentage margins.
- LayoutRect borderBoxRect = toRenderBox(&boxModelObject)->borderBoxRectInRegion(startRegion, RenderBox::DoNotCacheRenderBoxRegionInfo);
- referencePoint.move(borderBoxRect.location().x(), 0);
- }
-
// Get the logical top coordinate of the current object.
LayoutUnit top = 0;
if (boxModelObject.isRenderBlock()) {
@@ -489,7 +254,7 @@ LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const Rende
// and compute the object's top, relative to the region's top.
LayoutUnit regionLogicalTop = startRegion->pageLogicalTopForOffset(top);
LayoutUnit topRelativeToRegion = top - regionLogicalTop;
- referencePoint.setY(startRegionBox->offsetTop() + topRelativeToRegion);
+ referencePoint.setY(startRegion->offsetTop() + topRelativeToRegion);
// Since the top has been overriden, check if the
// relative/sticky positioning must be reconsidered.
@@ -501,7 +266,7 @@ LayoutPoint RenderFlowThread::adjustedPositionRelativeToOffsetParent(const Rende
// Since we're looking for the offset relative to the body, we must also
// take into consideration the borders of the region.
- referencePoint.move(startRegionBox->borderLeft(), startRegionBox->borderTop());
+ referencePoint.move(startRegion->borderLeft(), startRegion->borderTop());
}
return referencePoint;
@@ -513,12 +278,6 @@ LayoutUnit RenderFlowThread::pageLogicalTopForOffset(LayoutUnit offset)
return region ? region->pageLogicalTopForOffset(offset) : LayoutUnit();
}
-LayoutUnit RenderFlowThread::pageLogicalWidthForOffset(LayoutUnit offset)
-{
- RenderRegion* region = regionAtBlockOffset(offset, true);
- return region ? region->pageLogicalWidth() : contentLogicalWidth();
-}
-
LayoutUnit RenderFlowThread::pageLogicalHeightForOffset(LayoutUnit offset)
{
RenderRegion* region = regionAtBlockOffset(offset);
@@ -546,125 +305,6 @@ LayoutUnit RenderFlowThread::pageRemainingLogicalHeightForOffset(LayoutUnit offs
return remainingHeight;
}
-RenderRegion* RenderFlowThread::mapFromFlowToRegion(TransformState& transformState) const
-{
- if (!hasValidRegionInfo())
- return 0;
-
- LayoutRect boxRect = transformState.mappedQuad().enclosingBoundingBox();
- flipForWritingMode(boxRect);
-
- // FIXME: We need to refactor RenderObject::absoluteQuads to be able to split the quads across regions,
- // for now we just take the center of the mapped enclosing box and map it to a region.
- // Note: Using the center in order to avoid rounding errors.
-
- LayoutPoint center = boxRect.center();
- RenderRegion* renderRegion = const_cast<RenderFlowThread*>(this)->regionAtBlockOffset(isHorizontalWritingMode() ? center.y() : center.x(), true, DisallowRegionAutoGeneration);
- if (!renderRegion)
- return 0;
-
- LayoutRect flippedRegionRect(renderRegion->flowThreadPortionRect());
- flipForWritingMode(flippedRegionRect);
-
- transformState.move(renderRegion->contentBoxRect().location() - flippedRegionRect.location());
-
- return renderRegion;
-}
-
-void RenderFlowThread::removeRenderBoxRegionInfo(RenderBox* box)
-{
- if (!hasRegions())
- return;
-
- // If the region chain was invalidated the next layout will clear the box information from all the regions.
- if (m_regionsInvalidated) {
- ASSERT(selfNeedsLayout());
- return;
- }
-
- RenderRegion* startRegion;
- RenderRegion* endRegion;
- getRegionRangeForBox(box, startRegion, endRegion);
-
- for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- region->removeRenderBoxRegionInfo(box);
- if (region == endRegion)
- break;
- }
-
-#ifndef NDEBUG
- // We have to make sure we did not leave any RenderBoxRegionInfo attached.
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- ASSERT(!region->renderBoxRegionInfo(box));
- }
-#endif
-
- m_regionRangeMap.remove(box);
-}
-
-bool RenderFlowThread::logicalWidthChangedInRegionsForBlock(const RenderBlock* block)
-{
- if (!hasRegions())
- return false;
-
- RenderRegion* startRegion;
- RenderRegion* endRegion;
- getRegionRangeForBox(block, startRegion, endRegion);
-
- // When the region chain is invalidated the box information is discarded so we must assume the width has changed.
- if (m_pageLogicalSizeChanged && !startRegion)
- return true;
-
- // Not necessary for the flow thread, since we already computed the correct info for it.
- if (block == this)
- return false;
-
- for (RenderRegionList::iterator iter = m_regionList.find(startRegion); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- ASSERT(!region->needsLayout() || region->isRenderRegionSet());
-
- OwnPtr<RenderBoxRegionInfo> oldInfo = region->takeRenderBoxRegionInfo(block);
- if (!oldInfo)
- continue;
-
- LayoutUnit oldLogicalWidth = oldInfo->logicalWidth();
- RenderBoxRegionInfo* newInfo = block->renderBoxRegionInfo(region);
- if (!newInfo || newInfo->logicalWidth() != oldLogicalWidth)
- return true;
-
- if (region == endRegion)
- break;
- }
-
- return false;
-}
-
-LayoutUnit RenderFlowThread::contentLogicalWidthOfFirstRegion() const
-{
- RenderRegion* firstValidRegionInFlow = firstRegion();
- if (!firstValidRegionInFlow)
- return 0;
- return isHorizontalWritingMode() ? firstValidRegionInFlow->contentWidth() : firstValidRegionInFlow->contentHeight();
-}
-
-LayoutUnit RenderFlowThread::contentLogicalHeightOfFirstRegion() const
-{
- RenderRegion* firstValidRegionInFlow = firstRegion();
- if (!firstValidRegionInFlow)
- return 0;
- return isHorizontalWritingMode() ? firstValidRegionInFlow->contentHeight() : firstValidRegionInFlow->contentWidth();
-}
-
-LayoutUnit RenderFlowThread::contentLogicalLeftOfFirstRegion() const
-{
- RenderRegion* firstValidRegionInFlow = firstRegion();
- if (!firstValidRegionInFlow)
- return 0;
- return isHorizontalWritingMode() ? firstValidRegionInFlow->flowThreadPortionRect().x() : firstValidRegionInFlow->flowThreadPortionRect().y();
-}
-
RenderRegion* RenderFlowThread::firstRegion() const
{
if (!hasValidRegionInfo())
@@ -679,44 +319,17 @@ RenderRegion* RenderFlowThread::lastRegion() const
return m_regionList.last();
}
-void RenderFlowThread::clearRenderObjectCustomStyle(const RenderObject* object,
- const RenderRegion* oldStartRegion, const RenderRegion* oldEndRegion,
- const RenderRegion* newStartRegion, const RenderRegion* newEndRegion)
-{
- // Clear the styles for the object in the regions.
- // The styles are not cleared for the regions that are contained in both ranges.
- bool insideOldRegionRange = false;
- bool insideNewRegionRange = false;
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
-
- if (oldStartRegion == region)
- insideOldRegionRange = true;
- if (newStartRegion == region)
- insideNewRegionRange = true;
-
- if (!(insideOldRegionRange && insideNewRegionRange))
- region->clearObjectStyleInRegion(object);
-
- if (oldEndRegion == region)
- insideOldRegionRange = false;
- if (newEndRegion == region)
- insideNewRegionRange = false;
- }
-}
-
void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit offsetFromLogicalTopOfFirstPage)
{
if (!hasRegions())
return;
// FIXME: Not right for differing writing-modes.
- RenderRegion* startRegion = regionAtBlockOffset(offsetFromLogicalTopOfFirstPage, true);
- RenderRegion* endRegion = regionAtBlockOffset(offsetFromLogicalTopOfFirstPage + box->logicalHeight(), true);
+ RenderRegion* startRegion = regionAtBlockOffset(offsetFromLogicalTopOfFirstPage);
+ RenderRegion* endRegion = regionAtBlockOffset(offsetFromLogicalTopOfFirstPage + box->logicalHeight());
RenderRegionRangeMap::iterator it = m_regionRangeMap.find(box);
if (it == m_regionRangeMap.end()) {
m_regionRangeMap.set(box, RenderRegionRange(startRegion, endRegion));
- clearRenderObjectCustomStyle(box);
return;
}
@@ -725,21 +338,6 @@ void RenderFlowThread::setRegionRangeForBox(const RenderBox* box, LayoutUnit off
if (range.startRegion() == startRegion && range.endRegion() == endRegion)
return;
- // Delete any info that we find before our new startRegion and after our new endRegion.
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- if (region == startRegion) {
- iter = m_regionList.find(endRegion);
- continue;
- }
-
- region->removeRenderBoxRegionInfo(box);
-
- if (region == range.endRegion())
- break;
- }
-
- clearRenderObjectCustomStyle(box, range.startRegion(), range.endRegion(), startRegion, endRegion);
range.setRange(startRegion, endRegion);
}
@@ -757,148 +355,15 @@ void RenderFlowThread::getRegionRangeForBox(const RenderBox* box, RenderRegion*&
ASSERT(m_regionList.contains(startRegion) && m_regionList.contains(endRegion));
}
-void RenderFlowThread::applyBreakAfterContent(LayoutUnit clientHeight)
-{
- // Simulate a region break at height. If it points inside an auto logical height region,
- // then it may determine the region computed autoheight.
- addForcedRegionBreak(clientHeight, this, false);
-}
-
-bool RenderFlowThread::regionInRange(const RenderRegion* targetRegion, const RenderRegion* startRegion, const RenderRegion* endRegion) const
-{
- ASSERT(targetRegion);
-
- for (RenderRegionList::const_iterator it = m_regionList.find(const_cast<RenderRegion*>(startRegion)); it != m_regionList.end(); ++it) {
- const RenderRegion* currRegion = *it;
- if (targetRegion == currRegion)
- return true;
- if (currRegion == endRegion)
- break;
- }
-
- return false;
-}
-
-// Check if the content is flown into at least a region with region styling rules.
-void RenderFlowThread::checkRegionsWithStyling()
-{
- bool hasRegionsWithStyling = false;
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- if (region->hasCustomRegionStyle()) {
- hasRegionsWithStyling = true;
- break;
- }
- }
- m_hasRegionsWithStyling = hasRegionsWithStyling;
-}
-
-bool RenderFlowThread::objectInFlowRegion(const RenderObject* object, const RenderRegion* region) const
-{
- ASSERT(object);
- ASSERT(region);
-
- RenderFlowThread* flowThread = object->flowThreadContainingBlock();
- if (flowThread != this)
- return false;
- if (!m_regionList.contains(const_cast<RenderRegion*>(region)))
- return false;
-
- RenderBox* enclosingBox = object->enclosingBox();
- RenderRegion* enclosingBoxStartRegion = 0;
- RenderRegion* enclosingBoxEndRegion = 0;
- getRegionRangeForBox(enclosingBox, enclosingBoxStartRegion, enclosingBoxEndRegion);
- if (!regionInRange(region, enclosingBoxStartRegion, enclosingBoxEndRegion))
- return false;
-
- if (object->isBox())
- return true;
-
- LayoutRect objectABBRect = object->absoluteBoundingBoxRect(true);
- if (!objectABBRect.width())
- objectABBRect.setWidth(1);
- if (!objectABBRect.height())
- objectABBRect.setHeight(1);
- if (objectABBRect.intersects(region->absoluteBoundingBoxRect(true)))
- return true;
-
- if (region == lastRegion()) {
- // If the object does not intersect any of the enclosing box regions
- // then the object is in last region.
- for (RenderRegionList::const_iterator it = m_regionList.find(enclosingBoxStartRegion); it != m_regionList.end(); ++it) {
- const RenderRegion* currRegion = *it;
- if (currRegion == region)
- break;
- if (objectABBRect.intersects(currRegion->absoluteBoundingBoxRect(true)))
- return false;
- }
- return true;
- }
-
- return false;
-}
-
-#ifndef NDEBUG
-bool RenderFlowThread::isAutoLogicalHeightRegionsCountConsistent() const
-{
- unsigned autoLogicalHeightRegions = 0;
- for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- const RenderRegion* region = *iter;
- if (region->hasAutoLogicalHeight())
- autoLogicalHeightRegions++;
- }
-
- return autoLogicalHeightRegions == m_autoLogicalHeightRegionsCount;
-}
-#endif
-
-// During the normal layout phase of the named flow the regions are initialized with a height equal to their max-height.
-// This way unforced breaks are automatically placed when a region is full and the content height/position correctly estimated.
-// Also, the region where a forced break falls is exactly the region found at the forced break offset inside the flow content.
-void RenderFlowThread::initializeRegionsComputedAutoHeight(RenderRegion* startRegion)
-{
- ASSERT(!inConstrainedLayoutPhase());
- if (!hasAutoLogicalHeightRegions())
- return;
-
- RenderRegionList::iterator regionIter = startRegion ? m_regionList.find(startRegion) : m_regionList.begin();
- for (; regionIter != m_regionList.end(); ++regionIter) {
- RenderRegion* region = *regionIter;
- if (region->hasAutoLogicalHeight())
- region->setComputedAutoHeight(region->maxPageLogicalHeight());
- }
-}
-
-void RenderFlowThread::markAutoLogicalHeightRegionsForLayout()
+void RenderFlowThread::updateRegionsFlowThreadPortionRect()
{
- ASSERT(hasAutoLogicalHeightRegions());
-
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- if (!region->hasAutoLogicalHeight())
- continue;
-
- // FIXME: We need to find a way to avoid marking all the regions ancestors for layout
- // as we are already inside layout.
- region->setNeedsLayout();
- }
-}
-
-void RenderFlowThread::updateRegionsFlowThreadPortionRect(const RenderRegion* lastRegionWithContent)
-{
- ASSERT(!lastRegionWithContent || (!inConstrainedLayoutPhase() && hasAutoLogicalHeightRegions()));
LayoutUnit logicalHeight = 0;
- bool emptyRegionsSegment = false;
// FIXME: Optimize not to clear the interval all the time. This implies manually managing the tree nodes lifecycle.
m_regionIntervalTree.clear();
m_regionIntervalTree.initIfNeeded();
for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
RenderRegion* region = *iter;
- // If we find an empty auto-height region, clear the computedAutoHeight value.
- if (emptyRegionsSegment && region->hasAutoLogicalHeight())
- region->clearComputedAutoHeight();
-
LayoutUnit regionLogicalWidth = region->pageLogicalWidth();
LayoutUnit regionLogicalHeight = std::min<LayoutUnit>(RenderFlowThread::maxLogicalHeight() - logicalHeight, region->logicalHeightOfAllFlowThreadContent());
@@ -909,104 +374,7 @@ void RenderFlowThread::updateRegionsFlowThreadPortionRect(const RenderRegion* la
m_regionIntervalTree.add(RegionIntervalTree::createInterval(logicalHeight, logicalHeight + regionLogicalHeight, region));
logicalHeight += regionLogicalHeight;
-
- // Once we find the last region with content the next regions are considered empty.
- if (lastRegionWithContent == region)
- emptyRegionsSegment = true;
}
-
- ASSERT(!lastRegionWithContent || emptyRegionsSegment);
-}
-
-// Even if we require the break to occur at offsetBreakInFlowThread, because regions may have min/max-height values,
-// it is possible that the break will occur at a different offset than the original one required.
-// offsetBreakAdjustment measures the different between the requested break offset and the current break offset.
-bool RenderFlowThread::addForcedRegionBreak(LayoutUnit offsetBreakInFlowThread, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment)
-{
- // We take breaks into account for height computation for auto logical height regions
- // only in the layout phase in which we lay out the flows threads unconstrained
- // and we use the content breaks to determine the computedAutoHeight for
- // auto logical height regions.
- if (inConstrainedLayoutPhase())
- return false;
-
- // Breaks can come before or after some objects. We need to track these objects, so that if we get
- // multiple breaks for the same object (for example because of multiple layouts on the same object),
- // we need to invalidate every other region after the old one and start computing from fresh.
- RenderObjectToRegionMap& mapToUse = isBefore ? m_breakBeforeToRegionMap : m_breakAfterToRegionMap;
- RenderObjectToRegionMap::iterator iter = mapToUse.find(breakChild);
- if (iter != mapToUse.end()) {
- RenderRegionList::iterator regionIter = m_regionList.find(iter->value);
- ASSERT_WITH_SECURITY_IMPLICATION(regionIter != m_regionList.end());
- ASSERT((*regionIter)->hasAutoLogicalHeight());
- initializeRegionsComputedAutoHeight(*regionIter);
-
- // We need to update the regions flow thread portion rect because we are going to process
- // a break on these regions.
- updateRegionsFlowThreadPortionRect();
- }
-
- // Simulate a region break at offsetBreakInFlowThread. If it points inside an auto logical height region,
- // then it determines the region computed auto height.
- RenderRegion* region = regionAtBlockOffset(offsetBreakInFlowThread);
- if (!region)
- return false;
-
- bool lastBreakAfterContent = breakChild == this;
- bool hasComputedAutoHeight = false;
-
- LayoutUnit currentRegionOffsetInFlowThread = isHorizontalWritingMode() ? region->flowThreadPortionRect().y() : region->flowThreadPortionRect().x();
- LayoutUnit offsetBreakInCurrentRegion = offsetBreakInFlowThread - currentRegionOffsetInFlowThread;
-
- if (region->hasAutoLogicalHeight()) {
- // A forced break can appear only in an auto-height region that didn't have a forced break before.
- // This ASSERT is a good-enough heuristic to verify the above condition.
- ASSERT(region->maxPageLogicalHeight() == region->computedAutoHeight());
-
- mapToUse.set(breakChild, region);
-
- hasComputedAutoHeight = true;
-
- // Compute the region height pretending that the offsetBreakInCurrentRegion is the logicalHeight for the auto-height region.
- LayoutUnit regionComputedAutoHeight = region->constrainContentBoxLogicalHeightByMinMax(offsetBreakInCurrentRegion, -1);
-
- // The new height of this region needs to be smaller than the initial value, the max height. A forced break is the only way to change the initial
- // height of an auto-height region besides content ending.
- ASSERT(regionComputedAutoHeight <= region->maxPageLogicalHeight());
-
- region->setComputedAutoHeight(regionComputedAutoHeight);
-
- currentRegionOffsetInFlowThread += regionComputedAutoHeight;
- } else {
- currentRegionOffsetInFlowThread += isHorizontalWritingMode() ? region->flowThreadPortionRect().height() : region->flowThreadPortionRect().width();
- }
-
- // If the break was found inside an auto-height region its size changed so we need to recompute the flow thread portion rectangles.
- // Also, if this is the last break after the content we need to clear the computedAutoHeight value on the last empty regions.
- if (hasAutoLogicalHeightRegions() && lastBreakAfterContent)
- updateRegionsFlowThreadPortionRect(region);
- else if (hasComputedAutoHeight)
- updateRegionsFlowThreadPortionRect();
-
- if (offsetBreakAdjustment)
- *offsetBreakAdjustment = max<LayoutUnit>(0, currentRegionOffsetInFlowThread - offsetBreakInFlowThread);
-
- return hasComputedAutoHeight;
-}
-
-void RenderFlowThread::incrementAutoLogicalHeightRegions()
-{
- if (!m_autoLogicalHeightRegionsCount)
- view()->flowThreadController()->incrementFlowThreadsWithAutoLogicalHeightRegions();
- ++m_autoLogicalHeightRegionsCount;
-}
-
-void RenderFlowThread::decrementAutoLogicalHeightRegions()
-{
- ASSERT(m_autoLogicalHeightRegionsCount > 0);
- --m_autoLogicalHeightRegionsCount;
- if (!m_autoLogicalHeightRegionsCount)
- view()->flowThreadController()->decrementFlowThreadsWithAutoLogicalHeightRegions();
}
void RenderFlowThread::collectLayerFragments(LayerFragments& layerFragments, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect)
@@ -1070,18 +438,18 @@ const RenderBox* RenderFlowThread::currentStatePusherRenderBox() const
return 0;
}
-void RenderFlowThread::pushFlowThreadLayoutState(const RenderObject* object)
+void RenderFlowThread::pushFlowThreadLayoutState(const RenderObject& object)
{
if (const RenderBox* currentBoxDescendant = currentStatePusherRenderBox()) {
LayoutState* layoutState = currentBoxDescendant->view()->layoutState();
if (layoutState && layoutState->isPaginated()) {
ASSERT(layoutState->renderer() == currentBoxDescendant);
- LayoutSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->pageOffset();
setOffsetFromLogicalTopOfFirstRegion(currentBoxDescendant, currentBoxDescendant->isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width());
}
}
- m_statePusherObjectsStack.add(object);
+ m_statePusherObjectsStack.add(&object);
}
void RenderFlowThread::popFlowThreadLayoutState()
@@ -1109,7 +477,7 @@ LayoutUnit RenderFlowThread::offsetFromLogicalTopOfFirstRegion(const RenderBlock
LayoutState* layoutState = view()->layoutState();
ASSERT(layoutState->renderer() == currentBlock);
ASSERT(layoutState && layoutState->isPaginated());
- LayoutSize offsetDelta = layoutState->m_layoutOffset - layoutState->m_pageOffset;
+ LayoutSize offsetDelta = layoutState->layoutOffset() - layoutState->pageOffset();
return currentBoxDescendant->isHorizontalWritingMode() ? offsetDelta.height() : offsetDelta.width();
}
@@ -1148,17 +516,6 @@ void RenderFlowThread::RegionSearchAdapter::collectIfNeeded(const RegionInterval
m_result = interval.data();
}
-void RenderFlowThread::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
-{
- if (this == repaintContainer)
- return;
-
- if (RenderRegion* region = mapFromFlowToRegion(transformState)) {
- // FIXME: The cast below is probably not the best solution, we may need to find a better way.
- static_cast<const RenderObject*>(region)->mapLocalToContainer(region->containerForRepaint(), transformState, mode, wasFixed);
- }
-}
-
CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer(RenderFlowThread* renderFlowThread)
: m_renderFlowThread(renderFlowThread)
, m_previousRenderFlowThread(0)
@@ -1167,7 +524,6 @@ CurrentRenderFlowThreadMaintainer::CurrentRenderFlowThreadMaintainer(RenderFlowT
return;
RenderView* view = m_renderFlowThread->view();
m_previousRenderFlowThread = view->flowThreadController()->currentRenderFlowThread();
- ASSERT(!m_previousRenderFlowThread || !renderFlowThread->isRenderNamedFlowThread());
view->flowThreadController()->setCurrentRenderFlowThread(m_renderFlowThread);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.h b/chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.h
index 7986768361e..12c92fb627b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFlowThread.h
@@ -41,7 +41,6 @@ namespace WebCore {
struct LayerFragment;
typedef Vector<LayerFragment, 1> LayerFragments;
class RenderFlowThread;
-class RenderStyle;
class RenderRegion;
typedef ListHashSet<RenderRegion*> RenderRegionList;
@@ -58,117 +57,58 @@ public:
virtual ~RenderFlowThread() { };
virtual bool isRenderFlowThread() const OVERRIDE FINAL { return true; }
+ virtual bool isRenderMultiColumnFlowThread() const { return false; }
- virtual void layout() OVERRIDE FINAL;
+ virtual void layout() OVERRIDE;
// Always create a RenderLayer for the RenderFlowThread so that we
// can easily avoid drawing the children directly.
- virtual bool requiresLayer() const OVERRIDE FINAL { return true; }
+ virtual LayerType layerTypeRequired() const OVERRIDE FINAL { return NormalLayer; }
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE FINAL;
- void removeFlowChildInfo(RenderObject*);
-#ifndef NDEBUG
- bool hasChildInfo(RenderObject* child) const { return child && child->isBox() && m_regionRangeMap.contains(toRenderBox(child)); }
-#endif
-
- virtual void addRegionToThread(RenderRegion*);
+ virtual void addRegionToThread(RenderRegion*) = 0;
virtual void removeRegionFromThread(RenderRegion*);
const RenderRegionList& renderRegionList() const { return m_regionList; }
- virtual void updateLogicalWidth() OVERRIDE FINAL;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
- void paintFlowThreadPortionInRegion(PaintInfo&, RenderRegion*, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint&) const;
- bool hitTestFlowThreadPortionInRegion(RenderRegion*, const LayoutRect& flowThreadPortionRect, const LayoutRect& flowThreadPortionOverflowRect, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const;
-
bool hasRegions() const { return m_regionList.size(); }
- // Check if the content is flown into at least a region with region styling rules.
- bool hasRegionsWithStyling() const { return m_hasRegionsWithStyling; }
- void checkRegionsWithStyling();
- virtual void regionChangedWritingMode(RenderRegion*) { }
void validateRegions();
void invalidateRegions();
bool hasValidRegionInfo() const { return !m_regionsInvalidated && !m_regionList.isEmpty(); }
- static PassRefPtr<RenderStyle> createFlowThreadStyle(RenderStyle* parentStyle);
-
- void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-
void repaintRectangleInRegions(const LayoutRect&) const;
LayoutPoint adjustedPositionRelativeToOffsetParent(const RenderBoxModelObject&, const LayoutPoint&);
LayoutUnit pageLogicalTopForOffset(LayoutUnit);
- LayoutUnit pageLogicalWidthForOffset(LayoutUnit);
LayoutUnit pageLogicalHeightForOffset(LayoutUnit);
LayoutUnit pageRemainingLogicalHeightForOffset(LayoutUnit, PageBoundaryRule = IncludePageBoundary);
virtual void setPageBreak(LayoutUnit /*offset*/, LayoutUnit /*spaceShortage*/) { }
virtual void updateMinimumPageHeight(LayoutUnit /*offset*/, LayoutUnit /*minHeight*/) { }
- enum RegionAutoGenerationPolicy {
- AllowRegionAutoGeneration,
- DisallowRegionAutoGeneration,
- };
- RenderRegion* regionAtBlockOffset(LayoutUnit, bool extendLastRegion = false, RegionAutoGenerationPolicy = AllowRegionAutoGeneration);
-
- RenderRegion* regionFromAbsolutePointAndBox(IntPoint, const RenderBox* flowedBox);
+ virtual RenderRegion* regionAtBlockOffset(LayoutUnit) const;
- bool regionsHaveUniformLogicalWidth() const { return m_regionsHaveUniformLogicalWidth; }
bool regionsHaveUniformLogicalHeight() const { return m_regionsHaveUniformLogicalHeight; }
- RenderRegion* mapFromFlowToRegion(TransformState&) const;
-
- void removeRenderBoxRegionInfo(RenderBox*);
- bool logicalWidthChangedInRegionsForBlock(const RenderBlock*);
-
- LayoutUnit contentLogicalWidthOfFirstRegion() const;
- LayoutUnit contentLogicalHeightOfFirstRegion() const;
- LayoutUnit contentLogicalLeftOfFirstRegion() const;
-
RenderRegion* firstRegion() const;
RenderRegion* lastRegion() const;
- bool previousRegionCountChanged() const { return m_previousRegionCount != m_regionList.size(); }
- void updatePreviousRegionCount() { m_previousRegionCount = m_regionList.size(); }
-
void setRegionRangeForBox(const RenderBox*, LayoutUnit offsetFromLogicalTopOfFirstPage);
void getRegionRangeForBox(const RenderBox*, RenderRegion*& startRegion, RenderRegion*& endRegion) const;
- void clearRenderObjectCustomStyle(const RenderObject*,
- const RenderRegion* oldStartRegion = 0, const RenderRegion* oldEndRegion = 0,
- const RenderRegion* newStartRegion = 0, const RenderRegion* newEndRegion = 0);
-
- // Check if the object is in region and the region is part of this flow thread.
- bool objectInFlowRegion(const RenderObject*, const RenderRegion*) const;
-
- void markAutoLogicalHeightRegionsForLayout();
-
- bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0);
- void applyBreakAfterContent(LayoutUnit);
+ virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) { return false; }
+ virtual bool isPageLogicalHeightKnown() const { return true; }
bool pageLogicalSizeChanged() const { return m_pageLogicalSizeChanged; }
- bool hasAutoLogicalHeightRegions() const { ASSERT(isAutoLogicalHeightRegionsCountConsistent()); return m_autoLogicalHeightRegionsCount; }
- void incrementAutoLogicalHeightRegions();
- void decrementAutoLogicalHeightRegions();
-
-#ifndef NDEBUG
- bool isAutoLogicalHeightRegionsCountConsistent() const;
-#endif
-
void collectLayerFragments(LayerFragments&, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect);
LayoutRect fragmentsBoundingBox(const LayoutRect& layerBoundingBox);
- void setInConstrainedLayoutPhase(bool value) { m_inConstrainedLayoutPhase = value; }
- bool inConstrainedLayoutPhase() const { return m_inConstrainedLayoutPhase; }
-
- bool needsTwoPhasesLayout() const { return m_needsTwoPhasesLayout; }
- void clearNeedsTwoPhasesLayout() { m_needsTwoPhasesLayout = false; }
-
- void pushFlowThreadLayoutState(const RenderObject*);
+ void pushFlowThreadLayoutState(const RenderObject&);
void popFlowThreadLayoutState();
LayoutUnit offsetFromLogicalTopOfFirstRegion(const RenderBlock*) const;
@@ -178,31 +118,8 @@ public:
protected:
virtual const char* renderName() const = 0;
- // Overridden by columns/pages to set up an initial logical width of the page width even when
- // no regions have been generated yet.
- virtual LayoutUnit initialLogicalWidth() const { return 0; };
-
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
-
- void updateRegionsFlowThreadPortionRect(const RenderRegion* = 0);
+ void updateRegionsFlowThreadPortionRect();
bool shouldRepaint(const LayoutRect&) const;
- bool regionInRange(const RenderRegion* targetRegion, const RenderRegion* startRegion, const RenderRegion* endRegion) const;
-
- LayoutRect computeRegionClippingRect(const LayoutPoint&, const LayoutRect&, const LayoutRect&) const;
-
- void setDispatchRegionLayoutUpdateEvent(bool value) { m_dispatchRegionLayoutUpdateEvent = value; }
- bool shouldDispatchRegionLayoutUpdateEvent() { return m_dispatchRegionLayoutUpdateEvent; }
-
- void setDispatchRegionOversetChangeEvent(bool value) { m_dispatchRegionOversetChangeEvent = value; }
- bool shouldDispatchRegionOversetChangeEvent() const { return m_dispatchRegionOversetChangeEvent; }
-
- // Override if the flow thread implementation supports dispatching events when the flow layout is updated (e.g. for named flows)
- virtual void dispatchRegionLayoutUpdateEvent() { m_dispatchRegionLayoutUpdateEvent = false; }
- virtual void dispatchRegionOversetChangeEvent() { m_dispatchRegionOversetChangeEvent = false; }
-
- void initializeRegionsComputedAutoHeight(RenderRegion* = 0);
-
- virtual void autoGenerateRegionsToBlockOffset(LayoutUnit) { };
bool cachedOffsetFromLogicalTopOfFirstRegion(const RenderBox*, LayoutUnit&) const;
void setOffsetFromLogicalTopOfFirstRegion(const RenderBox*, LayoutUnit);
@@ -211,7 +128,6 @@ protected:
const RenderBox* currentStatePusherRenderBox() const;
RenderRegionList m_regionList;
- unsigned short m_previousRegionCount;
class RenderRegionRange {
public:
@@ -265,10 +181,6 @@ protected:
typedef HashMap<const RenderBox*, RenderRegionRange> RenderRegionRangeMap;
RenderRegionRangeMap m_regionRangeMap;
- typedef HashMap<RenderObject*, RenderRegion*> RenderObjectToRegionMap;
- RenderObjectToRegionMap m_breakBeforeToRegionMap;
- RenderObjectToRegionMap m_breakAfterToRegionMap;
-
// Stack of objects that pushed a LayoutState object on the RenderView. The
// objects on the stack are the ones that are curently in the process of being
// laid out.
@@ -276,23 +188,11 @@ protected:
typedef HashMap<const RenderBox*, LayoutUnit> RenderBoxToOffsetMap;
RenderBoxToOffsetMap m_boxesToOffsetMap;
- unsigned m_autoLogicalHeightRegionsCount;
-
RegionIntervalTree m_regionIntervalTree;
bool m_regionsInvalidated : 1;
- bool m_regionsHaveUniformLogicalWidth : 1;
bool m_regionsHaveUniformLogicalHeight : 1;
- bool m_hasRegionsWithStyling : 1;
- bool m_dispatchRegionLayoutUpdateEvent : 1;
- bool m_dispatchRegionOversetChangeEvent : 1;
bool m_pageLogicalSizeChanged : 1;
- bool m_inConstrainedLayoutPhase : 1;
- bool m_needsTwoPhasesLayout : 1;
-
-private:
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderFlowThread, isRenderFlowThread());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFrame.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderFrame.cpp
index 329ae3422b4..3468cc3af7c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFrame.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFrame.cpp
@@ -47,21 +47,4 @@ void RenderFrame::updateFromElement()
toRenderFrameSet(parent())->notifyFrameEdgeInfoChanged();
}
-void RenderFrame::viewCleared()
-{
- HTMLFrameElement* element = toHTMLFrameElement(node());
- if (!element || !widget() || !widget()->isFrameView())
- return;
-
- FrameView* view = toFrameView(widget());
-
- int marginWidth = element->marginWidth();
- int marginHeight = element->marginHeight();
-
- if (marginWidth != -1)
- view->setMarginWidth(marginWidth);
- if (marginHeight != -1)
- view->setMarginHeight(marginHeight);
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFrame.h b/chromium/third_party/WebKit/Source/core/rendering/RenderFrame.h
index 55391b98bd9..8d953191ad9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFrame.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFrame.h
@@ -37,12 +37,10 @@ public:
FrameEdgeInfo edgeInfo() const;
private:
- virtual const char* renderName() const { return "RenderFrame"; }
- virtual bool isFrame() const { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderFrame"; }
+ virtual bool isFrame() const OVERRIDE { return true; }
- virtual void updateFromElement();
-
- virtual void viewCleared();
+ virtual void updateFromElement() OVERRIDE;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderFrame, isFrame());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.cpp
index a0bf472cac3..afae324b731 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.cpp
@@ -26,13 +26,11 @@
#include "core/dom/Document.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLDimension.h"
#include "core/html/HTMLFrameSetElement.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
#include "core/rendering/GraphicsContextAnnotator.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderFrame.h"
#include "core/rendering/RenderView.h"
@@ -441,13 +439,12 @@ void RenderFrameSet::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
- bool doFullRepaint = !RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && selfNeedsLayout() && checkForRepaintDuringLayout();
+ bool doFullRepaint = selfNeedsLayout() && checkForPaintInvalidationDuringLayout();
LayoutRect oldBounds;
- RenderLayerModelObject* repaintContainer = 0;
+ const RenderLayerModelObject* repaintContainer = 0;
if (doFullRepaint) {
- repaintContainer = containerForRepaint();
- oldBounds = clippedOverflowRectForRepaint(repaintContainer);
+ repaintContainer = containerForPaintInvalidation();
+ oldBounds = boundsRectForPaintInvalidation(repaintContainer);
}
if (!parent()->isFrameSet() && !document().printing()) {
@@ -473,13 +470,13 @@ void RenderFrameSet::layout()
computeEdgeInfo();
- updateLayerTransform();
+ updateLayerTransformAfterLayout();
if (doFullRepaint) {
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds));
- LayoutRect newBounds = clippedOverflowRectForRepaint(repaintContainer);
+ invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds), InvalidationSelfLayout);
+ LayoutRect newBounds = boundsRectForPaintInvalidation(repaintContainer);
if (newBounds != oldBounds)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds));
+ invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds), InvalidationSelfLayout);
}
clearNeedsLayout();
@@ -517,7 +514,7 @@ void RenderFrameSet::positionFrames()
if (width != child->width() || height != child->height()) {
child->setWidth(width);
child->setHeight(height);
- child->setNeedsLayout();
+ child->setNeedsLayoutAndFullPaintInvalidation();
child->layout();
}
@@ -557,7 +554,7 @@ void RenderFrameSet::continueResizing(GridAxis& axis, int position)
return;
axis.m_deltas[axis.m_splitBeingResized - 1] += delta;
axis.m_deltas[axis.m_splitBeingResized] -= delta;
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
}
bool RenderFrameSet::userResize(MouseEvent* evt)
@@ -596,20 +593,10 @@ void RenderFrameSet::setIsResizing(bool isResizing)
if (ancestor->isFrameSet())
toRenderFrameSet(ancestor)->m_isChildResizing = isResizing;
}
- if (Frame* frame = this->frame())
+ if (LocalFrame* frame = this->frame())
frame->eventHandler().setResizingFrameSet(isResizing ? frameSet() : 0);
}
-bool RenderFrameSet::isResizingRow() const
-{
- return m_isResizing && m_rows.m_splitBeingResized != noSplit;
-}
-
-bool RenderFrameSet::isResizingColumn() const
-{
- return m_isResizing && m_cols.m_splitBeingResized != noSplit;
-}
-
bool RenderFrameSet::canResizeRow(const IntPoint& p) const
{
int r = hitTestSplit(m_rows, p.y());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.h b/chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.h
index 21f90eac87a..90bf5933792 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFrameSet.h
@@ -30,7 +30,6 @@ namespace WebCore {
class HTMLDimension;
class HTMLFrameSetElement;
class MouseEvent;
-class RenderFrame;
enum FrameEdge { LeftFrameEdge, RightFrameEdge, TopFrameEdge, BottomFrameEdge };
@@ -62,6 +61,10 @@ public:
RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
+ // If you have a RenderFrameSet, use firstChild or lastChild instead.
+ void slowFirstChild() const WTF_DELETED_FUNCTION;
+ void slowLastChild() const WTF_DELETED_FUNCTION;
+
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
@@ -69,9 +72,6 @@ public:
bool userResize(MouseEvent*);
- bool isResizingRow() const;
- bool isResizingColumn() const;
-
bool canResizeRow(const IntPoint&) const;
bool canResizeColumn(const IntPoint&) const;
@@ -94,16 +94,16 @@ private:
int m_splitResizeOffset;
};
- virtual RenderObjectChildList* virtualChildren() { return children(); }
- virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ virtual RenderObjectChildList* virtualChildren() OVERRIDE { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const OVERRIDE { return children(); }
- virtual const char* renderName() const { return "RenderFrameSet"; }
- virtual bool isFrameSet() const { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderFrameSet"; }
+ virtual bool isFrameSet() const OVERRIDE { return true; }
- virtual void layout();
- virtual void paint(PaintInfo&, const LayoutPoint&);
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
- virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
+ virtual void layout() OVERRIDE;
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
+ virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const OVERRIDE;
inline HTMLFrameSetElement* frameSet() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.cpp
index 23fa9925c0f..9ce9810a3ac 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.cpp
@@ -39,9 +39,8 @@ public:
setDocumentForAnonymous(&owner->document());
}
private:
- virtual bool isRenderFullScreenPlaceholder() const { return true; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
- virtual void willBeDestroyed();
+ virtual bool isRenderFullScreenPlaceholder() const OVERRIDE { return true; }
+ virtual void willBeDestroyed() OVERRIDE;
RenderFullScreen* m_owner;
};
@@ -76,9 +75,9 @@ void RenderFullScreen::willBeDestroyed()
// RenderObjects are unretained, so notify the document (which holds a pointer to a RenderFullScreen)
// if it's RenderFullScreen is destroyed.
- FullscreenElementStack* controller = FullscreenElementStack::from(&document());
- if (controller->fullScreenRenderer() == this)
- controller->fullScreenRendererDestroyed();
+ FullscreenElementStack& controller = FullscreenElementStack::from(document());
+ if (controller.fullScreenRenderer() == this)
+ controller.fullScreenRendererDestroyed();
RenderFlexibleBox::willBeDestroyed();
}
@@ -91,11 +90,11 @@ static PassRefPtr<RenderStyle> createFullScreenStyle()
fullscreenStyle->setZIndex(INT_MAX);
fullscreenStyle->setFontDescription(FontDescription());
- fullscreenStyle->font().update(0);
+ fullscreenStyle->font().update(nullptr);
fullscreenStyle->setDisplay(FLEX);
fullscreenStyle->setJustifyContent(JustifyCenter);
- fullscreenStyle->setAlignItems(AlignCenter);
+ fullscreenStyle->setAlignItems(ItemPositionCenter);
fullscreenStyle->setFlexDirection(FlowColumn);
fullscreenStyle->setPosition(FixedPosition);
@@ -104,13 +103,17 @@ static PassRefPtr<RenderStyle> createFullScreenStyle()
fullscreenStyle->setLeft(Length(0, WebCore::Fixed));
fullscreenStyle->setTop(Length(0, WebCore::Fixed));
- fullscreenStyle->setBackgroundColor(Color::black);
+ fullscreenStyle->setBackgroundColor(StyleColor(Color::black));
return fullscreenStyle.release();
}
RenderObject* RenderFullScreen::wrapRenderer(RenderObject* object, RenderObject* parent, Document* document)
{
+ // FIXME: We should not modify the structure of the render tree during
+ // layout. crbug.com/370459
+ DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
+
RenderFullScreen* fullscreenRenderer = RenderFullScreen::createAnonymous(document);
fullscreenRenderer->setStyle(createFullScreenStyle());
if (parent && !parent->isChildAllowed(fullscreenRenderer, fullscreenRenderer->style())) {
@@ -133,19 +136,24 @@ RenderObject* RenderFullScreen::wrapRenderer(RenderObject* object, RenderObject*
// Always just do a full layout to ensure that line boxes get deleted properly.
// Because objects moved from |parent| to |fullscreenRenderer|, we want to
// make new line boxes instead of leaving the old ones around.
- parent->setNeedsLayoutAndPrefWidthsRecalc();
- containingBlock->setNeedsLayoutAndPrefWidthsRecalc();
+ parent->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ containingBlock->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
fullscreenRenderer->addChild(object);
- fullscreenRenderer->setNeedsLayoutAndPrefWidthsRecalc();
+ fullscreenRenderer->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
- FullscreenElementStack::from(document)->setFullScreenRenderer(fullscreenRenderer);
+ ASSERT(document);
+ FullscreenElementStack::from(*document).setFullScreenRenderer(fullscreenRenderer);
return fullscreenRenderer;
}
void RenderFullScreen::unwrapRenderer()
{
+ // FIXME: We should not modify the structure of the render tree during
+ // layout. crbug.com/370459
+ DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
+
if (parent()) {
RenderObject* child;
while ((child = firstChild())) {
@@ -156,13 +164,13 @@ void RenderFullScreen::unwrapRenderer()
toRenderBox(child)->clearOverrideSize();
child->remove();
parent()->addChild(child, this);
- parent()->setNeedsLayoutAndPrefWidthsRecalc();
+ parent()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
}
if (placeholder())
placeholder()->remove();
remove();
- FullscreenElementStack::from(&document())->setFullScreenRenderer(0);
+ FullscreenElementStack::from(document()).setFullScreenRenderer(0);
}
void RenderFullScreen::setPlaceholder(RenderBlock* placeholder)
@@ -182,7 +190,7 @@ void RenderFullScreen::createPlaceholder(PassRefPtr<RenderStyle> style, const La
m_placeholder->setStyle(style);
if (parent()) {
parent()->addChild(m_placeholder, this);
- parent()->setNeedsLayoutAndPrefWidthsRecalc();
+ parent()->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
} else
m_placeholder->setStyle(style);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.h b/chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.h
index 48c40f4f7fe..285dbd21a70 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderFullScreen.h
@@ -34,8 +34,8 @@ class RenderFullScreen FINAL : public RenderFlexibleBox {
public:
static RenderFullScreen* createAnonymous(Document*);
- virtual bool isRenderFullScreen() const { return true; }
- virtual const char* renderName() const { return "RenderFullScreen"; }
+ virtual bool isRenderFullScreen() const OVERRIDE { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderFullScreen"; }
void setPlaceholder(RenderBlock*);
RenderBlock* placeholder() { return m_placeholder; }
@@ -47,8 +47,7 @@ public:
private:
RenderFullScreen();
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
protected:
RenderBlock* m_placeholder;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.cpp
index 07ab16f7014..13782a8af3d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/rendering/RenderGeometryMap.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "platform/geometry/TransformState.h"
@@ -57,7 +57,7 @@ void RenderGeometryMap::mapToContainer(TransformState& transformState, const Ren
}
bool inFixed = false;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool foundContainer = !container || (m_mapping.size() && m_mapping[0].m_renderer == container);
#endif
@@ -66,7 +66,7 @@ void RenderGeometryMap::mapToContainer(TransformState& transformState, const Ren
// If container is the root RenderView (step 0) we want to apply its fixed position offset.
if (i > 0 && currentStep.m_renderer == container) {
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
foundContainer = true;
#endif
break;
@@ -109,14 +109,14 @@ FloatPoint RenderGeometryMap::mapToContainer(const FloatPoint& p, const RenderLa
FloatPoint result;
if (!hasFixedPositionStep() && !hasTransformStep() && !hasNonUniformStep() && (!container || (m_mapping.size() && container == m_mapping[0].m_renderer)))
- result = p + roundedIntSize(m_accumulatedOffset);
+ result = p + m_accumulatedOffset;
else {
TransformState transformState(TransformState::ApplyTransformDirection, p);
mapToContainer(transformState, container);
result = transformState.lastPlanarPoint();
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
if (m_mapping.size() > 0) {
const RenderObject* lastRenderer = m_mapping.last().m_renderer;
const RenderLayer* layer = lastRenderer->enclosingLayer();
@@ -125,7 +125,7 @@ FloatPoint RenderGeometryMap::mapToContainer(const FloatPoint& p, const RenderLa
// therefore not necessarily expected to be correct here. This is ok,
// because they will be recomputed if the layer becomes visible.
if (!layer || !layer->subtreeIsInvisible()) {
- FloatPoint rendererMappedResult = lastRenderer->localToAbsolute(p, m_mapCoordinatesFlags);
+ FloatPoint rendererMappedResult = lastRenderer->localToContainerPoint(p, container, m_mapCoordinatesFlags);
ASSERT(roundedIntPoint(rendererMappedResult) == roundedIntPoint(result));
}
@@ -137,7 +137,7 @@ FloatPoint RenderGeometryMap::mapToContainer(const FloatPoint& p, const RenderLa
#ifndef NDEBUG
// Handy function to call from gdb while debugging mismatched point/rect errors.
-void RenderGeometryMap::dumpSteps()
+void RenderGeometryMap::dumpSteps() const
{
fprintf(stderr, "RenderGeometryMap::dumpSteps accumulatedOffset=%d,%d\n", m_accumulatedOffset.width().toInt(), m_accumulatedOffset.height().toInt());
for (int i = m_mapping.size() - 1; i >= 0; --i) {
@@ -162,7 +162,7 @@ FloatQuad RenderGeometryMap::mapToContainer(const FloatRect& rect, const RenderL
result = transformState.lastPlanarQuad().boundingBox();
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
if (m_mapping.size() > 0) {
const RenderObject* lastRenderer = m_mapping.last().m_renderer;
const RenderLayer* layer = lastRenderer->enclosingLayer();
@@ -170,7 +170,7 @@ FloatQuad RenderGeometryMap::mapToContainer(const FloatRect& rect, const RenderL
// Bounds for invisible layers are intentionally not calculated, and are
// therefore not necessarily expected to be correct here. This is ok,
// because they will be recomputed if the layer becomes visible.
- if (!layer || !layer->subtreeIsInvisible()) {
+ if (!layer->subtreeIsInvisible() && lastRenderer->style()->visibility() == VISIBLE) {
FloatRect rendererMappedResult = lastRenderer->localToContainerQuad(rect, container, m_mapCoordinatesFlags).boundingBox();
// Inspector creates renderers with negative width <https://bugs.webkit.org/show_bug.cgi?id=87194>.
@@ -235,7 +235,8 @@ void RenderGeometryMap::pushMappingsToAncestor(const RenderLayer* layer, const R
}
TemporaryChange<size_t> positionChange(m_insertionPosition, m_mapping.size());
- push(renderer, toLayoutSize(layerOffset), /*accumulatingTransform*/ true, /*isNonUniform*/ false, /*isFixedPosition*/ false, /*hasTransform*/ false);
+ bool accumulatingTransform = layer->renderer()->style()->preserves3D() || ancestorLayer->renderer()->style()->preserves3D();
+ push(renderer, toLayoutSize(layerOffset), accumulatingTransform, /*isNonUniform*/ false, /*isFixedPosition*/ false, /*hasTransform*/ false);
return;
}
const RenderLayerModelObject* ancestorRenderer = ancestorLayer ? ancestorLayer->renderer() : 0;
@@ -328,7 +329,7 @@ void RenderGeometryMap::stepRemoved(const RenderGeometryMapStep& step)
}
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool RenderGeometryMap::isTopmostRenderView(const RenderObject* renderer) const
{
if (!renderer->isRenderView())
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.h b/chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.h
index 8049bbbc066..807c458be7e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderGeometryMap.h
@@ -38,7 +38,6 @@ namespace WebCore {
class RenderLayer;
class RenderLayerModelObject;
-class RenderView;
class TransformState;
// Stores data about how to map from one renderer to its container.
@@ -121,10 +120,10 @@ private:
bool hasFixedPositionStep() const { return m_fixedStepsCount; }
#ifndef NDEBUG
- void dumpSteps();
+ void dumpSteps() const;
#endif
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool isTopmostRenderView(const RenderObject* renderer) const;
#endif
@@ -141,10 +140,6 @@ private:
} // namespace WebCore
-namespace WTF {
-// This is required for a struct with OwnPtr. We know RenderGeometryMapStep is simple enough that
-// initializing to 0 and moving with memcpy (and then not destructing the original) will work.
-template<> struct VectorTraits<WebCore::RenderGeometryMapStep> : SimpleClassVectorTraits { };
-}
+WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(WebCore::RenderGeometryMapStep);
#endif // RenderGeometryMap_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderGrid.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderGrid.cpp
index 38c296ac866..0d167415707 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderGrid.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderGrid.cpp
@@ -26,10 +26,12 @@
#include "config.h"
#include "core/rendering/RenderGrid.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/style/GridCoordinate.h"
+#include "platform/LengthFunctions.h"
namespace WebCore {
@@ -75,7 +77,7 @@ struct GridTrackForNormalization {
}
// Required by std::sort.
- GridTrackForNormalization operator=(const GridTrackForNormalization& o)
+ GridTrackForNormalization& operator=(const GridTrackForNormalization& o)
{
m_track = o.m_track;
m_flex = o.m_flex;
@@ -120,16 +122,37 @@ public:
return 0;
}
- PassOwnPtr<GridCoordinate> nextEmptyGridArea()
+ bool checkEmptyCells(size_t rowSpan, size_t columnSpan) const
+ {
+ // Ignore cells outside current grid as we will grow it later if needed.
+ size_t maxRows = std::min(m_rowIndex + rowSpan, m_grid.size());
+ size_t maxColumns = std::min(m_columnIndex + columnSpan, m_grid[0].size());
+
+ // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spanning areas to be small.
+ for (size_t row = m_rowIndex; row < maxRows; ++row) {
+ for (size_t column = m_columnIndex; column < maxColumns; ++column) {
+ const GridCell& children = m_grid[row][column];
+ if (!children.isEmpty())
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ PassOwnPtr<GridCoordinate> nextEmptyGridArea(size_t fixedTrackSpan, size_t varyingTrackSpan)
{
ASSERT(!m_grid.isEmpty());
+ ASSERT(fixedTrackSpan >= 1 && varyingTrackSpan >= 1);
+
+ size_t rowSpan = (m_direction == ForColumns) ? varyingTrackSpan : fixedTrackSpan;
+ size_t columnSpan = (m_direction == ForColumns) ? fixedTrackSpan : varyingTrackSpan;
size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
- const GridCell& children = m_grid[m_rowIndex][m_columnIndex];
- if (children.isEmpty()) {
- OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(GridSpan(m_rowIndex, m_rowIndex), GridSpan(m_columnIndex, m_columnIndex)));
+ if (checkEmptyCells(rowSpan, columnSpan)) {
+ OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(GridSpan(m_rowIndex, m_rowIndex + rowSpan - 1), GridSpan(m_columnIndex, m_columnIndex + columnSpan - 1)));
// Advance the iterator to avoid an infinite loop where we would return the same grid area over and over.
++varyingTrackIndex;
return result.release();
@@ -168,7 +191,6 @@ RenderGrid::RenderGrid(Element* element)
: RenderBlock(element)
, m_gridIsDirty(true)
, m_orderIterator(this)
- , m_gridItemOverflowGridArea(false)
{
// All of our children must be block level.
setChildrenInline(false);
@@ -190,20 +212,44 @@ void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild)
return;
}
+ if (style()->gridAutoFlow() != AutoFlowNone) {
+ // The grid needs to be recomputed as it might contain auto-placed items that will change their position.
+ dirtyGrid();
+ return;
+ }
+
RenderBox* newChildBox = toRenderBox(newChild);
- OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(newChildBox, ForRows);
- OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(newChildBox, ForColumns);
+ OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *newChildBox, ForRows);
+ OwnPtr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *newChildBox, ForColumns);
if (!rowPositions || !columnPositions) {
// The new child requires the auto-placement algorithm to run so we need to recompute the grid fully.
dirtyGrid();
+ return;
} else {
- if (gridRowCount() <= rowPositions->finalPositionIndex || gridColumnCount() <= columnPositions->finalPositionIndex) {
- // FIXME: We could just insert the new child provided we had a primitive to arbitrarily grow the grid.
- dirtyGrid();
- } else {
- insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *columnPositions));
- }
+ insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *columnPositions));
+ addChildToIndexesMap(newChildBox);
+ }
+}
+
+void RenderGrid::addChildToIndexesMap(RenderBox* child)
+{
+ ASSERT(!m_gridItemsIndexesMap.contains(child));
+ RenderBox* sibling = child->nextSiblingBox();
+ bool lastSibling = !sibling;
+
+ if (lastSibling)
+ sibling = child->previousSiblingBox();
+
+ size_t index = 0;
+ if (sibling)
+ index = lastSibling ? m_gridItemsIndexesMap.get(sibling) + 1 : m_gridItemsIndexesMap.get(sibling);
+
+ if (sibling && !lastSibling) {
+ for (; sibling; sibling = sibling->nextSiblingBox())
+ m_gridItemsIndexesMap.set(sibling, m_gridItemsIndexesMap.get(sibling) + 1);
}
+
+ m_gridItemsIndexesMap.set(child, index);
}
void RenderGrid::removeChild(RenderObject* child)
@@ -214,8 +260,24 @@ void RenderGrid::removeChild(RenderObject* child)
return;
ASSERT(child->isBox());
- // FIXME: We could avoid dirtying the grid in some cases (e.g. if it's an explicitly positioned element).
- dirtyGrid();
+
+ if (style()->gridAutoFlow() != AutoFlowNone) {
+ // The grid needs to be recomputed as it might contain auto-placed items that will change their position.
+ dirtyGrid();
+ return;
+ }
+
+ const RenderBox* childBox = toRenderBox(child);
+ GridCoordinate coordinate = m_gridItemCoordinate.take(childBox);
+
+ for (GridSpan::iterator row = coordinate.rows.begin(); row != coordinate.rows.end(); ++row) {
+ for (GridSpan::iterator column = coordinate.columns.begin(); column != coordinate.columns.end(); ++column) {
+ GridCell& cell = m_grid[row.toInt()][column.toInt()];
+ cell.remove(cell.find(childBox));
+ }
+ }
+
+ m_gridItemsIndexesMap.remove(childBox);
}
void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
@@ -237,8 +299,8 @@ void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl
bool RenderGrid::explicitGridDidResize(const RenderStyle* oldStyle) const
{
- return oldStyle->gridDefinitionColumns().size() != style()->gridDefinitionColumns().size()
- || oldStyle->gridDefinitionRows().size() != style()->gridDefinitionRows().size();
+ return oldStyle->gridTemplateColumns().size() != style()->gridTemplateColumns().size()
+ || oldStyle->gridTemplateRows().size() != style()->gridTemplateRows().size();
}
bool RenderGrid::namedGridLinesDefinitionDidChange(const RenderStyle* oldStyle) const
@@ -247,7 +309,7 @@ bool RenderGrid::namedGridLinesDefinitionDidChange(const RenderStyle* oldStyle)
|| oldStyle->namedGridColumnLines() != style()->namedGridColumnLines();
}
-void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
+void RenderGrid::layoutBlock(bool relayoutChildren)
{
ASSERT(needsLayout());
@@ -256,21 +318,16 @@ void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
// FIXME: Much of this method is boiler plate that matches RenderBox::layoutBlock and Render*FlexibleBox::layoutBlock.
// It would be nice to refactor some of the duplicate code.
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
-
- // Regions changing widths can force us to relayout our children.
- RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (logicalWidthChangedInRegions(flowThread))
- relayoutChildren = true;
- if (updateRegionsAndShapesLogicalSize(flowThread))
- relayoutChildren = true;
+ LayoutRepainter repainter(*this, checkForPaintInvalidationDuringLayout());
+ LayoutState state(*this, locationOffset());
LayoutSize previousSize = size();
setLogicalHeight(0);
updateLogicalWidth();
+ FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
+
layoutGridItems();
LayoutUnit oldClientAfterEdge = clientLogicalBottom();
@@ -279,14 +336,13 @@ void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
if (size() != previousSize)
relayoutChildren = true;
- layoutPositionedObjects(relayoutChildren || isRoot());
+ layoutPositionedObjects(relayoutChildren || isDocumentElement());
- computeRegionRangeForBlock(flowThread);
+ computeRegionRangeForBlock(flowThreadContainingBlock());
computeOverflow(oldClientAfterEdge);
- statePusher.pop();
- updateLayerTransform();
+ updateLayerTransformAfterLayout();
// Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
// we overflow or not.
@@ -304,7 +360,7 @@ void RenderGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo
GridSizingData sizingData(gridColumnCount(), gridRowCount());
LayoutUnit availableLogicalSpace = 0;
- const_cast<RenderGrid*>(this)->computedUsedBreadthOfGridTracks(ForColumns, sizingData, availableLogicalSpace);
+ const_cast<RenderGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, sizingData, availableLogicalSpace);
for (size_t i = 0; i < sizingData.columnTracks.size(); ++i) {
LayoutUnit minTrackBreadth = sizingData.columnTracks[i].m_usedBreadth;
@@ -337,16 +393,24 @@ void RenderGrid::computePreferredLogicalWidths()
clearPreferredLogicalWidthsDirty();
}
-void RenderGrid::computedUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData)
+void RenderGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData)
{
LayoutUnit availableLogicalSpace = (direction == ForColumns) ? availableLogicalWidth() : availableLogicalHeight(IncludeMarginBorderPadding);
- computedUsedBreadthOfGridTracks(direction, sizingData, availableLogicalSpace);
+ computeUsedBreadthOfGridTracks(direction, sizingData, availableLogicalSpace);
}
-void RenderGrid::computedUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
+bool RenderGrid::gridElementIsShrinkToFit()
+{
+ return isFloatingOrOutOfFlowPositioned();
+}
+
+void RenderGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
{
Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTracks : sizingData.rowTracks;
+ Vector<size_t> flexibleSizedTracksIndex;
sizingData.contentSizedTracksIndex.shrink(0);
+
+ // 1. Initialize per Grid track variables.
for (size_t i = 0; i < tracks.size(); ++i) {
GridTrack& track = tracks[i];
const GridTrackSize& trackSize = gridTrackSize(direction, i);
@@ -360,8 +424,11 @@ void RenderGrid::computedUsedBreadthOfGridTracks(GridTrackSizingDirection direct
if (trackSize.isContentSized())
sizingData.contentSizedTracksIndex.append(i);
+ if (trackSize.maxTrackBreadth().isFlex())
+ flexibleSizedTracksIndex.append(i);
}
+ // 2. Resolve content-based TrackSizingFunctions.
if (!sizingData.contentSizedTracksIndex.isEmpty())
resolveContentBasedTrackSizingFunctions(direction, sizingData, availableLogicalSpace);
@@ -370,26 +437,60 @@ void RenderGrid::computedUsedBreadthOfGridTracks(GridTrackSizingDirection direct
availableLogicalSpace -= tracks[i].m_usedBreadth;
}
- if (availableLogicalSpace <= 0)
+ const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->logicalHeight().isAuto() : gridElementIsShrinkToFit();
+
+ if (!hasUndefinedRemainingSpace && availableLogicalSpace <= 0)
return;
+ // 3. Grow all Grid tracks in GridTracks from their UsedBreadth up to their MaxBreadth value until
+ // availableLogicalSpace (RemainingSpace in the specs) is exhausted.
const size_t tracksSize = tracks.size();
- Vector<GridTrack*> tracksForDistribution(tracksSize);
- for (size_t i = 0; i < tracksSize; ++i)
- tracksForDistribution[i] = tracks.data() + i;
+ if (!hasUndefinedRemainingSpace) {
+ Vector<GridTrack*> tracksForDistribution(tracksSize);
+ for (size_t i = 0; i < tracksSize; ++i)
+ tracksForDistribution[i] = tracks.data() + i;
- distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, sizingData, availableLogicalSpace);
+ distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, sizingData, availableLogicalSpace);
+ } else {
+ for (size_t i = 0; i < tracksSize; ++i)
+ tracks[i].m_usedBreadth = tracks[i].m_maxBreadth;
+ }
+
+ if (flexibleSizedTracksIndex.isEmpty())
+ return;
// 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction.
+ double normalizedFractionBreadth = 0;
+ if (!hasUndefinedRemainingSpace) {
+ normalizedFractionBreadth = computeNormalizedFractionBreadth(tracks, GridSpan(0, tracks.size() - 1), direction, availableLogicalSpace);
+ } else {
+ for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) {
+ const size_t trackIndex = flexibleSizedTracksIndex[i];
+ const GridTrackSize& trackSize = gridTrackSize(direction, trackIndex);
+ normalizedFractionBreadth = std::max(normalizedFractionBreadth, tracks[trackIndex].m_usedBreadth / trackSize.maxTrackBreadth().flex());
+ }
- // FIXME: Handle the case where RemainingSpace is not defined.
- double normalizedFractionBreadth = computeNormalizedFractionBreadth(tracks, direction, availableLogicalSpace);
- for (size_t i = 0; i < tracksSize; ++i) {
- const GridTrackSize& trackSize = gridTrackSize(direction, i);
- if (!trackSize.maxTrackBreadth().isFlex())
- continue;
+ for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) {
+ GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i]);
+ while (RenderBox* gridItem = iterator.nextGridItem()) {
+ const GridCoordinate coordinate = cachedGridCoordinate(gridItem);
+ const GridSpan span = (direction == ForColumns) ? coordinate.columns : coordinate.rows;
+
+ // Do not include already processed items.
+ if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSizedTracksIndex[i - 1])
+ continue;
+
+ double itemNormalizedFlexBreadth = computeNormalizedFractionBreadth(tracks, span, direction, maxContentForChild(gridItem, direction, sizingData.columnTracks));
+ normalizedFractionBreadth = std::max(normalizedFractionBreadth, itemNormalizedFlexBreadth);
+ }
+ }
+ }
- tracks[i].m_usedBreadth = std::max<LayoutUnit>(tracks[i].m_usedBreadth, normalizedFractionBreadth * trackSize.maxTrackBreadth().flex());
+ for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) {
+ const size_t trackIndex = flexibleSizedTracksIndex[i];
+ const GridTrackSize& trackSize = gridTrackSize(direction, trackIndex);
+
+ tracks[trackIndex].m_usedBreadth = std::max<LayoutUnit>(tracks[trackIndex].m_usedBreadth, normalizedFractionBreadth * trackSize.maxTrackBreadth().flex());
}
}
@@ -428,7 +529,7 @@ LayoutUnit RenderGrid::computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirect
{
ASSERT(trackLength.isSpecified());
// FIXME: The -1 here should be replaced by whatever the intrinsic height of the grid is.
- return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : computeContentLogicalHeight(style()->logicalHeight(), -1), view());
+ return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : computeContentLogicalHeight(style()->logicalHeight(), -1));
}
static bool sortByGridNormalizedFlexValue(const GridTrackForNormalization& track1, const GridTrackForNormalization& track2)
@@ -436,22 +537,21 @@ static bool sortByGridNormalizedFlexValue(const GridTrackForNormalization& track
return track1.m_normalizedFlexValue < track2.m_normalizedFlexValue;
}
-double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, GridTrackSizingDirection direction, LayoutUnit availableLogicalSpace) const
+double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, const GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit availableLogicalSpace) const
{
// |availableLogicalSpace| already accounts for the used breadths so no need to remove it here.
Vector<GridTrackForNormalization> tracksForNormalization;
- for (size_t i = 0; i < tracks.size(); ++i) {
- const GridTrackSize& trackSize = gridTrackSize(direction, i);
+ for (GridSpan::iterator resolvedPosition = tracksSpan.begin(); resolvedPosition != tracksSpan.end(); ++resolvedPosition) {
+ const GridTrackSize& trackSize = gridTrackSize(direction, resolvedPosition.toInt());
if (!trackSize.maxTrackBreadth().isFlex())
continue;
- tracksForNormalization.append(GridTrackForNormalization(tracks[i], trackSize.maxTrackBreadth().flex()));
+ tracksForNormalization.append(GridTrackForNormalization(tracks[resolvedPosition.toInt()], trackSize.maxTrackBreadth().flex()));
}
- // FIXME: Ideally we shouldn't come here without any <flex> grid track.
- if (tracksForNormalization.isEmpty())
- return LayoutUnit();
+ // The function is not called if we don't have <flex> grid tracks
+ ASSERT(!tracksForNormalization.isEmpty());
std::sort(tracksForNormalization.begin(), tracksForNormalization.end(), sortByGridNormalizedFlexValue);
@@ -483,40 +583,37 @@ double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, G
const GridTrackSize& RenderGrid::gridTrackSize(GridTrackSizingDirection direction, size_t i) const
{
- const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridDefinitionColumns() : style()->gridDefinitionRows();
+ const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridTemplateColumns() : style()->gridTemplateRows();
if (i >= trackStyles.size())
return (direction == ForColumns) ? style()->gridAutoColumns() : style()->gridAutoRows();
- return trackStyles[i];
-}
-
-size_t RenderGrid::explicitGridColumnCount() const
-{
- return style()->gridDefinitionColumns().size();
-}
-
-size_t RenderGrid::explicitGridRowCount() const
-{
- return style()->gridDefinitionRows().size();
-}
+ const GridTrackSize& trackSize = trackStyles[i];
+ // If the logical width/height of the grid container is indefinite, percentage values are treated as <auto>.
+ if (trackSize.isPercentage()) {
+ Length logicalSize = direction == ForColumns ? style()->logicalWidth() : style()->logicalHeight();
+ if (logicalSize.isIntrinsicOrAuto()) {
+ DEFINE_STATIC_LOCAL(GridTrackSize, autoTrackSize, (Length(Auto)));
+ return autoTrackSize;
+ }
+ }
-size_t RenderGrid::explicitGridSizeForSide(GridPositionSide side) const
-{
- return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColumnCount() : explicitGridRowCount();
+ return trackSize;
}
-LayoutUnit RenderGrid::logicalContentHeightForChild(RenderBox* child, Vector<GridTrack>& columnTracks)
+LayoutUnit RenderGrid::logicalHeightForChild(RenderBox* child, Vector<GridTrack>& columnTracks)
{
- SubtreeLayoutScope layoutScope(child);
- if (child->style()->logicalHeight().isPercent())
+ SubtreeLayoutScope layoutScope(*child);
+ LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOverrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogicalWidth() : LayoutUnit();
+ LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForChild(child, ForColumns, columnTracks);
+ if (child->style()->logicalHeight().isPercent() || oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth)
layoutScope.setNeedsLayout(child);
- child->setOverrideContainingBlockContentLogicalWidth(gridAreaBreadthForChild(child, ForColumns, columnTracks));
+ child->setOverrideContainingBlockContentLogicalWidth(overrideContainingBlockContentLogicalWidth);
// If |child| has a percentage logical height, we shouldn't let it override its intrinsic height, which is
// what we are interested in here. Thus we need to set the override logical height to -1 (no possible resolution).
child->setOverrideContainingBlockContentLogicalHeight(-1);
child->layoutIfNeeded();
- return child->logicalHeight();
+ return child->logicalHeight() + child->marginLogicalHeight();
}
LayoutUnit RenderGrid::minContentForChild(RenderBox* child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
@@ -532,7 +629,7 @@ LayoutUnit RenderGrid::minContentForChild(RenderBox* child, GridTrackSizingDirec
return child->minPreferredLogicalWidth() + marginIntrinsicLogicalWidthForChild(child);
}
- return logicalContentHeightForChild(child, columnTracks);
+ return logicalHeightForChild(child, columnTracks);
}
LayoutUnit RenderGrid::maxContentForChild(RenderBox* child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
@@ -548,7 +645,7 @@ LayoutUnit RenderGrid::maxContentForChild(RenderBox* child, GridTrackSizingDirec
return child->maxPreferredLogicalWidth() + marginIntrinsicLogicalWidthForChild(child);
}
- return logicalContentHeightForChild(child, columnTracks);
+ return logicalHeightForChild(child, columnTracks);
}
void RenderGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
@@ -575,16 +672,16 @@ void RenderGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirectio
void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection direction, GridSizingData& sizingData, RenderBox* gridItem, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction)
{
const GridCoordinate coordinate = cachedGridCoordinate(gridItem);
- const size_t initialTrackIndex = (direction == ForColumns) ? coordinate.columns.initialPositionIndex : coordinate.rows.initialPositionIndex;
- const size_t finalTrackIndex = (direction == ForColumns) ? coordinate.columns.finalPositionIndex : coordinate.rows.finalPositionIndex;
+ const GridResolvedPosition initialTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPosition;
+ const GridResolvedPosition finalTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedFinalPosition : coordinate.rows.resolvedFinalPosition;
sizingData.filteredTracks.shrink(0);
- for (size_t trackIndex = initialTrackIndex; trackIndex <= finalTrackIndex; ++trackIndex) {
- const GridTrackSize& trackSize = gridTrackSize(direction, trackIndex);
+ for (GridResolvedPosition trackPosition = initialTrackPosition; trackPosition <= finalTrackPosition; ++trackPosition) {
+ const GridTrackSize& trackSize = gridTrackSize(direction, trackPosition.toInt());
if (!(trackSize.*filterFunction)())
continue;
- GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex];
+ GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackPosition.toInt()] : sizingData.rowTracks[trackPosition.toInt()];
sizingData.filteredTracks.append(&track);
}
@@ -592,8 +689,8 @@ void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing
return;
LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direction, sizingData.columnTracks);
- for (size_t trackIndexForSpace = initialTrackIndex; trackIndexForSpace <= finalTrackIndex; ++trackIndexForSpace) {
- GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndexForSpace] : sizingData.rowTracks[trackIndexForSpace];
+ for (GridResolvedPosition trackIndexForSpace = initialTrackPosition; trackIndexForSpace <= finalTrackPosition; ++trackIndexForSpace) {
+ GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndexForSpace.toInt()] : sizingData.rowTracks[trackIndexForSpace.toInt()];
additionalBreadthSpace -= (track.*trackGetter)();
}
@@ -655,36 +752,33 @@ bool RenderGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire
}
#endif
-void RenderGrid::growGrid(GridTrackSizingDirection direction)
+void RenderGrid::ensureGridSize(size_t maximumRowIndex, size_t maximumColumnIndex)
{
- if (direction == ForColumns) {
- const size_t oldColumnSize = m_grid[0].size();
- for (size_t row = 0; row < m_grid.size(); ++row)
- m_grid[row].grow(oldColumnSize + 1);
- } else {
- const size_t oldRowSize = m_grid.size();
- m_grid.grow(oldRowSize + 1);
- m_grid[oldRowSize].grow(m_grid[0].size());
+ const size_t oldRowSize = gridRowCount();
+ if (maximumRowIndex >= oldRowSize) {
+ m_grid.grow(maximumRowIndex + 1);
+ for (size_t row = oldRowSize; row < gridRowCount(); ++row)
+ m_grid[row].grow(gridColumnCount());
+ }
+
+ if (maximumColumnIndex >= gridColumnCount()) {
+ for (size_t row = 0; row < gridRowCount(); ++row)
+ m_grid[row].grow(maximumColumnIndex + 1);
}
}
void RenderGrid::insertItemIntoGrid(RenderBox* child, const GridCoordinate& coordinate)
{
- for (size_t row = coordinate.rows.initialPositionIndex; row <= coordinate.rows.finalPositionIndex; ++row) {
- for (size_t column = coordinate.columns.initialPositionIndex; column <= coordinate.columns.finalPositionIndex; ++column)
- m_grid[row][column].append(child);
+ ensureGridSize(coordinate.rows.resolvedFinalPosition.toInt(), coordinate.columns.resolvedFinalPosition.toInt());
+
+ for (GridSpan::iterator row = coordinate.rows.begin(); row != coordinate.rows.end(); ++row) {
+ for (GridSpan::iterator column = coordinate.columns.begin(); column != coordinate.columns.end(); ++column)
+ m_grid[row.toInt()][column.toInt()].append(child);
}
m_gridItemCoordinate.set(child, coordinate);
}
-void RenderGrid::insertItemIntoGrid(RenderBox* child, size_t rowTrack, size_t columnTrack)
-{
- const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(child, ForRows, rowTrack);
- const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(child, ForColumns, columnTrack);
- insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan));
-}
-
void RenderGrid::placeItemsOnGrid()
{
if (!gridIsDirty())
@@ -704,8 +798,8 @@ void RenderGrid::placeItemsOnGrid()
for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) {
// FIXME: We never re-resolve positions if the grid is grown during auto-placement which may lead auto / <integer>
// positions to not match the author's intent. The specification is unclear on what should be done in this case.
- OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, ForRows);
- OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child, ForColumns);
+ OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows);
+ OwnPtr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForColumns);
if (!rowPositions || !columnPositions) {
GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions.get() : rowPositions.get();
if (!majorAxisPositions)
@@ -717,8 +811,8 @@ void RenderGrid::placeItemsOnGrid()
insertItemIntoGrid(child, GridCoordinate(*rowPositions, *columnPositions));
}
- ASSERT(gridRowCount() >= style()->gridDefinitionRows().size());
- ASSERT(gridColumnCount() >= style()->gridDefinitionColumns().size());
+ ASSERT(gridRowCount() >= style()->gridTemplateRows().size());
+ ASSERT(gridColumnCount() >= style()->gridTemplateColumns().size());
if (autoFlow == AutoFlowNone) {
// If we did collect some grid items, they won't be placed thus never laid out.
@@ -737,22 +831,35 @@ void RenderGrid::populateExplicitGridAndOrderIterator()
{
OrderIteratorPopulator populator(m_orderIterator);
- size_t maximumRowIndex = std::max<size_t>(1, explicitGridRowCount());
- size_t maximumColumnIndex = std::max<size_t>(1, explicitGridColumnCount());
+ size_t maximumRowIndex = std::max<size_t>(1, GridResolvedPosition::explicitGridRowCount(*style()));
+ size_t maximumColumnIndex = std::max<size_t>(1, GridResolvedPosition::explicitGridColumnCount(*style()));
+ ASSERT(m_gridItemsIndexesMap.isEmpty());
+ size_t childIndex = 0;
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
populator.collectChild(child);
+ m_gridItemsIndexesMap.set(child, childIndex++);
// This function bypasses the cache (cachedGridCoordinate()) as it is used to build it.
- OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, ForRows);
- OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child, ForColumns);
-
- // |positions| is 0 if we need to run the auto-placement algorithm. Our estimation ignores
- // this case as the auto-placement algorithm will grow the grid as needed.
- if (rowPositions)
- maximumRowIndex = std::max(maximumRowIndex, rowPositions->finalPositionIndex + 1);
- if (columnPositions)
- maximumColumnIndex = std::max(maximumColumnIndex, columnPositions->finalPositionIndex + 1);
+ OwnPtr<GridSpan> rowPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForRows);
+ OwnPtr<GridSpan> columnPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *child, ForColumns);
+
+ // |positions| is 0 if we need to run the auto-placement algorithm.
+ if (rowPositions) {
+ maximumRowIndex = std::max<size_t>(maximumRowIndex, rowPositions->resolvedFinalPosition.next().toInt());
+ } else {
+ // Grow the grid for items with a definite row span, getting the largest such span.
+ GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *child, ForRows, GridResolvedPosition(0));
+ maximumRowIndex = std::max<size_t>(maximumRowIndex, positions.resolvedFinalPosition.next().toInt());
+ }
+
+ if (columnPositions) {
+ maximumColumnIndex = std::max<size_t>(maximumColumnIndex, columnPositions->resolvedFinalPosition.next().toInt());
+ } else {
+ // Grow the grid for items with a definite column span, getting the largest such span.
+ GridSpan positions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *child, ForColumns, GridResolvedPosition(0));
+ maximumColumnIndex = std::max<size_t>(maximumColumnIndex, positions.resolvedFinalPosition.next().toInt());
+ }
}
m_grid.grow(maximumRowIndex);
@@ -760,20 +867,25 @@ void RenderGrid::populateExplicitGridAndOrderIterator()
m_grid[i].grow(maximumColumnIndex);
}
+PassOwnPtr<GridCoordinate> RenderGrid::createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection, const GridSpan& specifiedPositions) const
+{
+ GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ? ForRows : ForColumns;
+ const size_t endOfCrossDirection = crossDirection == ForColumns ? gridColumnCount() : gridRowCount();
+ GridSpan crossDirectionPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *gridItem, crossDirection, GridResolvedPosition(endOfCrossDirection));
+ return adoptPtr(new GridCoordinate(specifiedDirection == ForColumns ? crossDirectionPositions : specifiedPositions, specifiedDirection == ForColumns ? specifiedPositions : crossDirectionPositions));
+}
+
void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGridItems)
{
for (size_t i = 0; i < autoGridItems.size(); ++i) {
- OwnPtr<GridSpan> majorAxisPositions = resolveGridPositionsFromStyle(autoGridItems[i], autoPlacementMajorAxisDirection());
- GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions->initialPositionIndex);
- if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) {
- insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
- continue;
- }
-
- growGrid(autoPlacementMinorAxisDirection());
- OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea();
- ASSERT(emptyGridArea);
- insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
+ OwnPtr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *autoGridItems[i], autoPlacementMajorAxisDirection());
+ GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *autoGridItems[i], autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
+
+ GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions->resolvedInitialPosition.toInt());
+ OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions->integerSpan(), minorAxisPositions.integerSpan());
+ if (!emptyGridArea)
+ emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(autoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPositions);
+ insertItemIntoGrid(autoGridItems[i], *emptyGridArea);
}
}
@@ -785,32 +897,41 @@ void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGri
void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem)
{
- OwnPtr<GridSpan> minorAxisPositions = resolveGridPositionsFromStyle(gridItem, autoPlacementMinorAxisDirection());
- ASSERT(!resolveGridPositionsFromStyle(gridItem, autoPlacementMajorAxisDirection()));
- size_t minorAxisIndex = 0;
+ OwnPtr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridItem, autoPlacementMinorAxisDirection());
+ ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridItem, autoPlacementMajorAxisDirection()));
+ GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMajorAxisDirection(), GridResolvedPosition(0));
+ OwnPtr<GridCoordinate> emptyGridArea;
if (minorAxisPositions) {
- minorAxisIndex = minorAxisPositions->initialPositionIndex;
- GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisIndex);
- if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) {
- insertItemIntoGrid(gridItem, emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
- return;
- }
+ GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisPositions->resolvedInitialPosition.toInt());
+ emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions->integerSpan(), majorAxisPositions.integerSpan());
+ if (!emptyGridArea)
+ emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions);
} else {
+ GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMinorAxisDirection(), GridResolvedPosition(0));
+
const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColumns) ? gridColumnCount() : gridRowCount();
for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++majorAxisIndex) {
GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisIndex);
- if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) {
- insertItemIntoGrid(gridItem, emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
- return;
+ emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.integerSpan(), minorAxisPositions.integerSpan());
+
+ if (emptyGridArea) {
+ // Check that it fits in the minor axis direction, as we shouldn't grow in that direction here (it was already managed in populateExplicitGridAndOrderIterator()).
+ GridResolvedPosition minorAxisFinalPositionIndex = autoPlacementMinorAxisDirection() == ForColumns ? emptyGridArea->columns.resolvedFinalPosition : emptyGridArea->rows.resolvedFinalPosition;
+ const size_t endOfMinorAxis = autoPlacementMinorAxisDirection() == ForColumns ? gridColumnCount() : gridRowCount();
+ if (minorAxisFinalPositionIndex.toInt() < endOfMinorAxis)
+ break;
+
+ // Discard empty grid area as it does not fit in the minor axis direction.
+ // We don't need to create a new empty grid area yet as we might find a valid one in the next iteration.
+ emptyGridArea = nullptr;
}
}
+
+ if (!emptyGridArea)
+ emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(gridItem, autoPlacementMinorAxisDirection(), minorAxisPositions);
}
- // We didn't find an empty grid area so we need to create an extra major axis line and insert our gridItem in it.
- const size_t columnIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? m_grid[0].size() : minorAxisIndex;
- const size_t rowIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? minorAxisIndex : m_grid.size();
- growGrid(autoPlacementMajorAxisDirection());
- insertItemIntoGrid(gridItem, rowIndex, columnIndex);
+ insertItemIntoGrid(gridItem, *emptyGridArea);
}
GridTrackSizingDirection RenderGrid::autoPlacementMajorAxisDirection() const
@@ -832,6 +953,8 @@ void RenderGrid::dirtyGrid()
m_grid.resize(0);
m_gridItemCoordinate.clear();
m_gridIsDirty = true;
+ m_gridItemsOverflowingGridArea.resize(0);
+ m_gridItemsIndexesMap.clear();
}
void RenderGrid::layoutGridItems()
@@ -839,12 +962,13 @@ void RenderGrid::layoutGridItems()
placeItemsOnGrid();
GridSizingData sizingData(gridColumnCount(), gridRowCount());
- computedUsedBreadthOfGridTracks(ForColumns, sizingData);
+ computeUsedBreadthOfGridTracks(ForColumns, sizingData);
ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks));
- computedUsedBreadthOfGridTracks(ForRows, sizingData);
+ computeUsedBreadthOfGridTracks(ForRows, sizingData);
ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks));
populateGridPositions(sizingData);
+ m_gridItemsOverflowingGridArea.resize(0);
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
// Because the grid area cannot be styled, we don't need to adjust
@@ -855,7 +979,7 @@ void RenderGrid::layoutGridItems()
LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForChild(child, ForColumns, sizingData.columnTracks);
LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadthForChild(child, ForRows, sizingData.rowTracks);
- SubtreeLayoutScope layoutScope(child);
+ SubtreeLayoutScope layoutScope(*child);
if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != overrideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight()))
layoutScope.setNeedsLayout(child);
@@ -869,16 +993,23 @@ void RenderGrid::layoutGridItems()
// now, just size as if we were a regular child.
child->layoutIfNeeded();
- child->setLogicalLocation(findChildLogicalPosition(child, sizingData));
+#ifndef NDEBUG
+ const GridCoordinate& coordinate = cachedGridCoordinate(child);
+ ASSERT(coordinate.columns.resolvedInitialPosition.toInt() < sizingData.columnTracks.size());
+ ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowTracks.size());
+#endif
+ child->setLogicalLocation(findChildLogicalPosition(child));
- // For correctness, we disable some painting optimizations if we have a child overflowing its grid area.
- m_gridItemOverflowGridArea = child->logicalHeight() > overrideContainingBlockContentLogicalHeight
- || child->logicalWidth() > overrideContainingBlockContentLogicalWidth;
+ // Keep track of children overflowing their grid area as we might need to paint them even if the grid-area is
+ // not visible
+ if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight
+ || child->logicalWidth() > overrideContainingBlockContentLogicalWidth)
+ m_gridItemsOverflowingGridArea.append(child);
// If the child moved, we have to repaint it as well as any floating/positioned
// descendants. An exception is if we need a layout. In this case, we know we're going to
// repaint ourselves (and the child) anyway.
- if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
+ if (!selfNeedsLayout() && child->checkForPaintInvalidationDuringLayout())
child->repaintDuringLayoutIfMoved(oldChildRect);
}
@@ -896,243 +1027,219 @@ GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const
return m_gridItemCoordinate.get(gridItem);
}
-GridSpan RenderGrid::resolveGridPositionsFromAutoPlacementPosition(const RenderBox*, GridTrackSizingDirection, size_t initialPosition) const
+LayoutUnit RenderGrid::gridAreaBreadthForChild(const RenderBox* child, GridTrackSizingDirection direction, const Vector<GridTrack>& tracks) const
{
- // FIXME: We don't support spanning with auto positions yet. Once we do, this is wrong. Also we should make
- // sure the grid can accomodate the new item as we only grow 1 position in a given direction.
- return GridSpan(initialPosition, initialPosition);
+ const GridCoordinate& coordinate = cachedGridCoordinate(child);
+ const GridSpan& span = (direction == ForColumns) ? coordinate.columns : coordinate.rows;
+ LayoutUnit gridAreaBreadth = 0;
+ for (GridSpan::iterator trackPosition = span.begin(); trackPosition != span.end(); ++trackPosition)
+ gridAreaBreadth += tracks[trackPosition.toInt()].m_usedBreadth;
+ return gridAreaBreadth;
}
-PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionsFromStyle(const RenderBox* gridItem, GridTrackSizingDirection direction) const
+void RenderGrid::populateGridPositions(const GridSizingData& sizingData)
{
- const GridPosition& initialPosition = (direction == ForColumns) ? gridItem->style()->gridColumnStart() : gridItem->style()->gridRowStart();
- const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide;
- const GridPosition& finalPosition = (direction == ForColumns) ? gridItem->style()->gridColumnEnd() : gridItem->style()->gridRowEnd();
- const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide;
-
- // We should NEVER see both spans as they should have been handled during style resolve.
- ASSERT(!initialPosition.isSpan() || !finalPosition.isSpan());
-
- if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) {
- if (style()->gridAutoFlow() == AutoFlowNone)
- return adoptPtr(new GridSpan(0, 0));
-
- // We can't get our grid positions without running the auto placement algorithm.
- return nullptr;
- }
-
- if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
- // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
- const size_t finalResolvedPosition = resolveGridPositionFromStyle(finalPosition, finalPositionSide);
- return resolveGridPositionAgainstOppositePosition(finalResolvedPosition, initialPosition, initialPositionSide);
- }
-
- if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
- // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
- const size_t initialResolvedPosition = resolveGridPositionFromStyle(initialPosition, initialPositionSide);
- return resolveGridPositionAgainstOppositePosition(initialResolvedPosition, finalPosition, finalPositionSide);
- }
-
- size_t resolvedInitialPosition = resolveGridPositionFromStyle(initialPosition, initialPositionSide);
- size_t resolvedFinalPosition = resolveGridPositionFromStyle(finalPosition, finalPositionSide);
-
- // If 'grid-after' specifies a line at or before that specified by 'grid-before', it computes to 'span 1'.
- if (resolvedFinalPosition < resolvedInitialPosition)
- resolvedFinalPosition = resolvedInitialPosition;
+ m_columnPositions.resize(sizingData.columnTracks.size() + 1);
+ m_columnPositions[0] = borderAndPaddingStart();
+ for (size_t i = 0; i < m_columnPositions.size() - 1; ++i)
+ m_columnPositions[i + 1] = m_columnPositions[i] + sizingData.columnTracks[i].m_usedBreadth;
- return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition));
+ m_rowPositions.resize(sizingData.rowTracks.size() + 1);
+ m_rowPositions[0] = borderAndPaddingBefore();
+ for (size_t i = 0; i < m_rowPositions.size() - 1; ++i)
+ m_rowPositions[i + 1] = m_rowPositions[i] + sizingData.rowTracks[i].m_usedBreadth;
}
-size_t RenderGrid::resolveNamedGridLinePositionFromStyle(const GridPosition& position, GridPositionSide side) const
+LayoutUnit RenderGrid::startOfColumnForChild(const RenderBox* child) const
{
- ASSERT(!position.namedGridLine().isNull());
-
- const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines();
- NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
- if (it == gridLinesNames.end()) {
- if (position.isPositive())
- return 0;
- const size_t lastLine = explicitGridSizeForSide(side);
- return GridPosition::adjustGridPositionForSide(lastLine, side);
- }
-
- size_t namedGridLineIndex;
- if (position.isPositive())
- namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->value.size()) - 1;
- else
- namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integerPosition()), 0);
- return GridPosition::adjustGridPositionForSide(it->value[namedGridLineIndex], side);
+ const GridCoordinate& coordinate = cachedGridCoordinate(child);
+ LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()];
+ // The grid items should be inside the grid container's border box, that's why they need to be shifted.
+ // FIXME: This should account for the grid item's <overflow-position>.
+ return startOfColumn + marginStartForChild(child);
}
-size_t RenderGrid::resolveGridPositionFromStyle(const GridPosition& position, GridPositionSide side) const
+LayoutUnit RenderGrid::endOfColumnForChild(const RenderBox* child) const
{
- switch (position.type()) {
- case ExplicitPosition: {
- ASSERT(position.integerPosition());
-
- if (!position.namedGridLine().isNull())
- return resolveNamedGridLinePositionFromStyle(position, side);
-
- // Handle <integer> explicit position.
- if (position.isPositive())
- return GridPosition::adjustGridPositionForSide(position.integerPosition() - 1, side);
-
- size_t resolvedPosition = abs(position.integerPosition()) - 1;
- const size_t endOfTrack = explicitGridSizeForSide(side);
-
- // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line.
- if (endOfTrack < resolvedPosition)
- return 0;
+ const GridCoordinate& coordinate = cachedGridCoordinate(child);
+ LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()];
+ // The grid items should be inside the grid container's border box, that's why they need to be shifted.
+ LayoutUnit columnPosition = startOfColumn + marginStartForChild(child);
- return GridPosition::adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
- }
- case NamedGridAreaPosition:
- {
- NamedGridAreaMap::const_iterator it = style()->namedGridArea().find(position.namedGridLine());
- // Unknown grid area should have been computed to 'auto' by now.
- ASSERT_WITH_SECURITY_IMPLICATION(it != style()->namedGridArea().end());
- const GridCoordinate& gridAreaCoordinate = it->value;
- switch (side) {
- case ColumnStartSide:
- return gridAreaCoordinate.columns.initialPositionIndex;
- case ColumnEndSide:
- return gridAreaCoordinate.columns.finalPositionIndex;
- case RowStartSide:
- return gridAreaCoordinate.rows.initialPositionIndex;
- case RowEndSide:
- return gridAreaCoordinate.rows.finalPositionIndex;
- }
- ASSERT_NOT_REACHED();
- return 0;
- }
- case AutoPosition:
- case SpanPosition:
- // 'auto' and span depend on the opposite position for resolution (e.g. grid-row: auto / 1 or grid-column: span 3 / "myHeader").
- ASSERT_NOT_REACHED();
- return 0;
- }
- ASSERT_NOT_REACHED();
- return 0;
+ LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFinalPosition.next().toInt()];
+ // FIXME: This should account for the grid item's <overflow-position>.
+ return columnPosition + std::max<LayoutUnit>(0, endOfColumn - m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()] - child->logicalWidth());
}
-PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side) const
+LayoutUnit RenderGrid::columnPositionAlignedWithGridContainerStart(const RenderBox* child) const
{
- if (position.isAuto())
- return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition);
+ if (style()->isLeftToRightDirection())
+ return startOfColumnForChild(child);
- ASSERT(position.isSpan());
- ASSERT(position.spanPosition() > 0);
-
- if (!position.namedGridLine().isNull()) {
- // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position.
- return resolveNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, side);
- }
-
- return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, position, side);
+ return endOfColumnForChild(child);
}
-PassOwnPtr<GridSpan> RenderGrid::resolveNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side) const
+LayoutUnit RenderGrid::columnPositionAlignedWithGridContainerEnd(const RenderBox* child) const
{
- ASSERT(position.isSpan());
- ASSERT(!position.namedGridLine().isNull());
- // Negative positions are not allowed per the specification and should have been handled during parsing.
- ASSERT(position.spanPosition() > 0);
+ if (!style()->isLeftToRightDirection())
+ return startOfColumnForChild(child);
- const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines();
- NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
-
- // If there is no named grid line of that name, we resolve the position to 'auto' (which is equivalent to 'span 1' in this case).
- // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
- if (it == gridLinesNames.end())
- return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition);
-
- return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, it->value);
+ return endOfColumnForChild(child);
}
-LayoutUnit RenderGrid::gridAreaBreadthForChild(const RenderBox* child, GridTrackSizingDirection direction, const Vector<GridTrack>& tracks) const
+LayoutUnit RenderGrid::centeredColumnPositionForChild(const RenderBox* child) const
{
const GridCoordinate& coordinate = cachedGridCoordinate(child);
- const GridSpan& span = (direction == ForColumns) ? coordinate.columns : coordinate.rows;
- LayoutUnit gridAreaBreadth = 0;
- for (size_t trackIndex = span.initialPositionIndex; trackIndex <= span.finalPositionIndex; ++trackIndex)
- gridAreaBreadth += tracks[trackIndex].m_usedBreadth;
- return gridAreaBreadth;
+ LayoutUnit startOfColumn = m_columnPositions[coordinate.columns.resolvedInitialPosition.toInt()];
+ LayoutUnit endOfColumn = m_columnPositions[coordinate.columns.resolvedFinalPosition.next().toInt()];
+ LayoutUnit columnPosition = startOfColumn + marginStartForChild(child);
+ return columnPosition + std::max<LayoutUnit>(0, endOfColumn - startOfColumn - child->logicalWidth()) / 2;
}
-void RenderGrid::populateGridPositions(const GridSizingData& sizingData)
+LayoutUnit RenderGrid::columnPositionForChild(const RenderBox* child) const
{
- m_columnPositions.resize(sizingData.columnTracks.size() + 1);
- m_columnPositions[0] = borderAndPaddingStart();
- for (size_t i = 0; i < m_columnPositions.size() - 1; ++i)
- m_columnPositions[i + 1] = m_columnPositions[i] + sizingData.columnTracks[i].m_usedBreadth;
+ ItemPosition childJustifySelf = child->style()->justifySelf();
+ switch (childJustifySelf) {
+ case ItemPositionSelfStart:
+ // self-start is based on the child's direction. That's why we need to check against the grid container's direction.
+ if (child->style()->direction() != style()->direction())
+ return columnPositionAlignedWithGridContainerEnd(child);
+
+ return columnPositionAlignedWithGridContainerStart(child);
+ case ItemPositionSelfEnd:
+ // self-end is based on the child's direction. That's why we need to check against the grid container's direction.
+ if (child->style()->direction() != style()->direction())
+ return columnPositionAlignedWithGridContainerStart(child);
+
+ return columnPositionAlignedWithGridContainerEnd(child);
+
+ case ItemPositionFlexStart:
+ case ItemPositionFlexEnd:
+ // Only used in flex layout, for other layout, it's equivalent to 'start'.
+ return columnPositionAlignedWithGridContainerStart(child);
+
+ case ItemPositionLeft:
+ // If the property's axis is not parallel with the inline axis, this is equivalent to ‘start’.
+ if (!isHorizontalWritingMode())
+ return columnPositionAlignedWithGridContainerStart(child);
+
+ if (style()->isLeftToRightDirection())
+ return columnPositionAlignedWithGridContainerStart(child);
+
+ return columnPositionAlignedWithGridContainerEnd(child);
+ case ItemPositionRight:
+ // If the property's axis is not parallel with the inline axis, this is equivalent to ‘start’.
+ if (!isHorizontalWritingMode())
+ return columnPositionAlignedWithGridContainerStart(child);
+
+ if (style()->isLeftToRightDirection())
+ return columnPositionAlignedWithGridContainerEnd(child);
+
+ return columnPositionAlignedWithGridContainerStart(child);
+
+ case ItemPositionCenter:
+ return centeredColumnPositionForChild(child);
+ case ItemPositionStart:
+ return columnPositionAlignedWithGridContainerStart(child);
+ case ItemPositionEnd:
+ return columnPositionAlignedWithGridContainerEnd(child);
+
+ case ItemPositionAuto:
+ case ItemPositionStretch:
+ case ItemPositionBaseline:
+ // FIXME: Implement the previous values. For now, we always start align the child.
+ return startOfColumnForChild(child);
+ }
- m_rowPositions.resize(sizingData.rowTracks.size() + 1);
- m_rowPositions[0] = borderAndPaddingBefore();
- for (size_t i = 0; i < m_rowPositions.size() - 1; ++i)
- m_rowPositions[i + 1] = m_rowPositions[i] + sizingData.rowTracks[i].m_usedBreadth;
+ ASSERT_NOT_REACHED();
+ return 0;
}
-LayoutPoint RenderGrid::findChildLogicalPosition(RenderBox* child, const GridSizingData& sizingData)
+LayoutUnit RenderGrid::rowPositionForChild(const RenderBox* child) const
{
const GridCoordinate& coordinate = cachedGridCoordinate(child);
- ASSERT(coordinate.columns.initialPositionIndex < sizingData.columnTracks.size());
- ASSERT(coordinate.rows.initialPositionIndex < sizingData.rowTracks.size());
// The grid items should be inside the grid container's border box, that's why they need to be shifted.
- return LayoutPoint(m_columnPositions[coordinate.columns.initialPositionIndex] + marginStartForChild(child), m_rowPositions[coordinate.rows.initialPositionIndex] + marginBeforeForChild(child));
+ LayoutUnit startOfRow = m_rowPositions[coordinate.rows.resolvedInitialPosition.toInt()];
+ LayoutUnit rowPosition = startOfRow + marginBeforeForChild(child);
+
+ // FIXME: This function should account for 'align-self'.
+
+ return rowPosition;
+}
+
+LayoutPoint RenderGrid::findChildLogicalPosition(const RenderBox* child) const
+{
+ return LayoutPoint(columnPositionForChild(child), rowPositionForChild(child));
}
static GridSpan dirtiedGridAreas(const Vector<LayoutUnit>& coordinates, LayoutUnit start, LayoutUnit end)
{
// This function does a binary search over the coordinates.
- // FIXME: This doesn't work with grid items overflowing their grid areas and should be tested & fixed.
+ // This doesn't work with grid items overflowing their grid areas, but that is managed with m_gridItemsOverflowingGridArea.
size_t startGridAreaIndex = std::upper_bound(coordinates.begin(), coordinates.end() - 1, start) - coordinates.begin();
if (startGridAreaIndex > 0)
--startGridAreaIndex;
size_t endGridAreaIndex = std::upper_bound(coordinates.begin() + startGridAreaIndex, coordinates.end() - 1, end) - coordinates.begin();
+ if (endGridAreaIndex > 0)
+ --endGridAreaIndex;
+
return GridSpan(startGridAreaIndex, endGridAreaIndex);
}
-void RenderGrid::paintChildrenSlowCase(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
-{
- for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next())
- paintChild(child, paintInfo, paintOffset);
-}
+class GridItemsSorter {
+public:
+ bool operator()(const std::pair<RenderBox*, size_t> firstChild, const std::pair<RenderBox*, size_t> secondChild) const
+ {
+ if (firstChild.first->style()->order() != secondChild.first->style()->order())
+ return firstChild.first->style()->order() < secondChild.first->style()->order();
+
+ return firstChild.second < secondChild.second;
+ }
+};
void RenderGrid::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ASSERT_WITH_SECURITY_IMPLICATION(!gridIsDirty());
- if (m_gridItemOverflowGridArea) {
- paintChildrenSlowCase(paintInfo, paintOffset);
- return;
- }
-
LayoutRect localRepaintRect = paintInfo.rect;
localRepaintRect.moveBy(-paintOffset);
GridSpan dirtiedColumns = dirtiedGridAreas(m_columnPositions, localRepaintRect.x(), localRepaintRect.maxX());
GridSpan dirtiedRows = dirtiedGridAreas(m_rowPositions, localRepaintRect.y(), localRepaintRect.maxY());
- OrderIterator paintIterator(this);
- {
- OrderIteratorPopulator populator(paintIterator);
-
- for (size_t row = dirtiedRows.initialPositionIndex; row < dirtiedRows.finalPositionIndex; ++row) {
- for (size_t column = dirtiedColumns.initialPositionIndex; column < dirtiedColumns.finalPositionIndex; ++column) {
- const Vector<RenderBox*, 1>& children = m_grid[row][column];
- // FIXME: If we start adding spanning children in all grid areas they span, this
- // would make us paint them several times, which is wrong!
- for (size_t j = 0; j < children.size(); ++j)
- populator.storeChild(children[j]);
- }
+ Vector<std::pair<RenderBox*, size_t> > gridItemsToBePainted;
+
+ for (GridSpan::iterator row = dirtiedRows.begin(); row != dirtiedRows.end(); ++row) {
+ for (GridSpan::iterator column = dirtiedColumns.begin(); column != dirtiedColumns.end(); ++column) {
+ const Vector<RenderBox*, 1>& children = m_grid[row.toInt()][column.toInt()];
+ for (size_t j = 0; j < children.size(); ++j)
+ gridItemsToBePainted.append(std::make_pair(children[j], m_gridItemsIndexesMap.get(children[j])));
}
}
- for (RenderBox* child = paintIterator.first(); child; child = paintIterator.next())
- paintChild(child, paintInfo, paintOffset);
+ for (Vector<RenderBox*>::const_iterator it = m_gridItemsOverflowingGridArea.begin(); it != m_gridItemsOverflowingGridArea.end(); ++it) {
+ if ((*it)->frameRect().intersects(localRepaintRect))
+ gridItemsToBePainted.append(std::make_pair(*it, m_gridItemsIndexesMap.get(*it)));
+ }
+
+ // Sort grid items following order-modified document order.
+ // See http://www.w3.org/TR/css-flexbox/#order-modified-document-order
+ std::stable_sort(gridItemsToBePainted.begin(), gridItemsToBePainted.end(), GridItemsSorter());
+
+ RenderBox* previous = 0;
+ for (Vector<std::pair<RenderBox*, size_t> >::const_iterator it = gridItemsToBePainted.begin(); it != gridItemsToBePainted.end(); ++it) {
+ // We might have duplicates because of spanning children are included in all cells they span.
+ // Skip them here to avoid painting items several times.
+ RenderBox* current = (*it).first;
+ if (current == previous)
+ continue;
+
+ paintChild(current, paintInfo, paintOffset);
+ previous = current;
+ }
}
const char* RenderGrid::renderName() const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderGrid.h b/chromium/third_party/WebKit/Source/core/rendering/RenderGrid.h
index f8a4de326f5..d06e2632141 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderGrid.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderGrid.h
@@ -28,6 +28,7 @@
#include "core/rendering/OrderIterator.h"
#include "core/rendering/RenderBlock.h"
+#include "core/rendering/style/GridResolvedPosition.h"
namespace WebCore {
@@ -35,11 +36,6 @@ struct GridCoordinate;
struct GridSpan;
class GridTrack;
-enum GridTrackSizingDirection {
- ForColumns,
- ForRows
-};
-
class RenderGrid FINAL : public RenderBlock {
public:
RenderGrid(Element*);
@@ -47,7 +43,7 @@ public:
virtual const char* renderName() const OVERRIDE;
- virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
+ virtual void layoutBlock(bool relayoutChildren) OVERRIDE;
virtual bool avoidsFloats() const OVERRIDE { return true; }
virtual bool canCollapseAnonymousBlockChild() const OVERRIDE { return false; }
@@ -63,6 +59,7 @@ private:
virtual void computePreferredLogicalWidths() OVERRIDE;
virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
+ void addChildToIndexesMap(RenderBox*);
virtual void removeChild(RenderObject*) OVERRIDE;
virtual void styleDidChange(StyleDifference, const RenderStyle*) OVERRIDE;
@@ -72,18 +69,19 @@ private:
class GridIterator;
struct GridSizingData;
- void computedUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&);
- void computedUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&, LayoutUnit& availableLogicalSpace);
+ bool gridElementIsShrinkToFit();
+ void computeUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&);
+ void computeUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&, LayoutUnit& availableLogicalSpace);
LayoutUnit computeUsedBreadthOfMinLength(GridTrackSizingDirection, const GridLength&) const;
LayoutUnit computeUsedBreadthOfMaxLength(GridTrackSizingDirection, const GridLength&, LayoutUnit usedBreadth) const;
LayoutUnit computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirection, const Length&) const;
void resolveContentBasedTrackSizingFunctions(GridTrackSizingDirection, GridSizingData&, LayoutUnit& availableLogicalSpace);
- void growGrid(GridTrackSizingDirection);
- void insertItemIntoGrid(RenderBox*, size_t rowTrack, size_t columnTrack);
+ void ensureGridSize(size_t maximumRowIndex, size_t maximumColumnIndex);
void insertItemIntoGrid(RenderBox*, const GridCoordinate&);
void placeItemsOnGrid();
void populateExplicitGridAndOrderIterator();
+ PassOwnPtr<GridCoordinate> createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(const RenderBox*, GridTrackSizingDirection, const GridSpan& specifiedPositions) const;
void placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>&);
void placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>&);
void placeAutoMajorAxisItemOnGrid(RenderBox*);
@@ -93,8 +91,6 @@ private:
void layoutGridItems();
void populateGridPositions(const GridSizingData&);
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
typedef LayoutUnit (RenderGrid::* SizingFunction)(RenderBox*, GridTrackSizingDirection, Vector<GridTrack>&);
typedef LayoutUnit (GridTrack::* AccumulatorGetter)() const;
typedef void (GridTrack::* AccumulatorGrowFunction)(LayoutUnit);
@@ -102,32 +98,26 @@ private:
void resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection, GridSizingData&, RenderBox*, FilterFunction, SizingFunction, AccumulatorGetter, AccumulatorGrowFunction);
void distributeSpaceToTracks(Vector<GridTrack*>&, Vector<GridTrack*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter, AccumulatorGrowFunction, GridSizingData&, LayoutUnit& availableLogicalSpace);
- double computeNormalizedFractionBreadth(Vector<GridTrack>&, GridTrackSizingDirection, LayoutUnit availableLogicalSpace) const;
+ double computeNormalizedFractionBreadth(Vector<GridTrack>&, const GridSpan& tracksSpan, GridTrackSizingDirection, LayoutUnit availableLogicalSpace) const;
const GridTrackSize& gridTrackSize(GridTrackSizingDirection, size_t) const;
- size_t explicitGridColumnCount() const;
- size_t explicitGridRowCount() const;
- size_t explicitGridSizeForSide(GridPositionSide) const;
- LayoutUnit logicalContentHeightForChild(RenderBox*, Vector<GridTrack>&);
+ LayoutUnit logicalHeightForChild(RenderBox*, Vector<GridTrack>&);
LayoutUnit minContentForChild(RenderBox*, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
LayoutUnit maxContentForChild(RenderBox*, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
- LayoutPoint findChildLogicalPosition(RenderBox*, const GridSizingData&);
+ LayoutUnit startOfColumnForChild(const RenderBox* child) const;
+ LayoutUnit endOfColumnForChild(const RenderBox* child) const;
+ LayoutUnit columnPositionAlignedWithGridContainerStart(const RenderBox*) const;
+ LayoutUnit columnPositionAlignedWithGridContainerEnd(const RenderBox*) const;
+ LayoutUnit centeredColumnPositionForChild(const RenderBox*) const;
+ LayoutUnit columnPositionForChild(const RenderBox*) const;
+ LayoutUnit rowPositionForChild(const RenderBox*) const;
+ LayoutPoint findChildLogicalPosition(const RenderBox*) const;
GridCoordinate cachedGridCoordinate(const RenderBox*) const;
- GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderBox*, GridTrackSizingDirection, size_t) const;
- PassOwnPtr<GridSpan> resolveGridPositionsFromStyle(const RenderBox*, GridTrackSizingDirection) const;
- size_t resolveNamedGridLinePositionFromStyle(const GridPosition&, GridPositionSide) const;
- size_t resolveGridPositionFromStyle(const GridPosition&, GridPositionSide) const;
- PassOwnPtr<GridSpan> resolveGridPositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, GridPositionSide) const;
- PassOwnPtr<GridSpan> resolveNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, GridPositionSide) const;
- PassOwnPtr<GridSpan> resolveBeforeStartNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, const Vector<size_t>&) const;
- PassOwnPtr<GridSpan> resolveAfterEndNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition&, const Vector<size_t>&) const;
-
LayoutUnit gridAreaBreadthForChild(const RenderBox* child, GridTrackSizingDirection, const Vector<GridTrack>&) const;
- virtual void paintChildren(PaintInfo&, const LayoutPoint&) OVERRIDE FINAL;
- void paintChildrenSlowCase(PaintInfo&, const LayoutPoint&);
+ virtual void paintChildren(PaintInfo&, const LayoutPoint&) OVERRIDE;
bool gridIsDirty() const { return m_gridIsDirty; }
@@ -154,7 +144,8 @@ private:
Vector<LayoutUnit> m_columnPositions;
HashMap<const RenderBox*, GridCoordinate> m_gridItemCoordinate;
OrderIterator m_orderIterator;
- bool m_gridItemOverflowGridArea;
+ Vector<RenderBox*> m_gridItemsOverflowingGridArea;
+ HashMap<const RenderBox*, size_t> m_gridItemsIndexesMap;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderGrid, isRenderGrid());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.cpp
index 96a06bbb5fd..41a29420906 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.cpp
@@ -28,8 +28,8 @@
#include "core/html/HTMLCanvasElement.h"
#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/Page.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderView.h"
@@ -44,13 +44,9 @@ RenderHTMLCanvas::RenderHTMLCanvas(HTMLCanvasElement* element)
view()->frameView()->setIsVisuallyNonEmpty();
}
-bool RenderHTMLCanvas::requiresLayer() const
+LayerType RenderHTMLCanvas::layerTypeRequired() const
{
- if (RenderReplaced::requiresLayer())
- return true;
-
- HTMLCanvasElement* canvas = toHTMLCanvasElement(node());
- return canvas && canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
+ return NormalLayer;
}
void RenderHTMLCanvas::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -69,8 +65,13 @@ void RenderHTMLCanvas::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& pa
paintInfo.context->clip(pixelSnappedIntRect(contentRect));
}
- bool useLowQualityScale = style()->imageRendering() == ImageRenderingOptimizeContrast;
- toHTMLCanvasElement(node())->paint(context, paintRect, useLowQualityScale);
+ // FIXME: InterpolationNone should be used if ImageRenderingOptimizeContrast is set.
+ // See bug for more details: crbug.com/353716.
+ InterpolationQuality interpolationQuality = style()->imageRendering() == ImageRenderingOptimizeContrast ? InterpolationLow : CanvasDefaultInterpolationQuality;
+ InterpolationQuality previousInterpolationQuality = context->imageInterpolationQuality();
+ context->setImageInterpolationQuality(interpolationQuality);
+ toHTMLCanvasElement(node())->paint(context, paintRect);
+ context->setImageInterpolationQuality(previousInterpolationQuality);
if (clip)
context->restore();
@@ -99,7 +100,19 @@ void RenderHTMLCanvas::canvasSizeChanged()
return;
if (!selfNeedsLayout())
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
+}
+
+CompositingReasons RenderHTMLCanvas::additionalCompositingReasons(CompositingTriggerFlags triggers) const
+{
+ if (!(triggers & CanvasTrigger))
+ return CompositingReasonNone;
+
+ HTMLCanvasElement* canvas = toHTMLCanvasElement(node());
+ if (canvas->renderingContext() && canvas->renderingContext()->isAccelerated())
+ return CompositingReasonCanvas;
+
+ return CompositingReasonNone;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.h b/chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.h
index 6cdaf64a1da..c06ee44cefc 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderHTMLCanvas.h
@@ -36,15 +36,17 @@ class RenderHTMLCanvas FINAL : public RenderReplaced {
public:
explicit RenderHTMLCanvas(HTMLCanvasElement*);
- virtual bool isCanvas() const { return true; }
- virtual bool requiresLayer() const;
+ virtual bool isCanvas() const OVERRIDE { return true; }
+ virtual LayerType layerTypeRequired() const OVERRIDE;
void canvasSizeChanged();
private:
- virtual const char* renderName() const { return "RenderHTMLCanvas"; }
- virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
- virtual void intrinsicSizeChanged() { canvasSizeChanged(); }
+ virtual const char* renderName() const OVERRIDE { return "RenderHTMLCanvas"; }
+ virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void intrinsicSizeChanged() OVERRIDE { canvasSizeChanged(); }
+
+ virtual CompositingReasons additionalCompositingReasons(CompositingTriggerFlags) const OVERRIDE;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderHTMLCanvas, isCanvas());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.cpp
index 85016ccc523..e783f196778 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.cpp
@@ -26,11 +26,10 @@
#include "config.h"
#include "core/rendering/RenderIFrame.h"
-#include "HTMLNames.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/frame/Frame.h"
+#include "core/HTMLNames.h"
#include "core/frame/FrameView.h"
-#include "core/rendering/LayoutRectRecorder.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLIFrameElement.h"
#include "core/rendering/RenderView.h"
namespace WebCore {
@@ -44,99 +43,32 @@ RenderIFrame::RenderIFrame(Element* element)
bool RenderIFrame::shouldComputeSizeAsReplaced() const
{
- // When we're seamless, we use normal block/box sizing code except when inline.
- return !isSeamless();
+ return true;
}
bool RenderIFrame::isInlineBlockOrInlineTable() const
{
- return isSeamless() && isInline();
-}
-
-LayoutUnit RenderIFrame::minPreferredLogicalWidth() const
-{
- if (!isSeamless())
- return RenderPart::minPreferredLogicalWidth();
-
- RenderView* childRoot = contentRootRenderer();
- if (!childRoot)
- return 0;
-
- return childRoot->minPreferredLogicalWidth() + borderAndPaddingLogicalWidth();
-}
-
-LayoutUnit RenderIFrame::maxPreferredLogicalWidth() const
-{
- if (!isSeamless())
- return RenderPart::maxPreferredLogicalWidth();
-
- RenderView* childRoot = contentRootRenderer();
- if (!childRoot)
- return 0;
-
- return childRoot->maxPreferredLogicalWidth() + borderAndPaddingLogicalWidth();
-}
-
-bool RenderIFrame::isSeamless() const
-{
- return node() && node()->hasTagName(iframeTag) && toHTMLIFrameElement(node())->shouldDisplaySeamlessly();
-}
-
-bool RenderIFrame::requiresLayer() const
-{
- return RenderPart::requiresLayer() || style()->resize() != RESIZE_NONE;
-}
-
-RenderView* RenderIFrame::contentRootRenderer() const
-{
- // FIXME: Is this always a valid cast? What about plugins?
- ASSERT(!widget() || widget()->isFrameView());
- FrameView* childFrameView = toFrameView(widget());
- return childFrameView ? childFrameView->frame().contentRenderer() : 0;
+ return isInline();
}
-void RenderIFrame::layoutSeamlessly()
+LayerType RenderIFrame::layerTypeRequired() const
{
- updateLogicalWidth();
- // FIXME: Containers set their height to 0 before laying out their kids (as we're doing here)
- // however, this causes FrameView::layout() to add vertical scrollbars, incorrectly inflating
- // the resulting contentHeight(). We'll need to make FrameView::layout() smarter.
- setLogicalHeight(0);
- updateWidgetPosition(); // Tell the Widget about our new width/height (it will also layout the child document).
-
- // Laying out our kids is normally responsible for adjusting our height, so we set it here.
- // Replaced elements normally do not respect padding, but seamless elements should: we'll add
- // both padding and border to the child's logical height here.
- FrameView* childFrameView = toFrameView(widget());
- if (childFrameView) // Widget should never be null during layout(), but just in case.
- setLogicalHeight(childFrameView->contentsHeight() + borderTop() + borderBottom() + paddingTop() + paddingBottom());
- updateLogicalHeight();
-
- updateWidgetPosition(); // Notify the Widget of our final height.
-
- // Assert that the child document did a complete layout.
- RenderView* childRoot = childFrameView ? childFrameView->frame().contentRenderer() : 0;
- ASSERT(!childFrameView || !childFrameView->layoutPending());
- ASSERT_UNUSED(childRoot, !childRoot || !childRoot->needsLayout());
+ if (style()->resize() != RESIZE_NONE)
+ return NormalLayer;
+ return RenderPart::layerTypeRequired();
}
void RenderIFrame::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
- if (isSeamless()) {
- layoutSeamlessly();
- // Do not return so as to share the layer and overflow updates below.
- } else {
- updateLogicalWidth();
- // No kids to layout as a replaced element.
- updateLogicalHeight();
- }
+ updateLogicalWidth();
+ // No kids to layout as a replaced element.
+ updateLogicalHeight();
m_overflow.clear();
addVisualEffectOverflow();
- updateLayerTransform();
+ updateLayerTransformAfterLayout();
clearNeedsLayout();
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.h b/chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.h
index e8a6197c91d..7ec616547c0 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderIFrame.h
@@ -30,18 +30,11 @@
namespace WebCore {
-class RenderView;
-
class RenderIFrame FINAL : public RenderPart {
public:
explicit RenderIFrame(Element*);
- bool isSeamless() const;
-
private:
- virtual LayoutUnit minPreferredLogicalWidth() const OVERRIDE;
- virtual LayoutUnit maxPreferredLogicalWidth() const OVERRIDE;
-
virtual bool shouldComputeSizeAsReplaced() const OVERRIDE;
virtual bool isInlineBlockOrInlineTable() const OVERRIDE;
@@ -51,11 +44,7 @@ private:
virtual const char* renderName() const OVERRIDE { return "RenderPartObject"; } // Lying for now to avoid breaking tests
- virtual bool requiresLayer() const OVERRIDE;
-
- void layoutSeamlessly();
-
- RenderView* contentRootRenderer() const;
+ virtual LayerType layerTypeRequired() const OVERRIDE;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderIFrame, isRenderIFrame());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderImage.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderImage.cpp
index f2db1e3a3a6..610c7906446 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderImage.cpp
@@ -28,19 +28,19 @@
#include "config.h"
#include "core/rendering/RenderImage.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/editing/FrameSelection.h"
#include "core/fetch/ImageResource.h"
#include "core/fetch/ResourceLoadPriorityOptimizer.h"
#include "core/fetch/ResourceLoader.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAreaElement.h"
#include "core/html/HTMLImageElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLMapElement.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderView.h"
#include "core/svg/graphics/SVGImage.h"
@@ -57,12 +57,12 @@ using namespace HTMLNames;
RenderImage::RenderImage(Element* element)
: RenderReplaced(element, IntSize())
- , m_needsToSetSizeForAltText(false)
, m_didIncrementVisuallyNonEmptyPixelCount(false)
, m_isGeneratedContent(false)
, m_imageDevicePixelRatio(1.0f)
{
updateAltText();
+ ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->addRenderObject(this);
}
RenderImage* RenderImage::createAnonymous(Document* document)
@@ -141,22 +141,12 @@ bool RenderImage::setImageSizeForAltText(ImageResource* newImage /* = 0 */)
return true;
}
-void RenderImage::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderReplaced::styleDidChange(diff, oldStyle);
- if (m_needsToSetSizeForAltText) {
- if (!m_altText.isEmpty() && setImageSizeForAltText(m_imageResource->cachedImage()))
- imageDimensionsChanged(true /* imageSizeChanged */);
- m_needsToSetSizeForAltText = false;
- }
-}
-
void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
{
if (documentBeingDestroyed())
return;
- if (hasBoxDecorations() || hasMask())
+ if (hasBoxDecorations() || hasMask() || hasShapeOutside())
RenderReplaced::imageChanged(newImage, rect);
if (!m_imageResource)
@@ -179,29 +169,17 @@ void RenderImage::imageChanged(WrappedImagePtr newImage, const IntRect* rect)
bool imageSizeChanged = false;
// Set image dimensions, taking into account the size of the alt text.
- if (m_imageResource->errorOccurred() || !newImage) {
- if (!m_altText.isEmpty() && document().hasPendingStyleRecalc()) {
- ASSERT(node());
- if (node()) {
- m_needsToSetSizeForAltText = true;
- node()->setNeedsStyleRecalc(LocalStyleChange, StyleChangeFromRenderer);
- }
- return;
- }
+ if (m_imageResource->errorOccurred() || !newImage)
imageSizeChanged = setImageSizeForAltText(m_imageResource->cachedImage());
- }
- imageDimensionsChanged(imageSizeChanged, rect);
+ repaintOrMarkForLayout(imageSizeChanged, rect);
}
-bool RenderImage::updateIntrinsicSizeIfNeeded(const LayoutSize& newSize, bool imageSizeChanged)
+void RenderImage::updateIntrinsicSizeIfNeeded(const LayoutSize& newSize)
{
- if (newSize == intrinsicSize() && !imageSizeChanged)
- return false;
if (m_imageResource->errorOccurred() || !m_imageResource->hasImage())
- return imageSizeChanged;
+ return;
setIntrinsicSize(newSize);
- return true;
}
void RenderImage::updateInnerContentRect()
@@ -213,9 +191,11 @@ void RenderImage::updateInnerContentRect()
m_imageResource->setContainerSizeForRenderer(containerSize);
}
-void RenderImage::imageDimensionsChanged(bool imageSizeChanged, const IntRect* rect)
+void RenderImage::repaintOrMarkForLayout(bool imageSizeChangedToAccomodateAltText, const IntRect* rect)
{
- bool intrinsicSizeChanged = updateIntrinsicSizeIfNeeded(m_imageResource->intrinsicSize(style()->effectiveZoom()), imageSizeChanged);
+ LayoutSize oldIntrinsicSize = intrinsicSize();
+ LayoutSize newIntrinsicSize = m_imageResource->intrinsicSize(style()->effectiveZoom());
+ updateIntrinsicSizeIfNeeded(newIntrinsicSize);
// In the case of generated image content using :before/:after/content, we might not be
// in the render tree yet. In that case, we just need to update our intrinsic size.
@@ -224,37 +204,25 @@ void RenderImage::imageDimensionsChanged(bool imageSizeChanged, const IntRect* r
if (!containingBlock())
return;
- bool shouldRepaint = true;
- if (intrinsicSizeChanged) {
- if (!preferredLogicalWidthsDirty())
- setPreferredLogicalWidthsDirty();
+ bool imageSourceHasChangedSize = oldIntrinsicSize != newIntrinsicSize || imageSizeChangedToAccomodateAltText;
+ if (imageSourceHasChangedSize)
+ setPreferredLogicalWidthsDirty();
- bool hasOverrideSize = hasOverrideHeight() || hasOverrideWidth();
- if (!hasOverrideSize && !imageSizeChanged) {
- LogicalExtentComputedValues computedValues;
- computeLogicalWidthInRegion(computedValues);
- LayoutUnit newWidth = computedValues.m_extent;
- computeLogicalHeight(height(), 0, computedValues);
- LayoutUnit newHeight = computedValues.m_extent;
+ // If the actual area occupied by the image has changed and it is not constrained by style then a layout is required.
+ bool imageSizeIsConstrained = style()->logicalWidth().isSpecified() && style()->logicalHeight().isSpecified();
+ bool needsLayout = !imageSizeIsConstrained && imageSourceHasChangedSize;
- imageSizeChanged = width() != newWidth || height() != newHeight;
- }
+ // FIXME: We only need to recompute the containing block's preferred size if the containing block's size
+ // depends on the image's size (i.e., the container uses shrink-to-fit sizing).
+ // There's no easy way to detect that shrink-to-fit is needed, always force a layout.
+ bool containingBlockNeedsToRecomputePreferredSize = style()->logicalWidth().isPercent() || style()->logicalMaxWidth().isPercent() || style()->logicalMinWidth().isPercent();
- // FIXME: We only need to recompute the containing block's preferred size
- // if the containing block's size depends on the image's size (i.e., the container uses shrink-to-fit sizing).
- // There's no easy way to detect that shrink-to-fit is needed, always force a layout.
- bool containingBlockNeedsToRecomputePreferredSize =
- style()->logicalWidth().isPercent()
- || style()->logicalMaxWidth().isPercent()
- || style()->logicalMinWidth().isPercent();
-
- if (imageSizeChanged || hasOverrideSize || containingBlockNeedsToRecomputePreferredSize) {
- shouldRepaint = false;
- if (!selfNeedsLayout())
- setNeedsLayout();
- }
+ if (needsLayout || containingBlockNeedsToRecomputePreferredSize) {
+ setNeedsLayoutAndFullPaintInvalidation();
+ return;
}
+ // The image hasn't changed in size or its style constrains its size, so a repaint will suffice.
if (everHadLayout() && !selfNeedsLayout()) {
// The inner content rectangle is calculated during layout, but may need an update now
// (unless the box has already been scheduled for layout). In order to calculate it, we
@@ -263,22 +231,26 @@ void RenderImage::imageDimensionsChanged(bool imageSizeChanged, const IntRect* r
updateInnerContentRect();
}
- if (shouldRepaint) {
- LayoutRect repaintRect;
- if (rect) {
- // The image changed rect is in source image coordinates (pre-zooming),
- // so map from the bounds of the image to the contentsBox.
- repaintRect = enclosingIntRect(mapRect(*rect, FloatRect(FloatPoint(), m_imageResource->imageSize(1.0f)), contentBoxRect()));
- // Guard against too-large changed rects.
- repaintRect.intersect(contentBoxRect());
- } else
- repaintRect = contentBoxRect();
-
- repaintRectangle(repaintRect);
+ LayoutRect repaintRect;
+ if (rect) {
+ // The image changed rect is in source image coordinates (without zoom),
+ // so map from the bounds of the image to the contentsBox.
+ const LayoutSize imageSizeWithoutZoom = m_imageResource->imageSize(1 / style()->effectiveZoom());
+ repaintRect = enclosingIntRect(mapRect(*rect, FloatRect(FloatPoint(), imageSizeWithoutZoom), contentBoxRect()));
+ // Guard against too-large changed rects.
+ repaintRect.intersect(contentBoxRect());
+ } else {
+ repaintRect = contentBoxRect();
+ }
- // Tell any potential compositing layers that the image needs updating.
- contentChanged(ImageChanged);
+ {
+ // FIXME: We should not be allowing repaint during layout. crbug.com/339584
+ AllowPaintInvalidationScope scoper(frameView());
+ invalidatePaintRectangle(repaintRect);
}
+
+ // Tell any potential compositing layers that the image needs updating.
+ contentChanged(ImageChanged);
}
void RenderImage::notifyFinished(Resource* newImage)
@@ -361,15 +333,20 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf
// Only draw the alt text if it'll fit within the content box,
// and only if it fits above the error image.
TextRun textRun = RenderBlockFlow::constructTextRun(this, font, m_altText, style(), TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, DefaultTextRunFlags | RespectDirection);
- LayoutUnit textWidth = font.width(textRun);
+ float textWidth = font.width(textRun);
TextRunPaintInfo textRunPaintInfo(textRun);
textRunPaintInfo.bounds = FloatRect(textRectOrigin, FloatSize(textWidth, fontMetrics.height()));
context->setFillColor(resolveColor(CSSPropertyColor));
+ if (textRun.direction() == RTL) {
+ int availableWidth = cWidth - static_cast<int>(paddingWidth);
+ textOrigin.move(availableWidth - ceilf(textWidth), 0);
+ }
if (errorPictureDrawn) {
if (usableWidth >= textWidth && fontMetrics.height() <= imageOffset.height())
- context->drawText(font, textRunPaintInfo, textOrigin);
- } else if (usableWidth >= textWidth && usableHeight >= fontMetrics.height())
- context->drawText(font, textRunPaintInfo, textOrigin);
+ context->drawBidiText(font, textRunPaintInfo, textOrigin);
+ } else if (usableWidth >= textWidth && usableHeight >= fontMetrics.height()) {
+ context->drawBidiText(font, textRunPaintInfo, textOrigin);
+ }
}
}
} else if (m_imageResource->hasImage() && cWidth > 0 && cHeight > 0) {
@@ -413,21 +390,21 @@ void RenderImage::paintAreaElementFocusRing(PaintInfo& paintInfo)
return;
Element* focusedElement = document.focusedElement();
- if (!focusedElement || !isHTMLAreaElement(focusedElement))
+ if (!isHTMLAreaElement(focusedElement))
return;
- HTMLAreaElement* areaElement = toHTMLAreaElement(focusedElement);
- if (areaElement->imageElement() != node())
+ HTMLAreaElement& areaElement = toHTMLAreaElement(*focusedElement);
+ if (areaElement.imageElement() != node())
return;
// Even if the theme handles focus ring drawing for entire elements, it won't do it for
// an area within an image, so we don't call RenderTheme::supportsFocusRing here.
- Path path = areaElement->computePath(this);
+ Path path = areaElement.computePath(this);
if (path.isEmpty())
return;
- RenderStyle* areaElementStyle = areaElement->computedStyle();
+ RenderStyle* areaElementStyle = areaElement.computedStyle();
unsigned short outlineWidth = areaElementStyle->outlineWidth();
if (!outlineWidth)
return;
@@ -456,7 +433,7 @@ void RenderImage::areaElementFocusChanged(HTMLAreaElement* areaElement)
repaintRect.moveBy(-absoluteContentBox().location());
repaintRect.inflate(outlineWidth);
- repaintRectangle(repaintRect);
+ invalidatePaintRectangle(repaintRect);
}
void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect)
@@ -469,13 +446,18 @@ void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect
if (!img || img->isNull())
return;
- HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? toHTMLImageElement(node()) : 0;
+ HTMLImageElement* imageElt = isHTMLImageElement(node()) ? toHTMLImageElement(node()) : 0;
CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
Image* image = m_imageResource->image().get();
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, alignedRect.size());
+ InterpolationQuality interpolationQuality = chooseInterpolationQuality(context, image, image, alignedRect.size());
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(*this));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
InspectorInstrumentation::willPaintImage(this);
- context->drawImage(m_imageResource->image(alignedRect.width(), alignedRect.height()).get(), alignedRect, compositeOperator, shouldRespectImageOrientation(), useLowQualityScaling);
+ InterpolationQuality previousInterpolationQuality = context->imageInterpolationQuality();
+ context->setImageInterpolationQuality(interpolationQuality);
+ context->drawImage(m_imageResource->image(alignedRect.width(), alignedRect.height()).get(), alignedRect, compositeOperator, shouldRespectImageOrientation());
+ context->setImageInterpolationQuality(previousInterpolationQuality);
InspectorInstrumentation::didPaintImage(this);
}
@@ -517,7 +499,11 @@ bool RenderImage::computeBackgroundIsKnownToBeObscured()
{
if (!hasBackground())
return false;
- return foregroundIsKnownToBeOpaqueInRect(backgroundPaintedExtent(), 0);
+
+ LayoutRect paintedExtent;
+ if (!getBackgroundPaintedExtent(paintedExtent))
+ return false;
+ return foregroundIsKnownToBeOpaqueInRect(paintedExtent, 0);
}
LayoutUnit RenderImage::minimumReplacedHeight() const
@@ -527,7 +513,7 @@ LayoutUnit RenderImage::minimumReplacedHeight() const
HTMLMapElement* RenderImage::imageMap() const
{
- HTMLImageElement* i = node() && node()->hasTagName(imgTag) ? toHTMLImageElement(node()) : 0;
+ HTMLImageElement* i = isHTMLImageElement(node()) ? toHTMLImageElement(node()) : 0;
return i ? i->treeScope().getImageMap(i->fastGetAttribute(usemapAttr)) : 0;
}
@@ -560,35 +546,22 @@ void RenderImage::updateAltText()
if (!node())
return;
- if (node()->hasTagName(inputTag))
+ if (isHTMLInputElement(*node()))
m_altText = toHTMLInputElement(node())->altText();
- else if (node()->hasTagName(imgTag))
+ else if (isHTMLImageElement(*node()))
m_altText = toHTMLImageElement(node())->altText();
}
void RenderImage::layout()
{
- LayoutRectRecorder recorder(*this);
RenderReplaced::layout();
updateInnerContentRect();
}
-void RenderImage::didLayout(ResourceLoadPriorityOptimizer& optimizer)
-{
- RenderReplaced::didLayout(optimizer);
- updateImageLoadingPriority(optimizer);
-}
-
-void RenderImage::didScroll(ResourceLoadPriorityOptimizer& optimizer)
-{
- RenderReplaced::didScroll(optimizer);
- updateImageLoadingPriority(optimizer);
-}
-
-void RenderImage::updateImageLoadingPriority(ResourceLoadPriorityOptimizer& optimizer)
+bool RenderImage::updateImageLoadingPriorities()
{
if (!m_imageResource || !m_imageResource->cachedImage() || m_imageResource->cachedImage()->isLoaded())
- return;
+ return false;
LayoutRect viewBounds = viewRect();
LayoutRect objectBounds = absoluteContentBox();
@@ -604,20 +577,28 @@ void RenderImage::updateImageLoadingPriority(ResourceLoadPriorityOptimizer& opti
ResourceLoadPriorityOptimizer::VisibilityStatus status = isVisible ?
ResourceLoadPriorityOptimizer::Visible : ResourceLoadPriorityOptimizer::NotVisible;
- optimizer.notifyImageResourceVisibility(m_imageResource->cachedImage(), status);
+ LayoutRect screenArea;
+ if (!objectBounds.isEmpty()) {
+ screenArea = viewBounds;
+ screenArea.intersect(objectBounds);
+ }
+
+ ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->notifyImageResourceVisibility(m_imageResource->cachedImage(), status, screenArea);
+
+ return true;
}
-void RenderImage::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
+void RenderImage::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const
{
- RenderReplaced::computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
+ RenderReplaced::computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio);
// Our intrinsicSize is empty if we're rendering generated images with relative width/height. Figure out the right intrinsic size to use.
if (intrinsicSize.isEmpty() && (m_imageResource->imageHasRelativeWidth() || m_imageResource->imageHasRelativeHeight())) {
RenderObject* containingBlock = isOutOfFlowPositioned() ? container() : this->containingBlock();
if (containingBlock->isBox()) {
RenderBox* box = toRenderBox(containingBlock);
- intrinsicSize.setWidth(box->availableLogicalWidth());
- intrinsicSize.setHeight(box->availableLogicalHeight(IncludeMarginBorderPadding));
+ intrinsicSize.setWidth(box->availableLogicalWidth().toFloat());
+ intrinsicSize.setHeight(box->availableLogicalHeight(IncludeMarginBorderPadding).toFloat());
}
}
// Don't compute an intrinsic ratio to preserve historical WebKit behavior if we're painting alt text and/or a broken image.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderImage.h b/chromium/third_party/WebKit/Source/core/rendering/RenderImage.h
index d7e67f0c7e3..0313703b8c7 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderImage.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderImage.h
@@ -67,32 +67,28 @@ public:
protected:
virtual bool needsPreferredWidthsRecalculation() const OVERRIDE FINAL;
virtual RenderBox* embeddedContentBox() const OVERRIDE FINAL;
- virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const OVERRIDE FINAL;
+ virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const OVERRIDE FINAL;
- virtual void styleDidChange(StyleDifference, const RenderStyle*) OVERRIDE FINAL;
-
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
void paintIntoRect(GraphicsContext*, const LayoutRect&);
virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE FINAL;
- virtual void layout();
- virtual void didLayout(ResourceLoadPriorityOptimizer&);
- virtual void didScroll(ResourceLoadPriorityOptimizer&);
- void updateImageLoadingPriority(ResourceLoadPriorityOptimizer&);
+ virtual void layout() OVERRIDE;
+ virtual bool updateImageLoadingPriorities() OVERRIDE FINAL;
- virtual void intrinsicSizeChanged()
+ virtual void intrinsicSizeChanged() OVERRIDE
{
if (m_imageResource)
imageChanged(m_imageResource->imagePtr());
}
private:
- virtual const char* renderName() const { return "RenderImage"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderImage"; }
- virtual bool isImage() const { return true; }
+ virtual bool isImage() const OVERRIDE { return true; }
virtual bool isRenderImage() const OVERRIDE FINAL { return true; }
- virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
+ virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE;
virtual bool foregroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect, unsigned maxDepthToTest) const OVERRIDE FINAL;
virtual bool computeBackgroundIsKnownToBeObscured() OVERRIDE FINAL;
@@ -105,8 +101,8 @@ private:
virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const OVERRIDE FINAL;
IntSize imageSizeForError(ImageResource*) const;
- void imageDimensionsChanged(bool imageSizeChanged, const IntRect* = 0);
- bool updateIntrinsicSizeIfNeeded(const LayoutSize&, bool imageSizeChanged);
+ void repaintOrMarkForLayout(bool imageSizeChanged, const IntRect* = 0);
+ void updateIntrinsicSizeIfNeeded(const LayoutSize&);
// Update the size of the image to be rendered. Object-fit may cause this to be different from the CSS box's content rect.
void updateInnerContentRect();
@@ -115,7 +111,6 @@ private:
// Text to display as long as the image isn't available.
String m_altText;
OwnPtr<RenderImageResource> m_imageResource;
- bool m_needsToSetSizeForAltText;
bool m_didIncrementVisuallyNonEmptyPixelCount;
bool m_isGeneratedContent;
float m_imageDevicePixelRatio;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.cpp
index 12ab7231776..79fd0804e73 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.cpp
@@ -87,7 +87,7 @@ void RenderImageResource::resetAnimation()
image()->resetAnimation();
if (!m_renderer->needsLayout())
- m_renderer->repaint();
+ m_renderer->paintInvalidationForWholeRenderer();
}
void RenderImageResource::setContainerSizeForRenderer(const IntSize& imageContainerSize)
@@ -97,11 +97,6 @@ void RenderImageResource::setContainerSizeForRenderer(const IntSize& imageContai
m_cachedImage->setContainerSizeForRenderer(m_renderer, imageContainerSize, m_renderer->style()->effectiveZoom());
}
-Image* RenderImageResource::nullImage()
-{
- return Image::nullImage();
-}
-
LayoutSize RenderImageResource::getImageSize(float multiplier, ImageResource::SizeType type) const
{
if (!m_cachedImage)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.h b/chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.h
index cae42e2eb03..2850d72ba5b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderImageResource.h
@@ -29,8 +29,6 @@
#include "core/fetch/ImageResource.h"
#include "core/fetch/ResourcePtr.h"
#include "core/rendering/style/StyleImage.h"
-#include "platform/geometry/LayoutSize.h"
-#include "platform/graphics/Image.h"
namespace WebCore {
@@ -55,7 +53,10 @@ public:
void resetAnimation();
- virtual PassRefPtr<Image> image(int /* width */ = 0, int /* height */ = 0) const { return m_cachedImage ? m_cachedImage->imageForRenderer(m_renderer) : nullImage(); }
+ virtual PassRefPtr<Image> image(int /* width */ = 0, int /* height */ = 0) const
+ {
+ return m_cachedImage ? m_cachedImage->imageForRenderer(m_renderer) : Image::nullImage();
+ }
virtual bool errorOccurred() const { return m_cachedImage && m_cachedImage->errorOccurred(); }
virtual void setContainerSizeForRenderer(const IntSize&);
@@ -74,7 +75,6 @@ protected:
ResourcePtr<ImageResource> m_cachedImage;
private:
- static Image* nullImage();
LayoutSize getImageSize(float multiplier, ImageResource::SizeType) const;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.cpp
index 5e0fff78319..eded16a0240 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.cpp
@@ -65,7 +65,7 @@ PassRefPtr<Image> RenderImageResourceStyleImage::image(int width, int height) co
{
// Generated content may trigger calls to image() while we're still pending, don't assert but gracefully exit.
if (m_styleImage->isPendingImage())
- return 0;
+ return nullptr;
return m_styleImage->image(m_renderer, IntSize(width, height));
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.h b/chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.h
index 6844e2a5811..098cc634acb 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderImageResourceStyleImage.h
@@ -34,7 +34,7 @@ namespace WebCore {
class RenderObject;
-class RenderImageResourceStyleImage : public RenderImageResource {
+class RenderImageResourceStyleImage FINAL : public RenderImageResource {
public:
virtual ~RenderImageResourceStyleImage();
@@ -42,22 +42,22 @@ public:
{
return adoptPtr(new RenderImageResourceStyleImage(styleImage));
}
- virtual void initialize(RenderObject*);
- virtual void shutdown();
+ virtual void initialize(RenderObject*) OVERRIDE;
+ virtual void shutdown() OVERRIDE;
- virtual bool hasImage() const { return true; }
- virtual PassRefPtr<Image> image(int width = 0, int height = 0) const;
- virtual bool errorOccurred() const { return m_styleImage->errorOccurred(); }
+ virtual bool hasImage() const OVERRIDE { return true; }
+ virtual PassRefPtr<Image> image(int width = 0, int height = 0) const OVERRIDE;
+ virtual bool errorOccurred() const OVERRIDE { return m_styleImage->errorOccurred(); }
- virtual void setContainerSizeForRenderer(const IntSize&);
- virtual bool usesImageContainerSize() const { return m_styleImage->usesImageContainerSize(); }
- virtual bool imageHasRelativeWidth() const { return m_styleImage->imageHasRelativeWidth(); }
- virtual bool imageHasRelativeHeight() const { return m_styleImage->imageHasRelativeHeight(); }
+ virtual void setContainerSizeForRenderer(const IntSize&) OVERRIDE;
+ virtual bool usesImageContainerSize() const OVERRIDE { return m_styleImage->usesImageContainerSize(); }
+ virtual bool imageHasRelativeWidth() const OVERRIDE { return m_styleImage->imageHasRelativeWidth(); }
+ virtual bool imageHasRelativeHeight() const OVERRIDE { return m_styleImage->imageHasRelativeHeight(); }
virtual LayoutSize imageSize(float multiplier) const OVERRIDE { return m_styleImage->imageSize(m_renderer, multiplier); }
virtual LayoutSize intrinsicSize(float multiplier) const OVERRIDE { return m_styleImage->imageSize(m_renderer, multiplier); }
- virtual WrappedImagePtr imagePtr() const { return m_styleImage->data(); }
+ virtual WrappedImagePtr imagePtr() const OVERRIDE { return m_styleImage->data(); }
private:
RenderImageResourceStyleImage(StyleImage*);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderInline.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderInline.cpp
index bd82486d441..80664b5e3b1 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderInline.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderInline.cpp
@@ -29,7 +29,6 @@
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/InlineTextBox.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderFullScreen.h"
@@ -62,7 +61,7 @@ RenderInline* RenderInline::createAnonymous(Document* document)
void RenderInline::willBeDestroyed()
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
// Make sure we do not retain "this" in the continuation outline table map of our containing blocks.
if (parent() && style()->visibility() == VISIBLE && hasOutline()) {
bool containingBlockPaintsContinuationOutline = continuation() || isInlineElementContinuation();
@@ -194,7 +193,7 @@ void RenderInline::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
bool alwaysCreateLineBoxes = hasSelfPaintingLayer() || hasBoxDecorations() || newStyle->hasPadding() || newStyle->hasMargin() || hasOutline();
if (oldStyle && alwaysCreateLineBoxes) {
dirtyLineBoxes(false);
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
}
m_alwaysCreateLineBoxes = alwaysCreateLineBoxes;
}
@@ -210,14 +209,12 @@ void RenderInline::updateAlwaysCreateLineBoxes(bool fullLayout)
RenderStyle* parentStyle = parent()->style();
RenderInline* parentRenderInline = parent()->isRenderInline() ? toRenderInline(parent()) : 0;
bool checkFonts = document().inNoQuirksMode();
- RenderFlowThread* flowThread = flowThreadContainingBlock();
bool alwaysCreateLineBoxes = (parentRenderInline && parentRenderInline->alwaysCreateLineBoxes())
|| (parentRenderInline && parentStyle->verticalAlign() != BASELINE)
|| style()->verticalAlign() != BASELINE
|| style()->textEmphasisMark() != TextEmphasisMarkNone
|| (checkFonts && (!parentStyle->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(style()->font().fontMetrics())
- || parentStyle->lineHeight() != style()->lineHeight()))
- || (flowThread && flowThread->hasRegionsWithStyling());
+ || parentStyle->lineHeight() != style()->lineHeight()));
if (!alwaysCreateLineBoxes && checkFonts && document().styleEngine()->usesFirstLineRules()) {
// Have to check the first line style as well.
@@ -283,7 +280,7 @@ RenderBoxModelObject* RenderInline::continuationBefore(RenderObject* beforeChild
RenderBoxModelObject* last = this;
while (curr) {
if (beforeChild && beforeChild->parent() == curr) {
- if (curr->firstChild() == beforeChild)
+ if (curr->slowFirstChild() == beforeChild)
return last;
return curr;
}
@@ -293,7 +290,7 @@ RenderBoxModelObject* RenderInline::continuationBefore(RenderObject* beforeChild
curr = nextContinuation(curr);
}
- if (!beforeChild && !last->firstChild())
+ if (!beforeChild && !last->slowFirstChild())
return nextToLast;
return last;
}
@@ -327,7 +324,7 @@ void RenderInline::addChildIgnoringContinuation(RenderObject* newChild, RenderOb
RenderBoxModelObject::addChild(newChild, beforeChild);
- newChild->setNeedsLayoutAndPrefWidthsRecalc();
+ newChild->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
RenderInline* RenderInline::clone() const
@@ -351,7 +348,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
// that renderer is wrapped in a RenderFullScreen, so |this| is not its
// parent. Since the splitting logic expects |this| to be the parent, set
// |beforeChild| to be the RenderFullScreen.
- if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document())) {
+ if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document())) {
const Element* fullScreenElement = fullscreen->webkitCurrentFullScreenElement();
if (fullScreenElement && beforeChild && beforeChild->node() == fullScreenElement)
beforeChild = fullscreen->fullScreenRenderer();
@@ -364,7 +361,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
RenderObject* tmp = o;
o = tmp->nextSibling();
cloneInline->addChildIgnoringContinuation(children()->removeChildNode(this, tmp), 0);
- tmp->setNeedsLayoutAndPrefWidthsRecalc();
+ tmp->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
// Hook |clone| up as the continuation of the middle block.
@@ -405,7 +402,7 @@ void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock,
RenderObject* tmp = o;
o = tmp->nextSibling();
cloneInline->addChildIgnoringContinuation(inlineCurr->children()->removeChildNode(curr, tmp), 0);
- tmp->setNeedsLayoutAndPrefWidthsRecalc();
+ tmp->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
}
@@ -466,7 +463,7 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
RenderObject* no = o;
o = no->nextSibling();
pre->children()->appendChildNode(pre, block->children()->removeChildNode(block, no));
- no->setNeedsLayoutAndPrefWidthsRecalc();
+ no->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
}
@@ -481,9 +478,9 @@ void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox
// Always just do a full layout in order to ensure that line boxes (especially wrappers for images)
// get deleted properly. Because objects moves from the pre block into the post block, we want to
// make new line boxes instead of leaving the old line boxes around.
- pre->setNeedsLayoutAndPrefWidthsRecalc();
- block->setNeedsLayoutAndPrefWidthsRecalc();
- post->setNeedsLayoutAndPrefWidthsRecalc();
+ pre->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ block->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ post->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
void RenderInline::addChildToContinuation(RenderObject* newChild, RenderObject* beforeChild)
@@ -560,13 +557,13 @@ void RenderInline::generateCulledLineBoxRects(GeneratorContext& yield, const Ren
if (curr->isBox()) {
RenderBox* currBox = toRenderBox(curr);
if (currBox->inlineBoxWrapper()) {
- RootInlineBox* rootBox = currBox->inlineBoxWrapper()->root();
- int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
- int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
+ RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root();
+ int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
+ int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
if (isHorizontal)
- yield(FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, currBox->width() + currBox->marginWidth(), logicalHeight));
+ yield(FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, (currBox->width() + currBox->marginWidth()).toFloat(), logicalHeight));
else
- yield(FloatRect(logicalTop, currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, currBox->height() + currBox->marginHeight()));
+ yield(FloatRect(logicalTop, currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, (currBox->height() + currBox->marginHeight()).toFloat()));
}
} else if (curr->isRenderInline()) {
// If the child doesn't need line boxes either, then we can recur.
@@ -575,9 +572,9 @@ void RenderInline::generateCulledLineBoxRects(GeneratorContext& yield, const Ren
currInline->generateCulledLineBoxRects(yield, container);
else {
for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox()) {
- RootInlineBox* rootBox = childLine->root();
- int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
- int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
+ RootInlineBox& rootBox = childLine->root();
+ int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
+ int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
if (isHorizontal)
yield(FloatRect(childLine->x() - childLine->marginLogicalLeft(),
logicalTop,
@@ -593,9 +590,9 @@ void RenderInline::generateCulledLineBoxRects(GeneratorContext& yield, const Ren
} else if (curr->isText()) {
RenderText* currText = toRenderText(curr);
for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox()) {
- RootInlineBox* rootBox = childText->root();
- int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
- int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
+ RootInlineBox& rootBox = childText->root();
+ int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
+ int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
if (isHorizontal)
yield(FloatRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight));
else
@@ -696,8 +693,6 @@ static LayoutUnit computeMargin(const RenderInline* renderer, const Length& marg
return margin.value();
if (margin.isPercent())
return minimumValueForLength(margin, max<LayoutUnit>(0, renderer->containingBlock()->availableLogicalWidth()));
- if (margin.isViewportPercentage())
- return valueForLength(margin, 0, renderer->view());
return 0;
}
@@ -817,7 +812,7 @@ PositionWithAffinity RenderInline::positionForPoint(const LayoutPoint& point)
RenderBoxModelObject* c = continuation();
while (c) {
RenderBox* contBlock = c->isInline() ? c->containingBlock() : toRenderBlock(c);
- if (c->isInline() || c->firstChild())
+ if (c->isInline() || c->slowFirstChild())
return c->positionForPoint(parentBlockPoint - contBlock->locationOffset());
c = toRenderBlock(c)->inlineElementContinuation();
}
@@ -984,12 +979,12 @@ LayoutRect RenderInline::linesVisualOverflowBoundingBox() const
logicalRightSide = max(logicalRightSide, curr->logicalRightVisualOverflow());
}
- RootInlineBox* firstRootBox = firstLineBox()->root();
- RootInlineBox* lastRootBox = lastLineBox()->root();
+ RootInlineBox& firstRootBox = firstLineBox()->root();
+ RootInlineBox& lastRootBox = lastLineBox()->root();
- LayoutUnit logicalTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox->lineTop());
+ LayoutUnit logicalTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox.lineTop());
LayoutUnit logicalWidth = logicalRightSide - logicalLeftSide;
- LayoutUnit logicalHeight = lastLineBox()->logicalBottomVisualOverflow(lastRootBox->lineBottom()) - logicalTop;
+ LayoutUnit logicalHeight = lastLineBox()->logicalBottomVisualOverflow(lastRootBox.lineBottom()) - logicalTop;
LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight);
if (!style()->isHorizontalWritingMode())
@@ -997,9 +992,9 @@ LayoutRect RenderInline::linesVisualOverflowBoundingBox() const
return rect;
}
-LayoutRect RenderInline::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+LayoutRect RenderInline::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
- ASSERT(!view() || !view()->layoutStateEnabled() || LayoutRectRecorder::shouldRecordLayoutRects());
+ ASSERT(!view() || !view()->layoutStateCachedOffsetsEnabled());
if (!firstLineBoxIncludingCulling() && !continuation())
return LayoutRect();
@@ -1012,7 +1007,7 @@ LayoutRect RenderInline::clippedOverflowRectForRepaint(const RenderLayerModelObj
RenderBlock* cb = containingBlock();
for (const RenderObject* inlineFlow = this; inlineFlow && inlineFlow->isRenderInline() && inlineFlow != cb;
inlineFlow = inlineFlow->parent()) {
- if (inlineFlow == repaintContainer) {
+ if (inlineFlow == paintInvalidationContainer) {
hitRepaintContainer = true;
break;
}
@@ -1032,51 +1027,51 @@ LayoutRect RenderInline::clippedOverflowRectForRepaint(const RenderLayerModelObj
if (cb->hasOverflowClip())
cb->applyCachedClipAndScrollOffsetForRepaint(repaintRect);
- cb->computeRectForRepaint(repaintContainer, repaintRect);
+ cb->mapRectToPaintInvalidationBacking(paintInvalidationContainer, repaintRect);
if (outlineSize) {
for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
if (!curr->isText())
- repaintRect.unite(curr->rectWithOutlineForRepaint(repaintContainer, outlineSize));
+ repaintRect.unite(curr->rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineSize));
}
if (continuation() && !continuation()->isInline() && continuation()->parent())
- repaintRect.unite(continuation()->rectWithOutlineForRepaint(repaintContainer, outlineSize));
+ repaintRect.unite(continuation()->rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineSize));
}
return repaintRect;
}
-LayoutRect RenderInline::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
+LayoutRect RenderInline::rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth) const
{
- LayoutRect r(RenderBoxModelObject::rectWithOutlineForRepaint(repaintContainer, outlineWidth));
+ LayoutRect r(RenderBoxModelObject::rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineWidth));
for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
if (!curr->isText())
- r.unite(curr->rectWithOutlineForRepaint(repaintContainer, outlineWidth));
+ r.unite(curr->rectWithOutlineForPaintInvalidation(paintInvalidationContainer, outlineWidth));
}
return r;
}
-void RenderInline::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
+void RenderInline::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, bool fixed) const
{
if (RenderView* v = view()) {
// LayoutState is only valid for root-relative repainting
- if (v->layoutStateEnabled() && !repaintContainer) {
+ if (v->canMapUsingLayoutStateForContainer(paintInvalidationContainer)) {
LayoutState* layoutState = v->layoutState();
if (style()->hasInFlowPosition() && layer())
rect.move(layer()->offsetForInFlowPosition());
- rect.move(layoutState->m_paintOffset);
- if (layoutState->m_clipped)
- rect.intersect(layoutState->m_clipRect);
+ rect.move(layoutState->paintOffset());
+ if (layoutState->isClipped())
+ rect.intersect(layoutState->clipRect());
return;
}
}
- if (repaintContainer == this)
+ if (paintInvalidationContainer == this)
return;
bool containerSkipped;
- RenderObject* o = container(repaintContainer, &containerSkipped);
+ RenderObject* o = container(paintInvalidationContainer, &containerSkipped);
if (!o)
return;
@@ -1111,16 +1106,16 @@ void RenderInline::computeRectForRepaint(const RenderLayerModelObject* repaintCo
}
if (containerSkipped) {
- // If the repaintContainer is below o, then we need to map the rect into repaintContainer's coordinates.
- LayoutSize containerOffset = repaintContainer->offsetFromAncestorContainer(o);
+ // If the paintInvalidationContainer is below o, then we need to map the rect into paintInvalidationContainer's coordinates.
+ LayoutSize containerOffset = paintInvalidationContainer->offsetFromAncestorContainer(o);
rect.move(-containerOffset);
return;
}
- o->computeRectForRepaint(repaintContainer, rect, fixed);
+ o->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, fixed);
}
-LayoutSize RenderInline::offsetFromContainer(RenderObject* container, const LayoutPoint& point, bool* offsetDependsOnPoint) const
+LayoutSize RenderInline::offsetFromContainer(const RenderObject* container, const LayoutPoint& point, bool* offsetDependsOnPoint) const
{
ASSERT(container == this->container());
@@ -1128,7 +1123,7 @@ LayoutSize RenderInline::offsetFromContainer(RenderObject* container, const Layo
if (isInFlowPositioned())
offset += offsetForInFlowPosition();
- container->adjustForColumns(offset, point);
+ offset += container->columnOffset(point);
if (container->hasOverflowClip())
offset -= toRenderBox(container)->scrolledContentOffset();
@@ -1148,9 +1143,9 @@ void RenderInline::mapLocalToContainer(const RenderLayerModelObject* repaintCont
return;
if (RenderView *v = view()) {
- if (v->layoutStateEnabled() && !repaintContainer) {
+ if (v->canMapUsingLayoutStateForContainer(repaintContainer)) {
LayoutState* layoutState = v->layoutState();
- LayoutSize offset = layoutState->m_paintOffset;
+ LayoutSize offset = layoutState->paintOffset();
if (style()->hasInFlowPosition() && layer())
offset += layer()->offsetForInFlowPosition();
transformState.move(offset);
@@ -1250,16 +1245,16 @@ void RenderInline::dirtyLineBoxes(bool fullLayout)
if (curr->isBox() && !curr->needsLayout()) {
RenderBox* currBox = toRenderBox(curr);
if (currBox->inlineBoxWrapper())
- currBox->inlineBoxWrapper()->root()->markDirty();
+ currBox->inlineBoxWrapper()->root().markDirty();
} else if (!curr->selfNeedsLayout()) {
if (curr->isRenderInline()) {
RenderInline* currInline = toRenderInline(curr);
for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox())
- childLine->root()->markDirty();
+ childLine->root().markDirty();
} else if (curr->isText()) {
RenderText* currText = toRenderText(curr);
for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox())
- childText->root()->markDirty();
+ childText->root().markDirty();
}
}
}
@@ -1274,7 +1269,7 @@ void RenderInline::deleteLineBoxTree()
InlineFlowBox* RenderInline::createInlineFlowBox()
{
- return new InlineFlowBox(this);
+ return new InlineFlowBox(*this);
}
InlineFlowBox* RenderInline::createAndAppendInlineFlowBox()
@@ -1290,10 +1285,10 @@ LayoutUnit RenderInline::lineHeight(bool firstLine, LineDirectionMode /*directio
if (firstLine && document().styleEngine()->usesFirstLineRules()) {
RenderStyle* s = style(firstLine);
if (s != style())
- return s->computedLineHeight(view());
+ return s->computedLineHeight();
}
- return style()->computedLineHeight(view());
+ return style()->computedLineHeight();
}
int RenderInline::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
@@ -1303,7 +1298,7 @@ int RenderInline::baselinePosition(FontBaseline baselineType, bool firstLine, Li
return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
}
-LayoutSize RenderInline::offsetForInFlowPositionedInline(const RenderBox* child) const
+LayoutSize RenderInline::offsetForInFlowPositionedInline(const RenderBox& child) const
{
// FIXME: This function isn't right with mixed writing modes.
@@ -1326,18 +1321,18 @@ LayoutSize RenderInline::offsetForInFlowPositionedInline(const RenderBox* child)
blockPosition = layer()->staticBlockPosition();
}
- if (!child->style()->hasStaticInlinePosition(style()->isHorizontalWritingMode()))
+ if (!child.style()->hasStaticInlinePosition(style()->isHorizontalWritingMode()))
logicalOffset.setWidth(inlinePosition);
// This is not terribly intuitive, but we have to match other browsers. Despite being a block display type inside
// an inline, we still keep our x locked to the left of the relative positioned inline. Arguably the correct
// behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
// do.
- else if (!child->style()->isOriginalDisplayInlineType())
+ else if (!child.style()->isOriginalDisplayInlineType())
// Avoid adding in the left border/padding of the containing block twice. Subtract it out.
- logicalOffset.setWidth(inlinePosition - child->containingBlock()->borderAndPaddingLogicalLeft());
+ logicalOffset.setWidth(inlinePosition - child.containingBlock()->borderAndPaddingLogicalLeft());
- if (!child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
+ if (!child.style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
logicalOffset.setHeight(blockPosition);
return style()->isHorizontalWritingMode() ? logicalOffset : logicalOffset.transposedSize();
@@ -1349,7 +1344,7 @@ void RenderInline::imageChanged(WrappedImagePtr, const IntRect*)
return;
// FIXME: We can do better.
- repaint();
+ paintInvalidationForWholeRenderer();
}
void RenderInline::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
@@ -1357,19 +1352,12 @@ void RenderInline::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&
AbsoluteRectsGeneratorContext context(rects, additionalOffset);
generateLineBoxRects(context);
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
- if (!curr->isText() && !curr->isListMarker()) {
- FloatPoint pos(additionalOffset);
- // FIXME: This doesn't work correctly with transforms.
- if (curr->hasLayer())
- pos = curr->localToContainerPoint(FloatPoint(), paintContainer);
- else if (curr->isBox())
- pos.move(toRenderBox(curr)->locationOffset());
- curr->addFocusRingRects(rects, flooredIntPoint(pos), paintContainer);
- }
- }
+ addChildFocusRingRects(rects, additionalOffset, paintContainer);
if (continuation()) {
+ // If the continuation doesn't paint into the same container, let its repaint container handle it.
+ if (paintContainer != continuation()->containerForPaintInvalidation())
+ return;
if (continuation()->isInline())
continuation()->addFocusRingRects(rects, flooredLayoutPoint(additionalOffset + continuation()->containingBlock()->location() - containingBlock()->location()), paintContainer);
else
@@ -1428,9 +1416,9 @@ void RenderInline::paintOutline(PaintInfo& paintInfo, const LayoutPoint& paintOf
rects.append(LayoutRect());
for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
- RootInlineBox* root = curr->root();
- LayoutUnit top = max<LayoutUnit>(root->lineTop(), curr->logicalTop());
- LayoutUnit bottom = min<LayoutUnit>(root->lineBottom(), curr->logicalBottom());
+ RootInlineBox& root = curr->root();
+ LayoutUnit top = max<LayoutUnit>(root.lineTop(), curr->logicalTop());
+ LayoutUnit bottom = min<LayoutUnit>(root.lineBottom(), curr->logicalBottom());
rects.append(LayoutRect(curr->x(), top, curr->logicalWidth(), bottom - top));
}
rects.append(LayoutRect());
@@ -1465,6 +1453,8 @@ void RenderInline::paintOutlineForLine(GraphicsContext* graphicsContext, const L
LayoutSize(thisline.width() + offset, thisline.height() + offset));
IntRect pixelSnappedBox = pixelSnappedIntRect(box);
+ if (pixelSnappedBox.width() < 0 || pixelSnappedBox.height() < 0)
+ return;
IntRect pixelSnappedLastLine = pixelSnappedIntRect(paintOffset.x() + lastline.x(), 0, lastline.width(), 0);
IntRect pixelSnappedNextLine = pixelSnappedIntRect(paintOffset.x() + nextline.x(), 0, nextline.width(), 0);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderInline.h b/chromium/third_party/WebKit/Source/core/rendering/RenderInline.h
index c69f0258daa..c2710ab5143 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderInline.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderInline.h
@@ -23,14 +23,13 @@
#ifndef RenderInline_h
#define RenderInline_h
+#include "core/animation/ActiveAnimations.h"
#include "core/rendering/InlineFlowBox.h"
#include "core/rendering/RenderBoxModelObject.h"
#include "core/rendering/RenderLineBoxList.h"
namespace WebCore {
-class Position;
-
class RenderInline : public RenderBoxModelObject {
public:
explicit RenderInline(Element*);
@@ -40,7 +39,11 @@ public:
RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
+ // If you have a RenderInline, use firstChild or lastChild instead.
+ void slowFirstChild() const WTF_DELETED_FUNCTION;
+ void slowLastChild() const WTF_DELETED_FUNCTION;
+
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
Element* node() const { return toElement(RenderBoxModelObject::node()); }
@@ -54,9 +57,9 @@ public:
virtual LayoutUnit marginEnd(const RenderStyle* otherStyle = 0) const OVERRIDE FINAL;
virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE FINAL;
- virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
+ virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE;
- virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const OVERRIDE FINAL;
+ virtual LayoutSize offsetFromContainer(const RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const OVERRIDE FINAL;
IntRect linesBoundingBox() const;
LayoutRect linesVisualOverflowBoundingBox() const;
@@ -79,7 +82,7 @@ public:
virtual void updateDragState(bool dragOn) OVERRIDE FINAL;
- LayoutSize offsetForInFlowPositionedInline(const RenderBox* child) const;
+ LayoutSize offsetForInFlowPositionedInline(const RenderBox& child) const;
virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE FINAL;
void paintOutline(PaintInfo&, const LayoutPoint&);
@@ -96,7 +99,7 @@ public:
bool hitTestCulledInline(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset);
protected:
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
@@ -108,7 +111,7 @@ private:
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
- virtual const char* renderName() const;
+ virtual const char* renderName() const OVERRIDE;
virtual bool isRenderInline() const OVERRIDE FINAL { return true; }
@@ -135,16 +138,16 @@ private:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE FINAL;
- virtual bool requiresLayer() const { return isInFlowPositioned() || createsGroup() || hasClipPath(); }
+ virtual LayerType layerTypeRequired() const OVERRIDE { return isInFlowPositioned() || createsGroup() || hasClipPath() || style()->shouldCompositeForCurrentAnimations() ? NormalLayer : NoLayer; }
virtual LayoutUnit offsetLeft() const OVERRIDE FINAL;
virtual LayoutUnit offsetTop() const OVERRIDE FINAL;
virtual LayoutUnit offsetWidth() const OVERRIDE FINAL { return linesBoundingBox().width(); }
virtual LayoutUnit offsetHeight() const OVERRIDE FINAL { return linesBoundingBox().height(); }
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const OVERRIDE FINAL;
- virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed) const OVERRIDE FINAL;
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE;
+ virtual LayoutRect rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth) const OVERRIDE FINAL;
+ virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed) const OVERRIDE FINAL;
virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderInputSpeech.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderInputSpeech.cpp
deleted file mode 100644
index 85134417040..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderInputSpeech.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#if ENABLE(INPUT_SPEECH)
-#include "core/rendering/RenderInputSpeech.h"
-
-#include "core/html/shadow/TextControlInnerElements.h"
-#include "core/rendering/PaintInfo.h"
-#include "core/rendering/RenderBox.h"
-#include "platform/graphics/GraphicsContext.h"
-
-namespace WebCore {
-
-static const float defaultControlFontPixelSize = 13;
-static const float defaultSpeechButtonSize = 16;
-static const float minSpeechButtonSize = 8;
-static const float maxSpeechButtonSize = 40;
-
-void RenderInputSpeech::adjustInputFieldSpeechButtonStyle(RenderStyle* style, Element*)
-{
- // Scale the button size based on the font size.
- float fontScale = style->fontSize() / defaultControlFontPixelSize;
- int speechButtonSize = lroundf(std::min(std::max(minSpeechButtonSize, defaultSpeechButtonSize * fontScale), maxSpeechButtonSize));
- style->setWidth(Length(speechButtonSize, Fixed));
- style->setHeight(Length(speechButtonSize, Fixed));
-}
-
-bool RenderInputSpeech::paintInputFieldSpeechButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
-{
- Element* element = object->node()->isElementNode() ? toElement(object->node()) : 0;
- if (!element || !element->isInputFieldSpeechButtonElement())
- return false;
-
- // Get the renderer of <input> element.
- Node* input = object->node()->shadowHost();
- if (!input->renderer()->isBox())
- return false;
- RenderBox* inputRenderBox = toRenderBox(input->renderer());
- LayoutRect inputContentBox = inputRenderBox->contentBoxRect();
-
- // Make sure the scaled button stays square and will fit in its parent's box.
- LayoutUnit buttonSize = std::min(inputContentBox.width(), std::min<LayoutUnit>(inputContentBox.height(), rect.height()));
- // Calculate button's coordinates relative to the input element.
- // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will
- // be one pixel closer to the bottom of the field. This tends to look better with the text.
- LayoutRect buttonRect(object->offsetFromAncestorContainer(inputRenderBox).width(),
- inputContentBox.y() + (inputContentBox.height() - buttonSize + 1) / 2,
- buttonSize, buttonSize);
-
- // Compute an offset between the part renderer and the input renderer.
- LayoutSize offsetFromInputRenderer = -(object->offsetFromAncestorContainer(inputRenderBox));
- // Move the rect into partRenderer's coords.
- buttonRect.move(offsetFromInputRenderer);
- // Account for the local drawing offset.
- buttonRect.moveBy(rect.location());
-
- DEFINE_STATIC_REF(Image, imageStateNormal, (Image::loadPlatformResource("inputSpeech")));
- DEFINE_STATIC_REF(Image, imageStateRecording, (Image::loadPlatformResource("inputSpeechRecording")));
- DEFINE_STATIC_REF(Image, imageStateWaiting, (Image::loadPlatformResource("inputSpeechWaiting")));
-
- InputFieldSpeechButtonElement* speechButton = toInputFieldSpeechButtonElement(element);
- Image* image = imageStateNormal;
- if (speechButton->state() == InputFieldSpeechButtonElement::Recording)
- image = imageStateRecording;
- else if (speechButton->state() == InputFieldSpeechButtonElement::Recognizing)
- image = imageStateWaiting;
- paintInfo.context->drawImage(image, pixelSnappedIntRect(buttonRect));
-
- return false;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderInputSpeech.h b/chromium/third_party/WebKit/Source/core/rendering/RenderInputSpeech.h
deleted file mode 100644
index e1d8c6e1ee8..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderInputSpeech.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RenderInputSpeech_h
-#define RenderInputSpeech_h
-
-#if ENABLE(INPUT_SPEECH)
-
-namespace WebCore {
-
-struct PaintInfo;
-
-class Element;
-class IntRect;
-class RenderObject;
-class RenderStyle;
-class StyleResolver;
-
-class RenderInputSpeech {
-public:
- static void adjustInputFieldSpeechButtonStyle(RenderStyle*, Element*);
- static bool paintInputFieldSpeechButton(RenderObject*, const PaintInfo&, const IntRect&);
-};
-
-} // namespace WebCore
-
-#endif
-#endif // RenderInputSpeech_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayer.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayer.cpp
index c3b8403215f..6b7ba1c904f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayer.cpp
@@ -44,23 +44,20 @@
#include "config.h"
#include "core/rendering/RenderLayer.h"
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
#include "core/animation/ActiveAnimations.h"
#include "core/css/PseudoStyleRequest.h"
#include "core/dom/Document.h"
#include "core/dom/shadow/ShadowRoot.h"
-#include "core/html/HTMLFrameElement.h"
-#include "core/frame/Frame.h"
+#include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h"
#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
-#include "core/frame/animation/AnimationController.h"
+#include "core/html/HTMLFrameElement.h"
+#include "core/page/Page.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
#include "core/rendering/ColumnInfo.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/FilterEffectRenderer.h"
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/HitTestResult.h"
@@ -68,26 +65,25 @@
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderInline.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderReplica.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/RenderScrollbarPart.h"
#include "core/rendering/RenderTreeAsText.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/rendering/svg/ReferenceFilterBuilder.h"
#include "core/rendering/svg/RenderSVGResourceClipper.h"
#include "platform/LengthFunctions.h"
#include "platform/Partitions.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "platform/geometry/FloatPoint3D.h"
#include "platform/geometry/FloatRect.h"
+#include "platform/geometry/TransformState.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/graphics/filters/ReferenceFilter.h"
#include "platform/graphics/filters/SourceGraphic.h"
-#include "platform/graphics/filters/custom/CustomFilterGlobalContext.h"
-#include "platform/graphics/filters/custom/CustomFilterOperation.h"
-#include "platform/graphics/filters/custom/CustomFilterValidatedProgram.h"
-#include "platform/graphics/filters/custom/ValidatedCustomFilterOperation.h"
#include "platform/transforms/ScaleTransformOperation.h"
#include "platform/transforms/TransformationMatrix.h"
#include "platform/transforms/TranslateTransformOperation.h"
@@ -99,19 +95,21 @@ using namespace std;
namespace WebCore {
+namespace {
+
+static CompositingQueryMode gCompositingQueryMode =
+ CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases;
+
+} // namespace
+
using namespace HTMLNames;
-RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
- : m_hasSelfPaintingLayerDescendant(false)
+RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type)
+ : m_layerType(type)
+ , m_hasSelfPaintingLayerDescendant(false)
, m_hasSelfPaintingLayerDescendantDirty(false)
- , m_hasOutOfFlowPositionedDescendant(false)
- , m_hasOutOfFlowPositionedDescendantDirty(true)
- , m_hasUnclippedDescendant(false)
- , m_isUnclippedDescendant(false)
, m_isRootLayer(renderer->isRenderView())
, m_usedTransparency(false)
- , m_childLayerHasBlendMode(false)
- , m_childLayerHasBlendModeStatusDirty(false)
, m_visibleContentStatusDirty(true)
, m_hasVisibleContent(false)
, m_visibleDescendantStatusDirty(false)
@@ -123,7 +121,13 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
, m_containsDirtyOverlayScrollbars(false)
, m_canSkipRepaintRectsUpdateOnScroll(renderer->isTableCell())
, m_hasFilterInfo(false)
- , m_blendMode(blink::WebBlendModeNormal)
+ , m_needsCompositingInputsUpdate(true)
+ , m_childNeedsCompositingInputsUpdate(true)
+ , m_hasCompositingDescendant(false)
+ , m_hasNonCompositedChild(false)
+ , m_shouldIsolateCompositedDescendants(false)
+ , m_lostGroupedMapping(false)
+ , m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
, m_renderer(renderer)
, m_parent(0)
, m_previous(0)
@@ -133,15 +137,18 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
, m_staticInlinePosition(0)
, m_staticBlockPosition(0)
, m_enclosingPaginationLayer(0)
+ , m_styleDeterminedCompositingReasons(CompositingReasonNone)
+ , m_compositingReasons(CompositingReasonNone)
, m_groupedMapping(0)
- , m_repainter(renderer)
- , m_clipper(renderer)
+ , m_repainter(*renderer)
+ , m_clipper(*renderer)
+ , m_blendInfo(*renderer)
{
updateStackingNode();
m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
- if (!renderer->firstChild() && renderer->style()) {
+ if (!renderer->slowFirstChild() && renderer->style()) {
m_visibleContentStatusDirty = false;
m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
}
@@ -151,9 +158,6 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
RenderLayer::~RenderLayer()
{
- if (!m_renderer->documentBeingDestroyed())
- compositor()->removeOutOfFlowPositionedLayer(this);
-
if (renderer()->frame() && renderer()->frame()->page()) {
if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator())
scrollingCoordinator->willDestroyRenderLayer(this);
@@ -161,6 +165,12 @@ RenderLayer::~RenderLayer()
removeFilterInfoIfNeeded();
+ if (groupedMapping()) {
+ DisableCompositingQueryAsserts disabler;
+ groupedMapping()->removeRenderLayerFromSquashingGraphicsLayer(this);
+ setGroupedMapping(0);
+ }
+
// Child layers will be deleted by their corresponding render objects, so
// we don't need to delete them ourselves.
@@ -169,8 +179,10 @@ RenderLayer::~RenderLayer()
String RenderLayer::debugName() const
{
- if (isReflection())
+ if (isReflection()) {
+ ASSERT(m_reflectionInfo);
return m_reflectionInfo->debugName();
+ }
return renderer()->debugName();
}
@@ -183,28 +195,38 @@ RenderLayerCompositor* RenderLayer::compositor() const
void RenderLayer::contentChanged(ContentChangeType changeType)
{
- // This can get called when video becomes accelerated, so the layers may change.
- if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged) && compositor()->updateLayerCompositingState(this))
- compositor()->setCompositingLayersNeedRebuild();
+ // updateLayerCompositingState will query compositingReasons for accelerated overflow scrolling.
+ // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.html
+ DisableCompositingQueryAsserts disabler;
+
+ if (changeType == CanvasChanged)
+ compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+
+ if (changeType == CanvasContextChanged) {
+ compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+
+ // Although we're missing test coverage, we need to call
+ // GraphicsLayer::setContentsToPlatformLayer with the new platform
+ // layer for this canvas.
+ // See http://crbug.com/349195
+ if (hasCompositedLayerMapping())
+ compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+ }
if (m_compositedLayerMapping)
m_compositedLayerMapping->contentChanged(changeType);
}
-bool RenderLayer::canRender3DTransforms() const
-{
- return compositor()->canRender3DTransforms();
-}
-
bool RenderLayer::paintsWithFilters() const
{
if (!renderer()->hasFilter())
return false;
- if (compositingState() != PaintsIntoOwnBacking)
- return true;
-
- if (!m_compositedLayerMapping || !m_compositedLayerMapping->canCompositeFilters())
+ // https://code.google.com/p/chromium/issues/detail?id=343759
+ DisableCompositingQueryAsserts disabler;
+ if (!m_compositedLayerMapping
+ || compositingState() != PaintsIntoOwnBacking
+ || !m_compositedLayerMapping->canCompositeFilters())
return true;
return false;
@@ -218,57 +240,43 @@ bool RenderLayer::requiresFullLayerImageForFilters() const
return filter ? filter->hasFilterThatMovesPixels() : false;
}
-LayoutPoint RenderLayer::computeOffsetFromRoot(bool& hasLayerOffset) const
+LayoutSize RenderLayer::subpixelAccumulation() const
{
- hasLayerOffset = true;
-
- if (!parent())
- return LayoutPoint();
-
- // This is similar to root() but we check if an ancestor layer would
- // prevent the optimization from working.
- const RenderLayer* rootLayer = 0;
- for (const RenderLayer* parentLayer = parent(); parentLayer; rootLayer = parentLayer, parentLayer = parentLayer->parent()) {
- hasLayerOffset = parentLayer->canUseConvertToLayerCoords();
- if (!hasLayerOffset)
- return LayoutPoint();
- }
- ASSERT(rootLayer == root());
+ return m_subpixelAccumulation;
+}
- LayoutPoint offset;
- parent()->convertToLayerCoords(rootLayer, offset);
- return offset;
+void RenderLayer::setSubpixelAccumulation(const LayoutSize& size)
+{
+ m_subpixelAccumulation = size;
}
void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags flags)
{
- RenderGeometryMap geometryMap(UseTransforms);
- if (this != rootLayer)
- geometryMap.pushMappingsToAncestor(parent(), 0);
- updateLayerPositions(&geometryMap, flags);
+ TRACE_EVENT0("blink_rendering", "RenderLayer::updateLayerPositionsAfterLayout");
+
+ // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
+ // https://code.google.com/p/chromium/issues/detail?id=343756
+ DisableCompositingQueryAsserts disabler;
+ updateLayerPositionRecursive(flags);
}
-void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLayerPositionsFlags flags)
+void RenderLayer::updateLayerPositionRecursive(UpdateLayerPositionsFlags flags)
{
- updateLayerPosition(); // For relpositioned layers or non-positioned layers,
- // we need to keep in sync, since we may have shifted relative
- // to our parent layer.
- if (geometryMap)
- geometryMap->pushMappingsToAncestor(this, parent());
+ if (updateLayerPosition())
+ flags |= ForceMayNeedPaintInvalidation;
+
+ if (flags & ForceMayNeedPaintInvalidation)
+ m_renderer->setMayNeedPaintInvalidation(true);
// Clear our cached clip rect information.
m_clipper.clearClipRects();
if (hasOverflowControls()) {
- LayoutPoint offsetFromRoot;
- if (geometryMap)
- offsetFromRoot = LayoutPoint(geometryMap->absolutePoint(FloatPoint()));
- else {
- // FIXME: It looks suspicious to call convertToLayerCoords here
- // as canUseConvertToLayerCoords may be true for an ancestor layer.
- convertToLayerCoords(root(), offsetFromRoot);
- }
- scrollableArea()->positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
+ // FIXME: We should figure out the right time to position the overflow controls.
+ // This call appears to be necessary to pass some layout test that use EventSender,
+ // presumably because the normal time to position the controls is during paint. We
+ // probably shouldn't position the overflow controls during paint either...
+ scrollableArea()->positionOverflowControls(IntSize());
}
updateDescendantDependentFlags();
@@ -280,18 +288,13 @@ void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLay
m_enclosingPaginationLayer = 0;
}
- repainter().repaintAfterLayout(geometryMap, flags & CheckForRepaint);
+ repainter().repaintAfterLayout(flags & CheckForRepaint);
// Go ahead and update the reflection's position and size.
if (m_reflectionInfo)
m_reflectionInfo->reflection()->layout();
- // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
- bool isUpdateRoot = (flags & IsCompositingUpdateRoot);
- if (hasCompositedLayerMapping())
- flags &= ~IsCompositingUpdateRoot;
-
- if (useRegionBasedColumns() && renderer()->isInFlowRenderFlowThread()) {
+ if (useRegionBasedColumns() && renderer()->isRenderFlowThread()) {
updatePagination();
flags |= UpdatePagination;
}
@@ -300,19 +303,15 @@ void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLay
flags |= UpdatePagination;
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
- child->updateLayerPositions(geometryMap, flags);
+ child->updateLayerPositionRecursive(flags);
- if ((flags & UpdateCompositingLayers) && hasCompositedLayerMapping()) {
- CompositedLayerMapping::UpdateAfterLayoutFlags updateFlags = CompositedLayerMapping::CompositingChildrenOnly;
- if (flags & NeedsFullRepaintInBacking)
- updateFlags |= CompositedLayerMapping::NeedsFullRepaint;
- if (isUpdateRoot)
- updateFlags |= CompositedLayerMapping::IsUpdateRoot;
- compositedLayerMapping()->updateAfterLayout(updateFlags);
+ // FIXME: why isn't FrameView just calling RenderLayerCompositor::repaintCompositedLayers? Does it really impact
+ // performance?
+ if ((flags & NeedsFullRepaintInBacking) && hasCompositedLayerMapping() && !compositedLayerMapping()->paintsIntoCompositedAncestor()) {
+ compositedLayerMapping()->setContentsNeedDisplay();
+ // This code is called when the FrameView wants to repaint the entire frame. This includes squashing content.
+ compositedLayerMapping()->setSquashingContentsNeedDisplay();
}
-
- if (geometryMap)
- geometryMap->popMappingsToAncestor(parent());
}
void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
@@ -339,52 +338,6 @@ void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
}
}
-void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant()
-{
- for (RenderLayer* layer = this; layer; layer = layer->parent()) {
- if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFlowPositionedDescendant())
- break;
-
- layer->setHasOutOfFlowPositionedDescendantDirty(false);
- layer->setHasOutOfFlowPositionedDescendant(true);
- }
-}
-
-void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus()
-{
- for (RenderLayer* layer = this; layer; layer = layer->parent()) {
- layer->setHasOutOfFlowPositionedDescendantDirty(true);
-
- // We may or may not have an unclipped descendant. If we do, we'll reset
- // this to true the next time composited scrolling state is updated.
- layer->setHasUnclippedDescendant(false);
-
- // If we have reached an out of flow positioned layer, we know our parent should have an out-of-flow positioned descendant.
- // In this case, there is no need to dirty our ancestors further.
- if (layer->renderer()->isOutOfFlowPositioned()) {
- ASSERT(!parent() || parent()->m_hasOutOfFlowPositionedDescendantDirty || parent()->hasOutOfFlowPositionedDescendant());
- break;
- }
- }
-}
-
-bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
-{
- const Settings* settings = renderer()->document().settings();
- return settings && settings->acceleratedCompositingForOverflowScrollEnabled();
-}
-
-// FIXME: This is a temporary flag and should be removed once accelerated
-// overflow scroll is ready (crbug.com/254111).
-bool RenderLayer::compositorDrivenAcceleratedScrollingEnabled() const
-{
- if (!acceleratedCompositingForOverflowScrollEnabled())
- return false;
-
- const Settings* settings = renderer()->document().settings();
- return settings && settings->compositorDrivenAcceleratedScrollingEnabled();
-}
-
bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
{
const EPosition position = renderer()->style()->position();
@@ -413,21 +366,28 @@ bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
const bool isRootFixedPos = position == FixedPosition && containingBlock->enclosingLayer() == rootLayer;
const bool otherIsRootFixedPos = otherPosition == FixedPosition && otherContainingBlock->enclosingLayer() == rootLayer;
+ // FIXME: some of these cases don't look quite right.
if (isRootFixedPos && otherIsRootFixedPos)
return false;
if (isRootFixedPos || otherIsRootFixedPos)
return true;
- if (containingBlock == otherContainingBlock)
+ if (containingBlock->enclosingLayer() == otherContainingBlock->enclosingLayer())
return false;
// Maintain a set of containing blocks between the first layer and its
// closest scrollable ancestor.
- HashSet<const RenderObject*> containingBlocks;
+ HashSet<const RenderLayer*> containingBlocks;
while (containingBlock) {
+ containingBlocks.add(containingBlock->enclosingLayer());
if (containingBlock->enclosingLayer()->scrollsOverflow())
break;
- containingBlocks.add(containingBlock);
+
+ if (containingBlock->enclosingLayer() == other) {
+ // This layer does not scroll with respect to the other layer if the other one does not scroll and this one is a child.
+ return false;
+ }
+
containingBlock = containingBlock->containingBlock();
}
@@ -435,7 +395,7 @@ bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
// it means both layers are contained within a single non-scrolling subtree.
// Hence, they will not scroll with respect to each other.
while (otherContainingBlock) {
- if (containingBlocks.contains(otherContainingBlock))
+ if (containingBlocks.contains(otherContainingBlock->enclosingLayer()))
return false;
if (otherContainingBlock->enclosingLayer()->scrollsOverflow())
break;
@@ -448,24 +408,17 @@ bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
void RenderLayer::updateLayerPositionsAfterDocumentScroll()
{
ASSERT(this == renderer()->view()->layer());
-
- RenderGeometryMap geometryMap(UseTransforms);
- updateLayerPositionsAfterScroll(&geometryMap);
+ updateLayerPositionsAfterScroll();
}
void RenderLayer::updateLayerPositionsAfterOverflowScroll()
{
- RenderGeometryMap geometryMap(UseTransforms);
- RenderView* view = renderer()->view();
- if (this != view->layer())
- geometryMap.pushMappingsToAncestor(parent(), 0);
-
// FIXME: why is it OK to not check the ancestors of this layer in order to
// initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags?
- updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll);
+ updateLayerPositionsAfterScroll(IsOverflowScroll);
}
-void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap, UpdateLayerPositionsAfterScrollFlags flags)
+void RenderLayer::updateLayerPositionsAfterScroll(UpdateLayerPositionsAfterScrollFlags flags)
{
// FIXME: This shouldn't be needed, but there are some corner cases where
// these flags are still dirty. Update so that the check below is valid.
@@ -477,14 +430,10 @@ void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap
if (subtreeIsInvisible())
return;
- bool positionChanged = updateLayerPosition();
- if (positionChanged)
+ if (updateLayerPosition())
flags |= HasChangedAncestor;
- if (geometryMap)
- geometryMap->pushMappingsToAncestor(this, parent());
-
- if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll)
+ if ((flags & HasChangedAncestor) || (flags & HasSeenViewportConstrainedAncestor) || (flags & IsOverflowScroll))
m_clipper.clearClipRects();
if (renderer()->style()->hasViewportConstrainedPosition())
@@ -493,57 +442,42 @@ void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap
if (renderer()->hasOverflowClip())
flags |= HasSeenAncestorWithOverflowClip;
- if (flags & HasSeenViewportConstrainedAncestor
- || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip && !m_canSkipRepaintRectsUpdateOnScroll)) {
+ if ((flags & IsOverflowScroll) && (flags & HasSeenAncestorWithOverflowClip) && !m_canSkipRepaintRectsUpdateOnScroll) {
// FIXME: We could track the repaint container as we walk down the tree.
- repainter().computeRepaintRects(renderer()->containerForRepaint(), geometryMap);
+ repainter().computeRepaintRects();
} else {
// Check that RenderLayerRepainter's cached rects are correct.
// FIXME: re-enable these assertions when the issue with table cells is resolved: https://bugs.webkit.org/show_bug.cgi?id=103432
- // ASSERT(repainter().m_repaintRect == renderer()->clippedOverflowRectForRepaint(renderer()->containerForRepaint()));
- // ASSERT(repainter().m_outlineBox == renderer()->outlineBoundsForRepaint(renderer()->containerForRepaint(), geometryMap));
+ // ASSERT(repainter().m_repaintRect == renderer()->clippedOverflowRectForPaintInvalidation(renderer()->containerForPaintInvalidation()));
}
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
- child->updateLayerPositionsAfterScroll(geometryMap, flags);
+ child->updateLayerPositionsAfterScroll(flags);
// We don't update our reflection as scrolling is a translation which does not change the size()
// of an object, thus RenderReplica will still repaint itself properly as the layer position was
// updated above.
-
- if (geometryMap)
- geometryMap->popMappingsToAncestor(parent());
}
-bool RenderLayer::hasBlendMode() const
+void RenderLayer::updateTransformationMatrix()
{
- return RuntimeEnabledFeatures::cssCompositingEnabled() && renderer()->hasBlendMode();
+ if (m_transform) {
+ RenderBox* box = renderBox();
+ ASSERT(box);
+ m_transform->makeIdentity();
+ box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
+ makeMatrixRenderable(*m_transform, compositor()->hasAcceleratedCompositing());
+ }
}
-void RenderLayer::updateBlendMode()
+void RenderLayer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle)
{
- if (!RuntimeEnabledFeatures::cssCompositingEnabled())
+ if (oldStyle && newStyle->transformDataEquivalent(*oldStyle))
return;
- bool hadBlendMode = m_blendMode != blink::WebBlendModeNormal;
- blink::WebBlendMode newBlendMode = renderer()->style()->blendMode();
- if (newBlendMode != m_blendMode) {
- m_blendMode = newBlendMode;
-
- // Only update the flag if a blend mode is set or unset.
- if (parent() && (!hadBlendMode || !hasBlendMode()))
- parent()->dirtyAncestorChainBlendedDescendantStatus();
-
- if (hasCompositedLayerMapping())
- compositedLayerMapping()->setBlendMode(newBlendMode);
- }
-}
-
-void RenderLayer::updateTransform()
-{
// hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
// so check style too.
- bool hasTransform = renderer()->hasTransform() && renderer()->style()->hasTransform();
+ bool hasTransform = renderer()->hasTransform() && newStyle->hasTransform();
bool had3DTransform = has3DTransform();
bool hadTransform = m_transform;
@@ -555,40 +489,47 @@ void RenderLayer::updateTransform()
// Layers with transforms act as clip rects roots, so clear the cached clip rects here.
m_clipper.clearClipRectsIncludingDescendants();
+ } else if (hasTransform) {
+ m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects);
}
- if (hasTransform) {
- RenderBox* box = renderBox();
- ASSERT(box);
- m_transform->makeIdentity();
- box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
- makeMatrixRenderable(*m_transform, canRender3DTransforms());
- }
+ updateTransformationMatrix();
if (had3DTransform != has3DTransform())
dirty3DTransformedDescendantStatus();
}
+static RenderLayer* enclosingLayerForContainingBlock(RenderLayer* layer)
+{
+ if (RenderObject* containingBlock = layer->renderer()->containingBlock())
+ return containingBlock->enclosingLayer();
+ return 0;
+}
+
+RenderLayer* RenderLayer::renderingContextRoot()
+{
+ RenderLayer* renderingContext = 0;
+
+ if (shouldPreserve3D())
+ renderingContext = this;
+
+ for (RenderLayer* current = enclosingLayerForContainingBlock(this); current && current->shouldPreserve3D(); current = enclosingLayerForContainingBlock(current))
+ renderingContext = current;
+
+ return renderingContext;
+}
+
TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
{
if (!m_transform)
return TransformationMatrix();
- // FIXME: handle this under web-animations
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled() && renderer()->style()->isRunningAcceleratedAnimation()) {
- TransformationMatrix currTransform;
- RefPtr<RenderStyle> style = renderer()->animation().getAnimatedStyleForRenderer(renderer());
- style->applyTransform(currTransform, renderBox()->pixelSnappedBorderBoxRect().size(), applyOrigin);
- makeMatrixRenderable(currTransform, canRender3DTransforms());
- return currTransform;
- }
-
// m_transform includes transform-origin, so we need to recompute the transform here.
if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
RenderBox* box = renderBox();
TransformationMatrix currTransform;
box->style()->applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
- makeMatrixRenderable(currTransform, canRender3DTransforms());
+ makeMatrixRenderable(currTransform, compositor()->hasAcceleratedCompositing());
return currTransform;
}
@@ -609,6 +550,18 @@ TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavio
return *m_transform;
}
+RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
+{
+ const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
+ while (layer) {
+ if (layer->renderer()->hasOverflowClip())
+ return const_cast<RenderLayer*>(layer);
+
+ layer = layer->parent();
+ }
+ return 0;
+}
+
static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
{
RenderView* view = renderer->view();
@@ -633,8 +586,7 @@ static bool checkContainingBlockChainForPagination(RenderLayerModelObject* rende
bool RenderLayer::useRegionBasedColumns() const
{
- const Settings* settings = renderer()->document().settings();
- return settings && settings->regionBasedColumnsEnabled();
+ return renderer()->document().regionBasedColumnsEnabled();
}
void RenderLayer::updatePagination()
@@ -654,7 +606,7 @@ void RenderLayer::updatePagination()
// layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
// to that layer easily.
bool regionBasedColumnsUsed = useRegionBasedColumns();
- if (regionBasedColumnsUsed && renderer()->isInFlowRenderFlowThread()) {
+ if (regionBasedColumnsUsed && renderer()->isRenderFlowThread()) {
m_enclosingPaginationLayer = this;
return;
}
@@ -694,17 +646,88 @@ void RenderLayer::updatePagination()
}
// If we're not normal flow, then we need to look for a multi-column object between us and our stacking container.
- RenderLayerStackingNode* ancestorStackingContainerNode = m_stackingNode->ancestorStackingContainerNode();
+ RenderLayerStackingNode* ancestorStackingContextNode = m_stackingNode->ancestorStackingContextNode();
for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
if (curr->renderer()->hasColumns()) {
m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox());
return;
}
- if (curr->stackingNode() == ancestorStackingContainerNode)
+ if (curr->stackingNode() == ancestorStackingContextNode)
return;
}
}
+static RenderLayerModelObject* getTransformedAncestor(const RenderLayerModelObject* repaintContainer)
+{
+ ASSERT(repaintContainer->layer()->enclosingTransformedAncestor());
+ ASSERT(repaintContainer->layer()->enclosingTransformedAncestor()->renderer());
+
+ // FIXME: this defensive code should not have to exist. None of these pointers should ever be 0. See crbug.com/370410.
+ RenderLayerModelObject* transformedAncestor = 0;
+ if (RenderLayer* ancestor = repaintContainer->layer()->enclosingTransformedAncestor())
+ transformedAncestor = ancestor->renderer();
+ return transformedAncestor;
+}
+
+LayoutPoint RenderLayer::positionFromPaintInvalidationContainer(const RenderObject* renderObject, const RenderLayerModelObject* repaintContainer)
+{
+ if (!repaintContainer || !repaintContainer->groupedMapping())
+ return renderObject->positionFromPaintInvalidationContainer(repaintContainer);
+
+ RenderLayerModelObject* transformedAncestor = getTransformedAncestor(repaintContainer);
+ if (!transformedAncestor)
+ return renderObject->positionFromPaintInvalidationContainer(repaintContainer);
+
+ // If the transformedAncestor is actually the RenderView, we might get
+ // confused and think that we can use LayoutState. Ideally, we'd made
+ // LayoutState work for all composited layers as well, but until then
+ // we need to disable LayoutState for squashed layers.
+ ForceHorriblySlowRectMapping slowRectMapping(*transformedAncestor);
+
+ LayoutPoint point = renderObject->positionFromPaintInvalidationContainer(transformedAncestor);
+ point.moveBy(-repaintContainer->groupedMapping()->squashingOffsetFromTransformedAncestor());
+ return point;
+}
+
+void RenderLayer::mapRectToRepaintBacking(const RenderObject* renderObject, const RenderLayerModelObject* repaintContainer, LayoutRect& rect)
+{
+ if (!repaintContainer->groupedMapping()) {
+ renderObject->mapRectToPaintInvalidationBacking(repaintContainer, rect);
+ return;
+ }
+
+ RenderLayerModelObject* transformedAncestor = getTransformedAncestor(repaintContainer);
+ if (!transformedAncestor)
+ return;
+
+ // If the transformedAncestor is actually the RenderView, we might get
+ // confused and think that we can use LayoutState. Ideally, we'd made
+ // LayoutState work for all composited layers as well, but until then
+ // we need to disable LayoutState for squashed layers.
+ ForceHorriblySlowRectMapping slowRectMapping(*transformedAncestor);
+
+ // This code adjusts the repaint rectangle to be in the space of the transformed ancestor of the grouped (i.e. squashed)
+ // layer. This is because all layers that squash together need to repaint w.r.t. a single container that is
+ // an ancestor of all of them, in order to properly take into account any local transforms etc.
+ // FIXME: remove this special-case code that works around the repainting code structure.
+ renderObject->mapRectToPaintInvalidationBacking(repaintContainer, rect);
+
+ // |repaintContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the
+ // transformed ancestor.
+ rect = LayoutRect(repaintContainer->localToContainerQuad(FloatRect(rect), transformedAncestor).boundingBox());
+
+ rect.moveBy(-repaintContainer->groupedMapping()->squashingOffsetFromTransformedAncestor());
+}
+
+LayoutRect RenderLayer::computeRepaintRect(const RenderObject* renderObject, const RenderLayer* repaintContainer)
+{
+ if (!repaintContainer->groupedMapping())
+ return renderObject->computePaintInvalidationRect(repaintContainer->renderer());
+ LayoutRect rect = renderObject->clippedOverflowRectForPaintInvalidation(repaintContainer->renderer());
+ mapRectToRepaintBacking(repaintContainer->renderer(), repaintContainer->renderer(), rect);
+ return rect;
+}
+
void RenderLayer::setHasVisibleContent()
{
if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
@@ -712,19 +735,11 @@ void RenderLayer::setHasVisibleContent()
return;
}
- m_visibleContentStatusDirty = false;
m_hasVisibleContent = true;
- repainter().computeRepaintRects(renderer()->containerForRepaint());
- if (!m_stackingNode->isNormalFlowOnly()) {
- // We don't collect invisible layers in z-order lists if we are not in compositing mode.
- // As we became visible, we need to dirty our stacking containers ancestors to be properly
- // collected. FIXME: When compositing, we could skip this dirtying phase.
- for (RenderLayerStackingNode* sc = m_stackingNode->ancestorStackingContainerNode(); sc; sc = sc->ancestorStackingContainerNode()) {
- sc->dirtyZOrderLists();
- if (sc->layer()->hasVisibleContent())
- break;
- }
- }
+ m_visibleContentStatusDirty = false;
+
+ setNeedsCompositingInputsUpdate();
+ repainter().computeRepaintRects();
if (parent())
parent()->setAncestorChainHasVisibleDescendant();
@@ -758,135 +773,84 @@ void RenderLayer::setAncestorChainHasVisibleDescendant()
}
}
-void RenderLayer::dirtyAncestorChainBlendedDescendantStatus()
-{
- for (RenderLayer* layer = this; layer; layer = layer->parent()) {
- if (layer->m_childLayerHasBlendModeStatusDirty)
- break;
-
- layer->m_childLayerHasBlendModeStatusDirty = true;
-
- if (layer->stackingNode()->isStackingContext())
- break;
- }
-}
-
-void RenderLayer::setAncestorChainBlendedDescendant()
-{
- for (RenderLayer* layer = this; layer; layer = layer->parent()) {
- if (!layer->m_childLayerHasBlendModeStatusDirty && layer->childLayerHasBlendMode())
- break;
-
- layer->m_childLayerHasBlendMode = true;
- layer->m_childLayerHasBlendModeStatusDirty = false;
-
- if (layer->stackingNode()->isStackingContext())
- break;
- }
-}
-
-void RenderLayer::updateHasUnclippedDescendant()
-{
- TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasUnclippedDescendant");
- ASSERT(renderer()->isOutOfFlowPositioned());
- if (!m_hasVisibleContent && !m_hasVisibleDescendant)
- return;
-
- FrameView* frameView = renderer()->view()->frameView();
- if (!frameView)
- return;
-
- const RenderObject* containingBlock = renderer()->containingBlock();
- setIsUnclippedDescendant(false);
- for (RenderLayer* ancestor = parent(); ancestor && ancestor->renderer() != containingBlock; ancestor = ancestor->parent()) {
- // TODO(vollick): This isn't quite right. Whenever ancestor is composited and clips
- // overflow, we're technically unclipped. However, this will currently cause a huge
- // number of layers to report that they are unclipped. Eventually, when we've formally
- // separated the clipping, transform, opacity, and stacking trees here and in the
- // compositor, we will be able to relax this restriction without it being prohibitively
- // expensive (currently, we have to do a lot of work in the compositor to honor a
- // clip child/parent relationship).
- if (ancestor->scrollsOverflow())
- setIsUnclippedDescendant(true);
- ancestor->setHasUnclippedDescendant(true);
- }
-}
-
// FIXME: this is quite brute-force. We could be more efficient if we were to
-// track state and update it as appropriate as changes are made in the RenderObject tree.
-void RenderLayer::updateHasVisibleNonLayerContent()
+// track state and update it as appropriate as changes are made in the Render tree.
+void RenderLayer::updateScrollingStateAfterCompositingChange()
{
- TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasVisibleNonLayerContent");
+ TRACE_EVENT0("blink_rendering", "RenderLayer::updateScrollingStateAfterCompositingChange");
m_hasVisibleNonLayerContent = false;
- for (RenderObject* r = renderer()->firstChild(); r; r = r->nextSibling()) {
+ for (RenderObject* r = renderer()->slowFirstChild(); r; r = r->nextSibling()) {
if (!r->hasLayer()) {
m_hasVisibleNonLayerContent = true;
break;
}
}
-}
-static bool subtreeContainsOutOfFlowPositionedLayer(const RenderLayer* subtreeRoot)
-{
- return (subtreeRoot->renderer() && subtreeRoot->renderer()->isOutOfFlowPositioned()) || subtreeRoot->hasOutOfFlowPositionedDescendant();
+ m_hasNonCompositedChild = false;
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->compositingState() == NotComposited) {
+ m_hasNonCompositedChild = true;
+ return;
+ }
+ }
}
void RenderLayer::updateDescendantDependentFlags()
{
- if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) {
+ if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty) {
m_hasVisibleDescendant = false;
m_hasSelfPaintingLayerDescendant = false;
- m_hasOutOfFlowPositionedDescendant = false;
for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
child->updateDescendantDependentFlags();
bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant;
bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
- bool hasOutOfFlowPositionedDescendant = subtreeContainsOutOfFlowPositionedLayer(child);
m_hasVisibleDescendant |= hasVisibleDescendant;
m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
- m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescendant;
- if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && hasOutOfFlowPositionedDescendant)
+ if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant)
break;
}
m_visibleDescendantStatusDirty = false;
m_hasSelfPaintingLayerDescendantDirty = false;
- m_hasOutOfFlowPositionedDescendantDirty = false;
}
- if (m_childLayerHasBlendModeStatusDirty) {
- m_childLayerHasBlendMode = false;
+ if (m_blendInfo.childLayerHasBlendModeStatusDirty()) {
+ m_blendInfo.setChildLayerHasBlendMode(false);
for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
if (!child->stackingNode()->isStackingContext())
child->updateDescendantDependentFlags();
- bool childLayerHasBlendMode = child->paintsWithBlendMode() || (child->m_childLayerHasBlendMode && !child->stackingNode()->isStackingContext());
- m_childLayerHasBlendMode |= childLayerHasBlendMode;
+ bool childLayerHadBlendMode = child->blendInfo().childLayerHasBlendModeWhileDirty();
+ bool childLayerHasBlendMode = childLayerHadBlendMode || child->blendInfo().hasBlendMode();
- if (m_childLayerHasBlendMode)
+ m_blendInfo.setChildLayerHasBlendMode(childLayerHasBlendMode);
+
+ if (childLayerHasBlendMode)
break;
}
- m_childLayerHasBlendModeStatusDirty = false;
+ m_blendInfo.setChildLayerHasBlendModeStatusDirty(false);
}
if (m_visibleContentStatusDirty) {
+ bool previouslyHasVisibleContent = m_hasVisibleContent;
if (renderer()->style()->visibility() == VISIBLE)
m_hasVisibleContent = true;
else {
// layer may be hidden but still have some visible content, check for this
m_hasVisibleContent = false;
- RenderObject* r = renderer()->firstChild();
+ RenderObject* r = renderer()->slowFirstChild();
while (r) {
if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
m_hasVisibleContent = true;
break;
}
- if (r->firstChild() && !r->hasLayer())
- r = r->firstChild();
+ RenderObject* rendererFirstChild = r->slowFirstChild();
+ if (rendererFirstChild && !r->hasLayer())
+ r = rendererFirstChild;
else if (r->nextSibling())
r = r->nextSibling();
else {
@@ -901,12 +865,17 @@ void RenderLayer::updateDescendantDependentFlags()
}
}
m_visibleContentStatusDirty = false;
+
+ // FIXME: We can remove this code once we remove the recursive tree
+ // walk inside updateGraphicsLayerGeometry.
+ if (hasVisibleContent() != previouslyHasVisibleContent)
+ setNeedsCompositingInputsUpdate();
}
}
void RenderLayer::dirty3DTransformedDescendantStatus()
{
- RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContainerNode();
+ RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContextNode();
if (!stackingNode)
return;
@@ -916,7 +885,7 @@ void RenderLayer::dirty3DTransformedDescendantStatus()
// Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
while (stackingNode && stackingNode->layer()->preserves3D()) {
stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
- stackingNode = stackingNode->ancestorStackingContainerNode();
+ stackingNode = stackingNode->ancestorStackingContextNode();
}
}
@@ -949,6 +918,7 @@ bool RenderLayer::updateLayerPosition()
{
LayoutPoint localPoint;
LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
+
if (renderer()->isInline() && renderer()->isRenderInline()) {
RenderInline* inlineFlow = toRenderInline(renderer());
IntRect lineBox = inlineFlow->linesBoundingBox();
@@ -990,20 +960,17 @@ bool RenderLayer::updateLayerPosition()
}
if (renderer()->isOutOfFlowPositioned() && positionedParent->renderer()->isInFlowPositioned() && positionedParent->renderer()->isRenderInline()) {
- LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(toRenderBox(renderer()));
+ LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(*toRenderBox(renderer()));
localPoint += offset;
}
} else if (parent()) {
if (hasCompositedLayerMapping()) {
// FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column.
// They won't split across columns properly.
- LayoutSize columnOffset;
- if (!parent()->renderer()->hasColumns() && parent()->renderer()->isRoot() && renderer()->view()->hasColumns())
- renderer()->view()->adjustForColumns(columnOffset, localPoint);
+ if (!parent()->renderer()->hasColumns() && parent()->renderer()->isDocumentElement() && renderer()->view()->hasColumns())
+ localPoint += renderer()->view()->columnOffset(localPoint);
else
- parent()->renderer()->adjustForColumns(columnOffset, localPoint);
-
- localPoint += columnOffset;
+ localPoint += parent()->renderer()->columnOffset(localPoint);
}
if (parent()->renderer()->hasOverflowClip()) {
@@ -1068,8 +1035,7 @@ FloatPoint RenderLayer::perspectiveOrigin() const
const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
RenderStyle* style = renderer()->style();
- return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width()),
- floatValueForLength(style->perspectiveOriginY(), borderBox.height()));
+ return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width().toFloat()), floatValueForLength(style->perspectiveOriginY(), borderBox.height().toFloat()));
}
static inline bool isFixedPositionedContainer(RenderLayer* layer)
@@ -1086,14 +1052,6 @@ RenderLayer* RenderLayer::enclosingPositionedAncestor() const
return curr;
}
-RenderLayer* RenderLayer::enclosingScrollableLayer() const
-{
- if (RenderBox* enclosingScrollableBox = renderer()->enclosingScrollableBox())
- return enclosingScrollableBox->layer();
-
- return 0;
-}
-
RenderLayer* RenderLayer::enclosingTransformedAncestor() const
{
RenderLayer* curr = parent();
@@ -1103,9 +1061,29 @@ RenderLayer* RenderLayer::enclosingTransformedAncestor() const
return curr;
}
-static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
+LayoutPoint RenderLayer::computeOffsetFromTransformedAncestor() const
+{
+ const CompositingInputs& properties = compositingInputs();
+
+ TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
+ // FIXME: add a test that checks flipped writing mode and ApplyContainerFlip are correct.
+ renderer()->mapLocalToContainer(properties.transformAncestor ? properties.transformAncestor->renderer() : 0, transformState, ApplyContainerFlip);
+ transformState.flatten();
+ return LayoutPoint(transformState.lastPlanarPoint());
+}
+
+const RenderLayer* RenderLayer::compositingContainer() const
+{
+ if (stackingNode()->isNormalFlowOnly())
+ return parent();
+ if (RenderLayerStackingNode* ancestorStackingNode = stackingNode()->ancestorStackingContextNode())
+ return ancestorStackingNode->layer();
+ return 0;
+}
+
+bool RenderLayer::isRepaintContainer() const
{
- return layer->stackingNode()->isNormalFlowOnly() ? layer->parent() : (layer->stackingNode()->ancestorStackingContainerNode() ? layer->stackingNode()->ancestorStackingContainerNode()->layer() : 0);
+ return compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking;
}
// FIXME: having two different functions named enclosingCompositingLayer and enclosingCompositingLayerForRepaint
@@ -1113,12 +1091,14 @@ static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
// the includeSelf option. It is very likely that we don't even want either of these functions; A layer
// should be told explicitly which GraphicsLayer is the repaintContainer for a RenderLayer, and
// any other use cases should probably have an API between the non-compositing and compositing sides of code.
-RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
+RenderLayer* RenderLayer::enclosingCompositingLayer(IncludeSelfOrNot includeSelf) const
{
- if (includeSelf && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking)
+ ASSERT(isAllowedToQueryCompositingState());
+
+ if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking)
return const_cast<RenderLayer*>(this);
- for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
+ for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
if (curr->compositingState() != NotComposited && curr->compositingState() != PaintsIntoGroupedBacking)
return const_cast<RenderLayer*>(curr);
}
@@ -1126,59 +1106,92 @@ RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
return 0;
}
-RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(bool includeSelf) const
+RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
{
- if (includeSelf && (compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking))
+ ASSERT(isAllowedToQueryCompositingState());
+
+ if ((includeSelf == IncludeSelf) && isRepaintContainer())
return const_cast<RenderLayer*>(this);
- for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
- if (curr->compositingState() == PaintsIntoOwnBacking || curr->compositingState() == PaintsIntoGroupedBacking)
+ for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
+ if (curr->isRepaintContainer())
return const_cast<RenderLayer*>(curr);
}
return 0;
}
-RenderLayer* RenderLayer::ancestorCompositedScrollingLayer() const
+RenderLayer* RenderLayer::ancestorScrollingLayer() const
{
- if (!acceleratedCompositingForOverflowScrollEnabled())
- return 0;
+ for (RenderObject* container = renderer()->containingBlock(); container; container = container->containingBlock()) {
+ RenderLayer* currentLayer = container->enclosingLayer();
+ if (currentLayer->scrollsOverflow())
+ return currentLayer;
+ }
- RenderObject* containingBlock = renderer()->containingBlock();
- if (!containingBlock)
- return 0;
+ return 0;
+}
- for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) {
- if (ancestorLayer->needsCompositedScrolling())
- return ancestorLayer;
+RenderLayer* RenderLayer::enclosingFilterLayer(IncludeSelfOrNot includeSelf) const
+{
+ const RenderLayer* curr = (includeSelf == IncludeSelf) ? this : parent();
+ for (; curr; curr = curr->parent()) {
+ if (curr->requiresFullLayerImageForFilters())
+ return const_cast<RenderLayer*>(curr);
}
return 0;
}
-RenderLayer* RenderLayer::ancestorScrollingLayer() const
+void RenderLayer::setNeedsCompositingInputsUpdate()
{
- RenderObject* containingBlock = renderer()->containingBlock();
- if (!containingBlock)
- return 0;
+ m_needsCompositingInputsUpdate = true;
- for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) {
- if (ancestorLayer->scrollsOverflow())
- return ancestorLayer;
- }
+ for (RenderLayer* current = this; current && !current->m_childNeedsCompositingInputsUpdate; current = current->parent())
+ current->m_childNeedsCompositingInputsUpdate = true;
+}
- return 0;
+void RenderLayer::updateCompositingInputs(const CompositingInputs& compositingInputs)
+{
+ m_compositingInputs = compositingInputs;
+ m_needsCompositingInputsUpdate = false;
}
-RenderLayer* RenderLayer::enclosingFilterLayer(bool includeSelf) const
+void RenderLayer::clearChildNeedsCompositingInputsUpdate()
{
- const RenderLayer* curr = includeSelf ? this : parent();
- for (; curr; curr = curr->parent()) {
- if (curr->requiresFullLayerImageForFilters())
- return const_cast<RenderLayer*>(curr);
- }
+ ASSERT(!m_needsCompositingInputsUpdate);
+ m_childNeedsCompositingInputsUpdate = false;
+}
- return 0;
+void RenderLayer::setCompositingReasons(CompositingReasons reasons, CompositingReasons mask)
+{
+ ASSERT(reasons == (reasons & mask));
+ if ((compositingReasons() & mask) == (reasons & mask))
+ return;
+ m_compositingReasons = (reasons & mask) | (compositingReasons() & ~mask);
+ m_clipper.setCompositingClipRectsDirty();
+}
+
+void RenderLayer::setHasCompositingDescendant(bool hasCompositingDescendant)
+{
+ if (m_hasCompositingDescendant == static_cast<unsigned>(hasCompositingDescendant))
+ return;
+
+ m_hasCompositingDescendant = hasCompositingDescendant;
+
+ if (hasCompositedLayerMapping())
+ compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
+}
+
+void RenderLayer::setShouldIsolateCompositedDescendants(bool shouldIsolateCompositedDescendants)
+{
+ if (m_shouldIsolateCompositedDescendants == static_cast<unsigned>(shouldIsolateCompositedDescendants))
+ return;
+
+ m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants;
+
+ if (hasCompositedLayerMapping())
+ compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
}
bool RenderLayer::hasAncestorWithFilterOutsets() const
@@ -1191,28 +1204,6 @@ bool RenderLayer::hasAncestorWithFilterOutsets() const
return false;
}
-RenderLayer* RenderLayer::clippingRootForPainting() const
-{
- if (hasCompositedLayerMapping())
- return const_cast<RenderLayer*>(this);
-
- const RenderLayer* current = this;
- while (current) {
- if (current->isRootLayer())
- return const_cast<RenderLayer*>(current);
-
- current = compositingContainer(current);
- ASSERT(current);
- if (current->transform()
- || (current->compositingState() == PaintsIntoOwnBacking)
- )
- return const_cast<RenderLayer*>(current);
- }
-
- ASSERT_NOT_REACHED();
- return 0;
-}
-
bool RenderLayer::cannotBlitToWindow() const
{
if (isTransparent() || m_reflectionInfo || hasTransform())
@@ -1222,14 +1213,6 @@ bool RenderLayer::cannotBlitToWindow() const
return parent()->cannotBlitToWindow();
}
-bool RenderLayer::isTransparent() const
-{
- if (renderer()->node() && renderer()->node()->isSVGElement())
- return false;
-
- return renderer()->isTransparent() || renderer()->hasMask();
-}
-
RenderLayer* RenderLayer::transparentPaintingAncestor()
{
if (hasCompositedLayerMapping())
@@ -1254,10 +1237,10 @@ enum TransparencyClipBoxMode {
RootOfTransparencyClipBox
};
-static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
+static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, const LayoutSize& subPixelAccumulation, PaintBehavior = 0);
static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
- TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
+ TransparencyClipBoxBehavior transparencyBehavior, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
{
// If we have a mask, then the clip is limited to the border box area (and there is
// no need to examine child layers).
@@ -1266,7 +1249,7 @@ static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, cons
// a stacking container. This means we can just walk the layer tree directly.
for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr)
- clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
+ clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, subPixelAccumulation, paintBehavior));
}
}
@@ -1284,7 +1267,7 @@ static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, cons
}
static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
- TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior)
+ TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
{
// FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
// paintDirtyRect, and that should cut down on the amount we have to paint. Still it
@@ -1299,14 +1282,16 @@ static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLaye
LayoutPoint delta;
layer->convertToLayerCoords(rootLayerForTransform, delta);
+ delta.move(subPixelAccumulation);
+ IntPoint pixelSnappedDelta = roundedIntPoint(delta);
TransformationMatrix transform;
- transform.translate(delta.x(), delta.y());
+ transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
transform = transform * *layer->transform();
// We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
// paints unfragmented.
- LayoutRect clipRect = layer->boundingBox(layer);
- expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, paintBehavior);
+ LayoutRect clipRect = layer->physicalBoundingBox(layer);
+ expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, paintBehavior);
layer->renderer()->style()->filterOutsets().expandRect(clipRect);
LayoutRect result = transform.mapRect(clipRect);
if (!paginationLayer)
@@ -1324,36 +1309,41 @@ static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLaye
return result;
}
- LayoutRect clipRect = layer->boundingBox(rootLayer, RenderLayer::UseFragmentBoxes);
- expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
+ LayoutRect clipRect = layer->physicalBoundingBox(rootLayer);
+ expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, subPixelAccumulation, paintBehavior);
layer->renderer()->style()->filterOutsets().expandRect(clipRect);
+ clipRect.move(subPixelAccumulation);
return clipRect;
}
-LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
+LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
{
- return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
+ return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paintDirtyRect);
}
-void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
+void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
{
- bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && m_childLayerHasBlendMode;
+ bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && m_blendInfo.childLayerHasBlendMode();
if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency))
return;
RenderLayer* ancestor = transparentPaintingAncestor();
if (ancestor)
- ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
+ ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
if (paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) {
m_usedTransparency = true;
context->save();
- LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
+ LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
context->clip(clipRect);
+
if (paintsWithBlendMode())
- context->setCompositeOperation(context->compositeOperation(), m_blendMode);
+ context->setCompositeOperation(context->compositeOperation(), m_blendInfo.blendMode());
context->beginTransparencyLayer(renderer()->opacity());
+
+ if (paintsWithBlendMode())
+ context->setCompositeOperation(context->compositeOperation(), blink::WebBlendModeNormal);
#ifdef REVEAL_TRANSPARENCY_LAYERS
context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
context->fillRect(clipRect);
@@ -1388,16 +1378,19 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
} else
setLastChild(child);
- child->setParent(this);
+ child->m_parent = this;
+
+ setNeedsCompositingInputsUpdate();
+ compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
if (child->stackingNode()->isNormalFlowOnly())
m_stackingNode->dirtyNormalFlowList();
if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) {
- // Dirty the z-order list in which we are contained. The ancestorStackingContainerNode() can be null in the
+ // Dirty the z-order list in which we are contained. The ancestorStackingContextNode() can be null in the
// case where we're building up generated content layers. This is ok, since the lists will start
// off dirty in that case anyway.
- child->stackingNode()->dirtyStackingContainerZOrderLists();
+ child->stackingNode()->dirtyStackingContextZOrderLists();
}
child->updateDescendantDependentFlags();
@@ -1407,32 +1400,12 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
setAncestorChainHasSelfPaintingLayerDescendant();
- if (child->paintsWithBlendMode() || child->childLayerHasBlendMode())
- setAncestorChainBlendedDescendant();
-
- if (subtreeContainsOutOfFlowPositionedLayer(child)) {
- // Now that the out of flow positioned descendant is in the tree, we
- // need to tell the compositor to reevaluate the compositing
- // requirements since we may be able to mark more layers as having
- // an 'unclipped' descendant.
- compositor()->setNeedsUpdateCompositingRequirementsState();
- setAncestorChainHasOutOfFlowPositionedDescendant();
- }
-
- // When we first dirty a layer, we will also dirty all the siblings in that
- // layer's stacking context. We need to manually do it here as well, in case
- // we're adding this layer after the stacking context has already been
- // updated.
- child->stackingNode()->setDescendantsAreContiguousInStackingOrderDirty(true);
- compositor()->layerWasAdded(this, child);
+ if (child->blendInfo().hasBlendMode() || child->blendInfo().childLayerHasBlendMode())
+ m_blendInfo.setAncestorChainBlendedDescendant();
}
RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
{
- if (!renderer()->documentBeingDestroyed())
- compositor()->layerWillBeRemoved(this, oldChild);
-
- // remove the child
if (oldChild->previousSibling())
oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
if (oldChild->nextSibling())
@@ -1448,28 +1421,25 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
if (!oldChild->stackingNode()->isNormalFlowOnly() || oldChild->firstChild()) {
// Dirty the z-order list in which we are contained. When called via the
// reattachment process in removeOnlyThisLayer, the layer may already be disconnected
- // from the main layer tree, so we need to null-check the |stackingContainer| value.
- oldChild->stackingNode()->dirtyStackingContainerZOrderLists();
+ // from the main layer tree, so we need to null-check the
+ // |stackingContext| value.
+ oldChild->stackingNode()->dirtyStackingContextZOrderLists();
}
+ if (renderer()->style()->visibility() != VISIBLE)
+ dirtyVisibleContentStatus();
+
oldChild->setPreviousSibling(0);
oldChild->setNextSibling(0);
- oldChild->setParent(0);
+ oldChild->m_parent = 0;
oldChild->updateDescendantDependentFlags();
- if (subtreeContainsOutOfFlowPositionedLayer(oldChild)) {
- // It may now be the case that a layer no longer has an unclipped
- // descendant. Let the compositor know that it needs to reevaluate
- // its compositing requirements to check this.
- compositor()->setNeedsUpdateCompositingRequirementsState();
- dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
- }
if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
dirtyAncestorChainVisibleDescendantStatus();
- if (oldChild->paintsWithBlendMode() || oldChild->childLayerHasBlendMode())
- dirtyAncestorChainBlendedDescendantStatus();
+ if (oldChild->m_blendInfo.hasBlendMode() || oldChild->blendInfo().childLayerHasBlendMode())
+ m_blendInfo.dirtyAncestorChainBlendedDescendantStatus();
if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
@@ -1482,9 +1452,6 @@ void RenderLayer::removeOnlyThisLayer()
if (!m_parent)
return;
- compositor()->layerWillBeRemoved(m_parent, this);
-
- // Dirty the clip rects.
m_clipper.clearClipRectsIncludingDescendants();
RenderLayer* nextSib = nextSibling();
@@ -1500,8 +1467,16 @@ void RenderLayer::removeOnlyThisLayer()
RenderLayer* next = current->nextSibling();
removeChild(current);
m_parent->addChild(current, nextSib);
- current->repainter().setRepaintStatus(NeedsFullRepaint);
- current->updateLayerPositions(0); // FIXME: use geometry map.
+
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ current->renderer()->setShouldDoFullPaintInvalidationAfterLayout(true);
+ else
+ current->repainter().setRepaintStatus(NeedsFullRepaint);
+
+ // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-part-1.html
+ DisableCompositingQueryAsserts disabler;
+
+ current->updateLayerPositionRecursive();
current = next;
}
@@ -1522,27 +1497,13 @@ void RenderLayer::insertOnlyThisLayer()
}
// Remove all descendant layers from the hierarchy and add them to the new position.
- for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())
+ for (RenderObject* curr = renderer()->slowFirstChild(); curr; curr = curr->nextSibling())
curr->moveLayers(m_parent, this);
// Clear out all the clip rects.
m_clipper.clearClipRectsIncludingDescendants();
}
-void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation) const
-{
- LayoutPoint location = roundedLocation;
- convertToLayerCoords(ancestorLayer, location);
- roundedLocation = roundedIntPoint(location);
-}
-
-void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect& roundedRect) const
-{
- LayoutRect rect = roundedRect;
- convertToLayerCoords(ancestorLayer, rect);
- roundedRect = pixelSnappedIntRect(rect);
-}
-
// Returns the layer reached on the walk up towards the ancestor.
static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location)
{
@@ -1559,7 +1520,7 @@ static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLay
// FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
// may need to be revisited in a future patch.
// If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
- // since localToAbsolute maps the coordinates from named flow to regions coordinates and regions can be
+ // since localToAbsolute maps the coordinates from flow thread to regions coordinates and regions can be
// positioned in a completely different place in the viewport (RenderView).
if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) {
// If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
@@ -1627,8 +1588,7 @@ static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLay
// We should not reach RenderView layer past the RenderFlowThread layer for any
// children of the RenderFlowThread.
- if (renderer->flowThreadContainingBlock() && !layer->isOutOfFlowRenderFlowThread())
- ASSERT(parentLayer != renderer->view()->layer());
+ ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer->view()->layer());
if (foundAncestorFirst) {
// Found ancestorLayer before the abs. positioned container, so compute offset of both relative
@@ -1673,8 +1633,7 @@ void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutR
RenderLayer* RenderLayer::scrollParent() const
{
- if (!compositorDrivenAcceleratedScrollingEnabled())
- return 0;
+ ASSERT(compositor()->acceleratedCompositingForOverflowScrollEnabled());
// Normal flow elements will be parented under the main scrolling layer, so
// we don't need a scroll parent/child relationship to get them to scroll.
@@ -1693,16 +1652,18 @@ RenderLayer* RenderLayer::scrollParent() const
// our scrolling ancestor, and we will therefore not scroll with it. In this case, we must
// be a composited layer since the compositor will need to take special measures to ensure
// that we scroll with our scrolling ancestor and it cannot do this if we do not promote.
- RenderLayer* scrollParent = ancestorCompositedScrollingLayer();
- if (!scrollParent || scrollParent->stackingNode()->isStackingContainer())
+ RenderLayer* scrollParent = ancestorScrollingLayer();
+ if (!scrollParent || scrollParent->stackingNode()->isStackingContext())
return 0;
// If we hit a stacking context on our way up to the ancestor scrolling layer, it will already
// be composited due to an overflow scrolling parent, so we don't need to.
for (RenderLayer* ancestor = parent(); ancestor && ancestor != scrollParent; ancestor = ancestor->parent()) {
- if (ancestor->stackingNode()->isStackingContainer())
- return 0;
+ if (ancestor->stackingNode()->isStackingContext()) {
+ scrollParent = 0;
+ break;
+ }
}
return scrollParent;
@@ -1710,38 +1671,24 @@ RenderLayer* RenderLayer::scrollParent() const
RenderLayer* RenderLayer::clipParent() const
{
- const bool needsAncestorClip = compositor()->clippedByAncestor(this);
-
- RenderLayer* clipParent = 0;
- if ((compositingReasons() & CompositingReasonOutOfFlowClipping) && !needsAncestorClip) {
+ if (compositingReasons() & CompositingReasonOutOfFlowClipping && !compositor()->clippedByNonAncestorInStackingTree(this)) {
if (RenderObject* containingBlock = renderer()->containingBlock())
- clipParent = containingBlock->enclosingLayer()->enclosingCompositingLayer(true);
+ return containingBlock->enclosingLayer()->enclosingCompositingLayer();
}
-
- return clipParent;
+ return 0;
}
void RenderLayer::didUpdateNeedsCompositedScrolling()
{
- m_stackingNode->updateIsNormalFlowOnly();
updateSelfPaintingLayer();
-
- if (m_stackingNode->isStackingContainer())
- m_stackingNode->dirtyZOrderLists();
- else
- m_stackingNode->clearZOrderLists();
-
- m_stackingNode->dirtyStackingContainerZOrderLists();
-
- compositor()->setNeedsToRecomputeCompositingRequirements();
- compositor()->setCompositingLayersNeedRebuild();
}
void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle)
{
+ ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle));
if (renderer()->hasReflection()) {
if (!m_reflectionInfo)
- m_reflectionInfo = adoptPtr(new RenderLayerReflectionInfo(toRenderBox(renderer())));
+ m_reflectionInfo = adoptPtr(new RenderLayerReflectionInfo(*renderBox()));
m_reflectionInfo->updateAfterStyleChange(oldStyle);
} else if (m_reflectionInfo) {
m_reflectionInfo = nullptr;
@@ -1759,7 +1706,7 @@ void RenderLayer::updateStackingNode()
void RenderLayer::updateScrollableArea()
{
if (requiresScrollableArea())
- m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(renderBox()));
+ m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(*this));
else
m_scrollableArea = nullptr;
}
@@ -1776,12 +1723,13 @@ bool RenderLayer::hasOverflowControls() const
return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollableArea->hasScrollCorner() || renderer()->style()->resize() != RESIZE_NONE);
}
-void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, RenderRegion* region, PaintLayerFlags paintFlags)
+void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, PaintLayerFlags paintFlags)
{
OverlapTestRequestMap overlapTestRequests;
- LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot, region, &overlapTestRequests);
- paintLayer(context, paintingInfo, paintFlags);
+ LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot, &overlapTestRequests);
+ if (shouldPaintLayerInSoftwareMode(context, paintingInfo, paintFlags))
+ paintLayer(context, paintingInfo, paintFlags);
OverlapTestRequestMap::iterator end = overlapTestRequests.end();
for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
@@ -1813,10 +1761,10 @@ static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye
return false;
}
-void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect,
- BorderRadiusClippingRule rule)
+void RenderLayer::clipToRect(const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const ClipRect& clipRect,
+ PaintLayerFlags paintFlags, BorderRadiusClippingRule rule)
{
- if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
+ if (clipRect.rect() == localPaintingInfo.paintDirtyRect && !clipRect.hasRadius())
return;
context->save();
context->clip(pixelSnappedIntRect(clipRect.rect()));
@@ -1828,13 +1776,20 @@ void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, c
// any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
// containing block chain so we check that also.
for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
+ // Composited scrolling layers handle border-radius clip in the compositor via a mask layer. We do not
+ // want to apply a border-radius clip to the layer contents itself, because that would require re-rastering
+ // every frame to update the clip. We only want to make sure that the mask layer is properly clipped so
+ // that it can in turn clip the scrolled contents in the compositor.
+ if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))
+ break;
+
if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) {
LayoutPoint delta;
- layer->convertToLayerCoords(rootLayer, delta);
+ layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size())));
}
- if (layer == rootLayer)
+ if (layer == localPaintingInfo.rootLayer)
break;
}
}
@@ -1850,7 +1805,7 @@ static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, cons
{
Vector<RenderWidget*> overlappedRequestClients;
OverlapTestRequestMap::iterator end = overlapTestRequests.end();
- LayoutRect boundingBox = layer->boundingBox(rootLayer);
+ LayoutRect boundingBox = layer->physicalBoundingBox(rootLayer);
for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) {
if (!boundingBox.intersects(it->value))
continue;
@@ -1858,13 +1813,7 @@ static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, cons
it->key->setIsOverlapped(true);
overlappedRequestClients.append(it->key);
}
- for (size_t i = 0; i < overlappedRequestClients.size(); ++i)
- overlapTestRequests.remove(overlappedRequestClients[i]);
-}
-
-static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection)
-{
- return paintingReflection && !layer->has3DTransform();
+ overlapTestRequests.removeAll(overlappedRequestClients);
}
static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
@@ -1872,7 +1821,7 @@ static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
// Avoid painting descendants of the root layer when stylesheets haven't loaded. This eliminates FOUC.
// It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
// will do a full repaint().
- if (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isRoot())
+ if (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isDocumentElement())
return true;
return false;
@@ -1880,21 +1829,22 @@ static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
static bool paintForFixedRootBackground(const RenderLayer* layer, PaintLayerFlags paintFlags)
{
- return layer->renderer()->isRoot() && (paintFlags & PaintLayerPaintingRootBackgroundOnly);
+ return layer->renderer()->isDocumentElement() && (paintFlags & PaintLayerPaintingRootBackgroundOnly);
+}
+
+static ShouldRespectOverflowClip shouldRespectOverflowClip(PaintLayerFlags paintFlags, const RenderObject* renderer)
+{
+ return (paintFlags & PaintLayerPaintingOverflowContents || (paintFlags & PaintLayerPaintingChildClippingMaskPhase && renderer->hasClipPath())) ? IgnoreOverflowClip : RespectOverflowClip;
}
void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
{
- if (compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking) {
- // The updatingControlTints() painting pass goes through compositing layers,
- // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
+ // https://code.google.com/p/chromium/issues/detail?id=343772
+ DisableCompositingQueryAsserts disabler;
+
+ if (compositingState() != NotComposited) {
if (context->updatingControlTints() || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)) {
paintFlags |= PaintLayerTemporaryClipRects;
- } else if (!compositedLayerMapping()->paintsIntoCompositedAncestor()
- && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)
- && !paintForFixedRootBackground(this, paintFlags)) {
- // If this RenderLayer should paint into its own backing, that will be done via CompositedLayerMapping::paintIntoLayer().
- return;
}
} else if (viewportConstrainedNotCompositedReason() == NotCompositedForBoundsOutOfView) {
// Don't paint out-of-view viewport constrained layers (when doing prepainting) because they will never be visible
@@ -1927,9 +1877,9 @@ void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
// layer from the parent now, assuming there is a parent
if (paintFlags & PaintLayerHaveTransparency) {
if (parent())
- parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+ parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
else
- beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+ beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
}
if (enclosingPaginationLayer()) {
@@ -1940,13 +1890,13 @@ void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
// Make sure the parent's clip rects have been calculated.
ClipRect clipRect = paintingInfo.paintDirtyRect;
if (parent()) {
- ClipRectsContext clipRectsContext(paintingInfo.rootLayer, paintingInfo.region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
- IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
- clipRect = backgroundClipRect(clipRectsContext);
+ ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
+ IgnoreOverlayScrollbarSize, shouldRespectOverflowClip(paintFlags, renderer()));
+ clipRect = clipper().backgroundClipRect(clipRectsContext);
clipRect.intersect(paintingInfo.paintDirtyRect);
// Push the parent coordinate space's clip.
- parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect);
+ parent()->clipToRect(paintingInfo, context, clipRect, paintFlags);
}
paintLayerByApplyingTransform(context, paintingInfo, paintFlags);
@@ -2003,7 +1953,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
GraphicsContext* transparencyLayerContext = context;
- if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isRoot())
+ if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isDocumentElement())
return;
// Ensure our lists are up-to-date.
@@ -2012,7 +1962,10 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
LayoutPoint offsetFromRoot;
convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
- IntRect rootRelativeBounds;
+ if (compositingState() == PaintsIntoOwnBacking)
+ offsetFromRoot.move(subpixelAccumulation());
+
+ LayoutRect rootRelativeBounds;
bool rootRelativeBoundsComputed = false;
// Apply clip-path to context.
@@ -2020,7 +1973,11 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
RenderStyle* style = renderer()->style();
RenderSVGResourceClipper* resourceClipper = 0;
ClipperContext clipperContext;
- if (renderer()->hasClipPath() && !context->paintingDisabled() && style) {
+
+ // Clip-path, like border radius, must not be applied to the contents of a composited-scrolling container.
+ // It must, however, still be applied to the mask layer, so that the compositor can properly mask the
+ // scrolling contents and scrollbars.
+ if (renderer()->hasClipPath() && !context->paintingDisabled() && style && (!needsCompositedScrolling() || paintFlags & PaintLayerPaintingChildClippingMaskPhase)) {
ASSERT(style->clipPath());
if (style->clipPath()->type() == ClipPathOperation::SHAPE) {
hasClipPath = true;
@@ -2028,7 +1985,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath());
if (!rootRelativeBoundsComputed) {
- rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
+ rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
rootRelativeBoundsComputed = true;
}
@@ -2038,9 +1995,9 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
Document& document = renderer()->document();
// FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
Element* element = document.getElementById(referenceClipPathOperation->fragment());
- if (element && element->hasTagName(SVGNames::clipPathTag) && element->renderer()) {
+ if (isSVGClipPathElement(element) && element->renderer()) {
if (!rootRelativeBoundsComputed) {
- rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
+ rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
rootRelativeBoundsComputed = true;
}
@@ -2056,10 +2013,10 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
// Blending operations must be performed only with the nearest ancestor stacking context.
// Note that there is no need to create a transparency layer if we're painting the root.
- bool createTransparencyLayerForBlendMode = !renderer()->isRoot() && m_stackingNode->isStackingContext() && m_childLayerHasBlendMode;
+ bool createTransparencyLayerForBlendMode = !renderer()->isDocumentElement() && m_stackingNode->isStackingContext() && m_blendInfo.childLayerHasBlendMode();
if (createTransparencyLayerForBlendMode)
- beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+ beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
LayerPaintingInfo localPaintingInfo(paintingInfo);
FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
@@ -2069,10 +2026,8 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y());
- if (!rootRelativeBoundsComputed) {
- rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
- rootRelativeBoundsComputed = true;
- }
+ if (!rootRelativeBoundsComputed)
+ rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
if (filterPainter.prepareFilterEffect(this, rootRelativeBounds, paintingInfo.paintDirtyRect, filterRepaintRect)) {
// Now we know for sure, that the source image will be updated, so we can revert our tracking repaint rect back to zero.
@@ -2097,7 +2052,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
if (filterPainter.hasStartedFilterEffect() && haveTransparency) {
// If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context.
- beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
+ beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
}
// If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
@@ -2132,37 +2087,39 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
// Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
// fragment should paint.
- collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.region, localPaintingInfo.paintDirtyRect,
+ collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect,
(paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
- (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetFromRoot);
+ shouldRespectOverflowClip(paintFlags, renderer()), &offsetFromRoot, localPaintingInfo.subPixelAccumulation);
updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot);
}
- if (shouldPaintBackground)
+ if (shouldPaintBackground) {
paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
- localPaintingInfo, paintBehavior, paintingRootForRenderer);
+ localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
+ }
if (shouldPaintNegZOrderList)
paintChildren(NegativeZOrderChildren, context, localPaintingInfo, paintFlags);
- if (shouldPaintOwnContents)
+ if (shouldPaintOwnContents) {
paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
- localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, forceBlackText);
+ localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, forceBlackText, paintFlags);
+ }
if (shouldPaintOutline)
- paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer);
+ paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
if (shouldPaintNormalFlowAndPosZOrderLists)
paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, localPaintingInfo, paintFlags);
if (shouldPaintOverlayScrollbars)
- paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo);
+ paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags);
if (filterPainter.hasStartedFilterEffect()) {
// Apply the correct clipping (ie. overflow: hidden).
// FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
- clipToRect(localPaintingInfo.rootLayer, transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
+ clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRect, paintFlags);
context = filterPainter.applyFilterEffect();
restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
}
@@ -2171,11 +2128,11 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
ASSERT(transparencyLayerContext == context);
if (shouldPaintMask)
- paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer);
+ paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
if (shouldPaintClippingMask) {
// Paint the border radius mask for the fragments.
- paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer);
+ paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
}
// End our transparency layer
@@ -2205,30 +2162,45 @@ void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const
LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
// Apply the transform.
- GraphicsContextStateSaver stateSaver(*context);
- context->concatCTM(transform.toAffineTransform());
+ GraphicsContextStateSaver stateSaver(*context, false);
+ if (!transform.isIdentity()) {
+ stateSaver.save();
+ context->concatCTM(transform.toAffineTransform());
+ }
// Now do a paint with the root layer shifted to be us.
LayerPaintingInfo transformedPaintingInfo(this, enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)), paintingInfo.paintBehavior,
- adjustedSubPixelAccumulation, paintingInfo.paintingRoot, paintingInfo.region, paintingInfo.overlapTestRequests);
+ adjustedSubPixelAccumulation, paintingInfo.paintingRoot, paintingInfo.overlapTestRequests);
paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
}
+bool RenderLayer::shouldPaintLayerInSoftwareMode(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
+{
+ DisableCompositingQueryAsserts disabler;
+
+ return compositingState() == NotComposited
+ || compositingState() == HasOwnBackingButPaintsIntoAncestor
+ || context->updatingControlTints()
+ || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)
+ || ((paintFlags & PaintLayerPaintingReflection) && !has3DTransform())
+ || paintForFixedRootBackground(this, paintFlags);
+}
+
void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
{
if (!hasSelfPaintingLayerDescendant())
return;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
LayerListMutationDetector mutationChecker(m_stackingNode.get());
#endif
RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit);
while (RenderLayerStackingNode* child = iterator.next()) {
RenderLayer* childLayer = child->layer();
-
- // Squashed RenderLayers should not paint into their ancestor.
- if (childLayer->compositingState() == PaintsIntoGroupedBacking)
+ // If this RenderLayer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents()
+ // and CompositedLayerMapping::doPaintTask().
+ if (!childLayer->shouldPaintLayerInSoftwareMode(context, paintingInfo, paintFlags))
continue;
if (!childLayer->isPaginated())
@@ -2238,15 +2210,15 @@ void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* conte
}
}
-void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, RenderRegion* region, const LayoutRect& dirtyRect,
+void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
- const LayoutRect* layerBoundingBox)
+ const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox)
{
if (!enclosingPaginationLayer() || hasTransform()) {
// For unpaginated layers, there is only one fragment.
LayerFragment fragment;
- ClipRectsContext clipRectsContext(rootLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
- calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
+ ClipRectsContext clipRectsContext(rootLayer, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip, subPixelAccumulation);
+ clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
fragments.append(fragment);
return;
}
@@ -2257,16 +2229,16 @@ void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer*
// Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
// layers between us and the pagination context. It's important to minimize the number of fragments we need to create and this helps with that.
- ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
+ ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
LayoutRect layerBoundsInFlowThread;
ClipRect backgroundRectInFlowThread;
ClipRect foregroundRectInFlowThread;
ClipRect outlineRectInFlowThread;
- calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
+ clipper().calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
outlineRectInFlowThread, &offsetWithinPaginatedLayer);
// Take our bounding box within the flow thread and clip it.
- LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : boundingBox(enclosingPaginationLayer(), 0, &offsetWithinPaginatedLayer);
+ LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : physicalBoundingBox(enclosingPaginationLayer(), &offsetWithinPaginatedLayer);
layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
// Shift the dirty rect into flow thread coordinates.
@@ -2286,8 +2258,8 @@ void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer*
// Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents.
ClipRect ancestorClipRect = dirtyRect;
if (enclosingPaginationLayer()->parent()) {
- ClipRectsContext clipRectsContext(rootLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
- ancestorClipRect = enclosingPaginationLayer()->backgroundClipRect(clipRectsContext);
+ ClipRectsContext clipRectsContext(rootLayer, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
+ ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect(clipRectsContext);
ancestorClipRect.intersect(dirtyRect);
}
@@ -2328,10 +2300,10 @@ void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, c
{
LayerFragments enclosingPaginationFragments;
LayoutPoint offsetOfPaginationLayerFromRoot;
- LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.paintBehavior);
- enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.region, paintingInfo.paintDirtyRect,
+ LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
+ enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
(paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
- (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetOfPaginationLayerFromRoot, &transformedExtent);
+ shouldRespectOverflowClip(paintFlags, renderer()), &offsetOfPaginationLayerFromRoot, paintingInfo.subPixelAccumulation, &transformedExtent);
for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) {
const LayerFragment& fragment = enclosingPaginationFragments.at(i);
@@ -2344,22 +2316,31 @@ void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, c
if (parent() != enclosingPaginationLayer()) {
enclosingPaginationLayer()->convertToLayerCoords(paintingInfo.rootLayer, offsetOfPaginationLayerFromRoot);
- ClipRectsContext clipRectsContext(enclosingPaginationLayer(), paintingInfo.region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
- IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
- LayoutRect parentClipRect = backgroundClipRect(clipRectsContext).rect();
+ ClipRectsContext clipRectsContext(enclosingPaginationLayer(), (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
+ IgnoreOverlayScrollbarSize, shouldRespectOverflowClip(paintFlags, renderer()));
+ LayoutRect parentClipRect = clipper().backgroundClipRect(clipRectsContext).rect();
parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
clipRect.intersect(parentClipRect);
}
- parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect);
+ parent()->clipToRect(paintingInfo, context, clipRect, paintFlags);
paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset);
parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
}
}
+static inline LayoutSize subPixelAccumulationIfNeeded(const LayoutSize& subPixelAccumulation, CompositingState compositingState)
+{
+ // Only apply the sub-pixel accumulation if we don't paint into our own backing layer, otherwise the position
+ // of the renderer already includes any sub-pixel offset.
+ if (compositingState == PaintsIntoOwnBacking)
+ return LayoutSize();
+ return subPixelAccumulation;
+}
+
void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
- RenderObject* paintingRootForRenderer)
+ RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
{
for (size_t i = 0; i < layerFragments.size(); ++i) {
const LayerFragment& fragment = layerFragments.at(i);
@@ -2368,18 +2349,18 @@ void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen
// Begin transparency layers lazily now that we know we have to paint something.
if (haveTransparency || paintsWithBlendMode())
- beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
+ beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
if (localPaintingInfo.clipToDirtyRect) {
// Paint our background first, before painting any child layers.
// Establish the clip used to paint our background.
- clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
+ clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
}
// Paint the background.
// FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
- PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
- renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+ PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
+ renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
if (localPaintingInfo.clipToDirtyRect)
restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
@@ -2388,14 +2369,14 @@ void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen
void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
- RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackText)
+ RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackText, PaintLayerFlags paintFlags)
{
// Begin transparency if we have something to paint.
if (haveTransparency || paintsWithBlendMode()) {
for (size_t i = 0; i < layerFragments.size(); ++i) {
const LayerFragment& fragment = layerFragments.at(i);
if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) {
- beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
+ beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
break;
}
}
@@ -2406,17 +2387,17 @@ void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen
// Optimize clipping for the single fragment case.
bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
if (shouldClip)
- clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
+ clipToRect(localPaintingInfo, context, layerFragments[0].foregroundRect, paintFlags);
// We have to loop through every fragment multiple times, since we have to repaint in each specific phase in order for
// interleaving of the fragments to work properly.
paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments,
- context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
+ context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer, paintFlags);
if (!selectionOnly) {
- paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
- paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
- paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
+ paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer, paintFlags);
+ paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer, paintFlags);
+ paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer, paintFlags);
}
if (shouldClip)
@@ -2424,7 +2405,7 @@ void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen
}
void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext* context,
- const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer)
+ const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
{
bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1;
@@ -2434,12 +2415,12 @@ void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const L
continue;
if (shouldClip)
- clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
+ clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags);
- PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
+ PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
if (phase == PaintPhaseForeground)
paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
- renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+ renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
if (shouldClip)
restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
@@ -2447,7 +2428,7 @@ void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const L
}
void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
- PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer)
+ PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
{
for (size_t i = 0; i < layerFragments.size(); ++i) {
const LayerFragment& fragment = layerFragments.at(i);
@@ -2455,15 +2436,15 @@ void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments,
continue;
// Paint our own outline
- PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
- clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.outlineRect, DoNotIncludeSelfForBorderRadius);
- renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+ PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
+ clipToRect(localPaintingInfo, context, fragment.outlineRect, paintFlags, DoNotIncludeSelfForBorderRadius);
+ renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect);
}
}
void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
- RenderObject* paintingRootForRenderer)
+ RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
{
for (size_t i = 0; i < layerFragments.size(); ++i) {
const LayerFragment& fragment = layerFragments.at(i);
@@ -2471,12 +2452,12 @@ void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, Gr
continue;
if (localPaintingInfo.clipToDirtyRect)
- clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
+ clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
// Paint the mask.
// FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
- PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
- renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+ PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
+ renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
if (localPaintingInfo.clipToDirtyRect)
restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
@@ -2484,7 +2465,7 @@ void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, Gr
}
void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
- RenderObject* paintingRootForRenderer)
+ RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
{
for (size_t i = 0; i < layerFragments.size(); ++i) {
const LayerFragment& fragment = layerFragments.at(i);
@@ -2492,24 +2473,24 @@ void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layer
continue;
if (localPaintingInfo.clipToDirtyRect)
- clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
+ clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
// Paint the the clipped mask.
- PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
- renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+ PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
+ renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
if (localPaintingInfo.clipToDirtyRect)
restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
}
}
-void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo)
+void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags)
{
for (size_t i = 0; i < layerFragments.size(); ++i) {
const LayerFragment& fragment = layerFragments.at(i);
- clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
+ clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags);
if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
- scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation)), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
+ scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
}
}
@@ -2518,7 +2499,7 @@ void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsCont
{
// We need to do multiple passes, breaking up our child layer into strips.
Vector<RenderLayer*> columnLayers;
- RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContainerNode();
+ RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
columnLayers.append(curr);
@@ -2527,8 +2508,8 @@ void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsCont
}
// It is possible for paintLayer() to be called after the child layer ceases to be paginated but before
- // updateLayerPositions() is called and resets the isPaginated() flag, see <rdar://problem/10098679>.
- // If this is the case, just bail out, since the upcoming call to updateLayerPositions() will repaint the layer.
+ // updateLayerPositionRecursive() is called and resets the isPaginated() flag, see <rdar://problem/10098679>.
+ // If this is the case, just bail out, since the upcoming call to updateLayerPositionRecursive() will repaint the layer.
if (!columnLayers.size())
return;
@@ -2582,7 +2563,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsCo
// Each strip pushes a clip, since column boxes are specified as being
// like overflow:hidden.
- context->clip(pixelSnappedIntRect(colRect));
+ context->clip(enclosingIntRect(colRect));
if (!colIndex) {
// Apply a translation transform to change where the layer paints.
@@ -2651,9 +2632,9 @@ bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation&
// RenderView should make sure to update layout before entering hit testing
ASSERT(!renderer()->frame()->view()->layoutPending());
- ASSERT(!renderer()->document().renderer()->needsLayout());
+ ASSERT(!renderer()->document().renderView()->needsLayout());
- LayoutRect hitTestArea = isOutOfFlowRenderFlowThread() ? toRenderFlowThread(renderer())->borderBoxRect() : renderer()->view()->documentRect();
+ LayoutRect hitTestArea = renderer()->view()->documentRect();
if (!request.ignoreClipping())
hitTestArea.intersect(frameVisibleRect(renderer()));
@@ -2694,15 +2675,6 @@ bool RenderLayer::isInTopLayer() const
return node && node->isElementNode() && toElement(node)->isInTopLayer();
}
-bool RenderLayer::isInTopLayerSubtree() const
-{
- for (const RenderLayer* layer = this; layer; layer = layer->parent()) {
- if (layer->isInTopLayer())
- return true;
- }
- return false;
-}
-
// Compute the z-offset of the point in the transformState.
// This is effectively projecting a ray normal to the plane of ancestor, finding where that
// ray intersects target, and computing the z delta between those two points.
@@ -2800,8 +2772,8 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
// Make sure the parent's clip rects have been calculated.
if (parent()) {
- ClipRectsContext clipRectsContext(rootLayer, hitTestLocation.region(), RootRelativeClipRects, IncludeOverlayScrollbarSize);
- ClipRect clipRect = backgroundClipRect(clipRectsContext);
+ ClipRectsContext clipRectsContext(rootLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize);
+ ClipRect clipRect = clipper().backgroundClipRect(clipRectsContext);
// Go ahead and test the enclosing clip now.
if (!clipRect.intersects(hitTestLocation))
return 0;
@@ -2886,7 +2858,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
// Collect the fragments. This will compute the clip rectangles for each layer fragment.
LayerFragments layerFragments;
- collectFragments(layerFragments, rootLayer, hitTestLocation.region(), hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
+ collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFragments, hitTestLocation)) {
renderer()->updateHitTestResult(result, hitTestLocation.point());
@@ -2968,9 +2940,10 @@ RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLa
{
LayerFragments enclosingPaginationFragments;
LayoutPoint offsetOfPaginationLayerFromRoot;
- LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox);
- enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestLocation.region(), hitTestRect,
- RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, &transformedExtent);
+ // FIXME: We're missing a sub-pixel offset here crbug.com/348728
+ LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox, LayoutSize());
+ enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect,
+ RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent);
for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) {
const LayerFragment& fragment = enclosingPaginationFragments.at(i);
@@ -2983,8 +2956,8 @@ RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLa
if (parent() != enclosingPaginationLayer()) {
enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
- ClipRectsContext clipRectsContext(enclosingPaginationLayer(), hitTestLocation.region(), RootRelativeClipRects, IncludeOverlayScrollbarSize);
- LayoutRect parentClipRect = backgroundClipRect(clipRectsContext).rect();
+ ClipRectsContext clipRectsContext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbarSize);
+ LayoutRect parentClipRect = clipper().backgroundClipRect(clipRectsContext).rect();
parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
clipRect.intersect(parentClipRect);
}
@@ -3100,7 +3073,7 @@ RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, Re
const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
{
Vector<RenderLayer*> columnLayers;
- RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContainerNode();
+ RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
columnLayers.append(curr);
@@ -3216,166 +3189,16 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
return 0;
}
-void RenderLayer::parentClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const
-{
- ASSERT(parent());
- if (clipRectsContext.clipRectsType == TemporaryClipRects) {
- parent()->clipper().calculateClipRects(clipRectsContext, clipRects);
- return;
- }
-
- parent()->m_clipper.updateClipRects(clipRectsContext);
- clipRects = *parent()->clipper().clipRects(clipRectsContext);
-}
-
-static inline ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position)
+void RenderLayer::blockSelectionGapsBoundsChanged()
{
- if (position == FixedPosition)
- return parentRects.fixedClipRect();
-
- if (position == AbsolutePosition)
- return parentRects.posClipRect();
-
- return parentRects.overflowClipRect();
-}
-
-ClipRect RenderLayer::backgroundClipRect(const ClipRectsContext& clipRectsContext) const
-{
- ASSERT(parent());
-
- ClipRects parentRects;
-
- // If we cross into a different pagination context, then we can't rely on the cache.
- // Just switch over to using TemporaryClipRects.
- if (clipRectsContext.clipRectsType != TemporaryClipRects && parent()->enclosingPaginationLayer() != enclosingPaginationLayer()) {
- ClipRectsContext tempContext(clipRectsContext);
- tempContext.clipRectsType = TemporaryClipRects;
- parentClipRects(tempContext, parentRects);
- } else
- parentClipRects(clipRectsContext, parentRects);
-
- ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer()->style()->position());
- RenderView* view = renderer()->view();
- ASSERT(view);
-
- // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
- if (parentRects.fixed() && clipRectsContext.rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect())
- backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition());
-
- return backgroundClipRect;
-}
-
-void RenderLayer::calculateRects(const ClipRectsContext& clipRectsContext, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
- ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot) const
-{
- if (clipRectsContext.rootLayer != this && parent()) {
- backgroundRect = backgroundClipRect(clipRectsContext);
- backgroundRect.intersect(paintDirtyRect);
- } else
- backgroundRect = paintDirtyRect;
-
- foregroundRect = backgroundRect;
- outlineRect = backgroundRect;
-
- LayoutPoint offset;
- if (offsetFromRoot)
- offset = *offsetFromRoot;
- else
- convertToLayerCoords(clipRectsContext.rootLayer, offset);
- layerBounds = LayoutRect(offset, size());
-
- // Update the clip rects that will be passed to child layers.
- if (renderer()->hasOverflowClip()) {
- // This layer establishes a clip of some kind.
- if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) {
- foregroundRect.intersect(toRenderBox(renderer())->overflowClipRect(offset, clipRectsContext.region, clipRectsContext.overlayScrollbarSizeRelevancy));
- if (renderer()->style()->hasBorderRadius())
- foregroundRect.setHasRadius(true);
- }
-
- // If we establish an overflow clip at all, then go ahead and make sure our background
- // rect is intersected with our layer's bounds including our visual overflow,
- // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden.
- if (renderBox()->hasVisualOverflow()) {
- // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though
- // we may need to inflate our clip specifically for shadows or outsets.
- // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the
- // individual region boxes as overflow.
- LayoutRect layerBoundsWithVisualOverflow = renderBox()->visualOverflowRect();
- renderBox()->flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped.
- layerBoundsWithVisualOverflow.moveBy(offset);
- if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)
- backgroundRect.intersect(layerBoundsWithVisualOverflow);
- } else {
- // Shift the bounds to be for our region only.
- LayoutRect bounds = renderBox()->borderBoxRectInRegion(clipRectsContext.region);
- bounds.moveBy(offset);
- if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)
- backgroundRect.intersect(bounds);
- }
- }
-
- // CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box.
- if (renderer()->hasClip()) {
- // Clip applies to *us* as well, so go ahead and update the damageRect.
- LayoutRect newPosClip = toRenderBox(renderer())->clipRect(offset, clipRectsContext.region);
- backgroundRect.intersect(newPosClip);
- foregroundRect.intersect(newPosClip);
- outlineRect.intersect(newPosClip);
- }
-}
-
-LayoutRect RenderLayer::childrenClipRect() const
-{
- // FIXME: border-radius not accounted for.
- // FIXME: Regions not accounted for.
- RenderView* renderView = renderer()->view();
- RenderLayer* clippingRootLayer = clippingRootForPainting();
- LayoutRect layerBounds;
- ClipRect backgroundRect, foregroundRect, outlineRect;
- ClipRectsContext clipRectsContext(clippingRootLayer, 0, TemporaryClipRects);
- // Need to use temporary clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>).
- calculateRects(clipRectsContext, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
- return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
-}
-
-LayoutRect RenderLayer::selfClipRect() const
-{
- // FIXME: border-radius not accounted for.
- // FIXME: Regions not accounted for.
- RenderView* renderView = renderer()->view();
- RenderLayer* clippingRootLayer = clippingRootForPainting();
- LayoutRect layerBounds;
- ClipRect backgroundRect, foregroundRect, outlineRect;
- ClipRectsContext clipRectsContext(clippingRootLayer, 0, PaintingClipRects);
- calculateRects(clipRectsContext, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
- return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox();
-}
-
-LayoutRect RenderLayer::localClipRect() const
-{
- // FIXME: border-radius not accounted for.
- // FIXME: Regions not accounted for.
- RenderLayer* clippingRootLayer = clippingRootForPainting();
- LayoutRect layerBounds;
- ClipRect backgroundRect, foregroundRect, outlineRect;
- ClipRectsContext clipRectsContext(clippingRootLayer, 0, PaintingClipRects);
- calculateRects(clipRectsContext, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
-
- LayoutRect clipRect = backgroundRect.rect();
- if (clipRect == PaintInfo::infiniteRect())
- return clipRect;
-
- LayoutPoint clippingRootOffset;
- convertToLayerCoords(clippingRootLayer, clippingRootOffset);
- clipRect.moveBy(-clippingRootOffset);
-
- return clipRect;
+ setNeedsCompositingInputsUpdate();
+ compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
}
void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds)
{
m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds));
+ blockSelectionGapsBoundsChanged();
}
void RenderLayer::clearBlockSelectionGapsBounds()
@@ -3383,6 +3206,7 @@ void RenderLayer::clearBlockSelectionGapsBounds()
m_blockSelectionGapsBounds = IntRect();
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
child->clearBlockSelectionGapsBounds();
+ blockSelectionGapsBoundsChanged();
}
void RenderLayer::repaintBlockSelectionGaps()
@@ -3398,25 +3222,43 @@ void RenderLayer::repaintBlockSelectionGaps()
RenderBox* box = renderBox();
rect.move(-box->scrolledContentOffset());
if (!scrollableArea()->usesCompositedScrolling())
- rect.intersect(box->overflowClipRect(LayoutPoint(), 0)); // FIXME: Regions not accounted for.
+ rect.intersect(box->overflowClipRect(LayoutPoint()));
}
if (renderer()->hasClip())
- rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint(), 0)); // FIXME: Regions not accounted for.
+ rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint()));
if (!rect.isEmpty())
- renderer()->repaintRectangle(rect);
+ renderer()->invalidatePaintRectangle(rect);
+}
+
+IntRect RenderLayer::blockSelectionGapsBounds() const
+{
+ if (!renderer()->isRenderBlock())
+ return IntRect();
+
+ RenderBlock* renderBlock = toRenderBlock(renderer());
+ LayoutRect gapRects = renderBlock->selectionGapRectsForRepaint(renderBlock);
+
+ return pixelSnappedIntRect(gapRects);
}
bool RenderLayer::hasBlockSelectionGapBounds() const
{
- return !m_blockSelectionGapsBounds.isEmpty();
+ // FIXME: it would be more accurate to return !blockSelectionGapsBounds().isEmpty(), but this is impossible
+ // at the moment because it causes invalid queries to layout-dependent code (crbug.com/372802).
+ // ASSERT(renderer()->document().lifecycle().state() >= DocumentLifecycle::LayoutClean);
+
+ if (!renderer()->isRenderBlock())
+ return false;
+
+ return toRenderBlock(renderer())->shouldPaintSelectionGaps();
}
bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const
{
// Always examine the canvas and the root.
- // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
+ // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
// paints the root's background.
- if (isRootLayer() || renderer()->isRoot())
+ if (isRootLayer() || renderer()->isDocumentElement())
return true;
// If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
@@ -3424,18 +3266,16 @@ bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo
RenderView* view = renderer()->view();
ASSERT(view);
if (view && !renderer()->isRenderInline()) {
- LayoutRect b = layerBounds;
- b.inflate(view->maximalOutlineSize());
- if (b.intersects(damageRect))
+ if (layerBounds.intersects(damageRect))
return true;
}
// Otherwise we need to compute the bounding box of this single layer and see if it intersects
// the damage rect.
- return boundingBox(rootLayer, 0, offsetFromRoot).intersects(damageRect);
+ return physicalBoundingBox(rootLayer, offsetFromRoot).intersects(damageRect);
}
-LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const
+LayoutRect RenderLayer::logicalBoundingBox() const
{
// There are three special cases we need to consider.
// (1) Inline Flows. For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
@@ -3447,11 +3287,11 @@ LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const
// as part of our bounding box. We do this because we are the responsible layer for both hit testing and painting those
// floats.
LayoutRect result;
- if (renderer()->isInline() && renderer()->isRenderInline())
+ if (renderer()->isInline() && renderer()->isRenderInline()) {
result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
- else if (renderer()->isTableRow()) {
+ } else if (renderer()->isTableRow()) {
// Our bounding box is just the union of all of our cells' border/overflow rects.
- for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
if (child->isTableCell()) {
LayoutRect bbox = toRenderBox(child)->borderBoxRect();
result.unite(bbox);
@@ -3463,52 +3303,21 @@ LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const
} else {
RenderBox* box = renderBox();
ASSERT(box);
- if (!(flags & DontConstrainForMask) && box->hasMask()) {
- result = box->maskClipRect();
- box->flipForWritingMode(result); // The mask clip rect is in physical coordinates, so we have to flip, since localBoundingBox is not.
- } else {
- LayoutRect bbox = box->borderBoxRect();
- result = bbox;
- LayoutRect overflowRect = box->visualOverflowRect();
- if (bbox != overflowRect)
- result.unite(overflowRect);
- }
+ result = box->borderBoxRect();
+ result.unite(box->visualOverflowRect());
}
- RenderView* view = renderer()->view();
- ASSERT(view);
- if (view)
- result.inflate(view->maximalOutlineSize()); // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
-
+ ASSERT(renderer()->view());
return result;
}
-LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer, CalculateLayerBoundsFlags flags, const LayoutPoint* offsetFromRoot) const
+LayoutRect RenderLayer::physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot) const
{
- LayoutRect result = localBoundingBox(flags);
- if (renderer()->isBox())
+ LayoutRect result = logicalBoundingBox();
+ if (m_renderer->isBox())
renderBox()->flipForWritingMode(result);
else
- renderer()->containingBlock()->flipForWritingMode(result);
-
- if (enclosingPaginationLayer() && (flags & UseFragmentBoxes)) {
- // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
- // get our true bounding box.
- LayoutPoint offsetWithinPaginationLayer;
- convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginationLayer);
- result.moveBy(offsetWithinPaginationLayer);
-
- RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
- result = enclosingFlowThread->fragmentsBoundingBox(result);
-
- LayoutPoint delta;
- if (offsetFromRoot)
- delta = *offsetFromRoot;
- else
- enclosingPaginationLayer()->convertToLayerCoords(ancestorLayer, delta);
- result.moveBy(delta);
- return result;
- }
+ m_renderer->containingBlock()->flipForWritingMode(result);
LayoutPoint delta;
if (offsetFromRoot)
@@ -3520,125 +3329,120 @@ LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer, CalculateL
return result;
}
-IntRect RenderLayer::absoluteBoundingBox() const
+LayoutRect RenderLayer::physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const
{
- return pixelSnappedIntRect(boundingBox(root()));
-}
+ LayoutPoint origin;
+ LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
-IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const
-{
- if (!isSelfPaintingLayer())
- return IntRect();
+ if (m_reflectionInfo && !m_reflectionInfo->reflectionLayer()->hasCompositedLayerMapping())
+ result.unite(m_reflectionInfo->reflectionLayer()->physicalBoundingBox(this));
- // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
- if ((flags & ExcludeHiddenDescendants) && this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
- return IntRect();
+ ASSERT(m_stackingNode->isStackingContext() || !m_stackingNode->hasPositiveZOrderList());
- RenderLayerModelObject* renderer = this->renderer();
+ const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
- if (isRootLayer()) {
- // The root layer is always just the size of the document.
- return renderer->view()->unscaledDocumentRect();
+#if ASSERT_ENABLED
+ LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(this)->stackingNode());
+#endif
+
+ RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), AllChildren);
+ while (RenderLayerStackingNode* node = iterator.next()) {
+ if (node->layer()->hasCompositedLayerMapping())
+ continue;
+ // FIXME: Can we call physicalBoundingBoxIncludingReflectionAndStackingChildren instead of boundingBoxForCompositing?
+ result.unite(node->layer()->boundingBoxForCompositing(this));
}
- LayoutRect boundingBoxRect = localBoundingBox(flags);
+ result.moveBy(offsetFromRoot);
+ return result;
+}
- if (renderer->isBox())
- toRenderBox(renderer)->flipForWritingMode(boundingBoxRect);
- else
- renderer->containingBlock()->flipForWritingMode(boundingBoxRect);
-
- if (renderer->isRoot()) {
- // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited),
- // then it has to be big enough to cover the viewport in order to display the background. This is akin
- // to the code in RenderBox::paintRootBoxFillLayers().
- if (FrameView* frameView = renderer->view()->frameView()) {
- LayoutUnit contentsWidth = frameView->contentsWidth();
- LayoutUnit contentsHeight = frameView->contentsHeight();
-
- boundingBoxRect.setWidth(max(boundingBoxRect.width(), contentsWidth - boundingBoxRect.x()));
- boundingBoxRect.setHeight(max(boundingBoxRect.height(), contentsHeight - boundingBoxRect.y()));
- }
+static void expandCompositingRectForStackingChildren(const RenderLayer* ancestorLayer, RenderLayer::CalculateBoundsOptions options, LayoutRect& result)
+{
+ RenderLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllChildren);
+ while (RenderLayerStackingNode* node = iterator.next()) {
+ // Here we exclude both directly composited layers and squashing layers
+ // because those RenderLayers don't paint into the graphics layer
+ // for this RenderLayer. For example, the bounds of squashed RenderLayers
+ // will be included in the computation of the appropriate squashing
+ // GraphicsLayer.
+ if (options != RenderLayer::ApplyBoundsChickenEggHacks && node->layer()->compositingState() != NotComposited)
+ continue;
+ result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, options));
}
+}
- LayoutRect unionBounds = boundingBoxRect;
- bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (transform() && flags & PretendLayerHasOwnBacking);
+LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLayer, CalculateBoundsOptions options) const
+{
+ if (!isSelfPaintingLayer())
+ return LayoutRect();
- if (flags & UseLocalClipRectIfPossible) {
- LayoutRect localClipRect = this->localClipRect();
- if (localClipRect != PaintInfo::infiniteRect()) {
- if ((flags & IncludeSelfTransform) && shouldIncludeTransform)
- localClipRect = transform()->mapRect(localClipRect);
+ if (!ancestorLayer)
+ ancestorLayer = this;
- LayoutPoint ancestorRelOffset;
- convertToLayerCoords(ancestorLayer, ancestorRelOffset);
- localClipRect.moveBy(ancestorRelOffset);
- return pixelSnappedIntRect(localClipRect);
- }
+ // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
+ if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
+ return LayoutRect();
+
+ // The root layer is always just the size of the document.
+ if (isRootLayer())
+ return m_renderer->view()->unscaledDocumentRect();
+
+ const bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChickenEggHacks && transform());
+
+ LayoutRect localClipRect = clipper().localClipRect();
+ if (localClipRect != PaintInfo::infiniteRect()) {
+ if (shouldIncludeTransform)
+ localClipRect = transform()->mapRect(localClipRect);
+
+ LayoutPoint delta;
+ convertToLayerCoords(ancestorLayer, delta);
+ localClipRect.moveBy(delta);
+ return localClipRect;
}
- // FIXME: should probably just pass 'flags' down to descendants.
- CalculateLayerBoundsFlags descendantFlags = DefaultCalculateLayerBoundsFlags | (flags & ExcludeHiddenDescendants) | (flags & IncludeCompositedDescendants);
+ LayoutPoint origin;
+ LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
- if (m_reflectionInfo) {
- RenderLayer* reflectionLayer = m_reflectionInfo->reflectionLayer();
- if (!reflectionLayer->hasCompositedLayerMapping()) {
- IntRect childUnionBounds = reflectionLayer->calculateLayerBounds(this, 0, descendantFlags);
- unionBounds.unite(childUnionBounds);
- }
- }
+ if (m_reflectionInfo && !m_reflectionInfo->reflectionLayer()->hasCompositedLayerMapping())
+ result.unite(m_reflectionInfo->reflectionLayer()->boundingBoxForCompositing(this));
- ASSERT(m_stackingNode->isStackingContainer() || !m_stackingNode->hasPositiveZOrderList());
+ ASSERT(m_stackingNode->isStackingContext() || !m_stackingNode->hasPositiveZOrderList());
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(this)->stackingNode());
#endif
- // FIXME: Descendants that are composited should not necessarily be skipped, if they don't paint into their own
- // separate backing. Instead, they ought to contribute to the bounds of the layer we're trying to compute.
- // This applies to all z-order lists below.
- RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), AllChildren);
- while (RenderLayerStackingNode* node = iterator.next()) {
- // Node's compositing ancestor may have changed its draw content status
- // prior to updating its bounds. The requires-own-backing-store-for-ancestor-reasons
- // could be stale. Refresh them now.
- if (node->layer()->hasCompositedLayerMapping()) {
- RenderLayer* enclosingCompositingLayer = node->layer()->enclosingCompositingLayer(false);
- node->layer()->compositedLayerMapping()->updateRequiresOwnBackingStoreForAncestorReasons(enclosingCompositingLayer);
- }
-
- if (flags & IncludeCompositedDescendants || !node->layer()->hasCompositedLayerMapping()) {
- IntRect childUnionBounds = node->layer()->calculateLayerBounds(this, 0, descendantFlags);
- unionBounds.unite(childUnionBounds);
- }
- }
+ // Reflections are implemented with RenderLayers that hang off of the reflected layer. However,
+ // the reflection layer subtree does not include the subtree of the parent RenderLayer, so
+ // a recursive computation of stacking children yields no results. This breaks cases when there are stacking
+ // children of the parent, that need to be included in reflected composited bounds.
+ // Fix this by including composited bounds of stacking children of the reflected RenderLayer.
+ if (parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this)
+ expandCompositingRectForStackingChildren(parent(), options, result);
+ else
+ expandCompositingRectForStackingChildren(this, options, result);
// FIXME: We can optimize the size of the composited layers, by not enlarging
// filtered areas with the outsets if we know that the filter is going to render in hardware.
// https://bugs.webkit.org/show_bug.cgi?id=81239
- if (flags & IncludeLayerFilterOutsets)
- renderer->style()->filterOutsets().expandRect(unionBounds);
-
- if ((flags & IncludeSelfTransform) && shouldIncludeTransform) {
- TransformationMatrix* affineTrans = transform();
- boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
- unionBounds = affineTrans->mapRect(unionBounds);
- }
+ m_renderer->style()->filterOutsets().expandRect(result);
- LayoutPoint ancestorRelOffset;
- if (offsetFromRoot)
- ancestorRelOffset = *offsetFromRoot;
- else
- convertToLayerCoords(ancestorLayer, ancestorRelOffset);
- unionBounds.moveBy(ancestorRelOffset);
+ if (shouldIncludeTransform)
+ result = transform()->mapRect(result);
- return pixelSnappedIntRect(unionBounds);
+ LayoutPoint delta;
+ convertToLayerCoords(ancestorLayer, delta);
+ result.moveBy(delta);
+ return result;
}
CompositingState RenderLayer::compositingState() const
{
+ ASSERT(isAllowedToQueryCompositingState());
+
// This is computed procedurally so there is no redundant state variable that
// can get out of sync from the real actual compositing state.
@@ -3651,34 +3455,70 @@ CompositingState RenderLayer::compositingState() const
if (!m_compositedLayerMapping)
return NotComposited;
- if (m_compositedLayerMapping && compositedLayerMapping()->paintsIntoCompositedAncestor())
+ if (compositedLayerMapping()->paintsIntoCompositedAncestor())
return HasOwnBackingButPaintsIntoAncestor;
- ASSERT(m_compositedLayerMapping);
return PaintsIntoOwnBacking;
}
+bool RenderLayer::isAllowedToQueryCompositingState() const
+{
+ if (gCompositingQueryMode == CompositingQueriesAreAllowed)
+ return true;
+ return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate;
+}
+
+CompositedLayerMappingPtr RenderLayer::compositedLayerMapping() const
+{
+ ASSERT(isAllowedToQueryCompositingState());
+ return m_compositedLayerMapping.get();
+}
+
CompositedLayerMappingPtr RenderLayer::ensureCompositedLayerMapping()
{
if (!m_compositedLayerMapping) {
- m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(this));
+ m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this));
+ m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
updateOrRemoveFilterEffectRenderer();
if (RuntimeEnabledFeatures::cssCompositingEnabled())
- compositedLayerMapping()->setBlendMode(m_blendMode);
+ compositedLayerMapping()->setBlendMode(m_blendInfo.blendMode());
}
return m_compositedLayerMapping.get();
}
void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed)
{
+ if (!layerBeingDestroyed) {
+ // We need to make sure our decendants get a geometry update. In principle,
+ // we could call setNeedsGraphicsLayerUpdate on our children, but that would
+ // require walking the z-order lists to find them. Instead, we over-invalidate
+ // by marking our parent as needing a geometry update.
+ if (RenderLayer* compositingParent = enclosingCompositingLayer(ExcludeSelf))
+ compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+ }
+
m_compositedLayerMapping.clear();
if (!layerBeingDestroyed)
updateOrRemoveFilterEffectRenderer();
}
+void RenderLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed)
+{
+ if (groupedMapping == m_groupedMapping)
+ return;
+
+ if (!layerBeingDestroyed && m_groupedMapping) {
+ m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+ m_groupedMapping->removeRenderLayerFromSquashingGraphicsLayer(this);
+ }
+ m_groupedMapping = groupedMapping;
+ if (!layerBeingDestroyed && m_groupedMapping)
+ m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+}
+
bool RenderLayer::hasCompositedMask() const
{
return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer();
@@ -3703,6 +3543,11 @@ bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking);
}
+bool RenderLayer::paintsWithBlendMode() const
+{
+ return m_blendInfo.hasBlendMode() && compositingState() != PaintsIntoOwnBacking;
+}
+
bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
{
if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
@@ -3764,32 +3609,13 @@ bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& local
return false;
}
-void RenderLayer::setParent(RenderLayer* parent)
-{
- if (parent == m_parent)
- return;
-
- if (m_parent && !renderer()->documentBeingDestroyed())
- compositor()->layerWillBeRemoved(m_parent, this);
-
- m_parent = parent;
-
- if (m_parent && !renderer()->documentBeingDestroyed())
- compositor()->layerWasAdded(m_parent, this);
-}
-
bool RenderLayer::shouldBeSelfPaintingLayer() const
{
- return !m_stackingNode->isNormalFlowOnly()
+ if (renderer()->isRenderPart() && toRenderPart(renderer())->requiresAcceleratedCompositing())
+ return true;
+ return m_layerType == NormalLayer
|| (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars())
- || needsCompositedScrolling()
- || renderer()->hasReflection()
- || renderer()->hasMask()
- || renderer()->isTableRow()
- || renderer()->isCanvas()
- || renderer()->isVideo()
- || renderer()->isEmbeddedObject()
- || renderer()->isRenderIFrame();
+ || needsCompositedScrolling();
}
void RenderLayer::updateSelfPaintingLayer()
@@ -3814,7 +3640,7 @@ bool RenderLayer::hasNonEmptyChildRenderers() const
// <img src=...>
// </div>
// so test for 0x0 RenderTexts here
- for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
if (!child->hasLayer()) {
if (child->isRenderInline() || !child->isBox())
return true;
@@ -3860,114 +3686,12 @@ bool RenderLayer::isVisuallyNonEmpty() const
return false;
}
-void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle)
-{
- if (!oldStyle || (oldStyle->visibility() != renderer()->style()->visibility()))
- compositor()->setNeedsUpdateCompositingRequirementsState();
-}
-
-void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle)
-{
- if (oldStyle && (renderer()->style()->position() == oldStyle->position()))
- return;
-
- bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsolutePosition || oldStyle->position() == FixedPosition);
- bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned();
- if (!wasOutOfFlowPositioned && !isOutOfFlowPositioned)
- return;
-
- // Even if the layer remains out-of-flow, a change to this property
- // will likely change its containing block. We must clear these bits
- // so that they can be set properly by the RenderLayerCompositor.
- for (RenderLayer* ancestor = parent(); ancestor; ancestor = ancestor->parent())
- ancestor->setHasUnclippedDescendant(false);
-
- // Ensures that we reset the above bits correctly.
- compositor()->setNeedsUpdateCompositingRequirementsState();
-
- if (wasOutOfFlowPositioned && isOutOfFlowPositioned)
- return;
-
- if (isOutOfFlowPositioned) {
- setAncestorChainHasOutOfFlowPositionedDescendant();
- compositor()->addOutOfFlowPositionedLayer(this);
- } else {
- dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
- compositor()->removeOutOfFlowPositionedLayer(this);
-
- // We need to reset the isUnclippedDescendant bit here because normally
- // the "unclipped-ness" property is only updated in
- // RenderLayerCompositor::updateCompositingRequirementsState(). However,
- // it is only updated for layers which are known to be out of flow.
- // Since this is no longer out of flow, we have to explicitly ensure
- // that it doesn't think it is unclipped.
- setIsUnclippedDescendant(false);
- }
-}
-
static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
{
ASSERT(newStyle);
return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter();
}
-inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
-{
- ASSERT(newStyle);
- return oldStyle && (oldStyle->clip() != newStyle->clip() || oldStyle->hasClip() != newStyle->hasClip());
-}
-
-inline bool RenderLayer::needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
-{
- ASSERT(newStyle);
- return !hasCompositedLayerMapping() && oldStyle && (oldStyle->overflowX() != newStyle->overflowX()) && m_stackingNode->ancestorStackingContainerNode()->layer()->hasCompositingDescendant();
-}
-
-inline bool RenderLayer::needsCompositingLayersRebuiltForFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle, bool didPaintWithFilters) const
-{
- if (!hasOrHadFilters(oldStyle, newStyle))
- return false;
-
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()
- ? hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyWebkitFilter)
- : renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitFilter)) {
-
- // When the compositor is performing the filter animation, we shouldn't touch the compositing layers.
- // All of the layers above us should have been promoted to compositing layers already.
- return false;
- }
-
- FilterOutsets newOutsets = newStyle->filterOutsets();
- if (oldStyle && (oldStyle->filterOutsets() != newOutsets)) {
- // When filter outsets change, we need to:
- // (1) Recompute the overlap map to promote the correct layers to composited layers.
- // (2) Update the composited layer bounds (and child GraphicsLayer positions) on platforms
- // whose compositors can't compute their own filter outsets.
- return true;
- }
-
-#if HAVE(COMPOSITOR_FILTER_OUTSETS)
- if ((didPaintWithFilters != paintsWithFilters()) && !newOutsets.isZero()) {
- // When the layer used to paint filters in software and now paints filters in the
- // compositor, the compositing layer bounds need to change from including filter outsets to
- // excluding filter outsets, on platforms whose compositors compute their own outsets.
- // Similarly for the reverse change from compositor-painted to software-painted filters.
- return true;
- }
-#endif
-
- return false;
-}
-
-inline bool RenderLayer::needsCompositingLayersRebuiltForBlending(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
-{
- ASSERT(newStyle);
- if (!hasCompositedLayerMapping())
- return false;
- return (shouldIsolateCompositedDescendants() && !stackingNode()->isStackingContext())
- || (oldStyle && (oldStyle->hasBlendMode() != newStyle->hasBlendMode()));
-}
-
void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
{
if (!hasOrHadFilters(oldStyle, newStyle))
@@ -3976,59 +3700,50 @@ void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle*
updateOrRemoveFilterClients();
// During an accelerated animation, both WebKit and the compositor animate properties.
// However, WebKit shouldn't ask the compositor to update its filters if the compositor is performing the animation.
- if (hasCompositedLayerMapping() && (RuntimeEnabledFeatures::webAnimationsCSSEnabled()
- ? !hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyWebkitFilter)
- : !renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitFilter)))
+ if (hasCompositedLayerMapping() && !newStyle->isRunningFilterAnimationOnCompositor())
compositedLayerMapping()->updateFilters(renderer()->style());
updateOrRemoveFilterEffectRenderer();
}
-void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
+void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
{
m_stackingNode->updateIsNormalFlowOnly();
+ m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle);
if (m_scrollableArea)
m_scrollableArea->updateAfterStyleChange(oldStyle);
- m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle);
- updateVisibilityAfterStyleChange(oldStyle);
+
// Overlay scrollbars can make this layer self-painting so we need
// to recompute the bit once scrollbars have been updated.
updateSelfPaintingLayer();
- updateOutOfFlowPositioned(oldStyle);
- updateReflectionInfo(oldStyle);
+ if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) {
+ ASSERT(!oldStyle || diff.needsFullLayout());
+ updateReflectionInfo(oldStyle);
+ }
if (RuntimeEnabledFeatures::cssCompositingEnabled())
- updateBlendMode();
+ m_blendInfo.updateBlendMode();
updateDescendantDependentFlags();
- updateTransform();
-
- bool didPaintWithFilters = false;
-
- if (paintsWithFilters())
- didPaintWithFilters = true;
- updateFilters(oldStyle, renderer()->style());
-
- const RenderStyle* newStyle = renderer()->style();
- if (compositor()->updateLayerCompositingState(this)
- || needsCompositingLayersRebuiltForClip(oldStyle, newStyle)
- || needsCompositingLayersRebuiltForOverflow(oldStyle, newStyle)
- || needsCompositingLayersRebuiltForFilters(oldStyle, newStyle, didPaintWithFilters)
- || needsCompositingLayersRebuiltForBlending(oldStyle, newStyle)) {
- compositor()->setCompositingLayersNeedRebuild();
- } else if (compositingState() == PaintsIntoOwnBacking || compositingState() == HasOwnBackingButPaintsIntoAncestor) {
- ASSERT(hasCompositedLayerMapping());
- compositedLayerMapping()->updateGraphicsLayerGeometry();
- } else if (compositingState() == PaintsIntoGroupedBacking) {
- ASSERT(compositor()->layerSquashingEnabled());
- ASSERT(groupedMapping());
- // updateGraphicsLayerGeometry() is called to update the squashingLayer in case its size/position has changed.
- // FIXME: Make sure to create a layout test that covers this scenario.
- // FIXME: It is not expected that any other layers on the compositedLayerMapping would change. we should
- // be able to just update the squashing layer only and save a lot of computation.
- groupedMapping()->updateGraphicsLayerGeometry();
+
+ updateTransform(oldStyle, renderer()->style());
+
+ {
+ // https://code.google.com/p/chromium/issues/detail?id=343759
+ DisableCompositingQueryAsserts disabler;
+ updateFilters(oldStyle, renderer()->style());
}
+
+ compositor()->updateStyleDeterminedCompositingReasons(this);
+
+ setNeedsCompositingInputsUpdate();
+
+ // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
+ // https://code.google.com/p/chromium/issues/detail?id=343756
+ DisableCompositingQueryAsserts disabler;
+
+ compositor()->updateLayerCompositingState(this, RenderLayerCompositor::UseChickenEggHacks);
}
bool RenderLayer::scrollsOverflow() const
@@ -4039,13 +3754,6 @@ bool RenderLayer::scrollsOverflow() const
return false;
}
-bool RenderLayer::isCSSCustomFilterEnabled() const
-{
- // We only want to enable shaders if WebGL is also enabled on this platform.
- const Settings* settings = renderer()->document().settings();
- return settings && RuntimeEnabledFeatures::cssCustomFilterEnabled() && settings->webGLEnabled();
-}
-
FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style)
{
const FilterOperations& filters = style->filter();
@@ -4057,48 +3765,19 @@ FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style)
ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
// FIXME: Cache the ReferenceFilter if it didn't change.
RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create();
+#ifdef BLINK_SCALE_FILTERS_AT_RECORD_TIME
float zoom = style->effectiveZoom() * WebCore::deviceScaleFactor(renderer()->frame());
- referenceFilter->setFilterResolution(FloatSize(zoom, zoom));
+#else
+ float zoom = style->effectiveZoom();
+#endif
+ referenceFilter->setAbsoluteTransform(AffineTransform().scale(zoom, zoom));
referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(),
referenceOperation));
referenceOperation->setFilter(referenceFilter.release());
}
}
- if (!filters.hasCustomFilter())
- return filters;
-
- if (!isCSSCustomFilterEnabled()) {
- // CSS Custom filters should not parse at all in this case, but there might be
- // remaining styles that were parsed when the flag was enabled. Reproduces in DumpRenderTree
- // because it resets the flag while the previous test is still loaded.
- return FilterOperations();
- }
-
- FilterOperations outputFilters;
- for (size_t i = 0; i < filters.size(); ++i) {
- RefPtr<FilterOperation> filterOperation = filters.operations().at(i);
- if (filterOperation->type() == FilterOperation::CUSTOM) {
- // We have to wait until the program of CSS Shaders is loaded before setting it on the layer.
- // Note that we will handle the loading of the shaders and repainting of the layer in updateOrRemoveFilterClients.
- const CustomFilterOperation* customOperation = toCustomFilterOperation(filterOperation.get());
- RefPtr<CustomFilterProgram> program = customOperation->program();
- if (!program->isLoaded())
- continue;
-
- CustomFilterGlobalContext* globalContext = renderer()->view()->customFilterGlobalContext();
- RefPtr<CustomFilterValidatedProgram> validatedProgram = globalContext->getValidatedProgram(program->programInfo());
- if (!validatedProgram->isInitialized())
- continue;
-
- RefPtr<ValidatedCustomFilterOperation> validatedOperation = ValidatedCustomFilterOperation::create(validatedProgram.release(),
- customOperation->parameters(), customOperation->meshRows(), customOperation->meshColumns(), customOperation->meshType());
- outputFilters.operations().append(validatedOperation.release());
- continue;
- }
- outputFilters.operations().append(filterOperation.release());
- }
- return outputFilters;
+ return filters;
}
void RenderLayer::updateOrRemoveFilterClients()
@@ -4108,11 +3787,6 @@ void RenderLayer::updateOrRemoveFilterClients()
return;
}
- if (renderer()->style()->filter().hasCustomFilter())
- ensureFilterInfo()->updateCustomFilterClients(renderer()->style()->filter());
- else if (hasFilterInfo())
- filterInfo()->removeCustomFilterClients();
-
if (renderer()->style()->filter().hasReferenceFilter())
ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->filter());
else if (hasFilterInfo())
@@ -4128,7 +3802,7 @@ void RenderLayer::updateOrRemoveFilterEffectRenderer()
// Don't delete the whole filter info here, because we might use it
// for loading CSS shader files.
if (RenderLayerFilterInfo* filterInfo = this->filterInfo())
- filterInfo->setRenderer(0);
+ filterInfo->setRenderer(nullptr);
return;
}
@@ -4136,7 +3810,6 @@ void RenderLayer::updateOrRemoveFilterEffectRenderer()
RenderLayerFilterInfo* filterInfo = ensureFilterInfo();
if (!filterInfo->renderer()) {
RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
- filterRenderer->setIsAccelerated(renderer()->frame()->settings()->acceleratedFiltersEnabled());
filterInfo->setRenderer(filterRenderer.release());
// We can optimize away code paths in other places if we know that there are no software filters.
@@ -4146,43 +3819,71 @@ void RenderLayer::updateOrRemoveFilterEffectRenderer()
// If the filter fails to build, remove it from the layer. It will still attempt to
// go through regular processing (e.g. compositing), but never apply anything.
if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style())))
- filterInfo->setRenderer(0);
+ filterInfo->setRenderer(nullptr);
}
void RenderLayer::filterNeedsRepaint()
{
- toElement(renderer()->node())->scheduleLayerUpdate();
- if (renderer()->view())
- renderer()->repaint();
+ {
+ DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().lifecycle());
+ // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style recalc, which
+ // is a problem because this function can be called while performing layout.
+ // Presumably this represents an illegal data flow of layout or compositing
+ // information into the style system.
+ toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack();
+ }
+
+ if (renderer()->view()) {
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && renderer()->frameView()->isInPerformLayout())
+ renderer()->setShouldDoFullPaintInvalidationAfterLayout(true);
+ else
+ renderer()->paintInvalidationForWholeRenderer();
+ }
}
void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const
{
+ computeSelfHitTestRects(rects);
+ for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+ child->addLayerHitTestRects(rects);
+}
+
+void RenderLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const
+{
if (!size().isEmpty()) {
Vector<LayoutRect> rect;
if (renderBox() && renderBox()->scrollsOverflow()) {
// For scrolling layers, rects are taken to be in the space of the contents.
- // We need to include both the entire contents, and also the bounding box
- // of the layer in the space of it's parent (eg. for border / scroll bars).
- rect.append(m_scrollableArea->overflowRect());
+ // We need to include the bounding box of the layer in the space of its parent
+ // (eg. for border / scroll bars) and if it's composited then the entire contents
+ // as well as they may be on another composited layer. Skip reporting contents
+ // for non-composited layers as they'll get projected to the same layer as the
+ // bounding box.
+ if (compositingState() != NotComposited)
+ rect.append(m_scrollableArea->overflowRect());
+
rects.set(this, rect);
if (const RenderLayer* parentLayer = parent()) {
LayerHitTestRects::iterator iter = rects.find(parentLayer);
- if (iter == rects.end())
- iter = rects.add(parentLayer, Vector<LayoutRect>()).iterator;
- iter->value.append(boundingBox(parentLayer));
+ if (iter == rects.end()) {
+ rects.add(parentLayer, Vector<LayoutRect>()).storedValue->value.append(physicalBoundingBox(parentLayer));
+ } else {
+ iter->value.append(physicalBoundingBox(parentLayer));
+ }
}
} else {
- rect.append(localBoundingBox());
+ rect.append(logicalBoundingBox());
rects.set(this, rect);
}
}
-
- for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
- child->addLayerHitTestRects(rects);
}
+DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
+ : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { }
+
+COMPILE_ASSERT(1 << RenderLayer::ViewportConstrainedNotCompositedReasonBits >= RenderLayer::NumNotCompositedReasons, too_many_viewport_constrained_not_compositing_reasons);
+
} // namespace WebCore
#ifndef NDEBUG
@@ -4191,7 +3892,7 @@ void showLayerTree(const WebCore::RenderLayer* layer)
if (!layer)
return;
- if (WebCore::Frame* frame = layer->renderer()->frame()) {
+ if (WebCore::LocalFrame* frame = layer->renderer()->frame()) {
WTF::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass | WebCore::RenderAsTextDontUpdateLayout | WebCore::RenderAsTextShowLayoutState);
fprintf(stderr, "%s\n", output.utf8().data());
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayer.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayer.h
index 06dd644f8b7..6e43a0b7fe5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayer.h
@@ -45,11 +45,10 @@
#ifndef RenderLayer_h
#define RenderLayer_h
-#include "core/rendering/CompositedLayerMappingPtr.h"
-#include "core/rendering/CompositingReasons.h"
+#include "core/rendering/compositing/CompositedLayerMappingPtr.h"
#include "core/rendering/LayerPaintingInfo.h"
-#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderBox.h"
+#include "core/rendering/RenderLayerBlendInfo.h"
#include "core/rendering/RenderLayerClipper.h"
#include "core/rendering/RenderLayerFilterInfo.h"
#include "core/rendering/RenderLayerReflectionInfo.h"
@@ -57,6 +56,7 @@
#include "core/rendering/RenderLayerScrollableArea.h"
#include "core/rendering/RenderLayerStackingNode.h"
#include "core/rendering/RenderLayerStackingNodeIterator.h"
+#include "platform/graphics/CompositingReasons.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
@@ -66,29 +66,32 @@ class FilterOperations;
class HitTestRequest;
class HitTestResult;
class HitTestingTransformState;
-class PlatformEvent;
-class RenderFlowThread;
-class RenderGeometryMap;
class CompositedLayerMapping;
class RenderLayerCompositor;
-class RenderReplica;
-class RenderScrollbarPart;
class RenderStyle;
-class RenderView;
-class Scrollbar;
class TransformationMatrix;
enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius };
+enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf };
-class RenderLayer {
+enum CompositingQueryMode {
+ CompositingQueriesAreAllowed,
+ CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases
+};
+
+// FIXME: remove this once the compositing query ASSERTS are no longer hit.
+class DisableCompositingQueryAsserts {
+ WTF_MAKE_NONCOPYABLE(DisableCompositingQueryAsserts);
public:
- friend class RenderReplica;
- // FIXME: Needed until we move all the necessary bits to the new class.
- friend class RenderLayerStackingNode;
- // FIXME: Needed until we move all the necessary bits to the new class.
- friend class RenderLayerScrollableArea;
+ DisableCompositingQueryAsserts();
+private:
+ TemporaryChange<CompositingQueryMode> m_disabler;
+};
- RenderLayer(RenderLayerModelObject*);
+class RenderLayer {
+ WTF_MAKE_NONCOPYABLE(RenderLayer);
+public:
+ RenderLayer(RenderLayerModelObject*, LayerType);
~RenderLayer();
String debugName() const;
@@ -101,6 +104,8 @@ public:
RenderLayer* firstChild() const { return m_first; }
RenderLayer* lastChild() const { return m_last; }
+ const RenderLayer* compositingContainer() const;
+
void addChild(RenderLayer* newChild, RenderLayer* beforeChild = 0);
RenderLayer* removeChild(RenderLayer*);
@@ -111,11 +116,13 @@ public:
bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
+ void setLayerType(LayerType layerType) { m_layerType = layerType; }
+
bool cannotBlitToWindow() const;
- bool isTransparent() const;
+ bool isTransparent() const { return renderer()->isTransparent() || renderer()->hasMask(); }
RenderLayer* transparentPaintingAncestor();
- void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior);
+ void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior);
bool isReflection() const { return renderer()->isReplica(); }
RenderLayerReflectionInfo* reflectionInfo() { return m_reflectionInfo.get(); }
@@ -145,35 +152,34 @@ public:
// Allows updates of layer content without repainting.
void contentChanged(ContentChangeType);
- bool canRender3DTransforms() const;
-
enum UpdateLayerPositionsFlag {
CheckForRepaint = 1 << 0,
NeedsFullRepaintInBacking = 1 << 1,
- IsCompositingUpdateRoot = 1 << 2,
- UpdateCompositingLayers = 1 << 3,
- UpdatePagination = 1 << 4
+ UpdatePagination = 1 << 2,
+ ForceMayNeedPaintInvalidation = 1 << 3,
};
typedef unsigned UpdateLayerPositionsFlags;
- static const UpdateLayerPositionsFlags defaultFlags = CheckForRepaint | IsCompositingUpdateRoot | UpdateCompositingLayers;
void updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags);
-
void updateLayerPositionsAfterOverflowScroll();
void updateLayerPositionsAfterDocumentScroll();
+ // FIXME: Should updateLayerPositions be private?
+ void updateLayerPositionRecursive(UpdateLayerPositionsFlags = CheckForRepaint);
+
bool isPaginated() const { return m_isPaginated; }
RenderLayer* enclosingPaginationLayer() const { return m_enclosingPaginationLayer; }
- void updateTransform();
-
- void updateBlendMode();
+ void updateTransformationMatrix();
+ RenderLayer* renderingContextRoot();
const LayoutSize& offsetForInFlowPosition() const { return m_offsetForInFlowPosition; }
+ void blockSelectionGapsBoundsChanged();
void addBlockSelectionGapsBounds(const LayoutRect&);
void clearBlockSelectionGapsBounds();
void repaintBlockSelectionGaps();
+ IntRect blockSelectionGapsBounds() const;
bool hasBlockSelectionGapBounds() const;
RenderLayerStackingNode* stackingNode() { return m_stackingNode.get(); }
@@ -200,46 +206,30 @@ public:
// Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates.
bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; }
- // FIXME: We should ASSERT(!m_hasOutOfFlowPositionedDescendantDirty) here. See above.
- bool hasOutOfFlowPositionedDescendant() const { return m_hasOutOfFlowPositionedDescendant; }
-
- void setHasOutOfFlowPositionedDescendant(bool hasDescendant) { m_hasOutOfFlowPositionedDescendant = hasDescendant; }
- void setHasOutOfFlowPositionedDescendantDirty(bool dirty) { m_hasOutOfFlowPositionedDescendantDirty = dirty; }
-
- bool childLayerHasBlendMode() const { ASSERT(!m_childLayerHasBlendModeStatusDirty); return m_childLayerHasBlendMode; }
-
- bool hasUnclippedDescendant() const { return m_hasUnclippedDescendant; }
- void setHasUnclippedDescendant(bool hasDescendant) { m_hasUnclippedDescendant = hasDescendant; }
- void updateHasUnclippedDescendant();
- bool isUnclippedDescendant() const { return m_isUnclippedDescendant; }
-
+ // Will ensure that hasNonCompositiedChild are up to date.
+ void updateScrollingStateAfterCompositingChange();
bool hasVisibleNonLayerContent() const { return m_hasVisibleNonLayerContent; }
- void updateHasVisibleNonLayerContent();
+ bool hasNonCompositedChild() const { ASSERT(isAllowedToQueryCompositingState()); return m_hasNonCompositedChild; }
+
+ bool usedTransparency() const { return m_usedTransparency; }
// Gets the nearest enclosing positioned ancestor layer (also includes
// the <html> layer and the root layer).
RenderLayer* enclosingPositionedAncestor() const;
- // Returns the nearest enclosing layer that is scrollable.
- RenderLayer* enclosingScrollableLayer() const;
-
- // The layer relative to which clipping rects for this layer are computed.
- RenderLayer* clippingRootForPainting() const;
+ RenderLayer* enclosingOverflowClipLayer(IncludeSelfOrNot = IncludeSelf) const;
+ bool isRepaintContainer() const;
// Enclosing compositing layer; if includeSelf is true, may return this.
- RenderLayer* enclosingCompositingLayer(bool includeSelf = true) const;
- RenderLayer* enclosingCompositingLayerForRepaint(bool includeSelf = true) const;
+ RenderLayer* enclosingCompositingLayer(IncludeSelfOrNot = IncludeSelf) const;
+ RenderLayer* enclosingCompositingLayerForRepaint(IncludeSelfOrNot = IncludeSelf) const;
// Ancestor compositing layer, excluding this.
- RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(false); }
-
- // Ancestor composited scrolling layer at or above our containing block.
- RenderLayer* ancestorCompositedScrollingLayer() const;
+ RenderLayer* ancestorCompositingLayer() const { return enclosingCompositingLayer(ExcludeSelf); }
// Ancestor scrolling layer at or above our containing block.
RenderLayer* ancestorScrollingLayer() const;
- RenderLayer* enclosingFilterLayer(bool includeSelf = true) const;
- RenderLayer* enclosingFilterRepaintLayer() const;
+ RenderLayer* enclosingFilterLayer(IncludeSelfOrNot = IncludeSelf) const;
bool hasAncestorWithFilterOutsets() const;
bool canUseConvertToLayerCoords() const
@@ -248,8 +238,6 @@ public:
return !renderer()->hasColumns() && !renderer()->hasTransform() && !renderer()->isSVGRoot();
}
- void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& location) const;
- void convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect&) const;
void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutPoint& location) const;
void convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutRect&) const;
@@ -257,58 +245,31 @@ public:
// paints the layers that intersect the damage rect from back to
// front. The hitTest method looks for mouse events by walking
// layers that intersect the point from front to back.
- void paint(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior = PaintBehaviorNormal, RenderObject* paintingRoot = 0,
- RenderRegion* = 0, PaintLayerFlags = 0);
+ // paint() assumes that the caller will clip to the bounds of damageRect if necessary.
+ void paint(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior = PaintBehaviorNormal, RenderObject* paintingRoot = 0, PaintLayerFlags = 0);
bool hitTest(const HitTestRequest&, HitTestResult&);
bool hitTest(const HitTestRequest&, const HitTestLocation&, HitTestResult&);
void paintOverlayScrollbars(GraphicsContext*, const LayoutRect& damageRect, PaintBehavior, RenderObject* paintingRoot = 0);
- // This method figures out our layerBounds in coordinates relative to
- // |rootLayer}. It also computes our background and foreground clip rects
- // for painting/event handling.
- // Pass offsetFromRoot if known.
- void calculateRects(const ClipRectsContext&, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
- ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot = 0) const;
-
- LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
- LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space.
- LayoutRect localClipRect() const; // Returns the background clip rect of the layer in the local coordinate space.
-
// Pass offsetFromRoot if known.
bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot = 0) const;
- enum CalculateLayerBoundsFlag {
- IncludeSelfTransform = 1 << 0,
- UseLocalClipRectIfPossible = 1 << 1,
- IncludeLayerFilterOutsets = 1 << 2,
- ExcludeHiddenDescendants = 1 << 3,
- DontConstrainForMask = 1 << 4,
- IncludeCompositedDescendants = 1 << 5,
- UseFragmentBoxes = 1 << 6,
- PretendLayerHasOwnBacking = 1 << 7,
- DefaultCalculateLayerBoundsFlags = IncludeSelfTransform | UseLocalClipRectIfPossible | IncludeLayerFilterOutsets | UseFragmentBoxes
- };
- typedef unsigned CalculateLayerBoundsFlags;
-
// Bounding box relative to some ancestor layer. Pass offsetFromRoot if known.
- LayoutRect boundingBox(const RenderLayer* rootLayer, CalculateLayerBoundsFlags = 0, const LayoutPoint* offsetFromRoot = 0) const;
- // Bounding box in the coordinates of this layer.
- LayoutRect localBoundingBox(CalculateLayerBoundsFlags = 0) const;
- // Pixel snapped bounding box relative to the root.
- IntRect absoluteBoundingBox() const;
+ LayoutRect physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0) const;
+ LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const;
- // Bounds used for layer overlap testing in RenderLayerCompositor.
- LayoutRect overlapBounds() const { return overlapBoundsIncludeChildren() ? calculateLayerBounds(this) : localBoundingBox(); }
+ // FIXME: This function is inconsistent as to whether the returned rect has been flipped for writing mode.
+ LayoutRect boundingBoxForCompositingOverlapTest() const { return overlapBoundsIncludeChildren() ? boundingBoxForCompositing() : logicalBoundingBox(); }
// If true, this layer's children are included in its bounds for overlap testing.
// We can't rely on the children's positions if this layer has a filter that could have moved the children's pixels around.
bool overlapBoundsIncludeChildren() const { return hasFilter() && renderer()->style()->filter().hasFilterThatMovesPixels(); }
- // Can pass offsetFromRoot if known.
- IntRect calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot = 0, CalculateLayerBoundsFlags = DefaultCalculateLayerBoundsFlags) const;
-
- // WARNING: This method returns the offset for the parent as this is what updateLayerPositions expects.
- LayoutPoint computeOffsetFromRoot(bool& hasLayerOffset) const;
+ enum CalculateBoundsOptions {
+ ApplyBoundsChickenEggHacks,
+ DoNotApplyBoundsChickenEggHacks,
+ };
+ LayoutRect boundingBoxForCompositing(const RenderLayer* ancestorLayer = 0, CalculateBoundsOptions = DoNotApplyBoundsChickenEggHacks) const;
LayoutUnit staticInlinePosition() const { return m_staticInlinePosition; }
LayoutUnit staticBlockPosition() const { return m_staticBlockPosition; }
@@ -316,6 +277,9 @@ public:
void setStaticInlinePosition(LayoutUnit position) { m_staticInlinePosition = position; }
void setStaticBlockPosition(LayoutUnit position) { m_staticBlockPosition = position; }
+ LayoutSize subpixelAccumulation() const;
+ void setSubpixelAccumulation(const LayoutSize&);
+
bool hasTransform() const { return renderer()->hasTransform(); }
// Note that this transform has the transform-origin baked in.
TransformationMatrix* transform() const { return m_transform.get(); }
@@ -333,11 +297,13 @@ public:
bool preserves3D() const { return renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
+ // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
+ bool shouldPreserve3D() const { return !renderer()->hasReflection() && renderer()->style()->transformStyle3D() == TransformStyle3DPreserve3D; }
+
void filterNeedsRepaint();
bool hasFilter() const { return renderer()->hasFilter(); }
- bool hasBlendMode() const;
- bool paintsWithBlendMode() const { return hasBlendMode() && compositingState() != PaintsIntoOwnBacking; }
+ bool paintsWithBlendMode() const;
void* operator new(size_t);
// Only safe to call from RenderLayerModelObject::destroyLayer()
@@ -345,7 +311,11 @@ public:
CompositingState compositingState() const;
- CompositedLayerMappingPtr compositedLayerMapping() const { return m_compositedLayerMapping.get(); }
+ // This returns true if our document is in a phase of its lifestyle during which
+ // compositing state may legally be read.
+ bool isAllowedToQueryCompositingState() const;
+
+ CompositedLayerMappingPtr compositedLayerMapping() const;
CompositedLayerMappingPtr ensureCompositedLayerMapping();
// NOTE: If you are using hasCompositedLayerMapping to determine the state of compositing for this layer,
@@ -355,7 +325,7 @@ public:
void clearCompositedLayerMapping(bool layerBeingDestroyed = false);
CompositedLayerMapping* groupedMapping() const { return m_groupedMapping; }
- void setGroupedMapping(CompositedLayerMapping* groupedMapping) { m_groupedMapping = groupedMapping; }
+ void setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed = false);
bool hasCompositedMask() const;
bool hasCompositedClippingMask() const;
@@ -366,10 +336,16 @@ public:
RenderLayer* scrollParent() const;
RenderLayer* clipParent() const;
- bool needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const;
- bool needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const;
- bool needsCompositingLayersRebuiltForFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle, bool didPaintWithFilters) const;
- bool needsCompositingLayersRebuiltForBlending(const RenderStyle* oldStyle, const RenderStyle* newStyle) const;
+ // Computes the position of the given render object in the space of |repaintContainer|.
+ // FIXME: invert the logic to have repaint containers take care of painting objects into them, rather than the reverse.
+ // This will allow us to clean up this static method messiness.
+ static LayoutPoint positionFromPaintInvalidationContainer(const RenderObject*, const RenderLayerModelObject* repaintContainer);
+
+ // Adjusts the given rect (in the coordinate space of the RenderObject) to the coordinate space of |repaintContainer|'s GraphicsLayer backing.
+ static void mapRectToRepaintBacking(const RenderObject*, const RenderLayerModelObject* repaintContainer, LayoutRect&);
+
+ // Computes the bounding repaint rect for |renderObject|, in the coordinate space of |repaintContainer|'s GraphicsLayer backing.
+ static LayoutRect computeRepaintRect(const RenderObject*, const RenderLayer* repaintContainer);
bool paintsWithTransparency(PaintBehavior paintBehavior) const
{
@@ -385,8 +361,6 @@ public:
bool containsDirtyOverlayScrollbars() const { return m_containsDirtyOverlayScrollbars; }
void setContainsDirtyOverlayScrollbars(bool dirtyScrollbars) { m_containsDirtyOverlayScrollbars = dirtyScrollbars; }
- bool isCSSCustomFilterEnabled() const;
-
FilterOperations computeFilterOperations(const RenderStyle*);
bool paintsWithFilters() const;
bool requiresFullLayerImageForFilters() const;
@@ -412,29 +386,36 @@ public:
Node* enclosingElement() const;
bool isInTopLayer() const;
- bool isInTopLayerSubtree() const;
enum ViewportConstrainedNotCompositedReason {
- NoNotCompositedReason,
+ NoNotCompositedReason = 0,
NotCompositedForBoundsOutOfView,
NotCompositedForNonViewContainer,
NotCompositedForNoVisibleContent,
NotCompositedForUnscrollableAncestors,
- };
+ NumNotCompositedReasons,
- void setViewportConstrainedNotCompositedReason(ViewportConstrainedNotCompositedReason reason) { m_compositingProperties.viewportConstrainedNotCompositedReason = reason; }
- ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason() const { return static_cast<ViewportConstrainedNotCompositedReason>(m_compositingProperties.viewportConstrainedNotCompositedReason); }
+ // This is the number of bits used to store the viewport constrained not composited
+ // reasons. We define this constant since sizeof won't return the number of bits, and we
+ // shouldn't duplicate the constant.
+ ViewportConstrainedNotCompositedReasonBits = 3
+ };
- bool isOutOfFlowRenderFlowThread() const { return renderer()->isOutOfFlowRenderFlowThread(); }
+ void setViewportConstrainedNotCompositedReason(ViewportConstrainedNotCompositedReason reason) { m_viewportConstrainedNotCompositedReason = reason; }
+ ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason() const { ASSERT(isAllowedToQueryCompositingState()); return static_cast<ViewportConstrainedNotCompositedReason>(m_viewportConstrainedNotCompositedReason); }
bool scrollsWithRespectTo(const RenderLayer*) const;
void addLayerHitTestRects(LayerHitTestRects&) const;
+ // Compute rects only for this layer
+ void computeSelfHitTestRects(LayerHitTestRects&) const;
+
// FIXME: This should probably return a ScrollableArea but a lot of internal methods are mistakenly exposed.
RenderLayerScrollableArea* scrollableArea() const { return m_scrollableArea.get(); }
RenderLayerRepainter& repainter() { return m_repainter; }
RenderLayerClipper& clipper() { return m_clipper; }
+ const RenderLayerClipper& clipper() const { return m_clipper; }
inline bool isPositionedContainer() const
{
@@ -445,45 +426,87 @@ public:
return isRootLayer() || layerRenderer->isPositioned() || hasTransform();
}
+ // paintLayer() assumes that the caller will clip to the bounds of the painting dirty if necessary.
void paintLayer(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
PassOwnPtr<Vector<FloatRect> > collectTrackedRepaintRects() const;
- void setOffsetFromSquashingLayerOrigin(IntSize offset) { m_compositingProperties.offsetFromSquashingLayerOrigin = offset; }
- IntSize offsetFromSquashingLayerOrigin() const { return m_compositingProperties.offsetFromSquashingLayerOrigin; }
+ RenderLayerBlendInfo& blendInfo() { return m_blendInfo; }
-private:
- bool hasOverflowControls() const;
+ void setOffsetFromSquashingLayerOrigin(IntSize offset) { m_offsetFromSquashingLayerOrigin = offset; }
+ IntSize offsetFromSquashingLayerOrigin() const { ASSERT(isAllowedToQueryCompositingState()); return m_offsetFromSquashingLayerOrigin; }
- void setIsUnclippedDescendant(bool isUnclippedDescendant) { m_isUnclippedDescendant = isUnclippedDescendant; }
+ bool scrollsOverflow() const;
- void setAncestorChainHasSelfPaintingLayerDescendant();
- void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
+ CompositingReasons styleDeterminedCompositingReasons() const { return m_styleDeterminedCompositingReasons; }
+ void setStyleDeterminedCompositingReasons(CompositingReasons reasons) { ASSERT(reasons == (reasons & CompositingReasonComboAllStyleDeterminedReasons)); m_styleDeterminedCompositingReasons = reasons; }
- void setAncestorChainHasOutOfFlowPositionedDescendant();
- void dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
+ class CompositingInputs {
+ public:
+ CompositingInputs()
+ : opacityAncestor(0)
+ , transformAncestor(0)
+ , filterAncestor(0)
+ , isUnclippedDescendant(false)
+ { }
- bool acceleratedCompositingForOverflowScrollEnabled() const;
- // FIXME: This is a temporary flag and should be removed once accelerated
- // overflow scroll is ready (crbug.com/254111).
- bool compositorDrivenAcceleratedScrollingEnabled() const;
+ IntRect clippedAbsoluteBoundingBox;
+ const RenderLayer* opacityAncestor;
+ const RenderLayer* transformAncestor;
+ const RenderLayer* filterAncestor;
+ unsigned isUnclippedDescendant : 1;
+ };
- void clipToRect(RenderLayer* rootLayer, GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&,
- BorderRadiusClippingRule = IncludeSelfForBorderRadius);
- void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&);
+ void setNeedsCompositingInputsUpdate();
+ bool childNeedsCompositingInputsUpdate() const { return m_childNeedsCompositingInputsUpdate; }
+ bool needsCompositingInputsUpdate() const { return m_needsCompositingInputsUpdate; }
+
+ void updateCompositingInputs(const CompositingInputs&);
+ void clearChildNeedsCompositingInputsUpdate();
+
+ const CompositingInputs& compositingInputs() const { ASSERT(!m_needsCompositingInputsUpdate); return m_compositingInputs; }
+
+ bool lostGroupedMapping() const { ASSERT(isAllowedToQueryCompositingState()); return m_lostGroupedMapping; }
+ void setLostGroupedMapping(bool b) { m_lostGroupedMapping = b; }
+
+ CompositingReasons compositingReasons() const { ASSERT(isAllowedToQueryCompositingState()); return m_compositingReasons; }
+ void setCompositingReasons(CompositingReasons, CompositingReasons mask = CompositingReasonAll);
+
+ bool hasCompositingDescendant() const { ASSERT(isAllowedToQueryCompositingState()); return m_hasCompositingDescendant; }
+ void setHasCompositingDescendant(bool);
+
+ bool shouldIsolateCompositedDescendants() const { ASSERT(isAllowedToQueryCompositingState()); return m_shouldIsolateCompositedDescendants; }
+ void setShouldIsolateCompositedDescendants(bool);
+
+ void updateDescendantDependentFlags();
+
+ void updateOrRemoveFilterEffectRenderer();
void updateSelfPaintingLayer();
- void updateVisibilityAfterStyleChange(const RenderStyle* oldStyle);
- void updateOutOfFlowPositioned(const RenderStyle* oldStyle);
+ // paintLayerContents() assumes that the caller will clip to the bounds of the painting dirty rect if necessary.
+ void paintLayerContents(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
+
+ RenderLayer* enclosingTransformedAncestor() const;
+ LayoutPoint computeOffsetFromTransformedAncestor() const;
void didUpdateNeedsCompositedScrolling();
+private:
+ // Bounding box in the coordinates of this layer.
+ LayoutRect logicalBoundingBox() const;
+
+ bool hasOverflowControls() const;
+
+ void setAncestorChainHasSelfPaintingLayerDescendant();
+ void dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
+
+ void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, PaintLayerFlags, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
+ void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&);
+
// Returns true if the position changed.
bool updateLayerPosition();
- void updateLayerPositions(RenderGeometryMap* = 0, UpdateLayerPositionsFlags = defaultFlags);
-
enum UpdateLayerPositionsAfterScrollFlag {
NoFlag = 0,
IsOverflowScroll = 1 << 0,
@@ -492,11 +515,10 @@ private:
HasChangedAncestor = 1 << 3
};
typedef unsigned UpdateLayerPositionsAfterScrollFlags;
- void updateLayerPositionsAfterScroll(RenderGeometryMap*, UpdateLayerPositionsAfterScrollFlags = NoFlag);
+ void updateLayerPositionsAfterScroll(UpdateLayerPositionsAfterScrollFlags = NoFlag);
void setNextSibling(RenderLayer* next) { m_next = next; }
void setPreviousSibling(RenderLayer* prev) { m_previous = prev; }
- void setParent(RenderLayer* parent);
void setFirstChild(RenderLayer* first) { m_first = first; }
void setLastChild(RenderLayer* last) { m_last = last; }
@@ -504,25 +526,30 @@ private:
void paintLayerContentsAndReflection(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
void paintLayerByApplyingTransform(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const LayoutPoint& translationOffset = LayoutPoint());
- void paintLayerContents(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
+
+ // Returns whether this layer should be painted during sofware painting (i.e., not via calls from CompositedLayerMapping to draw into composited
+ // layers).
+ bool shouldPaintLayerInSoftwareMode(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags paintFlags);
+
void paintChildren(unsigned childrenToVisit, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
void paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
void paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags, const Vector<RenderLayer*>& columnLayers, size_t columnIndex);
- void collectFragments(LayerFragments&, const RenderLayer* rootLayer, RenderRegion*, const LayoutRect& dirtyRect,
+ void collectFragments(LayerFragments&, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
ClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize,
- ShouldRespectOverflowClip = RespectOverflowClip, const LayoutPoint* offsetFromRoot = 0, const LayoutRect* layerBoundingBox = 0);
+ ShouldRespectOverflowClip = RespectOverflowClip, const LayoutPoint* offsetFromRoot = 0,
+ const LayoutSize& subPixelAccumulation = LayoutSize(), const LayoutRect* layerBoundingBox = 0);
void updatePaintingInfoForFragments(LayerFragments&, const LayerPaintingInfo&, PaintLayerFlags, bool shouldPaintContent, const LayoutPoint* offsetFromRoot);
void paintBackgroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext,
- const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer);
+ const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags);
void paintForegroundForFragments(const LayerFragments&, GraphicsContext*, GraphicsContext* transparencyLayerContext,
const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer,
- bool selectionOnly, bool forceBlackText);
- void paintForegroundForFragmentsWithPhase(PaintPhase, const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer);
- void paintOutlineForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer);
- void paintOverflowControlsForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&);
- void paintMaskForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer);
- void paintChildClippingMaskForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer);
+ bool selectionOnly, bool forceBlackText, PaintLayerFlags);
+ void paintForegroundForFragmentsWithPhase(PaintPhase, const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags);
+ void paintOutlineForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags);
+ void paintOverflowControlsForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
+ void paintMaskForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer, PaintLayerFlags);
+ void paintChildClippingMaskForFragments(const LayerFragments&, GraphicsContext*, const LayerPaintingInfo&, RenderObject* paintingRootForRenderer, PaintLayerFlags);
void paintTransformedLayerIntoFragments(GraphicsContext*, const LayerPaintingInfo&, PaintLayerFlags);
RenderLayer* hitTestLayer(RenderLayer* rootLayer, RenderLayer* containerLayer, const HitTestRequest& request, HitTestResult& result,
@@ -557,7 +584,6 @@ private:
bool shouldBeSelfPaintingLayer() const;
-private:
// FIXME: We should only create the stacking node if needed.
bool requiresStackingNode() const { return true; }
void updateStackingNode();
@@ -569,58 +595,29 @@ private:
bool requiresScrollableArea() const { return renderBox(); }
void updateScrollableArea();
- // Returns true our scrollable area is in the FrameView's collection of scrollable areas. This can
- // only happen if we're both scrollable, and we do in fact overflow.
- bool scrollsOverflow() const;
-
void dirtyAncestorChainVisibleDescendantStatus();
void setAncestorChainHasVisibleDescendant();
- void dirtyAncestorChainBlendedDescendantStatus();
- void setAncestorChainBlendedDescendant();
-
- void updateDescendantDependentFlags();
-
- // This flag is computed by RenderLayerCompositor, which knows more about 3d hierarchies than we do.
- void setHas3DTransformedDescendant(bool b) { m_has3DTransformedDescendant = b; }
- bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
+ void updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle);
void dirty3DTransformedDescendantStatus();
// Both updates the status, and returns true if descendants of this have 3d.
bool update3DTransformedDescendantStatus();
void updateOrRemoveFilterClients();
- void updateOrRemoveFilterEffectRenderer();
-
- void parentClipRects(const ClipRectsContext&, ClipRects&) const;
- ClipRect backgroundClipRect(const ClipRectsContext&) const;
- LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior);
-
- RenderLayer* enclosingTransformedAncestor() const;
+ LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior);
void updatePagination();
// FIXME: Temporary. Remove when new columns come online.
bool useRegionBasedColumns() const;
- bool hasCompositingDescendant() const { return m_compositingProperties.hasCompositingDescendant; }
- void setHasCompositingDescendant(bool b) { m_compositingProperties.hasCompositingDescendant = b; }
-
- bool hasNonCompositedChild() const { return m_compositingProperties.hasNonCompositedChild; }
- void setHasNonCompositedChild(bool b) { m_compositingProperties.hasNonCompositedChild = b; }
-
- bool shouldIsolateCompositedDescendants() const { return m_compositingProperties.shouldIsolateCompositedDescendants; }
- void setShouldIsolateCompositedDescendants(bool b) { m_compositingProperties.shouldIsolateCompositedDescendants = b; }
-
- void setCompositingReasons(CompositingReasons reasons) { m_compositingProperties.compositingReasons = reasons; }
- CompositingReasons compositingReasons() const { return m_compositingProperties.compositingReasons; }
+ LayerType m_layerType;
- friend class CompositedLayerMapping;
- friend class RenderLayerCompositor;
- friend class RenderLayerModelObject;
-
-protected:
+ // Self-painting layer is an optimization where we avoid the heavy RenderLayer painting
+ // machinery for a RenderLayer allocated only to handle the overflow clip case.
+ // FIXME(crbug.com/332791): Self-painting layer should be merged into the overflow-only concept.
unsigned m_isSelfPaintingLayer : 1;
// If have no self-painting descendants, we don't have to walk our children during painting. This can lead to
@@ -628,26 +625,12 @@ protected:
unsigned m_hasSelfPaintingLayerDescendant : 1;
unsigned m_hasSelfPaintingLayerDescendantDirty : 1;
- unsigned m_hasOutOfFlowPositionedDescendant : 1;
- unsigned m_hasOutOfFlowPositionedDescendantDirty : 1;
-
- // This is true if we have an out-of-flow positioned descendant whose
- // containing block is our ancestor. If this is the case, the descendant
- // may fall outside of our clip preventing things like opting into
- // composited scrolling (which causes clipping of all descendants).
- unsigned m_hasUnclippedDescendant : 1;
-
- unsigned m_isUnclippedDescendant : 1;
-
const unsigned m_isRootLayer : 1;
unsigned m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether
// we ended up painting this layer or any descendants (and therefore need to
// blend).
- unsigned m_childLayerHasBlendMode : 1;
- unsigned m_childLayerHasBlendModeStatusDirty : 1;
-
unsigned m_visibleContentStatusDirty : 1;
unsigned m_hasVisibleContent : 1;
unsigned m_visibleDescendantStatusDirty : 1;
@@ -670,8 +653,25 @@ protected:
const unsigned m_canSkipRepaintRectsUpdateOnScroll : 1;
unsigned m_hasFilterInfo : 1;
+ unsigned m_needsCompositingInputsUpdate : 1;
+ unsigned m_childNeedsCompositingInputsUpdate : 1;
+
+ // Used only while determining what layers should be composited. Applies to the tree of z-order lists.
+ unsigned m_hasCompositingDescendant : 1;
- blink::WebBlendMode m_blendMode;
+ // Applies to the real render layer tree (i.e., the tree determined by the layer's parent and children and
+ // as opposed to the tree formed by the z-order and normal flow lists).
+ unsigned m_hasNonCompositedChild : 1;
+
+ // Should be for stacking contexts having unisolated blending descendants.
+ unsigned m_shouldIsolateCompositedDescendants : 1;
+
+ // True if this render layer just lost its grouped mapping due to the CompositedLayerMapping being destroyed,
+ // and we don't yet know to what graphics layer this RenderLayer will be assigned.
+ unsigned m_lostGroupedMapping : 1;
+
+ // The reason, if any exists, that a fixed-position layer is chosen not to be composited.
+ unsigned m_viewportConstrainedNotCompositedReason : ViewportConstrainedNotCompositedReasonBits;
RenderLayerModelObject* m_renderer;
@@ -699,46 +699,17 @@ protected:
// Pointer to the enclosing RenderLayer that caused us to be paginated. It is 0 if we are not paginated.
RenderLayer* m_enclosingPaginationLayer;
- // Properties that are computed while updating compositing layers. These values may be dirty/invalid if
- // compositing status is not up-to-date before using them.
- struct CompositingProperties {
- CompositingProperties()
- : hasCompositingDescendant(false)
- , hasNonCompositedChild(false)
- , shouldIsolateCompositedDescendants(false)
- , viewportConstrainedNotCompositedReason(NoNotCompositedReason)
- , compositingReasons(CompositingReasonNone)
- { }
+ // These compositing reasons are updated whenever style changes, not while updating compositing layers.
+ // They should not be used to infer the compositing state of this layer.
+ CompositingReasons m_styleDeterminedCompositingReasons;
- // Used only while determining what layers should be composited. Applies to the tree of z-order lists.
- bool hasCompositingDescendant : 1;
+ // Once computed, indicates all that a layer needs to become composited using the CompositingReasons enum bitfield.
+ CompositingReasons m_compositingReasons;
- // Applies to the real render layer tree (i.e., the tree determined by the layer's parent and children and
- // as opposed to the tree formed by the z-order and normal flow lists).
- bool hasNonCompositedChild : 1;
+ // Used for invalidating this layer's contents on the squashing GraphicsLayer.
+ IntSize m_offsetFromSquashingLayerOrigin;
- // Should be for stacking contexts having unisolated blending descendants.
- bool shouldIsolateCompositedDescendants : 1;
-
- // The reason, if any exists, that a fixed-position layer is chosen not to be composited.
- unsigned viewportConstrainedNotCompositedReason : 2;
-
- // Once computed, indicates all that a layer needs to become composited using the CompositingReasons enum bitfield.
- CompositingReasons compositingReasons;
-
- // Used for invalidating this layer's contents on the squashing GraphicsLayer.
- IntSize offsetFromSquashingLayerOrigin;
- };
-
- CompositingProperties m_compositingProperties;
-
-private:
- enum CompositedScrollingHistogramBuckets {
- IsScrollableAreaBucket = 0,
- NeedsToBeStackingContainerBucket = 1,
- WillUseCompositedScrollingBucket = 2,
- CompositedScrollingHistogramMax = 3
- };
+ CompositingInputs m_compositingInputs;
IntRect m_blockSelectionGapsBounds;
@@ -751,6 +722,9 @@ private:
RenderLayerClipper m_clipper; // FIXME: Lazily allocate?
OwnPtr<RenderLayerStackingNode> m_stackingNode;
OwnPtr<RenderLayerReflectionInfo> m_reflectionInfo;
+ RenderLayerBlendInfo m_blendInfo;
+
+ LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of a composited layer's composited bounds compared to absolute coordinates.
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp
new file mode 100644
index 00000000000..d8158b4cc40
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ *
+ * Portions are Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * Other contributors:
+ * Robert O'Callahan <roc+@cs.cmu.edu>
+ * David Baron <dbaron@fas.harvard.edu>
+ * Christian Biesinger <cbiesinger@web.de>
+ * Randall Jesup <rjesup@wgate.com>
+ * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
+ * Josh Soref <timeless@mac.com>
+ * Boris Zbarsky <bzbarsky@mit.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "config.h"
+#include "core/rendering/RenderLayerBlendInfo.h"
+
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderLayerModelObject.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+
+namespace WebCore {
+
+RenderLayerBlendInfo::RenderLayerBlendInfo(RenderLayerModelObject& renderer)
+ : m_renderer(renderer)
+ , m_blendMode(blink::WebBlendModeNormal)
+ , m_childLayerHasBlendMode(false)
+ , m_childLayerHasBlendModeStatusDirty(false)
+{
+}
+
+bool RenderLayerBlendInfo::hasBlendMode() const
+{
+ return RuntimeEnabledFeatures::cssCompositingEnabled() && m_renderer.hasBlendMode();
+}
+
+void RenderLayerBlendInfo::updateBlendMode()
+{
+ if (!RuntimeEnabledFeatures::cssCompositingEnabled())
+ return;
+
+ blink::WebBlendMode newBlendMode = m_renderer.style()->blendMode();
+ if (newBlendMode == m_blendMode)
+ return;
+
+ bool hadBlendMode = m_blendMode != blink::WebBlendModeNormal;
+ m_blendMode = newBlendMode;
+
+ RenderLayer* layer = m_renderer.layer();
+ // Only update the flag if a blend mode is set or unset.
+ if (layer->parent() && (!hadBlendMode || !hasBlendMode()))
+ layer->parent()->blendInfo().dirtyAncestorChainBlendedDescendantStatus();
+
+ if (layer->hasCompositedLayerMapping())
+ layer->compositedLayerMapping()->setBlendMode(newBlendMode);
+}
+
+void RenderLayerBlendInfo::dirtyAncestorChainBlendedDescendantStatus()
+{
+ for (RenderLayer* layer = m_renderer.layer(); layer; layer = layer->parent()) {
+ if (layer->blendInfo().childLayerHasBlendModeStatusDirty())
+ break;
+
+ layer->blendInfo().setChildLayerHasBlendModeStatusDirty(true);
+
+ if (layer->stackingNode()->isStackingContext())
+ break;
+ }
+}
+
+void RenderLayerBlendInfo::setAncestorChainBlendedDescendant()
+{
+ for (RenderLayer* layer = m_renderer.layer(); layer; layer = layer->parent()) {
+ if (!layer->blendInfo().childLayerHasBlendModeStatusDirty() && layer->blendInfo().childLayerHasBlendMode())
+ break;
+
+ layer->blendInfo().setChildLayerHasBlendMode(true);
+ layer->blendInfo().setChildLayerHasBlendModeStatusDirty(false);
+
+ if (layer->stackingNode()->isStackingContext())
+ break;
+ }
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.h
new file mode 100644
index 00000000000..6800baa6eef
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2013 Intel Corporation. All rights reserved.
+ *
+ * Portions are Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * Other contributors:
+ * Robert O'Callahan <roc+@cs.cmu.edu>
+ * David Baron <dbaron@fas.harvard.edu>
+ * Christian Biesinger <cbiesinger@web.de>
+ * Randall Jesup <rjesup@wgate.com>
+ * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
+ * Josh Soref <timeless@mac.com>
+ * Boris Zbarsky <bzbarsky@mit.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#ifndef RenderLayerBlendInfo_h
+#define RenderLayerBlendInfo_h
+
+#include "public/platform/WebBlendMode.h"
+#include "wtf/Assertions.h"
+#include "wtf/Noncopyable.h"
+
+namespace WebCore {
+
+class RenderLayerModelObject;
+
+class RenderLayerBlendInfo {
+ WTF_MAKE_NONCOPYABLE(RenderLayerBlendInfo);
+public:
+ explicit RenderLayerBlendInfo(RenderLayerModelObject&);
+
+ bool hasBlendMode() const;
+ void updateBlendMode();
+
+ bool childLayerHasBlendMode() const
+ {
+ ASSERT(!m_childLayerHasBlendModeStatusDirty);
+ return m_childLayerHasBlendMode;
+ }
+ bool childLayerHasBlendModeWhileDirty() const { return m_childLayerHasBlendMode; }
+
+ void setChildLayerHasBlendMode(bool b) { m_childLayerHasBlendMode = b; }
+
+ bool childLayerHasBlendModeStatusDirty() const { return m_childLayerHasBlendModeStatusDirty; }
+ void setChildLayerHasBlendModeStatusDirty(bool b) { m_childLayerHasBlendModeStatusDirty = b; }
+
+ void setAncestorChainBlendedDescendant();
+ void dirtyAncestorChainBlendedDescendantStatus();
+
+ blink::WebBlendMode blendMode() const { return m_blendMode; }
+
+private:
+ RenderLayerModelObject& m_renderer;
+ blink::WebBlendMode m_blendMode;
+
+ unsigned m_childLayerHasBlendMode : 1;
+ unsigned m_childLayerHasBlendModeStatusDirty : 1;
+};
+
+} // namespace WebCore
+
+#endif // RenderLayerBlendInfo_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp
index f14aa06ee27..786a17f7440 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp
@@ -53,9 +53,12 @@ void RenderLayerClipper::updateClipRects(const ClipRectsContext& clipRectsContex
{
ClipRectsType clipRectsType = clipRectsContext.clipRectsType;
ASSERT(clipRectsType < NumCachedClipRectsTypes);
- if (m_clipRectsCache && m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip)) {
- // FIXME: these asserts trigger for squashing. Need to update this code to support squashing as appropriate.
- ASSERT(clipRectsContext.rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]);
+ if (m_clipRectsCache
+ && clipRectsContext.rootLayer == m_clipRectsCache->clipRectsRoot(clipRectsType)
+ && m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip)) {
+ // FIXME: We used to ASSERT that we always got a consistent root layer.
+ // We should add a test that has an inconsistent root. See
+ // http://crbug.com/366118 for an example.
ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy);
#ifdef CHECK_CACHED_CLIP_RECTS
@@ -71,7 +74,7 @@ void RenderLayerClipper::updateClipRects(const ClipRectsContext& clipRectsContex
// For transformed layers, the root layer was shifted to be us, so there is no need to
// examine the parent. We want to cache clip rects with us as the root.
- RenderLayer* parentLayer = clipRectsContext.rootLayer != m_renderer->layer() ? m_renderer->layer()->parent() : 0;
+ RenderLayer* parentLayer = !isClippingRootForContext(clipRectsContext) ? m_renderer.layer()->parent() : 0;
if (parentLayer)
parentLayer->clipper().updateClipRects(clipRectsContext);
@@ -82,12 +85,11 @@ void RenderLayerClipper::updateClipRects(const ClipRectsContext& clipRectsContex
m_clipRectsCache = adoptPtr(new ClipRectsCache);
if (parentLayer && parentLayer->clipper().clipRects(clipRectsContext) && clipRects == *parentLayer->clipper().clipRects(clipRectsContext))
- m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, parentLayer->clipper().clipRects(clipRectsContext));
+ m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, parentLayer->clipper().clipRects(clipRectsContext), clipRectsContext.rootLayer);
else
- m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, ClipRects::create(clipRects));
+ m_clipRectsCache->setClipRects(clipRectsType, clipRectsContext.respectOverflowClip, ClipRects::create(clipRects), clipRectsContext.rootLayer);
#ifndef NDEBUG
- m_clipRectsCache->m_clipRectsRoot[clipRectsType] = clipRectsContext.rootLayer;
m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] = clipRectsContext.overlayScrollbarSizeRelevancy;
#endif
}
@@ -100,7 +102,7 @@ void RenderLayerClipper::clearClipRectsIncludingDescendants(ClipRectsType typeTo
clearClipRects(typeToClear);
- for (RenderLayer* layer = m_renderer->layer()->firstChild(); layer; layer = layer->nextSibling())
+ for (RenderLayer* layer = m_renderer.layer()->firstChild(); layer; layer = layer->nextSibling())
layer->clipper().clearClipRectsIncludingDescendants(typeToClear);
}
@@ -108,17 +110,118 @@ void RenderLayerClipper::clearClipRects(ClipRectsType typeToClear)
{
if (typeToClear == AllClipRectTypes) {
m_clipRectsCache = nullptr;
+ m_compositingClipRectsDirty = false;
} else {
+ if (typeToClear == CompositingClipRects)
+ m_compositingClipRectsDirty = false;
+
ASSERT(typeToClear < NumCachedClipRectsTypes);
RefPtr<ClipRects> dummy;
- m_clipRectsCache->setClipRects(typeToClear, RespectOverflowClip, dummy);
- m_clipRectsCache->setClipRects(typeToClear, IgnoreOverflowClip, dummy);
+ m_clipRectsCache->setClipRects(typeToClear, RespectOverflowClip, dummy, 0);
+ m_clipRectsCache->setClipRects(typeToClear, IgnoreOverflowClip, dummy, 0);
+ }
+}
+
+LayoutRect RenderLayerClipper::childrenClipRect() const
+{
+ // FIXME: border-radius not accounted for.
+ // FIXME: Regions not accounted for.
+ RenderView* renderView = m_renderer.view();
+ RenderLayer* clippingRootLayer = clippingRootForPainting();
+ LayoutRect layerBounds;
+ ClipRect backgroundRect, foregroundRect, outlineRect;
+ ClipRectsContext clipRectsContext(clippingRootLayer, TemporaryClipRects);
+ // Need to use temporary clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>).
+ calculateRects(clipRectsContext, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
+ return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
+}
+
+LayoutRect RenderLayerClipper::localClipRect() const
+{
+ // FIXME: border-radius not accounted for.
+ RenderLayer* clippingRootLayer = clippingRootForPainting();
+ LayoutRect layerBounds;
+ ClipRect backgroundRect, foregroundRect, outlineRect;
+ ClipRectsContext clipRectsContext(clippingRootLayer, PaintingClipRects);
+ calculateRects(clipRectsContext, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
+
+ LayoutRect clipRect = backgroundRect.rect();
+ if (clipRect == PaintInfo::infiniteRect())
+ return clipRect;
+
+ LayoutPoint clippingRootOffset;
+ m_renderer.layer()->convertToLayerCoords(clippingRootLayer, clippingRootOffset);
+ clipRect.moveBy(-clippingRootOffset);
+
+ return clipRect;
+}
+
+void RenderLayerClipper::calculateRects(const ClipRectsContext& clipRectsContext, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
+ ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot) const
+{
+ bool isClippingRoot = isClippingRootForContext(clipRectsContext);
+
+ if (!isClippingRoot && m_renderer.layer()->parent()) {
+ backgroundRect = backgroundClipRect(clipRectsContext);
+ backgroundRect.move(roundedIntSize(clipRectsContext.subPixelAccumulation));
+ backgroundRect.intersect(paintDirtyRect);
+ } else {
+ backgroundRect = paintDirtyRect;
+ }
+
+ foregroundRect = backgroundRect;
+ outlineRect = backgroundRect;
+
+ LayoutPoint offset;
+ if (offsetFromRoot)
+ offset = *offsetFromRoot;
+ else
+ m_renderer.layer()->convertToLayerCoords(clipRectsContext.rootLayer, offset);
+ layerBounds = LayoutRect(offset, m_renderer.layer()->size());
+
+ // Update the clip rects that will be passed to child layers.
+ if (m_renderer.hasOverflowClip()) {
+ // This layer establishes a clip of some kind.
+ if (!isClippingRoot || clipRectsContext.respectOverflowClip == RespectOverflowClip) {
+ foregroundRect.intersect(toRenderBox(m_renderer).overflowClipRect(offset, clipRectsContext.overlayScrollbarSizeRelevancy));
+ if (m_renderer.style()->hasBorderRadius())
+ foregroundRect.setHasRadius(true);
+ }
+
+ // If we establish an overflow clip at all, then go ahead and make sure our background
+ // rect is intersected with our layer's bounds including our visual overflow,
+ // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden.
+ if (toRenderBox(m_renderer).hasVisualOverflow()) {
+ // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though
+ // we may need to inflate our clip specifically for shadows or outsets.
+ // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the
+ // individual region boxes as overflow.
+ LayoutRect layerBoundsWithVisualOverflow = toRenderBox(m_renderer).visualOverflowRect();
+ toRenderBox(m_renderer).flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped.
+ layerBoundsWithVisualOverflow.moveBy(offset);
+ if (!isClippingRoot || clipRectsContext.respectOverflowClip == RespectOverflowClip)
+ backgroundRect.intersect(layerBoundsWithVisualOverflow);
+ } else {
+ LayoutRect bounds = toRenderBox(m_renderer).borderBoxRect();
+ bounds.moveBy(offset);
+ if (!isClippingRoot || clipRectsContext.respectOverflowClip == RespectOverflowClip)
+ backgroundRect.intersect(bounds);
+ }
+ }
+
+ // CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box.
+ if (m_renderer.hasClip()) {
+ // Clip applies to *us* as well, so go ahead and update the damageRect.
+ LayoutRect newPosClip = toRenderBox(m_renderer).clipRect(offset);
+ backgroundRect.intersect(newPosClip);
+ foregroundRect.intersect(newPosClip);
+ outlineRect.intersect(newPosClip);
}
}
void RenderLayerClipper::calculateClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const
{
- if (!m_renderer->layer()->parent()) {
+ if (!m_renderer.layer()->parent()) {
// The root layer's clip rect is always infinite.
clipRects.reset(PaintInfo::infiniteRect());
return;
@@ -127,9 +230,11 @@ void RenderLayerClipper::calculateClipRects(const ClipRectsContext& clipRectsCon
ClipRectsType clipRectsType = clipRectsContext.clipRectsType;
bool useCached = clipRectsType != TemporaryClipRects;
+ bool isClippingRoot = isClippingRootForContext(clipRectsContext);
+
// For transformed layers, the root layer was shifted to be us, so there is no need to
// examine the parent. We want to cache clip rects with us as the root.
- RenderLayer* parentLayer = clipRectsContext.rootLayer != m_renderer->layer() ? m_renderer->layer()->parent() : 0;
+ RenderLayer* parentLayer = !isClippingRoot ? m_renderer.layer()->parent() : 0;
// Ensure that our parent's clip has been calculated so that we can examine the values.
if (parentLayer) {
@@ -146,41 +251,41 @@ void RenderLayerClipper::calculateClipRects(const ClipRectsContext& clipRectsCon
// A fixed object is essentially the root of its containing block hierarchy, so when
// we encounter such an object, we reset our clip rects to the fixedClipRect.
- if (m_renderer->style()->position() == FixedPosition) {
+ if (m_renderer.style()->position() == FixedPosition) {
clipRects.setPosClipRect(clipRects.fixedClipRect());
clipRects.setOverflowClipRect(clipRects.fixedClipRect());
clipRects.setFixed(true);
- } else if (m_renderer->style()->hasInFlowPosition()) {
+ } else if (m_renderer.style()->hasInFlowPosition()) {
clipRects.setPosClipRect(clipRects.overflowClipRect());
- } else if (m_renderer->style()->position() == AbsolutePosition) {
+ } else if (m_renderer.style()->position() == AbsolutePosition) {
clipRects.setOverflowClipRect(clipRects.posClipRect());
}
// Update the clip rects that will be passed to child layers.
- if ((m_renderer->hasOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || m_renderer->layer() != clipRectsContext.rootLayer)) || m_renderer->hasClip()) {
+ if ((m_renderer.hasOverflowClip() && (clipRectsContext.respectOverflowClip == RespectOverflowClip || !isClippingRoot)) || m_renderer.hasClip()) {
// This layer establishes a clip of some kind.
// This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across
// some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where
// clipRects are needed in view space.
LayoutPoint offset;
- offset = roundedLayoutPoint(m_renderer->localToContainerPoint(FloatPoint(), clipRectsContext.rootLayer->renderer()));
- RenderView* view = m_renderer->view();
+ offset = roundedLayoutPoint(m_renderer.localToContainerPoint(FloatPoint(), clipRectsContext.rootLayer->renderer()));
+ RenderView* view = m_renderer.view();
ASSERT(view);
if (view && clipRects.fixed() && clipRectsContext.rootLayer->renderer() == view) {
offset -= view->frameView()->scrollOffsetForFixedPosition();
}
- if (m_renderer->hasOverflowClip()) {
- ClipRect newOverflowClip = toRenderBox(m_renderer)->overflowClipRect(offset, clipRectsContext.region, clipRectsContext.overlayScrollbarSizeRelevancy);
- if (m_renderer->style()->hasBorderRadius())
+ if (m_renderer.hasOverflowClip()) {
+ ClipRect newOverflowClip = toRenderBox(m_renderer).overflowClipRect(offset, clipRectsContext.overlayScrollbarSizeRelevancy);
+ if (m_renderer.style()->hasBorderRadius())
newOverflowClip.setHasRadius(true);
clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
- if (m_renderer->isPositioned())
+ if (m_renderer.isPositioned())
clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
}
- if (m_renderer->hasClip()) {
- LayoutRect newPosClip = toRenderBox(m_renderer)->clipRect(offset, clipRectsContext.region);
+ if (m_renderer.hasClip()) {
+ LayoutRect newPosClip = toRenderBox(m_renderer).clipRect(offset);
clipRects.setPosClipRect(intersection(newPosClip, clipRects.posClipRect()));
clipRects.setOverflowClipRect(intersection(newPosClip, clipRects.overflowClipRect()));
clipRects.setFixedClipRect(intersection(newPosClip, clipRects.fixedClipRect()));
@@ -188,4 +293,95 @@ void RenderLayerClipper::calculateClipRects(const ClipRectsContext& clipRectsCon
}
}
+static inline ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position)
+{
+ if (position == FixedPosition)
+ return parentRects.fixedClipRect();
+
+ if (position == AbsolutePosition)
+ return parentRects.posClipRect();
+
+ return parentRects.overflowClipRect();
+}
+
+void RenderLayerClipper::setCompositingClipRectsDirty()
+{
+ m_compositingClipRectsDirty = true;
+}
+
+ClipRect RenderLayerClipper::backgroundClipRect(const ClipRectsContext& clipRectsContext) const
+{
+ ASSERT(m_renderer.layer()->parent());
+
+ if (clipRectsContext.clipRectsType == CompositingClipRects)
+ const_cast<RenderLayerClipper*>(this)->clearClipRectsIncludingDescendants(CompositingClipRects);
+
+ ClipRects parentRects;
+
+ // If we cross into a different pagination context, then we can't rely on the cache.
+ // Just switch over to using TemporaryClipRects.
+ if (clipRectsContext.clipRectsType != TemporaryClipRects && m_renderer.layer()->parent()->enclosingPaginationLayer() != m_renderer.layer()->enclosingPaginationLayer()) {
+ ClipRectsContext tempContext(clipRectsContext);
+ tempContext.clipRectsType = TemporaryClipRects;
+ parentClipRects(tempContext, parentRects);
+ } else {
+ parentClipRects(clipRectsContext, parentRects);
+ }
+
+ ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, m_renderer.style()->position());
+ RenderView* view = m_renderer.view();
+ ASSERT(view);
+
+ // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
+ if (parentRects.fixed() && clipRectsContext.rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect())
+ backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition());
+
+ return backgroundClipRect;
+}
+
+bool RenderLayerClipper::isClippingRootForContext(const ClipRectsContext& clipRectsContext) const
+{
+ return clipRectsContext.rootLayer == m_renderer.layer();
+}
+
+void RenderLayerClipper::parentClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const
+{
+ // The root is not clipped.
+ if (isClippingRootForContext(clipRectsContext)) {
+ clipRects.reset(PaintInfo::infiniteRect());
+ return;
+ }
+
+ ASSERT(m_renderer.layer()->parent());
+
+ RenderLayerClipper& parentClipper = m_renderer.layer()->parent()->clipper();
+ if (clipRectsContext.clipRectsType == TemporaryClipRects) {
+ parentClipper.calculateClipRects(clipRectsContext, clipRects);
+ return;
+ }
+
+ parentClipper.updateClipRects(clipRectsContext);
+ clipRects = *parentClipper.clipRects(clipRectsContext);
+}
+
+RenderLayer* RenderLayerClipper::clippingRootForPainting() const
+{
+ if (m_renderer.hasCompositedLayerMapping() || m_renderer.groupedMapping())
+ return const_cast<RenderLayer*>(m_renderer.layer());
+
+ const RenderLayer* current = m_renderer.layer();
+ while (current) {
+ if (current->isRootLayer())
+ return const_cast<RenderLayer*>(current);
+
+ current = current->compositingContainer();
+ ASSERT(current);
+ if (current->transform() || (current->compositingState() == PaintsIntoOwnBacking) || current->groupedMapping())
+ return const_cast<RenderLayer*>(current);
+ }
+
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.h
index 03a3ef1a603..362097929ff 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerClipper.h
@@ -51,28 +51,28 @@
namespace WebCore {
class RenderLayer;
-class RenderRegion;
struct ClipRectsContext {
- ClipRectsContext(const RenderLayer* inRootLayer, RenderRegion* inRegion, ClipRectsType inClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, ShouldRespectOverflowClip inRespectOverflowClip = RespectOverflowClip)
+ ClipRectsContext(const RenderLayer* inRootLayer, ClipRectsType inClipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, ShouldRespectOverflowClip inRespectOverflowClip = RespectOverflowClip, const LayoutSize& inSubPixelAccumulation = LayoutSize())
: rootLayer(inRootLayer)
- , region(inRegion)
, clipRectsType(inClipRectsType)
, overlayScrollbarSizeRelevancy(inOverlayScrollbarSizeRelevancy)
, respectOverflowClip(inRespectOverflowClip)
+ , subPixelAccumulation(inSubPixelAccumulation)
{ }
const RenderLayer* rootLayer;
- RenderRegion* region;
ClipRectsType clipRectsType;
OverlayScrollbarSizeRelevancy overlayScrollbarSizeRelevancy;
ShouldRespectOverflowClip respectOverflowClip;
+ LayoutSize subPixelAccumulation;
};
-class RenderLayerClipper {
+class RenderLayerClipper FINAL {
WTF_MAKE_NONCOPYABLE(RenderLayerClipper);
public:
- RenderLayerClipper(RenderLayerModelObject* renderer)
- : m_renderer(renderer)
+ explicit RenderLayerClipper(RenderLayerModelObject& renderer)
+ : m_renderer(renderer)
+ , m_compositingClipRectsDirty(false)
{
}
@@ -88,15 +88,38 @@ public:
void clearClipRectsIncludingDescendants(ClipRectsType typeToClear = AllClipRectTypes);
void clearClipRects(ClipRectsType typeToClear = AllClipRectTypes);
+ void setCompositingClipRectsDirty();
+
+ LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
+ LayoutRect localClipRect() const; // Returns the background clip rect of the layer in the local coordinate space.
+
+ ClipRect backgroundClipRect(const ClipRectsContext&) const;
+
+ // FIXME: The following functions should be private.
+
+ // This method figures out our layerBounds in coordinates relative to
+ // |rootLayer}. It also computes our background and foreground clip rects
+ // for painting/event handling.
+ // Pass offsetFromRoot if known.
+ void calculateRects(const ClipRectsContext&, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
+ ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot = 0) const;
+
// Compute and return the clip rects. If useCached is true, will used previously computed clip rects on ancestors
// (rather than computing them all from scratch up the parent chain).
void calculateClipRects(const ClipRectsContext&, ClipRects&) const;
private:
- // FIXME: Could this be a RenderBox?
- RenderLayerModelObject* m_renderer;
+ void parentClipRects(const ClipRectsContext&, ClipRects&) const;
+
+ // The layer relative to which clipping rects for this layer are computed.
+ RenderLayer* clippingRootForPainting() const;
+ bool isClippingRootForContext(const ClipRectsContext&) const;
+
+ // FIXME: Could this be a RenderBox?
+ RenderLayerModelObject& m_renderer;
OwnPtr<ClipRectsCache> m_clipRectsCache;
+ unsigned m_compositingClipRectsDirty : 1;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp
deleted file mode 100644
index 45565a55007..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp
+++ /dev/null
@@ -1,2605 +0,0 @@
-/*
- * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/rendering/RenderLayerCompositor.h"
-
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "core/animation/ActiveAnimations.h"
-#include "core/animation/DocumentAnimations.h"
-#include "core/dom/FullscreenElementStack.h"
-#include "core/dom/NodeList.h"
-#include "core/html/HTMLCanvasElement.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/page/Chrome.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
-#include "core/frame/animation/AnimationController.h"
-#include "core/page/scrolling/ScrollingConstraints.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/CompositedLayerMapping.h"
-#include "core/rendering/HitTestResult.h"
-#include "core/rendering/RenderApplet.h"
-#include "core/rendering/RenderEmbeddedObject.h"
-#include "core/rendering/RenderFullScreen.h"
-#include "core/rendering/RenderGeometryMap.h"
-#include "core/rendering/RenderIFrame.h"
-#include "core/rendering/RenderLayerStackingNode.h"
-#include "core/rendering/RenderLayerStackingNodeIterator.h"
-#include "core/rendering/RenderReplica.h"
-#include "core/rendering/RenderVideo.h"
-#include "core/rendering/RenderView.h"
-#include "platform/OverscrollTheme.h"
-#include "platform/TraceEvent.h"
-#include "platform/geometry/TransformState.h"
-#include "platform/graphics/GraphicsLayer.h"
-#include "platform/scroll/ScrollbarTheme.h"
-#include "public/platform/Platform.h"
-#include "wtf/TemporaryChange.h"
-
-#ifndef NDEBUG
-#include "core/rendering/RenderTreeAsText.h"
-#endif
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-class OverlapMapContainer {
-public:
- void add(const IntRect& bounds)
- {
- m_layerRects.append(bounds);
- m_boundingBox.unite(bounds);
- }
-
- bool overlapsLayers(const IntRect& bounds) const
- {
- // Checking with the bounding box will quickly reject cases when
- // layers are created for lists of items going in one direction and
- // never overlap with each other.
- if (!bounds.intersects(m_boundingBox))
- return false;
- for (unsigned i = 0; i < m_layerRects.size(); i++) {
- if (m_layerRects[i].intersects(bounds))
- return true;
- }
- return false;
- }
-
- void unite(const OverlapMapContainer& otherContainer)
- {
- m_layerRects.append(otherContainer.m_layerRects);
- m_boundingBox.unite(otherContainer.m_boundingBox);
- }
-private:
- Vector<IntRect> m_layerRects;
- IntRect m_boundingBox;
-};
-
-class RenderLayerCompositor::OverlapMap {
- WTF_MAKE_NONCOPYABLE(OverlapMap);
-public:
- OverlapMap()
- : m_geometryMap(UseTransforms)
- {
- // Begin by assuming the root layer will be composited so that there
- // is something on the stack. The root layer should also never get a
- // finishCurrentOverlapTestingContext() call.
- beginNewOverlapTestingContext();
- }
-
- void add(const RenderLayer* layer, const IntRect& bounds)
- {
- // Layers do not contribute to overlap immediately--instead, they will
- // contribute to overlap as soon as they have been recursively processed
- // and popped off the stack.
- ASSERT(m_overlapStack.size() >= 2);
- m_overlapStack[m_overlapStack.size() - 2].add(bounds);
- m_layers.add(layer);
- }
-
- bool contains(const RenderLayer* layer)
- {
- return m_layers.contains(layer);
- }
-
- bool overlapsLayers(const IntRect& bounds) const
- {
- return m_overlapStack.last().overlapsLayers(bounds);
- }
-
- bool isEmpty()
- {
- return m_layers.isEmpty();
- }
-
- void beginNewOverlapTestingContext()
- {
- // This effectively creates a new "clean slate" for overlap state.
- // This is used when we know that a subtree or remaining set of
- // siblings does not need to check overlap with things behind it.
- m_overlapStack.append(OverlapMapContainer());
- }
-
- void finishCurrentOverlapTestingContext()
- {
- // The overlap information on the top of the stack is still necessary
- // for checking overlap of any layers outside this context that may
- // overlap things from inside this context. Therefore, we must merge
- // the information from the top of the stack before popping the stack.
- //
- // FIXME: we may be able to avoid this deep copy by rearranging how
- // overlapMap state is managed.
- m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
- m_overlapStack.removeLast();
- }
-
- RenderGeometryMap& geometryMap() { return m_geometryMap; }
-
-private:
- Vector<OverlapMapContainer> m_overlapStack;
- HashSet<const RenderLayer*> m_layers;
- RenderGeometryMap m_geometryMap;
-};
-
-struct CompositingRecursionData {
- CompositingRecursionData(RenderLayer* compAncestor, bool testOverlap)
- : m_compositingAncestor(compAncestor)
- , m_subtreeIsCompositing(false)
- , m_hasUnisolatedCompositedBlendingDescendant(false)
- , m_testingOverlap(testOverlap)
-#ifndef NDEBUG
- , m_depth(0)
-#endif
- {
- }
-
- CompositingRecursionData(const CompositingRecursionData& other)
- : m_compositingAncestor(other.m_compositingAncestor)
- , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
- , m_hasUnisolatedCompositedBlendingDescendant(other.m_hasUnisolatedCompositedBlendingDescendant)
- , m_testingOverlap(other.m_testingOverlap)
-#ifndef NDEBUG
- , m_depth(other.m_depth + 1)
-#endif
- {
- }
-
- RenderLayer* m_compositingAncestor;
- bool m_subtreeIsCompositing;
- bool m_hasUnisolatedCompositedBlendingDescendant;
- bool m_testingOverlap;
-#ifndef NDEBUG
- int m_depth;
-#endif
-};
-
-
-RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
- : m_renderView(renderView)
- , m_hasAcceleratedCompositing(true)
- , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
- , m_showRepaintCounter(false)
- , m_needsToRecomputeCompositingRequirements(false)
- , m_needsToUpdateLayerTreeGeometry(false)
- , m_compositing(false)
- , m_compositingLayersNeedRebuild(false)
- , m_forceCompositingMode(false)
- , m_inPostLayoutUpdate(false)
- , m_needsUpdateCompositingRequirementsState(false)
- , m_isTrackingRepaints(false)
- , m_rootLayerAttachment(RootLayerUnattached)
-{
-}
-
-RenderLayerCompositor::~RenderLayerCompositor()
-{
- ASSERT(m_rootLayerAttachment == RootLayerUnattached);
-}
-
-void RenderLayerCompositor::enableCompositingMode(bool enable /* = true */)
-{
- if (enable != m_compositing) {
- m_compositing = enable;
-
- if (m_compositing) {
- ensureRootLayer();
- notifyIFramesOfCompositingChange();
- } else
- destroyRootLayer();
- }
-}
-
-void RenderLayerCompositor::cacheAcceleratedCompositingFlags()
-{
- bool hasAcceleratedCompositing = false;
- bool showRepaintCounter = false;
- bool forceCompositingMode = false;
-
- if (Settings* settings = m_renderView->document().settings()) {
- hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
-
- // We allow the chrome to override the settings, in case the page is rendered
- // on a chrome that doesn't allow accelerated compositing.
- if (hasAcceleratedCompositing) {
- if (Page* page = this->page()) {
- m_compositingTriggers = page->chrome().client().allowedCompositingTriggers();
- hasAcceleratedCompositing = m_compositingTriggers;
- }
- }
-
- showRepaintCounter = settings->showRepaintCounter();
- forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing;
-
- if (forceCompositingMode && !isMainFrame())
- forceCompositingMode = requiresCompositingForScrollableFrame();
- }
-
- if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode)
- setCompositingLayersNeedRebuild();
-
- m_hasAcceleratedCompositing = hasAcceleratedCompositing;
- m_showRepaintCounter = showRepaintCounter;
- m_forceCompositingMode = forceCompositingMode;
-}
-
-bool RenderLayerCompositor::layerSquashingEnabled() const
-{
- if (Settings* settings = m_renderView->document().settings())
- return settings->layerSquashingEnabled();
-
- return false;
-}
-
-bool RenderLayerCompositor::canRender3DTransforms() const
-{
- return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
-}
-
-void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
-{
- // FIXME: crbug,com/332248 ideally this could be merged with setNeedsCompositingUpdate().
- if (inCompositingMode())
- m_compositingLayersNeedRebuild = needRebuild;
-
- m_renderView->frameView()->scheduleAnimation();
-}
-
-void RenderLayerCompositor::didChangeVisibleRect()
-{
- GraphicsLayer* rootLayer = rootGraphicsLayer();
- if (!rootLayer)
- return;
-
- FrameView* frameView = m_renderView ? m_renderView->frameView() : 0;
- if (!frameView)
- return;
-
- IntRect visibleRect = m_containerLayer ? IntRect(IntPoint(), frameView->contentsSize()) : frameView->visibleContentRect();
- if (rootLayer->visibleRectChangeRequiresFlush(visibleRect)) {
- if (Page* page = this->page())
- page->chrome().client().scheduleCompositingLayerFlush();
- }
-}
-
-void RenderLayerCompositor::updateCompositingRequirementsState()
-{
- if (!m_needsUpdateCompositingRequirementsState)
- return;
-
- TRACE_EVENT0("blink_rendering,comp-scroll", "RenderLayerCompositor::updateCompositingRequirementsState");
-
- m_needsUpdateCompositingRequirementsState = false;
-
- if (!rootRenderLayer() || !rootRenderLayer()->acceleratedCompositingForOverflowScrollEnabled())
- return;
-
- for (HashSet<RenderLayer*>::iterator it = m_outOfFlowPositionedLayers.begin(); it != m_outOfFlowPositionedLayers.end(); ++it)
- (*it)->updateHasUnclippedDescendant();
-
- const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas();
- if (!scrollableAreas)
- return;
-
- for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
- (*it)->updateNeedsCompositedScrolling();
-}
-
-static RenderVideo* findFullscreenVideoRenderer(Document* document)
-{
- Element* fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(document);
- while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
- document = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
- if (!document)
- return 0;
- fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(document);
- }
- if (!fullscreenElement || !isHTMLVideoElement(fullscreenElement))
- return 0;
- RenderObject* renderer = fullscreenElement->renderer();
- if (!renderer)
- return 0;
- return toRenderVideo(renderer);
-}
-
-void RenderLayerCompositor::finishCompositingUpdateForFrameTree(Frame* frame)
-{
- for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
- finishCompositingUpdateForFrameTree(child);
-
- // Update compositing for current frame after all descendant frames are updated.
- if (frame && frame->contentRenderer()) {
- RenderLayerCompositor* frameCompositor = frame->contentRenderer()->compositor();
- if (frameCompositor && !frameCompositor->isMainFrame())
- frame->contentRenderer()->compositor()->updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
- }
-}
-
-void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType)
-{
- // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
- if (m_renderView->needsLayout())
- return;
-
- if (updateType == CompositingUpdateFinishAllDeferredWork && isMainFrame() && m_renderView->frameView())
- finishCompositingUpdateForFrameTree(&m_renderView->frameView()->frame());
-
- if (m_forceCompositingMode && !m_compositing)
- enableCompositingMode(true);
-
- if (!m_needsToRecomputeCompositingRequirements && !m_compositing)
- return;
-
- AnimationUpdateBlock animationUpdateBlock(m_renderView->frameView()->frame().animation());
-
- TemporaryChange<bool> postLayoutChange(m_inPostLayoutUpdate, true);
-
- bool needCompositingRequirementsUpdate = false;
- bool needHierarchyAndGeometryUpdate = false;
- bool needGeometryUpdate = false;
- bool needsToUpdateScrollingCoordinator = false;
-
- // CompositingUpdateFinishAllDeferredWork is the only updateType that will actually do any work in this
- // function. All other updateTypes will simply mark that something needed updating, and defer the actual
- // update. This way we only need to compute all compositing state once for every frame drawn (if needed).
- switch (updateType) {
- case CompositingUpdateAfterStyleChange:
- case CompositingUpdateAfterLayout:
- m_needsToRecomputeCompositingRequirements = true;
- break;
- case CompositingUpdateOnScroll:
- m_needsToRecomputeCompositingRequirements = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
- m_needsToUpdateLayerTreeGeometry = true;
- break;
- case CompositingUpdateOnCompositedScroll:
- m_needsToUpdateLayerTreeGeometry = true;
- break;
- case CompositingUpdateFinishAllDeferredWork:
- needCompositingRequirementsUpdate = m_needsToRecomputeCompositingRequirements;
- needHierarchyAndGeometryUpdate = m_compositingLayersNeedRebuild;
- needGeometryUpdate = m_needsToUpdateLayerTreeGeometry;
- needsToUpdateScrollingCoordinator = scrollingCoordinator() ? scrollingCoordinator()->needsToUpdateAfterCompositingChange() : false;
- break;
- }
-
- if (!needCompositingRequirementsUpdate && !needHierarchyAndGeometryUpdate && !needGeometryUpdate && !needsToUpdateScrollingCoordinator)
- return;
-
- ASSERT(updateType == CompositingUpdateFinishAllDeferredWork);
-
- // Only clear the flags if we're updating the entire hierarchy.
- m_compositingLayersNeedRebuild = false;
- m_needsToUpdateLayerTreeGeometry = false;
- m_needsToRecomputeCompositingRequirements = false;
- RenderLayer* updateRoot = rootRenderLayer();
-
- if (needCompositingRequirementsUpdate) {
- // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
- // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
- CompositingRecursionData recursionData(updateRoot, true);
- bool layersChanged = false;
- bool saw3DTransform = false;
- {
- TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::computeCompositingRequirements");
- OverlapMap overlapTestRequestMap;
-
- // FIXME: Passing these unclippedDescendants down and keeping track
- // of them dynamically, we are requiring a full tree walk. This
- // should be removed as soon as proper overlap testing based on
- // scrolling and animation bounds is implemented (crbug.com/252472).
- Vector<RenderLayer*> unclippedDescendants;
- computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants);
- }
-
- {
- TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::assignLayersToBackings");
- assignLayersToBackings(updateRoot, layersChanged);
- }
-
- {
- TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateHasVisibleNonLayerContentLoop");
- const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas();
- if (scrollableAreas) {
- for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
- (*it)->updateHasVisibleNonLayerContent();
- }
- }
-
- needHierarchyAndGeometryUpdate |= layersChanged;
- }
-
- if (needHierarchyAndGeometryUpdate) {
- // Update the hierarchy of the compositing layers.
- Vector<GraphicsLayer*> childList;
- {
- TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::rebuildCompositingLayerTree");
- rebuildCompositingLayerTree(updateRoot, childList, 0);
- }
-
- // Host the document layer in the RenderView's root layer.
- if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isMainFrame()) {
- RenderVideo* video = findFullscreenVideoRenderer(&m_renderView->document());
- if (video && video->hasCompositedLayerMapping()) {
- childList.clear();
- childList.append(video->compositedLayerMapping()->mainGraphicsLayer());
- }
- }
-
- if (childList.isEmpty())
- destroyRootLayer();
- else
- m_rootContentLayer->setChildren(childList);
- } else if (needGeometryUpdate) {
- // We just need to do a geometry update. This is only used for position:fixed scrolling;
- // most of the time, geometry is updated via RenderLayer::styleChanged().
- updateLayerTreeGeometry(updateRoot);
- }
-
- ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
-
- if (!hasAcceleratedCompositing())
- enableCompositingMode(false);
-
- // The scrolling coordinator may realize that it needs updating while compositing was being updated in this function.
- needsToUpdateScrollingCoordinator |= scrollingCoordinator() ? scrollingCoordinator()->needsToUpdateAfterCompositingChange() : false;
- if (needsToUpdateScrollingCoordinator && isMainFrame() && scrollingCoordinator() && inCompositingMode())
- scrollingCoordinator()->updateAfterCompositingChange();
-
- // Inform the inspector that the layer tree has changed.
- if (isMainFrame())
- InspectorInstrumentation::layerTreeDidChange(page());
-}
-
-static bool requiresCompositing(CompositingReasons reasons)
-{
- // Any reasons other than overlap or assumed overlap will require the layer to be separately compositing.
- return reasons & ~CompositingReasonComboAllOverlapReasons;
-}
-
-static bool requiresSquashing(CompositingReasons reasons)
-{
- // If the layer has overlap or assumed overlap, but no other reasons, then it should be squashed.
- return !requiresCompositing(reasons) && (reasons & CompositingReasonComboAllOverlapReasons);
-}
-
-static bool requiresCompositingOrSquashing(CompositingReasons reasons)
-{
-#ifndef NDEBUG
- bool fastAnswer = reasons != CompositingReasonNone;
- bool slowAnswer = requiresCompositing(reasons) || requiresSquashing(reasons);
- ASSERT(fastAnswer == slowAnswer);
-#endif
- return reasons != CompositingReasonNone;
-}
-
-void RenderLayerCompositor::addOutOfFlowPositionedLayer(RenderLayer* layer)
-{
- m_outOfFlowPositionedLayers.add(layer);
-}
-
-void RenderLayerCompositor::removeOutOfFlowPositionedLayer(RenderLayer* layer)
-{
- m_outOfFlowPositionedLayers.remove(layer);
-}
-
-bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer)
-{
- bool compositedLayerMappingChanged = false;
- RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
- requiresCompositingForPosition(layer->renderer(), layer, &viewportConstrainedNotCompositedReason);
-
- // FIXME: It would be nice to directly use the layer's compositing reason,
- // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
- // requirements fully.
- if (needsOwnBacking(layer)) {
- enableCompositingMode();
-
- if (!layer->hasCompositedLayerMapping()) {
- // If we need to repaint, do so before allocating the compositedLayerMapping
- repaintOnCompositingChange(layer);
-
- layer->ensureCompositedLayerMapping();
- compositedLayerMappingChanged = true;
-
- // At this time, the ScrollingCooridnator only supports the top-level frame.
- if (layer->isRootLayer() && isMainFrame()) {
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
- }
-
- // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
- // that computing repaint rects will know the layer's correct compositingState.
- // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
- // Need to create a test where a squashed layer pops into compositing. And also to cover all other
- // sorts of compositingState transitions.
- layer->setGroupedMapping(0);
-
- // FIXME: it seems premature to compute this before all compositing state has been updated?
- // This layer and all of its descendants have cached repaints rects that are relative to
- // the repaint container, so change when compositing changes; we need to update them here.
- if (layer->parent())
- layer->repainter().computeRepaintRectsIncludingDescendants();
- }
-
- if (layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons())
- compositedLayerMappingChanged = true;
- } else {
- if (layer->hasCompositedLayerMapping()) {
- // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to
- // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
- // are both either composited, or not composited.
- if (layer->isReflection()) {
- RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
- if (sourceLayer->hasCompositedLayerMapping()) {
- ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
- sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0);
- }
- }
-
- removeViewportConstrainedLayer(layer);
-
- layer->clearCompositedLayerMapping();
- compositedLayerMappingChanged = true;
-
- // This layer and all of its descendants have cached repaints rects that are relative to
- // the repaint container, so change when compositing changes; we need to update them here.
- layer->repainter().computeRepaintRectsIncludingDescendants();
-
- // If we need to repaint, do so now that we've removed the compositedLayerMapping
- repaintOnCompositingChange(layer);
- }
- }
-
- if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) {
- RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
- if (innerCompositor && innerCompositor->inCompositingMode())
- innerCompositor->updateRootLayerAttachment();
- }
-
- if (compositedLayerMappingChanged)
- layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
-
- // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
- // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
- bool nonCompositedReasonChanged = false;
- if (layer->renderer()->style()->position() == FixedPosition) {
- if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
- layer->setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
- nonCompositedReasonChanged = true;
- }
- if (compositedLayerMappingChanged || nonCompositedReasonChanged) {
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView->frameView());
- }
- }
-
- return compositedLayerMappingChanged || nonCompositedReasonChanged;
-}
-
-bool RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer)
-{
- updateDirectCompositingReasons(layer);
- bool layerChanged = allocateOrClearCompositedLayerMapping(layer);
-
- if (layerSquashingEnabled()) {
- // FIXME: this is not correct... info may be out of date and squashing returning true doesn't indicate that the layer changed
- layerChanged = requiresSquashing(layer->compositingReasons());
- }
-
- // See if we need content or clipping layers. Methods called here should assume
- // that the compositing state of descendant layers has not been updated yet.
- if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateGraphicsLayerConfiguration())
- layerChanged = true;
-
- return layerChanged;
-}
-
-void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
-{
- // If the renderer is not attached yet, no need to repaint.
- if (layer->renderer() != m_renderView && !layer->renderer()->parent())
- return;
-
- RenderLayerModelObject* repaintContainer = layer->renderer()->containerForRepaint();
- if (!repaintContainer)
- repaintContainer = m_renderView;
-
- layer->repainter().repaintIncludingNonCompositingDescendants(repaintContainer);
-}
-
-// This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
-void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect)
-{
- RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(false /*exclude self*/);
- if (compositedAncestor) {
- // FIXME: make sure repaintRect is computed correctly for squashed scenario
- LayoutPoint offset;
- layer->convertToLayerCoords(compositedAncestor, offset);
-
- LayoutRect repaintRect = rect;
- repaintRect.moveBy(offset);
-
- if (compositedAncestor->compositingState() == PaintsIntoOwnBacking) {
- compositedAncestor->repainter().setBackingNeedsRepaintInRect(repaintRect);
- } else if (compositedAncestor->compositingState() == PaintsIntoGroupedBacking) {
- // FIXME: Need to perform the correct coordinate conversion for repaintRect here, including transforms
- compositedAncestor->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(repaintRect);
- } else {
- ASSERT_NOT_REACHED();
- }
- }
-}
-
-// The bounds of the GraphicsLayer created for a compositing layer is the union of the bounds of all the descendant
-// RenderLayers that are rendered by the composited RenderLayer.
-IntRect RenderLayerCompositor::calculateCompositedBounds(const RenderLayer* layer, const RenderLayer* ancestorLayer) const
-{
- if (!canBeComposited(layer))
- return IntRect();
-
- RenderLayer::CalculateLayerBoundsFlags flags = RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask;
-#if HAVE(COMPOSITOR_FILTER_OUTSETS)
- // If the compositor computes its own filter outsets, don't include them in the composited bounds.
- if (!layer->paintsWithFilters())
- flags &= ~RenderLayer::IncludeLayerFilterOutsets;
-#endif
- return layer->calculateLayerBounds(ancestorLayer, 0, flags);
-}
-
-void RenderLayerCompositor::layerWasAdded(RenderLayer* /*parent*/, RenderLayer* /*child*/)
-{
- setCompositingLayersNeedRebuild();
-}
-
-void RenderLayerCompositor::layerWillBeRemoved(RenderLayer* parent, RenderLayer* child)
-{
- if (!child->hasCompositedLayerMapping() || parent->renderer()->documentBeingDestroyed())
- return;
-
- removeViewportConstrainedLayer(child);
- repaintInCompositedAncestor(child, child->compositedLayerMapping()->compositedBounds());
-
- setCompositingParent(child, 0);
- setCompositingLayersNeedRebuild();
-}
-
-RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
-{
- for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
- if (curr->stackingNode()->isStackingContainer())
- return 0;
-
- if (curr->renderer()->hasClipOrOverflowClip())
- return curr;
- }
- return 0;
-}
-
-void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
-{
- if (layer->isRootLayer())
- return;
-
- if (!boundsComputed) {
- // FIXME: If this layer's overlap bounds include its children, we don't need to add its
- // children's bounds to the overlap map.
- layerBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer->overlapBounds()));
- // Empty rects never intersect, but we need them to for the purposes of overlap testing.
- if (layerBounds.isEmpty())
- layerBounds.setSize(IntSize(1, 1));
- boundsComputed = true;
- }
-
- IntRect clipRect = pixelSnappedIntRect(layer->backgroundClipRect(ClipRectsContext(rootRenderLayer(), 0, AbsoluteClipRects)).rect()); // FIXME: Incorrect for CSS regions.
- clipRect.intersect(layerBounds);
- overlapMap.add(layer, clipRect);
-}
-
-void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, RenderLayer* layer, RenderLayer* ancestorLayer)
-{
- if (!canBeComposited(layer) || overlapMap.contains(layer))
- return;
-
- // A null ancestorLayer is an indication that 'layer' has already been pushed.
- if (ancestorLayer)
- overlapMap.geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
-
- IntRect bounds;
- bool haveComputedBounds = false;
- addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds);
-
-#if !ASSERT_DISABLED
- LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
- while (RenderLayerStackingNode* curNode = iterator.next())
- addToOverlapMapRecursive(overlapMap, curNode->layer(), layer);
-
- if (ancestorLayer)
- overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
-}
-
-// Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
-// For the z-order children of a compositing layer:
-// If a child layers has a compositing layer, then all subsequent layers must
-// be compositing in order to render above that layer.
-//
-// If a child in the negative z-order list is compositing, then the layer itself
-// must be compositing so that its contents render over that child.
-// This implies that its positive z-index children must also be compositing.
-//
-void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingRecursionData& currentRecursionData, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants)
-{
- layer->stackingNode()->updateLayerListsIfNeeded();
-
- if (overlapMap)
- overlapMap->geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
-
- // Clear the flag
- layer->setHasCompositingDescendant(false);
- layer->setHasNonCompositedChild(false);
-
- // Start by assuming this layer will not need to composite.
- CompositingReasons reasonsToComposite = CompositingReasonNone;
-
- // First accumulate the straightforward compositing reasons.
- CompositingReasons directReasons = directReasonsForCompositing(layer);
-
- // Video is special. It's the only RenderLayer type that can both have
- // RenderLayer children and whose children can't use its backing to render
- // into. These children (the controls) always need to be promoted into their
- // own layers to draw on top of the accelerated video.
- if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_compositingAncestor->renderer()->isVideo())
- directReasons |= CompositingReasonLayerForVideoOverlay;
-
- if (canBeComposited(layer))
- reasonsToComposite |= directReasons;
-
- // Next, accumulate reasons related to overlap.
- // If overlap testing is used, this reason will be overridden. If overlap testing is not
- // used, we must assume we overlap if there is anything composited behind us in paint-order.
- CompositingReasons overlapCompositingReason = currentRecursionData.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone;
-
- if (rootRenderLayer()->compositorDrivenAcceleratedScrollingEnabled()) {
- Vector<size_t> unclippedDescendantsToRemove;
- for (size_t i = 0; i < unclippedDescendants.size(); i++) {
- RenderLayer* unclippedDescendant = unclippedDescendants.at(i);
- // If we've reached the containing block of one of the unclipped
- // descendants, that element is no longer relevant to whether or not we
- // should opt in. Unfortunately we can't easily remove from the list
- // while we're iterating, so we have to store it for later removal.
- if (unclippedDescendant->renderer()->containingBlock() == layer->renderer()) {
- unclippedDescendantsToRemove.append(i);
- continue;
- }
- if (layer->scrollsWithRespectTo(unclippedDescendant))
- reasonsToComposite |= CompositingReasonAssumedOverlap;
- }
-
- // Remove irrelevant unclipped descendants in reverse order so our stored
- // indices remain valid.
- for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++)
- unclippedDescendants.remove(unclippedDescendantsToRemove.at(unclippedDescendantsToRemove.size() - i - 1));
-
- if (reasonsToComposite & CompositingReasonOutOfFlowClipping)
- unclippedDescendants.append(layer);
- }
-
- bool haveComputedBounds = false;
- IntRect absBounds;
- // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map.
- if (overlapMap && !overlapMap->isEmpty() && currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons)) {
- // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
- absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds()));
-
- // Empty rects never intersect, but we need them to for the purposes of overlap testing.
- if (absBounds.isEmpty())
- absBounds.setSize(IntSize(1, 1));
- haveComputedBounds = true;
- overlapCompositingReason = overlapMap->overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone;
- }
-
- reasonsToComposite |= overlapCompositingReason;
-
- // The children of this layer don't need to composite, unless there is
- // a compositing layer among them, so start by inheriting the compositing
- // ancestor with m_subtreeIsCompositing set to false.
- CompositingRecursionData childRecursionData(currentRecursionData);
- childRecursionData.m_subtreeIsCompositing = false;
-
- bool willBeComposited = canBeComposited(layer) && requiresCompositingOrSquashing(reasonsToComposite);
- if (willBeComposited) {
- // Tell the parent it has compositing descendants.
- currentRecursionData.m_subtreeIsCompositing = true;
- // This layer now acts as the ancestor for kids.
- childRecursionData.m_compositingAncestor = layer;
-
- // Here we know that all children and the layer's own contents can blindly paint into
- // this layer's backing, until a descendant is composited. So, we don't need to check
- // for overlap with anything behind this layer.
- if (overlapMap)
- overlapMap->beginNewOverlapTestingContext();
- // This layer is going to be composited, so children can safely ignore the fact that there's an
- // animation running behind this layer, meaning they can rely on the overlap map testing again.
- childRecursionData.m_testingOverlap = true;
- }
-
-#if !ASSERT_DISABLED
- LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
- bool anyDescendantHas3DTransform = false;
- bool willHaveForegroundLayer = false;
-
- if (layer->stackingNode()->isStackingContainer()) {
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
- while (RenderLayerStackingNode* curNode = iterator.next()) {
- computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants);
-
- // If we have to make a layer for this child, make one now so we can have a contents layer
- // (since we need to ensure that the -ve z-order child renders underneath our contents).
- if (childRecursionData.m_subtreeIsCompositing) {
- reasonsToComposite |= CompositingReasonNegativeZIndexChildren;
-
- if (!willBeComposited) {
- // make layer compositing
- childRecursionData.m_compositingAncestor = layer;
- overlapMap->beginNewOverlapTestingContext();
- willBeComposited = true;
- willHaveForegroundLayer = true;
-
- // FIXME: temporary solution for the first negative z-index composited child:
- // re-compute the absBounds for the child so that we can add the
- // negative z-index child's bounds to the new overlap context.
- if (overlapMap) {
- overlapMap->geometryMap().pushMappingsToAncestor(curNode->layer(), layer);
- IntRect childAbsBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(curNode->layer()->overlapBounds()));
- bool boundsComputed = true;
- overlapMap->beginNewOverlapTestingContext();
- addToOverlapMap(*overlapMap, curNode->layer(), childAbsBounds, boundsComputed);
- overlapMap->finishCurrentOverlapTestingContext();
- overlapMap->geometryMap().popMappingsToAncestor(layer);
- }
- }
- }
- }
- }
-
- if (overlapMap && willHaveForegroundLayer) {
- ASSERT(willBeComposited);
- // A foreground layer effectively is a new backing for all subsequent children, so
- // we don't need to test for overlap with anything behind this. So, we can finish
- // the previous context that was accumulating rects for the negative z-index
- // children, and start with a fresh new empty context.
- overlapMap->finishCurrentOverlapTestingContext();
- overlapMap->beginNewOverlapTestingContext();
- // This layer is going to be composited, so children can safely ignore the fact that there's an
- // animation running behind this layer, meaning they can rely on the overlap map testing again
- childRecursionData.m_testingOverlap = true;
- }
-
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
- while (RenderLayerStackingNode* curNode = iterator.next())
- computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants);
-
- // Now that the subtree has been traversed, we can check for compositing reasons that depended on the state of the subtree.
-
- // If we entered compositing mode during the recursion, the root will also need to be composited (as long as accelerated compositing is enabled).
- if (layer->isRootLayer()) {
- if (inCompositingMode() && m_hasAcceleratedCompositing)
- willBeComposited = true;
- }
-
- // All layers (even ones that aren't being composited) need to get added to
- // the overlap map. Layers that are not separately composited will paint into their
- // compositing ancestor's backing, and so are still considered for overlap.
- if (overlapMap && childRecursionData.m_compositingAncestor && !childRecursionData.m_compositingAncestor->isRootLayer())
- addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
-
- if (layer->stackingNode()->isStackingContext()) {
- layer->setShouldIsolateCompositedDescendants(childRecursionData.m_hasUnisolatedCompositedBlendingDescendant);
- } else {
- layer->setShouldIsolateCompositedDescendants(false);
- currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = childRecursionData.m_hasUnisolatedCompositedBlendingDescendant;
- }
-
- // Now check for reasons to become composited that depend on the state of descendant layers.
- CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3DTransform);
- reasonsToComposite |= subtreeCompositingReasons;
- if (!willBeComposited && canBeComposited(layer) && requiresCompositingOrSquashing(subtreeCompositingReasons)) {
- childRecursionData.m_compositingAncestor = layer;
- if (overlapMap) {
- // FIXME: this context push is effectively a no-op but needs to exist for
- // now, because the code is designed to push overlap information to the
- // second-from-top context of the stack.
- overlapMap->beginNewOverlapTestingContext();
- addToOverlapMapRecursive(*overlapMap, layer);
- }
- willBeComposited = true;
- }
-
- // If the original layer is composited, the reflection needs to be, too.
- if (layer->reflectionInfo()) {
- // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
- CompositingReasons reflectionCompositingReason = willBeComposited ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone;
- layer->reflectionInfo()->reflectionLayer()->setCompositingReasons(layer->reflectionInfo()->reflectionLayer()->compositingReasons() | reflectionCompositingReason);
- }
-
- // Subsequent layers in the parent's stacking context may also need to composite.
- if (childRecursionData.m_subtreeIsCompositing)
- currentRecursionData.m_subtreeIsCompositing = true;
-
- if (willBeComposited && layer->hasBlendMode())
- currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true;
-
- // Set the flag to say that this SC has compositing children.
- layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing);
-
- // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
- // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
- // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
- bool isCompositedClippingLayer = canBeComposited(layer) && (reasonsToComposite & CompositingReasonClipsCompositingDescendants);
- if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) || isRunningAcceleratedTransformAnimation(layer->renderer()))
- currentRecursionData.m_testingOverlap = false;
-
- if (overlapMap && childRecursionData.m_compositingAncestor == layer && !layer->isRootLayer())
- overlapMap->finishCurrentOverlapTestingContext();
-
- if (layer->isRootLayer()) {
- // The root layer needs to be composited if anything else in the tree is composited.
- // Otherwise, we can disable compositing entirely.
- if (childRecursionData.m_subtreeIsCompositing || requiresCompositingOrSquashing(reasonsToComposite) || m_forceCompositingMode) {
- willBeComposited = true;
- reasonsToComposite |= CompositingReasonRoot;
- } else {
- enableCompositingMode(false);
- willBeComposited = false;
- reasonsToComposite = CompositingReasonNone;
- }
- }
-
- // At this point we have finished collecting all reasons to composite this layer.
- layer->setCompositingReasons(reasonsToComposite);
-
- if (!willBeComposited && layer->parent())
- layer->parent()->setHasNonCompositedChild(true);
-
- descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform();
-
- if (overlapMap)
- overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer);
-}
-
-void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsolute)
-{
- // The most recent backing is done accumulating any more squashing layers.
- if (hasMostRecentMapping)
- mostRecentMapping->finishAccumulatingSquashingLayers(nextSquashedLayerIndex);
-
- nextSquashedLayerIndex = 0;
- mostRecentMapping = newCompositedLayerMapping;
- hasMostRecentMapping = hasNewCompositedLayerMapping;
- offsetFromAbsolute = newOffsetFromAbsolute;
-}
-
-static IntPoint computeOffsetFromAbsolute(RenderLayer* layer)
-{
- TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
- layer->renderer()->mapLocalToContainer(0, transformState, ApplyContainerFlip);
- transformState.flatten();
- return roundedIntPoint(transformState.lastPlanarPoint());
-}
-
-void RenderLayerCompositor::assignLayersToBackings(RenderLayer* updateRoot, bool& layersChanged)
-{
- SquashingState squashingState;
- assignLayersToBackingsInternal(updateRoot, squashingState, layersChanged);
- if (squashingState.hasMostRecentMapping)
- squashingState.mostRecentMapping->finishAccumulatingSquashingLayers(squashingState.nextSquashedLayerIndex);
-}
-
-void RenderLayerCompositor::assignLayersToBackingsInternal(RenderLayer* layer, SquashingState& squashingState, bool& layersChanged)
-{
- if (allocateOrClearCompositedLayerMapping(layer))
- layersChanged = true;
-
- if (layer->reflectionInfo() && updateLayerCompositingState(layer->reflectionInfo()->reflectionLayer()))
- layersChanged = true;
-
- // Add this layer to a squashing backing if needed.
- if (layerSquashingEnabled()) {
- // NOTE: In the future as we generalize this, the background of this layer may need to be assigned to a different backing than
- // the layer's own primary contents. This would happen when we have a composited negative z-index element that needs to
- // paint on top of the background, but below the layer's main contents. For now, because we always composite layers
- // when they have a composited negative z-index child, such layers will never need squashing so it is not yet an issue.
- if (requiresSquashing(layer->compositingReasons())) {
- // A layer that is squashed with other layers cannot have its own CompositedLayerMapping.
- ASSERT(!layer->hasCompositedLayerMapping());
- ASSERT(squashingState.hasMostRecentMapping);
-
- IntPoint offsetFromAbsolute = computeOffsetFromAbsolute(layer);
-
- // FIXME: see if we can refactor this to be clearer
- IntSize offsetFromTargetBacking(offsetFromAbsolute.x() - squashingState.offsetFromAbsolute.x(),
- offsetFromAbsolute.y() - squashingState.offsetFromAbsolute.y());
-
- squashingState.mostRecentMapping->addRenderLayerToSquashingGraphicsLayer(layer, offsetFromTargetBacking, squashingState.nextSquashedLayerIndex);
- squashingState.nextSquashedLayerIndex++;
-
- // FIXME: does this need to be true here? Do we need more logic to decide when it should be true?
- layersChanged = true;
-
- // FIXME: this should be conditioned on whether this layer actually changed status
- layer->clipper().clearClipRectsIncludingDescendants();
- }
- }
-
- if (layer->stackingNode()->isStackingContainer()) {
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
- while (RenderLayerStackingNode* curNode = iterator.next())
- assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged);
- }
-
- if (layerSquashingEnabled()) {
- // At this point, if the layer is to be "separately" composited, then its backing becomes the most recent in paint-order.
- if (layer->compositingState() == PaintsIntoOwnBacking || layer->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
- ASSERT(!requiresSquashing(layer->compositingReasons()));
- IntPoint offsetFromAbsolute = computeOffsetFromAbsolute(layer);
- squashingState.updateSquashingStateForNewMapping(layer->compositedLayerMapping(), layer->hasCompositedLayerMapping(), offsetFromAbsolute);
- }
- }
-
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
- while (RenderLayerStackingNode* curNode = iterator.next())
- assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged);
-}
-
-void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
-{
- ASSERT(!parentLayer || childLayer->ancestorCompositingLayer() == parentLayer);
- ASSERT(childLayer->hasCompositedLayerMapping());
-
- // It's possible to be called with a parent that isn't yet composited when we're doing
- // partial updates as required by painting or hit testing. Just bail in that case;
- // we'll do a full layer update soon.
- if (!parentLayer || !parentLayer->hasCompositedLayerMapping())
- return;
-
- if (parentLayer) {
- GraphicsLayer* hostingLayer = parentLayer->compositedLayerMapping()->parentForSublayers();
- GraphicsLayer* hostedLayer = childLayer->compositedLayerMapping()->childForSuperlayers();
-
- hostingLayer->addChild(hostedLayer);
- } else {
- childLayer->compositedLayerMapping()->childForSuperlayers()->removeFromParent();
- }
-}
-
-void RenderLayerCompositor::removeCompositedChildren(RenderLayer* layer)
-{
- ASSERT(layer->hasCompositedLayerMapping());
-
- GraphicsLayer* hostingLayer = layer->compositedLayerMapping()->parentForSublayers();
- hostingLayer->removeAllChildren();
-}
-
-bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
-{
- if (!m_hasAcceleratedCompositing)
- return false;
-
- return o->supportsAcceleratedRendering();
-}
-
-void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
-{
- // Make the layer compositing if necessary, and set up clipping and content layers.
- // Note that we can only do work here that is independent of whether the descendant layers
- // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
-
- layer->stackingNode()->updateLayerListsIfNeeded();
-
- // Used for gathering UMA data about the effect on memory usage of promoting all layers
- // that have a webkit-transition on opacity or transform and intersect the viewport.
- static double pixelsWithoutPromotingAllTransitions = 0.0;
- static double pixelsAddedByPromotingAllTransitions = 0.0;
-
- if (!depth) {
- pixelsWithoutPromotingAllTransitions = 0.0;
- pixelsAddedByPromotingAllTransitions = 0.0;
- }
-
- const bool hasCompositedLayerMapping = layer->hasCompositedLayerMapping();
- CompositedLayerMappingPtr currentCompositedLayerMapping = layer->compositedLayerMapping();
- if (hasCompositedLayerMapping) {
- // The compositing state of all our children has been updated already, so now
- // we can compute and cache the composited bounds for this layer.
- currentCompositedLayerMapping->updateCompositedBounds();
-
- if (layer->reflectionInfo()) {
- RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
- if (reflectionLayer->hasCompositedLayerMapping())
- reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
- }
-
- currentCompositedLayerMapping->updateGraphicsLayerConfiguration();
- currentCompositedLayerMapping->updateGraphicsLayerGeometry();
-
- if (!layer->parent())
- updateRootLayerPosition();
-
- if (currentCompositedLayerMapping->hasUnpositionedOverflowControlsLayers())
- layer->scrollableArea()->positionOverflowControls();
-
- pixelsWithoutPromotingAllTransitions += layer->size().height() * layer->size().width();
- } else {
- if ((layer->renderer()->style()->transitionForProperty(CSSPropertyOpacity) ||
- layer->renderer()->style()->transitionForProperty(CSSPropertyWebkitTransform)) &&
- m_renderView->viewRect().intersects(layer->absoluteBoundingBox()))
- pixelsAddedByPromotingAllTransitions += layer->size().height() * layer->size().width();
- }
-
- // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
- // Otherwise children continue to append to the child list of the enclosing layer.
- Vector<GraphicsLayer*> layerChildren;
- Vector<GraphicsLayer*>& childList = hasCompositedLayerMapping ? layerChildren : childLayersOfEnclosingLayer;
-
-#if !ASSERT_DISABLED
- LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
- if (layer->stackingNode()->isStackingContainer()) {
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
- while (RenderLayerStackingNode* curNode = iterator.next())
- rebuildCompositingLayerTree(curNode->layer(), childList, depth + 1);
-
- // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
- if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
- childList.append(currentCompositedLayerMapping->foregroundLayer());
- }
-
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
- while (RenderLayerStackingNode* curNode = iterator.next())
- rebuildCompositingLayerTree(curNode->layer(), childList, depth + 1);
-
- if (hasCompositedLayerMapping) {
- bool parented = false;
- if (layer->renderer()->isRenderPart())
- parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
-
- if (!parented)
- currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren);
-
- // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
- // Otherwise, the overflow control layers are normal children.
- if (!currentCompositedLayerMapping->hasClippingLayer() && !currentCompositedLayerMapping->hasScrollingLayer()) {
- if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForHorizontalScrollbar()) {
- overflowControlLayer->removeFromParent();
- currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
- }
-
- if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) {
- overflowControlLayer->removeFromParent();
- currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
- }
-
- if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) {
- overflowControlLayer->removeFromParent();
- currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
- }
- }
-
- childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers());
- }
-
- if (!depth) {
- int percentageIncreaseInPixels = static_cast<int>(pixelsAddedByPromotingAllTransitions / pixelsWithoutPromotingAllTransitions * 100);
- blink::Platform::current()->histogramCustomCounts("Renderer.PixelIncreaseFromTransitions", percentageIncreaseInPixels, 0, 1000, 50);
- }
-}
-
-void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
-{
- if (m_overflowControlsHostLayer)
- m_overflowControlsHostLayer->setPosition(contentsOffset);
-}
-
-void RenderLayerCompositor::frameViewDidChangeSize()
-{
- if (m_containerLayer) {
- FrameView* frameView = m_renderView->frameView();
- m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
-
- frameViewDidScroll();
- updateOverflowControlsLayers();
- }
-}
-
-enum AcceleratedFixedRootBackgroundHistogramBuckets {
- ScrolledMainFrameBucket = 0,
- ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
- ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
- AcceleratedFixedRootBackgroundHistogramMax = 3
-};
-
-void RenderLayerCompositor::frameViewDidScroll()
-{
- FrameView* frameView = m_renderView->frameView();
- IntPoint scrollPosition = frameView->scrollPosition();
-
- if (!m_scrollLayer)
- return;
-
- bool scrollingCoordinatorHandlesOffset = false;
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
- if (Settings* settings = m_renderView->document().settings()) {
- if (isMainFrame() || settings->compositedScrollingForFramesEnabled())
- scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
- }
- }
-
- // Scroll position = scroll minimum + scroll offset. Adjust the layer's
- // position to handle whatever the scroll coordinator isn't handling.
- // The minimum scroll position is non-zero for RTL pages with overflow.
- if (scrollingCoordinatorHandlesOffset)
- m_scrollLayer->setPosition(-frameView->minimumScrollPosition());
- else
- m_scrollLayer->setPosition(-scrollPosition);
-
-
- blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
- ScrolledMainFrameBucket,
- AcceleratedFixedRootBackgroundHistogramMax);
-
- if (!m_renderView->rootBackgroundIsEntirelyFixed())
- return;
-
- blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
- !!fixedRootBackgroundLayer()
- ? ScrolledMainFrameWithAcceleratedFixedRootBackground
- : ScrolledMainFrameWithUnacceleratedFixedRootBackground,
- AcceleratedFixedRootBackgroundHistogramMax);
-}
-
-void RenderLayerCompositor::frameViewDidLayout()
-{
-}
-
-void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
-{
- if (m_containerLayer)
- updateOverflowControlsLayers();
-}
-
-void RenderLayerCompositor::rootFixedBackgroundsChanged()
-{
- if (!supportsFixedRootBackgroundCompositing())
- return;
-
- // To avoid having to make the fixed root background layer fixed positioned to
- // stay put, we position it in the layer tree as follows:
- //
- // + Overflow controls host
- // + Frame clip
- // + (Fixed root background) <-- Here.
- // + Frame scroll
- // + Root content layer
- // + Scrollbars
- //
- // That is, it needs to be the first child of the frame clip, the sibling of
- // the frame scroll layer. The compositor does not own the background layer, it
- // just positions it (like the foreground layer).
- if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
- m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get());
-}
-
-bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
-{
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
- return false;
-}
-
-String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
-{
- // Before dumping the layer tree, finish any pending compositing update.
- updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
-
- if (!m_rootContentLayer)
- return String();
-
- // We skip dumping the scroll and clip layers to keep layerTreeAsText output
- // similar between platforms (unless we explicitly request dumping from the
- // root.
- GraphicsLayer* rootLayer = m_rootContentLayer.get();
- if (flags & LayerTreeIncludesRootLayer)
- rootLayer = rootGraphicsLayer();
-
- String layerTreeText = rootLayer->layerTreeAsText(flags);
-
- // The true root layer is not included in the dump, so if we want to report
- // its repaint rects, they must be included here.
- if (flags & LayerTreeIncludesRepaintRects)
- return m_renderView->frameView()->trackedRepaintRectsAsText() + layerTreeText;
-
- return layerTreeText;
-}
-
-RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
-{
- if (!renderer->node()->isFrameOwnerElement())
- return 0;
-
- HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node());
- if (Document* contentDocument = element->contentDocument()) {
- if (RenderView* view = contentDocument->renderView())
- return view->compositor();
- }
- return 0;
-}
-
-bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
-{
- RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
- if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
- return false;
-
- RenderLayer* layer = renderer->layer();
- if (!layer->hasCompositedLayerMapping())
- return false;
-
- CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
- GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers();
- GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
- if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
- hostingLayer->removeAllChildren();
- hostingLayer->addChild(rootLayer);
- }
- return true;
-}
-
-// This just updates layer geometry without changing the hierarchy.
-void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
-{
- if (layer->hasCompositedLayerMapping()) {
- CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
- // The compositing state of all our children has been updated already, so now
- // we can compute and cache the composited bounds for this layer.
- compositedLayerMapping->updateCompositedBounds();
-
- if (layer->reflectionInfo()) {
- RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
- if (reflectionLayer->hasCompositedLayerMapping())
- reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
- }
-
- compositedLayerMapping->updateGraphicsLayerConfiguration();
- compositedLayerMapping->updateGraphicsLayerGeometry();
-
- if (!layer->parent())
- updateRootLayerPosition();
- }
-
-#if !ASSERT_DISABLED
- LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
- while (RenderLayerStackingNode* curNode = iterator.next())
- updateLayerTreeGeometry(curNode->layer());
-}
-
-// Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
-void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayerStackingNode* compositingAncestor, RenderLayer* layer, bool compositedChildrenOnly)
-{
- if (layer->stackingNode() != compositingAncestor) {
- if (layer->hasCompositedLayerMapping()) {
- CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
- compositedLayerMapping->updateCompositedBounds();
-
- if (layer->reflectionInfo()) {
- RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
- if (reflectionLayer->hasCompositedLayerMapping())
- reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
- }
-
- compositedLayerMapping->updateGraphicsLayerGeometry();
- if (compositedChildrenOnly)
- return;
- }
- }
-
- if (layer->reflectionInfo())
- updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionInfo()->reflectionLayer(), compositedChildrenOnly);
-
- if (!layer->hasCompositingDescendant())
- return;
-
-#if !ASSERT_DISABLED
- LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
- while (RenderLayerStackingNode* curNode = iterator.next())
- updateCompositingDescendantGeometry(compositingAncestor, curNode->layer(), compositedChildrenOnly);
-}
-
-
-void RenderLayerCompositor::repaintCompositedLayers(const IntRect* absRect)
-{
- recursiveRepaintLayer(rootRenderLayer(), absRect);
-}
-
-void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer, const IntRect* rect)
-{
- // FIXME: This method does not work correctly with transforms.
- if (layer->compositingState() == PaintsIntoOwnBacking) {
- if (rect)
- layer->repainter().setBackingNeedsRepaintInRect(*rect);
- else
- layer->repainter().setBackingNeedsRepaint();
- }
-
-#if !ASSERT_DISABLED
- LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
- unsigned childrenToVisit = NormalFlowChildren;
- if (layer->hasCompositingDescendant())
- childrenToVisit |= PositiveZOrderChildren | NegativeZOrderChildren;
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), childrenToVisit);
- while (RenderLayerStackingNode* curNode = iterator.next()) {
- if (rect) {
- IntRect childRect(*rect);
- curNode->layer()->convertToPixelSnappedLayerCoords(layer, childRect);
- recursiveRepaintLayer(curNode->layer(), &childRect);
- } else {
- recursiveRepaintLayer(curNode->layer());
- }
- }
-}
-
-RenderLayer* RenderLayerCompositor::rootRenderLayer() const
-{
- return m_renderView->layer();
-}
-
-GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
-{
- if (m_overflowControlsHostLayer)
- return m_overflowControlsHostLayer.get();
- return m_rootContentLayer.get();
-}
-
-GraphicsLayer* RenderLayerCompositor::scrollLayer() const
-{
- return m_scrollLayer.get();
-}
-
-void RenderLayerCompositor::setIsInWindow(bool isInWindow)
-{
- if (!inCompositingMode())
- return;
-
- if (isInWindow) {
- if (m_rootLayerAttachment != RootLayerUnattached)
- return;
-
- RootLayerAttachment attachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
- attachRootLayer(attachment);
- } else {
- if (m_rootLayerAttachment == RootLayerUnattached)
- return;
-
- detachRootLayer();
- }
-}
-
-void RenderLayerCompositor::clearMappingForRenderLayerIncludingDescendants(RenderLayer* layer)
-{
- if (!layer)
- return;
-
- if (layer->hasCompositedLayerMapping()) {
- removeViewportConstrainedLayer(layer);
- layer->clearCompositedLayerMapping();
- }
-
- for (RenderLayer* currLayer = layer->firstChild(); currLayer; currLayer = currLayer->nextSibling())
- clearMappingForRenderLayerIncludingDescendants(currLayer);
-}
-
-void RenderLayerCompositor::clearMappingForAllRenderLayers()
-{
- clearMappingForRenderLayerIncludingDescendants(m_renderView->layer());
-}
-
-void RenderLayerCompositor::updateRootLayerPosition()
-{
- if (m_rootContentLayer) {
- const IntRect& documentRect = m_renderView->documentRect();
- m_rootContentLayer->setSize(documentRect.size());
- m_rootContentLayer->setPosition(documentRect.location());
-#if USE(RUBBER_BANDING)
- if (m_layerForOverhangShadow)
- OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
-#endif
- }
- if (m_containerLayer) {
- FrameView* frameView = m_renderView->frameView();
- m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
- }
-}
-
-bool RenderLayerCompositor::has3DContent() const
-{
- return layerHas3DContent(rootRenderLayer());
-}
-
-void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
-{
- CompositingReasons layerReasons = layer->compositingReasons();
-
- layerReasons &= ~CompositingReasonComboAllDirectReasons;
- layerReasons |= directReasonsForCompositing(layer);
- layer->setCompositingReasons(layerReasons);
-}
-
-bool RenderLayerCompositor::needsOwnBacking(const RenderLayer* layer) const
-{
- if (!canBeComposited(layer))
- return false;
-
- // If squashing is disabled, then layers that would have been squashed should just be separately composited.
- bool needsOwnBackingForDisabledSquashing = !layerSquashingEnabled() && requiresSquashing(layer->compositingReasons());
-
- return requiresCompositing(layer->compositingReasons()) || needsOwnBackingForDisabledSquashing || (inCompositingMode() && layer->isRootLayer());
-}
-
-bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
-{
- // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
- // See http://webkit.org/b/84900 to re-enable it.
- return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread;
-}
-
-CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const RenderLayer* layer) const
-{
- RenderObject* renderer = layer->renderer();
- CompositingReasons directReasons = CompositingReasonNone;
-
- if (requiresCompositingForTransform(renderer))
- directReasons |= CompositingReason3DTransform;
-
- // Only zero or one of the following conditions will be true for a given RenderLayer.
- if (requiresCompositingForVideo(renderer))
- directReasons |= CompositingReasonVideo;
- else if (requiresCompositingForCanvas(renderer))
- directReasons |= CompositingReasonCanvas;
- else if (requiresCompositingForPlugin(renderer))
- directReasons |= CompositingReasonPlugin;
- else if (requiresCompositingForFrame(renderer))
- directReasons |= CompositingReasonIFrame;
-
- if (requiresCompositingForBackfaceVisibilityHidden(renderer))
- directReasons |= CompositingReasonBackfaceVisibilityHidden;
-
- if (requiresCompositingForAnimation(renderer))
- directReasons |= CompositingReasonAnimation;
-
- if (requiresCompositingForTransition(renderer))
- directReasons |= CompositingReasonAnimation;
-
- if (requiresCompositingForFilters(renderer))
- directReasons |= CompositingReasonFilters;
-
- if (requiresCompositingForPosition(renderer, layer))
- directReasons |= renderer->style()->position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky;
-
- if (requiresCompositingForOverflowScrolling(layer))
- directReasons |= CompositingReasonOverflowScrollingTouch;
-
- if (requiresCompositingForOverflowScrollingParent(layer))
- directReasons |= CompositingReasonOverflowScrollingParent;
-
- if (requiresCompositingForOutOfFlowClipping(layer))
- directReasons |= CompositingReasonOutOfFlowClipping;
-
- return directReasons;
-}
-
-// Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
-// up to the enclosing compositing ancestor. This is required because compositing layers are parented
-// according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
-// Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
-// but a sibling in the z-order hierarchy.
-bool RenderLayerCompositor::clippedByAncestor(const RenderLayer* layer) const
-{
- if (!layer->hasCompositedLayerMapping() || !layer->parent())
- return false;
-
- // FIXME: need to double-check if semantics of ancestorCompositingLayer() work correctly here?
- const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
- if (!compositingAncestor)
- return false;
-
- // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
- // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
- // and layer.
- const RenderLayer* computeClipRoot = 0;
- const RenderLayer* curr = layer;
- while (curr) {
- const RenderLayer* next = curr->parent();
- if (next == compositingAncestor) {
- computeClipRoot = curr;
- break;
- }
- curr = next;
- }
-
- if (!computeClipRoot || computeClipRoot == layer)
- return false;
-
- return layer->backgroundClipRect(ClipRectsContext(computeClipRoot, 0, TemporaryClipRects)).rect() != PaintInfo::infiniteRect(); // FIXME: Incorrect for CSS regions.
-}
-
-// Return true if the given layer is a stacking context and has compositing child
-// layers that it needs to clip. In this case we insert a clipping GraphicsLayer
-// into the hierarchy between this layer and its children in the z-order hierarchy.
-bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
-{
- return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
-}
-
-bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
-{
- // Need this done first to determine overflow.
- ASSERT(!m_renderView->needsLayout());
- if (isMainFrame())
- return false;
-
- if (!(m_compositingTriggers & ChromeClient::ScrollableInnerFrameTrigger))
- return false;
-
- FrameView* frameView = m_renderView->frameView();
- return frameView->isScrollable();
-}
-
-bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
-{
- if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
- return false;
-
- RenderStyle* style = renderer->style();
- // Note that we ask the renderer if it has a transform, because the style may have transforms,
- // but the renderer may be an inline that doesn't suppport them.
- return renderer->hasTransform() && style->transform().has3DOperation();
-}
-
-bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
-{
- if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer->isVideo()) {
- HTMLMediaElement* media = toHTMLMediaElement(renderer->node());
- if (media->isFullscreen())
- return true;
- }
-
- if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
- return false;
-
- if (renderer->isVideo()) {
- RenderVideo* video = toRenderVideo(renderer);
- return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
- }
- return false;
-}
-
-bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
-{
- if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
- return false;
-
- if (renderer->isCanvas()) {
- HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
- return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
- }
- return false;
-}
-
-bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
-{
- if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
- return false;
-
- bool composite = renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
- if (!composite)
- return false;
-
- // FIXME: this seems bogus. If we don't know the layout position/size of the plugin yet, would't that be handled elsewhere?
- m_needsToRecomputeCompositingRequirements = true;
-
- RenderWidget* pluginRenderer = toRenderWidget(renderer);
- // If we can't reliably know the size of the plugin yet, don't change compositing state.
- if (pluginRenderer->needsLayout())
- return pluginRenderer->hasLayer() && pluginRenderer->layer()->hasCompositedLayerMapping();
-
- // Don't go into compositing mode if height or width are zero, or size is 1x1.
- IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
- return contentBox.height() * contentBox.width() > 1;
-}
-
-bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
-{
- if (!renderer->isRenderPart())
- return false;
-
- RenderPart* frameRenderer = toRenderPart(renderer);
-
- if (!frameRenderer->requiresAcceleratedCompositing())
- return false;
-
- if (frameRenderer->node() && frameRenderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame()->remotePlatformLayer())
- return true;
-
- // FIXME: this seems bogus. If we don't know the layout position/size of the frame yet, wouldn't that be handled elsehwere?
- m_needsToRecomputeCompositingRequirements = true;
-
- RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
- if (!innerCompositor)
- return false;
-
- // If we can't reliably know the size of the iframe yet, don't change compositing state.
- if (renderer->needsLayout())
- return frameRenderer->hasLayer() && frameRenderer->layer()->hasCompositedLayerMapping();
-
- // Don't go into compositing mode if height or width are zero.
- IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
- return contentBox.height() * contentBox.width() > 0;
-}
-
-bool RenderLayerCompositor::requiresCompositingForBackfaceVisibilityHidden(RenderObject* renderer) const
-{
- return canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden;
-}
-
-bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
-{
- if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
- return false;
-
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- return renderer->animation().isRunningAcceleratableAnimationOnRenderer(renderer);
-
- return shouldCompositeForActiveAnimations(*renderer);
-}
-
-bool RenderLayerCompositor::requiresCompositingForTransition(RenderObject* renderer) const
-{
- if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
- return false;
-
- if (Settings* settings = m_renderView->document().settings()) {
- if (!settings->acceleratedCompositingForTransitionEnabled())
- return false;
- }
-
- return renderer->style()->transitionForProperty(CSSPropertyOpacity)
- || renderer->style()->transitionForProperty(CSSPropertyWebkitFilter)
- || renderer->style()->transitionForProperty(CSSPropertyWebkitTransform);
-}
-
-CompositingReasons RenderLayerCompositor::subtreeReasonsForCompositing(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants) const
-{
- CompositingReasons subtreeReasons = CompositingReasonNone;
-
- // FIXME: this seems to be a potentially different layer than the layer for which this was called. May not be an error, but is very confusing.
- RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
-
- // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
- // via compositing so that they also apply to those composited descdendants.
- if (hasCompositedDescendants) {
- if (layer->transform())
- subtreeReasons |= CompositingReasonTransformWithCompositedDescendants;
-
- if (layer->shouldIsolateCompositedDescendants()) {
- ASSERT(layer->stackingNode()->isStackingContext());
- subtreeReasons |= CompositingReasonIsolateCompositedDescendants;
- }
-
- // If the implementation of createsGroup changes, we need to be aware of that in this part of code.
- ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->hasFilter() || renderer->hasBlendMode()) == renderer->createsGroup());
- if (renderer->isTransparent())
- subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants;
- if (renderer->hasMask())
- subtreeReasons |= CompositingReasonMaskWithCompositedDescendants;
- if (renderer->hasFilter())
- subtreeReasons |= CompositingReasonFilterWithCompositedDescendants;
- if (renderer->hasBlendMode())
- subtreeReasons |= CompositingReasonBlendingWithCompositedDescendants;
-
- if (renderer->hasReflection())
- subtreeReasons |= CompositingReasonReflectionWithCompositedDescendants;
-
- if (renderer->hasClipOrOverflowClip())
- subtreeReasons |= CompositingReasonClipsCompositingDescendants;
- }
-
-
- // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
- // will be affected by the preserve-3d or perspective.
- if (has3DTransformedDescendants) {
- if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D)
- subtreeReasons |= CompositingReasonPreserve3D;
-
- if (renderer->style()->hasPerspective())
- subtreeReasons |= CompositingReasonPerspective;
- }
-
- return subtreeReasons;
-}
-
-bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
-{
- if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
- return false;
-
- return renderer->hasFilter();
-}
-
-bool RenderLayerCompositor::requiresCompositingForOverflowScrollingParent(const RenderLayer* layer) const
-{
- return !!layer->scrollParent();
-}
-
-bool RenderLayerCompositor::requiresCompositingForOutOfFlowClipping(const RenderLayer* layer) const
-{
- return layer->compositorDrivenAcceleratedScrollingEnabled() && layer->isUnclippedDescendant();
-}
-
-bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
-{
- // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
- // opacity, transform) can get their own composited layer. A stacking context is required otherwise
- // z-index and clipping will be broken.
- if (!renderer->isPositioned())
- return false;
-
- EPosition position = renderer->style()->position();
- bool isFixed = renderer->isOutOfFlowPositioned() && position == FixedPosition;
- if (isFixed && !layer->stackingNode()->isStackingContainer())
- return false;
-
- bool isSticky = renderer->isInFlowPositioned() && position == StickyPosition;
- if (!isFixed && !isSticky)
- return false;
-
- // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
- if (Settings* settings = m_renderView->document().settings()) {
- if (!settings->acceleratedCompositingForFixedPositionEnabled())
- return false;
- }
-
- if (isSticky)
- return true;
-
- RenderObject* container = renderer->container();
- // If the renderer is not hooked up yet then we have to wait until it is.
- if (!container) {
- m_needsToRecomputeCompositingRequirements = true;
- return false;
- }
-
- // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
- // They will stay fixed wrt the container rather than the enclosing frame.
- if (container != m_renderView) {
- if (viewportConstrainedNotCompositedReason)
- *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
- return false;
- }
-
- // If the fixed-position element does not have any scrollable ancestor between it and
- // its container, then we do not need to spend compositor resources for it. Start by
- // assuming we can opt-out (i.e. no scrollable ancestor), and refine the answer below.
- bool hasScrollableAncestor = false;
-
- // The FrameView has the scrollbars associated with the top level viewport, so we have to
- // check the FrameView in addition to the hierarchy of ancestors.
- FrameView* frameView = m_renderView->frameView();
- if (frameView && frameView->isScrollable())
- hasScrollableAncestor = true;
-
- RenderLayer* ancestor = layer->parent();
- while (ancestor && !hasScrollableAncestor) {
- if (frameView->containsScrollableArea(ancestor->scrollableArea()))
- hasScrollableAncestor = true;
- if (ancestor->renderer() == m_renderView)
- break;
- ancestor = ancestor->parent();
- }
-
- if (!hasScrollableAncestor) {
- if (viewportConstrainedNotCompositedReason)
- *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForUnscrollableAncestors;
- return false;
- }
-
- // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done.
- if (!m_inPostLayoutUpdate) {
- m_needsToRecomputeCompositingRequirements = true;
- return layer->hasCompositedLayerMapping();
- }
-
- bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescendant();
- if (!paintsContent) {
- if (viewportConstrainedNotCompositedReason)
- *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent;
- return false;
- }
-
- // Fixed position elements that are invisible in the current view don't get their own layer.
- if (FrameView* frameView = m_renderView->frameView()) {
- LayoutRect viewBounds = frameView->viewportConstrainedVisibleContentRect();
- LayoutRect layerBounds = layer->calculateLayerBounds(rootRenderLayer(), 0,
- RenderLayer::DefaultCalculateLayerBoundsFlags
- | RenderLayer::ExcludeHiddenDescendants
- | RenderLayer::DontConstrainForMask
- | RenderLayer::IncludeCompositedDescendants
- | RenderLayer::PretendLayerHasOwnBacking);
- if (!viewBounds.intersects(enclosingIntRect(layerBounds))) {
- if (viewportConstrainedNotCompositedReason) {
- *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
- m_needsToRecomputeCompositingRequirements = true;
- }
- return false;
- }
- }
-
- return true;
-}
-
-bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer* layer) const
-{
- return layer->needsCompositedScrolling();
-}
-
-bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
-{
- if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
- return false;
- if (!RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- return renderer->animation().isRunningAnimationOnRenderer(renderer, CSSPropertyWebkitTransform);
- return hasActiveAnimations(*renderer, CSSPropertyWebkitTransform);
-}
-
-// If an element has negative z-index children, those children render in front of the
-// layer background, so we need an extra 'contents' layer for the foreground of the layer
-// object.
-bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
-{
- return layer->stackingNode()->hasNegativeZOrderList();
-}
-
-static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
-{
- if (!scrollbar)
- return;
-
- context.save();
- const IntRect& scrollbarRect = scrollbar->frameRect();
- context.translate(-scrollbarRect.x(), -scrollbarRect.y());
- IntRect transformedClip = clip;
- transformedClip.moveBy(scrollbarRect.location());
- scrollbar->paint(&context, transformedClip);
- context.restore();
-}
-
-void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
-{
- if (graphicsLayer == layerForHorizontalScrollbar())
- paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
- else if (graphicsLayer == layerForVerticalScrollbar())
- paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
- else if (graphicsLayer == layerForScrollCorner()) {
- const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
- context.save();
- context.translate(-scrollCorner.x(), -scrollCorner.y());
- IntRect transformedClip = clip;
- transformedClip.moveBy(scrollCorner.location());
- m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
- context.restore();
- }
-}
-
-bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
-{
- if (Settings* settings = m_renderView->document().settings()) {
- if (settings->acceleratedCompositingForFixedRootBackgroundEnabled())
- return true;
- }
- return false;
-}
-
-bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
-{
- if (layer != m_renderView->layer())
- return false;
-
- return supportsFixedRootBackgroundCompositing() && m_renderView->rootBackgroundIsEntirelyFixed();
-}
-
-GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
-{
- // Get the fixed root background from the RenderView layer's compositedLayerMapping.
- RenderLayer* viewLayer = m_renderView->layer();
- if (!viewLayer)
- return 0;
-
- if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
- return viewLayer->compositedLayerMapping()->backgroundLayer();
-
- return 0;
-}
-
-static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer)
-{
- if (!graphicsLayer)
- return;
-
- graphicsLayer->resetTrackedRepaints();
-
- for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
- resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]);
-
- if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
- resetTrackedRepaintRectsRecursive(replicaLayer);
-
- if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
- resetTrackedRepaintRectsRecursive(maskLayer);
-
- if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer())
- resetTrackedRepaintRectsRecursive(clippingMaskLayer);
-}
-
-void RenderLayerCompositor::resetTrackedRepaintRects()
-{
- if (GraphicsLayer* rootLayer = rootGraphicsLayer())
- resetTrackedRepaintRectsRecursive(rootLayer);
-}
-
-void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints)
-{
- updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
- m_isTrackingRepaints = tracksRepaints;
-}
-
-bool RenderLayerCompositor::isTrackingRepaints() const
-{
- return m_isTrackingRepaints;
-}
-
-void RenderLayerCompositor::didCommitChangesForLayer(const GraphicsLayer*) const
-{
- // Nothing to do here yet.
-}
-
-static bool shouldCompositeOverflowControls(FrameView* view)
-{
- if (Page* page = view->frame().page()) {
- if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
- if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
- return true;
- }
-
- return true;
-}
-
-bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
-{
- FrameView* view = m_renderView->frameView();
- return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
-}
-
-bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
-{
- FrameView* view = m_renderView->frameView();
- return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
-}
-
-bool RenderLayerCompositor::requiresScrollCornerLayer() const
-{
- FrameView* view = m_renderView->frameView();
- return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
-}
-
-#if USE(RUBBER_BANDING)
-bool RenderLayerCompositor::requiresOverhangLayers() const
-{
- // We don't want a layer if this is a subframe.
- if (!isMainFrame())
- return false;
-
- // We do want a layer if we have a scrolling coordinator and can scroll.
- if (scrollingCoordinator() && m_renderView->frameView()->hasOpaqueBackground())
- return true;
-
- // Chromium always wants a layer.
- return true;
-}
-#endif
-
-void RenderLayerCompositor::updateOverflowControlsLayers()
-{
-#if USE(RUBBER_BANDING)
- if (requiresOverhangLayers()) {
- if (!m_layerForOverhangShadow) {
- m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this);
- OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get());
- OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
- m_scrollLayer->addChild(m_layerForOverhangShadow.get());
- }
- } else {
- if (m_layerForOverhangShadow) {
- m_layerForOverhangShadow->removeFromParent();
- m_layerForOverhangShadow = nullptr;
- }
- }
-#endif
-
- if (requiresHorizontalScrollbarLayer()) {
- if (!m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
- m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
-
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
- }
- } else if (m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar->removeFromParent();
- m_layerForHorizontalScrollbar = nullptr;
-
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
- }
-
- if (requiresVerticalScrollbarLayer()) {
- if (!m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
- m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
-
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
- }
- } else if (m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar->removeFromParent();
- m_layerForVerticalScrollbar = nullptr;
-
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
- }
-
- if (requiresScrollCornerLayer()) {
- if (!m_layerForScrollCorner) {
- m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
- m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
- }
- } else if (m_layerForScrollCorner) {
- m_layerForScrollCorner->removeFromParent();
- m_layerForScrollCorner = nullptr;
- }
-
- m_renderView->frameView()->positionScrollbarLayers();
-}
-
-void RenderLayerCompositor::ensureRootLayer()
-{
- RootLayerAttachment expectedAttachment = isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
- if (expectedAttachment == m_rootLayerAttachment)
- return;
-
- if (!m_rootContentLayer) {
- m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
- IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect();
- m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
- m_rootContentLayer->setPosition(FloatPoint());
-
- // Need to clip to prevent transformed content showing outside this frame
- m_rootContentLayer->setMasksToBounds(true);
- }
-
- if (!m_overflowControlsHostLayer) {
- ASSERT(!m_scrollLayer);
- ASSERT(!m_containerLayer);
-
- // Create a layer to host the clipping layer and the overflow controls layers.
- m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
-
- // Create a clipping layer if this is an iframe or settings require to clip.
- m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
- bool containerMasksToBounds = !isMainFrame();
- if (Settings* settings = m_renderView->document().settings()) {
- if (settings->mainFrameClipsContent())
- containerMasksToBounds = true;
- }
- m_containerLayer->setMasksToBounds(containerMasksToBounds);
-
- m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
-
- // Hook them up
- m_overflowControlsHostLayer->addChild(m_containerLayer.get());
- m_containerLayer->addChild(m_scrollLayer.get());
- m_scrollLayer->addChild(m_rootContentLayer.get());
-
- frameViewDidChangeSize();
- frameViewDidScroll();
- }
-
- // Check to see if we have to change the attachment
- if (m_rootLayerAttachment != RootLayerUnattached)
- detachRootLayer();
-
- attachRootLayer(expectedAttachment);
-}
-
-void RenderLayerCompositor::destroyRootLayer()
-{
- if (!m_rootContentLayer)
- return;
-
- detachRootLayer();
-
-#if USE(RUBBER_BANDING)
- if (m_layerForOverhangShadow) {
- m_layerForOverhangShadow->removeFromParent();
- m_layerForOverhangShadow = nullptr;
- }
-#endif
-
- if (m_layerForHorizontalScrollbar) {
- m_layerForHorizontalScrollbar->removeFromParent();
- m_layerForHorizontalScrollbar = nullptr;
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
- if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
- m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
- }
-
- if (m_layerForVerticalScrollbar) {
- m_layerForVerticalScrollbar->removeFromParent();
- m_layerForVerticalScrollbar = nullptr;
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
- if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
- m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
- }
-
- if (m_layerForScrollCorner) {
- m_layerForScrollCorner = nullptr;
- m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect());
- }
-
- if (m_overflowControlsHostLayer) {
- m_overflowControlsHostLayer = nullptr;
- m_containerLayer = nullptr;
- m_scrollLayer = nullptr;
- }
- ASSERT(!m_scrollLayer);
- m_rootContentLayer = nullptr;
-}
-
-void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
-{
- if (!m_rootContentLayer)
- return;
-
- switch (attachment) {
- case RootLayerUnattached:
- ASSERT_NOT_REACHED();
- break;
- case RootLayerAttachedViaChromeClient: {
- Frame& frame = m_renderView->frameView()->frame();
- Page* page = frame.page();
- if (!page)
- return;
- page->chrome().client().attachRootGraphicsLayer(&frame, rootGraphicsLayer());
- break;
- }
- case RootLayerAttachedViaEnclosingFrame: {
- // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
- // for the frame's renderer in the parent document.
- m_renderView->document().ownerElement()->scheduleLayerUpdate();
- break;
- }
- }
-
- m_rootLayerAttachment = attachment;
-}
-
-void RenderLayerCompositor::detachRootLayer()
-{
- if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
- return;
-
- switch (m_rootLayerAttachment) {
- case RootLayerAttachedViaEnclosingFrame: {
- // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
- // for the frame's renderer in the parent document.
- if (m_overflowControlsHostLayer)
- m_overflowControlsHostLayer->removeFromParent();
- else
- m_rootContentLayer->removeFromParent();
-
- if (HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement())
- ownerElement->scheduleLayerUpdate();
- break;
- }
- case RootLayerAttachedViaChromeClient: {
- Frame& frame = m_renderView->frameView()->frame();
- Page* page = frame.page();
- if (!page)
- return;
- page->chrome().client().attachRootGraphicsLayer(&frame, 0);
- }
- break;
- case RootLayerUnattached:
- break;
- }
-
- m_rootLayerAttachment = RootLayerUnattached;
-}
-
-void RenderLayerCompositor::updateRootLayerAttachment()
-{
- ensureRootLayer();
-}
-
-bool RenderLayerCompositor::isMainFrame() const
-{
- // FIXME: Frame::isMainFrame() is probably better.
- return !m_renderView->document().ownerElement();
-}
-
-// IFrames are special, because we hook compositing layers together across iframe boundaries
-// when both parent and iframe content are composited. So when this frame becomes composited, we have
-// to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
-void RenderLayerCompositor::notifyIFramesOfCompositingChange()
-{
- if (!m_renderView->frameView())
- return;
- Frame& frame = m_renderView->frameView()->frame();
-
- for (Frame* child = frame.tree().firstChild(); child; child = child->tree().traverseNext(&frame)) {
- if (child->document() && child->document()->ownerElement())
- child->document()->ownerElement()->scheduleLayerUpdate();
- }
-
- // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
- // we need to schedule a style recalc in our parent document.
- if (HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement())
- ownerElement->scheduleLayerUpdate();
-}
-
-bool RenderLayerCompositor::layerHas3DContent(const RenderLayer* layer) const
-{
- const RenderStyle* style = layer->renderer()->style();
- RenderLayerStackingNode* stackingNode = const_cast<RenderLayer*>(layer)->stackingNode();
-
- if (style &&
- (style->transformStyle3D() == TransformStyle3DPreserve3D ||
- style->hasPerspective() ||
- style->transform().has3DOperation()))
- return true;
-
- stackingNode->updateLayerListsIfNeeded();
-
-#if !ASSERT_DISABLED
- LayerListMutationDetector mutationChecker(stackingNode);
-#endif
-
- RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
- while (RenderLayerStackingNode* curNode = iterator.next()) {
- if (layerHas3DContent(curNode->layer()))
- return true;
- }
-
- return false;
-}
-
-static bool isRootmostFixedOrStickyLayer(RenderLayer* layer)
-{
- if (layer->renderer()->isStickyPositioned())
- return true;
-
- if (layer->renderer()->style()->position() != FixedPosition)
- return false;
-
- for (RenderLayerStackingNode* stackingContainerNode = layer->stackingNode()->ancestorStackingContainerNode(); stackingContainerNode; stackingContainerNode = stackingContainerNode->ancestorStackingContainerNode()) {
- if (stackingContainerNode->layer()->hasCompositedLayerMapping() && stackingContainerNode->layer()->renderer()->style()->position() == FixedPosition)
- return false;
- }
-
- return true;
-}
-
-void RenderLayerCompositor::updateViewportConstraintStatus(RenderLayer* layer)
-{
- if (isRootmostFixedOrStickyLayer(layer))
- addViewportConstrainedLayer(layer);
- else
- removeViewportConstrainedLayer(layer);
-}
-
-void RenderLayerCompositor::addViewportConstrainedLayer(RenderLayer* layer)
-{
- m_viewportConstrainedLayers.add(layer);
-}
-
-void RenderLayerCompositor::removeViewportConstrainedLayer(RenderLayer* layer)
-{
- if (!m_viewportConstrainedLayers.contains(layer))
- return;
-
- m_viewportConstrainedLayers.remove(layer);
-}
-
-FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer* layer) const
-{
- ASSERT(layer->hasCompositedLayerMapping());
-
- FrameView* frameView = m_renderView->frameView();
- LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect();
-
- FixedPositionViewportConstraints constraints;
-
- GraphicsLayer* graphicsLayer = layer->compositedLayerMapping()->mainGraphicsLayer();
-
- constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
- constraints.setViewportRectAtLastLayout(viewportRect);
-
- RenderStyle* style = layer->renderer()->style();
- if (!style->left().isAuto())
- constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
-
- if (!style->right().isAuto())
- constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);
-
- if (!style->top().isAuto())
- constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
-
- if (!style->bottom().isAuto())
- constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);
-
- // If left and right are auto, use left.
- if (style->left().isAuto() && style->right().isAuto())
- constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
-
- // If top and bottom are auto, use top.
- if (style->top().isAuto() && style->bottom().isAuto())
- constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
-
- return constraints;
-}
-
-StickyPositionViewportConstraints RenderLayerCompositor::computeStickyViewportConstraints(RenderLayer* layer) const
-{
- ASSERT(layer->hasCompositedLayerMapping());
-
- FrameView* frameView = m_renderView->frameView();
- LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect();
-
- StickyPositionViewportConstraints constraints;
-
- RenderBoxModelObject* renderer = toRenderBoxModelObject(layer->renderer());
-
- renderer->computeStickyPositionConstraints(constraints, viewportRect);
-
- GraphicsLayer* graphicsLayer = layer->compositedLayerMapping()->mainGraphicsLayer();
-
- constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
- constraints.setStickyOffsetAtLastLayout(renderer->stickyPositionOffset());
-
- return constraints;
-}
-
-ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
-{
- if (Page* page = this->page())
- return page->scrollingCoordinator();
-
- return 0;
-}
-
-GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
-{
- if (Page* page = this->page())
- return page->chrome().client().graphicsLayerFactory();
- return 0;
-}
-
-Page* RenderLayerCompositor::page() const
-{
- return m_renderView->frameView()->frame().page();
-}
-
-String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
-{
- String name;
- if (graphicsLayer == m_rootContentLayer.get()) {
- name = "Content Root Layer";
-#if USE(RUBBER_BANDING)
- } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
- name = "Overhang Areas Shadow";
-#endif
- } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
- name = "Overflow Controls Host Layer";
- } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
- name = "Horizontal Scrollbar Layer";
- } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
- name = "Vertical Scrollbar Layer";
- } else if (graphicsLayer == m_layerForScrollCorner.get()) {
- name = "Scroll Corner Layer";
- } else if (graphicsLayer == m_containerLayer.get()) {
- name = "Frame Clipping Layer";
- } else if (graphicsLayer == m_scrollLayer.get()) {
- name = "Frame Scrolling Layer";
- } else {
- ASSERT_NOT_REACHED();
- }
-
- return name;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerCompositor.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerCompositor.h
deleted file mode 100644
index 162348c866c..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerCompositor.h
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef RenderLayerCompositor_h
-#define RenderLayerCompositor_h
-
-#include "core/page/ChromeClient.h"
-#include "core/rendering/RenderLayer.h"
-#include "platform/graphics/GraphicsLayerClient.h"
-#include "wtf/HashMap.h"
-
-namespace WebCore {
-
-class FixedPositionViewportConstraints;
-class GraphicsLayer;
-class RenderEmbeddedObject;
-class RenderLayerStackingNode;
-class RenderPart;
-class RenderVideo;
-class ScrollingCoordinator;
-class StickyPositionViewportConstraints;
-
-
-enum CompositingUpdateType {
- CompositingUpdateAfterStyleChange,
- CompositingUpdateAfterLayout,
- CompositingUpdateOnScroll,
- CompositingUpdateOnCompositedScroll,
- CompositingUpdateFinishAllDeferredWork
-};
-
-// RenderLayerCompositor manages the hierarchy of
-// composited RenderLayers. It determines which RenderLayers
-// become compositing, and creates and maintains a hierarchy of
-// GraphicsLayers based on the RenderLayer painting order.
-//
-// There is one RenderLayerCompositor per RenderView.
-
-class RenderLayerCompositor : public GraphicsLayerClient {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit RenderLayerCompositor(RenderView*);
- ~RenderLayerCompositor();
-
- // Return true if this RenderView is in "compositing mode" (i.e. has one or more
- // composited RenderLayers)
- bool inCompositingMode() const { return m_compositing; }
- // This will make a compositing layer at the root automatically, and hook up to
- // the native view/window system.
- void enableCompositingMode(bool enable = true);
-
- bool inForcedCompositingMode() const { return m_forceCompositingMode; }
-
- // Returns true if the accelerated compositing is enabled
- bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; }
- bool layerSquashingEnabled() const;
-
- bool canRender3DTransforms() const;
-
- // Copy the accelerated compositing related flags from Settings
- void cacheAcceleratedCompositingFlags();
-
- // Called when the layer hierarchy needs to be updated (compositing layers have been
- // created, destroyed or re-parented).
- void setCompositingLayersNeedRebuild(bool needRebuild = true);
- bool compositingLayersNeedRebuild() const { return m_compositingLayersNeedRebuild; }
-
- // Called when something outside WebKit affects the visible rect (e.g. delegated scrolling). Might schedule a layer flush.
- void didChangeVisibleRect();
-
- // Updating properties required for determining if compositing is necessary.
- void updateCompositingRequirementsState();
- void setNeedsUpdateCompositingRequirementsState() { m_needsUpdateCompositingRequirementsState = true; }
-
- // Main entry point for a full update. As needed, this function will compute compositing requirements,
- // rebuild the composited layer tree, and/or update all the properties assocaited with each layer of the
- // composited layer tree.
- void updateCompositingLayers(CompositingUpdateType);
-
- // Update the compositing state of the given layer. Returns true if that state changed.
- bool updateLayerCompositingState(RenderLayer*);
-
- // Update the geometry for compositing children of compositingAncestor.
- void updateCompositingDescendantGeometry(RenderLayerStackingNode* compositingAncestor, RenderLayer*, bool compositedChildrenOnly);
-
- // Whether layer's compositedLayerMapping needs a GraphicsLayer to do clipping by an ancestor (non-stacking-context parent with overflow).
- bool clippedByAncestor(const RenderLayer*) const;
- // Whether layer's compositedLayerMapping needs a GraphicsLayer to clip z-order children of the given RenderLayer.
- bool clipsCompositingDescendants(const RenderLayer*) const;
-
- // Whether the given layer needs an extra 'contents' layer.
- bool needsContentsCompositingLayer(const RenderLayer*) const;
-
- bool supportsFixedRootBackgroundCompositing() const;
- bool needsFixedRootBackgroundLayer(const RenderLayer*) const;
- GraphicsLayer* fixedRootBackgroundLayer() const;
-
- // Return the bounding box required for compositing layer and its childern, relative to ancestorLayer.
- // If layerBoundingBox is not 0, on return it contains the bounding box of this layer only.
- IntRect calculateCompositedBounds(const RenderLayer*, const RenderLayer* ancestorLayer) const;
-
- // Repaint the appropriate layers when the given RenderLayer starts or stops being composited.
- void repaintOnCompositingChange(RenderLayer*);
-
- void repaintInCompositedAncestor(RenderLayer*, const LayoutRect&);
-
- // Notify us that a layer has been added or removed
- void layerWasAdded(RenderLayer* parent, RenderLayer* child);
- void layerWillBeRemoved(RenderLayer* parent, RenderLayer* child);
-
- // Get the nearest ancestor layer that has overflow or clip, but is not a stacking context
- RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer* layer) const;
-
- // Repaint parts of all composited layers that intersect the given absolute rectangle (or the entire layer if the pointer is null).
- void repaintCompositedLayers(const IntRect* = 0);
-
- RenderLayer* rootRenderLayer() const;
- GraphicsLayer* rootGraphicsLayer() const;
- GraphicsLayer* scrollLayer() const;
-
- enum RootLayerAttachment {
- RootLayerUnattached,
- RootLayerAttachedViaChromeClient,
- RootLayerAttachedViaEnclosingFrame
- };
-
- RootLayerAttachment rootLayerAttachment() const { return m_rootLayerAttachment; }
- void updateRootLayerAttachment();
- void updateRootLayerPosition();
-
- void setIsInWindow(bool);
-
- void clearMappingForAllRenderLayers();
-
- // Use by RenderVideo to ask if it should try to use accelerated compositing.
- bool canAccelerateVideoRendering(RenderVideo*) const;
-
- // Walk the tree looking for layers with 3d transforms. Useful in case you need
- // to know if there is non-affine content, e.g. for drawing into an image.
- bool has3DContent() const;
-
- static RenderLayerCompositor* frameContentsCompositor(RenderPart*);
- // Return true if the layers changed.
- static bool parentFrameContentLayers(RenderPart*);
-
- // Update the geometry of the layers used for clipping and scrolling in frames.
- void frameViewDidChangeLocation(const IntPoint& contentsOffset);
- void frameViewDidChangeSize();
- void frameViewDidScroll();
- void frameViewDidLayout();
- void frameViewScrollbarsExistenceDidChange();
- void rootFixedBackgroundsChanged();
-
- bool scrollingLayerDidChange(RenderLayer*);
-
- String layerTreeAsText(LayerTreeFlags);
-
- virtual void didCommitChangesForLayer(const GraphicsLayer*) const OVERRIDE;
-
- GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
- GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
- GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
-
- void updateViewportConstraintStatus(RenderLayer*);
- void removeViewportConstrainedLayer(RenderLayer*);
-
- void addOutOfFlowPositionedLayer(RenderLayer*);
- void removeOutOfFlowPositionedLayer(RenderLayer*);
-
- void resetTrackedRepaintRects();
- void setTracksRepaints(bool);
-
- void setNeedsToRecomputeCompositingRequirements() { m_needsToRecomputeCompositingRequirements = true; }
-
- virtual String debugName(const GraphicsLayer*) OVERRIDE;
-
-private:
- class OverlapMap;
-
- // GraphicsLayerClient implementation
- virtual void notifyAnimationStarted(const GraphicsLayer*, double, double) OVERRIDE { }
- virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) OVERRIDE;
-
- virtual bool isTrackingRepaints() const OVERRIDE;
-
- // Whether the given RL needs to paint into its own separate backing (and hence would need its own CompositedLayerMapping).
- bool needsOwnBacking(const RenderLayer*) const;
- // Whether the layer could ever be composited.
- bool canBeComposited(const RenderLayer*) const;
-
- // Returns all direct reasons that a layer should be composited.
- CompositingReasons directReasonsForCompositing(const RenderLayer*) const;
-
- void updateDirectCompositingReasons(RenderLayer*);
-
- // Returns indirect reasons that a layer should be composited because of something in its subtree.
- CompositingReasons subtreeReasonsForCompositing(RenderObject*, bool hasCompositedDescendants, bool has3DTransformedDescendants) const;
-
- // Make or destroy the CompositedLayerMapping for this layer; returns true if the compositedLayerMapping changed.
- bool allocateOrClearCompositedLayerMapping(RenderLayer*);
-
- void clearMappingForRenderLayerIncludingDescendants(RenderLayer*);
-
- // Repaint the given rect (which is layer's coords), and regions of child layers that intersect that rect.
- void recursiveRepaintLayer(RenderLayer*, const IntRect* = 0);
-
- void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed);
- void addToOverlapMapRecursive(OverlapMap&, RenderLayer*, RenderLayer* ancestorLayer = 0);
-
- struct SquashingState {
- SquashingState()
- : mostRecentMapping(0)
- , hasMostRecentMapping(false)
- , nextSquashedLayerIndex(0) { }
-
- void updateSquashingStateForNewMapping(CompositedLayerMappingPtr, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsolute);
-
- // The most recent composited backing that the layer should squash onto if needed.
- CompositedLayerMappingPtr mostRecentMapping;
- bool hasMostRecentMapping;
-
- // Offset in absolute coordinates of the compositedLayerMapping's owning layer.
- IntPoint offsetFromAbsolute;
-
- // Counter that tracks what index the next RenderLayer would be if it gets squashed to the current squashing layer.
- size_t nextSquashedLayerIndex;
- };
-
- // Forces an update for all frames of frame tree recursively. Used only when the mainFrame compositor is ready to
- // finish all deferred work.
- static void finishCompositingUpdateForFrameTree(Frame*);
-
- // Returns true if any layer's compositing changed
- void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingRecursionData&, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants);
-
- // Defines which RenderLayers will paint into which composited backings, by allocating and destroying CompositedLayerMappings as needed.
- void assignLayersToBackings(RenderLayer*, bool& layersChanged);
- void assignLayersToBackingsInternal(RenderLayer*, SquashingState&, bool& layersChanged);
-
- // Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer.
- void rebuildCompositingLayerTree(RenderLayer*, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer, int depth);
-
- // Recurses down the tree, updating layer geometry only.
- void updateLayerTreeGeometry(RenderLayer*);
-
- // Hook compositing layers together
- void setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer);
- void removeCompositedChildren(RenderLayer*);
-
- bool layerHas3DContent(const RenderLayer*) const;
- bool isRunningAcceleratedTransformAnimation(RenderObject*) const;
-
- bool hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const;
-
- void ensureRootLayer();
- void destroyRootLayer();
-
- void attachRootLayer(RootLayerAttachment);
- void detachRootLayer();
-
- bool isMainFrame() const;
-
- void updateOverflowControlsLayers();
-
- void notifyIFramesOfCompositingChange();
-
- Page* page() const;
-
- GraphicsLayerFactory* graphicsLayerFactory() const;
- ScrollingCoordinator* scrollingCoordinator() const;
-
- // Whether a running transition or animation enforces the need for a compositing layer.
- bool requiresCompositingForAnimation(RenderObject*) const;
- // Whether a (not necessarily running) transition enforces the need for a compositing layer.
- bool requiresCompositingForTransition(RenderObject*) const;
- bool requiresCompositingForTransform(RenderObject*) const;
- bool requiresCompositingForVideo(RenderObject*) const;
- bool requiresCompositingForCanvas(RenderObject*) const;
- bool requiresCompositingForPlugin(RenderObject*) const;
- bool requiresCompositingForFrame(RenderObject*) const;
- bool requiresCompositingForBackfaceVisibilityHidden(RenderObject*) const;
- bool requiresCompositingForFilters(RenderObject*) const;
- bool requiresCompositingForOverflowScrollingParent(const RenderLayer*) const;
- bool requiresCompositingForOutOfFlowClipping(const RenderLayer*) const;
- bool requiresCompositingForScrollableFrame() const;
- bool requiresCompositingForPosition(RenderObject*, const RenderLayer*, RenderLayer::ViewportConstrainedNotCompositedReason* = 0) const;
- bool requiresCompositingForOverflowScrolling(const RenderLayer*) const;
-
- void addViewportConstrainedLayer(RenderLayer*);
-
- FixedPositionViewportConstraints computeFixedViewportConstraints(RenderLayer*) const;
- StickyPositionViewportConstraints computeStickyViewportConstraints(RenderLayer*) const;
-
- bool requiresHorizontalScrollbarLayer() const;
- bool requiresVerticalScrollbarLayer() const;
- bool requiresScrollCornerLayer() const;
-#if USE(RUBBER_BANDING)
- bool requiresOverhangLayers() const;
-#endif
-
-private:
- RenderView* m_renderView;
- OwnPtr<GraphicsLayer> m_rootContentLayer;
-
- bool m_hasAcceleratedCompositing;
- ChromeClient::CompositingTriggerFlags m_compositingTriggers;
-
- bool m_showRepaintCounter;
-
- // FIXME: This should absolutely not be mutable.
- mutable bool m_needsToRecomputeCompositingRequirements;
- bool m_needsToUpdateLayerTreeGeometry;
-
- bool m_compositing;
- bool m_compositingLayersNeedRebuild;
- bool m_forceCompositingMode;
- bool m_inPostLayoutUpdate; // true when it's OK to trust layout information (e.g. layer sizes and positions)
- bool m_needsUpdateCompositingRequirementsState;
-
- bool m_isTrackingRepaints; // Used for testing.
-
- RootLayerAttachment m_rootLayerAttachment;
-
- // Enclosing container layer, which clips for iframe content
- OwnPtr<GraphicsLayer> m_containerLayer;
- OwnPtr<GraphicsLayer> m_scrollLayer;
-
- HashSet<RenderLayer*> m_viewportConstrainedLayers;
- HashSet<RenderLayer*> m_viewportConstrainedLayersNeedingUpdate;
-
- // This is used in updateCompositingRequirementsState to avoid full tree
- // walks while determining if layers have unclipped descendants.
- HashSet<RenderLayer*> m_outOfFlowPositionedLayers;
-
- // Enclosing layer for overflow controls and the clipping layer
- OwnPtr<GraphicsLayer> m_overflowControlsHostLayer;
-
- // Layers for overflow controls
- OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
- OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
- OwnPtr<GraphicsLayer> m_layerForScrollCorner;
-#if USE(RUBBER_BANDING)
- OwnPtr<GraphicsLayer> m_layerForOverhangShadow;
-#endif
-};
-
-
-} // namespace WebCore
-
-#endif // RenderLayerCompositor_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp
index 600ced9e77a..1d0ff416d46 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp
@@ -39,8 +39,6 @@
#include "core/svg/SVGFilterElement.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "core/svg/graphics/filters/SVGFilter.h"
-#include "platform/graphics/filters/custom/CustomFilterOperation.h"
-#include "platform/graphics/filters/custom/CustomFilterProgram.h"
namespace WebCore {
@@ -95,7 +93,6 @@ RenderLayerFilterInfo::RenderLayerFilterInfo(RenderLayer* layer)
RenderLayerFilterInfo::~RenderLayerFilterInfo()
{
- removeCustomFilterClients();
removeReferenceFilterClients();
}
@@ -107,8 +104,12 @@ void RenderLayerFilterInfo::setRenderer(PassRefPtr<FilterEffectRenderer> rendere
void RenderLayerFilterInfo::notifyFinished(Resource*)
{
RenderObject* renderer = m_layer->renderer();
- toElement(renderer->node())->scheduleLayerUpdate();
- renderer->repaint();
+ // FIXME: This caller of scheduleSVGFilterLayerUpdateHack() is not correct. It's using the layer update
+ // system to trigger a RenderLayer to go through the filter updating logic, but that might not
+ // even happen if this element is style sharing and RenderObject::setStyle() returns early.
+ // Filters need to find a better way to hook into the system.
+ toElement(renderer->node())->scheduleSVGFilterLayerUpdateHack();
+ renderer->paintInvalidationForWholeRenderer();
}
void RenderLayerFilterInfo::updateReferenceFilterClients(const FilterOperations& operations)
@@ -130,7 +131,7 @@ void RenderLayerFilterInfo::updateReferenceFilterClients(const FilterOperations&
// Reference is internal; add layer as a client so we can trigger
// filter repaint on SVG attribute change.
Element* filter = m_layer->renderer()->node()->document().getElementById(referenceFilterOperation->fragment());
- if (!filter || !filter->hasTagName(SVGNames::filterTag))
+ if (!isSVGFilterElement(filter))
continue;
if (filter->renderer())
toRenderSVGResourceContainer(filter->renderer())->addClientRenderLayer(m_layer);
@@ -156,39 +157,5 @@ void RenderLayerFilterInfo::removeReferenceFilterClients()
m_internalSVGReferences.clear();
}
-void RenderLayerFilterInfo::notifyCustomFilterProgramLoaded(CustomFilterProgram*)
-{
- RenderObject* renderer = m_layer->renderer();
- toElement(renderer->node())->scheduleLayerUpdate();
- renderer->repaint();
-}
-
-void RenderLayerFilterInfo::updateCustomFilterClients(const FilterOperations& operations)
-{
- if (!operations.size()) {
- removeCustomFilterClients();
- return;
- }
- CustomFilterProgramList cachedCustomFilterPrograms;
- for (size_t i = 0; i < operations.size(); ++i) {
- const FilterOperation* filterOperation = operations.at(i);
- if (filterOperation->type() != FilterOperation::CUSTOM)
- continue;
- RefPtr<CustomFilterProgram> program = toCustomFilterOperation(filterOperation)->program();
- cachedCustomFilterPrograms.append(program);
- program->addClient(this);
- }
- // Remove the old clients here, after we've added the new ones, so that we don't flicker if some shaders are unchanged.
- removeCustomFilterClients();
- m_cachedCustomFilterPrograms.swap(cachedCustomFilterPrograms);
-}
-
-void RenderLayerFilterInfo::removeCustomFilterClients()
-{
- for (size_t i = 0; i < m_cachedCustomFilterPrograms.size(); ++i)
- m_cachedCustomFilterPrograms.at(i)->removeClient(this);
- m_cachedCustomFilterPrograms.clear();
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.h
index f982008fc55..4c84861c4b2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.h
@@ -34,7 +34,6 @@
#include "core/fetch/DocumentResource.h"
#include "platform/geometry/LayoutRect.h"
#include "platform/graphics/filters/FilterOperation.h"
-#include "platform/graphics/filters/custom/CustomFilterProgramClient.h"
#include "wtf/HashMap.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -48,7 +47,7 @@ class RenderLayerFilterInfo;
typedef HashMap<const RenderLayer*, RenderLayerFilterInfo*> RenderLayerFilterInfoMap;
-class RenderLayerFilterInfo : public CustomFilterProgramClient, public DocumentResourceClient {
+class RenderLayerFilterInfo FINAL : public DocumentResourceClient {
public:
static RenderLayerFilterInfo* filterInfoForRenderLayer(const RenderLayer*);
static RenderLayerFilterInfo* createFilterInfoForRenderLayerIfNeeded(RenderLayer*);
@@ -61,30 +60,21 @@ public:
FilterEffectRenderer* renderer() const { return m_renderer.get(); }
void setRenderer(PassRefPtr<FilterEffectRenderer>);
- // Implementation of the CustomFilterProgramClient interface.
- virtual void notifyCustomFilterProgramLoaded(CustomFilterProgram*);
-
- void updateCustomFilterClients(const FilterOperations&);
- void removeCustomFilterClients();
-
void updateReferenceFilterClients(const FilterOperations&);
- virtual void notifyFinished(Resource*);
+ virtual void notifyFinished(Resource*) OVERRIDE;
void removeReferenceFilterClients();
private:
RenderLayerFilterInfo(RenderLayer*);
- ~RenderLayerFilterInfo();
+ virtual ~RenderLayerFilterInfo();
RenderLayer* m_layer;
RefPtr<FilterEffectRenderer> m_renderer;
LayoutRect m_dirtySourceRect;
- typedef Vector<RefPtr<CustomFilterProgram> > CustomFilterProgramList;
- CustomFilterProgramList m_cachedCustomFilterPrograms;
-
static RenderLayerFilterInfoMap* s_filterMap;
- Vector<RefPtr<Element> > m_internalSVGReferences;
+ WillBePersistentHeapVector<RefPtrWillBeMember<Element> > m_internalSVGReferences;
Vector<ResourcePtr<DocumentResource> > m_externalSVGReferences;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp
index 801c0af5199..cb617a2e8a4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp
@@ -25,7 +25,7 @@
#include "config.h"
#include "core/rendering/RenderLayerModelObject.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
@@ -53,10 +53,10 @@ void RenderLayerModelObject::destroyLayer()
m_layer = nullptr;
}
-void RenderLayerModelObject::createLayer()
+void RenderLayerModelObject::createLayer(LayerType type)
{
ASSERT(!m_layer);
- m_layer = adoptPtr(new RenderLayer(this));
+ m_layer = adoptPtr(new RenderLayer(this, type));
setHasLayer(true);
m_layer->insertOnlyThisLayer();
}
@@ -75,7 +75,7 @@ void RenderLayerModelObject::willBeDestroyed()
{
if (isPositioned()) {
// Don't use this->view() because the document's renderView has been set to 0 during destruction.
- if (Frame* frame = this->frame()) {
+ if (LocalFrame* frame = this->frame()) {
if (FrameView* frameView = frame->view()) {
if (style()->hasViewportConstrainedPosition())
frameView->removeViewportConstrainedObject(this);
@@ -88,43 +88,29 @@ void RenderLayerModelObject::willBeDestroyed()
destroyLayer();
}
-void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
s_wasFloating = isFloating();
// If our z-index changes value or our visibility changes,
// we need to dirty our stacking context's z-order list.
RenderStyle* oldStyle = style();
- if (oldStyle && newStyle) {
- if (parent()) {
- // Do a repaint with the old style first, e.g., for example if we go from
- // having an outline to not having an outline.
- if (diff == StyleDifferenceRepaintLayer) {
- layer()->repainter().repaintIncludingDescendants();
- if (!(oldStyle->clip() == newStyle->clip()))
- layer()->clipper().clearClipRectsIncludingDescendants();
- } else if (diff == StyleDifferenceRepaint || newStyle->outlineSize() < oldStyle->outlineSize())
- repaint();
- }
-
- if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) {
- // When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could
- // end up being destroyed.
+ if (oldStyle) {
+ // Do a repaint with the old style first through RenderLayerRepainter.
+ // RenderObject::styleWillChange takes care of repainting objects without RenderLayers.
+ if (parent() && diff.needsRepaintLayer()) {
+ layer()->repainter().repaintIncludingNonCompositingDescendants();
+ if (oldStyle->hasClip() != newStyle.hasClip()
+ || oldStyle->clip() != newStyle.clip())
+ layer()->clipper().clearClipRectsIncludingDescendants();
+ } else if (diff.needsFullLayout()) {
if (hasLayer()) {
- if (oldStyle->position() != newStyle->position()
- || oldStyle->zIndex() != newStyle->zIndex()
- || oldStyle->hasAutoZIndex() != newStyle->hasAutoZIndex()
- || !(oldStyle->clip() == newStyle->clip())
- || oldStyle->hasClip() != newStyle->hasClip()
- || oldStyle->opacity() != newStyle->opacity()
- || oldStyle->transform() != newStyle->transform()
- || oldStyle->filter() != newStyle->filter()
- )
- layer()->repainter().repaintIncludingDescendants();
- } else if (newStyle->hasTransform() || newStyle->opacity() < 1 || newStyle->hasFilter()) {
+ if (!layer()->hasCompositedLayerMapping() && oldStyle->position() != newStyle.position())
+ layer()->repainter().repaintIncludingNonCompositingDescendants();
+ } else if (newStyle.hasTransform() || newStyle.opacity() < 1 || newStyle.hasFilter()) {
// If we don't have a layer yet, but we are going to get one because of transform or opacity,
// then we need to repaint the old position of the object.
- repaint();
+ paintInvalidationForWholeRenderer();
}
}
}
@@ -135,22 +121,27 @@ void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderS
void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
bool hadTransform = hasTransform();
- bool hadLayer = hasLayer();
- bool layerWasSelfPainting = hadLayer && layer()->isSelfPaintingLayer();
RenderObject::styleDidChange(diff, oldStyle);
updateFromStyle();
- if (requiresLayer()) {
+ LayerType type = layerTypeRequired();
+ if (type != NoLayer) {
if (!layer() && layerCreationAllowedForSubtree()) {
if (s_wasFloating && isFloating())
setChildNeedsLayout();
- createLayer();
+ createLayer(type);
if (parent() && !needsLayout() && containingBlock()) {
- layer()->repainter().setRepaintStatus(NeedsFullRepaint);
- // There is only one layer to update, it is not worth using |cachedOffset| since
- // we are not sure the value will be used.
- layer()->updateLayerPositions(0);
+ // FIXME: This invalidation is overly broad. We should update to
+ // do the correct invalidation at RenderStyle::diff time. crbug.com/349061
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ layer()->renderer()->setShouldDoFullPaintInvalidationAfterLayout(true);
+ else
+ layer()->repainter().setRepaintStatus(NeedsFullRepaint);
+ // Hit in animations/interpolation/perspective-interpolation.html
+ // FIXME: I suspect we can remove this assert disabler now.
+ DisableCompositingQueryAsserts disabler;
+ layer()->updateLayerPositionRecursive();
}
}
} else if (layer() && layer()->parent()) {
@@ -160,13 +151,14 @@ void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderSt
if (s_wasFloating && isFloating())
setChildNeedsLayout();
if (hadTransform)
- setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
if (layer()) {
+ // FIXME: Ideally we shouldn't need this setter but we can't easily infer an overflow-only layer
+ // from the style.
+ layer()->setLayerType(type);
layer()->styleChanged(diff, oldStyle);
- if (hadLayer && layer()->isSelfPaintingLayer() != layerWasSelfPainting)
- setChildNeedsLayout();
}
if (FrameView *frameView = view()->frameView()) {
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.h
index 4eb42633a7f..d3153e6217e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerModelObject.h
@@ -23,7 +23,7 @@
#ifndef RenderLayerModelObject_h
#define RenderLayerModelObject_h
-#include "core/rendering/CompositedLayerMappingPtr.h"
+#include "core/rendering/compositing/CompositedLayerMappingPtr.h"
#include "core/rendering/RenderObject.h"
namespace WebCore {
@@ -32,6 +32,15 @@ class RenderLayer;
class CompositedLayerMapping;
class ScrollableArea;
+enum LayerType {
+ NoLayer,
+ NormalLayer,
+ // A forced or overflow clip layer is required for bookkeeping purposes,
+ // but does not force a layer to be self painting.
+ OverflowClipLayer,
+ ForcedLayer
+};
+
class RenderLayerModelObject : public RenderObject {
public:
explicit RenderLayerModelObject(ContainerNode*);
@@ -44,11 +53,11 @@ public:
RenderLayer* layer() const { return m_layer.get(); }
ScrollableArea* scrollableArea() const;
- virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE;
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
virtual void updateFromStyle() { }
- virtual bool requiresLayer() const = 0;
+ virtual LayerType layerTypeRequired() const = 0;
// Returns true if the background is painted opaque in the given rect.
// The query rect is given in local coordinate system.
@@ -62,7 +71,7 @@ public:
CompositedLayerMapping* groupedMapping() const;
protected:
- void createLayer();
+ void createLayer(LayerType);
virtual void willBeDestroyed() OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp
index 38801bdbdc4..f6e2d9e5de3 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp
@@ -55,20 +55,20 @@
namespace WebCore {
-RenderLayerReflectionInfo::RenderLayerReflectionInfo(RenderBox* renderer)
- : m_renderer(renderer)
+RenderLayerReflectionInfo::RenderLayerReflectionInfo(RenderBox& renderer)
+ : m_box(renderer)
, m_isPaintingInsideReflection(false)
{
- UseCounter::count(m_renderer->document(), UseCounter::Reflection);
+ UseCounter::count(m_box.document(), UseCounter::Reflection);
- m_reflection = RenderReplica::createAnonymous(&(m_renderer->document()));
- m_reflection->setParent(m_renderer); // We create a 1-way connection.
+ m_reflection = RenderReplica::createAnonymous(&(m_box.document()));
+ m_reflection->setParent(&m_box); // We create a 1-way connection.
}
RenderLayerReflectionInfo::~RenderLayerReflectionInfo()
{
if (!m_reflection->documentBeingDestroyed())
- m_reflection->removeLayers(renderer()->layer());
+ m_reflection->removeLayers(m_box.layer());
m_reflection->setParent(0);
m_reflection->destroy();
@@ -84,16 +84,16 @@ RenderLayer* RenderLayerReflectionInfo::reflectionLayer() const
void RenderLayerReflectionInfo::updateAfterStyleChange(const RenderStyle* oldStyle)
{
RefPtr<RenderStyle> newStyle = RenderStyle::create();
- newStyle->inheritFrom(renderer()->style());
+ newStyle->inheritFrom(m_box.style());
// Map in our transform.
TransformOperations transform;
- switch (renderer()->style()->boxReflect()->direction()) {
+ switch (m_box.style()->boxReflect()->direction()) {
case ReflectionBelow:
transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
Length(100., Percent), TransformOperation::Translate));
transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
- renderer()->style()->boxReflect()->offset(), TransformOperation::Translate));
+ m_box.style()->boxReflect()->offset(), TransformOperation::Translate));
transform.operations().append(ScaleTransformOperation::create(1.0, -1.0, ScaleTransformOperation::Scale));
break;
@@ -102,14 +102,14 @@ void RenderLayerReflectionInfo::updateAfterStyleChange(const RenderStyle* oldSty
transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
Length(100., Percent), TransformOperation::Translate));
transform.operations().append(TranslateTransformOperation::create(Length(0, Fixed),
- renderer()->style()->boxReflect()->offset(), TransformOperation::Translate));
+ m_box.style()->boxReflect()->offset(), TransformOperation::Translate));
break;
case ReflectionRight:
transform.operations().append(TranslateTransformOperation::create(Length(100., Percent),
Length(0, Fixed), TransformOperation::Translate));
transform.operations().append(TranslateTransformOperation::create(
- renderer()->style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::Translate));
+ m_box.style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::Translate));
transform.operations().append(ScaleTransformOperation::create(-1.0, 1.0, ScaleTransformOperation::Scale));
break;
@@ -118,13 +118,13 @@ void RenderLayerReflectionInfo::updateAfterStyleChange(const RenderStyle* oldSty
transform.operations().append(TranslateTransformOperation::create(Length(100., Percent),
Length(0, Fixed), TransformOperation::Translate));
transform.operations().append(TranslateTransformOperation::create(
- renderer()->style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::Translate));
+ m_box.style()->boxReflect()->offset(), Length(0, Fixed), TransformOperation::Translate));
break;
}
newStyle->setTransform(transform);
// Map in our mask.
- newStyle->setMaskBoxImage(renderer()->style()->boxReflect()->mask());
+ newStyle->setMaskBoxImage(m_box.style()->boxReflect()->mask());
m_reflection->setStyle(newStyle.release());
}
@@ -142,7 +142,7 @@ void RenderLayerReflectionInfo::paint(GraphicsContext* context, const LayerPaint
String RenderLayerReflectionInfo::debugName() const
{
- return renderer()->debugName() + " (reflection)";
+ return m_box.debugName() + " (reflection)";
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.h
index 90ec7898acf..83009eb0b91 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.h
@@ -57,7 +57,7 @@ class RenderReplica;
class RenderLayerReflectionInfo {
WTF_MAKE_NONCOPYABLE(RenderLayerReflectionInfo);
public:
- explicit RenderLayerReflectionInfo(RenderBox*);
+ explicit RenderLayerReflectionInfo(RenderBox&);
~RenderLayerReflectionInfo();
RenderReplica* reflection() const { return m_reflection; }
@@ -72,9 +72,7 @@ public:
String debugName() const;
private:
- RenderBox* renderer() const { return m_renderer; }
-
- RenderBox* m_renderer;
+ RenderBox& m_box;
RenderReplica* m_reflection;
// A state bit tracking if we are painting inside a replica.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.cpp
index 77da5c125d9..d502c3cf52c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.cpp
@@ -44,44 +44,49 @@
#include "config.h"
#include "core/rendering/RenderLayerRepainter.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/FilterEffectRenderer.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
namespace WebCore {
-RenderLayerRepainter::RenderLayerRepainter(RenderLayerModelObject* renderer)
+RenderLayerRepainter::RenderLayerRepainter(RenderLayerModelObject& renderer)
: m_renderer(renderer)
, m_repaintStatus(NeedsNormalRepaint)
{
}
-void RenderLayerRepainter::repaintAfterLayout(RenderGeometryMap* geometryMap, bool shouldCheckForRepaint)
+void RenderLayerRepainter::repaintAfterLayout(bool shouldCheckForRepaint)
{
- if (m_renderer->layer()->hasVisibleContent()) {
- RenderView* view = m_renderer->view();
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ return;
+
+ // FIXME: really, we're in the repaint phase here, and the following queries are legal.
+ // Until those states are fully fledged, I'll just disable the ASSERTS.
+ DisableCompositingQueryAsserts disabler;
+ if (m_renderer.layer()->hasVisibleContent()) {
+ RenderView* view = m_renderer.view();
ASSERT(view);
// FIXME: LayoutState does not work with RenderLayers as there is not a 1-to-1
// mapping between them and the RenderObjects. It would be neat to enable
// LayoutState outside the layout() phase and use it here.
- ASSERT(!view->layoutStateEnabled());
+ ASSERT(!view->layoutStateCachedOffsetsEnabled());
- RenderLayerModelObject* repaintContainer = m_renderer->containerForRepaint();
+ const RenderLayerModelObject* repaintContainer = m_renderer.containerForPaintInvalidation();
LayoutRect oldRepaintRect = m_repaintRect;
- LayoutRect oldOutlineBox = m_outlineBox;
- computeRepaintRects(repaintContainer, geometryMap);
+ LayoutPoint oldOffset = m_offset;
+ computeRepaintRects();
+ shouldCheckForRepaint &= shouldRepaintLayer();
- // FIXME: Should ASSERT that value calculated for m_outlineBox using the cached offset is the same
- // as the value not using the cached offset, but we can't due to https://bugs.webkit.org/show_bug.cgi?id=37048
if (shouldCheckForRepaint) {
if (view && !view->document().printing()) {
if (m_repaintStatus & NeedsFullRepaint) {
- m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldRepaintRect));
+ m_renderer.invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldRepaintRect), InvalidationLayer);
if (m_repaintRect != oldRepaintRect)
- m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect));
- } else if (shouldRepaintAfterLayout()) {
- m_renderer->repaintAfterLayoutIfNeeded(repaintContainer, m_renderer->selfNeedsLayout(), oldRepaintRect, oldOutlineBox, &m_repaintRect, &m_outlineBox);
+ m_renderer.invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect), InvalidationLayer);
+ } else {
+ m_renderer.invalidatePaintAfterLayoutIfNeeded(repaintContainer, m_renderer.selfNeedsLayout(), oldRepaintRect, oldOffset, &m_repaintRect, &m_offset);
}
}
}
@@ -95,57 +100,83 @@ void RenderLayerRepainter::repaintAfterLayout(RenderGeometryMap* geometryMap, bo
void RenderLayerRepainter::clearRepaintRects()
{
- ASSERT(!m_renderer->layer()->hasVisibleContent());
+ ASSERT(!m_renderer.layer()->hasVisibleContent());
m_repaintRect = IntRect();
- m_outlineBox = IntRect();
}
-void RenderLayerRepainter::computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap)
+void RenderLayerRepainter::computeRepaintRects()
{
- m_repaintRect = m_renderer->clippedOverflowRectForRepaint(repaintContainer);
- m_outlineBox = m_renderer->outlineBoundsForRepaint(repaintContainer, geometryMap);
+ const RenderLayerModelObject* repaintContainer = m_renderer.containerForPaintInvalidation();
+ LayoutRect repaintRect = m_renderer.boundsRectForPaintInvalidation(repaintContainer);
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ // FIXME: We want RenderLayerRepainter to go away when
+ // repaint-after-layout is on by default so we need to figure out how to
+ // handle this update.
+ m_renderer.setPreviousPaintInvalidationRect(repaintRect);
+ } else {
+ m_repaintRect = repaintRect;
+ m_offset = RenderLayer::positionFromPaintInvalidationContainer(&m_renderer, repaintContainer);
+ }
}
-void RenderLayerRepainter::computeRepaintRectsIncludingDescendants()
+void RenderLayerRepainter::computeRepaintRectsIncludingNonCompositingDescendants()
{
// FIXME: computeRepaintRects() has to walk up the parent chain for every layer to compute the rects.
// We should make this more efficient.
// FIXME: it's wrong to call this when layout is not up-to-date, which we do.
- computeRepaintRects(m_renderer->containerForRepaint());
+ computeRepaintRects();
- for (RenderLayer* layer = m_renderer->layer()->firstChild(); layer; layer = layer->nextSibling())
- layer->repainter().computeRepaintRectsIncludingDescendants();
+ for (RenderLayer* layer = m_renderer.layer()->firstChild(); layer; layer = layer->nextSibling()) {
+ if (layer->compositingState() != PaintsIntoOwnBacking && layer->compositingState() != PaintsIntoGroupedBacking)
+ layer->repainter().computeRepaintRectsIncludingNonCompositingDescendants();
+ }
}
-inline bool RenderLayerRepainter::shouldRepaintAfterLayout() const
+inline bool RenderLayerRepainter::shouldRepaintLayer() const
{
- if (m_repaintStatus == NeedsNormalRepaint)
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ return false;
+
+ if (m_repaintStatus != NeedsFullRepaintForPositionedMovementLayout)
return true;
// Composited layers that were moved during a positioned movement only
// layout, don't need to be repainted. They just need to be recomposited.
- ASSERT(m_repaintStatus == NeedsFullRepaintForPositionedMovementLayout);
- return m_renderer->compositingState() != PaintsIntoOwnBacking;
+ return m_renderer.compositingState() != PaintsIntoOwnBacking;
}
// Since we're only painting non-composited layers, we know that they all share the same repaintContainer.
-void RenderLayerRepainter::repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer)
+void RenderLayerRepainter::repaintIncludingNonCompositingDescendants()
{
- m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_renderer->clippedOverflowRectForRepaint(repaintContainer)));
+ repaintIncludingNonCompositingDescendantsInternal(m_renderer.containerForPaintInvalidation());
+}
- for (RenderLayer* curr = m_renderer->layer()->firstChild(); curr; curr = curr->nextSibling()) {
- if (!curr->hasCompositedLayerMapping())
- curr->repainter().repaintIncludingNonCompositingDescendants(repaintContainer);
+void RenderLayerRepainter::repaintIncludingNonCompositingDescendantsInternal(const RenderLayerModelObject* repaintContainer)
+{
+ m_renderer.invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_renderer.boundsRectForPaintInvalidation(repaintContainer)), InvalidationLayer);
+
+ // FIXME: Repaints can be issued during style recalc at present, via RenderLayerModelObject::styleWillChange. This happens in scenarios when
+ // repaint is needed but not layout.
+ DisableCompositingQueryAsserts disabler;
+
+ for (RenderLayer* curr = m_renderer.layer()->firstChild(); curr; curr = curr->nextSibling()) {
+ if (curr->compositingState() != PaintsIntoOwnBacking && curr->compositingState() != PaintsIntoGroupedBacking)
+ curr->repainter().repaintIncludingNonCompositingDescendantsInternal(repaintContainer);
}
}
LayoutRect RenderLayerRepainter::repaintRectIncludingNonCompositingDescendants() const
{
- LayoutRect repaintRect = m_repaintRect;
- for (RenderLayer* child = m_renderer->layer()->firstChild(); child; child = child->nextSibling()) {
+ LayoutRect repaintRect;
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ repaintRect = m_renderer.previousPaintInvalidationRect();
+ else
+ repaintRect = m_repaintRect;
+
+ for (RenderLayer* child = m_renderer.layer()->firstChild(); child; child = child->nextSibling()) {
// Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
- if (child->hasCompositedLayerMapping())
+ if (child->compositingState() == PaintsIntoOwnBacking || child->compositingState() == PaintsIntoGroupedBacking)
continue;
repaintRect.unite(child->repainter().repaintRectIncludingNonCompositingDescendants());
@@ -153,80 +184,55 @@ LayoutRect RenderLayerRepainter::repaintRectIncludingNonCompositingDescendants()
return repaintRect;
}
-void RenderLayerRepainter::setBackingNeedsRepaint()
-{
- ASSERT(m_renderer->compositingState() != NotComposited);
-
- if (m_renderer->compositingState() == PaintsIntoGroupedBacking) {
- // FIXME: should probably setNeedsDisplayInRect for this layer's bounds only.
- m_renderer->groupedMapping()->squashingLayer()->setNeedsDisplay();
- } else {
- m_renderer->compositedLayerMapping()->setContentsNeedDisplay();
- }
-}
-
void RenderLayerRepainter::setBackingNeedsRepaintInRect(const LayoutRect& r)
{
// https://bugs.webkit.org/show_bug.cgi?id=61159 describes an unreproducible crash here,
// so assert but check that the layer is composited.
- ASSERT(m_renderer->compositingState() != NotComposited);
- if (m_renderer->compositingState() == NotComposited) {
+ ASSERT(m_renderer.compositingState() != NotComposited);
+ if (m_renderer.compositingState() == NotComposited) {
// If we're trying to repaint the placeholder document layer, propagate the
// repaint to the native view system.
LayoutRect absRect(r);
LayoutPoint delta;
- m_renderer->layer()->convertToLayerCoords(m_renderer->layer()->root(), delta);
+ m_renderer.layer()->convertToLayerCoords(m_renderer.layer()->root(), delta);
absRect.moveBy(delta);
- RenderView* view = m_renderer->view();
+ if (absRect.isEmpty())
+ return;
+
+ RenderView* view = m_renderer.view();
if (view)
view->repaintViewRectangle(absRect);
+ return;
+ }
+ IntRect repaintRect = pixelSnappedIntRect(r);
+ // FIXME: generalize accessors to backing GraphicsLayers so that this code is squashing-agnostic.
+ if (m_renderer.groupedMapping()) {
+ if (GraphicsLayer* squashingLayer = m_renderer.groupedMapping()->squashingLayer())
+ squashingLayer->setNeedsDisplayInRect(repaintRect);
} else {
- if (m_renderer->compositingState() == PaintsIntoGroupedBacking) {
- // FIXME: LayoutRect rounding to IntRect is probably not a good idea.
- IntRect offsetRect = pixelSnappedIntRect(r);
- if (m_renderer->hasTransform())
- offsetRect = m_renderer->layer()->transform()->mapRect(pixelSnappedIntRect(r));
-
- offsetRect.move(-m_renderer->layer()->offsetFromSquashingLayerOrigin());
- m_renderer->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(offsetRect);
- } else {
- m_renderer->compositedLayerMapping()->setContentsNeedDisplayInRect(pixelSnappedIntRect(r));
- }
+ m_renderer.compositedLayerMapping()->setContentsNeedDisplayInRect(repaintRect);
}
}
-void RenderLayerRepainter::repaintIncludingDescendants()
-{
- m_renderer->repaint();
- for (RenderLayer* curr = m_renderer->layer()->firstChild(); curr; curr = curr->nextSibling())
- curr->repainter().repaintIncludingDescendants();
-}
-
void RenderLayerRepainter::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect)
{
if (rect.isEmpty())
return;
-
LayoutRect rectForRepaint = rect;
- m_renderer->style()->filterOutsets().expandRect(rectForRepaint);
+ m_renderer.style()->filterOutsets().expandRect(rectForRepaint);
- RenderLayerFilterInfo* filterInfo = m_renderer->layer()->filterInfo();
+ RenderLayerFilterInfo* filterInfo = m_renderer.layer()->filterInfo();
ASSERT(filterInfo);
filterInfo->expandDirtySourceRect(rectForRepaint);
- ASSERT(filterInfo->renderer());
- if (filterInfo->renderer()->hasCustomShaderFilter()) {
- // If we have at least one custom shader, we need to update the whole bounding box of the layer, because the
- // shader can address any ouput pixel.
- // Note: This is only for output rect, so there's no need to expand the dirty source rect.
- rectForRepaint.unite(m_renderer->layer()->calculateLayerBounds(m_renderer->layer()));
- }
-
RenderLayer* parentLayer = enclosingFilterRepaintLayer();
ASSERT(parentLayer);
FloatQuad repaintQuad(rectForRepaint);
- LayoutRect parentLayerRect = m_renderer->localToContainerQuad(repaintQuad, parentLayer->renderer()).enclosingBoundingBox();
+ LayoutRect parentLayerRect = m_renderer.localToContainerQuad(repaintQuad, parentLayer->renderer()).enclosingBoundingBox();
+
+ if (parentLayerRect.isEmpty())
+ return;
if (parentLayer->hasCompositedLayerMapping()) {
parentLayer->repainter().setBackingNeedsRepaintInRect(parentLayerRect);
@@ -249,8 +255,8 @@ void RenderLayerRepainter::setFilterBackendNeedsRepaintingInRect(const LayoutRec
RenderLayer* RenderLayerRepainter::enclosingFilterRepaintLayer() const
{
- for (const RenderLayer* curr = m_renderer->layer(); curr; curr = curr->parent()) {
- if ((curr != m_renderer->layer() && curr->requiresFullLayerImageForFilters()) || curr->compositingState() == PaintsIntoOwnBacking || curr->isRootLayer())
+ for (const RenderLayer* curr = m_renderer.layer(); curr; curr = curr->parent()) {
+ if ((curr != m_renderer.layer() && curr->requiresFullLayerImageForFilters()) || curr->compositingState() == PaintsIntoOwnBacking || curr->isRootLayer())
return const_cast<RenderLayer*>(curr);
}
return 0;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.h
index ffc08ee8947..b55d89d0ffd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerRepainter.h
@@ -53,51 +53,50 @@ namespace WebCore {
enum RepaintStatus {
NeedsNormalRepaint = 0,
NeedsFullRepaint = 1 << 0,
- NeedsFullRepaintForPositionedMovementLayout = 1 << 1
+ NeedsFullRepaintForPositionedMovementLayout = NeedsFullRepaint | 1 << 1
};
-class RenderGeometryMap;
class RenderLayer;
class RenderLayerModelObject;
class RenderLayerRepainter {
WTF_MAKE_NONCOPYABLE(RenderLayerRepainter);
public:
- RenderLayerRepainter(RenderLayerModelObject*);
+ RenderLayerRepainter(RenderLayerModelObject&);
- // Return a cached repaint rect, computed relative to the layer renderer's containerForRepaint.
+ // Return a cached repaint rect, computed relative to the layer renderer's containerForPaintInvalidation.
LayoutRect repaintRect() const { return m_repaintRect; }
LayoutRect repaintRectIncludingNonCompositingDescendants() const;
- void repaintAfterLayout(RenderGeometryMap*, bool shouldCheckForRepaint);
- void repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer);
- void repaintIncludingDescendants();
+ void repaintAfterLayout(bool shouldCheckForRepaint);
+ void repaintIncludingNonCompositingDescendants();
void setRepaintStatus(RepaintStatus status) { m_repaintStatus = status; }
- void computeRepaintRects(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* = 0);
- void computeRepaintRectsIncludingDescendants();
+ void computeRepaintRects();
+ void computeRepaintRectsIncludingNonCompositingDescendants();
// Indicate that the layer contents need to be repainted. Only has an effect
// if layer compositing is being used,
- void setBackingNeedsRepaint();
void setBackingNeedsRepaintInRect(const LayoutRect&); // r is in the coordinate space of the layer's render object
void setFilterBackendNeedsRepaintingInRect(const LayoutRect&);
private:
- bool shouldRepaintAfterLayout() const;
+ void repaintIncludingNonCompositingDescendantsInternal(const RenderLayerModelObject* repaintContainer);
+
+ bool shouldRepaintLayer() const;
void clearRepaintRects();
RenderLayer* enclosingFilterRepaintLayer() const;
- RenderLayerModelObject* m_renderer;
+ RenderLayerModelObject& m_renderer;
unsigned m_repaintStatus; // RepaintStatus
LayoutRect m_repaintRect; // Cached repaint rects. Used by layout.
- LayoutRect m_outlineBox;
+ LayoutPoint m_offset;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp
index 0486111467d..b9512464833 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.cpp
@@ -47,20 +47,21 @@
#include "core/css/PseudoStyleRequest.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/FrameSelection.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/page/EventHandler.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/RenderGeometryMap.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/RenderScrollbarPart.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "platform/PlatformGestureEvent.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
@@ -73,21 +74,18 @@ namespace WebCore {
const int ResizerControlExpandRatioForTouch = 2;
-RenderLayerScrollableArea::RenderLayerScrollableArea(RenderBox* box)
- : m_box(box)
+RenderLayerScrollableArea::RenderLayerScrollableArea(RenderLayer& layer)
+ : m_layer(layer)
, m_inResizeMode(false)
+ , m_scrollsOverflow(false)
, m_scrollDimensionsDirty(true)
, m_inOverflowRelayout(false)
- , m_needsCompositedScrolling(false)
- , m_willUseCompositedScrollingHasBeenRecorded(false)
- , m_isScrollableAreaHasBeenRecorded(false)
- , m_forceNeedsCompositedScrolling(DoNotForceCompositedScrolling)
, m_scrollCorner(0)
, m_resizer(0)
{
ScrollableArea::setConstrainsScrollingToContentEdge(false);
- Node* node = m_box->node();
+ Node* node = box().node();
if (node && node->isElementNode()) {
// We save and restore only the scrollOffset as the other scroll values are recalculated.
Element* element = toElement(node);
@@ -102,31 +100,31 @@ RenderLayerScrollableArea::RenderLayerScrollableArea(RenderBox* box)
RenderLayerScrollableArea::~RenderLayerScrollableArea()
{
- if (inResizeMode() && !m_box->documentBeingDestroyed()) {
- if (Frame* frame = m_box->frame())
+ if (inResizeMode() && !box().documentBeingDestroyed()) {
+ if (LocalFrame* frame = box().frame())
frame->eventHandler().resizeScrollableAreaDestroyed();
}
- if (Frame* frame = m_box->frame()) {
+ if (LocalFrame* frame = box().frame()) {
if (FrameView* frameView = frame->view()) {
frameView->removeScrollableArea(this);
}
}
- if (m_box->frame() && m_box->frame()->page()) {
- if (ScrollingCoordinator* scrollingCoordinator = m_box->frame()->page()->scrollingCoordinator())
+ if (box().frame() && box().frame()->page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = box().frame()->page()->scrollingCoordinator())
scrollingCoordinator->willDestroyScrollableArea(this);
}
- if (!m_box->documentBeingDestroyed()) {
- Node* node = m_box->node();
+ if (!box().documentBeingDestroyed()) {
+ Node* node = box().node();
if (node && node->isElementNode())
toElement(node)->setSavedLayerScrollOffset(m_scrollOffset);
}
- if (Frame* frame = m_box->frame()) {
+ if (LocalFrame* frame = box().frame()) {
if (FrameView* frameView = frame->view())
- frameView->removeResizerArea(m_box);
+ frameView->removeResizerArea(box());
}
destroyScrollbar(HorizontalScrollbar);
@@ -138,38 +136,40 @@ RenderLayerScrollableArea::~RenderLayerScrollableArea()
m_resizer->destroy();
}
-ScrollableArea* RenderLayerScrollableArea::enclosingScrollableArea() const
-{
- if (RenderBox* enclosingScrollableBox = m_box->enclosingScrollableBox())
- return enclosingScrollableBox->layer()->scrollableArea();
-
- // FIXME: We should return the frame view here (or possibly an ancestor frame view,
- // if the frame view isn't scrollable.
- return 0;
-}
-
GraphicsLayer* RenderLayerScrollableArea::layerForScrolling() const
{
- return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->scrollingContentsLayer() : 0;
+ return box().hasCompositedLayerMapping() ? box().compositedLayerMapping()->scrollingContentsLayer() : 0;
}
GraphicsLayer* RenderLayerScrollableArea::layerForHorizontalScrollbar() const
{
- return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForHorizontalScrollbar() : 0;
+ // See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
+ return box().hasCompositedLayerMapping() ? box().compositedLayerMapping()->layerForHorizontalScrollbar() : 0;
}
GraphicsLayer* RenderLayerScrollableArea::layerForVerticalScrollbar() const
{
- return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForVerticalScrollbar() : 0;
+ // See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
+ return box().hasCompositedLayerMapping() ? box().compositedLayerMapping()->layerForVerticalScrollbar() : 0;
}
GraphicsLayer* RenderLayerScrollableArea::layerForScrollCorner() const
{
- return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForScrollCorner() : 0;
+ // See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
+ return box().hasCompositedLayerMapping() ? box().compositedLayerMapping()->layerForScrollCorner() : 0;
}
void RenderLayerScrollableArea::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
{
+ // See crbug.com/343132.
+ DisableCompositingQueryAsserts disabler;
+
if (scrollbar == m_vBar.get()) {
if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
layer->setNeedsDisplayInRect(rect);
@@ -184,14 +184,34 @@ void RenderLayerScrollableArea::invalidateScrollbarRect(Scrollbar* scrollbar, co
IntRect scrollRect = rect;
// If we are not yet inserted into the tree, there is no need to repaint.
- if (!m_box->parent())
+ if (!box().parent())
return;
if (scrollbar == m_vBar.get())
- scrollRect.move(verticalScrollbarStart(0, m_box->width()), m_box->borderTop());
+ scrollRect.move(verticalScrollbarStart(0, box().width()), box().borderTop());
else
- scrollRect.move(horizontalScrollbarStart(0), m_box->height() - m_box->borderBottom() - scrollbar->height());
- m_box->repaintRectangle(scrollRect);
+ scrollRect.move(horizontalScrollbarStart(0), box().height() - box().borderBottom() - scrollbar->height());
+
+ if (scrollRect.isEmpty())
+ return;
+
+ LayoutRect repaintRect = scrollRect;
+ box().flipForWritingMode(repaintRect);
+
+ IntRect intRect = pixelSnappedIntRect(repaintRect);
+
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && box().frameView()->isInPerformLayout()) {
+ if (scrollbar == m_vBar.get()) {
+ m_verticalBarDamage = intRect;
+ m_hasVerticalBarDamage = true;
+ } else {
+ m_horizontalBarDamage = intRect;
+ m_hasHorizontalBarDamage = true;
+ }
+
+ } else {
+ box().invalidatePaintRectangle(intRect);
+ }
}
void RenderLayerScrollableArea::invalidateScrollCornerRect(const IntRect& rect)
@@ -202,14 +222,14 @@ void RenderLayerScrollableArea::invalidateScrollCornerRect(const IntRect& rect)
}
if (m_scrollCorner)
- m_scrollCorner->repaintRectangle(rect);
+ m_scrollCorner->invalidatePaintRectangle(rect);
if (m_resizer)
- m_resizer->repaintRectangle(rect);
+ m_resizer->invalidatePaintRectangle(rect);
}
bool RenderLayerScrollableArea::isActive() const
{
- Page* page = m_box->frame()->page();
+ Page* page = box().frame()->page();
return page && page->focusController().isActive();
}
@@ -258,53 +278,53 @@ IntRect RenderLayerScrollableArea::scrollCornerRect() const
// (b) Both scrollbars are present.
bool hasHorizontalBar = horizontalScrollbar();
bool hasVerticalBar = verticalScrollbar();
- bool hasResizer = m_box->style()->resize() != RESIZE_NONE;
+ bool hasResizer = box().style()->resize() != RESIZE_NONE;
if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
- return cornerRect(m_box->style(), horizontalScrollbar(), verticalScrollbar(), m_box->pixelSnappedBorderBoxRect());
+ return cornerRect(box().style(), horizontalScrollbar(), verticalScrollbar(), box().pixelSnappedBorderBoxRect());
return IntRect();
}
IntRect RenderLayerScrollableArea::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return scrollbarRect;
IntRect rect = scrollbarRect;
rect.move(scrollbarOffset(scrollbar));
- return view->frameView()->convertFromRenderer(m_box, rect);
+ return view->frameView()->convertFromRenderer(box(), rect);
}
IntRect RenderLayerScrollableArea::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return parentRect;
- IntRect rect = view->frameView()->convertToRenderer(m_box, parentRect);
+ IntRect rect = view->frameView()->convertToRenderer(box(), parentRect);
rect.move(-scrollbarOffset(scrollbar));
return rect;
}
IntPoint RenderLayerScrollableArea::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return scrollbarPoint;
IntPoint point = scrollbarPoint;
point.move(scrollbarOffset(scrollbar));
- return view->frameView()->convertFromRenderer(m_box, point);
+ return view->frameView()->convertFromRenderer(box(), point);
}
IntPoint RenderLayerScrollableArea::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return parentPoint;
- IntPoint point = view->frameView()->convertToRenderer(m_box, parentPoint);
+ IntPoint point = view->frameView()->convertToRenderer(box(), parentPoint);
point.move(-scrollbarOffset(scrollbar));
return point;
@@ -318,7 +338,7 @@ int RenderLayerScrollableArea::scrollSize(ScrollbarOrientation orientation) cons
void RenderLayerScrollableArea::setScrollOffset(const IntPoint& newScrollOffset)
{
- if (!m_box->isMarquee()) {
+ if (!box().isMarquee()) {
// Ensure that the dimensions will be computed if they need to be (for overflow:hidden blocks).
if (m_scrollDimensionsDirty)
computeScrollDimensions();
@@ -329,62 +349,77 @@ void RenderLayerScrollableArea::setScrollOffset(const IntPoint& newScrollOffset)
setScrollOffset(toIntSize(newScrollOffset));
- Frame* frame = m_box->frame();
- InspectorInstrumentation::willScrollLayer(m_box);
+ LocalFrame* frame = box().frame();
+ ASSERT(frame);
- RenderView* view = m_box->view();
+ RefPtr<FrameView> frameView = box().frameView();
- // We should have a RenderView if we're trying to scroll.
- ASSERT(view);
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "ScrollLayer", "data", InspectorScrollLayerEvent::data(&box()));
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::willScrollLayer(&box());
// Update the positions of our child layers (if needed as only fixed layers should be impacted by a scroll).
// We don't update compositing layers, because we need to do a deep update from the compositing ancestor.
- bool inLayout = view ? view->frameView()->isInLayout() : false;
- if (!inLayout) {
+ if (!frameView->isInPerformLayout()) {
// If we're in the middle of layout, we'll just update layers once layout has finished.
layer()->updateLayerPositionsAfterOverflowScroll();
- if (view) {
- // Update regions, scrolling may change the clip of a particular region.
- view->frameView()->updateAnnotatedRegions();
- view->updateWidgetPositions();
- }
-
+ // Update regions, scrolling may change the clip of a particular region.
+ frameView->updateAnnotatedRegions();
+ // FIXME: We shouldn't call updateWidgetPositions() here since it might tear down the render tree,
+ // for now we just crash to avoid allowing an attacker to use after free.
+ frameView->updateWidgetPositions();
+ RELEASE_ASSERT(frameView->renderView());
updateCompositingLayersAfterScroll();
}
- RenderLayerModelObject* repaintContainer = m_box->containerForRepaint();
- if (frame) {
- // The caret rect needs to be invalidated after scrolling
- frame->selection().setCaretRectNeedsUpdate();
+ const RenderLayerModelObject* repaintContainer = box().containerForPaintInvalidation();
+ // The caret rect needs to be invalidated after scrolling
+ frame->selection().setCaretRectNeedsUpdate();
- FloatQuad quadForFakeMouseMoveEvent = FloatQuad(layer()->repainter().repaintRect());
- if (repaintContainer)
- quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
- frame->eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
- }
+ FloatQuad quadForFakeMouseMoveEvent;
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ quadForFakeMouseMoveEvent = FloatQuad(layer()->renderer()->previousPaintInvalidationRect());
+ else
+ quadForFakeMouseMoveEvent = FloatQuad(layer()->repainter().repaintRect());
+
+ quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent);
+ frame->eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
bool requiresRepaint = true;
- if (m_box->view()->compositor()->inCompositingMode()) {
+ if (box().view()->compositor()->inCompositingMode()) {
+ // Hits in virtual/gpu/fast/canvas/canvas-scroll-path-into-view.html.
+ DisableCompositingQueryAsserts disabler;
bool onlyScrolledCompositedLayers = scrollsOverflow()
&& !layer()->hasVisibleNonLayerContent()
&& !layer()->hasNonCompositedChild()
&& !layer()->hasBlockSelectionGapBounds()
- && !m_box->isMarquee();
+ && !box().isMarquee();
if (usesCompositedScrolling() || onlyScrolledCompositedLayers)
requiresRepaint = false;
}
// Just schedule a full repaint of our object.
- if (view && requiresRepaint)
- m_box->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(layer()->repainter().repaintRect()));
+ if (requiresRepaint) {
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ if (box().frameView()->isInPerformLayout())
+ box().setShouldDoFullPaintInvalidationAfterLayout(true);
+ else
+ box().invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(layer()->renderer()->previousPaintInvalidationRect()), InvalidationScroll);
+ } else {
+ box().invalidatePaintUsingContainer(repaintContainer, pixelSnappedIntRect(layer()->repainter().repaintRect()), InvalidationScroll);
+ }
+ }
// Schedule the scroll DOM event.
- if (m_box->node())
- m_box->node()->document().enqueueScrollEventForNode(m_box->node());
+ if (box().node())
+ box().node()->document().enqueueScrollEventForNode(box().node());
- InspectorInstrumentation::didScrollLayer(m_box);
+ if (AXObjectCache* cache = box().document().existingAXObjectCache())
+ cache->handleScrollPositionChanged(&box());
+
+ InspectorInstrumentation::didScrollLayer(&box());
}
IntPoint RenderLayerScrollableArea::scrollPosition() const
@@ -399,10 +434,10 @@ IntPoint RenderLayerScrollableArea::minimumScrollPosition() const
IntPoint RenderLayerScrollableArea::maximumScrollPosition() const
{
- if (!m_box->hasOverflowClip())
+ if (!box().hasOverflowClip())
return -scrollOrigin();
- return -scrollOrigin() + enclosingIntRect(m_overflowRect).size() - enclosingIntRect(m_box->clientBoxRect()).size();
+ return -scrollOrigin() + enclosingIntRect(m_overflowRect).size() - enclosingIntRect(box().clientBoxRect()).size();
}
IntRect RenderLayerScrollableArea::visibleContentRect(IncludeScrollbarsInRect scrollbarInclusion) const
@@ -440,12 +475,12 @@ IntSize RenderLayerScrollableArea::overhangAmount() const
IntPoint RenderLayerScrollableArea::lastKnownMousePosition() const
{
- return m_box->frame() ? m_box->frame()->eventHandler().lastKnownMousePosition() : IntPoint();
+ return box().frame() ? box().frame()->eventHandler().lastKnownMousePosition() : IntPoint();
}
bool RenderLayerScrollableArea::shouldSuspendScrollAnimations() const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return true;
return view->frameView()->shouldSuspendScrollAnimations();
@@ -453,7 +488,7 @@ bool RenderLayerScrollableArea::shouldSuspendScrollAnimations() const
bool RenderLayerScrollableArea::scrollbarsCanBeActive() const
{
- RenderView* view = m_box->view();
+ RenderView* view = box().view();
if (!view)
return false;
return view->frameView()->scrollbarsCanBeActive();
@@ -461,62 +496,67 @@ bool RenderLayerScrollableArea::scrollbarsCanBeActive() const
IntRect RenderLayerScrollableArea::scrollableAreaBoundingBox() const
{
- return m_box->absoluteBoundingBoxRect();
+ return box().absoluteBoundingBoxRect();
}
bool RenderLayerScrollableArea::userInputScrollable(ScrollbarOrientation orientation) const
{
- if (m_box->isIntristicallyScrollable(orientation))
+ if (box().isIntristicallyScrollable(orientation))
return true;
EOverflow overflowStyle = (orientation == HorizontalScrollbar) ?
- m_box->style()->overflowX() : m_box->style()->overflowY();
+ box().style()->overflowX() : box().style()->overflowY();
return (overflowStyle == OSCROLL || overflowStyle == OAUTO || overflowStyle == OOVERLAY);
}
bool RenderLayerScrollableArea::shouldPlaceVerticalScrollbarOnLeft() const
{
- return m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft();
+ return box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft();
}
int RenderLayerScrollableArea::pageStep(ScrollbarOrientation orientation) const
{
int length = (orientation == HorizontalScrollbar) ?
- m_box->pixelSnappedClientWidth() : m_box->pixelSnappedClientHeight();
+ box().pixelSnappedClientWidth() : box().pixelSnappedClientHeight();
int minPageStep = static_cast<float>(length) * ScrollableArea::minFractionToStepWhenPaging();
int pageStep = max(minPageStep, length - ScrollableArea::maxOverlapBetweenPages());
return max(pageStep, 1);
}
+RenderBox& RenderLayerScrollableArea::box() const
+{
+ return *m_layer.renderBox();
+}
+
RenderLayer* RenderLayerScrollableArea::layer() const
{
- return m_box->layer();
+ return &m_layer;
}
-int RenderLayerScrollableArea::scrollWidth() const
+LayoutUnit RenderLayerScrollableArea::scrollWidth() const
{
if (m_scrollDimensionsDirty)
const_cast<RenderLayerScrollableArea*>(this)->computeScrollDimensions();
- return snapSizeToPixel(m_overflowRect.width(), m_box->clientLeft() + m_box->x());
+ return m_overflowRect.width();
}
-int RenderLayerScrollableArea::scrollHeight() const
+LayoutUnit RenderLayerScrollableArea::scrollHeight() const
{
if (m_scrollDimensionsDirty)
const_cast<RenderLayerScrollableArea*>(this)->computeScrollDimensions();
- return snapSizeToPixel(m_overflowRect.height(), m_box->clientTop() + m_box->y());
+ return m_overflowRect.height();
}
void RenderLayerScrollableArea::computeScrollDimensions()
{
m_scrollDimensionsDirty = false;
- m_overflowRect = m_box->layoutOverflowRect();
- m_box->flipForWritingMode(m_overflowRect);
+ m_overflowRect = box().layoutOverflowRect();
+ box().flipForWritingMode(m_overflowRect);
- int scrollableLeftOverflow = m_overflowRect.x() - m_box->borderLeft() - (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? m_box->verticalScrollbarWidth() : 0);
- int scrollableTopOverflow = m_overflowRect.y() - m_box->borderTop();
+ int scrollableLeftOverflow = m_overflowRect.x() - box().borderLeft() - (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? box().verticalScrollbarWidth() : 0);
+ int scrollableTopOverflow = m_overflowRect.y() - box().borderTop();
setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
}
@@ -530,7 +570,7 @@ void RenderLayerScrollableArea::scrollToOffset(const IntSize& scrollOffset, Scro
void RenderLayerScrollableArea::updateAfterLayout()
{
// List box parts handle the scrollbars by themselves so we have nothing to do.
- if (m_box->style()->appearance() == ListboxPart)
+ if (box().style()->appearance() == ListboxPart)
return;
m_scrollDimensionsDirty = true;
@@ -538,7 +578,7 @@ void RenderLayerScrollableArea::updateAfterLayout()
computeScrollDimensions();
- if (!m_box->isMarquee()) {
+ if (!box().isMarquee()) {
// Layout may cause us to be at an invalid scroll position. In this case we need
// to pull our scroll offsets back to the max (or push them up to the min).
IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset());
@@ -552,87 +592,97 @@ void RenderLayerScrollableArea::updateAfterLayout()
bool hasHorizontalOverflow = this->hasHorizontalOverflow();
bool hasVerticalOverflow = this->hasVerticalOverflow();
- // overflow:scroll should just enable/disable.
- if (m_box->style()->overflowX() == OSCROLL)
- horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
- if (m_box->style()->overflowY() == OSCROLL)
- verticalScrollbar()->setEnabled(hasVerticalOverflow);
+ {
+ // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
+ DisableCompositingQueryAsserts disabler;
+
+ // overflow:scroll should just enable/disable.
+ if (box().style()->overflowX() == OSCROLL)
+ horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
+ if (box().style()->overflowY() == OSCROLL)
+ verticalScrollbar()->setEnabled(hasVerticalOverflow);
+ }
// overflow:auto may need to lay out again if scrollbars got added/removed.
- bool autoHorizontalScrollBarChanged = m_box->hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
- bool autoVerticalScrollBarChanged = m_box->hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
+ bool autoHorizontalScrollBarChanged = box().hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
+ bool autoVerticalScrollBarChanged = box().hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged) {
- if (m_box->hasAutoHorizontalScrollbar())
+ if (box().hasAutoHorizontalScrollbar())
setHasHorizontalScrollbar(hasHorizontalOverflow);
- if (m_box->hasAutoVerticalScrollbar())
+ if (box().hasAutoVerticalScrollbar())
setHasVerticalScrollbar(hasVerticalOverflow);
+ if (hasVerticalOverflow || hasHorizontalOverflow)
+ updateScrollCornerStyle();
+
layer()->updateSelfPaintingLayer();
// Force an update since we know the scrollbars have changed things.
- if (m_box->document().hasAnnotatedRegions())
- m_box->document().setAnnotatedRegionsDirty(true);
+ if (box().document().hasAnnotatedRegions())
+ box().document().setAnnotatedRegionsDirty(true);
- m_box->repaint();
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ box().paintInvalidationForWholeRenderer();
- if (m_box->style()->overflowX() == OAUTO || m_box->style()->overflowY() == OAUTO) {
+ if (box().style()->overflowX() == OAUTO || box().style()->overflowY() == OAUTO) {
if (!m_inOverflowRelayout) {
// Our proprietary overflow: overlay value doesn't trigger a layout.
m_inOverflowRelayout = true;
- SubtreeLayoutScope layoutScope(m_box);
- layoutScope.setNeedsLayout(m_box);
- if (m_box->isRenderBlock()) {
- RenderBlock* block = toRenderBlock(m_box);
- block->scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
- block->layoutBlock(true);
+ SubtreeLayoutScope layoutScope(box());
+ layoutScope.setNeedsLayout(&box());
+ if (box().isRenderBlock()) {
+ RenderBlock& block = toRenderBlock(box());
+ block.scrollbarsChanged(autoHorizontalScrollBarChanged, autoVerticalScrollBarChanged);
+ block.layoutBlock(true);
} else {
- m_box->layout();
+ box().layout();
}
m_inOverflowRelayout = false;
}
}
}
- // Set up the range (and page step/line step).
- if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
- int clientWidth = m_box->pixelSnappedClientWidth();
- horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
- }
- if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
- int clientHeight = m_box->pixelSnappedClientHeight();
- verticalScrollbar->setProportion(clientHeight, overflowRect().height());
+ {
+ // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
+ DisableCompositingQueryAsserts disabler;
+
+ // Set up the range (and page step/line step).
+ if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
+ int clientWidth = box().pixelSnappedClientWidth();
+ horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
+ }
+ if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
+ int clientHeight = box().pixelSnappedClientHeight();
+ verticalScrollbar->setProportion(clientHeight, overflowRect().height());
+ }
}
updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
-
- // Composited scrolling may need to be enabled or disabled if the amount of overflow changed.
- if (m_box->view() && m_box->view()->compositor()->updateLayerCompositingState(m_box->layer()))
- m_box->view()->compositor()->setCompositingLayersNeedRebuild();
}
bool RenderLayerScrollableArea::hasHorizontalOverflow() const
{
ASSERT(!m_scrollDimensionsDirty);
- return scrollWidth() > m_box->pixelSnappedClientWidth();
+ return scrollWidth() > box().clientWidth();
}
bool RenderLayerScrollableArea::hasVerticalOverflow() const
{
ASSERT(!m_scrollDimensionsDirty);
- return scrollHeight() > m_box->pixelSnappedClientHeight();
+ return scrollHeight() > box().clientHeight();
}
bool RenderLayerScrollableArea::hasScrollableHorizontalOverflow() const
{
- return hasHorizontalOverflow() && m_box->scrollsOverflowX();
+ return hasHorizontalOverflow() && box().scrollsOverflowX();
}
bool RenderLayerScrollableArea::hasScrollableVerticalOverflow() const
{
- return hasVerticalOverflow() && m_box->scrollsOverflowY();
+ return hasVerticalOverflow() && box().scrollsOverflowY();
}
static bool overflowRequiresScrollbar(EOverflow overflow)
@@ -648,14 +698,18 @@ static bool overflowDefinesAutomaticScrollbar(EOverflow overflow)
void RenderLayerScrollableArea::updateAfterStyleChange(const RenderStyle* oldStyle)
{
// List box parts handle the scrollbars by themselves so we have nothing to do.
- if (m_box->style()->appearance() == ListboxPart)
+ if (box().style()->appearance() == ListboxPart)
+ return;
+
+ // RenderView shouldn't provide scrollbars on its own.
+ if (box().isRenderView())
return;
if (!m_scrollDimensionsDirty)
updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
- EOverflow overflowX = m_box->style()->overflowX();
- EOverflow overflowY = m_box->style()->overflowY();
+ EOverflow overflowX = box().style()->overflowX();
+ EOverflow overflowY = box().style()->overflowY();
// To avoid doing a relayout in updateScrollbarsAfterLayout, we try to keep any automatic scrollbar that was already present.
bool needsHorizontalScrollbar = (hasHorizontalScrollbar() && overflowDefinesAutomaticScrollbar(overflowX)) || overflowRequiresScrollbar(overflowX);
@@ -686,10 +740,35 @@ void RenderLayerScrollableArea::updateAfterStyleChange(const RenderStyle* oldSty
updateResizerStyle();
}
+void RenderLayerScrollableArea::updateAfterCompositingChange()
+{
+ layer()->updateScrollingStateAfterCompositingChange();
+}
+
+void RenderLayerScrollableArea::updateAfterOverflowRecalc()
+{
+ computeScrollDimensions();
+ if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
+ int clientWidth = box().pixelSnappedClientWidth();
+ horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
+ }
+ if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
+ int clientHeight = box().pixelSnappedClientHeight();
+ verticalScrollbar->setProportion(clientHeight, overflowRect().height());
+ }
+
+ bool hasHorizontalOverflow = this->hasHorizontalOverflow();
+ bool hasVerticalOverflow = this->hasVerticalOverflow();
+ bool autoHorizontalScrollBarChanged = box().hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
+ bool autoVerticalScrollBarChanged = box().hasAutoVerticalScrollbar() && (hasVerticalScrollbar() != hasVerticalOverflow);
+ if (autoHorizontalScrollBarChanged || autoVerticalScrollBarChanged)
+ box().setNeedsLayoutAndFullPaintInvalidation();
+}
+
IntSize RenderLayerScrollableArea::clampScrollOffset(const IntSize& scrollOffset) const
{
- int maxX = scrollWidth() - m_box->pixelSnappedClientWidth();
- int maxY = scrollHeight() - m_box->pixelSnappedClientHeight();
+ int maxX = scrollWidth() - box().pixelSnappedClientWidth();
+ int maxY = scrollHeight() - box().pixelSnappedClientHeight();
int x = std::max(std::min(scrollOffset.width(), maxX), 0);
int y = std::max(std::min(scrollOffset.height(), maxY), 0);
@@ -704,8 +783,8 @@ IntRect RenderLayerScrollableArea::rectForHorizontalScrollbar(const IntRect& bor
const IntRect& scrollCorner = scrollCornerRect();
return IntRect(horizontalScrollbarStart(borderBoxRect.x()),
- borderBoxRect.maxY() - m_box->borderBottom() - m_hBar->height(),
- borderBoxRect.width() - (m_box->borderLeft() + m_box->borderRight()) - scrollCorner.width(),
+ borderBoxRect.maxY() - box().borderBottom() - m_hBar->height(),
+ borderBoxRect.width() - (box().borderLeft() + box().borderRight()) - scrollCorner.width(),
m_hBar->height());
}
@@ -717,54 +796,54 @@ IntRect RenderLayerScrollableArea::rectForVerticalScrollbar(const IntRect& borde
const IntRect& scrollCorner = scrollCornerRect();
return IntRect(verticalScrollbarStart(borderBoxRect.x(), borderBoxRect.maxX()),
- borderBoxRect.y() + m_box->borderTop(),
+ borderBoxRect.y() + box().borderTop(),
m_vBar->width(),
- borderBoxRect.height() - (m_box->borderTop() + m_box->borderBottom()) - scrollCorner.height());
+ borderBoxRect.height() - (box().borderTop() + box().borderBottom()) - scrollCorner.height());
}
LayoutUnit RenderLayerScrollableArea::verticalScrollbarStart(int minX, int maxX) const
{
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- return minX + m_box->borderLeft();
- return maxX - m_box->borderRight() - m_vBar->width();
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+ return minX + box().borderLeft();
+ return maxX - box().borderRight() - m_vBar->width();
}
LayoutUnit RenderLayerScrollableArea::horizontalScrollbarStart(int minX) const
{
- int x = minX + m_box->borderLeft();
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
- x += m_vBar ? m_vBar->width() : resizerCornerRect(m_box->pixelSnappedBorderBoxRect(), ResizerForPointer).width();
+ int x = minX + box().borderLeft();
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+ x += m_vBar ? m_vBar->width() : resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer).width();
return x;
}
IntSize RenderLayerScrollableArea::scrollbarOffset(const Scrollbar* scrollbar) const
{
if (scrollbar == m_vBar.get())
- return IntSize(verticalScrollbarStart(0, m_box->width()), m_box->borderTop());
+ return IntSize(verticalScrollbarStart(0, box().width()), box().borderTop());
if (scrollbar == m_hBar.get())
- return IntSize(horizontalScrollbarStart(0), m_box->height() - m_box->borderBottom() - scrollbar->height());
+ return IntSize(horizontalScrollbarStart(0), box().height() - box().borderBottom() - scrollbar->height());
ASSERT_NOT_REACHED();
return IntSize();
}
-static inline RenderObject* rendererForScrollbar(RenderObject* renderer)
+static inline RenderObject* rendererForScrollbar(RenderObject& renderer)
{
- if (Node* node = renderer->node()) {
+ if (Node* node = renderer.node()) {
if (ShadowRoot* shadowRoot = node->containingShadowRoot()) {
if (shadowRoot->type() == ShadowRoot::UserAgentShadowRoot)
return shadowRoot->host()->renderer();
}
}
- return renderer;
+ return &renderer;
}
PassRefPtr<Scrollbar> RenderLayerScrollableArea::createScrollbar(ScrollbarOrientation orientation)
{
RefPtr<Scrollbar> widget;
- RenderObject* actualRenderer = rendererForScrollbar(m_box);
+ RenderObject* actualRenderer = rendererForScrollbar(box());
bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style()->hasPseudoStyle(SCROLLBAR);
if (hasCustomScrollbarStyle) {
widget = RenderScrollbar::createCustomScrollbar(this, orientation, actualRenderer->node());
@@ -775,7 +854,7 @@ PassRefPtr<Scrollbar> RenderLayerScrollableArea::createScrollbar(ScrollbarOrient
else
didAddScrollbar(widget.get(), VerticalScrollbar);
}
- m_box->document().view()->addChild(widget.get());
+ box().document().view()->addChild(widget.get());
return widget.release();
}
@@ -790,7 +869,7 @@ void RenderLayerScrollableArea::destroyScrollbar(ScrollbarOrientation orientatio
scrollbar->removeFromParent();
scrollbar->disconnectFromScrollableArea();
- scrollbar = 0;
+ scrollbar = nullptr;
}
void RenderLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar)
@@ -798,10 +877,14 @@ void RenderLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar)
if (hasScrollbar == hasHorizontalScrollbar())
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
+ // This doesn't hit in any tests, but since the equivalent code in setHasVerticalScrollbar
+ // does, presumably this code does as well.
+ DisableCompositingQueryAsserts disabler;
m_hBar = createScrollbar(HorizontalScrollbar);
- else
+ } else {
destroyScrollbar(HorizontalScrollbar);
+ }
// Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
if (m_hBar)
@@ -810,8 +893,8 @@ void RenderLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar)
m_vBar->styleChanged();
// Force an update since we know the scrollbars have changed things.
- if (m_box->document().hasAnnotatedRegions())
- m_box->document().setAnnotatedRegionsDirty(true);
+ if (box().document().hasAnnotatedRegions())
+ box().document().setAnnotatedRegionsDirty(true);
}
void RenderLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar)
@@ -819,10 +902,13 @@ void RenderLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar)
if (hasScrollbar == hasVerticalScrollbar())
return;
- if (hasScrollbar)
+ if (hasScrollbar) {
+ // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html
+ DisableCompositingQueryAsserts disabler;
m_vBar = createScrollbar(VerticalScrollbar);
- else
+ } else {
destroyScrollbar(VerticalScrollbar);
+ }
// Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
if (m_hBar)
@@ -831,8 +917,8 @@ void RenderLayerScrollableArea::setHasVerticalScrollbar(bool hasScrollbar)
m_vBar->styleChanged();
// Force an update since we know the scrollbars have changed things.
- if (m_box->document().hasAnnotatedRegions())
- m_box->document().setAnnotatedRegionsDirty(true);
+ if (box().document().hasAnnotatedRegions())
+ box().document().setAnnotatedRegionsDirty(true);
}
int RenderLayerScrollableArea::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const
@@ -849,23 +935,12 @@ int RenderLayerScrollableArea::horizontalScrollbarHeight(OverlayScrollbarSizeRel
return m_hBar->height();
}
-void RenderLayerScrollableArea::positionOverflowControls()
-{
- RenderGeometryMap geometryMap(UseTransforms);
- RenderView* view = m_box->view();
- if (m_box->layer() != view->layer() && m_box->layer()->parent())
- geometryMap.pushMappingsToAncestor(m_box->layer()->parent(), 0);
-
- LayoutPoint offsetFromRoot = LayoutPoint(geometryMap.absolutePoint(FloatPoint()));
- positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
-}
-
void RenderLayerScrollableArea::positionOverflowControls(const IntSize& offsetFromRoot)
{
- if (!hasScrollbar() && !m_box->canResize())
+ if (!hasScrollbar() && !box().canResize())
return;
- const IntRect borderBox = m_box->pixelSnappedBorderBoxRect();
+ const IntRect borderBox = box().pixelSnappedBorderBoxRect();
if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
IntRect vBarRect = rectForVerticalScrollbar(borderBox);
vBarRect.move(offsetFromRoot);
@@ -888,26 +963,23 @@ void RenderLayerScrollableArea::positionOverflowControls(const IntSize& offsetFr
// FIXME, this should eventually be removed, once we are certain that composited
// controls get correctly positioned on a compositor update. For now, conservatively
// leaving this unchanged.
- if (m_box->hasCompositedLayerMapping())
- m_box->compositedLayerMapping()->positionOverflowControlsLayers(offsetFromRoot);
-}
-
-bool RenderLayerScrollableArea::scrollsOverflow() const
-{
- if (FrameView* frameView = m_box->view()->frameView())
- return frameView->containsScrollableArea(this);
-
- return false;
+ if (box().hasCompositedLayerMapping())
+ box().compositedLayerMapping()->positionOverflowControlsLayers(offsetFromRoot);
}
void RenderLayerScrollableArea::updateScrollCornerStyle()
{
- RenderObject* actualRenderer = rendererForScrollbar(m_box);
- RefPtr<RenderStyle> corner = m_box->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
+ if (!m_scrollCorner && !hasScrollbar())
+ return;
+ if (!m_scrollCorner && hasOverlayScrollbars())
+ return;
+
+ RenderObject* actualRenderer = rendererForScrollbar(box());
+ RefPtr<RenderStyle> corner = box().hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->style()) : PassRefPtr<RenderStyle>(nullptr);
if (corner) {
if (!m_scrollCorner) {
- m_scrollCorner = RenderScrollbarPart::createAnonymous(&m_box->document());
- m_scrollCorner->setParent(m_box);
+ m_scrollCorner = RenderScrollbarPart::createAnonymous(&box().document());
+ m_scrollCorner->setParent(&box());
}
m_scrollCorner->setStyle(corner.release());
} else if (m_scrollCorner) {
@@ -919,7 +991,7 @@ void RenderLayerScrollableArea::updateScrollCornerStyle()
void RenderLayerScrollableArea::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
{
// Don't do anything if we have no overflow.
- if (!m_box->hasOverflowClip())
+ if (!box().hasOverflowClip())
return;
IntPoint adjustedPaintOffset = paintOffset;
@@ -947,7 +1019,7 @@ void RenderLayerScrollableArea::paintOverflowControls(GraphicsContext* context,
if (!overflowControlsIntersectRect(localDamgeRect))
return;
- RenderView* renderView = m_box->view();
+ RenderView* renderView = box().view();
RenderLayer* paintingRoot = layer()->enclosingCompositingLayer();
if (!paintingRoot)
@@ -1003,22 +1075,22 @@ void RenderLayerScrollableArea::paintScrollCorner(GraphicsContext* context, cons
bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, const IntPoint& localPoint)
{
- if (!hasScrollbar() && !m_box->canResize())
+ if (!hasScrollbar() && !box().canResize())
return false;
IntRect resizeControlRect;
- if (m_box->style()->resize() != RESIZE_NONE) {
- resizeControlRect = resizerCornerRect(m_box->pixelSnappedBorderBoxRect(), ResizerForPointer);
+ if (box().style()->resize() != RESIZE_NONE) {
+ resizeControlRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer);
if (resizeControlRect.contains(localPoint))
return true;
}
int resizeControlSize = max(resizeControlRect.height(), 0);
if (m_vBar && m_vBar->shouldParticipateInHitTesting()) {
- LayoutRect vBarRect(verticalScrollbarStart(0, m_box->width()),
- m_box->borderTop(),
+ LayoutRect vBarRect(verticalScrollbarStart(0, box().width()),
+ box().borderTop(),
m_vBar->width(),
- m_box->height() - (m_box->borderTop() + m_box->borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
+ box().height() - (box().borderTop() + box().borderBottom()) - (m_hBar ? m_hBar->height() : resizeControlSize));
if (vBarRect.contains(localPoint)) {
result.setScrollbar(m_vBar.get());
return true;
@@ -1028,8 +1100,8 @@ bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, c
resizeControlSize = max(resizeControlRect.width(), 0);
if (m_hBar && m_hBar->shouldParticipateInHitTesting()) {
LayoutRect hBarRect(horizontalScrollbarStart(0),
- m_box->height() - m_box->borderBottom() - m_hBar->height(),
- m_box->width() - (m_box->borderLeft() + m_box->borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
+ box().height() - box().borderBottom() - m_hBar->height(),
+ box().width() - (box().borderLeft() + box().borderRight()) - (m_vBar ? m_vBar->width() : resizeControlSize),
m_hBar->height());
if (hBarRect.contains(localPoint)) {
result.setScrollbar(m_hBar.get());
@@ -1044,9 +1116,9 @@ bool RenderLayerScrollableArea::hitTestOverflowControls(HitTestResult& result, c
IntRect RenderLayerScrollableArea::resizerCornerRect(const IntRect& bounds, ResizerHitTestType resizerHitTestType) const
{
- if (m_box->style()->resize() == RESIZE_NONE)
+ if (box().style()->resize() == RESIZE_NONE)
return IntRect();
- IntRect corner = cornerRect(m_box->style(), horizontalScrollbar(), verticalScrollbar(), bounds);
+ IntRect corner = cornerRect(box().style(), horizontalScrollbar(), verticalScrollbar(), bounds);
if (resizerHitTestType == ResizerForTouch) {
// We make the resizer virtually larger for touch hit testing. With the
@@ -1065,13 +1137,13 @@ IntRect RenderLayerScrollableArea::scrollCornerAndResizerRect() const
{
IntRect scrollCornerAndResizer = scrollCornerRect();
if (scrollCornerAndResizer.isEmpty())
- scrollCornerAndResizer = resizerCornerRect(m_box->pixelSnappedBorderBoxRect(), ResizerForPointer);
+ scrollCornerAndResizer = resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer);
return scrollCornerAndResizer;
}
bool RenderLayerScrollableArea::overflowControlsIntersectRect(const IntRect& localRect) const
{
- const IntRect borderBox = m_box->pixelSnappedBorderBoxRect();
+ const IntRect borderBox = box().pixelSnappedBorderBoxRect();
if (rectForHorizontalScrollbar(borderBox).intersects(localRect))
return true;
@@ -1090,10 +1162,10 @@ bool RenderLayerScrollableArea::overflowControlsIntersectRect(const IntRect& loc
void RenderLayerScrollableArea::paintResizer(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
{
- if (m_box->style()->resize() == RESIZE_NONE)
+ if (box().style()->resize() == RESIZE_NONE)
return;
- IntRect absRect = resizerCornerRect(m_box->pixelSnappedBorderBoxRect(), ResizerForPointer);
+ IntRect absRect = resizerCornerRect(box().pixelSnappedBorderBoxRect(), ResizerForPointer);
absRect.moveBy(paintOffset);
if (!absRect.intersects(damageRect))
return;
@@ -1126,17 +1198,17 @@ void RenderLayerScrollableArea::paintResizer(GraphicsContext* context, const Int
bool RenderLayerScrollableArea::isPointInResizeControl(const IntPoint& absolutePoint, ResizerHitTestType resizerHitTestType) const
{
- if (!m_box->canResize())
+ if (!box().canResize())
return false;
- IntPoint localPoint = roundedIntPoint(m_box->absoluteToLocal(absolutePoint, UseTransforms));
- IntRect localBounds(0, 0, m_box->pixelSnappedWidth(), m_box->pixelSnappedHeight());
+ IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, UseTransforms));
+ IntRect localBounds(0, 0, box().pixelSnappedWidth(), box().pixelSnappedHeight());
return resizerCornerRect(localBounds, resizerHitTestType).contains(localPoint);
}
bool RenderLayerScrollableArea::hitTestResizerInFragments(const LayerFragments& layerFragments, const HitTestLocation& hitTestLocation) const
{
- if (!m_box->canResize())
+ if (!box().canResize())
return false;
if (layerFragments.isEmpty())
@@ -1153,26 +1225,29 @@ bool RenderLayerScrollableArea::hitTestResizerInFragments(const LayerFragments&
void RenderLayerScrollableArea::updateResizerAreaSet()
{
- Frame* frame = m_box->frame();
+ LocalFrame* frame = box().frame();
if (!frame)
return;
FrameView* frameView = frame->view();
if (!frameView)
return;
- if (m_box->canResize())
- frameView->addResizerArea(m_box);
+ if (box().canResize())
+ frameView->addResizerArea(box());
else
- frameView->removeResizerArea(m_box);
+ frameView->removeResizerArea(box());
}
void RenderLayerScrollableArea::updateResizerStyle()
{
- RenderObject* actualRenderer = rendererForScrollbar(m_box);
- RefPtr<RenderStyle> resizer = m_box->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(RESIZER), actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
+ if (!m_resizer && !box().canResize())
+ return;
+
+ RenderObject* actualRenderer = rendererForScrollbar(box());
+ RefPtr<RenderStyle> resizer = box().hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(RESIZER), actualRenderer->style()) : PassRefPtr<RenderStyle>(nullptr);
if (resizer) {
if (!m_resizer) {
- m_resizer = RenderScrollbarPart::createAnonymous(&m_box->document());
- m_resizer->setParent(m_box);
+ m_resizer = RenderScrollbarPart::createAnonymous(&box().document());
+ m_resizer->setParent(&box());
}
m_resizer->setStyle(resizer.release());
} else if (m_resizer) {
@@ -1183,7 +1258,7 @@ void RenderLayerScrollableArea::updateResizerStyle()
void RenderLayerScrollableArea::drawPlatformResizerImage(GraphicsContext* context, IntRect resizerCornerRect)
{
- float deviceScaleFactor = WebCore::deviceScaleFactor(m_box->frame());
+ float deviceScaleFactor = WebCore::deviceScaleFactor(box().frame());
RefPtr<Image> resizeCornerImage;
IntSize cornerResizerSize;
@@ -1198,10 +1273,10 @@ void RenderLayerScrollableArea::drawPlatformResizerImage(GraphicsContext* contex
cornerResizerSize = resizeCornerImage->size();
}
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
context->save();
context->translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
- context->scale(FloatSize(-1.0, 1.0));
+ context->scale(-1.0, 1.0);
context->drawImage(resizeCornerImage.get(), IntRect(IntPoint(), cornerResizerSize));
context->restore();
return;
@@ -1215,21 +1290,21 @@ IntSize RenderLayerScrollableArea::offsetFromResizeCorner(const IntPoint& absolu
// Currently the resize corner is either the bottom right corner or the bottom left corner.
// FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
IntSize elementSize = layer()->size();
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
elementSize.setWidth(0);
IntPoint resizerPoint = IntPoint(elementSize);
- IntPoint localPoint = roundedIntPoint(m_box->absoluteToLocal(absolutePoint, UseTransforms));
+ IntPoint localPoint = roundedIntPoint(box().absoluteToLocal(absolutePoint, UseTransforms));
return localPoint - resizerPoint;
}
void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSize& oldOffset)
{
// FIXME: This should be possible on generated content but is not right now.
- if (!inResizeMode() || !m_box->canResize() || !m_box->node())
+ if (!inResizeMode() || !box().canResize() || !box().node())
return;
- ASSERT(m_box->node()->isElementNode());
- Element* element = toElement(m_box->node());
+ ASSERT(box().node()->isElementNode());
+ Element* element = toElement(box().node());
Document& document = element->document();
@@ -1253,34 +1328,34 @@ void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSiz
ASSERT_NOT_REACHED();
}
- float zoomFactor = m_box->style()->effectiveZoom();
+ float zoomFactor = box().style()->effectiveZoom();
LayoutSize newOffset = offsetFromResizeCorner(document.view()->windowToContents(pos));
newOffset.setWidth(newOffset.width() / zoomFactor);
newOffset.setHeight(newOffset.height() / zoomFactor);
- LayoutSize currentSize = LayoutSize(m_box->width() / zoomFactor, m_box->height() / zoomFactor);
+ LayoutSize currentSize = LayoutSize(box().width() / zoomFactor, box().height() / zoomFactor);
LayoutSize minimumSize = element->minimumSizeForResizing().shrunkTo(currentSize);
element->setMinimumSizeForResizing(minimumSize);
LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
- if (m_box->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
+ if (box().style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft()) {
newOffset.setWidth(-newOffset.width());
adjustedOldOffset.setWidth(-adjustedOldOffset.width());
}
LayoutSize difference = (currentSize + newOffset - adjustedOldOffset).expandedTo(minimumSize) - currentSize;
- bool isBoxSizingBorder = m_box->style()->boxSizing() == BORDER_BOX;
+ bool isBoxSizingBorder = box().style()->boxSizing() == BORDER_BOX;
- EResize resize = m_box->style()->resize();
+ EResize resize = box().style()->resize();
if (resize != RESIZE_VERTICAL && difference.width()) {
if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
- element->setInlineStyleProperty(CSSPropertyMarginLeft, m_box->marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
- element->setInlineStyleProperty(CSSPropertyMarginRight, m_box->marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
+ element->setInlineStyleProperty(CSSPropertyMarginLeft, box().marginLeft() / zoomFactor, CSSPrimitiveValue::CSS_PX);
+ element->setInlineStyleProperty(CSSPropertyMarginRight, box().marginRight() / zoomFactor, CSSPrimitiveValue::CSS_PX);
}
- LayoutUnit baseWidth = m_box->width() - (isBoxSizingBorder ? LayoutUnit() : m_box->borderAndPaddingWidth());
+ LayoutUnit baseWidth = box().width() - (isBoxSizingBorder ? LayoutUnit() : box().borderAndPaddingWidth());
baseWidth = baseWidth / zoomFactor;
element->setInlineStyleProperty(CSSPropertyWidth, roundToInt(baseWidth + difference.width()), CSSPrimitiveValue::CSS_PX);
}
@@ -1288,10 +1363,10 @@ void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSiz
if (resize != RESIZE_HORIZONTAL && difference.height()) {
if (element->isFormControlElement()) {
// Make implicit margins from the theme explicit (see <http://bugs.webkit.org/show_bug.cgi?id=9547>).
- element->setInlineStyleProperty(CSSPropertyMarginTop, m_box->marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
- element->setInlineStyleProperty(CSSPropertyMarginBottom, m_box->marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
+ element->setInlineStyleProperty(CSSPropertyMarginTop, box().marginTop() / zoomFactor, CSSPrimitiveValue::CSS_PX);
+ element->setInlineStyleProperty(CSSPropertyMarginBottom, box().marginBottom() / zoomFactor, CSSPrimitiveValue::CSS_PX);
}
- LayoutUnit baseHeight = m_box->height() - (isBoxSizingBorder ? LayoutUnit() : m_box->borderAndPaddingHeight());
+ LayoutUnit baseHeight = box().height() - (isBoxSizingBorder ? LayoutUnit() : box().borderAndPaddingHeight());
baseHeight = baseHeight / zoomFactor;
element->setInlineStyleProperty(CSSPropertyHeight, roundToInt(baseHeight + difference.height()), CSSPrimitiveValue::CSS_PX);
}
@@ -1303,8 +1378,8 @@ void RenderLayerScrollableArea::resize(const PlatformEvent& evt, const LayoutSiz
LayoutRect RenderLayerScrollableArea::exposeRect(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
{
- LayoutRect localExposeRect(m_box->absoluteToLocalQuad(FloatQuad(FloatRect(rect)), UseTransforms).boundingBox());
- LayoutRect layerBounds(0, 0, m_box->clientWidth(), m_box->clientHeight());
+ LayoutRect localExposeRect(box().absoluteToLocalQuad(FloatQuad(FloatRect(rect)), UseTransforms).boundingBox());
+ LayoutRect layerBounds(0, 0, box().clientWidth(), box().clientHeight());
LayoutRect r = ScrollAlignment::getRectToExpose(layerBounds, localExposeRect, alignX, alignY);
IntSize clampedScrollOffset = clampScrollOffset(adjustedScrollOffset() + toIntSize(roundedIntRect(r).location()));
@@ -1315,12 +1390,12 @@ LayoutRect RenderLayerScrollableArea::exposeRect(const LayoutRect& rect, const S
scrollToOffset(clampedScrollOffset);
IntSize scrollOffsetDifference = adjustedScrollOffset() - oldScrollOffset;
localExposeRect.move(-scrollOffsetDifference);
- return LayoutRect(m_box->localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
+ return LayoutRect(box().localToAbsoluteQuad(FloatQuad(FloatRect(localExposeRect)), UseTransforms).boundingBox());
}
void RenderLayerScrollableArea::updateScrollableAreaSet(bool hasOverflow)
{
- Frame* frame = m_box->frame();
+ LocalFrame* frame = box().frame();
if (!frame)
return;
@@ -1328,148 +1403,58 @@ void RenderLayerScrollableArea::updateScrollableAreaSet(bool hasOverflow)
if (!frameView)
return;
- bool isVisibleToHitTest = m_box->visibleToHitTesting();
- if (HTMLFrameOwnerElement* owner = frame->ownerElement())
+ // FIXME: Does this need to be fixed later for OOPI?
+ bool isVisibleToHitTest = box().visibleToHitTesting();
+ if (HTMLFrameOwnerElement* owner = frame->deprecatedLocalOwner())
isVisibleToHitTest &= owner->renderer() && owner->renderer()->visibleToHitTesting();
- bool requiresScrollableArea = hasOverflow && isVisibleToHitTest;
- bool updatedScrollableAreaSet = false;
- if (requiresScrollableArea) {
- if (frameView->addScrollableArea(this))
- updatedScrollableAreaSet = true;
- } else {
- if (frameView->removeScrollableArea(this))
- updatedScrollableAreaSet = true;
- }
-
- if (updatedScrollableAreaSet) {
- // Count the total number of RenderLayers that are scrollable areas for
- // any period. We only want to record this at most once per RenderLayer.
- if (requiresScrollableArea && !m_isScrollableAreaHasBeenRecorded) {
- blink::Platform::current()->histogramEnumeration("Renderer.CompositedScrolling", RenderLayer::IsScrollableAreaBucket, RenderLayer::CompositedScrollingHistogramMax);
- m_isScrollableAreaHasBeenRecorded = true;
- }
-
- // We always want composited scrolling if compositor driven accelerated
- // scrolling is enabled. Since we will not update needs composited scrolling
- // in this case, we must force our state to update.
- if (layer()->compositorDrivenAcceleratedScrollingEnabled())
- layer()->didUpdateNeedsCompositedScrolling();
- else if (requiresScrollableArea)
- m_box->view()->compositor()->setNeedsUpdateCompositingRequirementsState();
- else
- setNeedsCompositedScrolling(false);
- }
-}
-
-void RenderLayerScrollableArea::updateNeedsCompositedScrolling()
-{
- TRACE_EVENT0("comp-scroll", "RenderLayer::updateNeedsCompositedScrolling");
-
- layer()->stackingNode()->updateDescendantsAreContiguousInStackingOrder();
- layer()->updateDescendantDependentFlags();
-
- ASSERT(scrollsOverflow());
- const bool needsToBeStackingContainer = layer()->acceleratedCompositingForOverflowScrollEnabled()
- && layer()->stackingNode()->descendantsAreContiguousInStackingOrder()
- && !layer()->hasUnclippedDescendant();
+ bool didNeedCompositedScrolling = needsCompositedScrolling();
- const bool needsToBeStackingContainerDidChange = layer()->stackingNode()->setNeedsToBeStackingContainer(needsToBeStackingContainer);
+ bool didScrollOverflow = m_scrollsOverflow;
- const bool needsCompositedScrolling = needsToBeStackingContainer
- || layer()->compositorDrivenAcceleratedScrollingEnabled();
-
- // We gather a boolean value for use with Google UMA histograms to
- // quantify the actual effects of a set of patches attempting to
- // relax composited scrolling requirements, thereby increasing the
- // number of composited overflow divs.
- if (layer()->acceleratedCompositingForOverflowScrollEnabled())
- blink::Platform::current()->histogramEnumeration("Renderer.NeedsCompositedScrolling", needsCompositedScrolling, 2);
+ m_scrollsOverflow = hasOverflow && isVisibleToHitTest;
+ if (didScrollOverflow == scrollsOverflow())
+ return;
- const bool needsCompositedScrollingDidChange = setNeedsCompositedScrolling(needsCompositedScrolling);
+ if (m_scrollsOverflow)
+ frameView->addScrollableArea(this);
+ else
+ frameView->removeScrollableArea(this);
- if (needsToBeStackingContainerDidChange || needsCompositedScrollingDidChange) {
- // Note, the z-order lists may need to be rebuilt, but our code guarantees
- // that we have not affected stacking, so we will not dirty
- // m_descendantsAreContiguousInStackingOrder for either us or our stacking
- // context or container.
+ if (didNeedCompositedScrolling != needsCompositedScrolling())
layer()->didUpdateNeedsCompositedScrolling();
- }
-}
-
-bool RenderLayerScrollableArea::setNeedsCompositedScrolling(bool needsCompositedScrolling)
-{
- if (this->needsCompositedScrolling() == needsCompositedScrolling)
- return false;
-
- // Count the total number of RenderLayers which need composited scrolling at
- // some point. This should be recorded at most once per RenderLayer, so we
- // check m_willUseCompositedScrollingHasBeenRecorded.
- if (layer()->acceleratedCompositingForOverflowScrollEnabled() && !m_willUseCompositedScrollingHasBeenRecorded) {
- blink::Platform::current()->histogramEnumeration("Renderer.CompositedScrolling", RenderLayer::WillUseCompositedScrollingBucket, RenderLayer::CompositedScrollingHistogramMax);
- m_willUseCompositedScrollingHasBeenRecorded = true;
- }
-
- m_needsCompositedScrolling = needsCompositedScrolling;
-
- return true;
-}
-
-void RenderLayerScrollableArea::updateHasVisibleNonLayerContent()
-{
- layer()->updateHasVisibleNonLayerContent();
}
void RenderLayerScrollableArea::updateCompositingLayersAfterScroll()
{
- RenderLayerCompositor* compositor = m_box->view()->compositor();
+ RenderLayerCompositor* compositor = box().view()->compositor();
if (compositor->inCompositingMode()) {
- // FIXME: Our stacking container is guaranteed to contain all of our descendants that may need
- // repositioning, so we should be able to enqueue a partial update compositing layers from there.
- // this feature was overridden for now by deferred compositing updates.
- if (usesCompositedScrolling())
- compositor->updateCompositingLayers(CompositingUpdateOnCompositedScroll);
- else
- compositor->updateCompositingLayers(CompositingUpdateOnScroll);
+ if (usesCompositedScrolling()) {
+ DisableCompositingQueryAsserts disabler;
+ ASSERT(box().hasCompositedLayerMapping());
+ box().compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+ compositor->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange);
+ } else {
+ layer()->setNeedsCompositingInputsUpdate();
+ compositor->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+ }
}
}
bool RenderLayerScrollableArea::usesCompositedScrolling() const
{
// Scroll form controls on the main thread so they exhibit correct touch scroll event bubbling
- if (m_box && (m_box->isIntristicallyScrollable(VerticalScrollbar) || m_box->isIntristicallyScrollable(HorizontalScrollbar)))
+ if (box().isIntristicallyScrollable(VerticalScrollbar) || box().isIntristicallyScrollable(HorizontalScrollbar))
return false;
- return m_box->hasCompositedLayerMapping() && m_box->compositedLayerMapping()->scrollingLayer();
-}
-
-bool RenderLayerScrollableArea::adjustForForceCompositedScrollingMode(bool value) const
-{
- switch (m_forceNeedsCompositedScrolling) {
- case DoNotForceCompositedScrolling:
- return value;
- case CompositedScrollingAlwaysOn:
- return true;
- case CompositedScrollingAlwaysOff:
- return false;
- }
-
- ASSERT_NOT_REACHED();
- return value;
+ // See https://codereview.chromium.org/176633003/ for the tests that fail without this disabler.
+ DisableCompositingQueryAsserts disabler;
+ return box().hasCompositedLayerMapping() && box().compositedLayerMapping()->scrollingLayer();
}
bool RenderLayerScrollableArea::needsCompositedScrolling() const
{
- return adjustForForceCompositedScrollingMode(m_needsCompositedScrolling);
-}
-
-void RenderLayerScrollableArea::setForceNeedsCompositedScrolling(ForceNeedsCompositedScrollingMode mode)
-{
- if (m_forceNeedsCompositedScrolling == mode)
- return;
-
- m_forceNeedsCompositedScrolling = mode;
- layer()->didUpdateNeedsCompositedScrolling();
+ return scrollsOverflow() && box().view()->compositor()->acceleratedCompositingForOverflowScrollEnabled();
}
} // Namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.h
index 0444ca78b33..a41bbde5232 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerScrollableArea.h
@@ -53,12 +53,6 @@ enum ResizerHitTestType {
ResizerForTouch
};
-enum ForceNeedsCompositedScrollingMode {
- DoNotForceCompositedScrolling = 0,
- CompositedScrollingAlwaysOn = 1,
- CompositedScrollingAlwaysOff = 2
-};
-
class PlatformEvent;
class RenderBox;
class RenderLayer;
@@ -68,7 +62,9 @@ class RenderLayerScrollableArea FINAL : public ScrollableArea {
friend class Internals;
public:
- RenderLayerScrollableArea(RenderBox*);
+ // FIXME: We should pass in the RenderBox but this opens a window
+ // for crashers during RenderLayer setup (see crbug.com/368062).
+ RenderLayerScrollableArea(RenderLayer&);
virtual ~RenderLayerScrollableArea();
bool hasHorizontalScrollbar() const { return horizontalScrollbar(); }
@@ -76,7 +72,6 @@ public:
virtual Scrollbar* horizontalScrollbar() const OVERRIDE { return m_hBar.get(); }
virtual Scrollbar* verticalScrollbar() const OVERRIDE { return m_vBar.get(); }
- virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE;
virtual GraphicsLayer* layerForScrolling() const OVERRIDE;
virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
@@ -124,6 +119,9 @@ public:
void updateAfterLayout();
void updateAfterStyleChange(const RenderStyle*);
+ void updateAfterOverflowRecalc();
+
+ virtual void updateAfterCompositingChange() OVERRIDE;
bool hasScrollbar() const { return m_hBar || m_vBar; }
@@ -141,8 +139,8 @@ public:
return resizerCornerRect(bounds, ResizerForTouch);
}
- int scrollWidth() const;
- int scrollHeight() const;
+ LayoutUnit scrollWidth() const;
+ LayoutUnit scrollHeight() const;
int verticalScrollbarWidth(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
int horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) const;
@@ -153,9 +151,6 @@ public:
void paintOverflowControls(GraphicsContext*, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls);
void paintScrollCorner(GraphicsContext*, const IntPoint&, const IntRect& damageRect);
- // If IntSize is not given, then we must incur additional overhead to instantiate a RenderGeometryMap
- // and compute the correct offset ourselves.
- void positionOverflowControls();
void positionOverflowControls(const IntSize& offsetFromRoot);
// isPointInResizeControl() is used for testing if a pointer/touch position is in the resize control
@@ -167,7 +162,10 @@ public:
LayoutRect exposeRect(const LayoutRect&, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
- bool scrollsOverflow() const;
+ // Returns true our scrollable area is in the FrameView's collection of scrollable areas. This can
+ // only happen if we're both scrollable, and we do in fact overflow. This means that overflow: hidden
+ // layers never get added to the FrameView's collection.
+ bool scrollsOverflow() const { return m_scrollsOverflow; }
// Rectangle encompassing the scroll corner and resizer rect.
IntRect scrollCornerAndResizerRect() const;
@@ -211,33 +209,22 @@ private:
void updateResizerStyle();
void drawPlatformResizerImage(GraphicsContext*, IntRect resizerCornerRect);
+ RenderBox& box() const;
RenderLayer* layer() const;
void updateScrollableAreaSet(bool hasOverflow);
void updateCompositingLayersAfterScroll();
- virtual void updateNeedsCompositedScrolling() OVERRIDE;
- bool setNeedsCompositedScrolling(bool);
-
- virtual void updateHasVisibleNonLayerContent() OVERRIDE;
- void setForceNeedsCompositedScrolling(ForceNeedsCompositedScrollingMode);
-
- RenderBox* m_box;
+ RenderLayer& m_layer;
// Keeps track of whether the layer is currently resizing, so events can cause resizing to start and stop.
unsigned m_inResizeMode : 1;
+ unsigned m_scrollsOverflow : 1;
unsigned m_scrollDimensionsDirty : 1;
unsigned m_inOverflowRelayout : 1;
- unsigned m_needsCompositedScrolling : 1;
- unsigned m_willUseCompositedScrollingHasBeenRecorded : 1;
-
- unsigned m_isScrollableAreaHasBeenRecorded : 1;
-
- ForceNeedsCompositedScrollingMode m_forceNeedsCompositedScrolling;
-
// The width/height of our scrolled area.
LayoutRect m_overflowRect;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.cpp
index 715dcecfe77..eaa6dfc09b4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.cpp
@@ -45,37 +45,33 @@
#include "core/rendering/RenderLayerStackingNode.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "public/platform/Platform.h"
namespace WebCore {
// FIXME: This should not require RenderLayer. There is currently a cycle where
-// in order to determine if we shoulBeNormalFlowOnly() and isStackingContainer()
-// we have to ask the render layer about some of its state.
+// in order to determine if we shoulBeNormalFlowOnly() we have to ask the render
+// layer about some of its state.
RenderLayerStackingNode::RenderLayerStackingNode(RenderLayer* layer)
: m_layer(layer)
- , m_descendantsAreContiguousInStackingOrder(false)
- , m_descendantsAreContiguousInStackingOrderDirty(true)
, m_normalFlowListDirty(true)
- , m_needsToBeStackingContainer(false)
- , m_needsToBeStackingContainerHasBeenRecorded(false)
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
, m_layerListMutationAllowed(true)
, m_stackingParent(0)
#endif
{
m_isNormalFlowOnly = shouldBeNormalFlowOnly();
- // Non-stacking containers should have empty z-order lists. As this is already the case,
+ // Non-stacking contexts should have empty z-order lists. As this is already the case,
// there is no need to dirty / recompute these lists.
- m_zOrderListsDirty = isStackingContainer();
+ m_zOrderListsDirty = isStackingContext();
}
RenderLayerStackingNode::~RenderLayerStackingNode()
{
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
if (!renderer()->documentBeingDestroyed()) {
ASSERT(!isInStackingParentZOrderLists());
ASSERT(!isInStackingParentNormalFlowList());
@@ -86,11 +82,6 @@ RenderLayerStackingNode::~RenderLayerStackingNode()
#endif
}
-bool RenderLayerStackingNode::isStackingContext(const RenderStyle* style) const
-{
- return !style->hasAutoZIndex() || layer()->isRootLayer();
-}
-
// Helper for the sorting of layers by z-index.
static inline bool compareZIndex(RenderLayerStackingNode* first, RenderLayerStackingNode* second)
{
@@ -99,47 +90,16 @@ static inline bool compareZIndex(RenderLayerStackingNode* first, RenderLayerStac
RenderLayerCompositor* RenderLayerStackingNode::compositor() const
{
- if (!renderer()->view())
- return 0;
+ ASSERT(renderer()->view());
return renderer()->view()->compositor();
}
-void RenderLayerStackingNode::dirtyNormalFlowListCanBePromotedToStackingContainer()
-{
- m_descendantsAreContiguousInStackingOrderDirty = true;
-
- if (m_normalFlowListDirty || !normalFlowList())
- return;
-
- for (size_t index = 0; index < normalFlowList()->size(); ++index)
- normalFlowList()->at(index)->dirtyNormalFlowListCanBePromotedToStackingContainer();
-}
-
-void RenderLayerStackingNode::dirtySiblingStackingNodeCanBePromotedToStackingContainer()
-{
- RenderLayerStackingNode* stackingNode = ancestorStackingNode();
- if (!stackingNode)
- return;
-
- if (!stackingNode->zOrderListsDirty() && stackingNode->posZOrderList()) {
- for (size_t index = 0; index < stackingNode->posZOrderList()->size(); ++index)
- stackingNode->posZOrderList()->at(index)->setDescendantsAreContiguousInStackingOrderDirty(true);
- }
-
- stackingNode->dirtyNormalFlowListCanBePromotedToStackingContainer();
-
- if (!stackingNode->zOrderListsDirty() && stackingNode->negZOrderList()) {
- for (size_t index = 0; index < stackingNode->negZOrderList()->size(); ++index)
- stackingNode->negZOrderList()->at(index)->setDescendantsAreContiguousInStackingOrderDirty(true);
- }
-}
-
void RenderLayerStackingNode::dirtyZOrderLists()
{
ASSERT(m_layerListMutationAllowed);
- ASSERT(isStackingContainer());
+ ASSERT(isStackingContext());
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
updateStackingParentForZOrderLists(0);
#endif
@@ -149,35 +109,13 @@ void RenderLayerStackingNode::dirtyZOrderLists()
m_negZOrderList->clear();
m_zOrderListsDirty = true;
- m_descendantsAreContiguousInStackingOrderDirty = true;
-
- if (!renderer()->documentBeingDestroyed()) {
- compositor()->setNeedsUpdateCompositingRequirementsState();
- compositor()->setCompositingLayersNeedRebuild();
- if (layer()->acceleratedCompositingForOverflowScrollEnabled())
- compositor()->setNeedsToRecomputeCompositingRequirements();
- }
+ if (!renderer()->documentBeingDestroyed())
+ compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
}
-void RenderLayerStackingNode::dirtyStackingContainerZOrderLists()
+void RenderLayerStackingNode::dirtyStackingContextZOrderLists()
{
- // Any siblings in the ancestor stacking context could also be affected.
- // Changing z-index, for example, could cause us to stack in between a
- // sibling's descendants, meaning that we have to recompute
- // m_descendantsAreContiguousInStackingOrder for that sibling.
- dirtySiblingStackingNodeCanBePromotedToStackingContainer();
-
- RenderLayerStackingNode* stackingContainerNode = ancestorStackingContainerNode();
- if (stackingContainerNode)
- stackingContainerNode->dirtyZOrderLists();
-
- // Any change that could affect our stacking container's z-order list could
- // cause other RenderLayers in our stacking context to either opt in or out
- // of composited scrolling. It is important that we make our stacking
- // context aware of these z-order changes so the appropriate updating can
- // happen.
- RenderLayerStackingNode* stackingNode = ancestorStackingNode();
- if (stackingNode && stackingNode != stackingContainerNode)
+ if (RenderLayerStackingNode* stackingNode = ancestorStackingContextNode())
stackingNode->dirtyZOrderLists();
}
@@ -185,7 +123,7 @@ void RenderLayerStackingNode::dirtyNormalFlowList()
{
ASSERT(m_layerListMutationAllowed);
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
updateStackingParentForNormalFlowList(0);
#endif
@@ -193,57 +131,48 @@ void RenderLayerStackingNode::dirtyNormalFlowList()
m_normalFlowList->clear();
m_normalFlowListDirty = true;
- if (!renderer()->documentBeingDestroyed()) {
- compositor()->setCompositingLayersNeedRebuild();
- if (layer()->acceleratedCompositingForOverflowScrollEnabled())
- compositor()->setNeedsToRecomputeCompositingRequirements();
- }
+ if (!renderer()->documentBeingDestroyed())
+ compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
}
void RenderLayerStackingNode::rebuildZOrderLists()
{
ASSERT(m_layerListMutationAllowed);
- ASSERT(isDirtyStackingContainer());
- rebuildZOrderLists(m_posZOrderList, m_negZOrderList);
-
-#if !ASSERT_DISABLED
- updateStackingParentForZOrderLists(this);
-#endif
-
- m_zOrderListsDirty = false;
-}
+ ASSERT(isDirtyStackingContext());
-void RenderLayerStackingNode::rebuildZOrderLists(OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList,
- OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList, const RenderLayerStackingNode* nodeToForceAsStackingContainer,
- CollectLayersBehavior collectLayersBehavior)
-{
for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
if (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)
- child->stackingNode()->collectLayers(posZOrderList, negZOrderList, nodeToForceAsStackingContainer, collectLayersBehavior);
+ child->stackingNode()->collectLayers(m_posZOrderList, m_negZOrderList);
}
// Sort the two lists.
- if (posZOrderList)
- std::stable_sort(posZOrderList->begin(), posZOrderList->end(), compareZIndex);
+ if (m_posZOrderList)
+ std::stable_sort(m_posZOrderList->begin(), m_posZOrderList->end(), compareZIndex);
- if (negZOrderList)
- std::stable_sort(negZOrderList->begin(), negZOrderList->end(), compareZIndex);
+ if (m_negZOrderList)
+ std::stable_sort(m_negZOrderList->begin(), m_negZOrderList->end(), compareZIndex);
// Append layers for top layer elements after normal layer collection, to ensure they are on top regardless of z-indexes.
// The renderers of top layer elements are children of the view, sorted in top layer stacking order.
if (layer()->isRootLayer()) {
- RenderObject* view = renderer()->view();
+ RenderView* view = renderer()->view();
for (RenderObject* child = view->firstChild(); child; child = child->nextSibling()) {
Element* childElement = (child->node() && child->node()->isElementNode()) ? toElement(child->node()) : 0;
if (childElement && childElement->isInTopLayer()) {
RenderLayer* layer = toRenderLayerModelObject(child)->layer();
// Create the buffer if it doesn't exist yet.
- if (!posZOrderList)
- posZOrderList = adoptPtr(new Vector<RenderLayerStackingNode*>);
- posZOrderList->append(layer->stackingNode());
+ if (!m_posZOrderList)
+ m_posZOrderList = adoptPtr(new Vector<RenderLayerStackingNode*>);
+ m_posZOrderList->append(layer->stackingNode());
}
}
}
+
+#if ASSERT_ENABLED
+ updateStackingParentForZOrderLists(this);
+#endif
+
+ m_zOrderListsDirty = false;
}
void RenderLayerStackingNode::updateNormalFlowList()
@@ -254,7 +183,6 @@ void RenderLayerStackingNode::updateNormalFlowList()
ASSERT(m_layerListMutationAllowed);
for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
- // Ignore non-overflow layers and reflections.
if (child->stackingNode()->isNormalFlowOnly() && (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)) {
if (!m_normalFlowList)
m_normalFlowList = adoptPtr(new Vector<RenderLayerStackingNode*>);
@@ -262,71 +190,36 @@ void RenderLayerStackingNode::updateNormalFlowList()
}
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
updateStackingParentForNormalFlowList(this);
#endif
m_normalFlowListDirty = false;
}
-void RenderLayerStackingNode::collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >& posBuffer, OwnPtr<Vector<RenderLayerStackingNode*> >& negBuffer,
- const RenderLayerStackingNode* nodeToForceAsStackingContainer, CollectLayersBehavior collectLayersBehavior)
+void RenderLayerStackingNode::collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >& posBuffer, OwnPtr<Vector<RenderLayerStackingNode*> >& negBuffer)
{
if (layer()->isInTopLayer())
return;
layer()->updateDescendantDependentFlags();
- bool isStacking = false;
- bool isNormalFlow = false;
-
- switch (collectLayersBehavior) {
- case ForceLayerToStackingContainer:
- ASSERT(nodeToForceAsStackingContainer);
- if (this == nodeToForceAsStackingContainer) {
- isStacking = true;
- isNormalFlow = false;
- } else {
- isStacking = isStackingContext();
- isNormalFlow = shouldBeNormalFlowOnlyIgnoringCompositedScrolling();
- }
- break;
- case OverflowScrollCanBeStackingContainers:
- ASSERT(!nodeToForceAsStackingContainer);
- isStacking = isStackingContainer();
- isNormalFlow = isNormalFlowOnly();
- break;
- case OnlyStackingContextsCanBeStackingContainers:
- isStacking = isStackingContext();
- isNormalFlow = shouldBeNormalFlowOnlyIgnoringCompositedScrolling();
- break;
- }
-
- // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
- if (!isNormalFlow && !layer()->isOutOfFlowRenderFlowThread()) {
- // Determine which buffer the child should be in.
+ if (!isNormalFlowOnly()) {
OwnPtr<Vector<RenderLayerStackingNode*> >& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
-
- // Create the buffer if it doesn't exist yet.
if (!buffer)
buffer = adoptPtr(new Vector<RenderLayerStackingNode*>);
-
- // Append ourselves at the end of the appropriate buffer.
buffer->append(this);
}
- // Recur into our children to collect more layers, but only if we don't establish
- // a stacking context/container.
- if (!isStacking) {
+ if (!isStackingContext()) {
for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
- // Ignore reflections.
if (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)
- child->stackingNode()->collectLayers(posBuffer, negBuffer, nodeToForceAsStackingContainer, collectLayersBehavior);
+ child->stackingNode()->collectLayers(posBuffer, negBuffer);
}
}
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool RenderLayerStackingNode::isInStackingParentZOrderLists() const
{
if (!m_stackingParent || m_stackingParent->zOrderListsDirty())
@@ -386,50 +279,26 @@ void RenderLayerStackingNode::updateLayerListsIfNeeded()
void RenderLayerStackingNode::updateStackingNodesAfterStyleChange(const RenderStyle* oldStyle)
{
- bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false;
- EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
+ bool wasStackingContext = oldStyle ? !oldStyle->hasAutoZIndex() : false;
int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;
- // FIXME: RenderLayer already handles visibility changes through our visiblity dirty bits. This logic could
- // likely be folded along with the rest.
bool isStackingContext = this->isStackingContext();
- if (isStackingContext == wasStackingContext && oldVisibility == renderer()->style()->visibility() && oldZIndex == zIndex())
+ if (isStackingContext == wasStackingContext && oldZIndex == zIndex())
return;
- dirtyStackingContainerZOrderLists();
+ dirtyStackingContextZOrderLists();
- if (isStackingContainer())
+ if (isStackingContext)
dirtyZOrderLists();
else
clearZOrderLists();
-
- compositor()->setNeedsUpdateCompositingRequirementsState();
}
+// FIXME: Rename shouldBeNormalFlowOnly to something more accurate now that CSS
+// 2.1 defines the term "normal flow".
bool RenderLayerStackingNode::shouldBeNormalFlowOnly() const
{
- return shouldBeNormalFlowOnlyIgnoringCompositedScrolling() && !layer()->needsCompositedScrolling();
-}
-
-bool RenderLayerStackingNode::shouldBeNormalFlowOnlyIgnoringCompositedScrolling() const
-{
- const bool couldBeNormalFlow = renderer()->hasOverflowClip()
- || renderer()->hasReflection()
- || renderer()->hasMask()
- || renderer()->isCanvas()
- || renderer()->isVideo()
- || renderer()->isEmbeddedObject()
- || renderer()->isRenderIFrame()
- || (renderer()->style()->specifiesColumns() && !layer()->isRootLayer());
- const bool preventsElementFromBeingNormalFlow = renderer()->isPositioned()
- || renderer()->hasTransform()
- || renderer()->hasClipPath()
- || renderer()->hasFilter()
- || renderer()->hasBlendMode()
- || layer()->isTransparent()
- || renderer()->style()->hasFlowFrom();
-
- return couldBeNormalFlow && !preventsElementFromBeingNormalFlow;
+ return !isStackingContext() && !renderer()->isPositioned();
}
void RenderLayerStackingNode::updateIsNormalFlowOnly()
@@ -441,215 +310,16 @@ void RenderLayerStackingNode::updateIsNormalFlowOnly()
m_isNormalFlowOnly = isNormalFlowOnly;
if (RenderLayer* p = layer()->parent())
p->stackingNode()->dirtyNormalFlowList();
- dirtyStackingContainerZOrderLists();
-}
-
-bool RenderLayerStackingNode::needsToBeStackingContainer() const
-{
- return layer()->scrollableArea() && layer()->scrollableArea()->adjustForForceCompositedScrollingMode(m_needsToBeStackingContainer);
-}
-
-// Determine whether the current layer can be promoted to a stacking container.
-// We do this by computing what positive and negative z-order lists would look
-// like before and after promotion, and ensuring that proper stacking order is
-// preserved between the two sets of lists.
-void RenderLayerStackingNode::updateDescendantsAreContiguousInStackingOrder()
-{
- TRACE_EVENT0("blink_rendering,comp-scroll", "RenderLayerStackingNode::updateDescendantsAreContiguousInStackingOrder");
-
- const RenderLayer* currentLayer = layer();
- if (isStackingContext() || !m_descendantsAreContiguousInStackingOrderDirty || !currentLayer->acceleratedCompositingForOverflowScrollEnabled())
- return;
-
- if (!currentLayer->scrollsOverflow())
- return;
-
- RenderLayerStackingNode* stackingNode = ancestorStackingNode();
- if (!stackingNode)
- return;
-
- OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderListBeforePromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
- OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderListBeforePromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
- OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderListAfterPromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
- OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderListAfterPromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
-
- collectBeforePromotionZOrderList(stackingNode, posZOrderListBeforePromote, negZOrderListBeforePromote);
- collectAfterPromotionZOrderList(stackingNode, posZOrderListAfterPromote, negZOrderListAfterPromote);
-
- size_t maxIndex = std::min(posZOrderListAfterPromote->size() + negZOrderListAfterPromote->size(), posZOrderListBeforePromote->size() + negZOrderListBeforePromote->size());
-
- m_descendantsAreContiguousInStackingOrderDirty = false;
- m_descendantsAreContiguousInStackingOrder = false;
-
- const RenderLayerStackingNode* nodeAfterPromote = 0;
- for (size_t i = 0; i < maxIndex && nodeAfterPromote != this; ++i) {
- const RenderLayerStackingNode* nodeBeforePromote = i < negZOrderListBeforePromote->size()
- ? negZOrderListBeforePromote->at(i)
- : posZOrderListBeforePromote->at(i - negZOrderListBeforePromote->size());
- nodeAfterPromote = i < negZOrderListAfterPromote->size()
- ? negZOrderListAfterPromote->at(i)
- : posZOrderListAfterPromote->at(i - negZOrderListAfterPromote->size());
-
- if (nodeBeforePromote != nodeAfterPromote && (nodeAfterPromote != this || renderer()->hasBackground()))
- return;
- }
-
- nodeAfterPromote = 0;
- for (size_t i = 0; i < maxIndex && nodeAfterPromote != this; ++i) {
- const RenderLayerStackingNode* nodeBeforePromote = i < posZOrderListBeforePromote->size()
- ? posZOrderListBeforePromote->at(posZOrderListBeforePromote->size() - i - 1)
- : negZOrderListBeforePromote->at(negZOrderListBeforePromote->size() + posZOrderListBeforePromote->size() - i - 1);
- nodeAfterPromote = i < posZOrderListAfterPromote->size()
- ? posZOrderListAfterPromote->at(posZOrderListAfterPromote->size() - i - 1)
- : negZOrderListAfterPromote->at(negZOrderListAfterPromote->size() + posZOrderListAfterPromote->size() - i - 1);
-
- if (nodeBeforePromote != nodeAfterPromote && nodeAfterPromote != this)
- return;
- }
-
- m_descendantsAreContiguousInStackingOrder = true;
-}
-
-void RenderLayerStackingNode::collectBeforePromotionZOrderList(RenderLayerStackingNode* ancestorStackingNode,
- OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList)
-{
- ancestorStackingNode->rebuildZOrderLists(posZOrderList, negZOrderList, this, OnlyStackingContextsCanBeStackingContainers);
-
- const RenderLayer* currentLayer = layer();
- const RenderLayer* positionedAncestor = currentLayer->parent();
- while (positionedAncestor && !positionedAncestor->isPositionedContainer() && !positionedAncestor->stackingNode()->isStackingContext())
- positionedAncestor = positionedAncestor->parent();
- if (positionedAncestor && (!positionedAncestor->isPositionedContainer() || positionedAncestor->stackingNode()->isStackingContext()))
- positionedAncestor = 0;
-
- if (!posZOrderList)
- posZOrderList = adoptPtr(new Vector<RenderLayerStackingNode*>());
- else if (posZOrderList->find(this) != kNotFound)
- return;
-
- // The current node will appear in the z-order lists after promotion, so
- // for a meaningful comparison, we must insert it in the z-order lists
- // before promotion if it does not appear there already.
- if (!positionedAncestor) {
- posZOrderList->prepend(this);
- return;
- }
-
- for (size_t index = 0; index < posZOrderList->size(); index++) {
- if (posZOrderList->at(index)->layer() == positionedAncestor) {
- posZOrderList->insert(index + 1, this);
- return;
- }
- }
-}
-
-void RenderLayerStackingNode::collectAfterPromotionZOrderList(RenderLayerStackingNode* ancestorStackingNode,
- OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList)
-{
- ancestorStackingNode->rebuildZOrderLists(posZOrderList, negZOrderList, this, ForceLayerToStackingContainer);
+ dirtyStackingContextZOrderLists();
}
-// Compute what positive and negative z-order lists would look like before and
-// after promotion, so we can later ensure that proper stacking order is
-// preserved between the two sets of lists.
-//
-// A few examples:
-// c = currentLayer
-// - = negative z-order child of currentLayer
-// + = positive z-order child of currentLayer
-// a = positioned ancestor of currentLayer
-// x = any other RenderLayer in the list
-//
-// (a) xxxxx-----++a+++x
-// (b) xxx-----c++++++xx
-//
-// Normally the current layer would be painted in the normal flow list if it
-// doesn't already appear in the positive z-order list. However, in the case
-// that the layer has a positioned ancestor, it will paint directly after the
-// positioned ancestor. In example (a), the current layer would be painted in
-// the middle of its own positive z-order children, so promoting would cause a
-// change in paint order (since a promoted layer will paint all of its positive
-// z-order children strictly after it paints itself).
-//
-// In example (b), it is ok to promote the current layer only if it does not
-// have a background. If it has a background, the background gets painted before
-// the layer's negative z-order children, so again, a promotion would cause a
-// change in paint order (causing the background to get painted after the
-// negative z-order children instead of before).
-//
-void RenderLayerStackingNode::computePaintOrderList(PaintOrderListType type, Vector<RefPtr<Node> >& list)
+RenderLayerStackingNode* RenderLayerStackingNode::ancestorStackingContextNode() const
{
- OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderList;
- OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderList;
-
- RenderLayerStackingNode* stackingNode = ancestorStackingNode();
- if (!stackingNode)
- return;
-
- switch (type) {
- case BeforePromote:
- collectBeforePromotionZOrderList(stackingNode, posZOrderList, negZOrderList);
- break;
- case AfterPromote:
- collectAfterPromotionZOrderList(stackingNode, posZOrderList, negZOrderList);
- break;
- }
-
- if (negZOrderList) {
- for (size_t index = 0; index < negZOrderList->size(); ++index)
- list.append(negZOrderList->at(index)->renderer()->node());
- }
-
- if (posZOrderList) {
- for (size_t index = 0; index < posZOrderList->size(); ++index)
- list.append(posZOrderList->at(index)->renderer()->node());
+ for (RenderLayer* ancestor = layer()->parent(); ancestor; ancestor = ancestor->parent()) {
+ RenderLayerStackingNode* stackingNode = ancestor->stackingNode();
+ if (stackingNode->isStackingContext())
+ return stackingNode;
}
-}
-
-bool RenderLayerStackingNode::descendantsAreContiguousInStackingOrder() const
-{
- if (isStackingContext() || !ancestorStackingContainerNode())
- return true;
-
- ASSERT(!m_descendantsAreContiguousInStackingOrderDirty);
- return m_descendantsAreContiguousInStackingOrder;
-}
-
-bool RenderLayerStackingNode::setNeedsToBeStackingContainer(bool needsToBeStackingContainer)
-{
- if (this->needsToBeStackingContainer() == needsToBeStackingContainer)
- return false;
-
- // Count the total number of RenderLayers which need to be stacking
- // containers some point. This should be recorded at most once per
- // RenderLayer, so we check m_needsToBeStackingContainerHasBeenRecorded.
- if (layer()->acceleratedCompositingForOverflowScrollEnabled() && !m_needsToBeStackingContainerHasBeenRecorded) {
- blink::Platform::current()->histogramEnumeration("Renderer.CompositedScrolling", RenderLayer::NeedsToBeStackingContainerBucket, RenderLayer::CompositedScrollingHistogramMax);
- m_needsToBeStackingContainerHasBeenRecorded = true;
- }
-
- m_needsToBeStackingContainer = needsToBeStackingContainer;
-
- return true;
-}
-
-RenderLayerStackingNode* RenderLayerStackingNode::ancestorStackingContainerNode() const
-{
- RenderLayer* ancestor = layer()->parent();
- while (ancestor && !ancestor->stackingNode()->isStackingContainer())
- ancestor = ancestor->parent();
- if (ancestor)
- return ancestor->stackingNode();
- return 0;
-}
-
-RenderLayerStackingNode* RenderLayerStackingNode::ancestorStackingNode() const
-{
- RenderLayer* ancestor = layer()->parent();
- while (ancestor && !ancestor->stackingNode()->isStackingContext())
- ancestor = ancestor->parent();
- if (ancestor)
- return ancestor->stackingNode();
return 0;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.h
index 12d7490fd8f..abe6b68c218 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNode.h
@@ -65,20 +65,7 @@ public:
int zIndex() const { return renderer()->style()->zIndex(); }
// A stacking context is a layer that has a non-auto z-index.
- bool isStackingContext() const { return isStackingContext(renderer()->style()); }
-
- // A stacking container can have z-order lists. All stacking contexts are
- // stacking containers, but the converse is not true. Layers that use
- // composited scrolling are stacking containers, but they may not
- // necessarily be stacking contexts.
- bool isStackingContainer() const { return isStackingContext() || needsToBeStackingContainer(); }
-
- bool setNeedsToBeStackingContainer(bool);
-
- // Returns true if z ordering would not change if this layer were a stacking container.
- bool descendantsAreContiguousInStackingOrder() const;
- void setDescendantsAreContiguousInStackingOrderDirty(bool flag) { m_descendantsAreContiguousInStackingOrderDirty = flag; }
- void updateDescendantsAreContiguousInStackingOrder();
+ bool isStackingContext() const { return !renderer()->style()->hasAutoZIndex(); }
// Update our normal and z-index lists.
void updateLayerListsIfNeeded();
@@ -87,31 +74,28 @@ public:
void dirtyZOrderLists();
void updateZOrderLists();
void clearZOrderLists();
- void dirtyStackingContainerZOrderLists();
+ void dirtyStackingContextZOrderLists();
bool hasPositiveZOrderList() const { return posZOrderList() && posZOrderList()->size(); }
bool hasNegativeZOrderList() const { return negZOrderList() && negZOrderList()->size(); }
+ // FIXME: should check for dirtiness here?
bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
void updateIsNormalFlowOnly();
bool normalFlowListDirty() const { return m_normalFlowListDirty; }
void dirtyNormalFlowList();
- enum PaintOrderListType {BeforePromote, AfterPromote};
- void computePaintOrderList(PaintOrderListType, Vector<RefPtr<Node> >&);
-
void updateStackingNodesAfterStyleChange(const RenderStyle* oldStyle);
- RenderLayerStackingNode* ancestorStackingContainerNode() const;
- RenderLayerStackingNode* ancestorStackingNode() const;
+ RenderLayerStackingNode* ancestorStackingContextNode() const;
- // Gets the enclosing stacking container for this node, possibly the node
- // itself, if it is a stacking container.
- RenderLayerStackingNode* enclosingStackingContainerNode() { return isStackingContainer() ? this : ancestorStackingContainerNode(); }
+ // Gets the enclosing stacking context for this node, possibly the node
+ // itself, if it is a stacking context.
+ RenderLayerStackingNode* enclosingStackingContextNode() { return isStackingContext() ? this : ancestorStackingContextNode(); }
RenderLayer* layer() const { return m_layer; }
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }
void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; }
#endif
@@ -124,7 +108,7 @@ private:
Vector<RenderLayerStackingNode*>* posZOrderList() const
{
ASSERT(!m_zOrderListsDirty);
- ASSERT(isStackingContainer() || !m_posZOrderList);
+ ASSERT(isStackingContext() || !m_posZOrderList);
return m_posZOrderList.get();
}
@@ -137,33 +121,14 @@ private:
Vector<RenderLayerStackingNode*>* negZOrderList() const
{
ASSERT(!m_zOrderListsDirty);
- ASSERT(isStackingContainer() || !m_negZOrderList);
+ ASSERT(isStackingContext() || !m_negZOrderList);
return m_negZOrderList.get();
}
- enum CollectLayersBehavior {
- ForceLayerToStackingContainer,
- OverflowScrollCanBeStackingContainers,
- OnlyStackingContextsCanBeStackingContainers
- };
-
- bool isStackingContext(const RenderStyle*) const;
-
void rebuildZOrderLists();
+ void collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList);
- // layerToForceAsStackingContainer allows us to build pre-promotion and
- // post-promotion layer lists, by allowing us to treat a layer as if it is a
- // stacking context, without adding a new member to RenderLayer or modifying
- // the style (which could cause extra allocations).
- void rebuildZOrderLists(OwnPtr<Vector<RenderLayerStackingNode*> >&, OwnPtr<Vector<RenderLayerStackingNode*> >&,
- const RenderLayerStackingNode* nodeToForceAsStackingContainer = 0,
- CollectLayersBehavior = OverflowScrollCanBeStackingContainers);
-
- void collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >&,
- OwnPtr<Vector<RenderLayerStackingNode*> >&, const RenderLayerStackingNode* nodeToForceAsStackingContainer = 0,
- CollectLayersBehavior = OverflowScrollCanBeStackingContainers);
-
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool isInStackingParentZOrderLists() const;
bool isInStackingParentNormalFlowList() const;
void updateStackingParentForZOrderLists(RenderLayerStackingNode* stackingParent);
@@ -172,21 +137,10 @@ private:
#endif
bool shouldBeNormalFlowOnly() const;
- bool shouldBeNormalFlowOnlyIgnoringCompositedScrolling() const;
void updateNormalFlowList();
- void dirtyNormalFlowListCanBePromotedToStackingContainer();
-
- void dirtySiblingStackingNodeCanBePromotedToStackingContainer();
-
- void collectBeforePromotionZOrderList(RenderLayerStackingNode*,
- OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList);
- void collectAfterPromotionZOrderList(RenderLayerStackingNode*,
- OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList);
- bool isDirtyStackingContainer() const { return m_zOrderListsDirty && isStackingContainer(); }
-
- bool needsToBeStackingContainer() const;
+ bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
RenderLayerCompositor* compositor() const;
// FIXME: Investigate changing this to Renderbox.
@@ -194,31 +148,21 @@ private:
RenderLayer* m_layer;
- // For stacking contexts, m_posZOrderList holds a sorted list of all the
- // descendant nodes within the stacking context that have z-indices of 0 or greater
- // (auto will count as 0). m_negZOrderList holds descendants within our stacking context with negative
- // z-indices.
+ // m_posZOrderList holds a sorted list of all the descendant nodes within
+ // that have z-indices of 0 or greater (auto will count as 0).
+ // m_negZOrderList holds descendants within our stacking context with
+ // negative z-indices.
OwnPtr<Vector<RenderLayerStackingNode*> > m_posZOrderList;
OwnPtr<Vector<RenderLayerStackingNode*> > m_negZOrderList;
- // This list contains child nodes that cannot create stacking contexts. For now it is just
- // overflow layers, but that may change in the future.
+ // This list contains child nodes that cannot create stacking contexts.
OwnPtr<Vector<RenderLayerStackingNode*> > m_normalFlowList;
- // If this is true, then no non-descendant appears between any of our
- // descendants in stacking order. This is one of the requirements of being
- // able to safely become a stacking context.
- unsigned m_descendantsAreContiguousInStackingOrder : 1;
- unsigned m_descendantsAreContiguousInStackingOrderDirty : 1;
-
unsigned m_zOrderListsDirty : 1;
unsigned m_normalFlowListDirty: 1;
unsigned m_isNormalFlowOnly : 1;
- unsigned m_needsToBeStackingContainer : 1;
- unsigned m_needsToBeStackingContainerHasBeenRecorded : 1;
-
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
unsigned m_layerListMutationAllowed : 1;
RenderLayerStackingNode* m_stackingParent;
#endif
@@ -226,9 +170,9 @@ private:
inline void RenderLayerStackingNode::clearZOrderLists()
{
- ASSERT(!isStackingContainer());
+ ASSERT(!isStackingContext());
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
updateStackingParentForZOrderLists(0);
#endif
@@ -241,7 +185,7 @@ inline void RenderLayerStackingNode::updateZOrderLists()
if (!m_zOrderListsDirty)
return;
- if (!isStackingContainer()) {
+ if (!isStackingContext()) {
clearZOrderLists();
m_zOrderListsDirty = false;
return;
@@ -250,7 +194,7 @@ inline void RenderLayerStackingNode::updateZOrderLists()
rebuildZOrderLists();
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
class LayerListMutationDetector {
public:
explicit LayerListMutationDetector(RenderLayerStackingNode* stackingNode)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNodeIterator.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNodeIterator.h
index 7682ea33d58..b230371fe1a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNodeIterator.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLayerStackingNodeIterator.h
@@ -42,7 +42,6 @@ enum ChildrenIteration {
AllChildren = NegativeZOrderChildren | NormalFlowChildren | PositiveZOrderChildren
};
-class RenderLayer;
class RenderLayerStackingNode;
// This iterator walks the RenderLayerStackingNode lists in the following order:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.cpp
index 085224721fe..9e0f01a30bc 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.cpp
@@ -170,27 +170,25 @@ bool RenderLineBoxList::rangeIntersectsRect(RenderBoxModelObject* renderer, Layo
return true;
}
-bool RenderLineBoxList::anyLineIntersectsRect(RenderBoxModelObject* renderer, const LayoutRect& rect, const LayoutPoint& offset, LayoutUnit outlineSize) const
+bool RenderLineBoxList::anyLineIntersectsRect(RenderBoxModelObject* renderer, const LayoutRect& rect, const LayoutPoint& offset) const
{
// We can check the first box and last box and avoid painting/hit testing if we don't
// intersect. This is a quick short-circuit that we can take to avoid walking any lines.
// FIXME: This check is flawed in the following extremely obscure way:
// if some line in the middle has a huge overflow, it might actually extend below the last line.
- RootInlineBox* firstRootBox = firstLineBox()->root();
- RootInlineBox* lastRootBox = lastLineBox()->root();
- LayoutUnit firstLineTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox->lineTop());
- LayoutUnit lastLineBottom = lastLineBox()->logicalBottomVisualOverflow(lastRootBox->lineBottom());
- LayoutUnit logicalTop = firstLineTop - outlineSize;
- LayoutUnit logicalBottom = outlineSize + lastLineBottom;
-
- return rangeIntersectsRect(renderer, logicalTop, logicalBottom, rect, offset);
+ RootInlineBox& firstRootBox = firstLineBox()->root();
+ RootInlineBox& lastRootBox = lastLineBox()->root();
+ LayoutUnit firstLineTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox.lineTop());
+ LayoutUnit lastLineBottom = lastLineBox()->logicalBottomVisualOverflow(lastRootBox.lineBottom());
+
+ return rangeIntersectsRect(renderer, firstLineTop, lastLineBottom, rect, offset);
}
bool RenderLineBoxList::lineIntersectsDirtyRect(RenderBoxModelObject* renderer, InlineFlowBox* box, const PaintInfo& paintInfo, const LayoutPoint& offset) const
{
- RootInlineBox* root = box->root();
- LayoutUnit logicalTop = min<LayoutUnit>(box->logicalTopVisualOverflow(root->lineTop()), root->selectionTop()) - renderer->maximalOutlineSize(paintInfo.phase);
- LayoutUnit logicalBottom = box->logicalBottomVisualOverflow(root->lineBottom()) + renderer->maximalOutlineSize(paintInfo.phase);
+ RootInlineBox& root = box->root();
+ LayoutUnit logicalTop = min<LayoutUnit>(box->logicalTopVisualOverflow(root.lineTop()), root.selectionTop());
+ LayoutUnit logicalBottom = box->logicalBottomVisualOverflow(root.lineBottom());
return rangeIntersectsRect(renderer, logicalTop, logicalBottom, paintInfo.rect, offset);
}
@@ -209,8 +207,7 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
if (!firstLineBox())
return;
- LayoutUnit outlineSize = renderer->maximalOutlineSize(paintInfo.phase);
- if (!anyLineIntersectsRect(renderer, paintInfo.rect, paintOffset, outlineSize))
+ if (!anyLineIntersectsRect(renderer, paintInfo.rect, paintOffset))
return;
PaintInfo info(paintInfo);
@@ -222,8 +219,8 @@ void RenderLineBoxList::paint(RenderBoxModelObject* renderer, PaintInfo& paintIn
// based off positions of our first line box or our last line box.
for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
if (lineIntersectsDirtyRect(renderer, curr, info, paintOffset)) {
- RootInlineBox* root = curr->root();
- curr->paint(info, paintOffset, root->lineTop(), root->lineBottom());
+ RootInlineBox& root = curr->root();
+ curr->paint(info, paintOffset, root.lineTop(), root.lineBottom());
}
}
@@ -260,9 +257,9 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq
// them further. Note that boxes can easily overlap, so we can't make any assumptions
// based off positions of our first line box or our last line box.
for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) {
- RootInlineBox* root = curr->root();
- if (rangeIntersectsRect(renderer, curr->logicalTopVisualOverflow(root->lineTop()), curr->logicalBottomVisualOverflow(root->lineBottom()), rect, accumulatedOffset)) {
- bool inside = curr->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, root->lineTop(), root->lineBottom());
+ RootInlineBox& root = curr->root();
+ if (rangeIntersectsRect(renderer, curr->logicalTopVisualOverflow(root.lineTop()), curr->logicalBottomVisualOverflow(root.lineBottom()), rect, accumulatedOffset)) {
+ bool inside = curr->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, root.lineTop(), root.lineBottom());
if (inside) {
renderer->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
return true;
@@ -304,15 +301,15 @@ void RenderLineBoxList::dirtyLinesFromChangedChild(RenderObject* container, Rend
if (curr->isReplaced()) {
InlineBox* wrapper = toRenderBox(curr)->inlineBoxWrapper();
if (wrapper)
- box = wrapper->root();
+ box = &wrapper->root();
} else if (curr->isText()) {
InlineTextBox* textBox = toRenderText(curr)->lastTextBox();
if (textBox)
- box = textBox->root();
+ box = &textBox->root();
} else if (curr->isRenderInline()) {
InlineBox* lastSiblingBox = toRenderInline(curr)->lastLineBoxIncludingCulling();
if (lastSiblingBox)
- box = lastSiblingBox->root();
+ box = &lastSiblingBox->root();
}
if (box)
@@ -331,7 +328,7 @@ void RenderLineBoxList::dirtyLinesFromChangedChild(RenderObject* container, Rend
}
return;
}
- box = firstBox->root();
+ box = &firstBox->root();
}
// If we found a line box, then dirty it.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.h b/chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.h
index b57a4a03806..611b4d42ba8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderLineBoxList.h
@@ -67,7 +67,7 @@ public:
bool hitTest(RenderBoxModelObject*, const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) const;
private:
- bool anyLineIntersectsRect(RenderBoxModelObject*, const LayoutRect&, const LayoutPoint&, LayoutUnit outlineSize = 0) const;
+ bool anyLineIntersectsRect(RenderBoxModelObject*, const LayoutRect&, const LayoutPoint&) const;
bool lineIntersectsDirtyRect(RenderBoxModelObject*, InlineFlowBox*, const PaintInfo&, const LayoutPoint&) const;
bool rangeIntersectsRect(RenderBoxModelObject*, LayoutUnit logicalTop, LayoutUnit logicalBottom, const LayoutRect&, const LayoutPoint&) const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderListBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderListBox.cpp
index bc4617f29ff..82c22b91945 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderListBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderListBox.cpp
@@ -30,25 +30,23 @@
#include "config.h"
#include "core/rendering/RenderListBox.h"
-#include <math.h>
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/Document.h"
#include "core/dom/NodeRenderStyle.h"
#include "core/editing/FrameSelection.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLOptGroupElement.h"
#include "core/html/HTMLOptionElement.h"
#include "core/html/HTMLSelectElement.h"
#include "core/page/EventHandler.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/page/SpatialNavigation.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/RenderText.h"
@@ -57,6 +55,8 @@
#include "platform/fonts/FontCache.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/scroll/Scrollbar.h"
+#include "platform/text/BidiTextRun.h"
+#include <math.h>
using namespace std;
@@ -86,10 +86,11 @@ RenderListBox::RenderListBox(Element* element)
, m_inAutoscroll(false)
, m_optionsWidth(0)
, m_indexOffset(0)
+ , m_listItemCount(0)
{
ASSERT(element);
ASSERT(element->isHTMLElement());
- ASSERT(element->hasTagName(HTMLNames::selectTag));
+ ASSERT(isHTMLSelectElement(element));
if (FrameView* frameView = frame()->view())
frameView->addScrollableArea(this);
@@ -103,6 +104,13 @@ RenderListBox::~RenderListBox()
frameView->removeScrollableArea(this);
}
+// FIXME: Instead of this hack we should add a ShadowRoot to <select> with no insertion point
+// to prevent children from rendering.
+bool RenderListBox::isChildAllowed(RenderObject* object, RenderStyle*) const
+{
+ return object->isAnonymous() && !object->isRenderFullScreen();
+}
+
inline HTMLSelectElement* RenderListBox::selectElement() const
{
return toHTMLSelectElement(node());
@@ -111,30 +119,46 @@ inline HTMLSelectElement* RenderListBox::selectElement() const
void RenderListBox::updateFromElement()
{
FontCachePurgePreventer fontCachePurgePreventer;
-
if (m_optionsChanged) {
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
- int size = numItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
+ int size = static_cast<int>(listItems.size());
float width = 0;
+ m_listItemCount = 0;
for (int i = 0; i < size; ++i) {
- HTMLElement* element = listItems[i];
+ const HTMLElement& element = *listItems[i];
+
String text;
Font itemFont = style()->font();
- if (element->hasTagName(optionTag)) {
- text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+ if (isHTMLOptionElement(element)) {
+ const HTMLOptionElement& optionElement = toHTMLOptionElement(element);
+ if (optionElement.isDisplayNone())
+ continue;
+ text = optionElement.textIndentedToRespectGroupLabel();
+ ++m_listItemCount;
} else if (isHTMLOptGroupElement(element)) {
- text = toHTMLOptGroupElement(element)->groupLabelText();
+ if (toHTMLOptGroupElement(element).isDisplayNone())
+ continue;
+ text = toHTMLOptGroupElement(element).groupLabelText();
FontDescription d = itemFont.fontDescription();
d.setWeight(d.bolderWeight());
- itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
+ itemFont = Font(d);
itemFont.update(document().styleEngine()->fontSelector());
+ ++m_listItemCount;
+ } else if (isHTMLHRElement(element)) {
+ // HTMLSelect adds it to its list, so we will also add it to match the count.
+ ++m_listItemCount;
+ continue;
}
if (!text.isEmpty()) {
applyTextTransform(style(), text, ' ');
- // FIXME: Why is this always LTR? Can't text direction affect the width?
+
+ bool hasStrongDirectionality;
+ TextDirection direction = determineDirectionality(text, hasStrongDirectionality);
TextRun textRun = constructTextRun(this, itemFont, text, style(), TextRun::AllowTrailingExpansion);
+ if (hasStrongDirectionality)
+ textRun.setDirection(direction);
textRun.disableRoundingHacks();
float textWidth = itemFont.width(textRun);
width = max(width, textWidth);
@@ -145,13 +169,13 @@ void RenderListBox::updateFromElement()
setHasVerticalScrollbar(true);
- setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
}
void RenderListBox::selectionChanged()
{
- repaint();
+ paintInvalidationForWholeRenderer();
if (!m_inAutoscroll) {
if (m_optionsChanged || needsLayout())
m_scrollToRevealSelectionAfterLayout = true;
@@ -165,7 +189,6 @@ void RenderListBox::selectionChanged()
void RenderListBox::layout()
{
- LayoutRectRecorder recorder(*this);
RenderBlockFlow::layout();
if (m_vBar) {
@@ -179,27 +202,32 @@ void RenderListBox::layout()
}
if (m_scrollToRevealSelectionAfterLayout) {
- LayoutStateDisabler layoutStateDisabler(view());
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
scrollToRevealSelection();
}
}
+void RenderListBox::invalidateTreeAfterLayout(const RenderLayerModelObject& invalidationContainer)
+{
+ repaintScrollbarIfNeeded();
+ RenderBox::invalidateTreeAfterLayout(invalidationContainer);
+}
+
void RenderListBox::scrollToRevealSelection()
{
HTMLSelectElement* select = selectElement();
m_scrollToRevealSelectionAfterLayout = false;
- int firstIndex = select->activeSelectionStartListIndex();
- if (firstIndex >= 0 && !listIndexIsVisible(select->activeSelectionEndListIndex()))
- scrollToRevealElementAtListIndex(firstIndex);
+ int firstIndex = listIndexToRenderListBoxIndex(select->activeSelectionStartListIndex());
+ int lastIndex = listIndexToRenderListBoxIndex(select->activeSelectionEndListIndex());
+ if (firstIndex >= 0 && !listIndexIsVisible(lastIndex))
+ scrollToRevealElementAtListIndexInternal(firstIndex);
}
void RenderListBox::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
- maxLogicalWidth = m_optionsWidth + 2 * optionsSpacingHorizontal;
- if (m_vBar)
- maxLogicalWidth += verticalScrollbarWidth();
+ maxLogicalWidth = m_optionsWidth + 2 * optionsSpacingHorizontal + verticalScrollbarWidth();
if (!style()->width().isPercent())
minLogicalWidth = maxLogicalWidth;
}
@@ -210,20 +238,21 @@ void RenderListBox::computePreferredLogicalWidths()
m_minPreferredLogicalWidth = 0;
m_maxPreferredLogicalWidth = 0;
+ RenderStyle* styleToUse = style();
- if (style()->width().isFixed() && style()->width().value() > 0)
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
+ if (styleToUse->width().isFixed() && styleToUse->width().value() > 0)
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->width().value());
else
computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
- if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
- m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
- m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
+ if (styleToUse->minWidth().isFixed() && styleToUse->minWidth().value() > 0) {
+ m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
+ m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
}
- if (style()->maxWidth().isFixed()) {
- m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
- m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
+ if (styleToUse->maxWidth().isFixed()) {
+ m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
+ m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
}
LayoutUnit toAdd = borderAndPaddingWidth();
@@ -250,7 +279,7 @@ int RenderListBox::numVisibleItems() const
int RenderListBox::numItems() const
{
- return selectElement()->listItems().size();
+ return m_listItemCount;
}
LayoutUnit RenderListBox::listHeight() const
@@ -260,7 +289,12 @@ LayoutUnit RenderListBox::listHeight() const
void RenderListBox::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{
- LayoutUnit height = itemHeight() * size() - rowSpacing + borderAndPaddingHeight();
+ LayoutUnit height = itemHeight() * size() - rowSpacing;
+ // FIXME: The item height should have been added before updateLogicalHeight was called to avoid this hack.
+ updateIntrinsicContentLogicalHeight(height);
+
+ height += borderAndPaddingHeight();
+
RenderBox::computeLogicalHeight(height, logicalTop, computedValues);
}
@@ -269,7 +303,7 @@ int RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, L
return RenderBox::baselinePosition(baselineType, firstLine, lineDirection, linePositionMode) - baselineAdjustment;
}
-LayoutRect RenderListBox::itemBoundingBoxRect(const LayoutPoint& additionalOffset, int index)
+LayoutRect RenderListBox::itemBoundingBoxRectInternal(const LayoutPoint& additionalOffset, int index) const
{
// For RTL, items start after the left-side vertical scrollbar.
int scrollbarOffset = style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? verticalScrollbarWidth() : 0;
@@ -294,7 +328,7 @@ void RenderListBox::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOf
}
// Paint the children.
- RenderBlock::paintObject(paintInfo, paintOffset);
+ RenderBlockFlow::paintObject(paintInfo, paintOffset);
switch (paintInfo.phase) {
// Depending on whether we have overlay scrollbars they
@@ -324,24 +358,24 @@ void RenderListBox::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOf
void RenderListBox::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
{
if (!isSpatialNavigationEnabled(frame()))
- return RenderBlock::addFocusRingRects(rects, additionalOffset, paintContainer);
+ return RenderBlockFlow::addFocusRingRects(rects, additionalOffset, paintContainer);
HTMLSelectElement* select = selectElement();
// Focus the last selected item.
int selectedItem = select->activeSelectionEndListIndex();
if (selectedItem >= 0) {
- rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffset, selectedItem)));
+ rects.append(pixelSnappedIntRect(itemBoundingBoxRectInternal(additionalOffset, selectedItem)));
return;
}
// No selected items, find the first non-disabled item.
int size = numItems();
- const Vector<HTMLElement*>& listItems = select->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = select->listItems();
for (int i = 0; i < size; ++i) {
- HTMLElement* element = listItems[i];
- if (element->hasTagName(optionTag) && !element->isDisabledFormControl()) {
- rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffset, i)));
+ HTMLElement* element = listItems[renderListBoxIndexToListIndex(i)];
+ if (isHTMLOptionElement(*element) && !element->isDisabledFormControl()) {
+ rects.append(pixelSnappedIntRect(itemBoundingBoxRectInternal(additionalOffset, i)));
return;
}
}
@@ -353,7 +387,7 @@ int RenderListBox::scrollbarLeft() const
if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
scrollbarLeft = borderLeft();
else
- scrollbarLeft = width() - borderRight() - verticalScrollbarWidth();
+ scrollbarLeft = width() - borderRight() - (m_vBar ? m_vBar->width() : 0);
return scrollbarLeft;
}
@@ -362,7 +396,7 @@ void RenderListBox::paintScrollbar(PaintInfo& paintInfo, const LayoutPoint& pain
if (m_vBar) {
IntRect scrollRect = pixelSnappedIntRect(paintOffset.x() + scrollbarLeft(),
paintOffset.y() + borderTop(),
- verticalScrollbarWidth(),
+ m_vBar->width(),
height() - (borderTop() + borderBottom()));
m_vBar->setFrameRect(scrollRect);
m_vBar->paint(paintInfo.context, paintInfo.rect);
@@ -395,8 +429,8 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint&
HTMLSelectElement* select = selectElement();
- const Vector<HTMLElement*>& listItems = select->listItems();
- HTMLElement* element = listItems[listIndex];
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = select->listItems();
+ HTMLElement* element = listItems[renderListBoxIndexToListIndex(listIndex)];
RenderStyle* itemStyle = element->renderStyle();
if (!itemStyle)
@@ -406,15 +440,15 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint&
return;
String itemText;
- bool isOptionElement = element->hasTagName(optionTag);
+ bool isOptionElement = isHTMLOptionElement(*element);
if (isOptionElement)
- itemText = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
- else if (isHTMLOptGroupElement(element))
- itemText = toHTMLOptGroupElement(element)->groupLabelText();
+ itemText = toHTMLOptionElement(*element).textIndentedToRespectGroupLabel();
+ else if (isHTMLOptGroupElement(*element))
+ itemText = toHTMLOptGroupElement(*element).groupLabelText();
applyTextTransform(style(), itemText, ' ');
Color textColor = element->renderStyle() ? resolveColor(element->renderStyle(), CSSPropertyColor) : resolveColor(CSSPropertyColor);
- if (isOptionElement && toHTMLOptionElement(element)->selected()) {
+ if (isOptionElement && ((toHTMLOptionElement(*element).selected() && select->suggestedIndex() < 0) || listIndex == select->suggestedIndex())) {
if (frame()->selection().isFocusedAndActive() && document().focusedElement() == node())
textColor = RenderTheme::theme().activeListBoxSelectionForegroundColor();
// Honor the foreground color for disabled items
@@ -426,13 +460,13 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint&
TextRun textRun(itemText, 0, 0, TextRun::AllowTrailingExpansion, itemStyle->direction(), isOverride(itemStyle->unicodeBidi()), true, TextRun::NoRounding);
Font itemFont = style()->font();
- LayoutRect r = itemBoundingBoxRect(paintOffset, listIndex);
+ LayoutRect r = itemBoundingBoxRectInternal(paintOffset, listIndex);
r.move(itemOffsetForAlignment(textRun, itemStyle, itemFont, r));
- if (isHTMLOptGroupElement(element)) {
+ if (isHTMLOptGroupElement(*element)) {
FontDescription d = itemFont.fontDescription();
d.setWeight(d.bolderWeight());
- itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
+ itemFont = Font(d);
itemFont.update(document().styleEngine()->fontSelector());
}
@@ -444,11 +478,11 @@ void RenderListBox::paintItemForeground(PaintInfo& paintInfo, const LayoutPoint&
void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint& paintOffset, int listIndex)
{
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
- HTMLElement* element = listItems[listIndex];
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
+ HTMLElement* element = listItems[renderListBoxIndexToListIndex(listIndex)];
Color backColor;
- if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected()) {
+ if (isHTMLOptionElement(*element) && ((toHTMLOptionElement(*element).selected() && selectElement()->suggestedIndex() < 0) || listIndex == selectElement()->suggestedIndex())) {
if (frame()->selection().isFocusedAndActive() && document().focusedElement() == node())
backColor = RenderTheme::theme().activeListBoxSelectionBackgroundColor();
else
@@ -459,7 +493,7 @@ void RenderListBox::paintItemBackground(PaintInfo& paintInfo, const LayoutPoint&
// Draw the background for this list box item
if (!element->renderStyle() || element->renderStyle()->visibility() != HIDDEN) {
- LayoutRect itemRect = itemBoundingBoxRect(paintOffset, listIndex);
+ LayoutRect itemRect = itemBoundingBoxRectInternal(paintOffset, listIndex);
itemRect.intersect(controlClipRect(paintOffset));
paintInfo.context->fillRect(pixelSnappedIntRect(itemRect), backColor);
}
@@ -482,7 +516,7 @@ bool RenderListBox::isPointInOverflowControl(HitTestResult& result, const Layout
return false;
}
-int RenderListBox::listIndexAtOffset(const LayoutSize& offset)
+int RenderListBox::listIndexAtOffset(const LayoutSize& offset) const
{
if (!numItems())
return -1;
@@ -498,7 +532,7 @@ int RenderListBox::listIndexAtOffset(const LayoutSize& offset)
return -1;
int newOffset = (offset.height() - borderTop() - paddingTop()) / itemHeight() + m_indexOffset;
- return newOffset < numItems() ? newOffset : -1;
+ return newOffset < numItems() ? renderListBoxIndexToListIndex(newOffset) : -1;
}
void RenderListBox::panScroll(const IntPoint& panStartMousePosition)
@@ -527,8 +561,7 @@ void RenderListBox::panScroll(const IntPoint& panStartMousePosition)
return;
if (yDelta > 0)
- //offsetY = view()->viewHeight();
- absOffset.move(0, listHeight());
+ absOffset.move(0, listHeight().toFloat());
else if (yDelta < 0)
yDelta--;
@@ -556,10 +589,10 @@ int RenderListBox::scrollToward(const IntPoint& destination)
int rows = numVisibleItems();
int offset = m_indexOffset;
- if (positionOffset.height() < borderTop() + paddingTop() && scrollToRevealElementAtListIndex(offset - 1))
+ if (positionOffset.height() < borderTop() + paddingTop() && scrollToRevealElementAtListIndexInternal(offset - 1))
return offset - 1;
- if (positionOffset.height() > height() - paddingBottom() - borderBottom() && scrollToRevealElementAtListIndex(offset + rows))
+ if (positionOffset.height() > height() - paddingBottom() - borderBottom() && scrollToRevealElementAtListIndexInternal(offset + rows))
return offset + rows - 1;
return listIndexAtOffset(positionOffset);
@@ -578,9 +611,9 @@ void RenderListBox::autoscroll(const IntPoint&)
m_inAutoscroll = true;
if (!select->multiple())
- select->setActiveSelectionAnchorIndex(endIndex);
+ select->setActiveSelectionAnchorIndex(renderListBoxIndexToListIndex(endIndex));
- select->setActiveSelectionEndIndex(endIndex);
+ select->setActiveSelectionEndIndex(renderListBoxIndexToListIndex(endIndex));
select->updateListBoxSelection(!select->multiple());
m_inAutoscroll = false;
}
@@ -594,7 +627,7 @@ void RenderListBox::stopAutoscroll()
selectElement()->listBoxOnChange();
}
-bool RenderListBox::scrollToRevealElementAtListIndex(int index)
+bool RenderListBox::scrollToRevealElementAtListIndexInternal(int index)
{
if (index < 0 || index >= numItems() || listIndexIsVisible(index))
return false;
@@ -610,7 +643,7 @@ bool RenderListBox::scrollToRevealElementAtListIndex(int index)
return true;
}
-bool RenderListBox::listIndexIsVisible(int index)
+bool RenderListBox::listIndexIsVisible(int index) const
{
return index >= m_indexOffset && index < m_indexOffset + numVisibleItems();
}
@@ -620,13 +653,6 @@ bool RenderListBox::scroll(ScrollDirection direction, ScrollGranularity granular
return ScrollableArea::scroll(direction, granularity, multiplier);
}
-void RenderListBox::valueChanged(unsigned listIndex)
-{
- HTMLSelectElement* element = selectElement();
- element->setSelectedIndex(element->listToOptionIndex(listIndex));
- element->dispatchFormControlChangeEvent();
-}
-
int RenderListBox::scrollSize(ScrollbarOrientation orientation) const
{
return orientation == VerticalScrollbar ? (numItems() - numVisibleItems()) : 0;
@@ -648,7 +674,12 @@ void RenderListBox::scrollTo(int newOffset)
return;
m_indexOffset = newOffset;
- repaint();
+
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && frameView()->isInPerformLayout())
+ setShouldDoFullPaintInvalidationAfterLayout(true);
+ else
+ paintInvalidationForWholeRenderer();
+
node()->document().enqueueScrollEventForNode(node());
}
@@ -664,32 +695,32 @@ int RenderListBox::verticalScrollbarWidth() const
// FIXME: We ignore padding in the vertical direction as far as these values are concerned, since that's
// how the control currently paints.
-int RenderListBox::scrollWidth() const
+LayoutUnit RenderListBox::scrollWidth() const
{
// There is no horizontal scrolling allowed.
- return pixelSnappedClientWidth();
+ return clientWidth();
}
-int RenderListBox::scrollHeight() const
+LayoutUnit RenderListBox::scrollHeight() const
{
- return max(pixelSnappedClientHeight(), roundToInt(listHeight()));
+ return max(clientHeight(), listHeight());
}
-int RenderListBox::scrollLeft() const
+LayoutUnit RenderListBox::scrollLeft() const
{
return 0;
}
-void RenderListBox::setScrollLeft(int)
+void RenderListBox::setScrollLeft(LayoutUnit)
{
}
-int RenderListBox::scrollTop() const
+LayoutUnit RenderListBox::scrollTop() const
{
return m_indexOffset * itemHeight();
}
-void RenderListBox::setScrollTop(int newTop)
+void RenderListBox::setScrollTop(LayoutUnit newTop)
{
// Determine an index and scroll to it.
int index = newTop / itemHeight();
@@ -701,15 +732,15 @@ void RenderListBox::setScrollTop(int newTop)
bool RenderListBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
{
- if (!RenderBlock::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction))
+ if (!RenderBlockFlow::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction))
return false;
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
int size = numItems();
LayoutPoint adjustedLocation = accumulatedOffset + location();
for (int i = 0; i < size; ++i) {
- if (itemBoundingBoxRect(adjustedLocation, i).contains(locationInContainer.point())) {
- if (Element* node = listItems[i]) {
+ if (itemBoundingBoxRectInternal(adjustedLocation, i).contains(locationInContainer.point())) {
+ if (Element* node = listItems[renderListBoxIndexToListIndex(i)]) {
result.setInnerNode(node);
if (!result.innerNonSharedNode())
result.setInnerNonSharedNode(node);
@@ -745,7 +776,22 @@ void RenderListBox::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect&
scrollRect.move(borderLeft(), borderTop());
else
scrollRect.move(width() - borderRight() - scrollbar->width(), borderTop());
- repaintRectangle(scrollRect);
+
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && frameView()->isInPerformLayout()) {
+ m_verticalBarDamage = scrollRect;
+ m_hasVerticalBarDamage = true;
+ } else {
+ invalidatePaintRectangle(scrollRect);
+ }
+}
+
+void RenderListBox::repaintScrollbarIfNeeded()
+{
+ if (!hasVerticalBarDamage())
+ return;
+ invalidatePaintRectangle(verticalBarDamage());
+
+ resetScrollbarDamage();
}
IntRect RenderListBox::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
@@ -759,7 +805,7 @@ IntRect RenderListBox::convertFromScrollbarToContainingView(const Scrollbar* scr
int scrollbarTop = borderTop();
rect.move(scrollbarLeft(), scrollbarTop);
- return view->frameView()->convertFromRenderer(this, rect);
+ return view->frameView()->convertFromRenderer(*this, rect);
}
IntRect RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
@@ -768,7 +814,7 @@ IntRect RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar* scr
if (!view)
return parentRect;
- IntRect rect = view->frameView()->convertToRenderer(this, parentRect);
+ IntRect rect = view->frameView()->convertToRenderer(*this, parentRect);
int scrollbarTop = borderTop();
rect.move(-scrollbarLeft(), -scrollbarTop);
@@ -786,7 +832,7 @@ IntPoint RenderListBox::convertFromScrollbarToContainingView(const Scrollbar* sc
int scrollbarTop = borderTop();
point.move(scrollbarLeft(), scrollbarTop);
- return view->frameView()->convertFromRenderer(this, point);
+ return view->frameView()->convertFromRenderer(*this, point);
}
IntPoint RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
@@ -795,7 +841,7 @@ IntPoint RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar* sc
if (!view)
return parentPoint;
- IntPoint point = view->frameView()->convertToRenderer(this, parentPoint);
+ IntPoint point = view->frameView()->convertToRenderer(*this, parentPoint);
int scrollbarTop = borderTop();
point.move(-scrollbarLeft(), -scrollbarTop);
@@ -848,7 +894,7 @@ IntPoint RenderListBox::minimumScrollPosition() const
IntPoint RenderListBox::maximumScrollPosition() const
{
- return IntPoint(0, numItems() - numVisibleItems());
+ return IntPoint(0, std::max(numItems() - numVisibleItems(), 0));
}
bool RenderListBox::userInputScrollable(ScrollbarOrientation orientation) const
@@ -876,12 +922,6 @@ float RenderListBox::pixelStep(ScrollbarOrientation) const
return 1.0f / itemHeight();
}
-ScrollableArea* RenderListBox::enclosingScrollableArea() const
-{
- // FIXME: Return a RenderLayer that's scrollable.
- return 0;
-}
-
IntRect RenderListBox::scrollableAreaBoundingBox() const
{
return absoluteBoundingBoxRect();
@@ -910,7 +950,7 @@ void RenderListBox::destroyScrollbar()
ScrollableArea::willRemoveScrollbar(m_vBar.get(), VerticalScrollbar);
m_vBar->removeFromParent();
m_vBar->disconnectFromScrollableArea();
- m_vBar = 0;
+ m_vBar = nullptr;
}
void RenderListBox::setHasVerticalScrollbar(bool hasScrollbar)
@@ -931,4 +971,59 @@ void RenderListBox::setHasVerticalScrollbar(bool hasScrollbar)
document().setAnnotatedRegionsDirty(true);
}
+int RenderListBox::renderListBoxIndexToListIndex(int index) const
+{
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
+ const int size = static_cast<int>(listItems.size());
+
+ if (size == numItems())
+ return index;
+
+ int listBoxIndex = 0;
+ int listIndex = 0;
+ for (; listIndex < size; ++listIndex) {
+ const HTMLElement& element = *listItems[listIndex];
+ if (isHTMLOptionElement(element) && toHTMLOptionElement(element).isDisplayNone())
+ continue;
+ if (isHTMLOptGroupElement(element) && toHTMLOptGroupElement(element).isDisplayNone())
+ continue;
+ if (index == listBoxIndex)
+ break;
+ ++listBoxIndex;
+ }
+ return listIndex;
+}
+
+int RenderListBox::listIndexToRenderListBoxIndex(int index) const
+{
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
+ const int size = static_cast<int>(listItems.size());
+
+ if (size == numItems())
+ return index;
+
+ int listBoxIndex = 0;
+ for (int listIndex = 0; listIndex < size; ++listIndex) {
+ const HTMLElement& element = *listItems[listIndex];
+ if (isHTMLOptionElement(element) && toHTMLOptionElement(element).isDisplayNone())
+ continue;
+ if (isHTMLOptGroupElement(element) && toHTMLOptGroupElement(element).isDisplayNone())
+ continue;
+ if (index == listIndex)
+ break;
+ ++listBoxIndex;
+ }
+ return listBoxIndex;
+}
+
+LayoutRect RenderListBox::itemBoundingBoxRect(const LayoutPoint& point, int index) const
+{
+ return itemBoundingBoxRectInternal(point, listIndexToRenderListBoxIndex(index));
+}
+
+bool RenderListBox::scrollToRevealElementAtListIndex(int index)
+{
+ return scrollToRevealElementAtListIndexInternal(listIndexToRenderListBoxIndex(index));
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderListBox.h b/chromium/third_party/WebKit/Source/core/rendering/RenderListBox.h
index c86b50869bc..9a99eab5f17 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderListBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderListBox.h
@@ -47,57 +47,58 @@ public:
void setOptionsChanged(bool changed) { m_optionsChanged = changed; }
- int listIndexAtOffset(const LayoutSize&);
- LayoutRect itemBoundingBoxRect(const LayoutPoint&, int index);
+ int listIndexAtOffset(const LayoutSize&) const;
+ LayoutRect itemBoundingBoxRect(const LayoutPoint&, int index) const;
bool scrollToRevealElementAtListIndex(int index);
- bool listIndexIsVisible(int index);
int scrollToward(const IntPoint&); // Returns the new index or -1 if no scroll occurred
int size() const;
+ void repaintScrollbarIfNeeded();
+
private:
HTMLSelectElement* selectElement() const;
- virtual const char* renderName() const { return "RenderListBox"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderListBox"; }
- virtual bool isListBox() const { return true; }
+ virtual bool isListBox() const OVERRIDE { return true; }
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
- virtual void updateFromElement();
- virtual bool hasControlClip() const { return true; }
- virtual void paintObject(PaintInfo&, const LayoutPoint&);
- virtual LayoutRect controlClipRect(const LayoutPoint&) const;
+ virtual void updateFromElement() OVERRIDE;
+ virtual bool hasControlClip() const OVERRIDE { return true; }
+ virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual LayoutRect controlClipRect(const LayoutPoint&) const OVERRIDE;
- virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
+ virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset) OVERRIDE;
virtual bool scroll(ScrollDirection, ScrollGranularity, float) OVERRIDE;
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
virtual void computePreferredLogicalWidths() OVERRIDE;
- virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
- virtual void layout();
+ virtual void layout() OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual void invalidateTreeAfterLayout(const RenderLayerModelObject&) OVERRIDE FINAL;
virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
- virtual bool canBeProgramaticallyScrolled() const { return true; }
- virtual void autoscroll(const IntPoint&);
- virtual void stopAutoscroll();
+ virtual bool canBeProgramaticallyScrolled() const OVERRIDE { return true; }
+ virtual void autoscroll(const IntPoint&) OVERRIDE;
+ virtual void stopAutoscroll() OVERRIDE;
- virtual bool shouldPanScroll() const { return true; }
- virtual void panScroll(const IntPoint&);
+ virtual void panScroll(const IntPoint&) OVERRIDE;
- virtual int verticalScrollbarWidth() const;
- virtual int scrollLeft() const;
- virtual int scrollTop() const;
- virtual int scrollWidth() const;
- virtual int scrollHeight() const;
- virtual void setScrollLeft(int);
- virtual void setScrollTop(int);
+ virtual int verticalScrollbarWidth() const OVERRIDE;
+ virtual LayoutUnit scrollLeft() const OVERRIDE;
+ virtual LayoutUnit scrollTop() const OVERRIDE;
+ virtual LayoutUnit scrollWidth() const OVERRIDE;
+ virtual LayoutUnit scrollHeight() const OVERRIDE;
+ virtual void setScrollLeft(LayoutUnit) OVERRIDE;
+ virtual void setScrollTop(LayoutUnit) OVERRIDE;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
@@ -125,14 +126,14 @@ private:
virtual IntPoint maximumScrollPosition() const OVERRIDE;
virtual bool userInputScrollable(ScrollbarOrientation) const OVERRIDE;
virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE;
- virtual int lineStep(ScrollbarOrientation) const;
- virtual int pageStep(ScrollbarOrientation) const;
- virtual float pixelStep(ScrollbarOrientation) const;
-
-
- virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE;
+ virtual int lineStep(ScrollbarOrientation) const OVERRIDE;
+ virtual int pageStep(ScrollbarOrientation) const OVERRIDE;
+ virtual float pixelStep(ScrollbarOrientation) const OVERRIDE;
virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
+ LayoutRect itemBoundingBoxRectInternal(const LayoutPoint&, int index) const;
+ bool scrollToRevealElementAtListIndexInternal(int index);
+
// NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
void scrollTo(int newOffset);
@@ -141,8 +142,8 @@ private:
void destroyScrollbar();
LayoutUnit itemHeight() const;
- void valueChanged(unsigned listIndex);
int numVisibleItems() const;
+ bool listIndexIsVisible(int index) const;
int numItems() const;
LayoutUnit listHeight() const;
int scrollbarLeft() const;
@@ -151,11 +152,15 @@ private:
void paintItemBackground(PaintInfo&, const LayoutPoint&, int listIndex);
void scrollToRevealSelection();
+ int renderListBoxIndexToListIndex(int index) const;
+ int listIndexToRenderListBoxIndex(int index) const;
+
bool m_optionsChanged;
bool m_scrollToRevealSelectionAfterLayout;
bool m_inAutoscroll;
int m_optionsWidth;
int m_indexOffset;
+ int m_listItemCount;
RefPtr<Scrollbar> m_vBar;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderListItem.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderListItem.cpp
index b3b57a571ba..54d3d2d7e4b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderListItem.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderListItem.cpp
@@ -24,10 +24,10 @@
#include "config.h"
#include "core/rendering/RenderListItem.h"
-#include "HTMLNames.h"
-#include "core/dom/ElementTraversal.h"
+#include "core/HTMLNames.h"
+#include "core/dom/NodeRenderingTraversal.h"
#include "core/html/HTMLOListElement.h"
-#include "core/rendering/LayoutRectRecorder.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/RenderListMarker.h"
#include "core/rendering/RenderView.h"
#include "wtf/StdLibExtras.h"
@@ -51,15 +51,11 @@ RenderListItem::RenderListItem(Element* element)
void RenderListItem::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- RenderBlock::styleDidChange(diff, oldStyle);
+ RenderBlockFlow::styleDidChange(diff, oldStyle);
if (style()->listStyleType() != NoneListStyle
|| (style()->listStyleImage() && !style()->listStyleImage()->errorOccurred())) {
RefPtr<RenderStyle> newStyle = RenderStyle::create();
- // Markers update their own margin style. By copying the existing style we can
- // avoid an unnecessary layout in setStyle below.
- if (m_marker)
- newStyle->copyNonInheritedFrom(m_marker->style());
// The marker always inherits from the list item, regardless of where it might end
// up (e.g., in some deeply nested line box). See CSS3 spec.
newStyle->inheritFrom(style());
@@ -95,9 +91,9 @@ void RenderListItem::willBeRemovedFromTree()
updateListMarkerNumbers();
}
-static bool isList(const Node* node)
+static bool isList(const Node& node)
{
- return (node->hasTagName(ulTag) || node->hasTagName(olTag));
+ return isHTMLUListElement(node) || isHTMLOListElement(node);
}
// Returns the enclosing list with respect to the DOM order.
@@ -106,8 +102,8 @@ static Node* enclosingList(const RenderListItem* listItem)
Node* listItemNode = listItem->node();
Node* firstNode = 0;
// We use parentNode because the enclosing list could be a ShadowRoot that's not Element.
- for (Node* parent = listItemNode->parentNode(); parent; parent = parent->parentNode()) {
- if (isList(parent))
+ for (Node* parent = NodeRenderingTraversal::parent(listItemNode); parent; parent = NodeRenderingTraversal::parent(parent)) {
+ if (isList(*parent))
return parent;
if (!firstNode)
firstNode = parent;
@@ -127,12 +123,13 @@ static RenderListItem* nextListItem(const Node* listNode, const RenderListItem*
const Node* current = item ? item->node() : listNode;
ASSERT(current);
- current = ElementTraversal::nextIncludingPseudo(*current, listNode);
+ ASSERT(!current->document().childNeedsDistributionRecalc());
+ current = NodeRenderingTraversal::next(current, listNode);
while (current) {
- if (isList(current)) {
+ if (isList(*current)) {
// We've found a nested, independent list: nothing to do here.
- current = ElementTraversal::nextIncludingPseudoSkippingChildren(*current, listNode);
+ current = NodeRenderingTraversal::next(current, listNode);
continue;
}
@@ -141,7 +138,7 @@ static RenderListItem* nextListItem(const Node* listNode, const RenderListItem*
return toRenderListItem(renderer);
// FIXME: Can this be optimized to skip the children of the elements without a renderer?
- current = ElementTraversal::nextIncludingPseudo(*current, listNode);
+ current = NodeRenderingTraversal::next(current, listNode);
}
return 0;
@@ -152,7 +149,8 @@ static RenderListItem* previousListItem(const Node* listNode, const RenderListIt
{
Node* current = item->node();
ASSERT(current);
- for (current = ElementTraversal::previousIncludingPseudo(*current, listNode); current; current = ElementTraversal::previousIncludingPseudo(*current, listNode)) {
+ ASSERT(!current->document().childNeedsDistributionRecalc());
+ for (current = NodeRenderingTraversal::previous(current, listNode); current && current != listNode; current = NodeRenderingTraversal::previous(current, listNode)) {
RenderObject* renderer = current->renderer();
if (!renderer || (renderer && !renderer->isListItem()))
continue;
@@ -165,7 +163,7 @@ static RenderListItem* previousListItem(const Node* listNode, const RenderListIt
// be a list item itself. We need to examine it, so we do this to counteract
// the previousIncludingPseudo() that will be done by the loop.
if (otherList)
- current = ElementTraversal::nextIncludingPseudo(*otherList);
+ current = NodeRenderingTraversal::next(otherList, listNode);
}
return 0;
}
@@ -195,7 +193,7 @@ inline int RenderListItem::calcValue() const
return m_explicitValue;
Node* list = enclosingList(this);
- HTMLOListElement* oListElement = (list && list->hasTagName(olTag)) ? toHTMLOListElement(list) : 0;
+ HTMLOListElement* oListElement = isHTMLOListElement(list) ? toHTMLOListElement(list) : 0;
int valueStep = 1;
if (oListElement && oListElement->isReversed())
valueStep = -1;
@@ -243,7 +241,7 @@ static RenderObject* getParentOfFirstLineBox(RenderBlockFlow* curr, RenderObject
break;
if (curr->isListItem() && inQuirksMode && currChild->node() &&
- (currChild->node()->hasTagName(ulTag)|| currChild->node()->hasTagName(olTag)))
+ (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*currChild->node())))
break;
RenderObject* lineBox = getParentOfFirstLineBox(toRenderBlockFlow(currChild), marker);
@@ -259,65 +257,82 @@ void RenderListItem::updateValue()
if (!m_hasExplicitValue) {
m_isValueUpToDate = false;
if (m_marker)
- m_marker->setNeedsLayoutAndPrefWidthsRecalc();
+ m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
}
static RenderObject* firstNonMarkerChild(RenderObject* parent)
{
- RenderObject* result = parent->firstChild();
+ RenderObject* result = parent->slowFirstChild();
while (result && result->isListMarker())
result = result->nextSibling();
return result;
}
-void RenderListItem::updateMarkerLocation()
+void RenderListItem::updateMarkerLocationAndInvalidateWidth()
{
- // Sanity check the location of our marker.
- if (m_marker) {
- RenderObject* markerParent = m_marker->parent();
- RenderObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker);
- if (!lineBoxParent) {
- // If the marker is currently contained inside an anonymous box,
- // then we are the only item in that anonymous box (since no line box
- // parent was found). It's ok to just leave the marker where it is
- // in this case.
- if (markerParent && markerParent->isAnonymousBlock())
- lineBoxParent = markerParent;
- else
- lineBoxParent = this;
- }
+ ASSERT(m_marker);
+
+ // FIXME: We should not modify the structure of the render tree
+ // during layout. crbug.com/370461
+ DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
+ // Removing and adding the marker can trigger repainting in
+ // containers other than ourselves, so we need to disable LayoutState.
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
+ if (updateMarkerLocation()) {
+ // If the marker is inside we need to redo the preferred width calculations
+ // as the size of the item now includes the size of the list marker.
+ if (m_marker->isInside())
+ containingBlock()->updateLogicalWidth();
+ }
+}
- if (markerParent != lineBoxParent || m_marker->preferredLogicalWidthsDirty()) {
- // Removing and adding the marker can trigger repainting in
- // containers other than ourselves, so we need to disable LayoutState.
- LayoutStateDisabler layoutStateDisabler(view());
- updateFirstLetter();
- m_marker->remove();
- if (markerParent)
- markerParent->dirtyLinesFromChangedChild(m_marker);
- if (!lineBoxParent)
- lineBoxParent = this;
- lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent));
- m_marker->updateMarginsAndContent();
- // If markerParent is an anonymous block that has lost all its children, destroy it.
- if (markerParent && markerParent->isAnonymousBlock() && !markerParent->firstChild() && !toRenderBlock(markerParent)->continuation())
- markerParent->destroy();
-
- // If the marker is inside we need to redo the preferred width calculations
- // as the size of the item now includes the size of the list marker.
- if (m_marker->isInside())
- containingBlock()->updateLogicalWidth();
- }
+bool RenderListItem::updateMarkerLocation()
+{
+ ASSERT(m_marker);
+ RenderObject* markerParent = m_marker->parent();
+ RenderObject* lineBoxParent = getParentOfFirstLineBox(this, m_marker);
+ if (!lineBoxParent) {
+ // If the marker is currently contained inside an anonymous box, then we
+ // are the only item in that anonymous box (since no line box parent was
+ // found). It's ok to just leave the marker where it is in this case.
+ if (markerParent && markerParent->isAnonymousBlock())
+ lineBoxParent = markerParent;
+ else
+ lineBoxParent = this;
+ }
+
+ if (markerParent != lineBoxParent) {
+ updateFirstLetter();
+ m_marker->remove();
+ // FIXME(crbug.com/391009): Investigate whether this call is needed.
+ if (markerParent)
+ markerParent->dirtyLinesFromChangedChild(m_marker);
+ lineBoxParent->addChild(m_marker, firstNonMarkerChild(lineBoxParent));
+ m_marker->updateMarginsAndContent();
+ // If markerParent is an anonymous block with no children, destroy it.
+ if (markerParent && markerParent->isAnonymousBlock() && !toRenderBlock(markerParent)->firstChild() && !toRenderBlock(markerParent)->continuation())
+ markerParent->destroy();
+ return true;
}
+
+ return false;
}
void RenderListItem::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
- updateMarkerLocation();
+ if (m_marker) {
+ // The marker must be autosized before calling
+ // updateMarkerLocationAndInvalidateWidth. It cannot be done in the
+ // parent's beginLayout because it is not yet in the render tree.
+ if (FastTextAutosizer* textAutosizer = document().fastTextAutosizer())
+ textAutosizer->inflateListItem(this, m_marker);
+
+ updateMarkerLocationAndInvalidateWidth();
+ }
+
RenderBlockFlow::layout();
}
@@ -340,18 +355,17 @@ void RenderListItem::positionListMarker()
bool adjustOverflow = false;
LayoutUnit markerLogicalLeft;
- RootInlineBox* root = m_marker->inlineBoxWrapper()->root();
+ RootInlineBox& root = m_marker->inlineBoxWrapper()->root();
bool hitSelfPaintingLayer = false;
- RootInlineBox* rootBox = m_marker->inlineBoxWrapper()->root();
- LayoutUnit lineTop = rootBox->lineTop();
- LayoutUnit lineBottom = rootBox->lineBottom();
+ LayoutUnit lineTop = root.lineTop();
+ LayoutUnit lineBottom = root.lineBottom();
// FIXME: Need to account for relative positioning in the layout overflow.
if (style()->isLeftToRightDirection()) {
LayoutUnit leftLineOffset = logicalLeftOffsetForLine(blockOffset, logicalLeftOffsetForLine(blockOffset, false), false);
markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - borderStart() + m_marker->marginStart();
- m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft);
+ m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat());
for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom);
LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom);
@@ -374,7 +388,7 @@ void RenderListItem::positionListMarker()
} else {
LayoutUnit rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false);
markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd();
- m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft);
+ m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat());
for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom);
LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom);
@@ -437,33 +451,10 @@ const String& RenderListItem::markerText() const
return nullAtom.string();
}
-String RenderListItem::markerTextWithSuffix() const
-{
- if (!m_marker)
- return String();
-
- // Append the suffix for the marker in the right place depending
- // on the direction of the text (right-to-left or left-to-right).
-
- const String& markerText = m_marker->text();
- const String markerSuffix = m_marker->suffix();
- StringBuilder result;
-
- if (!m_marker->style()->isLeftToRightDirection())
- result.append(markerSuffix);
-
- result.append(markerText);
-
- if (m_marker->style()->isLeftToRightDirection())
- result.append(markerSuffix);
-
- return result.toString();
-}
-
void RenderListItem::explicitValueChanged()
{
if (m_marker)
- m_marker->setNeedsLayoutAndPrefWidthsRecalc();
+ m_marker->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
Node* listNode = enclosingList(this);
for (RenderListItem* item = this; item; item = nextListItem(listNode, item))
item->updateValue();
@@ -492,6 +483,13 @@ void RenderListItem::clearExplicitValue()
explicitValueChanged();
}
+void RenderListItem::setNotInList(bool notInList)
+{
+ m_notInList = notInList;
+ if (m_marker)
+ updateMarkerLocation();
+}
+
static RenderListItem* previousOrNextItem(bool isListReversed, Node* list, RenderListItem* item)
{
return isListReversed ? previousListItem(list, item) : nextListItem(list, item);
@@ -499,18 +497,28 @@ static RenderListItem* previousOrNextItem(bool isListReversed, Node* list, Rende
void RenderListItem::updateListMarkerNumbers()
{
+ // If distribution recalc is needed, updateListMarkerNumber will be re-invoked
+ // after distribution is calculated.
+ if (node()->document().childNeedsDistributionRecalc())
+ return;
+
Node* listNode = enclosingList(this);
- // The list node can be the shadow root which has no renderer.
ASSERT(listNode);
- if (!listNode)
- return;
bool isListReversed = false;
- HTMLOListElement* oListElement = (listNode && listNode->hasTagName(olTag)) ? toHTMLOListElement(listNode) : 0;
+ HTMLOListElement* oListElement = isHTMLOListElement(listNode) ? toHTMLOListElement(listNode) : 0;
if (oListElement) {
oListElement->itemCountChanged();
isListReversed = oListElement->isReversed();
}
+
+ // FIXME: The n^2 protection below doesn't help if the elements were inserted after the
+ // the list had already been displayed.
+
+ // Avoid an O(n^2) walk over the children below when they're all known to be attaching.
+ if (listNode->needsAttach())
+ return;
+
for (RenderListItem* item = previousOrNextItem(isListReversed, listNode, this); item; item = previousOrNextItem(isListReversed, listNode, item)) {
if (!item->m_isValueUpToDate) {
// If an item has been marked for update before, we can safely
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderListItem.h b/chromium/third_party/WebKit/Source/core/rendering/RenderListItem.h
index 76f6087ea4b..ca46d46bf42 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderListItem.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderListItem.h
@@ -42,40 +42,41 @@ public:
void setExplicitValue(int value);
void clearExplicitValue();
- void setNotInList(bool notInList) { m_notInList = notInList; }
+ void setNotInList(bool);
bool notInList() const { return m_notInList; }
const String& markerText() const;
- String markerTextWithSuffix() const;
void updateListMarkerNumbers();
- void updateMarkerLocation();
static void updateItemValuesForOrderedList(const HTMLOListElement*);
static unsigned itemCountForOrderedList(const HTMLOListElement*);
+ bool isEmpty() const;
+
private:
- virtual const char* renderName() const { return "RenderListItem"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderListItem"; }
- virtual bool isListItem() const { return true; }
+ virtual bool isListItem() const OVERRIDE { return true; }
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
virtual void insertedIntoTree() OVERRIDE;
virtual void willBeRemovedFromTree() OVERRIDE;
- virtual bool isEmpty() const;
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
- virtual void layout();
+ virtual void layout() OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ // Returns true if we re-attached and updated the location of the marker.
+ bool updateMarkerLocation();
+ void updateMarkerLocationAndInvalidateWidth();
void positionListMarker();
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
- virtual void addOverflowFromChildren();
+ virtual void addOverflowFromChildren() OVERRIDE;
inline int calcValue() const;
void updateValueNow() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.cpp
index f05497493e5..492c3620d2f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.cpp
@@ -28,7 +28,6 @@
#include "core/dom/Document.h"
#include "core/fetch/ImageResource.h"
#include "core/rendering/GraphicsContextAnnotator.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderListItem.h"
#include "core/rendering/RenderView.h"
@@ -1078,10 +1077,10 @@ RenderListMarker* RenderListMarker::createAnonymous(RenderListItem* item)
return renderer;
}
-void RenderListMarker::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderListMarker::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
- if (style() && (newStyle->listStylePosition() != style()->listStylePosition() || newStyle->listStyleType() != style()->listStyleType()))
- setNeedsLayoutAndPrefWidthsRecalc();
+ if (style() && (newStyle.listStylePosition() != style()->listStylePosition() || newStyle.listStyleType() != style()->listStyleType()))
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
RenderBox::styleWillChange(diff, newStyle);
}
@@ -1116,11 +1115,11 @@ LayoutRect RenderListMarker::localSelectionRect()
InlineBox* box = inlineBoxWrapper();
if (!box)
return LayoutRect(LayoutPoint(), size());
- RootInlineBox* root = m_inlineBoxWrapper->root();
- LayoutUnit newLogicalTop = root->block()->style()->isFlippedBlocksWritingMode() ? m_inlineBoxWrapper->logicalBottom() - root->selectionBottom() : root->selectionTop() - m_inlineBoxWrapper->logicalTop();
- if (root->block()->style()->isHorizontalWritingMode())
- return LayoutRect(0, newLogicalTop, width(), root->selectionHeight());
- return LayoutRect(newLogicalTop, 0, root->selectionHeight(), height());
+ RootInlineBox& root = inlineBoxWrapper()->root();
+ LayoutUnit newLogicalTop = root.block().style()->isFlippedBlocksWritingMode() ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() : root.selectionTop() - inlineBoxWrapper()->logicalTop();
+ if (root.block().style()->isHorizontalWritingMode())
+ return LayoutRect(0, newLogicalTop, width(), root.selectionHeight());
+ return LayoutRect(newLogicalTop, 0, root.selectionHeight(), height());
}
void RenderListMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -1136,7 +1135,6 @@ void RenderListMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
LayoutPoint boxOrigin(paintOffset + location());
LayoutRect overflowRect(visualOverflowRect());
overflowRect.moveBy(boxOrigin);
- overflowRect.inflate(maximalOutlineSize(paintInfo.phase));
if (!paintInfo.rect.intersects(pixelSnappedIntRect(overflowRect)))
return;
@@ -1301,21 +1299,19 @@ void RenderListMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
}
const UChar suffix = listMarkerSuffix(type, m_listItem->value());
+ UChar suffixStr[2] = {
+ style()->isLeftToRightDirection() ? suffix : ' ',
+ style()->isLeftToRightDirection() ? ' ' : suffix
+ };
+ TextRun suffixRun = RenderBlockFlow::constructTextRun(this, font, suffixStr, 2, style(), style()->direction());
+ TextRunPaintInfo suffixRunInfo(suffixRun);
+ suffixRunInfo.bounds = marker;
+
if (style()->isLeftToRightDirection()) {
context->drawText(font, textRunPaintInfo, textOrigin);
-
- UChar suffixSpace[2] = { suffix, ' ' };
- TextRun suffixRun = RenderBlockFlow::constructTextRun(this, font, suffixSpace, 2, style());
- TextRunPaintInfo suffixRunInfo(suffixRun);
- suffixRunInfo.bounds = marker;
context->drawText(font, suffixRunInfo, textOrigin + IntSize(font.width(textRun), 0));
} else {
- UChar spaceSuffix[2] = { ' ', suffix };
- TextRun suffixRun = RenderBlockFlow::constructTextRun(this, font, spaceSuffix, 2, style());
- TextRunPaintInfo suffixRunInfo(suffixRun);
- suffixRunInfo.bounds = marker;
context->drawText(font, suffixRunInfo, textOrigin);
-
context->drawText(font, textRunPaintInfo, textOrigin + IntSize(font.width(suffixRun), 0));
}
}
@@ -1325,7 +1321,6 @@ void RenderListMarker::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
if (isImage()) {
updateMarginsAndContent();
setWidth(m_image->imageSize(this, style()->effectiveZoom()).width());
@@ -1355,9 +1350,9 @@ void RenderListMarker::imageChanged(WrappedImagePtr o, const IntRect*)
return;
if (width() != m_image->imageSize(this, style()->effectiveZoom()).width() || height() != m_image->imageSize(this, style()->effectiveZoom()).height() || m_image->errorOccurred())
- setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
else
- repaint();
+ paintInvalidationForWholeRenderer();
}
void RenderListMarker::updateMarginsAndContent()
@@ -1379,7 +1374,9 @@ void RenderListMarker::updateContent()
// FIXME: This is a somewhat arbitrary width. Generated images for markers really won't become particularly useful
// until we support the CSS3 marker pseudoclass to allow control over the width and height of the marker box.
int bulletWidth = style()->fontMetrics().ascent() / 2;
- m_image->setContainerSizeForRenderer(this, IntSize(bulletWidth, bulletWidth), style()->effectiveZoom());
+ IntSize defaultBulletSize(bulletWidth, bulletWidth);
+ IntSize imageSize = calculateImageIntrinsicDimensions(m_image.get(), defaultBulletSize, DoNotScaleByEffectiveZoom);
+ m_image->setContainerSizeForRenderer(this, imageSize, style()->effectiveZoom());
return;
}
@@ -1583,7 +1580,7 @@ void RenderListMarker::computePreferredLogicalWidths()
else {
LayoutUnit itemWidth = font.width(m_text);
UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
- LayoutUnit suffixSpaceWidth = font.width(RenderBlockFlow::constructTextRun(this, font, suffixSpace, 2, style()));
+ LayoutUnit suffixSpaceWidth = font.width(RenderBlockFlow::constructTextRun(this, font, suffixSpace, 2, style(), style()->direction()));
logicalWidth = itemWidth + suffixSpaceWidth;
}
break;
@@ -1809,7 +1806,7 @@ IntRect RenderListMarker::getRelativeMarkerRect()
const Font& font = style()->font();
int itemWidth = font.width(m_text);
UChar suffixSpace[2] = { listMarkerSuffix(type, m_listItem->value()), ' ' };
- int suffixSpaceWidth = font.width(RenderBlockFlow::constructTextRun(this, font, suffixSpace, 2, style()));
+ int suffixSpaceWidth = font.width(RenderBlockFlow::constructTextRun(this, font, suffixSpace, 2, style(), style()->direction()));
relativeRect = IntRect(0, 0, itemWidth + suffixSpaceWidth, font.fontMetrics().height());
}
@@ -1826,25 +1823,24 @@ void RenderListMarker::setSelectionState(SelectionState state)
// The selection state for our containing block hierarchy is updated by the base class call.
RenderBox::setSelectionState(state);
- if (m_inlineBoxWrapper && canUpdateSelectionOnRootLineBoxes())
- if (RootInlineBox* root = m_inlineBoxWrapper->root())
- root->setHasSelectedChildren(state != SelectionNone);
+ if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes())
+ inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone);
}
-LayoutRect RenderListMarker::selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent)
+LayoutRect RenderListMarker::selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, bool clipToVisibleContent)
{
ASSERT(!needsLayout());
if (selectionState() == SelectionNone || !inlineBoxWrapper())
return LayoutRect();
- RootInlineBox* root = inlineBoxWrapper()->root();
- LayoutRect rect(0, root->selectionTop() - y(), width(), root->selectionHeight());
+ RootInlineBox& root = inlineBoxWrapper()->root();
+ LayoutRect rect(0, root.selectionTop() - y(), width(), root.selectionHeight());
if (clipToVisibleContent)
- computeRectForRepaint(repaintContainer, rect);
+ mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect);
else
- rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
+ rect = localToContainerQuad(FloatRect(rect), paintInvalidationContainer).enclosingBoundingBox();
return rect;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.h b/chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.h
index d0002ffb973..278626a3c5b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderListMarker.h
@@ -49,34 +49,34 @@ public:
private:
RenderListMarker(RenderListItem*);
- virtual const char* renderName() const { return "RenderListMarker"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderListMarker"; }
virtual void computePreferredLogicalWidths() OVERRIDE;
- virtual bool isListMarker() const { return true; }
+ virtual bool isListMarker() const OVERRIDE { return true; }
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
- virtual void layout();
+ virtual void layout() OVERRIDE;
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
- virtual InlineBox* createInlineBox();
+ virtual InlineBox* createInlineBox() OVERRIDE;
- virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
- virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
- bool isImage() const;
+ virtual bool isImage() const OVERRIDE;
bool isText() const { return !isImage(); }
- virtual void setSelectionState(SelectionState);
- virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) OVERRIDE;
- virtual bool canBeSelectionLeaf() const { return true; }
+ virtual void setSelectionState(SelectionState) OVERRIDE;
+ virtual LayoutRect selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, bool clipToVisibleContent = true) OVERRIDE;
+ virtual bool canBeSelectionLeaf() const OVERRIDE { return true; }
void updateMargins();
void updateContent();
- virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
IntRect getRelativeMarkerRect();
LayoutRect localSelectionRect();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.cpp
index a40fed1583d..4b1e9a20c00 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.cpp
@@ -46,12 +46,13 @@
#include "core/rendering/RenderMarquee.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLMarqueeElement.h"
#include "core/frame/FrameView.h"
#include "core/frame/UseCounter.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
+#include "platform/LengthFunctions.h"
using namespace std;
@@ -172,7 +173,7 @@ void RenderMarquee::start()
m_stopped = false;
}
- m_timer.startRepeating(speed() * 0.001);
+ m_timer.startRepeating(speed() * 0.001, FROM_HERE);
}
void RenderMarquee::suspend()
@@ -194,8 +195,11 @@ void RenderMarquee::updateMarqueePosition()
EMarqueeBehavior behavior = style()->marqueeBehavior();
m_start = computePosition(direction(), behavior == MALTERNATE);
m_end = computePosition(reverseDirection(), behavior == MALTERNATE || behavior == MSLIDE);
- if (!m_stopped)
+ if (!m_stopped) {
+ // Hits in compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html during layout.
+ DisableCompositingQueryAsserts disabler;
start();
+ }
}
}
@@ -215,7 +219,7 @@ const char* RenderMarquee::renderName() const
void RenderMarquee::styleDidChange(StyleDifference difference, const RenderStyle* oldStyle)
{
- RenderBlock::styleDidChange(difference, oldStyle);
+ RenderBlockFlow::styleDidChange(difference, oldStyle);
RenderStyle* s = style();
@@ -248,20 +252,20 @@ void RenderMarquee::styleDidChange(StyleDifference difference, const RenderStyle
if (speed() != marqueeSpeed()) {
m_speed = marqueeSpeed();
if (m_timer.isActive())
- m_timer.startRepeating(speed() * 0.001);
+ m_timer.startRepeating(speed() * 0.001, FROM_HERE);
}
// Check the loop count to see if we should now stop.
bool activate = (m_totalLoops <= 0 || m_currentLoop < m_totalLoops);
if (activate && !m_timer.isActive())
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
else if (!activate && m_timer.isActive())
m_timer.stop();
}
-void RenderMarquee::layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight)
+void RenderMarquee::layoutBlock(bool relayoutChildren)
{
- RenderBlockFlow::layoutBlock(relayoutChildren, pageLogicalHeight);
+ RenderBlockFlow::layoutBlock(relayoutChildren);
updateMarqueePosition();
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.h
index f69801dd44f..a089b234697 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMarquee.h
@@ -52,8 +52,6 @@
namespace WebCore {
-class RenderLayer;
-
// This class handles the auto-scrolling for <marquee>
class RenderMarquee FINAL : public RenderBlockFlow {
public:
@@ -83,15 +81,13 @@ public:
void timerFired();
private:
- virtual const char* renderName() const OVERRIDE FINAL;
-
- virtual bool isMarquee() const OVERRIDE FINAL { return true; }
+ virtual const char* renderName() const OVERRIDE;
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE FINAL;
+ virtual bool isMarquee() const OVERRIDE { return true; }
- virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE FINAL;
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual void layoutBlock(bool relayoutChildren) OVERRIDE;
int m_currentLoop;
int m_totalLoops;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMedia.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMedia.cpp
index aacc6ae38a9..0062b292055 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMedia.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMedia.cpp
@@ -28,8 +28,6 @@
#include "core/rendering/RenderMedia.h"
#include "core/html/HTMLMediaElement.h"
-#include "core/rendering/LayoutRectRecorder.h"
-#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderView.h"
namespace WebCore {
@@ -51,7 +49,6 @@ HTMLMediaElement* RenderMedia::mediaElement() const
void RenderMedia::layout()
{
- LayoutRectRecorder recorder(*this);
LayoutSize oldSize = contentBoxRect().size();
RenderImage::layout();
@@ -61,30 +58,17 @@ void RenderMedia::layout()
return;
bool controlsNeedLayout = controlsRenderer->needsLayout();
- // If the region chain has changed we also need to relayout the controls to update the region box info.
- // FIXME: We can do better once we compute region box info for RenderReplaced, not only for RenderBlock.
- const RenderFlowThread* flowThread = flowThreadContainingBlock();
- if (flowThread && !controlsNeedLayout) {
- if (flowThread->pageLogicalSizeChanged())
- controlsNeedLayout = true;
- }
-
LayoutSize newSize = contentBoxRect().size();
if (newSize == oldSize && !controlsNeedLayout)
return;
- // When calling layout() on a child node, a parent must either push a LayoutStateMaintainter, or
- // instantiate LayoutStateDisabler. Since using a LayoutStateMaintainer is slightly more efficient,
- // and this method will be called many times per second during playback, use a LayoutStateMaintainer:
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+ LayoutState state(*this, locationOffset());
controlsRenderer->setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed));
controlsRenderer->style()->setWidth(Length(newSize.width(), Fixed));
controlsRenderer->forceLayout();
clearNeedsLayout();
-
- statePusher.pop();
}
void RenderMedia::paintReplaced(PaintInfo&, const LayoutPoint&)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMedia.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMedia.h
index ada064b59c0..c970b2909db 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMedia.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMedia.h
@@ -40,27 +40,33 @@ public:
RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
+ // If you have a RenderMedia, use firstChild or lastChild instead.
+ void slowFirstChild() const WTF_DELETED_FUNCTION;
+ void slowLastChild() const WTF_DELETED_FUNCTION;
+
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
HTMLMediaElement* mediaElement() const;
protected:
- virtual void layout();
+ virtual void layout() OVERRIDE;
private:
virtual RenderObjectChildList* virtualChildren() OVERRIDE FINAL { return children(); }
virtual const RenderObjectChildList* virtualChildren() const OVERRIDE FINAL { return children(); }
+ virtual LayerType layerTypeRequired() const OVERRIDE { return NormalLayer; }
+
// FIXME: RenderMedia::layout makes assumptions about what children are allowed
// so we can't support generated content.
virtual bool canHaveGeneratedChildren() const OVERRIDE FINAL { return false; }
virtual bool canHaveChildren() const OVERRIDE FINAL { return true; }
- virtual const char* renderName() const { return "RenderMedia"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderMedia"; }
virtual bool isMedia() const OVERRIDE FINAL { return true; }
virtual bool isImage() const OVERRIDE FINAL { return false; }
- virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
+ virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE;
RenderObjectChildList m_children;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.cpp
index da2babc48d5..bdf6b1367c8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.cpp
@@ -29,7 +29,7 @@
#include "core/rendering/RenderMediaControlElements.h"
-#include "core/rendering/LayoutRectRecorder.h"
+#include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h"
#include "core/rendering/RenderView.h"
namespace WebCore {
@@ -41,17 +41,16 @@ RenderTextTrackContainerElement::RenderTextTrackContainerElement(Element* elemen
void RenderTextTrackContainerElement::layout()
{
- LayoutRectRecorder recorder(*this);
- RenderBlock::layout();
+ RenderBlockFlow::layout();
if (style()->display() == NONE)
return;
ASSERT(mediaControlElementType(node()) == MediaTextTrackDisplayContainer);
- LayoutStateDisabler layoutStateDisabler(view());
+ DeprecatedScheduleStyleRecalcDuringLayout marker(node()->document().lifecycle());
+
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
static_cast<MediaControlTextTrackContainerElement*>(node())->updateSizes();
}
-
} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.h
index 90a7d5ea1f2..b22aa736013 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControlElements.h
@@ -39,8 +39,7 @@ public:
RenderTextTrackContainerElement(Element*);
private:
- virtual void layout();
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual void layout() OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp
index 13d1620367a..90b28aa442f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp
@@ -106,7 +106,7 @@ static bool paintMediaPlayButton(RenderObject* object, const PaintInfo& paintInf
if (!hasSource(mediaElement))
return paintMediaButton(paintInfo.context, rect, mediaPlayDisabled);
- return paintMediaButton(paintInfo.context, rect, mediaElement->canPlay() ? mediaPlay : mediaPause);
+ return paintMediaButton(paintInfo.context, rect, mediaControlElementType(object->node()) == MediaPlayButton ? mediaPlay : mediaPause);
}
static bool paintMediaOverlayPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
@@ -115,7 +115,7 @@ static bool paintMediaOverlayPlayButton(RenderObject* object, const PaintInfo& p
if (!mediaElement)
return false;
- if (!hasSource(mediaElement) || !mediaElement->canPlay())
+ if (!hasSource(mediaElement) || !mediaElement->togglePlayStateWillPlay())
return false;
static Image* mediaOverlayPlay = platformResource("mediaplayerOverlayPlay");
@@ -133,9 +133,7 @@ static void paintRoundedSliderBackground(const IntRect& rect, const RenderStyle*
int borderRadius = rect.height() / 2;
IntSize radii(borderRadius, borderRadius);
Color sliderBackgroundColor = Color(11, 11, 11);
- context->save();
context->fillRoundedRect(rect, radii, radii, radii, radii, sliderBackgroundColor);
- context->restore();
}
static void paintSliderRangeHighlight(const IntRect& rect, const RenderStyle* style, GraphicsContext* context, int startPosition, int endPosition, Color startColor, Color endColor)
@@ -156,10 +154,8 @@ static void paintSliderRangeHighlight(const IntRect& rect, const RenderStyle* st
// Make sure the range width is bigger than border radius at the edges to retain rounded corners.
if (startOffset < borderRadius && rangeWidth < borderRadius)
rangeWidth = borderRadius;
- if (endOffset < borderRadius && rangeWidth < borderRadius) {
- startPosition -= borderRadius - rangeWidth;
+ if (endOffset < borderRadius && rangeWidth < borderRadius)
rangeWidth = borderRadius;
- }
// Set rectangle to highlight range.
IntRect highlightRect = rect;
@@ -365,16 +361,11 @@ bool RenderMediaControls::paintMediaControlsPart(MediaControlElementType part, R
return paintMediaFullscreenButton(object, paintInfo, rect);
case MediaOverlayPlayButton:
return paintMediaOverlayPlayButton(object, paintInfo, rect);
- case MediaVolumeSliderMuteButton:
- case MediaSeekBackButton:
- case MediaSeekForwardButton:
case MediaVolumeSliderContainer:
case MediaTimelineContainer:
case MediaCurrentTimeDisplay:
case MediaTimeRemainingDisplay:
case MediaControlsPanel:
- case MediaRewindButton:
- case MediaReturnToRealtimeButton:
case MediaStatusDisplay:
case MediaHideClosedCaptionsButton:
case MediaTextTrackDisplayContainer:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.h
index 8f40830228b..f007d6490ff 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMediaControls.h
@@ -34,7 +34,6 @@ namespace WebCore {
struct PaintInfo;
-class HTMLMediaElement;
class IntRect;
class RenderObject;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.cpp
index 57c8afc1cf8..f900e5885f0 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.cpp
@@ -25,26 +25,27 @@
#include "config.h"
#include "core/rendering/RenderMenuList.h"
-#include <math.h>
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXMenuList.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/css/CSSFontSelector.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/dom/NodeRenderStyle.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLOptGroupElement.h"
#include "core/html/HTMLOptionElement.h"
#include "core/html/HTMLSelectElement.h"
#include "core/page/Chrome.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
#include "core/rendering/RenderBR.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
#include "platform/fonts/FontCache.h"
#include "platform/geometry/IntSize.h"
+#include "platform/text/PlatformLocale.h"
+#include <math.h>
using namespace std;
@@ -61,16 +62,21 @@ RenderMenuList::RenderMenuList(Element* element)
, m_lastActiveIndex(-1)
, m_popupIsVisible(false)
{
- ASSERT(element);
- ASSERT(element->isHTMLElement());
- ASSERT(element->hasTagName(HTMLNames::selectTag));
+ ASSERT(isHTMLSelectElement(element));
}
RenderMenuList::~RenderMenuList()
{
if (m_popup)
m_popup->disconnectClient();
- m_popup = 0;
+ m_popup = nullptr;
+}
+
+// FIXME: Instead of this hack we should add a ShadowRoot to <select> with no insertion point
+// to prevent children from rendering.
+bool RenderMenuList::isChildAllowed(RenderObject* object, RenderStyle*) const
+{
+ return object->isAnonymous() && !object->isRenderFullScreen();
}
void RenderMenuList::createInnerBlock()
@@ -93,16 +99,13 @@ void RenderMenuList::adjustInnerStyle()
RenderStyle* innerStyle = m_innerBlock->style();
innerStyle->setFlexGrow(1);
innerStyle->setFlexShrink(1);
- // min-width: 0; is needed for correct shrinking.
- // FIXME: Remove this line when https://bugs.webkit.org/show_bug.cgi?id=111790 is fixed.
- innerStyle->setMinWidth(Length(0, Fixed));
// Use margin:auto instead of align-items:center to get safe centering, i.e.
// when the content overflows, treat it the same as align-items: flex-start.
// But we only do that for the cases where html.css would otherwise use center.
- if (style()->alignItems() == AlignCenter) {
+ if (style()->alignItems() == ItemPositionCenter) {
innerStyle->setMarginTop(Length());
innerStyle->setMarginBottom(Length());
- innerStyle->setAlignSelf(AlignFlexStart);
+ innerStyle->setAlignSelf(ItemPositionFlexStart);
}
innerStyle->setPaddingLeft(Length(RenderTheme::theme().popupInternalPaddingLeft(style()), Fixed));
@@ -112,7 +115,7 @@ void RenderMenuList::adjustInnerStyle()
if (m_optionStyle) {
if ((m_optionStyle->direction() != innerStyle->direction() || m_optionStyle->unicodeBidi() != innerStyle->unicodeBidi()))
- m_innerBlock->setNeedsLayoutAndPrefWidthsRecalc();
+ m_innerBlock->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
innerStyle->setTextAlign(style()->isLeftToRightDirection() ? LEFT : RIGHT);
innerStyle->setDirection(m_optionStyle->direction());
innerStyle->setUnicodeBidi(m_optionStyle->unicodeBidi());
@@ -160,13 +163,13 @@ void RenderMenuList::styleDidChange(StyleDifference diff, const RenderStyle* old
void RenderMenuList::updateOptionsWidth()
{
float maxOptionWidth = 0;
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
int size = listItems.size();
FontCachePurgePreventer fontCachePurgePreventer;
for (int i = 0; i < size; ++i) {
HTMLElement* element = listItems[i];
- if (!element->hasTagName(optionTag))
+ if (!isHTMLOptionElement(*element))
continue;
String text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
@@ -175,7 +178,7 @@ void RenderMenuList::updateOptionsWidth()
// Add in the option's text indent. We can't calculate percentage values for now.
float optionWidth = 0;
if (RenderStyle* optionStyle = element->renderStyle())
- optionWidth += minimumValueForLength(optionStyle->textIndent(), 0, view());
+ optionWidth += minimumValueForLength(optionStyle->textIndent(), 0);
if (!text.isEmpty())
optionWidth += style()->font().width(text);
maxOptionWidth = max(maxOptionWidth, optionWidth);
@@ -189,7 +192,7 @@ void RenderMenuList::updateOptionsWidth()
m_optionsWidth = width;
if (parent())
- setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
void RenderMenuList::updateFromElement()
@@ -199,29 +202,65 @@ void RenderMenuList::updateFromElement()
m_optionsChanged = false;
}
- if (m_popupIsVisible)
+ if (m_popupIsVisible) {
m_popup->updateFromElement();
- else
- setTextFromOption(selectElement()->selectedIndex());
+ } else {
+ if (selectElement()->suggestedIndex() >= 0)
+ setTextFromOption(selectElement()->suggestedIndex());
+ else
+ setTextFromOption(selectElement()->selectedIndex());
+ }
}
void RenderMenuList::setTextFromOption(int optionIndex)
{
HTMLSelectElement* select = selectElement();
- const Vector<HTMLElement*>& listItems = select->listItems();
- int size = listItems.size();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = select->listItems();
+ const int size = listItems.size();
- int i = select->optionToListIndex(optionIndex);
String text = emptyString();
- if (i >= 0 && i < size) {
- Element* element = listItems[i];
- if (element->hasTagName(optionTag)) {
- text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
- m_optionStyle = element->renderStyle();
+ m_optionStyle.clear();
+
+ if (multiple()) {
+ unsigned selectedCount = 0;
+ int firstSelectedIndex = -1;
+ for (int i = 0; i < size; ++i) {
+ Element* element = listItems[i];
+ if (!isHTMLOptionElement(*element))
+ continue;
+
+ if (toHTMLOptionElement(element)->selected()) {
+ if (++selectedCount == 1)
+ firstSelectedIndex = i;
+ }
+ }
+
+ if (selectedCount == 1) {
+ ASSERT(0 <= firstSelectedIndex);
+ ASSERT(firstSelectedIndex < size);
+ HTMLOptionElement* selectedOptionElement = toHTMLOptionElement(listItems[firstSelectedIndex]);
+ ASSERT(selectedOptionElement->selected());
+ text = selectedOptionElement->textIndentedToRespectGroupLabel();
+ m_optionStyle = selectedOptionElement->renderStyle();
+ } else {
+ Locale& locale = select->locale();
+ String localizedNumberString = locale.convertToLocalizedNumber(String::number(selectedCount));
+ text = locale.queryString(blink::WebLocalizedString::SelectMenuListText, localizedNumberString);
+ ASSERT(!m_optionStyle);
+ }
+ } else {
+ const int i = select->optionToListIndex(optionIndex);
+ if (i >= 0 && i < size) {
+ Element* element = listItems[i];
+ if (isHTMLOptionElement(*element)) {
+ text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+ m_optionStyle = element->renderStyle();
+ }
}
}
setText(text.stripWhiteSpace());
+
didUpdateActiveOption(optionIndex);
}
@@ -229,6 +268,9 @@ void RenderMenuList::setText(const String& s)
{
if (s.isEmpty()) {
if (!m_buttonText || !m_buttonText->isBR()) {
+ // FIXME: We should not modify the structure of the render tree
+ // during layout. crbug.com/370462
+ DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
if (m_buttonText)
m_buttonText->destroy();
m_buttonText = new RenderBR(&document());
@@ -239,6 +281,9 @@ void RenderMenuList::setText(const String& s)
if (m_buttonText && !m_buttonText->isBR())
m_buttonText->setText(s.impl(), true);
else {
+ // FIXME: We should not modify the structure of the render tree
+ // during layout. crbug.com/370462
+ DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
if (m_buttonText)
m_buttonText->destroy();
m_buttonText = new RenderText(&document(), s.impl());
@@ -287,20 +332,21 @@ void RenderMenuList::computePreferredLogicalWidths()
{
m_minPreferredLogicalWidth = 0;
m_maxPreferredLogicalWidth = 0;
+ RenderStyle* styleToUse = style();
- if (style()->width().isFixed() && style()->width().value() > 0)
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
+ if (styleToUse->width().isFixed() && styleToUse->width().value() > 0)
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->width().value());
else
computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
- if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
- m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
- m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
+ if (styleToUse->minWidth().isFixed() && styleToUse->minWidth().value() > 0) {
+ m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
+ m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
}
- if (style()->maxWidth().isFixed()) {
- m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
- m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
+ if (styleToUse->maxWidth().isFixed()) {
+ m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
+ m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
}
LayoutUnit toAdd = borderAndPaddingWidth();
@@ -315,7 +361,7 @@ void RenderMenuList::showPopup()
if (m_popupIsVisible)
return;
- if (document().page()->chrome().hasOpenedPopup())
+ if (document().frameHost()->chrome().hasOpenedPopup())
return;
// Create m_innerBlock here so it ends up as the first child.
@@ -323,7 +369,7 @@ void RenderMenuList::showPopup()
// inside the showPopup call and it would fail.
createInnerBlock();
if (!m_popup)
- m_popup = document().page()->chrome().createPopupMenu(*document().frame(), this);
+ m_popup = document().frameHost()->chrome().createPopupMenu(*document().frame(), this);
m_popupIsVisible = true;
FloatQuad quad(localToAbsoluteQuad(FloatQuad(borderBoundingBox())));
@@ -385,35 +431,25 @@ void RenderMenuList::didUpdateActiveOption(int optionIndex)
String RenderMenuList::itemText(unsigned listIndex) const
{
HTMLSelectElement* select = selectElement();
- const Vector<HTMLElement*>& listItems = select->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = select->listItems();
if (listIndex >= listItems.size())
return String();
String itemString;
Element* element = listItems[listIndex];
- if (isHTMLOptGroupElement(element))
- itemString = toHTMLOptGroupElement(element)->groupLabelText();
- else if (element->hasTagName(optionTag))
- itemString = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+ if (isHTMLOptGroupElement(*element))
+ itemString = toHTMLOptGroupElement(*element).groupLabelText();
+ else if (isHTMLOptionElement(*element))
+ itemString = toHTMLOptionElement(*element).textIndentedToRespectGroupLabel();
applyTextTransform(style(), itemString, ' ');
return itemString;
}
-String RenderMenuList::itemLabel(unsigned) const
-{
- return String();
-}
-
-String RenderMenuList::itemIcon(unsigned) const
-{
- return String();
-}
-
String RenderMenuList::itemAccessibilityText(unsigned listIndex) const
{
// Allow the accessible name be changed if necessary.
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
if (listIndex >= listItems.size())
return String();
return listItems[listIndex]->fastGetAttribute(aria_labelAttr);
@@ -421,7 +457,7 @@ String RenderMenuList::itemAccessibilityText(unsigned listIndex) const
String RenderMenuList::itemToolTip(unsigned listIndex) const
{
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
if (listIndex >= listItems.size())
return String();
return listItems[listIndex]->title();
@@ -429,16 +465,16 @@ String RenderMenuList::itemToolTip(unsigned listIndex) const
bool RenderMenuList::itemIsEnabled(unsigned listIndex) const
{
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
if (listIndex >= listItems.size())
return false;
HTMLElement* element = listItems[listIndex];
- if (!element->hasTagName(optionTag))
+ if (!isHTMLOptionElement(*element))
return false;
bool groupEnabled = true;
if (Element* parentElement = element->parentElement()) {
- if (isHTMLOptGroupElement(parentElement))
+ if (isHTMLOptGroupElement(*parentElement))
groupEnabled = !parentElement->isDisabledFormControl();
}
if (!groupEnabled)
@@ -449,7 +485,7 @@ bool RenderMenuList::itemIsEnabled(unsigned listIndex) const
PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
{
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
if (listIndex >= listItems.size()) {
// If we are making an out of bounds access, then we want to use the style
// of a different option element (index 0). However, if there isn't an option element
@@ -474,7 +510,7 @@ PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const
void RenderMenuList::getItemBackgroundColor(unsigned listIndex, Color& itemBackgroundColor, bool& itemHasCustomBackgroundColor) const
{
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
if (listIndex >= listItems.size()) {
itemBackgroundColor = resolveColor(CSSPropertyBackgroundColor);
itemHasCustomBackgroundColor = false;
@@ -485,7 +521,7 @@ void RenderMenuList::getItemBackgroundColor(unsigned listIndex, Color& itemBackg
Color backgroundColor;
if (element->renderStyle())
backgroundColor = resolveColor(element->renderStyle(), CSSPropertyBackgroundColor);
- itemHasCustomBackgroundColor = backgroundColor.isValid() && backgroundColor.alpha();
+ itemHasCustomBackgroundColor = backgroundColor.alpha();
// If the item has an opaque background color, return that.
if (!backgroundColor.hasAlpha()) {
itemBackgroundColor = backgroundColor;
@@ -511,32 +547,6 @@ PopupMenuStyle RenderMenuList::menuStyle() const
s->display() == NONE, s->textIndent(), style()->direction(), isOverride(style()->unicodeBidi()));
}
-HostWindow* RenderMenuList::hostWindow() const
-{
- return document().view()->hostWindow();
-}
-
-PassRefPtr<Scrollbar> RenderMenuList::createScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
-{
- RefPtr<Scrollbar> widget;
- bool hasCustomScrollbarStyle = style()->hasPseudoStyle(SCROLLBAR);
- if (hasCustomScrollbarStyle)
- widget = RenderScrollbar::createCustomScrollbar(scrollableArea, orientation, this->node());
- else
- widget = Scrollbar::create(scrollableArea, orientation, controlSize);
- return widget.release();
-}
-
-int RenderMenuList::clientInsetLeft() const
-{
- return 0;
-}
-
-int RenderMenuList::clientInsetRight() const
-{
- return 0;
-}
-
LayoutUnit RenderMenuList::clientPaddingLeft() const
{
return paddingLeft() + m_innerBlock->paddingLeft();
@@ -576,23 +586,23 @@ void RenderMenuList::popupDidHide()
bool RenderMenuList::itemIsSeparator(unsigned listIndex) const
{
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
- return listIndex < listItems.size() && listItems[listIndex]->hasTagName(hrTag);
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
+ return listIndex < listItems.size() && isHTMLHRElement(*listItems[listIndex]);
}
bool RenderMenuList::itemIsLabel(unsigned listIndex) const
{
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
- return listIndex < listItems.size() && isHTMLOptGroupElement(listItems[listIndex]);
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
+ return listIndex < listItems.size() && isHTMLOptGroupElement(*listItems[listIndex]);
}
bool RenderMenuList::itemIsSelected(unsigned listIndex) const
{
- const Vector<HTMLElement*>& listItems = selectElement()->listItems();
+ const WillBeHeapVector<RawPtrWillBeMember<HTMLElement> >& listItems = selectElement()->listItems();
if (listIndex >= listItems.size())
return false;
HTMLElement* element = listItems[listIndex];
- return element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected();
+ return isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selected();
}
void RenderMenuList::setTextFromItem(unsigned listIndex)
@@ -600,9 +610,4 @@ void RenderMenuList::setTextFromItem(unsigned listIndex)
setTextFromOption(selectElement()->listToOptionIndex(listIndex));
}
-FontSelector* RenderMenuList::fontSelector() const
-{
- return document().styleEngine()->fontSelector();
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.h
index 54561e0d673..b7dc98c965b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMenuList.h
@@ -54,39 +54,36 @@ public:
private:
HTMLSelectElement* selectElement() const;
- virtual bool isMenuList() const { return true; }
+ virtual bool isMenuList() const OVERRIDE { return true; }
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0);
- virtual void removeChild(RenderObject*);
- virtual bool createsAnonymousWrapper() const { return true; }
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
+ virtual void removeChild(RenderObject*) OVERRIDE;
+ virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
- virtual void updateFromElement();
+ virtual void updateFromElement() OVERRIDE;
- virtual LayoutRect controlClipRect(const LayoutPoint&) const;
- virtual bool hasControlClip() const { return true; }
+ virtual LayoutRect controlClipRect(const LayoutPoint&) const OVERRIDE;
+ virtual bool hasControlClip() const OVERRIDE { return true; }
virtual bool canHaveGeneratedChildren() const OVERRIDE { return false; }
- virtual const char* renderName() const { return "RenderMenuList"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderMenuList"; }
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
virtual void computePreferredLogicalWidths() OVERRIDE;
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
// PopupMenuClient methods
virtual void valueChanged(unsigned listIndex, bool fireOnChange = true) OVERRIDE;
virtual void selectionChanged(unsigned, bool) OVERRIDE { }
virtual void selectionCleared() OVERRIDE { }
virtual String itemText(unsigned listIndex) const OVERRIDE;
- virtual String itemLabel(unsigned listIndex) const OVERRIDE;
- virtual String itemIcon(unsigned listIndex) const OVERRIDE;
virtual String itemToolTip(unsigned listIndex) const OVERRIDE;
virtual String itemAccessibilityText(unsigned listIndex) const OVERRIDE;
virtual bool itemIsEnabled(unsigned listIndex) const OVERRIDE;
virtual PopupMenuStyle itemStyle(unsigned listIndex) const OVERRIDE;
virtual PopupMenuStyle menuStyle() const OVERRIDE;
- virtual int clientInsetLeft() const OVERRIDE;
- virtual int clientInsetRight() const OVERRIDE;
virtual LayoutUnit clientPaddingLeft() const OVERRIDE;
virtual LayoutUnit clientPaddingRight() const OVERRIDE;
virtual int listSize() const OVERRIDE;
@@ -95,15 +92,11 @@ private:
virtual bool itemIsSeparator(unsigned listIndex) const OVERRIDE;
virtual bool itemIsLabel(unsigned listIndex) const OVERRIDE;
virtual bool itemIsSelected(unsigned listIndex) const OVERRIDE;
- virtual bool valueShouldChangeOnHotTrack() const OVERRIDE { return true; }
virtual void setTextFromItem(unsigned listIndex) OVERRIDE;
virtual void listBoxSelectItem(int listIndex, bool allowMultiplySelections, bool shift, bool fireOnChangeNow = true) OVERRIDE;
virtual bool multiple() const OVERRIDE;
- virtual FontSelector* fontSelector() const OVERRIDE;
- virtual HostWindow* hostWindow() const OVERRIDE;
- virtual PassRefPtr<Scrollbar> createScrollbar(ScrollableArea*, ScrollbarOrientation, ScrollbarControlSize) OVERRIDE;
- virtual bool hasLineIfEmpty() const { return true; }
+ virtual bool hasLineIfEmpty() const OVERRIDE { return true; }
// Flexbox defines baselines differently than regular blocks.
// For backwards compatibility, menulists need to do the regular block behavior.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMeter.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMeter.cpp
index a4982a9bb70..1a26f7ac286 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMeter.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMeter.cpp
@@ -44,7 +44,7 @@ HTMLMeterElement* RenderMeter::meterElement() const
{
ASSERT(node());
- if (isHTMLMeterElement(node()))
+ if (isHTMLMeterElement(*node()))
return toHTMLMeterElement(node());
ASSERT(node()->shadowHost());
@@ -79,7 +79,7 @@ double RenderMeter::valueRatio() const
void RenderMeter::updateFromElement()
{
- repaint();
+ paintInvalidationForWholeRenderer();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMeter.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMeter.h
index d1f1e438aef..51ced2147e4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMeter.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMeter.h
@@ -34,16 +34,14 @@ public:
virtual ~RenderMeter();
HTMLMeterElement* meterElement() const;
- virtual void updateFromElement();
+ virtual void updateFromElement() OVERRIDE;
private:
virtual void updateLogicalWidth() OVERRIDE;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
- virtual const char* renderName() const { return "RenderMeter"; }
- virtual bool isMeter() const { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderMeter"; }
+ virtual bool isMeter() const OVERRIDE { return true; }
double valueRatio() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp
deleted file mode 100644
index 53c1fe86a66..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/RenderMultiColumnBlock.h"
-
-#include "core/rendering/RenderMultiColumnFlowThread.h"
-#include "core/rendering/RenderMultiColumnSet.h"
-#include "core/rendering/RenderView.h"
-
-using namespace std;
-
-namespace WebCore {
-
-RenderMultiColumnBlock::RenderMultiColumnBlock(Element* element)
- : RenderBlockFlow(element)
- , m_flowThread(0)
- , m_columnCount(1)
- , m_columnWidth(0)
- , m_columnHeightAvailable(0)
- , m_inBalancingPass(false)
-{
-}
-
-void RenderMultiColumnBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderBlock::styleDidChange(diff, oldStyle);
- for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox())
- child->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
-}
-
-void RenderMultiColumnBlock::computeColumnCountAndWidth()
-{
- // Calculate our column width and column count.
- // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
- m_columnCount = 1;
- m_columnWidth = contentLogicalWidth();
-
- ASSERT(!style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth());
-
- LayoutUnit availWidth = m_columnWidth;
- LayoutUnit colGap = columnGap();
- LayoutUnit colWidth = max<LayoutUnit>(1, LayoutUnit(style()->columnWidth()));
- int colCount = max<int>(1, style()->columnCount());
-
- if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
- m_columnCount = colCount;
- m_columnWidth = max<LayoutUnit>(0, (availWidth - ((m_columnCount - 1) * colGap)) / m_columnCount);
- } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
- m_columnCount = max<LayoutUnit>(1, (availWidth + colGap) / (colWidth + colGap));
- m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap;
- } else {
- m_columnCount = max<LayoutUnit>(min<LayoutUnit>(colCount, (availWidth + colGap) / (colWidth + colGap)), 1);
- m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap;
- }
-}
-
-bool RenderMultiColumnBlock::updateLogicalWidthAndColumnWidth()
-{
- bool relayoutChildren = RenderBlock::updateLogicalWidthAndColumnWidth();
- LayoutUnit oldColumnWidth = m_columnWidth;
- computeColumnCountAndWidth();
- if (m_columnWidth != oldColumnWidth)
- relayoutChildren = true;
- return relayoutChildren;
-}
-
-void RenderMultiColumnBlock::checkForPaginationLogicalHeightChange(LayoutUnit& /*pageLogicalHeight*/, bool& /*pageLogicalHeightChanged*/, bool& /*hasSpecifiedPageLogicalHeight*/)
-{
- // We don't actually update any of the variables. We just subclassed to adjust our column height.
- updateLogicalHeight();
- m_columnHeightAvailable = max<LayoutUnit>(contentLogicalHeight(), 0);
- setLogicalHeight(0);
-}
-
-bool RenderMultiColumnBlock::relayoutForPagination(bool, LayoutUnit, LayoutStateMaintainer& statePusher)
-{
- if (m_inBalancingPass || !requiresBalancing())
- return false;
- m_inBalancingPass = true; // Prevent re-entering this method (and recursion into layout).
-
- bool needsRelayout;
- bool neededRelayout = false;
- bool firstPass = true;
- do {
- // Column heights may change here because of balancing. We may have to do multiple layout
- // passes, depending on how the contents is fitted to the changed column heights. In most
- // cases, laying out again twice or even just once will suffice. Sometimes we need more
- // passes than that, though, but the number of retries should not exceed the number of
- // columns, unless we have a bug.
- needsRelayout = false;
- for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
- if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) {
- RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
- if (multicolSet->calculateBalancedHeight(firstPass)) {
- multicolSet->setChildNeedsLayout(MarkOnlyThis);
- needsRelayout = true;
- }
- }
- }
-
- if (needsRelayout) {
- // Layout again. Column balancing resulted in a new height.
- neededRelayout = true;
- m_flowThread->setChildNeedsLayout(MarkOnlyThis);
- setChildNeedsLayout(MarkOnlyThis);
- if (firstPass)
- statePusher.pop();
- layoutBlock(false);
- }
- firstPass = false;
- } while (needsRelayout);
- m_inBalancingPass = false;
- return neededRelayout;
-}
-
-void RenderMultiColumnBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
-{
- if (!m_flowThread) {
- m_flowThread = RenderMultiColumnFlowThread::createAnonymous(&document());
- m_flowThread->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
- RenderBlock::addChild(m_flowThread);
- }
- m_flowThread->addChild(newChild, beforeChild);
-}
-
-RenderObject* RenderMultiColumnBlock::layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope& layoutScope)
-{
- if (!m_flowThread)
- return 0;
-
- // Update the dimensions of our regions before we lay out the flow thread.
- // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions
- // instead of trying to keep them around.
- bool shouldInvalidateRegions = false;
- for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
- if (childBox == m_flowThread)
- continue;
-
- if (relayoutChildren || childBox->needsLayout()) {
- if (!m_inBalancingPass && childBox->isRenderMultiColumnSet())
- toRenderMultiColumnSet(childBox)->prepareForLayout();
- shouldInvalidateRegions = true;
- }
- }
-
- if (shouldInvalidateRegions)
- m_flowThread->invalidateRegions();
-
- if (relayoutChildren)
- layoutScope.setChildNeedsLayout(m_flowThread);
-
- setLogicalTopForChild(m_flowThread, borderBefore() + paddingBefore());
- m_flowThread->layoutIfNeeded();
- determineLogicalLeftPositionForChild(m_flowThread);
-
- return m_flowThread;
-}
-
-const char* RenderMultiColumnBlock::renderName() const
-{
- if (isFloating())
- return "RenderMultiColumnBlock (floating)";
- if (isOutOfFlowPositioned())
- return "RenderMultiColumnBlock (positioned)";
- if (isAnonymousBlock())
- return "RenderMultiColumnBlock (anonymous)";
- // FIXME: Temporary hack while the new generated content system is being implemented.
- if (isPseudoElement())
- return "RenderMultiColumnBlock (generated)";
- if (isAnonymous())
- return "RenderMultiColumnBlock (generated)";
- if (isRelPositioned())
- return "RenderMultiColumnBlock (relative positioned)";
- return "RenderMultiColumnBlock";
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.h
deleted file mode 100644
index ac92d2f9ff9..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef RenderMultiColumnBlock_h
-#define RenderMultiColumnBlock_h
-
-#include "core/rendering/RenderBlockFlow.h"
-
-namespace WebCore {
-
-class RenderMultiColumnFlowThread;
-
-class RenderMultiColumnBlock FINAL : public RenderBlockFlow {
-public:
- RenderMultiColumnBlock(Element*);
-
- LayoutUnit columnHeightAvailable() const { return m_columnHeightAvailable; }
-
- LayoutUnit columnWidth() const { return m_columnWidth; }
- unsigned columnCount() const { return m_columnCount; }
-
- RenderMultiColumnFlowThread* flowThread() const { return m_flowThread; }
-
- bool requiresBalancing() const { return !m_columnHeightAvailable || style()->columnFill() == ColumnFillBalance; }
-
-private:
- virtual bool isRenderMultiColumnBlock() const { return true; }
-
- virtual const char* renderName() const;
-
- virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&) OVERRIDE;
-
- virtual void styleDidChange(StyleDifference, const RenderStyle*) OVERRIDE;
-
- virtual bool updateLogicalWidthAndColumnWidth() OVERRIDE;
- virtual void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight) OVERRIDE;
- virtual bool relayoutForPagination(bool hasSpecifiedPageLogicalHeight, LayoutUnit pageLogicalHeight, LayoutStateMaintainer&) OVERRIDE;
-
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
-
- void computeColumnCountAndWidth();
-
- void ensureColumnSets();
-
- RenderMultiColumnFlowThread* m_flowThread;
- unsigned m_columnCount; // The default column count/width that are based off our containing block width. These values represent only the default,
- LayoutUnit m_columnWidth; // since a multi-column block that is split across variable width pages or regions will have different column counts and widths in each.
- // These values will be cached (eventually) for multi-column blocks.
- LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto.
- bool m_inBalancingPass; // Set when relayouting for column balancing.
-};
-
-DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderMultiColumnBlock, isRenderMultiColumnBlock());
-
-} // namespace WebCore
-
-#endif // RenderMultiColumnBlock_h
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp
index 1a2fc6f74b2..9b50901bcba 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp
@@ -26,12 +26,15 @@
#include "config.h"
#include "core/rendering/RenderMultiColumnFlowThread.h"
-#include "core/rendering/RenderMultiColumnBlock.h"
#include "core/rendering/RenderMultiColumnSet.h"
namespace WebCore {
RenderMultiColumnFlowThread::RenderMultiColumnFlowThread()
+ : m_columnCount(1)
+ , m_columnHeightAvailable(0)
+ , m_inBalancingPass(false)
+ , m_needsColumnHeightsRecalculation(false)
{
setFlowThreadState(InsideInFlowThread);
}
@@ -40,72 +43,249 @@ RenderMultiColumnFlowThread::~RenderMultiColumnFlowThread()
{
}
-RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Document* document)
+RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Document& document, RenderStyle* parentStyle)
{
RenderMultiColumnFlowThread* renderer = new RenderMultiColumnFlowThread();
- renderer->setDocumentForAnonymous(document);
+ renderer->setDocumentForAnonymous(&document);
+ renderer->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentStyle, BLOCK));
return renderer;
}
-const char* RenderMultiColumnFlowThread::renderName() const
+RenderMultiColumnSet* RenderMultiColumnFlowThread::firstMultiColumnSet() const
{
- return "RenderMultiColumnFlowThread";
+ for (RenderObject* sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) {
+ if (sibling->isRenderMultiColumnSet())
+ return toRenderMultiColumnSet(sibling);
+ }
+ return 0;
}
-void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
+RenderMultiColumnSet* RenderMultiColumnFlowThread::lastMultiColumnSet() const
{
- // We simply remain at our intrinsic height.
- computedValues.m_extent = logicalHeight;
- computedValues.m_position = logicalTop;
+ for (RenderObject* sibling = multiColumnBlockFlow()->lastChild(); sibling; sibling = sibling->previousSibling()) {
+ if (sibling->isRenderMultiColumnSet())
+ return toRenderMultiColumnSet(sibling);
+ }
+ return 0;
}
-LayoutUnit RenderMultiColumnFlowThread::initialLogicalWidth() const
-{
- RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
- return parentBlock->columnWidth();
-}
-
-void RenderMultiColumnFlowThread::autoGenerateRegionsToBlockOffset(LayoutUnit /*offset*/)
-{
- // This function ensures we have the correct column set information at all times.
- // For a simple multi-column layout in continuous media, only one column set child is required.
- // Once a column is nested inside an enclosing pagination context, the number of column sets
- // required becomes 2n-1, where n is the total number of nested pagination contexts. For example:
- //
- // Column layout with no enclosing pagination model = 2 * 1 - 1 = 1 column set.
- // Columns inside pages = 2 * 2 - 1 = 3 column sets (bottom of first page, all the subsequent pages, then the last page).
- // Columns inside columns inside pages = 2 * 3 - 1 = 5 column sets.
- //
- // In addition, column spans will force a column set to "split" into before/after sets around the spanning element.
- //
- // Finally, we will need to deal with columns inside regions. If regions have variable widths, then there will need
- // to be unique column sets created inside any region whose width is different from its surrounding regions. This is
- // actually pretty similar to the spanning case, in that we break up the column sets whenever the width varies.
- //
- // FIXME: For now just make one column set. This matches the old multi-column code.
- // Right now our goal is just feature parity with the old multi-column code so that we can switch over to the
- // new code as soon as possible.
- RenderMultiColumnSet* firstSet = toRenderMultiColumnSet(firstRegion());
- if (firstSet)
+void RenderMultiColumnFlowThread::addChild(RenderObject* newChild, RenderObject* beforeChild)
+{
+ RenderBlockFlow::addChild(newChild, beforeChild);
+ if (firstMultiColumnSet())
return;
+ // For now we only create one column set. It's created as soon as the multicol container gets
+ // any content at all.
+ RenderMultiColumnSet* newSet = RenderMultiColumnSet::createAnonymous(this, multiColumnBlockFlow()->style());
+
+ // Need to skip RenderBlockFlow's implementation of addChild(), or we'd get redirected right
+ // back here.
+ multiColumnBlockFlow()->RenderBlock::addChild(newSet);
+
invalidateRegions();
+}
- RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
- firstSet = RenderMultiColumnSet::createAnonymous(this);
- firstSet->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentBlock->style(), BLOCK));
- parentBlock->RenderBlock::addChild(firstSet);
+void RenderMultiColumnFlowThread::populate()
+{
+ RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
+ ASSERT(!nextSibling());
+ // Reparent children preceding the flow thread into the flow thread. It's multicol content
+ // now. At this point there's obviously nothing after the flow thread, but renderers (column
+ // sets and spanners) will be inserted there as we insert elements into the flow thread.
+ multicolContainer->moveChildrenTo(this, multicolContainer->firstChild(), this, true);
+}
+
+void RenderMultiColumnFlowThread::evacuateAndDestroy()
+{
+ RenderBlockFlow* multicolContainer = multiColumnBlockFlow();
+
+ // Remove all sets.
+ while (RenderMultiColumnSet* columnSet = firstMultiColumnSet())
+ columnSet->destroy();
- // Even though we aren't placed yet, we can go ahead and set up our size. At this point we're
- // typically in the middle of laying out the thread, attempting to paginate, and we need to do
- // some rudimentary "layout" of the set now, so that pagination will work.
- firstSet->prepareForLayout();
+ ASSERT(!previousSibling());
+ ASSERT(!nextSibling());
+ // Finally we can promote all flow thread's children. Before we move them to the flow thread's
+ // container, we need to unregister the flow thread, so that they aren't just re-added again to
+ // the flow thread that we're trying to empty.
+ multicolContainer->resetMultiColumnFlowThread();
+ moveAllChildrenTo(multicolContainer, true);
+
+ // FIXME: it's scary that neither destroy() nor the move*Children* methods take care of this,
+ // and instead leave you with dangling root line box pointers. But since this is how it is done
+ // in other parts of the code that deal with reparenting renderers, let's do the cleanup on our
+ // own here as well.
+ deleteLineBoxTree();
+
+ destroy();
+}
+
+LayoutSize RenderMultiColumnFlowThread::columnOffset(const LayoutPoint& point) const
+{
+ if (!hasValidRegionInfo())
+ return LayoutSize(0, 0);
+
+ LayoutPoint flowThreadPoint(point);
+ flipForWritingMode(flowThreadPoint);
+ LayoutUnit blockOffset = isHorizontalWritingMode() ? flowThreadPoint.y() : flowThreadPoint.x();
+ RenderRegion* renderRegion = regionAtBlockOffset(blockOffset);
+ if (!renderRegion)
+ return LayoutSize(0, 0);
+ return toRenderMultiColumnSet(renderRegion)->flowThreadTranslationAtOffset(blockOffset);
+}
+
+bool RenderMultiColumnFlowThread::needsNewWidth() const
+{
+ LayoutUnit newWidth;
+ unsigned dummyColumnCount; // We only care if used column-width changes.
+ calculateColumnCountAndWidth(newWidth, dummyColumnCount);
+ return newWidth != logicalWidth();
+}
+
+void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLayoutScope& layoutScope)
+{
+ if (relayoutChildren)
+ layoutScope.setChildNeedsLayout(this);
+
+ if (!needsLayout()) {
+ // Just before the multicol container (our parent RenderBlockFlow) finishes laying out, it
+ // will call recalculateColumnHeights() on us unconditionally, but we only want that method
+ // to do any work if we actually laid out the flow thread. Otherwise, the balancing
+ // machinery would kick in needlessly, and trigger additional layout passes. Furthermore, we
+ // actually depend on a proper flowthread layout pass in order to do balancing, since it's
+ // flowthread layout that sets up content runs.
+ m_needsColumnHeightsRecalculation = false;
+ return;
+ }
+
+ for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet()) {
+ if (!m_inBalancingPass) {
+ // This is the initial layout pass. We need to reset the column height, because contents
+ // typically have changed.
+ columnSet->resetColumnHeight();
+ }
+ }
+
+ invalidateRegions();
+ m_needsColumnHeightsRecalculation = requiresBalancing();
+ layout();
+}
+
+bool RenderMultiColumnFlowThread::recalculateColumnHeights()
+{
+ // All column sets that needed layout have now been laid out, so we can finally validate them.
validateRegions();
+
+ if (!m_needsColumnHeightsRecalculation)
+ return false;
+
+ // Column heights may change here because of balancing. We may have to do multiple layout
+ // passes, depending on how the contents is fitted to the changed column heights. In most
+ // cases, laying out again twice or even just once will suffice. Sometimes we need more
+ // passes than that, though, but the number of retries should not exceed the number of
+ // columns, unless we have a bug.
+ bool needsRelayout = false;
+ for (RenderMultiColumnSet* multicolSet = firstMultiColumnSet(); multicolSet; multicolSet = multicolSet->nextSiblingMultiColumnSet()) {
+ needsRelayout |= multicolSet->recalculateColumnHeight(m_inBalancingPass ? RenderMultiColumnSet::StretchBySpaceShortage : RenderMultiColumnSet::GuessFromFlowThreadPortion);
+ if (needsRelayout) {
+ // Once a column set gets a new column height, that column set and all successive column
+ // sets need to be laid out over again, since their logical top will be affected by
+ // this, and therefore their column heights may change as well, at least if the multicol
+ // height is constrained.
+ multicolSet->setChildNeedsLayout(MarkOnlyThis);
+ }
+ }
+
+ if (needsRelayout)
+ setChildNeedsLayout(MarkOnlyThis);
+
+ m_inBalancingPass = needsRelayout;
+ return needsRelayout;
+}
+
+void RenderMultiColumnFlowThread::calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const
+{
+ RenderBlock* columnBlock = multiColumnBlockFlow();
+ const RenderStyle* columnStyle = columnBlock->style();
+ LayoutUnit availableWidth = columnBlock->contentLogicalWidth();
+ LayoutUnit columnGap = columnBlock->columnGap();
+ LayoutUnit computedColumnWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle->columnWidth()));
+ unsigned computedColumnCount = max<int>(1, columnStyle->columnCount());
+
+ ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidth());
+ if (columnStyle->hasAutoColumnWidth() && !columnStyle->hasAutoColumnCount()) {
+ count = computedColumnCount;
+ width = std::max<LayoutUnit>(0, (availableWidth - ((count - 1) * columnGap)) / count);
+ } else if (!columnStyle->hasAutoColumnWidth() && columnStyle->hasAutoColumnCount()) {
+ count = std::max<LayoutUnit>(1, (availableWidth + columnGap) / (computedColumnWidth + columnGap));
+ width = ((availableWidth + columnGap) / count) - columnGap;
+ } else {
+ count = std::max<LayoutUnit>(std::min<LayoutUnit>(computedColumnCount, (availableWidth + columnGap) / (computedColumnWidth + columnGap)), 1);
+ width = ((availableWidth + columnGap) / count) - columnGap;
+ }
+}
+
+const char* RenderMultiColumnFlowThread::renderName() const
+{
+ return "RenderMultiColumnFlowThread";
+}
+
+void RenderMultiColumnFlowThread::addRegionToThread(RenderRegion* renderRegion)
+{
+ RenderMultiColumnSet* columnSet = toRenderMultiColumnSet(renderRegion);
+ if (RenderMultiColumnSet* nextSet = columnSet->nextSiblingMultiColumnSet()) {
+ RenderRegionList::iterator it = m_regionList.find(nextSet);
+ ASSERT(it != m_regionList.end());
+ m_regionList.insertBefore(it, columnSet);
+ } else {
+ m_regionList.add(columnSet);
+ }
+ renderRegion->setIsValid(true);
+}
+
+void RenderMultiColumnFlowThread::willBeRemovedFromTree()
+{
+ // Detach all column sets from the flow thread. Cannot destroy them at this point, since they
+ // are siblings of this object, and there may be pointers to this object's sibling somewhere
+ // further up on the call stack.
+ for (RenderMultiColumnSet* columnSet = firstMultiColumnSet(); columnSet; columnSet = columnSet->nextSiblingMultiColumnSet())
+ columnSet->detachRegion();
+ multiColumnBlockFlow()->resetMultiColumnFlowThread();
+ RenderFlowThread::willBeRemovedFromTree();
+}
+
+void RenderMultiColumnFlowThread::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
+{
+ // We simply remain at our intrinsic height.
+ computedValues.m_extent = logicalHeight;
+ computedValues.m_position = logicalTop;
+}
+
+void RenderMultiColumnFlowThread::updateLogicalWidth()
+{
+ LayoutUnit columnWidth;
+ calculateColumnCountAndWidth(columnWidth, m_columnCount);
+ setLogicalWidth(columnWidth);
+}
+
+void RenderMultiColumnFlowThread::layout()
+{
+ RenderFlowThread::layout();
+ if (RenderMultiColumnSet* lastSet = lastMultiColumnSet())
+ lastSet->expandToEncompassFlowThreadContentsIfNeeded();
}
void RenderMultiColumnFlowThread::setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage)
{
+ // Only positive values are interesting (and allowed) here. Zero space shortage may be reported
+ // when we're at the top of a column and the element has zero height. Ignore this, and also
+ // ignore any negative values, which may occur when we set an early break in order to honor
+ // widows in the next column.
+ if (spaceShortage <= 0)
+ return;
+
if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(offset)))
multicolSet->recordSpaceShortage(spaceShortage);
}
@@ -116,4 +296,28 @@ void RenderMultiColumnFlowThread::updateMinimumPageHeight(LayoutUnit offset, Lay
multicolSet->updateMinimumColumnHeight(minHeight);
}
+RenderRegion* RenderMultiColumnFlowThread::regionAtBlockOffset(LayoutUnit /*offset*/) const
+{
+ // For now there's only one column set, so this is easy:
+ return firstMultiColumnSet();
+}
+
+bool RenderMultiColumnFlowThread::addForcedRegionBreak(LayoutUnit offset, RenderObject* /*breakChild*/, bool /*isBefore*/, LayoutUnit* offsetBreakAdjustment)
+{
+ if (RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(regionAtBlockOffset(offset))) {
+ multicolSet->addContentRun(offset);
+ if (offsetBreakAdjustment)
+ *offsetBreakAdjustment = pageLogicalHeightForOffset(offset) ? pageRemainingLogicalHeightForOffset(offset, IncludePageBoundary) : LayoutUnit();
+ return true;
+ }
+ return false;
+}
+
+bool RenderMultiColumnFlowThread::isPageLogicalHeightKnown() const
+{
+ if (RenderMultiColumnSet* columnSet = lastMultiColumnSet())
+ return columnSet->pageLogicalHeight();
+ return false;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h
index ace5c43cbfc..ff5784835b1 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.h
@@ -31,21 +31,118 @@
namespace WebCore {
+class RenderMultiColumnSet;
+
+// Flow thread implementation for CSS multicol. This will be inserted as an anonymous child block of
+// the actual multicol container (i.e. the RenderBlockFlow whose style computes to non-auto
+// column-count and/or column-width). RenderMultiColumnFlowThread is the heart of the multicol
+// implementation, and there is only one instance per multicol container. Child content of the
+// multicol container is parented into the flow thread at the time of renderer insertion.
+//
+// Apart from this flow thread child, the multicol container will also have RenderMultiColumnSet
+// "region" children, which are used to position the columns visually. The flow thread is in charge
+// of layout, and, after having calculated the column width, it lays out content as if everything
+// were in one tall single column, except that there will typically be some amount of blank space
+// (also known as pagination struts) at the offsets where the actual column boundaries are. This
+// way, content that needs to be preceded by a break will appear at the top of the next
+// column. Content needs to be preceded by a break when there's a forced break or when the content
+// is unbreakable and cannot fully fit in the same column as the preceding piece of
+// content. Although a RenderMultiColumnFlowThread is laid out, it does not take up any space in its
+// container. It's the RenderMultiColumnSet objects that take up the necessary amount of space, and
+// make sure that the columns are painted and hit-tested correctly.
+//
+// The width of the flow thread is the same as the column width. The width of a column set is the
+// same as the content box width of the multicol container; in other words exactly enough to hold
+// the number of columns to be used, stacked horizontally, plus column gaps between them.
+//
+// Since it's the first child of the multicol container, the flow thread is laid out first, albeit
+// in a slightly special way, since it's not to take up any space in its ancestors. Afterwards, the
+// column sets are laid out. They get their height from the columns that they hold. In single
+// column-row constrained height non-balancing cases this will simply be the same as the content
+// height of the multicol container itself. In most other cases we'll have to calculate optimal
+// column heights ourselves, though. This process is referred to as column balancing, and then we
+// infer the column set height from the flow thread's height.
+//
+// More on column balancing: the columns' height is unknown in the first layout pass when
+// balancing. This means that we cannot insert any implicit (soft / unforced) breaks (and pagination
+// struts) when laying out the contents of the flow thread. We'll just lay out everything in tall
+// single strip. After the initial flow thread layout pass we can determine a tentative / minimal /
+// initial column height. This is calculated by simply dividing the flow thread's height by the
+// number of specified columns. In the layout pass that follows, we can insert breaks (and
+// pagination struts) at column boundaries, since we now have a column height. It may very easily
+// turn out that the calculated height wasn't enough, though. We'll notice this at end of layout. If
+// we end up with too many columns (i.e. columns overflowing the multicol container), it wasn't
+// enough. In this case we need to increase the column heights. We'll increase them by the lowest
+// amount of space that could possibly affect where the breaks occur (see
+// RenderMultiColumnSet::recordSpaceShortage()). We'll relayout (to find new break points and the
+// new lowest amount of space increase that could affect where they occur, in case we need another
+// round) until we've reached an acceptable height (where everything fits perfectly in the number of
+// columns that we have specified). The rule of thumb is that we shouldn't have to perform more of
+// such iterations than the number of columns that we have.
+//
+// For each layout iteration done for column balancing, the flow thread will need a deep layout if
+// column heights changed in the previous pass, since column height changes may affect break points
+// and pagination struts anywhere in the tree, and currently no way exists to do this in a more
+// optimized manner.
class RenderMultiColumnFlowThread FINAL : public RenderFlowThread {
public:
- ~RenderMultiColumnFlowThread();
+ virtual ~RenderMultiColumnFlowThread();
+
+ static RenderMultiColumnFlowThread* createAnonymous(Document&, RenderStyle* parentStyle);
+
+ virtual bool isRenderMultiColumnFlowThread() const OVERRIDE FINAL { return true; }
+
+ RenderBlockFlow* multiColumnBlockFlow() const { return toRenderBlockFlow(parent()); }
+
+ RenderMultiColumnSet* firstMultiColumnSet() const;
+ RenderMultiColumnSet* lastMultiColumnSet() const;
+
+ virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
+
+ // Populate the flow thread with what's currently its siblings. Called when a regular block
+ // becomes a multicol container.
+ void populate();
- static RenderMultiColumnFlowThread* createAnonymous(Document*);
+ // Empty the flow thread by moving everything to the parent. Remove all multicol specific
+ // renderers. Then destroy the flow thread. Called when a multicol container becomes a regular
+ // block.
+ void evacuateAndDestroy();
+
+ unsigned columnCount() const { return m_columnCount; }
+ LayoutUnit columnHeightAvailable() const { return m_columnHeightAvailable; }
+ void setColumnHeightAvailable(LayoutUnit available) { m_columnHeightAvailable = available; }
+ bool requiresBalancing() const { return !columnHeightAvailable() || multiColumnBlockFlow()->style()->columnFill() == ColumnFillBalance; }
+
+ virtual LayoutSize columnOffset(const LayoutPoint&) const OVERRIDE FINAL;
+
+ // Do we need to set a new width and lay out?
+ bool needsNewWidth() const;
+
+ void layoutColumns(bool relayoutChildren, SubtreeLayoutScope&);
+
+ bool recalculateColumnHeights();
private:
RenderMultiColumnFlowThread();
+ void calculateColumnCountAndWidth(LayoutUnit& width, unsigned& count) const;
+
virtual const char* renderName() const OVERRIDE;
+ virtual void addRegionToThread(RenderRegion*) OVERRIDE;
+ virtual void willBeRemovedFromTree() OVERRIDE;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
- virtual void autoGenerateRegionsToBlockOffset(LayoutUnit) OVERRIDE;
- virtual LayoutUnit initialLogicalWidth() const OVERRIDE;
+ virtual void updateLogicalWidth() OVERRIDE FINAL;
+ virtual void layout() OVERRIDE FINAL;
virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) OVERRIDE;
virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight) OVERRIDE;
+ virtual RenderRegion* regionAtBlockOffset(LayoutUnit) const OVERRIDE;
+ virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) OVERRIDE;
+ virtual bool isPageLogicalHeightKnown() const OVERRIDE;
+
+ unsigned m_columnCount; // The used value of column-count
+ LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto.
+ bool m_inBalancingPass; // Set when relayouting for column balancing.
+ bool m_needsColumnHeightsRecalculation; // Set when we need to recalculate the column set heights after layout.
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp
index 449073752ae..eee9aee2b43 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp
@@ -28,7 +28,6 @@
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderMultiColumnBlock.h"
#include "core/rendering/RenderMultiColumnFlowThread.h"
using namespace std;
@@ -36,91 +35,202 @@ using namespace std;
namespace WebCore {
RenderMultiColumnSet::RenderMultiColumnSet(RenderFlowThread* flowThread)
- : RenderRegionSet(0, flowThread)
- , m_computedColumnCount(1)
- , m_computedColumnWidth(0)
- , m_computedColumnHeight(0)
- , m_maxColumnHeight(LayoutUnit::max())
- , m_minSpaceShortage(LayoutUnit::max())
+ : RenderRegion(0, flowThread)
+ , m_columnHeight(0)
+ , m_maxColumnHeight(RenderFlowThread::maxLogicalHeight())
+ , m_minSpaceShortage(RenderFlowThread::maxLogicalHeight())
, m_minimumColumnHeight(0)
- , m_forcedBreaksCount(0)
- , m_maximumDistanceBetweenForcedBreaks(0)
- , m_forcedBreakOffset(0)
{
}
-RenderMultiColumnSet* RenderMultiColumnSet::createAnonymous(RenderFlowThread* flowThread)
+RenderMultiColumnSet* RenderMultiColumnSet::createAnonymous(RenderFlowThread* flowThread, RenderStyle* parentStyle)
{
Document& document = flowThread->document();
RenderMultiColumnSet* renderer = new RenderMultiColumnSet(flowThread);
renderer->setDocumentForAnonymous(&document);
+ renderer->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentStyle, BLOCK));
return renderer;
}
-LayoutUnit RenderMultiColumnSet::heightAdjustedForSetOffset(LayoutUnit height) const
+RenderMultiColumnSet* RenderMultiColumnSet::nextSiblingMultiColumnSet() const
+{
+ for (RenderObject* sibling = nextSibling(); sibling; sibling = sibling->nextSibling()) {
+ if (sibling->isRenderMultiColumnSet())
+ return toRenderMultiColumnSet(sibling);
+ }
+ return 0;
+}
+
+RenderMultiColumnSet* RenderMultiColumnSet::previousSiblingMultiColumnSet() const
+{
+ for (RenderObject* sibling = previousSibling(); sibling; sibling = sibling->previousSibling()) {
+ if (sibling->isRenderMultiColumnSet())
+ return toRenderMultiColumnSet(sibling);
+ }
+ return 0;
+}
+
+LayoutSize RenderMultiColumnSet::flowThreadTranslationAtOffset(LayoutUnit blockOffset) const
{
- RenderMultiColumnBlock* multicolBlock = toRenderMultiColumnBlock(parent());
- LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderBefore() - multicolBlock->paddingBefore();
+ unsigned columnIndex = columnIndexAtOffset(blockOffset);
+ LayoutRect portionRect(flowThreadPortionRectAt(columnIndex));
+ flipForWritingMode(portionRect);
+ LayoutRect columnRect(columnRectAt(columnIndex));
+ flipForWritingMode(columnRect);
+ return contentBoxRect().location() + columnRect.location() - portionRect.location();
+}
- height -= contentLogicalTop;
+LayoutUnit RenderMultiColumnSet::heightAdjustedForSetOffset(LayoutUnit height) const
+{
+ // Adjust for the top offset within the content box of the multicol container (containing
+ // block), unless this is the first set. We know that the top offset for the first set will be
+ // zero, but if the multicol container has non-zero top border or padding, the set's top offset
+ // (initially being 0 and relative to the border box) will be negative until it has been laid
+ // out. Had we used this bogus offset, we would calculate the wrong height, and risk performing
+ // a wasted layout iteration. Of course all other sets (if any) have this problem in the first
+ // layout pass too, but there's really nothing we can do there until the flow thread has been
+ // laid out anyway.
+ if (previousSiblingMultiColumnSet()) {
+ RenderBlockFlow* multicolBlock = multiColumnBlockFlow();
+ LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderAndPaddingBefore();
+ height -= contentLogicalTop;
+ }
return max(height, LayoutUnit(1)); // Let's avoid zero height, as that would probably cause an infinite amount of columns to be created.
}
LayoutUnit RenderMultiColumnSet::pageLogicalTopForOffset(LayoutUnit offset) const
{
- LayoutUnit portionLogicalTop = (isHorizontalWritingMode() ? flowThreadPortionRect().y() : flowThreadPortionRect().x());
unsigned columnIndex = columnIndexAtOffset(offset, AssumeNewColumns);
- return portionLogicalTop + columnIndex * computedColumnHeight();
+ return logicalTopInFlowThread() + columnIndex * pageLogicalHeight();
}
void RenderMultiColumnSet::setAndConstrainColumnHeight(LayoutUnit newHeight)
{
- m_computedColumnHeight = newHeight;
- if (m_computedColumnHeight > m_maxColumnHeight)
- m_computedColumnHeight = m_maxColumnHeight;
+ m_columnHeight = newHeight;
+ if (m_columnHeight > m_maxColumnHeight)
+ m_columnHeight = m_maxColumnHeight;
// FIXME: the height may also be affected by the enclosing pagination context, if any.
}
-bool RenderMultiColumnSet::calculateBalancedHeight(bool initial)
+unsigned RenderMultiColumnSet::findRunWithTallestColumns() const
+{
+ unsigned indexWithLargestHeight = 0;
+ LayoutUnit largestHeight;
+ LayoutUnit previousOffset = logicalTopInFlowThread();
+ size_t runCount = m_contentRuns.size();
+ ASSERT(runCount);
+ for (size_t i = 0; i < runCount; i++) {
+ const ContentRun& run = m_contentRuns[i];
+ LayoutUnit height = run.columnLogicalHeight(previousOffset);
+ if (largestHeight < height) {
+ largestHeight = height;
+ indexWithLargestHeight = i;
+ }
+ previousOffset = run.breakOffset();
+ }
+ return indexWithLargestHeight;
+}
+
+void RenderMultiColumnSet::distributeImplicitBreaks()
+{
+#ifndef NDEBUG
+ // There should be no implicit breaks assumed at this point.
+ for (unsigned i = 0; i < m_contentRuns.size(); i++)
+ ASSERT(!m_contentRuns[i].assumedImplicitBreaks());
+#endif // NDEBUG
+
+ // Insert a final content run to encompass all content. This will include overflow if this is
+ // the last set.
+ addContentRun(logicalBottomInFlowThread());
+ unsigned columnCount = m_contentRuns.size();
+
+ // If there is room for more breaks (to reach the used value of column-count), imagine that we
+ // insert implicit breaks at suitable locations. At any given time, the content run with the
+ // currently tallest columns will get another implicit break "inserted", which will increase its
+ // column count by one and shrink its columns' height. Repeat until we have the desired total
+ // number of breaks. The largest column height among the runs will then be the initial column
+ // height for the balancer to use.
+ while (columnCount < usedColumnCount()) {
+ unsigned index = findRunWithTallestColumns();
+ m_contentRuns[index].assumeAnotherImplicitBreak();
+ columnCount++;
+ }
+}
+
+LayoutUnit RenderMultiColumnSet::calculateColumnHeight(BalancedHeightCalculation calculationMode) const
{
- ASSERT(toRenderMultiColumnBlock(parent())->requiresBalancing());
- LayoutUnit oldColumnHeight = m_computedColumnHeight;
- LayoutUnit currentMinSpaceShortage = m_minSpaceShortage;
- m_minSpaceShortage = LayoutUnit::max();
-
- if (initial) {
- // Start with the lowest imaginable column height.
- LayoutUnit logicalHeightGuess = ceilf(float(flowThread()->logicalHeight()) / float(m_computedColumnCount));
- logicalHeightGuess = max(logicalHeightGuess, m_minimumColumnHeight);
- setAndConstrainColumnHeight(logicalHeightGuess);
-
- // The multicol container now typically needs at least one more layout pass with a new
- // column height, but if height was specified, we only need to do this if we found that we
- // might need less space than that. On the other hand, if we determined that the columns
- // need to be as tall as the specified height of the container, we have already laid it out
- // correctly, and there's no need for another pass.
- return m_computedColumnHeight != oldColumnHeight;
+ if (calculationMode == GuessFromFlowThreadPortion) {
+ // Initial balancing. Start with the lowest imaginable column height. We use the tallest
+ // content run (after having "inserted" implicit breaks), and find its start offset (by
+ // looking at the previous run's end offset, or, if there's no previous run, the set's start
+ // offset in the flow thread).
+ unsigned index = findRunWithTallestColumns();
+ LayoutUnit startOffset = index > 0 ? m_contentRuns[index - 1].breakOffset() : logicalTopInFlowThread();
+ return std::max<LayoutUnit>(m_contentRuns[index].columnLogicalHeight(startOffset), m_minimumColumnHeight);
}
- if (columnCount() <= computedColumnCount()) {
+ if (actualColumnCount() <= usedColumnCount()) {
// With the current column height, the content fits without creating overflowing columns. We're done.
- return false;
+ return m_columnHeight;
+ }
+
+ if (m_contentRuns.size() >= usedColumnCount()) {
+ // Too many forced breaks to allow any implicit breaks. Initial balancing should already
+ // have set a good height. There's nothing more we should do.
+ return m_columnHeight;
}
// If the initial guessed column height wasn't enough, stretch it now. Stretch by the lowest
// amount of space shortage found during layout.
- ASSERT(currentMinSpaceShortage != LayoutUnit::max()); // If this can actually happen, we probably have a bug.
- if (currentMinSpaceShortage == LayoutUnit::max())
- return false; // So bail out rather than looping infinitely.
+ ASSERT(m_minSpaceShortage > 0); // We should never _shrink_ the height!
+ ASSERT(m_minSpaceShortage != RenderFlowThread::maxLogicalHeight()); // If this happens, we probably have a bug.
+ if (m_minSpaceShortage == RenderFlowThread::maxLogicalHeight())
+ return m_columnHeight; // So bail out rather than looping infinitely.
+
+ return m_columnHeight + m_minSpaceShortage;
+}
+
+void RenderMultiColumnSet::addContentRun(LayoutUnit endOffsetFromFirstPage)
+{
+ if (!multiColumnFlowThread()->requiresBalancing())
+ return;
+ if (!m_contentRuns.isEmpty() && endOffsetFromFirstPage <= m_contentRuns.last().breakOffset())
+ return;
+ // Append another item as long as we haven't exceeded used column count. What ends up in the
+ // overflow area shouldn't affect column balancing.
+ if (m_contentRuns.size() < usedColumnCount())
+ m_contentRuns.append(ContentRun(endOffsetFromFirstPage));
+}
+
+bool RenderMultiColumnSet::recalculateColumnHeight(BalancedHeightCalculation calculationMode)
+{
+ ASSERT(multiColumnFlowThread()->requiresBalancing());
+
+ LayoutUnit oldColumnHeight = m_columnHeight;
+ if (calculationMode == GuessFromFlowThreadPortion) {
+ // Post-process the content runs and find out where the implicit breaks will occur.
+ distributeImplicitBreaks();
+ }
+ LayoutUnit newColumnHeight = calculateColumnHeight(calculationMode);
+ setAndConstrainColumnHeight(newColumnHeight);
+
+ // After having calculated an initial column height, the multicol container typically needs at
+ // least one more layout pass with a new column height, but if a height was specified, we only
+ // need to do this if we think that we need less space than specified. Conversely, if we
+ // determined that the columns need to be as tall as the specified height of the container, we
+ // have already laid it out correctly, and there's no need for another pass.
- setAndConstrainColumnHeight(m_computedColumnHeight + currentMinSpaceShortage);
+ // We can get rid of the content runs now, if we haven't already done so. They are only needed
+ // to calculate the initial balanced column height. In fact, we have to get rid of them before
+ // the next layout pass, since each pass will rebuild this.
+ m_contentRuns.clear();
- // If we reach the maximum column height (typically set by the height or max-height property),
- // we may not be allowed to stretch further. Return true only if stretching
- // succeeded. Otherwise, we're done.
- ASSERT(m_computedColumnHeight >= oldColumnHeight); // We shouldn't be able to shrink the height!
- return m_computedColumnHeight > oldColumnHeight;
+ if (m_columnHeight == oldColumnHeight)
+ return false; // No change. We're done.
+
+ m_minSpaceShortage = RenderFlowThread::maxLogicalHeight();
+ return true; // Need another pass.
}
void RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage)
@@ -135,94 +245,95 @@ void RenderMultiColumnSet::recordSpaceShortage(LayoutUnit spaceShortage)
m_minSpaceShortage = spaceShortage;
}
-void RenderMultiColumnSet::updateLogicalWidth()
+void RenderMultiColumnSet::resetColumnHeight()
{
- RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
- setComputedColumnWidthAndCount(parentBlock->columnWidth(), parentBlock->columnCount()); // FIXME: This will eventually vary if we are contained inside regions.
+ // Nuke previously stored minimum column height. Contents may have changed for all we know.
+ m_minimumColumnHeight = 0;
- // FIXME: When we add regions support, we'll start it off at the width of the multi-column
- // block in that particular region.
- setLogicalWidth(parentBox()->contentLogicalWidth());
+ m_maxColumnHeight = calculateMaxColumnHeight();
- // If we overflow, increase our logical width.
- unsigned colCount = columnCount();
- LayoutUnit colGap = columnGap();
- LayoutUnit minimumContentLogicalWidth = colCount * computedColumnWidth() + (colCount - 1) * colGap;
- LayoutUnit currentContentLogicalWidth = contentLogicalWidth();
- LayoutUnit delta = max(LayoutUnit(), minimumContentLogicalWidth - currentContentLogicalWidth);
- if (!delta)
- return;
+ LayoutUnit oldColumnHeight = pageLogicalHeight();
- // Increase our logical width by the delta.
- setLogicalWidth(logicalWidth() + delta);
-}
+ if (multiColumnFlowThread()->requiresBalancing())
+ m_columnHeight = 0;
+ else
+ setAndConstrainColumnHeight(heightAdjustedForSetOffset(multiColumnFlowThread()->columnHeightAvailable()));
-void RenderMultiColumnSet::prepareForLayout()
-{
- RenderMultiColumnBlock* multicolBlock = toRenderMultiColumnBlock(parent());
- RenderStyle* multicolStyle = multicolBlock->style();
+ if (pageLogicalHeight() != oldColumnHeight)
+ setChildNeedsLayout(MarkOnlyThis);
- // Set box logical top.
- ASSERT(!previousSiblingBox() || !previousSiblingBox()->isRenderMultiColumnSet()); // FIXME: multiple set not implemented; need to examine previous set to calculate the correct logical top.
- setLogicalTop(multicolBlock->borderBefore() + multicolBlock->paddingBefore());
-
- // Set box width.
- updateLogicalWidth();
-
- if (multicolBlock->requiresBalancing()) {
- // Set maximum column height. We will not stretch beyond this.
- m_maxColumnHeight = LayoutUnit::max();
- if (!multicolStyle->logicalHeight().isAuto())
- m_maxColumnHeight = multicolBlock->computeContentLogicalHeight(multicolStyle->logicalHeight(), -1);
- if (!multicolStyle->logicalMaxHeight().isUndefined()) {
- LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(multicolStyle->logicalMaxHeight(), -1);
- if (m_maxColumnHeight > logicalMaxHeight)
- m_maxColumnHeight = logicalMaxHeight;
- }
- m_maxColumnHeight = heightAdjustedForSetOffset(m_maxColumnHeight);
- m_computedColumnHeight = 0; // Restart balancing.
- } else {
- setAndConstrainColumnHeight(heightAdjustedForSetOffset(multicolBlock->columnHeightAvailable()));
- }
+ // Content runs are only needed in the initial layout pass, in order to find an initial column
+ // height, and should have been deleted afterwards. We're about to rebuild the content runs, so
+ // the list needs to be empty.
+ ASSERT(m_contentRuns.isEmpty());
+}
- // Nuke previously stored minimum column height. Contents may have changed for all we know.
- m_minimumColumnHeight = 0;
+void RenderMultiColumnSet::expandToEncompassFlowThreadContentsIfNeeded()
+{
+ ASSERT(multiColumnFlowThread()->lastMultiColumnSet() == this);
+ LayoutRect rect(flowThreadPortionRect());
+
+ // Get the offset within the flow thread in its block progression direction. Then get the
+ // flow thread's remaining logical height including its overflow and expand our rect
+ // to encompass that remaining height and overflow. The idea is that we will generate
+ // additional columns and pages to hold that overflow, since people do write bad
+ // content like <body style="height:0px"> in multi-column layouts.
+ bool isHorizontal = flowThread()->isHorizontalWritingMode();
+ LayoutUnit logicalTopOffset = isHorizontal ? rect.y() : rect.x();
+ LayoutRect layoutRect = flowThread()->layoutOverflowRect();
+ LayoutUnit logicalHeightWithOverflow = (isHorizontal ? layoutRect.maxY() : layoutRect.maxX()) - logicalTopOffset;
+ setFlowThreadPortionRect(LayoutRect(rect.x(), rect.y(), isHorizontal ? rect.width() : logicalHeightWithOverflow, isHorizontal ? logicalHeightWithOverflow : rect.height()));
}
void RenderMultiColumnSet::computeLogicalHeight(LayoutUnit, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{
- computedValues.m_extent = m_computedColumnHeight;
+ computedValues.m_extent = m_columnHeight;
computedValues.m_position = logicalTop;
}
+LayoutUnit RenderMultiColumnSet::calculateMaxColumnHeight() const
+{
+ RenderBlockFlow* multicolBlock = multiColumnBlockFlow();
+ RenderStyle* multicolStyle = multicolBlock->style();
+ LayoutUnit availableHeight = multiColumnFlowThread()->columnHeightAvailable();
+ LayoutUnit maxColumnHeight = availableHeight ? availableHeight : RenderFlowThread::maxLogicalHeight();
+ if (!multicolStyle->logicalMaxHeight().isUndefined()) {
+ LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(multicolStyle->logicalMaxHeight(), -1);
+ if (logicalMaxHeight != -1 && maxColumnHeight > logicalMaxHeight)
+ maxColumnHeight = logicalMaxHeight;
+ }
+ return heightAdjustedForSetOffset(maxColumnHeight);
+}
+
LayoutUnit RenderMultiColumnSet::columnGap() const
{
- // FIXME: Eventually we will cache the column gap when the widths of columns start varying, but for now we just
- // go to the parent block to get the gap.
- RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
+ RenderBlockFlow* parentBlock = multiColumnBlockFlow();
if (parentBlock->style()->hasNormalColumnGap())
return parentBlock->style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
return parentBlock->style()->columnGap();
}
-unsigned RenderMultiColumnSet::columnCount() const
+unsigned RenderMultiColumnSet::actualColumnCount() const
{
// We must always return a value of 1 or greater. Column count = 0 is a meaningless situation,
// and will confuse and cause problems in other parts of the code.
- if (!computedColumnHeight())
+ if (!pageLogicalHeight())
return 1;
// Our portion rect determines our column count. We have as many columns as needed to fit all the content.
LayoutUnit logicalHeightInColumns = flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().height() : flowThreadPortionRect().width();
- unsigned count = ceil(static_cast<float>(logicalHeightInColumns) / computedColumnHeight());
+ if (!logicalHeightInColumns)
+ return 1;
+
+ unsigned count = ceil(logicalHeightInColumns.toFloat() / pageLogicalHeight().toFloat());
ASSERT(count >= 1);
return count;
}
LayoutRect RenderMultiColumnSet::columnRectAt(unsigned index) const
{
- LayoutUnit colLogicalWidth = computedColumnWidth();
- LayoutUnit colLogicalHeight = computedColumnHeight();
+ LayoutUnit colLogicalWidth = pageLogicalWidth();
+ LayoutUnit colLogicalHeight = pageLogicalHeight();
LayoutUnit colLogicalTop = borderBefore() + paddingBefore();
LayoutUnit colLogicalLeft = borderAndPaddingLogicalLeft();
LayoutUnit colGap = columnGap();
@@ -249,20 +360,20 @@ unsigned RenderMultiColumnSet::columnIndexAtOffset(LayoutUnit offset, ColumnInde
if (mode == ClampToExistingColumns) {
LayoutUnit flowThreadLogicalBottom = isHorizontalWritingMode() ? portionRect.maxY() : portionRect.maxX();
if (offset >= flowThreadLogicalBottom)
- return columnCount() - 1;
+ return actualColumnCount() - 1;
}
// Just divide by the column height to determine the correct column.
- return static_cast<float>(offset - flowThreadLogicalTop) / computedColumnHeight();
+ return (offset - flowThreadLogicalTop).toFloat() / pageLogicalHeight().toFloat();
}
LayoutRect RenderMultiColumnSet::flowThreadPortionRectAt(unsigned index) const
{
LayoutRect portionRect = flowThreadPortionRect();
if (isHorizontalWritingMode())
- portionRect = LayoutRect(portionRect.x(), portionRect.y() + index * computedColumnHeight(), portionRect.width(), computedColumnHeight());
+ portionRect = LayoutRect(portionRect.x(), portionRect.y() + index * pageLogicalHeight(), portionRect.width(), pageLogicalHeight());
else
- portionRect = LayoutRect(portionRect.x() + index * computedColumnHeight(), portionRect.y(), computedColumnHeight(), portionRect.height());
+ portionRect = LayoutRect(portionRect.x() + index * pageLogicalHeight(), portionRect.y(), pageLogicalHeight(), portionRect.height());
return portionRect;
}
@@ -308,7 +419,7 @@ void RenderMultiColumnSet::paintObject(PaintInfo& paintInfo, const LayoutPoint&
if (style()->visibility() != VISIBLE)
return;
- RenderBlock::paintObject(paintInfo, paintOffset);
+ RenderBlockFlow::paintObject(paintInfo, paintOffset);
// FIXME: Right now we're only painting in the foreground phase.
// Columns should technically respect phases and allow for background/float/foreground overlap etc., just like
@@ -326,7 +437,7 @@ void RenderMultiColumnSet::paintColumnRules(PaintInfo& paintInfo, const LayoutPo
if (paintInfo.context->paintingDisabled())
return;
- RenderStyle* blockStyle = toRenderMultiColumnBlock(parent())->style();
+ RenderStyle* blockStyle = multiColumnBlockFlow()->style();
const Color& ruleColor = resolveColor(blockStyle, CSSPropertyWebkitColumnRuleColor);
bool ruleTransparent = blockStyle->columnRuleIsTransparent();
EBorderStyle ruleStyle = blockStyle->columnRuleStyle();
@@ -336,7 +447,7 @@ void RenderMultiColumnSet::paintColumnRules(PaintInfo& paintInfo, const LayoutPo
if (!renderRule)
return;
- unsigned colCount = columnCount();
+ unsigned colCount = actualColumnCount();
if (colCount <= 1)
return;
@@ -346,7 +457,7 @@ void RenderMultiColumnSet::paintColumnRules(PaintInfo& paintInfo, const LayoutPo
LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentLogicalWidth();
LayoutUnit ruleAdd = borderAndPaddingLogicalLeft();
LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogicalWidth();
- LayoutUnit inlineDirectionSize = computedColumnWidth();
+ LayoutUnit inlineDirectionSize = pageLogicalWidth();
BoxSide boxSide = isHorizontalWritingMode()
? leftToRight ? BSLeft : BSRight
: leftToRight ? BSTop : BSBottom;
@@ -398,7 +509,7 @@ void RenderMultiColumnSet::repaintFlowThreadContent(const LayoutRect& repaintRec
unsigned endColumn = columnIndexAtOffset(repaintLogicalBottom);
LayoutUnit colGap = columnGap();
- unsigned colCount = columnCount();
+ unsigned colCount = actualColumnCount();
for (unsigned i = startColumn; i <= endColumn; i++) {
LayoutRect colRect = columnRectAt(i);
@@ -451,9 +562,9 @@ void RenderMultiColumnSet::collectLayerFragments(LayerFragments& fragments, cons
unsigned startColumn = columnIndexAtOffset(layerLogicalTop);
unsigned endColumn = columnIndexAtOffset(layerLogicalBottom);
- LayoutUnit colLogicalWidth = computedColumnWidth();
+ LayoutUnit colLogicalWidth = pageLogicalWidth();
LayoutUnit colGap = columnGap();
- unsigned colCount = columnCount();
+ unsigned colCount = actualColumnCount();
for (unsigned i = startColumn; i <= endColumn; i++) {
// Get the portion of the flow thread that corresponds to this column.
@@ -507,6 +618,18 @@ void RenderMultiColumnSet::collectLayerFragments(LayerFragments& fragments, cons
}
}
+void RenderMultiColumnSet::addOverflowFromChildren()
+{
+ unsigned colCount = actualColumnCount();
+ if (!colCount)
+ return;
+
+ LayoutRect lastRect = columnRectAt(colCount - 1);
+ addLayoutOverflow(lastRect);
+ if (!hasOverflowClip())
+ addVisualOverflow(lastRect);
+}
+
const char* RenderMultiColumnSet::renderName() const
{
return "RenderMultiColumnSet";
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h
index 3ebfc5e9c56..16c12faaf36 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.h
@@ -27,65 +27,75 @@
#ifndef RenderMultiColumnSet_h
#define RenderMultiColumnSet_h
-#include "core/rendering/RenderRegionSet.h"
+#include "core/rendering/RenderMultiColumnFlowThread.h"
+#include "core/rendering/RenderRegion.h"
+#include "wtf/Vector.h"
namespace WebCore {
-// RenderMultiColumnSet represents a set of columns that all have the same width and height. By combining runs of same-size columns into a single
-// object, we significantly reduce the number of unique RenderObjects required to represent columns.
+// RenderMultiColumnSet represents a set of columns that all have the same width and height. By
+// combining runs of same-size columns into a single object, we significantly reduce the number of
+// unique RenderObjects required to represent columns.
//
-// A simple multi-column block will have exactly one RenderMultiColumnSet child. A simple paginated multi-column block will have three
-// RenderMultiColumnSet children: one for the content at the bottom of the first page (whose columns will have a shorter height), one
-// for the 2nd to n-1 pages, and then one last column set that will hold the shorter columns on the final page (that may have to be balanced
-// as well).
+// Column sets are inserted as anonymous children of the actual multicol container (i.e. the
+// renderer whose style computes to non-auto column-count and/or column-width).
//
-// Column spans result in the creation of new column sets as well, since a spanning region has to be placed in between the column sets that
-// come before and after the span.
-class RenderMultiColumnSet FINAL : public RenderRegionSet {
+// Being a "region", a column set has no children on its own, but is merely used to slice a portion
+// of the tall "single-column" flow thread into actual columns visually, to convert from flow thread
+// coordinates to visual ones. It is in charge of both positioning columns correctly relatively to
+// the parent multicol container, and to calculate the correct translation for each column's
+// contents, and to paint any rules between them. RenderMultiColumnSet objects are used for
+// painting, hit testing, and any other type of operation that requires mapping from flow thread
+// coordinates to visual coordinates.
+//
+// Column spans result in the creation of new column sets, since a spanning renderer has to be
+// placed in between the column sets that come before and after the span.
+class RenderMultiColumnSet FINAL : public RenderRegion {
public:
- static RenderMultiColumnSet* createAnonymous(RenderFlowThread*);
+ enum BalancedHeightCalculation { GuessFromFlowThreadPortion, StretchBySpaceShortage };
+
+ static RenderMultiColumnSet* createAnonymous(RenderFlowThread*, RenderStyle* parentStyle);
virtual bool isRenderMultiColumnSet() const OVERRIDE { return true; }
- unsigned computedColumnCount() const { return m_computedColumnCount; }
- LayoutUnit computedColumnWidth() const { return m_computedColumnWidth; }
- LayoutUnit computedColumnHeight() const { return m_computedColumnHeight; }
+ virtual LayoutUnit pageLogicalWidth() const OVERRIDE FINAL { return flowThread()->logicalWidth(); }
+ virtual LayoutUnit pageLogicalHeight() const OVERRIDE FINAL { return m_columnHeight; }
- void setComputedColumnWidthAndCount(LayoutUnit width, unsigned count)
+ RenderBlockFlow* multiColumnBlockFlow() const { return toRenderBlockFlow(parent()); }
+ RenderMultiColumnFlowThread* multiColumnFlowThread() const
{
- m_computedColumnWidth = width;
- m_computedColumnCount = count;
+ ASSERT_WITH_SECURITY_IMPLICATION(!flowThread() || flowThread()->isRenderMultiColumnFlowThread());
+ return static_cast<RenderMultiColumnFlowThread*>(flowThread());
}
+ RenderMultiColumnSet* nextSiblingMultiColumnSet() const;
+ RenderMultiColumnSet* previousSiblingMultiColumnSet() const;
+
+ LayoutUnit logicalTopInFlowThread() const { return isHorizontalWritingMode() ? flowThreadPortionRect().y() : flowThreadPortionRect().x(); }
+ LayoutUnit logicalBottomInFlowThread() const { return isHorizontalWritingMode() ? flowThreadPortionRect().maxY() : flowThreadPortionRect().maxX(); }
+
+ LayoutUnit logicalHeightInFlowThread() const { return isHorizontalWritingMode() ? flowThreadPortionRect().height() : flowThreadPortionRect().width(); }
+
+ // The used CSS value of column-count, i.e. how many columns there are room for without overflowing.
+ unsigned usedColumnCount() const { return multiColumnFlowThread()->columnCount(); }
+
+ // Find the column that contains the given block offset, and return the translation needed to
+ // get from flow thread coordinates to visual coordinates.
+ LayoutSize flowThreadTranslationAtOffset(LayoutUnit) const;
+
LayoutUnit heightAdjustedForSetOffset(LayoutUnit height) const;
void updateMinimumColumnHeight(LayoutUnit height) { m_minimumColumnHeight = std::max(height, m_minimumColumnHeight); }
LayoutUnit minimumColumnHeight() const { return m_minimumColumnHeight; }
- unsigned forcedBreaksCount() const { return m_forcedBreaksCount; }
- LayoutUnit forcedBreakOffset() const { return m_forcedBreakOffset; }
- LayoutUnit maximumDistanceBetweenForcedBreaks() const { return m_maximumDistanceBetweenForcedBreaks; }
- void clearForcedBreaks()
- {
- m_forcedBreaksCount = 0;
- m_maximumDistanceBetweenForcedBreaks = 0;
- m_forcedBreakOffset = 0;
- }
- void addForcedBreak(LayoutUnit offsetFromFirstPage)
- {
- ASSERT(!computedColumnHeight());
- LayoutUnit distanceFromLastBreak = offsetFromFirstPage - m_forcedBreakOffset;
- if (!distanceFromLastBreak)
- return;
- m_forcedBreaksCount++;
- m_maximumDistanceBetweenForcedBreaks = std::max(m_maximumDistanceBetweenForcedBreaks, distanceFromLastBreak);
- m_forcedBreakOffset = offsetFromFirstPage;
- }
+ // Add a content run, specified by its end position. A content run is appended at every
+ // forced/explicit break and at the end of the column set. The content runs are used to
+ // determine where implicit/soft breaks will occur, in order to calculate an initial column
+ // height.
+ void addContentRun(LayoutUnit endOffsetFromFirstPage);
- // Calculate the column height when contents are supposed to be balanced. If 'initial' is set,
- // guess an initial column height; otherwise, stretch the column height a tad. Return true if
- // column height changed and another layout pass is required.
- bool calculateBalancedHeight(bool initial);
+ // (Re-)calculate the column height if it's auto.
+ bool recalculateColumnHeight(BalancedHeightCalculation);
// Record space shortage (the amount of space that would have been enough to prevent some
// element from being moved to the next column) at a column break. The smallest amount of space
@@ -93,9 +103,12 @@ public:
// after layout that the columns weren't tall enough.
void recordSpaceShortage(LayoutUnit spaceShortage);
- virtual void updateLogicalWidth() OVERRIDE;
+ // Reset previously calculated column height. Will mark for layout if needed.
+ void resetColumnHeight();
- void prepareForLayout();
+ // Expand this set's flow thread portion rectangle to contain all trailing flow thread
+ // overflow. Only to be called on the last set.
+ void expandToEncompassFlowThreadContentsIfNeeded();
private:
RenderMultiColumnSet(RenderFlowThread*);
@@ -104,29 +117,26 @@ private:
virtual void paintObject(PaintInfo&, const LayoutPoint& paintOffset) OVERRIDE;
- virtual LayoutUnit pageLogicalWidth() const OVERRIDE { return m_computedColumnWidth; }
- virtual LayoutUnit pageLogicalHeight() const OVERRIDE { return m_computedColumnHeight; }
-
virtual LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const OVERRIDE;
- // FIXME: This will change once we have column sets constrained by enclosing pages, etc.
- virtual LayoutUnit logicalHeightOfAllFlowThreadContent() const OVERRIDE { return m_computedColumnHeight; }
-
- // FIXME: For now we return false, but it's likely we will leverage the auto height region code to do column
- // balancing. That's why we have an override of this function that is distinct from RenderRegionSet's override.
- virtual bool shouldHaveAutoLogicalHeight() const OVERRIDE { return false; }
+ virtual LayoutUnit logicalHeightOfAllFlowThreadContent() const OVERRIDE { return logicalHeightInFlowThread(); }
virtual void repaintFlowThreadContent(const LayoutRect& repaintRect) const OVERRIDE;
virtual void collectLayerFragments(LayerFragments&, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect) OVERRIDE;
- virtual const char* renderName() const;
+ virtual void addOverflowFromChildren() OVERRIDE;
+
+ virtual const char* renderName() const OVERRIDE;
void paintColumnRules(PaintInfo&, const LayoutPoint& paintOffset);
+ LayoutUnit calculateMaxColumnHeight() const;
LayoutUnit columnGap() const;
LayoutRect columnRectAt(unsigned index) const;
- unsigned columnCount() const;
+
+ // The "CSS actual" value of column-count. This includes overflowing columns, if any.
+ unsigned actualColumnCount() const;
LayoutRect flowThreadPortionRectAt(unsigned index) const;
LayoutRect flowThreadPortionOverflowRect(const LayoutRect& flowThreadPortion, unsigned index, unsigned colCount, LayoutUnit colGap) const;
@@ -139,17 +149,50 @@ private:
void setAndConstrainColumnHeight(LayoutUnit);
- unsigned m_computedColumnCount;
- LayoutUnit m_computedColumnWidth;
- LayoutUnit m_computedColumnHeight;
+ // Return the index of the content run with the currently tallest columns, taking all implicit
+ // breaks assumed so far into account.
+ unsigned findRunWithTallestColumns() const;
+
+ // Given the current list of content runs, make assumptions about where we need to insert
+ // implicit breaks (if there's room for any at all; depending on the number of explicit breaks),
+ // and store the results. This is needed in order to balance the columns.
+ void distributeImplicitBreaks();
+
+ LayoutUnit calculateColumnHeight(BalancedHeightCalculation) const;
+
+ LayoutUnit m_columnHeight;
// The following variables are used when balancing the column set.
LayoutUnit m_maxColumnHeight; // Maximum column height allowed.
LayoutUnit m_minSpaceShortage; // The smallest amout of space shortage that caused a column break.
LayoutUnit m_minimumColumnHeight;
- unsigned m_forcedBreaksCount; // FIXME: We will ultimately need to cache more information to balance around forced breaks properly.
- LayoutUnit m_maximumDistanceBetweenForcedBreaks;
- LayoutUnit m_forcedBreakOffset;
+
+ // A run of content without explicit (forced) breaks; i.e. a flow thread portion between two
+ // explicit breaks, between flow thread start and an explicit break, between an explicit break
+ // and flow thread end, or, in cases when there are no explicit breaks at all: between flow
+ // thread portion start and flow thread portion end. We need to know where the explicit breaks
+ // are, in order to figure out where the implicit breaks will end up, so that we get the columns
+ // properly balanced. A content run starts out as representing one single column, and will
+ // represent one additional column for each implicit break "inserted" there.
+ class ContentRun {
+ public:
+ ContentRun(LayoutUnit breakOffset)
+ : m_breakOffset(breakOffset)
+ , m_assumedImplicitBreaks(0) { }
+
+ unsigned assumedImplicitBreaks() const { return m_assumedImplicitBreaks; }
+ void assumeAnotherImplicitBreak() { m_assumedImplicitBreaks++; }
+ LayoutUnit breakOffset() const { return m_breakOffset; }
+
+ // Return the column height that this content run would require, considering the implicit
+ // breaks assumed so far.
+ LayoutUnit columnLogicalHeight(LayoutUnit startOffset) const { return ceilf((m_breakOffset - startOffset).toFloat() / float(m_assumedImplicitBreaks + 1)); }
+
+ private:
+ LayoutUnit m_breakOffset; // Flow thread offset where this run ends.
+ unsigned m_assumedImplicitBreaks; // Number of implicit breaks in this run assumed so far.
+ };
+ Vector<ContentRun, 1> m_contentRuns;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderMultiColumnSet, isRenderMultiColumnSet());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowFragment.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowFragment.cpp
deleted file mode 100644
index 5a754e99f82..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowFragment.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/RenderNamedFlowFragment.h"
-
-#include "core/rendering/FlowThreadController.h"
-#include "core/rendering/RenderBoxRegionInfo.h"
-#include "core/rendering/RenderFlowThread.h"
-#include "core/rendering/RenderNamedFlowThread.h"
-#include "core/rendering/RenderView.h"
-
-using namespace std;
-
-namespace WebCore {
-
-RenderNamedFlowFragment::RenderNamedFlowFragment()
- : RenderRegion(0, 0)
-{
-}
-
-RenderNamedFlowFragment::~RenderNamedFlowFragment()
-{
-}
-
-RenderNamedFlowFragment* RenderNamedFlowFragment::createAnonymous(Document* document)
-{
- RenderNamedFlowFragment* region = new RenderNamedFlowFragment();
- region->setDocumentForAnonymous(document);
- return region;
-}
-
-void RenderNamedFlowFragment::setStyleForNamedFlowFragment(const RenderStyle* parentStyle)
-{
- RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(parentStyle, BLOCK);
-
- newStyle->setFlowThread(parentStyle->flowThread());
- newStyle->setRegionThread(parentStyle->regionThread());
- newStyle->setRegionFragment(parentStyle->regionFragment());
- newStyle->setShapeInside(parentStyle->shapeInside());
- newStyle->setOverflowX(parentStyle->overflowX());
- newStyle->setOverflowY(parentStyle->overflowY());
-
- setStyle(newStyle.release());
-}
-
-void RenderNamedFlowFragment::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderRegion::styleDidChange(diff, oldStyle);
-
- if (parent() && parent()->needsLayout())
- setNeedsLayout();
-}
-
-// FIXME: flex items as regions with flex-basis: 0 inside a flex container
-// with flex-direction: column should not be treated as auto-height regions
-bool RenderNamedFlowFragment::shouldHaveAutoLogicalHeight() const
-{
- ASSERT(parent());
-
- RenderStyle* styleToUse = parent()->style();
- bool hasSpecifiedEndpointsForHeight = styleToUse->logicalTop().isSpecified() && styleToUse->logicalBottom().isSpecified();
- bool hasAnchoredEndpointsForHeight = isOutOfFlowPositioned() && hasSpecifiedEndpointsForHeight;
- bool hasAutoHeightStyle = styleToUse->logicalHeight().isAuto()
- || styleToUse->logicalHeight().isFitContent()
- || styleToUse->logicalHeight().isMaxContent()
- || styleToUse->logicalHeight().isMinContent();
- return hasAutoHeightStyle && !hasAnchoredEndpointsForHeight;
-}
-
-LayoutUnit RenderNamedFlowFragment::maxPageLogicalHeight() const
-{
- ASSERT(m_flowThread);
- ASSERT(hasAutoLogicalHeight() && !m_flowThread->inConstrainedLayoutPhase());
- ASSERT(isAnonymous());
- ASSERT(parent());
-
- RenderStyle* styleToUse = parent()->style();
- return styleToUse->logicalMaxHeight().isUndefined() ? RenderFlowThread::maxLogicalHeight() : toRenderBlock(parent())->computeReplacedLogicalHeightUsing(styleToUse->logicalMaxHeight());
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowFragment.h b/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowFragment.h
deleted file mode 100644
index 79e4d7ceb63..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowFragment.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef RenderNamedFlowFragment_h
-#define RenderNamedFlowFragment_h
-
-#include "core/rendering/RenderRegion.h"
-
-namespace WebCore {
-
-class Element;
-class RenderStyle;
-
-// RenderNamedFlowFragment represents a region that is responsible for the fragmentation of
-// the RenderNamedFlowThread content.
-//
-// A RenderNamedFlowFragment object is created as an anonymous child for a RenderBlockFlow object
-// that has a valid -webkit-flow-from property.
-//
-// This allows a non-replaced block to behave like a region if needed, following the CSSRegions specification:
-// http://dev.w3.org/csswg/css-regions/#the-flow-from-property.
-// list-item, table-caption, table-cell can become regions in addition to block | inline-block.
-
-class RenderNamedFlowFragment FINAL : public RenderRegion {
-public:
- virtual ~RenderNamedFlowFragment();
- static RenderNamedFlowFragment* createAnonymous(Document*);
-
- void setStyleForNamedFlowFragment(const RenderStyle*);
-
- virtual bool isRenderNamedFlowFragment() const OVERRIDE { return true; }
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
-
- virtual LayoutUnit maxPageLogicalHeight() const OVERRIDE;
-
-protected:
- RenderNamedFlowFragment();
-
-private:
- virtual bool shouldHaveAutoLogicalHeight() const OVERRIDE;
- virtual const char* renderName() const OVERRIDE { return "RenderNamedFlowFragment"; }
-};
-
-DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderNamedFlowFragment, isRenderNamedFlowFragment());
-
-}
-
-#endif // RenderNamedFlowFragment_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowThread.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowThread.cpp
deleted file mode 100644
index 72049543c9d..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowThread.cpp
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS IN..0TERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/RenderNamedFlowThread.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/dom/NamedFlow.h"
-#include "core/dom/NodeRenderingTraversal.h"
-#include "core/dom/NodeTraversal.h"
-#include "core/dom/Position.h"
-#include "core/dom/Range.h"
-#include "core/dom/Text.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/rendering/FlowThreadController.h"
-#include "core/rendering/InlineTextBox.h"
-#include "core/rendering/RenderInline.h"
-#include "core/rendering/RenderRegion.h"
-#include "core/rendering/RenderText.h"
-#include "core/rendering/RenderView.h"
-
-namespace WebCore {
-
-RenderNamedFlowThread* RenderNamedFlowThread::createAnonymous(Document* document, PassRefPtr<NamedFlow> namedFlow)
-{
- ASSERT(RuntimeEnabledFeatures::cssRegionsEnabled());
- RenderNamedFlowThread* renderer = new RenderNamedFlowThread(namedFlow);
- renderer->setDocumentForAnonymous(document);
- return renderer;
-}
-
-RenderNamedFlowThread::RenderNamedFlowThread(PassRefPtr<NamedFlow> namedFlow)
- : m_overset(true)
- , m_namedFlow(namedFlow)
- , m_regionLayoutUpdateEventTimer(this, &RenderNamedFlowThread::regionLayoutUpdateEventTimerFired)
- , m_regionOversetChangeEventTimer(this, &RenderNamedFlowThread::regionOversetChangeEventTimerFired)
-{
-}
-
-RenderNamedFlowThread::~RenderNamedFlowThread()
-{
- // The flow thread can be destroyed without unregistering the content nodes if the document is destroyed.
- // This can lead to problems because the nodes are still marked as belonging to a flow thread.
- clearContentNodes();
-
- // Also leave the NamedFlow object in a consistent state by calling mark for destruction.
- setMarkForDestruction();
-}
-
-const char* RenderNamedFlowThread::renderName() const
-{
- return "RenderNamedFlowThread";
-}
-
-void RenderNamedFlowThread::clearContentNodes()
-{
- for (NamedFlowContentNodes::iterator it = m_contentNodes.begin(); it != m_contentNodes.end(); ++it) {
- Node* contentNode = *it;
-
- ASSERT(contentNode && contentNode->isElementNode());
- ASSERT(contentNode->inNamedFlow());
- ASSERT(contentNode->document() == document());
-
- contentNode->clearInNamedFlow();
- }
-
- m_contentNodes.clear();
-}
-
-void RenderNamedFlowThread::updateWritingMode()
-{
- RenderRegion* firstRegion = m_regionList.first();
- if (!firstRegion)
- return;
- if (style()->writingMode() == firstRegion->style()->writingMode())
- return;
-
- // The first region defines the principal writing mode for the entire flow.
- RefPtr<RenderStyle> newStyle = RenderStyle::clone(style());
- newStyle->setWritingMode(firstRegion->style()->writingMode());
- setStyle(newStyle.release());
-}
-
-RenderObject* RenderNamedFlowThread::nextRendererForNode(Node* node) const
-{
- FlowThreadChildList::const_iterator it = m_flowThreadChildList.begin();
- FlowThreadChildList::const_iterator end = m_flowThreadChildList.end();
-
- for (; it != end; ++it) {
- RenderObject* child = *it;
- ASSERT(child->node());
- unsigned short position = node->compareDocumentPosition(child->node());
- if (position & Node::DOCUMENT_POSITION_FOLLOWING)
- return child;
- }
-
- return 0;
-}
-
-RenderObject* RenderNamedFlowThread::previousRendererForNode(Node* node) const
-{
- if (m_flowThreadChildList.isEmpty())
- return 0;
-
- FlowThreadChildList::const_iterator begin = m_flowThreadChildList.begin();
- FlowThreadChildList::const_iterator end = m_flowThreadChildList.end();
- FlowThreadChildList::const_iterator it = end;
-
- do {
- --it;
- RenderObject* child = *it;
- ASSERT(child->node());
- unsigned short position = node->compareDocumentPosition(child->node());
- if (position & Node::DOCUMENT_POSITION_PRECEDING)
- return child;
- } while (it != begin);
-
- return 0;
-}
-
-void RenderNamedFlowThread::addFlowChild(RenderObject* newChild)
-{
- // The child list is used to sort the flow thread's children render objects
- // based on their corresponding nodes DOM order. The list is needed to avoid searching the whole DOM.
-
- Node* childNode = newChild->node();
-
- // Do not add anonymous objects.
- if (!childNode)
- return;
-
- ASSERT(childNode->isElementNode());
-
- RenderObject* beforeChild = nextRendererForNode(childNode);
- if (beforeChild)
- m_flowThreadChildList.insertBefore(beforeChild, newChild);
- else
- m_flowThreadChildList.add(newChild);
-}
-
-void RenderNamedFlowThread::removeFlowChild(RenderObject* child)
-{
- m_flowThreadChildList.remove(child);
-}
-
-bool RenderNamedFlowThread::dependsOn(RenderNamedFlowThread* otherRenderFlowThread) const
-{
- if (m_layoutBeforeThreadsSet.contains(otherRenderFlowThread))
- return true;
-
- // Recursively traverse the m_layoutBeforeThreadsSet.
- RenderNamedFlowThreadCountedSet::const_iterator iterator = m_layoutBeforeThreadsSet.begin();
- RenderNamedFlowThreadCountedSet::const_iterator end = m_layoutBeforeThreadsSet.end();
- for (; iterator != end; ++iterator) {
- const RenderNamedFlowThread* beforeFlowThread = (*iterator).key;
- if (beforeFlowThread->dependsOn(otherRenderFlowThread))
- return true;
- }
-
- return false;
-}
-
-// Compare two regions to determine in which one the content should flow first.
-// The function returns true if the first passed region is "less" than the second passed region.
-// If the first region appears before second region in DOM,
-// the first region is "less" than the second region.
-// If the first region is "less" than the second region, the first region receives content before second region.
-static bool compareRenderRegions(const RenderRegion* firstRegion, const RenderRegion* secondRegion)
-{
- ASSERT(firstRegion);
- ASSERT(secondRegion);
-
- ASSERT(firstRegion->generatingNodeForRegion());
- ASSERT(secondRegion->generatingNodeForRegion());
-
- // If the regions belong to different nodes, compare their position in the DOM.
- if (firstRegion->generatingNodeForRegion() != secondRegion->generatingNodeForRegion()) {
- unsigned short position = firstRegion->generatingNodeForRegion()->compareDocumentPosition(secondRegion->generatingNodeForRegion());
-
- // If the second region is contained in the first one, the first region is "less" if it's :before.
- if (position & Node::DOCUMENT_POSITION_CONTAINED_BY) {
- ASSERT(secondRegion->style()->styleType() == NOPSEUDO);
- return firstRegion->style()->styleType() == BEFORE;
- }
-
- // If the second region contains the first region, the first region is "less" if the second is :after.
- if (position & Node::DOCUMENT_POSITION_CONTAINS) {
- ASSERT(firstRegion->style()->styleType() == NOPSEUDO);
- return secondRegion->style()->styleType() == AFTER;
- }
-
- return (position & Node::DOCUMENT_POSITION_FOLLOWING);
- }
-
- // FIXME: Currently it's not possible for an element to be both a region and have pseudo-children. The case is covered anyway.
- switch (firstRegion->style()->styleType()) {
- case BEFORE:
- // The second region can be the node or the after pseudo-element (before is smaller than any of those).
- return true;
- case AFTER:
- // The second region can be the node or the before pseudo-element (after is greater than any of those).
- return false;
- case NOPSEUDO:
- // The second region can either be the before or the after pseudo-element (the node is only smaller than the after pseudo-element).
- return firstRegion->style()->styleType() == AFTER;
- default:
- break;
- }
-
- ASSERT_NOT_REACHED();
- return true;
-}
-
-// This helper function adds a region to a list preserving the order property of the list.
-static void addRegionToList(RenderRegionList& regionList, RenderRegion* renderRegion)
-{
- if (regionList.isEmpty()) {
- regionList.add(renderRegion);
- } else {
- // Find the first region "greater" than renderRegion.
- RenderRegionList::iterator it = regionList.begin();
- while (it != regionList.end() && !compareRenderRegions(renderRegion, *it))
- ++it;
- regionList.insertBefore(it, renderRegion);
- }
-}
-
-void RenderNamedFlowThread::addRegionToNamedFlowThread(RenderRegion* renderRegion)
-{
- ASSERT(renderRegion);
- ASSERT(!renderRegion->isValid());
-
- if (renderRegion->parentNamedFlowThread())
- addDependencyOnFlowThread(renderRegion->parentNamedFlowThread());
-
- renderRegion->setIsValid(true);
- addRegionToList(m_regionList, renderRegion);
-
- if (m_regionList.first() == renderRegion)
- updateWritingMode();
-}
-
-void RenderNamedFlowThread::addRegionToThread(RenderRegion* renderRegion)
-{
- ASSERT(renderRegion);
- ASSERT(!renderRegion->isValid());
-
- resetMarkForDestruction();
-
- if (renderRegion->parentNamedFlowThread() && renderRegion->parentNamedFlowThread()->dependsOn(this)) {
- // The order of invalid regions is irrelevant.
- m_invalidRegionList.add(renderRegion);
- // Register ourself to get a notification when the state changes.
- renderRegion->parentNamedFlowThread()->m_observerThreadsSet.add(this);
- return;
- }
-
- addRegionToNamedFlowThread(renderRegion);
-
- invalidateRegions();
-}
-
-void RenderNamedFlowThread::removeRegionFromThread(RenderRegion* renderRegion)
-{
- ASSERT(renderRegion);
-
- if (renderRegion->parentNamedFlowThread()) {
- if (!renderRegion->isValid()) {
- ASSERT(m_invalidRegionList.contains(renderRegion));
- m_invalidRegionList.remove(renderRegion);
- renderRegion->parentNamedFlowThread()->m_observerThreadsSet.remove(this);
- // No need to invalidate the regions rectangles. The removed region
- // was not taken into account. Just return here.
- return;
- }
- removeDependencyOnFlowThread(renderRegion->parentNamedFlowThread());
- }
-
- ASSERT(m_regionList.contains(renderRegion));
- bool wasFirst = m_regionList.first() == renderRegion;
- m_regionList.remove(renderRegion);
-
- if (canBeDestroyed())
- setMarkForDestruction();
-
- // After removing all the regions in the flow the following layout needs to dispatch the regionLayoutUpdate event
- if (m_regionList.isEmpty())
- setDispatchRegionLayoutUpdateEvent(true);
- else if (wasFirst)
- updateWritingMode();
-
- invalidateRegions();
-}
-
-void RenderNamedFlowThread::regionChangedWritingMode(RenderRegion* region)
-{
- if (m_regionList.first() == region)
- updateWritingMode();
-}
-
-void RenderNamedFlowThread::computeOversetStateForRegions(LayoutUnit oldClientAfterEdge)
-{
- LayoutUnit height = oldClientAfterEdge;
-
- // FIXME: the visual overflow of middle region (if it is the last one to contain any content in a render flow thread)
- // might not be taken into account because the render flow thread height is greater that that regions height + its visual overflow
- // because of how computeLogicalHeight is implemented for RenderFlowThread (as a sum of all regions height).
- // This means that the middle region will be marked as fit (even if it has visual overflow flowing into the next region)
- if (hasRenderOverflow()
- && ( (isHorizontalWritingMode() && visualOverflowRect().maxY() > clientBoxRect().maxY())
- || (!isHorizontalWritingMode() && visualOverflowRect().maxX() > clientBoxRect().maxX())))
- height = isHorizontalWritingMode() ? visualOverflowRect().maxY() : visualOverflowRect().maxX();
-
- RenderRegion* lastReg = lastRegion();
- for (RenderRegionList::iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) {
- RenderRegion* region = *iter;
- LayoutUnit flowMin = height - (isHorizontalWritingMode() ? region->flowThreadPortionRect().y() : region->flowThreadPortionRect().x());
- LayoutUnit flowMax = height - (isHorizontalWritingMode() ? region->flowThreadPortionRect().maxY() : region->flowThreadPortionRect().maxX());
- RegionOversetState previousState = region->regionOversetState();
- RegionOversetState state = RegionFit;
- if (flowMin <= 0)
- state = RegionEmpty;
- if (flowMax > 0 && region == lastReg)
- state = RegionOverset;
- region->setRegionOversetState(state);
- // determine whether the NamedFlow object should dispatch a regionLayoutUpdate event
- // FIXME: currently it cannot determine whether a region whose regionOverset state remained either "fit" or "overset" has actually
- // changed, so it just assumes that the NamedFlow should dispatch the event
- if (previousState != state
- || state == RegionFit
- || state == RegionOverset)
- setDispatchRegionLayoutUpdateEvent(true);
-
- if (previousState != state)
- setDispatchRegionOversetChangeEvent(true);
- }
-
- // If the number of regions has changed since we last computed the overset property, schedule the regionOversetChange event.
- if (previousRegionCountChanged()) {
- setDispatchRegionOversetChangeEvent(true);
- updatePreviousRegionCount();
- }
-
- // With the regions overflow state computed we can also set the overset flag for the named flow.
- // If there are no valid regions in the chain, overset is true.
- m_overset = lastReg ? lastReg->regionOversetState() == RegionOverset : true;
-}
-
-void RenderNamedFlowThread::checkInvalidRegions()
-{
- Vector<RenderRegion*> newValidRegions;
- for (RenderRegionList::iterator iter = m_invalidRegionList.begin(); iter != m_invalidRegionList.end(); ++iter) {
- RenderRegion* region = *iter;
- // The only reason a region would be invalid is because it has a parent flow thread.
- ASSERT(!region->isValid() && region->parentNamedFlowThread());
- if (region->parentNamedFlowThread()->dependsOn(this))
- continue;
-
- newValidRegions.append(region);
- }
-
- for (Vector<RenderRegion*>::iterator iter = newValidRegions.begin(); iter != newValidRegions.end(); ++iter) {
- RenderRegion* region = *iter;
- m_invalidRegionList.remove(region);
- region->parentNamedFlowThread()->m_observerThreadsSet.remove(this);
- addRegionToNamedFlowThread(region);
- }
-
- if (!newValidRegions.isEmpty())
- invalidateRegions();
-
- if (m_observerThreadsSet.isEmpty())
- return;
-
- // Notify all the flow threads that were dependent on this flow.
-
- // Create a copy of the list first. That's because observers might change the list when calling checkInvalidRegions.
- Vector<RenderNamedFlowThread*> observers;
- copyToVector(m_observerThreadsSet, observers);
-
- for (size_t i = 0; i < observers.size(); ++i) {
- RenderNamedFlowThread* flowThread = observers.at(i);
- flowThread->checkInvalidRegions();
- }
-}
-
-void RenderNamedFlowThread::addDependencyOnFlowThread(RenderNamedFlowThread* otherFlowThread)
-{
- RenderNamedFlowThreadCountedSet::AddResult result = m_layoutBeforeThreadsSet.add(otherFlowThread);
- if (result.isNewEntry) {
- // This is the first time we see this dependency. Make sure we recalculate all the dependencies.
- view()->flowThreadController()->setIsRenderNamedFlowThreadOrderDirty(true);
- }
-}
-
-void RenderNamedFlowThread::removeDependencyOnFlowThread(RenderNamedFlowThread* otherFlowThread)
-{
- bool removed = m_layoutBeforeThreadsSet.remove(otherFlowThread);
- if (removed) {
- checkInvalidRegions();
- view()->flowThreadController()->setIsRenderNamedFlowThreadOrderDirty(true);
- }
-}
-
-void RenderNamedFlowThread::pushDependencies(RenderNamedFlowThreadList& list)
-{
- for (RenderNamedFlowThreadCountedSet::iterator iter = m_layoutBeforeThreadsSet.begin(); iter != m_layoutBeforeThreadsSet.end(); ++iter) {
- RenderNamedFlowThread* flowThread = (*iter).key;
- if (list.contains(flowThread))
- continue;
- flowThread->pushDependencies(list);
- list.add(flowThread);
- }
-}
-
-// The content nodes list contains those nodes with -webkit-flow-into: flow.
-// An element with display:none should also be listed among those nodes.
-// The list of nodes is ordered.
-void RenderNamedFlowThread::registerNamedFlowContentNode(Node* contentNode)
-{
- ASSERT(contentNode && contentNode->isElementNode());
- ASSERT(contentNode->document() == document());
-
- contentNode->setInNamedFlow();
-
- resetMarkForDestruction();
-
- // Find the first content node following the new content node.
- for (NamedFlowContentNodes::iterator it = m_contentNodes.begin(); it != m_contentNodes.end(); ++it) {
- Node* node = *it;
- unsigned short position = contentNode->compareDocumentPosition(node);
- if (position & Node::DOCUMENT_POSITION_FOLLOWING) {
- m_contentNodes.insertBefore(node, contentNode);
- return;
- }
- }
- m_contentNodes.add(contentNode);
-}
-
-void RenderNamedFlowThread::unregisterNamedFlowContentNode(Node* contentNode)
-{
- ASSERT(contentNode && contentNode->isElementNode());
- ASSERT(m_contentNodes.contains(contentNode));
- ASSERT(contentNode->inNamedFlow());
- ASSERT(contentNode->document() == document());
-
- contentNode->clearInNamedFlow();
- m_contentNodes.remove(contentNode);
-
- if (canBeDestroyed())
- setMarkForDestruction();
-}
-
-const AtomicString& RenderNamedFlowThread::flowThreadName() const
-{
- return m_namedFlow->name();
-}
-
-bool RenderNamedFlowThread::isChildAllowed(RenderObject* child, RenderStyle* style) const
-{
- if (!child->node())
- return true;
-
- ASSERT(child->node()->isElementNode());
- Node* originalParent = NodeRenderingTraversal::parent(child->node());
- if (!originalParent || !originalParent->renderer())
- return true;
-
- return originalParent->renderer()->isChildAllowed(child, style);
-}
-
-void RenderNamedFlowThread::dispatchRegionLayoutUpdateEvent()
-{
- RenderFlowThread::dispatchRegionLayoutUpdateEvent();
- InspectorInstrumentation::didUpdateRegionLayout(&document(), m_namedFlow.get());
-
- if (!m_regionLayoutUpdateEventTimer.isActive() && m_namedFlow->hasEventListeners())
- m_regionLayoutUpdateEventTimer.startOneShot(0);
-}
-
-void RenderNamedFlowThread::dispatchRegionOversetChangeEvent()
-{
- RenderFlowThread::dispatchRegionOversetChangeEvent();
- InspectorInstrumentation::didChangeRegionOverset(&document(), m_namedFlow.get());
-
- if (!m_regionOversetChangeEventTimer.isActive() && m_namedFlow->hasEventListeners())
- m_regionOversetChangeEventTimer.startOneShot(0);
-}
-
-void RenderNamedFlowThread::regionLayoutUpdateEventTimerFired(Timer<RenderNamedFlowThread>*)
-{
- ASSERT(m_namedFlow);
-
- m_namedFlow->dispatchRegionLayoutUpdateEvent();
-}
-
-void RenderNamedFlowThread::regionOversetChangeEventTimerFired(Timer<RenderNamedFlowThread>*)
-{
- ASSERT(m_namedFlow);
-
- m_namedFlow->dispatchRegionOversetChangeEvent();
-}
-
-void RenderNamedFlowThread::setMarkForDestruction()
-{
- if (m_namedFlow->flowState() == NamedFlow::FlowStateNull)
- return;
-
- m_namedFlow->setRenderer(0);
- // After this call ends, the renderer can be safely destroyed.
- // The NamedFlow object may outlive its renderer if it's referenced from a script and may be reatached to one if the named flow is recreated in the stylesheet.
-}
-
-void RenderNamedFlowThread::resetMarkForDestruction()
-{
- if (m_namedFlow->flowState() == NamedFlow::FlowStateCreated)
- return;
-
- m_namedFlow->setRenderer(this);
-}
-
-bool RenderNamedFlowThread::isMarkedForDestruction() const
-{
- // Flow threads in the "NULL" state can be destroyed.
- return m_namedFlow->flowState() == NamedFlow::FlowStateNull;
-}
-
-static bool isContainedInNodes(Vector<Node*> others, Node* node)
-{
- for (size_t i = 0; i < others.size(); i++) {
- Node* other = others.at(i);
- if (other->contains(node))
- return true;
- }
- return false;
-}
-
-static bool boxIntersectsRegion(LayoutUnit logicalTopForBox, LayoutUnit logicalBottomForBox, LayoutUnit logicalTopForRegion, LayoutUnit logicalBottomForRegion)
-{
- bool regionIsEmpty = logicalBottomForRegion != LayoutUnit::max() && logicalTopForRegion != LayoutUnit::min()
- && (logicalBottomForRegion - logicalTopForRegion) <= 0;
- return (logicalBottomForBox - logicalTopForBox) > 0
- && !regionIsEmpty
- && logicalTopForBox < logicalBottomForRegion && logicalTopForRegion < logicalBottomForBox;
-}
-
-// Retrieve the next node to be visited while computing the ranges inside a region.
-static Node* nextNodeInsideContentNode(const Node& currNode, const Node* contentNode)
-{
- ASSERT(contentNode && contentNode->inNamedFlow());
-
- if (currNode.renderer() && currNode.renderer()->isSVGRoot())
- return NodeTraversal::nextSkippingChildren(currNode, contentNode);
- return NodeTraversal::next(currNode, contentNode);
-}
-
-void RenderNamedFlowThread::getRanges(Vector<RefPtr<Range> >& rangeObjects, const RenderRegion* region) const
-{
- LayoutUnit logicalTopForRegion;
- LayoutUnit logicalBottomForRegion;
-
- // extend the first region top to contain everything up to its logical height
- if (region->isFirstRegion())
- logicalTopForRegion = LayoutUnit::min();
- else
- logicalTopForRegion = region->logicalTopForFlowThreadContent();
-
- // extend the last region to contain everything above its y()
- if (region->isLastRegion())
- logicalBottomForRegion = LayoutUnit::max();
- else
- logicalBottomForRegion = region->logicalBottomForFlowThreadContent();
-
- Vector<Node*> nodes;
- // eliminate the contentNodes that are descendants of other contentNodes
- for (NamedFlowContentNodes::const_iterator it = contentNodes().begin(); it != contentNodes().end(); ++it) {
- Node* node = *it;
- if (!isContainedInNodes(nodes, node))
- nodes.append(node);
- }
-
- for (size_t i = 0; i < nodes.size(); i++) {
- Node* contentNode = nodes.at(i);
- if (!contentNode->renderer())
- continue;
-
- RefPtr<Range> range = Range::create(contentNode->document());
- bool foundStartPosition = false;
- bool startsAboveRegion = true;
- bool endsBelowRegion = true;
- bool skipOverOutsideNodes = false;
- Node* lastEndNode = 0;
-
- for (Node* node = contentNode; node; node = nextNodeInsideContentNode(*node, contentNode)) {
- RenderObject* renderer = node->renderer();
- if (!renderer)
- continue;
-
- LayoutRect boundingBox;
- if (renderer->isRenderInline()) {
- boundingBox = toRenderInline(renderer)->linesBoundingBox();
- } else if (renderer->isText()) {
- boundingBox = toRenderText(renderer)->linesBoundingBox();
- } else {
- boundingBox = toRenderBox(renderer)->frameRect();
- if (toRenderBox(renderer)->isRelPositioned())
- boundingBox.move(toRenderBox(renderer)->relativePositionLogicalOffset());
- }
-
- LayoutUnit offsetTop = renderer->containingBlock()->offsetFromLogicalTopOfFirstPage();
- const LayoutPoint logicalOffsetFromTop(isHorizontalWritingMode() ? LayoutUnit() : offsetTop,
- isHorizontalWritingMode() ? offsetTop : LayoutUnit());
-
- boundingBox.moveBy(logicalOffsetFromTop);
-
- LayoutUnit logicalTopForRenderer = region->logicalTopOfFlowThreadContentRect(boundingBox);
- LayoutUnit logicalBottomForRenderer = region->logicalBottomOfFlowThreadContentRect(boundingBox);
-
- // if the bounding box of the current element doesn't intersect the region box
- // close the current range only if the start element began inside the region,
- // otherwise just move the start position after this node and keep skipping them until we found a proper start position.
- if (!boxIntersectsRegion(logicalTopForRenderer, logicalBottomForRenderer, logicalTopForRegion, logicalBottomForRegion)) {
- if (foundStartPosition) {
- if (!startsAboveRegion) {
- if (range->intersectsNode(node, IGNORE_EXCEPTION))
- range->setEndBefore(node, IGNORE_EXCEPTION);
- rangeObjects.append(range->cloneRange(IGNORE_EXCEPTION));
- range = Range::create(contentNode->document());
- startsAboveRegion = true;
- } else {
- skipOverOutsideNodes = true;
- }
- }
- if (skipOverOutsideNodes)
- range->setStartAfter(node, IGNORE_EXCEPTION);
- foundStartPosition = false;
- continue;
- }
-
- // start position
- if (logicalTopForRenderer < logicalTopForRegion && startsAboveRegion) {
- if (renderer->isText()) { // Text crosses region top
- // for Text elements, just find the last textbox that is contained inside the region and use its start() offset as start position
- RenderText* textRenderer = toRenderText(renderer);
- for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (offsetTop + box->logicalBottom() < logicalTopForRegion)
- continue;
- range->setStart(Position(toText(node), box->start()));
- startsAboveRegion = false;
- break;
- }
- } else { // node crosses region top
- // for all elements, except Text, just set the start position to be before their children
- startsAboveRegion = true;
- range->setStart(Position(node, Position::PositionIsBeforeChildren));
- }
- } else { // node starts inside region
- // for elements that start inside the region, set the start position to be before them. If we found one, we will just skip the others until
- // the range is closed.
- if (startsAboveRegion) {
- startsAboveRegion = false;
- range->setStartBefore(node, IGNORE_EXCEPTION);
- }
- }
- skipOverOutsideNodes = false;
- foundStartPosition = true;
-
- // end position
- if (logicalBottomForRegion < logicalBottomForRenderer && (endsBelowRegion || (!endsBelowRegion && !node->isDescendantOf(lastEndNode)))) {
- // for Text elements, just find just find the last textbox that is contained inside the region and use its start()+len() offset as end position
- if (renderer->isText()) { // Text crosses region bottom
- RenderText* textRenderer = toRenderText(renderer);
- InlineTextBox* lastBox = 0;
- for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if ((offsetTop + box->logicalTop()) < logicalBottomForRegion) {
- lastBox = box;
- continue;
- }
- ASSERT(lastBox);
- if (lastBox)
- range->setEnd(Position(toText(node), lastBox->start() + lastBox->len()));
- break;
- }
- endsBelowRegion = false;
- lastEndNode = node;
- } else { // node crosses region bottom
- // for all elements, except Text, just set the start position to be after their children
- range->setEnd(Position(node, Position::PositionIsAfterChildren));
- endsBelowRegion = true;
- lastEndNode = node;
- }
- } else { // node ends inside region
- // for elements that ends inside the region, set the end position to be after them
- // allow this end position to be changed only by other elements that are not descendants of the current end node
- if (endsBelowRegion || (!endsBelowRegion && !node->isDescendantOf(lastEndNode))) {
- range->setEndAfter(node, IGNORE_EXCEPTION);
- endsBelowRegion = false;
- lastEndNode = node;
- }
- }
- }
- if (foundStartPosition || skipOverOutsideNodes)
- rangeObjects.append(range);
- }
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowThread.h b/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowThread.h
deleted file mode 100644
index 6528c1106c5..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderNamedFlowThread.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef RenderNamedFlowThread_h
-#define RenderNamedFlowThread_h
-
-#include "core/rendering/RenderFlowThread.h"
-#include "platform/Timer.h"
-#include "wtf/HashCountedSet.h"
-#include "wtf/ListHashSet.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-class NamedFlow;
-class Node;
-class RenderNamedFlowThread;
-
-typedef ListHashSet<RenderNamedFlowThread*> RenderNamedFlowThreadList;
-typedef HashCountedSet<RenderNamedFlowThread*> RenderNamedFlowThreadCountedSet;
-typedef ListHashSet<Node*> NamedFlowContentNodes;
-
-class RenderNamedFlowThread FINAL : public RenderFlowThread {
-public:
- virtual ~RenderNamedFlowThread();
-
- static RenderNamedFlowThread* createAnonymous(Document*, PassRefPtr<NamedFlow>);
-
- const AtomicString& flowThreadName() const;
-
- const RenderRegionList& invalidRenderRegionList() const { return m_invalidRegionList; }
-
- RenderObject* nextRendererForNode(Node*) const;
- RenderObject* previousRendererForNode(Node*) const;
-
- void addFlowChild(RenderObject* newChild);
- void removeFlowChild(RenderObject*);
- bool hasChildren() const { return !m_flowThreadChildList.isEmpty(); }
-#ifndef NDEBUG
- bool hasChild(RenderObject* child) const { return m_flowThreadChildList.contains(child); }
-#endif
-
- void pushDependencies(RenderNamedFlowThreadList&);
-
- virtual void addRegionToThread(RenderRegion*) OVERRIDE;
- virtual void removeRegionFromThread(RenderRegion*) OVERRIDE;
-
- virtual void regionChangedWritingMode(RenderRegion*) OVERRIDE;
-
- bool overset() const { return m_overset; }
- void computeOversetStateForRegions(LayoutUnit oldClientAfterEdge);
-
- void registerNamedFlowContentNode(Node*);
- void unregisterNamedFlowContentNode(Node*);
- const NamedFlowContentNodes& contentNodes() const { return m_contentNodes; }
- bool hasContentNode(Node* contentNode) const { ASSERT(contentNode); return m_contentNodes.contains(contentNode); }
- bool isMarkedForDestruction() const;
- void getRanges(Vector<RefPtr<Range> >&, const RenderRegion*) const;
-
-protected:
- void setMarkForDestruction();
- void resetMarkForDestruction();
-
-private:
- RenderNamedFlowThread(PassRefPtr<NamedFlow>);
-
- virtual const char* renderName() const OVERRIDE;
- virtual bool isRenderNamedFlowThread() const OVERRIDE { return true; }
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
-
- virtual void dispatchRegionLayoutUpdateEvent() OVERRIDE;
- virtual void dispatchRegionOversetChangeEvent() OVERRIDE;
-
- bool dependsOn(RenderNamedFlowThread* otherRenderFlowThread) const;
- void addDependencyOnFlowThread(RenderNamedFlowThread*);
- void removeDependencyOnFlowThread(RenderNamedFlowThread*);
-
- void addRegionToNamedFlowThread(RenderRegion*);
-
- void checkInvalidRegions();
-
- bool canBeDestroyed() const { return m_invalidRegionList.isEmpty() && m_regionList.isEmpty() && m_contentNodes.isEmpty(); }
- void regionLayoutUpdateEventTimerFired(Timer<RenderNamedFlowThread>*);
- void regionOversetChangeEventTimerFired(Timer<RenderNamedFlowThread>*);
- void clearContentNodes();
- void updateWritingMode();
-
-private:
- // Observer flow threads have invalid regions that depend on the state of this thread
- // to re-validate their regions. Keeping a set of observer threads make it easy
- // to notify them when a region was removed from this flow.
- RenderNamedFlowThreadCountedSet m_observerThreadsSet;
-
- // Some threads need to have a complete layout before we layout this flow.
- // That's because they contain a RenderRegion that should display this thread. The set makes it
- // easy to sort the order of threads layout.
- RenderNamedFlowThreadCountedSet m_layoutBeforeThreadsSet;
-
- // Holds the sorted children of a named flow. This is the only way we can get the ordering right.
- typedef ListHashSet<RenderObject*> FlowThreadChildList;
- FlowThreadChildList m_flowThreadChildList;
-
- NamedFlowContentNodes m_contentNodes;
-
- RenderRegionList m_invalidRegionList;
-
- bool m_overset : 1;
-
- // The DOM Object that represents a named flow.
- RefPtr<NamedFlow> m_namedFlow;
-
- Timer<RenderNamedFlowThread> m_regionLayoutUpdateEventTimer;
- Timer<RenderNamedFlowThread> m_regionOversetChangeEventTimer;
-};
-
-DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderNamedFlowThread, isRenderNamedFlowThread());
-
-} // namespace WebCore
-
-#endif // RenderNamedFlowThread_h
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderObject.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderObject.cpp
index 1192be3d768..90af71bf364 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderObject.cpp
@@ -27,48 +27,43 @@
#include "config.h"
#include "core/rendering/RenderObject.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/HTMLNames.h"
#include "core/accessibility/AXObjectCache.h"
#include "core/animation/ActiveAnimations.h"
#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/EditingBoundary.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/htmlediting.h"
+#include "core/fetch/ResourceLoadPriorityOptimizer.h"
#include "core/fetch/ResourceLoader.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLElement.h"
#include "core/html/HTMLHtmlElement.h"
+#include "core/html/HTMLTableCellElement.h"
#include "core/html/HTMLTableElement.h"
#include "core/page/AutoscrollController.h"
#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/frame/UseCounter.h"
-#include "core/frame/animation/AnimationController.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderCounter.h"
#include "core/rendering/RenderDeprecatedFlexibleBox.h"
#include "core/rendering/RenderFlexibleBox.h"
+#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderGrid.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderImageResourceStyleImage.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderListItem.h"
#include "core/rendering/RenderMarquee.h"
-#include "core/rendering/RenderMultiColumnBlock.h"
-#include "core/rendering/RenderNamedFlowThread.h"
-#include "core/rendering/RenderRegion.h"
-#include "core/rendering/RenderRuby.h"
-#include "core/rendering/RenderRubyText.h"
#include "core/rendering/RenderScrollbarPart.h"
#include "core/rendering/RenderTableCaption.h"
#include "core/rendering/RenderTableCell.h"
@@ -76,15 +71,20 @@
#include "core/rendering/RenderTableRow.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/rendering/style/ContentData.h"
-#include "core/rendering/style/CursorList.h"
#include "core/rendering/style/ShadowList.h"
-#include "core/rendering/svg/SVGRenderSupport.h"
+#include "platform/JSONValues.h"
#include "platform/Partitions.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/TraceEvent.h"
+#include "platform/TracedValue.h"
#include "platform/geometry/TransformState.h"
#include "platform/graphics/GraphicsContext.h"
#include "wtf/RefCountedLeakCounter.h"
#include "wtf/text/StringBuilder.h"
+#include "wtf/text/WTFString.h"
#include <algorithm>
#ifndef NDEBUG
#include <stdio.h>
@@ -94,20 +94,26 @@ using namespace std;
namespace WebCore {
+namespace {
+
+static bool gModifyRenderTreeStructureAnyState = false;
+
+} // namespace
+
using namespace HTMLNames;
#ifndef NDEBUG
-RenderObject::SetLayoutNeededForbiddenScope::SetLayoutNeededForbiddenScope(RenderObject* renderObject)
+RenderObject::SetLayoutNeededForbiddenScope::SetLayoutNeededForbiddenScope(RenderObject& renderObject)
: m_renderObject(renderObject)
- , m_preexistingForbidden(m_renderObject->isSetNeedsLayoutForbidden())
+ , m_preexistingForbidden(m_renderObject.isSetNeedsLayoutForbidden())
{
- m_renderObject->setNeedsLayoutIsForbidden(true);
+ m_renderObject.setNeedsLayoutIsForbidden(true);
}
RenderObject::SetLayoutNeededForbiddenScope::~SetLayoutNeededForbiddenScope()
{
- m_renderObject->setNeedsLayoutIsForbidden(m_preexistingForbidden);
+ m_renderObject.setNeedsLayoutIsForbidden(m_preexistingForbidden);
}
#endif
@@ -119,7 +125,8 @@ struct SameSizeAsRenderObject {
#endif
unsigned m_bitfields;
unsigned m_bitfields2;
- LayoutRect rects[2]; // Stores the old/new repaint rects.
+ LayoutRect rect; // Stores the previous paint invalidation rect.
+ LayoutPoint position; // Stores the previous position from the paint invalidation container.
};
COMPILE_ASSERT(sizeof(RenderObject) == sizeof(SameSizeAsRenderObject), RenderObject_should_stay_small);
@@ -140,7 +147,7 @@ void RenderObject::operator delete(void* ptr)
RenderObject* RenderObject::createObject(Element* element, RenderStyle* style)
{
- Document& doc = element->document();
+ ASSERT(isAllowedToModifyRenderTreeStructure(element->document()));
// Minimal support for content properties replacing an entire element.
// Works only if we have exactly one piece of content and it's a URL.
@@ -157,20 +164,10 @@ RenderObject* RenderObject::createObject(Element* element, RenderStyle* style)
image->setIsGeneratedContent();
} else
image->setImageResource(RenderImageResource::create());
- image->setStyleInternal(0);
+ image->setStyleInternal(nullptr);
return image;
}
- if (element->hasTagName(rubyTag)) {
- if (style->display() == INLINE)
- return new RenderRubyAsInline(element);
- else if (style->display() == BLOCK)
- return new RenderRubyAsBlock(element);
- }
- // treat <rt> as ruby text ONLY if it still has its default treatment of block
- if (element->hasTagName(rtTag) && style->display() == BLOCK)
- return new RenderRubyText(element);
-
switch (style->display()) {
case NONE:
return 0;
@@ -178,8 +175,6 @@ RenderObject* RenderObject::createObject(Element* element, RenderStyle* style)
return new RenderInline(element);
case BLOCK:
case INLINE_BLOCK:
- if ((!style->hasAutoColumnCount() || !style->hasAutoColumnWidth()) && doc.regionBasedColumnsEnabled())
- return new RenderMultiColumnBlock(element);
return new RenderBlockFlow(element);
case LIST_ITEM:
return new RenderListItem(element);
@@ -217,7 +212,7 @@ DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, renderObjectCounter, ("Rend
RenderObject::RenderObject(Node* node)
: ImageResourceClient()
- , m_style(0)
+ , m_style(nullptr)
, m_node(node)
, m_parent(0)
, m_previous(0)
@@ -235,6 +230,7 @@ RenderObject::RenderObject(Node* node)
RenderObject::~RenderObject()
{
+ ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->removeRenderObject(this);
#ifndef NDEBUG
ASSERT(!m_hasAXObject);
renderObjectCounter.decrement();
@@ -263,31 +259,24 @@ bool RenderObject::isDescendantOf(const RenderObject* obj) const
return false;
}
-bool RenderObject::isBody() const
-{
- return node() && node()->hasTagName(bodyTag);
-}
-
bool RenderObject::isHR() const
{
- return node() && node()->hasTagName(hrTag);
+ return isHTMLHRElement(node());
}
bool RenderObject::isLegend() const
{
- return node() && node()->hasTagName(legendTag);
+ return isHTMLLegendElement(node());
}
void RenderObject::setFlowThreadStateIncludingDescendants(FlowThreadState state)
{
- setFlowThreadState(state);
-
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- // If the child is a fragmentation context it already updated the descendants flag accordingly.
- if (child->isRenderFlowThread())
+ for (RenderObject *object = this; object; object = object->nextInPreOrder(this)) {
+ // If object is a fragmentation context it already updated the descendants flag accordingly.
+ if (object->isRenderFlowThread())
continue;
- ASSERT(state != child->flowThreadState());
- child->setFlowThreadStateIncludingDescendants(state);
+ ASSERT(state != object->flowThreadState());
+ object->setFlowThreadState(state);
}
}
@@ -313,6 +302,8 @@ bool RenderObject::requiresAnonymousTableWrappers(const RenderObject* newChild)
void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
{
+ ASSERT(isAllowedToModifyRenderTreeStructure(document()));
+
RenderObjectChildList* children = virtualChildren();
ASSERT(children);
if (!children)
@@ -340,7 +331,7 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
// SVG creates renderers for <g display="none">, as SVG requires children of hidden
// <g>s to have renderers - at least that's how our implementation works. Consider:
// <g display="none"><foreignObject><body style="position: relative">FOO...
- // - requiresLayer() would return true for the <body>, creating a new RenderLayer
+ // - layerTypeRequired() would return true for the <body>, creating a new RenderLayer
// - when the document is painted, both layers are painted. The <body> layer doesn't
// know that it's inside a "hidden SVG subtree", and thus paints, even if it shouldn't.
// To avoid the problem alltogether, detect early if we're inside a hidden SVG subtree
@@ -351,6 +342,8 @@ void RenderObject::addChild(RenderObject* newChild, RenderObject* beforeChild)
void RenderObject::removeChild(RenderObject* oldChild)
{
+ ASSERT(isAllowedToModifyRenderTreeStructure(document()));
+
RenderObjectChildList* children = virtualChildren();
ASSERT(children);
if (!children)
@@ -361,7 +354,7 @@ void RenderObject::removeChild(RenderObject* oldChild)
RenderObject* RenderObject::nextInPreOrder() const
{
- if (RenderObject* o = firstChild())
+ if (RenderObject* o = slowFirstChild())
return o;
return nextInPreOrderAfterChildren();
@@ -383,7 +376,7 @@ RenderObject* RenderObject::nextInPreOrderAfterChildren() const
RenderObject* RenderObject::nextInPreOrder(const RenderObject* stayWithin) const
{
- if (RenderObject* o = firstChild())
+ if (RenderObject* o = slowFirstChild())
return o;
return nextInPreOrderAfterChildren(stayWithin);
@@ -407,8 +400,8 @@ RenderObject* RenderObject::nextInPreOrderAfterChildren(const RenderObject* stay
RenderObject* RenderObject::previousInPreOrder() const
{
if (RenderObject* o = previousSibling()) {
- while (o->lastChild())
- o = o->lastChild();
+ while (RenderObject* lastChild = o->slowLastChild())
+ o = lastChild;
return o;
}
@@ -425,7 +418,7 @@ RenderObject* RenderObject::previousInPreOrder(const RenderObject* stayWithin) c
RenderObject* RenderObject::childAt(unsigned index) const
{
- RenderObject* child = firstChild();
+ RenderObject* child = slowFirstChild();
for (unsigned i = 0; child && i < index; i++)
child = child->nextSibling();
return child;
@@ -433,10 +426,10 @@ RenderObject* RenderObject::childAt(unsigned index) const
RenderObject* RenderObject::lastLeafChild() const
{
- RenderObject* r = lastChild();
+ RenderObject* r = slowLastChild();
while (r) {
RenderObject* n = 0;
- n = r->lastChild();
+ n = r->slowLastChild();
if (!n)
break;
r = n;
@@ -459,7 +452,7 @@ static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject*
return;
}
- for (RenderObject* curr = obj->firstChild(); curr; curr = curr->nextSibling())
+ for (RenderObject* curr = obj->slowFirstChild(); curr; curr = curr->nextSibling())
addLayers(curr, parentLayer, newObject, beforeChild);
}
@@ -483,7 +476,7 @@ void RenderObject::removeLayers(RenderLayer* parentLayer)
return;
}
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
+ for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling())
curr->removeLayers(parentLayer);
}
@@ -501,7 +494,7 @@ void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
return;
}
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
+ for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling())
curr->moveLayers(oldParent, newParent);
}
@@ -520,7 +513,7 @@ RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject*
// Step 2: If we don't have a layer, or our layer is the desired parent, then descend
// into our siblings trying to find the next layer whose parent is the desired parent.
if (!ourLayer || ourLayer == parentLayer) {
- for (RenderObject* curr = startPoint ? startPoint->nextSibling() : firstChild();
+ for (RenderObject* curr = startPoint ? startPoint->nextSibling() : slowFirstChild();
curr; curr = curr->nextSibling()) {
RenderLayer* nextLayer = curr->findNextLayer(parentLayer, 0, false);
if (nextLayer)
@@ -543,13 +536,13 @@ RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject*
RenderLayer* RenderObject::enclosingLayer() const
{
- const RenderObject* curr = this;
- while (curr) {
- RenderLayer* layer = curr->hasLayer() ? toRenderLayerModelObject(curr)->layer() : 0;
- if (layer)
- return layer;
- curr = curr->parent();
+ for (const RenderObject* current = this; current; current = current->parent()) {
+ if (current->hasLayer())
+ return toRenderLayerModelObject(current)->layer();
}
+ // FIXME: We should remove the one caller that triggers this case and make
+ // this function return a reference.
+ ASSERT(!m_parent && !isRenderView());
return 0;
}
@@ -622,15 +615,6 @@ RenderFlowThread* RenderObject::locateFlowThreadContainingBlock() const
return 0;
}
-RenderNamedFlowThread* RenderObject::renderNamedFlowThreadWrapper() const
-{
- RenderObject* object = const_cast<RenderObject*>(this);
- while (object && object->isAnonymousBlock() && !object->isRenderNamedFlowThread())
- object = object->parent();
-
- return object && object->isRenderNamedFlowThread() ? toRenderNamedFlowThread(object) : 0;
-}
-
RenderBlock* RenderObject::firstLineBlock() const
{
return 0;
@@ -729,19 +713,12 @@ void RenderObject::checkBlockPositionedObjectsNeedLayout()
if (isRenderBlock())
toRenderBlock(this)->checkPositionedObjectsNeedLayout();
}
-
-void RenderObject::checkNotInPartialLayout()
-{
- // During partial layout, setNeedsLayout(true or false) should not be called.
- ASSERT(!frameView()->partialLayout().isStopping());
-}
#endif
void RenderObject::setPreferredLogicalWidthsDirty(MarkingBehavior markParents)
{
- bool alreadyDirty = preferredLogicalWidthsDirty();
m_bitfields.setPreferredLogicalWidthsDirty(true);
- if (!alreadyDirty && markParents == MarkContainingBlockChain && (isText() || !style()->hasOutOfFlowPosition()))
+ if (markParents == MarkContainingBlockChain && (isText() || !style()->hasOutOfFlowPosition()))
invalidateContainerPreferredLogicalWidths();
}
@@ -771,28 +748,22 @@ void RenderObject::invalidateContainerPreferredLogicalWidths()
}
}
-void RenderObject::setLayerNeedsFullRepaint()
-{
- ASSERT(hasLayer());
- toRenderLayerModelObject(this)->layer()->repainter().setRepaintStatus(NeedsFullRepaint);
-}
-
-void RenderObject::setLayerNeedsFullRepaintForPositionedMovementLayout()
+void RenderObject::setLayerNeedsFullPaintInvalidationForPositionedMovementLayout()
{
ASSERT(hasLayer());
toRenderLayerModelObject(this)->layer()->repainter().setRepaintStatus(NeedsFullRepaintForPositionedMovementLayout);
}
-RenderBlock* RenderObject::containerForFixedPosition(const RenderLayerModelObject* repaintContainer, bool* repaintContainerSkipped) const
+RenderBlock* RenderObject::containerForFixedPosition(const RenderLayerModelObject* paintInvalidationContainer, bool* paintInvalidationContainerSkipped) const
{
- ASSERT(!repaintContainerSkipped || !*repaintContainerSkipped);
+ ASSERT(!paintInvalidationContainerSkipped || !*paintInvalidationContainerSkipped);
ASSERT(!isText());
ASSERT(style()->position() == FixedPosition);
RenderObject* ancestor = parent();
for (; ancestor && !ancestor->canContainFixedPositionObjects(); ancestor = ancestor->parent()) {
- if (repaintContainerSkipped && ancestor == repaintContainer)
- *repaintContainerSkipped = true;
+ if (paintInvalidationContainerSkipped && ancestor == paintInvalidationContainer)
+ *paintInvalidationContainerSkipped = true;
}
ASSERT(!ancestor || !ancestor->isAnonymousBlock());
@@ -816,7 +787,7 @@ RenderBlock* RenderObject::containingBlock() const
if (o->style()->position() != StaticPosition && (!o->isInline() || o->isReplaced()))
break;
- if (o->canContainAbsolutePositionObjects())
+ if (o->canContainFixedPositionObjects())
break;
if (o->style()->hasInFlowPosition() && o->isInline() && !o->isReplaced()) {
@@ -827,6 +798,9 @@ RenderBlock* RenderObject::containingBlock() const
o = o->parent();
}
+ if (o && !o->isRenderBlock())
+ o = o->containingBlock();
+
while (o && o->isAnonymousBlock())
o = o->containingBlock();
} else {
@@ -840,29 +814,66 @@ RenderBlock* RenderObject::containingBlock() const
return toRenderBlock(o);
}
-static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* layer)
+RenderObject* RenderObject::clippingContainer() const
+{
+ RenderObject* container = const_cast<RenderObject*>(this);
+ while (container) {
+ if (container->style()->position() == FixedPosition) {
+ for (container = container->parent(); container && !container->canContainFixedPositionObjects(); container = container->parent()) {
+ // CSS clip applies to fixed position elements even for ancestors that are not what the
+ // fixed element is positioned with respect to.
+ if (container->hasClip())
+ return container;
+ }
+ } else {
+ container = container->containingBlock();
+ }
+
+ if (!container)
+ return 0;
+ if (container->hasClipOrOverflowClip())
+ return container;
+ }
+ return 0;
+}
+
+bool RenderObject::canRenderBorderImage() const
+{
+ ASSERT(style()->hasBorder());
+
+ StyleImage* borderImage = style()->borderImage().image();
+ return borderImage && borderImage->canRender(*this, style()->effectiveZoom()) && borderImage->isLoaded();
+}
+
+bool RenderObject::mustInvalidateFillLayersPaintOnWidthChange(const FillLayer& layer) const
{
// Nobody will use multiple layers without wanting fancy positioning.
- if (layer->next())
+ if (layer.next())
return true;
// Make sure we have a valid image.
- StyleImage* img = layer->image();
- if (!img || !img->canRender(renderer, renderer->style()->effectiveZoom()))
+ StyleImage* img = layer.image();
+ if (!img || !img->canRender(*this, style()->effectiveZoom()))
return false;
- if (!layer->xPosition().isZero() || !layer->yPosition().isZero())
+ if (layer.repeatX() != RepeatFill && layer.repeatX() != NoRepeatFill)
return true;
- EFillSizeType sizeType = layer->sizeType();
+ if (layer.xPosition().isPercent() && !layer.xPosition().isZero())
+ return true;
+
+ if (layer.backgroundXOrigin() != LeftEdge)
+ return true;
+
+ EFillSizeType sizeType = layer.sizeType();
if (sizeType == Contain || sizeType == Cover)
return true;
if (sizeType == SizeLength) {
- if (layer->sizeLength().width().isPercent() || layer->sizeLength().height().isPercent())
+ if (layer.sizeLength().width().isPercent() && !layer.sizeLength().width().isZero())
return true;
- if (img->isGeneratedImage() && (layer->sizeLength().width().isAuto() || layer->sizeLength().height().isAuto()))
+ if (img->isGeneratedImage() && layer.sizeLength().width().isAuto())
return true;
} else if (img->usesImageContainerSize()) {
return true;
@@ -871,28 +882,76 @@ static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer*
return false;
}
-bool RenderObject::borderImageIsLoadedAndCanBeRendered() const
+bool RenderObject::mustInvalidateFillLayersPaintOnHeightChange(const FillLayer& layer) const
{
- ASSERT(style()->hasBorder());
+ // Nobody will use multiple layers without wanting fancy positioning.
+ if (layer.next())
+ return true;
- StyleImage* borderImage = style()->borderImage().image();
- return borderImage && borderImage->canRender(this, style()->effectiveZoom()) && borderImage->isLoaded();
+ // Make sure we have a valid image.
+ StyleImage* img = layer.image();
+ if (!img || !img->canRender(*this, style()->effectiveZoom()))
+ return false;
+
+ if (layer.repeatY() != RepeatFill && layer.repeatY() != NoRepeatFill)
+ return true;
+
+ if (layer.yPosition().isPercent() && !layer.yPosition().isZero())
+ return true;
+
+ if (layer.backgroundYOrigin() != TopEdge)
+ return true;
+
+ EFillSizeType sizeType = layer.sizeType();
+
+ if (sizeType == Contain || sizeType == Cover)
+ return true;
+
+ if (sizeType == SizeLength) {
+ if (layer.sizeLength().height().isPercent() && !layer.sizeLength().height().isZero())
+ return true;
+ if (img->isGeneratedImage() && layer.sizeLength().height().isAuto())
+ return true;
+ } else if (img->usesImageContainerSize()) {
+ return true;
+ }
+
+ return false;
}
-bool RenderObject::mustRepaintBackgroundOrBorder() const
+bool RenderObject::mustInvalidateBackgroundOrBorderPaintOnWidthChange() const
{
- if (hasMask() && mustRepaintFillLayers(this, style()->maskLayers()))
+ if (hasMask() && mustInvalidateFillLayersPaintOnWidthChange(*style()->maskLayers()))
return true;
// If we don't have a background/border/mask, then nothing to do.
if (!hasBoxDecorations())
return false;
- if (mustRepaintFillLayers(this, style()->backgroundLayers()))
+ if (mustInvalidateFillLayersPaintOnWidthChange(*style()->backgroundLayers()))
+ return true;
+
+ // Our fill layers are ok. Let's check border.
+ if (style()->hasBorder() && canRenderBorderImage())
+ return true;
+
+ return false;
+}
+
+bool RenderObject::mustInvalidateBackgroundOrBorderPaintOnHeightChange() const
+{
+ if (hasMask() && mustInvalidateFillLayersPaintOnHeightChange(*style()->maskLayers()))
+ return true;
+
+ // If we don't have a background/border/mask, then nothing to do.
+ if (!hasBoxDecorations())
+ return false;
+
+ if (mustInvalidateFillLayersPaintOnHeightChange(*style()->backgroundLayers()))
return true;
// Our fill layers are ok. Let's check border.
- if (style()->hasBorder() && borderImageIsLoadedAndCanBeRendered())
+ if (style()->hasBorder() && canRenderBorderImage())
return true;
return false;
@@ -1250,22 +1309,62 @@ void RenderObject::paintOutline(PaintInfo& paintInfo, const LayoutRect& paintRec
graphicsContext->endLayer();
}
-IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
+void RenderObject::addChildFocusRingRects(Vector<IntRect>& rects, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer)
{
- if (useTransforms) {
- Vector<FloatQuad> quads;
- absoluteQuads(quads);
-
- size_t n = quads.size();
- if (!n)
- return IntRect();
+ for (RenderObject* current = slowFirstChild(); current; current = current->nextSibling()) {
+ if (current->isText() || current->isListMarker())
+ continue;
- IntRect result = quads[0].enclosingBoundingBox();
- for (size_t i = 1; i < n; ++i)
- result.unite(quads[i].enclosingBoundingBox());
- return result;
+ if (current->isBox()) {
+ RenderBox* box = toRenderBox(current);
+ if (box->hasLayer()) {
+ Vector<IntRect> layerFocusRingRects;
+ box->addFocusRingRects(layerFocusRingRects, LayoutPoint(), box);
+ for (size_t i = 0; i < layerFocusRingRects.size(); ++i) {
+ FloatQuad quadInBox = box->localToContainerQuad(FloatRect(layerFocusRingRects[i]), paintContainer);
+ rects.append(pixelSnappedIntRect(LayoutRect(quadInBox.boundingBox())));
+ }
+ } else {
+ FloatPoint pos(additionalOffset);
+ pos.move(box->locationOffset()); // FIXME: Snap offsets? crbug.com/350474
+ box->addFocusRingRects(rects, flooredIntPoint(pos), paintContainer);
+ }
+ } else {
+ current->addFocusRingRects(rects, additionalOffset, paintContainer);
+ }
}
+}
+
+// FIXME: In repaint-after-layout, we should be able to change the logic to remove the need for this function. See crbug.com/368416.
+LayoutPoint RenderObject::positionFromPaintInvalidationContainer(const RenderLayerModelObject* paintInvalidationContainer) const
+{
+ // FIXME: This assert should be re-enabled when we move paint invalidation to after compositing update. crbug.com/360286
+ // ASSERT(containerForPaintInvalidation() == paintInvalidationContainer);
+
+ LayoutPoint offset = isBox() ? toRenderBox(this)->location() : LayoutPoint();
+ if (paintInvalidationContainer == this)
+ return offset;
+
+ return roundedIntPoint(localToContainerPoint(offset, paintInvalidationContainer));
+}
+
+IntRect RenderObject::absoluteBoundingBoxRect() const
+{
+ Vector<FloatQuad> quads;
+ absoluteQuads(quads);
+ size_t n = quads.size();
+ if (!n)
+ return IntRect();
+
+ IntRect result = quads[0].enclosingBoundingBox();
+ for (size_t i = 1; i < n; ++i)
+ result.unite(quads[i].enclosingBoundingBox());
+ return result;
+}
+
+IntRect RenderObject::absoluteBoundingBoxRectIgnoringTransforms() const
+{
FloatPoint absPos = localToAbsolute();
Vector<IntRect> rects;
absoluteRects(rects, flooredLayoutPoint(absPos));
@@ -1283,18 +1382,11 @@ IntRect RenderObject::absoluteBoundingBoxRect(bool useTransforms) const
void RenderObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
{
Vector<IntRect> rects;
- // FIXME: addFocusRingRects() needs to be passed this transform-unaware
- // localToAbsolute() offset here because RenderInline::addFocusRingRects()
- // implicitly assumes that. This doesn't work correctly with transformed
- // descendants.
- FloatPoint absolutePoint = localToAbsolute();
- addFocusRingRects(rects, flooredLayoutPoint(absolutePoint));
+ const RenderLayerModelObject* container = containerForPaintInvalidation();
+ addFocusRingRects(rects, LayoutPoint(localToContainerPoint(FloatPoint(), container)), container);
size_t count = rects.size();
- for (size_t i = 0; i < count; ++i) {
- IntRect rect = rects[i];
- rect.move(-absolutePoint.x(), -absolutePoint.y());
- quads.append(localToAbsoluteQuad(FloatQuad(rect)));
- }
+ for (size_t i = 0; i < count; ++i)
+ quads.append(container->localToAbsoluteQuad(FloatQuad(rects[i])));
}
FloatRect RenderObject::absoluteBoundingBoxRectForRange(const Range* range)
@@ -1317,16 +1409,16 @@ FloatRect RenderObject::absoluteBoundingBoxRectForRange(const Range* range)
void RenderObject::addAbsoluteRectForLayer(LayoutRect& result)
{
if (hasLayer())
- result.unite(absoluteBoundingBoxRectIgnoringTransforms());
- for (RenderObject* current = firstChild(); current; current = current->nextSibling())
+ result.unite(absoluteBoundingBoxRect());
+ for (RenderObject* current = slowFirstChild(); current; current = current->nextSibling())
current->addAbsoluteRectForLayer(result);
}
LayoutRect RenderObject::paintingRootRect(LayoutRect& topLevelRect)
{
- LayoutRect result = absoluteBoundingBoxRectIgnoringTransforms();
+ LayoutRect result = absoluteBoundingBoxRect();
topLevelRect = result;
- for (RenderObject* current = firstChild(); current; current = current->nextSibling())
+ for (RenderObject* current = slowFirstChild(); current; current = current->nextSibling())
current->addAbsoluteRectForLayer(result);
return result;
}
@@ -1335,145 +1427,157 @@ void RenderObject::paint(PaintInfo&, const LayoutPoint&)
{
}
-RenderLayerModelObject* RenderObject::containerForRepaint() const
+const RenderLayerModelObject* RenderObject::containerForPaintInvalidation() const
{
- RenderView* v = view();
- if (!v)
+ if (!isRooted())
return 0;
- RenderLayerModelObject* repaintContainer = 0;
+ return adjustCompositedContainerForSpecialAncestors(enclosingCompositedContainer());
+}
- if (v->usesCompositing()) {
- if (RenderLayer* parentLayer = enclosingLayer()) {
- RenderLayer* compLayer = parentLayer->enclosingCompositingLayerForRepaint();
- if (compLayer)
- repaintContainer = compLayer->renderer();
- }
+const RenderLayerModelObject* RenderObject::enclosingCompositedContainer() const
+{
+ RenderLayerModelObject* container = 0;
+ if (view()->usesCompositing()) {
+ // FIXME: CompositingState is not necessarily up to date for many callers of this function.
+ DisableCompositingQueryAsserts disabler;
+
+ if (RenderLayer* compositingLayer = enclosingLayer()->enclosingCompositingLayerForRepaint())
+ container = compositingLayer->renderer();
}
+ return container;
+}
+
+const RenderLayerModelObject* RenderObject::adjustCompositedContainerForSpecialAncestors(const RenderLayerModelObject* paintInvalidationContainer) const
+{
if (document().view()->hasSoftwareFilters()) {
- if (RenderLayer* parentLayer = enclosingLayer()) {
- RenderLayer* enclosingFilterLayer = parentLayer->enclosingFilterLayer();
- if (enclosingFilterLayer)
- return enclosingFilterLayer->renderer();
- }
+ if (RenderLayer* enclosingFilterLayer = enclosingLayer()->enclosingFilterLayer())
+ return enclosingFilterLayer->renderer();
}
- // If we have a flow thread, then we need to do individual repaints within the RenderRegions instead.
- // Return the flow thread as a repaint container in order to create a chokepoint that allows us to change
- // repainting to do individual region repaints.
- RenderFlowThread* parentRenderFlowThread = flowThreadContainingBlock();
- if (parentRenderFlowThread) {
- // The ancestor document will do the reparenting when the repaint propagates further up.
- // We're just a seamless child document, and we don't need to do the hacking.
- if (parentRenderFlowThread->document() != document())
- return repaintContainer;
- // If we have already found a repaint container then we will repaint into that container only if it is part of the same
- // flow thread. Otherwise we will need to catch the repaint call and send it to the flow thread.
- RenderFlowThread* repaintContainerFlowThread = repaintContainer ? repaintContainer->flowThreadContainingBlock() : 0;
- if (!repaintContainerFlowThread || repaintContainerFlowThread != parentRenderFlowThread)
- repaintContainer = parentRenderFlowThread;
+ // If we have a flow thread, then we need to do individual paint invalidations within the RenderRegions instead.
+ // Return the flow thread as a paint invalidation container in order to create a chokepoint that allows us to change
+ // paint invalidation to do individual region paint invalidations.
+ if (RenderFlowThread* parentRenderFlowThread = flowThreadContainingBlock()) {
+ // If we have already found a paint invalidation container then we will invalidate paints in that container only if it is part of the same
+ // flow thread. Otherwise we will need to catch the paint invalidation call and send it to the flow thread.
+ if (!paintInvalidationContainer || paintInvalidationContainer->flowThreadContainingBlock() != parentRenderFlowThread)
+ paintInvalidationContainer = parentRenderFlowThread;
}
- return repaintContainer;
+ return paintInvalidationContainer ? paintInvalidationContainer : view();
}
-void RenderObject::repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const IntRect& r) const
+bool RenderObject::isPaintInvalidationContainer() const
{
- if (!repaintContainer) {
- view()->repaintViewRectangle(r);
- return;
- }
+ return hasLayer() && toRenderLayerModelObject(this)->layer()->isRepaintContainer();
+}
- if (repaintContainer->compositingState() == PaintsIntoGroupedBacking) {
- ASSERT(repaintContainer->groupedMapping());
+template<typename T> PassRefPtr<JSONValue> jsonObjectForRect(const T& rect)
+{
+ RefPtr<JSONObject> object = JSONObject::create();
+ object->setNumber("x", rect.x());
+ object->setNumber("y", rect.y());
+ object->setNumber("width", rect.width());
+ object->setNumber("height", rect.height());
+ return object.release();
+}
- // Not clean, but if squashing layer does not yet exist here (e.g. repaint invalidation coming from within recomputing compositing requirements)
- // then it's ok to just exit here, since the squashing layer will get repainted when it is newly created.
- if (!repaintContainer->groupedMapping()->squashingLayer())
- return;
+static PassRefPtr<JSONValue> jsonObjectForPaintInvalidationInfo(const IntRect& rect, const String& invalidationReason)
+{
+ RefPtr<JSONObject> object = JSONObject::create();
+ object->setValue("rect", jsonObjectForRect(rect));
+ object->setString("invalidation_reason", invalidationReason);
+ return object.release();
+}
+LayoutRect RenderObject::computePaintInvalidationRect(const RenderLayerModelObject* paintInvalidationContainer) const
+{
+ return clippedOverflowRectForPaintInvalidation(paintInvalidationContainer);
+}
- IntRect offsetRect(r);
+void RenderObject::invalidatePaintUsingContainer(const RenderLayerModelObject* paintInvalidationContainer, const IntRect& r, InvalidationReason invalidationReason) const
+{
+ if (r.isEmpty())
+ return;
- // First, convert the repaint rect into the space of the repaintContainer
- TransformState transformState(TransformState::ApplyTransformDirection, FloatQuad(FloatRect(r)));
- mapLocalToContainer(repaintContainer, transformState, ApplyContainerFlip);
- transformState.flatten();
- offsetRect = transformState.lastPlanarQuad().enclosingBoundingBox();
+ // FIXME: This should be an assert, but editing/selection can trigger this case to invalidate
+ // the selection. crbug.com/368140.
+ if (!isRooted())
+ return;
- // FIXME: the repaint rect computed below could be tighter in uncommon nested transform cases, if we passed the quad
- // directly to the next chunk of code.
+ TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "RenderObject::invalidatePaintUsingContainer()",
+ "object", this->debugName().ascii(),
+ "info", TracedValue::fromJSONValue(jsonObjectForPaintInvalidationInfo(r, invalidationReasonToString(invalidationReason))));
- // Then, convert the repaint rect from repaintConainer space into the squashing GraphicsLayer's coordinates.
- if (repaintContainer->hasTransform())
- offsetRect = repaintContainer->layer()->transform()->mapRect(r);
- offsetRect.move(-repaintContainer->layer()->offsetFromSquashingLayerOrigin());
- repaintContainer->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(offsetRect);
- return;
- }
+ // For querying RenderLayer::compositingState()
+ DisableCompositingQueryAsserts disabler;
- if (repaintContainer->isRenderFlowThread()) {
- toRenderFlowThread(repaintContainer)->repaintRectangleInRegions(r);
+ if (paintInvalidationContainer->isRenderFlowThread()) {
+ toRenderFlowThread(paintInvalidationContainer)->repaintRectangleInRegions(r);
return;
}
- if (repaintContainer->hasFilter() && repaintContainer->layer()->requiresFullLayerImageForFilters()) {
- repaintContainer->layer()->repainter().setFilterBackendNeedsRepaintingInRect(r);
+ if (paintInvalidationContainer->hasFilter() && paintInvalidationContainer->layer()->requiresFullLayerImageForFilters()) {
+ paintInvalidationContainer->layer()->repainter().setFilterBackendNeedsRepaintingInRect(r);
return;
}
RenderView* v = view();
- if (repaintContainer->isRenderView()) {
- ASSERT(repaintContainer == v);
- bool viewHasCompositedLayer = v->hasLayer() && v->layer()->compositingState() == PaintsIntoOwnBacking;
- if (!viewHasCompositedLayer) {
- IntRect repaintRectangle = r;
- if (viewHasCompositedLayer && v->layer()->transform())
- repaintRectangle = v->layer()->transform()->mapRect(r);
- v->repaintViewRectangle(repaintRectangle);
- return;
- }
+ if (paintInvalidationContainer->isRenderView()) {
+ ASSERT(paintInvalidationContainer == v);
+ v->repaintViewRectangle(r);
+ return;
}
if (v->usesCompositing()) {
- ASSERT(repaintContainer->hasLayer() && repaintContainer->layer()->compositingState() == PaintsIntoOwnBacking);
- repaintContainer->layer()->repainter().setBackingNeedsRepaintInRect(r);
+ ASSERT(paintInvalidationContainer->hasLayer() && (paintInvalidationContainer->layer()->compositingState() == PaintsIntoOwnBacking || paintInvalidationContainer->layer()->compositingState() == PaintsIntoGroupedBacking));
+ paintInvalidationContainer->layer()->repainter().setBackingNeedsRepaintInRect(r);
}
}
-void RenderObject::repaint() const
+void RenderObject::paintInvalidationForWholeRenderer() const
{
- // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
- RenderView* view;
- if (!isRooted(&view))
+ if (!isRooted())
return;
- if (view->document().printing())
- return; // Don't repaint if we're printing.
+ if (view()->document().printing())
+ return; // Don't invalidate paints if we're printing.
- RenderLayerModelObject* repaintContainer = containerForRepaint();
- repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(clippedOverflowRectForRepaint(repaintContainer)));
+ // FIXME: really, we're in the paint invalidation phase here, and the following queries are legal.
+ // Until those states are fully fledged, I'll just disable the ASSERTS.
+ DisableCompositingQueryAsserts disabler;
+ const RenderLayerModelObject* paintInvalidationContainer = containerForPaintInvalidation();
+ LayoutRect paintInvalidationRect = boundsRectForPaintInvalidation(paintInvalidationContainer);
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(paintInvalidationRect), InvalidationPaint);
}
-void RenderObject::repaintRectangle(const LayoutRect& r) const
+LayoutRect RenderObject::boundsRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
- // Don't repaint if we're unrooted (note that view() still returns the view when unrooted)
- RenderView* view;
- if (!isRooted(&view))
+ if (!paintInvalidationContainer)
+ return computePaintInvalidationRect(paintInvalidationContainer);
+ return RenderLayer::computeRepaintRect(this, paintInvalidationContainer->layer());
+}
+
+void RenderObject::invalidatePaintRectangle(const LayoutRect& r) const
+{
+ if (!isRooted())
return;
- if (view->document().printing())
- return; // Don't repaint if we're printing.
+ if (view()->document().printing())
+ return; // Don't invalidate paints if we're printing.
LayoutRect dirtyRect(r);
- // FIXME: layoutDelta needs to be applied in parts before/after transforms and
- // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
- dirtyRect.move(view->layoutDelta());
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ // FIXME: layoutDelta needs to be applied in parts before/after transforms and
+ // paint invalidation containers. https://bugs.webkit.org/show_bug.cgi?id=23308
+ dirtyRect.move(view()->layoutDelta());
+ }
- RenderLayerModelObject* repaintContainer = containerForRepaint();
- computeRectForRepaint(repaintContainer, dirtyRect);
- repaintUsingContainer(repaintContainer ? repaintContainer : view, pixelSnappedIntRect(dirtyRect));
+ const RenderLayerModelObject* paintInvalidationContainer = containerForPaintInvalidation();
+ RenderLayer::mapRectToRepaintBacking(this, paintInvalidationContainer, dirtyRect);
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(dirtyRect), InvalidationPaintRectangle);
}
IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
@@ -1481,84 +1585,165 @@ IntRect RenderObject::pixelSnappedAbsoluteClippedOverflowRect() const
return pixelSnappedIntRect(absoluteClippedOverflowRect());
}
-bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, bool wasSelfLayout,
- const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox,
- const LayoutRect* newBoundsPtr, const LayoutRect* newOutlineBoxRectPtr)
+const char* RenderObject::invalidationReasonToString(InvalidationReason reason) const
+{
+ switch (reason) {
+ case InvalidationIncremental:
+ return "incremental";
+ case InvalidationSelfLayout:
+ return "self layout";
+ case InvalidationBorderFitLines:
+ return "border fit lines";
+ case InvalidationBorderRadius:
+ return "border radius";
+ case InvalidationBoundsChangeWithBackground:
+ return "bounds change with background";
+ case InvalidationBoundsChange:
+ return "bounds change";
+ case InvalidationLocationChange:
+ return "location change";
+ case InvalidationScroll:
+ return "scroll";
+ case InvalidationSelection:
+ return "selection";
+ case InvalidationLayer:
+ return "layer";
+ case InvalidationPaint:
+ return "invalidate paint";
+ case InvalidationPaintRectangle:
+ return "invalidate paint rectangle";
+ }
+ ASSERT_NOT_REACHED();
+ return "";
+}
+
+void RenderObject::invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer)
+{
+ // If we didn't need paint invalidation then our children don't need as well.
+ // Skip walking down the tree as everything should be fine below us.
+ if (!shouldCheckForPaintInvalidationAfterLayout())
+ return;
+
+ clearPaintInvalidationState();
+
+ for (RenderObject* child = slowFirstChild(); child; child = child->nextSibling()) {
+ if (!child->isOutOfFlowPositioned())
+ child->invalidateTreeAfterLayout(paintInvalidationContainer);
+ }
+}
+
+static PassRefPtr<JSONValue> jsonObjectForOldAndNewRects(const LayoutRect& oldRect, const LayoutRect& newRect)
+{
+ RefPtr<JSONObject> object = JSONObject::create();
+
+ object->setValue("old", jsonObjectForRect(oldRect));
+ object->setValue("new", jsonObjectForRect(newRect));
+ return object.release();
+}
+
+bool RenderObject::invalidatePaintAfterLayoutIfNeeded(const RenderLayerModelObject* paintInvalidationContainer, bool wasSelfLayout,
+ const LayoutRect& oldBounds, const LayoutPoint& oldLocation, const LayoutRect* newBoundsPtr, const LayoutPoint* newLocationPtr)
{
RenderView* v = view();
if (v->document().printing())
- return false; // Don't repaint if we're printing.
+ return false; // Don't invalidate paints if we're printing.
// This ASSERT fails due to animations. See https://bugs.webkit.org/show_bug.cgi?id=37048
- // ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForRepaint(repaintContainer));
- LayoutRect newBounds = newBoundsPtr ? *newBoundsPtr : clippedOverflowRectForRepaint(repaintContainer);
- LayoutRect newOutlineBox;
+ // ASSERT(!newBoundsPtr || *newBoundsPtr == clippedOverflowRectForPaintInvalidation(paintInvalidationContainer));
+ LayoutRect newBounds = newBoundsPtr ? *newBoundsPtr : computePaintInvalidationRect();
+ LayoutPoint newLocation = newLocationPtr ? (*newLocationPtr) : RenderLayer::positionFromPaintInvalidationContainer(this, paintInvalidationContainer);
+
+ // FIXME: This should use a ConvertableToTraceFormat when they are available in Blink.
+ TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "RenderObject::invalidatePaintAfterLayoutIfNeeded()",
+ "object", this->debugName().ascii(),
+ "info", TracedValue::fromJSONValue(jsonObjectForOldAndNewRects(oldBounds, newBounds)));
+
+ InvalidationReason invalidationReason = wasSelfLayout ? InvalidationSelfLayout : InvalidationIncremental;
- bool fullRepaint = wasSelfLayout;
// Presumably a background or a border exists if border-fit:lines was specified.
- if (!fullRepaint && style()->borderFit() == BorderFitLines)
- fullRepaint = true;
- if (!fullRepaint && style()->hasBorderRadius()) {
+ if (invalidationReason == InvalidationIncremental && style()->borderFit() == BorderFitLines)
+ invalidationReason = InvalidationBorderFitLines;
+
+ if (invalidationReason == InvalidationIncremental && style()->hasBorderRadius()) {
// If a border-radius exists and width/height is smaller than
- // radius width/height, we cannot use delta-repaint.
- RoundedRect oldRoundedRect = style()->getRoundedBorderFor(oldBounds, v);
- RoundedRect newRoundedRect = style()->getRoundedBorderFor(newBounds, v);
- fullRepaint = oldRoundedRect.radii() != newRoundedRect.radii();
+ // radius width/height, we cannot use delta-paint-invalidation.
+ RoundedRect oldRoundedRect = style()->getRoundedBorderFor(oldBounds);
+ RoundedRect newRoundedRect = style()->getRoundedBorderFor(newBounds);
+ if (oldRoundedRect.radii() != newRoundedRect.radii())
+ invalidationReason = InvalidationBorderRadius;
}
- if (!fullRepaint) {
- // This ASSERT fails due to animations. See https://bugs.webkit.org/show_bug.cgi?id=37048
- // ASSERT(!newOutlineBoxRectPtr || *newOutlineBoxRectPtr == outlineBoundsForRepaint(repaintContainer));
- newOutlineBox = newOutlineBoxRectPtr ? *newOutlineBoxRectPtr : outlineBoundsForRepaint(repaintContainer);
- if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
- fullRepaint = true;
+
+ if (invalidationReason == InvalidationIncremental && compositingState() != PaintsIntoOwnBacking && newLocation != oldLocation)
+ invalidationReason = InvalidationLocationChange;
+
+ // If the bounds are the same then we know that none of the statements below
+ // can match, so we can early out since we will not need to do any
+ // invalidation.
+ if (invalidationReason == InvalidationIncremental && oldBounds == newBounds)
+ return false;
+
+ if (invalidationReason == InvalidationIncremental) {
+ if (oldBounds.width() != newBounds.width() && mustInvalidateBackgroundOrBorderPaintOnWidthChange())
+ invalidationReason = InvalidationBoundsChangeWithBackground;
+ else if (oldBounds.height() != newBounds.height() && mustInvalidateBackgroundOrBorderPaintOnHeightChange())
+ invalidationReason = InvalidationBoundsChangeWithBackground;
}
- if (!repaintContainer)
- repaintContainer = v;
+ // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could
+ // be caused by some layout property (left / top) or some in-flow renderer inserted / removed before us in the tree.
+ if (invalidationReason == InvalidationIncremental && newBounds.location() != oldBounds.location())
+ invalidationReason = InvalidationBoundsChange;
+
+ // If the size is zero on one of our bounds then we know we're going to have
+ // to do a full invalidation of either old bounds or new bounds. If we fall
+ // into the incremental invalidation we'll issue two invalidations instead
+ // of one.
+ if (invalidationReason == InvalidationIncremental && (oldBounds.size().isZero() || newBounds.size().isZero()))
+ invalidationReason = InvalidationBoundsChange;
+
+ ASSERT(paintInvalidationContainer);
- if (fullRepaint) {
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds));
+ if (invalidationReason != InvalidationIncremental) {
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds), invalidationReason);
if (newBounds != oldBounds)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds), invalidationReason);
return true;
}
- if (newBounds == oldBounds && newOutlineBox == oldOutlineBox)
- return false;
-
LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
if (deltaLeft > 0)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()), invalidationReason);
else if (deltaLeft < 0)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()), invalidationReason);
LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
if (deltaRight > 0)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()), invalidationReason);
else if (deltaRight < 0)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()), invalidationReason);
LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
if (deltaTop > 0)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop), invalidationReason);
else if (deltaTop < 0)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop), invalidationReason);
LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
if (deltaBottom > 0)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom), invalidationReason);
else if (deltaBottom < 0)
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom), invalidationReason);
- if (newOutlineBox == oldOutlineBox)
+ // FIXME: This is a limitation of our visual overflow being a single rectangle.
+ if (!style()->boxShadow() && !style()->hasBorderImageOutsets() && !style()->hasOutline())
return false;
// We didn't move, but we did change size. Invalidate the delta, which will consist of possibly
// two rectangles (but typically only one).
- RenderStyle* outlineStyle = outlineStyleForRepaint();
+ RenderStyle* outlineStyle = outlineStyleForPaintInvalidation();
LayoutUnit outlineWidth = outlineStyle->outlineSize();
LayoutBoxExtent insetShadowExtent = style()->getBoxShadowInsetExtent();
- LayoutUnit width = absoluteValue(newOutlineBox.width() - oldOutlineBox.width());
+ LayoutUnit width = absoluteValue(newBounds.width() - oldBounds.width());
if (width) {
LayoutUnit shadowLeft;
LayoutUnit shadowRight;
@@ -1566,19 +1751,20 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repa
int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0;
LayoutUnit boxWidth = isBox() ? toRenderBox(this)->width() : LayoutUnit();
LayoutUnit minInsetRightShadowExtent = min<LayoutUnit>(-insetShadowExtent.right(), min<LayoutUnit>(newBounds.width(), oldBounds.width()));
- LayoutUnit borderWidth = max<LayoutUnit>(borderRight, max<LayoutUnit>(valueForLength(style()->borderTopRightRadius().width(), boxWidth, v), valueForLength(style()->borderBottomRightRadius().width(), boxWidth, v)));
- LayoutUnit decorationsWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderWidth + minInsetRightShadowExtent) + max<LayoutUnit>(outlineWidth, shadowRight);
- LayoutRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - decorationsWidth,
- newOutlineBox.y(),
- width + decorationsWidth,
- max(newOutlineBox.height(), oldOutlineBox.height()));
+ LayoutUnit borderWidth = max<LayoutUnit>(borderRight, max<LayoutUnit>(valueForLength(style()->borderTopRightRadius().width(), boxWidth), valueForLength(style()->borderBottomRightRadius().width(), boxWidth)));
+ LayoutUnit decorationsLeftWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderWidth + minInsetRightShadowExtent) + max<LayoutUnit>(outlineWidth, -shadowLeft);
+ LayoutUnit decorationsRightWidth = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderWidth + minInsetRightShadowExtent) + max<LayoutUnit>(outlineWidth, shadowRight);
+ LayoutRect rightRect(newBounds.x() + min(newBounds.width(), oldBounds.width()) - decorationsLeftWidth,
+ newBounds.y(),
+ width + decorationsLeftWidth + decorationsRightWidth,
+ max(newBounds.height(), oldBounds.height()));
LayoutUnit right = min<LayoutUnit>(newBounds.maxX(), oldBounds.maxX());
if (rightRect.x() < right) {
rightRect.setWidth(min(rightRect.width(), right - rightRect.x()));
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(rightRect));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(rightRect), invalidationReason);
}
}
- LayoutUnit height = absoluteValue(newOutlineBox.height() - oldOutlineBox.height());
+ LayoutUnit height = absoluteValue(newBounds.height() - oldBounds.height());
if (height) {
LayoutUnit shadowTop;
LayoutUnit shadowBottom;
@@ -1586,46 +1772,58 @@ bool RenderObject::repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repa
int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0;
LayoutUnit boxHeight = isBox() ? toRenderBox(this)->height() : LayoutUnit();
LayoutUnit minInsetBottomShadowExtent = min<LayoutUnit>(-insetShadowExtent.bottom(), min<LayoutUnit>(newBounds.height(), oldBounds.height()));
- LayoutUnit borderHeight = max<LayoutUnit>(borderBottom, max<LayoutUnit>(valueForLength(style()->borderBottomLeftRadius().height(), boxHeight, v), valueForLength(style()->borderBottomRightRadius().height(), boxHeight, v)));
- LayoutUnit decorationsHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderHeight + minInsetBottomShadowExtent) + max<LayoutUnit>(outlineWidth, shadowBottom);
- LayoutRect bottomRect(newOutlineBox.x(),
- min(newOutlineBox.maxY(), oldOutlineBox.maxY()) - decorationsHeight,
- max(newOutlineBox.width(), oldOutlineBox.width()),
- height + decorationsHeight);
+ LayoutUnit borderHeight = max<LayoutUnit>(borderBottom, max<LayoutUnit>(valueForLength(style()->borderBottomLeftRadius().height(), boxHeight), valueForLength(style()->borderBottomRightRadius().height(), boxHeight)));
+ LayoutUnit decorationsTopHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderHeight + minInsetBottomShadowExtent) + max<LayoutUnit>(outlineWidth, -shadowTop);
+ LayoutUnit decorationsBottomHeight = max<LayoutUnit>(-outlineStyle->outlineOffset(), borderHeight + minInsetBottomShadowExtent) + max<LayoutUnit>(outlineWidth, shadowBottom);
+ LayoutRect bottomRect(newBounds.x(),
+ min(newBounds.maxY(), oldBounds.maxY()) - decorationsTopHeight,
+ max(newBounds.width(), oldBounds.width()),
+ height + decorationsTopHeight + decorationsBottomHeight);
LayoutUnit bottom = min(newBounds.maxY(), oldBounds.maxY());
if (bottomRect.y() < bottom) {
bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y()));
- repaintUsingContainer(repaintContainer, pixelSnappedIntRect(bottomRect));
+ invalidatePaintUsingContainer(paintInvalidationContainer, pixelSnappedIntRect(bottomRect), invalidationReason);
}
}
return false;
}
-void RenderObject::repaintOverflow()
+void RenderObject::invalidatePaintForOverflow()
+{
+}
+
+void RenderObject::invalidatePaintForOverflowIfNeeded()
+{
+ if (shouldInvalidateOverflowForPaint())
+ invalidatePaintForOverflow();
+}
+
+bool RenderObject::checkForPaintInvalidation() const
{
+ return !document().view()->needsFullPaintInvalidation() && everHadLayout();
}
-bool RenderObject::checkForRepaintDuringLayout() const
+bool RenderObject::checkForPaintInvalidationDuringLayout() const
{
- return !document().view()->needsFullRepaint() && !hasLayer() && everHadLayout();
+ return !RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && checkForPaintInvalidation();
}
-LayoutRect RenderObject::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
+LayoutRect RenderObject::rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth) const
{
- LayoutRect r(clippedOverflowRectForRepaint(repaintContainer));
+ LayoutRect r(clippedOverflowRectForPaintInvalidation(paintInvalidationContainer));
r.inflate(outlineWidth);
return r;
}
-LayoutRect RenderObject::clippedOverflowRectForRepaint(const RenderLayerModelObject*) const
+LayoutRect RenderObject::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject*) const
{
ASSERT_NOT_REACHED();
return LayoutRect();
}
-void RenderObject::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
+void RenderObject::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, bool fixed) const
{
- if (repaintContainer == this)
+ if (paintInvalidationContainer == this)
return;
if (RenderObject* o = parent()) {
@@ -1642,11 +1840,11 @@ void RenderObject::computeRectForRepaint(const RenderLayerModelObject* repaintCo
return;
}
- o->computeRectForRepaint(repaintContainer, rect, fixed);
+ o->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, fixed);
}
}
-void RenderObject::computeFloatRectForRepaint(const RenderLayerModelObject*, FloatRect&, bool) const
+void RenderObject::computeFloatRectForPaintInvalidation(const RenderLayerModelObject*, FloatRect&, bool) const
{
ASSERT_NOT_REACHED();
}
@@ -1714,7 +1912,7 @@ void RenderObject::showRenderTreeAndMark(const RenderObject* markedObject1, cons
if (!this)
return;
- for (const RenderObject* child = firstChild(); child; child = child->nextSibling())
+ for (const RenderObject* child = slowFirstChild(); child; child = child->nextSibling())
child->showRenderTreeAndMark(markedObject1, markedLabel1, markedObject2, markedLabel2, depth + 1);
}
@@ -1727,19 +1925,14 @@ bool RenderObject::isSelectable() const
Color RenderObject::selectionBackgroundColor() const
{
- Color backgroundColor;
- if (isSelectable()) {
- RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(PseudoStyleRequest(SELECTION));
- if (pseudoStyle && resolveColor(pseudoStyle.get(), CSSPropertyBackgroundColor).isValid()) {
- backgroundColor = resolveColor(pseudoStyle.get(), CSSPropertyBackgroundColor).blendWithWhite();
- } else {
- backgroundColor = frame()->selection().isFocusedAndActive() ?
- RenderTheme::theme().activeSelectionBackgroundColor() :
- RenderTheme::theme().inactiveSelectionBackgroundColor();
- }
- }
+ if (!isSelectable())
+ return Color::transparent;
- return backgroundColor;
+ if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyleFromParentOrShadowHost())
+ return resolveColor(pseudoStyle.get(), CSSPropertyBackgroundColor).blendWithWhite();
+ return frame()->selection().isFocusedAndActive() ?
+ RenderTheme::theme().activeSelectionBackgroundColor() :
+ RenderTheme::theme().inactiveSelectionBackgroundColor();
}
Color RenderObject::selectionColor(int colorProperty) const
@@ -1747,19 +1940,15 @@ Color RenderObject::selectionColor(int colorProperty) const
// If the element is unselectable, or we are only painting the selection,
// don't override the foreground color with the selection foreground color.
if (!isSelectable() || (frame()->view()->paintBehavior() & PaintBehaviorSelectionOnly))
- return Color::transparent;
+ return resolveColor(colorProperty);
- Color color;
- if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(PseudoStyleRequest(SELECTION))) {
- Color selectionColor = resolveColor(pseudoStyle.get(), colorProperty);
- color = selectionColor.isValid() ? selectionColor : resolveColor(pseudoStyle.get(), CSSPropertyColor);
- } else {
- color = frame()->selection().isFocusedAndActive() ?
- RenderTheme::theme().activeSelectionForegroundColor() :
- RenderTheme::theme().inactiveSelectionForegroundColor();
- }
-
- return color;
+ if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyleFromParentOrShadowHost())
+ return resolveColor(pseudoStyle.get(), colorProperty);
+ if (!RenderTheme::theme().supportsSelectionForegroundColors())
+ return resolveColor(colorProperty);
+ return frame()->selection().isFocusedAndActive() ?
+ RenderTheme::theme().activeSelectionForegroundColor() :
+ RenderTheme::theme().inactiveSelectionForegroundColor();
}
Color RenderObject::selectionForegroundColor() const
@@ -1796,65 +1985,57 @@ void RenderObject::handleDynamicFloatPositionChange()
}
}
-void RenderObject::setAnimatableStyle(PassRefPtr<RenderStyle> style)
-{
- if (!isText() && style && !RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
- setStyle(animation().updateAnimations(*this, *style));
- return;
- }
- setStyle(style);
-}
-
StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const
{
- // If transform changed, and the layer does not paint into its own separate backing, then we need to do a layout.
- // FIXME: The comment above is what the code does, but it is technically not following spec. This means we will
- // not to layout for 3d transforms, but we should be invoking a simplified relayout. Is it possible we are avoiding
- // doing this for some performance reason at this time?
+ if (contextSensitiveProperties & ContextSensitivePropertyTransform && isSVG())
+ diff.setNeedsFullLayout();
+
+ // If transform changed, and the layer does not paint into its own separate backing, then we need to invalidate paints.
if (contextSensitiveProperties & ContextSensitivePropertyTransform) {
// Text nodes share style with their parents but transforms don't apply to them,
// hence the !isText() check.
- // FIXME: when transforms are taken into account for overflow, we will need to do a layout.
- if (!isText() && (!hasLayer() || toRenderLayerModelObject(this)->layer()->compositingState() != PaintsIntoOwnBacking)) {
- // We need to set at least SimplifiedLayout, but if PositionedMovementOnly is already set
- // then we actually need SimplifiedLayoutAndPositionedMovement.
- if (!hasLayer())
- diff = StyleDifferenceLayout; // FIXME: Do this for now since SimplifiedLayout cannot handle updating floating objects lists.
- else if (diff < StyleDifferenceLayoutPositionedMovementOnly)
- diff = StyleDifferenceSimplifiedLayout;
- else if (diff < StyleDifferenceSimplifiedLayout)
- diff = StyleDifferenceSimplifiedLayoutAndPositionedMovement;
- } else if (diff < StyleDifferenceRecompositeLayer)
- diff = StyleDifferenceRecompositeLayer;
- }
-
- // If opacity or filters changed, and the layer does not paint into its own separate backing, then we need to repaint (also
+ if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer()->styleDeterminedCompositingReasons()))
+ diff.setNeedsRepaintLayer();
+ else
+ diff.setNeedsRecompositeLayer();
+ }
+
+ // If opacity or zIndex changed, and the layer does not paint into its own separate backing, then we need to invalidate paints (also
// ignoring text nodes)
- if (contextSensitiveProperties & ContextSensitivePropertyOpacity && diff <= StyleDifferenceRepaintLayer) {
- if (!isText() && (!hasLayer() || toRenderLayerModelObject(this)->layer()->compositingState() != PaintsIntoOwnBacking))
- diff = StyleDifferenceRepaintLayer;
- else if (diff < StyleDifferenceRecompositeLayer)
- diff = StyleDifferenceRecompositeLayer;
+ if (contextSensitiveProperties & (ContextSensitivePropertyOpacity | ContextSensitivePropertyZIndex)) {
+ if (!isText() && (!hasLayer() || !toRenderLayerModelObject(this)->layer()->styleDeterminedCompositingReasons()))
+ diff.setNeedsRepaintLayer();
+ else
+ diff.setNeedsRecompositeLayer();
}
- if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLayer() && diff <= StyleDifferenceRepaintLayer) {
+
+ // If filter changed, and the layer does not paint into its own separate backing or it paints with filters, then we need to invalidate paints.
+ if ((contextSensitiveProperties & ContextSensitivePropertyFilter) && hasLayer()) {
RenderLayer* layer = toRenderLayerModelObject(this)->layer();
- if (layer->compositingState() != PaintsIntoOwnBacking || layer->paintsWithFilters())
- diff = StyleDifferenceRepaintLayer;
- else if (diff < StyleDifferenceRecompositeLayer)
- diff = StyleDifferenceRecompositeLayer;
+ if (!layer->styleDeterminedCompositingReasons() || layer->paintsWithFilters())
+ diff.setNeedsRepaintLayer();
+ else
+ diff.setNeedsRecompositeLayer();
}
- // The answer to requiresLayer() for plugins, iframes, and canvas can change without the actual
+ if ((contextSensitiveProperties & ContextSensitivePropertyTextOrColor) && !diff.needsRepaint()
+ && hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor())
+ diff.setNeedsRepaintObject();
+
+ // The answer to layerTypeRequired() for plugins, iframes, and canvas can change without the actual
// style changing, since it depends on whether we decide to composite these elements. When the
// layer status of one of these elements changes, we need to force a layout.
- if (diff == StyleDifferenceEqual && style() && isLayerModelObject()) {
- if (hasLayer() != toRenderLayerModelObject(this)->requiresLayer())
- diff = StyleDifferenceLayout;
+ if (!diff.needsFullLayout() && style() && isLayerModelObject()) {
+ bool requiresLayer = toRenderLayerModelObject(this)->layerTypeRequired() != NoLayer;
+ if (hasLayer() != requiresLayer)
+ diff.setNeedsFullLayout();
}
- // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint.
- if (diff == StyleDifferenceRepaintLayer && !hasLayer())
- diff = StyleDifferenceRepaint;
+ // If we have no layer(), just treat a RepaintLayer hint as a normal paint invalidation.
+ if (diff.needsRepaintLayer() && !hasLayer()) {
+ diff.clearNeedsRepaint();
+ diff.setNeedsRepaintObject();
+ }
return diff;
}
@@ -1884,7 +2065,9 @@ void RenderObject::setPseudoStyle(PassRefPtr<RenderStyle> pseudoStyle)
inline bool RenderObject::hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor() const
{
- for (const RenderObject* r = firstChild(); r; r = r->nextSibling()) {
+ if (style()->hasBorder() || style()->hasOutline())
+ return true;
+ for (const RenderObject* r = slowFirstChild(); r; r = r->nextSibling()) {
if (r->isText() && !toRenderText(r)->isAllCollapsibleWhitespace())
return true;
if (r->style()->hasOutline() || r->style()->hasBorder())
@@ -1893,13 +2076,24 @@ inline bool RenderObject::hasImmediateNonWhitespaceTextChildOrPropertiesDependen
return false;
}
-inline bool RenderObject::shouldRepaintForStyleDifference(StyleDifference diff) const
+void RenderObject::markContainingBlocksForOverflowRecalc()
{
- return diff == StyleDifferenceRepaint || (diff == StyleDifferenceRepaintIfTextOrColorChange && hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor());
+ for (RenderBlock* container = containingBlock(); container && !container->childNeedsOverflowRecalcAfterStyleChange(); container = container->containingBlock())
+ container->setChildNeedsOverflowRecalcAfterStyleChange(true);
+}
+
+void RenderObject::setNeedsOverflowRecalcAfterStyleChange()
+{
+ bool neededRecalc = needsOverflowRecalcAfterStyleChange();
+ setSelfNeedsOverflowRecalcAfterStyleChange(true);
+ if (!neededRecalc)
+ markContainingBlocksForOverflowRecalc();
}
void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
{
+ ASSERT(style);
+
if (m_style == style) {
// We need to run through adjustStyleDifference() for iframes, plugins, and canvas so
// style sharing is disabled for them. That should ensure that we never hit this code path.
@@ -1907,14 +2101,14 @@ void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
return;
}
- StyleDifference diff = StyleDifferenceEqual;
+ StyleDifference diff;
unsigned contextSensitiveProperties = ContextSensitivePropertyNone;
if (m_style)
- diff = m_style->diff(style.get(), contextSensitiveProperties);
+ diff = m_style->visualInvalidationDiff(*style, contextSensitiveProperties);
diff = adjustStyleDifference(diff, contextSensitiveProperties);
- styleWillChange(diff, style.get());
+ styleWillChange(diff, *style);
RefPtr<RenderStyle> oldStyle = m_style.release();
setStyleInternal(style);
@@ -1925,15 +2119,8 @@ void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
updateImage(oldStyle ? oldStyle->borderImage().image() : 0, m_style ? m_style->borderImage().image() : 0);
updateImage(oldStyle ? oldStyle->maskBoxImage().image() : 0, m_style ? m_style->maskBoxImage().image() : 0);
- updateShapeImage(oldStyle ? oldStyle->shapeInside() : 0, m_style ? m_style->shapeInside() : 0);
updateShapeImage(oldStyle ? oldStyle->shapeOutside() : 0, m_style ? m_style->shapeOutside() : 0);
- // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen
- // during styleDidChange (it's used by clippedOverflowRectForRepaint()).
- // FIXME: Do this more cleanly. http://crbug.com/273904
- if (m_style->outlineWidth() > 0 && m_style->outlineSize() > view()->maximalOutlineSize())
- view()->setMaximalOutlineSize(m_style->outlineSize());
-
bool doesNotNeedLayout = !m_parent || isText();
styleDidChange(diff, oldStyle.get());
@@ -1946,25 +2133,28 @@ void RenderObject::setStyle(PassRefPtr<RenderStyle> style)
return;
// Now that the layer (if any) has been updated, we need to adjust the diff again,
- // check whether we should layout now, and decide if we need to repaint.
+ // check whether we should layout now, and decide if we need to invalidate paints.
StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties);
- if (diff <= StyleDifferenceLayoutPositionedMovementOnly) {
- if (updatedDiff == StyleDifferenceLayout)
+ if (!diff.needsFullLayout()) {
+ if (updatedDiff.needsFullLayout())
setNeedsLayoutAndPrefWidthsRecalc();
- else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly)
- setNeedsPositionedMovementLayout();
- else if (updatedDiff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
+ else if (updatedDiff.needsPositionedMovementLayout())
setNeedsPositionedMovementLayout();
- setNeedsSimplifiedNormalFlowLayout();
- } else if (updatedDiff == StyleDifferenceSimplifiedLayout)
- setNeedsSimplifiedNormalFlowLayout();
}
- if (updatedDiff == StyleDifferenceRepaintLayer || shouldRepaintForStyleDifference(updatedDiff)) {
- // Do a repaint with the new style now, e.g., for example if we go from
- // not having an outline to having an outline.
- repaint();
+ if (contextSensitiveProperties & ContextSensitivePropertyTransform && !needsLayout()) {
+ if (RenderBlock* container = containingBlock())
+ container->setNeedsOverflowRecalcAfterStyleChange();
+ }
+
+ if (updatedDiff.needsRepaint()) {
+ // Invalidate paints with the new style, e.g., for example if we go from not having
+ // an outline to having an outline.
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && needsLayout())
+ setShouldDoFullPaintInvalidationAfterLayout(true);
+ else if (!selfNeedsLayout())
+ paintInvalidationForWholeRenderer();
}
}
@@ -1973,76 +2163,80 @@ static inline bool rendererHasBackground(const RenderObject* renderer)
return renderer && renderer->hasBackground();
}
-void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
if (m_style) {
// If our z-index changes value or our visibility changes,
// we need to dirty our stacking context's z-order list.
- if (newStyle) {
- bool visibilityChanged = m_style->visibility() != newStyle->visibility()
- || m_style->zIndex() != newStyle->zIndex()
- || m_style->hasAutoZIndex() != newStyle->hasAutoZIndex();
- if (visibilityChanged) {
- document().setAnnotatedRegionsDirty(true);
- if (AXObjectCache* cache = document().existingAXObjectCache())
- cache->childrenChanged(parent());
- }
+ bool visibilityChanged = m_style->visibility() != newStyle.visibility()
+ || m_style->zIndex() != newStyle.zIndex()
+ || m_style->hasAutoZIndex() != newStyle.hasAutoZIndex();
+ if (visibilityChanged) {
+ document().setAnnotatedRegionsDirty(true);
+ if (AXObjectCache* cache = document().existingAXObjectCache())
+ cache->childrenChanged(parent());
+ }
- // Keep layer hierarchy visibility bits up to date if visibility changes.
- if (m_style->visibility() != newStyle->visibility()) {
- if (RenderLayer* l = enclosingLayer()) {
- if (newStyle->visibility() == VISIBLE)
- l->setHasVisibleContent();
- else if (l->hasVisibleContent() && (this == l->renderer() || l->renderer()->style()->visibility() != VISIBLE)) {
- l->dirtyVisibleContentStatus();
- if (diff > StyleDifferenceRepaintLayer)
- repaint();
- }
+ // Keep layer hierarchy visibility bits up to date if visibility changes.
+ if (m_style->visibility() != newStyle.visibility()) {
+ // We might not have an enclosing layer yet because we might not be in the tree.
+ if (RenderLayer* layer = enclosingLayer()) {
+ if (newStyle.visibility() == VISIBLE) {
+ layer->setHasVisibleContent();
+ } else if (layer->hasVisibleContent() && (this == layer->renderer() || layer->renderer()->style()->visibility() != VISIBLE)) {
+ layer->dirtyVisibleContentStatus();
+ if (diff.needsLayout())
+ paintInvalidationForWholeRenderer();
}
}
}
- if (m_parent && (newStyle->outlineSize() < m_style->outlineSize() || shouldRepaintForStyleDifference(diff)))
- repaint();
- if (isFloating() && (m_style->floating() != newStyle->floating()))
+ if (m_parent && diff.needsRepaintObject()) {
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && (diff.needsLayout() || needsLayout()))
+ setShouldDoFullPaintInvalidationAfterLayout(true);
+ else if (!diff.needsFullLayout() && !selfNeedsLayout())
+ paintInvalidationForWholeRenderer();
+ }
+
+ if (isFloating() && (m_style->floating() != newStyle.floating()))
// For changes in float styles, we need to conceivably remove ourselves
// from the floating objects list.
toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
- else if (isOutOfFlowPositioned() && (m_style->position() != newStyle->position()))
+ else if (isOutOfFlowPositioned() && (m_style->position() != newStyle.position()))
// For changes in positioning styles, we need to conceivably remove ourselves
// from the positioned objects list.
toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists();
s_affectsParentBlock = isFloatingOrOutOfFlowPositioned()
- && (!newStyle->isFloating() && !newStyle->hasOutOfFlowPosition())
+ && (!newStyle.isFloating() && !newStyle.hasOutOfFlowPosition())
&& parent() && (parent()->isRenderBlockFlow() || parent()->isRenderInline());
// Clearing these bits is required to avoid leaving stale renderers.
// FIXME: We shouldn't need that hack if our logic was totally correct.
- if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositionedMovementOnly) {
+ if (diff.needsLayout()) {
setFloating(false);
clearPositionedState();
}
- } else
+ } else {
s_affectsParentBlock = false;
+ }
if (view()->frameView()) {
bool shouldBlitOnFixedBackgroundImage = false;
-#if ENABLE(FAST_MOBILE_SCROLLING)
- // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
- // when scrolling a page with a fixed background image. As an optimization, assuming there are
- // no fixed positoned elements on the page, we can acclerate scrolling (via blitting) if we
- // ignore the CSS property "background-attachment: fixed".
- shouldBlitOnFixedBackgroundImage = true;
-#endif
-
- bool newStyleSlowScroll = newStyle && !shouldBlitOnFixedBackgroundImage && newStyle->hasFixedBackgroundImage();
+ if (RuntimeEnabledFeatures::fastMobileScrollingEnabled()) {
+ // On low-powered/mobile devices, preventing blitting on a scroll can cause noticeable delays
+ // when scrolling a page with a fixed background image. As an optimization, assuming there are
+ // no fixed positoned elements on the page, we can acclerate scrolling (via blitting) if we
+ // ignore the CSS property "background-attachment: fixed".
+ shouldBlitOnFixedBackgroundImage = true;
+ }
+ bool newStyleSlowScroll = !shouldBlitOnFixedBackgroundImage && newStyle.hasFixedBackgroundImage();
bool oldStyleSlowScroll = m_style && !shouldBlitOnFixedBackgroundImage && m_style->hasFixedBackgroundImage();
- bool drawsRootBackground = isRoot() || (isBody() && !rendererHasBackground(document().documentElement()->renderer()));
+ bool drawsRootBackground = isDocumentElement() || (isBody() && !rendererHasBackground(document().documentElement()->renderer()));
if (drawsRootBackground && !shouldBlitOnFixedBackgroundImage) {
if (view()->compositor()->supportsFixedRootBackgroundCompositing()) {
- if (newStyleSlowScroll && newStyle->hasEntirelyFixedBackground())
+ if (newStyleSlowScroll && newStyle.hasEntirelyFixedBackground())
newStyleSlowScroll = false;
if (oldStyleSlowScroll && m_style->hasEntirelyFixedBackground())
@@ -2057,6 +2251,20 @@ void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newS
view()->frameView()->addSlowRepaintObject();
}
}
+
+ // Elements with non-auto touch-action will send a SetTouchAction message
+ // on touchstart in EventHandler::handleTouchEvent, and so effectively have
+ // a touchstart handler that must be reported.
+ //
+ // Since a CSS property cannot be applied directly to a text node, a
+ // handler will have already been added for its parent so ignore it.
+ TouchAction oldTouchAction = m_style ? m_style->touchAction() : TouchActionAuto;
+ if (node() && !node()->isTextNode() && (oldTouchAction == TouchActionAuto) != (newStyle.touchAction() == TouchActionAuto)) {
+ if (newStyle.touchAction() != TouchActionAuto)
+ document().didAddTouchEventHandler(node());
+ else
+ document().didRemoveTouchEventHandler(node());
+ }
}
static bool areNonIdenticalCursorListsEqual(const RenderStyle* a, const RenderStyle* b)
@@ -2078,7 +2286,7 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
if (!m_parent)
return;
- if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) {
+ if (diff.needsFullLayout()) {
RenderCounter::rendererStyleChanged(*this, oldStyle, m_style.get());
// If the object already needs layout, then setNeedsLayout won't do
@@ -2089,21 +2297,20 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
if (needsLayout() && oldStyle->position() != m_style->position())
markContainingBlocksForLayout();
- if (diff == StyleDifferenceLayout)
+ // Ditto.
+ if (needsOverflowRecalcAfterStyleChange() && oldStyle->position() != m_style->position())
+ markContainingBlocksForOverflowRecalc();
+
+ if (diff.needsFullLayout())
setNeedsLayoutAndPrefWidthsRecalc();
- else
- setNeedsSimplifiedNormalFlowLayout();
- } else if (diff == StyleDifferenceSimplifiedLayoutAndPositionedMovement) {
- setNeedsPositionedMovementLayout();
- setNeedsSimplifiedNormalFlowLayout();
- } else if (diff == StyleDifferenceLayoutPositionedMovementOnly)
+ } else if (diff.needsPositionedMovementLayout())
setNeedsPositionedMovementLayout();
- // Don't check for repaint here; we need to wait until the layer has been
- // updated by subclasses before we know if we have to repaint (in setStyle()).
+ // Don't check for paint invalidation here; we need to wait until the layer has been
+ // updated by subclasses before we know if we have to invalidate paints (in setStyle()).
if (oldStyle && !areCursorsEqual(oldStyle, style())) {
- if (Frame* frame = this->frame())
+ if (LocalFrame* frame = this->frame())
frame->eventHandler().scheduleCursorUpdate();
}
}
@@ -2111,7 +2318,7 @@ void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle* oldSt
void RenderObject::propagateStyleToAnonymousChildren(bool blockChildrenOnly)
{
// FIXME: We could save this call when the change only affected non-inherited properties.
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = slowFirstChild(); child; child = child->nextSibling()) {
if (!child->isAnonymous() || child->style()->styleType() != NOPSEUDO)
continue;
@@ -2203,9 +2410,9 @@ FloatQuad RenderObject::absoluteToLocalQuad(const FloatQuad& quad, MapCoordinate
return transformState.lastPlanarQuad();
}
-void RenderObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
+void RenderObject::mapLocalToContainer(const RenderLayerModelObject* paintInvalidationContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
{
- if (repaintContainer == this)
+ if (paintInvalidationContainer == this)
return;
RenderObject* o = parent();
@@ -2220,15 +2427,12 @@ void RenderObject::mapLocalToContainer(const RenderLayerModelObject* repaintCont
mode &= ~ApplyContainerFlip;
}
- LayoutSize columnOffset;
- o->adjustForColumns(columnOffset, roundedLayoutPoint(transformState.mappedPoint()));
- if (!columnOffset.isZero())
- transformState.move(columnOffset);
+ transformState.move(o->columnOffset(roundedLayoutPoint(transformState.mappedPoint())));
if (o->hasOverflowClip())
transformState.move(-toRenderBox(o)->scrolledContentOffset());
- o->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed);
+ o->mapLocalToContainer(paintInvalidationContainer, transformState, mode, wasFixed);
}
const RenderObject* RenderObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
@@ -2269,7 +2473,7 @@ bool RenderObject::shouldUseTransformFromContainer(const RenderObject* container
void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
{
transform.makeIdentity();
- transform.translate(offsetInContainer.width(), offsetInContainer.height());
+ transform.translate(offsetInContainer.width().toFloat(), offsetInContainer.height().toFloat());
RenderLayer* layer;
if (hasLayer() && (layer = toRenderLayerModelObject(this)->layer()) && layer->transform())
transform.multiply(layer->currentTransform());
@@ -2288,33 +2492,31 @@ void RenderObject::getTransformFromContainer(const RenderObject* containerObject
}
}
-FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
+FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, const RenderLayerModelObject* paintInvalidationContainer, MapCoordinatesFlags mode, bool* wasFixed) const
{
// Track the point at the center of the quad's bounding box. As mapLocalToContainer() calls offsetFromContainer(),
// it will use that point as the reference point to decide which column's transform to apply in multiple-column blocks.
TransformState transformState(TransformState::ApplyTransformDirection, localQuad.boundingBox().center(), localQuad);
- mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
+ mapLocalToContainer(paintInvalidationContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
transformState.flatten();
return transformState.lastPlanarQuad();
}
-FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags mode, bool* wasFixed) const
+FloatPoint RenderObject::localToContainerPoint(const FloatPoint& localPoint, const RenderLayerModelObject* paintInvalidationContainer, MapCoordinatesFlags mode, bool* wasFixed) const
{
TransformState transformState(TransformState::ApplyTransformDirection, localPoint);
- mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
+ mapLocalToContainer(paintInvalidationContainer, transformState, mode | ApplyContainerFlip | UseTransforms, wasFixed);
transformState.flatten();
return transformState.lastPlanarPoint();
}
-LayoutSize RenderObject::offsetFromContainer(RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
+LayoutSize RenderObject::offsetFromContainer(const RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
{
ASSERT(o == container());
- LayoutSize offset;
-
- o->adjustForColumns(offset, point);
+ LayoutSize offset = o->columnOffset(point);
if (o->hasOverflowClip())
offset -= toRenderBox(o)->scrolledContentOffset();
@@ -2325,13 +2527,13 @@ LayoutSize RenderObject::offsetFromContainer(RenderObject* o, const LayoutPoint&
return offset;
}
-LayoutSize RenderObject::offsetFromAncestorContainer(RenderObject* container) const
+LayoutSize RenderObject::offsetFromAncestorContainer(const RenderObject* container) const
{
LayoutSize offset;
LayoutPoint referencePoint;
const RenderObject* currContainer = this;
do {
- RenderObject* nextContainer = currContainer->container();
+ const RenderObject* nextContainer = currContainer->container();
ASSERT(nextContainer); // This means we reached the top without finding container.
if (!nextContainer)
break;
@@ -2362,21 +2564,15 @@ void RenderObject::computeLayerHitTestRects(LayerHitTestRects& layerRects) const
if (!hasLayer()) {
RenderObject* container = this->container();
- if (container) {
- currentLayer = container->enclosingLayer();
- if (currentLayer && currentLayer->renderer() != container) {
- layerOffset.move(container->offsetFromAncestorContainer(currentLayer->renderer()));
- // If the layer itself is scrolled, we have to undo the subtraction of its scroll
- // offset since we want the offset relative to the scrolling content, not the
- // element itself.
- if (currentLayer->renderer()->hasOverflowClip())
- layerOffset.move(currentLayer->renderBox()->scrolledContentOffset());
- }
- } else {
- currentLayer = enclosingLayer();
+ currentLayer = container->enclosingLayer();
+ if (container && currentLayer->renderer() != container) {
+ layerOffset.move(container->offsetFromAncestorContainer(currentLayer->renderer()));
+ // If the layer itself is scrolled, we have to undo the subtraction of its scroll
+ // offset since we want the offset relative to the scrolling content, not the
+ // element itself.
+ if (currentLayer->renderer()->hasOverflowClip())
+ layerOffset.move(currentLayer->renderBox()->scrolledContentOffset());
}
- if (!currentLayer)
- return;
}
this->addLayerHitTestRects(layerRects, currentLayer, layerOffset, LayoutRect());
@@ -2401,12 +2597,15 @@ void RenderObject::addLayerHitTestRects(LayerHitTestRects& layerRects, const Ren
const size_t maxRectsPerLayer = 100;
LayerHitTestRects::iterator iter = layerRects.find(currentLayer);
+ Vector<WebCore::LayoutRect>* iterValue;
if (iter == layerRects.end())
- iter = layerRects.add(currentLayer, Vector<LayoutRect>()).iterator;
+ iterValue = &layerRects.add(currentLayer, Vector<LayoutRect>()).storedValue->value;
+ else
+ iterValue = &iter->value;
for (size_t i = 0; i < ownRects.size(); i++) {
if (!containerRect.contains(ownRects[i])) {
- iter->value.append(ownRects[i]);
- if (iter->value.size() > maxRectsPerLayer) {
+ iterValue->append(ownRects[i]);
+ if (iterValue->size() > maxRectsPerLayer) {
// Just mark the entire layer instead, and switch to walking the layer
// tree instead of the render tree.
layerRects.remove(currentLayer);
@@ -2428,31 +2627,26 @@ void RenderObject::addLayerHitTestRects(LayerHitTestRects& layerRects, const Ren
// partially redundant rectangles. If we find examples where this is expensive, then we could
// rewrite Region to be more efficient. See https://bugs.webkit.org/show_bug.cgi?id=100814.
if (!isRenderView()) {
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) {
+ for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling()) {
curr->addLayerHitTestRects(layerRects, currentLayer, layerOffset, newContainerRect);
}
}
}
-bool RenderObject::isRooted(RenderView** view) const
+bool RenderObject::isRooted() const
{
- const RenderObject* o = this;
- while (o->parent())
- o = o->parent();
-
- if (!o->isRenderView())
- return false;
-
- if (view)
- *view = const_cast<RenderView*>(toRenderView(o));
-
- return true;
+ const RenderObject* object = this;
+ while (object->parent() && !object->hasLayer())
+ object = object->parent();
+ if (object->hasLayer())
+ return toRenderLayerModelObject(object)->layer()->root()->isRootLayer();
+ return false;
}
RenderObject* RenderObject::rendererForRootBackground()
{
- ASSERT(isRoot());
- if (!hasBackground() && node() && isHTMLHtmlElement(node())) {
+ ASSERT(isDocumentElement());
+ if (!hasBackground() && isHTMLHtmlElement(node())) {
// Locate the <body> element using the DOM. This is easier than trying
// to crawl around a render tree with potential :before/:after content and
// anonymous blocks created by inline <body> tags etc. We can locate the <body>
@@ -2471,7 +2665,7 @@ RespectImageOrientationEnum RenderObject::shouldRespectImageOrientation() const
// Respect the image's orientation if it's being used as a full-page image or it's
// an <img> and the setting to respect it everywhere is set.
return document().isImageDocument()
- || (document().settings() && document().settings()->shouldRespectImageOrientation() && node() && node()->hasTagName(HTMLNames::imgTag)) ? RespectImageOrientation : DoNotRespectImageOrientation;
+ || (document().settings() && document().settings()->shouldRespectImageOrientation() && isHTMLImageElement(node())) ? RespectImageOrientation : DoNotRespectImageOrientation;
}
bool RenderObject::hasOutlineAnnotation() const
@@ -2484,10 +2678,10 @@ bool RenderObject::hasEntirelyFixedBackground() const
return m_style->hasEntirelyFixedBackground();
}
-RenderObject* RenderObject::container(const RenderLayerModelObject* repaintContainer, bool* repaintContainerSkipped) const
+RenderObject* RenderObject::container(const RenderLayerModelObject* paintInvalidationContainer, bool* paintInvalidationContainerSkipped) const
{
- if (repaintContainerSkipped)
- *repaintContainerSkipped = false;
+ if (paintInvalidationContainerSkipped)
+ *paintInvalidationContainerSkipped = false;
// This method is extremely similar to containingBlock(), but with a few notable
// exceptions.
@@ -2505,7 +2699,7 @@ RenderObject* RenderObject::container(const RenderLayerModelObject* repaintConta
EPosition pos = m_style->position();
if (pos == FixedPosition) {
- return containerForFixedPosition(repaintContainer, repaintContainerSkipped);
+ return containerForFixedPosition(paintInvalidationContainer, paintInvalidationContainerSkipped);
} else if (pos == AbsolutePosition) {
// We technically just want our containing block, but
// we may not have one if we're part of an uninstalled
@@ -2517,8 +2711,8 @@ RenderObject* RenderObject::container(const RenderLayerModelObject* repaintConta
if (o->canContainFixedPositionObjects())
break;
- if (repaintContainerSkipped && o == repaintContainer)
- *repaintContainerSkipped = true;
+ if (paintInvalidationContainerSkipped && o == paintInvalidationContainer)
+ *paintInvalidationContainerSkipped = true;
o = o->parent();
}
@@ -2543,7 +2737,7 @@ inline void RenderObject::clearLayoutRootIfNeeded() const
// This indicates a failure to layout the child, which is why
// the layout root is still set to |this|. Make sure to clear it
// since we are getting destroyed.
- view->clearLayoutRoot();
+ view->clearLayoutSubtreeRoot();
}
}
}
@@ -2557,10 +2751,9 @@ void RenderObject::willBeDestroyed()
children->destroyLeftoverChildren();
// If this renderer is being autoscrolled, stop the autoscrolling.
- if (Frame* frame = this->frame()) {
+ if (LocalFrame* frame = this->frame()) {
if (frame->page())
frame->page()->autoscrollController().stopAutoscrollIfNeeded(this);
- frame->animation().cancelAnimations(this);
}
// For accessibility management, notify the parent of the imminent change to its child set.
@@ -2575,18 +2768,6 @@ void RenderObject::willBeDestroyed()
if (AXObjectCache* cache = document().existingAXObjectCache())
cache->remove(this);
-#ifndef NDEBUG
- if (!documentBeingDestroyed() && view() && view()->hasRenderNamedFlowThreads()) {
- // After remove, the object and the associated information should not be in any flow thread.
- const RenderNamedFlowThreadList* flowThreadList = view()->flowThreadController()->renderNamedFlowThreadList();
- for (RenderNamedFlowThreadList::const_iterator iter = flowThreadList->begin(); iter != flowThreadList->end(); ++iter) {
- const RenderNamedFlowThread* renderFlowThread = *iter;
- ASSERT(!renderFlowThread->hasChild(this));
- ASSERT(!renderFlowThread->hasChildInfo(this));
- }
- }
-#endif
-
// If this renderer had a parent, remove should have destroyed any counters
// attached to this renderer and marked the affected other counters for
// reevaluation. This apparently redundant check is here for the case when
@@ -2595,6 +2776,13 @@ void RenderObject::willBeDestroyed()
if (hasCounterNodeMap())
RenderCounter::destroyCounterNodes(*this);
+ // Remove the handler if node had touch-action set. Don't call when
+ // document is being destroyed as all handlers will have been cleared
+ // previously. Handlers are not added for text nodes so don't try removing
+ // for one too. Need to check if m_style is null in cases of partial construction.
+ if (!documentBeingDestroyed() && node() && !node()->isTextNode() && m_style && m_style->touchAction() != TouchActionAuto)
+ document().didRemoveTouchEventHandler(node());
+
setAncestorLineBoxDirty(false);
clearLayoutRootIfNeeded();
@@ -2607,7 +2795,7 @@ void RenderObject::insertedIntoTree()
// Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
// and don't have a layer attached to ourselves.
RenderLayer* layer = 0;
- if (firstChild() || hasLayer()) {
+ if (slowFirstChild() || hasLayer()) {
layer = parent()->enclosingLayer();
addLayers(layer);
}
@@ -2623,9 +2811,6 @@ void RenderObject::insertedIntoTree()
if (!isFloating() && parent()->childrenInline())
parent()->dirtyLinesFromChangedChild(this);
-
- if (RenderNamedFlowThread* containerFlowThread = parent()->renderNamedFlowThreadWrapper())
- containerFlowThread->addFlowChild(this);
}
void RenderObject::willBeRemovedFromTree()
@@ -2635,12 +2820,13 @@ void RenderObject::willBeRemovedFromTree()
// If we remove a visible child from an invisible parent, we don't know the layer visibility any more.
RenderLayer* layer = 0;
if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
- if ((layer = parent()->enclosingLayer()))
+ layer = parent()->enclosingLayer();
+ if (layer)
layer->dirtyVisibleContentStatus();
}
// Keep our layer hierarchy updated.
- if (firstChild() || hasLayer()) {
+ if (slowFirstChild() || hasLayer()) {
if (!layer)
layer = parent()->enclosingLayer();
removeLayers(layer);
@@ -2651,11 +2837,9 @@ void RenderObject::willBeRemovedFromTree()
removeFromRenderFlowThread();
- if (RenderNamedFlowThread* containerFlowThread = parent()->renderNamedFlowThreadWrapper())
- containerFlowThread->removeFlowChild(this);
-
// Update cached boundaries in SVG renderers if a child is removed.
- parent()->setNeedsBoundariesUpdate();
+ if (parent()->isSVG())
+ parent()->setNeedsBoundariesUpdate();
}
void RenderObject::removeFromRenderFlowThread()
@@ -2677,11 +2861,6 @@ void RenderObject::removeFromRenderFlowThreadRecursive(RenderFlowThread* renderF
child->removeFromRenderFlowThreadRecursive(renderFlowThread);
}
- RenderFlowThread* localFlowThread = renderFlowThread;
- if (flowThreadState() == InsideInFlowThread)
- localFlowThread = flowThreadContainingBlock(); // We have to ask. We can't just assume we are in the same flow thread.
- if (localFlowThread)
- localFlowThread->removeFlowChildInfo(this);
setFlowThreadState(NotInsideFlowThread);
}
@@ -2703,7 +2882,7 @@ void RenderObject::destroyAndCleanupAnonymousWrappers()
if (destroyRootParent->isRenderFlowThread() || destroyRootParent->isAnonymousColumnSpanBlock())
break;
- if (destroyRootParent->firstChild() != this || destroyRootParent->lastChild() != this)
+ if (destroyRootParent->slowFirstChild() != this || destroyRootParent->slowLastChild() != this)
break;
}
@@ -2712,6 +2891,12 @@ void RenderObject::destroyAndCleanupAnonymousWrappers()
// WARNING: |this| is deleted here.
}
+void RenderObject::destroy()
+{
+ willBeDestroyed();
+ postDestroy();
+}
+
void RenderObject::removeShapeImageClient(ShapeValue* shapeValue)
{
if (!shapeValue)
@@ -2720,12 +2905,6 @@ void RenderObject::removeShapeImageClient(ShapeValue* shapeValue)
shapeImage->removeClient(this);
}
-void RenderObject::destroy()
-{
- willBeDestroyed();
- postDestroy();
-}
-
void RenderObject::postDestroy()
{
// It seems ugly that this is not in willBeDestroyed().
@@ -2746,7 +2925,6 @@ void RenderObject::postDestroy()
if (StyleImage* maskBoxImage = m_style->maskBoxImage().image())
maskBoxImage->removeClient(this);
- removeShapeImageClient(m_style->shapeInside());
removeShapeImageClient(m_style->shapeOutside());
}
@@ -2762,9 +2940,13 @@ void RenderObject::updateDragState(bool dragOn)
{
bool valueChanged = (dragOn != isDragging());
setIsDragging(dragOn);
- if (valueChanged && node() && (style()->affectedByDrag() || (node()->isElementNode() && toElement(node())->childrenAffectedByDrag())))
- node()->setNeedsStyleRecalc();
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
+ if (valueChanged && node()) {
+ if (node()->isElementNode() && toElement(node())->childrenOrSiblingsAffectedByDrag())
+ node()->setNeedsStyleRecalc(SubtreeStyleChange);
+ else if (style()->affectedByDrag())
+ node()->setNeedsStyleRecalc(LocalStyleChange);
+ }
+ for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling())
curr->updateDragState(dragOn);
}
@@ -2773,6 +2955,11 @@ CompositingState RenderObject::compositingState() const
return hasLayer() ? toRenderLayerModelObject(this)->layer()->compositingState() : NotComposited;
}
+CompositingReasons RenderObject::additionalCompositingReasons(CompositingTriggerFlags) const
+{
+ return CompositingReasonNone;
+}
+
bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
{
bool inside = false;
@@ -2839,35 +3026,10 @@ void RenderObject::scheduleRelayout()
}
}
-void RenderObject::layout()
-{
- ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
- RenderObject* child = firstChild();
- while (child) {
- child->layoutIfNeeded();
- ASSERT(!child->needsLayout());
- child = child->nextSibling();
- }
- clearNeedsLayout();
-}
-
-void RenderObject::didLayout(ResourceLoadPriorityOptimizer& priorityModifier)
-{
- for (RenderObject* child = firstChild(); child; child = child->nextSibling())
- child->didLayout(priorityModifier);
-}
-
-void RenderObject::didScroll(ResourceLoadPriorityOptimizer& priorityModifier)
-{
- for (RenderObject* child = firstChild(); child; child = child->nextSibling())
- child->didScroll(priorityModifier);
-}
-
void RenderObject::forceLayout()
{
setSelfNeedsLayout(true);
- setShouldDoFullRepaintAfterLayout(true);
+ setShouldDoFullPaintInvalidationAfterLayout(true);
layout();
}
@@ -2907,13 +3069,13 @@ static PassRefPtr<RenderStyle> firstLineStyleForCachedUncachedType(StyleCacheSta
return rendererForFirstLineStyle->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE_INHERITED), parentStyle, style);
}
}
- return 0;
+ return nullptr;
}
PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const
{
if (!document().styleEngine()->usesFirstLineRules())
- return 0;
+ return nullptr;
ASSERT(!isText());
@@ -2948,20 +3110,19 @@ RenderStyle* RenderObject::getCachedPseudoStyle(PseudoId pseudo, RenderStyle* pa
PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, RenderStyle* ownStyle) const
{
if (pseudoStyleRequest.pseudoId < FIRST_INTERNAL_PSEUDOID && !ownStyle && !style()->hasPseudoStyle(pseudoStyleRequest.pseudoId))
- return 0;
+ return nullptr;
if (!parentStyle) {
ASSERT(!ownStyle);
parentStyle = style();
}
- // FIXME: This "find nearest element parent" should be a helper function.
- Node* n = node();
- while (n && !n->isElementNode())
- n = n->parentNode();
- if (!n)
- return 0;
- Element* element = toElement(n);
+ if (!node())
+ return nullptr;
+
+ Element* element = Traversal<Element>::firstAncestorOrSelf(*node());
+ if (!element)
+ return nullptr;
if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) {
RefPtr<RenderStyle> result = document().ensureStyleResolver().styleForElement(element, parentStyle, DisallowStyleSharing);
@@ -2972,54 +3133,56 @@ PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(const PseudoStyleRe
return document().ensureStyleResolver().pseudoStyleForElement(element, pseudoStyleRequest, parentStyle);
}
-bool RenderObject::hasBlendMode() const
+PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyleFromParentOrShadowHost() const
{
- return RuntimeEnabledFeatures::cssCompositingEnabled() && style() && style()->hasBlendMode();
-}
+ if (!node())
+ return nullptr;
-static Color decorationColor(const RenderObject* object, RenderStyle* style)
-{
- Color result;
- // Check for text decoration color first.
- result = object->resolveColor(style, CSSPropertyTextDecorationColor);
- if (result.isValid())
- return result;
- if (style->textStrokeWidth() > 0) {
- // Prefer stroke color if possible but not if it's fully transparent.
- result = object->resolveColor(style, CSSPropertyWebkitTextStrokeColor);
- if (result.alpha())
- return result;
+ if (ShadowRoot* root = node()->containingShadowRoot()) {
+ if (root->type() == ShadowRoot::UserAgentShadowRoot) {
+ if (Element* shadowHost = node()->shadowHost()) {
+ return shadowHost->renderer()->getUncachedPseudoStyle(PseudoStyleRequest(SELECTION));
+ }
+ }
}
- result = object->resolveColor(style, CSSPropertyWebkitTextFillColor);
- return result;
+ return getUncachedPseudoStyle(PseudoStyleRequest(SELECTION));
+}
+
+bool RenderObject::hasBlendMode() const
+{
+ return RuntimeEnabledFeatures::cssCompositingEnabled() && style() && style()->hasBlendMode();
}
-void RenderObject::getTextDecorationColors(unsigned decorations, Color& underline, Color& overline,
- Color& linethrough, bool quirksMode, bool firstlineStyle)
+void RenderObject::getTextDecorations(unsigned decorations, AppliedTextDecoration& underline, AppliedTextDecoration& overline, AppliedTextDecoration& linethrough, bool quirksMode, bool firstlineStyle)
{
RenderObject* curr = this;
RenderStyle* styleToUse = 0;
unsigned currDecs = TextDecorationNone;
Color resultColor;
+ TextDecorationStyle resultStyle;
do {
styleToUse = curr->style(firstlineStyle);
currDecs = styleToUse->textDecoration();
currDecs &= decorations;
- resultColor = decorationColor(this, styleToUse);
+ resultColor = styleToUse->visitedDependentDecorationColor();
+ resultStyle = styleToUse->textDecorationStyle();
// Parameter 'decorations' is cast as an int to enable the bitwise operations below.
if (currDecs) {
if (currDecs & TextDecorationUnderline) {
decorations &= ~TextDecorationUnderline;
- underline = resultColor;
+ underline.color = resultColor;
+ underline.style = resultStyle;
}
if (currDecs & TextDecorationOverline) {
decorations &= ~TextDecorationOverline;
- overline = resultColor;
+ overline.color = resultColor;
+ overline.style = resultStyle;
}
if (currDecs & TextDecorationLineThrough) {
decorations &= ~TextDecorationLineThrough;
- linethrough = resultColor;
+ linethrough.color = resultColor;
+ linethrough.style = resultStyle;
}
}
if (curr->isRubyText())
@@ -3027,18 +3190,24 @@ void RenderObject::getTextDecorationColors(unsigned decorations, Color& underlin
curr = curr->parent();
if (curr && curr->isAnonymousBlock() && toRenderBlock(curr)->continuation())
curr = toRenderBlock(curr)->continuation();
- } while (curr && decorations && (!quirksMode || !curr->node() || (!isHTMLAnchorElement(curr->node()) && !curr->node()->hasTagName(fontTag))));
+ } while (curr && decorations && (!quirksMode || !curr->node() || (!isHTMLAnchorElement(*curr->node()) && !isHTMLFontElement(*curr->node()))));
// If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
if (decorations && curr) {
styleToUse = curr->style(firstlineStyle);
- resultColor = decorationColor(this, styleToUse);
- if (decorations & TextDecorationUnderline)
- underline = resultColor;
- if (decorations & TextDecorationOverline)
- overline = resultColor;
- if (decorations & TextDecorationLineThrough)
- linethrough = resultColor;
+ resultColor = styleToUse->visitedDependentDecorationColor();
+ if (decorations & TextDecorationUnderline) {
+ underline.color = resultColor;
+ underline.style = resultStyle;
+ }
+ if (decorations & TextDecorationOverline) {
+ overline.color = resultColor;
+ overline.style = resultStyle;
+ }
+ if (decorations & TextDecorationLineThrough) {
+ linethrough.color = resultColor;
+ linethrough.style = resultStyle;
+ }
}
}
@@ -3052,7 +3221,7 @@ void RenderObject::addAnnotatedRegions(Vector<AnnotatedRegionValue>& regions)
return;
RenderBox* box = toRenderBox(this);
- FloatRect localBounds(FloatPoint(), FloatSize(box->width(), box->height()));
+ FloatRect localBounds(FloatPoint(), FloatSize(box->width().toFloat(), box->height().toFloat()));
FloatRect absBounds = localToAbsoluteQuad(localBounds).boundingBox();
AnnotatedRegionValue region;
@@ -3069,7 +3238,7 @@ void RenderObject::collectAnnotatedRegions(Vector<AnnotatedRegionValue>& regions
return;
addAnnotatedRegions(regions);
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
+ for (RenderObject* curr = slowFirstChild(); curr; curr = curr->nextSibling())
curr->collectAnnotatedRegions(regions);
}
@@ -3085,14 +3254,7 @@ bool RenderObject::willRenderImage(ImageResource*)
// If we're not in a window (i.e., we're dormant from being in a background tab)
// then we don't want to render either.
- return !document().view()->isOffscreen();
-}
-
-int RenderObject::maximalOutlineSize(PaintPhase p) const
-{
- if (p != PaintPhaseOutline && p != PaintPhaseSelfOutline && p != PaintPhaseChildOutlines)
- return 0;
- return view()->maximalOutlineSize();
+ return document().view()->isVisible();
}
int RenderObject::caretMinOffset() const
@@ -3103,7 +3265,7 @@ int RenderObject::caretMinOffset() const
int RenderObject::caretMaxOffset() const
{
if (isReplaced())
- return node() ? max(1U, node()->childNodeCount()) : 1;
+ return node() ? max(1U, node()->countChildren()) : 1;
if (isHR())
return 1;
return 0;
@@ -3124,22 +3286,6 @@ int RenderObject::nextOffset(int current) const
return current + 1;
}
-void RenderObject::adjustRectForOutlineAndShadow(LayoutRect& rect) const
-{
- int outlineSize = outlineStyleForRepaint()->outlineSize();
- if (const ShadowList* boxShadow = style()->boxShadow()) {
- boxShadow->adjustRectForShadow(rect, outlineSize);
- return;
- }
-
- rect.inflate(outlineSize);
-}
-
-AnimationController& RenderObject::animation() const
-{
- return frame()->animation();
-}
-
bool RenderObject::isInert() const
{
const RenderObject* renderer = this;
@@ -3148,41 +3294,28 @@ bool RenderObject::isInert() const
return renderer->node()->isInert();
}
-void RenderObject::imageChanged(ImageResource* image, const IntRect* rect)
+// touch-action applies to all elements with both width AND height properties.
+// According to the CSS Box Model Spec (http://dev.w3.org/csswg/css-box/#the-width-and-height-properties)
+// width applies to all elements but non-replaced inline elements, table rows, and row groups and
+// height applies to all elements but non-replaced inline elements, table columns, and column groups.
+bool RenderObject::supportsTouchAction() const
{
- imageChanged(static_cast<WrappedImagePtr>(image), rect);
+ if (isInline() && !isReplaced())
+ return false;
+ if (isTableRow() || isRenderTableCol())
+ return false;
+
+ return true;
}
-RenderObject* RenderObject::hoverAncestor() const
+void RenderObject::imageChanged(ImageResource* image, const IntRect* rect)
{
- // When searching for the hover ancestor and encountering a named flow thread,
- // the search will continue with the DOM ancestor of the top-most element
- // in the named flow thread.
- // See https://code.google.com/p/chromium/issues/detail?id=243278
- RenderObject* hoverAncestor = parent();
-
- // Skip anonymous blocks directly flowed into flow threads as it would
- // prevent us from continuing the search on the DOM tree when reaching the named flow thread.
- if (hoverAncestor && hoverAncestor->isAnonymousBlock() && hoverAncestor->parent() && hoverAncestor->parent()->isRenderNamedFlowThread())
- hoverAncestor = hoverAncestor->parent();
-
- if (hoverAncestor && hoverAncestor->isRenderNamedFlowThread()) {
- hoverAncestor = 0;
-
- Node* node = this->node();
- if (node) {
- Node* domAncestorNode = node->parentNode();
- if (domAncestorNode)
- hoverAncestor = domAncestorNode->renderer();
- }
- }
-
- return hoverAncestor;
+ imageChanged(static_cast<WrappedImagePtr>(image), rect);
}
Element* RenderObject::offsetParent() const
{
- if (isRoot() || isBody())
+ if (isDocumentElement() || isBody())
return 0;
if (isOutOfFlowPositioned() && style()->position() == FixedPosition)
@@ -3197,10 +3330,6 @@ Element* RenderObject::offsetParent() const
for (RenderObject* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
// Spec: http://www.w3.org/TR/cssom-view/#offset-attributes
- // CSS regions specification says that region flows should return the body element as their offsetParent.
- if (ancestor->isRenderNamedFlowThread())
- return document().body();
-
node = ancestor->node();
if (!node)
@@ -3209,10 +3338,10 @@ Element* RenderObject::offsetParent() const
if (ancestor->isPositioned())
break;
- if (node->hasTagName(HTMLNames::bodyTag))
+ if (isHTMLBodyElement(*node))
break;
- if (!isPositioned() && (isHTMLTableElement(node) || node->hasTagName(tdTag) || node->hasTagName(thTag)))
+ if (!isPositioned() && (isHTMLTableElement(*node) || isHTMLTableCellElement(*node)))
break;
// Webkit specific extension where offsetParent stops at zoom level changes.
@@ -3329,7 +3458,7 @@ FloatRect RenderObject::strokeBoundingBox() const
// Returns the smallest rectangle enclosing all of the painted content
// respecting clipping, masking, filters, opacity, stroke-width and markers
-FloatRect RenderObject::repaintRectInLocalCoordinates() const
+FloatRect RenderObject::paintInvalidationRectInLocalCoordinates() const
{
ASSERT_NOT_REACHED();
return FloatRect();
@@ -3353,25 +3482,35 @@ bool RenderObject::nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const
return false;
}
-// FIXME: This should really use local coords
-// Works on absolute coords - expensive to call
-bool RenderObject::isContainedInParentBoundingBox() const
+bool RenderObject::isRelayoutBoundaryForInspector() const
{
- if (!parent())
- return false;
+ return objectIsRelayoutBoundary(this);
+}
+
+void RenderObject::clearPaintInvalidationState()
+{
+ setShouldDoFullPaintInvalidationAfterLayout(false);
+ setShouldDoFullPaintInvalidationIfSelfPaintingLayer(false);
+ setOnlyNeededPositionedMovementLayout(false);
+ setShouldInvalidateOverflowForPaint(false);
+ setLayoutDidGetCalled(false);
+ setMayNeedPaintInvalidation(false);
+}
- IntRect parentRect = parent()->absoluteBoundingBoxRect();
- return parentRect.contains(absoluteBoundingBoxRect());
+bool RenderObject::isAllowedToModifyRenderTreeStructure(Document& document)
+{
+ return DeprecatedDisableModifyRenderTreeStructureAsserts::canModifyRenderTreeStateInAnyState()
+ || document.lifecycle().stateAllowsRenderTreeMutations();
}
-bool RenderObject::isRelayoutBoundaryForInspector() const
+DeprecatedDisableModifyRenderTreeStructureAsserts::DeprecatedDisableModifyRenderTreeStructureAsserts()
+ : m_disabler(gModifyRenderTreeStructureAnyState, true)
{
- return objectIsRelayoutBoundary(this);
}
-bool RenderObject::isRenderNamedFlowFragmentContainer() const
+bool DeprecatedDisableModifyRenderTreeStructureAsserts::canModifyRenderTreeStateInAnyState()
{
- return isRenderBlockFlow() && toRenderBlockFlow(this)->renderNamedFlowFragment();
+ return gModifyRenderTreeStructureAnyState;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderObject.h b/chromium/third_party/WebKit/Source/core/rendering/RenderObject.h
index 37044c4e86d..11ca5569050 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderObject.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderObject.h
@@ -26,48 +26,42 @@
#ifndef RenderObject_h
#define RenderObject_h
+#include "core/dom/DocumentLifecycle.h"
#include "core/dom/Element.h"
#include "core/dom/Position.h"
#include "core/dom/StyleEngine.h"
#include "core/fetch/ImageResourceClient.h"
-#include "core/rendering/CompositingState.h"
-#include "core/rendering/LayoutIndicator.h"
+#include "core/rendering/compositing/CompositingState.h"
#include "core/rendering/PaintPhase.h"
#include "core/rendering/RenderObjectChildList.h"
-#include "core/rendering/ScrollBehavior.h"
+#include "core/rendering/ScrollAlignment.h"
#include "core/rendering/SubtreeLayoutScope.h"
+#include "core/rendering/compositing/CompositingTriggers.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/StyleInheritedData.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/LayoutRect.h"
+#include "platform/graphics/CompositingReasons.h"
#include "platform/transforms/TransformationMatrix.h"
namespace WebCore {
class AffineTransform;
-class AnimationController;
class Cursor;
class Document;
class HitTestLocation;
class HitTestResult;
class InlineBox;
class InlineFlowBox;
-class Path;
class Position;
class PseudoStyleRequest;
class RenderBoxModelObject;
-class RenderInline;
class RenderBlock;
class RenderFlowThread;
class RenderGeometryMap;
class RenderLayer;
class RenderLayerModelObject;
-class RenderNamedFlowThread;
-class RenderSVGResourceContainer;
-class RenderTable;
-class RenderTheme;
class RenderView;
-class ResourceLoadPriorityOptimizer;
class TransformState;
struct PaintInfo;
@@ -113,6 +107,21 @@ enum MapCoordinatesMode {
};
typedef unsigned MapCoordinatesFlags;
+enum InvalidationReason {
+ InvalidationIncremental,
+ InvalidationSelfLayout,
+ InvalidationBorderFitLines,
+ InvalidationBorderRadius,
+ InvalidationBoundsChangeWithBackground,
+ InvalidationBoundsChange,
+ InvalidationLocationChange,
+ InvalidationScroll,
+ InvalidationSelection,
+ InvalidationLayer,
+ InvalidationPaint,
+ InvalidationPaintRectangle
+};
+
const int caretWidth = 1;
struct AnnotatedRegionValue {
@@ -135,10 +144,10 @@ const int showTreeCharacterOffset = 39;
class RenderObject : public ImageResourceClient {
friend class RenderBlock;
friend class RenderBlockFlow;
- friend class RenderLayer; // For setParent.
friend class RenderLayerReflectionInfo; // For setParent
friend class RenderLayerScrollableArea; // For setParent.
friend class RenderObjectChildList;
+ WTF_MAKE_NONCOPYABLE(RenderObject);
public:
// Anonymous objects should pass the document as their node, and they will then automatically be
// marked as anonymous in the constructor.
@@ -155,18 +164,13 @@ public:
RenderObject* previousSibling() const { return m_previous; }
RenderObject* nextSibling() const { return m_next; }
- // FIXME: These should be renamed slowFirstChild, slowLastChild, etc.
- // to discourage their use. The virtualChildren() call inside these
- // can be slow for hot code paths.
- // Currently, some subclasses like RenderBlock, override these NON-virtual
- // functions to make these fast when we already have a more specific pointer type.
- RenderObject* firstChild() const
+ RenderObject* slowFirstChild() const
{
if (const RenderObjectChildList* children = virtualChildren())
return children->firstChild();
return 0;
}
- RenderObject* lastChild() const
+ RenderObject* slowLastChild() const
{
if (const RenderObjectChildList* children = virtualChildren())
return children->lastChild();
@@ -213,10 +217,6 @@ public:
return locateFlowThreadContainingBlock();
}
- RenderNamedFlowThread* renderNamedFlowThreadWrapper() const;
-
- virtual bool isEmpty() const { return firstChild() == 0; }
-
#ifndef NDEBUG
void setHasAXObject(bool flag) { m_hasAXObject = flag; }
bool hasAXObject() const { return m_hasAXObject; }
@@ -224,10 +224,10 @@ public:
// Helper class forbidding calls to setNeedsLayout() during its lifetime.
class SetLayoutNeededForbiddenScope {
public:
- explicit SetLayoutNeededForbiddenScope(RenderObject*);
+ explicit SetLayoutNeededForbiddenScope(RenderObject&);
~SetLayoutNeededForbiddenScope();
private:
- RenderObject* m_renderObject;
+ RenderObject& m_renderObject;
bool m_preexistingForbidden;
};
@@ -291,10 +291,13 @@ private:
#endif
void addAbsoluteRectForLayer(LayoutRect& result);
- void setLayerNeedsFullRepaint();
- void setLayerNeedsFullRepaintForPositionedMovementLayout();
+ void setLayerNeedsFullPaintInvalidationForPositionedMovementLayout();
bool requiresAnonymousTableWrappers(const RenderObject*) const;
+ // Gets pseudoStyle from Shadow host(in case of input elements)
+ // or from Parent element.
+ PassRefPtr<RenderStyle> getUncachedPseudoStyleFromParentOrShadowHost() const;
+
public:
#ifndef NDEBUG
void showTreeForThis() const;
@@ -317,11 +320,10 @@ public:
public:
bool isPseudoElement() const { return node() && node()->isPseudoElement(); }
- virtual bool isBR() const { return false; }
virtual bool isBoxModelObject() const { return false; }
+ virtual bool isBR() const { return false; }
+ virtual bool isCanvas() const { return false; }
virtual bool isCounter() const { return false; }
- virtual bool isQuote() const { return false; }
-
virtual bool isDetailsMarker() const { return false; }
virtual bool isEmbeddedObject() const { return false; }
virtual bool isFieldset() const { return false; }
@@ -339,56 +341,44 @@ public:
virtual bool isMenuList() const { return false; }
virtual bool isMeter() const { return false; }
virtual bool isProgress() const { return false; }
+ virtual bool isQuote() const { return false; }
virtual bool isRenderBlock() const { return false; }
virtual bool isRenderBlockFlow() const { return false; }
- virtual bool isRenderSVGBlock() const { return false; };
virtual bool isRenderButton() const { return false; }
+ virtual bool isRenderFlowThread() const { return false; }
+ virtual bool isRenderFullScreen() const { return false; }
+ virtual bool isRenderFullScreenPlaceholder() const { return false; }
+ virtual bool isRenderGrid() const { return false; }
virtual bool isRenderIFrame() const { return false; }
virtual bool isRenderImage() const { return false; }
virtual bool isRenderInline() const { return false; }
+ virtual bool isRenderMultiColumnSet() const { return false; }
virtual bool isRenderPart() const { return false; }
virtual bool isRenderRegion() const { return false; }
- virtual bool isRenderNamedFlowFragment() const { return false; }
+ virtual bool isRenderScrollbarPart() const { return false; }
+ virtual bool isRenderTableCol() const { return false; }
virtual bool isRenderView() const { return false; }
virtual bool isReplica() const { return false; }
-
virtual bool isRuby() const { return false; }
virtual bool isRubyBase() const { return false; }
virtual bool isRubyRun() const { return false; }
virtual bool isRubyText() const { return false; }
-
virtual bool isSlider() const { return false; }
virtual bool isSliderThumb() const { return false; }
virtual bool isTable() const { return false; }
- virtual bool isTableCell() const { return false; }
- virtual bool isRenderTableCol() const { return false; }
virtual bool isTableCaption() const { return false; }
+ virtual bool isTableCell() const { return false; }
virtual bool isTableRow() const { return false; }
virtual bool isTableSection() const { return false; }
- virtual bool isTextControl() const { return false; }
virtual bool isTextArea() const { return false; }
+ virtual bool isTextControl() const { return false; }
virtual bool isTextField() const { return false; }
virtual bool isVideo() const { return false; }
virtual bool isWidget() const { return false; }
- virtual bool isCanvas() const { return false; }
- virtual bool isRenderFullScreen() const { return false; }
- virtual bool isRenderFullScreenPlaceholder() const { return false; }
-
- virtual bool isRenderGrid() const { return false; }
-
- virtual bool isRenderFlowThread() const { return false; }
- virtual bool isRenderNamedFlowThread() const { return false; }
- bool isInFlowRenderFlowThread() const { return isRenderFlowThread() && !isOutOfFlowPositioned(); }
- bool isOutOfFlowRenderFlowThread() const { return isRenderFlowThread() && isOutOfFlowPositioned(); }
- bool isRenderNamedFlowFragmentContainer() const;
-
- virtual bool isRenderMultiColumnBlock() const { return false; }
- virtual bool isRenderMultiColumnSet() const { return false; }
-
- virtual bool isRenderScrollbarPart() const { return false; }
- bool isRoot() const { return document().documentElement() == m_node; }
- bool isBody() const;
+ bool isDocumentElement() const { return document().documentElement() == m_node; }
+ // isBody is called from RenderBox::styleWillChange and is thus quite hot.
+ bool isBody() const { return node() && node()->hasTagName(HTMLNames::bodyTag); }
bool isHR() const;
bool isLegend() const;
@@ -413,7 +403,7 @@ public:
{
m_bitfields.setAncestorLineBoxDirty(value);
if (value)
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
}
enum FlowThreadState {
@@ -429,6 +419,7 @@ public:
// FIXME: Until all SVG renders can be subclasses of RenderSVGModelObject we have
// to add SVG renderer methods to RenderObject with an ASSERT_NOT_REACHED() default implementation.
+ virtual bool isSVG() const { return false; }
virtual bool isSVGRoot() const { return false; }
virtual bool isSVGContainer() const { return false; }
virtual bool isSVGTransformableContainer() const { return false; }
@@ -452,7 +443,6 @@ public:
// to inherit from RenderSVGObject -> RenderObject (some need RenderBlock inheritance for instance)
virtual void setNeedsTransformUpdate() { }
virtual void setNeedsBoundariesUpdate();
- virtual bool needsBoundariesUpdate() { return false; }
// Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects, opacity and stroke-width.
// This is used for all computation of objectBoundingBox relative units and by SVGLocatable::getBBox().
@@ -465,7 +455,7 @@ public:
// Returns the smallest rectangle enclosing all of the painted content
// respecting clipping, masking, filters, opacity, stroke-width and markers
- virtual FloatRect repaintRectInLocalCoordinates() const;
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const;
// This only returns the transform="" value from the element
// most callsites want localToParentTransform() instead.
@@ -476,7 +466,7 @@ public:
virtual const AffineTransform& localToParentTransform() const;
// SVG uses FloatPoint precise hit testing, and passes the point in parent
- // coordinates instead of in repaint container coordinates. Eventually the
+ // coordinates instead of in paint invalidaiton container coordinates. Eventually the
// rest of the rendering tree will move to a similar model.
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
@@ -529,8 +519,11 @@ public:
};
bool hasBoxDecorations() const { return m_bitfields.boxDecorationState() != NoBoxDecorations; }
bool backgroundIsKnownToBeObscured();
- bool borderImageIsLoadedAndCanBeRendered() const;
- bool mustRepaintBackgroundOrBorder() const;
+ bool canRenderBorderImage() const;
+ bool mustInvalidateBackgroundOrBorderPaintOnWidthChange() const;
+ bool mustInvalidateBackgroundOrBorderPaintOnHeightChange() const;
+ bool mustInvalidateFillLayersPaintOnWidthChange(const FillLayer&) const;
+ bool mustInvalidateFillLayersPaintOnHeightChange(const FillLayer&) const;
bool hasBackground() const { return style()->hasBackground(); }
bool hasEntirelyFixedBackground() const;
@@ -554,6 +547,10 @@ public:
bool preferredLogicalWidthsDirty() const { return m_bitfields.preferredLogicalWidthsDirty(); }
+ bool needsOverflowRecalcAfterStyleChange() const { return m_bitfields.selfNeedsOverflowRecalcAfterStyleChange() || m_bitfields.childNeedsOverflowRecalcAfterStyleChange(); }
+ bool selfNeedsOverflowRecalcAfterStyleChange() const { return m_bitfields.selfNeedsOverflowRecalcAfterStyleChange(); }
+ bool childNeedsOverflowRecalcAfterStyleChange() const { return m_bitfields.childNeedsOverflowRecalcAfterStyleChange(); }
+
bool isSelectionBorder() const;
bool hasClip() const { return isOutOfFlowPositioned() && style()->hasClip(); }
@@ -569,6 +566,8 @@ public:
bool hasBlendMode() const;
+ bool hasShapeOutside() const { return style() && style()->shapeOutside(); }
+
inline bool preservesNewline() const;
// The pseudo element style can be cached or uncached. Use the cached method if the pseudo element doesn't respect
@@ -581,8 +580,7 @@ public:
RenderView* view() const { return document().renderView(); };
FrameView* frameView() const { return document().view(); };
- // Returns true if this renderer is rooted, and optionally returns the hosting view (the root of the hierarchy).
- bool isRooted(RenderView** = 0) const;
+ bool isRooted() const;
Node* node() const
{
@@ -591,7 +589,6 @@ public:
Node* nonPseudoNode() const
{
- ASSERT(!LayoutIndicator::inLayout());
return isPseudoElement() ? 0 : node();
}
@@ -604,26 +601,26 @@ public:
Node* generatingNode() const { return isPseudoElement() ? node()->parentOrShadowHostNode() : node(); }
Document& document() const { return m_node->document(); }
- Frame* frame() const { return document().frame(); }
+ LocalFrame* frame() const { return document().frame(); }
bool hasOutlineAnnotation() const;
bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); }
// Returns the object containing this one. Can be different from parent for positioned elements.
- // If repaintContainer and repaintContainerSkipped are not null, on return *repaintContainerSkipped
- // is true if the renderer returned is an ancestor of repaintContainer.
- RenderObject* container(const RenderLayerModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const;
+ // If paintInvalidationContainer and paintInvalidationContainerSkipped are not null, on return *paintInvalidationContainerSkipped
+ // is true if the renderer returned is an ancestor of paintInvalidationContainer.
+ RenderObject* container(const RenderLayerModelObject* paintInvalidationContainer = 0, bool* paintInvalidationContainerSkipped = 0) const;
- virtual RenderObject* hoverAncestor() const;
+ virtual RenderObject* hoverAncestor() const { return parent(); }
Element* offsetParent() const;
void markContainingBlocksForLayout(bool scheduleRelayout = true, RenderObject* newRoot = 0, SubtreeLayoutScope* = 0);
void setNeedsLayout(MarkingBehavior = MarkContainingBlockChain, SubtreeLayoutScope* = 0);
+ void setNeedsLayoutAndFullPaintInvalidation(MarkingBehavior = MarkContainingBlockChain, SubtreeLayoutScope* = 0);
void clearNeedsLayout();
void setChildNeedsLayout(MarkingBehavior = MarkContainingBlockChain, SubtreeLayoutScope* = 0);
void setNeedsPositionedMovementLayout();
- void setNeedsSimplifiedNormalFlowLayout();
void setPreferredLogicalWidthsDirty(MarkingBehavior = MarkContainingBlockChain);
void clearPreferredLogicalWidthsDirty();
void invalidateContainerPreferredLogicalWidths();
@@ -633,6 +630,11 @@ public:
setNeedsLayout();
setPreferredLogicalWidthsDirty();
}
+ void setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation()
+ {
+ setNeedsLayoutAndFullPaintInvalidation();
+ setPreferredLogicalWidthsDirty();
+ }
void setPositionState(EPosition position)
{
@@ -665,10 +667,12 @@ public:
virtual void paint(PaintInfo&, const LayoutPoint&);
- // Recursive function that computes the size and position of this object and all its descendants.
- virtual void layout();
- virtual void didLayout(ResourceLoadPriorityOptimizer&);
- virtual void didScroll(ResourceLoadPriorityOptimizer&);
+ // Subclasses must reimplement this method to compute the size and position
+ // of this object and all its descendants.
+ virtual void layout() = 0;
+ virtual bool updateImageLoadingPriorities() { return false; }
+ void setHasPendingResourceUpdate(bool hasPendingResourceUpdate) { m_bitfields.setHasPendingResourceUpdate(hasPendingResourceUpdate); }
+ bool hasPendingResourceUpdate() const { return m_bitfields.hasPendingResourceUpdate(); }
/* This function performs a layout only if one is needed. */
void layoutIfNeeded() { if (needsLayout()) layout(); }
@@ -676,17 +680,15 @@ public:
void forceLayout();
void forceChildLayout();
- // True if we can abort layout, leaving a partially laid out tree.
- virtual bool supportsPartialLayout() const { return false; }
-
- // used for element state updates that cannot be fixed with a
- // repaint and do not need a relayout
+ // Used for element state updates that cannot be fixed with a
+ // paint invalidation and do not need a relayout.
virtual void updateFromElement() { }
virtual void addAnnotatedRegions(Vector<AnnotatedRegionValue>&);
void collectAnnotatedRegions(Vector<AnnotatedRegionValue>&);
CompositingState compositingState() const;
+ virtual CompositingReasons additionalCompositingReasons(CompositingTriggerFlags) const;
bool hitTest(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter = HitTestAll);
virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
@@ -698,11 +700,6 @@ public:
virtual void dirtyLinesFromChangedChild(RenderObject*);
- // Called to update a style that is allowed to trigger animations.
- // FIXME: Right now this will typically be called only when updating happens from the DOM on explicit elements.
- // We don't yet handle generated content animation such as first-letter or before/after (we'll worry about this later).
- void setAnimatableStyle(PassRefPtr<RenderStyle>);
-
// Set the style of the object and update the state of the object accordingly.
void setStyle(PassRefPtr<RenderStyle>);
@@ -715,13 +712,10 @@ public:
// returns the containing block level element for this element.
RenderBlock* containingBlock() const;
+ RenderObject* clippingContainer() const;
bool canContainFixedPositionObjects() const
{
- return isRenderView() || (hasTransform() && isRenderBlock()) || isSVGForeignObject() || isOutOfFlowRenderFlowThread();
- }
- bool canContainAbsolutePositionObjects() const
- {
return isRenderView() || (hasTransform() && isRenderBlock()) || isSVGForeignObject();
}
@@ -739,22 +733,23 @@ public:
FloatQuad absoluteToLocalQuad(const FloatQuad&, MapCoordinatesFlags mode = 0) const;
// Convert a local quad into the coordinate system of container, taking transforms into account.
- FloatQuad localToContainerQuad(const FloatQuad&, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const;
- FloatPoint localToContainerPoint(const FloatPoint&, const RenderLayerModelObject* repaintContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const;
+ FloatQuad localToContainerQuad(const FloatQuad&, const RenderLayerModelObject* paintInvalidatinoContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const;
+ FloatPoint localToContainerPoint(const FloatPoint&, const RenderLayerModelObject* paintInvalidationContainer, MapCoordinatesFlags = 0, bool* wasFixed = 0) const;
// Return the offset from the container() renderer (excluding transforms). In multi-column layout,
// different offsets apply at different points, so return the offset that applies to the given point.
- virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
+ virtual LayoutSize offsetFromContainer(const RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
// Return the offset from an object up the container() chain. Asserts that none of the intermediate objects have transforms.
- LayoutSize offsetFromAncestorContainer(RenderObject*) const;
+ LayoutSize offsetFromAncestorContainer(const RenderObject*) const;
virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint&) const { }
- // FIXME: useTransforms should go away eventually
- IntRect absoluteBoundingBoxRect(bool useTransform = true) const;
- IntRect absoluteBoundingBoxRectIgnoringTransforms() const { return absoluteBoundingBoxRect(false); }
+ // Computes the position of the given render object in the space of |repaintContainer|.
+ LayoutPoint positionFromPaintInvalidationContainer(const RenderLayerModelObject* paintInvalidationContainer) const;
- bool isContainedInParentBoundingBox() const;
+ IntRect absoluteBoundingBoxRect() const;
+ // FIXME: This function should go away eventually
+ IntRect absoluteBoundingBoxRectIgnoringTransforms() const;
// Build an array of quads in absolute coords for line boxes
virtual void absoluteQuads(Vector<FloatQuad>&, bool* /*wasFixed*/ = 0) const { }
@@ -783,79 +778,91 @@ public:
return style()->visitedDependentColor(colorProperty);
}
- inline Color resolveColor(int colorProperty, Color fallback) const
- {
- Color color = resolveColor(colorProperty);
- return color.isValid() ? color : fallback;
- }
-
- inline Color resolveColor(Color color) const
- {
- return color;
- }
-
// Used only by Element::pseudoStyleCacheIsInvalid to get a first line style based off of a
// given new style, without accessing the cache.
PassRefPtr<RenderStyle> uncachedFirstLineStyle(RenderStyle*) const;
// Anonymous blocks that are part of of a continuation chain will return their inline continuation's outline style instead.
- // This is typically only relevant when repainting.
- virtual RenderStyle* outlineStyleForRepaint() const { return style(); }
+ // This is typically only relevant when invalidating paints.
+ virtual RenderStyle* outlineStyleForPaintInvalidation() const { return style(); }
virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
- void getTextDecorationColors(unsigned decorations, Color& underline, Color& overline, Color& linethrough, bool quirksMode = false, bool firstlineStyle = false);
+ struct AppliedTextDecoration {
+ Color color;
+ TextDecorationStyle style;
+ AppliedTextDecoration() : color(Color::transparent), style(TextDecorationStyleSolid) { }
+ };
+
+ void getTextDecorations(unsigned decorations, AppliedTextDecoration& underline, AppliedTextDecoration& overline, AppliedTextDecoration& linethrough, bool quirksMode = false, bool firstlineStyle = false);
// Return the RenderLayerModelObject in the container chain which is responsible for painting this object, or 0
- // if painting is root-relative. This is the container that should be passed to the 'forRepaint'
+ // if painting is root-relative. This is the container that should be passed to the 'forPaintInvalidation'
// methods.
- RenderLayerModelObject* containerForRepaint() const;
- // Actually do the repaint of rect r for this object which has been computed in the coordinate space
- // of repaintContainer. If repaintContainer is 0, repaint via the view.
- void repaintUsingContainer(const RenderLayerModelObject* repaintContainer, const IntRect&) const;
+ const RenderLayerModelObject* containerForPaintInvalidation() const;
+ const RenderLayerModelObject* enclosingCompositedContainer() const;
+ const RenderLayerModelObject* adjustCompositedContainerForSpecialAncestors(const RenderLayerModelObject* paintInvalidationContainer) const;
+ bool isPaintInvalidationContainer() const;
+
+ LayoutRect computePaintInvalidationRect()
+ {
+ return computePaintInvalidationRect(containerForPaintInvalidation());
+ }
+
+ // Returns the paint invalidation rect for this RenderObject in the coordinate space of the paint backing (typically a GraphicsLayer) for |paintInvalidationContainer|.
+ LayoutRect computePaintInvalidationRect(const RenderLayerModelObject* paintInvalidationContainer) const;
+
+ // Returns the rect bounds needed to invalidate the paint of this object, in the coordinate space of the rendering backing of |paintInvalidationContainer|
+ LayoutRect boundsRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const;
- // Repaint the entire object. Called when, e.g., the color of a border changes, or when a border
+ // Actually do the paint invalidate of rect r for this object which has been computed in the coordinate space
+ // of the GraphicsLayer backing of |paintInvalidationContainer|. Note that this coordinaten space is not the same
+ // as the local coordinate space of |paintInvalidationContainer| in the presence of layer squashing.
+ // If |paintInvalidationContainer| is 0, invalidate paints via the view.
+ // FIXME: |paintInvalidationContainer| should never be 0. See crbug.com/363699.
+ void invalidatePaintUsingContainer(const RenderLayerModelObject* paintInvalidationContainer, const IntRect&, InvalidationReason) const;
+
+ // Invalidate the paint of the entire object. Called when, e.g., the color of a border changes, or when a border
// style changes.
- void repaint() const;
+ void paintInvalidationForWholeRenderer() const;
+
+ // Invalidate the paint of a specific subrectangle within a given object. The rect |r| is in the object's coordinate space.
+ void invalidatePaintRectangle(const LayoutRect&) const;
- // Repaint a specific subrectangle within a given object. The rect |r| is in the object's coordinate space.
- void repaintRectangle(const LayoutRect&) const;
+ // Invalidate the paint only if our old bounds and new bounds are different. The caller may pass in newBounds if they are known.
+ bool invalidatePaintAfterLayoutIfNeeded(const RenderLayerModelObject* paintInvalidationContainer, bool wasSelfLayout,
+ const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalidationContainer,
+ const LayoutRect* newBoundsPtr = 0, const LayoutPoint* newPositionFromPaintInvalidationContainer = 0);
- // Repaint only if our old bounds and new bounds are different. The caller may pass in newBounds and newOutlineBox if they are known.
- bool repaintAfterLayoutIfNeeded(const RenderLayerModelObject* repaintContainer, bool wasSelfLayout,
- const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = 0, const LayoutRect* newOutlineBoxPtr = 0);
+ // Walk the tree after layout issuing paint invalidations for renderers that have changed or moved, updating bounds that have changed, and clearing paint invalidation state.
+ virtual void invalidateTreeAfterLayout(const RenderLayerModelObject&);
- virtual void repaintOverflow();
+ virtual void invalidatePaintForOverflow();
+ void invalidatePaintForOverflowIfNeeded();
- bool checkForRepaintDuringLayout() const;
+ bool checkForPaintInvalidation() const;
+ bool checkForPaintInvalidationDuringLayout() const;
- // Returns the rect that should be repainted whenever this object changes. The rect is in the view's
- // coordinate space. This method deals with outlines and overflow.
+ // Returns the rect that should have paint invalidated whenever this object changes. The rect is in the view's
+ // coordinate space. This method deals with outlines and overflow.
LayoutRect absoluteClippedOverflowRect() const
{
- return clippedOverflowRectForRepaint(0);
+ return clippedOverflowRectForPaintInvalidation(0);
}
IntRect pixelSnappedAbsoluteClippedOverflowRect() const;
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const;
- virtual LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const;
- virtual LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* /*repaintContainer*/, const RenderGeometryMap* = 0) const { return LayoutRect(); }
-
- // Given a rect in the object's coordinate space, compute a rect suitable for repainting
- // that rect in the coordinate space of repaintContainer.
- virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const;
- virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed = false) const;
-
- // If multiple-column layout results in applying an offset to the given point, add the same
- // offset to the given size.
- virtual void adjustForColumns(LayoutSize&, const LayoutPoint&) const { }
- LayoutSize offsetForColumns(const LayoutPoint& point) const
- {
- LayoutSize offset;
- adjustForColumns(offset, point);
- return offset;
- }
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const;
+ virtual LayoutRect rectWithOutlineForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, LayoutUnit outlineWidth) const;
- virtual unsigned int length() const { return 1; }
+ // Given a rect in the object's coordinate space, compute a rect suitable for invalidating paints of
+ // that rect in the coordinate space of paintInvalidationContainer.
+ virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed = false) const;
+ virtual void computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect& paintInvalidationRect, bool fixed = false) const;
+
+ // Return the offset to the column in which the specified point (in flow-thread coordinates)
+ // lives. This is used to convert a flow-thread point to a visual point.
+ virtual LayoutSize columnOffset(const LayoutPoint&) const { return LayoutSize(); }
+
+ virtual unsigned length() const { return 1; }
bool isFloatingOrOutOfFlowPositioned() const { return (isFloating() || isOutOfFlowPositioned()); }
@@ -864,9 +871,6 @@ public:
bool hasReflection() const { return m_bitfields.hasReflection(); }
- // Applied as a "slop" to dirty rect checks during the outline painting phase's dirty-rect checks.
- int maximalOutlineSize(PaintPhase) const;
-
enum SelectionState {
SelectionNone, // The object is not selected.
SelectionStart, // The object either contains the start of a selection run or is the start of a run
@@ -884,8 +888,8 @@ public:
// A single rectangle that encompasses all of the selected objects within this object. Used to determine the tightest
// possible bounding box for the selection.
- LayoutRect selectionRect(bool clipToVisibleContent = true) { return selectionRectForRepaint(0, clipToVisibleContent); }
- virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* /*repaintContainer*/, bool /*clipToVisibleContent*/ = true) { return LayoutRect(); }
+ LayoutRect selectionRect(bool clipToVisibleContent = true) { return selectionRectForPaintInvalidation(0, clipToVisibleContent); }
+ virtual LayoutRect selectionRectForPaintInvalidation(const RenderLayerModelObject* /*paintInvalidationContainer*/, bool /*clipToVisibleContent*/ = true) { return LayoutRect(); }
virtual bool canBeSelectionLeaf() const { return false; }
bool hasSelectedChildren() const { return selectionState() != SelectionNone; }
@@ -916,7 +920,6 @@ public:
// Virtual function helpers for the deprecated Flexible Box Layout (display: -webkit-box).
virtual bool isDeprecatedFlexibleBox() const { return false; }
- virtual bool isStretchingChildren() const { return false; }
// Virtual function helper for the new FlexibleBox Layout (display: -webkit-flex).
virtual bool isFlexibleBox() const { return false; }
@@ -935,23 +938,25 @@ public:
virtual int previousOffsetForBackwardDeletion(int current) const;
virtual int nextOffset(int current) const;
- virtual void imageChanged(ImageResource*, const IntRect* = 0);
+ virtual void imageChanged(ImageResource*, const IntRect* = 0) OVERRIDE FINAL;
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) { }
- virtual bool willRenderImage(ImageResource*);
+ virtual bool willRenderImage(ImageResource*) OVERRIDE FINAL;
void selectionStartEnd(int& spos, int& epos) const;
void remove() { if (parent()) parent()->removeChild(this); }
- AnimationController& animation() const;
-
bool isInert() const;
+
+ bool supportsTouchAction() const;
+
bool visibleToHitTestRequest(const HitTestRequest& request) const { return style()->visibility() == VISIBLE && (request.ignorePointerEventsNone() || style()->pointerEvents() != PE_NONE) && !isInert(); }
+
bool visibleToHitTesting() const { return style()->visibility() == VISIBLE && style()->pointerEvents() != PE_NONE && !isInert(); }
// Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use
// localToAbsolute/absoluteToLocal methods instead.
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* paintInvalidationContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const;
virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const;
// Pushes state onto RenderGeometryMap about how to map coordinates from this renderer to its container, or ancestorToStopAt (whichever is encountered first).
@@ -968,49 +973,64 @@ public:
// Compute a list of hit-test rectangles per layer rooted at this renderer.
virtual void computeLayerHitTestRects(LayerHitTestRects&) const;
- LayoutRect absoluteOutlineBounds() const
- {
- return outlineBoundsForRepaint(0);
- }
-
- // Return the renderer whose background style is used to paint the root background. Should only be called on the renderer for which isRoot() is true.
+ // Return the renderer whose background style is used to paint the root background. Should only be called on the renderer for which isDocumentElement() is true.
RenderObject* rendererForRootBackground();
RespectImageOrientationEnum shouldRespectImageOrientation() const;
bool isRelayoutBoundaryForInspector() const;
- const LayoutRect& newRepaintRect() const { return m_newRepaintRect; }
- void setNewRepaintRect(const LayoutRect& rect) { m_newRepaintRect = rect; }
+ const LayoutRect& previousPaintInvalidationRect() const { return m_previousPaintInvalidationRect; }
+ void setPreviousPaintInvalidationRect(const LayoutRect& rect) { m_previousPaintInvalidationRect = rect; }
- const LayoutRect& oldRepaintRect() const { return m_oldRepaintRect; }
- void setOldRepaintRect(const LayoutRect& rect) { m_oldRepaintRect = rect; }
+ const LayoutPoint& previousPositionFromPaintInvalidationContainer() const { return m_previousPositionFromPaintInvalidationContainer; }
+ void setPreviousPositionFromPaintInvalidationContainer(const LayoutPoint& location) { m_previousPositionFromPaintInvalidationContainer = location; }
- bool shouldDoFullRepaintAfterLayout() const { return m_bitfields.shouldDoFullRepaintAfterLayout(); }
- void setShouldDoFullRepaintAfterLayout(bool b) { m_bitfields.setShouldDoFullRepaintAfterLayout(b); }
- bool shouldRepaintOverflowIfNeeded() const { return m_bitfields.shouldRepaintOverflowIfNeeded(); }
+ bool shouldDoFullPaintInvalidationAfterLayout() const { return m_bitfields.shouldDoFullPaintInvalidationAfterLayout(); }
+ void setShouldDoFullPaintInvalidationAfterLayout(bool b) { m_bitfields.setShouldDoFullPaintInvalidationAfterLayout(b); }
+ bool shouldInvalidateOverflowForPaint() const { return m_bitfields.shouldInvalidateOverflowForPaint(); }
- void clearRepaintRects()
- {
- setNewRepaintRect(LayoutRect());
- setOldRepaintRect(LayoutRect());
+ bool shouldDoFullPaintInvalidationIfSelfPaintingLayer() const { return m_bitfields.shouldDoFullPaintInvalidationIfSelfPaintingLayer(); }
+ void setShouldDoFullPaintInvalidationIfSelfPaintingLayer(bool b) { m_bitfields.setShouldDoFullPaintInvalidationIfSelfPaintingLayer(b); }
- setShouldDoFullRepaintAfterLayout(false);
- setShouldRepaintOverflowIfNeeded(false);
- setLayoutDidGetCalled(false);
- }
+ bool onlyNeededPositionedMovementLayout() const { return m_bitfields.onlyNeededPositionedMovementLayout(); }
+ void setOnlyNeededPositionedMovementLayout(bool b) { m_bitfields.setOnlyNeededPositionedMovementLayout(b); }
+
+ void clearPaintInvalidationState();
// layoutDidGetCalled indicates whether this render object was re-laid-out
// since the last call to setLayoutDidGetCalled(false) on this object.
bool layoutDidGetCalled() { return m_bitfields.layoutDidGetCalled(); }
void setLayoutDidGetCalled(bool b) { m_bitfields.setLayoutDidGetCalled(b); }
+ bool mayNeedPaintInvalidation() { return m_bitfields.mayNeedPaintInvalidation(); }
+ void setMayNeedPaintInvalidation(bool b)
+ {
+ m_bitfields.setMayNeedPaintInvalidation(b);
+
+ // Make sure our parent is marked as needing invalidation.
+ if (b && parent() && !parent()->mayNeedPaintInvalidation())
+ parent()->setMayNeedPaintInvalidation(b);
+ }
+
+ bool shouldCheckForPaintInvalidationAfterLayout()
+ {
+ return layoutDidGetCalled() || mayNeedPaintInvalidation();
+ }
+
+ bool supportsLayoutStateCachedOffsets() const { return !hasColumns() && !hasTransform() && !hasReflection() && !style()->isFlippedBlocksWritingMode(); }
+
+ void setNeedsOverflowRecalcAfterStyleChange();
+ void markContainingBlocksForOverflowRecalc();
+
protected:
inline bool layerCreationAllowedForSubtree() const;
- // Overrides should call the superclass at the end
- virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
- // Overrides should call the superclass at the start
+ // Overrides should call the superclass at the end. m_style will be 0 the first time
+ // this function will be called.
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle);
+ // Overrides should call the superclass at the start. |oldStyle| will be 0 the first
+ // time this function is called.
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
void propagateStyleToAnonymousChildren(bool blockChildrenOnly = false);
@@ -1028,11 +1048,10 @@ protected:
void paintFocusRing(PaintInfo&, const LayoutPoint&, RenderStyle*);
void paintOutline(PaintInfo&, const LayoutRect&);
void addPDFURLRect(GraphicsContext*, const LayoutRect&);
+ void addChildFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer);
virtual LayoutRect viewRect() const;
- void adjustRectForOutlineAndShadow(LayoutRect&) const;
-
void clearLayoutRootIfNeeded() const;
virtual void willBeDestroyed();
void postDestroy();
@@ -1057,13 +1076,12 @@ protected:
virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const { };
private:
- RenderBlock* containerForFixedPosition(const RenderLayerModelObject* repaintContainer = 0, bool* repaintContainerSkipped = 0) const;
+ RenderBlock* containerForFixedPosition(const RenderLayerModelObject* paintInvalidationContainer = 0, bool* paintInvalidationContainerSkipped = 0) const;
RenderFlowThread* locateFlowThreadContainingBlock() const;
void removeFromRenderFlowThread();
void removeFromRenderFlowThreadRecursive(RenderFlowThread*);
- bool shouldRepaintForStyleDifference(StyleDifference) const;
bool hasImmediateNonWhitespaceTextChildOrPropertiesDependentOnColor() const;
RenderStyle* cachedFirstLineStyle() const;
@@ -1075,8 +1093,10 @@ private:
#ifndef NDEBUG
void checkBlockPositionedObjectsNeedLayout();
- void checkNotInPartialLayout();
#endif
+ const char* invalidationReasonToString(InvalidationReason) const;
+
+ static bool isAllowedToModifyRenderTreeStructure(Document&);
RefPtr<RenderStyle> m_style;
@@ -1109,18 +1129,25 @@ private:
public:
RenderObjectBitfields(Node* node)
: m_selfNeedsLayout(false)
- // FIXME: shouldDoFullRepaintAfterLayout is needed because we reset
- // the layout bits before repaint when doing repaintAfterLayout.
- // Holding the layout bits until after repaint would remove the need
+ // FIXME: shouldDoFullPaintInvalidationAfterLayout is needed because we reset
+ // the layout bits beforeissing paint invalidations when doing invalidateTreeAfterLayout.
+ // Holding the layout bits until after paint invalidation would remove the need
// for this flag.
- , m_shouldDoFullRepaintAfterLayout(false)
- , m_shouldRepaintOverflowIfNeeded(false)
+ , m_shouldDoFullPaintInvalidationAfterLayout(false)
+ , m_shouldInvalidateOverflowForPaint(false)
+ , m_shouldDoFullPaintInvalidationIfSelfPaintingLayer(false)
+ // FIXME: We should remove mayNeedPaintInvalidation once we are able to
+ // use the other layout flags to detect the same cases. crbug.com/370118
+ , m_mayNeedPaintInvalidation(false)
+ , m_onlyNeededPositionedMovementLayout(false)
, m_needsPositionedMovementLayout(false)
, m_normalChildNeedsLayout(false)
, m_posChildNeedsLayout(false)
, m_needsSimplifiedNormalFlowLayout(false)
, m_preferredLogicalWidthsDirty(false)
, m_floating(false)
+ , m_selfNeedsOverflowRecalcAfterStyleChange(false)
+ , m_childNeedsOverflowRecalcAfterStyleChange(false)
, m_isAnonymous(!node)
, m_isText(false)
, m_isBox(false)
@@ -1142,19 +1169,25 @@ private:
, m_selectionState(SelectionNone)
, m_flowThreadState(NotInsideFlowThread)
, m_boxDecorationState(NoBoxDecorations)
+ , m_hasPendingResourceUpdate(false)
{
}
- // 32 bits have been used in the first word, and 2 in the second.
+ // 32 bits have been used in the first word, and 6 in the second.
ADD_BOOLEAN_BITFIELD(selfNeedsLayout, SelfNeedsLayout);
- ADD_BOOLEAN_BITFIELD(shouldDoFullRepaintAfterLayout, ShouldDoFullRepaintAfterLayout);
- ADD_BOOLEAN_BITFIELD(shouldRepaintOverflowIfNeeded, ShouldRepaintOverflowIfNeeded);
+ ADD_BOOLEAN_BITFIELD(shouldDoFullPaintInvalidationAfterLayout, ShouldDoFullPaintInvalidationAfterLayout);
+ ADD_BOOLEAN_BITFIELD(shouldInvalidateOverflowForPaint, ShouldInvalidateOverflowForPaint);
+ ADD_BOOLEAN_BITFIELD(shouldDoFullPaintInvalidationIfSelfPaintingLayer, ShouldDoFullPaintInvalidationIfSelfPaintingLayer);
+ ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidation, MayNeedPaintInvalidation);
+ ADD_BOOLEAN_BITFIELD(onlyNeededPositionedMovementLayout, OnlyNeededPositionedMovementLayout);
ADD_BOOLEAN_BITFIELD(needsPositionedMovementLayout, NeedsPositionedMovementLayout);
ADD_BOOLEAN_BITFIELD(normalChildNeedsLayout, NormalChildNeedsLayout);
ADD_BOOLEAN_BITFIELD(posChildNeedsLayout, PosChildNeedsLayout);
ADD_BOOLEAN_BITFIELD(needsSimplifiedNormalFlowLayout, NeedsSimplifiedNormalFlowLayout);
ADD_BOOLEAN_BITFIELD(preferredLogicalWidthsDirty, PreferredLogicalWidthsDirty);
ADD_BOOLEAN_BITFIELD(floating, Floating);
+ ADD_BOOLEAN_BITFIELD(selfNeedsOverflowRecalcAfterStyleChange, SelfNeedsOverflowRecalcAfterStyleChange);
+ ADD_BOOLEAN_BITFIELD(childNeedsOverflowRecalcAfterStyleChange, ChildNeedsOverflowRecalcAfterStyleChange);
ADD_BOOLEAN_BITFIELD(isAnonymous, IsAnonymous);
ADD_BOOLEAN_BITFIELD(isText, IsText);
@@ -1186,6 +1219,9 @@ private:
unsigned m_boxDecorationState : 2; // BoxDecorationState
public:
+
+ ADD_BOOLEAN_BITFIELD(hasPendingResourceUpdate, HasPendingResourceUpdate);
+
bool isOutOfFlowPositioned() const { return m_positionedState == IsOutOfFlowPositioned; }
bool isRelPositioned() const { return m_positionedState == IsRelativelyPositioned; }
bool isStickyPositioned() const { return m_positionedState == IsStickyPositioned; }
@@ -1219,19 +1255,40 @@ private:
void setNeedsSimplifiedNormalFlowLayout(bool b) { m_bitfields.setNeedsSimplifiedNormalFlowLayout(b); }
void setIsDragging(bool b) { m_bitfields.setIsDragging(b); }
void setEverHadLayout(bool b) { m_bitfields.setEverHadLayout(b); }
- void setShouldRepaintOverflowIfNeeded(bool b) { m_bitfields.setShouldRepaintOverflowIfNeeded(b); }
+ void setShouldInvalidateOverflowForPaint(bool b) { m_bitfields.setShouldInvalidateOverflowForPaint(b); }
+ void setSelfNeedsOverflowRecalcAfterStyleChange(bool b) { m_bitfields.setSelfNeedsOverflowRecalcAfterStyleChange(b); }
+ void setChildNeedsOverflowRecalcAfterStyleChange(bool b) { m_bitfields.setChildNeedsOverflowRecalcAfterStyleChange(b); }
private:
// Store state between styleWillChange and styleDidChange
static bool s_affectsParentBlock;
- LayoutRect m_oldRepaintRect;
- LayoutRect m_newRepaintRect;
+ // This stores the paint invalidation rect from the previous layout.
+ LayoutRect m_previousPaintInvalidationRect;
+
+ // This stores the position in the paint invalidation container's coordinate.
+ // It is used to detect renderer shifts that forces a full invalidation.
+ LayoutPoint m_previousPositionFromPaintInvalidationContainer;
+};
+
+// FIXME: remove this once the render object lifecycle ASSERTS are no longer hit.
+class DeprecatedDisableModifyRenderTreeStructureAsserts {
+ WTF_MAKE_NONCOPYABLE(DeprecatedDisableModifyRenderTreeStructureAsserts);
+public:
+ DeprecatedDisableModifyRenderTreeStructureAsserts();
+
+ static bool canModifyRenderTreeStateInAnyState();
+
+private:
+ TemporaryChange<bool> m_disabler;
};
+// Allow equality comparisons of RenderObjects by reference or pointer, interchangeably.
+DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(RenderObject)
+
inline bool RenderObject::documentBeingDestroyed() const
{
- return !document().renderer();
+ return document().lifecycle().state() >= DocumentLifecycle::Stopping;
}
inline bool RenderObject::isBeforeContent() const
@@ -1259,27 +1316,30 @@ inline bool RenderObject::isBeforeOrAfterContent() const
return isBeforeContent() || isAfterContent();
}
+// If repaintAfterLayout is enabled, setNeedsLayout() won't cause full paint invalidations as
+// setNeedsLayoutAndFullPaintInvalidation() does. Otherwise the two methods are identical.
inline void RenderObject::setNeedsLayout(MarkingBehavior markParents, SubtreeLayoutScope* layouter)
{
-#ifndef NDEBUG
- checkNotInPartialLayout();
-#endif
ASSERT(!isSetNeedsLayoutForbidden());
bool alreadyNeededLayout = m_bitfields.selfNeedsLayout();
setSelfNeedsLayout(true);
if (!alreadyNeededLayout) {
if (markParents == MarkContainingBlockChain && (!layouter || layouter->root() != this))
markContainingBlocksForLayout(true, 0, layouter);
- if (hasLayer())
- setLayerNeedsFullRepaint();
}
}
+inline void RenderObject::setNeedsLayoutAndFullPaintInvalidation(MarkingBehavior markParents, SubtreeLayoutScope* layouter)
+{
+ setNeedsLayout(markParents, layouter);
+ setShouldDoFullPaintInvalidationAfterLayout(true);
+}
+
inline void RenderObject::clearNeedsLayout()
{
-#ifndef NDEBUG
- checkNotInPartialLayout();
-#endif
+ if (needsPositionedMovementLayoutOnly())
+ setOnlyNeededPositionedMovementLayout(true);
+ setLayoutDidGetCalled(true);
setSelfNeedsLayout(false);
setEverHadLayout(true);
setPosChildNeedsLayout(false);
@@ -1310,19 +1370,7 @@ inline void RenderObject::setNeedsPositionedMovementLayout()
if (!alreadyNeededLayout) {
markContainingBlocksForLayout();
if (hasLayer())
- setLayerNeedsFullRepaintForPositionedMovementLayout();
- }
-}
-
-inline void RenderObject::setNeedsSimplifiedNormalFlowLayout()
-{
- bool alreadyNeededLayout = needsSimplifiedNormalFlowLayout();
- setNeedsSimplifiedNormalFlowLayout(true);
- ASSERT(!isSetNeedsLayoutForbidden());
- if (!alreadyNeededLayout) {
- markContainingBlocksForLayout();
- if (hasLayer())
- setLayerNeedsFullRepaint();
+ setLayerNeedsFullPaintInvalidationForPositionedMovementLayout();
}
}
@@ -1392,6 +1440,12 @@ inline int adjustForAbsoluteZoom(int value, RenderObject* renderer)
return adjustForAbsoluteZoom(value, renderer->style());
}
+inline double adjustDoubleForAbsoluteZoom(double value, RenderObject& renderer)
+{
+ ASSERT(renderer.style());
+ return adjustDoubleForAbsoluteZoom(value, *renderer.style());
+}
+
inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, RenderObject& renderer)
{
ASSERT(renderer.style());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderObjectChildList.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderObjectChildList.cpp
index 80cee464c7d..6fd0358266b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderObjectChildList.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderObjectChildList.cpp
@@ -56,16 +56,21 @@ RenderObject* RenderObjectChildList::removeChildNode(RenderObject* owner, Render
if (oldChild->isFloatingOrOutOfFlowPositioned())
toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
- // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
- // that a positioned child got yanked). We also repaint, so that the area exposed when the child
- // disappears gets repainted properly.
- if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) {
- oldChild->setNeedsLayoutAndPrefWidthsRecalc();
- // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent.
- if (oldChild->isBody())
- owner->view()->repaint();
- else
- oldChild->repaint();
+ {
+ // FIXME: We should not be allowing repaint during layout. crbug.com/336250
+ AllowPaintInvalidationScope scoper(owner->frameView());
+
+ // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
+ // that a positioned child got yanked). We also repaint, so that the area exposed when the child
+ // disappears gets repainted properly.
+ if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) {
+ oldChild->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent.
+ if (oldChild->isBody())
+ owner->view()->paintInvalidationForWholeRenderer();
+ else
+ oldChild->paintInvalidationForWholeRenderer();
+ }
}
// If we have a line box wrapper, delete it.
@@ -153,7 +158,7 @@ void RenderObjectChildList::insertChildNode(RenderObject* owner, RenderObject* n
RenderCounter::rendererSubtreeAttached(newChild);
}
- newChild->setNeedsLayoutAndPrefWidthsRecalc();
+ newChild->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
if (!owner->normalChildNeedsLayout())
owner->setChildNeedsLayout(); // We may supply the static position for an absolute positioned child.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderOverflow.h b/chromium/third_party/WebKit/Source/core/rendering/RenderOverflow.h
index 2a965c7037a..2860b7cf848 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderOverflow.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderOverflow.h
@@ -50,16 +50,6 @@ public:
const LayoutRect visualOverflowRect() const { return m_visualOverflow; }
LayoutRect contentsVisualOverflowRect() const { return m_contentsVisualOverflow; }
- void setMinYLayoutOverflow(LayoutUnit overflow) { m_layoutOverflow.setY(overflow); }
- void setMaxYLayoutOverflow(LayoutUnit overflow) { m_layoutOverflow.setHeight(overflow - m_layoutOverflow.y()); }
- void setMinXLayoutOverflow(LayoutUnit overflow) { m_layoutOverflow.setX(overflow); }
- void setMaxXLayoutOverflow(LayoutUnit overflow) { m_layoutOverflow.setWidth(overflow - m_layoutOverflow.x()); }
-
- void setMinYVisualOverflow(LayoutUnit overflow) { m_visualOverflow.setY(overflow); }
- void setMaxYVisualOverflow(LayoutUnit overflow) { m_visualOverflow.setHeight(overflow - m_layoutOverflow.y()); }
- void setMinXVisualOverflow(LayoutUnit overflow) { m_visualOverflow.setX(overflow); }
- void setMaxXVisualOverflow(LayoutUnit overflow) { m_visualOverflow.setWidth(overflow - m_layoutOverflow.x()); }
-
void move(LayoutUnit dx, LayoutUnit dy);
void addLayoutOverflow(const LayoutRect&);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderPart.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderPart.cpp
index c0cbf957881..408a6453598 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderPart.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderPart.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/rendering/RenderPart.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLFrameElementBase.h"
#include "core/plugins/PluginView.h"
#include "core/rendering/HitTestResult.h"
@@ -46,31 +46,14 @@ RenderPart::RenderPart(Element* node)
RenderPart::~RenderPart()
{
- clearWidget();
}
-void RenderPart::setWidget(PassRefPtr<Widget> widget)
+LayerType RenderPart::layerTypeRequired() const
{
- if (widget == this->widget())
- return;
-
- RenderWidget::setWidget(widget);
-
- // make sure the scrollbars are set correctly for restore
- // ### find better fix
- viewCleared();
-}
-
-void RenderPart::viewCleared()
-{
-}
-
-bool RenderPart::requiresLayer() const
-{
- if (RenderWidget::requiresLayer())
- return true;
-
- return requiresAcceleratedCompositing();
+ LayerType type = RenderWidget::layerTypeRequired();
+ if (type != NoLayer)
+ return type;
+ return ForcedLayer;
}
bool RenderPart::requiresAcceleratedCompositing() const
@@ -104,18 +87,15 @@ bool RenderPart::needsPreferredWidthsRecalculation() const
return embeddedContentBox();
}
-RenderBox* RenderPart::embeddedContentBox() const
-{
- if (!node() || !widget() || !widget()->isFrameView())
- return 0;
- return toFrameView(widget())->embeddedContentBox();
-}
-
bool RenderPart::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
{
if (!widget() || !widget()->isFrameView() || !request.allowsChildFrameContent())
return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);
+ // FIXME: Until RemoteFrames use RemoteFrameViews, we need an explicit check here.
+ if (toFrameView(widget())->frame().isRemoteFrameTemporary())
+ return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);
+
FrameView* childFrameView = toFrameView(widget());
RenderView* childRoot = childFrameView->renderView();
@@ -149,4 +129,11 @@ bool RenderPart::nodeAtPoint(const HitTestRequest& request, HitTestResult& resul
return RenderWidget::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, action);
}
+CompositingReasons RenderPart::additionalCompositingReasons(CompositingTriggerFlags) const
+{
+ if (requiresAcceleratedCompositing())
+ return CompositingReasonIFrame;
+ return CompositingReasonNone;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderPart.h b/chromium/third_party/WebKit/Source/core/rendering/RenderPart.h
index f26a7e242c5..f0a1699740c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderPart.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderPart.h
@@ -33,22 +33,20 @@ public:
explicit RenderPart(Element*);
virtual ~RenderPart();
- virtual void setWidget(PassRefPtr<Widget>) OVERRIDE FINAL;
- virtual void viewCleared();
-
bool requiresAcceleratedCompositing() const;
virtual bool needsPreferredWidthsRecalculation() const OVERRIDE FINAL;
- virtual RenderBox* embeddedContentBox() const OVERRIDE FINAL;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
protected:
- virtual bool requiresLayer() const;
+ virtual LayerType layerTypeRequired() const OVERRIDE;
private:
virtual bool isRenderPart() const OVERRIDE FINAL { return true; }
- virtual const char* renderName() const { return "RenderPart"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderPart"; }
+
+ virtual CompositingReasons additionalCompositingReasons(CompositingTriggerFlags) const OVERRIDE;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderPart, isRenderPart());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderProgress.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderProgress.cpp
index 9bf99a86a3d..b3d994d6c3c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderProgress.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderProgress.cpp
@@ -54,8 +54,8 @@ void RenderProgress::updateFromElement()
m_position = element->position();
updateAnimationState();
- repaint();
- RenderBlock::updateFromElement();
+ paintInvalidationForWholeRenderer();
+ RenderBlockFlow::updateFromElement();
}
double RenderProgress::animationProgress() const
@@ -71,9 +71,9 @@ bool RenderProgress::isDeterminate() const
void RenderProgress::animationTimerFired(Timer<RenderProgress>*)
{
- repaint();
+ paintInvalidationForWholeRenderer();
if (!m_animationTimer.isActive() && m_animating)
- m_animationTimer.startOneShot(m_animationRepeatInterval);
+ m_animationTimer.startOneShot(m_animationRepeatInterval, FROM_HERE);
}
void RenderProgress::updateAnimationState()
@@ -88,7 +88,7 @@ void RenderProgress::updateAnimationState()
m_animating = animating;
if (m_animating) {
m_animationStartTime = currentTime();
- m_animationTimer.startOneShot(m_animationRepeatInterval);
+ m_animationTimer.startOneShot(m_animationRepeatInterval, FROM_HERE);
} else
m_animationTimer.stop();
}
@@ -98,7 +98,7 @@ HTMLProgressElement* RenderProgress::progressElement() const
if (!node())
return 0;
- if (isHTMLProgressElement(node()))
+ if (isHTMLProgressElement(*node()))
return toHTMLProgressElement(node());
ASSERT(node()->shadowHost());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderProgress.h b/chromium/third_party/WebKit/Source/core/rendering/RenderProgress.h
index bd1cac97f15..18d5c5d3e9f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderProgress.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderProgress.h
@@ -37,14 +37,13 @@ public:
double animationStartTime() const { return m_animationStartTime; }
bool isDeterminate() const;
- virtual void updateFromElement();
+ virtual void updateFromElement() OVERRIDE;
HTMLProgressElement* progressElement() const;
private:
- virtual const char* renderName() const { return "RenderProgress"; }
- virtual bool isProgress() const { return true; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual const char* renderName() const OVERRIDE { return "RenderProgress"; }
+ virtual bool isProgress() const OVERRIDE { return true; }
void animationTimerFired(Timer<RenderProgress>*);
void updateAnimationState();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRegion.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderRegion.cpp
index 0614d3aade2..864f98807e9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRegion.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRegion.cpp
@@ -34,8 +34,7 @@
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/HitTestLocation.h"
#include "core/rendering/PaintInfo.h"
-#include "core/rendering/RenderBoxRegionInfo.h"
-#include "core/rendering/RenderNamedFlowThread.h"
+#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderView.h"
using namespace std;
@@ -45,11 +44,7 @@ namespace WebCore {
RenderRegion::RenderRegion(Element* element, RenderFlowThread* flowThread)
: RenderBlockFlow(element)
, m_flowThread(flowThread)
- , m_parentNamedFlowThread(0)
- , m_computedAutoHeight(-1)
, m_isValid(false)
- , m_hasCustomRegionStyle(false)
- , m_hasAutoLogicalHeight(false)
{
}
@@ -62,29 +57,12 @@ LayoutUnit RenderRegion::pageLogicalWidth() const
LayoutUnit RenderRegion::pageLogicalHeight() const
{
ASSERT(m_flowThread);
- if (hasComputedAutoHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
- ASSERT(hasAutoLogicalHeight());
- return computedAutoHeight();
- }
return m_flowThread->isHorizontalWritingMode() ? contentHeight() : contentWidth();
}
-// This method returns the maximum page size of a region with auto-height. This is the initial
-// height value for auto-height regions in the first layout phase of the parent named flow.
-LayoutUnit RenderRegion::maxPageLogicalHeight() const
-{
- ASSERT(m_flowThread);
- ASSERT(hasAutoLogicalHeight() && !m_flowThread->inConstrainedLayoutPhase());
- return style()->logicalMaxHeight().isUndefined() ? RenderFlowThread::maxLogicalHeight() : computeReplacedLogicalHeightUsing(style()->logicalMaxHeight());
-}
-
LayoutUnit RenderRegion::logicalHeightOfAllFlowThreadContent() const
{
ASSERT(m_flowThread);
- if (hasComputedAutoHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
- ASSERT(hasAutoLogicalHeight());
- return computedAutoHeight();
- }
return m_flowThread->isHorizontalWritingMode() ? contentHeight() : contentWidth();
}
@@ -97,54 +75,30 @@ LayoutRect RenderRegion::overflowRectForFlowThreadPortion(const LayoutRect& flow
{
ASSERT(isValid());
- bool isLastRegionWithRegionFragmentBreak = (isLastPortion && (style()->regionFragment() == BreakRegionFragment));
- if (hasOverflowClip() || isLastRegionWithRegionFragmentBreak)
+ if (hasOverflowClip())
return flowThreadPortionRect;
LayoutRect flowThreadOverflow = m_flowThread->visualOverflowRect();
// Only clip along the flow thread axis.
- LayoutUnit outlineSize = maximalOutlineSize(PaintPhaseOutline);
LayoutRect clipRect;
if (m_flowThread->isHorizontalWritingMode()) {
- LayoutUnit minY = isFirstPortion ? (flowThreadOverflow.y() - outlineSize) : flowThreadPortionRect.y();
- LayoutUnit maxY = isLastPortion ? max(flowThreadPortionRect.maxY(), flowThreadOverflow.maxY()) + outlineSize : flowThreadPortionRect.maxY();
- bool clipX = style()->overflowX() != OVISIBLE;
- LayoutUnit minX = clipX ? flowThreadPortionRect.x() : min(flowThreadPortionRect.x(), flowThreadOverflow.x() - outlineSize);
- LayoutUnit maxX = clipX ? flowThreadPortionRect.maxX() : max(flowThreadPortionRect.maxX(), (flowThreadOverflow.maxX() + outlineSize));
+ LayoutUnit minY = isFirstPortion ? flowThreadOverflow.y() : flowThreadPortionRect.y();
+ LayoutUnit maxY = isLastPortion ? max(flowThreadPortionRect.maxY(), flowThreadOverflow.maxY()) : flowThreadPortionRect.maxY();
+ LayoutUnit minX = min(flowThreadPortionRect.x(), flowThreadOverflow.x());
+ LayoutUnit maxX = max(flowThreadPortionRect.maxX(), flowThreadOverflow.maxX());
clipRect = LayoutRect(minX, minY, maxX - minX, maxY - minY);
} else {
- LayoutUnit minX = isFirstPortion ? (flowThreadOverflow.x() - outlineSize) : flowThreadPortionRect.x();
- LayoutUnit maxX = isLastPortion ? max(flowThreadPortionRect.maxX(), flowThreadOverflow.maxX()) + outlineSize : flowThreadPortionRect.maxX();
- bool clipY = style()->overflowY() != OVISIBLE;
- LayoutUnit minY = clipY ? flowThreadPortionRect.y() : min(flowThreadPortionRect.y(), (flowThreadOverflow.y() - outlineSize));
- LayoutUnit maxY = clipY ? flowThreadPortionRect.maxY() : max(flowThreadPortionRect.y(), (flowThreadOverflow.maxY() + outlineSize));
+ LayoutUnit minX = isFirstPortion ? flowThreadOverflow.x() : flowThreadPortionRect.x();
+ LayoutUnit maxX = isLastPortion ? max(flowThreadPortionRect.maxX(), flowThreadOverflow.maxX()) : flowThreadPortionRect.maxX();
+ LayoutUnit minY = min(flowThreadPortionRect.y(), (flowThreadOverflow.y()));
+ LayoutUnit maxY = max(flowThreadPortionRect.y(), (flowThreadOverflow.maxY()));
clipRect = LayoutRect(minX, minY, maxX - minX, maxY - minY);
}
return clipRect;
}
-RegionOversetState RenderRegion::regionOversetState() const
-{
- if (isValid() && element())
- return element()->regionOversetState();
-
- return RegionUndefined;
-}
-
-void RenderRegion::setRegionOversetState(RegionOversetState state)
-{
- if (element())
- element()->setRegionOversetState(state);
-}
-
-Element* RenderRegion::element() const
-{
- ASSERT(nodeForRegion() && nodeForRegion()->isElementNode());
- return toElement(nodeForRegion());
-}
-
LayoutUnit RenderRegion::pageLogicalTopForOffset(LayoutUnit /* offset */) const
{
return flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().y() : flowThreadPortionRect().x();
@@ -164,148 +118,10 @@ bool RenderRegion::isLastRegion() const
return m_flowThread->lastRegion() == this;
}
-static bool shouldPaintRegionContentsInPhase(PaintPhase phase)
-{
- return phase == PaintPhaseForeground
- || phase == PaintPhaseSelection
- || phase == PaintPhaseTextClip;
-}
-
-void RenderRegion::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
-{
- if (style()->visibility() != VISIBLE)
- return;
-
- RenderBlock::paintObject(paintInfo, paintOffset);
-
- if (!isValid())
- return;
-
- // Delegate painting of content in region to RenderFlowThread.
- // RenderFlowThread is a self painting layer (being a positioned object) who is painting its children, the collected objects.
- // Since we do not want to paint the flow thread content multiple times (for each painting phase of the region object),
- // we allow the flow thread painting only in certain phases.
- if (!shouldPaintRegionContentsInPhase(paintInfo.phase))
- return;
-
- setRegionObjectsRegionStyle();
- m_flowThread->paintFlowThreadPortionInRegion(paintInfo, this, flowThreadPortionRect(), flowThreadPortionOverflowRect(), LayoutPoint(paintOffset.x() + borderLeft() + paddingLeft(), paintOffset.y() + borderTop() + paddingTop()));
- restoreRegionObjectsOriginalStyle();
-}
-
-// Hit Testing
-bool RenderRegion::hitTestFlowThreadContents(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
-{
- if (!isValid() || action != HitTestForeground)
- return false;
-
- LayoutRect boundsRect = borderBoxRectInRegion(locationInContainer.region());
- boundsRect.moveBy(accumulatedOffset);
- if (visibleToHitTesting() && locationInContainer.intersects(boundsRect)) {
- if (m_flowThread->hitTestFlowThreadPortionInRegion(this, flowThreadPortionRect(), flowThreadPortionOverflowRect(), request, result,
- locationInContainer, LayoutPoint(accumulatedOffset.x() + borderLeft() + paddingLeft(), accumulatedOffset.y() + borderTop() + paddingTop())))
- return true;
- }
-
- return false;
-}
-
-void RenderRegion::checkRegionStyle()
-{
- ASSERT(m_flowThread);
- bool customRegionStyle = false;
-
- // FIXME: Region styling doesn't work for pseudo elements.
- if (isElementBasedRegion())
- customRegionStyle = view()->document().ensureStyleResolver().checkRegionStyle(this->element());
-
- setHasCustomRegionStyle(customRegionStyle);
- m_flowThread->checkRegionsWithStyling();
-}
-
-void RenderRegion::incrementAutoLogicalHeightCount()
-{
- ASSERT(isValid());
- ASSERT(m_hasAutoLogicalHeight);
-
- m_flowThread->incrementAutoLogicalHeightRegions();
-}
-
-void RenderRegion::decrementAutoLogicalHeightCount()
-{
- ASSERT(isValid());
-
- m_flowThread->decrementAutoLogicalHeightRegions();
-}
-
-void RenderRegion::updateRegionHasAutoLogicalHeightFlag()
-{
- ASSERT(m_flowThread);
-
- if (!isValid())
- return;
-
- bool didHaveAutoLogicalHeight = m_hasAutoLogicalHeight;
- m_hasAutoLogicalHeight = shouldHaveAutoLogicalHeight();
- if (m_hasAutoLogicalHeight != didHaveAutoLogicalHeight) {
- if (m_hasAutoLogicalHeight) {
- incrementAutoLogicalHeightCount();
- } else {
- clearComputedAutoHeight();
- decrementAutoLogicalHeightCount();
- }
- }
-}
-
-bool RenderRegion::shouldHaveAutoLogicalHeight() const
-{
- bool hasSpecifiedEndpointsForHeight = style()->logicalTop().isSpecified() && style()->logicalBottom().isSpecified();
- bool hasAnchoredEndpointsForHeight = isOutOfFlowPositioned() && hasSpecifiedEndpointsForHeight;
- bool hasAutoHeightStyle = style()->logicalHeight().isAuto() || style()->logicalHeight().isFitContent()
- || style()->logicalHeight().isMaxContent() || style()->logicalHeight().isMinContent();
- return hasAutoHeightStyle && !hasAnchoredEndpointsForHeight;
-}
-
-void RenderRegion::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderBlock::styleDidChange(diff, oldStyle);
-
- // If the region is not attached to any thread, there is no need to check
- // whether the region has region styling since no content will be displayed
- // into the region.
- if (!m_flowThread) {
- setHasCustomRegionStyle(false);
- return;
- }
-
- checkRegionStyle();
- updateRegionHasAutoLogicalHeightFlag();
-
- if (oldStyle && oldStyle->writingMode() != style()->writingMode())
- m_flowThread->regionChangedWritingMode(this);
-}
-
-void RenderRegion::layoutBlock(bool relayoutChildren, LayoutUnit)
+void RenderRegion::layoutBlock(bool relayoutChildren)
{
RenderBlockFlow::layoutBlock(relayoutChildren);
- if (isValid()) {
- LayoutRect oldRegionRect(flowThreadPortionRect());
- if (!isHorizontalWritingMode())
- oldRegionRect = oldRegionRect.transposedRect();
-
- if (hasAutoLogicalHeight() && !m_flowThread->inConstrainedLayoutPhase()) {
- m_flowThread->invalidateRegions();
- clearComputedAutoHeight();
- return;
- }
-
- if (!isRenderRegionSet() && (oldRegionRect.width() != pageLogicalWidth() || oldRegionRect.height() != pageLogicalHeight())) {
- // This can happen even if we are in the inConstrainedLayoutPhase and it will trigger a pathological layout of the flow thread.
- m_flowThread->invalidateRegions();
- }
- }
-
// FIXME: We need to find a way to set up overflow properly. Our flow thread hasn't gotten a layout
// yet, so we can't look to it for correct information. It's possible we could wait until after the RenderFlowThread
// gets a layout, and then try to propagate overflow information back to the region, and then mark for a second layout.
@@ -314,8 +130,6 @@ void RenderRegion::layoutBlock(bool relayoutChildren, LayoutUnit)
// The big problem though is that overflow needs to be region-specific. We can't simply use the RenderFlowThread's global
// overflow values, since then we'd always think any narrow region had huge overflow (all the way to the width of the
// RenderFlowThread itself).
- //
- // We'll need to expand RenderBoxRegionInfo to also hold left and right overflow values.
}
void RenderRegion::repaintFlowThreadContent(const LayoutRect& repaintRect) const
@@ -345,30 +159,7 @@ void RenderRegion::repaintFlowThreadContentRectangle(const LayoutRect& repaintRe
flipForWritingMode(clippedRect);
// Issue the repaint.
- repaintRectangle(clippedRect);
-}
-
-void RenderRegion::installFlowThread()
-{
- ASSERT(view());
-
- m_flowThread = view()->flowThreadController()->ensureRenderFlowThreadWithName(style()->regionThread());
-
- // By now the flow thread should already be added to the rendering tree,
- // so we go up the rendering parents and check that this region is not part of the same
- // flow that it actually needs to display. It would create a circular reference.
- RenderObject* parentObject = parent();
- m_parentNamedFlowThread = 0;
- for ( ; parentObject; parentObject = parentObject->parent()) {
- if (parentObject->isRenderNamedFlowThread()) {
- m_parentNamedFlowThread = toRenderNamedFlowThread(parentObject);
- // Do not take into account a region that links a flow with itself. The dependency
- // cannot change, so it is not worth adding it to the list.
- if (m_flowThread == m_parentNamedFlowThread)
- m_flowThread = 0;
- break;
- }
- }
+ invalidatePaintRectangle(clippedRect);
}
void RenderRegion::attachRegion()
@@ -379,72 +170,19 @@ void RenderRegion::attachRegion()
// A region starts off invalid.
setIsValid(false);
- // Initialize the flow thread reference and create the flow thread object if needed.
- // The flow thread lifetime is influenced by the number of regions attached to it,
- // and we are attaching the region to the flow thread.
- installFlowThread();
-
if (!m_flowThread)
return;
// Only after adding the region to the thread, the region is marked to be valid.
m_flowThread->addRegionToThread(this);
-
- // The region just got attached to the flow thread, lets check whether
- // it has region styling rules associated.
- checkRegionStyle();
-
- if (!isValid())
- return;
-
- m_hasAutoLogicalHeight = shouldHaveAutoLogicalHeight();
- if (hasAutoLogicalHeight())
- incrementAutoLogicalHeightCount();
}
void RenderRegion::detachRegion()
{
if (m_flowThread) {
m_flowThread->removeRegionFromThread(this);
- if (hasAutoLogicalHeight())
- decrementAutoLogicalHeightCount();
+ m_flowThread = 0;
}
- m_flowThread = 0;
-}
-
-RenderBoxRegionInfo* RenderRegion::renderBoxRegionInfo(const RenderBox* box) const
-{
- ASSERT(isValid());
- return m_renderBoxRegionInfo.get(box);
-}
-
-RenderBoxRegionInfo* RenderRegion::setRenderBoxRegionInfo(const RenderBox* box, LayoutUnit logicalLeftInset, LayoutUnit logicalRightInset,
- bool containingBlockChainIsInset)
-{
- ASSERT(isValid());
-
- OwnPtr<RenderBoxRegionInfo>& boxInfo = m_renderBoxRegionInfo.add(box, nullptr).iterator->value;
- if (boxInfo)
- *boxInfo = RenderBoxRegionInfo(logicalLeftInset, logicalRightInset, containingBlockChainIsInset);
- else
- boxInfo = adoptPtr(new RenderBoxRegionInfo(logicalLeftInset, logicalRightInset, containingBlockChainIsInset));
-
- return boxInfo.get();
-}
-
-PassOwnPtr<RenderBoxRegionInfo> RenderRegion::takeRenderBoxRegionInfo(const RenderBox* box)
-{
- return m_renderBoxRegionInfo.take(box);
-}
-
-void RenderRegion::removeRenderBoxRegionInfo(const RenderBox* box)
-{
- m_renderBoxRegionInfo.remove(box);
-}
-
-void RenderRegion::deleteAllRenderBoxRegionInfo()
-{
- m_renderBoxRegionInfo.clear();
}
LayoutUnit RenderRegion::logicalTopOfFlowThreadContentRect(const LayoutRect& rect) const
@@ -459,167 +197,24 @@ LayoutUnit RenderRegion::logicalBottomOfFlowThreadContentRect(const LayoutRect&
return flowThread()->isHorizontalWritingMode() ? rect.maxY() : rect.maxX();
}
-void RenderRegion::setRegionObjectsRegionStyle()
-{
- if (!hasCustomRegionStyle())
- return;
-
- // Start from content nodes and recursively compute the style in region for the render objects below.
- // If the style in region was already computed, used that style instead of computing a new one.
- RenderNamedFlowThread* namedFlow = view()->flowThreadController()->ensureRenderFlowThreadWithName(style()->regionThread());
- const NamedFlowContentNodes& contentNodes = namedFlow->contentNodes();
-
- for (NamedFlowContentNodes::const_iterator iter = contentNodes.begin(), end = contentNodes.end(); iter != end; ++iter) {
- const Node* node = *iter;
- // The list of content nodes contains also the nodes with display:none.
- if (!node->renderer())
- continue;
-
- RenderObject* object = node->renderer();
- // If the content node does not flow any of its children in this region,
- // we do not compute any style for them in this region.
- if (!flowThread()->objectInFlowRegion(object, this))
- continue;
-
- // If the object has style in region, use that instead of computing a new one.
- RenderObjectRegionStyleMap::iterator it = m_renderObjectRegionStyle.find(object);
- RefPtr<RenderStyle> objectStyleInRegion;
- bool objectRegionStyleCached = false;
- if (it != m_renderObjectRegionStyle.end()) {
- objectStyleInRegion = it->value.style;
- ASSERT(it->value.cached);
- objectRegionStyleCached = true;
- } else {
- objectStyleInRegion = computeStyleInRegion(object);
- }
-
- setObjectStyleInRegion(object, objectStyleInRegion, objectRegionStyleCached);
-
- computeChildrenStyleInRegion(object);
- }
-}
-
-void RenderRegion::restoreRegionObjectsOriginalStyle()
-{
- if (!hasCustomRegionStyle())
- return;
-
- RenderObjectRegionStyleMap temp;
- for (RenderObjectRegionStyleMap::iterator iter = m_renderObjectRegionStyle.begin(), end = m_renderObjectRegionStyle.end(); iter != end; ++iter) {
- RenderObject* object = const_cast<RenderObject*>(iter->key);
- RefPtr<RenderStyle> objectRegionStyle = object->style();
- RefPtr<RenderStyle> objectOriginalStyle = iter->value.style;
- object->setStyleInternal(objectOriginalStyle);
-
- bool shouldCacheRegionStyle = iter->value.cached;
- if (!shouldCacheRegionStyle) {
- // Check whether we should cache the computed style in region.
- unsigned changedContextSensitiveProperties = ContextSensitivePropertyNone;
- StyleDifference styleDiff = objectOriginalStyle->diff(objectRegionStyle.get(), changedContextSensitiveProperties);
- if (styleDiff < StyleDifferenceLayoutPositionedMovementOnly)
- shouldCacheRegionStyle = true;
- }
- if (shouldCacheRegionStyle) {
- ObjectRegionStyleInfo styleInfo;
- styleInfo.style = objectRegionStyle;
- styleInfo.cached = true;
- temp.set(object, styleInfo);
- }
- }
-
- m_renderObjectRegionStyle.swap(temp);
-}
-
void RenderRegion::insertedIntoTree()
{
- RenderBlock::insertedIntoTree();
+ RenderBlockFlow::insertedIntoTree();
attachRegion();
}
void RenderRegion::willBeRemovedFromTree()
{
- RenderBlock::willBeRemovedFromTree();
+ RenderBlockFlow::willBeRemovedFromTree();
detachRegion();
}
-PassRefPtr<RenderStyle> RenderRegion::computeStyleInRegion(const RenderObject* object)
-{
- ASSERT(object);
- ASSERT(object->view());
- ASSERT(!object->isAnonymous());
- ASSERT(object->node() && object->node()->isElementNode());
-
- // FIXME: Region styling fails for pseudo-elements because the renderers don't have a node.
- Element* element = toElement(object->node());
- RefPtr<RenderStyle> renderObjectRegionStyle = object->view()->document().ensureStyleResolver().styleForElement(element, 0, DisallowStyleSharing, MatchAllRules, this);
-
- return renderObjectRegionStyle.release();
-}
-
-void RenderRegion::computeChildrenStyleInRegion(const RenderObject* object)
-{
- for (RenderObject* child = object->lastChild(); child; child = child->previousSibling()) {
-
- RenderObjectRegionStyleMap::iterator it = m_renderObjectRegionStyle.find(child);
-
- RefPtr<RenderStyle> childStyleInRegion;
- bool objectRegionStyleCached = false;
- if (it != m_renderObjectRegionStyle.end()) {
- childStyleInRegion = it->value.style;
- objectRegionStyleCached = true;
- } else {
- if (child->isAnonymous() || child->isInFlowRenderFlowThread())
- childStyleInRegion = RenderStyle::createAnonymousStyleWithDisplay(object->style(), child->style()->display());
- else if (child->isText())
- childStyleInRegion = RenderStyle::clone(object->style());
- else
- childStyleInRegion = computeStyleInRegion(child);
- }
-
- setObjectStyleInRegion(child, childStyleInRegion, objectRegionStyleCached);
-
- computeChildrenStyleInRegion(child);
- }
-}
-
-void RenderRegion::setObjectStyleInRegion(RenderObject* object, PassRefPtr<RenderStyle> styleInRegion, bool objectRegionStyleCached)
-{
- ASSERT(object->flowThreadContainingBlock());
-
- RefPtr<RenderStyle> objectOriginalStyle = object->style();
- object->setStyleInternal(styleInRegion);
-
- if (object->isBoxModelObject() && !object->hasBoxDecorations()) {
- bool hasBoxDecorations = object->isTableCell()
- || object->style()->hasBackground()
- || object->style()->hasBorder()
- || object->style()->hasAppearance()
- || object->style()->boxShadow();
- object->setHasBoxDecorations(hasBoxDecorations);
- }
-
- ObjectRegionStyleInfo styleInfo;
- styleInfo.style = objectOriginalStyle;
- styleInfo.cached = objectRegionStyleCached;
- m_renderObjectRegionStyle.set(object, styleInfo);
-}
-
-void RenderRegion::clearObjectStyleInRegion(const RenderObject* object)
-{
- ASSERT(object);
- m_renderObjectRegionStyle.remove(object);
-
- // Clear the style for the children of this object.
- for (RenderObject* child = object->lastChild(); child; child = child->previousSibling())
- clearObjectStyleInRegion(child);
-}
-
void RenderRegion::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
if (!isValid()) {
- RenderBlock::computeIntrinsicLogicalWidths(minLogicalWidth, maxLogicalWidth);
+ RenderBlockFlow::computeIntrinsicLogicalWidths(minLogicalWidth, maxLogicalWidth);
return;
}
@@ -627,62 +222,4 @@ void RenderRegion::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, La
maxLogicalWidth = m_flowThread->maxPreferredLogicalWidth();
}
-void RenderRegion::getRanges(Vector<RefPtr<Range> >& rangeObjects) const
-{
- RenderNamedFlowThread* namedFlow = view()->flowThreadController()->ensureRenderFlowThreadWithName(style()->regionThread());
- namedFlow->getRanges(rangeObjects, this);
-}
-
-void RenderRegion::updateLogicalHeight()
-{
- RenderBlock::updateLogicalHeight();
-
- if (!hasAutoLogicalHeight())
- return;
-
- // We want to update the logical height based on the computed auto-height
- // only if the view is in the layout phase in which all the
- // auto logical height regions have a computed auto-height.
- if (!m_flowThread->inConstrainedLayoutPhase())
- return;
-
- // There may be regions with auto logical height that during the prerequisite layout phase
- // did not have the chance to layout flow thread content. Because of that, these regions do not
- // have a computedAutoHeight and they will not be able to fragment any flow
- // thread content.
- if (!hasComputedAutoHeight())
- return;
-
- LayoutUnit autoHeight = hasOverrideHeight() ? overrideLogicalContentHeight() : computedAutoHeight();
-
- LayoutUnit newLogicalHeight = autoHeight + borderAndPaddingLogicalHeight();
- ASSERT(newLogicalHeight < RenderFlowThread::maxLogicalHeight());
- if (newLogicalHeight > logicalHeight()) {
- setLogicalHeight(newLogicalHeight);
- // Recalculate position of the render block after new logical height is set.
- // (needed in absolute positioning case with bottom alignment for example)
- RenderBlock::updateLogicalHeight();
- }
-}
-
-Node* RenderRegion::nodeForRegion() const
-{
- if (parent() && isRenderNamedFlowFragment())
- return parent()->node();
- return node();
-}
-
-Node* RenderRegion::generatingNodeForRegion() const
-{
- if (parent() && isRenderNamedFlowFragment())
- return parent()->generatingNode();
- return generatingNode();
-}
-
-bool RenderRegion::isElementBasedRegion() const
-{
- Node* node = nodeForRegion();
- return node && node->isElementNode() && !node->isPseudoElement();
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRegion.h b/chromium/third_party/WebKit/Source/core/rendering/RenderRegion.h
index c05d61359b2..d1a134c6b5f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRegion.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRegion.h
@@ -37,20 +37,13 @@ namespace WebCore {
struct LayerFragment;
typedef Vector<LayerFragment, 1> LayerFragments;
-class RenderBox;
-class RenderBoxRegionInfo;
class RenderFlowThread;
-class RenderNamedFlowThread;
class RenderRegion : public RenderBlockFlow {
public:
explicit RenderRegion(Element*, RenderFlowThread*);
- virtual bool isRenderRegion() const OVERRIDE { return true; }
-
- bool hitTestFlowThreadContents(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
-
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+ virtual bool isRenderRegion() const OVERRIDE FINAL { return true; }
void setFlowThreadPortionRect(const LayoutRect& rect) { m_flowThreadPortionRect = rect; }
LayoutRect flowThreadPortionRect() const { return m_flowThreadPortionRect; }
@@ -59,167 +52,64 @@ public:
void attachRegion();
void detachRegion();
- RenderNamedFlowThread* parentNamedFlowThread() const { return m_parentNamedFlowThread; }
RenderFlowThread* flowThread() const { return m_flowThread; }
// Valid regions do not create circular dependencies with other flows.
bool isValid() const { return m_isValid; }
void setIsValid(bool valid) { m_isValid = valid; }
- bool hasCustomRegionStyle() const { return m_hasCustomRegionStyle; }
- void setHasCustomRegionStyle(bool hasCustomRegionStyle) { m_hasCustomRegionStyle = hasCustomRegionStyle; }
-
- RenderBoxRegionInfo* renderBoxRegionInfo(const RenderBox*) const;
- RenderBoxRegionInfo* setRenderBoxRegionInfo(const RenderBox*, LayoutUnit logicalLeftInset, LayoutUnit logicalRightInset,
- bool containingBlockChainIsInset);
- PassOwnPtr<RenderBoxRegionInfo> takeRenderBoxRegionInfo(const RenderBox*);
- void removeRenderBoxRegionInfo(const RenderBox*);
-
- void deleteAllRenderBoxRegionInfo();
-
bool isFirstRegion() const;
bool isLastRegion() const;
- void clearObjectStyleInRegion(const RenderObject*);
-
- RegionOversetState regionOversetState() const;
- void setRegionOversetState(RegionOversetState);
-
- // These methods represent the width and height of a "page" and for a RenderRegion they are just the
- // content width and content height of a region. For RenderRegionSets, however, they will be the width and
- // height of a single column or page in the set.
+ // These methods represent the width and height of a "page" and for a RenderRegion they are just
+ // the content width and content height of a region. For RenderMultiColumnSets, however, they
+ // will be the width and height of a single column or page in the set.
virtual LayoutUnit pageLogicalWidth() const;
virtual LayoutUnit pageLogicalHeight() const;
- virtual LayoutUnit maxPageLogicalHeight() const;
LayoutUnit logicalTopOfFlowThreadContentRect(const LayoutRect&) const;
LayoutUnit logicalBottomOfFlowThreadContentRect(const LayoutRect&) const;
LayoutUnit logicalTopForFlowThreadContent() const { return logicalTopOfFlowThreadContentRect(flowThreadPortionRect()); };
LayoutUnit logicalBottomForFlowThreadContent() const { return logicalBottomOfFlowThreadContentRect(flowThreadPortionRect()); };
- void getRanges(Vector<RefPtr<Range> >&) const;
-
// This method represents the logical height of the entire flow thread portion used by the region or set.
// For RenderRegions it matches logicalPaginationHeight(), but for sets it is the height of all the pages
// or columns added together.
virtual LayoutUnit logicalHeightOfAllFlowThreadContent() const;
- bool hasAutoLogicalHeight() const { return m_hasAutoLogicalHeight; }
-
- const LayoutUnit& computedAutoHeight() const
- {
- ASSERT(hasComputedAutoHeight());
- return m_computedAutoHeight;
- }
-
- void setComputedAutoHeight(LayoutUnit computedAutoHeight)
- {
- ASSERT(computedAutoHeight >= 0);
- m_computedAutoHeight = computedAutoHeight;
- }
-
- void clearComputedAutoHeight()
- {
- m_computedAutoHeight = -1;
- }
-
- bool hasComputedAutoHeight() const { return (m_computedAutoHeight >= 0); }
-
// The top of the nearest page inside the region. For RenderRegions, this is just the logical top of the
// flow thread portion we contain. For sets, we have to figure out the top of the nearest column or
// page.
virtual LayoutUnit pageLogicalTopForOffset(LayoutUnit offset) const;
- virtual void expandToEncompassFlowThreadContentsIfNeeded() { };
-
- // Whether or not this region is a set.
- virtual bool isRenderRegionSet() const { return false; }
-
virtual void repaintFlowThreadContent(const LayoutRect& repaintRect) const;
virtual void collectLayerFragments(LayerFragments&, const LayoutRect&, const LayoutRect&) { }
- virtual bool canHaveChildren() const OVERRIDE { return false; }
- virtual bool canHaveGeneratedChildren() const OVERRIDE { return true; }
-
- bool isElementBasedRegion() const;
-
- Node* nodeForRegion() const;
- Node* generatingNodeForRegion() const;
+ virtual bool canHaveChildren() const OVERRIDE FINAL { return false; }
+ virtual bool canHaveGeneratedChildren() const OVERRIDE FINAL { return true; }
virtual const char* renderName() const OVERRIDE { return "RenderRegion"; }
protected:
- void setRegionObjectsRegionStyle();
- void restoreRegionObjectsOriginalStyle();
-
- virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
+ virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE FINAL;
LayoutRect overflowRectForFlowThreadPortion(const LayoutRect& flowThreadPortionRect, bool isFirstPortion, bool isLastPortion) const;
void repaintFlowThreadContentRectangle(const LayoutRect& repaintRect, const LayoutRect& flowThreadPortionRect,
const LayoutRect& flowThreadPortionOverflowRect, const LayoutPoint& regionLocation) const;
- virtual bool shouldHaveAutoLogicalHeight() const;
-
private:
- virtual void insertedIntoTree() OVERRIDE;
- virtual void willBeRemovedFromTree() OVERRIDE;
-
- virtual void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
- virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
-
- virtual void updateLogicalHeight() OVERRIDE;
+ virtual void insertedIntoTree() OVERRIDE FINAL;
+ virtual void willBeRemovedFromTree() OVERRIDE FINAL;
- virtual void installFlowThread();
-
- PassRefPtr<RenderStyle> computeStyleInRegion(const RenderObject*);
- void computeChildrenStyleInRegion(const RenderObject*);
- void setObjectStyleInRegion(RenderObject*, PassRefPtr<RenderStyle>, bool objectRegionStyleCached);
-
- void checkRegionStyle();
- void updateRegionHasAutoLogicalHeightFlag();
-
- void incrementAutoLogicalHeightCount();
- void decrementAutoLogicalHeightCount();
-
- Element* element() const;
+ virtual void layoutBlock(bool relayoutChildren) OVERRIDE FINAL;
protected:
RenderFlowThread* m_flowThread;
private:
- // If this RenderRegion is displayed as part of another named flow,
- // we need to create a dependency tree, so that layout of the
- // regions is always done before the regions themselves.
- RenderNamedFlowThread* m_parentNamedFlowThread;
LayoutRect m_flowThreadPortionRect;
-
- // This map holds unique information about a block that is split across regions.
- // A RenderBoxRegionInfo* tells us about any layout information for a RenderBox that
- // is unique to the region. For now it just holds logical width information for RenderBlocks, but eventually
- // it will also hold a custom style for any box (for region styling).
- typedef HashMap<const RenderBox*, OwnPtr<RenderBoxRegionInfo> > RenderBoxRegionInfoMap;
- RenderBoxRegionInfoMap m_renderBoxRegionInfo;
-
- struct ObjectRegionStyleInfo {
- // Used to store the original style of the object in region
- // so that the original style is properly restored after paint.
- // Also used to store computed style of the object in region between
- // region paintings, so that the style in region is computed only
- // when necessary.
- RefPtr<RenderStyle> style;
- // True if the computed style in region is cached.
- bool cached;
- };
- typedef HashMap<const RenderObject*, ObjectRegionStyleInfo > RenderObjectRegionStyleMap;
- RenderObjectRegionStyleMap m_renderObjectRegionStyle;
-
- LayoutUnit m_computedAutoHeight;
-
bool m_isValid : 1;
- bool m_hasCustomRegionStyle : 1;
- bool m_hasAutoLogicalHeight : 1;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderRegion, isRenderRegion());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRegionSet.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderRegionSet.cpp
deleted file mode 100644
index 933611547d9..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRegionSet.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/RenderRegionSet.h"
-
-#include "core/rendering/RenderFlowThread.h"
-
-namespace WebCore {
-
-RenderRegionSet::RenderRegionSet(Element* element, RenderFlowThread* flowThread)
- : RenderRegion(element, flowThread)
-{
-}
-
-void RenderRegionSet::installFlowThread()
-{
- // We don't have to do anything, since we were able to connect the flow thread
- // in the constructor.
-}
-
-void RenderRegionSet::expandToEncompassFlowThreadContentsIfNeeded()
-{
- // Whenever the last region is a set, it always expands its region rect to consume all
- // of the flow thread content. This is because it is always capable of generating an
- // infinite number of boxes in order to hold all of the remaining content.
- LayoutRect rect(flowThreadPortionRect());
-
- // Get the offset within the flow thread in its block progression direction. Then get the
- // flow thread's remaining logical height including its overflow and expand our rect
- // to encompass that remaining height and overflow. The idea is that we will generate
- // additional columns and pages to hold that overflow, since people do write bad
- // content like <body style="height:0px"> in multi-column layouts.
- bool isHorizontal = flowThread()->isHorizontalWritingMode();
- LayoutUnit logicalTopOffset = isHorizontal ? rect.y() : rect.x();
- LayoutRect layoutRect = flowThread()->layoutOverflowRect();
- LayoutUnit logicalHeightWithOverflow = (isHorizontal ? layoutRect.maxY() : layoutRect.maxX()) - logicalTopOffset;
- setFlowThreadPortionRect(LayoutRect(rect.x(), rect.y(), isHorizontal ? rect.width() : logicalHeightWithOverflow, isHorizontal ? logicalHeightWithOverflow : rect.height()));
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRegionSet.h b/chromium/third_party/WebKit/Source/core/rendering/RenderRegionSet.h
deleted file mode 100644
index 6802852d0be..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRegionSet.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef RenderRegionSet_h
-#define RenderRegionSet_h
-
-#include "core/rendering/RenderBoxRegionInfo.h"
-#include "core/rendering/RenderRegion.h"
-
-namespace WebCore {
-
-class RenderFlowThread;
-
-// RenderRegionSet represents a set of regions that all have the same width and height. It is a "composite region box" that
-// can be used to represent a single run of contiguous regions.
-//
-// By combining runs of same-size columns or pages into a single object, we significantly reduce the number of unique RenderObjects
-// required to represent those objects.
-//
-// This class is abstract and is only intended for use by renderers that generate anonymous runs of identical regions, i.e.,
-// columns and printing. RenderMultiColumnSet and RenderPageSet represent runs of columns and pages respectively.
-//
-// FIXME: For now we derive from RenderRegion, but this may change at some point.
-
-class RenderRegionSet : public RenderRegion {
-public:
- RenderRegionSet(Element*, RenderFlowThread*);
-
-protected:
- virtual bool shouldHaveAutoLogicalHeight() const OVERRIDE { return false; }
-
-private:
- virtual void installFlowThread() OVERRIDE FINAL;
-
- virtual void expandToEncompassFlowThreadContentsIfNeeded() OVERRIDE FINAL;
-
- virtual const char* renderName() const = 0;
-
- virtual bool isRenderRegionSet() const OVERRIDE FINAL { return true; }
-};
-
-} // namespace WebCore
-
-#endif // RenderRegionSet_h
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.cpp
index 059cd205f57..89970827847 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.cpp
@@ -24,14 +24,14 @@
#include "config.h"
#include "core/rendering/RenderReplaced.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/rendering/GraphicsContextAnnotator.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/RenderImage.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
+#include "platform/LengthFunctions.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/graphics/GraphicsContext.h"
using namespace std;
@@ -81,8 +81,7 @@ void RenderReplaced::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+ LayoutRepainter repainter(*this, checkForPaintInvalidationDuringLayout());
setHeight(minimumReplacedHeight());
@@ -91,7 +90,7 @@ void RenderReplaced::layout()
m_overflow.clear();
addVisualEffectOverflow();
- updateLayerTransform();
+ updateLayerTransformAfterLayout();
invalidateBackgroundObscurationStatus();
repainter.repaintAfterLayout();
@@ -103,7 +102,7 @@ void RenderReplaced::intrinsicSizeChanged()
int scaledWidth = static_cast<int>(cDefaultWidth * style()->effectiveZoom());
int scaledHeight = static_cast<int>(cDefaultHeight * style()->effectiveZoom());
m_intrinsicSize = IntSize(scaledWidth, scaledHeight);
- setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
void RenderReplaced::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -196,19 +195,17 @@ bool RenderReplaced::shouldPaint(PaintInfo& paintInfo, const LayoutPoint& paintO
// Early exit if the element touches the edges.
LayoutUnit top = adjustedPaintOffset.y() + visualOverflowRect().y();
LayoutUnit bottom = adjustedPaintOffset.y() + visualOverflowRect().maxY();
- if (isSelected() && m_inlineBoxWrapper) {
- LayoutUnit selTop = paintOffset.y() + m_inlineBoxWrapper->root()->selectionTop();
- LayoutUnit selBottom = paintOffset.y() + selTop + m_inlineBoxWrapper->root()->selectionHeight();
+ if (isSelected() && inlineBoxWrapper()) {
+ LayoutUnit selTop = paintOffset.y() + inlineBoxWrapper()->root().selectionTop();
+ LayoutUnit selBottom = paintOffset.y() + selTop + inlineBoxWrapper()->root().selectionHeight();
top = min(selTop, top);
bottom = max(selBottom, bottom);
}
- LayoutRect localRepaintRect = paintInfo.rect;
- localRepaintRect.inflate(maximalOutlineSize(paintInfo.phase));
- if (adjustedPaintOffset.x() + visualOverflowRect().x() >= localRepaintRect.maxX() || adjustedPaintOffset.x() + visualOverflowRect().maxX() <= localRepaintRect.x())
+ if (adjustedPaintOffset.x() + visualOverflowRect().x() >= paintInfo.rect.maxX() || adjustedPaintOffset.x() + visualOverflowRect().maxX() <= paintInfo.rect.x())
return false;
- if (top >= localRepaintRect.maxY() || bottom <= localRepaintRect.y())
+ if (top >= paintInfo.rect.maxY() || bottom <= paintInfo.rect.y())
return false;
return true;
@@ -224,24 +221,15 @@ static inline RenderBlock* firstContainingBlockWithLogicalWidth(const RenderRepl
return 0;
for (; !containingBlock->isRenderView() && !containingBlock->isBody(); containingBlock = containingBlock->containingBlock()) {
- if (containingBlock->style()->logicalWidth().isSpecified())
+ if (containingBlock->style()->logicalWidth().isSpecified()
+ && containingBlock->style()->logicalMinWidth().isSpecified()
+ && (containingBlock->style()->logicalMaxWidth().isSpecified() || containingBlock->style()->logicalMaxWidth().isUndefined()))
return containingBlock;
}
return 0;
}
-bool RenderReplaced::hasReplacedLogicalWidth() const
-{
- if (style()->logicalWidth().isSpecified())
- return true;
-
- if (style()->logicalWidth().isAuto())
- return false;
-
- return firstContainingBlockWithLogicalWidth(this);
-}
-
bool RenderReplaced::hasReplacedLogicalHeight() const
{
if (style()->logicalHeight().isAuto())
@@ -272,28 +260,21 @@ static inline bool rendererHasAspectRatio(const RenderObject* renderer)
return renderer->isImage() || renderer->isCanvas() || renderer->isVideo();
}
-void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* contentRenderer, FloatSize& constrainedSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
+void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* contentRenderer, FloatSize& constrainedSize, double& intrinsicRatio) const
{
FloatSize intrinsicSize;
if (contentRenderer) {
- contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
- if (intrinsicRatio)
- ASSERT(!isPercentageIntrinsicSize);
+ contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio);
// Handle zoom & vertical writing modes here, as the embedded document doesn't know about them.
- if (!isPercentageIntrinsicSize) {
- intrinsicSize.scale(style()->effectiveZoom());
- if (isRenderImage())
- intrinsicSize.scale(toRenderImage(this)->imageDevicePixelRatio());
- }
-
- if (rendererHasAspectRatio(this) && isPercentageIntrinsicSize)
- intrinsicRatio = 1;
+ intrinsicSize.scale(style()->effectiveZoom());
+ if (isRenderImage())
+ intrinsicSize.scale(toRenderImage(this)->imageDevicePixelRatio());
// Update our intrinsic size to match what the content renderer has computed, so that when we
// constrain the size below, the correct intrinsic size will be obtained for comparison against
// min and max widths.
- if (intrinsicRatio && !isPercentageIntrinsicSize && !intrinsicSize.isEmpty())
+ if (intrinsicRatio && !intrinsicSize.isEmpty())
m_intrinsicSize = LayoutSize(intrinsicSize);
if (!isHorizontalWritingMode()) {
@@ -302,12 +283,9 @@ void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* conten
intrinsicSize = intrinsicSize.transposedSize();
}
} else {
- computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize);
- if (intrinsicRatio) {
- ASSERT(!isPercentageIntrinsicSize);
- if (!intrinsicSize.isEmpty())
- m_intrinsicSize = LayoutSize(isHorizontalWritingMode() ? intrinsicSize : intrinsicSize.transposedSize());
- }
+ computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio);
+ if (intrinsicRatio && !intrinsicSize.isEmpty())
+ m_intrinsicSize = LayoutSize(isHorizontalWritingMode() ? intrinsicSize : intrinsicSize.transposedSize());
}
// Now constrain the intrinsic size along each axis according to minimum and maximum width/heights along the
@@ -317,7 +295,7 @@ void RenderReplaced::computeAspectRatioInformationForRenderBox(RenderBox* conten
// FIXME: In the long term, it might be better to just return this code more to the way it used to be before this
// function was added, since all it has done is make the code more unclear.
constrainedSize = intrinsicSize;
- if (intrinsicRatio && !isPercentageIntrinsicSize && !intrinsicSize.isEmpty() && style()->logicalWidth().isAuto() && style()->logicalHeight().isAuto()) {
+ if (intrinsicRatio && !intrinsicSize.isEmpty() && style()->logicalWidth().isAuto() && style()->logicalHeight().isAuto()) {
// We can't multiply or divide by 'intrinsicRatio' here, it breaks tests, like fast/images/zoomed-img-size.html, which
// can only be fixed once subpixel precision is available for things like intrinsicWidth/Height - which include zoom!
constrainedSize.setWidth(RenderBox::computeReplacedLogicalHeight() * intrinsicSize.width() / intrinsicSize.height());
@@ -358,19 +336,18 @@ LayoutRect RenderReplaced::replacedContentRect(const LayoutSize* overriddenIntri
ASSERT_NOT_REACHED();
}
- LayoutUnit xOffset = minimumValueForLength(style()->objectPosition().x(), contentRect.width() - finalRect.width(), view());
- LayoutUnit yOffset = minimumValueForLength(style()->objectPosition().y(), contentRect.height() - finalRect.height(), view());
+ LayoutUnit xOffset = minimumValueForLength(style()->objectPosition().x(), contentRect.width() - finalRect.width());
+ LayoutUnit yOffset = minimumValueForLength(style()->objectPosition().y(), contentRect.height() - finalRect.height());
finalRect.move(xOffset, yOffset);
return finalRect;
}
-void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
+void RenderReplaced::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const
{
// If there's an embeddedContentBox() of a remote, referenced document available, this code-path should never be used.
ASSERT(!embeddedContentBox());
- isPercentageIntrinsicSize = false;
- intrinsicSize = FloatSize(intrinsicLogicalWidth(), intrinsicLogicalHeight());
+ intrinsicSize = FloatSize(intrinsicLogicalWidth().toFloat(), intrinsicLogicalHeight().toFloat());
// Figure out if we need to compute an intrinsic ratio.
if (intrinsicSize.isEmpty() || !rendererHasAspectRatio(this))
@@ -387,25 +364,24 @@ LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred sh
RenderBox* contentRenderer = embeddedContentBox();
// 10.3.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-width
- bool isPercentageIntrinsicSize = false;
double intrinsicRatio = 0;
FloatSize constrainedSize;
- computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio, isPercentageIntrinsicSize);
+ computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio);
if (style()->logicalWidth().isAuto()) {
- bool heightIsAuto = style()->logicalHeight().isAuto();
- bool hasIntrinsicWidth = !isPercentageIntrinsicSize && constrainedSize.width() > 0;
+ bool computedHeightIsAuto = hasAutoHeightOrContainingBlockWithAutoHeight();
+ bool hasIntrinsicWidth = constrainedSize.width() > 0;
// If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic width, then that intrinsic width is the used value of 'width'.
- if (heightIsAuto && hasIntrinsicWidth)
+ if (computedHeightIsAuto && hasIntrinsicWidth)
return computeReplacedLogicalWidthRespectingMinMaxWidth(constrainedSize.width(), shouldComputePreferred);
- bool hasIntrinsicHeight = !isPercentageIntrinsicSize && constrainedSize.height() > 0;
- if (intrinsicRatio || isPercentageIntrinsicSize) {
+ bool hasIntrinsicHeight = constrainedSize.height() > 0;
+ if (intrinsicRatio) {
// If 'height' and 'width' both have computed values of 'auto' and the element has no intrinsic width, but does have an intrinsic height and intrinsic ratio;
// or if 'width' has a computed value of 'auto', 'height' has some other computed value, and the element does have an intrinsic ratio; then the used value
// of 'width' is: (used height) * (intrinsic ratio)
- if (intrinsicRatio && ((heightIsAuto && !hasIntrinsicWidth && hasIntrinsicHeight) || !heightIsAuto)) {
+ if (intrinsicRatio && ((computedHeightIsAuto && !hasIntrinsicWidth && hasIntrinsicHeight) || !computedHeightIsAuto)) {
LayoutUnit logicalHeight = computeReplacedLogicalHeight();
return computeReplacedLogicalWidthRespectingMinMaxWidth(roundToInt(round(logicalHeight * intrinsicRatio)), shouldComputePreferred);
}
@@ -413,21 +389,30 @@ LayoutUnit RenderReplaced::computeReplacedLogicalWidth(ShouldComputePreferred sh
// If 'height' and 'width' both have computed values of 'auto' and the element has an intrinsic ratio but no intrinsic height or width, then the used value of
// 'width' is undefined in CSS 2.1. However, it is suggested that, if the containing block's width does not itself depend on the replaced element's width, then
// the used value of 'width' is calculated from the constraint equation used for block-level, non-replaced elements in normal flow.
- if (heightIsAuto && !hasIntrinsicWidth && !hasIntrinsicHeight) {
+ if (computedHeightIsAuto && !hasIntrinsicWidth && !hasIntrinsicHeight) {
+ if (shouldComputePreferred == ComputePreferred)
+ return 0;
// The aforementioned 'constraint equation' used for block-level, non-replaced elements in normal flow:
// 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
LayoutUnit logicalWidth;
- if (RenderBlock* blockWithWidth = firstContainingBlockWithLogicalWidth(this))
+ // FIXME: This walking up the containgBlock chain to find the first one with a specified width is bonkers.
+ // If nothing else, it requires making sure that computeReplacedLogicalWidthRespectingMinMaxWidth cannot
+ // depend on the width of the replaced element or we infinite loop. Right now we do that in
+ // firstContainingBlockWithLogicalWidth by checking that width/min-width/max-width are all specified.
+ //
+ // Firefox 27 seems to only do this if the <svg> has a viewbox.
+ if (RenderBlock* blockWithWidth = firstContainingBlockWithLogicalWidth(this)) {
logicalWidth = blockWithWidth->computeReplacedLogicalWidthRespectingMinMaxWidth(blockWithWidth->computeReplacedLogicalWidthUsing(blockWithWidth->style()->logicalWidth()), shouldComputePreferred);
- else
+ } else {
+ // FIXME: If shouldComputePreferred == ComputePreferred, then we're reading this during preferred width
+ // computation, at which point this is reading stale data from a previous layout.
logicalWidth = containingBlock()->availableLogicalWidth();
+ }
// This solves above equation for 'width' (== logicalWidth).
LayoutUnit marginStart = minimumValueForLength(style()->marginStart(), logicalWidth);
LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd(), logicalWidth);
logicalWidth = max<LayoutUnit>(0, logicalWidth - (marginStart + marginEnd + (width() - clientWidth())));
- if (isPercentageIntrinsicSize)
- logicalWidth = logicalWidth * constrainedSize.width() / 100;
return computeReplacedLogicalWidthRespectingMinMaxWidth(logicalWidth, shouldComputePreferred);
}
}
@@ -455,13 +440,12 @@ LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const
RenderBox* contentRenderer = embeddedContentBox();
// 10.6.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-height
- bool isPercentageIntrinsicSize = false;
double intrinsicRatio = 0;
FloatSize constrainedSize;
- computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio, isPercentageIntrinsicSize);
+ computeAspectRatioInformationForRenderBox(contentRenderer, constrainedSize, intrinsicRatio);
bool widthIsAuto = style()->logicalWidth().isAuto();
- bool hasIntrinsicHeight = !isPercentageIntrinsicSize && constrainedSize.height() > 0;
+ bool hasIntrinsicHeight = constrainedSize.height() > 0;
// If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'.
if (widthIsAuto && hasIntrinsicHeight)
@@ -498,7 +482,7 @@ void RenderReplaced::computePreferredLogicalWidths()
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = computeReplacedLogicalWidth(ComputePreferred);
RenderStyle* styleToUse = style();
- if (styleToUse->logicalWidth().isPercent() || styleToUse->logicalMaxWidth().isPercent() || hasRelativeIntrinsicLogicalWidth())
+ if (styleToUse->logicalWidth().isPercent() || styleToUse->logicalMaxWidth().isPercent())
m_minPreferredLogicalWidth = 0;
if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
@@ -522,7 +506,7 @@ PositionWithAffinity RenderReplaced::positionForPoint(const LayoutPoint& point)
{
// FIXME: This code is buggy if the replaced element is relative positioned.
InlineBox* box = inlineBoxWrapper();
- RootInlineBox* rootBox = box ? box->root() : 0;
+ RootInlineBox* rootBox = box ? &box->root() : 0;
LayoutUnit top = rootBox ? rootBox->selectionTop() : logicalTop();
LayoutUnit bottom = rootBox ? rootBox->selectionBottom() : logicalBottom();
@@ -545,7 +529,7 @@ PositionWithAffinity RenderReplaced::positionForPoint(const LayoutPoint& point)
return RenderBox::positionForPoint(point);
}
-LayoutRect RenderReplaced::selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent)
+LayoutRect RenderReplaced::selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, bool clipToVisibleContent)
{
ASSERT(!needsLayout());
@@ -554,9 +538,9 @@ LayoutRect RenderReplaced::selectionRectForRepaint(const RenderLayerModelObject*
LayoutRect rect = localSelectionRect();
if (clipToVisibleContent)
- computeRectForRepaint(repaintContainer, rect);
+ mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect);
else
- rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
+ rect = localToContainerQuad(FloatRect(rect), paintInvalidationContainer).enclosingBoundingBox();
return rect;
}
@@ -566,15 +550,15 @@ LayoutRect RenderReplaced::localSelectionRect(bool checkWhetherSelected) const
if (checkWhetherSelected && !isSelected())
return LayoutRect();
- if (!m_inlineBoxWrapper)
+ if (!inlineBoxWrapper())
// We're a block-level replaced element. Just return our own dimensions.
return LayoutRect(LayoutPoint(), size());
- RootInlineBox* root = m_inlineBoxWrapper->root();
- LayoutUnit newLogicalTop = root->block()->style()->isFlippedBlocksWritingMode() ? m_inlineBoxWrapper->logicalBottom() - root->selectionBottom() : root->selectionTop() - m_inlineBoxWrapper->logicalTop();
- if (root->block()->style()->isHorizontalWritingMode())
- return LayoutRect(0, newLogicalTop, width(), root->selectionHeight());
- return LayoutRect(newLogicalTop, 0, root->selectionHeight(), height());
+ RootInlineBox& root = inlineBoxWrapper()->root();
+ LayoutUnit newLogicalTop = root.block().style()->isFlippedBlocksWritingMode() ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() : root.selectionTop() - inlineBoxWrapper()->logicalTop();
+ if (root.block().style()->isHorizontalWritingMode())
+ return LayoutRect(0, newLogicalTop, width(), root.selectionHeight());
+ return LayoutRect(newLogicalTop, 0, root.selectionHeight(), height());
}
void RenderReplaced::setSelectionState(SelectionState state)
@@ -582,9 +566,16 @@ void RenderReplaced::setSelectionState(SelectionState state)
// The selection state for our containing block hierarchy is updated by the base class call.
RenderBox::setSelectionState(state);
- if (m_inlineBoxWrapper && canUpdateSelectionOnRootLineBoxes())
- if (RootInlineBox* root = m_inlineBoxWrapper->root())
- root->setHasSelectedChildren(isSelected());
+ if (!inlineBoxWrapper())
+ return;
+
+ // We only include the space below the baseline in our layer's cached repaint rect if the
+ // image is selected. Since the selection state has changed update the rect.
+ if (hasLayer())
+ layer()->repainter().computeRepaintRects();
+
+ if (canUpdateSelectionOnRootLineBoxes())
+ inlineBoxWrapper()->root().setHasSelectedChildren(isSelected());
}
bool RenderReplaced::isSelected() const
@@ -600,7 +591,7 @@ bool RenderReplaced::isSelected() const
if (s == SelectionStart)
return selectionStart == 0;
- int end = node()->hasChildNodes() ? node()->childNodeCount() : 1;
+ int end = node()->hasChildren() ? node()->countChildren() : 1;
if (s == SelectionEnd)
return selectionEnd == end;
if (s == SelectionBoth)
@@ -609,28 +600,23 @@ bool RenderReplaced::isSelected() const
ASSERT(0);
return false;
}
-
-LayoutRect RenderReplaced::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+LayoutRect RenderReplaced::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
return LayoutRect();
// The selectionRect can project outside of the overflowRect, so take their union
// for repainting to avoid selection painting glitches.
- LayoutRect r = unionRect(localSelectionRect(false), visualOverflowRect());
+ LayoutRect r = isSelected() ? localSelectionRect() : visualOverflowRect();
RenderView* v = view();
- if (v) {
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && v) {
// FIXME: layoutDelta needs to be applied in parts before/after transforms and
// repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
r.move(v->layoutDelta());
}
- if (style()) {
- if (v)
- r.inflate(style()->outlineSize());
- }
- computeRectForRepaint(repaintContainer, r);
+ mapRectToPaintInvalidationBacking(paintInvalidationContainer, r);
return r;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.h b/chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.h
index e5db970baa1..fa20c6b9a7e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderReplaced.h
@@ -33,57 +33,57 @@ public:
virtual ~RenderReplaced();
virtual LayoutUnit computeReplacedLogicalWidth(ShouldComputePreferred = ComputeActual) const OVERRIDE;
- virtual LayoutUnit computeReplacedLogicalHeight() const;
+ virtual LayoutUnit computeReplacedLogicalHeight() const OVERRIDE;
- bool hasReplacedLogicalWidth() const;
bool hasReplacedLogicalHeight() const;
+ LayoutRect replacedContentRect(const LayoutSize* overriddenIntrinsicSize = 0) const;
virtual bool needsPreferredWidthsRecalculation() const OVERRIDE;
protected:
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
- virtual void layout();
+ virtual void layout() OVERRIDE;
virtual LayoutSize intrinsicSize() const OVERRIDE FINAL { return m_intrinsicSize; }
- LayoutRect replacedContentRect(const LayoutSize* overriddenIntrinsicSize = 0) const;
- virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const;
+ virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const OVERRIDE;
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE FINAL;
+ virtual LayoutUnit intrinsicContentLogicalHeight() const { return intrinsicLogicalHeight(); }
+
virtual LayoutUnit minimumReplacedHeight() const { return LayoutUnit(); }
virtual void setSelectionState(SelectionState) OVERRIDE FINAL;
bool isSelected() const;
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
void setIntrinsicSize(const LayoutSize& intrinsicSize) { m_intrinsicSize = intrinsicSize; }
virtual void intrinsicSizeChanged();
- virtual bool hasRelativeIntrinsicLogicalWidth() const { return false; }
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
bool shouldPaint(PaintInfo&, const LayoutPoint&);
LayoutRect localSelectionRect(bool checkWhetherSelected = true) const; // This is in local coordinates, but it's a physical rect (so the top left corner is physical top left).
+ virtual RenderBox* embeddedContentBox() const { return 0; }
private:
- virtual RenderBox* embeddedContentBox() const { return 0; }
- virtual const char* renderName() const { return "RenderReplaced"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderReplaced"; }
- virtual bool canHaveChildren() const { return false; }
+ virtual bool canHaveChildren() const OVERRIDE { return false; }
virtual void computePreferredLogicalWidths() OVERRIDE FINAL;
virtual void paintReplaced(PaintInfo&, const LayoutPoint&) { }
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE;
virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
- virtual bool canBeSelectionLeaf() const { return true; }
+ virtual bool canBeSelectionLeaf() const OVERRIDE { return true; }
- virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) OVERRIDE FINAL;
- void computeAspectRatioInformationForRenderBox(RenderBox*, FloatSize& constrainedSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const;
+ virtual LayoutRect selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, bool clipToVisibleContent = true) OVERRIDE FINAL;
+ void computeAspectRatioInformationForRenderBox(RenderBox*, FloatSize& constrainedSize, double& intrinsicRatio) const;
mutable LayoutSize m_intrinsicSize;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderReplica.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderReplica.cpp
index d7885c27909..ad083b27ae9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderReplica.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderReplica.cpp
@@ -30,7 +30,6 @@
#include "core/rendering/RenderReplica.h"
#include "core/rendering/GraphicsContextAnnotator.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderLayer.h"
namespace WebCore {
@@ -58,9 +57,9 @@ RenderReplica::~RenderReplica()
void RenderReplica::layout()
{
- LayoutRectRecorder recorder(*this);
setFrameRect(parentBox()->borderBoxRect());
- updateLayerTransform();
+ addVisualOverflow(parentBox()->visualOverflowRect());
+ updateLayerTransformAfterLayout();
clearNeedsLayout();
}
@@ -84,7 +83,7 @@ void RenderReplica::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
// Turn around and paint the parent layer. Use temporary clipRects, so that the layer doesn't end up caching clip rects
// computing using the wrong rootLayer
RenderLayer* rootPaintingLayer = layer()->transform() ? layer()->parent() : layer()->enclosingTransformedAncestor();
- LayerPaintingInfo paintingInfo(rootPaintingLayer, paintInfo.rect, PaintBehaviorNormal, LayoutSize(), 0, paintInfo.renderRegion);
+ LayerPaintingInfo paintingInfo(rootPaintingLayer, paintInfo.rect, PaintBehaviorNormal, LayoutSize(), 0);
PaintLayerFlags flags = PaintLayerHaveTransparency | PaintLayerAppliedTransform | PaintLayerTemporaryClipRects | PaintLayerPaintingReflection;
layer()->parent()->paintLayer(paintInfo.context, paintingInfo, flags);
} else if (paintInfo.phase == PaintPhaseMask)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderReplica.h b/chromium/third_party/WebKit/Source/core/rendering/RenderReplica.h
index 43bee56f207..84bbc6fab5f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderReplica.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderReplica.h
@@ -39,19 +39,19 @@ public:
virtual ~RenderReplica();
- virtual const char* renderName() const { return "RenderReplica"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderReplica"; }
- virtual bool requiresLayer() const { return true; }
+ virtual LayerType layerTypeRequired() const OVERRIDE { return NormalLayer; }
- virtual void layout();
+ virtual void layout() OVERRIDE;
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
private:
RenderReplica();
- virtual bool isReplica() const { return true; }
- virtual void computePreferredLogicalWidths();
+ virtual bool isReplica() const OVERRIDE { return true; }
+ virtual void computePreferredLogicalWidths() OVERRIDE;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRuby.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderRuby.cpp
index 8a9ef79b624..5383683eebd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRuby.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRuby.cpp
@@ -58,27 +58,27 @@ static inline bool isRubyBeforeBlock(const RenderObject* object)
{
return isAnonymousRubyInlineBlock(object)
&& !object->previousSibling()
- && object->firstChild()
- && object->firstChild()->style()->styleType() == BEFORE;
+ && toRenderBlock(object)->firstChild()
+ && toRenderBlock(object)->firstChild()->style()->styleType() == BEFORE;
}
static inline bool isRubyAfterBlock(const RenderObject* object)
{
return isAnonymousRubyInlineBlock(object)
&& !object->nextSibling()
- && object->firstChild()
- && object->firstChild()->style()->styleType() == AFTER;
+ && toRenderBlock(object)->firstChild()
+ && toRenderBlock(object)->firstChild()->style()->styleType() == AFTER;
}
static inline RenderBlock* rubyBeforeBlock(const RenderObject* ruby)
{
- RenderObject* child = ruby->firstChild();
+ RenderObject* child = ruby->slowFirstChild();
return isRubyBeforeBlock(child) ? toRenderBlock(child) : 0;
}
static inline RenderBlock* rubyAfterBlock(const RenderObject* ruby)
{
- RenderObject* child = ruby->lastChild();
+ RenderObject* child = ruby->slowLastChild();
return isRubyAfterBlock(child) ? toRenderBlock(child) : 0;
}
@@ -92,7 +92,7 @@ static RenderBlockFlow* createAnonymousRubyInlineBlock(RenderObject* ruby)
static RenderRubyRun* lastRubyRun(const RenderObject* ruby)
{
- RenderObject* child = ruby->lastChild();
+ RenderObject* child = ruby->slowLastChild();
if (child && !child->isRubyRun())
child = child->previousSibling();
ASSERT(!child || child->isRubyRun() || child->isBeforeContent() || child == rubyBeforeBlock(ruby));
@@ -225,7 +225,7 @@ RenderRubyAsBlock::~RenderRubyAsBlock()
void RenderRubyAsBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- RenderBlock::styleDidChange(diff, oldStyle);
+ RenderBlockFlow::styleDidChange(diff, oldStyle);
propagateStyleToAnonymousChildren();
}
@@ -235,13 +235,13 @@ void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
if (child->isBeforeContent()) {
if (child->isInline()) {
// Add generated inline content normally
- RenderBlock::addChild(child, firstChild());
+ RenderBlockFlow::addChild(child, firstChild());
} else {
// Wrap non-inline content with an anonymous inline-block.
RenderBlock* beforeBlock = rubyBeforeBlock(this);
if (!beforeBlock) {
beforeBlock = createAnonymousRubyInlineBlock(this);
- RenderBlock::addChild(beforeBlock, firstChild());
+ RenderBlockFlow::addChild(beforeBlock, firstChild());
}
beforeBlock->addChild(child);
}
@@ -250,13 +250,13 @@ void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
if (child->isAfterContent()) {
if (child->isInline()) {
// Add generated inline content normally
- RenderBlock::addChild(child);
+ RenderBlockFlow::addChild(child);
} else {
// Wrap non-inline content with an anonymous inline-block.
RenderBlock* afterBlock = rubyAfterBlock(this);
if (!afterBlock) {
afterBlock = createAnonymousRubyInlineBlock(this);
- RenderBlock::addChild(afterBlock);
+ RenderBlockFlow::addChild(afterBlock);
}
afterBlock->addChild(child);
}
@@ -265,7 +265,7 @@ void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
// If the child is a ruby run, just add it normally.
if (child->isRubyRun()) {
- RenderBlock::addChild(child, beforeChild);
+ RenderBlockFlow::addChild(child, beforeChild);
return;
}
@@ -289,7 +289,7 @@ void RenderRubyAsBlock::addChild(RenderObject* child, RenderObject* beforeChild)
RenderRubyRun* lastRun = lastRubyRun(this);
if (!lastRun || lastRun->hasRubyText()) {
lastRun = RenderRubyRun::staticCreateRubyRun(this);
- RenderBlock::addChild(lastRun, beforeChild);
+ RenderBlockFlow::addChild(lastRun, beforeChild);
}
lastRun->addChild(child);
}
@@ -300,7 +300,7 @@ void RenderRubyAsBlock::removeChild(RenderObject* child)
// just use the normal remove method.
if (child->parent() == this) {
ASSERT(child->isRubyRun() || child->isBeforeContent() || child->isAfterContent() || isAnonymousRubyInlineBlock(child));
- RenderBlock::removeChild(child);
+ RenderBlockFlow::removeChild(child);
return;
}
// If the child's parent is an anoymous block (must be generated :before/:after content)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRuby.h b/chromium/third_party/WebKit/Source/core/rendering/RenderRuby.h
index d9da35b9f3b..cd0a7fc6db0 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRuby.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRuby.h
@@ -56,18 +56,16 @@ public:
RenderRubyAsInline(Element*);
virtual ~RenderRubyAsInline();
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
- virtual void removeChild(RenderObject* child);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
+ virtual void removeChild(RenderObject* child) OVERRIDE;
protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
private:
- virtual bool isRuby() const { return true; }
- virtual const char* renderName() const { return "RenderRuby (inline)"; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
- virtual bool createsAnonymousWrapper() const { return true; }
- virtual void removeLeftoverAnonymousBlock(RenderBlock*) { ASSERT_NOT_REACHED(); }
+ virtual bool isRuby() const OVERRIDE { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderRuby (inline)"; }
+ virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
};
// <ruby> when used as 'display:block' or 'display:inline-block'
@@ -76,18 +74,17 @@ public:
RenderRubyAsBlock(Element*);
virtual ~RenderRubyAsBlock();
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
- virtual void removeChild(RenderObject* child);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
+ virtual void removeChild(RenderObject* child) OVERRIDE;
protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
private:
- virtual bool isRuby() const { return true; }
- virtual const char* renderName() const { return "RenderRuby (block)"; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
- virtual bool createsAnonymousWrapper() const { return true; }
- virtual void removeLeftoverAnonymousBlock(RenderBlock*) { ASSERT_NOT_REACHED(); }
+ virtual bool isRuby() const OVERRIDE { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderRuby (block)"; }
+ virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
+ virtual void removeLeftoverAnonymousBlock(RenderBlock*) OVERRIDE { ASSERT_NOT_REACHED(); }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.cpp
index e32478ed14b..1ceeec05486 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.cpp
@@ -73,8 +73,8 @@ void RenderRubyBase::moveChildren(RenderRubyBase* toBase, RenderObject* beforeCh
else
moveBlockChildren(toBase, beforeChild);
- setNeedsLayoutAndPrefWidthsRecalc();
- toBase->setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
+ toBase->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
void RenderRubyBase::moveInlineChildren(RenderRubyBase* toBase, RenderObject* beforeChild)
@@ -130,20 +130,12 @@ void RenderRubyBase::moveBlockChildren(RenderRubyBase* toBase, RenderObject* bef
moveChildrenTo(toBase, firstChild(), beforeChild);
}
-RenderRubyRun* RenderRubyBase::rubyRun() const
-{
- ASSERT(parent());
- ASSERT(parent()->isRubyRun());
-
- return toRenderRubyRun(parent());
-}
-
ETextAlign RenderRubyBase::textAlignmentForLine(bool /* endsWithSoftBreak */) const
{
return JUSTIFY;
}
-void RenderRubyBase::adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const
+void RenderRubyBase::adjustInlineDirectionLineBounds(unsigned expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const
{
int maxPreferredLogicalWidth = this->maxPreferredLogicalWidth();
if (maxPreferredLogicalWidth >= logicalWidth)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.h b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.h
index 197aebba507..98748be1157 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyBase.h
@@ -43,26 +43,22 @@ public:
static RenderRubyBase* createAnonymous(Document*);
- virtual const char* renderName() const { return "RenderRubyBase (anonymous)"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderRubyBase (anonymous)"; }
- virtual bool isRubyBase() const { return true; }
+ virtual bool isRubyBase() const OVERRIDE { return true; }
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
private:
RenderRubyBase();
- virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
- virtual void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const;
-
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const OVERRIDE;
+ virtual void adjustInlineDirectionLineBounds(unsigned expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const OVERRIDE;
void moveChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
void moveInlineChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
void moveBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
- RenderRubyRun* rubyRun() const;
-
// Allow RenderRubyRun to manipulate the children within ruby bases.
friend class RenderRubyRun;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.cpp
index fe58c872243..09c0146e75a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.cpp
@@ -32,7 +32,6 @@
#include "core/rendering/RenderRubyRun.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderRubyBase.h"
#include "core/rendering/RenderRubyText.h"
#include "core/rendering/RenderText.h"
@@ -66,11 +65,6 @@ bool RenderRubyRun::hasRubyBase() const
return lastChild() && lastChild()->isRubyBase();
}
-bool RenderRubyRun::isEmpty() const
-{
- return !hasRubyText() && !hasRubyBase();
-}
-
RenderRubyText* RenderRubyRun::rubyText() const
{
RenderObject* child = firstChild();
@@ -91,7 +85,7 @@ RenderRubyBase* RenderRubyRun::rubyBaseSafe()
RenderRubyBase* base = rubyBase();
if (!base) {
base = createRubyBase();
- RenderBlock::addChild(base);
+ RenderBlockFlow::addChild(base);
}
return base;
}
@@ -119,7 +113,7 @@ void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
// RenderRuby has already ascertained that we can add the child here.
ASSERT(!hasRubyText());
// prepend ruby texts as first child
- RenderBlock::addChild(child, firstChild());
+ RenderBlockFlow::addChild(child, firstChild());
} else if (beforeChild->isRubyText()) {
// New text is inserted just before another.
// In this case the new text takes the place of the old one, and
@@ -133,8 +127,8 @@ void RenderRubyRun::addChild(RenderObject* child, RenderObject* beforeChild)
// Note: Doing it in this order and not using RenderRubyRun's methods,
// in order to avoid automatic removal of the ruby run in case there is no
// other child besides the old ruby text.
- RenderBlock::addChild(child, beforeChild);
- RenderBlock::removeChild(beforeChild);
+ RenderBlockFlow::addChild(child, beforeChild);
+ RenderBlockFlow::removeChild(beforeChild);
newRun->addChild(beforeChild);
} else if (hasRubyBase()) {
// Insertion before a ruby base object.
@@ -176,20 +170,19 @@ void RenderRubyRun::removeChild(RenderObject* child)
}
}
- RenderBlock::removeChild(child);
+ RenderBlockFlow::removeChild(child);
if (!beingDestroyed() && !documentBeingDestroyed()) {
// Check if our base (if any) is now empty. If so, destroy it.
RenderBlock* base = rubyBase();
if (base && !base->firstChild()) {
- RenderBlock::removeChild(base);
+ RenderBlockFlow::removeChild(base);
base->deleteLineBoxTree();
base->destroy();
}
// If any of the above leaves the run empty, destroy it as well.
- if (isEmpty()) {
- parent()->removeChild(this);
+ if (!hasRubyText() && !hasRubyBase()) {
deleteLineBoxTree();
destroy();
}
@@ -229,8 +222,7 @@ RenderObject* RenderRubyRun::layoutSpecialExcludedChild(bool relayoutChildren, S
void RenderRubyRun::layout()
{
- LayoutRectRecorder recorder(*this);
- RenderBlock::layout();
+ RenderBlockFlow::layout();
RenderRubyText* rt = rubyText();
if (!rt)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.h b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.h
index 2005bc1322b..118533ae2b2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyRun.h
@@ -47,20 +47,19 @@ public:
bool hasRubyText() const;
bool hasRubyBase() const;
- bool isEmpty() const;
RenderRubyText* rubyText() const;
RenderRubyBase* rubyBase() const;
RenderRubyBase* rubyBaseSafe(); // creates the base if it doesn't already exist
- virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&);
- virtual void layout();
+ virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&) OVERRIDE;
+ virtual void layout() OVERRIDE;
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
- virtual void removeChild(RenderObject* child);
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
+ virtual void removeChild(RenderObject* child) OVERRIDE;
- virtual RenderBlock* firstLineBlock() const;
- virtual void updateFirstLetter();
+ virtual RenderBlock* firstLineBlock() const OVERRIDE;
+ virtual void updateFirstLetter() OVERRIDE;
void getOverhang(bool firstLine, RenderObject* startRenderer, RenderObject* endRenderer, int& startOverhang, int& endOverhang) const;
@@ -72,11 +71,10 @@ protected:
private:
RenderRubyRun();
- virtual bool isRubyRun() const { return true; }
- virtual const char* renderName() const { return "RenderRubyRun (anonymous)"; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
- virtual bool createsAnonymousWrapper() const { return true; }
- virtual void removeLeftoverAnonymousBlock(RenderBlock*) { }
+ virtual bool isRubyRun() const OVERRIDE { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderRubyRun (anonymous)"; }
+ virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
+ virtual void removeLeftoverAnonymousBlock(RenderBlock*) OVERRIDE { }
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderRubyRun, isRubyRun());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.cpp
index 3e5a60f0dfb..5e469787347 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.cpp
@@ -62,12 +62,12 @@ ETextAlign RenderRubyText::textAlignmentForLine(bool endsWithSoftBreak) const
return JUSTIFY;
}
-void RenderRubyText::adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const
+void RenderRubyText::adjustInlineDirectionLineBounds(unsigned expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const
{
ETextAlign textAlign = style()->textAlign();
// FIXME: This check is bogus since user can set the initial value.
if (textAlign != RenderStyle::initialTextAlign())
- return RenderBlock::adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, logicalWidth);
+ return RenderBlockFlow::adjustInlineDirectionLineBounds(expansionOpportunityCount, logicalLeft, logicalWidth);
int maxPreferredLogicalWidth = this->maxPreferredLogicalWidth();
if (maxPreferredLogicalWidth >= logicalWidth)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.h b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.h
index b1cb992c5eb..1e2b636acdc 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderRubyText.h
@@ -40,19 +40,17 @@ public:
RenderRubyText(Element*);
virtual ~RenderRubyText();
- virtual const char* renderName() const { return "RenderRubyText"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderRubyText"; }
- virtual bool isRubyText() const { return true; }
+ virtual bool isRubyText() const OVERRIDE { return true; }
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
private:
- virtual bool avoidsFloats() const;
+ virtual bool avoidsFloats() const OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
- virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const;
- virtual void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const;
+ virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const OVERRIDE;
+ virtual void adjustInlineDirectionLineBounds(unsigned expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.cpp
index a3aaeacba69..4ea0ba701ef 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.cpp
@@ -27,20 +27,21 @@
#include "core/rendering/RenderScrollbar.h"
#include "core/css/PseudoStyleRequest.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/RenderPart.h"
#include "core/rendering/RenderScrollbarPart.h"
#include "core/rendering/RenderScrollbarTheme.h"
+#include "platform/graphics/GraphicsContext.h"
namespace WebCore {
-PassRefPtr<Scrollbar> RenderScrollbar::createCustomScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, Frame* owningFrame)
+PassRefPtr<Scrollbar> RenderScrollbar::createCustomScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, LocalFrame* owningFrame)
{
return adoptRef(new RenderScrollbar(scrollableArea, orientation, ownerNode, owningFrame));
}
-RenderScrollbar::RenderScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, Frame* owningFrame)
+RenderScrollbar::RenderScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, LocalFrame* owningFrame)
: Scrollbar(scrollableArea, orientation, RegularScrollbar, RenderScrollbarTheme::renderScrollbarTheme())
, m_owner(ownerNode)
, m_owningFrame(owningFrame)
@@ -148,7 +149,7 @@ void RenderScrollbar::setPressedPart(ScrollbarPart part)
PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId)
{
if (!owningRenderer())
- return 0;
+ return nullptr;
RefPtr<RenderStyle> result = owningRenderer()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId, this, partType), owningRenderer()->style());
// Scrollbars for root frames should always have background color
@@ -156,7 +157,7 @@ PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart p
// This is because WebKit assumes scrollbar to be always painted and missing background
// causes visual artifact like non-repainted dirty region.
if (result && m_owningFrame && m_owningFrame->view() && !m_owningFrame->view()->isTransparent() && !result->hasBackground())
- result->setBackgroundColor(Color::white);
+ result->setBackgroundColor(StyleColor(Color::white));
return result;
}
@@ -223,9 +224,9 @@ void RenderScrollbar::updateScrollbarPart(ScrollbarPart partType, bool destroy)
if (partType == NoPart)
return;
- RefPtr<RenderStyle> partStyle = !destroy ? getScrollbarPseudoStyle(partType, pseudoForScrollbarPart(partType)) : PassRefPtr<RenderStyle>(0);
+ RefPtr<RenderStyle> partStyle = !destroy ? getScrollbarPseudoStyle(partType, pseudoForScrollbarPart(partType)) : PassRefPtr<RenderStyle>(nullptr);
- bool needRenderer = !destroy && partStyle && partStyle->display() != NONE && partStyle->visibility() == VISIBLE;
+ bool needRenderer = !destroy && partStyle && partStyle->display() != NONE;
if (needRenderer && partStyle->display() != BLOCK) {
// See if we are a button that should not be visible according to OS settings.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.h b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.h
index fcb60151a20..7d29c397224 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbar.h
@@ -32,19 +32,19 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class Node;
class RenderBox;
class RenderScrollbarPart;
class RenderStyle;
-class RenderScrollbar : public Scrollbar {
+class RenderScrollbar FINAL : public Scrollbar {
protected:
- RenderScrollbar(ScrollableArea*, ScrollbarOrientation, Node*, Frame*);
+ RenderScrollbar(ScrollableArea*, ScrollbarOrientation, Node*, LocalFrame*);
public:
friend class Scrollbar;
- static PassRefPtr<Scrollbar> createCustomScrollbar(ScrollableArea*, ScrollbarOrientation, Node*, Frame* owningFrame = 0);
+ static PassRefPtr<Scrollbar> createCustomScrollbar(ScrollableArea*, ScrollbarOrientation, Node*, LocalFrame* owningFrame = 0);
virtual ~RenderScrollbar();
RenderBox* owningRenderer() const;
@@ -57,20 +57,20 @@ public:
int minimumThumbLength();
- virtual bool isOverlayScrollbar() const { return false; }
+ virtual bool isOverlayScrollbar() const OVERRIDE { return false; }
private:
virtual void setParent(Widget*) OVERRIDE;
- virtual void setEnabled(bool);
+ virtual void setEnabled(bool) OVERRIDE;
- virtual void paint(GraphicsContext*, const IntRect& damageRect);
+ virtual void paint(GraphicsContext*, const IntRect& damageRect) OVERRIDE;
- virtual void setHoveredPart(ScrollbarPart);
- virtual void setPressedPart(ScrollbarPart);
+ virtual void setHoveredPart(ScrollbarPart) OVERRIDE;
+ virtual void setPressedPart(ScrollbarPart) OVERRIDE;
- virtual void styleChanged();
+ virtual void styleChanged() OVERRIDE;
- virtual bool isCustomScrollbar() const { return true; }
+ virtual bool isCustomScrollbar() const OVERRIDE { return true; }
void updateScrollbarParts(bool destroy = false);
@@ -81,9 +81,9 @@ private:
// so we keep a reference to the Node which caused this custom scrollbar creation.
// This will not create a reference cycle as the Widget tree is owned by our containing
// FrameView which this Node pointer can in no way keep alive. See webkit bug 80610.
- RefPtr<Node> m_owner;
+ RefPtrWillBePersistent<Node> m_owner;
- Frame* m_owningFrame;
+ LocalFrame* m_owningFrame;
HashMap<unsigned, RenderScrollbarPart*> m_parts;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.cpp
index 13a35ebb832..927079a1fdf 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.cpp
@@ -26,11 +26,11 @@
#include "config.h"
#include "core/rendering/RenderScrollbarPart.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/RenderScrollbarTheme.h"
#include "core/rendering/RenderView.h"
+#include "platform/LengthFunctions.h"
using namespace std;
@@ -56,7 +56,6 @@ RenderScrollbarPart* RenderScrollbarPart::createAnonymous(Document* document, Re
void RenderScrollbarPart::layout()
{
- LayoutRectRecorder recorder(*this);
setLocation(LayoutPoint()); // We don't worry about positioning ourselves. We're just determining our minimum width/height.
if (m_scrollbar->orientation() == HorizontalScrollbar)
layoutHorizontalPart();
@@ -88,10 +87,10 @@ void RenderScrollbarPart::layoutVerticalPart()
}
}
-static int calcScrollbarThicknessUsing(SizeType sizeType, const Length& length, int containingLength, RenderView* renderView)
+static int calcScrollbarThicknessUsing(SizeType sizeType, const Length& length, int containingLength)
{
if (!length.isIntrinsicOrAuto() || (sizeType == MinSize && length.isAuto()))
- return minimumValueForLength(length, containingLength, renderView);
+ return minimumValueForLength(length, containingLength);
return ScrollbarTheme::theme()->scrollbarThickness();
}
@@ -99,36 +98,34 @@ void RenderScrollbarPart::computeScrollbarWidth()
{
if (!m_scrollbar->owningRenderer())
return;
- RenderView* renderView = view();
// FIXME: We are querying layout information but nothing guarantees that it's up-to-date, especially since we are called at style change.
// FIXME: Querying the style's border information doesn't work on table cells with collapsing borders.
int visibleSize = m_scrollbar->owningRenderer()->width() - m_scrollbar->owningRenderer()->style()->borderLeftWidth() - m_scrollbar->owningRenderer()->style()->borderRightWidth();
- int w = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->width(), visibleSize, renderView);
- int minWidth = calcScrollbarThicknessUsing(MinSize, style()->minWidth(), visibleSize, renderView);
- int maxWidth = style()->maxWidth().isUndefined() ? w : calcScrollbarThicknessUsing(MaxSize, style()->maxWidth(), visibleSize, renderView);
+ int w = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->width(), visibleSize);
+ int minWidth = calcScrollbarThicknessUsing(MinSize, style()->minWidth(), visibleSize);
+ int maxWidth = style()->maxWidth().isUndefined() ? w : calcScrollbarThicknessUsing(MaxSize, style()->maxWidth(), visibleSize);
setWidth(max(minWidth, min(maxWidth, w)));
// Buttons and track pieces can all have margins along the axis of the scrollbar.
- m_marginBox.setLeft(minimumValueForLength(style()->marginLeft(), visibleSize, renderView));
- m_marginBox.setRight(minimumValueForLength(style()->marginRight(), visibleSize, renderView));
+ m_marginBox.setLeft(minimumValueForLength(style()->marginLeft(), visibleSize));
+ m_marginBox.setRight(minimumValueForLength(style()->marginRight(), visibleSize));
}
void RenderScrollbarPart::computeScrollbarHeight()
{
if (!m_scrollbar->owningRenderer())
return;
- RenderView* renderView = view();
// FIXME: We are querying layout information but nothing guarantees that it's up-to-date, especially since we are called at style change.
// FIXME: Querying the style's border information doesn't work on table cells with collapsing borders.
int visibleSize = m_scrollbar->owningRenderer()->height() - m_scrollbar->owningRenderer()->style()->borderTopWidth() - m_scrollbar->owningRenderer()->style()->borderBottomWidth();
- int h = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->height(), visibleSize, renderView);
- int minHeight = calcScrollbarThicknessUsing(MinSize, style()->minHeight(), visibleSize, renderView);
- int maxHeight = style()->maxHeight().isUndefined() ? h : calcScrollbarThicknessUsing(MaxSize, style()->maxHeight(), visibleSize, renderView);
+ int h = calcScrollbarThicknessUsing(MainOrPreferredSize, style()->height(), visibleSize);
+ int minHeight = calcScrollbarThicknessUsing(MinSize, style()->minHeight(), visibleSize);
+ int maxHeight = style()->maxHeight().isUndefined() ? h : calcScrollbarThicknessUsing(MaxSize, style()->maxHeight(), visibleSize);
setHeight(max(minHeight, min(maxHeight, h)));
// Buttons and track pieces can all have margins along the axis of the scrollbar.
- m_marginBox.setTop(minimumValueForLength(style()->marginTop(), visibleSize, renderView));
- m_marginBox.setBottom(minimumValueForLength(style()->marginBottom(), visibleSize, renderView));
+ m_marginBox.setTop(minimumValueForLength(style()->marginTop(), visibleSize));
+ m_marginBox.setBottom(minimumValueForLength(style()->marginBottom(), visibleSize));
}
void RenderScrollbarPart::computePreferredLogicalWidths()
@@ -141,7 +138,7 @@ void RenderScrollbarPart::computePreferredLogicalWidths()
clearPreferredLogicalWidthsDirty();
}
-void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
+void RenderScrollbarPart::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
{
RenderBlock::styleWillChange(diff, newStyle);
setInline(false);
@@ -154,7 +151,7 @@ void RenderScrollbarPart::styleDidChange(StyleDifference diff, const RenderStyle
clearPositionedState();
setFloating(false);
setHasOverflowClip(false);
- if (oldStyle && m_scrollbar && m_part != NoPart && diff >= StyleDifferenceRepaint)
+ if (oldStyle && m_scrollbar && m_part != NoPart && (diff.needsRepaint() || diff.needsLayout()))
m_scrollbar->theme()->invalidatePart(m_scrollbar, m_part);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.h b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.h
index a1f24654f4b..f289ce6f431 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarPart.h
@@ -39,11 +39,11 @@ public:
virtual ~RenderScrollbarPart();
- virtual const char* renderName() const { return "RenderScrollbarPart"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderScrollbarPart"; }
- virtual bool requiresLayer() const { return false; }
+ virtual LayerType layerTypeRequired() const OVERRIDE { return NoLayer; }
- virtual void layout();
+ virtual void layout() OVERRIDE;
void paintIntoRect(GraphicsContext*, const LayoutPoint&, const LayoutRect&);
@@ -53,20 +53,31 @@ public:
virtual LayoutUnit marginLeft() const OVERRIDE { ASSERT(isIntegerValue(m_marginBox.left())); return m_marginBox.left(); }
virtual LayoutUnit marginRight() const OVERRIDE { ASSERT(isIntegerValue(m_marginBox.right())); return m_marginBox.right(); }
- virtual bool isRenderScrollbarPart() const { return true; }
+ virtual bool isRenderScrollbarPart() const OVERRIDE { return true; }
RenderObject* rendererOwningScrollbar() const;
protected:
- virtual void styleWillChange(StyleDifference diff, const RenderStyle* newStyle);
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual void styleWillChange(StyleDifference, const RenderStyle& newStyle) OVERRIDE;
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
private:
RenderScrollbarPart(RenderScrollbar*, ScrollbarPart);
- virtual void computePreferredLogicalWidths();
-
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual void computePreferredLogicalWidths() OVERRIDE;
+
+ // Have all padding getters return 0. The important point here is to avoid resolving percents
+ // against the containing block, since scroll bar corners don't always have one (so it would
+ // crash). Scroll bar corners are not actually laid out, and they don't have child content, so
+ // what we return here doesn't really matter.
+ virtual LayoutUnit paddingTop() const OVERRIDE { return LayoutUnit(); }
+ virtual LayoutUnit paddingBottom() const OVERRIDE { return LayoutUnit(); }
+ virtual LayoutUnit paddingLeft() const OVERRIDE { return LayoutUnit(); }
+ virtual LayoutUnit paddingRight() const OVERRIDE { return LayoutUnit(); }
+ virtual LayoutUnit paddingBefore() const OVERRIDE { return LayoutUnit(); }
+ virtual LayoutUnit paddingAfter() const OVERRIDE { return LayoutUnit(); }
+ virtual LayoutUnit paddingStart() const OVERRIDE { return LayoutUnit(); }
+ virtual LayoutUnit paddingEnd() const OVERRIDE { return LayoutUnit(); }
void layoutHorizontalPart();
void layoutVerticalPart();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.cpp
index 63f1a1e23d5..dad81e83bec 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "core/rendering/RenderScrollbar.h"
#include "core/rendering/RenderScrollbarTheme.h"
+#include "platform/graphics/GraphicsContext.h"
#include "platform/scroll/ScrollbarThemeClient.h"
#include "wtf/StdLibExtras.h"
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.h b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.h
index 0b5b56e8145..56431e48b5f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderScrollbarTheme.h
@@ -31,9 +31,8 @@
namespace WebCore {
class PlatformMouseEvent;
-class Scrollbar;
-class RenderScrollbarTheme : public ScrollbarTheme {
+class RenderScrollbarTheme FINAL : public ScrollbarTheme {
public:
virtual ~RenderScrollbarTheme() { }
@@ -41,11 +40,10 @@ public:
virtual ScrollbarButtonsPlacement buttonsPlacement() const OVERRIDE { return ScrollbarTheme::theme()->buttonsPlacement(); }
- virtual bool supportsControlTints() const OVERRIDE { return true; }
-
virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect) OVERRIDE;
virtual bool shouldCenterOnThumb(ScrollbarThemeClient* scrollbar, const PlatformMouseEvent& event) OVERRIDE { return ScrollbarTheme::theme()->shouldCenterOnThumb(scrollbar, event); }
+ virtual bool shouldSnapBackToDragOrigin(ScrollbarThemeClient* scrollbar, const PlatformMouseEvent& event) OVERRIDE { return ScrollbarTheme::theme()->shouldSnapBackToDragOrigin(scrollbar, event); }
virtual double initialAutoscrollTimerDelay() OVERRIDE { return ScrollbarTheme::theme()->initialAutoscrollTimerDelay(); }
virtual double autoscrollTimerDelay() OVERRIDE { return ScrollbarTheme::theme()->autoscrollTimerDelay(); }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderSelectionInfo.h b/chromium/third_party/WebKit/Source/core/rendering/RenderSelectionInfo.h
index d3ec42d5720..6cdb43649f4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderSelectionInfo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderSelectionInfo.h
@@ -42,18 +42,18 @@ public:
RenderSelectionInfoBase(RenderObject* o)
: m_object(o)
- , m_repaintContainer(o->containerForRepaint())
+ , m_repaintContainer(o->containerForPaintInvalidation())
, m_state(o->selectionState())
{
}
RenderObject* object() const { return m_object; }
- RenderLayerModelObject* repaintContainer() const { return m_repaintContainer; }
+ const RenderLayerModelObject* repaintContainer() const { return m_repaintContainer; }
RenderObject::SelectionState state() const { return m_state; }
protected:
RenderObject* m_object;
- RenderLayerModelObject* m_repaintContainer;
+ const RenderLayerModelObject* m_repaintContainer;
RenderObject::SelectionState m_state;
};
@@ -62,13 +62,20 @@ class RenderSelectionInfo : public RenderSelectionInfoBase {
public:
RenderSelectionInfo(RenderObject* o, bool clipToVisibleContent)
: RenderSelectionInfoBase(o)
- , m_rect(o->canUpdateSelectionOnRootLineBoxes() ? o->selectionRectForRepaint(m_repaintContainer, clipToVisibleContent) : LayoutRect())
{
+ if (o->canUpdateSelectionOnRootLineBoxes()) {
+ m_rect = o->selectionRectForPaintInvalidation(m_repaintContainer, clipToVisibleContent);
+ // FIXME: groupedMapping() leaks the squashing abstraction. See RenderBlockSelectionInfo for more details.
+ if (m_repaintContainer && m_repaintContainer->groupedMapping())
+ RenderLayer::mapRectToRepaintBacking(m_repaintContainer, m_repaintContainer, m_rect);
+ } else {
+ m_rect = LayoutRect();
+ }
}
void repaint()
{
- m_object->repaintUsingContainer(m_repaintContainer, enclosingIntRect(m_rect));
+ m_object->invalidatePaintUsingContainer(m_repaintContainer, enclosingIntRect(m_rect), InvalidationSelection);
}
LayoutRect rect() const { return m_rect; }
@@ -83,13 +90,22 @@ class RenderBlockSelectionInfo : public RenderSelectionInfoBase {
public:
RenderBlockSelectionInfo(RenderBlock* b)
: RenderSelectionInfoBase(b)
- , m_rects(b->canUpdateSelectionOnRootLineBoxes() ? block()->selectionGapRectsForRepaint(m_repaintContainer) : GapRects())
{
+ if (b->canUpdateSelectionOnRootLineBoxes())
+ m_rects = block()->selectionGapRectsForRepaint(m_repaintContainer);
+ else
+ m_rects = GapRects();
}
void repaint()
{
- m_object->repaintUsingContainer(m_repaintContainer, enclosingIntRect(m_rects));
+ LayoutRect repaintRect = enclosingIntRect(m_rects);
+ // FIXME: this is leaking the squashing abstraction. However, removing the groupedMapping() condiitional causes
+ // RenderBox::mapRectToRepaintBacking to get called, which makes rect adjustments even if you pass the same
+ // repaintContainer as the render object. Find out why it does that and fix.
+ if (m_repaintContainer && m_repaintContainer->groupedMapping())
+ RenderLayer::mapRectToRepaintBacking(m_repaintContainer, m_repaintContainer, repaintRect);
+ m_object->invalidatePaintUsingContainer(m_repaintContainer, enclosingIntRect(repaintRect), InvalidationSelection);
}
RenderBlock* block() const { return toRenderBlock(m_object); }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderSlider.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderSlider.cpp
index 73e4d67bdda..0dff3af336e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderSlider.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderSlider.cpp
@@ -25,7 +25,6 @@
#include "core/html/HTMLInputElement.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/html/shadow/SliderThumbElement.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "wtf/MathExtras.h"
using std::min;
@@ -63,20 +62,21 @@ void RenderSlider::computePreferredLogicalWidths()
{
m_minPreferredLogicalWidth = 0;
m_maxPreferredLogicalWidth = 0;
+ RenderStyle* styleToUse = style();
- if (style()->width().isFixed() && style()->width().value() > 0)
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->width().value());
+ if (styleToUse->width().isFixed() && styleToUse->width().value() > 0)
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->width().value());
else
computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
- if (style()->minWidth().isFixed() && style()->minWidth().value() > 0) {
- m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
- m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->minWidth().value()));
+ if (styleToUse->minWidth().isFixed() && styleToUse->minWidth().value() > 0) {
+ m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
+ m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->minWidth().value()));
}
- if (style()->maxWidth().isFixed()) {
- m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
- m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->maxWidth().value()));
+ if (styleToUse->maxWidth().isFixed()) {
+ m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
+ m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->maxWidth().value()));
}
LayoutUnit toAdd = borderAndPaddingWidth();
@@ -93,7 +93,6 @@ inline SliderThumbElement* RenderSlider::sliderThumbElement() const
void RenderSlider::layout()
{
- LayoutRectRecorder recorder(*this);
// FIXME: Find a way to cascade appearance.
// http://webkit.org/b/62535
RenderBox* thumbBox = sliderThumbElement()->renderBox();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderSlider.h b/chromium/third_party/WebKit/Source/core/rendering/RenderSlider.h
index a627e2c0489..9d1fc60434b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderSlider.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderSlider.h
@@ -26,7 +26,6 @@
namespace WebCore {
class HTMLInputElement;
-class MouseEvent;
class SliderThumbElement;
class RenderSlider FINAL : public RenderFlexibleBox {
@@ -39,13 +38,13 @@ public:
bool inDragMode() const;
private:
- virtual const char* renderName() const { return "RenderSlider"; }
- virtual bool isSlider() const { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSlider"; }
+ virtual bool isSlider() const OVERRIDE { return true; }
- virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const;
+ virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
virtual void computePreferredLogicalWidths() OVERRIDE;
- virtual void layout();
+ virtual void layout() OVERRIDE;
SliderThumbElement* sliderThumbElement() const;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTable.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTable.cpp
index 5ca0c17e93e..ea196ecff95 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTable.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTable.cpp
@@ -4,7 +4,7 @@
* (C) 1998 Waldo Bastian (bastian@kde.org)
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
* This library is free software; you can redistribute it and/or
@@ -26,15 +26,15 @@
#include "config.h"
#include "core/rendering/RenderTable.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
-#include "core/html/HTMLTableElement.h"
#include "core/frame/FrameView.h"
+#include "core/html/HTMLTableElement.h"
#include "core/rendering/AutoTableLayout.h"
+#include "core/rendering/FastTextAutosizer.h"
#include "core/rendering/FixedTableLayout.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderTableCaption.h"
@@ -63,6 +63,7 @@ RenderTable::RenderTable(Element* element)
, m_needsSectionRecalc(false)
, m_columnLogicalWidthChanged(false)
, m_columnRenderersValid(false)
+ , m_hasCellColspanThatDeterminesTableWidth(false)
, m_hSpacing(0)
, m_vSpacing(0)
, m_borderStart(0)
@@ -82,20 +83,20 @@ void RenderTable::styleDidChange(StyleDifference diff, const RenderStyle* oldSty
RenderBlock::styleDidChange(diff, oldStyle);
propagateStyleToAnonymousChildren();
- ETableLayout oldTableLayout = oldStyle ? oldStyle->tableLayout() : TAUTO;
+ bool oldFixedTableLayout = oldStyle ? oldStyle->isFixedTableLayout() : false;
// In the collapsed border model, there is no cell spacing.
m_hSpacing = collapseBorders() ? 0 : style()->horizontalBorderSpacing();
m_vSpacing = collapseBorders() ? 0 : style()->verticalBorderSpacing();
m_columnPos[0] = m_hSpacing;
- if (!m_tableLayout || style()->tableLayout() != oldTableLayout) {
+ if (!m_tableLayout || style()->isFixedTableLayout() != oldFixedTableLayout) {
if (m_tableLayout)
m_tableLayout->willChangeTableLayout();
// According to the CSS2 spec, you only use fixed table layout if an
// explicit width is specified on the table. Auto width implies auto table layout.
- if (style()->tableLayout() == TFIXED && !style()->logicalWidth().isAuto())
+ if (style()->isFixedTableLayout())
m_tableLayout = adoptPtr(new FixedTableLayout(this));
else
m_tableLayout = adoptPtr(new AutoTableLayout(this));
@@ -117,6 +118,14 @@ static inline void resetSectionPointerIfNotBefore(RenderTableSection*& ptr, Rend
ptr = 0;
}
+static inline bool needsTableSection(RenderObject* object)
+{
+ // Return true if 'object' can't exist in an anonymous table without being
+ // wrapped in a table section box.
+ EDisplay display = object->style()->display();
+ return display != TABLE_CAPTION && display != TABLE_COLUMN_GROUP && display != TABLE_COLUMN;
+}
+
void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
{
bool wrapInAnonymousSection = !child->isOutOfFlowPositioned();
@@ -156,9 +165,7 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
default:
ASSERT_NOT_REACHED();
}
- } else if (child->isTableCell() || child->isTableRow())
- wrapInAnonymousSection = true;
- else
+ } else
wrapInAnonymousSection = true;
if (child->isTableSection())
@@ -186,16 +193,16 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
}
RenderObject* lastBox = beforeChild;
- while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableSection() && lastBox->style()->display() != TABLE_CAPTION && lastBox->style()->display() != TABLE_COLUMN_GROUP)
+ while (lastBox && lastBox->parent()->isAnonymous() && !lastBox->isTableSection() && needsTableSection(lastBox))
lastBox = lastBox->parent();
if (lastBox && lastBox->isAnonymous() && !isAfterContent(lastBox)) {
if (beforeChild == lastBox)
- beforeChild = lastBox->firstChild();
+ beforeChild = lastBox->slowFirstChild();
lastBox->addChild(child, beforeChild);
return;
}
- if (beforeChild && !beforeChild->isTableSection() && beforeChild->style()->display() != TABLE_CAPTION && beforeChild->style()->display() != TABLE_COLUMN_GROUP)
+ if (beforeChild && !beforeChild->isTableSection() && needsTableSection(beforeChild))
beforeChild = 0;
RenderTableSection* section = RenderTableSection::createAnonymousWithParentRenderer(this);
@@ -253,7 +260,6 @@ void RenderTable::updateLogicalWidth()
}
RenderBlock* cb = containingBlock();
- RenderView* renderView = view();
LayoutUnit availableLogicalWidth = containingBlockLogicalWidthForContent();
bool hasPerpendicularContainingBlock = cb->style()->isHorizontalWritingMode() != style()->isHorizontalWritingMode();
@@ -264,16 +270,14 @@ void RenderTable::updateLogicalWidth()
setLogicalWidth(convertStyleLogicalWidthToComputedWidth(styleLogicalWidth, containerWidthInInlineDirection));
else {
// Subtract out any fixed margins from our available width for auto width tables.
- LayoutUnit marginStart = minimumValueForLength(style()->marginStart(), availableLogicalWidth, renderView);
- LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd(), availableLogicalWidth, renderView);
+ LayoutUnit marginStart = minimumValueForLength(style()->marginStart(), availableLogicalWidth);
+ LayoutUnit marginEnd = minimumValueForLength(style()->marginEnd(), availableLogicalWidth);
LayoutUnit marginTotal = marginStart + marginEnd;
// Subtract out our margins to get the available content width.
LayoutUnit availableContentLogicalWidth = max<LayoutUnit>(0, containerWidthInInlineDirection - marginTotal);
- if (shrinkToAvoidFloats() && cb->containsFloats() && !hasPerpendicularContainingBlock) {
- // FIXME: Work with regions someday.
- availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, toRenderBlockFlow(cb), 0);
- }
+ if (shrinkToAvoidFloats() && cb->containsFloats() && !hasPerpendicularContainingBlock)
+ availableContentLogicalWidth = shrinkLogicalWidthToAvoidFloats(marginStart, marginEnd, toRenderBlockFlow(cb));
// Ensure we aren't bigger than our available width.
setLogicalWidth(min<int>(availableContentLogicalWidth, maxPreferredLogicalWidth()));
@@ -298,23 +302,10 @@ void RenderTable::updateLogicalWidth()
}
// Finally, with our true width determined, compute our margins for real.
- setMarginStart(0);
- setMarginEnd(0);
- if (!hasPerpendicularContainingBlock) {
- LayoutUnit containerLogicalWidthForAutoMargins = availableLogicalWidth;
- if (avoidsFloats() && cb->containsFloats())
- containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidthInRegion(0); // FIXME: Work with regions someday.
- ComputedMarginValues marginValues;
- bool hasInvertedDirection = cb->style()->isLeftToRightDirection() == style()->isLeftToRightDirection();
- computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, logicalWidth(),
- hasInvertedDirection ? marginValues.m_start : marginValues.m_end,
- hasInvertedDirection ? marginValues.m_end : marginValues.m_start);
- setMarginStart(marginValues.m_start);
- setMarginEnd(marginValues.m_end);
- } else {
- setMarginStart(minimumValueForLength(style()->marginStart(), availableLogicalWidth, renderView));
- setMarginEnd(minimumValueForLength(style()->marginEnd(), availableLogicalWidth, renderView));
- }
+ ComputedMarginValues marginValues;
+ computeMarginsForDirection(InlineDirection, cb, availableLogicalWidth, logicalWidth(), marginValues.m_start, marginValues.m_end, style()->marginStart(), style()->marginEnd());
+ setMarginStart(marginValues.m_start);
+ setMarginEnd(marginValues.m_end);
// We should NEVER shrink the table below the min-content logical width, or else the table can't accomodate
// its own content which doesn't match CSS nor what authors expect.
@@ -331,11 +322,11 @@ LayoutUnit RenderTable::convertStyleLogicalWidthToComputedWidth(const Length& st
// HTML tables' width styles already include borders and paddings, but CSS tables' width styles do not.
LayoutUnit borders = 0;
- bool isCSSTable = !node() || !isHTMLTableElement(node());
+ bool isCSSTable = !isHTMLTableElement(node());
if (isCSSTable && styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive() && style()->boxSizing() == CONTENT_BOX)
borders = borderStart() + borderEnd() + (collapseBorders() ? LayoutUnit() : paddingStart() + paddingEnd());
- return minimumValueForLength(styleLogicalWidth, availableWidth, view()) + borders;
+ return minimumValueForLength(styleLogicalWidth, availableWidth) + borders;
}
LayoutUnit RenderTable::convertStyleLogicalHeightToComputedHeight(const Length& styleLogicalHeight)
@@ -348,14 +339,12 @@ LayoutUnit RenderTable::convertStyleLogicalHeightToComputedHeight(const Length&
// HTML tables size as though CSS height includes border/padding, CSS tables do not.
LayoutUnit borders = LayoutUnit();
// FIXME: We cannot apply box-sizing: content-box on <table> which other browsers allow.
- if ((node() && isHTMLTableElement(node())) || style()->boxSizing() == BORDER_BOX) {
+ if (isHTMLTableElement(node()) || style()->boxSizing() == BORDER_BOX) {
borders = borderAndPadding;
}
computedLogicalHeight = styleLogicalHeight.value() - borders;
} else if (styleLogicalHeight.isPercent())
computedLogicalHeight = computePercentageLogicalHeight(styleLogicalHeight);
- else if (styleLogicalHeight.isViewportPercentage())
- computedLogicalHeight = minimumValueForLength(styleLogicalHeight, 0, view());
else if (styleLogicalHeight.isIntrinsic())
computedLogicalHeight = computeIntrinsicLogicalContentHeightUsing(styleLogicalHeight, logicalHeight() - borderAndPadding, borderAndPadding);
else
@@ -375,9 +364,14 @@ void RenderTable::layoutCaption(RenderTableCaption* caption)
caption->layoutIfNeeded();
}
// Apply the margins to the location now that they are definitely available from layout
- caption->setLogicalLocation(LayoutPoint(caption->marginStart(), collapsedMarginBeforeForChild(caption) + logicalHeight()));
+ LayoutUnit captionLogicalTop = collapsedMarginBeforeForChild(caption) + logicalHeight();
+ if (view()->layoutState()->isPaginated()) {
+ captionLogicalTop += caption->paginationStrut();
+ caption->setPaginationStrut(0);
+ }
+ caption->setLogicalLocation(LayoutPoint(caption->marginStart(), captionLogicalTop));
- if (!selfNeedsLayout() && caption->checkForRepaintDuringLayout())
+ if (!selfNeedsLayout() && caption->checkForPaintInvalidationDuringLayout())
caption->repaintDuringLayoutIfMoved(captionRect);
setLogicalHeight(logicalHeight() + caption->logicalHeight() + collapsedMarginBeforeForChild(caption) + collapsedMarginAfterForChild(caption));
@@ -409,172 +403,179 @@ void RenderTable::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
-
if (simplifiedLayout())
return;
+ // Note: RenderTable is handled differently than other RenderBlocks and the LayoutScope
+ // must be created before the table begins laying out.
+ FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
+
recalcSectionsIfNeeded();
// FIXME: We should do this recalc lazily in borderStart/borderEnd so that we don't have to make sure
// to call this before we call borderStart/borderEnd to avoid getting a stale value.
recalcBordersInRowDirection();
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
-
- setLogicalHeight(0);
-
- LayoutUnit oldLogicalWidth = logicalWidth();
- updateLogicalWidth();
-
- SubtreeLayoutScope layouter(this);
-
- if (logicalWidth() != oldLogicalWidth) {
- for (unsigned i = 0; i < m_captions.size(); i++)
- layouter.setNeedsLayout(m_captions[i]);
- }
- // FIXME: The optimisation below doesn't work since the internal table
- // layout could have changed. we need to add a flag to the table
- // layout that tells us if something has changed in the min max
- // calculations to do it correctly.
-// if ( oldWidth != width() || columns.size() + 1 != columnPos.size() )
- m_tableLayout->layout();
-
- LayoutUnit totalSectionLogicalHeight = 0;
- LayoutUnit oldTableLogicalTop = 0;
- for (unsigned i = 0; i < m_captions.size(); i++)
- oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
+ LayoutRepainter repainter(*this, checkForPaintInvalidationDuringLayout());
+ SubtreeLayoutScope layouter(*this);
- bool collapsing = collapseBorders();
-
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (child->isTableSection()) {
- RenderTableSection* section = toRenderTableSection(child);
- if (m_columnLogicalWidthChanged)
- layouter.setChildNeedsLayout(section);
- section->layoutIfNeeded();
- totalSectionLogicalHeight += section->calcRowLogicalHeight();
- if (collapsing)
- section->recalcOuterBorder();
- ASSERT(!section->needsLayout());
- } else if (child->isRenderTableCol()) {
- child->layoutIfNeeded();
- ASSERT(!child->needsLayout());
- } else {
- // FIXME: We should never have other type of children (they should be wrapped in an
- // anonymous table section) but our code is too crazy and this can happen in practice.
- // Until this is fixed, let's make sure we don't leave non laid out children in the tree.
- child->layoutIfNeeded();
- }
- }
// If any table section moved vertically, we will just repaint everything from that
// section down (it is quite unlikely that any of the following sections
// did not shift).
bool sectionMoved = false;
LayoutUnit movedSectionLogicalTop = 0;
+ {
+ LayoutState state(*this, locationOffset());
- // FIXME: Collapse caption margin.
- if (!m_captions.isEmpty()) {
- for (unsigned i = 0; i < m_captions.size(); i++) {
- if (m_captions[i]->style()->captionSide() == CAPBOTTOM)
- continue;
- layoutCaption(m_captions[i]);
- }
- if (logicalHeight() != oldTableLogicalTop) {
- sectionMoved = true;
- movedSectionLogicalTop = min(logicalHeight(), oldTableLogicalTop);
+ setLogicalHeight(0);
+
+ LayoutUnit oldLogicalWidth = logicalWidth();
+ updateLogicalWidth();
+
+ if (logicalWidth() != oldLogicalWidth) {
+ for (unsigned i = 0; i < m_captions.size(); i++)
+ layouter.setNeedsLayout(m_captions[i]);
}
- }
+ // FIXME: The optimisation below doesn't work since the internal table
+ // layout could have changed. We need to add a flag to the table
+ // layout that tells us if something has changed in the min max
+ // calculations to do it correctly.
+ // if ( oldWidth != width() || columns.size() + 1 != columnPos.size() )
+ m_tableLayout->layout();
+
+ LayoutUnit totalSectionLogicalHeight = 0;
+ LayoutUnit oldTableLogicalTop = 0;
+ for (unsigned i = 0; i < m_captions.size(); i++)
+ oldTableLogicalTop += m_captions[i]->logicalHeight() + m_captions[i]->marginBefore() + m_captions[i]->marginAfter();
- LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? LayoutUnit() : paddingBefore());
- LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? LayoutUnit() : paddingAfter());
+ bool collapsing = collapseBorders();
- setLogicalHeight(logicalHeight() + borderAndPaddingBefore);
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->isTableSection()) {
+ RenderTableSection* section = toRenderTableSection(child);
+ if (m_columnLogicalWidthChanged)
+ layouter.setChildNeedsLayout(section);
+ section->layoutIfNeeded();
+ totalSectionLogicalHeight += section->calcRowLogicalHeight();
+ if (collapsing)
+ section->recalcOuterBorder();
+ ASSERT(!section->needsLayout());
+ } else if (child->isRenderTableCol()) {
+ child->layoutIfNeeded();
+ ASSERT(!child->needsLayout());
+ } else {
+ // FIXME: We should never have other type of children (they should be wrapped in an
+ // anonymous table section) but our code is too crazy and this can happen in practice.
+ // Until this is fixed, let's make sure we don't leave non laid out children in the tree.
+ child->layoutIfNeeded();
+ }
+ }
+
+ // FIXME: Collapse caption margin.
+ if (!m_captions.isEmpty()) {
+ for (unsigned i = 0; i < m_captions.size(); i++) {
+ if (m_captions[i]->style()->captionSide() == CAPBOTTOM)
+ continue;
+ layoutCaption(m_captions[i]);
+ }
+ if (logicalHeight() != oldTableLogicalTop) {
+ sectionMoved = true;
+ movedSectionLogicalTop = min(logicalHeight(), oldTableLogicalTop);
+ }
+ }
- if (!isOutOfFlowPositioned())
- updateLogicalHeight();
+ LayoutUnit borderAndPaddingBefore = borderBefore() + (collapsing ? LayoutUnit() : paddingBefore());
+ LayoutUnit borderAndPaddingAfter = borderAfter() + (collapsing ? LayoutUnit() : paddingAfter());
- LayoutUnit computedLogicalHeight = 0;
+ setLogicalHeight(logicalHeight() + borderAndPaddingBefore);
- Length logicalHeightLength = style()->logicalHeight();
- if (logicalHeightLength.isIntrinsic() || (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive()))
- computedLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
+ if (!isOutOfFlowPositioned())
+ updateLogicalHeight();
- Length logicalMaxHeightLength = style()->logicalMaxHeight();
- if (logicalMaxHeightLength.isIntrinsic() || (logicalMaxHeightLength.isSpecified() && !logicalMaxHeightLength.isNegative())) {
- LayoutUnit computedMaxLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMaxHeightLength);
- computedLogicalHeight = min(computedLogicalHeight, computedMaxLogicalHeight);
- }
+ LayoutUnit computedLogicalHeight = 0;
- Length logicalMinHeightLength = style()->logicalMinHeight();
- if (logicalMinHeightLength.isIntrinsic() || (logicalMinHeightLength.isSpecified() && !logicalMinHeightLength.isNegative())) {
- LayoutUnit computedMinLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMinHeightLength);
- computedLogicalHeight = max(computedLogicalHeight, computedMinLogicalHeight);
- }
+ Length logicalHeightLength = style()->logicalHeight();
+ if (logicalHeightLength.isIntrinsic() || (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive()))
+ computedLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
- distributeExtraLogicalHeight(floorToInt(computedLogicalHeight - totalSectionLogicalHeight));
+ Length logicalMaxHeightLength = style()->logicalMaxHeight();
+ if (logicalMaxHeightLength.isIntrinsic() || (logicalMaxHeightLength.isSpecified() && !logicalMaxHeightLength.isNegative())) {
+ LayoutUnit computedMaxLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMaxHeightLength);
+ computedLogicalHeight = min(computedLogicalHeight, computedMaxLogicalHeight);
+ }
- for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
- section->layoutRows();
+ Length logicalMinHeightLength = style()->logicalMinHeight();
+ if (logicalMinHeightLength.isIntrinsic() || (logicalMinHeightLength.isSpecified() && !logicalMinHeightLength.isNegative())) {
+ LayoutUnit computedMinLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMinHeightLength);
+ computedLogicalHeight = max(computedLogicalHeight, computedMinLogicalHeight);
+ }
- if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !document().inQuirksMode()) {
- // Completely empty tables (with no sections or anything) should at least honor specified height
- // in strict mode.
- setLogicalHeight(logicalHeight() + computedLogicalHeight);
- }
+ distributeExtraLogicalHeight(floorToInt(computedLogicalHeight - totalSectionLogicalHeight));
- LayoutUnit sectionLogicalLeft = style()->isLeftToRightDirection() ? borderStart() : borderEnd();
- if (!collapsing)
- sectionLogicalLeft += style()->isLeftToRightDirection() ? paddingStart() : paddingEnd();
+ for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
+ section->layoutRows();
- // position the table sections
- RenderTableSection* section = topSection();
- while (section) {
- if (!sectionMoved && section->logicalTop() != logicalHeight()) {
- sectionMoved = true;
- movedSectionLogicalTop = min(logicalHeight(), section->logicalTop()) + (style()->isHorizontalWritingMode() ? section->visualOverflowRect().y() : section->visualOverflowRect().x());
+ if (!topSection() && computedLogicalHeight > totalSectionLogicalHeight && !document().inQuirksMode()) {
+ // Completely empty tables (with no sections or anything) should at least honor specified height
+ // in strict mode.
+ setLogicalHeight(logicalHeight() + computedLogicalHeight);
}
- section->setLogicalLocation(LayoutPoint(sectionLogicalLeft, logicalHeight()));
- setLogicalHeight(logicalHeight() + section->logicalHeight());
- section = sectionBelow(section);
- }
+ LayoutUnit sectionLogicalLeft = style()->isLeftToRightDirection() ? borderStart() : borderEnd();
+ if (!collapsing)
+ sectionLogicalLeft += style()->isLeftToRightDirection() ? paddingStart() : paddingEnd();
- setLogicalHeight(logicalHeight() + borderAndPaddingAfter);
+ // position the table sections
+ RenderTableSection* section = topSection();
+ while (section) {
+ if (!sectionMoved && section->logicalTop() != logicalHeight()) {
+ sectionMoved = true;
+ movedSectionLogicalTop = min(logicalHeight(), section->logicalTop()) + (style()->isHorizontalWritingMode() ? section->visualOverflowRect().y() : section->visualOverflowRect().x());
+ }
+ section->setLogicalLocation(LayoutPoint(sectionLogicalLeft, logicalHeight()));
- for (unsigned i = 0; i < m_captions.size(); i++) {
- if (m_captions[i]->style()->captionSide() != CAPBOTTOM)
- continue;
- layoutCaption(m_captions[i]);
- }
+ setLogicalHeight(logicalHeight() + section->logicalHeight());
+ section = sectionBelow(section);
+ }
+
+ setLogicalHeight(logicalHeight() + borderAndPaddingAfter);
+
+ for (unsigned i = 0; i < m_captions.size(); i++) {
+ if (m_captions[i]->style()->captionSide() != CAPBOTTOM)
+ continue;
+ layoutCaption(m_captions[i]);
+ }
- if (isOutOfFlowPositioned())
- updateLogicalHeight();
+ if (isOutOfFlowPositioned())
+ updateLogicalHeight();
- // table can be containing block of positioned elements.
- // FIXME: Only pass true if width or height changed.
- layoutPositionedObjects(true);
+ // table can be containing block of positioned elements.
+ // FIXME: Only pass true if width or height changed.
+ layoutPositionedObjects(true);
- updateLayerTransform();
+ updateLayerTransformAfterLayout();
- // Layout was changed, so probably borders too.
- invalidateCollapsedBorders();
+ // Layout was changed, so probably borders too.
+ invalidateCollapsedBorders();
- computeOverflow(clientLogicalBottom());
+ computeOverflow(clientLogicalBottom());
+ }
- statePusher.pop();
+ // FIXME: This value isn't the intrinsic content logical height, but we need
+ // to update the value as its used by flexbox layout. crbug.com/367324
+ updateIntrinsicContentLogicalHeight(contentLogicalHeight());
if (view()->layoutState()->pageLogicalHeight())
- setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(this, logicalTop()));
+ setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(*this, logicalTop()));
bool didFullRepaint = repainter.repaintAfterLayout();
// Repaint with our new bounds if they are different from our old bounds.
- if (!didFullRepaint && sectionMoved) {
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()
+ && !didFullRepaint && sectionMoved) {
if (style()->isHorizontalWritingMode())
- repaintRectangle(LayoutRect(visualOverflowRect().x(), movedSectionLogicalTop, visualOverflowRect().width(), visualOverflowRect().maxY() - movedSectionLogicalTop));
+ invalidatePaintRectangle(LayoutRect(visualOverflowRect().x(), movedSectionLogicalTop, visualOverflowRect().width(), visualOverflowRect().maxY() - movedSectionLogicalTop));
else
- repaintRectangle(LayoutRect(movedSectionLogicalTop, visualOverflowRect().y(), visualOverflowRect().maxX() - movedSectionLogicalTop, visualOverflowRect().height()));
+ invalidatePaintRectangle(LayoutRect(movedSectionLogicalTop, visualOverflowRect().y(), visualOverflowRect().maxX() - movedSectionLogicalTop, visualOverflowRect().height()));
}
m_columnLogicalWidthChanged = false;
@@ -591,14 +592,10 @@ void RenderTable::recalcCollapsedBorders()
for (RenderObject* section = firstChild(); section; section = section->nextSibling()) {
if (!section->isTableSection())
continue;
- for (RenderObject* row = section->firstChild(); row; row = row->nextSibling()) {
- if (!row->isTableRow())
- continue;
- for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
- if (!cell->isTableCell())
- continue;
- ASSERT(toRenderTableCell(cell)->table() == this);
- toRenderTableCell(cell)->collectBorderValues(m_collapsedBorders);
+ for (RenderTableRow* row = toRenderTableSection(section)->firstRow(); row; row = row->nextRow()) {
+ for (RenderTableCell* cell = row->firstCell(); cell; cell = cell->nextCell()) {
+ ASSERT(cell->table() == this);
+ cell->collectBorderValues(m_collapsedBorders);
}
}
}
@@ -640,10 +637,9 @@ void RenderTable::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
PaintPhase paintPhase = paintInfo.phase;
- if (!isRoot()) {
+ if (!isDocumentElement()) {
LayoutRect overflowBox = visualOverflowRect();
flipForWritingMode(overflowBox);
- overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
overflowBox.moveBy(adjustedPaintOffset);
if (!overflowBox.intersects(paintInfo.rect))
return;
@@ -773,13 +769,13 @@ void RenderTable::computePreferredLogicalWidths()
m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, m_captions[i]->minPreferredLogicalWidth());
RenderStyle* styleToUse = style();
- // FIXME: This should probably be checking for isSpecified since you should be able to use percentage, calc or viewport relative values for min-width.
+ // FIXME: This should probably be checking for isSpecified since you should be able to use percentage or calc values for min-width.
if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
m_maxPreferredLogicalWidth = std::max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
m_minPreferredLogicalWidth = std::max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
}
- // FIXME: This should probably be checking for isSpecified since you should be able to use percentage, calc or viewport relative values for maxWidth.
+ // FIXME: This should probably be checking for isSpecified since you should be able to use percentage or calc values for maxWidth.
if (styleToUse->logicalMaxWidth().isFixed()) {
// We don't constrain m_minPreferredLogicalWidth as the table should be at least the size of its min-content, regardless of 'max-width'.
m_maxPreferredLogicalWidth = std::min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
@@ -827,6 +823,10 @@ void RenderTable::appendColumn(unsigned span)
unsigned newColumnIndex = m_columns.size();
m_columns.append(ColumnStruct(span));
+ // Unless the table has cell(s) with colspan that exceed the number of columns afforded
+ // by the other rows in the table we can use the fast path when mapping columns to effective columns.
+ m_hasCellColspanThatDeterminesTableWidth = m_hasCellColspanThatDeterminesTableWidth || span > 1;
+
// Propagate the change in our columns representation to the sections that don't need
// cell recalc. If they do, they will be synced up directly with m_columns later.
for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
@@ -901,6 +901,7 @@ void RenderTable::recalcSections() const
m_foot = 0;
m_firstBody = 0;
m_hasColElements = false;
+ m_hasCellColspanThatDeterminesTableWidth = hasCellColspanThatDeterminesTableWidth();
// We need to get valid pointers to caption, head, foot and first body again
RenderObject* nextSibling;
@@ -1331,9 +1332,12 @@ void RenderTable::updateFirstLetter()
int RenderTable::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
ASSERT(linePositionMode == PositionOnContainingLine);
- LayoutUnit baseline = firstLineBoxBaseline();
- if (baseline != -1)
+ int baseline = firstLineBoxBaseline();
+ if (baseline != -1) {
+ if (isInline())
+ return beforeMarginInLineDirection(direction) + baseline;
return baseline;
+ }
return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
}
@@ -1367,9 +1371,9 @@ int RenderTable::firstLineBoxBaseline() const
return -1;
}
-LayoutRect RenderTable::overflowClipRect(const LayoutPoint& location, RenderRegion* region, OverlayScrollbarSizeRelevancy relevancy)
+LayoutRect RenderTable::overflowClipRect(const LayoutPoint& location, OverlayScrollbarSizeRelevancy relevancy)
{
- LayoutRect rect = RenderBlock::overflowClipRect(location, region, relevancy);
+ LayoutRect rect = RenderBlock::overflowClipRect(location, relevancy);
// If we have a caption, expand the clip to include the caption.
// FIXME: Technically this is wrong, but it's virtually impossible to fix this
@@ -1395,7 +1399,7 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
LayoutPoint adjustedLocation = accumulatedOffset + location();
// Check kids first.
- if (!hasOverflowClip() || locationInContainer.intersects(overflowClipRect(adjustedLocation, locationInContainer.region()))) {
+ if (!hasOverflowClip() || locationInContainer.intersects(overflowClipRect(adjustedLocation))) {
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child->isTableCaption())) {
LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(child), adjustedLocation);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTable.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTable.h
index ba7ab67b752..811c28668db 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTable.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTable.h
@@ -25,7 +25,7 @@
#ifndef RenderTable_h
#define RenderTable_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/rendering/RenderBlock.h"
#include "core/rendering/style/CollapsedBorderValue.h"
#include "wtf/Vector.h"
@@ -52,33 +52,33 @@ public:
bool collapseBorders() const { return style()->borderCollapse(); }
- int borderStart() const { return m_borderStart; }
- int borderEnd() const { return m_borderEnd; }
- int borderBefore() const;
- int borderAfter() const;
+ virtual int borderStart() const OVERRIDE { return m_borderStart; }
+ virtual int borderEnd() const OVERRIDE { return m_borderEnd; }
+ virtual int borderBefore() const OVERRIDE;
+ virtual int borderAfter() const OVERRIDE;
- int borderLeft() const
+ virtual int borderLeft() const OVERRIDE
{
if (style()->isHorizontalWritingMode())
return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
}
- int borderRight() const
+ virtual int borderRight() const OVERRIDE
{
if (style()->isHorizontalWritingMode())
return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
}
- int borderTop() const
+ virtual int borderTop() const OVERRIDE
{
if (style()->isHorizontalWritingMode())
return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
}
- int borderBottom() const
+ virtual int borderBottom() const OVERRIDE
{
if (style()->isHorizontalWritingMode())
return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
@@ -124,7 +124,7 @@ public:
int calcBorderEnd() const;
void recalcBordersInRowDirection();
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
struct ColumnStruct {
explicit ColumnStruct(unsigned initialSpan = 1)
@@ -171,6 +171,9 @@ public:
unsigned colToEffCol(unsigned column) const
{
+ if (!m_hasCellColspanThatDeterminesTableWidth)
+ return column;
+
unsigned effColumn = 0;
unsigned numColumns = numEffCols();
for (unsigned c = 0; effColumn < numColumns && c + m_columns[effColumn].span - 1 < column; ++effColumn)
@@ -180,6 +183,9 @@ public:
unsigned effColToCol(unsigned effCol) const
{
+ if (!m_hasCellColspanThatDeterminesTableWidth)
+ return effCol;
+
unsigned c = 0;
for (unsigned i = 0; i < effCol; i++)
c += m_columns[i].span;
@@ -221,7 +227,7 @@ public:
if (documentBeingDestroyed())
return;
m_needsSectionRecalc = true;
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
}
RenderTableSection* sectionAbove(const RenderTableSection*, SkipEmptySectionsValue = DoNotSkipEmptySections) const;
@@ -263,22 +269,21 @@ public:
void removeColumn(const RenderTableCol*);
protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual void simplifiedNormalFlowLayout();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+ virtual void simplifiedNormalFlowLayout() OVERRIDE;
private:
- virtual const char* renderName() const { return "RenderTable"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderTable"; }
- virtual bool isTable() const { return true; }
+ virtual bool isTable() const OVERRIDE { return true; }
- virtual bool avoidsFloats() const { return true; }
+ virtual bool avoidsFloats() const OVERRIDE { return true; }
- virtual void paint(PaintInfo&, const LayoutPoint&);
- virtual void paintObject(PaintInfo&, const LayoutPoint&);
- virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
- virtual void paintMask(PaintInfo&, const LayoutPoint&);
- virtual void layout();
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void paintMask(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void layout() OVERRIDE;
virtual void computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth) const OVERRIDE;
virtual void computePreferredLogicalWidths() OVERRIDE;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
@@ -292,17 +297,17 @@ private:
void updateColumnCache() const;
void invalidateCachedColumns();
- virtual RenderBlock* firstLineBlock() const;
- virtual void updateFirstLetter();
+ virtual RenderBlock* firstLineBlock() const OVERRIDE;
+ virtual void updateFirstLetter() OVERRIDE;
virtual void updateLogicalWidth() OVERRIDE;
LayoutUnit convertStyleLogicalWidthToComputedWidth(const Length& styleLogicalWidth, LayoutUnit availableWidth);
LayoutUnit convertStyleLogicalHeightToComputedHeight(const Length& styleLogicalHeight);
- virtual LayoutRect overflowClipRect(const LayoutPoint& location, RenderRegion*, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
+ virtual LayoutRect overflowClipRect(const LayoutPoint& location, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize) OVERRIDE;
- virtual void addOverflowFromChildren();
+ virtual void addOverflowFromChildren() OVERRIDE;
void subtractCaptionRect(LayoutRect&) const;
@@ -332,6 +337,15 @@ private:
bool m_columnLogicalWidthChanged : 1;
mutable bool m_columnRenderersValid: 1;
+ mutable bool m_hasCellColspanThatDeterminesTableWidth : 1;
+ bool hasCellColspanThatDeterminesTableWidth() const
+ {
+ for (unsigned c = 0; c < numEffCols(); c++) {
+ if (m_columns[c].span > 1)
+ return true;
+ }
+ return false;
+ }
short m_hSpacing;
short m_vSpacing;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.cpp
index af677b71de9..24dc5eccb48 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.cpp
@@ -48,7 +48,7 @@ void RenderTableCaption::insertedIntoTree()
void RenderTableCaption::willBeRemovedFromTree()
{
- RenderBlock::willBeRemovedFromTree();
+ RenderBlockFlow::willBeRemovedFromTree();
table()->removeCaption(this);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.h
index 35755a9d03b..d24acf84184 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCaption.h
@@ -35,8 +35,6 @@ public:
private:
virtual bool isTableCaption() const OVERRIDE { return true; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
virtual void insertedIntoTree() OVERRIDE;
virtual void willBeRemovedFromTree() OVERRIDE;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.cpp
index 9737da43de8..5cf8270ad12 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.cpp
@@ -25,10 +25,9 @@
#include "config.h"
#include "core/rendering/RenderTableCell.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/StylePropertySet.h"
#include "core/html/HTMLTableCellElement.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderTableCol.h"
#include "core/rendering/RenderView.h"
@@ -66,7 +65,7 @@ RenderTableCell::RenderTableCell(Element* element)
void RenderTableCell::willBeRemovedFromTree()
{
- RenderBlock::willBeRemovedFromTree();
+ RenderBlockFlow::willBeRemovedFromTree();
section()->setNeedsCellRecalc();
section()->removeCachedCollapsedBorders(this);
@@ -75,16 +74,16 @@ void RenderTableCell::willBeRemovedFromTree()
unsigned RenderTableCell::parseColSpanFromDOM() const
{
ASSERT(node());
- if (node()->hasTagName(tdTag) || node()->hasTagName(thTag))
- return min<unsigned>(toHTMLTableCellElement(node())->colSpan(), maxColumnIndex);
+ if (isHTMLTableCellElement(*node()))
+ return min<unsigned>(toHTMLTableCellElement(*node()).colSpan(), maxColumnIndex);
return 1;
}
unsigned RenderTableCell::parseRowSpanFromDOM() const
{
ASSERT(node());
- if (node()->hasTagName(tdTag) || node()->hasTagName(thTag))
- return min<unsigned>(toHTMLTableCellElement(node())->rowSpan(), maxRowIndex);
+ if (isHTMLTableCellElement(*node()))
+ return min<unsigned>(toHTMLTableCellElement(*node()).rowSpan(), maxRowIndex);
return 1;
}
@@ -99,13 +98,13 @@ void RenderTableCell::updateColAndRowSpanFlags()
void RenderTableCell::colSpanOrRowSpanChanged()
{
ASSERT(node());
- ASSERT(node()->hasTagName(tdTag) || node()->hasTagName(thTag));
+ ASSERT(isHTMLTableCellElement(*node()));
updateColAndRowSpanFlags();
// FIXME: I suspect that we could return early here if !m_hasColSpan && !m_hasRowSpan.
- setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
if (parent() && section())
section()->setNeedsCellRecalc();
}
@@ -149,7 +148,7 @@ void RenderTableCell::computePreferredLogicalWidths()
// grids. We must refresh those grids before the child cells try to use them.
table()->recalcSectionsIfNeeded();
- RenderBlock::computePreferredLogicalWidths();
+ RenderBlockFlow::computePreferredLogicalWidths();
if (node() && style()->autoWrap()) {
// See if nowrap was set.
Length w = styleOrColLogicalWidth();
@@ -226,8 +225,8 @@ void RenderTableCell::setCellLogicalWidth(int tableLayoutLogicalWidth, SubtreeLa
layouter.setNeedsLayout(this);
- if (!table()->selfNeedsLayout() && checkForRepaintDuringLayout())
- repaint();
+ if (!table()->selfNeedsLayout() && checkForPaintInvalidationDuringLayout())
+ paintInvalidationForWholeRenderer();
setLogicalWidth(tableLayoutLogicalWidth);
setCellWidthChanged(true);
@@ -237,8 +236,6 @@ void RenderTableCell::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
-
updateFirstLetter();
int oldCellBaseline = cellBaselinePosition();
@@ -251,11 +248,15 @@ void RenderTableCell::layout()
if (isBaselineAligned() && section()->rowBaseline(rowIndex()) && cellBaselinePosition() > section()->rowBaseline(rowIndex())) {
int newIntrinsicPaddingBefore = max<LayoutUnit>(0, intrinsicPaddingBefore() - max<LayoutUnit>(0, cellBaselinePosition() - oldCellBaseline));
setIntrinsicPaddingBefore(newIntrinsicPaddingBefore);
- SubtreeLayoutScope layouter(this);
+ SubtreeLayoutScope layouter(*this);
layouter.setNeedsLayout(this);
layoutBlock(cellWidthChanged());
}
+ // FIXME: This value isn't the intrinsic content logical height, but we need
+ // to update the value as its used by flexbox layout. crbug.com/367324
+ updateIntrinsicContentLogicalHeight(contentLogicalHeight());
+
setCellWidthChanged(false);
}
@@ -307,25 +308,25 @@ void RenderTableCell::setOverrideLogicalContentHeightFromRowHeight(LayoutUnit ro
setOverrideLogicalContentHeight(max<LayoutUnit>(0, rowHeight - borderAndPaddingLogicalHeight()));
}
-LayoutSize RenderTableCell::offsetFromContainer(RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
+LayoutSize RenderTableCell::offsetFromContainer(const RenderObject* o, const LayoutPoint& point, bool* offsetDependsOnPoint) const
{
ASSERT(o == container());
- LayoutSize offset = RenderBlock::offsetFromContainer(o, point, offsetDependsOnPoint);
+ LayoutSize offset = RenderBlockFlow::offsetFromContainer(o, point, offsetDependsOnPoint);
if (parent())
offset -= parentBox()->locationOffset();
return offset;
}
-LayoutRect RenderTableCell::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+LayoutRect RenderTableCell::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
// If the table grid is dirty, we cannot get reliable information about adjoining cells,
// so we ignore outside borders. This should not be a problem because it means that
// the table is going to recalculate the grid, relayout and repaint its current rect, which
// includes any outside borders of this cell.
if (!table()->collapseBorders() || table()->needsSectionRecalc())
- return RenderBlock::clippedOverflowRectForRepaint(repaintContainer);
+ return RenderBlockFlow::clippedOverflowRectForPaintInvalidation(paintInvalidationContainer);
bool rtl = !styleForCellFlow()->isLeftToRightDirection();
int outlineSize = style()->outlineSize();
@@ -360,24 +361,26 @@ LayoutRect RenderTableCell::clippedOverflowRectForRepaint(const RenderLayerModel
LayoutPoint location(max<LayoutUnit>(left, -visualOverflowRect().x()), max<LayoutUnit>(top, -visualOverflowRect().y()));
LayoutRect r(-location.x(), -location.y(), location.x() + max(width() + right, visualOverflowRect().maxX()), location.y() + max(height() + bottom, visualOverflowRect().maxY()));
- if (RenderView* v = view()) {
- // FIXME: layoutDelta needs to be applied in parts before/after transforms and
- // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
- r.move(v->layoutDelta());
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ if (RenderView* v = view()) {
+ // FIXME: layoutDelta needs to be applied in parts before/after transforms and
+ // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308
+ r.move(v->layoutDelta());
+ }
}
- computeRectForRepaint(repaintContainer, r);
+ mapRectToPaintInvalidationBacking(paintInvalidationContainer, r);
return r;
}
-void RenderTableCell::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& r, bool fixed) const
+void RenderTableCell::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& r, bool fixed) const
{
- if (repaintContainer == this)
+ if (paintInvalidationContainer == this)
return;
r.setY(r.y());
RenderView* v = view();
- if ((!v || !v->layoutStateEnabled() || repaintContainer) && parent())
+ if ((!v || !v->canMapUsingLayoutStateForContainer(paintInvalidationContainer)) && parent())
r.moveBy(-parentBox()->location()); // Rows are in the same coordinate space, so don't add their offset in.
- RenderBlock::computeRectForRepaint(repaintContainer, r, fixed);
+ RenderBlockFlow::mapRectToPaintInvalidationBacking(paintInvalidationContainer, r, fixed);
}
LayoutUnit RenderTableCell::cellBaselinePosition() const
@@ -396,7 +399,7 @@ void RenderTableCell::styleDidChange(StyleDifference diff, const RenderStyle* ol
ASSERT(style()->display() == TABLE_CELL);
ASSERT(!row() || row()->rowIndexWasSet());
- RenderBlock::styleDidChange(diff, oldStyle);
+ RenderBlockFlow::styleDidChange(diff, oldStyle);
setHasBoxDecorations(true);
if (parent() && section() && oldStyle && style()->height() != oldStyle->height())
@@ -738,7 +741,7 @@ CollapsedBorderValue RenderTableCell::computeCollapsedBeforeBorder(IncludeBorder
if (prevCell->section() == section())
prevRow = parent()->previousSibling();
else
- prevRow = prevCell->section()->lastChild();
+ prevRow = prevCell->section()->lastRow();
if (prevRow) {
result = chooseBorder(CollapsedBorderValue(prevRow->style()->borderAfter(), includeColor ? prevRow->resolveColor(afterColorProperty) : Color(), BROW), result);
@@ -894,44 +897,44 @@ inline CollapsedBorderValue RenderTableCell::cachedCollapsedBottomBorder(const R
int RenderTableCell::borderLeft() const
{
- return table()->collapseBorders() ? borderHalfLeft(false) : RenderBlock::borderLeft();
+ return table()->collapseBorders() ? borderHalfLeft(false) : RenderBlockFlow::borderLeft();
}
int RenderTableCell::borderRight() const
{
- return table()->collapseBorders() ? borderHalfRight(false) : RenderBlock::borderRight();
+ return table()->collapseBorders() ? borderHalfRight(false) : RenderBlockFlow::borderRight();
}
int RenderTableCell::borderTop() const
{
- return table()->collapseBorders() ? borderHalfTop(false) : RenderBlock::borderTop();
+ return table()->collapseBorders() ? borderHalfTop(false) : RenderBlockFlow::borderTop();
}
int RenderTableCell::borderBottom() const
{
- return table()->collapseBorders() ? borderHalfBottom(false) : RenderBlock::borderBottom();
+ return table()->collapseBorders() ? borderHalfBottom(false) : RenderBlockFlow::borderBottom();
}
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=46191, make the collapsed border drawing
// work with different block flow values instead of being hard-coded to top-to-bottom.
int RenderTableCell::borderStart() const
{
- return table()->collapseBorders() ? borderHalfStart(false) : RenderBlock::borderStart();
+ return table()->collapseBorders() ? borderHalfStart(false) : RenderBlockFlow::borderStart();
}
int RenderTableCell::borderEnd() const
{
- return table()->collapseBorders() ? borderHalfEnd(false) : RenderBlock::borderEnd();
+ return table()->collapseBorders() ? borderHalfEnd(false) : RenderBlockFlow::borderEnd();
}
int RenderTableCell::borderBefore() const
{
- return table()->collapseBorders() ? borderHalfBefore(false) : RenderBlock::borderBefore();
+ return table()->collapseBorders() ? borderHalfBefore(false) : RenderBlockFlow::borderBefore();
}
int RenderTableCell::borderAfter() const
{
- return table()->collapseBorders() ? borderHalfAfter(false) : RenderBlock::borderAfter();
+ return table()->collapseBorders() ? borderHalfAfter(false) : RenderBlockFlow::borderAfter();
}
int RenderTableCell::borderHalfLeft(bool outer) const
@@ -1001,7 +1004,7 @@ int RenderTableCell::borderHalfAfter(bool outer) const
void RenderTableCell::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
ASSERT(paintInfo.phase != PaintPhaseCollapsedTableBorders);
- RenderBlock::paint(paintInfo, paintOffset);
+ RenderBlockFlow::paint(paintInfo, paintOffset);
}
static EBorderStyle collapsedBorderStyle(EBorderStyle style)
@@ -1105,14 +1108,11 @@ void RenderTableCell::paintCollapsedBorders(PaintInfo& paintInfo, const LayoutPo
if (!paintInfo.shouldPaintWithinRoot(this) || style()->visibility() != VISIBLE)
return;
- LayoutRect localRepaintRect = paintInfo.rect;
- localRepaintRect.inflate(maximalOutlineSize(paintInfo.phase));
-
LayoutRect paintRect = LayoutRect(paintOffset + location(), pixelSnappedSize());
- if (paintRect.y() - table()->outerBorderTop() >= localRepaintRect.maxY())
+ if (paintRect.y() - table()->outerBorderTop() >= paintInfo.rect.maxY())
return;
- if (paintRect.maxY() + table()->outerBorderBottom() <= localRepaintRect.y())
+ if (paintRect.maxY() + table()->outerBorderBottom() <= paintInfo.rect.y())
return;
GraphicsContext* graphicsContext = paintInfo.context;
@@ -1159,7 +1159,7 @@ void RenderTableCell::paintCollapsedBorders(PaintInfo& paintInfo, const LayoutPo
for (CollapsedBorder* border = borders.nextBorder(); border; border = borders.nextBorder()) {
if (border->borderValue.isSameIgnoringColor(*table()->currentBorderValue())) {
drawLineForBoxSide(graphicsContext, border->x1, border->y1, border->x2, border->y2, border->side,
- resolveColor(border->borderValue.color()), border->style, 0, 0, antialias);
+ border->borderValue.color().resolve(style()->visitedDependentColor(CSSPropertyColor)), border->style, 0, 0, antialias);
}
}
}
@@ -1186,7 +1186,7 @@ void RenderTableCell::paintBackgroundsBehindCell(PaintInfo& paintInfo, const Lay
Color c = backgroundObject->resolveColor(CSSPropertyBackgroundColor);
const FillLayer* bgLayer = backgroundObject->style()->backgroundLayers();
- if (bgLayer->hasImage() || c.isValid()) {
+ if (bgLayer->hasImage() || c.alpha()) {
// We have to clip here because the background would paint
// on top of the borders otherwise. This only matters for cells and rows.
bool shouldClip = backgroundObject->hasLayer() && (backgroundObject == this || backgroundObject == parent()) && tableElt->collapseBorders();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.h
index 9eeb48e4f01..dcffc575763 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCell.h
@@ -4,7 +4,7 @@
* (C) 1998 Waldo Bastian (bastian@kde.org)
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -28,6 +28,7 @@
#include "core/rendering/RenderBlockFlow.h"
#include "core/rendering/RenderTableRow.h"
#include "core/rendering/RenderTableSection.h"
+#include "platform/LengthFunctions.h"
namespace WebCore {
@@ -76,6 +77,9 @@ public:
RenderTableSection* section() const { return toRenderTableSection(parent()->parent()); }
RenderTable* table() const { return toRenderTable(parent()->parent()->parent()); }
+ RenderTableCell* previousCell() const;
+ RenderTableCell* nextCell() const;
+
unsigned rowIndex() const
{
// This function shouldn't be called on a detached cell.
@@ -97,7 +101,7 @@ public:
{
// FIXME: This function does too much work, and is very hot during table layout!
int adjustedLogicalHeight = pixelSnappedLogicalHeight() - (intrinsicPaddingBefore() + intrinsicPaddingAfter());
- int styleLogicalHeight = valueForLength(style()->logicalHeight(), 0, view());
+ int styleLogicalHeight = valueForLength(style()->logicalHeight(), 0);
// In strict mode, box-sizing: content-box do the right thing and actually add in the border and padding.
// Call computedCSSPadding* directly to avoid including implicitPadding.
if (!document().inQuirksMode() && style()->boxSizing() != BORDER_BOX)
@@ -108,23 +112,21 @@ public:
void setCellLogicalWidth(int constrainedLogicalWidth, SubtreeLayoutScope&);
- virtual int borderLeft() const;
- virtual int borderRight() const;
- virtual int borderTop() const;
- virtual int borderBottom() const;
- virtual int borderStart() const;
- virtual int borderEnd() const;
- virtual int borderBefore() const;
- virtual int borderAfter() const;
+ virtual int borderLeft() const OVERRIDE;
+ virtual int borderRight() const OVERRIDE;
+ virtual int borderTop() const OVERRIDE;
+ virtual int borderBottom() const OVERRIDE;
+ virtual int borderStart() const OVERRIDE;
+ virtual int borderEnd() const OVERRIDE;
+ virtual int borderBefore() const OVERRIDE;
+ virtual int borderAfter() const OVERRIDE;
void collectBorderValues(RenderTable::CollapsedBorderValues&) const;
static void sortBorderValues(RenderTable::CollapsedBorderValues&);
- virtual void layout();
-
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual void layout() OVERRIDE;
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
void paintCollapsedBorders(PaintInfo&, const LayoutPoint&);
void paintBackgroundsBehindCell(PaintInfo&, const LayoutPoint&, RenderObject* backgroundObject);
@@ -155,7 +157,7 @@ public:
void setOverrideLogicalContentHeightFromRowHeight(LayoutUnit);
- virtual void scrollbarsChanged(bool horizontalScrollbarChanged, bool verticalScrollbarChanged);
+ virtual void scrollbarsChanged(bool horizontalScrollbarChanged, bool verticalScrollbarChanged) OVERRIDE;
bool cellWidthChanged() const { return m_cellWidthChanged; }
void setCellWidthChanged(bool b = true) { m_cellWidthChanged = b; }
@@ -216,28 +218,28 @@ public:
}
#endif
protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
- virtual void computePreferredLogicalWidths();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+ virtual void computePreferredLogicalWidths() OVERRIDE;
virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const OVERRIDE;
private:
- virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableCell (anonymous)" : "RenderTableCell"; }
+ virtual const char* renderName() const OVERRIDE { return (isAnonymous() || isPseudoElement()) ? "RenderTableCell (anonymous)" : "RenderTableCell"; }
- virtual bool isTableCell() const { return true; }
+ virtual bool isTableCell() const OVERRIDE { return true; }
virtual void willBeRemovedFromTree() OVERRIDE;
virtual void updateLogicalWidth() OVERRIDE;
- virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
- virtual void paintMask(PaintInfo&, const LayoutPoint&);
+ virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void paintMask(PaintInfo&, const LayoutPoint&) OVERRIDE;
virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const OVERRIDE;
- virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
+ virtual LayoutSize offsetFromContainer(const RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const OVERRIDE;
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE;
+ virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
int borderHalfLeft(bool outer) const;
int borderHalfRight(bool outer) const;
@@ -278,6 +280,9 @@ private:
unsigned parseRowSpanFromDOM() const;
unsigned parseColSpanFromDOM() const;
+ void nextSibling() const WTF_DELETED_FUNCTION;
+ void previousSibling() const WTF_DELETED_FUNCTION;
+
// Note MSVC will only pack members if they have identical types, hence we use unsigned instead of bool here.
unsigned m_column : 29;
unsigned m_cellWidthChanged : 1;
@@ -289,6 +294,28 @@ private:
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderTableCell, isTableCell());
+inline RenderTableCell* RenderTableCell::previousCell() const
+{
+ return toRenderTableCell(RenderObject::previousSibling());
+}
+
+inline RenderTableCell* RenderTableCell::nextCell() const
+{
+ return toRenderTableCell(RenderObject::nextSibling());
+}
+
+inline RenderTableCell* RenderTableRow::firstCell() const
+{
+ ASSERT(children() == virtualChildren());
+ return toRenderTableCell(children()->firstChild());
+}
+
+inline RenderTableCell* RenderTableRow::lastCell() const
+{
+ ASSERT(children() == virtualChildren());
+ return toRenderTableCell(children()->lastChild());
+}
+
} // namespace WebCore
#endif // RenderTableCell_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.cpp
index 26c5935f97f..b27a30d75aa 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/rendering/RenderTableCol.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/html/HTMLTableColElement.h"
#include "core/rendering/RenderTable.h"
#include "core/rendering/RenderTableCell.h"
@@ -60,13 +60,13 @@ void RenderTableCol::updateFromElement()
{
unsigned oldSpan = m_span;
Node* n = node();
- if (n && (n->hasTagName(colTag) || n->hasTagName(colgroupTag))) {
- HTMLTableColElement* tc = toHTMLTableColElement(n);
- m_span = tc->span();
+ if (isHTMLTableColElement(n)) {
+ HTMLTableColElement& tc = toHTMLTableColElement(*n);
+ m_span = tc.span();
} else
m_span = !(style() && style()->display() == TABLE_COLUMN_GROUP);
if (m_span != oldSpan && style() && parent())
- setNeedsLayoutAndPrefWidthsRecalc();
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
}
void RenderTableCol::insertedIntoTree()
@@ -94,23 +94,23 @@ bool RenderTableCol::canHaveChildren() const
return isTableColumnGroup();
}
-LayoutRect RenderTableCol::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+LayoutRect RenderTableCol::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
// For now, just repaint the whole table.
// FIXME: Find a better way to do this, e.g., need to repaint all the cells that we
// might have propagated a background color or borders into.
- // FIXME: check for repaintContainer each time here?
+ // FIXME: check for paintInvalidationContainer each time here?
RenderTable* parentTable = table();
if (!parentTable)
return LayoutRect();
- return parentTable->clippedOverflowRectForRepaint(repaintContainer);
+ return parentTable->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer);
}
void RenderTableCol::imageChanged(WrappedImagePtr, const IntRect*)
{
// FIXME: Repaint only the rect the image paints in.
- repaint();
+ paintInvalidationForWholeRenderer();
}
void RenderTableCol::clearPreferredLogicalWidthsDirtyBits()
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.h
index a28f36085bb..acb7d01e89c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableCol.h
@@ -40,6 +40,10 @@ public:
RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
+ // If you have a RenderTableCol, use firstChild or lastChild instead.
+ void slowFirstChild() const WTF_DELETED_FUNCTION;
+ void slowLastChild() const WTF_DELETED_FUNCTION;
+
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
@@ -77,25 +81,25 @@ public:
const BorderValue& borderAdjoiningCellAfter(const RenderTableCell*) const;
private:
- virtual RenderObjectChildList* virtualChildren() { return children(); }
- virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ virtual RenderObjectChildList* virtualChildren() OVERRIDE { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const OVERRIDE { return children(); }
- virtual const char* renderName() const { return "RenderTableCol"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderTableCol"; }
virtual bool isRenderTableCol() const OVERRIDE { return true; }
- virtual void updateFromElement();
+ virtual void updateFromElement() OVERRIDE;
virtual void computePreferredLogicalWidths() OVERRIDE { ASSERT_NOT_REACHED(); }
virtual void insertedIntoTree() OVERRIDE;
virtual void willBeRemovedFromTree() OVERRIDE;
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
- virtual bool canHaveChildren() const;
- virtual bool requiresLayer() const { return false; }
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
+ virtual bool canHaveChildren() const OVERRIDE;
+ virtual LayerType layerTypeRequired() const OVERRIDE { return NoLayer; }
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE;
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
RenderTable* table() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.cpp
index 528ae08d38c..f1f7ef78242 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.cpp
@@ -1,10 +1,10 @@
-/**
+/*
* Copyright (C) 1997 Martin Jones (mjones@kde.org)
* (C) 1997 Torben Weis (weis@kde.org)
* (C) 1998 Waldo Bastian (bastian@kde.org)
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,12 +25,11 @@
#include "config.h"
#include "core/rendering/RenderTableRow.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
#include "core/fetch/ImageResource.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderTableCell.h"
#include "core/rendering/RenderView.h"
@@ -80,7 +79,7 @@ void RenderTableRow::styleDidChange(StyleDifference diff, const RenderStyle* old
if (table && !table->selfNeedsLayout() && !table->normalChildNeedsLayout() && oldStyle && oldStyle->border() != style()->border())
table->invalidateCollapsedBorders();
- if (table && oldStyle && diff == StyleDifferenceLayout && needsLayout() && table->collapseBorders() && borderWidthChanged(oldStyle, style())) {
+ if (table && oldStyle && diff.needsFullLayout() && needsLayout() && table->collapseBorders() && borderWidthChanged(oldStyle, style())) {
// If the border width changes on a row, we need to make sure the cells in the row know to lay out again.
// This only happens when borders are collapsed, since they end up affecting the border sides of the cell
// itself.
@@ -112,11 +111,12 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
if (!child->isTableCell()) {
RenderObject* last = beforeChild;
if (!last)
- last = lastChild();
+ last = lastCell();
if (last && last->isAnonymous() && last->isTableCell() && !last->isBeforeOrAfterContent()) {
- if (beforeChild == last)
- beforeChild = last->firstChild();
- last->addChild(child, beforeChild);
+ RenderTableCell* lastCell = toRenderTableCell(last);
+ if (beforeChild == lastCell)
+ beforeChild = lastCell->firstChild();
+ lastCell->addChild(child, beforeChild);
return;
}
@@ -152,7 +152,7 @@ void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
ASSERT(!beforeChild || beforeChild->isTableCell());
RenderBox::addChild(cell, beforeChild);
- if (beforeChild || nextSibling())
+ if (beforeChild || nextRow())
section()->setNeedsCellRecalc();
}
@@ -160,74 +160,55 @@ void RenderTableRow::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
-
// Table rows do not add translation.
- LayoutStateMaintainer statePusher(view(), this, LayoutSize(), style()->isFlippedBlocksWritingMode());
-
- bool paginated = view()->layoutState()->isPaginated();
-
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (child->isTableCell()) {
- SubtreeLayoutScope layouter(child);
- RenderTableCell* cell = toRenderTableCell(child);
- if (!cell->needsLayout() && paginated && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell, cell->logicalTop()) != cell->pageLogicalOffset())
- layouter.setChildNeedsLayout(cell);
-
- if (child->needsLayout()) {
- cell->computeAndSetBlockDirectionMargins(table());
- cell->layout();
- }
+ LayoutState state(*this, LayoutSize());
+
+ for (RenderTableCell* cell = firstCell(); cell; cell = cell->nextCell()) {
+ SubtreeLayoutScope layouter(*cell);
+ if (!cell->needsLayout())
+ cell->markForPaginationRelayoutIfNeeded(layouter);
+ if (cell->needsLayout()) {
+ cell->computeAndSetBlockDirectionMargins(table());
+ cell->layout();
}
}
- // We only ever need to repaint if our cells didn't, which menas that they didn't need
+ m_overflow.clear();
+ addVisualEffectOverflow();
+
+ // We only ever need to issue paint invalidations if our cells didn't, which means that they didn't need
// layout, so we know that our bounds didn't change. This code is just making up for
- // the fact that we did not repaint in setStyle() because we had a layout hint.
- // We cannot call repaint() because our clippedOverflowRectForRepaint() is taken from the
- // parent table, and being mid-layout, that is invalid. Instead, we repaint our cells.
- if (selfNeedsLayout() && checkForRepaintDuringLayout()) {
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (child->isTableCell())
- child->repaint();
+ // the fact that we did not invalidate paints in setStyle() because we had a layout hint.
+ // We cannot call repaint() because our clippedOverflowRectForPaintInvalidation() is taken from the
+ // parent table, and being mid-layout, that is invalid. Instead, we issue paint invalidations for our cells.
+ if (selfNeedsLayout() && checkForPaintInvalidation()) {
+ for (RenderTableCell* cell = firstCell(); cell; cell = cell->nextCell()) {
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ // FIXME: Is this needed with Repaint After Layout?
+ cell->setShouldDoFullPaintInvalidationAfterLayout(true);
+ } else {
+ cell->paintInvalidationForWholeRenderer();
+ }
}
}
- statePusher.pop();
// RenderTableSection::layoutRows will set our logical height and width later, so it calls updateLayerTransform().
clearNeedsLayout();
}
-LayoutRect RenderTableRow::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
-{
- ASSERT(parent());
-
- if (repaintContainer == this)
- return RenderBox::clippedOverflowRectForRepaint(repaintContainer);
-
- // For now, just repaint the whole table.
- // FIXME: Find a better way to do this, e.g., need to repaint all the cells that we
- // might have propagated a background color into.
- // FIXME: do repaintContainer checks here
- if (RenderTable* parentTable = table())
- return parentTable->clippedOverflowRectForRepaint(repaintContainer);
-
- return LayoutRect();
-}
-
// Hit Testing
bool RenderTableRow::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
{
// Table rows cannot ever be hit tested. Effectively they do not exist.
// Just forward to our children always.
- for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
+ for (RenderTableCell* cell = lastCell(); cell; cell = cell->previousCell()) {
// FIXME: We have to skip over inline flows, since they can show up inside table rows
// at the moment (a demoted inline <form> for example). If we ever implement a
// table-specific hit-test method (which we should do for performance reasons anyway),
// then we can remove this check.
- if (child->isTableCell() && !toRenderBox(child)->hasSelfPaintingLayer()) {
- LayoutPoint cellPoint = flipForWritingModeForChild(toRenderTableCell(child), accumulatedOffset);
- if (child->nodeAtPoint(request, result, locationInContainer, cellPoint, action)) {
+ if (!cell->hasSelfPaintingLayer()) {
+ LayoutPoint cellPoint = flipForWritingModeForChild(cell, accumulatedOffset);
+ if (cell->nodeAtPoint(request, result, locationInContainer, cellPoint, action)) {
updateHitTestResult(result, locationInContainer.point() - toLayoutSize(cellPoint));
return true;
}
@@ -251,23 +232,19 @@ void RenderTableRow::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
paintOutlineForRowIfNeeded(paintInfo, paintOffset);
- for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
- if (child->isTableCell()) {
- // Paint the row background behind the cell.
- if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground) {
- RenderTableCell* cell = toRenderTableCell(child);
- cell->paintBackgroundsBehindCell(paintInfo, paintOffset, this);
- }
- if (!toRenderBox(child)->hasSelfPaintingLayer())
- child->paint(paintInfo, paintOffset);
- }
+ for (RenderTableCell* cell = firstCell(); cell; cell = cell->nextCell()) {
+ // Paint the row background behind the cell.
+ if (paintInfo.phase == PaintPhaseBlockBackground || paintInfo.phase == PaintPhaseChildBlockBackground)
+ cell->paintBackgroundsBehindCell(paintInfo, paintOffset, this);
+ if (!cell->hasSelfPaintingLayer())
+ cell->paint(paintInfo, paintOffset);
}
}
void RenderTableRow::imageChanged(WrappedImagePtr, const IntRect*)
{
// FIXME: Examine cells and repaint only the rect the image paints in.
- repaint();
+ paintInvalidationForWholeRenderer();
}
RenderTableRow* RenderTableRow::createAnonymous(Document* document)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.h
index 735f903c627..8dc3550ed97 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableRow.h
@@ -4,7 +4,7 @@
* (C) 1998 Waldo Bastian (bastian@kde.org)
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -36,8 +36,11 @@ class RenderTableRow FINAL : public RenderBox {
public:
explicit RenderTableRow(Element*);
- RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
- RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
+ RenderTableCell* firstCell() const;
+ RenderTableCell* lastCell() const;
+
+ RenderTableRow* previousRow() const;
+ RenderTableRow* nextRow() const;
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
@@ -88,28 +91,40 @@ public:
const BorderValue& borderAdjoiningStartCell(const RenderTableCell*) const;
const BorderValue& borderAdjoiningEndCell(const RenderTableCell*) const;
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
+
private:
- virtual RenderObjectChildList* virtualChildren() { return children(); }
- virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ virtual RenderObjectChildList* virtualChildren() OVERRIDE { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const OVERRIDE { return children(); }
- virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableRow (anonymous)" : "RenderTableRow"; }
+ virtual const char* renderName() const OVERRIDE { return (isAnonymous() || isPseudoElement()) ? "RenderTableRow (anonymous)" : "RenderTableRow"; }
- virtual bool isTableRow() const { return true; }
+ virtual bool isTableRow() const OVERRIDE { return true; }
virtual void willBeRemovedFromTree() OVERRIDE;
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
- virtual void layout();
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const;
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
+ virtual void layout() OVERRIDE;
+
+ virtual LayerType layerTypeRequired() const OVERRIDE
+ {
+ if (hasTransform() || hasHiddenBackface() || hasClipPath() || createsGroup() || isStickyPositioned() || style()->shouldCompositeForCurrentAnimations())
+ return NormalLayer;
+
+ if (hasOverflowClip())
+ return OverflowClipLayer;
- virtual bool requiresLayer() const OVERRIDE { return hasOverflowClip() || hasTransform() || hasHiddenBackface() || hasClipPath() || createsGroup(); }
+ return NoLayer;
+ }
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+
+ void nextSibling() const WTF_DELETED_FUNCTION;
+ void previousSibling() const WTF_DELETED_FUNCTION;
RenderObjectChildList m_children;
unsigned m_rowIndex : 31;
@@ -117,6 +132,28 @@ private:
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderTableRow, isTableRow());
+inline RenderTableRow* RenderTableRow::previousRow() const
+{
+ return toRenderTableRow(RenderObject::previousSibling());
+}
+
+inline RenderTableRow* RenderTableRow::nextRow() const
+{
+ return toRenderTableRow(RenderObject::nextSibling());
+}
+
+inline RenderTableRow* RenderTableSection::firstRow() const
+{
+ ASSERT(children() == virtualChildren());
+ return toRenderTableRow(children()->firstChild());
+}
+
+inline RenderTableRow* RenderTableSection::lastRow() const
+{
+ ASSERT(children() == virtualChildren());
+ return toRenderTableRow(children()->lastChild());
+}
+
} // namespace WebCore
#endif // RenderTableRow_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.cpp
index ab6d4da9c60..d7dfc425eee 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.cpp
@@ -4,7 +4,7 @@
* (C) 1998 Waldo Bastian (bastian@kde.org)
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
*
* This library is free software; you can redistribute it and/or
@@ -26,12 +26,9 @@
#include "config.h"
#include "core/rendering/RenderTableSection.h"
-// FIXME: Remove 'RuntimeEnabledFeatures.h' when http://crbug.com/78724 is closed.
-#include "RuntimeEnabledFeatures.h"
#include <limits>
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderTableCell.h"
#include "core/rendering/RenderTableCol.h"
@@ -127,10 +124,10 @@ void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild
if (!child->isTableRow()) {
RenderObject* last = beforeChild;
if (!last)
- last = lastChild();
+ last = lastRow();
if (last && last->isAnonymous() && !last->isBeforeOrAfterContent()) {
if (beforeChild == last)
- beforeChild = last->firstChild();
+ beforeChild = last->slowFirstChild();
last->addChild(child, beforeChild);
return;
}
@@ -289,7 +286,7 @@ void RenderTableSection::populateSpanningRowsHeightFromCell(RenderTableCell* cel
spanningRowsHeight.rowHeight[row] = m_rowPos[actualRow + 1] - m_rowPos[actualRow] - borderSpacingForRow(actualRow);
if (!spanningRowsHeight.rowHeight[row])
- spanningRowsHeight.rowWithOnlySpanningCells |= rowHasOnlySpanningCells(actualRow);
+ spanningRowsHeight.isAnyRowWithOnlySpanningCells |= rowHasOnlySpanningCells(actualRow);
spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row];
spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= borderSpacingForRow(actualRow);
@@ -328,6 +325,17 @@ void RenderTableSection::distributeExtraRowSpanHeightToPercentRows(RenderTableCe
}
}
+// Sometimes the multiplication of the 2 values below will overflow an integer.
+// So we convert the parameters to 'long long' instead of 'int' to avoid the
+// problem in this function.
+static void updatePositionIncreasedWithRowHeight(long long extraHeight, long long rowHeight, long long totalHeight, int& accumulatedPositionIncrease, int& remainder)
+{
+ COMPILE_ASSERT(sizeof(long long int) > sizeof(int), int_should_be_less_than_longlong);
+
+ accumulatedPositionIncrease += (extraHeight * rowHeight) / totalHeight;
+ remainder += (extraHeight * rowHeight) % totalHeight;
+}
+
void RenderTableSection::distributeExtraRowSpanHeightToAutoRows(RenderTableCell* cell, int totalAutoRowsHeight, int& extraRowSpanningHeight, Vector<int>& rowsHeight)
{
if (!extraRowSpanningHeight || !totalAutoRowsHeight)
@@ -342,8 +350,7 @@ void RenderTableSection::distributeExtraRowSpanHeightToAutoRows(RenderTableCell*
// So extra height distributed in auto spanning rows based on their weight in spanning cell.
for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
if (m_grid[row].logicalHeight.isAuto()) {
- accumulatedPositionIncrease += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) / totalAutoRowsHeight;
- remainder += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) % totalAutoRowsHeight;
+ updatePositionIncreasedWithRowHeight(extraRowSpanningHeight, rowsHeight[row - rowIndex], totalAutoRowsHeight, accumulatedPositionIncrease, remainder);
// While whole extra spanning height is distributing in auto spanning rows, rational parts remains
// in every integer division. So accumulating all remainder part in integer division and when total remainder
@@ -376,8 +383,7 @@ void RenderTableSection::distributeExtraRowSpanHeightToRemainingRows(RenderTable
// So extra height distribution in remaining spanning rows based on their weight in spanning cell.
for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
if (!m_grid[row].logicalHeight.isPercent()) {
- accumulatedPositionIncrease += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) / totalRemainingRowsHeight;
- remainder += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) % totalRemainingRowsHeight;
+ updatePositionIncreasedWithRowHeight(extraRowSpanningHeight, rowsHeight[row - rowIndex], totalRemainingRowsHeight, accumulatedPositionIncrease, remainder);
// While whole extra spanning height is distributing in remaining spanning rows, rational parts remains
// in every integer division. So accumulating all remainder part in integer division and when total remainder
@@ -542,14 +548,31 @@ void RenderTableSection::distributeRowSpanHeightToRows(SpanningRenderTableCells&
populateSpanningRowsHeightFromCell(cell, spanningRowsHeight);
- if (spanningRowsHeight.rowWithOnlySpanningCells)
+ // Here we are handling only row(s) who have only rowspanning cells and do not have any empty cell.
+ if (spanningRowsHeight.isAnyRowWithOnlySpanningCells)
updateRowsHeightHavingOnlySpanningCells(cell, spanningRowsHeight);
- if (!spanningRowsHeight.totalRowsHeight || spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= spanningRowsHeight.totalRowsHeight) {
+ // This code handle row(s) that have rowspanning cell(s) and at least one empty cell.
+ // Such rows are not handled below and end up having a height of 0. That would mean
+ // content overlapping if one of their cells has any content. To avoid the problem, we
+ // add all the remaining spanning cells' height to the last spanned row.
+ // This means that we could grow a row past its 'height' or break percentage spreading
+ // however this is better than overlapping content.
+ // FIXME: Is there a better algorithm?
+ if (!spanningRowsHeight.totalRowsHeight) {
+ if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing)
+ m_rowPos[spanningCellEndIndex] += spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing + borderSpacingForRow(spanningCellEndIndex - 1);
+
+ extraHeightToPropagate = m_rowPos[spanningCellEndIndex] - originalBeforePosition;
+ continue;
+ }
+
+ if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= spanningRowsHeight.totalRowsHeight) {
extraHeightToPropagate = m_rowPos[rowIndex + rowSpan] - originalBeforePosition;
continue;
}
+ // Below we are handling only row(s) who have at least one visible cell without rowspan value.
int totalPercent = 0;
int totalAutoRowsHeight = 0;
int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight;
@@ -612,15 +635,15 @@ void RenderTableSection::updateBaselineForCell(RenderTableCell* cell, unsigned r
int RenderTableSection::calcRowLogicalHeight()
{
#ifndef NDEBUG
- SetLayoutNeededForbiddenScope layoutForbiddenScope(this);
+ SetLayoutNeededForbiddenScope layoutForbiddenScope(*this);
#endif
ASSERT(!needsLayout());
RenderTableCell* cell;
- RenderView* viewRenderer = view();
- LayoutStateMaintainer statePusher(viewRenderer);
+ // FIXME: This shouldn't use the same constructor as RenderView.
+ LayoutState state(*this);
m_rowPos.resize(m_grid.size() + 1);
@@ -640,7 +663,7 @@ int RenderTableSection::calcRowLogicalHeight()
LayoutUnit baselineDescent = 0;
// Our base size is the biggest logical height from our cells' styles (excluding row spanning cells).
- m_rowPos[r + 1] = max(m_rowPos[r] + minimumValueForLength(m_grid[r].logicalHeight, 0, viewRenderer).round(), 0);
+ m_rowPos[r + 1] = max(m_rowPos[r] + minimumValueForLength(m_grid[r].logicalHeight, 0).round(), 0);
Row& row = m_grid[r].row;
unsigned totalCols = row.size();
@@ -653,58 +676,35 @@ int RenderTableSection::calcRowLogicalHeight()
if (current.inColSpan && cell->rowSpan() == 1)
continue;
- if (RuntimeEnabledFeatures::rowSpanLogicalHeightSpreadingEnabled()) {
- if (cell->rowSpan() > 1) {
- // For row spanning cells, we only handle them for the first row they span. This ensures we take their baseline into account.
- if (lastRowSpanCell != cell && cell->rowIndex() == r) {
+ if (cell->rowSpan() > 1) {
+ // For row spanning cells, we only handle them for the first row they span. This ensures we take their baseline into account.
+ if (lastRowSpanCell != cell && cell->rowIndex() == r) {
#ifndef NDEBUG
- ASSERT(!uniqueCells.contains(cell));
- uniqueCells.add(cell);
+ ASSERT(!uniqueCells.contains(cell));
+ uniqueCells.add(cell);
#endif
- rowSpanCells.append(cell);
- lastRowSpanCell = cell;
+ rowSpanCells.append(cell);
+ lastRowSpanCell = cell;
- // Find out the baseline. The baseline is set on the first row in a rowSpan.
- updateBaselineForCell(cell, r, baselineDescent);
- }
- continue;
+ // Find out the baseline. The baseline is set on the first row in a rowSpan.
+ updateBaselineForCell(cell, r, baselineDescent);
}
-
- ASSERT(cell->rowSpan() == 1);
- } else {
- // FIXME: We add all the logical row of a rowspan to the last rows
- // until crbug.com/78724 is fixed and the runtime flag removed.
- // This avoids propagating temporary regressions while we fix the bug.
- if ((cell->rowIndex() + cell->rowSpan() - 1) != r)
- continue;
+ continue;
}
+ ASSERT(cell->rowSpan() == 1);
+
if (cell->hasOverrideHeight()) {
- if (!statePusher.didPush()) {
- // Technically, we should also push state for the row, but since
- // rows don't push a coordinate transform, that's not necessary.
- statePusher.push(this, locationOffset());
- }
cell->clearIntrinsicPadding();
cell->clearOverrideSize();
cell->forceChildLayout();
}
- if (RuntimeEnabledFeatures::rowSpanLogicalHeightSpreadingEnabled()) {
- m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r] + cell->logicalHeightForRowSizing());
-
- // Find out the baseline.
- updateBaselineForCell(cell, r, baselineDescent);
- } else {
- // For row spanning cells, |r| is the last row in the span.
- unsigned cellStartRow = cell->rowIndex();
+ m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r] + cell->logicalHeightForRowSizing());
- m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[cellStartRow] + cell->logicalHeightForRowSizing());
-
- // Find out the baseline.
- updateBaselineForCell(cell, cellStartRow, baselineDescent);
- }
+ // Find out the baseline.
+ updateBaselineForCell(cell, r, baselineDescent);
}
}
@@ -713,15 +713,11 @@ int RenderTableSection::calcRowLogicalHeight()
m_rowPos[r + 1] = max(m_rowPos[r + 1], m_rowPos[r]);
}
- if (!rowSpanCells.isEmpty()) {
- ASSERT(RuntimeEnabledFeatures::rowSpanLogicalHeightSpreadingEnabled());
+ if (!rowSpanCells.isEmpty())
distributeRowSpanHeightToRows(rowSpanCells);
- }
ASSERT(!needsLayout());
- statePusher.pop();
-
return m_rowPos[m_grid.size()];
}
@@ -731,17 +727,15 @@ void RenderTableSection::layout()
ASSERT(!needsCellRecalc());
ASSERT(!table()->needsSectionRecalc());
- LayoutRectRecorder recorder(*this);
-
// addChild may over-grow m_grid but we don't want to throw away the memory too early as addChild
// can be called in a loop (e.g during parsing). Doing it now ensures we have a stable-enough structure.
m_grid.shrinkToFit();
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
+ LayoutState state(*this, locationOffset());
const Vector<int>& columnPos = table()->columnPositions();
- SubtreeLayoutScope layouter(this);
+ SubtreeLayoutScope layouter(*this);
for (unsigned r = 0; r < m_grid.size(); ++r) {
Row& row = m_grid[r].row;
unsigned cols = row.size();
@@ -764,11 +758,13 @@ void RenderTableSection::layout()
cell->setCellLogicalWidth(tableLayoutLogicalWidth, layouter);
}
- if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer)
+ if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) {
+ if (!rowRenderer->needsLayout())
+ rowRenderer->markForPaginationRelayoutIfNeeded(layouter);
rowRenderer->layoutIfNeeded();
+ }
}
- statePusher.pop();
clearNeedsLayout();
}
@@ -874,11 +870,13 @@ static bool shouldFlexCellChild(RenderObject* cellDescendant)
void RenderTableSection::layoutRows()
{
#ifndef NDEBUG
- SetLayoutNeededForbiddenScope layoutForbiddenScope(this);
+ SetLayoutNeededForbiddenScope layoutForbiddenScope(*this);
#endif
ASSERT(!needsLayout());
+ // FIXME: Changing the height without a layout can change the overflow so it seems wrong.
+
unsigned totalRows = m_grid.size();
// Set the width of our section now. The rows will also be this width.
@@ -890,7 +888,7 @@ void RenderTableSection::layoutRows()
int vspacing = table()->vBorderSpacing();
unsigned nEffCols = table()->numEffCols();
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
+ LayoutState state(*this, locationOffset());
for (unsigned r = 0; r < totalRows; r++) {
// Set the row's x/y position and width/height.
@@ -898,7 +896,9 @@ void RenderTableSection::layoutRows()
rowRenderer->setLocation(LayoutPoint(0, m_rowPos[r]));
rowRenderer->setLogicalWidth(logicalWidth());
rowRenderer->setLogicalHeight(m_rowPos[r + 1] - m_rowPos[r] - vspacing);
- rowRenderer->updateLayerTransform();
+ rowRenderer->updateLayerTransformAfterLayout();
+ rowRenderer->clearAllOverflows();
+ rowRenderer->addVisualEffectOverflow();
}
int rowHeightIncreaseForPagination = 0;
@@ -966,15 +966,15 @@ void RenderTableSection::layoutRows()
}
}
- SubtreeLayoutScope layouter(cell);
+ SubtreeLayoutScope layouter(*cell);
cell->computeIntrinsicPadding(rHeight, layouter);
LayoutRect oldCellRect = cell->frameRect();
setLogicalPositionForCell(cell, c);
- if (!cell->needsLayout() && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell, cell->logicalTop()) != cell->pageLogicalOffset())
- layouter.setChildNeedsLayout(cell);
+ if (!cell->needsLayout())
+ cell->markForPaginationRelayoutIfNeeded(layouter);
cell->layoutIfNeeded();
@@ -983,20 +983,27 @@ void RenderTableSection::layoutRows()
// FIXME: Pagination might have made us change size. For now just shrink or grow the cell to fit without doing a relayout.
// We'll also do a basic increase of the row height to accommodate the cell if it's bigger, but this isn't quite right
// either. It's at least stable though and won't result in an infinite # of relayouts that may never stabilize.
- if (cell->logicalHeight() > rHeight)
- rowHeightIncreaseForPagination = max<int>(rowHeightIncreaseForPagination, cell->logicalHeight() - rHeight);
+ LayoutUnit oldLogicalHeight = cell->logicalHeight();
+ if (oldLogicalHeight > rHeight)
+ rowHeightIncreaseForPagination = max<int>(rowHeightIncreaseForPagination, oldLogicalHeight - rHeight);
cell->setLogicalHeight(rHeight);
+ cell->computeOverflow(oldLogicalHeight, false);
}
LayoutSize childOffset(cell->location() - oldCellRect.location());
if (childOffset.width() || childOffset.height()) {
- view()->addLayoutDelta(childOffset);
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ view()->addLayoutDelta(childOffset);
// If the child moved, we have to repaint it as well as any floating/positioned
- // descendants. An exception is if we need a layout. In this case, we know we're going to
+ // descendants. An exception is if we need a layout. In this case, we know we're going to
// repaint ourselves (and the child) anyway.
- if (!table()->selfNeedsLayout() && cell->checkForRepaintDuringLayout())
- cell->repaintDuringLayoutIfMoved(oldCellRect);
+ if (!table()->selfNeedsLayout() && cell->checkForPaintInvalidation()) {
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ cell->setMayNeedPaintInvalidation(true);
+ else
+ cell->repaintDuringLayoutIfMoved(oldCellRect);
+ }
}
}
if (rowHeightIncreaseForPagination) {
@@ -1004,8 +1011,11 @@ void RenderTableSection::layoutRows()
m_rowPos[rowIndex] += rowHeightIncreaseForPagination;
for (unsigned c = 0; c < nEffCols; ++c) {
Vector<RenderTableCell*, 1>& cells = cellAt(r, c).cells;
- for (size_t i = 0; i < cells.size(); ++i)
- cells[i]->setLogicalHeight(cells[i]->logicalHeight() + rowHeightIncreaseForPagination);
+ for (size_t i = 0; i < cells.size(); ++i) {
+ LayoutUnit oldLogicalHeight = cells[i]->logicalHeight();
+ cells[i]->setLogicalHeight(oldLogicalHeight + rowHeightIncreaseForPagination);
+ cells[i]->computeOverflow(oldLogicalHeight, false);
+ }
}
}
}
@@ -1015,8 +1025,6 @@ void RenderTableSection::layoutRows()
setLogicalHeight(m_rowPos[totalRows]);
computeOverflowFromCells(totalRows, nEffCols);
-
- statePusher.pop();
}
void RenderTableSection::computeOverflowFromCells()
@@ -1062,7 +1070,7 @@ void RenderTableSection::computeOverflowFromCells(unsigned totalRows, unsigned n
ASSERT(hasOverflowingCell == this->hasOverflowingCell());
}
-int RenderTableSection::calcOuterBorderBefore() const
+int RenderTableSection::calcBlockDirectionOuterBorder(BlockBorderSide side) const
{
unsigned totalCols = table()->numEffCols();
if (!m_grid.size() || !totalCols)
@@ -1070,13 +1078,13 @@ int RenderTableSection::calcOuterBorderBefore() const
unsigned borderWidth = 0;
- const BorderValue& sb = style()->borderBefore();
+ const BorderValue& sb = side == BorderBefore ? style()->borderBefore() : style()->borderAfter();
if (sb.style() == BHIDDEN)
return -1;
if (sb.style() > BHIDDEN)
borderWidth = sb.width();
- const BorderValue& rb = firstChild()->style()->borderBefore();
+ const BorderValue& rb = side == BorderBefore ? firstRow()->style()->borderBefore() : lastRow()->style()->borderAfter();
if (rb.style() == BHIDDEN)
return -1;
if (rb.style() > BHIDDEN && rb.width() > borderWidth)
@@ -1084,14 +1092,15 @@ int RenderTableSection::calcOuterBorderBefore() const
bool allHidden = true;
for (unsigned c = 0; c < totalCols; c++) {
- const CellStruct& current = cellAt(0, c);
+ const CellStruct& current = cellAt(side == BorderBefore ? 0 : m_grid.size() - 1, c);
if (current.inColSpan || !current.hasCells())
continue;
- const BorderValue& cb = current.primaryCell()->style()->borderBefore(); // FIXME: Make this work with perpendicular and flipped cells.
+ const RenderStyle* primaryCellStyle = current.primaryCell()->style();
+ const BorderValue& cb = side == BorderBefore ? primaryCellStyle->borderBefore() : primaryCellStyle->borderAfter(); // FIXME: Make this work with perpendicular and flipped cells.
// FIXME: Don't repeat for the same col group
RenderTableCol* colGroup = table()->colElement(c);
if (colGroup) {
- const BorderValue& gb = colGroup->style()->borderBefore();
+ const BorderValue& gb = side == BorderBefore ? colGroup->style()->borderBefore() : colGroup->style()->borderAfter();
if (gb.style() == BHIDDEN || cb.style() == BHIDDEN)
continue;
allHidden = false;
@@ -1110,76 +1119,28 @@ int RenderTableSection::calcOuterBorderBefore() const
if (allHidden)
return -1;
+ if (side == BorderAfter)
+ borderWidth++; // Distribute rounding error
return borderWidth / 2;
}
-int RenderTableSection::calcOuterBorderAfter() const
+int RenderTableSection::calcInlineDirectionOuterBorder(InlineBorderSide side) const
{
unsigned totalCols = table()->numEffCols();
if (!m_grid.size() || !totalCols)
return 0;
+ unsigned colIndex = side == BorderStart ? 0 : totalCols - 1;
unsigned borderWidth = 0;
- const BorderValue& sb = style()->borderAfter();
+ const BorderValue& sb = side == BorderStart ? style()->borderStart() : style()->borderEnd();
if (sb.style() == BHIDDEN)
return -1;
if (sb.style() > BHIDDEN)
borderWidth = sb.width();
- const BorderValue& rb = lastChild()->style()->borderAfter();
- if (rb.style() == BHIDDEN)
- return -1;
- if (rb.style() > BHIDDEN && rb.width() > borderWidth)
- borderWidth = rb.width();
-
- bool allHidden = true;
- for (unsigned c = 0; c < totalCols; c++) {
- const CellStruct& current = cellAt(m_grid.size() - 1, c);
- if (current.inColSpan || !current.hasCells())
- continue;
- const BorderValue& cb = current.primaryCell()->style()->borderAfter(); // FIXME: Make this work with perpendicular and flipped cells.
- // FIXME: Don't repeat for the same col group
- RenderTableCol* colGroup = table()->colElement(c);
- if (colGroup) {
- const BorderValue& gb = colGroup->style()->borderAfter();
- if (gb.style() == BHIDDEN || cb.style() == BHIDDEN)
- continue;
- allHidden = false;
- if (gb.style() > BHIDDEN && gb.width() > borderWidth)
- borderWidth = gb.width();
- if (cb.style() > BHIDDEN && cb.width() > borderWidth)
- borderWidth = cb.width();
- } else {
- if (cb.style() == BHIDDEN)
- continue;
- allHidden = false;
- if (cb.style() > BHIDDEN && cb.width() > borderWidth)
- borderWidth = cb.width();
- }
- }
- if (allHidden)
- return -1;
-
- return (borderWidth + 1) / 2;
-}
-
-int RenderTableSection::calcOuterBorderStart() const
-{
- unsigned totalCols = table()->numEffCols();
- if (!m_grid.size() || !totalCols)
- return 0;
-
- unsigned borderWidth = 0;
-
- const BorderValue& sb = style()->borderStart();
- if (sb.style() == BHIDDEN)
- return -1;
- if (sb.style() > BHIDDEN)
- borderWidth = sb.width();
-
- if (RenderTableCol* colGroup = table()->colElement(0)) {
- const BorderValue& gb = colGroup->style()->borderStart();
+ if (RenderTableCol* colGroup = table()->colElement(colIndex)) {
+ const BorderValue& gb = side == BorderStart ? colGroup->style()->borderStart() : colGroup->style()->borderEnd();
if (gb.style() == BHIDDEN)
return -1;
if (gb.style() > BHIDDEN && gb.width() > borderWidth)
@@ -1188,12 +1149,14 @@ int RenderTableSection::calcOuterBorderStart() const
bool allHidden = true;
for (unsigned r = 0; r < m_grid.size(); r++) {
- const CellStruct& current = cellAt(r, 0);
+ const CellStruct& current = cellAt(r, colIndex);
if (!current.hasCells())
continue;
// FIXME: Don't repeat for the same cell
- const BorderValue& cb = current.primaryCell()->style()->borderStart(); // FIXME: Make this work with perpendicular and flipped cells.
- const BorderValue& rb = current.primaryCell()->parent()->style()->borderStart();
+ const RenderStyle* primaryCellStyle = current.primaryCell()->style();
+ const RenderStyle* primaryCellParentStyle = current.primaryCell()->parent()->style();
+ const BorderValue& cb = side == BorderStart ? primaryCellStyle->borderStart() : primaryCellStyle->borderEnd(); // FIXME: Make this work with perpendicular and flipped cells.
+ const BorderValue& rb = side == BorderStart ? primaryCellParentStyle->borderStart() : primaryCellParentStyle->borderEnd();
if (cb.style() == BHIDDEN || rb.style() == BHIDDEN)
continue;
allHidden = false;
@@ -1205,59 +1168,17 @@ int RenderTableSection::calcOuterBorderStart() const
if (allHidden)
return -1;
- return (borderWidth + (table()->style()->isLeftToRightDirection() ? 0 : 1)) / 2;
-}
-
-int RenderTableSection::calcOuterBorderEnd() const
-{
- unsigned totalCols = table()->numEffCols();
- if (!m_grid.size() || !totalCols)
- return 0;
-
- unsigned borderWidth = 0;
-
- const BorderValue& sb = style()->borderEnd();
- if (sb.style() == BHIDDEN)
- return -1;
- if (sb.style() > BHIDDEN)
- borderWidth = sb.width();
-
- if (RenderTableCol* colGroup = table()->colElement(totalCols - 1)) {
- const BorderValue& gb = colGroup->style()->borderEnd();
- if (gb.style() == BHIDDEN)
- return -1;
- if (gb.style() > BHIDDEN && gb.width() > borderWidth)
- borderWidth = gb.width();
- }
-
- bool allHidden = true;
- for (unsigned r = 0; r < m_grid.size(); r++) {
- const CellStruct& current = cellAt(r, totalCols - 1);
- if (!current.hasCells())
- continue;
- // FIXME: Don't repeat for the same cell
- const BorderValue& cb = current.primaryCell()->style()->borderEnd(); // FIXME: Make this work with perpendicular and flipped cells.
- const BorderValue& rb = current.primaryCell()->parent()->style()->borderEnd();
- if (cb.style() == BHIDDEN || rb.style() == BHIDDEN)
- continue;
- allHidden = false;
- if (cb.style() > BHIDDEN && cb.width() > borderWidth)
- borderWidth = cb.width();
- if (rb.style() > BHIDDEN && rb.width() > borderWidth)
- borderWidth = rb.width();
- }
- if (allHidden)
- return -1;
-
- return (borderWidth + (table()->style()->isLeftToRightDirection() ? 1 : 0)) / 2;
+ if ((side == BorderStart) != table()->style()->isLeftToRightDirection())
+ borderWidth++; // Distribute rounding error
+ return borderWidth / 2;
}
void RenderTableSection::recalcOuterBorder()
{
- m_outerBorderBefore = calcOuterBorderBefore();
- m_outerBorderAfter = calcOuterBorderAfter();
- m_outerBorderStart = calcOuterBorderStart();
- m_outerBorderEnd = calcOuterBorderEnd();
+ m_outerBorderBefore = calcBlockDirectionOuterBorder(BorderBefore);
+ m_outerBorderAfter = calcBlockDirectionOuterBorder(BorderAfter);
+ m_outerBorderStart = calcInlineDirectionOuterBorder(BorderStart);
+ m_outerBorderEnd = calcInlineDirectionOuterBorder(BorderEnd);
}
int RenderTableSection::firstLineBoxBaseline() const
@@ -1286,7 +1207,7 @@ void RenderTableSection::paint(PaintInfo& paintInfo, const LayoutPoint& paintOff
{
ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
- ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
+ ASSERT(!needsLayout());
// avoid crashing on bugs that cause us to paint with dirty layout
if (needsLayout())
return;
@@ -1463,11 +1384,8 @@ CellSpan RenderTableSection::spannedColumns(const LayoutRect& flippedRect) const
void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
- PaintPhase paintPhase = paintInfo.phase;
-
LayoutRect localRepaintRect = paintInfo.rect;
localRepaintRect.moveBy(-paintOffset);
- localRepaintRect.inflate(maximalOutlineSize(paintPhase));
LayoutRect tableAlignedRect = logicalRectForWritingModeAndDirection(localRepaintRect);
@@ -1564,7 +1482,7 @@ void RenderTableSection::paintObject(PaintInfo& paintInfo, const LayoutPoint& pa
void RenderTableSection::imageChanged(WrappedImagePtr, const IntRect*)
{
// FIXME: Examine cells and repaint only the rect the image paints in.
- repaint();
+ paintInvalidationForWholeRenderer();
}
void RenderTableSection::recalcCells()
@@ -1579,30 +1497,22 @@ void RenderTableSection::recalcCells()
m_cRow = 0;
m_grid.clear();
- for (RenderObject* row = firstChild(); row; row = row->nextSibling()) {
- if (row->isTableRow()) {
- unsigned insertionRow = m_cRow;
- m_cRow++;
- m_cCol = 0;
- ensureRows(m_cRow);
-
- RenderTableRow* tableRow = toRenderTableRow(row);
- m_grid[insertionRow].rowRenderer = tableRow;
- tableRow->setRowIndex(insertionRow);
- setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]);
+ for (RenderTableRow* row = firstRow(); row; row = row->nextRow()) {
+ unsigned insertionRow = m_cRow;
+ ++m_cRow;
+ m_cCol = 0;
+ ensureRows(m_cRow);
- for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
- if (!cell->isTableCell())
- continue;
+ m_grid[insertionRow].rowRenderer = row;
+ row->setRowIndex(insertionRow);
+ setRowLogicalHeightToRowStyleLogicalHeight(m_grid[insertionRow]);
- RenderTableCell* tableCell = toRenderTableCell(cell);
- addCell(tableCell, tableRow);
- }
- }
+ for (RenderTableCell* cell = row->firstCell(); cell; cell = cell->nextCell())
+ addCell(cell, row);
}
m_grid.shrinkToFit();
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
}
// FIXME: This function could be made O(1) in certain cases (like for the non-most-constrainive cells' case).
@@ -1613,12 +1523,8 @@ void RenderTableSection::rowLogicalHeightChanged(unsigned rowIndex)
setRowLogicalHeightToRowStyleLogicalHeight(m_grid[rowIndex]);
- for (RenderObject* cell = m_grid[rowIndex].rowRenderer->firstChild(); cell; cell = cell->nextSibling()) {
- if (!cell->isTableCell())
- continue;
-
- updateLogicalHeightForCell(m_grid[rowIndex], toRenderTableCell(cell));
- }
+ for (RenderTableCell* cell = m_grid[rowIndex].rowRenderer->firstCell(); cell; cell = cell->nextCell())
+ updateLogicalHeightForCell(m_grid[rowIndex], cell);
}
void RenderTableSection::setNeedsCellRecalc()
@@ -1685,7 +1591,7 @@ void RenderTableSection::splitColumn(unsigned pos, unsigned first)
Row& r = m_grid[row].row;
r.insert(pos + 1, CellStruct());
if (r[pos].hasCells()) {
- r[pos + 1].cells.append(r[pos].cells);
+ r[pos + 1].cells.appendVector(r[pos].cells);
RenderTableCell* cell = r[pos].primaryCell();
ASSERT(cell);
ASSERT(cell->colSpan() >= (r[pos].inColSpan ? 1u : 0));
@@ -1704,25 +1610,25 @@ void RenderTableSection::splitColumn(unsigned pos, unsigned first)
bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
{
// If we have no children then we have nothing to do.
- if (!firstChild())
+ if (!firstRow())
return false;
// Table sections cannot ever be hit tested. Effectively they do not exist.
// Just forward to our children always.
LayoutPoint adjustedLocation = accumulatedOffset + location();
- if (hasOverflowClip() && !locationInContainer.intersects(overflowClipRect(adjustedLocation, locationInContainer.region())))
+ if (hasOverflowClip() && !locationInContainer.intersects(overflowClipRect(adjustedLocation)))
return false;
if (hasOverflowingCell()) {
- for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
+ for (RenderTableRow* row = lastRow(); row; row = row->previousRow()) {
// FIXME: We have to skip over inline flows, since they can show up inside table rows
// at the moment (a demoted inline <form> for example). If we ever implement a
// table-specific hit-test method (which we should do for performance reasons anyway),
// then we can remove this check.
- if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer()) {
- LayoutPoint childPoint = flipForWritingModeForChild(toRenderBox(child), adjustedLocation);
- if (child->nodeAtPoint(request, result, locationInContainer, childPoint, action)) {
+ if (!row->hasSelfPaintingLayer()) {
+ LayoutPoint childPoint = flipForWritingModeForChild(row, adjustedLocation);
+ if (row->nodeAtPoint(request, result, locationInContainer, childPoint, action)) {
updateHitTestResult(result, toLayoutPoint(locationInContainer.point() - childPoint));
return true;
}
@@ -1814,7 +1720,9 @@ void RenderTableSection::setLogicalPositionForCell(RenderTableCell* cell, unsign
cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizontalBorderSpacing);
cell->setLogicalLocation(cellLocation);
- view()->addLayoutDelta(oldCellLocation - cell->location());
+
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+ view()->addLayoutDelta(oldCellLocation - cell->location());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.h
index 42b51ec6b3e..27410d5b14e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTableSection.h
@@ -4,7 +4,7 @@
* (C) 1998 Waldo Bastian (bastian@kde.org)
* (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 1999 Antti Koivisto (koivisto@kde.org)
- * Copyright (C) 2003, 2004, 2005, 2006, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -65,13 +65,13 @@ public:
RenderTableSection(Element*);
virtual ~RenderTableSection();
- RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
- RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
+ RenderTableRow* firstRow() const;
+ RenderTableRow* lastRow() const;
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
virtual int firstLineBoxBaseline() const OVERRIDE;
@@ -129,14 +129,14 @@ public:
SpanningRowsHeight()
: totalRowsHeight(0)
, spanningCellHeightIgnoringBorderSpacing(0)
- , rowWithOnlySpanningCells(false)
+ , isAnyRowWithOnlySpanningCells(false)
{
}
Vector<int> rowHeight;
int totalRowsHeight;
int spanningCellHeightIgnoringBorderSpacing;
- bool rowWithOnlySpanningCells;
+ bool isAnyRowWithOnlySpanningCells;
};
const BorderValue& borderAdjoiningTableStart() const
@@ -174,10 +174,10 @@ public:
void appendColumn(unsigned pos);
void splitColumn(unsigned pos, unsigned first);
- int calcOuterBorderBefore() const;
- int calcOuterBorderAfter() const;
- int calcOuterBorderStart() const;
- int calcOuterBorderEnd() const;
+ enum BlockBorderSide { BorderBefore, BorderAfter };
+ int calcBlockDirectionOuterBorder(BlockBorderSide) const;
+ enum InlineBorderSide { BorderStart, BorderEnd };
+ int calcInlineDirectionOuterBorder(InlineBorderSide) const;
void recalcOuterBorder();
int outerBorderBefore() const { return m_outerBorderBefore; }
@@ -218,26 +218,25 @@ public:
virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
private:
- virtual RenderObjectChildList* virtualChildren() { return children(); }
- virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ virtual RenderObjectChildList* virtualChildren() OVERRIDE { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const OVERRIDE { return children(); }
- virtual const char* renderName() const { return (isAnonymous() || isPseudoElement()) ? "RenderTableSection (anonymous)" : "RenderTableSection"; }
+ virtual const char* renderName() const OVERRIDE { return (isAnonymous() || isPseudoElement()) ? "RenderTableSection (anonymous)" : "RenderTableSection"; }
- virtual bool isTableSection() const { return true; }
+ virtual bool isTableSection() const OVERRIDE { return true; }
virtual void willBeRemovedFromTree() OVERRIDE;
- virtual void layout();
-
- virtual void paintCell(RenderTableCell*, PaintInfo&, const LayoutPoint&);
- virtual void paintObject(PaintInfo&, const LayoutPoint&);
+ virtual void layout() OVERRIDE;
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ void paintCell(RenderTableCell*, PaintInfo&, const LayoutPoint&);
+ virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
int borderSpacingForRow(unsigned row) const { return m_grid[row].rowRenderer ? table()->vBorderSpacing() : 0; }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderText.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderText.cpp
index b89ddc756ba..64fa967bd38 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderText.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderText.cpp
@@ -28,9 +28,9 @@
#include "core/accessibility/AXObjectCache.h"
#include "core/dom/Text.h"
#include "core/editing/TextIterator.h"
-#include "core/fetch/TextResourceDecoder.h"
#include "core/frame/FrameView.h"
#include "core/frame/Settings.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/rendering/AbstractInlineTextBox.h"
#include "core/rendering/EllipsisBox.h"
#include "core/rendering/InlineTextBox.h"
@@ -39,8 +39,12 @@
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/break_lines.h"
+#include "platform/fonts/Character.h"
+#include "platform/fonts/FontCache.h"
#include "platform/geometry/FloatQuad.h"
+#include "platform/text/BidiResolver.h"
#include "platform/text/TextBreakIterator.h"
+#include "platform/text/TextRunIterator.h"
#include "wtf/text/StringBuffer.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/unicode/CharacterNames.h"
@@ -64,7 +68,7 @@ class SecureTextTimer;
typedef HashMap<RenderText*, SecureTextTimer*> SecureTextTimerMap;
static SecureTextTimerMap* gSecureTextTimers = 0;
-class SecureTextTimer : public TimerBase {
+class SecureTextTimer FINAL : public TimerBase {
public:
SecureTextTimer(RenderText* renderText)
: m_renderText(renderText)
@@ -76,13 +80,13 @@ public:
{
m_lastTypedCharacterOffset = lastTypedCharacterOffset;
if (Settings* settings = m_renderText->document().settings())
- startOneShot(settings->passwordEchoDurationInSeconds());
+ startOneShot(settings->passwordEchoDurationInSeconds(), FROM_HERE);
}
void invalidate() { m_lastTypedCharacterOffset = -1; }
unsigned lastTypedCharacterOffset() { return m_lastTypedCharacterOffset; }
private:
- virtual void fired()
+ virtual void fired() OVERRIDE
{
ASSERT(gSecureTextTimers->contains(m_renderText));
m_renderText->setText(m_renderText->text().impl(), true /* forcing setting text as it may be masked later */);
@@ -190,8 +194,8 @@ void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl
// we already did this for the parent of the text run.
// We do have to schedule layouts, though, since a style change can force us to
// need to relayout.
- if (diff == StyleDifferenceLayout) {
- setNeedsLayoutAndPrefWidthsRecalc();
+ if (diff.needsFullLayout()) {
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
m_knownToHaveNoOverflowAndNoFallbackFonts = false;
}
@@ -201,8 +205,11 @@ void RenderText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyl
if (oldTransform != newStyle->textTransform() || oldSecurity != newStyle->textSecurity())
transformText();
+ // This is an optimization that kicks off font load before layout.
+ // In order to make it fast, we only check if the first character of the
+ // text is included in the unicode ranges of the fonts.
if (!text().containsOnlyWhitespace())
- newStyle->font().willUseFontData();
+ newStyle->font().willUseFontData(text().characterStartingAt(0));
}
void RenderText::removeAndDestroyTextBoxes()
@@ -210,7 +217,7 @@ void RenderText::removeAndDestroyTextBoxes()
if (!documentBeingDestroyed()) {
if (firstTextBox()) {
if (isBR()) {
- RootInlineBox* next = firstTextBox()->root()->nextRootBox();
+ RootInlineBox* next = firstTextBox()->root().nextRootBox();
if (next)
next->markDirty();
}
@@ -362,11 +369,11 @@ void RenderText::absoluteRectsForRange(Vector<IntRect>& rects, unsigned start, u
if (useSelectionHeight) {
LayoutRect selectionRect = box->localSelectionRect(start, end);
if (box->isHorizontal()) {
- r.setHeight(selectionRect.height());
- r.setY(selectionRect.y());
+ r.setHeight(selectionRect.height().toFloat());
+ r.setY(selectionRect.y().toFloat());
} else {
- r.setWidth(selectionRect.width());
- r.setX(selectionRect.x());
+ r.setWidth(selectionRect.width().toFloat());
+ r.setX(selectionRect.x().toFloat());
}
}
rects.append(localToAbsoluteQuad(r, 0, wasFixed).enclosingBoundingBox());
@@ -389,7 +396,7 @@ static IntRect ellipsisRectForBox(InlineTextBox* box, unsigned startPos, unsigne
return IntRect();
IntRect rect;
- if (EllipsisBox* ellipsis = box->root()->ellipsisBox()) {
+ if (EllipsisBox* ellipsis = box->root().ellipsisBox()) {
int ellipsisStartPosition = max<int>(startPos - box->start(), 0);
int ellipsisEndPosition = min<int>(endPos - box->start(), box->len());
@@ -445,11 +452,11 @@ void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
if (useSelectionHeight) {
LayoutRect selectionRect = box->localSelectionRect(start, end);
if (box->isHorizontal()) {
- r.setHeight(selectionRect.height());
- r.setY(selectionRect.y());
+ r.setHeight(selectionRect.height().toFloat());
+ r.setY(selectionRect.y().toFloat());
} else {
- r.setWidth(selectionRect.width());
- r.setX(selectionRect.x());
+ r.setWidth(selectionRect.width().toFloat());
+ r.setX(selectionRect.x().toFloat());
}
}
quads.append(localToAbsoluteQuad(r, 0, wasFixed));
@@ -461,27 +468,6 @@ void RenderText::absoluteQuadsForRange(Vector<FloatQuad>& quads, unsigned start,
}
}
-InlineTextBox* RenderText::findNextInlineTextBox(int offset, int& pos) const
-{
- // The text runs point to parts of the RenderText's m_text
- // (they don't include '\n')
- // Find the text run that includes the character at offset
- // and return pos, which is the position of the char in the run.
-
- if (!m_firstTextBox)
- return 0;
-
- InlineTextBox* s = m_firstTextBox;
- int off = s->len();
- while (offset > off && s->nextTextBox()) {
- s = s->nextTextBox();
- off = s->start() + s->len();
- }
- // we are now in the correct text run
- pos = (offset > off ? s->len() : s->len() - (off - offset) );
- return s;
-}
-
enum ShouldAffinityBeDownstream { AlwaysDownstream, AlwaysUpstream, UpstreamIfPositionIsNotAtStart };
static bool lineDirectionPointFitsInBox(int pointLineDirection, InlineTextBox* box, ShouldAffinityBeDownstream& shouldAffinityBeDownstream)
@@ -533,14 +519,13 @@ static PositionWithAffinity createPositionWithAffinityForBox(const InlineBox* bo
affinity = offset > box->caretMinOffset() ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM;
break;
}
- int textStartOffset = box->renderer()->isText() ? toRenderText(box->renderer())->textStartOffset() : 0;
- return box->renderer()->createPositionWithAffinity(offset + textStartOffset, affinity);
+ int textStartOffset = box->renderer().isText() ? toRenderText(box->renderer()).textStartOffset() : 0;
+ return box->renderer().createPositionWithAffinity(offset + textStartOffset, affinity);
}
static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
{
ASSERT(box);
- ASSERT(box->renderer());
ASSERT(offset >= 0);
if (offset && static_cast<unsigned>(offset) < box->len())
@@ -552,7 +537,7 @@ static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffset
const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak();
if ((prevBox && prevBox->bidiLevel() == box->bidiLevel())
- || box->renderer()->containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA
+ || box->renderer().containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA
return createPositionWithAffinityForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
if (prevBox && prevBox->bidiLevel() > box->bidiLevel()) {
@@ -582,7 +567,7 @@ static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffset
const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak();
if ((nextBox && nextBox->bidiLevel() == box->bidiLevel())
- || box->renderer()->containingBlock()->style()->direction() == box->direction())
+ || box->renderer().containingBlock()->style()->direction() == box->direction())
return createPositionWithAffinityForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
// offset is on the right edge
@@ -625,17 +610,17 @@ PositionWithAffinity RenderText::positionForPoint(const LayoutPoint& point)
if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak())
box = box->nextTextBox();
- RootInlineBox* rootBox = box->root();
- LayoutUnit top = min(rootBox->selectionTop(), rootBox->lineTop());
+ RootInlineBox& rootBox = box->root();
+ LayoutUnit top = min(rootBox.selectionTop(), rootBox.lineTop());
if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirection == top)) {
- LayoutUnit bottom = rootBox->selectionBottom();
- if (rootBox->nextRootBox())
- bottom = min(bottom, rootBox->nextRootBox()->lineTop());
+ LayoutUnit bottom = rootBox.selectionBottom();
+ if (rootBox.nextRootBox())
+ bottom = min(bottom, rootBox.nextRootBox()->lineTop());
if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) {
ShouldAffinityBeDownstream shouldAffinityBeDownstream;
if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldAffinityBeDownstream))
- return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection.toFloat()), shouldAffinityBeDownstream);
}
}
lastBox = box;
@@ -644,7 +629,7 @@ PositionWithAffinity RenderText::positionForPoint(const LayoutPoint& point)
if (lastBox) {
ShouldAffinityBeDownstream shouldAffinityBeDownstream;
lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityBeDownstream);
- return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream);
+ return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection.toFloat()) + lastBox->start(), shouldAffinityBeDownstream);
}
return createPositionWithAffinity(0, DOWNSTREAM);
}
@@ -660,8 +645,8 @@ LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, Lay
InlineTextBox* box = toInlineTextBox(inlineBox);
- int height = box->root()->selectionHeight();
- int top = box->root()->selectionTop();
+ int height = box->root().selectionHeight();
+ int top = box->root().selectionTop();
// Go ahead and round left to snap it to the nearest pixel.
float left = box->positionForOffset(caretOffset);
@@ -673,13 +658,13 @@ LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, Lay
left = roundf(left);
- float rootLeft = box->root()->logicalLeft();
- float rootRight = box->root()->logicalRight();
+ float rootLeft = box->root().logicalLeft();
+ float rootRight = box->root().logicalRight();
// FIXME: should we use the width of the root inline box or the
// width of the containing block for this?
if (extraWidthToEndOfLine)
- *extraWidthToEndOfLine = (box->root()->logicalWidth() + rootLeft) - (left + 1);
+ *extraWidthToEndOfLine = (box->root().logicalWidth() + rootLeft) - (left + 1);
RenderBlock* cb = containingBlock();
RenderStyle* cbStyle = cb->style();
@@ -687,7 +672,7 @@ LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, Lay
float leftEdge;
float rightEdge;
leftEdge = min<float>(0, rootLeft);
- rightEdge = max<float>(cb->logicalWidth(), rootRight);
+ rightEdge = max<float>(cb->logicalWidth().toFloat(), rootRight);
bool rightAligned = false;
switch (cbStyle->textAlign()) {
@@ -720,7 +705,7 @@ LayoutRect RenderText::localCaretRect(InlineBox* inlineBox, int caretOffset, Lay
return style()->isHorizontalWritingMode() ? IntRect(left, top, caretWidth, height) : IntRect(top, left, height, caretWidth);
}
-ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len, float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
if (style()->hasTextCombine() && isCombineText()) {
const RenderCombineText* combineText = toRenderCombineText(this);
@@ -728,7 +713,7 @@ ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len
return combineText->combinedTextWidth(f);
}
- if (f.isFixedPitch() && !f.isSmallCaps() && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) {
+ if (f.isFixedPitch() && f.fontDescription().variant() == FontVariantNormal && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) {
float monospaceCharacterWidth = f.spaceWidth();
float w = 0;
bool isSpace;
@@ -755,18 +740,19 @@ ALWAYS_INLINE float RenderText::widthFromCache(const Font& f, int start, int len
isSpace = false;
}
if (isSpace && i > start)
- w += f.wordSpacing();
+ w += f.fontDescription().wordSpacing();
}
return w;
}
- TextRun run = RenderBlockFlow::constructTextRun(const_cast<RenderText*>(this), f, this, start, len, style());
+ TextRun run = RenderBlockFlow::constructTextRun(const_cast<RenderText*>(this), f, this, start, len, style(), textDirection);
run.setCharactersLength(textLength() - start);
ASSERT(run.charactersLength() >= run.length());
run.setCharacterScanForCodePath(!canUseSimpleFontCodePath());
run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
run.setXPos(xPos);
+ FontCachePurgePreventer fontCachePurgePreventer;
return f.width(run, fallbackFonts, glyphOverflow);
}
@@ -775,7 +761,8 @@ void RenderText::trimmedPrefWidths(float leadWidth,
float& lastLineMinWidth, bool& hasBreakableEnd,
bool& hasBreakableChar, bool& hasBreak,
float& firstLineMaxWidth, float& lastLineMaxWidth,
- float& minWidth, float& maxWidth, bool& stripFrontSpaces)
+ float& minWidth, float& maxWidth, bool& stripFrontSpaces,
+ TextDirection direction)
{
bool collapseWhiteSpace = style()->collapseWhiteSpace();
if (!collapseWhiteSpace)
@@ -815,10 +802,10 @@ void RenderText::trimmedPrefWidths(float leadWidth,
const Font& font = style()->font(); // FIXME: This ignores first-line.
if (stripFrontSpaces) {
const UChar space = ' ';
- float spaceWidth = font.width(RenderBlockFlow::constructTextRun(this, font, &space, 1, style()));
+ float spaceWidth = font.width(RenderBlockFlow::constructTextRun(this, font, &space, 1, style(), direction));
maxWidth -= spaceWidth;
} else {
- maxWidth += font.wordSpacing();
+ maxWidth += font.fontDescription().wordSpacing();
}
}
@@ -839,7 +826,7 @@ void RenderText::trimmedPrefWidths(float leadWidth,
linelen++;
if (linelen) {
- lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + lastLineMaxWidth, 0, 0);
+ lastLineMaxWidth = widthFromCache(f, i, linelen, leadWidth + lastLineMaxWidth, direction, 0, 0);
if (firstLine) {
firstLine = false;
leadWidth = 0;
@@ -886,10 +873,10 @@ void RenderText::computePreferredLogicalWidths(float leadWidth)
m_knownToHaveNoOverflowAndNoFallbackFonts = true;
}
-static inline float hyphenWidth(RenderText* renderer, const Font& font)
+static inline float hyphenWidth(RenderText* renderer, const Font& font, TextDirection direction)
{
RenderStyle* style = renderer->style();
- return font.width(RenderBlockFlow::constructTextRun(renderer, font, style->hyphenString().string(), style));
+ return font.width(RenderBlockFlow::constructTextRun(renderer, font, style->hyphenString().string(), style, direction));
}
void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const SimpleFontData*>& fallbackFonts, GlyphOverflow& glyphOverflow)
@@ -925,23 +912,47 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
bool firstLine = true;
int nextBreakable = -1;
int lastWordBoundary = 0;
+ float cachedWordTrailingSpaceWidth[2] = { 0, 0 }; // LTR, RTL
- // Non-zero only when kerning is enabled, in which case we measure words with their trailing
- // space, then subtract its width.
- float wordTrailingSpaceWidth = f.typesettingFeatures() & Kerning ? f.width(RenderBlockFlow::constructTextRun(this, f, &space, 1, styleToUse)) + wordSpacing : 0;
-
- // If automatic hyphenation is allowed, we keep track of the width of the widest word (or word
- // fragment) encountered so far, and only try hyphenating words that are wider.
- float maxWordWidth = numeric_limits<float>::max();
int firstGlyphLeftOverflow = -1;
bool breakAll = (styleToUse->wordBreak() == BreakAllWordBreak || styleToUse->wordBreak() == BreakWordBreak) && styleToUse->autoWrap();
+ TextRun textRun(text());
+ BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
+
+ BidiCharacterRun* run;
+ TextDirection textDirection = styleToUse->direction();
+ if (isOverride(styleToUse->unicodeBidi())) {
+ run = 0;
+ } else {
+ BidiStatus status(LTR, false);
+ status.last = status.lastStrong = WTF::Unicode::OtherNeutral;
+ bidiResolver.setStatus(status);
+ bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&textRun, 0));
+ bool hardLineBreak = false;
+ bool reorderRuns = false;
+ bidiResolver.createBidiRunsForLine(TextRunIterator(&textRun, textRun.length()), NoVisualOverride, hardLineBreak, reorderRuns);
+ BidiRunList<BidiCharacterRun>& bidiRuns = bidiResolver.runs();
+ run = bidiRuns.firstRun();
+ }
+
for (int i = 0; i < len; i++) {
UChar c = uncheckedCharacterAt(i);
- bool previousCharacterIsSpace = isSpace;
+ if (run) {
+ // Treat adjacent runs with the same resolved directionality
+ // (TextDirection as opposed to WTF::Unicode::Direction) as belonging
+ // to the same run to avoid breaking unnecessarily.
+ while (i > run->stop() || (run->next() && run->next()->direction() == run->direction()))
+ run = run->next();
+ ASSERT(run);
+ ASSERT(i <= run->stop());
+ textDirection = run->direction();
+ }
+
+ bool previousCharacterIsSpace = isSpace;
bool isNewline = false;
if (c == '\n') {
if (styleToUse->preserveNewline()) {
@@ -979,7 +990,7 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
lastWordBoundary++;
continue;
} else if (c == softHyphen) {
- currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
+ currMaxWidth += widthFromCache(f, lastWordBoundary, i - lastWordBoundary, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow);
if (firstGlyphLeftOverflow < 0)
firstGlyphLeftOverflow = glyphOverflow.left;
lastWordBoundary = i + 1;
@@ -1002,20 +1013,32 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
}
}
+ // Terminate word boundary at bidi run boundary.
+ if (run)
+ j = min(j, run->stop() + 1);
int wordLen = j - i;
if (wordLen) {
bool isSpace = (j < len) && c == ' ';
+
+ // Non-zero only when kerning is enabled, in which case we measure words with their trailing
+ // space, then subtract its width.
+ float wordTrailingSpaceWidth = 0;
+ if (isSpace && (f.fontDescription().typesettingFeatures() & Kerning)) {
+ ASSERT(textDirection >=0 && textDirection <= 1);
+ if (!cachedWordTrailingSpaceWidth[textDirection])
+ cachedWordTrailingSpaceWidth[textDirection] = f.width(RenderBlockFlow::constructTextRun(this, f, &space, 1, styleToUse, textDirection)) + wordSpacing;
+ wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirection];
+ }
+
float w;
if (wordTrailingSpaceWidth && isSpace)
- w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth;
+ w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth;
else {
- w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
+ w = widthFromCache(f, i, wordLen, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow);
if (c == softHyphen)
- currMinWidth += hyphenWidth(this, f);
+ currMinWidth += hyphenWidth(this, f, textDirection);
}
- maxWordWidth = max(maxWordWidth, w);
-
if (firstGlyphLeftOverflow < 0)
firstGlyphLeftOverflow = glyphOverflow.left;
currMinWidth += w;
@@ -1023,7 +1046,7 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
if (lastWordBoundary == i)
currMaxWidth += w;
else
- currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, &fallbackFonts, &glyphOverflow);
+ currMaxWidth += widthFromCache(f, lastWordBoundary, j - lastWordBoundary, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow);
lastWordBoundary = j;
}
@@ -1074,7 +1097,7 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
m_maxWidth = currMaxWidth;
currMaxWidth = 0;
} else {
- TextRun run = RenderBlockFlow::constructTextRun(this, f, this, i, 1, styleToUse);
+ TextRun run = RenderBlockFlow::constructTextRun(this, f, this, i, 1, styleToUse, textDirection);
run.setCharactersLength(len - i);
ASSERT(run.charactersLength() >= run.length());
run.setTabSize(!style()->collapseWhiteSpace(), style()->tabSize());
@@ -1088,6 +1111,8 @@ void RenderText::computePreferredLogicalWidths(float leadWidth, HashSet<const Si
lastWordBoundary++;
}
}
+ if (run)
+ bidiResolver.runs().deleteRuns();
if (firstGlyphLeftOverflow > 0)
glyphOverflow.left = firstGlyphLeftOverflow;
@@ -1172,16 +1197,12 @@ void RenderText::setSelectionState(SelectionState state)
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
if (box->isSelected(startPos, endPos)) {
- RootInlineBox* root = box->root();
- if (root)
- root->setHasSelectedChildren(true);
+ box->root().setHasSelectedChildren(true);
}
}
} else {
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
- RootInlineBox* root = box->root();
- if (root)
- root->setHasSelectedChildren(state == SelectionInside);
+ box->root().setHasSelectedChildren(state == SelectionInside);
}
}
}
@@ -1217,7 +1238,7 @@ void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset,
// Text run is entirely after the affected range.
if (curr->start() > end) {
curr->offsetRun(delta);
- RootInlineBox* root = curr->root();
+ RootInlineBox* root = &curr->root();
if (!firstRootBox) {
firstRootBox = root;
// The affected area was in between two runs. Go ahead and mark the root box of
@@ -1251,7 +1272,7 @@ void RenderText::setTextWithOffset(PassRefPtr<StringImpl> text, unsigned offset,
firstRootBox = prev;
} else if (lastTextBox()) {
ASSERT(!lastRootBox);
- firstRootBox = lastTextBox()->root();
+ firstRootBox = &lastTextBox()->root();
firstRootBox->markDirty();
dirtiedLines = true;
}
@@ -1385,7 +1406,11 @@ void RenderText::setText(PassRefPtr<StringImpl> text, bool force)
return;
setTextInternal(text);
- setNeedsLayoutAndPrefWidthsRecalc();
+ // If preferredLogicalWidthsDirty() of an orphan child is true, RenderObjectChildList::
+ // insertChildNode() fails to set true to owner. To avoid that, we call
+ // setNeedsLayoutAndPrefWidthsRecalc() only if this RenderText has parent.
+ if (parent())
+ setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation();
m_knownToHaveNoOverflowAndNoFallbackFonts = false;
if (AXObjectCache* cache = document().existingAXObjectCache())
@@ -1405,7 +1430,7 @@ void RenderText::dirtyLineBoxes(bool fullLayout)
InlineTextBox* RenderText::createTextBox()
{
- return new InlineTextBox(this);
+ return new InlineTextBox(*this);
}
InlineTextBox* RenderText::createInlineTextBox()
@@ -1429,7 +1454,7 @@ void RenderText::positionLineBox(InlineBox* box)
// FIXME: should not be needed!!!
if (!s->len()) {
// We want the box to be destroyed.
- s->remove();
+ s->remove(DontMarkLineBoxes);
if (m_firstTextBox == s)
m_firstTextBox = s->nextTextBox();
else
@@ -1445,7 +1470,7 @@ void RenderText::positionLineBox(InlineBox* box)
m_containsReversedText |= !s->isLeftToRightDirection();
}
-float RenderText::width(unsigned from, unsigned len, float xPos, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderText::width(unsigned from, unsigned len, float xPos, TextDirection textDirection, bool firstLine, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
if (from >= textLength())
return 0;
@@ -1453,10 +1478,10 @@ float RenderText::width(unsigned from, unsigned len, float xPos, bool firstLine,
if (from + len > textLength())
len = textLength() - from;
- return width(from, len, style(firstLine)->font(), xPos, fallbackFonts, glyphOverflow);
+ return width(from, len, style(firstLine)->font(), xPos, textDirection, fallbackFonts, glyphOverflow);
}
-float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
+float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos, TextDirection textDirection, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
{
ASSERT(from + len <= textLength());
if (!textLength())
@@ -1473,12 +1498,14 @@ float RenderText::width(unsigned from, unsigned len, const Font& f, float xPos,
m_knownToHaveNoOverflowAndNoFallbackFonts = true;
}
w = m_maxWidth;
- } else
+ } else {
w = maxLogicalWidth();
- } else
- w = widthFromCache(f, from, len, xPos, fallbackFonts, glyphOverflow);
+ }
+ } else {
+ w = widthFromCache(f, from, len, xPos, textDirection, fallbackFonts, glyphOverflow);
+ }
} else {
- TextRun run = RenderBlockFlow::constructTextRun(const_cast<RenderText*>(this), f, this, from, len, style());
+ TextRun run = RenderBlockFlow::constructTextRun(const_cast<RenderText*>(this), f, this, from, len, style(), textDirection);
run.setCharactersLength(textLength() - from);
ASSERT(run.charactersLength() >= run.length());
@@ -1542,7 +1569,7 @@ LayoutRect RenderText::linesVisualOverflowBoundingBox() const
return rect;
}
-LayoutRect RenderText::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+LayoutRect RenderText::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
RenderObject* rendererToRepaint = containingBlock();
@@ -1551,14 +1578,14 @@ LayoutRect RenderText::clippedOverflowRectForRepaint(const RenderLayerModelObjec
if (enclosingLayerRenderer != rendererToRepaint && !rendererToRepaint->isDescendantOf(enclosingLayerRenderer))
rendererToRepaint = enclosingLayerRenderer;
- // The renderer we chose to repaint may be an ancestor of repaintContainer, but we need to do a repaintContainer-relative repaint.
- if (repaintContainer && repaintContainer != rendererToRepaint && !rendererToRepaint->isDescendantOf(repaintContainer))
- return repaintContainer->clippedOverflowRectForRepaint(repaintContainer);
+ // The renderer we chose to repaint may be an ancestor of paintInvalidationContainer, but we need to do a paintInvalidationContainer-relative repaint.
+ if (paintInvalidationContainer && paintInvalidationContainer != rendererToRepaint && !rendererToRepaint->isDescendantOf(paintInvalidationContainer))
+ return paintInvalidationContainer->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer);
- return rendererToRepaint->clippedOverflowRectForRepaint(repaintContainer);
+ return rendererToRepaint->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer);
}
-LayoutRect RenderText::selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent)
+LayoutRect RenderText::selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, bool clipToVisibleContent)
{
ASSERT(!needsLayout());
@@ -1593,12 +1620,12 @@ LayoutRect RenderText::selectionRectForRepaint(const RenderLayerModelObject* rep
}
if (clipToVisibleContent)
- computeRectForRepaint(repaintContainer, rect);
+ mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect);
else {
if (cb->hasColumns())
cb->adjustRectForColumns(rect);
- rect = localToContainerQuad(FloatRect(rect), repaintContainer).enclosingBoundingBox();
+ rect = localToContainerQuad(FloatRect(rect), paintInvalidationContainer).enclosingBoundingBox();
}
return rect;
@@ -1809,7 +1836,7 @@ bool RenderText::computeCanUseSimpleFontCodePath() const
{
if (isAllASCII() || m_text.is8Bit())
return true;
- return Font::characterRangeCodePath(characters16(), length()) == Font::Simple;
+ return Character::characterRangeCodePath(characters16(), length()) == SimplePath;
}
#ifndef NDEBUG
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderText.h b/chromium/third_party/WebKit/Source/core/rendering/RenderText.h
index 13af4be1c6b..1f3de61ca18 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderText.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderText.h
@@ -24,6 +24,8 @@
#define RenderText_h
#include "core/rendering/RenderObject.h"
+#include "platform/LengthFunctions.h"
+#include "platform/text/TextPath.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
@@ -42,7 +44,7 @@ public:
virtual ~RenderText();
#endif
- virtual const char* renderName() const;
+ virtual const char* renderName() const OVERRIDE;
virtual bool isTextFragment() const;
virtual bool isWordBreak() const;
@@ -82,8 +84,8 @@ public:
unsigned textLength() const { return m_text.length(); } // non virtual implementation of length()
void positionLineBox(InlineBox*);
- virtual float width(unsigned from, unsigned len, const Font&, float xPos, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
- virtual float width(unsigned from, unsigned len, float xPos, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+ virtual float width(unsigned from, unsigned len, const Font&, float xPos, TextDirection, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
+ virtual float width(unsigned from, unsigned len, float xPos, TextDirection, bool firstLine = false, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;
float minLogicalWidth() const;
float maxLogicalWidth() const;
@@ -93,7 +95,8 @@ public:
float& lastLineMinWidth, bool& hasBreakableEnd,
bool& hasBreakableChar, bool& hasBreak,
float& firstLineMaxWidth, float& lastLineMaxWidth,
- float& minWidth, float& maxWidth, bool& stripFrontSpaces);
+ float& minWidth, float& maxWidth, bool& stripFrontSpaces,
+ TextDirection);
virtual IntRect linesBoundingBox() const;
LayoutRect linesVisualOverflowBoundingBox() const;
@@ -107,21 +110,21 @@ public:
virtual void transformText();
- virtual bool canBeSelectionLeaf() const { return true; }
+ virtual bool canBeSelectionLeaf() const OVERRIDE { return true; }
virtual void setSelectionState(SelectionState s) OVERRIDE FINAL;
- virtual LayoutRect selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent = true) OVERRIDE;
- virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0);
+ virtual LayoutRect selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, bool clipToVisibleContent = true) OVERRIDE;
+ virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) OVERRIDE;
- LayoutUnit marginLeft() const { return minimumValueForLength(style()->marginLeft(), 0, view()); }
- LayoutUnit marginRight() const { return minimumValueForLength(style()->marginRight(), 0, view()); }
+ LayoutUnit marginLeft() const { return minimumValueForLength(style()->marginLeft(), 0); }
+ LayoutUnit marginRight() const { return minimumValueForLength(style()->marginRight(), 0); }
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE FINAL;
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE FINAL;
InlineTextBox* firstTextBox() const { return m_firstTextBox; }
InlineTextBox* lastTextBox() const { return m_lastTextBox; }
- virtual int caretMinOffset() const;
- virtual int caretMaxOffset() const;
+ virtual int caretMinOffset() const OVERRIDE;
+ virtual int caretMaxOffset() const OVERRIDE;
unsigned renderedTextLength() const;
virtual int previousOffset(int current) const OVERRIDE FINAL;
@@ -133,8 +136,6 @@ public:
bool isSecure() const { return style()->textSecurity() != TSNONE; }
void momentarilyRevealLastTypedCharacter(unsigned lastTypedCharacterOffset);
- InlineTextBox* findNextInlineTextBox(int offset, int& pos) const;
-
void checkConsistency() const;
bool isAllCollapsibleWhitespace() const;
@@ -148,10 +149,10 @@ public:
protected:
virtual void computePreferredLogicalWidths(float leadWidth);
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
- virtual void styleWillChange(StyleDifference, const RenderStyle*) OVERRIDE FINAL { }
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleWillChange(StyleDifference, const RenderStyle&) OVERRIDE FINAL { }
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
virtual void setTextInternal(PassRefPtr<StringImpl>);
virtual UChar previousCharacter() const;
@@ -176,7 +177,7 @@ private:
void deleteTextBoxes();
bool containsOnlyWhitespace(unsigned from, unsigned len) const;
- float widthFromCache(const Font&, int start, int len, float xPos, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const;
+ float widthFromCache(const Font&, int start, int len, float xPos, TextDirection, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow*) const;
bool isAllASCII() const { return m_isAllASCII; }
void secureText(UChar mask);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.cpp
index d420fbff074..81369e99415 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.cpp
@@ -47,9 +47,9 @@ HTMLTextFormControlElement* RenderTextControl::textFormControlElement() const
return toHTMLTextFormControlElement(node());
}
-HTMLElement* RenderTextControl::innerTextElement() const
+HTMLElement* RenderTextControl::innerEditorElement() const
{
- return textFormControlElement()->innerTextElement();
+ return textFormControlElement()->innerEditorElement();
}
void RenderTextControl::addChild(RenderObject* newChild, RenderObject* beforeChild)
@@ -57,26 +57,26 @@ void RenderTextControl::addChild(RenderObject* newChild, RenderObject* beforeChi
// FIXME: This is a terrible hack to get the caret over the placeholder text since it'll
// make us paint the placeholder first. (See https://trac.webkit.org/changeset/118733)
Node* node = newChild->node();
- if (node && node->isElementNode() && toElement(node)->pseudo() == "-webkit-input-placeholder")
- RenderBlock::addChild(newChild, firstChild());
+ if (node && node->isElementNode() && toElement(node)->shadowPseudoId() == "-webkit-input-placeholder")
+ RenderBlockFlow::addChild(newChild, firstChild());
else
- RenderBlock::addChild(newChild, beforeChild);
+ RenderBlockFlow::addChild(newChild, beforeChild);
}
void RenderTextControl::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- RenderBlock::styleDidChange(diff, oldStyle);
- Element* innerText = innerTextElement();
- if (!innerText)
+ RenderBlockFlow::styleDidChange(diff, oldStyle);
+ Element* innerEditor = innerEditorElement();
+ if (!innerEditor)
return;
- RenderBlock* innerTextRenderer = toRenderBlock(innerText->renderer());
- if (innerTextRenderer) {
+ RenderBlock* innerEditorRenderer = toRenderBlock(innerEditor->renderer());
+ if (innerEditorRenderer) {
// We may have set the width and the height in the old style in layout().
// Reset them now to avoid getting a spurious layout hint.
- innerTextRenderer->style()->setHeight(Length());
- innerTextRenderer->style()->setWidth(Length());
- innerTextRenderer->setStyle(createInnerTextStyle(style()));
- innerText->setNeedsStyleRecalc();
+ innerEditorRenderer->style()->setHeight(Length());
+ innerEditorRenderer->style()->setWidth(Length());
+ innerEditorRenderer->setStyle(createInnerEditorStyle(style()));
+ innerEditor->setNeedsStyleRecalc(SubtreeStyleChange);
}
textFormControlElement()->updatePlaceholderVisibility(false);
}
@@ -86,7 +86,7 @@ static inline void updateUserModifyProperty(HTMLTextFormControlElement* node, Re
style->setUserModify(node->isDisabledOrReadOnly() ? READ_ONLY : READ_WRITE_PLAINTEXT_ONLY);
}
-void RenderTextControl::adjustInnerTextStyle(RenderStyle* textBlockStyle) const
+void RenderTextControl::adjustInnerEditorStyle(RenderStyle* textBlockStyle) const
{
// The inner block, if present, always has its direction set to LTR,
// so we need to inherit the direction and unicode-bidi style from the element.
@@ -103,21 +103,21 @@ int RenderTextControl::textBlockLogicalHeight() const
int RenderTextControl::textBlockLogicalWidth() const
{
- Element* innerText = innerTextElement();
- ASSERT(innerText);
+ Element* innerEditor = innerEditorElement();
+ ASSERT(innerEditor);
LayoutUnit unitWidth = logicalWidth() - borderAndPaddingLogicalWidth();
- if (innerText->renderer())
- unitWidth -= innerText->renderBox()->paddingStart() + innerText->renderBox()->paddingEnd();
+ if (innerEditor->renderer())
+ unitWidth -= innerEditor->renderBox()->paddingStart() + innerEditor->renderBox()->paddingEnd();
return unitWidth;
}
void RenderTextControl::updateFromElement()
{
- Element* innerText = innerTextElement();
- if (innerText && innerText->renderer())
- updateUserModifyProperty(textFormControlElement(), innerText->renderer()->style());
+ Element* innerEditor = innerEditorElement();
+ if (innerEditor && innerEditor->renderer())
+ updateUserModifyProperty(textFormControlElement(), innerEditor->renderer()->style());
}
int RenderTextControl::scrollbarThickness() const
@@ -128,33 +128,39 @@ int RenderTextControl::scrollbarThickness() const
void RenderTextControl::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const
{
- HTMLElement* innerText = innerTextElement();
- ASSERT(innerText);
- if (RenderBox* innerTextBox = innerText->renderBox()) {
- LayoutUnit nonContentHeight = innerTextBox->borderAndPaddingHeight() + innerTextBox->marginHeight();
- logicalHeight = computeControlLogicalHeight(innerTextBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight) + borderAndPaddingHeight();
+ HTMLElement* innerEditor = innerEditorElement();
+ ASSERT(innerEditor);
+ if (RenderBox* innerEditorBox = innerEditor->renderBox()) {
+ LayoutUnit nonContentHeight = innerEditorBox->borderAndPaddingHeight() + innerEditorBox->marginHeight();
+ logicalHeight = computeControlLogicalHeight(innerEditorBox->lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes), nonContentHeight);
// We are able to have a horizontal scrollbar if the overflow style is scroll, or if its auto and there's no word wrap.
- if ((isHorizontalWritingMode() && (style()->overflowX() == OSCROLL || (style()->overflowX() == OAUTO && innerText->renderer()->style()->overflowWrap() == NormalOverflowWrap)))
- || (!isHorizontalWritingMode() && (style()->overflowY() == OSCROLL || (style()->overflowY() == OAUTO && innerText->renderer()->style()->overflowWrap() == NormalOverflowWrap))))
+ if ((isHorizontalWritingMode() && (style()->overflowX() == OSCROLL || (style()->overflowX() == OAUTO && innerEditor->renderer()->style()->overflowWrap() == NormalOverflowWrap)))
+ || (!isHorizontalWritingMode() && (style()->overflowY() == OSCROLL || (style()->overflowY() == OAUTO && innerEditor->renderer()->style()->overflowWrap() == NormalOverflowWrap))))
logicalHeight += scrollbarThickness();
+
+ // FIXME: The logical height of the inner text box should have been added before calling computeLogicalHeight to
+ // avoid this hack.
+ updateIntrinsicContentLogicalHeight(logicalHeight);
+
+ logicalHeight += borderAndPaddingHeight();
}
RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues);
}
-void RenderTextControl::hitInnerTextElement(HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset)
+void RenderTextControl::hitInnerEditorElement(HitTestResult& result, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset)
{
- HTMLElement* innerText = innerTextElement();
- if (!innerText->renderer())
+ HTMLElement* innerEditor = innerEditorElement();
+ if (!innerEditor->renderer())
return;
LayoutPoint adjustedLocation = accumulatedOffset + location();
- LayoutPoint localPoint = pointInContainer - toLayoutSize(adjustedLocation + innerText->renderBox()->location());
+ LayoutPoint localPoint = pointInContainer - toLayoutSize(adjustedLocation + innerEditor->renderBox()->location());
if (hasOverflowClip())
localPoint += scrolledContentOffset();
- result.setInnerNode(innerText);
- result.setInnerNonSharedNode(innerText);
+ result.setInnerNode(innerEditor);
+ result.setInnerNonSharedNode(innerEditor);
result.setLocalPoint(localPoint);
}
@@ -234,16 +240,16 @@ float RenderTextControl::scaleEmToUnits(int x) const
{
// This matches the unitsPerEm value for MS Shell Dlg and Courier New from the "head" font table.
float unitsPerEm = 2048.0f;
- return roundf(style()->font().size() * x / unitsPerEm);
+ return roundf(style()->font().fontDescription().computedSize() * x / unitsPerEm);
}
void RenderTextControl::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
// Use average character width. Matches IE.
- AtomicString family = style()->font().family().family();
+ AtomicString family = style()->font().fontDescription().family().family();
maxLogicalWidth = preferredContentLogicalWidth(const_cast<RenderTextControl*>(this)->getAvgCharWidth(family));
- if (RenderBox* innerTextRenderBox = innerTextElement()->renderBox())
- maxLogicalWidth += innerTextRenderBox->paddingStart() + innerTextRenderBox->paddingEnd();
+ if (RenderBox* innerEditorRenderBox = innerEditorElement()->renderBox())
+ maxLogicalWidth += innerEditorRenderBox->paddingStart() + innerEditorRenderBox->paddingEnd();
if (!style()->logicalWidth().isPercent())
minLogicalWidth = maxLogicalWidth;
}
@@ -254,20 +260,21 @@ void RenderTextControl::computePreferredLogicalWidths()
m_minPreferredLogicalWidth = 0;
m_maxPreferredLogicalWidth = 0;
+ RenderStyle* styleToUse = style();
- if (style()->logicalWidth().isFixed() && style()->logicalWidth().value() >= 0)
- m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(style()->logicalWidth().value());
+ if (styleToUse->logicalWidth().isFixed() && styleToUse->logicalWidth().value() >= 0)
+ m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalWidth().value());
else
computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
- if (style()->logicalMinWidth().isFixed() && style()->logicalMinWidth().value() > 0) {
- m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->logicalMinWidth().value()));
- m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->logicalMinWidth().value()));
+ if (styleToUse->logicalMinWidth().isFixed() && styleToUse->logicalMinWidth().value() > 0) {
+ m_maxPreferredLogicalWidth = max(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
+ m_minPreferredLogicalWidth = max(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMinWidth().value()));
}
- if (style()->logicalMaxWidth().isFixed()) {
- m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->logicalMaxWidth().value()));
- m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(style()->logicalMaxWidth().value()));
+ if (styleToUse->logicalMaxWidth().isFixed()) {
+ m_maxPreferredLogicalWidth = min(m_maxPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
+ m_minPreferredLogicalWidth = min(m_minPreferredLogicalWidth, adjustContentBoxLogicalWidthForBoxSizing(styleToUse->logicalMaxWidth().value()));
}
LayoutUnit toAdd = borderAndPaddingLogicalWidth();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.h
index 6269af8d7e0..5a0434563aa 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControl.h
@@ -34,20 +34,21 @@ public:
virtual ~RenderTextControl();
HTMLTextFormControlElement* textFormControlElement() const;
- virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const = 0;
+ virtual PassRefPtr<RenderStyle> createInnerEditorStyle(const RenderStyle* startStyle) const = 0;
protected:
RenderTextControl(HTMLTextFormControlElement*);
- // This convenience function should not be made public because innerTextElement may outlive the render tree.
- HTMLElement* innerTextElement() const;
+ // This convenience function should not be made public because
+ // innerEditorElement may outlive the render tree.
+ HTMLElement* innerEditorElement() const;
int scrollbarThickness() const;
- void adjustInnerTextStyle(RenderStyle* textBlockStyle) const;
+ void adjustInnerEditorStyle(RenderStyle* textBlockStyle) const;
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
- void hitInnerTextElement(HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset);
+ void hitInnerEditorElement(HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset);
int textBlockLogicalWidth() const;
int textBlockLogicalHeight() const;
@@ -59,9 +60,9 @@ protected:
virtual LayoutUnit preferredContentLogicalWidth(float charWidth) const = 0;
virtual LayoutUnit computeControlLogicalHeight(LayoutUnit lineHeight, LayoutUnit nonContentHeight) const = 0;
- virtual void updateFromElement();
+ virtual void updateFromElement() OVERRIDE;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
- virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&);
+ virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&) OVERRIDE;
// We need to override this function because we don't want overflow:hidden on an <input>
// to affect the baseline calculation. This is necessary because we are an inline-block
@@ -69,20 +70,19 @@ protected:
virtual int inlineBlockBaseline(LineDirectionMode direction) const OVERRIDE { return lastLineBoxBaseline(direction); }
private:
- virtual const char* renderName() const { return "RenderTextControl"; }
- virtual bool isTextControl() const { return true; }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
- virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
- virtual void computePreferredLogicalWidths() OVERRIDE;
- virtual void removeLeftoverAnonymousBlock(RenderBlock*) { }
- virtual bool avoidsFloats() const { return true; }
- virtual bool canHaveGeneratedChildren() const OVERRIDE { return false; }
+ virtual const char* renderName() const OVERRIDE { return "RenderTextControl"; }
+ virtual bool isTextControl() const OVERRIDE FINAL { return true; }
+ virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE FINAL;
+ virtual void computePreferredLogicalWidths() OVERRIDE FINAL;
+ virtual void removeLeftoverAnonymousBlock(RenderBlock*) OVERRIDE FINAL { }
+ virtual bool avoidsFloats() const OVERRIDE FINAL { return true; }
+ virtual bool canHaveGeneratedChildren() const OVERRIDE FINAL { return false; }
virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE FINAL;
- virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
+ virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE FINAL;
- virtual bool canBeProgramaticallyScrolled() const { return true; }
+ virtual bool canBeProgramaticallyScrolled() const OVERRIDE FINAL { return true; }
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderTextControl, isTextControl());
@@ -104,7 +104,6 @@ public:
}
virtual int firstLineBoxBaseline() const OVERRIDE { return RenderBlock::firstLineBoxBaseline(); }
virtual int inlineBlockBaseline(LineDirectionMode direction) const OVERRIDE { return lastLineBoxBaseline(direction); }
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.cpp
index 01fa15a7d4d..eef715fa748 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.cpp
@@ -35,8 +35,6 @@ RenderTextControlMultiLine::RenderTextControlMultiLine(HTMLTextAreaElement* elem
RenderTextControlMultiLine::~RenderTextControlMultiLine()
{
- if (node() && node()->inDocument())
- toHTMLTextAreaElement(node())->rendererWillBeDestroyed();
}
bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
@@ -44,8 +42,8 @@ bool RenderTextControlMultiLine::nodeAtPoint(const HitTestRequest& request, HitT
if (!RenderTextControl::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction))
return false;
- if (result.innerNode() == node() || result.innerNode() == innerTextElement())
- hitInnerTextElement(result, locationInContainer.point(), accumulatedOffset);
+ if (result.innerNode() == node() || result.innerNode() == innerEditorElement())
+ hitInnerEditorElement(result, locationInContainer.point(), accumulatedOffset);
return true;
}
@@ -77,11 +75,11 @@ int RenderTextControlMultiLine::baselinePosition(FontBaseline baselineType, bool
return RenderBox::baselinePosition(baselineType, firstLine, direction, linePositionMode);
}
-PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const
+PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerEditorStyle(const RenderStyle* startStyle) const
{
RefPtr<RenderStyle> textBlockStyle = RenderStyle::create();
textBlockStyle->inheritFrom(startStyle);
- adjustInnerTextStyle(textBlockStyle.get());
+ adjustInnerEditorStyle(textBlockStyle.get());
textBlockStyle->setDisplay(BLOCK);
textBlockStyle->setUnique();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.h
index 3371c2602b0..73132f5372d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlMultiLine.h
@@ -34,19 +34,19 @@ public:
virtual ~RenderTextControlMultiLine();
private:
- virtual bool isTextArea() const { return true; }
+ virtual bool isTextArea() const OVERRIDE { return true; }
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
- virtual float getAvgCharWidth(AtomicString family);
- virtual LayoutUnit preferredContentLogicalWidth(float charWidth) const;
+ virtual float getAvgCharWidth(AtomicString family) OVERRIDE;
+ virtual LayoutUnit preferredContentLogicalWidth(float charWidth) const OVERRIDE;
virtual LayoutUnit computeControlLogicalHeight(LayoutUnit lineHeight, LayoutUnit nonContentHeight) const OVERRIDE;
// We override the two baseline functions because we want our baseline to be the bottom of our margin box.
virtual int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const OVERRIDE;
virtual int inlineBlockBaseline(LineDirectionMode) const OVERRIDE { return -1; }
- virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const;
- virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&);
+ virtual PassRefPtr<RenderStyle> createInnerEditorStyle(const RenderStyle* startStyle) const OVERRIDE;
+ virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&) OVERRIDE;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderTextControlMultiLine, isTextArea());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.cpp
index 04ecfea2fc8..b896d6c9c0b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.cpp
@@ -24,13 +24,12 @@
#include "config.h"
#include "core/rendering/RenderTextControlSingleLine.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "core/dom/shadow/ShadowRoot.h"
#include "core/editing/FrameSelection.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/shadow/ShadowElementNames.h"
-#include "core/frame/Frame.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderTheme.h"
#include "platform/PlatformKeyboardEvent.h"
@@ -45,9 +44,8 @@ using namespace HTMLNames;
RenderTextControlSingleLine::RenderTextControlSingleLine(HTMLInputElement* element)
: RenderTextControl(element)
, m_shouldDrawCapsLockIndicator(false)
- , m_desiredInnerTextLogicalHeight(-1)
+ , m_desiredInnerEditorLogicalHeight(-1)
{
- ASSERT(element->hasTagName(inputTag));
}
RenderTextControlSingleLine::~RenderTextControlSingleLine()
@@ -95,8 +93,7 @@ LayoutUnit RenderTextControlSingleLine::computeLogicalHeightLimit() const
void RenderTextControlSingleLine::layout()
{
- LayoutRectRecorder recorder(*this);
- SubtreeLayoutScope layoutScope(this);
+ SubtreeLayoutScope layoutScope(*this);
// FIXME: We should remove the height-related hacks in layout() and
// styleDidChange(). We need them because
@@ -109,13 +106,16 @@ void RenderTextControlSingleLine::layout()
// and type=search if the text height is taller than the contentHeight()
// because of compability.
- RenderBox* innerTextRenderer = innerTextElement()->renderBox();
+ RenderBox* innerEditorRenderer = innerEditorElement()->renderBox();
RenderBox* viewPortRenderer = editingViewPortElement() ? editingViewPortElement()->renderBox() : 0;
// To ensure consistency between layouts, we need to reset any conditionally overriden height.
- if (innerTextRenderer && !innerTextRenderer->style()->logicalHeight().isAuto()) {
- innerTextRenderer->style()->setLogicalHeight(Length(Auto));
- layoutScope.setNeedsLayout(innerTextRenderer);
+ if (innerEditorRenderer && !innerEditorRenderer->style()->logicalHeight().isAuto()) {
+ innerEditorRenderer->style()->setLogicalHeight(Length(Auto));
+ layoutScope.setNeedsLayout(innerEditorRenderer);
+ HTMLElement* placeholderElement = inputElement()->placeholderElement();
+ if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0)
+ layoutScope.setNeedsLayout(placeholderBox);
}
if (viewPortRenderer && !viewPortRenderer->style()->logicalHeight().isAuto()) {
viewPortRenderer->style()->setLogicalHeight(Length(Auto));
@@ -130,14 +130,14 @@ void RenderTextControlSingleLine::layout()
// Set the text block height
LayoutUnit desiredLogicalHeight = textBlockLogicalHeight();
LayoutUnit logicalHeightLimit = computeLogicalHeightLimit();
- if (innerTextRenderer && innerTextRenderer->logicalHeight() > logicalHeightLimit) {
- if (desiredLogicalHeight != innerTextRenderer->logicalHeight())
+ if (innerEditorRenderer && innerEditorRenderer->logicalHeight() > logicalHeightLimit) {
+ if (desiredLogicalHeight != innerEditorRenderer->logicalHeight())
layoutScope.setNeedsLayout(this);
- m_desiredInnerTextLogicalHeight = desiredLogicalHeight;
+ m_desiredInnerEditorLogicalHeight = desiredLogicalHeight;
- innerTextRenderer->style()->setLogicalHeight(Length(desiredLogicalHeight, Fixed));
- layoutScope.setNeedsLayout(innerTextRenderer);
+ innerEditorRenderer->style()->setLogicalHeight(Length(desiredLogicalHeight, Fixed));
+ layoutScope.setNeedsLayout(innerEditorRenderer);
if (viewPortRenderer) {
viewPortRenderer->style()->setLogicalHeight(Length(desiredLogicalHeight, Fixed));
layoutScope.setNeedsLayout(viewPortRenderer);
@@ -162,45 +162,36 @@ void RenderTextControlSingleLine::layout()
RenderBlockFlow::layoutBlock(true);
// Center the child block in the block progression direction (vertical centering for horizontal text fields).
- if (!container && innerTextRenderer && innerTextRenderer->height() != contentLogicalHeight()) {
- LayoutUnit logicalHeightDiff = innerTextRenderer->logicalHeight() - contentLogicalHeight();
- innerTextRenderer->setLogicalTop(innerTextRenderer->logicalTop() - (logicalHeightDiff / 2 + layoutMod(logicalHeightDiff, 2)));
+ if (!container && innerEditorRenderer && innerEditorRenderer->height() != contentLogicalHeight()) {
+ LayoutUnit logicalHeightDiff = innerEditorRenderer->logicalHeight() - contentLogicalHeight();
+ innerEditorRenderer->setLogicalTop(innerEditorRenderer->logicalTop() - (logicalHeightDiff / 2 + layoutMod(logicalHeightDiff, 2)));
} else
centerContainerIfNeeded(containerRenderer);
- // Ignores the paddings for the inner spin button.
- if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) {
- RenderBox* parentBox = innerSpinBox->parentBox();
- if (containerRenderer && !containerRenderer->style()->isLeftToRightDirection())
- innerSpinBox->setLogicalLocation(LayoutPoint(-paddingLogicalLeft(), -paddingBefore()));
- else
- innerSpinBox->setLogicalLocation(LayoutPoint(parentBox->logicalWidth() - innerSpinBox->logicalWidth() + paddingLogicalRight(), -paddingBefore()));
- innerSpinBox->setLogicalHeight(logicalHeight() - borderBefore() - borderAfter());
- }
-
HTMLElement* placeholderElement = inputElement()->placeholderElement();
if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) {
- LayoutSize innerTextSize;
- if (innerTextRenderer)
- innerTextSize = innerTextRenderer->size();
- placeholderBox->style()->setWidth(Length(innerTextSize.width() - placeholderBox->borderAndPaddingWidth(), Fixed));
- placeholderBox->style()->setHeight(Length(innerTextSize.height() - placeholderBox->borderAndPaddingHeight(), Fixed));
+ LayoutSize innerEditorSize;
+
+ if (innerEditorRenderer)
+ innerEditorSize = innerEditorRenderer->size();
+ placeholderBox->style()->setWidth(Length(innerEditorSize.width() - placeholderBox->borderAndPaddingWidth(), Fixed));
+ placeholderBox->style()->setHeight(Length(innerEditorSize.height() - placeholderBox->borderAndPaddingHeight(), Fixed));
bool neededLayout = placeholderBox->needsLayout();
bool placeholderBoxHadLayout = placeholderBox->everHadLayout();
placeholderBox->layoutIfNeeded();
LayoutPoint textOffset;
- if (innerTextRenderer)
- textOffset = innerTextRenderer->location();
+ if (innerEditorRenderer)
+ textOffset = innerEditorRenderer->location();
if (editingViewPortElement() && editingViewPortElement()->renderBox())
textOffset += toLayoutSize(editingViewPortElement()->renderBox()->location());
if (containerRenderer)
textOffset += toLayoutSize(containerRenderer->location());
placeholderBox->setLocation(textOffset);
- if (!placeholderBoxHadLayout && placeholderBox->checkForRepaintDuringLayout()) {
+ if (!placeholderBoxHadLayout && placeholderBox->checkForPaintInvalidationDuringLayout()) {
// This assumes a shadow tree without floats. If floats are added, the
- // logic should be shared with RenderBlock::layoutBlockChild.
- placeholderBox->repaint();
+ // logic should be shared with RenderBlockFlow::layoutBlockChild.
+ placeholderBox->paintInvalidationForWholeRenderer();
}
// The placeholder gets layout last, after the parent text control and its other children,
// so in order to get the correct overflow from the placeholder we need to recompute it now.
@@ -219,7 +210,7 @@ bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, Hit
// - we hit the <input> element (e.g. we're over the border or padding), or
// - we hit regions not in any decoration buttons.
Element* container = containerElement();
- if (result.innerNode()->isDescendantOf(innerTextElement()) || result.innerNode() == node() || (container && container == result.innerNode())) {
+ if (result.innerNode()->isDescendantOf(innerEditorElement()) || result.innerNode() == node() || (container && container == result.innerNode())) {
LayoutPoint pointInParent = locationInContainer.point();
if (container && editingViewPortElement()) {
if (editingViewPortElement()->renderBox())
@@ -227,14 +218,14 @@ bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, Hit
if (container->renderBox())
pointInParent -= toLayoutSize(container->renderBox()->location());
}
- hitInnerTextElement(result, pointInParent, accumulatedOffset);
+ hitInnerEditorElement(result, pointInParent, accumulatedOffset);
}
return true;
}
void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- m_desiredInnerTextLogicalHeight = -1;
+ m_desiredInnerEditorLogicalHeight = -1;
RenderTextControl::styleDidChange(diff, oldStyle);
// We may have set the width and the height in the old style in layout().
@@ -249,9 +240,9 @@ void RenderTextControlSingleLine::styleDidChange(StyleDifference diff, const Ren
containerRenderer->style()->setHeight(Length());
containerRenderer->style()->setWidth(Length());
}
- RenderObject* innerTextRenderer = innerTextElement()->renderer();
- if (innerTextRenderer && diff == StyleDifferenceLayout)
- innerTextRenderer->setNeedsLayout();
+ RenderObject* innerEditorRenderer = innerEditorElement()->renderer();
+ if (innerEditorRenderer && diff.needsFullLayout())
+ innerEditorRenderer->setNeedsLayoutAndFullPaintInvalidation();
if (HTMLElement* placeholder = inputElement()->placeholderElement())
placeholder->setInlineStyleProperty(CSSPropertyTextOverflow, textShouldBeTruncated() ? CSSValueEllipsis : CSSValueClip);
setHasOverflowClip(false);
@@ -269,12 +260,12 @@ void RenderTextControlSingleLine::capsLockStateMayHaveChanged()
// 4) The caps lock is on
bool shouldDrawCapsLockIndicator = false;
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
shouldDrawCapsLockIndicator = inputElement()->isPasswordField() && frame->selection().isFocusedAndActive() && document().focusedElement() == node() && PlatformKeyboardEvent::currentCapsLockState();
if (shouldDrawCapsLockIndicator != m_shouldDrawCapsLockIndicator) {
m_shouldDrawCapsLockIndicator = shouldDrawCapsLockIndicator;
- repaint();
+ paintInvalidationForWholeRenderer();
}
}
@@ -316,7 +307,7 @@ LayoutUnit RenderTextControlSingleLine::preferredContentLogicalWidth(float charW
LayoutUnit result = LayoutUnit::fromFloatCeil(charWidth * factor);
float maxCharWidth = 0.f;
- AtomicString family = style()->font().family().family();
+ AtomicString family = style()->font().fontDescription().family().family();
// Since Lucida Grande is the default font, we want this to match the width
// of MS Shell Dlg, the default font for textareas in Firefox, Safari Win and
// IE for some encodings (in IE, the default font is encoding specific).
@@ -348,16 +339,11 @@ LayoutUnit RenderTextControlSingleLine::computeControlLogicalHeight(LayoutUnit l
return lineHeight + nonContentHeight;
}
-void RenderTextControlSingleLine::updateFromElement()
-{
- RenderTextControl::updateFromElement();
-}
-
-PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const RenderStyle* startStyle) const
+PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerEditorStyle(const RenderStyle* startStyle) const
{
RefPtr<RenderStyle> textBlockStyle = RenderStyle::create();
textBlockStyle->inheritFrom(startStyle);
- adjustInnerTextStyle(textBlockStyle.get());
+ adjustInnerEditorStyle(textBlockStyle.get());
textBlockStyle->setWhiteSpace(PRE);
textBlockStyle->setOverflowWrap(NormalOverflowWrap);
@@ -365,8 +351,8 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const
textBlockStyle->setOverflowY(OHIDDEN);
textBlockStyle->setTextOverflow(textShouldBeTruncated() ? TextOverflowEllipsis : TextOverflowClip);
- if (m_desiredInnerTextLogicalHeight >= 0)
- textBlockStyle->setLogicalHeight(Length(m_desiredInnerTextLogicalHeight, Fixed));
+ if (m_desiredInnerEditorLogicalHeight >= 0)
+ textBlockStyle->setLogicalHeight(Length(m_desiredInnerEditorLogicalHeight, Fixed));
// Do not allow line-height to be smaller than our default.
if (textBlockStyle->fontMetrics().lineSpacing() > lineHeight(true, HorizontalLine, PositionOfInteriorLineBoxes))
textBlockStyle->setLineHeight(RenderStyle::initialLineHeight());
@@ -374,6 +360,9 @@ PassRefPtr<RenderStyle> RenderTextControlSingleLine::createInnerTextStyle(const
textBlockStyle->setDisplay(BLOCK);
textBlockStyle->setUnique();
+ if (inputElement()->shouldRevealPassword())
+ textBlockStyle->setTextSecurity(TSNONE);
+
return textBlockStyle.release();
}
@@ -384,51 +373,51 @@ bool RenderTextControlSingleLine::textShouldBeTruncated() const
void RenderTextControlSingleLine::autoscroll(const IntPoint& position)
{
- RenderBox* renderer = innerTextElement()->renderBox();
+ RenderBox* renderer = innerEditorElement()->renderBox();
if (!renderer)
return;
renderer->autoscroll(position);
}
-int RenderTextControlSingleLine::scrollWidth() const
+LayoutUnit RenderTextControlSingleLine::scrollWidth() const
{
- if (innerTextElement())
- return innerTextElement()->scrollWidth();
- return RenderBlock::scrollWidth();
+ if (innerEditorElement())
+ return innerEditorElement()->scrollWidth();
+ return RenderBlockFlow::scrollWidth();
}
-int RenderTextControlSingleLine::scrollHeight() const
+LayoutUnit RenderTextControlSingleLine::scrollHeight() const
{
- if (innerTextElement())
- return innerTextElement()->scrollHeight();
- return RenderBlock::scrollHeight();
+ if (innerEditorElement())
+ return innerEditorElement()->scrollHeight();
+ return RenderBlockFlow::scrollHeight();
}
-int RenderTextControlSingleLine::scrollLeft() const
+LayoutUnit RenderTextControlSingleLine::scrollLeft() const
{
- if (innerTextElement())
- return innerTextElement()->scrollLeft();
- return RenderBlock::scrollLeft();
+ if (innerEditorElement())
+ return innerEditorElement()->scrollLeft();
+ return RenderBlockFlow::scrollLeft();
}
-int RenderTextControlSingleLine::scrollTop() const
+LayoutUnit RenderTextControlSingleLine::scrollTop() const
{
- if (innerTextElement())
- return innerTextElement()->scrollTop();
- return RenderBlock::scrollTop();
+ if (innerEditorElement())
+ return innerEditorElement()->scrollTop();
+ return RenderBlockFlow::scrollTop();
}
-void RenderTextControlSingleLine::setScrollLeft(int newLeft)
+void RenderTextControlSingleLine::setScrollLeft(LayoutUnit newLeft)
{
- if (innerTextElement())
- innerTextElement()->setScrollLeft(newLeft);
+ if (innerEditorElement())
+ innerEditorElement()->setScrollLeft(newLeft);
}
-void RenderTextControlSingleLine::setScrollTop(int newTop)
+void RenderTextControlSingleLine::setScrollTop(LayoutUnit newTop)
{
- if (innerTextElement())
- innerTextElement()->setScrollTop(newTop);
+ if (innerEditorElement())
+ innerEditorElement()->setScrollTop(newTop);
}
HTMLInputElement* RenderTextControlSingleLine::inputElement() const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.h
index 64a07cc74fc..60715c0deb9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTextControlSingleLine.h
@@ -34,8 +34,8 @@ class RenderTextControlSingleLine : public RenderTextControl {
public:
RenderTextControlSingleLine(HTMLInputElement*);
virtual ~RenderTextControlSingleLine();
- // FIXME: Move createInnerTextStyle() to TextControlInnerTextElement.
- virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const;
+ // FIXME: Move createInnerEditorStyle() to TextControlInnerEditorElement.
+ virtual PassRefPtr<RenderStyle> createInnerEditorStyle(const RenderStyle* startStyle) const OVERRIDE FINAL;
void capsLockStateMayHaveChanged();
@@ -45,41 +45,40 @@ protected:
Element* containerElement() const;
Element* editingViewPortElement() const;
HTMLInputElement* inputElement() const;
- virtual void updateFromElement() OVERRIDE;
private:
- virtual bool hasControlClip() const;
- virtual LayoutRect controlClipRect(const LayoutPoint&) const;
- virtual bool isTextField() const { return true; }
+ virtual bool hasControlClip() const OVERRIDE FINAL;
+ virtual LayoutRect controlClipRect(const LayoutPoint&) const OVERRIDE FINAL;
+ virtual bool isTextField() const OVERRIDE FINAL { return true; }
- virtual void paint(PaintInfo&, const LayoutPoint&);
- virtual void layout();
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual void layout() OVERRIDE;
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE FINAL;
- virtual void autoscroll(const IntPoint&);
+ virtual void autoscroll(const IntPoint&) OVERRIDE FINAL;
// Subclassed to forward to our inner div.
- virtual int scrollLeft() const;
- virtual int scrollTop() const;
- virtual int scrollWidth() const;
- virtual int scrollHeight() const;
- virtual void setScrollLeft(int);
- virtual void setScrollTop(int);
+ virtual LayoutUnit scrollLeft() const OVERRIDE FINAL;
+ virtual LayoutUnit scrollTop() const OVERRIDE FINAL;
+ virtual LayoutUnit scrollWidth() const OVERRIDE FINAL;
+ virtual LayoutUnit scrollHeight() const OVERRIDE FINAL;
+ virtual void setScrollLeft(LayoutUnit) OVERRIDE FINAL;
+ virtual void setScrollTop(LayoutUnit) OVERRIDE FINAL;
int textBlockWidth() const;
- virtual float getAvgCharWidth(AtomicString family);
- virtual LayoutUnit preferredContentLogicalWidth(float charWidth) const;
+ virtual float getAvgCharWidth(AtomicString family) OVERRIDE FINAL;
+ virtual LayoutUnit preferredContentLogicalWidth(float charWidth) const OVERRIDE FINAL;
virtual LayoutUnit computeControlLogicalHeight(LayoutUnit lineHeight, LayoutUnit nonContentHeight) const OVERRIDE;
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE FINAL;
bool textShouldBeTruncated() const;
HTMLElement* innerSpinButtonElement() const;
bool m_shouldDrawCapsLockIndicator;
- LayoutUnit m_desiredInnerTextLogicalHeight;
+ LayoutUnit m_desiredInnerEditorLogicalHeight;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderTextControlSingleLine, isTextField());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.cpp
index 759eb9dd368..f2eb3ff2262 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.cpp
@@ -30,7 +30,7 @@
namespace WebCore {
RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str, int startOffset, int length)
- : RenderText(node, str ? str->substring(startOffset, length) : PassRefPtr<StringImpl>(0))
+ : RenderText(node, str ? str->substring(startOffset, length) : PassRefPtr<StringImpl>(nullptr))
, m_start(startOffset)
, m_end(length)
, m_firstLetter(0)
@@ -64,7 +64,7 @@ PassRefPtr<StringImpl> RenderTextFragment::originalText() const
Node* e = node();
RefPtr<StringImpl> result = ((e && e->isTextNode()) ? toText(e)->dataImpl() : contentString());
if (!result)
- return 0;
+ return nullptr;
return result->substring(start(), end());
}
@@ -92,6 +92,10 @@ void RenderTextFragment::setText(PassRefPtr<StringImpl> text, bool force)
m_start = 0;
m_end = textLength();
if (m_firstLetter) {
+ // FIXME: We should not modify the structure of the render tree during
+ // layout. crbug.com/370458
+ DeprecatedDisableModifyRenderTreeStructureAsserts disabler;
+
ASSERT(!m_contentString);
m_firstLetter->destroy();
m_firstLetter = 0;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.h
index 44bbfe81f6d..de9858c4862 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTextFragment.h
@@ -37,7 +37,7 @@ public:
RenderTextFragment(Node*, StringImpl*);
virtual ~RenderTextFragment();
- virtual bool isTextFragment() const { return true; }
+ virtual bool isTextFragment() const OVERRIDE { return true; }
virtual bool canBeSelectionLeaf() const OVERRIDE { return node() && node()->rendererIsEditable(); }
@@ -45,31 +45,31 @@ public:
unsigned end() const { return m_end; }
virtual unsigned textStartOffset() const OVERRIDE { return start(); }
- RenderObject* firstLetter() const { return m_firstLetter; }
- void setFirstLetter(RenderObject* firstLetter) { m_firstLetter = firstLetter; }
+ RenderBoxModelObject* firstLetter() const { return m_firstLetter; }
+ void setFirstLetter(RenderBoxModelObject* firstLetter) { m_firstLetter = firstLetter; }
RenderText* firstRenderTextInFirstLetter() const;
StringImpl* contentString() const { return m_contentString.get(); }
- virtual PassRefPtr<StringImpl> originalText() const;
+ virtual PassRefPtr<StringImpl> originalText() const OVERRIDE;
virtual void setText(PassRefPtr<StringImpl>, bool force = false) OVERRIDE;
virtual void transformText() OVERRIDE;
protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
private:
- virtual void willBeDestroyed();
+ virtual void willBeDestroyed() OVERRIDE;
- virtual UChar previousCharacter() const;
+ virtual UChar previousCharacter() const OVERRIDE;
RenderBlock* blockForAccompanyingFirstLetter() const;
virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRIDE;
unsigned m_start;
unsigned m_end;
RefPtr<StringImpl> m_contentString;
- RenderObject* m_firstLetter;
+ RenderBoxModelObject* m_firstLetter;
};
DEFINE_TYPE_CASTS(RenderTextFragment, RenderObject, object, toRenderText(object)->isTextFragment(), toRenderText(object).isTextFragment());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTheme.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTheme.cpp
index 90c56f77dbd..3c0e2c6fe12 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTheme.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTheme.cpp
@@ -22,16 +22,17 @@
#include "config.h"
#include "core/rendering/RenderTheme.h"
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
-#include "InputTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/CSSValueKeywords.h"
+#include "core/HTMLNames.h"
+#include "core/InputTypeNames.h"
#include "core/dom/Document.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/editing/FrameSelection.h"
#include "core/fileapi/FileList.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLCollection.h"
#include "core/html/HTMLDataListElement.h"
+#include "core/html/HTMLFormControlElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLMeterElement.h"
#include "core/html/HTMLOptionElement.h"
@@ -41,7 +42,6 @@
#include "core/html/shadow/SpinButtonElement.h"
#include "core/html/shadow/TextControlInnerElements.h"
#include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/frame/Settings.h"
#include "core/rendering/PaintInfo.h"
@@ -50,6 +50,7 @@
#include "core/rendering/style/RenderStyle.h"
#include "platform/FileMetadata.h"
#include "platform/FloatConversion.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/fonts/FontSelector.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/text/PlatformLocale.h"
@@ -59,22 +60,12 @@
#include "public/platform/WebRect.h"
#include "wtf/text/StringBuilder.h"
-#if ENABLE(INPUT_SPEECH)
-#include "core/rendering/RenderInputSpeech.h"
-#endif
-
// The methods in this file are shared by all themes on every platform.
namespace WebCore {
using namespace HTMLNames;
-static Color& customFocusRingColor()
-{
- DEFINE_STATIC_LOCAL(Color, color, ());
- return color;
-}
-
static blink::WebFallbackThemeEngine::State getWebFallbackThemeState(const RenderTheme* theme, const RenderObject* o)
{
if (!theme->isEnabled(o))
@@ -88,13 +79,14 @@ static blink::WebFallbackThemeEngine::State getWebFallbackThemeState(const Rende
}
RenderTheme::RenderTheme()
+ : m_hasCustomFocusRingColor(false)
#if USE(NEW_THEME)
- : m_platformTheme(platformTheme())
+ , m_platformTheme(platformTheme())
#endif
{
}
-void RenderTheme::adjustStyle(RenderStyle* style, Element* e, const CachedUAStyle& uaStyle)
+void RenderTheme::adjustStyle(RenderStyle* style, Element* e, const CachedUAStyle* uaStyle)
{
// Force inline and table display styles to be inline-block (except for table- which is block)
ControlPart part = style->appearance();
@@ -106,7 +98,7 @@ void RenderTheme::adjustStyle(RenderStyle* style, Element* e, const CachedUAStyl
else if (style->display() == LIST_ITEM || style->display() == TABLE)
style->setDisplay(BLOCK);
- if (uaStyle.hasAppearance && isControlStyled(style, uaStyle)) {
+ if (uaStyle && uaStyle->hasAppearance && isControlStyled(style, uaStyle)) {
if (part == MenulistPart) {
style->setAppearance(MenulistButtonPart);
part = MenulistButtonPart;
@@ -193,7 +185,7 @@ void RenderTheme::adjustStyle(RenderStyle* style, Element* e, const CachedUAStyl
// Now update our font.
if (style->setFontDescription(controlFont))
- style->font().update(0);
+ style->font().update(nullptr);
}
}
default:
@@ -230,10 +222,6 @@ void RenderTheme::adjustStyle(RenderStyle* style, Element* e, const CachedUAStyl
return adjustSearchFieldDecorationStyle(style, e);
case SearchFieldResultsDecorationPart:
return adjustSearchFieldResultsDecorationStyle(style, e);
-#if ENABLE(INPUT_SPEECH)
- case InputSpeechButtonPart:
- return adjustInputFieldSpeechButtonStyle(style, e);
-#endif
default:
break;
}
@@ -246,12 +234,9 @@ bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRe
// for that control.
if (paintInfo.context->updatingControlTints()) {
if (controlSupportsTints(o))
- o->repaint();
+ o->paintInvalidationForWholeRenderer();
return false;
}
- if (paintInfo.context->paintingDisabled())
- return false;
-
ControlPart part = o->style()->appearance();
if (shouldUseFallbackTheme(o->style()))
@@ -311,22 +296,12 @@ bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRe
return paintMediaOverlayPlayButton(o, paintInfo, r);
case MediaMuteButtonPart:
return paintMediaMuteButton(o, paintInfo, r);
- case MediaSeekBackButtonPart:
- return paintMediaSeekBackButton(o, paintInfo, r);
- case MediaSeekForwardButtonPart:
- return paintMediaSeekForwardButton(o, paintInfo, r);
- case MediaRewindButtonPart:
- return paintMediaRewindButton(o, paintInfo, r);
- case MediaReturnToRealtimeButtonPart:
- return paintMediaReturnToRealtimeButton(o, paintInfo, r);
case MediaToggleClosedCaptionsButtonPart:
return paintMediaToggleClosedCaptionsButton(o, paintInfo, r);
case MediaSliderPart:
return paintMediaSliderTrack(o, paintInfo, r);
case MediaSliderThumbPart:
return paintMediaSliderThumb(o, paintInfo, r);
- case MediaVolumeSliderMuteButtonPart:
- return paintMediaMuteButton(o, paintInfo, r);
case MediaVolumeSliderContainerPart:
return paintMediaVolumeSliderContainer(o, paintInfo, r);
case MediaVolumeSliderPart:
@@ -356,10 +331,6 @@ bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRe
return paintSearchFieldDecoration(o, paintInfo, r);
case SearchFieldResultsDecorationPart:
return paintSearchFieldResultsDecoration(o, paintInfo, r);
-#if ENABLE(INPUT_SPEECH)
- case InputSpeechButtonPart:
- return paintInputFieldSpeechButton(o, paintInfo, r);
-#endif
default:
break;
}
@@ -369,9 +340,6 @@ bool RenderTheme::paint(RenderObject* o, const PaintInfo& paintInfo, const IntRe
bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
- if (paintInfo.context->paintingDisabled())
- return false;
-
// Call the appropriate paint method based off the appearance value.
switch (o->style()->appearance()) {
case TextFieldPart:
@@ -401,9 +369,6 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, c
case SearchFieldCancelButtonPart:
case SearchFieldDecorationPart:
case SearchFieldResultsDecorationPart:
-#if ENABLE(INPUT_SPEECH)
- case InputSpeechButtonPart:
-#endif
default:
break;
}
@@ -413,9 +378,6 @@ bool RenderTheme::paintBorderOnly(RenderObject* o, const PaintInfo& paintInfo, c
bool RenderTheme::paintDecorations(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
- if (paintInfo.context->paintingDisabled())
- return false;
-
// Call the appropriate paint method based off the appearance value.
switch (o->style()->appearance()) {
case MenulistButtonPart:
@@ -443,9 +405,6 @@ bool RenderTheme::paintDecorations(RenderObject* o, const PaintInfo& paintInfo,
case SearchFieldCancelButtonPart:
case SearchFieldDecorationPart:
case SearchFieldResultsDecorationPart:
-#if ENABLE(INPUT_SPEECH)
- case InputSpeechButtonPart:
-#endif
default:
break;
}
@@ -455,19 +414,7 @@ bool RenderTheme::paintDecorations(RenderObject* o, const PaintInfo& paintInfo,
String RenderTheme::extraDefaultStyleSheet()
{
- if (!RuntimeEnabledFeatures::dataListElementEnabled() && !RuntimeEnabledFeatures::dialogElementEnabled())
- return String();
StringBuilder runtimeCSS;
-
- if (RuntimeEnabledFeatures::dataListElementEnabled()) {
- runtimeCSS.appendLiteral("datalist {display: none ;}");
-
- if (RuntimeEnabledFeatures::inputTypeColorEnabled()) {
- runtimeCSS.appendLiteral("input[type=\"color\"][list] { -webkit-appearance: menulist; width: 88px; height: 23px;}");
- runtimeCSS.appendLiteral("input[type=\"color\"][list]::-webkit-color-swatch-wrapper { padding-left: 8px; padding-right: 24px;}");
- runtimeCSS.appendLiteral("input[type=\"color\"][list]::-webkit-color-swatch { border-color: #000000;}");
- }
- }
if (RuntimeEnabledFeatures::dialogElementEnabled()) {
runtimeCSS.appendLiteral("dialog:not([open]) { display: none; }");
runtimeCSS.appendLiteral("dialog { position: absolute; left: 0; right: 0; width: -webkit-fit-content; height: -webkit-fit-content; margin: auto; border: solid; padding: 1em; background: white; color: black;}");
@@ -502,58 +449,42 @@ String RenderTheme::formatMediaControlsCurrentTime(float currentTime, float /*du
Color RenderTheme::activeSelectionBackgroundColor() const
{
- if (!m_activeSelectionBackgroundColor.isValid())
- m_activeSelectionBackgroundColor = platformActiveSelectionBackgroundColor().blendWithWhite();
- return m_activeSelectionBackgroundColor;
+ return platformActiveSelectionBackgroundColor().blendWithWhite();
}
Color RenderTheme::inactiveSelectionBackgroundColor() const
{
- if (!m_inactiveSelectionBackgroundColor.isValid())
- m_inactiveSelectionBackgroundColor = platformInactiveSelectionBackgroundColor().blendWithWhite();
- return m_inactiveSelectionBackgroundColor;
+ return platformInactiveSelectionBackgroundColor().blendWithWhite();
}
Color RenderTheme::activeSelectionForegroundColor() const
{
- if (!m_activeSelectionForegroundColor.isValid() && supportsSelectionForegroundColors())
- m_activeSelectionForegroundColor = platformActiveSelectionForegroundColor();
- return m_activeSelectionForegroundColor;
+ return platformActiveSelectionForegroundColor();
}
Color RenderTheme::inactiveSelectionForegroundColor() const
{
- if (!m_inactiveSelectionForegroundColor.isValid() && supportsSelectionForegroundColors())
- m_inactiveSelectionForegroundColor = platformInactiveSelectionForegroundColor();
- return m_inactiveSelectionForegroundColor;
+ return platformInactiveSelectionForegroundColor();
}
Color RenderTheme::activeListBoxSelectionBackgroundColor() const
{
- if (!m_activeListBoxSelectionBackgroundColor.isValid())
- m_activeListBoxSelectionBackgroundColor = platformActiveListBoxSelectionBackgroundColor();
- return m_activeListBoxSelectionBackgroundColor;
+ return platformActiveListBoxSelectionBackgroundColor();
}
Color RenderTheme::inactiveListBoxSelectionBackgroundColor() const
{
- if (!m_inactiveListBoxSelectionBackgroundColor.isValid())
- m_inactiveListBoxSelectionBackgroundColor = platformInactiveListBoxSelectionBackgroundColor();
- return m_inactiveListBoxSelectionBackgroundColor;
+ return platformInactiveListBoxSelectionBackgroundColor();
}
Color RenderTheme::activeListBoxSelectionForegroundColor() const
{
- if (!m_activeListBoxSelectionForegroundColor.isValid() && supportsListBoxSelectionForegroundColors())
- m_activeListBoxSelectionForegroundColor = platformActiveListBoxSelectionForegroundColor();
- return m_activeListBoxSelectionForegroundColor;
+ return platformActiveListBoxSelectionForegroundColor();
}
Color RenderTheme::inactiveListBoxSelectionForegroundColor() const
{
- if (!m_inactiveListBoxSelectionForegroundColor.isValid() && supportsListBoxSelectionForegroundColors())
- m_inactiveListBoxSelectionForegroundColor = platformInactiveListBoxSelectionForegroundColor();
- return m_inactiveListBoxSelectionForegroundColor;
+ return platformInactiveListBoxSelectionForegroundColor();
}
Color RenderTheme::platformActiveSelectionBackgroundColor() const
@@ -637,8 +568,10 @@ static bool isBackgroundOrBorderStyled(const RenderStyle& style, const CachedUAS
|| style.visitedDependentColor(CSSPropertyBackgroundColor) != uaStyle.backgroundColor;
}
-bool RenderTheme::isControlStyled(const RenderStyle* style, const CachedUAStyle& uaStyle) const
+bool RenderTheme::isControlStyled(const RenderStyle* style, const CachedUAStyle* uaStyle) const
{
+ ASSERT(uaStyle);
+
switch (style->appearance()) {
case PushButtonPart:
case SquareButtonPart:
@@ -649,14 +582,14 @@ bool RenderTheme::isControlStyled(const RenderStyle* style, const CachedUAStyle&
case ContinuousCapacityLevelIndicatorPart:
case DiscreteCapacityLevelIndicatorPart:
case RatingLevelIndicatorPart:
- return isBackgroundOrBorderStyled(*style, uaStyle);
+ return isBackgroundOrBorderStyled(*style, *uaStyle);
case ListboxPart:
case MenulistPart:
case SearchFieldPart:
case TextAreaPart:
case TextFieldPart:
- return isBackgroundOrBorderStyled(*style, uaStyle) || style->boxShadow();
+ return isBackgroundOrBorderStyled(*style, *uaStyle) || style->boxShadow();
case SliderHorizontalPart:
case SliderVerticalPart:
@@ -698,15 +631,15 @@ bool RenderTheme::supportsFocusRing(const RenderStyle* style) const
bool RenderTheme::stateChanged(RenderObject* o, ControlState state) const
{
// Default implementation assumes the controls don't respond to changes in :hover state
- if (state == HoverState && !supportsHover(o->style()))
+ if (state == HoverControlState && !supportsHover(o->style()))
return false;
// Assume pressed state is only responded to if the control is enabled.
- if (state == PressedState && !isEnabled(o))
+ if (state == PressedControlState && !isEnabled(o))
return false;
// Repaint the control.
- o->repaint();
+ o->paintInvalidationForWholeRenderer();
return true;
}
@@ -714,27 +647,27 @@ ControlStates RenderTheme::controlStatesForRenderer(const RenderObject* o) const
{
ControlStates result = 0;
if (isHovered(o)) {
- result |= HoverState;
+ result |= HoverControlState;
if (isSpinUpButtonPartHovered(o))
- result |= SpinUpState;
+ result |= SpinUpControlState;
}
if (isPressed(o)) {
- result |= PressedState;
+ result |= PressedControlState;
if (isSpinUpButtonPartPressed(o))
- result |= SpinUpState;
+ result |= SpinUpControlState;
}
if (isFocused(o) && o->style()->outlineStyleIsAuto())
- result |= FocusState;
+ result |= FocusControlState;
if (isEnabled(o))
- result |= EnabledState;
+ result |= EnabledControlState;
if (isChecked(o))
- result |= CheckedState;
+ result |= CheckedControlState;
if (isReadOnlyControl(o))
- result |= ReadOnlyState;
+ result |= ReadOnlyControlState;
if (!isActive(o))
- result |= WindowInactiveState;
+ result |= WindowInactiveControlState;
if (isIndeterminate(o))
- result |= IndeterminateState;
+ result |= IndeterminateControlState;
return result;
}
@@ -753,14 +686,14 @@ bool RenderTheme::isActive(const RenderObject* o) const
bool RenderTheme::isChecked(const RenderObject* o) const
{
- if (!o->node() || !o->node()->hasTagName(inputTag))
+ if (!isHTMLInputElement(o->node()))
return false;
return toHTMLInputElement(o->node())->shouldAppearChecked();
}
bool RenderTheme::isIndeterminate(const RenderObject* o) const
{
- if (!o->node() || !o->node()->hasTagName(inputTag))
+ if (!isHTMLInputElement(o->node()))
return false;
return toHTMLInputElement(o->node())->shouldAppearIndeterminate();
}
@@ -781,8 +714,8 @@ bool RenderTheme::isFocused(const RenderObject* o) const
node = node->focusDelegate();
Document& document = node->document();
- Frame* frame = document.frame();
- return node == document.focusedElement() && node->shouldHaveFocusAppearance() && frame && frame->selection().isFocusedAndActive();
+ LocalFrame* frame = document.frame();
+ return node == document.focusedElement() && node->focused() && node->shouldHaveFocusAppearance() && frame && frame->selection().isFocusedAndActive();
}
bool RenderTheme::isPressed(const RenderObject* o) const
@@ -805,9 +738,10 @@ bool RenderTheme::isSpinUpButtonPartPressed(const RenderObject* o) const
bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
{
Node* node = o->node();
- if (!node || !node->isElementNode())
+ if (!node || !node->isElementNode() || !toElement(node)->isFormControlElement())
return false;
- return toElement(node)->matchesReadOnlyPseudoClass();
+ HTMLFormControlElement* element = toHTMLFormControlElement(node);
+ return element->isReadOnly();
}
bool RenderTheme::isHovered(const RenderObject* o) const
@@ -875,18 +809,6 @@ void RenderTheme::adjustMenuListStyle(RenderStyle*, Element*) const
{
}
-#if ENABLE(INPUT_SPEECH)
-void RenderTheme::adjustInputFieldSpeechButtonStyle(RenderStyle* style, Element* element) const
-{
- RenderInputSpeech::adjustInputFieldSpeechButtonStyle(style, element);
-}
-
-bool RenderTheme::paintInputFieldSpeechButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
-{
- return RenderInputSpeech::paintInputFieldSpeechButton(object, paintInfo, rect);
-}
-#endif
-
IntSize RenderTheme::meterSizeForBounds(const RenderMeter*, const IntRect& bounds) const
{
return bounds.size();
@@ -905,10 +827,13 @@ bool RenderTheme::paintMeter(RenderObject*, const PaintInfo&, const IntRect&)
void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
{
Node* node = o->node();
- if (!node || !node->hasTagName(inputTag))
+ if (!isHTMLInputElement(node))
return;
HTMLInputElement* input = toHTMLInputElement(node);
+ if (!input->isRangeControl())
+ return;
+
HTMLDataListElement* dataList = input->dataList();
if (!dataList)
return;
@@ -960,13 +885,13 @@ void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo,
tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
tickRegionWidth = trackBounds.height() - thumbSize.width();
}
- RefPtr<HTMLCollection> options = dataList->options();
+ RefPtrWillBeRawPtr<HTMLCollection> options = dataList->options();
GraphicsContextStateSaver stateSaver(*paintInfo.context);
paintInfo.context->setFillColor(o->resolveColor(CSSPropertyColor));
- for (unsigned i = 0; Node* node = options->item(i); i++) {
- ASSERT(node->hasTagName(optionTag));
- HTMLOptionElement* optionElement = toHTMLOptionElement(node);
- String value = optionElement->value();
+ for (unsigned i = 0; Element* element = options->item(i); i++) {
+ ASSERT(isHTMLOptionElement(*element));
+ HTMLOptionElement& optionElement = toHTMLOptionElement(*element);
+ String value = optionElement.value();
if (!input->isValidValue(value))
continue;
double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
@@ -1027,16 +952,6 @@ void RenderTheme::adjustSearchFieldResultsDecorationStyle(RenderStyle*, Element*
void RenderTheme::platformColorsDidChange()
{
- m_activeSelectionForegroundColor = Color();
- m_inactiveSelectionForegroundColor = Color();
- m_activeSelectionBackgroundColor = Color();
- m_inactiveSelectionBackgroundColor = Color();
-
- m_activeListBoxSelectionForegroundColor = Color();
- m_inactiveListBoxSelectionForegroundColor = Color();
- m_activeListBoxSelectionBackgroundColor = Color();
- m_inactiveListBoxSelectionForegroundColor = Color();
-
Page::scheduleForcedStyleRecalcForAllPages();
}
@@ -1116,6 +1031,7 @@ Color RenderTheme::systemColor(CSSValueID cssValueId) const
default:
break;
}
+ ASSERT_NOT_REACHED();
return Color();
}
@@ -1136,12 +1052,13 @@ Color RenderTheme::tapHighlightColor()
void RenderTheme::setCustomFocusRingColor(const Color& c)
{
- customFocusRingColor() = c;
+ m_customFocusRingColor = c;
+ m_hasCustomFocusRingColor = true;
}
-Color RenderTheme::focusRingColor()
+Color RenderTheme::focusRingColor() const
{
- return customFocusRingColor().isValid() ? customFocusRingColor() : theme().platformFocusRingColor();
+ return m_hasCustomFocusRingColor ? m_customFocusRingColor : theme().platformFocusRingColor();
}
String RenderTheme::fileListNameForWidth(Locale& locale, const FileList* fileList, const Font& font, int width) const
@@ -1167,20 +1084,6 @@ bool RenderTheme::shouldOpenPickerWithF4Key() const
return false;
}
-bool RenderTheme::supportsDataListUI(const AtomicString& type) const
-{
- return type == InputTypeNames::text || type == InputTypeNames::search || type == InputTypeNames::url
- || type == InputTypeNames::tel || type == InputTypeNames::email || type == InputTypeNames::number
- || type == InputTypeNames::color
- || type == InputTypeNames::date
- || type == InputTypeNames::datetime
- || type == InputTypeNames::datetime_local
- || type == InputTypeNames::month
- || type == InputTypeNames::week
- || type == InputTypeNames::time
- || type == InputTypeNames::range;
-}
-
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
bool RenderTheme::supportsCalendarPicker(const AtomicString& type) const
{
@@ -1235,6 +1138,8 @@ void RenderTheme::setSizeIfAuto(RenderStyle* style, const IntSize& size)
bool RenderTheme::paintCheckboxUsingFallbackTheme(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
+ if (i.context->paintingDisabled())
+ return false;
blink::WebFallbackThemeEngine::ExtraParams extraParams;
blink::WebCanvas* canvas = i.context->canvas();
extraParams.button.checked = isChecked(o);
@@ -1247,7 +1152,7 @@ bool RenderTheme::paintCheckboxUsingFallbackTheme(RenderObject* o, const PaintIn
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
i.context->translate(unzoomedRect.x(), unzoomedRect.y());
- i.context->scale(FloatSize(zoomLevel, zoomLevel));
+ i.context->scale(zoomLevel, zoomLevel);
i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -1277,6 +1182,8 @@ void RenderTheme::adjustCheckboxStyleUsingFallbackTheme(RenderStyle* style, Elem
bool RenderTheme::paintRadioUsingFallbackTheme(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
+ if (i.context->paintingDisabled())
+ return false;
blink::WebFallbackThemeEngine::ExtraParams extraParams;
blink::WebCanvas* canvas = i.context->canvas();
extraParams.button.checked = isChecked(o);
@@ -1289,7 +1196,7 @@ bool RenderTheme::paintRadioUsingFallbackTheme(RenderObject* o, const PaintInfo&
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
i.context->translate(unzoomedRect.x(), unzoomedRect.y());
- i.context->scale(FloatSize(zoomLevel, zoomLevel));
+ i.context->scale(zoomLevel, zoomLevel);
i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTheme.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTheme.h
index 30a1c143153..4e8661e50b8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTheme.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTheme.h
@@ -37,12 +37,9 @@
namespace WebCore {
-class CSSStyleSheet;
class Element;
class FileList;
class HTMLInputElement;
-class PopupMenu;
-class RenderMenuList;
class RenderMeter;
class RenderProgress;
@@ -65,7 +62,7 @@ public:
// metrics and defaults given the contents of the style. This includes sophisticated operations like
// selection of control size based off the font, the disabling of appearance when certain other properties like
// "border" are set, or if the appearance is not supported by the theme.
- void adjustStyle(RenderStyle*, Element*, const CachedUAStyle&);
+ void adjustStyle(RenderStyle*, Element*, const CachedUAStyle*);
// This method is called to paint the widget as a background of the RenderObject. A widget's foreground, e.g., the
// text of a button, is always rendered by the engine itself. The boolean return value indicates
@@ -97,7 +94,7 @@ public:
virtual bool controlSupportsTints(const RenderObject*) const { return false; }
// Whether or not the control has been styled enough by the author to disable the native appearance.
- virtual bool isControlStyled(const RenderStyle*, const CachedUAStyle&) const;
+ virtual bool isControlStyled(const RenderStyle*, const CachedUAStyle*) const;
// A general method asking if any control tinting is supported at all.
virtual bool supportsControlTints() const { return false; }
@@ -115,9 +112,6 @@ public:
// A method asking if the theme's controls actually care about redrawing when hovered.
virtual bool supportsHover(const RenderStyle*) const { return false; }
- // A method asking if the platform is able to show datalist suggestions for a given input type.
- virtual bool supportsDataListUI(const AtomicString&) const;
-
#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
// A method asking if the platform is able to show a calendar picker for a given input type.
virtual bool supportsCalendarPicker(const AtomicString&) const;
@@ -139,11 +133,12 @@ public:
virtual Color platformActiveTextSearchHighlightColor() const;
virtual Color platformInactiveTextSearchHighlightColor() const;
- static Color focusRingColor();
+ Color focusRingColor() const;
virtual Color platformFocusRingColor() const { return Color(0, 0, 0); }
- static void setCustomFocusRingColor(const Color&);
+ void setCustomFocusRingColor(const Color&);
static Color tapHighlightColor();
virtual Color platformTapHighlightColor() const { return RenderTheme::defaultTapHighlightColor; }
+ virtual Color platformDefaultCompositionBackgroundColor() const { return defaultCompositionBackgroundColor; }
virtual void platformColorsDidChange();
virtual double caretBlinkInterval() const { return 0.5; }
@@ -173,9 +168,6 @@ public:
virtual double animationDurationForProgressBar(RenderProgress*) const;
// Media controls
- virtual bool supportsClosedCaptioning() const { return false; }
- virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return false; }
- virtual bool usesVerticalVolumeSlider() const { return true; }
virtual String formatMediaControlsTime(float time) const;
virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const;
@@ -201,6 +193,8 @@ public:
virtual bool shouldOpenPickerWithF4Key() const;
+ virtual bool supportsSelectionForegroundColors() const { return true; }
+
protected:
// The platform selection color.
virtual Color platformActiveSelectionBackgroundColor() const;
@@ -215,8 +209,6 @@ protected:
// A method asking if the theme is able to draw the focus ring.
virtual bool supportsFocusRing(const RenderStyle*) const;
- virtual bool supportsSelectionForegroundColors() const { return true; }
- virtual bool supportsListBoxSelectionForegroundColors() const { return true; }
#if !USE(NEW_THEME)
// Methods for each appearance value.
@@ -249,11 +241,6 @@ protected:
virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
-#if ENABLE(INPUT_SPEECH)
- virtual void adjustInputFieldSpeechButtonStyle(RenderStyle*, Element*) const;
- virtual bool paintInputFieldSpeechButton(RenderObject*, const PaintInfo&, const IntRect&);
-#endif
-
virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual void adjustSliderThumbStyle(RenderStyle*, Element*) const;
@@ -275,15 +262,11 @@ protected:
virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaOverlayPlayButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
- virtual bool paintMediaSeekBackButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
- virtual bool paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
- virtual bool paintMediaRewindButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
- virtual bool paintMediaReturnToRealtimeButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaControlsBackground(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
virtual bool paintMediaCurrentTime(RenderObject*, const PaintInfo&, const IntRect&) { return true; }
@@ -314,20 +297,15 @@ public:
bool isReadOnlyControl(const RenderObject*) const;
private:
- mutable Color m_activeSelectionBackgroundColor;
- mutable Color m_inactiveSelectionBackgroundColor;
- mutable Color m_activeSelectionForegroundColor;
- mutable Color m_inactiveSelectionForegroundColor;
-
- mutable Color m_activeListBoxSelectionBackgroundColor;
- mutable Color m_inactiveListBoxSelectionBackgroundColor;
- mutable Color m_activeListBoxSelectionForegroundColor;
- mutable Color m_inactiveListBoxSelectionForegroundColor;
+ Color m_customFocusRingColor;
+ bool m_hasCustomFocusRingColor;
// This color is expected to be drawn on a semi-transparent overlay,
// making it more transparent than its alpha value indicates.
static const RGBA32 defaultTapHighlightColor = 0x66000000;
+ static const RGBA32 defaultCompositionBackgroundColor = 0xFFFFDD55;
+
#if USE(NEW_THEME)
Theme* m_platformTheme; // The platform-specific theme.
#endif
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.cpp
index 4cad9a6c0a6..0c4040af05b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "core/rendering/RenderThemeChromiumAndroid.h"
-#include "CSSValueKeywords.h"
-#include "InputTypeNames.h"
-#include "UserAgentStyleSheets.h"
+#include "core/CSSValueKeywords.h"
+#include "core/InputTypeNames.h"
+#include "core/UserAgentStyleSheets.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderMediaControls.h"
#include "core/rendering/RenderObject.h"
@@ -38,7 +38,7 @@
#include "platform/graphics/Color.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "public/platform/Platform.h"
-#include "public/platform/default/WebThemeEngine.h"
+#include "public/platform/WebThemeEngine.h"
#include "wtf/StdLibExtras.h"
namespace WebCore {
@@ -58,16 +58,6 @@ RenderThemeChromiumAndroid::~RenderThemeChromiumAndroid()
{
}
-Color RenderThemeChromiumAndroid::systemColor(CSSValueID cssValueId) const
-{
- if (isRunningLayoutTest() && cssValueId == CSSValueButtonface) {
- // Match Linux button color in layout tests.
- static const Color linuxButtonGrayColor(0xffdddddd);
- return linuxButtonGrayColor;
- }
- return RenderTheme::systemColor(cssValueId);
-}
-
String RenderThemeChromiumAndroid::extraMediaControlsStyleSheet()
{
return String(mediaControlsAndroidUserAgentStyleSheet, sizeof(mediaControlsAndroidUserAgentStyleSheet));
@@ -91,11 +81,6 @@ void RenderThemeChromiumAndroid::adjustInnerSpinButtonStyle(RenderStyle* style,
}
}
-bool RenderThemeChromiumAndroid::paintMediaOverlayPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
-{
- return RenderMediaControls::paintMediaControlsPart(MediaOverlayPlayButton, object, paintInfo, rect);
-}
-
int RenderThemeChromiumAndroid::menuListArrowPadding() const
{
// We cannot use the scrollbar thickness here, as it's width is 0 on Android.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.h b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.h
index 93abb212e22..9889dc0b5f5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumAndroid.h
@@ -30,19 +30,15 @@
namespace WebCore {
-class RenderThemeChromiumAndroid : public RenderThemeChromiumDefault {
+class RenderThemeChromiumAndroid FINAL : public RenderThemeChromiumDefault {
public:
static PassRefPtr<RenderTheme> create();
virtual String extraDefaultStyleSheet() OVERRIDE;
- virtual Color systemColor(CSSValueID) const OVERRIDE;
-
virtual void adjustInnerSpinButtonStyle(RenderStyle*, Element*) const OVERRIDE;
virtual bool delegatesMenuListRendering() const OVERRIDE { return true; }
- virtual bool paintMediaOverlayPlayButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
-
virtual String extraMediaControlsStyleSheet() OVERRIDE;
virtual Color platformTapHighlightColor() const OVERRIDE
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.cpp
index de62300e085..3f65622e8fc 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.cpp
@@ -25,8 +25,8 @@
#include "config.h"
#include "core/rendering/RenderThemeChromiumDefault.h"
-#include "CSSValueKeywords.h"
-#include "UserAgentStyleSheets.h"
+#include "core/CSSValueKeywords.h"
+#include "core/UserAgentStyleSheets.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderProgress.h"
@@ -34,9 +34,9 @@
#include "platform/graphics/Color.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
-#include "public/platform/default/WebThemeEngine.h"
#include "public/platform/Platform.h"
#include "public/platform/WebRect.h"
+#include "public/platform/WebThemeEngine.h"
#include "wtf/StdLibExtras.h"
namespace WebCore {
@@ -220,11 +220,6 @@ void RenderThemeChromiumDefault::adjustSliderThumbSize(RenderStyle* style, Eleme
RenderThemeChromiumSkia::adjustSliderThumbSize(style, element);
}
-bool RenderThemeChromiumDefault::supportsControlTints() const
-{
- return true;
-}
-
void RenderThemeChromiumDefault::setCaretBlinkInterval(double interval)
{
m_caretBlinkInterval = interval;
@@ -249,19 +244,22 @@ void RenderThemeChromiumDefault::setSelectionColors(
bool RenderThemeChromiumDefault::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
+ if (i.context->paintingDisabled())
+ return false;
blink::WebThemeEngine::ExtraParams extraParams;
blink::WebCanvas* canvas = i.context->canvas();
extraParams.button.checked = isChecked(o);
extraParams.button.indeterminate = isIndeterminate(o);
float zoomLevel = o->style()->effectiveZoom();
- GraphicsContextStateSaver stateSaver(*i.context);
+ GraphicsContextStateSaver stateSaver(*i.context, false);
IntRect unzoomedRect = rect;
if (zoomLevel != 1) {
+ stateSaver.save();
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
i.context->translate(unzoomedRect.x(), unzoomedRect.y());
- i.context->scale(FloatSize(zoomLevel, zoomLevel));
+ i.context->scale(zoomLevel, zoomLevel);
i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -284,6 +282,8 @@ void RenderThemeChromiumDefault::setCheckboxSize(RenderStyle* style) const
bool RenderThemeChromiumDefault::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
+ if (i.context->paintingDisabled())
+ return false;
blink::WebThemeEngine::ExtraParams extraParams;
blink::WebCanvas* canvas = i.context->canvas();
extraParams.button.checked = isChecked(o);
@@ -307,6 +307,8 @@ void RenderThemeChromiumDefault::setRadioSize(RenderStyle* style) const
bool RenderThemeChromiumDefault::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
+ if (i.context->paintingDisabled())
+ return false;
blink::WebThemeEngine::ExtraParams extraParams;
blink::WebCanvas* canvas = i.context->canvas();
extraParams.button.hasBorder = true;
@@ -324,6 +326,8 @@ bool RenderThemeChromiumDefault::paintTextField(RenderObject* o, const PaintInfo
// so return true to draw CSS border and background.
if (o->style()->hasBorderRadius() || o->style()->hasBackgroundImage())
return true;
+ if (i.context->paintingDisabled())
+ return false;
ControlPart part = o->style()->appearance();
@@ -333,8 +337,7 @@ bool RenderThemeChromiumDefault::paintTextField(RenderObject* o, const PaintInfo
blink::WebCanvas* canvas = i.context->canvas();
- // Fallback to white if the specified color object is invalid.
- Color backgroundColor = o->resolveColor(CSSPropertyBackgroundColor, Color::white);
+ Color backgroundColor = o->resolveColor(CSSPropertyBackgroundColor);
extraParams.textField.backgroundColor = backgroundColor.rgb();
blink::Platform::current()->themeEngine()->paint(canvas, blink::WebThemeEngine::PartTextField, getWebThemeState(this, o), blink::WebRect(rect), &extraParams);
@@ -343,7 +346,7 @@ bool RenderThemeChromiumDefault::paintTextField(RenderObject* o, const PaintInfo
bool RenderThemeChromiumDefault::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
- if (!o->isBox())
+ if (!o->isBox() || i.context->paintingDisabled())
return false;
const int right = rect.x() + rect.width();
@@ -388,7 +391,7 @@ bool RenderThemeChromiumDefault::paintMenuList(RenderObject* o, const PaintInfo&
bool RenderThemeChromiumDefault::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
- if (!o->isBox())
+ if (!o->isBox() || i.context->paintingDisabled())
return false;
const int right = rect.x() + rect.width();
@@ -422,6 +425,8 @@ bool RenderThemeChromiumDefault::paintMenuListButton(RenderObject* o, const Pain
bool RenderThemeChromiumDefault::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
+ if (i.context->paintingDisabled())
+ return false;
blink::WebThemeEngine::ExtraParams extraParams;
blink::WebCanvas* canvas = i.context->canvas();
extraParams.slider.vertical = o->style()->appearance() == SliderVerticalPart;
@@ -430,13 +435,14 @@ bool RenderThemeChromiumDefault::paintSliderTrack(RenderObject* o, const PaintIn
// FIXME: Mock theme doesn't handle zoomed sliders.
float zoomLevel = useMockTheme() ? 1 : o->style()->effectiveZoom();
- GraphicsContextStateSaver stateSaver(*i.context);
+ GraphicsContextStateSaver stateSaver(*i.context, false);
IntRect unzoomedRect = rect;
if (zoomLevel != 1) {
+ stateSaver.save();
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
i.context->translate(unzoomedRect.x(), unzoomedRect.y());
- i.context->scale(FloatSize(zoomLevel, zoomLevel));
+ i.context->scale(zoomLevel, zoomLevel);
i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -447,6 +453,8 @@ bool RenderThemeChromiumDefault::paintSliderTrack(RenderObject* o, const PaintIn
bool RenderThemeChromiumDefault::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
+ if (i.context->paintingDisabled())
+ return false;
blink::WebThemeEngine::ExtraParams extraParams;
blink::WebCanvas* canvas = i.context->canvas();
extraParams.slider.vertical = o->style()->appearance() == SliderThumbVerticalPart;
@@ -454,13 +462,14 @@ bool RenderThemeChromiumDefault::paintSliderThumb(RenderObject* o, const PaintIn
// FIXME: Mock theme doesn't handle zoomed sliders.
float zoomLevel = useMockTheme() ? 1 : o->style()->effectiveZoom();
- GraphicsContextStateSaver stateSaver(*i.context);
+ GraphicsContextStateSaver stateSaver(*i.context, false);
IntRect unzoomedRect = rect;
if (zoomLevel != 1) {
+ stateSaver.save();
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
i.context->translate(unzoomedRect.x(), unzoomedRect.y());
- i.context->scale(FloatSize(zoomLevel, zoomLevel));
+ i.context->scale(zoomLevel, zoomLevel);
i.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -478,9 +487,11 @@ void RenderThemeChromiumDefault::adjustInnerSpinButtonStyle(RenderStyle* style,
bool RenderThemeChromiumDefault::paintInnerSpinButton(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
+ if (i.context->paintingDisabled())
+ return false;
blink::WebThemeEngine::ExtraParams extraParams;
blink::WebCanvas* canvas = i.context->canvas();
- extraParams.innerSpin.spinUp = (controlStatesForRenderer(o) & SpinUpState);
+ extraParams.innerSpin.spinUp = (controlStatesForRenderer(o) & SpinUpControlState);
extraParams.innerSpin.readOnly = isReadOnlyControl(o);
blink::Platform::current()->themeEngine()->paint(canvas, blink::WebThemeEngine::PartInnerSpinButton, getWebThemeState(this, o), blink::WebRect(rect), &extraParams);
@@ -491,6 +502,8 @@ bool RenderThemeChromiumDefault::paintProgressBar(RenderObject* o, const PaintIn
{
if (!o->isProgress())
return true;
+ if (i.context->paintingDisabled())
+ return false;
RenderProgress* renderProgress = toRenderProgress(o);
IntRect valueRect = progressValueRectFor(renderProgress, rect);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.h b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.h
index 74527e0732d..e69546895ea 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumDefault.h
@@ -36,12 +36,12 @@ namespace WebCore {
class RenderThemeChromiumDefault : public RenderThemeChromiumSkia {
public:
static PassRefPtr<RenderTheme> create();
- virtual String extraDefaultStyleSheet();
+ virtual String extraDefaultStyleSheet() OVERRIDE;
- virtual Color systemColor(CSSValueID) const;
+ virtual Color systemColor(CSSValueID) const OVERRIDE;
// A method asking if the control changes its tint when the window has focus or not.
- virtual bool controlSupportsTints(const RenderObject*) const;
+ virtual bool controlSupportsTints(const RenderObject*) const OVERRIDE;
virtual bool supportsFocusRing(const RenderStyle*) const OVERRIDE;
@@ -51,23 +51,23 @@ public:
virtual Color inactiveListBoxSelectionBackgroundColor() const;
virtual Color inactiveListBoxSelectionForegroundColor() const;
- virtual Color platformActiveSelectionBackgroundColor() const;
- virtual Color platformInactiveSelectionBackgroundColor() const;
- virtual Color platformActiveSelectionForegroundColor() const;
- virtual Color platformInactiveSelectionForegroundColor() const;
+ virtual Color platformActiveSelectionBackgroundColor() const OVERRIDE;
+ virtual Color platformInactiveSelectionBackgroundColor() const OVERRIDE;
+ virtual Color platformActiveSelectionForegroundColor() const OVERRIDE;
+ virtual Color platformInactiveSelectionForegroundColor() const OVERRIDE;
virtual IntSize sliderTickSize() const OVERRIDE;
virtual int sliderTickOffsetFromTrackCenter() const OVERRIDE;
- virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const OVERRIDE;
static void setCaretBlinkInterval(double);
- virtual double caretBlinkIntervalInternal() const;
+ virtual double caretBlinkIntervalInternal() const OVERRIDE;
- virtual bool paintCheckbox(RenderObject*, const PaintInfo&, const IntRect&);
- virtual void setCheckboxSize(RenderStyle*) const;
+ virtual bool paintCheckbox(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual void setCheckboxSize(RenderStyle*) const OVERRIDE;
- virtual bool paintRadio(RenderObject*, const PaintInfo&, const IntRect&);
- virtual void setRadioSize(RenderStyle*) const;
+ virtual bool paintRadio(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual void setRadioSize(RenderStyle*) const OVERRIDE;
virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
@@ -76,12 +76,12 @@ public:
virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual void adjustInnerSpinButtonStyle(RenderStyle*, Element*) const;
- virtual bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustInnerSpinButtonStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool popsMenuBySpaceOrReturn() const OVERRIDE { return true; }
+ virtual bool popsMenuBySpaceOrReturn() const OVERRIDE FINAL { return true; }
- virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
virtual bool shouldOpenPickerWithF4Key() const OVERRIDE;
@@ -93,9 +93,6 @@ protected:
virtual bool shouldUseFallbackTheme(RenderStyle*) const OVERRIDE;
private:
- // A general method asking if any control tinting is supported at all.
- virtual bool supportsControlTints() const;
-
static double m_caretBlinkInterval;
static unsigned m_activeSelectionBackgroundColor;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.cpp
index 527f8558f78..b8083e015fe 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.cpp
@@ -46,9 +46,9 @@ float RenderThemeChromiumFontProvider::s_defaultFontSize = 16.0;
// FIXME: The only case where we know we don't match IE is for ANSI encodings.
// IE uses MS Shell Dlg there, which we render incorrectly at certain pixel
// sizes (e.g. 15px). So, for now we just use Arial.
-const String& RenderThemeChromiumFontProvider::defaultGUIFont()
+const AtomicString& RenderThemeChromiumFontProvider::defaultGUIFont()
{
- DEFINE_STATIC_LOCAL(String, fontFace, ("Arial"));
+ DEFINE_STATIC_LOCAL(const AtomicString, fontFace, ("Arial", AtomicString::ConstructFromLiteral));
return fontFace;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.h b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.h
index 57589c2a397..e31322461b2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProvider.h
@@ -26,11 +26,7 @@
#ifndef RenderThemeChromiumFontProvider_h
#define RenderThemeChromiumFontProvider_h
-#include "CSSValueKeywords.h"
-
-namespace WTF {
-class String;
-}
+#include "core/CSSValueKeywords.h"
namespace WebCore {
@@ -42,7 +38,7 @@ public:
static void setDefaultFontSize(int);
protected:
- static const WTF::String& defaultGUIFont();
+ static const WTF::AtomicString& defaultGUIFont();
static float s_defaultFontSize;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp
index 3d1d0260d0a..35e16714738 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "core/rendering/RenderThemeChromiumFontProvider.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "platform/fonts/FontDescription.h"
#include "wtf/StdLibExtras.h"
@@ -65,7 +65,7 @@ void RenderThemeChromiumFontProvider::systemFont(CSSValueID valueID, FontDescrip
fontDescription.setIsAbsoluteSize(true);
fontDescription.setGenericFamily(FontDescription::NoFamily);
fontDescription.setWeight(FontWeightNormal);
- fontDescription.setItalic(false);
+ fontDescription.setStyle(FontStyleNormal);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp
index 18305cc31d6..0db04403219 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp
@@ -26,13 +26,12 @@
#include "config.h"
#include "core/rendering/RenderThemeChromiumFontProvider.h"
-#include <windows.h>
-
-#include "CSSValueKeywords.h"
+#include "core/CSSValueKeywords.h"
#include "platform/fonts/FontDescription.h"
#include "platform/win/HWndDC.h"
#include "platform/win/SystemInfo.h"
#include "wtf/text/WTFString.h"
+#include <windows.h>
#define SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(structName, member) \
offsetof(structName, member) + \
@@ -175,7 +174,7 @@ void RenderThemeChromiumFontProvider::systemFont(CSSValueID valueID, FontDescrip
cachedDesc->setGenericFamily(FontDescription::NoFamily);
cachedDesc->setSpecifiedSize(fontSize);
cachedDesc->setWeight(FontWeightNormal);
- cachedDesc->setItalic(false);
+ cachedDesc->setStyle(FontStyleNormal);
}
fontDescription = *cachedDesc;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.h b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.h
index 371ecc6c717..3dc8de4841d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.h
@@ -32,7 +32,7 @@ OBJC_CLASS WebCoreRenderThemeNotificationObserver;
namespace WebCore {
-class RenderThemeChromiumMac : public RenderTheme {
+class RenderThemeChromiumMac FINAL : public RenderTheme {
public:
static PassRefPtr<RenderTheme> create();
@@ -44,10 +44,11 @@ public:
virtual void adjustRepaintRect(const RenderObject*, IntRect&) OVERRIDE;
- virtual bool isControlStyled(const RenderStyle*, const CachedUAStyle&) const OVERRIDE;
+ virtual bool isControlStyled(const RenderStyle*, const CachedUAStyle*) const OVERRIDE;
virtual Color platformActiveSelectionBackgroundColor() const OVERRIDE;
virtual Color platformInactiveSelectionBackgroundColor() const OVERRIDE;
+ virtual Color platformActiveSelectionForegroundColor() const OVERRIDE;
virtual Color platformActiveListBoxSelectionBackgroundColor() const OVERRIDE;
virtual Color platformActiveListBoxSelectionForegroundColor() const OVERRIDE;
virtual Color platformInactiveListBoxSelectionBackgroundColor() const OVERRIDE;
@@ -88,41 +89,39 @@ public:
virtual Color systemColor(CSSValueID) const OVERRIDE;
+ virtual bool supportsSelectionForegroundColors() const OVERRIDE { return false; }
+
protected:
RenderThemeChromiumMac();
virtual ~RenderThemeChromiumMac();
- virtual bool supportsSelectionForegroundColors() const OVERRIDE { return false; }
-
- virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&);
-
- virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&);
- virtual void adjustMenuListStyle(RenderStyle*, Element*) const;
+ virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&);
- virtual void adjustMenuListButtonStyle(RenderStyle*, Element*) const;
+ virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual void adjustMenuListStyle(RenderStyle*, Element*) const OVERRIDE;
- virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual void adjustMenuListButtonStyle(RenderStyle*, Element*) const OVERRIDE;
- virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&);
- virtual void adjustSearchFieldStyle(RenderStyle*, Element*) const;
+ virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual void adjustSearchFieldCancelButtonStyle(RenderStyle*, Element*) const;
- virtual bool paintSearchFieldCancelButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual void adjustSearchFieldStyle(RenderStyle*, Element*) const OVERRIDE;
- virtual void adjustSearchFieldDecorationStyle(RenderStyle*, Element*) const;
- virtual bool paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustSearchFieldCancelButtonStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSearchFieldCancelButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual void adjustSearchFieldResultsDecorationStyle(RenderStyle*, Element*) const;
- virtual bool paintSearchFieldResultsDecoration(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustSearchFieldDecorationStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSearchFieldDecoration(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool supportsClosedCaptioning() const { return true; }
+ virtual void adjustSearchFieldResultsDecorationStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSearchFieldResultsDecoration(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
private:
virtual String fileListNameForWidth(Locale&, const FileList*, const Font&, int width) const OVERRIDE;
@@ -151,7 +150,6 @@ private:
const IntSize* popupButtonSizes() const;
const int* popupButtonMargins() const;
const int* popupButtonPadding(NSControlSize) const;
- void paintMenuListButtonGradients(RenderObject*, const PaintInfo&, const IntRect&);
const IntSize* menuListSizes() const;
const IntSize* searchFieldSizes() const;
@@ -174,21 +172,20 @@ private:
protected:
virtual void adjustMediaSliderThumbSize(RenderStyle*) const;
- virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
- virtual String extraFullScreenStyleSheet();
-
- virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
- virtual bool usesVerticalVolumeSlider() const { return false; }
- virtual String formatMediaControlsTime(float time) const;
- virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const;
- virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaOverlayPlayButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual String extraFullScreenStyleSheet() OVERRIDE;
+
+ virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual String formatMediaControlsTime(float time) const OVERRIDE;
+ virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const OVERRIDE;
+ virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
// Controls color values returned from platformFocusRingColor(). systemColor() will be used when false.
bool usesTestModeFocusRingColor() const;
@@ -199,7 +196,7 @@ protected:
private:
virtual void updateActiveState(NSCell*, const RenderObject*);
- virtual String extraDefaultStyleSheet();
+ virtual String extraDefaultStyleSheet() OVERRIDE;
virtual bool shouldShowPlaceholderWhenFocused() const OVERRIDE;
mutable RetainPtr<NSPopUpButtonCell> m_popupButton;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.mm b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.mm
index 82f39e25601..a25be5a7c89 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.mm
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumMac.mm
@@ -34,7 +34,6 @@
#import "core/html/TimeRanges.h"
#import "core/html/shadow/MediaControlElements.h"
#import "core/frame/FrameView.h"
-#import "core/platform/mac/ThemeMac.h"
#import "core/rendering/PaintInfo.h"
#import "core/rendering/RenderLayer.h"
#import "core/rendering/RenderMedia.h"
@@ -50,9 +49,9 @@
#import "platform/graphics/GraphicsContextStateSaver.h"
#import "platform/graphics/Image.h"
#import "platform/graphics/ImageBuffer.h"
-#import "platform/graphics/cg/GraphicsContextCG.h"
#import "platform/mac/ColorMac.h"
#import "platform/mac/LocalCurrentGraphicsContext.h"
+#import "platform/mac/ThemeMac.h"
#import "platform/mac/WebCoreNSCellExtras.h"
#import "platform/text/PlatformLocale.h"
#import "platform/text/StringTruncator.h"
@@ -194,6 +193,11 @@ Color RenderThemeChromiumMac::platformInactiveSelectionBackgroundColor() const
return Color(static_cast<int>(255.0 * [color redComponent]), static_cast<int>(255.0 * [color greenComponent]), static_cast<int>(255.0 * [color blueComponent]));
}
+Color RenderThemeChromiumMac::platformActiveSelectionForegroundColor() const
+{
+ return Color::black;
+}
+
Color RenderThemeChromiumMac::platformActiveListBoxSelectionBackgroundColor() const
{
NSColor* color = [[NSColor alternateSelectedControlColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace];
@@ -212,8 +216,9 @@ Color RenderThemeChromiumMac::platformInactiveListBoxSelectionForegroundColor()
Color RenderThemeChromiumMac::platformFocusRingColor() const
{
+ static const RGBA32 oldAquaFocusRingColor = 0xFF7DADD9;
if (usesTestModeFocusRingColor())
- return oldAquaFocusRingColor();
+ return oldAquaFocusRingColor;
return systemColor(CSSValueWebkitFocusRingColor);
}
@@ -306,7 +311,7 @@ void RenderThemeChromiumMac::systemFont(CSSValueID cssValueId, FontDescription&
cachedDesc->firstFamily().setFamily([font webCoreFamilyName]);
cachedDesc->setSpecifiedSize([font pointSize]);
cachedDesc->setWeight(toFontWeight([fontManager weightOfFont:font]));
- cachedDesc->setItalic([fontManager traitsOfFont:font] & NSItalicFontMask);
+ cachedDesc->setStyle([fontManager traitsOfFont:font] & NSItalicFontMask ? FontStyleItalic : FontStyleNormal);
}
fontDescription = *cachedDesc;
}
@@ -394,6 +399,7 @@ Color RenderThemeChromiumMac::systemColor(CSSValueID cssValueId) const
}
Color color;
+ bool needsFallback = false;
switch (cssValueId) {
case CSSValueActiveborder:
color = convertNSColorToColor([NSColor keyboardFocusIndicatorColor]);
@@ -406,6 +412,7 @@ Color RenderThemeChromiumMac::systemColor(CSSValueID cssValueId) const
break;
case CSSValueBackground:
// Use theme independent default
+ needsFallback = true;
break;
case CSSValueButtonface:
// We use this value instead of NSColor's controlColor to avoid website incompatibilities.
@@ -491,22 +498,23 @@ Color RenderThemeChromiumMac::systemColor(CSSValueID cssValueId) const
color = convertNSColorToColor([NSColor windowFrameTextColor]);
break;
default:
+ needsFallback = true;
break;
}
- if (!color.isValid())
+ if (needsFallback)
color = RenderTheme::systemColor(cssValueId);
- if (color.isValid())
- m_systemColorCache.set(cssValueId, color.rgb());
+ m_systemColorCache.set(cssValueId, color.rgb());
return color;
}
-bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const CachedUAStyle& uaStyle) const
+bool RenderThemeChromiumMac::isControlStyled(const RenderStyle* style, const CachedUAStyle* uaStyle) const
{
+ ASSERT(uaStyle);
if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart || style->appearance() == ListboxPart)
- return style->border() != uaStyle.border || style->boxShadow();
+ return style->border() != uaStyle->border || style->boxShadow();
// FIXME: This is horrible, but there is not much else that can be done. Menu lists cannot draw properly when
// scaled. They can't really draw properly when transformed either. We can't detect the transform case at style
@@ -733,7 +741,7 @@ void RenderThemeChromiumMac::setFontFromControlSize(RenderStyle* style, NSContro
style->setLineHeight(RenderStyle::initialLineHeight());
if (style->setFontDescription(fontDescription))
- style->font().update(0);
+ style->font().update(nullptr);
}
NSControlSize RenderThemeChromiumMac::controlSizeForSystemFont(RenderStyle* style) const
@@ -903,7 +911,7 @@ bool RenderThemeChromiumMac::paintMenuList(RenderObject* o, const PaintInfo& pai
inflatedRect.setWidth(inflatedRect.width() / zoomLevel);
inflatedRect.setHeight(inflatedRect.height() / zoomLevel);
paintInfo.context->translate(inflatedRect.x(), inflatedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
+ paintInfo.context->scale(zoomLevel, zoomLevel);
paintInfo.context->translate(-inflatedRect.x(), -inflatedRect.y());
}
@@ -1096,10 +1104,11 @@ bool RenderThemeChromiumMac::paintProgressBar(RenderObject* renderObject, const
if (!renderProgress->style()->isLeftToRightDirection()) {
paintInfo.context->translate(2 * inflatedRect.x() + inflatedRect.width(), 0);
- paintInfo.context->scale(FloatSize(-1, 1));
+ paintInfo.context->scale(-1, 1);
}
- paintInfo.context->drawImageBuffer(imageBuffer.get(), inflatedRect.location());
+ paintInfo.context->drawImageBuffer(imageBuffer.get(),
+ FloatRect(inflatedRect.location(), imageBuffer->size()));
return false;
}
@@ -1115,112 +1124,12 @@ const int styledPopupPaddingLeft = 8;
const int styledPopupPaddingTop = 1;
const int styledPopupPaddingBottom = 2;
-static void TopGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
- static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f };
- static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f };
- float a = inData[0];
- int i = 0;
- for (i = 0; i < 4; i++)
- outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-static void BottomGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
- static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
- static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f };
- float a = inData[0];
- int i = 0;
- for (i = 0; i < 4; i++)
- outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-static void MainGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
- static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f };
- static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
- float a = inData[0];
- int i = 0;
- for (i = 0; i < 4; i++)
- outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
- if (r.isEmpty())
- return;
-
- ContextContainer cgContextContainer(paintInfo.context);
- CGContextRef context = cgContextContainer.context();
-
- GraphicsContextStateSaver stateSaver(*paintInfo.context);
-
- RoundedRect border = o->style()->getRoundedBorderFor(r, o->view());
- int radius = border.radii().topLeft().width();
-
- CGColorSpaceRef cspace = deviceRGBColorSpaceRef();
-
- FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f);
- struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL };
- RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks));
- RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.maxY()), topFunction.get(), false, false));
-
- FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f);
- struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL };
- RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks));
- RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(), bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.maxY()), bottomFunction.get(), false, false));
-
- struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL };
- RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
- RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x(), r.maxY()), mainFunction.get(), false, false));
-
- RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(), r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false));
-
- RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.maxX(), r.y()), CGPointMake(r.maxX() - radius, r.y()), mainFunction.get(), false, false));
-
- {
- GraphicsContextStateSaver stateSaver(*paintInfo.context);
- CGContextClipToRect(context, r);
- paintInfo.context->clipRoundedRect(border);
- context = cgContextContainer.context();
- CGContextDrawShading(context, mainShading.get());
- }
-
- {
- GraphicsContextStateSaver stateSaver(*paintInfo.context);
- CGContextClipToRect(context, topGradient);
- paintInfo.context->clipRoundedRect(RoundedRect(enclosingIntRect(topGradient), border.radii().topLeft(), border.radii().topRight(), IntSize(), IntSize()));
- context = cgContextContainer.context();
- CGContextDrawShading(context, topShading.get());
- }
-
- if (!bottomGradient.isEmpty()) {
- GraphicsContextStateSaver stateSaver(*paintInfo.context);
- CGContextClipToRect(context, bottomGradient);
- paintInfo.context->clipRoundedRect(RoundedRect(enclosingIntRect(bottomGradient), IntSize(), IntSize(), border.radii().bottomLeft(), border.radii().bottomRight()));
- context = cgContextContainer.context();
- CGContextDrawShading(context, bottomShading.get());
- }
-
- {
- GraphicsContextStateSaver stateSaver(*paintInfo.context);
- CGContextClipToRect(context, r);
- paintInfo.context->clipRoundedRect(border);
- context = cgContextContainer.context();
- CGContextDrawShading(context, leftShading.get());
- CGContextDrawShading(context, rightShading.get());
- }
-}
-
bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(),
r.y() + o->style()->borderTopWidth(),
r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(),
r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth());
- // Draw the gradients to give the styled popup menu a button appearance
- paintMenuListButtonGradients(o, paintInfo, bounds);
-
// Since we actually know the size of the control here, we restrict the font scale to make sure the arrows will fit vertically in the bounds
float fontScale = min(o->style()->fontSize() / baseFontSize, bounds.height() / (baseArrowHeight * 2 + baseSpaceBetweenArrows));
float centerY = bounds.y() + bounds.height() / 2.0f;
@@ -1252,24 +1161,6 @@ bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const PaintInf
// Draw the bottom arrow
paintInfo.context->drawConvexPolygon(3, arrow2, true);
-
- Color leftSeparatorColor(0, 0, 0, 40);
- Color rightSeparatorColor(255, 255, 255, 40);
-
- // FIXME: Should the separator thickness and space be scaled up by fontScale?
- int separatorSpace = 2; // Deliberately ignores zoom since it looks nicer if it stays thin.
- int leftEdgeOfSeparator = static_cast<int>(leftEdge - arrowPaddingLeft * o->style()->effectiveZoom()); // FIXME: Round?
-
- // Draw the separator to the left of the arrows
- paintInfo.context->setStrokeThickness(1.0f); // Deliberately ignores zoom since it looks nicer if it stays thin.
- paintInfo.context->setStrokeStyle(SolidStroke);
- paintInfo.context->setStrokeColor(leftSeparatorColor);
- paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
- IntPoint(leftEdgeOfSeparator, bounds.maxY()));
-
- paintInfo.context->setStrokeColor(rightSeparatorColor);
- paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
- IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.maxY()));
return false;
}
@@ -1423,7 +1314,7 @@ bool RenderThemeChromiumMac::paintSliderTrack(RenderObject* o, const PaintInfo&
GraphicsContextStateSaver stateSaver(*paintInfo.context);
if (zoomLevel != 1) {
paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
+ paintInfo.context->scale(zoomLevel, zoomLevel);
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -1488,7 +1379,7 @@ bool RenderThemeChromiumMac::paintSliderThumb(RenderObject* o, const PaintInfo&
FloatRect unzoomedRect(r.x(), r.y(), sliderThumbWidth, sliderThumbHeight);
if (zoomLevel != 1.0f) {
paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
+ paintInfo.context->scale(zoomLevel, zoomLevel);
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -1573,7 +1464,7 @@ bool RenderThemeChromiumMac::paintSearchField(RenderObject* o, const PaintInfo&
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
+ paintInfo.context->scale(zoomLevel, zoomLevel);
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -1656,6 +1547,8 @@ void RenderThemeChromiumMac::adjustSearchFieldStyle(RenderStyle* style, Element*
bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
+ if (!o->node())
+ return false;
Element* input = o->node()->shadowHost();
if (!input)
input = toElement(o->node());
@@ -1671,7 +1564,7 @@ bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
+ paintInfo.context->scale(zoomLevel, zoomLevel);
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -1754,6 +1647,8 @@ void RenderThemeChromiumMac::adjustSearchFieldResultsDecorationStyle(RenderStyle
bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
{
+ if (!o->node())
+ return false;
Node* input = o->node()->shadowHost();
if (!input)
input = o->node();
@@ -1768,7 +1663,7 @@ bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o,
unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
paintInfo.context->translate(unzoomedRect.x(), unzoomedRect.y());
- paintInfo.context->scale(FloatSize(zoomLevel, zoomLevel));
+ paintInfo.context->scale(zoomLevel, zoomLevel);
paintInfo.context->translate(-unzoomedRect.x(), -unzoomedRect.y());
}
@@ -1940,6 +1835,11 @@ bool RenderThemeChromiumMac::paintMediaPlayButton(RenderObject* object, const Pa
return RenderMediaControls::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect);
}
+bool RenderThemeChromiumMac::paintMediaOverlayPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ return RenderMediaControls::paintMediaControlsPart(MediaOverlayPlayButton, object, paintInfo, rect);
+}
+
bool RenderThemeChromiumMac::paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
{
return RenderMediaControls::paintMediaControlsPart(MediaMuteButton, object, paintInfo, rect);
@@ -1959,7 +1859,8 @@ String RenderThemeChromiumMac::extraFullScreenStyleSheet()
String RenderThemeChromiumMac::extraDefaultStyleSheet()
{
return RenderTheme::extraDefaultStyleSheet() +
- String(themeChromiumUserAgentStyleSheet, sizeof(themeChromiumUserAgentStyleSheet));
+ String(themeChromiumUserAgentStyleSheet, sizeof(themeChromiumUserAgentStyleSheet)) +
+ String(themeMacUserAgentStyleSheet, sizeof(themeMacUserAgentStyleSheet));
}
bool RenderThemeChromiumMac::paintMediaVolumeSliderContainer(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.cpp
index 2a7e3c2b232..f836738a38c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "core/rendering/RenderThemeChromiumSkia.h"
-#include "UserAgentStyleSheets.h"
+#include "core/UserAgentStyleSheets.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderBox.h"
#include "core/rendering/RenderMediaControls.h"
@@ -91,11 +91,6 @@ bool RenderThemeChromiumSkia::supportsFocusRing(const RenderStyle* style) const
return false;
}
-bool RenderThemeChromiumSkia::supportsClosedCaptioning() const
-{
- return true;
-}
-
Color RenderThemeChromiumSkia::platformActiveSelectionBackgroundColor() const
{
return Color(0x1e, 0x90, 0xff);
@@ -227,6 +222,8 @@ IntRect RenderThemeChromiumSkia::convertToPaintingRect(RenderObject* inputRender
bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* cancelButtonObject, const PaintInfo& paintInfo, const IntRect& r)
{
// Get the renderer of <input> element.
+ if (!cancelButtonObject->node())
+ return false;
Node* input = cancelButtonObject->node()->shadowHost();
RenderObject* baseRenderer = input ? input->renderer() : cancelButtonObject;
if (!baseRenderer->isBox())
@@ -270,6 +267,8 @@ void RenderThemeChromiumSkia::adjustSearchFieldResultsDecorationStyle(RenderStyl
bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* magnifierObject, const PaintInfo& paintInfo, const IntRect& r)
{
// Get the renderer of <input> element.
+ if (!magnifierObject->node())
+ return false;
Node* input = magnifierObject->node()->shadowHost();
RenderObject* baseRenderer = input ? input->renderer() : magnifierObject;
if (!baseRenderer->isBox())
@@ -327,6 +326,11 @@ bool RenderThemeChromiumSkia::paintMediaPlayButton(RenderObject* object, const P
return RenderMediaControls::paintMediaControlsPart(MediaPlayButton, object, paintInfo, rect);
}
+bool RenderThemeChromiumSkia::paintMediaOverlayPlayButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
+{
+ return RenderMediaControls::paintMediaControlsPart(MediaOverlayPlayButton, object, paintInfo, rect);
+}
+
bool RenderThemeChromiumSkia::paintMediaMuteButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
{
return RenderMediaControls::paintMediaControlsPart(MediaMuteButton, object, paintInfo, rect);
@@ -473,7 +477,7 @@ RenderThemeChromiumSkia::DirectionFlippingScope::DirectionFlippingScope(RenderOb
return;
m_paintInfo.context->save();
m_paintInfo.context->translate(2 * rect.x() + rect.width(), 0);
- m_paintInfo.context->scale(FloatSize(-1, 1));
+ m_paintInfo.context->scale(-1, 1);
}
RenderThemeChromiumSkia::DirectionFlippingScope::~DirectionFlippingScope()
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.h b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.h
index f3550c7aca0..c47eff77872 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumSkia.h
@@ -39,8 +39,8 @@ public:
RenderThemeChromiumSkia();
virtual ~RenderThemeChromiumSkia();
- virtual String extraDefaultStyleSheet();
- virtual String extraQuirksStyleSheet();
+ virtual String extraDefaultStyleSheet() OVERRIDE;
+ virtual String extraQuirksStyleSheet() OVERRIDE;
virtual Color platformTapHighlightColor() const OVERRIDE
{
@@ -48,57 +48,57 @@ public:
}
// A method asking if the theme's controls actually care about redrawing when hovered.
- virtual bool supportsHover(const RenderStyle*) const;
+ virtual bool supportsHover(const RenderStyle*) const OVERRIDE FINAL;
// A method asking if the theme is able to draw the focus ring.
- virtual bool supportsFocusRing(const RenderStyle*) const;
+ virtual bool supportsFocusRing(const RenderStyle*) const OVERRIDE;
- virtual bool supportsClosedCaptioning() const OVERRIDE;
// The platform selection color.
- virtual Color platformActiveSelectionBackgroundColor() const;
- virtual Color platformInactiveSelectionBackgroundColor() const;
- virtual Color platformActiveSelectionForegroundColor() const;
- virtual Color platformInactiveSelectionForegroundColor() const;
- virtual Color platformFocusRingColor() const;
+ virtual Color platformActiveSelectionBackgroundColor() const OVERRIDE;
+ virtual Color platformInactiveSelectionBackgroundColor() const OVERRIDE;
+ virtual Color platformActiveSelectionForegroundColor() const OVERRIDE;
+ virtual Color platformInactiveSelectionForegroundColor() const OVERRIDE;
+ virtual Color platformFocusRingColor() const OVERRIDE;
// To change the blink interval, override caretBlinkIntervalInternal instead of this one so that we may share layout test code an intercepts.
- virtual double caretBlinkInterval() const;
+ virtual double caretBlinkInterval() const OVERRIDE;
// System fonts.
- virtual void systemFont(CSSValueID, FontDescription&) const;
+ virtual void systemFont(CSSValueID, FontDescription&) const OVERRIDE;
- virtual int minimumMenuListSize(RenderStyle*) const;
+ virtual int minimumMenuListSize(RenderStyle*) const OVERRIDE;
- virtual void setCheckboxSize(RenderStyle*) const;
+ virtual void setCheckboxSize(RenderStyle*) const OVERRIDE;
- virtual void setRadioSize(RenderStyle*) const;
+ virtual void setRadioSize(RenderStyle*) const OVERRIDE;
- virtual void adjustButtonStyle(RenderStyle*, Element*) const;
+ virtual void adjustButtonStyle(RenderStyle*, Element*) const OVERRIDE;
- virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintTextArea(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual void adjustSearchFieldStyle(RenderStyle*, Element*) const;
- virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustSearchFieldStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual void adjustSearchFieldCancelButtonStyle(RenderStyle*, Element*) const;
- virtual bool paintSearchFieldCancelButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustSearchFieldCancelButtonStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSearchFieldCancelButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual void adjustSearchFieldDecorationStyle(RenderStyle*, Element*) const;
+ virtual void adjustSearchFieldDecorationStyle(RenderStyle*, Element*) const OVERRIDE;
- virtual void adjustSearchFieldResultsDecorationStyle(RenderStyle*, Element*) const;
- virtual bool paintSearchFieldResultsDecoration(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustSearchFieldResultsDecorationStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintSearchFieldResultsDecoration(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
- virtual void adjustSliderThumbSize(RenderStyle*, Element*) const;
- virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&);
- virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&);
- virtual String formatMediaControlsTime(float time) const;
- virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const;
- virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual void adjustSliderThumbSize(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaToggleClosedCaptionsButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaPlayButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaOverlayPlayButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual bool paintMediaMuteButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
+ virtual String formatMediaControlsTime(float time) const OVERRIDE;
+ virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const OVERRIDE;
+ virtual bool paintMediaFullscreenButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
// MenuList refers to an unstyled menulist (meaning a menulist without
// background-color or border set) and MenuListButton refers to a styled
@@ -109,22 +109,18 @@ public:
// In short, we either go down the MenuList code path or the MenuListButton
// codepath. We never go down both. And in both cases, they render the
// entire menulist.
- virtual void adjustMenuListStyle(RenderStyle*, Element*) const;
- virtual void adjustMenuListButtonStyle(RenderStyle*, Element*) const;
- virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual void adjustMenuListStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual void adjustMenuListButtonStyle(RenderStyle*, Element*) const OVERRIDE;
+ virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const;
- virtual double animationDurationForProgressBar(RenderProgress*) const;
+ virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const OVERRIDE;
+ virtual double animationDurationForProgressBar(RenderProgress*) const OVERRIDE;
// These methods define the padding for the MenuList's inner block.
- virtual int popupInternalPaddingLeft(RenderStyle*) const;
- virtual int popupInternalPaddingRight(RenderStyle*) const;
- virtual int popupInternalPaddingTop(RenderStyle*) const;
- virtual int popupInternalPaddingBottom(RenderStyle*) const;
-
- // Media controls
- virtual bool hasOwnDisabledStateHandlingFor(ControlPart) const { return true; }
- virtual bool usesVerticalVolumeSlider() const { return false; }
+ virtual int popupInternalPaddingLeft(RenderStyle*) const OVERRIDE;
+ virtual int popupInternalPaddingRight(RenderStyle*) const OVERRIDE;
+ virtual int popupInternalPaddingTop(RenderStyle*) const OVERRIDE;
+ virtual int popupInternalPaddingBottom(RenderStyle*) const OVERRIDE;
// Provide a way to pass the default font size from the Settings object
// to the render theme. FIXME: http://b/1129186 A cleaner way would be
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumWin.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumWin.cpp
deleted file mode 100644
index b1224074607..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumWin.cpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * This file is part of the WebKit project.
- *
- * Copyright (C) 2006 Apple Computer, Inc.
- * Copyright (C) 2008, 2009 Google, Inc.
- * Copyright (C) 2009 Kenneth Rohde Christiansen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#include "config.h"
-#include "core/rendering/RenderThemeChromiumWin.h"
-
-#include <windows.h>
-#include <uxtheme.h>
-#include <vssym32.h>
-
-#include "CSSValueKeywords.h"
-#include "HTMLNames.h"
-#include "core/html/HTMLMediaElement.h"
-#include "core/html/shadow/MediaControlElements.h"
-#include "core/rendering/PaintInfo.h"
-#include "core/rendering/RenderBox.h"
-#include "core/rendering/RenderProgress.h"
-#include "core/rendering/RenderSlider.h"
-#include "platform/LayoutTestSupport.h"
-#include "platform/fonts/FontSelector.h"
-#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/win/TransparencyWin.h"
-#include "platform/scroll/ScrollbarTheme.h"
-#include "platform/win/SystemInfo.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebColor.h"
-#include "public/platform/WebRect.h"
-#include "public/platform/win/WebThemeEngine.h"
-#include "wtf/CurrentTime.h"
-#include "wtf/StdLibExtras.h"
-
-// FIXME: This dependency should eventually be removed.
-#include <skia/ext/skia_utils_win.h>
-
-namespace WebCore {
-
-// The standard width for the menu list drop-down button when run under
-// layout test mode. Use the value that's currently captured in most baselines.
-static const int kStandardMenuListButtonWidth = 17;
-
-namespace {
-// We must not create multiple ThemePainter instances.
-class ThemePainter {
-public:
- ThemePainter(GraphicsContext* context, const IntRect& r)
- {
-#ifndef NDEBUG
- ASSERT(!s_hasInstance);
- s_hasInstance = true;
-#endif
- TransparencyWin::TransformMode transformMode = getTransformMode(context->getCTM());
- m_helper.init(context, getLayerMode(context, transformMode), transformMode, r);
-
- if (!m_helper.context()) {
- // TransparencyWin doesn't have well-defined copy-ctor nor op=()
- // so we re-initialize it instead of assigning a fresh istance.
- // On the reinitialization, we fallback to use NoLayer mode.
- // Note that the original initialization failure can be caused by
- // a failure of an internal buffer allocation and NoLayer mode
- // does not have such buffer allocations.
- m_helper.~TransparencyWin();
- new (&m_helper) TransparencyWin();
- m_helper.init(context, TransparencyWin::NoLayer, transformMode, r);
- }
- }
-
- ~ThemePainter()
- {
- m_helper.composite();
-#ifndef NDEBUG
- s_hasInstance = false;
-#endif
- }
-
- GraphicsContext* context() { return m_helper.context(); }
- const IntRect& drawRect() { return m_helper.drawRect(); }
-
-private:
-
- static TransparencyWin::LayerMode getLayerMode(GraphicsContext* context, TransparencyWin::TransformMode transformMode)
- {
- if (!context->isCertainlyOpaque()) // Might have transparent background.
- return TransparencyWin::WhiteLayer;
- if (context->canvas()->isDrawingToLayer()) // Needs antialiasing help.
- return TransparencyWin::OpaqueCompositeLayer;
- // Nothing interesting.
- return transformMode == TransparencyWin::KeepTransform ? TransparencyWin::NoLayer : TransparencyWin::OpaqueCompositeLayer;
- }
-
- static TransparencyWin::TransformMode getTransformMode(const AffineTransform& matrix)
- {
- if (matrix.b() || matrix.c()) // Skew.
- return TransparencyWin::Untransform;
- if (matrix.a() != 1.0 || matrix.d() != 1.0) // Scale.
- return TransparencyWin::ScaleTransform;
- // Nothing interesting.
- return TransparencyWin::KeepTransform;
- }
-
- TransparencyWin m_helper;
-#ifndef NDEBUG
- static bool s_hasInstance;
-#endif
-};
-
-#ifndef NDEBUG
-bool ThemePainter::s_hasInstance = false;
-#endif
-
-} // namespace
-
-// Internal static helper functions. We don't put them in an anonymous
-// namespace so they have easier access to the WebCore namespace.
-
-static bool supportsFocus(ControlPart appearance)
-{
- switch (appearance) {
- case SquareButtonPart:
- case PushButtonPart:
- case ButtonPart:
- case SearchFieldPart:
- case TextFieldPart:
- case TextAreaPart:
- return true;
- }
- return false;
-}
-
-static double querySystemBlinkInterval(double defaultInterval)
-{
- UINT blinkTime = GetCaretBlinkTime();
- if (!blinkTime)
- return defaultInterval;
- if (blinkTime == INFINITE)
- return 0;
- return blinkTime / 1000.0;
-}
-
-PassRefPtr<RenderTheme> RenderThemeChromiumWin::create()
-{
- return adoptRef(new RenderThemeChromiumWin);
-}
-
-RenderTheme& RenderTheme::theme()
-{
- DEFINE_STATIC_REF(RenderTheme, renderTheme, (RenderThemeChromiumWin::create()));
- return *renderTheme;
-}
-
-bool RenderThemeChromiumWin::supportsFocusRing(const RenderStyle* style) const
-{
- // Let webkit draw one of its halo rings around any focused element,
- // except push buttons. For buttons we use the windows PBS_DEFAULTED
- // styling to give it a blue border.
- return style->appearance() == ButtonPart
- || style->appearance() == PushButtonPart
- || style->appearance() == SquareButtonPart;
-}
-
-Color RenderThemeChromiumWin::platformActiveSelectionBackgroundColor() const
-{
- if (isRunningLayoutTest())
- return Color(0x00, 0x00, 0xff); // Royal blue.
- COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
- return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
-}
-
-Color RenderThemeChromiumWin::platformInactiveSelectionBackgroundColor() const
-{
- if (isRunningLayoutTest())
- return Color(0x99, 0x99, 0x99); // Medium gray.
- COLORREF color = GetSysColor(COLOR_GRAYTEXT);
- return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
-}
-
-Color RenderThemeChromiumWin::platformActiveSelectionForegroundColor() const
-{
- if (isRunningLayoutTest())
- return Color(0xff, 0xff, 0xcc); // Pale yellow.
- COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
- return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
-}
-
-Color RenderThemeChromiumWin::platformInactiveSelectionForegroundColor() const
-{
- return Color::white;
-}
-
-Color RenderThemeChromiumWin::platformActiveTextSearchHighlightColor() const
-{
- return Color(0xff, 0x96, 0x32); // Orange.
-}
-
-Color RenderThemeChromiumWin::platformInactiveTextSearchHighlightColor() const
-{
- return Color(0xff, 0xff, 0x96); // Yellow.
-}
-
-// Map a CSSValue* system color to an index understood by GetSysColor().
-static int cssValueIdToSysColorIndex(int cssValueId)
-{
- switch (cssValueId) {
- case CSSValueActiveborder: return COLOR_ACTIVEBORDER;
- case CSSValueActivecaption: return COLOR_ACTIVECAPTION;
- case CSSValueAppworkspace: return COLOR_APPWORKSPACE;
- case CSSValueBackground: return COLOR_BACKGROUND;
- case CSSValueButtonface: return COLOR_BTNFACE;
- case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT;
- case CSSValueButtonshadow: return COLOR_BTNSHADOW;
- case CSSValueButtontext: return COLOR_BTNTEXT;
- case CSSValueCaptiontext: return COLOR_CAPTIONTEXT;
- case CSSValueGraytext: return COLOR_GRAYTEXT;
- case CSSValueHighlight: return COLOR_HIGHLIGHT;
- case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT;
- case CSSValueInactiveborder: return COLOR_INACTIVEBORDER;
- case CSSValueInactivecaption: return COLOR_INACTIVECAPTION;
- case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT;
- case CSSValueInfobackground: return COLOR_INFOBK;
- case CSSValueInfotext: return COLOR_INFOTEXT;
- case CSSValueMenu: return COLOR_MENU;
- case CSSValueMenutext: return COLOR_MENUTEXT;
- case CSSValueScrollbar: return COLOR_SCROLLBAR;
- case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW;
- case CSSValueThreedface: return COLOR_3DFACE;
- case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT;
- case CSSValueThreedlightshadow: return COLOR_3DLIGHT;
- case CSSValueThreedshadow: return COLOR_3DSHADOW;
- case CSSValueWindow: return COLOR_WINDOW;
- case CSSValueWindowframe: return COLOR_WINDOWFRAME;
- case CSSValueWindowtext: return COLOR_WINDOWTEXT;
- default: return -1; // Unsupported CSSValue
- }
-}
-
-Color RenderThemeChromiumWin::systemColor(CSSValueID cssValueId) const
-{
- int sysColorIndex = cssValueIdToSysColorIndex(cssValueId);
- if (isRunningLayoutTest() || (sysColorIndex == -1))
- return RenderTheme::systemColor(cssValueId);
-
- COLORREF color = GetSysColor(sysColorIndex);
- return Color(GetRValue(color), GetGValue(color), GetBValue(color));
-}
-
-IntSize RenderThemeChromiumWin::sliderTickSize() const
-{
- return IntSize(1, 3);
-}
-
-int RenderThemeChromiumWin::sliderTickOffsetFromTrackCenter() const
-{
- return 11;
-}
-
-void RenderThemeChromiumWin::adjustSliderThumbSize(RenderStyle* style, Element* element) const
-{
- // These sizes match what WinXP draws for various menus.
- const int sliderThumbAlongAxis = 11;
- const int sliderThumbAcrossAxis = 21;
- if (style->appearance() == SliderThumbHorizontalPart) {
- style->setWidth(Length(sliderThumbAlongAxis, Fixed));
- style->setHeight(Length(sliderThumbAcrossAxis, Fixed));
- } else if (style->appearance() == SliderThumbVerticalPart) {
- style->setWidth(Length(sliderThumbAcrossAxis, Fixed));
- style->setHeight(Length(sliderThumbAlongAxis, Fixed));
- } else
- RenderThemeChromiumSkia::adjustSliderThumbSize(style, element);
-}
-
-bool RenderThemeChromiumWin::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- return paintButton(o, i, r);
-}
-bool RenderThemeChromiumWin::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- return paintButton(o, i, r);
-}
-
-bool RenderThemeChromiumWin::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- const ThemeData& themeData = getThemeData(o);
-
- ThemePainter painter(i.context, r);
- blink::WebCanvas* canvas = painter.context()->canvas();
- blink::Platform::current()->themeEngine()->paintButton(canvas, themeData.m_part, themeData.m_state, themeData.m_classicState, blink::WebRect(painter.drawRect()));
- return false;
-}
-
-bool RenderThemeChromiumWin::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- return paintTextFieldInternal(o, i, r, true);
-}
-
-bool RenderThemeChromiumWin::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- const ThemeData& themeData = getThemeData(o);
-
- ThemePainter painter(i.context, r);
- blink::WebCanvas* canvas = painter.context()->canvas();
- blink::Platform::current()->themeEngine()->paintTrackbar(canvas, themeData.m_part, themeData.m_state, themeData.m_classicState, blink::WebRect(painter.drawRect()));
-
- paintSliderTicks(o, i, r);
-
- return false;
-}
-
-bool RenderThemeChromiumWin::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- const ThemeData& themeData = getThemeData(o);
-
- ThemePainter painter(i.context, r);
- blink::WebCanvas* canvas = painter.context()->canvas();
- blink::Platform::current()->themeEngine()->paintTrackbar(canvas, themeData.m_part, themeData.m_state, themeData.m_classicState, blink::WebRect(painter.drawRect()));
-
- return false;
-}
-
-static int menuListButtonWidth()
-{
- static int width = isRunningLayoutTest() ? kStandardMenuListButtonWidth :
- IntSize(blink::Platform::current()->themeEngine()->getSize(SBP_ARROWBTN)).width();
- return width;
-}
-
-// Used to paint unstyled menulists (i.e. with the default border)
-bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- if (!o->isBox())
- return false;
-
- const RenderBox* box = toRenderBox(o);
- int borderRight = box->borderRight();
- int borderLeft = box->borderLeft();
- int borderTop = box->borderTop();
- int borderBottom = box->borderBottom();
-
- // If all the borders are 0, then tell skia not to paint the border on the
- // textfield. FIXME: http://b/1210017 Figure out how to get Windows to not
- // draw individual borders and then pass that to skia so we can avoid
- // drawing any borders that are set to 0. For non-zero borders, we draw the
- // border, but webkit just draws over it.
- bool drawEdges = !(!borderRight && !borderLeft && !borderTop && !borderBottom);
-
- paintTextFieldInternal(o, i, r, drawEdges);
- return paintMenuListButton(o, i, r);
-}
-
-bool RenderThemeChromiumWin::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- if (!o->isBox())
- return false;
-
- const RenderBox* box = toRenderBox(o);
- // Take padding and border into account. If the MenuList is smaller than
- // the size of a button, make sure to shrink it appropriately and not put
- // its x position to the left of the menulist.
- const int buttonWidth = menuListButtonWidth();
- int spacingLeft = box->borderLeft() + box->paddingLeft();
- int spacingRight = box->borderRight() + box->paddingRight();
- int spacingTop = box->borderTop() + box->paddingTop();
- int spacingBottom = box->borderBottom() + box->paddingBottom();
-
- int buttonX;
- if (r.maxX() - r.x() < buttonWidth)
- buttonX = r.x();
- else
- buttonX = o->style()->direction() == LTR ? r.maxX() - spacingRight - buttonWidth : r.x() + spacingLeft;
-
- // Compute the rectangle of the button in the destination image.
- IntRect rect(buttonX,
- r.y() + spacingTop,
- std::min(buttonWidth, r.maxX() - r.x()),
- r.height() - (spacingTop + spacingBottom));
-
- // Get the correct theme data for a textfield and paint the menu.
- ThemePainter painter(i.context, rect);
- blink::WebCanvas* canvas = painter.context()->canvas();
- blink::Platform::current()->themeEngine()->paintMenuList(canvas, CP_DROPDOWNBUTTON, determineState(o), determineClassicState(o), blink::WebRect(painter.drawRect()));
- return false;
-}
-
-double RenderThemeChromiumWin::caretBlinkIntervalInternal() const
-{
- // This involves a system call, so we cache the result.
- static double blinkInterval = querySystemBlinkInterval(RenderTheme::caretBlinkInterval());
- return blinkInterval;
-}
-
-unsigned RenderThemeChromiumWin::determineState(RenderObject* o, ControlSubPart subPart)
-{
- unsigned result = TS_NORMAL;
- ControlPart appearance = o->style()->appearance();
- if (!isEnabled(o))
- result = TS_DISABLED;
- else if (isReadOnlyControl(o))
- result = (appearance == TextFieldPart || appearance == TextAreaPart || appearance == SearchFieldPart) ? ETS_READONLY : TS_DISABLED;
- // Active overrides hover and focused.
- else if (isPressed(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartPressed(o))
- result = TS_PRESSED;
- else if (supportsFocus(appearance) && isFocused(o))
- result = ETS_FOCUSED;
- else if (isHovered(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartHovered(o))
- result = TS_HOT;
-
- // CBS_UNCHECKED*: 1-4
- // CBS_CHECKED*: 5-8
- // CBS_MIXED*: 9-12
- if (isIndeterminate(o))
- result += 8;
- else if (isChecked(o))
- result += 4;
- return result;
-}
-
-unsigned RenderThemeChromiumWin::determineSliderThumbState(RenderObject* o)
-{
- unsigned result = TUS_NORMAL;
- if (!isEnabled(o))
- result = TUS_DISABLED;
- else if (supportsFocus(o->style()->appearance()) && isFocused(o))
- result = TUS_FOCUSED;
- else if (isPressed(o))
- result = TUS_PRESSED;
- else if (isHovered(o))
- result = TUS_HOT;
- return result;
-}
-
-unsigned RenderThemeChromiumWin::determineClassicState(RenderObject* o, ControlSubPart subPart)
-{
- unsigned result = 0;
-
- ControlPart part = o->style()->appearance();
-
- // Sliders are always in the normal state.
- if (part == SliderHorizontalPart || part == SliderVerticalPart)
- return result;
-
- // So are readonly text fields.
- if (isReadOnlyControl(o) && (part == TextFieldPart || part == TextAreaPart || part == SearchFieldPart))
- return result;
-
- if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
- if (!isEnabled(o))
- result = DFCS_INACTIVE;
- else if (isPressed(o)) // Active supersedes hover
- result = DFCS_PUSHED;
- else if (isHovered(o))
- result = DFCS_HOT;
- } else {
- if (!isEnabled(o) || isReadOnlyControl(o))
- result = DFCS_INACTIVE;
- // Active supersedes hover
- else if (isPressed(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartPressed(o))
- result = DFCS_PUSHED;
- else if (supportsFocus(part) && isFocused(o)) // So does focused
- result = 0;
- else if (isHovered(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartHovered(o))
- result = DFCS_HOT;
- // Classic theme can't represent indeterminate states. Use unchecked appearance.
- if (isChecked(o) && !isIndeterminate(o))
- result |= DFCS_CHECKED;
- }
- return result;
-}
-
-ThemeData RenderThemeChromiumWin::getThemeData(RenderObject* o, ControlSubPart subPart)
-{
- ThemeData result;
- switch (o->style()->appearance()) {
- case CheckboxPart:
- result.m_part = BP_CHECKBOX;
- result.m_state = determineState(o);
- result.m_classicState = DFCS_BUTTONCHECK;
- break;
- case RadioPart:
- result.m_part = BP_RADIOBUTTON;
- result.m_state = determineState(o);
- result.m_classicState = DFCS_BUTTONRADIO;
- break;
- case SquareButtonPart:
- case PushButtonPart:
- case ButtonPart:
- result.m_part = BP_PUSHBUTTON;
- result.m_state = determineState(o);
- result.m_classicState = DFCS_BUTTONPUSH;
- break;
- case SliderHorizontalPart:
- result.m_part = TKP_TRACK;
- result.m_state = TRS_NORMAL;
- break;
- case SliderVerticalPart:
- result.m_part = TKP_TRACKVERT;
- result.m_state = TRVS_NORMAL;
- break;
- case SliderThumbHorizontalPart:
- result.m_part = TKP_THUMBBOTTOM;
- result.m_state = determineSliderThumbState(o);
- break;
- case SliderThumbVerticalPart:
- result.m_part = TKP_THUMBVERT;
- result.m_state = determineSliderThumbState(o);
- break;
- case ListboxPart:
- case MenulistPart:
- case MenulistButtonPart:
- case SearchFieldPart:
- case TextFieldPart:
- case TextAreaPart:
- result.m_part = EP_EDITTEXT;
- result.m_state = determineState(o);
- break;
- case InnerSpinButtonPart:
- result.m_part = subPart == SpinButtonUp ? SPNP_UP : SPNP_DOWN;
- result.m_state = determineState(o, subPart);
- result.m_classicState = subPart == SpinButtonUp ? DFCS_SCROLLUP : DFCS_SCROLLDOWN;
- break;
- }
-
- result.m_classicState |= determineClassicState(o, subPart);
-
- return result;
-}
-
-bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o,
- const PaintInfo& i,
- const IntRect& r,
- bool drawEdges)
-{
- // Fallback to white if the specified color object is invalid.
- Color backgroundColor(Color::white);
- if (o->style()->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
- backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor);
-
- // If we have background-image, don't fill the content area to expose the
- // parent's background. Also, we shouldn't fill the content area if the
- // alpha of the color is 0. The API of Windows GDI ignores the alpha.
- //
- // Note that we should paint the content area white if we have neither the
- // background color nor background image explicitly specified to keep the
- // appearance of select element consistent with other browsers.
- bool fillContentArea = !o->style()->hasBackgroundImage() && backgroundColor.alpha();
-
- if (o->style()->hasBorderRadius()) {
- // If the style has rounded borders, setup the context to clip the
- // background (themed or filled) appropriately.
- // FIXME: make sure we do the right thing if css background-clip is set.
- i.context->save();
- i.context->clipRoundedRect(o->style()->getRoundedBorderFor(r));
- }
- {
- const ThemeData& themeData = getThemeData(o);
- ThemePainter painter(i.context, r);
- blink::WebCanvas* canvas = painter.context()->canvas();
- blink::Platform::current()->themeEngine()->paintTextField(canvas, themeData.m_part, themeData.m_state, themeData.m_classicState, blink::WebRect(painter.drawRect()), backgroundColor.rgb(), fillContentArea, drawEdges);
- // End of block commits the painter before restoring context.
- }
- if (o->style()->hasBorderRadius())
- i.context->restore();
- return false;
-}
-
-void RenderThemeChromiumWin::adjustInnerSpinButtonStyle(RenderStyle* style, Element*) const
-{
- int width = ScrollbarTheme::theme()->scrollbarThickness();
- style->setWidth(Length(width, Fixed));
- style->setMinWidth(Length(width, Fixed));
-}
-
-bool RenderThemeChromiumWin::paintInnerSpinButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
-{
- IntRect half = rect;
-
- // Need explicit blocks to avoid to create multiple ThemePainter instances.
- {
- half.setHeight(rect.height() / 2);
- const ThemeData& upThemeData = getThemeData(object, SpinButtonUp);
- ThemePainter upPainter(info.context, half);
- blink::WebCanvas* canvas = upPainter.context()->canvas();
- blink::Platform::current()->themeEngine()->paintSpinButton(canvas, upThemeData.m_part, upThemeData.m_state, upThemeData.m_classicState, blink::WebRect(upPainter.drawRect()));
- }
-
- {
- half.setY(rect.y() + rect.height() / 2);
- const ThemeData& downThemeData = getThemeData(object, SpinButtonDown);
- ThemePainter downPainter(info.context, half);
- blink::WebCanvas* canvas = downPainter.context()->canvas();
- blink::Platform::current()->themeEngine()->paintSpinButton(canvas, downThemeData.m_part, downThemeData.m_state, downThemeData.m_classicState, blink::WebRect(downPainter.drawRect()));
- }
- return false;
-}
-
-// MSDN says that update intervals for the bar is 30ms.
-// http://msdn.microsoft.com/en-us/library/bb760842(v=VS.85).aspx
-static const double progressAnimationFrameRate = 0.033;
-
-double RenderThemeChromiumWin::animationRepeatIntervalForProgressBar(RenderProgress*) const
-{
- return progressAnimationFrameRate;
-}
-
-double RenderThemeChromiumWin::animationDurationForProgressBar(RenderProgress* renderProgress) const
-{
- // On Chromium Windows port, animationProgress() and associated values aren't used.
- // So here we can return arbitrary positive value.
- return progressAnimationFrameRate;
-}
-
-bool RenderThemeChromiumWin::paintProgressBar(RenderObject* o, const PaintInfo& i, const IntRect& r)
-{
- if (!o->isProgress())
- return true;
-
- RenderProgress* renderProgress = toRenderProgress(o);
- // For indeterminate bar, valueRect is ignored and it is computed by the theme engine
- // because the animation is a platform detail and WebKit doesn't need to know how.
- IntRect valueRect = renderProgress->isDeterminate() ? determinateProgressValueRectFor(renderProgress, r) : IntRect(0, 0, 0, 0);
- double animatedSeconds = renderProgress->animationStartTime() ? WTF::currentTime() - renderProgress->animationStartTime() : 0;
- ThemePainter painter(i.context, r);
- DirectionFlippingScope scope(o, i, r);
- blink::WebCanvas* canvas = painter.context()->canvas();
- blink::Platform::current()->themeEngine()->paintProgressBar(canvas, blink::WebRect(r), blink::WebRect(valueRect), renderProgress->isDeterminate(), animatedSeconds);
- return false;
-}
-
-bool RenderThemeChromiumWin::shouldOpenPickerWithF4Key() const
-{
- return true;
-}
-
-bool RenderThemeChromiumWin::shouldUseFallbackTheme(RenderStyle* style) const
-{
- ControlPart part = style->appearance();
- if (part == CheckboxPart || part == RadioPart)
- return style->effectiveZoom() != 1;
- return false;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumWin.h b/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumWin.h
deleted file mode 100644
index b44e44bb51e..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderThemeChromiumWin.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * This file is part of the WebKit project.
- *
- * Copyright (C) 2006 Apple Computer, Inc.
- * Copyright (C) 2008, 2009 Google, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef RenderThemeChromiumWin_h
-#define RenderThemeChromiumWin_h
-
-#include "core/rendering/RenderThemeChromiumSkia.h"
-
-#if WIN32
-typedef void* HANDLE;
-typedef struct HINSTANCE__* HINSTANCE;
-typedef HINSTANCE HMODULE;
-#endif
-
-namespace WebCore {
-
-struct ThemeData {
- ThemeData() : m_part(0), m_state(0), m_classicState(0) { }
-
- unsigned m_part;
- unsigned m_state;
- unsigned m_classicState;
-};
-
-class RenderThemeChromiumWin : public RenderThemeChromiumSkia {
-public:
- static PassRefPtr<RenderTheme> create();
-
- // A method asking if the theme is able to draw the focus ring.
- virtual bool supportsFocusRing(const RenderStyle*) const OVERRIDE;
-
- // The platform selection color.
- virtual Color platformActiveSelectionBackgroundColor() const OVERRIDE;
- virtual Color platformInactiveSelectionBackgroundColor() const OVERRIDE;
- virtual Color platformActiveSelectionForegroundColor() const OVERRIDE;
- virtual Color platformInactiveSelectionForegroundColor() const OVERRIDE;
- virtual Color platformActiveTextSearchHighlightColor() const OVERRIDE;
- virtual Color platformInactiveTextSearchHighlightColor() const OVERRIDE;
-
- virtual Color systemColor(CSSValueID) const OVERRIDE;
-
- virtual IntSize sliderTickSize() const OVERRIDE;
- virtual int sliderTickOffsetFromTrackCenter() const OVERRIDE;
- virtual void adjustSliderThumbSize(RenderStyle*, Element*) const OVERRIDE;
-
- // Various paint functions.
- virtual bool paintCheckbox(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintRadio(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
-
- // MenuList refers to an unstyled menulist (meaning a menulist without
- // background-color or border set) and MenuListButton refers to a styled
- // menulist (a menulist with background-color or border set).
- virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
- virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
-
- virtual void adjustInnerSpinButtonStyle(RenderStyle*, Element*) const OVERRIDE;
- virtual bool paintInnerSpinButton(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
-
- virtual double animationRepeatIntervalForProgressBar(RenderProgress*) const OVERRIDE;
- virtual double animationDurationForProgressBar(RenderProgress*) const OVERRIDE;
- virtual bool paintProgressBar(RenderObject*, const PaintInfo&, const IntRect&) OVERRIDE;
-
- virtual bool shouldOpenPickerWithF4Key() const OVERRIDE;
-
-protected:
- virtual double caretBlinkIntervalInternal() const OVERRIDE;
- virtual bool shouldUseFallbackTheme(RenderStyle*) const OVERRIDE;
-
-private:
- enum ControlSubPart {
- None,
- SpinButtonDown,
- SpinButtonUp,
- };
-
- RenderThemeChromiumWin() { }
- virtual ~RenderThemeChromiumWin() { }
-
- unsigned determineState(RenderObject*, ControlSubPart = None);
- unsigned determineSliderThumbState(RenderObject*);
- unsigned determineClassicState(RenderObject*, ControlSubPart = None);
-
- ThemeData getThemeData(RenderObject*, ControlSubPart = None);
-
- bool paintTextFieldInternal(RenderObject*, const PaintInfo&, const IntRect&, bool);
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.cpp
index ccc630e5e81..a450d9773fe 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.cpp
@@ -26,30 +26,29 @@
#include "config.h"
#include "core/rendering/RenderTreeAsText.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/css/StylePropertySet.h"
#include "core/dom/Document.h"
#include "core/editing/FrameSelection.h"
-#include "core/html/HTMLElement.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLElement.h"
#include "core/page/PrintContext.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderBR.h"
#include "core/rendering/RenderDetailsMarker.h"
#include "core/rendering/RenderFileUploadControl.h"
+#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderInline.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderListItem.h"
#include "core/rendering/RenderListMarker.h"
-#include "core/rendering/RenderNamedFlowThread.h"
#include "core/rendering/RenderPart.h"
-#include "core/rendering/RenderRegion.h"
#include "core/rendering/RenderTableCell.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/RenderWidget.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
#include "core/rendering/svg/RenderSVGContainer.h"
#include "core/rendering/svg/RenderSVGGradientStop.h"
#include "core/rendering/svg/RenderSVGImage.h"
@@ -115,17 +114,17 @@ static String getTagName(Node* n)
static bool isEmptyOrUnstyledAppleStyleSpan(const Node* node)
{
- if (!node || !node->isHTMLElement() || !node->hasTagName(spanTag))
+ if (!isHTMLSpanElement(node))
return false;
- const HTMLElement* elem = toHTMLElement(node);
- if (elem->getAttribute(classAttr) != "Apple-style-span")
+ const HTMLElement& elem = toHTMLElement(*node);
+ if (elem.getAttribute(classAttr) != "Apple-style-span")
return false;
- if (!node->hasChildNodes())
+ if (!elem.hasChildren())
return true;
- const StylePropertySet* inlineStyleDecl = elem->inlineStyle();
+ const StylePropertySet* inlineStyleDecl = elem.inlineStyle();
return (!inlineStyleDecl || inlineStyleDecl->isEmpty());
}
@@ -227,17 +226,17 @@ void RenderTreeAsText::writeRenderObject(TextStream& ts, const RenderObject& o,
// Do not dump invalid or transparent backgrounds, since that is the default.
Color backgroundColor = o.resolveColor(CSSPropertyBackgroundColor);
if (o.parent()->resolveColor(CSSPropertyBackgroundColor) != backgroundColor
- && backgroundColor.isValid() && backgroundColor.rgb())
+ && backgroundColor.rgb())
ts << " [bgcolor=" << backgroundColor.nameForRenderTreeAsText() << "]";
Color textFillColor = o.resolveColor(CSSPropertyWebkitTextFillColor);
if (o.parent()->resolveColor(CSSPropertyWebkitTextFillColor) != textFillColor
- && textFillColor.isValid() && textFillColor != color && textFillColor.rgb())
+ && textFillColor != color && textFillColor.rgb())
ts << " [textFillColor=" << textFillColor.nameForRenderTreeAsText() << "]";
Color textStrokeColor = o.resolveColor(CSSPropertyWebkitTextStrokeColor);
if (o.parent()->resolveColor(CSSPropertyWebkitTextStrokeColor) != textStrokeColor
- && textStrokeColor.isValid() && textStrokeColor != color && textStrokeColor.rgb())
+ && textStrokeColor != color && textStrokeColor.rgb())
ts << " [textStrokeColor=" << textStrokeColor.nameForRenderTreeAsText() << "]";
if (o.parent()->style()->textStrokeWidth() != o.style()->textStrokeWidth() && o.style()->textStrokeWidth() > 0)
@@ -475,7 +474,7 @@ void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavi
}
}
- for (RenderObject* child = o.firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = o.slowFirstChild(); child; child = child->nextSibling()) {
if (child->hasLayer())
continue;
write(ts, *child, indent + 1, behavior);
@@ -539,10 +538,10 @@ static void write(TextStream& ts, RenderLayer& l,
ts << " scrollX " << l.scrollableArea()->scrollXOffset();
if (l.scrollableArea()->scrollYOffset())
ts << " scrollY " << l.scrollableArea()->scrollYOffset();
- if (l.renderBox() && l.renderBox()->pixelSnappedClientWidth() != l.renderBox()->scrollWidth())
- ts << " scrollWidth " << l.renderBox()->scrollWidth();
- if (l.renderBox() && l.renderBox()->pixelSnappedClientHeight() != l.renderBox()->scrollHeight())
- ts << " scrollHeight " << l.renderBox()->scrollHeight();
+ if (l.renderBox() && l.renderBox()->pixelSnappedClientWidth() != l.renderBox()->pixelSnappedScrollWidth())
+ ts << " scrollWidth " << l.renderBox()->pixelSnappedScrollWidth();
+ if (l.renderBox() && l.renderBox()->pixelSnappedClientHeight() != l.renderBox()->pixelSnappedScrollHeight())
+ ts << " scrollHeight " << l.renderBox()->pixelSnappedScrollHeight();
}
if (paintPhase == LayerPaintPhaseBackground)
@@ -550,6 +549,11 @@ static void write(TextStream& ts, RenderLayer& l,
else if (paintPhase == LayerPaintPhaseForeground)
ts << " layerType: foreground only";
+ if (l.blendInfo().childLayerHasBlendMode())
+ ts << " isolatesBlending";
+ if (l.blendInfo().hasBlendMode())
+ ts << " blendMode: " << compositeOperatorName(CompositeSourceOver, l.blendInfo().blendMode());
+
if (behavior & RenderAsTextShowCompositedLayers) {
if (l.hasCompositedLayerMapping()) {
ts << " (composited, bounds="
@@ -558,6 +562,7 @@ static void write(TextStream& ts, RenderLayer& l,
<< l.compositedLayerMapping()->mainGraphicsLayer()->drawsContent()
<< ", paints into ancestor="
<< l.compositedLayerMapping()->paintsIntoCompositedAncestor()
+ << (l.shouldIsolateCompositedDescendants() ? ", isolatesCompositedBlending" : "")
<< ")";
}
}
@@ -568,91 +573,6 @@ static void write(TextStream& ts, RenderLayer& l,
write(ts, *l.renderer(), indent + 1, behavior);
}
-static void writeRenderRegionList(const RenderRegionList& flowThreadRegionList, TextStream& ts, int indent)
-{
- for (RenderRegionList::const_iterator itRR = flowThreadRegionList.begin(); itRR != flowThreadRegionList.end(); ++itRR) {
- const RenderRegion* renderRegion = *itRR;
-
- writeIndent(ts, indent);
- ts << renderRegion->renderName();
-
- Node* generatingNodeForRegion = renderRegion->generatingNodeForRegion();
- if (generatingNodeForRegion) {
- if (renderRegion->hasCustomRegionStyle())
- ts << " region style: 1";
- if (renderRegion->hasAutoLogicalHeight())
- ts << " hasAutoLogicalHeight";
-
- bool isRenderNamedFlowFragment = renderRegion->isRenderNamedFlowFragment();
- if (isRenderNamedFlowFragment)
- ts << " (anonymous child of";
-
- StringBuilder tagName;
- tagName.append(generatingNodeForRegion->nodeName());
-
- Node* nodeForRegion = renderRegion->nodeForRegion();
- if (nodeForRegion->isPseudoElement()) {
- if (nodeForRegion->isBeforePseudoElement())
- tagName.append("::before");
- else if (nodeForRegion->isAfterPseudoElement())
- tagName.append("::after");
- }
-
- ts << " {" << tagName.toString() << "}";
-
- if (generatingNodeForRegion->isElementNode() && generatingNodeForRegion->hasID()) {
- Element* element = toElement(generatingNodeForRegion);
- ts << " #" << element->idForStyleResolution();
- }
-
- if (isRenderNamedFlowFragment)
- ts << ")";
- }
-
- if (!renderRegion->isValid())
- ts << " invalid";
-
- ts << "\n";
- }
-}
-
-static void writeRenderNamedFlowThreads(TextStream& ts, RenderView* renderView, const RenderLayer* rootLayer,
- const LayoutRect& paintRect, int indent, RenderAsTextBehavior behavior)
-{
- if (!renderView->hasRenderNamedFlowThreads())
- return;
-
- const RenderNamedFlowThreadList* list = renderView->flowThreadController()->renderNamedFlowThreadList();
-
- writeIndent(ts, indent);
- ts << "Named flows\n";
-
- for (RenderNamedFlowThreadList::const_iterator iter = list->begin(); iter != list->end(); ++iter) {
- const RenderNamedFlowThread* renderFlowThread = *iter;
-
- writeIndent(ts, indent + 1);
- ts << "Named flow '" << renderFlowThread->flowThreadName() << "'\n";
-
- RenderLayer* layer = renderFlowThread->layer();
- RenderTreeAsText::writeLayers(ts, rootLayer, layer, paintRect, indent + 2, behavior);
-
- // Display the valid and invalid render regions attached to this flow thread.
- const RenderRegionList& validRegionsList = renderFlowThread->renderRegionList();
- if (!validRegionsList.isEmpty()) {
- writeIndent(ts, indent + 2);
- ts << "Regions for named flow '" << renderFlowThread->flowThreadName() << "'\n";
- writeRenderRegionList(validRegionsList, ts, indent + 3);
- }
-
- const RenderRegionList& invalidRegionsList = renderFlowThread->invalidRenderRegionList();
- if (!invalidRegionsList.isEmpty()) {
- writeIndent(ts, indent + 2);
- ts << "Invalid regions for named flow '" << renderFlowThread->flowThreadName() << "'\n";
- writeRenderRegionList(invalidRegionsList, ts, indent + 3);
- }
- }
-}
-
void RenderTreeAsText::writeLayers(TextStream& ts, const RenderLayer* rootLayer, RenderLayer* layer,
const LayoutRect& paintRect, int indent, RenderAsTextBehavior behavior)
{
@@ -667,7 +587,7 @@ void RenderTreeAsText::writeLayers(TextStream& ts, const RenderLayer* rootLayer,
// Calculate the clip rects we should use.
LayoutRect layerBounds;
ClipRect damageRect, clipRectToApply, outlineRect;
- layer->calculateRects(ClipRectsContext(rootLayer, 0, TemporaryClipRects), paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
+ layer->clipper().calculateRects(ClipRectsContext(rootLayer, TemporaryClipRects), paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect);
// Ensure our lists are up-to-date.
layer->stackingNode()->updateLayerListsIfNeeded();
@@ -714,13 +634,6 @@ void RenderTreeAsText::writeLayers(TextStream& ts, const RenderLayer* rootLayer,
for (unsigned i = 0; i != posList->size(); ++i)
writeLayers(ts, rootLayer, posList->at(i)->layer(), paintDirtyRect, currIndent, behavior);
}
-
- // Altough the RenderFlowThread requires a layer, it is not collected by its parent,
- // so we have to treat it as a special case.
- if (layer->renderer()->isRenderView()) {
- RenderView* renderView = toRenderView(layer->renderer());
- writeRenderNamedFlowThreads(ts, renderView, rootLayer, paintDirtyRect, indent, behavior);
- }
}
static String nodePosition(Node* node)
@@ -764,7 +677,7 @@ static void writeSelection(TextStream& ts, const RenderObject* o)
return;
Document* doc = toDocument(n);
- Frame* frame = doc->frame();
+ LocalFrame* frame = doc->frame();
if (!frame)
return;
@@ -791,7 +704,7 @@ static String externalRepresentation(RenderBox* renderer, RenderAsTextBehavior b
return ts.release();
}
-String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
+String externalRepresentation(LocalFrame* frame, RenderAsTextBehavior behavior)
{
if (!(behavior & RenderAsTextDontUpdateLayout))
frame->document()->updateLayout();
@@ -802,7 +715,7 @@ String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
PrintContext printContext(frame);
if (behavior & RenderAsTextPrintingMode)
- printContext.begin(toRenderBox(renderer)->width());
+ printContext.begin(toRenderBox(renderer)->width().toFloat());
return externalRepresentation(toRenderBox(renderer), behavior);
}
@@ -823,7 +736,7 @@ String externalRepresentation(Element* element, RenderAsTextBehavior behavior)
static void writeCounterValuesFromChildren(TextStream& stream, RenderObject* parent, bool& isFirstCounter)
{
- for (RenderObject* child = parent->firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = parent->slowFirstChild(); child; child = child->nextSibling()) {
if (child->isCounter()) {
if (!isFirstCounter)
stream << " ";
@@ -837,7 +750,7 @@ static void writeCounterValuesFromChildren(TextStream& stream, RenderObject* par
String counterValueForElement(Element* element)
{
// Make sure the element is not freed during the layout.
- RefPtr<Element> elementRef(element);
+ RefPtrWillBeRawPtr<Element> protector(element);
element->document().updateLayout();
TextStream stream;
bool isFirstCounter = true;
@@ -852,7 +765,7 @@ String counterValueForElement(Element* element)
String markerTextForListItem(Element* element)
{
// Make sure the element is not freed during the layout.
- RefPtr<Element> elementRef(element);
+ RefPtrWillBeRawPtr<Element> protector(element);
element->document().updateLayout();
RenderObject* renderer = element->renderer();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.h b/chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.h
index 63c900ca947..aa66a867604 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderTreeAsText.h
@@ -32,7 +32,7 @@
namespace WebCore {
class Element;
-class Frame;
+class LocalFrame;
class LayoutRect;
class RenderLayer;
class RenderObject;
@@ -52,7 +52,7 @@ enum RenderAsTextBehaviorFlags {
typedef unsigned RenderAsTextBehavior;
// You don't need pageWidthInPixels if you don't specify RenderAsTextInPrintingMode.
-String externalRepresentation(Frame*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
+String externalRepresentation(LocalFrame*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
String externalRepresentation(Element*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
void write(TextStream&, const RenderObject&, int indent = 0, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.cpp
index 4507321ee6f..349e98ad698 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.cpp
@@ -27,7 +27,6 @@
#include "core/rendering/RenderVTTCue.h"
#include "core/html/track/vtt/VTTCue.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderView.h"
namespace WebCore {
@@ -40,7 +39,6 @@ RenderVTTCue::RenderVTTCue(VTTCueBox* element)
void RenderVTTCue::layout()
{
- LayoutRectRecorder recorder(*this);
RenderBlockFlow::layout();
// If WebVTT Regions are used, the regular WebVTT layout algorithm is no
@@ -50,14 +48,12 @@ void RenderVTTCue::layout()
if (!m_cue->regionId().isEmpty())
return;
- LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+ LayoutState state(*this, locationOffset());
if (m_cue->snapToLines())
repositionCueSnapToLinesSet();
else
repositionCueSnapToLinesNotSet();
-
- statePusher.pop();
}
bool RenderVTTCue::findFirstLineBox(InlineFlowBox*& firstLineBox)
@@ -127,7 +123,8 @@ void RenderVTTCue::placeBoxInDefaultPosition(LayoutUnit position, bool& switched
// 9. Default: Remember the position of all the boxes in boxes as their
// default position.
- m_fallbackPosition = FloatPoint(x(), y());
+ // FIXME: Why the direct conversion between float and LayoutUnit? crbug.com/350474
+ m_fallbackPosition = FloatPoint(location());
// 10. Let switched be false.
switched = false;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.h b/chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.h
index d357b24cc3a..953ff82f4b0 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderVTTCue.h
@@ -41,7 +41,6 @@ public:
private:
virtual void layout() OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
bool isOutside() const;
bool isOverlapping() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderVideo.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderVideo.cpp
index b498f90186a..902641ddd06 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderVideo.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderVideo.cpp
@@ -27,13 +27,11 @@
#include "core/rendering/RenderVideo.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/dom/Document.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
-#include "core/rendering/LayoutRectRecorder.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLVideoElement.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderFullScreen.h"
#include "platform/graphics/media/MediaPlayer.h"
@@ -83,7 +81,7 @@ void RenderVideo::updateIntrinsicSize()
setIntrinsicSize(size);
setPreferredLogicalWidthsDirty();
- setNeedsLayout();
+ setNeedsLayoutAndFullPaintInvalidation();
}
LayoutSize RenderVideo::calculateIntrinsicSize()
@@ -99,9 +97,9 @@ LayoutSize RenderVideo::calculateIntrinsicSize()
// The intrinsic height of a video element's playback area is the intrinsic height
// of the video resource, if that is available; otherwise it is the intrinsic
// height of the poster frame, if that is available; otherwise it is 150 CSS pixels.
- MediaPlayer* player = mediaElement()->player();
- if (player && video->readyState() >= HTMLVideoElement::HAVE_METADATA) {
- LayoutSize size = player->naturalSize();
+ blink::WebMediaPlayer* webMediaPlayer = mediaElement()->webMediaPlayer();
+ if (webMediaPlayer && video->readyState() >= HTMLVideoElement::HAVE_METADATA) {
+ IntSize size = webMediaPlayer->naturalSize();
if (!size.isEmpty())
return size;
}
@@ -186,14 +184,12 @@ bool RenderVideo::acceleratedRenderingInUse()
void RenderVideo::layout()
{
- LayoutRectRecorder recorder(*this);
updatePlayer();
RenderMedia::layout();
}
HTMLVideoElement* RenderVideo::videoElement() const
{
- ASSERT(isHTMLVideoElement(node()));
return toHTMLVideoElement(node());
}
@@ -214,7 +210,7 @@ void RenderVideo::updatePlayer()
if (!videoElement()->isActive())
return;
- contentChanged(VideoChanged);
+ videoElement()->setNeedsCompositingUpdate();
}
LayoutUnit RenderVideo::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
@@ -278,4 +274,18 @@ LayoutUnit RenderVideo::offsetHeight() const
return RenderMedia::offsetHeight();
}
+CompositingReasons RenderVideo::additionalCompositingReasons(CompositingTriggerFlags triggers) const
+{
+ if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled()) {
+ HTMLMediaElement* media = toHTMLMediaElement(node());
+ if (media->isFullscreen())
+ return CompositingReasonVideo;
+ }
+
+ if ((triggers & VideoTrigger) && shouldDisplayVideo() && supportsAcceleratedRendering())
+ return CompositingReasonVideo;
+
+ return CompositingReasonNone;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderVideo.h b/chromium/third_party/WebKit/Source/core/rendering/RenderVideo.h
index 40a400d9075..405f99cddee 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderVideo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderVideo.h
@@ -30,7 +30,6 @@
namespace WebCore {
-class HTMLMediaElement;
class HTMLVideoElement;
class RenderVideo FINAL : public RenderMedia {
@@ -44,35 +43,36 @@ public:
bool supportsAcceleratedRendering() const;
- virtual bool shouldDisplayVideo() const;
+ bool shouldDisplayVideo() const;
private:
- virtual void updateFromElement();
+ virtual void updateFromElement() OVERRIDE;
inline HTMLVideoElement* videoElement() const;
- virtual void intrinsicSizeChanged();
+ virtual void intrinsicSizeChanged() OVERRIDE;
LayoutSize calculateIntrinsicSize();
void updateIntrinsicSize();
- virtual void imageChanged(WrappedImagePtr, const IntRect*);
+ virtual void imageChanged(WrappedImagePtr, const IntRect*) OVERRIDE;
- virtual const char* renderName() const { return "RenderVideo"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderVideo"; }
- virtual bool requiresLayer() const { return true; }
- virtual bool isVideo() const { return true; }
+ virtual bool isVideo() const OVERRIDE { return true; }
- virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
+ virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE;
- virtual void layout();
+ virtual void layout() OVERRIDE;
virtual LayoutUnit computeReplacedLogicalWidth(ShouldComputePreferred = ComputeActual) const OVERRIDE;
- virtual LayoutUnit computeReplacedLogicalHeight() const;
+ virtual LayoutUnit computeReplacedLogicalHeight() const OVERRIDE;
virtual LayoutUnit minimumReplacedHeight() const OVERRIDE;
- virtual LayoutUnit offsetLeft() const;
- virtual LayoutUnit offsetTop() const;
- virtual LayoutUnit offsetWidth() const;
- virtual LayoutUnit offsetHeight() const;
+ virtual LayoutUnit offsetLeft() const OVERRIDE;
+ virtual LayoutUnit offsetTop() const OVERRIDE;
+ virtual LayoutUnit offsetWidth() const OVERRIDE;
+ virtual LayoutUnit offsetHeight() const OVERRIDE;
+
+ virtual CompositingReasons additionalCompositingReasons(CompositingTriggerFlags) const OVERRIDE;
void updatePlayer();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderView.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderView.cpp
index 05955691af5..8aa9ddacbd3 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderView.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderView.cpp
@@ -21,31 +21,29 @@
#include "config.h"
#include "core/rendering/RenderView.h"
-#include "RuntimeEnabledFeatures.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLDialogElement.h"
#include "core/html/HTMLFrameOwnerElement.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/frame/Frame.h"
#include "core/page/Page.h"
#include "core/rendering/ColumnInfo.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/FlowThreadController.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderFlowThread.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderSelectionInfo.h"
-#include "core/rendering/RenderWidget.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/svg/SVGDocumentExtensions.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/TraceEvent.h"
#include "platform/geometry/FloatQuad.h"
#include "platform/geometry/TransformState.h"
#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/filters/custom/CustomFilterGlobalContext.h"
namespace WebCore {
@@ -56,11 +54,9 @@ RenderView::RenderView(Document* document)
, m_selectionEnd(0)
, m_selectionStartPos(-1)
, m_selectionEndPos(-1)
- , m_maximalOutlineSize(0)
, m_pageLogicalHeight(0)
, m_pageLogicalHeightChanged(false)
, m_layoutState(0)
- , m_layoutStateDisableCount(0)
, m_renderQuoteHead(0)
, m_renderCounterCount(0)
{
@@ -86,6 +82,8 @@ bool RenderView::hitTest(const HitTestRequest& request, HitTestResult& result)
bool RenderView::hitTest(const HitTestRequest& request, const HitTestLocation& location, HitTestResult& result)
{
+ TRACE_EVENT0("blink", "RenderView::hitTest");
+
// We have to recursively update layout/style here because otherwise, when the hit test recurses
// into a child document, it could trigger a layout on the parent document, which can destroy RenderLayers
// that are higher up in the call stack, leading to crashes.
@@ -111,7 +109,7 @@ LayoutUnit RenderView::availableLogicalHeight(AvailableLogicalHeightType heightT
// If we have columns, then the available logical height is reduced to the column height.
if (hasColumns())
return columnInfo()->columnHeight();
- return RenderBlock::availableLogicalHeight(heightType);
+ return RenderBlockFlow::availableLogicalHeight(heightType);
}
bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const
@@ -119,8 +117,9 @@ bool RenderView::isChildAllowed(RenderObject* child, RenderStyle*) const
return child->isBox();
}
-static bool dialogNeedsCentering(const RenderStyle* style)
+static bool canCenterDialog(const RenderStyle* style)
{
+ // FIXME: We must center for FixedPosition as well.
return style->position() == AbsolutePosition && style->hasAutoTopAndBottom();
}
@@ -130,18 +129,19 @@ void RenderView::positionDialog(RenderBox* box)
if (dialog->centeringMode() == HTMLDialogElement::NotCentered)
return;
if (dialog->centeringMode() == HTMLDialogElement::Centered) {
- if (dialogNeedsCentering(box->style()))
+ if (canCenterDialog(box->style()))
box->setY(dialog->centeredPosition());
return;
}
- if (!dialogNeedsCentering(box->style())) {
+ ASSERT(dialog->centeringMode() == HTMLDialogElement::NeedsCentering);
+ if (!canCenterDialog(box->style())) {
dialog->setNotCentered();
return;
}
FrameView* frameView = document().view();
int scrollTop = frameView->scrollOffset().height();
- int visibleHeight = frameView->visibleContentRect(ScrollableArea::IncludeScrollbars).height();
+ int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height();
LayoutUnit top = scrollTop;
if (box->height() < visibleHeight)
top += (visibleHeight - box->height()) / 2;
@@ -157,146 +157,68 @@ void RenderView::positionDialogs()
TrackedRendererListHashSet::iterator end = positionedDescendants->end();
for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
RenderBox* box = *it;
- if (box->node() && box->node()->hasTagName(HTMLNames::dialogTag))
+ if (isHTMLDialogElement(box->node()))
positionDialog(box);
}
}
-void RenderView::layoutContent(const LayoutState& state)
+void RenderView::layoutContent()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
- RenderBlock::layout();
+ RenderBlockFlow::layout();
if (RuntimeEnabledFeatures::dialogElementEnabled())
positionDialogs();
- if (m_frameView->partialLayout().isStopping())
- return;
-
- if (hasRenderNamedFlowThreads())
- flowThreadController()->layoutRenderNamedFlowThreads();
-
#ifndef NDEBUG
- checkLayoutState(state);
+ checkLayoutState();
#endif
}
#ifndef NDEBUG
-void RenderView::checkLayoutState(const LayoutState& state)
+void RenderView::checkLayoutState()
{
- ASSERT(layoutDeltaMatches(LayoutSize()));
- ASSERT(!m_layoutStateDisableCount);
- ASSERT(m_layoutState == &state);
+ if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
+ ASSERT(layoutDeltaMatches(LayoutSize()));
+ }
+ ASSERT(!m_layoutState->next());
}
#endif
-static RenderBox* enclosingSeamlessRenderer(const Document& doc)
+bool RenderView::shouldDoFullRepaintForNextLayout() const
{
- Element* ownerElement = doc.seamlessParentIFrame();
- if (!ownerElement)
- return 0;
- return ownerElement->renderBox();
-}
-
-void RenderView::addChild(RenderObject* newChild, RenderObject* beforeChild)
-{
- // Seamless iframes are considered part of an enclosing render flow thread from the parent document. This is necessary for them to look
- // up regions in the parent document during layout.
- if (newChild && !newChild->isRenderFlowThread()) {
- RenderBox* seamlessBox = enclosingSeamlessRenderer(document());
- if (seamlessBox && seamlessBox->flowThreadContainingBlock())
- newChild->setFlowThreadState(seamlessBox->flowThreadState());
- }
- RenderBlock::addChild(newChild, beforeChild);
-}
+ // It's hard to predict here which of full repaint or per-descendant repaint costs less.
+ // For vertical writing mode or width change it's more likely that per-descendant repaint
+ // eventually turns out to be full repaint but with the cost to handle more layout states
+ // and discrete repaint rects, so marking full repaint here is more likely to cost less.
+ // Otherwise, per-descendant repaint is more likely to avoid unnecessary full repaints.
-bool RenderView::initializeLayoutState(LayoutState& state)
-{
- bool isSeamlessAncestorInFlowThread = false;
-
- // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
- state.m_clipped = false;
-
- // Check the writing mode of the seamless ancestor. It has to match our document's writing mode, or we won't inherit any
- // pagination information.
- RenderBox* seamlessAncestor = enclosingSeamlessRenderer(document());
- LayoutState* seamlessLayoutState = seamlessAncestor ? seamlessAncestor->view()->layoutState() : 0;
- bool shouldInheritPagination = seamlessLayoutState && !m_pageLogicalHeight && seamlessAncestor->style()->writingMode() == style()->writingMode();
-
- state.m_pageLogicalHeight = shouldInheritPagination ? seamlessLayoutState->m_pageLogicalHeight : m_pageLogicalHeight;
- state.m_pageLogicalHeightChanged = shouldInheritPagination ? seamlessLayoutState->m_pageLogicalHeightChanged : m_pageLogicalHeightChanged;
- state.m_isPaginated = state.m_pageLogicalHeight;
- if (state.m_isPaginated && shouldInheritPagination) {
- // Set up the correct pagination offset. We can use a negative offset in order to push the top of the RenderView into its correct place
- // on a page. We can take the iframe's offset from the logical top of the first page and make the negative into the pagination offset within the child
- // view.
- bool isFlipped = seamlessAncestor->style()->isFlippedBlocksWritingMode();
- LayoutSize layoutOffset = seamlessLayoutState->layoutOffset();
- LayoutSize iFrameOffset(layoutOffset.width() + seamlessAncestor->x() + (!isFlipped ? seamlessAncestor->borderLeft() + seamlessAncestor->paddingLeft() :
- seamlessAncestor->borderRight() + seamlessAncestor->paddingRight()),
- layoutOffset.height() + seamlessAncestor->y() + (!isFlipped ? seamlessAncestor->borderTop() + seamlessAncestor->paddingTop() :
- seamlessAncestor->borderBottom() + seamlessAncestor->paddingBottom()));
-
- LayoutSize offsetDelta = seamlessLayoutState->m_pageOffset - iFrameOffset;
- state.m_pageOffset = offsetDelta;
-
- // Set the current render flow thread to point to our ancestor. This will allow the seamless document to locate the correct
- // regions when doing a layout.
- if (seamlessAncestor->flowThreadContainingBlock()) {
- flowThreadController()->setCurrentRenderFlowThread(seamlessAncestor->view()->flowThreadController()->currentRenderFlowThread());
- isSeamlessAncestorInFlowThread = true;
+ if (shouldUsePrintingLayout())
+ return true;
+
+ if (!style()->isHorizontalWritingMode() || width() != viewWidth())
+ return true;
+
+ if (height() != viewHeight()) {
+ // FIXME: Disable optimization to fix crbug.com/390378 for the branch.
+ return true;
+#if 0
+ if (RenderObject* backgroundRenderer = this->backgroundRenderer()) {
+ // When background-attachment is 'fixed', we treat the viewport (instead of the 'root'
+ // i.e. html or body) as the background positioning area, and we should full repaint
+ // viewport resize if the background image is not composited and needs full repaint on
+ // background positioning area resize.
+ if (!m_compositor || !m_compositor->needsFixedRootBackgroundLayer(layer())) {
+ if (backgroundRenderer->style()->hasFixedBackgroundImage()
+ && mustInvalidateFillLayersPaintOnHeightChange(*backgroundRenderer->style()->backgroundLayers()))
+ return true;
+ }
}
+#endif
}
- // FIXME: We need to make line grids and exclusions work with seamless iframes as well here. Basically all layout state information needs
- // to propagate here and not just pagination information.
- return isSeamlessAncestorInFlowThread;
-}
-
-// The algorithm below assumes this is a full layout. In case there are previously computed values for regions, supplemental steps are taken
-// to ensure the results are the same as those obtained from a full layout (i.e. the auto-height regions from all the flows are marked as needing
-// layout).
-// 1. The flows are laid out from the outer flow to the inner flow. This successfully computes the outer non-auto-height regions size so the
-// inner flows have the necessary information to correctly fragment the content.
-// 2. The flows are laid out from the inner flow to the outer flow. After an inner flow is laid out it goes into the constrained layout phase
-// and marks the auto-height regions they need layout. This means the outer flows will relayout if they depend on regions with auto-height regions
-// belonging to inner flows. This step will correctly set the computedAutoHeight for the auto-height regions. It's possible for non-auto-height
-// regions to relayout if they depend on auto-height regions. This will invalidate the inner flow threads and mark them as needing layout.
-// 3. The last step is to do one last layout if there are pathological dependencies between non-auto-height regions and auto-height regions
-// as detected in the previous step.
-void RenderView::layoutContentInAutoLogicalHeightRegions(const LayoutState& state)
-{
- if (!m_frameView->partialLayout().isStopping()) {
- // Disable partial layout for any two-pass layout algorithm.
- m_frameView->partialLayout().reset();
- }
-
- // We need to invalidate all the flows with auto-height regions if one such flow needs layout.
- // If none is found we do a layout a check back again afterwards.
- if (!flowThreadController()->updateFlowThreadsNeedingLayout()) {
- // Do a first layout of the content. In some cases more layouts are not needed (e.g. only flows with non-auto-height regions have changed).
- layoutContent(state);
-
- // If we find no named flow needing a two step layout after the first layout, exit early.
- // Otherwise, initiate the two step layout algorithm and recompute all the flows.
- if (!flowThreadController()->updateFlowThreadsNeedingTwoStepLayout())
- return;
- }
-
- // Layout to recompute all the named flows with auto-height regions.
- layoutContent(state);
-
- // Propagate the computed auto-height values upwards.
- // Non-auto-height regions may invalidate the flow thread because they depended on auto-height regions, but that's ok.
- flowThreadController()->updateFlowThreadsIntoConstrainedPhase();
-
- // Do one last layout that should update the auto-height regions found in the main flow
- // and solve pathological dependencies between regions (e.g. a non-auto-height region depending
- // on an auto-height one).
- if (needsLayout())
- layoutContent(state);
+ return false;
}
void RenderView::layout()
@@ -307,7 +229,7 @@ void RenderView::layout()
if (shouldUsePrintingLayout())
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth();
- SubtreeLayoutScope layoutScope(this);
+ SubtreeLayoutScope layoutScope(*this);
// Use calcWidth/Height to get the new width/height, since this will take the full page zoom factor into account.
bool relayoutChildren = !shouldUsePrintingLayout() && (!m_frameView || width() != viewWidth() || height() != viewHeight());
@@ -320,45 +242,28 @@ void RenderView::layout()
if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight())
|| child->style()->logicalHeight().isPercent()
|| child->style()->logicalMinHeight().isPercent()
- || child->style()->logicalMaxHeight().isPercent()
- || child->style()->logicalHeight().isViewportPercentage()
- || child->style()->logicalMinHeight().isViewportPercentage()
- || child->style()->logicalMaxHeight().isViewportPercentage())
+ || child->style()->logicalMaxHeight().isPercent())
layoutScope.setChildNeedsLayout(child);
}
if (document().svgExtensions())
- document().accessSVGExtensions()->invalidateSVGRootsWithRelativeLengthDescendents(&layoutScope);
+ document().accessSVGExtensions().invalidateSVGRootsWithRelativeLengthDescendents(&layoutScope);
}
ASSERT(!m_layoutState);
if (!needsLayout())
return;
- LayoutState state;
- bool isSeamlessAncestorInFlowThread = initializeLayoutState(state);
+ LayoutState rootLayoutState(pageLogicalHeight(), pageLogicalHeightChanged(), *this);
m_pageLogicalHeightChanged = false;
- m_layoutState = &state;
- if (checkTwoPassLayoutForAutoHeightRegions())
- layoutContentInAutoLogicalHeightRegions(state);
- else
- layoutContent(state);
-
- if (m_frameView->partialLayout().isStopping()) {
- m_layoutState = 0;
- return;
- }
+ layoutContent();
#ifndef NDEBUG
- checkLayoutState(state);
+ checkLayoutState();
#endif
- m_layoutState = 0;
clearNeedsLayout();
-
- if (isSeamlessAncestorInFlowThread)
- flowThreadController()->setCurrentRenderFlowThread(0);
}
void RenderView::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
@@ -444,32 +349,6 @@ void RenderView::computeSelfHitTestRects(Vector<LayoutRect>& rects, const Layout
rects.append(LayoutRect(LayoutPoint::zero(), frameView()->contentsSize()));
}
-bool RenderView::requiresColumns(int desiredColumnCount) const
-{
- if (m_frameView)
- return m_frameView->pagination().mode != Pagination::Unpaginated;
-
- return RenderBlock::requiresColumns(desiredColumnCount);
-}
-
-void RenderView::calcColumnWidth()
-{
- int columnWidth = contentLogicalWidth();
- if (m_frameView && style()->hasInlineColumnAxis()) {
- if (int pageLength = m_frameView->pagination().pageLength)
- columnWidth = pageLength;
- }
- setDesiredColumnCountAndWidth(1, columnWidth);
-}
-
-ColumnInfo::PaginationUnit RenderView::paginationUnit() const
-{
- if (m_frameView)
- return m_frameView->pagination().behavesLikeColumns ? ColumnInfo::Column : ColumnInfo::Page;
-
- return ColumnInfo::Page;
-}
-
void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// If we ever require layout but receive a paint anyway, something has gone horribly wrong.
@@ -480,33 +359,42 @@ void RenderView::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
// This avoids painting garbage between columns if there is a column gap.
- if (m_frameView && m_frameView->pagination().mode != Pagination::Unpaginated)
+ if (m_frameView && style()->isOverflowPaged())
paintInfo.context->fillRect(paintInfo.rect, m_frameView->baseBackgroundColor());
paintObject(paintInfo, paintOffset);
}
-static inline bool rendererObscuresBackground(RenderObject* rootObject)
+static inline bool rendererObscuresBackground(RenderBox* rootBox)
{
- if (!rootObject)
- return false;
-
- RenderStyle* style = rootObject->style();
+ ASSERT(rootBox);
+ RenderStyle* style = rootBox->style();
if (style->visibility() != VISIBLE
|| style->opacity() != 1
+ || style->hasFilter()
|| style->hasTransform())
return false;
- if (rootObject->compositingState() == PaintsIntoOwnBacking)
+ if (rootBox->compositingState() == PaintsIntoOwnBacking)
return false;
- const RenderObject* rootRenderer = rootObject->rendererForRootBackground();
+ const RenderObject* rootRenderer = rootBox->rendererForRootBackground();
if (rootRenderer->style()->backgroundClip() == TextFillBox)
return false;
return true;
}
+bool RenderView::rootFillsViewportBackground(RenderBox* rootBox) const
+{
+ ASSERT(rootBox);
+ // CSS Boxes always fill the viewport background (see paintRootBoxFillLayers)
+ if (!rootBox->isSVG())
+ return true;
+
+ return rootBox->frameRect().contains(frameRect());
+}
+
void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
{
// Check to see if we are enclosed by a layer that requires complex painting rules. If so, we cannot blit
@@ -534,21 +422,13 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
if (paintInfo.skipRootBackground())
return;
- bool rootFillsViewport = false;
- bool rootObscuresBackground = false;
+ bool shouldPaintBackground = true;
Node* documentElement = document().documentElement();
- if (RenderObject* rootRenderer = documentElement ? documentElement->renderer() : 0) {
- // The document element's renderer is currently forced to be a block, but may not always be.
- RenderBox* rootBox = rootRenderer->isBox() ? toRenderBox(rootRenderer) : 0;
- rootFillsViewport = rootBox && !rootBox->x() && !rootBox->y() && rootBox->width() >= width() && rootBox->height() >= height();
- rootObscuresBackground = rendererObscuresBackground(rootRenderer);
- }
-
- Page* page = document().page();
- float pageScaleFactor = page ? page->pageScaleFactor() : 1;
+ if (RenderBox* rootBox = documentElement ? toRenderBox(documentElement->renderer()) : 0)
+ shouldPaintBackground = !rootFillsViewportBackground(rootBox) || !rendererObscuresBackground(rootBox);
// If painting will entirely fill the view, no need to fill the background.
- if (rootFillsViewport && rootObscuresBackground && pageScaleFactor >= 1)
+ if (!shouldPaintBackground)
return;
// This code typically only executes if the root element's visibility has been set to hidden,
@@ -570,63 +450,64 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
}
}
-bool RenderView::shouldRepaint(const LayoutRect& rect) const
+void RenderView::invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer)
{
- if (document().printing())
- return false;
- return m_frameView && !rect.isEmpty();
+ ASSERT(RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
+ ASSERT(!needsLayout());
+
+ // We specifically need to repaint the viewRect since other renderers
+ // short-circuit on full-repaint.
+ if (doingFullRepaint() && !viewRect().isEmpty())
+ repaintViewRectangle(viewRect());
+
+ LayoutState rootLayoutState(0, false, *this);
+ RenderBlock::invalidateTreeAfterLayout(paintInvalidationContainer);
}
-void RenderView::repaintViewRectangle(const LayoutRect& ur) const
+void RenderView::repaintViewRectangle(const LayoutRect& repaintRect) const
{
- if (!shouldRepaint(ur))
+ ASSERT(!repaintRect.isEmpty());
+
+ if (document().printing() || !m_frameView)
return;
// We always just invalidate the root view, since we could be an iframe that is clipped out
// or even invisible.
- Element* elt = document().ownerElement();
- if (!elt)
- m_frameView->repaintContentRectangle(pixelSnappedIntRect(ur));
- else if (RenderBox* obj = elt->renderBox()) {
- LayoutRect vr = viewRect();
- LayoutRect r = intersection(ur, vr);
+ Element* owner = document().ownerElement();
+ if (layer()->compositingState() == PaintsIntoOwnBacking) {
+ layer()->repainter().setBackingNeedsRepaintInRect(repaintRect);
+ } else if (!owner) {
+ m_frameView->contentRectangleForPaintInvalidation(pixelSnappedIntRect(repaintRect));
+ } else if (RenderBox* obj = owner->renderBox()) {
+ LayoutRect viewRectangle = viewRect();
+ LayoutRect rectToRepaint = intersection(repaintRect, viewRectangle);
// Subtract out the contentsX and contentsY offsets to get our coords within the viewing
// rectangle.
- r.moveBy(-vr.location());
+ rectToRepaint.moveBy(-viewRectangle.location());
// FIXME: Hardcoded offsets here are not good.
- r.moveBy(obj->contentBoxRect().location());
- obj->repaintRectangle(r);
- }
-}
-
-void RenderView::repaintRectangleInViewAndCompositedLayers(const LayoutRect& ur)
-{
- if (!shouldRepaint(ur))
- return;
-
- repaintViewRectangle(ur);
-
- if (compositor()->inCompositingMode()) {
- IntRect repaintRect = pixelSnappedIntRect(ur);
- compositor()->repaintCompositedLayers(&repaintRect);
+ rectToRepaint.moveBy(obj->contentBoxRect().location());
+ obj->invalidatePaintRectangle(rectToRepaint);
}
}
void RenderView::repaintViewAndCompositedLayers()
{
- repaint();
+ paintInvalidationForWholeRenderer();
+
+ // The only way we know how to hit these ASSERTS below this point is via the Chromium OS login screen.
+ DisableCompositingQueryAsserts disabler;
if (compositor()->inCompositingMode())
compositor()->repaintCompositedLayers();
}
-void RenderView::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
+void RenderView::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, bool fixed) const
{
// If a container was specified, and was not 0 or the RenderView,
// then we should have found it by now.
- ASSERT_ARG(repaintContainer, !repaintContainer || repaintContainer == this);
+ ASSERT_ARG(paintInvalidationContainer, !paintInvalidationContainer || paintInvalidationContainer == this);
if (document().printing())
return;
@@ -640,11 +521,16 @@ void RenderView::computeRectForRepaint(const RenderLayerModelObject* repaintCont
rect.setX(viewWidth() - rect.maxX());
}
- if (fixed && m_frameView)
+ if (fixed && m_frameView) {
rect.move(m_frameView->scrollOffsetForFixedPosition());
+ // If we have a pending scroll, invalidate the previous scroll position.
+ if (!m_frameView->pendingScrollDelta().isZero()) {
+ rect.move(-m_frameView->pendingScrollDelta());
+ }
+ }
// Apply our transform if we have one (because of full page zooming).
- if (!repaintContainer && layer() && layer()->transform())
+ if (!paintInvalidationContainer && layer() && layer()->transform())
rect = layer()->transform()->mapRect(rect);
}
@@ -682,7 +568,7 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
selectedObjects.set(os, adoptPtr(new RenderSelectionInfo(os, clipToVisibleContent)));
RenderBlock* cb = os->containingBlock();
while (cb && !cb->isRenderView()) {
- OwnPtr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).iterator->value;
+ OwnPtr<RenderSelectionInfo>& blockInfo = selectedObjects.add(cb, nullptr).storedValue->value;
if (blockInfo)
break;
blockInfo = adoptPtr(new RenderSelectionInfo(cb, clipToVisibleContent));
@@ -700,7 +586,7 @@ IntRect RenderView::selectionBounds(bool clipToVisibleContent) const
RenderSelectionInfo* info = i->value.get();
// RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
LayoutRect currRect = info->rect();
- if (RenderLayerModelObject* repaintContainer = info->repaintContainer()) {
+ if (const RenderLayerModelObject* repaintContainer = info->repaintContainer()) {
FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(FloatRect(currRect));
currRect = absQuad.enclosingBoundingBox();
}
@@ -731,19 +617,6 @@ void RenderView::repaintSelection() const
}
}
-// Compositing layer dimensions take outline size into account, so we have to recompute layer
-// bounds when it changes.
-// FIXME: This is ugly; it would be nice to have a better way to do this.
-void RenderView::setMaximalOutlineSize(int o)
-{
- if (o != m_maximalOutlineSize) {
- m_maximalOutlineSize = o;
-
- // maximalOutlineSize affects compositing layer dimensions.
- compositor()->setCompositingLayersNeedRebuild(); // FIXME: this really just needs to be a geometry update.
- }
-}
-
// When exploring the RenderTree looking for the nodes involved in the Selection, sometimes it's
// required to change the traversing direction because the "start" position is below the "end" one.
static inline RenderObject* getNextOrPrevRenderObjectBasedOnDirection(const RenderObject* o, const RenderObject* stop, bool& continueExploring, bool& exploringBackwards)
@@ -810,7 +683,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
if (blockRepaintMode == RepaintNewXOROld) {
RenderBlock* cb = os->containingBlock();
while (cb && !cb->isRenderView()) {
- OwnPtr<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).iterator->value;
+ OwnPtr<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).storedValue->value;
if (blockInfo)
break;
blockInfo = adoptPtr(new RenderBlockSelectionInfo(cb));
@@ -865,7 +738,7 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
newSelectedObjects.set(o, adoptPtr(new RenderSelectionInfo(o, true)));
RenderBlock* cb = o->containingBlock();
while (cb && !cb->isRenderView()) {
- OwnPtr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).iterator->value;
+ OwnPtr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).storedValue->value;
if (blockInfo)
break;
blockInfo = adoptPtr(new RenderBlockSelectionInfo(cb));
@@ -879,8 +752,6 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
if (!m_frameView || blockRepaintMode == RepaintNothing)
return;
- FrameView::DeferredRepaintScope deferRepaints(*m_frameView);
-
// Have any of the old selected objects changed compared to the new selection?
for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
RenderObject* obj = i->key;
@@ -950,57 +821,6 @@ bool RenderView::shouldUsePrintingLayout() const
return m_frameView->frame().shouldUsePrintingLayout();
}
-size_t RenderView::getRetainedWidgets(Vector<RenderWidget*>& renderWidgets)
-{
- size_t size = m_widgets.size();
-
- renderWidgets.reserveCapacity(size);
-
- RenderWidgetSet::const_iterator end = m_widgets.end();
- for (RenderWidgetSet::const_iterator it = m_widgets.begin(); it != end; ++it) {
- renderWidgets.uncheckedAppend(*it);
- (*it)->ref();
- }
-
- return size;
-}
-
-void RenderView::releaseWidgets(Vector<RenderWidget*>& renderWidgets)
-{
- size_t size = renderWidgets.size();
-
- for (size_t i = 0; i < size; ++i)
- renderWidgets[i]->deref();
-}
-
-void RenderView::updateWidgetPositions()
-{
- // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running
- // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets
- // alive during enumeration.
-
- Vector<RenderWidget*> renderWidgets;
- size_t size = getRetainedWidgets(renderWidgets);
-
- for (size_t i = 0; i < size; ++i)
- renderWidgets[i]->updateWidgetPosition();
-
- for (size_t i = 0; i < size; ++i)
- renderWidgets[i]->widgetPositionsUpdated();
-
- releaseWidgets(renderWidgets);
-}
-
-void RenderView::addWidget(RenderWidget* o)
-{
- m_widgets.add(o);
-}
-
-void RenderView::removeWidget(RenderWidget* o)
-{
- m_widgets.remove(o);
-}
-
LayoutRect RenderView::viewRect() const
{
if (shouldUsePrintingLayout())
@@ -1019,12 +839,18 @@ IntRect RenderView::unscaledDocumentRect() const
bool RenderView::rootBackgroundIsEntirelyFixed() const
{
- RenderObject* rootObject = document().documentElement() ? document().documentElement()->renderer() : 0;
- if (!rootObject)
- return false;
+ if (RenderObject* backgroundRenderer = this->backgroundRenderer())
+ return backgroundRenderer->hasEntirelyFixedBackground();
+ return false;
+}
- RenderObject* rootRenderer = rootObject->rendererForRootBackground();
- return rootRenderer->hasEntirelyFixedBackground();
+RenderObject* RenderView::backgroundRenderer() const
+{
+ if (Element* documentElement = document().documentElement()) {
+ if (RenderObject* rootObject = documentElement->renderer())
+ return rootObject->rendererForRootBackground();
+ }
+ return 0;
}
LayoutRect RenderView::backgroundRect(RenderBox* backgroundRenderer) const
@@ -1049,7 +875,7 @@ IntRect RenderView::documentRect() const
return IntRect(overflowRect);
}
-int RenderView::viewHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion) const
+int RenderView::viewHeight(IncludeScrollbarsInRect scrollbarInclusion) const
{
int height = 0;
if (!shouldUsePrintingLayout() && m_frameView)
@@ -1058,7 +884,7 @@ int RenderView::viewHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarIncl
return height;
}
-int RenderView::viewWidth(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion) const
+int RenderView::viewWidth(IncludeScrollbarsInRect scrollbarInclusion) const
{
int width = 0;
if (!shouldUsePrintingLayout() && m_frameView)
@@ -1067,41 +893,21 @@ int RenderView::viewWidth(ScrollableArea::IncludeScrollbarsInRect scrollbarInclu
return width;
}
-int RenderView::viewLogicalHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion) const
-{
- int height = style()->isHorizontalWritingMode() ? viewHeight(scrollbarInclusion) : viewWidth(scrollbarInclusion);
-
- if (hasColumns() && !style()->hasInlineColumnAxis()) {
- if (int pageLength = m_frameView->pagination().pageLength)
- height = pageLength;
- }
-
- return height;
-}
-
-float RenderView::zoomFactor() const
+int RenderView::viewLogicalHeight() const
{
- return m_frameView->frame().pageZoomFactor();
+ return style()->isHorizontalWritingMode() ? viewHeight(ExcludeScrollbars) : viewWidth(ExcludeScrollbars);
}
-void RenderView::pushLayoutState(RenderObject* root)
+LayoutUnit RenderView::viewLogicalHeightForPercentages() const
{
- ASSERT(m_layoutStateDisableCount == 0);
- ASSERT(m_layoutState == 0);
-
- pushLayoutStateForCurrentFlowThread(root);
- m_layoutState = new LayoutState(root);
+ if (shouldUsePrintingLayout())
+ return pageLogicalHeight();
+ return viewLogicalHeight();
}
-bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
+float RenderView::zoomFactor() const
{
- RenderObject* o = renderer;
- while (o) {
- if (o->hasColumns() || o->hasTransform() || o->hasReflection())
- return true;
- o = o->container();
- }
- return false;
+ return m_frameView->frame().pageZoomFactor();
}
void RenderView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
@@ -1124,13 +930,13 @@ void RenderView::updateHitTestResult(HitTestResult& result, const LayoutPoint& p
bool RenderView::usesCompositing() const
{
- return m_compositor && m_compositor->inCompositingMode();
+ return m_compositor && m_compositor->staleInCompositingMode();
}
RenderLayerCompositor* RenderView::compositor()
{
if (!m_compositor)
- m_compositor = adoptPtr(new RenderLayerCompositor(this));
+ m_compositor = adoptPtr(new RenderLayerCompositor(*this));
return m_compositor.get();
}
@@ -1141,52 +947,28 @@ void RenderView::setIsInWindow(bool isInWindow)
m_compositor->setIsInWindow(isInWindow);
}
-CustomFilterGlobalContext* RenderView::customFilterGlobalContext()
-{
- if (!m_customFilterGlobalContext)
- m_customFilterGlobalContext = adoptPtr(new CustomFilterGlobalContext());
- return m_customFilterGlobalContext.get();
-}
-
-void RenderView::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderBlock::styleDidChange(diff, oldStyle);
- if (hasRenderNamedFlowThreads())
- flowThreadController()->styleDidChange();
-}
-
-bool RenderView::hasRenderNamedFlowThreads() const
-{
- return m_flowThreadController && m_flowThreadController->hasRenderNamedFlowThreads();
-}
-
-bool RenderView::checkTwoPassLayoutForAutoHeightRegions() const
-{
- return hasRenderNamedFlowThreads() && m_flowThreadController->hasFlowThreadsWithAutoLogicalHeightRegions();
-}
-
FlowThreadController* RenderView::flowThreadController()
{
if (!m_flowThreadController)
- m_flowThreadController = FlowThreadController::create(this);
+ m_flowThreadController = FlowThreadController::create();
return m_flowThreadController.get();
}
-void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject* object)
+void RenderView::pushLayoutState(LayoutState& layoutState)
{
- if (!m_flowThreadController)
- return;
-
- RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();
- if (!currentFlowThread)
- return;
-
- currentFlowThread->pushFlowThreadLayoutState(object);
+ if (m_flowThreadController) {
+ RenderFlowThread* currentFlowThread = m_flowThreadController->currentRenderFlowThread();
+ if (currentFlowThread)
+ currentFlowThread->pushFlowThreadLayoutState(layoutState.renderer());
+ }
+ m_layoutState = &layoutState;
}
-void RenderView::popLayoutStateForCurrentFlowThread()
+void RenderView::popLayoutState()
{
+ ASSERT(m_layoutState);
+ m_layoutState = m_layoutState->next();
if (!m_flowThreadController)
return;
@@ -1207,70 +989,22 @@ IntervalArena* RenderView::intervalArena()
bool RenderView::backgroundIsKnownToBeOpaqueInRect(const LayoutRect&) const
{
// FIXME: Remove this main frame check. Same concept applies to subframes too.
- if (!m_frameView || !m_frameView->isMainFrame())
+ if (!frame()->isMainFrame())
return false;
return m_frameView->hasOpaqueBackground();
}
-LayoutUnit RenderView::viewportPercentageWidth(float percentage) const
-{
- return viewLogicalWidth(ScrollableArea::IncludeScrollbars) * percentage / 100.f;
-}
-
-LayoutUnit RenderView::viewportPercentageHeight(float percentage) const
+double RenderView::layoutViewportWidth() const
{
- return viewLogicalHeight(ScrollableArea::IncludeScrollbars) * percentage / 100.f;
+ float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
+ return viewWidth(IncludeScrollbars) / scale;
}
-LayoutUnit RenderView::viewportPercentageMin(float percentage) const
+double RenderView::layoutViewportHeight() const
{
- return std::min(viewLogicalWidth(ScrollableArea::IncludeScrollbars), viewLogicalHeight(ScrollableArea::IncludeScrollbars))
- * percentage / 100.f;
-}
-
-LayoutUnit RenderView::viewportPercentageMax(float percentage) const
-{
- return std::max(viewLogicalWidth(ScrollableArea::IncludeScrollbars), viewLogicalHeight(ScrollableArea::IncludeScrollbars))
- * percentage / 100.f;
-}
-
-FragmentationDisabler::FragmentationDisabler(RenderObject* root)
-{
- RenderView* renderView = root->view();
- ASSERT(renderView);
-
- LayoutState* layoutState = renderView->layoutState();
-
- m_root = root;
- m_fragmenting = layoutState && layoutState->isPaginated();
- m_flowThreadState = m_root->flowThreadState();
-#ifndef NDEBUG
- m_layoutState = layoutState;
-#endif
-
- if (layoutState)
- layoutState->m_isPaginated = false;
-
- if (m_flowThreadState != RenderObject::NotInsideFlowThread)
- m_root->setFlowThreadStateIncludingDescendants(RenderObject::NotInsideFlowThread);
-}
-
-FragmentationDisabler::~FragmentationDisabler()
-{
- RenderView* renderView = m_root->view();
- ASSERT(renderView);
-
- LayoutState* layoutState = renderView->layoutState();
-#ifndef NDEBUG
- ASSERT(m_layoutState == layoutState);
-#endif
-
- if (layoutState)
- layoutState->m_isPaginated = m_fragmenting;
-
- if (m_flowThreadState != RenderObject::NotInsideFlowThread)
- m_root->setFlowThreadStateIncludingDescendants(m_flowThreadState);
+ float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
+ return viewHeight(IncludeScrollbars) / scale;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderView.h b/chromium/third_party/WebKit/Source/core/rendering/RenderView.h
index 246db98be54..2ca7efbe591 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderView.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderView.h
@@ -23,7 +23,6 @@
#define RenderView_h
#include "core/frame/FrameView.h"
-#include "core/rendering/LayoutIndicator.h"
#include "core/rendering/LayoutState.h"
#include "core/rendering/RenderBlockFlow.h"
#include "platform/PODFreeListArena.h"
@@ -32,11 +31,9 @@
namespace WebCore {
-class CustomFilterGlobalContext;
class FlowThreadController;
class RenderLayerCompositor;
class RenderQuote;
-class RenderWidget;
// The root of the render tree, corresponding to the CSS initial containing block.
// It's dimensions match that of the logical viewport (which may be different from
@@ -54,7 +51,7 @@ public:
virtual bool isRenderView() const OVERRIDE { return true; }
- virtual bool requiresLayer() const OVERRIDE { return true; }
+ virtual LayerType layerTypeRequired() const OVERRIDE { return NormalLayer; }
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
@@ -62,31 +59,28 @@ public:
virtual void updateLogicalWidth() OVERRIDE;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
- virtual bool supportsPartialLayout() const OVERRIDE { return true; }
-
virtual LayoutUnit availableLogicalHeight(AvailableLogicalHeightType) const OVERRIDE;
// The same as the FrameView's layoutHeight/layoutWidth but with null check guards.
- int viewHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion = ScrollableArea::ExcludeScrollbars) const;
- int viewWidth(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion = ScrollableArea::ExcludeScrollbars) const;
- int viewLogicalWidth(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion = ScrollableArea::ExcludeScrollbars) const
+ int viewHeight(IncludeScrollbarsInRect = ExcludeScrollbars) const;
+ int viewWidth(IncludeScrollbarsInRect = ExcludeScrollbars) const;
+ int viewLogicalWidth() const
{
- return style()->isHorizontalWritingMode() ? viewWidth(scrollbarInclusion) : viewHeight(scrollbarInclusion);
+ return style()->isHorizontalWritingMode() ? viewWidth(ExcludeScrollbars) : viewHeight(ExcludeScrollbars);
}
- int viewLogicalHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion = ScrollableArea::ExcludeScrollbars) const;
+ int viewLogicalHeight() const;
+ LayoutUnit viewLogicalHeightForPercentages() const;
float zoomFactor() const;
FrameView* frameView() const { return m_frameView; }
- virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
+ virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
void repaintViewRectangle(const LayoutRect&) const;
- // Repaint the view, and all composited layers that intersect the given absolute rectangle.
- // FIXME: ideally we'd never have to do this, if all repaints are container-relative.
- void repaintRectangleInViewAndCompositedLayers(const LayoutRect&);
+
void repaintViewAndCompositedLayers();
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE;
enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld, RepaintNothing };
@@ -99,61 +93,50 @@ public:
void selectionStartEnd(int& startPos, int& endPos) const;
void repaintSelection() const;
- virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
- virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
-
- void setMaximalOutlineSize(int o);
- int maximalOutlineSize() const { return m_maximalOutlineSize; }
-
- void setOldMaximalOutlineSize(int o) { m_oldMaximalOutlineSize = o; }
- int oldMaximalOutlineSize() const { return m_oldMaximalOutlineSize; }
+ virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE;
+ virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE;
virtual LayoutRect viewRect() const OVERRIDE;
- void updateWidgetPositions();
- void addWidget(RenderWidget*);
- void removeWidget(RenderWidget*);
-
// layoutDelta is used transiently during layout to store how far an object has moved from its
// last layout location, in order to repaint correctly.
// If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter.
LayoutSize layoutDelta() const
{
- return m_layoutState ? m_layoutState->m_layoutDelta : LayoutSize();
+ ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
+ return m_layoutState ? m_layoutState->layoutDelta() : LayoutSize();
}
void addLayoutDelta(const LayoutSize& delta)
{
- if (m_layoutState) {
- m_layoutState->m_layoutDelta += delta;
-#if !ASSERT_DISABLED
- m_layoutState->m_layoutDeltaXSaturated |= m_layoutState->m_layoutDelta.width() == LayoutUnit::max() || m_layoutState->m_layoutDelta.width() == LayoutUnit::min();
- m_layoutState->m_layoutDeltaYSaturated |= m_layoutState->m_layoutDelta.height() == LayoutUnit::max() || m_layoutState->m_layoutDelta.height() == LayoutUnit::min();
-#endif
- }
+ ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
+ if (m_layoutState)
+ m_layoutState->addLayoutDelta(delta);
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool layoutDeltaMatches(const LayoutSize& delta)
{
+ ASSERT(!RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
if (!m_layoutState)
return false;
- return (delta.width() == m_layoutState->m_layoutDelta.width() || m_layoutState->m_layoutDeltaXSaturated) && (delta.height() == m_layoutState->m_layoutDelta.height() || m_layoutState->m_layoutDeltaYSaturated);
+ return (delta.width() == m_layoutState->layoutDelta().width() || m_layoutState->layoutDeltaXSaturated()) && (delta.height() == m_layoutState->layoutDelta().height() || m_layoutState->layoutDeltaYSaturated());
}
#endif
- bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); }
-
- // Subtree push/pop
- void pushLayoutState(RenderObject*);
- void popLayoutState(RenderObject*) { return popLayoutState(); } // Just doing this to keep popLayoutState() private and to make the subtree calls symmetrical.
-
- bool shouldDisableLayoutStateForSubtree(RenderObject*) const;
+ bool shouldDoFullRepaintForNextLayout() const;
+ bool doingFullRepaint() const { return m_frameView->needsFullPaintInvalidation(); }
// Returns true if layoutState should be used for its cached offset and clip.
- bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m_layoutState; }
+ bool layoutStateCachedOffsetsEnabled() const { return m_layoutState && m_layoutState->cachedOffsetsEnabled(); }
LayoutState* layoutState() const { return m_layoutState; }
- virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&);
+ bool canMapUsingLayoutStateForContainer(const RenderObject* repaintContainer) const
+ {
+ // FIXME: LayoutState should be enabled for other repaint containers than the RenderView. crbug.com/363834
+ return layoutStateCachedOffsetsEnabled() && (repaintContainer == this);
+ }
+
+ virtual void updateHitTestResult(HitTestResult&, const LayoutPoint&) OVERRIDE;
LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; }
void setPageLogicalHeight(LayoutUnit height)
@@ -163,6 +146,7 @@ public:
m_pageLogicalHeightChanged = true;
}
}
+ bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
// Notification that this view moved into or out of a native window.
void setIsInWindow(bool);
@@ -170,8 +154,6 @@ public:
RenderLayerCompositor* compositor();
bool usesCompositing() const;
- CustomFilterGlobalContext* customFilterGlobalContext();
-
IntRect unscaledDocumentRect() const;
LayoutRect backgroundRect(RenderBox* backgroundRenderer) const;
@@ -180,12 +162,8 @@ public:
// Renderer that paints the root background has background-images which all have background-attachment: fixed.
bool rootBackgroundIsEntirelyFixed() const;
- bool hasRenderNamedFlowThreads() const;
- bool checkTwoPassLayoutForAutoHeightRegions() const;
FlowThreadController* flowThreadController();
- void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-
IntervalArena* intervalArena();
void setRenderQuoteHead(RenderQuote* head) { m_renderQuoteHead = head; }
@@ -199,81 +177,39 @@ public:
void removeRenderCounter() { ASSERT(m_renderCounterCount > 0); m_renderCounterCount--; }
bool hasRenderCounters() { return m_renderCounterCount; }
- virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
+ virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const OVERRIDE;
- virtual bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const OVERRIDE FINAL;
-
- LayoutUnit viewportPercentageWidth(float percentage) const;
- LayoutUnit viewportPercentageHeight(float percentage) const;
- LayoutUnit viewportPercentageMin(float percentage) const;
- LayoutUnit viewportPercentageMax(float percentage) const;
+ double layoutViewportWidth() const;
+ double layoutViewportHeight() const;
+ void pushLayoutState(LayoutState&);
+ void popLayoutState();
private:
virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
- virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const;
- virtual bool requiresColumns(int desiredColumnCount) const OVERRIDE;
+ virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE;
virtual void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const OVERRIDE;
- bool initializeLayoutState(LayoutState&);
-
- virtual void calcColumnWidth() OVERRIDE;
- virtual ColumnInfo::PaginationUnit paginationUnit() const OVERRIDE;
+ virtual void invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer) OVERRIDE FINAL;
bool shouldRepaint(const LayoutRect&) const;
- // These functions may only be accessed by LayoutStateMaintainer.
- bool pushLayoutState(RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
- {
- // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
- if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer->hasColumns() || renderer->flowThreadContainingBlock()
- || m_layoutState->lineGrid() || (renderer->style()->lineGrid() != RenderStyle::initialLineGrid() && renderer->isRenderBlockFlow())
- || (renderer->isRenderBlock() && toRenderBlock(renderer)->shapeInsideInfo())
- || (m_layoutState->shapeInsideInfo() && renderer->isRenderBlock() && !toRenderBlock(renderer)->allowsShapeInsideInfoSharing(m_layoutState->shapeInsideInfo()->owner()))
- ) {
- pushLayoutStateForCurrentFlowThread(renderer);
- m_layoutState = new LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo);
- return true;
- }
- return false;
- }
-
- void popLayoutState()
- {
- LayoutState* state = m_layoutState;
- m_layoutState = state->m_next;
- delete state;
- popLayoutStateForCurrentFlowThread();
- }
-
- // Suspends the LayoutState optimization. Used under transforms that cannot be represented by
- // LayoutState (common in SVG) and when manipulating the render tree during layout in ways
- // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around).
- // Note that even when disabled, LayoutState is still used to store layoutDelta.
- // These functions may only be accessed by LayoutStateMaintainer or LayoutStateDisabler.
- void disableLayoutState() { m_layoutStateDisableCount++; }
- void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; }
+ bool rootFillsViewportBackground(RenderBox* rootBox) const;
- void layoutContent(const LayoutState&);
- void layoutContentInAutoLogicalHeightRegions(const LayoutState&);
+ void layoutContent();
#ifndef NDEBUG
- void checkLayoutState(const LayoutState&);
+ void checkLayoutState();
#endif
void positionDialog(RenderBox*);
void positionDialogs();
- size_t getRetainedWidgets(Vector<RenderWidget*>&);
- void releaseWidgets(Vector<RenderWidget*>&);
-
- void pushLayoutStateForCurrentFlowThread(const RenderObject*);
- void popLayoutStateForCurrentFlowThread();
-
- friend class LayoutStateMaintainer;
- friend class LayoutStateDisabler;
+ friend class ForceHorriblySlowRectMapping;
bool shouldUsePrintingLayout() const;
+ RenderObject* backgroundRenderer() const;
+
FrameView* m_frameView;
RenderObject* m_selectionStart;
@@ -282,18 +218,10 @@ private:
int m_selectionStartPos;
int m_selectionEndPos;
- int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
- int m_oldMaximalOutlineSize; // The fudge factor from the previous layout.
-
- typedef HashSet<RenderWidget*> RenderWidgetSet;
- RenderWidgetSet m_widgets;
-
LayoutUnit m_pageLogicalHeight;
bool m_pageLogicalHeightChanged;
LayoutState* m_layoutState;
- unsigned m_layoutStateDisableCount;
OwnPtr<RenderLayerCompositor> m_compositor;
- OwnPtr<CustomFilterGlobalContext> m_customFilterGlobalContext;
OwnPtr<FlowThreadController> m_flowThreadController;
RefPtr<IntervalArena> m_intervalArena;
@@ -303,99 +231,35 @@ private:
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderView, isRenderView());
-// Stack-based class to assist with LayoutState push/pop
-class LayoutStateMaintainer {
- WTF_MAKE_NONCOPYABLE(LayoutStateMaintainer);
+// Suspends the LayoutState cached offset and clipRect optimization. Used under transforms
+// that cannot be represented by LayoutState (common in SVG) and when manipulating the render
+// tree during layout in ways that can trigger repaint of a non-child (e.g. when a list item
+// moves its list marker around). Note that even when disabled, LayoutState is still used to
+// store layoutDelta.
+class ForceHorriblySlowRectMapping {
+ WTF_MAKE_NONCOPYABLE(ForceHorriblySlowRectMapping);
public:
- // ctor to push now
- LayoutStateMaintainer(RenderView* view, RenderBox* root, LayoutSize offset, bool disableState = false, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
- : m_view(view)
- , m_disabled(disableState)
- , m_didStart(false)
- , m_didEnd(false)
- , m_didCreateLayoutState(false)
+ ForceHorriblySlowRectMapping(const RenderObject& root)
+ : m_view(*root.view())
+ , m_didDisable(m_view.layoutState() && m_view.layoutState()->cachedOffsetsEnabled())
{
- push(root, offset, pageHeight, pageHeightChanged, colInfo);
- }
-
- // ctor to maybe push later
- LayoutStateMaintainer(RenderView* view)
- : m_view(view)
- , m_disabled(false)
- , m_didStart(false)
- , m_didEnd(false)
- , m_didCreateLayoutState(false)
- {
- }
-
- ~LayoutStateMaintainer()
- {
- ASSERT(m_didStart == m_didEnd); // if this fires, it means that someone did a push(), but forgot to pop().
- }
-
- void push(RenderBox* root, LayoutSize offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
- {
- ASSERT(!m_didStart);
- // We push state even if disabled, because we still need to store layoutDelta
- m_didCreateLayoutState = m_view->pushLayoutState(root, offset, pageHeight, pageHeightChanged, colInfo);
- if (m_disabled && m_didCreateLayoutState)
- m_view->disableLayoutState();
- m_didStart = true;
- }
-
- void pop()
- {
- if (m_didStart) {
- ASSERT(!m_didEnd);
- if (m_didCreateLayoutState) {
- m_view->popLayoutState();
- if (m_disabled)
- m_view->enableLayoutState();
- }
-
- m_didEnd = true;
- }
- }
-
- bool didPush() const { return m_didStart; }
-
-private:
- RenderView* m_view;
- bool m_disabled : 1; // true if the offset and clip part of layoutState is disabled
- bool m_didStart : 1; // true if we did a push or disable
- bool m_didEnd : 1; // true if we popped or re-enabled
- bool m_didCreateLayoutState : 1; // true if we actually made a layout state.
-};
-
-class LayoutStateDisabler {
- WTF_MAKE_NONCOPYABLE(LayoutStateDisabler);
-public:
- LayoutStateDisabler(RenderView* view)
- : m_view(view)
- {
- if (m_view)
- m_view->disableLayoutState();
+ if (m_view.layoutState())
+ m_view.layoutState()->m_cachedOffsetsEnabled = false;
+#if ASSERT_ENABLED
+ m_layoutState = m_view.layoutState();
+#endif
}
- ~LayoutStateDisabler()
+ ~ForceHorriblySlowRectMapping()
{
- if (m_view)
- m_view->enableLayoutState();
+ ASSERT(m_view.layoutState() == m_layoutState);
+ if (m_didDisable)
+ m_view.layoutState()->m_cachedOffsetsEnabled = true;
}
private:
- RenderView* m_view;
-};
-
-class FragmentationDisabler {
- WTF_MAKE_NONCOPYABLE(FragmentationDisabler);
-public:
- FragmentationDisabler(RenderObject* root);
- ~FragmentationDisabler();
-private:
- RenderObject* m_root;
- RenderObject::FlowThreadState m_flowThreadState;
- bool m_fragmenting;
-#ifndef NDEBUG
+ RenderView& m_view;
+ bool m_didDisable;
+#if ASSERT_ENABLED
LayoutState* m_layoutState;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderWidget.cpp b/chromium/third_party/WebKit/Source/core/rendering/RenderWidget.cpp
index 90b089686a8..43ecbdf8a8b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderWidget.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderWidget.cpp
@@ -25,89 +25,42 @@
#include "core/rendering/RenderWidget.h"
#include "core/accessibility/AXObjectCache.h"
-#include "core/frame/Frame.h"
-#include "core/rendering/CompositedLayerMapping.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLFrameOwnerElement.h"
+#include "core/html/HTMLPlugInElement.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
-#include "platform/graphics/GraphicsContext.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "wtf/HashMap.h"
namespace WebCore {
-typedef HashMap<RefPtr<Widget>, FrameView*> WidgetToParentMap;
-static WidgetToParentMap& widgetNewParentMap()
-{
- DEFINE_STATIC_LOCAL(WidgetToParentMap, map, ());
- return map;
-}
-
-static unsigned s_updateSuspendCount = 0;
-
-RenderWidget::UpdateSuspendScope::UpdateSuspendScope()
-{
- ++s_updateSuspendCount;
-}
-
-RenderWidget::UpdateSuspendScope::~UpdateSuspendScope()
-{
- ASSERT(s_updateSuspendCount > 0);
- if (s_updateSuspendCount == 1) {
- WidgetToParentMap map;
- widgetNewParentMap().swap(map);
- WidgetToParentMap::iterator end = map.end();
- for (WidgetToParentMap::iterator it = map.begin(); it != end; ++it) {
- Widget* child = it->key.get();
- ScrollView* currentParent = toScrollView(child->parent());
- FrameView* newParent = it->value;
- if (newParent != currentParent) {
- if (currentParent)
- currentParent->removeChild(child);
- if (newParent)
- newParent->addChild(child);
- }
- }
- }
- --s_updateSuspendCount;
-}
-
-static void moveWidgetToParentSoon(Widget* child, FrameView* parent)
-{
- if (!s_updateSuspendCount) {
- if (parent)
- parent->addChild(child);
- else
- toScrollView(child->parent())->removeChild(child);
- return;
- }
- widgetNewParentMap().set(child, parent);
-}
-
RenderWidget::RenderWidget(Element* element)
: RenderReplaced(element)
- , m_widget(0)
- , m_frameView(element->document().view())
// Reference counting is used to prevent the widget from being
// destroyed while inside the Widget code, which might not be
// able to handle that.
, m_refCount(1)
{
- view()->addWidget(this);
+ ASSERT(element);
+ frameView()->addWidget(this);
}
void RenderWidget::willBeDestroyed()
{
- if (RenderView* v = view())
- v->removeWidget(this);
+ frameView()->removeWidget(this);
if (AXObjectCache* cache = document().existingAXObjectCache()) {
cache->childrenChanged(this->parent());
cache->remove(this);
}
- setWidget(0);
+ Element* element = toElement(node());
+ if (element && element->isFrameOwnerElement())
+ toHTMLFrameOwnerElement(element)->setWidget(nullptr);
RenderReplaced::willBeDestroyed();
}
@@ -122,7 +75,17 @@ void RenderWidget::destroy()
RenderWidget::~RenderWidget()
{
ASSERT(m_refCount <= 0);
- clearWidget();
+}
+
+Widget* RenderWidget::widget() const
+{
+ // Plugin widgets are stored in their DOM node. This includes HTMLAppletElement.
+ Element* element = toElement(node());
+
+ if (element && element->isFrameOwnerElement())
+ return toHTMLFrameOwnerElement(element)->ownedWidget();
+
+ return 0;
}
// Widgets are always placed on integer boundaries, so rounding the size is actually
@@ -138,35 +101,28 @@ bool RenderWidget::setWidgetGeometry(const LayoutRect& frame)
if (!node())
return false;
- IntRect clipRect = roundedIntRect(enclosingLayer()->childrenClipRect());
+ Widget* widget = this->widget();
+ ASSERT(widget);
+
IntRect newFrame = roundedIntRect(frame);
- bool clipChanged = m_clipRect != clipRect;
- bool frameRectChanged = m_widget->frameRect() != newFrame;
- if (!frameRectChanged && !clipChanged)
+ if (widget->frameRect() == newFrame)
return false;
- m_clipRect = clipRect;
-
RefPtr<RenderWidget> protector(this);
- RefPtr<Node> protectedNode(node());
- m_widget->setFrameRect(newFrame);
-
- if (clipChanged && !frameRectChanged)
- m_widget->clipRectChanged();
-
- if (hasLayer() && layer()->compositingState() == PaintsIntoOwnBacking)
- layer()->compositedLayerMapping()->updateAfterWidgetResize();
-
- bool boundsChanged = m_widget->frameRect().size() != newFrame.size();
- return boundsChanged;
+ RefPtrWillBeRawPtr<Node> protectedNode(node());
+ widget->setFrameRect(newFrame);
+ return widget->frameRect().size() != newFrame.size();
}
bool RenderWidget::updateWidgetGeometry()
{
+ Widget* widget = this->widget();
+ ASSERT(widget);
+
LayoutRect contentBox = contentBoxRect();
LayoutRect absoluteContentBox(localToAbsoluteQuad(FloatQuad(contentBox)).boundingBox());
- if (m_widget->isFrameView()) {
+ if (widget->isFrameView()) {
contentBox.setLocation(absoluteContentBox.location());
return setWidgetGeometry(contentBox);
}
@@ -174,54 +130,24 @@ bool RenderWidget::updateWidgetGeometry()
return setWidgetGeometry(absoluteContentBox);
}
-void RenderWidget::setWidget(PassRefPtr<Widget> widget)
-{
- if (widget == m_widget)
- return;
-
- if (m_widget) {
- moveWidgetToParentSoon(m_widget.get(), 0);
- clearWidget();
- }
- m_widget = widget;
- if (m_widget) {
- // If we've already received a layout, apply the calculated space to the
- // widget immediately, but we have to have really been fully constructed (with a non-null
- // style pointer).
- if (style()) {
- if (!needsLayout())
- updateWidgetGeometry();
-
- if (style()->visibility() != VISIBLE)
- m_widget->hide();
- else {
- m_widget->show();
- repaint();
- }
- }
- moveWidgetToParentSoon(m_widget.get(), m_frameView);
- }
-
- if (AXObjectCache* cache = document().existingAXObjectCache())
- cache->childrenChanged(this);
-}
-
void RenderWidget::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
clearNeedsLayout();
}
void RenderWidget::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderReplaced::styleDidChange(diff, oldStyle);
- if (m_widget) {
- if (style()->visibility() != VISIBLE)
- m_widget->hide();
- else
- m_widget->show();
+ Widget* widget = this->widget();
+
+ if (widget) {
+ if (style()->visibility() != VISIBLE) {
+ widget->hide();
+ } else {
+ widget->show();
+ }
}
}
@@ -229,9 +155,12 @@ void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintO
{
LayoutPoint adjustedPaintOffset = paintOffset + location();
+ Widget* widget = this->widget();
+ ASSERT(widget);
+
// Tell the widget to paint now. This is the only time the widget is allowed
// to paint itself. That way it will composite properly with z-indexed layers.
- IntPoint widgetLocation = m_widget->frameRect().location();
+ IntPoint widgetLocation = widget->frameRect().location();
IntPoint paintLocation(roundToInt(adjustedPaintOffset.x() + borderLeft() + paddingLeft()),
roundToInt(adjustedPaintOffset.y() + borderTop() + paddingTop()));
IntRect paintRect = paintInfo.rect;
@@ -240,20 +169,20 @@ void RenderWidget::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintO
// When painting widgets into compositing layers, tx and ty are relative to the enclosing compositing layer,
// not the root. In this case, shift the CTM and adjust the paintRect to be root-relative to fix plug-in drawing.
if (!widgetPaintOffset.isZero()) {
- paintInfo.context->translate(widgetPaintOffset);
+ paintInfo.context->translate(widgetPaintOffset.width(), widgetPaintOffset.height());
paintRect.move(-widgetPaintOffset);
}
- m_widget->paint(paintInfo.context, paintRect);
+ widget->paint(paintInfo.context, paintRect);
if (!widgetPaintOffset.isZero())
- paintInfo.context->translate(-widgetPaintOffset);
+ paintInfo.context->translate(-widgetPaintOffset.width(), -widgetPaintOffset.height());
- if (m_widget->isFrameView()) {
- FrameView* frameView = toFrameView(m_widget.get());
+ if (widget->isFrameView()) {
+ FrameView* frameView = toFrameView(widget);
bool runOverlapTests = !frameView->useSlowRepaintsIfNotOverlapped() || frameView->hasCompositedContent();
if (paintInfo.overlapTestRequests && runOverlapTests) {
ASSERT(!paintInfo.overlapTestRequests->contains(this));
- paintInfo.overlapTestRequests->set(this, m_widget->frameRect());
+ paintInfo.overlapTestRequests->set(this, widget->frameRect());
}
}
}
@@ -278,7 +207,7 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && hasOutline())
paintOutline(paintInfo, LayoutRect(adjustedPaintOffset, size()));
- if (!m_frameView || paintInfo.phase != PaintPhaseForeground)
+ if (paintInfo.phase != PaintPhaseForeground)
return;
if (style()->hasBorderRadius()) {
@@ -294,7 +223,8 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
clipRoundedInnerRect(paintInfo.context, borderRect, roundedInnerRect);
}
- if (m_widget)
+ Widget* widget = this->widget();
+ if (widget)
paintContents(paintInfo, paintOffset);
if (style()->hasBorderRadius())
@@ -312,9 +242,10 @@ void RenderWidget::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
void RenderWidget::setIsOverlapped(bool isOverlapped)
{
- ASSERT(m_widget);
- ASSERT(m_widget->isFrameView());
- toFrameView(m_widget.get())->setIsOverlapped(isOverlapped);
+ Widget* widget = this->widget();
+ ASSERT(widget);
+ ASSERT(widget->isFrameView());
+ toFrameView(widget)->setIsOverlapped(isOverlapped);
}
void RenderWidget::deref()
@@ -323,17 +254,39 @@ void RenderWidget::deref()
postDestroy();
}
+void RenderWidget::updateOnWidgetChange()
+{
+ Widget* widget = this->widget();
+ if (!widget)
+ return;
+
+ if (!style())
+ return;
+
+ if (!needsLayout())
+ updateWidgetGeometry();
+
+ if (style()->visibility() != VISIBLE) {
+ widget->hide();
+ } else {
+ widget->show();
+ // FIXME: Why do we repaint in this case, but not the other?
+ paintInvalidationForWholeRenderer();
+ }
+}
+
void RenderWidget::updateWidgetPosition()
{
- if (!m_widget || !node()) // Check the node in case destroy() has been called.
+ Widget* widget = this->widget();
+ if (!widget || !node()) // Check the node in case destroy() has been called.
return;
bool boundsChanged = updateWidgetGeometry();
// if the frame bounds got changed, or if view needs layout (possibly indicating
// content size is wrong) we have to do a layout to set the right widget size
- if (m_widget && m_widget->isFrameView()) {
- FrameView* frameView = toFrameView(m_widget.get());
+ if (widget && widget->isFrameView()) {
+ FrameView* frameView = toFrameView(widget);
// Check the frame's page to make sure that the frame isn't in the process of being destroyed.
if ((boundsChanged || frameView->needsLayout()) && frameView->frame().page())
frameView->layout();
@@ -342,14 +295,10 @@ void RenderWidget::updateWidgetPosition()
void RenderWidget::widgetPositionsUpdated()
{
- if (!m_widget)
+ Widget* widget = this->widget();
+ if (!widget)
return;
- m_widget->widgetPositionsUpdated();
-}
-
-void RenderWidget::clearWidget()
-{
- m_widget = 0;
+ widget->widgetPositionsUpdated();
}
bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderWidget.h b/chromium/third_party/WebKit/Source/core/rendering/RenderWidget.h
index 2cde8486906..7c29616245d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderWidget.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderWidget.h
@@ -31,9 +31,9 @@ class RenderWidget : public RenderReplaced {
public:
virtual ~RenderWidget();
- Widget* widget() const { return m_widget.get(); }
- virtual void setWidget(PassRefPtr<Widget>);
+ Widget* widget() const;
+ void updateOnWidgetChange();
void updateWidgetPosition();
void widgetPositionsUpdated();
@@ -42,37 +42,26 @@ public:
void ref() { ++m_refCount; }
void deref();
- class UpdateSuspendScope {
- public:
- UpdateSuspendScope();
- ~UpdateSuspendScope();
- };
+ virtual bool isWidget() const OVERRIDE FINAL { return true; }
+ bool updateWidgetGeometry();
protected:
explicit RenderWidget(Element*);
- void clearWidget();
-
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE FINAL;
- virtual void layout();
- virtual void paint(PaintInfo&, const LayoutPoint&);
- virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
+ virtual void layout() OVERRIDE;
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const OVERRIDE FINAL;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
virtual void paintContents(PaintInfo&, const LayoutPoint&);
private:
- virtual bool isWidget() const OVERRIDE FINAL { return true; }
-
virtual void willBeDestroyed() OVERRIDE FINAL;
virtual void destroy() OVERRIDE FINAL;
bool setWidgetGeometry(const LayoutRect&);
- bool updateWidgetGeometry();
- RefPtr<Widget> m_widget;
- FrameView* m_frameView;
- IntRect m_clipRect; // The rectangle needs to remain correct after scrolling, so it is stored in content view coordinates, and not clipped to window.
int m_refCount;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RenderWordBreak.h b/chromium/third_party/WebKit/Source/core/rendering/RenderWordBreak.h
index acf3c6075d0..d5b0d31c73d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RenderWordBreak.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RenderWordBreak.h
@@ -37,8 +37,8 @@ class RenderWordBreak FINAL : public RenderText {
public:
explicit RenderWordBreak(HTMLElement*);
- virtual const char* renderName() const;
- virtual bool isWordBreak() const;
+ virtual const char* renderName() const OVERRIDE;
+ virtual bool isWordBreak() const OVERRIDE;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.cpp
index 871cf0ff1ad..5b0a8fde96c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.cpp
@@ -47,7 +47,7 @@ COMPILE_ASSERT(sizeof(RootInlineBox) == sizeof(SameSizeAsRootInlineBox), RootInl
typedef WTF::HashMap<const RootInlineBox*, EllipsisBox*> EllipsisBoxMap;
static EllipsisBoxMap* gEllipsisBoxMap = 0;
-RootInlineBox::RootInlineBox(RenderBlockFlow* block)
+RootInlineBox::RootInlineBox(RenderBlockFlow& block)
: InlineFlowBox(block)
, m_lineBreakPos(0)
, m_lineBreakObj(0)
@@ -56,7 +56,7 @@ RootInlineBox::RootInlineBox(RenderBlockFlow* block)
, m_lineTopWithLeading(0)
, m_lineBottomWithLeading(0)
{
- setIsHorizontal(block->isHorizontalWritingMode());
+ setIsHorizontal(block.isHorizontalWritingMode());
}
@@ -78,7 +78,7 @@ void RootInlineBox::detachEllipsisBox()
RenderLineBoxList* RootInlineBox::rendererLineBoxes() const
{
- return block()->lineBoxes();
+ return block().lineBoxes();
}
void RootInlineBox::clearTruncation()
@@ -164,7 +164,7 @@ float RootInlineBox::placeEllipsisBox(bool ltr, float blockLeftEdge, float block
void RootInlineBox::paintEllipsisBox(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) const
{
- if (hasEllipsisBox() && paintInfo.shouldPaintWithinRoot(renderer()) && renderer()->style()->visibility() == VISIBLE
+ if (hasEllipsisBox() && paintInfo.shouldPaintWithinRoot(&renderer()) && renderer().style()->visibility() == VISIBLE
&& paintInfo.phase == PaintPhaseForeground)
ellipsisBox()->paint(paintInfo, paintOffset, lineTop, lineBottom);
}
@@ -179,7 +179,7 @@ bool RootInlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
{
if (hasEllipsisBox() && visibleToHitTestRequest(request)) {
if (ellipsisBox()->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom)) {
- renderer()->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
+ renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
return true;
}
}
@@ -200,38 +200,15 @@ void RootInlineBox::adjustPosition(float dx, float dy)
void RootInlineBox::childRemoved(InlineBox* box)
{
- if (box->renderer() == m_lineBreakObj)
+ if (&box->renderer() == m_lineBreakObj)
setLineBreakInfo(0, 0, BidiStatus());
- for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == box->renderer(); prev = prev->prevRootBox()) {
+ for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == &box->renderer(); prev = prev->prevRootBox()) {
prev->setLineBreakInfo(0, 0, BidiStatus());
prev->markDirty();
}
}
-RenderRegion* RootInlineBox::containingRegion() const
-{
- RenderRegion* region = m_fragmentationData ? m_fragmentationData->m_containingRegion : 0;
-
-#ifndef NDEBUG
- if (region) {
- RenderFlowThread* flowThread = block()->flowThreadContainingBlock();
- const RenderRegionList& regionList = flowThread->renderRegionList();
- ASSERT(regionList.contains(region));
- }
-#endif
-
- return region;
-}
-
-void RootInlineBox::setContainingRegion(RenderRegion* region)
-{
- ASSERT(!isDirty());
- ASSERT(block()->flowThreadContainingBlock());
- LineFragmentationData* fragmentationData = ensureLineFragmentationData();
- fragmentationData->m_containingRegion = region;
-}
-
LayoutUnit RootInlineBox::alignBoxesInBlockDirection(LayoutUnit heightOfBlock, GlyphOverflowAndFallbackFontsMap& textBoxDataMap, VerticalPositionCache& verticalPositionCache)
{
// SVG will handle vertical alignment on its own.
@@ -246,7 +223,7 @@ LayoutUnit RootInlineBox::alignBoxesInBlockDirection(LayoutUnit heightOfBlock, G
bool setMaxDescent = false;
// Figure out if we're in no-quirks mode.
- bool noQuirksMode = renderer()->document().inNoQuirksMode();
+ bool noQuirksMode = renderer().document().inNoQuirksMode();
m_baselineType = requiresIdeographicBaseline(textBoxDataMap) ? IdeographicBaseline : AlphabeticBaseline;
@@ -272,22 +249,17 @@ LayoutUnit RootInlineBox::alignBoxesInBlockDirection(LayoutUnit heightOfBlock, G
maxHeight = max<LayoutUnit>(0, maxHeight); // FIXME: Is this really necessary?
setLineTopBottomPositions(lineTop, lineBottom, heightOfBlock, heightOfBlock + maxHeight);
- setPaginatedLineWidth(block()->availableLogicalWidthForContent(heightOfBlock));
+ if (block().view()->layoutState()->isPaginated())
+ setPaginatedLineWidth(block().availableLogicalWidthForContent());
LayoutUnit annotationsAdjustment = beforeAnnotationsAdjustment();
if (annotationsAdjustment) {
// FIXME: Need to handle pagination here. We might have to move to the next page/column as a result of the
// ruby expansion.
- adjustBlockDirectionPosition(annotationsAdjustment);
+ adjustBlockDirectionPosition(annotationsAdjustment.toFloat());
heightOfBlock += annotationsAdjustment;
}
- LayoutUnit gridSnapAdjustment = lineSnapAdjustment();
- if (gridSnapAdjustment) {
- adjustBlockDirectionPosition(gridSnapAdjustment);
- heightOfBlock += gridSnapAdjustment;
- }
-
return heightOfBlock + maxHeight;
}
@@ -302,7 +274,7 @@ LayoutUnit RootInlineBox::beforeAnnotationsAdjustment() const
{
LayoutUnit result = 0;
- if (!renderer()->style()->isFlippedLinesWritingMode()) {
+ if (!renderer().style()->isFlippedLinesWritingMode()) {
// Annotations under the previous line may push us down.
if (prevRootBox() && prevRootBox()->hasAnnotationsAfter())
result = prevRootBox()->computeUnderAnnotationAdjustment(lineTop());
@@ -311,12 +283,12 @@ LayoutUnit RootInlineBox::beforeAnnotationsAdjustment() const
return result;
// Annotations over this line may push us further down.
- LayoutUnit highestAllowedPosition = prevRootBox() ? min(prevRootBox()->lineBottom(), lineTop()) + result : static_cast<LayoutUnit>(block()->borderBefore());
+ LayoutUnit highestAllowedPosition = prevRootBox() ? min(prevRootBox()->lineBottom(), lineTop()) + result : static_cast<LayoutUnit>(block().borderBefore());
result = computeOverAnnotationAdjustment(highestAllowedPosition);
} else {
// Annotations under this line may push us up.
if (hasAnnotationsBefore())
- result = computeUnderAnnotationAdjustment(prevRootBox() ? prevRootBox()->lineBottom() : static_cast<LayoutUnit>(block()->borderBefore()));
+ result = computeUnderAnnotationAdjustment(prevRootBox() ? prevRootBox()->lineBottom() : static_cast<LayoutUnit>(block().borderBefore()));
if (!prevRootBox() || !prevRootBox()->hasAnnotationsAfter())
return result;
@@ -329,115 +301,26 @@ LayoutUnit RootInlineBox::beforeAnnotationsAdjustment() const
return result;
}
-LayoutUnit RootInlineBox::lineSnapAdjustment(LayoutUnit delta) const
-{
- // If our block doesn't have snapping turned on, do nothing.
- // FIXME: Implement bounds snapping.
- if (block()->style()->lineSnap() == LineSnapNone)
- return 0;
-
- // Get the current line grid and offset.
- LayoutState* layoutState = block()->view()->layoutState();
- RenderBlockFlow* lineGrid = layoutState->lineGrid();
- LayoutSize lineGridOffset = layoutState->lineGridOffset();
- if (!lineGrid || lineGrid->style()->writingMode() != block()->style()->writingMode())
- return 0;
-
- // Get the hypothetical line box used to establish the grid.
- RootInlineBox* lineGridBox = lineGrid->lineGridBox();
- if (!lineGridBox)
- return 0;
-
- LayoutUnit lineGridBlockOffset = lineGrid->isHorizontalWritingMode() ? lineGridOffset.height() : lineGridOffset.width();
- LayoutUnit blockOffset = block()->isHorizontalWritingMode() ? layoutState->layoutOffset().height() : layoutState->layoutOffset().width();
-
- // Now determine our position on the grid. Our baseline needs to be adjusted to the nearest baseline multiple
- // as established by the line box.
- // FIXME: Need to handle crazy line-box-contain values that cause the root line box to not be considered. I assume
- // the grid should honor line-box-contain.
- LayoutUnit gridLineHeight = lineGridBox->lineBottomWithLeading() - lineGridBox->lineTopWithLeading();
- if (!gridLineHeight)
- return 0;
-
- LayoutUnit lineGridFontAscent = lineGrid->style()->fontMetrics().ascent(baselineType());
- LayoutUnit lineGridFontHeight = lineGridBox->logicalHeight();
- LayoutUnit firstTextTop = lineGridBlockOffset + lineGridBox->logicalTop();
- LayoutUnit firstLineTopWithLeading = lineGridBlockOffset + lineGridBox->lineTopWithLeading();
- LayoutUnit firstBaselinePosition = firstTextTop + lineGridFontAscent;
-
- LayoutUnit currentTextTop = blockOffset + logicalTop() + delta;
- LayoutUnit currentFontAscent = block()->style()->fontMetrics().ascent(baselineType());
- LayoutUnit currentBaselinePosition = currentTextTop + currentFontAscent;
-
- LayoutUnit lineGridPaginationOrigin = isHorizontal() ? layoutState->lineGridPaginationOrigin().height() : layoutState->lineGridPaginationOrigin().width();
-
- // If we're paginated, see if we're on a page after the first one. If so, the grid resets on subsequent pages.
- // FIXME: If the grid is an ancestor of the pagination establisher, then this is incorrect.
- LayoutUnit pageLogicalTop = 0;
- if (layoutState->isPaginated() && layoutState->pageLogicalHeight()) {
- pageLogicalTop = block()->pageLogicalTopForOffset(lineTopWithLeading() + delta);
- if (pageLogicalTop > firstLineTopWithLeading)
- firstTextTop = pageLogicalTop + lineGridBox->logicalTop() - lineGrid->borderBefore() - lineGrid->paddingBefore() + lineGridPaginationOrigin;
- }
-
- if (block()->style()->lineSnap() == LineSnapContain) {
- // Compute the desired offset from the text-top of a grid line.
- // Look at our height (logicalHeight()).
- // Look at the total available height. It's going to be (textBottom - textTop) + (n-1)*(multiple with leading)
- // where n is number of grid lines required to enclose us.
- if (logicalHeight() <= lineGridFontHeight)
- firstTextTop += (lineGridFontHeight - logicalHeight()) / 2;
- else {
- LayoutUnit numberOfLinesWithLeading = ceilf(static_cast<float>(logicalHeight() - lineGridFontHeight) / gridLineHeight);
- LayoutUnit totalHeight = lineGridFontHeight + numberOfLinesWithLeading * gridLineHeight;
- firstTextTop += (totalHeight - logicalHeight()) / 2;
- }
- firstBaselinePosition = firstTextTop + currentFontAscent;
- } else
- firstBaselinePosition = firstTextTop + lineGridFontAscent;
-
- // If we're above the first line, just push to the first line.
- if (currentBaselinePosition < firstBaselinePosition)
- return delta + firstBaselinePosition - currentBaselinePosition;
-
- // Otherwise we're in the middle of the grid somewhere. Just push to the next line.
- LayoutUnit baselineOffset = currentBaselinePosition - firstBaselinePosition;
- LayoutUnit remainder = roundToInt(baselineOffset) % roundToInt(gridLineHeight);
- LayoutUnit result = delta;
- if (remainder)
- result += gridLineHeight - remainder;
-
- // If we aren't paginated we can return the result.
- if (!layoutState->isPaginated() || !layoutState->pageLogicalHeight() || result == delta)
- return result;
-
- // We may end up shifted to a new page. We need to do a re-snap when that happens.
- LayoutUnit newPageLogicalTop = block()->pageLogicalTopForOffset(lineBottomWithLeading() + result);
- if (newPageLogicalTop == pageLogicalTop)
- return result;
-
- // Put ourselves at the top of the next page to force a snap onto the new grid established by that page.
- return lineSnapAdjustment(newPageLogicalTop - (blockOffset + lineTopWithLeading()));
-}
-
GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo* paintInfo)
{
RenderObject::SelectionState lineState = selectionState();
bool leftGap, rightGap;
- block()->getSelectionGapInfo(lineState, leftGap, rightGap);
+ block().getSelectionGapInfo(lineState, leftGap, rightGap);
GapRects result;
InlineBox* firstBox = firstSelectedBox();
InlineBox* lastBox = lastSelectedBox();
- if (leftGap)
- result.uniteLeft(block()->logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
- firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo));
- if (rightGap)
- result.uniteRight(block()->logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
- lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo));
+ if (leftGap) {
+ result.uniteLeft(block().logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
+ &firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo));
+ }
+ if (rightGap) {
+ result.uniteRight(block().logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
+ &lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo));
+ }
// When dealing with bidi text, a non-contiguous selection region is possible.
// e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capitals LTR) is layed out
@@ -453,11 +336,11 @@ GapRects RootInlineBox::lineSelectionGap(RenderBlock* rootBlock, const LayoutPoi
for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLeafChild()) {
if (box->selectionState() != RenderObject::SelectionNone) {
LayoutRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft() - lastLogicalLeft, selHeight);
- logicalRect.move(renderer()->isHorizontalWritingMode() ? offsetFromRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
+ logicalRect.move(renderer().isHorizontalWritingMode() ? offsetFromRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.height() > 0) {
- if (paintInfo && box->parent()->renderer()->style()->visibility() == VISIBLE)
- paintInfo->context->fillRect(gapRect, box->parent()->renderer()->selectionBackgroundColor());
+ if (paintInfo && box->parent()->renderer().style()->visibility() == VISIBLE)
+ paintInfo->context->fillRect(gapRect, box->parent()->renderer().selectionBackgroundColor());
// VisibleSelection may be non-contiguous, see comment above.
result.uniteCenter(gapRect);
}
@@ -521,20 +404,20 @@ LayoutUnit RootInlineBox::selectionTop() const
LayoutUnit selectionTop = m_lineTop;
if (m_hasAnnotationsBefore)
- selectionTop -= !renderer()->style()->isFlippedLinesWritingMode() ? computeOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_lineTop);
+ selectionTop -= !renderer().style()->isFlippedLinesWritingMode() ? computeOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_lineTop);
- if (renderer()->style()->isFlippedLinesWritingMode())
+ if (renderer().style()->isFlippedLinesWritingMode() || !prevRootBox())
return selectionTop;
- LayoutUnit prevBottom = prevRootBox() ? prevRootBox()->selectionBottom() : block()->borderBefore() + block()->paddingBefore();
- if (prevBottom < selectionTop && block()->containsFloats()) {
+ LayoutUnit prevBottom = prevRootBox()->selectionBottom();
+ if (prevBottom < selectionTop && block().containsFloats()) {
// This line has actually been moved further down, probably from a large line-height, but possibly because the
// line was forced to clear floats. If so, let's check the offsets, and only be willing to use the previous
// line's bottom if the offsets are greater on both sides.
- LayoutUnit prevLeft = block()->logicalLeftOffsetForLine(prevBottom, false);
- LayoutUnit prevRight = block()->logicalRightOffsetForLine(prevBottom, false);
- LayoutUnit newLeft = block()->logicalLeftOffsetForLine(selectionTop, false);
- LayoutUnit newRight = block()->logicalRightOffsetForLine(selectionTop, false);
+ LayoutUnit prevLeft = block().logicalLeftOffsetForLine(prevBottom, false);
+ LayoutUnit prevRight = block().logicalRightOffsetForLine(prevBottom, false);
+ LayoutUnit newLeft = block().logicalLeftOffsetForLine(selectionTop, false);
+ LayoutUnit newRight = block().logicalRightOffsetForLine(selectionTop, false);
if (prevLeft > newLeft || prevRight < newRight)
return selectionTop;
}
@@ -546,12 +429,12 @@ LayoutUnit RootInlineBox::selectionTopAdjustedForPrecedingBlock() const
{
LayoutUnit top = selectionTop();
- RenderObject::SelectionState blockSelectionState = root()->block()->selectionState();
+ RenderObject::SelectionState blockSelectionState = root().block().selectionState();
if (blockSelectionState != RenderObject::SelectionInside && blockSelectionState != RenderObject::SelectionEnd)
return top;
LayoutSize offsetToBlockBefore;
- if (RenderBlock* block = root()->block()->blockBeforeWithinSelectionRoot(offsetToBlockBefore)) {
+ if (RenderBlock* block = root().block().blockBeforeWithinSelectionRoot(offsetToBlockBefore)) {
if (RootInlineBox* lastLine = block->lastRootBox()) {
RenderObject::SelectionState lastLineSelectionState = lastLine->selectionState();
if (lastLineSelectionState != RenderObject::SelectionInside && lastLineSelectionState != RenderObject::SelectionStart)
@@ -570,20 +453,20 @@ LayoutUnit RootInlineBox::selectionBottom() const
LayoutUnit selectionBottom = m_lineBottom;
if (m_hasAnnotationsAfter)
- selectionBottom += !renderer()->style()->isFlippedLinesWritingMode() ? computeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(m_lineBottom);
+ selectionBottom += !renderer().style()->isFlippedLinesWritingMode() ? computeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(m_lineBottom);
- if (!renderer()->style()->isFlippedLinesWritingMode() || !nextRootBox())
+ if (!renderer().style()->isFlippedLinesWritingMode() || !nextRootBox())
return selectionBottom;
LayoutUnit nextTop = nextRootBox()->selectionTop();
- if (nextTop > selectionBottom && block()->containsFloats()) {
+ if (nextTop > selectionBottom && block().containsFloats()) {
// The next line has actually been moved further over, probably from a large line-height, but possibly because the
// line was forced to clear floats. If so, let's check the offsets, and only be willing to use the next
// line's top if the offsets are greater on both sides.
- LayoutUnit nextLeft = block()->logicalLeftOffsetForLine(nextTop, false);
- LayoutUnit nextRight = block()->logicalRightOffsetForLine(nextTop, false);
- LayoutUnit newLeft = block()->logicalLeftOffsetForLine(selectionBottom, false);
- LayoutUnit newRight = block()->logicalRightOffsetForLine(selectionBottom, false);
+ LayoutUnit nextLeft = block().logicalLeftOffsetForLine(nextTop, false);
+ LayoutUnit nextRight = block().logicalRightOffsetForLine(nextTop, false);
+ LayoutUnit newLeft = block().logicalLeftOffsetForLine(selectionBottom, false);
+ LayoutUnit newRight = block().logicalRightOffsetForLine(selectionBottom, false);
if (nextLeft > newLeft || nextRight < newRight)
return selectionBottom;
}
@@ -593,22 +476,22 @@ LayoutUnit RootInlineBox::selectionBottom() const
int RootInlineBox::blockDirectionPointInLine() const
{
- return !block()->style()->isFlippedBlocksWritingMode() ? max(lineTop(), selectionTop()) : min(lineBottom(), selectionBottom());
+ return !block().style()->isFlippedBlocksWritingMode() ? max(lineTop(), selectionTop()) : min(lineBottom(), selectionBottom());
}
-RenderBlockFlow* RootInlineBox::block() const
+RenderBlockFlow& RootInlineBox::block() const
{
return toRenderBlockFlow(renderer());
}
static bool isEditableLeaf(InlineBox* leaf)
{
- return leaf && leaf->renderer() && leaf->renderer()->node() && leaf->renderer()->node()->rendererIsEditable();
+ return leaf && leaf->renderer().node() && leaf->renderer().node()->rendererIsEditable();
}
InlineBox* RootInlineBox::closestLeafChildForPoint(const IntPoint& pointInContents, bool onlyEditableLeaves)
{
- return closestLeafChildForLogicalLeftPosition(block()->isHorizontalWritingMode() ? pointInContents.x() : pointInContents.y(), onlyEditableLeaves);
+ return closestLeafChildForLogicalLeftPosition(block().isHorizontalWritingMode() ? pointInContents.x() : pointInContents.y(), onlyEditableLeaves);
}
InlineBox* RootInlineBox::closestLeafChildForLogicalLeftPosition(int leftPosition, bool onlyEditableLeaves)
@@ -627,19 +510,19 @@ InlineBox* RootInlineBox::closestLeafChildForLogicalLeftPosition(int leftPositio
return firstLeaf;
// Avoid returning a list marker when possible.
- if (leftPosition <= firstLeaf->logicalLeft() && !firstLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
+ if (leftPosition <= firstLeaf->logicalLeft() && !firstLeaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
// The leftPosition coordinate is less or equal to left edge of the firstLeaf.
// Return it.
return firstLeaf;
- if (leftPosition >= lastLeaf->logicalRight() && !lastLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
+ if (leftPosition >= lastLeaf->logicalRight() && !lastLeaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
// The leftPosition coordinate is greater or equal to right edge of the lastLeaf.
// Return it.
return lastLeaf;
InlineBox* closestLeaf = 0;
for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChildIgnoringLineBreak()) {
- if (!leaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
+ if (!leaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
closestLeaf = leaf;
if (leftPosition < leaf->logicalRight())
// The x coordinate is less than the right edge of the box.
@@ -682,17 +565,17 @@ EllipsisBox* RootInlineBox::ellipsisBox() const
void RootInlineBox::removeLineBoxFromRenderObject()
{
- block()->lineBoxes()->removeLineBox(this);
+ block().lineBoxes()->removeLineBox(this);
}
void RootInlineBox::extractLineBoxFromRenderObject()
{
- block()->lineBoxes()->extractLineBox(this);
+ block().lineBoxes()->extractLineBox(this);
}
void RootInlineBox::attachLineBoxToRenderObject()
{
- block()->lineBoxes()->attachLineBox(this);
+ block().lineBoxes()->attachLineBox(this);
}
LayoutRect RootInlineBox::paddedLayoutOverflowRect(LayoutUnit endPadding) const
@@ -735,8 +618,8 @@ void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
// Replaced boxes will return 0 for the line-height if line-box-contain says they are
// not to be included.
- if (box->renderer()->isReplaced()) {
- if (renderer()->style(isFirstLineStyle())->lineBoxContain() & LineBoxContainReplaced) {
+ if (box->renderer().isReplaced()) {
+ if (renderer().style(isFirstLineStyle())->lineBoxContain() & LineBoxContainReplaced) {
ascent = box->baselinePosition(baselineType());
descent = box->lineHeight() - ascent;
@@ -761,8 +644,8 @@ void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
bool setUsedFont = false;
bool setUsedFontWithLeading = false;
- if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->renderer()->style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) {
- usedFonts->append(box->renderer()->style(isFirstLineStyle())->font().primaryFont());
+ if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->renderer().style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) {
+ usedFonts->append(box->renderer().style(isFirstLineStyle())->font().primaryFont());
for (size_t i = 0; i < usedFonts->size(); ++i) {
const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics();
int usedFontAscent = fontMetrics.ascent(baselineType());
@@ -800,8 +683,8 @@ void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
}
if (includeFontForBox(box) && !setUsedFont) {
- int fontAscent = box->renderer()->style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
- int fontDescent = box->renderer()->style(isFirstLineStyle())->fontMetrics().descent(baselineType());
+ int fontAscent = box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
+ int fontDescent = box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType());
setAscentAndDescent(ascent, descent, fontAscent, fontDescent, ascentDescentSet);
affectsAscent = fontAscent - box->logicalTop() > 0;
affectsDescent = fontDescent + box->logicalTop() > 0;
@@ -811,14 +694,14 @@ void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
setAscentAndDescent(ascent, descent, glyphOverflow->top, glyphOverflow->bottom, ascentDescentSet);
affectsAscent = glyphOverflow->top - box->logicalTop() > 0;
affectsDescent = glyphOverflow->bottom + box->logicalTop() > 0;
- glyphOverflow->top = min(glyphOverflow->top, max(0, glyphOverflow->top - box->renderer()->style(isFirstLineStyle())->fontMetrics().ascent(baselineType())));
- glyphOverflow->bottom = min(glyphOverflow->bottom, max(0, glyphOverflow->bottom - box->renderer()->style(isFirstLineStyle())->fontMetrics().descent(baselineType())));
+ glyphOverflow->top = min(glyphOverflow->top, max(0, glyphOverflow->top - box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType())));
+ glyphOverflow->bottom = min(glyphOverflow->bottom, max(0, glyphOverflow->bottom - box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType())));
}
if (includeMarginForBox(box)) {
- LayoutUnit ascentWithMargin = box->renderer()->style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
- LayoutUnit descentWithMargin = box->renderer()->style(isFirstLineStyle())->fontMetrics().descent(baselineType());
- if (box->parent() && !box->renderer()->isText()) {
+ LayoutUnit ascentWithMargin = box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
+ LayoutUnit descentWithMargin = box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType());
+ if (box->parent() && !box->renderer().isText()) {
ascentWithMargin += box->boxModelObject()->borderBefore() + box->boxModelObject()->paddingBefore() + box->boxModelObject()->marginBefore();
descentWithMargin += box->boxModelObject()->borderAfter() + box->boxModelObject()->paddingAfter() + box->boxModelObject()->marginAfter();
}
@@ -832,7 +715,7 @@ void RootInlineBox::ascentAndDescentForBox(InlineBox* box, GlyphOverflowAndFallb
LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositionCache& verticalPositionCache)
{
- if (box->renderer()->isText())
+ if (box->renderer().isText())
return box->parent()->logicalTop();
RenderBoxModelObject* renderer = box->boxModelObject();
@@ -865,7 +748,7 @@ LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio
if (verticalAlign != BASELINE) {
const Font& font = parent->style(firstLine)->font();
const FontMetrics& fontMetrics = font.fontMetrics();
- int fontSize = font.pixelSize();
+ int fontSize = font.fontDescription().computedPixelSize();
LineDirectionMode lineDirection = parent->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
@@ -891,7 +774,7 @@ LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio
lineHeight = renderer->style()->computedLineHeight();
else
lineHeight = renderer->lineHeight(firstLine, lineDirection);
- verticalPosition -= valueForLength(renderer->style()->verticalAlignLength(), lineHeight, renderer->view());
+ verticalPosition -= valueForLength(renderer->style()->verticalAlignLength(), lineHeight);
}
}
@@ -904,45 +787,45 @@ LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositio
bool RootInlineBox::includeLeadingForBox(InlineBox* box) const
{
- if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isText()))
+ if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
return false;
- LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+ LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
return (lineBoxContain & LineBoxContainInline) || (box == this && (lineBoxContain & LineBoxContainBlock));
}
bool RootInlineBox::includeFontForBox(InlineBox* box) const
{
- if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isText()))
+ if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
return false;
if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTextChildren())
return false;
// For now map "glyphs" to "font" in vertical text mode until the bounds returned by glyphs aren't garbage.
- LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+ LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
return (lineBoxContain & LineBoxContainFont) || (!isHorizontal() && (lineBoxContain & LineBoxContainGlyphs));
}
bool RootInlineBox::includeGlyphsForBox(InlineBox* box) const
{
- if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isText()))
+ if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
return false;
if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTextChildren())
return false;
// FIXME: We can't fit to glyphs yet for vertical text, since the bounds returned are garbage.
- LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+ LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs);
}
bool RootInlineBox::includeMarginForBox(InlineBox* box) const
{
- if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isText()))
+ if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
return false;
- LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+ LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
return lineBoxContain & LineBoxContainInlineBox;
}
@@ -950,13 +833,13 @@ bool RootInlineBox::includeMarginForBox(InlineBox* box) const
bool RootInlineBox::fitsToGlyphs() const
{
// FIXME: We can't fit to glyphs yet for vertical text, since the bounds returned are garbage.
- LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+ LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs);
}
bool RootInlineBox::includesRootLineBoxFontOrLeading() const
{
- LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+ LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
return (lineBoxContain & LineBoxContainBlock) || (lineBoxContain & LineBoxContainInline) || (lineBoxContain & LineBoxContainFont);
}
@@ -965,9 +848,9 @@ Node* RootInlineBox::getLogicalStartBoxWithNode(InlineBox*& startBox) const
Vector<InlineBox*> leafBoxesInLogicalOrder;
collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder);
for (size_t i = 0; i < leafBoxesInLogicalOrder.size(); ++i) {
- if (leafBoxesInLogicalOrder[i]->renderer()->node()) {
+ if (leafBoxesInLogicalOrder[i]->renderer().node()) {
startBox = leafBoxesInLogicalOrder[i];
- return startBox->renderer()->node();
+ return startBox->renderer().node();
}
}
startBox = 0;
@@ -979,9 +862,9 @@ Node* RootInlineBox::getLogicalEndBoxWithNode(InlineBox*& endBox) const
Vector<InlineBox*> leafBoxesInLogicalOrder;
collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder);
for (size_t i = leafBoxesInLogicalOrder.size(); i > 0; --i) {
- if (leafBoxesInLogicalOrder[i - 1]->renderer()->node()) {
+ if (leafBoxesInLogicalOrder[i - 1]->renderer().node()) {
endBox = leafBoxesInLogicalOrder[i - 1];
- return endBox->renderer()->node();
+ return endBox->renderer().node();
}
}
endBox = 0;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.h b/chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.h
index 7dfde5faf5b..32b1c55221d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/RootInlineBox.h
@@ -29,14 +29,13 @@ namespace WebCore {
class EllipsisBox;
class HitTestResult;
class RenderBlockFlow;
-class RenderRegion;
struct BidiStatus;
struct GapRects;
class RootInlineBox : public InlineFlowBox {
public:
- explicit RootInlineBox(RenderBlockFlow*);
+ explicit RootInlineBox(RenderBlockFlow&);
virtual void destroy() OVERRIDE FINAL;
@@ -64,9 +63,6 @@ public:
LayoutUnit paginatedLineWidth() const { return m_fragmentationData ? m_fragmentationData->m_paginatedLineWidth : LayoutUnit(0); }
void setPaginatedLineWidth(LayoutUnit width) { ensureLineFragmentationData()->m_paginatedLineWidth = width; }
- RenderRegion* containingRegion() const;
- void setContainingRegion(RenderRegion*);
-
LayoutUnit selectionTop() const;
LayoutUnit selectionBottom() const;
LayoutUnit selectionHeight() const { return max<LayoutUnit>(0, selectionBottom() - selectionTop()); }
@@ -117,7 +113,7 @@ public:
virtual int baselinePosition(FontBaseline baselineType) const OVERRIDE FINAL;
virtual LayoutUnit lineHeight() const OVERRIDE FINAL;
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE FINAL;
using InlineBox::hasSelectedChildren;
@@ -129,7 +125,7 @@ public:
GapRects lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo*);
- RenderBlockFlow* block() const;
+ RenderBlockFlow& block() const;
InlineBox* closestLeafChildForPoint(const IntPoint&, bool onlyEditableLeaves);
InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
@@ -189,11 +185,9 @@ public:
Node* getLogicalEndBoxWithNode(InlineBox*&) const;
#ifndef NDEBUG
- virtual const char* boxName() const;
+ virtual const char* boxName() const OVERRIDE;
#endif
private:
- LayoutUnit lineSnapAdjustment(LayoutUnit delta = 0) const;
-
LayoutUnit beforeAnnotationsAdjustment() const;
struct LineFragmentationData;
@@ -223,17 +217,13 @@ private:
WTF_MAKE_NONCOPYABLE(LineFragmentationData); WTF_MAKE_FAST_ALLOCATED;
public:
LineFragmentationData()
- : m_containingRegion(0)
- , m_paginationStrut(0)
+ : m_paginationStrut(0)
, m_paginatedLineWidth(0)
, m_isFirstAfterPageBreak(false)
{
}
- // It should not be assumed the |containingRegion| is always valid.
- // It can also be 0 if the flow has no region chain.
- RenderRegion* m_containingRegion;
LayoutUnit m_paginationStrut;
LayoutUnit m_paginatedLineWidth;
bool m_isFirstAfterPageBreak;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ScrollAlignment.cpp b/chromium/third_party/WebKit/Source/core/rendering/ScrollAlignment.cpp
new file mode 100644
index 00000000000..433a0864815
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/ScrollAlignment.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * Portions are Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * Other contributors:
+ * Robert O'Callahan <roc+@cs.cmu.edu>
+ * David Baron <dbaron@fas.harvard.edu>
+ * Christian Biesinger <cbiesinger@web.de>
+ * Randall Jesup <rjesup@wgate.com>
+ * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
+ * Josh Soref <timeless@mac.com>
+ * Boris Zbarsky <bzbarsky@mit.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "config.h"
+#include "core/rendering/ScrollAlignment.h"
+
+#include "platform/geometry/LayoutRect.h"
+
+namespace WebCore {
+
+const ScrollAlignment ScrollAlignment::alignCenterIfNeeded = { ScrollAlignmentNoScroll, ScrollAlignmentCenter, ScrollAlignmentClosestEdge };
+const ScrollAlignment ScrollAlignment::alignToEdgeIfNeeded = { ScrollAlignmentNoScroll, ScrollAlignmentClosestEdge, ScrollAlignmentClosestEdge };
+const ScrollAlignment ScrollAlignment::alignCenterAlways = { ScrollAlignmentCenter, ScrollAlignmentCenter, ScrollAlignmentCenter };
+const ScrollAlignment ScrollAlignment::alignTopAlways = { ScrollAlignmentTop, ScrollAlignmentTop, ScrollAlignmentTop };
+const ScrollAlignment ScrollAlignment::alignBottomAlways = { ScrollAlignmentBottom, ScrollAlignmentBottom, ScrollAlignmentBottom };
+
+#define MIN_INTERSECT_FOR_REVEAL 32
+
+LayoutRect ScrollAlignment::getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
+{
+ // Determine the appropriate X behavior.
+ ScrollAlignmentBehavior scrollX;
+ LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
+ LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width();
+ if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL) {
+ // If the rectangle is fully visible, use the specified visible behavior.
+ // If the rectangle is partially visible, but over a certain threshold,
+ // then treat it as fully visible to avoid unnecessary horizontal scrolling
+ scrollX = getVisibleBehavior(alignX);
+ } else if (intersectWidth == visibleRect.width()) {
+ // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
+ scrollX = getVisibleBehavior(alignX);
+ if (scrollX == ScrollAlignmentCenter)
+ scrollX = ScrollAlignmentNoScroll;
+ } else if (intersectWidth > 0) {
+ // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
+ scrollX = getPartialBehavior(alignX);
+ } else {
+ scrollX = getHiddenBehavior(alignX);
+ }
+
+ if (scrollX == ScrollAlignmentClosestEdge) {
+ // Closest edge is the right in two cases:
+ // (1) exposeRect to the right of and smaller than visibleRect
+ // (2) exposeRect to the left of and larger than visibleRect
+ if ((exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
+ || (exposeRect.maxX() < visibleRect.maxX() && exposeRect.width() > visibleRect.width())) {
+ scrollX = ScrollAlignmentRight;
+ }
+ }
+
+ // Given the X behavior, compute the X coordinate.
+ LayoutUnit x;
+ if (scrollX == ScrollAlignmentNoScroll)
+ x = visibleRect.x();
+ else if (scrollX == ScrollAlignmentRight)
+ x = exposeRect.maxX() - visibleRect.width();
+ else if (scrollX == ScrollAlignmentCenter)
+ x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
+ else
+ x = exposeRect.x();
+
+ // Determine the appropriate Y behavior.
+ ScrollAlignmentBehavior scrollY;
+ LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
+ LayoutUnit intersectHeight = intersection(visibleRect, exposeRectY).height();
+ if (intersectHeight == exposeRect.height()) {
+ // If the rectangle is fully visible, use the specified visible behavior.
+ scrollY = getVisibleBehavior(alignY);
+ } else if (intersectHeight == visibleRect.height()) {
+ // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
+ scrollY = getVisibleBehavior(alignY);
+ if (scrollY == ScrollAlignmentCenter)
+ scrollY = ScrollAlignmentNoScroll;
+ } else if (intersectHeight > 0) {
+ // If the rectangle is partially visible, use the specified partial behavior
+ scrollY = getPartialBehavior(alignY);
+ } else {
+ scrollY = getHiddenBehavior(alignY);
+ }
+
+ if (scrollY == ScrollAlignmentClosestEdge) {
+ // Closest edge is the bottom in two cases:
+ // (1) exposeRect below and smaller than visibleRect
+ // (2) exposeRect above and larger than visibleRect
+ if ((exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
+ || (exposeRect.maxY() < visibleRect.maxY() && exposeRect.height() > visibleRect.height())) {
+ scrollY = ScrollAlignmentBottom;
+ }
+ }
+
+ // Given the Y behavior, compute the Y coordinate.
+ LayoutUnit y;
+ if (scrollY == ScrollAlignmentNoScroll)
+ y = visibleRect.y();
+ else if (scrollY == ScrollAlignmentBottom)
+ y = exposeRect.maxY() - visibleRect.height();
+ else if (scrollY == ScrollAlignmentCenter)
+ y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
+ else
+ y = exposeRect.y();
+
+ return LayoutRect(LayoutPoint(x, y), visibleRect.size());
+}
+
+}; // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ScrollAlignment.h b/chromium/third_party/WebKit/Source/core/rendering/ScrollAlignment.h
new file mode 100644
index 00000000000..f22b1d9d6a8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/ScrollAlignment.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2003, 2009 Apple Inc. All rights reserved.
+ *
+ * Portions are Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * Other contributors:
+ * Robert O'Callahan <roc+@cs.cmu.edu>
+ * David Baron <dbaron@fas.harvard.edu>
+ * Christian Biesinger <cbiesinger@web.de>
+ * Randall Jesup <rjesup@wgate.com>
+ * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
+ * Josh Soref <timeless@mac.com>
+ * Boris Zbarsky <bzbarsky@mit.edu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#ifndef ScrollAlignment_h
+#define ScrollAlignment_h
+
+namespace WebCore {
+
+enum ScrollAlignmentBehavior {
+ ScrollAlignmentNoScroll,
+ ScrollAlignmentCenter,
+ ScrollAlignmentTop,
+ ScrollAlignmentBottom,
+ ScrollAlignmentLeft,
+ ScrollAlignmentRight,
+ ScrollAlignmentClosestEdge
+};
+
+class LayoutRect;
+
+struct ScrollAlignment {
+ static ScrollAlignmentBehavior getVisibleBehavior(const ScrollAlignment& s) { return s.m_rectVisible; }
+ static ScrollAlignmentBehavior getPartialBehavior(const ScrollAlignment& s) { return s.m_rectPartial; }
+ static ScrollAlignmentBehavior getHiddenBehavior(const ScrollAlignment& s) { return s.m_rectHidden; }
+
+ // FIXME: This function should probably go somewhere else but where?
+ static LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
+
+ static const ScrollAlignment alignCenterIfNeeded;
+ static const ScrollAlignment alignToEdgeIfNeeded;
+ static const ScrollAlignment alignCenterAlways;
+ static const ScrollAlignment alignTopAlways;
+ static const ScrollAlignment alignBottomAlways;
+
+ ScrollAlignmentBehavior m_rectVisible;
+ ScrollAlignmentBehavior m_rectHidden;
+ ScrollAlignmentBehavior m_rectPartial;
+};
+
+
+}; // namespace WebCore
+
+#endif // ScrollAlignment_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp b/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp
deleted file mode 100644
index d331f1dc07b..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
- *
- * Portions are Copyright (C) 1998 Netscape Communications Corporation.
- *
- * Other contributors:
- * Robert O'Callahan <roc+@cs.cmu.edu>
- * David Baron <dbaron@fas.harvard.edu>
- * Christian Biesinger <cbiesinger@web.de>
- * Randall Jesup <rjesup@wgate.com>
- * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
- * Josh Soref <timeless@mac.com>
- * Boris Zbarsky <bzbarsky@mit.edu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above. If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#include "config.h"
-#include "core/rendering/ScrollBehavior.h"
-
-#include "platform/geometry/LayoutRect.h"
-
-namespace WebCore {
-
-const ScrollAlignment ScrollAlignment::alignCenterIfNeeded = { noScroll, alignCenter, alignToClosestEdge };
-const ScrollAlignment ScrollAlignment::alignToEdgeIfNeeded = { noScroll, alignToClosestEdge, alignToClosestEdge };
-const ScrollAlignment ScrollAlignment::alignCenterAlways = { alignCenter, alignCenter, alignCenter };
-const ScrollAlignment ScrollAlignment::alignTopAlways = { alignTop, alignTop, alignTop };
-const ScrollAlignment ScrollAlignment::alignBottomAlways = { alignBottom, alignBottom, alignBottom };
-
-#define MIN_INTERSECT_FOR_REVEAL 32
-
-LayoutRect ScrollAlignment::getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
-{
- // Determine the appropriate X behavior.
- ScrollBehavior scrollX;
- LayoutRect exposeRectX(exposeRect.x(), visibleRect.y(), exposeRect.width(), visibleRect.height());
- LayoutUnit intersectWidth = intersection(visibleRect, exposeRectX).width();
- if (intersectWidth == exposeRect.width() || intersectWidth >= MIN_INTERSECT_FOR_REVEAL) {
- // If the rectangle is fully visible, use the specified visible behavior.
- // If the rectangle is partially visible, but over a certain threshold,
- // then treat it as fully visible to avoid unnecessary horizontal scrolling
- scrollX = getVisibleBehavior(alignX);
- } else if (intersectWidth == visibleRect.width()) {
- // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
- scrollX = getVisibleBehavior(alignX);
- if (scrollX == alignCenter)
- scrollX = noScroll;
- } else if (intersectWidth > 0) {
- // If the rectangle is partially visible, but not above the minimum threshold, use the specified partial behavior
- scrollX = getPartialBehavior(alignX);
- } else {
- scrollX = getHiddenBehavior(alignX);
- }
-
- if (scrollX == alignToClosestEdge) {
- // Closest edge is the right in two cases:
- // (1) exposeRect to the right of and smaller than visibleRect
- // (2) exposeRect to the left of and larger than visibleRect
- if ((exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
- || (exposeRect.maxX() < visibleRect.maxX() && exposeRect.width() > visibleRect.width())) {
- scrollX = alignRight;
- }
- }
-
- // Given the X behavior, compute the X coordinate.
- LayoutUnit x;
- if (scrollX == noScroll)
- x = visibleRect.x();
- else if (scrollX == alignRight)
- x = exposeRect.maxX() - visibleRect.width();
- else if (scrollX == alignCenter)
- x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
- else
- x = exposeRect.x();
-
- // Determine the appropriate Y behavior.
- ScrollBehavior scrollY;
- LayoutRect exposeRectY(visibleRect.x(), exposeRect.y(), visibleRect.width(), exposeRect.height());
- LayoutUnit intersectHeight = intersection(visibleRect, exposeRectY).height();
- if (intersectHeight == exposeRect.height()) {
- // If the rectangle is fully visible, use the specified visible behavior.
- scrollY = getVisibleBehavior(alignY);
- } else if (intersectHeight == visibleRect.height()) {
- // If the rect is bigger than the visible area, don't bother trying to center. Other alignments will work.
- scrollY = getVisibleBehavior(alignY);
- if (scrollY == alignCenter)
- scrollY = noScroll;
- } else if (intersectHeight > 0) {
- // If the rectangle is partially visible, use the specified partial behavior
- scrollY = getPartialBehavior(alignY);
- } else {
- scrollY = getHiddenBehavior(alignY);
- }
-
- if (scrollY == alignToClosestEdge) {
- // Closest edge is the bottom in two cases:
- // (1) exposeRect below and smaller than visibleRect
- // (2) exposeRect above and larger than visibleRect
- if ((exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
- || (exposeRect.maxY() < visibleRect.maxY() && exposeRect.height() > visibleRect.height())) {
- scrollY = alignBottom;
- }
- }
-
- // Given the Y behavior, compute the Y coordinate.
- LayoutUnit y;
- if (scrollY == noScroll)
- y = visibleRect.y();
- else if (scrollY == alignBottom)
- y = exposeRect.maxY() - visibleRect.height();
- else if (scrollY == alignCenter)
- y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
- else
- y = exposeRect.y();
-
- return LayoutRect(LayoutPoint(x, y), visibleRect.size());
-}
-
-}; // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.h b/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.h
deleted file mode 100644
index 7c683d874a0..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/ScrollBehavior.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2003, 2009 Apple Inc. All rights reserved.
- *
- * Portions are Copyright (C) 1998 Netscape Communications Corporation.
- *
- * Other contributors:
- * Robert O'Callahan <roc+@cs.cmu.edu>
- * David Baron <dbaron@fas.harvard.edu>
- * Christian Biesinger <cbiesinger@web.de>
- * Randall Jesup <rjesup@wgate.com>
- * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
- * Josh Soref <timeless@mac.com>
- * Boris Zbarsky <bzbarsky@mit.edu>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above. If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#ifndef ScrollBehavior_h
-#define ScrollBehavior_h
-
-namespace WebCore {
-
-enum ScrollBehavior {
- noScroll,
- alignCenter,
- alignTop,
- alignBottom,
- alignLeft,
- alignRight,
- alignToClosestEdge
-};
-
-class LayoutRect;
-
-struct ScrollAlignment {
- static ScrollBehavior getVisibleBehavior(const ScrollAlignment& s) { return s.m_rectVisible; }
- static ScrollBehavior getPartialBehavior(const ScrollAlignment& s) { return s.m_rectPartial; }
- static ScrollBehavior getHiddenBehavior(const ScrollAlignment& s) { return s.m_rectHidden; }
-
- // FIXME: This function should probably go somewhere else but where?
- static LayoutRect getRectToExpose(const LayoutRect& visibleRect, const LayoutRect& exposeRect, const ScrollAlignment& alignX, const ScrollAlignment& alignY);
-
- static const ScrollAlignment alignCenterIfNeeded;
- static const ScrollAlignment alignToEdgeIfNeeded;
- static const ScrollAlignment alignCenterAlways;
- static const ScrollAlignment alignTopAlways;
- static const ScrollAlignment alignBottomAlways;
-
- ScrollBehavior m_rectVisible;
- ScrollBehavior m_rectHidden;
- ScrollBehavior m_rectPartial;
-};
-
-
-}; // namespace WebCore
-
-#endif // ScrollBehavior_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp b/chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp
index d650513a1c8..a5793a69e9a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp
@@ -36,21 +36,15 @@
namespace WebCore {
-SubtreeLayoutScope::SubtreeLayoutScope(RenderObject* root)
+SubtreeLayoutScope::SubtreeLayoutScope(RenderObject& root)
: m_root(root)
{
- RELEASE_ASSERT(m_root->document().view()->isInLayout());
+ RELEASE_ASSERT(m_root.document().view()->isInPerformLayout());
}
SubtreeLayoutScope::~SubtreeLayoutScope()
{
- // Partial layout early-exits layout and will leave the tree as needing layout.
- if (m_root->frameView()->partialLayout().isStopping()) {
- ASSERT(m_root->needsLayout());
- return;
- }
-
- RELEASE_ASSERT(!m_root->needsLayout());
+ RELEASE_ASSERT(!m_root.needsLayout());
#ifndef NDEBUG
for (HashSet<RenderObject*>::iterator it = m_renderersToLayout.begin(); it != m_renderersToLayout.end(); ++it)
@@ -60,13 +54,13 @@ SubtreeLayoutScope::~SubtreeLayoutScope()
void SubtreeLayoutScope::setNeedsLayout(RenderObject* descendant)
{
- ASSERT(descendant->isDescendantOf(m_root));
- descendant->setNeedsLayout(MarkContainingBlockChain, this);
+ ASSERT(descendant->isDescendantOf(&m_root));
+ descendant->setNeedsLayoutAndFullPaintInvalidation(MarkContainingBlockChain, this);
}
void SubtreeLayoutScope::setChildNeedsLayout(RenderObject* descendant)
{
- ASSERT(descendant->isDescendantOf(m_root));
+ ASSERT(descendant->isDescendantOf(&m_root));
descendant->setChildNeedsLayout(MarkContainingBlockChain, this);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.h b/chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.h
index c073b7f4cf1..fc9219ff5da 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.h
@@ -48,17 +48,17 @@ class RenderObject;
class SubtreeLayoutScope {
public:
- SubtreeLayoutScope(RenderObject* root);
+ SubtreeLayoutScope(RenderObject& root);
~SubtreeLayoutScope();
void setNeedsLayout(RenderObject* descendant);
void setChildNeedsLayout(RenderObject* descendant);
- RenderObject* root() { return m_root; }
+ RenderObject& root() { return m_root; }
void addRendererToLayout(RenderObject* renderer);
private:
- RenderObject* m_root;
+ RenderObject& m_root;
#ifndef NDEBUG
HashSet<RenderObject*> m_renderersToLayout;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp b/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp
index bc57d66cfab..290c008fa79 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp
@@ -24,9 +24,11 @@
#include <algorithm>
#include "core/dom/Document.h"
-#include "core/html/HTMLElement.h"
-#include "core/inspector/InspectorInstrumentation.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
+#include "core/html/HTMLElement.h"
+#include "core/page/Page.h"
#include "core/rendering/RenderListItem.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderText.h"
@@ -36,10 +38,11 @@
#include "platform/TraceEvent.h"
#include "platform/geometry/IntSize.h"
#include "wtf/StdLibExtras.h"
-#include "wtf/Vector.h"
namespace WebCore {
+#define AUTOSIZING_CLUSTER_HASH
+
using namespace HTMLNames;
struct TextAutosizingWindowInfo {
@@ -47,26 +50,25 @@ struct TextAutosizingWindowInfo {
IntSize minLayoutSize;
};
-// Represents cluster related data. Instances should not persist between calls to processSubtree.
-struct TextAutosizingClusterInfo {
- explicit TextAutosizingClusterInfo(RenderBlock* root)
- : root(root)
- , blockContainingAllText(0)
- , maxAllowedDifferenceFromTextWidth(150)
+// Represents a POD of a selection of fields for hashing. The fields are selected to detect similar
+// nodes in the Render Tree from the viewpoint of text autosizing.
+struct RenderObjectPodForHash {
+ RenderObjectPodForHash()
+ : qualifiedNameHash(0)
+ , packedStyleProperties(0)
+ , width(0)
{
}
+ ~RenderObjectPodForHash() { }
- RenderBlock* root;
- const RenderBlock* blockContainingAllText;
+ unsigned qualifiedNameHash;
- // Upper limit on the difference between the width of the cluster's block containing all
- // text and that of a narrow child before the child becomes a separate cluster.
- float maxAllowedDifferenceFromTextWidth;
-
- // Descendants of the cluster that are narrower than the block containing all text and must be
- // processed together.
- Vector<TextAutosizingClusterInfo> narrowDescendants;
+ // Style specific selection of signals
+ unsigned packedStyleProperties;
+ float width;
};
+// To allow for efficient hashing using StringHasher.
+COMPILE_ASSERT(!(sizeof(RenderObjectPodForHash) % sizeof(UChar)), RenderObjectPodForHashMultipleOfUchar);
#ifdef AUTOSIZING_DOM_DEBUG_INFO
static void writeDebugInfo(RenderObject* renderObject, const AtomicString& output)
@@ -104,48 +106,115 @@ static RenderObject* getAncestorList(const RenderObject* renderer)
// see http://www.whatwg.org/specs/web-apps/current-work/multipage/grouping-content.html#the-li-element
for (RenderObject* ancestor = renderer->parent(); ancestor; ancestor = ancestor->parent()) {
Node* parentNode = ancestor->generatingNode();
- if (parentNode && (parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag)))
+ if (parentNode && (isHTMLOListElement(*parentNode) || isHTMLUListElement(*parentNode)))
return ancestor;
}
return 0;
}
+static Node* getGeneratingElementNode(const RenderObject* renderer)
+{
+ Node* node = renderer->generatingNode();
+ return (node && node->isElementNode()) ? node : 0;
+}
+
+static unsigned hashMemory(const void* data, size_t length)
+{
+ return StringHasher::computeHash<UChar>(static_cast<const UChar*>(data), length / sizeof(UChar));
+}
+
+static unsigned computeLocalHash(const RenderObject* renderer)
+{
+ Node* generatingElementNode = getGeneratingElementNode(renderer);
+ ASSERT(generatingElementNode);
+
+ RenderObjectPodForHash podForHash;
+ podForHash.qualifiedNameHash = QualifiedNameHash::hash(toElement(generatingElementNode)->tagQName());
+
+ if (RenderStyle* style = renderer->style()) {
+ podForHash.packedStyleProperties = style->direction();
+ podForHash.packedStyleProperties |= (style->position() << 1);
+ podForHash.packedStyleProperties |= (style->floating() << 4);
+ podForHash.packedStyleProperties |= (style->display() << 6);
+ podForHash.packedStyleProperties |= (style->width().type() << 11);
+ // packedStyleProperties effectively using 15 bits now.
+
+ // consider for adding: writing mode, padding.
+
+ podForHash.width = style->width().getFloatValue();
+ }
+
+ return hashMemory(&podForHash, sizeof(podForHash));
+}
+
TextAutosizer::TextAutosizer(Document* document)
: m_document(document)
+ , m_previouslyAutosized(false)
+{
+}
+
+unsigned TextAutosizer::getCachedHash(const RenderObject* renderer, bool putInCacheIfAbsent)
{
+ HashMap<const RenderObject*, unsigned>::const_iterator it = m_hashCache.find(renderer);
+ if (it != m_hashCache.end())
+ return it->value;
+
+ RenderObject* rendererParent = renderer->parent();
+ while (rendererParent && !getGeneratingElementNode(rendererParent))
+ rendererParent = rendererParent->parent();
+
+ const unsigned parentHashValue = rendererParent ? getCachedHash(rendererParent, true) : 0;
+ const unsigned hashes[2] = { parentHashValue, computeLocalHash(renderer) };
+ const unsigned combinedHashValue = hashMemory(hashes, sizeof(hashes));
+ if (putInCacheIfAbsent)
+ m_hashCache.add(renderer, combinedHashValue);
+ return combinedHashValue;
+}
+
+bool TextAutosizer::isApplicable() const
+{
+ return m_document->settings()
+ && m_document->settings()->textAutosizingEnabled()
+ && m_document->page()
+ && m_document->page()->mainFrame()
+ && m_document->page()->deprecatedLocalMainFrame()->loader().stateMachine()->committedFirstRealDocumentLoad();
}
void TextAutosizer::recalculateMultipliers()
{
- RenderObject* renderer = m_document->renderer();
+ if (!isApplicable() && !m_previouslyAutosized)
+ return;
+
+ RenderObject* renderer = m_document->renderView();
while (renderer) {
if (renderer->style() && renderer->style()->textAutosizingMultiplier() != 1)
setMultiplier(renderer, 1);
renderer = renderer->nextInPreOrder();
}
+ m_previouslyAutosized = false;
}
bool TextAutosizer::processSubtree(RenderObject* layoutRoot)
{
- TRACE_EVENT0("webkit", "TextAutosizer::processSubtree");
+ TRACE_EVENT0("webkit", "TextAutosizer: check if needed");
- if (!m_document->settings() || !m_document->settings()->textAutosizingEnabled() || layoutRoot->view()->document().printing() || !m_document->page())
+ if (!isApplicable() || layoutRoot->view()->document().printing())
return false;
- Frame* mainFrame = m_document->page()->mainFrame();
-
+ LocalFrame* mainFrame = m_document->page()->deprecatedLocalMainFrame();
TextAutosizingWindowInfo windowInfo;
// Window area, in logical (density-independent) pixels.
windowInfo.windowSize = m_document->settings()->textAutosizingWindowSizeOverride();
if (windowInfo.windowSize.isEmpty())
- windowInfo.windowSize = mainFrame->view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
+ windowInfo.windowSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollbars);
// Largest area of block that can be visible at once (assuming the main
// frame doesn't get scaled to less than overview scale), in CSS pixels.
windowInfo.minLayoutSize = mainFrame->view()->layoutSize();
- for (Frame* frame = m_document->frame(); frame; frame = frame->tree().parent())
- windowInfo.minLayoutSize = windowInfo.minLayoutSize.shrunkTo(frame->view()->layoutSize());
+ for (Frame* frame = m_document->frame(); frame; frame = frame->tree().parent()) {
+ windowInfo.minLayoutSize = windowInfo.minLayoutSize.shrunkTo(toLocalFrame(frame)->view()->layoutSize());
+ }
// The layoutRoot could be neither a container nor a cluster, so walk up the tree till we find each of these.
RenderBlock* container = layoutRoot->isRenderBlock() ? toRenderBlock(layoutRoot) : layoutRoot->containingBlock();
@@ -163,9 +232,21 @@ bool TextAutosizer::processSubtree(RenderObject* layoutRoot)
std::numeric_limits<float>::infinity()) == 1.0f)
return false;
+ TRACE_EVENT0("webkit", "TextAutosizer: process root cluster");
+ UseCounter::count(*m_document, UseCounter::TextAutosizing);
+
TextAutosizingClusterInfo clusterInfo(cluster);
processCluster(clusterInfo, container, layoutRoot, windowInfo);
- InspectorInstrumentation::didAutosizeText(layoutRoot);
+
+#ifdef AUTOSIZING_CLUSTER_HASH
+ // Second pass to autosize stale non-autosized clusters for consistency.
+ secondPassProcessStaleNonAutosizedClusters();
+ m_hashCache.clear();
+ m_hashToMultiplier.clear();
+ m_hashesToAutosizeSecondPass.clear();
+ m_nonAutosizedClusters.clear();
+#endif
+ m_previouslyAutosized = true;
return true;
}
@@ -180,9 +261,10 @@ float TextAutosizer::clusterMultiplier(WritingMode writingMode, const TextAutosi
multiplier *= m_document->settings()->accessibilityFontScaleFactor();
// If the page has a meta viewport or @viewport, don't apply the device scale adjustment.
- const ViewportDescription& viewportDescription = m_document->page()->mainFrame()->document()->viewportDescription();
+ const ViewportDescription& viewportDescription = m_document->page()->deprecatedLocalMainFrame()->document()->viewportDescription();
if (!viewportDescription.isSpecifiedByAuthor()) {
- multiplier *= m_document->settings()->deviceScaleAdjustment();
+ float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustment();
+ multiplier *= deviceScaleAdjustment;
}
return std::max(1.0f, multiplier);
}
@@ -191,7 +273,7 @@ void TextAutosizer::processClusterInternal(TextAutosizingClusterInfo& clusterInf
{
processContainer(multiplier, container, clusterInfo, subtreeRoot, windowInfo);
#ifdef AUTOSIZING_DOM_DEBUG_INFO
- writeDebugInfo(clusterInfo.root, String::format("cluster:%f", multiplier));
+ writeDebugInfo(clusterInfo.root, AtomicString(String::format("cluster:%f", multiplier)));
#endif
Vector<Vector<TextAutosizingClusterInfo> > narrowDescendantsGroups;
@@ -200,6 +282,58 @@ void TextAutosizer::processClusterInternal(TextAutosizingClusterInfo& clusterInf
processCompositeCluster(narrowDescendantsGroups[i], windowInfo);
}
+unsigned TextAutosizer::computeCompositeClusterHash(Vector<TextAutosizingClusterInfo>& clusterInfos)
+{
+ if (clusterInfos.size() == 1 && getGeneratingElementNode(clusterInfos[0].root))
+ return getCachedHash(clusterInfos[0].root, false);
+
+ // FIXME: consider hashing clusters for which clusterInfos.size() > 1
+ return 0;
+}
+
+void TextAutosizer::addNonAutosizedCluster(unsigned key, TextAutosizingClusterInfo& value)
+{
+ HashMap<unsigned, OwnPtr<Vector<TextAutosizingClusterInfo> > >::const_iterator it = m_nonAutosizedClusters.find(key);
+ if (it == m_nonAutosizedClusters.end()) {
+ m_nonAutosizedClusters.add(key, adoptPtr(new Vector<TextAutosizingClusterInfo>(1, value)));
+ return;
+ }
+ it->value->append(value);
+}
+
+float TextAutosizer::computeMultiplier(Vector<TextAutosizingClusterInfo>& clusterInfos, const TextAutosizingWindowInfo& windowInfo, float textWidth)
+{
+#ifdef AUTOSIZING_CLUSTER_HASH
+ // When hashing is enabled this function returns a multiplier based on previously seen clusters.
+ // It will return a non-unit multiplier if a cluster with the same hash value has been previously
+ // autosized.
+ unsigned clusterHash = computeCompositeClusterHash(clusterInfos);
+#else
+ unsigned clusterHash = 0;
+#endif
+
+ if (clusterHash) {
+ HashMap<unsigned, float>::iterator it = m_hashToMultiplier.find(clusterHash);
+ if (it != m_hashToMultiplier.end())
+ return it->value;
+ }
+
+ if (compositeClusterShouldBeAutosized(clusterInfos, textWidth)) {
+ float multiplier = clusterMultiplier(clusterInfos[0].root->style()->writingMode(), windowInfo, textWidth);
+ if (clusterHash) {
+ if (multiplier > 1 && m_nonAutosizedClusters.contains(clusterHash))
+ m_hashesToAutosizeSecondPass.append(clusterHash);
+ m_hashToMultiplier.add(clusterHash, multiplier);
+ }
+ return multiplier;
+ }
+
+ if (clusterHash)
+ addNonAutosizedCluster(clusterHash, clusterInfos[0]);
+
+ return 1.0f;
+}
+
void TextAutosizer::processCluster(TextAutosizingClusterInfo& clusterInfo, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo& windowInfo)
{
// Many pages set a max-width on their content. So especially for the RenderView, instead of
@@ -207,10 +341,11 @@ void TextAutosizer::processCluster(TextAutosizingClusterInfo& clusterInfo, Rende
// descendant text node of the cluster (i.e. the deepest wrapper block that contains all the
// text), and use its width instead.
clusterInfo.blockContainingAllText = findDeepestBlockContainingAllText(clusterInfo.root);
- float textWidth = clusterInfo.blockContainingAllText->contentLogicalWidth();
- float multiplier = 1.0;
- if (clusterShouldBeAutosized(clusterInfo, textWidth))
- multiplier = clusterMultiplier(clusterInfo.root->style()->writingMode(), windowInfo, textWidth);
+ float textWidth = clusterInfo.blockContainingAllText->contentLogicalWidth().toFloat();
+
+ Vector<TextAutosizingClusterInfo> clusterInfos(1, clusterInfo);
+ float multiplier = computeMultiplier(clusterInfos, windowInfo, textWidth);
+
processClusterInternal(clusterInfo, container, subtreeRoot, windowInfo, multiplier);
}
@@ -223,18 +358,52 @@ void TextAutosizer::processCompositeCluster(Vector<TextAutosizingClusterInfo>& c
for (size_t i = 0; i < clusterInfos.size(); ++i) {
TextAutosizingClusterInfo& clusterInfo = clusterInfos[i];
clusterInfo.blockContainingAllText = findDeepestBlockContainingAllText(clusterInfo.root);
- maxTextWidth = max<float>(maxTextWidth, clusterInfo.blockContainingAllText->contentLogicalWidth());
+ maxTextWidth = max<float>(maxTextWidth, clusterInfo.blockContainingAllText->contentLogicalWidth().toFloat());
}
- float multiplier = 1.0;
- if (compositeClusterShouldBeAutosized(clusterInfos, maxTextWidth))
- multiplier = clusterMultiplier(clusterInfos[0].root->style()->writingMode(), windowInfo, maxTextWidth);
+ float multiplier = computeMultiplier(clusterInfos, windowInfo, maxTextWidth);
for (size_t i = 0; i < clusterInfos.size(); ++i) {
ASSERT(clusterInfos[i].root->style()->writingMode() == clusterInfos[0].root->style()->writingMode());
processClusterInternal(clusterInfos[i], clusterInfos[i].root, clusterInfos[i].root, windowInfo, multiplier);
}
}
+void TextAutosizer::secondPassProcessStaleNonAutosizedClusters()
+{
+ for (size_t i = 0; i < m_hashesToAutosizeSecondPass.size(); ++i) {
+ unsigned hash = m_hashesToAutosizeSecondPass[i];
+ float multiplier = m_hashToMultiplier.get(hash);
+ Vector<TextAutosizingClusterInfo>* val = m_nonAutosizedClusters.get(hash);
+ for (Vector<TextAutosizingClusterInfo>::iterator it2 = val->begin(); it2 != val->end(); ++it2)
+ processStaleContainer(multiplier, (*it2).root, *it2);
+ }
+}
+
+void TextAutosizer::processStaleContainer(float multiplier, RenderBlock* cluster, TextAutosizingClusterInfo& clusterInfo)
+{
+ ASSERT(isAutosizingContainer(cluster));
+
+ // This method is different from processContainer() mainly in that it does not recurse into sub-clusters.
+ // Multiplier updates are restricted to the specified cluster only. Also the multiplier > 1 by construction
+ // of m_hashesToAutosizeSecondPass, so we don't need to check it explicitly.
+ float localMultiplier = containerShouldBeAutosized(cluster) ? multiplier : 1;
+
+ RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(cluster, cluster);
+ while (descendant) {
+ if (descendant->isText()) {
+ if (localMultiplier != 1 && descendant->style()->textAutosizingMultiplier() == 1) {
+ setMultiplier(descendant, localMultiplier);
+ setMultiplier(descendant->parent(), localMultiplier); // Parent does line spacing.
+ }
+ } else if (isAutosizingContainer(descendant)) {
+ RenderBlock* descendantBlock = toRenderBlock(descendant);
+ if (!isAutosizingCluster(descendantBlock, clusterInfo))
+ processStaleContainer(multiplier, descendantBlock, clusterInfo);
+ }
+ descendant = nextInPreOrderSkippingDescendantsOfContainers(descendant, cluster);
+ }
+}
+
void TextAutosizer::processContainer(float multiplier, RenderBlock* container, TextAutosizingClusterInfo& clusterInfo, RenderObject* subtreeRoot, const TextAutosizingWindowInfo& windowInfo)
{
ASSERT(isAutosizingContainer(container));
@@ -242,7 +411,7 @@ void TextAutosizer::processContainer(float multiplier, RenderBlock* container, T
writeDebugInfo(container, "container");
#endif
- float localMultiplier = containerShouldBeAutosized(container) ? multiplier: 1;
+ float localMultiplier = (multiplier > 1 && containerShouldBeAutosized(container)) ? multiplier: 1;
RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(subtreeRoot, subtreeRoot);
while (descendant) {
@@ -287,12 +456,12 @@ void TextAutosizer::setMultiplierForList(RenderObject* renderer, float multiplie
#ifndef NDEBUG
Node* parentNode = renderer->generatingNode();
ASSERT(parentNode);
- ASSERT(parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag));
+ ASSERT(isHTMLOListElement(parentNode) || isHTMLUListElement(parentNode));
#endif
setMultiplier(renderer, multiplier);
// Make sure all list items are autosized consistently.
- for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = renderer->slowFirstChild(); child; child = child->nextSibling()) {
if (child->isListItem() && child->style()->textAutosizingMultiplier() == 1)
setMultiplier(child, multiplier);
}
@@ -337,7 +506,7 @@ bool TextAutosizer::isAutosizingContainer(const RenderObject* renderer)
// - Must not be normal list items, as items in the same list should look
// consistent, unless they are floating or position:absolute/fixed.
Node* node = renderer->generatingNode();
- if ((node && !node->hasChildNodes())
+ if ((node && !node->hasChildren())
|| !renderer->isRenderBlock()
|| (renderer->isInline() && !renderer->style()->isDisplayReplacedType()))
return false;
@@ -367,14 +536,14 @@ bool TextAutosizer::isNarrowDescendant(const RenderBlock* renderer, TextAutosizi
// the enclosing cluster. This 150px limit is adjusted whenever a descendant container is
// less than 50px narrower than the current limit.
const float differenceFromMaxWidthDifference = 50;
- float contentWidth = renderer->contentLogicalWidth();
- float clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
- float widthDifference = clusterTextWidth - contentWidth;
+ LayoutUnit contentWidth = renderer->contentLogicalWidth();
+ LayoutUnit clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
+ LayoutUnit widthDifference = clusterTextWidth - contentWidth;
if (widthDifference - parentClusterInfo.maxAllowedDifferenceFromTextWidth > differenceFromMaxWidthDifference)
return true;
- parentClusterInfo.maxAllowedDifferenceFromTextWidth = std::max(widthDifference, parentClusterInfo.maxAllowedDifferenceFromTextWidth);
+ parentClusterInfo.maxAllowedDifferenceFromTextWidth = std::max(widthDifference.toFloat(), parentClusterInfo.maxAllowedDifferenceFromTextWidth);
return false;
}
@@ -384,8 +553,8 @@ bool TextAutosizer::isWiderDescendant(const RenderBlock* renderer, const TextAut
// Autosizing containers that are wider than the |blockContainingAllText| of their enclosing
// cluster are treated the same way as autosizing clusters to be autosized separately.
- float contentWidth = renderer->contentLogicalWidth();
- float clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
+ LayoutUnit contentWidth = renderer->contentLogicalWidth();
+ LayoutUnit clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
return contentWidth > clusterTextWidth;
}
@@ -412,6 +581,7 @@ bool TextAutosizer::isIndependentDescendant(const RenderBlock* renderer)
// from the box's parent (we want to avoid having significantly different
// width blocks within a cluster, since the narrower blocks would end up
// larger than would otherwise be necessary).
+ RenderBlock* containingBlock = renderer->containingBlock();
return renderer->isRenderView()
|| renderer->isFloating()
|| renderer->isOutOfFlowPositioned()
@@ -419,7 +589,7 @@ bool TextAutosizer::isIndependentDescendant(const RenderBlock* renderer)
|| renderer->isTableCaption()
|| renderer->isFlexibleBoxIncludingDeprecated()
|| renderer->hasColumns()
- || renderer->containingBlock()->isHorizontalWritingMode() != renderer->isHorizontalWritingMode()
+ || (containingBlock && containingBlock->isHorizontalWritingMode() != renderer->isHorizontalWritingMode())
|| renderer->style()->isDisplayReplacedType()
|| renderer->isTextArea()
|| renderer->style()->userModify() != READ_ONLY;
@@ -520,7 +690,7 @@ bool TextAutosizer::contentHeightIsConstrained(const RenderBlock* container)
if (style->height().isSpecified() || style->maxHeight().isSpecified() || container->isOutOfFlowPositioned()) {
// Some sites (e.g. wikipedia) set their html and/or body elements to height:100%,
// without intending to constrain the height of the content within them.
- return !container->isRoot() && !container->isBody();
+ return !container->isDocumentElement() && !container->isBody();
}
if (container->isFloating())
return false;
@@ -528,12 +698,6 @@ bool TextAutosizer::contentHeightIsConstrained(const RenderBlock* container)
return false;
}
-bool TextAutosizer::clusterShouldBeAutosized(TextAutosizingClusterInfo& clusterInfo, float blockWidth)
-{
- Vector<TextAutosizingClusterInfo> clusterInfos(1, clusterInfo);
- return compositeClusterShouldBeAutosized(clusterInfos, blockWidth);
-}
-
bool TextAutosizer::compositeClusterShouldBeAutosized(Vector<TextAutosizingClusterInfo>& clusterInfos, float blockWidth)
{
// Don't autosize clusters that contain less than 4 lines of text (in
@@ -634,11 +798,11 @@ const RenderBlock* TextAutosizer::findDeepestBlockContainingAllText(const Render
const RenderObject* TextAutosizer::findFirstTextLeafNotInCluster(const RenderObject* parent, size_t& depth, TraversalDirection direction)
{
- if (parent->isEmpty())
- return parent->isText() ? parent : 0;
+ if (parent->isText())
+ return parent;
++depth;
- const RenderObject* child = (direction == FirstToLast) ? parent->firstChild() : parent->lastChild();
+ const RenderObject* child = (direction == FirstToLast) ? parent->slowFirstChild() : parent->slowLastChild();
while (child) {
if (!isAutosizingContainer(child) || !isIndependentDescendant(toRenderBlock(child))) {
const RenderObject* leaf = findFirstTextLeafNotInCluster(child, depth, direction);
@@ -681,8 +845,8 @@ void TextAutosizer::getNarrowDescendantsGroupedByWidth(const TextAutosizingClust
groups.last().append(clusterInfos[i]);
if (i + 1 < clusterInfos.size()) {
- float currentWidth = clusterInfos[i].root->contentLogicalWidth();
- float nextWidth = clusterInfos[i + 1].root->contentLogicalWidth();
+ LayoutUnit currentWidth = clusterInfos[i].root->contentLogicalWidth();
+ LayoutUnit nextWidth = clusterInfos[i + 1].root->contentLogicalWidth();
if (currentWidth - nextWidth > maxWidthDifferenceWithinGroup)
groups.grow(groups.size() + 1);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.h b/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.h
index dda763efa7b..aac87074bb4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.h
@@ -26,9 +26,11 @@
#ifndef TextAutosizer_h
#define TextAutosizer_h
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "platform/text/WritingMode.h"
+#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
+#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
@@ -36,9 +38,28 @@ namespace WebCore {
class Document;
class RenderBlock;
class RenderObject;
-class RenderText;
struct TextAutosizingWindowInfo;
-struct TextAutosizingClusterInfo;
+
+// Represents cluster related data. Instances should not persist between calls to processSubtree.
+struct TextAutosizingClusterInfo {
+ explicit TextAutosizingClusterInfo(RenderBlock* root)
+ : root(root)
+ , blockContainingAllText(0)
+ , maxAllowedDifferenceFromTextWidth(150)
+ {
+ }
+
+ RenderBlock* root;
+ const RenderBlock* blockContainingAllText;
+
+ // Upper limit on the difference between the width of the cluster's block containing all
+ // text and that of a narrow child before the child becomes a separate cluster.
+ float maxAllowedDifferenceFromTextWidth;
+
+ // Descendants of the cluster that are narrower than the block containing all text and must be
+ // processed together.
+ Vector<TextAutosizingClusterInfo> narrowDescendants;
+};
class TextAutosizer FINAL {
WTF_MAKE_NONCOPYABLE(TextAutosizer);
@@ -61,6 +82,7 @@ private:
explicit TextAutosizer(Document*);
+ bool isApplicable() const;
float clusterMultiplier(WritingMode, const TextAutosizingWindowInfo&, float textWidth) const;
void processClusterInternal(TextAutosizingClusterInfo&, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo&, float multiplier);
@@ -71,6 +93,8 @@ private:
void setMultiplier(RenderObject*, float);
void setMultiplierForList(RenderObject* renderer, float multiplier);
+ unsigned getCachedHash(const RenderObject* renderer, bool putInCacheIfAbsent);
+
static bool isAutosizingContainer(const RenderObject*);
static bool isNarrowDescendant(const RenderBlock*, TextAutosizingClusterInfo& parentClusterInfo);
static bool isWiderDescendant(const RenderBlock*, const TextAutosizingClusterInfo& parentClusterInfo);
@@ -81,9 +105,10 @@ private:
static bool containerContainsOneOfTags(const RenderBlock* cluster, const Vector<QualifiedName>& tags);
static bool containerIsRowOfLinks(const RenderObject* container);
static bool contentHeightIsConstrained(const RenderBlock* container);
- static bool clusterShouldBeAutosized(TextAutosizingClusterInfo&, float blockWidth);
static bool compositeClusterShouldBeAutosized(Vector<TextAutosizingClusterInfo>&, float blockWidth);
static void measureDescendantTextWidth(const RenderBlock* container, TextAutosizingClusterInfo&, float minTextWidth, float& textWidth);
+ unsigned computeCompositeClusterHash(Vector<TextAutosizingClusterInfo>&);
+ float computeMultiplier(Vector<TextAutosizingClusterInfo>&, const TextAutosizingWindowInfo&, float textWidth);
// Use to traverse the tree of descendants, excluding descendants of containers (but returning the containers themselves).
static RenderObject* nextInPreOrderSkippingDescendantsOfContainers(const RenderObject*, const RenderObject* stayWithin);
@@ -99,7 +124,22 @@ private:
// |blockContainingAllText|.
static void getNarrowDescendantsGroupedByWidth(const TextAutosizingClusterInfo& parentClusterInfo, Vector<Vector<TextAutosizingClusterInfo> >&);
+ void addNonAutosizedCluster(unsigned key, TextAutosizingClusterInfo& value);
+ void secondPassProcessStaleNonAutosizedClusters();
+ void processStaleContainer(float multiplier, RenderBlock* cluster, TextAutosizingClusterInfo&);
+
Document* m_document;
+
+ HashMap<const RenderObject*, unsigned> m_hashCache;
+
+ // Mapping from all autosized (i.e. multiplier > 1) cluster hashes to their respective multipliers.
+ HashMap<unsigned, float> m_hashToMultiplier;
+ Vector<unsigned> m_hashesToAutosizeSecondPass;
+
+ // Mapping from a cluster hash to the corresponding cluster infos which have not been autosized yet.
+ HashMap<unsigned, OwnPtr<Vector<TextAutosizingClusterInfo> > > m_nonAutosizedClusters;
+
+ bool m_previouslyAutosized;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/TrailingFloatsRootInlineBox.h b/chromium/third_party/WebKit/Source/core/rendering/TrailingFloatsRootInlineBox.h
index 8036f5a0432..151f0b08b19 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/TrailingFloatsRootInlineBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/TrailingFloatsRootInlineBox.h
@@ -32,14 +32,14 @@ namespace WebCore {
class TrailingFloatsRootInlineBox FINAL : public RootInlineBox {
public:
- TrailingFloatsRootInlineBox(RenderBlockFlow* block)
+ TrailingFloatsRootInlineBox(RenderBlockFlow& block)
: RootInlineBox(block)
{
setHasVirtualLogicalHeight();
}
private:
- virtual float virtualLogicalHeight() const { return 0; }
+ virtual float virtualLogicalHeight() const OVERRIDE { return 0; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/animation/WebAnimationProvider.cpp b/chromium/third_party/WebKit/Source/core/rendering/animation/WebAnimationProvider.cpp
deleted file mode 100644
index 473e3ff8073..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/animation/WebAnimationProvider.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/rendering/animation/WebAnimationProvider.h"
-
-#include "core/platform/animation/AnimationTranslationUtil.h"
-#include "core/platform/animation/CSSAnimationData.h"
-#include "core/rendering/style/KeyframeList.h"
-#include "core/rendering/style/RenderStyle.h"
-#include "public/platform/WebAnimation.h"
-#include "wtf/text/StringBuilder.h"
-
-using blink::WebAnimation;
-
-namespace WebCore {
-
-namespace {
-
-String animationNameForTransition(AnimatedPropertyID property)
-{
- // | is not a valid identifier character in CSS, so this can never conflict with a keyframe identifier.
- StringBuilder id;
- id.appendLiteral("-|transition");
- id.appendNumber(static_cast<int>(property));
- id.append('-');
- return id.toString();
-}
-
-AnimatedPropertyID cssToGraphicsLayerProperty(CSSPropertyID cssProperty)
-{
- switch (cssProperty) {
- case CSSPropertyWebkitTransform:
- return AnimatedPropertyWebkitTransform;
- case CSSPropertyOpacity:
- return AnimatedPropertyOpacity;
- case CSSPropertyBackgroundColor:
- ASSERT_NOT_REACHED();
- return AnimatedPropertyInvalid; // Chromium compositor cannot accelerate background color yet.
- case CSSPropertyWebkitFilter:
- return AnimatedPropertyWebkitFilter;
- default:
- // It's fine if we see other css properties here; they are just not accelerated.
- break;
- }
- return AnimatedPropertyInvalid;
-}
-
-} // namespace
-
-WebAnimations::WebAnimations()
-{
-}
-
-WebAnimations::~WebAnimations()
-{
-}
-
-// Copy constructor is needed to use this struct as a return value. It actually moves the ownership, not copy.
-WebAnimations::WebAnimations(const WebAnimations& other)
-{
- ASSERT(isEmpty());
- m_transformAnimation.swap(const_cast<OwnPtr<WebAnimation>& >(other.m_transformAnimation));
- m_opacityAnimation.swap(const_cast<OwnPtr<WebAnimation>& >(other.m_opacityAnimation));
- m_filterAnimation.swap(const_cast<OwnPtr<WebAnimation>& >(other.m_filterAnimation));
- ASSERT(other.isEmpty());
-}
-
-bool WebAnimations::isEmpty() const
-{
- return !m_transformAnimation && !m_opacityAnimation && !m_filterAnimation;
-}
-
-WebAnimationProvider::WebAnimationProvider()
-{
-}
-
-WebAnimationProvider::~WebAnimationProvider()
-{
-}
-
-int WebAnimationProvider::getWebAnimationId(const String& animationName) const
-{
- if (!m_animationIdMap.contains(animationName))
- return 0;
- return m_animationIdMap.get(animationName);
-}
-
-int WebAnimationProvider::getWebAnimationId(CSSPropertyID property) const
-{
- AnimatedPropertyID animatedProperty = cssToGraphicsLayerProperty(property);
- ASSERT(animatedProperty != AnimatedPropertyInvalid);
- return getWebAnimationId(animationNameForTransition(animatedProperty));
-}
-
-WebAnimations WebAnimationProvider::startAnimation(double timeOffset, const CSSAnimationData* anim, const KeyframeList& keyframes, bool hasTransform, const IntSize& boxSize)
-{
- ASSERT(hasTransform || boxSize.isEmpty());
- bool hasOpacity = keyframes.containsProperty(CSSPropertyOpacity);
- bool hasFilter = keyframes.containsProperty(CSSPropertyWebkitFilter);
-
- if (!hasOpacity && !hasTransform && !hasFilter)
- return WebAnimations();
-
- KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
- KeyframeValueList opacityVector(AnimatedPropertyOpacity);
- KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
-
- size_t numKeyframes = keyframes.size();
- for (size_t i = 0; i < numKeyframes; ++i) {
- const KeyframeValue& currentKeyframe = keyframes[i];
- const RenderStyle* keyframeStyle = currentKeyframe.style();
- double key = currentKeyframe.key();
-
- if (!keyframeStyle)
- continue;
-
- // Get timing function.
- RefPtr<TimingFunction> tf = KeyframeValue::timingFunction(*keyframeStyle);
-
- bool isFirstOrLastKeyframe = !key || key == 1;
- if ((hasTransform && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitTransform))
- transformVector.insert(adoptPtr(new TransformAnimationValue(key, &(keyframeStyle->transform()), tf)));
-
- if ((hasOpacity && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyOpacity))
- opacityVector.insert(adoptPtr(new FloatAnimationValue(key, keyframeStyle->opacity(), tf)));
-
- if ((hasFilter && isFirstOrLastKeyframe) || currentKeyframe.containsProperty(CSSPropertyWebkitFilter))
- filterVector.insert(adoptPtr(new FilterAnimationValue(key, &(keyframeStyle->filter()), tf)));
- }
- WebAnimations resultAnimations;
- if (hasTransform)
- resultAnimations.m_transformAnimation = createWebAnimationAndStoreId(transformVector, boxSize, anim, keyframes.animationName(), timeOffset);
- if (hasOpacity)
- resultAnimations.m_opacityAnimation = createWebAnimationAndStoreId(opacityVector, IntSize(), anim, keyframes.animationName(), timeOffset);
- if (hasFilter)
- resultAnimations.m_filterAnimation = createWebAnimationAndStoreId(filterVector, IntSize(), anim, keyframes.animationName(), timeOffset);
-
- return resultAnimations;
-}
-
-WebAnimations WebAnimationProvider::startTransition(double timeOffset, CSSPropertyID property, const RenderStyle* fromStyle, const RenderStyle* toStyle, bool hasTransform, bool hasFilter, const IntSize& boxSize, float fromOpacity, float toOpacity)
-{
- ASSERT(property != CSSPropertyInvalid);
- ASSERT(property == CSSPropertyOpacity || (!fromOpacity && !toOpacity));
-
- WebAnimations resultAnimations;
- if (property == CSSPropertyOpacity) {
- const CSSAnimationData* opacityAnim = toStyle->transitionForProperty(CSSPropertyOpacity);
- if (opacityAnim && !opacityAnim->isEmptyOrZeroDuration()) {
- KeyframeValueList opacityVector(AnimatedPropertyOpacity);
- opacityVector.insert(adoptPtr(new FloatAnimationValue(0, fromOpacity)));
- opacityVector.insert(adoptPtr(new FloatAnimationValue(1, toOpacity)));
- resultAnimations.m_opacityAnimation = createWebAnimationAndStoreId(opacityVector, IntSize(), opacityAnim, animationNameForTransition(AnimatedPropertyOpacity), timeOffset);
- }
- }
- if (property == CSSPropertyWebkitTransform && hasTransform) {
- const CSSAnimationData* transformAnim = toStyle->transitionForProperty(CSSPropertyWebkitTransform);
- if (transformAnim && !transformAnim->isEmptyOrZeroDuration()) {
- KeyframeValueList transformVector(AnimatedPropertyWebkitTransform);
- transformVector.insert(adoptPtr(new TransformAnimationValue(0, &fromStyle->transform())));
- transformVector.insert(adoptPtr(new TransformAnimationValue(1, &toStyle->transform())));
- resultAnimations.m_transformAnimation = createWebAnimationAndStoreId(transformVector, boxSize, transformAnim, animationNameForTransition(AnimatedPropertyWebkitTransform), timeOffset);
- }
- }
- if (property == CSSPropertyWebkitFilter && hasFilter) {
- const CSSAnimationData* filterAnim = toStyle->transitionForProperty(CSSPropertyWebkitFilter);
- if (filterAnim && !filterAnim->isEmptyOrZeroDuration()) {
- KeyframeValueList filterVector(AnimatedPropertyWebkitFilter);
- filterVector.insert(adoptPtr(new FilterAnimationValue(0, &fromStyle->filter())));
- filterVector.insert(adoptPtr(new FilterAnimationValue(1, &toStyle->filter())));
- resultAnimations.m_filterAnimation = createWebAnimationAndStoreId(filterVector, IntSize(), filterAnim, animationNameForTransition(AnimatedPropertyWebkitFilter), timeOffset);
- }
- }
-
- return resultAnimations;
-}
-
-PassOwnPtr<WebAnimation> WebAnimationProvider::createWebAnimationAndStoreId(const KeyframeValueList& values, const IntSize& boxSize, const CSSAnimationData* animation, const String& animationName, double timeOffset)
-{
- int animationId = getWebAnimationId(animationName);
- OwnPtr<WebAnimation> webAnimation(createWebAnimation(values, animation, animationId, timeOffset, boxSize));
- if (!webAnimation)
- return PassOwnPtr<WebAnimation>();
-
- if (!animationId)
- m_animationIdMap.set(animationName, webAnimation->id());
- return webAnimation.release();
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/animation/WebAnimationProvider.h b/chromium/third_party/WebKit/Source/core/rendering/animation/WebAnimationProvider.h
deleted file mode 100644
index 724de2e1696..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/animation/WebAnimationProvider.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebAnimationProvider_h
-#define WebAnimationProvider_h
-
-#include "CSSPropertyNames.h"
-#include "core/platform/animation/KeyframeValueList.h"
-#include "wtf/HashMap.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-class WebAnimation;
-}
-
-namespace WebCore {
-class CSSAnimationData;
-class IntSize;
-class KeyframeList;
-class RenderStyle;
-
-struct WebAnimations {
- WebAnimations();
- ~WebAnimations();
- WebAnimations(const WebAnimations&);
- bool isEmpty() const;
- OwnPtr<blink::WebAnimation> m_transformAnimation;
- OwnPtr<blink::WebAnimation> m_opacityAnimation;
- OwnPtr<blink::WebAnimation> m_filterAnimation;
-};
-
-class WebAnimationProvider {
- WTF_MAKE_NONCOPYABLE(WebAnimationProvider); WTF_MAKE_FAST_ALLOCATED;
-public:
- WebAnimationProvider();
- ~WebAnimationProvider();
-
- int getWebAnimationId(const String& animationName) const;
- int getWebAnimationId(CSSPropertyID) const;
- WebAnimations startAnimation(double timeOffset, const CSSAnimationData*, const KeyframeList&, bool hasTransform, const IntSize& boxSize);
- WebAnimations startTransition(double timeOffset, CSSPropertyID, const RenderStyle* fromStyle, const RenderStyle* toStyle, bool hasTransform, bool hasFilter, const IntSize& boxSize, float fromOpacity, float toOpacity);
-
-private:
- PassOwnPtr<blink::WebAnimation> createWebAnimationAndStoreId(const KeyframeValueList&, const IntSize& boxSize, const CSSAnimationData*, const String& animationName, double timeOffset);
-
- typedef HashMap<String, int> AnimationIdMap;
- AnimationIdMap m_animationIdMap;
-};
-
-} // namespace WebCore
-
-#endif // WebAnimationProvider_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp
new file mode 100644
index 00000000000..0b01a059bc5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp
@@ -0,0 +1,2246 @@
+/*
+ * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+
+#include "core/HTMLNames.h"
+#include "core/fetch/ImageResource.h"
+#include "core/html/HTMLCanvasElement.h"
+#include "core/html/HTMLIFrameElement.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorNodeIds.h"
+#include "core/inspector/InspectorTraceEvents.h"
+#include "core/page/Chrome.h"
+#include "core/frame/FrameView.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "core/plugins/PluginView.h"
+#include "core/rendering/FilterEffectRenderer.h"
+#include "core/rendering/RenderImage.h"
+#include "core/rendering/RenderLayerStackingNodeIterator.h"
+#include "core/rendering/RenderVideo.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "core/rendering/style/KeyframeList.h"
+#include "platform/LengthFunctions.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/fonts/FontCache.h"
+#include "platform/graphics/GraphicsContext.h"
+#include "wtf/CurrentTime.h"
+#include "wtf/text/StringBuilder.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static IntRect clipBox(RenderBox* renderer);
+
+static IntRect contentsRect(const RenderObject* renderer)
+{
+ if (!renderer->isBox())
+ return IntRect();
+
+ return renderer->isVideo() ?
+ toRenderVideo(renderer)->videoBox() :
+ pixelSnappedIntRect(toRenderBox(renderer)->contentBoxRect());
+}
+
+static IntRect backgroundRect(const RenderObject* renderer)
+{
+ if (!renderer->isBox())
+ return IntRect();
+
+ LayoutRect rect;
+ const RenderBox* box = toRenderBox(renderer);
+ EFillBox clip = box->style()->backgroundClip();
+ switch (clip) {
+ case BorderFillBox:
+ rect = box->borderBoxRect();
+ break;
+ case PaddingFillBox:
+ rect = box->paddingBoxRect();
+ break;
+ case ContentFillBox:
+ rect = box->contentBoxRect();
+ break;
+ case TextFillBox:
+ break;
+ }
+
+ return pixelSnappedIntRect(rect);
+}
+
+static inline bool isAcceleratedCanvas(const RenderObject* renderer)
+{
+ if (renderer->isCanvas()) {
+ HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
+ if (CanvasRenderingContext* context = canvas->renderingContext())
+ return context->isAccelerated();
+ }
+ return false;
+}
+
+static bool hasBoxDecorations(const RenderStyle* style)
+{
+ return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
+}
+
+static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
+{
+ return hasBoxDecorations(style) || style->hasBackgroundImage();
+}
+
+static bool contentLayerSupportsDirectBackgroundComposition(const RenderObject* renderer)
+{
+ // No support for decorations - border, border-radius or outline.
+ // Only simple background - solid color or transparent.
+ if (hasBoxDecorationsOrBackgroundImage(renderer->style()))
+ return false;
+
+ // If there is no background, there is nothing to support.
+ if (!renderer->style()->hasBackground())
+ return true;
+
+ // Simple background that is contained within the contents rect.
+ return contentsRect(renderer).contains(backgroundRect(renderer));
+}
+
+static blink::WebLayer* platformLayerForPlugin(RenderObject* renderer)
+{
+ if (!renderer->isEmbeddedObject())
+ return 0;
+ Widget* widget = toRenderEmbeddedObject(renderer)->widget();
+ if (!widget || !widget->isPluginView())
+ return 0;
+ return toPluginView(widget)->platformLayer();
+
+}
+
+static inline bool isAcceleratedContents(RenderObject* renderer)
+{
+ return isAcceleratedCanvas(renderer)
+ || (renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->requiresAcceleratedCompositing())
+ || renderer->isVideo();
+}
+
+// Get the scrolling coordinator in a way that works inside CompositedLayerMapping's destructor.
+static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer& layer)
+{
+ Page* page = layer.renderer()->frame()->page();
+ if (!page)
+ return 0;
+
+ return page->scrollingCoordinator();
+}
+
+CompositedLayerMapping::CompositedLayerMapping(RenderLayer& layer)
+ : m_owningLayer(layer)
+ , m_pendingUpdateScope(GraphicsLayerUpdateNone)
+ , m_isMainFrameRenderViewLayer(false)
+ , m_requiresOwnBackingStoreForIntrinsicReasons(true)
+ , m_requiresOwnBackingStoreForAncestorReasons(true)
+ , m_canCompositeFilters(false)
+ , m_backgroundLayerPaintsFixedRootBackground(false)
+ , m_scrollingContentsAreEmpty(false)
+{
+ if (layer.isRootLayer() && renderer()->frame()->isMainFrame())
+ m_isMainFrameRenderViewLayer = true;
+
+ createPrimaryGraphicsLayer();
+}
+
+CompositedLayerMapping::~CompositedLayerMapping()
+{
+ // Hits in compositing/squashing/squash-onto-nephew.html.
+ DisableCompositingQueryAsserts disabler;
+
+ // Do not leave the destroyed pointer dangling on any RenderLayers that painted to this mapping's squashing layer.
+ for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
+ RenderLayer* oldSquashedLayer = m_squashedLayers[i].renderLayer;
+ if (oldSquashedLayer->groupedMapping() == this) {
+ oldSquashedLayer->setGroupedMapping(0, true);
+ oldSquashedLayer->setLostGroupedMapping(true);
+ }
+ }
+
+ updateClippingLayers(false, false);
+ updateOverflowControlsLayers(false, false, false);
+ updateChildTransformLayer(false);
+ updateForegroundLayer(false);
+ updateBackgroundLayer(false);
+ updateMaskLayer(false);
+ updateClippingMaskLayers(false);
+ updateScrollingLayers(false);
+ updateSquashingLayers(false);
+ destroyGraphicsLayers();
+}
+
+PassOwnPtr<GraphicsLayer> CompositedLayerMapping::createGraphicsLayer(CompositingReasons reasons)
+{
+ GraphicsLayerFactory* graphicsLayerFactory = 0;
+ if (Page* page = renderer()->frame()->page())
+ graphicsLayerFactory = page->chrome().client().graphicsLayerFactory();
+
+ OwnPtr<GraphicsLayer> graphicsLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+
+ graphicsLayer->setCompositingReasons(reasons);
+ if (Node* owningNode = m_owningLayer.renderer()->generatingNode())
+ graphicsLayer->setOwnerNodeId(InspectorNodeIds::idForNode(owningNode));
+
+ return graphicsLayer.release();
+}
+
+void CompositedLayerMapping::createPrimaryGraphicsLayer()
+{
+ m_graphicsLayer = createGraphicsLayer(m_owningLayer.compositingReasons());
+
+#if !OS(ANDROID)
+ if (m_isMainFrameRenderViewLayer)
+ m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
+#endif
+
+ updateOpacity(renderer()->style());
+ updateTransform(renderer()->style());
+ updateFilters(renderer()->style());
+
+ if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
+ updateLayerBlendMode(renderer()->style());
+ updateIsRootForIsolatedGroup();
+ }
+}
+
+void CompositedLayerMapping::destroyGraphicsLayers()
+{
+ if (m_graphicsLayer)
+ m_graphicsLayer->removeFromParent();
+
+ m_ancestorClippingLayer = nullptr;
+ m_graphicsLayer = nullptr;
+ m_foregroundLayer = nullptr;
+ m_backgroundLayer = nullptr;
+ m_childContainmentLayer = nullptr;
+ m_childTransformLayer = nullptr;
+ m_maskLayer = nullptr;
+ m_childClippingMaskLayer = nullptr;
+
+ m_scrollingLayer = nullptr;
+ m_scrollingContentsLayer = nullptr;
+ m_scrollingBlockSelectionLayer = nullptr;
+}
+
+void CompositedLayerMapping::updateOpacity(const RenderStyle* style)
+{
+ m_graphicsLayer->setOpacity(compositingOpacity(style->opacity()));
+}
+
+void CompositedLayerMapping::updateTransform(const RenderStyle* style)
+{
+ // FIXME: This could use m_owningLayer.transform(), but that currently has transform-origin
+ // baked into it, and we don't want that.
+ TransformationMatrix t;
+ if (m_owningLayer.hasTransform()) {
+ style->applyTransform(t, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
+ makeMatrixRenderable(t, compositor()->hasAcceleratedCompositing());
+ }
+
+ m_graphicsLayer->setTransform(t);
+}
+
+void CompositedLayerMapping::updateFilters(const RenderStyle* style)
+{
+ unsigned didCompositeFilters = m_canCompositeFilters;
+ m_canCompositeFilters = m_graphicsLayer->setFilters(owningLayer().computeFilterOperations(style));
+ if (didCompositeFilters != m_canCompositeFilters) {
+ //
+ // If filters used to be painted in software and are now painted in the compositor, we need to:
+ // (1) Remove the FilterEffectRenderer, which was used for painting filters in software.
+ // (2) Repaint the layer contents to remove the software-applied filter because the compositor will apply it.
+ //
+ // Similarly, if filters used to be painted in the compositor and are now painted in software, we need to:
+ // (1) Create a FilterEffectRenderer.
+ // (2) Repaint the layer contents to apply a software filter because the compositor won't apply it.
+ //
+ m_owningLayer.updateOrRemoveFilterEffectRenderer();
+ setContentsNeedDisplay();
+ }
+}
+
+void CompositedLayerMapping::updateLayerBlendMode(const RenderStyle* style)
+{
+ setBlendMode(style->blendMode());
+}
+
+void CompositedLayerMapping::updateIsRootForIsolatedGroup()
+{
+ bool isolate = m_owningLayer.shouldIsolateCompositedDescendants();
+
+ // non stacking context layers should never isolate
+ ASSERT(m_owningLayer.stackingNode()->isStackingContext() || !isolate);
+
+ m_graphicsLayer->setIsRootForIsolatedGroup(isolate);
+}
+
+void CompositedLayerMapping::updateContentsOpaque()
+{
+ // For non-root layers, background is always painted by the primary graphics layer.
+ ASSERT(m_isMainFrameRenderViewLayer || !m_backgroundLayer);
+ if (m_backgroundLayer) {
+ m_graphicsLayer->setContentsOpaque(false);
+ m_backgroundLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
+ } else {
+ m_graphicsLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
+ }
+}
+
+void CompositedLayerMapping::updateCompositedBounds(GraphicsLayerUpdater::UpdateType updateType)
+{
+ if (!shouldUpdateGraphicsLayer(updateType))
+ return;
+
+ // FIXME: if this is really needed for performance, it would be better to store it on RenderLayer.
+ m_compositedBounds = m_owningLayer.boundingBoxForCompositing();
+}
+
+void CompositedLayerMapping::updateAfterWidgetResize()
+{
+ if (renderer()->isRenderPart()) {
+ if (RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(toRenderPart(renderer()))) {
+ innerCompositor->frameViewDidChangeSize();
+ // We can floor this point because our frameviews are always aligned to pixel boundaries.
+ ASSERT(contentsBox().location() == flooredIntPoint(contentsBox().location()));
+ innerCompositor->frameViewDidChangeLocation(flooredIntPoint(contentsBox().location()));
+ }
+ }
+}
+
+void CompositedLayerMapping::updateCompositingReasons()
+{
+ // All other layers owned by this mapping will have the same compositing reason
+ // for their lifetime, so they are initialized only when created.
+ m_graphicsLayer->setCompositingReasons(m_owningLayer.compositingReasons());
+}
+
+bool CompositedLayerMapping::updateGraphicsLayerConfiguration(GraphicsLayerUpdater::UpdateType updateType)
+{
+ if (!shouldUpdateGraphicsLayer(updateType))
+ return false;
+
+ RenderLayerCompositor* compositor = this->compositor();
+ RenderObject* renderer = this->renderer();
+
+ m_owningLayer.updateDescendantDependentFlags();
+ m_owningLayer.stackingNode()->updateZOrderLists();
+
+ bool layerConfigChanged = false;
+ setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(&m_owningLayer));
+
+ // The background layer is currently only used for fixed root backgrounds.
+ if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
+ layerConfigChanged = true;
+
+ if (updateForegroundLayer(compositor->needsContentsCompositingLayer(&m_owningLayer)))
+ layerConfigChanged = true;
+
+ bool needsDescendantsClippingLayer = compositor->clipsCompositingDescendants(&m_owningLayer);
+
+ // Our scrolling layer will clip.
+ if (m_owningLayer.needsCompositedScrolling())
+ needsDescendantsClippingLayer = false;
+
+ RenderLayer* scrollParent = compositor->acceleratedCompositingForOverflowScrollEnabled() ? m_owningLayer.scrollParent() : 0;
+ bool needsAncestorClip = compositor->clippedByNonAncestorInStackingTree(&m_owningLayer);
+ if (scrollParent) {
+ // If our containing block is our ancestor scrolling layer, then we'll already be clipped
+ // to it via our scroll parent and we don't need an ancestor clipping layer.
+ if (m_owningLayer.renderer()->containingBlock()->enclosingLayer() == m_owningLayer.ancestorScrollingLayer())
+ needsAncestorClip = false;
+ }
+
+ if (updateClippingLayers(needsAncestorClip, needsDescendantsClippingLayer))
+ layerConfigChanged = true;
+
+ if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
+ layerConfigChanged = true;
+
+ bool scrollingConfigChanged = false;
+ if (updateScrollingLayers(m_owningLayer.needsCompositedScrolling())) {
+ layerConfigChanged = true;
+ scrollingConfigChanged = true;
+ }
+
+ bool hasPerspective = false;
+ if (RenderStyle* style = renderer->style())
+ hasPerspective = style->hasPerspective();
+ bool needsChildTransformLayer = hasPerspective && (layerForChildrenTransform() == m_childTransformLayer.get()) && renderer->isBox();
+ if (updateChildTransformLayer(needsChildTransformLayer))
+ layerConfigChanged = true;
+
+ updateScrollParent(scrollParent);
+ updateClipParent(m_owningLayer.clipParent());
+
+ if (updateSquashingLayers(!m_squashedLayers.isEmpty()))
+ layerConfigChanged = true;
+
+ if (layerConfigChanged)
+ updateInternalHierarchy();
+
+ if (scrollingConfigChanged) {
+ if (renderer->view())
+ compositor->scrollingLayerDidChange(&m_owningLayer);
+ }
+
+ // A mask layer is not part of the hierarchy proper, it's an auxiliary layer
+ // that's plugged into another GraphicsLayer that is part of the hierarchy.
+ // It has no parent or child GraphicsLayer. For that reason, we process it
+ // here, after the hierarchy has been updated.
+ bool maskLayerChanged = false;
+ if (updateMaskLayer(renderer->hasMask())) {
+ maskLayerChanged = true;
+ m_graphicsLayer->setMaskLayer(m_maskLayer.get());
+ }
+
+ bool hasChildClippingLayer = compositor->clipsCompositingDescendants(&m_owningLayer) && (hasClippingLayer() || hasScrollingLayer());
+ // If we have a border radius or clip path on a scrolling layer, we need a clipping mask to properly
+ // clip the scrolled contents, even if there are no composited descendants.
+ bool hasClipPath = renderer->style()->clipPath();
+ bool needsChildClippingMask = (hasClipPath || renderer->style()->hasBorderRadius()) && (hasChildClippingLayer || isAcceleratedContents(renderer) || hasScrollingLayer());
+ if (updateClippingMaskLayers(needsChildClippingMask)) {
+ // Clip path clips the entire subtree, including scrollbars. It must be attached directly onto
+ // the main m_graphicsLayer.
+ if (hasClipPath)
+ m_graphicsLayer->setMaskLayer(m_childClippingMaskLayer.get());
+ else if (hasClippingLayer())
+ clippingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
+ else if (hasScrollingLayer())
+ scrollingLayer()->setMaskLayer(m_childClippingMaskLayer.get());
+ else if (isAcceleratedContents(renderer))
+ m_graphicsLayer->setContentsClippingMaskLayer(m_childClippingMaskLayer.get());
+ }
+
+ if (m_owningLayer.reflectionInfo()) {
+ if (m_owningLayer.reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
+ GraphicsLayer* reflectionLayer = m_owningLayer.reflectionInfo()->reflectionLayer()->compositedLayerMapping()->mainGraphicsLayer();
+ m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
+ }
+ } else {
+ m_graphicsLayer->setReplicatedByLayer(0);
+ }
+
+ updateBackgroundColor();
+
+ if (isDirectlyCompositedImage())
+ updateImageContents();
+
+ if (blink::WebLayer* layer = platformLayerForPlugin(renderer)) {
+ m_graphicsLayer->setContentsToPlatformLayer(layer);
+ } else if (renderer->node() && renderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(renderer->node())->contentFrame()) {
+ blink::WebLayer* layer = toHTMLFrameOwnerElement(renderer->node())->contentFrame()->remotePlatformLayer();
+ if (layer)
+ m_graphicsLayer->setContentsToPlatformLayer(layer);
+ } else if (renderer->isVideo()) {
+ HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer->node());
+ m_graphicsLayer->setContentsToPlatformLayer(mediaElement->platformLayer());
+ } else if (isAcceleratedCanvas(renderer)) {
+ HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
+ if (CanvasRenderingContext* context = canvas->renderingContext())
+ m_graphicsLayer->setContentsToPlatformLayer(context->platformLayer());
+ layerConfigChanged = true;
+ }
+ if (renderer->isRenderPart())
+ layerConfigChanged = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(renderer));
+
+ // Changes to either the internal hierarchy or the mask layer have an impact
+ // on painting phases, so we need to update when either are updated.
+ if (layerConfigChanged || maskLayerChanged)
+ updatePaintingPhases();
+
+ return layerConfigChanged;
+}
+
+static IntRect clipBox(RenderBox* renderer)
+{
+ LayoutRect result = PaintInfo::infiniteRect();
+ if (renderer->hasOverflowClip())
+ result = renderer->overflowClipRect(LayoutPoint());
+
+ if (renderer->hasClip())
+ result.intersect(renderer->clipRect(LayoutPoint()));
+
+ return pixelSnappedIntRect(result);
+}
+
+static LayoutPoint computeOffsetFromCompositedAncestor(const RenderLayer* layer, const RenderLayer* compositedAncestor)
+{
+ LayoutPoint offset;
+ layer->convertToLayerCoords(compositedAncestor, offset);
+ if (compositedAncestor)
+ offset.move(compositedAncestor->compositedLayerMapping()->owningLayer().subpixelAccumulation());
+ return offset;
+}
+
+void CompositedLayerMapping::computeBoundsOfOwningLayer(const RenderLayer* compositedAncestor, IntRect& localBounds, IntRect& compositingBoundsRelativeToCompositedAncestor, LayoutPoint& offsetFromCompositedAncestor,
+ IntPoint& snappedOffsetFromCompositedAncestor)
+{
+ LayoutRect localRawCompositingBounds = compositedBounds();
+ offsetFromCompositedAncestor = computeOffsetFromCompositedAncestor(&m_owningLayer, compositedAncestor);
+ snappedOffsetFromCompositedAncestor = IntPoint(offsetFromCompositedAncestor.x().round(), offsetFromCompositedAncestor.y().round());
+
+ LayoutSize subpixelAccumulation = offsetFromCompositedAncestor - snappedOffsetFromCompositedAncestor;
+ m_owningLayer.setSubpixelAccumulation(subpixelAccumulation);
+
+ // Move the bounds by the subpixel accumulation so that it pixel-snaps relative to absolute pixels instead of local coordinates.
+ localRawCompositingBounds.move(subpixelAccumulation);
+ localBounds = pixelSnappedIntRect(localRawCompositingBounds);
+
+ compositingBoundsRelativeToCompositedAncestor = localBounds;
+ compositingBoundsRelativeToCompositedAncestor.moveBy(snappedOffsetFromCompositedAncestor);
+}
+
+void CompositedLayerMapping::updateSquashingLayerGeometry(const LayoutPoint& offsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation, const RenderLayer& referenceLayer,
+ Vector<GraphicsLayerPaintInfo>& layers, GraphicsLayer* squashingLayer, LayoutPoint* offsetFromTransformedAncestor, Vector<RenderLayer*>& layersNeedingPaintInvalidation)
+{
+ if (!squashingLayer)
+ return;
+ ASSERT(compositor()->layerSquashingEnabled());
+
+ LayoutPoint offsetFromReferenceLayerToParentGraphicsLayer(offsetFromCompositedAncestor);
+ offsetFromReferenceLayerToParentGraphicsLayer.moveBy(-graphicsLayerParentLocation);
+
+ // FIXME: Cache these offsets.
+ LayoutPoint referenceOffsetFromTransformedAncestor = referenceLayer.computeOffsetFromTransformedAncestor();
+
+ LayoutRect totalSquashBounds;
+ for (size_t i = 0; i < layers.size(); ++i) {
+ LayoutRect squashedBounds = layers[i].renderLayer->boundingBoxForCompositing();
+
+ // Store the local bounds of the RenderLayer subtree before applying the offset.
+ layers[i].compositedBounds = squashedBounds;
+
+ LayoutPoint offsetFromTransformedAncestorForSquashedLayer = layers[i].renderLayer->computeOffsetFromTransformedAncestor();
+ LayoutSize offsetFromSquashingLayer = offsetFromTransformedAncestorForSquashedLayer - referenceOffsetFromTransformedAncestor;
+
+ squashedBounds.move(offsetFromSquashingLayer);
+ totalSquashBounds.unite(squashedBounds);
+ }
+
+ // The totalSquashBounds is positioned with respect to referenceLayer of this CompositedLayerMapping.
+ // But the squashingLayer needs to be positioned with respect to the ancestor CompositedLayerMapping.
+ // The conversion between referenceLayer and the ancestor CLM is already computed as
+ // offsetFromReferenceLayerToParentGraphicsLayer.
+ totalSquashBounds.moveBy(offsetFromReferenceLayerToParentGraphicsLayer);
+ IntRect squashLayerBounds = enclosingIntRect(totalSquashBounds);
+ IntPoint squashLayerOrigin = squashLayerBounds.location();
+ LayoutSize squashLayerOriginInOwningLayerSpace = squashLayerOrigin - offsetFromReferenceLayerToParentGraphicsLayer;
+
+ // Now that the squashing bounds are known, we can convert the RenderLayer painting offsets
+ // from CLM owning layer space to the squashing layer space.
+ //
+ // The painting offset we want to compute for each squashed RenderLayer is essentially the position of
+ // the squashed RenderLayer described w.r.t. referenceLayer's origin. For this purpose we already cached
+ // offsetFromSquashingCLM before, which describes where the squashed RenderLayer is located w.r.t.
+ // referenceLayer. So we just need to convert that point from referenceLayer space to referenceLayer
+ // space. This is simply done by subtracing squashLayerOriginInOwningLayerSpace, but then the offset
+ // overall needs to be negated because that's the direction that the painting code expects the
+ // offset to be.
+ for (size_t i = 0; i < layers.size(); ++i) {
+ LayoutPoint offsetFromTransformedAncestorForSquashedLayer = layers[i].renderLayer->computeOffsetFromTransformedAncestor();
+ LayoutSize offsetFromSquashLayerOrigin = (offsetFromTransformedAncestorForSquashedLayer - referenceOffsetFromTransformedAncestor) - squashLayerOriginInOwningLayerSpace;
+
+ // It is ok to repaint here, because all of the geometry needed to correctly repaint is computed by this point.
+ IntSize newOffsetFromRenderer = -IntSize(offsetFromSquashLayerOrigin.width().round(), offsetFromSquashLayerOrigin.height().round());
+ LayoutSize subpixelAccumulation = offsetFromSquashLayerOrigin + newOffsetFromRenderer;
+ if (layers[i].offsetFromRendererSet && layers[i].offsetFromRenderer != newOffsetFromRenderer) {
+ layers[i].renderLayer->repainter().repaintIncludingNonCompositingDescendants();
+ layersNeedingPaintInvalidation.append(layers[i].renderLayer);
+ }
+ layers[i].offsetFromRenderer = newOffsetFromRenderer;
+ layers[i].offsetFromRendererSet = true;
+
+ layers[i].renderLayer->setSubpixelAccumulation(subpixelAccumulation);
+
+ // FIXME: find a better design to avoid this redundant value - most likely it will make
+ // sense to move the paint task info into RenderLayer's m_compositingProperties.
+ layers[i].renderLayer->setOffsetFromSquashingLayerOrigin(layers[i].offsetFromRenderer);
+ }
+
+ squashingLayer->setPosition(squashLayerBounds.location());
+ squashingLayer->setSize(squashLayerBounds.size());
+
+ *offsetFromTransformedAncestor = referenceOffsetFromTransformedAncestor;
+ offsetFromTransformedAncestor->move(squashLayerOriginInOwningLayerSpace);
+
+ for (size_t i = 0; i < layers.size(); ++i)
+ layers[i].localClipRectForSquashedLayer = localClipRectForSquashedLayer(referenceLayer, layers[i], layers);
+}
+
+void CompositedLayerMapping::updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType updateType, const RenderLayer* compositingContainer, Vector<RenderLayer*>& layersNeedingPaintInvalidation)
+{
+ if (!shouldUpdateGraphicsLayer(updateType))
+ return;
+
+ // Set transform property, if it is not animating. We have to do this here because the transform
+ // is affected by the layer dimensions.
+ if (!renderer()->style()->isRunningTransformAnimationOnCompositor())
+ updateTransform(renderer()->style());
+
+ // Set opacity, if it is not animating.
+ if (!renderer()->style()->isRunningOpacityAnimationOnCompositor())
+ updateOpacity(renderer()->style());
+
+ m_owningLayer.updateDescendantDependentFlags();
+
+ // We compute everything relative to the enclosing compositing layer.
+ IntRect ancestorCompositingBounds;
+ if (compositingContainer) {
+ ASSERT(compositingContainer->hasCompositedLayerMapping());
+ ancestorCompositingBounds = compositingContainer->compositedLayerMapping()->pixelSnappedCompositedBounds();
+ }
+
+ IntRect localCompositingBounds;
+ IntRect relativeCompositingBounds;
+ LayoutPoint offsetFromCompositedAncestor;
+ IntPoint snappedOffsetFromCompositedAncestor;
+ computeBoundsOfOwningLayer(compositingContainer, localCompositingBounds, relativeCompositingBounds, offsetFromCompositedAncestor, snappedOffsetFromCompositedAncestor);
+
+ IntPoint graphicsLayerParentLocation;
+ computeGraphicsLayerParentLocation(compositingContainer, ancestorCompositingBounds, graphicsLayerParentLocation);
+
+ // Might update graphicsLayerParentLocation.
+ updateAncestorClippingLayerGeometry(compositingContainer, snappedOffsetFromCompositedAncestor, graphicsLayerParentLocation);
+
+ FloatSize contentsSize = relativeCompositingBounds.size();
+
+ updateMainGraphicsLayerGeometry(relativeCompositingBounds, localCompositingBounds, graphicsLayerParentLocation);
+ updateSquashingLayerGeometry(offsetFromCompositedAncestor, graphicsLayerParentLocation, m_owningLayer, m_squashedLayers, m_squashingLayer.get(), &m_squashingLayerOffsetFromTransformedAncestor, layersNeedingPaintInvalidation);
+
+ // If we have a layer that clips children, position it.
+ IntRect clippingBox;
+ if (m_childContainmentLayer)
+ clippingBox = clipBox(toRenderBox(renderer()));
+
+ updateChildContainmentLayerGeometry(clippingBox, localCompositingBounds);
+ updateChildTransformLayerGeometry();
+
+ updateMaskLayerGeometry();
+ updateTransformGeometry(snappedOffsetFromCompositedAncestor, relativeCompositingBounds);
+ updateForegroundLayerGeometry(contentsSize, clippingBox);
+ updateBackgroundLayerGeometry(contentsSize);
+ updateReflectionLayerGeometry(layersNeedingPaintInvalidation);
+ updateScrollingLayerGeometry(localCompositingBounds);
+ updateChildClippingMaskLayerGeometry();
+
+ if (m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->scrollsOverflow())
+ m_owningLayer.scrollableArea()->positionOverflowControls(IntSize());
+
+ if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
+ updateLayerBlendMode(renderer()->style());
+ updateIsRootForIsolatedGroup();
+ }
+
+ updateContentsRect();
+ updateBackgroundColor();
+ updateDrawsContent();
+ updateContentsOpaque();
+ updateAfterWidgetResize();
+ updateRenderingContext();
+ updateShouldFlattenTransform();
+ updateChildrenTransform();
+ updateScrollParent(compositor()->acceleratedCompositingForOverflowScrollEnabled() ? m_owningLayer.scrollParent() : 0);
+ registerScrollingLayers();
+
+ updateCompositingReasons();
+}
+
+void CompositedLayerMapping::updateMainGraphicsLayerGeometry(const IntRect& relativeCompositingBounds, const IntRect& localCompositingBounds, IntPoint& graphicsLayerParentLocation)
+{
+ m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
+ m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
+
+ FloatSize oldSize = m_graphicsLayer->size();
+ const IntSize& contentsSize = relativeCompositingBounds.size();
+ if (oldSize != contentsSize)
+ m_graphicsLayer->setSize(contentsSize);
+
+ // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
+ // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
+ // non-compositing visible layers.
+ bool contentsVisible = m_owningLayer.hasVisibleContent() || hasVisibleNonCompositingDescendant(&m_owningLayer);
+ if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer()->isVideo()) {
+ HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer()->node());
+ if (mediaElement->isFullscreen())
+ contentsVisible = false;
+ }
+ m_graphicsLayer->setContentsVisible(contentsVisible);
+
+ m_graphicsLayer->setBackfaceVisibility(renderer()->style()->backfaceVisibility() == BackfaceVisibilityVisible);
+}
+
+void CompositedLayerMapping::computeGraphicsLayerParentLocation(const RenderLayer* compositingContainer, const IntRect& ancestorCompositingBounds, IntPoint& graphicsLayerParentLocation)
+{
+ if (compositingContainer && compositingContainer->compositedLayerMapping()->hasClippingLayer()) {
+ // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
+ // position relative to it.
+ IntRect clippingBox = clipBox(toRenderBox(compositingContainer->renderer()));
+ graphicsLayerParentLocation = clippingBox.location() + roundedIntSize(compositingContainer->subpixelAccumulation());
+ } else if (compositingContainer && compositingContainer->compositedLayerMapping()->childTransformLayer()) {
+ // Similarly, if the compositing ancestor has a child transform layer, we parent in that, and therefore
+ // position relative to it. It's already taken into account the contents offset, so we do not need to here.
+ graphicsLayerParentLocation = roundedIntPoint(compositingContainer->subpixelAccumulation());
+ } else if (compositingContainer) {
+ graphicsLayerParentLocation = ancestorCompositingBounds.location();
+ } else {
+ graphicsLayerParentLocation = renderer()->view()->documentRect().location();
+ }
+
+ if (compositingContainer && compositingContainer->needsCompositedScrolling()) {
+ RenderBox* renderBox = toRenderBox(compositingContainer->renderer());
+ IntSize scrollOffset = renderBox->scrolledContentOffset();
+ IntPoint scrollOrigin(renderBox->borderLeft(), renderBox->borderTop());
+ graphicsLayerParentLocation = scrollOrigin - scrollOffset;
+ }
+}
+
+void CompositedLayerMapping::updateAncestorClippingLayerGeometry(const RenderLayer* compositingContainer, const IntPoint& snappedOffsetFromCompositedAncestor, IntPoint& graphicsLayerParentLocation)
+{
+ if (!compositingContainer || !m_ancestorClippingLayer)
+ return;
+
+ // FIXME: this should use cached clip rects, but this sometimes give
+ // inaccurate results (and trips the ASSERTS in RenderLayerClipper).
+ ClipRectsContext clipRectsContext(compositingContainer, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
+ IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer.clipper().backgroundClipRect(clipRectsContext).rect());
+ ASSERT(parentClipRect != PaintInfo::infiniteRect());
+ m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
+ m_ancestorClippingLayer->setSize(parentClipRect.size());
+
+ // backgroundRect is relative to compositingContainer, so subtract snappedOffsetFromCompositedAncestor.X/snappedOffsetFromCompositedAncestor.Y to get back to local coords.
+ m_ancestorClippingLayer->setOffsetFromRenderer(parentClipRect.location() - snappedOffsetFromCompositedAncestor);
+
+ // The primary layer is then parented in, and positioned relative to this clipping layer.
+ graphicsLayerParentLocation = parentClipRect.location();
+}
+
+void CompositedLayerMapping::updateChildContainmentLayerGeometry(const IntRect& clippingBox, const IntRect& localCompositingBounds)
+{
+ if (!m_childContainmentLayer)
+ return;
+
+ m_childContainmentLayer->setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location() + roundedIntSize(m_owningLayer.subpixelAccumulation())));
+ m_childContainmentLayer->setSize(clippingBox.size());
+ m_childContainmentLayer->setOffsetFromRenderer(toIntSize(clippingBox.location()));
+ if (m_childClippingMaskLayer && !m_scrollingLayer && !renderer()->style()->clipPath()) {
+ m_childClippingMaskLayer->setPosition(m_childContainmentLayer->position());
+ m_childClippingMaskLayer->setSize(m_childContainmentLayer->size());
+ m_childClippingMaskLayer->setOffsetFromRenderer(m_childContainmentLayer->offsetFromRenderer());
+ }
+}
+
+void CompositedLayerMapping::updateChildTransformLayerGeometry()
+{
+ if (!m_childTransformLayer)
+ return;
+ const IntRect borderBox = toRenderBox(m_owningLayer.renderer())->pixelSnappedBorderBoxRect();
+ m_childTransformLayer->setSize(borderBox.size());
+ m_childTransformLayer->setPosition(FloatPoint(contentOffsetInCompositingLayer()));
+}
+
+void CompositedLayerMapping::updateMaskLayerGeometry()
+{
+ if (!m_maskLayer)
+ return;
+
+ if (m_maskLayer->size() != m_graphicsLayer->size()) {
+ m_maskLayer->setSize(m_graphicsLayer->size());
+ m_maskLayer->setNeedsDisplay();
+ }
+ m_maskLayer->setPosition(FloatPoint());
+ m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
+}
+
+void CompositedLayerMapping::updateTransformGeometry(const IntPoint& snappedOffsetFromCompositedAncestor, const IntRect& relativeCompositingBounds)
+{
+ if (m_owningLayer.hasTransform()) {
+ const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
+
+ // Get layout bounds in the coords of compositingContainer to match relativeCompositingBounds.
+ IntRect layerBounds = pixelSnappedIntRect(toLayoutPoint(m_owningLayer.subpixelAccumulation()), borderBox.size());
+ layerBounds.moveBy(snappedOffsetFromCompositedAncestor);
+
+ // Update properties that depend on layer dimensions
+ FloatPoint3D transformOrigin = computeTransformOrigin(IntRect(IntPoint(), layerBounds.size()));
+
+ // |transformOrigin| is in the local space of this layer. layerBounds - relativeCompositingBounds converts to the space of the
+ // compositing bounds relative to the composited ancestor. This does not apply to the z direction, since the page is 2D.
+ FloatPoint3D compositedTransformOrigin(
+ layerBounds.x() - relativeCompositingBounds.x() + transformOrigin.x(),
+ layerBounds.y() - relativeCompositingBounds.y() + transformOrigin.y(),
+ transformOrigin.z());
+ m_graphicsLayer->setTransformOrigin(compositedTransformOrigin);
+ } else {
+ FloatPoint3D compositedTransformOrigin(
+ relativeCompositingBounds.width() * 0.5f,
+ relativeCompositingBounds.height() * 0.5f,
+ 0.f);
+ m_graphicsLayer->setTransformOrigin(compositedTransformOrigin);
+ }
+}
+
+void CompositedLayerMapping::updateReflectionLayerGeometry(Vector<RenderLayer*>& layersNeedingPaintInvalidation)
+{
+ if (!m_owningLayer.reflectionInfo() || !m_owningLayer.reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping())
+ return;
+
+ CompositedLayerMappingPtr reflectionCompositedLayerMapping = m_owningLayer.reflectionInfo()->reflectionLayer()->compositedLayerMapping();
+ reflectionCompositedLayerMapping->updateGraphicsLayerGeometry(GraphicsLayerUpdater::ForceUpdate, &m_owningLayer, layersNeedingPaintInvalidation);
+}
+
+void CompositedLayerMapping::updateScrollingLayerGeometry(const IntRect& localCompositingBounds)
+{
+ if (!m_scrollingLayer)
+ return;
+
+ ASSERT(m_scrollingContentsLayer);
+ RenderBox* renderBox = toRenderBox(renderer());
+ IntRect clientBox = enclosingIntRect(renderBox->clientBoxRect());
+
+ IntSize adjustedScrollOffset = m_owningLayer.scrollableArea()->adjustedScrollOffset();
+ m_scrollingLayer->setPosition(FloatPoint(clientBox.location() - localCompositingBounds.location() + roundedIntSize(m_owningLayer.subpixelAccumulation())));
+ m_scrollingLayer->setSize(clientBox.size());
+
+ IntSize oldScrollingLayerOffset = m_scrollingLayer->offsetFromRenderer();
+ m_scrollingLayer->setOffsetFromRenderer(-toIntSize(clientBox.location()));
+
+ if (m_childClippingMaskLayer && !renderer()->style()->clipPath()) {
+ m_childClippingMaskLayer->setPosition(m_scrollingLayer->position());
+ m_childClippingMaskLayer->setSize(m_scrollingLayer->size());
+ m_childClippingMaskLayer->setOffsetFromRenderer(toIntSize(clientBox.location()));
+ }
+
+ bool clientBoxOffsetChanged = oldScrollingLayerOffset != m_scrollingLayer->offsetFromRenderer();
+
+ IntSize scrollSize(renderBox->scrollWidth(), renderBox->scrollHeight());
+ if (scrollSize != m_scrollingContentsLayer->size() || clientBoxOffsetChanged)
+ m_scrollingContentsLayer->setNeedsDisplay();
+
+ IntSize scrollingContentsOffset = toIntSize(clientBox.location() - adjustedScrollOffset);
+ if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size()) {
+ bool coordinatorHandlesOffset = compositor()->scrollingLayerDidChange(&m_owningLayer);
+ m_scrollingContentsLayer->setPosition(coordinatorHandlesOffset ? FloatPoint() : FloatPoint(-adjustedScrollOffset));
+ }
+
+ m_scrollingContentsLayer->setSize(scrollSize);
+ // FIXME: The paint offset and the scroll offset should really be separate concepts.
+ m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
+
+ if (m_foregroundLayer) {
+ if (m_foregroundLayer->size() != m_scrollingContentsLayer->size())
+ m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
+ m_foregroundLayer->setNeedsDisplay();
+ m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
+ }
+
+ updateScrollingBlockSelection();
+}
+
+void CompositedLayerMapping::updateChildClippingMaskLayerGeometry()
+{
+ if (!m_childClippingMaskLayer || !renderer()->style()->clipPath())
+ return;
+ RenderBox* renderBox = toRenderBox(renderer());
+ IntRect clientBox = enclosingIntRect(renderBox->clientBoxRect());
+
+ m_childClippingMaskLayer->setPosition(m_graphicsLayer->position());
+ m_childClippingMaskLayer->setSize(m_graphicsLayer->size());
+ m_childClippingMaskLayer->setOffsetFromRenderer(toIntSize(clientBox.location()));
+
+ // NOTE: also some stuff happening in updateChildContainmentLayerGeometry().
+}
+
+void CompositedLayerMapping::updateForegroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize, const IntRect& clippingBox)
+{
+ if (!m_foregroundLayer)
+ return;
+
+ FloatSize foregroundSize = relativeCompositingBoundsSize;
+ IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
+ m_foregroundLayer->setPosition(FloatPoint());
+
+ if (hasClippingLayer()) {
+ // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
+ // so that it gets correctly sorted with children. In that case, position relative to the clipping layer.
+ foregroundSize = FloatSize(clippingBox.size());
+ foregroundOffset = toIntSize(clippingBox.location());
+ } else if (m_childTransformLayer) {
+ // Things are different if we have a child transform layer rather
+ // than a clipping layer. In this case, we want to actually change
+ // the position of the layer (to compensate for our ancestor
+ // compositing layer's position) rather than leave the position the
+ // same and use offset-from-renderer + size to describe a clipped
+ // "window" onto the clipped layer.
+
+ m_foregroundLayer->setPosition(-m_childTransformLayer->position());
+ }
+
+ if (foregroundSize != m_foregroundLayer->size()) {
+ m_foregroundLayer->setSize(foregroundSize);
+ m_foregroundLayer->setNeedsDisplay();
+ }
+ m_foregroundLayer->setOffsetFromRenderer(foregroundOffset);
+
+ // NOTE: there is some more configuring going on in updateScrollingLayerGeometry().
+}
+
+void CompositedLayerMapping::updateBackgroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize)
+{
+ if (!m_backgroundLayer)
+ return;
+
+ FloatSize backgroundSize = relativeCompositingBoundsSize;
+ if (backgroundLayerPaintsFixedRootBackground()) {
+ FrameView* frameView = toRenderView(renderer())->frameView();
+ backgroundSize = frameView->visibleContentRect().size();
+ }
+ m_backgroundLayer->setPosition(FloatPoint());
+ if (backgroundSize != m_backgroundLayer->size()) {
+ m_backgroundLayer->setSize(backgroundSize);
+ m_backgroundLayer->setNeedsDisplay();
+ }
+ m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
+}
+
+void CompositedLayerMapping::registerScrollingLayers()
+{
+ // Register fixed position layers and their containers with the scrolling coordinator.
+ ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
+ if (!scrollingCoordinator)
+ return;
+
+ scrollingCoordinator->updateLayerPositionConstraint(&m_owningLayer);
+
+ // Page scale is applied as a transform on the root render view layer. Because the scroll
+ // layer is further up in the hierarchy, we need to avoid marking the root render view
+ // layer as a container.
+ bool isContainer = m_owningLayer.hasTransform() && !m_owningLayer.isRootLayer();
+ // FIXME: we should make certain that childForSuperLayers will never be the m_squashingContainmentLayer here
+ scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(localRootForOwningLayer(), isContainer);
+}
+
+void CompositedLayerMapping::updateInternalHierarchy()
+{
+ // m_foregroundLayer has to be inserted in the correct order with child layers,
+ // so it's not inserted here.
+ if (m_ancestorClippingLayer)
+ m_ancestorClippingLayer->removeAllChildren();
+
+ m_graphicsLayer->removeFromParent();
+
+ if (m_ancestorClippingLayer)
+ m_ancestorClippingLayer->addChild(m_graphicsLayer.get());
+
+ if (m_childContainmentLayer)
+ m_graphicsLayer->addChild(m_childContainmentLayer.get());
+ else if (m_childTransformLayer)
+ m_graphicsLayer->addChild(m_childTransformLayer.get());
+
+ if (m_scrollingLayer) {
+ GraphicsLayer* superLayer = m_graphicsLayer.get();
+
+ if (m_childContainmentLayer)
+ superLayer = m_childContainmentLayer.get();
+
+ if (m_childTransformLayer)
+ superLayer = m_childTransformLayer.get();
+
+ superLayer->addChild(m_scrollingLayer.get());
+ }
+
+ // The clip for child layers does not include space for overflow controls, so they exist as
+ // siblings of the clipping layer if we have one. Normal children of this layer are set as
+ // children of the clipping layer.
+ if (m_layerForHorizontalScrollbar)
+ m_graphicsLayer->addChild(m_layerForHorizontalScrollbar.get());
+ if (m_layerForVerticalScrollbar)
+ m_graphicsLayer->addChild(m_layerForVerticalScrollbar.get());
+ if (m_layerForScrollCorner)
+ m_graphicsLayer->addChild(m_layerForScrollCorner.get());
+
+ // The squashing containment layer, if it exists, becomes a no-op parent.
+ if (m_squashingLayer) {
+ ASSERT(compositor()->layerSquashingEnabled());
+ ASSERT((m_ancestorClippingLayer && !m_squashingContainmentLayer) || (!m_ancestorClippingLayer && m_squashingContainmentLayer));
+
+ if (m_squashingContainmentLayer) {
+ m_squashingContainmentLayer->removeAllChildren();
+ m_squashingContainmentLayer->addChild(m_graphicsLayer.get());
+ m_squashingContainmentLayer->addChild(m_squashingLayer.get());
+ } else {
+ // The ancestor clipping layer is already set up and has m_graphicsLayer under it.
+ m_ancestorClippingLayer->addChild(m_squashingLayer.get());
+ }
+ }
+}
+
+void CompositedLayerMapping::updatePaintingPhases()
+{
+ m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
+ if (m_scrollingContentsLayer) {
+ GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
+ if (!m_foregroundLayer)
+ paintPhase |= GraphicsLayerPaintForeground;
+ m_scrollingContentsLayer->setPaintingPhase(paintPhase);
+ m_scrollingBlockSelectionLayer->setPaintingPhase(paintPhase);
+ }
+}
+
+void CompositedLayerMapping::updateContentsRect()
+{
+ m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
+}
+
+void CompositedLayerMapping::updateScrollingBlockSelection()
+{
+ if (!m_scrollingBlockSelectionLayer)
+ return;
+
+ if (!m_scrollingContentsAreEmpty) {
+ // In this case, the selection will be painted directly into m_scrollingContentsLayer.
+ m_scrollingBlockSelectionLayer->setDrawsContent(false);
+ return;
+ }
+
+ const IntRect blockSelectionGapsBounds = m_owningLayer.blockSelectionGapsBounds();
+ const bool shouldDrawContent = !blockSelectionGapsBounds.isEmpty();
+ m_scrollingBlockSelectionLayer->setDrawsContent(shouldDrawContent);
+ if (!shouldDrawContent)
+ return;
+
+ const IntPoint position = blockSelectionGapsBounds.location() + m_owningLayer.scrollableArea()->adjustedScrollOffset();
+ if (m_scrollingBlockSelectionLayer->size() == blockSelectionGapsBounds.size() && m_scrollingBlockSelectionLayer->position() == position)
+ return;
+
+ m_scrollingBlockSelectionLayer->setPosition(position);
+ m_scrollingBlockSelectionLayer->setSize(blockSelectionGapsBounds.size());
+ m_scrollingBlockSelectionLayer->setOffsetFromRenderer(toIntSize(blockSelectionGapsBounds.location()), GraphicsLayer::SetNeedsDisplay);
+}
+
+void CompositedLayerMapping::updateDrawsContent()
+{
+ if (m_scrollingLayer) {
+ // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
+ // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
+ // m_scrollingLayer never has backing store.
+ // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
+ bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasBoxDecorationsOrBackground();
+ m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
+
+ m_scrollingContentsAreEmpty = !m_owningLayer.hasVisibleContent() || !(renderer()->hasBackground() || paintsChildren());
+ m_scrollingContentsLayer->setDrawsContent(!m_scrollingContentsAreEmpty);
+
+ updateScrollingBlockSelection();
+ return;
+ }
+
+ bool hasPaintedContent = containsPaintedContent();
+ if (hasPaintedContent && isAcceleratedCanvas(renderer())) {
+ CanvasRenderingContext* context = toHTMLCanvasElement(renderer()->node())->renderingContext();
+ // Content layer may be null if context is lost.
+ if (blink::WebLayer* contentLayer = context->platformLayer()) {
+ Color bgColor(Color::transparent);
+ if (contentLayerSupportsDirectBackgroundComposition(renderer())) {
+ bgColor = rendererBackgroundColor();
+ hasPaintedContent = false;
+ }
+ contentLayer->setBackgroundColor(bgColor.rgb());
+ }
+ }
+
+ // FIXME: we could refine this to only allocate backings for one of these layers if possible.
+ m_graphicsLayer->setDrawsContent(hasPaintedContent);
+ if (m_foregroundLayer)
+ m_foregroundLayer->setDrawsContent(hasPaintedContent);
+
+ if (m_backgroundLayer)
+ m_backgroundLayer->setDrawsContent(hasPaintedContent);
+}
+
+void CompositedLayerMapping::updateChildrenTransform()
+{
+ if (GraphicsLayer* childTransformLayer = layerForChildrenTransform()) {
+ childTransformLayer->setTransform(owningLayer().perspectiveTransform());
+ childTransformLayer->setTransformOrigin(FloatPoint3D(childTransformLayer->size().width() * 0.5f, childTransformLayer->size().height() * 0.5f, 0.f));
+ bool hasPerspective = false;
+ if (RenderStyle* style = m_owningLayer.renderer()->style())
+ hasPerspective = style->hasPerspective();
+ if (hasPerspective)
+ childTransformLayer->setShouldFlattenTransform(false);
+
+ // Note, if the target is the scrolling layer, we need to ensure that the
+ // scrolling content layer doesn't flatten the transform. (It would be nice
+ // if we could apply transform to the scrolling content layer, but that's
+ // too late, we need the children transform to be applied _before_ the
+ // scrolling offset.)
+ if (childTransformLayer == m_scrollingLayer.get())
+ m_scrollingContentsLayer->setShouldFlattenTransform(false);
+ }
+}
+
+// Return true if the layers changed.
+bool CompositedLayerMapping::updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip)
+{
+ bool layersChanged = false;
+
+ if (needsAncestorClip) {
+ if (!m_ancestorClippingLayer) {
+ m_ancestorClippingLayer = createGraphicsLayer(CompositingReasonLayerForAncestorClip);
+ m_ancestorClippingLayer->setMasksToBounds(true);
+ layersChanged = true;
+ }
+ } else if (m_ancestorClippingLayer) {
+ m_ancestorClippingLayer->removeFromParent();
+ m_ancestorClippingLayer = nullptr;
+ layersChanged = true;
+ }
+
+ if (needsDescendantClip) {
+ // We don't need a child containment layer if we're the main frame render view
+ // layer. It's redundant as the frame clip above us will handle this clipping.
+ if (!m_childContainmentLayer && !m_isMainFrameRenderViewLayer) {
+ m_childContainmentLayer = createGraphicsLayer(CompositingReasonLayerForDescendantClip);
+ m_childContainmentLayer->setMasksToBounds(true);
+ layersChanged = true;
+ }
+ } else if (hasClippingLayer()) {
+ m_childContainmentLayer->removeFromParent();
+ m_childContainmentLayer = nullptr;
+ layersChanged = true;
+ }
+
+ return layersChanged;
+}
+
+bool CompositedLayerMapping::updateChildTransformLayer(bool needsChildTransformLayer)
+{
+ bool layersChanged = false;
+
+ if (needsChildTransformLayer) {
+ if (!m_childTransformLayer) {
+ m_childTransformLayer = createGraphicsLayer(CompositingReasonLayerForPerspective);
+ m_childTransformLayer->setDrawsContent(false);
+ m_childTransformLayer->setShouldFlattenTransform(false);
+ layersChanged = true;
+ }
+ } else if (m_childTransformLayer) {
+ m_childTransformLayer->removeFromParent();
+ m_childTransformLayer = nullptr;
+ layersChanged = true;
+ }
+
+ return layersChanged;
+}
+
+void CompositedLayerMapping::setBackgroundLayerPaintsFixedRootBackground(bool backgroundLayerPaintsFixedRootBackground)
+{
+ m_backgroundLayerPaintsFixedRootBackground = backgroundLayerPaintsFixedRootBackground;
+}
+
+// Only a member function so it can call createGraphicsLayer.
+bool CompositedLayerMapping::toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>& layer, bool needsLayer, CompositingReasons reason)
+{
+ if (needsLayer == !!layer)
+ return false;
+ layer = needsLayer ? createGraphicsLayer(reason) : nullptr;
+ return true;
+}
+
+bool CompositedLayerMapping::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
+{
+ bool horizontalScrollbarLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForHorizontalScrollbar, needsHorizontalScrollbarLayer, CompositingReasonLayerForHorizontalScrollbar);
+ bool verticalScrollbarLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForVerticalScrollbar, needsVerticalScrollbarLayer, CompositingReasonLayerForVerticalScrollbar);
+ bool scrollCornerLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForScrollCorner, needsScrollCornerLayer, CompositingReasonLayerForScrollCorner);
+
+ if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
+ if (horizontalScrollbarLayerChanged)
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer.scrollableArea(), HorizontalScrollbar);
+ if (verticalScrollbarLayerChanged)
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer.scrollableArea(), VerticalScrollbar);
+ }
+
+ return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
+}
+
+void CompositedLayerMapping::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
+{
+ IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer() - roundedIntSize(m_owningLayer.subpixelAccumulation());
+ if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
+ Scrollbar* hBar = m_owningLayer.scrollableArea()->horizontalScrollbar();
+ if (hBar) {
+ layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
+ layer->setSize(hBar->frameRect().size());
+ if (layer->hasContentsLayer())
+ layer->setContentsRect(IntRect(IntPoint(), hBar->frameRect().size()));
+ }
+ layer->setDrawsContent(hBar && !layer->hasContentsLayer());
+ }
+
+ if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
+ Scrollbar* vBar = m_owningLayer.scrollableArea()->verticalScrollbar();
+ if (vBar) {
+ layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
+ layer->setSize(vBar->frameRect().size());
+ if (layer->hasContentsLayer())
+ layer->setContentsRect(IntRect(IntPoint(), vBar->frameRect().size()));
+ }
+ layer->setDrawsContent(vBar && !layer->hasContentsLayer());
+ }
+
+ if (GraphicsLayer* layer = layerForScrollCorner()) {
+ const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollableArea()->scrollCornerAndResizerRect();
+ layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
+ layer->setSize(scrollCornerAndResizer.size());
+ layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
+ }
+}
+
+bool CompositedLayerMapping::hasUnpositionedOverflowControlsLayers() const
+{
+ if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
+ if (!layer->drawsContent())
+ return true;
+ }
+
+ if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
+ if (!layer->drawsContent())
+ return true;
+ }
+
+ if (GraphicsLayer* layer = layerForScrollCorner()) {
+ if (!layer->drawsContent())
+ return true;
+ }
+
+ return false;
+}
+
+enum ApplyToGraphicsLayersModeFlags {
+ ApplyToCoreLayers = (1 << 0),
+ ApplyToSquashingLayer = (1 << 1),
+ ApplyToScrollbarLayers = (1 << 2),
+ ApplyToBackgroundLayer = (1 << 3),
+ ApplyToMaskLayers = (1 << 4),
+ ApplyToContentLayers = (1 << 5),
+ ApplyToAllGraphicsLayers = (ApplyToSquashingLayer | ApplyToScrollbarLayers | ApplyToBackgroundLayer | ApplyToMaskLayers | ApplyToCoreLayers | ApplyToContentLayers)
+};
+typedef unsigned ApplyToGraphicsLayersMode;
+
+template <typename Func>
+static void ApplyToGraphicsLayers(const CompositedLayerMapping* mapping, const Func& f, ApplyToGraphicsLayersMode mode)
+{
+ ASSERT(mode);
+
+ if ((mode & ApplyToCoreLayers) && mapping->squashingContainmentLayer())
+ f(mapping->squashingContainmentLayer());
+ if ((mode & ApplyToCoreLayers) && mapping->childTransformLayer())
+ f(mapping->childTransformLayer());
+ if ((mode & ApplyToCoreLayers) && mapping->ancestorClippingLayer())
+ f(mapping->ancestorClippingLayer());
+ if (((mode & ApplyToCoreLayers) || (mode & ApplyToContentLayers)) && mapping->mainGraphicsLayer())
+ f(mapping->mainGraphicsLayer());
+ if ((mode & ApplyToCoreLayers) && mapping->clippingLayer())
+ f(mapping->clippingLayer());
+ if ((mode & ApplyToCoreLayers) && mapping->scrollingLayer())
+ f(mapping->scrollingLayer());
+ if (((mode & ApplyToCoreLayers) || (mode & ApplyToContentLayers)) && mapping->scrollingContentsLayer())
+ f(mapping->scrollingContentsLayer());
+ if (((mode & ApplyToCoreLayers) || (mode & ApplyToContentLayers)) && mapping->foregroundLayer())
+ f(mapping->foregroundLayer());
+
+ if ((mode & ApplyToSquashingLayer) && mapping->squashingLayer())
+ f(mapping->squashingLayer());
+
+ if (((mode & ApplyToMaskLayers) || (mode & ApplyToContentLayers)) && mapping->maskLayer())
+ f(mapping->maskLayer());
+ if (((mode & ApplyToMaskLayers) || (mode & ApplyToContentLayers)) && mapping->childClippingMaskLayer())
+ f(mapping->childClippingMaskLayer());
+
+ if (((mode & ApplyToBackgroundLayer) || (mode & ApplyToContentLayers)) && mapping->backgroundLayer())
+ f(mapping->backgroundLayer());
+
+ if ((mode & ApplyToScrollbarLayers) && mapping->layerForHorizontalScrollbar())
+ f(mapping->layerForHorizontalScrollbar());
+ if ((mode & ApplyToScrollbarLayers) && mapping->layerForVerticalScrollbar())
+ f(mapping->layerForVerticalScrollbar());
+ if ((mode & ApplyToScrollbarLayers) && mapping->layerForScrollCorner())
+ f(mapping->layerForScrollCorner());
+}
+
+struct UpdateRenderingContextFunctor {
+ void operator() (GraphicsLayer* layer) const { layer->setRenderingContext(renderingContext); }
+ int renderingContext;
+};
+
+void CompositedLayerMapping::updateRenderingContext()
+{
+ // All layers but the squashing layer (which contains 'alien' content) should be included in this
+ // rendering context.
+ int id = 0;
+
+ // NB, it is illegal at this point to query an ancestor's compositing state. Some compositing
+ // reasons depend on the compositing state of ancestors. So if we want a rendering context id
+ // for the context root, we cannot ask for the id of its associated WebLayer now; it may not have
+ // one yet. We could do a second past after doing the compositing updates to get these ids,
+ // but this would actually be harmful. We do not want to attach any semantic meaning to
+ // the context id other than the fact that they group a number of layers together for the
+ // sake of 3d sorting. So instead we will ask the compositor to vend us an arbitrary, but
+ // consistent id.
+ if (RenderLayer* root = m_owningLayer.renderingContextRoot()) {
+ if (Node* node = root->renderer()->node())
+ id = static_cast<int>(WTF::PtrHash<Node*>::hash(node));
+ }
+
+ UpdateRenderingContextFunctor functor = { id };
+ ApplyToGraphicsLayersMode mode = ApplyToAllGraphicsLayers & ~ApplyToSquashingLayer;
+ ApplyToGraphicsLayers<UpdateRenderingContextFunctor>(this, functor, mode);
+}
+
+struct UpdateShouldFlattenTransformFunctor {
+ void operator() (GraphicsLayer* layer) const { layer->setShouldFlattenTransform(shouldFlatten); }
+ bool shouldFlatten;
+};
+
+void CompositedLayerMapping::updateShouldFlattenTransform()
+{
+ // All CLM-managed layers that could affect a descendant layer should update their
+ // should-flatten-transform value (the other layers' transforms don't matter here).
+ UpdateShouldFlattenTransformFunctor functor = { !m_owningLayer.shouldPreserve3D() };
+ ApplyToGraphicsLayersMode mode = ApplyToCoreLayers;
+ ApplyToGraphicsLayers(this, functor, mode);
+}
+
+bool CompositedLayerMapping::updateForegroundLayer(bool needsForegroundLayer)
+{
+ bool layerChanged = false;
+ if (needsForegroundLayer) {
+ if (!m_foregroundLayer) {
+ m_foregroundLayer = createGraphicsLayer(CompositingReasonLayerForForeground);
+ m_foregroundLayer->setDrawsContent(true);
+ m_foregroundLayer->setPaintingPhase(GraphicsLayerPaintForeground);
+ layerChanged = true;
+ }
+ } else if (m_foregroundLayer) {
+ FloatRect repaintRect(FloatPoint(), m_foregroundLayer->size());
+ m_foregroundLayer->removeFromParent();
+ m_foregroundLayer = nullptr;
+ layerChanged = true;
+ }
+
+ return layerChanged;
+}
+
+bool CompositedLayerMapping::updateBackgroundLayer(bool needsBackgroundLayer)
+{
+ bool layerChanged = false;
+ if (needsBackgroundLayer) {
+ if (!m_backgroundLayer) {
+ m_backgroundLayer = createGraphicsLayer(CompositingReasonLayerForBackground);
+ m_backgroundLayer->setDrawsContent(true);
+ m_backgroundLayer->setTransformOrigin(FloatPoint3D());
+ m_backgroundLayer->setPaintingPhase(GraphicsLayerPaintBackground);
+#if !OS(ANDROID)
+ m_backgroundLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
+ m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(false);
+#endif
+ layerChanged = true;
+ }
+ } else {
+ if (m_backgroundLayer) {
+ m_backgroundLayer->removeFromParent();
+ m_backgroundLayer = nullptr;
+#if !OS(ANDROID)
+ m_graphicsLayer->contentLayer()->setDrawCheckerboardForMissingTiles(true);
+#endif
+ layerChanged = true;
+ }
+ }
+
+ if (layerChanged && !m_owningLayer.renderer()->documentBeingDestroyed())
+ compositor()->rootFixedBackgroundsChanged();
+
+ return layerChanged;
+}
+
+bool CompositedLayerMapping::updateMaskLayer(bool needsMaskLayer)
+{
+ bool layerChanged = false;
+ if (needsMaskLayer) {
+ if (!m_maskLayer) {
+ m_maskLayer = createGraphicsLayer(CompositingReasonLayerForMask);
+ m_maskLayer->setDrawsContent(true);
+ m_maskLayer->setPaintingPhase(GraphicsLayerPaintMask);
+ layerChanged = true;
+ }
+ } else if (m_maskLayer) {
+ m_maskLayer = nullptr;
+ layerChanged = true;
+ }
+
+ return layerChanged;
+}
+
+bool CompositedLayerMapping::updateClippingMaskLayers(bool needsChildClippingMaskLayer)
+{
+ bool layerChanged = false;
+ if (needsChildClippingMaskLayer) {
+ if (!m_childClippingMaskLayer) {
+ m_childClippingMaskLayer = createGraphicsLayer(CompositingReasonLayerForClippingMask);
+ m_childClippingMaskLayer->setDrawsContent(true);
+ m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask);
+ layerChanged = true;
+ }
+ } else if (m_childClippingMaskLayer) {
+ m_childClippingMaskLayer = nullptr;
+ layerChanged = true;
+ }
+ return layerChanged;
+}
+
+bool CompositedLayerMapping::updateScrollingLayers(bool needsScrollingLayers)
+{
+ ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer);
+
+ bool layerChanged = false;
+ if (needsScrollingLayers) {
+ if (!m_scrollingLayer) {
+ // Outer layer which corresponds with the scroll view.
+ m_scrollingLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContainer);
+ m_scrollingLayer->setDrawsContent(false);
+ m_scrollingLayer->setMasksToBounds(true);
+
+ // Inner layer which renders the content that scrolls.
+ m_scrollingContentsLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContents);
+ m_scrollingContentsLayer->setDrawsContent(true);
+ m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
+
+ m_scrollingBlockSelectionLayer = createGraphicsLayer(CompositingReasonLayerForScrollingBlockSelection);
+ m_scrollingBlockSelectionLayer->setDrawsContent(true);
+ m_scrollingContentsLayer->addChild(m_scrollingBlockSelectionLayer.get());
+
+ layerChanged = true;
+ if (scrollingCoordinator)
+ scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.scrollableArea());
+ }
+ } else if (m_scrollingLayer) {
+ m_scrollingLayer = nullptr;
+ m_scrollingContentsLayer = nullptr;
+ m_scrollingBlockSelectionLayer = nullptr;
+ layerChanged = true;
+ if (scrollingCoordinator)
+ scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.scrollableArea());
+ }
+
+ return layerChanged;
+}
+
+static void updateScrollParentForGraphicsLayer(GraphicsLayer* layer, GraphicsLayer* topmostLayer, RenderLayer* scrollParent, ScrollingCoordinator* scrollingCoordinator)
+{
+ if (!layer)
+ return;
+
+ // Only the topmost layer has a scroll parent. All other layers have a null scroll parent.
+ if (layer != topmostLayer)
+ scrollParent = 0;
+
+ scrollingCoordinator->updateScrollParentForGraphicsLayer(layer, scrollParent);
+}
+
+void CompositedLayerMapping::updateScrollParent(RenderLayer* scrollParent)
+{
+ if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
+ GraphicsLayer* topmostLayer = childForSuperlayers();
+ updateScrollParentForGraphicsLayer(m_squashingContainmentLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
+ updateScrollParentForGraphicsLayer(m_ancestorClippingLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
+ updateScrollParentForGraphicsLayer(m_graphicsLayer.get(), topmostLayer, scrollParent, scrollingCoordinator);
+ }
+}
+
+void CompositedLayerMapping::updateClipParent(RenderLayer* clipParent)
+{
+ if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer))
+ scrollingCoordinator->updateClipParentForGraphicsLayer(m_graphicsLayer.get(), clipParent);
+}
+
+bool CompositedLayerMapping::updateSquashingLayers(bool needsSquashingLayers)
+{
+ bool layersChanged = false;
+
+ if (needsSquashingLayers) {
+ ASSERT(compositor()->layerSquashingEnabled());
+
+ if (!m_squashingLayer) {
+ m_squashingLayer = createGraphicsLayer(CompositingReasonLayerForSquashingContents);
+ m_squashingLayer->setDrawsContent(true);
+ layersChanged = true;
+ }
+
+ if (m_ancestorClippingLayer) {
+ if (m_squashingContainmentLayer) {
+ m_squashingContainmentLayer->removeFromParent();
+ m_squashingContainmentLayer = nullptr;
+ layersChanged = true;
+ }
+ } else {
+ if (!m_squashingContainmentLayer) {
+ m_squashingContainmentLayer = createGraphicsLayer(CompositingReasonLayerForSquashingContainer);
+ layersChanged = true;
+ }
+ }
+
+ ASSERT((m_ancestorClippingLayer && !m_squashingContainmentLayer) || (!m_ancestorClippingLayer && m_squashingContainmentLayer));
+ ASSERT(m_squashingLayer);
+ } else {
+ if (m_squashingLayer) {
+ m_squashingLayer->removeFromParent();
+ m_squashingLayer = nullptr;
+ layersChanged = true;
+ }
+ if (m_squashingContainmentLayer) {
+ m_squashingContainmentLayer->removeFromParent();
+ m_squashingContainmentLayer = nullptr;
+ layersChanged = true;
+ }
+ ASSERT(!m_squashingLayer && !m_squashingContainmentLayer);
+ }
+
+ return layersChanged;
+}
+
+GraphicsLayerPaintingPhase CompositedLayerMapping::paintingPhaseForPrimaryLayer() const
+{
+ unsigned phase = 0;
+ if (!m_backgroundLayer)
+ phase |= GraphicsLayerPaintBackground;
+ if (!m_foregroundLayer)
+ phase |= GraphicsLayerPaintForeground;
+ if (!m_maskLayer)
+ phase |= GraphicsLayerPaintMask;
+
+ if (m_scrollingContentsLayer) {
+ phase &= ~GraphicsLayerPaintForeground;
+ phase |= GraphicsLayerPaintCompositedScroll;
+ }
+
+ return static_cast<GraphicsLayerPaintingPhase>(phase);
+}
+
+float CompositedLayerMapping::compositingOpacity(float rendererOpacity) const
+{
+ float finalOpacity = rendererOpacity;
+
+ for (RenderLayer* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
+ // We only care about parents that are stacking contexts.
+ // Recall that opacity creates stacking context.
+ if (!curr->stackingNode()->isStackingContext())
+ continue;
+
+ // If we found a composited layer, regardless of whether it actually
+ // paints into it, we want to compute opacity relative to it. So we can
+ // break here.
+ //
+ // FIXME: with grouped backings, a composited descendant will have to
+ // continue past the grouped (squashed) layers that its parents may
+ // contribute to. This whole confusion can be avoided by specifying
+ // explicitly the composited ancestor where we would stop accumulating
+ // opacity.
+ if (curr->compositingState() == PaintsIntoOwnBacking || curr->compositingState() == HasOwnBackingButPaintsIntoAncestor)
+ break;
+
+ finalOpacity *= curr->renderer()->opacity();
+ }
+
+ return finalOpacity;
+}
+
+Color CompositedLayerMapping::rendererBackgroundColor() const
+{
+ RenderObject* backgroundRenderer = renderer();
+ if (backgroundRenderer->isDocumentElement())
+ backgroundRenderer = backgroundRenderer->rendererForRootBackground();
+
+ return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor);
+}
+
+void CompositedLayerMapping::updateBackgroundColor()
+{
+ m_graphicsLayer->setBackgroundColor(rendererBackgroundColor());
+}
+
+bool CompositedLayerMapping::paintsChildren() const
+{
+ if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers())
+ return true;
+
+ if (hasVisibleNonCompositingDescendant(&m_owningLayer))
+ return true;
+
+ return false;
+}
+
+static bool isCompositedPlugin(RenderObject* renderer)
+{
+ return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->requiresAcceleratedCompositing();
+}
+
+bool CompositedLayerMapping::hasVisibleNonCompositingDescendant(RenderLayer* parent)
+{
+ if (!parent->hasVisibleDescendant())
+ return false;
+
+ // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
+ parent->stackingNode()->updateLayerListsIfNeeded();
+
+#if ASSERT_ENABLED
+ LayerListMutationDetector mutationChecker(parent->stackingNode());
+#endif
+
+ RenderLayerStackingNodeIterator normalFlowIterator(*parent->stackingNode(), AllChildren);
+ while (RenderLayerStackingNode* curNode = normalFlowIterator.next()) {
+ RenderLayer* curLayer = curNode->layer();
+ if (curLayer->hasCompositedLayerMapping())
+ continue;
+ if (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer))
+ return true;
+ }
+
+ return false;
+}
+
+bool CompositedLayerMapping::containsPaintedContent() const
+{
+ if (paintsIntoCompositedAncestor() || m_owningLayer.isReflection())
+ return false;
+
+ if (isDirectlyCompositedImage())
+ return false;
+
+ RenderObject* renderObject = renderer();
+ // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
+ // and set background color on the layer in that case, instead of allocating backing store and painting.
+ if (renderObject->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
+ return m_owningLayer.hasBoxDecorationsOrBackground();
+
+ if (m_owningLayer.hasVisibleBoxDecorations())
+ return true;
+
+ if (renderObject->hasMask()) // masks require special treatment
+ return true;
+
+ if (renderObject->isReplaced() && !isCompositedPlugin(renderObject))
+ return true;
+
+ if (renderObject->isRenderRegion())
+ return true;
+
+ if (renderObject->node() && renderObject->node()->isDocumentNode()) {
+ // Look to see if the root object has a non-simple background
+ RenderObject* rootObject = renderObject->document().documentElement() ? renderObject->document().documentElement()->renderer() : 0;
+ // Reject anything that has a border, a border-radius or outline,
+ // or is not a simple background (no background, or solid color).
+ if (rootObject && hasBoxDecorationsOrBackgroundImage(rootObject->style()))
+ return true;
+
+ // Now look at the body's renderer.
+ HTMLElement* body = renderObject->document().body();
+ RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
+ if (bodyObject && hasBoxDecorationsOrBackgroundImage(bodyObject->style()))
+ return true;
+ }
+
+ // FIXME: it's O(n^2). A better solution is needed.
+ return paintsChildren();
+}
+
+// An image can be directly compositing if it's the sole content of the layer, and has no box decorations
+// that require painting. Direct compositing saves backing store.
+bool CompositedLayerMapping::isDirectlyCompositedImage() const
+{
+ RenderObject* renderObject = renderer();
+
+ if (!renderObject->isImage() || m_owningLayer.hasBoxDecorationsOrBackground() || renderObject->hasClip())
+ return false;
+
+ RenderImage* imageRenderer = toRenderImage(renderObject);
+ if (ImageResource* cachedImage = imageRenderer->cachedImage()) {
+ if (!cachedImage->hasImage())
+ return false;
+
+ Image* image = cachedImage->imageForRenderer(imageRenderer);
+ return image->isBitmapImage();
+ }
+
+ return false;
+}
+
+void CompositedLayerMapping::contentChanged(ContentChangeType changeType)
+{
+ if ((changeType == ImageChanged) && isDirectlyCompositedImage()) {
+ updateImageContents();
+ return;
+ }
+
+ if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && isAcceleratedCanvas(renderer())) {
+ m_graphicsLayer->setContentsNeedsDisplay();
+ return;
+ }
+}
+
+void CompositedLayerMapping::updateImageContents()
+{
+ ASSERT(renderer()->isImage());
+ RenderImage* imageRenderer = toRenderImage(renderer());
+
+ ImageResource* cachedImage = imageRenderer->cachedImage();
+ if (!cachedImage)
+ return;
+
+ Image* image = cachedImage->imageForRenderer(imageRenderer);
+ if (!image)
+ return;
+
+ // We have to wait until the image is fully loaded before setting it on the layer.
+ if (!cachedImage->isLoaded())
+ return;
+
+ // This is a no-op if the layer doesn't have an inner layer for the image.
+ m_graphicsLayer->setContentsToImage(image);
+ updateDrawsContent();
+
+ // Image animation is "lazy", in that it automatically stops unless someone is drawing
+ // the image. So we have to kick the animation each time; this has the downside that the
+ // image will keep animating, even if its layer is not visible.
+ image->startAnimation();
+}
+
+FloatPoint3D CompositedLayerMapping::computeTransformOrigin(const IntRect& borderBox) const
+{
+ RenderStyle* style = renderer()->style();
+
+ FloatPoint3D origin;
+ origin.setX(floatValueForLength(style->transformOriginX(), borderBox.width()));
+ origin.setY(floatValueForLength(style->transformOriginY(), borderBox.height()));
+ origin.setZ(style->transformOriginZ());
+
+ return origin;
+}
+
+// Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
+LayoutSize CompositedLayerMapping::contentOffsetInCompositingLayer() const
+{
+ return LayoutSize(-m_compositedBounds.x(), -m_compositedBounds.y());
+}
+
+LayoutRect CompositedLayerMapping::contentsBox() const
+{
+ LayoutRect contentsBox = contentsRect(renderer());
+ contentsBox.move(contentOffsetInCompositingLayer());
+ return contentsBox;
+}
+
+GraphicsLayer* CompositedLayerMapping::parentForSublayers() const
+{
+ if (m_scrollingBlockSelectionLayer)
+ return m_scrollingBlockSelectionLayer.get();
+
+ if (m_scrollingContentsLayer)
+ return m_scrollingContentsLayer.get();
+
+ if (m_childContainmentLayer)
+ return m_childContainmentLayer.get();
+
+ if (m_childTransformLayer)
+ return m_childTransformLayer.get();
+
+ return m_graphicsLayer.get();
+}
+
+GraphicsLayer* CompositedLayerMapping::localRootForOwningLayer() const
+{
+ if (m_ancestorClippingLayer)
+ return m_ancestorClippingLayer.get();
+
+ return m_graphicsLayer.get();
+}
+
+GraphicsLayer* CompositedLayerMapping::childForSuperlayers() const
+{
+ if (m_squashingContainmentLayer)
+ return m_squashingContainmentLayer.get();
+
+ return localRootForOwningLayer();
+}
+
+GraphicsLayer* CompositedLayerMapping::layerForChildrenTransform() const
+{
+ if (GraphicsLayer* clipLayer = clippingLayer())
+ return clipLayer;
+ if (m_scrollingLayer)
+ return m_scrollingLayer.get();
+ return m_childTransformLayer.get();
+}
+
+bool CompositedLayerMapping::updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer* compositingAncestorLayer)
+{
+ unsigned previousRequiresOwnBackingStoreForAncestorReasons = m_requiresOwnBackingStoreForAncestorReasons;
+ bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
+ bool canPaintIntoAncestor = compositingAncestorLayer
+ && (compositingAncestorLayer->compositedLayerMapping()->mainGraphicsLayer()->drawsContent()
+ || compositingAncestorLayer->compositedLayerMapping()->paintsIntoCompositedAncestor());
+ m_requiresOwnBackingStoreForAncestorReasons = !canPaintIntoAncestor;
+
+ if (paintsIntoCompositedAncestor() != previousPaintsIntoCompositedAncestor)
+ paintsIntoCompositedAncestorChanged();
+ return m_requiresOwnBackingStoreForAncestorReasons != previousRequiresOwnBackingStoreForAncestorReasons;
+}
+
+bool CompositedLayerMapping::updateRequiresOwnBackingStoreForIntrinsicReasons()
+{
+ unsigned previousRequiresOwnBackingStoreForIntrinsicReasons = m_requiresOwnBackingStoreForIntrinsicReasons;
+ bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
+ RenderObject* renderer = m_owningLayer.renderer();
+ m_requiresOwnBackingStoreForIntrinsicReasons = m_owningLayer.isRootLayer()
+ || (m_owningLayer.compositingReasons() & CompositingReasonComboReasonsThatRequireOwnBacking)
+ || m_owningLayer.transform()
+ || m_owningLayer.clipsCompositingDescendantsWithBorderRadius() // FIXME: Revisit this if the paintsIntoCompositedAncestor state is removed.
+ || renderer->isTransparent()
+ || renderer->hasMask()
+ || renderer->hasReflection()
+ || renderer->hasFilter();
+
+ if (paintsIntoCompositedAncestor() != previousPaintsIntoCompositedAncestor)
+ paintsIntoCompositedAncestorChanged();
+ return m_requiresOwnBackingStoreForIntrinsicReasons != previousRequiresOwnBackingStoreForIntrinsicReasons;
+}
+
+void CompositedLayerMapping::paintsIntoCompositedAncestorChanged()
+{
+ // The answer to paintsIntoCompositedAncestor() affects cached clip rects, so when
+ // it changes we have to clear clip rects on descendants.
+ m_owningLayer.clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
+ m_owningLayer.repainter().computeRepaintRectsIncludingNonCompositingDescendants();
+
+ compositor()->repaintInCompositedAncestor(&m_owningLayer, compositedBounds());
+}
+
+void CompositedLayerMapping::setBlendMode(blink::WebBlendMode blendMode)
+{
+ if (m_ancestorClippingLayer) {
+ m_ancestorClippingLayer->setBlendMode(blendMode);
+ m_graphicsLayer->setBlendMode(blink::WebBlendModeNormal);
+ } else {
+ m_graphicsLayer->setBlendMode(blendMode);
+ }
+}
+
+GraphicsLayerUpdater::UpdateType CompositedLayerMapping::updateTypeForChildren(GraphicsLayerUpdater::UpdateType updateType) const
+{
+ if (m_pendingUpdateScope >= GraphicsLayerUpdateSubtree)
+ return GraphicsLayerUpdater::ForceUpdate;
+ return updateType;
+}
+
+struct SetContentsNeedsDisplayFunctor {
+ void operator() (GraphicsLayer* layer) const
+ {
+ if (layer->drawsContent())
+ layer->setNeedsDisplay();
+ }
+};
+
+void CompositedLayerMapping::setSquashingContentsNeedDisplay()
+{
+ ApplyToGraphicsLayers(this, SetContentsNeedsDisplayFunctor(), ApplyToSquashingLayer);
+}
+
+void CompositedLayerMapping::setContentsNeedDisplay()
+{
+ // FIXME: need to split out repaints for the background.
+ ASSERT(!paintsIntoCompositedAncestor());
+ ApplyToGraphicsLayers(this, SetContentsNeedsDisplayFunctor(), ApplyToContentLayers);
+}
+
+struct SetContentsNeedsDisplayInRectFunctor {
+ void operator() (GraphicsLayer* layer) const
+ {
+ if (layer->drawsContent()) {
+ IntRect layerDirtyRect = r;
+ layerDirtyRect.move(-layer->offsetFromRenderer());
+ layer->setNeedsDisplayInRect(layerDirtyRect);
+ }
+ }
+
+ IntRect r;
+};
+
+// r is in the coordinate space of the layer's render object
+void CompositedLayerMapping::setContentsNeedDisplayInRect(const IntRect& r)
+{
+ // FIXME: need to split out repaints for the background.
+ ASSERT(!paintsIntoCompositedAncestor());
+ SetContentsNeedsDisplayInRectFunctor functor = { r };
+ ApplyToGraphicsLayers(this, functor, ApplyToContentLayers);
+}
+
+const GraphicsLayerPaintInfo* CompositedLayerMapping::containingSquashedLayer(const RenderObject* renderObject, const Vector<GraphicsLayerPaintInfo>& layers)
+{
+ for (size_t i = 0; i < layers.size(); ++i) {
+ if (renderObject->isDescendantOf(layers[i].renderLayer->renderer())) {
+ return &layers[i];
+ break;
+ }
+ }
+ return 0;
+}
+
+const GraphicsLayerPaintInfo* CompositedLayerMapping::containingSquashedLayer(const RenderObject* renderObject)
+{
+ return CompositedLayerMapping::containingSquashedLayer(renderObject, m_squashedLayers);
+}
+
+IntRect CompositedLayerMapping::localClipRectForSquashedLayer(const RenderLayer& referenceLayer, const GraphicsLayerPaintInfo& paintInfo, const Vector<GraphicsLayerPaintInfo>& layers)
+{
+ const RenderObject* clippingContainer = paintInfo.renderLayer->renderer()->clippingContainer();
+ if (clippingContainer == referenceLayer.renderer()->clippingContainer())
+ return PaintInfo::infiniteRect();
+
+ ASSERT(clippingContainer);
+
+ const GraphicsLayerPaintInfo* ancestorPaintInfo = containingSquashedLayer(clippingContainer, layers);
+ // Must be there, otherwise CompositingLayerAssigner::canSquashIntoCurrentSquashingOwner would have disallowed squashing.
+ ASSERT(ancestorPaintInfo);
+
+ // FIXME: this is a potential performance issue. We shoudl consider caching these clip rects or otherwise optimizing.
+ ClipRectsContext clipRectsContext(ancestorPaintInfo->renderLayer, TemporaryClipRects);
+ IntRect parentClipRect = pixelSnappedIntRect(paintInfo.renderLayer->clipper().backgroundClipRect(clipRectsContext).rect());
+ ASSERT(parentClipRect != PaintInfo::infiniteRect());
+
+ // Convert from ancestor to local coordinates.
+ IntSize ancestorToLocalOffset = paintInfo.offsetFromRenderer - ancestorPaintInfo->offsetFromRenderer;
+ parentClipRect.move(ancestorToLocalOffset);
+ return parentClipRect;
+}
+
+void CompositedLayerMapping::doPaintTask(GraphicsLayerPaintInfo& paintInfo, GraphicsContext* context,
+ const IntRect& clip) // In the coords of rootLayer.
+{
+ if (paintsIntoCompositedAncestor()) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ FontCachePurgePreventer fontCachePurgePreventer;
+
+ PaintLayerFlags paintFlags = 0;
+ if (paintInfo.paintingPhase & GraphicsLayerPaintBackground)
+ paintFlags |= PaintLayerPaintingCompositingBackgroundPhase;
+ if (paintInfo.paintingPhase & GraphicsLayerPaintForeground)
+ paintFlags |= PaintLayerPaintingCompositingForegroundPhase;
+ if (paintInfo.paintingPhase & GraphicsLayerPaintMask)
+ paintFlags |= PaintLayerPaintingCompositingMaskPhase;
+ if (paintInfo.paintingPhase & GraphicsLayerPaintChildClippingMask)
+ paintFlags |= PaintLayerPaintingChildClippingMaskPhase;
+ if (paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents)
+ paintFlags |= PaintLayerPaintingOverflowContents;
+ if (paintInfo.paintingPhase & GraphicsLayerPaintCompositedScroll)
+ paintFlags |= PaintLayerPaintingCompositingScrollingPhase;
+
+ if (paintInfo.isBackgroundLayer)
+ paintFlags |= (PaintLayerPaintingRootBackgroundOnly | PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
+ else if (compositor()->fixedRootBackgroundLayer())
+ paintFlags |= PaintLayerPaintingSkipRootBackground;
+
+ // Note carefully: in theory it is appropriate to invoke context->save() here
+ // and restore the context after painting. For efficiency, we are assuming that
+ // it is equivalent to manually undo this offset translation, which means we are
+ // assuming that the context's space was not affected by the RenderLayer
+ // painting code.
+
+ IntSize offset = paintInfo.offsetFromRenderer;
+ context->translate(-offset.width(), -offset.height());
+
+ // The dirtyRect is in the coords of the painting root.
+ IntRect dirtyRect(clip);
+ dirtyRect.move(offset);
+
+ if (!(paintInfo.paintingPhase & GraphicsLayerPaintOverflowContents)) {
+ LayoutRect bounds = paintInfo.compositedBounds;
+ bounds.move(paintInfo.renderLayer->subpixelAccumulation());
+ dirtyRect.intersect(pixelSnappedIntRect(bounds));
+ } else {
+ dirtyRect.move(roundedIntSize(paintInfo.renderLayer->subpixelAccumulation()));
+ }
+
+#ifndef NDEBUG
+ paintInfo.renderLayer->renderer()->assertSubtreeIsLaidOut();
+#endif
+
+ if (paintInfo.renderLayer->compositingState() != PaintsIntoGroupedBacking) {
+ // FIXME: GraphicsLayers need a way to split for RenderRegions.
+ LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, paintInfo.renderLayer->subpixelAccumulation());
+ paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags);
+
+ ASSERT(!paintInfo.isBackgroundLayer || paintFlags & PaintLayerPaintingRootBackgroundOnly);
+
+ if (paintInfo.renderLayer->containsDirtyOverlayScrollbars())
+ paintInfo.renderLayer->paintLayerContents(context, paintingInfo, paintFlags | PaintLayerPaintingOverlayScrollbars);
+ } else {
+ ASSERT(compositor()->layerSquashingEnabled());
+ LayerPaintingInfo paintingInfo(paintInfo.renderLayer, dirtyRect, PaintBehaviorNormal, paintInfo.renderLayer->subpixelAccumulation());
+
+ // RenderLayer::paintLayer assumes that the caller clips to the passed rect. Squashed layers need to do this clipping in software,
+ // since there is no graphics layer to clip them precisely. Furthermore, in some cases we squash layers that need clipping in software
+ // from clipping ancestors (see CompositedLayerMapping::localClipRectForSquashedLayer()).
+ context->save();
+ dirtyRect.intersect(paintInfo.localClipRectForSquashedLayer);
+ context->clip(dirtyRect);
+ paintInfo.renderLayer->paintLayer(context, paintingInfo, paintFlags);
+ context->restore();
+ }
+
+ ASSERT(!paintInfo.renderLayer->usedTransparency());
+
+ // Manually restore the context to its original state by applying the opposite translation.
+ context->translate(offset.width(), offset.height());
+}
+
+static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
+{
+ if (!scrollbar)
+ return;
+
+ context.save();
+ const IntRect& scrollbarRect = scrollbar->frameRect();
+ context.translate(-scrollbarRect.x(), -scrollbarRect.y());
+ IntRect transformedClip = clip;
+ transformedClip.moveBy(scrollbarRect.location());
+ scrollbar->paint(&context, transformedClip);
+ context.restore();
+}
+
+// Up-call from compositing layer drawing callback.
+void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase paintingPhase, const IntRect& clip)
+{
+ // https://code.google.com/p/chromium/issues/detail?id=343772
+ DisableCompositingQueryAsserts disabler;
+#ifndef NDEBUG
+ // FIXME: once the state machine is ready, this can be removed and we can refer to that instead.
+ if (Page* page = renderer()->frame()->page())
+ page->setIsPainting(true);
+#endif
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Paint", "data", InspectorPaintEvent::data(m_owningLayer.renderer(), clip, graphicsLayer));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing.
+ InspectorInstrumentation::willPaint(m_owningLayer.renderer(), graphicsLayer);
+
+ if (graphicsLayer == m_graphicsLayer.get()
+ || graphicsLayer == m_foregroundLayer.get()
+ || graphicsLayer == m_backgroundLayer.get()
+ || graphicsLayer == m_maskLayer.get()
+ || graphicsLayer == m_childClippingMaskLayer.get()
+ || graphicsLayer == m_scrollingContentsLayer.get()
+ || graphicsLayer == m_scrollingBlockSelectionLayer.get()) {
+
+ GraphicsLayerPaintInfo paintInfo;
+ paintInfo.renderLayer = &m_owningLayer;
+ paintInfo.compositedBounds = compositedBounds();
+ paintInfo.offsetFromRenderer = graphicsLayer->offsetFromRenderer();
+ paintInfo.paintingPhase = paintingPhase;
+ paintInfo.isBackgroundLayer = (graphicsLayer == m_backgroundLayer);
+
+ // We have to use the same root as for hit testing, because both methods can compute and cache clipRects.
+ doPaintTask(paintInfo, &context, clip);
+ } else if (graphicsLayer == m_squashingLayer.get()) {
+ ASSERT(compositor()->layerSquashingEnabled());
+ for (size_t i = 0; i < m_squashedLayers.size(); ++i)
+ doPaintTask(m_squashedLayers[i], &context, clip);
+ } else if (graphicsLayer == layerForHorizontalScrollbar()) {
+ paintScrollbar(m_owningLayer.scrollableArea()->horizontalScrollbar(), context, clip);
+ } else if (graphicsLayer == layerForVerticalScrollbar()) {
+ paintScrollbar(m_owningLayer.scrollableArea()->verticalScrollbar(), context, clip);
+ } else if (graphicsLayer == layerForScrollCorner()) {
+ const IntRect& scrollCornerAndResizer = m_owningLayer.scrollableArea()->scrollCornerAndResizerRect();
+ context.save();
+ context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
+ IntRect transformedClip = clip;
+ transformedClip.moveBy(scrollCornerAndResizer.location());
+ m_owningLayer.scrollableArea()->paintScrollCorner(&context, IntPoint(), transformedClip);
+ m_owningLayer.scrollableArea()->paintResizer(&context, IntPoint(), transformedClip);
+ context.restore();
+ }
+ InspectorInstrumentation::didPaint(m_owningLayer.renderer(), graphicsLayer, &context, clip);
+#ifndef NDEBUG
+ if (Page* page = renderer()->frame()->page())
+ page->setIsPainting(false);
+#endif
+}
+
+bool CompositedLayerMapping::isTrackingRepaints() const
+{
+ GraphicsLayerClient* client = compositor();
+ return client ? client->isTrackingRepaints() : false;
+}
+
+struct CollectTrackedRepaintRectsFunctor {
+ void operator() (GraphicsLayer* layer) const { layer->collectTrackedRepaintRects(*rects); }
+ Vector<FloatRect>* rects;
+};
+
+PassOwnPtr<Vector<FloatRect> > CompositedLayerMapping::collectTrackedRepaintRects() const
+{
+ OwnPtr<Vector<FloatRect> > rects = adoptPtr(new Vector<FloatRect>);
+ CollectTrackedRepaintRectsFunctor functor = { rects.get() };
+ ApplyToGraphicsLayers(this, functor, ApplyToAllGraphicsLayers);
+ return rects.release();
+}
+
+#ifndef NDEBUG
+void CompositedLayerMapping::verifyNotPainting()
+{
+ ASSERT(!renderer()->frame()->page() || !renderer()->frame()->page()->isPainting());
+}
+#endif
+
+void CompositedLayerMapping::notifyAnimationStarted(const GraphicsLayer*, double monotonicTime)
+{
+ renderer()->node()->document().compositorPendingAnimations().notifyCompositorAnimationStarted(monotonicTime);
+}
+
+IntRect CompositedLayerMapping::pixelSnappedCompositedBounds() const
+{
+ LayoutRect bounds = m_compositedBounds;
+ bounds.move(m_owningLayer.subpixelAccumulation());
+ return pixelSnappedIntRect(bounds);
+}
+
+bool CompositedLayerMapping::updateSquashingLayerAssignment(RenderLayer* squashedLayer, const RenderLayer& owningLayer, size_t nextSquashedLayerIndex)
+{
+ ASSERT(compositor()->layerSquashingEnabled());
+
+ GraphicsLayerPaintInfo paintInfo;
+ paintInfo.renderLayer = squashedLayer;
+ // NOTE: composited bounds are updated elsewhere
+ // NOTE: offsetFromRenderer is updated elsewhere
+ paintInfo.paintingPhase = GraphicsLayerPaintAllWithOverflowClip;
+ paintInfo.isBackgroundLayer = false;
+
+ // Change tracking on squashing layers: at the first sign of something changed, just invalidate the layer.
+ // FIXME: Perhaps we can find a tighter more clever mechanism later.
+ bool updatedAssignment = false;
+ if (nextSquashedLayerIndex < m_squashedLayers.size()) {
+ if (!paintInfo.isEquivalentForSquashing(m_squashedLayers[nextSquashedLayerIndex])) {
+ compositor()->repaintOnCompositingChange(squashedLayer);
+ updatedAssignment = true;
+ m_squashedLayers[nextSquashedLayerIndex] = paintInfo;
+ }
+ } else {
+ compositor()->repaintOnCompositingChange(squashedLayer);
+ m_squashedLayers.append(paintInfo);
+ updatedAssignment = true;
+ }
+ squashedLayer->setGroupedMapping(this);
+ return updatedAssignment;
+}
+
+void CompositedLayerMapping::removeRenderLayerFromSquashingGraphicsLayer(const RenderLayer* layer)
+{
+ size_t layerIndex = kNotFound;
+
+ for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
+ if (m_squashedLayers[i].renderLayer == layer) {
+ layerIndex = i;
+ break;
+ }
+ }
+
+ if (layerIndex == kNotFound)
+ return;
+
+ m_squashedLayers.remove(layerIndex);
+}
+
+void CompositedLayerMapping::finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex)
+{
+ ASSERT(compositor()->layerSquashingEnabled());
+
+ // Any additional squashed RenderLayers in the array no longer exist, and removing invalidates the squashingLayer contents.
+ if (nextSquashedLayerIndex < m_squashedLayers.size())
+ m_squashedLayers.remove(nextSquashedLayerIndex, m_squashedLayers.size() - nextSquashedLayerIndex);
+}
+
+String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer)
+{
+ String name;
+ if (graphicsLayer == m_graphicsLayer.get()) {
+ name = m_owningLayer.debugName();
+ } else if (graphicsLayer == m_squashingContainmentLayer.get()) {
+ name = "Squashing Containment Layer";
+ } else if (graphicsLayer == m_squashingLayer.get()) {
+ name = "Squashing Layer";
+ } else if (graphicsLayer == m_ancestorClippingLayer.get()) {
+ name = "Ancestor Clipping Layer";
+ } else if (graphicsLayer == m_foregroundLayer.get()) {
+ name = m_owningLayer.debugName() + " (foreground) Layer";
+ } else if (graphicsLayer == m_backgroundLayer.get()) {
+ name = m_owningLayer.debugName() + " (background) Layer";
+ } else if (graphicsLayer == m_childContainmentLayer.get()) {
+ name = "Child Containment Layer";
+ } else if (graphicsLayer == m_childTransformLayer.get()) {
+ name = "Child Transform Layer";
+ } else if (graphicsLayer == m_maskLayer.get()) {
+ name = "Mask Layer";
+ } else if (graphicsLayer == m_childClippingMaskLayer.get()) {
+ name = "Child Clipping Mask Layer";
+ } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
+ name = "Horizontal Scrollbar Layer";
+ } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
+ name = "Vertical Scrollbar Layer";
+ } else if (graphicsLayer == m_layerForScrollCorner.get()) {
+ name = "Scroll Corner Layer";
+ } else if (graphicsLayer == m_scrollingLayer.get()) {
+ name = "Scrolling Layer";
+ } else if (graphicsLayer == m_scrollingContentsLayer.get()) {
+ name = "Scrolling Contents Layer";
+ } else if (graphicsLayer == m_scrollingBlockSelectionLayer.get()) {
+ name = "Scrolling Block Selection Layer";
+ } else {
+ ASSERT_NOT_REACHED();
+ }
+
+ return name;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.h
new file mode 100644
index 00000000000..22a0d75a125
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.h
@@ -0,0 +1,419 @@
+/*
+ * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CompositedLayerMapping_h
+#define CompositedLayerMapping_h
+
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/compositing/GraphicsLayerUpdater.h"
+#include "platform/geometry/FloatPoint.h"
+#include "platform/geometry/FloatPoint3D.h"
+#include "platform/graphics/GraphicsLayer.h"
+#include "platform/graphics/GraphicsLayerClient.h"
+
+namespace WebCore {
+
+class RenderLayerCompositor;
+
+// A GraphicsLayerPaintInfo contains all the info needed to paint a partial subtree of RenderLayers into a GraphicsLayer.
+struct GraphicsLayerPaintInfo {
+ RenderLayer* renderLayer;
+
+ LayoutRect compositedBounds;
+
+ // The clip rect to apply, in the local coordinate space of the squashed layer, when painting it.
+ IntRect localClipRectForSquashedLayer;
+
+ // Offset describing where this squashed RenderLayer paints into the shared GraphicsLayer backing.
+ IntSize offsetFromRenderer;
+ bool offsetFromRendererSet;
+
+ LayoutSize subpixelAccumulation;
+
+ GraphicsLayerPaintingPhase paintingPhase;
+
+ bool isBackgroundLayer;
+
+ GraphicsLayerPaintInfo() : renderLayer(0), offsetFromRendererSet(false), isBackgroundLayer(false) { }
+
+ bool isEquivalentForSquashing(const GraphicsLayerPaintInfo& other)
+ {
+ // FIXME: offsetFromRenderer and compositedBounds should not be checked here, because
+ // they are not yet fixed at the time this function is used.
+ return renderLayer == other.renderLayer
+ && paintingPhase == other.paintingPhase
+ && isBackgroundLayer == other.isBackgroundLayer;
+ }
+};
+
+enum GraphicsLayerUpdateScope {
+ GraphicsLayerUpdateNone,
+ GraphicsLayerUpdateLocal,
+ GraphicsLayerUpdateSubtree,
+};
+
+// CompositedLayerMapping keeps track of how RenderLayers of the render tree correspond to
+// GraphicsLayers of the composited layer tree. Each instance of CompositedLayerMapping
+// manages a small cluster of GraphicsLayers and the references to which RenderLayers
+// and paint phases contribute to each GraphicsLayer.
+//
+// Currently (Oct. 2013) there is one CompositedLayerMapping for each RenderLayer,
+// but this is likely to evolve soon.
+class CompositedLayerMapping FINAL : public GraphicsLayerClient {
+ WTF_MAKE_NONCOPYABLE(CompositedLayerMapping); WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit CompositedLayerMapping(RenderLayer&);
+ virtual ~CompositedLayerMapping();
+
+ RenderLayer& owningLayer() const { return m_owningLayer; }
+
+ // Returns true if layer configuration changed.
+ bool updateGraphicsLayerConfiguration(GraphicsLayerUpdater::UpdateType);
+ // Update graphics layer position and bounds.
+
+ void updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType, const RenderLayer* compositingContainer, Vector<RenderLayer*>& layersNeedingPaintInvalidation);
+
+ // Update whether layer needs blending.
+ void updateContentsOpaque();
+
+ GraphicsLayer* mainGraphicsLayer() const { return m_graphicsLayer.get(); }
+
+ // Layer to clip children
+ bool hasClippingLayer() const { return m_childContainmentLayer; }
+ GraphicsLayer* clippingLayer() const { return m_childContainmentLayer.get(); }
+
+ // Layer to get clipped by ancestor
+ bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer; }
+ GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer.get(); }
+
+ bool hasContentsLayer() const { return m_foregroundLayer; }
+ GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); }
+
+ GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); }
+ bool backgroundLayerPaintsFixedRootBackground() const { return m_backgroundLayerPaintsFixedRootBackground; }
+
+ bool hasScrollingLayer() const { return m_scrollingLayer; }
+ GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
+ GraphicsLayer* scrollingContentsLayer() const { return m_scrollingContentsLayer.get(); }
+ GraphicsLayer* scrollingBlockSelectionLayer() const { return m_scrollingBlockSelectionLayer.get(); }
+
+ bool hasMaskLayer() const { return m_maskLayer; }
+ GraphicsLayer* maskLayer() const { return m_maskLayer.get(); }
+
+ bool hasChildClippingMaskLayer() const { return m_childClippingMaskLayer; }
+ GraphicsLayer* childClippingMaskLayer() const { return m_childClippingMaskLayer.get(); }
+
+ GraphicsLayer* parentForSublayers() const;
+ GraphicsLayer* childForSuperlayers() const;
+ // localRootForOwningLayer does not include the m_squashingContainmentLayer, which is technically not associated with this CLM's owning layer.
+ GraphicsLayer* localRootForOwningLayer() const;
+
+ GraphicsLayer* childTransformLayer() const { return m_childTransformLayer.get(); }
+
+ GraphicsLayer* squashingContainmentLayer() const { return m_squashingContainmentLayer.get(); }
+ GraphicsLayer* squashingLayer() const { return m_squashingLayer.get(); }
+ // Contains the bottommost layer in the hierarchy that can contain the children transform.
+ GraphicsLayer* layerForChildrenTransform() const;
+
+ // Returns true for a composited layer that has no backing store of its own, so
+ // paints into some ancestor layer.
+ bool paintsIntoCompositedAncestor() const { return !(m_requiresOwnBackingStoreForAncestorReasons || m_requiresOwnBackingStoreForIntrinsicReasons); }
+
+ // Updates whether a backing store is needed based on the layer's compositing ancestor's
+ // properties; returns true if the need for a backing store for ancestor reasons changed.
+ bool updateRequiresOwnBackingStoreForAncestorReasons(const RenderLayer* compositingAncestor);
+
+ // Updates whether a backing store is needed for intrinsic reasons (that is, based on the
+ // layer's own properties or compositing reasons); returns true if the intrinsic need for
+ // a backing store changed.
+ bool updateRequiresOwnBackingStoreForIntrinsicReasons();
+
+ void setSquashingContentsNeedDisplay();
+ void setContentsNeedDisplay();
+ // r is in the coordinate space of the layer's render object
+ void setContentsNeedDisplayInRect(const IntRect&);
+
+ // Notification from the renderer that its content changed.
+ void contentChanged(ContentChangeType);
+
+ LayoutRect compositedBounds() const { return m_compositedBounds; }
+ IntRect pixelSnappedCompositedBounds() const;
+ void updateCompositedBounds(GraphicsLayerUpdater::UpdateType);
+
+ void positionOverflowControlsLayers(const IntSize& offsetFromRoot);
+ bool hasUnpositionedOverflowControlsLayers() const;
+
+ // Returns true if the assignment actually changed the assigned squashing layer.
+ bool updateSquashingLayerAssignment(RenderLayer* squashedLayer, const RenderLayer& owningLayer, size_t nextSquashedLayerIndex);
+ void removeRenderLayerFromSquashingGraphicsLayer(const RenderLayer*);
+
+ void finishAccumulatingSquashingLayers(size_t nextSquashedLayerIndex);
+ void updateRenderingContext();
+ void updateShouldFlattenTransform();
+
+ // GraphicsLayerClient interface
+ virtual void notifyAnimationStarted(const GraphicsLayer*, double monotonicTime) OVERRIDE;
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip) OVERRIDE;
+ virtual bool isTrackingRepaints() const OVERRIDE;
+
+ PassOwnPtr<Vector<FloatRect> > collectTrackedRepaintRects() const;
+
+#ifndef NDEBUG
+ virtual void verifyNotPainting() OVERRIDE;
+#endif
+
+ LayoutRect contentsBox() const;
+
+ GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
+ GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
+ GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
+
+ void updateFilters(const RenderStyle*);
+ bool canCompositeFilters() const { return m_canCompositeFilters; }
+
+ void setBlendMode(blink::WebBlendMode);
+
+ void setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateScope scope) { m_pendingUpdateScope = std::max(static_cast<GraphicsLayerUpdateScope>(m_pendingUpdateScope), scope); }
+ void clearNeedsGraphicsLayerUpdate() { m_pendingUpdateScope = GraphicsLayerUpdateNone; }
+
+ bool shouldUpdateGraphicsLayer(GraphicsLayerUpdater::UpdateType updateType) const { return m_pendingUpdateScope > GraphicsLayerUpdateNone || updateType == GraphicsLayerUpdater::ForceUpdate; }
+ GraphicsLayerUpdater::UpdateType updateTypeForChildren(GraphicsLayerUpdater::UpdateType) const;
+
+#if ASSERT_ENABLED
+ void assertNeedsToUpdateGraphicsLayerBitsCleared() { ASSERT(m_pendingUpdateScope == GraphicsLayerUpdateNone); }
+#endif
+
+ virtual String debugName(const GraphicsLayer*) OVERRIDE;
+
+ LayoutSize contentOffsetInCompositingLayer() const;
+
+ LayoutPoint squashingOffsetFromTransformedAncestor()
+ {
+ return m_squashingLayerOffsetFromTransformedAncestor;
+ }
+
+ // If there is a squashed layer painting into this CLM that is an ancestor of the given RenderObject, return it. Otherwise return 0.
+ const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*);
+
+ void updateScrollingBlockSelection();
+
+private:
+ static const GraphicsLayerPaintInfo* containingSquashedLayer(const RenderObject*, const Vector<GraphicsLayerPaintInfo>& layers);
+
+ // Helper methods to updateGraphicsLayerGeometry:
+ void computeGraphicsLayerParentLocation(const RenderLayer* compositingContainer, const IntRect& ancestorCompositingBounds, IntPoint& graphicsLayerParentLocation);
+ void updateSquashingLayerGeometry(const LayoutPoint& offsetFromCompositedAncestor, const IntPoint& graphicsLayerParentLocation, const RenderLayer& referenceLayer, Vector<GraphicsLayerPaintInfo>& layers, GraphicsLayer*, LayoutPoint* offsetFromTransformedAncestor, Vector<RenderLayer*>& layersNeedingPaintInvalidation);
+ void updateMainGraphicsLayerGeometry(const IntRect& relativeCompositingBounds, const IntRect& localCompositingBounds, IntPoint& graphicsLayerParentLocation);
+ void updateAncestorClippingLayerGeometry(const RenderLayer* compositingContainer, const IntPoint& snappedOffsetFromCompositedAncestor, IntPoint& graphicsLayerParentLocation);
+ void updateChildContainmentLayerGeometry(const IntRect& clippingBox, const IntRect& localCompositingBounds);
+ void updateChildTransformLayerGeometry();
+ void updateMaskLayerGeometry();
+ void updateTransformGeometry(const IntPoint& snappedOffsetFromCompositedAncestor, const IntRect& relativeCompositingBounds);
+ void updateForegroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize, const IntRect& clippingBox);
+ void updateBackgroundLayerGeometry(const FloatSize& relativeCompositingBoundsSize);
+ void updateReflectionLayerGeometry(Vector<RenderLayer*>& layersNeedingPaintInvalidation);
+ void updateScrollingLayerGeometry(const IntRect& localCompositingBounds);
+ void updateChildClippingMaskLayerGeometry();
+
+ void createPrimaryGraphicsLayer();
+ void destroyGraphicsLayers();
+
+ PassOwnPtr<GraphicsLayer> createGraphicsLayer(CompositingReasons);
+ bool toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>&, bool needsLayer, CompositingReasons);
+
+ RenderLayerModelObject* renderer() const { return m_owningLayer.renderer(); }
+ RenderLayerCompositor* compositor() const { return m_owningLayer.compositor(); }
+
+ void updateInternalHierarchy();
+ void updatePaintingPhases();
+ bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
+ bool updateChildTransformLayer(bool needsChildTransformLayer);
+ bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer);
+ bool updateForegroundLayer(bool needsForegroundLayer);
+ bool updateBackgroundLayer(bool needsBackgroundLayer);
+ bool updateMaskLayer(bool needsMaskLayer);
+ bool updateClippingMaskLayers(bool needsChildClippingMaskLayer);
+ bool requiresHorizontalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->horizontalScrollbar(); }
+ bool requiresVerticalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->verticalScrollbar(); }
+ bool requiresScrollCornerLayer() const { return m_owningLayer.scrollableArea() && !m_owningLayer.scrollableArea()->scrollCornerAndResizerRect().isEmpty(); }
+ bool updateScrollingLayers(bool scrollingLayers);
+ void updateScrollParent(RenderLayer*);
+ void updateClipParent(RenderLayer*);
+ bool updateSquashingLayers(bool needsSquashingLayers);
+ void updateDrawsContent();
+ void updateChildrenTransform();
+ void registerScrollingLayers();
+
+ // Also sets subpixelAccumulation on the layer.
+ void computeBoundsOfOwningLayer(const RenderLayer* compositedAncestor, IntRect& localCompositingBounds, IntRect& compositingBoundsRelativeToCompositedAncestor, LayoutPoint& offsetFromCompositedAncestor, IntPoint& snappedOffsetFromCompositedAncestor);
+
+ void setBackgroundLayerPaintsFixedRootBackground(bool);
+
+ GraphicsLayerPaintingPhase paintingPhaseForPrimaryLayer() const;
+
+ // Result is transform origin in pixels.
+ FloatPoint3D computeTransformOrigin(const IntRect& borderBox) const;
+
+ void updateOpacity(const RenderStyle*);
+ void updateTransform(const RenderStyle*);
+ void updateLayerBlendMode(const RenderStyle*);
+ void updateIsRootForIsolatedGroup();
+ // Return the opacity value that this layer should use for compositing.
+ float compositingOpacity(float rendererOpacity) const;
+
+ bool isMainFrameRenderViewLayer() const;
+
+ bool paintsChildren() const;
+
+ // Returns true if this layer has content that needs to be rendered by painting into the backing store.
+ bool containsPaintedContent() const;
+ // Returns true if the RenderLayer just contains an image that we can composite directly.
+ bool isDirectlyCompositedImage() const;
+ void updateImageContents();
+
+ Color rendererBackgroundColor() const;
+ void updateBackgroundColor();
+ void updateContentsRect();
+ void updateAfterWidgetResize();
+ void updateCompositingReasons();
+
+ static bool hasVisibleNonCompositingDescendant(RenderLayer* parent);
+
+ void paintsIntoCompositedAncestorChanged();
+
+ void doPaintTask(GraphicsLayerPaintInfo&, GraphicsContext*, const IntRect& clip);
+
+ // Computes the background clip rect for the given squashed layer, up to any containing layer that is squashed into the
+ // same squashing layer and contains this squashed layer's clipping ancestor.
+ // The clip rect is returned in the coordinate space of the given squashed layer.
+ // If there is no such containing layer, returns the infinite rect.
+ // FIXME: unify this code with the code that sets up m_ancestorClippingLayer. They are doing very similar things.
+ static IntRect localClipRectForSquashedLayer(const RenderLayer& referenceLayer, const GraphicsLayerPaintInfo&, const Vector<GraphicsLayerPaintInfo>& layers);
+
+ RenderLayer& m_owningLayer;
+
+ // The hierarchy of layers that is maintained by the CompositedLayerMapping looks like this:
+ //
+ // + m_ancestorClippingLayer [OPTIONAL]
+ // + m_graphicsLayer
+ // + m_childContainmentLayer [OPTIONAL] <-OR-> m_scrollingLayer [OPTIONAL] <-OR-> m_childTransformLayer
+ // + m_scrollingContentsLayer [Present iff m_scrollingLayer is present]
+ // + m_scrollingBlockSelectionLayer [Present iff m_scrollingLayer is present]
+ //
+ // We need an ancestor clipping layer if our clipping ancestor is not our ancestor in the
+ // clipping tree. Here's what that might look like.
+ //
+ // Let A = the clipping ancestor,
+ // B = the clip descendant, and
+ // SC = the stacking context that is the ancestor of A and B in the stacking tree.
+ //
+ // SC
+ // + A = m_graphicsLayer
+ // | + m_childContainmentLayer
+ // | + ...
+ // ...
+ // |
+ // + B = m_ancestorClippingLayer [+]
+ // + m_graphicsLayer
+ // + ...
+ //
+ // In this case B is clipped by another layer that doesn't happen to be its ancestor: A.
+ // So we create an ancestor clipping layer for B, [+], which ensures that B is clipped
+ // as if it had been A's descendant.
+ OwnPtr<GraphicsLayer> m_ancestorClippingLayer; // Only used if we are clipped by an ancestor which is not a stacking context.
+ OwnPtr<GraphicsLayer> m_graphicsLayer;
+ OwnPtr<GraphicsLayer> m_childContainmentLayer; // Only used if we have clipping on a stacking context with compositing children.
+ OwnPtr<GraphicsLayer> m_childTransformLayer; // Only used if we have perspective and no m_childContainmentLayer.
+ OwnPtr<GraphicsLayer> m_scrollingLayer; // Only used if the layer is using composited scrolling.
+ OwnPtr<GraphicsLayer> m_scrollingContentsLayer; // Only used if the layer is using composited scrolling.
+ OwnPtr<GraphicsLayer> m_scrollingBlockSelectionLayer; // Only used if the layer is using composited scrolling, but has no scrolling contents apart from block selection gaps.
+
+ // This layer is also added to the hierarchy by the RLB, but in a different way than
+ // the layers above. It's added to m_graphicsLayer as its mask layer (naturally) if
+ // we have a mask, and isn't part of the typical hierarchy (it has no children).
+ OwnPtr<GraphicsLayer> m_maskLayer; // Only used if we have a mask.
+ OwnPtr<GraphicsLayer> m_childClippingMaskLayer; // Only used if we have to clip child layers or accelerated contents with border radius or clip-path.
+
+ // There are two other (optional) layers whose painting is managed by the CompositedLayerMapping,
+ // but whose position in the hierarchy is maintained by the RenderLayerCompositor. These
+ // are the foreground and background layers. The foreground layer exists if we have composited
+ // descendants with negative z-order. We need the extra layer in this case because the layer
+ // needs to draw both below (for the background, say) and above (for the normal flow content, say)
+ // the negative z-order descendants and this is impossible with a single layer. The RLC handles
+ // inserting m_foregroundLayer in the correct position in our descendant list for us (right after
+ // the neg z-order dsecendants).
+ //
+ // The background layer is only created if this is the root layer and our background is entirely
+ // fixed. In this case we want to put the background in a separate composited layer so that when
+ // we scroll, we don't have to re-raster the background into position. This layer is also inserted
+ // into the tree by the RLC as it gets a special home. This layer becomes a descendant of the
+ // frame clipping layer. That is:
+ // ...
+ // + frame clipping layer
+ // + m_backgroundLayer
+ // + frame scrolling layer
+ // + root content layer
+ //
+ // With the hierarchy set up like this, the root content layer is able to scroll without affecting
+ // the background layer (or repainting).
+ OwnPtr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately.
+ OwnPtr<GraphicsLayer> m_backgroundLayer; // Only used in cases where we need to draw the background separately.
+
+ OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
+ OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
+ OwnPtr<GraphicsLayer> m_layerForScrollCorner;
+
+ // A squashing CLM has two possible squashing-related structures.
+ //
+ // If m_ancestorClippingLayer is present:
+ //
+ // m_ancestorClippingLayer
+ // + m_graphicsLayer
+ // + m_squashingLayer
+ //
+ // If not:
+ //
+ // m_squashingContainmentLayer
+ // + m_graphicsLayer
+ // + m_squashingLayer
+ OwnPtr<GraphicsLayer> m_squashingContainmentLayer; // Only used if any squashed layers exist and m_squashingContainmentLayer is not present, to contain the squashed layers as siblings to the rest of the GraphicsLayer tree chunk.
+ OwnPtr<GraphicsLayer> m_squashingLayer; // Only used if any squashed layers exist, this is the backing that squashed layers paint into.
+ Vector<GraphicsLayerPaintInfo> m_squashedLayers;
+ LayoutPoint m_squashingLayerOffsetFromTransformedAncestor;
+
+ LayoutRect m_compositedBounds;
+
+ unsigned m_pendingUpdateScope : 2;
+ unsigned m_isMainFrameRenderViewLayer : 1;
+ unsigned m_requiresOwnBackingStoreForIntrinsicReasons : 1;
+ unsigned m_requiresOwnBackingStoreForAncestorReasons : 1;
+ unsigned m_canCompositeFilters : 1;
+ unsigned m_backgroundLayerPaintsFixedRootBackground : 1;
+ unsigned m_scrollingContentsAreEmpty : 1;
+};
+
+} // namespace WebCore
+
+#endif // CompositedLayerMapping_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMappingPtr.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMappingPtr.h
index 27cb68581d5..27cb68581d5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/CompositedLayerMappingPtr.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMappingPtr.h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingInputsUpdater.cpp b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingInputsUpdater.cpp
new file mode 100644
index 00000000000..af8ea1f0973
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingInputsUpdater.cpp
@@ -0,0 +1,94 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/rendering/compositing/CompositingInputsUpdater.h"
+
+#include "core/rendering/RenderBlock.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+
+namespace WebCore {
+
+CompositingInputsUpdater::CompositingInputsUpdater(RenderLayer* rootRenderLayer)
+ : m_geometryMap(UseTransforms)
+ , m_rootRenderLayer(rootRenderLayer)
+{
+ rootRenderLayer->updateDescendantDependentFlags();
+}
+
+CompositingInputsUpdater::~CompositingInputsUpdater()
+{
+}
+
+void CompositingInputsUpdater::update(RenderLayer* layer, UpdateType updateType, AncestorInfo info)
+{
+ if (!layer->childNeedsCompositingInputsUpdate() && updateType != ForceUpdate)
+ return;
+
+ m_geometryMap.pushMappingsToAncestor(layer, layer->parent());
+
+ if (layer->hasCompositedLayerMapping())
+ info.enclosingCompositedLayer = layer;
+
+ if (layer->needsCompositingInputsUpdate()) {
+ if (info.enclosingCompositedLayer)
+ info.enclosingCompositedLayer->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+ updateType = ForceUpdate;
+ }
+
+ if (updateType == ForceUpdate) {
+ RenderLayer::CompositingInputs properties;
+
+ if (!layer->isRootLayer()) {
+ properties.clippedAbsoluteBoundingBox = enclosingIntRect(m_geometryMap.absoluteRect(layer->boundingBoxForCompositingOverlapTest()));
+ // FIXME: Setting the absBounds to 1x1 instead of 0x0 makes very little sense,
+ // but removing this code will make JSGameBench sad.
+ // See https://codereview.chromium.org/13912020/
+ if (properties.clippedAbsoluteBoundingBox.isEmpty())
+ properties.clippedAbsoluteBoundingBox.setSize(IntSize(1, 1));
+
+ IntRect clipRect = pixelSnappedIntRect(layer->clipper().backgroundClipRect(ClipRectsContext(m_rootRenderLayer, AbsoluteClipRects)).rect());
+ properties.clippedAbsoluteBoundingBox.intersect(clipRect);
+
+ const RenderLayer* parent = layer->parent();
+ properties.opacityAncestor = parent->isTransparent() ? parent : parent->compositingInputs().opacityAncestor;
+ properties.transformAncestor = parent->transform() ? parent : parent->compositingInputs().transformAncestor;
+ properties.filterAncestor = parent->hasFilter() ? parent : parent->compositingInputs().filterAncestor;
+
+ if (layer->renderer()->isOutOfFlowPositioned() && info.ancestorScrollingLayer && !layer->subtreeIsInvisible()) {
+ const RenderObject* container = layer->renderer()->containingBlock();
+ const RenderObject* scroller = info.ancestorScrollingLayer->renderer();
+ properties.isUnclippedDescendant = scroller != container && scroller->isDescendantOf(container);
+ }
+ }
+
+ layer->updateCompositingInputs(properties);
+ }
+
+ if (layer->scrollsOverflow())
+ info.ancestorScrollingLayer = layer;
+
+ for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling())
+ update(child, updateType, info);
+
+ m_geometryMap.popMappingsToAncestor(layer->parent());
+
+ layer->clearChildNeedsCompositingInputsUpdate();
+}
+
+#if ASSERT_ENABLED
+
+void CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(RenderLayer* layer)
+{
+ ASSERT(!layer->childNeedsCompositingInputsUpdate());
+ ASSERT(!layer->needsCompositingInputsUpdate());
+
+ for (RenderLayer* child = layer->firstChild(); child; child = child->nextSibling())
+ assertNeedsCompositingInputsUpdateBitsCleared(child);
+}
+
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingInputsUpdater.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingInputsUpdater.h
new file mode 100644
index 00000000000..49086287061
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingInputsUpdater.h
@@ -0,0 +1,49 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CompositingInputsUpdater_h
+#define CompositingInputsUpdater_h
+
+#include "core/rendering/RenderGeometryMap.h"
+
+namespace WebCore {
+
+class RenderLayer;
+
+class CompositingInputsUpdater {
+private:
+ struct AncestorInfo {
+ AncestorInfo()
+ : enclosingCompositedLayer(0)
+ , ancestorScrollingLayer(0)
+ {
+ }
+
+ RenderLayer* enclosingCompositedLayer;
+ RenderLayer* ancestorScrollingLayer;
+ };
+
+public:
+ explicit CompositingInputsUpdater(RenderLayer* rootRenderLayer);
+ ~CompositingInputsUpdater();
+
+ enum UpdateType {
+ DoNotForceUpdate,
+ ForceUpdate,
+ };
+
+ void update(RenderLayer*, UpdateType = DoNotForceUpdate, AncestorInfo = AncestorInfo());
+
+#if ASSERT_ENABLED
+ static void assertNeedsCompositingInputsUpdateBitsCleared(RenderLayer*);
+#endif
+
+private:
+ RenderGeometryMap m_geometryMap;
+ RenderLayer* m_rootRenderLayer;
+};
+
+} // namespace WebCore
+
+#endif // CompositingInputsUpdater_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingLayerAssigner.cpp b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingLayerAssigner.cpp
new file mode 100644
index 00000000000..e3d944fef94
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingLayerAssigner.cpp
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/rendering/compositing/CompositingLayerAssigner.h"
+
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+
+namespace WebCore {
+
+// We will only allow squashing if the bbox-area:squashed-area doesn't exceed
+// the ratio |gSquashingSparsityTolerance|:1.
+static uint64_t gSquashingSparsityTolerance = 6;
+
+CompositingLayerAssigner::CompositingLayerAssigner(RenderLayerCompositor* compositor)
+ : m_compositor(compositor)
+ , m_layerSquashingEnabled(compositor->layerSquashingEnabled())
+{
+}
+
+CompositingLayerAssigner::~CompositingLayerAssigner()
+{
+}
+
+void CompositingLayerAssigner::assign(RenderLayer* updateRoot, bool& layersChanged, Vector<RenderLayer*>& layersNeedingRepaint)
+{
+ SquashingState squashingState;
+ assignLayersToBackingsInternal(updateRoot, squashingState, layersChanged, layersNeedingRepaint);
+ if (squashingState.hasMostRecentMapping)
+ squashingState.mostRecentMapping->finishAccumulatingSquashingLayers(squashingState.nextSquashedLayerIndex);
+}
+
+void CompositingLayerAssigner::SquashingState::updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMapping)
+{
+ // The most recent backing is done accumulating any more squashing layers.
+ if (hasMostRecentMapping)
+ mostRecentMapping->finishAccumulatingSquashingLayers(nextSquashedLayerIndex);
+
+ nextSquashedLayerIndex = 0;
+ boundingRect = IntRect();
+ mostRecentMapping = newCompositedLayerMapping;
+ hasMostRecentMapping = hasNewCompositedLayerMapping;
+ haveAssignedBackingsToEntireSquashingLayerSubtree = false;
+}
+
+bool CompositingLayerAssigner::squashingWouldExceedSparsityTolerance(const RenderLayer* candidate, const CompositingLayerAssigner::SquashingState& squashingState)
+{
+ IntRect bounds = candidate->compositingInputs().clippedAbsoluteBoundingBox;
+ IntRect newBoundingRect = squashingState.boundingRect;
+ newBoundingRect.unite(bounds);
+ const uint64_t newBoundingRectArea = newBoundingRect.size().area();
+ const uint64_t newSquashedArea = squashingState.totalAreaOfSquashedRects + bounds.size().area();
+ return newBoundingRectArea > gSquashingSparsityTolerance * newSquashedArea;
+}
+
+bool CompositingLayerAssigner::needsOwnBacking(const RenderLayer* layer) const
+{
+ if (!m_compositor->canBeComposited(layer))
+ return false;
+
+ // If squashing is disabled, then layers that would have been squashed should just be separately composited.
+ bool needsOwnBackingForDisabledSquashing = !m_layerSquashingEnabled && requiresSquashing(layer->compositingReasons());
+
+ return requiresCompositing(layer->compositingReasons()) || needsOwnBackingForDisabledSquashing || (m_compositor->staleInCompositingMode() && layer->isRootLayer());
+}
+
+CompositingStateTransitionType CompositingLayerAssigner::computeCompositedLayerUpdate(RenderLayer* layer)
+{
+ CompositingStateTransitionType update = NoCompositingStateChange;
+ if (needsOwnBacking(layer)) {
+ if (!layer->hasCompositedLayerMapping()) {
+ update = AllocateOwnCompositedLayerMapping;
+ }
+ } else {
+ if (layer->hasCompositedLayerMapping())
+ update = RemoveOwnCompositedLayerMapping;
+
+ if (m_layerSquashingEnabled) {
+ if (!layer->subtreeIsInvisible() && requiresSquashing(layer->compositingReasons())) {
+ // We can't compute at this time whether the squashing layer update is a no-op,
+ // since that requires walking the render layer tree.
+ update = PutInSquashingLayer;
+ } else if (layer->groupedMapping() || layer->lostGroupedMapping()) {
+ update = RemoveFromSquashingLayer;
+ }
+ }
+ }
+ return update;
+}
+
+CompositingReasons CompositingLayerAssigner::getReasonsPreventingSquashing(const RenderLayer* layer, const CompositingLayerAssigner::SquashingState& squashingState)
+{
+ if (!squashingState.haveAssignedBackingsToEntireSquashingLayerSubtree)
+ return CompositingReasonSquashingWouldBreakPaintOrder;
+
+ // FIXME: this special case for video exists only to deal with corner cases
+ // where a RenderVideo does not report that it needs to be directly composited.
+ // Video does not currently support sharing a backing, but this could be
+ // generalized in the future. The following layout tests fail if we permit the
+ // video to share a backing with other layers.
+ //
+ // compositing/video/video-controls-layer-creation.html
+ // virtual/softwarecompositing/video/video-controls-layer-creation.html
+ if (layer->renderer()->isVideo())
+ return CompositingReasonSquashingVideoIsDisallowed;
+
+ if (squashingWouldExceedSparsityTolerance(layer, squashingState))
+ return CompositingReasonSquashingSparsityExceeded;
+
+ // FIXME: this is not efficient, since it walks up the tree . We should store these values on the CompositingInputsCache.
+ ASSERT(squashingState.hasMostRecentMapping);
+ const RenderLayer& squashingLayer = squashingState.mostRecentMapping->owningLayer();
+
+ if (layer->renderer()->clippingContainer() != squashingLayer.renderer()->clippingContainer()) {
+ if (!squashingLayer.compositedLayerMapping()->containingSquashedLayer(layer->renderer()->clippingContainer()))
+ return CompositingReasonSquashingClippingContainerMismatch;
+ }
+
+ // Composited descendants need to be clipped by a child containment graphics layer, which would not be available if the layer is
+ // squashed (and therefore has no CLM nor a child containment graphics layer).
+ if (m_compositor->clipsCompositingDescendants(layer))
+ return CompositingReasonSquashedLayerClipsCompositingDescendants;
+
+ if (layer->scrollsWithRespectTo(&squashingLayer))
+ return CompositingReasonScrollsWithRespectToSquashingLayer;
+
+ const RenderLayer::CompositingInputs& compositingInputs = layer->compositingInputs();
+ const RenderLayer::CompositingInputs& squashingLayerCompositingInputs = squashingLayer.compositingInputs();
+
+ if (compositingInputs.opacityAncestor != squashingLayerCompositingInputs.opacityAncestor)
+ return CompositingReasonSquashingOpacityAncestorMismatch;
+
+ if (compositingInputs.transformAncestor != squashingLayerCompositingInputs.transformAncestor)
+ return CompositingReasonSquashingTransformAncestorMismatch;
+
+ if (compositingInputs.filterAncestor != squashingLayerCompositingInputs.filterAncestor)
+ return CompositingReasonSquashingFilterAncestorMismatch;
+
+ return CompositingReasonNone;
+}
+
+bool CompositingLayerAssigner::updateSquashingAssignment(RenderLayer* layer, SquashingState& squashingState, const CompositingStateTransitionType compositedLayerUpdate,
+ Vector<RenderLayer*>& layersNeedingRepaint)
+{
+ // NOTE: In the future as we generalize this, the background of this layer may need to be assigned to a different backing than
+ // the squashed RenderLayer's own primary contents. This would happen when we have a composited negative z-index element that needs
+ // to paint on top of the background, but below the layer's main contents. For now, because we always composite layers
+ // when they have a composited negative z-index child, such layers will never need squashing so it is not yet an issue.
+ if (compositedLayerUpdate == PutInSquashingLayer) {
+ // A layer that is squashed with other layers cannot have its own CompositedLayerMapping.
+ ASSERT(!layer->hasCompositedLayerMapping());
+ ASSERT(squashingState.hasMostRecentMapping);
+
+ bool changedSquashingLayer =
+ squashingState.mostRecentMapping->updateSquashingLayerAssignment(layer, squashingState.mostRecentMapping->owningLayer(), squashingState.nextSquashedLayerIndex);
+ if (!changedSquashingLayer)
+ return true;
+
+ // If we've modified the collection of squashed layers, we must update
+ // the graphics layer geometry.
+ squashingState.mostRecentMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+
+ layer->clipper().clearClipRectsIncludingDescendants();
+
+ // Issue a repaint, since |layer| may have been added to an already-existing squashing layer.
+ layersNeedingRepaint.append(layer);
+
+ return true;
+ }
+ if (compositedLayerUpdate == RemoveFromSquashingLayer) {
+ if (layer->groupedMapping()) {
+ // Before removing |layer| from an already-existing squashing layer that may have other content, issue a repaint.
+ m_compositor->repaintOnCompositingChange(layer);
+ layer->groupedMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+ layer->setGroupedMapping(0);
+ }
+
+ // If we need to repaint, do so now that we've removed it from a squashed layer.
+ layersNeedingRepaint.append(layer);
+
+ layer->setLostGroupedMapping(false);
+ return true;
+ }
+
+ return false;
+}
+
+void CompositingLayerAssigner::assignLayersToBackingsForReflectionLayer(RenderLayer* reflectionLayer, bool& layersChanged, Vector<RenderLayer*>& layersNeedingRepaint)
+{
+ CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(reflectionLayer);
+ if (compositedLayerUpdate != NoCompositingStateChange) {
+ layersNeedingRepaint.append(reflectionLayer);
+ layersChanged = true;
+ m_compositor->allocateOrClearCompositedLayerMapping(reflectionLayer, compositedLayerUpdate);
+ }
+ m_compositor->updateDirectCompositingReasons(reflectionLayer);
+ if (reflectionLayer->hasCompositedLayerMapping())
+ reflectionLayer->compositedLayerMapping()->updateGraphicsLayerConfiguration(GraphicsLayerUpdater::ForceUpdate);
+}
+
+void CompositingLayerAssigner::assignLayersToBackingsInternal(RenderLayer* layer, SquashingState& squashingState, bool& layersChanged, Vector<RenderLayer*>& layersNeedingRepaint)
+{
+ if (m_layerSquashingEnabled && requiresSquashing(layer->compositingReasons())) {
+ CompositingReasons reasonsPreventingSquashing = getReasonsPreventingSquashing(layer, squashingState);
+ if (reasonsPreventingSquashing)
+ layer->setCompositingReasons(layer->compositingReasons() | reasonsPreventingSquashing);
+ }
+
+ CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(layer);
+
+ if (m_compositor->allocateOrClearCompositedLayerMapping(layer, compositedLayerUpdate)) {
+ layersNeedingRepaint.append(layer);
+ layersChanged = true;
+ }
+
+ // FIXME: special-casing reflection layers here is not right.
+ if (layer->reflectionInfo())
+ assignLayersToBackingsForReflectionLayer(layer->reflectionInfo()->reflectionLayer(), layersChanged, layersNeedingRepaint);
+
+ // Add this layer to a squashing backing if needed.
+ if (m_layerSquashingEnabled) {
+ if (updateSquashingAssignment(layer, squashingState, compositedLayerUpdate, layersNeedingRepaint))
+ layersChanged = true;
+
+ const bool layerIsSquashed = compositedLayerUpdate == PutInSquashingLayer || (compositedLayerUpdate == NoCompositingStateChange && layer->groupedMapping());
+ if (layerIsSquashed) {
+ squashingState.nextSquashedLayerIndex++;
+ IntRect layerBounds = layer->compositingInputs().clippedAbsoluteBoundingBox;
+ squashingState.totalAreaOfSquashedRects += layerBounds.size().area();
+ squashingState.boundingRect.unite(layerBounds);
+ }
+ }
+
+ if (layer->stackingNode()->isStackingContext()) {
+ RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
+ while (RenderLayerStackingNode* curNode = iterator.next())
+ assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged, layersNeedingRepaint);
+ }
+
+ if (m_layerSquashingEnabled) {
+ // At this point, if the layer is to be "separately" composited, then its backing becomes the most recent in paint-order.
+ if (layer->compositingState() == PaintsIntoOwnBacking || layer->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
+ ASSERT(!requiresSquashing(layer->compositingReasons()));
+ squashingState.updateSquashingStateForNewMapping(layer->compositedLayerMapping(), layer->hasCompositedLayerMapping());
+ }
+ }
+
+ RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
+ while (RenderLayerStackingNode* curNode = iterator.next())
+ assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged, layersNeedingRepaint);
+
+ if (squashingState.hasMostRecentMapping && &squashingState.mostRecentMapping->owningLayer() == layer)
+ squashingState.haveAssignedBackingsToEntireSquashingLayerSubtree = true;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingLayerAssigner.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingLayerAssigner.h
new file mode 100644
index 00000000000..ccc283d3e20
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingLayerAssigner.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CompositingLayerAssigner_h
+#define CompositingLayerAssigner_h
+
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "platform/geometry/IntRect.h"
+#include "platform/geometry/LayoutPoint.h"
+
+namespace WebCore {
+
+class RenderLayer;
+
+class CompositingLayerAssigner {
+public:
+ explicit CompositingLayerAssigner(RenderLayerCompositor*);
+ ~CompositingLayerAssigner();
+
+ void assign(RenderLayer* updateRoot, bool& layersChanged, Vector<RenderLayer*>& layersNeedingRepaint);
+
+ // FIXME: This function should be private. We should remove the one caller
+ // once we've fixed the compositing chicken/egg issues.
+ CompositingStateTransitionType computeCompositedLayerUpdate(RenderLayer*);
+
+private:
+ struct SquashingState {
+ SquashingState()
+ : mostRecentMapping(0)
+ , hasMostRecentMapping(false)
+ , haveAssignedBackingsToEntireSquashingLayerSubtree(false)
+ , nextSquashedLayerIndex(0)
+ , totalAreaOfSquashedRects(0) { }
+
+ void updateSquashingStateForNewMapping(CompositedLayerMappingPtr, bool hasNewCompositedLayerMapping);
+
+ // The most recent composited backing that the layer should squash onto if needed.
+ CompositedLayerMappingPtr mostRecentMapping;
+ bool hasMostRecentMapping;
+
+ // Whether all RenderLayers in the stacking subtree rooted at the most recent mapping's
+ // owning layer have had CompositedLayerMappings assigned. Layers cannot squash into a
+ // CompositedLayerMapping owned by a stacking ancestor, since this changes paint order.
+ bool haveAssignedBackingsToEntireSquashingLayerSubtree;
+
+ // Counter that tracks what index the next RenderLayer would be if it gets squashed to the current squashing layer.
+ size_t nextSquashedLayerIndex;
+
+ // The absolute bounding rect of all the squashed layers.
+ IntRect boundingRect;
+
+ // This is simply the sum of the areas of the squashed rects. This can be very skewed if the rects overlap,
+ // but should be close enough to drive a heuristic.
+ uint64_t totalAreaOfSquashedRects;
+ };
+
+ void assignLayersToBackingsInternal(RenderLayer*, SquashingState&, bool& layersChanged, Vector<RenderLayer*>& layersNeedingRepaint);
+ void assignLayersToBackingsForReflectionLayer(RenderLayer* reflectionLayer, bool& layersChanged, Vector<RenderLayer*>& layersNeedingRepaint);
+ CompositingReasons getReasonsPreventingSquashing(const RenderLayer*, const SquashingState&);
+ bool squashingWouldExceedSparsityTolerance(const RenderLayer* candidate, const SquashingState&);
+ bool updateSquashingAssignment(RenderLayer*, SquashingState&, CompositingStateTransitionType, Vector<RenderLayer*>& layersNeedingRepaint);
+ bool needsOwnBacking(const RenderLayer*) const;
+
+ RenderLayerCompositor* m_compositor;
+ bool m_layerSquashingEnabled;
+};
+
+} // namespace WebCore
+
+#endif // CompositingLayerAssigner_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp
new file mode 100644
index 00000000000..289ba10aed5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp
@@ -0,0 +1,236 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/rendering/compositing/CompositingReasonFinder.h"
+
+#include "core/frame/FrameView.h"
+#include "core/frame/Settings.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+
+namespace WebCore {
+
+CompositingReasonFinder::CompositingReasonFinder(RenderView& renderView)
+ : m_renderView(renderView)
+ , m_compositingTriggers(static_cast<CompositingTriggerFlags>(AllCompositingTriggers))
+{
+ updateTriggers();
+}
+
+void CompositingReasonFinder::updateTriggers()
+{
+ m_compositingTriggers = 0;
+
+ Settings& settings = m_renderView.document().page()->settings();
+ if (settings.acceleratedCompositingForVideoEnabled())
+ m_compositingTriggers |= VideoTrigger;
+ if (settings.acceleratedCompositingForCanvasEnabled())
+ m_compositingTriggers |= CanvasTrigger;
+ if (settings.compositedScrollingForFramesEnabled())
+ m_compositingTriggers |= ScrollableInnerFrameTrigger;
+ if (settings.acceleratedCompositingForFiltersEnabled())
+ m_compositingTriggers |= FilterTrigger;
+
+ // We map both these settings to universal overlow scrolling.
+ // FIXME: Replace these settings with a generic compositing setting for HighDPI.
+ if (settings.acceleratedCompositingForOverflowScrollEnabled() || settings.compositorDrivenAcceleratedScrollingEnabled())
+ m_compositingTriggers |= OverflowScrollTrigger;
+
+ // FIXME: acceleratedCompositingForFixedPositionEnabled should be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
+ // Or the sticky and fixed position elements should be behind different flags.
+ if (settings.acceleratedCompositingForFixedPositionEnabled())
+ m_compositingTriggers |= ViewportConstrainedPositionedTrigger;
+}
+
+bool CompositingReasonFinder::hasOverflowScrollTrigger() const
+{
+ return m_compositingTriggers & OverflowScrollTrigger;
+}
+
+bool CompositingReasonFinder::isMainFrame() const
+{
+ // FIXME: LocalFrame::isMainFrame() is probably better.
+ return !m_renderView.document().ownerElement();
+}
+
+CompositingReasons CompositingReasonFinder::directReasons(const RenderLayer* layer) const
+{
+ CompositingReasons styleReasons = layer->styleDeterminedCompositingReasons();
+ ASSERT(styleDeterminedReasons(layer->renderer()) == styleReasons);
+ return styleReasons | nonStyleDeterminedDirectReasons(layer);
+}
+
+// This information doesn't appear to be incorporated into CompositingReasons.
+bool CompositingReasonFinder::requiresCompositingForScrollableFrame() const
+{
+ // Need this done first to determine overflow.
+ ASSERT(!m_renderView.needsLayout());
+ if (isMainFrame())
+ return false;
+
+ if (!(m_compositingTriggers & ScrollableInnerFrameTrigger))
+ return false;
+
+ return m_renderView.frameView()->isScrollable();
+}
+
+CompositingReasons CompositingReasonFinder::styleDeterminedReasons(RenderObject* renderer) const
+{
+ CompositingReasons directReasons = CompositingReasonNone;
+
+ RenderStyle* style = renderer->style();
+
+ if (requiresCompositingForTransform(renderer))
+ directReasons |= CompositingReason3DTransform;
+
+ if (requiresCompositingForFilters(renderer))
+ directReasons |= CompositingReasonFilters;
+
+ if (style->backfaceVisibility() == BackfaceVisibilityHidden)
+ directReasons |= CompositingReasonBackfaceVisibilityHidden;
+
+ if (requiresCompositingForAnimation(style))
+ directReasons |= CompositingReasonActiveAnimation;
+
+ if (style->hasWillChangeCompositingHint() && !style->subtreeWillChangeContents())
+ directReasons |= CompositingReasonWillChangeCompositingHint;
+
+ ASSERT(!(directReasons & ~CompositingReasonComboAllStyleDeterminedReasons));
+ return directReasons;
+}
+
+bool CompositingReasonFinder::requiresCompositingForTransform(RenderObject* renderer) const
+{
+ // Note that we ask the renderer if it has a transform, because the style may have transforms,
+ // but the renderer may be an inline that doesn't suppport them.
+ return renderer->hasTransform() && renderer->style()->transform().has3DOperation();
+}
+
+bool CompositingReasonFinder::requiresCompositingForFilters(RenderObject* renderer) const
+{
+ if (!(m_compositingTriggers & FilterTrigger))
+ return false;
+
+ return renderer->hasFilter();
+}
+
+CompositingReasons CompositingReasonFinder::nonStyleDeterminedDirectReasons(const RenderLayer* layer) const
+{
+ CompositingReasons directReasons = CompositingReasonNone;
+ RenderObject* renderer = layer->renderer();
+
+ if (hasOverflowScrollTrigger()) {
+ // IsUnclippedDescendant is only actually stale during the chicken/egg code path.
+ // FIXME: Use compositingInputs().isUnclippedDescendant to ASSERT that
+ // this value isn't stale.
+ if (layer->compositingInputs().isUnclippedDescendant)
+ directReasons |= CompositingReasonOutOfFlowClipping;
+
+ if (layer->scrollParent())
+ directReasons |= CompositingReasonOverflowScrollingParent;
+
+ if (layer->needsCompositedScrolling())
+ directReasons |= CompositingReasonOverflowScrollingTouch;
+ }
+
+ if (requiresCompositingForPositionFixed(renderer, layer, 0))
+ directReasons |= CompositingReasonPositionFixed;
+
+ directReasons |= renderer->additionalCompositingReasons(m_compositingTriggers);
+
+ ASSERT(!(directReasons & CompositingReasonComboAllStyleDeterminedReasons));
+ return directReasons;
+}
+
+bool CompositingReasonFinder::requiresCompositingForAnimation(RenderStyle* style) const
+{
+ if (style->subtreeWillChangeContents())
+ return style->isRunningAnimationOnCompositor();
+
+ return style->shouldCompositeForCurrentAnimations();
+}
+
+bool CompositingReasonFinder::requiresCompositingForPositionFixed(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
+{
+ if (!(m_compositingTriggers & ViewportConstrainedPositionedTrigger))
+ return false;
+
+ if (renderer->style()->position() != FixedPosition)
+ return false;
+
+ RenderObject* container = renderer->container();
+ // If the renderer is not hooked up yet then we have to wait until it is.
+ if (!container) {
+ ASSERT(m_renderView.document().lifecycle().state() < DocumentLifecycle::InCompositingUpdate);
+ // FIXME: Remove this and ASSERT(container) once we get rid of the incremental
+ // allocateOrClearCompositedLayerMapping compositing update. This happens when
+ // adding the renderer to the tree because we setStyle before addChild in
+ // createRendererForElementIfNeeded.
+ return false;
+ }
+
+ // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
+ // They will stay fixed wrt the container rather than the enclosing frame.
+ if (container != &m_renderView) {
+ if (viewportConstrainedNotCompositedReason)
+ *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
+ return false;
+ }
+
+ // If the fixed-position element does not have any scrollable ancestor between it and
+ // its container, then we do not need to spend compositor resources for it. Start by
+ // assuming we can opt-out (i.e. no scrollable ancestor), and refine the answer below.
+ bool hasScrollableAncestor = false;
+
+ // The FrameView has the scrollbars associated with the top level viewport, so we have to
+ // check the FrameView in addition to the hierarchy of ancestors.
+ FrameView* frameView = m_renderView.frameView();
+ if (frameView && frameView->isScrollable())
+ hasScrollableAncestor = true;
+
+ RenderLayer* ancestor = layer->parent();
+ while (ancestor && !hasScrollableAncestor) {
+ if (ancestor->scrollsOverflow())
+ hasScrollableAncestor = true;
+ if (ancestor->renderer() == &m_renderView)
+ break;
+ ancestor = ancestor->parent();
+ }
+
+ if (!hasScrollableAncestor) {
+ if (viewportConstrainedNotCompositedReason)
+ *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForUnscrollableAncestors;
+ return false;
+ }
+
+ // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done.
+ // FIXME: Get rid of this codepath once we get rid of the incremental compositing update in RenderLayer::styleChanged.
+ if (m_renderView.document().lifecycle().state() < DocumentLifecycle::LayoutClean)
+ return layer->hasCompositedLayerMapping();
+
+ bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescendant();
+ if (!paintsContent) {
+ if (viewportConstrainedNotCompositedReason)
+ *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent;
+ return false;
+ }
+
+ // Fixed position elements that are invisible in the current view don't get their own layer.
+ if (FrameView* frameView = m_renderView.frameView()) {
+ ASSERT(m_renderView.document().lifecycle().state() == DocumentLifecycle::InCompositingUpdate);
+ LayoutRect viewBounds = frameView->viewportConstrainedVisibleContentRect();
+ LayoutRect layerBounds = layer->boundingBoxForCompositing(layer->compositor()->rootRenderLayer(), RenderLayer::ApplyBoundsChickenEggHacks);
+ if (!viewBounds.intersects(enclosingIntRect(layerBounds))) {
+ if (viewportConstrainedNotCompositedReason)
+ *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.h
new file mode 100644
index 00000000000..dce877b3fee
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.h
@@ -0,0 +1,47 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CompositingReasonFinder_h
+#define CompositingReasonFinder_h
+
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/compositing/CompositingTriggers.h"
+#include "platform/graphics/CompositingReasons.h"
+
+namespace WebCore {
+
+class RenderObject;
+class RenderView;
+
+class CompositingReasonFinder {
+ WTF_MAKE_NONCOPYABLE(CompositingReasonFinder);
+public:
+ explicit CompositingReasonFinder(RenderView&);
+
+ CompositingReasons styleDeterminedReasons(RenderObject*) const;
+ CompositingReasons directReasons(const RenderLayer*) const;
+
+ void updateTriggers();
+
+ bool hasOverflowScrollTrigger() const;
+
+ bool requiresCompositingForScrollableFrame() const;
+ bool requiresCompositingForPositionFixed(RenderObject*, const RenderLayer*, RenderLayer::ViewportConstrainedNotCompositedReason*) const;
+
+private:
+ bool isMainFrame() const;
+
+ CompositingReasons nonStyleDeterminedDirectReasons(const RenderLayer*) const;
+
+ bool requiresCompositingForTransform(RenderObject*) const;
+ bool requiresCompositingForFilters(RenderObject*) const;
+ bool requiresCompositingForAnimation(RenderStyle*) const;
+
+ RenderView& m_renderView;
+ CompositingTriggerFlags m_compositingTriggers;
+};
+
+} // namespace WebCore
+
+#endif // CompositingReasonFinder_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingRequirementsUpdater.cpp b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingRequirementsUpdater.cpp
new file mode 100644
index 00000000000..f44d52d0472
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingRequirementsUpdater.cpp
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/rendering/compositing/CompositingRequirementsUpdater.h"
+
+#include "core/rendering/RenderLayerStackingNode.h"
+#include "core/rendering/RenderLayerStackingNodeIterator.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "platform/TraceEvent.h"
+
+namespace WebCore {
+
+class OverlapMapContainer {
+public:
+ void add(const IntRect& bounds)
+ {
+ m_layerRects.append(bounds);
+ m_boundingBox.unite(bounds);
+ }
+
+ bool overlapsLayers(const IntRect& bounds) const
+ {
+ // Checking with the bounding box will quickly reject cases when
+ // layers are created for lists of items going in one direction and
+ // never overlap with each other.
+ if (!bounds.intersects(m_boundingBox))
+ return false;
+ for (unsigned i = 0; i < m_layerRects.size(); i++) {
+ if (m_layerRects[i].intersects(bounds))
+ return true;
+ }
+ return false;
+ }
+
+ void unite(const OverlapMapContainer& otherContainer)
+ {
+ m_layerRects.appendVector(otherContainer.m_layerRects);
+ m_boundingBox.unite(otherContainer.m_boundingBox);
+ }
+private:
+ Vector<IntRect, 64> m_layerRects;
+ IntRect m_boundingBox;
+};
+
+class CompositingRequirementsUpdater::OverlapMap {
+ WTF_MAKE_NONCOPYABLE(OverlapMap);
+public:
+ OverlapMap()
+ {
+ // Begin by assuming the root layer will be composited so that there
+ // is something on the stack. The root layer should also never get a
+ // finishCurrentOverlapTestingContext() call.
+ beginNewOverlapTestingContext();
+ }
+
+ void add(RenderLayer* layer, const IntRect& bounds)
+ {
+ ASSERT(!layer->isRootLayer());
+ if (bounds.isEmpty())
+ return;
+
+ // Layers do not contribute to overlap immediately--instead, they will
+ // contribute to overlap as soon as they have been recursively processed
+ // and popped off the stack.
+ ASSERT(m_overlapStack.size() >= 2);
+ m_overlapStack[m_overlapStack.size() - 2].add(bounds);
+ }
+
+ bool overlapsLayers(const IntRect& bounds) const
+ {
+ return m_overlapStack.last().overlapsLayers(bounds);
+ }
+
+ void beginNewOverlapTestingContext()
+ {
+ // This effectively creates a new "clean slate" for overlap state.
+ // This is used when we know that a subtree or remaining set of
+ // siblings does not need to check overlap with things behind it.
+ m_overlapStack.append(OverlapMapContainer());
+ }
+
+ void finishCurrentOverlapTestingContext()
+ {
+ // The overlap information on the top of the stack is still necessary
+ // for checking overlap of any layers outside this context that may
+ // overlap things from inside this context. Therefore, we must merge
+ // the information from the top of the stack before popping the stack.
+ //
+ // FIXME: we may be able to avoid this deep copy by rearranging how
+ // overlapMap state is managed.
+ m_overlapStack[m_overlapStack.size() - 2].unite(m_overlapStack.last());
+ m_overlapStack.removeLast();
+ }
+
+private:
+ Vector<OverlapMapContainer> m_overlapStack;
+};
+
+class CompositingRequirementsUpdater::RecursionData {
+public:
+ RecursionData(RenderLayer* compAncestor, bool testOverlap)
+ : m_compositingAncestor(compAncestor)
+ , m_subtreeIsCompositing(false)
+ , m_hasUnisolatedCompositedBlendingDescendant(false)
+ , m_testingOverlap(testOverlap)
+#ifndef NDEBUG
+ , m_depth(0)
+#endif
+ {
+ }
+
+ RecursionData(const RecursionData& other)
+ : m_compositingAncestor(other.m_compositingAncestor)
+ , m_subtreeIsCompositing(other.m_subtreeIsCompositing)
+ , m_hasUnisolatedCompositedBlendingDescendant(other.m_hasUnisolatedCompositedBlendingDescendant)
+ , m_testingOverlap(other.m_testingOverlap)
+#ifndef NDEBUG
+ , m_depth(other.m_depth + 1)
+#endif
+ {
+ }
+
+ RenderLayer* m_compositingAncestor;
+ bool m_subtreeIsCompositing;
+ bool m_hasUnisolatedCompositedBlendingDescendant;
+ bool m_testingOverlap;
+#ifndef NDEBUG
+ int m_depth;
+#endif
+};
+
+static bool requiresCompositingOrSquashing(CompositingReasons reasons)
+{
+#ifndef NDEBUG
+ bool fastAnswer = reasons != CompositingReasonNone;
+ bool slowAnswer = requiresCompositing(reasons) || requiresSquashing(reasons);
+ ASSERT(fastAnswer == slowAnswer);
+#endif
+ return reasons != CompositingReasonNone;
+}
+
+static CompositingReasons subtreeReasonsForCompositing(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants)
+{
+ CompositingReasons subtreeReasons = CompositingReasonNone;
+
+ // FIXME: this seems to be a potentially different layer than the layer for which this was called. May not be an error, but is very confusing.
+ RenderLayer* layer = toRenderBoxModelObject(renderer)->layer();
+
+ // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
+ // via compositing so that they also apply to those composited descdendants.
+ if (hasCompositedDescendants) {
+ if (layer->transform())
+ subtreeReasons |= CompositingReasonTransformWithCompositedDescendants;
+
+ if (layer->shouldIsolateCompositedDescendants()) {
+ ASSERT(layer->stackingNode()->isStackingContext());
+ subtreeReasons |= CompositingReasonIsolateCompositedDescendants;
+ }
+
+ // If the implementation of createsGroup changes, we need to be aware of that in this part of code.
+ ASSERT((renderer->isTransparent() || renderer->hasMask() || renderer->hasFilter() || renderer->hasBlendMode()) == renderer->createsGroup());
+ if (renderer->isTransparent())
+ subtreeReasons |= CompositingReasonOpacityWithCompositedDescendants;
+ if (renderer->hasMask())
+ subtreeReasons |= CompositingReasonMaskWithCompositedDescendants;
+ if (renderer->hasFilter())
+ subtreeReasons |= CompositingReasonFilterWithCompositedDescendants;
+ if (renderer->hasBlendMode())
+ subtreeReasons |= CompositingReasonBlendingWithCompositedDescendants;
+
+ if (renderer->hasReflection())
+ subtreeReasons |= CompositingReasonReflectionWithCompositedDescendants;
+
+ if (renderer->hasClipOrOverflowClip())
+ subtreeReasons |= CompositingReasonClipsCompositingDescendants;
+ }
+
+ // A layer with preserve-3d or perspective only needs to be composited if there are descendant layers that
+ // will be affected by the preserve-3d or perspective.
+ if (has3DTransformedDescendants) {
+ if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D)
+ subtreeReasons |= CompositingReasonPreserve3DWith3DDescendants;
+
+ if (renderer->style()->hasPerspective())
+ subtreeReasons |= CompositingReasonPerspectiveWith3DDescendants;
+ }
+
+ return subtreeReasons;
+}
+
+CompositingRequirementsUpdater::CompositingRequirementsUpdater(RenderView& renderView, CompositingReasonFinder& compositingReasonFinder)
+ : m_renderView(renderView)
+ , m_compositingReasonFinder(compositingReasonFinder)
+{
+}
+
+CompositingRequirementsUpdater::~CompositingRequirementsUpdater()
+{
+}
+
+void CompositingRequirementsUpdater::update(RenderLayer* root)
+{
+ TRACE_EVENT0("blink_rendering", "CompositingRequirementsUpdater::updateRecursive");
+
+ // Go through the layers in presentation order, so that we can compute which RenderLayers need compositing layers.
+ // FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
+ RecursionData recursionData(root, true);
+ OverlapMap overlapTestRequestMap;
+ bool saw3DTransform = false;
+
+ // FIXME: Passing these unclippedDescendants down and keeping track
+ // of them dynamically, we are requiring a full tree walk. This
+ // should be removed as soon as proper overlap testing based on
+ // scrolling and animation bounds is implemented (crbug.com/252472).
+ Vector<RenderLayer*> unclippedDescendants;
+ IntRect absoluteDecendantBoundingBox;
+ updateRecursive(0, root, overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants, absoluteDecendantBoundingBox);
+}
+
+void CompositingRequirementsUpdater::updateRecursive(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap& overlapMap, RecursionData& currentRecursionData, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants, IntRect& absoluteDecendantBoundingBox)
+{
+ RenderLayerCompositor* compositor = m_renderView.compositor();
+
+ layer->stackingNode()->updateLayerListsIfNeeded();
+
+ CompositingReasons reasonsToComposite = CompositingReasonNone;
+ CompositingReasons directReasons = m_compositingReasonFinder.directReasons(layer);
+
+ // Video is special. It's the only RenderLayer type that can both have
+ // RenderLayer children and whose children can't use its backing to render
+ // into. These children (the controls) always need to be promoted into their
+ // own layers to draw on top of the accelerated video.
+ if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_compositingAncestor->renderer()->isVideo())
+ directReasons |= CompositingReasonVideoOverlay;
+
+ if (compositor->canBeComposited(layer))
+ reasonsToComposite |= directReasons;
+
+ // Next, accumulate reasons related to overlap.
+ // If overlap testing is used, this reason will be overridden. If overlap testing is not
+ // used, we must assume we overlap if there is anything composited behind us in paint-order.
+ CompositingReasons overlapCompositingReason = currentRecursionData.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone;
+
+ if (m_renderView.compositor()->acceleratedCompositingForOverflowScrollEnabled()) {
+ Vector<size_t> unclippedDescendantsToRemove;
+ for (size_t i = 0; i < unclippedDescendants.size(); i++) {
+ RenderLayer* unclippedDescendant = unclippedDescendants.at(i);
+ // If we've reached the containing block of one of the unclipped
+ // descendants, that element is no longer relevant to whether or not we
+ // should opt in. Unfortunately we can't easily remove from the list
+ // while we're iterating, so we have to store it for later removal.
+ if (unclippedDescendant->renderer()->containingBlock() == layer->renderer()) {
+ unclippedDescendantsToRemove.append(i);
+ continue;
+ }
+ if (layer->scrollsWithRespectTo(unclippedDescendant))
+ reasonsToComposite |= CompositingReasonAssumedOverlap;
+ }
+
+ // Remove irrelevant unclipped descendants in reverse order so our stored
+ // indices remain valid.
+ for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++)
+ unclippedDescendants.remove(unclippedDescendantsToRemove.at(unclippedDescendantsToRemove.size() - i - 1));
+
+ if (reasonsToComposite & CompositingReasonOutOfFlowClipping)
+ unclippedDescendants.append(layer);
+ }
+
+ const IntRect& absBounds = layer->compositingInputs().clippedAbsoluteBoundingBox;
+ absoluteDecendantBoundingBox = absBounds;
+
+ if (currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons))
+ overlapCompositingReason = overlapMap.overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone;
+
+ reasonsToComposite |= overlapCompositingReason;
+
+ // The children of this layer don't need to composite, unless there is
+ // a compositing layer among them, so start by inheriting the compositing
+ // ancestor with m_subtreeIsCompositing set to false.
+ RecursionData childRecursionData(currentRecursionData);
+ childRecursionData.m_subtreeIsCompositing = false;
+
+ bool willBeCompositedOrSquashed = compositor->canBeComposited(layer) && requiresCompositingOrSquashing(reasonsToComposite);
+ if (willBeCompositedOrSquashed) {
+ // Tell the parent it has compositing descendants.
+ currentRecursionData.m_subtreeIsCompositing = true;
+ // This layer now acts as the ancestor for kids.
+ childRecursionData.m_compositingAncestor = layer;
+
+ // Here we know that all children and the layer's own contents can blindly paint into
+ // this layer's backing, until a descendant is composited. So, we don't need to check
+ // for overlap with anything behind this layer.
+ overlapMap.beginNewOverlapTestingContext();
+ // This layer is going to be composited, so children can safely ignore the fact that there's an
+ // animation running behind this layer, meaning they can rely on the overlap map testing again.
+ childRecursionData.m_testingOverlap = true;
+ }
+
+#if ASSERT_ENABLED
+ LayerListMutationDetector mutationChecker(layer->stackingNode());
+#endif
+
+ bool anyDescendantHas3DTransform = false;
+ bool willHaveForegroundLayer = false;
+
+ if (layer->stackingNode()->isStackingContext()) {
+ RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
+ while (RenderLayerStackingNode* curNode = iterator.next()) {
+ IntRect absoluteChildDecendantBoundingBox;
+ updateRecursive(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChildDecendantBoundingBox);
+ absoluteDecendantBoundingBox.unite(absoluteChildDecendantBoundingBox);
+
+ // If we have to make a layer for this child, make one now so we can have a contents layer
+ // (since we need to ensure that the -ve z-order child renders underneath our contents).
+ if (childRecursionData.m_subtreeIsCompositing) {
+ reasonsToComposite |= CompositingReasonNegativeZIndexChildren;
+
+ if (!willBeCompositedOrSquashed) {
+ // make layer compositing
+ childRecursionData.m_compositingAncestor = layer;
+ overlapMap.beginNewOverlapTestingContext();
+ willBeCompositedOrSquashed = true;
+ willHaveForegroundLayer = true;
+
+ // FIXME: temporary solution for the first negative z-index composited child:
+ // re-compute the absBounds for the child so that we can add the
+ // negative z-index child's bounds to the new overlap context.
+ overlapMap.beginNewOverlapTestingContext();
+ overlapMap.add(curNode->layer(), curNode->layer()->compositingInputs().clippedAbsoluteBoundingBox);
+ overlapMap.finishCurrentOverlapTestingContext();
+ }
+ }
+ }
+ }
+
+ if (willHaveForegroundLayer) {
+ ASSERT(willBeCompositedOrSquashed);
+ // A foreground layer effectively is a new backing for all subsequent children, so
+ // we don't need to test for overlap with anything behind this. So, we can finish
+ // the previous context that was accumulating rects for the negative z-index
+ // children, and start with a fresh new empty context.
+ overlapMap.finishCurrentOverlapTestingContext();
+ overlapMap.beginNewOverlapTestingContext();
+ // This layer is going to be composited, so children can safely ignore the fact that there's an
+ // animation running behind this layer, meaning they can rely on the overlap map testing again
+ childRecursionData.m_testingOverlap = true;
+ }
+
+ RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
+ while (RenderLayerStackingNode* curNode = iterator.next()) {
+ IntRect absoluteChildDecendantBoundingBox;
+ updateRecursive(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChildDecendantBoundingBox);
+ absoluteDecendantBoundingBox.unite(absoluteChildDecendantBoundingBox);
+ }
+
+ // Now that the subtree has been traversed, we can check for compositing reasons that depended on the state of the subtree.
+
+ if (layer->stackingNode()->isStackingContext()) {
+ layer->setShouldIsolateCompositedDescendants(childRecursionData.m_hasUnisolatedCompositedBlendingDescendant);
+ } else {
+ layer->setShouldIsolateCompositedDescendants(false);
+ currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = childRecursionData.m_hasUnisolatedCompositedBlendingDescendant;
+ }
+
+ // Subsequent layers in the parent's stacking context may also need to composite.
+ if (childRecursionData.m_subtreeIsCompositing)
+ currentRecursionData.m_subtreeIsCompositing = true;
+
+ // Set the flag to say that this SC has compositing children.
+ layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing);
+
+ if (layer->isRootLayer()) {
+ // The root layer needs to be composited if anything else in the tree is composited.
+ // Otherwise, we can disable compositing entirely.
+ if (childRecursionData.m_subtreeIsCompositing || requiresCompositingOrSquashing(reasonsToComposite) || compositor->rootShouldAlwaysComposite()) {
+ reasonsToComposite |= CompositingReasonRoot;
+ } else {
+ compositor->setCompositingModeEnabled(false);
+ reasonsToComposite = CompositingReasonNone;
+ }
+ } else {
+ // All layers (even ones that aren't being composited) need to get added to
+ // the overlap map. Layers that are not separately composited will paint into their
+ // compositing ancestor's backing, and so are still considered for overlap.
+ if (childRecursionData.m_compositingAncestor && !childRecursionData.m_compositingAncestor->isRootLayer())
+ overlapMap.add(layer, absBounds);
+
+ // Now check for reasons to become composited that depend on the state of descendant layers.
+ CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(layer->renderer(), childRecursionData.m_subtreeIsCompositing, anyDescendantHas3DTransform);
+ reasonsToComposite |= subtreeCompositingReasons;
+ if (!willBeCompositedOrSquashed && compositor->canBeComposited(layer) && requiresCompositingOrSquashing(subtreeCompositingReasons)) {
+ childRecursionData.m_compositingAncestor = layer;
+ // FIXME: this context push is effectively a no-op but needs to exist for
+ // now, because the code is designed to push overlap information to the
+ // second-from-top context of the stack.
+ overlapMap.beginNewOverlapTestingContext();
+ overlapMap.add(layer, absoluteDecendantBoundingBox);
+ willBeCompositedOrSquashed = true;
+ }
+
+ // If the original layer is composited, the reflection needs to be, too.
+ if (layer->reflectionInfo()) {
+ // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another renderer?
+ RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
+ CompositingReasons reflectionCompositingReason = willBeCompositedOrSquashed ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone;
+ reflectionLayer->setCompositingReasons(reflectionLayer->compositingReasons() | reflectionCompositingReason);
+ }
+
+ if (willBeCompositedOrSquashed && layer->blendInfo().hasBlendMode())
+ currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true;
+
+ // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
+ // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
+ // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
+ bool isCompositedClippingLayer = compositor->canBeComposited(layer) && (reasonsToComposite & CompositingReasonClipsCompositingDescendants);
+ if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) || isRunningAcceleratedTransformAnimation(layer->renderer()))
+ currentRecursionData.m_testingOverlap = false;
+
+ if (childRecursionData.m_compositingAncestor == layer)
+ overlapMap.finishCurrentOverlapTestingContext();
+
+ descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform();
+ }
+
+ // At this point we have finished collecting all reasons to composite this layer.
+ layer->setCompositingReasons(reasonsToComposite);
+
+}
+
+bool CompositingRequirementsUpdater::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
+{
+ return renderer->style()->hasCurrentTransformAnimation();
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingRequirementsUpdater.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingRequirementsUpdater.h
new file mode 100644
index 00000000000..09f219fb002
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingRequirementsUpdater.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CompositingRequirementsUpdater_h
+#define CompositingRequirementsUpdater_h
+
+#include "platform/geometry/IntRect.h"
+#include "platform/graphics/CompositingReasons.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class CompositingReasonFinder;
+class RenderLayer;
+class RenderObject;
+class RenderView;
+
+class CompositingRequirementsUpdater {
+public:
+ CompositingRequirementsUpdater(RenderView&, CompositingReasonFinder&);
+ ~CompositingRequirementsUpdater();
+
+ // Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
+ // For the z-order children of a compositing layer:
+ // If a child layers has a compositing layer, then all subsequent layers must
+ // be compositing in order to render above that layer.
+ //
+ // If a child in the negative z-order list is compositing, then the layer itself
+ // must be compositing so that its contents render over that child.
+ // This implies that its positive z-index children must also be compositing.
+ //
+ void update(RenderLayer* root);
+
+private:
+ class OverlapMap;
+ class RecursionData;
+
+ void updateRecursive(RenderLayer* ancestorLayer, RenderLayer* currentLayer, OverlapMap&, RecursionData&, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants, IntRect& absoluteDecendantBoundingBox);
+ bool isRunningAcceleratedTransformAnimation(RenderObject*) const;
+
+ RenderView& m_renderView;
+ CompositingReasonFinder& m_compositingReasonFinder;
+};
+
+} // namespace WebCore
+
+#endif // CompositingRequirementsUpdater_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/CompositingState.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingState.h
index 3873871f304..3873871f304 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/CompositingState.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingState.h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingTriggers.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingTriggers.h
new file mode 100644
index 00000000000..499718864be
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/CompositingTriggers.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple, Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (C) 2012 Samsung Electronics. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CompositingTriggers_h
+#define CompositingTriggers_h
+
+namespace WebCore {
+
+enum CompositingTrigger {
+ VideoTrigger = 1 << 1,
+ CanvasTrigger = 1 << 3,
+ FilterTrigger = 1 << 5,
+ ScrollableInnerFrameTrigger = 1 << 6,
+ OverflowScrollTrigger = 1 << 7,
+ ViewportConstrainedPositionedTrigger = 1 << 8,
+ AllCompositingTriggers = 0xFFFFFFFF,
+};
+
+typedef unsigned CompositingTriggerFlags;
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerTreeBuilder.cpp b/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerTreeBuilder.cpp
new file mode 100644
index 00000000000..9826be1185e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerTreeBuilder.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/rendering/compositing/GraphicsLayerTreeBuilder.h"
+
+#include "core/html/HTMLMediaElement.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderLayerReflectionInfo.h"
+#include "core/rendering/RenderPart.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+
+namespace WebCore {
+
+GraphicsLayerTreeBuilder::GraphicsLayerTreeBuilder()
+{
+}
+
+GraphicsLayerTreeBuilder::~GraphicsLayerTreeBuilder()
+{
+}
+
+static bool shouldAppendLayer(const RenderLayer& layer)
+{
+ if (!RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
+ return true;
+ Node* node = layer.renderer()->node();
+ if (node && isHTMLMediaElement(*node) && toHTMLMediaElement(node)->isFullscreen())
+ return false;
+ return true;
+}
+
+void GraphicsLayerTreeBuilder::rebuild(RenderLayer& layer, GraphicsLayerVector& childLayersOfEnclosingLayer)
+{
+ // Make the layer compositing if necessary, and set up clipping and content layers.
+ // Note that we can only do work here that is independent of whether the descendant layers
+ // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
+
+ layer.stackingNode()->updateLayerListsIfNeeded();
+
+ const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping();
+ CompositedLayerMappingPtr currentCompositedLayerMapping = layer.compositedLayerMapping();
+
+ // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
+ // Otherwise children continue to append to the child list of the enclosing layer.
+ GraphicsLayerVector layerChildren;
+ GraphicsLayerVector& childList = hasCompositedLayerMapping ? layerChildren : childLayersOfEnclosingLayer;
+
+#if ASSERT_ENABLED
+ LayerListMutationDetector mutationChecker(layer.stackingNode());
+#endif
+
+ if (layer.stackingNode()->isStackingContext()) {
+ RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren);
+ while (RenderLayerStackingNode* curNode = iterator.next())
+ rebuild(*curNode->layer(), childList);
+
+ // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
+ if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
+ childList.append(currentCompositedLayerMapping->foregroundLayer());
+ }
+
+ RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
+ while (RenderLayerStackingNode* curNode = iterator.next())
+ rebuild(*curNode->layer(), childList);
+
+ if (hasCompositedLayerMapping) {
+ bool parented = false;
+ if (layer.renderer()->isRenderPart())
+ parented = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(layer.renderer()));
+
+ if (!parented)
+ currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren);
+
+ // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
+ // Otherwise, the overflow control layers are normal children.
+ if (!currentCompositedLayerMapping->hasClippingLayer() && !currentCompositedLayerMapping->hasScrollingLayer()) {
+ if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForHorizontalScrollbar()) {
+ overflowControlLayer->removeFromParent();
+ currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
+ }
+
+ if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) {
+ overflowControlLayer->removeFromParent();
+ currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
+ }
+
+ if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) {
+ overflowControlLayer->removeFromParent();
+ currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
+ }
+ }
+
+ if (shouldAppendLayer(layer))
+ childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers());
+ }
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerTreeBuilder.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerTreeBuilder.h
new file mode 100644
index 00000000000..4389ebe7f83
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerTreeBuilder.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsLayerTreeBuilder_h
+#define GraphicsLayerTreeBuilder_h
+
+#include "platform/graphics/GraphicsLayer.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class RenderLayer;
+
+class GraphicsLayerTreeBuilder {
+public:
+ GraphicsLayerTreeBuilder();
+ ~GraphicsLayerTreeBuilder();
+
+ void rebuild(RenderLayer&, GraphicsLayerVector& childLayersOfEnclosingLayer);
+};
+
+} // namespace WebCore
+
+#endif // GraphicsLayerTreeBuilder_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp b/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp
new file mode 100644
index 00000000000..ab9428cef19
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/rendering/compositing/GraphicsLayerUpdater.h"
+
+#include "core/html/HTMLMediaElement.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderLayerReflectionInfo.h"
+#include "core/rendering/RenderPart.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+
+namespace WebCore {
+
+GraphicsLayerUpdater::UpdateContext::UpdateContext(const UpdateContext& other, const RenderLayer& layer)
+ : m_compositingStackingContext(other.m_compositingStackingContext)
+ , m_compositingAncestor(other.compositingContainer(layer))
+{
+ CompositingState compositingState = layer.compositingState();
+ if (compositingState != NotComposited && compositingState != PaintsIntoGroupedBacking) {
+ m_compositingAncestor = &layer;
+ if (layer.stackingNode()->isStackingContext())
+ m_compositingStackingContext = &layer;
+ }
+}
+
+const RenderLayer* GraphicsLayerUpdater::UpdateContext::compositingContainer(const RenderLayer& layer) const
+{
+ return layer.stackingNode()->isNormalFlowOnly() ? m_compositingAncestor : m_compositingStackingContext;
+}
+
+GraphicsLayerUpdater::GraphicsLayerUpdater()
+ : m_needsRebuildTree(false)
+{
+}
+
+GraphicsLayerUpdater::~GraphicsLayerUpdater()
+{
+}
+
+void GraphicsLayerUpdater::update(Vector<RenderLayer*>& layersNeedingPaintInvalidation, RenderLayer& layer, UpdateType updateType, const UpdateContext& context)
+{
+ if (layer.hasCompositedLayerMapping()) {
+ CompositedLayerMappingPtr mapping = layer.compositedLayerMapping();
+
+ const RenderLayer* compositingContainer = context.compositingContainer(layer);
+ ASSERT(compositingContainer == layer.ancestorCompositingLayer());
+ if (mapping->updateRequiresOwnBackingStoreForAncestorReasons(compositingContainer))
+ updateType = ForceUpdate;
+
+ // Note carefully: here we assume that the compositing state of all descendants have been updated already,
+ // so it is legitimate to compute and cache the composited bounds for this layer.
+ mapping->updateCompositedBounds(updateType);
+
+ if (RenderLayerReflectionInfo* reflection = layer.reflectionInfo()) {
+ if (reflection->reflectionLayer()->hasCompositedLayerMapping())
+ reflection->reflectionLayer()->compositedLayerMapping()->updateCompositedBounds(ForceUpdate);
+ }
+
+ if (mapping->updateGraphicsLayerConfiguration(updateType))
+ m_needsRebuildTree = true;
+
+ mapping->updateGraphicsLayerGeometry(updateType, compositingContainer, layersNeedingPaintInvalidation);
+
+ updateType = mapping->updateTypeForChildren(updateType);
+ mapping->clearNeedsGraphicsLayerUpdate();
+
+ if (!layer.parent())
+ layer.compositor()->updateRootLayerPosition();
+
+ if (mapping->hasUnpositionedOverflowControlsLayers())
+ layer.scrollableArea()->positionOverflowControls(IntSize());
+ }
+
+ UpdateContext childContext(context, layer);
+ for (RenderLayer* child = layer.firstChild(); child; child = child->nextSibling())
+ update(layersNeedingPaintInvalidation, *child, updateType, childContext);
+}
+
+#if ASSERT_ENABLED
+
+void GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(RenderLayer& layer)
+{
+ if (layer.hasCompositedLayerMapping())
+ layer.compositedLayerMapping()->assertNeedsToUpdateGraphicsLayerBitsCleared();
+
+ for (RenderLayer* child = layer.firstChild(); child; child = child->nextSibling())
+ assertNeedsToUpdateGraphicsLayerBitsCleared(*child);
+}
+
+#endif
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.h
new file mode 100644
index 00000000000..df992fa91a1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsLayerUpdater_h
+#define GraphicsLayerUpdater_h
+
+#include "platform/graphics/GraphicsLayer.h"
+
+namespace WebCore {
+
+class RenderLayer;
+
+class GraphicsLayerUpdater {
+ class UpdateContext {
+ public:
+ UpdateContext()
+ : m_compositingStackingContext(0)
+ , m_compositingAncestor(0)
+ {
+ }
+
+ UpdateContext(const UpdateContext&, const RenderLayer&);
+
+ const RenderLayer* compositingContainer(const RenderLayer&) const;
+ private:
+ const RenderLayer* m_compositingStackingContext;
+ const RenderLayer* m_compositingAncestor;
+ };
+
+public:
+ GraphicsLayerUpdater();
+ ~GraphicsLayerUpdater();
+
+ enum UpdateType {
+ DoNotForceUpdate,
+ ForceUpdate,
+ };
+
+ void update(Vector<RenderLayer*>& layersNeedingPaintInvalidation, RenderLayer&, UpdateType = DoNotForceUpdate, const UpdateContext& = UpdateContext());
+ void rebuildTree(RenderLayer&, GraphicsLayerVector& childLayersOfEnclosingLayer);
+
+ bool needsRebuildTree() const { return m_needsRebuildTree; }
+
+#if ASSERT_ENABLED
+ static void assertNeedsToUpdateGraphicsLayerBitsCleared(RenderLayer&);
+#endif
+
+private:
+ bool m_needsRebuildTree;
+};
+
+} // namespace WebCore
+
+#endif // GraphicsLayerUpdater_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp b/chromium/third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp
new file mode 100644
index 00000000000..5d35300f2a7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp
@@ -0,0 +1,1259 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+
+#include "core/animation/DocumentAnimations.h"
+#include "core/dom/FullscreenElementStack.h"
+#include "core/dom/ScriptForbiddenScope.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLIFrameElement.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorNodeIds.h"
+#include "core/page/Chrome.h"
+#include "core/page/Page.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "core/rendering/RenderLayerStackingNode.h"
+#include "core/rendering/RenderLayerStackingNodeIterator.h"
+#include "core/rendering/RenderVideo.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/CompositingInputsUpdater.h"
+#include "core/rendering/compositing/CompositingLayerAssigner.h"
+#include "core/rendering/compositing/CompositingRequirementsUpdater.h"
+#include "core/rendering/compositing/GraphicsLayerTreeBuilder.h"
+#include "core/rendering/compositing/GraphicsLayerUpdater.h"
+#include "platform/OverscrollTheme.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "platform/TraceEvent.h"
+#include "platform/graphics/GraphicsLayer.h"
+#include "public/platform/Platform.h"
+
+namespace WebCore {
+
+RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
+ : m_renderView(renderView)
+ , m_compositingReasonFinder(renderView)
+ , m_pendingUpdateType(CompositingUpdateNone)
+ , m_hasAcceleratedCompositing(true)
+ , m_compositing(false)
+ , m_rootShouldAlwaysCompositeDirty(true)
+ , m_needsUpdateFixedBackground(false)
+ , m_isTrackingRepaints(false)
+ , m_rootLayerAttachment(RootLayerUnattached)
+ , m_inOverlayFullscreenVideo(false)
+{
+ updateAcceleratedCompositingSettings();
+}
+
+RenderLayerCompositor::~RenderLayerCompositor()
+{
+ ASSERT(m_rootLayerAttachment == RootLayerUnattached);
+}
+
+bool RenderLayerCompositor::inCompositingMode() const
+{
+ // FIXME: This should assert that lificycle is >= CompositingClean since
+ // the last step of updateIfNeeded can set this bit to false.
+ ASSERT(!m_rootShouldAlwaysCompositeDirty);
+ return m_compositing;
+}
+
+bool RenderLayerCompositor::staleInCompositingMode() const
+{
+ return m_compositing;
+}
+
+void RenderLayerCompositor::setCompositingModeEnabled(bool enable)
+{
+ if (enable == m_compositing)
+ return;
+
+ m_compositing = enable;
+
+ // RenderPart::requiresAcceleratedCompositing is used to determine self-paintingness
+ // and bases it's return value for frames on the m_compositing bit here.
+ if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) {
+ if (RenderPart* renderer = ownerElement->renderPart())
+ renderer->layer()->updateSelfPaintingLayer();
+ }
+
+ if (m_compositing)
+ ensureRootLayer();
+ else
+ destroyRootLayer();
+
+ // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
+ // we need to schedule a style recalc in our parent document.
+ if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
+ ownerElement->setNeedsCompositingUpdate();
+}
+
+void RenderLayerCompositor::enableCompositingModeIfNeeded()
+{
+ if (!m_rootShouldAlwaysCompositeDirty)
+ return;
+
+ m_rootShouldAlwaysCompositeDirty = false;
+ if (m_compositing)
+ return;
+
+ if (rootShouldAlwaysComposite()) {
+ // FIXME: Is this needed? It was added in https://bugs.webkit.org/show_bug.cgi?id=26651.
+ // No tests fail if it's deleted.
+ setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
+ setCompositingModeEnabled(true);
+ }
+}
+
+bool RenderLayerCompositor::rootShouldAlwaysComposite() const
+{
+ if (!m_hasAcceleratedCompositing)
+ return false;
+ return m_renderView.frame()->isMainFrame() || m_compositingReasonFinder.requiresCompositingForScrollableFrame();
+}
+
+void RenderLayerCompositor::updateAcceleratedCompositingSettings()
+{
+ m_compositingReasonFinder.updateTriggers();
+ m_hasAcceleratedCompositing = m_renderView.document().settings()->acceleratedCompositingEnabled();
+ m_rootShouldAlwaysCompositeDirty = true;
+}
+
+bool RenderLayerCompositor::layerSquashingEnabled() const
+{
+ if (!RuntimeEnabledFeatures::layerSquashingEnabled())
+ return false;
+ if (Settings* settings = m_renderView.document().settings())
+ return settings->layerSquashingEnabled();
+ return true;
+}
+
+bool RenderLayerCompositor::acceleratedCompositingForOverflowScrollEnabled() const
+{
+ return m_compositingReasonFinder.hasOverflowScrollTrigger();
+}
+
+static RenderVideo* findFullscreenVideoRenderer(Document& document)
+{
+ Element* fullscreenElement = FullscreenElementStack::fullscreenElementFrom(document);
+ while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
+ Document* contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
+ if (!contentDocument)
+ return 0;
+ fullscreenElement = FullscreenElementStack::fullscreenElementFrom(*contentDocument);
+ }
+ if (!isHTMLVideoElement(fullscreenElement))
+ return 0;
+ RenderObject* renderer = fullscreenElement->renderer();
+ if (!renderer)
+ return 0;
+ return toRenderVideo(renderer);
+}
+
+void RenderLayerCompositor::updateIfNeededRecursive()
+{
+ for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ toLocalFrame(child)->contentRenderer()->compositor()->updateIfNeededRecursive();
+ }
+
+ TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateIfNeededRecursive");
+
+ ASSERT(!m_renderView.needsLayout());
+
+ ScriptForbiddenScope forbidScript;
+
+ // FIXME: enableCompositingModeIfNeeded can trigger a CompositingUpdateRebuildTree,
+ // which asserts that it's not InCompositingUpdate.
+ enableCompositingModeIfNeeded();
+
+ lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate);
+ updateIfNeeded();
+ lifecycle().advanceTo(DocumentLifecycle::CompositingClean);
+
+ DocumentAnimations::startPendingAnimations(m_renderView.document());
+ // TODO: Figure out why this fails on Chrome OS login page. crbug.com/365507
+ // ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean);
+
+#if ASSERT_ENABLED
+ assertNoUnresolvedDirtyBits();
+ for (Frame* child = m_renderView.frameView()->frame().tree().firstChild(); child; child = child->tree().nextSibling()) {
+ if (child->isLocalFrame())
+ toLocalFrame(child)->contentRenderer()->compositor()->assertNoUnresolvedDirtyBits();
+ }
+#endif
+}
+
+void RenderLayerCompositor::setNeedsCompositingUpdate(CompositingUpdateType updateType)
+{
+ ASSERT(updateType != CompositingUpdateNone);
+
+ // FIXME: This function should only set dirty bits. We shouldn't
+ // enable compositing mode here.
+ // We check needsLayout here because we don't know if we need to enable
+ // compositing mode until layout is up-to-date because we need to know
+ // if this frame scrolls.
+ //
+ // NOTE: CastStreamingApiTestWithPixelOutput.RtpStreamError triggers
+ // an ASSERT when this code is removed.
+ if (!m_renderView.needsLayout())
+ enableCompositingModeIfNeeded();
+
+ m_pendingUpdateType = std::max(m_pendingUpdateType, updateType);
+ page()->animator().scheduleVisualUpdate();
+ lifecycle().ensureStateAtMost(DocumentLifecycle::LayoutClean);
+}
+
+void RenderLayerCompositor::didLayout()
+{
+ // FIXME: Technically we only need to do this when the FrameView's
+ // isScrollable method would return a different value.
+ m_rootShouldAlwaysCompositeDirty = true;
+ enableCompositingModeIfNeeded();
+
+ // FIXME: Rather than marking the entire RenderView as dirty, we should
+ // track which RenderLayers moved during layout and only dirty those
+ // specific RenderLayers.
+ rootRenderLayer()->setNeedsCompositingInputsUpdate();
+ setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+}
+
+#if ASSERT_ENABLED
+
+void RenderLayerCompositor::assertNoUnresolvedDirtyBits()
+{
+ ASSERT(m_pendingUpdateType == CompositingUpdateNone);
+ ASSERT(!m_rootShouldAlwaysCompositeDirty);
+}
+
+#endif
+
+void RenderLayerCompositor::applyOverlayFullscreenVideoAdjustment()
+{
+ m_inOverlayFullscreenVideo = false;
+ if (!m_rootContentLayer)
+ return;
+
+ bool isMainFrame = m_renderView.frame()->isMainFrame();
+ RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document());
+ if (!video || !video->hasCompositedLayerMapping()) {
+ if (isMainFrame) {
+ GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer();
+ if (backgroundLayer && !backgroundLayer->parent())
+ rootFixedBackgroundsChanged();
+ }
+ return;
+ }
+
+ GraphicsLayer* videoLayer = video->compositedLayerMapping()->mainGraphicsLayer();
+
+ // The fullscreen video has layer position equal to its enclosing frame's scroll position because fullscreen container is fixed-positioned.
+ // We should reset layer position here since we are going to reattach the layer at the very top level.
+ videoLayer->setPosition(IntPoint());
+
+ // Only steal fullscreen video layer and clear all other layers if we are the main frame.
+ if (!isMainFrame)
+ return;
+
+ m_rootContentLayer->removeAllChildren();
+ m_overflowControlsHostLayer->addChild(videoLayer);
+ if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
+ backgroundLayer->removeFromParent();
+ m_inOverlayFullscreenVideo = true;
+}
+
+void RenderLayerCompositor::updateIfNeeded()
+{
+ CompositingUpdateType updateType = m_pendingUpdateType;
+ m_pendingUpdateType = CompositingUpdateNone;
+
+ if (!hasAcceleratedCompositing() || updateType == CompositingUpdateNone)
+ return;
+
+ RenderLayer* updateRoot = rootRenderLayer();
+
+ Vector<RenderLayer*> layersNeedingRepaint;
+
+ if (updateType >= CompositingUpdateAfterCompositingInputChange) {
+ bool layersChanged = false;
+ {
+ TRACE_EVENT0("blink_rendering", "CompositingInputsUpdater::update");
+ CompositingInputsUpdater(updateRoot).update(updateRoot);
+#if ASSERT_ENABLED
+ CompositingInputsUpdater::assertNeedsCompositingInputsUpdateBitsCleared(updateRoot);
+#endif
+ }
+
+ CompositingRequirementsUpdater(m_renderView, m_compositingReasonFinder).update(updateRoot);
+
+ {
+ TRACE_EVENT0("blink_rendering", "CompositingLayerAssigner::assign");
+ CompositingLayerAssigner(this).assign(updateRoot, layersChanged, layersNeedingRepaint);
+ }
+
+ {
+ TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateAfterCompositingChange");
+ if (const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas()) {
+ for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
+ (*it)->updateAfterCompositingChange();
+ }
+ }
+
+ if (layersChanged)
+ updateType = std::max(updateType, CompositingUpdateRebuildTree);
+ }
+
+ if (updateType != CompositingUpdateNone) {
+ TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::updateRecursive");
+ GraphicsLayerUpdater updater;
+ updater.update(layersNeedingRepaint, *updateRoot);
+
+ if (updater.needsRebuildTree())
+ updateType = std::max(updateType, CompositingUpdateRebuildTree);
+
+#if ASSERT_ENABLED
+ // FIXME: Move this check to the end of the compositing update.
+ GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(*updateRoot);
+#endif
+ }
+
+ if (updateType >= CompositingUpdateRebuildTree) {
+ GraphicsLayerVector childList;
+ {
+ TRACE_EVENT0("blink_rendering", "GraphicsLayerTreeBuilder::rebuild");
+ GraphicsLayerTreeBuilder().rebuild(*updateRoot, childList);
+ }
+
+ if (childList.isEmpty())
+ destroyRootLayer();
+ else
+ m_rootContentLayer->setChildren(childList);
+
+ if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
+ applyOverlayFullscreenVideoAdjustment();
+ }
+
+ if (m_needsUpdateFixedBackground) {
+ rootFixedBackgroundsChanged();
+ m_needsUpdateFixedBackground = false;
+ }
+
+ for (unsigned i = 0; i < layersNeedingRepaint.size(); i++) {
+ RenderLayer* layer = layersNeedingRepaint[i];
+ layer->repainter().computeRepaintRectsIncludingNonCompositingDescendants();
+
+ repaintOnCompositingChange(layer);
+ }
+
+ // Inform the inspector that the layer tree has changed.
+ if (m_renderView.frame()->isMainFrame())
+ InspectorInstrumentation::layerTreeDidChange(m_renderView.frame());
+}
+
+bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
+{
+ bool compositedLayerMappingChanged = false;
+ bool nonCompositedReasonChanged = updateLayerIfViewportConstrained(layer);
+
+ // FIXME: It would be nice to directly use the layer's compositing reason,
+ // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
+ // requirements fully.
+ switch (compositedLayerUpdate) {
+ case AllocateOwnCompositedLayerMapping:
+ ASSERT(!layer->hasCompositedLayerMapping());
+ setCompositingModeEnabled(true);
+
+ // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
+ // that computing repaint rects will know the layer's correct compositingState.
+ // FIXME: do we need to also remove the layer from it's location in the squashing list of its groupedMapping?
+ // Need to create a test where a squashed layer pops into compositing. And also to cover all other
+ // sorts of compositingState transitions.
+ layer->setLostGroupedMapping(false);
+ layer->setGroupedMapping(0);
+
+ // If we need to repaint, do so before allocating the compositedLayerMapping
+ repaintOnCompositingChange(layer);
+ layer->ensureCompositedLayerMapping();
+ compositedLayerMappingChanged = true;
+
+ // At this time, the ScrollingCooridnator only supports the top-level frame.
+ if (layer->isRootLayer() && m_renderView.frame()->isMainFrame()) {
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
+ }
+ break;
+ case RemoveOwnCompositedLayerMapping:
+ // PutInSquashingLayer means you might have to remove the composited layer mapping first.
+ case PutInSquashingLayer:
+ if (layer->hasCompositedLayerMapping()) {
+ // If we're removing the compositedLayerMapping from a reflection, clear the source GraphicsLayer's pointer to
+ // its replica GraphicsLayer. In practice this should never happen because reflectee and reflection
+ // are both either composited, or not composited.
+ if (layer->isReflection()) {
+ RenderLayer* sourceLayer = toRenderLayerModelObject(layer->renderer()->parent())->layer();
+ if (sourceLayer->hasCompositedLayerMapping()) {
+ ASSERT(sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->replicaLayer() == layer->compositedLayerMapping()->mainGraphicsLayer());
+ sourceLayer->compositedLayerMapping()->mainGraphicsLayer()->setReplicatedByLayer(0);
+ }
+ }
+
+ layer->clearCompositedLayerMapping();
+ compositedLayerMappingChanged = true;
+ }
+
+ break;
+ case RemoveFromSquashingLayer:
+ case NoCompositingStateChange:
+ // Do nothing.
+ break;
+ }
+
+ if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateRequiresOwnBackingStoreForIntrinsicReasons())
+ compositedLayerMappingChanged = true;
+
+ if (compositedLayerMappingChanged && layer->renderer()->isRenderPart()) {
+ RenderLayerCompositor* innerCompositor = frameContentsCompositor(toRenderPart(layer->renderer()));
+ if (innerCompositor && innerCompositor->staleInCompositingMode())
+ innerCompositor->updateRootLayerAttachment();
+ }
+
+ if (compositedLayerMappingChanged)
+ layer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
+
+ // If a fixed position layer gained/lost a compositedLayerMapping or the reason not compositing it changed,
+ // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
+ if (compositedLayerMappingChanged || nonCompositedReasonChanged) {
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView());
+ }
+
+ return compositedLayerMappingChanged || nonCompositedReasonChanged;
+}
+
+bool RenderLayerCompositor::updateLayerIfViewportConstrained(RenderLayer* layer)
+{
+ RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
+ m_compositingReasonFinder.requiresCompositingForPositionFixed(layer->renderer(), layer, &viewportConstrainedNotCompositedReason);
+
+ if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
+ ASSERT(viewportConstrainedNotCompositedReason == RenderLayer::NoNotCompositedReason || layer->renderer()->style()->position() == FixedPosition);
+ layer->setViewportConstrainedNotCompositedReason(viewportConstrainedNotCompositedReason);
+ return true;
+ }
+ return false;
+}
+
+// These are temporary hacks to work around chicken-egg issues while we continue to refactor the compositing code.
+// See crbug.com/383191 for a list of tests that fail if this method is removed.
+void RenderLayerCompositor::applyUpdateLayerCompositingStateChickenEggHacks(RenderLayer* layer, CompositingStateTransitionType compositedLayerUpdate)
+{
+ if (compositedLayerUpdate != NoCompositingStateChange) {
+ bool compositedLayerMappingChanged = allocateOrClearCompositedLayerMapping(layer, compositedLayerUpdate);
+ if (compositedLayerMappingChanged) {
+ // Repaint rects can only be computed for layers that have already been attached to the
+ // render tree, but a chicken-egg compositing update can happen before |layer| gets
+ // attached. Since newly-created renderers don't get parented until they are attached
+ // (see RenderTreeBuilder::createRendererForElementIfNeeded), we can check for attachment
+ // by checking for a parent.
+ if (layer->parent())
+ layer->repainter().computeRepaintRectsIncludingNonCompositingDescendants();
+ repaintOnCompositingChange(layer);
+ }
+ }
+}
+
+void RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, UpdateLayerCompositingStateOptions options)
+{
+ layer->setCompositingReasons(layer->styleDeterminedCompositingReasons(), CompositingReasonComboAllStyleDeterminedReasons);
+ CompositingStateTransitionType compositedLayerUpdate = CompositingLayerAssigner(this).computeCompositedLayerUpdate(layer);
+
+ if (compositedLayerUpdate != NoCompositingStateChange)
+ setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
+
+ if (options == UseChickenEggHacks)
+ applyUpdateLayerCompositingStateChickenEggHacks(layer, compositedLayerUpdate);
+}
+
+void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
+{
+ // If the renderer is not attached yet, no need to repaint.
+ if (layer->renderer() != &m_renderView && !layer->renderer()->parent())
+ return;
+
+ layer->repainter().repaintIncludingNonCompositingDescendants();
+}
+
+// This method assumes that layout is up-to-date, unlike repaintOnCompositingChange().
+void RenderLayerCompositor::repaintInCompositedAncestor(RenderLayer* layer, const LayoutRect& rect)
+{
+ RenderLayer* compositedAncestor = layer->enclosingCompositingLayerForRepaint(ExcludeSelf);
+ if (!compositedAncestor)
+ return;
+ ASSERT(compositedAncestor->compositingState() == PaintsIntoOwnBacking || compositedAncestor->compositingState() == PaintsIntoGroupedBacking);
+
+ LayoutPoint offset;
+ layer->convertToLayerCoords(compositedAncestor, offset);
+ LayoutRect repaintRect = rect;
+ repaintRect.moveBy(offset);
+ compositedAncestor->repainter().setBackingNeedsRepaintInRect(repaintRect);
+}
+
+void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
+{
+ if (m_overflowControlsHostLayer)
+ m_overflowControlsHostLayer->setPosition(contentsOffset);
+}
+
+void RenderLayerCompositor::frameViewDidChangeSize()
+{
+ if (m_containerLayer) {
+ FrameView* frameView = m_renderView.frameView();
+ m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
+
+ frameViewDidScroll();
+ updateOverflowControlsLayers();
+ }
+}
+
+enum AcceleratedFixedRootBackgroundHistogramBuckets {
+ ScrolledMainFrameBucket = 0,
+ ScrolledMainFrameWithAcceleratedFixedRootBackground = 1,
+ ScrolledMainFrameWithUnacceleratedFixedRootBackground = 2,
+ AcceleratedFixedRootBackgroundHistogramMax = 3
+};
+
+void RenderLayerCompositor::frameViewDidScroll()
+{
+ FrameView* frameView = m_renderView.frameView();
+ IntPoint scrollPosition = frameView->scrollPosition();
+
+ if (!m_scrollLayer)
+ return;
+
+ bool scrollingCoordinatorHandlesOffset = false;
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
+ if (Settings* settings = m_renderView.document().settings()) {
+ if (m_renderView.frame()->isMainFrame() || settings->compositedScrollingForFramesEnabled())
+ scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
+ }
+ }
+
+ // Scroll position = scroll minimum + scroll offset. Adjust the layer's
+ // position to handle whatever the scroll coordinator isn't handling.
+ // The minimum scroll position is non-zero for RTL pages with overflow.
+ if (scrollingCoordinatorHandlesOffset)
+ m_scrollLayer->setPosition(-frameView->minimumScrollPosition());
+ else
+ m_scrollLayer->setPosition(-scrollPosition);
+
+
+ blink::Platform::current()->histogramEnumeration("Renderer.AcceleratedFixedRootBackground",
+ ScrolledMainFrameBucket,
+ AcceleratedFixedRootBackgroundHistogramMax);
+}
+
+void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
+{
+ if (m_containerLayer)
+ updateOverflowControlsLayers();
+}
+
+void RenderLayerCompositor::rootFixedBackgroundsChanged()
+{
+ if (!supportsFixedRootBackgroundCompositing())
+ return;
+
+ // To avoid having to make the fixed root background layer fixed positioned to
+ // stay put, we position it in the layer tree as follows:
+ //
+ // + Overflow controls host
+ // + LocalFrame clip
+ // + (Fixed root background) <-- Here.
+ // + LocalFrame scroll
+ // + Root content layer
+ // + Scrollbars
+ //
+ // That is, it needs to be the first child of the frame clip, the sibling of
+ // the frame scroll layer. The compositor does not own the background layer, it
+ // just positions it (like the foreground layer).
+ if (GraphicsLayer* backgroundLayer = fixedRootBackgroundLayer())
+ m_containerLayer->addChildBelow(backgroundLayer, m_scrollLayer.get());
+}
+
+bool RenderLayerCompositor::scrollingLayerDidChange(RenderLayer* layer)
+{
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ return scrollingCoordinator->scrollableAreaScrollLayerDidChange(layer->scrollableArea());
+ return false;
+}
+
+String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
+{
+ ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean);
+
+ if (!m_rootContentLayer)
+ return String();
+
+ // We skip dumping the scroll and clip layers to keep layerTreeAsText output
+ // similar between platforms (unless we explicitly request dumping from the
+ // root.
+ GraphicsLayer* rootLayer = m_rootContentLayer.get();
+ if (flags & LayerTreeIncludesRootLayer)
+ rootLayer = rootGraphicsLayer();
+
+ String layerTreeText = rootLayer->layerTreeAsText(flags);
+
+ // The true root layer is not included in the dump, so if we want to report
+ // its repaint rects, they must be included here.
+ if (flags & LayerTreeIncludesRepaintRects)
+ return m_renderView.frameView()->trackedPaintInvalidationRectsAsText() + layerTreeText;
+
+ return layerTreeText;
+}
+
+RenderLayerCompositor* RenderLayerCompositor::frameContentsCompositor(RenderPart* renderer)
+{
+ if (!renderer->node()->isFrameOwnerElement())
+ return 0;
+
+ HTMLFrameOwnerElement* element = toHTMLFrameOwnerElement(renderer->node());
+ if (Document* contentDocument = element->contentDocument()) {
+ if (RenderView* view = contentDocument->renderView())
+ return view->compositor();
+ }
+ return 0;
+}
+
+// FIXME: What does this function do? It needs a clearer name.
+bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
+{
+ RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
+ if (!innerCompositor || !innerCompositor->staleInCompositingMode() || innerCompositor->rootLayerAttachment() != RootLayerAttachedViaEnclosingFrame)
+ return false;
+
+ RenderLayer* layer = renderer->layer();
+ if (!layer->hasCompositedLayerMapping())
+ return false;
+
+ CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
+ GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers();
+ GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer();
+ if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) {
+ hostingLayer->removeAllChildren();
+ hostingLayer->addChild(rootLayer);
+ }
+ return true;
+}
+
+void RenderLayerCompositor::repaintCompositedLayers()
+{
+ recursiveRepaintLayer(rootRenderLayer());
+}
+
+void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer)
+{
+ // FIXME: This method does not work correctly with transforms.
+ if (layer->compositingState() == PaintsIntoOwnBacking) {
+ layer->compositedLayerMapping()->setContentsNeedDisplay();
+ // This function is called only when it is desired to repaint the entire compositing graphics layer tree.
+ // This includes squashing.
+ layer->compositedLayerMapping()->setSquashingContentsNeedDisplay();
+ }
+
+ layer->stackingNode()->updateLayerListsIfNeeded();
+
+#if ASSERT_ENABLED
+ LayerListMutationDetector mutationChecker(layer->stackingNode());
+#endif
+
+ unsigned childrenToVisit = NormalFlowChildren;
+ if (layer->hasCompositingDescendant())
+ childrenToVisit |= PositiveZOrderChildren | NegativeZOrderChildren;
+ RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), childrenToVisit);
+ while (RenderLayerStackingNode* curNode = iterator.next())
+ recursiveRepaintLayer(curNode->layer());
+}
+
+RenderLayer* RenderLayerCompositor::rootRenderLayer() const
+{
+ return m_renderView.layer();
+}
+
+GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
+{
+ if (m_overflowControlsHostLayer)
+ return m_overflowControlsHostLayer.get();
+ return m_rootContentLayer.get();
+}
+
+GraphicsLayer* RenderLayerCompositor::scrollLayer() const
+{
+ return m_scrollLayer.get();
+}
+
+GraphicsLayer* RenderLayerCompositor::containerLayer() const
+{
+ return m_containerLayer.get();
+}
+
+GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer()
+{
+ ASSERT(rootGraphicsLayer());
+
+ if (!m_rootTransformLayer.get()) {
+ m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
+ m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get());
+ m_rootTransformLayer->addChild(m_containerLayer.get());
+ updateOverflowControlsLayers();
+ }
+
+ return m_rootTransformLayer.get();
+}
+
+void RenderLayerCompositor::setIsInWindow(bool isInWindow)
+{
+ if (!staleInCompositingMode())
+ return;
+
+ if (isInWindow) {
+ if (m_rootLayerAttachment != RootLayerUnattached)
+ return;
+
+ RootLayerAttachment attachment = m_renderView.frame()->isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
+ attachRootLayer(attachment);
+ } else {
+ if (m_rootLayerAttachment == RootLayerUnattached)
+ return;
+
+ detachRootLayer();
+ }
+}
+
+void RenderLayerCompositor::updateRootLayerPosition()
+{
+ if (m_rootContentLayer) {
+ const IntRect& documentRect = m_renderView.documentRect();
+ m_rootContentLayer->setSize(documentRect.size());
+ m_rootContentLayer->setPosition(documentRect.location());
+#if USE(RUBBER_BANDING)
+ if (m_layerForOverhangShadow)
+ OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
+#endif
+ }
+ if (m_containerLayer) {
+ FrameView* frameView = m_renderView.frameView();
+ m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
+ }
+}
+
+void RenderLayerCompositor::updateStyleDeterminedCompositingReasons(RenderLayer* layer)
+{
+ CompositingReasons reasons = m_compositingReasonFinder.styleDeterminedReasons(layer->renderer());
+ layer->setStyleDeterminedCompositingReasons(reasons);
+}
+
+void RenderLayerCompositor::updateDirectCompositingReasons(RenderLayer* layer)
+{
+ CompositingReasons reasons = m_compositingReasonFinder.directReasons(layer);
+ layer->setCompositingReasons(reasons, CompositingReasonComboAllDirectReasons);
+}
+
+void RenderLayerCompositor::setOverlayLayer(GraphicsLayer* layer)
+{
+ ASSERT(rootGraphicsLayer());
+
+ if (layer->parent() != m_overflowControlsHostLayer.get())
+ m_overflowControlsHostLayer->addChild(layer);
+}
+
+bool RenderLayerCompositor::canBeComposited(const RenderLayer* layer) const
+{
+ // FIXME: We disable accelerated compositing for elements in a RenderFlowThread as it doesn't work properly.
+ // See http://webkit.org/b/84900 to re-enable it.
+ return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && !layer->subtreeIsInvisible() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread;
+}
+
+// Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
+// up to the enclosing compositing ancestor. This is required because compositing layers are parented
+// according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
+// Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
+// but a sibling in the z-order hierarchy.
+bool RenderLayerCompositor::clippedByNonAncestorInStackingTree(const RenderLayer* layer) const
+{
+ if (!layer->hasCompositedLayerMapping() || !layer->parent())
+ return false;
+
+ const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
+ if (!compositingAncestor)
+ return false;
+
+ RenderObject* clippingContainer = layer->renderer()->clippingContainer();
+ if (!clippingContainer)
+ return false;
+
+ if (compositingAncestor->renderer()->isDescendantOf(clippingContainer))
+ return false;
+
+ return true;
+}
+
+// Return true if the given layer is a stacking context and has compositing child
+// layers that it needs to clip. In this case we insert a clipping GraphicsLayer
+// into the hierarchy between this layer and its children in the z-order hierarchy.
+bool RenderLayerCompositor::clipsCompositingDescendants(const RenderLayer* layer) const
+{
+ return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
+}
+
+// If an element has negative z-index children, those children render in front of the
+// layer background, so we need an extra 'contents' layer for the foreground of the layer
+// object.
+bool RenderLayerCompositor::needsContentsCompositingLayer(const RenderLayer* layer) const
+{
+ return layer->stackingNode()->hasNegativeZOrderList();
+}
+
+static void paintScrollbar(Scrollbar* scrollbar, GraphicsContext& context, const IntRect& clip)
+{
+ if (!scrollbar)
+ return;
+
+ context.save();
+ const IntRect& scrollbarRect = scrollbar->frameRect();
+ context.translate(-scrollbarRect.x(), -scrollbarRect.y());
+ IntRect transformedClip = clip;
+ transformedClip.moveBy(scrollbarRect.location());
+ scrollbar->paint(&context, transformedClip);
+ context.restore();
+}
+
+void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
+{
+ if (graphicsLayer == layerForHorizontalScrollbar())
+ paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context, clip);
+ else if (graphicsLayer == layerForVerticalScrollbar())
+ paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, clip);
+ else if (graphicsLayer == layerForScrollCorner()) {
+ const IntRect& scrollCorner = m_renderView.frameView()->scrollCornerRect();
+ context.save();
+ context.translate(-scrollCorner.x(), -scrollCorner.y());
+ IntRect transformedClip = clip;
+ transformedClip.moveBy(scrollCorner.location());
+ m_renderView.frameView()->paintScrollCorner(&context, transformedClip);
+ context.restore();
+ }
+}
+
+bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
+{
+ if (Settings* settings = m_renderView.document().settings()) {
+ if (settings->acceleratedCompositingForFixedRootBackgroundEnabled())
+ return true;
+ }
+ return false;
+}
+
+bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
+{
+ if (layer != m_renderView.layer())
+ return false;
+
+ return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
+}
+
+GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
+{
+ // Get the fixed root background from the RenderView layer's compositedLayerMapping.
+ RenderLayer* viewLayer = m_renderView.layer();
+ if (!viewLayer)
+ return 0;
+
+ if (viewLayer->compositingState() == PaintsIntoOwnBacking && viewLayer->compositedLayerMapping()->backgroundLayerPaintsFixedRootBackground())
+ return viewLayer->compositedLayerMapping()->backgroundLayer();
+
+ return 0;
+}
+
+static void resetTrackedRepaintRectsRecursive(GraphicsLayer* graphicsLayer)
+{
+ if (!graphicsLayer)
+ return;
+
+ graphicsLayer->resetTrackedRepaints();
+
+ for (size_t i = 0; i < graphicsLayer->children().size(); ++i)
+ resetTrackedRepaintRectsRecursive(graphicsLayer->children()[i]);
+
+ if (GraphicsLayer* replicaLayer = graphicsLayer->replicaLayer())
+ resetTrackedRepaintRectsRecursive(replicaLayer);
+
+ if (GraphicsLayer* maskLayer = graphicsLayer->maskLayer())
+ resetTrackedRepaintRectsRecursive(maskLayer);
+
+ if (GraphicsLayer* clippingMaskLayer = graphicsLayer->contentsClippingMaskLayer())
+ resetTrackedRepaintRectsRecursive(clippingMaskLayer);
+}
+
+void RenderLayerCompositor::resetTrackedRepaintRects()
+{
+ if (GraphicsLayer* rootLayer = rootGraphicsLayer())
+ resetTrackedRepaintRectsRecursive(rootLayer);
+}
+
+void RenderLayerCompositor::setTracksRepaints(bool tracksRepaints)
+{
+ ASSERT(lifecycle().state() == DocumentLifecycle::CompositingClean);
+ m_isTrackingRepaints = tracksRepaints;
+}
+
+bool RenderLayerCompositor::isTrackingRepaints() const
+{
+ return m_isTrackingRepaints;
+}
+
+static bool shouldCompositeOverflowControls(FrameView* view)
+{
+ if (Page* page = view->frame().page()) {
+ if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
+ if (scrollingCoordinator->coordinatesScrollingForFrameView(view))
+ return true;
+ }
+
+ return true;
+}
+
+bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
+{
+ FrameView* view = m_renderView.frameView();
+ return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
+}
+
+bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
+{
+ FrameView* view = m_renderView.frameView();
+ return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
+}
+
+bool RenderLayerCompositor::requiresScrollCornerLayer() const
+{
+ FrameView* view = m_renderView.frameView();
+ return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
+}
+
+void RenderLayerCompositor::updateOverflowControlsLayers()
+{
+#if USE(RUBBER_BANDING)
+ if (m_renderView.frame()->isMainFrame()) {
+ if (!m_layerForOverhangShadow) {
+ m_layerForOverhangShadow = GraphicsLayer::create(graphicsLayerFactory(), this);
+ OverscrollTheme::theme()->setUpOverhangShadowLayer(m_layerForOverhangShadow.get());
+ OverscrollTheme::theme()->updateOverhangShadowLayer(m_layerForOverhangShadow.get(), m_rootContentLayer.get());
+ m_scrollLayer->addChild(m_layerForOverhangShadow.get());
+ }
+ } else {
+ ASSERT(!m_layerForOverhangShadow);
+ }
+#endif
+ GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransformLayer.get() : m_overflowControlsHostLayer.get();
+
+ if (requiresHorizontalScrollbarLayer()) {
+ if (!m_layerForHorizontalScrollbar) {
+ m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
+ }
+
+ if (m_layerForHorizontalScrollbar->parent() != controlsParent) {
+ controlsParent->addChild(m_layerForHorizontalScrollbar.get());
+
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
+ }
+ } else if (m_layerForHorizontalScrollbar) {
+ m_layerForHorizontalScrollbar->removeFromParent();
+ m_layerForHorizontalScrollbar = nullptr;
+
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
+ }
+
+ if (requiresVerticalScrollbarLayer()) {
+ if (!m_layerForVerticalScrollbar) {
+ m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
+ }
+
+ if (m_layerForVerticalScrollbar->parent() != controlsParent) {
+ controlsParent->addChild(m_layerForVerticalScrollbar.get());
+
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
+ }
+ } else if (m_layerForVerticalScrollbar) {
+ m_layerForVerticalScrollbar->removeFromParent();
+ m_layerForVerticalScrollbar = nullptr;
+
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
+ }
+
+ if (requiresScrollCornerLayer()) {
+ if (!m_layerForScrollCorner) {
+ m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
+ controlsParent->addChild(m_layerForScrollCorner.get());
+ }
+ } else if (m_layerForScrollCorner) {
+ m_layerForScrollCorner->removeFromParent();
+ m_layerForScrollCorner = nullptr;
+ }
+
+ m_renderView.frameView()->positionScrollbarLayers();
+}
+
+void RenderLayerCompositor::ensureRootLayer()
+{
+ RootLayerAttachment expectedAttachment = m_renderView.frame()->isMainFrame() ? RootLayerAttachedViaChromeClient : RootLayerAttachedViaEnclosingFrame;
+ if (expectedAttachment == m_rootLayerAttachment)
+ return;
+
+ if (!m_rootContentLayer) {
+ m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
+ IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect();
+ m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
+ m_rootContentLayer->setPosition(FloatPoint());
+ m_rootContentLayer->setOwnerNodeId(InspectorNodeIds::idForNode(m_renderView.generatingNode()));
+
+ // Need to clip to prevent transformed content showing outside this frame
+ m_rootContentLayer->setMasksToBounds(true);
+ }
+
+ if (!m_overflowControlsHostLayer) {
+ ASSERT(!m_scrollLayer);
+ ASSERT(!m_containerLayer);
+
+ // Create a layer to host the clipping layer and the overflow controls layers.
+ m_overflowControlsHostLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
+
+ // Create a clipping layer if this is an iframe or settings require to clip.
+ m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
+ bool containerMasksToBounds = !m_renderView.frame()->isMainFrame();
+ if (Settings* settings = m_renderView.document().settings()) {
+ if (settings->mainFrameClipsContent())
+ containerMasksToBounds = true;
+ }
+ m_containerLayer->setMasksToBounds(containerMasksToBounds);
+
+ m_scrollLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(m_scrollLayer.get(), true);
+
+ // Hook them up
+ m_overflowControlsHostLayer->addChild(m_containerLayer.get());
+ m_containerLayer->addChild(m_scrollLayer.get());
+ m_scrollLayer->addChild(m_rootContentLayer.get());
+
+ frameViewDidChangeSize();
+ }
+
+ // Check to see if we have to change the attachment
+ if (m_rootLayerAttachment != RootLayerUnattached)
+ detachRootLayer();
+
+ attachRootLayer(expectedAttachment);
+}
+
+void RenderLayerCompositor::destroyRootLayer()
+{
+ if (!m_rootContentLayer)
+ return;
+
+ detachRootLayer();
+
+#if USE(RUBBER_BANDING)
+ if (m_layerForOverhangShadow) {
+ m_layerForOverhangShadow->removeFromParent();
+ m_layerForOverhangShadow = nullptr;
+ }
+#endif
+
+ if (m_layerForHorizontalScrollbar) {
+ m_layerForHorizontalScrollbar->removeFromParent();
+ m_layerForHorizontalScrollbar = nullptr;
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
+ if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalScrollbar())
+ m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
+ }
+
+ if (m_layerForVerticalScrollbar) {
+ m_layerForVerticalScrollbar->removeFromParent();
+ m_layerForVerticalScrollbar = nullptr;
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
+ scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
+ if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScrollbar())
+ m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
+ }
+
+ if (m_layerForScrollCorner) {
+ m_layerForScrollCorner = nullptr;
+ m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView()->scrollCornerRect());
+ }
+
+ if (m_overflowControlsHostLayer) {
+ m_overflowControlsHostLayer = nullptr;
+ m_containerLayer = nullptr;
+ m_scrollLayer = nullptr;
+ }
+ ASSERT(!m_scrollLayer);
+ m_rootContentLayer = nullptr;
+ m_rootTransformLayer = nullptr;
+}
+
+void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
+{
+ if (!m_rootContentLayer)
+ return;
+
+ switch (attachment) {
+ case RootLayerUnattached:
+ ASSERT_NOT_REACHED();
+ break;
+ case RootLayerAttachedViaChromeClient: {
+ LocalFrame& frame = m_renderView.frameView()->frame();
+ Page* page = frame.page();
+ if (!page)
+ return;
+ page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer());
+ break;
+ }
+ case RootLayerAttachedViaEnclosingFrame: {
+ HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
+ ASSERT(ownerElement);
+ // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
+ // for the frame's renderer in the parent document.
+ ownerElement->setNeedsCompositingUpdate();
+ break;
+ }
+ }
+
+ m_rootLayerAttachment = attachment;
+}
+
+void RenderLayerCompositor::detachRootLayer()
+{
+ if (!m_rootContentLayer || m_rootLayerAttachment == RootLayerUnattached)
+ return;
+
+ switch (m_rootLayerAttachment) {
+ case RootLayerAttachedViaEnclosingFrame: {
+ // The layer will get unhooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
+ // for the frame's renderer in the parent document.
+ if (m_overflowControlsHostLayer)
+ m_overflowControlsHostLayer->removeFromParent();
+ else
+ m_rootContentLayer->removeFromParent();
+
+ if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement())
+ ownerElement->setNeedsCompositingUpdate();
+ break;
+ }
+ case RootLayerAttachedViaChromeClient: {
+ LocalFrame& frame = m_renderView.frameView()->frame();
+ Page* page = frame.page();
+ if (!page)
+ return;
+ page->chrome().client().attachRootGraphicsLayer(0);
+ }
+ break;
+ case RootLayerUnattached:
+ break;
+ }
+
+ m_rootLayerAttachment = RootLayerUnattached;
+}
+
+void RenderLayerCompositor::updateRootLayerAttachment()
+{
+ ensureRootLayer();
+}
+
+ScrollingCoordinator* RenderLayerCompositor::scrollingCoordinator() const
+{
+ if (Page* page = this->page())
+ return page->scrollingCoordinator();
+
+ return 0;
+}
+
+GraphicsLayerFactory* RenderLayerCompositor::graphicsLayerFactory() const
+{
+ if (Page* page = this->page())
+ return page->chrome().client().graphicsLayerFactory();
+ return 0;
+}
+
+Page* RenderLayerCompositor::page() const
+{
+ return m_renderView.frameView()->frame().page();
+}
+
+DocumentLifecycle& RenderLayerCompositor::lifecycle() const
+{
+ return m_renderView.document().lifecycle();
+}
+
+String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
+{
+ String name;
+ if (graphicsLayer == m_rootContentLayer.get()) {
+ name = "Content Root Layer";
+ } else if (graphicsLayer == m_rootTransformLayer.get()) {
+ name = "Root Transform Layer";
+#if USE(RUBBER_BANDING)
+ } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
+ name = "Overhang Areas Shadow";
+#endif
+ } else if (graphicsLayer == m_overflowControlsHostLayer.get()) {
+ name = "Overflow Controls Host Layer";
+ } else if (graphicsLayer == m_layerForHorizontalScrollbar.get()) {
+ name = "Horizontal Scrollbar Layer";
+ } else if (graphicsLayer == m_layerForVerticalScrollbar.get()) {
+ name = "Vertical Scrollbar Layer";
+ } else if (graphicsLayer == m_layerForScrollCorner.get()) {
+ name = "Scroll Corner Layer";
+ } else if (graphicsLayer == m_containerLayer.get()) {
+ name = "LocalFrame Clipping Layer";
+ } else if (graphicsLayer == m_scrollLayer.get()) {
+ name = "LocalFrame Scrolling Layer";
+ } else {
+ ASSERT_NOT_REACHED();
+ }
+
+ return name;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.h b/chromium/third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.h
new file mode 100644
index 00000000000..4fc1a0456f9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef RenderLayerCompositor_h
+#define RenderLayerCompositor_h
+
+#include "core/page/ChromeClient.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/compositing/CompositingReasonFinder.h"
+#include "platform/graphics/GraphicsLayerClient.h"
+#include "wtf/HashMap.h"
+
+namespace WebCore {
+
+class GraphicsLayer;
+class RenderPart;
+class ScrollingCoordinator;
+
+enum CompositingUpdateType {
+ CompositingUpdateNone,
+ CompositingUpdateAfterGeometryChange,
+ CompositingUpdateAfterCompositingInputChange,
+ CompositingUpdateRebuildTree,
+};
+
+enum CompositingStateTransitionType {
+ NoCompositingStateChange,
+ AllocateOwnCompositedLayerMapping,
+ RemoveOwnCompositedLayerMapping,
+ PutInSquashingLayer,
+ RemoveFromSquashingLayer
+};
+
+// RenderLayerCompositor manages the hierarchy of
+// composited RenderLayers. It determines which RenderLayers
+// become compositing, and creates and maintains a hierarchy of
+// GraphicsLayers based on the RenderLayer painting order.
+//
+// There is one RenderLayerCompositor per RenderView.
+
+class RenderLayerCompositor FINAL : public GraphicsLayerClient {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ explicit RenderLayerCompositor(RenderView&);
+ virtual ~RenderLayerCompositor();
+
+ void updateIfNeededRecursive();
+
+ // Return true if this RenderView is in "compositing mode" (i.e. has one or more
+ // composited RenderLayers)
+ bool inCompositingMode() const;
+ // FIXME: Replace all callers with inCompositingMdoe and remove this function.
+ bool staleInCompositingMode() const;
+ // This will make a compositing layer at the root automatically, and hook up to
+ // the native view/window system.
+ void setCompositingModeEnabled(bool);
+
+ // Returns true if the accelerated compositing is enabled
+ bool hasAcceleratedCompositing() const { return m_hasAcceleratedCompositing; }
+ bool layerSquashingEnabled() const;
+
+ bool acceleratedCompositingForOverflowScrollEnabled() const;
+
+ bool rootShouldAlwaysComposite() const;
+
+ // Copy the accelerated compositing related flags from Settings
+ void updateAcceleratedCompositingSettings();
+
+ // Used to indicate that a compositing update will be needed for the next frame that gets drawn.
+ void setNeedsCompositingUpdate(CompositingUpdateType);
+
+ void didLayout();
+
+ enum UpdateLayerCompositingStateOptions {
+ Normal,
+ UseChickenEggHacks, // Use this to trigger temporary chicken-egg hacks. See crbug.com/339892.
+ };
+
+ // Update the compositing dirty bits, based on the compositing-impacting properties of the layer.
+ void updateLayerCompositingState(RenderLayer*, UpdateLayerCompositingStateOptions = Normal);
+
+ // Returns whether this layer is clipped by another layer that is not an ancestor of the given layer in the stacking context hierarchy.
+ bool clippedByNonAncestorInStackingTree(const RenderLayer*) const;
+ // Whether layer's compositedLayerMapping needs a GraphicsLayer to clip z-order children of the given RenderLayer.
+ bool clipsCompositingDescendants(const RenderLayer*) const;
+
+ // Whether the given layer needs an extra 'contents' layer.
+ bool needsContentsCompositingLayer(const RenderLayer*) const;
+
+ bool supportsFixedRootBackgroundCompositing() const;
+ bool needsFixedRootBackgroundLayer(const RenderLayer*) const;
+ GraphicsLayer* fixedRootBackgroundLayer() const;
+ void setNeedsUpdateFixedBackground() { m_needsUpdateFixedBackground = true; }
+
+ // Repaint the appropriate layers when the given RenderLayer starts or stops being composited.
+ void repaintOnCompositingChange(RenderLayer*);
+
+ void repaintInCompositedAncestor(RenderLayer*, const LayoutRect&);
+ void repaintCompositedLayers();
+
+ RenderLayer* rootRenderLayer() const;
+ GraphicsLayer* rootGraphicsLayer() const;
+ GraphicsLayer* scrollLayer() const;
+ GraphicsLayer* containerLayer() const;
+
+ // We don't always have a root transform layer. This function lazily allocates one
+ // and returns it as required.
+ GraphicsLayer* ensureRootTransformLayer();
+
+ enum RootLayerAttachment {
+ RootLayerUnattached,
+ RootLayerAttachedViaChromeClient,
+ RootLayerAttachedViaEnclosingFrame
+ };
+
+ RootLayerAttachment rootLayerAttachment() const { return m_rootLayerAttachment; }
+ void updateRootLayerAttachment();
+ void updateRootLayerPosition();
+
+ void setIsInWindow(bool);
+
+ static RenderLayerCompositor* frameContentsCompositor(RenderPart*);
+ // Return true if the layers changed.
+ static bool parentFrameContentLayers(RenderPart*);
+
+ // Update the geometry of the layers used for clipping and scrolling in frames.
+ void frameViewDidChangeLocation(const IntPoint& contentsOffset);
+ void frameViewDidChangeSize();
+ void frameViewDidScroll();
+ void frameViewScrollbarsExistenceDidChange();
+ void rootFixedBackgroundsChanged();
+
+ bool scrollingLayerDidChange(RenderLayer*);
+
+ String layerTreeAsText(LayerTreeFlags);
+
+ GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
+ GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
+ GraphicsLayer* layerForScrollCorner() const { return m_layerForScrollCorner.get(); }
+
+ void resetTrackedRepaintRects();
+ void setTracksRepaints(bool);
+
+ virtual String debugName(const GraphicsLayer*) OVERRIDE;
+
+ void updateStyleDeterminedCompositingReasons(RenderLayer*);
+
+ // Whether the layer could ever be composited.
+ bool canBeComposited(const RenderLayer*) const;
+
+ // FIXME: Move allocateOrClearCompositedLayerMapping to CompositingLayerAssigner once we've fixed
+ // the compositing chicken/egg issues.
+ bool allocateOrClearCompositedLayerMapping(RenderLayer*, CompositingStateTransitionType compositedLayerUpdate);
+
+ void updateDirectCompositingReasons(RenderLayer*);
+
+ void setOverlayLayer(GraphicsLayer*);
+
+ bool inOverlayFullscreenVideo() const { return m_inOverlayFullscreenVideo; }
+
+private:
+ class OverlapMap;
+
+#if ASSERT_ENABLED
+ void assertNoUnresolvedDirtyBits();
+#endif
+
+ // Make updates to the layer based on viewport-constrained properties such as position:fixed. This can in turn affect
+ // compositing.
+ bool updateLayerIfViewportConstrained(RenderLayer*);
+
+ // GraphicsLayerClient implementation
+ virtual void notifyAnimationStarted(const GraphicsLayer*, double) OVERRIDE { }
+ virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) OVERRIDE;
+
+ virtual bool isTrackingRepaints() const OVERRIDE;
+
+ // Whether the given RL needs to paint into its own separate backing (and hence would need its own CompositedLayerMapping).
+ bool needsOwnBacking(const RenderLayer*) const;
+
+ void updateIfNeeded();
+
+ void recursiveRepaintLayer(RenderLayer*);
+
+ void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap&, struct CompositingRecursionData&, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants, IntRect& absoluteDecendantBoundingBox);
+
+ bool hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const;
+
+ void ensureRootLayer();
+ void destroyRootLayer();
+
+ void attachRootLayer(RootLayerAttachment);
+ void detachRootLayer();
+
+ void updateOverflowControlsLayers();
+
+ Page* page() const;
+
+ GraphicsLayerFactory* graphicsLayerFactory() const;
+ ScrollingCoordinator* scrollingCoordinator() const;
+
+ void enableCompositingModeIfNeeded();
+
+ bool requiresHorizontalScrollbarLayer() const;
+ bool requiresVerticalScrollbarLayer() const;
+ bool requiresScrollCornerLayer() const;
+
+ void applyUpdateLayerCompositingStateChickenEggHacks(RenderLayer*, CompositingStateTransitionType compositedLayerUpdate);
+
+ DocumentLifecycle& lifecycle() const;
+
+ void applyOverlayFullscreenVideoAdjustment();
+
+ RenderView& m_renderView;
+ OwnPtr<GraphicsLayer> m_rootContentLayer;
+ OwnPtr<GraphicsLayer> m_rootTransformLayer;
+
+ CompositingReasonFinder m_compositingReasonFinder;
+
+ CompositingUpdateType m_pendingUpdateType;
+
+ bool m_hasAcceleratedCompositing;
+ bool m_compositing;
+
+ // The root layer doesn't composite if it's a non-scrollable frame.
+ // So, after a layout we set this dirty bit to know that we need
+ // to recompute whether the root layer should composite even if
+ // none of its descendants composite.
+ // FIXME: Get rid of all the callers of setCompositingModeEnabled
+ // except the one in updateIfNeeded, then rename this to
+ // m_compositingDirty.
+ bool m_rootShouldAlwaysCompositeDirty;
+ bool m_needsUpdateFixedBackground;
+ bool m_isTrackingRepaints; // Used for testing.
+
+ RootLayerAttachment m_rootLayerAttachment;
+
+ // Enclosing container layer, which clips for iframe content
+ OwnPtr<GraphicsLayer> m_containerLayer;
+ OwnPtr<GraphicsLayer> m_scrollLayer;
+
+ // Enclosing layer for overflow controls and the clipping layer
+ OwnPtr<GraphicsLayer> m_overflowControlsHostLayer;
+
+ // Layers for overflow controls
+ OwnPtr<GraphicsLayer> m_layerForHorizontalScrollbar;
+ OwnPtr<GraphicsLayer> m_layerForVerticalScrollbar;
+ OwnPtr<GraphicsLayer> m_layerForScrollCorner;
+#if USE(RUBBER_BANDING)
+ OwnPtr<GraphicsLayer> m_layerForOverhangShadow;
+#endif
+
+ bool m_inOverlayFullscreenVideo;
+};
+
+} // namespace WebCore
+
+#endif // RenderLayerCompositor_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp b/chromium/third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp
new file mode 100644
index 00000000000..513b2c3beaa
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Adobe Systems Incorporated.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/rendering/line/BreakingContextInlineHeaders.h"
+
+namespace WebCore {
+
+InlineIterator BreakingContext::handleEndOfLine()
+{
+ if (m_lineBreak == m_resolver.position() && (!m_lineBreak.object() || !m_lineBreak.object()->isBR())) {
+ // we just add as much as possible
+ if (m_blockStyle->whiteSpace() == PRE && !m_current.offset()) {
+ m_lineBreak.moveTo(m_lastObject, m_lastObject->isText() ? m_lastObject->length() : 0);
+ } else if (m_lineBreak.object()) {
+ // Don't ever break in the middle of a word if we can help it.
+ // There's no room at all. We just have to be on this line,
+ // even though we'll spill out.
+ m_lineBreak.moveTo(m_current.object(), m_current.offset());
+ }
+ }
+
+ // FIXME Bug 100049: We do not need to consume input in a multi-segment line
+ // unless no segment will.
+ if (m_lineBreak == m_resolver.position())
+ m_lineBreak.increment();
+
+ // Sanity check our midpoints.
+ m_lineMidpointState.checkMidpoints(m_lineBreak);
+
+ m_trailingObjects.updateMidpointsForTrailingObjects(m_lineMidpointState, m_lineBreak, TrailingObjects::CollapseFirstSpace);
+
+ // We might have made lineBreak an iterator that points past the end
+ // of the object. Do this adjustment to make it point to the start
+ // of the next object instead to avoid confusing the rest of the
+ // code.
+ if (m_lineBreak.offset()) {
+ // This loop enforces the invariant that line breaks should never point
+ // at an empty inline. See http://crbug.com/305904.
+ do {
+ m_lineBreak.setOffset(m_lineBreak.offset() - 1);
+ m_lineBreak.increment();
+ } while (!m_lineBreak.atEnd() && isEmptyInline(m_lineBreak.object()));
+ }
+
+ return m_lineBreak;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/BreakingContextInlineHeaders.h b/chromium/third_party/WebKit/Source/core/rendering/line/BreakingContextInlineHeaders.h
index 989d7e3cfd0..fba56c6fa7c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/line/BreakingContextInlineHeaders.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/BreakingContextInlineHeaders.h
@@ -26,183 +26,25 @@
#include "core/rendering/InlineIterator.h"
#include "core/rendering/InlineTextBox.h"
-#include "core/rendering/LineWidth.h"
#include "core/rendering/RenderCombineText.h"
#include "core/rendering/RenderInline.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderListMarker.h"
+#include "core/rendering/RenderRubyRun.h"
#include "core/rendering/break_lines.h"
+#include "core/rendering/line/LineBreaker.h"
#include "core/rendering/line/LineInfo.h"
-#include "core/rendering/shapes/ShapeInsideInfo.h"
+#include "core/rendering/line/LineWidth.h"
+#include "core/rendering/line/RenderTextInfo.h"
+#include "core/rendering/line/TrailingObjects.h"
+#include "core/rendering/line/WordMeasurement.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
namespace WebCore {
-using namespace std;
-using namespace WTF;
-using namespace Unicode;
-
// We don't let our line box tree for a single line get any deeper than this.
const unsigned cMaxLineDepth = 200;
-struct RenderTextInfo {
- // Destruction of m_layout requires TextLayout to be a complete type, so the constructor and destructor are made non-inline to avoid compilation errors.
- RenderTextInfo();
- ~RenderTextInfo();
-
- RenderText* m_text;
- OwnPtr<TextLayout> m_layout;
- LazyLineBreakIterator m_lineBreakIterator;
- const Font* m_font;
-
- void createLayout(RenderText* renderText, float xPos, bool collapseWhiteSpace)
- {
-#if OS(MACOSX)
- m_layout = m_font->createLayoutForMacComplexText(RenderBlockFlow::constructTextRun(renderText, *m_font, renderText, renderText->style()), renderText->textLength(), xPos, collapseWhiteSpace);
-#else
- m_layout = nullptr;
-#endif
- }
-};
-
-class WordMeasurement {
-public:
- WordMeasurement()
- : renderer(0)
- , width(0)
- , startOffset(0)
- , endOffset(0)
- {
- }
-
- RenderText* renderer;
- float width;
- int startOffset;
- int endOffset;
- HashSet<const SimpleFontData*> fallbackFonts;
-};
-
-// Don't call this directly. Use one of the descriptive helper functions below.
-inline void deprecatedAddMidpoint(LineMidpointState& lineMidpointState, const InlineIterator& midpoint)
-{
- if (lineMidpointState.midpoints.size() <= lineMidpointState.numMidpoints)
- lineMidpointState.midpoints.grow(lineMidpointState.numMidpoints + 10);
-
- InlineIterator* midpoints = lineMidpointState.midpoints.data();
- midpoints[lineMidpointState.numMidpoints++] = midpoint;
-}
-
-inline void startIgnoringSpaces(LineMidpointState& lineMidpointState, const InlineIterator& midpoint)
-{
- ASSERT(!(lineMidpointState.numMidpoints % 2));
- deprecatedAddMidpoint(lineMidpointState, midpoint);
-}
-
-inline void stopIgnoringSpaces(LineMidpointState& lineMidpointState, const InlineIterator& midpoint)
-{
- ASSERT(lineMidpointState.numMidpoints % 2);
- deprecatedAddMidpoint(lineMidpointState, midpoint);
-}
-
-// When ignoring spaces, this needs to be called for objects that need line boxes such as RenderInlines or
-// hard line breaks to ensure that they're not ignored.
-inline void ensureLineBoxInsideIgnoredSpaces(LineMidpointState& lineMidpointState, RenderObject* renderer)
-{
- InlineIterator midpoint(0, renderer, 0);
- stopIgnoringSpaces(lineMidpointState, midpoint);
- startIgnoringSpaces(lineMidpointState, midpoint);
-}
-
-// Adding a pair of midpoints before a character will split it out into a new line box.
-inline void ensureCharacterGetsLineBox(LineMidpointState& lineMidpointState, InlineIterator& textParagraphSeparator)
-{
- InlineIterator midpoint(0, textParagraphSeparator.object(), textParagraphSeparator.m_pos);
- startIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparator.object(), textParagraphSeparator.m_pos - 1));
- stopIgnoringSpaces(lineMidpointState, InlineIterator(0, textParagraphSeparator.object(), textParagraphSeparator.m_pos));
-}
-
-class TrailingObjects {
-public:
- TrailingObjects();
- void setTrailingWhitespace(RenderText*);
- void clear();
- void appendBoxIfNeeded(RenderBox*);
-
- enum CollapseFirstSpaceOrNot { DoNotCollapseFirstSpace, CollapseFirstSpace };
-
- void updateMidpointsForTrailingBoxes(LineMidpointState&, const InlineIterator& lBreak, CollapseFirstSpaceOrNot);
-
-private:
- RenderText* m_whitespace;
- Vector<RenderBox*, 4> m_boxes;
-};
-
-TrailingObjects::TrailingObjects()
- : m_whitespace(0)
-{
-}
-
-inline void TrailingObjects::setTrailingWhitespace(RenderText* whitespace)
-{
- ASSERT(whitespace);
- m_whitespace = whitespace;
-}
-
-inline void TrailingObjects::clear()
-{
- m_whitespace = 0;
- // Using resize(0) rather than clear() here saves 2% on
- // PerformanceTests/Layout/line-layout.html because we avoid freeing and
- // re-allocating the underlying buffer repeatedly.
- m_boxes.resize(0);
-}
-
-inline void TrailingObjects::appendBoxIfNeeded(RenderBox* box)
-{
- if (m_whitespace)
- m_boxes.append(box);
-}
-
-void TrailingObjects::updateMidpointsForTrailingBoxes(LineMidpointState& lineMidpointState, const InlineIterator& lBreak, CollapseFirstSpaceOrNot collapseFirstSpace)
-{
- if (!m_whitespace)
- return;
-
- // This object is either going to be part of the last midpoint, or it is going to be the actual endpoint.
- // In both cases we just decrease our pos by 1 level to exclude the space, allowing it to - in effect - collapse into the newline.
- if (lineMidpointState.numMidpoints % 2) {
- // Find the trailing space object's midpoint.
- int trailingSpaceMidpoint = lineMidpointState.numMidpoints - 1;
- for ( ; trailingSpaceMidpoint > 0 && lineMidpointState.midpoints[trailingSpaceMidpoint].object() != m_whitespace; --trailingSpaceMidpoint) { }
- ASSERT(trailingSpaceMidpoint >= 0);
- if (collapseFirstSpace == CollapseFirstSpace)
- lineMidpointState.midpoints[trailingSpaceMidpoint].m_pos--;
-
- // Now make sure every single trailingPositionedBox following the trailingSpaceMidpoint properly stops and starts
- // ignoring spaces.
- size_t currentMidpoint = trailingSpaceMidpoint + 1;
- for (size_t i = 0; i < m_boxes.size(); ++i) {
- if (currentMidpoint >= lineMidpointState.numMidpoints) {
- // We don't have a midpoint for this box yet.
- ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]);
- } else {
- ASSERT(lineMidpointState.midpoints[currentMidpoint].object() == m_boxes[i]);
- ASSERT(lineMidpointState.midpoints[currentMidpoint + 1].object() == m_boxes[i]);
- }
- currentMidpoint += 2;
- }
- } else if (!lBreak.object()) {
- ASSERT(m_whitespace->isText());
- ASSERT(collapseFirstSpace == CollapseFirstSpace);
- // Add a new end midpoint that stops right at the very end.
- unsigned length = m_whitespace->textLength();
- unsigned pos = length >= 2 ? length - 2 : UINT_MAX;
- InlineIterator endMid(0, m_whitespace, pos);
- startIgnoringSpaces(lineMidpointState, endMid);
- for (size_t i = 0; i < m_boxes.size(); ++i) {
- ensureLineBoxInsideIgnoredSpaces(lineMidpointState, m_boxes[i]);
- }
- }
-}
-
class BreakingContext {
public:
BreakingContext(InlineBidiResolver& resolver, LineInfo& inLineInfo, LineWidth& lineWidth, RenderTextInfo& inRenderTextInfo, FloatingObject* inLastFloatFromPreviousLine, bool appliedStartWidth, RenderBlockFlow* block)
@@ -309,8 +151,6 @@ private:
TrailingObjects m_trailingObjects;
};
-enum WhitespacePosition { LeadingWhitespace, TrailingWhitespace };
-
inline bool shouldCollapseWhiteSpace(const RenderStyle* style, const LineInfo& lineInfo, WhitespacePosition whitespacePosition)
{
// CSS2 16.6.1
@@ -441,7 +281,7 @@ inline void BreakingContext::handleBR(EClear& clear)
// need to check for floats to clear - so if we're ignoring spaces, stop ignoring them and add a
// run for this object.
if (m_ignoringSpaces && m_currentStyle->clear() != CNONE)
- ensureLineBoxInsideIgnoredSpaces(m_lineMidpointState, br);
+ m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(br);
if (!m_lineInfo.isEmpty())
clear = m_currentStyle->clear();
@@ -495,7 +335,7 @@ inline void BreakingContext::handleOutOfFlowPositioned(Vector<RenderBox*>& posit
RenderBox* box = toRenderBox(m_current.object());
bool isInlineType = box->style()->isOriginalDisplayInlineType();
if (!isInlineType) {
- m_block->setStaticInlinePositionForChild(box, m_block->logicalHeight(), m_block->startOffsetForContent(m_block->logicalHeight()));
+ m_block->setStaticInlinePositionForChild(box, m_block->logicalHeight(), m_block->startOffsetForContent());
} else {
// If our original display was an INLINE type, then we can go ahead
// and determine our static y position now.
@@ -506,12 +346,12 @@ inline void BreakingContext::handleOutOfFlowPositioned(Vector<RenderBox*>& posit
// then start ignoring spaces again.
if (isInlineType || box->container()->isRenderInline()) {
if (m_ignoringSpaces)
- ensureLineBoxInsideIgnoredSpaces(m_lineMidpointState, box);
- m_trailingObjects.appendBoxIfNeeded(box);
+ m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(box);
+ m_trailingObjects.appendObjectIfNeeded(box);
} else {
positionedObjects.append(box);
}
- m_width.addUncommittedWidth(inlineLogicalWidth(box));
+ m_width.addUncommittedWidth(inlineLogicalWidth(box).toFloat());
// Reset prior line break context characters.
m_renderTextInfo.m_lineBreakIterator.resetPriorContext();
}
@@ -524,10 +364,10 @@ inline void BreakingContext::handleFloat()
// If it does, position it now, otherwise, position
// it after moving to next line (in newLine() func)
// FIXME: Bug 110372: Properly position multiple stacked floats with non-rectangular shape outside.
- if (m_floatsFitOnLine && m_width.fitsOnLine(m_block->logicalWidthForFloat(floatingObject))) {
+ if (m_floatsFitOnLine && m_width.fitsOnLine(m_block->logicalWidthForFloat(floatingObject).toFloat(), ExcludeWhitespace)) {
m_block->positionNewFloatOnLine(floatingObject, m_lastFloatFromPreviousLine, m_lineInfo, m_width);
if (m_lineBreak.object() == m_current.object()) {
- ASSERT(!m_lineBreak.m_pos);
+ ASSERT(!m_lineBreak.offset());
m_lineBreak.increment();
}
} else {
@@ -549,7 +389,7 @@ inline bool shouldSkipWhitespaceAfterStartObject(RenderBlockFlow* block, RenderO
RenderText* nextText = toRenderText(next);
UChar nextChar = nextText->characterAt(0);
if (nextText->style()->isCollapsibleWhiteSpace(nextChar)) {
- startIgnoringSpaces(lineMidpointState, InlineIterator(0, o, 0));
+ lineMidpointState.startIgnoringSpaces(InlineIterator(0, o, 0));
return true;
}
}
@@ -564,29 +404,31 @@ inline void BreakingContext::handleEmptyInline()
RenderInline* flowBox = toRenderInline(m_current.object());
- // Now that some inline flows have line boxes, if we are already ignoring spaces, we need
- // to make sure that we stop to include this object and then start ignoring spaces again.
- // If this object is at the start of the line, we need to behave like list markers and
- // start ignoring spaces.
bool requiresLineBox = alwaysRequiresLineBox(m_current.object());
if (requiresLineBox || requiresLineBoxForContent(flowBox, m_lineInfo)) {
- // An empty inline that only has line-height, vertical-align or font-metrics will only get a
- // line box to affect the height of the line if the rest of the line is not empty.
+ // An empty inline that only has line-height, vertical-align or font-metrics will
+ // not force linebox creation (and thus affect the height of the line) if the rest of the line is empty.
if (requiresLineBox)
m_lineInfo.setEmpty(false, m_block, &m_width);
if (m_ignoringSpaces) {
+ // If we are in a run of ignored spaces then ensure we get a linebox if lineboxes are eventually
+ // created for the line...
m_trailingObjects.clear();
- ensureLineBoxInsideIgnoredSpaces(m_lineMidpointState, m_current.object());
+ m_lineMidpointState.ensureLineBoxInsideIgnoredSpaces(m_current.object());
} else if (m_blockStyle->collapseWhiteSpace() && m_resolver.position().object() == m_current.object()
&& shouldSkipWhitespaceAfterStartObject(m_block, m_current.object(), m_lineMidpointState)) {
- // Like with list markers, we start ignoring spaces to make sure that any
- // additional spaces we see will be discarded.
+ // If this object is at the start of the line, we need to behave like list markers and
+ // start ignoring spaces.
m_currentCharacterShouldCollapseIfPreWap = m_currentCharacterIsSpace = true;
m_ignoringSpaces = true;
+ } else {
+ // If we are after a trailing space but aren't ignoring spaces yet then ensure we get a linebox
+ // if we encounter collapsible whitepace.
+ m_trailingObjects.appendObjectIfNeeded(m_current.object());
}
}
- m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox));
+ m_width.addUncommittedWidth((inlineLogicalWidth(m_current.object()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox)).toFloat());
}
inline void BreakingContext::handleReplaced()
@@ -603,7 +445,7 @@ inline void BreakingContext::handleReplaced()
}
if (m_ignoringSpaces)
- stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.object(), 0));
+ m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.object(), 0));
m_lineInfo.setEmpty(false, m_block, &m_width);
m_ignoringSpaces = false;
@@ -621,9 +463,9 @@ inline void BreakingContext::handleReplaced()
m_ignoringSpaces = true;
}
if (toRenderListMarker(m_current.object())->isInside())
- m_width.addUncommittedWidth(replacedLogicalWidth);
+ m_width.addUncommittedWidth(replacedLogicalWidth.toFloat());
} else {
- m_width.addUncommittedWidth(replacedLogicalWidth);
+ m_width.addUncommittedWidth(replacedLogicalWidth.toFloat());
}
if (m_current.object()->isRubyRun())
m_width.applyOverhang(toRenderRubyRun(m_current.object()), m_lastObject, m_nextObject);
@@ -633,7 +475,7 @@ inline void BreakingContext::handleReplaced()
inline bool iteratorIsBeyondEndOfRenderCombineText(const InlineIterator& iter, RenderCombineText* renderer)
{
- return iter.object() == renderer && iter.m_pos >= renderer->textLength();
+ return iter.object() == renderer && iter.offset() >= renderer->textLength();
}
inline void nextCharacter(UChar& currentCharacter, UChar& lastCharacter, UChar& secondToLastCharacter)
@@ -651,66 +493,26 @@ inline float firstPositiveWidth(const WordMeasurements& wordMeasurements)
return 0;
}
-inline void updateSegmentsForShapes(RenderBlockFlow* block, const FloatingObject* lastFloatFromPreviousLine, const WordMeasurements& wordMeasurements, LineWidth& width, bool isFirstLine)
+inline float measureHyphenWidth(RenderText* renderer, const Font& font, TextDirection textDirection)
{
- ASSERT(lastFloatFromPreviousLine);
-
- ShapeInsideInfo* shapeInsideInfo = block->layoutShapeInsideInfo();
- if (!lastFloatFromPreviousLine->isPlaced() || !shapeInsideInfo)
- return;
-
- bool isHorizontalWritingMode = block->isHorizontalWritingMode();
- LayoutUnit logicalOffsetFromShapeContainer = block->logicalOffsetFromShapeAncestorContainer(shapeInsideInfo->owner()).height();
-
- LayoutUnit lineLogicalTop = block->logicalHeight() + logicalOffsetFromShapeContainer;
- LayoutUnit lineLogicalHeight = block->lineHeight(isFirstLine, isHorizontalWritingMode ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
- LayoutUnit lineLogicalBottom = lineLogicalTop + lineLogicalHeight;
-
- LayoutUnit floatLogicalTop = block->logicalTopForFloat(lastFloatFromPreviousLine);
- LayoutUnit floatLogicalBottom = block->logicalBottomForFloat(lastFloatFromPreviousLine);
-
- bool lineOverlapsWithFloat = (floatLogicalTop < lineLogicalBottom) && (lineLogicalTop < floatLogicalBottom);
- if (!lineOverlapsWithFloat)
- return;
-
- float minSegmentWidth = firstPositiveWidth(wordMeasurements);
-
- LayoutUnit floatLogicalWidth = block->logicalWidthForFloat(lastFloatFromPreviousLine);
- LayoutUnit availableLogicalWidth = block->logicalWidth() - block->logicalRightForFloat(lastFloatFromPreviousLine);
- if (availableLogicalWidth < minSegmentWidth)
- block->setLogicalHeight(floatLogicalBottom);
-
- if (block->logicalHeight() < floatLogicalTop) {
- shapeInsideInfo->adjustLogicalLineTop(minSegmentWidth + floatLogicalWidth);
- block->setLogicalHeight(shapeInsideInfo->logicalLineTop() - logicalOffsetFromShapeContainer);
- }
-
- lineLogicalTop = block->logicalHeight() + logicalOffsetFromShapeContainer;
-
- shapeInsideInfo->updateSegmentsForLine(lineLogicalTop, lineLogicalHeight);
- width.updateCurrentShapeSegment();
- width.updateAvailableWidth();
+ RenderStyle* style = renderer->style();
+ return font.width(RenderBlockFlow::constructTextRun(renderer, font,
+ style->hyphenString().string(), style, style->direction()));
}
-inline float measureHyphenWidth(RenderText* renderer, const Font& font)
+ALWAYS_INLINE TextDirection textDirectionFromUnicode(WTF::Unicode::Direction direction)
{
- RenderStyle* style = renderer->style();
- return font.width(RenderBlockFlow::constructTextRun(renderer, font, style->hyphenString().string(), style));
+ return direction == WTF::Unicode::RightToLeft
+ || direction == WTF::Unicode::RightToLeftArabic ? RTL : LTR;
}
-ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, HashSet<const SimpleFontData*>* fallbackFonts = 0, TextLayout* layout = 0)
+ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, HashSet<const SimpleFontData*>* fallbackFonts = 0)
{
GlyphOverflow glyphOverflow;
if (isFixedPitch || (!from && len == text->textLength()) || text->style()->hasTextCombine())
- return text->width(from, len, font, xPos, fallbackFonts, &glyphOverflow);
-
- if (layout)
- return Font::width(*layout, from, len, fallbackFonts);
+ return text->width(from, len, font, xPos, text->style()->direction(), fallbackFonts, &glyphOverflow);
TextRun run = RenderBlockFlow::constructTextRun(text, font, text, from, len, text->style());
- run.setCharactersLength(text->textLength() - from);
- ASSERT(run.charactersLength() >= run.length());
-
run.setCharacterScanForCodePath(!text->canUseSimpleFontCodePath());
run.setTabSize(!collapseWhiteSpace, text->style()->tabSize());
run.setXPos(xPos);
@@ -719,13 +521,20 @@ ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, con
inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool& hyphenated)
{
- if (!m_current.m_pos)
+ if (!m_current.offset())
m_appliedStartWidth = false;
RenderText* renderText = toRenderText(m_current.object());
bool isSVGText = renderText->isSVGInlineText();
+ // If we have left a no-wrap inline and entered an autowrap inline while ignoring spaces
+ // then we need to mark the start of the autowrap inline as a potential linebreak now.
+ if (m_autoWrap && !RenderStyle::autoWrap(m_lastWS) && m_ignoringSpaces) {
+ m_width.commit();
+ m_lineBreak.moveToStartOf(m_current.object());
+ }
+
if (renderText->style()->hasTextCombine() && m_current.object()->isCombineText() && !toRenderCombineText(m_current.object())->isCombined()) {
RenderCombineText* combineRenderer = toRenderCombineText(m_current.object());
combineRenderer->combineText();
@@ -741,7 +550,7 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
const Font& font = style->font();
bool isFixedPitch = font.isFixedPitch();
- unsigned lastSpace = m_current.m_pos;
+ unsigned lastSpace = m_current.offset();
float wordSpacing = m_currentStyle->wordSpacing();
float lastSpaceWordSpacing = 0;
float wordSpacingForWordMeasurement = 0;
@@ -763,28 +572,28 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
if (renderText->isWordBreak()) {
m_width.commit();
m_lineBreak.moveToStartOf(m_current.object());
- ASSERT(m_current.m_pos == renderText->textLength());
+ ASSERT(m_current.offset() == renderText->textLength());
}
if (m_renderTextInfo.m_text != renderText) {
m_renderTextInfo.m_text = renderText;
m_renderTextInfo.m_font = &font;
- m_renderTextInfo.createLayout(renderText, m_width.currentWidth(), m_collapseWhiteSpace);
m_renderTextInfo.m_lineBreakIterator.resetStringAndReleaseIterator(renderText->text(), style->locale());
- } else if (m_renderTextInfo.m_layout && m_renderTextInfo.m_font != &font) {
+ } else if (m_renderTextInfo.m_font != &font) {
m_renderTextInfo.m_font = &font;
- m_renderTextInfo.createLayout(renderText, m_width.currentWidth(), m_collapseWhiteSpace);
}
- TextLayout* textLayout = m_renderTextInfo.m_layout.get();
-
- // Non-zero only when kerning is enabled and TextLayout isn't used, in which case we measure
+ // Non-zero only when kerning is enabled, in which case we measure
// words with their trailing space, then subtract its width.
- float wordTrailingSpaceWidth = (font.typesettingFeatures() & Kerning) && !textLayout ? font.width(RenderBlockFlow::constructTextRun(renderText, font, &space, 1, style)) + wordSpacing : 0;
+ float wordTrailingSpaceWidth = (font.fontDescription().typesettingFeatures() & Kerning) ?
+ font.width(RenderBlockFlow::constructTextRun(
+ renderText, font, &space, 1, style,
+ style->direction())) + wordSpacing
+ : 0;
UChar lastCharacter = m_renderTextInfo.m_lineBreakIterator.lastCharacter();
UChar secondToLastCharacter = m_renderTextInfo.m_lineBreakIterator.secondToLastCharacter();
- for (; m_current.m_pos < renderText->textLength(); m_current.fastIncrementInTextNode()) {
+ for (; m_current.offset() < renderText->textLength(); m_current.fastIncrementInTextNode()) {
bool previousCharacterIsSpace = m_currentCharacterIsSpace;
bool previousCharacterShouldCollapseIfPreWap = m_currentCharacterShouldCollapseIfPreWap;
UChar c = m_current.current();
@@ -794,7 +603,7 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
m_lineInfo.setEmpty(false, m_block, &m_width);
if (c == softHyphen && m_autoWrap && !hyphenWidth) {
- hyphenWidth = measureHyphenWidth(renderText, font);
+ hyphenWidth = measureHyphenWidth(renderText, font, textDirectionFromUnicode(m_resolver.position().direction()));
m_width.addUncommittedWidth(hyphenWidth);
}
@@ -802,12 +611,14 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
if ((breakAll || breakWords) && !midWordBreak) {
wrapW += charWidth;
- bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current.m_pos + 1 < renderText->textLength() && U16_IS_TRAIL((*renderText)[m_current.m_pos + 1]);
- charWidth = textWidth(renderText, m_current.m_pos, midWordBreakIsBeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitch, m_collapseWhiteSpace, 0, textLayout);
+ bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current.offset() + 1 < renderText->textLength() && U16_IS_TRAIL((*renderText)[m_current.offset() + 1]);
+ charWidth = textWidth(renderText, m_current.offset(), midWordBreakIsBeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitch, m_collapseWhiteSpace, 0);
midWordBreak = m_width.committedWidth() + wrapW + charWidth > m_width.availableWidth();
}
- bool betweenWords = c == '\n' || (m_currWS != PRE && !m_atStart && isBreakable(m_renderTextInfo.m_lineBreakIterator, m_current.m_pos, m_current.m_nextBreakablePosition));
+ int nextBreakablePosition = m_current.nextBreakablePosition();
+ bool betweenWords = c == '\n' || (m_currWS != PRE && !m_atStart && isBreakable(m_renderTextInfo.m_lineBreakIterator, m_current.offset(), nextBreakablePosition));
+ m_current.setNextBreakablePosition(nextBreakablePosition);
if (betweenWords || midWordBreak) {
bool stoppedIgnoringSpaces = false;
@@ -818,8 +629,8 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
// new point.
m_ignoringSpaces = false;
wordSpacingForWordMeasurement = 0;
- lastSpace = m_current.m_pos; // e.g., "Foo goo", don't add in any of the ignored spaces.
- stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.object(), m_current.m_pos));
+ lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of the ignored spaces.
+ m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.object(), m_current.offset()));
stoppedIgnoringSpaces = true;
} else {
// Just keep ignoring these spaces.
@@ -832,37 +643,38 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
WordMeasurement& wordMeasurement = wordMeasurements.last();
wordMeasurement.renderer = renderText;
- wordMeasurement.endOffset = m_current.m_pos;
+ wordMeasurement.endOffset = m_current.offset();
wordMeasurement.startOffset = lastSpace;
- float additionalTmpW;
+ float additionalTempWidth;
if (wordTrailingSpaceWidth && c == ' ')
- additionalTmpW = textWidth(renderText, lastSpace, m_current.m_pos + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout) - wordTrailingSpaceWidth;
+ additionalTempWidth = textWidth(renderText, lastSpace, m_current.offset() + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts) - wordTrailingSpaceWidth;
else
- additionalTmpW = textWidth(renderText, lastSpace, m_current.m_pos - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout);
+ additionalTempWidth = textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts);
+
+ wordMeasurement.width = additionalTempWidth + wordSpacingForWordMeasurement;
+ additionalTempWidth += lastSpaceWordSpacing;
+ m_width.addUncommittedWidth(additionalTempWidth);
+
+ if (m_collapseWhiteSpace && previousCharacterIsSpace && m_currentCharacterIsSpace && additionalTempWidth)
+ m_width.setTrailingWhitespaceWidth(additionalTempWidth);
- wordMeasurement.width = additionalTmpW + wordSpacingForWordMeasurement;
- additionalTmpW += lastSpaceWordSpacing;
- m_width.addUncommittedWidth(additionalTmpW);
if (!m_appliedStartWidth) {
- m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object(), true, false));
+ m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object(), true, false).toFloat());
m_appliedStartWidth = true;
}
- if (m_lastFloatFromPreviousLine)
- updateSegmentsForShapes(m_block, m_lastFloatFromPreviousLine, wordMeasurements, m_width, m_lineInfo.isFirstLine());
-
applyWordSpacing = wordSpacing && m_currentCharacterIsSpace;
if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine())
- m_width.fitBelowFloats();
+ m_width.fitBelowFloats(m_lineInfo.isFirstLine());
if (m_autoWrap || breakWords) {
// If we break only after white-space, consider the current character
// as candidate width for this line.
bool lineWasTooWide = false;
if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_currentStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) {
- float charWidth = textWidth(renderText, m_current.m_pos, 1, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout) + (applyWordSpacing ? wordSpacing : 0);
+ float charWidth = textWidth(renderText, m_current.offset(), 1, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts) + (applyWordSpacing ? wordSpacing : 0);
// Check if line is too big even without the extra space
// at the end of the line. If it is not, do nothing.
// If the line needs the extra whitespace to be too long,
@@ -870,23 +682,23 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
// additional whitespace.
if (!m_width.fitsOnLine(charWidth)) {
lineWasTooWide = true;
- m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_current.m_nextBreakablePosition);
+ m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current.nextBreakablePosition());
skipTrailingWhitespace(m_lineBreak, m_lineInfo);
}
}
if (lineWasTooWide || !m_width.fitsOnLine()) {
if (m_lineBreak.atTextParagraphSeparator()) {
- if (!stoppedIgnoringSpaces && m_current.m_pos > 0)
- ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
+ if (!stoppedIgnoringSpaces && m_current.offset() > 0)
+ m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
m_lineBreak.increment();
m_lineInfo.setPreviousLineBrokeCleanly(true);
- wordMeasurement.endOffset = m_lineBreak.m_pos;
+ wordMeasurement.endOffset = m_lineBreak.offset();
}
- if (m_lineBreak.object() && m_lineBreak.m_pos && m_lineBreak.object()->isText() && toRenderText(m_lineBreak.object())->textLength() && toRenderText(m_lineBreak.object())->characterAt(m_lineBreak.m_pos - 1) == softHyphen)
+ if (m_lineBreak.object() && m_lineBreak.offset() && m_lineBreak.object()->isText() && toRenderText(m_lineBreak.object())->textLength() && toRenderText(m_lineBreak.object())->characterAt(m_lineBreak.offset() - 1) == softHyphen)
hyphenated = true;
- if (m_lineBreak.m_pos && m_lineBreak.m_pos != (unsigned)wordMeasurement.endOffset && !wordMeasurement.width) {
+ if (m_lineBreak.offset() && m_lineBreak.offset() != (unsigned)wordMeasurement.endOffset && !wordMeasurement.width) {
if (charWidth) {
- wordMeasurement.endOffset = m_lineBreak.m_pos;
+ wordMeasurement.endOffset = m_lineBreak.offset();
wordMeasurement.width = charWidth;
}
}
@@ -897,7 +709,7 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
}
} else {
if (!betweenWords || (midWordBreak && !m_autoWrap))
- m_width.addUncommittedWidth(-additionalTmpW);
+ m_width.addUncommittedWidth(-additionalTempWidth);
if (hyphenWidth) {
// Subtract the width of the soft hyphen out since we fit on a line.
m_width.addUncommittedWidth(-hyphenWidth);
@@ -907,9 +719,9 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
}
if (c == '\n' && m_preservesNewline) {
- if (!stoppedIgnoringSpaces && m_current.m_pos > 0)
- ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
- m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_current.m_nextBreakablePosition);
+ if (!stoppedIgnoringSpaces && m_current.offset())
+ m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
+ m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current.nextBreakablePosition());
m_lineBreak.increment();
m_lineInfo.setPreviousLineBrokeCleanly(true);
return true;
@@ -918,23 +730,23 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
if (m_autoWrap && betweenWords) {
m_width.commit();
wrapW = 0;
- m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_current.m_nextBreakablePosition);
+ m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current.nextBreakablePosition());
// Auto-wrapping text should not wrap in the middle of a word once it has had an
// opportunity to break after a word.
breakWords = false;
}
- if (midWordBreak && !U16_IS_TRAIL(c) && !(category(c) & (Mark_NonSpacing | Mark_Enclosing | Mark_SpacingCombining))) {
+ if (midWordBreak && !U16_IS_TRAIL(c) && !(WTF::Unicode::category(c) & (WTF::Unicode::Mark_NonSpacing | WTF::Unicode::Mark_Enclosing | WTF::Unicode::Mark_SpacingCombining))) {
// Remember this as a breakable position in case
// adding the end width forces a break.
- m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_current.m_nextBreakablePosition);
+ m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current.nextBreakablePosition());
midWordBreak &= (breakWords || breakAll);
}
if (betweenWords) {
lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurement.width) ? wordSpacing : 0;
- lastSpace = m_current.m_pos;
+ lastSpace = m_current.offset();
}
if (!m_ignoringSpaces && m_currentStyle->collapseWhiteSpace()) {
@@ -947,8 +759,8 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
// We just entered a mode where we are ignoring
// spaces. Create a midpoint to terminate the run
// before the second space.
- startIgnoringSpaces(m_lineMidpointState, m_startOfIgnoredSpaces);
- m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
+ m_lineMidpointState.startIgnoringSpaces(m_startOfIgnoredSpaces);
+ m_trailingObjects.updateMidpointsForTrailingObjects(m_lineMidpointState, InlineIterator(), TrailingObjects::DoNotCollapseFirstSpace);
}
}
} else if (m_ignoringSpaces) {
@@ -957,24 +769,24 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
m_ignoringSpaces = false;
lastSpaceWordSpacing = applyWordSpacing ? wordSpacing : 0;
wordSpacingForWordMeasurement = (applyWordSpacing && wordMeasurements.last().width) ? wordSpacing : 0;
- lastSpace = m_current.m_pos; // e.g., "Foo goo", don't add in any of the ignored spaces.
- stopIgnoringSpaces(m_lineMidpointState, InlineIterator(0, m_current.object(), m_current.m_pos));
+ lastSpace = m_current.offset(); // e.g., "Foo goo", don't add in any of the ignored spaces.
+ m_lineMidpointState.stopIgnoringSpaces(InlineIterator(0, m_current.object(), m_current.offset()));
}
- if (isSVGText && m_current.m_pos > 0) {
+ if (isSVGText && m_current.offset()) {
// Force creation of new InlineBoxes for each absolute positioned character (those that start new text chunks).
- if (toRenderSVGInlineText(renderText)->characterStartsNewTextChunk(m_current.m_pos))
- ensureCharacterGetsLineBox(m_lineMidpointState, m_current);
+ if (toRenderSVGInlineText(renderText)->characterStartsNewTextChunk(m_current.offset()))
+ m_lineMidpointState.ensureCharacterGetsLineBox(m_current);
}
if (m_currentCharacterIsSpace && !previousCharacterIsSpace) {
m_startOfIgnoredSpaces.setObject(m_current.object());
- m_startOfIgnoredSpaces.m_pos = m_current.m_pos;
+ m_startOfIgnoredSpaces.setOffset(m_current.offset());
}
if (!m_currentCharacterIsSpace && previousCharacterShouldCollapseIfPreWap) {
if (m_autoWrap && m_currentStyle->breakOnlyAfterWhiteSpace())
- m_lineBreak.moveTo(m_current.object(), m_current.m_pos, m_current.m_nextBreakablePosition);
+ m_lineBreak.moveTo(m_current.object(), m_current.offset(), m_current.nextBreakablePosition());
}
if (m_collapseWhiteSpace && m_currentCharacterIsSpace && !m_ignoringSpaces)
@@ -993,12 +805,18 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
wordMeasurement.renderer = renderText;
// IMPORTANT: current.m_pos is > length here!
- float additionalTmpW = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpace, m_current.m_pos - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts, textLayout);
+ float additionalTempWidth = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts);
wordMeasurement.startOffset = lastSpace;
- wordMeasurement.endOffset = m_current.m_pos;
- wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTmpW + wordSpacingForWordMeasurement;
- additionalTmpW += lastSpaceWordSpacing;
- m_width.addUncommittedWidth(additionalTmpW + inlineLogicalWidth(m_current.object(), !m_appliedStartWidth, m_includeEndWidth));
+ wordMeasurement.endOffset = m_current.offset();
+ wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTempWidth + wordSpacingForWordMeasurement;
+ additionalTempWidth += lastSpaceWordSpacing;
+
+ LayoutUnit inlineLogicalTempWidth = inlineLogicalWidth(m_current.object(), !m_appliedStartWidth, m_includeEndWidth);
+ m_width.addUncommittedWidth(additionalTempWidth + inlineLogicalTempWidth);
+
+ if (m_collapseWhiteSpace && m_currentCharacterIsSpace && additionalTempWidth)
+ m_width.setTrailingWhitespaceWidth(additionalTempWidth + inlineLogicalTempWidth);
+
m_includeEndWidth = false;
if (!m_width.fitsOnLine()) {
@@ -1031,7 +849,7 @@ inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
}
if (!m_width.fitsOnLine() && !m_width.committedWidth())
- m_width.fitBelowFloats();
+ m_width.fitBelowFloats(m_lineInfo.isFirstLine());
bool canPlaceOnLine = m_width.fitsOnLine() || !m_autoWrapWasEverTrueOnLine;
if (canPlaceOnLine && checkForBreak) {
@@ -1041,6 +859,7 @@ inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
}
}
+ ASSERT_WITH_SECURITY_IMPLICATION(m_currentStyle->refCount() > 0);
if (checkForBreak && !m_width.fitsOnLine()) {
// if we have floats, try to get below them.
if (m_currentCharacterIsSpace && !m_ignoringSpaces && m_currentStyle->collapseWhiteSpace())
@@ -1051,7 +870,7 @@ inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
return;
}
- m_width.fitBelowFloats();
+ m_width.fitBelowFloats(m_lineInfo.isFirstLine());
// |width| may have been adjusted because we got shoved down past a float (thus
// giving us more room), so we need to retest, and only jump to
@@ -1063,7 +882,7 @@ inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
} else if (m_blockStyle->autoWrap() && !m_width.fitsOnLine() && !m_width.committedWidth()) {
// If the container autowraps but the current child does not then we still need to ensure that it
// wraps and moves below any floats.
- m_width.fitBelowFloats();
+ m_width.fitBelowFloats(m_lineInfo.isFirstLine());
}
if (!m_current.object()->isFloatingOrOutOfFlowPositioned()) {
@@ -1075,69 +894,16 @@ inline void BreakingContext::commitAndUpdateLineBreakIfNeeded()
}
}
-inline void checkMidpoints(LineMidpointState& lineMidpointState, InlineIterator& lBreak)
-{
- // Check to see if our last midpoint is a start point beyond the line break. If so,
- // shave it off the list, and shave off a trailing space if the previous end point doesn't
- // preserve whitespace.
- if (lBreak.object() && lineMidpointState.numMidpoints && !(lineMidpointState.numMidpoints % 2)) {
- InlineIterator* midpoints = lineMidpointState.midpoints.data();
- InlineIterator& endpoint = midpoints[lineMidpointState.numMidpoints - 2];
- const InlineIterator& startpoint = midpoints[lineMidpointState.numMidpoints - 1];
- InlineIterator currpoint = endpoint;
- while (!currpoint.atEnd() && currpoint != startpoint && currpoint != lBreak)
- currpoint.increment();
- if (currpoint == lBreak) {
- // We hit the line break before the start point. Shave off the start point.
- lineMidpointState.numMidpoints--;
- if (endpoint.object()->style()->collapseWhiteSpace() && endpoint.object()->isText())
- endpoint.m_pos--;
- }
- }
-}
-
-InlineIterator BreakingContext::handleEndOfLine()
+inline IndentTextOrNot requiresIndent(bool isFirstLine, bool isAfterHardLineBreak, RenderStyle* style)
{
- ShapeInsideInfo* shapeInfo = m_block->layoutShapeInsideInfo();
- bool segmentAllowsOverflow = !shapeInfo || !shapeInfo->hasSegments();
-
- if (m_lineBreak == m_resolver.position() && (!m_lineBreak.object() || !m_lineBreak.object()->isBR()) && segmentAllowsOverflow) {
- // we just add as much as possible
- if (m_blockStyle->whiteSpace() == PRE && !m_current.m_pos) {
- m_lineBreak.moveTo(m_lastObject, m_lastObject->isText() ? m_lastObject->length() : 0);
- } else if (m_lineBreak.object()) {
- // Don't ever break in the middle of a word if we can help it.
- // There's no room at all. We just have to be on this line,
- // even though we'll spill out.
- m_lineBreak.moveTo(m_current.object(), m_current.m_pos);
- }
- }
+ IndentTextOrNot shouldIndentText = DoNotIndentText;
+ if (isFirstLine || (isAfterHardLineBreak && style->textIndentLine()) == TextIndentEachLine)
+ shouldIndentText = IndentText;
- // FIXME Bug 100049: We do not need to consume input in a multi-segment line
- // unless no segment will.
- // make sure we consume at least one char/object.
- if (m_lineBreak == m_resolver.position() && segmentAllowsOverflow)
- m_lineBreak.increment();
-
- // Sanity check our midpoints.
- checkMidpoints(m_lineMidpointState, m_lineBreak);
-
- m_trailingObjects.updateMidpointsForTrailingBoxes(m_lineMidpointState, m_lineBreak, TrailingObjects::CollapseFirstSpace);
-
- // We might have made lineBreak an iterator that points past the end
- // of the object. Do this adjustment to make it point to the start
- // of the next object instead to avoid confusing the rest of the
- // code.
- if (m_lineBreak.m_pos > 0) {
- // This loop enforces the invariant that line breaks should never point
- // at an empty inline. See http://crbug.com/305904.
- do {
- m_lineBreak.m_pos--;
- m_lineBreak.increment();
- } while (!m_lineBreak.atEnd() && isEmptyInline(m_lineBreak.object()));
- }
+ if (style->textIndentType() == TextIndentHanging)
+ shouldIndentText = shouldIndentText == IndentText ? DoNotIndentText : IndentText;
- return m_lineBreak;
+ return shouldIndentText;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp b/chromium/third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp
new file mode 100644
index 00000000000..074aafe5a4b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/rendering/line/LineBreaker.h"
+
+#include "core/rendering/line/BreakingContextInlineHeaders.h"
+
+namespace WebCore {
+
+void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo,
+ FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
+{
+ while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
+ RenderObject* object = resolver.position().object();
+ if (object->isOutOfFlowPositioned()) {
+ setStaticPositions(m_block, toRenderBox(object));
+ if (object->style()->isOriginalDisplayInlineType()) {
+ resolver.runs().addRun(createRun(0, 1, object, resolver));
+ lineInfo.incrementRunsFromLeadingWhitespace();
+ }
+ } else if (object->isFloating()) {
+ m_block->positionNewFloatOnLine(m_block->insertFloatingObject(toRenderBox(object)), lastFloatFromPreviousLine, lineInfo, width);
+ } else if (object->isText() && object->style()->hasTextCombine() && object->isCombineText() && !toRenderCombineText(object)->isCombined()) {
+ toRenderCombineText(object)->combineText();
+ if (toRenderCombineText(object)->isCombined())
+ continue;
+ }
+ resolver.position().increment(&resolver);
+ }
+ resolver.commitExplicitEmbedding();
+}
+
+void LineBreaker::reset()
+{
+ m_positionedObjects.clear();
+ m_hyphenated = false;
+ m_clear = CNONE;
+}
+
+InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo, RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements& wordMeasurements)
+{
+ reset();
+
+ ASSERT(resolver.position().root() == m_block);
+
+ bool appliedStartWidth = resolver.position().offset() > 0;
+
+ LineWidth width(*m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isFirstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style()));
+
+ skipLeadingWhitespace(resolver, lineInfo, lastFloatFromPreviousLine, width);
+
+ if (resolver.position().atEnd())
+ return resolver.position();
+
+ BreakingContext context(resolver, lineInfo, width, renderTextInfo, lastFloatFromPreviousLine, appliedStartWidth, m_block);
+
+ while (context.currentObject()) {
+ context.initializeForCurrentObject();
+ if (context.currentObject()->isBR()) {
+ context.handleBR(m_clear);
+ } else if (context.currentObject()->isOutOfFlowPositioned()) {
+ context.handleOutOfFlowPositioned(m_positionedObjects);
+ } else if (context.currentObject()->isFloating()) {
+ context.handleFloat();
+ } else if (context.currentObject()->isRenderInline()) {
+ context.handleEmptyInline();
+ } else if (context.currentObject()->isReplaced()) {
+ context.handleReplaced();
+ } else if (context.currentObject()->isText()) {
+ if (context.handleText(wordMeasurements, m_hyphenated)) {
+ // We've hit a hard text line break. Our line break iterator is updated, so go ahead and early return.
+ return context.lineBreak();
+ }
+ } else {
+ ASSERT_NOT_REACHED();
+ }
+
+ if (context.atEnd())
+ return context.handleEndOfLine();
+
+ context.commitAndUpdateLineBreakIfNeeded();
+
+ if (context.atEnd())
+ return context.handleEndOfLine();
+
+ context.increment();
+ }
+
+ context.clearLineBreakIfFitsOnLine();
+
+ return context.handleEndOfLine();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/LineBreaker.h b/chromium/third_party/WebKit/Source/core/rendering/line/LineBreaker.h
new file mode 100644
index 00000000000..2cb519205df
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/LineBreaker.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LineBreaker_h
+#define LineBreaker_h
+
+#include "core/rendering/InlineIterator.h"
+#include "core/rendering/line/LineInfo.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+enum WhitespacePosition { LeadingWhitespace, TrailingWhitespace };
+
+struct RenderTextInfo;
+
+class LineBreaker {
+public:
+ friend class BreakingContext;
+ LineBreaker(RenderBlockFlow* block)
+ : m_block(block)
+ {
+ reset();
+ }
+
+ InlineIterator nextLineBreak(InlineBidiResolver&, LineInfo&, RenderTextInfo&, FloatingObject* lastFloatFromPreviousLine, unsigned consecutiveHyphenatedLines, WordMeasurements&);
+
+ bool lineWasHyphenated() { return m_hyphenated; }
+ const Vector<RenderBox*>& positionedObjects() { return m_positionedObjects; }
+ EClear clear() { return m_clear; }
+private:
+ void reset();
+
+ void skipLeadingWhitespace(InlineBidiResolver&, LineInfo&, FloatingObject* lastFloatFromPreviousLine, LineWidth&);
+
+ RenderBlockFlow* m_block;
+ bool m_hyphenated;
+ EClear m_clear;
+ Vector<RenderBox*> m_positionedObjects;
+};
+
+}
+
+#endif // LineBreaker_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/LineInfo.h b/chromium/third_party/WebKit/Source/core/rendering/line/LineInfo.h
index 337da116e8b..bd5ad169678 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/line/LineInfo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/LineInfo.h
@@ -24,6 +24,8 @@
#ifndef LineInfo_h
#define LineInfo_h
+#include "core/rendering/line/LineWidth.h"
+
namespace WebCore {
class LineInfo {
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/LineLayoutState.h b/chromium/third_party/WebKit/Source/core/rendering/line/LineLayoutState.h
new file mode 100644
index 00000000000..b62adcd9bd6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/LineLayoutState.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LineLayoutState_h
+#define LineLayoutState_h
+
+#include "core/rendering/RenderBlockFlow.h"
+#include "platform/geometry/LayoutRect.h"
+
+namespace WebCore {
+
+// Like LayoutState for layout(), LineLayoutState keeps track of global information
+// during an entire linebox tree layout pass (aka layoutInlineChildren).
+class LineLayoutState {
+public:
+ LineLayoutState(bool fullLayout, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, RenderFlowThread* flowThread)
+ : m_lastFloat(0)
+ , m_endLine(0)
+ , m_floatIndex(0)
+ , m_endLineLogicalTop(0)
+ , m_endLineMatched(false)
+ , m_checkForFloatsFromLastLine(false)
+ , m_hasInlineChild(false)
+ , m_isFullLayout(fullLayout)
+ , m_repaintLogicalTop(repaintLogicalTop)
+ , m_repaintLogicalBottom(repaintLogicalBottom)
+ , m_adjustedLogicalLineTop(0)
+ , m_usesRepaintBounds(false)
+ , m_flowThread(flowThread)
+ { }
+
+ void markForFullLayout() { m_isFullLayout = true; }
+ bool isFullLayout() const { return m_isFullLayout; }
+
+ bool usesRepaintBounds() const { return m_usesRepaintBounds; }
+
+ void setRepaintRange(LayoutUnit logicalHeight)
+ {
+ m_usesRepaintBounds = true;
+ m_repaintLogicalTop = m_repaintLogicalBottom = logicalHeight;
+ }
+
+ void updateRepaintRangeFromBox(RootInlineBox* box, LayoutUnit paginationDelta = 0)
+ {
+ m_usesRepaintBounds = true;
+ m_repaintLogicalTop = std::min(m_repaintLogicalTop, box->logicalTopVisualOverflow() + std::min<LayoutUnit>(paginationDelta, 0));
+ m_repaintLogicalBottom = std::max(m_repaintLogicalBottom, box->logicalBottomVisualOverflow() + std::max<LayoutUnit>(paginationDelta, 0));
+ }
+
+ bool endLineMatched() const { return m_endLineMatched; }
+ void setEndLineMatched(bool endLineMatched) { m_endLineMatched = endLineMatched; }
+
+ bool checkForFloatsFromLastLine() const { return m_checkForFloatsFromLastLine; }
+ void setCheckForFloatsFromLastLine(bool check) { m_checkForFloatsFromLastLine = check; }
+
+ bool hasInlineChild() const { return m_hasInlineChild; }
+ void setHasInlineChild(bool hasInlineChild) { m_hasInlineChild = hasInlineChild; }
+
+ LineInfo& lineInfo() { return m_lineInfo; }
+ const LineInfo& lineInfo() const { return m_lineInfo; }
+
+ LayoutUnit endLineLogicalTop() const { return m_endLineLogicalTop; }
+ void setEndLineLogicalTop(LayoutUnit logicalTop) { m_endLineLogicalTop = logicalTop; }
+
+ RootInlineBox* endLine() const { return m_endLine; }
+ void setEndLine(RootInlineBox* line) { m_endLine = line; }
+
+ FloatingObject* lastFloat() const { return m_lastFloat; }
+ void setLastFloat(FloatingObject* lastFloat) { m_lastFloat = lastFloat; }
+
+ Vector<RenderBlockFlow::FloatWithRect>& floats() { return m_floats; }
+
+ unsigned floatIndex() const { return m_floatIndex; }
+ void setFloatIndex(unsigned floatIndex) { m_floatIndex = floatIndex; }
+
+ LayoutUnit adjustedLogicalLineTop() const { return m_adjustedLogicalLineTop; }
+ void setAdjustedLogicalLineTop(LayoutUnit value) { m_adjustedLogicalLineTop = value; }
+
+ RenderFlowThread* flowThread() const { return m_flowThread; }
+ void setFlowThread(RenderFlowThread* thread) { m_flowThread = thread; }
+
+private:
+ Vector<RenderBlockFlow::FloatWithRect> m_floats;
+ FloatingObject* m_lastFloat;
+ RootInlineBox* m_endLine;
+ LineInfo m_lineInfo;
+ unsigned m_floatIndex;
+ LayoutUnit m_endLineLogicalTop;
+ bool m_endLineMatched;
+ bool m_checkForFloatsFromLastLine;
+ // Used as a performance optimization to avoid doing a full repaint when our floats
+ // change but we don't have any inline children.
+ bool m_hasInlineChild;
+
+ bool m_isFullLayout;
+
+ // FIXME: Should this be a range object instead of two ints?
+ LayoutUnit& m_repaintLogicalTop;
+ LayoutUnit& m_repaintLogicalBottom;
+
+ LayoutUnit m_adjustedLogicalLineTop;
+
+ bool m_usesRepaintBounds;
+
+ RenderFlowThread* m_flowThread;
+};
+
+}
+
+#endif // LineLayoutState_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/LineWidth.cpp b/chromium/third_party/WebKit/Source/core/rendering/line/LineWidth.cpp
new file mode 100644
index 00000000000..1b46843d9f4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/LineWidth.cpp
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/rendering/line/LineWidth.h"
+
+#include "core/rendering/RenderBlock.h"
+#include "core/rendering/RenderRubyRun.h"
+
+namespace WebCore {
+
+LineWidth::LineWidth(RenderBlockFlow& block, bool isFirstLine, IndentTextOrNot shouldIndentText)
+ : m_block(block)
+ , m_uncommittedWidth(0)
+ , m_committedWidth(0)
+ , m_overhangWidth(0)
+ , m_trailingWhitespaceWidth(0)
+ , m_left(0)
+ , m_right(0)
+ , m_availableWidth(0)
+ , m_isFirstLine(isFirstLine)
+ , m_shouldIndentText(shouldIndentText)
+{
+ updateAvailableWidth();
+}
+
+void LineWidth::updateAvailableWidth(LayoutUnit replacedHeight)
+{
+ LayoutUnit height = m_block.logicalHeight();
+ LayoutUnit logicalHeight = m_block.minLineHeightForReplacedRenderer(m_isFirstLine, replacedHeight);
+ m_left = m_block.logicalLeftOffsetForLine(height, shouldIndentText(), logicalHeight).toFloat();
+ m_right = m_block.logicalRightOffsetForLine(height, shouldIndentText(), logicalHeight).toFloat();
+
+ computeAvailableWidthFromLeftAndRight();
+}
+
+void LineWidth::shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject* newFloat)
+{
+ LayoutUnit height = m_block.logicalHeight();
+ if (height < m_block.logicalTopForFloat(newFloat) || height >= m_block.logicalBottomForFloat(newFloat))
+ return;
+
+ ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer()->shapeOutsideInfo();
+ if (shapeOutsideInfo) {
+ LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
+ shapeOutsideInfo->updateDeltasForContainingBlockLine(m_block, *newFloat, m_block.logicalHeight(), lineHeight);
+ }
+
+ if (newFloat->type() == FloatingObject::FloatLeft) {
+ float newLeft = m_block.logicalRightForFloat(newFloat).toFloat();
+ if (shapeOutsideInfo) {
+ if (shapeOutsideInfo->lineOverlapsShape())
+ newLeft += shapeOutsideInfo->rightMarginBoxDelta();
+ else // Per the CSS Shapes spec, If the line doesn't overlap the shape, then ignore this shape for this line.
+ newLeft = m_left;
+ }
+ if (shouldIndentText() && m_block.style()->isLeftToRightDirection())
+ newLeft += floorToInt(m_block.textIndentOffset());
+ m_left = std::max<float>(m_left, newLeft);
+ } else {
+ float newRight = m_block.logicalLeftForFloat(newFloat).toFloat();
+ if (shapeOutsideInfo) {
+ if (shapeOutsideInfo->lineOverlapsShape())
+ newRight += shapeOutsideInfo->leftMarginBoxDelta();
+ else // Per the CSS Shapes spec, If the line doesn't overlap the shape, then ignore this shape for this line.
+ newRight = m_right;
+ }
+ if (shouldIndentText() && !m_block.style()->isLeftToRightDirection())
+ newRight -= floorToInt(m_block.textIndentOffset());
+ m_right = std::min<float>(m_right, newRight);
+ }
+
+ computeAvailableWidthFromLeftAndRight();
+}
+
+void LineWidth::commit()
+{
+ m_committedWidth += m_uncommittedWidth;
+ m_uncommittedWidth = 0;
+}
+
+void LineWidth::applyOverhang(RenderRubyRun* rubyRun, RenderObject* startRenderer, RenderObject* endRenderer)
+{
+ int startOverhang;
+ int endOverhang;
+ rubyRun->getOverhang(m_isFirstLine, startRenderer, endRenderer, startOverhang, endOverhang);
+
+ startOverhang = std::min<int>(startOverhang, m_committedWidth);
+ m_availableWidth += startOverhang;
+
+ endOverhang = std::max(std::min<int>(endOverhang, m_availableWidth - currentWidth()), 0);
+ m_availableWidth += endOverhang;
+ m_overhangWidth += startOverhang + endOverhang;
+}
+
+inline static float availableWidthAtOffset(const RenderBlockFlow& block, const LayoutUnit& offset, bool shouldIndentText, float& newLineLeft, float& newLineRight)
+{
+ newLineLeft = block.logicalLeftOffsetForLine(offset, shouldIndentText).toFloat();
+ newLineRight = block.logicalRightOffsetForLine(offset, shouldIndentText).toFloat();
+ return std::max(0.0f, newLineRight - newLineLeft);
+}
+
+inline static float availableWidthAtOffset(const RenderBlockFlow& block, const LayoutUnit& offset, bool shouldIndentText)
+{
+ float newLineLeft = block.logicalLeftOffsetForLine(offset, shouldIndentText).toFloat();
+ float newLineRight = block.logicalRightOffsetForLine(offset, shouldIndentText).toFloat();
+ return std::max(0.0f, newLineRight - newLineLeft);
+}
+
+void LineWidth::updateLineDimension(LayoutUnit newLineTop, LayoutUnit newLineWidth, const float& newLineLeft, const float& newLineRight)
+{
+ if (newLineWidth <= m_availableWidth)
+ return;
+
+ m_block.setLogicalHeight(newLineTop);
+ m_availableWidth = newLineWidth + m_overhangWidth;
+ m_left = newLineLeft;
+ m_right = newLineRight;
+}
+
+inline static bool isWholeLineFit(const RenderBlockFlow& block, const LayoutUnit& lineTop, LayoutUnit lineHeight, float uncommittedWidth, bool shouldIndentText)
+{
+ for (LayoutUnit lineBottom = lineTop; lineBottom <= lineTop + lineHeight; lineBottom++) {
+ LayoutUnit availableWidthAtBottom = availableWidthAtOffset(block, lineBottom, shouldIndentText);
+ if (availableWidthAtBottom < uncommittedWidth)
+ return false;
+ }
+ return true;
+}
+
+void LineWidth::wrapNextToShapeOutside(bool isFirstLine)
+{
+ LayoutUnit lineHeight = m_block.lineHeight(isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
+ LayoutUnit lineLogicalTop = m_block.logicalHeight();
+ LayoutUnit newLineTop = lineLogicalTop;
+ LayoutUnit floatLogicalBottom = m_block.nextFloatLogicalBottomBelow(lineLogicalTop);
+
+ float newLineWidth;
+ float newLineLeft = m_left;
+ float newLineRight = m_right;
+ while (true) {
+ newLineWidth = availableWidthAtOffset(m_block, newLineTop, shouldIndentText(), newLineLeft, newLineRight);
+ if (newLineWidth >= m_uncommittedWidth && isWholeLineFit(m_block, newLineTop, lineHeight, m_uncommittedWidth, shouldIndentText()))
+ break;
+
+ if (newLineTop >= floatLogicalBottom)
+ break;
+
+ newLineTop++;
+ }
+ updateLineDimension(newLineTop, newLineWidth, newLineLeft, newLineRight);
+}
+
+void LineWidth::fitBelowFloats(bool isFirstLine)
+{
+ ASSERT(!m_committedWidth);
+ ASSERT(!fitsOnLine());
+
+ LayoutUnit floatLogicalBottom;
+ LayoutUnit lastFloatLogicalBottom = m_block.logicalHeight();
+ float newLineWidth = m_availableWidth;
+ float newLineLeft = m_left;
+ float newLineRight = m_right;
+
+ FloatingObject* lastFloatFromPreviousLine = (m_block.containsFloats() ? m_block.m_floatingObjects->set().last().get() : 0);
+ if (lastFloatFromPreviousLine && lastFloatFromPreviousLine->renderer()->shapeOutsideInfo())
+ return wrapNextToShapeOutside(isFirstLine);
+
+ while (true) {
+ floatLogicalBottom = m_block.nextFloatLogicalBottomBelow(lastFloatLogicalBottom, ShapeOutsideFloatShapeOffset);
+ if (floatLogicalBottom <= lastFloatLogicalBottom)
+ break;
+
+ newLineWidth = availableWidthAtOffset(m_block, floatLogicalBottom, shouldIndentText(), newLineLeft, newLineRight);
+ lastFloatLogicalBottom = floatLogicalBottom;
+
+ if (newLineWidth >= m_uncommittedWidth)
+ break;
+ }
+ updateLineDimension(lastFloatLogicalBottom, newLineWidth, newLineLeft, newLineRight);
+}
+
+void LineWidth::computeAvailableWidthFromLeftAndRight()
+{
+ m_availableWidth = max(0.0f, m_right - m_left) + m_overhangWidth;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/LineWidth.h b/chromium/third_party/WebKit/Source/core/rendering/line/LineWidth.h
new file mode 100644
index 00000000000..c9346b770b7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/LineWidth.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LineWidth_h
+#define LineWidth_h
+
+#include "platform/LayoutUnit.h"
+
+namespace WebCore {
+
+class FloatingObject;
+class RenderObject;
+class RenderRubyRun;
+class RenderBlockFlow;
+
+enum IndentTextOrNot { DoNotIndentText, IndentText };
+enum WhitespaceTreatment { ExcludeWhitespace, IncludeWhitespace };
+
+class LineWidth {
+public:
+ LineWidth(RenderBlockFlow&, bool isFirstLine, IndentTextOrNot shouldIndentText);
+
+ bool fitsOnLine() const { return currentWidth() <= (m_availableWidth + LayoutUnit::epsilon()); }
+ bool fitsOnLine(float extra) const { return currentWidth() + extra <= (m_availableWidth + LayoutUnit::epsilon()); }
+ bool fitsOnLine(float extra, WhitespaceTreatment whitespaceTreatment) const
+ {
+ return currentWidth() - (whitespaceTreatment == ExcludeWhitespace ? trailingWhitespaceWidth() : 0) + extra <= (m_availableWidth + LayoutUnit::epsilon());
+ }
+
+ float currentWidth() const { return m_committedWidth + m_uncommittedWidth; }
+ // FIXME: We should eventually replace these three functions by ones that work on a higher abstraction.
+ float uncommittedWidth() const { return m_uncommittedWidth; }
+ float committedWidth() const { return m_committedWidth; }
+ float availableWidth() const { return m_availableWidth; }
+ float trailingWhitespaceWidth() const { return m_trailingWhitespaceWidth; }
+
+ void updateAvailableWidth(LayoutUnit minimumHeight = 0);
+ void shrinkAvailableWidthForNewFloatIfNeeded(FloatingObject*);
+ void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
+ void commit();
+ void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
+ void fitBelowFloats(bool isFirstLine = false);
+ void setTrailingWhitespaceWidth(float width) { m_trailingWhitespaceWidth = width; }
+
+ bool shouldIndentText() const { return m_shouldIndentText == IndentText; }
+
+private:
+ void computeAvailableWidthFromLeftAndRight();
+ void updateLineDimension(LayoutUnit newLineTop, LayoutUnit newLineWidth, const float& newLineLeft, const float& newLineRight);
+ void wrapNextToShapeOutside(bool isFirstLine);
+
+ RenderBlockFlow& m_block;
+ float m_uncommittedWidth;
+ float m_committedWidth;
+ float m_overhangWidth; // The amount by which |m_availableWidth| has been inflated to account for possible contraction due to ruby overhang.
+ float m_trailingWhitespaceWidth;
+ float m_left;
+ float m_right;
+ float m_availableWidth;
+ bool m_isFirstLine;
+ IndentTextOrNot m_shouldIndentText;
+};
+
+}
+
+#endif // LineWidth_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/RenderTextInfo.h b/chromium/third_party/WebKit/Source/core/rendering/line/RenderTextInfo.h
new file mode 100644
index 00000000000..0ad1c598a25
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/RenderTextInfo.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef RenderTextInfo_h
+#define RenderTextInfo_h
+
+#include "platform/text/TextBreakIterator.h"
+
+namespace WebCore {
+
+class Font;
+class RenderText;
+
+struct RenderTextInfo {
+ RenderTextInfo()
+ : m_text(0)
+ , m_font(0)
+ {
+ }
+
+ RenderText* m_text;
+ LazyLineBreakIterator m_lineBreakIterator;
+ const Font* m_font;
+};
+
+} // namespace WebCore
+
+#endif // RenderTextInfo_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/TrailingObjects.cpp b/chromium/third_party/WebKit/Source/core/rendering/line/TrailingObjects.cpp
new file mode 100644
index 00000000000..62c489b84b5
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/TrailingObjects.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Adobe Systems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "core/rendering/line/TrailingObjects.h"
+
+#include "core/rendering/InlineIterator.h"
+
+namespace WebCore {
+
+void TrailingObjects::updateMidpointsForTrailingObjects(LineMidpointState& lineMidpointState, const InlineIterator& lBreak, CollapseFirstSpaceOrNot collapseFirstSpace)
+{
+ if (!m_whitespace)
+ return;
+
+ // This object is either going to be part of the last midpoint, or it is going to be the actual endpoint.
+ // In both cases we just decrease our pos by 1 level to exclude the space, allowing it to - in effect - collapse into the newline.
+ if (lineMidpointState.numMidpoints() % 2) {
+ // Find the trailing space object's midpoint.
+ int trailingSpaceMidpoint = lineMidpointState.numMidpoints() - 1;
+ for ( ; trailingSpaceMidpoint > 0 && lineMidpointState.midpoints()[trailingSpaceMidpoint].object() != m_whitespace; --trailingSpaceMidpoint) { }
+ ASSERT(trailingSpaceMidpoint >= 0);
+ if (collapseFirstSpace == CollapseFirstSpace)
+ lineMidpointState.midpoints()[trailingSpaceMidpoint].setOffset(lineMidpointState.midpoints()[trailingSpaceMidpoint].offset() -1);
+
+ // Now make sure every single trailingPositionedBox following the trailingSpaceMidpoint properly stops and starts
+ // ignoring spaces.
+ size_t currentMidpoint = trailingSpaceMidpoint + 1;
+ for (size_t i = 0; i < m_objects.size(); ++i) {
+ if (currentMidpoint >= lineMidpointState.numMidpoints()) {
+ // We don't have a midpoint for this box yet.
+ lineMidpointState.ensureLineBoxInsideIgnoredSpaces(m_objects[i]);
+ } else {
+ ASSERT(lineMidpointState.midpoints()[currentMidpoint].object() == m_objects[i]);
+ ASSERT(lineMidpointState.midpoints()[currentMidpoint + 1].object() == m_objects[i]);
+ }
+ currentMidpoint += 2;
+ }
+ } else if (!lBreak.object()) {
+ ASSERT(m_whitespace->isText());
+ ASSERT(collapseFirstSpace == CollapseFirstSpace);
+ // Add a new end midpoint that stops right at the very end.
+ unsigned length = m_whitespace->textLength();
+ unsigned pos = length >= 2 ? length - 2 : UINT_MAX;
+ InlineIterator endMid(0, m_whitespace, pos);
+ lineMidpointState.startIgnoringSpaces(endMid);
+ for (size_t i = 0; i < m_objects.size(); ++i) {
+ lineMidpointState.ensureLineBoxInsideIgnoredSpaces(m_objects[i]);
+ }
+ }
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/TrailingObjects.h b/chromium/third_party/WebKit/Source/core/rendering/line/TrailingObjects.h
new file mode 100644
index 00000000000..72b1369ab20
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/TrailingObjects.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Adobe Systems Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TrailingObjects_h
+#define TrailingObjects_h
+
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class InlineIterator;
+class RenderObject;
+class RenderText;
+
+struct BidiRun;
+
+template <class Iterator, class Run> class BidiResolver;
+template <class Iterator> class MidpointState;
+typedef BidiResolver<InlineIterator, BidiRun> InlineBidiResolver;
+typedef MidpointState<InlineIterator> LineMidpointState;
+
+// This class allows us to ensure lineboxes are created in the right place on the line when
+// an out-of-flow positioned object or an empty inline is encountered between a trailing space
+// and subsequent spaces and we want to ignore (i.e. collapse) surplus whitespace. So for example:
+// <div>X <span></span> Y</div>
+// or
+// <div>X <div style="position: absolute"></div> Y</div>
+// In both of the above snippets the inline and the positioned object occur after a trailing space
+// and before a space that will cause our line breaking algorithm to start ignoring spaces. When it
+// does that we want to ensure that the inline/positioned object gets a linebox and that it is part
+// of the collapsed whitespace. So to achieve this we use appendObjectIfNeeded() to keep track of
+// objects encountered after a trailing whitespace and updateMidpointsForTrailingObjects() to put
+// them in the right place when we start ignoring surplus whitespace.
+
+class TrailingObjects {
+public:
+ TrailingObjects()
+ : m_whitespace(0)
+ {
+ }
+
+ void setTrailingWhitespace(RenderText* whitespace)
+ {
+ ASSERT(whitespace);
+ m_whitespace = whitespace;
+ }
+
+ void clear()
+ {
+ m_whitespace = 0;
+ // Using resize(0) rather than clear() here saves 2% on
+ // PerformanceTests/Layout/line-layout.html because we avoid freeing and
+ // re-allocating the underlying buffer repeatedly.
+ m_objects.resize(0);
+ }
+
+ void appendObjectIfNeeded(RenderObject* object)
+ {
+ if (m_whitespace)
+ m_objects.append(object);
+ }
+
+ enum CollapseFirstSpaceOrNot { DoNotCollapseFirstSpace, CollapseFirstSpace };
+
+ void updateMidpointsForTrailingObjects(LineMidpointState&, const InlineIterator& lBreak, CollapseFirstSpaceOrNot);
+
+private:
+ RenderText* m_whitespace;
+ Vector<RenderObject*, 4> m_objects;
+};
+
+}
+
+#endif // TrailingObjects_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/line/WordMeasurement.h b/chromium/third_party/WebKit/Source/core/rendering/line/WordMeasurement.h
new file mode 100644
index 00000000000..46803dd0c56
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/line/WordMeasurement.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2003, 2004, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All right reserved.
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Adobe Systems Incorporated.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef WordMeasurement_h
+#define WordMeasurement_h
+
+#include "platform/fonts/SimpleFontData.h"
+#include "wtf/HashSet.h"
+
+namespace WebCore {
+
+class RenderText;
+
+class WordMeasurement {
+public:
+ WordMeasurement()
+ : renderer(0)
+ , width(0)
+ , startOffset(0)
+ , endOffset(0)
+ {
+ }
+
+ RenderText* renderer;
+ float width;
+ int startOffset;
+ int endOffset;
+ HashSet<const SimpleFontData*> fallbackFonts;
+};
+
+} // namespace WebCore
+
+#endif // WordMeasurement_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.cpp
index 86c9136ac90..bba80270c55 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.cpp
@@ -42,14 +42,6 @@ LayoutRect BoxShape::shapeMarginLogicalBoundingBox() const
return static_cast<LayoutRect>(marginBounds);
}
-LayoutRect BoxShape::shapePaddingLogicalBoundingBox() const
-{
- FloatRect paddingBounds(m_bounds.rect());
- if (shapePadding() > 0)
- paddingBounds.inflate(-shapePadding());
- return static_cast<LayoutRect>(paddingBounds);
-}
-
FloatRoundedRect BoxShape::shapeMarginBounds() const
{
FloatRoundedRect marginBounds(m_bounds);
@@ -60,24 +52,14 @@ FloatRoundedRect BoxShape::shapeMarginBounds() const
return marginBounds;
}
-FloatRoundedRect BoxShape::shapePaddingBounds() const
-{
- FloatRoundedRect paddingBounds(m_bounds);
- if (shapePadding() > 0) {
- paddingBounds.inflate(-shapePadding());
- paddingBounds.expandRadii(-shapePadding());
- }
- return paddingBounds;
-}
-
void BoxShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
{
const FloatRoundedRect& marginBounds = shapeMarginBounds();
if (marginBounds.isEmpty() || !lineOverlapsShapeMarginBounds(logicalTop, logicalHeight))
return;
- float y1 = logicalTop;
- float y2 = logicalTop + logicalHeight;
+ float y1 = logicalTop.toFloat();
+ float y2 = (logicalTop + logicalHeight).toFloat();
const FloatRect& rect = marginBounds.rect();
if (!marginBounds.isRounded()) {
@@ -85,11 +67,25 @@ void BoxShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHei
return;
}
+ float topCornerMaxY = std::max<float>(marginBounds.topLeftCorner().maxY(), marginBounds.topRightCorner().maxY());
+ float bottomCornerMinY = std::min<float>(marginBounds.bottomLeftCorner().y(), marginBounds.bottomRightCorner().y());
+
+ if (topCornerMaxY <= bottomCornerMinY && y1 <= topCornerMaxY && y2 >= bottomCornerMinY) {
+ result.append(LineSegment(rect.x(), rect.maxX()));
+ return;
+ }
+
float x1 = rect.maxX();
float x2 = rect.x();
float minXIntercept;
float maxXIntercept;
+ if (y1 <= marginBounds.topLeftCorner().maxY() && y2 >= marginBounds.bottomLeftCorner().y())
+ x1 = rect.x();
+
+ if (y1 <= marginBounds.topRightCorner().maxY() && y2 >= marginBounds.bottomRightCorner().y())
+ x2 = rect.maxX();
+
if (marginBounds.xInterceptsAtY(y1, minXIntercept, maxXIntercept)) {
x1 = std::min<float>(x1, minXIntercept);
x2 = std::max<float>(x2, maxXIntercept);
@@ -104,27 +100,11 @@ void BoxShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHei
result.append(LineSegment(x1, x2));
}
-void BoxShape::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
+void BoxShape::buildDisplayPaths(DisplayPaths& paths) const
{
- const FloatRoundedRect& paddingBounds = shapePaddingBounds();
- if (paddingBounds.isEmpty())
- return;
-
- const FloatRect& rect = paddingBounds.rect();
- if (logicalTop < rect.y() || logicalTop + logicalHeight > rect.maxY())
- return;
-
- // FIXME: this method is only a stub, https://bugs.webkit.org/show_bug.cgi?id=124605.
-
- result.append(LineSegment(rect.x(), rect.maxX()));
-}
-
-bool BoxShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize&, LayoutUnit& result) const
-{
- // FIXME: this method is only a stub, https://bugs.webkit.org/show_bug.cgi?id=124606.
-
- result = minLogicalIntervalTop;
- return true;
+ paths.shape.addRoundedRect(m_bounds.rect(), m_bounds.radii().topLeft(), m_bounds.radii().topRight(), m_bounds.radii().bottomLeft(), m_bounds.radii().bottomRight());
+ if (shapeMargin())
+ paths.marginShape.addRoundedRect(shapeMarginBounds().rect(), shapeMarginBounds().radii().topLeft(), shapeMarginBounds().radii().topRight(), shapeMarginBounds().radii().bottomLeft(), shapeMarginBounds().radii().bottomRight());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.h
index 823187a7ca9..06a51489615 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShape.h
@@ -35,7 +35,7 @@
namespace WebCore {
-class BoxShape : public Shape {
+class BoxShape FINAL : public Shape {
public:
BoxShape(const FloatRoundedRect& bounds)
: Shape()
@@ -44,15 +44,12 @@ public:
}
virtual LayoutRect shapeMarginLogicalBoundingBox() const OVERRIDE;
- virtual LayoutRect shapePaddingLogicalBoundingBox() const OVERRIDE;
virtual bool isEmpty() const OVERRIDE { return m_bounds.isEmpty(); }
virtual void getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const OVERRIDE;
- virtual void getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const OVERRIDE;
- virtual bool firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit&) const OVERRIDE;
+ virtual void buildDisplayPaths(DisplayPaths&) const OVERRIDE;
private:
FloatRoundedRect shapeMarginBounds() const;
- FloatRoundedRect shapePaddingBounds() const;
FloatRoundedRect m_bounds;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShapeTest.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShapeTest.cpp
index 9b1f50193f1..74538f391fd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShapeTest.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/BoxShapeTest.cpp
@@ -31,6 +31,8 @@
#include "core/rendering/shapes/BoxShape.h"
+#include "platform/geometry/RoundedRect.h"
+
#include <gtest/gtest.h>
namespace WebCore {
@@ -39,9 +41,9 @@ class BoxShapeTest : public ::testing::Test {
protected:
BoxShapeTest() { }
- PassOwnPtr<Shape> createBoxShape(const LayoutSize& size, float shapeMargin, float shapePadding)
+ PassOwnPtr<Shape> createBoxShape(const RoundedRect& bounds, float shapeMargin)
{
- return Shape::createLayoutBoxShape(size, TopToBottomWritingMode, Length(shapeMargin, Fixed), Length(shapePadding, Fixed));
+ return Shape::createLayoutBoxShape(bounds, TopToBottomWritingMode, shapeMargin);
}
};
@@ -56,8 +58,10 @@ using namespace WebCore;
SegmentList result; \
shapePtr->getExcludedIntervals(lineTop, lineHeight, result); \
EXPECT_EQ(1u, result.size()); \
- EXPECT_EQ(expectedLeft, result[0].logicalLeft); \
- EXPECT_EQ(expectedRight, result[0].logicalRight); \
+ if (result.size() == 1u) { \
+ EXPECT_FLOAT_EQ(expectedLeft, result[0].logicalLeft); \
+ EXPECT_FLOAT_EQ(expectedRight, result[0].logicalRight); \
+ } \
}
#define TEST_NO_EXCLUDED_INTERVAL(shapePtr, lineTop, lineHeight) \
@@ -67,13 +71,21 @@ using namespace WebCore;
EXPECT_EQ(0u, result.size()); \
}
+/* The BoxShape is based on a 100x50 rectangle at 0,0. The shape-margin value is 10,
+ * so the shapeMarginBoundingBox rectangle is 120x70 at -10,-10:
+ *
+ * -10,-10 110,-10
+ * +--------+
+ * | |
+ * +--------+
+ * -10,60 60,60
+ */
TEST_F(BoxShapeTest, zeroRadii)
{
- OwnPtr<Shape> shape = createBoxShape(LayoutSize(100, 50), 10, 20);
+ OwnPtr<Shape> shape = createBoxShape(RoundedRect(0, 0, 100, 50), 10);
EXPECT_FALSE(shape->isEmpty());
EXPECT_EQ(LayoutRect(-10, -10, 120, 70), shape->shapeMarginLogicalBoundingBox());
- EXPECT_EQ(LayoutRect(20, 20, 60, 10), shape->shapePaddingLogicalBoundingBox());
// A BoxShape's bounds include the top edge but not the bottom edge.
// Similarly a "line", specified as top,height to the overlap methods,
@@ -98,16 +110,34 @@ TEST_F(BoxShapeTest, zeroRadii)
TEST_NO_EXCLUDED_INTERVAL(shape, -12, 2);
TEST_NO_EXCLUDED_INTERVAL(shape, 60, 1);
TEST_NO_EXCLUDED_INTERVAL(shape, 100, 200);
+}
+
+/* BoxShape geometry for this test. Corner radii are in parens, x and y intercepts
+ * for the elliptical corners are noted. The rectangle itself is at 0,0 with width and height 100.
+ *
+ * (10, 15) x=10 x=90 (10, 20)
+ * (--+---------+--)
+ * y=15 +--| |-+ y=20
+ * | |
+ * | |
+ * y=85 + -| |- + y=70
+ * (--+---------+--)
+ * (25, 15) x=25 x=80 (20, 30)
+ */
+TEST_F(BoxShapeTest, getIntervals)
+{
+ const RoundedRect::Radii cornerRadii(IntSize(10, 15), IntSize(10, 20), IntSize(25, 15), IntSize(20, 30));
+ OwnPtr<Shape> shape = createBoxShape(RoundedRect(IntRect(0, 0, 100, 100), cornerRadii), 0);
+ EXPECT_FALSE(shape->isEmpty());
- EXPECT_TRUE(shape->lineOverlapsShapePaddingBounds(21, 1));
- EXPECT_TRUE(shape->lineOverlapsShapePaddingBounds(20, 0));
- EXPECT_TRUE(shape->lineOverlapsShapePaddingBounds(-10, 200));
- EXPECT_TRUE(shape->lineOverlapsShapePaddingBounds(25, 35));
- EXPECT_TRUE(shape->lineOverlapsShapePaddingBounds(29, 1));
+ EXPECT_EQ(LayoutRect(0, 0, 100, 100), shape->shapeMarginLogicalBoundingBox());
- EXPECT_FALSE(shape->lineOverlapsShapePaddingBounds(18, 2));
- EXPECT_FALSE(shape->lineOverlapsShapePaddingBounds(30, 1));
- EXPECT_FALSE(shape->lineOverlapsShapePaddingBounds(100, 200));
+ TEST_EXCLUDED_INTERVAL(shape, 10, 95, 0, 100);
+ TEST_EXCLUDED_INTERVAL(shape, 5, 25, 0, 100);
+ TEST_EXCLUDED_INTERVAL(shape, 15, 6, 0, 100);
+ TEST_EXCLUDED_INTERVAL(shape, 20, 50, 0, 100);
+ TEST_EXCLUDED_INTERVAL(shape, 69, 5, 0, 100);
+ TEST_EXCLUDED_INTERVAL(shape, 85, 10, 0, 97.320511f);
}
} // namespace
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.cpp
index 26ddcf3606b..98cd8367e1e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.cpp
@@ -30,70 +30,11 @@
#include "config.h"
#include "core/rendering/shapes/PolygonShape.h"
-#include "core/rendering/shapes/ShapeInterval.h"
#include "platform/geometry/LayoutPoint.h"
#include "wtf/MathExtras.h"
namespace WebCore {
-enum EdgeIntersectionType {
- Normal,
- VertexMinY,
- VertexMaxY,
- VertexYBoth
-};
-
-struct EdgeIntersection {
- const FloatPolygonEdge* edge;
- FloatPoint point;
- EdgeIntersectionType type;
-};
-
-static inline float leftSide(const FloatPoint& vertex1, const FloatPoint& vertex2, const FloatPoint& point)
-{
- return ((point.x() - vertex1.x()) * (vertex2.y() - vertex1.y())) - ((vertex2.x() - vertex1.x()) * (point.y() - vertex1.y()));
-}
-
-static inline bool isReflexVertex(const FloatPoint& prevVertex, const FloatPoint& vertex, const FloatPoint& nextVertex)
-{
- return leftSide(prevVertex, nextVertex, vertex) < 0;
-}
-
-static bool computeXIntersection(const FloatPolygonEdge* edgePointer, float y, EdgeIntersection& result)
-{
- const FloatPolygonEdge& edge = *edgePointer;
-
- if (edge.minY() > y || edge.maxY() < y)
- return false;
-
- const FloatPoint& vertex1 = edge.vertex1();
- const FloatPoint& vertex2 = edge.vertex2();
- float dy = vertex2.y() - vertex1.y();
-
- float intersectionX;
- EdgeIntersectionType intersectionType;
-
- if (!dy) {
- intersectionType = VertexYBoth;
- intersectionX = edge.minX();
- } else if (y == edge.minY()) {
- intersectionType = VertexMinY;
- intersectionX = (vertex1.y() < vertex2.y()) ? vertex1.x() : vertex2.x();
- } else if (y == edge.maxY()) {
- intersectionType = VertexMaxY;
- intersectionX = (vertex1.y() > vertex2.y()) ? vertex1.x() : vertex2.x();
- } else {
- intersectionType = Normal;
- intersectionX = ((y - vertex1.y()) * (vertex2.x() - vertex1.x()) / dy) + vertex1.x();
- }
-
- result.edge = edgePointer;
- result.type = intersectionType;
- result.point.set(intersectionX, y);
-
- return true;
-}
-
static inline FloatSize inwardEdgeNormal(const FloatPolygonEdge& edge)
{
FloatSize edgeDelta = edge.vertex2() - edge.vertex1();
@@ -110,422 +51,113 @@ static inline FloatSize outwardEdgeNormal(const FloatPolygonEdge& edge)
return -inwardEdgeNormal(edge);
}
-static inline void appendArc(Vector<FloatPoint>& vertices, const FloatPoint& arcCenter, float arcRadius, const FloatPoint& startArcVertex, const FloatPoint& endArcVertex, bool padding)
-{
- float startAngle = atan2(startArcVertex.y() - arcCenter.y(), startArcVertex.x() - arcCenter.x());
- float endAngle = atan2(endArcVertex.y() - arcCenter.y(), endArcVertex.x() - arcCenter.x());
- const float twoPI = piFloat * 2;
- if (startAngle < 0)
- startAngle += twoPI;
- if (endAngle < 0)
- endAngle += twoPI;
- float angle = (startAngle > endAngle) ? (startAngle - endAngle) : (startAngle + twoPI - endAngle);
- const float arcSegmentCount = 6; // An even number so that one arc vertex will be eactly arcRadius from arcCenter.
- float arcSegmentAngle = ((padding) ? -angle : twoPI - angle) / arcSegmentCount;
-
- vertices.append(startArcVertex);
- for (unsigned i = 1; i < arcSegmentCount; ++i) {
- float angle = startAngle + arcSegmentAngle * i;
- vertices.append(arcCenter + FloatPoint(cos(angle) * arcRadius, sin(angle) * arcRadius));
- }
- vertices.append(endArcVertex);
-}
-
-static inline void snapVerticesToLayoutUnitGrid(Vector<FloatPoint>& vertices)
-{
- for (unsigned i = 0; i < vertices.size(); ++i)
- vertices[i] = flooredLayoutPoint(vertices[i]);
-}
-
-static inline PassOwnPtr<FloatPolygon> computeShapePaddingBounds(const FloatPolygon& polygon, float padding, WindRule fillRule)
-{
- OwnPtr<Vector<FloatPoint> > paddedVertices = adoptPtr(new Vector<FloatPoint>());
- FloatPoint intersection;
-
- for (unsigned i = 0; i < polygon.numberOfEdges(); ++i) {
- const FloatPolygonEdge& thisEdge = polygon.edgeAt(i);
- const FloatPolygonEdge& prevEdge = thisEdge.previousEdge();
- OffsetPolygonEdge thisOffsetEdge(thisEdge, inwardEdgeNormal(thisEdge) * padding);
- OffsetPolygonEdge prevOffsetEdge(prevEdge, inwardEdgeNormal(prevEdge) * padding);
-
- if (prevOffsetEdge.intersection(thisOffsetEdge, intersection))
- paddedVertices->append(intersection);
- else if (isReflexVertex(prevEdge.vertex1(), thisEdge.vertex1(), thisEdge.vertex2()))
- appendArc(*paddedVertices, thisEdge.vertex1(), padding, prevOffsetEdge.vertex2(), thisOffsetEdge.vertex1(), true);
- }
-
- snapVerticesToLayoutUnitGrid(*paddedVertices);
- return adoptPtr(new FloatPolygon(paddedVertices.release(), fillRule));
-}
-
-static inline PassOwnPtr<FloatPolygon> computeShapeMarginBounds(const FloatPolygon& polygon, float margin, WindRule fillRule)
-{
- OwnPtr<Vector<FloatPoint> > marginVertices = adoptPtr(new Vector<FloatPoint>());
- FloatPoint intersection;
-
- for (unsigned i = 0; i < polygon.numberOfEdges(); ++i) {
- const FloatPolygonEdge& thisEdge = polygon.edgeAt(i);
- const FloatPolygonEdge& prevEdge = thisEdge.previousEdge();
- OffsetPolygonEdge thisOffsetEdge(thisEdge, outwardEdgeNormal(thisEdge) * margin);
- OffsetPolygonEdge prevOffsetEdge(prevEdge, outwardEdgeNormal(prevEdge) * margin);
-
- if (prevOffsetEdge.intersection(thisOffsetEdge, intersection))
- marginVertices->append(intersection);
- else
- appendArc(*marginVertices, thisEdge.vertex1(), margin, prevOffsetEdge.vertex2(), thisOffsetEdge.vertex1(), false);
- }
-
- snapVerticesToLayoutUnitGrid(*marginVertices);
- return adoptPtr(new FloatPolygon(marginVertices.release(), fillRule));
-}
+static inline bool overlapsYRange(const FloatRect& rect, float y1, float y2) { return !rect.isEmpty() && y2 >= y1 && y2 >= rect.y() && y1 <= rect.maxY(); }
-const FloatPolygon& PolygonShape::shapePaddingBounds() const
+float OffsetPolygonEdge::xIntercept(float y) const
{
- ASSERT(shapePadding() >= 0);
- if (!shapePadding() || m_polygon.isEmpty())
- return m_polygon;
+ ASSERT(y >= minY() && y <= maxY());
- if (!m_paddingBounds)
- m_paddingBounds = computeShapePaddingBounds(m_polygon, shapePadding(), m_polygon.fillRule());
+ if (vertex1().y() == vertex2().y() || vertex1().x() == vertex2().x())
+ return minX();
+ if (y == minY())
+ return vertex1().y() < vertex2().y() ? vertex1().x() : vertex2().x();
+ if (y == maxY())
+ return vertex1().y() > vertex2().y() ? vertex1().x() : vertex2().x();
- return *m_paddingBounds;
+ return vertex1().x() + ((y - vertex1().y()) * (vertex2().x() - vertex1().x()) / (vertex2().y() - vertex1().y()));
}
-const FloatPolygon& PolygonShape::shapeMarginBounds() const
+FloatShapeInterval OffsetPolygonEdge::clippedEdgeXRange(float y1, float y2) const
{
- ASSERT(shapeMargin() >= 0);
- if (!shapeMargin() || m_polygon.isEmpty())
- return m_polygon;
+ if (!overlapsYRange(y1, y2) || (y1 == maxY() && minY() <= y1) || (y2 == minY() && maxY() >= y2))
+ return FloatShapeInterval();
- if (!m_marginBounds)
- m_marginBounds = computeShapeMarginBounds(m_polygon, shapeMargin(), m_polygon.fillRule());
+ if (isWithinYRange(y1, y2))
+ return FloatShapeInterval(minX(), maxX());
- return *m_marginBounds;
-}
-
-static inline bool getVertexIntersectionVertices(const EdgeIntersection& intersection, FloatPoint& prevVertex, FloatPoint& thisVertex, FloatPoint& nextVertex)
-{
- if (intersection.type != VertexMinY && intersection.type != VertexMaxY)
- return false;
-
- ASSERT(intersection.edge && intersection.edge->polygon());
- const FloatPolygon& polygon = *(intersection.edge->polygon());
- const FloatPolygonEdge& thisEdge = *(intersection.edge);
+ // Clip the edge line segment to the vertical range y1,y2 and then return
+ // the clipped line segment's horizontal range.
- if ((intersection.type == VertexMinY && (thisEdge.vertex1().y() < thisEdge.vertex2().y()))
- || (intersection.type == VertexMaxY && (thisEdge.vertex1().y() > thisEdge.vertex2().y()))) {
- prevVertex = polygon.vertexAt(thisEdge.previousEdge().vertexIndex1());
- thisVertex = polygon.vertexAt(thisEdge.vertexIndex1());
- nextVertex = polygon.vertexAt(thisEdge.vertexIndex2());
+ FloatPoint minYVertex;
+ FloatPoint maxYVertex;
+ if (vertex1().y() < vertex2().y()) {
+ minYVertex = vertex1();
+ maxYVertex = vertex2();
} else {
- prevVertex = polygon.vertexAt(thisEdge.vertexIndex1());
- thisVertex = polygon.vertexAt(thisEdge.vertexIndex2());
- nextVertex = polygon.vertexAt(thisEdge.nextEdge().vertexIndex2());
+ minYVertex = vertex2();
+ maxYVertex = vertex1();
}
-
- return true;
-}
-
-static inline bool appendIntervalX(float x, bool inside, FloatShapeIntervals& result)
-{
- if (!inside)
- result.append(FloatShapeInterval(x, x));
- else
- result.last().setX2(x);
-
- return !inside;
+ float xForY1 = (minYVertex.y() < y1) ? xIntercept(y1) : minYVertex.x();
+ float xForY2 = (maxYVertex.y() > y2) ? xIntercept(y2) : maxYVertex.x();
+ return FloatShapeInterval(std::min(xForY1, xForY2), std::max(xForY1, xForY2));
}
-static bool compareEdgeIntersectionX(const EdgeIntersection& intersection1, const EdgeIntersection& intersection2)
+static float circleXIntercept(float y, float radius)
{
- float x1 = intersection1.point.x();
- float x2 = intersection2.point.x();
- return (x1 == x2) ? intersection1.type < intersection2.type : x1 < x2;
+ ASSERT(radius > 0);
+ return radius * sqrt(1 - (y * y) / (radius * radius));
}
-static void computeXIntersections(const FloatPolygon& polygon, float y, bool isMinY, FloatShapeIntervals& result)
+static FloatShapeInterval clippedCircleXRange(const FloatPoint& center, float radius, float y1, float y2)
{
- Vector<const FloatPolygonEdge*> edges;
- if (!polygon.overlappingEdges(y, y, edges))
- return;
-
- Vector<EdgeIntersection> intersections;
- EdgeIntersection intersection;
- for (unsigned i = 0; i < edges.size(); ++i) {
- if (computeXIntersection(edges[i], y, intersection) && intersection.type != VertexYBoth)
- intersections.append(intersection);
- }
-
- if (intersections.size() < 2)
- return;
-
- std::sort(intersections.begin(), intersections.end(), WebCore::compareEdgeIntersectionX);
-
- unsigned index = 0;
- int windCount = 0;
- bool inside = false;
+ if (y1 > center.y() + radius || y2 < center.y() - radius)
+ return FloatShapeInterval();
- while (index < intersections.size()) {
- const EdgeIntersection& thisIntersection = intersections[index];
- if (index + 1 < intersections.size()) {
- const EdgeIntersection& nextIntersection = intersections[index + 1];
- if ((thisIntersection.point.x() == nextIntersection.point.x()) && (thisIntersection.type == VertexMinY || thisIntersection.type == VertexMaxY)) {
- if (thisIntersection.type == nextIntersection.type) {
- // Skip pairs of intersections whose types are VertexMaxY,VertexMaxY and VertexMinY,VertexMinY.
- index += 2;
- } else {
- // Replace pairs of intersections whose types are VertexMinY,VertexMaxY or VertexMaxY,VertexMinY with one intersection.
- ++index;
- }
- continue;
- }
- }
-
- bool edgeCrossing = thisIntersection.type == Normal;
- if (!edgeCrossing) {
- FloatPoint prevVertex;
- FloatPoint thisVertex;
- FloatPoint nextVertex;
-
- if (getVertexIntersectionVertices(thisIntersection, prevVertex, thisVertex, nextVertex)) {
- if (nextVertex.y() == y)
- edgeCrossing = (isMinY) ? prevVertex.y() > y : prevVertex.y() < y;
- else if (prevVertex.y() == y)
- edgeCrossing = (isMinY) ? nextVertex.y() > y : nextVertex.y() < y;
- else
- edgeCrossing = true;
- }
- }
+ if (center.y() >= y1 && center.y() <= y2)
+ return FloatShapeInterval(center.x() - radius, center.x() + radius);
- if (edgeCrossing && polygon.fillRule() == RULE_NONZERO) {
- const FloatPolygonEdge& thisEdge = *thisIntersection.edge;
- windCount += (thisEdge.vertex2().y() > thisEdge.vertex1().y()) ? 1 : -1;
- }
-
- if (edgeCrossing && (!inside || !windCount))
- inside = appendIntervalX(thisIntersection.point.x(), inside, result);
+ // Clip the circle to the vertical range y1,y2 and return the extent of the clipped circle's
+ // projection on the X axis
- ++index;
- }
+ float xi = circleXIntercept((y2 < center.y() ? y2 : y1) - center.y(), radius);
+ return FloatShapeInterval(center.x() - xi, center.x() + xi);
}
-static bool compareX1(const FloatShapeInterval a, const FloatShapeInterval& b) { return a.x1() < b.x1(); }
-
-static void sortAndMergeShapeIntervals(FloatShapeIntervals& intervals)
+LayoutRect PolygonShape::shapeMarginLogicalBoundingBox() const
{
- std::sort(intervals.begin(), intervals.end(), compareX1);
-
- for (unsigned i = 1; i < intervals.size(); ) {
- const FloatShapeInterval& thisInterval = intervals[i];
- FloatShapeInterval& previousInterval = intervals[i - 1];
- if (thisInterval.overlaps(previousInterval)) {
- previousInterval.setX2(std::max<float>(previousInterval.x2(), thisInterval.x2()));
- intervals.remove(i);
- } else {
- ++i;
- }
- }
+ FloatRect box = m_polygon.boundingBox();
+ box.inflate(shapeMargin());
+ return LayoutRect(box);
}
-static void computeOverlappingEdgeXProjections(const FloatPolygon& polygon, float y1, float y2, FloatShapeIntervals& result)
+void PolygonShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
{
- Vector<const FloatPolygonEdge*> edges;
- if (!polygon.overlappingEdges(y1, y2, edges))
- return;
+ float y1 = logicalTop.toFloat();
+ float y2 = logicalTop.toFloat() + logicalHeight.toFloat();
- EdgeIntersection intersection;
- for (unsigned i = 0; i < edges.size(); ++i) {
- const FloatPolygonEdge *edge = edges[i];
- float x1;
- float x2;
+ if (m_polygon.isEmpty() || !overlapsYRange(m_polygon.boundingBox(), y1 - shapeMargin(), y2 + shapeMargin()))
+ return;
- if (edge->minY() < y1) {
- computeXIntersection(edge, y1, intersection);
- x1 = intersection.point.x();
- } else {
- x1 = (edge->vertex1().y() < edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x();
- }
+ Vector<const FloatPolygonEdge*> overlappingEdges;
+ if (!m_polygon.overlappingEdges(y1 - shapeMargin(), y2 + shapeMargin(), overlappingEdges))
+ return;
- if (edge->maxY() > y2) {
- computeXIntersection(edge, y2, intersection);
- x2 = intersection.point.x();
+ FloatShapeInterval excludedInterval;
+ for (unsigned i = 0; i < overlappingEdges.size(); i++) {
+ const FloatPolygonEdge& edge = *(overlappingEdges[i]);
+ if (edge.maxY() == edge.minY())
+ continue;
+ if (!shapeMargin()) {
+ excludedInterval.unite(OffsetPolygonEdge(edge, FloatSize()).clippedEdgeXRange(y1, y2));
} else {
- x2 = (edge->vertex1().y() > edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x();
+ excludedInterval.unite(OffsetPolygonEdge(edge, outwardEdgeNormal(edge) * shapeMargin()).clippedEdgeXRange(y1, y2));
+ excludedInterval.unite(OffsetPolygonEdge(edge, inwardEdgeNormal(edge) * shapeMargin()).clippedEdgeXRange(y1, y2));
+ excludedInterval.unite(clippedCircleXRange(edge.vertex1(), shapeMargin(), y1, y2));
}
-
- if (x1 > x2)
- std::swap(x1, x2);
-
- if (x2 > x1)
- result.append(FloatShapeInterval(x1, x2));
}
- sortAndMergeShapeIntervals(result);
-}
-
-void PolygonShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
-{
- const FloatPolygon& polygon = shapeMarginBounds();
- if (polygon.isEmpty())
- return;
-
- float y1 = logicalTop;
- float y2 = logicalTop + logicalHeight;
-
- FloatShapeIntervals y1XIntervals, y2XIntervals;
- computeXIntersections(polygon, y1, true, y1XIntervals);
- computeXIntersections(polygon, y2, false, y2XIntervals);
-
- FloatShapeIntervals mergedIntervals;
- FloatShapeInterval::uniteShapeIntervals(y1XIntervals, y2XIntervals, mergedIntervals);
-
- FloatShapeIntervals edgeIntervals;
- computeOverlappingEdgeXProjections(polygon, y1, y2, edgeIntervals);
-
- FloatShapeIntervals excludedIntervals;
- FloatShapeInterval::uniteShapeIntervals(mergedIntervals, edgeIntervals, excludedIntervals);
-
- for (unsigned i = 0; i < excludedIntervals.size(); ++i) {
- const FloatShapeInterval& interval = excludedIntervals[i];
- result.append(LineSegment(interval.x1(), interval.x2()));
- }
+ if (!excludedInterval.isEmpty())
+ result.append(LineSegment(excludedInterval.x1(), excludedInterval.x2()));
}
-void PolygonShape::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
+void PolygonShape::buildDisplayPaths(DisplayPaths& paths) const
{
- const FloatPolygon& polygon = shapePaddingBounds();
- if (polygon.isEmpty())
+ if (!m_polygon.numberOfVertices())
return;
-
- float y1 = logicalTop;
- float y2 = logicalTop + logicalHeight;
-
- FloatShapeIntervals y1XIntervals, y2XIntervals;
- computeXIntersections(polygon, y1, true, y1XIntervals);
- computeXIntersections(polygon, y2, false, y2XIntervals);
-
- FloatShapeIntervals commonIntervals;
- FloatShapeInterval::intersectShapeIntervals(y1XIntervals, y2XIntervals, commonIntervals);
-
- FloatShapeIntervals edgeIntervals;
- computeOverlappingEdgeXProjections(polygon, y1, y2, edgeIntervals);
-
- FloatShapeIntervals includedIntervals;
- FloatShapeInterval::subtractShapeIntervals(commonIntervals, edgeIntervals, includedIntervals);
-
- for (unsigned i = 0; i < includedIntervals.size(); ++i) {
- const FloatShapeInterval& interval = includedIntervals[i];
- result.append(LineSegment(interval.x1(), interval.x2()));
- }
-}
-
-static inline bool firstFitRectInPolygon(const FloatPolygon& polygon, const FloatRect& rect, unsigned offsetEdgeIndex1, unsigned offsetEdgeIndex2)
-{
- Vector<const FloatPolygonEdge*> edges;
- if (!polygon.overlappingEdges(rect.y(), rect.maxY(), edges))
- return true;
-
- for (unsigned i = 0; i < edges.size(); ++i) {
- const FloatPolygonEdge* edge = edges[i];
- if (edge->edgeIndex() != offsetEdgeIndex1 && edge->edgeIndex() != offsetEdgeIndex2 && edge->overlapsRect(rect))
- return false;
- }
-
- return true;
-}
-
-static inline bool aboveOrToTheLeft(const FloatRect& r1, const FloatRect& r2)
-{
- if (r1.y() < r2.y())
- return true;
- if (r1.y() == r2.y())
- return r1.x() < r2.x();
- return false;
-}
-
-bool PolygonShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit& result) const
-{
- float minIntervalTop = minLogicalIntervalTop;
- float minIntervalHeight = minLogicalIntervalSize.height();
- float minIntervalWidth = minLogicalIntervalSize.width();
-
- const FloatPolygon& polygon = shapePaddingBounds();
- const FloatRect boundingBox = polygon.boundingBox();
- if (minIntervalWidth > boundingBox.width())
- return false;
-
- float minY = std::max(boundingBox.y(), minIntervalTop);
- float maxY = minY + minIntervalHeight;
-
- if (maxY > boundingBox.maxY())
- return false;
-
- Vector<const FloatPolygonEdge*> edges;
- polygon.overlappingEdges(minIntervalTop, boundingBox.maxY(), edges);
-
- float dx = minIntervalWidth / 2;
- float dy = minIntervalHeight / 2;
- Vector<OffsetPolygonEdge> offsetEdges;
-
- for (unsigned i = 0; i < edges.size(); ++i) {
- const FloatPolygonEdge& edge = *(edges[i]);
- const FloatPoint& vertex0 = edge.previousEdge().vertex1();
- const FloatPoint& vertex1 = edge.vertex1();
- const FloatPoint& vertex2 = edge.vertex2();
- Vector<OffsetPolygonEdge> offsetEdgeBuffer;
-
- if (vertex2.y() > vertex1.y() ? vertex2.x() >= vertex1.x() : vertex1.x() >= vertex2.x()) {
- offsetEdgeBuffer.append(OffsetPolygonEdge(edge, FloatSize(dx, -dy)));
- offsetEdgeBuffer.append(OffsetPolygonEdge(edge, FloatSize(-dx, dy)));
- } else {
- offsetEdgeBuffer.append(OffsetPolygonEdge(edge, FloatSize(dx, dy)));
- offsetEdgeBuffer.append(OffsetPolygonEdge(edge, FloatSize(-dx, -dy)));
- }
-
- if (isReflexVertex(vertex0, vertex1, vertex2)) {
- if (vertex2.x() <= vertex1.x() && vertex0.x() <= vertex1.x())
- offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(dx, -dy), FloatSize(dx, dy)));
- else if (vertex2.x() >= vertex1.x() && vertex0.x() >= vertex1.x())
- offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx, -dy), FloatSize(-dx, dy)));
- if (vertex2.y() <= vertex1.y() && vertex0.y() <= vertex1.y())
- offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx, dy), FloatSize(dx, dy)));
- else if (vertex2.y() >= vertex1.y() && vertex0.y() >= vertex1.y())
- offsetEdgeBuffer.append(OffsetPolygonEdge(vertex1, FloatSize(-dx, -dy), FloatSize(dx, -dy)));
- }
-
- for (unsigned j = 0; j < offsetEdgeBuffer.size(); ++j) {
- if (offsetEdgeBuffer[j].maxY() >= minY)
- offsetEdges.append(offsetEdgeBuffer[j]);
- }
- }
-
- offsetEdges.append(OffsetPolygonEdge(polygon, minIntervalTop, FloatSize(0, dy)));
-
- FloatPoint offsetEdgesIntersection;
- FloatRect firstFitRect;
- bool firstFitFound = false;
-
- for (unsigned i = 0; i < offsetEdges.size() - 1; ++i) {
- for (unsigned j = i + 1; j < offsetEdges.size(); ++j) {
- if (offsetEdges[i].intersection(offsetEdges[j], offsetEdgesIntersection)) {
- FloatPoint potentialFirstFitLocation(offsetEdgesIntersection.x() - dx, offsetEdgesIntersection.y() - dy);
- FloatRect potentialFirstFitRect(potentialFirstFitLocation, minLogicalIntervalSize);
- if ((offsetEdges[i].basis() == OffsetPolygonEdge::LineTop
- || offsetEdges[j].basis() == OffsetPolygonEdge::LineTop
- || potentialFirstFitLocation.y() >= minIntervalTop)
- && (!firstFitFound || aboveOrToTheLeft(potentialFirstFitRect, firstFitRect))
- && polygon.contains(offsetEdgesIntersection)
- && firstFitRectInPolygon(polygon, potentialFirstFitRect, offsetEdges[i].edgeIndex(), offsetEdges[j].edgeIndex())) {
- firstFitFound = true;
- firstFitRect = potentialFirstFitRect;
- }
- }
- }
- }
-
- if (firstFitFound)
- result = LayoutUnit::fromFloatCeil(firstFitRect.y());
- return firstFitFound;
+ paths.shape.moveTo(m_polygon.vertexAt(0));
+ for (size_t i = 1; i < m_polygon.numberOfVertices(); ++i)
+ paths.shape.addLineTo(m_polygon.vertexAt(i));
+ paths.shape.closeSubpath();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.h
index 38b0d8e75c7..f7171c929f4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/PolygonShape.h
@@ -31,79 +31,48 @@
#define PolygonShape_h
#include "core/rendering/shapes/Shape.h"
+#include "core/rendering/shapes/ShapeInterval.h"
#include "platform/geometry/FloatPolygon.h"
namespace WebCore {
-class OffsetPolygonEdge : public VertexPair {
+class OffsetPolygonEdge FINAL : public VertexPair {
public:
- enum Basis {
- Edge,
- Vertex,
- LineTop
- };
-
OffsetPolygonEdge(const FloatPolygonEdge& edge, const FloatSize& offset)
: m_vertex1(edge.vertex1() + offset)
, m_vertex2(edge.vertex2() + offset)
- , m_edgeIndex(edge.edgeIndex())
- , m_basis(Edge)
- {
- }
-
- OffsetPolygonEdge(const FloatPoint& reflexVertex, const FloatSize& offset1, const FloatSize& offset2)
- : m_vertex1(reflexVertex + offset1)
- , m_vertex2(reflexVertex + offset2)
- , m_edgeIndex(-1)
- , m_basis(Vertex)
- {
- }
-
- OffsetPolygonEdge(const FloatPolygon& polygon, float minLogicalIntervalTop, const FloatSize& offset)
- : m_vertex1(FloatPoint(polygon.boundingBox().x(), minLogicalIntervalTop) + offset)
- , m_vertex2(FloatPoint(polygon.boundingBox().maxX(), minLogicalIntervalTop) + offset)
- , m_edgeIndex(-1)
- , m_basis(LineTop)
{
}
virtual const FloatPoint& vertex1() const OVERRIDE { return m_vertex1; }
virtual const FloatPoint& vertex2() const OVERRIDE { return m_vertex2; }
- int edgeIndex() const { return m_edgeIndex; }
- Basis basis() const { return m_basis; }
+
+ bool isWithinYRange(float y1, float y2) const { return y1 <= minY() && y2 >= maxY(); }
+ bool overlapsYRange(float y1, float y2) const { return y2 >= minY() && y1 <= maxY(); }
+ float xIntercept(float y) const;
+ FloatShapeInterval clippedEdgeXRange(float y1, float y2) const;
private:
FloatPoint m_vertex1;
FloatPoint m_vertex2;
- int m_edgeIndex;
- Basis m_basis;
};
-class PolygonShape : public Shape {
+class PolygonShape FINAL : public Shape {
WTF_MAKE_NONCOPYABLE(PolygonShape);
public:
PolygonShape(PassOwnPtr<Vector<FloatPoint> > vertices, WindRule fillRule)
: Shape()
, m_polygon(vertices, fillRule)
- , m_marginBounds(nullptr)
- , m_paddingBounds(nullptr)
{
}
- virtual LayoutRect shapeMarginLogicalBoundingBox() const OVERRIDE { return static_cast<LayoutRect>(shapeMarginBounds().boundingBox()); }
- virtual LayoutRect shapePaddingLogicalBoundingBox() const OVERRIDE { return static_cast<LayoutRect>(shapePaddingBounds().boundingBox()); }
+ virtual LayoutRect shapeMarginLogicalBoundingBox() const OVERRIDE;
virtual bool isEmpty() const OVERRIDE { return m_polygon.isEmpty(); }
virtual void getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const OVERRIDE;
- virtual void getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const OVERRIDE;
- virtual bool firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit&) const OVERRIDE;
+ virtual void buildDisplayPaths(DisplayPaths&) const OVERRIDE;
private:
- const FloatPolygon& shapeMarginBounds() const;
- const FloatPolygon& shapePaddingBounds() const;
-
FloatPolygon m_polygon;
- mutable OwnPtr<FloatPolygon> m_marginBounds;
- mutable OwnPtr<FloatPolygon> m_paddingBounds;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.cpp
index 78b00211519..8dda343bc66 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.cpp
@@ -73,182 +73,67 @@ IntShapeInterval MarginIntervalGenerator::intervalAt(int y) const
return IntShapeInterval(m_x1 - dx, m_x2 + dx);
}
-void RasterShapeIntervals::appendInterval(int y, int x1, int x2)
+PassOwnPtr<RasterShapeIntervals> RasterShapeIntervals::computeShapeMarginIntervals(int shapeMargin) const
{
- ASSERT(x2 > x1 && (intervalsAt(y).isEmpty() || x1 > intervalsAt(y).last().x2()));
- m_bounds.unite(IntRect(x1, y, x2 - x1, 1));
- intervalsAt(y).append(IntShapeInterval(x1, x2));
-}
-
-void RasterShapeIntervals::uniteMarginInterval(int y, const IntShapeInterval& interval)
-{
- ASSERT(intervalsAt(y).size() <= 1); // Each m_intervalLists entry has 0 or one interval.
-
- if (intervalsAt(y).isEmpty()) {
- intervalsAt(y).append(interval);
- } else {
- IntShapeInterval& resultInterval = intervalsAt(y)[0];
- resultInterval.set(std::min(resultInterval.x1(), interval.x1()), std::max(resultInterval.x2(), interval.x2()));
- }
-
- m_bounds.unite(IntRect(interval.x1(), y, interval.width(), 1));
-}
-
-static inline bool shapeIntervalsContain(const IntShapeIntervals& intervals, const IntShapeInterval& interval)
-{
- for (unsigned i = 0; i < intervals.size(); i++) {
- if (intervals[i].x1() > interval.x2())
- return false;
- if (intervals[i].contains(interval))
- return true;
- }
-
- return false;
-}
-
-bool RasterShapeIntervals::contains(const IntRect& rect) const
-{
- if (!bounds().contains(rect))
- return false;
-
- const IntShapeInterval& rectInterval = IntShapeInterval(rect.x(), rect.maxX());
- for (int y = rect.y(); y < rect.maxY(); y++) {
- if (!shapeIntervalsContain(intervalsAt(y), rectInterval))
- return false;
- }
-
- return true;
-}
-
-static inline void appendX1Values(const IntShapeIntervals& intervals, int minIntervalWidth, Vector<int>& result)
-{
- for (unsigned i = 0; i < intervals.size(); i++) {
- if (intervals[i].width() >= minIntervalWidth)
- result.append(intervals[i].x1());
- }
-}
-
-bool RasterShapeIntervals::getIntervalX1Values(int y1, int y2, int minIntervalWidth, Vector<int>& result) const
-{
- ASSERT(y1 >= 0 && y2 > y1);
-
- for (int y = y1; y < y2; y++) {
- if (intervalsAt(y).isEmpty())
- return false;
- }
-
- appendX1Values(intervalsAt(y1), minIntervalWidth, result);
- for (int y = y1 + 1; y < y2; y++) {
- if (intervalsAt(y) != intervalsAt(y - 1))
- appendX1Values(intervalsAt(y), minIntervalWidth, result);
- }
-
- return true;
-}
-
-bool RasterShapeIntervals::firstIncludedIntervalY(int minY, const IntSize& minSize, LayoutUnit& result) const
-{
- minY = std::max<int>(bounds().y(), minY);
-
- ASSERT(minY >= 0 && minY < size());
-
- if (minSize.isEmpty() || minSize.width() > bounds().width())
- return false;
+ int marginIntervalsSize = (offset() > shapeMargin) ? size() : size() - offset() * 2 + shapeMargin * 2;
+ OwnPtr<RasterShapeIntervals> result = adoptPtr(new RasterShapeIntervals(marginIntervalsSize, std::max(shapeMargin, offset())));
+ MarginIntervalGenerator marginIntervalGenerator(shapeMargin);
- for (int lineY = minY; lineY <= bounds().maxY() - minSize.height(); lineY++) {
- Vector<int> intervalX1Values;
- if (!getIntervalX1Values(lineY, lineY + minSize.height(), minSize.width(), intervalX1Values))
+ for (int y = bounds().y(); y < bounds().maxY(); ++y) {
+ const IntShapeInterval& intervalAtY = intervalAt(y);
+ if (intervalAtY.isEmpty())
continue;
- std::sort(intervalX1Values.begin(), intervalX1Values.end());
+ marginIntervalGenerator.set(y, intervalAtY);
+ int marginY0 = std::max(minY(), y - shapeMargin);
+ int marginY1 = std::min(maxY(), y + shapeMargin + 1);
- IntRect firstFitRect(IntPoint(0, 0), minSize);
- for (unsigned i = 0; i < intervalX1Values.size(); i++) {
- int lineX = intervalX1Values[i];
- if (i > 0 && lineX == intervalX1Values[i - 1])
- continue;
- firstFitRect.setLocation(IntPoint(lineX, lineY));
- if (contains(firstFitRect)) {
- result = lineY;
- return true;
- }
+ for (int marginY = y - 1; marginY >= marginY0; --marginY) {
+ if (marginY > bounds().y() && intervalAt(marginY).contains(intervalAtY))
+ break;
+ result->intervalAt(marginY).unite(marginIntervalGenerator.intervalAt(marginY));
}
- }
-
- return false;
-}
-
-void RasterShapeIntervals::getIncludedIntervals(int y1, int y2, IntShapeIntervals& result) const
-{
- ASSERT(y2 >= y1);
- if (y1 < bounds().y() || y2 > bounds().maxY())
- return;
+ result->intervalAt(y).unite(marginIntervalGenerator.intervalAt(y));
- for (int y = y1; y < y2; y++) {
- if (intervalsAt(y).isEmpty())
- return;
+ for (int marginY = y + 1; marginY < marginY1; ++marginY) {
+ if (marginY < bounds().maxY() && intervalAt(marginY).contains(intervalAtY))
+ break;
+ result->intervalAt(marginY).unite(marginIntervalGenerator.intervalAt(marginY));
+ }
}
- result = intervalsAt(y1);
- for (int y = y1 + 1; y < y2 && !result.isEmpty(); y++) {
- IntShapeIntervals intervals;
- IntShapeInterval::intersectShapeIntervals(result, intervalsAt(y), intervals);
- result.swap(intervals);
- }
+ result->initializeBounds();
+ return result.release();
}
-void RasterShapeIntervals::getExcludedIntervals(int y1, int y2, IntShapeIntervals& result) const
+void RasterShapeIntervals::initializeBounds()
{
- ASSERT(y2 >= y1);
-
- if (y2 < bounds().y() || y1 >= bounds().maxY())
- return;
-
- y1 = std::max(y1, bounds().y());
- y2 = std::min(y2, bounds().maxY());
-
- result = intervalsAt(y1);
- for (int y = y1 + 1; y < y2; y++) {
- IntShapeIntervals intervals;
- IntShapeInterval::uniteShapeIntervals(result, intervalsAt(y), intervals);
- result.swap(intervals);
+ m_bounds = IntRect();
+ for (int y = minY(); y < maxY(); ++y) {
+ const IntShapeInterval& intervalAtY = intervalAt(y);
+ if (intervalAtY.isEmpty())
+ continue;
+ m_bounds.unite(IntRect(intervalAtY.x1(), y, intervalAtY.width(), 1));
}
}
-PassOwnPtr<RasterShapeIntervals> RasterShapeIntervals::computeShapeMarginIntervals(unsigned shapeMargin) const
+void RasterShapeIntervals::buildBoundsPath(Path& path) const
{
- OwnPtr<RasterShapeIntervals> result = adoptPtr(new RasterShapeIntervals(size(), shapeMargin));
- MarginIntervalGenerator marginIntervalGenerator(shapeMargin);
-
- int minY = bounds().y();
int maxY = bounds().maxY();
-
- for (int y = minY; y < maxY; ++y) {
- const IntShapeInterval& intervalAtY = limitIntervalAt(y);
- if (intervalAtY.isEmpty())
+ for (int y = bounds().y(); y < maxY; y++) {
+ if (intervalAt(y).isEmpty())
continue;
- marginIntervalGenerator.set(y, intervalAtY);
- int marginY0 = y - clampToInteger(shapeMargin);
- int marginY1 = y + clampToInteger(shapeMargin);
-
- for (int marginY = y - 1; marginY >= marginY0; --marginY) {
- if (marginY > minY && limitIntervalAt(marginY).contains(intervalAtY))
+ IntShapeInterval extent = intervalAt(y);
+ int endY = y + 1;
+ for (; endY < maxY; endY++) {
+ if (intervalAt(endY).isEmpty() || intervalAt(endY) != extent)
break;
- result->uniteMarginInterval(marginY, marginIntervalGenerator.intervalAt(marginY));
- }
-
- result->uniteMarginInterval(y, marginIntervalGenerator.intervalAt(y));
-
- for (int marginY = y + 1; marginY <= marginY1; ++marginY) {
- if (marginY < maxY && limitIntervalAt(marginY).contains(intervalAtY))
- break;
- result->uniteMarginInterval(marginY, marginIntervalGenerator.intervalAt(marginY));
}
+ path.addRect(FloatRect(extent.x1(), y, extent.width(), endY - y));
+ y = endY - 1;
}
-
- return result.release();
}
const RasterShapeIntervals& RasterShape::marginIntervals() const
@@ -257,58 +142,37 @@ const RasterShapeIntervals& RasterShape::marginIntervals() const
if (!shapeMargin())
return *m_intervals;
- unsigned marginBoundaryRadius = std::min(clampToUnsigned(ceil(shapeMargin())), std::max<unsigned>(m_imageSize.width(), m_imageSize.height()));
+ int shapeMarginInt = clampToPositiveInteger(ceil(shapeMargin()));
+ int maxShapeMarginInt = std::max(m_marginRectSize.width(), m_marginRectSize.height()) * sqrtf(2);
if (!m_marginIntervals)
- m_marginIntervals = m_intervals->computeShapeMarginIntervals(marginBoundaryRadius);
+ m_marginIntervals = m_intervals->computeShapeMarginIntervals(std::min(shapeMarginInt, maxShapeMarginInt));
return *m_marginIntervals;
}
-const RasterShapeIntervals& RasterShape::paddingIntervals() const
-{
- ASSERT(shapePadding() >= 0);
- if (!shapePadding())
- return *m_intervals;
-
- // FIXME: Add support for non-zero padding, see https://bugs.webkit.org/show_bug.cgi?id=116348.
- return *m_intervals;
-}
-
-static inline void appendLineSegments(const IntShapeIntervals& intervals, SegmentList& result)
-{
- for (unsigned i = 0; i < intervals.size(); i++)
- result.append(LineSegment(intervals[i].x1(), intervals[i].x2() + 1));
-}
-
void RasterShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
{
const RasterShapeIntervals& intervals = marginIntervals();
if (intervals.isEmpty())
return;
- IntShapeIntervals excludedIntervals;
- intervals.getExcludedIntervals(logicalTop, logicalTop + logicalHeight, excludedIntervals);
- appendLineSegments(excludedIntervals, result);
-}
-
-void RasterShape::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
-{
- const RasterShapeIntervals& intervals = paddingIntervals();
- if (intervals.isEmpty())
+ int y1 = logicalTop;
+ int y2 = logicalTop + logicalHeight;
+ ASSERT(y2 >= y1);
+ if (y2 < intervals.bounds().y() || y1 >= intervals.bounds().maxY())
return;
- IntShapeIntervals includedIntervals;
- intervals.getIncludedIntervals(logicalTop, logicalTop + logicalHeight, includedIntervals);
- appendLineSegments(includedIntervals, result);
-}
+ y1 = std::max(y1, intervals.bounds().y());
+ y2 = std::min(y2, intervals.bounds().maxY());
+ IntShapeInterval excludedInterval;
-bool RasterShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit& result) const
-{
- const RasterShapeIntervals& intervals = paddingIntervals();
- if (intervals.isEmpty())
- return false;
+ for (int y = y1; y < y2; y++)
+ excludedInterval.unite(intervals.intervalAt(y));
- return intervals.firstIncludedIntervalY(minLogicalIntervalTop.floor(), flooredIntSize(minLogicalIntervalSize), result);
+ // Note: |marginIntervals()| returns end-point exclusive
+ // intervals. |excludedInterval.x2()| contains the left-most pixel
+ // offset to the right of the calculated union.
+ result.append(LineSegment(excludedInterval.x1(), excludedInterval.x2()));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.h
index 903eabb0527..0ca8d8a5ba9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/RasterShape.h
@@ -40,74 +40,69 @@ namespace WebCore {
class RasterShapeIntervals {
public:
- RasterShapeIntervals(unsigned size, unsigned shapeMargin = 0)
- : m_shapeMargin(shapeMargin)
+ RasterShapeIntervals(unsigned size, int offset = 0)
+ : m_offset(offset)
{
- m_intervalLists.resize(size + shapeMargin * 2);
+ m_intervals.resize(clampTo<int>(size));
}
+ void initializeBounds();
const IntRect& bounds() const { return m_bounds; }
bool isEmpty() const { return m_bounds.isEmpty(); }
- void appendInterval(int y, int x1, int x2);
- void getIncludedIntervals(int y1, int y2, IntShapeIntervals& result) const;
- void getExcludedIntervals(int y1, int y2, IntShapeIntervals& result) const;
- bool firstIncludedIntervalY(int minY, const IntSize& minSize, LayoutUnit& result) const;
- PassOwnPtr<RasterShapeIntervals> computeShapeMarginIntervals(unsigned shapeMargin) const;
-
-private:
- int size() const { return m_intervalLists.size(); }
-
- IntShapeIntervals& intervalsAt(int y)
+ IntShapeInterval& intervalAt(int y)
{
- ASSERT(y + m_shapeMargin >= 0 && y + m_shapeMargin < m_intervalLists.size());
- return m_intervalLists[y + m_shapeMargin];
+ ASSERT(y + m_offset >= 0 && static_cast<unsigned>(y + m_offset) < m_intervals.size());
+ return m_intervals[y + m_offset];
}
- const IntShapeIntervals& intervalsAt(int y) const
+ const IntShapeInterval& intervalAt(int y) const
{
- ASSERT(y + m_shapeMargin >= 0 && y + m_shapeMargin < m_intervalLists.size());
- return m_intervalLists[y + m_shapeMargin];
+ ASSERT(y + m_offset >= 0 && static_cast<unsigned>(y + m_offset) < m_intervals.size());
+ return m_intervals[y + m_offset];
}
- IntShapeInterval limitIntervalAt(int y) const
- {
- const IntShapeIntervals& intervals = intervalsAt(y);
- return intervals.size() ? IntShapeInterval(intervals[0].x1(), intervals.last().x2()) : IntShapeInterval();
- }
+ PassOwnPtr<RasterShapeIntervals> computeShapeMarginIntervals(int shapeMargin) const;
+
+ void buildBoundsPath(Path&) const;
+
+private:
+ int size() const { return m_intervals.size(); }
+ int offset() const { return m_offset; }
+ int minY() const { return -m_offset; }
+ int maxY() const { return -m_offset + m_intervals.size(); }
- bool contains(const IntRect&) const;
- bool getIntervalX1Values(int minY, int maxY, int minIntervalWidth, Vector<int>& result) const;
- void uniteMarginInterval(int y, const IntShapeInterval&);
IntRect m_bounds;
- Vector<IntShapeIntervals> m_intervalLists;
- unsigned m_shapeMargin;
+ Vector<IntShapeInterval> m_intervals;
+ int m_offset;
};
-class RasterShape : public Shape {
+class RasterShape FINAL : public Shape {
WTF_MAKE_NONCOPYABLE(RasterShape);
public:
- RasterShape(PassOwnPtr<RasterShapeIntervals> intervals, const IntSize& imageSize)
- : Shape()
- , m_intervals(intervals)
- , m_imageSize(imageSize)
+ RasterShape(PassOwnPtr<RasterShapeIntervals> intervals, const IntSize& marginRectSize)
+ : m_intervals(intervals)
+ , m_marginRectSize(marginRectSize)
{
+ m_intervals->initializeBounds();
}
virtual LayoutRect shapeMarginLogicalBoundingBox() const OVERRIDE { return static_cast<LayoutRect>(marginIntervals().bounds()); }
- virtual LayoutRect shapePaddingLogicalBoundingBox() const OVERRIDE { return static_cast<LayoutRect>(paddingIntervals().bounds()); }
virtual bool isEmpty() const OVERRIDE { return m_intervals->isEmpty(); }
virtual void getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const OVERRIDE;
- virtual void getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const OVERRIDE;
- virtual bool firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit&) const OVERRIDE;
+ virtual void buildDisplayPaths(DisplayPaths& paths) const OVERRIDE
+ {
+ m_intervals->buildBoundsPath(paths.shape);
+ if (shapeMargin())
+ marginIntervals().buildBoundsPath(paths.marginShape);
+ }
private:
const RasterShapeIntervals& marginIntervals() const;
- const RasterShapeIntervals& paddingIntervals() const;
OwnPtr<RasterShapeIntervals> m_intervals;
mutable OwnPtr<RasterShapeIntervals> m_marginIntervals;
- IntSize m_imageSize;
+ IntSize m_marginRectSize;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.cpp
index efe1f69831b..eaf51424c83 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.cpp
@@ -40,26 +40,6 @@ static inline float ellipseXIntercept(float y, float rx, float ry)
return rx * sqrt(1 - (y * y) / (ry * ry));
}
-static inline float ellipseYIntercept(float x, float rx, float ry)
-{
- ASSERT(rx > 0);
- return ry * sqrt(1 - (x * x) / (rx * rx));
-}
-
-FloatRect RectangleShape::shapePaddingBounds() const
-{
- ASSERT(shapePadding() >= 0);
- if (!shapePadding() || isEmpty())
- return m_bounds;
-
- float boundsX = x() + std::min(width() / 2, shapePadding());
- float boundsY = y() + std::min(height() / 2, shapePadding());
- float boundsWidth = std::max(0.0f, width() - shapePadding() * 2);
- float boundsHeight = std::max(0.0f, height() - shapePadding() * 2);
-
- return FloatRect(boundsX, boundsY, boundsWidth, boundsHeight);
-}
-
FloatRect RectangleShape::shapeMarginBounds() const
{
ASSERT(shapeMargin() >= 0);
@@ -79,8 +59,8 @@ void RectangleShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logi
if (bounds.isEmpty())
return;
- float y1 = logicalTop;
- float y2 = logicalTop + logicalHeight;
+ float y1 = logicalTop.toFloat();
+ float y2 = (logicalTop + logicalHeight).toFloat();
if (y2 < bounds.y() || y1 >= bounds.maxY())
return;
@@ -108,112 +88,11 @@ void RectangleShape::getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logi
result.append(LineSegment(x1, x2));
}
-void RectangleShape::getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList& result) const
+void RectangleShape::buildDisplayPaths(DisplayPaths& paths) const
{
- const FloatRect& bounds = shapePaddingBounds();
- if (bounds.isEmpty())
- return;
-
- float y1 = logicalTop;
- float y2 = logicalTop + logicalHeight;
-
- if (y1 < bounds.y() || y2 > bounds.maxY())
- return;
-
- float x1 = bounds.x();
- float x2 = bounds.maxX();
-
- float paddingRadiusX = std::max(0.0f, rx() - shapePadding());
- float paddingRadiusY = std::max(0.0f, ry() - shapePadding());
-
- if (paddingRadiusX > 0) {
- bool y1InterceptsCorner = y1 < bounds.y() + paddingRadiusY;
- bool y2InterceptsCorner = y2 > bounds.maxY() - paddingRadiusY;
- float xi = 0;
-
- if (y1InterceptsCorner && y2InterceptsCorner) {
- if (y1 < bounds.height() + 2 * bounds.y() - y2) {
- float yi = y1 - bounds.y() - paddingRadiusY;
- xi = ellipseXIntercept(yi, paddingRadiusX, paddingRadiusY);
- } else {
- float yi = y2 - (bounds.maxY() - paddingRadiusY);
- xi = ellipseXIntercept(yi, paddingRadiusX, paddingRadiusY);
- }
- } else if (y1InterceptsCorner) {
- float yi = y1 - bounds.y() - paddingRadiusY;
- xi = ellipseXIntercept(yi, paddingRadiusX, paddingRadiusY);
- } else if (y2InterceptsCorner) {
- float yi = y2 - (bounds.maxY() - paddingRadiusY);
- xi = ellipseXIntercept(yi, paddingRadiusX, paddingRadiusY);
- }
-
- if (y1InterceptsCorner || y2InterceptsCorner) {
- x1 = bounds.x() + paddingRadiusX - xi;
- x2 = bounds.maxX() - paddingRadiusX + xi;
- }
- }
-
- result.append(LineSegment(x1, x2));
-}
-
-static FloatPoint cornerInterceptForWidth(float width, float widthAtIntercept, float rx, float ry)
-{
- float xi = (width - widthAtIntercept) / 2;
- float yi = ry - ellipseYIntercept(rx - xi, rx, ry);
- return FloatPoint(xi, yi);
-}
-
-bool RectangleShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit& result) const
-{
- float minIntervalTop = minLogicalIntervalTop;
- float minIntervalHeight = minLogicalIntervalSize.height();
- float minIntervalWidth = minLogicalIntervalSize.width();
-
- const FloatRect& bounds = shapePaddingBounds();
- if (bounds.isEmpty() || minIntervalWidth > bounds.width())
- return false;
-
- float minY = LayoutUnit::fromFloatCeil(std::max(bounds.y(), minIntervalTop));
- float maxY = minY + minIntervalHeight;
-
- if (maxY > bounds.maxY())
- return false;
-
- float paddingRadiusX = std::max(0.0f, rx() - shapePadding());
- float paddingRadiusY = std::max(0.0f, ry() - shapePadding());
-
- bool intervalOverlapsMinCorner = minY < bounds.y() + paddingRadiusY;
- bool intervalOverlapsMaxCorner = maxY > bounds.maxY() - paddingRadiusY;
-
- if (!intervalOverlapsMinCorner && !intervalOverlapsMaxCorner) {
- result = minY;
- return true;
- }
-
- float centerY = bounds.y() + bounds.height() / 2;
- bool minCornerDefinesX = fabs(centerY - minY) > fabs(centerY - maxY);
- bool intervalFitsWithinCorners = minIntervalWidth + 2 * paddingRadiusX <= bounds.width();
- FloatPoint cornerIntercept = cornerInterceptForWidth(bounds.width(), minIntervalWidth, paddingRadiusX, paddingRadiusY);
-
- if (intervalOverlapsMinCorner && (!intervalOverlapsMaxCorner || minCornerDefinesX)) {
- if (intervalFitsWithinCorners || bounds.y() + cornerIntercept.y() < minY) {
- result = minY;
- return true;
- }
- if (minIntervalHeight < bounds.height() - (2 * cornerIntercept.y())) {
- result = LayoutUnit::fromFloatCeil(bounds.y() + cornerIntercept.y());
- return true;
- }
- }
-
- if (intervalOverlapsMaxCorner && (!intervalOverlapsMinCorner || !minCornerDefinesX)) {
- if (intervalFitsWithinCorners || minY <= bounds.maxY() - cornerIntercept.y() - minIntervalHeight) {
- result = minY;
- return true;
- }
- }
-
- return false;
+ paths.shape.addRoundedRect(m_bounds, m_radii);
+ if (shapeMargin())
+ paths.marginShape.addRoundedRect(shapeMarginBounds(), FloatSize(m_radii.width() + shapeMargin(), m_radii.height() + shapeMargin()));
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.h
index 9a9dae5522e..d47471da48f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/RectangleShape.h
@@ -39,7 +39,7 @@
namespace WebCore {
-class RectangleShape : public Shape {
+class RectangleShape FINAL : public Shape {
public:
RectangleShape(const FloatRect& bounds, const FloatSize& radii)
: Shape()
@@ -49,15 +49,12 @@ public:
}
virtual LayoutRect shapeMarginLogicalBoundingBox() const OVERRIDE { return static_cast<LayoutRect>(shapeMarginBounds()); }
- virtual LayoutRect shapePaddingLogicalBoundingBox() const OVERRIDE { return static_cast<LayoutRect>(shapePaddingBounds()); }
virtual bool isEmpty() const OVERRIDE { return m_bounds.isEmpty(); }
virtual void getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const OVERRIDE;
- virtual void getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const OVERRIDE;
- virtual bool firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit&) const OVERRIDE;
+ virtual void buildDisplayPaths(DisplayPaths&) const OVERRIDE;
private:
FloatRect shapeMarginBounds() const;
- FloatRect shapePaddingBounds() const;
float rx() const { return m_radii.width(); }
float ry() const { return m_radii.height(); }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.cpp
index ffe05053133..6e382254b9a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.cpp
@@ -30,14 +30,16 @@
#include "config.h"
#include "core/rendering/shapes/Shape.h"
+#include "core/css/BasicShapeFunctions.h"
#include "core/fetch/ImageResource.h"
#include "core/rendering/shapes/BoxShape.h"
#include "core/rendering/shapes/PolygonShape.h"
#include "core/rendering/shapes/RasterShape.h"
#include "core/rendering/shapes/RectangleShape.h"
+#include "core/rendering/style/RenderStyle.h"
#include "platform/LengthFunctions.h"
-#include "platform/geometry/FloatRoundedRect.h"
#include "platform/geometry/FloatSize.h"
+#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/WindRule.h"
#include "wtf/MathExtras.h"
@@ -45,18 +47,12 @@
namespace WebCore {
-static PassOwnPtr<Shape> createBoxShape(const FloatRoundedRect& bounds)
+static PassOwnPtr<Shape> createInsetShape(const FloatRoundedRect& bounds)
{
ASSERT(bounds.rect().width() >= 0 && bounds.rect().height() >= 0);
return adoptPtr(new BoxShape(bounds));
}
-static PassOwnPtr<Shape> createRectangleShape(const FloatRect& bounds, const FloatSize& radii)
-{
- ASSERT(bounds.width() >= 0 && bounds.height() >= 0 && radii.width() >= 0 && radii.height() >= 0);
- return adoptPtr(new RectangleShape(bounds, radii));
-}
-
static PassOwnPtr<Shape> createCircleShape(const FloatPoint& center, float radius)
{
ASSERT(radius >= 0);
@@ -99,55 +95,22 @@ static inline FloatSize physicalSizeToLogical(const FloatSize& size, WritingMode
return size.transposedSize();
}
-static inline void ensureRadiiDoNotOverlap(FloatRect &bounds, FloatSize &radii)
-{
- float widthRatio = bounds.width() / (2 * radii.width());
- float heightRatio = bounds.height() / (2 * radii.height());
- float reductionRatio = std::min<float>(widthRatio, heightRatio);
- if (reductionRatio < 1) {
- radii.setWidth(reductionRatio * radii.width());
- radii.setHeight(reductionRatio * radii.height());
- }
-}
-
-PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutSize& logicalBoxSize, WritingMode writingMode, Length margin, Length padding)
+PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutSize& logicalBoxSize, WritingMode writingMode, float margin)
{
ASSERT(basicShape);
bool horizontalWritingMode = isHorizontalWritingMode(writingMode);
- float boxWidth = horizontalWritingMode ? logicalBoxSize.width() : logicalBoxSize.height();
- float boxHeight = horizontalWritingMode ? logicalBoxSize.height() : logicalBoxSize.width();
+ float boxWidth = horizontalWritingMode ? logicalBoxSize.width().toFloat() : logicalBoxSize.height().toFloat();
+ float boxHeight = horizontalWritingMode ? logicalBoxSize.height().toFloat() : logicalBoxSize.width().toFloat();
OwnPtr<Shape> shape;
switch (basicShape->type()) {
- case BasicShape::BasicShapeRectangleType: {
- const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
- FloatRect bounds(
- floatValueForLength(rectangle->x(), boxWidth),
- floatValueForLength(rectangle->y(), boxHeight),
- floatValueForLength(rectangle->width(), boxWidth),
- floatValueForLength(rectangle->height(), boxHeight));
- FloatSize cornerRadii(
- floatValueForLength(rectangle->cornerRadiusX(), boxWidth),
- floatValueForLength(rectangle->cornerRadiusY(), boxHeight));
- ensureRadiiDoNotOverlap(bounds, cornerRadii);
- FloatRect logicalBounds = physicalRectToLogical(bounds, logicalBoxSize.height(), writingMode);
-
- shape = createRectangleShape(logicalBounds, physicalSizeToLogical(cornerRadii, writingMode));
- break;
- }
-
case BasicShape::BasicShapeCircleType: {
const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
- float centerX = floatValueForLength(circle->centerX(), boxWidth);
- float centerY = floatValueForLength(circle->centerY(), boxHeight);
- // This method of computing the radius is as defined in SVG
- // (http://www.w3.org/TR/SVG/coords.html#Units). It bases the radius
- // off of the diagonal of the box and ensures that if the box is
- // square, the radius is equal to half the diagonal.
- float radius = floatValueForLength(circle->radius(), sqrtf((boxWidth * boxWidth + boxHeight * boxHeight) / 2));
- FloatPoint logicalCenter = physicalPointToLogical(FloatPoint(centerX, centerY), logicalBoxSize.height(), writingMode);
+ FloatPoint center = floatPointForCenterCoordinate(circle->centerX(), circle->centerY(), FloatSize(boxWidth, boxHeight));
+ float radius = circle->floatValueForRadiusInBox(FloatSize(boxWidth, boxHeight));
+ FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize.height().toFloat(), writingMode);
shape = createCircleShape(logicalCenter, radius);
break;
@@ -155,14 +118,12 @@ PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutS
case BasicShape::BasicShapeEllipseType: {
const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
- float centerX = floatValueForLength(ellipse->centerX(), boxWidth);
- float centerY = floatValueForLength(ellipse->centerY(), boxHeight);
- float radiusX = floatValueForLength(ellipse->radiusX(), boxWidth);
- float radiusY = floatValueForLength(ellipse->radiusY(), boxHeight);
- FloatPoint logicalCenter = physicalPointToLogical(FloatPoint(centerX, centerY), logicalBoxSize.height(), writingMode);
- FloatSize logicalRadii = physicalSizeToLogical(FloatSize(radiusX, radiusY), writingMode);
-
- shape = createEllipseShape(logicalCenter, logicalRadii);
+ FloatPoint center = floatPointForCenterCoordinate(ellipse->centerX(), ellipse->centerY(), FloatSize(boxWidth, boxHeight));
+ float radiusX = ellipse->floatValueForRadiusInBox(ellipse->radiusX(), center.x(), boxWidth);
+ float radiusY = ellipse->floatValueForRadiusInBox(ellipse->radiusY(), center.y(), boxHeight);
+ FloatPoint logicalCenter = physicalPointToLogical(center, logicalBoxSize.height().toFloat(), writingMode);
+
+ shape = createEllipseShape(logicalCenter, FloatSize(radiusX, radiusY));
break;
}
@@ -176,28 +137,31 @@ PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutS
FloatPoint vertex(
floatValueForLength(values.at(i), boxWidth),
floatValueForLength(values.at(i + 1), boxHeight));
- (*vertices)[i / 2] = physicalPointToLogical(vertex, logicalBoxSize.height(), writingMode);
+ (*vertices)[i / 2] = physicalPointToLogical(vertex, logicalBoxSize.height().toFloat(), writingMode);
}
shape = createPolygonShape(vertices.release(), polygon->windRule());
break;
}
- case BasicShape::BasicShapeInsetRectangleType: {
- const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShapeInsetRectangle*>(basicShape);
- float left = floatValueForLength(rectangle->left(), boxWidth);
- float top = floatValueForLength(rectangle->top(), boxHeight);
- FloatRect bounds(
- left,
- top,
- boxWidth - left - floatValueForLength(rectangle->right(), boxWidth),
- boxHeight - top - floatValueForLength(rectangle->bottom(), boxHeight));
- FloatSize cornerRadii(
- floatValueForLength(rectangle->cornerRadiusX(), boxWidth),
- floatValueForLength(rectangle->cornerRadiusY(), boxHeight));
- ensureRadiiDoNotOverlap(bounds, cornerRadii);
- FloatRect logicalBounds = physicalRectToLogical(bounds, logicalBoxSize.height(), writingMode);
-
- shape = createRectangleShape(logicalBounds, physicalSizeToLogical(cornerRadii, writingMode));
+ case BasicShape::BasicShapeInsetType: {
+ const BasicShapeInset& inset = *static_cast<const BasicShapeInset*>(basicShape);
+ float left = floatValueForLength(inset.left(), boxWidth);
+ float top = floatValueForLength(inset.top(), boxHeight);
+ float right = floatValueForLength(inset.right(), boxWidth);
+ float bottom = floatValueForLength(inset.bottom(), boxHeight);
+ FloatRect rect(left, top, std::max<float>(boxWidth - left - right, 0), std::max<float>(boxHeight - top - bottom, 0));
+ FloatRect logicalRect = physicalRectToLogical(rect, logicalBoxSize.height().toFloat(), writingMode);
+
+ FloatSize boxSize(boxWidth, boxHeight);
+ FloatSize topLeftRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.topLeftRadius(), boxSize), writingMode);
+ FloatSize topRightRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.topRightRadius(), boxSize), writingMode);
+ FloatSize bottomLeftRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.bottomLeftRadius(), boxSize), writingMode);
+ FloatSize bottomRightRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.bottomRightRadius(), boxSize), writingMode);
+ FloatRoundedRect::Radii cornerRadii(topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+
+ cornerRadii.scale(calcBorderRadiiConstraintScaleFor(logicalRect, cornerRadii));
+
+ shape = createInsetShape(FloatRoundedRect(logicalRect, cornerRadii));
break;
}
@@ -206,61 +170,60 @@ PassOwnPtr<Shape> Shape::createShape(const BasicShape* basicShape, const LayoutS
}
shape->m_writingMode = writingMode;
- shape->m_margin = floatValueForLength(margin, 0);
- shape->m_padding = floatValueForLength(padding, 0);
+ shape->m_margin = margin;
return shape.release();
}
-PassOwnPtr<Shape> Shape::createShape(const StyleImage* styleImage, float threshold, const LayoutSize&, WritingMode writingMode, Length margin, Length padding)
+PassOwnPtr<Shape> Shape::createRasterShape(Image* image, float threshold, const LayoutRect& imageR, const LayoutRect& marginR, WritingMode writingMode, float margin)
{
- ASSERT(styleImage && styleImage->isImageResource() && styleImage->cachedImage() && styleImage->cachedImage()->image());
+ IntRect imageRect = pixelSnappedIntRect(imageR);
+ IntRect marginRect = pixelSnappedIntRect(marginR);
+ OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(marginRect.height(), -marginRect.y()));
+ OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(imageRect.size());
- Image* image = styleImage->cachedImage()->image();
- const IntSize& imageSize = image->size();
- OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(imageSize.height()));
- OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(imageSize);
if (imageBuffer) {
GraphicsContext* graphicsContext = imageBuffer->context();
- graphicsContext->drawImage(image, IntPoint());
+ graphicsContext->drawImage(image, IntRect(IntPoint(), imageRect.size()));
- RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getUnmultipliedImageData(IntRect(IntPoint(), imageSize));
- unsigned pixelArrayLength = pixelArray->length();
+ RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getUnmultipliedImageData(IntRect(IntPoint(), imageRect.size()));
unsigned pixelArrayOffset = 3; // Each pixel is four bytes: RGBA.
uint8_t alphaPixelThreshold = threshold * 255;
- ASSERT(static_cast<unsigned>(imageSize.width() * imageSize.height() * 4) == pixelArrayLength);
+ ASSERT(static_cast<unsigned>(imageRect.width() * imageRect.height() * 4) == pixelArray->length());
+
+ int minBufferY = std::max(0, marginRect.y() - imageRect.y());
+ int maxBufferY = std::min(imageRect.height(), marginRect.maxY() - imageRect.y());
- for (int y = 0; y < imageSize.height(); ++y) {
+ for (int y = minBufferY; y < maxBufferY; ++y) {
int startX = -1;
- for (int x = 0; x < imageSize.width() && pixelArrayOffset < pixelArrayLength; ++x, pixelArrayOffset += 4) {
+ for (int x = 0; x < imageRect.width(); ++x, pixelArrayOffset += 4) {
uint8_t alpha = pixelArray->item(pixelArrayOffset);
- if ((startX == -1) && alpha > alphaPixelThreshold) {
+ bool alphaAboveThreshold = alpha > alphaPixelThreshold;
+ if (startX == -1 && alphaAboveThreshold) {
startX = x;
- } else if (startX != -1 && (alpha <= alphaPixelThreshold || x == imageSize.width() - 1)) {
- intervals->appendInterval(y, startX, x);
+ } else if (startX != -1 && (!alphaAboveThreshold || x == imageRect.width() - 1)) {
+ int endX = alphaAboveThreshold ? x + 1 : x;
+ intervals->intervalAt(y + imageRect.y()).unite(IntShapeInterval(startX + imageRect.x(), endX + imageRect.x()));
startX = -1;
}
}
}
}
- OwnPtr<RasterShape> rasterShape = adoptPtr(new RasterShape(intervals.release(), imageSize));
+ OwnPtr<RasterShape> rasterShape = adoptPtr(new RasterShape(intervals.release(), marginRect.size()));
rasterShape->m_writingMode = writingMode;
- rasterShape->m_margin = floatValueForLength(margin, 0);
- rasterShape->m_padding = floatValueForLength(padding, 0);
+ rasterShape->m_margin = margin;
return rasterShape.release();
}
-PassOwnPtr<Shape> Shape::createLayoutBoxShape(const LayoutSize& logicalSize, WritingMode writingMode, const Length& margin, const Length& padding)
+PassOwnPtr<Shape> Shape::createLayoutBoxShape(const RoundedRect& roundedRect, WritingMode writingMode, float margin)
{
- FloatRect rect(0, 0, logicalSize.width(), logicalSize.height());
- FloatSize radii(0, 0);
- FloatRoundedRect bounds(rect, radii, radii, radii, radii);
- OwnPtr<Shape> shape = createBoxShape(bounds);
+ FloatRect rect(0, 0, roundedRect.rect().width(), roundedRect.rect().height());
+ FloatRoundedRect bounds(rect, roundedRect.radii());
+ OwnPtr<Shape> shape = createInsetShape(bounds);
shape->m_writingMode = writingMode;
- shape->m_margin = floatValueForLength(margin, 0);
- shape->m_padding = floatValueForLength(padding, 0);
+ shape->m_margin = margin;
return shape.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.h
index de9aef9f99d..fb649957671 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/Shape.h
@@ -33,6 +33,8 @@
#include "core/rendering/style/BasicShapes.h"
#include "core/rendering/style/StyleImage.h"
#include "platform/geometry/LayoutRect.h"
+#include "platform/geometry/RoundedRect.h"
+#include "platform/graphics/Path.h"
#include "platform/text/WritingMode.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/Vector.h"
@@ -60,24 +62,25 @@ typedef Vector<LineSegment> SegmentList;
class Shape {
public:
- static PassOwnPtr<Shape> createShape(const BasicShape*, const LayoutSize& logicalBoxSize, WritingMode, Length margin, Length padding);
- static PassOwnPtr<Shape> createShape(const StyleImage*, float threshold, const LayoutSize& logicalBoxSize, WritingMode, Length margin, Length padding);
- static PassOwnPtr<Shape> createLayoutBoxShape(const LayoutSize& logicalBoxSize, WritingMode, const Length& margin, const Length& padding);
+ struct DisplayPaths {
+ Path shape;
+ Path marginShape;
+ };
+ static PassOwnPtr<Shape> createShape(const BasicShape*, const LayoutSize& logicalBoxSize, WritingMode, float margin);
+ static PassOwnPtr<Shape> createRasterShape(Image*, float threshold, const LayoutRect& imageRect, const LayoutRect& marginRect, WritingMode, float margin);
+ static PassOwnPtr<Shape> createLayoutBoxShape(const RoundedRect&, WritingMode, float margin);
virtual ~Shape() { }
virtual LayoutRect shapeMarginLogicalBoundingBox() const = 0;
- virtual LayoutRect shapePaddingLogicalBoundingBox() const = 0;
virtual bool isEmpty() const = 0;
- virtual void getIncludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const = 0;
virtual void getExcludedIntervals(LayoutUnit logicalTop, LayoutUnit logicalHeight, SegmentList&) const = 0;
- virtual bool firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const LayoutSize& minLogicalIntervalSize, LayoutUnit& result) const = 0;
+
bool lineOverlapsShapeMarginBounds(LayoutUnit lineTop, LayoutUnit lineHeight) const { return lineOverlapsBoundingBox(lineTop, lineHeight, shapeMarginLogicalBoundingBox()); }
- bool lineOverlapsShapePaddingBounds(LayoutUnit lineTop, LayoutUnit lineHeight) const { return lineOverlapsBoundingBox(lineTop, lineHeight, shapePaddingLogicalBoundingBox()); }
+ virtual void buildDisplayPaths(DisplayPaths&) const = 0;
protected:
float shapeMargin() const { return m_margin; }
- float shapePadding() const { return m_padding; }
private:
bool lineOverlapsBoundingBox(LayoutUnit lineTop, LayoutUnit lineHeight, const LayoutRect& rect) const
@@ -89,7 +92,6 @@ private:
WritingMode m_writingMode;
float m_margin;
- float m_padding;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInfo.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInfo.cpp
deleted file mode 100644
index e2668712991..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInfo.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/shapes/ShapeInfo.h"
-
-#include "core/rendering/RenderRegion.h"
-
-namespace WebCore {
-
-bool checkShapeImageOrigin(Document& document, ImageResource& imageResource)
-{
- if (imageResource.isAccessAllowed(document.securityOrigin()))
- return true;
-
- const KURL& url = imageResource.url();
- String urlString = url.isNull() ? "''" : url.elidedString();
- document.addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Unsafe attempt to load URL " + urlString + ".");
-
- return false;
-}
-
-template<class RenderType>
-const Shape* ShapeInfo<RenderType>::computedShape() const
-{
- if (Shape* shape = m_shape.get())
- return shape;
-
- WritingMode writingMode = m_renderer->style()->writingMode();
- Length margin = m_renderer->style()->shapeMargin();
- Length padding = m_renderer->style()->shapePadding();
- float shapeImageThreshold = m_renderer->style()->shapeImageThreshold();
- const ShapeValue* shapeValue = this->shapeValue();
- ASSERT(shapeValue);
-
- switch (shapeValue->type()) {
- case ShapeValue::Shape:
- ASSERT(shapeValue->shape());
- m_shape = Shape::createShape(shapeValue->shape(), m_shapeLogicalSize, writingMode, margin, padding);
- break;
- case ShapeValue::Image:
- ASSERT(shapeValue->image());
- m_shape = Shape::createShape(shapeValue->image(), shapeImageThreshold, m_shapeLogicalSize, writingMode, margin, padding);
- break;
- case ShapeValue::Box:
- m_shape = Shape::createLayoutBoxShape(m_shapeLogicalSize, writingMode, margin, padding);
- break;
- case ShapeValue::Outside:
- // Outside should have already resolved to a different shape value.
- ASSERT_NOT_REACHED();
- }
-
- ASSERT(m_shape);
- return m_shape.get();
-}
-
-template<class RenderType>
-SegmentList ShapeInfo<RenderType>::computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const
-{
- ASSERT(lineHeight >= 0);
- SegmentList segments;
-
- getIntervals((lineTop - logicalTopOffset()), std::min(lineHeight, shapeLogicalBottom() - lineTop), segments);
-
- for (size_t i = 0; i < segments.size(); i++) {
- segments[i].logicalLeft += logicalLeftOffset();
- segments[i].logicalRight += logicalLeftOffset();
- }
-
- return segments;
-}
-
-template class ShapeInfo<RenderBlock>;
-template class ShapeInfo<RenderBox>;
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInfo.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInfo.h
deleted file mode 100644
index 1314f3409c1..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInfo.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
-* Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* 1. Redistributions of source code must retain the above
-* copyright notice, this list of conditions and the following
-* disclaimer.
-* 2. Redistributions in binary form must reproduce the above
-* copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials
-* provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
-* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
-* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-* SUCH DAMAGE.
-*/
-
-#ifndef ShapeInfo_h
-#define ShapeInfo_h
-
-#include "core/rendering/shapes/Shape.h"
-#include "core/rendering/style/RenderStyle.h"
-#include "core/rendering/style/ShapeValue.h"
-#include "platform/LayoutUnit.h"
-#include "platform/geometry/FloatRect.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-template<class KeyType, class InfoType>
-class MappedInfo {
-public:
- static InfoType* ensureInfo(const KeyType* key)
- {
- InfoMap& infoMap = MappedInfo<KeyType, InfoType>::infoMap();
- if (InfoType* info = infoMap.get(key))
- return info;
- typename InfoMap::AddResult result = infoMap.add(key, InfoType::createInfo(key));
- return result.iterator->value.get();
- }
- static void removeInfo(const KeyType* key) { infoMap().remove(key); }
- static InfoType* info(const KeyType* key) { return infoMap().get(key); }
-private:
- typedef HashMap<const KeyType*, OwnPtr<InfoType> > InfoMap;
- static InfoMap& infoMap()
- {
- DEFINE_STATIC_LOCAL(InfoMap, staticInfoMap, ());
- return staticInfoMap;
- }
-};
-
-template<class RenderType>
-class ShapeInfo {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- virtual ~ShapeInfo() { }
-
- void setShapeSize(LayoutUnit logicalWidth, LayoutUnit logicalHeight)
- {
- if (shapeValue()->type() == ShapeValue::Box) {
- switch (shapeValue()->layoutBox()) {
- case MarginBox:
- logicalHeight += m_renderer->marginLogicalHeight();
- logicalWidth += m_renderer->marginLogicalWidth();
- break;
- case BorderBox:
- break;
- case PaddingBox:
- logicalHeight -= m_renderer->borderLogicalHeight();
- logicalWidth -= m_renderer->borderLogicalWidth();
- break;
- case ContentBox:
- logicalHeight -= m_renderer->borderAndPaddingLogicalHeight();
- logicalWidth -= m_renderer->borderAndPaddingLogicalWidth();
- break;
- }
- } else if (m_renderer->style()->boxSizing() == CONTENT_BOX) {
- logicalHeight -= m_renderer->borderAndPaddingLogicalHeight();
- logicalWidth -= m_renderer->borderAndPaddingLogicalWidth();
- }
-
- LayoutSize newLogicalSize(logicalWidth, logicalHeight);
- if (m_shapeLogicalSize == newLogicalSize)
- return;
- dirtyShapeSize();
- m_shapeLogicalSize = newLogicalSize;
- }
-
- SegmentList computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const;
-
- LayoutUnit shapeLogicalTop() const { return computedShapeLogicalBoundingBox().y() + logicalTopOffset(); }
- LayoutUnit shapeLogicalBottom() const { return computedShapeLogicalBoundingBox().maxY() + logicalTopOffset(); }
- LayoutUnit shapeLogicalLeft() const { return computedShapeLogicalBoundingBox().x() + logicalLeftOffset(); }
- LayoutUnit shapeLogicalRight() const { return computedShapeLogicalBoundingBox().maxX() + logicalLeftOffset(); }
- LayoutUnit shapeLogicalWidth() const { return computedShapeLogicalBoundingBox().width(); }
- LayoutUnit shapeLogicalHeight() const { return computedShapeLogicalBoundingBox().height(); }
-
- LayoutUnit logicalLineTop() const { return m_shapeLineTop + logicalTopOffset(); }
- LayoutUnit logicalLineBottom() const { return m_shapeLineTop + m_lineHeight + logicalTopOffset(); }
-
- LayoutUnit shapeContainingBlockHeight() const { return (m_renderer->style()->boxSizing() == CONTENT_BOX) ? (m_shapeLogicalSize.height() + m_renderer->borderAndPaddingLogicalHeight()) : m_shapeLogicalSize.height(); }
-
- virtual bool lineOverlapsShapeBounds() const = 0;
-
- void dirtyShapeSize() { m_shape.clear(); }
- bool shapeSizeDirty() { return !m_shape.get(); }
- const RenderType* owner() const { return m_renderer; }
- LayoutSize shapeSize() const { return m_shapeLogicalSize; }
-
-protected:
- ShapeInfo(const RenderType* renderer): m_renderer(renderer) { }
-
- const Shape* computedShape() const;
-
- virtual LayoutRect computedShapeLogicalBoundingBox() const = 0;
- virtual ShapeValue* shapeValue() const = 0;
- virtual void getIntervals(LayoutUnit, LayoutUnit, SegmentList&) const = 0;
-
- LayoutUnit logicalTopOffset() const
- {
- if (shapeValue()->type() == ShapeValue::Box) {
- switch (shapeValue()->layoutBox()) {
- case MarginBox:
- return -m_renderer->marginBefore();
- case BorderBox:
- return LayoutUnit();
- case PaddingBox:
- return m_renderer->borderBefore();
- case ContentBox:
- return m_renderer->borderAndPaddingBefore();
- }
- }
- return m_renderer->style()->boxSizing() == CONTENT_BOX ? m_renderer->borderAndPaddingBefore() : LayoutUnit();
- }
-
- LayoutUnit logicalLeftOffset() const
- {
- if (shapeValue()->type() == ShapeValue::Box) {
- switch (shapeValue()->layoutBox()) {
- case MarginBox:
- return -m_renderer->marginStart();
- case BorderBox:
- return LayoutUnit();
- case PaddingBox:
- return m_renderer->borderStart();
- case ContentBox:
- return m_renderer->borderAndPaddingStart();
- }
- }
- return (m_renderer->style()->boxSizing() == CONTENT_BOX && !m_renderer->isRenderRegion()) ? m_renderer->borderAndPaddingStart() : LayoutUnit();
- }
-
- LayoutUnit m_shapeLineTop;
- LayoutUnit m_lineHeight;
-
- const RenderType* m_renderer;
-
-private:
- mutable OwnPtr<Shape> m_shape;
- LayoutSize m_shapeLogicalSize;
-};
-
-bool checkShapeImageOrigin(Document&, ImageResource&);
-
-}
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInsideInfo.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInsideInfo.cpp
deleted file mode 100644
index 301200b19e7..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInsideInfo.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/shapes/ShapeInsideInfo.h"
-
-#include "core/rendering/InlineIterator.h"
-#include "core/rendering/RenderBlock.h"
-
-namespace WebCore {
-
-LineSegmentRange::LineSegmentRange(const InlineIterator& start, const InlineIterator& end)
- : start(start.root(), start.object(), start.offset())
- , end(end.root(), end.object(), end.offset())
- {
- }
-
-bool ShapeInsideInfo::isEnabledFor(const RenderBlock* renderer)
-{
- ShapeValue* shapeValue = renderer->style()->resolvedShapeInside();
- if (!shapeValue)
- return false;
-
- switch (shapeValue->type()) {
- case ShapeValue::Shape:
- return shapeValue->shape() && shapeValue->shape()->type() != BasicShape::BasicShapeInsetRectangleType;
- case ShapeValue::Image:
- return shapeValue->isImageValid() && checkShapeImageOrigin(renderer->document(), *(shapeValue->image()->cachedImage()));
- case ShapeValue::Box:
- case ShapeValue::Outside:
- return false;
- }
-
- return false;
-}
-
-bool ShapeInsideInfo::updateSegmentsForLine(LayoutSize lineOffset, LayoutUnit lineHeight)
-{
- bool result = updateSegmentsForLine(lineOffset.height(), lineHeight);
- for (size_t i = 0; i < m_segments.size(); i++) {
- m_segments[i].logicalLeft -= lineOffset.width();
- m_segments[i].logicalRight -= lineOffset.width();
- }
- return result;
-}
-
-bool ShapeInsideInfo::updateSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight)
-{
- ASSERT(lineHeight >= 0);
- m_shapeLineTop = lineTop - logicalTopOffset();
- m_lineHeight = lineHeight;
- m_segments.clear();
- m_segmentRanges.clear();
-
- if (lineOverlapsShapeBounds())
- m_segments = computeSegmentsForLine(lineTop, lineHeight);
-
- return m_segments.size();
-}
-
-bool ShapeInsideInfo::adjustLogicalLineTop(float minSegmentWidth)
-{
- const Shape* shape = computedShape();
- if (!shape || m_lineHeight <= 0 || logicalLineTop() > shapeLogicalBottom())
- return false;
-
- LayoutUnit newLineTop;
- if (shape->firstIncludedIntervalLogicalTop(m_shapeLineTop, LayoutSize(minSegmentWidth, m_lineHeight), newLineTop)) {
- if (newLineTop > m_shapeLineTop) {
- m_shapeLineTop = newLineTop;
- return true;
- }
- }
-
- return false;
-}
-
-ShapeValue* ShapeInsideInfo::shapeValue() const
-{
- return m_renderer->style()->resolvedShapeInside();
-}
-
-LayoutUnit ShapeInsideInfo::computeFirstFitPositionForFloat(const LayoutSize floatSize) const
-{
- if (!computedShape() || !floatSize.width() || shapeLogicalBottom() < logicalLineTop())
- return 0;
-
- LayoutUnit firstFitPosition = 0;
- if (computedShape()->firstIncludedIntervalLogicalTop(m_shapeLineTop, floatSize, firstFitPosition) && (m_shapeLineTop <= firstFitPosition))
- return firstFitPosition;
-
- return 0;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInsideInfo.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInsideInfo.h
deleted file mode 100644
index 0f0f3855266..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInsideInfo.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef ShapeInsideInfo_h
-#define ShapeInsideInfo_h
-
-#include "core/rendering/shapes/ShapeInfo.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class InlineIterator;
-class RenderBlock;
-class RenderObject;
-
-struct LineSegmentIterator {
- RenderObject* root;
- RenderObject* object;
- unsigned offset;
- LineSegmentIterator(RenderObject* root, RenderObject* object, unsigned offset)
- : root(root)
- , object(object)
- , offset(offset)
- {
- }
-};
-
-struct LineSegmentRange {
- LineSegmentIterator start;
- LineSegmentIterator end;
- LineSegmentRange(const InlineIterator& start, const InlineIterator& end);
-};
-
-typedef Vector<LineSegmentRange> SegmentRangeList;
-
-class ShapeInsideInfo FINAL : public ShapeInfo<RenderBlock> {
-public:
- static PassOwnPtr<ShapeInsideInfo> createInfo(const RenderBlock* renderer) { return adoptPtr(new ShapeInsideInfo(renderer)); }
-
- static bool isEnabledFor(const RenderBlock* renderer);
-
- bool updateSegmentsForLine(LayoutSize lineOffset, LayoutUnit lineHeight);
- bool updateSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight);
-
- bool hasSegments() const
- {
- return lineOverlapsShapeBounds() && m_segments.size();
- }
- const SegmentList& segments() const
- {
- ASSERT(hasSegments());
- return m_segments;
- }
- SegmentRangeList& segmentRanges() { return m_segmentRanges; }
- const SegmentRangeList& segmentRanges() const { return m_segmentRanges; }
- const LineSegment* currentSegment() const
- {
- if (!hasSegments())
- return 0;
- ASSERT(m_segmentRanges.size() < m_segments.size());
- return &m_segments[m_segmentRanges.size()];
- }
- void clearSegments() { m_segments.clear(); }
- bool adjustLogicalLineTop(float minSegmentWidth);
- LayoutUnit computeFirstFitPositionForFloat(const LayoutSize) const;
-
- void setNeedsLayout(bool value) { m_needsLayout = value; }
- bool needsLayout() { return m_needsLayout; }
-
- virtual bool lineOverlapsShapeBounds() const OVERRIDE
- {
- return computedShape()->lineOverlapsShapePaddingBounds(m_shapeLineTop, m_lineHeight);
- }
-
-protected:
- virtual LayoutRect computedShapeLogicalBoundingBox() const OVERRIDE { return computedShape()->shapePaddingLogicalBoundingBox(); }
- virtual ShapeValue* shapeValue() const OVERRIDE;
- virtual void getIntervals(LayoutUnit lineTop, LayoutUnit lineHeight, SegmentList& segments) const OVERRIDE
- {
- return computedShape()->getIncludedIntervals(lineTop, lineHeight, segments);
- }
-
-private:
- ShapeInsideInfo(const RenderBlock* renderer)
- : ShapeInfo<RenderBlock> (renderer)
- , m_needsLayout(false)
- { }
-
- SegmentRangeList m_segmentRanges;
- bool m_needsLayout;
- SegmentList m_segments;
-};
-
-}
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInterval.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInterval.h
index efeb7d862c0..47c20178f0f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInterval.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeInterval.h
@@ -38,29 +38,27 @@ template <typename T>
class ShapeInterval {
WTF_MAKE_FAST_ALLOCATED;
public:
- ShapeInterval(T x1 = 0, T x2 = 0)
- : m_x1(x1)
- , m_x2(x2)
+ ShapeInterval()
+ : m_x1(-1)
+ , m_x2(-2)
{
- ASSERT(x2 >= x1);
+ // The initial values of m_x1,x2 don't matter (unless you're looking
+ // at them in the debugger) so long as isUndefined() is true.
+ ASSERT(isUndefined());
}
- T x1() const { return m_x1; }
- T x2() const { return m_x2; }
- T width() const { return m_x2 - m_x1; }
- bool isEmpty() const { return m_x1 == m_x2; }
-
- void setX1(T x1)
+ ShapeInterval(T x1, T x2)
+ : m_x1(x1)
+ , m_x2(x2)
{
- ASSERT(m_x2 >= x1);
- m_x1 = x1;
+ ASSERT(x2 >= x1);
}
- void setX2(T x2)
- {
- ASSERT(x2 >= m_x1);
- m_x2 = x2;
- }
+ bool isUndefined() const { return m_x2 < m_x1; }
+ T x1() const { return isUndefined() ? 0 : m_x1; }
+ T x2() const { return isUndefined() ? 0 : m_x2; }
+ T width() const { return isUndefined() ? 0 : m_x2 - m_x1; }
+ bool isEmpty() const { return isUndefined() ? true : m_x1 == m_x2; }
void set(T x1, T x2)
{
@@ -71,155 +69,34 @@ public:
bool overlaps(const ShapeInterval<T>& interval) const
{
+ if (isUndefined() || interval.isUndefined())
+ return false;
return x2() >= interval.x1() && x1() <= interval.x2();
}
bool contains(const ShapeInterval<T>& interval) const
{
+ if (isUndefined() || interval.isUndefined())
+ return false;
return x1() <= interval.x1() && x2() >= interval.x2();
}
- ShapeInterval<T> intersect(const ShapeInterval<T>& interval) const
- {
- ASSERT(overlaps(interval));
- return ShapeInterval<T>(std::max<T>(x1(), interval.x1()), std::min<T>(x2(), interval.x2()));
- }
-
- typedef Vector<ShapeInterval<T> > ShapeIntervals;
- typedef typename ShapeIntervals::const_iterator const_iterator;
- typedef typename ShapeIntervals::iterator iterator;
-
- static void uniteShapeIntervals(const ShapeIntervals& a, const ShapeIntervals& b, ShapeIntervals& result)
- {
- ASSERT(shapeIntervalsAreSortedAndDisjoint(a) && shapeIntervalsAreSortedAndDisjoint(b));
-
- if (a.isEmpty() || a == b) {
- result.appendRange(b.begin(), b.end());
- return;
- }
-
- if (b.isEmpty()) {
- result.appendRange(a.begin(), a.end());
- return;
- }
-
- const_iterator aNext = a.begin();
- const_iterator bNext = b.begin();
-
- while (aNext != a.end() || bNext != b.end()) {
- const_iterator next = (bNext == b.end() || (aNext != a.end() && aNext->x1() < bNext->x1())) ? aNext++ : bNext++;
- if (result.isEmpty() || !result.last().overlaps(*next))
- result.append(*next);
- else
- result.last().setX2(std::max<T>(result.last().x2(), next->x2()));
- }
- }
-
- static void intersectShapeIntervals(const ShapeIntervals& a, const ShapeIntervals& b, ShapeIntervals& result)
- {
- ASSERT(shapeIntervalsAreSortedAndDisjoint(a) && shapeIntervalsAreSortedAndDisjoint(b));
-
- if (a.isEmpty() || b.isEmpty())
- return;
-
- if (a == b) {
- result.appendRange(a.begin(), a.end());
- return;
- }
-
- const_iterator aNext = a.begin();
- const_iterator bNext = b.begin();
- const_iterator working = aNext->x1() < bNext->x1() ? aNext++ : bNext++;
-
- while (aNext != a.end() || bNext != b.end()) {
- const_iterator next = (bNext == b.end() || (aNext != a.end() && aNext->x1() < bNext->x1())) ? aNext++ : bNext++;
- if (working->overlaps(*next)) {
- result.append(working->intersect(*next));
- if (next->x2() > working->x2())
- working = next;
- } else {
- working = next;
- }
- }
- }
+ bool operator==(const ShapeInterval<T>& other) const { return x1() == other.x1() && x2() == other.x2(); }
+ bool operator!=(const ShapeInterval<T>& other) const { return !operator==(other); }
- static void subtractShapeIntervals(const ShapeIntervals& a, const ShapeIntervals& b, ShapeIntervals& result)
+ void unite(const ShapeInterval<T>& interval)
{
- ASSERT(shapeIntervalsAreSortedAndDisjoint(a) && shapeIntervalsAreSortedAndDisjoint(b));
-
- if (a.isEmpty() || a == b)
- return;
-
- if (b.isEmpty()) {
- result.appendRange(a.begin(), a.end());
+ if (interval.isUndefined())
return;
- }
-
- const_iterator aNext = a.begin();
- const_iterator bNext = b.begin();
- ShapeInterval<T> aValue = *aNext;
- ShapeInterval<T> bValue = *bNext;
-
- do {
- bool aIncrement = false;
- bool bIncrement = false;
-
- if (bValue.contains(aValue)) {
- aIncrement = true;
- } else if (aValue.contains(bValue)) {
- if (bValue.x1() > aValue.x1())
- result.append(ShapeInterval<T>(aValue.x1(), bValue.x1()));
- if (aValue.x2() > bValue.x2())
- aValue.setX1(bValue.x2());
- else
- aIncrement = true;
- bIncrement = true;
- } else if (aValue.overlaps(bValue)) {
- if (aValue.x1() < bValue.x1()) {
- result.append(ShapeInterval<T>(aValue.x1(), bValue.x1()));
- aIncrement = true;
- } else {
- aValue.setX1(bValue.x2());
- bIncrement = true;
- }
- } else {
- if (aValue.x1() < bValue.x1()) {
- result.append(aValue);
- aIncrement = true;
- } else {
- bIncrement = true;
- }
- }
-
- if (aIncrement && ++aNext != a.end())
- aValue = *aNext;
- if (bIncrement && ++bNext != b.end())
- bValue = *bNext;
-
- } while (aNext != a.end() && bNext != b.end());
-
- if (aNext != a.end()) {
- result.append(aValue);
- result.appendRange(++aNext, a.end());
- }
+ if (isUndefined())
+ set(interval.x1(), interval.x2());
+ else
+ set(std::min<T>(x1(), interval.x1()), std::max<T>(x2(), interval.x2()));
}
- bool operator==(const ShapeInterval<T>& other) const { return x1() == other.x1() && x2() == other.x2(); }
- bool operator!=(const ShapeInterval<T>& other) const { return !operator==(other); }
-
private:
T m_x1;
T m_x2;
-
- static bool shapeIntervalsAreSortedAndDisjoint(const ShapeIntervals& intervals)
- {
- for (unsigned i = 1; i < intervals.size(); i++) {
- if (intervals[i - 1].x2() > intervals[i].x1())
- return false;
- }
-
- return true;
- }
};
typedef ShapeInterval<int> IntShapeInterval;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.cpp b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.cpp
index 98bea9a0a16..216d3091acf 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.cpp
@@ -33,48 +33,269 @@
#include "core/rendering/FloatingObjects.h"
#include "core/rendering/RenderBlockFlow.h"
#include "core/rendering/RenderBox.h"
+#include "core/rendering/RenderImage.h"
+#include "platform/LengthFunctions.h"
namespace WebCore {
-bool ShapeOutsideInfo::isEnabledFor(const RenderBox* box)
+
+CSSBoxType referenceBox(const ShapeValue& shapeValue)
+{
+ if (shapeValue.cssBox() == BoxMissing)
+ return MarginBox;
+ return shapeValue.cssBox();
+}
+
+void ShapeOutsideInfo::setReferenceBoxLogicalSize(LayoutSize newReferenceBoxLogicalSize)
+{
+ bool isHorizontalWritingMode = m_renderer.containingBlock()->style()->isHorizontalWritingMode();
+ switch (referenceBox(*m_renderer.style()->shapeOutside())) {
+ case MarginBox:
+ if (isHorizontalWritingMode)
+ newReferenceBoxLogicalSize.expand(m_renderer.marginWidth(), m_renderer.marginHeight());
+ else
+ newReferenceBoxLogicalSize.expand(m_renderer.marginHeight(), m_renderer.marginWidth());
+ break;
+ case BorderBox:
+ break;
+ case PaddingBox:
+ if (isHorizontalWritingMode)
+ newReferenceBoxLogicalSize.shrink(m_renderer.borderWidth(), m_renderer.borderHeight());
+ else
+ newReferenceBoxLogicalSize.shrink(m_renderer.borderHeight(), m_renderer.borderWidth());
+ break;
+ case ContentBox:
+ if (isHorizontalWritingMode)
+ newReferenceBoxLogicalSize.shrink(m_renderer.borderAndPaddingWidth(), m_renderer.borderAndPaddingHeight());
+ else
+ newReferenceBoxLogicalSize.shrink(m_renderer.borderAndPaddingHeight(), m_renderer.borderAndPaddingWidth());
+ break;
+ case BoxMissing:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+
+ if (m_referenceBoxLogicalSize == newReferenceBoxLogicalSize)
+ return;
+ markShapeAsDirty();
+ m_referenceBoxLogicalSize = newReferenceBoxLogicalSize;
+}
+
+static bool checkShapeImageOrigin(Document& document, const StyleImage& styleImage)
{
- ShapeValue* shapeValue = box->style()->shapeOutside();
- if (!box->isFloating() || !shapeValue)
+ if (styleImage.isGeneratedImage())
+ return true;
+
+ ASSERT(styleImage.cachedImage());
+ ImageResource& imageResource = *(styleImage.cachedImage());
+ if (imageResource.isAccessAllowed(document.securityOrigin()))
+ return true;
+
+ const KURL& url = imageResource.url();
+ String urlString = url.isNull() ? "''" : url.elidedString();
+ document.addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Unsafe attempt to load URL " + urlString + ".");
+
+ return false;
+}
+
+static LayoutRect getShapeImageMarginRect(const RenderBox& renderBox, const LayoutSize& referenceBoxLogicalSize)
+{
+ LayoutPoint marginBoxOrigin(-renderBox.marginLogicalLeft() - renderBox.borderAndPaddingLogicalLeft(), -renderBox.marginBefore() - renderBox.borderBefore() - renderBox.paddingBefore());
+ LayoutSize marginBoxSizeDelta(renderBox.marginLogicalWidth() + renderBox.borderAndPaddingLogicalWidth(), renderBox.marginLogicalHeight() + renderBox.borderAndPaddingLogicalHeight());
+ return LayoutRect(marginBoxOrigin, referenceBoxLogicalSize + marginBoxSizeDelta);
+}
+
+PassOwnPtr<Shape> ShapeOutsideInfo::createShapeForImage(StyleImage* styleImage, float shapeImageThreshold, WritingMode writingMode, float margin) const
+{
+ const IntSize& imageSize = m_renderer.calculateImageIntrinsicDimensions(styleImage, roundedIntSize(m_referenceBoxLogicalSize), RenderImage::ScaleByEffectiveZoom);
+ styleImage->setContainerSizeForRenderer(&m_renderer, imageSize, m_renderer.style()->effectiveZoom());
+
+ const LayoutRect& marginRect = getShapeImageMarginRect(m_renderer, m_referenceBoxLogicalSize);
+ const LayoutRect& imageRect = (m_renderer.isRenderImage())
+ ? toRenderImage(&m_renderer)->replacedContentRect()
+ : LayoutRect(LayoutPoint(), imageSize);
+
+ ASSERT(!styleImage->isPendingImage());
+ RefPtr<Image> image = styleImage->image(const_cast<RenderBox*>(&m_renderer), imageSize);
+
+ return Shape::createRasterShape(image.get(), shapeImageThreshold, imageRect, marginRect, writingMode, margin);
+}
+
+const Shape& ShapeOutsideInfo::computedShape() const
+{
+ if (Shape* shape = m_shape.get())
+ return *shape;
+
+ const RenderStyle& style = *m_renderer.style();
+ ASSERT(m_renderer.containingBlock());
+ const RenderStyle& containingBlockStyle = *m_renderer.containingBlock()->style();
+
+ WritingMode writingMode = containingBlockStyle.writingMode();
+ LayoutUnit maximumValue = m_renderer.containingBlock() ? m_renderer.containingBlock()->contentWidth() : LayoutUnit();
+ float margin = floatValueForLength(m_renderer.style()->shapeMargin(), maximumValue.toFloat());
+
+ float shapeImageThreshold = style.shapeImageThreshold();
+ ASSERT(style.shapeOutside());
+ const ShapeValue& shapeValue = *style.shapeOutside();
+
+ switch (shapeValue.type()) {
+ case ShapeValue::Shape:
+ ASSERT(shapeValue.shape());
+ m_shape = Shape::createShape(shapeValue.shape(), m_referenceBoxLogicalSize, writingMode, margin);
+ break;
+ case ShapeValue::Image:
+ ASSERT(shapeValue.isImageValid());
+ m_shape = createShapeForImage(shapeValue.image(), shapeImageThreshold, writingMode, margin);
+ break;
+ case ShapeValue::Box: {
+ const RoundedRect& shapeRect = style.getRoundedBorderFor(LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize), m_renderer.view());
+ m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin);
+ break;
+ }
+ }
+
+ ASSERT(m_shape);
+ return *m_shape;
+}
+
+SegmentList ShapeOutsideInfo::computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const
+{
+ ASSERT(lineHeight >= 0);
+ SegmentList segments;
+
+ computedShape().getExcludedIntervals((lineTop - logicalTopOffset()), std::min(lineHeight, shapeLogicalBottom() - lineTop), segments);
+
+ for (size_t i = 0; i < segments.size(); i++) {
+ segments[i].logicalLeft += logicalLeftOffset();
+ segments[i].logicalRight += logicalLeftOffset();
+ }
+
+ return segments;
+}
+
+inline LayoutUnit borderBeforeInWritingMode(const RenderBox& renderer, WritingMode writingMode)
+{
+ switch (writingMode) {
+ case TopToBottomWritingMode: return renderer.borderTop();
+ case BottomToTopWritingMode: return renderer.borderBottom();
+ case LeftToRightWritingMode: return renderer.borderLeft();
+ case RightToLeftWritingMode: return renderer.borderRight();
+ }
+
+ ASSERT_NOT_REACHED();
+ return renderer.borderBefore();
+}
+
+inline LayoutUnit borderAndPaddingBeforeInWritingMode(const RenderBox& renderer, WritingMode writingMode)
+{
+ switch (writingMode) {
+ case TopToBottomWritingMode: return renderer.borderTop() + renderer.paddingTop();
+ case BottomToTopWritingMode: return renderer.borderBottom() + renderer.paddingBottom();
+ case LeftToRightWritingMode: return renderer.borderLeft() + renderer.paddingLeft();
+ case RightToLeftWritingMode: return renderer.borderRight() + renderer.paddingRight();
+ }
+
+ ASSERT_NOT_REACHED();
+ return renderer.borderAndPaddingBefore();
+}
+
+LayoutUnit ShapeOutsideInfo::logicalTopOffset() const
+{
+ switch (referenceBox(*m_renderer.style()->shapeOutside())) {
+ case MarginBox: return -m_renderer.marginBefore(m_renderer.containingBlock()->style());
+ case BorderBox: return LayoutUnit();
+ case PaddingBox: return borderBeforeInWritingMode(m_renderer, m_renderer.containingBlock()->style()->writingMode());
+ case ContentBox: return borderAndPaddingBeforeInWritingMode(m_renderer, m_renderer.containingBlock()->style()->writingMode());
+ case BoxMissing: break;
+ }
+
+ ASSERT_NOT_REACHED();
+ return LayoutUnit();
+}
+
+inline LayoutUnit borderStartWithStyleForWritingMode(const RenderBox& renderer, const RenderStyle* style)
+{
+ if (style->isHorizontalWritingMode()) {
+ if (style->isLeftToRightDirection())
+ return renderer.borderLeft();
+
+ return renderer.borderRight();
+ }
+ if (style->isLeftToRightDirection())
+ return renderer.borderTop();
+
+ return renderer.borderBottom();
+}
+
+inline LayoutUnit borderAndPaddingStartWithStyleForWritingMode(const RenderBox& renderer, const RenderStyle* style)
+{
+ if (style->isHorizontalWritingMode()) {
+ if (style->isLeftToRightDirection())
+ return renderer.borderLeft() + renderer.paddingLeft();
+
+ return renderer.borderRight() + renderer.paddingRight();
+ }
+ if (style->isLeftToRightDirection())
+ return renderer.borderTop() + renderer.paddingTop();
+
+ return renderer.borderBottom() + renderer.paddingBottom();
+}
+
+LayoutUnit ShapeOutsideInfo::logicalLeftOffset() const
+{
+ switch (referenceBox(*m_renderer.style()->shapeOutside())) {
+ case MarginBox: return -m_renderer.marginStart(m_renderer.containingBlock()->style());
+ case BorderBox: return LayoutUnit();
+ case PaddingBox: return borderStartWithStyleForWritingMode(m_renderer, m_renderer.containingBlock()->style());
+ case ContentBox: return borderAndPaddingStartWithStyleForWritingMode(m_renderer, m_renderer.containingBlock()->style());
+ case BoxMissing: break;
+ }
+
+ ASSERT_NOT_REACHED();
+ return LayoutUnit();
+}
+
+
+bool ShapeOutsideInfo::isEnabledFor(const RenderBox& box)
+{
+ ShapeValue* shapeValue = box.style()->shapeOutside();
+ if (!box.isFloating() || !shapeValue)
return false;
switch (shapeValue->type()) {
case ShapeValue::Shape:
return shapeValue->shape();
case ShapeValue::Image:
- return shapeValue->isImageValid() && checkShapeImageOrigin(box->document(), *(shapeValue->image()->cachedImage()));
+ return shapeValue->isImageValid() && checkShapeImageOrigin(box.document(), *(shapeValue->image()));
case ShapeValue::Box:
return true;
- case ShapeValue::Outside:
- return false;
}
return false;
}
-void ShapeOutsideInfo::updateDeltasForContainingBlockLine(const RenderBlockFlow* containingBlock, const FloatingObject* floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight)
+void ShapeOutsideInfo::updateDeltasForContainingBlockLine(const RenderBlockFlow& containingBlock, const FloatingObject& floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight)
{
- LayoutUnit shapeTop = containingBlock->logicalTopForFloat(floatingObject) + std::max(LayoutUnit(), containingBlock->marginBeforeForChild(m_renderer));
- LayoutUnit floatRelativeLineTop = lineTop - shapeTop;
+ LayoutUnit borderBoxTop = containingBlock.logicalTopForFloat(&floatingObject) + containingBlock.marginBeforeForChild(&m_renderer);
+ LayoutUnit borderBoxLineTop = lineTop - borderBoxTop;
- if (shapeSizeDirty() || m_lineTop != floatRelativeLineTop || m_lineHeight != lineHeight) {
- m_lineTop = floatRelativeLineTop;
- m_shapeLineTop = floatRelativeLineTop - logicalTopOffset();
+ if (isShapeDirty() || m_borderBoxLineTop != borderBoxLineTop || m_lineHeight != lineHeight) {
+ m_borderBoxLineTop = borderBoxLineTop;
+ m_referenceBoxLineTop = borderBoxLineTop - logicalTopOffset();
m_lineHeight = lineHeight;
- LayoutUnit floatMarginBoxWidth = containingBlock->logicalWidthForFloat(floatingObject);
+ LayoutUnit floatMarginBoxWidth = containingBlock.logicalWidthForFloat(&floatingObject);
if (lineOverlapsShapeBounds()) {
- SegmentList segments = computeSegmentsForLine(floatRelativeLineTop, lineHeight);
+ SegmentList segments = computeSegmentsForLine(borderBoxLineTop, lineHeight);
if (segments.size()) {
- LayoutUnit rawLeftMarginBoxDelta = segments.first().logicalLeft + containingBlock->marginStartForChild(m_renderer);
- m_leftMarginBoxDelta = clampTo<LayoutUnit>(rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth);
+ LayoutUnit logicalLeftMargin = containingBlock.style()->isLeftToRightDirection() ? containingBlock.marginStartForChild(&m_renderer) : containingBlock.marginEndForChild(&m_renderer);
+ LayoutUnit rawLeftMarginBoxDelta = segments.first().logicalLeft + logicalLeftMargin;
+ m_leftMarginBoxDelta = clampToLayoutUnit(rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth);
- LayoutUnit rawRightMarginBoxDelta = segments.last().logicalRight - containingBlock->logicalWidthForChild(m_renderer) - containingBlock->marginEndForChild(m_renderer);
- m_rightMarginBoxDelta = clampTo<LayoutUnit>(rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit());
+ LayoutUnit logicalRightMargin = containingBlock.style()->isLeftToRightDirection() ? containingBlock.marginEndForChild(&m_renderer) : containingBlock.marginStartForChild(&m_renderer);
+ LayoutUnit rawRightMarginBoxDelta = segments.last().logicalRight - containingBlock.logicalWidthForChild(&m_renderer) - logicalRightMargin;
+ m_rightMarginBoxDelta = clampToLayoutUnit(rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit());
+ m_lineOverlapsShape = true;
return;
}
}
@@ -82,19 +303,45 @@ void ShapeOutsideInfo::updateDeltasForContainingBlockLine(const RenderBlockFlow*
// Lines that do not overlap the shape should act as if the float
// wasn't there for layout purposes. So we set the deltas to remove the
// entire width of the float.
- // FIXME: The latest CSS Shapes spec says that in this case, the
- // content should interact with previously stacked floats on the line
- // as if this outermost float did not exist. Perhaps obviously, this
- // solution cannot do that, and will be revisted when that part of the
- // spec is implemented.
m_leftMarginBoxDelta = floatMarginBoxWidth;
m_rightMarginBoxDelta = -floatMarginBoxWidth;
+ m_lineOverlapsShape = false;
}
}
-ShapeValue* ShapeOutsideInfo::shapeValue() const
+LayoutRect ShapeOutsideInfo::computedShapePhysicalBoundingBox() const
+{
+ LayoutRect physicalBoundingBox = computedShape().shapeMarginLogicalBoundingBox();
+ physicalBoundingBox.setX(physicalBoundingBox.x() + logicalLeftOffset());
+
+ if (m_renderer.style()->isFlippedBlocksWritingMode())
+ physicalBoundingBox.setY(m_renderer.logicalHeight() - physicalBoundingBox.maxY());
+ else
+ physicalBoundingBox.setY(physicalBoundingBox.y() + logicalTopOffset());
+
+ if (!m_renderer.style()->isHorizontalWritingMode())
+ physicalBoundingBox = physicalBoundingBox.transposedRect();
+ else
+ physicalBoundingBox.setY(physicalBoundingBox.y() + logicalTopOffset());
+
+ return physicalBoundingBox;
+}
+
+FloatPoint ShapeOutsideInfo::shapeToRendererPoint(FloatPoint point) const
+{
+ FloatPoint result = FloatPoint(point.x() + logicalLeftOffset(), point.y() + logicalTopOffset());
+ if (m_renderer.style()->isFlippedBlocksWritingMode())
+ result.setY(m_renderer.logicalHeight() - result.y());
+ if (!m_renderer.style()->isHorizontalWritingMode())
+ result = result.transposedPoint();
+ return result;
+}
+
+FloatSize ShapeOutsideInfo::shapeToRendererSize(FloatSize size) const
{
- return m_renderer->style()->shapeOutside();
+ if (!m_renderer.style()->isHorizontalWritingMode())
+ return size.transposedSize();
+ return size;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.h b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.h
index 82b31f65f69..36276e91fdb 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/shapes/ShapeOutsideInfo.h
@@ -30,8 +30,13 @@
#ifndef ShapeOutsideInfo_h
#define ShapeOutsideInfo_h
-#include "core/rendering/shapes/ShapeInfo.h"
+#include "core/rendering/shapes/Shape.h"
+#include "core/rendering/style/RenderStyle.h"
+#include "core/rendering/style/ShapeValue.h"
+#include "platform/geometry/FloatRect.h"
#include "platform/geometry/LayoutSize.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/Vector.h"
namespace WebCore {
@@ -39,35 +44,85 @@ class RenderBlockFlow;
class RenderBox;
class FloatingObject;
-class ShapeOutsideInfo FINAL : public ShapeInfo<RenderBox>, public MappedInfo<RenderBox, ShapeOutsideInfo> {
+class ShapeOutsideInfo FINAL {
+ WTF_MAKE_FAST_ALLOCATED;
public:
+ void setReferenceBoxLogicalSize(LayoutSize);
+
+ SegmentList computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const;
+
+ LayoutUnit shapeLogicalTop() const { return computedShape().shapeMarginLogicalBoundingBox().y() + logicalTopOffset(); }
+ LayoutUnit shapeLogicalBottom() const { return computedShape().shapeMarginLogicalBoundingBox().maxY() + logicalTopOffset(); }
+ LayoutUnit shapeLogicalLeft() const { return computedShape().shapeMarginLogicalBoundingBox().x() + logicalLeftOffset(); }
+ LayoutUnit shapeLogicalRight() const { return computedShape().shapeMarginLogicalBoundingBox().maxX() + logicalLeftOffset(); }
+ LayoutUnit shapeLogicalWidth() const { return computedShape().shapeMarginLogicalBoundingBox().width(); }
+ LayoutUnit shapeLogicalHeight() const { return computedShape().shapeMarginLogicalBoundingBox().height(); }
+
+ LayoutUnit logicalLineTop() const { return m_referenceBoxLineTop + logicalTopOffset(); }
+ LayoutUnit logicalLineBottom() const { return m_referenceBoxLineTop + m_lineHeight + logicalTopOffset(); }
+
LayoutUnit leftMarginBoxDelta() const { return m_leftMarginBoxDelta; }
LayoutUnit rightMarginBoxDelta() const { return m_rightMarginBoxDelta; }
+ bool lineOverlapsShape() const { return m_lineOverlapsShape; }
- void updateDeltasForContainingBlockLine(const RenderBlockFlow*, const FloatingObject*, LayoutUnit lineTop, LayoutUnit lineHeight);
+ static PassOwnPtr<ShapeOutsideInfo> createInfo(const RenderBox& renderer) { return adoptPtr(new ShapeOutsideInfo(renderer)); }
+ static bool isEnabledFor(const RenderBox&);
+ void updateDeltasForContainingBlockLine(const RenderBlockFlow&, const FloatingObject&, LayoutUnit lineTop, LayoutUnit lineHeight);
- static PassOwnPtr<ShapeOutsideInfo> createInfo(const RenderBox* renderer) { return adoptPtr(new ShapeOutsideInfo(renderer)); }
- static bool isEnabledFor(const RenderBox*);
+ bool lineOverlapsShapeBounds() const
+ {
+ return computedShape().lineOverlapsShapeMarginBounds(m_referenceBoxLineTop, m_lineHeight);
+ }
- virtual bool lineOverlapsShapeBounds() const OVERRIDE
+ static ShapeOutsideInfo& ensureInfo(const RenderBox& key)
{
- return computedShape()->lineOverlapsShapeMarginBounds(m_shapeLineTop, m_lineHeight);
+ InfoMap& infoMap = ShapeOutsideInfo::infoMap();
+ if (ShapeOutsideInfo* info = infoMap.get(&key))
+ return *info;
+ InfoMap::AddResult result = infoMap.add(&key, ShapeOutsideInfo::createInfo(key));
+ return *result.storedValue->value;
}
+ static void removeInfo(const RenderBox& key) { infoMap().remove(&key); }
+ static ShapeOutsideInfo* info(const RenderBox& key) { return infoMap().get(&key); }
+
+ void markShapeAsDirty() { m_shape.clear(); }
+ bool isShapeDirty() { return !m_shape.get(); }
+ LayoutSize shapeSize() const { return m_referenceBoxLogicalSize; }
+
+ LayoutRect computedShapePhysicalBoundingBox() const;
+ FloatPoint shapeToRendererPoint(FloatPoint) const;
+ FloatSize shapeToRendererSize(FloatSize) const;
+ const Shape& computedShape() const;
protected:
- virtual LayoutRect computedShapeLogicalBoundingBox() const OVERRIDE { return computedShape()->shapeMarginLogicalBoundingBox(); }
- virtual ShapeValue* shapeValue() const OVERRIDE;
- virtual void getIntervals(LayoutUnit lineTop, LayoutUnit lineHeight, SegmentList& segments) const OVERRIDE
+ ShapeOutsideInfo(const RenderBox& renderer)
+ : m_renderer(renderer)
+ , m_lineOverlapsShape(false)
+ { }
+
+private:
+ PassOwnPtr<Shape> createShapeForImage(StyleImage*, float shapeImageThreshold, WritingMode, float margin) const;
+
+ LayoutUnit logicalTopOffset() const;
+ LayoutUnit logicalLeftOffset() const;
+
+ typedef HashMap<const RenderBox*, OwnPtr<ShapeOutsideInfo> > InfoMap;
+ static InfoMap& infoMap()
{
- return computedShape()->getExcludedIntervals(lineTop, lineHeight, segments);
+ DEFINE_STATIC_LOCAL(InfoMap, staticInfoMap, ());
+ return staticInfoMap;
}
-private:
- ShapeOutsideInfo(const RenderBox* renderer) : ShapeInfo<RenderBox>(renderer) { }
+ LayoutUnit m_referenceBoxLineTop;
+ LayoutUnit m_lineHeight;
+ const RenderBox& m_renderer;
+ mutable OwnPtr<Shape> m_shape;
+ LayoutSize m_referenceBoxLogicalSize;
LayoutUnit m_leftMarginBoxDelta;
LayoutUnit m_rightMarginBoxDelta;
- LayoutUnit m_lineTop;
+ LayoutUnit m_borderBoxLineTop;
+ bool m_lineOverlapsShape;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/AppliedTextDecoration.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/AppliedTextDecoration.cpp
new file mode 100644
index 00000000000..ea8be8483a8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/AppliedTextDecoration.cpp
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/rendering/style/AppliedTextDecoration.h"
+
+namespace WebCore {
+
+AppliedTextDecoration::AppliedTextDecoration(TextDecoration line, TextDecorationStyle style, StyleColor color)
+ : m_line(line)
+ , m_style(style)
+ , m_color(color)
+{
+}
+
+AppliedTextDecoration::AppliedTextDecoration(TextDecoration line)
+ : m_line(line)
+ , m_style(TextDecorationStyleSolid)
+ , m_color(StyleColor::currentColor())
+{
+}
+
+AppliedTextDecoration::AppliedTextDecoration()
+ : m_line(TextDecorationUnderline)
+ , m_style(TextDecorationStyleSolid)
+ , m_color(StyleColor::currentColor())
+{
+}
+
+bool AppliedTextDecoration::operator==(const AppliedTextDecoration& o) const
+{
+ return m_color == o.m_color && m_line == o.m_line && m_style == o.m_style;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/AppliedTextDecoration.h b/chromium/third_party/WebKit/Source/core/rendering/style/AppliedTextDecoration.h
new file mode 100644
index 00000000000..fd0df809194
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/AppliedTextDecoration.h
@@ -0,0 +1,34 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AppliedTextDecoration_h
+#define AppliedTextDecoration_h
+
+#include "core/css/StyleColor.h"
+#include "core/rendering/style/RenderStyleConstants.h"
+
+namespace WebCore {
+
+class AppliedTextDecoration {
+public:
+ AppliedTextDecoration(TextDecoration, TextDecorationStyle, StyleColor);
+ explicit AppliedTextDecoration(TextDecoration);
+ AppliedTextDecoration();
+
+ TextDecoration line() const { return static_cast<TextDecoration>(m_line); }
+ TextDecorationStyle style() const { return static_cast<TextDecorationStyle>(m_style); }
+
+ bool isSimpleUnderline() const { return m_line == TextDecorationUnderline && m_style == TextDecorationStyleSolid && m_color.isCurrentColor(); }
+ bool operator==(const AppliedTextDecoration&) const;
+ bool operator!=(const AppliedTextDecoration& o) const { return !(*this == o); }
+
+private:
+ unsigned m_line : TextDecorationBits;
+ unsigned m_style : 3; // TextDecorationStyle
+ StyleColor m_color;
+};
+
+} // namespace WebCore
+
+#endif // AppliedTextDecoration_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.cpp
index 1eed605f291..a41a1d6393c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.cpp
@@ -28,70 +28,90 @@
*/
#include "config.h"
-
#include "core/rendering/style/BasicShapes.h"
+
+#include "core/css/BasicShapeFunctions.h"
+#include "platform/CalculationValue.h"
#include "platform/LengthFunctions.h"
#include "platform/geometry/FloatRect.h"
#include "platform/graphics/Path.h"
namespace WebCore {
+void BasicShapeCenterCoordinate::updateComputedLength()
+{
+ if (m_direction == TopLeft) {
+ m_computedLength = m_length.isUndefined() ? Length(0, Fixed) : m_length;
+ return;
+ }
+ if (m_length.isUndefined()) {
+ m_computedLength = Length(100, Percent);
+ return;
+ }
+
+ m_computedLength = m_length.subtractFromOneHundredPercent();
+}
+
bool BasicShape::canBlend(const BasicShape* other) const
{
// FIXME: Support animations between different shapes in the future.
- if (type() != other->type())
+ if (!other || !isSameType(*other))
return false;
// Just polygons with same number of vertices can be animated.
if (type() == BasicShape::BasicShapePolygonType
- && static_cast<const BasicShapePolygon*>(this)->values().size() != static_cast<const BasicShapePolygon*>(other)->values().size())
+ && (static_cast<const BasicShapePolygon*>(this)->values().size() != static_cast<const BasicShapePolygon*>(other)->values().size()
+ || static_cast<const BasicShapePolygon*>(this)->windRule() != static_cast<const BasicShapePolygon*>(other)->windRule()))
return false;
- return true;
+ // Circles with keywords for radii or center coordinates cannot be animated.
+ if (type() == BasicShape::BasicShapeCircleType) {
+ const BasicShapeCircle* thisCircle = static_cast<const BasicShapeCircle*>(this);
+ const BasicShapeCircle* otherCircle = static_cast<const BasicShapeCircle*>(other);
+ if (!thisCircle->radius().canBlend(otherCircle->radius()))
+ return false;
+ }
+
+ // Ellipses with keywords for radii or center coordinates cannot be animated.
+ if (type() != BasicShape::BasicShapeEllipseType)
+ return true;
+
+ const BasicShapeEllipse* thisEllipse = static_cast<const BasicShapeEllipse*>(this);
+ const BasicShapeEllipse* otherEllipse = static_cast<const BasicShapeEllipse*>(other);
+ return (thisEllipse->radiusX().canBlend(otherEllipse->radiusX())
+ && thisEllipse->radiusY().canBlend(otherEllipse->radiusY()));
}
-void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox)
+bool BasicShapeCircle::operator==(const BasicShape& o) const
{
- ASSERT(path.isEmpty());
- path.addRoundedRect(
- FloatRect(
- floatValueForLength(m_x, boundingBox.width()) + boundingBox.x(),
- floatValueForLength(m_y, boundingBox.height()) + boundingBox.y(),
- floatValueForLength(m_width, boundingBox.width()),
- floatValueForLength(m_height, boundingBox.height())
- ),
- FloatSize(
- floatValueForLength(m_cornerRadiusX, boundingBox.width()),
- floatValueForLength(m_cornerRadiusY, boundingBox.height())
- )
- );
+ if (!isSameType(o))
+ return false;
+ const BasicShapeCircle& other = toBasicShapeCircle(o);
+ return m_centerX == other.m_centerX && m_centerY == other.m_centerY && m_radius == other.m_radius;
}
-PassRefPtr<BasicShape> BasicShapeRectangle::blend(const BasicShape* other, double progress) const
+float BasicShapeCircle::floatValueForRadiusInBox(FloatSize boxSize) const
{
- ASSERT(type() == other->type());
+ if (m_radius.type() == BasicShapeRadius::Value)
+ return floatValueForLength(m_radius.value(), hypotf(boxSize.width(), boxSize.height()) / sqrtf(2));
- const BasicShapeRectangle* o = static_cast<const BasicShapeRectangle*>(other);
- RefPtr<BasicShapeRectangle> result = BasicShapeRectangle::create();
- result->setX(m_x.blend(o->x(), progress, ValueRangeAll));
- result->setY(m_y.blend(o->y(), progress, ValueRangeAll));
- result->setWidth(m_width.blend(o->width(), progress, ValueRangeNonNegative));
- result->setHeight(m_height.blend(o->height(), progress, ValueRangeNonNegative));
- result->setCornerRadiusX(m_cornerRadiusX.blend(o->cornerRadiusX(), progress, ValueRangeNonNegative));
- result->setCornerRadiusY(m_cornerRadiusY.blend(o->cornerRadiusY(), progress, ValueRangeNonNegative));
- return result.release();
+ FloatPoint center = floatPointForCenterCoordinate(m_centerX, m_centerY, boxSize);
+
+ if (m_radius.type() == BasicShapeRadius::ClosestSide)
+ return std::min(std::min(center.x(), boxSize.width() - center.x()), std::min(center.y(), boxSize.height() - center.y()));
+
+ // If radius.type() == BasicShapeRadius::FarthestSide.
+ return std::max(std::max(center.x(), boxSize.width() - center.x()), std::max(center.y(), boxSize.height() - center.y()));
}
void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox)
{
ASSERT(path.isEmpty());
- float diagonal = sqrtf((boundingBox.width() * boundingBox.width() + boundingBox.height() * boundingBox.height()) / 2);
- float centerX = floatValueForLength(m_centerX, boundingBox.width());
- float centerY = floatValueForLength(m_centerY, boundingBox.height());
- float radius = floatValueForLength(m_radius, diagonal);
+ FloatPoint center = floatPointForCenterCoordinate(m_centerX, m_centerY, boundingBox.size());
+ float radius = floatValueForRadiusInBox(boundingBox.size());
path.addEllipse(FloatRect(
- centerX - radius + boundingBox.x(),
- centerY - radius + boundingBox.y(),
+ center.x() - radius + boundingBox.x(),
+ center.y() - radius + boundingBox.y(),
radius * 2,
radius * 2
));
@@ -100,25 +120,44 @@ void BasicShapeCircle::path(Path& path, const FloatRect& boundingBox)
PassRefPtr<BasicShape> BasicShapeCircle::blend(const BasicShape* other, double progress) const
{
ASSERT(type() == other->type());
-
const BasicShapeCircle* o = static_cast<const BasicShapeCircle*>(other);
RefPtr<BasicShapeCircle> result = BasicShapeCircle::create();
- result->setCenterX(m_centerX.blend(o->centerX(), progress, ValueRangeAll));
- result->setCenterY(m_centerY.blend(o->centerY(), progress, ValueRangeAll));
- result->setRadius(m_radius.blend(o->radius(), progress, ValueRangeNonNegative));
+
+ result->setCenterX(m_centerX.blend(o->centerX(), progress));
+ result->setCenterY(m_centerY.blend(o->centerY(), progress));
+ result->setRadius(m_radius.blend(o->radius(), progress));
return result.release();
}
+bool BasicShapeEllipse::operator==(const BasicShape& o) const
+{
+ if (!isSameType(o))
+ return false;
+ const BasicShapeEllipse& other = toBasicShapeEllipse(o);
+ return m_centerX == other.m_centerX && m_centerY == other.m_centerY && m_radiusX == other.m_radiusX && m_radiusY == other.m_radiusY;
+}
+
+float BasicShapeEllipse::floatValueForRadiusInBox(const BasicShapeRadius& radius, float center, float boxWidthOrHeight) const
+{
+ if (radius.type() == BasicShapeRadius::Value)
+ return floatValueForLength(radius.value(), boxWidthOrHeight);
+
+ if (radius.type() == BasicShapeRadius::ClosestSide)
+ return std::min(center, boxWidthOrHeight - center);
+
+ ASSERT(radius.type() == BasicShapeRadius::FarthestSide);
+ return std::max(center, boxWidthOrHeight - center);
+}
+
void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox)
{
ASSERT(path.isEmpty());
- float centerX = floatValueForLength(m_centerX, boundingBox.width());
- float centerY = floatValueForLength(m_centerY, boundingBox.height());
- float radiusX = floatValueForLength(m_radiusX, boundingBox.width());
- float radiusY = floatValueForLength(m_radiusY, boundingBox.height());
+ FloatPoint center = floatPointForCenterCoordinate(m_centerX, m_centerY, boundingBox.size());
+ float radiusX = floatValueForRadiusInBox(m_radiusX, center.x(), boundingBox.width());
+ float radiusY = floatValueForRadiusInBox(m_radiusY, center.y(), boundingBox.height());
path.addEllipse(FloatRect(
- centerX - radiusX + boundingBox.x(),
- centerY - radiusY + boundingBox.y(),
+ center.x() - radiusX + boundingBox.x(),
+ center.y() - radiusY + boundingBox.y(),
radiusX * 2,
radiusY * 2
));
@@ -127,13 +166,22 @@ void BasicShapeEllipse::path(Path& path, const FloatRect& boundingBox)
PassRefPtr<BasicShape> BasicShapeEllipse::blend(const BasicShape* other, double progress) const
{
ASSERT(type() == other->type());
-
const BasicShapeEllipse* o = static_cast<const BasicShapeEllipse*>(other);
RefPtr<BasicShapeEllipse> result = BasicShapeEllipse::create();
- result->setCenterX(m_centerX.blend(o->centerX(), progress, ValueRangeAll));
- result->setCenterY(m_centerY.blend(o->centerY(), progress, ValueRangeAll));
- result->setRadiusX(m_radiusX.blend(o->radiusX(), progress, ValueRangeNonNegative));
- result->setRadiusY(m_radiusY.blend(o->radiusY(), progress, ValueRangeNonNegative));
+
+ if (m_radiusX.type() != BasicShapeRadius::Value || o->radiusX().type() != BasicShapeRadius::Value
+ || m_radiusY.type() != BasicShapeRadius::Value || o->radiusY().type() != BasicShapeRadius::Value) {
+ result->setCenterX(o->centerX());
+ result->setCenterY(o->centerY());
+ result->setRadiusX(o->radiusX());
+ result->setRadiusY(o->radiusY());
+ return result;
+ }
+
+ result->setCenterX(m_centerX.blend(o->centerX(), progress));
+ result->setCenterY(m_centerY.blend(o->centerY(), progress));
+ result->setRadiusX(m_radiusX.blend(o->radiusX(), progress));
+ result->setRadiusY(m_radiusY.blend(o->radiusY(), progress));
return result.release();
}
@@ -157,7 +205,7 @@ void BasicShapePolygon::path(Path& path, const FloatRect& boundingBox)
PassRefPtr<BasicShape> BasicShapePolygon::blend(const BasicShape* other, double progress) const
{
- ASSERT(type() == other->type());
+ ASSERT(other && isSameType(*other));
const BasicShapePolygon* o = static_cast<const BasicShapePolygon*>(other);
ASSERT(m_values.size() == o->values().size());
@@ -178,7 +226,21 @@ PassRefPtr<BasicShape> BasicShapePolygon::blend(const BasicShape* other, double
return result.release();
}
-void BasicShapeInsetRectangle::path(Path& path, const FloatRect& boundingBox)
+bool BasicShapePolygon::operator==(const BasicShape& o) const
+{
+ if (!isSameType(o))
+ return false;
+ const BasicShapePolygon& other = toBasicShapePolygon(o);
+ return m_windRule == other.m_windRule && m_values == other.m_values;
+}
+
+static FloatSize floatSizeForLengthSize(const LengthSize& lengthSize, const FloatRect& boundingBox)
+{
+ return FloatSize(floatValueForLength(lengthSize.width(), boundingBox.width()),
+ floatValueForLength(lengthSize.height(), boundingBox.height()));
+}
+
+void BasicShapeInset::path(Path& path, const FloatRect& boundingBox)
{
ASSERT(path.isEmpty());
float left = floatValueForLength(m_left, boundingBox.width());
@@ -190,25 +252,33 @@ void BasicShapeInsetRectangle::path(Path& path, const FloatRect& boundingBox)
std::max<float>(boundingBox.width() - left - floatValueForLength(m_right, boundingBox.width()), 0),
std::max<float>(boundingBox.height() - top - floatValueForLength(m_bottom, boundingBox.height()), 0)
),
- FloatSize(
- floatValueForLength(m_cornerRadiusX, boundingBox.width()),
- floatValueForLength(m_cornerRadiusY, boundingBox.height())
- )
+ floatSizeForLengthSize(m_topLeftRadius, boundingBox),
+ floatSizeForLengthSize(m_topRightRadius, boundingBox),
+ floatSizeForLengthSize(m_bottomLeftRadius, boundingBox),
+ floatSizeForLengthSize(m_bottomRightRadius, boundingBox)
);
}
-PassRefPtr<BasicShape> BasicShapeInsetRectangle::blend(const BasicShape* other, double progress) const
+PassRefPtr<BasicShape> BasicShapeInset::blend(const BasicShape* other, double) const
{
ASSERT(type() == other->type());
+ // FIXME: Implement blend for BasicShapeInset.
+ return nullptr;
+}
- const BasicShapeInsetRectangle* o = static_cast<const BasicShapeInsetRectangle*>(other);
- RefPtr<BasicShapeInsetRectangle> result = BasicShapeInsetRectangle::create();
- result->setTop(m_top.blend(o->top(), progress, ValueRangeNonNegative));
- result->setRight(m_right.blend(o->right(), progress, ValueRangeNonNegative));
- result->setBottom(m_bottom.blend(o->bottom(), progress, ValueRangeNonNegative));
- result->setLeft(m_left.blend(o->left(), progress, ValueRangeNonNegative));
- result->setCornerRadiusX(m_cornerRadiusX.blend(o->cornerRadiusX(), progress, ValueRangeNonNegative));
- result->setCornerRadiusY(m_cornerRadiusY.blend(o->cornerRadiusY(), progress, ValueRangeNonNegative));
- return result.release();
+bool BasicShapeInset::operator==(const BasicShape& o) const
+{
+ if (!isSameType(o))
+ return false;
+ const BasicShapeInset& other = toBasicShapeInset(o);
+ return m_right == other.m_right
+ && m_top == other.m_top
+ && m_bottom == other.m_bottom
+ && m_left == other.m_left
+ && m_topLeftRadius == other.m_topLeftRadius
+ && m_topRightRadius == other.m_topRightRadius
+ && m_bottomRightRadius == other.m_bottomRightRadius
+ && m_bottomLeftRadius == other.m_bottomLeftRadius;
}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.h b/chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.h
index b8735a82095..6f414688e28 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/BasicShapes.h
@@ -30,7 +30,9 @@
#ifndef BasicShapes_h
#define BasicShapes_h
+#include "core/rendering/style/RenderStyleConstants.h"
#include "platform/Length.h"
+#include "platform/LengthSize.h"
#include "platform/graphics/WindRule.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -39,6 +41,7 @@
namespace WebCore {
class FloatRect;
+class FloatSize;
class Path;
class BasicShape : public RefCounted<BasicShape> {
@@ -46,117 +49,174 @@ public:
virtual ~BasicShape() { }
enum Type {
- BasicShapeRectangleType = 1,
- BasicShapeCircleType = 2,
- BasicShapeEllipseType = 3,
- BasicShapePolygonType = 4,
- BasicShapeInsetRectangleType = 5
+ BasicShapeEllipseType,
+ BasicShapePolygonType,
+ BasicShapeCircleType,
+ BasicShapeInsetType
};
bool canBlend(const BasicShape*) const;
+ bool isSameType(const BasicShape& other) const { return type() == other.type(); }
virtual void path(Path&, const FloatRect&) = 0;
virtual WindRule windRule() const { return RULE_NONZERO; }
virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const = 0;
+ virtual bool operator==(const BasicShape&) const = 0;
virtual Type type() const = 0;
+
protected:
- BasicShape() { }
+ BasicShape()
+ {
+ }
+
};
-class BasicShapeRectangle : public BasicShape {
+#define DEFINE_BASICSHAPE_TYPE_CASTS(thisType) \
+ DEFINE_TYPE_CASTS(thisType, BasicShape, value, value->type() == BasicShape::thisType##Type, value.type() == BasicShape::thisType##Type)
+
+class BasicShapeCenterCoordinate {
public:
- static PassRefPtr<BasicShapeRectangle> create() { return adoptRef(new BasicShapeRectangle); }
-
- Length x() const { return m_x; }
- Length y() const { return m_y; }
- Length width() const { return m_width; }
- Length height() const { return m_height; }
- Length cornerRadiusX() const { return m_cornerRadiusX; }
- Length cornerRadiusY() const { return m_cornerRadiusY; }
-
- void setX(Length x) { m_x = x; }
- void setY(Length y) { m_y = y; }
- void setWidth(Length width) { m_width = width; }
- void setHeight(Length height) { m_height = height; }
- void setCornerRadiusX(Length radiusX)
+ enum Direction {
+ TopLeft,
+ BottomRight
+ };
+ BasicShapeCenterCoordinate()
+ : m_direction(TopLeft)
+ , m_length(Undefined)
{
- ASSERT(!radiusX.isUndefined());
- m_cornerRadiusX = radiusX;
+ updateComputedLength();
}
- void setCornerRadiusY(Length radiusY)
+
+ BasicShapeCenterCoordinate(Direction direction, const Length& length)
+ : m_direction(direction)
+ , m_length(length)
{
- ASSERT(!radiusY.isUndefined());
- m_cornerRadiusY = radiusY;
+ updateComputedLength();
}
- virtual void path(Path&, const FloatRect&) OVERRIDE;
- virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+ BasicShapeCenterCoordinate(const BasicShapeCenterCoordinate& other)
+ : m_direction(other.direction())
+ , m_length(other.length())
+ , m_computedLength(other.m_computedLength)
+ {
+ }
+
+ bool operator==(const BasicShapeCenterCoordinate& other) const { return m_direction == other.m_direction && m_length == other.m_length && m_computedLength == other.m_computedLength; }
+
+ Direction direction() const { return m_direction; }
+ const Length& length() const { return m_length; }
+ const Length& computedLength() const { return m_computedLength; }
+
+ BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress) const
+ {
+ return BasicShapeCenterCoordinate(TopLeft, m_computedLength.blend(other.m_computedLength, progress, ValueRangeAll));
+ }
- virtual Type type() const { return BasicShapeRectangleType; }
private:
- BasicShapeRectangle() { }
-
- Length m_y;
- Length m_x;
- Length m_width;
- Length m_height;
- Length m_cornerRadiusX;
- Length m_cornerRadiusY;
+ Direction m_direction;
+ Length m_length;
+ Length m_computedLength;
+
+ void updateComputedLength();
};
-class BasicShapeCircle : public BasicShape {
+class BasicShapeRadius {
+public:
+ enum Type {
+ Value,
+ ClosestSide,
+ FarthestSide
+ };
+ BasicShapeRadius() : m_value(Undefined), m_type(ClosestSide) { }
+ explicit BasicShapeRadius(const Length& v) : m_value(v), m_type(Value) { }
+ explicit BasicShapeRadius(Type t) : m_value(Undefined), m_type(t) { }
+ BasicShapeRadius(const BasicShapeRadius& other) : m_value(other.value()), m_type(other.type()) { }
+ bool operator==(const BasicShapeRadius& other) const { return m_type == other.m_type && m_value == other.m_value; }
+
+ const Length& value() const { return m_value; }
+ Type type() const { return m_type; }
+
+ bool canBlend(const BasicShapeRadius& other) const
+ {
+ // FIXME determine how to interpolate between keywords. See issue 330248.
+ return m_type == Value && other.type() == Value;
+ }
+
+ BasicShapeRadius blend(const BasicShapeRadius& other, double progress) const
+ {
+ if (m_type != Value || other.type() != Value)
+ return BasicShapeRadius(other);
+
+ return BasicShapeRadius(m_value.blend(other.value(), progress, ValueRangeNonNegative));
+ }
+
+private:
+ Length m_value;
+ Type m_type;
+
+};
+
+class BasicShapeCircle FINAL : public BasicShape {
public:
static PassRefPtr<BasicShapeCircle> create() { return adoptRef(new BasicShapeCircle); }
- Length centerX() const { return m_centerX; }
- Length centerY() const { return m_centerY; }
- Length radius() const { return m_radius; }
+ const BasicShapeCenterCoordinate& centerX() const { return m_centerX; }
+ const BasicShapeCenterCoordinate& centerY() const { return m_centerY; }
+ const BasicShapeRadius& radius() const { return m_radius; }
- void setCenterX(Length centerX) { m_centerX = centerX; }
- void setCenterY(Length centerY) { m_centerY = centerY; }
- void setRadius(Length radius) { m_radius = radius; }
+ float floatValueForRadiusInBox(FloatSize) const;
+ void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = centerX; }
+ void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = centerY; }
+ void setRadius(BasicShapeRadius radius) { m_radius = radius; }
virtual void path(Path&, const FloatRect&) OVERRIDE;
virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+ virtual bool operator==(const BasicShape&) const OVERRIDE;
- virtual Type type() const { return BasicShapeCircleType; }
+ virtual Type type() const OVERRIDE { return BasicShapeCircleType; }
private:
BasicShapeCircle() { }
- Length m_centerX;
- Length m_centerY;
- Length m_radius;
+ BasicShapeCenterCoordinate m_centerX;
+ BasicShapeCenterCoordinate m_centerY;
+ BasicShapeRadius m_radius;
};
-class BasicShapeEllipse : public BasicShape {
+DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeCircle);
+
+class BasicShapeEllipse FINAL : public BasicShape {
public:
static PassRefPtr<BasicShapeEllipse> create() { return adoptRef(new BasicShapeEllipse); }
- Length centerX() const { return m_centerX; }
- Length centerY() const { return m_centerY; }
- Length radiusX() const { return m_radiusX; }
- Length radiusY() const { return m_radiusY; }
+ const BasicShapeCenterCoordinate& centerX() const { return m_centerX; }
+ const BasicShapeCenterCoordinate& centerY() const { return m_centerY; }
+ const BasicShapeRadius& radiusX() const { return m_radiusX; }
+ const BasicShapeRadius& radiusY() const { return m_radiusY; }
+ float floatValueForRadiusInBox(const BasicShapeRadius&, float center, float boxWidthOrHeight) const;
- void setCenterX(Length centerX) { m_centerX = centerX; }
- void setCenterY(Length centerY) { m_centerY = centerY; }
- void setRadiusX(Length radiusX) { m_radiusX = radiusX; }
- void setRadiusY(Length radiusY) { m_radiusY = radiusY; }
+ void setCenterX(BasicShapeCenterCoordinate centerX) { m_centerX = centerX; }
+ void setCenterY(BasicShapeCenterCoordinate centerY) { m_centerY = centerY; }
+ void setRadiusX(BasicShapeRadius radiusX) { m_radiusX = radiusX; }
+ void setRadiusY(BasicShapeRadius radiusY) { m_radiusY = radiusY; }
virtual void path(Path&, const FloatRect&) OVERRIDE;
virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+ virtual bool operator==(const BasicShape&) const OVERRIDE;
- virtual Type type() const { return BasicShapeEllipseType; }
+ virtual Type type() const OVERRIDE { return BasicShapeEllipseType; }
private:
BasicShapeEllipse() { }
- Length m_centerX;
- Length m_centerY;
- Length m_radiusX;
- Length m_radiusY;
+ BasicShapeCenterCoordinate m_centerX;
+ BasicShapeCenterCoordinate m_centerY;
+ BasicShapeRadius m_radiusX;
+ BasicShapeRadius m_radiusY;
};
-class BasicShapePolygon : public BasicShape {
+DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeEllipse);
+
+class BasicShapePolygon FINAL : public BasicShape {
public:
static PassRefPtr<BasicShapePolygon> create() { return adoptRef(new BasicShapePolygon); }
@@ -165,14 +225,15 @@ public:
Length getYAt(unsigned i) const { return m_values.at(2 * i + 1); }
void setWindRule(WindRule windRule) { m_windRule = windRule; }
- void appendPoint(Length x, Length y) { m_values.append(x); m_values.append(y); }
+ void appendPoint(const Length& x, const Length& y) { m_values.append(x); m_values.append(y); }
virtual void path(Path&, const FloatRect&) OVERRIDE;
virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+ virtual bool operator==(const BasicShape&) const OVERRIDE;
- virtual WindRule windRule() const { return m_windRule; }
+ virtual WindRule windRule() const OVERRIDE { return m_windRule; }
- virtual Type type() const { return BasicShapePolygonType; }
+ virtual Type type() const OVERRIDE { return BasicShapePolygonType; }
private:
BasicShapePolygon()
: m_windRule(RULE_NONZERO)
@@ -182,45 +243,52 @@ private:
Vector<Length> m_values;
};
-class BasicShapeInsetRectangle : public BasicShape {
+DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapePolygon);
+
+class BasicShapeInset : public BasicShape {
public:
- static PassRefPtr<BasicShapeInsetRectangle> create() { return adoptRef(new BasicShapeInsetRectangle); }
-
- Length top() const { return m_top; }
- Length right() const { return m_right; }
- Length bottom() const { return m_bottom; }
- Length left() const { return m_left; }
- Length cornerRadiusX() const { return m_cornerRadiusX; }
- Length cornerRadiusY() const { return m_cornerRadiusY; }
-
- void setTop(Length top) { m_top = top; }
- void setRight(Length right) { m_right = right; }
- void setBottom(Length bottom) { m_bottom = bottom; }
- void setLeft(Length left) { m_left = left; }
- void setCornerRadiusX(Length radiusX)
- {
- ASSERT(!radiusX.isUndefined());
- m_cornerRadiusX = radiusX;
- }
- void setCornerRadiusY(Length radiusY)
- {
- ASSERT(!radiusY.isUndefined());
- m_cornerRadiusY = radiusY;
- }
+ static PassRefPtr<BasicShapeInset> create() { return adoptRef(new BasicShapeInset); }
+
+ const Length& top() const { return m_top; }
+ const Length& right() const { return m_right; }
+ const Length& bottom() const { return m_bottom; }
+ const Length& left() const { return m_left; }
+
+ const LengthSize& topLeftRadius() const { return m_topLeftRadius; }
+ const LengthSize& topRightRadius() const { return m_topRightRadius; }
+ const LengthSize& bottomRightRadius() const { return m_bottomRightRadius; }
+ const LengthSize& bottomLeftRadius() const { return m_bottomLeftRadius; }
+
+ void setTop(const Length& top) { m_top = top; }
+ void setRight(const Length& right) { m_right = right; }
+ void setBottom(const Length& bottom) { m_bottom = bottom; }
+ void setLeft(const Length& left) { m_left = left; }
+
+ void setTopLeftRadius(const LengthSize& radius) { m_topLeftRadius = radius; }
+ void setTopRightRadius(const LengthSize& radius) { m_topRightRadius = radius; }
+ void setBottomRightRadius(const LengthSize& radius) { m_bottomRightRadius = radius; }
+ void setBottomLeftRadius(const LengthSize& radius) { m_bottomLeftRadius = radius; }
virtual void path(Path&, const FloatRect&) OVERRIDE;
virtual PassRefPtr<BasicShape> blend(const BasicShape*, double) const OVERRIDE;
+ virtual bool operator==(const BasicShape&) const OVERRIDE;
- virtual Type type() const { return BasicShapeInsetRectangleType; }
+ virtual Type type() const OVERRIDE { return BasicShapeInsetType; }
private:
- BasicShapeInsetRectangle() { }
+ BasicShapeInset() { }
Length m_right;
Length m_top;
Length m_bottom;
Length m_left;
- Length m_cornerRadiusX;
- Length m_cornerRadiusY;
+
+ LengthSize m_topLeftRadius;
+ LengthSize m_topRightRadius;
+ LengthSize m_bottomRightRadius;
+ LengthSize m_bottomLeftRadius;
};
+
+DEFINE_BASICSHAPE_TYPE_CASTS(BasicShapeInset);
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/BorderData.h b/chromium/third_party/WebKit/Source/core/rendering/style/BorderData.h
index bf96bcf797c..4df4644ebfe 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/BorderData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/BorderData.h
@@ -94,6 +94,19 @@ public:
&& m_topLeft == o.m_topLeft && m_topRight == o.m_topRight && m_bottomLeft == o.m_bottomLeft && m_bottomRight == o.m_bottomRight;
}
+ bool visuallyEqual(const BorderData& o) const
+ {
+ return m_left.visuallyEqual(o.m_left)
+ && m_right.visuallyEqual(o.m_right)
+ && m_top.visuallyEqual(o.m_top)
+ && m_bottom.visuallyEqual(o.m_bottom)
+ && m_image == o.m_image
+ && m_topLeft == o.m_topLeft
+ && m_topRight == o.m_topRight
+ && m_bottomLeft == o.m_bottomLeft
+ && m_bottomRight == o.m_bottomRight;
+ }
+
bool operator!=(const BorderData& o) const
{
return !(*this == o);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/BorderValue.h b/chromium/third_party/WebKit/Source/core/rendering/style/BorderValue.h
index dcd5096df0b..211f0be97f9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/BorderValue.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/BorderValue.h
@@ -25,6 +25,7 @@
#ifndef BorderValue_h
#define BorderValue_h
+#include "core/css/StyleColor.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "platform/graphics/Color.h"
@@ -35,7 +36,7 @@ friend class RenderStyle;
public:
BorderValue()
: m_color(0)
- , m_colorIsValid(false)
+ , m_colorIsCurrentColor(true)
, m_width(3)
, m_style(BNONE)
, m_isAuto(AUTO_OFF)
@@ -49,7 +50,7 @@ public:
bool isTransparent() const
{
- return m_colorIsValid && !alphaChannel(m_color);
+ return !m_colorIsCurrentColor && !m_color.alpha();
}
bool isVisible(bool checkStyle = true) const
@@ -59,7 +60,17 @@ public:
bool operator==(const BorderValue& o) const
{
- return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color && m_colorIsValid == o.m_colorIsValid;
+ return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color && m_colorIsCurrentColor == o.m_colorIsCurrentColor;
+ }
+
+ // The default width is 3px, but if the style is none we compute a value of 0 (in RenderStyle itself)
+ bool visuallyEqual(const BorderValue& o) const
+ {
+ if (m_style == BNONE && o.m_style == BNONE)
+ return true;
+ if (m_style == BHIDDEN && o.m_style == BHIDDEN)
+ return true;
+ return *this == o;
}
bool operator!=(const BorderValue& o) const
@@ -67,20 +78,20 @@ public:
return !(*this == o);
}
- void setColor(const Color& color)
+ void setColor(const StyleColor& color)
{
- m_color = color.rgb();
- m_colorIsValid = color.isValid();
+ m_color = color.resolve(Color());
+ m_colorIsCurrentColor = color.isCurrentColor();
}
- Color color() const { return Color(m_color, m_colorIsValid); }
+ StyleColor color() const { return m_colorIsCurrentColor ? StyleColor::currentColor() : StyleColor(m_color); }
unsigned width() const { return m_width; }
EBorderStyle style() const { return static_cast<EBorderStyle>(m_style); }
protected:
- RGBA32 m_color;
- unsigned m_colorIsValid : 1;
+ Color m_color;
+ unsigned m_colorIsCurrentColor : 1;
unsigned m_width : 26;
unsigned m_style : 4; // EBorderStyle
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/CachedUAStyle.h b/chromium/third_party/WebKit/Source/core/rendering/style/CachedUAStyle.h
index f56d66f3395..10bed857f56 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/CachedUAStyle.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/CachedUAStyle.h
@@ -32,32 +32,31 @@ namespace WebCore {
// applyMatchedProperties for later use during adjustRenderStyle.
class CachedUAStyle {
public:
- CachedUAStyle()
- : hasAppearance(false)
- , backgroundLayers(BackgroundFillLayer)
- { }
+ static PassOwnPtr<CachedUAStyle> create(const RenderStyle* style)
+ {
+ return adoptPtr(new CachedUAStyle(style));
+ }
+
+ bool hasAppearance;
+ BorderData border;
+ FillLayer backgroundLayers;
+ StyleColor backgroundColor;
+private:
explicit CachedUAStyle(const RenderStyle* style)
- : hasAppearance(style->hasAppearance())
+ : hasAppearance(true)
, backgroundLayers(BackgroundFillLayer)
+ , backgroundColor(StyleColor::currentColor())
{
- // RenderTheme::adjustStyle is the only consumer of this data.
- // It only cares about the styles if appearance is set,
- // so we cheat and don't bother to copy them when !hasAppearance.
- if (!hasAppearance)
- return;
+ ASSERT(style->hasAppearance());
border = style->border();
backgroundLayers = *style->backgroundLayers();
backgroundColor = style->backgroundColor();
}
-
- bool hasAppearance;
- BorderData border;
- FillLayer backgroundLayers;
- Color backgroundColor;
};
+
} // namespace WebCore
#endif // CachedUAStyle_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/CollapsedBorderValue.h b/chromium/third_party/WebKit/Source/core/rendering/style/CollapsedBorderValue.h
index ef16dba2322..ac7b0575557 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/CollapsedBorderValue.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/CollapsedBorderValue.h
@@ -33,7 +33,7 @@ class CollapsedBorderValue {
public:
CollapsedBorderValue()
: m_color(0)
- , m_colorIsValid(false)
+ , m_colorIsCurrentColor(true)
, m_width(0)
, m_style(BNONE)
, m_precedence(BOFF)
@@ -41,9 +41,9 @@ public:
{
}
- CollapsedBorderValue(const BorderValue& border, const Color& color, EBorderPrecedence precedence)
- : m_color(color.rgb())
- , m_colorIsValid(color.isValid())
+ CollapsedBorderValue(const BorderValue& border, const StyleColor& color, EBorderPrecedence precedence)
+ : m_color(color.resolve(Color()))
+ , m_colorIsCurrentColor(color.isCurrentColor())
, m_width(border.nonZero() ? border.width() : 0)
, m_style(border.style())
, m_precedence(precedence)
@@ -54,7 +54,7 @@ public:
unsigned width() const { return m_style > BHIDDEN ? m_width : 0; }
EBorderStyle style() const { return static_cast<EBorderStyle>(m_style); }
bool exists() const { return m_precedence != BOFF; }
- Color color() const { return Color(m_color, m_colorIsValid); }
+ StyleColor color() const { return m_colorIsCurrentColor ? StyleColor::currentColor() : StyleColor(m_color); }
bool isTransparent() const { return m_transparent; }
EBorderPrecedence precedence() const { return static_cast<EBorderPrecedence>(m_precedence); }
@@ -64,8 +64,8 @@ public:
}
private:
- RGBA32 m_color;
- unsigned m_colorIsValid : 1;
+ Color m_color;
+ unsigned m_colorIsCurrentColor : 1;
unsigned m_width : 23;
unsigned m_style : 4; // EBorderStyle
unsigned m_precedence : 3; // EBorderPrecedence
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/ContentData.h b/chromium/third_party/WebKit/Source/core/rendering/style/ContentData.h
index 77dd5619e9c..a01f6cc018f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/ContentData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/ContentData.h
@@ -66,7 +66,7 @@ private:
OwnPtr<ContentData> m_next;
};
-class ImageContentData : public ContentData {
+class ImageContentData FINAL : public ContentData {
friend class ContentData;
public:
const StyleImage* image() const { return m_image.get(); }
@@ -89,7 +89,7 @@ private:
{
}
- virtual PassOwnPtr<ContentData> cloneInternal() const
+ virtual PassOwnPtr<ContentData> cloneInternal() const OVERRIDE
{
RefPtr<StyleImage> image = const_cast<StyleImage*>(this->image());
return create(image.release());
@@ -98,7 +98,7 @@ private:
RefPtr<StyleImage> m_image;
};
-class TextContentData : public ContentData {
+class TextContentData FINAL : public ContentData {
friend class ContentData;
public:
const String& text() const { return m_text; }
@@ -120,12 +120,12 @@ private:
{
}
- virtual PassOwnPtr<ContentData> cloneInternal() const { return create(text()); }
+ virtual PassOwnPtr<ContentData> cloneInternal() const OVERRIDE { return create(text()); }
String m_text;
};
-class CounterContentData : public ContentData {
+class CounterContentData FINAL : public ContentData {
friend class ContentData;
public:
const CounterContent* counter() const { return m_counter.get(); }
@@ -140,7 +140,7 @@ private:
{
}
- virtual PassOwnPtr<ContentData> cloneInternal() const
+ virtual PassOwnPtr<ContentData> cloneInternal() const OVERRIDE
{
OwnPtr<CounterContent> counterData = adoptPtr(new CounterContent(*counter()));
return create(counterData.release());
@@ -156,7 +156,7 @@ private:
OwnPtr<CounterContent> m_counter;
};
-class QuoteContentData : public ContentData {
+class QuoteContentData FINAL : public ContentData {
friend class ContentData;
public:
QuoteType quote() const { return m_quote; }
@@ -178,7 +178,7 @@ private:
{
}
- virtual PassOwnPtr<ContentData> cloneInternal() const { return create(quote()); }
+ virtual PassOwnPtr<ContentData> cloneInternal() const OVERRIDE { return create(quote()); }
QuoteType m_quote;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/CursorList.h b/chromium/third_party/WebKit/Source/core/rendering/style/CursorList.h
deleted file mode 100644
index 90bd00c181d..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/CursorList.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
- * (C) 2000 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef CursorList_h
-#define CursorList_h
-
-#include "core/rendering/style/CursorData.h"
-#include "wtf/RefCounted.h"
-#include "wtf/Vector.h"
-
-namespace WebCore {
-
-class CursorList : public RefCounted<CursorList> {
-public:
- static PassRefPtr<CursorList> create()
- {
- return adoptRef(new CursorList);
- }
-
- const CursorData& operator[](int i) const { return m_vector[i]; }
- CursorData& operator[](int i) { return m_vector[i]; }
- const CursorData& at(size_t i) const { return m_vector.at(i); }
- CursorData& at(size_t i) { return m_vector.at(i); }
-
- bool operator==(const CursorList& o) const { return m_vector == o.m_vector; }
- bool operator!=(const CursorList& o) const { return m_vector != o.m_vector; }
-
- size_t size() const { return m_vector.size(); }
- void append(const CursorData& cursorData) { m_vector.append(cursorData); }
-
-private:
- CursorList()
- {
- }
-
- Vector<CursorData> m_vector;
-};
-
-} // namespace WebCore
-
-#endif // CursorList_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/DataEquivalency.h b/chromium/third_party/WebKit/Source/core/rendering/style/DataEquivalency.h
new file mode 100644
index 00000000000..87d92388bbe
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/DataEquivalency.h
@@ -0,0 +1,49 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef DataEquivalency_h
+#define DataEquivalency_h
+
+#include "wtf/OwnPtr.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+template <typename T>
+bool dataEquivalent(const T* a, const T* b)
+{
+ if (a == b)
+ return true;
+ if (!a || !b)
+ return false;
+ return *a == *b;
+}
+
+template <typename T>
+bool dataEquivalent(const RefPtr<T>& a, const RefPtr<T>& b)
+{
+ return dataEquivalent(a.get(), b.get());
+}
+
+template <typename T>
+bool dataEquivalent(const Persistent<T>& a, const Persistent<T>& b)
+{
+ return dataEquivalent(a.get(), b.get());
+}
+
+template <typename T>
+bool dataEquivalent(const Member<T>& a, const Member<T>& b)
+{
+ return dataEquivalent(a.get(), b.get());
+}
+
+template <typename T>
+bool dataEquivalent(const OwnPtr<T>& a, const OwnPtr<T>& b)
+{
+ return dataEquivalent(a.get(), b.get());
+}
+
+} // namespace WebCore
+
+#endif // DataEquivalency_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.cpp
index 5a621e0c1f2..907a80d5b52 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.cpp
@@ -22,6 +22,8 @@
#include "config.h"
#include "core/rendering/style/FillLayer.h"
+#include "core/rendering/style/DataEquivalency.h"
+
namespace WebCore {
struct SameSizeAsFillLayer {
@@ -34,8 +36,8 @@ struct SameSizeAsFillLayer {
LengthSize m_sizeLength;
- unsigned m_bitfields: 32;
- unsigned m_bitfields2: 1;
+ unsigned m_bitfields1;
+ unsigned m_bitfields2;
};
COMPILE_ASSERT(sizeof(FillLayer) == sizeof(SameSizeAsFillLayer), FillLayer_should_stay_small);
@@ -159,7 +161,7 @@ bool FillLayer::operator==(const FillLayer& o) const
{
// We do not check the "isSet" booleans for each property, since those are only used during initial construction
// to propagate patterns into layers. All layer comparisons happen after values have all been filled in anyway.
- return StyleImage::imagesEquivalent(m_image.get(), o.m_image.get()) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition
+ return dataEquivalent(m_image, o.m_image) && m_xPosition == o.m_xPosition && m_yPosition == o.m_yPosition
&& m_backgroundXOrigin == o.m_backgroundXOrigin && m_backgroundYOrigin == o.m_backgroundYOrigin
&& m_attachment == o.m_attachment && m_clip == o.m_clip && m_composite == o.m_composite
&& m_blendMode == o.m_blendMode && m_origin == o.m_origin && m_repeatX == o.m_repeatX
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.h b/chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.h
index 790f202db1b..f79abaf9588 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/FillLayer.h
@@ -40,7 +40,7 @@ struct FillSize {
{
}
- FillSize(EFillSizeType t, LengthSize l)
+ FillSize(EFillSizeType t, const LengthSize& l)
: type(t)
, size(l)
{
@@ -66,8 +66,8 @@ public:
~FillLayer();
StyleImage* image() const { return m_image.get(); }
- Length xPosition() const { return m_xPosition; }
- Length yPosition() const { return m_yPosition; }
+ const Length& xPosition() const { return m_xPosition; }
+ const Length& yPosition() const { return m_yPosition; }
BackgroundEdgeOrigin backgroundXOrigin() const { return static_cast<BackgroundEdgeOrigin>(m_backgroundXOrigin); }
BackgroundEdgeOrigin backgroundYOrigin() const { return static_cast<BackgroundEdgeOrigin>(m_backgroundYOrigin); }
EFillAttachment attachment() const { return static_cast<EFillAttachment>(m_attachment); }
@@ -77,7 +77,7 @@ public:
EFillRepeat repeatY() const { return static_cast<EFillRepeat>(m_repeatY); }
CompositeOperator composite() const { return static_cast<CompositeOperator>(m_composite); }
blink::WebBlendMode blendMode() const { return static_cast<blink::WebBlendMode>(m_blendMode); }
- LengthSize sizeLength() const { return m_sizeLength; }
+ const LengthSize& sizeLength() const { return m_sizeLength; }
EFillSizeType sizeType() const { return static_cast<EFillSizeType>(m_sizeType); }
FillSize size() const { return FillSize(static_cast<EFillSizeType>(m_sizeType), m_sizeLength); }
EMaskSourceType maskSourceType() const { return static_cast<EMaskSourceType>(m_maskSourceType); }
@@ -101,8 +101,8 @@ public:
bool isMaskSourceTypeSet() const { return m_maskSourceTypeSet; }
void setImage(PassRefPtr<StyleImage> i) { m_image = i; m_imageSet = true; }
- void setXPosition(Length position) { m_xPosition = position; m_xPosSet = true; m_backgroundXOriginSet = false; m_backgroundXOrigin = LeftEdge; }
- void setYPosition(Length position) { m_yPosition = position; m_yPosSet = true; m_backgroundYOriginSet = false; m_backgroundYOrigin = TopEdge; }
+ void setXPosition(const Length& position) { m_xPosition = position; m_xPosSet = true; m_backgroundXOriginSet = false; m_backgroundXOrigin = LeftEdge; }
+ void setYPosition(const Length& position) { m_yPosition = position; m_yPosSet = true; m_backgroundYOriginSet = false; m_backgroundYOrigin = TopEdge; }
void setBackgroundXOrigin(BackgroundEdgeOrigin origin) { m_backgroundXOrigin = origin; m_backgroundXOriginSet = true; }
void setBackgroundYOrigin(BackgroundEdgeOrigin origin) { m_backgroundYOrigin = origin; m_backgroundYOriginSet = true; }
void setAttachment(EFillAttachment attachment) { m_attachment = attachment; m_attachmentSet = true; }
@@ -113,7 +113,7 @@ public:
void setComposite(CompositeOperator c) { m_composite = c; m_compositeSet = true; }
void setBlendMode(blink::WebBlendMode b) { m_blendMode = b; m_blendModeSet = true; }
void setSizeType(EFillSizeType b) { m_sizeType = b; }
- void setSizeLength(LengthSize l) { m_sizeLength = l; }
+ void setSizeLength(const LengthSize& l) { m_sizeLength = l; }
void setSize(FillSize f) { m_sizeType = f.type; m_sizeLength = f.size; }
void setMaskSourceType(EMaskSourceType m) { m_maskSourceType = m; m_maskSourceTypeSet = true; }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/GridCoordinate.h b/chromium/third_party/WebKit/Source/core/rendering/style/GridCoordinate.h
index 937d3f08b9b..fa78aa22a79 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/GridCoordinate.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/GridCoordinate.h
@@ -31,36 +31,36 @@
#ifndef GridCoordinate_h
#define GridCoordinate_h
-#include "core/rendering/style/GridPosition.h"
+#include "core/rendering/style/GridResolvedPosition.h"
#include "wtf/HashMap.h"
#include "wtf/PassOwnPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-// A span in a single direction (either rows or columns). Note that |initialPositionIndex|
-// and |finalPositionIndex| are grid areas' indexes, NOT grid lines'. Iterating over the
-// span should include both |initialPositionIndex| and |finalPositionIndex| to be correct.
+// A span in a single direction (either rows or columns). Note that |resolvedInitialPosition|
+// and |resolvedFinalPosition| are grid areas' indexes, NOT grid lines'. Iterating over the
+// span should include both |resolvedInitialPosition| and |resolvedFinalPosition| to be correct.
struct GridSpan {
- static PassOwnPtr<GridSpan> create(size_t initialPosition, size_t finalPosition)
+ static PassOwnPtr<GridSpan> create(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition)
{
- return adoptPtr(new GridSpan(initialPosition, finalPosition));
+ return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition));
}
- static PassOwnPtr<GridSpan> createWithSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+ static PassOwnPtr<GridSpan> createWithSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
{
// 'span 1' is contained inside a single grid track regardless of the direction.
// That's why the CSS span value is one more than the offset we apply.
size_t positionOffset = position.spanPosition() - 1;
if (side == ColumnStartSide || side == RowStartSide) {
- size_t initialResolvedPosition = std::max<int>(0, resolvedOppositePosition - positionOffset);
+ GridResolvedPosition initialResolvedPosition = GridResolvedPosition(std::max<int>(0, resolvedOppositePosition.toInt() - positionOffset));
return GridSpan::create(initialResolvedPosition, resolvedOppositePosition);
}
- return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition + positionOffset);
+ return GridSpan::create(resolvedOppositePosition, GridResolvedPosition(resolvedOppositePosition.toInt() + positionOffset));
}
- static PassOwnPtr<GridSpan> createWithNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>& gridLines)
+ static PassOwnPtr<GridSpan> createWithNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side, const Vector<size_t>& gridLines)
{
if (side == RowStartSide || side == ColumnStartSide)
return createWithInitialNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
@@ -68,50 +68,71 @@ struct GridSpan {
return createWithFinalNamedSpanAgainstOpposite(resolvedOppositePosition, position, gridLines);
}
- static PassOwnPtr<GridSpan> createWithInitialNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
+ static PassOwnPtr<GridSpan> createWithInitialNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
{
// The grid line inequality needs to be strict (which doesn't match the after / end case) because |resolvedOppositePosition|
// is already converted to an index in our grid representation (ie one was removed from the grid line to account for the side).
size_t firstLineBeforeOppositePositionIndex = 0;
- const size_t* firstLineBeforeOppositePosition = std::lower_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
- if (firstLineBeforeOppositePosition != gridLines.end())
+ const size_t* firstLineBeforeOppositePosition = std::lower_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition.toInt());
+ if (firstLineBeforeOppositePosition != gridLines.end()) {
+ if (*firstLineBeforeOppositePosition > resolvedOppositePosition.toInt() && firstLineBeforeOppositePosition != gridLines.begin())
+ --firstLineBeforeOppositePosition;
+
firstLineBeforeOppositePositionIndex = firstLineBeforeOppositePosition - gridLines.begin();
+ }
size_t gridLineIndex = std::max<int>(0, firstLineBeforeOppositePositionIndex - position.spanPosition() + 1);
- size_t resolvedGridLinePosition = gridLines[gridLineIndex];
+ GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition(gridLines[gridLineIndex]);
if (resolvedGridLinePosition > resolvedOppositePosition)
resolvedGridLinePosition = resolvedOppositePosition;
return GridSpan::create(resolvedGridLinePosition, resolvedOppositePosition);
}
- static PassOwnPtr<GridSpan> createWithFinalNamedSpanAgainstOpposite(size_t resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
+ static PassOwnPtr<GridSpan> createWithFinalNamedSpanAgainstOpposite(const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, const Vector<size_t>& gridLines)
{
size_t firstLineAfterOppositePositionIndex = gridLines.size() - 1;
- const size_t* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
+ const size_t* firstLineAfterOppositePosition = std::upper_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition.toInt());
if (firstLineAfterOppositePosition != gridLines.end())
firstLineAfterOppositePositionIndex = firstLineAfterOppositePosition - gridLines.begin();
size_t gridLineIndex = std::min(gridLines.size() - 1, firstLineAfterOppositePositionIndex + position.spanPosition() - 1);
- size_t resolvedGridLinePosition = GridPosition::adjustGridPositionForAfterEndSide(gridLines[gridLineIndex]);
+ GridResolvedPosition resolvedGridLinePosition = GridResolvedPosition::adjustGridPositionForAfterEndSide(gridLines[gridLineIndex]);
if (resolvedGridLinePosition < resolvedOppositePosition)
resolvedGridLinePosition = resolvedOppositePosition;
return GridSpan::create(resolvedOppositePosition, resolvedGridLinePosition);
}
- GridSpan(size_t initialPosition, size_t finalPosition)
- : initialPositionIndex(initialPosition)
- , finalPositionIndex(finalPosition)
+ GridSpan(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition)
+ : resolvedInitialPosition(resolvedInitialPosition)
+ , resolvedFinalPosition(resolvedFinalPosition)
{
- ASSERT(initialPositionIndex <= finalPositionIndex);
+ ASSERT(resolvedInitialPosition <= resolvedFinalPosition);
}
bool operator==(const GridSpan& o) const
{
- return initialPositionIndex == o.initialPositionIndex && finalPositionIndex == o.finalPositionIndex;
+ return resolvedInitialPosition == o.resolvedInitialPosition && resolvedFinalPosition == o.resolvedFinalPosition;
+ }
+
+ size_t integerSpan() const
+ {
+ return resolvedFinalPosition.toInt() - resolvedInitialPosition.toInt() + 1;
+ }
+
+ GridResolvedPosition resolvedInitialPosition;
+ GridResolvedPosition resolvedFinalPosition;
+
+ typedef GridResolvedPosition iterator;
+
+ iterator begin() const
+ {
+ return resolvedInitialPosition;
}
- size_t initialPositionIndex;
- size_t finalPositionIndex;
+ iterator end() const
+ {
+ return resolvedFinalPosition.next();
+ }
};
// This represents a grid area that spans in both rows' and columns' direction.
@@ -139,6 +160,22 @@ struct GridCoordinate {
return !(*this == o);
}
+ GridResolvedPosition positionForSide(GridPositionSide side) const
+ {
+ switch (side) {
+ case ColumnStartSide:
+ return columns.resolvedInitialPosition;
+ case ColumnEndSide:
+ return columns.resolvedFinalPosition;
+ case RowStartSide:
+ return rows.resolvedInitialPosition;
+ case RowEndSide:
+ return rows.resolvedFinalPosition;
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
GridSpan columns;
GridSpan rows;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/GridLength.h b/chromium/third_party/WebKit/Source/core/rendering/style/GridLength.h
index dadf7dac255..e822d08ab0b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/GridLength.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/GridLength.h
@@ -40,17 +40,17 @@ namespace WebCore {
// an new unit to Length.h.
class GridLength {
public:
- GridLength()
- : m_length(Undefined)
+ GridLength(const Length& length)
+ : m_length(length)
, m_flex(0)
, m_type(LengthType)
{
+ ASSERT(!length.isUndefined());
}
- GridLength(const Length& length)
- : m_length(length)
- , m_flex(0)
- , m_type(LengthType)
+ explicit GridLength(double flex)
+ : m_flex(flex)
+ , m_type(FlexType)
{
}
@@ -58,14 +58,8 @@ public:
bool isFlex() const { return m_type == FlexType; }
const Length& length() const { ASSERT(isLength()); return m_length; }
- Length& length() { ASSERT(isLength()); return m_length; }
double flex() const { ASSERT(isFlex()); return m_flex; }
- void setFlex(double flex)
- {
- m_type = FlexType;
- m_flex = flex;
- }
bool operator==(const GridLength& o) const
{
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/GridPosition.h b/chromium/third_party/WebKit/Source/core/rendering/style/GridPosition.h
index 133cdd55123..bb404909546 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/GridPosition.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/GridPosition.h
@@ -42,13 +42,6 @@ enum GridPositionType {
NamedGridAreaPosition // <ident>
};
-enum GridPositionSide {
- ColumnStartSide,
- ColumnEndSide,
- RowStartSide,
- RowEndSide
-};
-
class GridPosition {
public:
GridPosition()
@@ -57,20 +50,6 @@ public:
{
}
- static size_t adjustGridPositionForAfterEndSide(size_t resolvedPosition)
- {
- return resolvedPosition ? resolvedPosition - 1 : 0;
- }
-
- static size_t adjustGridPositionForSide(size_t resolvedPosition, GridPositionSide side)
- {
- // An item finishing on the N-th line belongs to the N-1-th cell.
- if (side == ColumnEndSide || side == RowEndSide)
- return adjustGridPositionForAfterEndSide(resolvedPosition);
-
- return resolvedPosition;
- }
-
bool isPositive() const { return integerPosition() > 0; }
GridPositionType type() const { return m_type; }
@@ -85,6 +64,12 @@ public:
m_namedGridLine = namedGridLine;
}
+ void setAutoPosition()
+ {
+ m_type = AutoPosition;
+ m_integerPosition = 0;
+ }
+
// 'span' values cannot be negative, yet we reuse the <integer> position which can
// be. This means that we have to convert the span position to an integer, losing
// some precision here. It shouldn't be an issue in practice though.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/GridResolvedPosition.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/GridResolvedPosition.cpp
new file mode 100644
index 00000000000..b537048b75c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/GridResolvedPosition.cpp
@@ -0,0 +1,253 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/rendering/style/GridResolvedPosition.h"
+
+#include "core/rendering/RenderBox.h"
+#include "core/rendering/style/GridCoordinate.h"
+
+namespace WebCore {
+
+static const NamedGridLinesMap& gridLinesForSide(const RenderStyle& style, GridPositionSide side)
+{
+ return (side == ColumnStartSide || side == ColumnEndSide) ? style.namedGridColumnLines() : style.namedGridRowLines();
+}
+
+static inline String implicitNamedGridLineForSide(const String& lineName, GridPositionSide side)
+{
+ return lineName + ((side == ColumnStartSide || side == RowStartSide) ? "-start" : "-end");
+}
+
+static bool isValidNamedLineOrArea(const String& lineName, const RenderStyle& style, GridPositionSide side)
+{
+ const NamedGridLinesMap& gridLineNames = gridLinesForSide(style, side);
+
+ return gridLineNames.contains(implicitNamedGridLineForSide(lineName, side)) || gridLineNames.contains(lineName);
+}
+
+static GridPositionSide calculateInitialPositionSide(GridTrackSizingDirection direction)
+{
+ return (direction == ForColumns) ? ColumnStartSide : RowStartSide;
+}
+
+static GridPositionSide calculateFinalPositionSide(GridTrackSizingDirection direction)
+{
+ return (direction == ForColumns) ? ColumnEndSide : RowEndSide;
+}
+
+void GridResolvedPosition::initialAndFinalPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, GridPosition& initialPosition, GridPosition& finalPosition)
+{
+ initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnStart() : gridItem.style()->gridRowStart();
+ finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd() : gridItem.style()->gridRowEnd();
+ GridPositionSide initialPositionSide = calculateInitialPositionSide(direction);
+ GridPositionSide finalPositionSide = calculateFinalPositionSide(direction);
+
+ // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to
+ // overwrite the specified values.
+ if (initialPosition.isSpan() && finalPosition.isSpan())
+ finalPosition.setAutoPosition();
+
+ // Try to early detect the case of non existing named grid lines. This way we could assume later that
+ // GridResolvedPosition::resolveGrisPositionFromStyle() always return a valid resolved position.
+ if (initialPosition.isNamedGridArea() && !isValidNamedLineOrArea(initialPosition.namedGridLine(), gridContainerStyle, initialPositionSide))
+ initialPosition.setAutoPosition();
+
+ if (finalPosition.isNamedGridArea() && !isValidNamedLineOrArea(finalPosition.namedGridLine(), gridContainerStyle, finalPositionSide))
+ finalPosition.setAutoPosition();
+
+ // If the grid item has an automatic position and a grid span for a named line in a given dimension, instead treat the grid span as one.
+ if (initialPosition.isAuto() && finalPosition.isSpan() && !finalPosition.namedGridLine().isNull())
+ finalPosition.setSpanPosition(1, String());
+ if (finalPosition.isAuto() && initialPosition.isSpan() && !initialPosition.namedGridLine().isNull())
+ initialPosition.setSpanPosition(1, String());
+}
+
+GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, const GridResolvedPosition& resolvedInitialPosition)
+{
+ GridPosition initialPosition, finalPosition;
+ initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, initialPosition, finalPosition);
+
+ GridPositionSide finalPositionSide = calculateFinalPositionSide(direction);
+
+ // This method will only be used when both positions need to be resolved against the opposite one.
+ ASSERT(initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition());
+
+ GridResolvedPosition resolvedFinalPosition = resolvedInitialPosition;
+
+ if (initialPosition.isSpan()) {
+ resolvedFinalPosition = resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, initialPosition, finalPositionSide)->resolvedFinalPosition;
+ } else if (finalPosition.isSpan()) {
+ resolvedFinalPosition = resolveGridPositionAgainstOppositePosition(gridContainerStyle, resolvedInitialPosition, finalPosition, finalPositionSide)->resolvedFinalPosition;
+ }
+
+ return GridSpan(resolvedInitialPosition, resolvedFinalPosition);
+}
+
+PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction)
+{
+ GridPosition initialPosition, finalPosition;
+ initialAndFinalPositionsFromStyle(gridContainerStyle, gridItem, direction, initialPosition, finalPosition);
+
+ GridPositionSide initialPositionSide = calculateInitialPositionSide(direction);
+ GridPositionSide finalPositionSide = calculateFinalPositionSide(direction);
+
+ if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) {
+ if (gridContainerStyle.gridAutoFlow() == AutoFlowNone)
+ return adoptPtr(new GridSpan(0, 0));
+
+ // We can't get our grid positions without running the auto placement algorithm.
+ return nullptr;
+ }
+
+ if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
+ // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
+ GridResolvedPosition finalResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide);
+ return resolveGridPositionAgainstOppositePosition(gridContainerStyle, finalResolvedPosition, initialPosition, initialPositionSide);
+ }
+
+ if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
+ // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
+ GridResolvedPosition initialResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide);
+ return resolveGridPositionAgainstOppositePosition(gridContainerStyle, initialResolvedPosition, finalPosition, finalPositionSide);
+ }
+
+ GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide);
+ GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide);
+
+ // If 'grid-after' specifies a line at or before that specified by 'grid-before', it computes to 'span 1'.
+ if (resolvedFinalPosition < resolvedInitialPosition)
+ resolvedFinalPosition = resolvedInitialPosition;
+
+ return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition));
+}
+
+size_t GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridContainerStyle)
+{
+ return gridContainerStyle.gridTemplateColumns().size();
+}
+
+size_t GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContainerStyle)
+{
+ return gridContainerStyle.gridTemplateRows().size();
+}
+
+size_t GridResolvedPosition::explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side)
+{
+ return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColumnCount(gridContainerStyle) : explicitGridRowCount(gridContainerStyle);
+}
+
+GridResolvedPosition GridResolvedPosition::resolveNamedGridLinePositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
+{
+ ASSERT(!position.namedGridLine().isNull());
+
+ const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyle, side);
+ NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
+ if (it == gridLinesNames.end()) {
+ if (position.isPositive())
+ return GridResolvedPosition(0);
+ const size_t lastLine = explicitGridSizeForSide(gridContainerStyle, side);
+ return adjustGridPositionForSide(lastLine, side);
+ }
+
+ size_t namedGridLineIndex;
+ if (position.isPositive())
+ namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->value.size()) - 1;
+ else
+ namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integerPosition()), 0);
+ return adjustGridPositionForSide(it->value[namedGridLineIndex], side);
+}
+
+GridResolvedPosition GridResolvedPosition::resolveGridPositionFromStyle(const RenderStyle& gridContainerStyle, const GridPosition& position, GridPositionSide side)
+{
+ switch (position.type()) {
+ case ExplicitPosition: {
+ ASSERT(position.integerPosition());
+
+ if (!position.namedGridLine().isNull())
+ return resolveNamedGridLinePositionFromStyle(gridContainerStyle, position, side);
+
+ // Handle <integer> explicit position.
+ if (position.isPositive())
+ return adjustGridPositionForSide(position.integerPosition() - 1, side);
+
+ size_t resolvedPosition = abs(position.integerPosition()) - 1;
+ const size_t endOfTrack = explicitGridSizeForSide(gridContainerStyle, side);
+
+ // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line.
+ if (endOfTrack < resolvedPosition)
+ return GridResolvedPosition(0);
+
+ return adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
+ }
+ case NamedGridAreaPosition:
+ {
+ // First attempt to match the grid area’s edge to a named grid area: if there is a named line with the name
+ // ''<custom-ident>-start (for grid-*-start) / <custom-ident>-end'' (for grid-*-end), contributes the first such
+ // line to the grid item’s placement.
+ String namedGridLine = position.namedGridLine();
+ ASSERT(isValidNamedLineOrArea(namedGridLine, gridContainerStyle, side));
+
+ const NamedGridLinesMap& gridLineNames = gridLinesForSide(gridContainerStyle, side);
+ NamedGridLinesMap::const_iterator implicitLineIter = gridLineNames.find(implicitNamedGridLineForSide(namedGridLine, side));
+ if (implicitLineIter != gridLineNames.end())
+ return adjustGridPositionForSide(implicitLineIter->value[0], side);
+
+ // Otherwise, if there is a named line with the specified name, contributes the first such line to the grid
+ // item’s placement.
+ NamedGridLinesMap::const_iterator explicitLineIter = gridLineNames.find(namedGridLine);
+ if (explicitLineIter != gridLineNames.end())
+ return adjustGridPositionForSide(explicitLineIter->value[0], side);
+
+ // If none of the above works specs mandate us to treat it as auto BUT we should have detected it before calling
+ // this function in GridResolvedPosition::resolveGridPositionsFromStyle(). We should be also covered by the
+ // ASSERT at the beginning of this block.
+ ASSERT_NOT_REACHED();
+ return GridResolvedPosition(0);
+ }
+ case AutoPosition:
+ case SpanPosition:
+ // 'auto' and span depend on the opposite position for resolution (e.g. grid-row: auto / 1 or grid-column: span 3 / "myHeader").
+ ASSERT_NOT_REACHED();
+ return GridResolvedPosition(0);
+ }
+ ASSERT_NOT_REACHED();
+ return GridResolvedPosition(0);
+}
+
+PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+{
+ if (position.isAuto())
+ return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition);
+
+ ASSERT(position.isSpan());
+ ASSERT(position.spanPosition() > 0);
+
+ if (!position.namedGridLine().isNull()) {
+ // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position.
+ return resolveNamedGridLinePositionAgainstOppositePosition(gridContainerStyle, resolvedOppositePosition, position, side);
+ }
+
+ return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, position, side);
+}
+
+PassOwnPtr<GridSpan> GridResolvedPosition::resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle& gridContainerStyle, const GridResolvedPosition& resolvedOppositePosition, const GridPosition& position, GridPositionSide side)
+{
+ ASSERT(position.isSpan());
+ ASSERT(!position.namedGridLine().isNull());
+ // Negative positions are not allowed per the specification and should have been handled during parsing.
+ ASSERT(position.spanPosition() > 0);
+
+ const NamedGridLinesMap& gridLinesNames = gridLinesForSide(gridContainerStyle, side);
+ NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
+
+ // If there is no named grid line of that name, we resolve the position to 'auto' (which is equivalent to 'span 1' in this case).
+ // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
+ if (it == gridLinesNames.end())
+ return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition);
+
+ return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, it->value);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/GridResolvedPosition.h b/chromium/third_party/WebKit/Source/core/rendering/style/GridResolvedPosition.h
new file mode 100644
index 00000000000..e9a79566736
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/GridResolvedPosition.h
@@ -0,0 +1,125 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GridResolvedPosition_h
+#define GridResolvedPosition_h
+
+#include "core/rendering/style/GridPosition.h"
+
+namespace WebCore {
+
+struct GridSpan;
+class RenderBox;
+class RenderStyle;
+
+enum GridPositionSide {
+ ColumnStartSide,
+ ColumnEndSide,
+ RowStartSide,
+ RowEndSide
+};
+
+enum GridTrackSizingDirection {
+ ForColumns,
+ ForRows
+};
+
+// This class represents an index into one of the dimensions of the grid array.
+// Wraps a size_t integer just for the purpose of knowing what we manipulate in the grid code.
+class GridResolvedPosition {
+public:
+ static GridResolvedPosition adjustGridPositionForAfterEndSide(size_t resolvedPosition)
+ {
+ return resolvedPosition ? GridResolvedPosition(resolvedPosition - 1) : GridResolvedPosition(0);
+ }
+
+ static GridResolvedPosition adjustGridPositionForSide(size_t resolvedPosition, GridPositionSide side)
+ {
+ // An item finishing on the N-th line belongs to the N-1-th cell.
+ if (side == ColumnEndSide || side == RowEndSide)
+ return adjustGridPositionForAfterEndSide(resolvedPosition);
+
+ return GridResolvedPosition(resolvedPosition);
+ }
+
+ static void initialAndFinalPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, GridPosition &initialPosition, GridPosition &finalPosition);
+ static GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderStyle&, const RenderBox&, GridTrackSizingDirection, const GridResolvedPosition&);
+ static PassOwnPtr<GridSpan> resolveGridPositionsFromStyle(const RenderStyle&, const RenderBox&, GridTrackSizingDirection);
+ static GridResolvedPosition resolveNamedGridLinePositionFromStyle(const RenderStyle&, const GridPosition&, GridPositionSide);
+ static GridResolvedPosition resolveGridPositionFromStyle(const RenderStyle&, const GridPosition&, GridPositionSide);
+ static PassOwnPtr<GridSpan> resolveGridPositionAgainstOppositePosition(const RenderStyle&, const GridResolvedPosition& resolvedOppositePosition, const GridPosition&, GridPositionSide);
+ static PassOwnPtr<GridSpan> resolveNamedGridLinePositionAgainstOppositePosition(const RenderStyle&, const GridResolvedPosition& resolvedOppositePosition, const GridPosition&, GridPositionSide);
+
+ GridResolvedPosition(size_t position)
+ : m_integerPosition(position)
+ {
+ }
+
+ GridResolvedPosition(const GridPosition& position, GridPositionSide side)
+ {
+ ASSERT(position.integerPosition());
+ size_t integerPosition = position.integerPosition() - 1;
+
+ m_integerPosition = adjustGridPositionForSide(integerPosition, side).toInt();
+ }
+
+ GridResolvedPosition& operator++()
+ {
+ m_integerPosition++;
+ return *this;
+ }
+
+ bool operator==(const GridResolvedPosition& other) const
+ {
+ return m_integerPosition == other.m_integerPosition;
+ }
+
+ bool operator!=(const GridResolvedPosition& other) const
+ {
+ return m_integerPosition != other.m_integerPosition;
+ }
+
+ bool operator<(const GridResolvedPosition& other) const
+ {
+ return m_integerPosition < other.m_integerPosition;
+ }
+
+ bool operator>(const GridResolvedPosition& other) const
+ {
+ return m_integerPosition > other.m_integerPosition;
+ }
+
+ bool operator<=(const GridResolvedPosition& other) const
+ {
+ return m_integerPosition <= other.m_integerPosition;
+ }
+
+ bool operator>=(const GridResolvedPosition& other) const
+ {
+ return m_integerPosition >= other.m_integerPosition;
+ }
+
+ size_t toInt() const
+ {
+ return m_integerPosition;
+ }
+
+ GridResolvedPosition next() const
+ {
+ return GridResolvedPosition(m_integerPosition + 1);
+ }
+
+ static size_t explicitGridColumnCount(const RenderStyle&);
+ static size_t explicitGridRowCount(const RenderStyle&);
+
+private:
+
+ static size_t explicitGridSizeForSide(const RenderStyle&, GridPositionSide);
+
+ size_t m_integerPosition;
+};
+
+} // namespace WebCore
+
+#endif // GridResolvedPosition_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/GridTrackSize.h b/chromium/third_party/WebKit/Source/core/rendering/style/GridTrackSize.h
index 584b47a4024..b64e5e3bc21 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/GridTrackSize.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/GridTrackSize.h
@@ -42,30 +42,27 @@ enum GridTrackSizeType {
class GridTrackSize {
public:
- GridTrackSize()
+ GridTrackSize(const GridLength& length)
: m_type(LengthTrackSizing)
- , m_minTrackBreadth(Undefined)
- , m_maxTrackBreadth(Undefined)
+ , m_minTrackBreadth(length)
+ , m_maxTrackBreadth(length)
, m_minTrackBreadthIsMinOrMaxContent(false)
, m_minTrackBreadthIsMaxContent(false)
, m_maxTrackBreadthIsMinOrMaxContent(false)
, m_maxTrackBreadthIsMaxContent(false)
{
- // Someone has to set a valid lenght type through setLength or
- // setMinMax before using the object.
+ cacheMinMaxTrackBreadthTypes();
}
- GridTrackSize(LengthType type)
- : m_type(LengthTrackSizing)
- , m_minTrackBreadth(type)
- , m_maxTrackBreadth(type)
+ GridTrackSize(const GridLength& minTrackBreadth, const GridLength& maxTrackBreadth)
+ : m_type(MinMaxTrackSizing)
+ , m_minTrackBreadth(minTrackBreadth)
+ , m_maxTrackBreadth(maxTrackBreadth)
, m_minTrackBreadthIsMinOrMaxContent(false)
, m_minTrackBreadthIsMaxContent(false)
, m_maxTrackBreadthIsMinOrMaxContent(false)
, m_maxTrackBreadthIsMaxContent(false)
{
- ASSERT(type != Undefined);
-
cacheMinMaxTrackBreadthTypes();
}
@@ -74,24 +71,13 @@ public:
ASSERT(m_type == LengthTrackSizing);
ASSERT(m_minTrackBreadth == m_maxTrackBreadth);
const GridLength& minTrackBreadth = m_minTrackBreadth;
- ASSERT(!minTrackBreadth.isLength() || !minTrackBreadth.length().isUndefined());
return minTrackBreadth;
}
- void setLength(const GridLength& length)
- {
- m_type = LengthTrackSizing;
- m_minTrackBreadth = length;
- m_maxTrackBreadth = length;
-
- cacheMinMaxTrackBreadthTypes();
- }
-
const GridLength& minTrackBreadth() const
{
- ASSERT(!m_minTrackBreadth.isLength() || !m_minTrackBreadth.length().isUndefined());
if (m_minTrackBreadth.isLength() && m_minTrackBreadth.length().isAuto()) {
- DEFINE_STATIC_LOCAL(GridLength, minContent, (MinContent));
+ DEFINE_STATIC_LOCAL(GridLength, minContent, (Length(MinContent)));
return minContent;
}
return m_minTrackBreadth;
@@ -99,27 +85,19 @@ public:
const GridLength& maxTrackBreadth() const
{
- ASSERT(!m_maxTrackBreadth.isLength() || !m_maxTrackBreadth.length().isUndefined());
if (m_maxTrackBreadth.isLength() && m_maxTrackBreadth.length().isAuto()) {
- DEFINE_STATIC_LOCAL(GridLength, maxContent, (MaxContent));
+ DEFINE_STATIC_LOCAL(GridLength, maxContent, (Length(MaxContent)));
return maxContent;
}
return m_maxTrackBreadth;
}
- void setMinMax(const GridLength& minTrackBreadth, const GridLength& maxTrackBreadth)
- {
- m_type = MinMaxTrackSizing;
- m_minTrackBreadth = minTrackBreadth;
- m_maxTrackBreadth = maxTrackBreadth;
-
- cacheMinMaxTrackBreadthTypes();
- }
-
GridTrackSizeType type() const { return m_type; }
bool isContentSized() const { return m_minTrackBreadth.isContentSized() || m_maxTrackBreadth.isContentSized(); }
+ bool isPercentage() const { return m_type == LengthTrackSizing && length().isLength() && length().length().isPercent(); }
+
bool operator==(const GridTrackSize& other) const
{
return m_type == other.m_type && m_minTrackBreadth == other.m_minTrackBreadth && m_maxTrackBreadth == other.m_maxTrackBreadth;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.cpp
index 2ed58360ee1..4ddaf8a5789 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.cpp
@@ -28,27 +28,6 @@
namespace WebCore {
-void KeyframeValue::addProperties(const StylePropertySet* propertySet)
-{
- if (!propertySet)
- return;
- unsigned propertyCount = propertySet->propertyCount();
- for (unsigned i = 0; i < propertyCount; ++i) {
- CSSPropertyID property = propertySet->propertyAt(i).id();
- // Timing-function within keyframes is special, because it is not animated; it just
- // describes the timing function between this keyframe and the next.
- if (property != CSSPropertyWebkitAnimationTimingFunction && property != CSSPropertyAnimationTimingFunction)
- addProperty(property);
- }
-}
-
-TimingFunction* KeyframeValue::timingFunction(const RenderStyle& keyframeStyle)
-{
- const CSSAnimationDataList* animations = keyframeStyle.animations();
- ASSERT(animations && !animations->isEmpty());
- return animations->animation(0)->timingFunction();
-}
-
KeyframeList::~KeyframeList()
{
clear();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.h b/chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.h
index ee2d237b505..26f7b9e76d7 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/KeyframeList.h
@@ -25,7 +25,7 @@
#ifndef KeyframeList_h
#define KeyframeList_h
-#include "CSSPropertyNames.h"
+#include "core/CSSPropertyNames.h"
#include "core/rendering/style/StyleInheritedData.h"
#include "wtf/HashSet.h"
#include "wtf/RefPtr.h"
@@ -36,8 +36,6 @@ namespace WebCore {
class RenderObject;
class RenderStyle;
-class StylePropertySet;
-class TimingFunction;
class KeyframeValue {
public:
@@ -47,7 +45,6 @@ public:
{
}
- void addProperties(const StylePropertySet*);
void addProperty(CSSPropertyID prop) { m_properties.add(prop); }
bool containsProperty(CSSPropertyID prop) const { return m_properties.contains(prop); }
const HashSet<CSSPropertyID>& properties() const { return m_properties; }
@@ -58,8 +55,6 @@ public:
const RenderStyle* style() const { return m_style.get(); }
void setStyle(PassRefPtr<RenderStyle> style) { m_style = style; }
- static TimingFunction* timingFunction(const RenderStyle& keyframeStyle);
-
private:
double m_key;
HashSet<CSSPropertyID> m_properties; // The properties specified in this keyframe.
@@ -71,8 +66,8 @@ public:
KeyframeList(RenderObject&, const AtomicString& animationName)
: m_animationName(animationName)
{
- insert(KeyframeValue(0, 0));
- insert(KeyframeValue(1, 0));
+ insert(KeyframeValue(0, nullptr));
+ insert(KeyframeValue(1, nullptr));
}
~KeyframeList();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/NinePieceImage.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/NinePieceImage.cpp
index 383ca14283a..12c050849b1 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/NinePieceImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/NinePieceImage.cpp
@@ -24,6 +24,8 @@
#include "config.h"
#include "core/rendering/style/NinePieceImage.h"
+#include "core/rendering/style/DataEquivalency.h"
+
namespace WebCore {
static DataRef<NinePieceImageData>& defaultData()
@@ -55,7 +57,7 @@ NinePieceImageData::NinePieceImageData()
: fill(false)
, horizontalRule(StretchImageRule)
, verticalRule(StretchImageRule)
- , image(0)
+ , image(nullptr)
, imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent))
, borderSlices(1.0, 1.0, 1.0, 1.0)
, outset(Length(0, Fixed), Length(0, Fixed), Length(0, Fixed), Length(0, Fixed))
@@ -76,7 +78,7 @@ NinePieceImageData::NinePieceImageData(const NinePieceImageData& other)
bool NinePieceImageData::operator==(const NinePieceImageData& other) const
{
- return StyleImage::imagesEquivalent(image.get(), other.image.get())
+ return dataEquivalent(image, other.image)
&& imageSlices == other.imageSlices
&& fill == other.fill
&& borderSlices == other.borderSlices
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/OutlineValue.h b/chromium/third_party/WebKit/Source/core/rendering/style/OutlineValue.h
index ccf3c272a01..e70b23229e6 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/OutlineValue.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/OutlineValue.h
@@ -39,7 +39,7 @@ public:
bool operator==(const OutlineValue& o) const
{
- return m_width == o.m_width && m_style == o.m_style && m_color == o.m_color && m_colorIsValid == o.m_colorIsValid && m_offset == o.m_offset && m_isAuto == o.m_isAuto;
+ return BorderValue::operator==(o) && m_offset == o.m_offset && m_isAuto == o.m_isAuto;
}
bool operator!=(const OutlineValue& o) const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.cpp
index a6ef8e9e120..5ec5c0c9374 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.cpp
@@ -64,13 +64,4 @@ const String QuotesData::getCloseQuote(int index) const
return m_quotePairs.at(index).second;
}
-bool QuotesData::equals(const QuotesData* a, const QuotesData* b)
-{
- if (a == b)
- return true;
- if (!a || !b)
- return false;
- return a->m_quotePairs == b->m_quotePairs;
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.h b/chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.h
index 94e89e37e10..f8db17b82b9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/QuotesData.h
@@ -35,8 +35,8 @@ public:
static PassRefPtr<QuotesData> create(const String open, const String close);
static PassRefPtr<QuotesData> create(UChar open1, UChar close1, UChar open2, UChar close2);
- // FIXME: this should be an operator==.
- static bool equals(const QuotesData*, const QuotesData*);
+ bool operator==(const QuotesData& o) const { return m_quotePairs == o.m_quotePairs; }
+ bool operator!=(const QuotesData& o) const { return !(*this == o); }
void addPair(const std::pair<String, String> quotePair);
const String getOpenQuote(int index) const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.cpp
index 2bbea394980..6b072146cfb 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.cpp
@@ -24,18 +24,20 @@
#include "core/rendering/style/RenderStyle.h"
#include <algorithm>
-#include "RuntimeEnabledFeatures.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/rendering/RenderTheme.h"
#include "core/rendering/TextAutosizer.h"
+#include "core/rendering/style/AppliedTextDecoration.h"
#include "core/rendering/style/ContentData.h"
-#include "core/rendering/style/CursorList.h"
#include "core/rendering/style/QuotesData.h"
#include "core/rendering/style/ShadowList.h"
#include "core/rendering/style/StyleImage.h"
#include "core/rendering/style/StyleInheritedData.h"
+#include "platform/LengthFunctions.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/fonts/Font.h"
#include "platform/fonts/FontSelector.h"
+#include "platform/geometry/FloatRoundedRect.h"
#include "wtf/MathExtras.h"
using namespace std;
@@ -124,6 +126,7 @@ ALWAYS_INLINE RenderStyle::RenderStyle(DefaultStyleTag)
rareNonInheritedData.access()->m_marquee.init();
rareNonInheritedData.access()->m_multiCol.init();
rareNonInheritedData.access()->m_transform.init();
+ rareNonInheritedData.access()->m_willChange.init();
rareNonInheritedData.access()->m_filter.init();
rareNonInheritedData.access()->m_grid.init();
rareNonInheritedData.access()->m_gridItem.init();
@@ -147,7 +150,7 @@ ALWAYS_INLINE RenderStyle::RenderStyle(const RenderStyle& o)
{
}
-static StyleRecalcChange comparePseudoStyles(const RenderStyle* oldStyle, const RenderStyle* newStyle)
+static StyleRecalcChange diffPseudoStyles(const RenderStyle* oldStyle, const RenderStyle* newStyle)
{
// If the pseudoStyles have changed, we want any StyleRecalcChange that is not NoChange
// because setStyle will do the right thing with anything else.
@@ -166,7 +169,7 @@ static StyleRecalcChange comparePseudoStyles(const RenderStyle* oldStyle, const
return NoChange;
}
-StyleRecalcChange RenderStyle::compare(const RenderStyle* oldStyle, const RenderStyle* newStyle)
+StyleRecalcChange RenderStyle::stylePropagationDiff(const RenderStyle* oldStyle, const RenderStyle* newStyle)
{
if ((!oldStyle && newStyle) || (oldStyle && !newStyle))
return Reattach;
@@ -177,15 +180,12 @@ StyleRecalcChange RenderStyle::compare(const RenderStyle* oldStyle, const Render
if (oldStyle->display() != newStyle->display()
|| oldStyle->hasPseudoStyle(FIRST_LETTER) != newStyle->hasPseudoStyle(FIRST_LETTER)
|| oldStyle->columnSpan() != newStyle->columnSpan()
- || oldStyle->specifiesAutoColumns() != newStyle->specifiesAutoColumns()
|| !oldStyle->contentDataEquivalent(newStyle)
- || oldStyle->hasTextCombine() != newStyle->hasTextCombine()
- || oldStyle->flowThread() != newStyle->flowThread()
- || oldStyle->regionThread() != newStyle->regionThread())
+ || oldStyle->hasTextCombine() != newStyle->hasTextCombine())
return Reattach;
if (*oldStyle == *newStyle)
- return comparePseudoStyles(oldStyle, newStyle);
+ return diffPseudoStyles(oldStyle, newStyle);
if (oldStyle->inheritedNotEqual(newStyle)
|| oldStyle->hasExplicitlyInheritedProperties()
@@ -233,6 +233,7 @@ void RenderStyle::copyNonInheritedFrom(const RenderStyle* other)
noninherited_flags._page_break_inside = other->noninherited_flags._page_break_inside;
noninherited_flags.explicitInheritance = other->noninherited_flags.explicitInheritance;
noninherited_flags.currentColor = other->noninherited_flags.currentColor;
+ noninherited_flags.hasViewportUnits = other->noninherited_flags.hasViewportUnits;
if (m_svgStyle != other->m_svgStyle)
m_svgStyle.access()->copyNonInheritedFrom(other->m_svgStyle.get());
ASSERT(zoom() == initialZoom());
@@ -336,7 +337,7 @@ bool RenderStyle::inheritedDataShared(const RenderStyle* other) const
&& rareInheritedData.get() == other->rareInheritedData.get();
}
-static bool positionedObjectMoved(const LengthBox& a, const LengthBox& b, const Length& width)
+static bool positionedObjectMovedOnly(const LengthBox& a, const LengthBox& b, const Length& width)
{
// If any unit types are different, then we can't guarantee
// that this was just a movement.
@@ -353,9 +354,11 @@ static bool positionedObjectMoved(const LengthBox& a, const LengthBox& b, const
return false;
if (!a.top().isIntrinsicOrAuto() && !a.bottom().isIntrinsicOrAuto())
return false;
- // If our width is auto and left or right is specified then this
+ // If our width is auto and left or right is specified and changed then this
// is not just a movement - we need to resize to our container.
- if ((!a.left().isIntrinsicOrAuto() || !a.right().isIntrinsicOrAuto()) && width.isIntrinsicOrAuto())
+ if (width.isIntrinsicOrAuto()
+ && ((!a.left().isIntrinsicOrAuto() && a.left() != b.left())
+ || (!a.right().isIntrinsicOrAuto() && a.right() != b.right())))
return false;
// One of the units is fixed or percent in both directions and stayed
@@ -363,328 +366,364 @@ static bool positionedObjectMoved(const LengthBox& a, const LengthBox& b, const
return true;
}
-StyleDifference RenderStyle::diff(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
+StyleDifference RenderStyle::visualInvalidationDiff(const RenderStyle& other, unsigned& changedContextSensitiveProperties) const
{
- changedContextSensitiveProperties = ContextSensitivePropertyNone;
+ // Note, we use .get() on each DataRef below because DataRef::operator== will do a deep
+ // compare, which is duplicate work when we're going to compare each property inside
+ // this function anyway.
- StyleDifference svgChange = StyleDifferenceEqual;
- if (m_svgStyle != other->m_svgStyle) {
- svgChange = m_svgStyle->diff(other->m_svgStyle.get());
- if (svgChange == StyleDifferenceLayout)
- return svgChange;
+ StyleDifference diff;
+ if (m_svgStyle.get() != other.m_svgStyle.get())
+ diff = m_svgStyle->diff(other.m_svgStyle.get());
+
+ if ((!diff.needsFullLayout() || !diff.needsRepaint()) && diffNeedsFullLayoutAndRepaint(other)) {
+ diff.setNeedsFullLayout();
+ diff.setNeedsRepaintObject();
+ }
+
+ if (!diff.needsFullLayout() && diffNeedsFullLayout(other))
+ diff.setNeedsFullLayout();
+
+ if (!diff.needsFullLayout() && position() != StaticPosition && surround->offset != other.surround->offset) {
+ // Optimize for the case where a positioned layer is moving but not changing size.
+ if ((position() == AbsolutePosition || position() == FixedPosition)
+ && positionedObjectMovedOnly(surround->offset, other.surround->offset, m_box->width())) {
+ diff.setNeedsPositionedMovementLayout();
+ } else {
+ // FIXME: We would like to use SimplifiedLayout for relative positioning, but we can't quite do that yet.
+ // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
+ // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
+ diff.setNeedsFullLayout();
+ }
+ }
+
+ if (diffNeedsRepaintLayer(other))
+ diff.setNeedsRepaintLayer();
+ else if (diffNeedsRepaintObject(other))
+ diff.setNeedsRepaintObject();
+
+ changedContextSensitiveProperties = computeChangedContextSensitiveProperties(other, diff);
+
+ if (diff.hasNoChange() && diffNeedsRecompositeLayer(other))
+ diff.setNeedsRecompositeLayer();
+
+ // Cursors are not checked, since they will be set appropriately in response to mouse events,
+ // so they don't need to cause any repaint or layout.
+
+ // Animations don't need to be checked either. We always set the new style on the RenderObject, so we will get a chance to fire off
+ // the resulting transition properly.
+
+ return diff;
+}
+
+bool RenderStyle::diffNeedsFullLayoutAndRepaint(const RenderStyle& other) const
+{
+ // FIXME: Not all cases in this method need both full layout and repaint.
+ // Should move cases into diffNeedsFullLayout() if
+ // - don't need repaint at all;
+ // - or the renderer knows how to exactly repaint caused by the layout change
+ // instead of forced full repaint.
+
+ if (m_box.get() != other.m_box.get()) {
+ if (m_box->width() != other.m_box->width()
+ || m_box->minWidth() != other.m_box->minWidth()
+ || m_box->maxWidth() != other.m_box->maxWidth()
+ || m_box->height() != other.m_box->height()
+ || m_box->minHeight() != other.m_box->minHeight()
+ || m_box->maxHeight() != other.m_box->maxHeight())
+ return true;
+
+ if (m_box->verticalAlign() != other.m_box->verticalAlign())
+ return true;
+
+ if (m_box->boxSizing() != other.m_box->boxSizing())
+ return true;
+ }
+
+ if (surround.get() != other.surround.get()) {
+ if (surround->margin != other.surround->margin)
+ return true;
+
+ if (surround->padding != other.surround->padding)
+ return true;
+
+ // If our border widths change, then we need to layout. Other changes to borders only necessitate a repaint.
+ if (borderLeftWidth() != other.borderLeftWidth()
+ || borderTopWidth() != other.borderTopWidth()
+ || borderBottomWidth() != other.borderBottomWidth()
+ || borderRightWidth() != other.borderRightWidth())
+ return true;
}
- if (m_box->width() != other->m_box->width()
- || m_box->minWidth() != other->m_box->minWidth()
- || m_box->maxWidth() != other->m_box->maxWidth()
- || m_box->height() != other->m_box->height()
- || m_box->minHeight() != other->m_box->minHeight()
- || m_box->maxHeight() != other->m_box->maxHeight())
- return StyleDifferenceLayout;
-
- if (m_box->verticalAlign() != other->m_box->verticalAlign() || noninherited_flags._vertical_align != other->noninherited_flags._vertical_align)
- return StyleDifferenceLayout;
-
- if (m_box->boxSizing() != other->m_box->boxSizing())
- return StyleDifferenceLayout;
-
- if (surround->margin != other->surround->margin)
- return StyleDifferenceLayout;
-
- if (surround->padding != other->surround->padding)
- return StyleDifferenceLayout;
-
- if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
- if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance
- || rareNonInheritedData->marginBeforeCollapse != other->rareNonInheritedData->marginBeforeCollapse
- || rareNonInheritedData->marginAfterCollapse != other->rareNonInheritedData->marginAfterCollapse
- || rareNonInheritedData->lineClamp != other->rareNonInheritedData->lineClamp
- || rareNonInheritedData->textOverflow != other->rareNonInheritedData->textOverflow)
- return StyleDifferenceLayout;
-
- if (rareNonInheritedData->m_regionFragment != other->rareNonInheritedData->m_regionFragment)
- return StyleDifferenceLayout;
-
- if (rareNonInheritedData->m_wrapFlow != other->rareNonInheritedData->m_wrapFlow
- || rareNonInheritedData->m_wrapThrough != other->rareNonInheritedData->m_wrapThrough
- || rareNonInheritedData->m_shapeMargin != other->rareNonInheritedData->m_shapeMargin
- || rareNonInheritedData->m_shapePadding != other->rareNonInheritedData->m_shapePadding)
- return StyleDifferenceLayout;
-
- if (rareNonInheritedData->m_deprecatedFlexibleBox.get() != other->rareNonInheritedData->m_deprecatedFlexibleBox.get()
- && *rareNonInheritedData->m_deprecatedFlexibleBox.get() != *other->rareNonInheritedData->m_deprecatedFlexibleBox.get())
- return StyleDifferenceLayout;
-
- if (rareNonInheritedData->m_flexibleBox.get() != other->rareNonInheritedData->m_flexibleBox.get()
- && *rareNonInheritedData->m_flexibleBox.get() != *other->rareNonInheritedData->m_flexibleBox.get())
- return StyleDifferenceLayout;
- if (rareNonInheritedData->m_order != other->rareNonInheritedData->m_order
- || rareNonInheritedData->m_alignContent != other->rareNonInheritedData->m_alignContent
- || rareNonInheritedData->m_alignItems != other->rareNonInheritedData->m_alignItems
- || rareNonInheritedData->m_alignSelf != other->rareNonInheritedData->m_alignSelf
- || rareNonInheritedData->m_justifyContent != other->rareNonInheritedData->m_justifyContent)
- return StyleDifferenceLayout;
+ if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
+ if (rareNonInheritedData->m_appearance != other.rareNonInheritedData->m_appearance
+ || rareNonInheritedData->marginBeforeCollapse != other.rareNonInheritedData->marginBeforeCollapse
+ || rareNonInheritedData->marginAfterCollapse != other.rareNonInheritedData->marginAfterCollapse
+ || rareNonInheritedData->lineClamp != other.rareNonInheritedData->lineClamp
+ || rareNonInheritedData->textOverflow != other.rareNonInheritedData->textOverflow
+ || rareNonInheritedData->m_wrapFlow != other.rareNonInheritedData->m_wrapFlow
+ || rareNonInheritedData->m_wrapThrough != other.rareNonInheritedData->m_wrapThrough
+ || rareNonInheritedData->m_shapeMargin != other.rareNonInheritedData->m_shapeMargin
+ || rareNonInheritedData->m_order != other.rareNonInheritedData->m_order
+ || rareNonInheritedData->m_alignContent != other.rareNonInheritedData->m_alignContent
+ || rareNonInheritedData->m_alignItems != other.rareNonInheritedData->m_alignItems
+ || rareNonInheritedData->m_alignSelf != other.rareNonInheritedData->m_alignSelf
+ || rareNonInheritedData->m_justifyContent != other.rareNonInheritedData->m_justifyContent
+ || rareNonInheritedData->m_grid.get() != other.rareNonInheritedData->m_grid.get()
+ || rareNonInheritedData->m_gridItem.get() != other.rareNonInheritedData->m_gridItem.get()
+ || rareNonInheritedData->m_textCombine != other.rareNonInheritedData->m_textCombine
+ || rareNonInheritedData->hasFilters() != other.rareNonInheritedData->hasFilters())
+ return true;
+
+ if (rareNonInheritedData->m_deprecatedFlexibleBox.get() != other.rareNonInheritedData->m_deprecatedFlexibleBox.get()
+ && *rareNonInheritedData->m_deprecatedFlexibleBox.get() != *other.rareNonInheritedData->m_deprecatedFlexibleBox.get())
+ return true;
+
+ if (rareNonInheritedData->m_flexibleBox.get() != other.rareNonInheritedData->m_flexibleBox.get()
+ && *rareNonInheritedData->m_flexibleBox.get() != *other.rareNonInheritedData->m_flexibleBox.get())
+ return true;
// FIXME: We should add an optimized form of layout that just recomputes visual overflow.
- if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
- return StyleDifferenceLayout;
+ if (!rareNonInheritedData->shadowDataEquivalent(*other.rareNonInheritedData.get()))
+ return true;
+
+ if (!rareNonInheritedData->reflectionDataEquivalent(*other.rareNonInheritedData.get()))
+ return true;
- if (!rareNonInheritedData->reflectionDataEquivalent(*other->rareNonInheritedData.get()))
- return StyleDifferenceLayout;
+ if (rareNonInheritedData->m_multiCol.get() != other.rareNonInheritedData->m_multiCol.get()
+ && *rareNonInheritedData->m_multiCol.get() != *other.rareNonInheritedData->m_multiCol.get())
+ return true;
- if (rareNonInheritedData->m_multiCol.get() != other->rareNonInheritedData->m_multiCol.get()
- && *rareNonInheritedData->m_multiCol.get() != *other->rareNonInheritedData->m_multiCol.get())
- return StyleDifferenceLayout;
+ // If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
+ const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives.get();
+ const CounterDirectiveMap* mapB = other.rareNonInheritedData->m_counterDirectives.get();
+ if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
+ return true;
- if (rareNonInheritedData->m_transform.get() != other->rareNonInheritedData->m_transform.get()
- && *rareNonInheritedData->m_transform.get() != *other->rareNonInheritedData->m_transform.get()) {
- // Don't return early here; instead take note of the type of
- // change, and deal with it when looking at compositing.
- changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
+ // We only need do layout for opacity changes if adding or losing opacity could trigger a change
+ // in us being a stacking context.
+ if (hasAutoZIndex() != other.hasAutoZIndex() && rareNonInheritedData->hasOpacity() != other.rareNonInheritedData->hasOpacity()) {
+ // FIXME: We would like to use SimplifiedLayout here, but we can't quite do that yet.
+ // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
+ // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
+ // In addition we need to solve the floating object issue when layers come and go. Right now
+ // a full layout is necessary to keep floating object lists sane.
+ return true;
}
+ }
- if (rareNonInheritedData->m_grid.get() != other->rareNonInheritedData->m_grid.get()
- || rareNonInheritedData->m_gridItem.get() != other->rareNonInheritedData->m_gridItem.get())
- return StyleDifferenceLayout;
+ if (rareInheritedData.get() != other.rareInheritedData.get()) {
+ if (rareInheritedData->highlight != other.rareInheritedData->highlight
+ || rareInheritedData->indent != other.rareInheritedData->indent
+ || rareInheritedData->m_textAlignLast != other.rareInheritedData->m_textAlignLast
+ || rareInheritedData->m_textIndentLine != other.rareInheritedData->m_textIndentLine
+ || rareInheritedData->m_effectiveZoom != other.rareInheritedData->m_effectiveZoom
+ || rareInheritedData->wordBreak != other.rareInheritedData->wordBreak
+ || rareInheritedData->overflowWrap != other.rareInheritedData->overflowWrap
+ || rareInheritedData->lineBreak != other.rareInheritedData->lineBreak
+ || rareInheritedData->textSecurity != other.rareInheritedData->textSecurity
+ || rareInheritedData->hyphens != other.rareInheritedData->hyphens
+ || rareInheritedData->hyphenationLimitBefore != other.rareInheritedData->hyphenationLimitBefore
+ || rareInheritedData->hyphenationLimitAfter != other.rareInheritedData->hyphenationLimitAfter
+ || rareInheritedData->hyphenationString != other.rareInheritedData->hyphenationString
+ || rareInheritedData->locale != other.rareInheritedData->locale
+ || rareInheritedData->m_rubyPosition != other.rareInheritedData->m_rubyPosition
+ || rareInheritedData->textEmphasisMark != other.rareInheritedData->textEmphasisMark
+ || rareInheritedData->textEmphasisPosition != other.rareInheritedData->textEmphasisPosition
+ || rareInheritedData->textEmphasisCustomMark != other.rareInheritedData->textEmphasisCustomMark
+ || rareInheritedData->m_textJustify != other.rareInheritedData->m_textJustify
+ || rareInheritedData->m_textOrientation != other.rareInheritedData->m_textOrientation
+ || rareInheritedData->m_tabSize != other.rareInheritedData->m_tabSize
+ || rareInheritedData->m_lineBoxContain != other.rareInheritedData->m_lineBoxContain
+ || rareInheritedData->listStyleImage != other.rareInheritedData->listStyleImage
+ || rareInheritedData->textStrokeWidth != other.rareInheritedData->textStrokeWidth)
+ return true;
- if (rareNonInheritedData->m_shapeInside != other->rareNonInheritedData->m_shapeInside)
- return StyleDifferenceLayout;
- }
+ if (!rareInheritedData->shadowDataEquivalent(*other.rareInheritedData.get()))
+ return true;
- if (rareInheritedData.get() != other->rareInheritedData.get()) {
- if (rareInheritedData->highlight != other->rareInheritedData->highlight
- || rareInheritedData->indent != other->rareInheritedData->indent
- || rareInheritedData->m_textAlignLast != other->rareInheritedData->m_textAlignLast
- || rareInheritedData->m_textIndentLine != other->rareInheritedData->m_textIndentLine
- || rareInheritedData->m_effectiveZoom != other->rareInheritedData->m_effectiveZoom
- || rareInheritedData->wordBreak != other->rareInheritedData->wordBreak
- || rareInheritedData->overflowWrap != other->rareInheritedData->overflowWrap
- || rareInheritedData->lineBreak != other->rareInheritedData->lineBreak
- || rareInheritedData->textSecurity != other->rareInheritedData->textSecurity
- || rareInheritedData->hyphens != other->rareInheritedData->hyphens
- || rareInheritedData->hyphenationLimitBefore != other->rareInheritedData->hyphenationLimitBefore
- || rareInheritedData->hyphenationLimitAfter != other->rareInheritedData->hyphenationLimitAfter
- || rareInheritedData->hyphenationString != other->rareInheritedData->hyphenationString
- || rareInheritedData->locale != other->rareInheritedData->locale
- || rareInheritedData->m_rubyPosition != other->rareInheritedData->m_rubyPosition
- || rareInheritedData->textEmphasisMark != other->rareInheritedData->textEmphasisMark
- || rareInheritedData->textEmphasisPosition != other->rareInheritedData->textEmphasisPosition
- || rareInheritedData->textEmphasisCustomMark != other->rareInheritedData->textEmphasisCustomMark
- || rareInheritedData->m_textAlignLast != other->rareInheritedData->m_textAlignLast
- || rareInheritedData->m_textJustify != other->rareInheritedData->m_textJustify
- || rareInheritedData->m_textOrientation != other->rareInheritedData->m_textOrientation
- || rareInheritedData->m_tabSize != other->rareInheritedData->m_tabSize
- || rareInheritedData->m_lineBoxContain != other->rareInheritedData->m_lineBoxContain
- || rareInheritedData->m_lineGrid != other->rareInheritedData->m_lineGrid
- || rareInheritedData->m_lineSnap != other->rareInheritedData->m_lineSnap
- || rareInheritedData->m_lineAlign != other->rareInheritedData->m_lineAlign
- || rareInheritedData->listStyleImage != other->rareInheritedData->listStyleImage)
- return StyleDifferenceLayout;
-
- if (!rareInheritedData->shadowDataEquivalent(*other->rareInheritedData.get()))
- return StyleDifferenceLayout;
-
- if (textStrokeWidth() != other->textStrokeWidth())
- return StyleDifferenceLayout;
+ if (!rareInheritedData->quotesDataEquivalent(*other.rareInheritedData.get()))
+ return true;
}
- if (visual->m_textAutosizingMultiplier != other->visual->m_textAutosizingMultiplier)
- return StyleDifferenceLayout;
+ if (inherited->textAutosizingMultiplier != other.inherited->textAutosizingMultiplier)
+ return true;
- if (inherited->line_height != other->inherited->line_height
- || inherited->font != other->inherited->font
- || inherited->horizontal_border_spacing != other->inherited->horizontal_border_spacing
- || inherited->vertical_border_spacing != other->inherited->vertical_border_spacing
- || inherited_flags._box_direction != other->inherited_flags._box_direction
- || inherited_flags.m_rtlOrdering != other->inherited_flags.m_rtlOrdering
- || noninherited_flags._position != other->noninherited_flags._position
- || noninherited_flags._floating != other->noninherited_flags._floating
- || noninherited_flags._originalDisplay != other->noninherited_flags._originalDisplay)
- return StyleDifferenceLayout;
+ if (inherited.get() != other.inherited.get()) {
+ if (inherited->line_height != other.inherited->line_height
+ || inherited->font != other.inherited->font
+ || inherited->horizontal_border_spacing != other.inherited->horizontal_border_spacing
+ || inherited->vertical_border_spacing != other.inherited->vertical_border_spacing)
+ return true;
+ }
+ if (inherited_flags._box_direction != other.inherited_flags._box_direction
+ || inherited_flags.m_rtlOrdering != other.inherited_flags.m_rtlOrdering
+ || inherited_flags._text_align != other.inherited_flags._text_align
+ || inherited_flags._text_transform != other.inherited_flags._text_transform
+ || inherited_flags._direction != other.inherited_flags._direction
+ || inherited_flags._white_space != other.inherited_flags._white_space
+ || inherited_flags.m_writingMode != other.inherited_flags.m_writingMode)
+ return true;
- if (((int)noninherited_flags._effectiveDisplay) >= TABLE) {
- if (inherited_flags._border_collapse != other->inherited_flags._border_collapse
- || inherited_flags._empty_cells != other->inherited_flags._empty_cells
- || inherited_flags._caption_side != other->inherited_flags._caption_side
- || noninherited_flags._table_layout != other->noninherited_flags._table_layout)
- return StyleDifferenceLayout;
+ if (noninherited_flags._overflowX != other.noninherited_flags._overflowX
+ || noninherited_flags._overflowY != other.noninherited_flags._overflowY
+ || noninherited_flags._clear != other.noninherited_flags._clear
+ || noninherited_flags._unicodeBidi != other.noninherited_flags._unicodeBidi
+ || noninherited_flags._position != other.noninherited_flags._position
+ || noninherited_flags._floating != other.noninherited_flags._floating
+ || noninherited_flags._originalDisplay != other.noninherited_flags._originalDisplay
+ || noninherited_flags._vertical_align != other.noninherited_flags._vertical_align)
+ return true;
+
+ if (noninherited_flags._effectiveDisplay >= FIRST_TABLE_DISPLAY && noninherited_flags._effectiveDisplay <= LAST_TABLE_DISPLAY) {
+ if (inherited_flags._border_collapse != other.inherited_flags._border_collapse
+ || inherited_flags._empty_cells != other.inherited_flags._empty_cells
+ || inherited_flags._caption_side != other.inherited_flags._caption_side
+ || noninherited_flags._table_layout != other.noninherited_flags._table_layout)
+ return true;
// In the collapsing border model, 'hidden' suppresses other borders, while 'none'
// does not, so these style differences can be width differences.
if (inherited_flags._border_collapse
- && ((borderTopStyle() == BHIDDEN && other->borderTopStyle() == BNONE)
- || (borderTopStyle() == BNONE && other->borderTopStyle() == BHIDDEN)
- || (borderBottomStyle() == BHIDDEN && other->borderBottomStyle() == BNONE)
- || (borderBottomStyle() == BNONE && other->borderBottomStyle() == BHIDDEN)
- || (borderLeftStyle() == BHIDDEN && other->borderLeftStyle() == BNONE)
- || (borderLeftStyle() == BNONE && other->borderLeftStyle() == BHIDDEN)
- || (borderRightStyle() == BHIDDEN && other->borderRightStyle() == BNONE)
- || (borderRightStyle() == BNONE && other->borderRightStyle() == BHIDDEN)))
- return StyleDifferenceLayout;
+ && ((borderTopStyle() == BHIDDEN && other.borderTopStyle() == BNONE)
+ || (borderTopStyle() == BNONE && other.borderTopStyle() == BHIDDEN)
+ || (borderBottomStyle() == BHIDDEN && other.borderBottomStyle() == BNONE)
+ || (borderBottomStyle() == BNONE && other.borderBottomStyle() == BHIDDEN)
+ || (borderLeftStyle() == BHIDDEN && other.borderLeftStyle() == BNONE)
+ || (borderLeftStyle() == BNONE && other.borderLeftStyle() == BHIDDEN)
+ || (borderRightStyle() == BHIDDEN && other.borderRightStyle() == BNONE)
+ || (borderRightStyle() == BNONE && other.borderRightStyle() == BHIDDEN)))
+ return true;
+ } else if (noninherited_flags._effectiveDisplay == LIST_ITEM) {
+ if (inherited_flags._list_style_type != other.inherited_flags._list_style_type
+ || inherited_flags._list_style_position != other.inherited_flags._list_style_position)
+ return true;
}
- if (noninherited_flags._effectiveDisplay == LIST_ITEM) {
- if (inherited_flags._list_style_type != other->inherited_flags._list_style_type
- || inherited_flags._list_style_position != other->inherited_flags._list_style_position)
- return StyleDifferenceLayout;
- }
+ if ((visibility() == COLLAPSE) != (other.visibility() == COLLAPSE))
+ return true;
- if (inherited_flags._text_align != other->inherited_flags._text_align
- || inherited_flags._text_transform != other->inherited_flags._text_transform
- || inherited_flags._direction != other->inherited_flags._direction
- || inherited_flags._white_space != other->inherited_flags._white_space
- || noninherited_flags._clear != other->noninherited_flags._clear
- || noninherited_flags._unicodeBidi != other->noninherited_flags._unicodeBidi)
- return StyleDifferenceLayout;
-
- // Check block flow direction.
- if (inherited_flags.m_writingMode != other->inherited_flags.m_writingMode)
- return StyleDifferenceLayout;
-
- // Check text combine mode.
- if (rareNonInheritedData->m_textCombine != other->rareNonInheritedData->m_textCombine)
- return StyleDifferenceLayout;
-
- // Overflow returns a layout hint.
- if (noninherited_flags._overflowX != other->noninherited_flags._overflowX
- || noninherited_flags._overflowY != other->noninherited_flags._overflowY)
- return StyleDifferenceLayout;
-
- // If our border widths change, then we need to layout. Other changes to borders
- // only necessitate a repaint.
- if (borderLeftWidth() != other->borderLeftWidth()
- || borderTopWidth() != other->borderTopWidth()
- || borderBottomWidth() != other->borderBottomWidth()
- || borderRightWidth() != other->borderRightWidth())
- return StyleDifferenceLayout;
-
- // If the counter directives change, trigger a relayout to re-calculate counter values and rebuild the counter node tree.
- const CounterDirectiveMap* mapA = rareNonInheritedData->m_counterDirectives.get();
- const CounterDirectiveMap* mapB = other->rareNonInheritedData->m_counterDirectives.get();
- if (!(mapA == mapB || (mapA && mapB && *mapA == *mapB)))
- return StyleDifferenceLayout;
-
- if ((visibility() == COLLAPSE) != (other->visibility() == COLLAPSE))
- return StyleDifferenceLayout;
-
- if (rareNonInheritedData->hasOpacity() != other->rareNonInheritedData->hasOpacity()) {
- // FIXME: We would like to use SimplifiedLayout here, but we can't quite do that yet.
- // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
- // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
- // In addition we need to solve the floating object issue when layers come and go. Right now
- // a full layout is necessary to keep floating object lists sane.
- return StyleDifferenceLayout;
+ if (!m_background->outline().visuallyEqual(other.m_background->outline())) {
+ // FIXME: We only really need to recompute the overflow but we don't have an optimized layout for it.
+ return true;
}
- if (rareNonInheritedData->hasFilters() != other->rareNonInheritedData->hasFilters())
- return StyleDifferenceLayout;
+ // Movement of non-static-positioned object is special cased in RenderStyle::visualInvalidationDiff().
- if (!QuotesData::equals(rareInheritedData->quotes.get(), other->rareInheritedData->quotes.get()))
- return StyleDifferenceLayout;
+ return false;
+}
+
+bool RenderStyle::diffNeedsFullLayout(const RenderStyle& other) const
+{
+ return false;
+}
- // SVGRenderStyle::diff() might have returned StyleDifferenceRepaint, eg. if fill changes.
- // If eg. the font-size changed at the same time, we're not allowed to return StyleDifferenceRepaint,
- // but have to return StyleDifferenceLayout, that's why this if branch comes after all branches
- // that are relevant for SVG and might return StyleDifferenceLayout.
- if (svgChange != StyleDifferenceEqual)
- return svgChange;
+bool RenderStyle::diffNeedsRepaintLayer(const RenderStyle& other) const
+{
+ if (position() != StaticPosition && (visual->clip != other.visual->clip || visual->hasClip != other.visual->hasClip))
+ return true;
- // Make sure these left/top/right/bottom checks stay below all layout checks and above
- // all visible checks.
- if (position() != StaticPosition && surround->offset != other->surround->offset) {
- // Optimize for the case where a positioned layer is moving but not changing size.
- if (position() == AbsolutePosition && positionedObjectMoved(surround->offset, other->surround->offset, m_box->width()) && repaintOnlyDiff(other, changedContextSensitiveProperties) == StyleDifferenceEqual)
- return StyleDifferenceLayoutPositionedMovementOnly;
+ if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
+ if (RuntimeEnabledFeatures::cssCompositingEnabled()
+ && (rareNonInheritedData->m_effectiveBlendMode != other.rareNonInheritedData->m_effectiveBlendMode
+ || rareNonInheritedData->m_isolation != other.rareNonInheritedData->m_isolation))
+ return true;
- // FIXME: We would like to use SimplifiedLayout for relative positioning, but we can't quite do that yet.
- // We need to make sure SimplifiedLayout can operate correctly on RenderInlines (we will need
- // to add a selfNeedsSimplifiedLayout bit in order to not get confused and taint every line).
- return StyleDifferenceLayout;
+ if (rareNonInheritedData->m_mask != other.rareNonInheritedData->m_mask
+ || rareNonInheritedData->m_maskBoxImage != other.rareNonInheritedData->m_maskBoxImage)
+ return true;
}
- return repaintOnlyDiff(other, changedContextSensitiveProperties);
+
+ return false;
}
-StyleDifference RenderStyle::repaintOnlyDiff(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
+bool RenderStyle::diffNeedsRepaintObject(const RenderStyle& other) const
{
- if (position() != StaticPosition && (m_box->zIndex() != other->m_box->zIndex() || m_box->hasAutoZIndex() != other->m_box->hasAutoZIndex()
- || visual->clip != other->visual->clip || visual->hasClip != other->visual->hasClip))
- return StyleDifferenceRepaintLayer;
-
- if (RuntimeEnabledFeatures::cssCompositingEnabled() && rareNonInheritedData->m_effectiveBlendMode != other->rareNonInheritedData->m_effectiveBlendMode)
- return StyleDifferenceRepaintLayer;
+ if (inherited_flags._visibility != other.inherited_flags._visibility
+ || inherited_flags.m_printColorAdjust != other.inherited_flags.m_printColorAdjust
+ || inherited_flags._insideLink != other.inherited_flags._insideLink
+ || !surround->border.visuallyEqual(other.surround->border)
+ || !m_background->visuallyEqual(*other.m_background))
+ return true;
- if (rareNonInheritedData->opacity != other->rareNonInheritedData->opacity) {
- // Don't return early here; instead take note of the type of change,
- // and deal with it when looking at compositing.
- changedContextSensitiveProperties |= ContextSensitivePropertyOpacity;
+ if (rareInheritedData.get() != other.rareInheritedData.get()) {
+ if (rareInheritedData->userModify != other.rareInheritedData->userModify
+ || rareInheritedData->userSelect != other.rareInheritedData->userSelect
+ || rareInheritedData->m_imageRendering != other.rareInheritedData->m_imageRendering)
+ return true;
}
- if (rareNonInheritedData->m_filter.get() != other->rareNonInheritedData->m_filter.get()
- && *rareNonInheritedData->m_filter.get() != *other->rareNonInheritedData->m_filter.get()) {
- // Don't return early here; instead take note of the type of change,
- // and deal with it when looking at compositing.
- changedContextSensitiveProperties |= ContextSensitivePropertyFilter;
+ if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
+ if (rareNonInheritedData->userDrag != other.rareNonInheritedData->userDrag
+ || rareNonInheritedData->m_borderFit != other.rareNonInheritedData->m_borderFit
+ || rareNonInheritedData->m_objectFit != other.rareNonInheritedData->m_objectFit
+ || rareNonInheritedData->m_objectPosition != other.rareNonInheritedData->m_objectPosition
+ || rareNonInheritedData->m_shapeOutside != other.rareNonInheritedData->m_shapeOutside
+ || rareNonInheritedData->m_clipPath != other.rareNonInheritedData->m_clipPath)
+ return true;
}
- if (rareNonInheritedData->m_mask != other->rareNonInheritedData->m_mask
- || rareNonInheritedData->m_maskBoxImage != other->rareNonInheritedData->m_maskBoxImage)
- return StyleDifferenceRepaintLayer;
-
- if (inherited_flags._visibility != other->inherited_flags._visibility
- || inherited_flags.m_printColorAdjust != other->inherited_flags.m_printColorAdjust
- || inherited_flags._insideLink != other->inherited_flags._insideLink
- || surround->border != other->surround->border
- || *m_background.get() != *other->m_background.get()
- || rareInheritedData->userModify != other->rareInheritedData->userModify
- || rareInheritedData->userSelect != other->rareInheritedData->userSelect
- || rareNonInheritedData->userDrag != other->rareNonInheritedData->userDrag
- || rareNonInheritedData->m_borderFit != other->rareNonInheritedData->m_borderFit
- || rareNonInheritedData->m_objectFit != other->rareNonInheritedData->m_objectFit
- || rareNonInheritedData->m_objectPosition != other->rareNonInheritedData->m_objectPosition
- || rareInheritedData->m_imageRendering != other->rareInheritedData->m_imageRendering)
- return StyleDifferenceRepaint;
-
- // FIXME: The current spec is being reworked to remove dependencies between exclusions and affected
- // content. There's a proposal to use floats instead. In that case, wrap-shape should actually relayout
- // the parent container. For sure, I will have to revisit this code, but for now I've added this in order
- // to avoid having diff() == StyleDifferenceEqual where wrap-shapes actually differ.
- // Tracking bug: https://bugs.webkit.org/show_bug.cgi?id=62991
- if (rareNonInheritedData->m_shapeOutside != other->rareNonInheritedData->m_shapeOutside)
- return StyleDifferenceRepaint;
-
- if (rareNonInheritedData->m_clipPath != other->rareNonInheritedData->m_clipPath)
- return StyleDifferenceRepaint;
-
- if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
- if (rareNonInheritedData->m_transformStyle3D != other->rareNonInheritedData->m_transformStyle3D
- || rareNonInheritedData->m_backfaceVisibility != other->rareNonInheritedData->m_backfaceVisibility
- || rareNonInheritedData->m_perspective != other->rareNonInheritedData->m_perspective
- || rareNonInheritedData->m_perspectiveOriginX != other->rareNonInheritedData->m_perspectiveOriginX
- || rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY)
- return StyleDifferenceRecompositeLayer;
+ return false;
+}
+
+bool RenderStyle::diffNeedsRecompositeLayer(const RenderStyle& other) const
+{
+ if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
+ if (rareNonInheritedData->m_transformStyle3D != other.rareNonInheritedData->m_transformStyle3D
+ || rareNonInheritedData->m_backfaceVisibility != other.rareNonInheritedData->m_backfaceVisibility
+ || rareNonInheritedData->m_perspective != other.rareNonInheritedData->m_perspective
+ || rareNonInheritedData->m_perspectiveOriginX != other.rareNonInheritedData->m_perspectiveOriginX
+ || rareNonInheritedData->m_perspectiveOriginY != other.rareNonInheritedData->m_perspectiveOriginY
+ || hasWillChangeCompositingHint() != other.hasWillChangeCompositingHint())
+ return true;
}
- if (inherited->color != other->inherited->color
- || inherited_flags._text_decorations != other->inherited_flags._text_decorations
- || visual->textDecoration != other->visual->textDecoration
- || rareNonInheritedData->m_textDecorationStyle != other->rareNonInheritedData->m_textDecorationStyle
- || rareNonInheritedData->m_textDecorationColor != other->rareNonInheritedData->m_textDecorationColor
- || rareInheritedData->textFillColor != other->rareInheritedData->textFillColor
- || rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor
- || rareInheritedData->textEmphasisColor != other->rareInheritedData->textEmphasisColor
- || rareInheritedData->textEmphasisFill != other->rareInheritedData->textEmphasisFill)
- return StyleDifferenceRepaintIfTextOrColorChange;
+ return false;
+}
- // Cursors are not checked, since they will be set appropriately in response to mouse events,
- // so they don't need to cause any repaint or layout.
+unsigned RenderStyle::computeChangedContextSensitiveProperties(const RenderStyle& other, StyleDifference diff) const
+{
+ unsigned changedContextSensitiveProperties = ContextSensitivePropertyNone;
- // Animations don't need to be checked either. We always set the new style on the RenderObject, so we will get a chance to fire off
- // the resulting transition properly.
- return StyleDifferenceEqual;
+ // StyleAdjuster has ensured that zIndex is non-auto only if it's applicable.
+ if (m_box->zIndex() != other.m_box->zIndex() || m_box->hasAutoZIndex() != other.m_box->hasAutoZIndex())
+ changedContextSensitiveProperties |= ContextSensitivePropertyZIndex;
+
+ if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
+ if (!transformDataEquivalent(other))
+ changedContextSensitiveProperties |= ContextSensitivePropertyTransform;
+
+ if (rareNonInheritedData->opacity != other.rareNonInheritedData->opacity)
+ changedContextSensitiveProperties |= ContextSensitivePropertyOpacity;
+
+ if (rareNonInheritedData->m_filter != other.rareNonInheritedData->m_filter)
+ changedContextSensitiveProperties |= ContextSensitivePropertyFilter;
+ }
+
+ if (!diff.needsRepaint()) {
+ if (inherited->color != other.inherited->color
+ || inherited_flags.m_textUnderline != other.inherited_flags.m_textUnderline
+ || visual->textDecoration != other.visual->textDecoration) {
+ changedContextSensitiveProperties |= ContextSensitivePropertyTextOrColor;
+ } else if (rareNonInheritedData.get() != other.rareNonInheritedData.get()) {
+ if (rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_textDecorationStyle
+ || rareNonInheritedData->m_textDecorationColor != other.rareNonInheritedData->m_textDecorationColor)
+ changedContextSensitiveProperties |= ContextSensitivePropertyTextOrColor;
+ } else if (rareInheritedData.get() != other.rareInheritedData.get()) {
+ if (rareInheritedData->textFillColor() != other.rareInheritedData->textFillColor()
+ || rareInheritedData->textStrokeColor() != other.rareInheritedData->textStrokeColor()
+ || rareInheritedData->textEmphasisColor() != other.rareInheritedData->textEmphasisColor()
+ || rareInheritedData->textEmphasisFill != other.rareInheritedData->textEmphasisFill
+ || rareInheritedData->appliedTextDecorations != other.rareInheritedData->appliedTextDecorations)
+ changedContextSensitiveProperties |= ContextSensitivePropertyTextOrColor;
+ }
+ }
+
+ return changedContextSensitiveProperties;
}
-void RenderStyle::setClip(Length top, Length right, Length bottom, Length left)
+void RenderStyle::setClip(const Length& top, const Length& right, const Length& bottom, const Length& left)
{
StyleVisualData* data = visual.access();
data->clip.m_top = top;
@@ -707,15 +746,13 @@ void RenderStyle::setCursorList(PassRefPtr<CursorList> other)
void RenderStyle::setQuotes(PassRefPtr<QuotesData> q)
{
- if (QuotesData::equals(rareInheritedData->quotes.get(), q.get()))
- return;
rareInheritedData.access()->quotes = q;
}
void RenderStyle::clearCursorList()
{
if (rareInheritedData->cursorData)
- rareInheritedData.access()->cursorData = 0;
+ rareInheritedData.access()->cursorData = nullptr;
}
void RenderStyle::addCallbackSelector(const String& selector)
@@ -842,6 +879,25 @@ bool RenderStyle::hasIsolation() const
return false;
}
+bool RenderStyle::hasWillChangeCompositingHint() const
+{
+ for (size_t i = 0; i < rareNonInheritedData->m_willChange->m_properties.size(); ++i) {
+ switch (rareNonInheritedData->m_willChange->m_properties[i]) {
+ case CSSPropertyOpacity:
+ case CSSPropertyTransform:
+ case CSSPropertyWebkitTransform:
+ case CSSPropertyTop:
+ case CSSPropertyLeft:
+ case CSSPropertyBottom:
+ case CSSPropertyRight:
+ return true;
+ default:
+ break;
+ }
+ }
+ return false;
+}
+
inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation> >& transformOperations, RenderStyle::ApplyTransformOrigin applyOrigin)
{
// transform-origin brackets the transform with translate operations.
@@ -878,8 +934,8 @@ void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRec
float offsetY = transformOriginY().type() == Percent ? boundingBox.y() : 0;
if (applyTransformOrigin) {
- transform.translate3d(floatValueForLength(transformOriginX(), boundingBox.width(), 0) + offsetX,
- floatValueForLength(transformOriginY(), boundingBox.height(), 0) + offsetY,
+ transform.translate3d(floatValueForLength(transformOriginX(), boundingBox.width()) + offsetX,
+ floatValueForLength(transformOriginY(), boundingBox.height()) + offsetY,
transformOriginZ());
}
@@ -888,8 +944,8 @@ void RenderStyle::applyTransform(TransformationMatrix& transform, const FloatRec
transformOperations[i]->apply(transform, boundingBox.size());
if (applyTransformOrigin) {
- transform.translate3d(-floatValueForLength(transformOriginX(), boundingBox.width(), 0) - offsetX,
- -floatValueForLength(transformOriginY(), boundingBox.height(), 0) - offsetY,
+ transform.translate3d(-floatValueForLength(transformOriginX(), boundingBox.width()) - offsetX,
+ -floatValueForLength(transformOriginY(), boundingBox.height()) - offsetY,
-transformOriginZ());
}
}
@@ -904,49 +960,17 @@ void RenderStyle::setBoxShadow(PassRefPtr<ShadowList> s)
rareNonInheritedData.access()->m_boxShadow = s;
}
-static RoundedRect::Radii calcRadiiFor(const BorderData& border, IntSize size, RenderView* renderView)
+static RoundedRect::Radii calcRadiiFor(const BorderData& border, IntSize size)
{
return RoundedRect::Radii(
- IntSize(valueForLength(border.topLeft().width(), size.width(), renderView),
- valueForLength(border.topLeft().height(), size.height(), renderView)),
- IntSize(valueForLength(border.topRight().width(), size.width(), renderView),
- valueForLength(border.topRight().height(), size.height(), renderView)),
- IntSize(valueForLength(border.bottomLeft().width(), size.width(), renderView),
- valueForLength(border.bottomLeft().height(), size.height(), renderView)),
- IntSize(valueForLength(border.bottomRight().width(), size.width(), renderView),
- valueForLength(border.bottomRight().height(), size.height(), renderView)));
-}
-
-static float calcConstraintScaleFor(const IntRect& rect, const RoundedRect::Radii& radii)
-{
- // Constrain corner radii using CSS3 rules:
- // http://www.w3.org/TR/css3-background/#the-border-radius
-
- float factor = 1;
- unsigned radiiSum;
-
- // top
- radiiSum = static_cast<unsigned>(radii.topLeft().width()) + static_cast<unsigned>(radii.topRight().width()); // Casts to avoid integer overflow.
- if (radiiSum > static_cast<unsigned>(rect.width()))
- factor = min(static_cast<float>(rect.width()) / radiiSum, factor);
-
- // bottom
- radiiSum = static_cast<unsigned>(radii.bottomLeft().width()) + static_cast<unsigned>(radii.bottomRight().width());
- if (radiiSum > static_cast<unsigned>(rect.width()))
- factor = min(static_cast<float>(rect.width()) / radiiSum, factor);
-
- // left
- radiiSum = static_cast<unsigned>(radii.topLeft().height()) + static_cast<unsigned>(radii.bottomLeft().height());
- if (radiiSum > static_cast<unsigned>(rect.height()))
- factor = min(static_cast<float>(rect.height()) / radiiSum, factor);
-
- // right
- radiiSum = static_cast<unsigned>(radii.topRight().height()) + static_cast<unsigned>(radii.bottomRight().height());
- if (radiiSum > static_cast<unsigned>(rect.height()))
- factor = min(static_cast<float>(rect.height()) / radiiSum, factor);
-
- ASSERT(factor <= 1);
- return factor;
+ IntSize(valueForLength(border.topLeft().width(), size.width()),
+ valueForLength(border.topLeft().height(), size.height())),
+ IntSize(valueForLength(border.topRight().width(), size.width()),
+ valueForLength(border.topRight().height(), size.height())),
+ IntSize(valueForLength(border.bottomLeft().width(), size.width()),
+ valueForLength(border.bottomLeft().height(), size.height())),
+ IntSize(valueForLength(border.bottomRight().width(), size.width()),
+ valueForLength(border.bottomRight().height(), size.height())));
}
StyleImage* RenderStyle::listStyleImage() const { return rareInheritedData->listStyleImage.get(); }
@@ -966,13 +990,13 @@ short RenderStyle::verticalBorderSpacing() const { return inherited->vertical_bo
void RenderStyle::setHorizontalBorderSpacing(short v) { SET_VAR(inherited, horizontal_border_spacing, v); }
void RenderStyle::setVerticalBorderSpacing(short v) { SET_VAR(inherited, vertical_border_spacing, v); }
-RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, RenderView* renderView, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
+RoundedRect RenderStyle::getRoundedBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const
{
IntRect snappedBorderRect(pixelSnappedIntRect(borderRect));
RoundedRect roundedRect(snappedBorderRect);
if (hasBorderRadius()) {
- RoundedRect::Radii radii = calcRadiiFor(surround->border, snappedBorderRect.size(), renderView);
- radii.scale(calcConstraintScaleFor(snappedBorderRect, radii));
+ RoundedRect::Radii radii = calcRadiiFor(surround->border, snappedBorderRect.size());
+ radii.scale(calcBorderRadiiConstraintScaleFor(borderRect, radii));
roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge);
}
return roundedRect;
@@ -1096,111 +1120,67 @@ const AtomicString& RenderStyle::textEmphasisMarkString() const
return nullAtom;
}
-void RenderStyle::adjustAnimations()
+CSSAnimationData& RenderStyle::accessAnimations()
{
- CSSAnimationDataList* animationList = rareNonInheritedData->m_animations.get();
- if (!animationList)
- return;
-
- // Get rid of empty animations and anything beyond them
- for (size_t i = 0; i < animationList->size(); ++i) {
- if (animationList->animation(i)->isEmpty()) {
- animationList->resize(i);
- break;
- }
- }
-
- if (animationList->isEmpty()) {
- clearAnimations();
- return;
- }
-
- // Repeat patterns into layers that don't have some properties set.
- animationList->fillUnsetProperties();
+ if (!rareNonInheritedData.access()->m_animations)
+ rareNonInheritedData.access()->m_animations = CSSAnimationData::create();
+ return *rareNonInheritedData->m_animations;
}
-void RenderStyle::adjustTransitions()
+CSSTransitionData& RenderStyle::accessTransitions()
{
- CSSAnimationDataList* transitionList = rareNonInheritedData->m_transitions.get();
- if (!transitionList)
- return;
+ if (!rareNonInheritedData.access()->m_transitions)
+ rareNonInheritedData.access()->m_transitions = CSSTransitionData::create();
+ return *rareNonInheritedData->m_transitions;
+}
- // Get rid of empty transitions and anything beyond them
- for (size_t i = 0; i < transitionList->size(); ++i) {
- if (transitionList->animation(i)->isEmpty()) {
- transitionList->resize(i);
- break;
- }
- }
+const Font& RenderStyle::font() const { return inherited->font; }
+const FontMetrics& RenderStyle::fontMetrics() const { return inherited->font.fontMetrics(); }
+const FontDescription& RenderStyle::fontDescription() const { return inherited->font.fontDescription(); }
+float RenderStyle::specifiedFontSize() const { return fontDescription().specifiedSize(); }
+float RenderStyle::computedFontSize() const { return fontDescription().computedSize(); }
+int RenderStyle::fontSize() const { return fontDescription().computedPixelSize(); }
+FontWeight RenderStyle::fontWeight() const { return fontDescription().weight(); }
- if (transitionList->isEmpty()) {
- clearTransitions();
- return;
- }
+TextDecoration RenderStyle::textDecorationsInEffect() const
+{
+ int decorations = 0;
- // Repeat patterns into layers that don't have some properties set.
- transitionList->fillUnsetProperties();
-
- // Make sure there are no duplicate properties. This is an O(n^2) algorithm
- // but the lists tend to be very short, so it is probably ok
- for (size_t i = 0; i < transitionList->size(); ++i) {
- for (size_t j = i+1; j < transitionList->size(); ++j) {
- if (transitionList->animation(i)->property() == transitionList->animation(j)->property()) {
- // toss i
- transitionList->remove(i);
- j = i;
- }
- }
- }
-}
+ const Vector<AppliedTextDecoration>& applied = appliedTextDecorations();
-CSSAnimationDataList* RenderStyle::accessAnimations()
-{
- if (!rareNonInheritedData.access()->m_animations)
- rareNonInheritedData.access()->m_animations = adoptPtr(new CSSAnimationDataList());
- return rareNonInheritedData->m_animations.get();
-}
+ for (size_t i = 0; i < applied.size(); ++i)
+ decorations |= applied[i].line();
-CSSAnimationDataList* RenderStyle::accessTransitions()
-{
- if (!rareNonInheritedData.access()->m_transitions)
- rareNonInheritedData.access()->m_transitions = adoptPtr(new CSSAnimationDataList());
- return rareNonInheritedData->m_transitions.get();
+ return static_cast<TextDecoration>(decorations);
}
-const CSSAnimationData* RenderStyle::transitionForProperty(CSSPropertyID property) const
+const Vector<AppliedTextDecoration>& RenderStyle::appliedTextDecorations() const
{
- if (transitions()) {
- for (size_t i = 0; i < transitions()->size(); ++i) {
- const CSSAnimationData* p = transitions()->animation(i);
- if (p->animationMode() == CSSAnimationData::AnimateAll || p->property() == property) {
- return p;
- }
- }
+ if (!inherited_flags.m_textUnderline && !rareInheritedData->appliedTextDecorations) {
+ DEFINE_STATIC_LOCAL(Vector<AppliedTextDecoration>, empty, ());
+ return empty;
+ }
+ if (inherited_flags.m_textUnderline) {
+ DEFINE_STATIC_LOCAL(Vector<AppliedTextDecoration>, underline, (1, AppliedTextDecoration(TextDecorationUnderline)));
+ return underline;
}
- return 0;
-}
-const Font& RenderStyle::font() const { return inherited->font; }
-const FontMetrics& RenderStyle::fontMetrics() const { return inherited->font.fontMetrics(); }
-const FontDescription& RenderStyle::fontDescription() const { return inherited->font.fontDescription(); }
-float RenderStyle::specifiedFontSize() const { return fontDescription().specifiedSize(); }
-float RenderStyle::computedFontSize() const { return fontDescription().computedSize(); }
-int RenderStyle::fontSize() const { return inherited->font.pixelSize(); }
+ return rareInheritedData->appliedTextDecorations->vector();
+}
-float RenderStyle::wordSpacing() const { return inherited->font.wordSpacing(); }
-float RenderStyle::letterSpacing() const { return inherited->font.letterSpacing(); }
+float RenderStyle::wordSpacing() const { return fontDescription().wordSpacing(); }
+float RenderStyle::letterSpacing() const { return fontDescription().letterSpacing(); }
bool RenderStyle::setFontDescription(const FontDescription& v)
{
if (inherited->font.fontDescription() != v) {
- inherited.access()->font = Font(v, inherited->font.letterSpacing(), inherited->font.wordSpacing());
+ inherited.access()->font = Font(v);
return true;
}
return false;
}
-Length RenderStyle::specifiedLineHeight() const { return inherited->line_height; }
+const Length& RenderStyle::specifiedLineHeight() const { return inherited->line_height; }
Length RenderStyle::lineHeight() const
{
const Length& lh = inherited->line_height;
@@ -1214,9 +1194,10 @@ Length RenderStyle::lineHeight() const
return lh;
}
-void RenderStyle::setLineHeight(Length specifiedLineHeight) { SET_VAR(inherited, line_height, specifiedLineHeight); }
-int RenderStyle::computedLineHeight(RenderView* renderView) const
+void RenderStyle::setLineHeight(const Length& specifiedLineHeight) { SET_VAR(inherited, line_height, specifiedLineHeight); }
+
+int RenderStyle::computedLineHeight() const
{
const Length& lh = lineHeight();
@@ -1227,14 +1208,26 @@ int RenderStyle::computedLineHeight(RenderView* renderView) const
if (lh.isPercent())
return minimumValueForLength(lh, fontSize());
- if (lh.isViewportPercentage())
- return valueForLength(lh, 0, renderView);
-
return lh.value();
}
-void RenderStyle::setWordSpacing(float v) { inherited.access()->font.setWordSpacing(v); }
-void RenderStyle::setLetterSpacing(float v) { inherited.access()->font.setLetterSpacing(v); }
+void RenderStyle::setWordSpacing(float wordSpacing)
+{
+ FontSelector* currentFontSelector = font().fontSelector();
+ FontDescription desc(fontDescription());
+ desc.setWordSpacing(wordSpacing);
+ setFontDescription(desc);
+ font().update(currentFontSelector);
+}
+
+void RenderStyle::setLetterSpacing(float letterSpacing)
+{
+ FontSelector* currentFontSelector = font().fontSelector();
+ FontDescription desc(fontDescription());
+ desc.setLetterSpacing(letterSpacing);
+ setFontDescription(desc);
+ font().update(currentFontSelector);
+}
void RenderStyle::setFontSize(float size)
{
@@ -1262,6 +1255,66 @@ void RenderStyle::setFontSize(float size)
font().update(currentFontSelector);
}
+void RenderStyle::setFontWeight(FontWeight weight)
+{
+ FontSelector* currentFontSelector = font().fontSelector();
+ FontDescription desc(fontDescription());
+ desc.setWeight(weight);
+ setFontDescription(desc);
+ font().update(currentFontSelector);
+}
+
+void RenderStyle::addAppliedTextDecoration(const AppliedTextDecoration& decoration)
+{
+ RefPtr<AppliedTextDecorationList>& list = rareInheritedData.access()->appliedTextDecorations;
+
+ if (!list)
+ list = AppliedTextDecorationList::create();
+ else if (!list->hasOneRef())
+ list = list->copy();
+
+ if (inherited_flags.m_textUnderline) {
+ inherited_flags.m_textUnderline = false;
+ list->append(AppliedTextDecoration(TextDecorationUnderline));
+ }
+
+ list->append(decoration);
+}
+
+void RenderStyle::applyTextDecorations()
+{
+ if (textDecoration() == TextDecorationNone)
+ return;
+
+ TextDecorationStyle style = textDecorationStyle();
+ StyleColor styleColor = visitedDependentDecorationStyleColor();
+
+ int decorations = textDecoration();
+
+ if (decorations & TextDecorationUnderline) {
+ // To save memory, we don't use AppliedTextDecoration objects in the
+ // common case of a single simple underline.
+ AppliedTextDecoration underline(TextDecorationUnderline, style, styleColor);
+
+ if (!rareInheritedData->appliedTextDecorations && underline.isSimpleUnderline())
+ inherited_flags.m_textUnderline = true;
+ else
+ addAppliedTextDecoration(underline);
+ }
+ if (decorations & TextDecorationOverline)
+ addAppliedTextDecoration(AppliedTextDecoration(TextDecorationOverline, style, styleColor));
+ if (decorations & TextDecorationLineThrough)
+ addAppliedTextDecoration(AppliedTextDecoration(TextDecorationLineThrough, style, styleColor));
+}
+
+void RenderStyle::clearAppliedTextDecorations()
+{
+ inherited_flags.m_textUnderline = false;
+
+ if (rareInheritedData->appliedTextDecorations)
+ rareInheritedData.access()->appliedTextDecorations = nullptr;
+}
+
void RenderStyle::getShadowExtent(const ShadowList* shadowList, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const
{
top = 0;
@@ -1274,7 +1327,7 @@ void RenderStyle::getShadowExtent(const ShadowList* shadowList, LayoutUnit &top,
const ShadowData& shadow = shadowList->shadows()[i];
if (shadow.style() == Inset)
continue;
- int blurAndSpread = shadow.blur() + shadow.spread();
+ float blurAndSpread = shadow.blur() + shadow.spread();
top = min<LayoutUnit>(top, shadow.y() - blurAndSpread);
right = max<LayoutUnit>(right, shadow.x() + blurAndSpread);
@@ -1295,7 +1348,7 @@ LayoutBoxExtent RenderStyle::getShadowInsetExtent(const ShadowList* shadowList)
const ShadowData& shadow = shadowList->shadows()[i];
if (shadow.style() == Normal)
continue;
- int blurAndSpread = shadow.blur() + shadow.spread();
+ float blurAndSpread = shadow.blur() + shadow.spread();
top = max<LayoutUnit>(top, shadow.y() + blurAndSpread);
right = min<LayoutUnit>(right, shadow.x() - blurAndSpread);
bottom = min<LayoutUnit>(bottom, shadow.y() - blurAndSpread);
@@ -1315,7 +1368,7 @@ void RenderStyle::getShadowHorizontalExtent(const ShadowList* shadowList, Layout
const ShadowData& shadow = shadowList->shadows()[i];
if (shadow.style() == Inset)
continue;
- int blurAndSpread = shadow.blur() + shadow.spread();
+ float blurAndSpread = shadow.blur() + shadow.spread();
left = min<LayoutUnit>(left, shadow.x() - blurAndSpread);
right = max<LayoutUnit>(right, shadow.x() + blurAndSpread);
@@ -1332,20 +1385,46 @@ void RenderStyle::getShadowVerticalExtent(const ShadowList* shadowList, LayoutUn
const ShadowData& shadow = shadowList->shadows()[i];
if (shadow.style() == Inset)
continue;
- int blurAndSpread = shadow.blur() + shadow.spread();
+ float blurAndSpread = shadow.blur() + shadow.spread();
top = min<LayoutUnit>(top, shadow.y() - blurAndSpread);
bottom = max<LayoutUnit>(bottom, shadow.y() + blurAndSpread);
}
}
+StyleColor RenderStyle::visitedDependentDecorationStyleColor() const
+{
+ bool isVisited = insideLink() == InsideVisitedLink;
+
+ StyleColor styleColor = isVisited ? visitedLinkTextDecorationColor() : textDecorationColor();
+
+ if (!styleColor.isCurrentColor())
+ return styleColor;
+
+ if (textStrokeWidth()) {
+ // Prefer stroke color if possible, but not if it's fully transparent.
+ StyleColor textStrokeStyleColor = isVisited ? visitedLinkTextStrokeColor() : textStrokeColor();
+ if (!textStrokeStyleColor.isCurrentColor() && textStrokeStyleColor.color().alpha())
+ return textStrokeStyleColor;
+ }
+
+ return isVisited ? visitedLinkTextFillColor() : textFillColor();
+}
+
+Color RenderStyle::visitedDependentDecorationColor() const
+{
+ bool isVisited = insideLink() == InsideVisitedLink;
+ return visitedDependentDecorationStyleColor().resolve(isVisited ? visitedLinkColor() : color());
+}
+
Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) const
{
- Color result;
+ StyleColor result(StyleColor::currentColor());
EBorderStyle borderStyle = BNONE;
switch (colorProperty) {
case CSSPropertyBackgroundColor:
- return visitedLink ? visitedLinkBackgroundColor() : backgroundColor(); // Background color doesn't fall back.
+ result = visitedLink ? visitedLinkBackgroundColor() : backgroundColor();
+ break;
case CSSPropertyBorderLeftColor:
result = visitedLink ? visitedLinkBorderLeftColor() : borderLeftColor();
borderStyle = borderLeftStyle();
@@ -1371,9 +1450,6 @@ Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c
case CSSPropertyWebkitColumnRuleColor:
result = visitedLink ? visitedLinkColumnRuleColor() : columnRuleColor();
break;
- case CSSPropertyTextDecorationColor:
- // Text decoration color fallback is handled in RenderObject::decorationColor.
- return visitedLink ? visitedLinkTextDecorationColor() : textDecorationColor();
case CSSPropertyWebkitTextEmphasisColor:
result = visitedLink ? visitedLinkTextEmphasisColor() : textEmphasisColor();
break;
@@ -1400,13 +1476,14 @@ Color RenderStyle::colorIncludingFallback(int colorProperty, bool visitedLink) c
break;
}
- if (!result.isValid()) {
- if (!visitedLink && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE))
- result.setRGB(238, 238, 238);
- else
- result = visitedLink ? visitedLinkColor() : color();
- }
- return result;
+ if (!result.isCurrentColor())
+ return result.color();
+
+ // FIXME: Treating styled borders with initial color differently causes problems
+ // See crbug.com/316559, crbug.com/276231
+ if (!visitedLink && (borderStyle == INSET || borderStyle == OUTSET || borderStyle == RIDGE || borderStyle == GROOVE))
+ return Color(238, 238, 238);
+ return visitedLink ? visitedLinkColor() : color();
}
Color RenderStyle::visitedDependentColor(int colorProperty) const
@@ -1417,10 +1494,6 @@ Color RenderStyle::visitedDependentColor(int colorProperty) const
Color visitedColor = colorIncludingFallback(colorProperty, true);
- // Text decoration color validity is preserved (checked in RenderObject::decorationColor).
- if (colorProperty == CSSPropertyTextDecorationColor)
- return visitedColor;
-
// FIXME: Technically someone could explicitly specify the color transparent, but for now we'll just
// assume that if the background color is transparent that it wasn't set. Note that it's weird that
// we're returning unvisited info for a visited link, but given our restriction that the alpha values
@@ -1525,7 +1598,7 @@ unsigned short RenderStyle::borderEndWidth() const
return isLeftToRightDirection() ? borderBottomWidth() : borderTopWidth();
}
-void RenderStyle::setMarginStart(Length margin)
+void RenderStyle::setMarginStart(const Length& margin)
{
if (isHorizontalWritingMode()) {
if (isLeftToRightDirection())
@@ -1540,7 +1613,7 @@ void RenderStyle::setMarginStart(Length margin)
}
}
-void RenderStyle::setMarginEnd(Length margin)
+void RenderStyle::setMarginEnd(const Length& margin)
{
if (isHorizontalWritingMode()) {
if (isLeftToRightDirection())
@@ -1587,7 +1660,7 @@ void RenderStyle::setBorderImageSource(PassRefPtr<StyleImage> image)
surround.access()->border.m_image.setImage(image);
}
-void RenderStyle::setBorderImageSlices(LengthBox slices)
+void RenderStyle::setBorderImageSlices(const LengthBox& slices)
{
if (surround->border.m_image.imageSlices() == slices)
return;
@@ -1608,4 +1681,36 @@ void RenderStyle::setBorderImageOutset(const BorderImageLengthBox& outset)
surround.access()->border.m_image.setOutset(outset);
}
+float calcBorderRadiiConstraintScaleFor(const FloatRect& rect, const FloatRoundedRect::Radii& radii)
+{
+ // Constrain corner radii using CSS3 rules:
+ // http://www.w3.org/TR/css3-background/#the-border-radius
+
+ float factor = 1;
+ float radiiSum;
+
+ // top
+ radiiSum = radii.topLeft().width() + radii.topRight().width(); // Casts to avoid integer overflow.
+ if (radiiSum > rect.width())
+ factor = std::min(rect.width() / radiiSum, factor);
+
+ // bottom
+ radiiSum = radii.bottomLeft().width() + radii.bottomRight().width();
+ if (radiiSum > rect.width())
+ factor = std::min(rect.width() / radiiSum, factor);
+
+ // left
+ radiiSum = radii.topLeft().height() + radii.bottomLeft().height();
+ if (radiiSum > rect.height())
+ factor = std::min(rect.height() / radiiSum, factor);
+
+ // right
+ radiiSum = radii.topRight().height() + radii.bottomRight().height();
+ if (radiiSum > rect.height())
+ factor = std::min(rect.height() / radiiSum, factor);
+
+ ASSERT(factor <= 1);
+ return factor;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.h b/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.h
index f405b951fbe..543c815d06d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyle.h
@@ -25,11 +25,11 @@
#ifndef RenderStyle_h
#define RenderStyle_h
-#include "CSSPropertyNames.h"
-#include "core/css/CSSLengthFunctions.h"
+#include "core/CSSPropertyNames.h"
+#include "core/animation/css/CSSAnimationData.h"
+#include "core/animation/css/CSSTransitionData.h"
#include "core/css/CSSLineBoxContainValue.h"
#include "core/css/CSSPrimitiveValue.h"
-#include "core/platform/animation/CSSAnimationDataList.h"
#include "core/rendering/style/BorderValue.h"
#include "core/rendering/style/CounterDirectives.h"
#include "core/rendering/style/DataRef.h"
@@ -42,10 +42,12 @@
#include "core/rendering/style/StyleBackgroundData.h"
#include "core/rendering/style/StyleBoxData.h"
#include "core/rendering/style/StyleDeprecatedFlexibleBoxData.h"
+#include "core/rendering/style/StyleDifference.h"
#include "core/rendering/style/StyleFilterData.h"
#include "core/rendering/style/StyleFlexibleBoxData.h"
#include "core/rendering/style/StyleGridData.h"
#include "core/rendering/style/StyleGridItemData.h"
+#include "core/rendering/style/StyleInheritedData.h"
#include "core/rendering/style/StyleMarqueeData.h"
#include "core/rendering/style/StyleMultiColData.h"
#include "core/rendering/style/StyleRareInheritedData.h"
@@ -54,6 +56,7 @@
#include "core/rendering/style/StyleSurroundData.h"
#include "core/rendering/style/StyleTransformData.h"
#include "core/rendering/style/StyleVisualData.h"
+#include "core/rendering/style/StyleWillChangeData.h"
#include "core/svg/SVGPaint.h"
#include "platform/Length.h"
#include "platform/LengthBox.h"
@@ -61,10 +64,12 @@
#include "platform/ThemeTypes.h"
#include "platform/fonts/FontBaseline.h"
#include "platform/fonts/FontDescription.h"
+#include "platform/geometry/FloatRoundedRect.h"
#include "platform/geometry/LayoutBoxExtent.h"
#include "platform/geometry/RoundedRect.h"
#include "platform/graphics/Color.h"
#include "platform/graphics/GraphicsTypes.h"
+#include "platform/scroll/ScrollableArea.h"
#include "platform/text/TextDirection.h"
#include "platform/text/UnicodeBidi.h"
#include "platform/transforms/TransformOperations.h"
@@ -80,6 +85,10 @@ template<typename T, typename U> inline bool compareEqual(const T& t, const U& u
if (!compareEqual(group->variable, value)) \
group.access()->variable = value
+#define SET_VAR_WITH_SETTER(group, getter, setter, value) \
+ if (!compareEqual(group->getter(), value)) \
+ group.access()->setter(value)
+
#define SET_BORDERVALUE_COLOR(group, variable, value) \
if (!compareEqual(group->variable.color(), value)) \
group.access()->variable.setColor(value)
@@ -90,13 +99,11 @@ using std::max;
class FilterOperations;
+class AppliedTextDecoration;
class BorderData;
class CounterContent;
-class CursorList;
class Font;
class FontMetrics;
-class IntRect;
-class Pair;
class ShadowList;
class StyleImage;
class StyleInheritedData;
@@ -110,11 +117,11 @@ typedef Vector<RefPtr<RenderStyle>, 4> PseudoStyleCache;
class RenderStyle: public RefCounted<RenderStyle> {
friend class AnimatedStyleBuilder; // Used by Web Animations CSS. Sets the color styles
friend class CSSAnimatableValueFactory; // Used by Web Animations CSS. Gets visited and unvisited colors separately.
- friend class CSSPropertyAnimation; // Used by CSS animations. We can't allow them to animate based off visited colors.
+ friend class CSSPropertyEquality; // Used by CSS animations. We can't allow them to animate based off visited colors.
friend class ApplyStyleCommand; // Editing has to only reveal unvisited info.
friend class EditingStyle; // Editing has to only reveal unvisited info.
friend class CSSComputedStyleDeclaration; // Ignores visited styles, so needs to be able to see unvisited info.
- friend class PropertyWrapperMaybeInvalidColor; // Used by CSS animations. We can't allow them to animate based off visited colors.
+ friend class PropertyWrapperMaybeInvalidStyleColor; // Used by CSS animations. We can't allow them to animate based off visited colors.
friend class StyleBuilderFunctions; // Sets color styles
friend class CachedUAStyle; // Saves Border/Background information for later comparison.
@@ -156,7 +163,7 @@ protected:
&& (_visibility == other._visibility)
&& (_text_align == other._text_align)
&& (_text_transform == other._text_transform)
- && (_text_decorations == other._text_decorations)
+ && (m_textUnderline == other.m_textUnderline)
&& (_cursor_style == other._cursor_style)
&& (_direction == other._direction)
&& (_white_space == other._white_space)
@@ -178,24 +185,23 @@ protected:
unsigned _visibility : 2; // EVisibility
unsigned _text_align : 4; // ETextAlign
unsigned _text_transform : 2; // ETextTransform
- unsigned _text_decorations : TextDecorationBits;
+ unsigned m_textUnderline : 1;
unsigned _cursor_style : 6; // ECursor
unsigned _direction : 1; // TextDirection
unsigned _white_space : 3; // EWhiteSpace
- // 32 bits
unsigned _border_collapse : 1; // EBorderCollapse
unsigned _box_direction : 1; // EBoxDirection (CSS3 box_direction property, flexible box layout module)
+ // 32 bits
// non CSS2 inherited
unsigned m_rtlOrdering : 1; // Order
unsigned m_printColorAdjust : PrintColorAdjustBits;
unsigned _pointerEvents : 4; // EPointerEvents
unsigned _insideLink : 2; // EInsideLink
- // 43 bits
// CSS Text Layout Module Level 3: Vertical writing support
unsigned m_writingMode : 2; // WritingMode
- // 45 bits
+ // 42 bits
} inherited_flags;
// don't inherit
@@ -243,7 +249,13 @@ protected:
unsigned _table_layout : 1; // ETableLayout
unsigned _unicodeBidi : 3; // EUnicodeBidi
- // 31 bits
+
+ // This is set if we used viewport units when resolving a length.
+ // It is mutable so we can pass around const RenderStyles to resolve lengths.
+ mutable unsigned hasViewportUnits : 1;
+
+ // 32 bits
+
unsigned _page_break_before : 2; // EPageBreak
unsigned _page_break_after : 2; // EPageBreak
unsigned _page_break_inside : 2; // EPageBreak
@@ -274,7 +286,7 @@ protected:
unsigned _affectedByDrag : 1;
unsigned _isLink : 1;
// If you add more style bits here, you will also need to update RenderStyle::copyNonInheritedFrom()
- // 60 bits
+ // 63 bits
} noninherited_flags;
// !END SYNC!
@@ -289,7 +301,7 @@ protected:
inherited_flags._visibility = initialVisibility();
inherited_flags._text_align = initialTextAlign();
inherited_flags._text_transform = initialTextTransform();
- inherited_flags._text_decorations = initialTextDecoration();
+ inherited_flags.m_textUnderline = false;
inherited_flags._cursor_style = initialCursor();
inherited_flags._direction = initialDirection();
inherited_flags._white_space = initialWhiteSpace();
@@ -321,6 +333,7 @@ protected:
noninherited_flags.emptyState = false;
noninherited_flags.firstChildState = false;
noninherited_flags.lastChildState = false;
+ noninherited_flags.hasViewportUnits = false;
noninherited_flags.setAffectedByFocus(false);
noninherited_flags.setAffectedByHover(false);
noninherited_flags.setAffectedByActive(false);
@@ -343,7 +356,11 @@ public:
static PassRefPtr<RenderStyle> createAnonymousStyleWithDisplay(const RenderStyle* parentStyle, EDisplay);
static PassRefPtr<RenderStyle> clone(const RenderStyle*);
- static StyleRecalcChange compare(const RenderStyle* oldStyle, const RenderStyle* newStyle);
+ // Computes how the style change should be propagated down the tree.
+ static StyleRecalcChange stylePropagationDiff(const RenderStyle* oldStyle, const RenderStyle* newStyle);
+
+ // Computes how much visual invalidation the style change causes: layout, repaint or recomposite.
+ StyleDifference visualInvalidationDiff(const RenderStyle&, unsigned& changedContextSensitiveProperties) const;
enum IsAtShadowBoundary {
AtShadowBoundary,
@@ -362,8 +379,8 @@ public:
const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); }
- void setVariable(const AtomicString& name, const String& value) { rareInheritedData.access()->m_variables.access()->setVariable(name, value); }
- const HashMap<AtomicString, String>* variables() { return &(rareInheritedData->m_variables->m_data); }
+ void setHasViewportUnits(bool hasViewportUnits = true) const { noninherited_flags.hasViewportUnits = hasViewportUnits; }
+ bool hasViewportUnits() const { return noninherited_flags.hasViewportUnits; }
bool affectedByFocus() const { return noninherited_flags.affectedByFocus(); }
bool affectedByHover() const { return noninherited_flags.affectedByHover(); }
@@ -395,7 +412,7 @@ public:
bool hasBackground() const
{
Color color = visitedDependentColor(CSSPropertyBackgroundColor);
- if (color.isValid() && color.alpha())
+ if (color.alpha())
return true;
return hasBackgroundImage();
}
@@ -427,22 +444,23 @@ public:
bool hasPseudoStyle(PseudoId pseudo) const;
void setHasPseudoStyle(PseudoId pseudo);
bool hasUniquePseudoStyle() const;
+ bool hasPseudoElementStyle() const;
// attribute getter methods
EDisplay display() const { return static_cast<EDisplay>(noninherited_flags._effectiveDisplay); }
EDisplay originalDisplay() const { return static_cast<EDisplay>(noninherited_flags._originalDisplay); }
- Length left() const { return surround->offset.left(); }
- Length right() const { return surround->offset.right(); }
- Length top() const { return surround->offset.top(); }
- Length bottom() const { return surround->offset.bottom(); }
+ const Length& left() const { return surround->offset.left(); }
+ const Length& right() const { return surround->offset.right(); }
+ const Length& top() const { return surround->offset.top(); }
+ const Length& bottom() const { return surround->offset.bottom(); }
// Accessors for positioned object edges that take into account writing mode.
- Length logicalLeft() const { return surround->offset.logicalLeft(writingMode()); }
- Length logicalRight() const { return surround->offset.logicalRight(writingMode()); }
- Length logicalTop() const { return surround->offset.before(writingMode()); }
- Length logicalBottom() const { return surround->offset.after(writingMode()); }
+ const Length& logicalLeft() const { return surround->offset.logicalLeft(writingMode()); }
+ const Length& logicalRight() const { return surround->offset.logicalRight(writingMode()); }
+ const Length& logicalTop() const { return surround->offset.before(writingMode()); }
+ const Length& logicalBottom() const { return surround->offset.after(writingMode()); }
// Whether or not a positioned element requires normal flow x/y to be computed
// to determine its position.
@@ -457,19 +475,19 @@ public:
bool hasViewportConstrainedPosition() const { return position() == FixedPosition || position() == StickyPosition; }
EFloat floating() const { return static_cast<EFloat>(noninherited_flags._floating); }
- Length width() const { return m_box->width(); }
- Length height() const { return m_box->height(); }
- Length minWidth() const { return m_box->minWidth(); }
- Length maxWidth() const { return m_box->maxWidth(); }
- Length minHeight() const { return m_box->minHeight(); }
- Length maxHeight() const { return m_box->maxHeight(); }
+ const Length& width() const { return m_box->width(); }
+ const Length& height() const { return m_box->height(); }
+ const Length& minWidth() const { return m_box->minWidth(); }
+ const Length& maxWidth() const { return m_box->maxWidth(); }
+ const Length& minHeight() const { return m_box->minHeight(); }
+ const Length& maxHeight() const { return m_box->maxHeight(); }
- Length logicalWidth() const { return isHorizontalWritingMode() ? width() : height(); }
- Length logicalHeight() const { return isHorizontalWritingMode() ? height() : width(); }
- Length logicalMinWidth() const { return isHorizontalWritingMode() ? minWidth() : minHeight(); }
- Length logicalMaxWidth() const { return isHorizontalWritingMode() ? maxWidth() : maxHeight(); }
- Length logicalMinHeight() const { return isHorizontalWritingMode() ? minHeight() : minWidth(); }
- Length logicalMaxHeight() const { return isHorizontalWritingMode() ? maxHeight() : maxWidth(); }
+ const Length& logicalWidth() const { return isHorizontalWritingMode() ? width() : height(); }
+ const Length& logicalHeight() const { return isHorizontalWritingMode() ? height() : width(); }
+ const Length& logicalMinWidth() const { return isHorizontalWritingMode() ? minWidth() : minHeight(); }
+ const Length& logicalMaxWidth() const { return isHorizontalWritingMode() ? maxWidth() : maxHeight(); }
+ const Length& logicalMinHeight() const { return isHorizontalWritingMode() ? minHeight() : minWidth(); }
+ const Length& logicalMaxHeight() const { return isHorizontalWritingMode() ? maxHeight() : maxWidth(); }
const BorderData& border() const { return surround->border; }
const BorderValue& borderLeft() const { return surround->border.left(); }
@@ -484,14 +502,14 @@ public:
const NinePieceImage& borderImage() const { return surround->border.image(); }
StyleImage* borderImageSource() const { return surround->border.image().image(); }
- LengthBox borderImageSlices() const { return surround->border.image().imageSlices(); }
+ const LengthBox& borderImageSlices() const { return surround->border.image().imageSlices(); }
const BorderImageLengthBox& borderImageWidth() const { return surround->border.image().borderSlices(); }
const BorderImageLengthBox& borderImageOutset() const { return surround->border.image().outset(); }
- LengthSize borderTopLeftRadius() const { return surround->border.topLeft(); }
- LengthSize borderTopRightRadius() const { return surround->border.topRight(); }
- LengthSize borderBottomLeftRadius() const { return surround->border.bottomLeft(); }
- LengthSize borderBottomRightRadius() const { return surround->border.bottomRight(); }
+ const LengthSize& borderTopLeftRadius() const { return surround->border.topLeft(); }
+ const LengthSize& borderTopRightRadius() const { return surround->border.topRight(); }
+ const LengthSize& borderBottomLeftRadius() const { return surround->border.bottomLeft(); }
+ const LengthSize& borderBottomRightRadius() const { return surround->border.bottomRight(); }
bool hasBorderRadius() const { return surround->border.hasBorderRadius(); }
unsigned borderLeftWidth() const { return surround->border.borderLeftWidth(); }
@@ -525,22 +543,26 @@ public:
EOverflow overflowX() const { return static_cast<EOverflow>(noninherited_flags._overflowX); }
EOverflow overflowY() const { return static_cast<EOverflow>(noninherited_flags._overflowY); }
+ // It's sufficient to just check one direction, since it's illegal to have visible on only one overflow value.
+ bool isOverflowVisible() const { ASSERT(overflowX() != OVISIBLE || overflowX() == overflowY()); return overflowX() == OVISIBLE; }
+ bool isOverflowPaged() const { return overflowY() == OPAGEDX || overflowY() == OPAGEDY; }
EVisibility visibility() const { return static_cast<EVisibility>(inherited_flags._visibility); }
EVerticalAlign verticalAlign() const { return static_cast<EVerticalAlign>(noninherited_flags._vertical_align); }
- Length verticalAlignLength() const { return m_box->verticalAlign(); }
+ const Length& verticalAlignLength() const { return m_box->verticalAlign(); }
- Length clipLeft() const { return visual->clip.left(); }
- Length clipRight() const { return visual->clip.right(); }
- Length clipTop() const { return visual->clip.top(); }
- Length clipBottom() const { return visual->clip.bottom(); }
- LengthBox clip() const { return visual->clip; }
+ const Length& clipLeft() const { return visual->clip.left(); }
+ const Length& clipRight() const { return visual->clip.right(); }
+ const Length& clipTop() const { return visual->clip.top(); }
+ const Length& clipBottom() const { return visual->clip.bottom(); }
+ const LengthBox& clip() const { return visual->clip; }
bool hasClip() const { return visual->hasClip; }
EUnicodeBidi unicodeBidi() const { return static_cast<EUnicodeBidi>(noninherited_flags._unicodeBidi); }
EClear clear() const { return static_cast<EClear>(noninherited_flags._clear); }
ETableLayout tableLayout() const { return static_cast<ETableLayout>(noninherited_flags._table_layout); }
+ bool isFixedTableLayout() const { return tableLayout() == TFIXED && !logicalWidth().isAuto(); }
const Font& font() const;
const FontMetrics& fontMetrics() const;
@@ -548,16 +570,19 @@ public:
float specifiedFontSize() const;
float computedFontSize() const;
int fontSize() const;
+ FontWeight fontWeight() const;
- float textAutosizingMultiplier() const { return visual->m_textAutosizingMultiplier; }
+ float textAutosizingMultiplier() const { return inherited->textAutosizingMultiplier; }
- Length textIndent() const { return rareInheritedData->indent; }
+ const Length& textIndent() const { return rareInheritedData->indent; }
TextIndentLine textIndentLine() const { return static_cast<TextIndentLine>(rareInheritedData->m_textIndentLine); }
+ TextIndentType textIndentType() const { return static_cast<TextIndentType>(rareInheritedData->m_textIndentType); }
ETextAlign textAlign() const { return static_cast<ETextAlign>(inherited_flags._text_align); }
TextAlignLast textAlignLast() const { return static_cast<TextAlignLast>(rareInheritedData->m_textAlignLast); }
TextJustify textJustify() const { return static_cast<TextJustify>(rareInheritedData->m_textJustify); }
ETextTransform textTransform() const { return static_cast<ETextTransform>(inherited_flags._text_transform); }
- TextDecoration textDecorationsInEffect() const { return static_cast<TextDecoration>(inherited_flags._text_decorations); }
+ TextDecoration textDecorationsInEffect() const;
+ const Vector<AppliedTextDecoration>& appliedTextDecorations() const;
TextDecoration textDecoration() const { return static_cast<TextDecoration>(visual->textDecoration); }
TextUnderlinePosition textUnderlinePosition() const { return static_cast<TextUnderlinePosition>(rareInheritedData->m_textUnderlinePosition); }
TextDecorationStyle textDecorationStyle() const { return static_cast<TextDecorationStyle>(rareNonInheritedData->m_textDecorationStyle); }
@@ -570,9 +595,9 @@ public:
TextDirection direction() const { return static_cast<TextDirection>(inherited_flags._direction); }
bool isLeftToRightDirection() const { return direction() == LTR; }
- Length specifiedLineHeight() const;
+ const Length& specifiedLineHeight() const;
Length lineHeight() const;
- int computedLineHeight(RenderView* = 0) const;
+ int computedLineHeight() const;
EWhiteSpace whiteSpace() const { return static_cast<EWhiteSpace>(inherited_flags._white_space); }
static bool autoWrap(EWhiteSpace ws)
@@ -636,10 +661,10 @@ public:
EFillAttachment backgroundAttachment() const { return static_cast<EFillAttachment>(m_background->background().attachment()); }
EFillBox backgroundClip() const { return static_cast<EFillBox>(m_background->background().clip()); }
EFillBox backgroundOrigin() const { return static_cast<EFillBox>(m_background->background().origin()); }
- Length backgroundXPosition() const { return m_background->background().xPosition(); }
- Length backgroundYPosition() const { return m_background->background().yPosition(); }
+ const Length& backgroundXPosition() const { return m_background->background().xPosition(); }
+ const Length& backgroundYPosition() const { return m_background->background().yPosition(); }
EFillSizeType backgroundSizeType() const { return m_background->background().sizeType(); }
- LengthSize backgroundSizeLength() const { return m_background->background().sizeLength(); }
+ const LengthSize& backgroundSizeLength() const { return m_background->background().sizeLength(); }
FillLayer* accessBackgroundLayers() { return &(m_background.access()->m_background); }
const FillLayer* backgroundLayers() const { return &(m_background->background()); }
@@ -649,16 +674,16 @@ public:
CompositeOperator maskComposite() const { return static_cast<CompositeOperator>(rareNonInheritedData->m_mask.composite()); }
EFillBox maskClip() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.clip()); }
EFillBox maskOrigin() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.origin()); }
- Length maskXPosition() const { return rareNonInheritedData->m_mask.xPosition(); }
- Length maskYPosition() const { return rareNonInheritedData->m_mask.yPosition(); }
+ const Length& maskXPosition() const { return rareNonInheritedData->m_mask.xPosition(); }
+ const Length& maskYPosition() const { return rareNonInheritedData->m_mask.yPosition(); }
EFillSizeType maskSizeType() const { return rareNonInheritedData->m_mask.sizeType(); }
- LengthSize maskSizeLength() const { return rareNonInheritedData->m_mask.sizeLength(); }
+ const LengthSize& maskSizeLength() const { return rareNonInheritedData->m_mask.sizeLength(); }
FillLayer* accessMaskLayers() { return &(rareNonInheritedData.access()->m_mask); }
const FillLayer* maskLayers() const { return &(rareNonInheritedData->m_mask); }
const NinePieceImage& maskBoxImage() const { return rareNonInheritedData->m_maskBoxImage; }
StyleImage* maskBoxImageSource() const { return rareNonInheritedData->m_maskBoxImage.image(); }
- LengthBox maskBoxImageSlices() const { return rareNonInheritedData->m_maskBoxImage.imageSlices(); }
+ const LengthBox& maskBoxImageSlices() const { return rareNonInheritedData->m_maskBoxImage.imageSlices(); }
bool maskBoxImageSlicesFill() const { return rareNonInheritedData->m_maskBoxImage.fill(); }
const BorderImageLengthBox& maskBoxImageWidth() const { return rareNonInheritedData->m_maskBoxImage.borderSlices(); }
const BorderImageLengthBox& maskBoxImageOutset() const { return rareNonInheritedData->m_maskBoxImage.outset(); }
@@ -673,28 +698,28 @@ public:
StyleImage* listStyleImage() const;
EListStylePosition listStylePosition() const { return static_cast<EListStylePosition>(inherited_flags._list_style_position); }
- Length marginTop() const { return surround->margin.top(); }
- Length marginBottom() const { return surround->margin.bottom(); }
- Length marginLeft() const { return surround->margin.left(); }
- Length marginRight() const { return surround->margin.right(); }
- Length marginBefore() const { return surround->margin.before(writingMode()); }
- Length marginAfter() const { return surround->margin.after(writingMode()); }
- Length marginStart() const { return surround->margin.start(writingMode(), direction()); }
- Length marginEnd() const { return surround->margin.end(writingMode(), direction()); }
- Length marginStartUsing(const RenderStyle* otherStyle) const { return surround->margin.start(otherStyle->writingMode(), otherStyle->direction()); }
- Length marginEndUsing(const RenderStyle* otherStyle) const { return surround->margin.end(otherStyle->writingMode(), otherStyle->direction()); }
- Length marginBeforeUsing(const RenderStyle* otherStyle) const { return surround->margin.before(otherStyle->writingMode()); }
- Length marginAfterUsing(const RenderStyle* otherStyle) const { return surround->margin.after(otherStyle->writingMode()); }
-
- LengthBox paddingBox() const { return surround->padding; }
- Length paddingTop() const { return surround->padding.top(); }
- Length paddingBottom() const { return surround->padding.bottom(); }
- Length paddingLeft() const { return surround->padding.left(); }
- Length paddingRight() const { return surround->padding.right(); }
- Length paddingBefore() const { return surround->padding.before(writingMode()); }
- Length paddingAfter() const { return surround->padding.after(writingMode()); }
- Length paddingStart() const { return surround->padding.start(writingMode(), direction()); }
- Length paddingEnd() const { return surround->padding.end(writingMode(), direction()); }
+ const Length& marginTop() const { return surround->margin.top(); }
+ const Length& marginBottom() const { return surround->margin.bottom(); }
+ const Length& marginLeft() const { return surround->margin.left(); }
+ const Length& marginRight() const { return surround->margin.right(); }
+ const Length& marginBefore() const { return surround->margin.before(writingMode()); }
+ const Length& marginAfter() const { return surround->margin.after(writingMode()); }
+ const Length& marginStart() const { return surround->margin.start(writingMode(), direction()); }
+ const Length& marginEnd() const { return surround->margin.end(writingMode(), direction()); }
+ const Length& marginStartUsing(const RenderStyle* otherStyle) const { return surround->margin.start(otherStyle->writingMode(), otherStyle->direction()); }
+ const Length& marginEndUsing(const RenderStyle* otherStyle) const { return surround->margin.end(otherStyle->writingMode(), otherStyle->direction()); }
+ const Length& marginBeforeUsing(const RenderStyle* otherStyle) const { return surround->margin.before(otherStyle->writingMode()); }
+ const Length& marginAfterUsing(const RenderStyle* otherStyle) const { return surround->margin.after(otherStyle->writingMode()); }
+
+ const LengthBox& paddingBox() const { return surround->padding; }
+ const Length& paddingTop() const { return surround->padding.top(); }
+ const Length& paddingBottom() const { return surround->padding.bottom(); }
+ const Length& paddingLeft() const { return surround->padding.left(); }
+ const Length& paddingRight() const { return surround->padding.right(); }
+ const Length& paddingBefore() const { return surround->padding.before(writingMode()); }
+ const Length& paddingAfter() const { return surround->padding.after(writingMode()); }
+ const Length& paddingStart() const { return surround->padding.start(writingMode(), direction()); }
+ const Length& paddingEnd() const { return surround->padding.end(writingMode(), direction()); }
ECursor cursor() const { return static_cast<ECursor>(inherited_flags._cursor_style); }
CursorList* cursors() const { return rareInheritedData->cursorData.get(); }
@@ -737,9 +762,9 @@ public:
EBoxAlignment boxAlign() const { return static_cast<EBoxAlignment>(rareNonInheritedData->m_deprecatedFlexibleBox->align); }
EBoxDirection boxDirection() const { return static_cast<EBoxDirection>(inherited_flags._box_direction); }
float boxFlex() const { return rareNonInheritedData->m_deprecatedFlexibleBox->flex; }
- unsigned int boxFlexGroup() const { return rareNonInheritedData->m_deprecatedFlexibleBox->flex_group; }
+ unsigned boxFlexGroup() const { return rareNonInheritedData->m_deprecatedFlexibleBox->flexGroup; }
EBoxLines boxLines() const { return static_cast<EBoxLines>(rareNonInheritedData->m_deprecatedFlexibleBox->lines); }
- unsigned int boxOrdinalGroup() const { return rareNonInheritedData->m_deprecatedFlexibleBox->ordinal_group; }
+ unsigned boxOrdinalGroup() const { return rareNonInheritedData->m_deprecatedFlexibleBox->ordinalGroup; }
EBoxOrient boxOrient() const { return static_cast<EBoxOrient>(rareNonInheritedData->m_deprecatedFlexibleBox->orient); }
EBoxPack boxPack() const { return static_cast<EBoxPack>(rareNonInheritedData->m_deprecatedFlexibleBox->pack); }
@@ -747,18 +772,22 @@ public:
const Vector<String>& callbackSelectors() const { return rareNonInheritedData->m_callbackSelectors; }
float flexGrow() const { return rareNonInheritedData->m_flexibleBox->m_flexGrow; }
float flexShrink() const { return rareNonInheritedData->m_flexibleBox->m_flexShrink; }
- Length flexBasis() const { return rareNonInheritedData->m_flexibleBox->m_flexBasis; }
+ const Length& flexBasis() const { return rareNonInheritedData->m_flexibleBox->m_flexBasis; }
EAlignContent alignContent() const { return static_cast<EAlignContent>(rareNonInheritedData->m_alignContent); }
- EAlignItems alignItems() const { return static_cast<EAlignItems>(rareNonInheritedData->m_alignItems); }
- EAlignItems alignSelf() const { return static_cast<EAlignItems>(rareNonInheritedData->m_alignSelf); }
+ ItemPosition alignItems() const { return static_cast<ItemPosition>(rareNonInheritedData->m_alignItems); }
+ OverflowAlignment alignItemsOverflowAlignment() const { return static_cast<OverflowAlignment>(rareNonInheritedData->m_alignItemsOverflowAlignment); }
+ ItemPosition alignSelf() const { return static_cast<ItemPosition>(rareNonInheritedData->m_alignSelf); }
+ OverflowAlignment alignSelfOverflowAlignment() const { return static_cast<OverflowAlignment>(rareNonInheritedData->m_alignSelfOverflowAlignment); }
EFlexDirection flexDirection() const { return static_cast<EFlexDirection>(rareNonInheritedData->m_flexibleBox->m_flexDirection); }
bool isColumnFlexDirection() const { return flexDirection() == FlowColumn || flexDirection() == FlowColumnReverse; }
bool isReverseFlexDirection() const { return flexDirection() == FlowRowReverse || flexDirection() == FlowColumnReverse; }
EFlexWrap flexWrap() const { return static_cast<EFlexWrap>(rareNonInheritedData->m_flexibleBox->m_flexWrap); }
EJustifyContent justifyContent() const { return static_cast<EJustifyContent>(rareNonInheritedData->m_justifyContent); }
+ ItemPosition justifySelf() const { return static_cast<ItemPosition>(rareNonInheritedData->m_justifySelf); }
+ OverflowAlignment justifySelfOverflowAlignment() const { return static_cast<OverflowAlignment>(rareNonInheritedData->m_justifySelfOverflowAlignment); }
- const Vector<GridTrackSize>& gridDefinitionColumns() const { return rareNonInheritedData->m_grid->m_gridDefinitionColumns; }
- const Vector<GridTrackSize>& gridDefinitionRows() const { return rareNonInheritedData->m_grid->m_gridDefinitionRows; }
+ const Vector<GridTrackSize>& gridTemplateColumns() const { return rareNonInheritedData->m_grid->m_gridTemplateColumns; }
+ const Vector<GridTrackSize>& gridTemplateRows() const { return rareNonInheritedData->m_grid->m_gridTemplateRows; }
const NamedGridLinesMap& namedGridColumnLines() const { return rareNonInheritedData->m_grid->m_namedGridColumnLines; }
const NamedGridLinesMap& namedGridRowLines() const { return rareNonInheritedData->m_grid->m_namedGridRowLines; }
const OrderedNamedGridLines& orderedNamedGridColumnLines() const { return rareNonInheritedData->m_grid->m_orderedNamedGridColumnLines; }
@@ -785,8 +814,10 @@ public:
EBoxDecorationBreak boxDecorationBreak() const { return m_box->boxDecorationBreak(); }
StyleReflection* boxReflect() const { return rareNonInheritedData->m_boxReflect.get(); }
+ bool reflectionDataEquivalent(const RenderStyle* otherStyle) const { return rareNonInheritedData->reflectionDataEquivalent(*otherStyle->rareNonInheritedData); }
+
EBoxSizing boxSizing() const { return m_box->boxSizing(); }
- Length marqueeIncrement() const { return rareNonInheritedData->m_marquee->increment; }
+ const Length& marqueeIncrement() const { return rareNonInheritedData->m_marquee->increment; }
int marqueeSpeed() const { return rareNonInheritedData->m_marquee->speed; }
int marqueeLoopCount() const { return rareNonInheritedData->m_marquee->loops; }
EMarqueeBehavior marqueeBehavior() const { return static_cast<EMarqueeBehavior>(rareNonInheritedData->m_marquee->behavior); }
@@ -805,18 +836,20 @@ public:
const AtomicString& locale() const { return rareInheritedData->locale; }
EBorderFit borderFit() const { return static_cast<EBorderFit>(rareNonInheritedData->m_borderFit); }
EResize resize() const { return static_cast<EResize>(rareInheritedData->resize); }
- ColumnAxis columnAxis() const { return static_cast<ColumnAxis>(rareNonInheritedData->m_multiCol->m_axis); }
- bool hasInlineColumnAxis() const {
- ColumnAxis axis = columnAxis();
- return axis == AutoColumnAxis || isHorizontalWritingMode() == (axis == HorizontalColumnAxis);
+ bool hasInlinePaginationAxis() const
+ {
+ // If the pagination axis is parallel with the writing mode inline axis, columns may be laid
+ // out along the inline axis, just like for regular multicol. Otherwise, we need to lay out
+ // along the block axis.
+ if (isOverflowPaged())
+ return (overflowY() == OPAGEDX) == isHorizontalWritingMode();
+ return false;
}
- ColumnProgression columnProgression() const { return static_cast<ColumnProgression>(rareNonInheritedData->m_multiCol->m_progression); }
float columnWidth() const { return rareNonInheritedData->m_multiCol->m_width; }
bool hasAutoColumnWidth() const { return rareNonInheritedData->m_multiCol->m_autoWidth; }
unsigned short columnCount() const { return rareNonInheritedData->m_multiCol->m_count; }
bool hasAutoColumnCount() const { return rareNonInheritedData->m_multiCol->m_autoCount; }
- bool specifiesAutoColumns() const { return hasAutoColumnCount() && hasAutoColumnWidth(); }
- bool specifiesColumns() const { return !hasAutoColumnCount() || !hasAutoColumnWidth() || !hasInlineColumnAxis(); }
+ bool specifiesColumns() const { return !hasAutoColumnCount() || !hasAutoColumnWidth(); }
ColumnFill columnFill() const { return static_cast<ColumnFill>(rareNonInheritedData->m_multiCol->m_fill); }
float columnGap() const { return rareNonInheritedData->m_multiCol->m_gap; }
bool hasNormalColumnGap() const { return rareNonInheritedData->m_multiCol->m_normalGap; }
@@ -827,14 +860,12 @@ public:
EPageBreak columnBreakBefore() const { return static_cast<EPageBreak>(rareNonInheritedData->m_multiCol->m_breakBefore); }
EPageBreak columnBreakInside() const { return static_cast<EPageBreak>(rareNonInheritedData->m_multiCol->m_breakInside); }
EPageBreak columnBreakAfter() const { return static_cast<EPageBreak>(rareNonInheritedData->m_multiCol->m_breakAfter); }
- EPageBreak regionBreakBefore() const { return static_cast<EPageBreak>(rareNonInheritedData->m_regionBreakBefore); }
- EPageBreak regionBreakInside() const { return static_cast<EPageBreak>(rareNonInheritedData->m_regionBreakInside); }
- EPageBreak regionBreakAfter() const { return static_cast<EPageBreak>(rareNonInheritedData->m_regionBreakAfter); }
const TransformOperations& transform() const { return rareNonInheritedData->m_transform->m_operations; }
- Length transformOriginX() const { return rareNonInheritedData->m_transform->m_x; }
- Length transformOriginY() const { return rareNonInheritedData->m_transform->m_y; }
+ const Length& transformOriginX() const { return rareNonInheritedData->m_transform->m_x; }
+ const Length& transformOriginY() const { return rareNonInheritedData->m_transform->m_y; }
float transformOriginZ() const { return rareNonInheritedData->m_transform->m_z; }
bool hasTransform() const { return !rareNonInheritedData->m_transform->m_operations.operations().isEmpty(); }
+ bool transformDataEquivalent(const RenderStyle& otherStyle) const { return rareNonInheritedData->m_transform == otherStyle.rareNonInheritedData->m_transform; }
TextEmphasisFill textEmphasisFill() const { return static_cast<TextEmphasisFill>(rareInheritedData->textEmphasisFill); }
TextEmphasisMark textEmphasisMark() const;
@@ -866,30 +897,16 @@ public:
// End CSS3 Getters
- const AtomicString& flowThread() const { return rareNonInheritedData->m_flowThread; }
- bool hasFlowFrom() const { return !rareNonInheritedData->m_regionThread.isNull(); }
- const AtomicString& regionThread() const { return rareNonInheritedData->m_regionThread; }
- RegionFragment regionFragment() const { return static_cast<RegionFragment>(rareNonInheritedData->m_regionFragment); }
-
- const AtomicString& lineGrid() const { return rareInheritedData->m_lineGrid; }
- LineSnap lineSnap() const { return static_cast<LineSnap>(rareInheritedData->m_lineSnap); }
- LineAlign lineAlign() const { return static_cast<LineAlign>(rareInheritedData->m_lineAlign); }
-
WrapFlow wrapFlow() const { return static_cast<WrapFlow>(rareNonInheritedData->m_wrapFlow); }
WrapThrough wrapThrough() const { return static_cast<WrapThrough>(rareNonInheritedData->m_wrapThrough); }
// Apple-specific property getter methods
EPointerEvents pointerEvents() const { return static_cast<EPointerEvents>(inherited_flags._pointerEvents); }
- const CSSAnimationDataList* animations() const { return rareNonInheritedData->m_animations.get(); }
- const CSSAnimationDataList* transitions() const { return rareNonInheritedData->m_transitions.get(); }
+ const CSSAnimationData* animations() const { return rareNonInheritedData->m_animations.get(); }
+ const CSSTransitionData* transitions() const { return rareNonInheritedData->m_transitions.get(); }
- CSSAnimationDataList* accessAnimations();
- CSSAnimationDataList* accessTransitions();
-
- bool hasAnimations() const { return rareNonInheritedData->m_animations && rareNonInheritedData->m_animations->size() > 0; }
-
- // return the first found Animation (including 'all' transitions)
- const CSSAnimationData* transitionForProperty(CSSPropertyID) const;
+ CSSAnimationData& accessAnimations();
+ CSSTransitionData& accessTransitions();
ETransformStyle3D transformStyle3D() const { return static_cast<ETransformStyle3D>(rareNonInheritedData->m_transformStyle3D); }
bool preserves3D() const { return rareNonInheritedData->m_transformStyle3D == TransformStyle3DPreserve3D; }
@@ -897,13 +914,20 @@ public:
EBackfaceVisibility backfaceVisibility() const { return static_cast<EBackfaceVisibility>(rareNonInheritedData->m_backfaceVisibility); }
float perspective() const { return rareNonInheritedData->m_perspective; }
bool hasPerspective() const { return rareNonInheritedData->m_perspective > 0; }
- Length perspectiveOriginX() const { return rareNonInheritedData->m_perspectiveOriginX; }
- Length perspectiveOriginY() const { return rareNonInheritedData->m_perspectiveOriginY; }
- LengthSize pageSize() const { return rareNonInheritedData->m_pageSize; }
+ const Length& perspectiveOriginX() const { return rareNonInheritedData->m_perspectiveOriginX; }
+ const Length& perspectiveOriginY() const { return rareNonInheritedData->m_perspectiveOriginY; }
+ const LengthSize& pageSize() const { return rareNonInheritedData->m_pageSize; }
PageSizeType pageSizeType() const { return static_cast<PageSizeType>(rareNonInheritedData->m_pageSizeType); }
- // When set, this ensures that styles compare as different. Used during accelerated animations.
- bool isRunningAcceleratedAnimation() const { return rareNonInheritedData->m_runningAcceleratedAnimation; }
+ bool hasCurrentOpacityAnimation() const { return rareNonInheritedData->m_hasCurrentOpacityAnimation; }
+ bool hasCurrentTransformAnimation() const { return rareNonInheritedData->m_hasCurrentTransformAnimation; }
+ bool hasCurrentFilterAnimation() const { return rareNonInheritedData->m_hasCurrentFilterAnimation; }
+ bool shouldCompositeForCurrentAnimations() { return hasCurrentOpacityAnimation() || hasCurrentTransformAnimation() || hasCurrentFilterAnimation(); }
+
+ bool isRunningOpacityAnimationOnCompositor() const { return rareNonInheritedData->m_runningOpacityAnimationOnCompositor; }
+ bool isRunningTransformAnimationOnCompositor() const { return rareNonInheritedData->m_runningTransformAnimationOnCompositor; }
+ bool isRunningFilterAnimationOnCompositor() const { return rareNonInheritedData->m_runningFilterAnimationOnCompositor; }
+ bool isRunningAnimationOnCompositor() { return isRunningOpacityAnimationOnCompositor() || isRunningTransformAnimationOnCompositor() || isRunningFilterAnimationOnCompositor(); }
LineBoxContain lineBoxContain() const { return rareInheritedData->m_lineBoxContain; }
const LineClampValue& lineClamp() const { return rareNonInheritedData->lineClamp; }
@@ -936,6 +960,14 @@ public:
TouchAction touchAction() const { return static_cast<TouchAction>(rareNonInheritedData->m_touchAction); }
TouchActionDelay touchActionDelay() const { return static_cast<TouchActionDelay>(rareInheritedData->m_touchActionDelay); }
+ ScrollBehavior scrollBehavior() const { return static_cast<ScrollBehavior>(rareNonInheritedData->m_scrollBehavior); }
+
+ const Vector<CSSPropertyID>& willChangeProperties() const { return rareNonInheritedData->m_willChange->m_properties; }
+ bool willChangeContents() const { return rareNonInheritedData->m_willChange->m_contents; }
+ bool willChangeScrollPosition() const { return rareNonInheritedData->m_willChange->m_scrollPosition; }
+ bool hasWillChangeCompositingHint() const;
+ bool subtreeWillChangeContents() const { return rareInheritedData->m_subtreeWillChangeContents; }
+
// attribute setter methods
void setDisplay(EDisplay v) { noninherited_flags._effectiveDisplay = v; }
@@ -943,15 +975,15 @@ public:
void setPosition(EPosition v) { noninherited_flags._position = v; }
void setFloating(EFloat v) { noninherited_flags._floating = v; }
- void setLeft(Length v) { SET_VAR(surround, offset.m_left, v); }
- void setRight(Length v) { SET_VAR(surround, offset.m_right, v); }
- void setTop(Length v) { SET_VAR(surround, offset.m_top, v); }
- void setBottom(Length v) { SET_VAR(surround, offset.m_bottom, v); }
+ void setLeft(const Length& v) { SET_VAR(surround, offset.m_left, v); }
+ void setRight(const Length& v) { SET_VAR(surround, offset.m_right, v); }
+ void setTop(const Length& v) { SET_VAR(surround, offset.m_top, v); }
+ void setBottom(const Length& v) { SET_VAR(surround, offset.m_bottom, v); }
- void setWidth(Length v) { SET_VAR(m_box, m_width, v); }
- void setHeight(Length v) { SET_VAR(m_box, m_height, v); }
+ void setWidth(const Length& v) { SET_VAR(m_box, m_width, v); }
+ void setHeight(const Length& v) { SET_VAR(m_box, m_height, v); }
- void setLogicalWidth(Length v)
+ void setLogicalWidth(const Length& v)
{
if (isHorizontalWritingMode()) {
SET_VAR(m_box, m_width, v);
@@ -960,7 +992,7 @@ public:
}
}
- void setLogicalHeight(Length v)
+ void setLogicalHeight(const Length& v)
{
if (isHorizontalWritingMode()) {
SET_VAR(m_box, m_height, v);
@@ -969,45 +1001,55 @@ public:
}
}
- void setMinWidth(Length v) { SET_VAR(m_box, m_minWidth, v); }
- void setMaxWidth(Length v) { SET_VAR(m_box, m_maxWidth, v); }
- void setMinHeight(Length v) { SET_VAR(m_box, m_minHeight, v); }
- void setMaxHeight(Length v) { SET_VAR(m_box, m_maxHeight, v); }
+ void setMinWidth(const Length& v) { SET_VAR(m_box, m_minWidth, v); }
+ void setMaxWidth(const Length& v) { SET_VAR(m_box, m_maxWidth, v); }
+ void setMinHeight(const Length& v) { SET_VAR(m_box, m_minHeight, v); }
+ void setMaxHeight(const Length& v) { SET_VAR(m_box, m_maxHeight, v); }
DraggableRegionMode getDraggableRegionMode() const { return rareNonInheritedData->m_draggableRegionMode; }
void setDraggableRegionMode(DraggableRegionMode v) { SET_VAR(rareNonInheritedData, m_draggableRegionMode, v); }
- void resetBorder() { resetBorderImage(); resetBorderTop(); resetBorderRight(); resetBorderBottom(); resetBorderLeft(); resetBorderRadius(); }
+ void resetBorder()
+ {
+ resetBorderImage();
+ resetBorderTop();
+ resetBorderRight();
+ resetBorderBottom();
+ resetBorderLeft();
+ resetBorderTopLeftRadius();
+ resetBorderTopRightRadius();
+ resetBorderBottomLeftRadius();
+ resetBorderBottomRightRadius();
+ }
void resetBorderTop() { SET_VAR(surround, border.m_top, BorderValue()); }
void resetBorderRight() { SET_VAR(surround, border.m_right, BorderValue()); }
void resetBorderBottom() { SET_VAR(surround, border.m_bottom, BorderValue()); }
void resetBorderLeft() { SET_VAR(surround, border.m_left, BorderValue()); }
void resetBorderImage() { SET_VAR(surround, border.m_image, NinePieceImage()); }
- void resetBorderRadius() { resetBorderTopLeftRadius(); resetBorderTopRightRadius(); resetBorderBottomLeftRadius(); resetBorderBottomRightRadius(); }
void resetBorderTopLeftRadius() { SET_VAR(surround, border.m_topLeft, initialBorderRadius()); }
void resetBorderTopRightRadius() { SET_VAR(surround, border.m_topRight, initialBorderRadius()); }
void resetBorderBottomLeftRadius() { SET_VAR(surround, border.m_bottomLeft, initialBorderRadius()); }
void resetBorderBottomRightRadius() { SET_VAR(surround, border.m_bottomRight, initialBorderRadius()); }
- void setBackgroundColor(const Color& v) { SET_VAR(m_background, m_color, v); }
+ void setBackgroundColor(const StyleColor& v) { SET_VAR(m_background, m_color, v); }
- void setBackgroundXPosition(Length length) { SET_VAR(m_background, m_background.m_xPosition, length); }
- void setBackgroundYPosition(Length length) { SET_VAR(m_background, m_background.m_yPosition, length); }
+ void setBackgroundXPosition(const Length& length) { SET_VAR(m_background, m_background.m_xPosition, length); }
+ void setBackgroundYPosition(const Length& length) { SET_VAR(m_background, m_background.m_yPosition, length); }
void setBackgroundSize(EFillSizeType b) { SET_VAR(m_background, m_background.m_sizeType, b); }
- void setBackgroundSizeLength(LengthSize s) { SET_VAR(m_background, m_background.m_sizeLength, s); }
+ void setBackgroundSizeLength(const LengthSize& s) { SET_VAR(m_background, m_background.m_sizeLength, s); }
void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.m_image, b); }
void setBorderImageSource(PassRefPtr<StyleImage>);
- void setBorderImageSlices(LengthBox);
+ void setBorderImageSlices(const LengthBox&);
void setBorderImageWidth(const BorderImageLengthBox&);
void setBorderImageOutset(const BorderImageLengthBox&);
- void setBorderTopLeftRadius(LengthSize s) { SET_VAR(surround, border.m_topLeft, s); }
- void setBorderTopRightRadius(LengthSize s) { SET_VAR(surround, border.m_topRight, s); }
- void setBorderBottomLeftRadius(LengthSize s) { SET_VAR(surround, border.m_bottomLeft, s); }
- void setBorderBottomRightRadius(LengthSize s) { SET_VAR(surround, border.m_bottomRight, s); }
+ void setBorderTopLeftRadius(const LengthSize& s) { SET_VAR(surround, border.m_topLeft, s); }
+ void setBorderTopRightRadius(const LengthSize& s) { SET_VAR(surround, border.m_topRight, s); }
+ void setBorderBottomLeftRadius(const LengthSize& s) { SET_VAR(surround, border.m_bottomLeft, s); }
+ void setBorderBottomRightRadius(const LengthSize& s) { SET_VAR(surround, border.m_bottomRight, s); }
- void setBorderRadius(LengthSize s)
+ void setBorderRadius(const LengthSize& s)
{
setBorderTopLeftRadius(s);
setBorderTopRightRadius(s);
@@ -1019,7 +1061,7 @@ public:
setBorderRadius(LengthSize(Length(s.width(), Fixed), Length(s.height(), Fixed)));
}
- RoundedRect getRoundedBorderFor(const LayoutRect& borderRect, RenderView* = 0, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const;
+ RoundedRect getRoundedBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const;
RoundedRect getRoundedInnerBorderFor(const LayoutRect& borderRect, bool includeLogicalLeftEdge = true, bool includeLogicalRightEdge = true) const;
RoundedRect getRoundedInnerBorderFor(const LayoutRect& borderRect,
@@ -1027,35 +1069,35 @@ public:
void setBorderLeftWidth(unsigned v) { SET_VAR(surround, border.m_left.m_width, v); }
void setBorderLeftStyle(EBorderStyle v) { SET_VAR(surround, border.m_left.m_style, v); }
- void setBorderLeftColor(const Color& v) { SET_BORDERVALUE_COLOR(surround, border.m_left, v); }
+ void setBorderLeftColor(const StyleColor& v) { SET_BORDERVALUE_COLOR(surround, border.m_left, v); }
void setBorderRightWidth(unsigned v) { SET_VAR(surround, border.m_right.m_width, v); }
void setBorderRightStyle(EBorderStyle v) { SET_VAR(surround, border.m_right.m_style, v); }
- void setBorderRightColor(const Color& v) { SET_BORDERVALUE_COLOR(surround, border.m_right, v); }
+ void setBorderRightColor(const StyleColor& v) { SET_BORDERVALUE_COLOR(surround, border.m_right, v); }
void setBorderTopWidth(unsigned v) { SET_VAR(surround, border.m_top.m_width, v); }
void setBorderTopStyle(EBorderStyle v) { SET_VAR(surround, border.m_top.m_style, v); }
- void setBorderTopColor(const Color& v) { SET_BORDERVALUE_COLOR(surround, border.m_top, v); }
+ void setBorderTopColor(const StyleColor& v) { SET_BORDERVALUE_COLOR(surround, border.m_top, v); }
void setBorderBottomWidth(unsigned v) { SET_VAR(surround, border.m_bottom.m_width, v); }
void setBorderBottomStyle(EBorderStyle v) { SET_VAR(surround, border.m_bottom.m_style, v); }
- void setBorderBottomColor(const Color& v) { SET_BORDERVALUE_COLOR(surround, border.m_bottom, v); }
+ void setBorderBottomColor(const StyleColor& v) { SET_BORDERVALUE_COLOR(surround, border.m_bottom, v); }
void setOutlineWidth(unsigned short v) { SET_VAR(m_background, m_outline.m_width, v); }
void setOutlineStyleIsAuto(OutlineIsAuto isAuto) { SET_VAR(m_background, m_outline.m_isAuto, isAuto); }
void setOutlineStyle(EBorderStyle v) { SET_VAR(m_background, m_outline.m_style, v); }
- void setOutlineColor(const Color& v) { SET_BORDERVALUE_COLOR(m_background, m_outline, v); }
+ void setOutlineColor(const StyleColor& v) { SET_BORDERVALUE_COLOR(m_background, m_outline, v); }
void setOverflowX(EOverflow v) { noninherited_flags._overflowX = v; }
void setOverflowY(EOverflow v) { noninherited_flags._overflowY = v; }
void setVisibility(EVisibility v) { inherited_flags._visibility = v; }
void setVerticalAlign(EVerticalAlign v) { noninherited_flags._vertical_align = v; }
- void setVerticalAlignLength(Length length) { setVerticalAlign(LENGTH); SET_VAR(m_box, m_verticalAlign, length); }
+ void setVerticalAlignLength(const Length& length) { setVerticalAlign(LENGTH); SET_VAR(m_box, m_verticalAlign, length); }
void setHasClip(bool b = true) { SET_VAR(visual, hasClip, b); }
- void setClipLeft(Length v) { SET_VAR(visual, clip.m_left, v); }
- void setClipRight(Length v) { SET_VAR(visual, clip.m_right, v); }
- void setClipTop(Length v) { SET_VAR(visual, clip.m_top, v); }
- void setClipBottom(Length v) { SET_VAR(visual, clip.m_bottom, v); }
- void setClip(Length top, Length right, Length bottom, Length left);
- void setClip(LengthBox box) { SET_VAR(visual, clip, box); }
+ void setClipLeft(const Length& v) { SET_VAR(visual, clip.m_left, v); }
+ void setClipRight(const Length& v) { SET_VAR(visual, clip.m_right, v); }
+ void setClipTop(const Length& v) { SET_VAR(visual, clip.m_top, v); }
+ void setClipBottom(const Length& v) { SET_VAR(visual, clip.m_bottom, v); }
+ void setClip(const Length& top, const Length& right, const Length& bottom, const Length& left);
+ void setClip(const LengthBox& box) { SET_VAR(visual, clip, box); }
void setUnicodeBidi(EUnicodeBidi b) { noninherited_flags._unicodeBidi = b; }
@@ -1065,41 +1107,40 @@ public:
bool setFontDescription(const FontDescription&);
// Only used for blending font sizes when animating and for text autosizing.
void setFontSize(float);
+ void setFontWeight(FontWeight);
void setTextAutosizingMultiplier(float v)
{
- SET_VAR(visual, m_textAutosizingMultiplier, v);
+ SET_VAR(inherited, textAutosizingMultiplier, v);
setFontSize(fontDescription().specifiedSize());
}
void setColor(const Color&);
- void setTextIndent(Length v) { SET_VAR(rareInheritedData, indent, v); }
+ void setTextIndent(const Length& v) { SET_VAR(rareInheritedData, indent, v); }
void setTextIndentLine(TextIndentLine v) { SET_VAR(rareInheritedData, m_textIndentLine, v); }
+ void setTextIndentType(TextIndentType v) { SET_VAR(rareInheritedData, m_textIndentType, v); }
void setTextAlign(ETextAlign v) { inherited_flags._text_align = v; }
void setTextAlignLast(TextAlignLast v) { SET_VAR(rareInheritedData, m_textAlignLast, v); }
void setTextJustify(TextJustify v) { SET_VAR(rareInheritedData, m_textJustify, v); }
void setTextTransform(ETextTransform v) { inherited_flags._text_transform = v; }
- void addToTextDecorationsInEffect(TextDecoration v) { inherited_flags._text_decorations |= v; }
- void setTextDecorationsInEffect(TextDecoration v) { inherited_flags._text_decorations = v; }
+ void applyTextDecorations();
+ void clearAppliedTextDecorations();
void setTextDecoration(TextDecoration v) { SET_VAR(visual, textDecoration, v); }
void setTextUnderlinePosition(TextUnderlinePosition v) { SET_VAR(rareInheritedData, m_textUnderlinePosition, v); }
void setTextDecorationStyle(TextDecorationStyle v) { SET_VAR(rareNonInheritedData, m_textDecorationStyle, v); }
void setDirection(TextDirection v) { inherited_flags._direction = v; }
- void setLineHeight(Length specifiedLineHeight);
+ void setLineHeight(const Length& specifiedLineHeight);
bool setZoom(float);
- void setZoomWithoutReturnValue(float f) { setZoom(f); }
bool setEffectiveZoom(float);
void setImageRendering(EImageRendering v) { SET_VAR(rareInheritedData, m_imageRendering, v); }
void setWhiteSpace(EWhiteSpace v) { inherited_flags._white_space = v; }
+ // FIXME: Remove these two and replace them with respective FontBuilder calls.
void setWordSpacing(float);
void setLetterSpacing(float);
- void clearBackgroundLayers() { m_background.access()->m_background = FillLayer(BackgroundFillLayer); }
- void inheritBackgroundLayers(const FillLayer& parent) { m_background.access()->m_background = parent; }
-
void adjustBackgroundLayers()
{
if (backgroundLayers()->next()) {
@@ -1108,9 +1149,6 @@ public:
}
}
- void clearMaskLayers() { rareNonInheritedData.access()->m_mask = FillLayer(MaskFillLayer); }
- void inheritMaskLayers(const FillLayer& parent) { rareNonInheritedData.access()->m_mask = parent; }
-
void adjustMaskLayers()
{
if (maskLayers()->next()) {
@@ -1123,7 +1161,7 @@ public:
void setMaskBoxImage(const NinePieceImage& b) { SET_VAR(rareNonInheritedData, m_maskBoxImage, b); }
void setMaskBoxImageSource(PassRefPtr<StyleImage> v) { rareNonInheritedData.access()->m_maskBoxImage.setImage(v); }
- void setMaskBoxImageSlices(LengthBox slices)
+ void setMaskBoxImageSlices(const LengthBox& slices)
{
rareNonInheritedData.access()->m_maskBoxImage.setImageSlices(slices);
}
@@ -1139,9 +1177,9 @@ public:
{
rareNonInheritedData.access()->m_maskBoxImage.setOutset(outset);
}
- void setMaskXPosition(Length length) { SET_VAR(rareNonInheritedData, m_mask.m_xPosition, length); }
- void setMaskYPosition(Length length) { SET_VAR(rareNonInheritedData, m_mask.m_yPosition, length); }
- void setMaskSize(LengthSize s) { SET_VAR(rareNonInheritedData, m_mask.m_sizeLength, s); }
+ void setMaskXPosition(const Length& length) { SET_VAR(rareNonInheritedData, m_mask.m_xPosition, length); }
+ void setMaskYPosition(const Length& length) { SET_VAR(rareNonInheritedData, m_mask.m_yPosition, length); }
+ void setMaskSize(const LengthSize& s) { SET_VAR(rareNonInheritedData, m_mask.m_sizeLength, s); }
void setBorderCollapse(EBorderCollapse collapse) { inherited_flags._border_collapse = collapse; }
void setHorizontalBorderSpacing(short);
@@ -1157,20 +1195,19 @@ public:
void setListStyleImage(PassRefPtr<StyleImage>);
void setListStylePosition(EListStylePosition v) { inherited_flags._list_style_position = v; }
- void resetMargin() { SET_VAR(surround, margin, LengthBox(Fixed)); }
- void setMarginTop(Length v) { SET_VAR(surround, margin.m_top, v); }
- void setMarginBottom(Length v) { SET_VAR(surround, margin.m_bottom, v); }
- void setMarginLeft(Length v) { SET_VAR(surround, margin.m_left, v); }
- void setMarginRight(Length v) { SET_VAR(surround, margin.m_right, v); }
- void setMarginStart(Length);
- void setMarginEnd(Length);
+ void setMarginTop(const Length& v) { SET_VAR(surround, margin.m_top, v); }
+ void setMarginBottom(const Length& v) { SET_VAR(surround, margin.m_bottom, v); }
+ void setMarginLeft(const Length& v) { SET_VAR(surround, margin.m_left, v); }
+ void setMarginRight(const Length& v) { SET_VAR(surround, margin.m_right, v); }
+ void setMarginStart(const Length&);
+ void setMarginEnd(const Length&);
void resetPadding() { SET_VAR(surround, padding, LengthBox(Auto)); }
void setPaddingBox(const LengthBox& b) { SET_VAR(surround, padding, b); }
- void setPaddingTop(Length v) { SET_VAR(surround, padding.m_top, v); }
- void setPaddingBottom(Length v) { SET_VAR(surround, padding.m_bottom, v); }
- void setPaddingLeft(Length v) { SET_VAR(surround, padding.m_left, v); }
- void setPaddingRight(Length v) { SET_VAR(surround, padding.m_right, v); }
+ void setPaddingTop(const Length& v) { SET_VAR(surround, padding.m_top, v); }
+ void setPaddingBottom(const Length& v) { SET_VAR(surround, padding.m_bottom, v); }
+ void setPaddingLeft(const Length& v) { SET_VAR(surround, padding.m_left, v); }
+ void setPaddingRight(const Length& v) { SET_VAR(surround, padding.m_right, v); }
void setCursor(ECursor c) { inherited_flags._cursor_style = c; }
void addCursor(PassRefPtr<StyleImage>, const IntPoint& hotSpot = IntPoint());
@@ -1202,9 +1239,9 @@ public:
// CSS3 Setters
void setOutlineOffset(int v) { SET_VAR(m_background, m_outline.m_offset, v); }
void setTextShadow(PassRefPtr<ShadowList>);
- void setTextStrokeColor(const Color& c) { SET_VAR(rareInheritedData, textStrokeColor, c); }
+ void setTextStrokeColor(const StyleColor& c) { SET_VAR_WITH_SETTER(rareInheritedData, textStrokeColor, setTextStrokeColor, c); }
void setTextStrokeWidth(float w) { SET_VAR(rareInheritedData, textStrokeWidth, w); }
- void setTextFillColor(const Color& c) { SET_VAR(rareInheritedData, textFillColor, c); }
+ void setTextFillColor(const StyleColor& c) { SET_VAR_WITH_SETTER(rareInheritedData, textFillColor, setTextFillColor, c); }
void setOpacity(float f) { float v = clampTo<float>(f, 0, 1); SET_VAR(rareNonInheritedData, opacity, v); }
void setAppearance(ControlPart a) { SET_VAR(rareNonInheritedData, m_appearance, a); }
// For valid values of box-align see http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/#alignment
@@ -1212,9 +1249,9 @@ public:
void setBoxDecorationBreak(EBoxDecorationBreak b) { SET_VAR(m_box, m_boxDecorationBreak, b); }
void setBoxDirection(EBoxDirection d) { inherited_flags._box_direction = d; }
void setBoxFlex(float f) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, flex, f); }
- void setBoxFlexGroup(unsigned int fg) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, flex_group, fg); }
+ void setBoxFlexGroup(unsigned fg) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, flexGroup, fg); }
void setBoxLines(EBoxLines l) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, lines, l); }
- void setBoxOrdinalGroup(unsigned int og) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, ordinal_group, og); }
+ void setBoxOrdinalGroup(unsigned og) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, ordinalGroup, og); }
void setBoxOrient(EBoxOrient o) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, orient, o); }
void setBoxPack(EBoxPack p) { SET_VAR(rareNonInheritedData.access()->m_deprecatedFlexibleBox, pack, p); }
void setBoxShadow(PassRefPtr<ShadowList>);
@@ -1222,19 +1259,24 @@ public:
void setBoxSizing(EBoxSizing s) { SET_VAR(m_box, m_boxSizing, s); }
void setFlexGrow(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexGrow, f); }
void setFlexShrink(float f) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexShrink, f); }
- void setFlexBasis(Length length) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexBasis, length); }
- void setOrder(int o) { SET_VAR(rareNonInheritedData, m_order, o); }
+ void setFlexBasis(const Length& length) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexBasis, length); }
+ // We restrict the smallest value to int min + 2 because we use int min and int min + 1 as special values in a hash set.
+ void setOrder(int o) { SET_VAR(rareNonInheritedData, m_order, max(std::numeric_limits<int>::min() + 2, o)); }
void addCallbackSelector(const String& selector);
void setAlignContent(EAlignContent p) { SET_VAR(rareNonInheritedData, m_alignContent, p); }
- void setAlignItems(EAlignItems a) { SET_VAR(rareNonInheritedData, m_alignItems, a); }
- void setAlignSelf(EAlignItems a) { SET_VAR(rareNonInheritedData, m_alignSelf, a); }
+ void setAlignItems(ItemPosition a) { SET_VAR(rareNonInheritedData, m_alignItems, a); }
+ void setAlignItemsOverflowAlignment(OverflowAlignment overflowAlignment) { SET_VAR(rareNonInheritedData, m_alignItemsOverflowAlignment, overflowAlignment); }
+ void setAlignSelf(ItemPosition a) { SET_VAR(rareNonInheritedData, m_alignSelf, a); }
+ void setAlignSelfOverflowAlignment(OverflowAlignment overflowAlignment) { SET_VAR(rareNonInheritedData, m_alignSelfOverflowAlignment, overflowAlignment); }
void setFlexDirection(EFlexDirection direction) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexDirection, direction); }
void setFlexWrap(EFlexWrap w) { SET_VAR(rareNonInheritedData.access()->m_flexibleBox, m_flexWrap, w); }
void setJustifyContent(EJustifyContent p) { SET_VAR(rareNonInheritedData, m_justifyContent, p); }
+ void setJustifySelf(ItemPosition justifySelf) { SET_VAR(rareNonInheritedData, m_justifySelf, justifySelf); }
+ void setJustifySelfOverflowAlignment(OverflowAlignment overflowAlignment) { SET_VAR(rareNonInheritedData, m_justifySelfOverflowAlignment, overflowAlignment); }
void setGridAutoColumns(const GridTrackSize& length) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridAutoColumns, length); }
void setGridAutoRows(const GridTrackSize& length) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridAutoRows, length); }
- void setGridDefinitionColumns(const Vector<GridTrackSize>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridDefinitionColumns, lengths); }
- void setGridDefinitionRows(const Vector<GridTrackSize>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridDefinitionRows, lengths); }
+ void setGridTemplateColumns(const Vector<GridTrackSize>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridTemplateColumns, lengths); }
+ void setGridTemplateRows(const Vector<GridTrackSize>& lengths) { SET_VAR(rareNonInheritedData.access()->m_grid, m_gridTemplateRows, lengths); }
void setNamedGridColumnLines(const NamedGridLinesMap& namedGridColumnLines) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridColumnLines, namedGridColumnLines); }
void setNamedGridRowLines(const NamedGridLinesMap& namedGridRowLines) { SET_VAR(rareNonInheritedData.access()->m_grid, m_namedGridRowLines, namedGridRowLines); }
void setOrderedNamedGridColumnLines(const OrderedNamedGridLines& orderedNamedGridColumnLines) { SET_VAR(rareNonInheritedData.access()->m_grid, m_orderedNamedGridColumnLines, orderedNamedGridColumnLines); }
@@ -1249,7 +1291,7 @@ public:
void setGridRowStart(const GridPosition& rowStartPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridRowStart, rowStartPosition); }
void setGridRowEnd(const GridPosition& rowEndPosition) { SET_VAR(rareNonInheritedData.access()->m_gridItem, m_gridRowEnd, rowEndPosition); }
- void setMarqueeIncrement(Length f) { SET_VAR(rareNonInheritedData.access()->m_marquee, increment, f); }
+ void setMarqueeIncrement(const Length& f) { SET_VAR(rareNonInheritedData.access()->m_marquee, increment, f); }
void setMarqueeSpeed(int f) { SET_VAR(rareNonInheritedData.access()->m_marquee, speed, f); }
void setMarqueeDirection(EMarqueeDirection d) { SET_VAR(rareNonInheritedData.access()->m_marquee, direction, d); }
void setMarqueeBehavior(EMarqueeBehavior b) { SET_VAR(rareNonInheritedData.access()->m_marquee, behavior, b); }
@@ -1269,8 +1311,6 @@ public:
void setLocale(const AtomicString& locale) { SET_VAR(rareInheritedData, locale, locale); }
void setBorderFit(EBorderFit b) { SET_VAR(rareNonInheritedData, m_borderFit, b); }
void setResize(EResize r) { SET_VAR(rareInheritedData, resize, r); }
- void setColumnAxis(ColumnAxis axis) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_axis, axis); }
- void setColumnProgression(ColumnProgression progression) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_progression, progression); }
void setColumnWidth(float f) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoWidth, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_width, f); }
void setHasAutoColumnWidth() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoWidth, true); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_width, 0); }
void setColumnCount(unsigned short c) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_autoCount, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_count, c); }
@@ -1278,7 +1318,7 @@ public:
void setColumnFill(ColumnFill columnFill) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_fill, columnFill); }
void setColumnGap(float f) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_normalGap, false); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_gap, f); }
void setHasNormalColumnGap() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_normalGap, true); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_gap, 0); }
- void setColumnRuleColor(const Color& c) { SET_BORDERVALUE_COLOR(rareNonInheritedData.access()->m_multiCol, m_rule, c); }
+ void setColumnRuleColor(const StyleColor& c) { SET_BORDERVALUE_COLOR(rareNonInheritedData.access()->m_multiCol, m_rule, c); }
void setColumnRuleStyle(EBorderStyle b) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.m_style, b); }
void setColumnRuleWidth(unsigned short w) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule.m_width, w); }
void resetColumnRule() { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_rule, BorderValue()); }
@@ -1287,18 +1327,15 @@ public:
// For valid values of column-break-inside see http://www.w3.org/TR/css3-multicol/#break-before-break-after-break-inside
void setColumnBreakInside(EPageBreak p) { ASSERT(p == PBAUTO || p == PBAVOID); SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakInside, p); }
void setColumnBreakAfter(EPageBreak p) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_breakAfter, p); }
- void setRegionBreakBefore(EPageBreak p) { SET_VAR(rareNonInheritedData, m_regionBreakBefore, p); }
- void setRegionBreakInside(EPageBreak p) { ASSERT(p == PBAUTO || p == PBAVOID); SET_VAR(rareNonInheritedData, m_regionBreakInside, p); }
- void setRegionBreakAfter(EPageBreak p) { SET_VAR(rareNonInheritedData, m_regionBreakAfter, p); }
void inheritColumnPropertiesFrom(RenderStyle* parent) { rareNonInheritedData.access()->m_multiCol = parent->rareNonInheritedData->m_multiCol; }
void setTransform(const TransformOperations& ops) { SET_VAR(rareNonInheritedData.access()->m_transform, m_operations, ops); }
- void setTransformOriginX(Length l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_x, l); }
- void setTransformOriginY(Length l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_y, l); }
+ void setTransformOriginX(const Length& l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_x, l); }
+ void setTransformOriginY(const Length& l) { SET_VAR(rareNonInheritedData.access()->m_transform, m_y, l); }
void setTransformOriginZ(float f) { SET_VAR(rareNonInheritedData.access()->m_transform, m_z, f); }
void setSpeak(ESpeak s) { SET_VAR(rareInheritedData, speak, s); }
void setTextCombine(TextCombine v) { SET_VAR(rareNonInheritedData, m_textCombine, v); }
- void setTextDecorationColor(const Color& c) { SET_VAR(rareNonInheritedData, m_textDecorationColor, c); }
- void setTextEmphasisColor(const Color& c) { SET_VAR(rareInheritedData, textEmphasisColor, c); }
+ void setTextDecorationColor(const StyleColor& c) { SET_VAR(rareNonInheritedData, m_textDecorationColor, c); }
+ void setTextEmphasisColor(const StyleColor& c) { SET_VAR_WITH_SETTER(rareInheritedData, textEmphasisColor, setTextEmphasisColor, c); }
void setTextEmphasisFill(TextEmphasisFill fill) { SET_VAR(rareInheritedData, textEmphasisFill, fill); }
void setTextEmphasisMark(TextEmphasisMark mark) { SET_VAR(rareInheritedData, textEmphasisMark, mark); }
void setTextEmphasisCustomMark(const AtomicString& mark) { SET_VAR(rareInheritedData, textEmphasisCustomMark, mark); }
@@ -1316,14 +1353,6 @@ public:
// End CSS3 Setters
- void setLineGrid(const AtomicString& lineGrid) { SET_VAR(rareInheritedData, m_lineGrid, lineGrid); }
- void setLineSnap(LineSnap lineSnap) { SET_VAR(rareInheritedData, m_lineSnap, lineSnap); }
- void setLineAlign(LineAlign lineAlign) { SET_VAR(rareInheritedData, m_lineAlign, lineAlign); }
-
- void setFlowThread(const AtomicString& flowThread) { SET_VAR(rareNonInheritedData, m_flowThread, flowThread); }
- void setRegionThread(const AtomicString& regionThread) { SET_VAR(rareNonInheritedData, m_regionThread, regionThread); }
- void setRegionFragment(RegionFragment regionFragment) { SET_VAR(rareNonInheritedData, m_regionFragment, regionFragment); }
-
void setWrapFlow(WrapFlow wrapFlow) { SET_VAR(rareNonInheritedData, m_wrapFlow, wrapFlow); }
void setWrapThrough(WrapThrough wrapThrough) { SET_VAR(rareNonInheritedData, m_wrapThrough, wrapThrough); }
@@ -1340,19 +1369,22 @@ public:
rareNonInheritedData.access()->m_transitions.clear();
}
- void adjustAnimations();
- void adjustTransitions();
-
void setTransformStyle3D(ETransformStyle3D b) { SET_VAR(rareNonInheritedData, m_transformStyle3D, b); }
void setBackfaceVisibility(EBackfaceVisibility b) { SET_VAR(rareNonInheritedData, m_backfaceVisibility, b); }
void setPerspective(float p) { SET_VAR(rareNonInheritedData, m_perspective, p); }
- void setPerspectiveOriginX(Length l) { SET_VAR(rareNonInheritedData, m_perspectiveOriginX, l); }
- void setPerspectiveOriginY(Length l) { SET_VAR(rareNonInheritedData, m_perspectiveOriginY, l); }
- void setPageSize(LengthSize s) { SET_VAR(rareNonInheritedData, m_pageSize, s); }
+ void setPerspectiveOriginX(const Length& l) { SET_VAR(rareNonInheritedData, m_perspectiveOriginX, l); }
+ void setPerspectiveOriginY(const Length& l) { SET_VAR(rareNonInheritedData, m_perspectiveOriginY, l); }
+ void setPageSize(const LengthSize& s) { SET_VAR(rareNonInheritedData, m_pageSize, s); }
void setPageSizeType(PageSizeType t) { SET_VAR(rareNonInheritedData, m_pageSizeType, t); }
void resetPageSizeType() { SET_VAR(rareNonInheritedData, m_pageSizeType, PAGE_SIZE_AUTO); }
- void setIsRunningAcceleratedAnimation(bool b = true) { SET_VAR(rareNonInheritedData, m_runningAcceleratedAnimation, b); }
+ void setHasCurrentOpacityAnimation(bool b = true) { SET_VAR(rareNonInheritedData, m_hasCurrentOpacityAnimation, b); }
+ void setHasCurrentTransformAnimation(bool b = true) { SET_VAR(rareNonInheritedData, m_hasCurrentTransformAnimation, b); }
+ void setHasCurrentFilterAnimation(bool b = true) { SET_VAR(rareNonInheritedData, m_hasCurrentFilterAnimation, b); }
+
+ void setIsRunningOpacityAnimationOnCompositor(bool b = true) { SET_VAR(rareNonInheritedData, m_runningOpacityAnimationOnCompositor, b); }
+ void setIsRunningTransformAnimationOnCompositor(bool b = true) { SET_VAR(rareNonInheritedData, m_runningTransformAnimationOnCompositor, b); }
+ void setIsRunningFilterAnimationOnCompositor(bool b = true) { SET_VAR(rareNonInheritedData, m_runningFilterAnimationOnCompositor, b); }
void setLineBoxContain(LineBoxContain c) { SET_VAR(rareInheritedData, m_lineBoxContain, c); }
void setLineClamp(LineClampValue c) { SET_VAR(rareNonInheritedData, lineClamp, c); }
@@ -1361,6 +1393,16 @@ public:
void setTouchAction(TouchAction t) { SET_VAR(rareNonInheritedData, m_touchAction, t); }
void setTouchActionDelay(TouchActionDelay t) { SET_VAR(rareInheritedData, m_touchActionDelay, t); }
+ void setScrollBehavior(ScrollBehavior b) { SET_VAR(rareNonInheritedData, m_scrollBehavior, b); }
+
+ void setWillChangeProperties(const Vector<CSSPropertyID>& properties) { SET_VAR(rareNonInheritedData.access()->m_willChange, m_properties, properties); }
+ void setWillChangeContents(bool b) { SET_VAR(rareNonInheritedData.access()->m_willChange, m_contents, b); }
+ void setWillChangeScrollPosition(bool b) { SET_VAR(rareNonInheritedData.access()->m_willChange, m_scrollPosition, b); }
+ void setSubtreeWillChangeContents(bool b) { SET_VAR(rareInheritedData, m_subtreeWillChangeContents, b); }
+
+ bool requiresAcceleratedCompositingForExternalReasons(bool b) { return rareNonInheritedData->m_requiresAcceleratedCompositingForExternalReasons; }
+ void setRequiresAcceleratedCompositingForExternalReasons(bool b) { SET_VAR(rareNonInheritedData, m_requiresAcceleratedCompositingForExternalReasons, b); }
+
const SVGRenderStyle* svgStyle() const { return m_svgStyle.get(); }
SVGRenderStyle* accessSVGStyle() { return m_svgStyle.access(); }
@@ -1375,12 +1417,12 @@ public:
void setStrokePaintColor(const Color& c) { accessSVGStyle()->setStrokePaint(SVGPaint::SVG_PAINTTYPE_RGBCOLOR, c, ""); }
float strokeOpacity() const { return svgStyle()->strokeOpacity(); }
void setStrokeOpacity(float f) { accessSVGStyle()->setStrokeOpacity(f); }
- SVGLength strokeWidth() const { return svgStyle()->strokeWidth(); }
- void setStrokeWidth(SVGLength w) { accessSVGStyle()->setStrokeWidth(w); }
- Vector<SVGLength> strokeDashArray() const { return svgStyle()->strokeDashArray(); }
- void setStrokeDashArray(Vector<SVGLength> array) { accessSVGStyle()->setStrokeDashArray(array); }
- SVGLength strokeDashOffset() const { return svgStyle()->strokeDashOffset(); }
- void setStrokeDashOffset(SVGLength d) { accessSVGStyle()->setStrokeDashOffset(d); }
+ SVGLength* strokeWidth() const { return svgStyle()->strokeWidth(); }
+ void setStrokeWidth(PassRefPtr<SVGLength> w) { accessSVGStyle()->setStrokeWidth(w); }
+ SVGLengthList* strokeDashArray() const { return svgStyle()->strokeDashArray(); }
+ void setStrokeDashArray(PassRefPtr<SVGLengthList> array) { accessSVGStyle()->setStrokeDashArray(array); }
+ SVGLength* strokeDashOffset() const { return svgStyle()->strokeDashOffset(); }
+ void setStrokeDashOffset(PassRefPtr<SVGLength> d) { accessSVGStyle()->setStrokeDashOffset(d); }
float strokeMiterLimit() const { return svgStyle()->strokeMiterLimit(); }
void setStrokeMiterLimit(float f) { accessSVGStyle()->setStrokeMiterLimit(f); }
@@ -1394,25 +1436,8 @@ public:
void setFloodColor(const Color& c) { accessSVGStyle()->setFloodColor(c); }
void setLightingColor(const Color& c) { accessSVGStyle()->setLightingColor(c); }
- SVGLength baselineShiftValue() const { return svgStyle()->baselineShiftValue(); }
- void setBaselineShiftValue(SVGLength s) { accessSVGStyle()->setBaselineShiftValue(s); }
- SVGLength kerning() const { return svgStyle()->kerning(); }
- void setKerning(SVGLength k) { accessSVGStyle()->setKerning(k); }
-
- void setShapeInside(PassRefPtr<ShapeValue> value)
- {
- if (rareNonInheritedData->m_shapeInside == value)
- return;
- rareNonInheritedData.access()->m_shapeInside = value;
- }
- ShapeValue* shapeInside() const { return rareNonInheritedData->m_shapeInside.get(); }
- ShapeValue* resolvedShapeInside() const
- {
- ShapeValue* shapeInside = this->shapeInside();
- if (shapeInside && shapeInside->type() == ShapeValue::Outside)
- return shapeOutside();
- return shapeInside;
- }
+ SVGLength* baselineShiftValue() const { return svgStyle()->baselineShiftValue(); }
+ void setBaselineShiftValue(PassRefPtr<SVGLength> s) { accessSVGStyle()->setBaselineShiftValue(s); }
void setShapeOutside(PassRefPtr<ShapeValue> value)
{
@@ -1422,7 +1447,6 @@ public:
}
ShapeValue* shapeOutside() const { return rareNonInheritedData->m_shapeOutside.get(); }
- static ShapeValue* initialShapeInside() { return 0; }
static ShapeValue* initialShapeOutside() { return 0; }
void setClipPath(PassRefPtr<ClipPathOperation> operation)
@@ -1434,12 +1458,8 @@ public:
static ClipPathOperation* initialClipPath() { return 0; }
- Length shapePadding() const { return rareNonInheritedData->m_shapePadding; }
- void setShapePadding(Length shapePadding) { SET_VAR(rareNonInheritedData, m_shapePadding, shapePadding); }
- static Length initialShapePadding() { return Length(0, Fixed); }
-
- Length shapeMargin() const { return rareNonInheritedData->m_shapeMargin; }
- void setShapeMargin(Length shapeMargin) { SET_VAR(rareNonInheritedData, m_shapeMargin, shapeMargin); }
+ const Length& shapeMargin() const { return rareNonInheritedData->m_shapeMargin; }
+ void setShapeMargin(const Length& shapeMargin) { SET_VAR(rareNonInheritedData, m_shapeMargin, shapeMargin); }
static Length initialShapeMargin() { return Length(0, Fixed); }
float shapeImageThreshold() const { return rareNonInheritedData->m_shapeImageThreshold; }
@@ -1471,17 +1491,9 @@ public:
bool inheritedNotEqual(const RenderStyle*) const;
bool inheritedDataShared(const RenderStyle*) const;
- StyleDifference diff(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
-
bool isDisplayReplacedType() const { return isDisplayReplacedType(display()); }
bool isDisplayInlineType() const { return isDisplayInlineType(display()); }
bool isOriginalDisplayInlineType() const { return isDisplayInlineType(originalDisplay()); }
- bool isDisplayRegionType() const
- {
- return display() == BLOCK || display() == INLINE_BLOCK
- || display() == TABLE_CELL || display() == TABLE_CAPTION
- || display() == LIST_ITEM;
- }
bool setWritingMode(WritingMode v)
{
@@ -1505,6 +1517,8 @@ public:
bool lastChildState() const { return noninherited_flags.lastChildState; }
void setLastChildState() { setUnique(); noninherited_flags.lastChildState = true; }
+ StyleColor visitedDependentDecorationStyleColor() const;
+ Color visitedDependentDecorationColor() const;
Color visitedDependentColor(int colorProperty) const;
void setHasExplicitlyInheritedProperties() { noninherited_flags.explicitInheritance = true; }
@@ -1521,8 +1535,6 @@ public:
static LengthSize initialBorderRadius() { return LengthSize(Length(0, Fixed), Length(0, Fixed)); }
static ECaptionSide initialCaptionSide() { return CAPTOP; }
static EClear initialClear() { return CNONE; }
- static ColumnAxis initialColumnAxis() { return AutoColumnAxis; }
- static ColumnProgression initialColumnProgression() { return NormalColumnProgression; }
static TextDirection initialDirection() { return LTR; }
static WritingMode initialWritingMode() { return TopToBottomWritingMode; }
static TextCombine initialTextCombine() { return TextCombineNone; }
@@ -1560,6 +1572,7 @@ public:
static Length initialPadding() { return Length(Fixed); }
static Length initialTextIndent() { return Length(Fixed); }
static TextIndentLine initialTextIndentLine() { return TextIndentFirstLine; }
+ static TextIndentType initialTextIndentType() { return TextIndentNormal; }
static EVerticalAlign initialVerticalAlign() { return BASELINE; }
static short initialWidows() { return 2; }
static short initialOrphans() { return 2; }
@@ -1580,8 +1593,8 @@ public:
static EBoxOrient initialBoxOrient() { return HORIZONTAL; }
static EBoxPack initialBoxPack() { return Start; }
static float initialBoxFlex() { return 0.0f; }
- static unsigned int initialBoxFlexGroup() { return 1; }
- static unsigned int initialBoxOrdinalGroup() { return 1; }
+ static unsigned initialBoxFlexGroup() { return 1; }
+ static unsigned initialBoxOrdinalGroup() { return 1; }
static EBoxSizing initialBoxSizing() { return CONTENT_BOX; }
static StyleReflection* initialBoxReflect() { return 0; }
static float initialFlexGrow() { return 0; }
@@ -1589,11 +1602,15 @@ public:
static Length initialFlexBasis() { return Length(Auto); }
static int initialOrder() { return 0; }
static EAlignContent initialAlignContent() { return AlignContentStretch; }
- static EAlignItems initialAlignItems() { return AlignStretch; }
- static EAlignItems initialAlignSelf() { return AlignAuto; }
+ static ItemPosition initialAlignItems() { return ItemPositionStretch; }
+ static OverflowAlignment initialAlignItemsOverflowAlignment() { return OverflowAlignmentDefault; }
+ static ItemPosition initialAlignSelf() { return ItemPositionAuto; }
+ static OverflowAlignment initialAlignSelfOverflowAlignment() { return OverflowAlignmentDefault; }
static EFlexDirection initialFlexDirection() { return FlowRow; }
static EFlexWrap initialFlexWrap() { return FlexNoWrap; }
static EJustifyContent initialJustifyContent() { return JustifyFlexStart; }
+ static ItemPosition initialJustifySelf() { return ItemPositionAuto; }
+ static OverflowAlignment initialJustifySelfOverflowAlignment() { return OverflowAlignmentDefault; }
static int initialMarqueeLoopCount() { return -1; }
static int initialMarqueeSpeed() { return 85; }
static Length initialMarqueeIncrement() { return Length(6, Fixed); }
@@ -1653,15 +1670,16 @@ public:
static TouchActionDelay initialTouchActionDelay() { return TouchActionDelayScript; }
static ShadowList* initialBoxShadow() { return 0; }
static ShadowList* initialTextShadow() { return 0; }
+ static ScrollBehavior initialScrollBehavior() { return ScrollBehaviorInstant; }
// The initial value is 'none' for grid tracks.
- static Vector<GridTrackSize> initialGridDefinitionColumns() { return Vector<GridTrackSize>(); }
- static Vector<GridTrackSize> initialGridDefinitionRows() { return Vector<GridTrackSize>(); }
+ static Vector<GridTrackSize> initialGridTemplateColumns() { return Vector<GridTrackSize>(); }
+ static Vector<GridTrackSize> initialGridTemplateRows() { return Vector<GridTrackSize>(); }
static GridAutoFlow initialGridAutoFlow() { return AutoFlowNone; }
- static GridTrackSize initialGridAutoColumns() { return GridTrackSize(Auto); }
- static GridTrackSize initialGridAutoRows() { return GridTrackSize(Auto); }
+ static GridTrackSize initialGridAutoColumns() { return GridTrackSize(Length(Auto)); }
+ static GridTrackSize initialGridAutoRows() { return GridTrackSize(Length(Auto)); }
static NamedGridLinesMap initialNamedGridColumnLines() { return NamedGridLinesMap(); }
static NamedGridLinesMap initialNamedGridRowLines() { return NamedGridLinesMap(); }
@@ -1680,14 +1698,6 @@ public:
static unsigned initialTabSize() { return 8; }
- static const AtomicString& initialLineGrid() { return nullAtom; }
- static LineSnap initialLineSnap() { return LineSnapNone; }
- static LineAlign initialLineAlign() { return LineAlignNone; }
-
- static const AtomicString& initialFlowThread() { return nullAtom; }
- static const AtomicString& initialRegionThread() { return nullAtom; }
- static RegionFragment initialRegionFragment() { return AutoRegionFragment; }
-
static WrapFlow initialWrapFlow() { return WrapFlowAuto; }
static WrapThrough initialWrapThrough() { return WrapThroughWrap; }
@@ -1703,17 +1713,17 @@ public:
static EIsolation initialIsolation() { return IsolationAuto; }
private:
void setVisitedLinkColor(const Color&);
- void setVisitedLinkBackgroundColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBackgroundColor, v); }
- void setVisitedLinkBorderLeftColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderLeftColor, v); }
- void setVisitedLinkBorderRightColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderRightColor, v); }
- void setVisitedLinkBorderBottomColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderBottomColor, v); }
- void setVisitedLinkBorderTopColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderTopColor, v); }
- void setVisitedLinkOutlineColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkOutlineColor, v); }
- void setVisitedLinkColumnRuleColor(const Color& v) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_visitedLinkColumnRuleColor, v); }
- void setVisitedLinkTextDecorationColor(const Color& v) { SET_VAR(rareNonInheritedData, m_visitedLinkTextDecorationColor, v); }
- void setVisitedLinkTextEmphasisColor(const Color& v) { SET_VAR(rareInheritedData, visitedLinkTextEmphasisColor, v); }
- void setVisitedLinkTextFillColor(const Color& v) { SET_VAR(rareInheritedData, visitedLinkTextFillColor, v); }
- void setVisitedLinkTextStrokeColor(const Color& v) { SET_VAR(rareInheritedData, visitedLinkTextStrokeColor, v); }
+ void setVisitedLinkBackgroundColor(const StyleColor& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBackgroundColor, v); }
+ void setVisitedLinkBorderLeftColor(const StyleColor& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderLeftColor, v); }
+ void setVisitedLinkBorderRightColor(const StyleColor& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderRightColor, v); }
+ void setVisitedLinkBorderBottomColor(const StyleColor& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderBottomColor, v); }
+ void setVisitedLinkBorderTopColor(const StyleColor& v) { SET_VAR(rareNonInheritedData, m_visitedLinkBorderTopColor, v); }
+ void setVisitedLinkOutlineColor(const StyleColor& v) { SET_VAR(rareNonInheritedData, m_visitedLinkOutlineColor, v); }
+ void setVisitedLinkColumnRuleColor(const StyleColor& v) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_visitedLinkColumnRuleColor, v); }
+ void setVisitedLinkTextDecorationColor(const StyleColor& v) { SET_VAR(rareNonInheritedData, m_visitedLinkTextDecorationColor, v); }
+ void setVisitedLinkTextEmphasisColor(const StyleColor& v) { SET_VAR_WITH_SETTER(rareInheritedData, visitedLinkTextEmphasisColor, setVisitedLinkTextEmphasisColor, v); }
+ void setVisitedLinkTextFillColor(const StyleColor& v) { SET_VAR_WITH_SETTER(rareInheritedData, visitedLinkTextFillColor, setVisitedLinkTextFillColor, v); }
+ void setVisitedLinkTextStrokeColor(const StyleColor& v) { SET_VAR_WITH_SETTER(rareInheritedData, visitedLinkTextStrokeColor, setVisitedLinkTextStrokeColor, v); }
void inheritUnicodeBidiFrom(const RenderStyle* parent) { noninherited_flags._unicodeBidi = parent->noninherited_flags._unicodeBidi; }
void getShadowExtent(const ShadowList*, LayoutUnit& top, LayoutUnit& right, LayoutUnit& bottom, LayoutUnit& left) const;
@@ -1741,31 +1751,30 @@ private:
}
// Color accessors are all private to make sure callers use visitedDependentColor instead to access them.
- Color invalidColor() const { static Color invalid; return invalid; }
- Color borderLeftColor() const { return surround->border.left().color(); }
- Color borderRightColor() const { return surround->border.right().color(); }
- Color borderTopColor() const { return surround->border.top().color(); }
- Color borderBottomColor() const { return surround->border.bottom().color(); }
- Color backgroundColor() const { return m_background->color(); }
+ StyleColor borderLeftColor() const { return surround->border.left().color(); }
+ StyleColor borderRightColor() const { return surround->border.right().color(); }
+ StyleColor borderTopColor() const { return surround->border.top().color(); }
+ StyleColor borderBottomColor() const { return surround->border.bottom().color(); }
+ StyleColor backgroundColor() const { return m_background->color(); }
Color color() const;
- Color columnRuleColor() const { return rareNonInheritedData->m_multiCol->m_rule.color(); }
- Color outlineColor() const { return m_background->outline().color(); }
- Color textEmphasisColor() const { return rareInheritedData->textEmphasisColor; }
- Color textFillColor() const { return rareInheritedData->textFillColor; }
- Color textStrokeColor() const { return rareInheritedData->textStrokeColor; }
+ StyleColor columnRuleColor() const { return rareNonInheritedData->m_multiCol->m_rule.color(); }
+ StyleColor outlineColor() const { return m_background->outline().color(); }
+ StyleColor textEmphasisColor() const { return rareInheritedData->textEmphasisColor(); }
+ StyleColor textFillColor() const { return rareInheritedData->textFillColor(); }
+ StyleColor textStrokeColor() const { return rareInheritedData->textStrokeColor(); }
Color visitedLinkColor() const;
- Color visitedLinkBackgroundColor() const { return rareNonInheritedData->m_visitedLinkBackgroundColor; }
- Color visitedLinkBorderLeftColor() const { return rareNonInheritedData->m_visitedLinkBorderLeftColor; }
- Color visitedLinkBorderRightColor() const { return rareNonInheritedData->m_visitedLinkBorderRightColor; }
- Color visitedLinkBorderBottomColor() const { return rareNonInheritedData->m_visitedLinkBorderBottomColor; }
- Color visitedLinkBorderTopColor() const { return rareNonInheritedData->m_visitedLinkBorderTopColor; }
- Color visitedLinkOutlineColor() const { return rareNonInheritedData->m_visitedLinkOutlineColor; }
- Color visitedLinkColumnRuleColor() const { return rareNonInheritedData->m_multiCol->m_visitedLinkColumnRuleColor; }
- Color textDecorationColor() const { return rareNonInheritedData->m_textDecorationColor; }
- Color visitedLinkTextDecorationColor() const { return rareNonInheritedData->m_visitedLinkTextDecorationColor; }
- Color visitedLinkTextEmphasisColor() const { return rareInheritedData->visitedLinkTextEmphasisColor; }
- Color visitedLinkTextFillColor() const { return rareInheritedData->visitedLinkTextFillColor; }
- Color visitedLinkTextStrokeColor() const { return rareInheritedData->visitedLinkTextStrokeColor; }
+ StyleColor visitedLinkBackgroundColor() const { return rareNonInheritedData->m_visitedLinkBackgroundColor; }
+ StyleColor visitedLinkBorderLeftColor() const { return rareNonInheritedData->m_visitedLinkBorderLeftColor; }
+ StyleColor visitedLinkBorderRightColor() const { return rareNonInheritedData->m_visitedLinkBorderRightColor; }
+ StyleColor visitedLinkBorderBottomColor() const { return rareNonInheritedData->m_visitedLinkBorderBottomColor; }
+ StyleColor visitedLinkBorderTopColor() const { return rareNonInheritedData->m_visitedLinkBorderTopColor; }
+ StyleColor visitedLinkOutlineColor() const { return rareNonInheritedData->m_visitedLinkOutlineColor; }
+ StyleColor visitedLinkColumnRuleColor() const { return rareNonInheritedData->m_multiCol->m_visitedLinkColumnRuleColor; }
+ StyleColor textDecorationColor() const { return rareNonInheritedData->m_textDecorationColor; }
+ StyleColor visitedLinkTextDecorationColor() const { return rareNonInheritedData->m_visitedLinkTextDecorationColor; }
+ StyleColor visitedLinkTextEmphasisColor() const { return rareInheritedData->visitedLinkTextEmphasisColor(); }
+ StyleColor visitedLinkTextFillColor() const { return rareInheritedData->visitedLinkTextFillColor(); }
+ StyleColor visitedLinkTextStrokeColor() const { return rareInheritedData->visitedLinkTextStrokeColor(); }
Color colorIncludingFallback(int colorProperty, bool visitedLink) const;
@@ -1774,22 +1783,32 @@ private:
Color lightingColor() const { return svgStyle()->lightingColor(); }
void appendContent(PassOwnPtr<ContentData>);
- StyleDifference repaintOnlyDiff(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const;
+ void addAppliedTextDecoration(const AppliedTextDecoration&);
+
+ bool diffNeedsFullLayoutAndRepaint(const RenderStyle& other) const;
+ bool diffNeedsFullLayout(const RenderStyle& other) const;
+ bool diffNeedsRepaintLayer(const RenderStyle& other) const;
+ bool diffNeedsRepaintObject(const RenderStyle& other) const;
+ bool diffNeedsRecompositeLayer(const RenderStyle& other) const;
+ unsigned computeChangedContextSensitiveProperties(const RenderStyle& other, StyleDifference) const;
};
+// FIXME: Reduce/remove the dependency on zoom adjusted int values.
+// The float or LayoutUnit versions of layout values should be used.
inline int adjustForAbsoluteZoom(int value, float zoomFactor)
{
if (zoomFactor == 1)
return value;
// Needed because computeLengthInt truncates (rather than rounds) when scaling up.
+ float fvalue = value;
if (zoomFactor > 1) {
if (value < 0)
- value--;
+ fvalue -= 0.5f;
else
- value++;
+ fvalue += 0.5f;
}
- return roundForImpreciseConversion<int>(value / zoomFactor);
+ return roundForImpreciseConversion<int>(fvalue / zoomFactor);
}
inline int adjustForAbsoluteZoom(int value, const RenderStyle* style)
@@ -1802,6 +1821,11 @@ inline float adjustFloatForAbsoluteZoom(float value, const RenderStyle& style)
return value / style.effectiveZoom();
}
+inline double adjustDoubleForAbsoluteZoom(double value, const RenderStyle& style)
+{
+ return value / style.effectiveZoom();
+}
+
inline LayoutUnit adjustLayoutUnitForAbsoluteZoom(LayoutUnit value, const RenderStyle& style)
{
return value / style.effectiveZoom();
@@ -1830,8 +1854,6 @@ inline bool RenderStyle::isSharable() const
return false;
if (hasUniquePseudoStyle())
return false;
- if (transitions() || animations())
- return false;
return true;
}
@@ -1863,6 +1885,13 @@ inline void RenderStyle::setHasPseudoStyle(PseudoId pseudo)
noninherited_flags._pseudoBits |= 1 << (pseudo - 1);
}
+inline bool RenderStyle::hasPseudoElementStyle() const
+{
+ return noninherited_flags._pseudoBits & PSEUDO_ELEMENT_MASK;
+}
+
+float calcBorderRadiiConstraintScaleFor(const FloatRect&, const FloatRoundedRect::Radii&);
+
} // namespace WebCore
#endif // RenderStyle_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyleConstants.h b/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyleConstants.h
index 45531d20231..f2a3d006af0 100755..100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyleConstants.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/RenderStyleConstants.h
@@ -31,9 +31,11 @@ namespace WebCore {
enum StyleRecalcChange {
NoChange,
NoInherit,
+ UpdatePseudoElements,
Inherit,
Force,
Reattach,
+ ReattachNoRenderer
};
static const size_t PrintColorAdjustBits = 1;
@@ -42,37 +44,18 @@ enum PrintColorAdjust {
PrintColorAdjustExact
};
-// The difference between two styles. The following values are used:
-// (1) StyleDifferenceEqual - The two styles are identical.
-// (2) StyleDifferenceRecompositeLayer - The layer needs its position and transform updated, but no repaint.
-// (3) StyleDifferenceRepaint - The object just needs to be repainted.
-// (4) StyleDifferenceRepaintIfTextOrColorChange - The object needs to be repainted if it contains text or properties dependent on color (e.g., border or outline).
-// (5) StyleDifferenceRepaintLayer - The layer and its descendant layers needs to be repainted.
-// (6) StyleDifferenceLayoutPositionedMovementOnly - Only the position of this positioned object has been updated.
-// (7) StyleDifferenceSimplifiedLayout - Only overflow needs to be recomputed.
-// (8) StyleDifferenceSimplifiedLayoutAndPositionedMovement - Both positioned movement and simplified layout updates are required.
-// (9) StyleDifferenceLayout - A full layout is required.
-enum StyleDifference {
- StyleDifferenceEqual,
- StyleDifferenceRecompositeLayer,
- StyleDifferenceRepaint,
- StyleDifferenceRepaintIfTextOrColorChange,
- StyleDifferenceRepaintLayer,
- StyleDifferenceLayoutPositionedMovementOnly,
- StyleDifferenceSimplifiedLayout,
- StyleDifferenceSimplifiedLayoutAndPositionedMovement,
- StyleDifferenceLayout
-};
-
// When some style properties change, different amounts of work have to be done depending on
// context (e.g. whether the property is changing on an element which has a compositing layer).
// A simple StyleDifference does not provide enough information so we return a bit mask of
-// StyleDifferenceContextSensitiveProperties from RenderStyle::diff() too.
+// StyleDifferenceContextSensitiveProperties from RenderStyle::visualInvalidationDiff() too.
enum StyleDifferenceContextSensitiveProperty {
ContextSensitivePropertyNone = 0,
ContextSensitivePropertyTransform = (1 << 0),
ContextSensitivePropertyOpacity = (1 << 1),
- ContextSensitivePropertyFilter = (1 << 2)
+ ContextSensitivePropertyZIndex = (1 << 2),
+ ContextSensitivePropertyFilter = (1 << 3),
+ // The object needs to be repainted if it contains text or properties dependent on color (e.g., border or outline).
+ ContextSensitivePropertyTextOrColor = (1 << 4)
};
// Static pseudo styles. Dynamic ones are produced on the fly.
@@ -81,13 +64,13 @@ enum PseudoId {
// If you add or remove a public ID, you must update _pseudoBits in RenderStyle.
NOPSEUDO, FIRST_LINE, FIRST_LETTER, BEFORE, AFTER, BACKDROP, SELECTION, FIRST_LINE_INHERITED, SCROLLBAR,
// Internal IDs follow:
- SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER,
- INPUT_LIST_BUTTON,
+ SCROLLBAR_THUMB, SCROLLBAR_BUTTON, SCROLLBAR_TRACK, SCROLLBAR_TRACK_PIECE, SCROLLBAR_CORNER, RESIZER, INPUT_LIST_BUTTON,
+ // Special values follow:
AFTER_LAST_INTERNAL_PSEUDOID,
- FULL_SCREEN, FULL_SCREEN_DOCUMENT, FULL_SCREEN_ANCESTOR,
FIRST_PUBLIC_PSEUDOID = FIRST_LINE,
FIRST_INTERNAL_PSEUDOID = SCROLLBAR_THUMB,
- PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1)
+ PUBLIC_PSEUDOID_MASK = ((1 << FIRST_INTERNAL_PSEUDOID) - 1) & ~((1 << FIRST_PUBLIC_PSEUDOID) - 1),
+ PSEUDO_ELEMENT_MASK = (1 << (BEFORE - 1)) | (1 << (AFTER - 1)) | (1 << (BACKDROP - 1))
};
enum ColumnFill { ColumnFillBalance, ColumnFillAuto };
@@ -191,7 +174,6 @@ enum EBoxDirection { BNORMAL, BREVERSE };
// CSS3 Flexbox Properties
enum EAlignContent { AlignContentFlexStart, AlignContentFlexEnd, AlignContentCenter, AlignContentSpaceBetween, AlignContentSpaceAround, AlignContentStretch };
-enum EAlignItems { AlignAuto, AlignFlexStart, AlignFlexEnd, AlignCenter, AlignStretch, AlignBaseline };
enum EFlexDirection { FlowRow, FlowRowReverse, FlowColumn, FlowColumnReverse };
enum EFlexWrap { FlexNoWrap, FlexWrap, FlexWrapReverse };
enum EJustifyContent { JustifyFlexStart, JustifyFlexEnd, JustifyCenter, JustifySpaceBetween, JustifySpaceAround };
@@ -330,11 +312,9 @@ enum QuoteType {
enum EBorderFit { BorderFitBorder, BorderFitLines };
-enum EAnimationFillMode { AnimationFillModeNone, AnimationFillModeForwards, AnimationFillModeBackwards, AnimationFillModeBoth };
-
enum EAnimPlayState {
- AnimPlayStatePlaying = 0x0,
- AnimPlayStatePaused = 0x1
+ AnimPlayStatePlaying,
+ AnimPlayStatePaused
};
enum EWhiteSpace {
@@ -413,8 +393,8 @@ enum ECursor {
CURSOR_PROGRESS,
CURSOR_NO_DROP,
CURSOR_NOT_ALLOWED,
- CURSOR_WEBKIT_ZOOM_IN,
- CURSOR_WEBKIT_ZOOM_OUT,
+ CURSOR_ZOOM_IN,
+ CURSOR_ZOOM_OUT,
CURSOR_E_RESIZE,
CURSOR_NE_RESIZE,
CURSOR_NW_RESIZE,
@@ -450,7 +430,9 @@ enum EDisplay {
TABLE_CAPTION, BOX, INLINE_BOX,
FLEX, INLINE_FLEX,
GRID, INLINE_GRID,
- NONE
+ NONE,
+ FIRST_TABLE_DISPLAY = TABLE,
+ LAST_TABLE_DISPLAY = TABLE_CAPTION
};
enum EInsideLink {
@@ -495,16 +477,6 @@ enum ImageResolutionSnap { ImageResolutionNoSnap = 0, ImageResolutionSnapPixels
enum Order { LogicalOrder = 0, VisualOrder };
-enum RegionFragment { AutoRegionFragment, BreakRegionFragment };
-
-enum ColumnAxis { HorizontalColumnAxis, VerticalColumnAxis, AutoColumnAxis };
-
-enum ColumnProgression { NormalColumnProgression, ReverseColumnProgression };
-
-enum LineSnap { LineSnapNone, LineSnapBaseline, LineSnapContain };
-
-enum LineAlign { LineAlignNone, LineAlignEdges };
-
enum WrapFlow { WrapFlowAuto, WrapFlowBoth, WrapFlowStart, WrapFlowEnd, WrapFlowMaximum, WrapFlowClear };
enum WrapThrough { WrapThroughWrap, WrapThroughNone };
@@ -515,12 +487,13 @@ enum GridAutoFlow { AutoFlowNone, AutoFlowColumn, AutoFlowRow };
enum DraggableRegionMode { DraggableRegionNone, DraggableRegionDrag, DraggableRegionNoDrag };
-static const size_t TouchActionBits = 3;
+static const size_t TouchActionBits = 4;
enum TouchAction {
TouchActionAuto = 0x0,
TouchActionNone = 0x1,
TouchActionPanX = 0x2,
- TouchActionPanY = 0x4
+ TouchActionPanY = 0x4,
+ TouchActionPinchZoom = 0x8,
};
inline TouchAction operator| (TouchAction a, TouchAction b) { return TouchAction(int(a) | int(b)); }
inline TouchAction& operator|= (TouchAction& a, TouchAction b) { return a = a | b; }
@@ -531,12 +504,34 @@ enum EIsolation { IsolationAuto, IsolationIsolate };
enum TouchActionDelay { TouchActionDelayNone, TouchActionDelayScript };
+enum ItemPosition {
+ ItemPositionAuto,
+ ItemPositionStretch,
+ ItemPositionBaseline,
+ ItemPositionCenter,
+ ItemPositionStart,
+ ItemPositionEnd,
+ ItemPositionSelfStart,
+ ItemPositionSelfEnd,
+ ItemPositionFlexStart,
+ ItemPositionFlexEnd,
+ ItemPositionLeft,
+ ItemPositionRight
+};
+
+enum OverflowAlignment {
+ OverflowAlignmentDefault,
+ OverflowAlignmentTrue,
+ OverflowAlignmentSafe
+};
+
// Reasonable maximum to prevent insane font sizes from causing crashes on some platforms (such as Windows).
static const float maximumAllowedFontSize = 1000000.0f;
enum TextIndentLine { TextIndentFirstLine, TextIndentEachLine };
+enum TextIndentType { TextIndentNormal, TextIndentHanging };
-enum LayoutBox { MarginBox, BorderBox, PaddingBox, ContentBox };
+enum CSSBoxType { BoxMissing = 0, MarginBox, BorderBox, PaddingBox, ContentBox };
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.cpp
index 947c39db641..2e0646ed587 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.cpp
@@ -40,7 +40,6 @@ SVGRenderStyle::SVGRenderStyle()
fill = defaultStyle->fill;
stroke = defaultStyle->stroke;
- text = defaultStyle->text;
stops = defaultStyle->stops;
misc = defaultStyle->misc;
inheritedResources = defaultStyle->inheritedResources;
@@ -55,7 +54,6 @@ SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
fill.init();
stroke.init();
- text.init();
stops.init();
misc.init();
inheritedResources.init();
@@ -67,7 +65,6 @@ SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
{
fill = other.fill;
stroke = other.stroke;
- text = other.text;
stops = other.stops;
misc = other.misc;
inheritedResources = other.inheritedResources;
@@ -85,7 +82,6 @@ bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const
{
return fill == other.fill
&& stroke == other.stroke
- && text == other.text
&& stops == other.stops
&& misc == other.misc
&& inheritedResources == other.inheritedResources
@@ -98,7 +94,6 @@ bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const
{
return fill != other->fill
|| stroke != other->stroke
- || text != other->text
|| inheritedResources != other->inheritedResources
|| svg_inherited_flags != other->svg_inherited_flags;
}
@@ -110,7 +105,6 @@ void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
fill = svgInheritParent->fill;
stroke = svgInheritParent->stroke;
- text = svgInheritParent->text;
inheritedResources = svgInheritParent->inheritedResources;
svg_inherited_flags = svgInheritParent->svg_inherited_flags;
@@ -126,19 +120,27 @@ void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other)
StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
{
- // NOTE: All comparisions that may return StyleDifferenceLayout have to go before those who return StyleDifferenceRepaint
+ StyleDifference styleDifference;
- // If kerning changes, we need a relayout, to force SVGCharacterData to be recalculated in the SVGRootInlineBox.
- if (text != other->text)
- return StyleDifferenceLayout;
+ if (diffNeedsLayoutAndRepaint(other)) {
+ styleDifference.setNeedsFullLayout();
+ styleDifference.setNeedsRepaintObject();
+ } else if (diffNeedsRepaint(other)) {
+ styleDifference.setNeedsRepaintObject();
+ }
+
+ return styleDifference;
+}
+bool SVGRenderStyle::diffNeedsLayoutAndRepaint(const SVGRenderStyle* other) const
+{
// If resources change, we need a relayout, as the presence of resources influences the repaint rect.
if (resources != other->resources)
- return StyleDifferenceLayout;
+ return true;
// If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath.
if (inheritedResources != other->inheritedResources)
- return StyleDifferenceLayout;
+ return true;
// All text related properties influence layout.
if (svg_inherited_flags._textAnchor != other->svg_inherited_flags._textAnchor
@@ -148,20 +150,23 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
|| svg_noninherited_flags.f._alignmentBaseline != other->svg_noninherited_flags.f._alignmentBaseline
|| svg_noninherited_flags.f._dominantBaseline != other->svg_noninherited_flags.f._dominantBaseline
|| svg_noninherited_flags.f._baselineShift != other->svg_noninherited_flags.f._baselineShift)
- return StyleDifferenceLayout;
+ return true;
// Text related properties influence layout.
- bool miscNotEqual = misc != other->misc;
- if (miscNotEqual && misc->baselineShiftValue != other->misc->baselineShiftValue)
- return StyleDifferenceLayout;
+ if (misc->baselineShiftValue != other->misc->baselineShiftValue)
+ return true;
// These properties affect the cached stroke bounding box rects.
if (svg_inherited_flags._capStyle != other->svg_inherited_flags._capStyle
|| svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle)
- return StyleDifferenceLayout;
+ return true;
+
+ // vector-effect changes require a re-layout.
+ if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect)
+ return true;
// Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
- if (stroke != other->stroke) {
+ if (stroke.get() != other->stroke.get()) {
if (stroke->width != other->stroke->width
|| stroke->paintType != other->stroke->paintType
|| stroke->paintColor != other->stroke->paintColor
@@ -172,35 +177,37 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
|| stroke->visitedLinkPaintColor != other->stroke->visitedLinkPaintColor
|| stroke->visitedLinkPaintUri != other->stroke->visitedLinkPaintUri
|| stroke->visitedLinkPaintType != other->stroke->visitedLinkPaintType)
- return StyleDifferenceLayout;
-
- // Only the stroke-opacity case remains, where we only need a repaint.
- ASSERT(stroke->opacity != other->stroke->opacity);
- return StyleDifferenceRepaint;
+ return true;
}
- // vector-effect changes require a re-layout.
- if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect)
- return StyleDifferenceLayout;
+ return false;
+}
- // NOTE: All comparisions below may only return StyleDifferenceRepaint
+bool SVGRenderStyle::diffNeedsRepaint(const SVGRenderStyle* other) const
+{
+ if (stroke->opacity != other->stroke->opacity)
+ return true;
// Painting related properties only need repaints.
- if (miscNotEqual) {
+ if (misc.get() != other->misc.get()) {
if (misc->floodColor != other->misc->floodColor
|| misc->floodOpacity != other->misc->floodOpacity
|| misc->lightingColor != other->misc->lightingColor)
- return StyleDifferenceRepaint;
+ return true;
}
// If fill changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains.
- if (fill->paintType != other->fill->paintType || fill->paintColor != other->fill->paintColor
- || fill->paintUri != other->fill->paintUri || fill->opacity != other->fill->opacity)
- return StyleDifferenceRepaint;
+ if (fill.get() != other->fill.get()) {
+ if (fill->paintType != other->fill->paintType
+ || fill->paintColor != other->fill->paintColor
+ || fill->paintUri != other->fill->paintUri
+ || fill->opacity != other->fill->opacity)
+ return true;
+ }
// If gradient stops change, we just need to repaint. Style updates are already handled through RenderSVGGradientSTop.
if (stops != other->stops)
- return StyleDifferenceRepaint;
+ return true;
// Changes of these flags only cause repaints.
if (svg_inherited_flags._colorRendering != other->svg_inherited_flags._colorRendering
@@ -210,15 +217,15 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
|| svg_inherited_flags._colorInterpolation != other->svg_inherited_flags._colorInterpolation
|| svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._colorInterpolationFilters
|| svg_inherited_flags._paintOrder != other->svg_inherited_flags._paintOrder)
- return StyleDifferenceRepaint;
+ return true;
if (svg_noninherited_flags.f.bufferedRendering != other->svg_noninherited_flags.f.bufferedRendering)
- return StyleDifferenceRepaint;
+ return true;
if (svg_noninherited_flags.f.maskType != other->svg_noninherited_flags.f.maskType)
- return StyleDifferenceRepaint;
+ return true;
- return StyleDifferenceEqual;
+ return false;
}
EPaintOrderType SVGRenderStyle::paintOrderType(unsigned index) const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.h b/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.h
index dba333e1ddf..128ed626aa7 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyle.h
@@ -28,16 +28,13 @@
#include "core/rendering/style/DataRef.h"
#include "core/rendering/style/RenderStyleConstants.h"
#include "core/rendering/style/SVGRenderStyleDefs.h"
+#include "core/rendering/style/StyleDifference.h"
#include "core/svg/SVGPaint.h"
#include "platform/graphics/GraphicsTypes.h"
#include "platform/graphics/Path.h"
namespace WebCore {
-class FloatRect;
-class IntRect;
-class RenderObject;
-
class SVGRenderStyle : public RefCounted<SVGRenderStyle> {
public:
static PassRefPtr<SVGRenderStyle> create() { return adoptRef(new SVGRenderStyle); }
@@ -79,48 +76,41 @@ public:
static SVGPaint::SVGPaintType initialStrokePaintType() { return SVGPaint::SVG_PAINTTYPE_NONE; }
static Color initialStrokePaintColor() { return Color(); }
static String initialStrokePaintUri() { return String(); }
- static Vector<SVGLength> initialStrokeDashArray() { return Vector<SVGLength>(); }
+ static PassRefPtr<SVGLengthList> initialStrokeDashArray() { return SVGLengthList::create(); }
static float initialStrokeMiterLimit() { return 4; }
static float initialStopOpacity() { return 1; }
static Color initialStopColor() { return Color(0, 0, 0); }
static float initialFloodOpacity() { return 1; }
static Color initialFloodColor() { return Color(0, 0, 0); }
static Color initialLightingColor() { return Color(255, 255, 255); }
- static String initialClipperResource() { return String(); }
- static String initialFilterResource() { return String(); }
- static String initialMaskerResource() { return String(); }
- static String initialMarkerStartResource() { return String(); }
- static String initialMarkerMidResource() { return String(); }
- static String initialMarkerEndResource() { return String(); }
+ static const AtomicString& initialClipperResource() { return nullAtom; }
+ static const AtomicString& initialFilterResource() { return nullAtom; }
+ static const AtomicString& initialMaskerResource() { return nullAtom; }
+ static const AtomicString& initialMarkerStartResource() { return nullAtom; }
+ static const AtomicString& initialMarkerMidResource() { return nullAtom; }
+ static const AtomicString& initialMarkerEndResource() { return nullAtom; }
static EMaskType initialMaskType() { return MT_LUMINANCE; }
static EPaintOrder initialPaintOrder() { return PO_NORMAL; }
- static SVGLength initialBaselineShiftValue()
- {
- SVGLength length;
- length.newValueSpecifiedUnits(LengthTypeNumber, 0, ASSERT_NO_EXCEPTION);
- return length;
- }
-
- static SVGLength initialKerning()
+ static PassRefPtr<SVGLength> initialBaselineShiftValue()
{
- SVGLength length;
- length.newValueSpecifiedUnits(LengthTypeNumber, 0, ASSERT_NO_EXCEPTION);
- return length;
+ RefPtr<SVGLength> length = SVGLength::create();
+ length->newValueSpecifiedUnits(LengthTypeNumber, 0);
+ return length.release();
}
- static SVGLength initialStrokeDashOffset()
+ static PassRefPtr<SVGLength> initialStrokeDashOffset()
{
- SVGLength length;
- length.newValueSpecifiedUnits(LengthTypeNumber, 0, ASSERT_NO_EXCEPTION);
- return length;
+ RefPtr<SVGLength> length = SVGLength::create();
+ length->newValueSpecifiedUnits(LengthTypeNumber, 0);
+ return length.release();
}
- static SVGLength initialStrokeWidth()
+ static PassRefPtr<SVGLength> initialStrokeWidth()
{
- SVGLength length;
- length.newValueSpecifiedUnits(LengthTypeNumber, 1, ASSERT_NO_EXCEPTION);
- return length;
+ RefPtr<SVGLength> length = SVGLength::create();
+ length->newValueSpecifiedUnits(LengthTypeNumber, 1);
+ return length.release();
}
// SVG CSS Property setters
@@ -196,7 +186,7 @@ public:
}
}
- void setStrokeDashArray(const Vector<SVGLength>& obj)
+ void setStrokeDashArray(PassRefPtr<SVGLengthList> obj)
{
if (!(stroke->dashArray == obj))
stroke.access()->dashArray = obj;
@@ -208,24 +198,18 @@ public:
stroke.access()->miterLimit = obj;
}
- void setStrokeWidth(const SVGLength& obj)
+ void setStrokeWidth(PassRefPtr<SVGLength> obj)
{
if (!(stroke->width == obj))
stroke.access()->width = obj;
}
- void setStrokeDashOffset(const SVGLength& obj)
+ void setStrokeDashOffset(PassRefPtr<SVGLength> obj)
{
if (!(stroke->dashOffset == obj))
stroke.access()->dashOffset = obj;
}
- void setKerning(const SVGLength& obj)
- {
- if (!(text->kerning == obj))
- text.access()->kerning = obj;
- }
-
void setStopOpacity(float obj)
{
if (!(stops->opacity == obj))
@@ -256,45 +240,45 @@ public:
misc.access()->lightingColor = obj;
}
- void setBaselineShiftValue(const SVGLength& obj)
+ void setBaselineShiftValue(PassRefPtr<SVGLength> obj)
{
if (!(misc->baselineShiftValue == obj))
misc.access()->baselineShiftValue = obj;
}
// Setters for non-inherited resources
- void setClipperResource(const String& obj)
+ void setClipperResource(const AtomicString& obj)
{
if (!(resources->clipper == obj))
resources.access()->clipper = obj;
}
- void setFilterResource(const String& obj)
+ void setFilterResource(const AtomicString& obj)
{
if (!(resources->filter == obj))
resources.access()->filter = obj;
}
- void setMaskerResource(const String& obj)
+ void setMaskerResource(const AtomicString& obj)
{
if (!(resources->masker == obj))
resources.access()->masker = obj;
}
// Setters for inherited resources
- void setMarkerStartResource(const String& obj)
+ void setMarkerStartResource(const AtomicString& obj)
{
if (!(inheritedResources->markerStart == obj))
inheritedResources.access()->markerStart = obj;
}
- void setMarkerMidResource(const String& obj)
+ void setMarkerMidResource(const AtomicString& obj)
{
if (!(inheritedResources->markerMid == obj))
inheritedResources.access()->markerMid = obj;
}
- void setMarkerEndResource(const String& obj)
+ void setMarkerEndResource(const AtomicString& obj)
{
if (!(inheritedResources->markerEnd == obj))
inheritedResources.access()->markerEnd = obj;
@@ -326,23 +310,22 @@ public:
const SVGPaint::SVGPaintType& strokePaintType() const { return stroke->paintType; }
const Color& strokePaintColor() const { return stroke->paintColor; }
const String& strokePaintUri() const { return stroke->paintUri; }
- Vector<SVGLength> strokeDashArray() const { return stroke->dashArray; }
+ SVGLengthList* strokeDashArray() const { return stroke->dashArray.get(); }
float strokeMiterLimit() const { return stroke->miterLimit; }
- SVGLength strokeWidth() const { return stroke->width; }
- SVGLength strokeDashOffset() const { return stroke->dashOffset; }
- SVGLength kerning() const { return text->kerning; }
+ SVGLength* strokeWidth() const { return stroke->width.get(); }
+ SVGLength* strokeDashOffset() const { return stroke->dashOffset.get(); }
float stopOpacity() const { return stops->opacity; }
const Color& stopColor() const { return stops->color; }
float floodOpacity() const { return misc->floodOpacity; }
const Color& floodColor() const { return misc->floodColor; }
const Color& lightingColor() const { return misc->lightingColor; }
- SVGLength baselineShiftValue() const { return misc->baselineShiftValue; }
- String clipperResource() const { return resources->clipper; }
- String filterResource() const { return resources->filter; }
- String maskerResource() const { return resources->masker; }
- String markerStartResource() const { return inheritedResources->markerStart; }
- String markerMidResource() const { return inheritedResources->markerMid; }
- String markerEndResource() const { return inheritedResources->markerEnd; }
+ SVGLength* baselineShiftValue() const { return misc->baselineShiftValue.get(); }
+ const AtomicString& clipperResource() const { return resources->clipper; }
+ const AtomicString& filterResource() const { return resources->filter; }
+ const AtomicString& maskerResource() const { return resources->masker; }
+ const AtomicString& markerStartResource() const { return inheritedResources->markerStart; }
+ const AtomicString& markerMidResource() const { return inheritedResources->markerMid; }
+ const AtomicString& markerEndResource() const { return inheritedResources->markerEnd; }
EMaskType maskType() const { return (EMaskType) svg_noninherited_flags.f.maskType; }
EPaintOrder paintOrder() const { return (EPaintOrder) svg_inherited_flags._paintOrder; }
EPaintOrderType paintOrderType(unsigned index) const;
@@ -360,7 +343,7 @@ public:
bool hasFilter() const { return !filterResource().isEmpty(); }
bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); }
bool hasStroke() const { return strokePaintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
- bool hasVisibleStroke() const { return hasStroke() && !strokeWidth().isZero(); }
+ bool hasVisibleStroke() const { return hasStroke() && !strokeWidth()->isZero(); }
bool hasFill() const { return fillPaintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
bool isVerticalWritingMode() const { return writingMode() == WM_TBRL || writingMode() == WM_TB; }
@@ -427,7 +410,6 @@ protected:
// inherited attributes
DataRef<StyleFillData> fill;
DataRef<StyleStrokeData> stroke;
- DataRef<StyleTextData> text;
DataRef<StyleInheritedResourceData> inheritedResources;
// non-inherited attributes
@@ -442,6 +424,9 @@ private:
SVGRenderStyle(const SVGRenderStyle&);
SVGRenderStyle(CreateDefaultType); // Used to create the default style.
+ bool diffNeedsLayoutAndRepaint(const SVGRenderStyle* other) const;
+ bool diffNeedsRepaint(const SVGRenderStyle* other) const;
+
void setBitDefaults()
{
svg_inherited_flags._clipRule = initialClipRule();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.cpp
index 56e4a06ed5f..7a7f562b4d3 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.cpp
@@ -86,9 +86,9 @@ StyleStrokeData::StyleStrokeData(const StyleStrokeData& other)
: RefCounted<StyleStrokeData>()
, opacity(other.opacity)
, miterLimit(other.miterLimit)
- , width(other.width)
- , dashOffset(other.dashOffset)
- , dashArray(other.dashArray)
+ , width(other.width->clone())
+ , dashOffset(other.dashOffset->clone())
+ , dashArray(other.dashArray->clone())
, paintType(other.paintType)
, paintColor(other.paintColor)
, paintUri(other.paintUri)
@@ -100,11 +100,11 @@ StyleStrokeData::StyleStrokeData(const StyleStrokeData& other)
bool StyleStrokeData::operator==(const StyleStrokeData& other) const
{
- return width == other.width
+ return *width == *other.width
&& opacity == other.opacity
&& miterLimit == other.miterLimit
- && dashOffset == other.dashOffset
- && dashArray == other.dashArray
+ && *dashOffset == *other.dashOffset
+ && *dashArray == *other.dashArray
&& paintType == other.paintType
&& paintColor == other.paintColor
&& paintUri == other.paintUri
@@ -132,22 +132,6 @@ bool StyleStopData::operator==(const StyleStopData& other) const
&& opacity == other.opacity;
}
-StyleTextData::StyleTextData()
- : kerning(SVGRenderStyle::initialKerning())
-{
-}
-
-StyleTextData::StyleTextData(const StyleTextData& other)
- : RefCounted<StyleTextData>()
- , kerning(other.kerning)
-{
-}
-
-bool StyleTextData::operator==(const StyleTextData& other) const
-{
- return kerning == other.kerning;
-}
-
StyleMiscData::StyleMiscData()
: floodColor(SVGRenderStyle::initialFloodColor())
, floodOpacity(SVGRenderStyle::initialFloodOpacity())
@@ -161,7 +145,7 @@ StyleMiscData::StyleMiscData(const StyleMiscData& other)
, floodColor(other.floodColor)
, floodOpacity(other.floodOpacity)
, lightingColor(other.lightingColor)
- , baselineShiftValue(other.baselineShiftValue)
+ , baselineShiftValue(other.baselineShiftValue->clone())
{
}
@@ -170,7 +154,7 @@ bool StyleMiscData::operator==(const StyleMiscData& other) const
return floodOpacity == other.floodOpacity
&& floodColor == other.floodColor
&& lightingColor == other.lightingColor
- && baselineShiftValue == other.baselineShiftValue;
+ && *baselineShiftValue == *other.baselineShiftValue;
}
StyleResourceData::StyleResourceData()
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.h b/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.h
index 9b32f78a578..abd12379dd6 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/SVGRenderStyleDefs.h
@@ -29,6 +29,7 @@
#define SVGRenderStyleDefs_h
#include "core/svg/SVGLength.h"
+#include "core/svg/SVGLengthList.h"
#include "core/svg/SVGPaint.h"
#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
@@ -103,10 +104,6 @@ namespace WebCore {
typedef unsigned EPaintOrder;
const unsigned PO_NORMAL = PT_FILL | PT_STROKE << 2 | PT_MARKERS << 4;
- class CSSValue;
- class CSSValueList;
- class SVGPaint;
-
// Inherited/Non-Inherited Style Datastructures
class StyleFillData : public RefCounted<StyleFillData> {
public:
@@ -146,9 +143,9 @@ namespace WebCore {
float opacity;
float miterLimit;
- SVGLength width;
- SVGLength dashOffset;
- Vector<SVGLength> dashArray;
+ RefPtr<SVGLength> width;
+ RefPtr<SVGLength> dashOffset;
+ RefPtr<SVGLengthList> dashArray;
SVGPaint::SVGPaintType paintType;
Color paintColor;
@@ -181,24 +178,6 @@ namespace WebCore {
StyleStopData(const StyleStopData&);
};
- class StyleTextData : public RefCounted<StyleTextData> {
- public:
- static PassRefPtr<StyleTextData> create() { return adoptRef(new StyleTextData); }
- PassRefPtr<StyleTextData> copy() const { return adoptRef(new StyleTextData(*this)); }
-
- bool operator==(const StyleTextData& other) const;
- bool operator!=(const StyleTextData& other) const
- {
- return !(*this == other);
- }
-
- SVGLength kerning;
-
- private:
- StyleTextData();
- StyleTextData(const StyleTextData&);
- };
-
// Note: the rule for this class is, *no inheritance* of these props
class StyleMiscData : public RefCounted<StyleMiscData> {
public:
@@ -215,8 +194,7 @@ namespace WebCore {
float floodOpacity;
Color lightingColor;
- // non-inherited text stuff lives here not in StyleTextData.
- SVGLength baselineShiftValue;
+ RefPtr<SVGLength> baselineShiftValue;
private:
StyleMiscData();
@@ -235,9 +213,9 @@ namespace WebCore {
return !(*this == other);
}
- String clipper;
- String filter;
- String masker;
+ AtomicString clipper;
+ AtomicString filter;
+ AtomicString masker;
private:
StyleResourceData();
@@ -256,9 +234,9 @@ namespace WebCore {
return !(*this == other);
}
- String markerStart;
- String markerMid;
- String markerEnd;
+ AtomicString markerStart;
+ AtomicString markerMid;
+ AtomicString markerEnd;
private:
StyleInheritedResourceData();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.cpp
index 7f81d909f6b..d89b03e74e8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.cpp
@@ -41,7 +41,7 @@ ShadowData ShadowData::blend(const ShadowData& from, double progress) const
return *this;
return ShadowData(WebCore::blend(from.location(), location(), progress),
- clampTo<int>(WebCore::blend(from.blur(), blur(), progress), 0),
+ clampTo(WebCore::blend(from.blur(), blur(), progress), 0.0f),
WebCore::blend(from.spread(), spread(), progress),
style(),
WebCore::blend(from.color(), color(), progress));
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.h b/chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.h
index 574b3f8214e..fa5a063cf34 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/ShadowData.h
@@ -25,7 +25,7 @@
#ifndef ShadowData_h
#define ShadowData_h
-#include "platform/geometry/IntPoint.h"
+#include "platform/geometry/FloatPoint.h"
#include "platform/graphics/Color.h"
namespace WebCore {
@@ -36,7 +36,7 @@ enum ShadowStyle { Normal, Inset };
class ShadowData {
WTF_MAKE_FAST_ALLOCATED;
public:
- ShadowData(const IntPoint& location, int blur, int spread, ShadowStyle style, const Color& color)
+ ShadowData(const FloatPoint& location, float blur, float spread, ShadowStyle style, const Color& color)
: m_location(location)
, m_blur(blur)
, m_spread(spread)
@@ -50,18 +50,19 @@ public:
ShadowData blend(const ShadowData& from, double progress) const;
- int x() const { return m_location.x(); }
- int y() const { return m_location.y(); }
- IntPoint location() const { return m_location; }
- int blur() const { return m_blur; }
- int spread() const { return m_spread; }
+ float x() const { return m_location.x(); }
+ float y() const { return m_location.y(); }
+ FloatPoint location() const { return m_location; }
+ float blur() const { return m_blur; }
+ float spread() const { return m_spread; }
ShadowStyle style() const { return m_style; }
const Color& color() const { return m_color; }
private:
- IntPoint m_location;
- int m_blur;
- int m_spread;
+ FloatPoint m_location;
+ float m_blur;
+ float m_spread;
+ // FIXME: We should use StyleColor here to allow currentColor to work correctly with visited links
Color m_color;
ShadowStyle m_style;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.cpp
index 675effec90b..b0f414a1162 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.cpp
@@ -32,11 +32,10 @@
#include "core/rendering/style/ShadowList.h"
#include "platform/geometry/FloatRect.h"
-#include "platform/geometry/LayoutRect.h"
namespace WebCore {
-static inline void calculateShadowExtent(const ShadowList* shadowList, int additionalOutlineSize, int& shadowLeft, int& shadowRight, int& shadowTop, int& shadowBottom)
+static inline void calculateShadowExtent(const ShadowList* shadowList, float additionalOutlineSize, float& shadowLeft, float& shadowRight, float& shadowTop, float& shadowBottom)
{
ASSERT(shadowList);
size_t shadowCount = shadowList->shadows().size();
@@ -44,7 +43,7 @@ static inline void calculateShadowExtent(const ShadowList* shadowList, int addit
const ShadowData& shadow = shadowList->shadows()[i];
if (shadow.style() == Inset)
continue;
- int blurAndSpread = shadow.blur() + shadow.spread() + additionalOutlineSize;
+ float blurAndSpread = shadow.blur() + shadow.spread() + additionalOutlineSize;
shadowLeft = std::min(shadow.x() - blurAndSpread, shadowLeft);
shadowRight = std::max(shadow.x() + blurAndSpread, shadowRight);
shadowTop = std::min(shadow.y() - blurAndSpread, shadowTop);
@@ -52,25 +51,19 @@ static inline void calculateShadowExtent(const ShadowList* shadowList, int addit
}
}
-void ShadowList::adjustRectForShadow(LayoutRect& rect, int additionalOutlineSize) const
+void ShadowList::adjustRectForShadow(LayoutRect& rect, float additionalOutlineSize) const
{
- int shadowLeft = 0;
- int shadowRight = 0;
- int shadowTop = 0;
- int shadowBottom = 0;
- calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom);
-
- rect.move(shadowLeft, shadowTop);
- rect.setWidth(rect.width() - shadowLeft + shadowRight);
- rect.setHeight(rect.height() - shadowTop + shadowBottom);
+ FloatRect floatRect(rect);
+ adjustRectForShadow(floatRect);
+ rect = LayoutRect(floatRect);
}
-void ShadowList::adjustRectForShadow(FloatRect& rect, int additionalOutlineSize) const
+void ShadowList::adjustRectForShadow(FloatRect& rect, float additionalOutlineSize) const
{
- int shadowLeft = 0;
- int shadowRight = 0;
- int shadowTop = 0;
- int shadowBottom = 0;
+ float shadowLeft = 0;
+ float shadowRight = 0;
+ float shadowTop = 0;
+ float shadowBottom = 0;
calculateShadowExtent(this, additionalOutlineSize, shadowLeft, shadowRight, shadowTop, shadowBottom);
rect.move(shadowLeft, shadowTop);
@@ -83,12 +76,12 @@ PassRefPtr<ShadowList> ShadowList::blend(const ShadowList* from, const ShadowLis
size_t fromLength = from ? from->shadows().size() : 0;
size_t toLength = to ? to->shadows().size() : 0;
if (!fromLength && !toLength)
- return 0;
+ return nullptr;
ShadowDataVector shadows;
- DEFINE_STATIC_LOCAL(ShadowData, defaultShadowData, (IntPoint(), 0, 0, Normal, Color::transparent));
- DEFINE_STATIC_LOCAL(ShadowData, defaultInsetShadowData, (IntPoint(), 0, 0, Inset, Color::transparent));
+ DEFINE_STATIC_LOCAL(ShadowData, defaultShadowData, (FloatPoint(), 0, 0, Normal, Color::transparent));
+ DEFINE_STATIC_LOCAL(ShadowData, defaultInsetShadowData, (FloatPoint(), 0, 0, Inset, Color::transparent));
size_t maxLength = std::max(fromLength, toLength);
for (size_t i = 0; i < maxLength; ++i) {
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.h b/chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.h
index 12acedf4801..6a1a4c1c9ad 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/ShadowList.h
@@ -32,6 +32,7 @@
#define ShadowList_h
#include "core/rendering/style/ShadowData.h"
+#include "platform/geometry/LayoutRect.h"
#include "wtf/RefCounted.h"
#include "wtf/Vector.h"
@@ -57,8 +58,8 @@ public:
static PassRefPtr<ShadowList> blend(const ShadowList* from, const ShadowList* to, double progress);
- void adjustRectForShadow(LayoutRect&, int additionalOutlineSize = 0) const;
- void adjustRectForShadow(FloatRect&, int additionalOutlineSize = 0) const;
+ void adjustRectForShadow(LayoutRect&, float additionalOutlineSize = 0) const;
+ void adjustRectForShadow(FloatRect&, float additionalOutlineSize = 0) const;
private:
ShadowList(ShadowDataVector& shadows)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/ShapeValue.h b/chromium/third_party/WebKit/Source/core/rendering/style/ShapeValue.h
index 6b872807dce..dc12b4f1ff8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/ShapeValue.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/ShapeValue.h
@@ -44,23 +44,17 @@ public:
// The Auto value is defined by a null ShapeValue*
Shape,
Box,
- Outside,
Image
};
- static PassRefPtr<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape)
+ static PassRefPtr<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape, CSSBoxType cssBox)
{
- return adoptRef(new ShapeValue(shape));
+ return adoptRef(new ShapeValue(shape, cssBox));
}
- static PassRefPtr<ShapeValue> createOutsideValue()
+ static PassRefPtr<ShapeValue> createBoxShapeValue(CSSBoxType cssBox)
{
- return adoptRef(new ShapeValue(Outside));
- }
-
- static PassRefPtr<ShapeValue> createLayoutBoxValue(LayoutBox layoutBox)
- {
- return adoptRef(new ShapeValue(layoutBox));
+ return adoptRef(new ShapeValue(cssBox));
}
static PassRefPtr<ShapeValue> createImageValue(PassRefPtr<StyleImage> image)
@@ -72,39 +66,45 @@ public:
BasicShape* shape() const { return m_shape.get(); }
StyleImage* image() const { return m_image.get(); }
- bool isImageValid() const { return image() && image()->cachedImage() && image()->cachedImage()->hasImage(); }
+ bool isImageValid() const
+ {
+ if (!image())
+ return false;
+ if (image()->isImageResource() || image()->isImageResourceSet())
+ return image()->cachedImage() && image()->cachedImage()->hasImage();
+ return image()->isGeneratedImage();
+ }
void setImage(PassRefPtr<StyleImage> image)
{
ASSERT(type() == Image);
if (m_image != image)
m_image = image;
}
- LayoutBox layoutBox() const { return m_layoutBox; }
- void setLayoutBox(LayoutBox layoutBox) { m_layoutBox = layoutBox; }
+ CSSBoxType cssBox() const { return m_cssBox; }
- bool operator==(const ShapeValue& other) const { return type() == other.type(); }
+ bool operator==(const ShapeValue& other) const;
private:
- ShapeValue(PassRefPtr<BasicShape> shape)
+ ShapeValue(PassRefPtr<BasicShape> shape, CSSBoxType cssBox)
: m_type(Shape)
, m_shape(shape)
- , m_layoutBox(ContentBox)
+ , m_cssBox(cssBox)
{
}
ShapeValue(ShapeValueType type)
: m_type(type)
- , m_layoutBox(ContentBox)
+ , m_cssBox(BoxMissing)
{
}
ShapeValue(PassRefPtr<StyleImage> image)
: m_type(Image)
, m_image(image)
- , m_layoutBox(ContentBox)
+ , m_cssBox(ContentBox)
{
}
- ShapeValue(LayoutBox layoutBox)
+ ShapeValue(CSSBoxType cssBox)
: m_type(Box)
- , m_layoutBox(layoutBox)
+ , m_cssBox(cssBox)
{
}
@@ -112,9 +112,27 @@ private:
ShapeValueType m_type;
RefPtr<BasicShape> m_shape;
RefPtr<StyleImage> m_image;
- LayoutBox m_layoutBox;
+ CSSBoxType m_cssBox;
};
+inline bool ShapeValue::operator==(const ShapeValue& other) const
+{
+ if (type() != other.type())
+ return false;
+
+ switch (type()) {
+ case Shape:
+ return shape() == other.shape() && cssBox() == other.cssBox();
+ case Box:
+ return cssBox() == other.cssBox();
+ case Image:
+ return image() == other.image();
+ }
+
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.cpp
index d0b7ba4ff27..1dcfc53fb58 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.cpp
@@ -46,4 +46,9 @@ bool StyleBackgroundData::operator==(const StyleBackgroundData& o) const
return m_background == o.m_background && m_color == o.m_color && m_outline == o.m_outline;
}
+bool StyleBackgroundData::visuallyEqual(const StyleBackgroundData& o) const
+{
+ return m_background == o.m_background && m_color == o.m_color && m_outline.visuallyEqual(o.m_outline);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.h
index fda242f38f2..f25efbd9f05 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleBackgroundData.h
@@ -45,8 +45,10 @@ public:
return !(*this == o);
}
+ bool visuallyEqual(const StyleBackgroundData&) const;
+
const FillLayer& background() const { return m_background; }
- const Color& color() const { return m_color; }
+ const StyleColor& color() const { return m_color; }
const OutlineValue& outline() const { return m_outline; }
private:
@@ -56,7 +58,7 @@ private:
StyleBackgroundData(const StyleBackgroundData&);
FillLayer m_background;
- Color m_color;
+ StyleColor m_color;
OutlineValue m_outline;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleBoxData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleBoxData.h
index 9b2296641df..6814b3a92e7 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleBoxData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleBoxData.h
@@ -43,16 +43,16 @@ public:
return !(*this == o);
}
- Length width() const { return m_width; }
- Length height() const { return m_height; }
+ const Length& width() const { return m_width; }
+ const Length& height() const { return m_height; }
- Length minWidth() const { return m_minWidth; }
- Length minHeight() const { return m_minHeight; }
+ const Length& minWidth() const { return m_minWidth; }
+ const Length& minHeight() const { return m_minHeight; }
- Length maxWidth() const { return m_maxWidth; }
- Length maxHeight() const { return m_maxHeight; }
+ const Length& maxWidth() const { return m_maxWidth; }
+ const Length& maxHeight() const { return m_maxHeight; }
- Length verticalAlign() const { return m_verticalAlign; }
+ const Length& verticalAlign() const { return m_verticalAlign; }
int zIndex() const { return m_zIndex; }
bool hasAutoZIndex() const { return m_hasAutoZIndex; }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgram.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgram.cpp
deleted file mode 100644
index 31c3d64d662..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgram.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/rendering/style/StyleCustomFilterProgram.h"
-
-#include "core/rendering/style/StyleCustomFilterProgramCache.h"
-
-namespace WebCore {
-
-StyleCustomFilterProgram::~StyleCustomFilterProgram()
-{
- if (m_cache)
- m_cache->remove(this);
-}
-
-} // namespace WebCore
-
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgram.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgram.h
deleted file mode 100644
index d79cf6368f5..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgram.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef StyleCustomFilterProgram_h
-#define StyleCustomFilterProgram_h
-
-#include "core/fetch/ResourceClient.h"
-#include "core/fetch/ResourcePtr.h"
-#include "core/fetch/ShaderResource.h"
-#include "core/rendering/style/StyleShader.h"
-#include "platform/graphics/filters/custom/CustomFilterProgram.h"
-#include "platform/weborigin/KURL.h"
-#include "wtf/FastAllocBase.h"
-
-namespace WebCore {
-
-// CSS Shaders
-
-class StyleCustomFilterProgramCache;
-
-class StyleCustomFilterProgram : public CustomFilterProgram, public ResourceClient {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassRefPtr<StyleCustomFilterProgram> create(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader,
- KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader, CustomFilterProgramType programType,
- const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
- {
- return adoptRef(new StyleCustomFilterProgram(vertexShaderURL, vertexShader, fragmentShaderURL, fragmentShader, programType, mixSettings, meshType));
- }
-
- void setVertexShader(PassRefPtr<StyleShader> shader)
- {
- // The shader is immutable while in the cache.
- ASSERT(!m_cache);
- m_vertexShader = shader;
- }
- StyleShader* vertexShader() const { return m_vertexShader.get(); }
-
- void setFragmentShader(PassRefPtr<StyleShader> shader)
- {
- // The shader is immutable while in the cache.
- ASSERT(!m_cache);
- m_fragmentShader = shader;
- }
- StyleShader* fragmentShader() const { return m_fragmentShader.get(); }
-
- virtual String vertexShaderString() const
- {
- ASSERT(isLoaded());
- return m_cachedVertexShader.get() ? m_cachedVertexShader->shaderString() : String();
- }
-
- virtual String fragmentShaderString() const
- {
- ASSERT(isLoaded());
- return m_cachedFragmentShader.get() ? m_cachedFragmentShader->shaderString() : String();
- }
-
- virtual bool isLoaded() const
- {
- // Do not use the Resource:isLoaded method here, because it actually means !isLoading(),
- // so missing and canceled resources will have isLoaded set to true, even if they are not loaded yet.
- ASSERT(!m_vertexShader || m_vertexShader->isShaderResource());
- ASSERT(!m_fragmentShader || m_fragmentShader->isShaderResource());
-
- // If we failed to create resources for the vertex shader or the
- // fragment shader, they won't be set here.
- // This can happen if the ResourceFetcher is no longer accepting fetch
- // requests because the page is being torn down.
- if (!m_vertexShader && !m_fragmentShader)
- return false;
-
- ASSERT(m_cachedVertexShader.get() || m_cachedFragmentShader.get());
- return (!m_cachedVertexShader.get() || m_isVertexShaderLoaded)
- && (!m_cachedFragmentShader.get() || m_isFragmentShaderLoaded);
- }
-
- virtual void willHaveClients()
- {
- if (m_vertexShader) {
- m_cachedVertexShader = m_vertexShader->resource();
- m_cachedVertexShader->addClient(this);
- }
- if (m_fragmentShader) {
- m_cachedFragmentShader = m_fragmentShader->resource();
- m_cachedFragmentShader->addClient(this);
- }
- }
-
- virtual void didRemoveLastClient()
- {
- if (m_cachedVertexShader.get()) {
- m_cachedVertexShader->removeClient(this);
- m_cachedVertexShader = 0;
- m_isVertexShaderLoaded = false;
- }
- if (m_cachedFragmentShader.get()) {
- m_cachedFragmentShader->removeClient(this);
- m_cachedFragmentShader = 0;
- m_isFragmentShaderLoaded = false;
- }
- }
-
- virtual void notifyFinished(Resource* resource)
- {
- if (resource->errorOccurred())
- return;
- // Note that m_cachedVertexShader might be equal to m_cachedFragmentShader and it would only get one event in that case.
- if (resource == m_cachedVertexShader.get())
- m_isVertexShaderLoaded = true;
- if (resource == m_cachedFragmentShader.get())
- m_isFragmentShaderLoaded = true;
- if (isLoaded())
- notifyClients();
- }
-
- bool hasPendingShaders() const
- {
- return (m_vertexShader && m_vertexShader->isPendingShader())
- || (m_fragmentShader && m_fragmentShader->isPendingShader());
- }
-
- // StyleCustomFilterProgramCache is responsible with updating the reference to the cache.
- void setCache(StyleCustomFilterProgramCache* cache) { m_cache = cache; }
- bool inCache() const { return m_cache; }
-
- KURL vertexShaderURL() const { return m_vertexShaderURL; }
- KURL fragmentShaderURL() const { return m_fragmentShaderURL; }
-
-private:
- StyleCustomFilterProgram(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader, KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader,
- CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
- : CustomFilterProgram(programType, mixSettings, meshType)
- , m_vertexShader(vertexShader)
- , m_fragmentShader(fragmentShader)
- , m_vertexShaderURL(vertexShaderURL)
- , m_fragmentShaderURL(fragmentShaderURL)
- , m_cache(0)
- , m_isVertexShaderLoaded(false)
- , m_isFragmentShaderLoaded(false)
- {
- }
-
- ~StyleCustomFilterProgram();
-
- RefPtr<StyleShader> m_vertexShader;
- RefPtr<StyleShader> m_fragmentShader;
-
- ResourcePtr<ShaderResource> m_cachedVertexShader;
- ResourcePtr<ShaderResource> m_cachedFragmentShader;
-
- // The URLs form the key of the StyleCustomFilterProgram in the cache and are used
- // to lookup the StyleCustomFilterProgram when it's removed from the cache.
- KURL m_vertexShaderURL;
- KURL m_fragmentShaderURL;
-
- // The Cache is responsible of invalidating this reference.
- StyleCustomFilterProgramCache* m_cache;
-
- bool m_isVertexShaderLoaded;
- bool m_isFragmentShaderLoaded;
-};
-
-} // namespace WebCore
-
-
-#endif // StyleCustomFilterProgram_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgramCache.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgramCache.cpp
deleted file mode 100644
index 87d3aba9b66..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgramCache.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/rendering/style/StyleCustomFilterProgramCache.h"
-
-#include "core/rendering/style/StyleCustomFilterProgram.h"
-
-namespace WebCore {
-
-static CustomFilterProgramInfo programCacheKey(StyleCustomFilterProgram* program)
-{
- ASSERT(program->vertexShaderURL().isValid() || program->fragmentShaderURL().isValid());
- return CustomFilterProgramInfo(program->vertexShaderURL().string(), program->fragmentShaderURL().string(),
- program->programType(), program->mixSettings(), program->meshType());
-}
-
-PassOwnPtr<StyleCustomFilterProgramCache> StyleCustomFilterProgramCache::create()
-{
- return adoptPtr(new StyleCustomFilterProgramCache());
-}
-
-StyleCustomFilterProgramCache::~StyleCustomFilterProgramCache()
-{
- // Make sure the programs are not calling back into this object.
- for (CacheMap::iterator iter = m_cache.begin(), end = m_cache.end(); iter != end; ++iter)
- iter->value->setCache(0);
-}
-
-StyleCustomFilterProgram* StyleCustomFilterProgramCache::lookup(const CustomFilterProgramInfo& programInfo) const
-{
- CacheMap::const_iterator iter = m_cache.find(programInfo);
- return iter != m_cache.end() ? iter->value : 0;
-}
-
-StyleCustomFilterProgram* StyleCustomFilterProgramCache::lookup(StyleCustomFilterProgram* program) const
-{
- return lookup(programCacheKey(program));
-}
-
-void StyleCustomFilterProgramCache::add(StyleCustomFilterProgram* program)
-{
- CustomFilterProgramInfo key = programCacheKey(program);
- ASSERT(m_cache.find(key) == m_cache.end());
- m_cache.set(key, program);
- program->setCache(this);
-}
-
-void StyleCustomFilterProgramCache::remove(StyleCustomFilterProgram* program)
-{
- CacheMap::iterator iter = m_cache.find(programCacheKey(program));
- ASSERT_WITH_SECURITY_IMPLICATION(iter != m_cache.end());
- m_cache.remove(iter);
-}
-
-
-} // namespace WebCore
-
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgramCache.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgramCache.h
deleted file mode 100644
index 2bc1652d0e6..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleCustomFilterProgramCache.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef StyleCustomFilterProgramCache_h
-#define StyleCustomFilterProgramCache_h
-
-#include "platform/graphics/filters/custom/CustomFilterProgramInfo.h"
-#include "wtf/FastAllocBase.h"
-#include "wtf/HashMap.h"
-
-namespace WebCore {
-
-class StyleCustomFilterProgram;
-class CustomFilterProgramInfo;
-
-class StyleCustomFilterProgramCache {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- static PassOwnPtr<StyleCustomFilterProgramCache> create();
- ~StyleCustomFilterProgramCache();
-
- // Lookups a StyleCustomFilterProgram that has similar parameters with the specified program.
- StyleCustomFilterProgram* lookup(StyleCustomFilterProgram*) const;
- StyleCustomFilterProgram* lookup(const CustomFilterProgramInfo&) const;
-
- void add(StyleCustomFilterProgram*);
- void remove(StyleCustomFilterProgram*);
-
-private:
- StyleCustomFilterProgramCache() { }
-
- typedef HashMap<CustomFilterProgramInfo, StyleCustomFilterProgram*> CacheMap;
- CacheMap m_cache;
-};
-
-} // namespace WebCore
-
-
-#endif // StyleCustomFilterProgramCache_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.cpp
index 4b3ff280e23..2c030fcc86a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.cpp
@@ -28,8 +28,8 @@ namespace WebCore {
StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData()
: flex(RenderStyle::initialBoxFlex())
- , flex_group(RenderStyle::initialBoxFlexGroup())
- , ordinal_group(RenderStyle::initialBoxOrdinalGroup())
+ , flexGroup(RenderStyle::initialBoxFlexGroup())
+ , ordinalGroup(RenderStyle::initialBoxOrdinalGroup())
, align(RenderStyle::initialBoxAlign())
, pack(RenderStyle::initialBoxPack())
, orient(RenderStyle::initialBoxOrient())
@@ -40,8 +40,8 @@ StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData()
StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData(const StyleDeprecatedFlexibleBoxData& o)
: RefCounted<StyleDeprecatedFlexibleBoxData>()
, flex(o.flex)
- , flex_group(o.flex_group)
- , ordinal_group(o.ordinal_group)
+ , flexGroup(o.flexGroup)
+ , ordinalGroup(o.ordinalGroup)
, align(o.align)
, pack(o.pack)
, orient(o.orient)
@@ -51,9 +51,7 @@ StyleDeprecatedFlexibleBoxData::StyleDeprecatedFlexibleBoxData(const StyleDeprec
bool StyleDeprecatedFlexibleBoxData::operator==(const StyleDeprecatedFlexibleBoxData& o) const
{
- return flex == o.flex && flex_group == o.flex_group &&
- ordinal_group == o.ordinal_group && align == o.align &&
- pack == o.pack && orient == o.orient && lines == o.lines;
+ return flex == o.flex && flexGroup == o.flexGroup && ordinalGroup == o.ordinalGroup && align == o.align && pack == o.pack && orient == o.orient && lines == o.lines;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.h
index 501157cc15d..adfee1f1717 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleDeprecatedFlexibleBoxData.h
@@ -42,8 +42,8 @@ public:
}
float flex;
- unsigned int flex_group;
- unsigned int ordinal_group;
+ unsigned flexGroup;
+ unsigned ordinalGroup;
unsigned align : 3; // EBoxAlignment
unsigned pack: 2; // EBoxPack
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleDifference.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleDifference.h
new file mode 100644
index 00000000000..d8418217b83
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleDifference.h
@@ -0,0 +1,80 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StyleDifference_h
+#define StyleDifference_h
+
+#include "wtf/Assertions.h"
+
+namespace WebCore {
+
+// This class represents the difference between two computed styles (RenderStyle).
+// The difference can be combination of 3 types according to the actions needed:
+// - Difference needing layout
+// - Difference needing repaint
+// - Difference needing recompositing layers
+class StyleDifference {
+public:
+ StyleDifference()
+ : m_needsRecompositeLayer(false)
+ , m_repaintType(NoRepaint)
+ , m_layoutType(NoLayout) { }
+
+ // The two styles are identical.
+ bool hasNoChange() const { return !m_needsRecompositeLayer && !m_repaintType && !m_layoutType; }
+
+ // The layer needs its position and transform updated. Implied by other repaint and layout flags.
+ bool needsRecompositeLayer() const { return m_needsRecompositeLayer || needsRepaint() || needsLayout(); }
+ void setNeedsRecompositeLayer() { m_needsRecompositeLayer = true; }
+
+ bool needsRepaint() const { return m_repaintType != NoRepaint; }
+ void clearNeedsRepaint() { m_repaintType = NoRepaint; }
+
+ // The object just needs to be repainted.
+ bool needsRepaintObject() const { return m_repaintType == RepaintObject; }
+ void setNeedsRepaintObject()
+ {
+ ASSERT(!needsRepaintLayer());
+ m_repaintType = RepaintObject;
+ }
+
+ // The layer and its descendant layers need to be repainted.
+ bool needsRepaintLayer() const { return m_repaintType == RepaintLayer; }
+ void setNeedsRepaintLayer() { m_repaintType = RepaintLayer; }
+
+ bool needsLayout() const { return m_layoutType != NoLayout; }
+ void clearNeedsLayout() { m_layoutType = NoLayout; }
+
+ // The offset of this positioned object has been updated.
+ bool needsPositionedMovementLayout() const { return m_layoutType == PositionedMovement; }
+ void setNeedsPositionedMovementLayout()
+ {
+ ASSERT(!needsFullLayout());
+ m_layoutType = PositionedMovement;
+ }
+
+ bool needsFullLayout() const { return m_layoutType == FullLayout; }
+ void setNeedsFullLayout() { m_layoutType = FullLayout; }
+
+private:
+ unsigned m_needsRecompositeLayer : 1;
+
+ enum RepaintType {
+ NoRepaint = 0,
+ RepaintObject,
+ RepaintLayer
+ };
+ unsigned m_repaintType : 2;
+
+ enum LayoutType {
+ NoLayout = 0,
+ PositionedMovement,
+ FullLayout
+ };
+ unsigned m_layoutType : 2;
+};
+
+} // namespace WebCore
+
+#endif // StyleDifference_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.cpp
index 31dc65a0452..e53dc04ada8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.cpp
@@ -24,6 +24,7 @@
#include "config.h"
#include "core/rendering/style/StyleFetchedImage.h"
+#include "core/css/CSSImageValue.h"
#include "core/fetch/ImageResource.h"
#include "core/rendering/RenderObject.h"
@@ -41,12 +42,12 @@ StyleFetchedImage::~StyleFetchedImage()
m_image->removeClient(this);
}
-PassRefPtr<CSSValue> StyleFetchedImage::cssValue() const
+PassRefPtrWillBeRawPtr<CSSValue> StyleFetchedImage::cssValue() const
{
- return CSSPrimitiveValue::create(m_image->url().string(), CSSPrimitiveValue::CSS_URI);
+ return CSSImageValue::create(m_image->url(), const_cast<StyleFetchedImage*>(this));
}
-bool StyleFetchedImage::canRender(const RenderObject* renderer, float multiplier) const
+bool StyleFetchedImage::canRender(const RenderObject& renderer, float multiplier) const
{
return m_image->canRender(renderer, multiplier);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.h
index e783439b195..e74c26c9168 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImage.h
@@ -32,28 +32,28 @@ namespace WebCore {
class ImageResource;
-class StyleFetchedImage : public StyleImage, private ImageResourceClient {
+class StyleFetchedImage FINAL : public StyleImage, private ImageResourceClient {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<StyleFetchedImage> create(ImageResource* image) { return adoptRef(new StyleFetchedImage(image)); }
virtual ~StyleFetchedImage();
- virtual WrappedImagePtr data() const { return m_image.get(); }
+ virtual WrappedImagePtr data() const OVERRIDE { return m_image.get(); }
- virtual PassRefPtr<CSSValue> cssValue() const;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const OVERRIDE;
- virtual bool canRender(const RenderObject*, float multiplier) const;
- virtual bool isLoaded() const;
- virtual bool errorOccurred() const;
+ virtual bool canRender(const RenderObject&, float multiplier) const OVERRIDE;
+ virtual bool isLoaded() const OVERRIDE;
+ virtual bool errorOccurred() const OVERRIDE;
virtual LayoutSize imageSize(const RenderObject*, float multiplier) const OVERRIDE;
- virtual bool imageHasRelativeWidth() const;
- virtual bool imageHasRelativeHeight() const;
- virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio);
- virtual bool usesImageContainerSize() const;
- virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float);
- virtual void addClient(RenderObject*);
- virtual void removeClient(RenderObject*);
- virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
+ virtual bool imageHasRelativeWidth() const OVERRIDE;
+ virtual bool imageHasRelativeHeight() const OVERRIDE;
+ virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) OVERRIDE;
+ virtual bool usesImageContainerSize() const OVERRIDE;
+ virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float) OVERRIDE;
+ virtual void addClient(RenderObject*) OVERRIDE;
+ virtual void removeClient(RenderObject*) OVERRIDE;
+ virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const OVERRIDE;
virtual bool knownToBeOpaque(const RenderObject*) const OVERRIDE;
virtual ImageResource* cachedImage() const OVERRIDE { return m_image.get(); }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.cpp
index 04a8d9d5961..2aacd2fedd9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.cpp
@@ -47,12 +47,12 @@ StyleFetchedImageSet::~StyleFetchedImageSet()
m_bestFitImage->removeClient(this);
}
-PassRefPtr<CSSValue> StyleFetchedImageSet::cssValue() const
+PassRefPtrWillBeRawPtr<CSSValue> StyleFetchedImageSet::cssValue() const
{
return m_imageSetValue;
}
-bool StyleFetchedImageSet::canRender(const RenderObject* renderer, float multiplier) const
+bool StyleFetchedImageSet::canRender(const RenderObject& renderer, float multiplier) const
{
return m_bestFitImage->canRender(renderer, multiplier);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.h
index 873c14299ef..cee20a65846 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedImageSet.h
@@ -38,7 +38,7 @@ class CSSImageSetValue;
// This class keeps one cached image and has access to a set of alternatives.
-class StyleFetchedImageSet : public StyleImage, private ImageResourceClient {
+class StyleFetchedImageSet FINAL : public StyleImage, private ImageResourceClient {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<StyleFetchedImageSet> create(ImageResource* image, float imageScaleFactor, CSSImageSetValue* value)
@@ -47,28 +47,28 @@ public:
}
virtual ~StyleFetchedImageSet();
- virtual PassRefPtr<CSSValue> cssValue() const;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const OVERRIDE;
// FIXME: This is used by StyleImage for equals comparison, but this implementation
// only looks at the image from the set that we have loaded. I'm not sure if that is
// meaningful enough or not.
- virtual WrappedImagePtr data() const { return m_bestFitImage.get(); }
+ virtual WrappedImagePtr data() const OVERRIDE { return m_bestFitImage.get(); }
void clearImageSetValue() { m_imageSetValue = 0; }
- virtual bool canRender(const RenderObject*, float multiplier) const;
- virtual bool isLoaded() const;
- virtual bool errorOccurred() const;
- virtual LayoutSize imageSize(const RenderObject*, float multiplier) const;
- virtual bool imageHasRelativeWidth() const;
- virtual bool imageHasRelativeHeight() const;
- virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio);
- virtual bool usesImageContainerSize() const;
- virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float);
- virtual void addClient(RenderObject*);
- virtual void removeClient(RenderObject*);
- virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
- virtual float imageScaleFactor() const { return m_imageScaleFactor; }
+ virtual bool canRender(const RenderObject&, float multiplier) const OVERRIDE;
+ virtual bool isLoaded() const OVERRIDE;
+ virtual bool errorOccurred() const OVERRIDE;
+ virtual LayoutSize imageSize(const RenderObject*, float multiplier) const OVERRIDE;
+ virtual bool imageHasRelativeWidth() const OVERRIDE;
+ virtual bool imageHasRelativeHeight() const OVERRIDE;
+ virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) OVERRIDE;
+ virtual bool usesImageContainerSize() const OVERRIDE;
+ virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float) OVERRIDE;
+ virtual void addClient(RenderObject*) OVERRIDE;
+ virtual void removeClient(RenderObject*) OVERRIDE;
+ virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const OVERRIDE;
+ virtual float imageScaleFactor() const OVERRIDE { return m_imageScaleFactor; }
virtual bool knownToBeOpaque(const RenderObject*) const OVERRIDE;
virtual ImageResource* cachedImage() const OVERRIDE { return m_bestFitImage.get(); }
@@ -77,6 +77,11 @@ private:
ResourcePtr<ImageResource> m_bestFitImage;
float m_imageScaleFactor;
+
+ // FIXME: oilpan: Change to RawPtrWillBeMember when moving this class onto oilpan heap.
+ // Also add "if !ENABLE(OILPAN)" around clearImageSetValue above as well as around its
+ // caller since it should not be needed once both of the objects are on the heap and
+ // oilpan is enabled.
CSSImageSetValue* m_imageSetValue; // Not retained; it owns us.
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedShader.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedShader.cpp
deleted file mode 100644
index 13a8b98c36a..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedShader.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "core/rendering/style/StyleFetchedShader.h"
-
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/fetch/ShaderResource.h"
-
-namespace WebCore {
-
-
-StyleFetchedShader::StyleFetchedShader(ShaderResource* shader)
- : m_shader(shader)
-{
- m_isShaderResource = true;
-}
-
-PassRefPtr<CSSValue> StyleFetchedShader::cssValue() const
-{
- return CSSPrimitiveValue::create(m_shader->url().string(), CSSPrimitiveValue::CSS_URI);
-}
-
-} // namespace WebCore
-
-
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedShader.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedShader.h
deleted file mode 100644
index 104a90cc871..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleFetchedShader.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef StyleFetchedShader_h
-#define StyleFetchedShader_h
-
-#include "core/fetch/ResourcePtr.h"
-#include "core/rendering/style/StyleShader.h"
-
-namespace WebCore {
-
-class ShaderResource;
-
-class StyleFetchedShader : public StyleShader {
-public:
- // FIXME: Keep a reference to the actual ShaderResource in this class.
- static PassRefPtr<StyleFetchedShader> create(ShaderResource* shader) { return adoptRef(new StyleFetchedShader(shader)); }
-
- virtual PassRefPtr<CSSValue> cssValue() const;
-
- virtual ShaderResource* resource() const { return m_shader.get(); }
-
-private:
- StyleFetchedShader(ShaderResource*);
-
- ResourcePtr<ShaderResource> m_shader;
-};
-
-}
-
-#endif // StyleFetchedShader_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.cpp
index 2ec1c87de4e..f675fa5b0b5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.cpp
@@ -30,16 +30,16 @@
namespace WebCore {
-StyleGeneratedImage::StyleGeneratedImage(PassRefPtr<CSSImageGeneratorValue> value)
+StyleGeneratedImage::StyleGeneratedImage(PassRefPtrWillBeRawPtr<CSSImageGeneratorValue> value)
: m_imageGeneratorValue(value)
, m_fixedSize(m_imageGeneratorValue->isFixedSize())
{
m_isGeneratedImage = true;
}
-PassRefPtr<CSSValue> StyleGeneratedImage::cssValue() const
+PassRefPtrWillBeRawPtr<CSSValue> StyleGeneratedImage::cssValue() const
{
- return m_imageGeneratorValue;
+ return m_imageGeneratorValue.get();
}
LayoutSize StyleGeneratedImage::imageSize(const RenderObject* renderer, float multiplier) const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.h
index bf93af475da..219f47e241d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleGeneratedImage.h
@@ -31,32 +31,33 @@ namespace WebCore {
class CSSValue;
class CSSImageGeneratorValue;
-class StyleGeneratedImage : public StyleImage {
+class StyleGeneratedImage FINAL : public StyleImage {
public:
static PassRefPtr<StyleGeneratedImage> create(CSSImageGeneratorValue* value)
{
return adoptRef(new StyleGeneratedImage(value));
}
- virtual WrappedImagePtr data() const { return m_imageGeneratorValue.get(); }
+ virtual WrappedImagePtr data() const OVERRIDE { return m_imageGeneratorValue.get(); }
- virtual PassRefPtr<CSSValue> cssValue() const;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const OVERRIDE;
virtual LayoutSize imageSize(const RenderObject*, float multiplier) const OVERRIDE;
- virtual bool imageHasRelativeWidth() const { return !m_fixedSize; }
- virtual bool imageHasRelativeHeight() const { return !m_fixedSize; }
- virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio);
- virtual bool usesImageContainerSize() const { return !m_fixedSize; }
- virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize& containerSize, float) { m_containerSize = containerSize; }
- virtual void addClient(RenderObject*);
- virtual void removeClient(RenderObject*);
- virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const;
+ virtual bool imageHasRelativeWidth() const OVERRIDE { return !m_fixedSize; }
+ virtual bool imageHasRelativeHeight() const OVERRIDE { return !m_fixedSize; }
+ virtual void computeIntrinsicDimensions(const RenderObject*, Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio) OVERRIDE;
+ virtual bool usesImageContainerSize() const OVERRIDE { return !m_fixedSize; }
+ virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize& containerSize, float) OVERRIDE { m_containerSize = containerSize; }
+ virtual void addClient(RenderObject*) OVERRIDE;
+ virtual void removeClient(RenderObject*) OVERRIDE;
+ virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const OVERRIDE;
virtual bool knownToBeOpaque(const RenderObject*) const OVERRIDE;
private:
- StyleGeneratedImage(PassRefPtr<CSSImageGeneratorValue>);
+ StyleGeneratedImage(PassRefPtrWillBeRawPtr<CSSImageGeneratorValue>);
- RefPtr<CSSImageGeneratorValue> m_imageGeneratorValue;
+ // FIXME: oilpan: change to member once StyleImage is moved to the oilpan heap
+ RefPtrWillBePersistent<CSSImageGeneratorValue> m_imageGeneratorValue;
IntSize m_containerSize;
bool m_fixedSize;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.cpp
index a3f8a348017..d323864b32b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.cpp
@@ -31,8 +31,8 @@
namespace WebCore {
StyleGridData::StyleGridData()
- : m_gridDefinitionColumns(RenderStyle::initialGridDefinitionColumns())
- , m_gridDefinitionRows(RenderStyle::initialGridDefinitionRows())
+ : m_gridTemplateColumns(RenderStyle::initialGridTemplateColumns())
+ , m_gridTemplateRows(RenderStyle::initialGridTemplateRows())
, m_namedGridColumnLines(RenderStyle::initialNamedGridColumnLines())
, m_namedGridRowLines(RenderStyle::initialNamedGridRowLines())
, m_orderedNamedGridColumnLines(RenderStyle::initialOrderedNamedGridColumnLines())
@@ -48,8 +48,8 @@ StyleGridData::StyleGridData()
StyleGridData::StyleGridData(const StyleGridData& o)
: RefCounted<StyleGridData>()
- , m_gridDefinitionColumns(o.m_gridDefinitionColumns)
- , m_gridDefinitionRows(o.m_gridDefinitionRows)
+ , m_gridTemplateColumns(o.m_gridTemplateColumns)
+ , m_gridTemplateRows(o.m_gridTemplateRows)
, m_namedGridColumnLines(o.m_namedGridColumnLines)
, m_namedGridRowLines(o.m_namedGridRowLines)
, m_orderedNamedGridColumnLines(o.m_orderedNamedGridColumnLines)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.h
index c7f5e5430e7..da14eaa2989 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleGridData.h
@@ -46,7 +46,7 @@ public:
bool operator==(const StyleGridData& o) const
{
- return m_gridDefinitionColumns == o.m_gridDefinitionColumns && m_gridDefinitionRows == o.m_gridDefinitionRows && m_gridAutoFlow == o.m_gridAutoFlow && m_gridAutoRows == o.m_gridAutoRows && m_gridAutoColumns == o.m_gridAutoColumns && m_namedGridColumnLines == o.m_namedGridColumnLines && m_namedGridRowLines == o.m_namedGridRowLines && m_orderedNamedGridColumnLines == o.m_orderedNamedGridColumnLines && m_orderedNamedGridRowLines == o.m_orderedNamedGridRowLines && m_namedGridArea == o.m_namedGridArea && m_namedGridArea == o.m_namedGridArea && m_namedGridAreaRowCount == o.m_namedGridAreaRowCount && m_namedGridAreaColumnCount == o.m_namedGridAreaColumnCount;
+ return m_gridTemplateColumns == o.m_gridTemplateColumns && m_gridTemplateRows == o.m_gridTemplateRows && m_gridAutoFlow == o.m_gridAutoFlow && m_gridAutoRows == o.m_gridAutoRows && m_gridAutoColumns == o.m_gridAutoColumns && m_namedGridColumnLines == o.m_namedGridColumnLines && m_namedGridRowLines == o.m_namedGridRowLines && m_orderedNamedGridColumnLines == o.m_orderedNamedGridColumnLines && m_orderedNamedGridRowLines == o.m_orderedNamedGridRowLines && m_namedGridArea == o.m_namedGridArea && m_namedGridArea == o.m_namedGridArea && m_namedGridAreaRowCount == o.m_namedGridAreaRowCount && m_namedGridAreaColumnCount == o.m_namedGridAreaColumnCount;
}
bool operator!=(const StyleGridData& o) const
@@ -54,8 +54,8 @@ public:
return !(*this == o);
}
- Vector<GridTrackSize> m_gridDefinitionColumns;
- Vector<GridTrackSize> m_gridDefinitionRows;
+ Vector<GridTrackSize> m_gridTemplateColumns;
+ Vector<GridTrackSize> m_gridTemplateRows;
NamedGridLinesMap m_namedGridColumnLines;
NamedGridLinesMap m_namedGridRowLines;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleImage.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleImage.h
index bca329ac568..b487e2c33ce 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleImage.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleImage.h
@@ -49,9 +49,9 @@ public:
return data() == other.data();
}
- virtual PassRefPtr<CSSValue> cssValue() const = 0;
+ virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const = 0;
- virtual bool canRender(const RenderObject*, float /*multiplier*/) const { return true; }
+ virtual bool canRender(const RenderObject&, float /*multiplier*/) const { return true; }
virtual bool isLoaded() const { return true; }
virtual bool errorOccurred() const { return false; }
virtual LayoutSize imageSize(const RenderObject*, float multiplier) const = 0;
@@ -73,16 +73,6 @@ public:
ALWAYS_INLINE bool isGeneratedImage() const { return m_isGeneratedImage; }
ALWAYS_INLINE bool isImageResourceSet() const { return m_isImageResourceSet; }
- static bool imagesEquivalent(const StyleImage* image1, const StyleImage* image2)
- {
- if (image1 != image2) {
- if (!image1 || !image2)
- return false;
- return *image1 == *image2;
- }
- return true;
- }
-
protected:
StyleImage()
: m_isImageResource(false)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.cpp
index 063e7d2286c..1b961aa497e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.cpp
@@ -32,6 +32,7 @@ StyleInheritedData::StyleInheritedData()
, line_height(RenderStyle::initialLineHeight())
, color(RenderStyle::initialColor())
, visitedLinkColor(RenderStyle::initialColor())
+ , textAutosizingMultiplier(1)
{
}
@@ -47,6 +48,7 @@ StyleInheritedData::StyleInheritedData(const StyleInheritedData& o)
, font(o.font)
, color(o.color)
, visitedLinkColor(o.visitedLinkColor)
+ , textAutosizingMultiplier(o.textAutosizingMultiplier)
{
}
@@ -57,6 +59,7 @@ bool StyleInheritedData::operator==(const StyleInheritedData& o) const
&& color == o.color
&& visitedLinkColor == o.visitedLinkColor
&& horizontal_border_spacing == o.horizontal_border_spacing
+ && textAutosizingMultiplier == o.textAutosizingMultiplier
&& vertical_border_spacing == o.vertical_border_spacing;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.h
index 11613a4abf7..7466a7c78fd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleInheritedData.h
@@ -56,6 +56,7 @@ public:
Font font;
Color color;
Color visitedLinkColor;
+ float textAutosizingMultiplier;
private:
StyleInheritedData();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.cpp
index 90897bb28bf..f7a7c5337e5 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.cpp
@@ -30,6 +30,7 @@ StyleMultiColData::StyleMultiColData()
: m_width(0)
, m_count(RenderStyle::initialColumnCount())
, m_gap(0)
+ , m_visitedLinkColumnRuleColor(StyleColor::currentColor())
, m_autoWidth(true)
, m_autoCount(true)
, m_normalGap(true)
@@ -38,8 +39,6 @@ StyleMultiColData::StyleMultiColData()
, m_breakBefore(RenderStyle::initialPageBreak())
, m_breakAfter(RenderStyle::initialPageBreak())
, m_breakInside(RenderStyle::initialPageBreak())
- , m_axis(RenderStyle::initialColumnAxis())
- , m_progression(RenderStyle::initialColumnProgression())
{
}
@@ -58,8 +57,6 @@ StyleMultiColData::StyleMultiColData(const StyleMultiColData& o)
, m_breakBefore(o.m_breakBefore)
, m_breakAfter(o.m_breakAfter)
, m_breakInside(o.m_breakInside)
- , m_axis(o.m_axis)
- , m_progression(o.m_progression)
{
}
@@ -69,8 +66,7 @@ bool StyleMultiColData::operator==(const StyleMultiColData& o) const
&& m_rule == o.m_rule && m_visitedLinkColumnRuleColor == o.m_visitedLinkColumnRuleColor && m_breakBefore == o.m_breakBefore
&& m_autoWidth == o.m_autoWidth && m_autoCount == o.m_autoCount && m_normalGap == o.m_normalGap
&& m_fill == o.m_fill && m_columnSpan == o.m_columnSpan
- && m_breakAfter == o.m_breakAfter && m_breakInside == o.m_breakInside
- && m_axis == o.m_axis && m_progression == o.m_progression;
+ && m_breakAfter == o.m_breakAfter && m_breakInside == o.m_breakInside;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.h
index fcf66802667..27441be85cd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleMultiColData.h
@@ -57,7 +57,7 @@ public:
unsigned short m_count;
float m_gap;
BorderValue m_rule;
- Color m_visitedLinkColumnRuleColor;
+ StyleColor m_visitedLinkColumnRuleColor;
bool m_autoWidth : 1;
bool m_autoCount : 1;
@@ -67,8 +67,6 @@ public:
unsigned m_breakBefore : 2; // EPageBreak
unsigned m_breakAfter : 2; // EPageBreak
unsigned m_breakInside : 2; // EPageBreak
- unsigned m_axis : 2; // ColumnAxis
- unsigned m_progression : 2; // ColumnProgression
private:
StyleMultiColData();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StylePendingImage.h b/chromium/third_party/WebKit/Source/core/rendering/style/StylePendingImage.h
index 4589f59a63d..d735175bb68 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StylePendingImage.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StylePendingImage.h
@@ -39,32 +39,32 @@ namespace WebCore {
// style resolution, in order to avoid loading images that are not referenced by the final style.
// They should never exist in a RenderStyle after it has been returned from the style selector.
-class StylePendingImage : public StyleImage {
+class StylePendingImage FINAL : public StyleImage {
public:
static PassRefPtr<StylePendingImage> create(CSSValue* value) { return adoptRef(new StylePendingImage(value)); }
- virtual WrappedImagePtr data() const { return m_value; }
+ virtual WrappedImagePtr data() const OVERRIDE { return m_value; }
- virtual PassRefPtr<CSSValue> cssValue() const { return m_value; }
+ virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const OVERRIDE { return m_value; }
CSSImageValue* cssImageValue() const { return m_value->isImageValue() ? toCSSImageValue(m_value) : 0; }
CSSImageGeneratorValue* cssImageGeneratorValue() const { return m_value->isImageGeneratorValue() ? toCSSImageGeneratorValue(m_value) : 0; }
CSSCursorImageValue* cssCursorImageValue() const { return m_value->isCursorImageValue() ? toCSSCursorImageValue(m_value) : 0; }
CSSImageSetValue* cssImageSetValue() const { return m_value->isImageSetValue() ? toCSSImageSetValue(m_value) : 0; }
virtual LayoutSize imageSize(const RenderObject*, float /*multiplier*/) const OVERRIDE { return LayoutSize(); }
- virtual bool imageHasRelativeWidth() const { return false; }
- virtual bool imageHasRelativeHeight() const { return false; }
- virtual void computeIntrinsicDimensions(const RenderObject*, Length& /* intrinsicWidth */ , Length& /* intrinsicHeight */, FloatSize& /* intrinsicRatio */) { }
- virtual bool usesImageContainerSize() const { return false; }
- virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float) { }
- virtual void addClient(RenderObject*) { }
- virtual void removeClient(RenderObject*) { }
- virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const
+ virtual bool imageHasRelativeWidth() const OVERRIDE { return false; }
+ virtual bool imageHasRelativeHeight() const OVERRIDE { return false; }
+ virtual void computeIntrinsicDimensions(const RenderObject*, Length& /* intrinsicWidth */ , Length& /* intrinsicHeight */, FloatSize& /* intrinsicRatio */) OVERRIDE { }
+ virtual bool usesImageContainerSize() const OVERRIDE { return false; }
+ virtual void setContainerSizeForRenderer(const RenderObject*, const IntSize&, float) OVERRIDE { }
+ virtual void addClient(RenderObject*) OVERRIDE { }
+ virtual void removeClient(RenderObject*) OVERRIDE { }
+ virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const OVERRIDE
{
ASSERT_NOT_REACHED();
- return 0;
+ return nullptr;
}
- virtual bool knownToBeOpaque(const RenderObject*) const { return false; }
+ virtual bool knownToBeOpaque(const RenderObject*) const OVERRIDE { return false; }
private:
StylePendingImage(CSSValue* value)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StylePendingShader.h b/chromium/third_party/WebKit/Source/core/rendering/style/StylePendingShader.h
deleted file mode 100644
index 1158e33a740..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StylePendingShader.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef StylePendingShader_h
-#define StylePendingShader_h
-
-#include "core/css/CSSShaderValue.h"
-#include "core/css/CSSValue.h"
-#include "core/rendering/style/StyleShader.h"
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-class WebKitCSSShaderValue;
-
-class StylePendingShader : public StyleShader {
-public:
- static PassRefPtr<StylePendingShader> create(CSSShaderValue* value) { return adoptRef(new StylePendingShader(value)); }
-
- virtual PassRefPtr<CSSValue> cssValue() const { return m_value; }
- CSSShaderValue* cssShaderValue() const { return m_value; }
-private:
- StylePendingShader(CSSShaderValue* value)
- : m_value(value)
- {
- m_isPendingShader = true;
- }
-
- CSSShaderValue* m_value; // Not retained; it owns us.
-};
-
-}
-
-#endif // StylePendingShader_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.cpp
index 1a1769c787f..741d22d7801 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.cpp
@@ -22,7 +22,9 @@
#include "config.h"
#include "core/rendering/style/StyleRareInheritedData.h"
-#include "core/rendering/style/CursorList.h"
+#include "core/rendering/style/AppliedTextDecoration.h"
+#include "core/rendering/style/CursorData.h"
+#include "core/rendering/style/DataEquivalency.h"
#include "core/rendering/style/QuotesData.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/RenderStyleConstants.h"
@@ -37,8 +39,8 @@ struct SameSizeAsStyleRareInheritedData : public RefCounted<SameSizeAsStyleRareI
float firstFloat;
Color colors[5];
void* ownPtrs[1];
- AtomicString atomicStrings[5];
- void* refPtrs[2];
+ AtomicString atomicStrings[4];
+ void* refPtrs[3];
Length lengths[1];
float secondFloat;
unsigned m_bitfields[2];
@@ -47,8 +49,6 @@ struct SameSizeAsStyleRareInheritedData : public RefCounted<SameSizeAsStyleRareI
short hyphenationShorts[3];
Color touchColors;
-
- void* variableDataRefs[1];
};
COMPILE_ASSERT(sizeof(StyleRareInheritedData) == sizeof(SameSizeAsStyleRareInheritedData), StyleRareInheritedData_should_bit_pack);
@@ -62,6 +62,12 @@ StyleRareInheritedData::StyleRareInheritedData()
, orphans(RenderStyle::initialOrphans())
, m_hasAutoWidows(true)
, m_hasAutoOrphans(true)
+ , m_textStrokeColorIsCurrentColor(true)
+ , m_textFillColorIsCurrentColor(true)
+ , m_textEmphasisColorIsCurrentColor(true)
+ , m_visitedLinkTextStrokeColorIsCurrentColor(true)
+ , m_visitedLinkTextFillColorIsCurrentColor(true)
+ , m_visitedLinkTextEmphasisColorIsCurrentColor(true)
, textSecurity(RenderStyle::initialTextSecurity())
, userModify(READ_ONLY)
, wordBreak(RenderStyle::initialWordBreak())
@@ -78,33 +84,31 @@ StyleRareInheritedData::StyleRareInheritedData()
, m_textJustify(RenderStyle::initialTextJustify())
, m_textOrientation(TextOrientationVerticalRight)
, m_textIndentLine(RenderStyle::initialTextIndentLine())
+ , m_textIndentType(RenderStyle::initialTextIndentLine())
, m_lineBoxContain(RenderStyle::initialLineBoxContain())
, m_imageRendering(RenderStyle::initialImageRendering())
- , m_lineSnap(RenderStyle::initialLineSnap())
- , m_lineAlign(RenderStyle::initialLineAlign())
, m_textUnderlinePosition(RenderStyle::initialTextUnderlinePosition())
, m_rubyPosition(RenderStyle::initialRubyPosition())
, m_touchActionDelay(RenderStyle::initialTouchActionDelay())
+ , m_subtreeWillChangeContents(false)
, hyphenationLimitBefore(-1)
, hyphenationLimitAfter(-1)
, hyphenationLimitLines(-1)
- , m_lineGrid(RenderStyle::initialLineGrid())
, m_tabSize(RenderStyle::initialTabSize())
, tapHighlightColor(RenderStyle::initialTapHighlightColor())
{
- m_variables.init();
}
StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
: RefCounted<StyleRareInheritedData>()
, listStyleImage(o.listStyleImage)
- , textStrokeColor(o.textStrokeColor)
+ , m_textStrokeColor(o.m_textStrokeColor)
, textStrokeWidth(o.textStrokeWidth)
- , textFillColor(o.textFillColor)
- , textEmphasisColor(o.textEmphasisColor)
- , visitedLinkTextStrokeColor(o.visitedLinkTextStrokeColor)
- , visitedLinkTextFillColor(o.visitedLinkTextFillColor)
- , visitedLinkTextEmphasisColor(o.visitedLinkTextEmphasisColor)
+ , m_textFillColor(o.m_textFillColor)
+ , m_textEmphasisColor(o.m_textEmphasisColor)
+ , m_visitedLinkTextStrokeColor(o.m_visitedLinkTextStrokeColor)
+ , m_visitedLinkTextFillColor(o.m_visitedLinkTextFillColor)
+ , m_visitedLinkTextEmphasisColor(o.m_visitedLinkTextEmphasisColor)
, textShadow(o.textShadow)
, highlight(o.highlight)
, cursorData(o.cursorData)
@@ -114,6 +118,12 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
, orphans(o.orphans)
, m_hasAutoWidows(o.m_hasAutoWidows)
, m_hasAutoOrphans(o.m_hasAutoOrphans)
+ , m_textStrokeColorIsCurrentColor(o.m_textStrokeColorIsCurrentColor)
+ , m_textFillColorIsCurrentColor(o.m_textFillColorIsCurrentColor)
+ , m_textEmphasisColorIsCurrentColor(o.m_textEmphasisColorIsCurrentColor)
+ , m_visitedLinkTextStrokeColorIsCurrentColor(o.m_visitedLinkTextStrokeColorIsCurrentColor)
+ , m_visitedLinkTextFillColorIsCurrentColor(o.m_visitedLinkTextFillColorIsCurrentColor)
+ , m_visitedLinkTextEmphasisColorIsCurrentColor(o.m_visitedLinkTextEmphasisColorIsCurrentColor)
, textSecurity(o.textSecurity)
, userModify(o.userModify)
, wordBreak(o.wordBreak)
@@ -130,23 +140,22 @@ StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedData& o)
, m_textJustify(o.m_textJustify)
, m_textOrientation(o.m_textOrientation)
, m_textIndentLine(o.m_textIndentLine)
+ , m_textIndentType(o.m_textIndentType)
, m_lineBoxContain(o.m_lineBoxContain)
, m_imageRendering(o.m_imageRendering)
- , m_lineSnap(o.m_lineSnap)
- , m_lineAlign(o.m_lineAlign)
, m_textUnderlinePosition(o.m_textUnderlinePosition)
, m_rubyPosition(o.m_rubyPosition)
, m_touchActionDelay(o.m_touchActionDelay)
+ , m_subtreeWillChangeContents(o.m_subtreeWillChangeContents)
, hyphenationString(o.hyphenationString)
, hyphenationLimitBefore(o.hyphenationLimitBefore)
, hyphenationLimitAfter(o.hyphenationLimitAfter)
, hyphenationLimitLines(o.hyphenationLimitLines)
, locale(o.locale)
, textEmphasisCustomMark(o.textEmphasisCustomMark)
- , m_lineGrid(o.m_lineGrid)
, m_tabSize(o.m_tabSize)
, tapHighlightColor(o.tapHighlightColor)
- , m_variables(o.m_variables)
+ , appliedTextDecorations(o.appliedTextDecorations)
{
}
@@ -154,34 +163,31 @@ StyleRareInheritedData::~StyleRareInheritedData()
{
}
-static bool cursorDataEquivalent(const CursorList* c1, const CursorList* c2)
-{
- if (c1 == c2)
- return true;
- if ((!c1 && c2) || (c1 && !c2))
- return false;
- return (*c1 == *c2);
-}
-
bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
{
- return textStrokeColor == o.textStrokeColor
+ return m_textStrokeColor == o.m_textStrokeColor
&& textStrokeWidth == o.textStrokeWidth
- && textFillColor == o.textFillColor
- && textEmphasisColor == o.textEmphasisColor
- && visitedLinkTextStrokeColor == o.visitedLinkTextStrokeColor
- && visitedLinkTextFillColor == o.visitedLinkTextFillColor
- && visitedLinkTextEmphasisColor == o.visitedLinkTextEmphasisColor
+ && m_textFillColor == o.m_textFillColor
+ && m_textEmphasisColor == o.m_textEmphasisColor
+ && m_visitedLinkTextStrokeColor == o.m_visitedLinkTextStrokeColor
+ && m_visitedLinkTextFillColor == o.m_visitedLinkTextFillColor
+ && m_visitedLinkTextEmphasisColor == o.m_visitedLinkTextEmphasisColor
&& tapHighlightColor == o.tapHighlightColor
&& shadowDataEquivalent(o)
&& highlight == o.highlight
- && cursorDataEquivalent(cursorData.get(), o.cursorData.get())
+ && dataEquivalent(cursorData.get(), o.cursorData.get())
&& indent == o.indent
&& m_effectiveZoom == o.m_effectiveZoom
&& widows == o.widows
&& orphans == o.orphans
&& m_hasAutoWidows == o.m_hasAutoWidows
&& m_hasAutoOrphans == o.m_hasAutoOrphans
+ && m_textStrokeColorIsCurrentColor == o.m_textStrokeColorIsCurrentColor
+ && m_textFillColorIsCurrentColor == o.m_textFillColorIsCurrentColor
+ && m_textEmphasisColorIsCurrentColor == o.m_textEmphasisColorIsCurrentColor
+ && m_visitedLinkTextStrokeColorIsCurrentColor == o.m_visitedLinkTextStrokeColorIsCurrentColor
+ && m_visitedLinkTextFillColorIsCurrentColor == o.m_visitedLinkTextFillColorIsCurrentColor
+ && m_visitedLinkTextEmphasisColorIsCurrentColor == o.m_visitedLinkTextEmphasisColorIsCurrentColor
&& textSecurity == o.textSecurity
&& userModify == o.userModify
&& wordBreak == o.wordBreak
@@ -202,29 +208,29 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
&& m_textJustify == o.m_textJustify
&& m_textOrientation == o.m_textOrientation
&& m_textIndentLine == o.m_textIndentLine
+ && m_textIndentType == o.m_textIndentType
&& m_lineBoxContain == o.m_lineBoxContain
+ && m_subtreeWillChangeContents == o.m_subtreeWillChangeContents
&& hyphenationString == o.hyphenationString
&& locale == o.locale
&& textEmphasisCustomMark == o.textEmphasisCustomMark
- && QuotesData::equals(quotes.get(), o.quotes.get())
+ && quotesDataEquivalent(o)
&& m_tabSize == o.m_tabSize
- && m_lineGrid == o.m_lineGrid
&& m_imageRendering == o.m_imageRendering
&& m_textUnderlinePosition == o.m_textUnderlinePosition
&& m_rubyPosition == o.m_rubyPosition
- && m_lineSnap == o.m_lineSnap
- && m_variables == o.m_variables
- && m_lineAlign == o.m_lineAlign
- && StyleImage::imagesEquivalent(listStyleImage.get(), o.listStyleImage.get());
+ && dataEquivalent(listStyleImage.get(), o.listStyleImage.get())
+ && dataEquivalent(appliedTextDecorations, o.appliedTextDecorations);
}
bool StyleRareInheritedData::shadowDataEquivalent(const StyleRareInheritedData& o) const
{
- if ((!textShadow && o.textShadow) || (textShadow && !o.textShadow))
- return false;
- if (textShadow && o.textShadow && (*textShadow != *o.textShadow))
- return false;
- return true;
+ return dataEquivalent(textShadow.get(), o.textShadow.get());
+}
+
+bool StyleRareInheritedData::quotesDataEquivalent(const StyleRareInheritedData& o) const
+{
+ return dataEquivalent(quotes, o.quotes);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.h
index 11d3c4b0f52..4dd0ba554a2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareInheritedData.h
@@ -25,21 +25,26 @@
#ifndef StyleRareInheritedData_h
#define StyleRareInheritedData_h
+#include "core/css/StyleColor.h"
#include "core/rendering/style/DataRef.h"
-#include "core/rendering/style/StyleVariableData.h"
#include "platform/Length.h"
#include "platform/graphics/Color.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
+#include "wtf/RefVector.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
-class CursorList;
+class AppliedTextDecoration;
+class CursorData;
class QuotesData;
class ShadowList;
class StyleImage;
+typedef RefVector<AppliedTextDecoration> AppliedTextDecorationList;
+typedef RefVector<CursorData> CursorList;
+
// This struct is for rarely used inherited CSS3, CSS2, and WebKit-specific properties.
// By grouping them together, we save space, and only allocate this object when someone
// actually uses one of these properties.
@@ -55,17 +60,32 @@ public:
return !(*this == o);
}
bool shadowDataEquivalent(const StyleRareInheritedData&) const;
+ bool quotesDataEquivalent(const StyleRareInheritedData&) const;
RefPtr<StyleImage> listStyleImage;
- Color textStrokeColor;
+ StyleColor textStrokeColor() const { return m_textStrokeColorIsCurrentColor ? StyleColor::currentColor() : StyleColor(m_textStrokeColor); }
+ StyleColor textFillColor() const { return m_textFillColorIsCurrentColor ? StyleColor::currentColor() : StyleColor(m_textFillColor); }
+ StyleColor textEmphasisColor() const { return m_textEmphasisColorIsCurrentColor ? StyleColor::currentColor() : StyleColor(m_textEmphasisColor); }
+ StyleColor visitedLinkTextStrokeColor() const { return m_visitedLinkTextStrokeColorIsCurrentColor ? StyleColor::currentColor() : StyleColor(m_visitedLinkTextStrokeColor); }
+ StyleColor visitedLinkTextFillColor() const { return m_visitedLinkTextFillColorIsCurrentColor ? StyleColor::currentColor() : StyleColor(m_visitedLinkTextFillColor); }
+ StyleColor visitedLinkTextEmphasisColor() const { return m_visitedLinkTextEmphasisColorIsCurrentColor ? StyleColor::currentColor() : StyleColor(m_visitedLinkTextEmphasisColor); }
+
+ void setTextStrokeColor(const StyleColor& color) { m_textStrokeColor = color.resolve(Color()); m_textStrokeColorIsCurrentColor = color.isCurrentColor(); }
+ void setTextFillColor(const StyleColor& color) { m_textFillColor = color.resolve(Color()); m_textFillColorIsCurrentColor = color.isCurrentColor(); }
+ void setTextEmphasisColor(const StyleColor& color) { m_textEmphasisColor = color.resolve(Color()); m_textEmphasisColorIsCurrentColor = color.isCurrentColor(); }
+ void setVisitedLinkTextStrokeColor(const StyleColor& color) { m_visitedLinkTextStrokeColor = color.resolve(Color()); m_visitedLinkTextStrokeColorIsCurrentColor = color.isCurrentColor(); }
+ void setVisitedLinkTextFillColor(const StyleColor& color) { m_visitedLinkTextFillColor = color.resolve(Color()); m_visitedLinkTextFillColorIsCurrentColor = color.isCurrentColor(); }
+ void setVisitedLinkTextEmphasisColor(const StyleColor& color) { m_visitedLinkTextEmphasisColor = color.resolve(Color()); m_visitedLinkTextEmphasisColorIsCurrentColor = color.isCurrentColor(); }
+
+ Color m_textStrokeColor;
float textStrokeWidth;
- Color textFillColor;
- Color textEmphasisColor;
+ Color m_textFillColor;
+ Color m_textEmphasisColor;
- Color visitedLinkTextStrokeColor;
- Color visitedLinkTextFillColor;
- Color visitedLinkTextEmphasisColor;
+ Color m_visitedLinkTextStrokeColor;
+ Color m_visitedLinkTextFillColor;
+ Color m_visitedLinkTextEmphasisColor;
RefPtr<ShadowList> textShadow; // Our text shadow information for shadowed text drawing.
AtomicString highlight; // Apple-specific extension for custom highlight rendering.
@@ -80,6 +100,13 @@ public:
unsigned m_hasAutoWidows : 1;
unsigned m_hasAutoOrphans : 1;
+ unsigned m_textStrokeColorIsCurrentColor : 1;
+ unsigned m_textFillColorIsCurrentColor : 1;
+ unsigned m_textEmphasisColorIsCurrentColor : 1;
+ unsigned m_visitedLinkTextStrokeColorIsCurrentColor : 1;
+ unsigned m_visitedLinkTextFillColorIsCurrentColor : 1;
+ unsigned m_visitedLinkTextEmphasisColorIsCurrentColor : 1;
+
unsigned textSecurity : 2; // ETextSecurity
unsigned userModify : 2; // EUserModify (editing)
unsigned wordBreak : 2; // EWordBreak
@@ -96,15 +123,18 @@ public:
unsigned m_textJustify : 2; // TextJustify
unsigned m_textOrientation : 2; // TextOrientation
unsigned m_textIndentLine : 1; // TextIndentEachLine
+ unsigned m_textIndentType : 1; // TextIndentHanging
unsigned m_lineBoxContain: 7; // LineBoxContain
// CSS Image Values Level 3
unsigned m_imageRendering : 2; // EImageRendering
- unsigned m_lineSnap : 2; // LineSnap
- unsigned m_lineAlign : 1; // LineAlign
unsigned m_textUnderlinePosition : 2; // TextUnderlinePosition
unsigned m_rubyPosition : 1; // RubyPosition
unsigned m_touchActionDelay : 1; // TouchActionDelay
+ // Though will-change is not itself an inherited property, the intent
+ // expressed by 'will-change: contents' includes descendants.
+ unsigned m_subtreeWillChangeContents : 1;
+
AtomicString hyphenationString;
short hyphenationLimitBefore;
short hyphenationLimitAfter;
@@ -115,12 +145,11 @@ public:
AtomicString textEmphasisCustomMark;
RefPtr<QuotesData> quotes;
- AtomicString m_lineGrid;
unsigned m_tabSize;
Color tapHighlightColor;
- DataRef<StyleVariableData> m_variables;
+ RefPtr<AppliedTextDecorationList> appliedTextDecorations;
private:
StyleRareInheritedData();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp
index 2d312788ec6..165edc705a4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp
@@ -23,6 +23,7 @@
#include "core/rendering/style/StyleRareNonInheritedData.h"
#include "core/rendering/style/ContentData.h"
+#include "core/rendering/style/DataEquivalency.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/ShadowList.h"
#include "core/rendering/style/StyleFilterData.h"
@@ -42,27 +43,28 @@ StyleRareNonInheritedData::StyleRareNonInheritedData()
, m_draggableRegionMode(DraggableRegionNone)
, m_mask(MaskFillLayer, true)
, m_pageSize()
- , m_shapeInside(RenderStyle::initialShapeInside())
, m_shapeOutside(RenderStyle::initialShapeOutside())
, m_shapeMargin(RenderStyle::initialShapeMargin())
- , m_shapePadding(RenderStyle::initialShapePadding())
, m_shapeImageThreshold(RenderStyle::initialShapeImageThreshold())
, m_clipPath(RenderStyle::initialClipPath())
+ , m_textDecorationColor(StyleColor::currentColor())
+ , m_visitedLinkTextDecorationColor(StyleColor::currentColor())
, m_visitedLinkBackgroundColor(RenderStyle::initialBackgroundColor())
+ , m_visitedLinkOutlineColor(StyleColor::currentColor())
+ , m_visitedLinkBorderLeftColor(StyleColor::currentColor())
+ , m_visitedLinkBorderRightColor(StyleColor::currentColor())
+ , m_visitedLinkBorderTopColor(StyleColor::currentColor())
+ , m_visitedLinkBorderBottomColor(StyleColor::currentColor())
, m_order(RenderStyle::initialOrder())
, m_objectPosition(RenderStyle::initialObjectPosition())
- , m_flowThread(RenderStyle::initialFlowThread())
- , m_regionThread(RenderStyle::initialRegionThread())
- , m_regionFragment(RenderStyle::initialRegionFragment())
- , m_regionBreakAfter(RenderStyle::initialPageBreak())
- , m_regionBreakBefore(RenderStyle::initialPageBreak())
- , m_regionBreakInside(RenderStyle::initialPageBreak())
, m_pageSizeType(PAGE_SIZE_AUTO)
, m_transformStyle3D(RenderStyle::initialTransformStyle3D())
, m_backfaceVisibility(RenderStyle::initialBackfaceVisibility())
, m_alignContent(RenderStyle::initialAlignContent())
, m_alignItems(RenderStyle::initialAlignItems())
+ , m_alignItemsOverflowAlignment(RenderStyle::initialAlignItemsOverflowAlignment())
, m_alignSelf(RenderStyle::initialAlignSelf())
+ , m_alignSelfOverflowAlignment(RenderStyle::initialAlignSelfOverflowAlignment())
, m_justifyContent(RenderStyle::initialJustifyContent())
, userDrag(RenderStyle::initialUserDrag())
, textOverflow(RenderStyle::initialTextOverflow())
@@ -74,12 +76,21 @@ StyleRareNonInheritedData::StyleRareNonInheritedData()
, m_textDecorationStyle(RenderStyle::initialTextDecorationStyle())
, m_wrapFlow(RenderStyle::initialWrapFlow())
, m_wrapThrough(RenderStyle::initialWrapThrough())
- , m_runningAcceleratedAnimation(false)
+ , m_hasCurrentOpacityAnimation(false)
+ , m_hasCurrentTransformAnimation(false)
+ , m_hasCurrentFilterAnimation(false)
+ , m_runningOpacityAnimationOnCompositor(false)
+ , m_runningTransformAnimationOnCompositor(false)
+ , m_runningFilterAnimationOnCompositor(false)
, m_hasAspectRatio(false)
, m_effectiveBlendMode(RenderStyle::initialBlendMode())
, m_touchAction(RenderStyle::initialTouchAction())
, m_objectFit(RenderStyle::initialObjectFit())
, m_isolation(RenderStyle::initialIsolation())
+ , m_justifySelf(RenderStyle::initialJustifySelf())
+ , m_justifySelfOverflowAlignment(RenderStyle::initialJustifySelfOverflowAlignment())
+ , m_scrollBehavior(RenderStyle::initialScrollBehavior())
+ , m_requiresAcceleratedCompositingForExternalReasons(false)
{
m_maskBoxImage.setMaskDefaults();
}
@@ -99,6 +110,7 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited
, m_marquee(o.m_marquee)
, m_multiCol(o.m_multiCol)
, m_transform(o.m_transform)
+ , m_willChange(o.m_willChange)
, m_filter(o.m_filter)
, m_grid(o.m_grid)
, m_gridItem(o.m_gridItem)
@@ -106,15 +118,13 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited
, m_counterDirectives(o.m_counterDirectives ? clone(*o.m_counterDirectives) : nullptr)
, m_boxShadow(o.m_boxShadow)
, m_boxReflect(o.m_boxReflect)
- , m_animations(o.m_animations ? adoptPtr(new CSSAnimationDataList(*o.m_animations)) : nullptr)
- , m_transitions(o.m_transitions ? adoptPtr(new CSSAnimationDataList(*o.m_transitions)) : nullptr)
+ , m_animations(o.m_animations ? CSSAnimationData::create(*o.m_animations) : nullptr)
+ , m_transitions(o.m_transitions ? CSSTransitionData::create(*o.m_transitions) : nullptr)
, m_mask(o.m_mask)
, m_maskBoxImage(o.m_maskBoxImage)
, m_pageSize(o.m_pageSize)
- , m_shapeInside(o.m_shapeInside)
, m_shapeOutside(o.m_shapeOutside)
, m_shapeMargin(o.m_shapeMargin)
- , m_shapePadding(o.m_shapePadding)
, m_shapeImageThreshold(o.m_shapeImageThreshold)
, m_clipPath(o.m_clipPath)
, m_textDecorationColor(o.m_textDecorationColor)
@@ -127,18 +137,14 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited
, m_visitedLinkBorderBottomColor(o.m_visitedLinkBorderBottomColor)
, m_order(o.m_order)
, m_objectPosition(o.m_objectPosition)
- , m_flowThread(o.m_flowThread)
- , m_regionThread(o.m_regionThread)
- , m_regionFragment(o.m_regionFragment)
- , m_regionBreakAfter(o.m_regionBreakAfter)
- , m_regionBreakBefore(o.m_regionBreakBefore)
- , m_regionBreakInside(o.m_regionBreakInside)
, m_pageSizeType(o.m_pageSizeType)
, m_transformStyle3D(o.m_transformStyle3D)
, m_backfaceVisibility(o.m_backfaceVisibility)
, m_alignContent(o.m_alignContent)
, m_alignItems(o.m_alignItems)
+ , m_alignItemsOverflowAlignment(o.m_alignItemsOverflowAlignment)
, m_alignSelf(o.m_alignSelf)
+ , m_alignSelfOverflowAlignment(o.m_alignSelfOverflowAlignment)
, m_justifyContent(o.m_justifyContent)
, userDrag(o.userDrag)
, textOverflow(o.textOverflow)
@@ -150,12 +156,21 @@ StyleRareNonInheritedData::StyleRareNonInheritedData(const StyleRareNonInherited
, m_textDecorationStyle(o.m_textDecorationStyle)
, m_wrapFlow(o.m_wrapFlow)
, m_wrapThrough(o.m_wrapThrough)
- , m_runningAcceleratedAnimation(o.m_runningAcceleratedAnimation)
+ , m_hasCurrentOpacityAnimation(o.m_hasCurrentOpacityAnimation)
+ , m_hasCurrentTransformAnimation(o.m_hasCurrentTransformAnimation)
+ , m_hasCurrentFilterAnimation(o.m_hasCurrentFilterAnimation)
+ , m_runningOpacityAnimationOnCompositor(o.m_runningOpacityAnimationOnCompositor)
+ , m_runningTransformAnimationOnCompositor(o.m_runningTransformAnimationOnCompositor)
+ , m_runningFilterAnimationOnCompositor(o.m_runningFilterAnimationOnCompositor)
, m_hasAspectRatio(o.m_hasAspectRatio)
, m_effectiveBlendMode(o.m_effectiveBlendMode)
, m_touchAction(o.m_touchAction)
, m_objectFit(o.m_objectFit)
, m_isolation(o.m_isolation)
+ , m_justifySelf(o.m_justifySelf)
+ , m_justifySelfOverflowAlignment(o.m_justifySelfOverflowAlignment)
+ , m_scrollBehavior(o.m_scrollBehavior)
+ , m_requiresAcceleratedCompositingForExternalReasons(o.m_requiresAcceleratedCompositingForExternalReasons)
{
}
@@ -181,6 +196,7 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
&& m_marquee == o.m_marquee
&& m_multiCol == o.m_multiCol
&& m_transform == o.m_transform
+ && m_willChange == o.m_willChange
&& m_filter == o.m_filter
&& m_grid == o.m_grid
&& m_gridItem == o.m_gridItem
@@ -193,10 +209,8 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
&& m_mask == o.m_mask
&& m_maskBoxImage == o.m_maskBoxImage
&& m_pageSize == o.m_pageSize
- && m_shapeInside == o.m_shapeInside
&& m_shapeOutside == o.m_shapeOutside
&& m_shapeMargin == o.m_shapeMargin
- && m_shapePadding == o.m_shapePadding
&& m_shapeImageThreshold == o.m_shapeImageThreshold
&& m_clipPath == o.m_clipPath
&& m_textDecorationColor == o.m_textDecorationColor
@@ -210,18 +224,14 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
&& m_order == o.m_order
&& m_objectPosition == o.m_objectPosition
&& m_callbackSelectors == o.m_callbackSelectors
- && m_flowThread == o.m_flowThread
- && m_regionThread == o.m_regionThread
- && m_regionFragment == o.m_regionFragment
- && m_regionBreakAfter == o.m_regionBreakAfter
- && m_regionBreakBefore == o.m_regionBreakBefore
- && m_regionBreakInside == o.m_regionBreakInside
&& m_pageSizeType == o.m_pageSizeType
&& m_transformStyle3D == o.m_transformStyle3D
&& m_backfaceVisibility == o.m_backfaceVisibility
&& m_alignContent == o.m_alignContent
&& m_alignItems == o.m_alignItems
+ && m_alignItemsOverflowAlignment == o.m_alignItemsOverflowAlignment
&& m_alignSelf == o.m_alignSelf
+ && m_alignSelfOverflowAlignment == o.m_alignSelfOverflowAlignment
&& m_justifyContent == o.m_justifyContent
&& userDrag == o.userDrag
&& textOverflow == o.textOverflow
@@ -233,12 +243,18 @@ bool StyleRareNonInheritedData::operator==(const StyleRareNonInheritedData& o) c
&& m_textDecorationStyle == o.m_textDecorationStyle
&& m_wrapFlow == o.m_wrapFlow
&& m_wrapThrough == o.m_wrapThrough
- && !m_runningAcceleratedAnimation && !o.m_runningAcceleratedAnimation
+ && m_hasCurrentOpacityAnimation == o.m_hasCurrentOpacityAnimation
+ && m_hasCurrentTransformAnimation == o.m_hasCurrentTransformAnimation
+ && m_hasCurrentFilterAnimation == o.m_hasCurrentFilterAnimation
&& m_effectiveBlendMode == o.m_effectiveBlendMode
&& m_hasAspectRatio == o.m_hasAspectRatio
&& m_touchAction == o.m_touchAction
&& m_objectFit == o.m_objectFit
- && m_isolation == o.m_isolation;
+ && m_isolation == o.m_isolation
+ && m_justifySelf == o.m_justifySelf
+ && m_justifySelfOverflowAlignment == o.m_justifySelfOverflowAlignment
+ && m_scrollBehavior == o.m_scrollBehavior
+ && m_requiresAcceleratedCompositingForExternalReasons == o.m_requiresAcceleratedCompositingForExternalReasons;
}
bool StyleRareNonInheritedData::contentDataEquivalent(const StyleRareNonInheritedData& o) const
@@ -256,50 +272,35 @@ bool StyleRareNonInheritedData::contentDataEquivalent(const StyleRareNonInherite
bool StyleRareNonInheritedData::counterDataEquivalent(const StyleRareNonInheritedData& o) const
{
- if (m_counterDirectives.get() == o.m_counterDirectives.get())
- return true;
-
- if (m_counterDirectives && o.m_counterDirectives && *m_counterDirectives == *o.m_counterDirectives)
- return true;
-
- return false;
+ return dataEquivalent(m_counterDirectives, o.m_counterDirectives);
}
bool StyleRareNonInheritedData::shadowDataEquivalent(const StyleRareNonInheritedData& o) const
{
- if ((!m_boxShadow && o.m_boxShadow) || (m_boxShadow && !o.m_boxShadow))
- return false;
- if (m_boxShadow && o.m_boxShadow && (*m_boxShadow != *o.m_boxShadow))
- return false;
- return true;
+ return dataEquivalent(m_boxShadow, o.m_boxShadow);
}
bool StyleRareNonInheritedData::reflectionDataEquivalent(const StyleRareNonInheritedData& o) const
{
- if (m_boxReflect != o.m_boxReflect) {
- if (!m_boxReflect || !o.m_boxReflect)
- return false;
- return *m_boxReflect == *o.m_boxReflect;
- }
- return true;
+ return dataEquivalent(m_boxReflect, o.m_boxReflect);
}
bool StyleRareNonInheritedData::animationDataEquivalent(const StyleRareNonInheritedData& o) const
{
- if ((!m_animations && o.m_animations) || (m_animations && !o.m_animations))
- return false;
- if (m_animations && o.m_animations && (*m_animations != *o.m_animations))
+ if (!m_animations && !o.m_animations)
+ return true;
+ if (!m_animations || !o.m_animations)
return false;
- return true;
+ return m_animations->animationsMatchForStyleRecalc(*o.m_animations);
}
bool StyleRareNonInheritedData::transitionDataEquivalent(const StyleRareNonInheritedData& o) const
{
- if ((!m_transitions && o.m_transitions) || (m_transitions && !o.m_transitions))
- return false;
- if (m_transitions && o.m_transitions && (*m_transitions != *o.m_transitions))
+ if (!m_transitions && !o.m_transitions)
+ return true;
+ if (!m_transitions || !o.m_transitions)
return false;
- return true;
+ return m_transitions->transitionsMatchForStyleRecalc(*o.m_transitions);
}
bool StyleRareNonInheritedData::hasFilters() const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.h
index 9ce04870219..f23461abab3 100755..100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.h
@@ -25,6 +25,7 @@
#ifndef StyleRareNonInheritedData_h
#define StyleRareNonInheritedData_h
+#include "core/css/StyleColor.h"
#include "core/rendering/ClipPathOperation.h"
#include "core/rendering/style/BasicShapes.h"
#include "core/rendering/style/CounterDirectives.h"
@@ -43,7 +44,9 @@
namespace WebCore {
class ContentData;
-class CSSAnimationDataList;
+class CSSAnimationData;
+class CSSTransitionData;
+class LengthSize;
class ShadowList;
class StyleDeprecatedFlexibleBoxData;
class StyleFilterData;
@@ -53,10 +56,8 @@ class StyleGridItemData;
class StyleMarqueeData;
class StyleMultiColData;
class StyleReflection;
-class StyleResolver;
class StyleTransformData;
-
-struct LengthSize;
+class StyleWillChangeData;
// Page size type.
// StyleRareNonInheritedData::m_pageSize is meaningful only when
@@ -106,6 +107,7 @@ public:
DataRef<StyleMarqueeData> m_marquee; // Marquee properties
DataRef<StyleMultiColData> m_multiCol; // CSS3 multicol properties
DataRef<StyleTransformData> m_transform; // Transform properties (rotate, scale, skew, etc.)
+ DataRef<StyleWillChangeData> m_willChange; // CSS Will Change
DataRef<StyleFilterData> m_filter; // Filter operations (url, sepia, blur, etc.)
@@ -119,30 +121,28 @@ public:
RefPtr<StyleReflection> m_boxReflect;
- OwnPtr<CSSAnimationDataList> m_animations;
- OwnPtr<CSSAnimationDataList> m_transitions;
+ OwnPtrWillBePersistent<CSSAnimationData> m_animations;
+ OwnPtrWillBePersistent<CSSTransitionData> m_transitions;
FillLayer m_mask;
NinePieceImage m_maskBoxImage;
LengthSize m_pageSize;
- RefPtr<ShapeValue> m_shapeInside;
RefPtr<ShapeValue> m_shapeOutside;
Length m_shapeMargin;
- Length m_shapePadding;
float m_shapeImageThreshold;
RefPtr<ClipPathOperation> m_clipPath;
- Color m_textDecorationColor;
- Color m_visitedLinkTextDecorationColor;
- Color m_visitedLinkBackgroundColor;
- Color m_visitedLinkOutlineColor;
- Color m_visitedLinkBorderLeftColor;
- Color m_visitedLinkBorderRightColor;
- Color m_visitedLinkBorderTopColor;
- Color m_visitedLinkBorderBottomColor;
+ StyleColor m_textDecorationColor;
+ StyleColor m_visitedLinkTextDecorationColor;
+ StyleColor m_visitedLinkBackgroundColor;
+ StyleColor m_visitedLinkOutlineColor;
+ StyleColor m_visitedLinkBorderLeftColor;
+ StyleColor m_visitedLinkBorderRightColor;
+ StyleColor m_visitedLinkBorderTopColor;
+ StyleColor m_visitedLinkBorderBottomColor;
int m_order;
@@ -150,21 +150,15 @@ public:
Vector<String> m_callbackSelectors;
- AtomicString m_flowThread;
- AtomicString m_regionThread;
- unsigned m_regionFragment : 1; // RegionFragment
-
- unsigned m_regionBreakAfter : 2; // EPageBreak
- unsigned m_regionBreakBefore : 2; // EPageBreak
- unsigned m_regionBreakInside : 2; // EPageBreak
-
unsigned m_pageSizeType : 2; // PageSizeType
unsigned m_transformStyle3D : 1; // ETransformStyle3D
unsigned m_backfaceVisibility : 1; // EBackfaceVisibility
unsigned m_alignContent : 3; // EAlignContent
- unsigned m_alignItems : 3; // EAlignItems
- unsigned m_alignSelf : 3; // EAlignItems
+ unsigned m_alignItems : 4; // ItemPosition
+ unsigned m_alignItemsOverflowAlignment : 2; // OverflowAlignment
+ unsigned m_alignSelf : 4; // ItemPosition
+ unsigned m_alignSelfOverflowAlignment : 2; // OverflowAlignment
unsigned m_justifyContent : 3; // EJustifyContent
unsigned userDrag : 2; // EUserDrag
@@ -179,7 +173,12 @@ public:
unsigned m_wrapFlow: 3; // WrapFlow
unsigned m_wrapThrough: 1; // WrapThrough
- unsigned m_runningAcceleratedAnimation : 1;
+ unsigned m_hasCurrentOpacityAnimation : 1;
+ unsigned m_hasCurrentTransformAnimation : 1;
+ unsigned m_hasCurrentFilterAnimation : 1;
+ unsigned m_runningOpacityAnimationOnCompositor : 1;
+ unsigned m_runningTransformAnimationOnCompositor : 1;
+ unsigned m_runningFilterAnimationOnCompositor : 1;
unsigned m_hasAspectRatio : 1; // Whether or not an aspect ratio has been specified.
@@ -191,6 +190,19 @@ public:
unsigned m_isolation : 1; // Isolation
+ unsigned m_justifySelf : 4; // ItemPosition
+ unsigned m_justifySelfOverflowAlignment : 2; // OverflowAlignment
+
+ // ScrollBehavior. 'scroll-behavior' has 2 accepted values, but ScrollBehavior has a third
+ // value (that can only be specified using CSSOM scroll APIs) so 2 bits are needed.
+ unsigned m_scrollBehavior: 2;
+
+ // Plugins require accelerated compositing for reasons external to blink.
+ // In which case, we need to update the RenderStyle on the RenderEmbeddedObject,
+ // so store this bit so that the style actually changes when the plugin
+ // becomes composited.
+ unsigned m_requiresAcceleratedCompositingForExternalReasons: 1;
+
private:
StyleRareNonInheritedData();
StyleRareNonInheritedData(const StyleRareNonInheritedData&);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleShader.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleShader.h
deleted file mode 100644
index c5927e67591..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleShader.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef StyleShader_h
-#define StyleShader_h
-
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-class ShaderResource;
-class CSSValue;
-
-class StyleShader : public RefCounted<StyleShader> {
-public:
- virtual ~StyleShader() { }
-
- ALWAYS_INLINE bool isShaderResource() const { return m_isShaderResource; }
- ALWAYS_INLINE bool isPendingShader() const { return m_isPendingShader; }
-
- virtual PassRefPtr<CSSValue> cssValue() const = 0;
-
- virtual ShaderResource* resource() const { return 0; }
-
-protected:
- StyleShader()
- : m_isShaderResource(false)
- , m_isPendingShader(false)
- {
- }
- bool m_isShaderResource : 1;
- bool m_isPendingShader : 1;
-};
-
-}
-
-
-#endif // StyleShader_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleVariableData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleVariableData.h
deleted file mode 100644
index 23429f19c2e..00000000000
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleVariableData.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef StyleVariableData_h
-#define StyleVariableData_h
-
-#include "wtf/Forward.h"
-#include "wtf/HashMap.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/AtomicStringHash.h"
-
-namespace WebCore {
-
-class CursorList;
-class QuotesData;
-class ShadowData;
-
-class StyleVariableData : public RefCounted<StyleVariableData> {
-public:
- static PassRefPtr<StyleVariableData> create() { return adoptRef(new StyleVariableData()); }
- PassRefPtr<StyleVariableData> copy() const { return adoptRef(new StyleVariableData(*this)); }
-
- bool operator==(const StyleVariableData& other) const { return other.m_data == m_data; }
- bool operator!=(const StyleVariableData& other) const { return !(*this == other); }
-
- void setVariable(const AtomicString& name, const String& value) { m_data.set(name, value); }
-
- HashMap<AtomicString, String> m_data;
-private:
- explicit StyleVariableData() : RefCounted<StyleVariableData>() { }
- StyleVariableData(const StyleVariableData& other) : RefCounted<StyleVariableData>(), m_data(HashMap<AtomicString, String>(other.m_data)) { }
-};
-
-} // namespace WebCore
-
-#endif /* StyleVariableData_h */
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
index db87122431b..e2774374bef 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
@@ -29,7 +29,6 @@ namespace WebCore {
StyleVisualData::StyleVisualData()
: hasClip(false)
, textDecoration(RenderStyle::initialTextDecoration())
- , m_textAutosizingMultiplier(1)
, m_zoom(RenderStyle::initialZoom())
{
}
@@ -43,7 +42,6 @@ StyleVisualData::StyleVisualData(const StyleVisualData& o)
, clip(o.clip)
, hasClip(o.hasClip)
, textDecoration(o.textDecoration)
- , m_textAutosizingMultiplier(o.m_textAutosizingMultiplier)
, m_zoom(RenderStyle::initialZoom())
{
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.h
index 2657b93ceec..ed79ea1aece 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleVisualData.h
@@ -43,7 +43,6 @@ public:
return clip == o.clip
&& hasClip == o.hasClip
&& textDecoration == o.textDecoration
- && m_textAutosizingMultiplier == o.m_textAutosizingMultiplier
&& m_zoom == o.m_zoom;
}
bool operator!=(const StyleVisualData& o) const { return !(*this == o); }
@@ -52,7 +51,6 @@ public:
bool hasClip : 1;
unsigned textDecoration : TextDecorationBits; // Text decorations defined *only* by this element.
- float m_textAutosizingMultiplier;
float m_zoom;
private:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp b/chromium/third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp
new file mode 100644
index 00000000000..7cd2bcbf0aa
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/rendering/style/StyleWillChangeData.h"
+
+namespace WebCore {
+
+StyleWillChangeData::StyleWillChangeData()
+ : m_contents(false)
+ , m_scrollPosition(false)
+{
+}
+
+StyleWillChangeData::StyleWillChangeData(const StyleWillChangeData& o)
+ : RefCounted<StyleWillChangeData>()
+ , m_properties(o.m_properties)
+ , m_contents(o.m_contents)
+ , m_scrollPosition(o.m_scrollPosition)
+{
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.h b/chromium/third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.h
new file mode 100644
index 00000000000..9a9b6e76212
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StyleWillChangeData_h
+#define StyleWillChangeData_h
+
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class StyleWillChangeData : public RefCounted<StyleWillChangeData> {
+public:
+ static PassRefPtr<StyleWillChangeData> create() { return adoptRef(new StyleWillChangeData); }
+ PassRefPtr<StyleWillChangeData> copy() const { return adoptRef(new StyleWillChangeData(*this)); }
+
+ bool operator==(const StyleWillChangeData& o) const
+ {
+ return m_properties == o.m_properties && m_contents == o.m_contents && m_scrollPosition == o.m_scrollPosition;
+ }
+
+ bool operator!=(const StyleWillChangeData& o) const
+ {
+ return !(*this == o);
+ }
+
+ Vector<CSSPropertyID> m_properties;
+ unsigned m_contents : 1;
+ unsigned m_scrollPosition : 1;
+
+private:
+ StyleWillChangeData();
+ StyleWillChangeData(const StyleWillChangeData&);
+};
+
+} // namespace WebCore
+
+#endif // StyleWillChangeData_h
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/ReferenceFilterBuilder.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
index 8c0a5c517a4..a53a3dcf118 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
@@ -29,9 +29,9 @@
#include "core/rendering/svg/ReferenceFilterBuilder.h"
-#include "SVGNames.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSPrimitiveValueMappings.h"
+#include "core/css/StylePropertySet.h"
#include "core/dom/Element.h"
#include "core/fetch/DocumentResource.h"
#include "core/rendering/svg/RenderSVGResourceFilter.h"
@@ -80,10 +80,11 @@ static bool getSVGElementColorSpace(SVGElement* svgElement, ColorSpace& cs)
if (svgStyle) {
// If a layout has been performed, then we can use the fast path to get this attribute
eColorInterpolation = svgStyle->colorInterpolationFilters();
+ } else if (!svgElement->presentationAttributeStyle()) {
+ return false;
} else {
// Otherwise, use the slow path by using string comparison (used by external svg files)
- RefPtr<CSSValue> cssValue = svgElement->getPresentationAttribute(
- SVGNames::color_interpolation_filtersAttr.toString());
+ RefPtrWillBeRawPtr<CSSValue> cssValue = svgElement->presentationAttributeStyle()->getPropertyCSSValue(CSSPropertyColorInterpolationFilters);
if (cssValue.get() && cssValue->isPrimitiveValue()) {
const CSSPrimitiveValue& primitiveValue = *((CSSPrimitiveValue*)cssValue.get());
eColorInterpolation = (EColorInterpolation)primitiveValue;
@@ -110,9 +111,9 @@ static bool getSVGElementColorSpace(SVGElement* svgElement, ColorSpace& cs)
PassRefPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* parentFilter, RenderObject* renderer, FilterEffect* previousEffect, const ReferenceFilterOperation* filterOperation)
{
if (!renderer)
- return 0;
+ return nullptr;
- Document* document = &renderer->document();
+ TreeScope* treeScope = &renderer->node()->treeScope();
if (DocumentResourceReference* documentResourceRef = documentResourceReference(filterOperation)) {
DocumentResource* cachedSVGDocument = documentResourceRef->document();
@@ -120,25 +121,25 @@ PassRefPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* parentFilter, Ren
// If we have an SVG document, this is an external reference. Otherwise
// we look up the referenced node in the current document.
if (cachedSVGDocument)
- document = cachedSVGDocument->document();
+ treeScope = cachedSVGDocument->document();
}
- if (!document)
- return 0;
+ if (!treeScope)
+ return nullptr;
- Element* filter = document->getElementById(filterOperation->fragment());
+ Element* filter = treeScope->getElementById(filterOperation->fragment());
if (!filter) {
// Although we did not find the referenced filter, it might exist later
- // in the document
- document->accessSVGExtensions()->addPendingResource(filterOperation->fragment(), toElement(renderer->node()));
- return 0;
+ // in the document.
+ treeScope->document().accessSVGExtensions().addPendingResource(filterOperation->fragment(), toElement(renderer->node()));
+ return nullptr;
}
- if (!filter->isSVGElement() || !filter->hasTagName(SVGNames::filterTag))
- return 0;
+ if (!isSVGFilterElement(*filter))
+ return nullptr;
- SVGFilterElement* filterElement = toSVGFilterElement(toSVGElement(filter));
+ SVGFilterElement& filterElement = toSVGFilterElement(*filter);
// FIXME: Figure out what to do with SourceAlpha. Right now, we're
// using the alpha of the original input layer, which is obviously
@@ -148,13 +149,9 @@ PassRefPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* parentFilter, Ren
RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(previousEffect, SourceAlpha::create(parentFilter));
ColorSpace filterColorSpace = ColorSpaceDeviceRGB;
- bool useFilterColorSpace = getSVGElementColorSpace(filterElement, filterColorSpace);
-
- for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement())
- continue;
+ bool useFilterColorSpace = getSVGElementColorSpace(&filterElement, filterColorSpace);
- SVGElement* element = toSVGElement(node);
+ for (SVGElement* element = Traversal<SVGElement>::firstChild(filterElement); element; element = Traversal<SVGElement>::nextSibling(*element)) {
if (!element->isFilterEffect())
continue;
@@ -165,11 +162,11 @@ PassRefPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* parentFilter, Ren
continue;
effectElement->setStandardAttributes(effect.get());
- effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnitsCurrentValue(), parentFilter->sourceImageRect()));
+ effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement.primitiveUnits()->currentValue()->enumValue(), parentFilter->sourceImageRect()));
ColorSpace colorSpace = filterColorSpace;
if (useFilterColorSpace || getSVGElementColorSpace(effectElement, colorSpace))
effect->setOperatingColorSpace(colorSpace);
- builder->add(effectElement->resultCurrentValue(), effect);
+ builder->add(AtomicString(effectElement->result()->currentValue()->value()), effect);
}
return builder->lastEffect();
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.cpp
index ab40394a4b3..8eddc1f1e6f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.cpp
@@ -23,7 +23,9 @@
#include "core/rendering/svg/RenderSVGBlock.h"
+#include "core/rendering/RenderView.h"
#include "core/rendering/style/ShadowList.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/rendering/svg/SVGResourcesCache.h"
#include "core/svg/SVGElement.h"
@@ -50,7 +52,7 @@ void RenderSVGBlock::updateFromStyle()
// RenderSVGlock, used by Render(SVGText|ForeignObject), is not allowed to call setHasOverflowClip(true).
// RenderBlock assumes a layer to be present when the overflow clip functionality is requested. Both
- // Render(SVGText|ForeignObject) return 'false' on 'requiresLayer'. Fine for RenderSVGText.
+ // Render(SVGText|ForeignObject) return 'NoLayer' on 'layerTypeRequired'. Fine for RenderSVGText.
//
// If we want to support overflow rules for <foreignObject> we can choose between two solutions:
// a) make RenderSVGForeignObject require layers and SVG layer aware
@@ -77,11 +79,46 @@ void RenderSVGBlock::willBeDestroyed()
void RenderSVGBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- if (diff == StyleDifferenceLayout)
+ if (diff.needsFullLayout())
setNeedsBoundariesUpdate();
RenderBlock::styleDidChange(diff, oldStyle);
SVGResourcesCache::clientStyleChanged(this, diff, style());
}
+void RenderSVGBlock::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
+{
+ SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
+}
+
+const RenderObject* RenderSVGBlock::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
+{
+ return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap);
+}
+
+LayoutRect RenderSVGBlock::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
+{
+ return SVGRenderSupport::clippedOverflowRectForRepaint(this, paintInvalidationContainer);
+}
+
+void RenderSVGBlock::computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect& paintInvalidationRect, bool fixed) const
+{
+ SVGRenderSupport::computeFloatRectForRepaint(this, paintInvalidationContainer, paintInvalidationRect, fixed);
+}
+
+bool RenderSVGBlock::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction)
+{
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+void RenderSVGBlock::invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer)
+{
+ if (!shouldCheckForPaintInvalidationAfterLayout())
+ return;
+
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
+ RenderBlockFlow::invalidateTreeAfterLayout(paintInvalidationContainer);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.h
index 6f08eb1f72f..1e21c7c639a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGBlock.h
@@ -32,19 +32,33 @@ public:
virtual LayoutRect visualOverflowRect() const OVERRIDE FINAL;
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE FINAL;
+ virtual void computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect&, bool fixed = false) const OVERRIDE FINAL;
+
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE FINAL;
+ virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE FINAL;
+
+ virtual AffineTransform localTransform() const OVERRIDE FINAL { return m_localTransform; }
+
+ virtual LayerType layerTypeRequired() const OVERRIDE FINAL { return NoLayer; }
+
+ virtual void invalidateTreeAfterLayout(const RenderLayerModelObject&) OVERRIDE;
+
protected:
virtual void willBeDestroyed() OVERRIDE;
+ AffineTransform m_localTransform;
+
private:
virtual void updateFromStyle() OVERRIDE FINAL;
- virtual bool isRenderSVGBlock() const OVERRIDE FINAL { return true; };
-
- virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+ virtual bool isSVG() const OVERRIDE FINAL { return true; }
virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE FINAL;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE FINAL;
+
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.cpp
index 04f28cae872..5767807922e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.cpp
@@ -25,13 +25,15 @@
#include "core/rendering/svg/RenderSVGContainer.h"
+#include "core/frame/Settings.h"
#include "core/rendering/GraphicsContextAnnotator.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/rendering/svg/SVGRenderingContext.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCache.h"
+#include "platform/graphics/GraphicsContextCullSaver.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
namespace WebCore {
@@ -52,9 +54,8 @@ void RenderSVGContainer::layout()
ASSERT(needsLayout());
// RenderSVGRoot disables layoutState for the SVG rendering tree.
- ASSERT(!view()->layoutStateEnabled());
+ ASSERT(!view()->layoutStateCachedOffsetsEnabled());
- LayoutRectRecorder recorder(*this);
LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) || selfWillPaint());
// Allow RenderSVGViewportContainer to update its viewport.
@@ -116,7 +117,7 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
if (!firstChild() && !selfWillPaint())
return;
- FloatRect repaintRect = repaintRectInLocalCoordinates();
+ FloatRect repaintRect = paintInvalidationRectInLocalCoordinates();
if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(repaintRect, localToParentTransform(), paintInfo))
return;
@@ -130,10 +131,14 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
childPaintInfo.applyTransform(localToParentTransform());
SVGRenderingContext renderingContext;
+ GraphicsContextCullSaver cullSaver(*childPaintInfo.context);
bool continueRendering = true;
if (childPaintInfo.phase == PaintPhaseForeground) {
renderingContext.prepareToRenderSVGContent(this, childPaintInfo);
continueRendering = renderingContext.isRenderingPrepared();
+
+ if (continueRendering && document().settings()->containerCullingEnabled())
+ cullSaver.cull(paintInvalidationRectInLocalCoordinates());
}
if (continueRendering) {
@@ -144,11 +149,11 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
}
// FIXME: This really should be drawn from local coordinates, but currently we hack it
- // to avoid our clip killing our outline rect. Thus we translate our
+ // to avoid our clip killing our outline rect. Thus we translate our
// outline rect into parent coords before drawing.
// FIXME: This means our focus ring won't share our rotation like it should.
// We should instead disable our clip during PaintPhaseOutline
- if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE) {
+ if (paintInfo.phase == PaintPhaseForeground && style()->outlineWidth() && style()->visibility() == VISIBLE) {
IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRect));
paintOutline(paintInfo, paintRectInParent);
}
@@ -157,7 +162,7 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
// addFocusRingRects is called from paintOutline and needs to be in the same coordinates as the paintOuline call
void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
{
- IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRectInLocalCoordinates()));
+ IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(paintInvalidationRectInLocalCoordinates()));
if (!paintRectInParent.isEmpty())
rects.append(paintRectInParent);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.h
index fd4e74db96b..b7235fbaded 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGContainer.h
@@ -37,12 +37,15 @@ public:
RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
+ // If you have a RenderSVGContainer, use firstChild or lastChild instead.
+ void slowFirstChild() const WTF_DELETED_FUNCTION;
+ void slowLastChild() const WTF_DELETED_FUNCTION;
+
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
virtual void setNeedsBoundariesUpdate() OVERRIDE FINAL { m_needsBoundariesUpdate = true; }
- virtual bool needsBoundariesUpdate() OVERRIDE FINAL { return m_needsBoundariesUpdate; }
virtual bool didTransformToRootUpdate() { return false; }
bool isObjectBoundingBoxValid() const { return m_objectBoundingBoxValid; }
@@ -51,9 +54,9 @@ protected:
virtual const RenderObjectChildList* virtualChildren() const OVERRIDE FINAL { return children(); }
virtual bool isSVGContainer() const OVERRIDE FINAL { return true; }
- virtual const char* renderName() const { return "RenderSVGContainer"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGContainer"; }
- virtual void layout();
+ virtual void layout() OVERRIDE;
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE FINAL;
virtual void removeChild(RenderObject*) OVERRIDE FINAL;
@@ -61,9 +64,9 @@ protected:
virtual FloatRect objectBoundingBox() const OVERRIDE FINAL { return m_objectBoundingBox; }
virtual FloatRect strokeBoundingBox() const OVERRIDE FINAL { return m_strokeBoundingBox; }
- virtual FloatRect repaintRectInLocalCoordinates() const OVERRIDE FINAL { return m_repaintBoundingBox; }
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const OVERRIDE FINAL { return m_repaintBoundingBox; }
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) OVERRIDE;
// Allow RenderSVGTransformableContainer to hook in at the right time in layout()
virtual bool calculateLocalTransform() { return false; }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.cpp
index ac5c6491fc3..b9a75029ae0 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.cpp
@@ -28,9 +28,9 @@
#include "core/rendering/svg/RenderSVGEllipse.h"
-#include "SVGNames.h"
#include "core/svg/SVGCircleElement.h"
#include "core/svg/SVGEllipseElement.h"
+#include "platform/graphics/GraphicsContext.h"
namespace WebCore {
@@ -53,20 +53,22 @@ void RenderSVGEllipse::updateShapeFromElement()
m_center = FloatPoint();
m_radii = FloatSize();
- // Fallback to RenderSVGShape if shape has a non-scaling stroke.
- if (hasNonScalingStroke()) {
- RenderSVGShape::updateShapeFromElement();
- m_usePathFallback = true;
- return;
- } else
- m_usePathFallback = false;
-
calculateRadiiAndCenter();
- // Spec: "A value of zero disables rendering of the element."
- if (m_radii.width() <= 0 || m_radii.height() <= 0)
+ // Spec: "A negative value is an error. A value of zero disables rendering of the element."
+ if (m_radii.width() < 0 || m_radii.height() < 0)
return;
+ if (!m_radii.isEmpty()) {
+ // Fallback to RenderSVGShape if shape has a non-scaling stroke.
+ if (hasNonScalingStroke()) {
+ RenderSVGShape::updateShapeFromElement();
+ m_usePathFallback = true;
+ return;
+ }
+ m_usePathFallback = false;
+ }
+
m_fillBoundingBox = FloatRect(m_center.x() - m_radii.width(), m_center.y() - m_radii.height(), 2 * m_radii.width(), 2 * m_radii.height());
m_strokeBoundingBox = m_fillBoundingBox;
if (style()->svgStyle()->hasStroke())
@@ -76,21 +78,21 @@ void RenderSVGEllipse::updateShapeFromElement()
void RenderSVGEllipse::calculateRadiiAndCenter()
{
ASSERT(element());
- if (element()->hasTagName(SVGNames::circleTag)) {
- SVGCircleElement* circle = toSVGCircleElement(element());
+ if (isSVGCircleElement(*element())) {
+ SVGCircleElement& circle = toSVGCircleElement(*element());
- SVGLengthContext lengthContext(circle);
- float radius = circle->rCurrentValue().value(lengthContext);
+ SVGLengthContext lengthContext(&circle);
+ float radius = circle.r()->currentValue()->value(lengthContext);
m_radii = FloatSize(radius, radius);
- m_center = FloatPoint(circle->cxCurrentValue().value(lengthContext), circle->cyCurrentValue().value(lengthContext));
+ m_center = FloatPoint(circle.cx()->currentValue()->value(lengthContext), circle.cy()->currentValue()->value(lengthContext));
return;
}
- SVGEllipseElement* ellipse = toSVGEllipseElement(element());
+ SVGEllipseElement& ellipse = toSVGEllipseElement(*element());
- SVGLengthContext lengthContext(ellipse);
- m_radii = FloatSize(ellipse->rxCurrentValue().value(lengthContext), ellipse->ryCurrentValue().value(lengthContext));
- m_center = FloatPoint(ellipse->cxCurrentValue().value(lengthContext), ellipse->cyCurrentValue().value(lengthContext));
+ SVGLengthContext lengthContext(&ellipse);
+ m_radii = FloatSize(ellipse.rx()->currentValue()->value(lengthContext), ellipse.ry()->currentValue()->value(lengthContext));
+ m_center = FloatPoint(ellipse.cx()->currentValue()->value(lengthContext), ellipse.cy()->currentValue()->value(lengthContext));
}
void RenderSVGEllipse::fillShape(GraphicsContext* context) const
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.h
index f06e5c16cf0..b73b5526853 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGEllipse.h
@@ -37,14 +37,14 @@ public:
virtual ~RenderSVGEllipse();
private:
- virtual const char* renderName() const { return "RenderSVGEllipse"; }
-
- virtual void updateShapeFromElement();
- virtual bool isEmpty() const { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); };
- virtual void fillShape(GraphicsContext*) const;
- virtual void strokeShape(GraphicsContext*) const;
- virtual bool shapeDependentStrokeContains(const FloatPoint&);
- virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGEllipse"; }
+
+ virtual void updateShapeFromElement() OVERRIDE;
+ virtual bool isShapeEmpty() const OVERRIDE { return m_usePathFallback ? RenderSVGShape::isShapeEmpty() : m_fillBoundingBox.isEmpty(); }
+ virtual void fillShape(GraphicsContext*) const OVERRIDE;
+ virtual void strokeShape(GraphicsContext*) const OVERRIDE;
+ virtual bool shapeDependentStrokeContains(const FloatPoint&) OVERRIDE;
+ virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const OVERRIDE;
void calculateRadiiAndCenter();
private:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.cpp
index e27e037926f..9a9459836e1 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.cpp
@@ -24,7 +24,6 @@
#include "core/rendering/svg/RenderSVGForeignObject.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/svg/SVGRenderSupport.h"
@@ -45,6 +44,12 @@ RenderSVGForeignObject::~RenderSVGForeignObject()
{
}
+bool RenderSVGForeignObject::isChildAllowed(RenderObject* child, RenderStyle* style) const
+{
+ // Disallow arbitary SVG content. Only allow proper <svg xmlns="svgNS"> subdocuments.
+ return !child->isSVG() || child->isSVGRoot();
+}
+
void RenderSVGForeignObject::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
if (paintInfo.context->paintingDisabled()
@@ -85,16 +90,6 @@ void RenderSVGForeignObject::paint(PaintInfo& paintInfo, const LayoutPoint&)
}
}
-LayoutRect RenderSVGForeignObject::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
-{
- return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
-}
-
-void RenderSVGForeignObject::computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const
-{
- SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed);
-}
-
const AffineTransform& RenderSVGForeignObject::localToParentTransform() const
{
m_localToParentTransform = localTransform();
@@ -121,9 +116,8 @@ void RenderSVGForeignObject::computeLogicalHeight(LayoutUnit, LayoutUnit logical
void RenderSVGForeignObject::layout()
{
ASSERT(needsLayout());
- ASSERT(!view()->layoutStateEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
+ ASSERT(!view()->layoutStateCachedOffsetsEnabled()); // RenderSVGRoot disables layoutState for the SVG rendering tree.
- LayoutRectRecorder recorder(*this);
LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this));
SVGForeignObjectElement* foreign = toSVGForeignObjectElement(node());
@@ -138,8 +132,8 @@ void RenderSVGForeignObject::layout()
// Cache viewport boundaries
SVGLengthContext lengthContext(foreign);
- FloatPoint viewportLocation(foreign->xCurrentValue().value(lengthContext), foreign->yCurrentValue().value(lengthContext));
- m_viewport = FloatRect(viewportLocation, FloatSize(foreign->widthCurrentValue().value(lengthContext), foreign->heightCurrentValue().value(lengthContext)));
+ FloatPoint viewportLocation(foreign->x()->currentValue()->value(lengthContext), foreign->y()->currentValue()->value(lengthContext));
+ m_viewport = FloatRect(viewportLocation, FloatSize(foreign->width()->currentValue()->value(lengthContext), foreign->height()->currentValue()->value(lengthContext)));
if (!updateCachedBoundariesInParents)
updateCachedBoundariesInParents = oldViewport != m_viewport;
@@ -165,6 +159,14 @@ void RenderSVGForeignObject::layout()
repainter.repaintAfterLayout();
}
+void RenderSVGForeignObject::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer,
+ LayoutRect& rect, bool fixed) const
+{
+ FloatRect r(rect);
+ SVGRenderSupport::computeFloatRectForRepaint(this, paintInvalidationContainer, r, fixed);
+ rect = enclosingLayoutRect(r);
+}
+
bool RenderSVGForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
// Embedded content is drawn in the foreground phase.
@@ -184,20 +186,4 @@ bool RenderSVGForeignObject::nodeAtFloatPoint(const HitTestRequest& request, Hit
|| RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestChildBlockBackgrounds);
}
-bool RenderSVGForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction)
-{
- ASSERT_NOT_REACHED();
- return false;
-}
-
-void RenderSVGForeignObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
-{
- SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
-}
-
-const RenderObject* RenderSVGForeignObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
-{
- return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap);
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.h
index 63cdac1d35b..d57b723aa18 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGForeignObject.h
@@ -32,38 +32,32 @@ public:
explicit RenderSVGForeignObject(SVGForeignObjectElement*);
virtual ~RenderSVGForeignObject();
- virtual const char* renderName() const { return "RenderSVGForeignObject"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGForeignObject"; }
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE;
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
- virtual bool requiresLayer() const { return false; }
- virtual void layout();
+ virtual void layout() OVERRIDE;
- virtual FloatRect objectBoundingBox() const { return FloatRect(FloatPoint(), m_viewport.size()); }
- virtual FloatRect strokeBoundingBox() const { return FloatRect(FloatPoint(), m_viewport.size()); }
- virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(FloatPoint(), m_viewport.size()); }
+ virtual FloatRect objectBoundingBox() const OVERRIDE { return FloatRect(FloatPoint(), m_viewport.size()); }
+ virtual FloatRect strokeBoundingBox() const OVERRIDE { return FloatRect(FloatPoint(), m_viewport.size()); }
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const OVERRIDE { return FloatRect(FloatPoint(), m_viewport.size()); }
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
- virtual bool isSVGForeignObject() const { return true; }
+ virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) OVERRIDE;
+ virtual bool isSVGForeignObject() const OVERRIDE { return true; }
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
- virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
- virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ virtual void setNeedsTransformUpdate() OVERRIDE { m_needsTransformUpdate = true; }
private:
virtual void updateLogicalWidth() OVERRIDE;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
- virtual const AffineTransform& localToParentTransform() const;
- virtual AffineTransform localTransform() const { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const OVERRIDE;
bool m_needsTransformUpdate : 1;
FloatRect m_viewport;
- AffineTransform m_localTransform;
mutable AffineTransform m_localToParentTransform;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.cpp
index ca5f315a7bc..d9ce3bf7015 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.cpp
@@ -21,15 +21,12 @@
#include "core/rendering/svg/RenderSVGGradientStop.h"
-#include "SVGNames.h"
#include "core/rendering/svg/RenderSVGResourceContainer.h"
#include "core/svg/SVGGradientElement.h"
#include "core/svg/SVGStopElement.h"
namespace WebCore {
-using namespace SVGNames;
-
RenderSVGGradientStop::RenderSVGGradientStop(SVGStopElement* element)
: RenderObject(element)
{
@@ -42,7 +39,7 @@ RenderSVGGradientStop::~RenderSVGGradientStop()
void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderObject::styleDidChange(diff, oldStyle);
- if (diff == StyleDifferenceEqual)
+ if (diff.hasNoChange())
return;
// <stop> elements should only be allowed to make renderers under gradient elements
@@ -67,9 +64,8 @@ void RenderSVGGradientStop::layout()
SVGGradientElement* RenderSVGGradientStop::gradientElement() const
{
ContainerNode* parentNode = node()->parentNode();
- if (parentNode->hasTagName(linearGradientTag) || parentNode->hasTagName(radialGradientTag))
- return toSVGGradientElement(parentNode);
- return 0;
+ ASSERT(parentNode);
+ return isSVGGradientElement(*parentNode) ? toSVGGradientElement(parentNode) : 0;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.h
index e56274e3ffc..4d6fee11121 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGGradientStop.h
@@ -34,21 +34,22 @@ public:
explicit RenderSVGGradientStop(SVGStopElement*);
virtual ~RenderSVGGradientStop();
- virtual bool isSVGGradientStop() const { return true; }
- virtual const char* renderName() const { return "RenderSVGGradientStop"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGGradientStop"; }
+ virtual bool isSVGGradientStop() const OVERRIDE { return true; }
+ virtual bool isSVG() const OVERRIDE { return true; }
- virtual void layout();
+ virtual void layout() OVERRIDE;
// This overrides are needed to prevent ASSERTs on <svg><stop /></svg>
// RenderObject's default implementations ASSERT_NOT_REACHED()
// https://bugs.webkit.org/show_bug.cgi?id=20400
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject*) const OVERRIDE { return LayoutRect(); }
- virtual FloatRect objectBoundingBox() const { return FloatRect(); }
- virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
- virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject*) const OVERRIDE { return LayoutRect(); }
+ virtual FloatRect objectBoundingBox() const OVERRIDE { return FloatRect(); }
+ virtual FloatRect strokeBoundingBox() const OVERRIDE { return FloatRect(); }
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const OVERRIDE { return FloatRect(); }
protected:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
private:
SVGGradientElement* gradientElement() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp
index 0f1578935a5..0e5af52bb57 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.cpp
@@ -20,8 +20,7 @@
#include "config.h"
#include "core/rendering/svg/RenderSVGHiddenContainer.h"
-
-#include "core/rendering/LayoutRectRecorder.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
namespace WebCore {
@@ -33,7 +32,6 @@ RenderSVGHiddenContainer::RenderSVGHiddenContainer(SVGElement* element)
void RenderSVGHiddenContainer::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
SVGRenderSupport::layoutChildren(this, selfNeedsLayout());
updateCachedBoundaries();
clearNeedsLayout();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.h
index f8e57d33f1d..0616b76b719 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGHiddenContainer.h
@@ -32,17 +32,17 @@ class RenderSVGHiddenContainer : public RenderSVGContainer {
public:
explicit RenderSVGHiddenContainer(SVGElement*);
- virtual const char* renderName() const { return "RenderSVGHiddenContainer"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGHiddenContainer"; }
protected:
- virtual void layout();
+ virtual void layout() OVERRIDE;
private:
virtual bool isSVGHiddenContainer() const OVERRIDE FINAL { return true; }
virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE FINAL;
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject*) const OVERRIDE FINAL { return LayoutRect(); }
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject*) const OVERRIDE FINAL { return LayoutRect(); }
virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE FINAL;
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) OVERRIDE FINAL;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.cpp
index 9e2e4cd9414..b483670d4f2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.cpp
@@ -29,11 +29,11 @@
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/ImageQualityController.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/PointerEventsHitRules.h"
#include "core/rendering/RenderImageResource.h"
#include "core/rendering/svg/RenderSVGResource.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/rendering/svg/SVGRenderingContext.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCache.h"
@@ -64,12 +64,12 @@ bool RenderSVGImage::updateImageViewport()
bool updatedViewport = false;
SVGLengthContext lengthContext(image);
- m_objectBoundingBox = FloatRect(image->xCurrentValue().value(lengthContext), image->yCurrentValue().value(lengthContext), image->widthCurrentValue().value(lengthContext), image->heightCurrentValue().value(lengthContext));
+ m_objectBoundingBox = FloatRect(image->x()->currentValue()->value(lengthContext), image->y()->currentValue()->value(lengthContext), image->width()->currentValue()->value(lengthContext), image->height()->currentValue()->value(lengthContext));
// Images with preserveAspectRatio=none should force non-uniform scaling. This can be achieved
// by setting the image's container size to its intrinsic size.
// See: http://www.w3.org/TR/SVG/single-page.html, 7.8 The ‘preserveAspectRatio’ attribute.
- if (image->preserveAspectRatioCurrentValue().align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE) {
+ if (image->preserveAspectRatio()->currentValue()->align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE) {
if (ImageResource* cachedImage = m_imageResource->cachedImage()) {
LayoutSize intrinsicSize = cachedImage->imageSizeForRenderer(0, style()->effectiveZoom());
if (intrinsicSize != m_imageResource->imageSize(style()->effectiveZoom())) {
@@ -93,7 +93,6 @@ void RenderSVGImage::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) && selfNeedsLayout());
updateImageViewport();
@@ -126,33 +125,38 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
- if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || !m_imageResource->hasImage())
+ if (paintInfo.context->paintingDisabled()
+ || paintInfo.phase != PaintPhaseForeground
+ || style()->visibility() == HIDDEN
+ || !m_imageResource->hasImage())
return;
- FloatRect boundingBox = repaintRectInLocalCoordinates();
+ FloatRect boundingBox = paintInvalidationRectInLocalCoordinates();
if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
return;
PaintInfo childPaintInfo(paintInfo);
- bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
- if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
- GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
- childPaintInfo.applyTransform(m_localTransform);
+ GraphicsContextStateSaver stateSaver(*childPaintInfo.context, false);
- if (childPaintInfo.phase == PaintPhaseForeground && !m_objectBoundingBox.isEmpty()) {
- SVGRenderingContext renderingContext(this, childPaintInfo);
+ if (!m_localTransform.isIdentity()) {
+ stateSaver.save();
+ childPaintInfo.applyTransform(m_localTransform, false);
+ }
+ if (!m_objectBoundingBox.isEmpty()) {
+ // SVGRenderingContext may taint the state - make sure we're always saving.
+ SVGRenderingContext renderingContext(this, childPaintInfo, stateSaver.saved() ?
+ SVGRenderingContext::DontSaveGraphicsContext : SVGRenderingContext::SaveGraphicsContext);
- if (renderingContext.isRenderingPrepared()) {
- if (style()->svgStyle()->bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
- return;
+ if (renderingContext.isRenderingPrepared()) {
+ if (style()->svgStyle()->bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
+ return;
- paintForeground(childPaintInfo);
- }
+ paintForeground(childPaintInfo);
}
-
- if (drawsOutline)
- paintOutline(childPaintInfo, IntRect(boundingBox));
}
+
+ if (style()->outlineWidth())
+ paintOutline(childPaintInfo, IntRect(boundingBox));
}
void RenderSVGImage::paintForeground(PaintInfo& paintInfo)
@@ -162,13 +166,16 @@ void RenderSVGImage::paintForeground(PaintInfo& paintInfo)
FloatRect srcRect(0, 0, image->width(), image->height());
SVGImageElement* imageElement = toSVGImageElement(element());
- imageElement->preserveAspectRatioCurrentValue().transformRect(destRect, srcRect);
+ imageElement->preserveAspectRatio()->currentValue()->transformRect(destRect, srcRect);
- bool useLowQualityScaling = false;
+ InterpolationQuality interpolationQuality = InterpolationDefault;
if (style()->svgStyle()->bufferedRendering() != BR_STATIC)
- useLowQualityScaling = ImageQualityController::imageQualityController()->shouldPaintAtLowQuality(paintInfo.context, this, image.get(), image.get(), LayoutSize(destRect.size()));
+ interpolationQuality = ImageQualityController::imageQualityController()->chooseInterpolationQuality(paintInfo.context, this, image.get(), image.get(), LayoutSize(destRect.size()));
- paintInfo.context->drawImage(image.get(), destRect, srcRect, CompositeSourceOver, DoNotRespectImageOrientation, useLowQualityScaling);
+ InterpolationQuality previousInterpolationQuality = paintInfo.context->imageInterpolationQuality();
+ paintInfo.context->setImageInterpolationQuality(interpolationQuality);
+ paintInfo.context->drawImage(image.get(), destRect, srcRect, CompositeSourceOver);
+ paintInfo.context->setImageInterpolationQuality(previousInterpolationQuality);
}
void RenderSVGImage::invalidateBufferedForeground()
@@ -218,13 +225,13 @@ void RenderSVGImage::imageChanged(WrappedImagePtr, const IntRect*)
invalidateBufferedForeground();
- repaint();
+ paintInvalidationForWholeRenderer();
}
void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
{
// this is called from paint() after the localTransform has already been applied
- IntRect contentRect = enclosingIntRect(repaintRectInLocalCoordinates());
+ IntRect contentRect = enclosingIntRect(paintInvalidationRectInLocalCoordinates());
if (!contentRect.isEmpty())
rects.append(contentRect);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.h
index e87392e04fa..644bdd15027 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGImage.h
@@ -37,9 +37,8 @@ public:
virtual ~RenderSVGImage();
bool updateImageViewport();
- virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
- virtual bool needsBoundariesUpdate() OVERRIDE { return m_needsBoundariesUpdate; }
- virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ virtual void setNeedsBoundariesUpdate() OVERRIDE { m_needsBoundariesUpdate = true; }
+ virtual void setNeedsTransformUpdate() OVERRIDE { m_needsTransformUpdate = true; }
RenderImageResource* imageResource() { return m_imageResource.get(); }
@@ -47,27 +46,27 @@ public:
void paintForeground(PaintInfo&);
private:
- virtual const char* renderName() const { return "RenderSVGImage"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGImage"; }
virtual bool isSVGImage() const OVERRIDE { return true; }
- virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const OVERRIDE { return m_localTransform; }
- virtual FloatRect objectBoundingBox() const { return m_objectBoundingBox; }
- virtual FloatRect strokeBoundingBox() const { return m_objectBoundingBox; }
- virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
+ virtual FloatRect objectBoundingBox() const OVERRIDE { return m_objectBoundingBox; }
+ virtual FloatRect strokeBoundingBox() const OVERRIDE { return m_objectBoundingBox; }
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const OVERRIDE { return m_repaintBoundingBox; }
virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
- virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0) OVERRIDE;
- virtual void layout();
- virtual void paint(PaintInfo&, const LayoutPoint&);
+ virtual void layout() OVERRIDE;
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
void invalidateBufferedForeground();
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) OVERRIDE;
- virtual AffineTransform localTransform() const { return m_localTransform; }
+ virtual AffineTransform localTransform() const OVERRIDE { return m_localTransform; }
bool m_needsBoundariesUpdate : 1;
bool m_needsTransformUpdate : 1;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.cpp
index 68b1a4029cd..07c0a58c4d9 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.cpp
@@ -27,12 +27,22 @@
#include "core/rendering/svg/SVGInlineFlowBox.h"
#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/rendering/svg/SVGResourcesCache.h"
+#include "core/svg/SVGAElement.h"
namespace WebCore {
bool RenderSVGInline::isChildAllowed(RenderObject* child, RenderStyle* style) const
{
- if (SVGRenderSupport::isEmptySVGInlineText(child))
+ if (child->isText())
+ return SVGRenderSupport::isRenderableTextNode(child);
+
+ if (isSVGAElement(*node())) {
+ // Disallow direct descendant 'a'.
+ if (isSVGAElement(*child->node()))
+ return false;
+ }
+
+ if (!child->isSVGInline() && !child->isSVGInlineText())
return false;
return RenderInline::isChildAllowed(child, style);
@@ -46,7 +56,7 @@ RenderSVGInline::RenderSVGInline(Element* element)
InlineFlowBox* RenderSVGInline::createInlineFlowBox()
{
- InlineFlowBox* box = new SVGInlineFlowBox(this);
+ InlineFlowBox* box = new SVGInlineFlowBox(*this);
box->setHasVirtualLogicalHeight();
return box;
}
@@ -67,22 +77,22 @@ FloatRect RenderSVGInline::strokeBoundingBox() const
return FloatRect();
}
-FloatRect RenderSVGInline::repaintRectInLocalCoordinates() const
+FloatRect RenderSVGInline::paintInvalidationRectInLocalCoordinates() const
{
if (const RenderObject* object = RenderSVGText::locateRenderSVGTextAncestor(this))
- return object->repaintRectInLocalCoordinates();
+ return object->paintInvalidationRectInLocalCoordinates();
return FloatRect();
}
-LayoutRect RenderSVGInline::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+LayoutRect RenderSVGInline::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
- return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
+ return SVGRenderSupport::clippedOverflowRectForRepaint(this, paintInvalidationContainer);
}
-void RenderSVGInline::computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const
+void RenderSVGInline::computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect& paintInvalidationRect, bool fixed) const
{
- SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed);
+ SVGRenderSupport::computeFloatRectForRepaint(this, paintInvalidationContainer, paintInvalidationRect, fixed);
}
void RenderSVGInline::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
@@ -114,7 +124,7 @@ void RenderSVGInline::willBeDestroyed()
void RenderSVGInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- if (diff == StyleDifferenceLayout)
+ if (diff.needsFullLayout())
setNeedsBoundariesUpdate();
RenderInline::styleDidChange(diff, oldStyle);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.h
index 43634a39c22..1c09c5666f6 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInline.h
@@ -29,9 +29,10 @@ class RenderSVGInline : public RenderInline {
public:
explicit RenderSVGInline(Element*);
- virtual const char* renderName() const { return "RenderSVGInline"; }
- virtual bool requiresLayer() const OVERRIDE FINAL { return false; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGInline"; }
+ virtual LayerType layerTypeRequired() const OVERRIDE FINAL { return NoLayer; }
virtual bool isSVGInline() const OVERRIDE FINAL { return true; }
+ virtual bool isSVG() const OVERRIDE FINAL { return true; }
virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
@@ -42,10 +43,10 @@ public:
// this element, since we need it for filters.
virtual FloatRect objectBoundingBox() const OVERRIDE FINAL;
virtual FloatRect strokeBoundingBox() const OVERRIDE FINAL;
- virtual FloatRect repaintRectInLocalCoordinates() const OVERRIDE FINAL;
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const OVERRIDE FINAL;
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE FINAL;
- virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE FINAL;
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE FINAL;
+ virtual void computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect&, bool fixed = false) const OVERRIDE FINAL;
virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE FINAL;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE FINAL;
virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE FINAL;
@@ -60,6 +61,8 @@ private:
virtual void removeChild(RenderObject*) OVERRIDE FINAL;
};
+DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderSVGInline, isSVGInline());
+
}
#endif // !RenderSVGTSpan_H
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.cpp
index e8041f8c1c2..d19fed0516d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.cpp
@@ -89,17 +89,17 @@ void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle
return;
}
- if (diff != StyleDifferenceLayout)
+ if (!diff.needsFullLayout())
return;
// The text metrics may be influenced by style changes.
if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
- textRenderer->subtreeStyleDidChange(this);
+ textRenderer->setNeedsLayoutAndFullPaintInvalidation();
}
InlineTextBox* RenderSVGInlineText::createTextBox()
{
- InlineTextBox* box = new SVGInlineTextBox(this);
+ InlineTextBox* box = new SVGInlineTextBox(*this);
box->setHasVirtualLogicalHeight();
return box;
}
@@ -186,8 +186,7 @@ PositionWithAffinity RenderSVGInlineText::positionForPoint(const LayoutPoint& po
const SVGTextFragment& fragment = fragments.at(i);
FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
fragment.buildFragmentTransform(fragmentTransform);
- if (!fragmentTransform.isIdentity())
- fragmentRect = fragmentTransform.mapRect(fragmentRect);
+ fragmentRect = fragmentTransform.mapRect(fragmentRect);
float distance = powf(fragmentRect.x() - absolutePoint.x(), 2) +
powf(fragmentRect.y() + fragmentRect.height() / 2 - absolutePoint.y(), 2);
@@ -226,7 +225,7 @@ void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, c
return;
}
- if (style->fontDescription().textRenderingMode() == GeometricPrecision)
+ if (style->fontDescription().textRendering() == GeometricPrecision)
scalingFactor = 1;
FontDescription fontDescription(style->fontDescription());
@@ -235,7 +234,7 @@ void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, c
// FIXME: We need to better handle the case when we compute very small fonts below (below 1pt).
fontDescription.setComputedSize(FontSize::getComputedSizeFromSpecifiedSize(&document, scalingFactor, fontDescription.isAbsoluteSize(), fontDescription.specifiedSize(), DoNotUseSmartMinimumForFontSize));
- scaledFont = Font(fontDescription, 0, 0);
+ scaledFont = Font(fontDescription);
scaledFont.update(document.styleEngine()->fontSelector());
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.h
index 8c7f711a68f..b7fc9add99b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGInlineText.h
@@ -27,8 +27,6 @@
namespace WebCore {
-class SVGInlineTextBox;
-
class RenderSVGInlineText FINAL : public RenderText {
public:
RenderSVGInlineText(Node*, PassRefPtr<StringImpl>);
@@ -45,19 +43,20 @@ public:
FloatRect floatLinesBoundingBox() const;
private:
- virtual const char* renderName() const { return "RenderSVGInlineText"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGInlineText"; }
- virtual void setTextInternal(PassRefPtr<StringImpl>);
- virtual void styleDidChange(StyleDifference, const RenderStyle*);
+ virtual void setTextInternal(PassRefPtr<StringImpl>) OVERRIDE;
+ virtual void styleDidChange(StyleDifference, const RenderStyle*) OVERRIDE;
- virtual FloatRect objectBoundingBox() const { return floatLinesBoundingBox(); }
+ virtual FloatRect objectBoundingBox() const OVERRIDE { return floatLinesBoundingBox(); }
- virtual bool isSVGInlineText() const { return true; }
+ virtual bool isSVGInlineText() const OVERRIDE { return true; }
+ virtual bool isSVG() const OVERRIDE { return true; }
- virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
- virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0);
- virtual IntRect linesBoundingBox() const;
- virtual InlineTextBox* createTextBox();
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
+ virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) OVERRIDE;
+ virtual IntRect linesBoundingBox() const OVERRIDE;
+ virtual InlineTextBox* createTextBox() OVERRIDE;
float m_scalingFactor;
Font m_scaledFont;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.cpp
index 12da706b521..a6918a93535 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.cpp
@@ -29,11 +29,12 @@
*/
#include "config.h"
-
#include "core/rendering/svg/RenderSVGModelObject.h"
-#include "SVGNames.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderView.h"
#include "core/rendering/svg/RenderSVGRoot.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/rendering/svg/SVGResourcesCache.h"
#include "core/svg/SVGGraphicsElement.h"
@@ -44,14 +45,19 @@ RenderSVGModelObject::RenderSVGModelObject(SVGElement* node)
{
}
-LayoutRect RenderSVGModelObject::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+bool RenderSVGModelObject::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isSVG() && !(child->isSVGInline() || child->isSVGInlineText());
+}
+
+LayoutRect RenderSVGModelObject::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
- return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
+ return SVGRenderSupport::clippedOverflowRectForRepaint(this, paintInvalidationContainer);
}
-void RenderSVGModelObject::computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const
+void RenderSVGModelObject::computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect& paintInvalidationRect, bool fixed) const
{
- SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed);
+ SVGRenderSupport::computeFloatRectForRepaint(this, paintInvalidationContainer, paintInvalidationRect, fixed);
}
void RenderSVGModelObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
@@ -64,18 +70,6 @@ const RenderObject* RenderSVGModelObject::pushMappingToContainer(const RenderLay
return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap);
}
-// Copied from RenderBox, this method likely requires further refactoring to work easily for both SVG and CSS Box Model content.
-// FIXME: This may also need to move into SVGRenderSupport as the RenderBox version depends
-// on borderBoundingBox() which SVG RenderBox subclases (like SVGRenderBlock) do not implement.
-LayoutRect RenderSVGModelObject::outlineBoundsForRepaint(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap*) const
-{
- LayoutRect box = enclosingLayoutRect(repaintRectInLocalCoordinates());
- adjustRectForOutlineAndShadow(box);
-
- FloatQuad containerRelativeQuad = localToContainerQuad(FloatRect(box), repaintContainer);
- return containerRelativeQuad.enclosingBoundingBox();
-}
-
void RenderSVGModelObject::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
{
IntRect rect = enclosingIntRect(strokeBoundingBox());
@@ -107,7 +101,7 @@ void RenderSVGModelObject::addLayerHitTestRects(LayerHitTestRects&, const Render
void RenderSVGModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- if (diff == StyleDifferenceLayout) {
+ if (diff.needsFullLayout()) {
setNeedsBoundariesUpdate();
if (style()->hasTransform())
setNeedsTransformUpdate();
@@ -123,82 +117,53 @@ bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, co
return false;
}
-static void getElementCTM(SVGGraphicsElement* element, AffineTransform& transform)
+// The SVG addFocusRingRects() method adds rects in local coordinates so the default absoluteFocusRingQuads
+// returns incorrect values for SVG objects. Overriding this method provides access to the absolute bounds.
+void RenderSVGModelObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
{
- ASSERT(element);
- element->document().updateLayoutIgnorePendingStylesheets();
-
- SVGElement* stopAtElement = element->nearestViewportElement();
- ASSERT(stopAtElement);
+ quads.append(localToAbsoluteQuad(FloatQuad(paintInvalidationRectInLocalCoordinates())));
+}
- AffineTransform localTransform;
- Node* current = element;
+void RenderSVGModelObject::invalidateTreeAfterLayout(const RenderLayerModelObject& paintInvalidationContainer)
+{
+ // Note: This is a reduced version of RenderBox::invalidateTreeAfterLayout().
+ // FIXME: Should share code with RenderBox::invalidateTreeAfterLayout().
+ ASSERT(RuntimeEnabledFeatures::repaintAfterLayoutEnabled());
+ ASSERT(!needsLayout());
- while (current && current->isSVGElement()) {
- SVGElement* currentElement = toSVGElement(current);
- localTransform = currentElement->renderer()->localToParentTransform();
- transform = localTransform.multiply(transform);
- // For getCTM() computation, stop at the nearest viewport element
- if (currentElement == stopAtElement)
- break;
+ if (!shouldCheckForPaintInvalidationAfterLayout())
+ return;
- current = current->parentOrShadowHostNode();
- }
-}
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
-// FloatRect::intersects does not consider horizontal or vertical lines (because of isEmpty()).
-// So special-case handling of such lines.
-static bool intersectsAllowingEmpty(const FloatRect& r, const FloatRect& other)
-{
- if (r.isEmpty() && other.isEmpty())
- return false;
- if (r.isEmpty() && !other.isEmpty()) {
- return (other.contains(r.x(), r.y()) && !other.contains(r.maxX(), r.maxY()))
- || (!other.contains(r.x(), r.y()) && other.contains(r.maxX(), r.maxY()));
- }
- if (other.isEmpty() && !r.isEmpty())
- return intersectsAllowingEmpty(other, r);
- return r.intersects(other);
-}
+ const LayoutRect oldPaintInvalidationRect = previousPaintInvalidationRect();
+ const LayoutPoint oldPositionFromPaintInvalidationContainer = previousPositionFromPaintInvalidationContainer();
+ const RenderLayerModelObject& newPaintInvalidationContainer = *containerForPaintInvalidation();
+ setPreviousPaintInvalidationRect(clippedOverflowRectForPaintInvalidation(&newPaintInvalidationContainer));
+ setPreviousPositionFromPaintInvalidationContainer(RenderLayer::positionFromPaintInvalidationContainer(this, &newPaintInvalidationContainer));
-// One of the element types that can cause graphics to be drawn onto the target canvas. Specifically: circle, ellipse,
-// image, line, path, polygon, polyline, rect, text and use.
-static bool isGraphicsElement(RenderObject* renderer)
-{
- return renderer->isSVGShape() || renderer->isSVGText() || renderer->isSVGImage() || renderer->node()->hasTagName(SVGNames::useTag);
-}
+ // If an ancestor container had its transform changed, then we just
+ // need to update the RenderSVGModelObject's repaint rect above. The invalidation
+ // will be handled by the container where the transform changed. This essentially
+ // means that we prune the entire branch for performance.
+ if (!SVGRenderSupport::parentTransformDidChange(this))
+ return;
-// The SVG addFocusRingRects() method adds rects in local coordinates so the default absoluteFocusRingQuads
-// returns incorrect values for SVG objects. Overriding this method provides access to the absolute bounds.
-void RenderSVGModelObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
-{
- quads.append(localToAbsoluteQuad(FloatQuad(repaintRectInLocalCoordinates())));
-}
+ // If we are set to do a full paint invalidation that means the RenderView will be
+ // issue paint invalidations. We can then skip issuing of paint invalidations for the child
+ // renderers as they'll be covered by the RenderView.
+ if (view()->doingFullRepaint()) {
+ RenderObject::invalidateTreeAfterLayout(newPaintInvalidationContainer);
+ return;
+ }
-bool RenderSVGModelObject::checkIntersection(RenderObject* renderer, const SVGRect& rect)
-{
- if (!renderer || renderer->style()->pointerEvents() == PE_NONE)
- return false;
- if (!isGraphicsElement(renderer))
- return false;
- AffineTransform ctm;
- SVGGraphicsElement* svgElement = toSVGGraphicsElement(renderer->node());
- getElementCTM(svgElement, ctm);
- ASSERT(svgElement->renderer());
- return intersectsAllowingEmpty(rect, ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
-}
+ const LayoutRect& newPaintInvalidationRect = previousPaintInvalidationRect();
+ const LayoutPoint& newPositionFromPaintInvalidationContainer = previousPositionFromPaintInvalidationContainer();
+ invalidatePaintAfterLayoutIfNeeded(containerForPaintInvalidation(),
+ shouldDoFullPaintInvalidationAfterLayout(), oldPaintInvalidationRect, oldPositionFromPaintInvalidationContainer,
+ &newPaintInvalidationRect, &newPositionFromPaintInvalidationContainer);
-bool RenderSVGModelObject::checkEnclosure(RenderObject* renderer, const SVGRect& rect)
-{
- if (!renderer || renderer->style()->pointerEvents() == PE_NONE)
- return false;
- if (!isGraphicsElement(renderer))
- return false;
- AffineTransform ctm;
- SVGGraphicsElement* svgElement = toSVGGraphicsElement(renderer->node());
- getElementCTM(svgElement, ctm);
- ASSERT(svgElement->renderer());
- return rect.contains(ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
+ RenderObject::invalidateTreeAfterLayout(newPaintInvalidationContainer);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.h
index c8df10aca7d..41bc62ae412 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGModelObject.h
@@ -32,9 +32,8 @@
#define RenderSVGModelObject_h
#include "core/rendering/RenderObject.h"
-#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGRect.h"
+#include "platform/geometry/FloatRect.h"
namespace WebCore {
@@ -49,34 +48,37 @@ class RenderSVGModelObject : public RenderObject {
public:
explicit RenderSVGModelObject(SVGElement*);
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE FINAL;
- virtual LayoutRect outlineBoundsForRepaint(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap*) const OVERRIDE FINAL;
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
+ virtual bool canHaveWhitespaceChildren() const OVERRIDE { return false; }
+
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE;
+ virtual void computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect&, bool fixed = false) const OVERRIDE FINAL;
virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE FINAL;
- virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
+ virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE;
virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE FINAL;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE FINAL;
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
-
- static bool checkIntersection(RenderObject*, const SVGRect&);
- static bool checkEnclosure(RenderObject*, const SVGRect&);
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
- virtual void computeLayerHitTestRects(LayerHitTestRects&) const OVERRIDE;
+ virtual void computeLayerHitTestRects(LayerHitTestRects&) const OVERRIDE FINAL;
SVGElement* element() const { return toSVGElement(RenderObject::node()); }
+ virtual bool isSVG() const OVERRIDE FINAL { return true; }
+
+ virtual void invalidateTreeAfterLayout(const RenderLayerModelObject&) OVERRIDE;
+
protected:
- virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const OVERRIDE;
- virtual void willBeDestroyed();
+ virtual void addLayerHitTestRects(LayerHitTestRects&, const RenderLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const OVERRIDE FINAL;
+ virtual void willBeDestroyed() OVERRIDE;
private:
// RenderSVGModelObject subclasses should use element() instead.
void node() const WTF_DELETED_FUNCTION;
// This method should never be called, SVG uses a different nodeAtPoint method
- bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE FINAL;
virtual void absoluteFocusRingQuads(Vector<FloatQuad>&) OVERRIDE FINAL;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGPath.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGPath.h
index 8cec15c4c92..48b36762e04 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGPath.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGPath.h
@@ -37,7 +37,7 @@ public:
private:
virtual bool isSVGPath() const OVERRIDE { return true; }
- virtual const char* renderName() const { return "RenderSVGPath"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGPath"; }
virtual void updateShapeFromElement() OVERRIDE;
FloatRect calculateUpdatedStrokeBoundingBox() const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.cpp
index dfe447156f6..5fd79e7f626 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.cpp
@@ -28,8 +28,7 @@
#include "config.h"
#include "core/rendering/svg/RenderSVGRect.h"
-
-#include "SVGNames.h"
+#include "platform/graphics/GraphicsContext.h"
namespace WebCore {
@@ -54,19 +53,24 @@ void RenderSVGRect::updateShapeFromElement()
ASSERT(rect);
SVGLengthContext lengthContext(rect);
- // Fallback to RenderSVGShape if rect has rounded corners or a non-scaling stroke.
- if (rect->rxCurrentValue().value(lengthContext) > 0 || rect->ryCurrentValue().value(lengthContext) > 0 || hasNonScalingStroke()) {
- RenderSVGShape::updateShapeFromElement();
- m_usePathFallback = true;
- return;
- }
+ FloatSize boundingBoxSize(rect->width()->currentValue()->value(lengthContext), rect->height()->currentValue()->value(lengthContext));
- m_usePathFallback = false;
- FloatSize boundingBoxSize(rect->widthCurrentValue().value(lengthContext), rect->heightCurrentValue().value(lengthContext));
- if (boundingBoxSize.isEmpty())
+ // Spec: "A negative value is an error."
+ if (boundingBoxSize.width() < 0 || boundingBoxSize.height() < 0)
return;
- m_fillBoundingBox = FloatRect(FloatPoint(rect->xCurrentValue().value(lengthContext), rect->yCurrentValue().value(lengthContext)), boundingBoxSize);
+ // Spec: "A value of zero disables rendering of the element."
+ if (!boundingBoxSize.isEmpty()) {
+ // Fallback to RenderSVGShape if rect has rounded corners or a non-scaling stroke.
+ if (rect->rx()->currentValue()->value(lengthContext) > 0 || rect->ry()->currentValue()->value(lengthContext) > 0 || hasNonScalingStroke()) {
+ RenderSVGShape::updateShapeFromElement();
+ m_usePathFallback = true;
+ return;
+ }
+ m_usePathFallback = false;
+ }
+
+ m_fillBoundingBox = FloatRect(FloatPoint(rect->x()->currentValue()->value(lengthContext), rect->y()->currentValue()->value(lengthContext)), boundingBoxSize);
// To decide if the stroke contains a point we create two rects which represent the inner and
// the outer stroke borders. A stroke contains the point, if the point is between them.
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.h
index 1a5d6e091e4..7ae39625755 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRect.h
@@ -39,14 +39,14 @@ public:
virtual ~RenderSVGRect();
private:
- virtual const char* renderName() const { return "RenderSVGRect"; }
-
- virtual void updateShapeFromElement();
- virtual bool isEmpty() const { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); };
- virtual void fillShape(GraphicsContext*) const;
- virtual void strokeShape(GraphicsContext*) const;
- virtual bool shapeDependentStrokeContains(const FloatPoint&);
- virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGRect"; }
+
+ virtual void updateShapeFromElement() OVERRIDE;
+ virtual bool isShapeEmpty() const OVERRIDE { return m_usePathFallback ? RenderSVGShape::isShapeEmpty() : m_fillBoundingBox.isEmpty(); }
+ virtual void fillShape(GraphicsContext*) const OVERRIDE;
+ virtual void strokeShape(GraphicsContext*) const OVERRIDE;
+ virtual bool shapeDependentStrokeContains(const FloatPoint&) OVERRIDE;
+ virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const OVERRIDE;
private:
FloatRect m_innerStrokeRect;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.cpp
index 4dd3ae01c90..0c67bc8d070 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.cpp
@@ -24,8 +24,8 @@
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/svg/RenderSVGResourceClipper.h"
#include "core/rendering/svg/RenderSVGResourceFilter.h"
#include "core/rendering/svg/RenderSVGResourceMasker.h"
@@ -35,22 +35,25 @@
namespace WebCore {
-static inline bool inheritColorFromParentStyleIfNeeded(RenderObject* object, bool applyToFill, Color& color)
+static inline bool inheritColorFromParentStyle(RenderObject* object, bool applyToFill, Color& color)
{
- if (color.isValid())
- return true;
if (!object->parent() || !object->parent()->style())
return false;
const SVGRenderStyle* parentSVGStyle = object->parent()->style()->svgStyle();
+ SVGPaint::SVGPaintType paintType = applyToFill ? parentSVGStyle->fillPaintType() : parentSVGStyle->strokePaintType();
+ if (paintType != SVGPaint::SVG_PAINTTYPE_RGBCOLOR && paintType != SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR)
+ return false;
color = applyToFill ? parentSVGStyle->fillPaintColor() : parentSVGStyle->strokePaintColor();
return true;
}
-static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode mode, RenderObject* object, const RenderStyle* style, Color& fallbackColor)
+static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode mode, RenderObject* object, const RenderStyle* style, bool& hasFallback)
{
ASSERT(object);
ASSERT(style);
+ hasFallback = false;
+
// If we have no style at all, ignore it.
const SVGRenderStyle* svgStyle = style->svgStyle();
if (!svgStyle)
@@ -78,10 +81,10 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m
bool applyToFill = mode == ApplyToFillMode;
SVGPaint::SVGPaintType paintType = applyToFill ? svgStyle->fillPaintType() : svgStyle->strokePaintType();
- if (paintType == SVGPaint::SVG_PAINTTYPE_NONE)
- return 0;
+ ASSERT(paintType != SVGPaint::SVG_PAINTTYPE_NONE);
Color color;
+ bool hasColor = false;
switch (paintType) {
case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR:
case SVGPaint::SVG_PAINTTYPE_RGBCOLOR:
@@ -90,6 +93,7 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m
case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR:
case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
color = applyToFill ? svgStyle->fillPaintColor() : svgStyle->strokePaintColor();
+ hasColor = true;
default:
break;
}
@@ -101,15 +105,15 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m
// For SVG_PAINTTYPE_CURRENTCOLOR, 'color' already contains the 'visitedColor'.
if (visitedPaintType < SVGPaint::SVG_PAINTTYPE_URI_NONE && visitedPaintType != SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR) {
const Color& visitedColor = applyToFill ? svgStyle->visitedLinkFillPaintColor() : svgStyle->visitedLinkStrokePaintColor();
- if (visitedColor.isValid())
- color = Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), color.alpha());
+ color = Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), color.alpha());
+ hasColor = true;
}
}
// If the primary resource is just a color, return immediately.
RenderSVGResourceSolidColor* colorResource = RenderSVGResource::sharedSolidPaintingResource();
if (paintType < SVGPaint::SVG_PAINTTYPE_URI_NONE) {
- if (!inheritColorFromParentStyleIfNeeded(object, applyToFill, color))
+ if (!hasColor && !inheritColorFromParentStyle(object, applyToFill, color))
return 0;
colorResource->setColor(color);
@@ -119,7 +123,7 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m
// If no resources are associated with the given renderer, return the color resource.
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
if (!resources) {
- if (paintType == SVGPaint::SVG_PAINTTYPE_URI_NONE || !inheritColorFromParentStyleIfNeeded(object, applyToFill, color))
+ if (paintType == SVGPaint::SVG_PAINTTYPE_URI_NONE || (!hasColor && !inheritColorFromParentStyle(object, applyToFill, color)))
return 0;
colorResource->setColor(color);
@@ -129,7 +133,7 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m
// If the requested resource is not available, return the color resource.
RenderSVGResource* uriResource = mode == ApplyToFillMode ? resources->fill() : resources->stroke();
if (!uriResource) {
- if (!inheritColorFromParentStyleIfNeeded(object, applyToFill, color))
+ if (!hasColor && !inheritColorFromParentStyle(object, applyToFill, color))
return 0;
colorResource->setColor(color);
@@ -137,19 +141,22 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m
}
// The paint server resource exists, though it may be invalid (pattern with width/height=0). Pass the fallback color to our caller
- // so it can use the solid color painting resource, if applyResource() on the URI resource failed.
- fallbackColor = color;
+ // via sharedSolidPaintingResource so it can use the solid color painting resource, if applyResource() on the URI resource failed.
+ if (hasColor) {
+ colorResource->setColor(color);
+ hasFallback = true;
+ }
return uriResource;
}
-RenderSVGResource* RenderSVGResource::fillPaintingResource(RenderObject* object, const RenderStyle* style, Color& fallbackColor)
+RenderSVGResource* RenderSVGResource::fillPaintingResource(RenderObject* object, const RenderStyle* style, bool& hasFallback)
{
- return requestPaintingResource(ApplyToFillMode, object, style, fallbackColor);
+ return requestPaintingResource(ApplyToFillMode, object, style, hasFallback);
}
-RenderSVGResource* RenderSVGResource::strokePaintingResource(RenderObject* object, const RenderStyle* style, Color& fallbackColor)
+RenderSVGResource* RenderSVGResource::strokePaintingResource(RenderObject* object, const RenderStyle* style, bool& hasFallback)
{
- return requestPaintingResource(ApplyToStrokeMode, object, style, fallbackColor);
+ return requestPaintingResource(ApplyToStrokeMode, object, style, hasFallback);
}
RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
@@ -176,13 +183,28 @@ static inline void removeFromCacheAndInvalidateDependencies(RenderObject* object
if (!object->node() || !object->node()->isSVGElement())
return;
- HashSet<SVGElement*>* dependencies = object->document().accessSVGExtensions()->setOfElementsReferencingTarget(toSVGElement(object->node()));
+ SVGElementSet* dependencies = object->document().accessSVGExtensions().setOfElementsReferencingTarget(toSVGElement(object->node()));
if (!dependencies)
return;
- HashSet<SVGElement*>::iterator end = dependencies->end();
- for (HashSet<SVGElement*>::iterator it = dependencies->begin(); it != end; ++it) {
- if (RenderObject* renderer = (*it)->renderer())
+
+ // We allow cycles in SVGDocumentExtensions reference sets in order to avoid expensive
+ // reference graph adjustments on changes, so we need to break possible cycles here.
+ // This strong reference is safe, as it is guaranteed that this set will be emptied
+ // at the end of recursion.
+ typedef WillBeHeapHashSet<RawPtrWillBeMember<SVGElement> > SVGElementSet;
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<SVGElementSet>, invalidatingDependencies, (adoptPtrWillBeNoop(new SVGElementSet)));
+
+ SVGElementSet::iterator end = dependencies->end();
+ for (SVGElementSet::iterator it = dependencies->begin(); it != end; ++it) {
+ if (RenderObject* renderer = (*it)->renderer()) {
+ if (UNLIKELY(!invalidatingDependencies->add(*it).isNewEntry)) {
+ // Reference cycle: we are in process of invalidating this dependant.
+ continue;
+ }
+
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, needsLayout);
+ invalidatingDependencies->remove(*it);
+ }
}
}
@@ -192,7 +214,7 @@ void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject*
ASSERT(object->node());
if (needsLayout && !object->documentBeingDestroyed())
- object->setNeedsLayout();
+ object->setNeedsLayoutAndFullPaintInvalidation();
removeFromCacheAndInvalidateDependencies(object, needsLayout);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.h
index 676562dd01c..d1d3a89926b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResource.h
@@ -43,9 +43,8 @@ enum RenderSVGResourceMode {
ApplyToStrokeMode = 1 << 2,
ApplyToTextMode = 1 << 3 // used in combination with ApplyTo{Fill|Stroke}Mode
};
+typedef unsigned RenderSVGResourceModeFlags;
-class Color;
-class FloatRect;
class GraphicsContext;
class Path;
class RenderObject;
@@ -75,8 +74,9 @@ public:
}
// Helper utilities used in the render tree to access resources used for painting shapes/text (gradients & patterns & solid colors only)
- static RenderSVGResource* fillPaintingResource(RenderObject*, const RenderStyle*, Color& fallbackColor);
- static RenderSVGResource* strokePaintingResource(RenderObject*, const RenderStyle*, Color& fallbackColor);
+ // If hasFallback gets set to true, the sharedSolidPaintingResource is set to a fallback color.
+ static RenderSVGResource* fillPaintingResource(RenderObject*, const RenderStyle*, bool& hasFallback);
+ static RenderSVGResource* strokePaintingResource(RenderObject*, const RenderStyle*, bool& hasFallback);
static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
static void markForLayoutAndParentResourceInvalidation(RenderObject*, bool needsLayout = true);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
index b98db0f7c86..62db92f8c1a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
@@ -24,15 +24,16 @@
#include "core/rendering/svg/RenderSVGResourceClipper.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
-#include "core/frame/Frame.h"
+#include "core/SVGNames.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/HitTestResult.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/rendering/svg/SVGRenderingContext.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCache.h"
#include "core/svg/SVGUseElement.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/graphics/DisplayList.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "wtf/TemporaryChange.h"
@@ -78,7 +79,7 @@ bool RenderSVGResourceClipper::applyStatefulResource(RenderObject* object, Graph
clearInvalidationMask();
- return applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context, clipperContext);
+ return applyClippingToContext(object, object->objectBoundingBox(), object->paintInvalidationRectInLocalCoordinates(), context, clipperContext);
}
bool RenderSVGResourceClipper::tryPathOnlyClipping(GraphicsContext* context,
@@ -89,16 +90,16 @@ bool RenderSVGResourceClipper::tryPathOnlyClipping(GraphicsContext* context,
WindRule clipRule = RULE_NONZERO;
Path clipPath = Path();
- for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
- RenderObject* renderer = childNode->renderer();
+ for (Element* childElement = ElementTraversal::firstWithin(*element()); childElement; childElement = ElementTraversal::nextSibling(*childElement)) {
+ RenderObject* renderer = childElement->renderer();
if (!renderer)
continue;
// Only shapes or paths are supported for direct clipping. We need to fallback to masking for texts.
if (renderer->isSVGText())
return false;
- if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGGraphicsElement())
+ if (!childElement->isSVGElement() || !toSVGElement(childElement)->isSVGGraphicsElement())
continue;
- SVGGraphicsElement* styled = toSVGGraphicsElement(childNode);
+ SVGGraphicsElement* styled = toSVGGraphicsElement(childElement);
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
@@ -127,7 +128,7 @@ bool RenderSVGResourceClipper::tryPathOnlyClipping(GraphicsContext* context,
}
}
// Only one visible shape/path was found. Directly continue clipping and transform the content to userspace if necessary.
- if (toSVGClipPathElement(element())->clipPathUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ if (toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
AffineTransform transform;
transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
@@ -148,7 +149,6 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* target, cons
const FloatRect& repaintRect, GraphicsContext* context, ClipperContext& clipperContext)
{
ASSERT(target);
- ASSERT(target->node());
ASSERT(context);
ASSERT(clipperContext.state == ClipperContext::NotAppliedState);
ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
@@ -161,8 +161,8 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* target, cons
// When drawing a clip for non-SVG elements, the CTM does not include the zoom factor.
// In this case, we need to apply the zoom scale explicitly - but only for clips with
// userSpaceOnUse units (the zoom is accounted for objectBoundingBox-resolved lengths).
- if (!target->node()->isSVGElement()
- && toSVGClipPathElement(element())->clipPathUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
+ if (!target->isSVG()
+ && toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
ASSERT(style());
animatedLocalTransform.scale(style()->effectiveZoom());
}
@@ -238,7 +238,7 @@ void RenderSVGResourceClipper::drawClipMaskContent(GraphicsContext* context, con
ASSERT(context);
AffineTransform contentTransformation;
- SVGUnitTypes::SVGUnitType contentUnits = toSVGClipPathElement(element())->clipPathUnitsCurrentValue();
+ SVGUnitTypes::SVGUnitType contentUnits = toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue();
if (contentUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox.y());
contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height());
@@ -258,7 +258,10 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext*
ASSERT(context);
ASSERT(frame());
- context->beginRecording(repaintRectInLocalCoordinates());
+ // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection
+ // with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and
+ // userSpaceOnUse units (http://crbug.com/294900).
+ context->beginRecording(strokeBoundingBox());
// Switch to a paint behavior where all children of this <clipPath> will be rendered using special constraints:
// - fill-opacity/stroke-opacity/opacity set to 1
@@ -268,9 +271,9 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext*
PaintBehavior oldBehavior = frame()->view()->paintBehavior();
frame()->view()->setPaintBehavior(oldBehavior | PaintBehaviorRenderingSVGMask);
- for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
- RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !renderer)
+ for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
+ RenderObject* renderer = childElement->renderer();
+ if (!renderer)
continue;
RenderStyle* style = renderer->style();
@@ -278,13 +281,13 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext*
continue;
WindRule newClipRule = style->svgStyle()->clipRule();
- bool isUseElement = childNode->hasTagName(SVGNames::useTag);
+ bool isUseElement = isSVGUseElement(*childElement);
if (isUseElement) {
- SVGUseElement* useElement = toSVGUseElement(childNode);
- renderer = useElement->rendererClipChild();
+ SVGUseElement& useElement = toSVGUseElement(*childElement);
+ renderer = useElement.rendererClipChild();
if (!renderer)
continue;
- if (!useElement->hasAttribute(SVGNames::clip_ruleAttr))
+ if (!useElement.hasAttribute(SVGNames::clip_ruleAttr))
newClipRule = renderer->style()->svgStyle()->clipRule();
}
@@ -295,7 +298,7 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext*
context->setFillRule(newClipRule);
if (isUseElement)
- renderer = childNode->renderer();
+ renderer = childElement->renderer();
SVGRenderingContext::renderSubtree(context, renderer, contentTransformation);
}
@@ -308,16 +311,16 @@ PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext*
void RenderSVGResourceClipper::calculateClipContentRepaintRect()
{
// This is a rough heuristic to appraise the clip size and doesn't consider clip on clip.
- for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
- RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !renderer)
+ for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
+ RenderObject* renderer = childElement->renderer();
+ if (!renderer)
continue;
- if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
+ if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElement(*childElement))
continue;
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
- m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
+ m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->paintInvalidationRectInLocalCoordinates()));
}
m_clipBoundaries = toSVGClipPathElement(element())->animatedLocalTransform().mapRect(m_clipBoundaries);
}
@@ -329,7 +332,7 @@ bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundin
return false;
SVGClipPathElement* clipPathElement = toSVGClipPathElement(element());
- if (clipPathElement->clipPathUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ if (clipPathElement->clipPathUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
AffineTransform transform;
transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
@@ -338,11 +341,11 @@ bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundin
point = clipPathElement->animatedLocalTransform().inverse().mapPoint(point);
- for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
- RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !renderer)
+ for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
+ RenderObject* renderer = childElement->renderer();
+ if (!renderer)
continue;
- if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
+ if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElement(*childElement))
continue;
IntPoint hitPoint;
HitTestResult result(hitPoint);
@@ -353,7 +356,7 @@ bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundin
return false;
}
-FloatRect RenderSVGResourceClipper::resourceBoundingBox(RenderObject* object)
+FloatRect RenderSVGResourceClipper::resourceBoundingBox(const RenderObject* object)
{
// Resource was not layouted yet. Give back the boundingBox of the object.
if (selfNeedsLayout())
@@ -362,7 +365,7 @@ FloatRect RenderSVGResourceClipper::resourceBoundingBox(RenderObject* object)
if (m_clipBoundaries.isEmpty())
calculateClipContentRepaintRect();
- if (toSVGClipPathElement(element())->clipPathUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ if (toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
FloatRect objectBoundingBox = object->objectBoundingBox();
AffineTransform transform;
transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.h
index ae89b1e3df5..75a805859ff 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceClipper.h
@@ -45,13 +45,13 @@ public:
explicit RenderSVGResourceClipper(SVGClipPathElement*);
virtual ~RenderSVGResourceClipper();
- virtual const char* renderName() const { return "RenderSVGResourceClipper"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGResourceClipper"; }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true);
- virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true) OVERRIDE;
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) OVERRIDE;
- virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE FINAL;
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short, const Path*, const RenderSVGShape*) OVERRIDE FINAL;
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE;
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short, const Path*, const RenderSVGShape*) OVERRIDE;
// FIXME: Filters are also stateful resources that could benefit from having their state managed
// on the caller stack instead of the current hashmap. We should look at refactoring these
@@ -64,13 +64,13 @@ public:
// FIXME: We made applyClippingToContext public because we cannot call applyResource on HTML elements (it asserts on RenderObject::objectBoundingBox)
bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*, ClipperContext&);
- FloatRect resourceBoundingBox(RenderObject*);
+ FloatRect resourceBoundingBox(const RenderObject*);
- virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
bool hitTestClipContent(const FloatRect&, const FloatPoint&);
- SVGUnitTypes::SVGUnitType clipPathUnits() const { return toSVGClipPathElement(element())->clipPathUnitsCurrentValue(); }
+ SVGUnitTypes::SVGUnitType clipPathUnits() const { return toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue(); }
static const RenderSVGResourceType s_resourceType;
private:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
index 55405a77a08..8434f4fe4ee 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
@@ -21,7 +21,6 @@
#include "core/rendering/svg/RenderSVGResourceContainer.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/svg/SVGRenderingContext.h"
@@ -32,7 +31,7 @@
namespace WebCore {
-static inline SVGDocumentExtensions* svgExtensionsFromElement(SVGElement* element)
+static inline SVGDocumentExtensions& svgExtensionsFromElement(SVGElement* element)
{
ASSERT(element);
return element->document().accessSVGExtensions();
@@ -51,7 +50,7 @@ RenderSVGResourceContainer::RenderSVGResourceContainer(SVGElement* node)
RenderSVGResourceContainer::~RenderSVGResourceContainer()
{
if (m_registered)
- svgExtensionsFromElement(element())->removeResource(m_id);
+ svgExtensionsFromElement(element()).removeResource(m_id);
}
void RenderSVGResourceContainer::layout()
@@ -62,7 +61,6 @@ void RenderSVGResourceContainer::layout()
if (m_isInLayout)
return;
- LayoutRectRecorder recorder(*this);
TemporaryChange<bool> inLayoutChange(m_isInLayout, true);
RenderSVGHiddenContainer::layout();
@@ -92,8 +90,8 @@ void RenderSVGResourceContainer::idChanged()
removeAllClientsFromCache();
// Remove old id, that is guaranteed to be present in cache.
- SVGDocumentExtensions* extensions = svgExtensionsFromElement(element());
- extensions->removeResource(m_id);
+ SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
+ extensions.removeResource(m_id);
m_id = element()->getIdAttribute();
registerResource();
@@ -150,10 +148,10 @@ void RenderSVGResourceContainer::markClientForInvalidation(RenderObject* client,
break;
case RepaintInvalidation:
if (client->view()) {
- if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && frameView()->isInLayout())
- client->setShouldDoFullRepaintAfterLayout(true);
+ if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled() && frameView()->isInPerformLayout())
+ client->setShouldDoFullPaintInvalidationAfterLayout(true);
else
- client->repaint();
+ client->paintInvalidationForWholeRenderer();
}
break;
case ParentOnlyInvalidation:
@@ -202,7 +200,7 @@ void RenderSVGResourceContainer::invalidateCacheAndMarkForLayout(SubtreeLayoutSc
if (selfNeedsLayout())
return;
- setNeedsLayout(MarkContainingBlockChain, layoutScope);
+ setNeedsLayoutAndFullPaintInvalidation(MarkContainingBlockChain, layoutScope);
if (everHadLayout())
removeAllClientsFromCache();
@@ -210,33 +208,36 @@ void RenderSVGResourceContainer::invalidateCacheAndMarkForLayout(SubtreeLayoutSc
void RenderSVGResourceContainer::registerResource()
{
- SVGDocumentExtensions* extensions = svgExtensionsFromElement(element());
- if (!extensions->hasPendingResource(m_id)) {
- extensions->addResource(m_id, this);
+ SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
+ if (!extensions.hasPendingResource(m_id)) {
+ extensions.addResource(m_id, this);
return;
}
- OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions->removePendingResource(m_id));
+ OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions.removePendingResource(m_id));
// Cache us with the new id.
- extensions->addResource(m_id, this);
+ extensions.addResource(m_id, this);
// Update cached resources of pending clients.
const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
ASSERT((*it)->hasPendingResources());
- extensions->clearHasPendingResourcesIfPossible(*it);
+ extensions.clearHasPendingResourcesIfPossible(*it);
RenderObject* renderer = (*it)->renderer();
if (!renderer)
continue;
- SVGResourcesCache::clientStyleChanged(renderer, StyleDifferenceLayout, renderer->style());
- renderer->setNeedsLayout();
+
+ StyleDifference diff;
+ diff.setNeedsFullLayout();
+ SVGResourcesCache::clientStyleChanged(renderer, diff, renderer->style());
+ renderer->setNeedsLayoutAndFullPaintInvalidation();
}
}
-bool RenderSVGResourceContainer::shouldTransformOnTextPainting(RenderObject* object, AffineTransform& resourceTransform)
+static bool shouldTransformOnTextPainting(RenderObject* object, AffineTransform& resourceTransform)
{
- ASSERT_UNUSED(object, object);
+ ASSERT(object);
// This method should only be called for RenderObjects that deal with text rendering. Cmp. RenderObject.h's is*() methods.
ASSERT(object->isSVGText() || object->isSVGTextPath() || object->isSVGInline());
@@ -251,6 +252,26 @@ bool RenderSVGResourceContainer::shouldTransformOnTextPainting(RenderObject* obj
return true;
}
+AffineTransform RenderSVGResourceContainer::computeResourceSpaceTransform(RenderObject* object, const AffineTransform& baseTransform, const SVGRenderStyle* svgStyle, unsigned short resourceMode)
+{
+ AffineTransform computedSpaceTransform = baseTransform;
+ if (resourceMode & ApplyToTextMode) {
+ // Depending on the font scaling factor, we may need to apply an
+ // additional transform (scale-factor) the paintserver, since text
+ // painting removes the scale factor from the context. (See
+ // SVGInlineTextBox::paintTextWithShadows.)
+ AffineTransform additionalTextTransformation;
+ if (shouldTransformOnTextPainting(object, additionalTextTransformation))
+ computedSpaceTransform = additionalTextTransformation * computedSpaceTransform;
+ }
+ if (resourceMode & ApplyToStrokeMode) {
+ // Non-scaling stroke needs to reset the transform back to the host transform.
+ if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
+ computedSpaceTransform = transformOnNonScalingStroke(object, computedSpaceTransform);
+ }
+ return computedSpaceTransform;
+}
+
// FIXME: This does not belong here.
AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
{
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.h
index 71d3c6f0cf1..52b50c394a3 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceContainer.h
@@ -33,12 +33,11 @@ public:
explicit RenderSVGResourceContainer(SVGElement*);
virtual ~RenderSVGResourceContainer();
- virtual void layout();
+ virtual void layout() OVERRIDE;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE FINAL;
virtual bool isSVGResourceContainer() const OVERRIDE FINAL { return true; }
- static bool shouldTransformOnTextPainting(RenderObject*, AffineTransform&);
static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
void idChanged();
@@ -64,6 +63,8 @@ protected:
void clearInvalidationMask() { m_invalidationMask = 0; }
+ static AffineTransform computeResourceSpaceTransform(RenderObject*, const AffineTransform& baseTransform, const SVGRenderStyle*, unsigned short resourceMode);
+
bool m_isInLayout;
private:
@@ -86,21 +87,21 @@ private:
HashSet<RenderLayer*> m_clientLayers;
};
-inline RenderSVGResourceContainer* getRenderSVGResourceContainerById(Document& document, const AtomicString& id)
+inline RenderSVGResourceContainer* getRenderSVGResourceContainerById(TreeScope& treeScope, const AtomicString& id)
{
if (id.isEmpty())
return 0;
- if (RenderSVGResourceContainer* renderResource = document.accessSVGExtensions()->resourceById(id))
+ if (RenderSVGResourceContainer* renderResource = treeScope.document().accessSVGExtensions().resourceById(id))
return renderResource;
return 0;
}
template<typename Renderer>
-Renderer* getRenderSVGResourceById(Document& document, const AtomicString& id)
+Renderer* getRenderSVGResourceById(TreeScope& treeScope, const AtomicString& id)
{
- if (RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id))
+ if (RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(treeScope, id))
return container->cast<Renderer>();
return 0;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
index 840c563c4c2..80f0a30a0c2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
@@ -30,9 +30,9 @@
#include "core/rendering/svg/SVGRenderingContext.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "platform/graphics/UnacceleratedImageBufferSurface.h"
+#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
#include "platform/graphics/filters/SourceAlpha.h"
#include "platform/graphics/filters/SourceGraphic.h"
-#include "platform/graphics/gpu/AcceleratedImageBufferSurface.h"
using namespace std;
@@ -50,6 +50,11 @@ RenderSVGResourceFilter::~RenderSVGResourceFilter()
m_filter.clear();
}
+bool RenderSVGResourceFilter::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isSVGResourceFilterPrimitive();
+}
+
void RenderSVGResourceFilter::removeAllClientsFromCache(bool markForInvalidation)
{
m_filter.clear();
@@ -77,11 +82,7 @@ PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter*
// Add effects to the builder
RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(SourceGraphic::create(filter), SourceAlpha::create(filter));
- for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement())
- continue;
-
- SVGElement* element = toSVGElement(node);
+ for (SVGElement* element = Traversal<SVGElement>::firstChild(*filterElement); element; element = Traversal<SVGElement>::nextSibling(*element)) {
if (!element->isFilterEffect() || !element->renderer())
continue;
@@ -89,46 +90,40 @@ PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter*
RefPtr<FilterEffect> effect = effectElement->build(builder.get(), filter);
if (!effect) {
builder->clearEffects();
- return 0;
+ return nullptr;
}
builder->appendEffectToEffectReferences(effect, effectElement->renderer());
effectElement->setStandardAttributes(effect.get());
- effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnitsCurrentValue(), targetBoundingBox));
+ effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnits()->currentValue()->enumValue(), targetBoundingBox));
effect->setOperatingColorSpace(
effectElement->renderer()->style()->svgStyle()->colorInterpolationFilters() == CI_LINEARRGB ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB);
- builder->add(effectElement->resultCurrentValue(), effect);
+ builder->add(AtomicString(effectElement->result()->currentValue()->value()), effect);
}
return builder.release();
}
-bool RenderSVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size, FloatSize& scale)
+void RenderSVGResourceFilter::adjustScaleForMaximumImageSize(const FloatSize& size, FloatSize& filterScale)
{
- bool matchesFilterSize = true;
- if (size.width() > kMaxFilterSize) {
- scale.setWidth(scale.width() * kMaxFilterSize / size.width());
- matchesFilterSize = false;
- }
- if (size.height() > kMaxFilterSize) {
- scale.setHeight(scale.height() * kMaxFilterSize / size.height());
- matchesFilterSize = false;
- }
+ FloatSize scaledSize(size);
+ scaledSize.scale(filterScale.width(), filterScale.height());
+ float scaledArea = scaledSize.width() * scaledSize.height();
+
+ if (scaledArea <= FilterEffect::maxFilterArea())
+ return;
- return matchesFilterSize;
+ // If area of scaled size is bigger than the upper limit, adjust the scale
+ // to fit.
+ filterScale.scale(sqrt(FilterEffect::maxFilterArea() / scaledArea));
}
-static bool createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform,
- OwnPtr<ImageBuffer>& imageBuffer, bool accelerated)
+static bool createImageBuffer(const Filter* filter, OwnPtr<ImageBuffer>& imageBuffer)
{
- IntRect paintRect = SVGRenderingContext::calculateImageBufferRect(targetRect, absoluteTransform);
+ IntRect paintRect = filter->sourceImageRect();
// Don't create empty ImageBuffers.
if (paintRect.isEmpty())
return false;
- OwnPtr<ImageBufferSurface> surface;
- if (accelerated)
- surface = adoptPtr(new AcceleratedImageBufferSurface(paintRect.size()));
- if (!accelerated || !surface->isValid())
- surface = adoptPtr(new UnacceleratedImageBufferSurface(paintRect.size()));
+ OwnPtr<ImageBufferSurface> surface = adoptPtr(new UnacceleratedImageBufferSurface(paintRect.size()));
if (!surface->isValid())
return false;
OwnPtr<ImageBuffer> image = ImageBuffer::create(surface.release());
@@ -137,12 +132,71 @@ static bool createImageBuffer(const FloatRect& targetRect, const AffineTransform
ASSERT(imageContext);
imageContext->translate(-paintRect.x(), -paintRect.y());
- imageContext->concatCTM(absoluteTransform);
-
+ imageContext->concatCTM(filter->absoluteTransform());
imageBuffer = image.release();
return true;
}
+static void beginDeferredFilter(GraphicsContext* context, FilterData* filterData, SVGFilterElement* filterElement)
+{
+ SkiaImageFilterBuilder builder(context);
+ RefPtr<ImageFilter> imageFilter = builder.build(filterData->builder->lastEffect(), ColorSpaceDeviceRGB);
+ // FIXME: Remove the cache when impl-size painting is enabled on every platform and the non impl-side painting path is removed
+ if (!context->isRecordingCanvas()) // Recording canvases do not use the cache
+ filterData->filter->enableCache();
+ FloatRect boundaries = enclosingIntRect(filterData->boundaries);
+ context->save();
+ float scaledArea = boundaries.width() * boundaries.height();
+
+ // If area of scaled size is bigger than the upper limit, adjust the scale
+ // to fit.
+ if (scaledArea > FilterEffect::maxFilterArea()) {
+ float scale = sqrtf(FilterEffect::maxFilterArea() / scaledArea);
+ context->scale(scale, scale);
+ }
+ // Clip drawing of filtered image to primitive boundaries.
+ context->clipRect(boundaries);
+ if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
+ // Get boundaries in device coords.
+ // FIXME: See crbug.com/382491. Is the use of getCTM OK here, given it does not include device
+ // zoom or High DPI adjustments?
+ FloatSize size = context->getCTM().mapSize(boundaries.size());
+ // Compute the scale amount required so that the resulting offscreen is exactly filterResX by filterResY pixels.
+ float filterResScaleX = filterElement->filterResX()->currentValue()->value() / size.width();
+ float filterResScaleY = filterElement->filterResY()->currentValue()->value() / size.height();
+ // Scale the CTM so the primitive is drawn to filterRes.
+ context->scale(filterResScaleX, filterResScaleY);
+ // Create a resize filter with the inverse scale.
+ AffineTransform resizeMatrix;
+ resizeMatrix.scale(1 / filterResScaleX, 1 / filterResScaleY);
+ imageFilter = builder.buildTransform(resizeMatrix, imageFilter.get());
+ }
+ // If the CTM contains rotation or shearing, apply the filter to
+ // the unsheared/unrotated matrix, and do the shearing/rotation
+ // as a final pass.
+ AffineTransform ctm = context->getCTM();
+ if (ctm.b() || ctm.c()) {
+ AffineTransform scaleAndTranslate;
+ scaleAndTranslate.translate(ctm.e(), ctm.f());
+ scaleAndTranslate.scale(ctm.xScale(), ctm.yScale());
+ ASSERT(scaleAndTranslate.isInvertible());
+ AffineTransform shearAndRotate = scaleAndTranslate.inverse();
+ shearAndRotate.multiply(ctm);
+ context->setCTM(scaleAndTranslate);
+ imageFilter = builder.buildTransform(shearAndRotate, imageFilter.get());
+ }
+ context->beginLayer(1, CompositeSourceOver, &boundaries, ColorFilterNone, imageFilter.get());
+}
+
+static void endDeferredFilter(GraphicsContext* context, FilterData* filterData)
+{
+ context->endLayer();
+ context->restore();
+ // FIXME: Remove the cache when impl-size painting is enabled on every platform and the non impl-side painting path is removed
+ if (!context->isRecordingCanvas()) // Recording canvases do not use the cache
+ filterData->filter->disableCache();
+}
+
bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
@@ -151,10 +205,16 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
clearInvalidationMask();
+ bool deferredFiltersEnabled = object->document().settings()->deferredFiltersEnabled();
if (m_filter.contains(object)) {
FilterData* filterData = m_filter.get(object);
if (filterData->state == FilterData::PaintingSource || filterData->state == FilterData::Applying)
filterData->state = FilterData::CycleDetected;
+ if (deferredFiltersEnabled && filterData->state == FilterData::Built) {
+ SVGFilterElement* filterElement = toSVGFilterElement(element());
+ beginDeferredFilter(context, filterData, filterElement);
+ return true;
+ }
return false; // Already built, or we're in a cycle, or we're marked for removal. Regardless, just do nothing more now.
}
@@ -162,64 +222,65 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
FloatRect targetBoundingBox = object->objectBoundingBox();
SVGFilterElement* filterElement = toSVGFilterElement(element());
- filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnitsCurrentValue(), targetBoundingBox);
+ filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnits()->currentValue()->enumValue(), targetBoundingBox);
if (filterData->boundaries.isEmpty())
return false;
// Determine absolute transformation matrix for filter.
AffineTransform absoluteTransform;
- SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform);
+ SVGRenderingContext::calculateDeviceSpaceTransformation(object, absoluteTransform);
if (!absoluteTransform.isInvertible())
return false;
- // Eliminate shear of the absolute transformation matrix, to be able to produce unsheared tile images for feTile.
- filterData->shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), 0, 0);
+ // Filters cannot handle a full transformation, only scales in each direction.
+ FloatSize filterScale;
+
+ // Calculate the scale factor for the filter.
+ // Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
+ if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
+ // If resolution is specified, scale to match it.
+ filterScale = FloatSize(
+ filterElement->filterResX()->currentValue()->value() / filterData->boundaries.width(),
+ filterElement->filterResY()->currentValue()->value() / filterData->boundaries.height());
+ } else {
+ // Otherwise, use the scale of the absolute transform.
+ filterScale = FloatSize(absoluteTransform.xScale(), absoluteTransform.yScale());
+ }
+ // The size of the scaled filter boundaries shouldn't be bigger than kMaxFilterSize.
+ // Intermediate filters are limited by the filter boundaries so they can't be bigger than this.
+ adjustScaleForMaximumImageSize(filterData->boundaries.size(), filterScale);
- // Determine absolute boundaries of the filter and the drawing region.
- FloatRect absoluteFilterBoundaries = filterData->shearFreeAbsoluteTransform.mapRect(filterData->boundaries);
filterData->drawingRegion = object->strokeBoundingBox();
filterData->drawingRegion.intersect(filterData->boundaries);
- FloatRect absoluteDrawingRegion = filterData->shearFreeAbsoluteTransform.mapRect(filterData->drawingRegion);
+ FloatRect absoluteDrawingRegion = filterData->drawingRegion;
+ if (!deferredFiltersEnabled)
+ absoluteDrawingRegion.scale(filterScale.width(), filterScale.height());
+
+ IntRect intDrawingRegion = enclosingIntRect(absoluteDrawingRegion);
// Create the SVGFilter object.
- bool primitiveBoundingBoxMode = filterElement->primitiveUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
- filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, absoluteDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);
+ bool primitiveBoundingBoxMode = filterElement->primitiveUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
+ filterData->shearFreeAbsoluteTransform = AffineTransform();
+ if (!deferredFiltersEnabled)
+ filterData->shearFreeAbsoluteTransform.scale(filterScale.width(), filterScale.height());
+ filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, intDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);
// Create all relevant filter primitives.
filterData->builder = buildPrimitives(filterData->filter.get());
if (!filterData->builder)
return false;
- // Calculate the scale factor for the use of filterRes.
- // Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
- FloatSize scale(1, 1);
- if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
- scale.setWidth(filterElement->filterResXCurrentValue() / absoluteFilterBoundaries.width());
- scale.setHeight(filterElement->filterResYCurrentValue() / absoluteFilterBoundaries.height());
- }
-
- if (scale.isEmpty())
- return false;
-
- // Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
- FloatRect tempSourceRect = absoluteDrawingRegion;
- tempSourceRect.scale(scale.width(), scale.height());
- fitsInMaximumImageSize(tempSourceRect.size(), scale);
-
- // Set the scale level in SVGFilter.
- filterData->filter->setFilterResolution(scale);
-
FilterEffect* lastEffect = filterData->builder->lastEffect();
if (!lastEffect)
return false;
lastEffect->determineFilterPrimitiveSubregion(ClipToFilterRegion);
- FloatRect subRegion = lastEffect->maxEffectRect();
- // At least one FilterEffect has a too big image size,
- // recalculate the effect sizes with new scale factors.
- if (!fitsInMaximumImageSize(subRegion.size(), scale)) {
- filterData->filter->setFilterResolution(scale);
- lastEffect->determineFilterPrimitiveSubregion(ClipToFilterRegion);
+
+ if (deferredFiltersEnabled) {
+ FilterData* data = filterData.get();
+ m_filter.set(object, filterData.release());
+ beginDeferredFilter(context, data, filterElement);
+ return true;
}
// If the drawingRegion is empty, we have something like <g filter=".."/>.
@@ -231,23 +292,14 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
return false;
}
- // Change the coordinate transformation applied to the filtered element to reflect the resolution of the filter.
- AffineTransform effectiveTransform;
- effectiveTransform.scale(scale.width(), scale.height());
- effectiveTransform.multiply(filterData->shearFreeAbsoluteTransform);
-
OwnPtr<ImageBuffer> sourceGraphic;
- bool isAccelerated = object->document().settings()->acceleratedFiltersEnabled();
- if (!createImageBuffer(filterData->drawingRegion, effectiveTransform, sourceGraphic, isAccelerated)) {
+ if (!createImageBuffer(filterData->filter.get(), sourceGraphic)) {
ASSERT(!m_filter.contains(object));
filterData->savedContext = context;
m_filter.set(object, filterData.release());
return false;
}
- // Set the rendering mode from the page's settings.
- filterData->filter->setIsAccelerated(isAccelerated);
-
GraphicsContext* sourceGraphicContext = sourceGraphic->context();
ASSERT(sourceGraphicContext);
@@ -272,6 +324,12 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
if (!filterData)
return;
+ if (object->document().settings()->deferredFiltersEnabled() && (filterData->state == FilterData::PaintingSource || filterData->state == FilterData::Built)) {
+ endDeferredFilter(context, filterData);
+ filterData->state = FilterData::Built;
+ return;
+ }
+
switch (filterData->state) {
case FilterData::MarkedForRemoval:
m_filter.remove(object);
@@ -319,22 +377,16 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
ImageBuffer* resultImage = lastEffect->asImageBuffer();
if (resultImage) {
- context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse());
-
- context->scale(FloatSize(1 / filterData->filter->filterResolution().width(), 1 / filterData->filter->filterResolution().height()));
- context->drawImageBuffer(resultImage, lastEffect->absolutePaintRect());
- context->scale(filterData->filter->filterResolution());
-
- context->concatCTM(filterData->shearFreeAbsoluteTransform);
+ context->drawImageBuffer(resultImage, filterData->filter->mapAbsoluteRectToLocalRect(lastEffect->absolutePaintRect()));
}
}
filterData->sourceGraphicBuffer.clear();
}
-FloatRect RenderSVGResourceFilter::resourceBoundingBox(RenderObject* object)
+FloatRect RenderSVGResourceFilter::resourceBoundingBox(const RenderObject* object)
{
if (SVGFilterElement* element = toSVGFilterElement(this->element()))
- return SVGLengthContext::resolveRectangle<SVGFilterElement>(element, element->filterUnitsCurrentValue(), object->objectBoundingBox());
+ return SVGLengthContext::resolveRectangle<SVGFilterElement>(element, element->filterUnits()->currentValue()->enumValue(), object->objectBoundingBox());
return FloatRect();
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.h
index 6455b039284..1c679130ccc 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilter.h
@@ -60,30 +60,32 @@ public:
explicit RenderSVGResourceFilter(SVGFilterElement*);
virtual ~RenderSVGResourceFilter();
- virtual const char* renderName() const { return "RenderSVGResourceFilter"; }
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
+
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGResourceFilter"; }
virtual bool isSVGResourceFilter() const OVERRIDE { return true; }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true);
- virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true) OVERRIDE;
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) OVERRIDE;
- virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*);
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE;
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*) OVERRIDE;
- FloatRect resourceBoundingBox(RenderObject*);
+ FloatRect resourceBoundingBox(const RenderObject*);
PassRefPtr<SVGFilterBuilder> buildPrimitives(SVGFilter*);
- SVGUnitTypes::SVGUnitType filterUnits() const { return toSVGFilterElement(element())->filterUnitsCurrentValue(); }
- SVGUnitTypes::SVGUnitType primitiveUnits() const { return toSVGFilterElement(element())->primitiveUnitsCurrentValue(); }
+ SVGUnitTypes::SVGUnitType filterUnits() const { return toSVGFilterElement(element())->filterUnits()->currentValue()->enumValue(); }
+ SVGUnitTypes::SVGUnitType primitiveUnits() const { return toSVGFilterElement(element())->primitiveUnits()->currentValue()->enumValue(); }
void primitiveAttributeChanged(RenderObject*, const QualifiedName&);
- virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
static const RenderSVGResourceType s_resourceType;
FloatRect drawingRegion(RenderObject*) const;
private:
- bool fitsInMaximumImageSize(const FloatSize&, FloatSize&);
+ void adjustScaleForMaximumImageSize(const FloatSize&, FloatSize&);
typedef HashMap<RenderObject*, OwnPtr<FilterData> > FilterMap;
FilterMap m_filter;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
index e34449d35ea..f7fce429304 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
@@ -40,16 +40,17 @@ void RenderSVGResourceFilterPrimitive::styleDidChange(StyleDifference diff, cons
return;
ASSERT(filter->isSVGResourceFilter());
- if (diff == StyleDifferenceEqual || !oldStyle)
+ if (diff.hasNoChange() || !oldStyle)
return;
const SVGRenderStyle* newStyle = this->style()->svgStyle();
- if (element()->hasTagName(SVGNames::feFloodTag)) {
+ ASSERT(element());
+ if (isSVGFEFloodElement(*element())) {
if (newStyle->floodColor() != oldStyle->svgStyle()->floodColor())
toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_colorAttr);
if (newStyle->floodOpacity() != oldStyle->svgStyle()->floodOpacity())
toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_opacityAttr);
- } else if (element()->hasTagName(SVGNames::feDiffuseLightingTag) || element()->hasTagName(SVGNames::feSpecularLightingTag)) {
+ } else if (isSVGFEDiffuseLightingElement(*element()) || isSVGFESpecularLightingElement(*element())) {
if (newStyle->lightingColor() != oldStyle->svgStyle()->lightingColor())
toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::lighting_colorAttr);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h
index 704df3d4075..b2a293d68fe 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.h
@@ -38,10 +38,12 @@ public:
{
}
- virtual void styleDidChange(StyleDifference, const RenderStyle*);
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE { return false; }
- virtual const char* renderName() const { return "RenderSVGResourceFilterPrimitive"; }
- virtual bool isSVGResourceFilterPrimitive() const { return true; }
+ virtual void styleDidChange(StyleDifference, const RenderStyle*) OVERRIDE;
+
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGResourceFilterPrimitive"; }
+ virtual bool isSVGResourceFilterPrimitive() const OVERRIDE { return true; }
inline void primitiveAttributeChanged(const QualifiedName& attribute)
{
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceGradient.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceGradient.cpp
index 4e432a56082..6f44a65b116 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceGradient.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceGradient.cpp
@@ -81,12 +81,10 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
return false;
- OwnPtr<GradientData>& gradientData = m_gradientMap.add(object, nullptr).iterator->value;
+ OwnPtr<GradientData>& gradientData = m_gradientMap.add(object, nullptr).storedValue->value;
if (!gradientData)
gradientData = adoptPtr(new GradientData);
- bool isPaintingText = resourceMode & ApplyToTextMode;
-
// Create gradient object
if (!gradientData->gradient) {
buildGradient(gradientData.get());
@@ -101,36 +99,29 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
calculateGradientTransform(gradientTransform);
gradientData->userspaceTransform *= gradientTransform;
- if (isPaintingText) {
- // Depending on font scaling factor, we may need to rescale the gradient here since
- // text painting removes the scale factor from the context.
- AffineTransform additionalTextTransform;
- if (shouldTransformOnTextPainting(object, additionalTextTransform))
- gradientData->userspaceTransform *= additionalTextTransform;
- }
- gradientData->gradient->setGradientSpaceTransform(gradientData->userspaceTransform);
}
if (!gradientData->gradient)
return false;
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+ ASSERT(svgStyle);
+
+ AffineTransform computedGradientSpaceTransform = computeResourceSpaceTransform(object, gradientData->userspaceTransform, svgStyle, resourceMode);
+ gradientData->gradient->setGradientSpaceTransform(computedGradientSpaceTransform);
+
// Draw gradient
context->save();
- if (isPaintingText)
+ if (resourceMode & ApplyToTextMode)
context->setTextDrawingMode(resourceMode & ApplyToFillMode ? TextModeFill : TextModeStroke);
- const SVGRenderStyle* svgStyle = style->svgStyle();
- ASSERT(svgStyle);
-
if (resourceMode & ApplyToFillMode) {
- context->setAlpha(svgStyle->fillOpacity());
+ context->setAlphaAsFloat(svgStyle->fillOpacity());
context->setFillGradient(gradientData->gradient);
context->setFillRule(svgStyle->fillRule());
} else if (resourceMode & ApplyToStrokeMode) {
- if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
- gradientData->gradient->setGradientSpaceTransform(transformOnNonScalingStroke(object, gradientData->userspaceTransform));
- context->setAlpha(svgStyle->strokeOpacity());
+ context->setAlphaAsFloat(svgStyle->strokeOpacity());
context->setStrokeGradient(gradientData->gradient);
SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceLinearGradient.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceLinearGradient.h
index ba1c3d27884..b829e403004 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceLinearGradient.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceLinearGradient.h
@@ -33,15 +33,15 @@ public:
explicit RenderSVGResourceLinearGradient(SVGLinearGradientElement*);
virtual ~RenderSVGResourceLinearGradient();
- virtual const char* renderName() const { return "RenderSVGResourceLinearGradient"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGResourceLinearGradient"; }
- virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
static const RenderSVGResourceType s_resourceType;
- virtual SVGUnitTypes::SVGUnitType gradientUnits() const { return m_attributes.gradientUnits(); }
- virtual void calculateGradientTransform(AffineTransform& transform) { transform = m_attributes.gradientTransform(); }
- virtual bool collectGradientAttributes(SVGGradientElement*);
- virtual void buildGradient(GradientData*) const;
+ virtual SVGUnitTypes::SVGUnitType gradientUnits() const OVERRIDE { return m_attributes.gradientUnits(); }
+ virtual void calculateGradientTransform(AffineTransform& transform) OVERRIDE { transform = m_attributes.gradientTransform(); }
+ virtual bool collectGradientAttributes(SVGGradientElement*) OVERRIDE;
+ virtual void buildGradient(GradientData*) const OVERRIDE;
FloatPoint startPoint(const LinearGradientAttributes&) const;
FloatPoint endPoint(const LinearGradientAttributes&) const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
index d3de3b7cc64..be93b479b2d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
@@ -23,7 +23,7 @@
#include "core/rendering/svg/RenderSVGResourceMarker.h"
-#include "core/rendering/LayoutRectRecorder.h"
+#include "core/rendering/PaintInfo.h"
#include "core/rendering/svg/RenderSVGContainer.h"
#include "core/rendering/svg/SVGRenderSupport.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
@@ -49,13 +49,8 @@ void RenderSVGResourceMarker::layout()
if (m_isInLayout)
return;
- LayoutRectRecorder recorder(*this);
TemporaryChange<bool> inLayoutChange(m_isInLayout, true);
- // Invalidate all resources if our layout changed.
- if (everHadLayout() && selfNeedsLayout())
- removeAllClientsFromCache();
-
// RenderSVGHiddenContainer overwrites layout(). We need the
// layouting of RenderSVGContainer for calculating local
// transformations and repaint.
@@ -83,7 +78,7 @@ void RenderSVGResourceMarker::applyViewportClip(PaintInfo& paintInfo)
FloatRect RenderSVGResourceMarker::markerBoundaries(const AffineTransform& markerTransformation) const
{
- FloatRect coordinates = RenderSVGContainer::repaintRectInLocalCoordinates();
+ FloatRect coordinates = RenderSVGContainer::paintInvalidationRectInLocalCoordinates();
// Map repaint rect into parent coordinate space, in which the marker boundaries have to be evaluated
coordinates = localToParentTransform().mapRect(coordinates);
@@ -105,7 +100,7 @@ FloatPoint RenderSVGResourceMarker::referencePoint() const
ASSERT(marker);
SVGLengthContext lengthContext(marker);
- return FloatPoint(marker->refXCurrentValue().value(lengthContext), marker->refYCurrentValue().value(lengthContext));
+ return FloatPoint(marker->refX()->currentValue()->value(lengthContext), marker->refY()->currentValue()->value(lengthContext));
}
float RenderSVGResourceMarker::angle() const
@@ -114,8 +109,8 @@ float RenderSVGResourceMarker::angle() const
ASSERT(marker);
float angle = -1;
- if (marker->orientTypeCurrentValue() == SVGMarkerOrientAngle)
- angle = marker->orientAngleCurrentValue().value();
+ if (marker->orientType()->currentValue()->enumValue() == SVGMarkerOrientAngle)
+ angle = marker->orientAngle()->currentValue()->value();
return angle;
}
@@ -126,7 +121,7 @@ AffineTransform RenderSVGResourceMarker::markerTransformation(const FloatPoint&
ASSERT(marker);
float markerAngle = angle();
- bool useStrokeWidth = marker->markerUnitsCurrentValue() == SVGMarkerUnitsStrokeWidth;
+ bool useStrokeWidth = marker->markerUnits()->currentValue()->enumValue() == SVGMarkerUnitsStrokeWidth;
AffineTransform transform;
transform.translate(origin.x(), origin.y());
@@ -142,12 +137,15 @@ void RenderSVGResourceMarker::draw(PaintInfo& paintInfo, const AffineTransform&
// An empty viewBox disables rendering.
SVGMarkerElement* marker = toSVGMarkerElement(element());
ASSERT(marker);
- if (marker->hasAttribute(SVGNames::viewBoxAttr) && marker->viewBoxCurrentValue().isValid() && marker->viewBoxCurrentValue().isEmpty())
+ if (marker->hasAttribute(SVGNames::viewBoxAttr) && marker->viewBox()->currentValue()->isValid() && marker->viewBox()->currentValue()->value().isEmpty())
return;
PaintInfo info(paintInfo);
- GraphicsContextStateSaver stateSaver(*info.context);
- info.applyTransform(transform);
+ GraphicsContextStateSaver stateSaver(*info.context, false);
+ if (!transform.isIdentity()) {
+ stateSaver.save();
+ info.applyTransform(transform, false);
+ }
RenderSVGContainer::paint(info, IntPoint());
}
@@ -181,8 +179,8 @@ void RenderSVGResourceMarker::calcViewport()
ASSERT(marker);
SVGLengthContext lengthContext(marker);
- float w = marker->markerWidthCurrentValue().value(lengthContext);
- float h = marker->markerHeightCurrentValue().value(lengthContext);
+ float w = marker->markerWidth()->currentValue()->value(lengthContext);
+ float h = marker->markerHeight()->currentValue()->value(lengthContext);
m_viewport = FloatRect(0, 0, w, h);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.h
index 625b37a652a..ba31fb21e45 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMarker.h
@@ -28,7 +28,6 @@
namespace WebCore {
-class AffineTransform;
class RenderObject;
class RenderSVGResourceMarker FINAL : public RenderSVGResourceContainer {
@@ -36,30 +35,30 @@ public:
explicit RenderSVGResourceMarker(SVGMarkerElement*);
virtual ~RenderSVGResourceMarker();
- virtual const char* renderName() const { return "RenderSVGResourceMarker"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGResourceMarker"; }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true);
- virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true) OVERRIDE;
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) OVERRIDE;
void draw(PaintInfo&, const AffineTransform&);
// Calculates marker boundaries, mapped to the target element's coordinate space
FloatRect markerBoundaries(const AffineTransform& markerTransformation) const;
- virtual void applyViewportClip(PaintInfo&);
- virtual void layout();
- virtual void calcViewport();
+ virtual void applyViewportClip(PaintInfo&) OVERRIDE;
+ virtual void layout() OVERRIDE;
+ virtual void calcViewport() OVERRIDE;
- virtual const AffineTransform& localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const OVERRIDE;
AffineTransform markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const;
- virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short) { return false; }
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short) OVERRIDE { return false; }
FloatPoint referencePoint() const;
float angle() const;
- SVGMarkerUnitsType markerUnits() const { return toSVGMarkerElement(element())->markerUnitsCurrentValue(); }
+ SVGMarkerUnitsType markerUnits() const { return toSVGMarkerElement(element())->markerUnits()->currentValue()->enumValue(); }
- virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
static const RenderSVGResourceType s_resourceType;
private:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
index 43c64ca081d..98a6d4c7639 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
@@ -66,8 +66,8 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
clearInvalidationMask();
- FloatRect repaintRect = object->repaintRectInLocalCoordinates();
- if (repaintRect.isEmpty() || !element()->hasChildNodes())
+ FloatRect repaintRect = object->paintInvalidationRectInLocalCoordinates();
+ if (repaintRect.isEmpty() || !element()->hasChildren())
return false;
// Content layer start.
@@ -85,7 +85,7 @@ void RenderSVGResourceMasker::postApplyResource(RenderObject* object, GraphicsCo
ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
- FloatRect repaintRect = object->repaintRectInLocalCoordinates();
+ FloatRect repaintRect = object->paintInvalidationRectInLocalCoordinates();
const SVGRenderStyle* svgStyle = style()->svgStyle();
ASSERT(svgStyle);
@@ -115,7 +115,7 @@ void RenderSVGResourceMasker::drawMaskForRenderer(GraphicsContext* context, cons
ASSERT(context);
AffineTransform contentTransformation;
- SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())->maskContentUnitsCurrentValue();
+ SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())->maskContentUnits()->currentValue()->enumValue();
if (contentUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox.y());
contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height());
@@ -133,10 +133,13 @@ PassRefPtr<DisplayList> RenderSVGResourceMasker::asDisplayList(GraphicsContext*
{
ASSERT(context);
- context->beginRecording(repaintRectInLocalCoordinates());
- for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
- RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !renderer)
+ // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection
+ // with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and
+ // userSpaceOnUse units (http://crbug.com/294900).
+ context->beginRecording(strokeBoundingBox());
+ for (Element* childElement = ElementTraversal::firstWithin(*element()); childElement; childElement = ElementTraversal::nextSibling(*childElement)) {
+ RenderObject* renderer = childElement->renderer();
+ if (!childElement->isSVGElement() || !renderer)
continue;
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
@@ -150,24 +153,24 @@ PassRefPtr<DisplayList> RenderSVGResourceMasker::asDisplayList(GraphicsContext*
void RenderSVGResourceMasker::calculateMaskContentRepaintRect()
{
- for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
- RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !renderer)
+ for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
+ RenderObject* renderer = childElement->renderer();
+ if (!renderer)
continue;
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
- m_maskContentBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
+ m_maskContentBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->paintInvalidationRectInLocalCoordinates()));
}
}
-FloatRect RenderSVGResourceMasker::resourceBoundingBox(RenderObject* object)
+FloatRect RenderSVGResourceMasker::resourceBoundingBox(const RenderObject* object)
{
SVGMaskElement* maskElement = toSVGMaskElement(element());
ASSERT(maskElement);
FloatRect objectBoundingBox = object->objectBoundingBox();
- FloatRect maskBoundaries = SVGLengthContext::resolveRectangle<SVGMaskElement>(maskElement, maskElement->maskUnitsCurrentValue(), objectBoundingBox);
+ FloatRect maskBoundaries = SVGLengthContext::resolveRectangle<SVGMaskElement>(maskElement, maskElement->maskUnits()->currentValue()->enumValue(), objectBoundingBox);
// Resource was not layouted yet. Give back clipping rect of the mask.
if (selfNeedsLayout())
@@ -177,7 +180,7 @@ FloatRect RenderSVGResourceMasker::resourceBoundingBox(RenderObject* object)
calculateMaskContentRepaintRect();
FloatRect maskRect = m_maskContentBoundaries;
- if (maskElement->maskContentUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ if (maskElement->maskContentUnits()->currentValue()->value() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
AffineTransform transform;
transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.h
index 2af52752127..e05fc0d9b95 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceMasker.h
@@ -25,7 +25,6 @@
#include "core/svg/SVGUnitTypes.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/IntSize.h"
-#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/ImageBuffer.h"
#include "wtf/HashMap.h"
@@ -34,24 +33,25 @@
namespace WebCore {
class DisplayList;
+class GraphicsContext;
class RenderSVGResourceMasker FINAL : public RenderSVGResourceContainer {
public:
explicit RenderSVGResourceMasker(SVGMaskElement*);
virtual ~RenderSVGResourceMasker();
- virtual const char* renderName() const { return "RenderSVGResourceMasker"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGResourceMasker"; }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true);
- virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true) OVERRIDE;
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) OVERRIDE;
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE;
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short, const Path*, const RenderSVGShape*) OVERRIDE;
- FloatRect resourceBoundingBox(RenderObject*);
+ FloatRect resourceBoundingBox(const RenderObject*);
- SVGUnitTypes::SVGUnitType maskUnits() const { return toSVGMaskElement(element())->maskUnitsCurrentValue(); }
- SVGUnitTypes::SVGUnitType maskContentUnits() const { return toSVGMaskElement(element())->maskContentUnitsCurrentValue(); }
+ SVGUnitTypes::SVGUnitType maskUnits() const { return toSVGMaskElement(element())->maskUnits()->currentValue()->enumValue(); }
+ SVGUnitTypes::SVGUnitType maskContentUnits() const { return toSVGMaskElement(element())->maskContentUnits()->currentValue()->enumValue(); }
- virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
static const RenderSVGResourceType s_resourceType;
private:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
index c107a793f4a..401a29057a8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
@@ -53,6 +53,7 @@ void RenderSVGResourcePattern::removeClientFromCache(RenderObject* client, bool
PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsigned short resourceMode)
{
+ ASSERT(object);
PatternData* currentData = m_patternMap.get(object);
if (currentData && currentData->pattern)
return currentData;
@@ -84,19 +85,18 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
return 0;
AffineTransform absoluteTransformIgnoringRotation;
- SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransformIgnoringRotation);
+ SVGRenderingContext::calculateDeviceSpaceTransformation(object, absoluteTransformIgnoringRotation);
// Ignore 2D rotation, as it doesn't affect the size of the tile.
SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
FloatRect absoluteTileBoundaries = absoluteTransformIgnoringRotation.mapRect(tileBoundaries);
- FloatRect clampedAbsoluteTileBoundaries;
// Scale the tile size to match the scale level of the patternTransform.
absoluteTileBoundaries.scale(static_cast<float>(m_attributes.patternTransform().xScale()),
static_cast<float>(m_attributes.patternTransform().yScale()));
// Build tile image.
- OwnPtr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries);
+ OwnPtr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform);
if (!tileImage)
return 0;
@@ -117,18 +117,10 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
if (!patternTransform.isIdentity())
patternData->transform = patternTransform * patternData->transform;
- // Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows.
- if (resourceMode & ApplyToTextMode) {
- AffineTransform additionalTextTransformation;
- if (shouldTransformOnTextPainting(object, additionalTextTransformation))
- patternData->transform *= additionalTextTransformation;
- }
- patternData->pattern->setPatternSpaceTransform(patternData->transform);
-
// Various calls above may trigger invalidations in some fringe cases (ImageBuffer allocation
// failures in the SVG image cache for example). To avoid having our PatternData deleted by
// removeAllClientsFromCache(), we only make it visible in the cache at the very end.
- return m_patternMap.set(object, patternData.release()).iterator->value.get();
+ return m_patternMap.set(object, patternData.release()).storedValue->value.get();
}
bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
@@ -150,20 +142,21 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
if (!patternData)
return false;
- // Draw pattern
- context->save();
-
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
+ AffineTransform computedPatternSpaceTransform = computeResourceSpaceTransform(object, patternData->transform, svgStyle, resourceMode);
+ patternData->pattern->setPatternSpaceTransform(computedPatternSpaceTransform);
+
+ // Draw pattern
+ context->save();
+
if (resourceMode & ApplyToFillMode) {
- context->setAlpha(svgStyle->fillOpacity());
+ context->setAlphaAsFloat(svgStyle->fillOpacity());
context->setFillPattern(patternData->pattern);
context->setFillRule(svgStyle->fillRule());
} else if (resourceMode & ApplyToStrokeMode) {
- if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
- patternData->pattern->setPatternSpaceTransform(transformOnNonScalingStroke(object, patternData->transform));
- context->setAlpha(svgStyle->strokeOpacity());
+ context->setAlphaAsFloat(svgStyle->strokeOpacity());
context->setStrokePattern(patternData->pattern);
SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
}
@@ -235,10 +228,9 @@ bool RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer,
PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes,
const FloatRect& tileBoundaries,
const FloatRect& absoluteTileBoundaries,
- const AffineTransform& tileImageTransform,
- FloatRect& clampedAbsoluteTileBoundaries) const
+ const AffineTransform& tileImageTransform) const
{
- clampedAbsoluteTileBoundaries = SVGRenderingContext::clampedAbsoluteTargetRect(absoluteTileBoundaries);
+ FloatRect clampedAbsoluteTileBoundaries = SVGRenderingContext::clampedAbsoluteTargetRect(absoluteTileBoundaries);
IntSize imageSize(roundedIntSize(clampedAbsoluteTileBoundaries.size()));
if (imageSize.isEmpty())
@@ -250,11 +242,12 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternA
GraphicsContext* tileImageContext = tileImage->context();
ASSERT(tileImageContext);
IntSize unclampedImageSize(roundedIntSize(absoluteTileBoundaries.size()));
- tileImageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTileBoundaries.width(), unclampedImageSize.height() / absoluteTileBoundaries.height()));
+ tileImageContext->scale(unclampedImageSize.width() / absoluteTileBoundaries.width(), unclampedImageSize.height() / absoluteTileBoundaries.height());
// The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation).
- tileImageContext->scale(FloatSize(clampedAbsoluteTileBoundaries.width() / tileBoundaries.width(),
- clampedAbsoluteTileBoundaries.height() / tileBoundaries.height()));
+ tileImageContext->scale(
+ clampedAbsoluteTileBoundaries.width() / tileBoundaries.width(),
+ clampedAbsoluteTileBoundaries.height() / tileBoundaries.height());
// Apply tile image transformations.
if (!tileImageTransform.isIdentity())
@@ -265,12 +258,12 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternA
contentTransformation = tileImageTransform;
// Draw the content into the ImageBuffer.
- for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement() || !node->renderer())
+ for (Element* element = ElementTraversal::firstWithin(*attributes.patternContentElement()); element; element = ElementTraversal::nextSibling(*element)) {
+ if (!element->isSVGElement() || !element->renderer())
continue;
- if (node->renderer()->needsLayout())
+ if (element->renderer()->needsLayout())
return nullptr;
- SVGRenderingContext::renderSubtree(tileImage->context(), node->renderer(), contentTransformation);
+ SVGRenderingContext::renderSubtree(tileImage->context(), element->renderer(), contentTransformation);
}
return tileImage.release();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.h
index 56a8318e06d..d6b4f12e577 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourcePattern.h
@@ -46,23 +46,22 @@ class RenderSVGResourcePattern FINAL : public RenderSVGResourceContainer {
public:
explicit RenderSVGResourcePattern(SVGPatternElement*);
- virtual const char* renderName() const { return "RenderSVGResourcePattern"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGResourcePattern"; }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true);
- virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true) OVERRIDE;
+ virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) OVERRIDE;
- virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*);
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE;
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*) OVERRIDE;
- virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
static const RenderSVGResourceType s_resourceType;
private:
bool buildTileImageTransform(RenderObject*, const PatternAttributes&, const SVGPatternElement*, FloatRect& patternBoundaries, AffineTransform& tileImageTransform) const;
PassOwnPtr<ImageBuffer> createTileImage(const PatternAttributes&, const FloatRect& tileBoundaries,
- const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform,
- FloatRect& clampedAbsoluteTileBoundaries) const;
+ const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform) const;
PatternData* buildPattern(RenderObject*, unsigned short resourceMode);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceRadialGradient.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceRadialGradient.h
index 43ee07601e0..1f9145a02bd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceRadialGradient.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceRadialGradient.h
@@ -33,15 +33,15 @@ public:
explicit RenderSVGResourceRadialGradient(SVGRadialGradientElement*);
virtual ~RenderSVGResourceRadialGradient();
- virtual const char* renderName() const { return "RenderSVGResourceRadialGradient"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGResourceRadialGradient"; }
- virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
static const RenderSVGResourceType s_resourceType;
- virtual SVGUnitTypes::SVGUnitType gradientUnits() const { return m_attributes.gradientUnits(); }
- virtual void calculateGradientTransform(AffineTransform& transform) { transform = m_attributes.gradientTransform(); }
- virtual bool collectGradientAttributes(SVGGradientElement*);
- virtual void buildGradient(GradientData*) const;
+ virtual SVGUnitTypes::SVGUnitType gradientUnits() const OVERRIDE { return m_attributes.gradientUnits(); }
+ virtual void calculateGradientTransform(AffineTransform& transform) OVERRIDE { transform = m_attributes.gradientTransform(); }
+ virtual bool collectGradientAttributes(SVGGradientElement*) OVERRIDE;
+ virtual void buildGradient(GradientData*) const OVERRIDE;
FloatPoint centerPoint(const RadialGradientAttributes&) const;
FloatPoint focalPoint(const RadialGradientAttributes&) const;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp
index a79ad3ad916..fac2a846c9a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp
@@ -21,8 +21,8 @@
#include "core/rendering/svg/RenderSVGResourceSolidColor.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/svg/RenderSVGShape.h"
#include "core/rendering/svg/SVGRenderSupport.h"
@@ -56,9 +56,9 @@ bool RenderSVGResourceSolidColor::applyResource(RenderObject* object, RenderStyl
if (resourceMode & ApplyToFillMode) {
if (!isRenderingMask && svgStyle)
- context->setAlpha(svgStyle->fillOpacity());
+ context->setAlphaAsFloat(svgStyle->fillOpacity());
else
- context->setAlpha(1);
+ context->setAlphaAsFloat(1);
context->setFillColor(m_color);
if (!isRenderingMask)
context->setFillRule(svgStyle ? svgStyle->fillRule() : RULE_NONZERO);
@@ -68,7 +68,7 @@ bool RenderSVGResourceSolidColor::applyResource(RenderObject* object, RenderStyl
} else if (resourceMode & ApplyToStrokeMode) {
// When rendering the mask for a RenderSVGResourceClipper, the stroke code path is never hit.
ASSERT(!isRenderingMask);
- context->setAlpha(svgStyle ? svgStyle->strokeOpacity() : 1);
+ context->setAlphaAsFloat(svgStyle ? svgStyle->strokeOpacity() : 1);
context->setStrokeColor(m_color);
if (style)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.h
index 85937ce9ef1..3583a0d1aec 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGResourceSolidColor.h
@@ -26,18 +26,18 @@
namespace WebCore {
-class RenderSVGResourceSolidColor : public RenderSVGResource {
+class RenderSVGResourceSolidColor FINAL : public RenderSVGResource {
public:
RenderSVGResourceSolidColor();
virtual ~RenderSVGResourceSolidColor();
- virtual void removeAllClientsFromCache(bool = true) { }
- virtual void removeClientFromCache(RenderObject*, bool = true) { }
+ virtual void removeAllClientsFromCache(bool = true) OVERRIDE { }
+ virtual void removeClientFromCache(RenderObject*, bool = true) OVERRIDE { }
- virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
- virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*);
+ virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE;
+ virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*) OVERRIDE;
- virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
static const RenderSVGResourceType s_resourceType;
const Color& color() const { return m_color; }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.cpp
index a4355cd4d9a..d88947d3574 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.cpp
@@ -25,19 +25,21 @@
#include "core/rendering/svg/RenderSVGRoot.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
+#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderPart.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/svg/RenderSVGResourceContainer.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/rendering/svg/SVGRenderingContext.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCache.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGSVGElement.h"
#include "core/svg/graphics/SVGImage.h"
+#include "platform/LengthFunctions.h"
#include "platform/graphics/GraphicsContext.h"
using namespace std;
@@ -49,6 +51,7 @@ RenderSVGRoot::RenderSVGRoot(SVGElement* node)
, m_objectBoundingBoxValid(false)
, m_isLayoutSizeChanged(false)
, m_needsBoundariesOrTransformUpdate(true)
+ , m_hasBoxDecorations(false)
{
}
@@ -56,19 +59,13 @@ RenderSVGRoot::~RenderSVGRoot()
{
}
-void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
+void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const
{
// Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing
// SVG needs to specify how to calculate some intrinsic sizing properties to enable inclusion within other languages.
// The intrinsic width and height of the viewport of SVG content must be determined from the ‘width’ and ‘height’ attributes.
- // If either of these are not specified, a value of '100%' must be assumed. Note: the ‘width’ and ‘height’ attributes are not
- // the same as the CSS width and height properties. Specifically, percentage values do not provide an intrinsic width or height,
- // and do not indicate a percentage of the containing block. Rather, once the viewport is established, they indicate the portion
- // of the viewport that is actually covered by image data.
SVGSVGElement* svg = toSVGSVGElement(node());
ASSERT(svg);
- Length intrinsicWidthAttribute = svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties);
- Length intrinsicHeightAttribute = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);
// The intrinsic aspect ratio of the viewport of SVG content is necessary for example, when including SVG from an ‘object’
// element in HTML styled with CSS. It is possible (indeed, common) for an SVG graphic to have an intrinsic aspect ratio but
@@ -77,33 +74,21 @@ void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, d
// - If the ‘width’ and ‘height’ of the rootmost ‘svg’ element are both specified with unit identifiers (in, mm, cm, pt, pc,
// px, em, ex) or in user units, then the aspect ratio is calculated from the ‘width’ and ‘height’ attributes after
// resolving both values to user units.
- if (intrinsicWidthAttribute.isFixed() || intrinsicHeightAttribute.isFixed()) {
- if (intrinsicWidthAttribute.isFixed())
- intrinsicSize.setWidth(floatValueForLength(intrinsicWidthAttribute, 0, 0));
- if (intrinsicHeightAttribute.isFixed())
- intrinsicSize.setHeight(floatValueForLength(intrinsicHeightAttribute, 0, 0));
- if (!intrinsicSize.isEmpty())
- intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height());
- return;
- }
+ intrinsicSize.setWidth(floatValueForLength(svg->intrinsicWidth(), 0));
+ intrinsicSize.setHeight(floatValueForLength(svg->intrinsicHeight(), 0));
- // - If either/both of the ‘width’ and ‘height’ of the rootmost ‘svg’ element are in percentage units (or omitted), the
- // aspect ratio is calculated from the width and height values of the ‘viewBox’ specified for the current SVG document
- // fragment. If the ‘viewBox’ is not correctly specified, or set to 'none', the intrinsic aspect ratio cannot be
- // calculated and is considered unspecified.
- intrinsicSize = svg->viewBoxCurrentValue().size();
if (!intrinsicSize.isEmpty()) {
- // The viewBox can only yield an intrinsic ratio, not an intrinsic size.
intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height());
- intrinsicSize = FloatSize();
- return;
- }
-
- // If our intrinsic size is in percentage units, return those to the caller through the intrinsicSize. Notify the caller
- // about the special situation, by setting isPercentageIntrinsicSize=true, so it knows how to interpret the return values.
- if (intrinsicWidthAttribute.isPercent() && intrinsicHeightAttribute.isPercent()) {
- isPercentageIntrinsicSize = true;
- intrinsicSize = FloatSize(intrinsicWidthAttribute.percent(), intrinsicHeightAttribute.percent());
+ } else {
+ // - If either/both of the ‘width’ and ‘height’ of the rootmost ‘svg’ element are in percentage units (or omitted), the
+ // aspect ratio is calculated from the width and height values of the ‘viewBox’ specified for the current SVG document
+ // fragment. If the ‘viewBox’ is not correctly specified, or set to 'none', the intrinsic aspect ratio cannot be
+ // calculated and is considered unspecified.
+ FloatSize viewBoxSize = svg->viewBox()->currentValue()->value().size();
+ if (!viewBoxSize.isEmpty()) {
+ // The viewBox can only yield an intrinsic ratio, not an intrinsic size.
+ intrinsicRatio = viewBoxSize.width() / static_cast<double>(viewBoxSize.height());
+ }
}
}
@@ -117,20 +102,20 @@ bool RenderSVGRoot::isEmbeddedThroughFrameContainingSVGDocument() const
if (!node())
return false;
- Frame* frame = node()->document().frame();
+ LocalFrame* frame = node()->document().frame();
if (!frame)
return false;
// If our frame has an owner renderer, we're embedded through eg. object/embed/iframe,
- // but we only negotiate if we're in an SVG document.
- if (!frame->ownerRenderer())
+ // but we only negotiate if we're in an SVG document inside a embedded object (object/embed).
+ if (!frame->ownerRenderer() || !frame->ownerRenderer()->isEmbeddedObject())
return false;
return frame->document()->isSVGDocument();
}
-static inline LayoutUnit resolveLengthAttributeForSVG(const Length& length, float scale, float maxSize, RenderView* renderView)
+static inline LayoutUnit resolveLengthAttributeForSVG(const Length& length, float scale, float maxSize)
{
- return static_cast<LayoutUnit>(valueForLength(length, maxSize, renderView) * (length.isFixed() ? scale : 1));
+ return static_cast<LayoutUnit>(valueForLength(length, maxSize) * (length.isFixed() ? scale : 1));
}
LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
@@ -142,15 +127,14 @@ LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred sho
if (!m_containerSize.isEmpty())
return m_containerSize.width();
+ if (isEmbeddedThroughFrameContainingSVGDocument())
+ return containingBlock()->availableLogicalWidth();
+
if (style()->logicalWidth().isSpecified() || style()->logicalMaxWidth().isSpecified())
return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred);
- if (svg->widthAttributeEstablishesViewport())
- return resolveLengthAttributeForSVG(svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties), style()->effectiveZoom(), containingBlock()->availableLogicalWidth(), view());
-
- // SVG embedded through object/embed/iframe.
- if (isEmbeddedThroughFrameContainingSVGDocument())
- return document().frame()->ownerRenderer()->availableLogicalWidth();
+ if (svg->hasIntrinsicWidth())
+ return resolveLengthAttributeForSVG(svg->intrinsicWidth(), style()->effectiveZoom(), containingBlock()->availableLogicalWidth().toFloat());
// SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred);
@@ -165,27 +149,14 @@ LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const
if (!m_containerSize.isEmpty())
return m_containerSize.height();
+ if (isEmbeddedThroughFrameContainingSVGDocument())
+ return containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding);
+
if (style()->logicalHeight().isSpecified() || style()->logicalMaxHeight().isSpecified())
return RenderReplaced::computeReplacedLogicalHeight();
- if (svg->heightAttributeEstablishesViewport()) {
- Length height = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);
- if (height.isPercent()) {
- RenderBlock* cb = containingBlock();
- ASSERT(cb);
- while (cb->isAnonymous()) {
- cb = cb->containingBlock();
- cb->addPercentHeightDescendant(const_cast<RenderSVGRoot*>(this));
- }
- } else
- RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this));
-
- return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding), view());
- }
-
- // SVG embedded through object/embed/iframe.
- if (isEmbeddedThroughFrameContainingSVGDocument())
- return document().frame()->ownerRenderer()->availableLogicalHeight(IncludeMarginBorderPadding);
+ if (svg->hasIntrinsicHeight())
+ return resolveLengthAttributeForSVG(svg->intrinsicHeight(), style()->effectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding).toFloat());
// SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
return RenderReplaced::computeReplacedLogicalHeight();
@@ -195,13 +166,11 @@ void RenderSVGRoot::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
-
// Arbitrary affine transforms are incompatible with LayoutState.
- LayoutStateDisabler layoutStateDisabler(view());
+ ForceHorriblySlowRectMapping slowRectMapping(*this);
bool needsLayout = selfNeedsLayout();
- LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && needsLayout);
+ LayoutRepainter repainter(*this, checkForPaintInvalidationDuringLayout() && needsLayout);
LayoutSize oldSize = size();
updateLogicalWidth();
@@ -222,13 +191,34 @@ void RenderSVGRoot::layout()
m_needsBoundariesOrTransformUpdate = false;
}
- updateLayerTransform();
+ m_overflow.clear();
+ addVisualEffectOverflow();
- repainter.repaintAfterLayout();
+ if (!shouldApplyViewportClip()) {
+ FloatRect contentRepaintRect = paintInvalidationRectInLocalCoordinates();
+ contentRepaintRect = m_localToBorderBoxTransform.mapRect(contentRepaintRect);
+ addVisualOverflow(enclosingLayoutRect(contentRepaintRect));
+ }
+ updateLayerTransformAfterLayout();
+ m_hasBoxDecorations = isDocumentElement() ? calculateHasBoxDecorations() : hasBoxDecorations();
+ invalidateBackgroundObscurationStatus();
+
+ repainter.repaintAfterLayout();
clearNeedsLayout();
}
+bool RenderSVGRoot::shouldApplyViewportClip() const
+{
+ // the outermost svg is clipped if auto, and svg document roots are always clipped
+ // When the svg is stand-alone (isDocumentElement() == true) the viewport clipping should always
+ // be applied, noting that the window scrollbars should be hidden if overflow=hidden.
+ return style()->overflowX() == OHIDDEN
+ || style()->overflowX() == OAUTO
+ || style()->overflowX() == OSCROLL
+ || this->isDocumentElement();
+}
+
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// An empty viewport disables rendering.
@@ -239,6 +229,10 @@ void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint
if (paintInfo.context->paintingDisabled())
return;
+ // SVG outlines are painted during PaintPhaseForeground.
+ if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline)
+ return;
+
// An empty viewBox also disables rendering.
// (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute)
SVGSVGElement* svg = toSVGSVGElement(node());
@@ -257,8 +251,9 @@ void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint
PaintInfo childPaintInfo(paintInfo);
childPaintInfo.context->save();
- // Apply initial viewport clip - not affected by overflow handling
- childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset, paintInfo.renderRegion)));
+ // Apply initial viewport clip
+ if (shouldApplyViewportClip())
+ childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset)));
// Convert from container offsets (html renderers) to a relative transform (svg renderers).
// Transform from our paint container's coordinate system to our local coords.
@@ -292,13 +287,22 @@ void RenderSVGRoot::willBeDestroyed()
void RenderSVGRoot::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
- if (diff == StyleDifferenceLayout)
+ if (diff.needsFullLayout())
setNeedsBoundariesUpdate();
+ if (diff.needsRepaint()) {
+ // Box decorations may have appeared/disappeared - recompute status.
+ m_hasBoxDecorations = calculateHasBoxDecorations();
+ }
RenderReplaced::styleDidChange(diff, oldStyle);
SVGResourcesCache::clientStyleChanged(this, diff, style());
}
+bool RenderSVGRoot::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ return child->isSVG() && !(child->isSVGInline() || child->isSVGInlineText());
+}
+
void RenderSVGRoot::addChild(RenderObject* child, RenderObject* beforeChild)
{
RenderReplaced::addChild(child, beforeChild);
@@ -330,12 +334,13 @@ void RenderSVGRoot::buildLocalToBorderBoxTransform()
SVGSVGElement* svg = toSVGSVGElement(node());
ASSERT(svg);
float scale = style()->effectiveZoom();
- SVGPoint translate = svg->currentTranslate();
+ FloatPoint translate = svg->currentTranslate();
LayoutSize borderAndPadding(borderLeft() + paddingLeft(), borderTop() + paddingTop());
m_localToBorderBoxTransform = svg->viewBoxToViewTransform(contentWidth() / scale, contentHeight() / scale);
- if (borderAndPadding.isEmpty() && scale == 1 && translate == SVGPoint::zero())
+ AffineTransform viewToBorderBoxTransform(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y());
+ if (viewToBorderBoxTransform.isIdentity())
return;
- m_localToBorderBoxTransform = AffineTransform(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y()) * m_localToBorderBoxTransform;
+ m_localToBorderBoxTransform = viewToBorderBoxTransform * m_localToBorderBoxTransform;
}
const AffineTransform& RenderSVGRoot::localToParentTransform() const
@@ -349,23 +354,53 @@ const AffineTransform& RenderSVGRoot::localToParentTransform() const
return m_localToParentTransform;
}
-LayoutRect RenderSVGRoot::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
+LayoutRect RenderSVGRoot::clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const
{
- return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
+ // This is an open-coded aggregate of SVGRenderSupport::clippedOverflowRectForPaintInvalidation,
+ // RenderSVGRoot::computeFloatRectForPaintInvalidation and RenderReplaced::clippedOverflowRectForPaintInvalidation.
+ // The reason for this is to optimize/minimize the repaint rect when the box is not "decorated"
+ // (does not have background/border/etc.)
+
+ // Return early for any cases where we don't actually paint.
+ if (style()->visibility() != VISIBLE && !enclosingLayer()->hasVisibleContent())
+ return LayoutRect();
+
+ // Compute the repaint rect of the content of the SVG in the border-box coordinate space.
+ FloatRect contentRepaintRect = paintInvalidationRectInLocalCoordinates();
+ contentRepaintRect = m_localToBorderBoxTransform.mapRect(contentRepaintRect);
+
+ // Apply initial viewport clip, overflow:visible content is added to visualOverflow
+ // but the most common case is that overflow is hidden, so always intersect.
+ contentRepaintRect.intersect(pixelSnappedBorderBoxRect());
+
+ LayoutRect repaintRect = enclosingLayoutRect(contentRepaintRect);
+ // If the box is decorated or is overflowing, extend it to include the border-box and overflow.
+ if (m_hasBoxDecorations || hasRenderOverflow()) {
+ // The selectionRect can project outside of the overflowRect, so take their union
+ // for repainting to avoid selection painting glitches.
+ LayoutRect decoratedRepaintRect = unionRect(localSelectionRect(false), visualOverflowRect());
+ repaintRect.unite(decoratedRepaintRect);
+ }
+
+ // Compute the repaint rect in the parent coordinate space.
+ LayoutRect rect = enclosingIntRect(repaintRect);
+ RenderReplaced::mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect);
+ return rect;
}
-void RenderSVGRoot::computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const
+void RenderSVGRoot::computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect& paintInvalidationRect, bool fixed) const
{
// Apply our local transforms (except for x/y translation), then our shadow,
// and then call RenderBox's method to handle all the normal CSS Box model bits
- repaintRect = m_localToBorderBoxTransform.mapRect(repaintRect);
+ paintInvalidationRect = m_localToBorderBoxTransform.mapRect(paintInvalidationRect);
- // Apply initial viewport clip - not affected by overflow settings
- repaintRect.intersect(pixelSnappedBorderBoxRect());
+ // Apply initial viewport clip
+ if (shouldApplyViewportClip())
+ paintInvalidationRect.intersect(pixelSnappedBorderBoxRect());
- LayoutRect rect = enclosingIntRect(repaintRect);
- RenderReplaced::computeRectForRepaint(repaintContainer, rect, fixed);
- repaintRect = rect;
+ LayoutRect rect = enclosingIntRect(paintInvalidationRect);
+ RenderReplaced::mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, fixed);
+ paintInvalidationRect = rect;
}
// This method expects local CSS box coordinates.
@@ -374,7 +409,9 @@ void RenderSVGRoot::computeFloatRectForRepaint(const RenderLayerModelObject* rep
void RenderSVGRoot::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
{
ASSERT(mode & ~IsFixed); // We should have no fixed content in the SVG rendering tree.
- ASSERT(mode & UseTransforms); // mapping a point through SVG w/o respecting trasnforms is useless.
+ // We used to have this ASSERT here, but we removed it when enabling layer squashing.
+ // See http://crbug.com/364901
+ // ASSERT(mode & UseTransforms); // mapping a point through SVG w/o respecting trasnforms is useless.
RenderReplaced::mapLocalToContainer(repaintContainer, transformState, mode | ApplyContainerFlip, wasFixed);
}
@@ -388,7 +425,6 @@ void RenderSVGRoot::updateCachedBoundaries()
{
SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox);
SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
- m_repaintBoundingBox.inflate(borderAndPaddingWidth());
}
bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
@@ -412,11 +448,11 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
}
// If we didn't early exit above, we've just hit the container <svg> element. Unlike SVG 1.1, 2nd Edition allows container elements to be hit.
- if (hitTestAction == HitTestBlockBackground && visibleToHitTestRequest(request)) {
- // Only return true here, if the last hit testing phase 'BlockBackground' is executed. If we'd return true in the 'Foreground' phase,
- // hit testing would stop immediately. For SVG only trees this doesn't matter. Though when we have a <foreignObject> subtree we need
- // to be able to detect hits on the background of a <div> element. If we'd return true here in the 'Foreground' phase, we are not able
- // to detect these hits anymore.
+ if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && visibleToHitTestRequest(request)) {
+ // Only return true here, if the last hit testing phase 'BlockBackground' (or 'ChildBlockBackground' - depending on context) is executed.
+ // If we'd return true in the 'Foreground' phase, hit testing would stop immediately. For SVG only trees this doesn't matter.
+ // Though when we have a <foreignObject> subtree we need to be able to detect hits on the background of a <div> element.
+ // If we'd return true here in the 'Foreground' phase, we are not able to detect these hits anymore.
LayoutRect boundsRect(accumulatedOffset + location(), size());
if (locationInContainer.intersects(boundsRect)) {
updateHitTestResult(result, pointInBorderBox);
@@ -428,27 +464,4 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
return false;
}
-bool RenderSVGRoot::hasRelativeDimensions() const
-{
- SVGSVGElement* svg = toSVGSVGElement(node());
- ASSERT(svg);
-
- return svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent() || svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties).isPercent();
-}
-
-bool RenderSVGRoot::hasRelativeIntrinsicLogicalWidth() const
-{
- SVGSVGElement* svg = toSVGSVGElement(node());
- ASSERT(svg);
- return svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties).isPercent();
-}
-
-bool RenderSVGRoot::hasRelativeLogicalHeight() const
-{
- SVGSVGElement* svg = toSVGSVGElement(node());
- ASSERT(svg);
-
- return svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent();
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.h
index f907222eb81..b38d51cbde8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGRoot.h
@@ -24,12 +24,10 @@
#define RenderSVGRoot_h
#include "core/rendering/RenderReplaced.h"
-#include "core/rendering/svg/SVGRenderSupport.h"
#include "platform/geometry/FloatRect.h"
namespace WebCore {
-class AffineTransform;
class SVGElement;
class RenderSVGRoot FINAL : public RenderReplaced {
@@ -40,66 +38,77 @@ public:
bool isEmbeddedThroughSVGImage() const;
bool isEmbeddedThroughFrameContainingSVGDocument() const;
- virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const;
+ virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const OVERRIDE;
RenderObject* firstChild() const { ASSERT(children() == virtualChildren()); return children()->firstChild(); }
RenderObject* lastChild() const { ASSERT(children() == virtualChildren()); return children()->lastChild(); }
+ // If you have a RenderSVGRoot, use firstChild or lastChild instead.
+ void slowFirstChild() const WTF_DELETED_FUNCTION;
+ void slowLastChild() const WTF_DELETED_FUNCTION;
+
const RenderObjectChildList* children() const { return &m_children; }
RenderObjectChildList* children() { return &m_children; }
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
- virtual void setNeedsBoundariesUpdate() { m_needsBoundariesOrTransformUpdate = true; }
- virtual bool needsBoundariesUpdate() OVERRIDE { return m_needsBoundariesOrTransformUpdate; }
- virtual void setNeedsTransformUpdate() { m_needsBoundariesOrTransformUpdate = true; }
+ virtual void setNeedsBoundariesUpdate() OVERRIDE { m_needsBoundariesOrTransformUpdate = true; }
+ virtual void setNeedsTransformUpdate() OVERRIDE { m_needsBoundariesOrTransformUpdate = true; }
IntSize containerSize() const { return m_containerSize; }
- void setContainerSize(const IntSize& containerSize) { m_containerSize = containerSize; }
-
- virtual bool hasRelativeDimensions() const OVERRIDE;
- virtual bool hasRelativeIntrinsicLogicalWidth() const OVERRIDE;
- virtual bool hasRelativeLogicalHeight() const OVERRIDE;
+ void setContainerSize(const IntSize& containerSize)
+ {
+ // SVGImage::draw() does a view layout prior to painting,
+ // and we need that layout to know of the new size otherwise
+ // the rendering may be incorrectly using the old size.
+ if (m_containerSize != containerSize)
+ setNeedsLayoutAndFullPaintInvalidation();
+ m_containerSize = containerSize;
+ }
// localToBorderBoxTransform maps local SVG viewport coordinates to local CSS box coordinates.
const AffineTransform& localToBorderBoxTransform() const { return m_localToBorderBoxTransform; }
private:
- virtual RenderObjectChildList* virtualChildren() { return children(); }
- virtual const RenderObjectChildList* virtualChildren() const { return children(); }
+ virtual RenderObjectChildList* virtualChildren() OVERRIDE { return children(); }
+ virtual const RenderObjectChildList* virtualChildren() const OVERRIDE { return children(); }
- virtual bool isSVGRoot() const { return true; }
- virtual const char* renderName() const { return "RenderSVGRoot"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGRoot"; }
+ virtual bool isSVGRoot() const OVERRIDE { return true; }
+ virtual bool isSVG() const OVERRIDE { return true; }
virtual LayoutUnit computeReplacedLogicalWidth(ShouldComputePreferred = ComputeActual) const OVERRIDE;
- virtual LayoutUnit computeReplacedLogicalHeight() const;
- virtual void layout();
- virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
+ virtual LayoutUnit computeReplacedLogicalHeight() const OVERRIDE;
+ virtual void layout() OVERRIDE;
+ virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE;
- virtual void willBeDestroyed();
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void willBeDestroyed() OVERRIDE;
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
virtual void removeChild(RenderObject*) OVERRIDE;
+ virtual bool canHaveWhitespaceChildren() const OVERRIDE { return false; }
virtual void insertedIntoTree() OVERRIDE;
virtual void willBeRemovedFromTree() OVERRIDE;
- virtual const AffineTransform& localToParentTransform() const;
+ virtual const AffineTransform& localToParentTransform() const OVERRIDE;
- virtual FloatRect objectBoundingBox() const { return m_objectBoundingBox; }
- virtual FloatRect strokeBoundingBox() const { return m_strokeBoundingBox; }
- virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
+ virtual FloatRect objectBoundingBox() const OVERRIDE { return m_objectBoundingBox; }
+ virtual FloatRect strokeBoundingBox() const OVERRIDE { return m_strokeBoundingBox; }
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const OVERRIDE { return m_repaintBoundingBox; }
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const OVERRIDE;
+ virtual LayoutRect clippedOverflowRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const OVERRIDE;
+ virtual void computeFloatRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer, FloatRect& paintInvalidationRect, bool fixed) const OVERRIDE;
virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
- virtual bool canBeSelectionLeaf() const { return false; }
- virtual bool canHaveChildren() const { return true; }
+ virtual bool canBeSelectionLeaf() const OVERRIDE { return false; }
+ virtual bool canHaveChildren() const OVERRIDE { return true; }
+ bool shouldApplyViewportClip() const;
void updateCachedBoundaries();
void buildLocalToBorderBoxTransform();
@@ -113,6 +122,7 @@ private:
AffineTransform m_localToBorderBoxTransform;
bool m_isLayoutSizeChanged : 1;
bool m_needsBoundariesOrTransformUpdate : 1;
+ bool m_hasBoxDecorations : 1;
};
DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderSVGRoot, isSVGRoot());
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.cpp
index 04298f7e49d..dfd09e70aef 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.cpp
@@ -26,17 +26,16 @@
*/
#include "config.h"
-
#include "core/rendering/svg/RenderSVGShape.h"
#include "core/rendering/GraphicsContextAnnotator.h"
#include "core/rendering/HitTestRequest.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
#include "core/rendering/PointerEventsHitRules.h"
#include "core/rendering/svg/RenderSVGResourceMarker.h"
#include "core/rendering/svg/RenderSVGResourceSolidColor.h"
#include "core/rendering/svg/SVGPathData.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/rendering/svg/SVGRenderingContext.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCache.h"
@@ -63,7 +62,7 @@ void RenderSVGShape::updateShapeFromElement()
{
m_path.clear();
m_path = adoptPtr(new Path);
- ASSERT(RenderSVGShape::isEmpty());
+ ASSERT(RenderSVGShape::isShapeEmpty());
updatePathFromGraphicsElement(toSVGGraphicsElement(element()), path());
processMarkerPositions();
@@ -72,11 +71,6 @@ void RenderSVGShape::updateShapeFromElement()
m_strokeBoundingBox = calculateStrokeBoundingBox();
}
-bool RenderSVGShape::isEmpty() const
-{
- return path().isEmpty();
-}
-
void RenderSVGShape::fillShape(GraphicsContext* context) const
{
context->fillPath(path());
@@ -119,8 +113,8 @@ bool RenderSVGShape::fillContains(const FloatPoint& point, bool requiresFill, co
if (!m_fillBoundingBox.contains(point))
return false;
- Color fallbackColor;
- if (requiresFill && !RenderSVGResource::fillPaintingResource(this, style(), fallbackColor))
+ bool hasFallback;
+ if (requiresFill && !RenderSVGResource::fillPaintingResource(this, style(), hasFallback))
return false;
return shapeDependentFillContains(point, fillRule);
@@ -131,8 +125,8 @@ bool RenderSVGShape::strokeContains(const FloatPoint& point, bool requiresStroke
if (!strokeBoundingBox().contains(point))
return false;
- Color fallbackColor;
- if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), fallbackColor))
+ bool hasFallback;
+ if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), hasFallback))
return false;
return shapeDependentStrokeContains(point);
@@ -140,7 +134,6 @@ bool RenderSVGShape::strokeContains(const FloatPoint& point, bool requiresStroke
void RenderSVGShape::layout()
{
- LayoutRectRecorder recorder(*this);
LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) && selfNeedsLayout());
bool updateCachedBoundariesInParents = false;
@@ -201,7 +194,7 @@ bool RenderSVGShape::shouldGenerateMarkerPositions() const
if (!style()->svgStyle()->hasMarkers())
return false;
- if (!toSVGGraphicsElement(element())->supportsMarkers())
+ if (!SVGResources::supportsMarkers(*toSVGGraphicsElement(element())))
return false;
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
@@ -213,13 +206,12 @@ bool RenderSVGShape::shouldGenerateMarkerPositions() const
void RenderSVGShape::fillShape(RenderStyle* style, GraphicsContext* context)
{
- Color fallbackColor;
- if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(this, style, fallbackColor)) {
- if (fillPaintingResource->applyResource(this, style, context, ApplyToFillMode))
+ bool hasFallback;
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(this, style, hasFallback)) {
+ if (fillPaintingResource->applyResource(this, style, context, ApplyToFillMode)) {
fillPaintingResource->postApplyResource(this, context, ApplyToFillMode, 0, this);
- else if (fallbackColor.isValid()) {
+ } else if (hasFallback) {
RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
- fallbackResource->setColor(fallbackColor);
if (fallbackResource->applyResource(this, style, context, ApplyToFillMode))
fallbackResource->postApplyResource(this, context, ApplyToFillMode, 0, this);
}
@@ -228,13 +220,12 @@ void RenderSVGShape::fillShape(RenderStyle* style, GraphicsContext* context)
void RenderSVGShape::strokeShape(RenderStyle* style, GraphicsContext* context)
{
- Color fallbackColor;
- if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(this, style, fallbackColor)) {
- if (strokePaintingResource->applyResource(this, style, context, ApplyToStrokeMode))
+ bool hasFallback;
+ if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(this, style, hasFallback)) {
+ if (strokePaintingResource->applyResource(this, style, context, ApplyToStrokeMode)) {
strokePaintingResource->postApplyResource(this, context, ApplyToStrokeMode, 0, this);
- else if (fallbackColor.isValid()) {
+ } else if (hasFallback) {
RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
- fallbackResource->setColor(fallbackColor);
if (fallbackResource->applyResource(this, style, context, ApplyToStrokeMode))
fallbackResource->postApplyResource(this, context, ApplyToStrokeMode, 0, this);
}
@@ -244,68 +235,67 @@ void RenderSVGShape::strokeShape(RenderStyle* style, GraphicsContext* context)
void RenderSVGShape::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
-
- if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || isEmpty())
+ if (paintInfo.context->paintingDisabled()
+ || paintInfo.phase != PaintPhaseForeground
+ || style()->visibility() == HIDDEN
+ || isShapeEmpty())
return;
- FloatRect boundingBox = repaintRectInLocalCoordinates();
+
+ FloatRect boundingBox = paintInvalidationRectInLocalCoordinates();
if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
return;
PaintInfo childPaintInfo(paintInfo);
- bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
- if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
- GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
- childPaintInfo.applyTransform(m_localTransform);
-
- if (childPaintInfo.phase == PaintPhaseForeground) {
- SVGRenderingContext renderingContext(this, childPaintInfo);
-
- if (renderingContext.isRenderingPrepared()) {
- const SVGRenderStyle* svgStyle = style()->svgStyle();
- if (svgStyle->shapeRendering() == SR_CRISPEDGES)
- childPaintInfo.context->setShouldAntialias(false);
-
- for (int i = 0; i < 3; i++) {
- switch (svgStyle->paintOrderType(i)) {
- case PT_FILL:
- fillShape(this->style(), childPaintInfo.context);
- break;
- case PT_STROKE:
- if (svgStyle->hasVisibleStroke()) {
- GraphicsContextStateSaver stateSaver(*childPaintInfo.context, false);
- AffineTransform nonScalingTransform;
-
- if (hasNonScalingStroke()) {
- AffineTransform nonScalingTransform = nonScalingStrokeTransform();
- if (!setupNonScalingStrokeContext(nonScalingTransform, stateSaver))
- return;
- }
-
- strokeShape(this->style(), childPaintInfo.context);
- }
- break;
- case PT_MARKERS:
- if (!m_markerPositions.isEmpty())
- drawMarkers(childPaintInfo);
- break;
- default:
- ASSERT_NOT_REACHED();
- break;
+
+ GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
+ childPaintInfo.applyTransform(m_localTransform);
+
+ SVGRenderingContext renderingContext(this, childPaintInfo);
+
+ if (renderingContext.isRenderingPrepared()) {
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
+ if (svgStyle->shapeRendering() == SR_CRISPEDGES)
+ childPaintInfo.context->setShouldAntialias(false);
+
+ for (int i = 0; i < 3; i++) {
+ switch (svgStyle->paintOrderType(i)) {
+ case PT_FILL:
+ fillShape(this->style(), childPaintInfo.context);
+ break;
+ case PT_STROKE:
+ if (svgStyle->hasVisibleStroke()) {
+ GraphicsContextStateSaver stateSaver(*childPaintInfo.context, false);
+ AffineTransform nonScalingTransform;
+
+ if (hasNonScalingStroke()) {
+ AffineTransform nonScalingTransform = nonScalingStrokeTransform();
+ if (!setupNonScalingStrokeContext(nonScalingTransform, stateSaver))
+ return;
}
+
+ strokeShape(this->style(), childPaintInfo.context);
}
+ break;
+ case PT_MARKERS:
+ if (!m_markerPositions.isEmpty())
+ drawMarkers(childPaintInfo);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
}
}
-
- if (drawsOutline)
- paintOutline(childPaintInfo, IntRect(boundingBox));
}
+
+ if (style()->outlineWidth())
+ paintOutline(childPaintInfo, IntRect(boundingBox));
}
// This method is called from inside paintOutline() since we call paintOutline()
// while transformed to our coord system, return local coords
void RenderSVGShape::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
{
- IntRect rect = enclosingIntRect(repaintRectInLocalCoordinates());
+ IntRect rect = enclosingIntRect(paintInvalidationRectInLocalCoordinates());
if (!rect.isEmpty())
rects.append(rect);
}
@@ -417,7 +407,7 @@ FloatRect RenderSVGShape::calculateStrokeBoundingBox() const
void RenderSVGShape::updateRepaintBoundingBox()
{
m_repaintBoundingBox = strokeBoundingBox();
- if (strokeWidth() < 1.0f)
+ if (strokeWidth() < 1.0f && !m_repaintBoundingBox.isEmpty())
m_repaintBoundingBox.inflate(1);
SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
}
@@ -425,13 +415,13 @@ void RenderSVGShape::updateRepaintBoundingBox()
float RenderSVGShape::strokeWidth() const
{
SVGLengthContext lengthContext(element());
- return style()->svgStyle()->strokeWidth().value(lengthContext);
+ return style()->svgStyle()->strokeWidth()->value(lengthContext);
}
bool RenderSVGShape::hasSmoothStroke() const
{
const SVGRenderStyle* svgStyle = style()->svgStyle();
- return svgStyle->strokeDashArray().isEmpty()
+ return svgStyle->strokeDashArray()->isEmpty()
&& svgStyle->strokeMiterLimit() == svgStyle->initialStrokeMiterLimit()
&& svgStyle->joinStyle() == svgStyle->initialJoinStyle()
&& svgStyle->capStyle() == svgStyle->initialCapStyle();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.h
index f800b2db555..12a703f063b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGShape.h
@@ -38,9 +38,6 @@ namespace WebCore {
class FloatPoint;
class GraphicsContextStateSaver;
class PointerEventsHitRules;
-class RenderSVGContainer;
-class RenderSVGPath;
-class RenderSVGResource;
class SVGGraphicsElement;
class RenderSVGShape : public RenderSVGModelObject {
@@ -51,7 +48,6 @@ public:
void setNeedsShapeUpdate() { m_needsShapeUpdate = true; }
virtual void setNeedsBoundariesUpdate() OVERRIDE FINAL { m_needsBoundariesUpdate = true; }
- virtual bool needsBoundariesUpdate() OVERRIDE FINAL { return m_needsBoundariesUpdate; }
virtual void setNeedsTransformUpdate() OVERRIDE FINAL { m_needsTransformUpdate = true; }
virtual void fillShape(GraphicsContext*) const;
virtual void strokeShape(GraphicsContext*) const;
@@ -66,7 +62,7 @@ public:
protected:
virtual void updateShapeFromElement();
- virtual bool isEmpty() const;
+ virtual bool isShapeEmpty() const { return path().isEmpty(); }
virtual bool shapeDependentStrokeContains(const FloatPoint&);
virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
float strokeWidth() const;
@@ -85,12 +81,12 @@ private:
bool fillContains(const FloatPoint&, bool requiresFill = true, const WindRule fillRule = RULE_NONZERO);
bool strokeContains(const FloatPoint&, bool requiresStroke = true);
- virtual FloatRect repaintRectInLocalCoordinates() const OVERRIDE FINAL { return m_repaintBoundingBox; }
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const OVERRIDE FINAL { return m_repaintBoundingBox; }
virtual const AffineTransform& localToParentTransform() const OVERRIDE FINAL { return m_localTransform; }
virtual AffineTransform localTransform() const OVERRIDE FINAL { return m_localTransform; }
virtual bool isSVGShape() const OVERRIDE FINAL { return true; }
- virtual const char* renderName() const { return "RenderSVGShape"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGShape"; }
virtual void layout() OVERRIDE FINAL;
virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE FINAL;
@@ -116,7 +112,6 @@ private:
private:
FloatRect m_repaintBoundingBox;
- FloatRect m_repaintBoundingBoxExcludingShadow;
AffineTransform m_localTransform;
OwnPtr<Path> m_path;
Vector<MarkerPosition> m_markerPositions;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.cpp
index 5f34538620b..30c06454d59 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.cpp
@@ -24,6 +24,9 @@
#include "core/rendering/svg/RenderSVGTSpan.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
+#include "core/svg/SVGAltGlyphElement.h"
+
namespace WebCore {
RenderSVGTSpan::RenderSVGTSpan(Element* element)
@@ -31,4 +34,20 @@ RenderSVGTSpan::RenderSVGTSpan(Element* element)
{
}
+bool RenderSVGTSpan::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ // Always allow text (except empty textnodes and <br>).
+ if (child->isText())
+ return SVGRenderSupport::isRenderableTextNode(child);
+
+#if ENABLE(SVG_FONTS)
+ // Only allow other types of children if this is not an 'altGlyph'.
+ ASSERT(node());
+ if (isSVGAltGlyphElement(*node()))
+ return false;
+#endif
+
+ return child->isSVGInline() && !child->isSVGTextPath();
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.h
index ba8cb31e1e0..7875119a34f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTSpan.h
@@ -28,7 +28,10 @@ namespace WebCore {
class RenderSVGTSpan FINAL : public RenderSVGInline {
public:
explicit RenderSVGTSpan(Element*);
- virtual const char* renderName() const { return "RenderSVGTSpan"; }
+
+ virtual bool isChildAllowed(RenderObject* child, RenderStyle*) const OVERRIDE;
+
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGTSpan"; }
};
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.cpp
index ba45ce98f18..8536029524b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.cpp
@@ -30,10 +30,11 @@
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/HitTestResult.h"
-#include "core/rendering/LayoutRectRecorder.h"
#include "core/rendering/LayoutRepainter.h"
+#include "core/rendering/PaintInfo.h"
#include "core/rendering/PointerEventsHitRules.h"
#include "core/rendering/style/ShadowList.h"
+#include "core/rendering/svg/RenderSVGInline.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/RenderSVGRoot.h"
@@ -70,7 +71,7 @@ RenderSVGText::~RenderSVGText()
bool RenderSVGText::isChildAllowed(RenderObject* child, RenderStyle*) const
{
- return child->isInline() && !SVGRenderSupport::isEmptySVGInlineText(child);
+ return child->isSVGInline() || (child->isText() && SVGRenderSupport::isRenderableTextNode(child));
}
RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(RenderObject* start)
@@ -93,33 +94,13 @@ const RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(const RenderObje
return toRenderSVGText(start);
}
-LayoutRect RenderSVGText::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
-{
- return SVGRenderSupport::clippedOverflowRectForRepaint(this, repaintContainer);
-}
-
-void RenderSVGText::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const
+void RenderSVGText::mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, bool fixed) const
{
FloatRect repaintRect = rect;
- computeFloatRectForRepaint(repaintContainer, repaintRect, fixed);
+ computeFloatRectForPaintInvalidation(paintInvalidationContainer, repaintRect, fixed);
rect = enclosingLayoutRect(repaintRect);
}
-void RenderSVGText::computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const
-{
- SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed);
-}
-
-void RenderSVGText::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
-{
- SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
-}
-
-const RenderObject* RenderSVGText::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
-{
- return SVGRenderSupport::pushMappingToContainer(this, ancestorToStopAt, geometryMap);
-}
-
static inline void collectLayoutAttributes(RenderObject* text, Vector<SVGTextLayoutAttributes*>& attributes)
{
for (RenderObject* descendant = text; descendant; descendant = descendant->nextInPreOrder(text)) {
@@ -128,14 +109,15 @@ static inline void collectLayoutAttributes(RenderObject* text, Vector<SVGTextLay
}
}
-static inline bool findPreviousAndNextAttributes(RenderObject* start, RenderSVGInlineText* locateElement, bool& stopAfterNext, SVGTextLayoutAttributes*& previous, SVGTextLayoutAttributes*& next)
+static inline bool findPreviousAndNextAttributes(RenderSVGText* root, RenderSVGInlineText* locateElement, SVGTextLayoutAttributes*& previous, SVGTextLayoutAttributes*& next)
{
- ASSERT(start);
+ ASSERT(root);
ASSERT(locateElement);
- // FIXME: Make this iterative.
- for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
- if (child->isSVGInlineText()) {
- RenderSVGInlineText* text = toRenderSVGInlineText(child);
+ bool stopAfterNext = false;
+ RenderObject* current = root->firstChild();
+ while (current) {
+ if (current->isSVGInlineText()) {
+ RenderSVGInlineText* text = toRenderSVGInlineText(current);
if (locateElement != text) {
if (stopAfterNext) {
next = text->layoutAttributes();
@@ -143,20 +125,19 @@ static inline bool findPreviousAndNextAttributes(RenderObject* start, RenderSVGI
}
previous = text->layoutAttributes();
+ } else {
+ stopAfterNext = true;
+ }
+ } else if (current->isSVGInline()) {
+ // Descend into text content (if possible).
+ if (RenderObject* child = toRenderSVGInline(current)->firstChild()) {
+ current = child;
continue;
}
-
- stopAfterNext = true;
- continue;
}
- if (!child->isSVGInline())
- continue;
-
- if (findPreviousAndNextAttributes(child, locateElement, stopAfterNext, previous, next))
- return true;
+ current = current->nextInPreOrderAfterChildren(root);
}
-
return false;
}
@@ -201,11 +182,10 @@ void RenderSVGText::subtreeChildWasAdded(RenderObject* child)
attributes = newLayoutAttributes[i];
if (m_layoutAttributes.find(attributes) == kNotFound) {
// Every time this is invoked, there's only a single new entry in the newLayoutAttributes list, compared to the old in m_layoutAttributes.
- bool stopAfterNext = false;
SVGTextLayoutAttributes* previous = 0;
SVGTextLayoutAttributes* next = 0;
ASSERT_UNUSED(child, attributes->context() == child);
- findPreviousAndNextAttributes(this, attributes->context(), stopAfterNext, previous, next);
+ findPreviousAndNextAttributes(this, attributes->context(), previous, next);
if (previous)
m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(previous->context());
@@ -258,11 +238,10 @@ void RenderSVGText::subtreeChildWillBeRemoved(RenderObject* child, Vector<SVGTex
// This logic requires that the 'text' child is still inserted in the tree.
RenderSVGInlineText* text = toRenderSVGInlineText(child);
- bool stopAfterNext = false;
SVGTextLayoutAttributes* previous = 0;
SVGTextLayoutAttributes* next = 0;
if (!documentBeingDestroyed())
- findPreviousAndNextAttributes(this, text, stopAfterNext, previous, next);
+ findPreviousAndNextAttributes(this, text, previous, next);
if (previous)
affectedAttributes.append(previous);
@@ -288,9 +267,8 @@ void RenderSVGText::subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes*
m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(affectedAttributes[i]->context());
}
-void RenderSVGText::subtreeStyleDidChange(RenderSVGInlineText* text)
+void RenderSVGText::subtreeStyleDidChange()
{
- ASSERT(text);
if (!shouldHandleSubtreeMutations() || documentBeingDestroyed())
return;
@@ -299,7 +277,7 @@ void RenderSVGText::subtreeStyleDidChange(RenderSVGInlineText* text)
// Only update the metrics cache, but not the text positioning element cache
// nor the layout attributes cached in the leaf #text renderers.
FontCachePurgePreventer fontCachePurgePreventer;
- for (RenderObject* descendant = text; descendant; descendant = descendant->nextInPreOrder(text)) {
+ for (RenderObject* descendant = firstChild(); descendant; descendant = descendant->nextInPreOrder(this)) {
if (descendant->isSVGInlineText())
m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(toRenderSVGInlineText(descendant));
}
@@ -344,7 +322,9 @@ static inline void updateFontInAllDescendants(RenderObject* start, SVGTextLayout
void RenderSVGText::layout()
{
ASSERT(needsLayout());
- LayoutRectRecorder recorder(*this);
+
+ subtreeStyleDidChange();
+
LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this));
bool updateCachedBoundariesInParents = false;
@@ -408,7 +388,16 @@ void RenderSVGText::layout()
// FIXME: We need to find a way to only layout the child boxes, if needed.
FloatRect oldBoundaries = objectBoundingBox();
ASSERT(childrenInline());
- forceLayoutInlineChildren();
+
+ rebuildFloatsFromIntruding();
+
+ LayoutUnit beforeEdge = borderBefore() + paddingBefore();
+ LayoutUnit afterEdge = borderAfter() + paddingAfter() + scrollbarLogicalHeight();
+ setLogicalHeight(beforeEdge);
+
+ LayoutUnit repaintLogicalTop = 0;
+ LayoutUnit repaintLogicalBottom = 0;
+ layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom, afterEdge);
if (m_needsReordering)
m_needsReordering = false;
@@ -430,7 +419,7 @@ void RenderSVGText::layout()
RootInlineBox* RenderSVGText::createRootInlineBox()
{
- RootInlineBox* box = new SVGRootInlineBox(this);
+ RootInlineBox* box = new SVGRootInlineBox(*this);
box->setHasVirtualLogicalHeight();
return box;
}
@@ -458,12 +447,6 @@ bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResul
return false;
}
-bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction)
-{
- ASSERT_NOT_REACHED();
- return false;
-}
-
PositionWithAffinity RenderSVGText::positionForPoint(const LayoutPoint& pointInContents)
{
RootInlineBox* rootBox = firstRootBox();
@@ -477,7 +460,7 @@ PositionWithAffinity RenderSVGText::positionForPoint(const LayoutPoint& pointInC
if (!closestBox)
return createPositionWithAffinity(0, DOWNSTREAM);
- return closestBox->renderer()->positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()));
+ return closestBox->renderer().positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()));
}
void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
@@ -491,14 +474,23 @@ void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&)
return;
if (paintInfo.phase != PaintPhaseForeground
- && paintInfo.phase != PaintPhaseSelfOutline
&& paintInfo.phase != PaintPhaseSelection)
return;
PaintInfo blockInfo(paintInfo);
- GraphicsContextStateSaver stateSaver(*blockInfo.context);
- blockInfo.applyTransform(localToParentTransform());
+ GraphicsContextStateSaver stateSaver(*blockInfo.context, false);
+ const AffineTransform& localTransform = localToParentTransform();
+ if (!localTransform.isIdentity()) {
+ stateSaver.save();
+ blockInfo.applyTransform(localTransform, false);
+ }
RenderBlock::paint(blockInfo, LayoutPoint());
+
+ // Paint the outlines, if any
+ if (paintInfo.phase == PaintPhaseForeground) {
+ blockInfo.phase = PaintPhaseSelfOutline;
+ RenderBlock::paint(blockInfo, LayoutPoint());
+ }
}
FloatRect RenderSVGText::strokeBoundingBox() const
@@ -511,11 +503,11 @@ FloatRect RenderSVGText::strokeBoundingBox() const
ASSERT(node());
ASSERT(node()->isSVGElement());
SVGLengthContext lengthContext(toSVGElement(node()));
- strokeBoundaries.inflate(svgStyle->strokeWidth().value(lengthContext));
+ strokeBoundaries.inflate(svgStyle->strokeWidth()->value(lengthContext));
return strokeBoundaries;
}
-FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
+FloatRect RenderSVGText::paintInvalidationRectInLocalCoordinates() const
{
FloatRect repaintRect = strokeBoundingBox();
SVGRenderSupport::intersectRepaintRectWithResources(this, repaintRect);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.h
index 56fb0db8e49..dfac5394a68 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGText.h
@@ -37,12 +37,12 @@ public:
explicit RenderSVGText(SVGTextElement*);
virtual ~RenderSVGText();
- virtual bool isChildAllowed(RenderObject*, RenderStyle*) const;
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
void setNeedsPositioningValuesUpdate() { m_needsPositioningValuesUpdate = true; }
- virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ virtual void setNeedsTransformUpdate() OVERRIDE { m_needsTransformUpdate = true; }
void setNeedsTextMetricsUpdate() { m_needsTextMetricsUpdate = true; }
- virtual FloatRect repaintRectInLocalCoordinates() const;
+ virtual FloatRect paintInvalidationRectInLocalCoordinates() const OVERRIDE;
static RenderSVGText* locateRenderSVGTextAncestor(RenderObject*);
static const RenderSVGText* locateRenderSVGTextAncestor(const RenderObject*);
@@ -53,42 +53,35 @@ public:
void subtreeChildWasAdded(RenderObject*);
void subtreeChildWillBeRemoved(RenderObject*, Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes);
void subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes);
- void subtreeStyleDidChange(RenderSVGInlineText*);
+ void subtreeStyleDidChange();
void subtreeTextDidChange(RenderSVGInlineText*);
private:
- virtual const char* renderName() const { return "RenderSVGText"; }
- virtual bool isSVGText() const { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGText"; }
+ virtual bool isSVGText() const OVERRIDE { return true; }
- virtual void paint(PaintInfo&, const LayoutPoint&);
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
- virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE FINAL;
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) OVERRIDE;
+ virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
- virtual bool requiresLayer() const { return false; }
- virtual void layout();
+ virtual void layout() OVERRIDE;
- virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
+ virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const OVERRIDE;
- virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
- virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
- virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE;
+ virtual void mapRectToPaintInvalidationBacking(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
- virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
virtual void removeChild(RenderObject*) OVERRIDE;
virtual void willBeDestroyed() OVERRIDE;
- virtual FloatRect objectBoundingBox() const { return frameRect(); }
- virtual FloatRect strokeBoundingBox() const;
+ virtual FloatRect objectBoundingBox() const OVERRIDE { return frameRect(); }
+ virtual FloatRect strokeBoundingBox() const OVERRIDE;
- virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
- virtual AffineTransform localTransform() const { return m_localTransform; }
- virtual RootInlineBox* createRootInlineBox();
+ virtual const AffineTransform& localToParentTransform() const OVERRIDE { return m_localTransform; }
+ virtual RootInlineBox* createRootInlineBox() OVERRIDE;
- virtual RenderBlock* firstLineBlock() const;
- virtual void updateFirstLetter();
+ virtual RenderBlock* firstLineBlock() const OVERRIDE;
+ virtual void updateFirstLetter() OVERRIDE;
bool shouldHandleSubtreeMutations() const;
@@ -96,7 +89,6 @@ private:
bool m_needsPositioningValuesUpdate : 1;
bool m_needsTransformUpdate : 1;
bool m_needsTextMetricsUpdate : 1;
- AffineTransform m_localTransform;
SVGTextLayoutAttributesBuilder m_layoutAttributesBuilder;
Vector<SVGTextLayoutAttributes*> m_layoutAttributes;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.cpp
index aec2da5ac29..f9deafa7276 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.cpp
@@ -21,8 +21,8 @@
#include "core/rendering/svg/RenderSVGTextPath.h"
-#include "SVGNames.h"
#include "core/rendering/svg/SVGPathData.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/svg/SVGPathElement.h"
#include "core/svg/SVGTextPathElement.h"
@@ -33,30 +33,45 @@ RenderSVGTextPath::RenderSVGTextPath(Element* element)
{
}
+bool RenderSVGTextPath::isChildAllowed(RenderObject* child, RenderStyle*) const
+{
+ if (child->isText())
+ return SVGRenderSupport::isRenderableTextNode(child);
+
+#if ENABLE(SVG_FONTS)
+ // 'altGlyph' is supported by the content model for 'textPath', but...
+ ASSERT(child->node());
+ if (isSVGAltGlyphElement(*child->node()))
+ return false;
+#endif
+
+ return child->isSVGInline() && !child->isSVGTextPath();
+}
+
Path RenderSVGTextPath::layoutPath() const
{
SVGTextPathElement* textPathElement = toSVGTextPathElement(node());
- Element* targetElement = SVGURIReference::targetElementFromIRIString(textPathElement->hrefCurrentValue(), textPathElement->document());
- if (!targetElement || !targetElement->hasTagName(SVGNames::pathTag))
+ Element* targetElement = SVGURIReference::targetElementFromIRIString(textPathElement->href()->currentValue()->value(), textPathElement->treeScope());
+ if (!isSVGPathElement(targetElement))
return Path();
- SVGPathElement* pathElement = toSVGPathElement(targetElement);
+ SVGPathElement& pathElement = toSVGPathElement(*targetElement);
Path pathData;
- updatePathFromGraphicsElement(pathElement, pathData);
+ updatePathFromGraphicsElement(&pathElement, pathData);
// Spec: The transform attribute on the referenced 'path' element represents a
// supplemental transformation relative to the current user coordinate system for
// the current 'text' element, including any adjustments to the current user coordinate
// system due to a possible transform attribute on the current 'text' element.
// http://www.w3.org/TR/SVG/text.html#TextPathElement
- pathData.transform(pathElement->animatedLocalTransform());
+ pathData.transform(pathElement.animatedLocalTransform());
return pathData;
}
float RenderSVGTextPath::startOffset() const
{
- return toSVGTextPathElement(node())->startOffsetCurrentValue().valueAsPercentage();
+ return toSVGTextPathElement(node())->startOffset()->currentValue()->valueAsPercentage();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.h
index 6e14b5528f6..6d98871341f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTextPath.h
@@ -32,10 +32,12 @@ public:
Path layoutPath() const;
float startOffset() const;
- virtual bool isSVGTextPath() const { return true; }
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
+
+ virtual bool isSVGTextPath() const OVERRIDE { return true; }
private:
- virtual const char* renderName() const { return "RenderSVGTextPath"; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGTextPath"; }
Path m_layoutPath;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp
index 52516c4c268..841bec55ec1 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp
@@ -23,8 +23,8 @@
#include "core/rendering/svg/RenderSVGTransformableContainer.h"
-#include "SVGNames.h"
#include "core/rendering/svg/SVGRenderSupport.h"
+#include "core/svg/SVGGElement.h"
#include "core/svg/SVGGraphicsElement.h"
#include "core/svg/SVGUseElement.h"
@@ -37,25 +37,60 @@ RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGGraphicsElem
{
}
+static bool hasValidPredecessor(const Node* node)
+{
+ ASSERT(node);
+ while ((node = node->previousSibling())) {
+ if (node->isSVGElement() && toSVGElement(node)->isValid())
+ return true;
+ }
+ return false;
+}
+
+bool RenderSVGTransformableContainer::isChildAllowed(RenderObject* child, RenderStyle* style) const
+{
+ ASSERT(element());
+ if (isSVGSwitchElement(*element())) {
+ Node* node = child->node();
+ // Reject non-SVG/non-valid elements.
+ if (!node->isSVGElement() || !toSVGElement(node)->isValid())
+ return false;
+ // Reject this child if it isn't the first valid node.
+ if (hasValidPredecessor(node))
+ return false;
+ } else if (isSVGAElement(*element())) {
+ // http://www.w3.org/2003/01/REC-SVG11-20030114-errata#linking-text-environment
+ // The 'a' element may contain any element that its parent may contain, except itself.
+ if (isSVGAElement(*child->node()))
+ return false;
+ if (parent() && parent()->isSVG())
+ return parent()->isChildAllowed(child, style);
+ }
+ return RenderSVGContainer::isChildAllowed(child, style);
+}
+
bool RenderSVGTransformableContainer::calculateLocalTransform()
{
SVGGraphicsElement* element = toSVGGraphicsElement(this->element());
+ ASSERT(element);
// If we're either the renderer for a <use> element, or for any <g> element inside the shadow
// tree, that was created during the use/symbol/svg expansion in SVGUseElement. These containers
// need to respect the translations induced by their corresponding use elements x/y attributes.
SVGUseElement* useElement = 0;
- if (element->hasTagName(SVGNames::useTag))
+ if (isSVGUseElement(*element)) {
useElement = toSVGUseElement(element);
- else if (element->isInShadowTree() && element->hasTagName(SVGNames::gTag)) {
+ } else if (isSVGGElement(*element) && toSVGGElement(element)->inUseShadowTree()) {
SVGElement* correspondingElement = element->correspondingElement();
- if (correspondingElement && correspondingElement->hasTagName(SVGNames::useTag))
+ if (isSVGUseElement(correspondingElement))
useElement = toSVGUseElement(correspondingElement);
}
if (useElement) {
SVGLengthContext lengthContext(useElement);
- FloatSize translation(useElement->xCurrentValue().value(lengthContext), useElement->yCurrentValue().value(lengthContext));
+ FloatSize translation(
+ useElement->x()->currentValue()->value(lengthContext),
+ useElement->y()->currentValue()->value(lengthContext));
if (translation != m_lastTranslation)
m_needsTransformUpdate = true;
m_lastTranslation = translation;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.h
index 6aa752aa95d..4b03d8a330d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGTransformableContainer.h
@@ -30,14 +30,16 @@ class RenderSVGTransformableContainer FINAL : public RenderSVGContainer {
public:
explicit RenderSVGTransformableContainer(SVGGraphicsElement*);
- virtual bool isSVGTransformableContainer() const { return true; }
- virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
- virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
- virtual bool didTransformToRootUpdate() { return m_didTransformToRootUpdate; }
+ virtual bool isChildAllowed(RenderObject*, RenderStyle*) const OVERRIDE;
+
+ virtual bool isSVGTransformableContainer() const OVERRIDE { return true; }
+ virtual const AffineTransform& localToParentTransform() const OVERRIDE { return m_localTransform; }
+ virtual void setNeedsTransformUpdate() OVERRIDE { m_needsTransformUpdate = true; }
+ virtual bool didTransformToRootUpdate() OVERRIDE { return m_didTransformToRootUpdate; }
private:
- virtual bool calculateLocalTransform();
- virtual AffineTransform localTransform() const { return m_localTransform; }
+ virtual bool calculateLocalTransform() OVERRIDE;
+ virtual AffineTransform localTransform() const OVERRIDE { return m_localTransform; }
bool m_needsTransformUpdate : 1;
bool m_didTransformToRootUpdate : 1;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
index 05234c18b57..4b4d3d5d4c3 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
@@ -21,11 +21,10 @@
*/
#include "config.h"
-
#include "core/rendering/svg/RenderSVGViewportContainer.h"
-#include "SVGNames.h"
-#include "core/svg/SVGElementInstance.h"
+#include "core/rendering/PaintInfo.h"
+#include "core/rendering/svg/SVGRenderSupport.h"
#include "core/svg/SVGSVGElement.h"
#include "core/svg/SVGUseElement.h"
#include "platform/graphics/GraphicsContext.h"
@@ -42,7 +41,8 @@ RenderSVGViewportContainer::RenderSVGViewportContainer(SVGElement* node)
void RenderSVGViewportContainer::determineIfLayoutSizeChanged()
{
- if (!element()->hasTagName(SVGNames::svgTag))
+ ASSERT(element());
+ if (!isSVGSVGElement(*element()))
return;
m_isLayoutSizeChanged = toSVGSVGElement(element())->hasRelativeLengths() && selfNeedsLayout();
@@ -57,59 +57,14 @@ void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
void RenderSVGViewportContainer::calcViewport()
{
SVGElement* element = this->element();
- if (!element->hasTagName(SVGNames::svgTag))
+ ASSERT(element);
+ if (!isSVGSVGElement(*element))
return;
SVGSVGElement* svg = toSVGSVGElement(element);
FloatRect oldViewport = m_viewport;
SVGLengthContext lengthContext(element);
- m_viewport = FloatRect(svg->xCurrentValue().value(lengthContext), svg->yCurrentValue().value(lengthContext), svg->widthCurrentValue().value(lengthContext), svg->heightCurrentValue().value(lengthContext));
-
- SVGElement* correspondingElement = svg->correspondingElement();
- if (correspondingElement && svg->isInShadowTree()) {
- const HashSet<SVGElementInstance*>& instances = correspondingElement->instancesForElement();
- ASSERT(!instances.isEmpty());
-
- SVGUseElement* useElement = 0;
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- const SVGElementInstance* instance = (*it);
- ASSERT(instance->correspondingElement()->hasTagName(SVGNames::svgTag) || instance->correspondingElement()->hasTagName(SVGNames::symbolTag));
- if (instance->shadowTreeElement() == svg) {
- ASSERT(correspondingElement == instance->correspondingElement());
- useElement = instance->directUseElement();
- if (!useElement)
- useElement = instance->correspondingUseElement();
- break;
- }
- }
-
- ASSERT(useElement);
- bool isSymbolElement = correspondingElement->hasTagName(SVGNames::symbolTag);
-
- // Spec (<use> on <symbol>): This generated 'svg' will always have explicit values for attributes width and height.
- // If attributes width and/or height are provided on the 'use' element, then these attributes
- // will be transferred to the generated 'svg'. If attributes width and/or height are not specified,
- // the generated 'svg' element will use values of 100% for these attributes.
-
- // Spec (<use> on <svg>): If attributes width and/or height are provided on the 'use' element, then these
- // values will override the corresponding attributes on the 'svg' in the generated tree.
-
- SVGLengthContext lengthContext(element);
- if (useElement->hasAttribute(SVGNames::widthAttr))
- m_viewport.setWidth(useElement->widthCurrentValue().value(lengthContext));
- else if (isSymbolElement && svg->hasAttribute(SVGNames::widthAttr)) {
- SVGLength containerWidth(LengthModeWidth, "100%");
- m_viewport.setWidth(containerWidth.value(lengthContext));
- }
-
- if (useElement->hasAttribute(SVGNames::heightAttr))
- m_viewport.setHeight(useElement->heightCurrentValue().value(lengthContext));
- else if (isSymbolElement && svg->hasAttribute(SVGNames::heightAttr)) {
- SVGLength containerHeight(LengthModeHeight, "100%");
- m_viewport.setHeight(containerHeight.value(lengthContext));
- }
- }
+ m_viewport = FloatRect(svg->x()->currentValue()->value(lengthContext), svg->y()->currentValue()->value(lengthContext), svg->width()->currentValue()->value(lengthContext), svg->height()->currentValue()->value(lengthContext));
if (oldViewport != m_viewport) {
setNeedsBoundariesUpdate();
@@ -130,7 +85,8 @@ bool RenderSVGViewportContainer::calculateLocalTransform()
AffineTransform RenderSVGViewportContainer::viewportTransform() const
{
- if (element()->hasTagName(SVGNames::svgTag)) {
+ ASSERT(element());
+ if (isSVGSVGElement(*element())) {
SVGSVGElement* svg = toSVGSVGElement(element());
return svg->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
}
@@ -149,11 +105,10 @@ bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& poi
void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
+ ASSERT(element());
// An empty viewBox disables rendering.
- if (element()->hasTagName(SVGNames::svgTag)) {
- if (toSVGSVGElement(element())->hasEmptyViewBox())
- return;
- }
+ if (isSVGSVGElement(*element()) && toSVGSVGElement(*element()).hasEmptyViewBox())
+ return;
RenderSVGContainer::paint(paintInfo, paintOffset);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.h b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.h
index b1b79ed5e31..679bd051dc7 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/RenderSVGViewportContainer.h
@@ -35,25 +35,25 @@ public:
FloatRect viewport() const { return m_viewport; }
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
- virtual bool didTransformToRootUpdate() { return m_didTransformToRootUpdate; }
+ virtual bool didTransformToRootUpdate() OVERRIDE { return m_didTransformToRootUpdate; }
- virtual void determineIfLayoutSizeChanged();
- virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ virtual void determineIfLayoutSizeChanged() OVERRIDE;
+ virtual void setNeedsTransformUpdate() OVERRIDE { m_needsTransformUpdate = true; }
virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
private:
- virtual bool isSVGViewportContainer() const { return true; }
- virtual const char* renderName() const { return "RenderSVGViewportContainer"; }
+ virtual bool isSVGViewportContainer() const OVERRIDE { return true; }
+ virtual const char* renderName() const OVERRIDE { return "RenderSVGViewportContainer"; }
AffineTransform viewportTransform() const;
- virtual const AffineTransform& localToParentTransform() const { return m_localToParentTransform; }
+ virtual const AffineTransform& localToParentTransform() const OVERRIDE { return m_localToParentTransform; }
- virtual void calcViewport();
- virtual bool calculateLocalTransform();
+ virtual void calcViewport() OVERRIDE;
+ virtual bool calculateLocalTransform() OVERRIDE;
- virtual void applyViewportClip(PaintInfo&);
- virtual bool pointIsInsideViewportClip(const FloatPoint& pointInParent);
+ virtual void applyViewportClip(PaintInfo&) OVERRIDE;
+ virtual bool pointIsInsideViewportClip(const FloatPoint& pointInParent) OVERRIDE;
FloatRect m_viewport;
mutable AffineTransform m_localToParentTransform;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.cpp
index c4f5cdb1203..d4a861c3db2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.cpp
@@ -23,8 +23,6 @@
#include "config.h"
#include "core/rendering/svg/SVGInlineFlowBox.h"
-#include "core/dom/DocumentMarkerController.h"
-#include "core/dom/RenderedDocumentMarker.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
#include "core/rendering/svg/SVGInlineTextBox.h"
#include "core/rendering/svg/SVGRenderingContext.h"
@@ -47,22 +45,15 @@ void SVGInlineFlowBox::paintSelectionBackground(PaintInfo& paintInfo)
}
}
-void SVGInlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
+void SVGInlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
{
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
ASSERT(!paintInfo.context->paintingDisabled());
- RenderObject* boxRenderer = renderer();
- ASSERT(boxRenderer);
-
- SVGRenderingContext renderingContext(boxRenderer, paintInfo, SVGRenderingContext::SaveGraphicsContext);
+ SVGRenderingContext renderingContext(&renderer(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
if (renderingContext.isRenderingPrepared()) {
- for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
- if (child->isSVGInlineTextBox())
- computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(toSVGInlineTextBox(child)->textRenderer()));
-
- child->paint(paintInfo, LayoutPoint(), 0, 0);
- }
+ for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
+ child->paint(paintInfo, paintOffset, 0, 0);
}
}
@@ -77,66 +68,4 @@ FloatRect SVGInlineFlowBox::calculateBoundaries() const
return childRect;
}
-void SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(RenderSVGInlineText* textRenderer)
-{
- ASSERT(textRenderer);
-
- Node* node = textRenderer->node();
- if (!node || !node->inDocument())
- return;
-
- RenderStyle* style = textRenderer->style();
- ASSERT(style);
-
- AffineTransform fragmentTransform;
- Document& document = textRenderer->document();
- Vector<DocumentMarker*> markers = document.markers()->markersFor(textRenderer->node());
-
- Vector<DocumentMarker*>::iterator markerEnd = markers.end();
- for (Vector<DocumentMarker*>::iterator markerIt = markers.begin(); markerIt != markerEnd; ++markerIt) {
- DocumentMarker* marker = *markerIt;
-
- // SVG is only interessted in the TextMatch marker, for now.
- if (marker->type() != DocumentMarker::TextMatch)
- continue;
-
- FloatRect markerRect;
- for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (!box->isSVGInlineTextBox())
- continue;
-
- SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
-
- int markerStartPosition = max<int>(marker->startOffset() - textBox->start(), 0);
- int markerEndPosition = min<int>(marker->endOffset() - textBox->start(), textBox->len());
-
- if (markerStartPosition >= markerEndPosition)
- continue;
-
- int fragmentStartPosition = 0;
- int fragmentEndPosition = 0;
-
- const Vector<SVGTextFragment>& fragments = textBox->textFragments();
- unsigned textFragmentsSize = fragments.size();
- for (unsigned i = 0; i < textFragmentsSize; ++i) {
- const SVGTextFragment& fragment = fragments.at(i);
-
- fragmentStartPosition = markerStartPosition;
- fragmentEndPosition = markerEndPosition;
- if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
- continue;
-
- FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
- fragment.buildFragmentTransform(fragmentTransform);
- if (!fragmentTransform.isIdentity())
- fragmentRect = fragmentTransform.mapRect(fragmentRect);
-
- markerRect.unite(fragmentRect);
- }
- }
-
- toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
- }
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.h
index e76a9ccdafc..0d66044e42b 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineFlowBox.h
@@ -25,26 +25,22 @@
namespace WebCore {
-class RenderSVGInlineText;
-
class SVGInlineFlowBox FINAL : public InlineFlowBox {
public:
- SVGInlineFlowBox(RenderObject* obj)
+ SVGInlineFlowBox(RenderObject& obj)
: InlineFlowBox(obj)
, m_logicalHeight(0)
{
}
- virtual bool isSVGInlineFlowBox() const { return true; }
- virtual float virtualLogicalHeight() const { return m_logicalHeight; }
+ virtual bool isSVGInlineFlowBox() const OVERRIDE { return true; }
+ virtual float virtualLogicalHeight() const OVERRIDE { return m_logicalHeight; }
void setLogicalHeight(float h) { m_logicalHeight = h; }
void paintSelectionBackground(PaintInfo&);
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
-
- virtual FloatRect calculateBoundaries() const;
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
- static void computeTextMatchMarkerRectForRenderer(RenderSVGInlineText*);
+ virtual FloatRect calculateBoundaries() const OVERRIDE;
private:
float m_logicalHeight;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.cpp
index 6c593827328..a5dc2fc742c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.cpp
@@ -22,11 +22,17 @@
#include "config.h"
#include "core/rendering/svg/SVGInlineTextBox.h"
-#include "core/frame/Frame.h"
+#include "core/dom/DocumentMarkerController.h"
+#include "core/dom/RenderedDocumentMarker.h"
+#include "core/editing/Editor.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/HitTestResult.h"
#include "core/rendering/InlineFlowBox.h"
+#include "core/rendering/PaintInfo.h"
#include "core/rendering/PointerEventsHitRules.h"
+#include "core/rendering/RenderInline.h"
+#include "core/rendering/RenderTheme.h"
#include "core/rendering/style/ShadowList.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
#include "core/rendering/svg/RenderSVGResource.h"
@@ -35,7 +41,7 @@
#include "core/rendering/svg/SVGTextRunRenderingContext.h"
#include "platform/FloatConversion.h"
#include "platform/fonts/FontCache.h"
-#include "platform/graphics/DrawLooper.h"
+#include "platform/graphics/DrawLooperBuilder.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
using namespace std;
@@ -44,17 +50,16 @@ namespace WebCore {
struct ExpectedSVGInlineTextBoxSize : public InlineTextBox {
float float1;
- uint32_t bitfields : 5;
+ uint32_t bitfields : 1;
void* pointer;
Vector<SVGTextFragment> vector;
};
COMPILE_ASSERT(sizeof(SVGInlineTextBox) == sizeof(ExpectedSVGInlineTextBoxSize), SVGInlineTextBox_is_not_of_expected_size);
-SVGInlineTextBox::SVGInlineTextBox(RenderObject* object)
+SVGInlineTextBox::SVGInlineTextBox(RenderObject& object)
: InlineTextBox(object)
, m_logicalHeight(0)
- , m_paintingResourceMode(ApplyToDefaultMode)
, m_startsNewTextChunk(false)
, m_paintingResource(0)
{
@@ -84,13 +89,12 @@ int SVGInlineTextBox::offsetForPosition(float, bool) const
int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragment, float position, bool includePartialGlyphs) const
{
- RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
- ASSERT(textRenderer);
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
- float scalingFactor = textRenderer->scalingFactor();
+ float scalingFactor = textRenderer.scalingFactor();
ASSERT(scalingFactor);
- RenderStyle* style = textRenderer->style();
+ RenderStyle* style = textRenderer.style();
ASSERT(style);
TextRun textRun = constructTextRun(style, fragment);
@@ -102,7 +106,7 @@ int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragmen
if (!fragmentTransform.isIdentity())
textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragmentTransform.xScale()));
- return fragment.characterOffset - start() + textRenderer->scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
+ return fragment.characterOffset - start() + textRenderer.scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
}
float SVGInlineTextBox::positionForOffset(int) const
@@ -119,13 +123,12 @@ FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
FontCachePurgePreventer fontCachePurgePreventer;
- RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
- ASSERT(textRenderer);
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
- float scalingFactor = textRenderer->scalingFactor();
+ float scalingFactor = textRenderer.scalingFactor();
ASSERT(scalingFactor);
- const Font& scaledFont = textRenderer->scaledFont();
+ const Font& scaledFont = textRenderer.scaledFont();
const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
FloatPoint textOrigin(fragment.x, fragment.y);
if (scalingFactor != 1)
@@ -149,10 +152,7 @@ LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
if (startPosition >= endPosition)
return LayoutRect();
- RenderText* text = textRenderer();
- ASSERT(text);
-
- RenderStyle* style = text->style();
+ RenderStyle* style = textRenderer().style();
ASSERT(style);
AffineTransform fragmentTransform;
@@ -171,8 +171,7 @@ LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
FloatRect fragmentRect = selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
fragment.buildFragmentTransform(fragmentTransform);
- if (!fragmentTransform.isIdentity())
- fragmentRect = fragmentTransform.mapRect(fragmentRect);
+ fragmentRect = fragmentTransform.mapRect(fragmentRect);
selectionRect.unite(fragmentRect);
}
@@ -180,25 +179,24 @@ LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
return enclosingIntRect(selectionRect);
}
-static inline bool textShouldBePainted(RenderSVGInlineText* textRenderer)
+static inline bool textShouldBePainted(RenderSVGInlineText& textRenderer)
{
// Font::pixelSize(), returns FontDescription::computedPixelSize(), which returns "int(x + 0.5)".
// If the absolute font size on screen is below x=0.5, don't render anything.
- return textRenderer->scaledFont().pixelSize();
+ return textRenderer.scaledFont().fontDescription().computedPixelSize();
}
void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
{
- ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
+ ASSERT(paintInfo.shouldPaintWithinRoot(&renderer()));
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
ASSERT(truncation() == cNoTruncation);
- if (renderer()->style()->visibility() != VISIBLE)
+ if (renderer().style()->visibility() != VISIBLE)
return;
- RenderObject* parentRenderer = parent()->renderer();
- ASSERT(parentRenderer);
- ASSERT(!parentRenderer->document().printing());
+ RenderObject& parentRenderer = parent()->renderer();
+ ASSERT(!parentRenderer.document().printing());
// Determine whether or not we're selected.
bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection;
@@ -206,25 +204,17 @@ void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
if (!hasSelection || paintSelectedTextOnly)
return;
- Color backgroundColor = renderer()->selectionBackgroundColor();
- if (!backgroundColor.isValid() || !backgroundColor.alpha())
+ Color backgroundColor = renderer().selectionBackgroundColor();
+ if (!backgroundColor.alpha())
return;
- RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
- ASSERT(textRenderer);
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
if (!textShouldBePainted(textRenderer))
return;
- RenderStyle* style = parentRenderer->style();
+ RenderStyle* style = parentRenderer.style();
ASSERT(style);
- RenderStyle* selectionStyle = style;
- if (hasSelection) {
- selectionStyle = parentRenderer->getCachedPseudoStyle(SELECTION);
- if (!selectionStyle)
- selectionStyle = style;
- }
-
int startPosition, endPosition;
selectionStartEnd(startPosition, endPosition);
@@ -248,41 +238,39 @@ void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
paintInfo.context->setFillColor(backgroundColor);
paintInfo.context->fillRect(selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style), backgroundColor);
-
- m_paintingResourceMode = ApplyToDefaultMode;
}
ASSERT(!m_paintingResource);
}
-void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
+void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
{
- ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
+ ASSERT(paintInfo.shouldPaintWithinRoot(&renderer()));
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
ASSERT(truncation() == cNoTruncation);
- if (renderer()->style()->visibility() != VISIBLE)
+ if (renderer().style()->visibility() != VISIBLE)
return;
// Note: We're explicitely not supporting composition & custom underlines and custom highlighters - unlike InlineTextBox.
// If we ever need that for SVG, it's very easy to refactor and reuse the code.
- RenderObject* parentRenderer = parent()->renderer();
- ASSERT(parentRenderer);
+ RenderObject& parentRenderer = parent()->renderer();
bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection;
- bool hasSelection = !parentRenderer->document().printing() && selectionState() != RenderObject::SelectionNone;
+ bool hasSelection = !parentRenderer.document().printing() && selectionState() != RenderObject::SelectionNone;
if (!hasSelection && paintSelectedTextOnly)
return;
- RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
- ASSERT(textRenderer);
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
if (!textShouldBePainted(textRenderer))
return;
- RenderStyle* style = parentRenderer->style();
+ RenderStyle* style = parentRenderer.style();
ASSERT(style);
+ paintDocumentMarkers(paintInfo.context, paintOffset, style, textRenderer.scaledFont(), true);
+
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
@@ -291,7 +279,7 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
RenderStyle* selectionStyle = style;
if (hasSelection) {
- selectionStyle = parentRenderer->getCachedPseudoStyle(SELECTION);
+ selectionStyle = parentRenderer.getCachedPseudoStyle(SELECTION);
if (selectionStyle) {
const SVGRenderStyle* svgSelectionStyle = selectionStyle->svgStyle();
ASSERT(svgSelectionStyle);
@@ -300,11 +288,12 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
hasFill = svgSelectionStyle->hasFill();
if (!hasVisibleStroke)
hasVisibleStroke = svgSelectionStyle->hasVisibleStroke();
- } else
+ } else {
selectionStyle = style;
+ }
}
- if (textRenderer->frame() && textRenderer->frame()->view() && textRenderer->frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask) {
+ if (textRenderer.frame() && textRenderer.frame()->view() && textRenderer.frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask) {
hasFill = true;
hasVisibleStroke = false;
}
@@ -315,10 +304,12 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
SVGTextFragment& fragment = m_textFragments.at(i);
ASSERT(!m_paintingResource);
- GraphicsContextStateSaver stateSaver(*paintInfo.context);
+ GraphicsContextStateSaver stateSaver(*paintInfo.context, false);
fragment.buildFragmentTransform(fragmentTransform);
- if (!fragmentTransform.isIdentity())
+ if (!fragmentTransform.isIdentity()) {
+ stateSaver.save();
paintInfo.context->concatCTM(fragmentTransform);
+ }
// Spec: All text decorations except line-through should be drawn before the text is filled and stroked; thus, the text is rendered on top of these decorations.
unsigned decorations = style->textDecorationsInEffect();
@@ -332,15 +323,15 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
case PT_FILL:
// Fill text
if (hasFill) {
- m_paintingResourceMode = ApplyToFillMode | ApplyToTextMode;
- paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
+ paintText(paintInfo.context, style, selectionStyle, fragment,
+ ApplyToFillMode | ApplyToTextMode, hasSelection, paintSelectedTextOnly);
}
break;
case PT_STROKE:
// Stroke text
if (hasVisibleStroke) {
- m_paintingResourceMode = ApplyToStrokeMode | ApplyToTextMode;
- paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
+ paintText(paintInfo.context, style, selectionStyle, fragment,
+ ApplyToStrokeMode | ApplyToTextMode, hasSelection, paintSelectedTextOnly);
}
break;
case PT_MARKERS:
@@ -355,25 +346,29 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
// Spec: Line-through should be drawn after the text is filled and stroked; thus, the line-through is rendered on top of the text.
if (decorations & TextDecorationLineThrough)
paintDecoration(paintInfo.context, TextDecorationLineThrough, fragment);
-
- m_paintingResourceMode = ApplyToDefaultMode;
}
+ // finally, paint the outline if any
+ if (style->hasOutline() && parentRenderer.isRenderInline())
+ toRenderInline(parentRenderer).paintOutline(paintInfo, paintOffset);
+
ASSERT(!m_paintingResource);
}
-bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, float scalingFactor, RenderObject* renderer, RenderStyle* style)
+bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, float scalingFactor,
+ RenderObject* renderer, RenderStyle* style, RenderSVGResourceModeFlags resourceMode)
{
+ // Callers must save the context state before calling when scalingFactor is not 1.
ASSERT(scalingFactor);
ASSERT(renderer);
ASSERT(style);
- ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
+ ASSERT(resourceMode != ApplyToDefaultMode);
- Color fallbackColor;
- if (m_paintingResourceMode & ApplyToFillMode)
- m_paintingResource = RenderSVGResource::fillPaintingResource(renderer, style, fallbackColor);
- else if (m_paintingResourceMode & ApplyToStrokeMode)
- m_paintingResource = RenderSVGResource::strokePaintingResource(renderer, style, fallbackColor);
+ bool hasFallback = false;
+ if (resourceMode & ApplyToFillMode)
+ m_paintingResource = RenderSVGResource::fillPaintingResource(renderer, style, hasFallback);
+ else if (resourceMode & ApplyToStrokeMode)
+ m_paintingResource = RenderSVGResource::strokePaintingResource(renderer, style, hasFallback);
else {
// We're either called for stroking or filling.
ASSERT_NOT_REACHED();
@@ -382,36 +377,32 @@ bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, float
if (!m_paintingResource)
return false;
- if (!m_paintingResource->applyResource(renderer, style, context, m_paintingResourceMode)) {
- if (fallbackColor.isValid()) {
- RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
- fallbackResource->setColor(fallbackColor);
-
- m_paintingResource = fallbackResource;
- m_paintingResource->applyResource(renderer, style, context, m_paintingResourceMode);
+ if (!m_paintingResource->applyResource(renderer, style, context, resourceMode)) {
+ if (hasFallback) {
+ m_paintingResource = RenderSVGResource::sharedSolidPaintingResource();
+ m_paintingResource->applyResource(renderer, style, context, resourceMode);
}
}
- if (scalingFactor != 1 && m_paintingResourceMode & ApplyToStrokeMode)
+ if (scalingFactor != 1 && resourceMode & ApplyToStrokeMode)
context->setStrokeThickness(context->strokeThickness() * scalingFactor);
return true;
}
-void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context, const Path* path)
+void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context, const Path* path,
+ RenderSVGResourceModeFlags resourceMode)
{
ASSERT(m_paintingResource);
- RenderObject* parentRenderer = parent()->renderer();
- ASSERT(parentRenderer);
-
- m_paintingResource->postApplyResource(parentRenderer, context, m_paintingResourceMode, path, /*RenderSVGShape*/ 0);
+ m_paintingResource->postApplyResource(&parent()->renderer(), context, resourceMode, path, 0);
m_paintingResource = 0;
}
-bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, float scalingFactor, TextRun& textRun, RenderStyle* style)
+bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context,
+ float scalingFactor, TextRun& textRun, RenderStyle* style, RenderSVGResourceModeFlags resourceMode)
{
- bool acquiredResource = acquirePaintingResource(context, scalingFactor, parent()->renderer(), style);
+ bool acquiredResource = acquirePaintingResource(context, scalingFactor, &parent()->renderer(), style, resourceMode);
if (!acquiredResource)
return false;
@@ -425,9 +416,10 @@ bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& c
return true;
}
-void SVGInlineTextBox::restoreGraphicsContextAfterTextPainting(GraphicsContext*& context, TextRun& textRun)
+void SVGInlineTextBox::restoreGraphicsContextAfterTextPainting(GraphicsContext*& context,
+ TextRun& textRun, RenderSVGResourceModeFlags resourceMode)
{
- releasePaintingResource(context, /* path */0);
+ releasePaintingResource(context, 0, resourceMode);
#if ENABLE(SVG_FONTS)
TextRun::RenderingContext* renderingContext = textRun.renderingContext();
@@ -439,10 +431,8 @@ void SVGInlineTextBox::restoreGraphicsContextAfterTextPainting(GraphicsContext*&
TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFragment& fragment) const
{
ASSERT(style);
- ASSERT(textRenderer());
- RenderText* text = textRenderer();
- ASSERT(text);
+ RenderText* text = &textRenderer();
// FIXME(crbug.com/264211): This should not be necessary but can occur if we
// layout during layout. Remove this when 264211 is fixed.
@@ -523,7 +513,7 @@ static inline float thicknessForDecoration(TextDecoration, const Font& font)
{
// FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified.
// Compatible with Batik/Opera
- return font.size() / 20.0f;
+ return font.fontDescription().computedSize() / 20.0f;
}
static inline RenderObject* findRenderObjectDefininingTextDecoration(InlineFlowBox* parentBox)
@@ -531,7 +521,7 @@ static inline RenderObject* findRenderObjectDefininingTextDecoration(InlineFlowB
// Lookup first render object in parent hierarchy which has text-decoration set.
RenderObject* renderer = 0;
while (parentBox) {
- renderer = parentBox->renderer();
+ renderer = &parentBox->renderer();
if (renderer->style() && renderer->style()->textDecoration() != TextDecorationNone)
break;
@@ -545,7 +535,7 @@ static inline RenderObject* findRenderObjectDefininingTextDecoration(InlineFlowB
void SVGInlineTextBox::paintDecoration(GraphicsContext* context, TextDecoration decoration, const SVGTextFragment& fragment)
{
- if (textRenderer()->style()->textDecorationsInEffect() == TextDecorationNone)
+ if (textRenderer().style()->textDecorationsInEffect() == TextDecorationNone)
return;
// Find out which render style defined the text-decoration, as its fill/stroke properties have to be used for drawing instead of ours.
@@ -559,24 +549,29 @@ void SVGInlineTextBox::paintDecoration(GraphicsContext* context, TextDecoration
const SVGRenderStyle* svgDecorationStyle = decorationStyle->svgStyle();
ASSERT(svgDecorationStyle);
- bool hasDecorationFill = svgDecorationStyle->hasFill();
- bool hasVisibleDecorationStroke = svgDecorationStyle->hasVisibleStroke();
-
- if (hasDecorationFill) {
- m_paintingResourceMode = ApplyToFillMode;
- paintDecorationWithStyle(context, decoration, fragment, decorationRenderer);
- }
-
- if (hasVisibleDecorationStroke) {
- m_paintingResourceMode = ApplyToStrokeMode;
- paintDecorationWithStyle(context, decoration, fragment, decorationRenderer);
+ for (int i = 0; i < 3; i++) {
+ switch (svgDecorationStyle->paintOrderType(i)) {
+ case PT_FILL:
+ if (svgDecorationStyle->hasFill())
+ paintDecorationWithStyle(context, decoration, fragment, decorationRenderer, ApplyToFillMode);
+ break;
+ case PT_STROKE:
+ if (svgDecorationStyle->hasVisibleStroke())
+ paintDecorationWithStyle(context, decoration, fragment, decorationRenderer, ApplyToStrokeMode);
+ break;
+ case PT_MARKERS:
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
}
}
-void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, TextDecoration decoration, const SVGTextFragment& fragment, RenderObject* decorationRenderer)
+void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, TextDecoration decoration,
+ const SVGTextFragment& fragment, RenderObject* decorationRenderer, RenderSVGResourceModeFlags resourceMode)
{
ASSERT(!m_paintingResource);
- ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
+ ASSERT(resourceMode != ApplyToDefaultMode);
RenderStyle* decorationStyle = decorationRenderer->style();
ASSERT(decorationStyle);
@@ -596,11 +591,12 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, TextDe
float width = fragment.width;
const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
- GraphicsContextStateSaver stateSaver(*context);
+ GraphicsContextStateSaver stateSaver(*context, false);
if (scalingFactor != 1) {
+ stateSaver.save();
width *= scalingFactor;
decorationOrigin.scale(scalingFactor, scalingFactor);
- context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+ context->scale(1 / scalingFactor, 1 / scalingFactor);
}
decorationOrigin.move(0, -scaledFontMetrics.floatAscent() + positionOffsetForDecoration(decoration, scaledFontMetrics, thickness));
@@ -608,19 +604,22 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, TextDe
Path path;
path.addRect(FloatRect(decorationOrigin, FloatSize(width, thickness)));
- if (acquirePaintingResource(context, scalingFactor, decorationRenderer, decorationStyle))
- releasePaintingResource(context, &path);
+ // acquirePaintingResource also modifies state if the scalingFactor is non-identity.
+ // Above we have saved the state for this case.
+ if (acquirePaintingResource(context, scalingFactor, decorationRenderer, decorationStyle, resourceMode))
+ releasePaintingResource(context, &path, resourceMode);
}
-void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyle* style, TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int endPosition)
+void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyle* style,
+ TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int endPosition,
+ RenderSVGResourceModeFlags resourceMode)
{
- RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
- ASSERT(textRenderer);
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
- float scalingFactor = textRenderer->scalingFactor();
+ float scalingFactor = textRenderer.scalingFactor();
ASSERT(scalingFactor);
- const Font& scaledFont = textRenderer->scaledFont();
+ const Font& scaledFont = textRenderer.scaledFont();
const ShadowList* shadowList = style->textShadow();
// Text shadows are disabled when printing. http://crbug.com/258321
@@ -633,28 +632,28 @@ void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
textOrigin.scale(scalingFactor, scalingFactor);
textSize.scale(scalingFactor);
context->save();
- context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+ context->scale(1 / scalingFactor, 1 / scalingFactor);
}
if (hasShadow) {
- DrawLooper drawLooper;
+ OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
for (size_t i = shadowList->shadows().size(); i--; ) {
const ShadowData& shadow = shadowList->shadows()[i];
FloatSize offset(shadow.x(), shadow.y());
- drawLooper.addShadow(offset, shadow.blur(), shadow.color(),
- DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowRespectsAlpha);
+ drawLooperBuilder->addShadow(offset, shadow.blur(), shadow.color(),
+ DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowRespectsAlpha);
}
- drawLooper.addUnmodifiedContent();
- context->setDrawLooper(drawLooper);
+ drawLooperBuilder->addUnmodifiedContent();
+ context->setDrawLooper(drawLooperBuilder.release());
}
- if (prepareGraphicsContextForTextPainting(context, scalingFactor, textRun, style)) {
+ if (prepareGraphicsContextForTextPainting(context, scalingFactor, textRun, style, resourceMode)) {
TextRunPaintInfo textRunPaintInfo(textRun);
textRunPaintInfo.from = startPosition;
textRunPaintInfo.to = endPosition;
textRunPaintInfo.bounds = FloatRect(textOrigin, textSize);
scaledFont.drawText(context, textRunPaintInfo, textOrigin);
- restoreGraphicsContextAfterTextPainting(context, textRun);
+ restoreGraphicsContextAfterTextPainting(context, textRun, resourceMode);
}
if (scalingFactor != 1)
@@ -663,7 +662,9 @@ void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
context->clearShadow();
}
-void SVGInlineTextBox::paintText(GraphicsContext* context, RenderStyle* style, RenderStyle* selectionStyle, const SVGTextFragment& fragment, bool hasSelection, bool paintSelectedTextOnly)
+void SVGInlineTextBox::paintText(GraphicsContext* context, RenderStyle* style,
+ RenderStyle* selectionStyle, const SVGTextFragment& fragment,
+ RenderSVGResourceModeFlags resourceMode, bool hasSelection, bool paintSelectedTextOnly)
{
ASSERT(style);
ASSERT(selectionStyle);
@@ -678,40 +679,104 @@ void SVGInlineTextBox::paintText(GraphicsContext* context, RenderStyle* style, R
// Fast path if there is no selection, just draw the whole chunk part using the regular style
TextRun textRun = constructTextRun(style, fragment);
if (!hasSelection || startPosition >= endPosition) {
- paintTextWithShadows(context, style, textRun, fragment, 0, fragment.length);
+ paintTextWithShadows(context, style, textRun, fragment, 0, fragment.length, resourceMode);
return;
}
// Eventually draw text using regular style until the start position of the selection
if (startPosition > 0 && !paintSelectedTextOnly)
- paintTextWithShadows(context, style, textRun, fragment, 0, startPosition);
+ paintTextWithShadows(context, style, textRun, fragment, 0, startPosition, resourceMode);
// Draw text using selection style from the start to the end position of the selection
- if (style != selectionStyle)
- SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, selectionStyle);
+ if (style != selectionStyle) {
+ StyleDifference diff;
+ diff.setNeedsRepaintObject();
+ SVGResourcesCache::clientStyleChanged(&parent()->renderer(), diff, selectionStyle);
+ }
- TextRun selectionTextRun = constructTextRun(selectionStyle, fragment);
- paintTextWithShadows(context, selectionStyle, textRun, fragment, startPosition, endPosition);
+ paintTextWithShadows(context, selectionStyle, textRun, fragment, startPosition, endPosition, resourceMode);
- if (style != selectionStyle)
- SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, style);
+ if (style != selectionStyle) {
+ StyleDifference diff;
+ diff.setNeedsRepaintObject();
+ SVGResourcesCache::clientStyleChanged(&parent()->renderer(), diff, selectionStyle);
+ }
// Eventually draw text using regular style from the end position of the selection to the end of the current chunk part
if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnly)
- paintTextWithShadows(context, style, textRun, fragment, endPosition, fragment.length);
+ paintTextWithShadows(context, style, textRun, fragment, endPosition, fragment.length, resourceMode);
+}
+
+void SVGInlineTextBox::paintDocumentMarker(GraphicsContext*, const FloatPoint&, DocumentMarker*, RenderStyle*, const Font&, bool)
+{
+ // SVG does not have support for generic document markers (e.g., spellchecking, etc).
+}
+
+void SVGInlineTextBox::paintTextMatchMarker(GraphicsContext* context, const FloatPoint&, DocumentMarker* marker, RenderStyle* style, const Font& font)
+{
+ // SVG is only interested in the TextMatch markers.
+ if (marker->type() != DocumentMarker::TextMatch)
+ return;
+
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
+
+ FloatRect markerRect;
+ AffineTransform fragmentTransform;
+ for (InlineTextBox* box = textRenderer.firstTextBox(); box; box = box->nextTextBox()) {
+ if (!box->isSVGInlineTextBox())
+ continue;
+
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
+
+ int markerStartPosition = max<int>(marker->startOffset() - textBox->start(), 0);
+ int markerEndPosition = min<int>(marker->endOffset() - textBox->start(), textBox->len());
+
+ if (markerStartPosition >= markerEndPosition)
+ continue;
+
+ const Vector<SVGTextFragment>& fragments = textBox->textFragments();
+ unsigned textFragmentsSize = fragments.size();
+ for (unsigned i = 0; i < textFragmentsSize; ++i) {
+ const SVGTextFragment& fragment = fragments.at(i);
+
+ int fragmentStartPosition = markerStartPosition;
+ int fragmentEndPosition = markerEndPosition;
+ if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
+ continue;
+
+ FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
+ fragment.buildFragmentTransform(fragmentTransform);
+
+ // Draw the marker highlight.
+ if (renderer().frame()->editor().markedTextMatchesAreHighlighted()) {
+ Color color = marker->activeMatch() ?
+ RenderTheme::theme().platformActiveTextSearchHighlightColor() :
+ RenderTheme::theme().platformInactiveTextSearchHighlightColor();
+ GraphicsContextStateSaver stateSaver(*context);
+ if (!fragmentTransform.isIdentity())
+ context->concatCTM(fragmentTransform);
+ context->setFillColor(color);
+ context->fillRect(fragmentRect, color);
+ }
+
+ fragmentRect = fragmentTransform.mapRect(fragmentRect);
+ markerRect.unite(fragmentRect);
+ }
+ }
+
+ toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer.localToAbsoluteQuad(markerRect).enclosingBoundingBox());
}
FloatRect SVGInlineTextBox::calculateBoundaries() const
{
FloatRect textRect;
- RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
- ASSERT(textRenderer);
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
- float scalingFactor = textRenderer->scalingFactor();
+ float scalingFactor = textRenderer.scalingFactor();
ASSERT(scalingFactor);
- float baseline = textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor;
+ float baseline = textRenderer.scaledFont().fontMetrics().floatAscent() / scalingFactor;
AffineTransform fragmentTransform;
unsigned textFragmentsSize = m_textFragments.size();
@@ -719,8 +784,7 @@ FloatRect SVGInlineTextBox::calculateBoundaries() const
const SVGTextFragment& fragment = m_textFragments.at(i);
FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
fragment.buildFragmentTransform(fragmentTransform);
- if (!fragmentTransform.isIdentity())
- fragmentRect = fragmentTransform.mapRect(fragmentRect);
+ fragmentRect = fragmentTransform.mapRect(fragmentRect);
textRect.unite(fragmentRect);
}
@@ -733,18 +797,18 @@ bool SVGInlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult&
// FIXME: integrate with InlineTextBox::nodeAtPoint better.
ASSERT(!isLineBreak());
- PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, renderer()->style()->pointerEvents());
- bool isVisible = renderer()->style()->visibility() == VISIBLE;
+ PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, renderer().style()->pointerEvents());
+ bool isVisible = renderer().style()->visibility() == VISIBLE;
if (isVisible || !hitRules.requireVisible) {
if (hitRules.canHitBoundingBox
- || (hitRules.canHitStroke && (renderer()->style()->svgStyle()->hasStroke() || !hitRules.requireStroke))
- || (hitRules.canHitFill && (renderer()->style()->svgStyle()->hasFill() || !hitRules.requireFill))) {
+ || (hitRules.canHitStroke && (renderer().style()->svgStyle()->hasStroke() || !hitRules.requireStroke))
+ || (hitRules.canHitFill && (renderer().style()->svgStyle()->hasFill() || !hitRules.requireFill))) {
FloatPoint boxOrigin(x(), y());
boxOrigin.moveBy(accumulatedOffset);
FloatRect rect(boxOrigin, size());
if (locationInContainer.intersects(rect)) {
- renderer()->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
- if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, locationInContainer, rect))
+ renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
+ if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, rect))
return true;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.h
index ccec860b863..2a5cb1bcd0e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGInlineTextBox.h
@@ -23,38 +23,38 @@
#define SVGInlineTextBox_h
#include "core/rendering/InlineTextBox.h"
+#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/SVGTextLayoutEngine.h"
namespace WebCore {
class RenderSVGResource;
-class SVGRootInlineBox;
class SVGInlineTextBox FINAL : public InlineTextBox {
public:
- SVGInlineTextBox(RenderObject*);
+ SVGInlineTextBox(RenderObject&);
- virtual bool isSVGInlineTextBox() const { return true; }
+ virtual bool isSVGInlineTextBox() const OVERRIDE { return true; }
- virtual float virtualLogicalHeight() const { return m_logicalHeight; }
+ virtual float virtualLogicalHeight() const OVERRIDE { return m_logicalHeight; }
void setLogicalHeight(float height) { m_logicalHeight = height; }
- virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
- virtual float positionForOffset(int offset) const;
+ virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const OVERRIDE;
+ virtual float positionForOffset(int offset) const OVERRIDE;
void paintSelectionBackground(PaintInfo&);
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
- virtual LayoutRect localSelectionRect(int startPosition, int endPosition);
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
+ virtual LayoutRect localSelectionRect(int startPosition, int endPosition) OVERRIDE;
bool mapStartEndPositionsIntoFragmentCoordinates(const SVGTextFragment&, int& startPosition, int& endPosition) const;
- virtual FloatRect calculateBoundaries() const;
+ virtual FloatRect calculateBoundaries() const OVERRIDE;
void clearTextFragments() { m_textFragments.clear(); }
Vector<SVGTextFragment>& textFragments() { return m_textFragments; }
const Vector<SVGTextFragment>& textFragments() const { return m_textFragments; }
- virtual void dirtyLineBoxes() OVERRIDE FINAL;
+ virtual void dirtyLineBoxes() OVERRIDE;
bool startsNewTextChunk() const { return m_startsNewTextChunk; }
void setStartsNewTextChunk(bool newTextChunk) { m_startsNewTextChunk = newTextChunk; }
@@ -65,23 +65,30 @@ public:
private:
TextRun constructTextRun(RenderStyle*, const SVGTextFragment&) const;
- bool acquirePaintingResource(GraphicsContext*&, float scalingFactor, RenderObject*, RenderStyle*);
- void releasePaintingResource(GraphicsContext*&, const Path*);
+ bool acquirePaintingResource(GraphicsContext*&, float scalingFactor, RenderObject*,
+ RenderStyle*, RenderSVGResourceModeFlags);
+ void releasePaintingResource(GraphicsContext*&, const Path*, RenderSVGResourceModeFlags);
- bool prepareGraphicsContextForTextPainting(GraphicsContext*&, float scalingFactor, TextRun&, RenderStyle*);
- void restoreGraphicsContextAfterTextPainting(GraphicsContext*&, TextRun&);
+ bool prepareGraphicsContextForTextPainting(GraphicsContext*&, float scalingFactor, TextRun&,
+ RenderStyle*, RenderSVGResourceModeFlags);
+ void restoreGraphicsContextAfterTextPainting(GraphicsContext*&, TextRun&, RenderSVGResourceModeFlags);
void paintDecoration(GraphicsContext*, TextDecoration, const SVGTextFragment&);
- void paintDecorationWithStyle(GraphicsContext*, TextDecoration, const SVGTextFragment&, RenderObject* decorationRenderer);
- void paintTextWithShadows(GraphicsContext*, RenderStyle*, TextRun&, const SVGTextFragment&, int startPosition, int endPosition);
- void paintText(GraphicsContext*, RenderStyle*, RenderStyle* selectionStyle, const SVGTextFragment&, bool hasSelection, bool paintSelectedTextOnly);
+ void paintDecorationWithStyle(GraphicsContext*, TextDecoration, const SVGTextFragment&,
+ RenderObject* decorationRenderer, RenderSVGResourceModeFlags);
+ void paintTextWithShadows(GraphicsContext*, RenderStyle*, TextRun&, const SVGTextFragment&,
+ int startPosition, int endPosition, RenderSVGResourceModeFlags);
+ void paintText(GraphicsContext*, RenderStyle*, RenderStyle* selectionStyle, const SVGTextFragment&,
+ RenderSVGResourceModeFlags, bool hasSelection, bool paintSelectedTextOnly);
+
+ virtual void paintDocumentMarker(GraphicsContext*, const FloatPoint&, DocumentMarker*, RenderStyle*, const Font&, bool) OVERRIDE FINAL;
+ virtual void paintTextMatchMarker(GraphicsContext*, const FloatPoint&, DocumentMarker*, RenderStyle*, const Font&) OVERRIDE FINAL;
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
private:
float m_logicalHeight;
- unsigned m_paintingResourceMode : 4;
- unsigned m_startsNewTextChunk : 1;
+ bool m_startsNewTextChunk : 1;
RenderSVGResource* m_paintingResource;
Vector<SVGTextFragment> m_textFragments;
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGMarkerData.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGMarkerData.h
index aebd83b3e1a..1b31b98b87f 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGMarkerData.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGMarkerData.h
@@ -26,8 +26,6 @@
namespace WebCore {
-class RenderSVGResourceMarker;
-
enum SVGMarkerType {
StartMarker,
MidMarker,
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGPathData.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGPathData.cpp
index f42f6410e57..5a18ba50295 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGPathData.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGPathData.cpp
@@ -20,7 +20,7 @@
#include "config.h"
#include "core/rendering/svg/SVGPathData.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGCircleElement.h"
#include "core/svg/SVGEllipseElement.h"
#include "core/svg/SVGLineElement.h"
@@ -34,14 +34,16 @@
namespace WebCore {
+using namespace SVGNames;
+
static void updatePathFromCircleElement(SVGElement* element, Path& path)
{
SVGCircleElement* circle = toSVGCircleElement(element);
SVGLengthContext lengthContext(element);
- float r = circle->rCurrentValue().value(lengthContext);
+ float r = circle->r()->currentValue()->value(lengthContext);
if (r > 0)
- path.addEllipse(FloatRect(circle->cxCurrentValue().value(lengthContext) - r, circle->cyCurrentValue().value(lengthContext) - r, r * 2, r * 2));
+ path.addEllipse(FloatRect(circle->cx()->currentValue()->value(lengthContext) - r, circle->cy()->currentValue()->value(lengthContext) - r, r * 2, r * 2));
}
static void updatePathFromEllipseElement(SVGElement* element, Path& path)
@@ -49,13 +51,16 @@ static void updatePathFromEllipseElement(SVGElement* element, Path& path)
SVGEllipseElement* ellipse = toSVGEllipseElement(element);
SVGLengthContext lengthContext(element);
- float rx = ellipse->rxCurrentValue().value(lengthContext);
- if (rx <= 0)
+ float rx = ellipse->rx()->currentValue()->value(lengthContext);
+ if (rx < 0)
+ return;
+ float ry = ellipse->ry()->currentValue()->value(lengthContext);
+ if (ry < 0)
return;
- float ry = ellipse->ryCurrentValue().value(lengthContext);
- if (ry <= 0)
+ if (!rx && !ry)
return;
- path.addEllipse(FloatRect(ellipse->cxCurrentValue().value(lengthContext) - rx, ellipse->cyCurrentValue().value(lengthContext) - ry, rx * 2, ry * 2));
+
+ path.addEllipse(FloatRect(ellipse->cx()->currentValue()->value(lengthContext) - rx, ellipse->cy()->currentValue()->value(lengthContext) - ry, rx * 2, ry * 2));
}
static void updatePathFromLineElement(SVGElement* element, Path& path)
@@ -63,8 +68,8 @@ static void updatePathFromLineElement(SVGElement* element, Path& path)
SVGLineElement* line = toSVGLineElement(element);
SVGLengthContext lengthContext(element);
- path.moveTo(FloatPoint(line->x1CurrentValue().value(lengthContext), line->y1CurrentValue().value(lengthContext)));
- path.addLineTo(FloatPoint(line->x2CurrentValue().value(lengthContext), line->y2CurrentValue().value(lengthContext)));
+ path.moveTo(FloatPoint(line->x1()->currentValue()->value(lengthContext), line->y1()->currentValue()->value(lengthContext)));
+ path.addLineTo(FloatPoint(line->x2()->currentValue()->value(lengthContext), line->y2()->currentValue()->value(lengthContext)));
}
static void updatePathFromPathElement(SVGElement* element, Path& path)
@@ -72,32 +77,26 @@ static void updatePathFromPathElement(SVGElement* element, Path& path)
buildPathFromByteStream(toSVGPathElement(element)->pathByteStream(), path);
}
-static void updatePathFromPolygonElement(SVGElement* element, Path& path)
+static void updatePathFromPolylineElement(SVGElement* element, Path& path)
{
- SVGPointList& points = toSVGPolygonElement(element)->pointsCurrentValue();
- if (points.isEmpty())
+ RefPtr<SVGPointList> points = toSVGPolyElement(element)->points()->currentValue();
+ if (points->isEmpty())
return;
- path.moveTo(points.first());
-
- unsigned size = points.size();
- for (unsigned i = 1; i < size; ++i)
- path.addLineTo(points.at(i));
+ SVGPointList::ConstIterator it = points->begin();
+ SVGPointList::ConstIterator itEnd = points->end();
+ ASSERT(it != itEnd);
+ path.moveTo(it->value());
+ ++it;
- path.closeSubpath();
+ for (; it != itEnd; ++it)
+ path.addLineTo(it->value());
}
-static void updatePathFromPolylineElement(SVGElement* element, Path& path)
+static void updatePathFromPolygonElement(SVGElement* element, Path& path)
{
- SVGPointList& points = toSVGPolylineElement(element)->pointsCurrentValue();
- if (points.isEmpty())
- return;
-
- path.moveTo(points.first());
-
- unsigned size = points.size();
- for (unsigned i = 1; i < size; ++i)
- path.addLineTo(points.at(i));
+ updatePathFromPolylineElement(element, path);
+ path.closeSubpath();
}
static void updatePathFromRectElement(SVGElement* element, Path& path)
@@ -105,19 +104,21 @@ static void updatePathFromRectElement(SVGElement* element, Path& path)
SVGRectElement* rect = toSVGRectElement(element);
SVGLengthContext lengthContext(element);
- float width = rect->widthCurrentValue().value(lengthContext);
- if (width <= 0)
+ float width = rect->width()->currentValue()->value(lengthContext);
+ if (width < 0)
+ return;
+ float height = rect->height()->currentValue()->value(lengthContext);
+ if (height < 0)
return;
- float height = rect->heightCurrentValue().value(lengthContext);
- if (height <= 0)
+ if (!width && !height)
return;
- float x = rect->xCurrentValue().value(lengthContext);
- float y = rect->yCurrentValue().value(lengthContext);
- bool hasRx = rect->rxCurrentValue().value(lengthContext) > 0;
- bool hasRy = rect->ryCurrentValue().value(lengthContext) > 0;
+ float x = rect->x()->currentValue()->value(lengthContext);
+ float y = rect->y()->currentValue()->value(lengthContext);
+ float rx = rect->rx()->currentValue()->value(lengthContext);
+ float ry = rect->ry()->currentValue()->value(lengthContext);
+ bool hasRx = rx > 0;
+ bool hasRy = ry > 0;
if (hasRx || hasRy) {
- float rx = rect->rxCurrentValue().value(lengthContext);
- float ry = rect->ryCurrentValue().value(lengthContext);
if (!hasRx)
rx = ry;
else if (!hasRy)
@@ -139,13 +140,13 @@ void updatePathFromGraphicsElement(SVGElement* element, Path& path)
static HashMap<StringImpl*, PathUpdateFunction>* map = 0;
if (!map) {
map = new HashMap<StringImpl*, PathUpdateFunction>;
- map->set(SVGNames::circleTag.localName().impl(), updatePathFromCircleElement);
- map->set(SVGNames::ellipseTag.localName().impl(), updatePathFromEllipseElement);
- map->set(SVGNames::lineTag.localName().impl(), updatePathFromLineElement);
- map->set(SVGNames::pathTag.localName().impl(), updatePathFromPathElement);
- map->set(SVGNames::polygonTag.localName().impl(), updatePathFromPolygonElement);
- map->set(SVGNames::polylineTag.localName().impl(), updatePathFromPolylineElement);
- map->set(SVGNames::rectTag.localName().impl(), updatePathFromRectElement);
+ map->set(circleTag.localName().impl(), updatePathFromCircleElement);
+ map->set(ellipseTag.localName().impl(), updatePathFromEllipseElement);
+ map->set(lineTag.localName().impl(), updatePathFromLineElement);
+ map->set(pathTag.localName().impl(), updatePathFromPathElement);
+ map->set(polygonTag.localName().impl(), updatePathFromPolygonElement);
+ map->set(polylineTag.localName().impl(), updatePathFromPolylineElement);
+ map->set(rectTag.localName().impl(), updatePathFromRectElement);
}
if (PathUpdateFunction pathUpdateFunction = map->get(element->localName().impl()))
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.cpp
index cfc4a641f7f..56c9e2cffdd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.cpp
@@ -23,9 +23,9 @@
*/
#include "config.h"
-
#include "core/rendering/svg/SVGRenderSupport.h"
+#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderGeometryMap.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/SubtreeLayoutScope.h"
@@ -51,8 +51,8 @@ LayoutRect SVGRenderSupport::clippedOverflowRectForRepaint(const RenderObject* o
// Pass our local paint rect to computeRectForRepaint() which will
// map to parent coords and recurse up the parent chain.
- FloatRect repaintRect = object->repaintRectInLocalCoordinates();
- object->computeFloatRectForRepaint(repaintContainer, repaintRect);
+ FloatRect repaintRect = object->paintInvalidationRectInLocalCoordinates();
+ object->computeFloatRectForPaintInvalidation(repaintContainer, repaintRect);
return enclosingLayoutRect(repaintRect);
}
@@ -60,9 +60,9 @@ void SVGRenderSupport::computeFloatRectForRepaint(const RenderObject* object, co
{
repaintRect.inflate(object->style()->outlineWidth());
- // Translate to coords in our parent renderer, and then call computeFloatRectForRepaint() on our parent.
+ // Translate to coords in our parent renderer, and then call computeFloatRectForPaintInvalidation() on our parent.
repaintRect = object->localToParentTransform().mapRect(repaintRect);
- object->parent()->computeFloatRectForRepaint(repaintContainer, repaintRect, fixed);
+ object->parent()->computeFloatRectForPaintInvalidation(repaintContainer, repaintRect, fixed);
}
void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, const RenderLayerModelObject* repaintContainer, TransformState& transformState, bool* wasFixed)
@@ -100,18 +100,24 @@ const RenderObject* SVGRenderSupport::pushMappingToContainer(const RenderObject*
return parent;
}
-bool SVGRenderSupport::checkForSVGRepaintDuringLayout(RenderObject* object)
+bool SVGRenderSupport::parentTransformDidChange(RenderObject* object)
{
- if (!object->checkForRepaintDuringLayout())
- return false;
// When a parent container is transformed in SVG, all children will be painted automatically
// so we are able to skip redundant repaint checks.
RenderObject* parent = object->parent();
return !(parent && parent->isSVGContainer() && toRenderSVGContainer(parent)->didTransformToRootUpdate());
}
+bool SVGRenderSupport::checkForSVGRepaintDuringLayout(RenderObject* object)
+{
+ if (!object->checkForPaintInvalidationDuringLayout())
+ return false;
+
+ return parentTransformDidChange(object);
+}
+
// Update a bounding box taking into account the validity of the other bounding box.
-static inline void updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, RenderObject* other, FloatRect otherBoundingBox)
+inline void SVGRenderSupport::updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, RenderObject* other, FloatRect otherBoundingBox)
{
bool otherValid = other->isSVGContainer() ? toRenderSVGContainer(other)->isObjectBoundingBoxValid() : true;
if (!otherValid)
@@ -135,18 +141,14 @@ void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* contain
// When computing the strokeBoundingBox, we use the repaintRects of the container's children so that the container's stroke includes
// the resources applied to the children (such as clips and filters). This allows filters applied to containers to correctly bound
// the children, and also improves inlining of SVG content, as the stroke bound is used in that situation also.
- for (RenderObject* current = container->firstChild(); current; current = current->nextSibling()) {
+ for (RenderObject* current = container->slowFirstChild(); current; current = current->nextSibling()) {
if (current->isSVGHiddenContainer())
continue;
const AffineTransform& transform = current->localToParentTransform();
- if (transform.isIdentity()) {
- updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, current->objectBoundingBox());
- strokeBoundingBox.unite(current->repaintRectInLocalCoordinates());
- } else {
- updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, transform.mapRect(current->objectBoundingBox()));
- strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
- }
+ updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current,
+ transform.mapRect(current->objectBoundingBox()));
+ strokeBoundingBox.unite(transform.mapRect(current->paintInvalidationRectInLocalCoordinates()));
}
repaintBoundingBox = strokeBoundingBox;
@@ -154,9 +156,6 @@ void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* contain
bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo)
{
- if (localTransform.isIdentity())
- return localRepaintRect.intersects(paintInfo.rect);
-
return localTransform.mapRect(localRepaintRect).intersects(paintInfo.rect);
}
@@ -170,17 +169,17 @@ const RenderSVGRoot* SVGRenderSupport::findTreeRootObject(const RenderObject* st
return toRenderSVGRoot(start);
}
-static inline void invalidateResourcesOfChildren(RenderObject* start)
+inline void SVGRenderSupport::invalidateResourcesOfChildren(RenderObject* start)
{
ASSERT(!start->needsLayout());
if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(start))
resources->removeClientFromCache(start, false);
- for (RenderObject* child = start->firstChild(); child; child = child->nextSibling())
+ for (RenderObject* child = start->slowFirstChild(); child; child = child->nextSibling())
invalidateResourcesOfChildren(child);
}
-static inline bool layoutSizeOfNearestViewportChanged(const RenderObject* start)
+inline bool SVGRenderSupport::layoutSizeOfNearestViewportChanged(const RenderObject* start)
{
while (start && !start->isSVGRoot() && !start->isSVGViewportContainer())
start = start->parent();
@@ -212,7 +211,7 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
bool transformChanged = transformToRootChanged(start);
HashSet<RenderObject*> notlayoutedObjects;
- for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = start->slowFirstChild(); child; child = child->nextSibling()) {
bool needsLayout = selfNeedsLayout;
bool childEverHadLayout = child->everHadLayout();
@@ -228,9 +227,9 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
if (SVGElement* element = child->node()->isSVGElement() ? toSVGElement(child->node()) : 0) {
if (element->hasRelativeLengths()) {
// When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object
- if (child->isSVGShape())
+ if (child->isSVGShape()) {
toRenderSVGShape(child)->setNeedsShapeUpdate();
- else if (child->isSVGText()) {
+ } else if (child->isSVGText()) {
toRenderSVGText(child)->setNeedsTextMetricsUpdate();
toRenderSVGText(child)->setNeedsPositioningValuesUpdate();
}
@@ -240,7 +239,7 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
}
}
- SubtreeLayoutScope layoutScope(child);
+ SubtreeLayoutScope layoutScope(*child);
// Resource containers are nasty: they can invalidate clients outside the current SubtreeLayoutScope.
// Since they only care about viewport size changes (to resolve their relative lengths), we trigger
// their invalidation directly from SVGSVGElement::svgAttributeChange() or at a higher
@@ -257,9 +256,10 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
// We could handle this in the individual objects, but for now it's easier to have
// parent containers call repaint(). (RenderBlock::layout* has similar logic.)
if (!childEverHadLayout && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
- child->repaint();
- } else if (layoutSizeChanged)
+ child->paintInvalidationForWholeRenderer();
+ } else if (layoutSizeChanged) {
notlayoutedObjects.add(child);
+ }
}
if (!layoutSizeChanged) {
@@ -284,23 +284,16 @@ void SVGRenderSupport::layoutResourcesIfNeeded(const RenderObject* object)
bool SVGRenderSupport::isOverflowHidden(const RenderObject* object)
{
- // SVG doesn't support independent x/y overflow
- ASSERT(object->style()->overflowX() == object->style()->overflowY());
-
- // OSCROLL is never set for SVG - see StyleResolver::adjustRenderStyle
- ASSERT(object->style()->overflowX() != OSCROLL);
-
// RenderSVGRoot should never query for overflow state - it should always clip itself to the initial viewport size.
- ASSERT(!object->isRoot());
+ ASSERT(!object->isDocumentElement());
- return object->style()->overflowX() == OHIDDEN;
+ return object->style()->overflowX() == OHIDDEN || object->style()->overflowX() == OSCROLL;
}
-void SVGRenderSupport::intersectRepaintRectWithResources(const RenderObject* object, FloatRect& repaintRect)
+void SVGRenderSupport::intersectRepaintRectWithResources(const RenderObject* renderer, FloatRect& repaintRect)
{
- ASSERT(object);
+ ASSERT(renderer);
- RenderObject* renderer = const_cast<RenderObject*>(object);
SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
if (!resources)
return;
@@ -357,21 +350,22 @@ void SVGRenderSupport::applyStrokeStyleToContext(GraphicsContext* context, const
ASSERT(svgStyle);
SVGLengthContext lengthContext(toSVGElement(object->node()));
- context->setStrokeThickness(svgStyle->strokeWidth().value(lengthContext));
+ context->setStrokeThickness(svgStyle->strokeWidth()->value(lengthContext));
context->setLineCap(svgStyle->capStyle());
context->setLineJoin(svgStyle->joinStyle());
context->setMiterLimit(svgStyle->strokeMiterLimit());
- const Vector<SVGLength>& dashes = svgStyle->strokeDashArray();
- if (dashes.isEmpty())
+ RefPtr<SVGLengthList> dashes = svgStyle->strokeDashArray();
+ if (dashes->isEmpty())
return;
DashArray dashArray;
- const Vector<SVGLength>::const_iterator end = dashes.end();
- for (Vector<SVGLength>::const_iterator it = dashes.begin(); it != end; ++it)
- dashArray.append((*it).value(lengthContext));
+ SVGLengthList::ConstIterator it = dashes->begin();
+ SVGLengthList::ConstIterator itEnd = dashes->end();
+ for (; it != itEnd; ++it)
+ dashArray.append(it->value(lengthContext));
- context->setLineDash(dashArray, svgStyle->strokeDashOffset().value(lengthContext));
+ context->setLineDash(dashArray, svgStyle->strokeDashOffset()->value(lengthContext));
}
void SVGRenderSupport::applyStrokeStyleToStrokeData(StrokeData* strokeData, const RenderStyle* style, const RenderObject* object)
@@ -386,29 +380,28 @@ void SVGRenderSupport::applyStrokeStyleToStrokeData(StrokeData* strokeData, cons
ASSERT(svgStyle);
SVGLengthContext lengthContext(toSVGElement(object->node()));
- strokeData->setThickness(svgStyle->strokeWidth().value(lengthContext));
+ strokeData->setThickness(svgStyle->strokeWidth()->value(lengthContext));
strokeData->setLineCap(svgStyle->capStyle());
strokeData->setLineJoin(svgStyle->joinStyle());
strokeData->setMiterLimit(svgStyle->strokeMiterLimit());
- const Vector<SVGLength>& dashes = svgStyle->strokeDashArray();
- if (dashes.isEmpty())
+ RefPtr<SVGLengthList> dashes = svgStyle->strokeDashArray();
+ if (dashes->isEmpty())
return;
DashArray dashArray;
- const Vector<SVGLength>::const_iterator end = dashes.end();
- for (Vector<SVGLength>::const_iterator it = dashes.begin(); it != end; ++it)
- dashArray.append((*it).value(lengthContext));
+ size_t length = dashes->length();
+ for (size_t i = 0; i < length; ++i)
+ dashArray.append(dashes->at(i)->value(lengthContext));
- strokeData->setLineDash(dashArray, svgStyle->strokeDashOffset().value(lengthContext));
+ strokeData->setLineDash(dashArray, svgStyle->strokeDashOffset()->value(lengthContext));
}
-bool SVGRenderSupport::isEmptySVGInlineText(const RenderObject* object)
+bool SVGRenderSupport::isRenderableTextNode(const RenderObject* object)
{
- // RenderSVGInlineText performs whitespace filtering in order to support xml:space
- // (http://www.w3.org/TR/SVG/struct.html#LangSpaceAttrs), and can end up with an empty string
- // even when its original constructor argument is non-empty.
- return object->isSVGInlineText() && toRenderSVGInlineText(object)->hasEmptyText();
+ ASSERT(object->isText());
+ // <br> is marked as text, but is not handled by the SVG rendering code-path.
+ return object->isSVGInlineText() && !toRenderSVGInlineText(object)->hasEmptyText();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.h
index 4265f64c780..087dcfbbd44 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderSupport.h
@@ -24,23 +24,22 @@
#ifndef SVGRenderSupport_h
#define SVGRenderSupport_h
-#include "core/rendering/PaintInfo.h"
-
namespace WebCore {
+class AffineTransform;
class FloatPoint;
class FloatRect;
-class ImageBuffer;
+class GraphicsContext;
class LayoutRect;
-class RenderBoxModelObject;
+struct PaintInfo;
class RenderGeometryMap;
class RenderLayerModelObject;
class RenderObject;
class RenderStyle;
class RenderSVGRoot;
+class StrokeData;
class TransformState;
-// SVGRendererSupport is a helper class sharing code between all SVG renderers.
class SVGRenderSupport {
public:
// Shares child layouting code between RenderSVGRoot/RenderSVG(Hidden)Container
@@ -62,8 +61,11 @@ public:
static bool pointInClippingArea(RenderObject*, const FloatPoint&);
static void computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox);
+
static bool paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo&);
+ static bool parentTransformDidChange(RenderObject*);
+
// Important functions used by nearly all SVG renderers centralizing coordinate transformations / repaint rect calculations
static LayoutRect clippedOverflowRectForRepaint(const RenderObject*, const RenderLayerModelObject* repaintContainer);
static void computeFloatRectForRepaint(const RenderObject*, const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed);
@@ -81,13 +83,14 @@ public:
// FIXME: These methods do not belong here.
static const RenderSVGRoot* findTreeRootObject(const RenderObject*);
- // Helper method for determining whether an RenderSVGInlineText object has zero length text.
- static bool isEmptySVGInlineText(const RenderObject*);
+ // Helper method for determining if a RenderObject marked as text (isText()== true)
+ // can/will be rendered as part of a <text>.
+ static bool isRenderableTextNode(const RenderObject*);
private:
- // This class is not constructable.
- SVGRenderSupport();
- ~SVGRenderSupport();
+ static void updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, RenderObject* other, FloatRect otherBoundingBox);
+ static void invalidateResourcesOfChildren(RenderObject* start);
+ static bool layoutSizeOfNearestViewportChanged(const RenderObject* start);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.cpp
index b92e9b99833..15726cb9c37 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.cpp
@@ -30,7 +30,6 @@
#include "core/rendering/svg/SVGRenderTreeAsText.h"
-#include "SVGNames.h"
#include "core/rendering/InlineTextBox.h"
#include "core/rendering/RenderTreeAsText.h"
#include "core/rendering/svg/RenderSVGGradientStop.h"
@@ -64,6 +63,7 @@
#include "core/svg/SVGRadialGradientElement.h"
#include "core/svg/SVGRectElement.h"
#include "core/svg/SVGStopElement.h"
+#include "platform/graphics/DashArray.h"
#include "platform/graphics/GraphicsTypes.h"
#include <math.h>
@@ -154,15 +154,35 @@ static TextStream& operator<<(TextStream& ts, const WindRule rule)
return ts;
}
+namespace {
+
+template<typename Enum>
+String SVGEnumerationToString(Enum value)
+{
+ const SVGEnumerationStringEntries& entries = getStaticStringEntries<Enum>();
+
+ SVGEnumerationStringEntries::const_iterator it = entries.begin();
+ SVGEnumerationStringEntries::const_iterator itEnd = entries.end();
+ for (; it != itEnd; ++it) {
+ if (value == it->first)
+ return it->second;
+ }
+
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
+}
+
static TextStream& operator<<(TextStream& ts, const SVGUnitTypes::SVGUnitType& unitType)
{
- ts << SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::toString(unitType);
+ ts << SVGEnumerationToString<SVGUnitTypes::SVGUnitType>(unitType);
return ts;
}
static TextStream& operator<<(TextStream& ts, const SVGMarkerUnitsType& markerUnit)
{
- ts << SVGPropertyTraits<SVGMarkerUnitsType>::toString(markerUnit);
+ ts << SVGEnumerationToString<SVGMarkerUnitsType>(markerUnit);
return ts;
}
@@ -221,7 +241,7 @@ static TextStream& operator<<(TextStream& ts, LineJoin style)
static TextStream& operator<<(TextStream& ts, const SVGSpreadMethodType& type)
{
- ts << SVGPropertyTraits<SVGSpreadMethodType>::toString(type).upper();
+ ts << SVGEnumerationToString<SVGSpreadMethodType>(type).upper();
return ts;
}
@@ -260,21 +280,22 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
const RenderSVGShape& shape = static_cast<const RenderSVGShape&>(object);
ASSERT(shape.element());
- Color fallbackColor;
- if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), fallbackColor)) {
+ bool hasFallback;
+ if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), hasFallback)) {
TextStreamSeparator s(" ");
ts << " [stroke={" << s;
writeSVGPaintingResource(ts, strokePaintingResource);
SVGLengthContext lengthContext(shape.element());
- double dashOffset = svgStyle->strokeDashOffset().value(lengthContext);
- double strokeWidth = svgStyle->strokeWidth().value(lengthContext);
- const Vector<SVGLength>& dashes = svgStyle->strokeDashArray();
+ double dashOffset = svgStyle->strokeDashOffset()->value(lengthContext);
+ double strokeWidth = svgStyle->strokeWidth()->value(lengthContext);
+ RefPtr<SVGLengthList> dashes = svgStyle->strokeDashArray();
DashArray dashArray;
- const Vector<SVGLength>::const_iterator end = dashes.end();
- for (Vector<SVGLength>::const_iterator it = dashes.begin(); it != end; ++it)
- dashArray.append((*it).value(lengthContext));
+ SVGLengthList::ConstIterator it = dashes->begin();
+ SVGLengthList::ConstIterator itEnd = dashes->end();
+ for (; it != itEnd; ++it)
+ dashArray.append(it->value(lengthContext));
writeIfNotDefault(ts, "opacity", svgStyle->strokeOpacity(), 1.0f);
writeIfNotDefault(ts, "stroke width", strokeWidth, 1.0);
@@ -288,7 +309,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
ts << "}]";
}
- if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), fallbackColor)) {
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), hasFallback)) {
TextStreamSeparator s(" ");
ts << " [fill={" << s;
writeSVGPaintingResource(ts, fillPaintingResource);
@@ -317,37 +338,38 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
writePositionAndStyle(ts, shape);
SVGElement* svgElement = shape.element();
+ ASSERT(svgElement);
SVGLengthContext lengthContext(svgElement);
- if (svgElement->hasTagName(SVGNames::rectTag)) {
- SVGRectElement* element = toSVGRectElement(svgElement);
- writeNameValuePair(ts, "x", element->xCurrentValue().value(lengthContext));
- writeNameValuePair(ts, "y", element->yCurrentValue().value(lengthContext));
- writeNameValuePair(ts, "width", element->widthCurrentValue().value(lengthContext));
- writeNameValuePair(ts, "height", element->heightCurrentValue().value(lengthContext));
- } else if (svgElement->hasTagName(SVGNames::lineTag)) {
- SVGLineElement* element = toSVGLineElement(svgElement);
- writeNameValuePair(ts, "x1", element->x1CurrentValue().value(lengthContext));
- writeNameValuePair(ts, "y1", element->y1CurrentValue().value(lengthContext));
- writeNameValuePair(ts, "x2", element->x2CurrentValue().value(lengthContext));
- writeNameValuePair(ts, "y2", element->y2CurrentValue().value(lengthContext));
- } else if (svgElement->hasTagName(SVGNames::ellipseTag)) {
- SVGEllipseElement* element = toSVGEllipseElement(svgElement);
- writeNameValuePair(ts, "cx", element->cxCurrentValue().value(lengthContext));
- writeNameValuePair(ts, "cy", element->cyCurrentValue().value(lengthContext));
- writeNameValuePair(ts, "rx", element->rxCurrentValue().value(lengthContext));
- writeNameValuePair(ts, "ry", element->ryCurrentValue().value(lengthContext));
- } else if (svgElement->hasTagName(SVGNames::circleTag)) {
- SVGCircleElement* element = toSVGCircleElement(svgElement);
- writeNameValuePair(ts, "cx", element->cxCurrentValue().value(lengthContext));
- writeNameValuePair(ts, "cy", element->cyCurrentValue().value(lengthContext));
- writeNameValuePair(ts, "r", element->rCurrentValue().value(lengthContext));
- } else if (svgElement->hasTagName(SVGNames::polygonTag) || svgElement->hasTagName(SVGNames::polylineTag)) {
- writeNameAndQuotedValue(ts, "points", toSVGPolyElement(svgElement)->pointsCurrentValue().valueAsString());
- } else if (svgElement->hasTagName(SVGNames::pathTag)) {
+ if (isSVGRectElement(*svgElement)) {
+ SVGRectElement& element = toSVGRectElement(*svgElement);
+ writeNameValuePair(ts, "x", element.x()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "y", element.y()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "width", element.width()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "height", element.height()->currentValue()->value(lengthContext));
+ } else if (isSVGLineElement(*svgElement)) {
+ SVGLineElement& element = toSVGLineElement(*svgElement);
+ writeNameValuePair(ts, "x1", element.x1()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "y1", element.y1()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "x2", element.x2()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "y2", element.y2()->currentValue()->value(lengthContext));
+ } else if (isSVGEllipseElement(*svgElement)) {
+ SVGEllipseElement& element = toSVGEllipseElement(*svgElement);
+ writeNameValuePair(ts, "cx", element.cx()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "cy", element.cy()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "rx", element.rx()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "ry", element.ry()->currentValue()->value(lengthContext));
+ } else if (isSVGCircleElement(*svgElement)) {
+ SVGCircleElement& element = toSVGCircleElement(*svgElement);
+ writeNameValuePair(ts, "cx", element.cx()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "cy", element.cy()->currentValue()->value(lengthContext));
+ writeNameValuePair(ts, "r", element.r()->currentValue()->value(lengthContext));
+ } else if (isSVGPolyElement(*svgElement)) {
+ writeNameAndQuotedValue(ts, "points", toSVGPolyElement(*svgElement).points()->currentValue()->valueAsString());
+ } else if (isSVGPathElement(*svgElement)) {
String pathString;
// FIXME: We should switch to UnalteredParsing here - this will affect the path dumping output of dozens of tests.
- buildStringFromByteStream(toSVGPathElement(svgElement)->pathByteStream(), pathString, NormalizedParsing);
+ buildStringFromByteStream(toSVGPathElement(*svgElement).pathByteStream(), pathString, NormalizedParsing);
writeNameAndQuotedValue(ts, "data", pathString);
} else
ASSERT_NOT_REACHED();
@@ -380,11 +402,10 @@ static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textB
if (fragments.isEmpty())
return;
- RenderSVGInlineText* textRenderer = toRenderSVGInlineText(textBox->textRenderer());
- ASSERT(textRenderer);
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(textBox->textRenderer());
- const SVGRenderStyle* svgStyle = textRenderer->style()->svgStyle();
- String text = textBox->textRenderer()->text();
+ const SVGRenderStyle* svgStyle = textRenderer.style()->svgStyle();
+ String text = textBox->textRenderer().text();
unsigned fragmentsSize = fragments.size();
for (unsigned i = 0; i < fragmentsSize; ++i) {
@@ -452,7 +473,7 @@ static void writeStandardPrefix(TextStream& ts, const RenderObject& object, int
static void writeChildren(TextStream& ts, const RenderObject& object, int indent)
{
- for (RenderObject* child = object.firstChild(); child; child = child->nextSibling())
+ for (RenderObject* child = object.slowFirstChild(); child; child = child->nextSibling())
write(ts, *child, indent + 1);
}
@@ -490,7 +511,8 @@ void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int i
ts << "\n";
// Creating a placeholder filter which is passed to the builder.
FloatRect dummyRect;
- RefPtr<SVGFilter> dummyFilter = SVGFilter::create(AffineTransform(), dummyRect, dummyRect, dummyRect, true);
+ IntRect dummyIntRect;
+ RefPtr<SVGFilter> dummyFilter = SVGFilter::create(AffineTransform(), dummyIntRect, dummyRect, dummyRect, true);
if (RefPtr<SVGFilterBuilder> builder = filter->buildPrimitives(dummyFilter.get())) {
if (FilterEffect* lastEffect = builder->lastEffect())
lastEffect->externalRepresentation(ts, indent + 1);
@@ -614,7 +636,7 @@ void writeSVGGradientStop(TextStream& ts, const RenderSVGGradientStop& stop, int
if (!style)
return;
- ts << " [offset=" << stopElement->offsetCurrentValue() << "] [color=" << stopElement->stopColorIncludingOpacity() << "]\n";
+ ts << " [offset=" << stopElement->offset()->currentValue()->value() << "] [color=" << stopElement->stopColorIncludingOpacity() << "]\n";
}
void writeResources(TextStream& ts, const RenderObject& object, int indent)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.h
index 055c587df57..63f26442a6d 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderTreeAsText.h
@@ -31,10 +31,6 @@
namespace WebCore {
class Color;
-class FloatRect;
-class FloatSize;
-class Node;
-class RenderImage;
class RenderObject;
class RenderSVGGradientStop;
class RenderSVGImage;
@@ -43,7 +39,6 @@ class RenderSVGShape;
class RenderSVGRoot;
class RenderSVGText;
class AffineTransform;
-class SVGUnitTypes;
// functions used by the main RenderTreeAsText code
void write(TextStream&, const RenderSVGShape&, int indent);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.cpp
index 55545097c0f..23766e3a505 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.cpp
@@ -26,9 +26,10 @@
#include "core/rendering/svg/SVGRenderingContext.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
-#include "core/page/Page.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/svg/RenderSVGImage.h"
#include "core/rendering/svg/RenderSVGResource.h"
@@ -113,23 +114,28 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderObject* object, PaintI
// Setup transparency layers before setting up SVG resources!
bool isRenderingMask = isRenderingMaskImage(m_object);
- float opacity = isRenderingMask ? 1 : style->opacity();
- blink::WebBlendMode blendMode = isRenderingMask ? blink::WebBlendModeNormal : style->blendMode();
- if (opacity < 1 || blendMode != blink::WebBlendModeNormal) {
- FloatRect repaintRect = m_object->repaintRectInLocalCoordinates();
-
- if (opacity < 1 || blendMode != blink::WebBlendModeNormal) {
- m_paintInfo->context->clip(repaintRect);
- if (blendMode != blink::WebBlendModeNormal) {
- if (!(m_renderingFlags & RestoreGraphicsContext)) {
- m_paintInfo->context->save();
- m_renderingFlags |= RestoreGraphicsContext;
- }
- m_paintInfo->context->setCompositeOperation(CompositeSourceOver, blendMode);
+ // RenderLayer takes care of root opacity.
+ float opacity = (object->isSVGRoot() || isRenderingMask) ? 1 : style->opacity();
+ bool hasBlendMode = style->hasBlendMode() && !isRenderingMask;
+
+ if (opacity < 1 || hasBlendMode || style->hasIsolation()) {
+ FloatRect repaintRect = m_object->paintInvalidationRectInLocalCoordinates();
+ m_paintInfo->context->clip(repaintRect);
+
+ if (hasBlendMode) {
+ if (!(m_renderingFlags & RestoreGraphicsContext)) {
+ m_paintInfo->context->save();
+ m_renderingFlags |= RestoreGraphicsContext;
}
- m_paintInfo->context->beginTransparencyLayer(opacity);
- m_renderingFlags |= EndOpacityLayer;
+ m_paintInfo->context->setCompositeOperation(CompositeSourceOver, style->blendMode());
}
+
+ m_paintInfo->context->beginTransparencyLayer(opacity);
+
+ if (hasBlendMode)
+ m_paintInfo->context->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal);
+
+ m_renderingFlags |= EndOpacityLayer;
}
ClipPathOperation* clipPathOperation = style->clipPath();
@@ -197,20 +203,23 @@ float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObje
ASSERT(renderer);
AffineTransform ctm;
- calculateTransformationToOutermostCoordinateSystem(renderer, ctm);
+ // FIXME: calculateDeviceSpaceTransformation() queries layer compositing state - which is not
+ // supported during layout. Hence, the result may not include all CSS transforms.
+ calculateDeviceSpaceTransformation(renderer, ctm);
return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
}
-void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform)
+void SVGRenderingContext::calculateDeviceSpaceTransformation(const RenderObject* renderer, AffineTransform& absoluteTransform)
{
- ASSERT(renderer);
- absoluteTransform = currentContentTransformation();
+ // FIXME: trying to compute a device space transform at record time is wrong. All clients
+ // should be updated to avoid relying on this information, and the method should be removed.
- float deviceScaleFactor = 1;
- if (Page* page = renderer->document().page())
- deviceScaleFactor = page->deviceScaleFactor();
+ ASSERT(renderer);
+ // We're about to possibly clear renderer, so save the deviceScaleFactor now.
+ float deviceScaleFactor = renderer->document().frameHost()->deviceScaleFactor();
// Walk up the render tree, accumulating SVG transforms.
+ absoluteTransform = currentContentTransformation();
while (renderer) {
absoluteTransform = renderer->localToParentTransform() * absoluteTransform;
if (renderer->isSVGRoot())
@@ -220,23 +229,22 @@ void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(con
// Continue walking up the layer tree, accumulating CSS transforms.
RenderLayer* layer = renderer ? renderer->enclosingLayer() : 0;
- while (layer) {
- if (TransformationMatrix* layerTransform = layer->transform())
- absoluteTransform = layerTransform->toAffineTransform() * absoluteTransform;
-
+ while (layer && layer->isAllowedToQueryCompositingState()) {
// We can stop at compositing layers, to match the backing resolution.
// FIXME: should we be computing the transform to the nearest composited layer,
// or the nearest composited layer that does not paint into its ancestor?
// I think this is the nearest composited ancestor since we will inherit its
// transforms in the composited layer tree.
- if (layer->hasCompositedLayerMapping())
+ if (layer->compositingState() != NotComposited)
break;
+ if (TransformationMatrix* layerTransform = layer->transform())
+ absoluteTransform = layerTransform->toAffineTransform() * absoluteTransform;
+
layer = layer->parent();
}
- if (deviceScaleFactor != 1)
- absoluteTransform.scale(deviceScaleFactor);
+ absoluteTransform.scale(deviceScaleFactor);
}
void SVGRenderingContext::renderSubtree(GraphicsContext* context, RenderObject* item, const AffineTransform& subtreeContentTransformation)
@@ -278,7 +286,7 @@ bool SVGRenderingContext::bufferForeground(OwnPtr<ImageBuffer>& imageBuffer)
// Invalidate an existing buffer if the scale is not correct.
if (imageBuffer) {
- AffineTransform transform = m_paintInfo->context->getCTM(GraphicsContext::DefinitelyIncludeDeviceScale);
+ AffineTransform transform = m_paintInfo->context->getCTM();
IntSize expandedBoundingBox = expandedIntSize(boundingBox.size());
IntSize bufferSize(static_cast<int>(ceil(expandedBoundingBox.width() * transform.xScale())), static_cast<int>(ceil(expandedBoundingBox.height() * transform.yScale())));
if (bufferSize != imageBuffer->size())
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.h
index 742e0a09997..3fcda0ae099 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRenderingContext.h
@@ -79,7 +79,7 @@ public:
static void renderSubtree(GraphicsContext*, RenderObject*, const AffineTransform&);
static float calculateScreenFontSizeScalingFactor(const RenderObject*);
- static void calculateTransformationToOutermostCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform);
+ static void calculateDeviceSpaceTransformation(const RenderObject*, AffineTransform& absoluteTransform);
static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect);
static void clear2DRotation(AffineTransform&);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.cpp
index 5c42dbcef69..dcb5113bff7 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.cpp
@@ -20,7 +20,7 @@
#include "config.h"
#include "core/rendering/svg/SVGResources.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/style/SVGRenderStyle.h"
#include "core/rendering/svg/RenderSVGResourceClipper.h"
#include "core/rendering/svg/RenderSVGResourceFilter.h"
@@ -38,6 +38,8 @@
namespace WebCore {
+using namespace SVGNames;
+
SVGResources::SVGResources()
: m_linkedResource(0)
{
@@ -49,39 +51,45 @@ static HashSet<AtomicString>& clipperFilterMaskerTags()
if (s_tagList.isEmpty()) {
// "container elements": http://www.w3.org/TR/SVG11/intro.html#TermContainerElement
// "graphics elements" : http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement
- s_tagList.add(SVGNames::aTag.localName());
- s_tagList.add(SVGNames::circleTag.localName());
- s_tagList.add(SVGNames::ellipseTag.localName());
- s_tagList.add(SVGNames::glyphTag.localName());
- s_tagList.add(SVGNames::gTag.localName());
- s_tagList.add(SVGNames::imageTag.localName());
- s_tagList.add(SVGNames::lineTag.localName());
- s_tagList.add(SVGNames::markerTag.localName());
- s_tagList.add(SVGNames::maskTag.localName());
- s_tagList.add(SVGNames::missing_glyphTag.localName());
- s_tagList.add(SVGNames::pathTag.localName());
- s_tagList.add(SVGNames::polygonTag.localName());
- s_tagList.add(SVGNames::polylineTag.localName());
- s_tagList.add(SVGNames::rectTag.localName());
- s_tagList.add(SVGNames::svgTag.localName());
- s_tagList.add(SVGNames::textTag.localName());
- s_tagList.add(SVGNames::useTag.localName());
+ s_tagList.add(aTag.localName());
+ s_tagList.add(circleTag.localName());
+ s_tagList.add(ellipseTag.localName());
+#if ENABLE(SVG_FONTS)
+ s_tagList.add(glyphTag.localName());
+#endif
+ s_tagList.add(gTag.localName());
+ s_tagList.add(imageTag.localName());
+ s_tagList.add(lineTag.localName());
+ s_tagList.add(markerTag.localName());
+ s_tagList.add(maskTag.localName());
+#if ENABLE(SVG_FONTS)
+ s_tagList.add(missing_glyphTag.localName());
+#endif
+ s_tagList.add(pathTag.localName());
+ s_tagList.add(polygonTag.localName());
+ s_tagList.add(polylineTag.localName());
+ s_tagList.add(rectTag.localName());
+ s_tagList.add(svgTag.localName());
+ s_tagList.add(textTag.localName());
+ s_tagList.add(useTag.localName());
// Not listed in the definitions is the clipPath element, the SVG spec says though:
// The "clipPath" element or any of its children can specify property "clip-path".
// So we have to add clipPathTag here, otherwhise clip-path on clipPath will fail.
// (Already mailed SVG WG, waiting for a solution)
- s_tagList.add(SVGNames::clipPathTag.localName());
+ s_tagList.add(clipPathTag.localName());
// Not listed in the definitions are the text content elements, though filter/clipper/masker on tspan/text/.. is allowed.
// (Already mailed SVG WG, waiting for a solution)
- s_tagList.add(SVGNames::altGlyphTag.localName());
- s_tagList.add(SVGNames::textPathTag.localName());
- s_tagList.add(SVGNames::tspanTag.localName());
+#if ENABLE(SVG_FONTS)
+ s_tagList.add(altGlyphTag.localName());
+#endif
+ s_tagList.add(textPathTag.localName());
+ s_tagList.add(tspanTag.localName());
// Not listed in the definitions is the foreignObject element, but clip-path
// is a supported attribute.
- s_tagList.add(SVGNames::foreignObjectTag.localName());
+ s_tagList.add(foreignObjectTag.localName());
// Elements that we ignore, as it doesn't make any sense.
// defs, pattern, switch (FIXME: Mail SVG WG about these)
@@ -91,34 +99,36 @@ static HashSet<AtomicString>& clipperFilterMaskerTags()
return s_tagList;
}
-static HashSet<AtomicString>& markerTags()
+bool SVGResources::supportsMarkers(const SVGElement& element)
{
DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
if (s_tagList.isEmpty()) {
- s_tagList.add(SVGNames::lineTag.localName());
- s_tagList.add(SVGNames::pathTag.localName());
- s_tagList.add(SVGNames::polygonTag.localName());
- s_tagList.add(SVGNames::polylineTag.localName());
+ s_tagList.add(lineTag.localName());
+ s_tagList.add(pathTag.localName());
+ s_tagList.add(polygonTag.localName());
+ s_tagList.add(polylineTag.localName());
}
- return s_tagList;
+ return s_tagList.contains(element.localName());
}
static HashSet<AtomicString>& fillAndStrokeTags()
{
DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
if (s_tagList.isEmpty()) {
- s_tagList.add(SVGNames::altGlyphTag.localName());
- s_tagList.add(SVGNames::circleTag.localName());
- s_tagList.add(SVGNames::ellipseTag.localName());
- s_tagList.add(SVGNames::lineTag.localName());
- s_tagList.add(SVGNames::pathTag.localName());
- s_tagList.add(SVGNames::polygonTag.localName());
- s_tagList.add(SVGNames::polylineTag.localName());
- s_tagList.add(SVGNames::rectTag.localName());
- s_tagList.add(SVGNames::textTag.localName());
- s_tagList.add(SVGNames::textPathTag.localName());
- s_tagList.add(SVGNames::tspanTag.localName());
+#if ENABLE(SVG_FONTS)
+ s_tagList.add(altGlyphTag.localName());
+#endif
+ s_tagList.add(circleTag.localName());
+ s_tagList.add(ellipseTag.localName());
+ s_tagList.add(lineTag.localName());
+ s_tagList.add(pathTag.localName());
+ s_tagList.add(polygonTag.localName());
+ s_tagList.add(polylineTag.localName());
+ s_tagList.add(rectTag.localName());
+ s_tagList.add(textTag.localName());
+ s_tagList.add(textPathTag.localName());
+ s_tagList.add(tspanTag.localName());
}
return s_tagList;
@@ -128,37 +138,52 @@ static HashSet<AtomicString>& chainableResourceTags()
{
DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
if (s_tagList.isEmpty()) {
- s_tagList.add(SVGNames::linearGradientTag.localName());
- s_tagList.add(SVGNames::filterTag.localName());
- s_tagList.add(SVGNames::patternTag.localName());
- s_tagList.add(SVGNames::radialGradientTag.localName());
+ s_tagList.add(linearGradientTag.localName());
+ s_tagList.add(filterTag.localName());
+ s_tagList.add(patternTag.localName());
+ s_tagList.add(radialGradientTag.localName());
}
return s_tagList;
}
-static inline String targetReferenceFromResource(SVGElement* element)
+static inline AtomicString targetReferenceFromResource(SVGElement& element)
{
String target;
- if (element->hasTagName(SVGNames::patternTag))
- target = toSVGPatternElement(element)->hrefCurrentValue();
- else if (element->hasTagName(SVGNames::linearGradientTag) || element->hasTagName(SVGNames::radialGradientTag))
- target = toSVGGradientElement(element)->hrefCurrentValue();
- else if (element->hasTagName(SVGNames::filterTag))
- target = toSVGFilterElement(element)->hrefCurrentValue();
+ if (isSVGPatternElement(element))
+ target = toSVGPatternElement(element).href()->currentValue()->value();
+ else if (isSVGGradientElement(element))
+ target = toSVGGradientElement(element).href()->currentValue()->value();
+ else if (isSVGFilterElement(element))
+ target = toSVGFilterElement(element).href()->currentValue()->value();
else
ASSERT_NOT_REACHED();
- return SVGURIReference::fragmentIdentifierFromIRIString(target, element->document());
+ return SVGURIReference::fragmentIdentifierFromIRIString(target, element.treeScope());
+}
+
+static inline bool svgPaintTypeHasURL(SVGPaint::SVGPaintType paintType)
+{
+ switch (paintType) {
+ case SVGPaint::SVG_PAINTTYPE_URI_NONE:
+ case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR:
+ case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR:
+ case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
+ case SVGPaint::SVG_PAINTTYPE_URI:
+ return true;
+ default:
+ break;
+ }
+ return false;
}
-static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document& document, const SVGPaint::SVGPaintType& paintType, const String& paintUri, AtomicString& id, bool& hasPendingResource)
+static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(TreeScope& treeScope, const SVGPaint::SVGPaintType& paintType, const String& paintUri, AtomicString& id, bool& hasPendingResource)
{
- if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)
+ if (!svgPaintTypeHasURL(paintType))
return 0;
- id = SVGURIReference::fragmentIdentifierFromIRIString(paintUri, document);
- RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id);
+ id = SVGURIReference::fragmentIdentifierFromIRIString(paintUri, treeScope);
+ RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(treeScope, id);
if (!container) {
hasPendingResource = true;
return 0;
@@ -171,10 +196,10 @@ static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document&
return container;
}
-static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, SVGElement* element)
+static inline void registerPendingResource(SVGDocumentExtensions& extensions, const AtomicString& id, SVGElement* element)
{
ASSERT(element);
- extensions->addPendingResource(id, element);
+ extensions.addPendingResource(id, element);
}
bool SVGResources::hasResourceData() const
@@ -206,10 +231,9 @@ PassOwnPtr<SVGResources> SVGResources::buildResources(const RenderObject* object
if (!element)
return nullptr;
- Document& document = object->document();
+ TreeScope& treeScope = element->treeScope();
- SVGDocumentExtensions* extensions = document.accessSVGExtensions();
- ASSERT(extensions);
+ SVGDocumentExtensions& extensions = object->document().accessSVGExtensions();
const AtomicString& tagName = element->localName();
if (tagName.isNull())
@@ -218,35 +242,35 @@ PassOwnPtr<SVGResources> SVGResources::buildResources(const RenderObject* object
OwnPtr<SVGResources> resources;
if (clipperFilterMaskerTags().contains(tagName)) {
if (style->hasClipper()) {
- AtomicString id(style->clipperResource());
- if (!ensureResources(resources)->setClipper(getRenderSVGResourceById<RenderSVGResourceClipper>(document, id)))
+ AtomicString id = style->clipperResource();
+ if (!ensureResources(resources)->setClipper(getRenderSVGResourceById<RenderSVGResourceClipper>(treeScope, id)))
registerPendingResource(extensions, id, element);
}
if (style->hasFilter()) {
- AtomicString id(style->filterResource());
- if (!ensureResources(resources)->setFilter(getRenderSVGResourceById<RenderSVGResourceFilter>(document, id)))
+ AtomicString id = style->filterResource();
+ if (!ensureResources(resources)->setFilter(getRenderSVGResourceById<RenderSVGResourceFilter>(treeScope, id)))
registerPendingResource(extensions, id, element);
}
if (style->hasMasker()) {
- AtomicString id(style->maskerResource());
- if (!ensureResources(resources)->setMasker(getRenderSVGResourceById<RenderSVGResourceMasker>(document, id)))
+ AtomicString id = style->maskerResource();
+ if (!ensureResources(resources)->setMasker(getRenderSVGResourceById<RenderSVGResourceMasker>(treeScope, id)))
registerPendingResource(extensions, id, element);
}
}
- if (markerTags().contains(tagName) && style->hasMarkers()) {
- AtomicString markerStartId(style->markerStartResource());
- if (!ensureResources(resources)->setMarkerStart(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId)))
+ if (style->hasMarkers() && supportsMarkers(*element)) {
+ const AtomicString& markerStartId = style->markerStartResource();
+ if (!ensureResources(resources)->setMarkerStart(getRenderSVGResourceById<RenderSVGResourceMarker>(treeScope, markerStartId)))
registerPendingResource(extensions, markerStartId, element);
- AtomicString markerMidId(style->markerMidResource());
- if (!ensureResources(resources)->setMarkerMid(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerMidId)))
+ const AtomicString& markerMidId = style->markerMidResource();
+ if (!ensureResources(resources)->setMarkerMid(getRenderSVGResourceById<RenderSVGResourceMarker>(treeScope, markerMidId)))
registerPendingResource(extensions, markerMidId, element);
- AtomicString markerEndId(style->markerEndResource());
- if (!ensureResources(resources)->setMarkerEnd(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerEndId)))
+ const AtomicString& markerEndId = style->markerEndResource();
+ if (!ensureResources(resources)->setMarkerEnd(getRenderSVGResourceById<RenderSVGResourceMarker>(treeScope, style->markerEndResource())))
registerPendingResource(extensions, markerEndId, element);
}
@@ -254,7 +278,7 @@ PassOwnPtr<SVGResources> SVGResources::buildResources(const RenderObject* object
if (style->hasFill()) {
bool hasPendingResource = false;
AtomicString id;
- RenderSVGResourceContainer* resource = paintingResourceFromSVGPaint(document, style->fillPaintType(), style->fillPaintUri(), id, hasPendingResource);
+ RenderSVGResourceContainer* resource = paintingResourceFromSVGPaint(treeScope, style->fillPaintType(), style->fillPaintUri(), id, hasPendingResource);
if (!ensureResources(resources)->setFill(resource) && hasPendingResource) {
registerPendingResource(extensions, id, element);
}
@@ -263,7 +287,7 @@ PassOwnPtr<SVGResources> SVGResources::buildResources(const RenderObject* object
if (style->hasStroke()) {
bool hasPendingResource = false;
AtomicString id;
- RenderSVGResourceContainer* resource = paintingResourceFromSVGPaint(document, style->strokePaintType(), style->strokePaintUri(), id, hasPendingResource);
+ RenderSVGResourceContainer* resource = paintingResourceFromSVGPaint(treeScope, style->strokePaintType(), style->strokePaintUri(), id, hasPendingResource);
if (!ensureResources(resources)->setStroke(resource) && hasPendingResource) {
registerPendingResource(extensions, id, element);
}
@@ -271,8 +295,8 @@ PassOwnPtr<SVGResources> SVGResources::buildResources(const RenderObject* object
}
if (chainableResourceTags().contains(tagName)) {
- AtomicString id(targetReferenceFromResource(element));
- if (!ensureResources(resources)->setLinkedResource(getRenderSVGResourceContainerById(document, id)))
+ AtomicString id = targetReferenceFromResource(*element);
+ if (!ensureResources(resources)->setLinkedResource(getRenderSVGResourceContainerById(treeScope, id)))
registerPendingResource(extensions, id, element);
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.h
index 8eb10adcb4e..41cdf2569d8 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResources.h
@@ -20,6 +20,7 @@
#ifndef SVGResources_h
#define SVGResources_h
+#include "wtf/FastAllocBase.h"
#include "wtf/HashSet.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
@@ -27,13 +28,13 @@
namespace WebCore {
-class Document;
class RenderObject;
class RenderSVGResourceClipper;
class RenderSVGResourceContainer;
class RenderSVGResourceFilter;
class RenderSVGResourceMarker;
class RenderSVGResourceMasker;
+class SVGElement;
class SVGRenderStyle;
// Holds a set of resources associated with a RenderObject
@@ -45,6 +46,8 @@ public:
static PassOwnPtr<SVGResources> buildResources(const RenderObject*, const SVGRenderStyle*);
void layoutIfNeeded();
+ static bool supportsMarkers(const SVGElement&);
+
// Ordinary resources
RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.cpp
index 7a8ed18b4d8..b8ba7101ded 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.cpp
@@ -20,7 +20,7 @@
#include "config.h"
#include "core/rendering/svg/SVGResourcesCache.h"
-#include "HTMLNames.h"
+#include "core/HTMLNames.h"
#include "core/rendering/svg/RenderSVGResourceContainer.h"
#include "core/rendering/svg/SVGResources.h"
#include "core/rendering/svg/SVGResourcesCycleSolver.h"
@@ -51,7 +51,7 @@ void SVGResourcesCache::addResourcesFromRenderObject(RenderObject* object, const
return;
// Put object in cache.
- SVGResources* resources = m_cache.set(object, newResources.release()).iterator->value.get();
+ SVGResources* resources = m_cache.set(object, newResources.release()).storedValue->value.get();
// Run cycle-detection _afterwards_, so self-references can be caught as well.
SVGResourcesCycleSolver solver(object, resources);
@@ -85,10 +85,8 @@ static inline SVGResourcesCache* resourcesCacheFromRenderObject(const RenderObje
{
Document& document = renderer->document();
- SVGDocumentExtensions* extensions = document.accessSVGExtensions();
- ASSERT(extensions);
-
- SVGResourcesCache* cache = extensions->resourcesCache();
+ SVGDocumentExtensions& extensions = document.accessSVGExtensions();
+ SVGResourcesCache* cache = extensions.resourcesCache();
ASSERT(cache);
return cache;
@@ -124,11 +122,11 @@ void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifferen
ASSERT(renderer->node());
ASSERT(renderer->node()->isSVGElement());
- if (diff == StyleDifferenceEqual || !renderer->parent())
+ if (diff.hasNoChange() || !renderer->parent())
return;
// In this case the proper SVGFE*Element will decide whether the modified CSS properties require a relayout or repaint.
- if (renderer->isSVGResourceFilterPrimitive() && (diff == StyleDifferenceRepaint || diff == StyleDifferenceRepaintIfTextOrColorChange))
+ if (renderer->isSVGResourceFilterPrimitive() && !diff.needsLayout())
return;
// Dynamic changes of CSS properties like 'clip-path' may require us to recompute the associated resources for a renderer.
@@ -194,9 +192,9 @@ void SVGResourcesCache::resourceDestroyed(RenderSVGResourceContainer* resource)
// Mark users of destroyed resources as pending resolution based on the id of the old resource.
Element* resourceElement = resource->element();
Element* clientElement = toElement(it->key->node());
- SVGDocumentExtensions* extensions = clientElement->document().accessSVGExtensions();
+ SVGDocumentExtensions& extensions = clientElement->document().accessSVGExtensions();
- extensions->addPendingResource(resourceElement->fastGetAttribute(HTMLNames::idAttr), clientElement);
+ extensions.addPendingResource(resourceElement->fastGetAttribute(HTMLNames::idAttr), clientElement);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.h
index ff5e9f903af..7bf878e7237 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCache.h
@@ -20,7 +20,8 @@
#ifndef SVGResourcesCache_h
#define SVGResourcesCache_h
-#include "core/rendering/style/RenderStyleConstants.h"
+#include "core/rendering/style/StyleDifference.h"
+#include "wtf/FastAllocBase.h"
#include "wtf/HashMap.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.cpp
index efa1b933394..ae7e954fb04 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.cpp
@@ -47,117 +47,83 @@ SVGResourcesCycleSolver::~SVGResourcesCycleSolver()
{
}
-bool SVGResourcesCycleSolver::resourceContainsCycles(RenderObject* renderer) const
-{
- ASSERT(renderer);
-
- // First operate on the resources of the given renderer.
- // <marker id="a"> <path marker-start="url(#b)"/> ...
- // <marker id="b" marker-start="url(#a)"/>
- if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer)) {
- HashSet<RenderSVGResourceContainer*> resourceSet;
- resources->buildSetOfResources(resourceSet);
-
- // Walk all resources and check wheter they reference any resource contained in the resources set.
- HashSet<RenderSVGResourceContainer*>::iterator end = resourceSet.end();
- for (HashSet<RenderSVGResourceContainer*>::iterator it = resourceSet.begin(); it != end; ++it) {
- if (m_allResources.contains(*it))
- return true;
- }
- }
+struct ActiveFrame {
+ typedef SVGResourcesCycleSolver::ResourceSet ResourceSet;
- // Then operate on the child resources of the given renderer.
- // <marker id="a"> <path marker-start="url(#b)"/> ...
- // <marker id="b"> <path marker-start="url(#a)"/> ...
- for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling()) {
- SVGResources* childResources = SVGResourcesCache::cachedResourcesForRenderObject(child);
- if (!childResources)
- continue;
+ ActiveFrame(ResourceSet& activeSet, RenderSVGResourceContainer* resource)
+ : m_activeSet(activeSet)
+ , m_resource(resource)
+ {
+ m_activeSet.add(m_resource);
+ }
+ ~ActiveFrame()
+ {
+ m_activeSet.remove(m_resource);
+ }
- // A child of the given 'resource' contains resources.
- HashSet<RenderSVGResourceContainer*> childSet;
- childResources->buildSetOfResources(childSet);
+ ResourceSet& m_activeSet;
+ RenderSVGResourceContainer* m_resource;
+};
- // Walk all child resources and check wheter they reference any resource contained in the resources set.
- HashSet<RenderSVGResourceContainer*>::iterator end = childSet.end();
- for (HashSet<RenderSVGResourceContainer*>::iterator it = childSet.begin(); it != end; ++it) {
- if (m_allResources.contains(*it))
- return true;
+bool SVGResourcesCycleSolver::resourceContainsCycles(RenderSVGResourceContainer* resource)
+{
+ // If we've traversed this sub-graph before and no cycles were observed, then
+ // reuse that result.
+ if (m_dagCache.contains(resource))
+ return false;
+
+ ActiveFrame frame(m_activeResources, resource);
+
+ RenderObject* node = resource;
+ while (node) {
+ // Skip subtrees which are themselves resources. (They will be
+ // processed - if needed - when they are actually referenced.)
+ if (node != resource && node->isSVGResourceContainer()) {
+ node = node->nextInPreOrderAfterChildren(resource);
+ continue;
}
-
- // Walk children recursively, stop immediately if we found a cycle
- if (resourceContainsCycles(child))
- return true;
+ if (SVGResources* nodeResources = SVGResourcesCache::cachedResourcesForRenderObject(node)) {
+ // Fetch all the resources referenced by |node|.
+ ResourceSet nodeSet;
+ nodeResources->buildSetOfResources(nodeSet);
+
+ // Iterate resources referenced by |node|.
+ ResourceSet::iterator end = nodeSet.end();
+ for (ResourceSet::iterator it = nodeSet.begin(); it != end; ++it) {
+ if (m_activeResources.contains(*it) || resourceContainsCycles(*it))
+ return true;
+ }
+ }
+ node = node->nextInPreOrder(resource);
}
+ // No cycles found in (or from) this resource. Add it to the "DAG cache".
+ m_dagCache.add(resource);
return false;
}
void SVGResourcesCycleSolver::resolveCycles()
{
- ASSERT(m_allResources.isEmpty());
-
-#if DEBUG_CYCLE_DETECTION > 0
- fprintf(stderr, "\nBefore cycle detection:\n");
- m_resources->dump(m_renderer);
-#endif
-
- // Stash all resources into a HashSet for the ease of traversing.
- HashSet<RenderSVGResourceContainer*> localResources;
- m_resources->buildSetOfResources(localResources);
- ASSERT(!localResources.isEmpty());
-
- // Add all parent resource containers to the HashSet.
- HashSet<RenderSVGResourceContainer*> parentResources;
- RenderObject* parent = m_renderer->parent();
- while (parent) {
- if (parent->isSVGResourceContainer())
- parentResources.add(toRenderSVGResourceContainer(parent));
- parent = parent->parent();
- }
+ ASSERT(m_activeResources.isEmpty());
-#if DEBUG_CYCLE_DETECTION > 0
- fprintf(stderr, "\nDetecting wheter any resources references any of following objects:\n");
- {
- fprintf(stderr, "Local resources:\n");
- HashSet<RenderSVGResourceContainer*>::iterator end = localResources.end();
- for (HashSet<RenderSVGResourceContainer*>::iterator it = localResources.begin(); it != end; ++it)
- fprintf(stderr, "|> %s: object=%p (node=%p)\n", (*it)->renderName(), *it, (*it)->node());
-
- fprintf(stderr, "Parent resources:\n");
- end = parentResources.end();
- for (HashSet<RenderSVGResourceContainer*>::iterator it = parentResources.begin(); it != end; ++it)
- fprintf(stderr, "|> %s: object=%p (node=%p)\n", (*it)->renderName(), *it, (*it)->node());
- }
-#endif
-
- // Build combined set of local and parent resources.
- m_allResources = localResources;
- HashSet<RenderSVGResourceContainer*>::iterator end = parentResources.end();
- for (HashSet<RenderSVGResourceContainer*>::iterator it = parentResources.begin(); it != end; ++it)
- m_allResources.add(*it);
-
- // If we're a resource, add ourselves to the HashSet.
+ // If the starting RenderObject is a resource container itself, then add it
+ // to the active set (to break direct self-references.)
if (m_renderer->isSVGResourceContainer())
- m_allResources.add(toRenderSVGResourceContainer(m_renderer));
+ m_activeResources.add(toRenderSVGResourceContainer(m_renderer));
- ASSERT(!m_allResources.isEmpty());
+ ResourceSet localResources;
+ m_resources->buildSetOfResources(localResources);
- // The job of this function is to determine wheter any of the 'resources' associated with the given 'renderer'
- // references us (or wheter any of its kids references us) -> that's a cycle, we need to find and break it.
- end = localResources.end();
- for (HashSet<RenderSVGResourceContainer*>::iterator it = localResources.begin(); it != end; ++it) {
- RenderSVGResourceContainer* resource = *it;
- if (parentResources.contains(resource) || resourceContainsCycles(resource))
- breakCycle(resource);
+ // This performs a depth-first search for a back-edge in all the
+ // (potentially disjoint) graphs formed by the resources referenced by
+ // |m_renderer|.
+ ResourceSet::iterator end = localResources.end();
+ for (ResourceSet::iterator it = localResources.begin(); it != end; ++it) {
+ if (m_activeResources.contains(*it) || resourceContainsCycles(*it))
+ breakCycle(*it);
}
-#if DEBUG_CYCLE_DETECTION > 0
- fprintf(stderr, "\nAfter cycle detection:\n");
- m_resources->dump(m_renderer);
-#endif
-
- m_allResources.clear();
+ m_activeResources.clear();
}
void SVGResourcesCycleSolver::breakCycle(RenderSVGResourceContainer* resourceLeadingToCycle)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.h
index cadaa5a311e..aadd9f6fa54 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGResourcesCycleSolver.h
@@ -37,13 +37,17 @@ public:
void resolveCycles();
+ typedef HashSet<RenderSVGResourceContainer*> ResourceSet;
+
private:
- bool resourceContainsCycles(RenderObject*) const;
+ bool resourceContainsCycles(RenderSVGResourceContainer*);
void breakCycle(RenderSVGResourceContainer*);
RenderObject* m_renderer;
SVGResources* m_resources;
- HashSet<RenderSVGResourceContainer*> m_allResources;
+
+ ResourceSet m_activeResources;
+ ResourceSet m_dagCache;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.cpp
index ec9a953d1b3..4cd80101e37 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.cpp
@@ -24,7 +24,6 @@
#include "config.h"
#include "core/rendering/svg/SVGRootInlineBox.h"
-#include "SVGNames.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
#include "core/rendering/svg/RenderSVGText.h"
#include "core/rendering/svg/SVGInlineFlowBox.h"
@@ -33,15 +32,12 @@
namespace WebCore {
-void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
+void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
{
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
ASSERT(!paintInfo.context->paintingDisabled());
- RenderObject* boxRenderer = renderer();
- ASSERT(boxRenderer);
-
- bool isPrinting = renderer()->document().printing();
+ bool isPrinting = renderer().document().printing();
bool hasSelection = !isPrinting && selectionState() != RenderObject::SelectionNone;
PaintInfo childPaintInfo(paintInfo);
@@ -54,35 +50,29 @@ void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
}
}
- SVGRenderingContext renderingContext(boxRenderer, paintInfo, SVGRenderingContext::SaveGraphicsContext);
+ SVGRenderingContext renderingContext(&renderer(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
if (renderingContext.isRenderingPrepared()) {
- for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
- if (child->isSVGInlineTextBox())
- SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(toSVGInlineTextBox(child)->textRenderer()));
-
- child->paint(paintInfo, LayoutPoint(), 0, 0);
- }
+ for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
+ child->paint(paintInfo, paintOffset, 0, 0);
}
}
-void SVGRootInlineBox::markDirty(bool dirty)
+void SVGRootInlineBox::markDirty()
{
- if (dirty)
- for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
- child->markDirty(true);
- RootInlineBox::markDirty(dirty);
+ for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
+ child->markDirty();
+ RootInlineBox::markDirty();
}
void SVGRootInlineBox::computePerCharacterLayoutInformation()
{
- RenderSVGText* textRoot = toRenderSVGText(block());
- ASSERT(textRoot);
+ RenderSVGText& textRoot = toRenderSVGText(block());
- Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot->layoutAttributes();
+ Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot.layoutAttributes();
if (layoutAttributes.isEmpty())
return;
- if (textRoot->needsReordering())
+ if (textRoot.needsReordering())
reorderValueLists(layoutAttributes);
// Perform SVG text layout phase two (see SVGTextLayoutEngine for details).
@@ -103,24 +93,23 @@ void SVGRootInlineBox::layoutCharactersInTextBoxes(InlineFlowBox* start, SVGText
{
for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
if (child->isSVGInlineTextBox()) {
- ASSERT(child->renderer());
- ASSERT(child->renderer()->isSVGInlineText());
+ ASSERT(child->renderer().isSVGInlineText());
characterLayout.layoutInlineTextBox(toSVGInlineTextBox(child));
} else {
// Skip generated content.
- Node* node = child->renderer()->node();
+ Node* node = child->renderer().node();
if (!node)
continue;
SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
- bool isTextPath = node->hasTagName(SVGNames::textPathTag);
+ bool isTextPath = isSVGTextPathElement(*node);
if (isTextPath) {
// Build text chunks for all <textPath> children, using the line layout algorithm.
// This is needeed as text-anchor is just an additional startOffset for text paths.
SVGTextLayoutEngine lineLayout(characterLayout.layoutAttributes());
layoutCharactersInTextBoxes(flowBox, lineLayout);
- characterLayout.beginTextPathLayout(child->renderer(), lineLayout);
+ characterLayout.beginTextPathLayout(&child->renderer(), lineLayout);
}
layoutCharactersInTextBoxes(flowBox, characterLayout);
@@ -136,8 +125,7 @@ void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRe
for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
FloatRect boxRect;
if (child->isSVGInlineTextBox()) {
- ASSERT(child->renderer());
- ASSERT(child->renderer()->isSVGInlineText());
+ ASSERT(child->renderer().isSVGInlineText());
SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
boxRect = textBox->calculateBoundaries();
@@ -147,7 +135,7 @@ void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRe
textBox->setLogicalHeight(boxRect.height());
} else {
// Skip generated content.
- if (!child->renderer()->node())
+ if (!child->renderer().node())
continue;
SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
@@ -166,18 +154,17 @@ void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRe
void SVGRootInlineBox::layoutRootBox(const FloatRect& childRect)
{
- RenderBlockFlow* parentBlock = block();
- ASSERT(parentBlock);
+ RenderBlockFlow& parentBlock = block();
// Finally, assign the root block position, now that all content is laid out.
LayoutRect boundingRect = enclosingLayoutRect(childRect);
- parentBlock->setLocation(boundingRect.location());
- parentBlock->setSize(boundingRect.size());
+ parentBlock.setLocation(boundingRect.location());
+ parentBlock.setSize(boundingRect.size());
// Position all children relative to the parent block.
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
// Skip generated content.
- if (!child->renderer()->node())
+ if (!child->renderer().node())
continue;
child->adjustPosition(-childRect.x(), -childRect.y());
}
@@ -221,21 +208,11 @@ static inline void swapItemsInLayoutAttributes(SVGTextLayoutAttributes* firstAtt
SVGCharacterDataMap::iterator itLast = lastAttributes->characterDataMap().find(lastPosition + 1);
bool firstPresent = itFirst != firstAttributes->characterDataMap().end();
bool lastPresent = itLast != lastAttributes->characterDataMap().end();
- if (!firstPresent && !lastPresent)
+ // We only want to perform the swap if both inline boxes are absolutely
+ // positioned.
+ if (!firstPresent || !lastPresent)
return;
-
- if (firstPresent && lastPresent) {
- std::swap(itFirst->value, itLast->value);
- return;
- }
-
- if (firstPresent && !lastPresent) {
- lastAttributes->characterDataMap().set(lastPosition + 1, itFirst->value);
- return;
- }
-
- // !firstPresent && lastPresent
- firstAttributes->characterDataMap().set(firstPosition + 1, itLast->value);
+ std::swap(itFirst->value, itLast->value);
}
static inline void findFirstAndLastAttributesInVector(Vector<SVGTextLayoutAttributes*>& attributes, RenderSVGInlineText* firstContext, RenderSVGInlineText* lastContext,
@@ -282,12 +259,12 @@ static inline void reverseInlineBoxRangeAndValueListsIfNeeded(void* userData, Ve
// Reordering is only necessary for BiDi text that is _absolutely_ positioned.
if (firstTextBox->len() == 1 && firstTextBox->len() == lastTextBox->len()) {
- RenderSVGInlineText* firstContext = toRenderSVGInlineText(firstTextBox->textRenderer());
- RenderSVGInlineText* lastContext = toRenderSVGInlineText(lastTextBox->textRenderer());
+ RenderSVGInlineText& firstContext = toRenderSVGInlineText(firstTextBox->textRenderer());
+ RenderSVGInlineText& lastContext = toRenderSVGInlineText(lastTextBox->textRenderer());
SVGTextLayoutAttributes* firstAttributes = 0;
SVGTextLayoutAttributes* lastAttributes = 0;
- findFirstAndLastAttributesInVector(attributes, firstContext, lastContext, firstAttributes, lastAttributes);
+ findFirstAndLastAttributesInVector(attributes, &firstContext, &lastContext, firstAttributes, lastAttributes);
swapItemsInLayoutAttributes(firstAttributes, lastAttributes, firstTextBox->start(), lastTextBox->start());
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.h
index efbe2f6b79b..862c9b24a4e 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGRootInlineBox.h
@@ -29,24 +29,22 @@
namespace WebCore {
-class SVGInlineTextBox;
-
class SVGRootInlineBox FINAL : public RootInlineBox {
public:
- SVGRootInlineBox(RenderBlockFlow* block)
+ SVGRootInlineBox(RenderBlockFlow& block)
: RootInlineBox(block)
, m_logicalHeight(0)
{
}
- virtual bool isSVGRootInlineBox() const OVERRIDE FINAL { return true; }
+ virtual bool isSVGRootInlineBox() const OVERRIDE { return true; }
- virtual float virtualLogicalHeight() const OVERRIDE FINAL { return m_logicalHeight; }
+ virtual float virtualLogicalHeight() const OVERRIDE { return m_logicalHeight; }
void setLogicalHeight(float height) { m_logicalHeight = height; }
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE FINAL;
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
- virtual void markDirty(bool dirty = true) OVERRIDE FINAL;
+ virtual void markDirty() OVERRIDE;
void computePerCharacterLayoutInformation();
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextChunkBuilder.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextChunkBuilder.cpp
index d26d868fff1..488fbd4bddd 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextChunkBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextChunkBuilder.cpp
@@ -91,10 +91,9 @@ void SVGTextChunkBuilder::addTextChunk(Vector<SVGInlineTextBox*>& lineLayoutBoxe
SVGInlineTextBox* textBox = lineLayoutBoxes[boxStart];
ASSERT(textBox);
- RenderSVGInlineText* textRenderer = toRenderSVGInlineText(textBox->textRenderer());
- ASSERT(textRenderer);
+ RenderSVGInlineText& textRenderer = toRenderSVGInlineText(textBox->textRenderer());
- const RenderStyle* style = textRenderer->style();
+ const RenderStyle* style = toRenderSVGInlineText(textBox->textRenderer()).style();
ASSERT(style);
const SVGRenderStyle* svgStyle = style->svgStyle();
@@ -125,11 +124,14 @@ void SVGTextChunkBuilder::addTextChunk(Vector<SVGInlineTextBox*>& lineLayoutBoxe
// Handle 'lengthAdjust' property.
float desiredTextLength = 0;
- if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textRenderer->parent())) {
+ if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textRenderer.parent())) {
SVGLengthContext lengthContext(textContentElement);
- desiredTextLength = textContentElement->specifiedTextLength().value(lengthContext);
+ if (textContentElement->textLengthIsSpecifiedByUser())
+ desiredTextLength = textContentElement->textLength()->currentValue()->value(lengthContext);
+ else
+ desiredTextLength = 0;
- switch (textContentElement->lengthAdjustCurrentValue()) {
+ switch (textContentElement->lengthAdjust()->currentValue()->enumValue()) {
case SVGLengthAdjustUnknown:
break;
case SVGLengthAdjustSpacing:
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
index 7c65a7e55e6..cbf018dc87a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
@@ -23,6 +23,7 @@
#include "core/rendering/svg/RenderSVGInlineText.h"
#include "core/rendering/svg/RenderSVGText.h"
+#include "core/rendering/svg/SVGTextMetricsBuilder.h"
#include "core/svg/SVGTextPositioningElement.h"
namespace WebCore {
@@ -53,7 +54,7 @@ void SVGTextLayoutAttributesBuilder::buildLayoutAttributesForTextRenderer(Render
buildCharacterDataMap(textRoot);
}
- m_metricsBuilder.buildMetricsAndLayoutAttributes(textRoot, text, m_characterDataMap);
+ SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(textRoot, text, m_characterDataMap);
}
bool SVGTextLayoutAttributesBuilder::buildLayoutAttributesForForSubtree(RenderSVGText* textRoot)
@@ -72,14 +73,14 @@ bool SVGTextLayoutAttributesBuilder::buildLayoutAttributesForForSubtree(RenderSV
return false;
buildCharacterDataMap(textRoot);
- m_metricsBuilder.buildMetricsAndLayoutAttributes(textRoot, 0, m_characterDataMap);
+ SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(textRoot, 0, m_characterDataMap);
return true;
}
void SVGTextLayoutAttributesBuilder::rebuildMetricsForTextRenderer(RenderSVGInlineText* text)
{
ASSERT(text);
- m_metricsBuilder.measureTextRenderer(text);
+ SVGTextMetricsBuilder::measureTextRenderer(text);
}
static inline void processRenderSVGInlineText(RenderSVGInlineText* text, unsigned& atCharacter, UChar& lastCharacter)
@@ -104,7 +105,7 @@ void SVGTextLayoutAttributesBuilder::collectTextPositioningElements(RenderObject
{
ASSERT(!start->isSVGText() || m_textPositions.isEmpty());
- for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = start->slowFirstChild(); child; child = child->nextSibling()) {
if (child->isSVGInlineText()) {
processRenderSVGInlineText(toRenderSVGInlineText(child), m_textLength, lastCharacter);
continue;
@@ -163,43 +164,43 @@ void SVGTextLayoutAttributesBuilder::buildCharacterDataMap(RenderSVGText* textRo
static inline void updateCharacterData(unsigned i, float& lastRotation, SVGCharacterData& data, const SVGLengthContext& lengthContext, const SVGLengthList* xList, const SVGLengthList* yList, const SVGLengthList* dxList, const SVGLengthList* dyList, const SVGNumberList* rotateList)
{
if (xList)
- data.x = xList->at(i).value(lengthContext);
+ data.x = xList->at(i)->value(lengthContext);
if (yList)
- data.y = yList->at(i).value(lengthContext);
+ data.y = yList->at(i)->value(lengthContext);
if (dxList)
- data.dx = dxList->at(i).value(lengthContext);
+ data.dx = dxList->at(i)->value(lengthContext);
if (dyList)
- data.dy = dyList->at(i).value(lengthContext);
+ data.dy = dyList->at(i)->value(lengthContext);
if (rotateList) {
- data.rotate = rotateList->at(i).value();
+ data.rotate = rotateList->at(i)->value();
lastRotation = data.rotate;
}
}
void SVGTextLayoutAttributesBuilder::fillCharacterDataMap(const TextPosition& position)
{
- const SVGLengthList& xList = position.element->xCurrentValue();
- const SVGLengthList& yList = position.element->yCurrentValue();
- const SVGLengthList& dxList = position.element->dxCurrentValue();
- const SVGLengthList& dyList = position.element->dyCurrentValue();
- const SVGNumberList& rotateList = position.element->rotateCurrentValue();
-
- unsigned xListSize = xList.size();
- unsigned yListSize = yList.size();
- unsigned dxListSize = dxList.size();
- unsigned dyListSize = dyList.size();
- unsigned rotateListSize = rotateList.size();
+ RefPtr<SVGLengthList> xList = position.element->x()->currentValue();
+ RefPtr<SVGLengthList> yList = position.element->y()->currentValue();
+ RefPtr<SVGLengthList> dxList = position.element->dx()->currentValue();
+ RefPtr<SVGLengthList> dyList = position.element->dy()->currentValue();
+ RefPtr<SVGNumberList> rotateList = position.element->rotate()->currentValue();
+
+ unsigned xListSize = xList->length();
+ unsigned yListSize = yList->length();
+ unsigned dxListSize = dxList->length();
+ unsigned dyListSize = dyList->length();
+ unsigned rotateListSize = rotateList->length();
if (!xListSize && !yListSize && !dxListSize && !dyListSize && !rotateListSize)
return;
float lastRotation = SVGTextLayoutAttributes::emptyValue();
SVGLengthContext lengthContext(position.element);
for (unsigned i = 0; i < position.length; ++i) {
- const SVGLengthList* xListPtr = i < xListSize ? &xList : 0;
- const SVGLengthList* yListPtr = i < yListSize ? &yList : 0;
- const SVGLengthList* dxListPtr = i < dxListSize ? &dxList : 0;
- const SVGLengthList* dyListPtr = i < dyListSize ? &dyList : 0;
- const SVGNumberList* rotateListPtr = i < rotateListSize ? &rotateList : 0;
+ const SVGLengthList* xListPtr = i < xListSize ? xList.get() : 0;
+ const SVGLengthList* yListPtr = i < yListSize ? yList.get() : 0;
+ const SVGLengthList* dxListPtr = i < dxListSize ? dxList.get() : 0;
+ const SVGLengthList* dyListPtr = i < dyListSize ? dyList.get() : 0;
+ const SVGNumberList* rotateListPtr = i < rotateListSize ? rotateList.get() : 0;
if (!xListPtr && !yListPtr && !dxListPtr && !dyListPtr && !rotateListPtr)
break;
@@ -218,7 +219,7 @@ void SVGTextLayoutAttributesBuilder::fillCharacterDataMap(const TextPosition& po
if (lastRotation == SVGTextLayoutAttributes::emptyValue())
return;
- for (unsigned i = rotateList.size(); i < position.length; ++i) {
+ for (unsigned i = rotateList->length(); i < position.length; ++i) {
SVGCharacterDataMap::iterator it = m_characterDataMap.find(position.start + i + 1);
if (it == m_characterDataMap.end()) {
SVGCharacterData data;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h
index d92c125f47f..82d2d064660 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h
@@ -20,7 +20,7 @@
#ifndef SVGTextLayoutAttributesBuilder_h
#define SVGTextLayoutAttributesBuilder_h
-#include "core/rendering/svg/SVGTextMetricsBuilder.h"
+#include "core/rendering/svg/SVGTextLayoutAttributes.h"
#include "wtf/Vector.h"
namespace WebCore {
@@ -73,7 +73,6 @@ private:
unsigned m_textLength;
Vector<TextPosition> m_textPositions;
SVGCharacterDataMap m_characterDataMap;
- SVGTextMetricsBuilder m_metricsBuilder;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
index 0ade353f4a7..fc5dc792329 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
@@ -47,6 +47,7 @@ SVGTextLayoutEngine::SVGTextLayoutEngine(Vector<SVGTextLayoutAttributes*>& layou
, m_dy(0)
, m_isVerticalText(false)
, m_inPathLayout(false)
+ , m_textPathCalculator(0)
, m_textPathLength(0)
, m_textPathCurrentOffset(0)
, m_textPathSpacing(0)
@@ -148,7 +149,7 @@ bool SVGTextLayoutEngine::parentDefinesTextLength(RenderObject* parent) const
while (currentParent) {
if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(currentParent)) {
SVGLengthContext lengthContext(textContentElement);
- if (textContentElement->lengthAdjustCurrentValue() == SVGLengthAdjustSpacing && textContentElement->specifiedTextLength().value(lengthContext) > 0)
+ if (textContentElement->lengthAdjust()->currentValue()->enumValue() == SVGLengthAdjustSpacing && textContentElement->textLengthIsSpecifiedByUser())
return true;
}
@@ -169,11 +170,12 @@ void SVGTextLayoutEngine::beginTextPathLayout(RenderObject* object, SVGTextLayou
m_inPathLayout = true;
RenderSVGTextPath* textPath = toRenderSVGTextPath(object);
- m_textPath = textPath->layoutPath();
- if (m_textPath.isEmpty())
+ Path path = textPath->layoutPath();
+ if (path.isEmpty())
return;
+ m_textPathCalculator = new Path::PositionCalculator(path);
m_textPathStartOffset = textPath->startOffset();
- m_textPathLength = m_textPath.length();
+ m_textPathLength = path.length();
if (m_textPathStartOffset > 0 && m_textPathStartOffset <= 1)
m_textPathStartOffset *= m_textPathLength;
@@ -206,8 +208,11 @@ void SVGTextLayoutEngine::beginTextPathLayout(RenderObject* object, SVGTextLayou
if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textPath)) {
SVGLengthContext lengthContext(textContentElement);
- lengthAdjust = textContentElement->lengthAdjustCurrentValue();
- desiredTextLength = textContentElement->specifiedTextLength().value(lengthContext);
+ lengthAdjust = textContentElement->lengthAdjust()->currentValue()->enumValue();
+ if (textContentElement->textLengthIsSpecifiedByUser())
+ desiredTextLength = textContentElement->textLength()->currentValue()->value(lengthContext);
+ else
+ desiredTextLength = 0;
}
if (!desiredTextLength)
@@ -222,7 +227,8 @@ void SVGTextLayoutEngine::beginTextPathLayout(RenderObject* object, SVGTextLayou
void SVGTextLayoutEngine::endTextPathLayout()
{
m_inPathLayout = false;
- m_textPath = Path();
+ delete m_textPathCalculator;
+ m_textPathCalculator = 0;
m_textPathLength = 0;
m_textPathStartOffset = 0;
m_textPathCurrentOffset = 0;
@@ -234,18 +240,17 @@ void SVGTextLayoutEngine::layoutInlineTextBox(SVGInlineTextBox* textBox)
{
ASSERT(textBox);
- RenderSVGInlineText* text = toRenderSVGInlineText(textBox->textRenderer());
- ASSERT(text);
- ASSERT(text->parent());
- ASSERT(text->parent()->node());
- ASSERT(text->parent()->node()->isSVGElement());
+ RenderSVGInlineText& text = toRenderSVGInlineText(textBox->textRenderer());
+ ASSERT(text.parent());
+ ASSERT(text.parent()->node());
+ ASSERT(text.parent()->node()->isSVGElement());
- const RenderStyle* style = text->style();
+ const RenderStyle* style = text.style();
ASSERT(style);
textBox->clearTextFragments();
m_isVerticalText = style->svgStyle()->isVerticalWritingMode();
- layoutTextOnLineOrPath(textBox, text, style);
+ layoutTextOnLineOrPath(textBox, &text, style);
if (m_inPathLayout) {
m_pathLayoutBoxes.append(textBox);
@@ -421,7 +426,7 @@ void SVGTextLayoutEngine::advanceToNextVisualCharacter(const SVGTextMetrics& vis
void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, RenderSVGInlineText* text, const RenderStyle* style)
{
- if (m_inPathLayout && m_textPath.isEmpty())
+ if (m_inPathLayout && !m_textPathCalculator)
return;
SVGElement* lengthContext = toSVGElement(text->parent()->node());
@@ -440,7 +445,7 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, Rend
const Font& font = style->font();
- SVGTextLayoutEngineSpacing spacingLayout(font);
+ SVGTextLayoutEngineSpacing spacingLayout(font, style->effectiveZoom());
SVGTextLayoutEngineBaseline baselineLayout(font);
bool didStartTextFragment = false;
@@ -505,8 +510,8 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, Rend
// Calculate SVG Fonts kerning, if needed.
float kerning = spacingLayout.calculateSVGKerning(m_isVerticalText, visualMetrics.glyph());
- // Calculate CSS 'kerning', 'letter-spacing' and 'word-spacing' for next character, if needed.
- float spacing = spacingLayout.calculateCSSKerningAndSpacing(svgStyle, lengthContext, currentCharacter);
+ // Calculate CSS 'letter-spacing' and 'word-spacing' for next character, if needed.
+ float spacing = spacingLayout.calculateCSSSpacing(currentCharacter);
float textPathOffset = 0;
if (m_inPathLayout) {
@@ -552,14 +557,11 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, Rend
if (textPathOffset > m_textPathLength)
break;
- bool ok = false;
- FloatPoint point = m_textPath.pointAtLength(textPathOffset, ok);
- ASSERT(ok);
-
+ FloatPoint point;
+ bool ok = m_textPathCalculator->pointAndNormalAtLength(textPathOffset, point, angle);
+ ASSERT_UNUSED(ok, ok);
x = point.x();
y = point.y();
- angle = m_textPath.normalAngleAtLength(textPathOffset, ok);
- ASSERT(ok);
// For vertical text on path, the actual angle has to be rotated 90 degrees anti-clockwise, not the orientation angle!
if (m_isVerticalText)
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.h
index 3ae5fa09087..b3c91a445b2 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngine.h
@@ -32,9 +32,7 @@ namespace WebCore {
class RenderObject;
class RenderStyle;
class RenderSVGInlineText;
-class SVGElement;
class SVGInlineTextBox;
-class SVGRenderStyle;
// SVGTextLayoutEngine performs the second layout phase for SVG text.
//
@@ -96,7 +94,7 @@ private:
bool m_inPathLayout;
// Text on path layout
- Path m_textPath;
+ Path::PositionCalculator* m_textPathCalculator;
float m_textPathLength;
float m_textPathStartOffset;
float m_textPathCurrentOffset;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineBaseline.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineBaseline.cpp
index 3825b4b1220..95c3beb137c 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineBaseline.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineBaseline.cpp
@@ -38,12 +38,12 @@ SVGTextLayoutEngineBaseline::SVGTextLayoutEngineBaseline(const Font& font)
float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle* style, SVGElement* contextElement) const
{
if (style->baselineShift() == BS_LENGTH) {
- SVGLength baselineShiftValueLength = style->baselineShiftValue();
- if (baselineShiftValueLength.unitType() == LengthTypePercentage)
- return baselineShiftValueLength.valueAsPercentage() * m_font.pixelSize();
+ RefPtr<SVGLength> baselineShiftValueLength = style->baselineShiftValue();
+ if (baselineShiftValueLength->unitType() == LengthTypePercentage)
+ return baselineShiftValueLength->valueAsPercentage() * m_font.fontDescription().computedPixelSize();
SVGLengthContext lengthContext(contextElement);
- return baselineShiftValueLength.value(lengthContext);
+ return baselineShiftValueLength->value(lengthContext);
}
switch (style->baselineShift()) {
@@ -160,7 +160,7 @@ float SVGTextLayoutEngineBaseline::calculateGlyphOrientationAngle(bool isVertica
case GO_AUTO: {
// Spec: Fullwidth ideographic and fullwidth Latin text will be set with a glyph-orientation of 0-degrees.
// Text which is not fullwidth will be set with a glyph-orientation of 90-degrees.
- unsigned int unicodeRange = findCharUnicodeRange(character);
+ unsigned unicodeRange = findCharUnicodeRange(character);
if (unicodeRange == cRangeSetLatin || unicodeRange == cRangeArabic)
return 90;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp
index 6f68e475f1e..e93bb48b41a 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp
@@ -21,8 +21,8 @@
#include "core/rendering/svg/SVGTextLayoutEngineSpacing.h"
-#include "core/rendering/style/SVGRenderStyle.h"
#include "core/svg/SVGLengthContext.h"
+#include "platform/fonts/Character.h"
#include "platform/fonts/Font.h"
#if ENABLE(SVG_FONTS)
@@ -33,18 +33,23 @@
namespace WebCore {
-SVGTextLayoutEngineSpacing::SVGTextLayoutEngineSpacing(const Font& font)
+SVGTextLayoutEngineSpacing::SVGTextLayoutEngineSpacing(const Font& font, float effectiveZoom)
: m_font(font)
, m_lastCharacter(0)
+ , m_effectiveZoom(effectiveZoom)
+#if ENABLE(SVG_FONTS)
+ , m_lastGlyph(0)
+#endif
{
+ ASSERT(m_effectiveZoom);
}
-float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, const SVGTextMetrics::Glyph& currentGlyph)
+float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, Glyph currentGlyph)
{
#if ENABLE(SVG_FONTS)
const SimpleFontData* fontData = m_font.primaryFont();
if (!fontData->isSVGFont()) {
- m_lastGlyph.isValid = false;
+ m_lastGlyph = 0;
return 0;
}
@@ -58,50 +63,44 @@ float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, const
SVGFontElement* svgFont = svgFontFace->associatedFontElement();
if (!svgFont) {
- m_lastGlyph.isValid = false;
+ m_lastGlyph = 0;
return 0;
}
float kerning = 0;
- if (m_lastGlyph.isValid) {
+ if (m_lastGlyph) {
if (isVerticalText)
- kerning = svgFont->verticalKerningForPairOfStringsAndGlyphs(m_lastGlyph.unicodeString, m_lastGlyph.name, currentGlyph.unicodeString, currentGlyph.name);
+ kerning = svgFont->verticalKerningForPairOfGlyphs(m_lastGlyph, currentGlyph);
else
- kerning = svgFont->horizontalKerningForPairOfStringsAndGlyphs(m_lastGlyph.unicodeString, m_lastGlyph.name, currentGlyph.unicodeString, currentGlyph.name);
+ kerning = svgFont->horizontalKerningForPairOfGlyphs(m_lastGlyph, currentGlyph);
+
+ kerning *= m_font.fontDescription().computedSize() / m_font.fontMetrics().unitsPerEm();
}
m_lastGlyph = currentGlyph;
- m_lastGlyph.isValid = true;
- kerning *= m_font.size() / m_font.fontMetrics().unitsPerEm();
return kerning;
#else
- return false;
+ return 0;
#endif
}
-float SVGTextLayoutEngineSpacing::calculateCSSKerningAndSpacing(const SVGRenderStyle* style, SVGElement* contextElement, UChar currentCharacter)
+float SVGTextLayoutEngineSpacing::calculateCSSSpacing(UChar currentCharacter)
{
- float kerning = 0;
- SVGLength kerningLength = style->kerning();
- if (kerningLength.unitType() == LengthTypePercentage)
- kerning = kerningLength.valueAsPercentage() * m_font.pixelSize();
- else {
- SVGLengthContext lengthContext(contextElement);
- kerning = kerningLength.value(lengthContext);
- }
-
UChar lastCharacter = m_lastCharacter;
m_lastCharacter = currentCharacter;
- if (!kerning && !m_font.letterSpacing() && !m_font.wordSpacing())
+ if (!m_font.fontDescription().letterSpacing() && !m_font.fontDescription().wordSpacing())
return 0;
- float spacing = m_font.letterSpacing() + kerning;
- if (currentCharacter && lastCharacter && m_font.wordSpacing()) {
- if (Font::treatAsSpace(currentCharacter) && !Font::treatAsSpace(lastCharacter))
- spacing += m_font.wordSpacing();
+ float spacing = m_font.fontDescription().letterSpacing();
+ if (currentCharacter && lastCharacter && m_font.fontDescription().wordSpacing()) {
+ if (Character::treatAsSpace(currentCharacter) && !Character::treatAsSpace(lastCharacter))
+ spacing += m_font.fontDescription().wordSpacing();
}
+ if (m_effectiveZoom != 1)
+ spacing = spacing / m_effectiveZoom;
+
return spacing;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h
index 5cc8bec5533..8618e246dd4 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h
@@ -25,24 +25,23 @@
namespace WebCore {
class Font;
-class SVGRenderStyle;
-class SVGElement;
-// Helper class used by SVGTextLayoutEngine to handle 'kerning' / 'letter-spacing' and 'word-spacing'.
+// Helper class used by SVGTextLayoutEngine to handle 'letter-spacing' and 'word-spacing'.
class SVGTextLayoutEngineSpacing {
WTF_MAKE_NONCOPYABLE(SVGTextLayoutEngineSpacing);
public:
- SVGTextLayoutEngineSpacing(const Font&);
+ SVGTextLayoutEngineSpacing(const Font&, float effectiveZoom);
- float calculateSVGKerning(bool isVerticalText, const SVGTextMetrics::Glyph& currentGlyph);
- float calculateCSSKerningAndSpacing(const SVGRenderStyle*, SVGElement* lengthContext, UChar currentCharacter);
+ float calculateSVGKerning(bool isVerticalText, Glyph currentGlyph);
+ float calculateCSSSpacing(UChar currentCharacter);
private:
const Font& m_font;
UChar m_lastCharacter;
+ float m_effectiveZoom;
#if ENABLE(SVG_FONTS)
- SVGTextMetrics::Glyph m_lastGlyph;
+ Glyph m_lastGlyph;
#endif
};
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.cpp
index 26c82dbec27..3ab52797f77 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.cpp
@@ -30,6 +30,7 @@ SVGTextMetrics::SVGTextMetrics()
: m_width(0)
, m_height(0)
, m_length(0)
+ , m_glyph(0)
{
}
@@ -37,6 +38,7 @@ SVGTextMetrics::SVGTextMetrics(SVGTextMetrics::MetricsType)
: m_width(0)
, m_height(0)
, m_length(1)
+ , m_glyph(0)
{
}
@@ -51,18 +53,21 @@ SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* textRenderer, const TextRun&
int length = 0;
// Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
- m_width = scaledFont.width(run, length, m_glyph.name) / scalingFactor;
+ m_width = scaledFont.width(run, length, m_glyph) / scalingFactor;
m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
- m_glyph.unicodeString = run.is8Bit() ? String(run.characters8(), length) : String(run.characters16(), length);
- m_glyph.isValid = true;
-
ASSERT(length >= 0);
m_length = static_cast<unsigned>(length);
}
TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned position, unsigned length)
{
+ ASSERT(text->style());
+ return constructTextRun(text, position, length, text->style()->direction());
+}
+
+TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned position, unsigned length, TextDirection textDirection)
+{
RenderStyle* style = text->style();
ASSERT(style);
@@ -71,7 +76,7 @@ TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned pos
, 0 // xPos, only relevant with allowTabs=true
, 0 // padding, only relevant for justified text, not relevant for SVG
, TextRun::AllowTrailingExpansion
- , style->direction()
+ , textDirection
, isOverride(style->unicodeBidi()) /* directionalOverride */);
if (length) {
@@ -95,13 +100,19 @@ TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, unsigned pos
return run;
}
+SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length, TextDirection textDirection)
+{
+ ASSERT(text);
+ return SVGTextMetrics(text, constructTextRun(text, position, length, textDirection));
+}
+
SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length)
{
ASSERT(text);
return SVGTextMetrics(text, constructTextRun(text, position, length));
}
-SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* text, unsigned position, unsigned length, float width, const String& glyphName)
+SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* text, unsigned position, unsigned length, float width, Glyph glyphNameGlyphId)
{
ASSERT(text);
@@ -111,11 +122,7 @@ SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* text, unsigned position, uns
m_width = width / scalingFactor;
m_height = text->scaledFont().fontMetrics().floatHeight() / scalingFactor;
- if (needsContext) {
- m_glyph.isValid = true;
- m_glyph.unicodeString = text->substring(position, length);
- m_glyph.name = glyphName;
- }
+ m_glyph = needsContext ? glyphNameGlyphId : 0;
m_length = length;
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.h
index 362933997ed..3c04901e2cf 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetrics.h
@@ -20,12 +20,13 @@
#ifndef SVGTextMetrics_h
#define SVGTextMetrics_h
+#include "platform/fonts/Glyph.h"
+#include "platform/text/TextDirection.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
class RenderSVGInlineText;
-class SVGTextLayoutAttributes;
class TextRun;
class SVGTextMetrics {
@@ -36,12 +37,16 @@ public:
SVGTextMetrics();
SVGTextMetrics(MetricsType);
- SVGTextMetrics(RenderSVGInlineText*, unsigned position, unsigned length, float width, const String& glyphName);
+ SVGTextMetrics(RenderSVGInlineText*, unsigned position, unsigned length, float width, Glyph glyphNameGlyphId);
+ // FIXME: Migrate away from these to the two below.
static SVGTextMetrics measureCharacterRange(RenderSVGInlineText*, unsigned position, unsigned length);
static TextRun constructTextRun(RenderSVGInlineText*, unsigned position, unsigned length);
- bool isEmpty() const { return !m_width && !m_height && !m_glyph.isValid && m_length == 1; }
+ static SVGTextMetrics measureCharacterRange(RenderSVGInlineText*, unsigned position, unsigned length, TextDirection);
+ static TextRun constructTextRun(RenderSVGInlineText*, unsigned position, unsigned length, TextDirection);
+
+ bool isEmpty() const { return !m_width && !m_height && m_length <= 1; }
float width() const { return m_width; }
void setWidth(float width) { m_width = width; }
@@ -49,19 +54,8 @@ public:
float height() const { return m_height; }
unsigned length() const { return m_length; }
- struct Glyph {
- Glyph()
- : isValid(false)
- {
- }
-
- bool isValid;
- String name;
- String unicodeString;
- };
-
// Only useful when measuring individual characters, to lookup ligatures.
- const Glyph& glyph() const { return m_glyph; }
+ Glyph glyph() const { return m_glyph; }
private:
SVGTextMetrics(RenderSVGInlineText*, const TextRun&);
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
index 46a27979e9d..eaaa9361d19 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
@@ -21,186 +21,238 @@
#include "core/rendering/svg/SVGTextMetricsBuilder.h"
+#include "core/rendering/svg/RenderSVGInline.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
#include "core/rendering/svg/RenderSVGText.h"
+#include "core/rendering/svg/SVGTextMetrics.h"
+#include "platform/fonts/GlyphBuffer.h"
+#include "platform/fonts/WidthIterator.h"
+#include "platform/text/BidiCharacterRun.h"
+#include "platform/text/BidiResolver.h"
+#include "platform/text/TextDirection.h"
+#include "platform/text/TextPath.h"
+#include "platform/text/TextRun.h"
+#include "platform/text/TextRunIterator.h"
+#include "wtf/Vector.h"
namespace WebCore {
-SVGTextMetricsBuilder::SVGTextMetricsBuilder()
- : m_text(0)
- , m_run(static_cast<const UChar*>(0), 0)
- , m_textPosition(0)
+class SVGTextMetricsCalculator {
+public:
+ SVGTextMetricsCalculator(RenderSVGInlineText*);
+ ~SVGTextMetricsCalculator();
+
+ SVGTextMetrics computeMetricsForCharacter(unsigned textPosition);
+ unsigned textLength() const { return static_cast<unsigned>(m_run.charactersLength()); }
+
+ bool characterStartsSurrogatePair(unsigned textPosition) const
+ {
+ return U16_IS_LEAD(m_run[textPosition]) && textPosition + 1 < textLength() && U16_IS_TRAIL(m_run[textPosition + 1]);
+ }
+ bool characterIsWhiteSpace(unsigned textPosition) const
+ {
+ return m_run[textPosition] == ' ';
+ }
+
+private:
+ void setupBidiRuns();
+ SVGTextMetrics computeMetricsForCharacterSimple(unsigned textPosition);
+ SVGTextMetrics computeMetricsForCharacterComplex(unsigned textPosition);
+
+ RenderSVGInlineText* m_text;
+ BidiCharacterRun* m_bidiRun;
+ TextRun m_run;
+ BidiResolver<TextRunIterator, BidiCharacterRun> m_bidiResolver;
+ bool m_isComplexText;
+ float m_totalWidth;
+ TextDirection m_textDirection;
+
+ // Simple text only.
+ OwnPtr<WidthIterator> m_simpleWidthIterator;
+};
+
+SVGTextMetricsCalculator::SVGTextMetricsCalculator(RenderSVGInlineText* text)
+ : m_text(text)
+ , m_bidiRun(0)
+ , m_run(SVGTextMetrics::constructTextRun(text, 0, text->textLength()))
, m_isComplexText(false)
, m_totalWidth(0)
{
+ const Font& scaledFont = text->scaledFont();
+ CodePath codePath = scaledFont.codePath(m_run);
+ m_isComplexText = codePath == ComplexPath;
+ m_run.setCharacterScanForCodePath(!m_isComplexText);
+
+ if (!m_isComplexText)
+ m_simpleWidthIterator = adoptPtr(new WidthIterator(&scaledFont, m_run));
+ else
+ setupBidiRuns();
}
-inline bool SVGTextMetricsBuilder::currentCharacterStartsSurrogatePair() const
+SVGTextMetricsCalculator::~SVGTextMetricsCalculator()
{
- return U16_IS_LEAD(m_run[m_textPosition]) && int(m_textPosition + 1) < m_run.charactersLength() && U16_IS_TRAIL(m_run[m_textPosition + 1]);
+ if (m_bidiRun)
+ m_bidiResolver.runs().deleteRuns();
}
-bool SVGTextMetricsBuilder::advance()
+void SVGTextMetricsCalculator::setupBidiRuns()
{
- m_textPosition += m_currentMetrics.length();
- if (int(m_textPosition) >= m_run.charactersLength())
- return false;
-
- if (m_isComplexText)
- advanceComplexText();
- else
- advanceSimpleText();
+ RenderStyle* style = m_text->style();
+ m_textDirection = style->direction();
+ if (isOverride(style->unicodeBidi()))
+ return;
- return m_currentMetrics.length() > 0;
+ BidiStatus status(LTR, false);
+ status.last = status.lastStrong = WTF::Unicode::OtherNeutral;
+ m_bidiResolver.setStatus(status);
+ m_bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&m_run, 0));
+ const bool hardLineBreak = false;
+ const bool reorderRuns = false;
+ m_bidiResolver.createBidiRunsForLine(TextRunIterator(&m_run, m_run.length()), NoVisualOverride, hardLineBreak, reorderRuns);
+ BidiRunList<BidiCharacterRun>& bidiRuns = m_bidiResolver.runs();
+ m_bidiRun = bidiRuns.firstRun();
}
-void SVGTextMetricsBuilder::advanceSimpleText()
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterSimple(unsigned textPosition)
{
GlyphBuffer glyphBuffer;
- unsigned metricsLength = m_simpleWidthIterator->advance(m_textPosition + 1, &glyphBuffer);
- if (!metricsLength) {
- m_currentMetrics = SVGTextMetrics();
- return;
- }
+ unsigned metricsLength = m_simpleWidthIterator->advance(textPosition + 1, &glyphBuffer);
+ if (!metricsLength)
+ return SVGTextMetrics();
float currentWidth = m_simpleWidthIterator->runWidthSoFar() - m_totalWidth;
m_totalWidth = m_simpleWidthIterator->runWidthSoFar();
-#if ENABLE(SVG_FONTS)
- m_currentMetrics = SVGTextMetrics(m_text, m_textPosition, metricsLength, currentWidth, m_simpleWidthIterator->lastGlyphName());
-#else
- m_currentMetrics = SVGTextMetrics(m_text, m_textPosition, metricsLength, currentWidth, emptyString());
-#endif
+ Glyph glyphId = glyphBuffer.glyphAt(0);
+ return SVGTextMetrics(m_text, textPosition, metricsLength, currentWidth, glyphId);
}
-void SVGTextMetricsBuilder::advanceComplexText()
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterComplex(unsigned textPosition)
{
- unsigned metricsLength = currentCharacterStartsSurrogatePair() ? 2 : 1;
- m_currentMetrics = SVGTextMetrics::measureCharacterRange(m_text, m_textPosition, metricsLength);
- m_complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, 0, m_textPosition + metricsLength);
- ASSERT(m_currentMetrics.length() == metricsLength);
+ unsigned metricsLength = characterStartsSurrogatePair(textPosition) ? 2 : 1;
+ SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, textPosition, metricsLength, m_textDirection);
+ ASSERT(metrics.length() == metricsLength);
+ unsigned startPosition = m_bidiRun ? m_bidiRun->start() : 0;
+ ASSERT(startPosition <= textPosition);
+ SVGTextMetrics complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, startPosition, textPosition - startPosition + metricsLength, m_textDirection);
// Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken
// when rendering the glyph "in context" (with it's surrounding characters) it changes due to shaping.
// So whenever currentWidth != currentMetrics.width(), we are processing a text run whose length is
// not equal to the sum of the individual lengths of the glyphs, when measuring them isolated.
- float currentWidth = m_complexStartToCurrentMetrics.width() - m_totalWidth;
- if (currentWidth != m_currentMetrics.width())
- m_currentMetrics.setWidth(currentWidth);
+ float currentWidth = complexStartToCurrentMetrics.width() - m_totalWidth;
+ if (currentWidth != metrics.width())
+ metrics.setWidth(currentWidth);
- m_totalWidth = m_complexStartToCurrentMetrics.width();
+ m_totalWidth = complexStartToCurrentMetrics.width();
+ return metrics;
}
-void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlineText* text)
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacter(unsigned textPosition)
{
- m_text = text;
- m_textPosition = 0;
- m_currentMetrics = SVGTextMetrics();
- m_complexStartToCurrentMetrics = SVGTextMetrics();
- m_totalWidth = 0;
-
- const Font& scaledFont = text->scaledFont();
- m_run = SVGTextMetrics::constructTextRun(text, 0, text->textLength());
- m_isComplexText = scaledFont.codePath(m_run) == Font::Complex;
+ if (m_bidiRun) {
+ if (textPosition >= static_cast<unsigned>(m_bidiRun->stop())) {
+ m_bidiRun = m_bidiRun->next();
+ // New BiDi run means new reference position for measurements, so reset |m_totalWidth|.
+ m_totalWidth = 0;
+ }
+ ASSERT(m_bidiRun);
+ ASSERT(static_cast<int>(textPosition) < m_bidiRun->stop());
+ m_textDirection = m_bidiRun->direction();
+ }
if (m_isComplexText)
- m_simpleWidthIterator.clear();
- else
- m_simpleWidthIterator = adoptPtr(new WidthIterator(&scaledFont, m_run));
+ return computeMetricsForCharacterComplex(textPosition);
+
+ return computeMetricsForCharacterSimple(textPosition);
}
struct MeasureTextData {
MeasureTextData(SVGCharacterDataMap* characterDataMap)
: allCharactersMap(characterDataMap)
- , hasLastCharacter(false)
- , lastCharacter(0)
- , processRenderer(false)
+ , lastCharacterWasWhiteSpace(true)
, valueListPosition(0)
- , skippedCharacters(0)
{
}
SVGCharacterDataMap* allCharactersMap;
- bool hasLastCharacter;
- UChar lastCharacter;
- bool processRenderer;
+ bool lastCharacterWasWhiteSpace;
unsigned valueListPosition;
- unsigned skippedCharacters;
};
-void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, MeasureTextData* data)
+static void measureTextRenderer(RenderSVGInlineText* text, MeasureTextData* data, bool processRenderer)
{
ASSERT(text);
SVGTextLayoutAttributes* attributes = text->layoutAttributes();
Vector<SVGTextMetrics>* textMetricsValues = &attributes->textMetricsValues();
- if (data->processRenderer) {
+ if (processRenderer) {
if (data->allCharactersMap)
attributes->clear();
else
textMetricsValues->clear();
}
- initializeMeasurementWithTextRenderer(text);
+ SVGTextMetricsCalculator calculator(text);
bool preserveWhiteSpace = text->style()->whiteSpace() == PRE;
- int surrogatePairCharacters = 0;
-
- while (advance()) {
- UChar currentCharacter = m_run[m_textPosition];
- if (currentCharacter == ' ' && !preserveWhiteSpace && (!data->hasLastCharacter || data->lastCharacter == ' ')) {
- if (data->processRenderer)
+ unsigned surrogatePairCharacters = 0;
+ unsigned skippedCharacters = 0;
+ unsigned textPosition = 0;
+ unsigned textLength = calculator.textLength();
+
+ SVGTextMetrics currentMetrics;
+ for (; textPosition < textLength; textPosition += currentMetrics.length()) {
+ currentMetrics = calculator.computeMetricsForCharacter(textPosition);
+ if (!currentMetrics.length())
+ break;
+
+ bool characterIsWhiteSpace = calculator.characterIsWhiteSpace(textPosition);
+ if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) {
+ if (processRenderer)
textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
if (data->allCharactersMap)
- data->skippedCharacters += m_currentMetrics.length();
+ skippedCharacters += currentMetrics.length();
continue;
}
- if (data->processRenderer) {
+ if (processRenderer) {
if (data->allCharactersMap) {
- const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + m_textPosition - data->skippedCharacters - surrogatePairCharacters + 1);
+ const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + textPosition - skippedCharacters - surrogatePairCharacters + 1);
if (it != data->allCharactersMap->end())
- attributes->characterDataMap().set(m_textPosition + 1, it->value);
+ attributes->characterDataMap().set(textPosition + 1, it->value);
}
- textMetricsValues->append(m_currentMetrics);
+ textMetricsValues->append(currentMetrics);
}
- if (data->allCharactersMap && currentCharacterStartsSurrogatePair())
+ if (data->allCharactersMap && calculator.characterStartsSurrogatePair(textPosition))
surrogatePairCharacters++;
- data->hasLastCharacter = true;
- data->lastCharacter = currentCharacter;
+ data->lastCharacterWasWhiteSpace = characterIsWhiteSpace;
}
if (!data->allCharactersMap)
return;
- data->valueListPosition += m_textPosition - data->skippedCharacters;
- data->skippedCharacters = 0;
+ data->valueListPosition += textPosition - skippedCharacters;
}
-void SVGTextMetricsBuilder::walkTree(RenderObject* start, RenderSVGInlineText* stopAtLeaf, MeasureTextData* data)
+static void walkTree(RenderSVGText* start, RenderSVGInlineText* stopAtLeaf, MeasureTextData* data)
{
- for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
+ RenderObject* child = start->firstChild();
+ while (child) {
if (child->isSVGInlineText()) {
RenderSVGInlineText* text = toRenderSVGInlineText(child);
- if (stopAtLeaf && stopAtLeaf != text) {
- data->processRenderer = false;
- measureTextRenderer(text, data);
+ measureTextRenderer(text, data, !stopAtLeaf || stopAtLeaf == text);
+ if (stopAtLeaf && stopAtLeaf == text)
+ return;
+ } else if (child->isSVGInline()) {
+ // Visit children of text content elements.
+ if (RenderObject* inlineChild = toRenderSVGInline(child)->firstChild()) {
+ child = inlineChild;
continue;
}
-
- data->processRenderer = true;
- measureTextRenderer(text, data);
- if (stopAtLeaf)
- return;
-
- continue;
}
-
- if (!child->isSVGInline())
- continue;
-
- walkTree(child, stopAtLeaf, data);
+ child = child->nextInPreOrderAfterChildren(start);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.h
index 076b052283a..bf0c5c77095 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextMetricsBuilder.h
@@ -21,48 +21,18 @@
#define SVGTextMetricsBuilder_h
#include "core/rendering/svg/SVGTextLayoutAttributes.h"
-#include "core/rendering/svg/SVGTextMetrics.h"
-#include "platform/fonts/WidthIterator.h"
-#include "platform/text/TextRun.h"
-#include "wtf/Vector.h"
namespace WebCore {
-class RenderObject;
class RenderSVGInlineText;
class RenderSVGText;
-struct MeasureTextData;
-class SVGTextMetricsBuilder {
- WTF_MAKE_NONCOPYABLE(SVGTextMetricsBuilder);
-public:
- SVGTextMetricsBuilder();
- void measureTextRenderer(RenderSVGInlineText*);
- void buildMetricsAndLayoutAttributes(RenderSVGText*, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap);
+namespace SVGTextMetricsBuilder {
-private:
- bool advance();
- void advanceSimpleText();
- void advanceComplexText();
- bool currentCharacterStartsSurrogatePair() const;
+void measureTextRenderer(RenderSVGInlineText*);
+void buildMetricsAndLayoutAttributes(RenderSVGText*, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap);
- void initializeMeasurementWithTextRenderer(RenderSVGInlineText*);
- void walkTree(RenderObject*, RenderSVGInlineText* stopAtLeaf, MeasureTextData*);
- void measureTextRenderer(RenderSVGInlineText*, MeasureTextData*);
-
- RenderSVGInlineText* m_text;
- TextRun m_run;
- unsigned m_textPosition;
- bool m_isComplexText;
- SVGTextMetrics m_currentMetrics;
- float m_totalWidth;
-
- // Simple text only.
- OwnPtr<WidthIterator> m_simpleWidthIterator;
-
- // Complex text only.
- SVGTextMetrics m_complexStartToCurrentMetrics;
-};
+} // namespace SVGTextMetricsBuilder
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.cpp
index 4bf2a3c3da7..f5ead0d4366 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.cpp
@@ -90,7 +90,7 @@ void SVGTextQuery::collectTextBoxesInFlowBox(InlineFlowBox* flowBox)
for (InlineBox* child = flowBox->firstChild(); child; child = child->nextOnLine()) {
if (child->isInlineFlowBox()) {
// Skip generated content.
- if (!child->renderer()->node())
+ if (!child->renderer().node())
continue;
collectTextBoxesInFlowBox(toInlineFlowBox(child));
@@ -112,8 +112,7 @@ bool SVGTextQuery::executeQuery(Data* queryData, ProcessTextFragmentCallback fra
// Loop over all text boxes
for (unsigned textBoxPosition = 0; textBoxPosition < textBoxCount; ++textBoxPosition) {
queryData->textBox = m_textBoxes.at(textBoxPosition);
- queryData->textRenderer = toRenderSVGInlineText(queryData->textBox->textRenderer());
- ASSERT(queryData->textRenderer);
+ queryData->textRenderer = &toRenderSVGInlineText(queryData->textBox->textRenderer());
ASSERT(queryData->textRenderer->style());
ASSERT(queryData->textRenderer->style()->svgStyle());
@@ -142,7 +141,9 @@ bool SVGTextQuery::mapStartEndPositionsIntoFragmentCoordinates(Data* queryData,
startPosition -= queryData->processedCharacters;
endPosition -= queryData->processedCharacters;
- if (startPosition >= endPosition || startPosition < 0 || endPosition < 0)
+ startPosition = max(0, startPosition);
+
+ if (startPosition >= endPosition)
return false;
modifyStartEndPositionsRespectingLigatures(queryData, startPosition, endPosition);
@@ -215,15 +216,11 @@ void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i
return;
if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) {
- if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset)) {
+ if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset))
startPosition = lastPositionOffset;
- alterStartPosition = false;
- }
- if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) {
+ if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset))
endPosition = positionOffset;
- alterEndPosition = false;
- }
}
}
@@ -480,8 +477,6 @@ static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const
AffineTransform fragmentTransform;
fragment.buildFragmentTransform(fragmentTransform, SVGTextFragment::TransformIgnoringTextLength);
- if (fragmentTransform.isIdentity())
- return;
extent = fragmentTransform.mapRect(extent);
}
@@ -499,10 +494,10 @@ bool SVGTextQuery::extentOfCharacterCallback(Data* queryData, const SVGTextFragm
return true;
}
-SVGRect SVGTextQuery::extentOfCharacter(unsigned position) const
+FloatRect SVGTextQuery::extentOfCharacter(unsigned position) const
{
if (m_textBoxes.isEmpty())
- return SVGRect();
+ return FloatRect();
ExtentOfCharacterData data(position);
executeQuery(&data, &SVGTextQuery::extentOfCharacterCallback);
@@ -540,7 +535,7 @@ bool SVGTextQuery::characterNumberAtPositionCallback(Data* queryData, const SVGT
return false;
}
-int SVGTextQuery::characterNumberAtPosition(const SVGPoint& position) const
+int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const
{
if (m_textBoxes.isEmpty())
return -1;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.h
index 652d751af70..a5601f74d30 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextQuery.h
@@ -21,8 +21,8 @@
#define SVGTextQuery_h
#include "core/rendering/svg/SVGTextFragment.h"
-#include "core/svg/SVGPoint.h"
-#include "core/svg/SVGRect.h"
+#include "platform/geometry/FloatPoint.h"
+#include "platform/geometry/FloatRect.h"
#include "wtf/Vector.h"
namespace WebCore {
@@ -41,8 +41,8 @@ public:
FloatPoint startPositionOfCharacter(unsigned position) const;
FloatPoint endPositionOfCharacter(unsigned position) const;
float rotationOfCharacter(unsigned position) const;
- SVGRect extentOfCharacter(unsigned position) const;
- int characterNumberAtPosition(const SVGPoint&) const;
+ FloatRect extentOfCharacter(unsigned position) const;
+ int characterNumberAtPosition(const FloatPoint&) const;
// Public helper struct. Private classes in SVGTextQuery inherit from it.
struct Data;
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp
index c48c91e2486..7765117cd28 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp
@@ -23,7 +23,6 @@
#if ENABLE(SVG_FONTS)
#include "core/rendering/svg/SVGTextRunRenderingContext.h"
-#include "SVGNames.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/svg/RenderSVGInlineText.h"
#include "core/rendering/svg/RenderSVGResourceSolidColor.h"
@@ -46,6 +45,10 @@ static inline const SVGFontData* svgFontAndFontFaceElementForFontData(const Simp
RefPtr<CustomFontData> customFontData = fontData->customFontData();
const SVGFontData* svgFontData = static_cast<const SVGFontData*>(customFontData.get());
+ // FIXME crbug.com/359380 : The current editing impl references the font after the svg font nodes are removed.
+ if (svgFontData->shouldSkipDrawing())
+ return 0;
+
fontFace = svgFontData->svgFontFaceElement();
ASSERT(fontFace);
@@ -73,12 +76,12 @@ static inline RenderSVGResource* activePaintingResourceFromRun(const TextRun& ru
return 0;
}
-float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int& charsConsumed, String& glyphName) const
+float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int& charsConsumed, Glyph& glyphId) const
{
WidthIterator it(&font, run);
GlyphBuffer glyphBuffer;
charsConsumed += it.advance(run.length(), &glyphBuffer);
- glyphName = it.lastGlyphName();
+ glyphId = !glyphBuffer.isEmpty() ? glyphBuffer.glyphAt(0) : 0;
return it.runWidthSoFar();
}
@@ -119,14 +122,17 @@ void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const T
glyphOrigin.setX(svgFontData->horizontalOriginX() * scale);
glyphOrigin.setY(svgFontData->horizontalOriginY() * scale);
+ unsigned short resourceMode = context->textDrawingMode() == TextModeStroke ? ApplyToStrokeMode : ApplyToFillMode;
+ // From a resource perspective this ought to be treated as "text mode".
+ resourceMode |= ApplyToTextMode;
+
FloatPoint currentPoint = point;
- RenderSVGResourceMode resourceMode = context->textDrawingMode() == TextModeStroke ? ApplyToStrokeMode : ApplyToFillMode;
for (int i = 0; i < numGlyphs; ++i) {
Glyph glyph = glyphBuffer.glyphAt(from + i);
if (!glyph)
continue;
- float advance = glyphBuffer.advanceAt(from + i);
+ float advance = glyphBuffer.advanceAt(from + i).width();
SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
ASSERT(!svgGlyph.isPartOfLigature);
ASSERT(svgGlyph.tableEntry == glyph);
@@ -198,7 +204,7 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co
RenderObject* parentRenderObject = renderObject->isText() ? renderObject->parent() : renderObject;
ASSERT(parentRenderObject);
if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
- if (parentRenderObjectElement->hasTagName(SVGNames::altGlyphTag))
+ if (isSVGAltGlyphElement(*parentRenderObjectElement))
glyphData.fontData = primaryFont;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.h b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.h
index e71eca2ca29..382c51feb50 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.h
+++ b/chromium/third_party/WebKit/Source/core/rendering/svg/SVGTextRunRenderingContext.h
@@ -29,7 +29,7 @@ namespace WebCore {
class RenderObject;
class RenderSVGResource;
-class SVGTextRunRenderingContext : public TextRun::RenderingContext {
+class SVGTextRunRenderingContext FINAL : public TextRun::RenderingContext {
public:
static PassRefPtr<SVGTextRunRenderingContext> create(RenderObject* renderer)
{
@@ -42,9 +42,13 @@ public:
RenderSVGResource* activePaintingResource() const { return m_activePaintingResource; }
void setActivePaintingResource(RenderSVGResource* object) { m_activePaintingResource = object; }
- virtual GlyphData glyphDataForCharacter(const Font&, const TextRun&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength);
- virtual void drawSVGGlyphs(GraphicsContext*, const TextRun&, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const;
- virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const;
+ virtual GlyphData glyphDataForCharacter(const Font&, const TextRun&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength) OVERRIDE;
+ virtual void drawSVGGlyphs(GraphicsContext*, const TextRun&, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const OVERRIDE;
+ virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, Glyph& glyphId) const OVERRIDE;
+#else
+ virtual GlyphData glyphDataForCharacter(const Font&, const TextRun&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength) OVERRIDE { return 0; }
+ virtual void drawSVGGlyphs(GraphicsContext*, const TextRun&, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const OVERRIDE { }
+ virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, Glyph& glyphId) const OVERRIDE { return 0; }
#endif
private:
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInput.cpp b/chromium/third_party/WebKit/Source/core/speech/SpeechInput.cpp
deleted file mode 100644
index 221e02377f2..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInput.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/speech/SpeechInput.h"
-
-#if ENABLE(INPUT_SPEECH)
-
-#include "core/speech/SpeechInputClient.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace WebCore {
-
-SpeechInput::SpeechInput(SpeechInputClient* client)
- : m_client(client)
- , m_nextListenerId(1)
-{
- m_client->setListener(this);
-}
-
-SpeechInput::~SpeechInput()
-{
- m_client->setListener(0);
-}
-
-PassOwnPtr<SpeechInput> SpeechInput::create(SpeechInputClient* client)
-{
- return adoptPtr(new SpeechInput(client));
-}
-
-int SpeechInput::registerListener(SpeechInputListener* listener)
-{
-#if defined(DEBUG)
- // Check if already present.
- for (HashMap<int, SpeechInputListener*>::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it)
- ASSERT(it->value != listener);
-#endif
-
- m_listeners.add(m_nextListenerId, listener);
- return m_nextListenerId++;
-}
-
-void SpeechInput::unregisterListener(int listenerId)
-{
- if (m_listeners.contains(listenerId))
- m_listeners.remove(listenerId);
-}
-
-void SpeechInput::didCompleteRecording(int listenerId)
-{
- // Don't assert if not present as the element might have been removed by the page while
- // this event was on the way.
- if (m_listeners.contains(listenerId))
- m_listeners.get(listenerId)->didCompleteRecording(listenerId);
-}
-
-void SpeechInput::didCompleteRecognition(int listenerId)
-{
- // Don't assert if not present as the element might have been removed by the page while
- // this event was on the way.
- if (m_listeners.contains(listenerId))
- m_listeners.get(listenerId)->didCompleteRecognition(listenerId);
-}
-
-void SpeechInput::setRecognitionResult(int listenerId, const SpeechInputResultArray& result)
-{
- // Don't assert if not present as the element might have been removed by the page while
- // this event was on the way.
- if (m_listeners.contains(listenerId))
- m_listeners.get(listenerId)->setRecognitionResult(listenerId, result);
-}
-
-bool SpeechInput::startRecognition(int listenerId, const IntRect& elementRect, const AtomicString& language, const String& grammar, SecurityOrigin* origin)
-{
- ASSERT(m_listeners.contains(listenerId));
- return m_client->startRecognition(listenerId, elementRect, language, grammar, origin);
-}
-
-void SpeechInput::stopRecording(int listenerId)
-{
- ASSERT(m_listeners.contains(listenerId));
- m_client->stopRecording(listenerId);
-}
-
-void SpeechInput::cancelRecognition(int listenerId)
-{
- ASSERT(m_listeners.contains(listenerId));
- m_client->cancelRecognition(listenerId);
-}
-
-const char* SpeechInput::supplementName()
-{
- return "SpeechInput";
-}
-
-void provideSpeechInputTo(Page* page, SpeechInputClient* client)
-{
- SpeechInput::provideTo(page, SpeechInput::supplementName(), SpeechInput::create(client));
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInput.h b/chromium/third_party/WebKit/Source/core/speech/SpeechInput.h
deleted file mode 100644
index dcc717137bf..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInput.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SpeechInput_h
-#define SpeechInput_h
-
-#if ENABLE(INPUT_SPEECH)
-
-#include "core/page/Page.h"
-#include "core/speech/SpeechInputListener.h"
-#include "wtf/Forward.h"
-#include "wtf/HashMap.h"
-
-namespace WebCore {
-
-class IntRect;
-class SecurityOrigin;
-class SpeechInputClient;
-class SpeechInputListener;
-
-// This class connects the input elements requiring speech input with the platform specific
-// speech recognition engine. It provides methods for the input elements to activate speech
-// recognition and methods for the speech recognition engine to return back the results.
-class SpeechInput : public SpeechInputListener, public Supplement<Page> {
- WTF_MAKE_NONCOPYABLE(SpeechInput);
-public:
- virtual ~SpeechInput();
-
- static PassOwnPtr<SpeechInput> create(SpeechInputClient*);
- static const char* supplementName();
- static SpeechInput* from(Page* page) { return static_cast<SpeechInput*>(Supplement<Page>::from(page, supplementName())); }
-
- // Generates a unique ID for the given listener to be used for speech requests.
- // This should be the first call made by listeners before anything else.
- int registerListener(SpeechInputListener*);
-
- // Invoked when the listener is done with recording or getting destroyed.
- // Failure to unregister may result in crashes if there were any pending speech events.
- void unregisterListener(int);
-
- // Methods invoked by the input elements.
- bool startRecognition(int listenerId, const IntRect& elementRect, const AtomicString& language, const String& grammar, SecurityOrigin*);
- void stopRecording(int);
- void cancelRecognition(int);
-
- // SpeechInputListener methods.
- virtual void didCompleteRecording(int);
- virtual void didCompleteRecognition(int);
- virtual void setRecognitionResult(int, const SpeechInputResultArray&);
-
-private:
- explicit SpeechInput(SpeechInputClient*);
-
- SpeechInputClient* m_client;
- HashMap<int, SpeechInputListener*> m_listeners;
- int m_nextListenerId;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
-
-#endif // SpeechInput_h
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputClient.h b/chromium/third_party/WebKit/Source/core/speech/SpeechInputClient.h
deleted file mode 100644
index 4e8eb6ff7a7..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputClient.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SpeechInputClient_h
-#define SpeechInputClient_h
-
-#include "wtf/Forward.h"
-
-#if ENABLE(INPUT_SPEECH)
-
-namespace WebCore {
-
-class IntRect;
-class SecurityOrigin;
-class SpeechInputListener;
-class Page;
-
-// Provides an interface for SpeechInput to call into the embedder.
-class SpeechInputClient {
-public:
- // This is the first call made by a listener, registering itself for future callbacks.
- // When the listener no longer needs speech input (for e.g. when it gets destroyed),
- // it should set a null listener to stop receiving callbacks.
- // The client does not take ownership of the pointer.
- virtual void setListener(SpeechInputListener*) = 0;
-
- // Starts speech recognition and audio recording. elementRect is the position
- // of the element where the user clicked in the RootView coordinate system.
- virtual bool startRecognition(int requestId, const IntRect& elementRect, const AtomicString& language, const String& grammar, SecurityOrigin*) = 0;
-
- // Stops audio recording and performs recognition with the audio recorded until now
- // (does not discard audio).
- virtual void stopRecording(int requestId) = 0;
-
- // Cancels an ongoing recognition and discards any audio recorded so far. No partial
- // recognition results are returned to the listener.
- virtual void cancelRecognition(int requestId) = 0;
-
-protected:
- virtual ~SpeechInputClient() { }
-};
-
-void provideSpeechInputTo(Page*, SpeechInputClient*);
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
-
-#endif // SpeechInputClient_h
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.cpp b/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.cpp
deleted file mode 100644
index f0222e9bb77..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(INPUT_SPEECH)
-
-#include "core/speech/SpeechInputEvent.h"
-
-#include "core/events/ThreadLocalEventNames.h"
-
-namespace WebCore {
-
-PassRefPtr<SpeechInputEvent> SpeechInputEvent::create()
-{
- return adoptRef(new SpeechInputEvent);
-}
-
-PassRefPtr<SpeechInputEvent> SpeechInputEvent::create(const AtomicString& eventType, const SpeechInputResultArray& results)
-{
- return adoptRef(new SpeechInputEvent(eventType, results));
-}
-
-SpeechInputEvent::SpeechInputEvent()
-{
- ScriptWrappable::init(this);
-}
-
-SpeechInputEvent::SpeechInputEvent(const AtomicString& eventType, const SpeechInputResultArray& results)
- : Event(eventType, true, false) // Can bubble, not cancelable
- , m_results(SpeechInputResultList::create(results))
-{
- ScriptWrappable::init(this);
-}
-
-SpeechInputEvent::~SpeechInputEvent()
-{
-}
-
-const AtomicString& SpeechInputEvent::interfaceName() const
-{
- return EventNames::SpeechInputEvent;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.h b/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.h
deleted file mode 100644
index 1a00925bf39..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SpeechInputEvent_h
-#define SpeechInputEvent_h
-
-#if ENABLE(INPUT_SPEECH)
-
-#include "core/events/Event.h"
-#include "core/speech/SpeechInputResultList.h"
-
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-class SpeechInputEvent : public Event {
-public:
- static PassRefPtr<SpeechInputEvent> create();
- static PassRefPtr<SpeechInputEvent> create(const AtomicString& eventType, const SpeechInputResultArray& results);
- ~SpeechInputEvent();
-
- SpeechInputResultList* results() const { return m_results.get(); }
-
- virtual const AtomicString& interfaceName() const;
-
-private:
- SpeechInputEvent();
- SpeechInputEvent(const AtomicString& eventType, const SpeechInputResultArray& results);
-
- RefPtr<SpeechInputResultList> m_results;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
-
-#endif // SpeechInputEvent_h
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.idl b/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.idl
deleted file mode 100644
index 4fe740b1bdb..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputEvent.idl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- Conditional=INPUT_SPEECH
-] interface SpeechInputEvent : Event {
- readonly attribute SpeechInputResultList results;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputListener.h b/chromium/third_party/WebKit/Source/core/speech/SpeechInputListener.h
deleted file mode 100644
index b4fc017d138..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputListener.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SpeechInputListener_h
-#define SpeechInputListener_h
-
-#if ENABLE(INPUT_SPEECH)
-
-#include "core/speech/SpeechInputResult.h"
-#include "wtf/Forward.h"
-
-namespace WebCore {
-
-// Interface to be implemented by the element which invokes SpeechInput.
-class SpeechInputListener {
-public:
- // Informs that audio recording has completed and recognition is underway.
- virtual void didCompleteRecording(int requestId) = 0;
-
- // Informs that speech recognition has completed. This gets invoked irrespective of whether
- // recognition was succesful or not, whether setRecognitionResult() was invoked or not. The
- // handler typically frees up any temporary resources allocated and waits for the next speech
- // recognition request.
- virtual void didCompleteRecognition(int requestId) = 0;
-
- // Gives results from speech recognition, either partial or the final results.
- // This method can potentially get called multiple times if there are partial results
- // available as the user keeps speaking. If the speech could not be recognized properly
- // or if there was any other errors in the process, this method may never be called.
- virtual void setRecognitionResult(int requestId, const SpeechInputResultArray&) = 0;
-
-protected:
- virtual ~SpeechInputListener() { }
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
-
-#endif // SpeechInputListener_h
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.cpp b/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.cpp
deleted file mode 100644
index 1673455fe4b..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/speech/SpeechInputResult.h"
-
-#if ENABLE(INPUT_SPEECH)
-
-namespace WebCore {
-
-PassRefPtr<SpeechInputResult> SpeechInputResult::create(const String& utterance, double confidence)
-{
- return adoptRef(new SpeechInputResult(utterance, confidence));
-}
-
-PassRefPtr<SpeechInputResult> SpeechInputResult::create(const SpeechInputResult& source)
-{
- return adoptRef(new SpeechInputResult(source.m_utterance, source.m_confidence));
-}
-
-SpeechInputResult::SpeechInputResult(const String& utterance, double confidence)
- : m_utterance(utterance)
- , m_confidence(confidence)
-{
- ScriptWrappable::init(this);
-}
-
-double SpeechInputResult::confidence() const
-{
- return m_confidence;
-}
-
-const String& SpeechInputResult::utterance() const
-{
- return m_utterance;
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.h b/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.h
deleted file mode 100644
index 5a5d44da7bd..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SpeechInputResult_h
-#define SpeechInputResult_h
-
-#if ENABLE(INPUT_SPEECH)
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-// This class holds one speech recognition result including the text and other related
-// fields, as received from the embedder.
-class SpeechInputResult : public RefCounted<SpeechInputResult>, public ScriptWrappable {
-public:
- static PassRefPtr<SpeechInputResult> create(const SpeechInputResult& source);
- static PassRefPtr<SpeechInputResult> create(const String& utterance, double confidence);
-
- double confidence() const;
- const String& utterance() const;
-
-private:
- SpeechInputResult(const String& utterance, double confidence);
-
- String m_utterance;
- double m_confidence;
-};
-
-typedef Vector<RefPtr<SpeechInputResult> > SpeechInputResultArray;
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
-
-#endif // SpeechInputResult_h
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.idl b/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.idl
deleted file mode 100644
index bc2d4097aac..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResult.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject,
- Conditional=INPUT_SPEECH
-] interface SpeechInputResult {
- readonly attribute DOMString utterance;
- readonly attribute float confidence;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.cpp b/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.cpp
deleted file mode 100644
index 86f7fda0764..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/speech/SpeechInputResultList.h"
-
-#if ENABLE(INPUT_SPEECH)
-
-namespace WebCore {
-
-PassRefPtr<SpeechInputResultList> SpeechInputResultList::create(const SpeechInputResultArray& results)
-{
- return adoptRef(new SpeechInputResultList(results));
-}
-
-SpeechInputResult* SpeechInputResultList::item(unsigned index)
-{
- return index >= m_results.size() ? 0 : m_results[index].get();
-}
-
-SpeechInputResultList::SpeechInputResultList(const SpeechInputResultArray& results)
- : m_results(results) // Takes a copy of the array of RefPtrs.
-{
- ScriptWrappable::init(this);
-}
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.h b/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.h
deleted file mode 100644
index 3edb9d5bef0..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SpeechInputResultList_h
-#define SpeechInputResultList_h
-
-#if ENABLE(INPUT_SPEECH)
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/speech/SpeechInputResult.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-class SpeechInputResultList : public RefCounted<SpeechInputResultList>, public ScriptWrappable {
-public:
- static PassRefPtr<SpeechInputResultList> create(const SpeechInputResultArray& results);
-
- // Methods from the IDL.
- size_t length() { return m_results.size(); }
- SpeechInputResult* item(unsigned index);
-
-private:
- explicit SpeechInputResultList(const SpeechInputResultArray& results);
-
- SpeechInputResultArray m_results;
-};
-
-} // namespace WebCore
-
-#endif // ENABLE(INPUT_SPEECH)
-
-#endif // SpeechInputResultList_h
diff --git a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.idl b/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.idl
deleted file mode 100644
index 1983aed5017..00000000000
--- a/chromium/third_party/WebKit/Source/core/speech/SpeechInputResultList.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject,
- Conditional=INPUT_SPEECH
-] interface SpeechInputResultList {
- readonly attribute unsigned long length;
- getter SpeechInputResult item(unsigned long index);
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/storage/Storage.cpp b/chromium/third_party/WebKit/Source/core/storage/Storage.cpp
index 76abd82a300..dbb7e8bacd2 100644
--- a/chromium/third_party/WebKit/Source/core/storage/Storage.cpp
+++ b/chromium/third_party/WebKit/Source/core/storage/Storage.cpp
@@ -33,12 +33,12 @@
namespace WebCore {
-PassRefPtr<Storage> Storage::create(Frame* frame, PassOwnPtr<StorageArea> storageArea)
+PassRefPtrWillBeRawPtr<Storage> Storage::create(LocalFrame* frame, PassOwnPtrWillBeRawPtr<StorageArea> storageArea)
{
- return adoptRef(new Storage(frame, storageArea));
+ return adoptRefWillBeNoop(new Storage(frame, storageArea));
}
-Storage::Storage(Frame* frame, PassOwnPtr<StorageArea> storageArea)
+Storage::Storage(LocalFrame* frame, PassOwnPtrWillBeRawPtr<StorageArea> storageArea)
: DOMWindowProperty(frame)
, m_storageArea(storageArea)
{
@@ -78,20 +78,23 @@ bool Storage::anonymousIndexedSetter(unsigned index, const AtomicString& value,
return anonymousNamedSetter(AtomicString::number(index), value, exceptionState);
}
-bool Storage::anonymousNamedDeleter(const AtomicString& name, ExceptionState& exceptionState)
+DeleteResult Storage::anonymousNamedDeleter(const AtomicString& name, ExceptionState& exceptionState)
{
bool found = contains(name, exceptionState);
- if (!found || exceptionState.hadException())
- return false;
+ if (!found)
+ return DeleteUnknownProperty;
+ if (exceptionState.hadException())
+ return DeleteReject;
removeItem(name, exceptionState);
if (exceptionState.hadException())
- return false;
- return true;
+ return DeleteReject;
+ return DeleteSuccess;
}
-bool Storage::anonymousIndexedDeleter(unsigned index, ExceptionState& exceptionState)
+DeleteResult Storage::anonymousIndexedDeleter(unsigned index, ExceptionState& exceptionState)
{
- return anonymousNamedDeleter(AtomicString::number(index), exceptionState);
+ DeleteResult result = anonymousNamedDeleter(AtomicString::number(index), exceptionState);
+ return result == DeleteUnknownProperty ? DeleteSuccess : result;
}
void Storage::namedPropertyEnumerator(Vector<String>& names, ExceptionState& exceptionState)
@@ -122,4 +125,9 @@ bool Storage::namedPropertyQuery(const AtomicString& name, ExceptionState& excep
return true;
}
+void Storage::trace(Visitor* visitor)
+{
+ visitor->trace(m_storageArea);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/storage/Storage.h b/chromium/third_party/WebKit/Source/core/storage/Storage.h
index 34e131712c6..760d55b8406 100644
--- a/chromium/third_party/WebKit/Source/core/storage/Storage.h
+++ b/chromium/third_party/WebKit/Source/core/storage/Storage.h
@@ -27,8 +27,10 @@
#define Storage_h
#include "bindings/v8/ScriptWrappable.h"
+#include "bindings/v8/V8Binding.h"
#include "core/frame/DOMWindowProperty.h"
#include "core/storage/StorageArea.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -36,12 +38,12 @@
namespace WebCore {
class ExceptionState;
-class Frame;
+class LocalFrame;
-class Storage : public ScriptWrappable, public RefCounted<Storage>, public DOMWindowProperty {
+class Storage FINAL : public RefCountedWillBeGarbageCollectedFinalized<Storage>, public ScriptWrappable, public DOMWindowProperty {
public:
- static PassRefPtr<Storage> create(Frame*, PassOwnPtr<StorageArea>);
- ~Storage();
+ static PassRefPtrWillBeRawPtr<Storage> create(LocalFrame*, PassOwnPtrWillBeRawPtr<StorageArea>);
+ virtual ~Storage();
unsigned length(ExceptionState& ec) const { return m_storageArea->length(ec, m_frame); }
String key(unsigned index, ExceptionState& ec) const { return m_storageArea->key(index, ec, m_frame); }
@@ -57,15 +59,17 @@ public:
String anonymousNamedGetter(const AtomicString&, ExceptionState&);
bool anonymousNamedSetter(const AtomicString& name, const AtomicString& value, ExceptionState&);
bool anonymousIndexedSetter(unsigned, const AtomicString&, ExceptionState&);
- bool anonymousNamedDeleter(const AtomicString&, ExceptionState&);
- bool anonymousIndexedDeleter(unsigned, ExceptionState&);
+ DeleteResult anonymousNamedDeleter(const AtomicString&, ExceptionState&);
+ DeleteResult anonymousIndexedDeleter(unsigned, ExceptionState&);
void namedPropertyEnumerator(Vector<String>&, ExceptionState&);
bool namedPropertyQuery(const AtomicString&, ExceptionState&);
+ void trace(Visitor*);
+
private:
- Storage(Frame*, PassOwnPtr<StorageArea>);
+ Storage(LocalFrame*, PassOwnPtrWillBeRawPtr<StorageArea>);
- OwnPtr<StorageArea> m_storageArea;
+ OwnPtrWillBeMember<StorageArea> m_storageArea;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/storage/Storage.idl b/chromium/third_party/WebKit/Source/core/storage/Storage.idl
index 90309fe7ccd..288703d2316 100644
--- a/chromium/third_party/WebKit/Source/core/storage/Storage.idl
+++ b/chromium/third_party/WebKit/Source/core/storage/Storage.idl
@@ -23,18 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface Storage {
- [RaisesException, ImplementedAs=anonymousIndexedGetter, NotEnumerable] getter DOMString(unsigned long index);
- [RaisesException, ImplementedAs=anonymousIndexedSetter] setter DOMString (unsigned long index, DOMString value);
- [ImplementedAs=anonymousIndexedDeleter, RaisesException] deleter boolean (unsigned long index);
- [RaisesException, ImplementedAs=anonymousNamedGetter] getter DOMString(DOMString name);
- [RaisesException, ImplementedAs=anonymousNamedSetter] setter DOMString(DOMString name, DOMString value);
- [ImplementedAs=anonymousNamedDeleter, RaisesException] deleter boolean (DOMString name);
+[
+ WillBeGarbageCollected
+] interface Storage {
+ [NotEnumerable, RaisesException] getter DOMString (unsigned long index);
+ [RaisesException] setter DOMString (unsigned long index, DOMString value);
+ [RaisesException] deleter boolean (unsigned long index);
+
+ [RaisesException] getter DOMString (DOMString name);
+ [RaisesException] setter DOMString (DOMString name, DOMString value);
+ [RaisesException] deleter boolean (DOMString name);
+
[NotEnumerable, RaisesException=Getter] readonly attribute unsigned long length;
- [NotEnumerable, TreatReturnedNullStringAs=Null, RaisesException] DOMString key(unsigned long index);
- [NotEnumerable, TreatReturnedNullStringAs=Null, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] DOMString getItem(DOMString key);
- [NotEnumerable, RaisesException, PerWorldBindings, ActivityLogging=ForIsolatedWorlds] void setItem(DOMString key, DOMString data);
- [NotEnumerable, RaisesException, PerWorldBindings, ActivityLogging=ForIsolatedWorlds] void removeItem(DOMString key);
- [NotEnumerable, RaisesException, PerWorldBindings, ActivityLogging=ForIsolatedWorlds] void clear();
+ [NotEnumerable, RaisesException, TreatReturnedNullStringAs=Null] DOMString key(unsigned long index);
+ [LogActivity, NotEnumerable, RaisesException, TreatReturnedNullStringAs=Null] DOMString getItem(DOMString key);
+ [LogActivity, NotEnumerable, RaisesException] void setItem(DOMString key, DOMString data);
+ [LogActivity, NotEnumerable, RaisesException] void removeItem(DOMString key);
+ [LogActivity, NotEnumerable, RaisesException] void clear();
};
-
diff --git a/chromium/third_party/WebKit/Source/core/storage/StorageArea.cpp b/chromium/third_party/WebKit/Source/core/storage/StorageArea.cpp
new file mode 100644
index 00000000000..49334cf36cd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/storage/StorageArea.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ * (C) 2008 Apple Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/storage/StorageArea.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/Document.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/page/Page.h"
+#include "core/page/StorageClient.h"
+#include "core/storage/Storage.h"
+#include "core/storage/StorageEvent.h"
+#include "core/storage/StorageNamespace.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/WebStorageArea.h"
+#include "public/platform/WebString.h"
+#include "public/platform/WebURL.h"
+
+namespace WebCore {
+
+StorageArea::StorageArea(PassOwnPtr<blink::WebStorageArea> storageArea, StorageType storageType)
+ : m_storageArea(storageArea)
+ , m_storageType(storageType)
+ , m_canAccessStorageCachedResult(false)
+ , m_canAccessStorageCachedFrame(0)
+{
+}
+
+StorageArea::~StorageArea()
+{
+}
+
+unsigned StorageArea::length(ExceptionState& exceptionState, LocalFrame* frame)
+{
+ if (!canAccessStorage(frame)) {
+ exceptionState.throwSecurityError("access is denied for this document.");
+ return 0;
+ }
+ return m_storageArea->length();
+}
+
+String StorageArea::key(unsigned index, ExceptionState& exceptionState, LocalFrame* frame)
+{
+ if (!canAccessStorage(frame)) {
+ exceptionState.throwSecurityError("access is denied for this document.");
+ return String();
+ }
+ return m_storageArea->key(index);
+}
+
+String StorageArea::getItem(const String& key, ExceptionState& exceptionState, LocalFrame* frame)
+{
+ if (!canAccessStorage(frame)) {
+ exceptionState.throwSecurityError("access is denied for this document.");
+ return String();
+ }
+ return m_storageArea->getItem(key);
+}
+
+void StorageArea::setItem(const String& key, const String& value, ExceptionState& exceptionState, LocalFrame* frame)
+{
+ if (!canAccessStorage(frame)) {
+ exceptionState.throwSecurityError("access is denied for this document.");
+ return;
+ }
+ blink::WebStorageArea::Result result = blink::WebStorageArea::ResultOK;
+ m_storageArea->setItem(key, value, frame->document()->url(), result);
+ if (result != blink::WebStorageArea::ResultOK)
+ exceptionState.throwDOMException(QuotaExceededError, "Setting the value of '" + key + "' exceeded the quota.");
+}
+
+void StorageArea::removeItem(const String& key, ExceptionState& exceptionState, LocalFrame* frame)
+{
+ if (!canAccessStorage(frame)) {
+ exceptionState.throwSecurityError("access is denied for this document.");
+ return;
+ }
+ m_storageArea->removeItem(key, frame->document()->url());
+}
+
+void StorageArea::clear(ExceptionState& exceptionState, LocalFrame* frame)
+{
+ if (!canAccessStorage(frame)) {
+ exceptionState.throwSecurityError("access is denied for this document.");
+ return;
+ }
+ m_storageArea->clear(frame->document()->url());
+}
+
+bool StorageArea::contains(const String& key, ExceptionState& exceptionState, LocalFrame* frame)
+{
+ if (!canAccessStorage(frame)) {
+ exceptionState.throwSecurityError("access is denied for this document.");
+ return false;
+ }
+ return !getItem(key, exceptionState, frame).isNull();
+}
+
+bool StorageArea::canAccessStorage(LocalFrame* frame)
+{
+ if (!frame || !frame->page())
+ return false;
+ if (m_canAccessStorageCachedFrame == frame)
+ return m_canAccessStorageCachedResult;
+ bool result = frame->page()->storageClient().canAccessStorage(frame, m_storageType);
+ m_canAccessStorageCachedFrame = frame;
+ m_canAccessStorageCachedResult = result;
+ return result;
+}
+
+size_t StorageArea::memoryBytesUsedByCache()
+{
+ return m_storageArea->memoryBytesUsedByCache();
+}
+
+void StorageArea::dispatchLocalStorageEvent(const String& key, const String& oldValue, const String& newValue, SecurityOrigin* securityOrigin, const KURL& pageURL, blink::WebStorageArea* sourceAreaInstance, bool originatedInProcess)
+{
+ // FIXME: This looks suspicious. Why doesn't this use allPages instead?
+ const HashSet<Page*>& pages = Page::ordinaryPages();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); ++it) {
+ for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ // FIXME: We do not yet have a way to dispatch events to out-of-process frames.
+ if (!frame->isLocalFrame())
+ continue;
+ Storage* storage = frame->domWindow()->optionalLocalStorage();
+ if (storage && toLocalFrame(frame)->document()->securityOrigin()->canAccess(securityOrigin) && !isEventSource(storage, sourceAreaInstance))
+ frame->domWindow()->enqueueWindowEvent(StorageEvent::create(EventTypeNames::storage, key, oldValue, newValue, pageURL, storage));
+ }
+ InspectorInstrumentation::didDispatchDOMStorageEvent(*it, key, oldValue, newValue, LocalStorage, securityOrigin);
+ }
+}
+
+static Page* findPageWithSessionStorageNamespace(const blink::WebStorageNamespace& sessionNamespace)
+{
+ // FIXME: This looks suspicious. Why doesn't this use allPages instead?
+ const HashSet<Page*>& pages = Page::ordinaryPages();
+ for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); ++it) {
+ const bool dontCreateIfMissing = false;
+ StorageNamespace* storageNamespace = (*it)->sessionStorage(dontCreateIfMissing);
+ if (storageNamespace && storageNamespace->isSameNamespace(sessionNamespace))
+ return *it;
+ }
+ return 0;
+}
+
+void StorageArea::dispatchSessionStorageEvent(const String& key, const String& oldValue, const String& newValue, SecurityOrigin* securityOrigin, const KURL& pageURL, const blink::WebStorageNamespace& sessionNamespace, blink::WebStorageArea* sourceAreaInstance, bool originatedInProcess)
+{
+ Page* page = findPageWithSessionStorageNamespace(sessionNamespace);
+ if (!page)
+ return;
+
+ for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+ // FIXME: We do not yet have a way to dispatch events to out-of-process frames.
+ if (!frame->isLocalFrame())
+ continue;
+ Storage* storage = frame->domWindow()->optionalSessionStorage();
+ if (storage && toLocalFrame(frame)->document()->securityOrigin()->canAccess(securityOrigin) && !isEventSource(storage, sourceAreaInstance))
+ frame->domWindow()->enqueueWindowEvent(StorageEvent::create(EventTypeNames::storage, key, oldValue, newValue, pageURL, storage));
+ }
+ InspectorInstrumentation::didDispatchDOMStorageEvent(page, key, oldValue, newValue, SessionStorage, securityOrigin);
+}
+
+bool StorageArea::isEventSource(Storage* storage, blink::WebStorageArea* sourceAreaInstance)
+{
+ ASSERT(storage);
+ StorageArea* area = storage->area();
+ return area->m_storageArea == sourceAreaInstance;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/storage/StorageArea.h b/chromium/third_party/WebKit/Source/core/storage/StorageArea.h
index 00114d5146a..6e039d2a91e 100644
--- a/chromium/third_party/WebKit/Source/core/storage/StorageArea.h
+++ b/chromium/third_party/WebKit/Source/core/storage/StorageArea.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,34 +26,62 @@
#ifndef StorageArea_h
#define StorageArea_h
-#include "wtf/Forward.h"
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/text/WTFString.h"
+namespace blink {
+class WebStorageArea;
+class WebStorageNamespace;
+}
+
namespace WebCore {
class ExceptionState;
-class Frame;
+class LocalFrame;
+class KURL;
+class Page;
class SecurityOrigin;
-class StorageSyncManager;
-enum StorageType { LocalStorage, SessionStorage };
+class Storage;
+
+enum StorageType {
+ LocalStorage,
+ SessionStorage
+};
-class StorageArea {
+class StorageArea : public NoBaseWillBeGarbageCollectedFinalized<StorageArea> {
public:
- virtual ~StorageArea() { }
+ StorageArea(PassOwnPtr<blink::WebStorageArea>, StorageType);
+ virtual ~StorageArea();
// The HTML5 DOM Storage API
- // FIXME: We should pass Document instead of Frame. Also, that parameter should go first.
- virtual unsigned length(ExceptionState&, Frame* sourceFrame) = 0;
- virtual String key(unsigned index, ExceptionState&, Frame* sourceFrame) = 0;
- virtual String getItem(const String& key, ExceptionState&, Frame* sourceFrame) = 0;
- virtual void setItem(const String& key, const String& value, ExceptionState&, Frame* sourceFrame) = 0;
- virtual void removeItem(const String& key, ExceptionState&, Frame* sourceFrame) = 0;
- virtual void clear(ExceptionState&, Frame* sourceFrame) = 0;
- virtual bool contains(const String& key, ExceptionState&, Frame* sourceFrame) = 0;
-
- virtual bool canAccessStorage(Frame*) = 0;
-
- virtual size_t memoryBytesUsedByCache() = 0;
+ unsigned length(ExceptionState&, LocalFrame* sourceFrame);
+ String key(unsigned index, ExceptionState&, LocalFrame* sourceFrame);
+ String getItem(const String& key, ExceptionState&, LocalFrame* sourceFrame);
+ void setItem(const String& key, const String& value, ExceptionState&, LocalFrame* sourceFrame);
+ void removeItem(const String& key, ExceptionState&, LocalFrame* sourceFrame);
+ void clear(ExceptionState&, LocalFrame* sourceFrame);
+ bool contains(const String& key, ExceptionState&, LocalFrame* sourceFrame);
+
+ bool canAccessStorage(LocalFrame*);
+ size_t memoryBytesUsedByCache();
+
+ static void dispatchLocalStorageEvent(const String& key, const String& oldValue, const String& newValue,
+ SecurityOrigin*, const KURL& pageURL, blink::WebStorageArea* sourceAreaInstance, bool originatedInProcess);
+ static void dispatchSessionStorageEvent(const String& key, const String& oldValue, const String& newValue,
+ SecurityOrigin*, const KURL& pageURL, const blink::WebStorageNamespace&,
+ blink::WebStorageArea* sourceAreaInstance, bool originatedInProcess);
+
+ void trace(Visitor*) { }
+
+private:
+ static bool isEventSource(Storage*, blink::WebStorageArea* sourceAreaInstance);
+
+ OwnPtr<blink::WebStorageArea> m_storageArea;
+ StorageType m_storageType;
+ bool m_canAccessStorageCachedResult;
+ LocalFrame* m_canAccessStorageCachedFrame;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/storage/StorageEvent.cpp b/chromium/third_party/WebKit/Source/core/storage/StorageEvent.cpp
index 1c434f39b4d..327896ce0a7 100644
--- a/chromium/third_party/WebKit/Source/core/storage/StorageEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/storage/StorageEvent.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "core/storage/StorageEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/storage/Storage.h"
namespace WebCore {
@@ -35,9 +34,9 @@ StorageEventInit::StorageEventInit()
{
}
-PassRefPtr<StorageEvent> StorageEvent::create()
+PassRefPtrWillBeRawPtr<StorageEvent> StorageEvent::create()
{
- return adoptRef(new StorageEvent);
+ return adoptRefWillBeNoop(new StorageEvent);
}
StorageEvent::StorageEvent()
@@ -49,14 +48,14 @@ StorageEvent::~StorageEvent()
{
}
-PassRefPtr<StorageEvent> StorageEvent::create(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea)
+PassRefPtrWillBeRawPtr<StorageEvent> StorageEvent::create(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea)
{
- return adoptRef(new StorageEvent(type, key, oldValue, newValue, url, storageArea));
+ return adoptRefWillBeNoop(new StorageEvent(type, key, oldValue, newValue, url, storageArea));
}
-PassRefPtr<StorageEvent> StorageEvent::create(const AtomicString& type, const StorageEventInit& initializer)
+PassRefPtrWillBeRawPtr<StorageEvent> StorageEvent::create(const AtomicString& type, const StorageEventInit& initializer)
{
- return adoptRef(new StorageEvent(type, initializer));
+ return adoptRefWillBeNoop(new StorageEvent(type, initializer));
}
StorageEvent::StorageEvent(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea)
@@ -100,4 +99,10 @@ const AtomicString& StorageEvent::interfaceName() const
return EventNames::StorageEvent;
}
+void StorageEvent::trace(Visitor* visitor)
+{
+ visitor->trace(m_storageArea);
+ Event::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/storage/StorageEvent.h b/chromium/third_party/WebKit/Source/core/storage/StorageEvent.h
index 2e6743a79d1..6d57b76b541 100644
--- a/chromium/third_party/WebKit/Source/core/storage/StorageEvent.h
+++ b/chromium/third_party/WebKit/Source/core/storage/StorageEvent.h
@@ -27,6 +27,7 @@
#define StorageEvent_h
#include "core/events/Event.h"
+#include "platform/heap/Handle.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -40,14 +41,14 @@ struct StorageEventInit : public EventInit {
String oldValue;
String newValue;
String url;
- RefPtr<Storage> storageArea;
+ RefPtrWillBeMember<Storage> storageArea;
};
-class StorageEvent : public Event {
+class StorageEvent FINAL : public Event {
public:
- static PassRefPtr<StorageEvent> create();
- static PassRefPtr<StorageEvent> create(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea);
- static PassRefPtr<StorageEvent> create(const AtomicString&, const StorageEventInit&);
+ static PassRefPtrWillBeRawPtr<StorageEvent> create();
+ static PassRefPtrWillBeRawPtr<StorageEvent> create(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea);
+ static PassRefPtrWillBeRawPtr<StorageEvent> create(const AtomicString&, const StorageEventInit&);
virtual ~StorageEvent();
const String& key() const { return m_key; }
@@ -62,7 +63,9 @@ public:
// Needed once we support init<blank>EventNS
// void initStorageEventNS(in DOMString namespaceURI, in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in DOMString keyArg, in DOMString oldValueArg, in DOMString newValueArg, in DOMString urlArg, Storage storageAreaArg);
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
StorageEvent();
@@ -73,7 +76,7 @@ private:
String m_oldValue;
String m_newValue;
String m_url;
- RefPtr<Storage> m_storageArea;
+ RefPtrWillBeMember<Storage> m_storageArea;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/storage/StorageNamespace.cpp b/chromium/third_party/WebKit/Source/core/storage/StorageNamespace.cpp
new file mode 100644
index 00000000000..84f6074265c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/storage/StorageNamespace.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2009 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/storage/StorageNamespace.h"
+
+#include "core/storage/StorageArea.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebStorageArea.h"
+#include "public/platform/WebStorageNamespace.h"
+#include "wtf/MainThread.h"
+
+namespace WebCore {
+
+StorageNamespace::StorageNamespace(PassOwnPtr<blink::WebStorageNamespace> webStorageNamespace)
+ : m_webStorageNamespace(webStorageNamespace)
+{
+}
+
+StorageNamespace::~StorageNamespace()
+{
+}
+
+PassOwnPtrWillBeRawPtr<StorageArea> StorageNamespace::localStorageArea(SecurityOrigin* origin)
+{
+ ASSERT(isMainThread());
+ static blink::WebStorageNamespace* localStorageNamespace = 0;
+ if (!localStorageNamespace)
+ localStorageNamespace = blink::Platform::current()->createLocalStorageNamespace();
+ return adoptPtrWillBeNoop(new StorageArea(adoptPtr(localStorageNamespace->createStorageArea(origin->toString())), LocalStorage));
+}
+
+PassOwnPtrWillBeRawPtr<StorageArea> StorageNamespace::storageArea(SecurityOrigin* origin)
+{
+ return adoptPtrWillBeNoop(new StorageArea(adoptPtr(m_webStorageNamespace->createStorageArea(origin->toString())), SessionStorage));
+}
+
+bool StorageNamespace::isSameNamespace(const blink::WebStorageNamespace& sessionNamespace) const
+{
+ return m_webStorageNamespace && m_webStorageNamespace->isSameNamespace(sessionNamespace);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/storage/StorageNamespace.h b/chromium/third_party/WebKit/Source/core/storage/StorageNamespace.h
index e3f7a9ba16d..64aa9a1544a 100644
--- a/chromium/third_party/WebKit/Source/core/storage/StorageNamespace.h
+++ b/chromium/third_party/WebKit/Source/core/storage/StorageNamespace.h
@@ -26,8 +26,14 @@
#ifndef StorageNamespace_h
#define StorageNamespace_h
+#include "platform/heap/Handle.h"
+#include "wtf/OwnPtr.h"
#include "wtf/PassOwnPtr.h"
+namespace blink {
+class WebStorageNamespace;
+}
+
namespace WebCore {
class Page;
@@ -36,11 +42,16 @@ class StorageArea;
class StorageNamespace {
public:
- static PassOwnPtr<StorageArea> localStorageArea(SecurityOrigin*);
- static PassOwnPtr<StorageNamespace> sessionStorageNamespace(Page*);
+ explicit StorageNamespace(PassOwnPtr<blink::WebStorageNamespace>);
+ ~StorageNamespace();
+
+ static PassOwnPtrWillBeRawPtr<StorageArea> localStorageArea(SecurityOrigin*);
+
+ PassOwnPtrWillBeRawPtr<StorageArea> storageArea(SecurityOrigin*);
+ bool isSameNamespace(const blink::WebStorageNamespace& sessionNamespace) const;
- virtual ~StorageNamespace() { }
- virtual PassOwnPtr<StorageArea> storageArea(SecurityOrigin*) = 0;
+private:
+ OwnPtr<blink::WebStorageNamespace> m_webStorageNamespace;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/ColorDistance.cpp b/chromium/third_party/WebKit/Source/core/svg/ColorDistance.cpp
index 00008684340..3af73c5343d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/ColorDistance.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/ColorDistance.cpp
@@ -21,54 +21,22 @@
#include "core/svg/ColorDistance.h"
#include "platform/graphics/Color.h"
-#include "wtf/MathExtras.h"
namespace WebCore {
-ColorDistance::ColorDistance()
- : m_redDiff(0)
- , m_greenDiff(0)
- , m_blueDiff(0)
-{
-}
-
-ColorDistance::ColorDistance(const Color& fromColor, const Color& toColor)
- : m_redDiff(toColor.red() - fromColor.red())
- , m_greenDiff(toColor.green() - fromColor.green())
- , m_blueDiff(toColor.blue() - fromColor.blue())
-{
-}
-
-ColorDistance::ColorDistance(int redDiff, int greenDiff, int blueDiff)
- : m_redDiff(redDiff)
- , m_greenDiff(greenDiff)
- , m_blueDiff(blueDiff)
-{
-}
-
-static inline int clampColorValue(int v)
-{
- if (v > 255)
- v = 255;
- else if (v < 0)
- v = 0;
- return v;
-}
-
-Color ColorDistance::clampColor(int red, int green, int blue, int alpha)
-{
- return Color(clampColorValue(red), clampColorValue(green), clampColorValue(blue), clampColorValue(alpha));
-}
-
Color ColorDistance::addColors(const Color& first, const Color& second)
{
return Color(first.red() + second.red(), first.green() + second.green(), first.blue() + second.blue());
}
-float ColorDistance::distance() const
+float ColorDistance::distance(const Color& fromColor, const Color& toColor)
{
+ int redDiff = toColor.red() - fromColor.red();
+ int greenDiff = toColor.green() - fromColor.green();
+ int blueDiff = toColor.blue() - fromColor.blue();
+
// This is just a simple distance calculation, not respecting color spaces
- return sqrtf(m_redDiff * m_redDiff + m_blueDiff * m_blueDiff + m_greenDiff * m_greenDiff);
+ return sqrtf(redDiff * redDiff + blueDiff * blueDiff + greenDiff * greenDiff);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/ColorDistance.h b/chromium/third_party/WebKit/Source/core/svg/ColorDistance.h
index 470effb7598..0eddc28daa2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/ColorDistance.h
+++ b/chromium/third_party/WebKit/Source/core/svg/ColorDistance.h
@@ -26,20 +26,10 @@ class Color;
class ColorDistance {
public:
- ColorDistance();
- ColorDistance(const Color& fromColor, const Color& toColor);
- ColorDistance(int redDiff, int blueDiff, int greenDiff);
-
static Color addColors(const Color&, const Color&);
- static Color clampColor(int red, int green, int blue, int alpha);
-
- float distance() const;
-
-private:
- int m_redDiff;
- int m_greenDiff;
- int m_blueDiff;
+ static float distance(const Color& fromColor, const Color& toColor);
};
+
}
#endif // ColorDistance_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/LinearGradientAttributes.h b/chromium/third_party/WebKit/Source/core/svg/LinearGradientAttributes.h
index ccf47b1ff57..30d4cac0276 100644
--- a/chromium/third_party/WebKit/Source/core/svg/LinearGradientAttributes.h
+++ b/chromium/third_party/WebKit/Source/core/svg/LinearGradientAttributes.h
@@ -25,26 +25,27 @@
namespace WebCore {
struct LinearGradientAttributes : GradientAttributes {
LinearGradientAttributes()
- : m_x1()
- , m_y1()
- , m_x2(LengthModeWidth, "100%")
- , m_y2()
+ : m_x1(SVGLength::create(LengthModeWidth))
+ , m_y1(SVGLength::create(LengthModeWidth))
+ , m_x2(SVGLength::create(LengthModeWidth))
+ , m_y2(SVGLength::create(LengthModeWidth))
, m_x1Set(false)
, m_y1Set(false)
, m_x2Set(false)
, m_y2Set(false)
{
+ m_x2->setValueAsString("100%", ASSERT_NO_EXCEPTION);
}
- SVGLength x1() const { return m_x1; }
- SVGLength y1() const { return m_y1; }
- SVGLength x2() const { return m_x2; }
- SVGLength y2() const { return m_y2; }
+ SVGLength* x1() const { return m_x1.get(); }
+ SVGLength* y1() const { return m_y1.get(); }
+ SVGLength* x2() const { return m_x2.get(); }
+ SVGLength* y2() const { return m_y2.get(); }
- void setX1(const SVGLength& value) { m_x1 = value; m_x1Set = true; }
- void setY1(const SVGLength& value) { m_y1 = value; m_y1Set = true; }
- void setX2(const SVGLength& value) { m_x2 = value; m_x2Set = true; }
- void setY2(const SVGLength& value) { m_y2 = value; m_y2Set = true; }
+ void setX1(PassRefPtr<SVGLength> value) { m_x1 = value; m_x1Set = true; }
+ void setY1(PassRefPtr<SVGLength> value) { m_y1 = value; m_y1Set = true; }
+ void setX2(PassRefPtr<SVGLength> value) { m_x2 = value; m_x2Set = true; }
+ void setY2(PassRefPtr<SVGLength> value) { m_y2 = value; m_y2Set = true; }
bool hasX1() const { return m_x1Set; }
bool hasY1() const { return m_y1Set; }
@@ -53,10 +54,10 @@ struct LinearGradientAttributes : GradientAttributes {
private:
// Properties
- SVGLength m_x1;
- SVGLength m_y1;
- SVGLength m_x2;
- SVGLength m_y2;
+ RefPtr<SVGLength> m_x1;
+ RefPtr<SVGLength> m_y1;
+ RefPtr<SVGLength> m_x2;
+ RefPtr<SVGLength> m_y2;
// Property states
bool m_x1Set : 1;
diff --git a/chromium/third_party/WebKit/Source/core/svg/PatternAttributes.h b/chromium/third_party/WebKit/Source/core/svg/PatternAttributes.h
index 7e4ae7520ca..3ce308a333e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/PatternAttributes.h
+++ b/chromium/third_party/WebKit/Source/core/svg/PatternAttributes.h
@@ -30,12 +30,12 @@ class SVGPatternElement;
struct PatternAttributes {
PatternAttributes()
- : m_x()
- , m_y()
- , m_width()
- , m_height()
+ : m_x(SVGLength::create(LengthModeWidth))
+ , m_y(SVGLength::create(LengthModeHeight))
+ , m_width(SVGLength::create(LengthModeWidth))
+ , m_height(SVGLength::create(LengthModeHeight))
, m_viewBox()
- , m_preserveAspectRatio()
+ , m_preserveAspectRatio(SVGPreserveAspectRatio::create())
, m_patternUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
, m_patternContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
, m_patternContentElement(0)
@@ -52,36 +52,36 @@ struct PatternAttributes {
{
}
- SVGLength x() const { return m_x; }
- SVGLength y() const { return m_y; }
- SVGLength width() const { return m_width; }
- SVGLength height() const { return m_height; }
+ SVGLength* x() const { return m_x.get(); }
+ SVGLength* y() const { return m_y.get(); }
+ SVGLength* width() const { return m_width.get(); }
+ SVGLength* height() const { return m_height.get(); }
FloatRect viewBox() const { return m_viewBox; }
- SVGPreserveAspectRatio preserveAspectRatio() const { return m_preserveAspectRatio; }
+ SVGPreserveAspectRatio* preserveAspectRatio() const { return m_preserveAspectRatio.get(); }
SVGUnitTypes::SVGUnitType patternUnits() const { return m_patternUnits; }
SVGUnitTypes::SVGUnitType patternContentUnits() const { return m_patternContentUnits; }
AffineTransform patternTransform() const { return m_patternTransform; }
const SVGPatternElement* patternContentElement() const { return m_patternContentElement; }
- void setX(const SVGLength& value)
+ void setX(PassRefPtr<SVGLength> value)
{
m_x = value;
m_xSet = true;
}
- void setY(const SVGLength& value)
+ void setY(PassRefPtr<SVGLength> value)
{
m_y = value;
m_ySet = true;
}
- void setWidth(const SVGLength& value)
+ void setWidth(PassRefPtr<SVGLength> value)
{
m_width = value;
m_widthSet = true;
}
- void setHeight(const SVGLength& value)
+ void setHeight(PassRefPtr<SVGLength> value)
{
m_height = value;
m_heightSet = true;
@@ -93,7 +93,7 @@ struct PatternAttributes {
m_viewBoxSet = true;
}
- void setPreserveAspectRatio(const SVGPreserveAspectRatio& value)
+ void setPreserveAspectRatio(PassRefPtr<SVGPreserveAspectRatio> value)
{
m_preserveAspectRatio = value;
m_preserveAspectRatioSet = true;
@@ -136,12 +136,12 @@ struct PatternAttributes {
private:
// Properties
- SVGLength m_x;
- SVGLength m_y;
- SVGLength m_width;
- SVGLength m_height;
+ RefPtr<SVGLength> m_x;
+ RefPtr<SVGLength> m_y;
+ RefPtr<SVGLength> m_width;
+ RefPtr<SVGLength> m_height;
FloatRect m_viewBox;
- SVGPreserveAspectRatio m_preserveAspectRatio;
+ RefPtr<SVGPreserveAspectRatio> m_preserveAspectRatio;
SVGUnitTypes::SVGUnitType m_patternUnits;
SVGUnitTypes::SVGUnitType m_patternContentUnits;
AffineTransform m_patternTransform;
diff --git a/chromium/third_party/WebKit/Source/core/svg/RadialGradientAttributes.h b/chromium/third_party/WebKit/Source/core/svg/RadialGradientAttributes.h
index f52dd326ae0..ba0a8f4eb17 100644
--- a/chromium/third_party/WebKit/Source/core/svg/RadialGradientAttributes.h
+++ b/chromium/third_party/WebKit/Source/core/svg/RadialGradientAttributes.h
@@ -25,9 +25,12 @@
namespace WebCore {
struct RadialGradientAttributes : GradientAttributes {
RadialGradientAttributes()
- : m_cx(LengthModeWidth, "50%")
- , m_cy(LengthModeWidth, "50%")
- , m_r(LengthModeWidth, "50%")
+ : m_cx(SVGLength::create(LengthModeWidth))
+ , m_cy(SVGLength::create(LengthModeHeight))
+ , m_r(SVGLength::create(LengthModeOther))
+ , m_fx(SVGLength::create(LengthModeWidth))
+ , m_fy(SVGLength::create(LengthModeHeight))
+ , m_fr(SVGLength::create(LengthModeOther))
, m_cxSet(false)
, m_cySet(false)
, m_rSet(false)
@@ -35,21 +38,24 @@ struct RadialGradientAttributes : GradientAttributes {
, m_fySet(false)
, m_frSet(false)
{
+ m_cx->setValueAsString("50%", IGNORE_EXCEPTION);
+ m_cy->setValueAsString("50%", IGNORE_EXCEPTION);
+ m_r->setValueAsString("50%", IGNORE_EXCEPTION);
}
- SVGLength cx() const { return m_cx; }
- SVGLength cy() const { return m_cy; }
- SVGLength r() const { return m_r; }
- SVGLength fx() const { return m_fx; }
- SVGLength fy() const { return m_fy; }
- SVGLength fr() const { return m_fr; }
+ SVGLength* cx() const { return m_cx.get(); }
+ SVGLength* cy() const { return m_cy.get(); }
+ SVGLength* r() const { return m_r.get(); }
+ SVGLength* fx() const { return m_fx.get(); }
+ SVGLength* fy() const { return m_fy.get(); }
+ SVGLength* fr() const { return m_fr.get(); }
- void setCx(const SVGLength& value) { m_cx = value; m_cxSet = true; }
- void setCy(const SVGLength& value) { m_cy = value; m_cySet = true; }
- void setR(const SVGLength& value) { m_r = value; m_rSet = true; }
- void setFx(const SVGLength& value) { m_fx = value; m_fxSet = true; }
- void setFy(const SVGLength& value) { m_fy = value; m_fySet = true; }
- void setFr(const SVGLength& value) { m_fr = value; m_frSet = true; }
+ void setCx(PassRefPtr<SVGLength> value) { m_cx = value; m_cxSet = true; }
+ void setCy(PassRefPtr<SVGLength> value) { m_cy = value; m_cySet = true; }
+ void setR(PassRefPtr<SVGLength> value) { m_r = value; m_rSet = true; }
+ void setFx(PassRefPtr<SVGLength> value) { m_fx = value; m_fxSet = true; }
+ void setFy(PassRefPtr<SVGLength> value) { m_fy = value; m_fySet = true; }
+ void setFr(PassRefPtr<SVGLength> value) { m_fr = value; m_frSet = true; }
bool hasCx() const { return m_cxSet; }
bool hasCy() const { return m_cySet; }
@@ -60,12 +66,12 @@ struct RadialGradientAttributes : GradientAttributes {
private:
// Properties
- SVGLength m_cx;
- SVGLength m_cy;
- SVGLength m_r;
- SVGLength m_fx;
- SVGLength m_fy;
- SVGLength m_fr;
+ RefPtr<SVGLength> m_cx;
+ RefPtr<SVGLength> m_cy;
+ RefPtr<SVGLength> m_r;
+ RefPtr<SVGLength> m_fx;
+ RefPtr<SVGLength> m_fy;
+ RefPtr<SVGLength> m_fr;
// Property states
bool m_cxSet : 1;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAElement.cpp
index 4cac139fddc..baa6754333f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAElement.cpp
@@ -24,15 +24,15 @@
#include "core/svg/SVGAElement.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Attr.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/events/KeyboardEvent.h"
#include "core/events/MouseEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/Frame.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLAnchorElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
@@ -45,7 +45,6 @@
#include "core/rendering/svg/RenderSVGInline.h"
#include "core/rendering/svg/RenderSVGText.h"
#include "core/rendering/svg/RenderSVGTransformableContainer.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/animation/SVGSMILElement.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/network/ResourceRequest.h"
@@ -54,29 +53,16 @@ namespace WebCore {
using namespace HTMLNames;
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGAElement, SVGNames::targetAttr, SVGTarget, svgTarget)
-DEFINE_ANIMATED_STRING(SVGAElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGAElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGAElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(svgTarget)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGAElement::SVGAElement(Document& document)
: SVGGraphicsElement(SVGNames::aTag, document)
+ , SVGURIReference(this)
+ , m_svgTarget(SVGAnimatedString::create(this, SVGNames::targetAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGAElement();
+ addToPropertyMap(m_svgTarget);
}
-PassRefPtr<SVGAElement> SVGAElement::create(Document& document)
-{
- return adoptRef(new SVGAElement(document));
-}
+DEFINE_NODE_FACTORY(SVGAElement)
String SVGAElement::title() const
{
@@ -94,7 +80,6 @@ bool SVGAElement::isSupportedAttribute(const QualifiedName& attrName)
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGURIReference::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::targetAttr);
}
return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
@@ -107,17 +92,16 @@ void SVGAElement::parseAttribute(const QualifiedName& name, const AtomicString&
return;
}
+ SVGParsingError parseError = NoError;
+
if (name == SVGNames::targetAttr) {
- setSVGTargetBaseValue(value);
- return;
+ m_svgTarget->setBaseValueAsString(value, parseError);
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else {
+ ASSERT_NOT_REACHED();
}
- if (SVGURIReference::parseAttribute(name, value))
- return;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGAElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -127,16 +111,16 @@ void SVGAElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
// Unlike other SVG*Element classes, SVGAElement only listens to SVGURIReference changes
// as none of the other properties changes the linking behaviour for our <a> element.
if (SVGURIReference::isKnownAttribute(attrName)) {
bool wasLink = isLink();
- setIsLink(!hrefCurrentValue().isNull());
+ setIsLink(!hrefString().isNull());
if (wasLink != isLink())
- setNeedsStyleRecalc();
+ setNeedsStyleRecalc(SubtreeStyleChange);
}
}
@@ -158,26 +142,23 @@ void SVGAElement::defaultEventHandler(Event* event)
}
if (isLinkClick(event)) {
- String url = stripLeadingAndTrailingHTMLSpaces(hrefCurrentValue());
+ String url = stripLeadingAndTrailingHTMLSpaces(hrefString());
if (url[0] == '#') {
- Element* targetElement = treeScope().getElementById(url.substring(1));
+ Element* targetElement = treeScope().getElementById(AtomicString(url.substring(1)));
if (targetElement && isSVGSMILElement(*targetElement)) {
toSVGSMILElement(targetElement)->beginByLinkActivation();
event->setDefaultHandled();
return;
}
- // Only allow navigation to internal <view> anchors.
- if (targetElement && !targetElement->hasTagName(SVGNames::viewTag))
- return;
}
- String target = this->target();
+ AtomicString target(m_svgTarget->currentValue()->value());
if (target.isEmpty() && fastGetAttribute(XLinkNames::showAttr) == "new")
- target = "_blank";
+ target = AtomicString("_blank", AtomicString::ConstructFromLiteral);
event->setDefaultHandled();
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
FrameLoadRequest frameRequest(&document(), ResourceRequest(document().completeURL(url)), target);
@@ -190,19 +171,18 @@ void SVGAElement::defaultEventHandler(Event* event)
SVGGraphicsElement::defaultEventHandler(event);
}
-bool SVGAElement::supportsFocus() const
+short SVGAElement::tabIndex() const
{
- if (rendererIsEditable())
- return SVGGraphicsElement::supportsFocus();
- return true;
+ // Skip the supportsFocus check in SVGElement.
+ return Element::tabIndex();
}
-bool SVGAElement::rendererIsFocusable() const
+bool SVGAElement::supportsFocus() const
{
- if (renderer() && renderer()->absoluteClippedOverflowRect().isEmpty())
- return false;
-
- return SVGElement::rendererIsFocusable();
+ if (rendererIsEditable())
+ return SVGGraphicsElement::supportsFocus();
+ // If not a link we should still be able to focus the element if it has tabIndex.
+ return isLink() || Element::supportsFocus();
}
bool SVGAElement::isURLAttribute(const Attribute& attribute) const
@@ -212,29 +192,34 @@ bool SVGAElement::isURLAttribute(const Attribute& attribute) const
bool SVGAElement::isMouseFocusable() const
{
- return false;
+ // Links are focusable by default, but only allow links with tabindex or contenteditable to be mouse focusable.
+ // https://bugs.webkit.org/show_bug.cgi?id=26856
+ if (isLink())
+ return Element::supportsFocus();
+
+ return SVGElement::isMouseFocusable();
}
bool SVGAElement::isKeyboardFocusable() const
{
- if (!isFocusable())
- return false;
+ if (isFocusable() && Element::supportsFocus())
+ return SVGElement::isKeyboardFocusable();
- if (Page* page = document().page())
- return page->chrome().client().tabsToLinks();
- return false;
+ if (isLink())
+ return document().frameHost()->chrome().client().tabsToLinks();
+ return SVGElement::isKeyboardFocusable();
+}
+
+bool SVGAElement::canStartSelection() const
+{
+ if (!isLink())
+ return SVGElement::canStartSelection();
+ return rendererIsEditable();
}
-bool SVGAElement::childShouldCreateRenderer(const Node& child) const
+bool SVGAElement::willRespondToMouseClickEvents()
{
- // http://www.w3.org/2003/01/REC-SVG11-20030114-errata#linking-text-environment
- // The 'a' element may contain any element that its parent may contain, except itself.
- if (child.hasTagName(SVGNames::aTag))
- return false;
- if (parentNode() && parentNode()->isSVGElement())
- return parentNode()->childShouldCreateRenderer(child);
-
- return SVGGraphicsElement::childShouldCreateRenderer(child);
+ return isLink() || SVGGraphicsElement::willRespondToMouseClickEvents();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAElement.h
index 10036dbee99..374bea0057b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAElement.h
@@ -23,49 +23,40 @@
#define SVGAElement_h
#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
#include "core/svg/SVGURIReference.h"
namespace WebCore {
class SVGAElement FINAL : public SVGGraphicsElement,
- public SVGURIReference,
- public SVGExternalResourcesRequired {
+ public SVGURIReference {
public:
- static PassRefPtr<SVGAElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGAElement);
+ SVGAnimatedString* svgTarget() { return m_svgTarget.get(); }
private:
explicit SVGAElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
-
- virtual String title() const;
- virtual String target() const { return svgTargetCurrentValue(); }
+ virtual String title() const OVERRIDE;
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual void defaultEventHandler(Event*);
+ virtual void defaultEventHandler(Event*) OVERRIDE;
virtual bool supportsFocus() const OVERRIDE;
virtual bool isMouseFocusable() const OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual bool rendererIsFocusable() const OVERRIDE;
- virtual bool isURLAttribute(const Attribute&) const;
+ virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
+ virtual bool canStartSelection() const OVERRIDE;
+ virtual short tabIndex() const OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const;
+ virtual bool willRespondToMouseClickEvents() OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAElement)
- // This declaration used to define a non-virtual "String& target() const" method, that clashes with "virtual String Element::target() const".
- // That's why it has been renamed to "svgTarget", the CodeGenerators take care of calling svgTargetAnimated() instead of targetAnimated(), see CodeGenerator.pm.
- DECLARE_ANIMATED_STRING(SVGTarget, svgTarget)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedString> m_svgTarget;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAElement.idl
index bcbb51787a1..8f0288ee63a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAElement.idl
@@ -27,6 +27,5 @@ interface SVGAElement : SVGGraphicsElement {
[ImplementedAs=svgTarget] readonly attribute SVGAnimatedString target;
};
-SVGAElement implements SVGExternalResourcesRequired;
SVGAElement implements SVGURIReference;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.cpp
index 4924ec5f3c5..e5bc92b7509 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.cpp
@@ -22,7 +22,8 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGAltGlyphDefElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/svg/SVGAltGlyphItemElement.h"
#include "core/svg/SVGGlyphRefElement.h"
@@ -34,12 +35,9 @@ inline SVGAltGlyphDefElement::SVGAltGlyphDefElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGAltGlyphDefElement> SVGAltGlyphDefElement::create(Document& document)
-{
- return adoptRef(new SVGAltGlyphDefElement(document));
-}
+DEFINE_NODE_FACTORY(SVGAltGlyphDefElement)
-bool SVGAltGlyphDefElement::hasValidGlyphElements(Vector<String>& glyphNames) const
+bool SVGAltGlyphDefElement::hasValidGlyphElements(Vector<AtomicString>& glyphNames) const
{
// Spec: http://www.w3.org/TR/SVG/text.html#AltGlyphDefElement
// An 'altGlyphDef' can contain either of the following:
@@ -88,10 +86,10 @@ bool SVGAltGlyphDefElement::hasValidGlyphElements(Vector<String>& glyphNames) co
bool fountFirstGlyphRef = false;
bool foundFirstAltGlyphItem = false;
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (!foundFirstAltGlyphItem && child->hasTagName(SVGNames::glyphRefTag)) {
+ for (SVGElement* child = Traversal<SVGElement>::firstChild(*this); child; child = Traversal<SVGElement>::nextSibling(*child)) {
+ if (!foundFirstAltGlyphItem && isSVGGlyphRefElement(*child)) {
fountFirstGlyphRef = true;
- String referredGlyphName;
+ AtomicString referredGlyphName;
if (toSVGGlyphRefElement(child)->hasValidGlyphElement(referredGlyphName))
glyphNames.append(referredGlyphName);
@@ -103,13 +101,13 @@ bool SVGAltGlyphDefElement::hasValidGlyphElements(Vector<String>& glyphNames) co
glyphNames.clear();
return false;
}
- } else if (!fountFirstGlyphRef && child->hasTagName(SVGNames::altGlyphItemTag)) {
+ } else if (!fountFirstGlyphRef && isSVGAltGlyphItemElement(*child)) {
foundFirstAltGlyphItem = true;
- Vector<String> referredGlyphNames;
+ Vector<AtomicString> referredGlyphNames;
// As the spec says "The first 'altGlyphItem' in which all referenced glyphs
// are available is chosen."
- if (static_cast<SVGAltGlyphItemElement*>(child)->hasValidGlyphElements(glyphNames) && !glyphNames.isEmpty())
+ if (toSVGAltGlyphItemElement(child)->hasValidGlyphElements(glyphNames) && !glyphNames.isEmpty())
return true;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.h
index e55794417b7..c6beca3e480 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphDefElement.h
@@ -21,6 +21,7 @@
#define SVGAltGlyphDefElement_h
#if ENABLE(SVG_FONTS)
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
#include "wtf/Vector.h"
@@ -28,9 +29,9 @@ namespace WebCore {
class SVGAltGlyphDefElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGAltGlyphDefElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGAltGlyphDefElement);
- bool hasValidGlyphElements(Vector<String>& glyphNames) const;
+ bool hasValidGlyphElements(Vector<AtomicString>& glyphNames) const;
private:
explicit SVGAltGlyphDefElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp
index b170919f5b9..b57d257242b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp
@@ -25,38 +25,28 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGAltGlyphElement.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/ExceptionCode.h"
#include "core/rendering/svg/RenderSVGTSpan.h"
#include "core/svg/SVGAltGlyphDefElement.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGAltGlyphElement, XLinkNames::hrefAttr, Href, href)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGAltGlyphElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextPositioningElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGAltGlyphElement::SVGAltGlyphElement(Document& document)
: SVGTextPositioningElement(SVGNames::altGlyphTag, document)
+ , SVGURIReference(this)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGAltGlyphElement();
}
-PassRefPtr<SVGAltGlyphElement> SVGAltGlyphElement::create(Document& document)
-{
- return adoptRef(new SVGAltGlyphElement(document));
-}
+DEFINE_NODE_FACTORY(SVGAltGlyphElement)
void SVGAltGlyphElement::setGlyphRef(const AtomicString&, ExceptionState& exceptionState)
{
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
+ exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly());
}
const AtomicString& SVGAltGlyphElement::glyphRef() const
@@ -66,7 +56,7 @@ const AtomicString& SVGAltGlyphElement::glyphRef() const
void SVGAltGlyphElement::setFormat(const AtomicString&, ExceptionState& exceptionState)
{
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
+ exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly());
}
const AtomicString& SVGAltGlyphElement::format() const
@@ -74,32 +64,24 @@ const AtomicString& SVGAltGlyphElement::format() const
return fastGetAttribute(SVGNames::formatAttr);
}
-bool SVGAltGlyphElement::childShouldCreateRenderer(const Node& child) const
-{
- if (child.isTextNode())
- return true;
- return false;
-}
-
RenderObject* SVGAltGlyphElement::createRenderer(RenderStyle*)
{
return new RenderSVGTSpan(this);
}
-bool SVGAltGlyphElement::hasValidGlyphElements(Vector<String>& glyphNames) const
+bool SVGAltGlyphElement::hasValidGlyphElements(Vector<AtomicString>& glyphNames) const
{
- String target;
- Element* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), document(), &target);
+ AtomicString target;
+ Element* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), treeScope(), &target);
if (!element)
return false;
- if (element->hasTagName(SVGNames::glyphTag)) {
+ if (isSVGGlyphElement(*element)) {
glyphNames.append(target);
return true;
}
- if (element->hasTagName(SVGNames::altGlyphDefTag)
- && static_cast<SVGAltGlyphDefElement*>(element)->hasValidGlyphElements(glyphNames))
+ if (isSVGAltGlyphDefElement(*element) && toSVGAltGlyphDefElement(*element).hasValidGlyphElements(glyphNames))
return true;
return false;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.h
index 841e1f0993e..afd562b8d4b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphElement.h
@@ -23,6 +23,7 @@
#define SVGAltGlyphElement_h
#if ENABLE(SVG_FONTS)
+#include "core/SVGNames.h"
#include "core/svg/SVGTextPositioningElement.h"
#include "core/svg/SVGURIReference.h"
#include "wtf/Vector.h"
@@ -30,29 +31,23 @@
namespace WebCore {
class ExceptionState;
-class SVGGlyphElement;
class SVGAltGlyphElement FINAL : public SVGTextPositioningElement,
public SVGURIReference {
public:
- static PassRefPtr<SVGAltGlyphElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGAltGlyphElement);
const AtomicString& glyphRef() const;
void setGlyphRef(const AtomicString&, ExceptionState&);
const AtomicString& format() const;
void setFormat(const AtomicString&, ExceptionState&);
- bool hasValidGlyphElements(Vector<String>& glyphNames) const;
+ bool hasValidGlyphElements(Vector<AtomicString>& glyphNames) const;
private:
explicit SVGAltGlyphElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool childShouldCreateRenderer(const Node& child) const;
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAltGlyphElement)
- DECLARE_ANIMATED_STRING(Href, href)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp
index 662dfeb54b7..af583efbc7c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp
@@ -22,7 +22,7 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGAltGlyphItemElement.h"
-#include "SVGNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/svg/SVGGlyphRefElement.h"
namespace WebCore {
@@ -33,12 +33,9 @@ inline SVGAltGlyphItemElement::SVGAltGlyphItemElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGAltGlyphItemElement> SVGAltGlyphItemElement::create(Document& document)
-{
- return adoptRef(new SVGAltGlyphItemElement(document));
-}
+DEFINE_NODE_FACTORY(SVGAltGlyphItemElement)
-bool SVGAltGlyphItemElement::hasValidGlyphElements(Vector<String>& glyphNames) const
+bool SVGAltGlyphItemElement::hasValidGlyphElements(Vector<AtomicString>& glyphNames) const
{
// Spec: http://www.w3.org/TR/SVG/text.html#AltGlyphItemElement
// The ‘altGlyphItem’ element defines a candidate set of possible glyph substitutions.
@@ -48,15 +45,13 @@ bool SVGAltGlyphItemElement::hasValidGlyphElements(Vector<String>& glyphNames) c
//
// Here we fill glyphNames and return true only if all referenced glyphs are valid and
// there is at least one glyph.
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(SVGNames::glyphRefTag)) {
- String referredGlyphName;
- if (toSVGGlyphRefElement(child)->hasValidGlyphElement(referredGlyphName))
- glyphNames.append(referredGlyphName);
- else {
- glyphNames.clear();
- return false;
- }
+ for (SVGGlyphRefElement* glyph = Traversal<SVGGlyphRefElement>::firstChild(*this); glyph; glyph = Traversal<SVGGlyphRefElement>::nextSibling(*glyph)) {
+ AtomicString referredGlyphName;
+ if (glyph->hasValidGlyphElement(referredGlyphName)) {
+ glyphNames.append(referredGlyphName);
+ } else {
+ glyphNames.clear();
+ return false;
}
}
return !glyphNames.isEmpty();
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.h
index cf4c9b09180..41004697009 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.h
@@ -21,6 +21,7 @@
#define SVGAltGlyphItemElement_h
#if ENABLE(SVG_FONTS)
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
#include "wtf/Vector.h"
@@ -28,9 +29,9 @@ namespace WebCore {
class SVGAltGlyphItemElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGAltGlyphItemElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGAltGlyphItemElement);
- bool hasValidGlyphElements(Vector<String>& glyphNames) const;
+ bool hasValidGlyphElements(Vector<AtomicString>& glyphNames) const;
private:
explicit SVGAltGlyphItemElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAngle.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAngle.cpp
index 30f4155db32..eedb177409e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAngle.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAngle.cpp
@@ -23,17 +23,91 @@
#include "core/svg/SVGAngle.h"
#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
#include "core/svg/SVGParserUtilities.h"
#include "wtf/MathExtras.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerOrientType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(SVGMarkerOrientAuto, "auto"));
+ entries.append(std::make_pair(SVGMarkerOrientAngle, "angle"));
+ }
+ return entries;
+}
+
+SVGMarkerOrientEnumeration::SVGMarkerOrientEnumeration(SVGAngle* angle)
+ : SVGEnumeration<SVGMarkerOrientType>(SVGMarkerOrientAngle)
+ , m_angle(angle)
+{
+}
+
+SVGMarkerOrientEnumeration::~SVGMarkerOrientEnumeration()
+{
+}
+
+void SVGMarkerOrientEnumeration::notifyChange()
+{
+ ASSERT(m_angle);
+ m_angle->orientTypeChanged();
+}
+
+void SVGMarkerOrientEnumeration::add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*)
+{
+ // SVGMarkerOrientEnumeration is only animated via SVGAngle
+ ASSERT_NOT_REACHED();
+}
+
+void SVGMarkerOrientEnumeration::calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+{
+ // SVGMarkerOrientEnumeration is only animated via SVGAngle
+ ASSERT_NOT_REACHED();
+}
+
+float SVGMarkerOrientEnumeration::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement)
+{
+ // SVGMarkerOrientEnumeration is only animated via SVGAngle
+ ASSERT_NOT_REACHED();
+ return -1.0;
+}
+
SVGAngle::SVGAngle()
- : m_unitType(SVG_ANGLETYPE_UNSPECIFIED)
+ : SVGPropertyBase(classType())
+ , m_unitType(SVG_ANGLETYPE_UNSPECIFIED)
, m_valueInSpecifiedUnits(0)
+ , m_orientType(SVGMarkerOrientEnumeration::create(this))
+{
+}
+
+SVGAngle::SVGAngle(SVGAngleType unitType, float valueInSpecifiedUnits, SVGMarkerOrientType orientType)
+ : SVGPropertyBase(classType())
+ , m_unitType(unitType)
+ , m_valueInSpecifiedUnits(valueInSpecifiedUnits)
+ , m_orientType(SVGMarkerOrientEnumeration::create(this))
{
+ m_orientType->setEnumValue(orientType);
+}
+
+SVGAngle::~SVGAngle()
+{
+}
+
+PassRefPtr<SVGAngle> SVGAngle::clone() const
+{
+ return adoptRef(new SVGAngle(m_unitType, m_valueInSpecifiedUnits, m_orientType->enumValue()));
+}
+
+PassRefPtr<SVGPropertyBase> SVGAngle::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGAngle> point = create();
+ point->setValueAsString(value, IGNORE_EXCEPTION);
+ return point.release();
}
float SVGAngle::value() const
@@ -43,6 +117,8 @@ float SVGAngle::value() const
return grad2deg(m_valueInSpecifiedUnits);
case SVG_ANGLETYPE_RAD:
return rad2deg(m_valueInSpecifiedUnits);
+ case SVG_ANGLETYPE_TURN:
+ return turn2deg(m_valueInSpecifiedUnits);
case SVG_ANGLETYPE_UNSPECIFIED:
case SVG_ANGLETYPE_UNKNOWN:
case SVG_ANGLETYPE_DEG:
@@ -62,12 +138,16 @@ void SVGAngle::setValue(float value)
case SVG_ANGLETYPE_RAD:
m_valueInSpecifiedUnits = deg2rad(value);
break;
+ case SVG_ANGLETYPE_TURN:
+ m_valueInSpecifiedUnits = deg2turn(value);
+ break;
case SVG_ANGLETYPE_UNSPECIFIED:
case SVG_ANGLETYPE_UNKNOWN:
case SVG_ANGLETYPE_DEG:
m_valueInSpecifiedUnits = value;
break;
}
+ m_orientType->setEnumValue(SVGMarkerOrientAngle);
}
template<typename CharType>
@@ -77,35 +157,29 @@ static SVGAngle::SVGAngleType stringToAngleType(const CharType*& ptr, const Char
if (ptr == end)
return SVGAngle::SVG_ANGLETYPE_UNSPECIFIED;
- const CharType firstChar = *ptr;
-
- // If the unit contains only one character, the angle type is unknown.
- ++ptr;
- if (ptr == end)
- return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
-
- const CharType secondChar = *ptr;
-
- // If the unit contains only two characters, the angle type is unknown.
- ++ptr;
- if (ptr == end)
- return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
-
- const CharType thirdChar = *ptr;
- if (firstChar == 'd' && secondChar == 'e' && thirdChar == 'g')
- return SVGAngle::SVG_ANGLETYPE_DEG;
- if (firstChar == 'r' && secondChar == 'a' && thirdChar == 'd')
- return SVGAngle::SVG_ANGLETYPE_RAD;
-
- // If the unit contains three characters, but is not deg or rad, then it's unknown.
- ++ptr;
- if (ptr == end)
- return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
-
- const CharType fourthChar = *ptr;
+ SVGAngle::SVGAngleType type = SVGAngle::SVG_ANGLETYPE_UNKNOWN;
+ const CharType firstChar = *ptr++;
+
+ if (isHTMLSpace<CharType>(firstChar)) {
+ type = SVGAngle::SVG_ANGLETYPE_UNSPECIFIED;
+ } else if (end - ptr >= 2) {
+ const CharType secondChar = *ptr++;
+ const CharType thirdChar = *ptr++;
+ if (firstChar == 'd' && secondChar == 'e' && thirdChar == 'g') {
+ type = SVGAngle::SVG_ANGLETYPE_DEG;
+ } else if (firstChar == 'r' && secondChar == 'a' && thirdChar == 'd') {
+ type = SVGAngle::SVG_ANGLETYPE_RAD;
+ } else if (ptr != end) {
+ const CharType fourthChar = *ptr++;
+ if (firstChar == 'g' && secondChar == 'r' && thirdChar == 'a' && fourthChar == 'd')
+ type = SVGAngle::SVG_ANGLETYPE_GRAD;
+ else if (firstChar == 't' && secondChar == 'u' && thirdChar == 'r' && fourthChar == 'n')
+ type = SVGAngle::SVG_ANGLETYPE_TURN;
+ }
+ }
- if (firstChar == 'g' && secondChar == 'r' && thirdChar == 'a' && fourthChar == 'd')
- return SVGAngle::SVG_ANGLETYPE_GRAD;
+ if (!skipOptionalSVGSpaces(ptr, end))
+ return type;
return SVGAngle::SVG_ANGLETYPE_UNKNOWN;
}
@@ -125,6 +199,10 @@ String SVGAngle::valueAsString() const
DEFINE_STATIC_LOCAL(String, gradString, ("grad"));
return String::number(m_valueInSpecifiedUnits) + gradString;
}
+ case SVG_ANGLETYPE_TURN: {
+ DEFINE_STATIC_LOCAL(String, turnString, ("turn"));
+ return String::number(m_valueInSpecifiedUnits) + turnString;
+ }
case SVG_ANGLETYPE_UNSPECIFIED:
case SVG_ANGLETYPE_UNKNOWN:
return String::number(m_valueInSpecifiedUnits);
@@ -140,7 +218,7 @@ static bool parseValue(const String& value, float& valueInSpecifiedUnits, SVGAng
const CharType* ptr = value.getCharacters<CharType>();
const CharType* end = ptr + value.length();
- if (!parseNumber(ptr, end, valueInSpecifiedUnits, false))
+ if (!parseNumber(ptr, end, valueInSpecifiedUnits, AllowLeadingWhitespace))
return false;
unitType = stringToAngleType(ptr, end);
@@ -153,7 +231,13 @@ static bool parseValue(const String& value, float& valueInSpecifiedUnits, SVGAng
void SVGAngle::setValueAsString(const String& value, ExceptionState& exceptionState)
{
if (value.isEmpty()) {
- m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
+ newValueSpecifiedUnits(SVG_ANGLETYPE_UNSPECIFIED, 0);
+ return;
+ }
+
+ if (value == "auto") {
+ newValueSpecifiedUnits(SVG_ANGLETYPE_UNSPECIFIED, 0);
+ m_orientType->setEnumValue(SVGMarkerOrientAuto);
return;
}
@@ -163,31 +247,26 @@ void SVGAngle::setValueAsString(const String& value, ExceptionState& exceptionSt
bool success = value.is8Bit() ? parseValue<LChar>(value, valueInSpecifiedUnits, unitType)
: parseValue<UChar>(value, valueInSpecifiedUnits, unitType);
if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + value + "') is invalid.");
return;
}
+ m_orientType->setEnumValue(SVGMarkerOrientAngle);
m_unitType = unitType;
m_valueInSpecifiedUnits = valueInSpecifiedUnits;
}
-void SVGAngle::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState& exceptionState)
+void SVGAngle::newValueSpecifiedUnits(SVGAngleType unitType, float valueInSpecifiedUnits)
{
- if (unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
-
- if (unitType != m_unitType)
- m_unitType = static_cast<SVGAngleType>(unitType);
-
+ m_orientType->setEnumValue(SVGMarkerOrientAngle);
+ m_unitType = unitType;
m_valueInSpecifiedUnits = valueInSpecifiedUnits;
}
-void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionState& exceptionState)
+void SVGAngle::convertToSpecifiedUnits(SVGAngleType unitType, ExceptionState& exceptionState)
{
- if (unitType == SVG_ANGLETYPE_UNKNOWN || m_unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ if (m_unitType == SVG_ANGLETYPE_UNKNOWN) {
+ exceptionState.throwDOMException(NotSupportedError, "Cannot convert from unknown or invalid units.");
return;
}
@@ -195,6 +274,24 @@ void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionState&
return;
switch (m_unitType) {
+ case SVG_ANGLETYPE_TURN:
+ switch (unitType) {
+ case SVG_ANGLETYPE_GRAD:
+ m_valueInSpecifiedUnits = turn2grad(m_valueInSpecifiedUnits);
+ break;
+ case SVG_ANGLETYPE_UNSPECIFIED:
+ case SVG_ANGLETYPE_DEG:
+ m_valueInSpecifiedUnits = turn2deg(m_valueInSpecifiedUnits);
+ break;
+ case SVG_ANGLETYPE_RAD:
+ m_valueInSpecifiedUnits = deg2rad(turn2deg(m_valueInSpecifiedUnits));
+ break;
+ case SVG_ANGLETYPE_TURN:
+ case SVG_ANGLETYPE_UNKNOWN:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+ break;
case SVG_ANGLETYPE_RAD:
switch (unitType) {
case SVG_ANGLETYPE_GRAD:
@@ -204,6 +301,9 @@ void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionState&
case SVG_ANGLETYPE_DEG:
m_valueInSpecifiedUnits = rad2deg(m_valueInSpecifiedUnits);
break;
+ case SVG_ANGLETYPE_TURN:
+ m_valueInSpecifiedUnits = deg2turn(rad2deg(m_valueInSpecifiedUnits));
+ break;
case SVG_ANGLETYPE_RAD:
case SVG_ANGLETYPE_UNKNOWN:
ASSERT_NOT_REACHED();
@@ -219,6 +319,9 @@ void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionState&
case SVG_ANGLETYPE_DEG:
m_valueInSpecifiedUnits = grad2deg(m_valueInSpecifiedUnits);
break;
+ case SVG_ANGLETYPE_TURN:
+ m_valueInSpecifiedUnits = grad2turn(m_valueInSpecifiedUnits);
+ break;
case SVG_ANGLETYPE_GRAD:
case SVG_ANGLETYPE_UNKNOWN:
ASSERT_NOT_REACHED();
@@ -235,9 +338,12 @@ void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionState&
case SVG_ANGLETYPE_GRAD:
m_valueInSpecifiedUnits = deg2grad(m_valueInSpecifiedUnits);
break;
- case SVG_ANGLETYPE_UNSPECIFIED:
+ case SVG_ANGLETYPE_TURN:
+ m_valueInSpecifiedUnits = deg2turn(m_valueInSpecifiedUnits);
break;
+ case SVG_ANGLETYPE_UNSPECIFIED:
case SVG_ANGLETYPE_DEG:
+ break;
case SVG_ANGLETYPE_UNKNOWN:
ASSERT_NOT_REACHED();
break;
@@ -248,7 +354,83 @@ void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionState&
break;
}
- m_unitType = static_cast<SVGAngleType>(unitType);
+ m_unitType = unitType;
+ m_orientType->setEnumValue(SVGMarkerOrientAngle);
+}
+
+void SVGAngle::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ RefPtr<SVGAngle> otherAngle = toSVGAngle(other);
+
+ // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto').
+ if (orientType()->enumValue() != SVGMarkerOrientAngle || otherAngle->orientType()->enumValue() != SVGMarkerOrientAngle)
+ return;
+
+ setValue(value() + otherAngle->value());
+}
+
+void SVGAngle::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDuration, SVGElement*)
+{
+ ASSERT(animationElement);
+ bool isToAnimation = animationElement->animationMode() == ToAnimation;
+
+ RefPtr<SVGAngle> fromAngle = isToAnimation ? this : toSVGAngle(from);
+ RefPtr<SVGAngle> toAngle = toSVGAngle(to);
+ RefPtr<SVGAngle> toAtEndOfDurationAngle = toSVGAngle(toAtEndOfDuration);
+
+ SVGMarkerOrientType fromOrientType = fromAngle->orientType()->enumValue();
+ SVGMarkerOrientType toOrientType = toAngle->orientType()->enumValue();
+
+ if (fromOrientType != toOrientType) {
+ // Animating from eg. auto to 90deg, or auto to 90deg.
+ if (fromOrientType == SVGMarkerOrientAngle) {
+ // Animating from an angle value to eg. 'auto' - this disabled additive as 'auto' is a keyword..
+ if (toOrientType == SVGMarkerOrientAuto) {
+ if (percentage < 0.5f) {
+ newValueSpecifiedUnits(fromAngle->unitType(), fromAngle->valueInSpecifiedUnits());
+ return;
+ }
+ orientType()->setEnumValue(SVGMarkerOrientAuto);
+ return;
+ }
+ m_valueInSpecifiedUnits = 0;
+ orientType()->setEnumValue(SVGMarkerOrientUnknown);
+ return;
+ }
+ }
+
+ // From 'auto' to 'auto'.
+ if (fromOrientType == SVGMarkerOrientAuto) {
+ m_valueInSpecifiedUnits = 0;
+ orientType()->setEnumValue(SVGMarkerOrientAuto);
+ return;
+ }
+
+ // If the enumeration value is not angle or auto, its unknown.
+ if (fromOrientType != SVGMarkerOrientAngle) {
+ m_valueInSpecifiedUnits = 0;
+ orientType()->setEnumValue(SVGMarkerOrientUnknown);
+ return;
+ }
+
+ // Regular from angle to angle animation, with all features like additive etc.
+ float animatedValue = value();
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngle->value(), toAngle->value(), toAtEndOfDurationAngle->value(), animatedValue);
+ orientType()->setEnumValue(SVGMarkerOrientAngle);
+ setValue(animatedValue);
+}
+
+float SVGAngle::calculateDistance(PassRefPtr<SVGPropertyBase> other, SVGElement*)
+{
+ return fabsf(value() - toSVGAngle(other)->value());
+}
+
+void SVGAngle::orientTypeChanged()
+{
+ if (orientType()->enumValue() == SVGMarkerOrientAuto) {
+ m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
+ m_valueInSpecifiedUnits = 0;
+ }
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAngle.h b/chromium/third_party/WebKit/Source/core/svg/SVGAngle.h
index 860d3f0f522..4f63310bc4c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAngle.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAngle.h
@@ -22,25 +22,62 @@
#ifndef SVGAngle_h
#define SVGAngle_h
-#include "core/svg/properties/SVGPropertyTraits.h"
+#include "core/svg/SVGEnumeration.h"
namespace WebCore {
-class ExceptionState;
+class SVGAngle;
+class SVGAngleTearOff;
-class SVGAngle {
- WTF_MAKE_FAST_ALLOCATED;
+enum SVGMarkerOrientType {
+ SVGMarkerOrientUnknown = 0,
+ SVGMarkerOrientAuto,
+ SVGMarkerOrientAngle
+};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerOrientType>();
+
+class SVGMarkerOrientEnumeration : public SVGEnumeration<SVGMarkerOrientType> {
public:
- SVGAngle();
+ static PassRefPtr<SVGMarkerOrientEnumeration> create(SVGAngle* angle)
+ {
+ return adoptRef(new SVGMarkerOrientEnumeration(angle));
+ }
+
+ virtual ~SVGMarkerOrientEnumeration();
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float, unsigned, PassRefPtr<SVGPropertyBase>, PassRefPtr<SVGPropertyBase>, PassRefPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+
+private:
+ SVGMarkerOrientEnumeration(SVGAngle*);
+
+ virtual void notifyChange() OVERRIDE;
+
+ // FIXME: oilpan: This is kept as raw-ptr to avoid reference cycles. Should be Member in oilpan.
+ SVGAngle* m_angle;
+};
+
+class SVGAngle : public SVGPropertyBase {
+public:
+ typedef SVGAngleTearOff TearOffType;
enum SVGAngleType {
SVG_ANGLETYPE_UNKNOWN = 0,
SVG_ANGLETYPE_UNSPECIFIED = 1,
SVG_ANGLETYPE_DEG = 2,
SVG_ANGLETYPE_RAD = 3,
- SVG_ANGLETYPE_GRAD = 4
+ SVG_ANGLETYPE_GRAD = 4,
+ SVG_ANGLETYPE_TURN = 5
};
+ static PassRefPtr<SVGAngle> create()
+ {
+ return adoptRef(new SVGAngle());
+ }
+
+ virtual ~SVGAngle();
+
SVGAngleType unitType() const { return m_unitType; }
void setValue(float);
@@ -49,22 +86,41 @@ public:
void setValueInSpecifiedUnits(float valueInSpecifiedUnits) { m_valueInSpecifiedUnits = valueInSpecifiedUnits; }
float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; }
+ void newValueSpecifiedUnits(SVGAngleType unitType, float valueInSpecifiedUnits);
+ void convertToSpecifiedUnits(SVGAngleType unitType, ExceptionState&);
+
+ SVGEnumeration<SVGMarkerOrientType>* orientType() { return m_orientType.get(); }
+ void orientTypeChanged();
+
+ // SVGPropertyBase:
+
+ PassRefPtr<SVGAngle> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+ virtual String valueAsString() const OVERRIDE;
void setValueAsString(const String&, ExceptionState&);
- String valueAsString() const;
- void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState&);
- void convertToSpecifiedUnits(unsigned short unitType, ExceptionState&);
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedAngle; }
private:
+ SVGAngle();
+ SVGAngle(SVGAngleType, float, SVGMarkerOrientType);
+
SVGAngleType m_unitType;
float m_valueInSpecifiedUnits;
+ RefPtr<SVGMarkerOrientEnumeration> m_orientType;
};
-template<>
-struct SVGPropertyTraits<SVGAngle> {
- static SVGAngle initialValue() { return SVGAngle(); }
- static String toString(const SVGAngle& type) { return type.valueAsString(); }
-};
+inline PassRefPtr<SVGAngle> toSVGAngle(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGAngle::classType());
+ return static_pointer_cast<SVGAngle>(base.release());
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAngle.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAngle.idl
index 665f6ead7fc..f4b306a5244 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAngle.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAngle.idl
@@ -20,7 +20,11 @@
* Boston, MA 02110-1301, USA.
*/
-interface SVGAngle {
+[
+ ImplementedAs=SVGAngleTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGAngle {
// Angle Unit Types
const unsigned short SVG_ANGLETYPE_UNKNOWN = 0;
const unsigned short SVG_ANGLETYPE_UNSPECIFIED = 1;
@@ -29,13 +33,13 @@ interface SVGAngle {
const unsigned short SVG_ANGLETYPE_GRAD = 4;
readonly attribute unsigned short unitType;
- [StrictTypeChecking] attribute float value;
- [StrictTypeChecking] attribute float valueInSpecifiedUnits;
+ [RaisesException=Setter] attribute float value;
+ [RaisesException=Setter] attribute float valueInSpecifiedUnits;
[TreatNullAs=NullString, RaisesException=Setter] attribute DOMString valueAsString;
- [StrictTypeChecking, RaisesException] void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits);
+ [RaisesException] void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits);
- [StrictTypeChecking, RaisesException] void convertToSpecifiedUnits(unsigned short unitType);
+ [RaisesException] void convertToSpecifiedUnits(unsigned short unitType);
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp
new file mode 100644
index 00000000000..33145fce03d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGAngleTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+SVGAngleTearOff::SVGAngleTearOff(PassRefPtr<SVGAngle> targetProperty, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ : SVGPropertyTearOff<SVGAngle>(targetProperty, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+SVGAngleTearOff::~SVGAngleTearOff()
+{
+}
+
+void SVGAngleTearOff::setValue(float value, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setValue(value);
+ commitChange();
+}
+
+void SVGAngleTearOff::setValueInSpecifiedUnits(float value, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setValueInSpecifiedUnits(value);
+ commitChange();
+}
+
+void SVGAngleTearOff::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ if (unitType == SVGAngle::SVG_ANGLETYPE_UNKNOWN || unitType > SVGAngle::SVG_ANGLETYPE_GRAD) {
+ exceptionState.throwDOMException(NotSupportedError, "Cannot set value with unknown or invalid units (" + String::number(unitType) + ").");
+ return;
+ }
+
+ target()->newValueSpecifiedUnits(static_cast<SVGAngle::SVGAngleType>(unitType), valueInSpecifiedUnits);
+ commitChange();
+}
+
+void SVGAngleTearOff::convertToSpecifiedUnits(unsigned short unitType, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ if (unitType == SVGAngle::SVG_ANGLETYPE_UNKNOWN || unitType > SVGAngle::SVG_ANGLETYPE_GRAD) {
+ exceptionState.throwDOMException(NotSupportedError, "Cannot convert to unknown or invalid units (" + String::number(unitType) + ").");
+ return;
+ }
+
+ target()->convertToSpecifiedUnits(static_cast<SVGAngle::SVGAngleType>(unitType), exceptionState);
+ if (!exceptionState.hadException())
+ commitChange();
+}
+
+void SVGAngleTearOff::setValueAsString(const String& value, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ String oldValue = target()->valueAsString();
+
+ target()->setValueAsString(value, exceptionState);
+
+ if (!exceptionState.hadException() && !hasExposedAngleUnit()) {
+ target()->setValueAsString(oldValue, ASSERT_NO_EXCEPTION); // rollback to old value
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + value + "') is invalid.");
+ return;
+ }
+
+ commitChange();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAngleTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGAngleTearOff.h
new file mode 100644
index 00000000000..798cf838d3e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAngleTearOff.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGAngleTearOff_h
+#define SVGAngleTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGAngle.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGAngleTearOff FINAL : public SVGPropertyTearOff<SVGAngle>, public ScriptWrappable {
+public:
+ static PassRefPtr<SVGAngleTearOff> create(PassRefPtr<SVGAngle> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGAngleTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ enum {
+ SVG_ANGLETYPE_UNKNOWN = SVGAngle::SVG_ANGLETYPE_UNKNOWN,
+ SVG_ANGLETYPE_UNSPECIFIED = SVGAngle::SVG_ANGLETYPE_UNSPECIFIED,
+ SVG_ANGLETYPE_DEG = SVGAngle::SVG_ANGLETYPE_DEG,
+ SVG_ANGLETYPE_RAD = SVGAngle::SVG_ANGLETYPE_RAD,
+ SVG_ANGLETYPE_GRAD = SVGAngle::SVG_ANGLETYPE_GRAD
+ };
+
+ virtual ~SVGAngleTearOff();
+
+ unsigned short unitType() { return hasExposedAngleUnit() ? target()->unitType() : SVGAngle::SVG_ANGLETYPE_UNKNOWN; }
+
+ void setValue(float, ExceptionState&);
+ float value() { return target()->value(); }
+
+ void setValueInSpecifiedUnits(float, ExceptionState&);
+ float valueInSpecifiedUnits() { return target()->valueInSpecifiedUnits(); }
+
+ void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState&);
+ void convertToSpecifiedUnits(unsigned short unitType, ExceptionState&);
+
+ String valueAsString() { return hasExposedAngleUnit() ? target()->valueAsString() : String::number(0); }
+ void setValueAsString(const String&, ExceptionState&);
+
+private:
+ SVGAngleTearOff(PassRefPtr<SVGAngle>, SVGElement*, PropertyIsAnimValType, const QualifiedName&);
+
+ bool hasExposedAngleUnit() { return target()->unitType() <= SVGAngle::SVG_ANGLETYPE_GRAD; }
+};
+
+} // namespace WebCore
+
+#endif // SVGAngleTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.cpp
deleted file mode 100644
index 7bf3842c491..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "SVGNames.h"
-#include "core/frame/UseCounter.h"
-#include "core/svg/SVGAnimateColorElement.h"
-
-namespace WebCore {
-
-inline SVGAnimateColorElement::SVGAnimateColorElement(Document& document)
- : SVGAnimateElement(SVGNames::animateColorTag, document)
-{
- ScriptWrappable::init(this);
-
- UseCounter::count(document, UseCounter::SVGAnimateColorElement);
-}
-
-PassRefPtr<SVGAnimateColorElement> SVGAnimateColorElement::create(Document& document)
-{
- return adoptRef(new SVGAnimateColorElement(document));
-}
-
-static bool attributeValueIsCurrentColor(const String& value)
-{
- DEFINE_STATIC_LOCAL(const AtomicString, currentColor, ("currentColor", AtomicString::ConstructFromLiteral));
- return value == currentColor;
-}
-
-void SVGAnimateColorElement::determinePropertyValueTypes(const String& from, const String& to)
-{
- SVGAnimateElement::determinePropertyValueTypes(from, to);
- if (attributeValueIsCurrentColor(from))
- m_fromPropertyValueType = CurrentColorValue;
- if (attributeValueIsCurrentColor(to))
- m_toPropertyValueType = CurrentColorValue;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.h
deleted file mode 100644
index f17ea2627ce..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimateColorElement_h
-#define SVGAnimateColorElement_h
-
-#include "core/svg/SVGAnimateElement.h"
-
-namespace WebCore {
-
-class SVGAnimateColorElement FINAL : public SVGAnimateElement {
-public:
- static PassRefPtr<SVGAnimateColorElement> create(Document&);
-
-private:
- explicit SVGAnimateColorElement(Document&);
- virtual void determinePropertyValueTypes(const String& from, const String& to);
-};
-
-} // namespace WebCore
-
-#endif // SVGAnimateColorElement_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.idl
deleted file mode 100644
index 69a58ebb74b..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateColorElement.idl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-interface SVGAnimateColorElement : SVGAnimationElement {
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
index 83e30da7fc3..c56ef5cb425 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp
@@ -24,34 +24,35 @@
#include "core/svg/SVGAnimateElement.h"
-#include "CSSPropertyNames.h"
-#include "core/css/CSSParser.h"
+#include "core/CSSPropertyNames.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/css/StylePropertySet.h"
+#include "core/dom/Document.h"
#include "core/dom/QualifiedName.h"
-#include "core/svg/SVGAnimatedType.h"
#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/SVGAnimatorFactory.h"
#include "core/svg/SVGDocumentExtensions.h"
namespace WebCore {
SVGAnimateElement::SVGAnimateElement(const QualifiedName& tagName, Document& document)
: SVGAnimationElement(tagName, document)
- , m_animatedPropertyType(AnimatedString)
{
- ASSERT(hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::setTag) || hasTagName(SVGNames::animateColorTag) || hasTagName(SVGNames::animateTransformTag));
+ ASSERT(isSVGAnimateElement(*this));
ScriptWrappable::init(this);
}
-PassRefPtr<SVGAnimateElement> SVGAnimateElement::create(Document& document)
+PassRefPtrWillBeRawPtr<SVGAnimateElement> SVGAnimateElement::create(Document& document)
{
- return adoptRef(new SVGAnimateElement(SVGNames::animateTag, document));
+ return adoptRefWillBeNoop(new SVGAnimateElement(SVGNames::animateTag, document));
}
SVGAnimateElement::~SVGAnimateElement()
{
- if (targetElement())
- clearAnimatedType(targetElement());
+}
+
+AnimatedPropertyType SVGAnimateElement::animatedPropertyType()
+{
+ return ensureAnimator()->type();
}
bool SVGAnimateElement::hasValidAttributeType()
@@ -60,39 +61,7 @@ bool SVGAnimateElement::hasValidAttributeType()
if (!targetElement)
return false;
- return m_animatedPropertyType != AnimatedUnknown && !hasInvalidCSSAttributeType();
-}
-
-AnimatedPropertyType SVGAnimateElement::determineAnimatedPropertyType(SVGElement* targetElement) const
-{
- ASSERT(targetElement);
-
- Vector<AnimatedPropertyType> propertyTypes;
- targetElement->animatedPropertyTypeForAttribute(attributeName(), propertyTypes);
- if (propertyTypes.isEmpty())
- return AnimatedUnknown;
-
- ASSERT(propertyTypes.size() <= 2);
- AnimatedPropertyType type = propertyTypes[0];
- if (hasTagName(SVGNames::animateColorTag) && type != AnimatedColor)
- return AnimatedUnknown;
-
- // Animations of transform lists are not allowed for <animate> or <set>
- // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
- if (type == AnimatedTransformList && !hasTagName(SVGNames::animateTransformTag))
- return AnimatedUnknown;
-
- // Fortunately there's just one special case needed here: SVGMarkerElements orientAttr, which
- // corresponds to SVGAnimatedAngle orientAngle and SVGAnimatedEnumeration orientType. We have to
- // figure out whose value to change here.
- if (targetElement->hasTagName(SVGNames::markerTag) && type == AnimatedAngle) {
- ASSERT(propertyTypes.size() == 2);
- ASSERT(propertyTypes[0] == AnimatedAngle);
- ASSERT(propertyTypes[1] == AnimatedEnumeration);
- } else if (propertyTypes.size() == 2)
- ASSERT(propertyTypes[0] == propertyTypes[1]);
-
- return type;
+ return animatedPropertyType() != AnimatedUnknown && !hasInvalidCSSAttributeType();
}
void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement)
@@ -102,22 +71,19 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
if (!targetElement || !isSVGAnimateElement(*resultElement))
return;
- ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(targetElement));
-
ASSERT(percentage >= 0 && percentage <= 1);
- ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag));
- ASSERT(m_animatedPropertyType != AnimatedUnknown);
ASSERT(m_animator);
- ASSERT(m_animator->type() == m_animatedPropertyType);
- ASSERT(m_fromType);
- ASSERT(m_fromType->type() == m_animatedPropertyType);
- ASSERT(m_toType);
+ ASSERT(animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this));
+ ASSERT(animatedPropertyType() != AnimatedUnknown);
+ ASSERT(m_fromProperty);
+ ASSERT(m_fromProperty->type() == animatedPropertyType());
+ ASSERT(m_toProperty);
SVGAnimateElement* resultAnimationElement = toSVGAnimateElement(resultElement);
- ASSERT(resultAnimationElement->m_animatedType);
- ASSERT(resultAnimationElement->m_animatedPropertyType == m_animatedPropertyType);
+ ASSERT(resultAnimationElement->m_animatedProperty);
+ ASSERT(resultAnimationElement->animatedPropertyType() == animatedPropertyType());
- if (hasTagName(SVGNames::setTag))
+ if (isSVGSetElement(*this))
percentage = 1;
if (calcMode() == CalcModeDiscrete)
@@ -126,23 +92,16 @@ void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeat
// Target element might have changed.
m_animator->setContextElement(targetElement);
- // Be sure to detach list wrappers before we modfiy their underlying value. If we'd do
- // if after calculateAnimatedValue() ran the cached pointers in the list propery tear
- // offs would point nowhere, and we couldn't create copies of those values anymore,
- // while detaching. This is covered by assertions, moving this down would fire them.
- if (!m_animatedProperties.isEmpty())
- m_animator->animValWillChange(m_animatedProperties);
-
// Values-animation accumulates using the last values entry corresponding to the end of duration time.
- SVGAnimatedType* toAtEndOfDurationType = m_toAtEndOfDurationType ? m_toAtEndOfDurationType.get() : m_toType.get();
- m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromType.get(), m_toType.get(), toAtEndOfDurationType, resultAnimationElement->m_animatedType.get());
+ SVGPropertyBase* toAtEndOfDurationProperty = m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty.get() : m_toProperty.get();
+ m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromProperty.get(), m_toProperty.get(), toAtEndOfDurationProperty, resultAnimationElement->m_animatedProperty.get());
}
bool SVGAnimateElement::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString)
{
if (toAtEndOfDurationString.isEmpty())
return false;
- m_toAtEndOfDurationType = ensureAnimator()->constructFromString(toAtEndOfDurationString);
+ m_toAtEndOfDurationProperty = ensureAnimator()->constructFromString(toAtEndOfDurationString);
return true;
}
@@ -153,8 +112,7 @@ bool SVGAnimateElement::calculateFromAndToValues(const String& fromString, const
return false;
determinePropertyValueTypes(fromString, toString);
- ensureAnimator()->calculateFromAndToValues(m_fromType, m_toType, fromString, toString);
- ASSERT(m_animatedPropertyType == m_animator->type());
+ ensureAnimator()->calculateFromAndToValues(m_fromProperty, m_toProperty, fromString, toString);
return true;
}
@@ -171,37 +129,37 @@ bool SVGAnimateElement::calculateFromAndByValues(const String& fromString, const
if (animationMode() == FromByAnimation && !animatedPropertyTypeSupportsAddition())
return false;
- ASSERT(!hasTagName(SVGNames::setTag));
+ ASSERT(!isSVGSetElement(*this));
determinePropertyValueTypes(fromString, byString);
- ensureAnimator()->calculateFromAndByValues(m_fromType, m_toType, fromString, byString);
- ASSERT(m_animatedPropertyType == m_animator->type());
+ ensureAnimator()->calculateFromAndByValues(m_fromProperty, m_toProperty, fromString, byString);
return true;
}
-#ifndef NDEBUG
-static inline bool propertyTypesAreConsistent(AnimatedPropertyType expectedPropertyType, const SVGElementAnimatedPropertyList& animatedTypes)
+namespace {
+
+WillBeHeapVector<RawPtrWillBeMember<SVGElement> > findElementInstances(SVGElement* targetElement)
{
- SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end();
- for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) {
- for (size_t i = 0; i < it->properties.size(); ++i) {
- if (expectedPropertyType != it->properties[i]->animatedPropertyType()) {
- // This is the only allowed inconsistency. SVGAnimatedAngleAnimator handles both SVGAnimatedAngle & SVGAnimatedEnumeration for markers orient attribute.
- if (expectedPropertyType == AnimatedAngle && it->properties[i]->animatedPropertyType() == AnimatedEnumeration)
- return true;
- return false;
- }
- }
+ ASSERT(targetElement);
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> > animatedElements;
+
+ animatedElements.append(targetElement);
+
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
+ if (SVGElement* shadowTreeElement = *it)
+ animatedElements.append(shadowTreeElement);
}
- return true;
+ return animatedElements;
+}
+
}
-#endif
void SVGAnimateElement::resetAnimatedType()
{
SVGAnimatedTypeAnimator* animator = ensureAnimator();
- ASSERT(m_animatedPropertyType == animator->type());
SVGElement* targetElement = this->targetElement();
const QualifiedName& attributeName = this->attributeName();
@@ -212,25 +170,22 @@ void SVGAnimateElement::resetAnimatedType()
if (shouldApply == ApplyXMLAnimation) {
// SVG DOM animVal animation code-path.
- m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(targetElement, attributeName);
- SVGElementAnimatedPropertyList::const_iterator end = m_animatedProperties.end();
- for (SVGElementAnimatedPropertyList::const_iterator it = m_animatedProperties.begin(); it != end; ++it)
- document().accessSVGExtensions()->addElementReferencingTarget(this, it->element);
-
- ASSERT(!m_animatedProperties.isEmpty());
-
- ASSERT(propertyTypesAreConsistent(m_animatedPropertyType, m_animatedProperties));
- if (!m_animatedType)
- m_animatedType = animator->startAnimValAnimation(m_animatedProperties);
- else {
- animator->resetAnimValToBaseVal(m_animatedProperties, m_animatedType.get());
- animator->animValDidChange(m_animatedProperties);
- }
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> > animatedElements = findElementInstances(targetElement);
+ ASSERT(!animatedElements.isEmpty());
+
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator end = animatedElements.end();
+ for (WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator it = animatedElements.begin(); it != end; ++it)
+ document().accessSVGExtensions().addElementReferencingTarget(this, *it);
+
+ if (!m_animatedProperty)
+ m_animatedProperty = animator->startAnimValAnimation(animatedElements);
+ else
+ m_animatedProperty = animator->resetAnimValToBaseVal(animatedElements);
+
return;
}
// CSS properties animation code-path.
- ASSERT(m_animatedProperties.isEmpty());
String baseValue;
if (shouldApply == ApplyCSSAnimation) {
@@ -238,15 +193,14 @@ void SVGAnimateElement::resetAnimatedType()
computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
}
- if (!m_animatedType)
- m_animatedType = animator->constructFromString(baseValue);
- else
- m_animatedType->setValueAsString(attributeName, baseValue);
+ m_animatedProperty = animator->constructFromString(baseValue);
}
static inline void applyCSSPropertyToTarget(SVGElement* targetElement, CSSPropertyID id, const String& value)
{
+#if !ENABLE(OILPAN)
ASSERT_WITH_SECURITY_IMPLICATION(!targetElement->m_deletionHasBegun);
+#endif
MutableStylePropertySet* propertySet = targetElement->ensureAnimatedSMILStyleProperties();
if (!propertySet->setProperty(id, value, false, 0))
@@ -257,7 +211,9 @@ static inline void applyCSSPropertyToTarget(SVGElement* targetElement, CSSProper
static inline void removeCSSPropertyFromTarget(SVGElement* targetElement, CSSPropertyID id)
{
+#if !ENABLE(OILPAN)
ASSERT_WITH_SECURITY_IMPLICATION(!targetElement->m_deletionHasBegun);
+#endif
targetElement->ensureAnimatedSMILStyleProperties()->removeProperty(id);
targetElement->setNeedsStyleRecalc(LocalStyleChange);
}
@@ -270,14 +226,14 @@ static inline void applyCSSPropertyToTargetAndInstances(SVGElement* targetElemen
CSSPropertyID id = cssPropertyID(attributeName.localName());
- SVGElementInstance::InstanceUpdateBlocker blocker(targetElement);
+ SVGElement::InstanceUpdateBlocker blocker(targetElement);
applyCSSPropertyToTarget(targetElement, id, valueAsString);
// If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement())
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
+ if (SVGElement* shadowTreeElement = *it)
applyCSSPropertyToTarget(shadowTreeElement, id, valueAsString);
}
}
@@ -290,21 +246,24 @@ static inline void removeCSSPropertyFromTargetAndInstances(SVGElement* targetEle
CSSPropertyID id = cssPropertyID(attributeName.localName());
- SVGElementInstance::InstanceUpdateBlocker blocker(targetElement);
+ SVGElement::InstanceUpdateBlocker blocker(targetElement);
removeCSSPropertyFromTarget(targetElement, id);
// If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement())
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
+ if (SVGElement* shadowTreeElement = *it)
removeCSSPropertyFromTarget(shadowTreeElement, id);
}
}
static inline void notifyTargetAboutAnimValChange(SVGElement* targetElement, const QualifiedName& attributeName)
{
+#if !ENABLE(OILPAN)
ASSERT_WITH_SECURITY_IMPLICATION(!targetElement->m_deletionHasBegun);
+#endif
+ targetElement->invalidateSVGAttributes();
targetElement->svgAttributeChanged(attributeName);
}
@@ -314,73 +273,71 @@ static inline void notifyTargetAndInstancesAboutAnimValChange(SVGElement* target
if (attributeName == anyQName() || !targetElement->inDocument() || !targetElement->parentNode())
return;
- SVGElementInstance::InstanceUpdateBlocker blocker(targetElement);
+ SVGElement::InstanceUpdateBlocker blocker(targetElement);
notifyTargetAboutAnimValChange(targetElement, attributeName);
// If the target element has instances, update them as well, w/o requiring the <use> tree to be rebuilt.
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement())
- notifyTargetAboutAnimValChange(shadowTreeElement, attributeName);
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
+ notifyTargetAboutAnimValChange(*it, attributeName);
}
}
void SVGAnimateElement::clearAnimatedType(SVGElement* targetElement)
{
- if (!m_animatedType)
+ if (!m_animatedProperty)
return;
if (!targetElement) {
- m_animatedType.clear();
+ m_animatedProperty.clear();
return;
}
- if (m_animatedProperties.isEmpty()) {
+ if (ensureAnimator()->isAnimatingCSSProperty()) {
// CSS properties animation code-path.
removeCSSPropertyFromTargetAndInstances(targetElement, attributeName());
- m_animatedType.clear();
+ m_animatedProperty.clear();
return;
}
// SVG DOM animVal animation code-path.
if (m_animator) {
- m_animator->stopAnimValAnimation(m_animatedProperties);
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> > animatedElements = findElementInstances(targetElement);
+ m_animator->stopAnimValAnimation(animatedElements);
notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName());
}
- m_animatedProperties.clear();
- m_animatedType.clear();
+ m_animatedProperty.clear();
}
void SVGAnimateElement::applyResultsToTarget()
{
- ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag));
- ASSERT(m_animatedPropertyType != AnimatedUnknown);
ASSERT(m_animator);
+ ASSERT(animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this));
+ ASSERT(animatedPropertyType() != AnimatedUnknown);
// Early exit if our animated type got destructed by a previous endedActiveInterval().
- if (!m_animatedType)
+ if (!m_animatedProperty)
return;
- if (m_animatedProperties.isEmpty()) {
+ if (m_animator->isAnimatingCSSProperty()) {
// CSS properties animation code-path.
// Convert the result of the animation to a String and apply it as CSS property on the target & all instances.
- applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedType->valueAsString());
+ applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedProperty->valueAsString());
return;
}
// SVG DOM animVal animation code-path.
// At this point the SVG DOM values are already changed, unlike for CSS.
// We only have to trigger update notifications here.
- m_animator->animValDidChange(m_animatedProperties);
notifyTargetAndInstancesAboutAnimValChange(targetElement(), attributeName());
}
-bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() const
+bool SVGAnimateElement::animatedPropertyTypeSupportsAddition()
{
// Spec: http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties.
- switch (m_animatedPropertyType) {
+ switch (animatedPropertyType()) {
case AnimatedBoolean:
case AnimatedEnumeration:
case AnimatedPreserveAspectRatio:
@@ -392,7 +349,7 @@ bool SVGAnimateElement::animatedPropertyTypeSupportsAddition() const
}
}
-bool SVGAnimateElement::isAdditive() const
+bool SVGAnimateElement::isAdditive()
{
if (animationMode() == ByAnimation || animationMode() == FromByAnimation)
if (!animatedPropertyTypeSupportsAddition())
@@ -425,20 +382,24 @@ void SVGAnimateElement::setAttributeName(const QualifiedName& attributeName)
void SVGAnimateElement::resetAnimatedPropertyType()
{
- ASSERT(!m_animatedType);
- m_fromType.clear();
- m_toType.clear();
- m_toAtEndOfDurationType.clear();
+ ASSERT(!m_animatedProperty);
+ m_fromProperty.clear();
+ m_toProperty.clear();
+ m_toAtEndOfDurationProperty.clear();
m_animator.clear();
- m_animatedPropertyType = targetElement() ? determineAnimatedPropertyType(targetElement()) : AnimatedString;
}
SVGAnimatedTypeAnimator* SVGAnimateElement::ensureAnimator()
{
if (!m_animator)
- m_animator = SVGAnimatorFactory::create(this, targetElement(), m_animatedPropertyType);
- ASSERT(m_animatedPropertyType == m_animator->type());
+ m_animator = SVGAnimatedTypeAnimator::create(this, targetElement());
return m_animator.get();
}
+void SVGAnimateElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_animator);
+ SVGAnimationElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.h
index e8b2dc438ab..8fd9c902e87 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateElement.h
@@ -23,67 +23,64 @@
#ifndef SVGAnimateElement_h
#define SVGAnimateElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
+#include "core/svg/SVGAnimatedTypeAnimator.h"
#include "core/svg/SVGAnimationElement.h"
#include "wtf/OwnPtr.h"
namespace WebCore {
-class SVGAnimatedProperty;
-class SVGAnimatedType;
class SVGAnimatedTypeAnimator;
class SVGAnimateElement : public SVGAnimationElement {
public:
- static PassRefPtr<SVGAnimateElement> create(Document&);
+ static PassRefPtrWillBeRawPtr<SVGAnimateElement> create(Document&);
virtual ~SVGAnimateElement();
- AnimatedPropertyType determineAnimatedPropertyType(SVGElement*) const;
+ virtual void trace(Visitor*) OVERRIDE;
+
+ AnimatedPropertyType animatedPropertyType();
+ bool animatedPropertyTypeSupportsAddition();
protected:
SVGAnimateElement(const QualifiedName&, Document&);
- virtual void resetAnimatedType();
- virtual void clearAnimatedType(SVGElement* targetElement);
-
- virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString);
- virtual bool calculateFromAndToValues(const String& fromString, const String& toString);
- virtual bool calculateFromAndByValues(const String& fromString, const String& byString);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement);
- virtual void applyResultsToTarget();
- virtual float calculateDistance(const String& fromString, const String& toString);
- virtual bool isAdditive() const OVERRIDE;
+ virtual void resetAnimatedType() OVERRIDE FINAL;
+ virtual void clearAnimatedType(SVGElement* targetElement) OVERRIDE FINAL;
- virtual void setTargetElement(SVGElement*) OVERRIDE;
- virtual void setAttributeName(const QualifiedName&) OVERRIDE;
+ virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) OVERRIDE FINAL;
+ virtual bool calculateFromAndToValues(const String& fromString, const String& toString) OVERRIDE FINAL;
+ virtual bool calculateFromAndByValues(const String& fromString, const String& byString) OVERRIDE FINAL;
+ virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) OVERRIDE FINAL;
+ virtual void applyResultsToTarget() OVERRIDE FINAL;
+ virtual float calculateDistance(const String& fromString, const String& toString) OVERRIDE FINAL;
+ virtual bool isAdditive() OVERRIDE FINAL;
- AnimatedPropertyType m_animatedPropertyType;
+ virtual void setTargetElement(SVGElement*) OVERRIDE FINAL;
+ virtual void setAttributeName(const QualifiedName&) OVERRIDE FINAL;
private:
void resetAnimatedPropertyType();
SVGAnimatedTypeAnimator* ensureAnimator();
- bool animatedPropertyTypeSupportsAddition() const;
- virtual bool hasValidAttributeType();
+ virtual bool hasValidAttributeType() OVERRIDE;
- OwnPtr<SVGAnimatedType> m_fromType;
- OwnPtr<SVGAnimatedType> m_toType;
- OwnPtr<SVGAnimatedType> m_toAtEndOfDurationType;
- OwnPtr<SVGAnimatedType> m_animatedType;
+ RefPtr<SVGPropertyBase> m_fromProperty;
+ RefPtr<SVGPropertyBase> m_toProperty;
+ RefPtr<SVGPropertyBase> m_toAtEndOfDurationProperty;
+ RefPtr<SVGPropertyBase> m_animatedProperty;
- SVGElementAnimatedPropertyList m_animatedProperties;
- OwnPtr<SVGAnimatedTypeAnimator> m_animator;
+ OwnPtrWillBeMember<SVGAnimatedTypeAnimator> m_animator;
};
inline bool isSVGAnimateElement(const Node& node)
{
return node.hasTagName(SVGNames::animateTag)
- || node.hasTagName(SVGNames::animateColorTag)
|| node.hasTagName(SVGNames::animateTransformTag)
|| node.hasTagName(SVGNames::setTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGAnimateElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGAnimateElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp
index 9c76b316404..52f4f4b09c2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp
@@ -23,11 +23,10 @@
#include "core/svg/SVGAnimateMotionElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/SVGPathData.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGMPathElement.h"
#include "core/svg/SVGParserUtilities.h"
#include "core/svg/SVGPathElement.h"
@@ -48,15 +47,10 @@ inline SVGAnimateMotionElement::SVGAnimateMotionElement(Document& document)
ScriptWrappable::init(this);
}
-SVGAnimateMotionElement::~SVGAnimateMotionElement()
-{
- if (targetElement())
- clearAnimatedType(targetElement());
-}
+DEFINE_NODE_FACTORY(SVGAnimateMotionElement)
-PassRefPtr<SVGAnimateMotionElement> SVGAnimateMotionElement::create(Document& document)
+SVGAnimateMotionElement::~SVGAnimateMotionElement()
{
- return adoptRef(new SVGAnimateMotionElement(document));
}
bool SVGAnimateMotionElement::hasValidAttributeType()
@@ -70,26 +64,24 @@ bool SVGAnimateMotionElement::hasValidAttributeType()
return false;
// Spec: SVG 1.1 section 19.2.15
// FIXME: svgTag is missing. Needs to be checked, if transforming <svg> could cause problems.
- if (targetElement->hasTagName(gTag)
- || targetElement->hasTagName(defsTag)
- || targetElement->hasTagName(useTag)
- || targetElement->hasTagName(SVGNames::imageTag)
- || targetElement->hasTagName(switchTag)
- || targetElement->hasTagName(pathTag)
- || targetElement->hasTagName(rectTag)
- || targetElement->hasTagName(circleTag)
- || targetElement->hasTagName(ellipseTag)
- || targetElement->hasTagName(lineTag)
- || targetElement->hasTagName(polylineTag)
- || targetElement->hasTagName(polygonTag)
- || targetElement->hasTagName(textTag)
- || targetElement->hasTagName(clipPathTag)
- || targetElement->hasTagName(maskTag)
- || targetElement->hasTagName(SVGNames::aTag)
- || targetElement->hasTagName(foreignObjectTag)
- )
- return true;
- return false;
+ return (isSVGGElement(*targetElement)
+ || isSVGDefsElement(*targetElement)
+ || isSVGUseElement(*targetElement)
+ || isSVGImageElement(*targetElement)
+ || isSVGSwitchElement(*targetElement)
+ || isSVGPathElement(*targetElement)
+ || isSVGRectElement(*targetElement)
+ || isSVGCircleElement(*targetElement)
+ || isSVGEllipseElement(*targetElement)
+ || isSVGLineElement(*targetElement)
+ || isSVGPolylineElement(*targetElement)
+ || isSVGPolygonElement(*targetElement)
+ || isSVGTextElement(*targetElement)
+ || isSVGClipPathElement(*targetElement)
+ || isSVGMaskElement(*targetElement)
+ || isSVGAElement(*targetElement)
+ || isSVGForeignObjectElement(*targetElement)
+ );
}
bool SVGAnimateMotionElement::hasValidAttributeName()
@@ -140,15 +132,11 @@ void SVGAnimateMotionElement::updateAnimationPath()
m_animationPath = Path();
bool foundMPath = false;
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(SVGNames::mpathTag)) {
- SVGMPathElement* mPath = toSVGMPathElement(child);
- SVGPathElement* pathElement = mPath->pathElement();
- if (pathElement) {
- updatePathFromGraphicsElement(pathElement, m_animationPath);
- foundMPath = true;
- break;
- }
+ for (SVGMPathElement* mpath = Traversal<SVGMPathElement>::firstChild(*this); mpath; mpath = Traversal<SVGMPathElement>::nextSibling(*mpath)) {
+ if (SVGPathElement* pathElement = mpath->pathElement()) {
+ updatePathFromGraphicsElement(pathElement, m_animationPath);
+ foundMPath = true;
+ break;
}
}
@@ -277,11 +265,10 @@ void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned
ASSERT(!m_animationPath.isEmpty());
- bool ok = false;
float positionOnPath = m_animationPath.length() * percentage;
FloatPoint position;
float angle;
- ok = m_animationPath.pointAndNormalAtLength(positionOnPath, position, angle);
+ bool ok = m_animationPath.pointAndNormalAtLength(positionOnPath, position, angle);
if (!ok)
return;
@@ -316,10 +303,10 @@ void SVGAnimateMotionElement::applyResultsToTarget()
return;
// ...except in case where we have additional instances in <use> trees.
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = targetElement->instancesForElement();
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
+ SVGElement* shadowTreeElement = *it;
ASSERT(shadowTreeElement);
AffineTransform* transform = shadowTreeElement->supplementalTransform();
if (!transform)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.h
index 46094a1302a..8f7c856190e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.h
@@ -26,32 +26,30 @@
namespace WebCore {
-class AffineTransform;
-
class SVGAnimateMotionElement FINAL : public SVGAnimationElement {
public:
virtual ~SVGAnimateMotionElement();
- static PassRefPtr<SVGAnimateMotionElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGAnimateMotionElement);
void updateAnimationPath();
private:
explicit SVGAnimateMotionElement(Document&);
- virtual bool hasValidAttributeType();
- virtual bool hasValidAttributeName();
+ virtual bool hasValidAttributeType() OVERRIDE;
+ virtual bool hasValidAttributeName() OVERRIDE;
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void resetAnimatedType();
- virtual void clearAnimatedType(SVGElement* targetElement);
- virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString);
- virtual bool calculateFromAndToValues(const String& fromString, const String& toString);
- virtual bool calculateFromAndByValues(const String& fromString, const String& byString);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement);
- virtual void applyResultsToTarget();
- virtual float calculateDistance(const String& fromString, const String& toString);
+ virtual void resetAnimatedType() OVERRIDE;
+ virtual void clearAnimatedType(SVGElement* targetElement) OVERRIDE;
+ virtual bool calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString) OVERRIDE;
+ virtual bool calculateFromAndToValues(const String& fromString, const String& toString) OVERRIDE;
+ virtual bool calculateFromAndByValues(const String& fromString, const String& byString) OVERRIDE;
+ virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement) OVERRIDE;
+ virtual void applyResultsToTarget() OVERRIDE;
+ virtual float calculateDistance(const String& fromString, const String& toString) OVERRIDE;
enum RotateMode {
RotateAngle,
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp
index 6774a387307..adf0a7cc3c8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.cpp
@@ -24,22 +24,19 @@
#include "core/svg/SVGAnimateTransformElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGParserUtilities.h"
namespace WebCore {
inline SVGAnimateTransformElement::SVGAnimateTransformElement(Document& document)
: SVGAnimateElement(SVGNames::animateTransformTag, document)
- , m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
+ , m_type(SVG_TRANSFORM_UNKNOWN)
{
ScriptWrappable::init(this);
}
-PassRefPtr<SVGAnimateTransformElement> SVGAnimateTransformElement::create(Document& document)
-{
- return adoptRef(new SVGAnimateTransformElement(document));
-}
+DEFINE_NODE_FACTORY(SVGAnimateTransformElement)
bool SVGAnimateTransformElement::hasValidAttributeType()
{
@@ -50,7 +47,7 @@ bool SVGAnimateTransformElement::hasValidAttributeType()
if (attributeType() == AttributeTypeCSS)
return false;
- return m_animatedPropertyType == AnimatedTransformList;
+ return animatedPropertyType() == AnimatedTransformList;
}
bool SVGAnimateTransformElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -70,8 +67,8 @@ void SVGAnimateTransformElement::parseAttribute(const QualifiedName& name, const
if (name == SVGNames::typeAttr) {
m_type = parseTransformType(value);
- if (m_type == SVGTransform::SVG_TRANSFORM_MATRIX)
- m_type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
+ if (m_type == SVG_TRANSFORM_MATRIX)
+ m_type = SVG_TRANSFORM_UNKNOWN;
return;
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h
index 86606d8890a..4a53eb4890d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimateTransformElement.h
@@ -28,23 +28,21 @@
namespace WebCore {
-class AffineTransform;
-
class SVGAnimateTransformElement FINAL : public SVGAnimateElement {
public:
- static PassRefPtr<SVGAnimateTransformElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGAnimateTransformElement);
- SVGTransform::SVGTransformType transformType() const { return m_type; }
+ SVGTransformType transformType() const { return m_type; }
private:
explicit SVGAnimateTransformElement(Document&);
- virtual bool hasValidAttributeType();
+ virtual bool hasValidAttributeType() OVERRIDE;
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- SVGTransform::SVGTransformType m_type;
+ SVGTransformType m_type;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp
index a6265e5466b..886a624097c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp
@@ -1,152 +1,73 @@
/*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "core/svg/SVGAnimatedAngle.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/svg/SVGAnimateElement.h"
+#include "core/SVGNames.h"
+#include "core/svg/SVGAngleTearOff.h"
#include "core/svg/SVGMarkerElement.h"
namespace WebCore {
-SVGAnimatedAngleAnimator::SVGAnimatedAngleAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedAngle, animationElement, contextElement)
+SVGAnimatedAngle::SVGAnimatedAngle(SVGMarkerElement* contextElement)
+ : SVGAnimatedProperty<SVGAngle>(contextElement, SVGNames::orientAttr, SVGAngle::create())
+ , m_orientType(SVGAnimatedEnumeration<SVGMarkerOrientType>::create(contextElement, SVGNames::orientAttr, baseValue()->orientType()))
{
}
-PassOwnPtr<SVGAnimatedType> SVGAnimatedAngleAnimator::constructFromString(const String& string)
+SVGAnimatedAngle::~SVGAnimatedAngle()
{
- OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createAngleAndEnumeration(new pair<SVGAngle, unsigned>);
- pair<SVGAngle, unsigned>& animatedPair = animatedType->angleAndEnumeration();
-
- SVGAngle angle;
- SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string, angle);
- if (orientType > 0)
- animatedPair.second = orientType;
- if (orientType == SVGMarkerOrientAngle)
- animatedPair.first = angle;
-
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedAngleAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createAngleAndEnumeration(constructFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes));
-}
-
-void SVGAnimatedAngleAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
}
-void SVGAnimatedAngleAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
+void SVGAnimatedAngle::synchronizeAttribute()
{
- resetFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes, type, &SVGAnimatedType::angleAndEnumeration);
-}
+ AtomicString value;
+ if (m_orientType->currentValue()->enumValue() == SVGMarkerOrientAuto)
+ value = "auto";
+ else
+ value = AtomicString(currentValue()->valueAsString());
-void SVGAnimatedAngleAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
+ contextElement()->setSynchronizedLazyAttribute(attributeName(), value);
}
-void SVGAnimatedAngleAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
+void SVGAnimatedAngle::setAnimatedValue(PassRefPtr<SVGPropertyBase> value)
{
- animValDidChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedAngleAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedAngle);
- ASSERT(from->type() == to->type());
-
- const pair<SVGAngle, unsigned>& fromAngleAndEnumeration = from->angleAndEnumeration();
- pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
- // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto').
- if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second || fromAngleAndEnumeration.second != SVGMarkerOrientAngle)
- return;
- const SVGAngle& fromAngle = fromAngleAndEnumeration.first;
- SVGAngle& toAngle = toAngleAndEnumeration.first;
- toAngle.setValue(toAngle.value() + fromAngle.value());
-}
-
-void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- const pair<SVGAngle, unsigned>& fromAngleAndEnumeration = m_animationElement->animationMode() == ToAnimation ? animated->angleAndEnumeration() : from->angleAndEnumeration();
- const pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
- const pair<SVGAngle, unsigned>& toAtEndOfDurationAngleAndEnumeration = toAtEndOfDuration->angleAndEnumeration();
- pair<SVGAngle, unsigned>& animatedAngleAndEnumeration = animated->angleAndEnumeration();
-
- if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second) {
- // Animating from eg. auto to 90deg, or auto to 90deg.
- if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) {
- // Animating from an angle value to eg. 'auto' - this disabled additive as 'auto' is a keyword..
- if (toAngleAndEnumeration.second == SVGMarkerOrientAuto) {
- if (percentage < 0.5f) {
- animatedAngleAndEnumeration.first = fromAngleAndEnumeration.first;
- animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
- return;
- }
- animatedAngleAndEnumeration.first.setValue(0);
- animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
- return;
- }
- animatedAngleAndEnumeration.first.setValue(0);
- animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
- return;
- }
- }
-
- // From 'auto' to 'auto'.
- if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto) {
- animatedAngleAndEnumeration.first.setValue(0);
- animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
- return;
- }
-
- // If the enumeration value is not angle or auto, its unknown.
- if (fromAngleAndEnumeration.second != SVGMarkerOrientAngle) {
- animatedAngleAndEnumeration.first.setValue(0);
- animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
- return;
- }
-
- // Regular from angle to angle animation, with all features like additive etc.
- animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
-
- SVGAngle& animatedSVGAngle = animatedAngleAndEnumeration.first;
- const SVGAngle& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first;
- float animatedAngle = animatedSVGAngle.value();
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle);
- animatedSVGAngle.setValue(animatedAngle);
+ SVGAnimatedProperty<SVGAngle>::setAnimatedValue(value);
+ m_orientType->setAnimatedValue(currentValue()->orientType());
}
-float SVGAnimatedAngleAnimator::calculateDistance(const String& fromString, const String& toString)
+void SVGAnimatedAngle::animationEnded()
{
- SVGAngle from = SVGAngle();
- from.setValueAsString(fromString, ASSERT_NO_EXCEPTION);
- SVGAngle to = SVGAngle();
- to.setValueAsString(toString, ASSERT_NO_EXCEPTION);
- return fabsf(to.value() - from.value());
+ SVGAnimatedProperty<SVGAngle>::animationEnded();
+ m_orientType->animationEnded();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.h
index 047719a6f1e..5f906f8febc 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.h
@@ -1,60 +1,68 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedAngle_h
#define SVGAnimatedAngle_h
-#include "core/svg/SVGAngle.h"
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedPropertyTearOff.h"
+#include "core/svg/SVGAngleTearOff.h"
+#include "core/svg/SVGAnimatedEnumeration.h"
namespace WebCore {
-typedef SVGAnimatedPropertyTearOff<SVGAngle> SVGAnimatedAngle;
+class SVGMarkerElement;
-// Helper macros to declare/define a SVGAnimatedAngle object. SVGAnimatedAngle is only used in the SVG DOM for SVGMarkerElement.
-#define DECLARE_ANIMATED_ANGLE(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedAngle, SVGAngle, UpperProperty, LowerProperty)
+class SVGAnimatedAngle FINAL : public SVGAnimatedProperty<SVGAngle> {
+public:
+ static PassRefPtr<SVGAnimatedAngle> create(SVGMarkerElement* contextElement)
+ {
+ return adoptRef(new SVGAnimatedAngle(contextElement));
+ }
-// Only used for SVGMarkerElements orientAttr, which maps to SVGAnimatedAngle orientAngle and SVGAnimatedEnumeration orientType.
-#define DEFINE_ANIMATED_ANGLE_AND_ENUMERATION(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedAngle, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty, SVGAnimatedAngle, SVGAngle)
+ virtual ~SVGAnimatedAngle();
-class SVGAnimationElement;
+ SVGAnimatedEnumeration<SVGMarkerOrientType>* orientType() { return m_orientType.get(); }
-class SVGAnimatedAngleAnimator : public SVGAnimatedTypeAnimator {
-public:
- SVGAnimatedAngleAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedAngleAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ // SVGAnimatedPropertyBase:
+
+ virtual void synchronizeAttribute() OVERRIDE;
+
+ virtual void setAnimatedValue(PassRefPtr<SVGPropertyBase>) OVERRIDE;
+ virtual void animationEnded() OVERRIDE;
+
+protected:
+ SVGAnimatedAngle(SVGMarkerElement* contextElement);
+
+private:
+ RefPtr<SVGAnimatedEnumeration<SVGMarkerOrientType> > m_orientType;
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedAngle_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.idl
index 9a51845b4a7..7fe115c9ece 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedAngle.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedAngle {
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedAngle {
readonly attribute SVGAngle baseVal;
readonly attribute SVGAngle animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.cpp
deleted file mode 100644
index 656bee87c8f..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedBoolean.h"
-
-#include "core/svg/SVGAnimateElement.h"
-
-namespace WebCore {
-
-SVGAnimatedBooleanAnimator::SVGAnimatedBooleanAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedBoolean, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedBooleanAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createBoolean(new bool);
- animtedType->boolean() = (string == "true"); // wat?
- return animtedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedBooleanAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createBoolean(constructFromBaseValue<SVGAnimatedBoolean>(animatedTypes));
-}
-
-void SVGAnimatedBooleanAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedBoolean>(animatedTypes);
-}
-
-void SVGAnimatedBooleanAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedBoolean>(animatedTypes, type, &SVGAnimatedType::boolean);
-}
-
-void SVGAnimatedBooleanAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedBoolean>(animatedTypes);
-}
-
-void SVGAnimatedBooleanAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedBoolean>(animatedTypes);
-}
-
-void SVGAnimatedBooleanAnimator::addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*)
-{
- ASSERT_NOT_REACHED();
-}
-
-void SVGAnimatedBooleanAnimator::calculateAnimatedValue(float percentage, unsigned, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType*, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- bool fromBoolean = m_animationElement->animationMode() == ToAnimation ? animated->boolean() : from->boolean();
- bool toBoolean = to->boolean();
- bool& animatedBoolean = animated->boolean();
-
- m_animationElement->animateDiscreteType<bool>(percentage, fromBoolean, toBoolean, animatedBoolean);
-}
-
-float SVGAnimatedBooleanAnimator::calculateDistance(const String&, const String&)
-{
- // No paced animations for boolean.
- return -1;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.h
index 442df071008..524bd723b47 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.h
@@ -1,58 +1,55 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedBoolean_h
#define SVGAnimatedBoolean_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h"
+#include "core/svg/SVGBoolean.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedStaticPropertyTearOff<bool> SVGAnimatedBoolean;
-
-// Helper macros to declare/define a SVGAnimatedBoolean object
-#define DECLARE_ANIMATED_BOOLEAN(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedBoolean, bool, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_BOOLEAN(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedBoolean, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedBoolean, bool)
-
-class SVGAnimationElement;
-
-class SVGAnimatedBooleanAnimator : public SVGAnimatedTypeAnimator {
+class SVGAnimatedBoolean FINAL : public SVGAnimatedProperty<SVGBoolean> {
public:
- SVGAnimatedBooleanAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedBooleanAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ static PassRefPtr<SVGAnimatedBoolean> create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGBoolean> initialValue)
+ {
+ return adoptRef(new SVGAnimatedBoolean(contextElement, attributeName, initialValue));
+ }
+
+protected:
+ SVGAnimatedBoolean(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGBoolean> initialValue)
+ : SVGAnimatedProperty<SVGBoolean>(contextElement, attributeName, initialValue)
+ {
+ }
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedBoolean_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.idl
index 7fc919ccf26..f009f6f2fe9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedBoolean.idl
@@ -23,8 +23,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedBoolean {
- [StrictTypeChecking, RaisesException=Setter] attribute boolean baseVal;
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGAnimatedBoolean {
+ [RaisesException=Setter] attribute boolean baseVal;
readonly attribute boolean animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp
index ad478afa9af..157458fe629 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp
@@ -24,89 +24,78 @@
#include "core/rendering/RenderObject.h"
#include "core/svg/ColorDistance.h"
#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGColor.h"
namespace WebCore {
-SVGAnimatedColorAnimator::SVGAnimatedColorAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedColor, animationElement, contextElement)
+String SVGColorProperty::valueAsString() const
{
+ return m_styleColor.isCurrentColor() ? "currentColor" : m_styleColor.color().serializedAsCSSComponentValue();
}
-PassOwnPtr<SVGAnimatedType> SVGAnimatedColorAnimator::constructFromString(const String& string)
+PassRefPtr<SVGPropertyBase> SVGColorProperty::cloneForAnimation(const String&) const
{
- OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createColor(new Color);
- animtedType->color() = string.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(string);
- return animtedType.release();
+ // SVGAnimatedColor is deprecated. So No SVG DOM animation.
+ ASSERT_NOT_REACHED();
+ return nullptr;
}
-void SVGAnimatedColorAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedColor);
- ASSERT(from->type() == to->type());
- to->color() = ColorDistance::addColors(from->color(), to->color());
-}
-
-static inline void adjustForCurrentColor(SVGElement* targetElement, Color& color)
+static inline Color fallbackColorForCurrentColor(SVGElement* targetElement)
{
ASSERT(targetElement);
-
if (RenderObject* targetRenderer = targetElement->renderer())
- color = targetRenderer->style()->visitedDependentColor(CSSPropertyColor);
+ return targetRenderer->style()->visitedDependentColor(CSSPropertyColor);
else
- color = Color();
+ return Color::transparent;
}
-static Color parseColorFromString(SVGAnimationElement*, const String& string)
+void SVGColorProperty::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement* contextElement)
{
- return SVGColor::colorFromRGBColorString(string);
+ ASSERT(contextElement);
+
+ Color fallbackColor = fallbackColorForCurrentColor(contextElement);
+ Color fromColor = toSVGColorProperty(other)->m_styleColor.resolve(fallbackColor);
+ Color toColor = m_styleColor.resolve(fallbackColor);
+ m_styleColor = StyleColor(ColorDistance::addColors(fromColor, toColor));
}
-void SVGAnimatedColorAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
+void SVGColorProperty::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- Color fromColor = m_animationElement->animationMode() == ToAnimation ? animated->color() : from->color();
- Color toColor = to->color();
- const Color& toAtEndOfDurationColor = toAtEndOfDuration->color();
- Color& animatedColor = animated->color();
-
- // Apply CSS inheritance rules.
- m_animationElement->adjustForInheritance<Color>(parseColorFromString, m_animationElement->fromPropertyValueType(), fromColor, m_contextElement);
- m_animationElement->adjustForInheritance<Color>(parseColorFromString, m_animationElement->toPropertyValueType(), toColor, m_contextElement);
-
- // Apply <animateColor> rules.
- if (m_animationElement->fromPropertyValueType() == CurrentColorValue)
- adjustForCurrentColor(m_contextElement, fromColor);
- if (m_animationElement->toPropertyValueType() == CurrentColorValue)
- adjustForCurrentColor(m_contextElement, toColor);
-
+ StyleColor fromStyleColor = toSVGColorProperty(fromValue)->m_styleColor;
+ StyleColor toStyleColor = toSVGColorProperty(toValue)->m_styleColor;
+ StyleColor toAtEndOfDurationStyleColor = toSVGColorProperty(toAtEndOfDurationValue)->m_styleColor;
+
+ // Apply currentColor rules.
+ ASSERT(contextElement);
+ Color fallbackColor = fallbackColorForCurrentColor(contextElement);
+ Color fromColor = fromStyleColor.resolve(fallbackColor);
+ Color toColor = toStyleColor.resolve(fallbackColor);
+ Color toAtEndOfDurationColor = toAtEndOfDurationStyleColor.resolve(fallbackColor);
+ Color animatedColor = m_styleColor.resolve(fallbackColor);
+
+ ASSERT(animationElement);
float animatedRed = animatedColor.red();
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.red(), toColor.red(), toAtEndOfDurationColor.red(), animatedRed);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.red(), toColor.red(), toAtEndOfDurationColor.red(), animatedRed);
float animatedGreen = animatedColor.green();
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.green(), toColor.green(), toAtEndOfDurationColor.green(), animatedGreen);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.green(), toColor.green(), toAtEndOfDurationColor.green(), animatedGreen);
float animatedBlue = animatedColor.blue();
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.blue(), toColor.blue(), toAtEndOfDurationColor.blue(), animatedBlue);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.blue(), toColor.blue(), toAtEndOfDurationColor.blue(), animatedBlue);
float animatedAlpha = animatedColor.alpha();
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.alpha(), toColor.alpha(), toAtEndOfDurationColor.alpha(), animatedAlpha);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromColor.alpha(), toColor.alpha(), toAtEndOfDurationColor.alpha(), animatedAlpha);
- animatedColor = ColorDistance::clampColor(static_cast<int>(roundf(animatedRed)), static_cast<int>(roundf(animatedGreen)), static_cast<int>(roundf(animatedBlue)), static_cast<int>(roundf(animatedAlpha)));
+ m_styleColor = StyleColor(makeRGBA(roundf(animatedRed), roundf(animatedGreen), roundf(animatedBlue), roundf(animatedAlpha)));
}
-float SVGAnimatedColorAnimator::calculateDistance(const String& fromString, const String& toString)
+float SVGColorProperty::calculateDistance(PassRefPtr<SVGPropertyBase> toValue, SVGElement* contextElement)
{
- ASSERT(m_contextElement);
- Color from = SVGColor::colorFromRGBColorString(fromString);
- if (!from.isValid())
- return -1;
- Color to = SVGColor::colorFromRGBColorString(toString);
- if (!to.isValid())
- return -1;
- return ColorDistance(from, to).distance();
+ ASSERT(contextElement);
+ Color fallbackColor = fallbackColorForCurrentColor(contextElement);
+
+ Color fromColor = m_styleColor.resolve(fallbackColor);
+ Color toColor = toSVGColorProperty(toValue)->m_styleColor.resolve(fallbackColor);
+ return ColorDistance::distance(fromColor, toColor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.h
index aa29efcc746..7fc14527204 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedColor.h
@@ -1,48 +1,78 @@
/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedColor_h
#define SVGAnimatedColor_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
+#include "core/css/StyleColor.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
class SVGAnimationElement;
-class SVGAnimatedColorAnimator : public SVGAnimatedTypeAnimator {
+// StyleColor adaptor to SVGPropertyBase. This is only used for SMIL animations.
+// FIXME: WebAnimations: Replacable with AnimatableColor once SMIL animations are implemented in WebAnimations.
+class SVGColorProperty FINAL : public SVGPropertyBase {
public:
- SVGAnimatedColorAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedColorAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) { return PassOwnPtr<SVGAnimatedType>(); }
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) { }
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) { }
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&) { }
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&) { }
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ static PassRefPtr<SVGColorProperty> create(StyleColor styleColor)
+ {
+ return adoptRef(new SVGColorProperty(styleColor));
+ }
+
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+ virtual String valueAsString() const OVERRIDE;
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedColor; }
+
+private:
+ explicit SVGColorProperty(StyleColor styleColor)
+ : SVGPropertyBase(classType())
+ , m_styleColor(styleColor)
+ {
+ }
+
+ StyleColor m_styleColor;
};
+inline PassRefPtr<SVGColorProperty> toSVGColorProperty(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGColorProperty::classType());
+ return static_pointer_cast<SVGColorProperty>(base.release());
+}
+
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp
deleted file mode 100644
index d23f38eaa6b..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedEnumeration.h"
-
-#include "SVGNames.h"
-#include "core/svg/SVGAnimationElement.h"
-#include "core/svg/SVGComponentTransferFunctionElement.h"
-#include "core/svg/SVGFEBlendElement.h"
-#include "core/svg/SVGFEColorMatrixElement.h"
-#include "core/svg/SVGFECompositeElement.h"
-#include "core/svg/SVGFEConvolveMatrixElement.h"
-#include "core/svg/SVGFEDisplacementMapElement.h"
-#include "core/svg/SVGFEMorphologyElement.h"
-#include "core/svg/SVGFETurbulenceElement.h"
-#include "core/svg/SVGGradientElement.h"
-#include "core/svg/SVGMarkerElement.h"
-#include "core/svg/SVGTextContentElement.h"
-#include "core/svg/SVGTextPathElement.h"
-#include "core/svg/SVGUnitTypes.h"
-
-namespace WebCore {
-
-static inline unsigned enumerationValueForTargetAttribute(SVGElement* targetElement, const QualifiedName& attrName, const String& value)
-{
- ASSERT(targetElement);
- if (attrName == SVGNames::clipPathUnitsAttr
- || attrName == SVGNames::filterUnitsAttr
- || attrName == SVGNames::gradientUnitsAttr
- || attrName == SVGNames::maskContentUnitsAttr
- || attrName == SVGNames::maskUnitsAttr
- || attrName == SVGNames::patternContentUnitsAttr
- || attrName == SVGNames::patternUnitsAttr
- || attrName == SVGNames::primitiveUnitsAttr)
- return SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-
- if (attrName == SVGNames::lengthAdjustAttr)
- return SVGPropertyTraits<SVGLengthAdjustType>::fromString(value);
- if (attrName == SVGNames::markerUnitsAttr)
- return SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value);
- if (attrName == SVGNames::methodAttr)
- return SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
- if (attrName == SVGNames::spacingAttr)
- return SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value);
- if (attrName == SVGNames::spreadMethodAttr)
- return SVGPropertyTraits<SVGSpreadMethodType>::fromString(value);
-
- if (attrName == SVGNames::edgeModeAttr)
- return SVGPropertyTraits<EdgeModeType>::fromString(value);
-
- if (attrName == SVGNames::operatorAttr) {
- if (targetElement->hasTagName(SVGNames::feCompositeTag))
- return SVGPropertyTraits<CompositeOperationType>::fromString(value);
- ASSERT(targetElement->hasTagName(SVGNames::feMorphologyTag));
- return SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
- }
-
- if (attrName == SVGNames::typeAttr) {
- if (targetElement->hasTagName(SVGNames::feColorMatrixTag))
- return SVGPropertyTraits<ColorMatrixType>::fromString(value);
- if (targetElement->hasTagName(SVGNames::feTurbulenceTag))
- return SVGPropertyTraits<TurbulenceType>::fromString(value);
-
- ASSERT(targetElement->hasTagName(SVGNames::feFuncATag)
- || targetElement->hasTagName(SVGNames::feFuncBTag)
- || targetElement->hasTagName(SVGNames::feFuncGTag)
- || targetElement->hasTagName(SVGNames::feFuncRTag));
- return SVGPropertyTraits<ComponentTransferType>::fromString(value);
- }
-
- if (attrName == SVGNames::modeAttr)
- return SVGPropertyTraits<BlendModeType>::fromString(value);
- if (attrName == SVGNames::stitchTilesAttr)
- return SVGPropertyTraits<SVGStitchOptions>::fromString(value);
- if (attrName == SVGNames::xChannelSelectorAttr)
- return SVGPropertyTraits<ChannelSelectorType>::fromString(value);
- if (attrName == SVGNames::yChannelSelectorAttr)
- return SVGPropertyTraits<ChannelSelectorType>::fromString(value);
-
- ASSERT_NOT_REACHED();
- return 0;
-}
-
-SVGAnimatedEnumerationAnimator::SVGAnimatedEnumerationAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedEnumeration, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedEnumerationAnimator::constructFromString(const String& string)
-{
- ASSERT(m_animationElement);
- OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createEnumeration(new unsigned);
- animatedType->enumeration() = enumerationValueForTargetAttribute(m_animationElement->targetElement(), m_animationElement->attributeName(), string);
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedEnumerationAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createEnumeration(constructFromBaseValue<SVGAnimatedEnumeration>(animatedTypes));
-}
-
-void SVGAnimatedEnumerationAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedEnumeration>(animatedTypes, type, &SVGAnimatedType::enumeration);
-}
-
-void SVGAnimatedEnumerationAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*)
-{
- ASSERT_NOT_REACHED();
-}
-
-void SVGAnimatedEnumerationAnimator::calculateAnimatedValue(float percentage, unsigned, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType*, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- unsigned fromEnumeration = m_animationElement->animationMode() == ToAnimation ? animated->enumeration() : from->enumeration();
- unsigned toEnumeration = to->enumeration();
- unsigned& animatedEnumeration = animated->enumeration();
-
- m_animationElement->animateDiscreteType<unsigned>(percentage, fromEnumeration, toEnumeration, animatedEnumeration);
-}
-
-float SVGAnimatedEnumerationAnimator::calculateDistance(const String&, const String&)
-{
- // No paced animations for enumerations.
- return -1;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.h
index b56e0ad4bea..98b2f7d6411 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.h
@@ -1,57 +1,75 @@
/*
- * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedEnumeration_h
#define SVGAnimatedEnumeration_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
+#include "core/svg/SVGAnimatedEnumerationBase.h"
namespace WebCore {
-typedef SVGAnimatedStaticPropertyTearOff<unsigned> SVGAnimatedEnumeration;
+template<typename Enum>
+class SVGAnimatedEnumeration : public SVGAnimatedEnumerationBase {
+public:
+ static PassRefPtr<SVGAnimatedEnumeration<Enum> > create(SVGElement* contextElement, const QualifiedName& attributeName, Enum initialValue)
+ {
+ return adoptRef(new SVGAnimatedEnumeration(contextElement, attributeName, SVGEnumeration<Enum>::create(initialValue)));
+ }
-// Helper macros to declare/define a SVGAnimatedEnumeration object
-#define DECLARE_ANIMATED_ENUMERATION(UpperProperty, LowerProperty, EnumType) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedEnumerationPropertyTearOff<EnumType>, EnumType, UpperProperty, LowerProperty)
+ static PassRefPtr<SVGAnimatedEnumeration<Enum> > create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGEnumeration<Enum> > initialValue)
+ {
+ return adoptRef(new SVGAnimatedEnumeration(contextElement, attributeName, initialValue));
+ }
-#define DEFINE_ANIMATED_ENUMERATION(OwnerType, DOMAttribute, UpperProperty, LowerProperty, EnumType) \
-DEFINE_ANIMATED_PROPERTY(AnimatedEnumeration, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedEnumerationPropertyTearOff<EnumType>, EnumType)
+ SVGEnumeration<Enum>* baseValue()
+ {
+ return static_cast<SVGEnumeration<Enum>*>(SVGAnimatedEnumerationBase::baseValue());
+ }
-class SVGAnimatedEnumerationAnimator : public SVGAnimatedTypeAnimator {
-public:
- SVGAnimatedEnumerationAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedEnumerationAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ SVGEnumeration<Enum>* currentValue()
+ {
+ return static_cast<SVGEnumeration<Enum>*>(SVGAnimatedEnumerationBase::currentValue());
+ }
+
+ const SVGEnumeration<Enum>* currentValue() const
+ {
+ return static_cast<const SVGEnumeration<Enum>*>(SVGAnimatedEnumerationBase::currentValue());
+ }
+
+protected:
+ SVGAnimatedEnumeration(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGEnumeration<Enum> > initialValue)
+ : SVGAnimatedEnumerationBase(contextElement, attributeName, initialValue)
+ {
+ }
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedEnumeration_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.idl
index e51c9c1f87d..25621e7b117 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.idl
@@ -23,8 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedEnumeration {
- [StrictTypeChecking, RaisesException=Setter] attribute unsigned short baseVal;
+[
+ ImplementedAs=SVGAnimatedEnumerationBase,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGAnimatedEnumeration {
+ [RaisesException=Setter] attribute unsigned short baseVal;
readonly attribute unsigned short animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp
new file mode 100644
index 00000000000..d9ed0460e3d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGAnimatedEnumerationBase.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGElement.h"
+
+namespace WebCore {
+
+SVGAnimatedEnumerationBase::~SVGAnimatedEnumerationBase()
+{
+}
+
+void SVGAnimatedEnumerationBase::setBaseVal(unsigned short value, ExceptionState& exceptionState)
+{
+ if (this->isReadOnly()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ baseValue()->setValue(value, exceptionState);
+ if (exceptionState.hadException())
+ return;
+
+ m_baseValueUpdated = true;
+
+ ASSERT(this->attributeName() != QualifiedName::null());
+ contextElement()->invalidateSVGAttributes();
+ contextElement()->svgAttributeChanged(this->attributeName());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.h
new file mode 100644
index 00000000000..ea5ffa0631e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGAnimatedEnumerationBase_h
+#define SVGAnimatedEnumerationBase_h
+
+#include "core/svg/SVGEnumeration.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
+
+namespace WebCore {
+
+class SVGAnimatedEnumerationBase : public SVGAnimatedProperty<SVGEnumerationBase> {
+public:
+ virtual ~SVGAnimatedEnumerationBase();
+
+ void setBaseVal(unsigned short, ExceptionState&);
+
+protected:
+ SVGAnimatedEnumerationBase(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGEnumerationBase> initialValue)
+ : SVGAnimatedProperty<SVGEnumerationBase>(contextElement, attributeName, initialValue)
+ {
+ }
+};
+
+}
+
+#endif // SVGAnimatedEnumerationBase_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp
index ff7ccee93d5..991ef7569a6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp
@@ -1,102 +1,48 @@
/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "core/svg/SVGAnimatedInteger.h"
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGAnimatedNumber.h"
-#include "wtf/MathExtras.h"
+#include "core/svg/SVGAnimatedIntegerOptionalInteger.h"
namespace WebCore {
-SVGAnimatedIntegerAnimator::SVGAnimatedIntegerAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedInteger, animationElement, contextElement)
+void SVGAnimatedInteger::synchronizeAttribute()
{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedIntegerAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createInteger(new int);
- animtedType->integer() = string.toIntStrict();
- return animtedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedIntegerAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createInteger(constructFromBaseValue<SVGAnimatedInteger>(animatedTypes));
-}
-
-void SVGAnimatedIntegerAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedInteger>(animatedTypes);
-}
-
-void SVGAnimatedIntegerAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedInteger>(animatedTypes, type, &SVGAnimatedType::integer);
-}
-
-void SVGAnimatedIntegerAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedInteger>(animatedTypes);
-}
+ if (m_parentIntegerOptionalInteger) {
+ m_parentIntegerOptionalInteger->synchronizeAttribute();
+ return;
+ }
-void SVGAnimatedIntegerAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedInteger>(animatedTypes);
-}
-
-void SVGAnimatedIntegerAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedInteger);
- ASSERT(from->type() == to->type());
-
- to->integer() += from->integer();
-}
-
-void SVGAnimatedIntegerAnimator::calculateAnimatedInteger(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, int fromInteger, int toInteger, int toAtEndOfDurationInteger, int& animatedInteger)
-{
- float animatedNumber = animatedInteger;
- animationElement->animateAdditiveNumber(percentage, repeatCount, fromInteger, toInteger, toAtEndOfDurationInteger, animatedNumber);
- animatedInteger = static_cast<int>(roundf(animatedNumber));
-}
-
-void SVGAnimatedIntegerAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- int fromInteger = m_animationElement->animationMode() == ToAnimation ? animated->integer() : from->integer();
- int toInteger = to->integer();
- int toAtEndOfDurationInteger = toAtEndOfDuration->integer();
- int& animatedInteger = animated->integer();
-
- calculateAnimatedInteger(m_animationElement, percentage, repeatCount, fromInteger, toInteger, toAtEndOfDurationInteger, animatedInteger);
-}
-
-float SVGAnimatedIntegerAnimator::calculateDistance(const String& fromString, const String& toString)
-{
- ASSERT(m_contextElement);
- int from = fromString.toIntStrict();
- int to = toString.toIntStrict();
- return abs(to - from);
+ SVGAnimatedProperty<SVGInteger>::synchronizeAttribute();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.h
index 6bca8579ec2..6a16d4b9772 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.h
@@ -1,64 +1,69 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedInteger_h
#define SVGAnimatedInteger_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
-#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h"
+#include "core/svg/SVGInteger.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedStaticPropertyTearOff<int> SVGAnimatedInteger;
+class SVGAnimatedIntegerOptionalInteger;
-// Helper macros to declare/define a SVGAnimatedInteger object
-#define DECLARE_ANIMATED_INTEGER(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedInteger, int, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_INTEGER(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedInteger, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedInteger, int)
-
-#define DEFINE_ANIMATED_INTEGER_MULTIPLE_WRAPPERS(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedIntegerOptionalInteger, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty, SVGAnimatedInteger, int)
-
-class SVGAnimationElement;
-
-class SVGAnimatedIntegerAnimator : public SVGAnimatedTypeAnimator {
+// SVG Spec: http://www.w3.org/TR/SVG11/types.html#InterfaceSVGAnimatedInteger
+class SVGAnimatedInteger : public SVGAnimatedProperty<SVGInteger> {
public:
- SVGAnimatedIntegerAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedIntegerAnimator() { }
+ static PassRefPtr<SVGAnimatedInteger> create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGInteger> initialValue)
+ {
+ return adoptRef(new SVGAnimatedInteger(contextElement, attributeName, initialValue));
+ }
+
+ virtual void synchronizeAttribute() OVERRIDE;
- static void calculateAnimatedInteger(SVGAnimationElement*, float percentage, unsigned repeatCount, int fromInteger, int toInteger, int toAtEndOfDurationInteger, int& animatedInteger);
+ void setParentOptionalInteger(SVGAnimatedIntegerOptionalInteger* numberOptionalInteger)
+ {
+ m_parentIntegerOptionalInteger = numberOptionalInteger;
+ }
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
+protected:
+ SVGAnimatedInteger(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGInteger> initialValue)
+ : SVGAnimatedProperty<SVGInteger>(contextElement, attributeName, initialValue)
+ , m_parentIntegerOptionalInteger(0)
+ {
+ }
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ // FIXME: oilpan: This is kept as raw ptr as this is a back ptr. Change this to Member<> in oilpan.
+ SVGAnimatedIntegerOptionalInteger* m_parentIntegerOptionalInteger;
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedInteger_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.idl
index 3c31681dc6c..4585be933e2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedInteger.idl
@@ -23,8 +23,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedInteger {
- [StrictTypeChecking, RaisesException=Setter] attribute long baseVal;
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGAnimatedInteger {
+ [RaisesException=Setter] attribute long baseVal;
readonly attribute long animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp
index 6db1926cc4f..eb5887f0598 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp
@@ -1,108 +1,67 @@
/*
- * Copyright (C) Research In Motion Limited 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "core/svg/SVGAnimatedIntegerOptionalInteger.h"
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGAnimatedInteger.h"
-#include "core/svg/SVGParserUtilities.h"
-
namespace WebCore {
-SVGAnimatedIntegerOptionalIntegerAnimator::SVGAnimatedIntegerOptionalIntegerAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedIntegerOptionalInteger, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedIntegerOptionalIntegerAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createIntegerOptionalInteger(new pair<int, int>);
- pair<int, int>& animatedInteger = animtedType->integerOptionalInteger();
- float firstNumber = 0;
- float secondNumber = 0;
- if (!parseNumberOptionalNumber(string, firstNumber, secondNumber)) {
- animatedInteger.first = 0;
- animatedInteger.second = 0;
- } else {
- animatedInteger.first = static_cast<int>(roundf(firstNumber));
- animatedInteger.second = static_cast<int>(roundf(secondNumber));
- }
- return animtedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedIntegerOptionalIntegerAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createIntegerOptionalInteger(constructFromBaseValues<SVGAnimatedInteger, SVGAnimatedInteger>(animatedTypes));
-}
-
-void SVGAnimatedIntegerOptionalIntegerAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
+SVGAnimatedIntegerOptionalInteger::SVGAnimatedIntegerOptionalInteger(SVGElement* contextElement, const QualifiedName& attributeName, float initialFirstValue, float initialSecondValue)
+ : SVGAnimatedPropertyCommon<SVGIntegerOptionalInteger>(contextElement, attributeName,
+ SVGIntegerOptionalInteger::create(SVGInteger::create(initialFirstValue), SVGInteger::create(initialSecondValue)))
+ , m_firstInteger(SVGAnimatedInteger::create(contextElement, attributeName, baseValue()->firstInteger()))
+ , m_secondInteger(SVGAnimatedInteger::create(contextElement, attributeName, baseValue()->secondInteger()))
{
- stopAnimValAnimationForTypes<SVGAnimatedInteger, SVGAnimatedInteger>(animatedTypes);
+ m_firstInteger->setParentOptionalInteger(this);
+ m_secondInteger->setParentOptionalInteger(this);
}
-void SVGAnimatedIntegerOptionalIntegerAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
+void SVGAnimatedIntegerOptionalInteger::setAnimatedValue(PassRefPtr<SVGPropertyBase> value)
{
- resetFromBaseValues<SVGAnimatedInteger, SVGAnimatedInteger>(animatedTypes, type, &SVGAnimatedType::integerOptionalInteger);
+ SVGAnimatedPropertyCommon<SVGIntegerOptionalInteger>::setAnimatedValue(value);
+ m_firstInteger->setAnimatedValue(currentValue()->firstInteger());
+ m_secondInteger->setAnimatedValue(currentValue()->secondInteger());
}
-void SVGAnimatedIntegerOptionalIntegerAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
+void SVGAnimatedIntegerOptionalInteger::animationEnded()
{
- animValWillChangeForTypes<SVGAnimatedInteger, SVGAnimatedInteger>(animatedTypes);
-}
-
-void SVGAnimatedIntegerOptionalIntegerAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForTypes<SVGAnimatedInteger, SVGAnimatedInteger>(animatedTypes);
-}
-
-void SVGAnimatedIntegerOptionalIntegerAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedIntegerOptionalInteger);
- ASSERT(from->type() == to->type());
-
- const pair<int, int>& fromIntegerPair = from->integerOptionalInteger();
- pair<int, int>& toIntegerPair = to->integerOptionalInteger();
-
- toIntegerPair.first += fromIntegerPair.first;
- toIntegerPair.second += fromIntegerPair.second;
-}
-
-void SVGAnimatedIntegerOptionalIntegerAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- const pair<int, int>& fromIntegerPair = m_animationElement->animationMode() == ToAnimation ? animated->integerOptionalInteger() : from->integerOptionalInteger();
- const pair<int, int>& toIntegerPair = to->integerOptionalInteger();
- const pair<int, int>& toAtEndOfDurationIntegerPair = toAtEndOfDuration->integerOptionalInteger();
- pair<int, int>& animatedIntegerPair = animated->integerOptionalInteger();
-
- SVGAnimatedIntegerAnimator::calculateAnimatedInteger(m_animationElement, percentage, repeatCount, fromIntegerPair.first, toIntegerPair.first, toAtEndOfDurationIntegerPair.first, animatedIntegerPair.first);
- SVGAnimatedIntegerAnimator::calculateAnimatedInteger(m_animationElement, percentage, repeatCount, fromIntegerPair.second, toIntegerPair.second, toAtEndOfDurationIntegerPair.second, animatedIntegerPair.second);
+ SVGAnimatedPropertyCommon<SVGIntegerOptionalInteger>::animationEnded();
+ m_firstInteger->animationEnded();
+ m_secondInteger->animationEnded();
}
-float SVGAnimatedIntegerOptionalIntegerAnimator::calculateDistance(const String&, const String&)
+bool SVGAnimatedIntegerOptionalInteger::needsSynchronizeAttribute()
{
- // FIXME: Distance calculation is not possible for SVGIntegerOptionalInteger right now. We need the distance for every single value.
- return -1;
+ return m_firstInteger->needsSynchronizeAttribute()
+ || m_secondInteger->needsSynchronizeAttribute();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h
index 05776bee64b..aed59207ea4 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h
@@ -1,48 +1,67 @@
/*
- * Copyright (C) Research In Motion Limited 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedIntegerOptionalInteger_h
#define SVGAnimatedIntegerOptionalInteger_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
+#include "core/svg/SVGAnimatedInteger.h"
+#include "core/svg/SVGIntegerOptionalInteger.h"
namespace WebCore {
-class SVGAnimationElement;
-
-class SVGAnimatedIntegerOptionalIntegerAnimator : public SVGAnimatedTypeAnimator {
+// SVG Spec: http://www.w3.org/TR/SVG11/types.html <number-optional-number>
+// Unlike other SVGAnimated* class, this class is not exposed to Javascript directly,
+// while DOM attribute and SMIL animations operate on this class.
+// From Javascript, the two SVGAnimatedIntegers |firstInteger| and |secondInteger| are used.
+// For example, see SVGFEDropShadowElement::stdDeviation{X,Y}()
+class SVGAnimatedIntegerOptionalInteger : public SVGAnimatedPropertyCommon<SVGIntegerOptionalInteger> {
public:
- SVGAnimatedIntegerOptionalIntegerAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedIntegerOptionalIntegerAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ static PassRefPtr<SVGAnimatedIntegerOptionalInteger> create(SVGElement* contextElement, const QualifiedName& attributeName, float initialFirstValue = 0, float initialSecondValue = 0)
+ {
+ return adoptRef(new SVGAnimatedIntegerOptionalInteger(contextElement, attributeName, initialFirstValue, initialSecondValue));
+ }
+
+ virtual void setAnimatedValue(PassRefPtr<SVGPropertyBase>) OVERRIDE;
+ virtual bool needsSynchronizeAttribute() OVERRIDE;
+ virtual void animationEnded() OVERRIDE;
+
+ SVGAnimatedInteger* firstInteger() { return m_firstInteger.get(); }
+ SVGAnimatedInteger* secondInteger() { return m_secondInteger.get(); }
+
+protected:
+ SVGAnimatedIntegerOptionalInteger(SVGElement* contextElement, const QualifiedName& attributeName, float initialFirstValue, float initialSecondValue);
+
+ RefPtr<SVGAnimatedInteger> m_firstInteger;
+ RefPtr<SVGAnimatedInteger> m_secondInteger;
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedIntegerOptionalInteger_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp
index d1f127ea02f..097c96decd7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp
@@ -1,122 +1,56 @@
/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-#include "core/svg/SVGAnimatedLength.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGAnimatedNumber.h"
+#include "core/svg/SVGAnimatedLength.h"
namespace WebCore {
-SVGAnimatedLengthAnimator::SVGAnimatedLengthAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedLength, animationElement, contextElement)
- , m_lengthMode(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()))
-{
-}
-
-static inline SVGLength& sharedSVGLength(SVGLengthMode mode, const String& valueAsString)
-{
- DEFINE_STATIC_LOCAL(SVGLength, sharedLength, ());
- sharedLength.setValueAsString(valueAsString, mode, ASSERT_NO_EXCEPTION);
- return sharedLength;
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedLengthAnimator::constructFromString(const String& string)
-{
- return SVGAnimatedType::createLength(new SVGLength(m_lengthMode, string));
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedLengthAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createLength(constructFromBaseValue<SVGAnimatedLength>(animatedTypes));
-}
-
-void SVGAnimatedLengthAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedLength>(animatedTypes);
-}
-
-void SVGAnimatedLengthAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedLength>(animatedTypes, type, &SVGAnimatedType::length);
-}
-
-void SVGAnimatedLengthAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedLength>(animatedTypes);
-}
-
-void SVGAnimatedLengthAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedLength>(animatedTypes);
-}
-
-void SVGAnimatedLengthAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedLength);
- ASSERT(from->type() == to->type());
-
- SVGLengthContext lengthContext(m_contextElement);
- const SVGLength& fromLength = from->length();
- SVGLength& toLength = to->length();
-
- toLength.setValue(toLength.value(lengthContext) + fromLength.value(lengthContext), lengthContext, ASSERT_NO_EXCEPTION);
-}
-
-static SVGLength parseLengthFromString(SVGAnimationElement* animationElement, const String& string)
+void SVGAnimatedLength::setDefaultValueAsString(const String& value)
{
- return sharedSVGLength(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()), string);
+ baseValue()->setValueAsString(value, ASSERT_NO_EXCEPTION);
}
-void SVGAnimatedLengthAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
+void SVGAnimatedLength::setBaseValueAsString(const String& value, SVGParsingError& parseError)
{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- SVGLength fromSVGLength = m_animationElement->animationMode() == ToAnimation ? animated->length() : from->length();
- SVGLength toSVGLength = to->length();
- const SVGLength& toAtEndOfDurationSVGLength = toAtEndOfDuration->length();
- SVGLength& animatedSVGLength = animated->length();
+ TrackExceptionState es;
- // Apply CSS inheritance rules.
- m_animationElement->adjustForInheritance<SVGLength>(parseLengthFromString, m_animationElement->fromPropertyValueType(), fromSVGLength, m_contextElement);
- m_animationElement->adjustForInheritance<SVGLength>(parseLengthFromString, m_animationElement->toPropertyValueType(), toSVGLength, m_contextElement);
+ baseValue()->setValueAsString(value, es);
- SVGLengthContext lengthContext(m_contextElement);
- float animatedNumber = animatedSVGLength.value(lengthContext);
- SVGLengthType unitType = percentage < 0.5 ? fromSVGLength.unitType() : toSVGLength.unitType();
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromSVGLength.value(lengthContext), toSVGLength.value(lengthContext), toAtEndOfDurationSVGLength.value(lengthContext), animatedNumber);
-
- animatedSVGLength.setValue(lengthContext, animatedNumber, m_lengthMode, unitType, ASSERT_NO_EXCEPTION);
-}
-
-float SVGAnimatedLengthAnimator::calculateDistance(const String& fromString, const String& toString)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
- SVGLengthMode lengthMode = SVGLength::lengthModeForAnimatedLengthAttribute(m_animationElement->attributeName());
- SVGLength from = SVGLength(lengthMode, fromString);
- SVGLength to = SVGLength(lengthMode, toString);
- SVGLengthContext lengthContext(m_contextElement);
- return fabsf(to.value(lengthContext) - from.value(lengthContext));
+ if (es.hadException()) {
+ parseError = ParsingAttributeFailedError;
+ baseValue()->newValueSpecifiedUnits(LengthTypeNumber, 0);
+ } else if (m_negativeValuesMode == ForbidNegativeLengths && baseValue()->valueInSpecifiedUnits() < 0) {
+ parseError = NegativeValueForbiddenError;
+ }
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.h
index d6f58ba8383..8a54929ffb8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.h
@@ -1,62 +1,62 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedLength_h
#define SVGAnimatedLength_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/SVGLength.h"
-#include "core/svg/properties/SVGAnimatedPropertyTearOff.h"
+#include "core/svg/SVGLengthTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedPropertyTearOff<SVGLength> SVGAnimatedLength;
-
-// Helper macros to declare/define a SVGAnimatedLength object
-#define DECLARE_ANIMATED_LENGTH(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedLength, SVGLength, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_LENGTH(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedLength, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedLength, SVGLength)
-
-class SVGAnimationElement;
-
-class SVGAnimatedLengthAnimator : public SVGAnimatedTypeAnimator {
+class SVGAnimatedLength : public SVGAnimatedProperty<SVGLength> {
public:
- SVGAnimatedLengthAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedLengthAnimator() { }
+ static PassRefPtr<SVGAnimatedLength> create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGLength> initialValue, SVGLengthNegativeValuesMode negativeValuesMode)
+ {
+ return adoptRef(new SVGAnimatedLength(contextElement, attributeName, initialValue, negativeValuesMode));
+ }
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
+ void setDefaultValueAsString(const String&);
+ void setBaseValueAsString(const String&, SVGParsingError&);
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+protected:
+ SVGAnimatedLength(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGLength> initialValue, SVGLengthNegativeValuesMode negativeValuesMode)
+ : SVGAnimatedProperty<SVGLength>(contextElement, attributeName, initialValue)
+ , m_negativeValuesMode(negativeValuesMode)
+ {
+ }
private:
- SVGLengthMode m_lengthMode;
+ SVGLengthNegativeValuesMode m_negativeValuesMode;
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedLength_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.idl
index d3003470f29..c741a20ed59 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLength.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedLength {
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedLength {
readonly attribute SVGLength baseVal;
readonly attribute SVGLength animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.cpp
deleted file mode 100644
index 513114bd7a3..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/SVGAnimatedLengthList.h"
-
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGAnimatedNumber.h"
-
-namespace WebCore {
-
-SVGAnimatedLengthListAnimator::SVGAnimatedLengthListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedLengthList, animationElement, contextElement)
- , m_lengthMode(SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()))
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedLengthListAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animateType = SVGAnimatedType::createLengthList(new SVGLengthList);
- animateType->lengthList().parse(string, m_lengthMode);
- return animateType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedLengthListAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createLengthList(constructFromBaseValue<SVGAnimatedLengthList>(animatedTypes));
-}
-
-void SVGAnimatedLengthListAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedLengthList>(animatedTypes);
-}
-
-void SVGAnimatedLengthListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedLengthList>(animatedTypes, type, &SVGAnimatedType::lengthList);
-}
-
-void SVGAnimatedLengthListAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedLengthList>(animatedTypes);
-}
-
-void SVGAnimatedLengthListAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedLengthList>(animatedTypes);
-}
-
-void SVGAnimatedLengthListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedLengthList);
- ASSERT(from->type() == to->type());
-
- const SVGLengthList& fromLengthList = from->lengthList();
- SVGLengthList& toLengthList = to->lengthList();
-
- unsigned fromLengthListSize = fromLengthList.size();
- if (!fromLengthListSize || fromLengthListSize != toLengthList.size())
- return;
-
- SVGLengthContext lengthContext(m_contextElement);
- for (unsigned i = 0; i < fromLengthListSize; ++i)
- toLengthList[i].setValue(toLengthList[i].value(lengthContext) + fromLengthList[i].value(lengthContext), lengthContext, ASSERT_NO_EXCEPTION);
-}
-
-static SVGLengthList parseLengthListFromString(SVGAnimationElement* animationElement, const String& string)
-{
- SVGLengthList lengthList;
- lengthList.parse(string, SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
- return lengthList;
-}
-
-void SVGAnimatedLengthListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- SVGLengthList fromLengthList = m_animationElement->animationMode() == ToAnimation ? animated->lengthList() : from->lengthList();
- SVGLengthList toLengthList = to->lengthList();
- const SVGLengthList& toAtEndOfDurationLengthList = toAtEndOfDuration->lengthList();
- SVGLengthList& animatedLengthList = animated->lengthList();
-
- // Apply CSS inheritance rules.
- m_animationElement->adjustForInheritance<SVGLengthList>(parseLengthListFromString, m_animationElement->fromPropertyValueType(), fromLengthList, m_contextElement);
- m_animationElement->adjustForInheritance<SVGLengthList>(parseLengthListFromString, m_animationElement->toPropertyValueType(), toLengthList, m_contextElement);
-
- if (!m_animationElement->adjustFromToListValues<SVGLengthList>(fromLengthList, toLengthList, animatedLengthList, percentage))
- return;
-
- unsigned fromLengthListSize = fromLengthList.size();
- unsigned toLengthListSize = toLengthList.size();
- unsigned toAtEndOfDurationListSize = toAtEndOfDurationLengthList.size();
-
- SVGLengthContext lengthContext(m_contextElement);
- for (unsigned i = 0; i < toLengthListSize; ++i) {
- float animatedNumber = animatedLengthList[i].value(lengthContext);
- SVGLengthType unitType = toLengthList[i].unitType();
- float effectiveFrom = 0;
- if (fromLengthListSize) {
- if (percentage < 0.5)
- unitType = fromLengthList[i].unitType();
- effectiveFrom = fromLengthList[i].value(lengthContext);
- }
- float effectiveToAtEnd = i < toAtEndOfDurationListSize ? toAtEndOfDurationLengthList[i].value(lengthContext) : 0;
-
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toLengthList[i].value(lengthContext), effectiveToAtEnd, animatedNumber);
- animatedLengthList[i].setValue(lengthContext, animatedNumber, m_lengthMode, unitType, ASSERT_NO_EXCEPTION);
- }
-}
-
-float SVGAnimatedLengthListAnimator::calculateDistance(const String&, const String&)
-{
- // FIXME: Distance calculation is not possible for SVGLengthList right now. We need the distance for every single value.
- return -1;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.h
index 805b7b17482..783c74ba6ae 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.h
@@ -1,61 +1,42 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedLengthList_h
#define SVGAnimatedLengthList_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/SVGLengthList.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
+#include "core/svg/SVGLengthListTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedListPropertyTearOff<SVGLengthList> SVGAnimatedLengthList;
-
-// Helper macros to declare/define a SVGAnimatedLengthList object
-#define DECLARE_ANIMATED_LENGTH_LIST(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedLengthList, SVGLengthList, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_LENGTH_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedLengthList, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedLengthList, SVGLengthList)
-
-class SVGAnimationElement;
-
-class SVGAnimatedLengthListAnimator : public SVGAnimatedTypeAnimator {
-public:
- SVGAnimatedLengthListAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedLengthListAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
-
-private:
- SVGLengthMode m_lengthMode;
-};
+typedef SVGAnimatedProperty<SVGLengthList> SVGAnimatedLengthList;
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.idl
index f193b7cbd80..ec507a32d61 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedLengthList.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedLengthList {
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedLengthList {
readonly attribute SVGLengthList baseVal;
readonly attribute SVGLengthList animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp
index 4c759eeafa6..e8280afa97f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp
@@ -1,112 +1,48 @@
/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "core/svg/SVGAnimatedNumber.h"
-
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGParserUtilities.h"
-
-using namespace std;
+#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
namespace WebCore {
-SVGAnimatedNumberAnimator::SVGAnimatedNumberAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedNumber, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNumberAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createNumber(new float);
- float& animatedNumber = animtedType->number();
- if (!parseNumberFromString(string, animatedNumber))
- animatedNumber = 0;
- return animtedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNumberAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createNumber(constructFromBaseValue<SVGAnimatedNumber>(animatedTypes));
-}
-
-void SVGAnimatedNumberAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedNumber>(animatedTypes);
-}
-
-void SVGAnimatedNumberAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
+void SVGAnimatedNumber::synchronizeAttribute()
{
- resetFromBaseValue<SVGAnimatedNumber>(animatedTypes, type, &SVGAnimatedType::number);
-}
-
-void SVGAnimatedNumberAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedNumber>(animatedTypes);
-}
+ if (m_parentNumberOptionalNumber) {
+ m_parentNumberOptionalNumber->synchronizeAttribute();
+ return;
+ }
-void SVGAnimatedNumberAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedNumber>(animatedTypes);
-}
-
-void SVGAnimatedNumberAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedNumber);
- ASSERT(from->type() == to->type());
-
- to->number() += from->number();
-}
-
-static float parseNumberFromString(SVGAnimationElement*, const String& string)
-{
- float number = 0;
- parseNumberFromString(string, number);
- return number;
-}
-
-void SVGAnimatedNumberAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- float fromNumber = m_animationElement->animationMode() == ToAnimation ? animated->number() : from->number();
- float toNumber = to->number();
- float toAtEndOfDurationNumber = toAtEndOfDuration->number();
- float& animatedNumber = animated->number();
-
- // Apply CSS inheritance rules.
- m_animationElement->adjustForInheritance<float>(parseNumberFromString, m_animationElement->fromPropertyValueType(), fromNumber, m_contextElement);
- m_animationElement->adjustForInheritance<float>(parseNumberFromString, m_animationElement->toPropertyValueType(), toNumber, m_contextElement);
-
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromNumber, toNumber, toAtEndOfDurationNumber, animatedNumber);
-}
-
-float SVGAnimatedNumberAnimator::calculateDistance(const String& fromString, const String& toString)
-{
- ASSERT(m_contextElement);
- float from = 0;
- float to = 0;
- parseNumberFromString(fromString, from);
- parseNumberFromString(toString, to);
- return fabsf(to - from);
+ SVGAnimatedProperty<SVGNumber>::synchronizeAttribute();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.h
index 7c5e54ee2cc..d71e6fd6cb3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.h
@@ -1,62 +1,69 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedNumber_h
#define SVGAnimatedNumber_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
-#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h"
+#include "core/svg/SVGNumberTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedStaticPropertyTearOff<float> SVGAnimatedNumber;
+class SVGAnimatedNumberOptionalNumber;
-// Helper macros to declare/define a SVGAnimatedNumber object
-#define DECLARE_ANIMATED_NUMBER(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedNumber, float, UpperProperty, LowerProperty)
+// SVG Spec: http://www.w3.org/TR/SVG11/types.html#InterfaceSVGAnimatedNumber
+class SVGAnimatedNumber : public SVGAnimatedProperty<SVGNumber> {
+public:
+ static PassRefPtr<SVGAnimatedNumber> create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGNumber> initialValue)
+ {
+ return adoptRef(new SVGAnimatedNumber(contextElement, attributeName, initialValue));
+ }
-#define DEFINE_ANIMATED_NUMBER(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedNumber, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedNumber, float)
+ virtual void synchronizeAttribute() OVERRIDE;
-#define DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedNumberOptionalNumber, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty, SVGAnimatedNumber, float)
+ void setParentOptionalNumber(SVGAnimatedNumberOptionalNumber* numberOptionalNumber)
+ {
+ m_parentNumberOptionalNumber = numberOptionalNumber;
+ }
-class SVGAnimationElement;
+protected:
+ SVGAnimatedNumber(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGNumber> initialValue)
+ : SVGAnimatedProperty<SVGNumber>(contextElement, attributeName, initialValue)
+ , m_parentNumberOptionalNumber(0)
+ {
+ }
-class SVGAnimatedNumberAnimator : public SVGAnimatedTypeAnimator {
-public:
- SVGAnimatedNumberAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedNumberAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ // FIXME: oilpan: This is kept as raw ptr as this is a back ptr. Change this to Member<> in oilpan.
+ SVGAnimatedNumberOptionalNumber* m_parentNumberOptionalNumber;
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedNumber_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.idl
index e8cc9ba3161..ca880825bd7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumber.idl
@@ -24,8 +24,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedNumber {
- [StrictTypeChecking, RaisesException=Setter] attribute float baseVal;
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGAnimatedNumber {
+ [RaisesException=Setter] attribute float baseVal;
readonly attribute float animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.cpp
deleted file mode 100644
index 7f1d9e7fe7d..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedNumberList.h"
-
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGAnimatedNumber.h"
-
-namespace WebCore {
-
-SVGAnimatedNumberListAnimator::SVGAnimatedNumberListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedNumberList, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNumberListAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createNumberList(new SVGNumberList);
- animtedType->numberList().parse(string);
- return animtedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNumberListAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createNumberList(constructFromBaseValue<SVGAnimatedNumberList>(animatedTypes));
-}
-
-void SVGAnimatedNumberListAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedNumberList>(animatedTypes);
-}
-
-void SVGAnimatedNumberListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedNumberList>(animatedTypes, type, &SVGAnimatedType::numberList);
-}
-
-void SVGAnimatedNumberListAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedNumberList>(animatedTypes);
-}
-
-void SVGAnimatedNumberListAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedNumberList>(animatedTypes);
-}
-
-void SVGAnimatedNumberListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedNumberList);
- ASSERT(from->type() == to->type());
-
- const SVGNumberList& fromNumberList = from->numberList();
- SVGNumberList& toNumberList = to->numberList();
-
- unsigned fromNumberListSize = fromNumberList.size();
- if (!fromNumberListSize || fromNumberListSize != toNumberList.size())
- return;
-
- for (unsigned i = 0; i < fromNumberListSize; ++i)
- toNumberList[i] += fromNumberList[i];
-}
-
-void SVGAnimatedNumberListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
-
- const SVGNumberList& fromNumberList = m_animationElement->animationMode() == ToAnimation ? animated->numberList() : from->numberList();
- const SVGNumberList& toNumberList = to->numberList();
- const SVGNumberList& toAtEndOfDurationNumberList = toAtEndOfDuration->numberList();
- SVGNumberList& animatedNumberList = animated->numberList();
- if (!m_animationElement->adjustFromToListValues<SVGNumberList>(fromNumberList, toNumberList, animatedNumberList, percentage))
- return;
-
- unsigned fromNumberListSize = fromNumberList.size();
- unsigned toNumberListSize = toNumberList.size();
- unsigned toAtEndOfDurationSize = toAtEndOfDurationNumberList.size();
-
- for (unsigned i = 0; i < toNumberListSize; ++i) {
- float effectiveFrom = fromNumberListSize ? fromNumberList[i].value() : 0;
- float effectiveToAtEnd = i < toAtEndOfDurationSize ? toAtEndOfDurationNumberList[i].value() : 0;
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, toNumberList[i].value(), effectiveToAtEnd, animatedNumberList[i].valueRef());
- }
-}
-
-float SVGAnimatedNumberListAnimator::calculateDistance(const String&, const String&)
-{
- // FIXME: Distance calculation is not possible for SVGNumberList right now. We need the distance for every single value.
- return -1;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.h
index a144c3fd454..8314c4e4e8b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.h
@@ -1,58 +1,42 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedNumberList_h
#define SVGAnimatedNumberList_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/SVGNumberList.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
+#include "core/svg/SVGNumberListTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedListPropertyTearOff<SVGNumberList> SVGAnimatedNumberList;
-
-// Helper macros to declare/define a SVGAnimatedNumberList object
-#define DECLARE_ANIMATED_NUMBER_LIST(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedNumberList, SVGNumberList, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_NUMBER_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedNumberList, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedNumberList, SVGNumberList)
-
-class SVGAnimationElement;
-
-class SVGAnimatedNumberListAnimator : public SVGAnimatedTypeAnimator {
-public:
- SVGAnimatedNumberListAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedNumberListAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
-};
+typedef SVGAnimatedProperty<SVGNumberList> SVGAnimatedNumberList;
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.idl
index 43845d319a9..355e49006e5 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberList.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedNumberList {
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedNumberList {
readonly attribute SVGNumberList baseVal;
readonly attribute SVGNumberList animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp
index e3e55a653f0..8c44117c2dc 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp
@@ -21,85 +21,36 @@
#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGAnimatedNumber.h"
-#include "core/svg/SVGParserUtilities.h"
-
-using namespace std;
-
namespace WebCore {
-SVGAnimatedNumberOptionalNumberAnimator::SVGAnimatedNumberOptionalNumberAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedNumberOptionalNumber, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNumberOptionalNumberAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createNumberOptionalNumber(new pair<float, float>);
- pair<float, float>& animatedNumber = animtedType->numberOptionalNumber();
- if (!parseNumberOptionalNumber(string, animatedNumber.first, animatedNumber.second)) {
- animatedNumber.first = 0;
- animatedNumber.second = 0;
- }
- return animtedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNumberOptionalNumberAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createNumberOptionalNumber(constructFromBaseValues<SVGAnimatedNumber, SVGAnimatedNumber>(animatedTypes));
-}
-
-void SVGAnimatedNumberOptionalNumberAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForTypes<SVGAnimatedNumber, SVGAnimatedNumber>(animatedTypes);
-}
-
-void SVGAnimatedNumberOptionalNumberAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValues<SVGAnimatedNumber, SVGAnimatedNumber>(animatedTypes, type, &SVGAnimatedType::numberOptionalNumber);
-}
-
-void SVGAnimatedNumberOptionalNumberAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForTypes<SVGAnimatedNumber, SVGAnimatedNumber>(animatedTypes);
-}
-
-void SVGAnimatedNumberOptionalNumberAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
+SVGAnimatedNumberOptionalNumber::SVGAnimatedNumberOptionalNumber(SVGElement* contextElement, const QualifiedName& attributeName, float initialFirstValue, float initialSecondValue)
+ : SVGAnimatedPropertyCommon<SVGNumberOptionalNumber>(contextElement, attributeName,
+ SVGNumberOptionalNumber::create(SVGNumber::create(initialFirstValue), SVGNumber::create(initialSecondValue)))
+ , m_firstNumber(SVGAnimatedNumber::create(contextElement, attributeName, baseValue()->firstNumber()))
+ , m_secondNumber(SVGAnimatedNumber::create(contextElement, attributeName, baseValue()->secondNumber()))
{
- animValDidChangeForTypes<SVGAnimatedNumber, SVGAnimatedNumber>(animatedTypes);
+ m_firstNumber->setParentOptionalNumber(this);
+ m_secondNumber->setParentOptionalNumber(this);
}
-void SVGAnimatedNumberOptionalNumberAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
+void SVGAnimatedNumberOptionalNumber::setAnimatedValue(PassRefPtr<SVGPropertyBase> value)
{
- ASSERT(from->type() == AnimatedNumberOptionalNumber);
- ASSERT(from->type() == to->type());
-
- const pair<float, float>& fromNumberPair = from->numberOptionalNumber();
- pair<float, float>& toNumberPair = to->numberOptionalNumber();
-
- toNumberPair.first += fromNumberPair.first;
- toNumberPair.second += fromNumberPair.second;
+ SVGAnimatedPropertyCommon<SVGNumberOptionalNumber>::setAnimatedValue(value);
+ m_firstNumber->setAnimatedValue(currentValue()->firstNumber());
+ m_secondNumber->setAnimatedValue(currentValue()->secondNumber());
}
-void SVGAnimatedNumberOptionalNumberAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
+void SVGAnimatedNumberOptionalNumber::animationEnded()
{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- const pair<float, float>& fromNumberPair = m_animationElement->animationMode() == ToAnimation ? animated->numberOptionalNumber() : from->numberOptionalNumber();
- const pair<float, float>& toNumberPair = to->numberOptionalNumber();
- const pair<float, float>& toAtEndOfDurationNumberPair = toAtEndOfDuration->numberOptionalNumber();
- pair<float, float>& animatedNumberPair = animated->numberOptionalNumber();
-
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromNumberPair.first, toNumberPair.first, toAtEndOfDurationNumberPair.first, animatedNumberPair.first);
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromNumberPair.second, toNumberPair.second, toAtEndOfDurationNumberPair.second, animatedNumberPair.second);
+ SVGAnimatedPropertyCommon<SVGNumberOptionalNumber>::animationEnded();
+ m_firstNumber->animationEnded();
+ m_secondNumber->animationEnded();
}
-float SVGAnimatedNumberOptionalNumberAnimator::calculateDistance(const String&, const String&)
+bool SVGAnimatedNumberOptionalNumber::needsSynchronizeAttribute()
{
- // FIXME: Distance calculation is not possible for SVGNumberOptionalNumber right now. We need the distance for every single value.
- return -1;
+ return m_firstNumber->needsSynchronizeAttribute()
+ || m_secondNumber->needsSynchronizeAttribute();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.h
index 3e43d9a59dd..d5f7ba88163 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.h
@@ -1,48 +1,67 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedNumberOptionalNumber_h
#define SVGAnimatedNumberOptionalNumber_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
+#include "core/svg/SVGAnimatedNumber.h"
+#include "core/svg/SVGNumberOptionalNumber.h"
namespace WebCore {
-class SVGAnimationElement;
-
-class SVGAnimatedNumberOptionalNumberAnimator : public SVGAnimatedTypeAnimator {
+// SVG Spec: http://www.w3.org/TR/SVG11/types.html <number-optional-number>
+// Unlike other SVGAnimated* class, this class is not exposed to Javascript directly,
+// while DOM attribute and SMIL animations operate on this class.
+// From Javascript, the two SVGAnimatedNumbers |firstNumber| and |secondNumber| are used.
+// For example, see SVGFEDropShadowElement::stdDeviation{X,Y}()
+class SVGAnimatedNumberOptionalNumber : public SVGAnimatedPropertyCommon<SVGNumberOptionalNumber> {
public:
- SVGAnimatedNumberOptionalNumberAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedNumberOptionalNumberAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ static PassRefPtr<SVGAnimatedNumberOptionalNumber> create(SVGElement* contextElement, const QualifiedName& attributeName, float initialFirstValue = 0, float initialSecondValue = 0)
+ {
+ return adoptRef(new SVGAnimatedNumberOptionalNumber(contextElement, attributeName, initialFirstValue, initialSecondValue));
+ }
+
+ virtual void setAnimatedValue(PassRefPtr<SVGPropertyBase>) OVERRIDE;
+ virtual bool needsSynchronizeAttribute() OVERRIDE;
+ virtual void animationEnded() OVERRIDE;
+
+ SVGAnimatedNumber* firstNumber() { return m_firstNumber.get(); }
+ SVGAnimatedNumber* secondNumber() { return m_secondNumber.get(); }
+
+protected:
+ SVGAnimatedNumberOptionalNumber(SVGElement* contextElement, const QualifiedName& attributeName, float initialFirstValue, float initialSecondValue);
+
+ RefPtr<SVGAnimatedNumber> m_firstNumber;
+ RefPtr<SVGAnimatedNumber> m_secondNumber;
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedNumberOptionalNumber_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp
index 57e33dce683..5e5cb707b20 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp
@@ -1,147 +1,47 @@
/*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
-
#include "core/svg/SVGAnimatedPath.h"
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGPathUtilities.h"
-#include "core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h"
+#include "core/svg/SVGPathElement.h"
namespace WebCore {
-SVGAnimatedPathAnimator::SVGAnimatedPathAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedPath, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedPathAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create();
- buildSVGPathByteStreamFromString(string, byteStream.get(), UnalteredParsing);
- return SVGAnimatedType::createPath(byteStream.release());
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedPathAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- ASSERT(animatedTypes.size() >= 1);
- SVGAnimatedPathSegListPropertyTearOff* property = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get());
- const SVGPathSegList& baseValue = property->currentBaseValue();
-
- // Build initial path byte stream.
- OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create();
- buildSVGPathByteStreamFromSVGPathSegList(baseValue, byteStream.get(), UnalteredParsing);
-
- Vector<RefPtr<SVGAnimatedPathSegListPropertyTearOff> > result;
-
- SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end();
- for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it)
- result.append(castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(it->properties[0].get()));
-
- SVGElementInstance::InstanceUpdateBlocker blocker(property->contextElement());
-
- size_t resultSize = result.size();
- for (size_t i = 0; i < resultSize; ++i)
- result[i]->animationStarted(byteStream.get(), &baseValue);
-
- return SVGAnimatedType::createPath(byteStream.release());
-}
-
-void SVGAnimatedPathAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
+SVGAnimatedPath::SVGAnimatedPath(SVGPathElement* contextElement, const QualifiedName& attributeName)
+ : SVGAnimatedProperty<SVGPathSegList>(contextElement, attributeName, SVGPathSegList::create(contextElement, PathSegUnalteredRole))
{
- stopAnimValAnimationForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes);
-}
-
-void SVGAnimatedPathAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- ASSERT(animatedTypes.size() >= 1);
- ASSERT(type);
- ASSERT(type->type() == m_type);
- const SVGPathSegList& baseValue = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get())->currentBaseValue();
- buildSVGPathByteStreamFromSVGPathSegList(baseValue, type->path(), UnalteredParsing);
-}
-
-void SVGAnimatedPathAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes);
-}
-
-void SVGAnimatedPathAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes);
-}
-
-void SVGAnimatedPathAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedPath);
- ASSERT(from->type() == to->type());
-
- SVGPathByteStream* fromPath = from->path();
- SVGPathByteStream* toPath = to->path();
- unsigned fromPathSize = fromPath->size();
- if (!fromPathSize || fromPathSize != toPath->size())
- return;
- addToSVGPathByteStream(toPath, fromPath);
-}
-
-void SVGAnimatedPathAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- SVGPathByteStream* fromPath = from->path();
- SVGPathByteStream* toPath = to->path();
- SVGPathByteStream* toAtEndOfDurationPath = toAtEndOfDuration->path();
- SVGPathByteStream* animatedPath = animated->path();
-
- OwnPtr<SVGPathByteStream> underlyingPath;
- bool isToAnimation = m_animationElement->animationMode() == ToAnimation;
- if (isToAnimation) {
- underlyingPath = animatedPath->copy();
- fromPath = underlyingPath.get();
- }
-
- // Cache the current animated value before the buildAnimatedSVGPathByteStream() clears animatedPath.
- OwnPtr<SVGPathByteStream> lastAnimatedPath;
- if (!fromPath->size() || (m_animationElement->isAdditive() && !isToAnimation))
- lastAnimatedPath = animatedPath->copy();
-
- // Pass false to 'resizeAnimatedListIfNeeded' here, as the path animation is not a regular Vector<SVGXXX> type, but a SVGPathByteStream, that works differently.
- if (!m_animationElement->adjustFromToListValues<SVGPathByteStream>(*fromPath, *toPath, *animatedPath, percentage, false))
- return;
-
- buildAnimatedSVGPathByteStream(fromPath, toPath, animatedPath, percentage);
-
- // Handle additive='sum'.
- if (lastAnimatedPath)
- addToSVGPathByteStream(animatedPath, lastAnimatedPath.get());
-
- // Handle accumulate='sum'.
- if (m_animationElement->isAccumulated() && repeatCount)
- addToSVGPathByteStream(animatedPath, toAtEndOfDurationPath, repeatCount);
}
-float SVGAnimatedPathAnimator::calculateDistance(const String&, const String&)
+SVGAnimatedPath::~SVGAnimatedPath()
{
- // FIXME: Support paced animations.
- return -1;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.h
index cca7bbd6845..be3533f564d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPath.h
@@ -1,48 +1,56 @@
/*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedPath_h
#define SVGAnimatedPath_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
+#include "core/svg/SVGPathSegListTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-class SVGAnimationElement;
+class SVGPathElement;
-class SVGAnimatedPathAnimator : public SVGAnimatedTypeAnimator {
+class SVGAnimatedPath : public SVGAnimatedProperty<SVGPathSegList> {
public:
- SVGAnimatedPathAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedPathAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ virtual ~SVGAnimatedPath();
+
+ static PassRefPtr<SVGAnimatedPath> create(SVGPathElement* contextElement, const QualifiedName& attributeName)
+ {
+ return adoptRef(new SVGAnimatedPath(contextElement, attributeName));
+ }
+
+protected:
+ SVGAnimatedPath(SVGPathElement*, const QualifiedName&);
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedPath_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.cpp
deleted file mode 100644
index fd68ad04e7e..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedPointList.h"
-
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGParserUtilities.h"
-
-namespace WebCore {
-
-SVGAnimatedPointListAnimator::SVGAnimatedPointListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedPoints, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedPointListAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animtedType = SVGAnimatedType::createPointList(new SVGPointList);
- pointsListFromSVGData(animtedType->pointList(), string);
- return animtedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedPointListAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createPointList(constructFromBaseValue<SVGAnimatedPointList>(animatedTypes));
-}
-
-void SVGAnimatedPointListAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedPointList>(animatedTypes);
-}
-
-void SVGAnimatedPointListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedPointList>(animatedTypes, type, &SVGAnimatedType::pointList);
-}
-
-void SVGAnimatedPointListAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedPointList>(animatedTypes);
-}
-
-void SVGAnimatedPointListAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedPointList>(animatedTypes);
-}
-
-void SVGAnimatedPointListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedPoints);
- ASSERT(from->type() == to->type());
-
- const SVGPointList& fromPointList = from->pointList();
- SVGPointList& toPointList = to->pointList();
-
- unsigned fromPointListSize = fromPointList.size();
- if (!fromPointListSize || fromPointListSize != toPointList.size())
- return;
-
- for (unsigned i = 0; i < fromPointListSize; ++i)
- toPointList[i] += fromPointList[i];
-}
-
-void SVGAnimatedPointListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
-
- const SVGPointList& fromPointList = m_animationElement->animationMode() == ToAnimation ? animated->pointList() : from->pointList();
- const SVGPointList& toPointList = to->pointList();
- const SVGPointList& toAtEndOfDurationPointList = toAtEndOfDuration->pointList();
- SVGPointList& animatedPointList = animated->pointList();
- if (!m_animationElement->adjustFromToListValues<SVGPointList>(fromPointList, toPointList, animatedPointList, percentage))
- return;
-
- unsigned fromPointListSize = fromPointList.size();
- unsigned toPointListSize = toPointList.size();
- unsigned toAtEndOfDurationSize = toAtEndOfDurationPointList.size();
-
- for (unsigned i = 0; i < toPointListSize; ++i) {
- FloatPoint effectiveFrom;
- if (fromPointListSize)
- effectiveFrom = fromPointList[i];
- FloatPoint effectiveToAtEnd = i < toAtEndOfDurationSize ? toAtEndOfDurationPointList[i] : FloatPoint();
-
- float animatedX = animatedPointList[i].x();
- float animatedY = animatedPointList[i].y();
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom.x(), toPointList[i].x(), effectiveToAtEnd.x(), animatedX);
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom.y(), toPointList[i].y(), effectiveToAtEnd.y(), animatedY);
- animatedPointList[i] = FloatPoint(animatedX, animatedY);
- }
-}
-
-float SVGAnimatedPointListAnimator::calculateDistance(const String&, const String&)
-{
- // FIXME: Distance calculation is not possible for SVGPointList right now. We need the distance of for every single value.
- return -1;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.h
index 8a835245968..d9e1de6d982 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPointList.h
@@ -1,51 +1,42 @@
/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedPointList_h
#define SVGAnimatedPointList_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/SVGPointList.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
+#include "core/svg/SVGPointListTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedListPropertyTearOff<SVGPointList> SVGAnimatedPointList;
-
-class SVGAnimationElement;
-
-class SVGAnimatedPointListAnimator : public SVGAnimatedTypeAnimator {
-public:
- SVGAnimatedPointListAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedPointListAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
-};
+typedef SVGAnimatedProperty<SVGPointList> SVGAnimatedPointList;
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.cpp
deleted file mode 100644
index 79f0178b3f9..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-
-#include "core/svg/SVGAnimateElement.h"
-
-namespace WebCore {
-
-SVGAnimatedPreserveAspectRatioAnimator::SVGAnimatedPreserveAspectRatioAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedPreserveAspectRatio, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedPreserveAspectRatioAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createPreserveAspectRatio(new SVGPreserveAspectRatio);
- animatedType->preserveAspectRatio().parse(string);
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedPreserveAspectRatioAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createPreserveAspectRatio(constructFromBaseValue<SVGAnimatedPreserveAspectRatio>(animatedTypes));
-}
-
-void SVGAnimatedPreserveAspectRatioAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedPreserveAspectRatio>(animatedTypes);
-}
-
-void SVGAnimatedPreserveAspectRatioAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedPreserveAspectRatio>(animatedTypes, type, &SVGAnimatedType::preserveAspectRatio);
-}
-
-void SVGAnimatedPreserveAspectRatioAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedPreserveAspectRatio>(animatedTypes);
-}
-
-void SVGAnimatedPreserveAspectRatioAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedPreserveAspectRatio>(animatedTypes);
-}
-
-void SVGAnimatedPreserveAspectRatioAnimator::addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*)
-{
- ASSERT_NOT_REACHED();
-}
-
-void SVGAnimatedPreserveAspectRatioAnimator::calculateAnimatedValue(float percentage, unsigned, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType*, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- const SVGPreserveAspectRatio& fromPreserveAspectRatio = m_animationElement->animationMode() == ToAnimation ? animated->preserveAspectRatio() : from->preserveAspectRatio();
- const SVGPreserveAspectRatio& toPreserveAspectRatio = to->preserveAspectRatio();
- SVGPreserveAspectRatio& animatedPreserveAspectRatio = animated->preserveAspectRatio();
-
- m_animationElement->animateDiscreteType<SVGPreserveAspectRatio>(percentage, fromPreserveAspectRatio, toPreserveAspectRatio, animatedPreserveAspectRatio);
-}
-
-float SVGAnimatedPreserveAspectRatioAnimator::calculateDistance(const String&, const String&)
-{
- // No paced animations for SVGPreserveAspectRatio.
- return -1;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.h
index d08e6988261..fd458b741a1 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.h
@@ -1,59 +1,55 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedPreserveAspectRatio_h
#define SVGAnimatedPreserveAspectRatio_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/SVGPreserveAspectRatio.h"
-#include "core/svg/properties/SVGAnimatedPropertyTearOff.h"
+#include "core/svg/SVGPreserveAspectRatioTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedPropertyTearOff<SVGPreserveAspectRatio> SVGAnimatedPreserveAspectRatio;
-
-// Helper macros to declare/define a SVGAnimatedPreserveAspectRatio object
-#define DECLARE_ANIMATED_PRESERVEASPECTRATIO(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedPreserveAspectRatio, SVGPreserveAspectRatio, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_PRESERVEASPECTRATIO(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedPreserveAspectRatio, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedPreserveAspectRatio, SVGPreserveAspectRatio)
-
-class SVGAnimationElement;
-
-class SVGAnimatedPreserveAspectRatioAnimator : public SVGAnimatedTypeAnimator {
+class SVGAnimatedPreserveAspectRatio : public SVGAnimatedProperty<SVGPreserveAspectRatio> {
public:
- SVGAnimatedPreserveAspectRatioAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedPreserveAspectRatioAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ static PassRefPtr<SVGAnimatedPreserveAspectRatio> create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGPreserveAspectRatio> initialValue)
+ {
+ return adoptRef(new SVGAnimatedPreserveAspectRatio(contextElement, attributeName, initialValue));
+ }
+
+protected:
+ SVGAnimatedPreserveAspectRatio(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGPreserveAspectRatio> initialValue)
+ : SVGAnimatedProperty<SVGPreserveAspectRatio>(contextElement, attributeName, initialValue)
+ {
+ }
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedPreserveAspectRatio_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl
index b2e6c7f89a3..dbcb42def94 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedPreserveAspectRatio {
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedPreserveAspectRatio {
readonly attribute SVGPreserveAspectRatio baseVal;
readonly attribute SVGPreserveAspectRatio animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.cpp
deleted file mode 100644
index be2b0e1b7b6..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedRect.h"
-
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGParserUtilities.h"
-
-namespace WebCore {
-
-SVGAnimatedRectAnimator::SVGAnimatedRectAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedRect, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedRectAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createRect(new SVGRect);
- parseRect(string, animatedType->rect());
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedRectAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createRect(constructFromBaseValue<SVGAnimatedRect>(animatedTypes));
-}
-
-void SVGAnimatedRectAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedRect>(animatedTypes);
-}
-
-void SVGAnimatedRectAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedRect>(animatedTypes, type, &SVGAnimatedType::rect);
-}
-
-void SVGAnimatedRectAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedRect>(animatedTypes);
-}
-
-void SVGAnimatedRectAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedRect>(animatedTypes);
-}
-
-void SVGAnimatedRectAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedRect);
- ASSERT(from->type() == to->type());
-
- to->rect() += from->rect();
-}
-
-void SVGAnimatedRectAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- const SVGRect& fromRect = m_animationElement->animationMode() == ToAnimation ? animated->rect() : from->rect();
- const SVGRect& toRect = to->rect();
- const SVGRect& toAtEndOfDurationRect = toAtEndOfDuration->rect();
- SVGRect& animatedRect = animated->rect();
-
- float animatedX = animatedRect.x();
- float animatedY = animatedRect.y();
- float animatedWidth = animatedRect.width();
- float animatedHeight = animatedRect.height();
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect.x(), toRect.x(), toAtEndOfDurationRect.x(), animatedX);
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect.y(), toRect.y(), toAtEndOfDurationRect.y(), animatedY);
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect.width(), toRect.width(), toAtEndOfDurationRect.width(), animatedWidth);
- m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect.height(), toRect.height(), toAtEndOfDurationRect.height(), animatedHeight);
-
- animatedRect = SVGRect(animatedX, animatedY, animatedWidth, animatedHeight);
-}
-
-float SVGAnimatedRectAnimator::calculateDistance(const String&, const String&)
-{
- // FIXME: Distance calculation is not possible for SVGRect right now. We need the distance of for every single value.
- return -1;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.h
index ccbaef87eda..182f6c1db95 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.h
@@ -1,60 +1,55 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedRect_h
#define SVGAnimatedRect_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/SVGRect.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
-#include "core/svg/properties/SVGAnimatedPropertyTearOff.h"
+#include "core/svg/SVGRectTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedPropertyTearOff<SVGRect> SVGAnimatedRect;
-
-// Helper macros to declare/define a SVGAnimatedRect object
-#define DECLARE_ANIMATED_RECT(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedRect, SVGRect, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_RECT(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedRect, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedRect, SVGRect)
-
-class SVGAnimationElement;
-
-class SVGAnimatedRectAnimator : public SVGAnimatedTypeAnimator {
+class SVGAnimatedRect : public SVGAnimatedProperty<SVGRect> {
public:
- SVGAnimatedRectAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedRectAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ static PassRefPtr<SVGAnimatedRect> create(SVGElement* contextElement, const QualifiedName& attributeName)
+ {
+ return adoptRef(new SVGAnimatedRect(contextElement, attributeName));
+ }
+
+protected:
+ SVGAnimatedRect(SVGElement* contextElement, const QualifiedName& attributeName)
+ : SVGAnimatedProperty<SVGRect>(contextElement, attributeName, SVGRect::create(SVGRect::InvalidSVGRectTag()))
+ {
+ }
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedRect_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.idl
index 6bce55623b3..33a7123c555 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedRect.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedRect {
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedRect {
readonly attribute SVGRect baseVal;
readonly attribute SVGRect animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.cpp
deleted file mode 100644
index 3e335d61423..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedString.h"
-
-#include "core/svg/SVGAnimateElement.h"
-
-namespace WebCore {
-
-SVGAnimatedStringAnimator::SVGAnimatedStringAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedString, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedStringAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createString(new String);
- animatedType->string() = string;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedStringAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createString(constructFromBaseValue<SVGAnimatedString>(animatedTypes));
-}
-
-void SVGAnimatedStringAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedString>(animatedTypes);
-}
-
-void SVGAnimatedStringAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedString>(animatedTypes, type, &SVGAnimatedType::string);
-}
-
-void SVGAnimatedStringAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedString>(animatedTypes);
-}
-
-void SVGAnimatedStringAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedString>(animatedTypes);
-}
-
-void SVGAnimatedStringAnimator::addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*)
-{
- ASSERT_NOT_REACHED();
-}
-
-static String parseStringFromString(SVGAnimationElement*, const String& string)
-{
- return string;
-}
-
-void SVGAnimatedStringAnimator::calculateAnimatedValue(float percentage, unsigned, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType*, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
- ASSERT(m_contextElement);
-
- String fromString = from->string();
- String toString = to->string();
- String& animatedString = animated->string();
-
- // Apply CSS inheritance rules.
- m_animationElement->adjustForInheritance<String>(parseStringFromString, m_animationElement->fromPropertyValueType(), fromString, m_contextElement);
- m_animationElement->adjustForInheritance<String>(parseStringFromString, m_animationElement->toPropertyValueType(), toString, m_contextElement);
-
- m_animationElement->animateDiscreteType<String>(percentage, fromString, toString, animatedString);
-}
-
-float SVGAnimatedStringAnimator::calculateDistance(const String&, const String&)
-{
- // No paced animations for strings.
- return -1;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.h
index 558d6ca2e3c..008d5bc221d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.h
@@ -1,59 +1,55 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedString_h
#define SVGAnimatedString_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
-#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h"
+#include "core/svg/SVGString.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedStaticPropertyTearOff<String> SVGAnimatedString;
-
-// Helper macros to declare/define a SVGAnimatedString object
-#define DECLARE_ANIMATED_STRING(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedString, String, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_STRING(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedString, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedString, String)
-
-class SVGAnimationElement;
-
-class SVGAnimatedStringAnimator : public SVGAnimatedTypeAnimator {
+class SVGAnimatedString FINAL : public SVGAnimatedProperty<SVGString> {
public:
- SVGAnimatedStringAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedStringAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
+ static PassRefPtr<SVGAnimatedString> create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGString> initialValue)
+ {
+ return adoptRef(new SVGAnimatedString(contextElement, attributeName, initialValue));
+ }
+
+protected:
+ SVGAnimatedString(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGString> initialValue)
+ : SVGAnimatedProperty<SVGString>(contextElement, attributeName, initialValue)
+ {
+ }
};
} // namespace WebCore
-#endif
+#endif // SVGAnimatedString_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.idl
index d1fbf52a247..dec2f0517fc 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedString.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedString {
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedString {
[RaisesException=Setter] attribute DOMString baseVal;
readonly attribute DOMString animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp
deleted file mode 100644
index bc11a030ace..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- * Copyright (C) Research In Motion Limited 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedTransformList.h"
-
-#include "SVGNames.h"
-#include "core/svg/SVGAnimateTransformElement.h"
-#include "core/svg/SVGAnimatedNumber.h"
-#include "core/svg/SVGTransformDistance.h"
-
-namespace WebCore {
-
-SVGAnimatedTransformListAnimator::SVGAnimatedTransformListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
- : SVGAnimatedTypeAnimator(AnimatedTransformList, animationElement, contextElement)
- , m_transformTypeString(SVGTransform::transformTypePrefixForParsing(static_cast<SVGAnimateTransformElement*>(animationElement)->transformType()))
-{
- // Only <animateTransform> uses this animator, as <animate> doesn't allow to animate transform lists directly.
- ASSERT(animationElement->hasTagName(SVGNames::animateTransformTag));
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedTransformListAnimator::constructFromString(const String& string)
-{
- OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createTransformList(new SVGTransformList);
- animatedType->transformList().parse(m_transformTypeString + string + ')');
- ASSERT(animatedType->transformList().size() <= 1);
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedTransformListAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- return SVGAnimatedType::createTransformList(constructFromBaseValue<SVGAnimatedTransformList>(animatedTypes));
-}
-
-void SVGAnimatedTransformListAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- stopAnimValAnimationForType<SVGAnimatedTransformList>(animatedTypes);
-}
-
-void SVGAnimatedTransformListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
- resetFromBaseValue<SVGAnimatedTransformList>(animatedTypes, type, &SVGAnimatedType::transformList);
-}
-
-void SVGAnimatedTransformListAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValWillChangeForType<SVGAnimatedTransformList>(animatedTypes);
-}
-
-void SVGAnimatedTransformListAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
- animValDidChangeForType<SVGAnimatedTransformList>(animatedTypes);
-}
-
-void SVGAnimatedTransformListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
- ASSERT(from->type() == AnimatedTransformList);
- ASSERT(from->type() == to->type());
-
- const SVGTransformList& fromTransformList = from->transformList();
- SVGTransformList& toTransformList = to->transformList();
- unsigned fromTransformListSize = fromTransformList.size();
- if (!fromTransformListSize || fromTransformListSize != toTransformList.size())
- return;
-
- ASSERT(fromTransformListSize == 1);
- const SVGTransform& fromTransform = fromTransformList[0];
- SVGTransform& toTransform = toTransformList[0];
-
- ASSERT(fromTransform.type() == toTransform.type());
- toTransform = SVGTransformDistance::addSVGTransforms(fromTransform, toTransform);
-}
-
-void SVGAnimatedTransformListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
- ASSERT(m_animationElement);
-
- // Spec: To animations provide specific functionality to get a smooth change from the underlying value to the
- // ‘to’ attribute value, which conflicts mathematically with the requirement for additive transform animations
- // to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to animations for ‘animateTransform’ is undefined.
- // FIXME: This is not taken into account yet.
- const SVGTransformList& fromTransformList = m_animationElement->animationMode() == ToAnimation ? animated->transformList() : from->transformList();
- const SVGTransformList& toTransformList = to->transformList();
- const SVGTransformList& toAtEndOfDurationTransformList = toAtEndOfDuration->transformList();
- SVGTransformList& animatedTransformList = animated->transformList();
-
- // Pass false to 'resizeAnimatedListIfNeeded' here, as the special post-multiplication behavior of <animateTransform> needs to be respected below.
- if (!m_animationElement->adjustFromToListValues<SVGTransformList>(fromTransformList, toTransformList, animatedTransformList, percentage, false))
- return;
-
- // Never resize the animatedTransformList to the toTransformList size, instead either clear the list or append to it.
- if (!animatedTransformList.isEmpty() && !m_animationElement->isAdditive())
- animatedTransformList.clear();
-
- unsigned fromTransformListSize = fromTransformList.size();
- const SVGTransform& toTransform = toTransformList[0];
- const SVGTransform effectiveFrom = fromTransformListSize ? fromTransformList[0] : SVGTransform(toTransform.type(), SVGTransform::ConstructZeroTransform);
- SVGTransform currentTransform = SVGTransformDistance(effectiveFrom, toTransform).scaledDistance(percentage).addToSVGTransform(effectiveFrom);
- if (m_animationElement->isAccumulated() && repeatCount) {
- const SVGTransform effectiveToAtEnd = toAtEndOfDurationTransformList.size() ? toAtEndOfDurationTransformList[0] : SVGTransform(toTransform.type(), SVGTransform::ConstructZeroTransform);
- animatedTransformList.append(SVGTransformDistance::addSVGTransforms(currentTransform, effectiveToAtEnd, repeatCount));
- } else
- animatedTransformList.append(currentTransform);
-}
-
-float SVGAnimatedTransformListAnimator::calculateDistance(const String& fromString, const String& toString)
-{
- ASSERT(m_animationElement);
-
- // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example)
- // is paced separately. To implement this we need to treat each component as individual animation everywhere.
- OwnPtr<SVGAnimatedType> from = constructFromString(fromString);
- OwnPtr<SVGAnimatedType> to = constructFromString(toString);
-
- SVGTransformList& fromTransformList = from->transformList();
- SVGTransformList& toTransformList = to->transformList();
- unsigned itemsCount = fromTransformList.size();
- if (!itemsCount || itemsCount != toTransformList.size())
- return -1;
-
- ASSERT(itemsCount == 1);
- if (fromTransformList[0].type() != toTransformList[0].type())
- return -1;
-
- // Spec: http://www.w3.org/TR/SVG/animate.html#complexDistances
- // Paced animations assume a notion of distance between the various animation values defined by the ‘to’, ‘from’, ‘by’ and ‘values’ attributes.
- // Distance is defined only for scalar types (such as <length>), colors and the subset of transformation types that are supported by ‘animateTransform’.
- return SVGTransformDistance(fromTransformList[0], toTransformList[0]).distance();
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.h
index 58e09fd068b..fee7137768b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.h
@@ -1,60 +1,42 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedTransformList_h
#define SVGAnimatedTransformList_h
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h"
+#include "core/svg/SVGTransformListTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
namespace WebCore {
-typedef SVGAnimatedTransformListPropertyTearOff SVGAnimatedTransformList;
-
-// Helper macros to declare/define a SVGAnimatedTransformList object
-#define DECLARE_ANIMATED_TRANSFORM_LIST(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedTransformList, SVGTransformList, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_TRANSFORM_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedTransformList, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedTransformList, SVGTransformList)
-
-class SVGAnimationElement;
-
-class SVGAnimatedTransformListAnimator : public SVGAnimatedTypeAnimator {
-public:
- SVGAnimatedTransformListAnimator(SVGAnimationElement*, SVGElement*);
- virtual ~SVGAnimatedTransformListAnimator() { }
-
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&);
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&);
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*);
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&);
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&);
-
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*);
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*);
- virtual float calculateDistance(const String& fromString, const String& toString);
-
-private:
- const String& m_transformTypeString;
-};
+typedef SVGAnimatedProperty<SVGTransformList> SVGAnimatedTransformList;
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.idl
index 718a2a66631..7a56c323c29 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGAnimatedTransformList {
+[
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedTransformList {
readonly attribute SVGTransformList baseVal;
readonly attribute SVGTransformList animVal;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp
deleted file mode 100644
index 486773f4306..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/SVGAnimatedType.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/svg/SVGParserUtilities.h"
-#include "core/svg/SVGPathByteStream.h"
-
-namespace WebCore {
-
-SVGAnimatedType::SVGAnimatedType(AnimatedPropertyType type)
- : m_type(type)
-{
-}
-
-SVGAnimatedType::~SVGAnimatedType()
-{
- switch (m_type) {
- case AnimatedAngle:
- delete m_data.angleAndEnumeration;
- break;
- case AnimatedBoolean:
- delete m_data.boolean;
- break;
- case AnimatedColor:
- delete m_data.color;
- break;
- case AnimatedEnumeration:
- delete m_data.enumeration;
- break;
- case AnimatedInteger:
- delete m_data.integer;
- break;
- case AnimatedIntegerOptionalInteger:
- delete m_data.integerOptionalInteger;
- break;
- case AnimatedLength:
- delete m_data.length;
- break;
- case AnimatedLengthList:
- delete m_data.lengthList;
- break;
- case AnimatedNumber:
- delete m_data.number;
- break;
- case AnimatedNumberList:
- delete m_data.numberList;
- break;
- case AnimatedNumberOptionalNumber:
- delete m_data.numberOptionalNumber;
- break;
- case AnimatedPath:
- delete m_data.path;
- break;
- case AnimatedPoints:
- delete m_data.pointList;
- break;
- case AnimatedPreserveAspectRatio:
- delete m_data.preserveAspectRatio;
- break;
- case AnimatedRect:
- delete m_data.rect;
- break;
- case AnimatedString:
- delete m_data.string;
- break;
- case AnimatedTransformList:
- delete m_data.transformList;
- break;
- case AnimatedUnknown:
- ASSERT_NOT_REACHED();
- break;
- }
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createAngleAndEnumeration(std::pair<SVGAngle, unsigned>* angleAndEnumeration)
-{
- ASSERT(angleAndEnumeration);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedAngle));
- animatedType->m_data.angleAndEnumeration = angleAndEnumeration;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createBoolean(bool* boolean)
-{
- ASSERT(boolean);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedBoolean));
- animatedType->m_data.boolean = boolean;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createColor(Color* color)
-{
- ASSERT(color);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedColor));
- animatedType->m_data.color = color;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createEnumeration(unsigned* enumeration)
-{
- ASSERT(enumeration);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedEnumeration));
- animatedType->m_data.enumeration = enumeration;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createInteger(int* integer)
-{
- ASSERT(integer);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedInteger));
- animatedType->m_data.integer = integer;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createIntegerOptionalInteger(pair<int, int>* integerOptionalInteger)
-{
- ASSERT(integerOptionalInteger);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedIntegerOptionalInteger));
- animatedType->m_data.integerOptionalInteger = integerOptionalInteger;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createLength(SVGLength* length)
-{
- ASSERT(length);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedLength));
- animatedType->m_data.length = length;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createLengthList(SVGLengthList* lengthList)
-{
- ASSERT(lengthList);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedLengthList));
- animatedType->m_data.lengthList = lengthList;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumber(float* number)
-{
- ASSERT(number);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumber));
- animatedType->m_data.number = number;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumberList(SVGNumberList* numberList)
-{
- ASSERT(numberList);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumberList));
- animatedType->m_data.numberList = numberList;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNumberOptionalNumber(pair<float, float>* numberOptionalNumber)
-{
- ASSERT(numberOptionalNumber);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedNumberOptionalNumber));
- animatedType->m_data.numberOptionalNumber = numberOptionalNumber;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPath(PassOwnPtr<SVGPathByteStream> path)
-{
- ASSERT(path);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPath));
- animatedType->m_data.path = path.leakPtr();
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPointList(SVGPointList* pointList)
-{
- ASSERT(pointList);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPoints));
- animatedType->m_data.pointList = pointList;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPreserveAspectRatio(SVGPreserveAspectRatio* preserveAspectRatio)
-{
- ASSERT(preserveAspectRatio);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPreserveAspectRatio));
- animatedType->m_data.preserveAspectRatio = preserveAspectRatio;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createRect(SVGRect* rect)
-{
- ASSERT(rect);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedRect));
- animatedType->m_data.rect = rect;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createString(String* string)
-{
- ASSERT(string);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedString));
- animatedType->m_data.string = string;
- return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createTransformList(SVGTransformList* transformList)
-{
- ASSERT(transformList);
- OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedTransformList));
- animatedType->m_data.transformList = transformList;
- return animatedType.release();
-}
-
-String SVGAnimatedType::valueAsString()
-{
- switch (m_type) {
- case AnimatedColor:
- ASSERT(m_data.color);
- return m_data.color->serialized();
- case AnimatedLength:
- ASSERT(m_data.length);
- return m_data.length->valueAsString();
- case AnimatedLengthList:
- ASSERT(m_data.lengthList);
- return m_data.lengthList->valueAsString();
- case AnimatedNumber:
- ASSERT(m_data.number);
- return String::number(*m_data.number);
- case AnimatedRect:
- ASSERT(m_data.rect);
- return String::number(m_data.rect->x()) + ' ' + String::number(m_data.rect->y()) + ' '
- + String::number(m_data.rect->width()) + ' ' + String::number(m_data.rect->height());
- case AnimatedString:
- ASSERT(m_data.string);
- return *m_data.string;
-
- // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need valueAsString() support.
- case AnimatedAngle:
- case AnimatedBoolean:
- case AnimatedEnumeration:
- case AnimatedInteger:
- case AnimatedIntegerOptionalInteger:
- case AnimatedNumberList:
- case AnimatedNumberOptionalNumber:
- case AnimatedPath:
- case AnimatedPoints:
- case AnimatedPreserveAspectRatio:
- case AnimatedTransformList:
- case AnimatedUnknown:
- // Only SVG DOM animations use these property types - that means valueAsString() is never used for those.
- ASSERT_NOT_REACHED();
- break;
- }
- ASSERT_NOT_REACHED();
- return String();
-}
-
-bool SVGAnimatedType::setValueAsString(const QualifiedName& attrName, const String& value)
-{
- switch (m_type) {
- case AnimatedColor:
- ASSERT(m_data.color);
- *m_data.color = value.isEmpty() ? Color() : SVGColor::colorFromRGBColorString(value);
- break;
- case AnimatedLength: {
- ASSERT(m_data.length);
- TrackExceptionState exceptionState;
- m_data.length->setValueAsString(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName), exceptionState);
- return !exceptionState.hadException();
- }
- case AnimatedLengthList:
- ASSERT(m_data.lengthList);
- m_data.lengthList->parse(value, SVGLength::lengthModeForAnimatedLengthAttribute(attrName));
- break;
- case AnimatedNumber:
- ASSERT(m_data.number);
- parseNumberFromString(value, *m_data.number);
- break;
- case AnimatedRect:
- ASSERT(m_data.rect);
- parseRect(value, *m_data.rect);
- break;
- case AnimatedString:
- ASSERT(m_data.string);
- *m_data.string = value;
- break;
-
- // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need setValueAsString() support.
- case AnimatedAngle:
- case AnimatedBoolean:
- case AnimatedEnumeration:
- case AnimatedInteger:
- case AnimatedIntegerOptionalInteger:
- case AnimatedNumberList:
- case AnimatedNumberOptionalNumber:
- case AnimatedPath:
- case AnimatedPoints:
- case AnimatedPreserveAspectRatio:
- case AnimatedTransformList:
- case AnimatedUnknown:
- // Only SVG DOM animations use these property types - that means setValueAsString() is never used for those.
- ASSERT_NOT_REACHED();
- break;
- }
- return true;
-}
-
-bool SVGAnimatedType::supportsAnimVal(AnimatedPropertyType type)
-{
- // AnimatedColor is only used for CSS property animations.
- return type != AnimatedUnknown && type != AnimatedColor;
-}
-
-} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedType.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedType.h
deleted file mode 100644
index 7c6aa01350a..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedType.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedType_h
-#define SVGAnimatedType_h
-
-#include "core/svg/SVGAngle.h"
-#include "core/svg/SVGColor.h"
-#include "core/svg/SVGLength.h"
-#include "core/svg/SVGLengthList.h"
-#include "core/svg/SVGNumberList.h"
-#include "core/svg/SVGPointList.h"
-#include "core/svg/SVGPreserveAspectRatio.h"
-#include "core/svg/SVGRect.h"
-#include "core/svg/SVGTransformList.h"
-#include "core/svg/properties/SVGPropertyInfo.h"
-
-namespace WebCore {
-
-class SVGPathByteStream;
-
-class SVGAnimatedType FINAL {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- ~SVGAnimatedType();
-
- static PassOwnPtr<SVGAnimatedType> createAngleAndEnumeration(std::pair<SVGAngle, unsigned>*);
- static PassOwnPtr<SVGAnimatedType> createBoolean(bool*);
- static PassOwnPtr<SVGAnimatedType> createColor(Color*);
- static PassOwnPtr<SVGAnimatedType> createEnumeration(unsigned*);
- static PassOwnPtr<SVGAnimatedType> createInteger(int*);
- static PassOwnPtr<SVGAnimatedType> createIntegerOptionalInteger(std::pair<int, int>*);
- static PassOwnPtr<SVGAnimatedType> createLength(SVGLength*);
- static PassOwnPtr<SVGAnimatedType> createLengthList(SVGLengthList*);
- static PassOwnPtr<SVGAnimatedType> createNumber(float*);
- static PassOwnPtr<SVGAnimatedType> createNumberList(SVGNumberList*);
- static PassOwnPtr<SVGAnimatedType> createNumberOptionalNumber(std::pair<float, float>*);
- static PassOwnPtr<SVGAnimatedType> createPath(PassOwnPtr<SVGPathByteStream>);
- static PassOwnPtr<SVGAnimatedType> createPointList(SVGPointList*);
- static PassOwnPtr<SVGAnimatedType> createPreserveAspectRatio(SVGPreserveAspectRatio*);
- static PassOwnPtr<SVGAnimatedType> createRect(SVGRect*);
- static PassOwnPtr<SVGAnimatedType> createString(String*);
- static PassOwnPtr<SVGAnimatedType> createTransformList(SVGTransformList*);
- static bool supportsAnimVal(AnimatedPropertyType);
-
- AnimatedPropertyType type() const { return m_type; }
-
- // Non-mutable accessors.
- const std::pair<SVGAngle, unsigned>& angleAndEnumeration() const
- {
- ASSERT(m_type == AnimatedAngle);
- return *m_data.angleAndEnumeration;
- }
-
- const bool& boolean() const
- {
- ASSERT(m_type == AnimatedBoolean);
- return *m_data.boolean;
- }
-
- const Color& color() const
- {
- ASSERT(m_type == AnimatedColor);
- return *m_data.color;
- }
-
- const unsigned& enumeration() const
- {
- ASSERT(m_type == AnimatedEnumeration);
- return *m_data.enumeration;
- }
-
- const int& integer() const
- {
- ASSERT(m_type == AnimatedInteger);
- return *m_data.integer;
- }
-
- const pair<int, int>& integerOptionalInteger() const
- {
- ASSERT(m_type == AnimatedIntegerOptionalInteger);
- return *m_data.integerOptionalInteger;
- }
-
- const SVGLength& length() const
- {
- ASSERT(m_type == AnimatedLength);
- return *m_data.length;
- }
-
- const SVGLengthList& lengthList() const
- {
- ASSERT(m_type == AnimatedLengthList);
- return *m_data.lengthList;
- }
-
- const float& number() const
- {
- ASSERT(m_type == AnimatedNumber);
- return *m_data.number;
- }
-
- const SVGNumberList& numberList() const
- {
- ASSERT(m_type == AnimatedNumberList);
- return *m_data.numberList;
- }
-
- const pair<float, float>& numberOptionalNumber() const
- {
- ASSERT(m_type == AnimatedNumberOptionalNumber);
- return *m_data.numberOptionalNumber;
- }
-
- const SVGPathByteStream* path() const
- {
- ASSERT(m_type == AnimatedPath);
- return m_data.path;
- }
-
- const SVGPointList& pointList() const
- {
- ASSERT(m_type == AnimatedPoints);
- return *m_data.pointList;
- }
-
- const SVGPreserveAspectRatio& preserveAspectRatio() const
- {
- ASSERT(m_type == AnimatedPreserveAspectRatio);
- return *m_data.preserveAspectRatio;
- }
-
- const SVGRect& rect() const
- {
- ASSERT(m_type == AnimatedRect);
- return *m_data.rect;
- }
-
- const String& string() const
- {
- ASSERT(m_type == AnimatedString);
- return *m_data.string;
- }
-
- const SVGTransformList& transformList() const
- {
- ASSERT(m_type == AnimatedTransformList);
- return *m_data.transformList;
- }
-
- // Mutable accessors.
- std::pair<SVGAngle, unsigned>& angleAndEnumeration()
- {
- ASSERT(m_type == AnimatedAngle);
- return *m_data.angleAndEnumeration;
- }
-
- bool& boolean()
- {
- ASSERT(m_type == AnimatedBoolean);
- return *m_data.boolean;
- }
-
- Color& color()
- {
- ASSERT(m_type == AnimatedColor);
- return *m_data.color;
- }
-
- unsigned& enumeration()
- {
- ASSERT(m_type == AnimatedEnumeration);
- return *m_data.enumeration;
- }
-
- int& integer()
- {
- ASSERT(m_type == AnimatedInteger);
- return *m_data.integer;
- }
-
- pair<int, int>& integerOptionalInteger()
- {
- ASSERT(m_type == AnimatedIntegerOptionalInteger);
- return *m_data.integerOptionalInteger;
- }
-
- SVGLength& length()
- {
- ASSERT(m_type == AnimatedLength);
- return *m_data.length;
- }
-
- SVGLengthList& lengthList()
- {
- ASSERT(m_type == AnimatedLengthList);
- return *m_data.lengthList;
- }
-
- float& number()
- {
- ASSERT(m_type == AnimatedNumber);
- return *m_data.number;
- }
-
- SVGNumberList& numberList()
- {
- ASSERT(m_type == AnimatedNumberList);
- return *m_data.numberList;
- }
-
- pair<float, float>& numberOptionalNumber()
- {
- ASSERT(m_type == AnimatedNumberOptionalNumber);
- return *m_data.numberOptionalNumber;
- }
-
- SVGPathByteStream* path()
- {
- ASSERT(m_type == AnimatedPath);
- return m_data.path;
- }
-
- SVGPointList& pointList()
- {
- ASSERT(m_type == AnimatedPoints);
- return *m_data.pointList;
- }
-
- SVGPreserveAspectRatio& preserveAspectRatio()
- {
- ASSERT(m_type == AnimatedPreserveAspectRatio);
- return *m_data.preserveAspectRatio;
- }
-
- SVGRect& rect()
- {
- ASSERT(m_type == AnimatedRect);
- return *m_data.rect;
- }
-
- String& string()
- {
- ASSERT(m_type == AnimatedString);
- return *m_data.string;
- }
-
- SVGTransformList& transformList()
- {
- ASSERT(m_type == AnimatedTransformList);
- return *m_data.transformList;
- }
-
- String valueAsString();
- bool setValueAsString(const QualifiedName&, const String&);
-
-private:
- SVGAnimatedType(AnimatedPropertyType);
-
- AnimatedPropertyType m_type;
-
- union DataUnion {
- DataUnion()
- : length(0)
- {
- }
-
- std::pair<SVGAngle, unsigned>* angleAndEnumeration;
- bool* boolean;
- Color* color;
- unsigned* enumeration;
- int* integer;
- std::pair<int, int>* integerOptionalInteger;
- SVGLength* length;
- SVGLengthList* lengthList;
- float* number;
- SVGNumberList* numberList;
- std::pair<float, float>* numberOptionalNumber;
- SVGPathByteStream* path;
- SVGPreserveAspectRatio* preserveAspectRatio;
- SVGPointList* pointList;
- SVGRect* rect;
- String* string;
- SVGTransformList* transformList;
- } m_data;
-};
-
-} // namespace WebCore
-
-#endif // SVGAnimatedType_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp
index 290b538afe4..c981f53617e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp
@@ -21,88 +21,242 @@
#include "config.h"
#include "core/svg/SVGAnimatedTypeAnimator.h"
+#include "core/svg/SVGAnimateTransformElement.h"
+#include "core/svg/SVGAnimatedColor.h"
+#include "core/svg/SVGAnimationElement.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/properties/SVGAttributeToPropertyMap.h"
+#include "core/svg/SVGLength.h"
+#include "core/svg/SVGLengthList.h"
+#include "core/svg/SVGNumber.h"
+#include "core/svg/SVGPaint.h"
+#include "core/svg/SVGPointList.h"
+#include "core/svg/SVGString.h"
+#include "core/svg/SVGTransformList.h"
namespace WebCore {
-SVGElementAnimatedProperties::SVGElementAnimatedProperties()
- : element(0)
-{ }
-
-SVGElementAnimatedProperties::SVGElementAnimatedProperties(SVGElement* element, Vector<RefPtr<SVGAnimatedProperty> >& properties)
- : element(element)
- , properties(properties)
-{ }
-
-SVGAnimatedTypeAnimator::SVGAnimatedTypeAnimator(AnimatedPropertyType type, SVGAnimationElement* animationElement, SVGElement* contextElement)
- : m_type(type)
- , m_animationElement(animationElement)
+SVGAnimatedTypeAnimator::SVGAnimatedTypeAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
+ : m_animationElement(animationElement)
, m_contextElement(contextElement)
{
+ ASSERT(m_animationElement);
+ ASSERT(m_contextElement);
+
+ const QualifiedName& attributeName = m_animationElement->attributeName();
+ m_animatedProperty = m_contextElement->propertyFromAttribute(attributeName);
+ m_type = m_animatedProperty ? m_animatedProperty->type()
+ : SVGElement::animatedPropertyTypeForCSSAttribute(attributeName);
+
+ // Only <animateTransform> is allowed to animate AnimatedTransformList.
+ // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
+ if (m_type == AnimatedTransformList && !isSVGAnimateTransformElement(*animationElement))
+ m_type = AnimatedUnknown;
+
+ ASSERT(m_type != AnimatedPoint
+ && m_type != AnimatedStringList
+ && m_type != AnimatedTransform);
}
SVGAnimatedTypeAnimator::~SVGAnimatedTypeAnimator()
{
}
-void SVGAnimatedTypeAnimator::calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString)
+PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::createPropertyForAnimation(const String& value)
+{
+ if (isAnimatingSVGDom()) {
+ // SVG DOM animVal animation code-path.
+
+ if (m_type == AnimatedTransformList) {
+ // TransformList must be animated via <animateTransform>,
+ // and its {from,by,to} attribute values needs to be parsed w.r.t. its "type" attribute.
+ // Spec: http://www.w3.org/TR/SVG/single-page.html#animate-AnimateTransformElement
+ ASSERT(m_animationElement);
+ SVGTransformType transformType = toSVGAnimateTransformElement(m_animationElement)->transformType();
+ return SVGTransformList::create(transformType, value);
+ }
+
+ ASSERT(m_animatedProperty);
+ return m_animatedProperty->currentValueBase()->cloneForAnimation(value);
+ }
+
+ ASSERT(isAnimatingCSSProperty());
+
+ // CSS properties animation code-path.
+ // Create a basic instance of the corresponding SVG property.
+ // The instance will not have full context info. (e.g. SVGLengthMode)
+
+ switch (m_type) {
+ case AnimatedColor:
+ return SVGColorProperty::create(value.isEmpty() ? StyleColor::currentColor() : SVGPaint::colorFromRGBColorString(value));
+ case AnimatedNumber: {
+ RefPtr<SVGNumber> property = SVGNumber::create();
+ property->setValueAsString(value, IGNORE_EXCEPTION);
+ return property.release();
+ }
+ case AnimatedLength: {
+ RefPtr<SVGLength> property = SVGLength::create(LengthModeOther);
+ property->setValueAsString(value, IGNORE_EXCEPTION);
+ return property.release();
+ }
+ case AnimatedLengthList: {
+ RefPtr<SVGLengthList> property = SVGLengthList::create(LengthModeOther);
+ property->setValueAsString(value, IGNORE_EXCEPTION);
+ return property.release();
+ }
+ case AnimatedString: {
+ RefPtr<SVGString> property = SVGString::create();
+ property->setValueAsString(value, IGNORE_EXCEPTION);
+ return property.release();
+ }
+
+ // These types don't appear in the table in SVGElement::animatedPropertyTypeForCSSAttribute() and thus don't need support.
+ case AnimatedAngle:
+ case AnimatedBoolean:
+ case AnimatedEnumeration:
+ case AnimatedInteger:
+ case AnimatedIntegerOptionalInteger:
+ case AnimatedNumberList:
+ case AnimatedNumberOptionalNumber:
+ case AnimatedPath:
+ case AnimatedPoint:
+ case AnimatedPoints:
+ case AnimatedPreserveAspectRatio:
+ case AnimatedRect:
+ case AnimatedStringList:
+ case AnimatedTransform:
+ case AnimatedTransformList:
+ ASSERT_NOT_REACHED();
+
+ case AnimatedUnknown:
+ ASSERT_NOT_REACHED();
+ };
+
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::constructFromString(const String& value)
+{
+ return createPropertyForAnimation(value);
+}
+
+void SVGAnimatedTypeAnimator::calculateFromAndToValues(RefPtr<SVGPropertyBase>& from, RefPtr<SVGPropertyBase>& to, const String& fromString, const String& toString)
{
from = constructFromString(fromString);
to = constructFromString(toString);
}
-void SVGAnimatedTypeAnimator::calculateFromAndByValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& byString)
+void SVGAnimatedTypeAnimator::calculateFromAndByValues(RefPtr<SVGPropertyBase>& from, RefPtr<SVGPropertyBase>& to, const String& fromString, const String& byString)
{
from = constructFromString(fromString);
to = constructFromString(byString);
- addAnimatedTypes(from.get(), to.get());
+ // FIXME(oilpan): Below .get() should be removed after transition types are gone.
+ to->add(from.get(), m_contextElement);
+}
+
+namespace {
+
+void setAnimatedValueOnAllTargetProperties(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >& list, const QualifiedName& attributeName, PassRefPtr<SVGPropertyBase> passValue)
+{
+ RefPtr<SVGPropertyBase> value = passValue;
+
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator it = list.begin();
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator itEnd = list.end();
+ for (; it != itEnd; ++it) {
+ RefPtr<SVGAnimatedPropertyBase> animatedProperty = (*it)->propertyFromAttribute(attributeName);
+ if (animatedProperty)
+ animatedProperty->setAnimatedValue(value);
+ }
}
-SVGElementAnimatedPropertyList SVGAnimatedTypeAnimator::findAnimatedPropertiesForAttributeName(SVGElement* targetElement, const QualifiedName& attributeName)
+}
+
+PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::resetAnimation(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >& list)
{
- ASSERT(targetElement);
+ ASSERT(isAnimatingSVGDom());
+ RefPtr<SVGPropertyBase> animatedValue = m_animatedProperty->createAnimatedValue();
+ ASSERT(animatedValue->type() == m_type);
+ setAnimatedValueOnAllTargetProperties(list, m_animatedProperty->attributeName(), animatedValue);
- SVGElementAnimatedPropertyList propertiesByInstance;
+ return animatedValue.release();
+}
- Vector<RefPtr<SVGAnimatedProperty> > targetProperties;
- targetElement->localAttributeToPropertyMap().animatedPropertiesForAttribute(targetElement, attributeName, targetProperties);
+PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::startAnimValAnimation(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >& list)
+{
+ ASSERT(isAnimatingSVGDom());
+ SVGElement::InstanceUpdateBlocker blocker(m_contextElement);
- if (!SVGAnimatedType::supportsAnimVal(m_type))
- return SVGElementAnimatedPropertyList();
+ return resetAnimation(list);
+}
- SVGElementAnimatedProperties propertiesPair(targetElement, targetProperties);
- propertiesByInstance.append(propertiesPair);
+void SVGAnimatedTypeAnimator::stopAnimValAnimation(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >& list)
+{
+ ASSERT(isAnimatingSVGDom());
+ SVGElement::InstanceUpdateBlocker blocker(m_contextElement);
- const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
- if (!shadowTreeElement)
- continue;
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator it = list.begin();
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::const_iterator itEnd = list.end();
+ for (; it != itEnd; ++it) {
+ RefPtr<SVGAnimatedPropertyBase> animatedProperty = (*it)->propertyFromAttribute(m_animatedProperty->attributeName());
+ if (animatedProperty)
+ animatedProperty->animationEnded();
+ }
+}
- Vector<RefPtr<SVGAnimatedProperty> > instanceProperties;
- targetElement->localAttributeToPropertyMap().animatedPropertiesForAttribute(shadowTreeElement, attributeName, instanceProperties);
+PassRefPtr<SVGPropertyBase> SVGAnimatedTypeAnimator::resetAnimValToBaseVal(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >& list)
+{
+ SVGElement::InstanceUpdateBlocker blocker(m_contextElement);
- SVGElementAnimatedProperties instancePropertiesPair(shadowTreeElement, instanceProperties);
- propertiesByInstance.append(instancePropertiesPair);
+ return resetAnimation(list);
+}
+
+class ParsePropertyFromString {
+public:
+ explicit ParsePropertyFromString(SVGAnimatedTypeAnimator* animator)
+ : m_animator(animator)
+ {
}
-#if !ASSERT_DISABLED
- SVGElementAnimatedPropertyList::const_iterator propertiesEnd = propertiesByInstance.end();
- for (SVGElementAnimatedPropertyList::const_iterator it = propertiesByInstance.begin(); it != propertiesEnd; ++it) {
- size_t propertiesSize = it->properties.size();
- for (size_t i = 0; i < propertiesSize; ++i) {
- RefPtr<SVGAnimatedProperty> property = it->properties[i];
- if (property->animatedPropertyType() != m_type) {
- ASSERT(m_type == AnimatedAngle);
- ASSERT(property->animatedPropertyType() == AnimatedEnumeration);
- }
- }
+ PassRefPtr<SVGPropertyBase> operator()(SVGAnimationElement*, const String& value)
+ {
+ return m_animator->createPropertyForAnimation(value);
}
-#endif
- return propertiesByInstance;
+private:
+ SVGAnimatedTypeAnimator* m_animator;
+};
+
+void SVGAnimatedTypeAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGPropertyBase* from, SVGPropertyBase* to, SVGPropertyBase* toAtEndOfDuration, SVGPropertyBase* animated)
+{
+ ASSERT(m_animationElement);
+ ASSERT(m_contextElement);
+
+ RefPtr<SVGPropertyBase> fromValue = m_animationElement->animationMode() == ToAnimation ? animated : from;
+ RefPtr<SVGPropertyBase> toValue = to;
+ RefPtr<SVGPropertyBase> toAtEndOfDurationValue = toAtEndOfDuration;
+ RefPtr<SVGPropertyBase> animatedValue = animated;
+
+ // Apply CSS inheritance rules.
+ ParsePropertyFromString parsePropertyFromString(this);
+ m_animationElement->adjustForInheritance<RefPtr<SVGPropertyBase>, ParsePropertyFromString>(parsePropertyFromString, m_animationElement->fromPropertyValueType(), fromValue, m_contextElement);
+ m_animationElement->adjustForInheritance<RefPtr<SVGPropertyBase>, ParsePropertyFromString>(parsePropertyFromString, m_animationElement->toPropertyValueType(), toValue, m_contextElement);
+
+ animatedValue->calculateAnimatedValue(m_animationElement, percentage, repeatCount, fromValue, toValue, toAtEndOfDurationValue, m_contextElement);
+}
+
+float SVGAnimatedTypeAnimator::calculateDistance(const String& fromString, const String& toString)
+{
+ ASSERT(m_animationElement);
+ ASSERT(m_contextElement);
+ RefPtr<SVGPropertyBase> fromValue = createPropertyForAnimation(fromString);
+ RefPtr<SVGPropertyBase> toValue = createPropertyForAnimation(toString);
+ return fromValue->calculateDistance(toValue, m_contextElement);
+}
+
+void SVGAnimatedTypeAnimator::trace(Visitor* visitor)
+{
+ visitor->trace(m_animationElement);
+ visitor->trace(m_contextElement);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.h
index fd6c4e36a1d..2c0711739f2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.h
@@ -21,206 +21,60 @@
#ifndef SVGAnimatedTypeAnimator_h
#define SVGAnimatedTypeAnimator_h
-#include "core/svg/SVGAnimatedType.h"
-#include "core/svg/SVGElementInstance.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
+#include "core/svg/properties/SVGPropertyInfo.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
-struct SVGElementAnimatedProperties {
- SVGElementAnimatedProperties();
-
- SVGElementAnimatedProperties(SVGElement*, Vector<RefPtr<SVGAnimatedProperty> >&);
-
- SVGElement* element;
- Vector<RefPtr<SVGAnimatedProperty> > properties;
-};
-typedef Vector<SVGElementAnimatedProperties> SVGElementAnimatedPropertyList;
-
+class SVGAnimatedPropertyBase;
+class SVGPropertyBase;
+class SVGElement;
class SVGAnimationElement;
-class SVGAnimatedTypeAnimator {
- WTF_MAKE_FAST_ALLOCATED;
+class SVGAnimatedTypeAnimator FINAL : public NoBaseWillBeGarbageCollectedFinalized<SVGAnimatedTypeAnimator> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- virtual ~SVGAnimatedTypeAnimator();
- virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&) = 0;
-
- virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) = 0;
- virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) = 0;
- virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) = 0;
- virtual void animValWillChange(const SVGElementAnimatedPropertyList&) = 0;
- virtual void animValDidChange(const SVGElementAnimatedPropertyList&) = 0;
- virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) = 0;
-
- virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) = 0;
- virtual float calculateDistance(const String& fromString, const String& toString) = 0;
-
- void calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString);
- void calculateFromAndByValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& byString);
-
- void setContextElement(SVGElement* contextElement) { m_contextElement = contextElement; }
- AnimatedPropertyType type() const { return m_type; }
-
- SVGElementAnimatedPropertyList findAnimatedPropertiesForAttributeName(SVGElement*, const QualifiedName&);
-
-protected:
- SVGAnimatedTypeAnimator(AnimatedPropertyType, SVGAnimationElement*, SVGElement*);
-
- // Helpers for animators that operate on single types, eg. just one SVGAnimatedInteger.
- template<typename AnimValType>
- typename AnimValType::ContentType* constructFromBaseValue(const SVGElementAnimatedPropertyList& animatedTypes)
+ static PassOwnPtrWillBeRawPtr<SVGAnimatedTypeAnimator> create(SVGAnimationElement* animationElement, SVGElement* targetElement)
{
- ASSERT(animatedTypes[0].properties.size() == 1);
- const typename AnimValType::ContentType& animatedType = castAnimatedPropertyToActualType<AnimValType>(animatedTypes[0].properties[0].get())->currentBaseValue();
-
- typename AnimValType::ContentType* copy = new typename AnimValType::ContentType(animatedType);
- executeAction<AnimValType>(StartAnimationAction, animatedTypes, 0, copy);
- return copy;
+ return adoptPtrWillBeNoop(new SVGAnimatedTypeAnimator(animationElement, targetElement));
}
+ ~SVGAnimatedTypeAnimator();
- template<typename AnimValType>
- void resetFromBaseValue(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type, typename AnimValType::ContentType& (SVGAnimatedType::*getter)())
- {
- ASSERT(animatedTypes[0].properties.size() == 1);
- ASSERT(type);
- ASSERT(type->type() == m_type);
- typename AnimValType::ContentType& animatedTypeValue = (type->*getter)();
- animatedTypeValue = castAnimatedPropertyToActualType<AnimValType>(animatedTypes[0].properties[0].get())->currentBaseValue();
+ PassRefPtr<SVGPropertyBase> constructFromString(const String&);
- executeAction<AnimValType>(StartAnimationAction, animatedTypes, 0, &animatedTypeValue);
- }
+ PassRefPtr<SVGPropertyBase> startAnimValAnimation(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >&);
+ void stopAnimValAnimation(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >&);
+ PassRefPtr<SVGPropertyBase> resetAnimValToBaseVal(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >&);
- template<typename AnimValType>
- void stopAnimValAnimationForType(const SVGElementAnimatedPropertyList& animatedTypes)
- {
- ASSERT(animatedTypes[0].properties.size() == 1);
- executeAction<AnimValType>(StopAnimationAction, animatedTypes, 0);
- }
+ void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGPropertyBase*, SVGPropertyBase*, SVGPropertyBase*, SVGPropertyBase*);
+ float calculateDistance(const String& fromString, const String& toString);
- template<typename AnimValType>
- void animValDidChangeForType(const SVGElementAnimatedPropertyList& animatedTypes)
- {
- ASSERT(animatedTypes[0].properties.size() == 1);
- executeAction<AnimValType>(AnimValDidChangeAction, animatedTypes, 0);
- }
-
- template<typename AnimValType>
- void animValWillChangeForType(const SVGElementAnimatedPropertyList& animatedTypes)
- {
- ASSERT(animatedTypes[0].properties.size() == 1);
- executeAction<AnimValType>(AnimValWillChangeAction, animatedTypes, 0);
- }
+ void calculateFromAndToValues(RefPtr<SVGPropertyBase>& from, RefPtr<SVGPropertyBase>& to, const String& fromString, const String& toString);
+ void calculateFromAndByValues(RefPtr<SVGPropertyBase>& from, RefPtr<SVGPropertyBase>& to, const String& fromString, const String& byString);
- // Helpers for animators that operate on pair types, eg. a pair of SVGAnimatedIntegers.
- template<typename AnimValType1, typename AnimValType2>
- pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>* constructFromBaseValues(const SVGElementAnimatedPropertyList& animatedTypes)
- {
- ASSERT(animatedTypes[0].properties.size() == 2);
- const typename AnimValType1::ContentType& firstType = castAnimatedPropertyToActualType<AnimValType1>(animatedTypes[0].properties[0].get())->currentBaseValue();
- const typename AnimValType2::ContentType& secondType = castAnimatedPropertyToActualType<AnimValType2>(animatedTypes[0].properties[1].get())->currentBaseValue();
-
- pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>* copy = new pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>(firstType, secondType);
- executeAction<AnimValType1>(StartAnimationAction, animatedTypes, 0, &copy->first);
- executeAction<AnimValType2>(StartAnimationAction, animatedTypes, 1, &copy->second);
- return copy;
- }
-
- template<typename AnimValType1, typename AnimValType2>
- void resetFromBaseValues(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type, pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& (SVGAnimatedType::*getter)())
- {
- ASSERT(animatedTypes[0].properties.size() == 2);
- ASSERT(type);
- ASSERT(type->type() == m_type);
-
- pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& animatedTypeValue = (type->*getter)();
- animatedTypeValue.first = castAnimatedPropertyToActualType<AnimValType1>(animatedTypes[0].properties[0].get())->currentBaseValue();
- animatedTypeValue.second = castAnimatedPropertyToActualType<AnimValType2>(animatedTypes[0].properties[1].get())->currentBaseValue();
-
- executeAction<AnimValType1>(StartAnimationAction, animatedTypes, 0, &animatedTypeValue.first);
- executeAction<AnimValType2>(StartAnimationAction, animatedTypes, 1, &animatedTypeValue.second);
- }
+ void setContextElement(SVGElement* contextElement) { m_contextElement = contextElement; }
+ AnimatedPropertyType type() const { return m_type; }
- template<typename AnimValType1, typename AnimValType2>
- void stopAnimValAnimationForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
- {
- ASSERT(animatedTypes[0].properties.size() == 2);
- executeAction<AnimValType1>(StopAnimationAction, animatedTypes, 0);
- executeAction<AnimValType2>(StopAnimationAction, animatedTypes, 1);
- }
+ bool isAnimatingSVGDom() const { return m_animatedProperty; }
+ bool isAnimatingCSSProperty() const { return !m_animatedProperty; }
- template<typename AnimValType1, typename AnimValType2>
- void animValDidChangeForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
- {
- ASSERT(animatedTypes[0].properties.size() == 2);
- executeAction<AnimValType1>(AnimValDidChangeAction, animatedTypes, 0);
- executeAction<AnimValType2>(AnimValDidChangeAction, animatedTypes, 1);
- }
+ void trace(Visitor*);
- template<typename AnimValType1, typename AnimValType2>
- void animValWillChangeForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
- {
- ASSERT(animatedTypes[0].properties.size() == 2);
- executeAction<AnimValType1>(AnimValWillChangeAction, animatedTypes, 0);
- executeAction<AnimValType2>(AnimValWillChangeAction, animatedTypes, 1);
- }
+private:
+ SVGAnimatedTypeAnimator(SVGAnimationElement*, SVGElement*);
- template<typename AnimValType>
- AnimValType* castAnimatedPropertyToActualType(SVGAnimatedProperty* property)
- {
- ASSERT(property);
- ASSERT(property->contextElement());
- // We can't assert property->animatedPropertyType() == m_type, as there's an exception for SVGMarkerElements orient attribute.
- if (property->animatedPropertyType() != m_type) {
- ASSERT(m_type == AnimatedAngle);
- ASSERT(property->animatedPropertyType() == AnimatedEnumeration);
- }
- return static_cast<AnimValType*>(property);
- }
+ friend class ParsePropertyFromString;
+ PassRefPtr<SVGPropertyBase> createPropertyForAnimation(const String&);
+ PassRefPtr<SVGPropertyBase> resetAnimation(const WillBeHeapVector<RawPtrWillBeMember<SVGElement> >&);
AnimatedPropertyType m_type;
- SVGAnimationElement* m_animationElement;
- SVGElement* m_contextElement;
-
-private:
- enum AnimationAction {
- StartAnimationAction,
- StopAnimationAction,
- AnimValWillChangeAction,
- AnimValDidChangeAction
- };
-
- template<typename AnimValType>
- void executeAction(AnimationAction action, const SVGElementAnimatedPropertyList& animatedTypes, unsigned whichProperty, typename AnimValType::ContentType* type = 0)
- {
- SVGElementInstance::InstanceUpdateBlocker blocker(animatedTypes[0].element);
-
- SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end();
- for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) {
- ASSERT_WITH_SECURITY_IMPLICATION(whichProperty < it->properties.size());
- AnimValType* property = castAnimatedPropertyToActualType<AnimValType>(it->properties[whichProperty].get());
-
- switch (action) {
- case StartAnimationAction:
- ASSERT(type);
- if (!property->isAnimating())
- property->animationStarted(type);
- break;
- case StopAnimationAction:
- ASSERT(!type);
- property->animationEnded();
- break;
- case AnimValWillChangeAction:
- ASSERT(!type);
- property->animValWillChange();
- break;
- case AnimValDidChangeAction:
- ASSERT(!type);
- property->animValDidChange();
- break;
- }
- }
- }
+ RawPtrWillBeMember<SVGAnimationElement> m_animationElement;
+ RawPtrWillBeMember<SVGElement> m_contextElement;
+ RefPtr<SVGAnimatedPropertyBase> m_animatedProperty;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
index f17bd5e7bd5..02f4cf766ab 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.cpp
@@ -26,10 +26,10 @@
#include "core/svg/SVGAnimationElement.h"
-#include "CSSPropertyNames.h"
-#include "SVGNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/SVGNames.h"
#include "core/css/CSSComputedStyleDeclaration.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/frame/UseCounter.h"
#include "core/svg/SVGAnimateElement.h"
#include "core/svg/SVGElement.h"
@@ -39,16 +39,9 @@
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_BOOLEAN(SVGAnimationElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGAnimationElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
-END_REGISTER_ANIMATED_PROPERTIES
-
SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document& document)
: SVGSMILElement(tagName, document)
+ , SVGTests(this)
, m_fromPropertyValueType(RegularPropertyValue)
, m_toPropertyValueType(RegularPropertyValue)
, m_animationValid(false)
@@ -57,9 +50,6 @@ SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document&
, m_calcMode(CalcModeLinear)
, m_animationMode(NoAnimation)
{
- ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGAnimationElement();
-
UseCounter::count(document, UseCounter::SVGAnimationElement);
}
@@ -118,7 +108,7 @@ static void parseKeySplinesInternal(const String& string, Vector<UnitBezier>& re
}
float posD = 0;
- if (!parseNumber(ptr, end, posD, false)) {
+ if (!parseNumber(ptr, end, posD, DisallowWhitespace)) {
result.clear();
return;
}
@@ -153,7 +143,6 @@ bool SVGAnimationElement::isSupportedAttribute(const QualifiedName& attrName)
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGTests::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::valuesAttr);
supportedAttributes.add(SVGNames::keyTimesAttr);
supportedAttributes.add(SVGNames::keyPointsAttr);
@@ -192,7 +181,7 @@ void SVGAnimationElement::parseAttribute(const QualifiedName& name, const Atomic
}
if (name == SVGNames::keyPointsAttr) {
- if (hasTagName(SVGNames::animateMotionTag)) {
+ if (isSVGAnimateMotionElement(*this)) {
// This is specified to be an animateMotion attribute only but it is simpler to put it here
// where the other timing calculatations are.
parseKeyTimes(value, m_keyPoints, false);
@@ -222,8 +211,6 @@ void SVGAnimationElement::parseAttribute(const QualifiedName& name, const Atomic
if (SVGTests::parseAttribute(name, value))
return;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
ASSERT_NOT_REACHED();
}
@@ -242,6 +229,8 @@ void SVGAnimationElement::animationAttributeChanged()
{
// Assumptions may not hold after an attribute change.
m_animationValid = false;
+ m_lastValuesAnimationFrom = String();
+ m_lastValuesAnimationTo = String();
setInactive();
}
@@ -267,7 +256,7 @@ void SVGAnimationElement::beginElement()
void SVGAnimationElement::beginElementAt(float offset)
{
- if (std::isnan(offset))
+ if (!std::isfinite(offset))
return;
SMILTime elapsed = this->elapsed();
addBeginTime(elapsed, elapsed + offset, SMILTimeWithOrigin::ScriptOrigin);
@@ -280,7 +269,7 @@ void SVGAnimationElement::endElement()
void SVGAnimationElement::endElementAt(float offset)
{
- if (std::isnan(offset))
+ if (!std::isfinite(offset))
return;
SMILTime elapsed = this->elapsed();
addEndTime(elapsed, elapsed + offset, SMILTimeWithOrigin::ScriptOrigin);
@@ -314,7 +303,7 @@ void SVGAnimationElement::setCalcMode(const AtomicString& calcMode)
else if (calcMode == spline)
setCalcMode(CalcModeSpline);
else
- setCalcMode(hasTagName(SVGNames::animateMotionTag) ? CalcModePaced : CalcModeLinear);
+ setCalcMode(isSVGAnimateMotionElement(*this) ? CalcModePaced : CalcModeLinear);
}
void SVGAnimationElement::setAttributeType(const AtomicString& attributeType)
@@ -345,7 +334,7 @@ String SVGAnimationElement::fromValue() const
return fastGetAttribute(SVGNames::fromAttr);
}
-bool SVGAnimationElement::isAdditive() const
+bool SVGAnimationElement::isAdditive()
{
DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum", AtomicString::ConstructFromLiteral));
const AtomicString& value = fastGetAttribute(SVGNames::additiveAttr);
@@ -424,10 +413,12 @@ unsigned SVGAnimationElement::calculateKeyTimesIndex(float percent) const
{
unsigned index;
unsigned keyTimesCount = m_keyTimes.size();
- // Compare index + 1 to keyTimesCount because the last keyTimes entry is
- // required to be 1, and percent can never exceed 1; i.e., the second last
- // keyTimes entry defines the beginning of the final interval
- for (index = 1; index + 1 < keyTimesCount; ++index) {
+ // For linear and spline animations, the last value must be '1'. In those
+ // cases we don't need to consider the last value, since |percent| is never
+ // greater than one.
+ if (keyTimesCount && calcMode() != CalcModeDiscrete)
+ keyTimesCount--;
+ for (index = 1; index < keyTimesCount; ++index) {
if (m_keyTimes[index] > percent)
break;
}
@@ -456,14 +447,15 @@ float SVGAnimationElement::calculatePercentFromKeyPoints(float percent) const
return m_keyPoints[m_keyPoints.size() - 1];
unsigned index = calculateKeyTimesIndex(percent);
- float fromPercent = m_keyTimes[index];
- float toPercent = m_keyTimes[index + 1];
float fromKeyPoint = m_keyPoints[index];
- float toKeyPoint = m_keyPoints[index + 1];
if (calcMode() == CalcModeDiscrete)
return fromKeyPoint;
+ ASSERT(index + 1 < m_keyTimes.size());
+ float fromPercent = m_keyTimes[index];
+ float toPercent = m_keyTimes[index + 1];
+ float toKeyPoint = m_keyPoints[index + 1];
float keyPointPercent = (percent - fromPercent) / (toPercent - fromPercent);
if (calcMode() == CalcModeSpline) {
@@ -506,14 +498,13 @@ void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float&
}
CalcMode calcMode = this->calcMode();
- if (hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::animateColorTag)) {
- AnimatedPropertyType attributeType = toSVGAnimateElement(this)->determineAnimatedPropertyType(targetElement());
- // Fall back to discrete animations for Strings.
- if (attributeType == AnimatedBoolean
- || attributeType == AnimatedEnumeration
- || attributeType == AnimatedPreserveAspectRatio
- || attributeType == AnimatedString)
+ if (isSVGAnimateElement(*this)) {
+ SVGAnimateElement& animateElement = toSVGAnimateElement(*this);
+ if (!animateElement.animatedPropertyTypeSupportsAddition()) {
+ ASSERT(animateElement.animatedPropertyType() != AnimatedTransformList || isSVGAnimateTransformElement(*this));
+ ASSERT(animateElement.animatedPropertyType() != AnimatedUnknown);
calcMode = CalcModeDiscrete;
+ }
}
if (!m_keyPoints.isEmpty() && calcMode != CalcModePaced)
return currentValuesFromKeyPoints(percent, effectivePercent, from, to);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.h
index 087529fc32d..f1fb91924b7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.h
@@ -26,10 +26,10 @@
#define SVGAnimationElement_h
#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGTests.h"
#include "core/svg/animation/SVGSMILElement.h"
#include "platform/animation/UnitBezier.h"
+#include "wtf/Functional.h"
namespace WebCore {
@@ -43,11 +43,10 @@ enum AnimationMode {
PathAnimation // Used by AnimateMotion.
};
-// If we have 'currentColor' or 'inherit' as animation value, we need to grab
-// the value during the animation since the value can be animated itself.
+// If we have 'inherit' as animation value, we need to grab the value
+// during the animation since the value can be animated itself.
enum AnimatedPropertyValueType {
RegularPropertyValue,
- CurrentColorValue,
InheritValue
};
@@ -58,13 +57,8 @@ enum CalcMode {
CalcModeSpline
};
-class ConditionEventListener;
-class TimeContainer;
-class SVGAnimatedType;
-
class SVGAnimationElement : public SVGSMILElement,
- public SVGTests,
- public SVGExternalResourcesRequired {
+ public SVGTests {
public:
// SVGAnimationElement
float getStartTime() const;
@@ -76,9 +70,13 @@ public:
void endElement();
void endElementAt(float offset);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(begin, beginEvent);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(end, endEvent);
+ DEFINE_MAPPED_ATTRIBUTE_EVENT_LISTENER(repeat, repeatEvent);
+
static bool isTargetAttributeCSSProperty(SVGElement*, const QualifiedName&);
- virtual bool isAdditive() const;
+ virtual bool isAdditive();
bool isAccumulated() const;
AnimationMode animationMode() const { return m_animationMode; }
CalcMode calcMode() const { return m_calcMode; }
@@ -94,44 +92,15 @@ public:
AnimatedPropertyValueType fromPropertyValueType() const { return m_fromPropertyValueType; }
AnimatedPropertyValueType toPropertyValueType() const { return m_toPropertyValueType; }
- template<typename AnimatedType>
- void adjustForInheritance(AnimatedType (*parseTypeFromString)(SVGAnimationElement*, const String&),
- AnimatedPropertyValueType valueType, AnimatedType& animatedType, SVGElement* contextElement)
+ template<typename AnimatedType, typename ParseTypeFromStringType>
+ void adjustForInheritance(ParseTypeFromStringType parseTypeFromString, AnimatedPropertyValueType valueType, AnimatedType& animatedType, SVGElement* contextElement)
{
if (valueType != InheritValue)
return;
// Replace 'inherit' by its computed property value.
- ASSERT(parseTypeFromString);
String typeString;
adjustForInheritance(contextElement, attributeName(), typeString);
- animatedType = (*parseTypeFromString)(this, typeString);
- }
-
- template<typename AnimatedType>
- bool adjustFromToListValues(const AnimatedType& fromList, const AnimatedType& toList, AnimatedType& animatedList, float percentage, bool resizeAnimatedListIfNeeded = true)
- {
- // If no 'to' value is given, nothing to animate.
- unsigned toListSize = toList.size();
- if (!toListSize)
- return false;
-
- // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
- unsigned fromListSize = fromList.size();
- if (fromListSize != toListSize && fromListSize) {
- if (percentage < 0.5) {
- if (animationMode() != ToAnimation)
- animatedList = AnimatedType(fromList);
- } else
- animatedList = AnimatedType(toList);
-
- return false;
- }
-
- ASSERT(!fromListSize || fromListSize == toListSize);
- if (resizeAnimatedListIfNeeded && animatedList.size() < toListSize)
- animatedList.resize(toListSize);
-
- return true;
+ animatedType = parseTypeFromString(this, typeString);
}
template<typename AnimatedType>
@@ -165,7 +134,7 @@ protected:
SVGAnimationElement(const QualifiedName&, Document&);
void computeCSSPropertyValue(SVGElement*, CSSPropertyID, String& value);
- virtual void determinePropertyValueTypes(const String& from, const String& to);
+ void determinePropertyValueTypes(const String& from, const String& to);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
@@ -182,8 +151,6 @@ protected:
String byValue() const;
String fromValue() const;
- String targetAttributeBaseValue();
-
// from SVGSMILElement
virtual void startedActiveInterval() OVERRIDE;
virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) OVERRIDE;
@@ -193,6 +160,7 @@ protected:
virtual void setTargetElement(SVGElement*) OVERRIDE;
virtual void setAttributeName(const QualifiedName&) OVERRIDE;
+
bool hasInvalidCSSAttributeType() const { return m_hasInvalidCSSAttributeType; }
virtual void updateAnimationMode();
@@ -219,18 +187,8 @@ private:
float calculatePercentForFromTo(float percent) const;
unsigned calculateKeyTimesIndex(float percent) const;
- void applyAnimatedValue(ShouldApplyAnimation, SVGElement* targetElement, const QualifiedName& attributeName, SVGAnimatedType*);
void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String&);
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAnimationElement)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
-
- // SVGTests
- virtual void synchronizeRequiredFeatures() { SVGTests::synchronizeRequiredFeatures(this); }
- virtual void synchronizeRequiredExtensions() { SVGTests::synchronizeRequiredExtensions(this); }
- virtual void synchronizeSystemLanguage() { SVGTests::synchronizeSystemLanguage(this); }
-
void setCalcMode(const AtomicString&);
bool m_animationValid;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.idl
index 9e11278015c..deb09d77217 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAnimationElement.idl
@@ -24,18 +24,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG2/animate.html#InterfaceSVGAnimationElement
+
interface SVGAnimationElement : SVGElement {
readonly attribute SVGElement targetElement;
+ attribute EventHandler onbegin;
+ attribute EventHandler onend;
+ attribute EventHandler onrepeat;
+
float getStartTime();
float getCurrentTime();
float getSimpleDuration();
void beginElement();
- void beginElementAt([Default=Undefined] optional float offset);
+ void beginElementAt(float offset);
void endElement();
- void endElementAt([Default=Undefined] optional float offset);
+ void endElementAt(float offset);
+
};
-SVGAnimationElement implements SVGExternalResourcesRequired;
SVGAnimationElement implements SVGTests;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatorFactory.h b/chromium/third_party/WebKit/Source/core/svg/SVGAnimatorFactory.h
deleted file mode 100644
index 9ff3837e13b..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAnimatorFactory.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatorFactory_h
-#define SVGAnimatorFactory_h
-
-#include "core/svg/SVGAnimatedAngle.h"
-#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGAnimatedColor.h"
-#include "core/svg/SVGAnimatedEnumeration.h"
-#include "core/svg/SVGAnimatedInteger.h"
-#include "core/svg/SVGAnimatedIntegerOptionalInteger.h"
-#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGAnimatedLengthList.h"
-#include "core/svg/SVGAnimatedNumber.h"
-#include "core/svg/SVGAnimatedNumberList.h"
-#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
-#include "core/svg/SVGAnimatedPath.h"
-#include "core/svg/SVGAnimatedPointList.h"
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGAnimatedRect.h"
-#include "core/svg/SVGAnimatedString.h"
-#include "core/svg/SVGAnimatedTransformList.h"
-
-namespace WebCore {
-
-class SVGAnimationElement;
-
-class SVGAnimatorFactory {
-public:
- static PassOwnPtr<SVGAnimatedTypeAnimator> create(SVGAnimationElement* animationElement, SVGElement* contextElement, AnimatedPropertyType attributeType)
- {
- ASSERT(animationElement);
- ASSERT(contextElement);
-
- switch (attributeType) {
- case AnimatedAngle:
- return adoptPtr(new SVGAnimatedAngleAnimator(animationElement, contextElement));
- case AnimatedBoolean:
- return adoptPtr(new SVGAnimatedBooleanAnimator(animationElement, contextElement));
- case AnimatedColor:
- return adoptPtr(new SVGAnimatedColorAnimator(animationElement, contextElement));
- case AnimatedEnumeration:
- return adoptPtr(new SVGAnimatedEnumerationAnimator(animationElement, contextElement));
- case AnimatedInteger:
- return adoptPtr(new SVGAnimatedIntegerAnimator(animationElement, contextElement));
- case AnimatedIntegerOptionalInteger:
- return adoptPtr(new SVGAnimatedIntegerOptionalIntegerAnimator(animationElement, contextElement));
- case AnimatedLength:
- return adoptPtr(new SVGAnimatedLengthAnimator(animationElement, contextElement));
- case AnimatedLengthList:
- return adoptPtr(new SVGAnimatedLengthListAnimator(animationElement, contextElement));
- case AnimatedNumber:
- return adoptPtr(new SVGAnimatedNumberAnimator(animationElement, contextElement));
- case AnimatedNumberList:
- return adoptPtr(new SVGAnimatedNumberListAnimator(animationElement, contextElement));
- case AnimatedNumberOptionalNumber:
- return adoptPtr(new SVGAnimatedNumberOptionalNumberAnimator(animationElement, contextElement));
- case AnimatedPath:
- return adoptPtr(new SVGAnimatedPathAnimator(animationElement, contextElement));
- case AnimatedPoints:
- return adoptPtr(new SVGAnimatedPointListAnimator(animationElement, contextElement));
- case AnimatedPreserveAspectRatio:
- return adoptPtr(new SVGAnimatedPreserveAspectRatioAnimator(animationElement, contextElement));
- case AnimatedRect:
- return adoptPtr(new SVGAnimatedRectAnimator(animationElement, contextElement));
- case AnimatedString:
- return adoptPtr(new SVGAnimatedStringAnimator(animationElement, contextElement));
- case AnimatedTransformList:
- return adoptPtr(new SVGAnimatedTransformListAnimator(animationElement, contextElement));
- case AnimatedUnknown:
- break;
- }
-
- ASSERT_NOT_REACHED();
- return nullptr;
- }
-
-private:
- SVGAnimatorFactory() { }
-
-};
-
-} // namespace WebCore
-
-#endif // SVGAnimatorFactory_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGAttributeNames.in b/chromium/third_party/WebKit/Source/core/svg/SVGAttributeNames.in
index bee8ecc5e2c..f236afdca25 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGAttributeNames.in
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGAttributeNames.in
@@ -31,10 +31,7 @@ clipPathUnits
color
color-interpolation
color-interpolation-filters
-color-profile
color-rendering
-contentScriptType
-contentStyleType
cursor
cx
cy
@@ -53,7 +50,6 @@ elevation
enable-background
end
exponent
-externalResourcesRequired
fill
fill-opacity
fill-rule
@@ -99,7 +95,6 @@ k3
k4
kernelMatrix
kernelUnitLength
-kerning
keyPoints
keySplines
keyTimes
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGBoolean.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGBoolean.cpp
new file mode 100644
index 00000000000..43aa55be5a0
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGBoolean.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGBoolean.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
+
+namespace WebCore {
+
+PassRefPtr<SVGPropertyBase> SVGBoolean::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGBoolean> svgBoolean = create();
+ svgBoolean->setValueAsString(value, IGNORE_EXCEPTION);
+ return svgBoolean.release();
+}
+
+String SVGBoolean::valueAsString() const
+{
+ return m_value ? "true" : "false";
+}
+
+void SVGBoolean::setValueAsString(const String& value, ExceptionState& exceptionState)
+{
+ if (value == "true") {
+ m_value = true;
+ } else if (value == "false") {
+ m_value = false;
+ } else {
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + value + "') is invalid.");
+ }
+}
+
+void SVGBoolean::add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void SVGBoolean::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ ASSERT(animationElement);
+ bool fromBoolean = animationElement->animationMode() == ToAnimation ? m_value : toSVGBoolean(from)->value();
+ bool toBoolean = toSVGBoolean(to)->value();
+
+ animationElement->animateDiscreteType<bool>(percentage, fromBoolean, toBoolean, m_value);
+}
+
+float SVGBoolean::calculateDistance(PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ // No paced animations for boolean.
+ return -1;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGBoolean.h b/chromium/third_party/WebKit/Source/core/svg/SVGBoolean.h
new file mode 100644
index 00000000000..3cbbd4030e8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGBoolean.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGBoolean_h
+#define SVGBoolean_h
+
+#include "core/svg/properties/SVGProperty.h"
+
+namespace WebCore {
+
+class SVGBoolean : public SVGPropertyBase {
+public:
+ // SVGBoolean does not have a tear-off type.
+ typedef void TearOffType;
+ typedef bool PrimitiveType;
+
+ static PassRefPtr<SVGBoolean> create(bool value = false)
+ {
+ return adoptRef(new SVGBoolean(value));
+ }
+
+ PassRefPtr<SVGBoolean> clone() const { return create(m_value); }
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+ virtual String valueAsString() const OVERRIDE;
+ void setValueAsString(const String&, ExceptionState&);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ bool operator==(const SVGBoolean& other) const { return m_value == other.m_value; }
+ bool operator!=(const SVGBoolean& other) const { return !operator==(other); }
+
+ bool value() const { return m_value; }
+ void setValue(bool value) { m_value = value; }
+
+ static AnimatedPropertyType classType() { return AnimatedBoolean; }
+
+private:
+ SVGBoolean(bool value)
+ : SVGPropertyBase(classType())
+ , m_value(value)
+ {
+ }
+
+ bool m_value;
+};
+
+inline PassRefPtr<SVGBoolean> toSVGBoolean(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGBoolean::classType());
+ return static_pointer_cast<SVGBoolean>(base.release());
+}
+
+} // namespace WebCore
+
+#endif // SVGBoolean_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.cpp
index e1d6ba3bb6d..f87c8b78381 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.cpp
@@ -24,45 +24,29 @@
#include "core/rendering/svg/RenderSVGEllipse.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLength.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGCircleElement, SVGNames::cxAttr, Cx, cx)
-DEFINE_ANIMATED_LENGTH(SVGCircleElement, SVGNames::cyAttr, Cy, cy)
-DEFINE_ANIMATED_LENGTH(SVGCircleElement, SVGNames::rAttr, R, r)
-DEFINE_ANIMATED_BOOLEAN(SVGCircleElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGCircleElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(cx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(cy)
- REGISTER_LOCAL_ANIMATED_PROPERTY(r)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGCircleElement::SVGCircleElement(Document& document)
: SVGGeometryElement(SVGNames::circleTag, document)
- , m_cx(LengthModeWidth)
- , m_cy(LengthModeHeight)
- , m_r(LengthModeOther)
+ , m_cx(SVGAnimatedLength::create(this, SVGNames::cxAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_cy(SVGAnimatedLength::create(this, SVGNames::cyAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_r(SVGAnimatedLength::create(this, SVGNames::rAttr, SVGLength::create(LengthModeOther), ForbidNegativeLengths))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGCircleElement();
-}
-PassRefPtr<SVGCircleElement> SVGCircleElement::create(Document& document)
-{
- return adoptRef(new SVGCircleElement(document));
+ addToPropertyMap(m_cx);
+ addToPropertyMap(m_cy);
+ addToPropertyMap(m_r);
}
+DEFINE_NODE_FACTORY(SVGCircleElement)
+
bool SVGCircleElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::cxAttr);
supportedAttributes.add(SVGNames::cyAttr);
supportedAttributes.add(SVGNames::rAttr);
@@ -77,13 +61,12 @@ void SVGCircleElement::parseAttribute(const QualifiedName& name, const AtomicStr
if (!isSupportedAttribute(name))
SVGGeometryElement::parseAttribute(name, value);
else if (name == SVGNames::cxAttr)
- setCxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_cx->setBaseValueAsString(value, parseError);
else if (name == SVGNames::cyAttr)
- setCyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_cy->setBaseValueAsString(value, parseError);
else if (name == SVGNames::rAttr)
- setRBaseValue(SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
- else if (SVGExternalResourcesRequired::parseAttribute(name, value)) {
- } else
+ m_r->setBaseValueAsString(value, parseError);
+ else
ASSERT_NOT_REACHED();
reportAttributeParsingError(parseError, name, value);
@@ -96,7 +79,7 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
bool isLengthAttribute = attrName == SVGNames::cxAttr
|| attrName == SVGNames::cyAttr
@@ -115,19 +98,14 @@ void SVGCircleElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
ASSERT_NOT_REACHED();
}
bool SVGCircleElement::selfHasRelativeLengths() const
{
- return cxCurrentValue().isRelative()
- || cyCurrentValue().isRelative()
- || rCurrentValue().isRelative();
+ return m_cx->currentValue()->isRelative()
+ || m_cy->currentValue()->isRelative()
+ || m_r->currentValue()->isRelative();
}
RenderObject* SVGCircleElement::createRenderer(RenderStyle*)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.h
index eb689f8d31d..b0fb11988db 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.h
@@ -21,43 +21,37 @@
#ifndef SVGCircleElement_h
#define SVGCircleElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGeometryElement.h"
namespace WebCore {
-class SVGCircleElement FINAL : public SVGGeometryElement,
- public SVGExternalResourcesRequired {
+class SVGCircleElement FINAL : public SVGGeometryElement {
public:
- static PassRefPtr<SVGCircleElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGCircleElement);
+
+ SVGAnimatedLength* cx() const { return m_cx.get(); }
+ SVGAnimatedLength* cy() const { return m_cy.get(); }
+ SVGAnimatedLength* r() const { return m_r.get(); }
private:
explicit SVGCircleElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGCircleElement)
- DECLARE_ANIMATED_LENGTH(Cx, cx)
- DECLARE_ANIMATED_LENGTH(Cy, cy)
- DECLARE_ANIMATED_LENGTH(R, r)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_cx;
+ RefPtr<SVGAnimatedLength> m_cy;
+ RefPtr<SVGAnimatedLength> m_r;
};
-DEFINE_NODE_TYPE_CASTS(SVGCircleElement, hasTagName(SVGNames::circleTag));
-
} // namespace WebCore
#endif // SVGCircleElement_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.idl
index 67f3d445648..19630dd5181 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGCircleElement.idl
@@ -30,5 +30,3 @@ interface SVGCircleElement : SVGGeometryElement {
readonly attribute SVGAnimatedLength r;
};
-SVGCircleElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp
index c4224f1cfa5..a18ad74ff5b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp
@@ -24,40 +24,25 @@
#include "core/svg/SVGClipPathElement.h"
#include "core/rendering/svg/RenderSVGResourceClipper.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGClipPathElement, SVGNames::clipPathUnitsAttr, ClipPathUnits, clipPathUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_BOOLEAN(SVGClipPathElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGClipPathElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(clipPathUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGClipPathElement::SVGClipPathElement(Document& document)
: SVGGraphicsElement(SVGNames::clipPathTag, document)
- , m_clipPathUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
+ , m_clipPathUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::clipPathUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGClipPathElement();
+ addToPropertyMap(m_clipPathUnits);
}
-PassRefPtr<SVGClipPathElement> SVGClipPathElement::create(Document& document)
-{
- return adoptRef(new SVGClipPathElement(document));
-}
+DEFINE_NODE_FACTORY(SVGClipPathElement)
bool SVGClipPathElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
- if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+ if (supportedAttributes.isEmpty())
supportedAttributes.add(SVGNames::clipPathUnitsAttr);
- }
+
return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
}
@@ -68,17 +53,14 @@ void SVGClipPathElement::parseAttribute(const QualifiedName& name, const AtomicS
return;
}
- if (name == SVGNames::clipPathUnitsAttr) {
- SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
- if (propertyValue > 0)
- setClipPathUnitsBaseValue(propertyValue);
- return;
- }
+ SVGParsingError parseError = NoError;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
+ if (name == SVGNames::clipPathUnitsAttr)
+ m_clipPathUnits->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -88,7 +70,7 @@ void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer());
if (renderer)
@@ -103,7 +85,7 @@ void SVGClipPathElement::childrenChanged(bool changedByParser, Node* beforeChang
return;
if (RenderObject* object = renderer())
- object->setNeedsLayout();
+ object->setNeedsLayoutAndFullPaintInvalidation();
}
RenderObject* SVGClipPathElement::createRenderer(RenderStyle*)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.h
index 0b0baec5ec7..893412a3f28 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.h
@@ -21,10 +21,9 @@
#ifndef SVGClipPathElement_h
#define SVGClipPathElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedEnumeration.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
#include "core/svg/SVGUnitTypes.h"
@@ -32,32 +31,28 @@ namespace WebCore {
class RenderObject;
-class SVGClipPathElement FINAL : public SVGGraphicsElement,
- public SVGExternalResourcesRequired {
+class SVGClipPathElement FINAL : public SVGGraphicsElement {
public:
- static PassRefPtr<SVGClipPathElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGClipPathElement);
+ SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* clipPathUnits() { return m_clipPathUnits.get(); }
+
+ virtual bool supportsFocus() const OVERRIDE { return false; }
private:
explicit SVGClipPathElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool needsPendingResourceHandling() const { return false; }
+ virtual bool needsPendingResourceHandling() const OVERRIDE { return false; }
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGClipPathElement)
- DECLARE_ANIMATED_ENUMERATION(ClipPathUnits, clipPathUnits, SVGUnitTypes::SVGUnitType)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_clipPathUnits;
};
-DEFINE_NODE_TYPE_CASTS(SVGClipPathElement, hasTagName(SVGNames::clipPathTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.idl
index 0d729d2258a..4bb7cf19cdd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGClipPathElement.idl
@@ -27,5 +27,3 @@
interface SVGClipPathElement : SVGGraphicsElement {
readonly attribute SVGAnimatedEnumeration clipPathUnits;
};
-
-SVGClipPathElement implements SVGExternalResourcesRequired;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGColor.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGColor.cpp
deleted file mode 100644
index 788ecf8d9f4..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGColor.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/SVGColor.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/css/CSSParser.h"
-#include "core/css/RGBColor.h"
-
-namespace WebCore {
-
-SVGColor::SVGColor(const SVGColorType& colorType)
- : CSSValue(SVGColorClass)
- , m_colorType(colorType)
-{
-}
-
-SVGColor::SVGColor(ClassType classType, const SVGColorType& colorType)
- : CSSValue(classType)
- , m_colorType(colorType)
-{
-}
-
-PassRefPtr<RGBColor> SVGColor::rgbColor() const
-{
- return RGBColor::create(m_color.rgb());
-}
-
-Color SVGColor::colorFromRGBColorString(const String& colorString)
-{
- // FIXME: Rework css parser so it is more SVG aware.
- RGBA32 color;
- if (CSSParser::parseColor(color, colorString.stripWhiteSpace()))
- return color;
- return Color();
-}
-
-void SVGColor::setRGBColor(const String&, ExceptionState& exceptionState)
-{
- // The whole SVGColor interface is deprecated in SVG 1.1 (2nd edition).
- // The setters are the most problematic part so we remove the support for those first.
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
-}
-
-void SVGColor::setRGBColorICCColor(const String&, const String&, ExceptionState& exceptionState)
-{
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
-}
-
-void SVGColor::setColor(unsigned short, const String&, const String&, ExceptionState& exceptionState)
-{
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
-}
-
-String SVGColor::customCSSText() const
-{
- switch (m_colorType) {
- case SVG_COLORTYPE_UNKNOWN:
- return String();
- case SVG_COLORTYPE_RGBCOLOR_ICCCOLOR:
- case SVG_COLORTYPE_RGBCOLOR:
- // FIXME: No ICC color support.
- return m_color.serialized();
- case SVG_COLORTYPE_CURRENTCOLOR:
- if (m_color.isValid())
- return m_color.serialized();
- return "currentColor";
- }
-
- ASSERT_NOT_REACHED();
- return String();
-}
-
-SVGColor::SVGColor(ClassType classType, const SVGColor& cloneFrom)
- : CSSValue(classType, /*isCSSOMSafe*/ true)
- , m_color(cloneFrom.m_color)
- , m_colorType(cloneFrom.m_colorType)
-{
-}
-
-PassRefPtr<SVGColor> SVGColor::cloneForCSSOM() const
-{
- return adoptRef(new SVGColor(SVGColorClass, *this));
-}
-
-bool SVGColor::equals(const SVGColor& other) const
-{
- return m_colorType == other.m_colorType && m_color == other.m_color;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGColor.h b/chromium/third_party/WebKit/Source/core/svg/SVGColor.h
deleted file mode 100644
index 03416661228..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGColor.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGColor_h
-#define SVGColor_h
-
-#include "core/css/CSSValue.h"
-#include "platform/graphics/Color.h"
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-class ExceptionState;
-class RGBColor;
-
-class SVGColor : public CSSValue {
-public:
- enum SVGColorType {
- SVG_COLORTYPE_UNKNOWN = 0,
- SVG_COLORTYPE_RGBCOLOR = 1,
- SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2,
- SVG_COLORTYPE_CURRENTCOLOR = 3
- };
-
- static PassRefPtr<SVGColor> createFromString(const String& rgbColor)
- {
- RefPtr<SVGColor> color = adoptRef(new SVGColor(SVG_COLORTYPE_RGBCOLOR));
- color->setColor(colorFromRGBColorString(rgbColor));
- return color.release();
- }
-
- static PassRefPtr<SVGColor> createFromColor(const Color& rgbColor)
- {
- RefPtr<SVGColor> color = adoptRef(new SVGColor(SVG_COLORTYPE_RGBCOLOR));
- color->setColor(rgbColor);
- return color.release();
- }
-
- static PassRefPtr<SVGColor> createCurrentColor()
- {
- return adoptRef(new SVGColor(SVG_COLORTYPE_CURRENTCOLOR));
- }
-
- const Color& color() const { return m_color; }
- const SVGColorType& colorType() const { return m_colorType; }
- PassRefPtr<RGBColor> rgbColor() const;
-
- static Color colorFromRGBColorString(const String&);
-
- void setRGBColor(const String& rgbColor, ExceptionState&);
- void setRGBColorICCColor(const String& rgbColor, const String& iccColor, ExceptionState&);
- void setColor(unsigned short colorType, const String& rgbColor, const String& iccColor, ExceptionState&);
-
- String customCSSText() const;
-
- ~SVGColor() { }
-
- PassRefPtr<SVGColor> cloneForCSSOM() const;
-
- bool equals(const SVGColor&) const;
-
-protected:
- friend class CSSComputedStyleDeclaration;
-
- SVGColor(ClassType, const SVGColorType&);
- SVGColor(ClassType, const SVGColor& cloneFrom);
-
- void setColor(const Color& color) { m_color = color; }
- void setColorType(const SVGColorType& type) { m_colorType = type; }
-
-private:
- SVGColor(const SVGColorType&);
-
- Color m_color;
- SVGColorType m_colorType;
-};
-
-DEFINE_CSS_VALUE_TYPE_CASTS(SVGColor, isSVGColor());
-
-} // namespace WebCore
-
-#endif // SVGColor_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGColor.idl b/chromium/third_party/WebKit/Source/core/svg/SVGColor.idl
deleted file mode 100644
index 6cce81e9a75..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGColor.idl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
- * Copyright (C) 2006 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-interface SVGColor : CSSValue {
- const unsigned short SVG_COLORTYPE_UNKNOWN = 0;
- const unsigned short SVG_COLORTYPE_RGBCOLOR = 1;
- const unsigned short SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2;
- const unsigned short SVG_COLORTYPE_CURRENTCOLOR = 3;
-
- readonly attribute unsigned short colorType;
- readonly attribute RGBColor rgbColor;
- // FIXME: readonly attribute SVGICCColor iccColor;
-
- [StrictTypeChecking, RaisesException] void setRGBColor(DOMString rgbColor);
-
- [StrictTypeChecking, RaisesException] void setRGBColorICCColor(DOMString rgbColor, DOMString iccColor);
-
- [StrictTypeChecking, RaisesException] void setColor(unsigned short colorType, DOMString rgbColor, DOMString iccColor);
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp
index 2e8818d31ed..2123cd30e30 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp
@@ -22,42 +22,45 @@
#include "core/svg/SVGComponentTransferFunctionElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Attribute.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGFEComponentTransferElement.h"
#include "core/svg/SVGNumberList.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGComponentTransferFunctionElement, SVGNames::typeAttr, Type, type, ComponentTransferType)
-DEFINE_ANIMATED_NUMBER_LIST(SVGComponentTransferFunctionElement, SVGNames::tableValuesAttr, TableValues, tableValues)
-DEFINE_ANIMATED_NUMBER(SVGComponentTransferFunctionElement, SVGNames::slopeAttr, Slope, slope)
-DEFINE_ANIMATED_NUMBER(SVGComponentTransferFunctionElement, SVGNames::interceptAttr, Intercept, intercept)
-DEFINE_ANIMATED_NUMBER(SVGComponentTransferFunctionElement, SVGNames::amplitudeAttr, Amplitude, amplitude)
-DEFINE_ANIMATED_NUMBER(SVGComponentTransferFunctionElement, SVGNames::exponentAttr, Exponent, exponent)
-DEFINE_ANIMATED_NUMBER(SVGComponentTransferFunctionElement, SVGNames::offsetAttr, Offset, offset)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGComponentTransferFunctionElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(type)
- REGISTER_LOCAL_ANIMATED_PROPERTY(tableValues)
- REGISTER_LOCAL_ANIMATED_PROPERTY(slope)
- REGISTER_LOCAL_ANIMATED_PROPERTY(intercept)
- REGISTER_LOCAL_ANIMATED_PROPERTY(amplitude)
- REGISTER_LOCAL_ANIMATED_PROPERTY(exponent)
- REGISTER_LOCAL_ANIMATED_PROPERTY(offset)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ComponentTransferType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_IDENTITY, "identity"));
+ entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_TABLE, "table"));
+ entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_DISCRETE, "discrete"));
+ entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_LINEAR, "linear"));
+ entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_GAMMA, "gamma"));
+ }
+ return entries;
+}
SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(const QualifiedName& tagName, Document& document)
: SVGElement(tagName, document)
- , m_type(FECOMPONENTTRANSFER_TYPE_IDENTITY)
- , m_slope(1)
- , m_amplitude(1)
- , m_exponent(1)
+ , m_tableValues(SVGAnimatedNumberList::create(this, SVGNames::tableValuesAttr, SVGNumberList::create()))
+ , m_slope(SVGAnimatedNumber::create(this, SVGNames::slopeAttr, SVGNumber::create(1)))
+ , m_intercept(SVGAnimatedNumber::create(this, SVGNames::interceptAttr, SVGNumber::create()))
+ , m_amplitude(SVGAnimatedNumber::create(this, SVGNames::amplitudeAttr, SVGNumber::create(1)))
+ , m_exponent(SVGAnimatedNumber::create(this, SVGNames::exponentAttr, SVGNumber::create(1)))
+ , m_offset(SVGAnimatedNumber::create(this, SVGNames::offsetAttr, SVGNumber::create()))
+ , m_type(SVGAnimatedEnumeration<ComponentTransferType>::create(this, SVGNames::typeAttr, FECOMPONENTTRANSFER_TYPE_IDENTITY))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGComponentTransferFunctionElement();
+
+ addToPropertyMap(m_tableValues);
+ addToPropertyMap(m_slope);
+ addToPropertyMap(m_intercept);
+ addToPropertyMap(m_amplitude);
+ addToPropertyMap(m_exponent);
+ addToPropertyMap(m_offset);
+ addToPropertyMap(m_type);
}
bool SVGComponentTransferFunctionElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -82,47 +85,24 @@ void SVGComponentTransferFunctionElement::parseAttribute(const QualifiedName& na
return;
}
- if (name == SVGNames::typeAttr) {
- ComponentTransferType propertyValue = SVGPropertyTraits<ComponentTransferType>::fromString(value);
- if (propertyValue > 0)
- setTypeBaseValue(propertyValue);
- return;
- }
-
- if (name == SVGNames::tableValuesAttr) {
- SVGNumberList newList;
- newList.parse(value);
- detachAnimatedTableValuesListWrappers(newList.size());
- setTableValuesBaseValue(newList);
- return;
- }
-
- if (name == SVGNames::slopeAttr) {
- setSlopeBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::interceptAttr) {
- setInterceptBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::amplitudeAttr) {
- setAmplitudeBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::exponentAttr) {
- setExponentBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::offsetAttr) {
- setOffsetBaseValue(value.toFloat());
- return;
- }
-
- ASSERT_NOT_REACHED();
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::tableValuesAttr)
+ m_tableValues->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::typeAttr)
+ m_type->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::slopeAttr)
+ m_slope->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::interceptAttr)
+ m_intercept->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::amplitudeAttr)
+ m_amplitude->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::exponentAttr)
+ m_exponent->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::offsetAttr)
+ m_offset->setBaseValueAsString(value, parseError);
+
+ reportAttributeParsingError(parseError, name, value);
}
void SVGComponentTransferFunctionElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -132,7 +112,7 @@ void SVGComponentTransferFunctionElement::svgAttributeChanged(const QualifiedNam
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
invalidateFilterPrimitiveParent(this);
}
@@ -140,13 +120,13 @@ void SVGComponentTransferFunctionElement::svgAttributeChanged(const QualifiedNam
ComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction() const
{
ComponentTransferFunction func;
- func.type = typeCurrentValue();
- func.slope = slopeCurrentValue();
- func.intercept = interceptCurrentValue();
- func.amplitude = amplitudeCurrentValue();
- func.exponent = exponentCurrentValue();
- func.offset = offsetCurrentValue();
- func.tableValues = tableValuesCurrentValue().toFloatVector();
+ func.type = m_type->currentValue()->enumValue();
+ func.slope = m_slope->currentValue()->value();
+ func.intercept = m_intercept->currentValue()->value();
+ func.amplitude = m_amplitude->currentValue()->value();
+ func.exponent = m_exponent->currentValue()->value();
+ func.offset = m_offset->currentValue()->value();
+ func.tableValues = m_tableValues->currentValue()->toFloatVector();
return func;
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.h
index b794e710d92..da9a95686ff 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.h
@@ -24,74 +24,42 @@
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedNumber.h"
#include "core/svg/SVGAnimatedNumberList.h"
+#include "core/svg/SVGElement.h"
#include "platform/graphics/filters/FEComponentTransfer.h"
namespace WebCore {
-template<>
-struct SVGPropertyTraits<ComponentTransferType> {
- static unsigned highestEnumValue() { return FECOMPONENTTRANSFER_TYPE_GAMMA; }
-
- static String toString(ComponentTransferType type)
- {
- switch (type) {
- case FECOMPONENTTRANSFER_TYPE_UNKNOWN:
- return emptyString();
- case FECOMPONENTTRANSFER_TYPE_IDENTITY:
- return "identity";
- case FECOMPONENTTRANSFER_TYPE_TABLE:
- return "table";
- case FECOMPONENTTRANSFER_TYPE_DISCRETE:
- return "discrete";
- case FECOMPONENTTRANSFER_TYPE_LINEAR:
- return "linear";
- case FECOMPONENTTRANSFER_TYPE_GAMMA:
- return "gamma";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static ComponentTransferType fromString(const String& value)
- {
- if (value == "identity")
- return FECOMPONENTTRANSFER_TYPE_IDENTITY;
- if (value == "table")
- return FECOMPONENTTRANSFER_TYPE_TABLE;
- if (value == "discrete")
- return FECOMPONENTTRANSFER_TYPE_DISCRETE;
- if (value == "linear")
- return FECOMPONENTTRANSFER_TYPE_LINEAR;
- if (value == "gamma")
- return FECOMPONENTTRANSFER_TYPE_GAMMA;
- return FECOMPONENTTRANSFER_TYPE_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ComponentTransferType>();
class SVGComponentTransferFunctionElement : public SVGElement {
public:
ComponentTransferFunction transferFunction() const;
+ SVGAnimatedNumberList* tableValues() { return m_tableValues.get(); }
+ SVGAnimatedNumber* slope() { return m_slope.get(); }
+ SVGAnimatedNumber* intercept() { return m_intercept.get(); }
+ SVGAnimatedNumber* amplitude() { return m_amplitude.get(); }
+ SVGAnimatedNumber* exponent() { return m_exponent.get(); }
+ SVGAnimatedNumber* offset() { return m_offset.get(); }
+ SVGAnimatedEnumeration<ComponentTransferType>* type() { return m_type.get(); }
+
protected:
SVGComponentTransferFunctionElement(const QualifiedName&, Document&);
bool isSupportedAttribute(const QualifiedName&);
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE FINAL;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE FINAL;
- virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE FINAL { return false; }
private:
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGComponentTransferFunctionElement)
- DECLARE_ANIMATED_ENUMERATION(Type, type, ComponentTransferType)
- DECLARE_ANIMATED_NUMBER_LIST(TableValues, tableValues)
- DECLARE_ANIMATED_NUMBER(Slope, slope)
- DECLARE_ANIMATED_NUMBER(Intercept, intercept)
- DECLARE_ANIMATED_NUMBER(Amplitude, amplitude)
- DECLARE_ANIMATED_NUMBER(Exponent, exponent)
- DECLARE_ANIMATED_NUMBER(Offset, offset)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumberList> m_tableValues;
+ RefPtr<SVGAnimatedNumber> m_slope;
+ RefPtr<SVGAnimatedNumber> m_intercept;
+ RefPtr<SVGAnimatedNumber> m_amplitude;
+ RefPtr<SVGAnimatedNumber> m_exponent;
+ RefPtr<SVGAnimatedNumber> m_offset;
+ RefPtr<SVGAnimatedEnumeration<ComponentTransferType> > m_type;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.cpp
index 5473a2f3084..578047f8d56 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.cpp
@@ -22,46 +22,35 @@
#include "core/svg/SVGCursorElement.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Document.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGCursorElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGCursorElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_STRING(SVGCursorElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGCursorElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGCursorElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGCursorElement::SVGCursorElement(Document& document)
: SVGElement(SVGNames::cursorTag, document)
- , m_x(LengthModeWidth)
- , m_y(LengthModeHeight)
+ , SVGTests(this)
+ , SVGURIReference(this)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGCursorElement();
-}
-PassRefPtr<SVGCursorElement> SVGCursorElement::create(Document& document)
-{
- return adoptRef(new SVGCursorElement(document));
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
}
+DEFINE_NODE_FACTORY(SVGCursorElement)
+
SVGCursorElement::~SVGCursorElement()
{
- HashSet<SVGElement*>::iterator end = m_clients.end();
- for (HashSet<SVGElement*>::iterator it = m_clients.begin(); it != end; ++it)
+ // The below teardown is all handled by weak pointer processing in oilpan.
+#if !ENABLE(OILPAN)
+ HashSet<RawPtr<SVGElement> >::iterator end = m_clients.end();
+ for (HashSet<RawPtr<SVGElement> >::iterator it = m_clients.begin(); it != end; ++it)
(*it)->cursorElementRemoved();
+#endif
}
bool SVGCursorElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -69,7 +58,6 @@ bool SVGCursorElement::isSupportedAttribute(const QualifiedName& attrName)
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGTests::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
SVGURIReference::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::xAttr);
supportedAttributes.add(SVGNames::yAttr);
@@ -81,17 +69,17 @@ void SVGCursorElement::parseAttribute(const QualifiedName& name, const AtomicStr
{
SVGParsingError parseError = NoError;
- if (!isSupportedAttribute(name))
+ if (!isSupportedAttribute(name)) {
SVGElement::parseAttribute(name, value);
- else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
- else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (SVGTests::parseAttribute(name, value)
- || SVGExternalResourcesRequired::parseAttribute(name, value)
- || SVGURIReference::parseAttribute(name, value)) {
- } else
+ } else if (name == SVGNames::xAttr) {
+ m_x->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::yAttr) {
+ m_y->setBaseValueAsString(value, parseError);
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else if (SVGTests::parseAttribute(name, value)) {
+ } else {
ASSERT_NOT_REACHED();
+ }
reportAttributeParsingError(parseError, name, value);
}
@@ -102,14 +90,16 @@ void SVGCursorElement::addClient(SVGElement* element)
element->setCursorElement(this);
}
+#if !ENABLE(OILPAN)
void SVGCursorElement::removeClient(SVGElement* element)
{
- HashSet<SVGElement*>::iterator it = m_clients.find(element);
+ HashSet<RawPtr<SVGElement> >::iterator it = m_clients.find(element);
if (it != m_clients.end()) {
m_clients.remove(it);
element->cursorElementRemoved();
}
}
+#endif
void SVGCursorElement::removeReferencedElement(SVGElement* element)
{
@@ -123,14 +113,20 @@ void SVGCursorElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
// Any change of a cursor specific attribute triggers this recalc.
- HashSet<SVGElement*>::const_iterator it = m_clients.begin();
- HashSet<SVGElement*>::const_iterator end = m_clients.end();
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = m_clients.begin();
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = m_clients.end();
for (; it != end; ++it)
- (*it)->setNeedsStyleRecalc();
+ (*it)->setNeedsStyleRecalc(SubtreeStyleChange);
+}
+
+void SVGCursorElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_clients);
+ SVGElement::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.h
index 57011308521..d1a290f3793 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.h
@@ -21,11 +21,11 @@
#ifndef SVGCursorElement_h
#define SVGCursorElement_h
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
#include "core/svg/SVGAnimatedString.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGTests.h"
#include "core/svg/SVGURIReference.h"
@@ -33,41 +33,38 @@ namespace WebCore {
class SVGCursorElement FINAL : public SVGElement,
public SVGTests,
- public SVGExternalResourcesRequired,
public SVGURIReference {
public:
- static PassRefPtr<SVGCursorElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGCursorElement);
virtual ~SVGCursorElement();
void addClient(SVGElement*);
+#if !ENABLE(OILPAN)
void removeClient(SVGElement*);
+#endif
void removeReferencedElement(SVGElement*);
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit SVGCursorElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
+ virtual bool isValid() const OVERRIDE { return SVGTests::isValid(); }
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGCursorElement)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
-
- // SVGTests
- virtual void synchronizeRequiredFeatures() { SVGTests::synchronizeRequiredFeatures(this); }
- virtual void synchronizeRequiredExtensions() { SVGTests::synchronizeRequiredExtensions(this); }
- virtual void synchronizeSystemLanguage() { SVGTests::synchronizeSystemLanguage(this); }
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
- HashSet<SVGElement*> m_clients;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > m_clients;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.idl
index d386935d108..627bf196c73 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGCursorElement.idl
@@ -23,12 +23,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG11/interact.html#InterfaceSVGCursorElement
+// http://www.w3.org/TR/SVG2/interact.html#InterfaceSVGCursorElement
+
interface SVGCursorElement : SVGElement {
readonly attribute SVGAnimatedLength x;
readonly attribute SVGAnimatedLength y;
};
-SVGCursorElement implements SVGExternalResourcesRequired;
SVGCursorElement implements SVGURIReference;
-SVGCursorElement implements SVGTests;
-
+SVGCursorElement implements SVGTests; // in SVG 1.1 but not SVG 2
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.cpp
index ae425f37ecf..778adbe391e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.cpp
@@ -22,35 +22,18 @@
#include "core/svg/SVGDefsElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/svg/RenderSVGHiddenContainer.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_BOOLEAN(SVGDefsElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGDefsElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGDefsElement::SVGDefsElement(Document& document)
: SVGGraphicsElement(SVGNames::defsTag, document)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGDefsElement();
}
-PassRefPtr<SVGDefsElement> SVGDefsElement::create(Document& document)
-{
- return adoptRef(new SVGDefsElement(document));
-}
-
-bool SVGDefsElement::isValid() const
-{
- return SVGTests::isValid();
-}
+DEFINE_NODE_FACTORY(SVGDefsElement)
RenderObject* SVGDefsElement::createRenderer(RenderStyle*)
{
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.h
index 60ff06beb4a..5d1b1563a9b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.h
@@ -22,26 +22,20 @@
#define SVGDefsElement_h
#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
namespace WebCore {
-class SVGDefsElement FINAL : public SVGGraphicsElement,
- public SVGExternalResourcesRequired {
+class SVGDefsElement FINAL : public SVGGraphicsElement {
public:
- static PassRefPtr<SVGDefsElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGDefsElement);
+
+ virtual bool supportsFocus() const OVERRIDE { return false; }
private:
explicit SVGDefsElement(Document&);
- virtual bool isValid() const;
-
- virtual RenderObject* createRenderer(RenderStyle*);
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGDefsElement)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.idl
index f4e727a0df2..807db63de6a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDefsElement.idl
@@ -26,5 +26,3 @@
interface SVGDefsElement : SVGGraphicsElement {
};
-SVGDefsElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDescElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGDescElement.cpp
index 9696aa1c04e..0d35608b343 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDescElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDescElement.cpp
@@ -19,9 +19,10 @@
*/
#include "config.h"
-#include "SVGNames.h"
#include "core/svg/SVGDescElement.h"
+#include "core/SVGNames.h"
+
namespace WebCore {
inline SVGDescElement::SVGDescElement(Document& document)
@@ -30,14 +31,6 @@ inline SVGDescElement::SVGDescElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGDescElement> SVGDescElement::create(Document& document)
-{
- return adoptRef(new SVGDescElement(document));
-}
-
-String SVGDescElement::description() const
-{
- return textContent().simplifyWhiteSpace();
-}
+DEFINE_NODE_FACTORY(SVGDescElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDescElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGDescElement.h
index 181053dc0a1..86dc6757bdb 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDescElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDescElement.h
@@ -27,14 +27,12 @@ namespace WebCore {
class SVGDescElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGDescElement> create(Document&);
-
- String description() const;
+ DECLARE_NODE_FACTORY(SVGDescElement);
private:
explicit SVGDescElement(Document&);
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp
new file mode 100644
index 00000000000..48d179868a8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGDiscardElement.h"
+
+#include "core/SVGNames.h"
+
+namespace WebCore {
+
+inline SVGDiscardElement::SVGDiscardElement(Document& document)
+ : SVGSMILElement(SVGNames::discardTag, document)
+{
+ ScriptWrappable::init(this);
+}
+
+DEFINE_NODE_FACTORY(SVGDiscardElement)
+
+bool SVGDiscardElement::hasValidAttributeType()
+{
+ // Even if there is no targetElement, discard is still a valid animation as it has to delete itself.
+ return true;
+}
+
+bool SVGDiscardElement::hasValidAttributeName()
+{
+ // discard does not use attributeName so it is always valid.
+ return true;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.h
new file mode 100644
index 00000000000..f03b71e486a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGDiscardElement_h
+#define SVGDiscardElement_h
+
+#include "core/svg/animation/SVGSMILElement.h"
+
+namespace WebCore {
+
+class SVGDiscardElement FINAL : public SVGSMILElement {
+public:
+ DECLARE_NODE_FACTORY(SVGDiscardElement);
+
+ virtual bool isSVGDiscardElement() const OVERRIDE { return true; }
+private:
+ explicit SVGDiscardElement(Document&);
+
+ virtual void resetAnimatedType() OVERRIDE { }
+ virtual void clearAnimatedType(SVGElement* targetElement) OVERRIDE { }
+ virtual void applyResultsToTarget() OVERRIDE { }
+ virtual bool hasValidAttributeType() OVERRIDE;
+ virtual bool hasValidAttributeName() OVERRIDE;
+ virtual void animationAttributeChanged() OVERRIDE { }
+
+ virtual void startedActiveInterval() OVERRIDE { }
+ virtual void updateAnimation(float percent, unsigned repeat, SVGSMILElement* resultElement) OVERRIDE { }
+};
+
+} // namespace WebCore
+
+#endif // SVGDiscardElement_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.idl
new file mode 100644
index 00000000000..54ee14a51d9
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDiscardElement.idl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+interface SVGDiscardElement : SVGElement {
+};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDocument.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGDocument.cpp
deleted file mode 100644
index 876b66f645a..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDocument.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/SVGDocument.h"
-
-#include "SVGNames.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/FrameView.h"
-#include "core/rendering/RenderView.h"
-#include "core/svg/SVGElement.h"
-#include "core/svg/SVGSVGElement.h"
-#include "core/svg/SVGViewSpec.h"
-#include "core/svg/SVGZoomAndPan.h"
-#include "core/svg/SVGZoomEvent.h"
-
-namespace WebCore {
-
-SVGDocument::SVGDocument(const DocumentInit& initializer)
- : Document(initializer, SVGDocumentClass)
-{
- ScriptWrappable::init(this);
-}
-
-SVGSVGElement* SVGDocument::rootElement() const
-{
- Element* elem = documentElement();
- if (elem && elem->hasTagName(SVGNames::svgTag))
- return toSVGSVGElement(elem);
-
- return 0;
-}
-
-void SVGDocument::dispatchZoomEvent(float prevScale, float newScale)
-{
- RefPtr<SVGZoomEvent> event = SVGZoomEvent::create();
- event->initEvent(EventTypeNames::zoom, true, false);
- event->setPreviousScale(prevScale);
- event->setNewScale(newScale);
- rootElement()->dispatchEvent(event.release(), IGNORE_EXCEPTION);
-}
-
-void SVGDocument::dispatchScrollEvent()
-{
- RefPtr<Event> event = Event::create();
- event->initEvent(EventTypeNames::scroll, true, false);
- rootElement()->dispatchEvent(event.release(), IGNORE_EXCEPTION);
-}
-
-bool SVGDocument::zoomAndPanEnabled() const
-{
- if (SVGSVGElement* svg = rootElement()) {
- if (svg->useCurrentView()) {
- if (svg->currentView())
- return svg->currentView()->zoomAndPan() == SVGZoomAndPanMagnify;
- } else {
- return svg->zoomAndPan() == SVGZoomAndPanMagnify;
- }
- }
-
- return false;
-}
-
-void SVGDocument::startPan(const FloatPoint& start)
-{
- if (SVGSVGElement* svg = rootElement())
- m_translate = FloatPoint(start.x() - svg->currentTranslate().x(), start.y() - svg->currentTranslate().y());
-}
-
-void SVGDocument::updatePan(const FloatPoint& pos) const
-{
- if (SVGSVGElement* svg = rootElement()) {
- svg->setCurrentTranslate(FloatPoint(pos.x() - m_translate.x(), pos.y() - m_translate.y()));
- if (renderer())
- renderer()->repaint();
- }
-}
-
-bool SVGDocument::childShouldCreateRenderer(const Node& child) const
-{
- if (child.hasTagName(SVGNames::svgTag))
- return toSVGSVGElement(&child)->isValid();
- return true;
-}
-
-PassRefPtr<Document> SVGDocument::cloneDocumentWithoutChildren()
-{
- return create(DocumentInit(url()));
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDocument.h b/chromium/third_party/WebKit/Source/core/svg/SVGDocument.h
deleted file mode 100644
index a9b3392c398..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDocument.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGDocument_h
-#define SVGDocument_h
-
-#include "core/dom/Document.h"
-#include "platform/geometry/FloatPoint.h"
-
-namespace WebCore {
-
-class SVGSVGElement;
-
-class SVGDocument FINAL : public Document {
-public:
- static PassRefPtr<SVGDocument> create(const DocumentInit& initializer = DocumentInit())
- {
- return adoptRef(new SVGDocument(initializer));
- }
-
- SVGSVGElement* rootElement() const;
-
- void dispatchZoomEvent(float prevScale, float newScale);
- void dispatchScrollEvent();
-
- bool zoomAndPanEnabled() const;
-
- void startPan(const FloatPoint& start);
- void updatePan(const FloatPoint& pos) const;
-
- virtual PassRefPtr<Document> cloneDocumentWithoutChildren() OVERRIDE FINAL;
-
-private:
- explicit SVGDocument(const DocumentInit&);
-
- virtual bool childShouldCreateRenderer(const Node& child) const;
-
- FloatPoint m_translate;
-};
-
-DEFINE_DOCUMENT_TYPE_CASTS(SVGDocument);
-
-} // namespace WebCore
-
-#endif // SVGDocument_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDocument.idl b/chromium/third_party/WebKit/Source/core/svg/SVGDocument.idl
index dced4119455..a57cb2ef6a8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDocument.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDocument.idl
@@ -19,10 +19,9 @@
* Boston, MA 02110-1301, USA.
*/
-interface SVGDocument : Document {
- readonly attribute SVGSVGElement rootElement;
-
- // Overwrite the one in events::DocumentEvent
- [RaisesException] Event createEvent([Default=Undefined] optional DOMString eventType);
+[
+ ImplementedAs=SVGDocumentExtensions
+] partial interface Document {
+ [MeasureAs=SVGDocumentRootElement] readonly attribute SVGSVGElement rootElement;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp
index a135845e036..a1a6c026be8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp
@@ -22,11 +22,14 @@
#include "config.h"
#include "core/svg/SVGDocumentExtensions.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Document.h"
+#include "core/rendering/RenderView.h"
#include "core/rendering/svg/SVGResourcesCache.h"
-#include "core/svg/SVGElement.h"
+#include "core/svg/SVGFontFaceElement.h"
#include "core/svg/SVGSVGElement.h"
+#include "core/svg/SVGViewSpec.h"
+#include "core/svg/SVGZoomAndPan.h"
#include "core/svg/animation/SMILTimeContainer.h"
#include "wtf/TemporaryChange.h"
#include "wtf/text/AtomicString.h"
@@ -36,7 +39,7 @@ namespace WebCore {
SVGDocumentExtensions::SVGDocumentExtensions(Document* document)
: m_document(document)
, m_resourcesCache(adoptPtr(new SVGResourcesCache))
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
, m_inRelativeLengthSVGRootsInvalidation(false)
#endif
{
@@ -83,44 +86,59 @@ RenderSVGResourceContainer* SVGDocumentExtensions::resourceById(const AtomicStri
return m_resources.get(id);
}
+void SVGDocumentExtensions::serviceOnAnimationFrame(Document& document, double monotonicAnimationStartTime)
+{
+ if (!document.svgExtensions())
+ return;
+ document.accessSVGExtensions().serviceAnimations(monotonicAnimationStartTime);
+}
+
+void SVGDocumentExtensions::serviceAnimations(double monotonicAnimationStartTime)
+{
+ WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> > timeContainers;
+ timeContainers.appendRange(m_timeContainers.begin(), m_timeContainers.end());
+ WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> >::iterator end = timeContainers.end();
+ for (WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> >::iterator itr = timeContainers.begin(); itr != end; ++itr)
+ (*itr)->timeContainer()->serviceAnimations(monotonicAnimationStartTime);
+}
+
void SVGDocumentExtensions::startAnimations()
{
// FIXME: Eventually every "Time Container" will need a way to latch on to some global timer
// starting animations for a document will do this "latching"
// FIXME: We hold a ref pointers to prevent a shadow tree from getting removed out from underneath us.
// In the future we should refactor the use-element to avoid this. See https://webkit.org/b/53704
- Vector<RefPtr<SVGSVGElement> > timeContainers;
+ WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> > timeContainers;
timeContainers.appendRange(m_timeContainers.begin(), m_timeContainers.end());
- Vector<RefPtr<SVGSVGElement> >::iterator end = timeContainers.end();
- for (Vector<RefPtr<SVGSVGElement> >::iterator itr = timeContainers.begin(); itr != end; ++itr)
- (*itr)->timeContainer()->begin();
+ WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> >::iterator end = timeContainers.end();
+ for (WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> >::iterator itr = timeContainers.begin(); itr != end; ++itr) {
+ SMILTimeContainer* timeContainer = (*itr)->timeContainer();
+ if (!timeContainer->isStarted())
+ timeContainer->begin();
+ }
}
void SVGDocumentExtensions::pauseAnimations()
{
- HashSet<SVGSVGElement*>::iterator end = m_timeContainers.end();
- for (HashSet<SVGSVGElement*>::iterator itr = m_timeContainers.begin(); itr != end; ++itr)
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGSVGElement> >::iterator end = m_timeContainers.end();
+ for (WillBeHeapHashSet<RawPtrWillBeMember<SVGSVGElement> >::iterator itr = m_timeContainers.begin(); itr != end; ++itr)
(*itr)->pauseAnimations();
}
-void SVGDocumentExtensions::unpauseAnimations()
-{
- HashSet<SVGSVGElement*>::iterator end = m_timeContainers.end();
- for (HashSet<SVGSVGElement*>::iterator itr = m_timeContainers.begin(); itr != end; ++itr)
- (*itr)->unpauseAnimations();
-}
-
void SVGDocumentExtensions::dispatchSVGLoadEventToOutermostSVGElements()
{
- Vector<RefPtr<SVGSVGElement> > timeContainers;
+ WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> > timeContainers;
timeContainers.appendRange(m_timeContainers.begin(), m_timeContainers.end());
- Vector<RefPtr<SVGSVGElement> >::iterator end = timeContainers.end();
- for (Vector<RefPtr<SVGSVGElement> >::iterator it = timeContainers.begin(); it != end; ++it) {
- SVGSVGElement* outerSVG = (*it).get();
+ WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> >::iterator end = timeContainers.end();
+ for (WillBeHeapVector<RefPtrWillBeMember<SVGSVGElement> >::iterator it = timeContainers.begin(); it != end; ++it) {
+ SVGSVGElement* outerSVG = it->get();
if (!outerSVG->isOutermostSVGSVGElement())
continue;
- outerSVG->sendSVGLoadEventIfPossible();
+
+ // don't dispatch the load event document is not wellformed (for XML/standalone svg)
+ if (outerSVG->document().wellFormed() || !outerSVG->document().isSVGDocument())
+ outerSVG->sendSVGLoadEventIfPossible();
}
}
@@ -150,8 +168,8 @@ void SVGDocumentExtensions::addPendingResource(const AtomicString& id, Element*
HashMap<AtomicString, OwnPtr<SVGPendingElements> >::AddResult result = m_pendingResources.add(id, nullptr);
if (result.isNewEntry)
- result.iterator->value = adoptPtr(new SVGPendingElements);
- result.iterator->value->add(element);
+ result.storedValue->value = adoptPtr(new SVGPendingElements);
+ result.storedValue->value->add(element);
element->setHasPendingResources();
}
@@ -289,10 +307,10 @@ Element* SVGDocumentExtensions::removeElementFromPendingResourcesForRemoval(cons
return element;
}
-HashSet<SVGElement*>* SVGDocumentExtensions::setOfElementsReferencingTarget(SVGElement* referencedElement) const
+SVGElementSet* SVGDocumentExtensions::setOfElementsReferencingTarget(SVGElement* referencedElement) const
{
ASSERT(referencedElement);
- const HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::const_iterator it = m_elementDependencies.find(referencedElement);
+ const ElementDependenciesMap::const_iterator it = m_elementDependencies.find(referencedElement);
if (it == m_elementDependencies.end())
return 0;
return it->value.get();
@@ -303,25 +321,25 @@ void SVGDocumentExtensions::addElementReferencingTarget(SVGElement* referencingE
ASSERT(referencingElement);
ASSERT(referencedElement);
- if (HashSet<SVGElement*>* elements = m_elementDependencies.get(referencedElement)) {
+ if (SVGElementSet* elements = m_elementDependencies.get(referencedElement)) {
elements->add(referencingElement);
return;
}
- OwnPtr<HashSet<SVGElement*> > elements = adoptPtr(new HashSet<SVGElement*>);
+ OwnPtrWillBeRawPtr<SVGElementSet> elements = adoptPtrWillBeNoop(new SVGElementSet);
elements->add(referencingElement);
m_elementDependencies.set(referencedElement, elements.release());
}
void SVGDocumentExtensions::removeAllTargetReferencesForElement(SVGElement* referencingElement)
{
- Vector<SVGElement*> toBeRemoved;
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> > toBeRemoved;
- HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator end = m_elementDependencies.end();
- for (HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator it = m_elementDependencies.begin(); it != end; ++it) {
+ ElementDependenciesMap::iterator end = m_elementDependencies.end();
+ for (ElementDependenciesMap::iterator it = m_elementDependencies.begin(); it != end; ++it) {
SVGElement* referencedElement = it->key;
- HashSet<SVGElement*>* referencingElements = it->value.get();
- HashSet<SVGElement*>::iterator setIt = referencingElements->find(referencingElement);
+ SVGElementSet* referencingElements = it->value.get();
+ SVGElementSet::iterator setIt = referencingElements->find(referencingElement);
if (setIt == referencingElements->end())
continue;
@@ -330,30 +348,26 @@ void SVGDocumentExtensions::removeAllTargetReferencesForElement(SVGElement* refe
toBeRemoved.append(referencedElement);
}
- Vector<SVGElement*>::iterator vectorEnd = toBeRemoved.end();
- for (Vector<SVGElement*>::iterator it = toBeRemoved.begin(); it != vectorEnd; ++it)
- m_elementDependencies.remove(*it);
+ m_elementDependencies.removeAll(toBeRemoved);
}
void SVGDocumentExtensions::rebuildAllElementReferencesForTarget(SVGElement* referencedElement)
{
ASSERT(referencedElement);
- HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator it = m_elementDependencies.find(referencedElement);
+ ElementDependenciesMap::iterator it = m_elementDependencies.find(referencedElement);
if (it == m_elementDependencies.end())
return;
ASSERT(it->key == referencedElement);
- Vector<SVGElement*> toBeNotified;
- HashSet<SVGElement*>* referencingElements = it->value.get();
- HashSet<SVGElement*>::iterator setEnd = referencingElements->end();
- for (HashSet<SVGElement*>::iterator setIt = referencingElements->begin(); setIt != setEnd; ++setIt)
- toBeNotified.append(*setIt);
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> > toBeNotified;
+ SVGElementSet* referencingElements = it->value.get();
+ copyToVector(*referencingElements, toBeNotified);
// Force rebuilding the referencingElement so it knows about this change.
- Vector<SVGElement*>::iterator vectorEnd = toBeNotified.end();
- for (Vector<SVGElement*>::iterator vectorIt = toBeNotified.begin(); vectorIt != vectorEnd; ++vectorIt) {
+ WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::iterator vectorEnd = toBeNotified.end();
+ for (WillBeHeapVector<RawPtrWillBeMember<SVGElement> >::iterator vectorIt = toBeNotified.begin(); vectorIt != vectorEnd; ++vectorIt) {
// Before rebuilding referencingElement ensure it was not removed from under us.
- if (HashSet<SVGElement*>* referencingElements = setOfElementsReferencingTarget(referencedElement)) {
+ if (SVGElementSet* referencingElements = setOfElementsReferencingTarget(referencedElement)) {
if (referencingElements->contains(*vectorIt))
(*vectorIt)->svgAttributeChanged(XLinkNames::hrefAttr);
}
@@ -363,7 +377,7 @@ void SVGDocumentExtensions::rebuildAllElementReferencesForTarget(SVGElement* ref
void SVGDocumentExtensions::removeAllElementReferencesForTarget(SVGElement* referencedElement)
{
ASSERT(referencedElement);
- HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > >::iterator it = m_elementDependencies.find(referencedElement);
+ ElementDependenciesMap::iterator it = m_elementDependencies.find(referencedElement);
if (it == m_elementDependencies.end())
return;
ASSERT(it->key == referencedElement);
@@ -391,12 +405,12 @@ bool SVGDocumentExtensions::isSVGRootWithRelativeLengthDescendents(SVGSVGElement
void SVGDocumentExtensions::invalidateSVGRootsWithRelativeLengthDescendents(SubtreeLayoutScope* scope)
{
ASSERT(!m_inRelativeLengthSVGRootsInvalidation);
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
TemporaryChange<bool> inRelativeLengthSVGRootsChange(m_inRelativeLengthSVGRootsInvalidation, true);
#endif
- HashSet<SVGSVGElement*>::iterator end = m_relativeLengthSVGRoots.end();
- for (HashSet<SVGSVGElement*>::iterator it = m_relativeLengthSVGRoots.begin(); it != end; ++it)
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGSVGElement> >::iterator end = m_relativeLengthSVGRoots.end();
+ for (WillBeHeapHashSet<RawPtrWillBeMember<SVGSVGElement> >::iterator it = m_relativeLengthSVGRoots.begin(); it != end; ++it)
(*it)->invalidateRelativeLengthClients(scope);
}
@@ -411,6 +425,67 @@ void SVGDocumentExtensions::unregisterSVGFontFaceElement(SVGFontFaceElement* ele
ASSERT(m_svgFontFaceElements.contains(element));
m_svgFontFaceElements.remove(element);
}
+
+void SVGDocumentExtensions::registerPendingSVGFontFaceElementsForRemoval(PassRefPtrWillBeRawPtr<SVGFontFaceElement> font)
+{
+ m_pendingSVGFontFaceElementsForRemoval.add(font);
+}
+
+void SVGDocumentExtensions::removePendingSVGFontFaceElementsForRemoval()
+{
+ m_pendingSVGFontFaceElementsForRemoval.clear();
+}
+
+#endif
+
+bool SVGDocumentExtensions::zoomAndPanEnabled() const
+{
+ if (SVGSVGElement* svg = rootElement(*m_document)) {
+ if (svg->useCurrentView()) {
+ if (svg->currentView())
+ return svg->currentView()->zoomAndPan() == SVGZoomAndPanMagnify;
+ } else {
+ return svg->zoomAndPan() == SVGZoomAndPanMagnify;
+ }
+ }
+
+ return false;
+}
+
+void SVGDocumentExtensions::startPan(const FloatPoint& start)
+{
+ if (SVGSVGElement* svg = rootElement(*m_document))
+ m_translate = FloatPoint(start.x() - svg->currentTranslate().x(), start.y() - svg->currentTranslate().y());
+}
+
+void SVGDocumentExtensions::updatePan(const FloatPoint& pos) const
+{
+ if (SVGSVGElement* svg = rootElement(*m_document))
+ svg->setCurrentTranslate(FloatPoint(pos.x() - m_translate.x(), pos.y() - m_translate.y()));
+}
+
+SVGSVGElement* SVGDocumentExtensions::rootElement(const Document& document)
+{
+ Element* elem = document.documentElement();
+ return isSVGSVGElement(elem) ? toSVGSVGElement(elem) : 0;
+}
+
+SVGSVGElement* SVGDocumentExtensions::rootElement() const
+{
+ ASSERT(m_document);
+ return rootElement(*m_document);
+}
+
+void SVGDocumentExtensions::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+ visitor->trace(m_timeContainers);
+#if ENABLE(SVG_FONTS)
+ visitor->trace(m_svgFontFaceElements);
+ visitor->trace(m_pendingSVGFontFaceElementsForRemoval);
#endif
+ visitor->trace(m_elementDependencies);
+ visitor->trace(m_relativeLengthSVGRoots);
+}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.h b/chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.h
index abf4a68172e..a03d0c5b157 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGDocumentExtensions.h
@@ -21,6 +21,8 @@
#ifndef SVGDocumentExtensions_h
#define SVGDocumentExtensions_h
+#include "platform/geometry/FloatPoint.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
@@ -36,15 +38,16 @@ class SVGElement;
class SVGFontFaceElement;
#endif
class SVGResourcesCache;
-class SVGSMILElement;
class SVGSVGElement;
class Element;
-class SVGDocumentExtensions {
- WTF_MAKE_NONCOPYABLE(SVGDocumentExtensions); WTF_MAKE_FAST_ALLOCATED;
+typedef WillBeHeapHashSet<RawPtrWillBeMember<SVGElement> > SVGElementSet;
+
+class SVGDocumentExtensions : public NoBaseWillBeGarbageCollectedFinalized<SVGDocumentExtensions> {
+ WTF_MAKE_NONCOPYABLE(SVGDocumentExtensions); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
typedef HashSet<Element*> SVGPendingElements;
- SVGDocumentExtensions(Document*);
+ explicit SVGDocumentExtensions(Document*);
~SVGDocumentExtensions();
void addTimeContainer(SVGSVGElement*);
@@ -54,9 +57,10 @@ public:
void removeResource(const AtomicString& id);
RenderSVGResourceContainer* resourceById(const AtomicString& id) const;
+ static void serviceOnAnimationFrame(Document&, double monotonicAnimationStartTime);
+
void startAnimations();
void pauseAnimations();
- void unpauseAnimations();
void dispatchSVGLoadEventToOutermostSVGElements();
void reportWarning(const String&);
@@ -64,7 +68,7 @@ public:
SVGResourcesCache* resourcesCache() const { return m_resourcesCache.get(); }
- HashSet<SVGElement*>* setOfElementsReferencingTarget(SVGElement* referencedElement) const;
+ SVGElementSet* setOfElementsReferencingTarget(SVGElement* referencedElement) const;
void addElementReferencingTarget(SVGElement* referencingElement, SVGElement* referencedElement);
void removeAllTargetReferencesForElement(SVGElement*);
void rebuildAllElementReferencesForTarget(SVGElement*);
@@ -76,24 +80,41 @@ public:
void invalidateSVGRootsWithRelativeLengthDescendents(SubtreeLayoutScope*);
#if ENABLE(SVG_FONTS)
- const HashSet<SVGFontFaceElement*>& svgFontFaceElements() const { return m_svgFontFaceElements; }
+ const WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> >& svgFontFaceElements() const { return m_svgFontFaceElements; }
void registerSVGFontFaceElement(SVGFontFaceElement*);
void unregisterSVGFontFaceElement(SVGFontFaceElement*);
+
+ void registerPendingSVGFontFaceElementsForRemoval(PassRefPtrWillBeRawPtr<SVGFontFaceElement>);
+ void removePendingSVGFontFaceElementsForRemoval();
#endif
+ bool zoomAndPanEnabled() const;
+
+ void startPan(const FloatPoint& start);
+ void updatePan(const FloatPoint& pos) const;
+
+ static SVGSVGElement* rootElement(const Document&);
+ SVGSVGElement* rootElement() const;
+
+ void trace(Visitor*);
+
private:
- Document* m_document; // weak reference
- HashSet<SVGSVGElement*> m_timeContainers; // For SVG 1.2 support this will need to be made more general.
+ RawPtrWillBeMember<Document> m_document;
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGSVGElement> > m_timeContainers; // For SVG 1.2 support this will need to be made more general.
#if ENABLE(SVG_FONTS)
- HashSet<SVGFontFaceElement*> m_svgFontFaceElements;
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGFontFaceElement> > m_svgFontFaceElements;
+ // SVGFontFaceElements that are pending and scheduled for removal.
+ WillBeHeapHashSet<RefPtrWillBeMember<SVGFontFaceElement> > m_pendingSVGFontFaceElementsForRemoval;
#endif
HashMap<AtomicString, RenderSVGResourceContainer*> m_resources;
HashMap<AtomicString, OwnPtr<SVGPendingElements> > m_pendingResources; // Resources that are pending.
HashMap<AtomicString, OwnPtr<SVGPendingElements> > m_pendingResourcesForRemoval; // Resources that are pending and scheduled for removal.
- HashMap<SVGElement*, OwnPtr<HashSet<SVGElement*> > > m_elementDependencies;
+ typedef WillBeHeapHashMap<RawPtrWillBeMember<SVGElement>, OwnPtrWillBeMember<SVGElementSet> > ElementDependenciesMap;
+ ElementDependenciesMap m_elementDependencies;
OwnPtr<SVGResourcesCache> m_resourcesCache;
- HashSet<SVGSVGElement*> m_relativeLengthSVGRoots; // Root SVG elements with relative length descendants.
-#if !ASSERT_DISABLED
+ WillBeHeapHashSet<RawPtrWillBeMember<SVGSVGElement> > m_relativeLengthSVGRoots; // Root SVG elements with relative length descendants.
+ FloatPoint m_translate;
+#if ASSERT_ENABLED
bool m_inRelativeLengthSVGRootsInvalidation;
#endif
@@ -109,6 +130,8 @@ public:
void removeElementFromPendingResources(Element*);
PassOwnPtr<SVGPendingElements> removePendingResource(const AtomicString& id);
+ void serviceAnimations(double monotonicAnimationStartTime);
+
// The following two functions are used for scheduling a pending resource to be removed.
void markPendingResourcesForRemoval(const AtomicString&);
Element* removeElementFromPendingResourcesForRemoval(const AtomicString&);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGElement.cpp
index 0ab482d46c4..fddac6d6e4d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGElement.cpp
@@ -25,113 +25,112 @@
#include "core/svg/SVGElement.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
-#include "XMLNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
+#include "core/XLinkNames.h"
+#include "core/XMLNames.h"
#include "core/css/CSSCursorImageValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/parser/BisonCSSParser.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
-#include "core/events/Event.h"
#include "core/dom/shadow/ShadowRoot.h"
+#include "core/events/Event.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLElement.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/svg/RenderSVGResourceContainer.h"
#include "core/svg/SVGCursorElement.h"
#include "core/svg/SVGDocumentExtensions.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGElementRareData.h"
#include "core/svg/SVGGraphicsElement.h"
#include "core/svg/SVGSVGElement.h"
+#include "core/svg/SVGTitleElement.h"
#include "core/svg/SVGUseElement.h"
#include "wtf/TemporaryChange.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGElement, HTMLNames::classAttr, ClassName, className)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(className)
-END_REGISTER_ANIMATED_PROPERTIES
-
using namespace HTMLNames;
using namespace SVGNames;
void mapAttributeToCSSProperty(HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName)
{
// FIXME: when CSS supports "transform-origin" the special case for transform_originAttr can be removed.
+ // FIXME: It's not clear the above is strictly true, as -webkit-transform-origin has non-standard behavior.
CSSPropertyID propertyId = cssPropertyID(attrName.localName());
- if (!propertyId && attrName == transform_originAttr)
+ if (!propertyId && attrName == transform_originAttr) {
propertyId = CSSPropertyWebkitTransformOrigin; // cssPropertyID("-webkit-transform-origin")
+ } else if (propertyId == CSSPropertyTransformOrigin) {
+ propertyId = CSSPropertyWebkitTransformOrigin;
+ }
ASSERT(propertyId > 0);
propertyNameToIdMap->set(attrName.localName().impl(), propertyId);
}
SVGElement::SVGElement(const QualifiedName& tagName, Document& document, ConstructionType constructionType)
: Element(tagName, &document, constructionType)
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
, m_inRelativeLengthClientsInvalidation(false)
#endif
- , m_animatedPropertiesDestructed(false)
+ // |m_isContextElement| must be initialized before |m_className|, as SVGAnimatedString tear-off c-tor currently set this to true.
, m_isContextElement(false)
+ , m_SVGRareData(nullptr)
+ , m_className(SVGAnimatedString::create(this, HTMLNames::classAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGElement();
+ addToPropertyMap(m_className);
setHasCustomStyleCallbacks();
}
SVGElement::~SVGElement()
{
ASSERT(inDocument() || !hasRelativeLengths());
+
+ // The below teardown is all handled by weak pointer processing in oilpan.
+#if !ENABLE(OILPAN)
+ if (hasSVGRareData()) {
+ if (SVGCursorElement* cursorElement = svgRareData()->cursorElement())
+ cursorElement->removeReferencedElement(this);
+ if (CSSCursorImageValue* cursorImageValue = svgRareData()->cursorImageValue())
+ cursorImageValue->removeReferencedElement(this);
+ // Clear the rare data now so that we are in a consistent state when
+ // calling rebuildAllElementReferencesForTarget() below.
+ m_SVGRareData.clear();
+ }
+
+ // With Oilpan, either removedFrom has been called or the document is dead
+ // as well and there is no reason to clear out the references.
+ document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
+ document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
+#endif
}
-void
-SVGElement::cleanupAnimatedProperties()
+void SVGElement::detach(const AttachContext& context)
{
- if (m_animatedPropertiesDestructed)
- return;
- m_animatedPropertiesDestructed = true;
-
- if (!hasSVGRareData())
- ASSERT(!SVGElementRareData::rareDataMap().contains(this));
- else {
- SVGElementRareData::SVGElementRareDataMap& rareDataMap = SVGElementRareData::rareDataMap();
- SVGElementRareData::SVGElementRareDataMap::iterator it = rareDataMap.find(this);
- ASSERT_WITH_SECURITY_IMPLICATION(it != rareDataMap.end());
-
- SVGElementRareData* rareData = it->value;
- rareData->destroyAnimatedSMILStyleProperties();
- if (SVGCursorElement* cursorElement = rareData->cursorElement())
- cursorElement->removeClient(this);
- if (CSSCursorImageValue* cursorImageValue = rareData->cursorImageValue())
- cursorImageValue->removeReferencedElement(this);
+ Element::detach(context);
+ if (SVGElement* element = correspondingElement())
+ element->removeInstanceMapping(this);
+}
- delete rareData;
+void SVGElement::attach(const AttachContext& context)
+{
+ Element::attach(context);
+ if (SVGElement* element = correspondingElement())
+ element->mapInstanceToElement(this);
+}
- // The rare data cleanup may have caused other SVG nodes to be deleted,
- // modifying the rare data map. Do not rely on the existing iterator.
- ASSERT(rareDataMap.contains(this));
- rareDataMap.remove(this);
- // Clear HasSVGRareData flag now so that we are in a consistent state when
- // calling rebuildAllElementReferencesForTarget() and
- // removeAllElementReferencesForTarget() below.
- clearHasSVGRareData();
- }
- document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
- document().accessSVGExtensions()->removeAllElementReferencesForTarget(this);
- SVGAnimatedProperty::detachAnimatedPropertiesForElement(this);
+short SVGElement::tabIndex() const
+{
+ if (supportsFocus())
+ return Element::tabIndex();
+ return -1;
}
void SVGElement::willRecalcStyle(StyleRecalcChange change)
{
- // FIXME: This assumes that when shouldNotifyRendererWithIdenticalStyles() is true
- // the change came from a SMIL animation, but what if there were non-SMIL changes
- // since then? I think we should remove the shouldNotifyRendererWithIdenticalStyles
- // check.
- if (!hasSVGRareData() || shouldNotifyRendererWithIdenticalStyles())
+ if (!hasSVGRareData())
return;
// If the style changes because of a regular property change (not induced by SMIL animations themselves)
// reset the "computed style without SMIL style properties", so the base value change gets reflected.
@@ -142,23 +141,29 @@ void SVGElement::willRecalcStyle(StyleRecalcChange change)
void SVGElement::buildPendingResourcesIfNeeded()
{
Document& document = this->document();
- if (!needsPendingResourceHandling() || !inDocument() || isInShadowTree())
+ if (!needsPendingResourceHandling() || !inDocument() || inUseShadowTree())
return;
- SVGDocumentExtensions* extensions = document.accessSVGExtensions();
- String resourceId = getIdAttribute();
- if (!extensions->hasPendingResource(resourceId))
+ SVGDocumentExtensions& extensions = document.accessSVGExtensions();
+ AtomicString resourceId = getIdAttribute();
+ if (!extensions.hasPendingResource(resourceId))
return;
// Mark pending resources as pending for removal.
- extensions->markPendingResourcesForRemoval(resourceId);
+ extensions.markPendingResourcesForRemoval(resourceId);
// Rebuild pending resources for each client of a pending resource that is being removed.
- while (Element* clientElement = extensions->removeElementFromPendingResourcesForRemoval(resourceId)) {
+ while (Element* clientElement = extensions.removeElementFromPendingResourcesForRemoval(resourceId)) {
ASSERT(clientElement->hasPendingResources());
if (clientElement->hasPendingResources()) {
- clientElement->buildPendingResource();
- extensions->clearHasPendingResourcesIfPossible(clientElement);
+ // FIXME: Ideally we'd always resolve pending resources async instead of inside
+ // insertedInto and svgAttributeChanged. For now we only do it for <use> since
+ // that would stamp out DOM.
+ if (isSVGUseElement(clientElement))
+ toSVGUseElement(clientElement)->invalidateShadowTree();
+ else
+ clientElement->buildPendingResource();
+ extensions.clearHasPendingResourcesIfPossible(clientElement);
}
}
}
@@ -176,27 +181,18 @@ bool SVGElement::rendererIsNeeded(const RenderStyle& style)
return false;
}
-SVGElementRareData* SVGElement::svgRareData() const
-{
- ASSERT(hasSVGRareData());
- return SVGElementRareData::rareDataFromMap(this);
-}
-
SVGElementRareData* SVGElement::ensureSVGRareData()
{
if (hasSVGRareData())
return svgRareData();
- ASSERT(!SVGElementRareData::rareDataMap().contains(this));
- SVGElementRareData* data = new SVGElementRareData;
- SVGElementRareData::rareDataMap().set(this, data);
- setHasSVGRareData();
- return data;
+ m_SVGRareData = adoptPtrWillBeNoop(new SVGElementRareData(this));
+ return m_SVGRareData.get();
}
bool SVGElement::isOutermostSVGSVGElement() const
{
- if (!hasTagName(SVGNames::svgTag))
+ if (!isSVGSVGElement(*this))
return false;
// Element may not be in the document, pretend we're outermost for viewport(), getCTM(), etc.
@@ -204,13 +200,13 @@ bool SVGElement::isOutermostSVGSVGElement() const
return true;
// We act like an outermost SVG element, if we're a direct child of a <foreignObject> element.
- if (parentNode()->hasTagName(SVGNames::foreignObjectTag))
+ if (isSVGForeignObjectElement(*parentNode()))
return true;
// If we're living in a shadow tree, we're a <svg> element that got created as replacement
// for a <symbol> element or a cloned <svg> element in the referenced tree. In that case
// we're always an inner <svg> element.
- if (isInShadowTree() && parentOrShadowHostElement() && parentOrShadowHostElement()->isSVGElement())
+ if (inUseShadowTree() && parentOrShadowHostElement() && parentOrShadowHostElement()->isSVGElement())
return false;
// This is true whenever this is the outermost SVG, even if there are HTML elements outside it
@@ -223,15 +219,15 @@ void SVGElement::reportAttributeParsingError(SVGParsingError error, const Qualif
return;
String errorString = "<" + tagName() + "> attribute " + name.toString() + "=\"" + value + "\"";
- SVGDocumentExtensions* extensions = document().accessSVGExtensions();
+ SVGDocumentExtensions& extensions = document().accessSVGExtensions();
if (error == NegativeValueForbiddenError) {
- extensions->reportError("Invalid negative value for " + errorString);
+ extensions.reportError("Invalid negative value for " + errorString);
return;
}
if (error == ParsingAttributeFailedError) {
- extensions->reportError("Invalid value for " + errorString);
+ extensions.reportError("Invalid value for " + errorString);
return;
}
@@ -245,57 +241,22 @@ String SVGElement::title() const
if (isOutermostSVGSVGElement())
return String();
- // Walk up the tree, to find out whether we're inside a <use> shadow tree, to find the right title.
- if (isInShadowTree()) {
- Element* shadowHostElement = toShadowRoot(treeScope().rootNode())->host();
- // At this time, SVG nodes are not allowed in non-<use> shadow trees, so any shadow root we do
- // have should be a use. The assert and following test is here to catch future shadow DOM changes
- // that do enable SVG in a shadow tree.
- ASSERT(!shadowHostElement || shadowHostElement->hasTagName(SVGNames::useTag));
- if (shadowHostElement && shadowHostElement->hasTagName(SVGNames::useTag)) {
- SVGUseElement* useElement = toSVGUseElement(shadowHostElement);
-
- // If the <use> title is not empty we found the title to use.
- String useTitle(useElement->title());
- if (!useTitle.isEmpty())
- return useTitle;
- }
+ if (inUseShadowTree()) {
+ String useTitle(shadowHost()->title());
+ if (!useTitle.isEmpty())
+ return useTitle;
}
// If we aren't an instance in a <use> or the <use> title was not found, then find the first
// <title> child of this element.
- Element* titleElement = ElementTraversal::firstWithin(*this);
- for (; titleElement; titleElement = ElementTraversal::nextSkippingChildren(*titleElement, this)) {
- if (titleElement->hasTagName(SVGNames::titleTag) && titleElement->isSVGElement())
- break;
- }
-
// If a title child was found, return the text contents.
- if (titleElement)
+ if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this))
return titleElement->innerText();
// Otherwise return a null/empty string.
return String();
}
-PassRefPtr<CSSValue> SVGElement::getPresentationAttribute(const String& name)
-{
- if (!hasAttributesWithoutUpdate())
- return 0;
-
- QualifiedName attributeName(nullAtom, name, nullAtom);
- const Attribute* attr = getAttributeItem(attributeName);
- if (!attr)
- return 0;
-
- RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create(SVGAttributeMode);
- CSSPropertyID propertyID = SVGElement::cssPropertyIdForSVGAttributeName(attr->name());
- style->setProperty(propertyID, attr->value());
- RefPtr<CSSValue> cssValue = style->getPropertyCSSValue(propertyID);
- return cssValue ? cssValue->cloneForCSSOM() : 0;
-}
-
-
bool SVGElement::instanceUpdatesBlocked() const
{
return hasSVGRareData() && svgRareData()->instanceUpdatesBlocked();
@@ -313,32 +274,32 @@ AffineTransform SVGElement::localCoordinateSpaceTransform(CTMScope) const
return AffineTransform();
}
-String SVGElement::xmlbase() const
+const AtomicString& SVGElement::xmlbase() const
{
return fastGetAttribute(XMLNames::baseAttr);
}
-void SVGElement::setXMLbase(const String& value)
+void SVGElement::setXMLbase(const AtomicString& value)
{
setAttribute(XMLNames::baseAttr, value);
}
-String SVGElement::xmllang() const
+const AtomicString& SVGElement::xmllang() const
{
return fastGetAttribute(XMLNames::langAttr);
}
-void SVGElement::setXMLlang(const String& value)
+void SVGElement::setXMLlang(const AtomicString& value)
{
setAttribute(XMLNames::langAttr, value);
}
-String SVGElement::xmlspace() const
+const AtomicString& SVGElement::xmlspace() const
{
return fastGetAttribute(XMLNames::spaceAttr);
}
-void SVGElement::setXMLspace(const String& value)
+void SVGElement::setXMLspace(const AtomicString& value)
{
setAttribute(XMLNames::spaceAttr, value);
}
@@ -372,20 +333,20 @@ void SVGElement::removedFrom(ContainerNode* rootParent)
Element::removedFrom(rootParent);
if (wasInDocument) {
- document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
- document().accessSVGExtensions()->removeAllElementReferencesForTarget(this);
+ document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
+ document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
}
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
}
void SVGElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
Element::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- // Invalidate all SVGElementInstances associated with us.
+ // Invalidate all instances associated with us.
if (!changedByParser)
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
}
CSSPropertyID SVGElement::cssPropertyIdForSVGAttributeName(const QualifiedName& attrName)
@@ -406,7 +367,6 @@ CSSPropertyID SVGElement::cssPropertyIdForSVGAttributeName(const QualifiedName&
mapAttributeToCSSProperty(propertyNameToIdMap, SVGNames::colorAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolationAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolation_filtersAttr);
- mapAttributeToCSSProperty(propertyNameToIdMap, color_profileAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, color_renderingAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, cursorAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, SVGNames::directionAttr);
@@ -428,7 +388,6 @@ CSSPropertyID SVGElement::cssPropertyIdForSVGAttributeName(const QualifiedName&
mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_horizontalAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_verticalAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, image_renderingAttr);
- mapAttributeToCSSProperty(propertyNameToIdMap, kerningAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, letter_spacingAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, lighting_colorAttr);
mapAttributeToCSSProperty(propertyNameToIdMap, marker_endAttr);
@@ -495,12 +454,12 @@ void SVGElement::updateRelativeLengthsInformation(bool clientHasRelativeLengths,
}
// Register root SVG elements for top level viewport change notifications.
- if (clientElement->isSVGSVGElement()) {
- SVGDocumentExtensions* svgExtensions = accessDocumentSVGExtensions();
+ if (isSVGSVGElement(*clientElement)) {
+ SVGDocumentExtensions& svgExtensions = accessDocumentSVGExtensions();
if (clientElement->hasRelativeLengths())
- svgExtensions->addSVGRootWithRelativeLengthDescendents(toSVGSVGElement(clientElement));
+ svgExtensions.addSVGRootWithRelativeLengthDescendents(toSVGSVGElement(clientElement));
else
- svgExtensions->removeSVGRootWithRelativeLengthDescendents(toSVGSVGElement(clientElement));
+ svgExtensions.removeSVGRootWithRelativeLengthDescendents(toSVGSVGElement(clientElement));
}
}
@@ -510,7 +469,7 @@ void SVGElement::invalidateRelativeLengthClients(SubtreeLayoutScope* layoutScope
return;
ASSERT(!m_inRelativeLengthClientsInvalidation);
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
TemporaryChange<bool> inRelativeLengthClientsInvalidationChange(m_inRelativeLengthClientsInvalidation, true);
#endif
@@ -519,11 +478,11 @@ void SVGElement::invalidateRelativeLengthClients(SubtreeLayoutScope* layoutScope
if (renderer->isSVGResourceContainer())
toRenderSVGResourceContainer(renderer)->invalidateCacheAndMarkForLayout(layoutScope);
else
- renderer->setNeedsLayout(MarkContainingBlockChain, layoutScope);
+ renderer->setNeedsLayoutAndFullPaintInvalidation(MarkContainingBlockChain, layoutScope);
}
- HashSet<SVGElement*>::iterator end = m_elementsWithRelativeLengths.end();
- for (HashSet<SVGElement*>::iterator it = m_elementsWithRelativeLengths.begin(); it != end; ++it) {
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::iterator end = m_elementsWithRelativeLengths.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::iterator it = m_elementsWithRelativeLengths.begin(); it != end; ++it) {
if (*it != this)
(*it)->invalidateRelativeLengthClients(layoutScope);
}
@@ -533,7 +492,7 @@ SVGSVGElement* SVGElement::ownerSVGElement() const
{
ContainerNode* n = parentOrShadowHostNode();
while (n) {
- if (n->hasTagName(SVGNames::svgTag))
+ if (isSVGSVGElement(*n))
return toSVGSVGElement(n);
n = n->parentOrShadowHostNode();
@@ -548,7 +507,7 @@ SVGElement* SVGElement::viewportElement() const
// to determine the "overflow" property. <use> on <symbol> wouldn't work otherwhise.
ContainerNode* n = parentOrShadowHostNode();
while (n) {
- if (n->hasTagName(SVGNames::svgTag) || n->hasTagName(SVGNames::imageTag) || n->hasTagName(SVGNames::symbolTag))
+ if (isSVGSVGElement(*n) || isSVGImageElement(*n) || isSVGSymbolElement(*n))
return toSVGElement(n);
n = n->parentOrShadowHostNode();
@@ -557,40 +516,53 @@ SVGElement* SVGElement::viewportElement() const
return 0;
}
-SVGDocumentExtensions* SVGElement::accessDocumentSVGExtensions()
+SVGDocumentExtensions& SVGElement::accessDocumentSVGExtensions()
{
// This function is provided for use by SVGAnimatedProperty to avoid
// global inclusion of core/dom/Document.h in SVG code.
return document().accessSVGExtensions();
}
-void SVGElement::mapInstanceToElement(SVGElementInstance* instance)
+void SVGElement::mapInstanceToElement(SVGElement* instance)
{
ASSERT(instance);
+ ASSERT(instance->inUseShadowTree());
- HashSet<SVGElementInstance*>& instances = ensureSVGRareData()->elementInstances();
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = ensureSVGRareData()->elementInstances();
ASSERT(!instances.contains(instance));
instances.add(instance);
}
-void SVGElement::removeInstanceMapping(SVGElementInstance* instance)
+void SVGElement::removeInstanceMapping(SVGElement* instance)
{
ASSERT(instance);
- ASSERT(hasSVGRareData());
+ ASSERT(instance->inUseShadowTree());
- HashSet<SVGElementInstance*>& instances = svgRareData()->elementInstances();
+ if (!hasSVGRareData())
+ return;
+
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = svgRareData()->elementInstances();
ASSERT(instances.contains(instance));
instances.remove(instance);
}
-const HashSet<SVGElementInstance*>& SVGElement::instancesForElement() const
+static WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& emptyInstances()
{
- if (!hasSVGRareData()) {
- DEFINE_STATIC_LOCAL(HashSet<SVGElementInstance*>, emptyInstances, ());
- return emptyInstances;
- }
+#if ENABLE(OILPAN)
+ DEFINE_STATIC_LOCAL(Persistent<HeapHashSet<WeakMember<SVGElement> > >, emptyInstances, (new HeapHashSet<WeakMember<SVGElement> >));
+ return *emptyInstances;
+#else
+ DEFINE_STATIC_LOCAL(HashSet<RawPtr<SVGElement> >, emptyInstances, ());
+ return emptyInstances;
+#endif
+}
+
+const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& SVGElement::instancesForElement() const
+{
+ if (!hasSVGRareData())
+ return emptyInstances();
return svgRareData()->elementInstances();
}
@@ -614,28 +586,32 @@ void SVGElement::setCursorElement(SVGCursorElement* cursorElement)
rareData->setCursorElement(cursorElement);
}
+#if !ENABLE(OILPAN)
void SVGElement::cursorElementRemoved()
{
- ASSERT(hasSVGRareData());
svgRareData()->setCursorElement(0);
}
+#endif
void SVGElement::setCursorImageValue(CSSCursorImageValue* cursorImageValue)
{
SVGElementRareData* rareData = ensureSVGRareData();
+#if !ENABLE(OILPAN)
if (CSSCursorImageValue* oldCursorImageValue = rareData->cursorImageValue()) {
if (cursorImageValue == oldCursorImageValue)
return;
oldCursorImageValue->removeReferencedElement(this);
}
+#endif
rareData->setCursorImageValue(cursorImageValue);
}
+#if !ENABLE(OILPAN)
void SVGElement::cursorImageValueRemoved()
{
- ASSERT(hasSVGRareData());
svgRareData()->setCursorImageValue(0);
}
+#endif
SVGElement* SVGElement::correspondingElement()
{
@@ -643,137 +619,152 @@ SVGElement* SVGElement::correspondingElement()
return hasSVGRareData() ? svgRareData()->correspondingElement() : 0;
}
+SVGUseElement* SVGElement::correspondingUseElement() const
+{
+ if (ShadowRoot* root = containingShadowRoot()) {
+ if (isSVGUseElement(root->host()) && (root->type() == ShadowRoot::UserAgentShadowRoot))
+ return toSVGUseElement(root->host());
+ }
+ return 0;
+}
+
void SVGElement::setCorrespondingElement(SVGElement* correspondingElement)
{
ensureSVGRareData()->setCorrespondingElement(correspondingElement);
}
+bool SVGElement::inUseShadowTree() const
+{
+ return correspondingUseElement();
+}
+
+bool SVGElement::supportsSpatialNavigationFocus() const
+{
+ // This function checks whether the element satisfies the extended criteria
+ // for the element to be focusable, introduced by spatial navigation feature,
+ // i.e. checks if click or keyboard event handler is specified.
+ // This is the way to make it possible to navigate to (focus) elements
+ // which web designer meant for being active (made them respond to click events).
+
+ if (!document().settings() || !document().settings()->spatialNavigationEnabled())
+ return false;
+ return hasEventListeners(EventTypeNames::click)
+ || hasEventListeners(EventTypeNames::keydown)
+ || hasEventListeners(EventTypeNames::keypress)
+ || hasEventListeners(EventTypeNames::keyup)
+ || hasEventListeners(EventTypeNames::focus)
+ || hasEventListeners(EventTypeNames::blur)
+ || hasEventListeners(EventTypeNames::focusin)
+ || hasEventListeners(EventTypeNames::focusout);
+}
+
void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- // standard events
- if (name == onloadAttr)
- setAttributeEventListener(EventTypeNames::load, createAttributeEventListener(this, name, value));
- else if (name == onbeginAttr)
- setAttributeEventListener(EventTypeNames::beginEvent, createAttributeEventListener(this, name, value));
- else if (name == onendAttr)
- setAttributeEventListener(EventTypeNames::endEvent, createAttributeEventListener(this, name, value));
- else if (name == onrepeatAttr)
- setAttributeEventListener(EventTypeNames::repeatEvent, createAttributeEventListener(this, name, value));
- else if (name == onclickAttr)
- setAttributeEventListener(EventTypeNames::click, createAttributeEventListener(this, name, value));
- else if (name == onmousedownAttr)
- setAttributeEventListener(EventTypeNames::mousedown, createAttributeEventListener(this, name, value));
- else if (name == onmouseenterAttr)
- setAttributeEventListener(EventTypeNames::mouseenter, createAttributeEventListener(this, name, value));
- else if (name == onmouseleaveAttr)
- setAttributeEventListener(EventTypeNames::mouseleave, createAttributeEventListener(this, name, value));
- else if (name == onmousemoveAttr)
- setAttributeEventListener(EventTypeNames::mousemove, createAttributeEventListener(this, name, value));
- else if (name == onmouseoutAttr)
- setAttributeEventListener(EventTypeNames::mouseout, createAttributeEventListener(this, name, value));
- else if (name == onmouseoverAttr)
- setAttributeEventListener(EventTypeNames::mouseover, createAttributeEventListener(this, name, value));
- else if (name == onmouseupAttr)
- setAttributeEventListener(EventTypeNames::mouseup, createAttributeEventListener(this, name, value));
- else if (name == SVGNames::onfocusinAttr)
- setAttributeEventListener(EventTypeNames::focusin, createAttributeEventListener(this, name, value));
- else if (name == SVGNames::onfocusoutAttr)
- setAttributeEventListener(EventTypeNames::focusout, createAttributeEventListener(this, name, value));
- else if (name == SVGNames::onactivateAttr)
- setAttributeEventListener(EventTypeNames::DOMActivate, createAttributeEventListener(this, name, value));
- else if (name == HTMLNames::classAttr) {
+ if (name == HTMLNames::classAttr) {
// SVG animation has currently requires special storage of values so we set
// the className here. svgAttributeChanged actually causes the resulting
// style updates (instead of Element::parseAttribute). We don't
// tell Element about the change to avoid parsing the class list twice
- setClassNameBaseValue(value);
+ SVGParsingError parseError = NoError;
+ m_className->setBaseValueAsString(value, parseError);
+ reportAttributeParsingError(parseError, name, value);
} else if (name.matches(XMLNames::langAttr) || name.matches(XMLNames::spaceAttr)) {
- } else
+ } else if (name == tabindexAttr) {
Element::parseAttribute(name, value);
+ } else {
+ // standard events
+ const AtomicString& eventName = HTMLElement::eventNameForAttributeName(name);
+ if (!eventName.isNull())
+ setAttributeEventListener(eventName, createAttributeEventListener(this, name, value, eventParameterName()));
+ else
+ Element::parseAttribute(name, value);
+ }
}
typedef HashMap<QualifiedName, AnimatedPropertyType> AttributeToPropertyTypeMap;
-static inline AttributeToPropertyTypeMap& cssPropertyToTypeMap()
-{
- DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_cssPropertyMap, ());
-
- if (!s_cssPropertyMap.isEmpty())
- return s_cssPropertyMap;
-
- // Fill the map for the first use.
- s_cssPropertyMap.set(alignment_baselineAttr, AnimatedString);
- s_cssPropertyMap.set(baseline_shiftAttr, AnimatedString);
- s_cssPropertyMap.set(buffered_renderingAttr, AnimatedString);
- s_cssPropertyMap.set(clipAttr, AnimatedRect);
- s_cssPropertyMap.set(clip_pathAttr, AnimatedString);
- s_cssPropertyMap.set(clip_ruleAttr, AnimatedString);
- s_cssPropertyMap.set(SVGNames::colorAttr, AnimatedColor);
- s_cssPropertyMap.set(color_interpolationAttr, AnimatedString);
- s_cssPropertyMap.set(color_interpolation_filtersAttr, AnimatedString);
- s_cssPropertyMap.set(color_profileAttr, AnimatedString);
- s_cssPropertyMap.set(color_renderingAttr, AnimatedString);
- s_cssPropertyMap.set(cursorAttr, AnimatedString);
- s_cssPropertyMap.set(displayAttr, AnimatedString);
- s_cssPropertyMap.set(dominant_baselineAttr, AnimatedString);
- s_cssPropertyMap.set(fillAttr, AnimatedColor);
- s_cssPropertyMap.set(fill_opacityAttr, AnimatedNumber);
- s_cssPropertyMap.set(fill_ruleAttr, AnimatedString);
- s_cssPropertyMap.set(filterAttr, AnimatedString);
- s_cssPropertyMap.set(flood_colorAttr, AnimatedColor);
- s_cssPropertyMap.set(flood_opacityAttr, AnimatedNumber);
- s_cssPropertyMap.set(font_familyAttr, AnimatedString);
- s_cssPropertyMap.set(font_sizeAttr, AnimatedLength);
- s_cssPropertyMap.set(font_stretchAttr, AnimatedString);
- s_cssPropertyMap.set(font_styleAttr, AnimatedString);
- s_cssPropertyMap.set(font_variantAttr, AnimatedString);
- s_cssPropertyMap.set(font_weightAttr, AnimatedString);
- s_cssPropertyMap.set(image_renderingAttr, AnimatedString);
- s_cssPropertyMap.set(kerningAttr, AnimatedLength);
- s_cssPropertyMap.set(letter_spacingAttr, AnimatedLength);
- s_cssPropertyMap.set(lighting_colorAttr, AnimatedColor);
- s_cssPropertyMap.set(marker_endAttr, AnimatedString);
- s_cssPropertyMap.set(marker_midAttr, AnimatedString);
- s_cssPropertyMap.set(marker_startAttr, AnimatedString);
- s_cssPropertyMap.set(maskAttr, AnimatedString);
- s_cssPropertyMap.set(mask_typeAttr, AnimatedString);
- s_cssPropertyMap.set(opacityAttr, AnimatedNumber);
- s_cssPropertyMap.set(overflowAttr, AnimatedString);
- s_cssPropertyMap.set(paint_orderAttr, AnimatedString);
- s_cssPropertyMap.set(pointer_eventsAttr, AnimatedString);
- s_cssPropertyMap.set(shape_renderingAttr, AnimatedString);
- s_cssPropertyMap.set(stop_colorAttr, AnimatedColor);
- s_cssPropertyMap.set(stop_opacityAttr, AnimatedNumber);
- s_cssPropertyMap.set(strokeAttr, AnimatedColor);
- s_cssPropertyMap.set(stroke_dasharrayAttr, AnimatedLengthList);
- s_cssPropertyMap.set(stroke_dashoffsetAttr, AnimatedLength);
- s_cssPropertyMap.set(stroke_linecapAttr, AnimatedString);
- s_cssPropertyMap.set(stroke_linejoinAttr, AnimatedString);
- s_cssPropertyMap.set(stroke_miterlimitAttr, AnimatedNumber);
- s_cssPropertyMap.set(stroke_opacityAttr, AnimatedNumber);
- s_cssPropertyMap.set(stroke_widthAttr, AnimatedLength);
- s_cssPropertyMap.set(text_anchorAttr, AnimatedString);
- s_cssPropertyMap.set(text_decorationAttr, AnimatedString);
- s_cssPropertyMap.set(text_renderingAttr, AnimatedString);
- s_cssPropertyMap.set(vector_effectAttr, AnimatedString);
- s_cssPropertyMap.set(visibilityAttr, AnimatedString);
- s_cssPropertyMap.set(word_spacingAttr, AnimatedLength);
- return s_cssPropertyMap;
-}
-
-void SVGElement::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes)
-{
- localAttributeToPropertyMap().animatedPropertyTypeForAttribute(attributeName, propertyTypes);
- if (!propertyTypes.isEmpty())
- return;
+AnimatedPropertyType SVGElement::animatedPropertyTypeForCSSAttribute(const QualifiedName& attributeName)
+{
+ DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, cssPropertyMap, ());
+
+ if (cssPropertyMap.isEmpty()) {
+ // Fill the map for the first use.
+ cssPropertyMap.set(alignment_baselineAttr, AnimatedString);
+ cssPropertyMap.set(baseline_shiftAttr, AnimatedString);
+ cssPropertyMap.set(buffered_renderingAttr, AnimatedString);
+ cssPropertyMap.set(clipAttr, AnimatedRect);
+ cssPropertyMap.set(clip_pathAttr, AnimatedString);
+ cssPropertyMap.set(clip_ruleAttr, AnimatedString);
+ cssPropertyMap.set(SVGNames::colorAttr, AnimatedColor);
+ cssPropertyMap.set(color_interpolationAttr, AnimatedString);
+ cssPropertyMap.set(color_interpolation_filtersAttr, AnimatedString);
+ cssPropertyMap.set(color_renderingAttr, AnimatedString);
+ cssPropertyMap.set(cursorAttr, AnimatedString);
+ cssPropertyMap.set(displayAttr, AnimatedString);
+ cssPropertyMap.set(dominant_baselineAttr, AnimatedString);
+ cssPropertyMap.set(fillAttr, AnimatedColor);
+ cssPropertyMap.set(fill_opacityAttr, AnimatedNumber);
+ cssPropertyMap.set(fill_ruleAttr, AnimatedString);
+ cssPropertyMap.set(filterAttr, AnimatedString);
+ cssPropertyMap.set(flood_colorAttr, AnimatedColor);
+ cssPropertyMap.set(flood_opacityAttr, AnimatedNumber);
+ cssPropertyMap.set(font_familyAttr, AnimatedString);
+ cssPropertyMap.set(font_sizeAttr, AnimatedLength);
+ cssPropertyMap.set(font_stretchAttr, AnimatedString);
+ cssPropertyMap.set(font_styleAttr, AnimatedString);
+ cssPropertyMap.set(font_variantAttr, AnimatedString);
+ cssPropertyMap.set(font_weightAttr, AnimatedString);
+ cssPropertyMap.set(image_renderingAttr, AnimatedString);
+ cssPropertyMap.set(letter_spacingAttr, AnimatedLength);
+ cssPropertyMap.set(lighting_colorAttr, AnimatedColor);
+ cssPropertyMap.set(marker_endAttr, AnimatedString);
+ cssPropertyMap.set(marker_midAttr, AnimatedString);
+ cssPropertyMap.set(marker_startAttr, AnimatedString);
+ cssPropertyMap.set(maskAttr, AnimatedString);
+ cssPropertyMap.set(mask_typeAttr, AnimatedString);
+ cssPropertyMap.set(opacityAttr, AnimatedNumber);
+ cssPropertyMap.set(overflowAttr, AnimatedString);
+ cssPropertyMap.set(paint_orderAttr, AnimatedString);
+ cssPropertyMap.set(pointer_eventsAttr, AnimatedString);
+ cssPropertyMap.set(shape_renderingAttr, AnimatedString);
+ cssPropertyMap.set(stop_colorAttr, AnimatedColor);
+ cssPropertyMap.set(stop_opacityAttr, AnimatedNumber);
+ cssPropertyMap.set(strokeAttr, AnimatedColor);
+ cssPropertyMap.set(stroke_dasharrayAttr, AnimatedLengthList);
+ cssPropertyMap.set(stroke_dashoffsetAttr, AnimatedLength);
+ cssPropertyMap.set(stroke_linecapAttr, AnimatedString);
+ cssPropertyMap.set(stroke_linejoinAttr, AnimatedString);
+ cssPropertyMap.set(stroke_miterlimitAttr, AnimatedNumber);
+ cssPropertyMap.set(stroke_opacityAttr, AnimatedNumber);
+ cssPropertyMap.set(stroke_widthAttr, AnimatedLength);
+ cssPropertyMap.set(text_anchorAttr, AnimatedString);
+ cssPropertyMap.set(text_decorationAttr, AnimatedString);
+ cssPropertyMap.set(text_renderingAttr, AnimatedString);
+ cssPropertyMap.set(vector_effectAttr, AnimatedString);
+ cssPropertyMap.set(visibilityAttr, AnimatedString);
+ cssPropertyMap.set(word_spacingAttr, AnimatedLength);
+ }
+
+ if (cssPropertyMap.contains(attributeName))
+ return cssPropertyMap.get(attributeName);
+
+ return AnimatedUnknown;
+}
+
+void SVGElement::addToPropertyMap(PassRefPtr<SVGAnimatedPropertyBase> passProperty)
+{
+ RefPtr<SVGAnimatedPropertyBase> property(passProperty);
+ QualifiedName attributeName = property->attributeName();
+ m_newAttributeToPropertyMap.set(attributeName, property.release());
+}
- AttributeToPropertyTypeMap& cssPropertyTypeMap = cssPropertyToTypeMap();
- if (cssPropertyTypeMap.contains(attributeName))
- propertyTypes.append(cssPropertyTypeMap.get(attributeName));
+PassRefPtr<SVGAnimatedPropertyBase> SVGElement::propertyFromAttribute(const QualifiedName& attributeName)
+{
+ return m_newAttributeToPropertyMap.get(attributeName);
}
bool SVGElement::isAnimatableCSSProperty(const QualifiedName& attrName)
{
- return cssPropertyToTypeMap().contains(attrName);
+ return animatedPropertyTypeForCSSAttribute(attrName) != AnimatedUnknown;
}
bool SVGElement::isPresentationAttribute(const QualifiedName& name) const
@@ -790,16 +781,14 @@ void SVGElement::collectStyleForPresentationAttribute(const QualifiedName& name,
bool SVGElement::haveLoadedRequiredResources()
{
- Node* child = firstChild();
- while (child) {
- if (child->isSVGElement() && !toSVGElement(child)->haveLoadedRequiredResources())
+ for (SVGElement* child = Traversal<SVGElement>::firstChild(*this); child; child = Traversal<SVGElement>::nextSibling(*child)) {
+ if (!child->haveLoadedRequiredResources())
return false;
- child = child->nextSibling();
}
return true;
}
-static inline void collectInstancesForSVGElement(SVGElement* element, HashSet<SVGElementInstance*>& instances)
+static inline void collectInstancesForSVGElement(SVGElement* element, WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances)
{
ASSERT(element);
if (element->containingShadowRoot())
@@ -819,14 +808,11 @@ bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<Even
return false;
// Add event listener to all shadow tree DOM element instances
- HashSet<SVGElementInstance*> instances;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > instances;
collectInstancesForSVGElement(this, instances);
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- ASSERT((*it)->shadowTreeElement());
- ASSERT((*it)->correspondingElement() == this);
-
- bool result = (*it)->shadowTreeElement()->Node::addEventListener(eventType, listener, useCapture);
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
+ bool result = (*it)->Node::addEventListener(eventType, listener, useCapture);
ASSERT_UNUSED(result, result);
}
@@ -835,7 +821,7 @@ bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<Even
bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
{
- HashSet<SVGElementInstance*> instances;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > instances;
collectInstancesForSVGElement(this, instances);
if (instances.isEmpty())
return Node::removeEventListener(eventType, listener, useCapture);
@@ -852,29 +838,12 @@ bool SVGElement::removeEventListener(const AtomicString& eventType, EventListene
return false;
// Remove event listener from all shadow tree DOM element instances
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
- ASSERT((*it)->correspondingElement() == this);
-
- SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
+ SVGElement* shadowTreeElement = *it;
ASSERT(shadowTreeElement);
- if (shadowTreeElement->Node::removeEventListener(eventType, listener, useCapture))
- continue;
-
- // This case can only be hit for event listeners created from markup
- ASSERT(listener->wasCreatedFromMarkup());
-
- // If the event listener 'listener' has been created from markup and has been fired before
- // then JSLazyEventListener::parseCode() has been called and m_jsFunction of that listener
- // has been created (read: it's not 0 anymore). During shadow tree creation, the event
- // listener DOM attribute has been cloned, and another event listener has been setup in
- // the shadow tree. If that event listener has not been used yet, m_jsFunction is still 0,
- // and tryRemoveEventListener() above will fail. Work around that very seldom problem.
- EventTargetData* data = shadowTreeElement->eventTargetData();
- ASSERT(data);
-
- data->eventListenerMap.removeFirstEventListenerCreatedFromMarkup(eventType);
+ shadowTreeElement->Node::removeEventListener(eventType, listener, useCapture);
}
return true;
@@ -896,22 +865,17 @@ static bool hasLoadListener(Element* element)
return false;
}
-bool SVGElement::shouldMoveToFlowThread(RenderStyle* styleToUse) const
-{
- // Allow only svg root elements to be directly collected by a render flow thread.
- return parentNode() && !parentNode()->isSVGElement() && hasTagName(SVGNames::svgTag) && Element::shouldMoveToFlowThread(styleToUse);
-}
-
void SVGElement::sendSVGLoadEventIfPossible(bool sendParentLoadEvents)
{
- RefPtr<SVGElement> currentTarget = this;
+ RefPtrWillBeRawPtr<SVGElement> currentTarget = this;
while (currentTarget && currentTarget->haveLoadedRequiredResources()) {
- RefPtr<Element> parent;
+ RefPtrWillBeRawPtr<Element> parent = nullptr;
if (sendParentLoadEvents)
parent = currentTarget->parentOrShadowHostElement(); // save the next parent to dispatch too incase dispatching the event changes the tree
- if (hasLoadListener(currentTarget.get()))
+ if (hasLoadListener(currentTarget.get())
+ && (currentTarget->isStructurallyExternal() || isSVGSVGElement(*currentTarget)))
currentTarget->dispatchEvent(Event::create(EventTypeNames::load));
- currentTarget = (parent && parent->isSVGElement()) ? static_pointer_cast<SVGElement>(parent) : RefPtr<SVGElement>();
+ currentTarget = (parent && parent->isSVGElement()) ? static_pointer_cast<SVGElement>(parent) : nullptr;
SVGElement* element = currentTarget.get();
if (!element || !element->isOutermostSVGSVGElement())
continue;
@@ -931,7 +895,7 @@ void SVGElement::sendSVGLoadEventIfPossible(bool sendParentLoadEvents)
void SVGElement::sendSVGLoadEventIfPossibleAsynchronously()
{
- svgLoadEventTimer()->startOneShot(0);
+ svgLoadEventTimer()->startOneShot(0, FROM_HERE);
}
void SVGElement::svgLoadEventTimerFired(Timer<SVGElement>*)
@@ -945,46 +909,12 @@ Timer<SVGElement>* SVGElement::svgLoadEventTimer()
return 0;
}
-void SVGElement::finishParsingChildren()
-{
- Element::finishParsingChildren();
-
- // The outermost SVGSVGElement SVGLoad event is fired through Document::dispatchWindowLoadEvent.
- if (isOutermostSVGSVGElement())
- return;
-
- // finishParsingChildren() is called when the close tag is reached for an element (e.g. </svg>)
- // we send SVGLoad events here if we can, otherwise they'll be sent when any required loads finish
- sendSVGLoadEventIfPossible();
-}
-
-bool SVGElement::childShouldCreateRenderer(const Node& child) const
-{
- DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, invalidTextContent, ());
-
- if (invalidTextContent.isEmpty()) {
- invalidTextContent.add(SVGNames::textPathTag);
-#if ENABLE(SVG_FONTS)
- invalidTextContent.add(SVGNames::altGlyphTag);
-#endif
- invalidTextContent.add(SVGNames::tspanTag);
- }
- if (child.isSVGElement()) {
- const SVGElement* svgChild = toSVGElement(&child);
- if (invalidTextContent.contains(svgChild->tagQName()))
- return false;
-
- return svgChild->isValid();
- }
- return false;
-}
-
void SVGElement::attributeChanged(const QualifiedName& name, const AtomicString& newValue, AttributeModificationReason)
{
Element::attributeChanged(name, newValue);
if (isIdAttributeName(name))
- document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
+ document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
// Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods),
// so we don't want changes to the style attribute to result in extra work here.
@@ -996,13 +926,13 @@ void SVGElement::svgAttributeChanged(const QualifiedName& attrName)
{
CSSPropertyID propId = SVGElement::cssPropertyIdForSVGAttributeName(attrName);
if (propId > 0) {
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
return;
}
if (attrName == HTMLNames::classAttr) {
- classAttributeChanged(classNameCurrentValue());
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ classAttributeChanged(AtomicString(m_className->currentValue()->value()));
+ invalidateInstances();
return;
}
@@ -1013,7 +943,7 @@ void SVGElement::svgAttributeChanged(const QualifiedName& attrName)
toRenderSVGResourceContainer(object)->idChanged();
if (inDocument())
buildPendingResourcesIfNeeded();
- SVGElementInstance::invalidateAllInstancesOfElement(this);
+ invalidateInstances();
return;
}
}
@@ -1023,30 +953,20 @@ void SVGElement::synchronizeAnimatedSVGAttribute(const QualifiedName& name) cons
if (!elementData() || !elementData()->m_animatedSVGAttributesAreDirty)
return;
- SVGElement* nonConstThis = const_cast<SVGElement*>(this);
if (name == anyQName()) {
- nonConstThis->localAttributeToPropertyMap().synchronizeProperties(nonConstThis);
- elementData()->m_animatedSVGAttributesAreDirty = false;
- } else
- nonConstThis->localAttributeToPropertyMap().synchronizeProperty(nonConstThis, name);
-}
-
-void SVGElement::synchronizeRequiredFeatures(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- contextElement->synchronizeRequiredFeatures();
-}
-
-void SVGElement::synchronizeRequiredExtensions(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- contextElement->synchronizeRequiredExtensions();
-}
+ AttributeToPropertyMap::const_iterator::Values it = m_newAttributeToPropertyMap.values().begin();
+ AttributeToPropertyMap::const_iterator::Values end = m_newAttributeToPropertyMap.values().end();
+ for (; it != end; ++it) {
+ if ((*it)->needsSynchronizeAttribute())
+ (*it)->synchronizeAttribute();
+ }
-void SVGElement::synchronizeSystemLanguage(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- contextElement->synchronizeSystemLanguage();
+ elementData()->m_animatedSVGAttributesAreDirty = false;
+ } else {
+ RefPtr<SVGAnimatedPropertyBase> property = m_newAttributeToPropertyMap.get(name);
+ if (property && property->needsSynchronizeAttribute())
+ property->synchronizeAttribute();
+ }
}
PassRefPtr<RenderStyle> SVGElement::customStyleForRenderer()
@@ -1097,12 +1017,49 @@ RenderStyle* SVGElement::computedStyle(PseudoId pseudoElementSpecifier)
bool SVGElement::hasFocusEventListeners() const
{
- return hasEventListeners(EventTypeNames::focusin) || hasEventListeners(EventTypeNames::focusout);
+ return hasEventListeners(EventTypeNames::focusin) || hasEventListeners(EventTypeNames::focusout)
+ || hasEventListeners(EventTypeNames::focus) || hasEventListeners(EventTypeNames::blur);
}
-bool SVGElement::isKeyboardFocusable() const
+void SVGElement::invalidateInstances()
{
- return isFocusable();
+ if (!inDocument())
+ return;
+
+ if (instanceUpdatesBlocked())
+ return;
+
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& set = instancesForElement();
+ if (set.isEmpty())
+ return;
+
+ // Mark all use elements referencing 'element' for rebuilding
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = set.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = set.begin(); it != end; ++it) {
+ (*it)->setCorrespondingElement(0);
+
+ if (SVGUseElement* element = (*it)->correspondingUseElement()) {
+ ASSERT(element->inDocument());
+ element->invalidateShadowTree();
+ }
+ }
+
+ svgRareData()->elementInstances().clear();
+
+ document().updateRenderTreeIfNeeded();
+}
+
+SVGElement::InstanceUpdateBlocker::InstanceUpdateBlocker(SVGElement* targetElement)
+ : m_targetElement(targetElement)
+{
+ if (m_targetElement)
+ m_targetElement->setInstanceUpdatesBlocked(true);
+}
+
+SVGElement::InstanceUpdateBlocker::~InstanceUpdateBlocker()
+{
+ if (m_targetElement)
+ m_targetElement->setInstanceUpdatesBlocked(false);
}
#ifndef NDEBUG
@@ -1126,7 +1083,6 @@ bool SVGElement::isAnimatableAttribute(const QualifiedName& name) const
animatableAttributes.add(SVGNames::edgeModeAttr);
animatableAttributes.add(SVGNames::elevationAttr);
animatableAttributes.add(SVGNames::exponentAttr);
- animatableAttributes.add(SVGNames::externalResourcesRequiredAttr);
animatableAttributes.add(SVGNames::filterResAttr);
animatableAttributes.add(SVGNames::filterUnitsAttr);
animatableAttributes.add(SVGNames::fxAttr);
@@ -1213,4 +1169,17 @@ bool SVGElement::isAnimatableAttribute(const QualifiedName& name) const
}
#endif
+void SVGElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_elementsWithRelativeLengths);
+ visitor->trace(m_SVGRareData);
+ Element::trace(visitor);
+}
+
+const AtomicString& SVGElement::eventParameterName()
+{
+ DEFINE_STATIC_LOCAL(const AtomicString, evtString, ("evt", AtomicString::ConstructFromLiteral));
+ return evtString;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGElement.h
index 9098753995f..753a5aff8e1 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGElement.h
@@ -22,25 +22,26 @@
#ifndef SVGElement_h
#define SVGElement_h
+#include "core/SVGElementTypeHelpers.h"
#include "core/dom/Element.h"
#include "core/svg/SVGAnimatedString.h"
#include "core/svg/SVGParsingError.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
#include "core/svg/properties/SVGPropertyInfo.h"
#include "platform/Timer.h"
#include "wtf/HashMap.h"
+#include "wtf/OwnPtr.h"
namespace WebCore {
class AffineTransform;
class CSSCursorImageValue;
class Document;
+class SVGAnimatedPropertyBase;
class SubtreeLayoutScope;
-class SVGAttributeToPropertyMap;
class SVGCursorElement;
class SVGDocumentExtensions;
-class SVGElementInstance;
class SVGElementRareData;
+class SVGFitToViewBox;
class SVGSVGElement;
void mapAttributeToCSSProperty(HashMap<StringImpl*, CSSPropertyID>* propertyNameToIdMap, const QualifiedName& attrName);
@@ -48,17 +49,21 @@ void mapAttributeToCSSProperty(HashMap<StringImpl*, CSSPropertyID>* propertyName
class SVGElement : public Element {
public:
virtual ~SVGElement();
+ virtual void attach(const AttachContext&) OVERRIDE;
+ virtual void detach(const AttachContext&) OVERRIDE;
+
+ virtual short tabIndex() const OVERRIDE;
+ virtual bool supportsFocus() const OVERRIDE { return false; }
bool isOutermostSVGSVGElement() const;
- virtual String title() const;
+ virtual String title() const OVERRIDE;
bool hasRelativeLengths() const { return !m_elementsWithRelativeLengths.isEmpty(); }
- virtual bool supportsMarkers() const { return false; }
- PassRefPtr<CSSValue> getPresentationAttribute(const String& name);
static bool isAnimatableCSSProperty(const QualifiedName&);
enum CTMScope {
NearestViewportScope, // Used by SVGGraphicsElement::getCTM()
- ScreenScope // Used by SVGGraphicsElement::getScreenCTM()
+ ScreenScope, // Used by SVGGraphicsElement::getScreenCTM()
+ AncestorScope // Used by SVGSVGElement::get{Enclosure|Intersection}List()
};
virtual AffineTransform localCoordinateSpaceTransform(CTMScope) const;
virtual bool needsPendingResourceHandling() const { return true; }
@@ -66,32 +71,33 @@ public:
bool instanceUpdatesBlocked() const;
void setInstanceUpdatesBlocked(bool);
- String xmlbase() const;
- void setXMLbase(const String&);
+ const AtomicString& xmlbase() const;
+ void setXMLbase(const AtomicString&);
- String xmllang() const;
- void setXMLlang(const String& xmlLang);
+ const AtomicString& xmllang() const;
+ void setXMLlang(const AtomicString&);
- String xmlspace() const;
- void setXMLspace(const String& xmlSpace);
+ const AtomicString& xmlspace() const;
+ void setXMLspace(const AtomicString&);
SVGSVGElement* ownerSVGElement() const;
SVGElement* viewportElement() const;
- SVGDocumentExtensions* accessDocumentSVGExtensions();
+ SVGDocumentExtensions& accessDocumentSVGExtensions();
virtual bool isSVGGraphicsElement() const { return false; }
- virtual bool isSVGSVGElement() const { return false; }
virtual bool isFilterEffect() const { return false; }
- virtual bool isGradientStop() const { return false; }
virtual bool isTextContent() const { return false; }
+ virtual bool isTextPositioning() const { return false; }
+ virtual bool isStructurallyExternal() const { return false; }
// For SVGTests
virtual bool isValid() const { return true; }
virtual void svgAttributeChanged(const QualifiedName&);
- virtual void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&);
+ PassRefPtr<SVGAnimatedPropertyBase> propertyFromAttribute(const QualifiedName& attributeName);
+ static AnimatedPropertyType animatedPropertyTypeForCSSAttribute(const QualifiedName& attributeName);
void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);
void sendSVGLoadEventIfPossibleAsynchronously();
@@ -100,34 +106,37 @@ public:
virtual AffineTransform* supplementalTransform() { return 0; }
- void invalidateSVGAttributes() { ensureUniqueElementData()->m_animatedSVGAttributesAreDirty = true; }
+ void invalidateSVGAttributes() { ensureUniqueElementData().m_animatedSVGAttributesAreDirty = true; }
+ void invalidateSVGPresentationAttributeStyle() { ensureUniqueElementData().m_presentationAttributeStyleIsDirty = true; }
- const HashSet<SVGElementInstance*>& instancesForElement() const;
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instancesForElement() const;
+ void mapInstanceToElement(SVGElement*);
+ void removeInstanceMapping(SVGElement*);
bool getBoundingBox(FloatRect&);
void setCursorElement(SVGCursorElement*);
- void cursorElementRemoved();
void setCursorImageValue(CSSCursorImageValue*);
+
+#if !ENABLE(OILPAN)
+ void cursorElementRemoved();
void cursorImageValueRemoved();
+#endif
SVGElement* correspondingElement();
void setCorrespondingElement(SVGElement*);
+ SVGUseElement* correspondingUseElement() const;
void synchronizeAnimatedSVGAttribute(const QualifiedName&) const;
- virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
-
- static void synchronizeRequiredFeatures(SVGElement* contextElement);
- static void synchronizeRequiredExtensions(SVGElement* contextElement);
- static void synchronizeSystemLanguage(SVGElement* contextElement);
+ virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE FINAL;
virtual void synchronizeRequiredFeatures() { }
virtual void synchronizeRequiredExtensions() { }
virtual void synchronizeSystemLanguage() { }
#ifndef NDEBUG
- bool isAnimatableAttribute(const QualifiedName&) const;
+ virtual bool isAnimatableAttribute(const QualifiedName&) const;
#endif
MutableStylePropertySet* animatedSMILStyleProperties() const;
@@ -136,24 +145,54 @@ public:
virtual bool haveLoadedRequiredResources();
- virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) OVERRIDE;
- virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) OVERRIDE;
-
- virtual bool shouldMoveToFlowThread(RenderStyle*) const OVERRIDE;
+ virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture = false) OVERRIDE FINAL;
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture = false) OVERRIDE FINAL;
void invalidateRelativeLengthClients(SubtreeLayoutScope* = 0);
bool isContextElement() const { return m_isContextElement; }
void setContextElement() { m_isContextElement = true; }
+ void addToPropertyMap(PassRefPtr<SVGAnimatedPropertyBase>);
+
+ SVGAnimatedString* className() { return m_className.get(); }
+
+ bool inUseShadowTree() const;
+
+ class InvalidationGuard {
+ STACK_ALLOCATED();
+ WTF_MAKE_NONCOPYABLE(InvalidationGuard);
+ public:
+ InvalidationGuard(SVGElement* element) : m_element(element) { }
+ ~InvalidationGuard() { m_element->invalidateInstances(); }
+
+ private:
+ RawPtrWillBeMember<SVGElement> m_element;
+ };
+
+ class InstanceUpdateBlocker {
+ STACK_ALLOCATED();
+ WTF_MAKE_NONCOPYABLE(InstanceUpdateBlocker);
+ public:
+ InstanceUpdateBlocker(SVGElement* targetElement);
+ ~InstanceUpdateBlocker();
+
+ private:
+ RawPtrWillBeMember<SVGElement> m_targetElement;
+ };
+
+ void invalidateInstances();
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+ static const AtomicString& eventParameterName();
+
protected:
SVGElement(const QualifiedName&, Document&, ConstructionType = CreateSVGElement);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void finishParsingChildren();
virtual void attributeChanged(const QualifiedName&, const AtomicString&, AttributeModificationReason = ModifiedDirectly) OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
@@ -161,7 +200,7 @@ protected:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
static CSSPropertyID cssPropertyIdForSVGAttributeName(const QualifiedName&);
void updateRelativeLengthsInformation() { updateRelativeLengthsInformation(selfHasRelativeLengths(), this); }
@@ -169,62 +208,45 @@ protected:
virtual bool selfHasRelativeLengths() const { return false; }
- SVGElementRareData* svgRareData() const;
SVGElementRareData* ensureSVGRareData();
+ inline bool hasSVGRareData() const { return m_SVGRareData; }
+ inline SVGElementRareData* svgRareData() const
+ {
+ ASSERT(m_SVGRareData);
+ return m_SVGRareData.get();
+ }
+
+ // SVGFitToViewBox::parseAttribute uses reportAttributeParsingError.
+ friend class SVGFitToViewBox;
void reportAttributeParsingError(SVGParsingError, const QualifiedName&, const AtomicString&);
bool hasFocusEventListeners() const;
- class CleanUpAnimatedPropertiesCaller {
- public:
- CleanUpAnimatedPropertiesCaller()
- : m_owner(0)
- {
- }
-
- ~CleanUpAnimatedPropertiesCaller()
- {
- ASSERT(m_owner);
- m_owner->cleanupAnimatedProperties();
- }
-
- void setOwner(SVGElement* owner) { m_owner = owner; }
-
- private:
- SVGElement* m_owner;
- };
-
private:
- friend class SVGElementInstance;
-
// FIXME: Author shadows should be allowed
// https://bugs.webkit.org/show_bug.cgi?id=77938
- virtual bool areAuthorShadowsAllowed() const OVERRIDE { return false; }
+ virtual bool areAuthorShadowsAllowed() const OVERRIDE FINAL { return false; }
RenderStyle* computedStyle(PseudoId = NOPSEUDO);
- virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) { return computedStyle(pseudoElementSpecifier); }
+ virtual RenderStyle* virtualComputedStyle(PseudoId pseudoElementSpecifier = NOPSEUDO) OVERRIDE FINAL { return computedStyle(pseudoElementSpecifier); }
virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
- virtual bool isKeyboardFocusable() const OVERRIDE;
void buildPendingResourcesIfNeeded();
- void mapInstanceToElement(SVGElementInstance*);
- void removeInstanceMapping(SVGElementInstance*);
-
- void cleanupAnimatedProperties();
- friend class CleanUpAnimatedPropertiesCaller;
+ bool supportsSpatialNavigationFocus() const;
- HashSet<SVGElement*> m_elementsWithRelativeLengths;
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > m_elementsWithRelativeLengths;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGElement)
- DECLARE_ANIMATED_STRING(ClassName, className)
- END_DECLARE_ANIMATED_PROPERTIES
+ typedef HashMap<QualifiedName, RefPtr<SVGAnimatedPropertyBase> > AttributeToPropertyMap;
+ AttributeToPropertyMap m_newAttributeToPropertyMap;
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
bool m_inRelativeLengthClientsInvalidation;
#endif
- bool m_animatedPropertiesDestructed;
- bool m_isContextElement;
+ unsigned m_isContextElement : 1;
+
+ OwnPtrWillBeMember<SVGElementRareData> m_SVGRareData;
+ RefPtr<SVGAnimatedString> m_className;
};
struct SVGAttributeHashTranslator {
@@ -239,7 +261,9 @@ struct SVGAttributeHashTranslator {
static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); }
};
-DEFINE_NODE_TYPE_CASTS(SVGElement, isSVGElement());
+DEFINE_ELEMENT_TYPE_CASTS(SVGElement, isSVGElement());
+
+template <> inline bool isElementOfType<const SVGElement>(const Node& node) { return node.isSVGElement(); }
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGElement.idl
index d27e2abb355..d18904f6412 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGElement.idl
@@ -23,17 +23,19 @@
[
Custom=Wrap,
] interface SVGElement : Element {
- [TreatNullAs=NullString] attribute DOMString xmlbase;
- readonly attribute SVGSVGElement ownerSVGElement;
- readonly attribute SVGElement viewportElement;
+ attribute DOMString xmlbase;
+ [TypeChecking=Interface|Nullable] readonly attribute SVGSVGElement? ownerSVGElement;
+ [TypeChecking=Interface|Nullable] readonly attribute SVGElement? viewportElement;
attribute DOMString xmllang;
attribute DOMString xmlspace;
- readonly attribute SVGAnimatedString className;
+ [MeasureAs=SVGClassName] readonly attribute SVGAnimatedString className;
+
readonly attribute CSSStyleDeclaration style;
- CSSValue getPresentationAttribute([Default=Undefined] optional DOMString name);
+ [CustomElementCallbacks] attribute long tabIndex;
};
SVGElement implements GlobalEventHandlers;
+
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.cpp
deleted file mode 100644
index 3e835c184e4..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGElementInstance.h"
-
-#include "core/dom/ContainerNodeAlgorithms.h"
-#include "core/events/Event.h"
-#include "core/events/EventListener.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/svg/SVGElement.h"
-#include "core/svg/SVGElementInstanceList.h"
-#include "core/svg/SVGUseElement.h"
-
-#include "wtf/RefCountedLeakCounter.h"
-
-namespace WebCore {
-
-DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, instanceCounter, ("WebCoreSVGElementInstance"));
-
-// EventTarget API
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), abort);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), blur);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), change);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), click);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), contextmenu);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dblclick);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), error);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), focus);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), input);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), keydown);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), keypress);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), keyup);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), load);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mousedown);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseenter);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseleave);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mousemove);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseout);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseover);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mouseup);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), mousewheel);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), wheel);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), beforecut);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), cut);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), beforecopy);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), copy);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), beforepaste);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), paste);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragenter);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragover);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragleave);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), drop);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragstart);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), drag);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), dragend);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), reset);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), resize);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), scroll);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), search);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), select);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), selectstart);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), submit);
-DEFINE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(SVGElementInstance, correspondingElement(), unload);
-
-PassRefPtr<SVGElementInstance> SVGElementInstance::create(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement)
-{
- return adoptRef(new SVGElementInstance(correspondingUseElement, directUseElement, originalElement));
-}
-
-SVGElementInstance::SVGElementInstance(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement)
- : m_parentInstance(0)
- , m_correspondingUseElement(correspondingUseElement)
- , m_directUseElement(directUseElement)
- , m_element(originalElement)
- , m_previousSibling(0)
- , m_nextSibling(0)
- , m_firstChild(0)
- , m_lastChild(0)
-{
- ASSERT(m_correspondingUseElement);
- ASSERT(m_element);
- ScriptWrappable::init(this);
-
- // Register as instance for passed element.
- m_element->mapInstanceToElement(this);
-
-#ifndef NDEBUG
- instanceCounter.increment();
-#endif
-}
-
-SVGElementInstance::~SVGElementInstance()
-{
- // Call detach because we may be deleted directly if we are a child of a detached instance.
- detach();
-
-#ifndef NDEBUG
- instanceCounter.decrement();
-#endif
-
- m_element = 0;
-}
-
-// It's important not to inline removedLastRef, because we don't want to inline the code to
-// delete an SVGElementInstance at each deref call site.
-void SVGElementInstance::removedLastRef()
-{
-#if SECURITY_ASSERT_ENABLED
- m_deletionHasBegun = true;
-#endif
- delete this;
-}
-
-void SVGElementInstance::detach()
-{
- // Clear all pointers. When the node is detached from the shadow DOM it should be removed but,
- // due to ref counting, it may not be. So clear everything to avoid dangling pointers.
-
- for (SVGElementInstance* node = firstChild(); node; node = node->nextSibling())
- node->detach();
-
- // Deregister as instance for passed element, if we haven't already.
- if (m_element->instancesForElement().contains(this))
- m_element->removeInstanceMapping(this);
- // DO NOT clear ref to m_element because JavaScriptCore uses it for garbage collection
-
- m_shadowTreeElement = 0;
-
- m_directUseElement = 0;
- m_correspondingUseElement = 0;
-
- removeDetachedChildrenInContainer<SVGElementInstance, SVGElementInstance>(*this);
-}
-
-PassRefPtr<SVGElementInstanceList> SVGElementInstance::childNodes()
-{
- return SVGElementInstanceList::create(this);
-}
-
-void SVGElementInstance::setShadowTreeElement(SVGElement* element)
-{
- ASSERT(element);
- m_shadowTreeElement = element;
-}
-
-void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child)
-{
- appendChildToContainer<SVGElementInstance, SVGElementInstance>(*child, *this);
-}
-
-void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
-{
- if (!element || !element->inDocument())
- return;
-
- if (element->instanceUpdatesBlocked())
- return;
-
- const HashSet<SVGElementInstance*>& set = element->instancesForElement();
- if (set.isEmpty())
- return;
-
- // Mark all use elements referencing 'element' for rebuilding
- const HashSet<SVGElementInstance*>::const_iterator end = set.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = set.begin(); it != end; ++it) {
- ASSERT((*it)->shadowTreeElement());
- ASSERT((*it)->shadowTreeElement()->correspondingElement());
- ASSERT((*it)->shadowTreeElement()->correspondingElement() == (*it)->correspondingElement());
- ASSERT((*it)->correspondingElement() == element);
- (*it)->shadowTreeElement()->setCorrespondingElement(0);
-
- if (SVGUseElement* element = (*it)->correspondingUseElement()) {
- ASSERT(element->inDocument());
- element->invalidateShadowTree();
- }
- }
-
- element->document().updateStyleIfNeeded();
-}
-
-const AtomicString& SVGElementInstance::interfaceName() const
-{
- return EventTargetNames::SVGElementInstance;
-}
-
-ExecutionContext* SVGElementInstance::executionContext() const
-{
- return &m_element->document();
-}
-
-bool SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
-{
- return m_element->addEventListener(eventType, listener, useCapture);
-}
-
-bool SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
-{
- return m_element->removeEventListener(eventType, listener, useCapture);
-}
-
-void SVGElementInstance::removeAllEventListeners()
-{
- m_element->removeAllEventListeners();
-}
-
-Node* SVGElementInstance::toNode()
-{
- return shadowTreeElement();
-}
-
-Document* SVGElementInstance::ownerDocument() const
-{
- return m_element ? m_element->ownerDocument() : 0;
-}
-
-bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> event)
-{
- SVGElement* element = shadowTreeElement();
- if (!element)
- return false;
-
- return element->dispatchEvent(event);
-}
-
-EventTargetData* SVGElementInstance::eventTargetData()
-{
- // Since no event listeners are added to an SVGElementInstance, we don't have eventTargetData.
- return 0;
-}
-
-EventTargetData& SVGElementInstance::ensureEventTargetData()
-{
- // EventTarget would use these methods if we were actually using its add/removeEventListener logic.
- // As we're forwarding those calls to the correspondingElement(), no one should ever call this function.
- ASSERT_NOT_REACHED();
- return *eventTargetData();
-}
-
-SVGElementInstance::InstanceUpdateBlocker::InstanceUpdateBlocker(SVGElement* targetElement)
- : m_targetElement(targetElement)
-{
- if (m_targetElement)
- m_targetElement->setInstanceUpdatesBlocked(true);
-}
-
-SVGElementInstance::InstanceUpdateBlocker::~InstanceUpdateBlocker()
-{
- if (m_targetElement)
- m_targetElement->setInstanceUpdatesBlocked(false);
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.h b/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.h
deleted file mode 100644
index 66de33c7d75..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2011 Torch Mobile (Beijing) Co. Ltd. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGElementInstance_h
-#define SVGElementInstance_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/dom/TreeShared.h"
-#include "core/events/EventTarget.h"
-
-namespace WebCore {
-
-namespace Private {
-template<class GenericNode, class GenericNodeContainer>
-void addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
-};
-
-class Document;
-class SVGElement;
-class SVGElementInstanceList;
-class SVGUseElement;
-
-// SVGElementInstance mimics Node, but without providing all its functionality
-class SVGElementInstance : public EventTarget, public ScriptWrappable, public TreeShared<SVGElementInstance> {
- DEFINE_EVENT_TARGET_REFCOUNTING(TreeShared<SVGElementInstance>);
-public:
- static PassRefPtr<SVGElementInstance> create(SVGUseElement* correspondingUseElement, SVGUseElement* directUseElement, PassRefPtr<SVGElement> originalElement);
-
- virtual ~SVGElementInstance();
-
- void setParentOrShadowHostNode(SVGElementInstance* instance) { m_parentInstance = instance; }
-
- virtual const AtomicString& interfaceName() const;
- virtual ExecutionContext* executionContext() const;
-
- virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
- virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
- virtual void removeAllEventListeners();
-
- using EventTarget::dispatchEvent;
- virtual bool dispatchEvent(PassRefPtr<Event>) OVERRIDE;
-
- SVGElement* correspondingElement() const { return m_element.get(); }
- SVGUseElement* correspondingUseElement() const { return m_correspondingUseElement; }
- SVGUseElement* directUseElement() const { return m_directUseElement; }
- SVGElement* shadowTreeElement() const { return m_shadowTreeElement.get(); }
-
- void detach();
-
- SVGElementInstance* parentNode() const { return m_parentInstance; }
- PassRefPtr<SVGElementInstanceList> childNodes();
-
- SVGElementInstance* previousSibling() const { return m_previousSibling; }
- SVGElementInstance* nextSibling() const { return m_nextSibling; }
-
- SVGElementInstance* firstChild() const { return m_firstChild; }
- SVGElementInstance* lastChild() const { return m_lastChild; }
-
- inline Document* ownerDocument() const;
-
- class InvalidationGuard {
- WTF_MAKE_NONCOPYABLE(InvalidationGuard);
- public:
- InvalidationGuard(SVGElement* element) : m_element(element) { }
- ~InvalidationGuard() { SVGElementInstance::invalidateAllInstancesOfElement(m_element); }
- private:
- SVGElement* m_element;
- };
-
- class InstanceUpdateBlocker {
- WTF_MAKE_NONCOPYABLE(InstanceUpdateBlocker);
- public:
- InstanceUpdateBlocker(SVGElement* targetElement);
- ~InstanceUpdateBlocker();
-
- private:
- SVGElement* m_targetElement;
- };
-
- static void invalidateAllInstancesOfElement(SVGElement*);
-
- // EventTarget API
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), abort);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), blur);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), change);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), click);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), contextmenu);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dblclick);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), error);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), focus);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), input);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keydown);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keypress);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), keyup);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), load);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousedown);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseenter);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseleave);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousemove);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseout);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseover);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mouseup);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), mousewheel);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), wheel);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecut);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), cut);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforecopy);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), copy);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), beforepaste);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), paste);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragenter);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragover);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragleave);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drop);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragstart);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), drag);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), dragend);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), reset);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), resize);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), scroll);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), search);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), select);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), selectstart);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), submit);
- DECLARE_FORWARDING_ATTRIBUTE_EVENT_LISTENER(correspondingElement(), unload);
-
-private:
- friend class SVGUseElement;
- friend class TreeShared<SVGElementInstance>;
-
- SVGElementInstance(SVGUseElement*, SVGUseElement*, PassRefPtr<SVGElement> originalElement);
-
- void removedLastRef();
- bool hasTreeSharedParent() const { return !!m_parentInstance; }
-
- virtual Node* toNode();
-
- void appendChild(PassRefPtr<SVGElementInstance> child);
- void setShadowTreeElement(SVGElement*);
-
- template<class GenericNode, class GenericNodeContainer>
- friend void appendChildToContainer(GenericNode& child, GenericNodeContainer&);
-
- template<class GenericNode, class GenericNodeContainer>
- friend void removeDetachedChildrenInContainer(GenericNodeContainer&);
-
- template<class GenericNode, class GenericNodeContainer>
- friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
-
- bool hasChildNodes() const { return m_firstChild; }
-
- void setFirstChild(SVGElementInstance* child) { m_firstChild = child; }
- void setLastChild(SVGElementInstance* child) { m_lastChild = child; }
-
- void setNextSibling(SVGElementInstance* sibling) { m_nextSibling = sibling; }
- void setPreviousSibling(SVGElementInstance* sibling) { m_previousSibling = sibling; }
-
- virtual EventTargetData* eventTargetData() OVERRIDE;
- virtual EventTargetData& ensureEventTargetData() OVERRIDE;
-
- SVGElementInstance* m_parentInstance;
-
- SVGUseElement* m_correspondingUseElement;
- SVGUseElement* m_directUseElement;
- RefPtr<SVGElement> m_element;
- RefPtr<SVGElement> m_shadowTreeElement;
-
- SVGElementInstance* m_previousSibling;
- SVGElementInstance* m_nextSibling;
-
- SVGElementInstance* m_firstChild;
- SVGElementInstance* m_lastChild;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.idl b/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.idl
deleted file mode 100644
index 8f6a1d84de3..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstance.idl
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-interface SVGElementInstance : EventTarget
-{
- readonly attribute SVGElement correspondingElement;
- readonly attribute SVGUseElement correspondingUseElement;
- readonly attribute SVGElementInstance parentNode;
- readonly attribute SVGElementInstanceList childNodes;
- readonly attribute SVGElementInstance firstChild;
- readonly attribute SVGElementInstance lastChild;
- readonly attribute SVGElementInstance previousSibling;
- readonly attribute SVGElementInstance nextSibling;
-
- // EventTarget
- [NotEnumerable] attribute EventHandler onabort;
- [NotEnumerable] attribute EventHandler onblur;
- [NotEnumerable] attribute EventHandler onchange;
- [NotEnumerable] attribute EventHandler onclick;
- [NotEnumerable] attribute EventHandler oncontextmenu;
- [NotEnumerable] attribute EventHandler ondblclick;
- [NotEnumerable] attribute EventHandler onerror;
- [NotEnumerable] attribute EventHandler onfocus;
- [NotEnumerable] attribute EventHandler oninput;
- [NotEnumerable] attribute EventHandler onkeydown;
- [NotEnumerable] attribute EventHandler onkeypress;
- [NotEnumerable] attribute EventHandler onkeyup;
- [NotEnumerable] attribute EventHandler onload;
- [NotEnumerable] attribute EventHandler onmousedown;
- [NotEnumerable] attribute EventHandler onmouseenter;
- [NotEnumerable] attribute EventHandler onmouseleave;
- [NotEnumerable] attribute EventHandler onmousemove;
- [NotEnumerable] attribute EventHandler onmouseout;
- [NotEnumerable] attribute EventHandler onmouseover;
- [NotEnumerable] attribute EventHandler onmouseup;
- [NotEnumerable] attribute EventHandler onmousewheel; // Deprecated in favor of onwheel.
- [NotEnumerable] attribute EventHandler onbeforecut;
- [NotEnumerable] attribute EventHandler oncut;
- [NotEnumerable] attribute EventHandler onbeforecopy;
- [NotEnumerable] attribute EventHandler oncopy;
- [NotEnumerable] attribute EventHandler onbeforepaste;
- [NotEnumerable] attribute EventHandler onpaste;
- [NotEnumerable] attribute EventHandler ondragenter;
- [NotEnumerable] attribute EventHandler ondragover;
- [NotEnumerable] attribute EventHandler ondragleave;
- [NotEnumerable] attribute EventHandler ondrop;
- [NotEnumerable] attribute EventHandler ondragstart;
- [NotEnumerable] attribute EventHandler ondrag;
- [NotEnumerable] attribute EventHandler ondragend;
- [NotEnumerable] attribute EventHandler onreset;
- [NotEnumerable] attribute EventHandler onresize;
- [NotEnumerable] attribute EventHandler onscroll;
- [NotEnumerable] attribute EventHandler onsearch;
- [NotEnumerable] attribute EventHandler onselect;
- [NotEnumerable] attribute EventHandler onselectstart;
- [NotEnumerable] attribute EventHandler onsubmit;
- [NotEnumerable] attribute EventHandler onunload;
- [NotEnumerable] attribute EventHandler onwheel;
-};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp
deleted file mode 100644
index 0e3d89518b8..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGElementInstanceList.h"
-#include "core/svg/SVGElementInstance.h"
-
-namespace WebCore {
-
-SVGElementInstanceList::SVGElementInstanceList(PassRefPtr<SVGElementInstance> rootInstance)
- : m_rootInstance(rootInstance)
-{
- ScriptWrappable::init(this);
-}
-
-unsigned SVGElementInstanceList::length() const
-{
- // NOTE: We could use the same caching facilities, like the ones "ChildNodeList" uses.
- unsigned length = 0;
- for (SVGElementInstance* instance = m_rootInstance->firstChild(); instance; instance = instance->nextSibling())
- length++;
- return length;
-}
-
-SVGElementInstance* SVGElementInstanceList::item(unsigned index)
-{
- unsigned pos = 0;
- SVGElementInstance* instance = m_rootInstance->firstChild();
- while (instance && pos < index) {
- instance = instance->nextSibling();
- pos++;
- }
- return instance;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.h b/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.h
deleted file mode 100644
index 2ac15927df0..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGElementInstanceList_h
-#define SVGElementInstanceList_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-class SVGElementInstance;
-
-class SVGElementInstanceList FINAL : public RefCounted<SVGElementInstanceList>, public ScriptWrappable {
-public:
- static PassRefPtr<SVGElementInstanceList> create(PassRefPtr<SVGElementInstance> root) { return adoptRef(new SVGElementInstanceList(root)); }
-
- unsigned length() const;
- SVGElementInstance* item(unsigned index);
-
-private:
- SVGElementInstanceList(PassRefPtr<SVGElementInstance>);
-
- RefPtr<SVGElementInstance> m_rootInstance;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.idl
deleted file mode 100644
index 91534bb01cd..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElementInstanceList.idl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-interface SVGElementInstanceList {
- readonly attribute unsigned long length;
-
- SVGElementInstance item([Default=Undefined] optional unsigned long index);
-};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGElementRareData.h b/chromium/third_party/WebKit/Source/core/svg/SVGElementRareData.h
index 91a69d938c5..57f4a5b20f7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGElementRareData.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGElementRareData.h
@@ -31,36 +31,27 @@ namespace WebCore {
class CSSCursorImageValue;
class SVGCursorElement;
class SVGElement;
-class SVGElementInstance;
-class SVGElementRareData {
- WTF_MAKE_NONCOPYABLE(SVGElementRareData); WTF_MAKE_FAST_ALLOCATED;
+class SVGElementRareData : public NoBaseWillBeGarbageCollectedFinalized<SVGElementRareData> {
+ WTF_MAKE_NONCOPYABLE(SVGElementRareData); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- SVGElementRareData()
- : m_cursorElement(0)
- , m_cursorImageValue(0)
- , m_correspondingElement(0)
+ SVGElementRareData(SVGElement* owner)
+#if ENABLE(OILPAN)
+ : m_owner(owner)
+ , m_cursorElement(nullptr)
+#else
+ : m_cursorElement(nullptr)
+#endif
+ , m_cursorImageValue(nullptr)
+ , m_correspondingElement(nullptr)
, m_instancesUpdatesBlocked(false)
, m_useOverrideComputedStyle(false)
, m_needsOverrideComputedStyleUpdate(false)
{
}
- typedef HashMap<const SVGElement*, SVGElementRareData*> SVGElementRareDataMap;
-
- static SVGElementRareDataMap& rareDataMap()
- {
- DEFINE_STATIC_LOCAL(SVGElementRareDataMap, rareDataMap, ());
- return rareDataMap;
- }
-
- static SVGElementRareData* rareDataFromMap(const SVGElement* element)
- {
- return rareDataMap().get(element);
- }
-
- HashSet<SVGElementInstance*>& elementInstances() { return m_elementInstances; }
- const HashSet<SVGElementInstance*>& elementInstances() const { return m_elementInstances; }
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& elementInstances() { return m_elementInstances; }
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& elementInstances() const { return m_elementInstances; }
bool instanceUpdatesBlocked() const { return m_instancesUpdatesBlocked; }
void setInstanceUpdatesBlocked(bool value) { m_instancesUpdatesBlocked = value; }
@@ -68,7 +59,7 @@ public:
SVGCursorElement* cursorElement() const { return m_cursorElement; }
void setCursorElement(SVGCursorElement* cursorElement) { m_cursorElement = cursorElement; }
- SVGElement* correspondingElement() { return m_correspondingElement; }
+ SVGElement* correspondingElement() { return m_correspondingElement.get(); }
void setCorrespondingElement(SVGElement* correspondingElement) { m_correspondingElement = correspondingElement; }
CSSCursorImageValue* cursorImageValue() const { return m_cursorImageValue; }
@@ -82,11 +73,6 @@ public:
return m_animatedSMILStyleProperties.get();
}
- void destroyAnimatedSMILStyleProperties()
- {
- m_animatedSMILStyleProperties.clear();
- }
-
RenderStyle* overrideComputedStyle(Element* element, RenderStyle* parentStyle)
{
ASSERT(element);
@@ -105,15 +91,50 @@ public:
void setUseOverrideComputedStyle(bool value) { m_useOverrideComputedStyle = value; }
void setNeedsOverrideComputedStyleUpdate() { m_needsOverrideComputedStyleUpdate = true; }
+ void trace(Visitor* visitor)
+ {
+#if ENABLE(OILPAN)
+ visitor->trace(m_animatedSMILStyleProperties);
+ visitor->trace(m_elementInstances);
+ visitor->trace(m_correspondingElement);
+ visitor->trace(m_owner);
+ visitor->registerWeakMembers<SVGElementRareData, &SVGElementRareData::processWeakMembers>(this);
+#endif
+ }
+
+ void processWeakMembers(Visitor* visitor)
+ {
+#if ENABLE(OILPAN)
+ ASSERT(m_owner);
+ if (!visitor->isAlive(m_cursorElement))
+ m_cursorElement = nullptr;
+
+ if (!visitor->isAlive(m_cursorImageValue)) {
+ // The owning SVGElement is still alive and if it is pointing to an SVGCursorElement
+ // we unregister it when the CSSCursorImageValue dies.
+ if (m_cursorElement) {
+ m_cursorElement->removeReferencedElement(m_owner);
+ m_cursorElement = nullptr;
+ }
+ m_cursorImageValue = nullptr;
+ }
+ ASSERT(!m_cursorElement || visitor->isAlive(m_cursorElement));
+ ASSERT(!m_cursorImageValue || visitor->isAlive(m_cursorImageValue));
+#endif
+ }
+
private:
- HashSet<SVGElementInstance*> m_elementInstances;
- SVGCursorElement* m_cursorElement;
- CSSCursorImageValue* m_cursorImageValue;
- SVGElement* m_correspondingElement;
+#if ENABLE(OILPAN)
+ Member<SVGElement> m_owner;
+#endif
+ WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> > m_elementInstances;
+ RawPtrWillBeWeakMember<SVGCursorElement> m_cursorElement;
+ RawPtrWillBeWeakMember<CSSCursorImageValue> m_cursorImageValue;
+ RefPtrWillBeMember<SVGElement> m_correspondingElement;
bool m_instancesUpdatesBlocked : 1;
bool m_useOverrideComputedStyle : 1;
bool m_needsOverrideComputedStyleUpdate : 1;
- RefPtr<MutableStylePropertySet> m_animatedSMILStyleProperties;
+ RefPtrWillBeMember<MutableStylePropertySet> m_animatedSMILStyleProperties;
RefPtr<RenderStyle> m_overrideComputedStyle;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.cpp
index b0e4aeda679..f2a83e94c64 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.cpp
@@ -24,48 +24,31 @@
#include "core/rendering/svg/RenderSVGEllipse.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLength.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::cxAttr, Cx, cx)
-DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::cyAttr, Cy, cy)
-DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::rxAttr, Rx, rx)
-DEFINE_ANIMATED_LENGTH(SVGEllipseElement, SVGNames::ryAttr, Ry, ry)
-DEFINE_ANIMATED_BOOLEAN(SVGEllipseElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGEllipseElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(cx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(cy)
- REGISTER_LOCAL_ANIMATED_PROPERTY(rx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(ry)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGEllipseElement::SVGEllipseElement(Document& document)
: SVGGeometryElement(SVGNames::ellipseTag, document)
- , m_cx(LengthModeWidth)
- , m_cy(LengthModeHeight)
- , m_rx(LengthModeWidth)
- , m_ry(LengthModeHeight)
+ , m_cx(SVGAnimatedLength::create(this, SVGNames::cxAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_cy(SVGAnimatedLength::create(this, SVGNames::cyAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_rx(SVGAnimatedLength::create(this, SVGNames::rxAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_ry(SVGAnimatedLength::create(this, SVGNames::ryAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGEllipseElement();
-}
-PassRefPtr<SVGEllipseElement> SVGEllipseElement::create(Document& document)
-{
- return adoptRef(new SVGEllipseElement(document));
+ addToPropertyMap(m_cx);
+ addToPropertyMap(m_cy);
+ addToPropertyMap(m_rx);
+ addToPropertyMap(m_ry);
}
+DEFINE_NODE_FACTORY(SVGEllipseElement)
+
bool SVGEllipseElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::cxAttr);
supportedAttributes.add(SVGNames::cyAttr);
supportedAttributes.add(SVGNames::rxAttr);
@@ -81,15 +64,14 @@ void SVGEllipseElement::parseAttribute(const QualifiedName& name, const AtomicSt
if (!isSupportedAttribute(name))
SVGGeometryElement::parseAttribute(name, value);
else if (name == SVGNames::cxAttr)
- setCxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_cx->setBaseValueAsString(value, parseError);
else if (name == SVGNames::cyAttr)
- setCyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_cy->setBaseValueAsString(value, parseError);
else if (name == SVGNames::rxAttr)
- setRxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+ m_rx->setBaseValueAsString(value, parseError);
else if (name == SVGNames::ryAttr)
- setRyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
- else if (SVGExternalResourcesRequired::parseAttribute(name, value)) {
- } else
+ m_ry->setBaseValueAsString(value, parseError);
+ else
ASSERT_NOT_REACHED();
reportAttributeParsingError(parseError, name, value);
@@ -102,7 +84,7 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
bool isLengthAttribute = attrName == SVGNames::cxAttr
|| attrName == SVGNames::cyAttr
@@ -122,20 +104,15 @@ void SVGEllipseElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
ASSERT_NOT_REACHED();
}
bool SVGEllipseElement::selfHasRelativeLengths() const
{
- return cxCurrentValue().isRelative()
- || cyCurrentValue().isRelative()
- || rxCurrentValue().isRelative()
- || ryCurrentValue().isRelative();
+ return m_cx->currentValue()->isRelative()
+ || m_cy->currentValue()->isRelative()
+ || m_rx->currentValue()->isRelative()
+ || m_ry->currentValue()->isRelative();
}
RenderObject* SVGEllipseElement::createRenderer(RenderStyle*)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.h
index e0cc981a96c..b2381ce6d17 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.h
@@ -21,44 +21,39 @@
#ifndef SVGEllipseElement_h
#define SVGEllipseElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGeometryElement.h"
namespace WebCore {
-class SVGEllipseElement FINAL : public SVGGeometryElement,
- public SVGExternalResourcesRequired {
+class SVGEllipseElement FINAL : public SVGGeometryElement {
public:
- static PassRefPtr<SVGEllipseElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGEllipseElement);
+
+ SVGAnimatedLength* cx() const { return m_cx.get(); }
+ SVGAnimatedLength* cy() const { return m_cy.get(); }
+ SVGAnimatedLength* rx() const { return m_rx.get(); }
+ SVGAnimatedLength* ry() const { return m_ry.get(); }
private:
explicit SVGEllipseElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGEllipseElement)
- DECLARE_ANIMATED_LENGTH(Cx, cx)
- DECLARE_ANIMATED_LENGTH(Cy, cy)
- DECLARE_ANIMATED_LENGTH(Rx, rx)
- DECLARE_ANIMATED_LENGTH(Ry, ry)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_cx;
+ RefPtr<SVGAnimatedLength> m_cy;
+ RefPtr<SVGAnimatedLength> m_rx;
+ RefPtr<SVGAnimatedLength> m_ry;
};
-DEFINE_NODE_TYPE_CASTS(SVGEllipseElement, hasTagName(SVGNames::ellipseTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.idl
index fcd09c7967f..141ac2eab51 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGEllipseElement.idl
@@ -30,5 +30,3 @@ interface SVGEllipseElement : SVGGeometryElement {
readonly attribute SVGAnimatedLength ry;
};
-SVGEllipseElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGEnumeration.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGEnumeration.cpp
new file mode 100644
index 00000000000..5dcf7ba5cbd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGEnumeration.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGEnumeration.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
+
+namespace WebCore {
+
+inline PassRefPtr<SVGEnumerationBase> toSVGEnumerationBase(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGEnumerationBase::classType());
+ return static_pointer_cast<SVGEnumerationBase>(base.release());
+}
+
+SVGEnumerationBase::~SVGEnumerationBase()
+{
+}
+
+PassRefPtr<SVGPropertyBase> SVGEnumerationBase::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGEnumerationBase> svgEnumeration = clone();
+ svgEnumeration->setValueAsString(value, IGNORE_EXCEPTION);
+ return svgEnumeration.release();
+}
+
+String SVGEnumerationBase::valueAsString() const
+{
+ StringEntries::const_iterator it = m_entries.begin();
+ StringEntries::const_iterator itEnd = m_entries.end();
+ for (; it != itEnd; ++it) {
+ if (m_value == it->first)
+ return it->second;
+ }
+
+ ASSERT(m_value < maxEnumValue());
+ return emptyString();
+}
+
+void SVGEnumerationBase::setValue(unsigned short value, ExceptionState& exceptionState)
+{
+ if (!value) {
+ exceptionState.throwTypeError("The enumeration value provided is 0, which is not settable.");
+ return;
+ }
+
+ if (value > maxEnumValue()) {
+ exceptionState.throwTypeError("The enumeration value provided (" + String::number(value) + ") is larger than the largest allowed value (" + String::number(maxEnumValue()) + ").");
+ return;
+ }
+
+ m_value = value;
+ notifyChange();
+}
+
+void SVGEnumerationBase::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+ StringEntries::const_iterator it = m_entries.begin();
+ StringEntries::const_iterator itEnd = m_entries.end();
+ for (; it != itEnd; ++it) {
+ if (string == it->second) {
+ // 0 corresponds to _UNKNOWN enumeration values, and should not be settable.
+ ASSERT(it->first);
+ m_value = it->first;
+ notifyChange();
+ return;
+ }
+ }
+
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
+ notifyChange();
+}
+
+void SVGEnumerationBase::add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void SVGEnumerationBase::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ ASSERT(animationElement);
+ unsigned short fromEnumeration = animationElement->animationMode() == ToAnimation ? m_value : toSVGEnumerationBase(from)->value();
+ unsigned short toEnumeration = toSVGEnumerationBase(to)->value();
+
+ animationElement->animateDiscreteType<unsigned short>(percentage, fromEnumeration, toEnumeration, m_value);
+}
+
+float SVGEnumerationBase::calculateDistance(PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ // No paced animations for boolean.
+ return -1;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGEnumeration.h b/chromium/third_party/WebKit/Source/core/svg/SVGEnumeration.h
new file mode 100644
index 00000000000..be25de0509e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGEnumeration.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGEnumeration_h
+#define SVGEnumeration_h
+
+#include "core/svg/properties/SVGProperty.h"
+
+namespace WebCore {
+
+class SVGEnumerationBase : public SVGPropertyBase {
+public:
+ typedef std::pair<unsigned short, String> StringEntry;
+ typedef Vector<StringEntry> StringEntries;
+
+ // SVGEnumeration does not have a tear-off type.
+ typedef void TearOffType;
+ typedef unsigned short PrimitiveType;
+
+ virtual ~SVGEnumerationBase();
+
+ unsigned short value() const { return m_value; }
+ void setValue(unsigned short, ExceptionState&);
+
+ // This assumes that |m_entries| are sorted.
+ unsigned short maxEnumValue() const { return m_entries.last().first; }
+
+ // SVGPropertyBase:
+ virtual PassRefPtr<SVGEnumerationBase> clone() const = 0;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+ virtual String valueAsString() const OVERRIDE;
+ void setValueAsString(const String&, ExceptionState&);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedEnumeration; }
+
+ // Ensure that |SVGAnimatedEnumerationBase::setBaseVal| is used instead of |SVGAnimatedProperty<SVGEnumerationBase>::setBaseVal|.
+ void setValue(unsigned short) { ASSERT_NOT_REACHED(); }
+
+protected:
+ SVGEnumerationBase(unsigned short value, const StringEntries& entries)
+ : SVGPropertyBase(classType())
+ , m_value(value)
+ , m_entries(entries)
+ {
+ }
+
+ // Used by SVGMarkerOrientEnumeration.
+ virtual void notifyChange() { }
+
+ unsigned short m_value;
+ const StringEntries& m_entries;
+};
+typedef SVGEnumerationBase::StringEntries SVGEnumerationStringEntries;
+
+template<typename Enum> const SVGEnumerationStringEntries& getStaticStringEntries();
+
+template<typename Enum>
+class SVGEnumeration : public SVGEnumerationBase {
+public:
+ static PassRefPtr<SVGEnumeration<Enum> > create(Enum newValue)
+ {
+ return adoptRef(new SVGEnumeration<Enum>(newValue));
+ }
+
+ virtual ~SVGEnumeration()
+ {
+ }
+
+ virtual PassRefPtr<SVGEnumerationBase> clone() const OVERRIDE
+ {
+ return create(enumValue());
+ }
+
+ Enum enumValue() const
+ {
+ ASSERT(m_value <= maxEnumValue());
+ return static_cast<Enum>(m_value);
+ }
+
+ void setEnumValue(Enum value)
+ {
+ m_value = value;
+ notifyChange();
+ }
+
+protected:
+ explicit SVGEnumeration(Enum newValue)
+ : SVGEnumerationBase(newValue, getStaticStringEntries<Enum>())
+ {
+ }
+};
+
+} // namespace WebCore
+
+#endif // SVGEnumeration_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.cpp
deleted file mode 100644
index 74bfcc52cbd..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2007 Rob Buis <buis@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGExternalResourcesRequired.h"
-
-#include "SVGNames.h"
-#include "core/svg/SVGElement.h"
-
-namespace WebCore {
-
-bool SVGExternalResourcesRequired::parseAttribute(const QualifiedName& name, const AtomicString& value)
-{
- if (name == SVGNames::externalResourcesRequiredAttr) {
- setExternalResourcesRequiredBaseValue(value == "true");
- return true;
- }
-
- return false;
-}
-
-bool SVGExternalResourcesRequired::isKnownAttribute(const QualifiedName& attrName)
-{
- return attrName == SVGNames::externalResourcesRequiredAttr;
-}
-
-void SVGExternalResourcesRequired::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
-{
- supportedAttributes.add(SVGNames::externalResourcesRequiredAttr);
-}
-
-bool SVGExternalResourcesRequired::handleAttributeChange(SVGElement* targetElement, const QualifiedName& attrName)
-{
- ASSERT(targetElement);
- if (!isKnownAttribute(attrName))
- return false;
- if (!targetElement->inDocument())
- return true;
-
- // Handle dynamic updates of the 'externalResourcesRequired' attribute. Only possible case: changing from 'true' to 'false'
- // causes an immediate dispatch of the SVGLoad event. If the attribute value was 'false' before inserting the script element
- // in the document, the SVGLoad event has already been dispatched.
- if (!externalResourcesRequiredBaseValue() && !haveFiredLoadEvent() && !isParserInserted()) {
- setHaveFiredLoadEvent(true);
- ASSERT(targetElement->haveLoadedRequiredResources());
-
- targetElement->sendSVGLoadEventIfPossible();
- }
-
- return true;
-}
-
-void SVGExternalResourcesRequired::dispatchLoadEvent(SVGElement* targetElement)
-{
- bool externalResourcesRequired = externalResourcesRequiredBaseValue();
-
- if (isParserInserted())
- ASSERT(externalResourcesRequired != haveFiredLoadEvent());
- else if (haveFiredLoadEvent())
- return;
-
- // HTML and SVG differ completely in the 'onload' event handling of <script> elements.
- // HTML fires the 'load' event after it sucessfully loaded a remote resource, otherwise an error event.
- // SVG fires the SVGLoad event immediately after parsing the <script> element, if externalResourcesRequired
- // is set to 'false', otherwise it dispatches the 'SVGLoad' event just after loading the remote resource.
- if (!externalResourcesRequired)
- return;
-
- ASSERT(!haveFiredLoadEvent());
-
- // Dispatch SVGLoad event
- setHaveFiredLoadEvent(true);
- ASSERT(targetElement->haveLoadedRequiredResources());
-
- targetElement->sendSVGLoadEventIfPossible();
-}
-
-void SVGExternalResourcesRequired::insertedIntoDocument(SVGElement* targetElement)
-{
- if (isParserInserted())
- return;
-
- // Eventually send SVGLoad event now for the dynamically inserted script element.
- if (externalResourcesRequiredBaseValue())
- return;
- setHaveFiredLoadEvent(true);
- targetElement->sendSVGLoadEventIfPossibleAsynchronously();
-}
-
-void SVGExternalResourcesRequired::finishParsingChildren()
-{
- // A SVGLoad event has been fired by SVGElement::finishParsingChildren.
- if (!externalResourcesRequiredBaseValue())
- setHaveFiredLoadEvent(true);
-}
-
-bool SVGExternalResourcesRequired::haveLoadedRequiredResources() const
-{
- return !externalResourcesRequiredBaseValue() || haveFiredLoadEvent();
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.h b/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.h
deleted file mode 100644
index 04b94fdd05f..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGExternalResourcesRequired_h
-#define SVGExternalResourcesRequired_h
-
-#include "core/dom/QualifiedName.h"
-#include "wtf/HashSet.h"
-
-namespace WebCore {
-
-class Attribute;
-class SVGElement;
-
-// Notes on a SVG 1.1 spec discrepancy:
-// The SVG DOM defines the attribute externalResourcesRequired as being of type SVGAnimatedBoolean, whereas the
-// SVG language definition says that externalResourcesRequired is not animated. Because the SVG language definition
-// states that externalResourcesRequired cannot be animated, the animVal will always be the same as the baseVal.
-// FIXME: When implementing animVal support, make sure that animVal==baseVal for externalResourcesRequired
-class SVGExternalResourcesRequired {
-public:
- virtual ~SVGExternalResourcesRequired() { }
-
- bool parseAttribute(const QualifiedName&, const AtomicString&);
- bool isKnownAttribute(const QualifiedName&);
- void addSupportedAttributes(HashSet<QualifiedName>&);
- bool handleAttributeChange(SVGElement*, const QualifiedName&);
-
-protected:
- // These types look a bit awkward, but have to match the generic types of the SVGAnimatedProperty macros.
- virtual void setExternalResourcesRequiredBaseValue(const bool&) = 0;
- virtual bool& externalResourcesRequiredBaseValue() const = 0;
-
- virtual void setHaveFiredLoadEvent(bool) { }
- virtual bool isParserInserted() const { return false; }
- virtual bool haveFiredLoadEvent() const { return false; }
-
- void dispatchLoadEvent(SVGElement*);
- void insertedIntoDocument(SVGElement*);
- void finishParsingChildren();
- bool haveLoadedRequiredResources() const;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.idl b/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.idl
deleted file mode 100644
index efc83669caa..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGExternalResourcesRequired.idl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
- * Copyright (C) 2006 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
-] interface SVGExternalResourcesRequired {
- readonly attribute SVGAnimatedBoolean externalResourcesRequired;
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp
index 832b4e40e65..5fd49d796ae 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.cpp
@@ -22,37 +22,38 @@
#include "core/svg/SVGFEBlendElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEBlendElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_STRING(SVGFEBlendElement, SVGNames::in2Attr, In2, in2)
-DEFINE_ANIMATED_ENUMERATION(SVGFEBlendElement, SVGNames::modeAttr, Mode, mode, BlendModeType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEBlendElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in2)
- REGISTER_LOCAL_ANIMATED_PROPERTY(mode)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<BlendModeType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(FEBLEND_MODE_NORMAL, "normal"));
+ entries.append(std::make_pair(FEBLEND_MODE_MULTIPLY, "multiply"));
+ entries.append(std::make_pair(FEBLEND_MODE_SCREEN, "screen"));
+ entries.append(std::make_pair(FEBLEND_MODE_DARKEN, "darken"));
+ entries.append(std::make_pair(FEBLEND_MODE_LIGHTEN, "lighten"));
+ }
+ return entries;
+}
inline SVGFEBlendElement::SVGFEBlendElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feBlendTag, document)
- , m_mode(FEBLEND_MODE_NORMAL)
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
+ , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
+ , m_mode(SVGAnimatedEnumeration<BlendModeType>::create(this, SVGNames::modeAttr, FEBLEND_MODE_NORMAL))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEBlendElement();
+ addToPropertyMap(m_in1);
+ addToPropertyMap(m_in2);
+ addToPropertyMap(m_mode);
}
-PassRefPtr<SVGFEBlendElement> SVGFEBlendElement::create(Document& document)
-{
- return adoptRef(new SVGFEBlendElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEBlendElement)
bool SVGFEBlendElement::isSupportedAttribute(const QualifiedName& attrName)
{
@@ -72,31 +73,25 @@ void SVGFEBlendElement::parseAttribute(const QualifiedName& name, const AtomicSt
return;
}
- if (name == SVGNames::modeAttr) {
- BlendModeType propertyValue = SVGPropertyTraits<BlendModeType>::fromString(value);
- if (propertyValue > 0)
- setModeBaseValue(propertyValue);
- return;
- }
-
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ SVGParsingError parseError = NoError;
- if (name == SVGNames::in2Attr) {
- setIn2BaseValue(value);
- return;
- }
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::in2Attr)
+ m_in2->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::modeAttr)
+ m_mode->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFEBlendElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
{
FEBlend* blend = static_cast<FEBlend*>(effect);
if (attrName == SVGNames::modeAttr)
- return blend->setBlendMode(modeCurrentValue());
+ return blend->setBlendMode(m_mode->currentValue()->enumValue());
ASSERT_NOT_REACHED();
return false;
@@ -109,7 +104,7 @@ void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::modeAttr) {
primitiveAttributeChanged(attrName);
@@ -126,13 +121,13 @@ void SVGFEBlendElement::svgAttributeChanged(const QualifiedName& attrName)
PassRefPtr<FilterEffect> SVGFEBlendElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
- FilterEffect* input2 = filterBuilder->getEffectById(in2CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
+ FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value()));
if (!input1 || !input2)
- return 0;
+ return nullptr;
- RefPtr<FilterEffect> effect = FEBlend::create(filter, modeCurrentValue());
+ RefPtr<FilterEffect> effect = FEBlend::create(filter, m_mode->currentValue()->enumValue());
FilterEffectVector& inputEffects = effect->inputEffects();
inputEffects.reserveCapacity(2);
inputEffects.append(input1);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.h
index 20e211dfd0f..20537b1ea13 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.h
@@ -27,65 +27,27 @@
namespace WebCore {
-template<>
-struct SVGPropertyTraits<BlendModeType> {
- static unsigned highestEnumValue() { return FEBLEND_MODE_LIGHTEN; }
-
- static String toString(BlendModeType type)
- {
- switch (type) {
- case FEBLEND_MODE_UNKNOWN:
- return emptyString();
- case FEBLEND_MODE_NORMAL:
- return "normal";
- case FEBLEND_MODE_MULTIPLY:
- return "multiply";
- case FEBLEND_MODE_SCREEN:
- return "screen";
- case FEBLEND_MODE_DARKEN:
- return "darken";
- case FEBLEND_MODE_LIGHTEN:
- return "lighten";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static BlendModeType fromString(const String& value)
- {
- if (value == "normal")
- return FEBLEND_MODE_NORMAL;
- if (value == "multiply")
- return FEBLEND_MODE_MULTIPLY;
- if (value == "screen")
- return FEBLEND_MODE_SCREEN;
- if (value == "darken")
- return FEBLEND_MODE_DARKEN;
- if (value == "lighten")
- return FEBLEND_MODE_LIGHTEN;
- return FEBLEND_MODE_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<BlendModeType>();
class SVGFEBlendElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEBlendElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEBlendElement);
+ SVGAnimatedString* in1() { return m_in1.get(); }
+ SVGAnimatedString* in2() { return m_in2.get(); }
+ SVGAnimatedEnumeration<BlendModeType>* mode() { return m_mode.get(); }
private:
explicit SVGFEBlendElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEBlendElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_STRING(In2, in2)
- DECLARE_ANIMATED_ENUMERATION(Mode, mode, BlendModeType)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedString> m_in1;
+ RefPtr<SVGAnimatedString> m_in2;
+ RefPtr<SVGAnimatedEnumeration<BlendModeType> > m_mode;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.idl
index fc3abe6691d..05cde556e4b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEBlendElement.idl
@@ -23,19 +23,22 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEBlendElement
+
[
- DoNotCheckConstants
+ DoNotCheckConstants,
] interface SVGFEBlendElement : SVGElement {
+
// Blend Mode Types
- const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0;
- const unsigned short SVG_FEBLEND_MODE_NORMAL = 1;
+ const unsigned short SVG_FEBLEND_MODE_UNKNOWN = 0;
+ const unsigned short SVG_FEBLEND_MODE_NORMAL = 1;
const unsigned short SVG_FEBLEND_MODE_MULTIPLY = 2;
- const unsigned short SVG_FEBLEND_MODE_SCREEN = 3;
- const unsigned short SVG_FEBLEND_MODE_DARKEN = 4;
- const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5;
+ const unsigned short SVG_FEBLEND_MODE_SCREEN = 3;
+ const unsigned short SVG_FEBLEND_MODE_DARKEN = 4;
+ const unsigned short SVG_FEBLEND_MODE_LIGHTEN = 5;
- readonly attribute SVGAnimatedString in1;
- readonly attribute SVGAnimatedString in2;
+ readonly attribute SVGAnimatedString in1;
+ readonly attribute SVGAnimatedString in2;
readonly attribute SVGAnimatedEnumeration mode;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp
index a6fc8e4079c..13420a0b270 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.cpp
@@ -22,38 +22,39 @@
#include "core/svg/SVGFEColorMatrixElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEColorMatrixElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_ENUMERATION(SVGFEColorMatrixElement, SVGNames::typeAttr, Type, type, ColorMatrixType)
-DEFINE_ANIMATED_NUMBER_LIST(SVGFEColorMatrixElement, SVGNames::valuesAttr, Values, values)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEColorMatrixElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(type)
- REGISTER_LOCAL_ANIMATED_PROPERTY(values)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ColorMatrixType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(FECOLORMATRIX_TYPE_MATRIX, "matrix"));
+ entries.append(std::make_pair(FECOLORMATRIX_TYPE_SATURATE, "saturate"));
+ entries.append(std::make_pair(FECOLORMATRIX_TYPE_HUEROTATE, "hueRotate"));
+ entries.append(std::make_pair(FECOLORMATRIX_TYPE_LUMINANCETOALPHA, "luminanceToAlpha"));
+ }
+ return entries;
+}
inline SVGFEColorMatrixElement::SVGFEColorMatrixElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feColorMatrixTag, document)
- , m_type(FECOLORMATRIX_TYPE_MATRIX)
+ , m_values(SVGAnimatedNumberList::create(this, SVGNames::valuesAttr, SVGNumberList::create()))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
+ , m_type(SVGAnimatedEnumeration<ColorMatrixType>::create(this, SVGNames::typeAttr, FECOLORMATRIX_TYPE_MATRIX))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEColorMatrixElement();
-}
-PassRefPtr<SVGFEColorMatrixElement> SVGFEColorMatrixElement::create(Document& document)
-{
- return adoptRef(new SVGFEColorMatrixElement(document));
+ addToPropertyMap(m_values);
+ addToPropertyMap(m_in1);
+ addToPropertyMap(m_type);
}
+DEFINE_NODE_FACTORY(SVGFEColorMatrixElement)
+
bool SVGFEColorMatrixElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
@@ -72,36 +73,27 @@ void SVGFEColorMatrixElement::parseAttribute(const QualifiedName& name, const At
return;
}
- if (name == SVGNames::typeAttr) {
- ColorMatrixType propertyValue = SVGPropertyTraits<ColorMatrixType>::fromString(value);
- if (propertyValue > 0)
- setTypeBaseValue(propertyValue);
- return;
- }
+ SVGParsingError parseError = NoError;
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::valuesAttr)
+ m_values->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::typeAttr)
+ m_type->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- if (name == SVGNames::valuesAttr) {
- SVGNumberList newList;
- newList.parse(value);
- detachAnimatedValuesListWrappers(newList.size());
- setValuesBaseValue(newList);
- return;
- }
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFEColorMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
{
FEColorMatrix* colorMatrix = static_cast<FEColorMatrix*>(effect);
if (attrName == SVGNames::typeAttr)
- return colorMatrix->setType(typeCurrentValue());
+ return colorMatrix->setType(m_type->currentValue()->enumValue());
if (attrName == SVGNames::valuesAttr)
- return colorMatrix->setValues(valuesCurrentValue().toFloatVector());
+ return colorMatrix->setValues(m_values->currentValue()->toFloatVector());
ASSERT_NOT_REACHED();
return false;
@@ -114,7 +106,7 @@ void SVGFEColorMatrixElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::typeAttr || attrName == SVGNames::valuesAttr) {
primitiveAttributeChanged(attrName);
@@ -131,13 +123,13 @@ void SVGFEColorMatrixElement::svgAttributeChanged(const QualifiedName& attrName)
PassRefPtr<FilterEffect> SVGFEColorMatrixElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
Vector<float> filterValues;
- ColorMatrixType filterType = typeCurrentValue();
+ ColorMatrixType filterType = m_type->currentValue()->enumValue();
// Use defaults if values is empty (SVG 1.1 15.10).
if (!hasAttribute(SVGNames::valuesAttr)) {
@@ -156,15 +148,15 @@ PassRefPtr<FilterEffect> SVGFEColorMatrixElement::build(SVGFilterBuilder* filter
break;
}
} else {
- SVGNumberList& values = valuesCurrentValue();
- unsigned size = values.size();
+ RefPtr<SVGNumberList> values = m_values->currentValue();
+ size_t size = values->length();
if ((filterType == FECOLORMATRIX_TYPE_MATRIX && size != 20)
|| (filterType == FECOLORMATRIX_TYPE_HUEROTATE && size != 1)
|| (filterType == FECOLORMATRIX_TYPE_SATURATE && size != 1))
- return 0;
+ return nullptr;
- filterValues = values.toFloatVector();
+ filterValues = values->toFloatVector();
}
RefPtr<FilterEffect> effect = FEColorMatrix::create(filter, filterType, filterValues);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.h
index 1ed615f2f24..637254ab916 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.h
@@ -28,61 +28,28 @@
namespace WebCore {
-template<>
-struct SVGPropertyTraits<ColorMatrixType> {
- static unsigned highestEnumValue() { return FECOLORMATRIX_TYPE_LUMINANCETOALPHA; }
-
- static String toString(ColorMatrixType type)
- {
- switch (type) {
- case FECOLORMATRIX_TYPE_UNKNOWN:
- return emptyString();
- case FECOLORMATRIX_TYPE_MATRIX:
- return "matrix";
- case FECOLORMATRIX_TYPE_SATURATE:
- return "saturate";
- case FECOLORMATRIX_TYPE_HUEROTATE:
- return "hueRotate";
- case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
- return "luminanceToAlpha";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static ColorMatrixType fromString(const String& value)
- {
- if (value == "matrix")
- return FECOLORMATRIX_TYPE_MATRIX;
- if (value == "saturate")
- return FECOLORMATRIX_TYPE_SATURATE;
- if (value == "hueRotate")
- return FECOLORMATRIX_TYPE_HUEROTATE;
- if (value == "luminanceToAlpha")
- return FECOLORMATRIX_TYPE_LUMINANCETOALPHA;
- return FECOLORMATRIX_TYPE_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ColorMatrixType>();
class SVGFEColorMatrixElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEColorMatrixElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEColorMatrixElement);
+
+ SVGAnimatedNumberList* values() { return m_values.get(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
+ SVGAnimatedEnumeration<ColorMatrixType>* type() { return m_type.get(); }
private:
explicit SVGFEColorMatrixElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEColorMatrixElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_ENUMERATION(Type, type, ColorMatrixType)
- DECLARE_ANIMATED_NUMBER_LIST(Values, values)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumberList> m_values;
+ RefPtr<SVGAnimatedString> m_in1;
+ RefPtr<SVGAnimatedEnumeration<ColorMatrixType> > m_type;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.idl
index 4d5504b76a6..fa9c032c48a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEColorMatrixElement.idl
@@ -23,19 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEColorMatrixElement
+
[
- DoNotCheckConstants
+ DoNotCheckConstants,
] interface SVGFEColorMatrixElement : SVGElement {
// Color Matrix Types
- const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0;
- const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX = 1;
- const unsigned short SVG_FECOLORMATRIX_TYPE_SATURATE = 2;
- const unsigned short SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
+ const unsigned short SVG_FECOLORMATRIX_TYPE_UNKNOWN = 0;
+ const unsigned short SVG_FECOLORMATRIX_TYPE_MATRIX = 1;
+ const unsigned short SVG_FECOLORMATRIX_TYPE_SATURATE = 2;
+ const unsigned short SVG_FECOLORMATRIX_TYPE_HUEROTATE = 3;
const unsigned short SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4;
- readonly attribute SVGAnimatedString in1;
+ readonly attribute SVGAnimatedString in1;
readonly attribute SVGAnimatedEnumeration type;
- readonly attribute SVGAnimatedNumberList values;
+ readonly attribute SVGAnimatedNumberList values;
};
SVGFEColorMatrixElement implements SVGFilterPrimitiveStandardAttributes;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp
index 127dac25411..7c55fe3217d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.cpp
@@ -22,35 +22,26 @@
#include "core/svg/SVGFEComponentTransferElement.h"
-#include "SVGNames.h"
-#include "platform/graphics/filters/FilterEffect.h"
+#include "core/SVGNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/svg/SVGFEFuncAElement.h"
#include "core/svg/SVGFEFuncBElement.h"
#include "core/svg/SVGFEFuncGElement.h"
#include "core/svg/SVGFEFuncRElement.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
+#include "platform/graphics/filters/FilterEffect.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEComponentTransferElement, SVGNames::inAttr, In1, in1)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEComponentTransferElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFEComponentTransferElement::SVGFEComponentTransferElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feComponentTransferTag, document)
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEComponentTransferElement();
+ addToPropertyMap(m_in1);
}
-PassRefPtr<SVGFEComponentTransferElement> SVGFEComponentTransferElement::create(Document& document)
-{
- return adoptRef(new SVGFEComponentTransferElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEComponentTransferElement)
bool SVGFEComponentTransferElement::isSupportedAttribute(const QualifiedName& attrName)
{
@@ -67,35 +58,37 @@ void SVGFEComponentTransferElement::parseAttribute(const QualifiedName& name, co
return;
}
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
PassRefPtr<FilterEffect> SVGFEComponentTransferElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
ComponentTransferFunction red;
ComponentTransferFunction green;
ComponentTransferFunction blue;
ComponentTransferFunction alpha;
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(SVGNames::feFuncRTag))
- red = toSVGFEFuncRElement(node)->transferFunction();
- else if (node->hasTagName(SVGNames::feFuncGTag))
- green = toSVGFEFuncGElement(node)->transferFunction();
- else if (node->hasTagName(SVGNames::feFuncBTag))
- blue = toSVGFEFuncBElement(node)->transferFunction();
- else if (node->hasTagName(SVGNames::feFuncATag))
- alpha = toSVGFEFuncAElement(node)->transferFunction();
+ for (SVGElement* element = Traversal<SVGElement>::firstChild(*this); element; element = Traversal<SVGElement>::nextSibling(*element)) {
+ if (isSVGFEFuncRElement(*element))
+ red = toSVGFEFuncRElement(*element).transferFunction();
+ else if (isSVGFEFuncGElement(*element))
+ green = toSVGFEFuncGElement(*element).transferFunction();
+ else if (isSVGFEFuncBElement(*element))
+ blue = toSVGFEFuncBElement(*element).transferFunction();
+ else if (isSVGFEFuncAElement(*element))
+ alpha = toSVGFEFuncAElement(*element).transferFunction();
}
RefPtr<FilterEffect> effect = FEComponentTransfer::create(filter, red, green, blue, alpha);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.h
index c83f1fedbdb..682eb576756 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.h
@@ -28,7 +28,8 @@ namespace WebCore {
class SVGFEComponentTransferElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEComponentTransferElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEComponentTransferElement);
+ SVGAnimatedString* in1() { return m_in1.get(); }
private:
explicit SVGFEComponentTransferElement(Document&);
@@ -36,11 +37,9 @@ private:
// FIXME: svgAttributeChanged missing.
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEComponentTransferElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedString> m_in1;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.idl
index a91f58b6c70..e8cc53ea84b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEComponentTransferElement.idl
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEComponentTransferElement
+
interface SVGFEComponentTransferElement : SVGElement {
readonly attribute SVGAnimatedString in1;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp
index d9afc49656f..72c537fba7a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.cpp
@@ -22,46 +22,49 @@
#include "core/svg/SVGFECompositeElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFECompositeElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_STRING(SVGFECompositeElement, SVGNames::in2Attr, In2, in2)
-DEFINE_ANIMATED_ENUMERATION(SVGFECompositeElement, SVGNames::operatorAttr, SVGOperator, svgOperator, CompositeOperationType)
-DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k1Attr, K1, k1)
-DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k2Attr, K2, k2)
-DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k3Attr, K3, k3)
-DEFINE_ANIMATED_NUMBER(SVGFECompositeElement, SVGNames::k4Attr, K4, k4)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFECompositeElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in2)
- REGISTER_LOCAL_ANIMATED_PROPERTY(svgOperator)
- REGISTER_LOCAL_ANIMATED_PROPERTY(k1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(k2)
- REGISTER_LOCAL_ANIMATED_PROPERTY(k3)
- REGISTER_LOCAL_ANIMATED_PROPERTY(k4)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<CompositeOperationType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(FECOMPOSITE_OPERATOR_OVER, "over"));
+ entries.append(std::make_pair(FECOMPOSITE_OPERATOR_IN, "in"));
+ entries.append(std::make_pair(FECOMPOSITE_OPERATOR_OUT, "out"));
+ entries.append(std::make_pair(FECOMPOSITE_OPERATOR_ATOP, "atop"));
+ entries.append(std::make_pair(FECOMPOSITE_OPERATOR_XOR, "xor"));
+ entries.append(std::make_pair(FECOMPOSITE_OPERATOR_ARITHMETIC, "arithmetic"));
+ }
+ return entries;
+}
inline SVGFECompositeElement::SVGFECompositeElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feCompositeTag, document)
- , m_svgOperator(FECOMPOSITE_OPERATOR_OVER)
+ , m_k1(SVGAnimatedNumber::create(this, SVGNames::k1Attr, SVGNumber::create()))
+ , m_k2(SVGAnimatedNumber::create(this, SVGNames::k2Attr, SVGNumber::create()))
+ , m_k3(SVGAnimatedNumber::create(this, SVGNames::k3Attr, SVGNumber::create()))
+ , m_k4(SVGAnimatedNumber::create(this, SVGNames::k4Attr, SVGNumber::create()))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
+ , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
+ , m_svgOperator(SVGAnimatedEnumeration<CompositeOperationType>::create(this, SVGNames::operatorAttr, FECOMPOSITE_OPERATOR_OVER))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFECompositeElement();
-}
-PassRefPtr<SVGFECompositeElement> SVGFECompositeElement::create(Document& document)
-{
- return adoptRef(new SVGFECompositeElement(document));
+ addToPropertyMap(m_k1);
+ addToPropertyMap(m_k2);
+ addToPropertyMap(m_k3);
+ addToPropertyMap(m_k4);
+ addToPropertyMap(m_in1);
+ addToPropertyMap(m_in2);
+ addToPropertyMap(m_svgOperator);
}
+DEFINE_NODE_FACTORY(SVGFECompositeElement)
+
bool SVGFECompositeElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
@@ -84,59 +87,41 @@ void SVGFECompositeElement::parseAttribute(const QualifiedName& name, const Atom
return;
}
- if (name == SVGNames::operatorAttr) {
- CompositeOperationType propertyValue = SVGPropertyTraits<CompositeOperationType>::fromString(value);
- if (propertyValue > 0)
- setSVGOperatorBaseValue(propertyValue);
- return;
- }
-
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
-
- if (name == SVGNames::in2Attr) {
- setIn2BaseValue(value);
- return;
- }
-
- if (name == SVGNames::k1Attr) {
- setK1BaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::k2Attr) {
- setK2BaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::k3Attr) {
- setK3BaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::k4Attr) {
- setK4BaseValue(value.toFloat());
- return;
- }
-
- ASSERT_NOT_REACHED();
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::in2Attr)
+ m_in2->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::k1Attr)
+ m_k1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::k2Attr)
+ m_k2->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::k3Attr)
+ m_k3->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::k4Attr)
+ m_k4->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::operatorAttr)
+ m_svgOperator->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFECompositeElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
{
FEComposite* composite = static_cast<FEComposite*>(effect);
if (attrName == SVGNames::operatorAttr)
- return composite->setOperation(svgOperatorCurrentValue());
+ return composite->setOperation(m_svgOperator->currentValue()->enumValue());
if (attrName == SVGNames::k1Attr)
- return composite->setK1(k1CurrentValue());
+ return composite->setK1(m_k1->currentValue()->value());
if (attrName == SVGNames::k2Attr)
- return composite->setK2(k2CurrentValue());
+ return composite->setK2(m_k2->currentValue()->value());
if (attrName == SVGNames::k3Attr)
- return composite->setK3(k3CurrentValue());
+ return composite->setK3(m_k3->currentValue()->value());
if (attrName == SVGNames::k4Attr)
- return composite->setK4(k4CurrentValue());
+ return composite->setK4(m_k4->currentValue()->value());
ASSERT_NOT_REACHED();
return false;
@@ -150,7 +135,7 @@ void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::operatorAttr
|| attrName == SVGNames::k1Attr
@@ -171,13 +156,13 @@ void SVGFECompositeElement::svgAttributeChanged(const QualifiedName& attrName)
PassRefPtr<FilterEffect> SVGFECompositeElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
- FilterEffect* input2 = filterBuilder->getEffectById(in2CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
+ FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value()));
if (!input1 || !input2)
- return 0;
+ return nullptr;
- RefPtr<FilterEffect> effect = FEComposite::create(filter, svgOperatorCurrentValue(), k1CurrentValue(), k2CurrentValue(), k3CurrentValue(), k4CurrentValue());
+ RefPtr<FilterEffect> effect = FEComposite::create(filter, m_svgOperator->currentValue()->enumValue(), m_k1->currentValue()->value(), m_k2->currentValue()->value(), m_k3->currentValue()->value(), m_k4->currentValue()->value());
FilterEffectVector& inputEffects = effect->inputEffects();
inputEffects.reserveCapacity(2);
inputEffects.append(input1);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.h
index dad0fb2e1a9..8a5877829ca 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.h
@@ -28,73 +28,36 @@
namespace WebCore {
-template<>
-struct SVGPropertyTraits<CompositeOperationType> {
- static unsigned highestEnumValue() { return FECOMPOSITE_OPERATOR_ARITHMETIC; }
-
- static String toString(CompositeOperationType type)
- {
- switch (type) {
- case FECOMPOSITE_OPERATOR_UNKNOWN:
- return emptyString();
- case FECOMPOSITE_OPERATOR_OVER:
- return "over";
- case FECOMPOSITE_OPERATOR_IN:
- return "in";
- case FECOMPOSITE_OPERATOR_OUT:
- return "out";
- case FECOMPOSITE_OPERATOR_ATOP:
- return "atop";
- case FECOMPOSITE_OPERATOR_XOR:
- return "xor";
- case FECOMPOSITE_OPERATOR_ARITHMETIC:
- return "arithmetic";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static CompositeOperationType fromString(const String& value)
- {
- if (value == "over")
- return FECOMPOSITE_OPERATOR_OVER;
- if (value == "in")
- return FECOMPOSITE_OPERATOR_IN;
- if (value == "out")
- return FECOMPOSITE_OPERATOR_OUT;
- if (value == "atop")
- return FECOMPOSITE_OPERATOR_ATOP;
- if (value == "xor")
- return FECOMPOSITE_OPERATOR_XOR;
- if (value == "arithmetic")
- return FECOMPOSITE_OPERATOR_ARITHMETIC;
- return FECOMPOSITE_OPERATOR_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<CompositeOperationType>();
class SVGFECompositeElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFECompositeElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFECompositeElement);
+
+ SVGAnimatedNumber* k1() { return m_k1.get(); }
+ SVGAnimatedNumber* k2() { return m_k2.get(); }
+ SVGAnimatedNumber* k3() { return m_k3.get(); }
+ SVGAnimatedNumber* k4() { return m_k4.get(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
+ SVGAnimatedString* in2() { return m_in2.get(); }
+ SVGAnimatedEnumeration<CompositeOperationType>* svgOperator() { return m_svgOperator.get(); }
private:
explicit SVGFECompositeElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFECompositeElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_STRING(In2, in2)
- DECLARE_ANIMATED_ENUMERATION(SVGOperator, svgOperator, CompositeOperationType)
- DECLARE_ANIMATED_NUMBER(K1, k1)
- DECLARE_ANIMATED_NUMBER(K2, k2)
- DECLARE_ANIMATED_NUMBER(K3, k3)
- DECLARE_ANIMATED_NUMBER(K4, k4)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumber> m_k1;
+ RefPtr<SVGAnimatedNumber> m_k2;
+ RefPtr<SVGAnimatedNumber> m_k3;
+ RefPtr<SVGAnimatedNumber> m_k4;
+ RefPtr<SVGAnimatedString> m_in1;
+ RefPtr<SVGAnimatedString> m_in2;
+ RefPtr<SVGAnimatedEnumeration<CompositeOperationType> > m_svgOperator;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.idl
index 986e4e19aa6..9735ce9ce27 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFECompositeElement.idl
@@ -23,25 +23,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFECompositeElement
+
[
- DoNotCheckConstants
+ DoNotCheckConstants,
] interface SVGFECompositeElement : SVGElement {
// Composite Operators
- const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0;
- const unsigned short SVG_FECOMPOSITE_OPERATOR_OVER = 1;
- const unsigned short SVG_FECOMPOSITE_OPERATOR_IN = 2;
- const unsigned short SVG_FECOMPOSITE_OPERATOR_OUT = 3;
- const unsigned short SVG_FECOMPOSITE_OPERATOR_ATOP = 4;
- const unsigned short SVG_FECOMPOSITE_OPERATOR_XOR = 5;
+ const unsigned short SVG_FECOMPOSITE_OPERATOR_UNKNOWN = 0;
+ const unsigned short SVG_FECOMPOSITE_OPERATOR_OVER = 1;
+ const unsigned short SVG_FECOMPOSITE_OPERATOR_IN = 2;
+ const unsigned short SVG_FECOMPOSITE_OPERATOR_OUT = 3;
+ const unsigned short SVG_FECOMPOSITE_OPERATOR_ATOP = 4;
+ const unsigned short SVG_FECOMPOSITE_OPERATOR_XOR = 5;
const unsigned short SVG_FECOMPOSITE_OPERATOR_ARITHMETIC = 6;
- readonly attribute SVGAnimatedString in1;
- readonly attribute SVGAnimatedString in2;
+ readonly attribute SVGAnimatedString in1;
+ readonly attribute SVGAnimatedString in2;
[ImplementedAs=svgOperator] readonly attribute SVGAnimatedEnumeration operator;
- readonly attribute SVGAnimatedNumber k1;
- readonly attribute SVGAnimatedNumber k2;
- readonly attribute SVGAnimatedNumber k3;
- readonly attribute SVGAnimatedNumber k4;
+ readonly attribute SVGAnimatedNumber k1;
+ readonly attribute SVGAnimatedNumber k2;
+ readonly attribute SVGAnimatedNumber k3;
+ readonly attribute SVGAnimatedNumber k4;
};
SVGFECompositeElement implements SVGFilterPrimitiveStandardAttributes;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp
index 2fad4d9fbad..20c8855fe20 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.cpp
@@ -21,9 +21,8 @@
#include "core/svg/SVGFEConvolveMatrixElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGParserUtilities.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
#include "platform/geometry/FloatPoint.h"
@@ -32,72 +31,45 @@
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEConvolveMatrixElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_INTEGER_MULTIPLE_WRAPPERS(SVGFEConvolveMatrixElement, SVGNames::orderAttr, orderXIdentifier(), OrderX, orderX)
-DEFINE_ANIMATED_INTEGER_MULTIPLE_WRAPPERS(SVGFEConvolveMatrixElement, SVGNames::orderAttr, orderYIdentifier(), OrderY, orderY)
-DEFINE_ANIMATED_NUMBER_LIST(SVGFEConvolveMatrixElement, SVGNames::kernelMatrixAttr, KernelMatrix, kernelMatrix)
-DEFINE_ANIMATED_NUMBER(SVGFEConvolveMatrixElement, SVGNames::divisorAttr, Divisor, divisor)
-DEFINE_ANIMATED_NUMBER(SVGFEConvolveMatrixElement, SVGNames::biasAttr, Bias, bias)
-DEFINE_ANIMATED_INTEGER(SVGFEConvolveMatrixElement, SVGNames::targetXAttr, TargetX, targetX)
-DEFINE_ANIMATED_INTEGER(SVGFEConvolveMatrixElement, SVGNames::targetYAttr, TargetY, targetY)
-DEFINE_ANIMATED_ENUMERATION(SVGFEConvolveMatrixElement, SVGNames::edgeModeAttr, EdgeMode, edgeMode, EdgeModeType)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEConvolveMatrixElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), KernelUnitLengthX, kernelUnitLengthX)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEConvolveMatrixElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), KernelUnitLengthY, kernelUnitLengthY)
-DEFINE_ANIMATED_BOOLEAN(SVGFEConvolveMatrixElement, SVGNames::preserveAlphaAttr, PreserveAlpha, preserveAlpha)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEConvolveMatrixElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(orderX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(orderY)
- REGISTER_LOCAL_ANIMATED_PROPERTY(kernelMatrix)
- REGISTER_LOCAL_ANIMATED_PROPERTY(divisor)
- REGISTER_LOCAL_ANIMATED_PROPERTY(bias)
- REGISTER_LOCAL_ANIMATED_PROPERTY(targetX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(targetY)
- REGISTER_LOCAL_ANIMATED_PROPERTY(edgeMode)
- REGISTER_LOCAL_ANIMATED_PROPERTY(kernelUnitLengthX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(kernelUnitLengthY)
- REGISTER_LOCAL_ANIMATED_PROPERTY(preserveAlpha)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<EdgeModeType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(EDGEMODE_DUPLICATE, "duplicate"));
+ entries.append(std::make_pair(EDGEMODE_WRAP, "wrap"));
+ entries.append(std::make_pair(EDGEMODE_NONE, "none"));
+ }
+ return entries;
+}
inline SVGFEConvolveMatrixElement::SVGFEConvolveMatrixElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feConvolveMatrixTag, document)
- , m_edgeMode(EDGEMODE_DUPLICATE)
+ , m_bias(SVGAnimatedNumber::create(this, SVGNames::biasAttr, SVGNumber::create()))
+ , m_divisor(SVGAnimatedNumber::create(this, SVGNames::divisorAttr, SVGNumber::create()))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
+ , m_edgeMode(SVGAnimatedEnumeration<EdgeModeType>::create(this, SVGNames::edgeModeAttr, EDGEMODE_DUPLICATE))
+ , m_kernelMatrix(SVGAnimatedNumberList::create(this, SVGNames::kernelMatrixAttr, SVGNumberList::create()))
+ , m_kernelUnitLength(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::kernelUnitLengthAttr))
+ , m_order(SVGAnimatedIntegerOptionalInteger::create(this, SVGNames::orderAttr))
+ , m_preserveAlpha(SVGAnimatedBoolean::create(this, SVGNames::preserveAlphaAttr, SVGBoolean::create()))
+ , m_targetX(SVGAnimatedInteger::create(this, SVGNames::targetXAttr, SVGInteger::create()))
+ , m_targetY(SVGAnimatedInteger::create(this, SVGNames::targetYAttr, SVGInteger::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEConvolveMatrixElement();
-}
-PassRefPtr<SVGFEConvolveMatrixElement> SVGFEConvolveMatrixElement::create(Document& document)
-{
- return adoptRef(new SVGFEConvolveMatrixElement(document));
+ addToPropertyMap(m_preserveAlpha);
+ addToPropertyMap(m_divisor);
+ addToPropertyMap(m_bias);
+ addToPropertyMap(m_kernelUnitLength);
+ addToPropertyMap(m_kernelMatrix);
+ addToPropertyMap(m_in1);
+ addToPropertyMap(m_edgeMode);
+ addToPropertyMap(m_order);
+ addToPropertyMap(m_targetX);
+ addToPropertyMap(m_targetY);
}
-const AtomicString& SVGFEConvolveMatrixElement::kernelUnitLengthXIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
-
-const AtomicString& SVGFEConvolveMatrixElement::kernelUnitLengthYIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
-
-const AtomicString& SVGFEConvolveMatrixElement::orderXIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrderX", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
-
-const AtomicString& SVGFEConvolveMatrixElement::orderYIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrderY", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+DEFINE_NODE_FACTORY(SVGFEConvolveMatrixElement)
bool SVGFEConvolveMatrixElement::isSupportedAttribute(const QualifiedName& attrName)
{
@@ -124,133 +96,61 @@ void SVGFEConvolveMatrixElement::parseAttribute(const QualifiedName& name, const
return;
}
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
-
- if (name == SVGNames::orderAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y) && x >= 1 && y >= 1) {
- setOrderXBaseValue(x);
- setOrderYBaseValue(y);
- } else {
- document().accessSVGExtensions()->reportWarning(
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::divisorAttr)
+ m_divisor->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::biasAttr)
+ m_bias->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::kernelUnitLengthAttr)
+ m_kernelUnitLength->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::kernelMatrixAttr)
+ m_kernelMatrix->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::preserveAlphaAttr)
+ m_preserveAlpha->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::edgeModeAttr)
+ m_edgeMode->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::targetXAttr)
+ m_targetX->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::targetYAttr)
+ m_targetY->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::orderAttr) {
+ m_order->setBaseValueAsString(value, parseError);
+ if (parseError == NoError && (orderX()->baseValue()->value() < 1 || orderY()->baseValue()->value() < 1)) {
+ document().accessSVGExtensions().reportWarning(
"feConvolveMatrix: problem parsing order=\"" + value
+ "\". Filtered element will not be displayed.");
}
- return;
- }
-
- if (name == SVGNames::edgeModeAttr) {
- EdgeModeType propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value);
- if (propertyValue > 0)
- setEdgeModeBaseValue(propertyValue);
- else
- document().accessSVGExtensions()->reportWarning(
- "feConvolveMatrix: problem parsing edgeMode=\"" + value
- + "\". Filtered element will not be displayed.");
- return;
- }
-
- if (name == SVGNames::kernelMatrixAttr) {
- SVGNumberList newList;
- newList.parse(value);
- detachAnimatedKernelMatrixListWrappers(newList.size());
- setKernelMatrixBaseValue(newList);
- return;
- }
-
- if (name == SVGNames::divisorAttr) {
- float divisor = value.toFloat();
- if (divisor)
- setDivisorBaseValue(divisor);
- else
- document().accessSVGExtensions()->reportWarning(
- "feConvolveMatrix: problem parsing divisor=\"" + value
- + "\". Filtered element will not be displayed.");
- return;
- }
-
- if (name == SVGNames::biasAttr) {
- setBiasBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::targetXAttr) {
- setTargetXBaseValue(value.string().toUIntStrict());
- return;
- }
-
- if (name == SVGNames::targetYAttr) {
- setTargetYBaseValue(value.string().toUIntStrict());
- return;
- }
-
- if (name == SVGNames::kernelUnitLengthAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y) && x > 0 && y > 0) {
- setKernelUnitLengthXBaseValue(x);
- setKernelUnitLengthYBaseValue(y);
- } else {
- document().accessSVGExtensions()->reportWarning(
- "feConvolveMatrix: problem parsing kernelUnitLength=\"" + value
- + "\". Filtered element will not be displayed.");
- }
- return;
- }
-
- if (name == SVGNames::preserveAlphaAttr) {
- if (value == "true")
- setPreserveAlphaBaseValue(true);
- else if (value == "false")
- setPreserveAlphaBaseValue(false);
- else
- document().accessSVGExtensions()->reportWarning(
- "feConvolveMatrix: problem parsing preserveAlphaAttr=\"" + value
- + "\". Filtered element will not be displayed.");
- return;
- }
+ } else
+ ASSERT_NOT_REACHED();
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFEConvolveMatrixElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
{
FEConvolveMatrix* convolveMatrix = static_cast<FEConvolveMatrix*>(effect);
if (attrName == SVGNames::edgeModeAttr)
- return convolveMatrix->setEdgeMode(edgeModeCurrentValue());
+ return convolveMatrix->setEdgeMode(m_edgeMode->currentValue()->enumValue());
if (attrName == SVGNames::divisorAttr)
- return convolveMatrix->setDivisor(divisorCurrentValue());
+ return convolveMatrix->setDivisor(m_divisor->currentValue()->value());
if (attrName == SVGNames::biasAttr)
- return convolveMatrix->setBias(biasCurrentValue());
+ return convolveMatrix->setBias(m_bias->currentValue()->value());
if (attrName == SVGNames::targetXAttr)
- return convolveMatrix->setTargetOffset(IntPoint(targetXCurrentValue(), targetYCurrentValue()));
+ return convolveMatrix->setTargetOffset(IntPoint(m_targetX->currentValue()->value(), m_targetY->currentValue()->value()));
if (attrName == SVGNames::targetYAttr)
- return convolveMatrix->setTargetOffset(IntPoint(targetXCurrentValue(), targetYCurrentValue()));
+ return convolveMatrix->setTargetOffset(IntPoint(m_targetX->currentValue()->value(), m_targetY->currentValue()->value()));
if (attrName == SVGNames::kernelUnitLengthAttr)
- return convolveMatrix->setKernelUnitLength(FloatPoint(kernelUnitLengthXCurrentValue(), kernelUnitLengthYCurrentValue()));
+ return convolveMatrix->setKernelUnitLength(FloatPoint(kernelUnitLengthX()->currentValue()->value(), kernelUnitLengthY()->currentValue()->value()));
if (attrName == SVGNames::preserveAlphaAttr)
- return convolveMatrix->setPreserveAlpha(preserveAlphaCurrentValue());
+ return convolveMatrix->setPreserveAlpha(m_preserveAlpha->currentValue()->value());
ASSERT_NOT_REACHED();
return false;
}
-void SVGFEConvolveMatrixElement::setOrder(float x, float y)
-{
- setOrderXBaseValue(x);
- setOrderYBaseValue(y);
- invalidate();
-}
-
-void SVGFEConvolveMatrixElement::setKernelUnitLength(float x, float y)
-{
- setKernelUnitLengthXBaseValue(x);
- setKernelUnitLengthYBaseValue(y);
- invalidate();
-}
-
void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrName)
{
if (!isSupportedAttribute(attrName)) {
@@ -258,7 +158,7 @@ void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrNa
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::edgeModeAttr
|| attrName == SVGNames::divisorAttr
@@ -283,63 +183,64 @@ void SVGFEConvolveMatrixElement::svgAttributeChanged(const QualifiedName& attrNa
PassRefPtr<FilterEffect> SVGFEConvolveMatrixElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
- int orderXValue = orderXCurrentValue();
- int orderYValue = orderYCurrentValue();
+ int orderXValue = orderX()->currentValue()->value();
+ int orderYValue = orderY()->currentValue()->value();
if (!hasAttribute(SVGNames::orderAttr)) {
orderXValue = 3;
orderYValue = 3;
}
// Spec says order must be > 0. Bail if it is not.
if (orderXValue < 1 || orderYValue < 1)
- return 0;
- SVGNumberList& kernelMatrix = this->kernelMatrixCurrentValue();
- int kernelMatrixSize = kernelMatrix.size();
+ return nullptr;
+ RefPtr<SVGNumberList> kernelMatrix = this->m_kernelMatrix->currentValue();
+ size_t kernelMatrixSize = kernelMatrix->length();
// The spec says this is a requirement, and should bail out if fails
- if (orderXValue * orderYValue != kernelMatrixSize)
- return 0;
+ if (orderXValue * orderYValue != static_cast<int>(kernelMatrixSize))
+ return nullptr;
- int targetXValue = targetXCurrentValue();
- int targetYValue = targetYCurrentValue();
+ int targetXValue = m_targetX->currentValue()->value();
+ int targetYValue = m_targetY->currentValue()->value();
if (hasAttribute(SVGNames::targetXAttr) && (targetXValue < 0 || targetXValue >= orderXValue))
- return 0;
+ return nullptr;
// The spec says the default value is: targetX = floor ( orderX / 2 ))
if (!hasAttribute(SVGNames::targetXAttr))
targetXValue = static_cast<int>(floorf(orderXValue / 2));
if (hasAttribute(SVGNames::targetYAttr) && (targetYValue < 0 || targetYValue >= orderYValue))
- return 0;
+ return nullptr;
// The spec says the default value is: targetY = floor ( orderY / 2 ))
if (!hasAttribute(SVGNames::targetYAttr))
targetYValue = static_cast<int>(floorf(orderYValue / 2));
// Spec says default kernelUnitLength is 1.0, and a specified length cannot be 0.
- int kernelUnitLengthXValue = kernelUnitLengthXCurrentValue();
- int kernelUnitLengthYValue = kernelUnitLengthYCurrentValue();
+ // FIXME: Why is this cast from float -> int -> float?
+ int kernelUnitLengthXValue = kernelUnitLengthX()->currentValue()->value();
+ int kernelUnitLengthYValue = kernelUnitLengthY()->currentValue()->value();
if (!hasAttribute(SVGNames::kernelUnitLengthAttr)) {
kernelUnitLengthXValue = 1;
kernelUnitLengthYValue = 1;
}
if (kernelUnitLengthXValue <= 0 || kernelUnitLengthYValue <= 0)
- return 0;
+ return nullptr;
- float divisorValue = divisorCurrentValue();
+ float divisorValue = m_divisor->currentValue()->value();
if (hasAttribute(SVGNames::divisorAttr) && !divisorValue)
- return 0;
+ return nullptr;
if (!hasAttribute(SVGNames::divisorAttr)) {
- for (int i = 0; i < kernelMatrixSize; ++i)
- divisorValue += kernelMatrix.at(i).value();
+ for (size_t i = 0; i < kernelMatrixSize; ++i)
+ divisorValue += kernelMatrix->at(i)->value();
if (!divisorValue)
divisorValue = 1;
}
RefPtr<FilterEffect> effect = FEConvolveMatrix::create(filter,
IntSize(orderXValue, orderYValue), divisorValue,
- biasCurrentValue(), IntPoint(targetXValue, targetYValue), edgeModeCurrentValue(),
- FloatPoint(kernelUnitLengthXValue, kernelUnitLengthYValue), preserveAlphaCurrentValue(), kernelMatrix.toFloatVector());
+ m_bias->currentValue()->value(), IntPoint(targetXValue, targetYValue), m_edgeMode->currentValue()->enumValue(),
+ FloatPoint(kernelUnitLengthXValue, kernelUnitLengthYValue), m_preserveAlpha->currentValue()->value(), m_kernelMatrix->currentValue()->toFloatVector());
effect->inputEffects().append(input1);
return effect.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.h
index 4bc21ab5fc4..ada653b9b4a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.h
@@ -23,81 +23,53 @@
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedInteger.h"
+#include "core/svg/SVGAnimatedIntegerOptionalInteger.h"
#include "core/svg/SVGAnimatedNumber.h"
#include "core/svg/SVGAnimatedNumberList.h"
+#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "platform/graphics/filters/FEConvolveMatrix.h"
namespace WebCore {
-template<>
-struct SVGPropertyTraits<EdgeModeType> {
- static unsigned highestEnumValue() { return EDGEMODE_NONE; }
-
- static String toString(EdgeModeType type)
- {
- switch (type) {
- case EDGEMODE_UNKNOWN:
- return emptyString();
- case EDGEMODE_DUPLICATE:
- return "duplicate";
- case EDGEMODE_WRAP:
- return "wrap";
- case EDGEMODE_NONE:
- return "none";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static EdgeModeType fromString(const String& value)
- {
- if (value == "duplicate")
- return EDGEMODE_DUPLICATE;
- if (value == "wrap")
- return EDGEMODE_WRAP;
- if (value == "none")
- return EDGEMODE_NONE;
- return EDGEMODE_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<EdgeModeType>();
class SVGFEConvolveMatrixElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEConvolveMatrixElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEConvolveMatrixElement);
- void setOrder(float orderX, float orderY);
- void setKernelUnitLength(float kernelUnitLengthX, float kernelUnitLengthY);
+ SVGAnimatedBoolean* preserveAlpha() { return m_preserveAlpha.get(); }
+ SVGAnimatedNumber* divisor() { return m_divisor.get(); }
+ SVGAnimatedNumber* bias() { return m_bias.get(); }
+ SVGAnimatedNumber* kernelUnitLengthX() { return m_kernelUnitLength->firstNumber(); }
+ SVGAnimatedNumber* kernelUnitLengthY() { return m_kernelUnitLength->secondNumber(); }
+ SVGAnimatedNumberList* kernelMatrix() { return m_kernelMatrix.get(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
+ SVGAnimatedEnumeration<EdgeModeType>* edgeMode() { return m_edgeMode.get(); }
+ SVGAnimatedInteger* orderX() { return m_order->firstInteger(); }
+ SVGAnimatedInteger* orderY() { return m_order->secondInteger(); }
+ SVGAnimatedInteger* targetX() { return m_targetX.get(); }
+ SVGAnimatedInteger* targetY() { return m_targetY.get(); }
private:
explicit SVGFEConvolveMatrixElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
-
- static const AtomicString& orderXIdentifier();
- static const AtomicString& orderYIdentifier();
- static const AtomicString& kernelUnitLengthXIdentifier();
- static const AtomicString& kernelUnitLengthYIdentifier();
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEConvolveMatrixElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_INTEGER(OrderX, orderX)
- DECLARE_ANIMATED_INTEGER(OrderY, orderY)
- DECLARE_ANIMATED_NUMBER_LIST(KernelMatrix, kernelMatrix)
- DECLARE_ANIMATED_NUMBER(Divisor, divisor)
- DECLARE_ANIMATED_NUMBER(Bias, bias)
- DECLARE_ANIMATED_INTEGER(TargetX, targetX)
- DECLARE_ANIMATED_INTEGER(TargetY, targetY)
- DECLARE_ANIMATED_ENUMERATION(EdgeMode, edgeMode, EdgeModeType)
- DECLARE_ANIMATED_NUMBER(KernelUnitLengthX, kernelUnitLengthX)
- DECLARE_ANIMATED_NUMBER(KernelUnitLengthY, kernelUnitLengthY)
- DECLARE_ANIMATED_BOOLEAN(PreserveAlpha, preserveAlpha)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumber> m_bias;
+ RefPtr<SVGAnimatedNumber> m_divisor;
+ RefPtr<SVGAnimatedString> m_in1;
+ RefPtr<SVGAnimatedEnumeration<EdgeModeType> > m_edgeMode;
+ RefPtr<SVGAnimatedNumberList> m_kernelMatrix;
+ RefPtr<SVGAnimatedNumberOptionalNumber> m_kernelUnitLength;
+ RefPtr<SVGAnimatedIntegerOptionalInteger> m_order;
+ RefPtr<SVGAnimatedBoolean> m_preserveAlpha;
+ RefPtr<SVGAnimatedInteger> m_targetX;
+ RefPtr<SVGAnimatedInteger> m_targetY;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.idl
index b759230c924..ea35c38eba4 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEConvolveMatrixElement.idl
@@ -23,27 +23,30 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG11/filters.html#InterfaceSVGFEConvolveMatrixElement
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEConvolveMatrixElement
+
[
- DoNotCheckConstants
+ DoNotCheckConstants,
] interface SVGFEConvolveMatrixElement : SVGElement {
// Edge Mode Values
- const unsigned short SVG_EDGEMODE_UNKNOWN = 0;
+ const unsigned short SVG_EDGEMODE_UNKNOWN = 0;
const unsigned short SVG_EDGEMODE_DUPLICATE = 1;
- const unsigned short SVG_EDGEMODE_WRAP = 2;
- const unsigned short SVG_EDGEMODE_NONE = 3;
+ const unsigned short SVG_EDGEMODE_WRAP = 2;
+ const unsigned short SVG_EDGEMODE_NONE = 3;
- readonly attribute SVGAnimatedString in1;
- readonly attribute SVGAnimatedInteger orderX;
- readonly attribute SVGAnimatedInteger orderY;
- readonly attribute SVGAnimatedNumberList kernelMatrix;
- readonly attribute SVGAnimatedNumber divisor;
- readonly attribute SVGAnimatedNumber bias;
- readonly attribute SVGAnimatedInteger targetX;
- readonly attribute SVGAnimatedInteger targetY;
+ readonly attribute SVGAnimatedString in1;
+ readonly attribute SVGAnimatedInteger orderX;
+ readonly attribute SVGAnimatedInteger orderY;
+ readonly attribute SVGAnimatedNumberList kernelMatrix;
+ readonly attribute SVGAnimatedNumber divisor;
+ readonly attribute SVGAnimatedNumber bias;
+ readonly attribute SVGAnimatedInteger targetX;
+ readonly attribute SVGAnimatedInteger targetY;
readonly attribute SVGAnimatedEnumeration edgeMode;
- readonly attribute SVGAnimatedNumber kernelUnitLengthX;
- readonly attribute SVGAnimatedNumber kernelUnitLengthY;
- readonly attribute SVGAnimatedBoolean preserveAlpha;
+ readonly attribute SVGAnimatedNumber kernelUnitLengthX;
+ readonly attribute SVGAnimatedNumber kernelUnitLengthY;
+ readonly attribute SVGAnimatedBoolean preserveAlpha; // in SVG 1.1, removed in SVG 2
};
SVGFEConvolveMatrixElement implements SVGFilterPrimitiveStandardAttributes;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
index 9d18e3ccc74..d2aa04c3e52 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.cpp
@@ -22,7 +22,6 @@
#include "core/svg/SVGFEDiffuseLightingElement.h"
#include "core/rendering/style/RenderStyle.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGParserUtilities.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
#include "platform/graphics/filters/FEDiffuseLighting.h"
@@ -30,47 +29,22 @@
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEDiffuseLightingElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_NUMBER(SVGFEDiffuseLightingElement, SVGNames::diffuseConstantAttr, DiffuseConstant, diffuseConstant)
-DEFINE_ANIMATED_NUMBER(SVGFEDiffuseLightingElement, SVGNames::surfaceScaleAttr, SurfaceScale, surfaceScale)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), KernelUnitLengthX, kernelUnitLengthX)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEDiffuseLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), KernelUnitLengthY, kernelUnitLengthY)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEDiffuseLightingElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(diffuseConstant)
- REGISTER_LOCAL_ANIMATED_PROPERTY(surfaceScale)
- REGISTER_LOCAL_ANIMATED_PROPERTY(kernelUnitLengthX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(kernelUnitLengthY)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFEDiffuseLightingElement::SVGFEDiffuseLightingElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feDiffuseLightingTag, document)
- , m_diffuseConstant(1)
- , m_surfaceScale(1)
+ , m_diffuseConstant(SVGAnimatedNumber::create(this, SVGNames::diffuseConstantAttr, SVGNumber::create(1)))
+ , m_surfaceScale(SVGAnimatedNumber::create(this, SVGNames::surfaceScaleAttr, SVGNumber::create(1)))
+ , m_kernelUnitLength(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::kernelUnitLengthAttr))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEDiffuseLightingElement();
-}
-
-PassRefPtr<SVGFEDiffuseLightingElement> SVGFEDiffuseLightingElement::create(Document& document)
-{
- return adoptRef(new SVGFEDiffuseLightingElement(document));
-}
-const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthXIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral));
- return s_identifier;
+ addToPropertyMap(m_diffuseConstant);
+ addToPropertyMap(m_surfaceScale);
+ addToPropertyMap(m_kernelUnitLength);
+ addToPropertyMap(m_in1);
}
-const AtomicString& SVGFEDiffuseLightingElement::kernelUnitLengthYIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+DEFINE_NODE_FACTORY(SVGFEDiffuseLightingElement)
bool SVGFEDiffuseLightingElement::isSupportedAttribute(const QualifiedName& attrName)
{
@@ -92,31 +66,20 @@ void SVGFEDiffuseLightingElement::parseAttribute(const QualifiedName& name, cons
return;
}
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ SVGParsingError parseError = NoError;
- if (name == SVGNames::surfaceScaleAttr) {
- setSurfaceScaleBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::diffuseConstantAttr) {
- setDiffuseConstantBaseValue(value.toFloat());
- return;
- }
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::diffuseConstantAttr)
+ m_diffuseConstant->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::surfaceScaleAttr)
+ m_surfaceScale->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::kernelUnitLengthAttr)
+ m_kernelUnitLength->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- if (name == SVGNames::kernelUnitLengthAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y)) {
- setKernelUnitLengthXBaseValue(x);
- setKernelUnitLengthYBaseValue(y);
- }
- return;
- }
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -130,35 +93,35 @@ bool SVGFEDiffuseLightingElement::setFilterEffectAttribute(FilterEffect* effect,
return diffuseLighting->setLightingColor(renderer->style()->svgStyle()->lightingColor());
}
if (attrName == SVGNames::surfaceScaleAttr)
- return diffuseLighting->setSurfaceScale(surfaceScaleCurrentValue());
+ return diffuseLighting->setSurfaceScale(m_surfaceScale->currentValue()->value());
if (attrName == SVGNames::diffuseConstantAttr)
- return diffuseLighting->setDiffuseConstant(diffuseConstantCurrentValue());
+ return diffuseLighting->setDiffuseConstant(m_diffuseConstant->currentValue()->value());
LightSource* lightSource = const_cast<LightSource*>(diffuseLighting->lightSource());
- const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
+ const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(*this);
ASSERT(lightSource);
ASSERT(lightElement);
if (attrName == SVGNames::azimuthAttr)
- return lightSource->setAzimuth(lightElement->azimuthCurrentValue());
+ return lightSource->setAzimuth(lightElement->azimuth()->currentValue()->value());
if (attrName == SVGNames::elevationAttr)
- return lightSource->setElevation(lightElement->elevationCurrentValue());
+ return lightSource->setElevation(lightElement->elevation()->currentValue()->value());
if (attrName == SVGNames::xAttr)
- return lightSource->setX(lightElement->xCurrentValue());
+ return lightSource->setX(lightElement->x()->currentValue()->value());
if (attrName == SVGNames::yAttr)
- return lightSource->setY(lightElement->yCurrentValue());
+ return lightSource->setY(lightElement->y()->currentValue()->value());
if (attrName == SVGNames::zAttr)
- return lightSource->setZ(lightElement->zCurrentValue());
+ return lightSource->setZ(lightElement->z()->currentValue()->value());
if (attrName == SVGNames::pointsAtXAttr)
- return lightSource->setPointsAtX(lightElement->pointsAtXCurrentValue());
+ return lightSource->setPointsAtX(lightElement->pointsAtX()->currentValue()->value());
if (attrName == SVGNames::pointsAtYAttr)
- return lightSource->setPointsAtY(lightElement->pointsAtYCurrentValue());
+ return lightSource->setPointsAtY(lightElement->pointsAtY()->currentValue()->value());
if (attrName == SVGNames::pointsAtZAttr)
- return lightSource->setPointsAtZ(lightElement->pointsAtZCurrentValue());
+ return lightSource->setPointsAtZ(lightElement->pointsAtZ()->currentValue()->value());
if (attrName == SVGNames::specularExponentAttr)
- return lightSource->setSpecularExponent(lightElement->specularExponentCurrentValue());
+ return lightSource->setSpecularExponent(lightElement->specularExponent()->currentValue()->value());
if (attrName == SVGNames::limitingConeAngleAttr)
- return lightSource->setLimitingConeAngle(lightElement->limitingConeAngleCurrentValue());
+ return lightSource->setLimitingConeAngle(lightElement->limitingConeAngle()->currentValue()->value());
ASSERT_NOT_REACHED();
return false;
@@ -171,7 +134,7 @@ void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrN
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::surfaceScaleAttr
|| attrName == SVGNames::diffuseConstantAttr
@@ -191,7 +154,7 @@ void SVGFEDiffuseLightingElement::svgAttributeChanged(const QualifiedName& attrN
void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
{
- if (SVGFELightElement::findLightElement(this) != lightElement)
+ if (SVGFELightElement::findLightElement(*this) != lightElement)
return;
// The light element has different attribute names.
@@ -200,24 +163,25 @@ void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightE
PassRefPtr<FilterEffect> SVGFEDiffuseLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
- RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this);
- if (!lightSource)
- return 0;
+ SVGFELightElement* lightNode = SVGFELightElement::findLightElement(*this);
+ if (!lightNode)
+ return nullptr;
RenderObject* renderer = this->renderer();
if (!renderer)
- return 0;
+ return nullptr;
ASSERT(renderer->style());
Color color = renderer->style()->svgStyle()->lightingColor();
- RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, surfaceScaleCurrentValue(), diffuseConstantCurrentValue(),
- kernelUnitLengthXCurrentValue(), kernelUnitLengthYCurrentValue(), lightSource.release());
+ RefPtr<LightSource> lightSource = lightNode->lightSource(filter);
+ RefPtr<FilterEffect> effect = FEDiffuseLighting::create(filter, color, m_surfaceScale->currentValue()->value(), m_diffuseConstant->currentValue()->value(),
+ kernelUnitLengthX()->currentValue()->value(), kernelUnitLengthY()->currentValue()->value(), lightSource.release());
effect->inputEffects().append(input1);
return effect.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.h
index c3cbbc4b035..08fd3b62134 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.h
@@ -22,43 +22,39 @@
#ifndef SVGFEDiffuseLightingElement_h
#define SVGFEDiffuseLightingElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
+#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
#include "core/svg/SVGFELightElement.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
namespace WebCore {
-class FEDiffuseLighting;
-class SVGColor;
-
class SVGFEDiffuseLightingElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEDiffuseLightingElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEDiffuseLightingElement);
void lightElementAttributeChanged(const SVGFELightElement*, const QualifiedName&);
+ SVGAnimatedNumber* diffuseConstant() { return m_diffuseConstant.get(); }
+ SVGAnimatedNumber* surfaceScale() { return m_surfaceScale.get(); }
+ SVGAnimatedNumber* kernelUnitLengthX() { return m_kernelUnitLength->firstNumber(); }
+ SVGAnimatedNumber* kernelUnitLengthY() { return m_kernelUnitLength->secondNumber(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
+
private:
explicit SVGFEDiffuseLightingElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
-
- static const AtomicString& kernelUnitLengthXIdentifier();
- static const AtomicString& kernelUnitLengthYIdentifier();
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEDiffuseLightingElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_NUMBER(DiffuseConstant, diffuseConstant)
- DECLARE_ANIMATED_NUMBER(SurfaceScale, surfaceScale)
- DECLARE_ANIMATED_NUMBER(KernelUnitLengthX, kernelUnitLengthX)
- DECLARE_ANIMATED_NUMBER(KernelUnitLengthY, kernelUnitLengthY)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
+
+ RefPtr<SVGAnimatedNumber> m_diffuseConstant;
+ RefPtr<SVGAnimatedNumber> m_surfaceScale;
+ RefPtr<SVGAnimatedNumberOptionalNumber> m_kernelUnitLength;
+ RefPtr<SVGAnimatedString> m_in1;
};
-DEFINE_NODE_TYPE_CASTS(SVGFEDiffuseLightingElement, hasTagName(SVGNames::feDiffuseLightingTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.idl
index b4ebb2bc467..f0e42d2847c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDiffuseLightingElement.idl
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEDiffuseLightingElement
+
interface SVGFEDiffuseLightingElement : SVGElement {
readonly attribute SVGAnimatedString in1;
readonly attribute SVGAnimatedNumber surfaceScale;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp
index 6aff75bdbfd..9b8a5dfa625 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.cpp
@@ -21,43 +21,43 @@
#include "core/svg/SVGFEDisplacementMapElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEDisplacementMapElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_STRING(SVGFEDisplacementMapElement, SVGNames::in2Attr, In2, in2)
-DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::xChannelSelectorAttr, XChannelSelector, xChannelSelector, ChannelSelectorType)
-DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::yChannelSelectorAttr, YChannelSelector, yChannelSelector, ChannelSelectorType)
-DEFINE_ANIMATED_NUMBER(SVGFEDisplacementMapElement, SVGNames::scaleAttr, Scale, scale)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEDisplacementMapElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in2)
- REGISTER_LOCAL_ANIMATED_PROPERTY(xChannelSelector)
- REGISTER_LOCAL_ANIMATED_PROPERTY(yChannelSelector)
- REGISTER_LOCAL_ANIMATED_PROPERTY(scale)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ChannelSelectorType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(CHANNEL_R, "R"));
+ entries.append(std::make_pair(CHANNEL_G, "G"));
+ entries.append(std::make_pair(CHANNEL_B, "B"));
+ entries.append(std::make_pair(CHANNEL_A, "A"));
+ }
+ return entries;
+}
inline SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feDisplacementMapTag, document)
- , m_xChannelSelector(CHANNEL_A)
- , m_yChannelSelector(CHANNEL_A)
+ , m_scale(SVGAnimatedNumber::create(this, SVGNames::scaleAttr, SVGNumber::create(0)))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
+ , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
+ , m_xChannelSelector(SVGAnimatedEnumeration<ChannelSelectorType>::create(this, SVGNames::xChannelSelectorAttr, CHANNEL_A))
+ , m_yChannelSelector(SVGAnimatedEnumeration<ChannelSelectorType>::create(this, SVGNames::yChannelSelectorAttr, CHANNEL_A))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEDisplacementMapElement();
-}
-PassRefPtr<SVGFEDisplacementMapElement> SVGFEDisplacementMapElement::create(Document& document)
-{
- return adoptRef(new SVGFEDisplacementMapElement(document));
+ addToPropertyMap(m_scale);
+ addToPropertyMap(m_in1);
+ addToPropertyMap(m_in2);
+ addToPropertyMap(m_xChannelSelector);
+ addToPropertyMap(m_yChannelSelector);
}
+DEFINE_NODE_FACTORY(SVGFEDisplacementMapElement)
+
bool SVGFEDisplacementMapElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
@@ -78,47 +78,33 @@ void SVGFEDisplacementMapElement::parseAttribute(const QualifiedName& name, cons
return;
}
- if (name == SVGNames::xChannelSelectorAttr) {
- ChannelSelectorType propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value);
- if (propertyValue > 0)
- setXChannelSelectorBaseValue(propertyValue);
- return;
- }
-
- if (name == SVGNames::yChannelSelectorAttr) {
- ChannelSelectorType propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value);
- if (propertyValue > 0)
- setYChannelSelectorBaseValue(propertyValue);
- return;
- }
-
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
-
- if (name == SVGNames::in2Attr) {
- setIn2BaseValue(value);
- return;
- }
-
- if (name == SVGNames::scaleAttr) {
- setScaleBaseValue(value.toFloat());
- return;
- }
-
- ASSERT_NOT_REACHED();
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::in2Attr)
+ m_in2->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::scaleAttr)
+ m_scale->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::xChannelSelectorAttr)
+ m_xChannelSelector->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::yChannelSelectorAttr)
+ m_yChannelSelector->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFEDisplacementMapElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
{
FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect);
if (attrName == SVGNames::xChannelSelectorAttr)
- return displacementMap->setXChannelSelector(xChannelSelectorCurrentValue());
+ return displacementMap->setXChannelSelector(m_xChannelSelector->currentValue()->enumValue());
if (attrName == SVGNames::yChannelSelectorAttr)
- return displacementMap->setYChannelSelector(yChannelSelectorCurrentValue());
+ return displacementMap->setYChannelSelector(m_yChannelSelector->currentValue()->enumValue());
if (attrName == SVGNames::scaleAttr)
- return displacementMap->setScale(scaleCurrentValue());
+ return displacementMap->setScale(m_scale->currentValue()->value());
ASSERT_NOT_REACHED();
return false;
@@ -131,7 +117,7 @@ void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrN
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::xChannelSelectorAttr || attrName == SVGNames::yChannelSelectorAttr || attrName == SVGNames::scaleAttr) {
primitiveAttributeChanged(attrName);
@@ -148,13 +134,13 @@ void SVGFEDisplacementMapElement::svgAttributeChanged(const QualifiedName& attrN
PassRefPtr<FilterEffect> SVGFEDisplacementMapElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
- FilterEffect* input2 = filterBuilder->getEffectById(in2CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
+ FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value()));
if (!input1 || !input2)
- return 0;
+ return nullptr;
- RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, xChannelSelectorCurrentValue(), yChannelSelectorCurrentValue(), scaleCurrentValue());
+ RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, m_xChannelSelector->currentValue()->enumValue(), m_yChannelSelector->currentValue()->enumValue(), m_scale->currentValue()->value());
FilterEffectVector& inputEffects = effect->inputEffects();
inputEffects.reserveCapacity(2);
inputEffects.append(input1);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.h
index cb0c70733ce..356925b8d7d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.h
@@ -27,65 +27,34 @@
namespace WebCore {
-template<>
-struct SVGPropertyTraits<ChannelSelectorType> {
- static unsigned highestEnumValue() { return CHANNEL_A; }
-
- static String toString(ChannelSelectorType type)
- {
- switch (type) {
- case CHANNEL_UNKNOWN:
- return emptyString();
- case CHANNEL_R:
- return "R";
- case CHANNEL_G:
- return "G";
- case CHANNEL_B:
- return "B";
- case CHANNEL_A:
- return "A";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static ChannelSelectorType fromString(const String& value)
- {
- if (value == "R")
- return CHANNEL_R;
- if (value == "G")
- return CHANNEL_G;
- if (value == "B")
- return CHANNEL_B;
- if (value == "A")
- return CHANNEL_A;
- return CHANNEL_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ChannelSelectorType>();
class SVGFEDisplacementMapElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEDisplacementMapElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEDisplacementMapElement);
static ChannelSelectorType stringToChannel(const String&);
+ SVGAnimatedNumber* scale() { return m_scale.get(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
+ SVGAnimatedString* in2() { return m_in2.get(); }
+ SVGAnimatedEnumeration<ChannelSelectorType>* xChannelSelector() { return m_xChannelSelector.get(); }
+ SVGAnimatedEnumeration<ChannelSelectorType>* yChannelSelector() { return m_yChannelSelector.get(); }
+
private:
SVGFEDisplacementMapElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEDisplacementMapElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_STRING(In2, in2)
- DECLARE_ANIMATED_ENUMERATION(XChannelSelector, xChannelSelector, ChannelSelectorType)
- DECLARE_ANIMATED_ENUMERATION(YChannelSelector, yChannelSelector, ChannelSelectorType)
- DECLARE_ANIMATED_NUMBER(Scale, scale)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
+
+ RefPtr<SVGAnimatedNumber> m_scale;
+ RefPtr<SVGAnimatedString> m_in1;
+ RefPtr<SVGAnimatedString> m_in2;
+ RefPtr<SVGAnimatedEnumeration<ChannelSelectorType> > m_xChannelSelector;
+ RefPtr<SVGAnimatedEnumeration<ChannelSelectorType> > m_yChannelSelector;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.idl
index 74ad074b367..25d13cc4c21 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDisplacementMapElement.idl
@@ -23,19 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEDisplacementMapElement
+
[
- DoNotCheckConstants
+ DoNotCheckConstants,
] interface SVGFEDisplacementMapElement : SVGElement {
// Channel Selectors
const unsigned short SVG_CHANNEL_UNKNOWN = 0;
- const unsigned short SVG_CHANNEL_R = 1;
- const unsigned short SVG_CHANNEL_G = 2;
- const unsigned short SVG_CHANNEL_B = 3;
- const unsigned short SVG_CHANNEL_A = 4;
+ const unsigned short SVG_CHANNEL_R = 1;
+ const unsigned short SVG_CHANNEL_G = 2;
+ const unsigned short SVG_CHANNEL_B = 3;
+ const unsigned short SVG_CHANNEL_A = 4;
- readonly attribute SVGAnimatedString in1;
- readonly attribute SVGAnimatedString in2;
- readonly attribute SVGAnimatedNumber scale;
+ readonly attribute SVGAnimatedString in1;
+ readonly attribute SVGAnimatedString in2;
+ readonly attribute SVGAnimatedNumber scale;
readonly attribute SVGAnimatedEnumeration xChannelSelector;
readonly attribute SVGAnimatedEnumeration yChannelSelector;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.cpp
index f641868e74d..5a8072a1574 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.cpp
@@ -20,7 +20,7 @@
#include "config.h"
#include "core/svg/SVGFEDistantLightElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/DistantLightSource.h"
namespace WebCore {
@@ -31,14 +31,11 @@ inline SVGFEDistantLightElement::SVGFEDistantLightElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFEDistantLightElement> SVGFEDistantLightElement::create(Document& document)
-{
- return adoptRef(new SVGFEDistantLightElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEDistantLightElement)
-PassRefPtr<LightSource> SVGFEDistantLightElement::lightSource() const
+PassRefPtr<LightSource> SVGFEDistantLightElement::lightSource(Filter* filter) const
{
- return DistantLightSource::create(azimuthCurrentValue(), elevationCurrentValue());
+ return DistantLightSource::create(azimuth()->currentValue()->value(), elevation()->currentValue()->value());
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.h
index 8a50cc8414d..7f278c147d2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDistantLightElement.h
@@ -26,12 +26,12 @@ namespace WebCore {
class SVGFEDistantLightElement FINAL : public SVGFELightElement {
public:
- static PassRefPtr<SVGFEDistantLightElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEDistantLightElement);
private:
explicit SVGFEDistantLightElement(Document&);
- virtual PassRefPtr<LightSource> lightSource() const;
+ virtual PassRefPtr<LightSource> lightSource(Filter*) const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp
index 366eaf3512c..58c7e00bbff 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.cpp
@@ -21,63 +21,35 @@
#include "core/svg/SVGFEDropShadowElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/SVGRenderStyle.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGParserUtilities.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEDropShadowElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_NUMBER(SVGFEDropShadowElement, SVGNames::dxAttr, Dx, dx)
-DEFINE_ANIMATED_NUMBER(SVGFEDropShadowElement, SVGNames::dyAttr, Dy, dy)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEDropShadowElement, SVGNames::stdDeviationAttr, stdDeviationXIdentifier(), StdDeviationX, stdDeviationX)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEDropShadowElement, SVGNames::stdDeviationAttr, stdDeviationYIdentifier(), StdDeviationY, stdDeviationY)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEDropShadowElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(dx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(dy)
- REGISTER_LOCAL_ANIMATED_PROPERTY(stdDeviationX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(stdDeviationY)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFEDropShadowElement::SVGFEDropShadowElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feDropShadowTag, document)
- , m_dx(2)
- , m_dy(2)
- , m_stdDeviationX(2)
- , m_stdDeviationY(2)
+ , m_dx(SVGAnimatedNumber::create(this, SVGNames::dxAttr, SVGNumber::create(2)))
+ , m_dy(SVGAnimatedNumber::create(this, SVGNames::dyAttr, SVGNumber::create(2)))
+ , m_stdDeviation(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::stdDeviationAttr, 2, 2))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEDropShadowElement();
-}
-
-PassRefPtr<SVGFEDropShadowElement> SVGFEDropShadowElement::create(Document& document)
-{
- return adoptRef(new SVGFEDropShadowElement(document));
-}
-const AtomicString& SVGFEDropShadowElement::stdDeviationXIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationX", AtomicString::ConstructFromLiteral));
- return s_identifier;
+ addToPropertyMap(m_dx);
+ addToPropertyMap(m_dy);
+ addToPropertyMap(m_stdDeviation);
+ addToPropertyMap(m_in1);
}
-const AtomicString& SVGFEDropShadowElement::stdDeviationYIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationY", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+DEFINE_NODE_FACTORY(SVGFEDropShadowElement)
void SVGFEDropShadowElement::setStdDeviation(float x, float y)
{
- setStdDeviationXBaseValue(x);
- setStdDeviationYBaseValue(y);
+ stdDeviationX()->baseValue()->setValue(x);
+ stdDeviationY()->baseValue()->setValue(y);
invalidate();
}
@@ -100,31 +72,20 @@ void SVGFEDropShadowElement::parseAttribute(const QualifiedName& name, const Ato
return;
}
- if (name == SVGNames::stdDeviationAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y)) {
- setStdDeviationXBaseValue(x);
- setStdDeviationYBaseValue(y);
- }
- return;
- }
+ SVGParsingError parseError = NoError;
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
-
- if (name == SVGNames::dxAttr) {
- setDxBaseValue(value.toFloat());
- return;
- }
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::dxAttr)
+ m_dx->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::dyAttr)
+ m_dy->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::stdDeviationAttr)
+ m_stdDeviation->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- if (name == SVGNames::dyAttr) {
- setDyBaseValue(value.toFloat());
- return;
- }
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGFEDropShadowElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -134,7 +95,7 @@ void SVGFEDropShadowElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::inAttr
|| attrName == SVGNames::stdDeviationAttr
@@ -151,10 +112,10 @@ PassRefPtr<FilterEffect> SVGFEDropShadowElement::build(SVGFilterBuilder* filterB
{
RenderObject* renderer = this->renderer();
if (!renderer)
- return 0;
+ return nullptr;
- if (stdDeviationXCurrentValue() < 0 || stdDeviationYCurrentValue() < 0)
- return 0;
+ if (stdDeviationX()->currentValue()->value() < 0 || stdDeviationY()->currentValue()->value() < 0)
+ return nullptr;
ASSERT(renderer->style());
const SVGRenderStyle* svgStyle = renderer->style()->svgStyle();
@@ -162,11 +123,11 @@ PassRefPtr<FilterEffect> SVGFEDropShadowElement::build(SVGFilterBuilder* filterB
Color color = svgStyle->floodColor();
float opacity = svgStyle->floodOpacity();
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
- RefPtr<FilterEffect> effect = FEDropShadow::create(filter, stdDeviationXCurrentValue(), stdDeviationYCurrentValue(), dxCurrentValue(), dyCurrentValue(), color, opacity);
+ RefPtr<FilterEffect> effect = FEDropShadow::create(filter, stdDeviationX()->currentValue()->value(), stdDeviationY()->currentValue()->value(), m_dx->currentValue()->value(), m_dy->currentValue()->value(), color, opacity);
effect->inputEffects().append(input1);
return effect.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.h
index 2b48d763b7d..7227fed5781 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.h
@@ -21,6 +21,7 @@
#define SVGFEDropShadowElement_h
#include "core/svg/SVGAnimatedNumber.h"
+#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "platform/graphics/filters/FEDropShadow.h"
@@ -28,28 +29,31 @@ namespace WebCore {
class SVGFEDropShadowElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEDropShadowElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEDropShadowElement);
void setStdDeviation(float stdDeviationX, float stdDeviationY);
+ SVGAnimatedNumber* dx() { return m_dx.get(); }
+ SVGAnimatedNumber* dy() { return m_dy.get(); }
+ SVGAnimatedNumber* stdDeviationX() { return m_stdDeviation->firstNumber(); }
+ SVGAnimatedNumber* stdDeviationY() { return m_stdDeviation->secondNumber(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
+
private:
explicit SVGFEDropShadowElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
static const AtomicString& stdDeviationXIdentifier();
static const AtomicString& stdDeviationYIdentifier();
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEDropShadowElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_NUMBER(Dx, dx)
- DECLARE_ANIMATED_NUMBER(Dy, dy)
- DECLARE_ANIMATED_NUMBER(StdDeviationX, stdDeviationX)
- DECLARE_ANIMATED_NUMBER(StdDeviationY, stdDeviationY)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumber> m_dx;
+ RefPtr<SVGAnimatedNumber> m_dy;
+ RefPtr<SVGAnimatedNumberOptionalNumber> m_stdDeviation;
+ RefPtr<SVGAnimatedString> m_in1;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.idl
index 8e7f36f3296..556fdaa432e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEDropShadowElement.idl
@@ -17,6 +17,8 @@
* Boston, MA 02110-1301, USA.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEDropShadowElement
+
interface SVGFEDropShadowElement : SVGElement {
readonly attribute SVGAnimatedString in1;
readonly attribute SVGAnimatedNumber dx;
@@ -24,8 +26,7 @@ interface SVGFEDropShadowElement : SVGElement {
readonly attribute SVGAnimatedNumber stdDeviationX;
readonly attribute SVGAnimatedNumber stdDeviationY;
- void setStdDeviation([Default=Undefined] optional float stdDeviationX,
- [Default=Undefined] optional float stdDeviationY);
+ void setStdDeviation(float stdDeviationX, float stdDeviationY);
};
SVGFEDropShadowElement implements SVGFilterPrimitiveStandardAttributes;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.cpp
index baee77b7311..6b9558583f0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.cpp
@@ -22,7 +22,7 @@
#include "core/svg/SVGFEFloodElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/style/SVGRenderStyle.h"
@@ -34,11 +34,7 @@ inline SVGFEFloodElement::SVGFEFloodElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFEFloodElement> SVGFEFloodElement::create(Document& document)
-{
- return adoptRef(new SVGFEFloodElement(document));
-}
-
+DEFINE_NODE_FACTORY(SVGFEFloodElement)
bool SVGFEFloodElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
{
@@ -61,7 +57,7 @@ PassRefPtr<FilterEffect> SVGFEFloodElement::build(SVGFilterBuilder*, Filter* fil
{
RenderObject* renderer = this->renderer();
if (!renderer)
- return 0;
+ return nullptr;
ASSERT(renderer->style());
const SVGRenderStyle* svgStyle = renderer->style()->svgStyle();
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.h
index 4fa91b67834..1a8069a972e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.h
@@ -28,13 +28,13 @@ namespace WebCore {
class SVGFEFloodElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEFloodElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEFloodElement);
private:
explicit SVGFEFloodElement(Document&);
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.idl
index 5334c5069cc..e586c72e475 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFloodElement.idl
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEFloodElement
+
interface SVGFEFloodElement : SVGElement {
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.cpp
index 757a4edf389..06caf7f970e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.cpp
@@ -30,9 +30,6 @@ inline SVGFEFuncAElement::SVGFEFuncAElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFEFuncAElement> SVGFEFuncAElement::create(Document& document)
-{
- return adoptRef(new SVGFEFuncAElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEFuncAElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.h
index 01a473aad7a..da59dcc23f3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncAElement.h
@@ -21,21 +21,19 @@
#ifndef SVGFEFuncAElement_h
#define SVGFEFuncAElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGComponentTransferFunctionElement.h"
namespace WebCore {
class SVGFEFuncAElement FINAL : public SVGComponentTransferFunctionElement {
public:
- static PassRefPtr<SVGFEFuncAElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEFuncAElement);
private:
explicit SVGFEFuncAElement(Document&);
};
-DEFINE_NODE_TYPE_CASTS(SVGFEFuncAElement, hasTagName(SVGNames::feFuncATag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.cpp
index 08bc49c289c..68249451a62 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.cpp
@@ -30,9 +30,6 @@ inline SVGFEFuncBElement::SVGFEFuncBElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFEFuncBElement> SVGFEFuncBElement::create(Document& document)
-{
- return adoptRef(new SVGFEFuncBElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEFuncBElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.h
index 24560e3c4f5..69bb3818904 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncBElement.h
@@ -21,21 +21,19 @@
#ifndef SVGFEFuncBElement_h
#define SVGFEFuncBElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGComponentTransferFunctionElement.h"
namespace WebCore {
class SVGFEFuncBElement FINAL : public SVGComponentTransferFunctionElement {
public:
- static PassRefPtr<SVGFEFuncBElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEFuncBElement);
private:
explicit SVGFEFuncBElement(Document&);
};
-DEFINE_NODE_TYPE_CASTS(SVGFEFuncBElement, hasTagName(SVGNames::feFuncBTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.cpp
index 4e27390412b..43b2ee03051 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.cpp
@@ -30,9 +30,6 @@ inline SVGFEFuncGElement::SVGFEFuncGElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFEFuncGElement> SVGFEFuncGElement::create(Document& document)
-{
- return adoptRef(new SVGFEFuncGElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEFuncGElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.h
index 3d6ccb827d0..f00a2aad005 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncGElement.h
@@ -21,21 +21,19 @@
#ifndef SVGFEFuncGElement_h
#define SVGFEFuncGElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGComponentTransferFunctionElement.h"
namespace WebCore {
class SVGFEFuncGElement FINAL : public SVGComponentTransferFunctionElement {
public:
- static PassRefPtr<SVGFEFuncGElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEFuncGElement);
private:
explicit SVGFEFuncGElement(Document&);
};
-DEFINE_NODE_TYPE_CASTS(SVGFEFuncGElement, hasTagName(SVGNames::feFuncGTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.cpp
index 786d4f8327a..8c82dea0d8e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.cpp
@@ -30,9 +30,6 @@ inline SVGFEFuncRElement::SVGFEFuncRElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFEFuncRElement> SVGFEFuncRElement::create(Document& document)
-{
- return adoptRef(new SVGFEFuncRElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEFuncRElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.h
index 49bff723664..15fcd2b48d1 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEFuncRElement.h
@@ -21,21 +21,19 @@
#ifndef SVGFEFuncRElement_h
#define SVGFEFuncRElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGComponentTransferFunctionElement.h"
namespace WebCore {
class SVGFEFuncRElement FINAL : public SVGComponentTransferFunctionElement {
public:
- static PassRefPtr<SVGFEFuncRElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEFuncRElement);
private:
explicit SVGFEFuncRElement(Document&);
};
-DEFINE_NODE_TYPE_CASTS(SVGFEFuncRElement, hasTagName(SVGNames::feFuncRTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp
index 75cadffb04f..85647679482 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.cpp
@@ -22,54 +22,30 @@
#include "core/svg/SVGFEGaussianBlurElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGParserUtilities.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEGaussianBlurElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, stdDeviationXIdentifier(), StdDeviationX, stdDeviationX)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEGaussianBlurElement, SVGNames::stdDeviationAttr, stdDeviationYIdentifier(), StdDeviationY, stdDeviationY)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEGaussianBlurElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(stdDeviationX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(stdDeviationY)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFEGaussianBlurElement::SVGFEGaussianBlurElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feGaussianBlurTag, document)
+ , m_stdDeviation(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::stdDeviationAttr, 0, 0))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEGaussianBlurElement();
-}
-PassRefPtr<SVGFEGaussianBlurElement> SVGFEGaussianBlurElement::create(Document& document)
-{
- return adoptRef(new SVGFEGaussianBlurElement(document));
-}
-
-const AtomicString& SVGFEGaussianBlurElement::stdDeviationXIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationX", AtomicString::ConstructFromLiteral));
- return s_identifier;
+ addToPropertyMap(m_stdDeviation);
+ addToPropertyMap(m_in1);
}
-const AtomicString& SVGFEGaussianBlurElement::stdDeviationYIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGStdDeviationY", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+DEFINE_NODE_FACTORY(SVGFEGaussianBlurElement)
void SVGFEGaussianBlurElement::setStdDeviation(float x, float y)
{
- setStdDeviationXBaseValue(x);
- setStdDeviationYBaseValue(y);
+ stdDeviationX()->baseValue()->setValue(x);
+ stdDeviationY()->baseValue()->setValue(y);
invalidate();
}
@@ -90,21 +66,16 @@ void SVGFEGaussianBlurElement::parseAttribute(const QualifiedName& name, const A
return;
}
- if (name == SVGNames::stdDeviationAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y)) {
- setStdDeviationXBaseValue(x);
- setStdDeviationYBaseValue(y);
- }
- return;
- }
+ SVGParsingError parseError = NoError;
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::stdDeviationAttr)
+ m_stdDeviation->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGFEGaussianBlurElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -114,7 +85,7 @@ void SVGFEGaussianBlurElement::svgAttributeChanged(const QualifiedName& attrName
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::inAttr || attrName == SVGNames::stdDeviationAttr) {
invalidate();
@@ -126,15 +97,15 @@ void SVGFEGaussianBlurElement::svgAttributeChanged(const QualifiedName& attrName
PassRefPtr<FilterEffect> SVGFEGaussianBlurElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
- if (stdDeviationXCurrentValue() < 0 || stdDeviationYCurrentValue() < 0)
- return 0;
+ if (stdDeviationX()->currentValue()->value() < 0 || stdDeviationY()->currentValue()->value() < 0)
+ return nullptr;
- RefPtr<FilterEffect> effect = FEGaussianBlur::create(filter, stdDeviationXCurrentValue(), stdDeviationYCurrentValue());
+ RefPtr<FilterEffect> effect = FEGaussianBlur::create(filter, stdDeviationX()->currentValue()->value(), stdDeviationY()->currentValue()->value());
effect->inputEffects().append(input1);
return effect.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.h
index 16b456b1692..f298427d11a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.h
@@ -21,7 +21,7 @@
#ifndef SVGFEGaussianBlurElement_h
#define SVGFEGaussianBlurElement_h
-#include "core/svg/SVGAnimatedNumber.h"
+#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "platform/graphics/filters/FEGaussianBlur.h"
@@ -29,26 +29,24 @@ namespace WebCore {
class SVGFEGaussianBlurElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEGaussianBlurElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEGaussianBlurElement);
void setStdDeviation(float stdDeviationX, float stdDeviationY);
+ SVGAnimatedNumber* stdDeviationX() { return m_stdDeviation->firstNumber(); }
+ SVGAnimatedNumber* stdDeviationY() { return m_stdDeviation->secondNumber(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
+
private:
explicit SVGFEGaussianBlurElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
-
- static const AtomicString& stdDeviationXIdentifier();
- static const AtomicString& stdDeviationYIdentifier();
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEGaussianBlurElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_NUMBER(StdDeviationX, stdDeviationX)
- DECLARE_ANIMATED_NUMBER(StdDeviationY, stdDeviationY)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumberOptionalNumber> m_stdDeviation;
+ RefPtr<SVGAnimatedString> m_in1;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.idl
index 53a06f3f2dc..f3a32d6b26c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEGaussianBlurElement.idl
@@ -23,13 +23,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG11/filters.html#InterfaceSVGFEGaussianBlurElement
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEGaussianBlurElement
+// Currently SVG 1.1 (SVG 2 members not implemented)
+
interface SVGFEGaussianBlurElement : SVGElement {
readonly attribute SVGAnimatedString in1;
readonly attribute SVGAnimatedNumber stdDeviationX;
readonly attribute SVGAnimatedNumber stdDeviationY;
- void setStdDeviation([Default=Undefined] optional float stdDeviationX,
- [Default=Undefined] optional float stdDeviationY);
+ void setStdDeviation(float stdDeviationX, float stdDeviationY);
};
SVGFEGaussianBlurElement implements SVGFilterPrimitiveStandardAttributes;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
index b886a5097f1..e115a9bb281 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.cpp
@@ -23,44 +23,37 @@
#include "core/svg/SVGFEImageElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Document.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGPreserveAspectRatio.h"
#include "platform/graphics/Image.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGFEImageElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
-DEFINE_ANIMATED_STRING(SVGFEImageElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGFEImageElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEImageElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(preserveAspectRatio)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFEImageElement::SVGFEImageElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feImageTag, document)
+ , SVGURIReference(this)
+ , m_preserveAspectRatio(SVGAnimatedPreserveAspectRatio::create(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEImageElement();
+ addToPropertyMap(m_preserveAspectRatio);
}
-PassRefPtr<SVGFEImageElement> SVGFEImageElement::create(Document& document)
-{
- return adoptRef(new SVGFEImageElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEImageElement)
SVGFEImageElement::~SVGFEImageElement()
{
+#if ENABLE(OILPAN)
+ if (m_cachedImage) {
+ m_cachedImage->removeClient(this);
+ m_cachedImage = 0;
+ }
+#else
clearResourceReferences();
+#endif
}
bool SVGFEImageElement::currentFrameHasSingleSecurityOrigin() const
@@ -78,12 +71,12 @@ void SVGFEImageElement::clearResourceReferences()
m_cachedImage = 0;
}
- document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+ document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
}
void SVGFEImageElement::fetchImageResource()
{
- FetchRequest request(ResourceRequest(ownerDocument()->completeURL(hrefCurrentValue())), localName());
+ FetchRequest request(ResourceRequest(ownerDocument()->completeURL(hrefString())), localName());
m_cachedImage = document().fetcher()->fetchImage(request);
if (m_cachedImage)
@@ -96,19 +89,19 @@ void SVGFEImageElement::buildPendingResource()
if (!inDocument())
return;
- String id;
- Element* target = SVGURIReference::targetElementFromIRIString(hrefCurrentValue(), document(), &id);
+ AtomicString id;
+ Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), treeScope(), &id);
if (!target) {
if (id.isEmpty())
fetchImageResource();
else {
- document().accessSVGExtensions()->addPendingResource(id, this);
+ document().accessSVGExtensions().addPendingResource(id, this);
ASSERT(hasPendingResources());
}
} else if (target->isSVGElement()) {
// Register us with the target in the dependencies map. Any change of hrefElement
// that leads to relayout/repainting now informs us, so we can react to it.
- document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target));
+ document().accessSVGExtensions().addElementReferencingTarget(this, toSVGElement(target));
}
invalidate();
@@ -119,7 +112,6 @@ bool SVGFEImageElement::isSupportedAttribute(const QualifiedName& attrName)
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGURIReference::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::preserveAspectRatioAttr);
}
return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
@@ -132,19 +124,16 @@ void SVGFEImageElement::parseAttribute(const QualifiedName& name, const AtomicSt
return;
}
+ SVGParsingError parseError = NoError;
+
if (name == SVGNames::preserveAspectRatioAttr) {
- SVGPreserveAspectRatio preserveAspectRatio;
- preserveAspectRatio.parse(value);
- setPreserveAspectRatioBaseValue(preserveAspectRatio);
- return;
+ m_preserveAspectRatio->setBaseValueAsString(value, parseError);
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else {
+ ASSERT_NOT_REACHED();
}
- if (SVGURIReference::parseAttribute(name, value))
- return;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -154,7 +143,7 @@ void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::preserveAspectRatioAttr) {
invalidate();
@@ -166,9 +155,6 @@ void SVGFEImageElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
- return;
-
ASSERT_NOT_REACHED();
}
@@ -194,7 +180,7 @@ void SVGFEImageElement::notifyFinished(Resource*)
Element* parent = parentElement();
ASSERT(parent);
- if (!parent->hasTagName(SVGNames::filterTag) || !parent->renderer())
+ if (!isSVGFilterElement(*parent) || !parent->renderer())
return;
if (RenderObject* renderer = this->renderer())
@@ -204,15 +190,8 @@ void SVGFEImageElement::notifyFinished(Resource*)
PassRefPtr<FilterEffect> SVGFEImageElement::build(SVGFilterBuilder*, Filter* filter)
{
if (m_cachedImage)
- return FEImage::createWithImage(filter, m_cachedImage->imageForRenderer(renderer()), preserveAspectRatioCurrentValue());
- return FEImage::createWithIRIReference(filter, document(), hrefCurrentValue(), preserveAspectRatioCurrentValue());
-}
-
-void SVGFEImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- SVGFilterPrimitiveStandardAttributes::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(hrefCurrentValue()));
+ return FEImage::createWithImage(filter, m_cachedImage->imageForRenderer(renderer()), m_preserveAspectRatio->currentValue());
+ return FEImage::createWithIRIReference(filter, treeScope(), hrefString(), m_preserveAspectRatio->currentValue());
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
index 5e6bb048582..082e6170147 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.h
@@ -21,12 +21,11 @@
#ifndef SVGFEImageElement_h
#define SVGFEImageElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/fetch/ImageResource.h"
#include "core/fetch/ResourcePtr.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "core/svg/SVGURIReference.h"
#include "core/svg/graphics/filters/SVGFEImage.h"
@@ -36,44 +35,37 @@ namespace WebCore {
class SVGFEImageElement FINAL : public SVGFilterPrimitiveStandardAttributes,
public SVGURIReference,
- public SVGExternalResourcesRequired,
public ImageResourceClient {
public:
- static PassRefPtr<SVGFEImageElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEImageElement);
bool currentFrameHasSingleSecurityOrigin() const;
virtual ~SVGFEImageElement();
+ SVGAnimatedPreserveAspectRatio* preserveAspectRatio() { return m_preserveAspectRatio.get(); }
private:
explicit SVGFEImageElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual void notifyFinished(Resource*);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual void notifyFinished(Resource*) OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
void clearResourceReferences();
void fetchImageResource();
- virtual void buildPendingResource();
+ virtual void buildPendingResource() OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEImageElement)
- DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedPreserveAspectRatio> m_preserveAspectRatio;
ResourcePtr<ImageResource> m_cachedImage;
};
-DEFINE_NODE_TYPE_CASTS(SVGFEImageElement, hasTagName(SVGNames::feImageTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.idl
index 40e41911451..9f2ca387de2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEImageElement.idl
@@ -23,11 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG11/filters.html#InterfaceSVGFEImageElement
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEImageElement
+// Currently SVG 1.1, SVG 2 members not implemented
+
interface SVGFEImageElement : SVGElement {
readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
};
-SVGFEImageElement implements SVGExternalResourcesRequired;
SVGFEImageElement implements SVGFilterPrimitiveStandardAttributes;
SVGFEImageElement implements SVGURIReference;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.cpp
index 4429044f7fb..e8aafb0c12a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.cpp
@@ -23,65 +23,42 @@
#include "core/svg/SVGFELightElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGFEDiffuseLightingElement.h"
#include "core/svg/SVGFESpecularLightingElement.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::azimuthAttr, Azimuth, azimuth)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::elevationAttr, Elevation, elevation)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::zAttr, Z, z)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtXAttr, PointsAtX, pointsAtX)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtYAttr, PointsAtY, pointsAtY)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::pointsAtZAttr, PointsAtZ, pointsAtZ)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::specularExponentAttr, SpecularExponent, specularExponent)
-DEFINE_ANIMATED_NUMBER(SVGFELightElement, SVGNames::limitingConeAngleAttr, LimitingConeAngle, limitingConeAngle)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFELightElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(azimuth)
- REGISTER_LOCAL_ANIMATED_PROPERTY(elevation)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(z)
- REGISTER_LOCAL_ANIMATED_PROPERTY(pointsAtX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(pointsAtY)
- REGISTER_LOCAL_ANIMATED_PROPERTY(pointsAtZ)
- REGISTER_LOCAL_ANIMATED_PROPERTY(specularExponent)
- REGISTER_LOCAL_ANIMATED_PROPERTY(limitingConeAngle)
-END_REGISTER_ANIMATED_PROPERTIES
-
SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document& document)
: SVGElement(tagName, document)
- , m_specularExponent(1)
+ , m_azimuth(SVGAnimatedNumber::create(this, SVGNames::azimuthAttr, SVGNumber::create()))
+ , m_elevation(SVGAnimatedNumber::create(this, SVGNames::elevationAttr, SVGNumber::create()))
+ , m_x(SVGAnimatedNumber::create(this, SVGNames::xAttr, SVGNumber::create()))
+ , m_y(SVGAnimatedNumber::create(this, SVGNames::yAttr, SVGNumber::create()))
+ , m_z(SVGAnimatedNumber::create(this, SVGNames::zAttr, SVGNumber::create()))
+ , m_pointsAtX(SVGAnimatedNumber::create(this, SVGNames::pointsAtXAttr, SVGNumber::create()))
+ , m_pointsAtY(SVGAnimatedNumber::create(this, SVGNames::pointsAtYAttr, SVGNumber::create()))
+ , m_pointsAtZ(SVGAnimatedNumber::create(this, SVGNames::pointsAtZAttr, SVGNumber::create()))
+ , m_specularExponent(SVGAnimatedNumber::create(this, SVGNames::specularExponentAttr, SVGNumber::create(1)))
+ , m_limitingConeAngle(SVGAnimatedNumber::create(this, SVGNames::limitingConeAngleAttr, SVGNumber::create()))
{
- registerAnimatedPropertiesForSVGFELightElement();
-}
-
-SVGFELightElement* SVGFELightElement::findLightElement(const SVGElement* svgElement)
-{
- for (Node* node = svgElement->firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(SVGNames::feDistantLightTag)
- || node->hasTagName(SVGNames::fePointLightTag)
- || node->hasTagName(SVGNames::feSpotLightTag)) {
- return static_cast<SVGFELightElement*>(node);
- }
- }
- return 0;
+ addToPropertyMap(m_azimuth);
+ addToPropertyMap(m_elevation);
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_z);
+ addToPropertyMap(m_pointsAtX);
+ addToPropertyMap(m_pointsAtY);
+ addToPropertyMap(m_pointsAtZ);
+ addToPropertyMap(m_specularExponent);
+ addToPropertyMap(m_limitingConeAngle);
}
-PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement)
+SVGFELightElement* SVGFELightElement::findLightElement(const SVGElement& svgElement)
{
- SVGFELightElement* lightNode = findLightElement(svgElement);
- if (!lightNode)
- return 0;
- return lightNode->lightSource();
+ return Traversal<SVGFELightElement>::firstChild(svgElement);
}
bool SVGFELightElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -109,57 +86,32 @@ void SVGFELightElement::parseAttribute(const QualifiedName& name, const AtomicSt
return;
}
- if (name == SVGNames::azimuthAttr) {
- setAzimuthBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::elevationAttr) {
- setElevationBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::xAttr) {
- setXBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::yAttr) {
- setYBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::zAttr) {
- setZBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::pointsAtXAttr) {
- setPointsAtXBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::pointsAtYAttr) {
- setPointsAtYBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::pointsAtZAttr) {
- setPointsAtZBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::specularExponentAttr) {
- setSpecularExponentBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::limitingConeAngleAttr) {
- setLimitingConeAngleBaseValue(value.toFloat());
- return;
- }
-
- ASSERT_NOT_REACHED();
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::azimuthAttr)
+ m_azimuth->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::elevationAttr)
+ m_elevation->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::xAttr)
+ m_x->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::yAttr)
+ m_y->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::zAttr)
+ m_z->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::pointsAtXAttr)
+ m_pointsAtX->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::pointsAtYAttr)
+ m_pointsAtY->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::pointsAtZAttr)
+ m_pointsAtZ->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::specularExponentAttr)
+ m_specularExponent->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::limitingConeAngleAttr)
+ m_limitingConeAngle->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -169,7 +121,7 @@ void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::azimuthAttr
|| attrName == SVGNames::elevationAttr
@@ -189,11 +141,12 @@ void SVGFELightElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer || !renderer->isSVGResourceFilterPrimitive())
return;
- if (parent->hasTagName(SVGNames::feDiffuseLightingTag)) {
- toSVGFEDiffuseLightingElement(parent)->lightElementAttributeChanged(this, attrName);
+ if (isSVGFEDiffuseLightingElement(*parent)) {
+ toSVGFEDiffuseLightingElement(*parent).lightElementAttributeChanged(this, attrName);
return;
- } else if (parent->hasTagName(SVGNames::feSpecularLightingTag)) {
- toSVGFESpecularLightingElement(parent)->lightElementAttributeChanged(this, attrName);
+ }
+ if (isSVGFESpecularLightingElement(*parent)) {
+ toSVGFESpecularLightingElement(*parent).lightElementAttributeChanged(this, attrName);
return;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.h
index 4473ed3e646..cee98e81bd0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFELightElement.h
@@ -22,43 +22,71 @@
#ifndef SVGFELightElement_h
#define SVGFELightElement_h
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedNumber.h"
#include "core/svg/SVGElement.h"
#include "platform/graphics/filters/LightSource.h"
namespace WebCore {
+class Filter;
+
class SVGFELightElement : public SVGElement {
public:
- virtual PassRefPtr<LightSource> lightSource() const = 0;
- static SVGFELightElement* findLightElement(const SVGElement*);
- static PassRefPtr<LightSource> findLightSource(const SVGElement*);
+ virtual PassRefPtr<LightSource> lightSource(Filter*) const = 0;
+ static SVGFELightElement* findLightElement(const SVGElement&);
+
+ SVGAnimatedNumber* azimuth() { return m_azimuth.get(); }
+ const SVGAnimatedNumber* azimuth() const { return m_azimuth.get(); }
+ SVGAnimatedNumber* elevation() { return m_elevation.get(); }
+ const SVGAnimatedNumber* elevation() const { return m_elevation.get(); }
+ SVGAnimatedNumber* x() { return m_x.get(); }
+ const SVGAnimatedNumber* x() const { return m_x.get(); }
+ SVGAnimatedNumber* y() { return m_y.get(); }
+ const SVGAnimatedNumber* y() const { return m_y.get(); }
+ SVGAnimatedNumber* z() { return m_z.get(); }
+ const SVGAnimatedNumber* z() const { return m_z.get(); }
+ SVGAnimatedNumber* pointsAtX() { return m_pointsAtX.get(); }
+ const SVGAnimatedNumber* pointsAtX() const { return m_pointsAtX.get(); }
+ SVGAnimatedNumber* pointsAtY() { return m_pointsAtY.get(); }
+ const SVGAnimatedNumber* pointsAtY() const { return m_pointsAtY.get(); }
+ SVGAnimatedNumber* pointsAtZ() { return m_pointsAtZ.get(); }
+ const SVGAnimatedNumber* pointsAtZ() const { return m_pointsAtZ.get(); }
+ SVGAnimatedNumber* specularExponent() { return m_specularExponent.get(); }
+ const SVGAnimatedNumber* specularExponent() const { return m_specularExponent.get(); }
+ SVGAnimatedNumber* limitingConeAngle() { return m_limitingConeAngle.get(); }
+ const SVGAnimatedNumber* limitingConeAngle() const { return m_limitingConeAngle.get(); }
protected:
SVGFELightElement(const QualifiedName&, Document&);
private:
bool isSupportedAttribute(const QualifiedName&);
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE FINAL;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE FINAL;
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE FINAL;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFELightElement)
- DECLARE_ANIMATED_NUMBER(Azimuth, azimuth)
- DECLARE_ANIMATED_NUMBER(Elevation, elevation)
- DECLARE_ANIMATED_NUMBER(X, x)
- DECLARE_ANIMATED_NUMBER(Y, y)
- DECLARE_ANIMATED_NUMBER(Z, z)
- DECLARE_ANIMATED_NUMBER(PointsAtX, pointsAtX)
- DECLARE_ANIMATED_NUMBER(PointsAtY, pointsAtY)
- DECLARE_ANIMATED_NUMBER(PointsAtZ, pointsAtZ)
- DECLARE_ANIMATED_NUMBER(SpecularExponent, specularExponent)
- DECLARE_ANIMATED_NUMBER(LimitingConeAngle, limitingConeAngle)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumber> m_azimuth;
+ RefPtr<SVGAnimatedNumber> m_elevation;
+ RefPtr<SVGAnimatedNumber> m_x;
+ RefPtr<SVGAnimatedNumber> m_y;
+ RefPtr<SVGAnimatedNumber> m_z;
+ RefPtr<SVGAnimatedNumber> m_pointsAtX;
+ RefPtr<SVGAnimatedNumber> m_pointsAtY;
+ RefPtr<SVGAnimatedNumber> m_pointsAtZ;
+ RefPtr<SVGAnimatedNumber> m_specularExponent;
+ RefPtr<SVGAnimatedNumber> m_limitingConeAngle;
};
+inline bool isSVGFELightElement(const Node& node)
+{
+ return node.hasTagName(SVGNames::feDistantLightTag) || node.hasTagName(SVGNames::fePointLightTag) || node.hasTagName(SVGNames::feSpotLightTag);
+}
+
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGFELightElement);
+
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp
index e1cf2db9b89..65835cfa64e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.cpp
@@ -22,7 +22,7 @@
#include "core/svg/SVGFEMergeElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
#include "core/svg/SVGFEMergeNodeElement.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
@@ -35,26 +35,21 @@ inline SVGFEMergeElement::SVGFEMergeElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFEMergeElement> SVGFEMergeElement::create(Document& document)
-{
- return adoptRef(new SVGFEMergeElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEMergeElement)
PassRefPtr<FilterEffect> SVGFEMergeElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
RefPtr<FilterEffect> effect = FEMerge::create(filter);
FilterEffectVector& mergeInputs = effect->inputEffects();
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (node->hasTagName(SVGNames::feMergeNodeTag)) {
- FilterEffect* mergeEffect = filterBuilder->getEffectById(toSVGFEMergeNodeElement(node)->in1CurrentValue());
- if (!mergeEffect)
- return 0;
- mergeInputs.append(mergeEffect);
- }
+ for (SVGFEMergeNodeElement* element = Traversal<SVGFEMergeNodeElement>::firstChild(*this); element; element = Traversal<SVGFEMergeNodeElement>::nextSibling(*element)) {
+ FilterEffect* mergeEffect = filterBuilder->getEffectById(AtomicString(element->in1()->currentValue()->value()));
+ if (!mergeEffect)
+ return nullptr;
+ mergeInputs.append(mergeEffect);
}
if (mergeInputs.isEmpty())
- return 0;
+ return nullptr;
return effect.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.h
index 9fae4a98d8f..8abe3b1b9ff 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.h
@@ -28,12 +28,12 @@ namespace WebCore {
class SVGFEMergeElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEMergeElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEMergeElement);
private:
explicit SVGFEMergeElement(Document&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.idl
index f4d8558b79b..d9da6e8eb07 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeElement.idl
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEMergeElement
+
interface SVGFEMergeElement : SVGElement {
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.cpp
index 30df5a14e5f..0807611c0f7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.cpp
@@ -22,29 +22,19 @@
#include "core/svg/SVGFEMergeNodeElement.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEMergeNodeElement, SVGNames::inAttr, In1, in1)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEMergeNodeElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFEMergeNodeElement::SVGFEMergeNodeElement(Document& document)
: SVGElement(SVGNames::feMergeNodeTag, document)
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEMergeNodeElement();
+ addToPropertyMap(m_in1);
}
-PassRefPtr<SVGFEMergeNodeElement> SVGFEMergeNodeElement::create(Document& document)
-{
- return adoptRef(new SVGFEMergeNodeElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEMergeNodeElement)
bool SVGFEMergeNodeElement::isSupportedAttribute(const QualifiedName& attrName)
{
@@ -61,12 +51,14 @@ void SVGFEMergeNodeElement::parseAttribute(const QualifiedName& name, const Atom
return;
}
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ SVGParsingError parseError = NoError;
- ASSERT_NOT_REACHED();
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
void SVGFEMergeNodeElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -76,7 +68,7 @@ void SVGFEMergeNodeElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::inAttr) {
invalidateFilterPrimitiveParent(this);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.h
index a0760887bc4..739939fc9df 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEMergeNodeElement.h
@@ -21,7 +21,7 @@
#ifndef SVGFEMergeNodeElement_h
#define SVGFEMergeNodeElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedString.h"
#include "core/svg/SVGElement.h"
@@ -29,24 +29,21 @@ namespace WebCore {
class SVGFEMergeNodeElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGFEMergeNodeElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEMergeNodeElement);
+ SVGAnimatedString* in1() { return m_in1.get(); }
private:
explicit SVGFEMergeNodeElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEMergeNodeElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedString> m_in1;
};
-DEFINE_NODE_TYPE_CASTS(SVGFEMergeNodeElement, hasTagName(SVGNames::feMergeNodeTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp
index 4f5385824e7..5a28b444c4e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.cpp
@@ -21,57 +21,42 @@
#include "core/svg/SVGFEMorphologyElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGParserUtilities.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEMorphologyElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_ENUMERATION(SVGFEMorphologyElement, SVGNames::operatorAttr, SVGOperator, svgOperator, MorphologyOperatorType)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, radiusXIdentifier(), RadiusX, radiusX)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFEMorphologyElement, SVGNames::radiusAttr, radiusYIdentifier(), RadiusY, radiusY)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEMorphologyElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(svgOperator)
- REGISTER_LOCAL_ANIMATED_PROPERTY(radiusX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(radiusY)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<MorphologyOperatorType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(FEMORPHOLOGY_OPERATOR_ERODE, "erode"));
+ entries.append(std::make_pair(FEMORPHOLOGY_OPERATOR_DILATE, "dilate"));
+ }
+ return entries;
+}
inline SVGFEMorphologyElement::SVGFEMorphologyElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feMorphologyTag, document)
- , m_svgOperator(FEMORPHOLOGY_OPERATOR_ERODE)
+ , m_radius(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::radiusAttr))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
+ , m_svgOperator(SVGAnimatedEnumeration<MorphologyOperatorType>::create(this, SVGNames::operatorAttr, FEMORPHOLOGY_OPERATOR_ERODE))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEMorphologyElement();
-}
-PassRefPtr<SVGFEMorphologyElement> SVGFEMorphologyElement::create(Document& document)
-{
- return adoptRef(new SVGFEMorphologyElement(document));
+ addToPropertyMap(m_radius);
+ addToPropertyMap(m_in1);
+ addToPropertyMap(m_svgOperator);
}
-const AtomicString& SVGFEMorphologyElement::radiusXIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGRadiusX", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
-
-const AtomicString& SVGFEMorphologyElement::radiusYIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGRadiusY", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+DEFINE_NODE_FACTORY(SVGFEMorphologyElement)
void SVGFEMorphologyElement::setRadius(float x, float y)
{
- setRadiusXBaseValue(x);
- setRadiusYBaseValue(y);
+ radiusX()->baseValue()->setValue(x);
+ radiusY()->baseValue()->setValue(y);
invalidate();
}
@@ -93,39 +78,29 @@ void SVGFEMorphologyElement::parseAttribute(const QualifiedName& name, const Ato
return;
}
- if (name == SVGNames::operatorAttr) {
- MorphologyOperatorType propertyValue = SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
- if (propertyValue > 0)
- setSVGOperatorBaseValue(propertyValue);
- return;
- }
+ SVGParsingError parseError = NoError;
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::radiusAttr)
+ m_radius->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::operatorAttr)
+ m_svgOperator->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- if (name == SVGNames::radiusAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y)) {
- setRadiusXBaseValue(x);
- setRadiusYBaseValue(y);
- }
- return;
- }
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFEMorphologyElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
{
FEMorphology* morphology = static_cast<FEMorphology*>(effect);
if (attrName == SVGNames::operatorAttr)
- return morphology->setMorphologyOperator(svgOperatorCurrentValue());
+ return morphology->setMorphologyOperator(m_svgOperator->currentValue()->enumValue());
if (attrName == SVGNames::radiusAttr) {
// Both setRadius functions should be evaluated separately.
- bool isRadiusXChanged = morphology->setRadiusX(radiusXCurrentValue());
- bool isRadiusYChanged = morphology->setRadiusY(radiusYCurrentValue());
+ bool isRadiusXChanged = morphology->setRadiusX(radiusX()->currentValue()->value());
+ bool isRadiusYChanged = morphology->setRadiusY(radiusY()->currentValue()->value());
return isRadiusXChanged || isRadiusYChanged;
}
@@ -140,7 +115,7 @@ void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::operatorAttr || attrName == SVGNames::radiusAttr) {
primitiveAttributeChanged(attrName);
@@ -157,17 +132,17 @@ void SVGFEMorphologyElement::svgAttributeChanged(const QualifiedName& attrName)
PassRefPtr<FilterEffect> SVGFEMorphologyElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
- float xRadius = radiusXCurrentValue();
- float yRadius = radiusYCurrentValue();
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
+ float xRadius = radiusX()->currentValue()->value();
+ float yRadius = radiusY()->currentValue()->value();
if (!input1)
- return 0;
+ return nullptr;
if (xRadius < 0 || yRadius < 0)
- return 0;
+ return nullptr;
- RefPtr<FilterEffect> effect = FEMorphology::create(filter, svgOperatorCurrentValue(), xRadius, yRadius);
+ RefPtr<FilterEffect> effect = FEMorphology::create(filter, m_svgOperator->currentValue()->enumValue(), xRadius, yRadius);
effect->inputEffects().append(input1);
return effect.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.h
index 5462712fdd7..4d356c9be81 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.h
@@ -21,65 +21,37 @@
#define SVGFEMorphologyElement_h
#include "core/svg/SVGAnimatedEnumeration.h"
-#include "core/svg/SVGAnimatedNumber.h"
+#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "platform/graphics/filters/FEMorphology.h"
namespace WebCore {
-template<>
-struct SVGPropertyTraits<MorphologyOperatorType> {
- static unsigned highestEnumValue() { return FEMORPHOLOGY_OPERATOR_DILATE; }
-
- static String toString(MorphologyOperatorType type)
- {
- switch (type) {
- case FEMORPHOLOGY_OPERATOR_UNKNOWN:
- return emptyString();
- case FEMORPHOLOGY_OPERATOR_ERODE:
- return "erode";
- case FEMORPHOLOGY_OPERATOR_DILATE:
- return "dilate";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static MorphologyOperatorType fromString(const String& value)
- {
- if (value == "erode")
- return FEMORPHOLOGY_OPERATOR_ERODE;
- if (value == "dilate")
- return FEMORPHOLOGY_OPERATOR_DILATE;
- return FEMORPHOLOGY_OPERATOR_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<MorphologyOperatorType>();
class SVGFEMorphologyElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEMorphologyElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEMorphologyElement);
void setRadius(float radiusX, float radiusY);
+ SVGAnimatedNumber* radiusX() { return m_radius->firstNumber(); }
+ SVGAnimatedNumber* radiusY() { return m_radius->secondNumber(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
+ SVGAnimatedEnumeration<MorphologyOperatorType>* svgOperator() { return m_svgOperator.get(); }
+
private:
explicit SVGFEMorphologyElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
-
- static const AtomicString& radiusXIdentifier();
- static const AtomicString& radiusYIdentifier();
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEMorphologyElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_ENUMERATION(SVGOperator, svgOperator, MorphologyOperatorType)
- DECLARE_ANIMATED_NUMBER(RadiusX, radiusX)
- DECLARE_ANIMATED_NUMBER(RadiusY, radiusY)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumberOptionalNumber> m_radius;
+ RefPtr<SVGAnimatedString> m_in1;
+ RefPtr<SVGAnimatedEnumeration<MorphologyOperatorType> > m_svgOperator;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.idl
index 550c368550c..831d1264628 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEMorphologyElement.idl
@@ -23,21 +23,23 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEMorphologyElement
+
[
- DoNotCheckConstants
+ DoNotCheckConstants,
] interface SVGFEMorphologyElement : SVGElement {
// Morphology Operators
- const unsigned short SVG_MORPHOLOGY_OPERATOR_UNKNOWN = 0;
- const unsigned short SVG_MORPHOLOGY_OPERATOR_ERODE = 1;
- const unsigned short SVG_MORPHOLOGY_OPERATOR_DILATE = 2;
+ const unsigned short SVG_MORPHOLOGY_OPERATOR_UNKNOWN = 0;
+ const unsigned short SVG_MORPHOLOGY_OPERATOR_ERODE = 1;
+ const unsigned short SVG_MORPHOLOGY_OPERATOR_DILATE = 2;
- readonly attribute SVGAnimatedString in1;
+ readonly attribute SVGAnimatedString in1;
[ImplementedAs=svgOperator] readonly attribute SVGAnimatedEnumeration operator;
- readonly attribute SVGAnimatedNumber radiusX;
- readonly attribute SVGAnimatedNumber radiusY;
+ readonly attribute SVGAnimatedNumber radiusX;
+ readonly attribute SVGAnimatedNumber radiusY;
- void setRadius([Default=Undefined] optional float radiusX,
- [Default=Undefined] optional float radiusY);
+ [MeasureAs=SVGFEMorphologyElementSetRadius] void setRadius([Default=Undefined] optional float radiusX,
+ [Default=Undefined] optional float radiusY); // non-standard
};
SVGFEMorphologyElement implements SVGFilterPrimitiveStandardAttributes;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp
index 7b29b59b8a4..ceccc37a1b9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.cpp
@@ -22,37 +22,27 @@
#include "core/svg/SVGFEOffsetElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFEOffsetElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_NUMBER(SVGFEOffsetElement, SVGNames::dxAttr, Dx, dx)
-DEFINE_ANIMATED_NUMBER(SVGFEOffsetElement, SVGNames::dyAttr, Dy, dy)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEOffsetElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(dx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(dy)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFEOffsetElement::SVGFEOffsetElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feOffsetTag, document)
+ , m_dx(SVGAnimatedNumber::create(this, SVGNames::dxAttr, SVGNumber::create()))
+ , m_dy(SVGAnimatedNumber::create(this, SVGNames::dyAttr, SVGNumber::create()))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFEOffsetElement();
-}
-PassRefPtr<SVGFEOffsetElement> SVGFEOffsetElement::create(Document& document)
-{
- return adoptRef(new SVGFEOffsetElement(document));
+ addToPropertyMap(m_dx);
+ addToPropertyMap(m_dy);
+ addToPropertyMap(m_in1);
}
+DEFINE_NODE_FACTORY(SVGFEOffsetElement)
+
bool SVGFEOffsetElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
@@ -71,22 +61,18 @@ void SVGFEOffsetElement::parseAttribute(const QualifiedName& name, const AtomicS
return;
}
- if (name == SVGNames::dxAttr) {
- setDxBaseValue(value.toFloat());
- return;
- }
+ SVGParsingError parseError = NoError;
- if (name == SVGNames::dyAttr) {
- setDyBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::dxAttr)
+ m_dx->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::dyAttr)
+ m_dy->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGFEOffsetElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -96,7 +82,7 @@ void SVGFEOffsetElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::inAttr || attrName == SVGNames::dxAttr || attrName == SVGNames::dyAttr) {
invalidate();
@@ -108,12 +94,12 @@ void SVGFEOffsetElement::svgAttributeChanged(const QualifiedName& attrName)
PassRefPtr<FilterEffect> SVGFEOffsetElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
- RefPtr<FilterEffect> effect = FEOffset::create(filter, dxCurrentValue(), dyCurrentValue());
+ RefPtr<FilterEffect> effect = FEOffset::create(filter, m_dx->currentValue()->value(), m_dy->currentValue()->value());
effect->inputEffects().append(input1);
return effect.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.h
index 74278647990..d1a3808ca16 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.h
@@ -29,21 +29,22 @@ namespace WebCore {
class SVGFEOffsetElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFEOffsetElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEOffsetElement);
+ SVGAnimatedNumber* dx() { return m_dx.get(); }
+ SVGAnimatedNumber* dy() { return m_dy.get(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
private:
explicit SVGFEOffsetElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEOffsetElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_NUMBER(Dx, dx)
- DECLARE_ANIMATED_NUMBER(Dy, dy)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
+
+ RefPtr<SVGAnimatedNumber> m_dx;
+ RefPtr<SVGAnimatedNumber> m_dy;
+ RefPtr<SVGAnimatedString> m_in1;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.idl
index 1b6460af6ce..38eb9c4f313 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEOffsetElement.idl
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFEOffsetElement
+
interface SVGFEOffsetElement : SVGElement {
readonly attribute SVGAnimatedString in1;
readonly attribute SVGAnimatedNumber dx;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.cpp
index aba77a621b8..79c43e74d6f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.cpp
@@ -20,7 +20,8 @@
#include "config.h"
#include "core/svg/SVGFEPointLightElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
+#include "platform/graphics/filters/Filter.h"
#include "platform/graphics/filters/PointLightSource.h"
namespace WebCore {
@@ -31,14 +32,12 @@ inline SVGFEPointLightElement::SVGFEPointLightElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFEPointLightElement> SVGFEPointLightElement::create(Document& document)
-{
- return adoptRef(new SVGFEPointLightElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFEPointLightElement)
-PassRefPtr<LightSource> SVGFEPointLightElement::lightSource() const
+PassRefPtr<LightSource> SVGFEPointLightElement::lightSource(Filter* filter) const
{
- return PointLightSource::create(FloatPoint3D(xCurrentValue(), yCurrentValue(), zCurrentValue()));
+ FloatPoint3D location(x()->currentValue()->value(), y()->currentValue()->value(), z()->currentValue()->value());
+ return PointLightSource::create(filter->resolve3dPoint(location));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.h
index b32b9516fb9..09ca37d69d5 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFEPointLightElement.h
@@ -26,12 +26,12 @@ namespace WebCore {
class SVGFEPointLightElement FINAL : public SVGFELightElement {
public:
- static PassRefPtr<SVGFEPointLightElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFEPointLightElement);
private:
explicit SVGFEPointLightElement(Document&);
- virtual PassRefPtr<LightSource> lightSource() const;
+ virtual PassRefPtr<LightSource> lightSource(Filter*) const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
index eee19788f0e..2781bd5eadb 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.cpp
@@ -25,56 +25,29 @@
#include "platform/graphics/filters/FilterEffect.h"
#include "core/rendering/style/RenderStyle.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGParserUtilities.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFESpecularLightingElement, SVGNames::inAttr, In1, in1)
-DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::specularConstantAttr, SpecularConstant, specularConstant)
-DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::specularExponentAttr, SpecularExponent, specularExponent)
-DEFINE_ANIMATED_NUMBER(SVGFESpecularLightingElement, SVGNames::surfaceScaleAttr, SurfaceScale, surfaceScale)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthXIdentifier(), KernelUnitLengthX, kernelUnitLengthX)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFESpecularLightingElement, SVGNames::kernelUnitLengthAttr, kernelUnitLengthYIdentifier(), KernelUnitLengthY, kernelUnitLengthY)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFESpecularLightingElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(specularConstant)
- REGISTER_LOCAL_ANIMATED_PROPERTY(specularExponent)
- REGISTER_LOCAL_ANIMATED_PROPERTY(surfaceScale)
- REGISTER_LOCAL_ANIMATED_PROPERTY(kernelUnitLengthX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(kernelUnitLengthY)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFESpecularLightingElement::SVGFESpecularLightingElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feSpecularLightingTag, document)
- , m_specularConstant(1)
- , m_specularExponent(1)
- , m_surfaceScale(1)
+ , m_specularConstant(SVGAnimatedNumber::create(this, SVGNames::specularConstantAttr, SVGNumber::create(1)))
+ , m_specularExponent(SVGAnimatedNumber::create(this, SVGNames::specularExponentAttr, SVGNumber::create(1)))
+ , m_surfaceScale(SVGAnimatedNumber::create(this, SVGNames::surfaceScaleAttr, SVGNumber::create(1)))
+ , m_kernelUnitLength(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::surfaceScaleAttr))
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFESpecularLightingElement();
-}
-
-PassRefPtr<SVGFESpecularLightingElement> SVGFESpecularLightingElement::create(Document& document)
-{
- return adoptRef(new SVGFESpecularLightingElement(document));
-}
-const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthXIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthX", AtomicString::ConstructFromLiteral));
- return s_identifier;
+ addToPropertyMap(m_specularConstant);
+ addToPropertyMap(m_specularExponent);
+ addToPropertyMap(m_surfaceScale);
+ addToPropertyMap(m_kernelUnitLength);
+ addToPropertyMap(m_in1);
}
-const AtomicString& SVGFESpecularLightingElement::kernelUnitLengthYIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGKernelUnitLengthY", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+DEFINE_NODE_FACTORY(SVGFESpecularLightingElement)
bool SVGFESpecularLightingElement::isSupportedAttribute(const QualifiedName& attrName)
{
@@ -96,36 +69,22 @@ void SVGFESpecularLightingElement::parseAttribute(const QualifiedName& name, con
return;
}
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
-
- if (name == SVGNames::surfaceScaleAttr) {
- setSurfaceScaleBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::specularConstantAttr) {
- setSpecularConstantBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::specularExponentAttr) {
- setSpecularExponentBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::kernelUnitLengthAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y)) {
- setKernelUnitLengthXBaseValue(x);
- setKernelUnitLengthYBaseValue(y);
- }
- return;
- }
-
- ASSERT_NOT_REACHED();
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::surfaceScaleAttr)
+ m_surfaceScale->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::specularConstantAttr)
+ m_specularConstant->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::specularExponentAttr)
+ m_specularExponent->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::kernelUnitLengthAttr)
+ m_kernelUnitLength->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
@@ -139,37 +98,37 @@ bool SVGFESpecularLightingElement::setFilterEffectAttribute(FilterEffect* effect
return specularLighting->setLightingColor(renderer->style()->svgStyle()->lightingColor());
}
if (attrName == SVGNames::surfaceScaleAttr)
- return specularLighting->setSurfaceScale(surfaceScaleCurrentValue());
+ return specularLighting->setSurfaceScale(m_surfaceScale->currentValue()->value());
if (attrName == SVGNames::specularConstantAttr)
- return specularLighting->setSpecularConstant(specularConstantCurrentValue());
+ return specularLighting->setSpecularConstant(m_specularConstant->currentValue()->value());
if (attrName == SVGNames::specularExponentAttr)
- return specularLighting->setSpecularExponent(specularExponentCurrentValue());
+ return specularLighting->setSpecularExponent(m_specularExponent->currentValue()->value());
LightSource* lightSource = const_cast<LightSource*>(specularLighting->lightSource());
- const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
+ SVGFELightElement* lightElement = SVGFELightElement::findLightElement(*this);
ASSERT(lightSource);
ASSERT(lightElement);
if (attrName == SVGNames::azimuthAttr)
- return lightSource->setAzimuth(lightElement->azimuthCurrentValue());
+ return lightSource->setAzimuth(lightElement->azimuth()->currentValue()->value());
if (attrName == SVGNames::elevationAttr)
- return lightSource->setElevation(lightElement->elevationCurrentValue());
+ return lightSource->setElevation(lightElement->elevation()->currentValue()->value());
if (attrName == SVGNames::xAttr)
- return lightSource->setX(lightElement->xCurrentValue());
+ return lightSource->setX(lightElement->x()->currentValue()->value());
if (attrName == SVGNames::yAttr)
- return lightSource->setY(lightElement->yCurrentValue());
+ return lightSource->setY(lightElement->y()->currentValue()->value());
if (attrName == SVGNames::zAttr)
- return lightSource->setZ(lightElement->zCurrentValue());
+ return lightSource->setZ(lightElement->z()->currentValue()->value());
if (attrName == SVGNames::pointsAtXAttr)
- return lightSource->setPointsAtX(lightElement->pointsAtXCurrentValue());
+ return lightSource->setPointsAtX(lightElement->pointsAtX()->currentValue()->value());
if (attrName == SVGNames::pointsAtYAttr)
- return lightSource->setPointsAtY(lightElement->pointsAtYCurrentValue());
+ return lightSource->setPointsAtY(lightElement->pointsAtY()->currentValue()->value());
if (attrName == SVGNames::pointsAtZAttr)
- return lightSource->setPointsAtZ(lightElement->pointsAtZCurrentValue());
+ return lightSource->setPointsAtZ(lightElement->pointsAtZ()->currentValue()->value());
if (attrName == SVGNames::specularExponentAttr)
- return lightSource->setSpecularExponent(lightElement->specularExponentCurrentValue());
+ return lightSource->setSpecularExponent(lightElement->specularExponent()->currentValue()->value());
if (attrName == SVGNames::limitingConeAngleAttr)
- return lightSource->setLimitingConeAngle(lightElement->limitingConeAngleCurrentValue());
+ return lightSource->setLimitingConeAngle(lightElement->limitingConeAngle()->currentValue()->value());
ASSERT_NOT_REACHED();
return false;
@@ -182,7 +141,7 @@ void SVGFESpecularLightingElement::svgAttributeChanged(const QualifiedName& attr
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::surfaceScaleAttr
|| attrName == SVGNames::specularConstantAttr
@@ -202,7 +161,7 @@ void SVGFESpecularLightingElement::svgAttributeChanged(const QualifiedName& attr
void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
{
- if (SVGFELightElement::findLightElement(this) != lightElement)
+ if (SVGFELightElement::findLightElement(*this) != lightElement)
return;
// The light element has different attribute names so attrName can identify the requested attribute.
@@ -211,24 +170,25 @@ void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELight
PassRefPtr<FilterEffect> SVGFESpecularLightingElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
- RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this);
- if (!lightSource)
- return 0;
+ SVGFELightElement* lightNode = SVGFELightElement::findLightElement(*this);
+ if (!lightNode)
+ return nullptr;
RenderObject* renderer = this->renderer();
if (!renderer)
- return 0;
+ return nullptr;
ASSERT(renderer->style());
Color color = renderer->style()->svgStyle()->lightingColor();
- RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, surfaceScaleCurrentValue(), specularConstantCurrentValue(),
- specularExponentCurrentValue(), kernelUnitLengthXCurrentValue(), kernelUnitLengthYCurrentValue(), lightSource.release());
+ RefPtr<LightSource> lightSource = lightNode->lightSource(filter);
+ RefPtr<FilterEffect> effect = FESpecularLighting::create(filter, color, m_surfaceScale->currentValue()->value(), m_specularConstant->currentValue()->value(),
+ m_specularExponent->currentValue()->value(), kernelUnitLengthX()->currentValue()->value(), kernelUnitLengthY()->currentValue()->value(), lightSource.release());
effect->inputEffects().append(input1);
return effect.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.h
index f76b161286d..8d5d5a125a6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.h
@@ -22,8 +22,9 @@
#ifndef SVGFESpecularLightingElement_h
#define SVGFESpecularLightingElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedNumber.h"
+#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
#include "core/svg/SVGFELightElement.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "platform/graphics/filters/FESpecularLighting.h"
@@ -32,33 +33,34 @@ namespace WebCore {
class SVGFESpecularLightingElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFESpecularLightingElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFESpecularLightingElement);
void lightElementAttributeChanged(const SVGFELightElement*, const QualifiedName&);
+ SVGAnimatedNumber* specularConstant() { return m_specularConstant.get(); }
+ SVGAnimatedNumber* specularExponent() { return m_specularExponent.get(); }
+ SVGAnimatedNumber* surfaceScale() { return m_surfaceScale.get(); }
+ SVGAnimatedNumber* kernelUnitLengthX() { return m_kernelUnitLength->firstNumber(); }
+ SVGAnimatedNumber* kernelUnitLengthY() { return m_kernelUnitLength->secondNumber(); }
+ SVGAnimatedString* in1() { return m_in1.get(); }
private:
explicit SVGFESpecularLightingElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
static const AtomicString& kernelUnitLengthXIdentifier();
static const AtomicString& kernelUnitLengthYIdentifier();
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFESpecularLightingElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- DECLARE_ANIMATED_NUMBER(SpecularConstant, specularConstant)
- DECLARE_ANIMATED_NUMBER(SpecularExponent, specularExponent)
- DECLARE_ANIMATED_NUMBER(SurfaceScale, surfaceScale)
- DECLARE_ANIMATED_NUMBER(KernelUnitLengthX, kernelUnitLengthX)
- DECLARE_ANIMATED_NUMBER(KernelUnitLengthY, kernelUnitLengthY)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumber> m_specularConstant;
+ RefPtr<SVGAnimatedNumber> m_specularExponent;
+ RefPtr<SVGAnimatedNumber> m_surfaceScale;
+ RefPtr<SVGAnimatedNumberOptionalNumber> m_kernelUnitLength;
+ RefPtr<SVGAnimatedString> m_in1;
};
-DEFINE_NODE_TYPE_CASTS(SVGFESpecularLightingElement, hasTagName(SVGNames::feSpecularLightingTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.idl
index 00b609e5c4e..66d506e9dcf 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFESpecularLightingElement.idl
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFESpecularLightingElement
+
interface SVGFESpecularLightingElement : SVGElement {
readonly attribute SVGAnimatedString in1;
readonly attribute SVGAnimatedNumber surfaceScale;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.cpp
index 2eafdb32874..8d1d081fbae 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.cpp
@@ -20,7 +20,8 @@
#include "config.h"
#include "core/svg/SVGFESpotLightElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
+#include "platform/graphics/filters/Filter.h"
#include "platform/graphics/filters/SpotLightSource.h"
namespace WebCore {
@@ -31,17 +32,14 @@ inline SVGFESpotLightElement::SVGFESpotLightElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFESpotLightElement> SVGFESpotLightElement::create(Document& document)
-{
- return adoptRef(new SVGFESpotLightElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFESpotLightElement)
-PassRefPtr<LightSource> SVGFESpotLightElement::lightSource() const
+PassRefPtr<LightSource> SVGFESpotLightElement::lightSource(Filter* filter) const
{
- FloatPoint3D pos(xCurrentValue(), yCurrentValue(), zCurrentValue());
- FloatPoint3D direction(pointsAtXCurrentValue(), pointsAtYCurrentValue(), pointsAtZCurrentValue());
+ FloatPoint3D pos(x()->currentValue()->value(), y()->currentValue()->value(), z()->currentValue()->value());
+ FloatPoint3D direction(pointsAtX()->currentValue()->value(), pointsAtY()->currentValue()->value(), pointsAtZ()->currentValue()->value());
- return SpotLightSource::create(pos, direction, specularExponentCurrentValue(), limitingConeAngleCurrentValue());
+ return SpotLightSource::create(filter->resolve3dPoint(pos), filter->resolve3dPoint(direction), specularExponent()->currentValue()->value(), limitingConeAngle()->currentValue()->value());
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.h
index a36d7628408..f5eb4bb860c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFESpotLightElement.h
@@ -26,12 +26,12 @@ namespace WebCore {
class SVGFESpotLightElement FINAL : public SVGFELightElement {
public:
- static PassRefPtr<SVGFESpotLightElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFESpotLightElement);
private:
explicit SVGFESpotLightElement(Document&);
- virtual PassRefPtr<LightSource> lightSource() const;
+ virtual PassRefPtr<LightSource> lightSource(Filter*) const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp
index f9833e817ed..4e4c91239fa 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.cpp
@@ -22,32 +22,21 @@
#include "core/svg/SVGFETileElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/graphics/filters/SVGFilterBuilder.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGFETileElement, SVGNames::inAttr, In1, in1)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFETileElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(in1)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFETileElement::SVGFETileElement(Document& document)
: SVGFilterPrimitiveStandardAttributes(SVGNames::feTileTag, document)
+ , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFETileElement();
+ addToPropertyMap(m_in1);
}
-PassRefPtr<SVGFETileElement> SVGFETileElement::create(Document& document)
-{
- return adoptRef(new SVGFETileElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFETileElement)
bool SVGFETileElement::isSupportedAttribute(const QualifiedName& attrName)
{
@@ -64,12 +53,14 @@ void SVGFETileElement::parseAttribute(const QualifiedName& name, const AtomicStr
return;
}
- if (name == SVGNames::inAttr) {
- setIn1BaseValue(value);
- return;
- }
+ SVGParsingError parseError = NoError;
- ASSERT_NOT_REACHED();
+ if (name == SVGNames::inAttr)
+ m_in1->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
void SVGFETileElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -79,7 +70,7 @@ void SVGFETileElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::inAttr) {
invalidate();
@@ -91,10 +82,10 @@ void SVGFETileElement::svgAttributeChanged(const QualifiedName& attrName)
PassRefPtr<FilterEffect> SVGFETileElement::build(SVGFilterBuilder* filterBuilder, Filter* filter)
{
- FilterEffect* input1 = filterBuilder->getEffectById(in1CurrentValue());
+ FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
if (!input1)
- return 0;
+ return nullptr;
RefPtr<FilterEffect> effect = FETile::create(filter);
effect->inputEffects().append(input1);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.h
index 0e605cd726c..b1a07150a40 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.h
@@ -28,19 +28,18 @@ namespace WebCore {
class SVGFETileElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFETileElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFETileElement);
+ SVGAnimatedString* in1() { return m_in1.get(); }
private:
explicit SVGFETileElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFETileElement)
- DECLARE_ANIMATED_STRING(In1, in1)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedString> m_in1;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.idl
index c3843236017..4395de571fc 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFETileElement.idl
@@ -23,6 +23,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFETileElement
+
interface SVGFETileElement : SVGElement {
readonly attribute SVGAnimatedString in1;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp
index b020f0fe1e4..2e48668453e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.cpp
@@ -22,57 +22,50 @@
#include "core/svg/SVGFETurbulenceElement.h"
-#include "SVGNames.h"
-#include "core/svg/SVGElementInstance.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGParserUtilities.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, baseFrequencyXIdentifier(), BaseFrequencyX, baseFrequencyX)
-DEFINE_ANIMATED_NUMBER_MULTIPLE_WRAPPERS(SVGFETurbulenceElement, SVGNames::baseFrequencyAttr, baseFrequencyYIdentifier(), BaseFrequencyY, baseFrequencyY)
-DEFINE_ANIMATED_INTEGER(SVGFETurbulenceElement, SVGNames::numOctavesAttr, NumOctaves, numOctaves)
-DEFINE_ANIMATED_NUMBER(SVGFETurbulenceElement, SVGNames::seedAttr, Seed, seed)
-DEFINE_ANIMATED_ENUMERATION(SVGFETurbulenceElement, SVGNames::stitchTilesAttr, StitchTiles, stitchTiles, SVGStitchOptions)
-DEFINE_ANIMATED_ENUMERATION(SVGFETurbulenceElement, SVGNames::typeAttr, Type, type, TurbulenceType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFETurbulenceElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(baseFrequencyX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(baseFrequencyY)
- REGISTER_LOCAL_ANIMATED_PROPERTY(numOctaves)
- REGISTER_LOCAL_ANIMATED_PROPERTY(seed)
- REGISTER_LOCAL_ANIMATED_PROPERTY(stitchTiles)
- REGISTER_LOCAL_ANIMATED_PROPERTY(type)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
-inline SVGFETurbulenceElement::SVGFETurbulenceElement(Document& document)
- : SVGFilterPrimitiveStandardAttributes(SVGNames::feTurbulenceTag, document)
- , m_numOctaves(1)
- , m_stitchTiles(SVG_STITCHTYPE_NOSTITCH)
- , m_type(FETURBULENCE_TYPE_TURBULENCE)
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGStitchOptions>()
{
- ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFETurbulenceElement();
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(SVG_STITCHTYPE_STITCH, "stitch"));
+ entries.append(std::make_pair(SVG_STITCHTYPE_NOSTITCH, "noStitch"));
+ }
+ return entries;
}
-PassRefPtr<SVGFETurbulenceElement> SVGFETurbulenceElement::create(Document& document)
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<TurbulenceType>()
{
- return adoptRef(new SVGFETurbulenceElement(document));
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(FETURBULENCE_TYPE_FRACTALNOISE, "fractalNoise"));
+ entries.append(std::make_pair(FETURBULENCE_TYPE_TURBULENCE, "turbulence"));
+ }
+ return entries;
}
-const AtomicString& SVGFETurbulenceElement::baseFrequencyXIdentifier()
+inline SVGFETurbulenceElement::SVGFETurbulenceElement(Document& document)
+ : SVGFilterPrimitiveStandardAttributes(SVGNames::feTurbulenceTag, document)
+ , m_baseFrequency(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::baseFrequencyAttr))
+ , m_seed(SVGAnimatedNumber::create(this, SVGNames::seedAttr, SVGNumber::create(0)))
+ , m_stitchTiles(SVGAnimatedEnumeration<SVGStitchOptions>::create(this, SVGNames::stitchTilesAttr, SVG_STITCHTYPE_NOSTITCH))
+ , m_type(SVGAnimatedEnumeration<TurbulenceType>::create(this, SVGNames::typeAttr, FETURBULENCE_TYPE_TURBULENCE))
+ , m_numOctaves(SVGAnimatedInteger::create(this, SVGNames::numOctavesAttr, SVGInteger::create(1)))
{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGBaseFrequencyX", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+ ScriptWrappable::init(this);
-const AtomicString& SVGFETurbulenceElement::baseFrequencyYIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGBaseFrequencyY", AtomicString::ConstructFromLiteral));
- return s_identifier;
+ addToPropertyMap(m_baseFrequency);
+ addToPropertyMap(m_seed);
+ addToPropertyMap(m_stitchTiles);
+ addToPropertyMap(m_type);
+ addToPropertyMap(m_numOctaves);
}
+DEFINE_NODE_FACTORY(SVGFETurbulenceElement)
+
bool SVGFETurbulenceElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
@@ -93,58 +86,40 @@ void SVGFETurbulenceElement::parseAttribute(const QualifiedName& name, const Ato
return;
}
- if (name == SVGNames::typeAttr) {
- TurbulenceType propertyValue = SVGPropertyTraits<TurbulenceType>::fromString(value);
- if (propertyValue > 0)
- setTypeBaseValue(propertyValue);
- return;
- }
-
- if (name == SVGNames::stitchTilesAttr) {
- SVGStitchOptions propertyValue = SVGPropertyTraits<SVGStitchOptions>::fromString(value);
- if (propertyValue > 0)
- setStitchTilesBaseValue(propertyValue);
- return;
- }
-
- if (name == SVGNames::baseFrequencyAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y)) {
- setBaseFrequencyXBaseValue(x);
- setBaseFrequencyYBaseValue(y);
- }
- return;
- }
-
- if (name == SVGNames::seedAttr) {
- setSeedBaseValue(value.toFloat());
- return;
- }
-
- if (name == SVGNames::numOctavesAttr) {
- setNumOctavesBaseValue(value.string().toUIntStrict());
- return;
- }
-
- ASSERT_NOT_REACHED();
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::baseFrequencyAttr)
+ m_baseFrequency->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::numOctavesAttr)
+ m_numOctaves->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::seedAttr)
+ m_seed->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::stitchTilesAttr)
+ m_stitchTiles->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::typeAttr)
+ m_type->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
bool SVGFETurbulenceElement::setFilterEffectAttribute(FilterEffect* effect, const QualifiedName& attrName)
{
FETurbulence* turbulence = static_cast<FETurbulence*>(effect);
if (attrName == SVGNames::typeAttr)
- return turbulence->setType(typeCurrentValue());
+ return turbulence->setType(m_type->currentValue()->enumValue());
if (attrName == SVGNames::stitchTilesAttr)
- return turbulence->setStitchTiles(stitchTilesCurrentValue());
+ return turbulence->setStitchTiles(m_stitchTiles->currentValue()->enumValue());
if (attrName == SVGNames::baseFrequencyAttr) {
- bool baseFrequencyXChanged = turbulence->setBaseFrequencyX(baseFrequencyXCurrentValue());
- bool baseFrequencyYChanged = turbulence->setBaseFrequencyY(baseFrequencyYCurrentValue());
+ bool baseFrequencyXChanged = turbulence->setBaseFrequencyX(baseFrequencyX()->currentValue()->value());
+ bool baseFrequencyYChanged = turbulence->setBaseFrequencyY(baseFrequencyY()->currentValue()->value());
return (baseFrequencyXChanged || baseFrequencyYChanged);
}
if (attrName == SVGNames::seedAttr)
- return turbulence->setSeed(seedCurrentValue());
+ return turbulence->setSeed(m_seed->currentValue()->value());
if (attrName == SVGNames::numOctavesAttr)
- return turbulence->setNumOctaves(numOctavesCurrentValue());
+ return turbulence->setNumOctaves(m_numOctaves->currentValue()->value());
ASSERT_NOT_REACHED();
return false;
@@ -157,7 +132,7 @@ void SVGFETurbulenceElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::baseFrequencyAttr
|| attrName == SVGNames::numOctavesAttr
@@ -173,9 +148,9 @@ void SVGFETurbulenceElement::svgAttributeChanged(const QualifiedName& attrName)
PassRefPtr<FilterEffect> SVGFETurbulenceElement::build(SVGFilterBuilder*, Filter* filter)
{
- if (baseFrequencyXCurrentValue() < 0 || baseFrequencyYCurrentValue() < 0)
- return 0;
- return FETurbulence::create(filter, typeCurrentValue(), baseFrequencyXCurrentValue(), baseFrequencyYCurrentValue(), numOctavesCurrentValue(), seedCurrentValue(), stitchTilesCurrentValue() == SVG_STITCHTYPE_STITCH);
+ if (baseFrequencyX()->currentValue()->value() < 0 || baseFrequencyY()->currentValue()->value() < 0)
+ return nullptr;
+ return FETurbulence::create(filter, m_type->currentValue()->enumValue(), baseFrequencyX()->currentValue()->value(), baseFrequencyY()->currentValue()->value(), m_numOctaves->currentValue()->value(), m_seed->currentValue()->value(), m_stitchTiles->currentValue()->enumValue() == SVG_STITCHTYPE_STITCH);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.h
index b9ead22cab9..875a86c249c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.h
@@ -24,6 +24,7 @@
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedInteger.h"
#include "core/svg/SVGAnimatedNumber.h"
+#include "core/svg/SVGAnimatedNumberOptionalNumber.h"
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
#include "platform/graphics/filters/FETurbulence.h"
@@ -34,89 +35,35 @@ enum SVGStitchOptions {
SVG_STITCHTYPE_STITCH = 1,
SVG_STITCHTYPE_NOSTITCH = 2
};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGStitchOptions>();
-template<>
-struct SVGPropertyTraits<SVGStitchOptions> {
- static unsigned highestEnumValue() { return SVG_STITCHTYPE_NOSTITCH; }
-
- static String toString(SVGStitchOptions type)
- {
- switch (type) {
- case SVG_STITCHTYPE_UNKNOWN:
- return emptyString();
- case SVG_STITCHTYPE_STITCH:
- return "stitch";
- case SVG_STITCHTYPE_NOSTITCH:
- return "noStitch";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static SVGStitchOptions fromString(const String& value)
- {
- if (value == "stitch")
- return SVG_STITCHTYPE_STITCH;
- if (value == "noStitch")
- return SVG_STITCHTYPE_NOSTITCH;
- return SVG_STITCHTYPE_UNKNOWN;
- }
-};
-
-template<>
-struct SVGPropertyTraits<TurbulenceType> {
- static unsigned highestEnumValue() { return FETURBULENCE_TYPE_TURBULENCE; }
-
- static String toString(TurbulenceType type)
- {
- switch (type) {
- case FETURBULENCE_TYPE_UNKNOWN:
- return emptyString();
- case FETURBULENCE_TYPE_FRACTALNOISE:
- return "fractalNoise";
- case FETURBULENCE_TYPE_TURBULENCE:
- return "turbulence";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static TurbulenceType fromString(const String& value)
- {
- if (value == "fractalNoise")
- return FETURBULENCE_TYPE_FRACTALNOISE;
- if (value == "turbulence")
- return FETURBULENCE_TYPE_TURBULENCE;
- return FETURBULENCE_TYPE_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<TurbulenceType>();
class SVGFETurbulenceElement FINAL : public SVGFilterPrimitiveStandardAttributes {
public:
- static PassRefPtr<SVGFETurbulenceElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFETurbulenceElement);
+
+ SVGAnimatedNumber* baseFrequencyX() { return m_baseFrequency->firstNumber(); }
+ SVGAnimatedNumber* baseFrequencyY() { return m_baseFrequency->secondNumber(); }
+ SVGAnimatedNumber* seed() { return m_seed.get(); }
+ SVGAnimatedEnumeration<SVGStitchOptions>* stitchTiles() { return m_stitchTiles.get(); }
+ SVGAnimatedEnumeration<TurbulenceType>* type() { return m_type.get(); }
+ SVGAnimatedInteger* numOctaves() { return m_numOctaves.get(); }
private:
explicit SVGFETurbulenceElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName);
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*);
-
- static const AtomicString& baseFrequencyXIdentifier();
- static const AtomicString& baseFrequencyYIdentifier();
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFETurbulenceElement)
- DECLARE_ANIMATED_NUMBER(BaseFrequencyX, baseFrequencyX)
- DECLARE_ANIMATED_NUMBER(BaseFrequencyY, baseFrequencyY)
- DECLARE_ANIMATED_INTEGER(NumOctaves, numOctaves)
- DECLARE_ANIMATED_NUMBER(Seed, seed)
- DECLARE_ANIMATED_ENUMERATION(StitchTiles, stitchTiles, SVGStitchOptions)
- DECLARE_ANIMATED_ENUMERATION(Type, type, TurbulenceType)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName& attrName) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
+
+ RefPtr<SVGAnimatedNumberOptionalNumber> m_baseFrequency;
+ RefPtr<SVGAnimatedNumber> m_seed;
+ RefPtr<SVGAnimatedEnumeration<SVGStitchOptions> > m_stitchTiles;
+ RefPtr<SVGAnimatedEnumeration<TurbulenceType> > m_type;
+ RefPtr<SVGAnimatedInteger> m_numOctaves;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.idl
index b91473980b1..0fceef915ba 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFETurbulenceElement.idl
@@ -23,23 +23,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFETurbulenceElement
+
[
- DoNotCheckConstants
+ DoNotCheckConstants,
] interface SVGFETurbulenceElement : SVGElement {
// Turbulence Types
- const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN = 0;
+ const unsigned short SVG_TURBULENCE_TYPE_UNKNOWN = 0;
const unsigned short SVG_TURBULENCE_TYPE_FRACTALNOISE = 1;
- const unsigned short SVG_TURBULENCE_TYPE_TURBULENCE = 2;
+ const unsigned short SVG_TURBULENCE_TYPE_TURBULENCE = 2;
// Stitch Options
- const unsigned short SVG_STITCHTYPE_UNKNOWN = 0;
- const unsigned short SVG_STITCHTYPE_STITCH = 1;
+ const unsigned short SVG_STITCHTYPE_UNKNOWN = 0;
+ const unsigned short SVG_STITCHTYPE_STITCH = 1;
const unsigned short SVG_STITCHTYPE_NOSTITCH = 2;
- readonly attribute SVGAnimatedNumber baseFrequencyX;
- readonly attribute SVGAnimatedNumber baseFrequencyY;
- readonly attribute SVGAnimatedInteger numOctaves;
- readonly attribute SVGAnimatedNumber seed;
+ readonly attribute SVGAnimatedNumber baseFrequencyX;
+ readonly attribute SVGAnimatedNumber baseFrequencyY;
+ readonly attribute SVGAnimatedInteger numOctaves;
+ readonly attribute SVGAnimatedNumber seed;
readonly attribute SVGAnimatedEnumeration stitchTiles;
readonly attribute SVGAnimatedEnumeration type;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.cpp
index 332233635d1..b0f578d4a33 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.cpp
@@ -25,78 +25,56 @@
#include "core/svg/SVGFilterElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
#include "core/rendering/svg/RenderSVGResourceFilter.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGParserUtilities.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFilterElement, SVGNames::filterUnitsAttr, FilterUnits, filterUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_ENUMERATION(SVGFilterElement, SVGNames::primitiveUnitsAttr, PrimitiveUnits, primitiveUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_LENGTH(SVGFilterElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGFilterElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGFilterElement, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGFilterElement, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_INTEGER_MULTIPLE_WRAPPERS(SVGFilterElement, SVGNames::filterResAttr, filterResXIdentifier(), FilterResX, filterResX)
-DEFINE_ANIMATED_INTEGER_MULTIPLE_WRAPPERS(SVGFilterElement, SVGNames::filterResAttr, filterResYIdentifier(), FilterResY, filterResY)
-DEFINE_ANIMATED_STRING(SVGFilterElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGFilterElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFilterElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(filterUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(primitiveUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(filterResX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(filterResY)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFilterElement::SVGFilterElement(Document& document)
: SVGElement(SVGNames::filterTag, document)
- , m_filterUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
- , m_primitiveUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
- , m_x(LengthModeWidth, "-10%")
- , m_y(LengthModeHeight, "-10%")
- , m_width(LengthModeWidth, "120%")
- , m_height(LengthModeHeight, "120%")
+ , SVGURIReference(this)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
+ , m_filterUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::filterUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
+ , m_primitiveUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::primitiveUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
+ , m_filterRes(SVGAnimatedIntegerOptionalInteger::create(this, SVGNames::filterResAttr))
{
- // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified.
- // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified.
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFilterElement();
-}
-PassRefPtr<SVGFilterElement> SVGFilterElement::create(Document& document)
-{
- return adoptRef(new SVGFilterElement(document));
+ // Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified.
+ // Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified.
+ m_x->setDefaultValueAsString("-10%");
+ m_y->setDefaultValueAsString("-10%");
+ m_width->setDefaultValueAsString("120%");
+ m_height->setDefaultValueAsString("120%");
+
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
+ addToPropertyMap(m_filterUnits);
+ addToPropertyMap(m_primitiveUnits);
+ addToPropertyMap(m_filterRes);
}
-const AtomicString& SVGFilterElement::filterResXIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGFilterResX", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+DEFINE_NODE_FACTORY(SVGFilterElement)
-const AtomicString& SVGFilterElement::filterResYIdentifier()
+void SVGFilterElement::trace(Visitor* visitor)
{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGFilterResY", AtomicString::ConstructFromLiteral));
- return s_identifier;
+ visitor->trace(m_clientsToAdd);
+ SVGElement::trace(visitor);
}
-void SVGFilterElement::setFilterRes(unsigned filterResX, unsigned filterResY)
+void SVGFilterElement::setFilterRes(unsigned x, unsigned y)
{
- setFilterResXBaseValue(filterResX);
- setFilterResYBaseValue(filterResY);
+ filterResX()->baseValue()->setValue(x);
+ filterResY()->baseValue()->setValue(y);
- RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer());
- if (renderer)
- renderer->invalidateCacheAndMarkForLayout();
+ invalidateSVGAttributes();
+ svgAttributeChanged(SVGNames::filterResAttr);
}
bool SVGFilterElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -104,7 +82,6 @@ bool SVGFilterElement::isSupportedAttribute(const QualifiedName& attrName)
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGURIReference::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::filterUnitsAttr);
supportedAttributes.add(SVGNames::primitiveUnitsAttr);
supportedAttributes.add(SVGNames::xAttr);
@@ -122,30 +99,21 @@ void SVGFilterElement::parseAttribute(const QualifiedName& name, const AtomicStr
if (!isSupportedAttribute(name))
SVGElement::parseAttribute(name, value);
- else if (name == SVGNames::filterUnitsAttr) {
- SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
- if (propertyValue > 0)
- setFilterUnitsBaseValue(propertyValue);
- } else if (name == SVGNames::primitiveUnitsAttr) {
- SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
- if (propertyValue > 0)
- setPrimitiveUnitsBaseValue(propertyValue);
- } else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ else if (name == SVGNames::filterUnitsAttr)
+ m_filterUnits->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::primitiveUnitsAttr)
+ m_primitiveUnits->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::xAttr)
+ m_x->setBaseValueAsString(value, parseError);
else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_y->setBaseValueAsString(value, parseError);
else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_width->setBaseValueAsString(value, parseError);
else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (name == SVGNames::filterResAttr) {
- float x, y;
- if (parseNumberOptionalNumber(value, x, y)) {
- setFilterResXBaseValue(x);
- setFilterResYBaseValue(y);
- }
- } else if (SVGURIReference::parseAttribute(name, value)
- || SVGExternalResourcesRequired::parseAttribute(name, value)) {
+ m_height->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::filterResAttr)
+ m_filterRes->setBaseValueAsString(value, parseError);
+ else if (SVGURIReference::parseAttribute(name, value, parseError)) {
} else
ASSERT_NOT_REACHED();
@@ -159,7 +127,7 @@ void SVGFilterElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
@@ -180,66 +148,27 @@ void SVGFilterElement::childrenChanged(bool changedByParser, Node* beforeChange,
return;
if (RenderObject* object = renderer())
- object->setNeedsLayout();
+ object->setNeedsLayoutAndFullPaintInvalidation();
}
RenderObject* SVGFilterElement::createRenderer(RenderStyle*)
{
RenderSVGResourceFilter* renderer = new RenderSVGResourceFilter(this);
- HashSet<RefPtr<Node> >::iterator layerEnd = m_clientsToAdd.end();
- for (HashSet<RefPtr<Node> >::iterator it = m_clientsToAdd.begin(); it != layerEnd; ++it)
- renderer->addClientRenderLayer((*it).get());
+ WillBeHeapHashSet<RefPtrWillBeMember<Node> >::iterator layerEnd = m_clientsToAdd.end();
+ for (WillBeHeapHashSet<RefPtrWillBeMember<Node> >::iterator it = m_clientsToAdd.begin(); it != layerEnd; ++it)
+ renderer->addClientRenderLayer(it->get());
m_clientsToAdd.clear();
return renderer;
}
-bool SVGFilterElement::childShouldCreateRenderer(const Node& child) const
-{
- if (!child.isSVGElement())
- return false;
-
- const SVGElement* svgElement = toSVGElement(&child);
-
- DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, allowedChildElementTags, ());
- if (allowedChildElementTags.isEmpty()) {
- allowedChildElementTags.add(SVGNames::feBlendTag);
- allowedChildElementTags.add(SVGNames::feColorMatrixTag);
- allowedChildElementTags.add(SVGNames::feComponentTransferTag);
- allowedChildElementTags.add(SVGNames::feCompositeTag);
- allowedChildElementTags.add(SVGNames::feConvolveMatrixTag);
- allowedChildElementTags.add(SVGNames::feDiffuseLightingTag);
- allowedChildElementTags.add(SVGNames::feDisplacementMapTag);
- allowedChildElementTags.add(SVGNames::feDistantLightTag);
- allowedChildElementTags.add(SVGNames::feDropShadowTag);
- allowedChildElementTags.add(SVGNames::feFloodTag);
- allowedChildElementTags.add(SVGNames::feFuncATag);
- allowedChildElementTags.add(SVGNames::feFuncBTag);
- allowedChildElementTags.add(SVGNames::feFuncGTag);
- allowedChildElementTags.add(SVGNames::feFuncRTag);
- allowedChildElementTags.add(SVGNames::feGaussianBlurTag);
- allowedChildElementTags.add(SVGNames::feImageTag);
- allowedChildElementTags.add(SVGNames::feMergeTag);
- allowedChildElementTags.add(SVGNames::feMergeNodeTag);
- allowedChildElementTags.add(SVGNames::feMorphologyTag);
- allowedChildElementTags.add(SVGNames::feOffsetTag);
- allowedChildElementTags.add(SVGNames::fePointLightTag);
- allowedChildElementTags.add(SVGNames::feSpecularLightingTag);
- allowedChildElementTags.add(SVGNames::feSpotLightTag);
- allowedChildElementTags.add(SVGNames::feTileTag);
- allowedChildElementTags.add(SVGNames::feTurbulenceTag);
- }
-
- return allowedChildElementTags.contains<SVGAttributeHashTranslator>(svgElement->tagQName());
-}
-
bool SVGFilterElement::selfHasRelativeLengths() const
{
- return xCurrentValue().isRelative()
- || yCurrentValue().isRelative()
- || widthCurrentValue().isRelative()
- || heightCurrentValue().isRelative();
+ return m_x->currentValue()->isRelative()
+ || m_y->currentValue()->isRelative()
+ || m_width->currentValue()->isRelative()
+ || m_height->currentValue()->isRelative();
}
void SVGFilterElement::addClient(Node* client)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.h
index 791939a0f5b..08d128f6be0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.h
@@ -23,64 +23,62 @@
#ifndef SVGFilterElement_h
#define SVGFilterElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedInteger.h"
+#include "core/svg/SVGAnimatedIntegerOptionalInteger.h"
#include "core/svg/SVGAnimatedLength.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGURIReference.h"
#include "core/svg/SVGUnitTypes.h"
namespace WebCore {
class SVGFilterElement FINAL : public SVGElement,
- public SVGURIReference,
- public SVGExternalResourcesRequired {
+ public SVGURIReference {
public:
- static PassRefPtr<SVGFilterElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFilterElement);
+ virtual void trace(Visitor*) OVERRIDE;
- void setFilterRes(unsigned filterResX, unsigned filterResY);
+ void setFilterRes(unsigned x, unsigned y);
void addClient(Node*);
void removeClient(Node*);
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
+ SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* filterUnits() { return m_filterUnits.get(); }
+ SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* primitiveUnits() { return m_primitiveUnits.get(); }
+ SVGAnimatedInteger* filterResX() { return m_filterRes->firstInteger(); }
+ SVGAnimatedInteger* filterResY() { return m_filterRes->secondInteger(); }
+
private:
explicit SVGFilterElement(Document&);
- virtual bool needsPendingResourceHandling() const { return false; }
+ virtual bool needsPendingResourceHandling() const OVERRIDE { return false; }
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE;
-
- virtual bool selfHasRelativeLengths() const;
- static const AtomicString& filterResXIdentifier();
- static const AtomicString& filterResYIdentifier();
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFilterElement)
- DECLARE_ANIMATED_ENUMERATION(FilterUnits, filterUnits, SVGUnitTypes::SVGUnitType)
- DECLARE_ANIMATED_ENUMERATION(PrimitiveUnits, primitiveUnits, SVGUnitTypes::SVGUnitType)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_INTEGER(FilterResX, filterResX)
- DECLARE_ANIMATED_INTEGER(FilterResY, filterResY)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
+ RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_filterUnits;
+ RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_primitiveUnits;
+ RefPtr<SVGAnimatedIntegerOptionalInteger> m_filterRes;
- HashSet<RefPtr<Node> > m_clientsToAdd;
+ WillBeHeapHashSet<RefPtrWillBeMember<Node> > m_clientsToAdd;
};
-DEFINE_NODE_TYPE_CASTS(SVGFilterElement, hasTagName(SVGNames::filterTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.idl
index 7934751647c..5aa71f57800 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFilterElement.idl
@@ -24,7 +24,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGFilterElement : SVGElement {
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGFilterElement : SVGElement {
readonly attribute SVGAnimatedEnumeration filterUnits;
readonly attribute SVGAnimatedEnumeration primitiveUnits;
readonly attribute SVGAnimatedLength x;
@@ -34,10 +36,9 @@ interface SVGFilterElement : SVGElement {
readonly attribute SVGAnimatedInteger filterResX;
readonly attribute SVGAnimatedInteger filterResY;
- void setFilterRes([Default=Undefined] optional unsigned long filterResX,
- [Default=Undefined] optional unsigned long filterResY);
+ void setFilterRes(unsigned long filterResX,
+ unsigned long filterResY);
};
-SVGFilterElement implements SVGExternalResourcesRequired;
SVGFilterElement implements SVGURIReference;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp
index cb25ed470d9..626f13f5464 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp
@@ -23,40 +23,34 @@
#include "core/svg/SVGFilterPrimitiveStandardAttributes.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "platform/graphics/filters/FilterEffect.h"
#include "core/rendering/svg/RenderSVGResourceFilterPrimitive.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLength.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGFilterPrimitiveStandardAttributes, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_STRING(SVGFilterPrimitiveStandardAttributes, SVGNames::resultAttr, Result, result)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(result)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const QualifiedName& tagName, Document& document)
: SVGElement(tagName, document)
- , m_x(LengthModeWidth, "0%")
- , m_y(LengthModeHeight, "0%")
- , m_width(LengthModeWidth, "100%")
- , m_height(LengthModeHeight, "100%")
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
+ , m_result(SVGAnimatedString::create(this, SVGNames::resultAttr, SVGString::create()))
{
// Spec: If the x/y attribute is not specified, the effect is as if a value of "0%" were specified.
+ m_x->setDefaultValueAsString("0%");
+ m_y->setDefaultValueAsString("0%");
+
// Spec: If the width/height attribute is not specified, the effect is as if a value of "100%" were specified.
- registerAnimatedPropertiesForSVGFilterPrimitiveStandardAttributes();
+ m_width->setDefaultValueAsString("100%");
+ m_height->setDefaultValueAsString("100%");
+
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
+ addToPropertyMap(m_result);
}
bool SVGFilterPrimitiveStandardAttributes::isSupportedAttribute(const QualifiedName& attrName)
@@ -79,15 +73,15 @@ void SVGFilterPrimitiveStandardAttributes::parseAttribute(const QualifiedName& n
if (!isSupportedAttribute(name))
SVGElement::parseAttribute(name, value);
else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_x->setBaseValueAsString(value, parseError);
else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_y->setBaseValueAsString(value, parseError);
else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_width->setBaseValueAsString(value, parseError);
else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_height->setBaseValueAsString(value, parseError);
else if (name == SVGNames::resultAttr)
- setResultBaseValue(value);
+ m_result->setBaseValueAsString(value, parseError);
else
ASSERT_NOT_REACHED();
@@ -108,7 +102,7 @@ void SVGFilterPrimitiveStandardAttributes::svgAttributeChanged(const QualifiedNa
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
invalidate();
}
@@ -143,7 +137,7 @@ RenderObject* SVGFilterPrimitiveStandardAttributes::createRenderer(RenderStyle*)
bool SVGFilterPrimitiveStandardAttributes::rendererIsNeeded(const RenderStyle& style)
{
- if (parentNode() && (parentNode()->hasTagName(SVGNames::filterTag)))
+ if (isSVGFilterElement(parentNode()))
return SVGElement::rendererIsNeeded(style);
return false;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h b/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h
index bbdc8ff9267..1b71e7b04b3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h
@@ -32,7 +32,6 @@ namespace WebCore {
class Filter;
class FilterEffect;
-class RenderSVGResourceFilterPrimitive;
class SVGFilterBuilder;
class SVGFilterPrimitiveStandardAttributes : public SVGElement {
@@ -43,13 +42,20 @@ public:
// Returns true, if the new value is different from the old one.
virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
+ // JS API
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
+ SVGAnimatedString* result() const { return m_result.get(); }
+
protected:
SVGFilterPrimitiveStandardAttributes(const QualifiedName&, Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
inline void invalidate()
{
@@ -60,19 +66,16 @@ protected:
void primitiveAttributeChanged(const QualifiedName&);
private:
- virtual bool isFilterEffect() const { return true; }
-
- virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const OVERRIDE { return false; }
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_STRING(Result, result)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual bool isFilterEffect() const OVERRIDE FINAL { return true; }
+
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE FINAL;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE FINAL;
+
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
+ RefPtr<SVGAnimatedString> m_result;
};
void invalidateFilterPrimitiveParent(SVGElement*);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.idl
index 9f368eec83a..aba43fc3069 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFilterPrimitiveStandardAttributes.idl
@@ -24,9 +24,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/filter-effects/#InterfaceSVGFilterPrimitiveStandardAttributes
+
[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
+ NoInterfaceObject, // Always used on target of 'implements'
] interface SVGFilterPrimitiveStandardAttributes {
readonly attribute SVGAnimatedLength x;
readonly attribute SVGAnimatedLength y;
@@ -34,4 +35,3 @@
readonly attribute SVGAnimatedLength height;
readonly attribute SVGAnimatedString result;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.cpp
index 60425c87a88..e764ee8038f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007, 2010 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,6 +26,7 @@
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/svg/SVGDocumentExtensions.h"
+#include "core/svg/SVGElement.h"
#include "core/svg/SVGParserUtilities.h"
#include "platform/geometry/FloatRect.h"
#include "platform/transforms/AffineTransform.h"
@@ -32,77 +34,23 @@
namespace WebCore {
-template<typename CharType>
-static bool parseViewBoxInternal(Document* document, const CharType*& ptr, const CharType* end, FloatRect& viewBox, bool validate)
+SVGFitToViewBox::SVGFitToViewBox(SVGElement* element, PropertyMapPolicy propertyMapPolicy)
+ : m_viewBox(SVGAnimatedRect::create(element, SVGNames::viewBoxAttr))
+ , m_preserveAspectRatio(SVGAnimatedPreserveAspectRatio::create(element, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()))
{
- const CharType* start = ptr;
-
- skipOptionalSVGSpaces(ptr, end);
-
- float x = 0.0f;
- float y = 0.0f;
- float width = 0.0f;
- float height = 0.0f;
- bool valid = parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, false);
- if (!validate) {
- viewBox = FloatRect(x, y, width, height);
- return true;
- }
- if (!valid) {
- document->accessSVGExtensions()->reportWarning("Problem parsing viewBox=\"" + String(start, end - start) + "\"");
- return false;
- }
-
- if (width < 0.0) { // check that width is positive
- document->accessSVGExtensions()->reportError("A negative value for ViewBox width is not allowed");
- return false;
- }
- if (height < 0.0) { // check that height is positive
- document->accessSVGExtensions()->reportError("A negative value for ViewBox height is not allowed");
- return false;
- }
- skipOptionalSVGSpaces(ptr, end);
- if (ptr < end) { // nothing should come after the last, fourth number
- document->accessSVGExtensions()->reportWarning("Problem parsing viewBox=\"" + String(start, end - start) + "\"");
- return false;
- }
-
- viewBox = FloatRect(x, y, width, height);
- return true;
-}
-
-bool SVGFitToViewBox::parseViewBox(Document* document, const LChar*& ptr, const LChar* end, FloatRect& viewBox, bool validate)
-{
- return parseViewBoxInternal(document, ptr, end, viewBox, validate);
-}
-
-bool SVGFitToViewBox::parseViewBox(Document* document, const UChar*& ptr, const UChar* end, FloatRect& viewBox, bool validate)
-{
- return parseViewBoxInternal(document, ptr, end, viewBox, validate);
-}
-
-bool SVGFitToViewBox::parseViewBox(Document* document, const String& string, FloatRect& viewBox)
-{
- if (string.isEmpty()) {
- const LChar* ptr = 0;
- return parseViewBoxInternal<LChar>(document, ptr, ptr, viewBox, true);
- }
- if (string.is8Bit()) {
- const LChar* ptr = string.characters8();
- const LChar* end = ptr + string.length();
- return parseViewBox(document, ptr, end, viewBox, true);
+ ASSERT(element);
+ if (propertyMapPolicy == PropertyMapPolicyAdd) {
+ element->addToPropertyMap(m_viewBox);
+ element->addToPropertyMap(m_preserveAspectRatio);
}
- const UChar* ptr = string.characters16();
- const UChar* end = ptr + string.length();
- return parseViewBox(document, ptr, end, viewBox, true);
}
-AffineTransform SVGFitToViewBox::viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatio& preserveAspectRatio, float viewWidth, float viewHeight)
+AffineTransform SVGFitToViewBox::viewBoxToViewTransform(const FloatRect& viewBoxRect, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio, float viewWidth, float viewHeight)
{
if (!viewBoxRect.width() || !viewBoxRect.height())
return AffineTransform();
- return preserveAspectRatio.getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), viewWidth, viewHeight);
+ return preserveAspectRatio->getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), viewWidth, viewHeight);
}
bool SVGFitToViewBox::isKnownAttribute(const QualifiedName& attrName)
@@ -116,4 +64,10 @@ void SVGFitToViewBox::addSupportedAttributes(HashSet<QualifiedName>& supportedAt
supportedAttributes.add(SVGNames::preserveAspectRatioAttr);
}
+void SVGFitToViewBox::updateViewBox(const FloatRect& rect)
+{
+ ASSERT(m_viewBox);
+ m_viewBox->baseValue()->setValue(rect);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.h b/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.h
index ba8ca3cf8fa..94d5504ee68 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007, 2010 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,8 +22,13 @@
#ifndef SVGFitToViewBox_h
#define SVGFitToViewBox_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
+#include "core/dom/Document.h"
#include "core/dom/QualifiedName.h"
+#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
+#include "core/svg/SVGAnimatedRect.h"
+#include "core/svg/SVGDocumentExtensions.h"
+#include "core/svg/SVGParsingError.h"
#include "core/svg/SVGPreserveAspectRatio.h"
#include "core/svg/SVGRect.h"
#include "wtf/HashSet.h"
@@ -34,40 +40,52 @@ class Document;
class SVGFitToViewBox {
public:
- static AffineTransform viewBoxToViewTransform(const FloatRect& viewBoxRect, const SVGPreserveAspectRatio&, float viewWidth, float viewHeight);
+ enum PropertyMapPolicy {
+ PropertyMapPolicyAdd,
+ PropertyMapPolicySkip,
+ };
+
+ static AffineTransform viewBoxToViewTransform(const FloatRect& viewBoxRect, PassRefPtr<SVGPreserveAspectRatio>, float viewWidth, float viewHeight);
static bool isKnownAttribute(const QualifiedName&);
static void addSupportedAttributes(HashSet<QualifiedName>&);
- template<class SVGElementTarget>
- static bool parseAttribute(SVGElementTarget* target, const QualifiedName& name, const AtomicString& value)
+ bool parseAttribute(const QualifiedName& name, const AtomicString& value, Document& document, SVGParsingError& parseError)
{
- ASSERT(target);
if (name == SVGNames::viewBoxAttr) {
- FloatRect viewBox;
- bool valueIsValid = !value.isNull() && parseViewBox(&target->document(), value, viewBox);
- if (valueIsValid)
- target->setViewBoxBaseValue(viewBox);
- else
- target->setViewBoxBaseValue(SVGRect(SVGRect::InvalidSVGRectTag()));
+ m_viewBox->setBaseValueAsString(value, parseError);
+ if (m_viewBox->baseValue()->width() < 0.0f) {
+ document.accessSVGExtensions().reportError("A negative value for ViewBox width is not allowed");
+ m_viewBox->baseValue()->setInvalid();
+ }
+ if (m_viewBox->baseValue()->height() < 0.0f) {
+ document.accessSVGExtensions().reportError("A negative value for ViewBox height is not allowed");
+ m_viewBox->baseValue()->setInvalid();
+ }
return true;
}
-
if (name == SVGNames::preserveAspectRatioAttr) {
- SVGPreserveAspectRatio preserveAspectRatio;
- preserveAspectRatio.parse(value);
- target->setPreserveAspectRatioBaseValue(preserveAspectRatio);
+ m_preserveAspectRatio->setBaseValueAsString(value, parseError);
return true;
}
-
return false;
}
- static bool parseViewBox(Document*, const LChar*& start, const LChar* end, FloatRect& viewBox, bool validate = true);
- static bool parseViewBox(Document*, const UChar*& start, const UChar* end, FloatRect& viewBox, bool validate = true);
+ bool hasEmptyViewBox() const { return m_viewBox->currentValue()->isValid() && m_viewBox->currentValue()->value().isEmpty(); }
+
+ // JS API
+ SVGAnimatedRect* viewBox() const { return m_viewBox.get(); }
+ SVGAnimatedPreserveAspectRatio* preserveAspectRatio() const { return m_preserveAspectRatio.get(); }
+
+protected:
+ explicit SVGFitToViewBox(SVGElement*, PropertyMapPolicy = PropertyMapPolicyAdd);
+ void updateViewBox(const FloatRect&);
+ void clearViewBox() { m_viewBox = nullptr; }
+ void clearPreserveAspectRatio() { m_preserveAspectRatio = nullptr; }
private:
- static bool parseViewBox(Document*, const String&, FloatRect&);
+ RefPtr<SVGAnimatedRect> m_viewBox;
+ RefPtr<SVGAnimatedPreserveAspectRatio> m_preserveAspectRatio;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.idl b/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.idl
index 4e115fe155a..f61e5eabbc3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFitToViewBox.idl
@@ -24,11 +24,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG2/types.html#InterfaceSVGFitToViewBox
+
[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
+ NoInterfaceObject, // Always used on target of 'implements'
] interface SVGFitToViewBox {
- readonly attribute SVGAnimatedRect viewBox;
+ readonly attribute SVGAnimatedRect viewBox;
readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontData.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFontData.cpp
index 64b6b3de5ca..c4cffb9c07a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontData.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontData.cpp
@@ -22,14 +22,15 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGFontData.h"
-#include "SVGNames.h"
-#include "XMLNames.h"
+#include "core/SVGNames.h"
+#include "core/XMLNames.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/svg/SVGTextRunRenderingContext.h"
#include "core/svg/SVGAltGlyphElement.h"
#include "core/svg/SVGFontElement.h"
#include "core/svg/SVGFontFaceElement.h"
#include "core/svg/SVGGlyphElement.h"
+#include "platform/fonts/Character.h"
#include "platform/fonts/SVGGlyph.h"
#include "platform/fonts/SimpleFontData.h"
#include "platform/fonts/WidthIterator.h"
@@ -44,8 +45,8 @@ using namespace Unicode;
namespace WebCore {
SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement)
- : CustomFontData(false)
- , m_svgFontFaceElement(fontFaceElement)
+ : CustomFontData()
+ , m_svgFontFaceElement(fontFaceElement->createWeakRef())
, m_horizontalOriginX(fontFaceElement->horizontalOriginX())
, m_horizontalOriginY(fontFaceElement->horizontalOriginY())
, m_horizontalAdvanceX(fontFaceElement->horizontalAdvanceX())
@@ -56,12 +57,15 @@ SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement)
ASSERT_ARG(fontFaceElement, fontFaceElement);
}
+SVGFontData::~SVGFontData()
+{
+}
+
void SVGFontData::initializeFontData(SimpleFontData* fontData, float fontSize)
{
ASSERT(fontData);
SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
- ASSERT(svgFontFaceElement);
SVGFontElement* svgFontElement = svgFontFaceElement->associatedFontElement();
ASSERT(svgFontElement);
@@ -120,8 +124,20 @@ void SVGFontData::initializeFontData(SimpleFontData* fontData, float fontSize)
float SVGFontData::widthForSVGGlyph(Glyph glyph, float fontSize) const
{
+ // FIXME: (http://crbug.com/359380) Width calculation may be triggered after removeNode from the current editing impl.
+ // The retrieved width is not being used, so here we return a dummy value.
+ if (shouldSkipDrawing())
+ return 0.0;
+
SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
- ASSERT(svgFontFaceElement);
+
+ // RenderView::clearSelection is invoked while removing some element, e.g.
+ // Document::nodeWillBeRemoved => FrameSelection::nodeWillBeRemoved => RenderView::clearSelection.
+ // Since recalc style has not been executed yet, RenderStyle might have some reference to
+ // SVGFontFaceElement which was also removed.
+ // In this case, use default horizontalAdvanceX instead of associatedFontElement's one.
+ if (!svgFontFaceElement->inDocument())
+ return m_horizontalAdvanceX * scaleEmToUnits(fontSize, svgFontFaceElement->unitsPerEm());
SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
ASSERT(associatedFontElement);
@@ -142,10 +158,10 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
if (run.is8Bit()) {
remainingTextInRun = String(run.data8(currentCharacter), run.charactersLength() - currentCharacter);
- remainingTextInRun = Font::normalizeSpaces(remainingTextInRun.characters8(), remainingTextInRun.length());
+ remainingTextInRun = Character::normalizeSpaces(remainingTextInRun.characters8(), remainingTextInRun.length());
} else {
remainingTextInRun = String(run.data16(currentCharacter), run.charactersLength() - currentCharacter);
- remainingTextInRun = Font::normalizeSpaces(remainingTextInRun.characters16(), remainingTextInRun.length());
+ remainingTextInRun = Character::normalizeSpaces(remainingTextInRun.characters16(), remainingTextInRun.length());
}
if (mirror)
@@ -154,8 +170,6 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
arabicForms = charactersWithArabicForm(remainingTextInRun, mirror);
SVGFontFaceElement* svgFontFaceElement = this->svgFontFaceElement();
- ASSERT(svgFontFaceElement);
-
SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement();
ASSERT(associatedFontElement);
@@ -165,7 +179,7 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
String language;
bool isVerticalText = false;
- Vector<String> altGlyphNames;
+ Vector<AtomicString> altGlyphNames;
if (renderObject) {
RenderObject* parentRenderObject = renderObject->isText() ? renderObject->parent() : renderObject;
@@ -175,9 +189,8 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
language = parentRenderObjectElement->getAttribute(XMLNames::langAttr);
- if (parentRenderObjectElement->hasTagName(SVGNames::altGlyphTag)) {
- SVGAltGlyphElement* altGlyph = static_cast<SVGAltGlyphElement*>(parentRenderObjectElement);
- if (!altGlyph->hasValidGlyphElements(altGlyphNames))
+ if (isSVGAltGlyphElement(*parentRenderObjectElement)) {
+ if (!toSVGAltGlyphElement(*parentRenderObjectElement).hasValidGlyphElements(altGlyphNames))
altGlyphNames.clear();
}
}
@@ -187,7 +200,7 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
size_t altGlyphNamesSize = altGlyphNames.size();
if (altGlyphNamesSize) {
for (size_t index = 0; index < altGlyphNamesSize; ++index)
- associatedFontElement->collectGlyphsForGlyphName(altGlyphNames[index], glyphs);
+ associatedFontElement->collectGlyphsForAltGlyphReference(altGlyphNames[index], glyphs);
// Assign the unicodeStringLength now that its known.
size_t glyphsSize = glyphs.size();
@@ -198,7 +211,6 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
// Later code will fail if we do not do this and the glyph is incompatible.
if (glyphsSize) {
SVGGlyph& svgGlyph = glyphs[0];
- iterator.setLastGlyphName(svgGlyph.glyphName);
glyphData.glyph = svgGlyph.tableEntry;
advanceLength = svgGlyph.unicodeStringLength;
return true;
@@ -213,13 +225,11 @@ bool SVGFontData::applySVGGlyphSelection(WidthIterator& iterator, GlyphData& gly
continue;
if (!isCompatibleGlyph(svgGlyph, isVerticalText, language, arabicForms, currentCharacter, currentCharacter + svgGlyph.unicodeStringLength))
continue;
- iterator.setLastGlyphName(svgGlyph.glyphName);
glyphData.glyph = svgGlyph.tableEntry;
advanceLength = svgGlyph.unicodeStringLength;
return true;
}
- iterator.setLastGlyphName(String());
return false;
}
@@ -229,8 +239,6 @@ bool SVGFontData::fillSVGGlyphPage(GlyphPage* pageToFill, unsigned offset, unsig
ASSERT(fontData->isSVGFont());
SVGFontFaceElement* fontFaceElement = this->svgFontFaceElement();
- ASSERT(fontFaceElement);
-
SVGFontElement* fontElement = fontFaceElement->associatedFontElement();
ASSERT(fontElement);
@@ -248,10 +256,8 @@ bool SVGFontData::fillBMPGlyphs(SVGFontElement* fontElement, GlyphPage* pageToFi
for (unsigned i = 0; i < length; ++i) {
String lookupString(buffer + i, 1);
fontElement->collectGlyphsForString(lookupString, glyphs);
- if (glyphs.isEmpty()) {
- pageToFill->setGlyphDataForIndex(offset + i, 0, 0);
+ if (glyphs.isEmpty())
continue;
- }
// Associate entry in glyph page with first valid SVGGlyph.
// If there are multiple valid ones, just take the first one. WidthIterator will take
@@ -273,10 +279,8 @@ bool SVGFontData::fillNonBMPGlyphs(SVGFontElement* fontElement, GlyphPage* pageT
// Each character here consists of a surrogate pair
String lookupString(buffer + i * 2, 2);
fontElement->collectGlyphsForString(lookupString, glyphs);
- if (glyphs.isEmpty()) {
- pageToFill->setGlyphDataForIndex(offset + i, 0, 0);
+ if (glyphs.isEmpty())
continue;
- }
// Associate entry in glyph page with first valid SVGGlyph.
// If there are multiple valid ones, just take the first one. WidthIterator will take
@@ -317,6 +321,19 @@ String SVGFontData::createStringWithMirroredCharacters(const String& string) con
return mirroredCharacters.toString();
}
+SVGFontFaceElement* SVGFontData::svgFontFaceElement() const
+{
+ // FIXME: SVGFontData should be only used from the document with the SVGFontFaceElement.
+ RELEASE_ASSERT(m_svgFontFaceElement && m_svgFontFaceElement->inDocument());
+ return m_svgFontFaceElement.get();
+}
+
+bool SVGFontData::shouldSkipDrawing() const
+{
+ // FIXME: (http://crbug.com/359380) Glyph may be referenced after removeNode from the current editing impl.
+ return !m_svgFontFaceElement || !m_svgFontFaceElement->inDocument();
+}
+
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontData.h b/chromium/third_party/WebKit/Source/core/svg/SVGFontData.h
index 8d4483fbfd7..7a59dc3d95a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontData.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontData.h
@@ -22,6 +22,7 @@
#if ENABLE(SVG_FONTS)
#include "platform/fonts/CustomFontData.h"
+#include "wtf/WeakPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -37,16 +38,16 @@ public:
return adoptRef(new SVGFontData(element));
}
- virtual ~SVGFontData() { }
+ virtual ~SVGFontData();
virtual bool isSVGFont() const OVERRIDE { return true; };
+ virtual bool shouldSkipDrawing() const OVERRIDE;
virtual void initializeFontData(SimpleFontData*, float fontSize) OVERRIDE;
virtual float widthForSVGGlyph(Glyph, float fontSize) const OVERRIDE;
virtual bool fillSVGGlyphPage(GlyphPage*, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData*) const OVERRIDE;
virtual bool applySVGGlyphSelection(WidthIterator&, GlyphData&, bool mirror, int currentCharacter, unsigned& advanceLength) const OVERRIDE;
-
- SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement; }
+ SVGFontFaceElement* svgFontFaceElement() const;
float horizontalOriginX() const { return m_horizontalOriginX; }
float horizontalOriginY() const { return m_horizontalOriginY; }
@@ -70,7 +71,7 @@ private:
// 2) in the in-document font case: by virtue of being in the document tree and making sure that when it is removed
// from the document, it removes the @font-face rule it owns from the document's mapped element sheet and forces
// a style update.
- SVGFontFaceElement* m_svgFontFaceElement;
+ WeakPtr<SVGFontFaceElement> m_svgFontFaceElement;
float m_horizontalOriginX;
float m_horizontalOriginY;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFontElement.cpp
index 6f956f582af..0d025f48469 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontElement.cpp
@@ -24,6 +24,7 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGFontElement.h"
+#include "core/dom/ElementTraversal.h"
#include "core/frame/UseCounter.h"
#include "core/svg/SVGGlyphElement.h"
#include "core/svg/SVGHKernElement.h"
@@ -33,50 +34,28 @@
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_BOOLEAN(SVGFontElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFontElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGFontElement::SVGFontElement(Document& document)
: SVGElement(SVGNames::fontTag, document)
, m_missingGlyph(0)
, m_isGlyphCacheValid(false)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGFontElement();
UseCounter::count(document, UseCounter::SVGFontElement);
}
-PassRefPtr<SVGFontElement> SVGFontElement::create(Document& document)
-{
- return adoptRef(new SVGFontElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFontElement)
void SVGFontElement::invalidateGlyphCache()
{
if (m_isGlyphCacheValid) {
m_glyphMap.clear();
- m_horizontalKerningPairs.clear();
- m_verticalKerningPairs.clear();
+ m_horizontalKerningTable.clear();
+ m_verticalKerningTable.clear();
}
m_isGlyphCacheValid = false;
}
-SVGMissingGlyphElement* SVGFontElement::firstMissingGlyphElement() const
-{
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(SVGNames::missing_glyphTag))
- return toSVGMissingGlyphElement(child);
- }
-
- return 0;
-}
-
void SVGFontElement::registerLigaturesInGlyphCache(Vector<String>& ligatures)
{
ASSERT(!ligatures.isEmpty());
@@ -113,35 +92,100 @@ void SVGFontElement::registerLigaturesInGlyphCache(Vector<String>& ligatures)
}
}
+static inline KerningPairKey makeKerningPairKey(Glyph glyphId1, Glyph glyphId2)
+{
+ return glyphId1 << 16 | glyphId2;
+}
+
+Vector<SVGGlyph> SVGFontElement::buildGlyphList(const UnicodeRanges& unicodeRanges, const HashSet<String>& unicodeNames, const HashSet<String>& glyphNames) const
+{
+ Vector<SVGGlyph> glyphs;
+ if (!unicodeRanges.isEmpty()) {
+ const UnicodeRanges::const_iterator end = unicodeRanges.end();
+ for (UnicodeRanges::const_iterator it = unicodeRanges.begin(); it != end; ++it)
+ m_glyphMap.collectGlyphsForUnicodeRange(*it, glyphs);
+ }
+ if (!unicodeNames.isEmpty()) {
+ const HashSet<String>::const_iterator end = unicodeNames.end();
+ for (HashSet<String>::const_iterator it = unicodeNames.begin(); it != end; ++it)
+ m_glyphMap.collectGlyphsForStringExact(*it, glyphs);
+ }
+ if (!glyphNames.isEmpty()) {
+ const HashSet<String>::const_iterator end = glyphNames.end();
+ for (HashSet<String>::const_iterator it = glyphNames.begin(); it != end; ++it) {
+ const SVGGlyph& glyph = m_glyphMap.glyphIdentifierForGlyphName(*it);
+ if (glyph.tableEntry)
+ glyphs.append(glyph);
+ }
+ }
+ return glyphs;
+}
+
+void SVGFontElement::addPairsToKerningTable(const SVGKerningPair& kerningPair, KerningTable& kerningTable)
+{
+ Vector<SVGGlyph> glyphsLhs = buildGlyphList(kerningPair.unicodeRange1, kerningPair.unicodeName1, kerningPair.glyphName1);
+ Vector<SVGGlyph> glyphsRhs = buildGlyphList(kerningPair.unicodeRange2, kerningPair.unicodeName2, kerningPair.glyphName2);
+ if (glyphsLhs.isEmpty() || glyphsRhs.isEmpty())
+ return;
+ size_t glyphsLhsSize = glyphsLhs.size();
+ size_t glyphsRhsSize = glyphsRhs.size();
+ // Enumerate all the valid kerning pairs, and add them to the table.
+ for (size_t lhsIndex = 0; lhsIndex < glyphsLhsSize; ++lhsIndex) {
+ for (size_t rhsIndex = 0; rhsIndex < glyphsRhsSize; ++rhsIndex) {
+ Glyph glyph1 = glyphsLhs[lhsIndex].tableEntry;
+ Glyph glyph2 = glyphsRhs[rhsIndex].tableEntry;
+ ASSERT(glyph1 && glyph2);
+ kerningTable.add(makeKerningPairKey(glyph1, glyph2), kerningPair.kerning);
+ }
+ }
+}
+
+void SVGFontElement::buildKerningTable(const KerningPairVector& kerningPairs, KerningTable& kerningTable)
+{
+ size_t kerningPairsSize = kerningPairs.size();
+ for (size_t i = 0; i < kerningPairsSize; ++i)
+ addPairsToKerningTable(kerningPairs[i], kerningTable);
+}
+
void SVGFontElement::ensureGlyphCache()
{
if (m_isGlyphCacheValid)
return;
+ KerningPairVector horizontalKerningPairs;
+ KerningPairVector verticalKerningPairs;
+
SVGMissingGlyphElement* firstMissingGlyphElement = 0;
Vector<String> ligatures;
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- if (child->hasTagName(SVGNames::glyphTag)) {
- SVGGlyphElement* glyph = toSVGGlyphElement(child);
- AtomicString unicode = glyph->fastGetAttribute(SVGNames::unicodeAttr);
- AtomicString glyphId = glyph->getIdAttribute();
+ for (SVGElement* element = Traversal<SVGElement>::firstChild(*this); element; element = Traversal<SVGElement>::nextSibling(*element)) {
+ if (isSVGGlyphElement(*element)) {
+ SVGGlyphElement& glyph = toSVGGlyphElement(*element);
+ AtomicString unicode = glyph.fastGetAttribute(SVGNames::unicodeAttr);
+ AtomicString glyphId = glyph.getIdAttribute();
if (glyphId.isEmpty() && unicode.isEmpty())
continue;
- m_glyphMap.addGlyph(glyphId, unicode, glyph->buildGlyphIdentifier());
+ m_glyphMap.addGlyph(glyphId, unicode, glyph.buildGlyphIdentifier());
// Register ligatures, if needed, don't mix up with surrogate pairs though!
if (unicode.length() > 1 && !U16_IS_SURROGATE(unicode[0]))
ligatures.append(unicode.string());
- } else if (child->hasTagName(SVGNames::hkernTag)) {
- toSVGHKernElement(child)->buildHorizontalKerningPair(m_horizontalKerningPairs);
- } else if (child->hasTagName(SVGNames::vkernTag)) {
- toSVGVKernElement(child)->buildVerticalKerningPair(m_verticalKerningPairs);
- } else if (child->hasTagName(SVGNames::missing_glyphTag) && !firstMissingGlyphElement) {
- firstMissingGlyphElement = toSVGMissingGlyphElement(child);
+ } else if (isSVGHKernElement(*element)) {
+ toSVGHKernElement(*element).buildHorizontalKerningPair(horizontalKerningPairs);
+ } else if (isSVGVKernElement(*element)) {
+ toSVGVKernElement(*element).buildVerticalKerningPair(verticalKerningPairs);
+ } else if (isSVGMissingGlyphElement(*element) && !firstMissingGlyphElement) {
+ firstMissingGlyphElement = toSVGMissingGlyphElement(element);
}
}
+ // Build the kerning tables.
+ buildKerningTable(horizontalKerningPairs, m_horizontalKerningTable);
+ buildKerningTable(verticalKerningPairs, m_verticalKerningTable);
+
+ // The glyph-name->glyph-id map won't be needed/used after having built the kerning table(s).
+ m_glyphMap.dropNamedGlyphMap();
+
// Register each character of each ligature, if needed.
if (!ligatures.isEmpty())
registerLigaturesInGlyphCache(ligatures);
@@ -157,76 +201,29 @@ void SVGFontElement::ensureGlyphCache()
m_isGlyphCacheValid = true;
}
-static bool stringMatchesUnicodeRange(const String& unicodeString, const UnicodeRanges& ranges, const HashSet<String>& unicodeValues)
+static float kerningForPairOfGlyphs(const KerningTable& kerningTable, Glyph glyphId1, Glyph glyphId2)
{
- if (unicodeString.isEmpty())
- return false;
-
- if (!ranges.isEmpty()) {
- UChar firstChar = unicodeString[0];
- const UnicodeRanges::const_iterator end = ranges.end();
- for (UnicodeRanges::const_iterator it = ranges.begin(); it != end; ++it) {
- if (firstChar >= it->first && firstChar <= it->second)
- return true;
- }
- }
-
- if (!unicodeValues.isEmpty())
- return unicodeValues.contains(unicodeString);
-
- return false;
-}
-
-static bool stringMatchesGlyphName(const String& glyphName, const HashSet<String>& glyphValues)
-{
- if (glyphName.isEmpty())
- return false;
-
- if (!glyphValues.isEmpty())
- return glyphValues.contains(glyphName);
-
- return false;
-}
-
-static bool matches(const String& u1, const String& g1, const String& u2, const String& g2, const SVGKerningPair& kerningPair)
-{
- if (!stringMatchesUnicodeRange(u1, kerningPair.unicodeRange1, kerningPair.unicodeName1)
- && !stringMatchesGlyphName(g1, kerningPair.glyphName1))
- return false;
-
- if (!stringMatchesUnicodeRange(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)
- && !stringMatchesGlyphName(g2, kerningPair.glyphName2))
- return false;
-
- return true;
-}
-
-static float kerningForPairOfStringsAndGlyphs(const KerningPairVector& kerningPairs, const String& u1, const String& g1, const String& u2, const String& g2)
-{
- KerningPairVector::const_iterator it = kerningPairs.end() - 1;
- const KerningPairVector::const_iterator begin = kerningPairs.begin() - 1;
- for (; it != begin; --it) {
- if (matches(u1, g1, u2, g2, *it))
- return it->kerning;
- }
+ KerningTable::const_iterator result = kerningTable.find(makeKerningPairKey(glyphId1, glyphId2));
+ if (result != kerningTable.end())
+ return result->value;
return 0;
}
-float SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const
+float SVGFontElement::horizontalKerningForPairOfGlyphs(Glyph glyphId1, Glyph glyphId2) const
{
- if (m_horizontalKerningPairs.isEmpty())
+ if (m_horizontalKerningTable.isEmpty())
return 0;
- return kerningForPairOfStringsAndGlyphs(m_horizontalKerningPairs, u1, g1, u2, g2);
+ return kerningForPairOfGlyphs(m_horizontalKerningTable, glyphId1, glyphId2);
}
-float SVGFontElement::verticalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const
+float SVGFontElement::verticalKerningForPairOfGlyphs(Glyph glyphId1, Glyph glyphId2) const
{
- if (m_verticalKerningPairs.isEmpty())
+ if (m_verticalKerningTable.isEmpty())
return 0;
- return kerningForPairOfStringsAndGlyphs(m_verticalKerningPairs, u1, g1, u2, g2);
+ return kerningForPairOfGlyphs(m_verticalKerningTable, glyphId1, glyphId2);
}
void SVGFontElement::collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs)
@@ -235,11 +232,11 @@ void SVGFontElement::collectGlyphsForString(const String& string, Vector<SVGGlyp
m_glyphMap.collectGlyphsForString(string, glyphs);
}
-void SVGFontElement::collectGlyphsForGlyphName(const String& glyphName, Vector<SVGGlyph>& glyphs)
+void SVGFontElement::collectGlyphsForAltGlyphReference(const String& glyphIdentifier, Vector<SVGGlyph>& glyphs)
{
ensureGlyphCache();
// FIXME: We only support glyphName -> single glyph mapping so far.
- glyphs.append(m_glyphMap.glyphIdentifierForGlyphName(glyphName));
+ glyphs.append(m_glyphMap.glyphIdentifierForAltGlyphReference(glyphIdentifier));
}
SVGGlyph SVGFontElement::svgGlyphForGlyph(Glyph glyph)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFontElement.h
index f7d945ef502..78024ff584b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontElement.h
@@ -23,10 +23,9 @@
#define SVGFontElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGlyphMap.h"
#include "core/svg/SVGParserUtilities.h"
@@ -48,49 +47,44 @@ struct SVGKerningPair {
}
};
+typedef unsigned KerningPairKey;
typedef Vector<SVGKerningPair> KerningPairVector;
+typedef HashMap<KerningPairKey, float> KerningTable;
-class SVGMissingGlyphElement;
-
-class SVGFontElement FINAL : public SVGElement
- , public SVGExternalResourcesRequired {
+class SVGFontElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGFontElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFontElement);
void invalidateGlyphCache();
void collectGlyphsForString(const String&, Vector<SVGGlyph>&);
- void collectGlyphsForGlyphName(const String&, Vector<SVGGlyph>&);
+ void collectGlyphsForAltGlyphReference(const String&, Vector<SVGGlyph>&);
- float horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const;
- float verticalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const;
+ float horizontalKerningForPairOfGlyphs(Glyph, Glyph) const;
+ float verticalKerningForPairOfGlyphs(Glyph, Glyph) const;
// Used by SimpleFontData/WidthIterator.
SVGGlyph svgGlyphForGlyph(Glyph);
Glyph missingGlyph();
- SVGMissingGlyphElement* firstMissingGlyphElement() const;
-
private:
explicit SVGFontElement(Document&);
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
void ensureGlyphCache();
void registerLigaturesInGlyphCache(Vector<String>&);
+ Vector<SVGGlyph> buildGlyphList(const UnicodeRanges&, const HashSet<String>& unicodeNames, const HashSet<String>& glyphNames) const;
+ void addPairsToKerningTable(const SVGKerningPair&, KerningTable&);
+ void buildKerningTable(const KerningPairVector&, KerningTable&);
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFontElement)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
- KerningPairVector m_horizontalKerningPairs;
- KerningPairVector m_verticalKerningPairs;
+ KerningTable m_horizontalKerningTable;
+ KerningTable m_verticalKerningTable;
SVGGlyphMap m_glyphMap;
Glyph m_missingGlyph;
bool m_isGlyphCacheValid;
};
-DEFINE_NODE_TYPE_CASTS(SVGFontElement, hasTagName(SVGNames::fontTag));
-
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp
index a4907f53142..540ac3fc737 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp
@@ -24,22 +24,23 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGFontFaceElement.h"
-#include <math.h>
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
#include "core/css/CSSFontFaceSrcValue.h"
-#include "core/css/CSSParser.h"
+#include "core/css/CSSFontSelector.h"
#include "core/css/CSSStyleSheet.h"
#include "core/css/CSSValueList.h"
#include "core/css/StylePropertySet.h"
#include "core/css/StyleRule.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGFontElement.h"
#include "core/svg/SVGFontFaceSrcElement.h"
#include "core/svg/SVGGlyphElement.h"
#include "platform/fonts/Font.h"
+#include <math.h>
namespace WebCore {
@@ -48,17 +49,15 @@ using namespace SVGNames;
inline SVGFontFaceElement::SVGFontFaceElement(Document& document)
: SVGElement(font_faceTag, document)
, m_fontFaceRule(StyleRuleFontFace::create())
- , m_fontElement(0)
+ , m_fontElement(nullptr)
+ , m_weakFactory(this)
{
ScriptWrappable::init(this);
- RefPtr<MutableStylePropertySet> styleDeclaration = MutableStylePropertySet::create(HTMLStandardMode);
+ RefPtrWillBeRawPtr<MutableStylePropertySet> styleDeclaration = MutableStylePropertySet::create(HTMLStandardMode);
m_fontFaceRule->setProperties(styleDeclaration.release());
}
-PassRefPtr<SVGFontFaceElement> SVGFontFaceElement::create(Document& document)
-{
- return adoptRef(new SVGFontFaceElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFontFaceElement)
static CSSPropertyID cssPropertyIdForFontFaceAttributeName(const QualifiedName& attrName)
{
@@ -112,7 +111,7 @@ void SVGFontFaceElement::parseAttribute(const QualifiedName& name, const AtomicS
{
CSSPropertyID propId = cssPropertyIdForFontFaceAttributeName(name);
if (propId > 0) {
- m_fontFaceRule->mutableProperties()->setProperty(propId, value, false);
+ m_fontFaceRule->mutableProperties().setProperty(propId, value, false);
rebuildFontFace();
return;
}
@@ -257,13 +256,13 @@ int SVGFontFaceElement::descent() const
String SVGFontFaceElement::fontFamily() const
{
- return m_fontFaceRule->properties()->getPropertyValue(CSSPropertyFontFamily);
+ return m_fontFaceRule->properties().getPropertyValue(CSSPropertyFontFamily);
}
SVGFontElement* SVGFontFaceElement::associatedFontElement() const
{
ASSERT(parentNode() == m_fontElement);
- ASSERT(!parentNode() || parentNode()->hasTagName(SVGNames::fontTag));
+ ASSERT(!parentNode() || isSVGFontElement(*parentNode()));
return m_fontElement;
}
@@ -274,16 +273,8 @@ void SVGFontFaceElement::rebuildFontFace()
return;
}
- // we currently ignore all but the first src element, alternatively we could concat them
- SVGFontFaceSrcElement* srcElement = 0;
-
- for (Node* child = firstChild(); child && !srcElement; child = child->nextSibling()) {
- if (child->hasTagName(font_face_srcTag))
- srcElement = static_cast<SVGFontFaceSrcElement*>(child);
- }
-
- bool describesParentFont = parentNode()->hasTagName(SVGNames::fontTag);
- RefPtr<CSSValueList> list;
+ bool describesParentFont = isSVGFontElement(*parentNode());
+ RefPtrWillBeRawPtr<CSSValueList> list = nullptr;
if (describesParentFont) {
m_fontElement = toSVGFontElement(parentNode());
@@ -291,20 +282,21 @@ void SVGFontFaceElement::rebuildFontFace()
list = CSSValueList::createCommaSeparated();
list->append(CSSFontFaceSrcValue::createLocal(fontFamily()));
} else {
- m_fontElement = 0;
- if (srcElement)
- list = srcElement->srcValue();
+ m_fontElement = nullptr;
+ // we currently ignore all but the last src element, alternatively we could concat them
+ if (SVGFontFaceSrcElement* element = Traversal<SVGFontFaceSrcElement>::lastChild(*this))
+ list = element->srcValue();
}
if (!list || !list->length())
return;
// Parse in-memory CSS rules
- m_fontFaceRule->mutableProperties()->addParsedProperty(CSSProperty(CSSPropertySrc, list));
+ m_fontFaceRule->mutableProperties().addParsedProperty(CSSProperty(CSSPropertySrc, list));
if (describesParentFont) {
// Traverse parsed CSS values and associate CSSFontFaceSrcValue elements with ourselves.
- RefPtr<CSSValue> src = m_fontFaceRule->properties()->getPropertyCSSValue(CSSPropertySrc);
+ RefPtrWillBeRawPtr<CSSValue> src = m_fontFaceRule->properties().getPropertyCSSValue(CSSPropertySrc);
CSSValueList* srcList = toCSSValueList(src.get());
unsigned srcLength = srcList ? srcList->length() : 0;
@@ -314,7 +306,7 @@ void SVGFontFaceElement::rebuildFontFace()
}
}
- document().styleResolverChanged(RecalcStyleDeferred);
+ document().styleResolverChanged();
}
Node::InsertionNotificationRequest SVGFontFaceElement::insertedInto(ContainerNode* rootParent)
@@ -324,7 +316,7 @@ Node::InsertionNotificationRequest SVGFontFaceElement::insertedInto(ContainerNod
ASSERT(!m_fontElement);
return InsertionDone;
}
- document().accessSVGExtensions()->registerSVGFontFaceElement(this);
+ document().accessSVGExtensions().registerSVGFontFaceElement(this);
rebuildFontFace();
return InsertionDone;
@@ -335,11 +327,18 @@ void SVGFontFaceElement::removedFrom(ContainerNode* rootParent)
SVGElement::removedFrom(rootParent);
if (rootParent->inDocument()) {
- m_fontElement = 0;
- document().accessSVGExtensions()->unregisterSVGFontFaceElement(this);
- m_fontFaceRule->mutableProperties()->clear();
-
- document().styleResolverChanged(RecalcStyleDeferred);
+ m_fontElement = nullptr;
+ document().accessSVGExtensions().unregisterSVGFontFaceElement(this);
+
+ // FIXME: HTMLTemplateElement's document or imported document can be active?
+ // If so, we also need to check whether fontSelector() is nullptr or not.
+ // Otherwise, we will use just document().isActive() here.
+ if (document().isActive() && document().styleEngine()->fontSelector()) {
+ document().styleEngine()->fontSelector()->fontFaceCache()->remove(m_fontFaceRule.get());
+ document().accessSVGExtensions().registerPendingSVGFontFaceElementsForRemoval(this);
+ }
+ m_fontFaceRule->mutableProperties().clear();
+ document().styleResolverChanged();
} else
ASSERT(!m_fontElement);
}
@@ -350,6 +349,13 @@ void SVGFontFaceElement::childrenChanged(bool changedByParser, Node* beforeChang
rebuildFontFace();
}
+void SVGFontFaceElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_fontFaceRule);
+ visitor->trace(m_fontElement);
+ SVGElement::trace(visitor);
+}
+
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.h
index 0950ef41323..292d3585dd9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceElement.h
@@ -23,8 +23,9 @@
#define SVGFontFaceElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
+#include "wtf/WeakPtr.h"
namespace WebCore {
@@ -33,7 +34,7 @@ class StyleRuleFontFace;
class SVGFontFaceElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGFontFaceElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFontFaceElement);
unsigned unitsPerEm() const;
int xHeight() const;
@@ -51,24 +52,26 @@ public:
void rebuildFontFace();
StyleRuleFontFace* fontFaceRule() const { return m_fontFaceRule.get(); }
+ WeakPtr<SVGFontFaceElement> createWeakRef() { return m_weakFactory.createWeakPtr(); }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit SVGFontFaceElement(Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
- RefPtr<StyleRuleFontFace> m_fontFaceRule;
- SVGFontElement* m_fontElement;
+ RefPtrWillBeMember<StyleRuleFontFace> m_fontFaceRule;
+ RawPtrWillBeMember<SVGFontElement> m_fontElement;
+ WeakPtrFactory<SVGFontFaceElement> m_weakFactory;
};
-DEFINE_NODE_TYPE_CASTS(SVGFontFaceElement, hasTagName(SVGNames::font_faceTag));
-
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp
index 5468bdb240e..4229f947884 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp
@@ -22,7 +22,7 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGFontFaceFormatElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGFontFaceElement.h"
namespace WebCore {
@@ -35,24 +35,21 @@ inline SVGFontFaceFormatElement::SVGFontFaceFormatElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFontFaceFormatElement> SVGFontFaceFormatElement::create(Document& document)
-{
- return adoptRef(new SVGFontFaceFormatElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFontFaceFormatElement)
void SVGFontFaceFormatElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!parentNode() || !parentNode()->hasTagName(font_face_uriTag))
+ if (!isSVGFontFaceUriElement(parentNode()))
return;
ContainerNode* ancestor = parentNode()->parentNode();
- if (!ancestor || !ancestor->hasTagName(font_face_srcTag))
+ if (!isSVGFontFaceSrcElement(ancestor))
return;
ancestor = ancestor->parentNode();
- if (ancestor && ancestor->hasTagName(font_faceTag))
+ if (isSVGFontFaceElement(ancestor))
toSVGFontFaceElement(ancestor)->rebuildFontFace();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.h
index 986431a58bd..ae0df13ff42 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.h
@@ -27,12 +27,12 @@ namespace WebCore {
class SVGFontFaceFormatElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGFontFaceFormatElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFontFaceFormatElement);
private:
explicit SVGFontFaceFormatElement(Document&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp
index 2675278c0ff..568d31d8de7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp
@@ -32,12 +32,9 @@ inline SVGFontFaceNameElement::SVGFontFaceNameElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFontFaceNameElement> SVGFontFaceNameElement::create(Document& document)
-{
- return adoptRef(new SVGFontFaceNameElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFontFaceNameElement)
-PassRefPtr<CSSFontFaceSrcValue> SVGFontFaceNameElement::srcValue() const
+PassRefPtrWillBeRawPtr<CSSFontFaceSrcValue> SVGFontFaceNameElement::srcValue() const
{
return CSSFontFaceSrcValue::createLocal(fastGetAttribute(SVGNames::nameAttr));
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.h
index 8b9394278c3..069509a2f6b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.h
@@ -21,7 +21,7 @@
#define SVGFontFaceNameElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
namespace WebCore {
@@ -30,9 +30,9 @@ class CSSFontFaceSrcValue;
class SVGFontFaceNameElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGFontFaceNameElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFontFaceNameElement);
- PassRefPtr<CSSFontFaceSrcValue> srcValue() const;
+ PassRefPtrWillBeRawPtr<CSSFontFaceSrcValue> srcValue() const;
private:
explicit SVGFontFaceNameElement(Document&);
@@ -40,8 +40,6 @@ private:
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
};
-DEFINE_NODE_TYPE_CASTS(SVGFontFaceNameElement, hasTagName(SVGNames::font_face_nameTag));
-
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp
new file mode 100644
index 00000000000..0f481f18c41
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp
@@ -0,0 +1,39 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#if ENABLE(SVG_FONTS)
+#include "core/svg/SVGFontFaceSource.h"
+
+#include "core/svg/SVGFontData.h"
+#include "core/svg/SVGFontFaceElement.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+
+namespace WebCore {
+
+SVGFontFaceSource::SVGFontFaceSource(SVGFontFaceElement* element)
+ : m_svgFontFaceElement(element)
+{
+}
+
+PassRefPtr<SimpleFontData> SVGFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+ return SimpleFontData::create(
+ SVGFontData::create(m_svgFontFaceElement.get()),
+ fontDescription.effectiveFontSize(),
+ fontDescription.isSyntheticBold(),
+ fontDescription.isSyntheticItalic());
+}
+
+void SVGFontFaceSource::trace(Visitor* visitor)
+{
+ visitor->trace(m_svgFontFaceElement);
+ CSSFontFaceSource::trace(visitor);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSource.h b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSource.h
new file mode 100644
index 00000000000..fdf13f23e98
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSource.h
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SVGFontFaceSource_h
+#define SVGFontFaceSource_h
+
+#if ENABLE(SVG_FONTS)
+
+#include "core/css/CSSFontFaceSource.h"
+
+namespace WebCore {
+
+class SVGFontFaceElement;
+
+class SVGFontFaceSource : public CSSFontFaceSource {
+public:
+ SVGFontFaceSource(SVGFontFaceElement*);
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+
+ RawPtrWillBeMember<SVGFontFaceElement> m_svgFontFaceElement;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG_FONTS)
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp
index bc2254ddea8..5485c4fee00 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp
@@ -22,9 +22,10 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGFontFaceSrcElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/css/CSSFontFaceSrcValue.h"
#include "core/css/CSSValueList.h"
+#include "core/dom/ElementTraversal.h"
#include "core/svg/SVGFontFaceElement.h"
#include "core/svg/SVGFontFaceNameElement.h"
#include "core/svg/SVGFontFaceUriElement.h"
@@ -39,20 +40,17 @@ inline SVGFontFaceSrcElement::SVGFontFaceSrcElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFontFaceSrcElement> SVGFontFaceSrcElement::create(Document& document)
-{
- return adoptRef(new SVGFontFaceSrcElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFontFaceSrcElement)
-PassRefPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const
+PassRefPtrWillBeRawPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const
{
- RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
- for (Node* child = firstChild(); child; child = child->nextSibling()) {
- RefPtr<CSSFontFaceSrcValue> srcValue;
- if (child->hasTagName(font_face_uriTag))
- srcValue = toSVGFontFaceUriElement(child)->srcValue();
- else if (child->hasTagName(font_face_nameTag))
- srcValue = toSVGFontFaceNameElement(child)->srcValue();
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+ for (SVGElement* element = Traversal<SVGElement>::firstChild(*this); element; element = Traversal<SVGElement>::nextSibling(*element)) {
+ RefPtrWillBeRawPtr<CSSFontFaceSrcValue> srcValue = nullptr;
+ if (isSVGFontFaceUriElement(*element))
+ srcValue = toSVGFontFaceUriElement(*element).srcValue();
+ else if (isSVGFontFaceNameElement(*element))
+ srcValue = toSVGFontFaceNameElement(*element).srcValue();
if (srcValue && srcValue->resource().length())
list->append(srcValue);
@@ -63,8 +61,8 @@ PassRefPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const
void SVGFontFaceSrcElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (parentNode() && parentNode()->hasTagName(font_faceTag))
- toSVGFontFaceElement(parentNode())->rebuildFontFace();
+ if (isSVGFontFaceElement(parentNode()))
+ toSVGFontFaceElement(*parentNode()).rebuildFontFace();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.h
index f7ef1af6f6b..5dd85481cc9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.h
@@ -21,6 +21,7 @@
#define SVGFontFaceSrcElement_h
#if ENABLE(SVG_FONTS)
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
namespace WebCore {
@@ -29,14 +30,14 @@ class CSSValueList;
class SVGFontFaceSrcElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGFontFaceSrcElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFontFaceSrcElement);
- PassRefPtr<CSSValueList> srcValue() const;
+ PassRefPtrWillBeRawPtr<CSSValueList> srcValue() const;
private:
explicit SVGFontFaceSrcElement(Document&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp
index fabcf7f5b0c..0386da1670b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp
@@ -23,7 +23,7 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGFontFaceUriElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
#include "core/css/CSSFontFaceSrcValue.h"
#include "core/dom/Document.h"
#include "core/fetch/FetchRequest.h"
@@ -40,10 +40,7 @@ inline SVGFontFaceUriElement::SVGFontFaceUriElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGFontFaceUriElement> SVGFontFaceUriElement::create(Document& document)
-{
- return adoptRef(new SVGFontFaceUriElement(document));
-}
+DEFINE_NODE_FACTORY(SVGFontFaceUriElement)
SVGFontFaceUriElement::~SVGFontFaceUriElement()
{
@@ -51,9 +48,9 @@ SVGFontFaceUriElement::~SVGFontFaceUriElement()
m_resource->removeClient(this);
}
-PassRefPtr<CSSFontFaceSrcValue> SVGFontFaceUriElement::srcValue() const
+PassRefPtrWillBeRawPtr<CSSFontFaceSrcValue> SVGFontFaceUriElement::srcValue() const
{
- RefPtr<CSSFontFaceSrcValue> src = CSSFontFaceSrcValue::create(getAttribute(XLinkNames::hrefAttr));
+ RefPtrWillBeRawPtr<CSSFontFaceSrcValue> src = CSSFontFaceSrcValue::create(getAttribute(XLinkNames::hrefAttr));
AtomicString value(fastGetAttribute(formatAttr));
src->setFormat(value.isEmpty() ? "svg" : value); // Default format
return src.release();
@@ -61,7 +58,7 @@ PassRefPtr<CSSFontFaceSrcValue> SVGFontFaceUriElement::srcValue() const
void SVGFontFaceUriElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (name == XLinkNames::hrefAttr)
+ if (name.matches(XLinkNames::hrefAttr))
loadFont();
else
SVGElement::parseAttribute(name, value);
@@ -71,12 +68,12 @@ void SVGFontFaceUriElement::childrenChanged(bool changedByParser, Node* beforeCh
{
SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (!parentNode() || !parentNode()->hasTagName(font_face_srcTag))
+ if (!isSVGFontFaceSrcElement(parentNode()))
return;
ContainerNode* grandparent = parentNode()->parentNode();
- if (grandparent && grandparent->hasTagName(font_faceTag))
- toSVGFontFaceElement(grandparent)->rebuildFontFace();
+ if (isSVGFontFaceElement(grandparent))
+ toSVGFontFaceElement(*grandparent).rebuildFontFace();
}
Node::InsertionNotificationRequest SVGFontFaceUriElement::insertedInto(ContainerNode* rootParent)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.h
index 338ce85b115..e738269c065 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.h
@@ -21,7 +21,7 @@
#define SVGFontFaceUriElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/fetch/FontResource.h"
#include "core/fetch/ResourcePtr.h"
#include "core/svg/SVGElement.h"
@@ -32,17 +32,17 @@ class CSSFontFaceSrcValue;
class SVGFontFaceUriElement FINAL : public SVGElement, public FontResourceClient {
public:
- static PassRefPtr<SVGFontFaceUriElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGFontFaceUriElement);
virtual ~SVGFontFaceUriElement();
- PassRefPtr<CSSFontFaceSrcValue> srcValue() const;
+ PassRefPtrWillBeRawPtr<CSSFontFaceSrcValue> srcValue() const;
private:
explicit SVGFontFaceUriElement(Document&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
@@ -52,8 +52,6 @@ private:
ResourcePtr<FontResource> m_resource;
};
-DEFINE_NODE_TYPE_CASTS(SVGFontFaceUriElement, hasTagName(SVGNames::font_face_uriTag));
-
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp
index 8db9e53ced7..106d65f27f4 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp
@@ -21,54 +21,38 @@
#include "config.h"
#include "core/svg/SVGForeignObjectElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
+#include "core/frame/UseCounter.h"
#include "core/rendering/svg/RenderSVGForeignObject.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLength.h"
#include "wtf/Assertions.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGForeignObjectElement, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_STRING(SVGForeignObjectElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGForeignObjectElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGForeignObjectElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGForeignObjectElement::SVGForeignObjectElement(Document& document)
: SVGGraphicsElement(SVGNames::foreignObjectTag, document)
- , m_x(LengthModeWidth)
- , m_y(LengthModeHeight)
- , m_width(LengthModeWidth)
- , m_height(LengthModeHeight)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGForeignObjectElement();
-}
-PassRefPtr<SVGForeignObjectElement> SVGForeignObjectElement::create(Document& document)
-{
- return adoptRef(new SVGForeignObjectElement(document));
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
+
+ UseCounter::count(document, UseCounter::SVGForeignObjectElement);
}
+DEFINE_NODE_FACTORY(SVGForeignObjectElement)
+
bool SVGForeignObjectElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::xAttr);
supportedAttributes.add(SVGNames::yAttr);
supportedAttributes.add(SVGNames::widthAttr);
@@ -84,20 +68,43 @@ void SVGForeignObjectElement::parseAttribute(const QualifiedName& name, const At
if (!isSupportedAttribute(name))
SVGGraphicsElement::parseAttribute(name, value);
else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_x->setBaseValueAsString(value, parseError);
else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_y->setBaseValueAsString(value, parseError);
else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_width->setBaseValueAsString(value, parseError);
else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (SVGExternalResourcesRequired::parseAttribute(name, value)) {
- } else
+ m_height->setBaseValueAsString(value, parseError);
+ else
ASSERT_NOT_REACHED();
reportAttributeParsingError(parseError, name, value);
}
+bool SVGForeignObjectElement::isPresentationAttribute(const QualifiedName& name) const
+{
+ if (name == SVGNames::widthAttr || name == SVGNames::heightAttr)
+ return true;
+ return SVGGraphicsElement::isPresentationAttribute(name);
+}
+
+void SVGForeignObjectElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
+{
+ if (name == SVGNames::widthAttr || name == SVGNames::heightAttr) {
+ RefPtr<SVGLength> length = SVGLength::create(LengthModeOther);
+ TrackExceptionState exceptionState;
+ length->setValueAsString(value, exceptionState);
+ if (!exceptionState.hadException()) {
+ if (name == SVGNames::widthAttr)
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value);
+ else if (name == SVGNames::heightAttr)
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value);
+ }
+ } else {
+ SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
+ }
+}
+
void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
{
if (!isSupportedAttribute(attrName)) {
@@ -105,7 +112,12 @@ void SVGForeignObjectElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ if (attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr) {
+ invalidateSVGPresentationAttributeStyle();
+ setNeedsStyleRecalc(LocalStyleChange);
+ }
+
+ SVGElement::InvalidationGuard invalidationGuard(this);
bool isLengthAttribute = attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
@@ -124,16 +136,6 @@ RenderObject* SVGForeignObjectElement::createRenderer(RenderStyle*)
return new RenderSVGForeignObject(this);
}
-bool SVGForeignObjectElement::childShouldCreateRenderer(const Node& child) const
-{
- // Disallow arbitary SVG content. Only allow proper <svg xmlns="svgNS"> subdocuments.
- if (child.isSVGElement())
- return child.hasTagName(SVGNames::svgTag);
-
- // Skip over SVG rules which disallow non-SVG kids
- return Element::childShouldCreateRenderer(child);
-}
-
bool SVGForeignObjectElement::rendererIsNeeded(const RenderStyle& style)
{
// Suppress foreignObject renderers in SVG hidden containers.
@@ -154,10 +156,10 @@ bool SVGForeignObjectElement::rendererIsNeeded(const RenderStyle& style)
bool SVGForeignObjectElement::selfHasRelativeLengths() const
{
- return xCurrentValue().isRelative()
- || yCurrentValue().isRelative()
- || widthCurrentValue().isRelative()
- || heightCurrentValue().isRelative();
+ return m_x->currentValue()->isRelative()
+ || m_y->currentValue()->isRelative()
+ || m_width->currentValue()->isRelative()
+ || m_height->currentValue()->isRelative();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.h
index 38d3734f37e..db0924b8182 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.h
@@ -20,46 +20,43 @@
#ifndef SVGForeignObjectElement_h
#define SVGForeignObjectElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
#include "core/svg/SVGURIReference.h"
namespace WebCore {
-class SVGForeignObjectElement FINAL : public SVGGraphicsElement,
- public SVGExternalResourcesRequired {
+class SVGForeignObjectElement FINAL : public SVGGraphicsElement {
public:
- static PassRefPtr<SVGForeignObjectElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGForeignObjectElement);
+
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
private:
explicit SVGForeignObjectElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
+ virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGForeignObjectElement)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
};
-DEFINE_NODE_TYPE_CASTS(SVGForeignObjectElement, hasTagName(SVGNames::foreignObjectTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.idl
index 778b9f5b3d0..3d348fffbb0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGForeignObjectElement.idl
@@ -30,5 +30,3 @@ interface SVGForeignObjectElement : SVGGraphicsElement {
readonly attribute SVGAnimatedLength height;
};
-SVGForeignObjectElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGGElement.cpp
index 6345cc7570f..b9cc50355f2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGElement.cpp
@@ -22,39 +22,24 @@
#include "core/svg/SVGGElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/svg/RenderSVGHiddenContainer.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/RenderSVGTransformableContainer.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_BOOLEAN(SVGGElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
-SVGGElement::SVGGElement(Document& document, ConstructionType constructionType)
+inline SVGGElement::SVGGElement(Document& document, ConstructionType constructionType)
: SVGGraphicsElement(SVGNames::gTag, document, constructionType)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGGElement();
}
-PassRefPtr<SVGGElement> SVGGElement::create(Document& document)
-{
- return adoptRef(new SVGGElement(document));
-}
+DEFINE_NODE_FACTORY(SVGGElement)
bool SVGGElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
- if (supportedAttributes.isEmpty())
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
}
@@ -75,7 +60,7 @@ void SVGGElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (RenderObject* renderer = this->renderer())
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGGElement.h
index 255e514de40..b72fbd45a10 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGElement.h
@@ -22,34 +22,26 @@
#define SVGGElement_h
#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
namespace WebCore {
-class SVGGElement FINAL : public SVGGraphicsElement,
- public SVGExternalResourcesRequired {
+class SVGGElement FINAL : public SVGGraphicsElement {
public:
- static PassRefPtr<SVGGElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGGElement);
protected:
explicit SVGGElement(Document&, ConstructionType = CreateSVGElement);
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
private:
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGElement)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGGElement.idl
index 060969fd04e..38a114697a5 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGElement.idl
@@ -26,5 +26,3 @@
interface SVGGElement : SVGGraphicsElement {
};
-SVGGElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.cpp
index 56b3d03b560..274f7a53876 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.cpp
@@ -31,10 +31,11 @@
#include "config.h"
#include "core/svg/SVGGeometryElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/HitTestRequest.h"
#include "core/rendering/PointerEventsHitRules.h"
#include "core/rendering/svg/RenderSVGShape.h"
+#include "core/svg/SVGPointTearOff.h"
namespace WebCore {
@@ -43,7 +44,7 @@ SVGGeometryElement::SVGGeometryElement(const QualifiedName& tagName, Document& d
{
}
-bool SVGGeometryElement::isPointInFill(const SVGPoint& point) const
+bool SVGGeometryElement::isPointInFill(PassRefPtr<SVGPointTearOff> point) const
{
document().updateLayoutIgnorePendingStylesheets();
@@ -54,10 +55,10 @@ bool SVGGeometryElement::isPointInFill(const SVGPoint& point) const
HitTestRequest request(HitTestRequest::ReadOnly);
PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_GEOMETRY_HITTESTING, request, renderer()->style()->pointerEvents());
hitRules.canHitStroke = false;
- return toRenderSVGShape(renderer())->nodeAtFloatPointInternal(request, point, hitRules);
+ return toRenderSVGShape(renderer())->nodeAtFloatPointInternal(request, point->target()->value(), hitRules);
}
-bool SVGGeometryElement::isPointInStroke(const SVGPoint& point) const
+bool SVGGeometryElement::isPointInStroke(PassRefPtr<SVGPointTearOff> point) const
{
document().updateLayoutIgnorePendingStylesheets();
@@ -68,7 +69,7 @@ bool SVGGeometryElement::isPointInStroke(const SVGPoint& point) const
HitTestRequest request(HitTestRequest::ReadOnly);
PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_GEOMETRY_HITTESTING, request, renderer()->style()->pointerEvents());
hitRules.canHitFill = false;
- return toRenderSVGShape(renderer())->nodeAtFloatPointInternal(request, point, hitRules);
+ return toRenderSVGShape(renderer())->nodeAtFloatPointInternal(request, point->target()->value(), hitRules);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.h
index 09fffa51344..a4cf565d49d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.h
@@ -32,14 +32,15 @@
#define SVGGeometryElement_h
#include "core/svg/SVGGraphicsElement.h"
-#include "core/svg/SVGPoint.h"
namespace WebCore {
+class SVGPointTearOff;
+
class SVGGeometryElement : public SVGGraphicsElement {
public:
- bool isPointInFill(const SVGPoint&) const;
- bool isPointInStroke(const SVGPoint&) const;
+ bool isPointInFill(PassRefPtr<SVGPointTearOff>) const;
+ bool isPointInStroke(PassRefPtr<SVGPointTearOff>) const;
protected:
SVGGeometryElement(const QualifiedName&, Document&, ConstructionType = CreateSVGElement);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.idl
index d7837585b28..cd4887ce7c2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGeometryElement.idl
@@ -28,7 +28,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGGeometryElement : SVGGraphicsElement {
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGGeometryElement : SVGGraphicsElement {
boolean isPointInFill(SVGPoint point);
boolean isPointInStroke(SVGPoint point);
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.cpp
index ace7f98f80e..49ee49a1d38 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.cpp
@@ -36,16 +36,13 @@ inline SVGGlyphElement::SVGGlyphElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGGlyphElement> SVGGlyphElement::create(Document& document)
-{
- return adoptRef(new SVGGlyphElement(document));
-}
+DEFINE_NODE_FACTORY(SVGGlyphElement)
void SVGGlyphElement::invalidateGlyphCache()
{
ContainerNode* fontNode = parentNode();
- if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
- toSVGFontElement(fontNode)->invalidateGlyphCache();
+ if (isSVGFontElement(fontNode))
+ toSVGFontElement(*fontNode).invalidateGlyphCache();
}
void SVGGlyphElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.h
index 565eb1de154..fd3a642ea13 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphElement.h
@@ -23,7 +23,7 @@
#define SVGGlyphElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
#include "platform/fonts/SVGGlyph.h"
@@ -33,13 +33,12 @@ class SVGFontData;
class SVGGlyphElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGGlyphElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGGlyphElement);
SVGGlyph buildGlyphIdentifier() const;
// Helper function used by SVGFont
static void inheritUnspecifiedAttributes(SVGGlyph&, const SVGFontData*);
- static String querySVGFontLanguage(const SVGElement*);
// Helper function shared between SVGGlyphElement & SVGMissingGlyphElement
static SVGGlyph buildGenericGlyphIdentifier(const SVGElement*);
@@ -53,13 +52,11 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
void invalidateGlyphCache();
};
-DEFINE_NODE_TYPE_CASTS(SVGGlyphElement, hasTagName(SVGNames::glyphTag));
-
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphMap.h b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphMap.h
index 8e20f0644ca..8d13f8ba1ef 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphMap.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphMap.h
@@ -21,6 +21,7 @@
#define SVGGlyphMap_h
#if ENABLE(SVG_FONTS)
+#include "core/svg/SVGParserUtilities.h"
#include "platform/fonts/Latin1TextIterator.h"
#include "platform/fonts/SVGGlyph.h"
#include "platform/text/SurrogatePairAwareTextIterator.h"
@@ -30,7 +31,6 @@
namespace WebCore {
struct GlyphMapNode;
-class SVGFontData;
typedef HashMap<UChar32, RefPtr<GlyphMapNode> > GlyphMapLayer;
@@ -49,16 +49,16 @@ class SVGGlyphMap {
public:
SVGGlyphMap() : m_currentPriority(0) { }
- void addGlyph(const String& glyphName, const String& unicodeString, SVGGlyph glyph)
+ void addGlyph(const String& glyphIdentifier, const String& unicodeString, SVGGlyph glyph)
{
- ASSERT(!glyphName.isEmpty() || !unicodeString.isEmpty());
+ ASSERT(!glyphIdentifier.isEmpty() || !unicodeString.isEmpty());
- bool hasGlyphName = !glyphName.isEmpty();
+ bool hasGlyphIdentifier = !glyphIdentifier.isEmpty();
if (unicodeString.isEmpty()) {
- // Register named glyph in the named glyph map and in the glyph table.
- ASSERT(hasGlyphName);
+ // Register glyphs with 'id's in the id glyph map and in the glyph table.
+ ASSERT(hasGlyphIdentifier);
appendToGlyphTable(glyph);
- m_namedGlyphs.add(glyphName, glyph.tableEntry);
+ m_idGlyphs.add(glyphIdentifier, glyph.tableEntry);
return;
}
@@ -83,8 +83,10 @@ public:
// If the glyph is named, also add it to the named glyph name, and to the glyph table in both cases.
appendToGlyphTable(lastGlyph);
- if (hasGlyphName)
- m_namedGlyphs.add(glyphName, lastGlyph.tableEntry);
+ if (!lastGlyph.glyphName.isEmpty())
+ m_namedGlyphs.add(lastGlyph.glyphName, lastGlyph.tableEntry);
+ if (hasGlyphIdentifier)
+ m_idGlyphs.add(glyphIdentifier, lastGlyph.tableEntry);
}
void appendToGlyphTable(SVGGlyph& glyph)
@@ -120,13 +122,48 @@ public:
std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority);
}
+ void collectGlyphsForStringExact(const String& string, Vector<SVGGlyph>& glyphs) const
+ {
+ unsigned length = string.length();
+
+ if (!length)
+ return;
+
+ RefPtr<GlyphMapNode> node;
+ if (string.is8Bit()) {
+ Latin1TextIterator textIterator(string.characters8(), 0, length, length);
+ node = findNode(textIterator);
+ } else {
+ SurrogatePairAwareTextIterator textIterator(string.characters16(), 0, length, length);
+ node = findNode(textIterator);
+ }
+
+ if (node)
+ glyphs.appendVector(node->glyphs);
+ }
+
+ void collectGlyphsForUnicodeRange(const UnicodeRange& unicodeRange, Vector<SVGGlyph>& glyphs) const
+ {
+ for (unsigned character = unicodeRange.first; character <= unicodeRange.second; ++character) {
+ if (RefPtr<GlyphMapNode> node = m_rootLayer.get(character))
+ glyphs.appendVector(node->glyphs);
+ }
+ }
+
void clear()
{
m_rootLayer.clear();
m_glyphTable.clear();
+ m_idGlyphs.clear();
+ m_namedGlyphs.clear();
m_currentPriority = 0;
}
+ void dropNamedGlyphMap()
+ {
+ m_namedGlyphs.clear();
+ }
+
const SVGGlyph& svgGlyphForGlyph(Glyph glyph) const
{
if (!glyph || glyph > m_glyphTable.size()) {
@@ -136,6 +173,11 @@ public:
return m_glyphTable[glyph - 1];
}
+ const SVGGlyph& glyphIdentifierForAltGlyphReference(const String& glyphIdentifier) const
+ {
+ return svgGlyphForGlyph(m_idGlyphs.get(glyphIdentifier));
+ }
+
const SVGGlyph& glyphIdentifierForGlyphName(const String& glyphName) const
{
return svgGlyphForGlyph(m_namedGlyphs.get(glyphName));
@@ -164,6 +206,25 @@ private:
}
template<typename Iterator>
+ PassRefPtr<GlyphMapNode> findNode(Iterator& textIterator) const
+ {
+ const GlyphMapLayer* currentLayer = &m_rootLayer;
+
+ RefPtr<GlyphMapNode> node;
+ UChar32 character = 0;
+ unsigned clusterLength = 0;
+ while (textIterator.consume(character, clusterLength)) {
+ node = currentLayer->get(character);
+ if (!node)
+ break;
+ currentLayer = &node->children;
+ textIterator.advance(clusterLength);
+ }
+
+ return node.release();
+ }
+
+ template<typename Iterator>
void collectGlyphsForIterator(Iterator& textIterator, Vector<SVGGlyph>& glyphs)
{
GlyphMapLayer* currentLayer = &m_rootLayer;
@@ -174,7 +235,7 @@ private:
RefPtr<GlyphMapNode> node = currentLayer->get(character);
if (!node)
break;
- glyphs.append(node->glyphs);
+ glyphs.appendVector(node->glyphs);
currentLayer = &node->children;
textIterator.advance(clusterLength);
}
@@ -183,6 +244,7 @@ private:
GlyphMapLayer m_rootLayer;
Vector<SVGGlyph> m_glyphTable;
HashMap<String, Glyph> m_namedGlyphs;
+ HashMap<String, Glyph> m_idGlyphs;
int m_currentPriority;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.cpp
index 5fd1b1c3667..04461d16290 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.cpp
@@ -22,44 +22,31 @@
#if ENABLE(SVG_FONTS)
#include "core/svg/SVGGlyphRefElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
#include "core/svg/SVGParserUtilities.h"
#include "wtf/text/AtomicString.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGGlyphRefElement, XLinkNames::hrefAttr, Href, href)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGlyphRefElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGGlyphRefElement::SVGGlyphRefElement(Document& document)
: SVGElement(SVGNames::glyphRefTag, document)
+ , SVGURIReference(this)
, m_x(0)
, m_y(0)
, m_dx(0)
, m_dy(0)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGGlyphRefElement();
}
-PassRefPtr<SVGGlyphRefElement> SVGGlyphRefElement::create(Document& document)
-{
- return adoptRef(new SVGGlyphRefElement(document));
-}
+DEFINE_NODE_FACTORY(SVGGlyphRefElement)
-bool SVGGlyphRefElement::hasValidGlyphElement(String& glyphName) const
+bool SVGGlyphRefElement::hasValidGlyphElement(AtomicString& glyphName) const
{
// FIXME: We only support xlink:href so far.
// https://bugs.webkit.org/show_bug.cgi?id=64787
Element* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), document(), &glyphName);
- if (!element || !element->hasTagName(SVGNames::glyphTag))
- return false;
- return true;
+ return isSVGGlyphElement(element);
}
template<typename CharType>
@@ -69,6 +56,7 @@ void SVGGlyphRefElement::parseAttributeInternal(const QualifiedName& name, const
const CharType* end = ptr + value.length();
// FIXME: We need some error handling here.
+ SVGParsingError parseError = NoError;
if (name == SVGNames::xAttr) {
parseNumber(ptr, end, m_x);
} else if (name == SVGNames::yAttr) {
@@ -77,11 +65,11 @@ void SVGGlyphRefElement::parseAttributeInternal(const QualifiedName& name, const
parseNumber(ptr, end, m_dx);
} else if (name == SVGNames::dyAttr) {
parseNumber(ptr, end, m_dy);
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
} else {
- if (SVGURIReference::parseAttribute(name, value))
- return;
SVGElement::parseAttribute(name, value);
}
+ reportAttributeParsingError(parseError, name, value);
}
void SVGGlyphRefElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.h
index 8de1d2b96ae..a89b2473a06 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGlyphRefElement.h
@@ -21,7 +21,7 @@
#define SVGGlyphRefElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGURIReference.h"
@@ -30,9 +30,9 @@ namespace WebCore {
class SVGGlyphRefElement FINAL : public SVGElement,
public SVGURIReference {
public:
- static PassRefPtr<SVGGlyphRefElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGGlyphRefElement);
- bool hasValidGlyphElement(String& glyphName) const;
+ bool hasValidGlyphElement(AtomicString& glyphName) const;
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
// DOM interface
@@ -53,11 +53,8 @@ private:
template<typename CharType>
void parseAttributeInternal(const QualifiedName&, const AtomicString&);
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGlyphRefElement)
- DECLARE_ANIMATED_STRING(Href, href)
- END_DECLARE_ANIMATED_PROPERTIES
float m_x;
float m_y;
@@ -65,8 +62,6 @@ private:
float m_dy;
};
-DEFINE_NODE_TYPE_CASTS(SVGGlyphRefElement, hasTagName(SVGNames::glyphRefTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp
index a9a85d2e449..92b1da6ccbd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.cpp
@@ -23,41 +23,37 @@
#include "core/svg/SVGGradientElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Attribute.h"
-#include "core/rendering/svg/RenderSVGHiddenContainer.h"
#include "core/rendering/svg/RenderSVGPath.h"
#include "core/rendering/svg/RenderSVGResourceLinearGradient.h"
#include "core/rendering/svg/RenderSVGResourceRadialGradient.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGStopElement.h"
#include "core/svg/SVGTransformList.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGGradientElement, SVGNames::spreadMethodAttr, SpreadMethod, spreadMethod, SVGSpreadMethodType)
-DEFINE_ANIMATED_ENUMERATION(SVGGradientElement, SVGNames::gradientUnitsAttr, GradientUnits, gradientUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_TRANSFORM_LIST(SVGGradientElement, SVGNames::gradientTransformAttr, GradientTransform, gradientTransform)
-DEFINE_ANIMATED_STRING(SVGGradientElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGGradientElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGradientElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(spreadMethod)
- REGISTER_LOCAL_ANIMATED_PROPERTY(gradientUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(gradientTransform)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGSpreadMethodType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(SVGSpreadMethodPad, "pad"));
+ entries.append(std::make_pair(SVGSpreadMethodReflect, "reflect"));
+ entries.append(std::make_pair(SVGSpreadMethodRepeat, "repeat"));
+ }
+ return entries;
+}
SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document& document)
: SVGElement(tagName, document)
- , m_spreadMethod(SVGSpreadMethodPad)
- , m_gradientUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
+ , SVGURIReference(this)
+ , m_gradientTransform(SVGAnimatedTransformList::create(this, SVGNames::gradientTransformAttr, SVGTransformList::create()))
+ , m_spreadMethod(SVGAnimatedEnumeration<SVGSpreadMethodType>::create(this, SVGNames::spreadMethodAttr, SVGSpreadMethodPad))
+ , m_gradientUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::gradientUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
{
- ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGGradientElement();
+ addToPropertyMap(m_gradientTransform);
+ addToPropertyMap(m_spreadMethod);
+ addToPropertyMap(m_gradientUnits);
}
bool SVGGradientElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -65,7 +61,6 @@ bool SVGGradientElement::isSupportedAttribute(const QualifiedName& attrName)
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGURIReference::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::gradientUnitsAttr);
supportedAttributes.add(SVGNames::gradientTransformAttr);
supportedAttributes.add(SVGNames::spreadMethodAttr);
@@ -80,34 +75,19 @@ void SVGGradientElement::parseAttribute(const QualifiedName& name, const AtomicS
return;
}
- if (name == SVGNames::gradientUnitsAttr) {
- SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
- if (propertyValue > 0)
- setGradientUnitsBaseValue(propertyValue);
- return;
- }
-
- if (name == SVGNames::gradientTransformAttr) {
- SVGTransformList newList;
- newList.parse(value);
- detachAnimatedGradientTransformListWrappers(newList.size());
- setGradientTransformBaseValue(newList);
- return;
- }
-
- if (name == SVGNames::spreadMethodAttr) {
- SVGSpreadMethodType propertyValue = SVGPropertyTraits<SVGSpreadMethodType>::fromString(value);
- if (propertyValue > 0)
- setSpreadMethodBaseValue(propertyValue);
- return;
- }
+ SVGParsingError parseError = NoError;
- if (SVGURIReference::parseAttribute(name, value))
- return;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
+ if (name == SVGNames::gradientTransformAttr)
+ m_gradientTransform->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::gradientUnitsAttr)
+ m_gradientUnits->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::spreadMethodAttr)
+ m_spreadMethod->setBaseValueAsString(value, parseError);
+ else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else
+ ASSERT_NOT_REACHED();
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -117,7 +97,7 @@ void SVGGradientElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
RenderSVGResourceContainer* renderer = toRenderSVGResourceContainer(this->renderer());
if (renderer)
@@ -132,7 +112,7 @@ void SVGGradientElement::childrenChanged(bool changedByParser, Node* beforeChang
return;
if (RenderObject* object = renderer())
- object->setNeedsLayout();
+ object->setNeedsLayoutAndFullPaintInvalidation();
}
Vector<Gradient::ColorStop> SVGGradientElement::buildStops()
@@ -140,25 +120,13 @@ Vector<Gradient::ColorStop> SVGGradientElement::buildStops()
Vector<Gradient::ColorStop> stops;
float previousOffset = 0.0f;
- for (Node* n = firstChild(); n; n = n->nextSibling()) {
- SVGElement* element = n->isSVGElement() ? toSVGElement(n) : 0;
- if (!element || !element->isGradientStop())
- continue;
-
- SVGStopElement* stop = toSVGStopElement(element);
- Color color = stop->stopColorIncludingOpacity();
-
+ for (SVGStopElement* stop = Traversal<SVGStopElement>::firstChild(*this); stop; stop = Traversal<SVGStopElement>::nextSibling(*stop)) {
// Figure out right monotonic offset
- float offset = stop->offsetCurrentValue();
+ float offset = stop->offset()->currentValue()->value();
offset = std::min(std::max(previousOffset, offset), 1.0f);
previousOffset = offset;
- // Extract individual channel values
- // FIXME: Why doesn't ColorStop take a Color and an offset??
- float r, g, b, a;
- color.getRGBA(r, g, b, a);
-
- stops.append(Gradient::ColorStop(offset, r, g, b, a));
+ stops.append(Gradient::ColorStop(offset, stop->stopColorIncludingOpacity()));
}
return stops;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.h
index cb2c9162659..1dfe8ff287f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.h
@@ -21,12 +21,11 @@
#ifndef SVGGradientElement_h
#define SVGGradientElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedTransformList.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGURIReference.h"
#include "core/svg/SVGUnitTypes.h"
#include "platform/graphics/Gradient.h"
@@ -39,43 +38,10 @@ enum SVGSpreadMethodType {
SVGSpreadMethodReflect,
SVGSpreadMethodRepeat
};
-
-template<>
-struct SVGPropertyTraits<SVGSpreadMethodType> {
- static unsigned highestEnumValue() { return SVGSpreadMethodRepeat; }
-
- static String toString(SVGSpreadMethodType type)
- {
- switch (type) {
- case SVGSpreadMethodUnknown:
- return emptyString();
- case SVGSpreadMethodPad:
- return "pad";
- case SVGSpreadMethodReflect:
- return "reflect";
- case SVGSpreadMethodRepeat:
- return "repeat";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static SVGSpreadMethodType fromString(const String& value)
- {
- if (value == "pad")
- return SVGSpreadMethodPad;
- if (value == "reflect")
- return SVGSpreadMethodReflect;
- if (value == "repeat")
- return SVGSpreadMethodRepeat;
- return SVGSpreadMethodUnknown;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGSpreadMethodType>();
class SVGGradientElement : public SVGElement,
- public SVGURIReference,
- public SVGExternalResourcesRequired {
+ public SVGURIReference {
public:
enum {
SVG_SPREADMETHOD_UNKNOWN = SVGSpreadMethodUnknown,
@@ -86,25 +52,25 @@ public:
Vector<Gradient::ColorStop> buildStops();
+ SVGAnimatedTransformList* gradientTransform() { return m_gradientTransform.get(); }
+ SVGAnimatedEnumeration<SVGSpreadMethodType>* spreadMethod() { return m_spreadMethod.get(); }
+ SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* gradientUnits() { return m_gradientUnits.get(); }
+
protected:
SVGGradientElement(const QualifiedName&, Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
private:
- virtual bool needsPendingResourceHandling() const { return false; }
+ virtual bool needsPendingResourceHandling() const OVERRIDE FINAL { return false; }
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE FINAL;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGradientElement)
- DECLARE_ANIMATED_ENUMERATION(SpreadMethod, spreadMethod, SVGSpreadMethodType)
- DECLARE_ANIMATED_ENUMERATION(GradientUnits, gradientUnits, SVGUnitTypes::SVGUnitType)
- DECLARE_ANIMATED_TRANSFORM_LIST(GradientTransform, gradientTransform)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedTransformList> m_gradientTransform;
+ RefPtr<SVGAnimatedEnumeration<SVGSpreadMethodType> > m_spreadMethod;
+ RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_gradientUnits;
};
inline bool isSVGGradientElement(const Node& node)
@@ -112,7 +78,7 @@ inline bool isSVGGradientElement(const Node& node)
return node.hasTagName(SVGNames::radialGradientTag) || node.hasTagName(SVGNames::linearGradientTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGGradientElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGGradientElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.idl
index cc2f00bfef4..ff2e0489c96 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGradientElement.idl
@@ -37,6 +37,5 @@
readonly attribute SVGAnimatedEnumeration spreadMethod;
};
-SVGGradientElement implements SVGExternalResourcesRequired;
SVGGradientElement implements SVGURIReference;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp
index 95bb0c2cd87..70b6e2d259b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -22,68 +23,79 @@
#include "core/svg/SVGGraphicsElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/svg/RenderSVGPath.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/SVGPathData.h"
-#include "core/svg/SVGElementInstance.h"
#include "platform/transforms/AffineTransform.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_TRANSFORM_LIST(SVGGraphicsElement, SVGNames::transformAttr, Transform, transform)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGraphicsElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(transform)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
-END_REGISTER_ANIMATED_PROPERTIES
-
SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, Document& document, ConstructionType constructionType)
: SVGElement(tagName, document, constructionType)
+ , SVGTests(this)
+ , m_transform(SVGAnimatedTransformList::create(this, SVGNames::transformAttr, SVGTransformList::create()))
{
- registerAnimatedPropertiesForSVGGraphicsElement();
+ addToPropertyMap(m_transform);
}
SVGGraphicsElement::~SVGGraphicsElement()
{
}
-AffineTransform SVGGraphicsElement::getTransformToElement(SVGElement* target, ExceptionState& exceptionState)
+PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getTransformToElement(SVGElement* target, ExceptionState& exceptionState)
{
AffineTransform ctm = getCTM(AllowStyleUpdate);
if (target && target->isSVGGraphicsElement()) {
AffineTransform targetCTM = toSVGGraphicsElement(target)->getCTM(AllowStyleUpdate);
if (!targetCTM.isInvertible()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
- return ctm;
+ exceptionState.throwDOMException(InvalidStateError, "The target transformation is not invertable.");
+ return nullptr;
}
ctm = targetCTM.inverse() * ctm;
}
- return ctm;
+ return SVGMatrixTearOff::create(ctm);
}
-static AffineTransform computeCTM(SVGGraphicsElement* element, SVGElement::CTMScope mode, SVGGraphicsElement::StyleUpdateStrategy styleUpdateStrategy)
+static bool isViewportElement(const Element& element)
{
- ASSERT(element);
- if (styleUpdateStrategy == SVGGraphicsElement::AllowStyleUpdate)
- element->document().updateLayoutIgnorePendingStylesheets();
+ return (isSVGSVGElement(element)
+ || isSVGSymbolElement(element)
+ || isSVGForeignObjectElement(element)
+ || isSVGImageElement(element));
+}
+
+AffineTransform SVGGraphicsElement::computeCTM(SVGElement::CTMScope mode,
+ SVGGraphicsElement::StyleUpdateStrategy styleUpdateStrategy, const SVGGraphicsElement* ancestor) const
+{
+ if (styleUpdateStrategy == AllowStyleUpdate)
+ document().updateLayoutIgnorePendingStylesheets();
AffineTransform ctm;
+ bool done = false;
- SVGElement* stopAtElement = mode == SVGGraphicsElement::NearestViewportScope ? element->nearestViewportElement() : 0;
- for (Element* currentElement = element; currentElement; currentElement = currentElement->parentOrShadowHostElement()) {
+ for (const Element* currentElement = this; currentElement && !done;
+ currentElement = currentElement->parentOrShadowHostElement()) {
if (!currentElement->isSVGElement())
break;
ctm = toSVGElement(currentElement)->localCoordinateSpaceTransform(mode).multiply(ctm);
- // For getCTM() computation, stop at the nearest viewport element
- if (currentElement == stopAtElement)
+ switch (mode) {
+ case NearestViewportScope:
+ // Stop at the nearest viewport ancestor.
+ done = currentElement != this && isViewportElement(*currentElement);
+ break;
+ case AncestorScope:
+ // Stop at the designated ancestor.
+ done = currentElement == ancestor;
break;
+ default:
+ ASSERT(mode == ScreenScope);
+ break;
+ }
}
return ctm;
@@ -91,12 +103,22 @@ static AffineTransform computeCTM(SVGGraphicsElement* element, SVGElement::CTMSc
AffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrategy)
{
- return computeCTM(this, NearestViewportScope, styleUpdateStrategy);
+ return computeCTM(NearestViewportScope, styleUpdateStrategy);
}
AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy)
{
- return computeCTM(this, ScreenScope, styleUpdateStrategy);
+ return computeCTM(ScreenScope, styleUpdateStrategy);
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getCTMFromJavascript()
+{
+ return SVGMatrixTearOff::create(getCTM());
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getScreenCTMFromJavascript()
+{
+ return SVGMatrixTearOff::create(getScreenCTM());
}
AffineTransform SVGGraphicsElement::animatedLocalTransform() const
@@ -106,23 +128,31 @@ AffineTransform SVGGraphicsElement::animatedLocalTransform() const
// If CSS property was set, use that, otherwise fallback to attribute (if set).
if (style && style->hasTransform()) {
+ TransformationMatrix transform;
+ float zoom = style->effectiveZoom();
+
+ // CSS transforms operate with pre-scaled lengths. To make this work with SVG
+ // (which applies the zoom factor globally, at the root level) we
+ //
+ // * pre-scale the bounding box (to bring it into the same space as the other CSS values)
+ // * invert the zoom factor (to effectively compute the CSS transform under a 1.0 zoom)
+ //
// Note: objectBoundingBox is an emptyRect for elements like pattern or clipPath.
// See the "Object bounding box units" section of http://dev.w3.org/csswg/css3-transforms/
- TransformationMatrix transform;
- style->applyTransform(transform, renderer()->objectBoundingBox());
+ if (zoom != 1) {
+ FloatRect scaledBBox = renderer()->objectBoundingBox();
+ scaledBBox.scale(zoom);
+ transform.scale(1 / zoom);
+ style->applyTransform(transform, scaledBBox);
+ transform.scale(zoom);
+ } else {
+ style->applyTransform(transform, renderer()->objectBoundingBox());
+ }
// Flatten any 3D transform.
matrix = transform.toAffineTransform();
-
- // CSS bakes the zoom factor into lengths, including translation components.
- // In order to align CSS & SVG transforms, we need to invert this operation.
- float zoom = style->effectiveZoom();
- if (zoom != 1) {
- matrix.setE(matrix.e() / zoom);
- matrix.setF(matrix.f() / zoom);
- }
} else {
- transformCurrentValue().concatenate(matrix);
+ m_transform->currentValue()->concatenate(matrix);
}
if (m_supplementalTransform)
@@ -154,17 +184,16 @@ void SVGGraphicsElement::parseAttribute(const QualifiedName& name, const AtomicS
return;
}
- if (name == SVGNames::transformAttr) {
- SVGTransformList newList;
- newList.parse(value);
- detachAnimatedTransformListWrappers(newList.size());
- setTransformBaseValue(newList);
- return;
- } else if (SVGTests::parseAttribute(name, value)) {
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::transformAttr)
+ m_transform->setBaseValueAsString(value, parseError);
+ else if (SVGTests::parseAttribute(name, value))
return;
- }
+ else
+ ASSERT_NOT_REACHED();
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -174,7 +203,7 @@ void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
// Reattach so the isValid() check will be run again during renderer creation.
if (SVGTests::isKnownAttribute(attrName)) {
@@ -195,18 +224,10 @@ void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName)
ASSERT_NOT_REACHED();
}
-static bool isViewportElement(Node* node)
-{
- return (node->hasTagName(SVGNames::svgTag)
- || node->hasTagName(SVGNames::symbolTag)
- || node->hasTagName(SVGNames::foreignObjectTag)
- || node->hasTagName(SVGNames::imageTag));
-}
-
SVGElement* SVGGraphicsElement::nearestViewportElement() const
{
for (Element* current = parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) {
- if (isViewportElement(current))
+ if (isViewportElement(*current))
return toSVGElement(current);
}
@@ -217,32 +238,26 @@ SVGElement* SVGGraphicsElement::farthestViewportElement() const
{
SVGElement* farthest = 0;
for (Element* current = parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) {
- if (isViewportElement(current))
+ if (isViewportElement(*current))
farthest = toSVGElement(current);
}
return farthest;
}
-SVGRect SVGGraphicsElement::getBBox()
+FloatRect SVGGraphicsElement::getBBox()
{
document().updateLayoutIgnorePendingStylesheets();
// FIXME: Eventually we should support getBBox for detached elements.
if (!renderer())
- return SVGRect();
+ return FloatRect();
return renderer()->objectBoundingBox();
}
-SVGRect SVGGraphicsElement::getStrokeBBox()
+PassRefPtr<SVGRectTearOff> SVGGraphicsElement::getBBoxFromJavascript()
{
- document().updateLayoutIgnorePendingStylesheets();
-
- // FIXME: Eventually we should support getStrokeBBox for detached elements.
- if (!renderer())
- return SVGRect();
-
- return renderer()->strokeBoundingBox();
+ return SVGRectTearOff::create(SVGRect::create(getBBox()), 0, PropertyIsNotAnimVal);
}
RenderObject* SVGGraphicsElement::createRenderer(RenderStyle*)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.h
index 6bc8830c32f..619443b6043 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,12 +24,14 @@
#include "core/svg/SVGAnimatedTransformList.h"
#include "core/svg/SVGElement.h"
+#include "core/svg/SVGRectTearOff.h"
#include "core/svg/SVGTests.h"
namespace WebCore {
class AffineTransform;
class Path;
+class SVGMatrixTearOff;
class SVGGraphicsElement : public SVGElement, public SVGTests {
public:
@@ -38,39 +41,46 @@ public:
AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate);
AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate);
- AffineTransform getTransformToElement(SVGElement*, ExceptionState&);
+ PassRefPtr<SVGMatrixTearOff> getCTMFromJavascript();
+ PassRefPtr<SVGMatrixTearOff> getScreenCTMFromJavascript();
+
+ PassRefPtr<SVGMatrixTearOff> getTransformToElement(SVGElement*, ExceptionState&);
+
SVGElement* nearestViewportElement() const;
SVGElement* farthestViewportElement() const;
virtual AffineTransform localCoordinateSpaceTransform(SVGElement::CTMScope) const OVERRIDE { return animatedLocalTransform(); }
virtual AffineTransform animatedLocalTransform() const;
- virtual AffineTransform* supplementalTransform();
+ virtual AffineTransform* supplementalTransform() OVERRIDE;
- virtual SVGRect getBBox();
- SVGRect getStrokeBBox();
+ virtual FloatRect getBBox();
+ PassRefPtr<SVGRectTearOff> getBBoxFromJavascript();
// "base class" methods for all the elements which render as paths
virtual void toClipPath(Path&);
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+
+ virtual bool isValid() const OVERRIDE FINAL { return SVGTests::isValid(); }
+
+ SVGAnimatedTransformList* transform() { return m_transform.get(); }
+ const SVGAnimatedTransformList* transform() const { return m_transform.get(); }
+
+ AffineTransform computeCTM(SVGElement::CTMScope mode, SVGGraphicsElement::StyleUpdateStrategy,
+ const SVGGraphicsElement* ancestor = 0) const;
protected:
SVGGraphicsElement(const QualifiedName&, Document&, ConstructionType = CreateSVGElement);
+ virtual bool supportsFocus() const OVERRIDE { return Element::supportsFocus() || hasFocusEventListeners(); }
+
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGraphicsElement)
- DECLARE_ANIMATED_TRANSFORM_LIST(Transform, transform)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedTransformList> m_transform;
private:
- virtual bool isSVGGraphicsElement() const OVERRIDE { return true; }
-
- // SVGTests
- virtual void synchronizeRequiredFeatures() { SVGTests::synchronizeRequiredFeatures(this); }
- virtual void synchronizeRequiredExtensions() { SVGTests::synchronizeRequiredExtensions(this); }
- virtual void synchronizeSystemLanguage() { SVGTests::synchronizeSystemLanguage(this); }
+ virtual bool isSVGGraphicsElement() const OVERRIDE FINAL { return true; }
// Used by <animateMotion>
OwnPtr<AffineTransform> m_supplementalTransform;
@@ -81,7 +91,7 @@ inline bool isSVGGraphicsElement(const Node& node)
return node.isSVGElement() && toSVGElement(node).isSVGGraphicsElement();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGGraphicsElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGGraphicsElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.idl
index eed23aa1d2f..42410204e99 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGGraphicsElement.idl
@@ -28,17 +28,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGGraphicsElement : SVGElement {
+// http://www.w3.org/TR/SVG2/types.html#InterfaceSVGGraphicsElement
+
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGGraphicsElement : SVGElement {
readonly attribute SVGAnimatedTransformList transform;
[MeasureAs=SVGLocatableNearestViewportElement] readonly attribute SVGElement nearestViewportElement;
[MeasureAs=SVGLocatableFarthestViewportElement] readonly attribute SVGElement farthestViewportElement;
- SVGRect getBBox();
- SVGRect getStrokeBBox();
- SVGMatrix getCTM();
- SVGMatrix getScreenCTM();
- [RaisesException] SVGMatrix getTransformToElement([Default=Undefined] optional SVGElement element);
+ [ImplementedAs=getBBoxFromJavascript] SVGRect getBBox();
+ [ImplementedAs=getCTMFromJavascript] SVGMatrix getCTM();
+ [ImplementedAs=getScreenCTMFromJavascript] SVGMatrix getScreenCTM();
+ [RaisesException] SVGMatrix getTransformToElement(SVGElement element);
};
SVGGraphicsElement implements SVGTests;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.cpp
index cfd9229fdb8..5ef358b0280 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.cpp
@@ -33,16 +33,13 @@ inline SVGHKernElement::SVGHKernElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGHKernElement> SVGHKernElement::create(Document& document)
-{
- return adoptRef(new SVGHKernElement(document));
-}
+DEFINE_NODE_FACTORY(SVGHKernElement)
Node::InsertionNotificationRequest SVGHKernElement::insertedInto(ContainerNode* rootParent)
{
ContainerNode* fontNode = parentNode();
- if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
- toSVGFontElement(fontNode)->invalidateGlyphCache();
+ if (isSVGFontElement(fontNode))
+ toSVGFontElement(*fontNode).invalidateGlyphCache();
return SVGElement::insertedInto(rootParent);
}
@@ -50,8 +47,8 @@ Node::InsertionNotificationRequest SVGHKernElement::insertedInto(ContainerNode*
void SVGHKernElement::removedFrom(ContainerNode* rootParent)
{
ContainerNode* fontNode = parentNode();
- if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
- toSVGFontElement(fontNode)->invalidateGlyphCache();
+ if (isSVGFontElement(fontNode))
+ toSVGFontElement(*fontNode).invalidateGlyphCache();
SVGElement::removedFrom(rootParent);
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.h
index d54d89d701a..7f71d18e0fd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGHKernElement.h
@@ -23,14 +23,14 @@
#define SVGHKernElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGFontElement.h"
namespace WebCore {
class SVGHKernElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGHKernElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGHKernElement);
void buildHorizontalKerningPair(KerningPairVector&);
@@ -40,11 +40,9 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
};
-DEFINE_NODE_TYPE_CASTS(SVGHKernElement, hasTagName(SVGNames::hkernTag));
-
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
index 72e3008be73..ed66be15ddd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.cpp
@@ -23,50 +23,40 @@
#include "core/svg/SVGImageElement.h"
-#include "CSSPropertyNames.h"
-#include "XLinkNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/XLinkNames.h"
#include "core/rendering/RenderImageResource.h"
#include "core/rendering/svg/RenderSVGImage.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGImageElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGImageElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGImageElement, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGImageElement, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGImageElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
-DEFINE_ANIMATED_STRING(SVGImageElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGImageElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGImageElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(preserveAspectRatio)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGImageElement::SVGImageElement(Document& document)
: SVGGraphicsElement(SVGNames::imageTag, document)
- , m_x(LengthModeWidth)
- , m_y(LengthModeHeight)
- , m_width(LengthModeWidth)
- , m_height(LengthModeHeight)
- , m_imageLoader(this)
+ , SVGURIReference(this)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
+ , m_preserveAspectRatio(SVGAnimatedPreserveAspectRatio::create(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()))
+ , m_imageLoader(SVGImageLoader::create(this))
+ , m_needsLoaderURIUpdate(true)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGImageElement();
+
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
+ addToPropertyMap(m_preserveAspectRatio);
}
-PassRefPtr<SVGImageElement> SVGImageElement::create(Document& document)
+DEFINE_NODE_FACTORY(SVGImageElement)
+
+void SVGImageElement::trace(Visitor* visitor)
{
- return adoptRef(new SVGImageElement(document));
+ visitor->trace(m_imageLoader);
+ SVGGraphicsElement::trace(visitor);
}
bool SVGImageElement::currentFrameHasSingleSecurityOrigin() const
@@ -85,7 +75,6 @@ bool SVGImageElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
SVGURIReference::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::xAttr);
supportedAttributes.add(SVGNames::yAttr);
@@ -117,24 +106,22 @@ void SVGImageElement::parseAttribute(const QualifiedName& name, const AtomicStri
{
SVGParsingError parseError = NoError;
- if (!isSupportedAttribute(name))
+ if (!isSupportedAttribute(name)) {
SVGGraphicsElement::parseAttribute(name, value);
- else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
- else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (name == SVGNames::preserveAspectRatioAttr) {
- SVGPreserveAspectRatio preserveAspectRatio;
- preserveAspectRatio.parse(value);
- setPreserveAspectRatioBaseValue(preserveAspectRatio);
- } else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
- else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
- else if (SVGExternalResourcesRequired::parseAttribute(name, value)
- || SVGURIReference::parseAttribute(name, value)) {
- } else
+ } else if (name == SVGNames::xAttr) {
+ m_x->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::yAttr) {
+ m_y->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::widthAttr) {
+ m_width->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::heightAttr) {
+ m_height->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::preserveAspectRatioAttr) {
+ m_preserveAspectRatio->setBaseValueAsString(value, parseError);
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else {
ASSERT_NOT_REACHED();
+ }
reportAttributeParsingError(parseError, name, value);
}
@@ -146,7 +133,7 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
bool isLengthAttribute = attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
@@ -157,7 +144,10 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
updateRelativeLengthsInformation();
if (SVGURIReference::isKnownAttribute(attrName)) {
- m_imageLoader.updateFromElementIgnoringPreviousError();
+ if (inDocument())
+ imageLoader().updateFromElementIgnoringPreviousError();
+ else
+ m_needsLoaderURIUpdate = true;
return;
}
@@ -171,8 +161,7 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- if (attrName == SVGNames::preserveAspectRatioAttr
- || SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
+ if (attrName == SVGNames::preserveAspectRatioAttr) {
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
@@ -182,10 +171,10 @@ void SVGImageElement::svgAttributeChanged(const QualifiedName& attrName)
bool SVGImageElement::selfHasRelativeLengths() const
{
- return xCurrentValue().isRelative()
- || yCurrentValue().isRelative()
- || widthCurrentValue().isRelative()
- || heightCurrentValue().isRelative();
+ return m_x->currentValue()->isRelative()
+ || m_y->currentValue()->isRelative()
+ || m_width->currentValue()->isRelative()
+ || m_height->currentValue()->isRelative();
}
RenderObject* SVGImageElement::createRenderer(RenderStyle*)
@@ -195,7 +184,7 @@ RenderObject* SVGImageElement::createRenderer(RenderStyle*)
bool SVGImageElement::haveLoadedRequiredResources()
{
- return !externalResourcesRequiredBaseValue() || !m_imageLoader.hasPendingActivity();
+ return !m_needsLoaderURIUpdate && !imageLoader().hasPendingActivity();
}
void SVGImageElement::attach(const AttachContext& context)
@@ -206,7 +195,7 @@ void SVGImageElement::attach(const AttachContext& context)
if (imageObj->imageResource()->hasImage())
return;
- imageObj->imageResource()->setImageResource(m_imageLoader.image());
+ imageObj->imageResource()->setImageResource(imageLoader().image());
}
}
@@ -215,27 +204,30 @@ Node::InsertionNotificationRequest SVGImageElement::insertedInto(ContainerNode*
SVGGraphicsElement::insertedInto(rootParent);
if (!rootParent->inDocument())
return InsertionDone;
- // Update image loader, as soon as we're living in the tree.
- // We can only resolve base URIs properly, after that!
- m_imageLoader.updateFromElement();
+
+ // We can only resolve base URIs properly after tree insertion - hence, URI mutations while
+ // detached are deferred until this point.
+ if (m_needsLoaderURIUpdate) {
+ imageLoader().updateFromElementIgnoringPreviousError();
+ m_needsLoaderURIUpdate = false;
+ } else {
+ // A previous loader update may have failed to actually fetch the image if the document
+ // was inactive. In that case, force a re-update (but don't clear previous errors).
+ if (!imageLoader().image())
+ imageLoader().updateFromElement();
+ }
+
return InsertionDone;
}
const AtomicString SVGImageElement::imageSourceURL() const
{
- return hrefCurrentValue();
-}
-
-void SVGImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- SVGGraphicsElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(hrefCurrentValue()));
+ return AtomicString(hrefString());
}
void SVGImageElement::didMoveToNewDocument(Document& oldDocument)
{
- m_imageLoader.elementDidMoveToNewDocument();
+ imageLoader().elementDidMoveToNewDocument();
SVGGraphicsElement::didMoveToNewDocument(oldDocument);
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.h
index 1270dc14204..d6943a7ba15 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.h
@@ -21,11 +21,10 @@
#ifndef SVGImageElement_h
#define SVGImageElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
#include "core/svg/SVGImageLoader.h"
#include "core/svg/SVGURIReference.h"
@@ -33,52 +32,52 @@
namespace WebCore {
class SVGImageElement FINAL : public SVGGraphicsElement,
- public SVGExternalResourcesRequired,
public SVGURIReference {
public:
- static PassRefPtr<SVGImageElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGImageElement);
+ virtual void trace(Visitor*) OVERRIDE;
bool currentFrameHasSingleSecurityOrigin() const;
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
+ SVGAnimatedPreserveAspectRatio* preserveAspectRatio() { return m_preserveAspectRatio.get(); }
+
private:
explicit SVGImageElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
+ virtual bool isStructurallyExternal() const OVERRIDE { return !hrefString().isNull(); }
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual const AtomicString imageSourceURL() const OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
- virtual bool haveLoadedRequiredResources();
+ virtual bool haveLoadedRequiredResources() OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
+ SVGImageLoader& imageLoader() { return *m_imageLoader; }
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGImageElement)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
-
- SVGImageLoader m_imageLoader;
-};
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
+ RefPtr<SVGAnimatedPreserveAspectRatio> m_preserveAspectRatio;
-DEFINE_NODE_TYPE_CASTS(SVGImageElement, hasTagName(SVGNames::imageTag));
+ OwnPtrWillBeMember<SVGImageLoader> m_imageLoader;
+ bool m_needsLoaderURIUpdate : 1;
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.idl
index a2bc7b0eab4..a659e29a06b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGImageElement.idl
@@ -31,6 +31,5 @@ interface SVGImageElement : SVGGraphicsElement {
readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
};
-SVGImageElement implements SVGExternalResourcesRequired;
SVGImageElement implements SVGURIReference;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp
index e889c61b149..af9d5b7587e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.cpp
@@ -23,7 +23,6 @@
#include "core/svg/SVGImageLoader.h"
#include "core/events/Event.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/fetch/ImageResource.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/svg/SVGImageElement.h"
@@ -41,17 +40,16 @@ void SVGImageLoader::dispatchLoadEvent()
element()->dispatchEvent(Event::create(EventTypeNames::error));
else {
SVGImageElement* imageElement = toSVGImageElement(element());
- if (imageElement->externalResourcesRequiredBaseValue())
- imageElement->sendSVGLoadEventIfPossible(true);
+ imageElement->sendSVGLoadEventIfPossible(true);
}
}
String SVGImageLoader::sourceURI(const AtomicString& attribute) const
{
KURL base = element()->baseURI();
- if (base.isValid())
- return KURL(base, stripLeadingAndTrailingHTMLSpaces(attribute)).string();
- return element()->document().completeURL(stripLeadingAndTrailingHTMLSpaces(attribute));
+ if (!base.isValid())
+ base = element()->document().baseURI();
+ return element()->document().completeURLWithOverride(stripLeadingAndTrailingHTMLSpaces(attribute), base);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.h b/chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.h
index 38842e3fee9..41687fe57b0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGImageLoader.h
@@ -26,13 +26,17 @@ namespace WebCore {
class SVGImageElement;
-class SVGImageLoader : public ImageLoader {
+class SVGImageLoader FINAL : public ImageLoader {
public:
- SVGImageLoader(SVGImageElement*);
+ static PassOwnPtrWillBeRawPtr<SVGImageLoader> create(SVGImageElement* element)
+ {
+ return adoptPtrWillBeNoop(new SVGImageLoader(element));
+ }
private:
- virtual void dispatchLoadEvent();
- virtual String sourceURI(const AtomicString&) const;
+ explicit SVGImageLoader(SVGImageElement*);
+ virtual void dispatchLoadEvent() OVERRIDE;
+ virtual String sourceURI(const AtomicString&) const OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGInteger.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGInteger.cpp
new file mode 100644
index 00000000000..2fc7e9a187a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGInteger.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGInteger.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+
+#include "core/svg/SVGAnimationElement.h"
+
+namespace WebCore {
+
+SVGInteger::SVGInteger(int value)
+ : SVGPropertyBase(classType())
+ , m_value(value)
+{
+}
+
+PassRefPtr<SVGInteger> SVGInteger::clone() const
+{
+ return create(m_value);
+}
+
+PassRefPtr<SVGPropertyBase> SVGInteger::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGInteger> svgInteger = create();
+ svgInteger->setValueAsString(value, IGNORE_EXCEPTION);
+ return svgInteger.release();
+}
+
+String SVGInteger::valueAsString() const
+{
+ return String::number(m_value);
+}
+
+void SVGInteger::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+ if (string.isEmpty()) {
+ m_value = 0;
+ return;
+ }
+
+ bool valid = true;
+ m_value = stripLeadingAndTrailingHTMLSpaces(string).toIntStrict(&valid);
+
+ if (!valid) {
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
+ m_value = 0;
+ }
+}
+
+void SVGInteger::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ setValue(m_value + toSVGInteger(other)->value());
+}
+
+void SVGInteger::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDuration, SVGElement*)
+{
+ ASSERT(animationElement);
+
+ RefPtr<SVGInteger> fromInteger = toSVGInteger(from);
+ RefPtr<SVGInteger> toInteger = toSVGInteger(to);
+ RefPtr<SVGInteger> toAtEndOfDurationInteger = toSVGInteger(toAtEndOfDuration);
+
+ float animatedFloat = m_value;
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromInteger->value(), toInteger->value(), toAtEndOfDurationInteger->value(), animatedFloat);
+ m_value = static_cast<int>(roundf(animatedFloat));
+}
+
+float SVGInteger::calculateDistance(PassRefPtr<SVGPropertyBase> other, SVGElement*)
+{
+ return abs(m_value - toSVGInteger(other)->value());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGInteger.h b/chromium/third_party/WebKit/Source/core/svg/SVGInteger.h
new file mode 100644
index 00000000000..bc1c7dd2b29
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGInteger.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGInteger_h
+#define SVGInteger_h
+
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/svg/properties/SVGProperty.h"
+
+namespace WebCore {
+
+class SVGInteger : public SVGPropertyBase {
+public:
+ typedef void TearOffType;
+ typedef int PrimitiveType;
+
+ static PassRefPtr<SVGInteger> create(int value = 0)
+ {
+ return adoptRef(new SVGInteger(value));
+ }
+
+ virtual PassRefPtr<SVGInteger> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+ int value() const { return m_value; }
+ void setValue(int value) { m_value = value; }
+
+ virtual String valueAsString() const OVERRIDE;
+ virtual void setValueAsString(const String&, ExceptionState&);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedInteger; }
+
+protected:
+ explicit SVGInteger(int);
+
+ int m_value;
+};
+
+inline PassRefPtr<SVGInteger> toSVGInteger(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGInteger::classType());
+ return static_pointer_cast<SVGInteger>(base.release());
+}
+
+} // namespace WebCore
+
+#endif // SVGInteger_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGIntegerOptionalInteger.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGIntegerOptionalInteger.cpp
new file mode 100644
index 00000000000..3e28442c51d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGIntegerOptionalInteger.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGIntegerOptionalInteger.h"
+
+#include "core/svg/SVGAnimationElement.h"
+#include "core/svg/SVGParserUtilities.h"
+
+namespace WebCore {
+
+SVGIntegerOptionalInteger::SVGIntegerOptionalInteger(PassRefPtr<SVGInteger> firstInteger, PassRefPtr<SVGInteger> secondInteger)
+ : SVGPropertyBase(classType())
+ , m_firstInteger(firstInteger)
+ , m_secondInteger(secondInteger)
+{
+}
+
+PassRefPtr<SVGIntegerOptionalInteger> SVGIntegerOptionalInteger::clone() const
+{
+ return SVGIntegerOptionalInteger::create(m_firstInteger->clone(), m_secondInteger->clone());
+}
+
+PassRefPtr<SVGPropertyBase> SVGIntegerOptionalInteger::cloneForAnimation(const String& value) const
+{
+ float floatX, floatY;
+ if (!parseNumberOptionalNumber(value, floatX, floatY)) {
+ return SVGIntegerOptionalInteger::create(SVGInteger::create(0), SVGInteger::create(0));
+ }
+
+ int x = static_cast<int>(roundf(floatX));
+ int y = static_cast<int>(roundf(floatY));
+
+ return SVGIntegerOptionalInteger::create(SVGInteger::create(x), SVGInteger::create(y));
+}
+
+String SVGIntegerOptionalInteger::valueAsString() const
+{
+ if (m_firstInteger->value() == m_secondInteger->value()) {
+ return String::number(m_firstInteger->value());
+ }
+
+ return String::number(m_firstInteger->value()) + " " + String::number(m_secondInteger->value());
+}
+
+void SVGIntegerOptionalInteger::setValueAsString(const String& value, ExceptionState& exceptionState)
+{
+ float x, y;
+ if (!parseNumberOptionalNumber(value, x, y)) {
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + value + "') is invalid.");
+ x = y = 0;
+ }
+
+ m_firstInteger->setValue(x);
+ m_secondInteger->setValue(y);
+}
+
+void SVGIntegerOptionalInteger::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ RefPtr<SVGIntegerOptionalInteger> otherIntegerOptionalInteger = toSVGIntegerOptionalInteger(other);
+
+ m_firstInteger->setValue(m_firstInteger->value() + otherIntegerOptionalInteger->m_firstInteger->value());
+ m_secondInteger->setValue(m_secondInteger->value() + otherIntegerOptionalInteger->m_secondInteger->value());
+}
+
+void SVGIntegerOptionalInteger::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDuration, SVGElement*)
+{
+ ASSERT(animationElement);
+
+ RefPtr<SVGIntegerOptionalInteger> fromInteger = toSVGIntegerOptionalInteger(from);
+ RefPtr<SVGIntegerOptionalInteger> toInteger = toSVGIntegerOptionalInteger(to);
+ RefPtr<SVGIntegerOptionalInteger> toAtEndOfDurationInteger = toSVGIntegerOptionalInteger(toAtEndOfDuration);
+
+ float x = m_firstInteger->value();
+ float y = m_secondInteger->value();
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromInteger->firstInteger()->value(), toInteger->firstInteger()->value(), toAtEndOfDurationInteger->firstInteger()->value(), x);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromInteger->secondInteger()->value(), toInteger->secondInteger()->value(), toAtEndOfDurationInteger->secondInteger()->value(), y);
+ m_firstInteger->setValue(static_cast<int>(roundf(x)));
+ m_secondInteger->setValue(static_cast<int>(roundf(y)));
+}
+
+float SVGIntegerOptionalInteger::calculateDistance(PassRefPtr<SVGPropertyBase> other, SVGElement*)
+{
+ // FIXME: Distance calculation is not possible for SVGIntegerOptionalInteger right now. We need the distance for every single value.
+ return -1;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGIntegerOptionalInteger.h b/chromium/third_party/WebKit/Source/core/svg/SVGIntegerOptionalInteger.h
new file mode 100644
index 00000000000..03519314d4b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGIntegerOptionalInteger.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGIntegerOptionalInteger_h
+#define SVGIntegerOptionalInteger_h
+
+#include "core/svg/SVGAnimatedInteger.h"
+
+namespace WebCore {
+
+class SVGIntegerOptionalInteger : public SVGPropertyBase {
+public:
+ // Tearoff of SVGIntegerOptionalInteger is never created.
+ typedef void TearOffType;
+ typedef void PrimitiveType;
+
+ static PassRefPtr<SVGIntegerOptionalInteger> create(PassRefPtr<SVGInteger> firstInteger, PassRefPtr<SVGInteger> secondInteger)
+ {
+ return adoptRef(new SVGIntegerOptionalInteger(firstInteger, secondInteger));
+ }
+
+ PassRefPtr<SVGIntegerOptionalInteger> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+ virtual String valueAsString() const OVERRIDE;
+ void setValueAsString(const String&, ExceptionState&);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedIntegerOptionalInteger; }
+
+ PassRefPtr<SVGInteger> firstInteger() { return m_firstInteger; }
+ PassRefPtr<SVGInteger> secondInteger() { return m_secondInteger; }
+
+protected:
+ SVGIntegerOptionalInteger(PassRefPtr<SVGInteger> firstInteger, PassRefPtr<SVGInteger> secondInteger);
+
+ RefPtr<SVGInteger> m_firstInteger;
+ RefPtr<SVGInteger> m_secondInteger;
+};
+
+inline PassRefPtr<SVGIntegerOptionalInteger> toSVGIntegerOptionalInteger(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGIntegerOptionalInteger::classType());
+ return static_pointer_cast<SVGIntegerOptionalInteger>(base.release());
+}
+
+} // namespace WebCore
+
+#endif // SVGIntegerOptionalInteger_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLength.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGLength.cpp
index b6a95967fea..b59cf57cda3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLength.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLength.cpp
@@ -23,47 +23,21 @@
#include "core/svg/SVGLength.h"
-#include "SVGNames.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/SVGNames.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
#include "core/svg/SVGParserUtilities.h"
+#include "platform/animation/AnimationUtilities.h"
#include "wtf/MathExtras.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-static inline SVGLengthMode toSVGLengthMode(unsigned short mode)
-{
- ASSERT(mode >= LengthModeWidth && mode <= LengthModeOther);
- return static_cast<SVGLengthMode>(mode);
-}
-
-static inline SVGLengthType toSVGLengthType(unsigned short type)
-{
- ASSERT(type >= LengthTypeUnknown && type <= LengthTypePC);
- return static_cast<SVGLengthType>(type);
-}
-
-static inline unsigned int storeUnit(SVGLengthMode mode, SVGLengthType type)
-{
- return (mode << 4) | type;
-}
-
-static inline SVGLengthMode extractMode(unsigned int unit)
-{
- unsigned int mode = unit >> 4;
- return toSVGLengthMode(mode);
-}
+namespace {
-static inline SVGLengthType extractType(unsigned int unit)
-{
- unsigned int mode = unit >> 4;
- unsigned int type = unit ^ (mode << 4);
- return toSVGLengthType(type);
-}
-
-static inline String lengthTypeToString(SVGLengthType type)
+inline String lengthTypeToString(SVGLengthType type)
{
switch (type) {
case LengthTypeUnknown:
@@ -94,134 +68,125 @@ static inline String lengthTypeToString(SVGLengthType type)
}
template<typename CharType>
-static SVGLengthType stringToLengthType(const CharType*& ptr, const CharType* end)
+SVGLengthType stringToLengthType(const CharType*& ptr, const CharType* end)
{
if (ptr == end)
return LengthTypeNumber;
- const UChar firstChar = *ptr;
-
- if (++ptr == end)
- return firstChar == '%' ? LengthTypePercentage : LengthTypeUnknown;
-
- const UChar secondChar = *ptr;
-
- if (++ptr != end)
- return LengthTypeUnknown;
-
- if (firstChar == 'e' && secondChar == 'm')
- return LengthTypeEMS;
- if (firstChar == 'e' && secondChar == 'x')
- return LengthTypeEXS;
- if (firstChar == 'p' && secondChar == 'x')
- return LengthTypePX;
- if (firstChar == 'c' && secondChar == 'm')
- return LengthTypeCM;
- if (firstChar == 'm' && secondChar == 'm')
- return LengthTypeMM;
- if (firstChar == 'i' && secondChar == 'n')
- return LengthTypeIN;
- if (firstChar == 'p' && secondChar == 't')
- return LengthTypePT;
- if (firstChar == 'p' && secondChar == 'c')
- return LengthTypePC;
+ SVGLengthType type = LengthTypeUnknown;
+ const CharType firstChar = *ptr++;
+
+ if (firstChar == '%') {
+ type = LengthTypePercentage;
+ } else if (isHTMLSpace<CharType>(firstChar)) {
+ type = LengthTypeNumber;
+ } else if (ptr < end) {
+ const CharType secondChar = *ptr++;
+
+ if (firstChar == 'p') {
+ if (secondChar == 'x')
+ type = LengthTypePX;
+ if (secondChar == 't')
+ type = LengthTypePT;
+ if (secondChar == 'c')
+ type = LengthTypePC;
+ } else if (firstChar == 'e') {
+ if (secondChar == 'm')
+ type = LengthTypeEMS;
+ if (secondChar == 'x')
+ type = LengthTypeEXS;
+ } else if (firstChar == 'c' && secondChar == 'm') {
+ type = LengthTypeCM;
+ } else if (firstChar == 'm' && secondChar == 'm') {
+ type = LengthTypeMM;
+ } else if (firstChar == 'i' && secondChar == 'n') {
+ type = LengthTypeIN;
+ } else if (isHTMLSpace<CharType>(firstChar) && isHTMLSpace<CharType>(secondChar)) {
+ type = LengthTypeNumber;
+ }
+ }
+
+ if (!skipOptionalSVGSpaces(ptr, end))
+ return type;
return LengthTypeUnknown;
}
-SVGLength::SVGLength(SVGLengthMode mode, const String& valueAsString)
- : m_valueInSpecifiedUnits(0)
- , m_unit(storeUnit(mode, LengthTypeNumber))
-{
- setValueAsString(valueAsString, IGNORE_EXCEPTION);
-}
+} // namespace
-SVGLength::SVGLength(const SVGLengthContext& context, float value, SVGLengthMode mode, SVGLengthType unitType)
- : m_valueInSpecifiedUnits(0)
- , m_unit(storeUnit(mode, unitType))
+SVGLength::SVGLength(SVGLengthMode mode)
+ : SVGPropertyBase(classType())
+ , m_valueInSpecifiedUnits(0)
+ , m_unitMode(mode)
+ , m_unitType(LengthTypeNumber)
{
- setValue(value, context, ASSERT_NO_EXCEPTION);
}
-SVGLength::SVGLength(const SVGLength& other)
- : m_valueInSpecifiedUnits(other.m_valueInSpecifiedUnits)
- , m_unit(other.m_unit)
+SVGLength::SVGLength(const SVGLength& o)
+ : SVGPropertyBase(classType())
+ , m_valueInSpecifiedUnits(o.m_valueInSpecifiedUnits)
+ , m_unitMode(o.m_unitMode)
+ , m_unitType(o.m_unitType)
{
}
-void SVGLength::setValueAsString(const String& valueAsString, SVGLengthMode mode, ExceptionState& exceptionState)
+PassRefPtr<SVGLength> SVGLength::clone() const
{
- m_valueInSpecifiedUnits = 0;
- m_unit = storeUnit(mode, LengthTypeNumber);
- setValueAsString(valueAsString, exceptionState);
+ return adoptRef(new SVGLength(*this));
}
-bool SVGLength::operator==(const SVGLength& other) const
+PassRefPtr<SVGPropertyBase> SVGLength::cloneForAnimation(const String& value) const
{
- return m_unit == other.m_unit
- && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits;
-}
+ RefPtr<SVGLength> length = create();
-bool SVGLength::operator!=(const SVGLength& other) const
-{
- return !operator==(other);
-}
+ length->m_unitMode = m_unitMode;
+ length->m_unitType = m_unitType;
-SVGLength SVGLength::construct(SVGLengthMode mode, const String& valueAsString, SVGParsingError& parseError, SVGLengthNegativeValuesMode negativeValuesMode)
-{
TrackExceptionState exceptionState;
- SVGLength length(mode);
-
- length.setValueAsString(valueAsString, exceptionState);
-
- if (exceptionState.hadException())
- parseError = ParsingAttributeFailedError;
- else if (negativeValuesMode == ForbidNegativeLengths && length.valueInSpecifiedUnits() < 0)
- parseError = NegativeValueForbiddenError;
+ length->setValueAsString(value, exceptionState);
+ if (exceptionState.hadException()) {
+ length->m_unitType = LengthTypeNumber;
+ length->m_valueInSpecifiedUnits = 0;
+ }
- return length;
+ return length.release();
}
-SVGLengthType SVGLength::unitType() const
+bool SVGLength::operator==(const SVGLength& other) const
{
- return extractType(m_unit);
+ return m_unitMode == other.m_unitMode
+ && m_unitType == other.m_unitType
+ && m_valueInSpecifiedUnits == other.m_valueInSpecifiedUnits;
}
-SVGLengthMode SVGLength::unitMode() const
+float SVGLength::value(const SVGLengthContext& context, ExceptionState& es) const
{
- return extractMode(m_unit);
+ return context.convertValueToUserUnits(m_valueInSpecifiedUnits, unitMode(), unitType(), es);
}
-float SVGLength::value(const SVGLengthContext& context) const
+void SVGLength::setValue(float value, const SVGLengthContext& context, ExceptionState& es)
{
- return value(context, IGNORE_EXCEPTION);
-}
+ // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed
+ if (m_unitType == LengthTypePercentage)
+ value = value / 100;
-float SVGLength::value(const SVGLengthContext& context, ExceptionState& exceptionState) const
-{
- return context.convertValueToUserUnits(m_valueInSpecifiedUnits, extractMode(m_unit), extractType(m_unit), exceptionState);
-}
+ float convertedValue = context.convertValueFromUserUnits(value, unitMode(), unitType(), es);
+ if (es.hadException())
+ return;
-void SVGLength::setValue(const SVGLengthContext& context, float value, SVGLengthMode mode, SVGLengthType unitType, ExceptionState& exceptionState)
-{
- m_unit = storeUnit(mode, unitType);
- setValue(value, context, exceptionState);
+ m_valueInSpecifiedUnits = convertedValue;
}
-void SVGLength::setValue(float value, const SVGLengthContext& context, ExceptionState& exceptionState)
+void SVGLength::setUnitType(SVGLengthType type)
{
- // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed
- if (extractType(m_unit) == LengthTypePercentage)
- value = value / 100;
-
- float convertedValue = context.convertValueFromUserUnits(value, extractMode(m_unit), extractType(m_unit), exceptionState);
- if (!exceptionState.hadException())
- m_valueInSpecifiedUnits = convertedValue;
+ ASSERT(type != LengthTypeUnknown && type <= LengthTypePC);
+ m_unitType = type;
}
+
float SVGLength::valueAsPercentage() const
{
// 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed
- if (extractType(m_unit) == LengthTypePercentage)
+ if (m_unitType == LengthTypePercentage)
return m_valueInSpecifiedUnits / 100;
return m_valueInSpecifiedUnits;
@@ -233,7 +198,7 @@ static bool parseValueInternal(const String& string, float& convertedNumber, SVG
const CharType* ptr = string.getCharacters<CharType>();
const CharType* end = ptr + string.length();
- if (!parseNumber(ptr, end, convertedNumber, false))
+ if (!parseNumber(ptr, end, convertedNumber, AllowLeadingWhitespace))
return false;
type = stringToLengthType(ptr, end);
@@ -246,8 +211,11 @@ static bool parseValueInternal(const String& string, float& convertedNumber, SVG
void SVGLength::setValueAsString(const String& string, ExceptionState& exceptionState)
{
- if (string.isEmpty())
+ if (string.isEmpty()) {
+ m_unitType = LengthTypeNumber;
+ m_valueInSpecifiedUnits = 0;
return;
+ }
float convertedNumber = 0;
SVGLengthType type = LengthTypeUnknown;
@@ -257,52 +225,44 @@ void SVGLength::setValueAsString(const String& string, ExceptionState& exception
parseValueInternal<UChar>(string, convertedNumber, type);
if (!success) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
return;
}
- m_unit = storeUnit(extractMode(m_unit), type);
+ m_unitType = type;
m_valueInSpecifiedUnits = convertedNumber;
}
String SVGLength::valueAsString() const
{
- return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(extractType(m_unit));
+ return String::number(m_valueInSpecifiedUnits) + lengthTypeToString(unitType());
}
-void SVGLength::newValueSpecifiedUnits(unsigned short type, float value, ExceptionState& exceptionState)
+void SVGLength::newValueSpecifiedUnits(SVGLengthType type, float value)
{
- if (type == LengthTypeUnknown || type > LengthTypePC) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
-
- m_unit = storeUnit(extractMode(m_unit), toSVGLengthType(type));
+ setUnitType(type);
m_valueInSpecifiedUnits = value;
}
-void SVGLength::convertToSpecifiedUnits(unsigned short type, const SVGLengthContext& context, ExceptionState& exceptionState)
+void SVGLength::convertToSpecifiedUnits(SVGLengthType type, const SVGLengthContext& context, ExceptionState& exceptionState)
{
- if (type == LengthTypeUnknown || type > LengthTypePC) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
+ ASSERT(type != LengthTypeUnknown && type <= LengthTypePC);
float valueInUserUnits = value(context, exceptionState);
if (exceptionState.hadException())
return;
- unsigned int originalUnitAndType = m_unit;
- m_unit = storeUnit(extractMode(m_unit), toSVGLengthType(type));
+ SVGLengthType originalType = unitType();
+ m_unitType = type;
setValue(valueInUserUnits, context, exceptionState);
if (!exceptionState.hadException())
return;
// Eventually restore old unit and type
- m_unit = originalUnitAndType;
+ m_unitType = originalType;
}
-SVGLength SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value)
+PassRefPtr<SVGLength> SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value)
{
ASSERT(value);
@@ -345,21 +305,19 @@ SVGLength SVGLength::fromCSSPrimitiveValue(CSSPrimitiveValue* value)
};
if (svgType == LengthTypeUnknown)
- return SVGLength();
+ return SVGLength::create();
- TrackExceptionState exceptionState;
- SVGLength length;
- length.newValueSpecifiedUnits(svgType, value->getFloatValue(), exceptionState);
- if (exceptionState.hadException())
- return SVGLength();
-
- return length;
+ RefPtr<SVGLength> length = SVGLength::create();
+ length->newValueSpecifiedUnits(svgType, value->getFloatValue());
+ return length.release();
}
-PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(const SVGLength& length)
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(PassRefPtr<SVGLength> passLength)
{
- CSSPrimitiveValue::UnitTypes cssType = CSSPrimitiveValue::CSS_UNKNOWN;
- switch (length.unitType()) {
+ RefPtr<SVGLength> length = passLength;
+
+ CSSPrimitiveValue::UnitType cssType = CSSPrimitiveValue::CSS_UNKNOWN;
+ switch (length->unitType()) {
case LengthTypeUnknown:
break;
case LengthTypeNumber:
@@ -394,7 +352,7 @@ PassRefPtr<CSSPrimitiveValue> SVGLength::toCSSPrimitiveValue(const SVGLength& le
break;
};
- return CSSPrimitiveValue::create(length.valueInSpecifiedUnits(), cssType);
+ return CSSPrimitiveValue::create(length->valueInSpecifiedUnits(), cssType);
}
SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedName& attrName)
@@ -412,6 +370,8 @@ SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedNam
s_lengthModeMap.set(SVGNames::fxAttr, LengthModeWidth);
s_lengthModeMap.set(SVGNames::fyAttr, LengthModeHeight);
s_lengthModeMap.set(SVGNames::rAttr, LengthModeOther);
+ s_lengthModeMap.set(SVGNames::rxAttr, LengthModeWidth);
+ s_lengthModeMap.set(SVGNames::ryAttr, LengthModeHeight);
s_lengthModeMap.set(SVGNames::widthAttr, LengthModeWidth);
s_lengthModeMap.set(SVGNames::heightAttr, LengthModeHeight);
s_lengthModeMap.set(SVGNames::x1Attr, LengthModeWidth);
@@ -432,4 +392,85 @@ SVGLengthMode SVGLength::lengthModeForAnimatedLengthAttribute(const QualifiedNam
return LengthModeOther;
}
+PassRefPtr<SVGLength> SVGLength::blend(PassRefPtr<SVGLength> passFrom, float progress) const
+{
+ RefPtr<SVGLength> from = passFrom;
+
+ SVGLengthType toType = unitType();
+ SVGLengthType fromType = from->unitType();
+ if ((from->isZero() && isZero())
+ || fromType == LengthTypeUnknown
+ || toType == LengthTypeUnknown
+ || (!from->isZero() && fromType != LengthTypePercentage && toType == LengthTypePercentage)
+ || (!isZero() && fromType == LengthTypePercentage && toType != LengthTypePercentage)
+ || (!from->isZero() && !isZero() && (fromType == LengthTypeEMS || fromType == LengthTypeEXS) && fromType != toType))
+ return clone();
+
+ RefPtr<SVGLength> length = create();
+
+ if (fromType == LengthTypePercentage || toType == LengthTypePercentage) {
+ float fromPercent = from->valueAsPercentage() * 100;
+ float toPercent = valueAsPercentage() * 100;
+ length->newValueSpecifiedUnits(LengthTypePercentage, WebCore::blend(fromPercent, toPercent, progress));
+ return length;
+ }
+
+ if (fromType == toType || from->isZero() || isZero() || fromType == LengthTypeEMS || fromType == LengthTypeEXS) {
+ float fromValue = from->valueInSpecifiedUnits();
+ float toValue = valueInSpecifiedUnits();
+ if (isZero())
+ length->newValueSpecifiedUnits(fromType, WebCore::blend(fromValue, toValue, progress));
+ else
+ length->newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress));
+ return length;
+ }
+
+ ASSERT(!isRelative());
+ ASSERT(!from->isRelative());
+
+ TrackExceptionState es;
+ SVGLengthContext nonRelativeLengthContext(0);
+ float fromValueInUserUnits = nonRelativeLengthContext.convertValueToUserUnits(from->valueInSpecifiedUnits(), from->unitMode(), fromType, es);
+ if (es.hadException())
+ return create();
+
+ float fromValue = nonRelativeLengthContext.convertValueFromUserUnits(fromValueInUserUnits, unitMode(), toType, es);
+ if (es.hadException())
+ return create();
+
+ float toValue = valueInSpecifiedUnits();
+ length->newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress));
+ return length;
+}
+
+void SVGLength::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement* contextElement)
+{
+ SVGLengthContext lengthContext(contextElement);
+
+ setValue(value(lengthContext) + toSVGLength(other)->value(lengthContext), lengthContext, ASSERT_NO_EXCEPTION);
+}
+
+void SVGLength::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+{
+ RefPtr<SVGLength> fromLength = toSVGLength(fromValue);
+ RefPtr<SVGLength> toLength = toSVGLength(toValue);
+ RefPtr<SVGLength> toAtEndOfDurationLength = toSVGLength(toAtEndOfDurationValue);
+
+ SVGLengthContext lengthContext(contextElement);
+ float animatedNumber = value(lengthContext, IGNORE_EXCEPTION);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromLength->value(lengthContext, IGNORE_EXCEPTION), toLength->value(lengthContext, IGNORE_EXCEPTION), toAtEndOfDurationLength->value(lengthContext, IGNORE_EXCEPTION), animatedNumber);
+
+ ASSERT(unitMode() == lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
+ m_unitType = percentage < 0.5 ? fromLength->unitType() : toLength->unitType();
+ setValue(animatedNumber, lengthContext, ASSERT_NO_EXCEPTION);
+}
+
+float SVGLength::calculateDistance(PassRefPtr<SVGPropertyBase> toValue, SVGElement* contextElement)
+{
+ SVGLengthContext lengthContext(contextElement);
+ RefPtr<SVGLength> toLength = toSVGLength(toValue);
+
+ return fabsf(toLength->value(lengthContext, IGNORE_EXCEPTION) - value(lengthContext, IGNORE_EXCEPTION));
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLength.h b/chromium/third_party/WebKit/Source/core/svg/SVGLength.h
index 31310509b1b..742dbe1f5d7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLength.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLength.h
@@ -21,11 +21,11 @@
#ifndef SVGLength_h
#define SVGLength_h
-#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/svg/SVGLengthContext.h"
-#include "core/svg/SVGParsingError.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "platform/animation/AnimationUtilities.h"
+#include "core/svg/properties/SVGProperty.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
@@ -38,58 +38,51 @@ enum SVGLengthNegativeValuesMode {
ForbidNegativeLengths
};
-class SVGLength {
- WTF_MAKE_FAST_ALLOCATED;
+class SVGLengthTearOff;
+
+class SVGLength FINAL : public SVGPropertyBase {
public:
- // Forward declare these enums in the w3c naming scheme, for IDL generation
- enum {
- SVG_LENGTHTYPE_UNKNOWN = LengthTypeUnknown,
- SVG_LENGTHTYPE_NUMBER = LengthTypeNumber,
- SVG_LENGTHTYPE_PERCENTAGE = LengthTypePercentage,
- SVG_LENGTHTYPE_EMS = LengthTypeEMS,
- SVG_LENGTHTYPE_EXS = LengthTypeEXS,
- SVG_LENGTHTYPE_PX = LengthTypePX,
- SVG_LENGTHTYPE_CM = LengthTypeCM,
- SVG_LENGTHTYPE_MM = LengthTypeMM,
- SVG_LENGTHTYPE_IN = LengthTypeIN,
- SVG_LENGTHTYPE_PT = LengthTypePT,
- SVG_LENGTHTYPE_PC = LengthTypePC
- };
-
- SVGLength(SVGLengthMode = LengthModeOther, const String& valueAsString = String());
- SVGLength(const SVGLengthContext&, float, SVGLengthMode = LengthModeOther, SVGLengthType = LengthTypeNumber);
- SVGLength(const SVGLength&);
+ typedef SVGLengthTearOff TearOffType;
- SVGLengthType unitType() const;
- SVGLengthMode unitMode() const;
+ static PassRefPtr<SVGLength> create(SVGLengthMode mode = LengthModeOther)
+ {
+ return adoptRef(new SVGLength(mode));
+ }
- bool operator==(const SVGLength&) const;
- bool operator!=(const SVGLength&) const;
+ PassRefPtr<SVGLength> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
- static SVGLength construct(SVGLengthMode, const String&, SVGParsingError&, SVGLengthNegativeValuesMode = AllowNegativeLengths);
+ SVGLengthType unitType() const { return static_cast<SVGLengthType>(m_unitType); }
+ void setUnitType(SVGLengthType);
+ SVGLengthMode unitMode() const { return static_cast<SVGLengthMode>(m_unitMode); }
- float value(const SVGLengthContext&) const;
+ bool operator==(const SVGLength&) const;
+ bool operator!=(const SVGLength& other) const { return !operator==(other); }
+
+ float value(const SVGLengthContext& context) const
+ {
+ return value(context, IGNORE_EXCEPTION);
+ }
float value(const SVGLengthContext&, ExceptionState&) const;
void setValue(float, const SVGLengthContext&, ExceptionState&);
- void setValue(const SVGLengthContext&, float, SVGLengthMode, SVGLengthType, ExceptionState&);
float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; }
void setValueInSpecifiedUnits(float value) { m_valueInSpecifiedUnits = value; }
float valueAsPercentage() const;
- String valueAsString() const;
+ virtual String valueAsString() const OVERRIDE;
void setValueAsString(const String&, ExceptionState&);
- void setValueAsString(const String&, SVGLengthMode, ExceptionState&);
- void newValueSpecifiedUnits(unsigned short, float valueInSpecifiedUnits, ExceptionState&);
- void convertToSpecifiedUnits(unsigned short, const SVGLengthContext&, ExceptionState&);
+ void newValueSpecifiedUnits(SVGLengthType, float valueInSpecifiedUnits);
+ void convertToSpecifiedUnits(SVGLengthType, const SVGLengthContext&, ExceptionState&);
// Helper functions
inline bool isRelative() const
{
- SVGLengthType type = unitType();
- return type == LengthTypePercentage || type == LengthTypeEMS || type == LengthTypeEXS;
+ return m_unitType == LengthTypePercentage
+ || m_unitType == LengthTypeEMS
+ || m_unitType == LengthTypeEXS;
}
bool isZero() const
@@ -97,77 +90,33 @@ public:
return !m_valueInSpecifiedUnits;
}
- static SVGLength fromCSSPrimitiveValue(CSSPrimitiveValue*);
- static PassRefPtr<CSSPrimitiveValue> toCSSPrimitiveValue(const SVGLength&);
+ static PassRefPtr<SVGLength> fromCSSPrimitiveValue(CSSPrimitiveValue*);
+ static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> toCSSPrimitiveValue(PassRefPtr<SVGLength>);
static SVGLengthMode lengthModeForAnimatedLengthAttribute(const QualifiedName&);
- SVGLength blend(const SVGLength& from, float progress) const
- {
- SVGLengthType toType = unitType();
- SVGLengthType fromType = from.unitType();
- if ((from.isZero() && isZero())
- || fromType == LengthTypeUnknown
- || toType == LengthTypeUnknown
- || (!from.isZero() && fromType != LengthTypePercentage && toType == LengthTypePercentage)
- || (!isZero() && fromType == LengthTypePercentage && toType != LengthTypePercentage)
- || (!from.isZero() && !isZero() && (fromType == LengthTypeEMS || fromType == LengthTypeEXS) && fromType != toType))
- return *this;
-
- SVGLength length;
- TrackExceptionState exceptionState;
-
- if (fromType == LengthTypePercentage || toType == LengthTypePercentage) {
- float fromPercent = from.valueAsPercentage() * 100;
- float toPercent = valueAsPercentage() * 100;
- length.newValueSpecifiedUnits(LengthTypePercentage, WebCore::blend(fromPercent, toPercent, progress), exceptionState);
- if (exceptionState.hadException())
- return SVGLength();
- return length;
- }
-
- if (fromType == toType || from.isZero() || isZero() || fromType == LengthTypeEMS || fromType == LengthTypeEXS) {
- float fromValue = from.valueInSpecifiedUnits();
- float toValue = valueInSpecifiedUnits();
- if (isZero())
- length.newValueSpecifiedUnits(fromType, WebCore::blend(fromValue, toValue, progress), exceptionState);
- else
- length.newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress), exceptionState);
- if (exceptionState.hadException())
- return SVGLength();
- return length;
- }
-
- ASSERT(!isRelative());
- ASSERT(!from.isRelative());
-
- SVGLengthContext nonRelativeLengthContext(0);
- float fromValueInUserUnits = nonRelativeLengthContext.convertValueToUserUnits(from.valueInSpecifiedUnits(), from.unitMode(), fromType, exceptionState);
- if (exceptionState.hadException())
- return SVGLength();
-
- float fromValue = nonRelativeLengthContext.convertValueFromUserUnits(fromValueInUserUnits, unitMode(), toType, exceptionState);
- if (exceptionState.hadException())
- return SVGLength();
-
- float toValue = valueInSpecifiedUnits();
- length.newValueSpecifiedUnits(toType, WebCore::blend(fromValue, toValue, progress), exceptionState);
-
- if (exceptionState.hadException())
- return SVGLength();
- return length;
- }
+ PassRefPtr<SVGLength> blend(PassRefPtr<SVGLength> from, float progress) const;
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedLength; }
private:
- float m_valueInSpecifiedUnits;
- unsigned int m_unit;
-};
+ SVGLength(SVGLengthMode);
+ SVGLength(const SVGLength&);
-template<>
-struct SVGPropertyTraits<SVGLength> {
- static SVGLength initialValue() { return SVGLength(); }
- static String toString(const SVGLength& type) { return type.valueAsString(); }
+ float m_valueInSpecifiedUnits;
+ unsigned m_unitMode : 2;
+ unsigned m_unitType : 4;
};
+inline PassRefPtr<SVGLength> toSVGLength(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGLength::classType());
+ return static_pointer_cast<SVGLength>(base.release());
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLength.idl b/chromium/third_party/WebKit/Source/core/svg/SVGLength.idl
index 4d29af7ffa4..1774912c61f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLength.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLength.idl
@@ -20,7 +20,11 @@
* Boston, MA 02110-1301, USA.
*/
-interface SVGLength {
+[
+ ImplementedAs=SVGLengthTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGLength {
// Length Unit Types
const unsigned short SVG_LENGTHTYPE_UNKNOWN = 0;
const unsigned short SVG_LENGTHTYPE_NUMBER = 1;
@@ -35,14 +39,13 @@ interface SVGLength {
const unsigned short SVG_LENGTHTYPE_PC = 10;
readonly attribute unsigned short unitType;
- [Custom, StrictTypeChecking, RaisesException] attribute float value;
+ [RaisesException] attribute float value;
- [StrictTypeChecking] attribute float valueInSpecifiedUnits;
- [TreatNullAs=NullString, StrictTypeChecking, RaisesException=Setter] attribute DOMString valueAsString;
+ [RaisesException=Setter] attribute float valueInSpecifiedUnits;
+ [TreatNullAs=NullString, RaisesException=Setter] attribute DOMString valueAsString;
- [StrictTypeChecking, RaisesException] void newValueSpecifiedUnits(unsigned short unitType,
- float valueInSpecifiedUnits);
+ [RaisesException] void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits);
- [Custom, StrictTypeChecking, RaisesException] void convertToSpecifiedUnits(unsigned short unitType);
+ [RaisesException] void convertToSpecifiedUnits(unsigned short unitType);
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
index 7fed6c20b7a..5fc56b94af8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.cpp
@@ -23,8 +23,9 @@
#include "config.h"
#include "core/svg/SVGLengthContext.h"
-#include "SVGNames.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/SVGNames.h"
#include "core/css/CSSHelper.h"
#include "core/dom/ExceptionCode.h"
#include "core/rendering/RenderPart.h"
@@ -47,43 +48,54 @@ SVGLengthContext::SVGLengthContext(const SVGElement* context, const FloatRect& v
{
}
-FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport, const SVGLength& x, const SVGLength& y, const SVGLength& width, const SVGLength& height)
+FloatRect SVGLengthContext::resolveRectangle(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport, PassRefPtr<SVGLength> passX, PassRefPtr<SVGLength> passY, PassRefPtr<SVGLength> passWidth, PassRefPtr<SVGLength> passHeight)
{
+ RefPtr<SVGLength> x = passX;
+ RefPtr<SVGLength> y = passY;
+ RefPtr<SVGLength> width = passWidth;
+ RefPtr<SVGLength> height = passHeight;
+
ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN);
if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
SVGLengthContext lengthContext(context);
- return FloatRect(x.value(lengthContext), y.value(lengthContext), width.value(lengthContext), height.value(lengthContext));
+ return FloatRect(x->value(lengthContext), y->value(lengthContext), width->value(lengthContext), height->value(lengthContext));
}
SVGLengthContext lengthContext(context, viewport);
- return FloatRect(x.value(lengthContext) + viewport.x(),
- y.value(lengthContext) + viewport.y(),
- width.value(lengthContext),
- height.value(lengthContext));
+ return FloatRect(
+ x->value(lengthContext) + viewport.x(),
+ y->value(lengthContext) + viewport.y(),
+ width->value(lengthContext),
+ height->value(lengthContext));
}
-FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLength& x, const SVGLength& y)
+FloatPoint SVGLengthContext::resolvePoint(const SVGElement* context, SVGUnitTypes::SVGUnitType type, PassRefPtr<SVGLength> passX, PassRefPtr<SVGLength> passY)
{
+ RefPtr<SVGLength> x = passX;
+ RefPtr<SVGLength> y = passY;
+
ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN);
if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
SVGLengthContext lengthContext(context);
- return FloatPoint(x.value(lengthContext), y.value(lengthContext));
+ return FloatPoint(x->value(lengthContext), y->value(lengthContext));
}
// FIXME: valueAsPercentage() won't be correct for eg. cm units. They need to be resolved in user space and then be considered in objectBoundingBox space.
- return FloatPoint(x.valueAsPercentage(), y.valueAsPercentage());
+ return FloatPoint(x->valueAsPercentage(), y->valueAsPercentage());
}
-float SVGLengthContext::resolveLength(const SVGElement* context, SVGUnitTypes::SVGUnitType type, const SVGLength& x)
+float SVGLengthContext::resolveLength(const SVGElement* context, SVGUnitTypes::SVGUnitType type, PassRefPtr<SVGLength> passX)
{
+ RefPtr<SVGLength> x = passX;
+
ASSERT(type != SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN);
if (type == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
SVGLengthContext lengthContext(context);
- return x.value(lengthContext);
+ return x->value(lengthContext);
}
// FIXME: valueAsPercentage() won't be correct for eg. cm units. They need to be resolved in user space and then be considered in objectBoundingBox space.
- return x.valueAsPercentage();
+ return x->valueAsPercentage();
}
float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, SVGLengthType fromUnit, ExceptionState& exceptionState) const
@@ -98,7 +110,7 @@ float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode,
switch (fromUnit) {
case LengthTypeUnknown:
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(3, "SVGLengthType"));
return 0;
case LengthTypeNumber:
return value;
@@ -130,7 +142,7 @@ float SVGLengthContext::convertValueFromUserUnits(float value, SVGLengthMode mod
{
switch (toUnit) {
case LengthTypeUnknown:
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(3, "SVGLengthType"));
return 0;
case LengthTypeNumber:
return value;
@@ -162,7 +174,7 @@ float SVGLengthContext::convertValueFromUserUnitsToPercentage(float value, SVGLe
{
FloatSize viewportSize;
if (!determineViewport(viewportSize)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "The viewport could not be determined.");
return 0;
}
@@ -183,7 +195,7 @@ float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLe
{
FloatSize viewportSize;
if (!determineViewport(viewportSize)) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "The viewport could not be determined.");
return 0;
}
@@ -206,11 +218,11 @@ static inline RenderStyle* renderStyleForLengthResolving(const SVGElement* conte
return 0;
const ContainerNode* currentContext = context;
- while (currentContext) {
+ do {
if (currentContext->renderer())
return currentContext->renderer()->style();
currentContext = currentContext->parentNode();
- }
+ } while (currentContext);
// There must be at least a RenderSVGRoot renderer, carrying a style.
ASSERT_NOT_REACHED();
@@ -221,13 +233,13 @@ float SVGLengthContext::convertValueFromUserUnitsToEMS(float value, ExceptionSta
{
RenderStyle* style = renderStyleForLengthResolving(m_context);
if (!style) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "No context could be found.");
return 0;
}
float fontSize = style->specifiedFontSize();
if (!fontSize) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "No font-size could be determined.");
return 0;
}
@@ -238,7 +250,7 @@ float SVGLengthContext::convertValueFromEMSToUserUnits(float value, ExceptionSta
{
RenderStyle* style = renderStyleForLengthResolving(m_context);
if (!style) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "No context could be found.");
return 0;
}
@@ -249,7 +261,7 @@ float SVGLengthContext::convertValueFromUserUnitsToEXS(float value, ExceptionSta
{
RenderStyle* style = renderStyleForLengthResolving(m_context);
if (!style) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "No context could be found.");
return 0;
}
@@ -257,7 +269,7 @@ float SVGLengthContext::convertValueFromUserUnitsToEXS(float value, ExceptionSta
// if this causes problems in real world cases maybe it would be best to remove this
float xHeight = ceilf(style->fontMetrics().xHeight());
if (!xHeight) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "No x-height could be determined.");
return 0;
}
@@ -268,7 +280,7 @@ float SVGLengthContext::convertValueFromEXSToUserUnits(float value, ExceptionSta
{
RenderStyle* style = renderStyleForLengthResolving(m_context);
if (!style) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
+ exceptionState.throwDOMException(NotSupportedError, "No context could be found.");
return 0;
}
@@ -296,13 +308,13 @@ bool SVGLengthContext::determineViewport(FloatSize& viewportSize) const
// Take size from nearest viewport element.
SVGElement* viewportElement = m_context->viewportElement();
- if (!viewportElement || !viewportElement->isSVGSVGElement())
+ if (!isSVGSVGElement(viewportElement))
return false;
- const SVGSVGElement* svg = toSVGSVGElement(viewportElement);
- viewportSize = svg->currentViewBoxRect().size();
+ const SVGSVGElement& svg = toSVGSVGElement(*viewportElement);
+ viewportSize = svg.currentViewBoxRect().size();
if (viewportSize.isEmpty())
- viewportSize = svg->currentViewportSize();
+ viewportSize = svg.currentViewportSize();
return true;
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.h b/chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.h
index 64c237040c1..6050207663f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLengthContext.h
@@ -50,18 +50,19 @@ enum SVGLengthMode {
};
class SVGLengthContext {
+ STACK_ALLOCATED();
public:
explicit SVGLengthContext(const SVGElement*);
template<typename T>
static FloatRect resolveRectangle(const T* context, SVGUnitTypes::SVGUnitType type, const FloatRect& viewport)
{
- return SVGLengthContext::resolveRectangle(context, type, viewport, context->xCurrentValue(), context->yCurrentValue(), context->widthCurrentValue(), context->heightCurrentValue());
+ return SVGLengthContext::resolveRectangle(context, type, viewport, context->x()->currentValue(), context->y()->currentValue(), context->width()->currentValue(), context->height()->currentValue());
}
- static FloatRect resolveRectangle(const SVGElement*, SVGUnitTypes::SVGUnitType, const FloatRect& viewport, const SVGLength& x, const SVGLength& y, const SVGLength& width, const SVGLength& height);
- static FloatPoint resolvePoint(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLength& x, const SVGLength& y);
- static float resolveLength(const SVGElement*, SVGUnitTypes::SVGUnitType, const SVGLength&);
+ static FloatRect resolveRectangle(const SVGElement*, SVGUnitTypes::SVGUnitType, const FloatRect& viewport, PassRefPtr<SVGLength> x, PassRefPtr<SVGLength> y, PassRefPtr<SVGLength> width, PassRefPtr<SVGLength> height);
+ static FloatPoint resolvePoint(const SVGElement*, SVGUnitTypes::SVGUnitType, PassRefPtr<SVGLength> x, PassRefPtr<SVGLength> y);
+ static float resolveLength(const SVGElement*, SVGUnitTypes::SVGUnitType, PassRefPtr<SVGLength>);
float convertValueToUserUnits(float, SVGLengthMode, SVGLengthType fromUnit, ExceptionState&) const;
float convertValueFromUserUnits(float, SVGLengthMode, SVGLengthType toUnit, ExceptionState&) const;
@@ -80,7 +81,7 @@ private:
float convertValueFromUserUnitsToEXS(float value, ExceptionState&) const;
float convertValueFromEXSToUserUnits(float value, ExceptionState&) const;
- const SVGElement* m_context;
+ RawPtrWillBeMember<const SVGElement> m_context;
FloatRect m_overridenViewport;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.cpp
index 1518d2c924a..49721564ec3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.cpp
@@ -21,29 +21,78 @@
#include "config.h"
#include "core/svg/SVGLengthList.h"
-#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/svg/SVGAnimationElement.h"
#include "core/svg/SVGParserUtilities.h"
#include "wtf/text/StringBuilder.h"
namespace WebCore {
-template<typename CharType>
-void SVGLengthList::parseInternal(const CharType*& ptr, const CharType* end, SVGLengthMode mode)
+inline PassRefPtr<SVGLengthList> toSVGLengthList(PassRefPtr<SVGPropertyBase> passBase)
{
- TrackExceptionState exceptionState;
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGLengthList::classType());
+ return static_pointer_cast<SVGLengthList>(base.release());
+}
+
+SVGLengthList::SVGLengthList(SVGLengthMode mode)
+ : m_mode(mode)
+{
+}
+
+SVGLengthList::~SVGLengthList()
+{
+}
+PassRefPtr<SVGLengthList> SVGLengthList::clone()
+{
+ RefPtr<SVGLengthList> ret = SVGLengthList::create(m_mode);
+ ret->deepCopy(this);
+ return ret.release();
+}
+
+PassRefPtr<SVGPropertyBase> SVGLengthList::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGLengthList> ret = SVGLengthList::create(m_mode);
+ ret->setValueAsString(value, IGNORE_EXCEPTION);
+ return ret.release();
+}
+
+String SVGLengthList::valueAsString() const
+{
+ StringBuilder builder;
+
+ ConstIterator it = begin();
+ ConstIterator itEnd = end();
+ if (it != itEnd) {
+ builder.append(it->valueAsString());
+ ++it;
+
+ for (; it != itEnd; ++it) {
+ builder.append(' ');
+ builder.append(it->valueAsString());
+ }
+ }
+
+ return builder.toString();
+}
+
+template <typename CharType>
+void SVGLengthList::parseInternal(const CharType*& ptr, const CharType* end, ExceptionState& exceptionState)
+{
+ clear();
while (ptr < end) {
const CharType* start = ptr;
- while (ptr < end && *ptr != ',' && !isSVGSpace(*ptr))
+ while (ptr < end && *ptr != ',' && !isHTMLSpace<CharType>(*ptr))
ptr++;
if (ptr == start)
break;
- SVGLength length(mode);
+ RefPtr<SVGLength> length = SVGLength::create(m_mode);
String valueString(start, ptr - start);
if (valueString.isEmpty())
return;
- length.setValueAsString(valueString, exceptionState);
+ length->setValueAsString(valueString, exceptionState);
if (exceptionState.hadException())
return;
append(length);
@@ -51,35 +100,105 @@ void SVGLengthList::parseInternal(const CharType*& ptr, const CharType* end, SVG
}
}
-void SVGLengthList::parse(const String& value, SVGLengthMode mode)
+void SVGLengthList::setValueAsString(const String& value, ExceptionState& exceptionState)
{
- clear();
- if (value.isEmpty())
+ if (value.isEmpty()) {
+ clear();
return;
+ }
if (value.is8Bit()) {
const LChar* ptr = value.characters8();
const LChar* end = ptr + value.length();
- parseInternal(ptr, end, mode);
+ parseInternal(ptr, end, exceptionState);
} else {
const UChar* ptr = value.characters16();
const UChar* end = ptr + value.length();
- parseInternal(ptr, end, mode);
+ parseInternal(ptr, end, exceptionState);
}
}
-String SVGLengthList::valueAsString() const
+void SVGLengthList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement* contextElement)
{
- StringBuilder builder;
+ RefPtr<SVGLengthList> otherList = toSVGLengthList(other);
- unsigned size = this->size();
- for (unsigned i = 0; i < size; ++i) {
- if (i > 0)
- builder.append(' ');
+ if (length() != otherList->length())
+ return;
+
+ SVGLengthContext lengthContext(contextElement);
+ for (size_t i = 0; i < length(); ++i)
+ at(i)->setValue(at(i)->value(lengthContext) + otherList->at(i)->value(lengthContext), lengthContext, ASSERT_NO_EXCEPTION);
+}
- builder.append(at(i).valueAsString());
+bool SVGLengthList::adjustFromToListValues(PassRefPtr<SVGLengthList> passFromList, PassRefPtr<SVGLengthList> passToList, float percentage, bool isToAnimation, bool resizeAnimatedListIfNeeded)
+{
+ RefPtr<SVGLengthList> fromList = passFromList;
+ RefPtr<SVGLengthList> toList = passToList;
+
+ // If no 'to' value is given, nothing to animate.
+ size_t toListSize = toList->length();
+ if (!toListSize)
+ return false;
+
+ // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
+ size_t fromListSize = fromList->length();
+ if (fromListSize != toListSize && fromListSize) {
+ if (percentage < 0.5) {
+ if (!isToAnimation)
+ deepCopy(fromList);
+ } else {
+ deepCopy(toList);
+ }
+
+ return false;
}
- return builder.toString();
+ ASSERT(!fromListSize || fromListSize == toListSize);
+ if (resizeAnimatedListIfNeeded && length() < toListSize) {
+ size_t paddingCount = toListSize - length();
+ for (size_t i = 0; i < paddingCount; ++i)
+ append(SVGLength::create(m_mode));
+ }
+
+ return true;
}
+void SVGLengthList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+{
+ RefPtr<SVGLengthList> fromList = toSVGLengthList(fromValue);
+ RefPtr<SVGLengthList> toList = toSVGLengthList(toValue);
+ RefPtr<SVGLengthList> toAtEndOfDurationList = toSVGLengthList(toAtEndOfDurationValue);
+
+ SVGLengthContext lengthContext(contextElement);
+ ASSERT(m_mode == SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
+
+ size_t fromLengthListSize = fromList->length();
+ size_t toLengthListSize = toList->length();
+ size_t toAtEndOfDurationListSize = toAtEndOfDurationList->length();
+
+ if (!adjustFromToListValues(fromList, toList, percentage, animationElement->animationMode() == ToAnimation, true))
+ return;
+
+ for (size_t i = 0; i < toLengthListSize; ++i) {
+ float animatedNumber = at(i)->value(lengthContext);
+ SVGLengthType unitType = toList->at(i)->unitType();
+ float effectiveFrom = 0;
+ if (fromLengthListSize) {
+ if (percentage < 0.5)
+ unitType = fromList->at(i)->unitType();
+ effectiveFrom = fromList->at(i)->value(lengthContext);
+ }
+ float effectiveTo = toList->at(i)->value(lengthContext);
+ float effectiveToAtEnd = i < toAtEndOfDurationListSize ? toAtEndOfDurationList->at(i)->value(lengthContext) : 0;
+
+ animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, effectiveTo, effectiveToAtEnd, animatedNumber);
+ at(i)->setUnitType(unitType);
+ at(i)->setValue(animatedNumber, lengthContext, ASSERT_NO_EXCEPTION);
+ }
+}
+
+float SVGLengthList::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*)
+{
+ // FIXME: Distance calculation is not possible for SVGLengthList right now. We need the distance for every single value.
+ return -1;
+}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.h b/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.h
index 12afeed2f3a..5334e6e804c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.h
@@ -1,51 +1,80 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGLengthList_h
#define SVGLengthList_h
+#include "bindings/v8/ScriptWrappable.h"
#include "core/svg/SVGLength.h"
-#include "wtf/Vector.h"
+#include "core/svg/properties/SVGListPropertyHelper.h"
namespace WebCore {
-class SVGLengthList : public Vector<SVGLength> {
+class SVGLengthListTearOff;
+
+class SVGLengthList FINAL : public SVGListPropertyHelper<SVGLengthList, SVGLength> {
public:
- SVGLengthList() { }
+ typedef SVGLengthListTearOff TearOffType;
+
+ static PassRefPtr<SVGLengthList> create(SVGLengthMode mode = LengthModeOther)
+ {
+ return adoptRef(new SVGLengthList(mode));
+ }
+
+ virtual ~SVGLengthList();
+
+ PassRefPtr<SVGLengthList> clone();
+
+ void setValueAsString(const String&, ExceptionState&);
- void parse(const String& value, SVGLengthMode);
- String valueAsString() const;
+ // SVGPropertyBase:
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+ virtual String valueAsString() const OVERRIDE;
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedLengthList; }
private:
- template<typename CharType>
- void parseInternal(const CharType*& ptr, const CharType* end, SVGLengthMode);
-};
+ explicit SVGLengthList(SVGLengthMode);
+
+ bool adjustFromToListValues(PassRefPtr<SVGLengthList> fromList, PassRefPtr<SVGLengthList> toList, float percentage, bool isToAnimation, bool resizeAnimatedListIfNeeded);
-template<>
-struct SVGPropertyTraits<SVGLengthList> {
- typedef SVGLength ListItemType;
+ template <typename CharType>
+ void parseInternal(const CharType*& ptr, const CharType* end, ExceptionState&);
- static SVGLengthList initialValue() { return SVGLengthList(); }
- static String toString(const SVGLengthList& type) { return type.valueAsString(); }
+ SVGLengthMode m_mode;
};
} // namespace WebCore
-#endif
+#endif // SVGLengthList_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.idl
index 4149ab61eb9..23c8719c684 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLengthList.idl
@@ -24,15 +24,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGLengthList {
- readonly attribute unsigned long numberOfItems;
+[
+ ImplementedAs=SVGLengthListTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGLengthList {
+ readonly attribute unsigned long length;
+ [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
[RaisesException] void clear();
- [StrictTypeChecking, RaisesException] SVGLength initialize(SVGLength item);
- [StrictTypeChecking, RaisesException] SVGLength getItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGLength insertItemBefore(SVGLength item, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGLength replaceItem(SVGLength item, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGLength removeItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGLength appendItem(SVGLength item);
+ [RaisesException] SVGLength initialize(SVGLength item);
+ [RaisesException] getter SVGLength getItem(unsigned long index);
+ [RaisesException] setter SVGLength (unsigned long index, SVGLength value);
+ [RaisesException] SVGLength insertItemBefore(SVGLength item, unsigned long index);
+ [RaisesException] SVGLength replaceItem(SVGLength item, unsigned long index);
+ [RaisesException] SVGLength removeItem(unsigned long index);
+ [RaisesException] SVGLength appendItem(SVGLength item);
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLengthListTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGLengthListTearOff.h
new file mode 100644
index 00000000000..d18532c36ca
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLengthListTearOff.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGLengthListTearOff_h
+#define SVGLengthListTearOff_h
+
+#include "core/svg/SVGLengthList.h"
+#include "core/svg/properties/SVGListPropertyTearOffHelper.h"
+
+namespace WebCore {
+
+class SVGLengthListTearOff FINAL :
+ public SVGListPropertyTearOffHelper<SVGLengthListTearOff, SVGLengthList>,
+ public ScriptWrappable {
+public:
+ static PassRefPtr<SVGLengthListTearOff> create(PassRefPtr<SVGLengthList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGLengthListTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+private:
+ SVGLengthListTearOff(PassRefPtr<SVGLengthList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ : SVGListPropertyTearOffHelper<SVGLengthListTearOff, SVGLengthList>(target, contextElement, propertyIsAnimVal, attributeName)
+ {
+ ScriptWrappable::init(this);
+ }
+};
+
+} // namespace WebCore
+
+#endif // SVGLengthListTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp
new file mode 100644
index 00000000000..4aff446ddeb
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGLengthTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+namespace {
+
+inline SVGLengthType toSVGLengthType(unsigned short type)
+{
+ ASSERT(type >= LengthTypeUnknown && type <= LengthTypePC);
+ return static_cast<SVGLengthType>(type);
+}
+
+} // namespace
+
+SVGLengthType SVGLengthTearOff::unitType()
+{
+ return target()->unitType();
+}
+
+SVGLengthMode SVGLengthTearOff::unitMode()
+{
+ return target()->unitMode();
+}
+
+float SVGLengthTearOff::value(ExceptionState& es)
+{
+ SVGLengthContext lengthContext(contextElement());
+ return target()->value(lengthContext, es);
+}
+
+void SVGLengthTearOff::setValue(float value, ExceptionState& es)
+{
+ if (isImmutable()) {
+ es.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ SVGLengthContext lengthContext(contextElement());
+ target()->setValue(value, lengthContext, es);
+ commitChange();
+}
+
+float SVGLengthTearOff::valueInSpecifiedUnits()
+{
+ return target()->valueInSpecifiedUnits();
+}
+
+void SVGLengthTearOff::setValueInSpecifiedUnits(float value, ExceptionState& es)
+{
+ if (isImmutable()) {
+ es.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+ target()->setValueInSpecifiedUnits(value);
+ commitChange();
+}
+
+String SVGLengthTearOff::valueAsString()
+{
+ return target()->valueAsString();
+}
+
+void SVGLengthTearOff::setValueAsString(const String& str, ExceptionState& es)
+{
+ if (isImmutable()) {
+ es.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setValueAsString(str, es);
+ commitChange();
+}
+
+void SVGLengthTearOff::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return;
+ }
+
+ if (unitType == LengthTypeUnknown || unitType > LengthTypePC) {
+ exceptionState.throwDOMException(NotSupportedError, "Cannot set value with unknown or invalid units (" + String::number(unitType) + ").");
+ return;
+ }
+
+ target()->newValueSpecifiedUnits(toSVGLengthType(unitType), valueInSpecifiedUnits);
+ commitChange();
+}
+
+void SVGLengthTearOff::convertToSpecifiedUnits(unsigned short unitType, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return;
+ }
+
+ if (unitType == LengthTypeUnknown || unitType > LengthTypePC) {
+ exceptionState.throwDOMException(NotSupportedError, "Cannot convert to unknown or invalid units (" + String::number(unitType) + ").");
+ return;
+ }
+
+ SVGLengthContext lengthContext(contextElement());
+ target()->convertToSpecifiedUnits(toSVGLengthType(unitType), lengthContext, exceptionState);
+ commitChange();
+}
+
+SVGLengthTearOff::SVGLengthTearOff(PassRefPtr<SVGLength> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ : SVGPropertyTearOff<SVGLength>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLengthTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGLengthTearOff.h
new file mode 100644
index 00000000000..5ef43e94c1e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLengthTearOff.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGLengthTearOff_h
+#define SVGLengthTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGLength.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGLengthTearOff FINAL : public SVGPropertyTearOff<SVGLength>, public ScriptWrappable {
+public:
+ // Forward declare these enums in the w3c naming scheme, for IDL generation
+ enum {
+ SVG_LENGTHTYPE_UNKNOWN = LengthTypeUnknown,
+ SVG_LENGTHTYPE_NUMBER = LengthTypeNumber,
+ SVG_LENGTHTYPE_PERCENTAGE = LengthTypePercentage,
+ SVG_LENGTHTYPE_EMS = LengthTypeEMS,
+ SVG_LENGTHTYPE_EXS = LengthTypeEXS,
+ SVG_LENGTHTYPE_PX = LengthTypePX,
+ SVG_LENGTHTYPE_CM = LengthTypeCM,
+ SVG_LENGTHTYPE_MM = LengthTypeMM,
+ SVG_LENGTHTYPE_IN = LengthTypeIN,
+ SVG_LENGTHTYPE_PT = LengthTypePT,
+ SVG_LENGTHTYPE_PC = LengthTypePC
+ };
+
+ static PassRefPtr<SVGLengthTearOff> create(PassRefPtr<SVGLength> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGLengthTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ SVGLengthType unitType();
+ SVGLengthMode unitMode();
+ float value(ExceptionState&);
+ void setValue(float value, ExceptionState&);
+ float valueInSpecifiedUnits();
+ void setValueInSpecifiedUnits(float value, ExceptionState&);
+ String valueAsString();
+ void setValueAsString(const String&, ExceptionState&);
+ void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState&);
+ void convertToSpecifiedUnits(unsigned short unitType, ExceptionState&);
+
+private:
+ SVGLengthTearOff(PassRefPtr<SVGLength>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName = QualifiedName::null());
+};
+
+} // namespace WebCore
+
+#endif // SVGLengthTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.cpp
index 05ffe1509e1..516723de6fe 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.cpp
@@ -23,48 +23,31 @@
#include "core/svg/SVGLineElement.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLength.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGLineElement, SVGNames::x1Attr, X1, x1)
-DEFINE_ANIMATED_LENGTH(SVGLineElement, SVGNames::y1Attr, Y1, y1)
-DEFINE_ANIMATED_LENGTH(SVGLineElement, SVGNames::x2Attr, X2, x2)
-DEFINE_ANIMATED_LENGTH(SVGLineElement, SVGNames::y2Attr, Y2, y2)
-DEFINE_ANIMATED_BOOLEAN(SVGLineElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGLineElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x2)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y2)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGLineElement::SVGLineElement(Document& document)
: SVGGeometryElement(SVGNames::lineTag, document)
- , m_x1(LengthModeWidth)
- , m_y1(LengthModeHeight)
- , m_x2(LengthModeWidth)
- , m_y2(LengthModeHeight)
+ , m_x1(SVGAnimatedLength::create(this, SVGNames::x1Attr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y1(SVGAnimatedLength::create(this, SVGNames::y1Attr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_x2(SVGAnimatedLength::create(this, SVGNames::x2Attr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y2(SVGAnimatedLength::create(this, SVGNames::y2Attr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGLineElement();
-}
-PassRefPtr<SVGLineElement> SVGLineElement::create(Document& document)
-{
- return adoptRef(new SVGLineElement(document));
+ addToPropertyMap(m_x1);
+ addToPropertyMap(m_y1);
+ addToPropertyMap(m_x2);
+ addToPropertyMap(m_y2);
}
+DEFINE_NODE_FACTORY(SVGLineElement)
+
bool SVGLineElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::x1Attr);
supportedAttributes.add(SVGNames::x2Attr);
supportedAttributes.add(SVGNames::y1Attr);
@@ -80,15 +63,14 @@ void SVGLineElement::parseAttribute(const QualifiedName& name, const AtomicStrin
if (!isSupportedAttribute(name))
SVGGeometryElement::parseAttribute(name, value);
else if (name == SVGNames::x1Attr)
- setX1BaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_x1->setBaseValueAsString(value, parseError);
else if (name == SVGNames::y1Attr)
- setY1BaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_y1->setBaseValueAsString(value, parseError);
else if (name == SVGNames::x2Attr)
- setX2BaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_x2->setBaseValueAsString(value, parseError);
else if (name == SVGNames::y2Attr)
- setY2BaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (SVGExternalResourcesRequired::parseAttribute(name, value)) {
- } else
+ m_y2->setBaseValueAsString(value, parseError);
+ else
ASSERT_NOT_REACHED();
reportAttributeParsingError(parseError, name, value);
@@ -101,7 +83,7 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
bool isLengthAttribute = attrName == SVGNames::x1Attr
|| attrName == SVGNames::y1Attr
@@ -121,20 +103,15 @@ void SVGLineElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
ASSERT_NOT_REACHED();
}
bool SVGLineElement::selfHasRelativeLengths() const
{
- return x1CurrentValue().isRelative()
- || y1CurrentValue().isRelative()
- || x2CurrentValue().isRelative()
- || y2CurrentValue().isRelative();
+ return m_x1->currentValue()->isRelative()
+ || m_y1->currentValue()->isRelative()
+ || m_x2->currentValue()->isRelative()
+ || m_y2->currentValue()->isRelative();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.h
index 68b961afa8d..16bec01c0b6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.h
@@ -21,44 +21,37 @@
#ifndef SVGLineElement_h
#define SVGLineElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGeometryElement.h"
namespace WebCore {
-class SVGLineElement FINAL : public SVGGeometryElement,
- public SVGExternalResourcesRequired {
+class SVGLineElement FINAL : public SVGGeometryElement {
public:
- static PassRefPtr<SVGLineElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGLineElement);
+
+ SVGAnimatedLength* x1() const { return m_x1.get(); }
+ SVGAnimatedLength* y1() const { return m_y1.get(); }
+ SVGAnimatedLength* x2() const { return m_x2.get(); }
+ SVGAnimatedLength* y2() const { return m_y2.get(); }
private:
explicit SVGLineElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual bool supportsMarkers() const { return true; }
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGLineElement)
- DECLARE_ANIMATED_LENGTH(X1, x1)
- DECLARE_ANIMATED_LENGTH(Y1, y1)
- DECLARE_ANIMATED_LENGTH(X2, x2)
- DECLARE_ANIMATED_LENGTH(Y2, y2)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_x1;
+ RefPtr<SVGAnimatedLength> m_y1;
+ RefPtr<SVGAnimatedLength> m_x2;
+ RefPtr<SVGAnimatedLength> m_y2;
};
-DEFINE_NODE_TYPE_CASTS(SVGLineElement, hasTagName(SVGNames::lineTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.idl
index a12e80b2cf7..5adea6ffa5f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLineElement.idl
@@ -30,5 +30,3 @@ interface SVGLineElement : SVGGeometryElement {
readonly attribute SVGAnimatedLength y2;
};
-SVGLineElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp
index 84cdebeab31..0fd03f93ed6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp
@@ -27,43 +27,31 @@
#include "core/rendering/svg/RenderSVGResourceLinearGradient.h"
#include "core/svg/LinearGradientAttributes.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLength.h"
#include "core/svg/SVGTransformList.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGLinearGradientElement, SVGNames::x1Attr, X1, x1)
-DEFINE_ANIMATED_LENGTH(SVGLinearGradientElement, SVGNames::y1Attr, Y1, y1)
-DEFINE_ANIMATED_LENGTH(SVGLinearGradientElement, SVGNames::x2Attr, X2, x2)
-DEFINE_ANIMATED_LENGTH(SVGLinearGradientElement, SVGNames::y2Attr, Y2, y2)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGLinearGradientElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y1)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x2)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y2)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGradientElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGLinearGradientElement::SVGLinearGradientElement(Document& document)
: SVGGradientElement(SVGNames::linearGradientTag, document)
- , m_x1(LengthModeWidth)
- , m_y1(LengthModeHeight)
- , m_x2(LengthModeWidth, "100%")
- , m_y2(LengthModeHeight)
+ , m_x1(SVGAnimatedLength::create(this, SVGNames::x1Attr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y1(SVGAnimatedLength::create(this, SVGNames::y1Attr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_x2(SVGAnimatedLength::create(this, SVGNames::x2Attr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y2(SVGAnimatedLength::create(this, SVGNames::y2Attr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
{
- // Spec: If the x2 attribute is not specified, the effect is as if a value of "100%" were specified.
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGLinearGradientElement();
-}
-PassRefPtr<SVGLinearGradientElement> SVGLinearGradientElement::create(Document& document)
-{
- return adoptRef(new SVGLinearGradientElement(document));
+ // Spec: If the x2 attribute is not specified, the effect is as if a value of "100%" were specified.
+ m_x2->setDefaultValueAsString("100%");
+
+ addToPropertyMap(m_x1);
+ addToPropertyMap(m_y1);
+ addToPropertyMap(m_x2);
+ addToPropertyMap(m_y2);
}
+DEFINE_NODE_FACTORY(SVGLinearGradientElement)
+
bool SVGLinearGradientElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
@@ -83,13 +71,13 @@ void SVGLinearGradientElement::parseAttribute(const QualifiedName& name, const A
if (!isSupportedAttribute(name))
SVGGradientElement::parseAttribute(name, value);
else if (name == SVGNames::x1Attr)
- setX1BaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_x1->setBaseValueAsString(value, parseError);
else if (name == SVGNames::y1Attr)
- setY1BaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_y1->setBaseValueAsString(value, parseError);
else if (name == SVGNames::x2Attr)
- setX2BaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_x2->setBaseValueAsString(value, parseError);
else if (name == SVGNames::y2Attr)
- setY2BaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_y2->setBaseValueAsString(value, parseError);
else
ASSERT_NOT_REACHED();
@@ -103,7 +91,7 @@ void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
updateRelativeLengthsInformation();
@@ -117,78 +105,84 @@ RenderObject* SVGLinearGradientElement::createRenderer(RenderStyle*)
return new RenderSVGResourceLinearGradient(this);
}
-bool SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttributes& attributes)
+static void setGradientAttributes(SVGGradientElement* element, LinearGradientAttributes& attributes, bool isLinear = true)
{
- HashSet<SVGGradientElement*> processedGradients;
+ if (!attributes.hasSpreadMethod() && element->spreadMethod()->isSpecified())
+ attributes.setSpreadMethod(element->spreadMethod()->currentValue()->enumValue());
- bool isLinear = true;
- SVGGradientElement* current = this;
-
- while (current) {
- if (!current->renderer())
- return false;
+ if (!attributes.hasGradientUnits() && element->gradientUnits()->isSpecified())
+ attributes.setGradientUnits(element->gradientUnits()->currentValue()->enumValue());
- if (!attributes.hasSpreadMethod() && current->hasAttribute(SVGNames::spreadMethodAttr))
- attributes.setSpreadMethod(current->spreadMethodCurrentValue());
+ if (!attributes.hasGradientTransform() && element->gradientTransform()->isSpecified()) {
+ AffineTransform transform;
+ element->gradientTransform()->currentValue()->concatenate(transform);
+ attributes.setGradientTransform(transform);
+ }
- if (!attributes.hasGradientUnits() && current->hasAttribute(SVGNames::gradientUnitsAttr))
- attributes.setGradientUnits(current->gradientUnitsCurrentValue());
+ if (!attributes.hasStops()) {
+ const Vector<Gradient::ColorStop>& stops(element->buildStops());
+ if (!stops.isEmpty())
+ attributes.setStops(stops);
+ }
- if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) {
- AffineTransform transform;
- current->gradientTransformCurrentValue().concatenate(transform);
- attributes.setGradientTransform(transform);
- }
+ if (isLinear) {
+ SVGLinearGradientElement* linear = toSVGLinearGradientElement(element);
- if (!attributes.hasStops()) {
- const Vector<Gradient::ColorStop>& stops(current->buildStops());
- if (!stops.isEmpty())
- attributes.setStops(stops);
- }
+ if (!attributes.hasX1() && linear->x1()->isSpecified())
+ attributes.setX1(linear->x1()->currentValue());
- if (isLinear) {
- SVGLinearGradientElement* linear = toSVGLinearGradientElement(current);
+ if (!attributes.hasY1() && linear->y1()->isSpecified())
+ attributes.setY1(linear->y1()->currentValue());
- if (!attributes.hasX1() && current->hasAttribute(SVGNames::x1Attr))
- attributes.setX1(linear->x1CurrentValue());
+ if (!attributes.hasX2() && linear->x2()->isSpecified())
+ attributes.setX2(linear->x2()->currentValue());
- if (!attributes.hasY1() && current->hasAttribute(SVGNames::y1Attr))
- attributes.setY1(linear->y1CurrentValue());
+ if (!attributes.hasY2() && linear->y2()->isSpecified())
+ attributes.setY2(linear->y2()->currentValue());
+ }
+}
- if (!attributes.hasX2() && current->hasAttribute(SVGNames::x2Attr))
- attributes.setX2(linear->x2CurrentValue());
+bool SVGLinearGradientElement::collectGradientAttributes(LinearGradientAttributes& attributes)
+{
+ if (!renderer())
+ return false;
- if (!attributes.hasY2() && current->hasAttribute(SVGNames::y2Attr))
- attributes.setY2(linear->y2CurrentValue());
- }
+ HashSet<SVGGradientElement*> processedGradients;
+ SVGGradientElement* current = this;
- processedGradients.add(current);
+ setGradientAttributes(current, attributes);
+ processedGradients.add(current);
+ while (true) {
// Respect xlink:href, take attributes from referenced element
- Node* refNode = SVGURIReference::targetElementFromIRIString(current->hrefCurrentValue(), document());
- if (refNode && (refNode->hasTagName(SVGNames::linearGradientTag) || refNode->hasTagName(SVGNames::radialGradientTag))) {
+ Node* refNode = SVGURIReference::targetElementFromIRIString(current->href()->currentValue()->value(), treeScope());
+ if (refNode && isSVGGradientElement(*refNode)) {
current = toSVGGradientElement(refNode);
// Cycle detection
- if (processedGradients.contains(current)) {
- current = 0;
- break;
- }
-
- isLinear = current->hasTagName(SVGNames::linearGradientTag);
- } else
- current = 0;
+ if (processedGradients.contains(current))
+ return true;
+
+ if (!current->renderer())
+ return false;
+
+ setGradientAttributes(current, attributes, isSVGLinearGradientElement(*current));
+ processedGradients.add(current);
+ } else {
+ return true;
+ }
}
- return true;
+ ASSERT_NOT_REACHED();
+ return false;
}
bool SVGLinearGradientElement::selfHasRelativeLengths() const
{
- return x1CurrentValue().isRelative()
- || y1CurrentValue().isRelative()
- || x2CurrentValue().isRelative()
- || y2CurrentValue().isRelative();
+ return m_x1->currentValue()->isRelative()
+ || m_y1->currentValue()->isRelative()
+ || m_x2->currentValue()->isRelative()
+ || m_y2->currentValue()->isRelative();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.h
index 179424e1ca7..a014b8bde8e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGLinearGradientElement.h
@@ -21,7 +21,7 @@
#ifndef SVGLinearGradientElement_h
#define SVGLinearGradientElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedLength.h"
#include "core/svg/SVGGradientElement.h"
@@ -31,31 +31,32 @@ struct LinearGradientAttributes;
class SVGLinearGradientElement FINAL : public SVGGradientElement {
public:
- static PassRefPtr<SVGLinearGradientElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGLinearGradientElement);
bool collectGradientAttributes(LinearGradientAttributes&);
+ SVGAnimatedLength* x1() const { return m_x1.get(); }
+ SVGAnimatedLength* y1() const { return m_y1.get(); }
+ SVGAnimatedLength* x2() const { return m_x2.get(); }
+ SVGAnimatedLength* y2() const { return m_y2.get(); }
+
private:
explicit SVGLinearGradientElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGLinearGradientElement)
- DECLARE_ANIMATED_LENGTH(X1, x1)
- DECLARE_ANIMATED_LENGTH(Y1, y1)
- DECLARE_ANIMATED_LENGTH(X2, x2)
- DECLARE_ANIMATED_LENGTH(Y2, y2)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_x1;
+ RefPtr<SVGAnimatedLength> m_y1;
+ RefPtr<SVGAnimatedLength> m_x2;
+ RefPtr<SVGAnimatedLength> m_y2;
};
-DEFINE_NODE_TYPE_CASTS(SVGLinearGradientElement, hasTagName(SVGNames::linearGradientTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.cpp
index 058738f61de..b15bcc1472a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.cpp
@@ -21,7 +21,7 @@
#include "core/svg/SVGMPathElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Document.h"
#include "core/svg/SVGAnimateMotionElement.h"
#include "core/svg/SVGDocumentExtensions.h"
@@ -29,30 +29,20 @@
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGMPathElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGMPathElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGMPathElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGMPathElement::SVGMPathElement(Document& document)
: SVGElement(SVGNames::mpathTag, document)
+ , SVGURIReference(this)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGMPathElement();
}
-PassRefPtr<SVGMPathElement> SVGMPathElement::create(Document& document)
-{
- return adoptRef(new SVGMPathElement(document));
-}
+DEFINE_NODE_FACTORY(SVGMPathElement)
SVGMPathElement::~SVGMPathElement()
{
+#if !ENABLE(OILPAN)
clearResourceReferences();
+#endif
}
void SVGMPathElement::buildPendingResource()
@@ -61,21 +51,21 @@ void SVGMPathElement::buildPendingResource()
if (!inDocument())
return;
- String id;
- Element* target = SVGURIReference::targetElementFromIRIString(hrefCurrentValue(), document(), &id);
+ AtomicString id;
+ Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), treeScope(), &id);
if (!target) {
// Do not register as pending if we are already pending this resource.
- if (document().accessSVGExtensions()->isElementPendingResource(this, id))
+ if (document().accessSVGExtensions().isElementPendingResource(this, id))
return;
if (!id.isEmpty()) {
- document().accessSVGExtensions()->addPendingResource(id, this);
+ document().accessSVGExtensions().addPendingResource(id, this);
ASSERT(hasPendingResources());
}
} else if (target->isSVGElement()) {
// Register us with the target in the dependencies map. Any change of hrefElement
// that leads to relayout/repainting now informs us, so we can react to it.
- document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target));
+ document().accessSVGExtensions().addElementReferencingTarget(this, toSVGElement(target));
}
targetPathChanged();
@@ -83,7 +73,7 @@ void SVGMPathElement::buildPendingResource()
void SVGMPathElement::clearResourceReferences()
{
- document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+ document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
}
Node::InsertionNotificationRequest SVGMPathElement::insertedInto(ContainerNode* rootParent)
@@ -107,24 +97,22 @@ bool SVGMPathElement::isSupportedAttribute(const QualifiedName& attrName)
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGURIReference::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
}
return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
}
void SVGMPathElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
+ SVGParsingError parseError = NoError;
+
if (!isSupportedAttribute(name)) {
SVGElement::parseAttribute(name, value);
- return;
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else {
+ ASSERT_NOT_REACHED();
}
- if (SVGURIReference::parseAttribute(name, value))
- return;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGMPathElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -134,25 +122,20 @@ void SVGMPathElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (SVGURIReference::isKnownAttribute(attrName)) {
buildPendingResource();
return;
}
- if (SVGExternalResourcesRequired::isKnownAttribute(attrName))
- return;
-
ASSERT_NOT_REACHED();
}
SVGPathElement* SVGMPathElement::pathElement()
{
- Element* target = targetElementFromIRIString(hrefCurrentValue(), document());
- if (target && target->hasTagName(SVGNames::pathTag))
- return toSVGPathElement(target);
- return 0;
+ Element* target = targetElementFromIRIString(hrefString(), treeScope());
+ return isSVGPathElement(target) ? toSVGPathElement(target) : 0;
}
void SVGMPathElement::targetPathChanged()
@@ -162,8 +145,8 @@ void SVGMPathElement::targetPathChanged()
void SVGMPathElement::notifyParentOfPathChange(ContainerNode* parent)
{
- if (parent && parent->hasTagName(SVGNames::animateMotionTag))
- static_cast<SVGAnimateMotionElement*>(parent)->updateAnimationPath();
+ if (isSVGAnimateMotionElement(parent))
+ toSVGAnimateMotionElement(parent)->updateAnimationPath();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.h
index 0bccf802d6c..e58051e2a09 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.h
@@ -20,11 +20,10 @@
#ifndef SVGMPathElement_h
#define SVGMPathElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedString.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGURIReference.h"
namespace WebCore {
@@ -32,10 +31,9 @@ namespace WebCore {
class SVGPathElement;
class SVGMPathElement FINAL : public SVGElement,
- public SVGURIReference,
- public SVGExternalResourcesRequired {
+ public SVGURIReference {
public:
- static PassRefPtr<SVGMPathElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGMPathElement);
virtual ~SVGMPathElement();
@@ -46,10 +44,10 @@ public:
private:
explicit SVGMPathElement(Document&);
- void buildPendingResource();
+ virtual void buildPendingResource() OVERRIDE;
void clearResourceReferences();
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
- void removedFrom(ContainerNode*);
+ virtual void removedFrom(ContainerNode*) OVERRIDE;
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
@@ -58,14 +56,8 @@ private:
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
void notifyParentOfPathChange(ContainerNode*);
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMPathElement)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
};
-DEFINE_NODE_TYPE_CASTS(SVGMPathElement, hasTagName(SVGNames::mpathTag));
-
} // namespace WebCore
#endif // SVGMPathElement_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.idl
index 384958290de..bb8aaf6e2ee 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMPathElement.idl
@@ -26,6 +26,5 @@
interface SVGMPathElement : SVGElement {
};
-SVGMPathElement implements SVGExternalResourcesRequired;
SVGMPathElement implements SVGURIReference;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
index 8bb26d62912..146824a3a6c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp
@@ -23,93 +23,58 @@
#include "core/svg/SVGMarkerElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/svg/RenderSVGResourceMarker.h"
-#include "core/svg/SVGElementInstance.h"
+#include "core/svg/SVGAngleTearOff.h"
namespace WebCore {
-// Define custom animated property 'orientType'.
-const SVGPropertyInfo* SVGMarkerElement::orientTypePropertyInfo()
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerUnitsType>()
{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedEnumeration,
- PropertyIsReadWrite,
- SVGNames::orientAttr,
- orientTypeIdentifier(),
- &SVGMarkerElement::synchronizeOrientType,
- &SVGMarkerElement::lookupOrCreateOrientTypeWrapper);
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(SVGMarkerUnitsUserSpaceOnUse, "userSpaceOnUse"));
+ entries.append(std::make_pair(SVGMarkerUnitsStrokeWidth, "strokeWidth"));
}
- return s_propertyInfo;
+ return entries;
}
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGMarkerElement, SVGNames::refXAttr, RefX, refX)
-DEFINE_ANIMATED_LENGTH(SVGMarkerElement, SVGNames::refYAttr, RefY, refY)
-DEFINE_ANIMATED_LENGTH(SVGMarkerElement, SVGNames::markerWidthAttr, MarkerWidth, markerWidth)
-DEFINE_ANIMATED_LENGTH(SVGMarkerElement, SVGNames::markerHeightAttr, MarkerHeight, markerHeight)
-DEFINE_ANIMATED_ENUMERATION(SVGMarkerElement, SVGNames::markerUnitsAttr, MarkerUnits, markerUnits, SVGMarkerUnitsType)
-DEFINE_ANIMATED_ANGLE_AND_ENUMERATION(SVGMarkerElement, SVGNames::orientAttr, orientAngleIdentifier(), OrientAngle, orientAngle)
-DEFINE_ANIMATED_BOOLEAN(SVGMarkerElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-DEFINE_ANIMATED_RECT(SVGMarkerElement, SVGNames::viewBoxAttr, ViewBox, viewBox)
-DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGMarkerElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGMarkerElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(refX)
- REGISTER_LOCAL_ANIMATED_PROPERTY(refY)
- REGISTER_LOCAL_ANIMATED_PROPERTY(markerWidth)
- REGISTER_LOCAL_ANIMATED_PROPERTY(markerHeight)
- REGISTER_LOCAL_ANIMATED_PROPERTY(markerUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(orientAngle)
- REGISTER_LOCAL_ANIMATED_PROPERTY(orientType)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_LOCAL_ANIMATED_PROPERTY(viewBox)
- REGISTER_LOCAL_ANIMATED_PROPERTY(preserveAspectRatio)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
inline SVGMarkerElement::SVGMarkerElement(Document& document)
: SVGElement(SVGNames::markerTag, document)
- , m_orientType(SVGMarkerOrientAngle)
- , m_refX(LengthModeWidth)
- , m_refY(LengthModeHeight)
- , m_markerWidth(LengthModeWidth, "3")
- , m_markerHeight(LengthModeHeight, "3")
- , m_markerUnits(SVGMarkerUnitsStrokeWidth)
+ , SVGFitToViewBox(this)
+ , m_refX(SVGAnimatedLength::create(this, SVGNames::refXAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_refY(SVGAnimatedLength::create(this, SVGNames::refXAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_markerWidth(SVGAnimatedLength::create(this, SVGNames::markerWidthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_markerHeight(SVGAnimatedLength::create(this, SVGNames::markerHeightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
+ , m_orientAngle(SVGAnimatedAngle::create(this))
+ , m_markerUnits(SVGAnimatedEnumeration<SVGMarkerUnitsType>::create(this, SVGNames::markerUnitsAttr, SVGMarkerUnitsStrokeWidth))
{
- // Spec: If the markerWidth/markerHeight attribute is not specified, the effect is as if a value of "3" were specified.
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGMarkerElement();
-}
-PassRefPtr<SVGMarkerElement> SVGMarkerElement::create(Document& document)
-{
- return adoptRef(new SVGMarkerElement(document));
-}
+ // Spec: If the markerWidth/markerHeight attribute is not specified, the effect is as if a value of "3" were specified.
+ m_markerWidth->setDefaultValueAsString("3");
+ m_markerHeight->setDefaultValueAsString("3");
-const AtomicString& SVGMarkerElement::orientTypeIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientType", AtomicString::ConstructFromLiteral));
- return s_identifier;
+ addToPropertyMap(m_refX);
+ addToPropertyMap(m_refY);
+ addToPropertyMap(m_markerWidth);
+ addToPropertyMap(m_markerHeight);
+ addToPropertyMap(m_orientAngle);
+ addToPropertyMap(m_markerUnits);
}
-const AtomicString& SVGMarkerElement::orientAngleIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientAngle", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
+DEFINE_NODE_FACTORY(SVGMarkerElement)
AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
{
- return SVGFitToViewBox::viewBoxToViewTransform(viewBoxCurrentValue(), preserveAspectRatioCurrentValue(), viewWidth, viewHeight);
+ return SVGFitToViewBox::viewBoxToViewTransform(viewBox()->currentValue()->value(), preserveAspectRatio()->currentValue(), viewWidth, viewHeight);
}
bool SVGMarkerElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
SVGFitToViewBox::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::markerUnitsAttr);
supportedAttributes.add(SVGNames::refXAttr);
@@ -127,27 +92,19 @@ void SVGMarkerElement::parseAttribute(const QualifiedName& name, const AtomicStr
if (!isSupportedAttribute(name))
SVGElement::parseAttribute(name, value);
- else if (name == SVGNames::markerUnitsAttr) {
- SVGMarkerUnitsType propertyValue = SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value);
- if (propertyValue > 0)
- setMarkerUnitsBaseValue(propertyValue);
- } else if (name == SVGNames::refXAttr)
- setRefXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ else if (name == SVGNames::markerUnitsAttr)
+ m_markerUnits->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::refXAttr)
+ m_refX->setBaseValueAsString(value, parseError);
else if (name == SVGNames::refYAttr)
- setRefYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_refY->setBaseValueAsString(value, parseError);
else if (name == SVGNames::markerWidthAttr)
- setMarkerWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_markerWidth->setBaseValueAsString(value, parseError);
else if (name == SVGNames::markerHeightAttr)
- setMarkerHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (name == SVGNames::orientAttr) {
- SVGAngle angle;
- SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(value, angle);
- if (orientType > 0)
- setOrientTypeBaseValue(orientType);
- if (orientType == SVGMarkerOrientAngle)
- setOrientAngleBaseValue(angle);
- } else if (SVGExternalResourcesRequired::parseAttribute(name, value)
- || SVGFitToViewBox::parseAttribute(this, name, value)) {
+ m_markerHeight->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::orientAttr)
+ m_orientAngle->setBaseValueAsString(value, parseError);
+ else if (SVGFitToViewBox::parseAttribute(name, value, document(), parseError)) {
} else
ASSERT_NOT_REACHED();
@@ -161,7 +118,7 @@ void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::refXAttr
|| attrName == SVGNames::refYAttr
@@ -182,31 +139,23 @@ void SVGMarkerElement::childrenChanged(bool changedByParser, Node* beforeChange,
return;
if (RenderObject* object = renderer())
- object->setNeedsLayout();
+ object->setNeedsLayoutAndFullPaintInvalidation();
}
void SVGMarkerElement::setOrientToAuto()
{
- setOrientTypeBaseValue(SVGMarkerOrientAuto);
- setOrientAngleBaseValue(SVGAngle());
-
- // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization.
- m_orientAngle.shouldSynchronize = true;
- m_orientType.shouldSynchronize = true;
+ m_orientAngle->baseValue()->orientType()->setEnumValue(SVGMarkerOrientAuto);
invalidateSVGAttributes();
- svgAttributeChanged(orientAnglePropertyInfo()->attributeName);
+ svgAttributeChanged(SVGNames::orientAttr);
}
-void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle)
+void SVGMarkerElement::setOrientToAngle(PassRefPtr<SVGAngleTearOff> angle)
{
- setOrientTypeBaseValue(SVGMarkerOrientAngle);
- setOrientAngleBaseValue(angle);
-
- // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization.
- m_orientAngle.shouldSynchronize = true;
- m_orientType.shouldSynchronize = true;
+ ASSERT(angle);
+ RefPtr<SVGAngle> target = angle->target();
+ m_orientAngle->baseValue()->newValueSpecifiedUnits(target->unitType(), target->valueInSpecifiedUnits());
invalidateSVGAttributes();
- svgAttributeChanged(orientAnglePropertyInfo()->attributeName);
+ svgAttributeChanged(SVGNames::orientAttr);
}
RenderObject* SVGMarkerElement::createRenderer(RenderStyle*)
@@ -216,39 +165,10 @@ RenderObject* SVGMarkerElement::createRenderer(RenderStyle*)
bool SVGMarkerElement::selfHasRelativeLengths() const
{
- return refXCurrentValue().isRelative()
- || refYCurrentValue().isRelative()
- || markerWidthCurrentValue().isRelative()
- || markerHeightCurrentValue().isRelative();
-}
-
-void SVGMarkerElement::synchronizeOrientType(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- SVGMarkerElement* ownerType = toSVGMarkerElement(contextElement);
- if (!ownerType->m_orientType.shouldSynchronize)
- return;
-
- // If orient is not auto, the previous call to synchronizeOrientAngle already set the orientAttr to the right angle.
- if (ownerType->m_orientType.value != SVGMarkerOrientAuto)
- return;
-
- DEFINE_STATIC_LOCAL(AtomicString, autoString, ("auto", AtomicString::ConstructFromLiteral));
- ownerType->m_orientType.synchronize(ownerType, orientTypePropertyInfo()->attributeName, autoString);
-}
-
-PassRefPtr<SVGAnimatedProperty> SVGMarkerElement::lookupOrCreateOrientTypeWrapper(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- SVGMarkerElement* ownerType = toSVGMarkerElement(contextElement);
- return SVGAnimatedProperty::lookupOrCreateWrapper<SVGMarkerElement, SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>, SVGMarkerOrientType>
- (ownerType, orientTypePropertyInfo(), ownerType->m_orientType.value);
-}
-
-PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType> > SVGMarkerElement::orientType()
-{
- m_orientType.shouldSynchronize = true;
- return static_pointer_cast<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType> >(lookupOrCreateOrientTypeWrapper(this));
+ return m_refX->currentValue()->isRelative()
+ || m_refY->currentValue()->isRelative()
+ || m_markerWidth->currentValue()->isRelative()
+ || m_markerHeight->currentValue()->isRelative();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.h
index da6b4654f8f..c167a9e2b4b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.h
@@ -26,10 +26,7 @@
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGAnimatedRect.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGFitToViewBox.h"
namespace WebCore {
@@ -39,63 +36,9 @@ enum SVGMarkerUnitsType {
SVGMarkerUnitsUserSpaceOnUse,
SVGMarkerUnitsStrokeWidth
};
-
-enum SVGMarkerOrientType {
- SVGMarkerOrientUnknown = 0,
- SVGMarkerOrientAuto,
- SVGMarkerOrientAngle
-};
-
-template<>
-struct SVGPropertyTraits<SVGMarkerUnitsType> {
- static unsigned highestEnumValue() { return SVGMarkerUnitsStrokeWidth; }
-
- static String toString(SVGMarkerUnitsType type)
- {
- switch (type) {
- case SVGMarkerUnitsUnknown:
- return emptyString();
- case SVGMarkerUnitsUserSpaceOnUse:
- return "userSpaceOnUse";
- case SVGMarkerUnitsStrokeWidth:
- return "strokeWidth";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static SVGMarkerUnitsType fromString(const String& value)
- {
- if (value == "userSpaceOnUse")
- return SVGMarkerUnitsUserSpaceOnUse;
- if (value == "strokeWidth")
- return SVGMarkerUnitsStrokeWidth;
- return SVGMarkerUnitsUnknown;
- }
-};
-
-template<>
-struct SVGPropertyTraits<SVGMarkerOrientType> {
- static unsigned highestEnumValue() { return SVGMarkerOrientAngle; }
-
- // toString is not needed, synchronizeOrientType() handles this on its own.
-
- static SVGMarkerOrientType fromString(const String& value, SVGAngle& angle)
- {
- if (value == "auto")
- return SVGMarkerOrientAuto;
-
- TrackExceptionState exceptionState;
- angle.setValueAsString(value, exceptionState);
- if (!exceptionState.hadException())
- return SVGMarkerOrientAngle;
- return SVGMarkerOrientUnknown;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerUnitsType>();
class SVGMarkerElement FINAL : public SVGElement,
- public SVGExternalResourcesRequired,
public SVGFitToViewBox {
public:
// Forward declare enumerations in the W3C naming scheme, for IDL generation.
@@ -111,60 +54,44 @@ public:
SVG_MARKER_ORIENT_ANGLE = SVGMarkerOrientAngle
};
- static PassRefPtr<SVGMarkerElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGMarkerElement);
AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
void setOrientToAuto();
- void setOrientToAngle(const SVGAngle&);
+ void setOrientToAngle(PassRefPtr<SVGAngleTearOff>);
- static const SVGPropertyInfo* orientTypePropertyInfo();
-
- // Custom 'orientType' property.
- static void synchronizeOrientType(SVGElement* contextElement);
- static PassRefPtr<SVGAnimatedProperty> lookupOrCreateOrientTypeWrapper(SVGElement* contextElement);
- SVGMarkerOrientType& orientTypeCurrentValue() const { return m_orientType.value; }
- SVGMarkerOrientType& orientTypeBaseValue() const { return m_orientType.value; }
- void setOrientTypeBaseValue(const SVGMarkerOrientType& type) { m_orientType.value = type; }
- PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType> > orientType();
+ SVGAnimatedLength* refX() const { return m_refX.get(); }
+ SVGAnimatedLength* refY() const { return m_refY.get(); }
+ SVGAnimatedLength* markerWidth() const { return m_markerWidth.get(); }
+ SVGAnimatedLength* markerHeight() const { return m_markerHeight.get(); }
+ SVGAnimatedEnumeration<SVGMarkerUnitsType>* markerUnits() { return m_markerUnits.get(); }
+ SVGAnimatedAngle* orientAngle() { return m_orientAngle.get(); }
+ SVGAnimatedEnumeration<SVGMarkerOrientType>* orientType() { return m_orientAngle->orientType(); }
private:
explicit SVGMarkerElement(Document&);
- virtual bool needsPendingResourceHandling() const { return false; }
+ virtual bool needsPendingResourceHandling() const OVERRIDE { return false; }
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool rendererIsNeeded(const RenderStyle&) { return true; }
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return true; }
- void synchronizeOrientType();
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
- static const AtomicString& orientTypeIdentifier();
- static const AtomicString& orientAngleIdentifier();
-
- mutable SVGSynchronizableAnimatedProperty<SVGMarkerOrientType> m_orientType;
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMarkerElement)
- DECLARE_ANIMATED_LENGTH(RefX, refX)
- DECLARE_ANIMATED_LENGTH(RefY, refY)
- DECLARE_ANIMATED_LENGTH(MarkerWidth, markerWidth)
- DECLARE_ANIMATED_LENGTH(MarkerHeight, markerHeight)
- DECLARE_ANIMATED_ENUMERATION(MarkerUnits, markerUnits, SVGMarkerUnitsType)
- DECLARE_ANIMATED_ANGLE(OrientAngle, orientAngle)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- DECLARE_ANIMATED_RECT(ViewBox, viewBox)
- DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_refX;
+ RefPtr<SVGAnimatedLength> m_refY;
+ RefPtr<SVGAnimatedLength> m_markerWidth;
+ RefPtr<SVGAnimatedLength> m_markerHeight;
+ RefPtr<SVGAnimatedAngle> m_orientAngle;
+ RefPtr<SVGAnimatedEnumeration<SVGMarkerUnitsType> > m_markerUnits;
};
-DEFINE_NODE_TYPE_CASTS(SVGMarkerElement, hasTagName(SVGNames::markerTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.idl
index 0918d76a0b4..4527585f38e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMarkerElement.idl
@@ -23,29 +23,32 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGMarkerElement : SVGElement {
+// http://www.w3.org/TR/SVG2/painting.html#InterfaceSVGMarkerElement
+
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGMarkerElement : SVGElement {
+
// Marker Unit Types
- const unsigned short SVG_MARKERUNITS_UNKNOWN = 0;
+ const unsigned short SVG_MARKERUNITS_UNKNOWN = 0;
const unsigned short SVG_MARKERUNITS_USERSPACEONUSE = 1;
- const unsigned short SVG_MARKERUNITS_STROKEWIDTH = 2;
+ const unsigned short SVG_MARKERUNITS_STROKEWIDTH = 2;
// Marker Orientation Types
- const unsigned short SVG_MARKER_ORIENT_UNKNOWN = 0;
- const unsigned short SVG_MARKER_ORIENT_AUTO = 1;
- const unsigned short SVG_MARKER_ORIENT_ANGLE = 2;
+ const unsigned short SVG_MARKER_ORIENT_UNKNOWN = 0;
+ const unsigned short SVG_MARKER_ORIENT_AUTO = 1;
+ const unsigned short SVG_MARKER_ORIENT_ANGLE = 2;
- readonly attribute SVGAnimatedLength refX;
- readonly attribute SVGAnimatedLength refY;
+ readonly attribute SVGAnimatedLength refX;
+ readonly attribute SVGAnimatedLength refY;
readonly attribute SVGAnimatedEnumeration markerUnits;
- readonly attribute SVGAnimatedLength markerWidth;
- readonly attribute SVGAnimatedLength markerHeight;
+ readonly attribute SVGAnimatedLength markerWidth;
+ readonly attribute SVGAnimatedLength markerHeight;
readonly attribute SVGAnimatedEnumeration orientType;
- readonly attribute SVGAnimatedAngle orientAngle;
+ readonly attribute SVGAnimatedAngle orientAngle;
void setOrientToAuto();
- void setOrientToAngle([Default=Undefined] optional SVGAngle angle);
+ void setOrientToAngle(SVGAngle angle);
};
-SVGMarkerElement implements SVGExternalResourcesRequired;
SVGMarkerElement implements SVGFitToViewBox;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.cpp
index 728dfcb8b4a..feebb7e0df9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.cpp
@@ -26,57 +26,44 @@
#include "core/svg/SVGMaskElement.h"
#include "core/rendering/svg/RenderSVGResourceMasker.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGMaskElement, SVGNames::maskUnitsAttr, MaskUnits, maskUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_ENUMERATION(SVGMaskElement, SVGNames::maskContentUnitsAttr, MaskContentUnits, maskContentUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_LENGTH(SVGMaskElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGMaskElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGMaskElement, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGMaskElement, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_BOOLEAN(SVGMaskElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGMaskElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(maskUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(maskContentUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGMaskElement::SVGMaskElement(Document& document)
: SVGElement(SVGNames::maskTag, document)
- , m_maskUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
- , m_maskContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
- , m_x(LengthModeWidth, "-10%")
- , m_y(LengthModeHeight, "-10%")
- , m_width(LengthModeWidth, "120%")
- , m_height(LengthModeHeight, "120%")
+ , SVGTests(this)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
+ , m_maskUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::maskUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
+ , m_maskContentUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
{
+ ScriptWrappable::init(this);
+
// Spec: If the x/y attribute is not specified, the effect is as if a value of "-10%" were specified.
+ m_x->setDefaultValueAsString("-10%");
+ m_y->setDefaultValueAsString("-10%");
+
// Spec: If the width/height attribute is not specified, the effect is as if a value of "120%" were specified.
- ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGMaskElement();
+ m_width->setDefaultValueAsString("120%");
+ m_height->setDefaultValueAsString("120%");
+
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
+ addToPropertyMap(m_maskUnits);
+ addToPropertyMap(m_maskContentUnits);
}
-PassRefPtr<SVGMaskElement> SVGMaskElement::create(Document& document)
-{
- return adoptRef(new SVGMaskElement(document));
-}
+DEFINE_NODE_FACTORY(SVGMaskElement)
bool SVGMaskElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGTests::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::maskUnitsAttr);
supportedAttributes.add(SVGNames::maskContentUnitsAttr);
supportedAttributes.add(SVGNames::xAttr);
@@ -93,26 +80,19 @@ void SVGMaskElement::parseAttribute(const QualifiedName& name, const AtomicStrin
if (!isSupportedAttribute(name))
SVGElement::parseAttribute(name, value);
- else if (name == SVGNames::maskUnitsAttr) {
- SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
- if (propertyValue > 0)
- setMaskUnitsBaseValue(propertyValue);
- return;
- } else if (name == SVGNames::maskContentUnitsAttr) {
- SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
- if (propertyValue > 0)
- setMaskContentUnitsBaseValue(propertyValue);
- return;
- } else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ else if (name == SVGNames::maskUnitsAttr)
+ m_maskUnits->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::maskContentUnitsAttr)
+ m_maskContentUnits->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::xAttr)
+ m_x->setBaseValueAsString(value, parseError);
else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_y->setBaseValueAsString(value, parseError);
else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_width->setBaseValueAsString(value, parseError);
else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (SVGTests::parseAttribute(name, value)
- || SVGExternalResourcesRequired::parseAttribute(name, value)) {
+ m_height->setBaseValueAsString(value, parseError);
+ else if (SVGTests::parseAttribute(name, value)) {
} else
ASSERT_NOT_REACHED();
@@ -126,7 +106,7 @@ void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
@@ -147,7 +127,7 @@ void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, N
return;
if (RenderObject* object = renderer())
- object->setNeedsLayout();
+ object->setNeedsLayoutAndFullPaintInvalidation();
}
RenderObject* SVGMaskElement::createRenderer(RenderStyle*)
@@ -157,10 +137,10 @@ RenderObject* SVGMaskElement::createRenderer(RenderStyle*)
bool SVGMaskElement::selfHasRelativeLengths() const
{
- return xCurrentValue().isRelative()
- || yCurrentValue().isRelative()
- || widthCurrentValue().isRelative()
- || heightCurrentValue().isRelative();
+ return m_x->currentValue()->isRelative()
+ || m_y->currentValue()->isRelative()
+ || m_width->currentValue()->isRelative()
+ || m_height->currentValue()->isRelative();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.h
index a4b09ae2e3a..c5b439ffe3c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.h
@@ -20,56 +20,51 @@
#ifndef SVGMaskElement_h
#define SVGMaskElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedLength.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGTests.h"
#include "core/svg/SVGUnitTypes.h"
namespace WebCore {
class SVGMaskElement FINAL : public SVGElement,
- public SVGTests,
- public SVGExternalResourcesRequired {
+ public SVGTests {
public:
- static PassRefPtr<SVGMaskElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGMaskElement);
+
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
+ SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* maskUnits() { return m_maskUnits.get(); }
+ SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* maskContentUnits() { return m_maskContentUnits.get(); }
private:
explicit SVGMaskElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool needsPendingResourceHandling() const { return false; }
+ virtual bool isValid() const OVERRIDE { return SVGTests::isValid(); }
+ virtual bool needsPendingResourceHandling() const OVERRIDE { return false; }
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMaskElement)
- DECLARE_ANIMATED_ENUMERATION(MaskUnits, maskUnits, SVGUnitTypes::SVGUnitType)
- DECLARE_ANIMATED_ENUMERATION(MaskContentUnits, maskContentUnits, SVGUnitTypes::SVGUnitType)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
- // SVGTests
- virtual void synchronizeRequiredFeatures() { SVGTests::synchronizeRequiredFeatures(this); }
- virtual void synchronizeRequiredExtensions() { SVGTests::synchronizeRequiredExtensions(this); }
- virtual void synchronizeSystemLanguage() { SVGTests::synchronizeSystemLanguage(this); }
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
+ RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_maskUnits;
+ RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_maskContentUnits;
};
-DEFINE_NODE_TYPE_CASTS(SVGMaskElement, hasTagName(SVGNames::maskTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.idl
index 22658d59e95..06ced403637 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMaskElement.idl
@@ -23,16 +23,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/css-masking/#InterfaceSVGMaskElement
+
interface SVGMaskElement : SVGElement {
readonly attribute SVGAnimatedEnumeration maskUnits;
readonly attribute SVGAnimatedEnumeration maskContentUnits;
-
readonly attribute SVGAnimatedLength x;
readonly attribute SVGAnimatedLength y;
readonly attribute SVGAnimatedLength width;
readonly attribute SVGAnimatedLength height;
};
-SVGMaskElement implements SVGExternalResourcesRequired;
SVGMaskElement implements SVGTests;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMatrix.h b/chromium/third_party/WebKit/Source/core/svg/SVGMatrix.h
deleted file mode 100644
index df536b56769..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMatrix.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGMatrix_h
-#define SVGMatrix_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "platform/transforms/AffineTransform.h"
-
-namespace WebCore {
-
-// Only used in the bindings.
-class SVGMatrix : public AffineTransform {
-public:
- SVGMatrix() { }
- SVGMatrix(const AffineTransform& other)
- : AffineTransform(other)
- {
- }
-
- SVGMatrix(double a, double b, double c, double d, double e, double f)
- : AffineTransform(a, b, c, d, e, f)
- {
- }
-
- SVGMatrix translate(double tx, double ty)
- {
- AffineTransform copy = *this;
- copy.translate(tx, ty);
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix scale(double s)
- {
- AffineTransform copy = *this;
- copy.scale(s, s);
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix scaleNonUniform(double sx, double sy)
- {
- AffineTransform copy = *this;
- copy.scale(sx, sy);
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix rotate(double d)
- {
- AffineTransform copy = *this;
- copy.rotate(d);
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix flipX()
- {
- AffineTransform copy = *this;
- copy.flipX();
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix flipY()
- {
- AffineTransform copy = *this;
- copy.flipY();
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix skewX(double angle)
- {
- AffineTransform copy = *this;
- copy.skewX(angle);
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix skewY(double angle)
- {
- AffineTransform copy = *this;
- copy.skewY(angle);
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix multiply(const SVGMatrix& other)
- {
- AffineTransform copy = *this;
- copy *= static_cast<const AffineTransform&>(other);
- return static_cast<SVGMatrix>(copy);
- }
-
- SVGMatrix inverse(ExceptionState& exceptionState) const
- {
- AffineTransform transform = AffineTransform::inverse();
- if (!isInvertible())
- exceptionState.throwDOMException(InvalidStateError, "The matrix is not invertible.");
-
- return transform;
- }
-
- SVGMatrix rotateFromVector(double x, double y, ExceptionState& exceptionState)
- {
- if (!x || !y)
- exceptionState.throwDOMException(InvalidAccessError, "Arguments cannot be zero.");
-
- AffineTransform copy = *this;
- copy.rotateFromVector(x, y);
- return static_cast<SVGMatrix>(copy);
- }
-
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMatrix.idl b/chromium/third_party/WebKit/Source/core/svg/SVGMatrix.idl
index af560290c01..90d00e4fdb0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMatrix.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMatrix.idl
@@ -21,27 +21,29 @@
*/
[
- SetReference(SVGTransform parent)
+ TypeChecking=Interface|Nullable,
+ ImplementedAs=SVGMatrixTearOff,
+ SetWrapperReferenceTo(SVGTransform contextTransform)
] interface SVGMatrix {
// FIXME: these attributes should all be floats but since we implement
// AffineTransform with doubles setting these as doubles makes more sense.
- [StrictTypeChecking] attribute double a;
- [StrictTypeChecking] attribute double b;
- [StrictTypeChecking] attribute double c;
- [StrictTypeChecking] attribute double d;
- [StrictTypeChecking] attribute double e;
- [StrictTypeChecking] attribute double f;
+ [RaisesException=Setter] attribute double a;
+ [RaisesException=Setter] attribute double b;
+ [RaisesException=Setter] attribute double c;
+ [RaisesException=Setter] attribute double d;
+ [RaisesException=Setter] attribute double e;
+ [RaisesException=Setter] attribute double f;
- [StrictTypeChecking] SVGMatrix multiply(SVGMatrix secondMatrix);
+ SVGMatrix multiply(SVGMatrix secondMatrix);
[RaisesException] SVGMatrix inverse();
- [Immutable, StrictTypeChecking] SVGMatrix translate(float x, float y);
- [Immutable, StrictTypeChecking] SVGMatrix scale(float scaleFactor);
- [Immutable, StrictTypeChecking] SVGMatrix scaleNonUniform(float scaleFactorX, float scaleFactorY);
- [Immutable, StrictTypeChecking] SVGMatrix rotate(float angle);
- [StrictTypeChecking, RaisesException] SVGMatrix rotateFromVector(float x, float y);
- [Immutable] SVGMatrix flipX();
- [Immutable] SVGMatrix flipY();
- [Immutable, StrictTypeChecking] SVGMatrix skewX(float angle);
- [Immutable, StrictTypeChecking] SVGMatrix skewY(float angle);
+ SVGMatrix translate(float x, float y);
+ SVGMatrix scale(float scaleFactor);
+ SVGMatrix scaleNonUniform(float scaleFactorX, float scaleFactorY);
+ SVGMatrix rotate(float angle);
+ [RaisesException] SVGMatrix rotateFromVector(float x, float y);
+ SVGMatrix flipX();
+ SVGMatrix flipY();
+ SVGMatrix skewX(float angle);
+ SVGMatrix skewY(float angle);
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp
new file mode 100644
index 00000000000..c43e555fd72
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGMatrixTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGTransformTearOff.h"
+
+namespace WebCore {
+
+SVGMatrixTearOff::SVGMatrixTearOff(const AffineTransform& staticValue)
+ : m_staticValue(staticValue)
+ , m_contextTransform(0)
+{
+ ScriptWrappable::init(this);
+}
+
+SVGMatrixTearOff::SVGMatrixTearOff(SVGTransformTearOff* transform)
+ : m_contextTransform(transform)
+{
+ ASSERT(transform);
+ ScriptWrappable::init(this);
+}
+
+SVGMatrixTearOff::~SVGMatrixTearOff()
+{
+}
+
+const AffineTransform& SVGMatrixTearOff::value() const
+{
+ return m_contextTransform ? m_contextTransform->target()->matrix() : m_staticValue;
+}
+
+AffineTransform* SVGMatrixTearOff::mutableValue()
+{
+ return m_contextTransform ? m_contextTransform->target()->mutableMatrix() : &m_staticValue;
+}
+
+void SVGMatrixTearOff::commitChange()
+{
+ if (!m_contextTransform)
+ return;
+
+ m_contextTransform->target()->onMatrixChange();
+ m_contextTransform->commitChange();
+}
+
+#define DEFINE_SETTER(ATTRIBUTE) \
+ void SVGMatrixTearOff::set##ATTRIBUTE(double f, ExceptionState& exceptionState) \
+ { \
+ if (m_contextTransform && m_contextTransform->isImmutable()) { \
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only."); \
+ return; \
+ } \
+ mutableValue()->set##ATTRIBUTE(f); \
+ commitChange(); \
+ }
+
+DEFINE_SETTER(A);
+DEFINE_SETTER(B);
+DEFINE_SETTER(C);
+DEFINE_SETTER(D);
+DEFINE_SETTER(E);
+DEFINE_SETTER(F);
+
+#undef DEFINE_SETTER
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::translate(double tx, double ty)
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ matrix->mutableValue()->translate(tx, ty);
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::scale(double s)
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ matrix->mutableValue()->scale(s, s);
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::scaleNonUniform(double sx, double sy)
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ matrix->mutableValue()->scale(sx, sy);
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::rotate(double d)
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ matrix->mutableValue()->rotate(d);
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::flipX()
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ matrix->mutableValue()->flipX();
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::flipY()
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ matrix->mutableValue()->flipY();
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::skewX(double angle)
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ matrix->mutableValue()->skewX(angle);
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::skewY(double angle)
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ matrix->mutableValue()->skewY(angle);
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::multiply(PassRefPtr<SVGMatrixTearOff> other)
+{
+ RefPtr<SVGMatrixTearOff> matrix = create(value());
+ *matrix->mutableValue() *= other->value();
+ return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::inverse(ExceptionState& exceptionState)
+{
+ AffineTransform transform = value().inverse();
+ if (!value().isInvertible())
+ exceptionState.throwDOMException(InvalidStateError, "The matrix is not invertible.");
+
+ return create(transform);
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::rotateFromVector(double x, double y, ExceptionState& exceptionState)
+{
+ if (!x || !y)
+ exceptionState.throwDOMException(InvalidAccessError, "Arguments cannot be zero.");
+
+ AffineTransform copy = value();
+ copy.rotateFromVector(x, y);
+ return create(copy);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMatrixTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGMatrixTearOff.h
new file mode 100644
index 00000000000..681b82d9aff
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMatrixTearOff.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGMatrixTearOff_h
+#define SVGMatrixTearOff_h
+
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ScriptWrappable.h"
+#include "platform/transforms/AffineTransform.h"
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class SVGTransformTearOff;
+
+// SVGMatrixTearOff wraps a AffineTransform for Javascript.
+// Its instance can either hold a static value, or this can be teared off from |SVGTransform.matrix|.
+// This does not derive from SVGPropertyTearOff, as its instances are never tied to an animated property nor an XML attribute.
+class SVGMatrixTearOff FINAL : public RefCounted<SVGMatrixTearOff>, public ScriptWrappable {
+public:
+ static PassRefPtr<SVGMatrixTearOff> create(const AffineTransform& value)
+ {
+ return adoptRef(new SVGMatrixTearOff(value));
+ }
+
+ static PassRefPtr<SVGMatrixTearOff> create(SVGTransformTearOff* target)
+ {
+ return adoptRef(new SVGMatrixTearOff(target));
+ }
+
+ ~SVGMatrixTearOff();
+
+ double a() { return value().a(); }
+ double b() { return value().b(); }
+ double c() { return value().c(); }
+ double d() { return value().d(); }
+ double e() { return value().e(); }
+ double f() { return value().f(); }
+
+ void setA(double, ExceptionState&);
+ void setB(double, ExceptionState&);
+ void setC(double, ExceptionState&);
+ void setD(double, ExceptionState&);
+ void setE(double, ExceptionState&);
+ void setF(double, ExceptionState&);
+
+ PassRefPtr<SVGMatrixTearOff> translate(double tx, double ty);
+ PassRefPtr<SVGMatrixTearOff> scale(double);
+ PassRefPtr<SVGMatrixTearOff> scaleNonUniform(double sx, double sy);
+ PassRefPtr<SVGMatrixTearOff> rotate(double);
+ PassRefPtr<SVGMatrixTearOff> flipX();
+ PassRefPtr<SVGMatrixTearOff> flipY();
+ PassRefPtr<SVGMatrixTearOff> skewX(double);
+ PassRefPtr<SVGMatrixTearOff> skewY(double);
+ PassRefPtr<SVGMatrixTearOff> multiply(PassRefPtr<SVGMatrixTearOff>);
+ PassRefPtr<SVGMatrixTearOff> inverse(ExceptionState&);
+ PassRefPtr<SVGMatrixTearOff> rotateFromVector(double x, double y, ExceptionState&);
+
+ SVGTransformTearOff* contextTransform() { return m_contextTransform; }
+
+ const AffineTransform& value() const;
+
+private:
+ SVGMatrixTearOff(const AffineTransform&);
+ SVGMatrixTearOff(SVGTransformTearOff*);
+
+ AffineTransform* mutableValue();
+ void commitChange();
+
+ AffineTransform m_staticValue;
+
+ // FIXME: oilpan: This is raw-ptr to avoid reference cycles. Should be Member in oilpan.
+ SVGTransformTearOff* m_contextTransform;
+};
+
+} // namespace WebCore
+
+#endif // SVGMatrixTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp
index d8ef56a6098..e0d55b6e39f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp
@@ -19,9 +19,10 @@
*/
#include "config.h"
-#include "SVGNames.h"
#include "core/svg/SVGMetadataElement.h"
+#include "core/SVGNames.h"
+
namespace WebCore {
inline SVGMetadataElement::SVGMetadataElement(Document& document)
@@ -30,9 +31,6 @@ inline SVGMetadataElement::SVGMetadataElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGMetadataElement> SVGMetadataElement::create(Document& document)
-{
- return adoptRef(new SVGMetadataElement(document));
-}
+DEFINE_NODE_FACTORY(SVGMetadataElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.h
index 1d889dfd0b2..a8cfb067829 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMetadataElement.h
@@ -27,7 +27,7 @@ namespace WebCore {
class SVGMetadataElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGMetadataElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGMetadataElement);
private:
explicit SVGMetadataElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp
index dd0ed72f92b..e9980012dfb 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp
@@ -30,10 +30,7 @@ inline SVGMissingGlyphElement::SVGMissingGlyphElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGMissingGlyphElement> SVGMissingGlyphElement::create(Document& document)
-{
- return adoptRef(new SVGMissingGlyphElement(document));
-}
+DEFINE_NODE_FACTORY(SVGMissingGlyphElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.h
index 9057582fab5..56016924da1 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.h
@@ -21,23 +21,21 @@
#define SVGMissingGlyphElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
namespace WebCore {
class SVGMissingGlyphElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGMissingGlyphElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGMissingGlyphElement);
private:
explicit SVGMissingGlyphElement(Document&);
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
};
-DEFINE_NODE_TYPE_CASTS(SVGMissingGlyphElement, hasTagName(SVGNames::missing_glyphTag));
-
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumber.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGNumber.cpp
new file mode 100644
index 00000000000..8e91bbf76e8
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumber.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGNumber.h"
+
+#include "core/svg/SVGAnimationElement.h"
+#include "core/svg/SVGParserUtilities.h"
+
+namespace WebCore {
+
+SVGNumber::SVGNumber(float value)
+ : SVGPropertyBase(classType())
+ , m_value(value)
+{
+}
+
+PassRefPtr<SVGNumber> SVGNumber::clone() const
+{
+ return create(m_value);
+}
+
+PassRefPtr<SVGPropertyBase> SVGNumber::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGNumber> svgNumber = create();
+ svgNumber->setValueAsString(value, IGNORE_EXCEPTION);
+ return svgNumber.release();
+}
+
+String SVGNumber::valueAsString() const
+{
+ return String::number(m_value);
+}
+
+template<typename CharType>
+bool SVGNumber::parse(const CharType*& ptr, const CharType* end)
+{
+ if (!parseNumber(ptr, end, m_value, AllowLeadingAndTrailingWhitespace)) {
+ m_value = 0;
+ return false;
+ }
+
+ if (ptr != end) {
+ m_value = 0;
+ return false;
+ }
+
+ return true;
+}
+
+void SVGNumber::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+ if (string.isEmpty()) {
+ m_value = 0;
+ return;
+ }
+
+ bool valid = false;
+ if (string.is8Bit()) {
+ const LChar* ptr = string.characters8();
+ const LChar* end = ptr + string.length();
+ valid = parse(ptr, end);
+ } else {
+ const UChar* ptr = string.characters16();
+ const UChar* end = ptr + string.length();
+ valid = parse(ptr, end);
+ }
+
+ if (!valid) {
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
+ m_value = 0;
+ }
+}
+
+void SVGNumber::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ setValue(m_value + toSVGNumber(other)->value());
+}
+
+void SVGNumber::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDuration, SVGElement*)
+{
+ ASSERT(animationElement);
+
+ RefPtr<SVGNumber> fromNumber = toSVGNumber(from);
+ RefPtr<SVGNumber> toNumber = toSVGNumber(to);
+ RefPtr<SVGNumber> toAtEndOfDurationNumber = toSVGNumber(toAtEndOfDuration);
+
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromNumber->value(), toNumber->value(), toAtEndOfDurationNumber->value(), m_value);
+}
+
+float SVGNumber::calculateDistance(PassRefPtr<SVGPropertyBase> other, SVGElement*)
+{
+ return fabsf(m_value - toSVGNumber(other)->value());
+}
+
+PassRefPtr<SVGNumber> SVGNumberAcceptPercentage::clone() const
+{
+ return create(m_value);
+}
+
+void SVGNumberAcceptPercentage::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+ bool valid = parseNumberOrPercentage(string, m_value);
+
+ if (!valid) {
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
+ m_value = 0;
+ }
+}
+
+SVGNumberAcceptPercentage::SVGNumberAcceptPercentage(float value)
+ : SVGNumber(value)
+{
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumber.h b/chromium/third_party/WebKit/Source/core/svg/SVGNumber.h
index db47ed0dfb2..04f798cd710 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGNumber.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumber.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -31,44 +31,72 @@
#ifndef SVGNumber_h
#define SVGNumber_h
-#include "core/svg/properties/SVGPropertyTraits.h"
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/svg/properties/SVGProperty.h"
namespace WebCore {
-class SVGNumber {
- WTF_MAKE_FAST_ALLOCATED;
+class SVGNumberTearOff;
+
+class SVGNumber : public SVGPropertyBase {
public:
- SVGNumber()
- : m_value(0)
- {
- }
+ // SVGNumber has a tear-off type, but SVGAnimatedNumber uses primitive type.
+ typedef SVGNumberTearOff TearOffType;
+ typedef float PrimitiveType;
- SVGNumber(float value)
- : m_value(value)
+ static PassRefPtr<SVGNumber> create(float value = 0.0f)
{
+ return adoptRef(new SVGNumber(value));
}
- SVGNumber& operator+=(const SVGNumber& rhs)
- {
- m_value += rhs.value();
- return *this;
- }
+ virtual PassRefPtr<SVGNumber> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
float value() const { return m_value; }
- float& valueRef() { return m_value; }
- String valueAsString() const { return String::number(m_value); }
void setValue(float value) { m_value = value; }
-private:
+ virtual String valueAsString() const OVERRIDE;
+ virtual void setValueAsString(const String&, ExceptionState&);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedNumber; }
+
+protected:
+ explicit SVGNumber(float);
+
+ template<typename CharType>
+ bool parse(const CharType*& ptr, const CharType* end);
+
float m_value;
};
-COMPILE_ASSERT(sizeof(SVGNumber) == sizeof(float), SVGNumber_same_size_as_float);
+inline PassRefPtr<SVGNumber> toSVGNumber(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGNumber::classType());
+ return static_pointer_cast<SVGNumber>(base.release());
+}
+
+// SVGNumber which also accepts percentage as its value.
+// This is used for <stop> "offset"
+// Spec: http://www.w3.org/TR/SVG11/pservers.html#GradientStops
+// offset = "<number> | <percentage>"
+class SVGNumberAcceptPercentage FINAL : public SVGNumber {
+public:
+ static PassRefPtr<SVGNumberAcceptPercentage> create(float value = 0)
+ {
+ return adoptRef(new SVGNumberAcceptPercentage(value));
+ }
+
+ virtual PassRefPtr<SVGNumber> clone() const OVERRIDE;
+ virtual void setValueAsString(const String&, ExceptionState&) OVERRIDE;
-template<>
-struct SVGPropertyTraits<SVGNumber> {
- static SVGNumber initialValue() { return SVGNumber(); }
- static String toString(const SVGNumber& type) { return type.valueAsString(); }
+private:
+ SVGNumberAcceptPercentage(float value);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumber.idl b/chromium/third_party/WebKit/Source/core/svg/SVGNumber.idl
index c77bbc90351..53ac71b15f6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGNumber.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumber.idl
@@ -20,7 +20,11 @@
* Boston, MA 02110-1301, USA.
*/
-interface SVGNumber {
- [StrictTypeChecking] attribute float value;
+[
+ ImplementedAs=SVGNumberTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGNumber {
+ [RaisesException=Setter] attribute float value;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.cpp
index 94934d17e55..88b912715b7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.cpp
@@ -21,52 +21,182 @@
#include "config.h"
#include "core/svg/SVGNumberList.h"
+#include "core/svg/SVGAnimationElement.h"
#include "core/svg/SVGParserUtilities.h"
#include "wtf/text/StringBuilder.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
-template<typename CharType>
-void SVGNumberList::parseInternal(const CharType*& ptr, const CharType* end)
+inline PassRefPtr<SVGNumberList> toSVGNumberList(PassRefPtr<SVGPropertyBase> passBase)
{
- // The spec strangely doesn't allow leading whitespace. We might choose to violate that intentionally. (section 4.1)
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGNumberList::classType());
+ return static_pointer_cast<SVGNumberList>(base.release());
+}
+
+SVGNumberList::SVGNumberList()
+{
+}
+
+SVGNumberList::~SVGNumberList()
+{
+}
+
+PassRefPtr<SVGNumberList> SVGNumberList::clone()
+{
+ RefPtr<SVGNumberList> svgNumberList = SVGNumberList::create();
+ svgNumberList->deepCopy(this);
+ return svgNumberList.release();
+}
+
+PassRefPtr<SVGPropertyBase> SVGNumberList::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGNumberList> svgNumberList = SVGNumberList::create();
+ svgNumberList->setValueAsString(value, IGNORE_EXCEPTION);
+ return svgNumberList.release();
+}
+
+String SVGNumberList::valueAsString() const
+{
+ StringBuilder builder;
+
+ ConstIterator it = begin();
+ ConstIterator itEnd = end();
+ if (it != itEnd) {
+ builder.append(it->valueAsString());
+ ++it;
+
+ for (; it != itEnd; ++it) {
+ builder.append(' ');
+ builder.append(it->valueAsString());
+ }
+ }
+
+ return builder.toString();
+}
+
+template <typename CharType>
+bool SVGNumberList::parse(const CharType*& ptr, const CharType* end)
+{
+ clear();
+
while (ptr < end) {
float number = 0;
if (!parseNumber(ptr, end, number))
- return;
- append(number);
+ return false;
+ append(SVGNumber::create(number));
}
+
+ return true;
}
-void SVGNumberList::parse(const String& value)
+void SVGNumberList::setValueAsString(const String& value, ExceptionState& exceptionState)
{
- clear();
- if (value.isEmpty())
+ if (value.isEmpty()) {
+ clear();
return;
+ }
+
+ bool valid = false;
if (value.is8Bit()) {
const LChar* ptr = value.characters8();
const LChar* end = ptr + value.length();
- parseInternal(ptr, end);
+ valid = parse(ptr, end);
} else {
const UChar* ptr = value.characters16();
const UChar* end = ptr + value.length();
- parseInternal(ptr, end);
+ valid = parse(ptr, end);
+ }
+
+ if (!valid) {
+ exceptionState.throwDOMException(SyntaxError, "Problem parsing number list \""+value+"\"");
+ // No call to |clear()| here. SVG policy is to use valid items before error.
+ // Spec: http://www.w3.org/TR/SVG/single-page.html#implnote-ErrorProcessing
}
}
-String SVGNumberList::valueAsString() const
+void SVGNumberList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement* contextElement)
{
- StringBuilder builder;
+ RefPtr<SVGNumberList> otherList = toSVGNumberList(other);
- unsigned size = this->size();
- for (unsigned i = 0; i < size; ++i) {
- if (i > 0)
- builder.append(' ');
+ if (length() != otherList->length())
+ return;
+
+ for (size_t i = 0; i < length(); ++i)
+ at(i)->setValue(at(i)->value() + otherList->at(i)->value());
+}
+
+bool SVGNumberList::adjustFromToListValues(PassRefPtr<SVGNumberList> passFromList, PassRefPtr<SVGNumberList> passToList, float percentage, bool isToAnimation, bool resizeAnimatedListIfNeeded)
+{
+ RefPtr<SVGNumberList> fromList = passFromList;
+ RefPtr<SVGNumberList> toList = passToList;
+
+ // If no 'to' value is given, nothing to animate.
+ size_t toListSize = toList->length();
+ if (!toListSize)
+ return false;
- builder.append(at(i).valueAsString());
+ // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
+ size_t fromListSize = fromList->length();
+ if (fromListSize != toListSize && fromListSize) {
+ if (percentage < 0.5) {
+ if (!isToAnimation)
+ deepCopy(fromList);
+ } else {
+ deepCopy(toList);
+ }
+
+ return false;
}
- return builder.toString();
+ ASSERT(!fromListSize || fromListSize == toListSize);
+ if (resizeAnimatedListIfNeeded && length() < toListSize) {
+ size_t paddingCount = toListSize - length();
+ for (size_t i = 0; i < paddingCount; ++i)
+ append(SVGNumber::create());
+ }
+
+ return true;
+}
+
+void SVGNumberList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+{
+ RefPtr<SVGNumberList> fromList = toSVGNumberList(fromValue);
+ RefPtr<SVGNumberList> toList = toSVGNumberList(toValue);
+ RefPtr<SVGNumberList> toAtEndOfDurationList = toSVGNumberList(toAtEndOfDurationValue);
+
+ size_t fromListSize = fromList->length();
+ size_t toListSize = toList->length();
+ size_t toAtEndOfDurationListSize = toAtEndOfDurationList->length();
+
+ if (!adjustFromToListValues(fromList, toList, percentage, animationElement->animationMode() == ToAnimation, true))
+ return;
+
+ for (size_t i = 0; i < toListSize; ++i) {
+ float effectiveFrom = fromListSize ? fromList->at(i)->value() : 0;
+ float effectiveTo = toListSize ? toList->at(i)->value() : 0;
+ float effectiveToAtEnd = i < toAtEndOfDurationListSize ? toAtEndOfDurationList->at(i)->value() : 0;
+
+ float animated = at(i)->value();
+ animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom, effectiveTo, effectiveToAtEnd, animated);
+ at(i)->setValue(animated);
+ }
+}
+
+float SVGNumberList::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*)
+{
+ // FIXME: Distance calculation is not possible for SVGNumberList right now. We need the distance for every single value.
+ return -1;
+}
+
+Vector<float> SVGNumberList::toFloatVector() const
+{
+ Vector<float> vec;
+ vec.reserveInitialCapacity(length());
+ for (size_t i = 0; i < length(); ++i)
+ vec.uncheckedAppend(at(i)->value());
+ return vec;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.h b/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.h
index 0b12d5d199b..2dfdf31dee4 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.h
@@ -1,61 +1,80 @@
/*
- * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGNumberList_h
#define SVGNumberList_h
+#include "bindings/v8/ScriptWrappable.h"
#include "core/svg/SVGNumber.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/Vector.h"
+#include "core/svg/properties/SVGListPropertyHelper.h"
namespace WebCore {
-class SVGNumberList : public Vector<SVGNumber> {
-public:
- SVGNumberList() { }
+class SVGNumberListTearOff;
- void parse(const String&);
- String valueAsString() const;
+class SVGNumberList FINAL : public SVGListPropertyHelper<SVGNumberList, SVGNumber> {
+public:
+ typedef SVGNumberListTearOff TearOffType;
- Vector<float> toFloatVector() const
+ static PassRefPtr<SVGNumberList> create()
{
- Vector<float> result;
- result.reserveInitialCapacity(size());
- for (size_t i = 0; i < size(); ++i)
- result.uncheckedAppend(at(i).value());
- return result;
+ return adoptRef(new SVGNumberList());
}
+ virtual ~SVGNumberList();
+
+ PassRefPtr<SVGNumberList> clone();
+
+ void setValueAsString(const String&, ExceptionState&);
+
+ // SVGPropertyBase:
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+ virtual String valueAsString() const OVERRIDE;
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedNumberList; }
+
+ Vector<float> toFloatVector() const;
+
private:
- template<typename CharType>
- void parseInternal(const CharType*& ptr, const CharType* end);
-};
+ SVGNumberList();
-template<>
-struct SVGPropertyTraits<SVGNumberList> {
- typedef SVGNumber ListItemType;
+ bool adjustFromToListValues(PassRefPtr<SVGNumberList> fromList, PassRefPtr<SVGNumberList> toList, float percentage, bool isToAnimation, bool resizeAnimatedListIfNeeded);
- static SVGNumberList initialValue() { return SVGNumberList(); }
- static String toString(const SVGNumberList& type) { return type.valueAsString(); }
+ template <typename CharType>
+ bool parse(const CharType*& ptr, const CharType* end);
};
} // namespace WebCore
-#endif
+#endif // SVGNumberList_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.idl
index 4711cc66379..e5cf2fe22f1 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumberList.idl
@@ -24,15 +24,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGNumberList {
- readonly attribute unsigned long numberOfItems;
+[
+ ImplementedAs=SVGNumberListTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGNumberList {
+ readonly attribute unsigned long length;
+ [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
[RaisesException] void clear();
- [StrictTypeChecking, RaisesException] SVGNumber initialize(SVGNumber item);
- [StrictTypeChecking, RaisesException] SVGNumber getItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGNumber insertItemBefore(SVGNumber item, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGNumber replaceItem(SVGNumber item, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGNumber removeItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGNumber appendItem(SVGNumber item);
+ [RaisesException] SVGNumber initialize(SVGNumber item);
+ [RaisesException] getter SVGNumber getItem(unsigned long index);
+ [RaisesException] setter SVGNumber (unsigned long index, SVGNumber value);
+ [RaisesException] SVGNumber insertItemBefore(SVGNumber item, unsigned long index);
+ [RaisesException] SVGNumber replaceItem(SVGNumber item, unsigned long index);
+ [RaisesException] SVGNumber removeItem(unsigned long index);
+ [RaisesException] SVGNumber appendItem(SVGNumber item);
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumberListTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGNumberListTearOff.h
new file mode 100644
index 00000000000..e316d003f2f
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumberListTearOff.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGNumberListTearOff_h
+#define SVGNumberListTearOff_h
+
+#include "core/svg/SVGNumberList.h"
+#include "core/svg/properties/SVGListPropertyTearOffHelper.h"
+
+namespace WebCore {
+
+class SVGNumberListTearOff FINAL :
+ public SVGListPropertyTearOffHelper<SVGNumberListTearOff, SVGNumberList>,
+ public ScriptWrappable {
+public:
+ static PassRefPtr<SVGNumberListTearOff> create(PassRefPtr<SVGNumberList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGNumberListTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+private:
+ SVGNumberListTearOff(PassRefPtr<SVGNumberList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ : SVGListPropertyTearOffHelper<SVGNumberListTearOff, SVGNumberList>(target, contextElement, propertyIsAnimVal, attributeName)
+ {
+ ScriptWrappable::init(this);
+ }
+};
+
+} // namespace WebCore
+
+#endif // SVGNumberListTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp
new file mode 100644
index 00000000000..36ff0ca0387
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGNumberOptionalNumber.h"
+
+#include "core/svg/SVGAnimationElement.h"
+#include "core/svg/SVGParserUtilities.h"
+
+namespace WebCore {
+
+SVGNumberOptionalNumber::SVGNumberOptionalNumber(PassRefPtr<SVGNumber> firstNumber, PassRefPtr<SVGNumber> secondNumber)
+ : SVGPropertyBase(classType())
+ , m_firstNumber(firstNumber)
+ , m_secondNumber(secondNumber)
+{
+}
+
+PassRefPtr<SVGNumberOptionalNumber> SVGNumberOptionalNumber::clone() const
+{
+ return SVGNumberOptionalNumber::create(m_firstNumber->clone(), m_secondNumber->clone());
+}
+
+PassRefPtr<SVGPropertyBase> SVGNumberOptionalNumber::cloneForAnimation(const String& value) const
+{
+ float x, y;
+ if (!parseNumberOptionalNumber(value, x, y)) {
+ x = y = 0;
+ }
+
+ return SVGNumberOptionalNumber::create(SVGNumber::create(x), SVGNumber::create(y));
+}
+
+String SVGNumberOptionalNumber::valueAsString() const
+{
+ if (m_firstNumber->value() == m_secondNumber->value()) {
+ return String::number(m_firstNumber->value());
+ }
+
+ return String::number(m_firstNumber->value()) + " " + String::number(m_secondNumber->value());
+}
+
+void SVGNumberOptionalNumber::setValueAsString(const String& value, ExceptionState& exceptionState)
+{
+ float x, y;
+ if (!parseNumberOptionalNumber(value, x, y)) {
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + value + "') is invalid.");
+ x = y = 0;
+ }
+
+ m_firstNumber->setValue(x);
+ m_secondNumber->setValue(y);
+}
+
+void SVGNumberOptionalNumber::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ RefPtr<SVGNumberOptionalNumber> otherNumberOptionalNumber = toSVGNumberOptionalNumber(other);
+
+ m_firstNumber->setValue(m_firstNumber->value() + otherNumberOptionalNumber->m_firstNumber->value());
+ m_secondNumber->setValue(m_secondNumber->value() + otherNumberOptionalNumber->m_secondNumber->value());
+}
+
+void SVGNumberOptionalNumber::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDuration, SVGElement*)
+{
+ ASSERT(animationElement);
+
+ RefPtr<SVGNumberOptionalNumber> fromNumber = toSVGNumberOptionalNumber(from);
+ RefPtr<SVGNumberOptionalNumber> toNumber = toSVGNumberOptionalNumber(to);
+ RefPtr<SVGNumberOptionalNumber> toAtEndOfDurationNumber = toSVGNumberOptionalNumber(toAtEndOfDuration);
+
+ float x = m_firstNumber->value();
+ float y = m_secondNumber->value();
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromNumber->firstNumber()->value(), toNumber->firstNumber()->value(), toAtEndOfDurationNumber->firstNumber()->value(), x);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromNumber->secondNumber()->value(), toNumber->secondNumber()->value(), toAtEndOfDurationNumber->secondNumber()->value(), y);
+ m_firstNumber->setValue(x);
+ m_secondNumber->setValue(y);
+}
+
+float SVGNumberOptionalNumber::calculateDistance(PassRefPtr<SVGPropertyBase> other, SVGElement*)
+{
+ // FIXME: Distance calculation is not possible for SVGNumberOptionalNumber right now. We need the distance for every single value.
+ return -1;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.h b/chromium/third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.h
new file mode 100644
index 00000000000..50eeec05daa
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGNumberOptionalNumber_h
+#define SVGNumberOptionalNumber_h
+
+#include "core/svg/SVGAnimatedNumber.h"
+
+namespace WebCore {
+
+class SVGNumberOptionalNumber : public SVGPropertyBase {
+public:
+ // Tearoff of SVGNumberOptionalNumber is never created.
+ typedef void TearOffType;
+ typedef void PrimitiveType;
+
+ static PassRefPtr<SVGNumberOptionalNumber> create(PassRefPtr<SVGNumber> firstNumber, PassRefPtr<SVGNumber> secondNumber)
+ {
+ return adoptRef(new SVGNumberOptionalNumber(firstNumber, secondNumber));
+ }
+
+ PassRefPtr<SVGNumberOptionalNumber> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+ virtual String valueAsString() const OVERRIDE;
+ void setValueAsString(const String&, ExceptionState&);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedNumberOptionalNumber; }
+
+ PassRefPtr<SVGNumber> firstNumber() { return m_firstNumber; }
+ PassRefPtr<SVGNumber> secondNumber() { return m_secondNumber; }
+
+protected:
+ SVGNumberOptionalNumber(PassRefPtr<SVGNumber> firstNumber, PassRefPtr<SVGNumber> secondNumber);
+
+ RefPtr<SVGNumber> m_firstNumber;
+ RefPtr<SVGNumber> m_secondNumber;
+};
+
+inline PassRefPtr<SVGNumberOptionalNumber> toSVGNumberOptionalNumber(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGNumberOptionalNumber::classType());
+ return static_pointer_cast<SVGNumberOptionalNumber>(base.release());
+}
+
+} // namespace WebCore
+
+#endif // SVGNumberOptionalNumber_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp
new file mode 100644
index 00000000000..08752a4cfd7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGNumberTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+SVGNumberTearOff::SVGNumberTearOff(PassRefPtr<SVGNumber> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ : SVGPropertyTearOff<SVGNumber>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+void SVGNumberTearOff::setValue(float f, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setValue(f);
+ commitChange();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGNumberTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGNumberTearOff.h
new file mode 100644
index 00000000000..b3f95824080
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGNumberTearOff.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGNumberTearOff_h
+#define SVGNumberTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGNumber.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGNumberTearOff : public SVGPropertyTearOff<SVGNumber>, public ScriptWrappable {
+public:
+ static PassRefPtr<SVGNumberTearOff> create(PassRefPtr<SVGNumber> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGNumberTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ void setValue(float, ExceptionState&);
+ float value() { return target()->value(); }
+
+protected:
+ SVGNumberTearOff(PassRefPtr<SVGNumber>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName = QualifiedName::null());
+};
+
+} // namespace WebCore
+
+#endif // SVGNumberTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPaint.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPaint.cpp
index 8aa13ae372b..42ff9b5b1a7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPaint.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPaint.cpp
@@ -22,70 +22,39 @@
#include "config.h"
#include "core/svg/SVGPaint.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/css/RGBColor.h"
+#include "core/css/parser/BisonCSSParser.h"
namespace WebCore {
-static inline SVGColor::SVGColorType colorTypeForPaintType(const SVGPaint::SVGPaintType& paintType)
-{
- switch (paintType) {
- case SVGPaint::SVG_PAINTTYPE_NONE:
- case SVGPaint::SVG_PAINTTYPE_UNKNOWN:
- case SVGPaint::SVG_PAINTTYPE_URI:
- case SVGPaint::SVG_PAINTTYPE_URI_NONE:
- return SVGColor::SVG_COLORTYPE_UNKNOWN;
- case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR:
- case SVGPaint::SVG_PAINTTYPE_RGBCOLOR:
- return SVGColor::SVG_COLORTYPE_RGBCOLOR;
- case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
- case SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
- return SVGColor::SVG_COLORTYPE_RGBCOLOR_ICCCOLOR;
- case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR:
- case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR:
- return SVGColor::SVG_COLORTYPE_CURRENTCOLOR;
- }
-
- ASSERT_NOT_REACHED();
- return SVGColor::SVG_COLORTYPE_UNKNOWN;
-}
-
SVGPaint::SVGPaint(const SVGPaintType& paintType, const String& uri)
- : SVGColor(SVGPaintClass, colorTypeForPaintType(paintType))
+ : CSSValue(SVGPaintClass)
, m_paintType(paintType)
, m_uri(uri)
{
}
-void SVGPaint::setUri(const String&)
-{
- // The whole SVGPaint interface is deprecated in SVG 1.1 (2nd edition).
- // The setters are the most problematic part so we remove the support for those first.
-}
-
-void SVGPaint::setPaint(unsigned short, const String&, const String&, const String&, ExceptionState& exceptionState)
-{
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
-}
-
String SVGPaint::customCSSText() const
{
switch (m_paintType) {
case SVG_PAINTTYPE_UNKNOWN:
+ return String();
case SVG_PAINTTYPE_RGBCOLOR:
case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
+ return m_color.serializedAsCSSComponentValue();
case SVG_PAINTTYPE_CURRENTCOLOR:
- return SVGColor::customCSSText();
+ return "currentColor";
case SVG_PAINTTYPE_NONE:
return "none";
case SVG_PAINTTYPE_URI_NONE:
return m_uri + " none";
case SVG_PAINTTYPE_URI_CURRENTCOLOR:
+ return "url(" + m_uri + ") currentColor";
case SVG_PAINTTYPE_URI_RGBCOLOR:
case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: {
- String color = SVGColor::customCSSText();
- if (color.isEmpty())
- return m_uri;
- return "url(" + m_uri + ") " + color;
+ return "url(" + m_uri + ") " + m_color.serializedAsCSSComponentValue();
}
case SVG_PAINTTYPE_URI:
return "url(" + m_uri + ')';
@@ -96,20 +65,31 @@ String SVGPaint::customCSSText() const
}
SVGPaint::SVGPaint(const SVGPaint& cloneFrom)
- : SVGColor(SVGPaintClass, cloneFrom)
+ : CSSValue(SVGPaintClass, /*isCSSOMSafe*/ true)
, m_paintType(cloneFrom.m_paintType)
+ , m_color(cloneFrom.m_color)
, m_uri(cloneFrom.m_uri)
{
}
-PassRefPtr<SVGPaint> SVGPaint::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<SVGPaint> SVGPaint::cloneForCSSOM() const
{
- return adoptRef(new SVGPaint(*this));
+ return adoptRefWillBeNoop(new SVGPaint(*this));
}
bool SVGPaint::equals(const SVGPaint& other) const
{
- return m_paintType == other.m_paintType && m_uri == other.m_uri && SVGColor::equals(other);
+ return m_paintType == other.m_paintType && m_uri == other.m_uri && m_color == other.m_color;
+}
+
+StyleColor SVGPaint::colorFromRGBColorString(const String& colorString)
+{
+ // FIXME: Rework css parser so it is more SVG aware.
+ RGBA32 color;
+ if (BisonCSSParser::parseColor(color, colorString.stripWhiteSpace()))
+ return StyleColor(color);
+ // FIXME: This branch catches the string currentColor, but we should error if we have an illegal color value.
+ return StyleColor::currentColor();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPaint.h b/chromium/third_party/WebKit/Source/core/svg/SVGPaint.h
index f48b4b7ba07..cf54b43d32e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPaint.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPaint.h
@@ -23,88 +23,98 @@
#ifndef SVGPaint_h
#define SVGPaint_h
-#include "core/svg/SVGColor.h"
+#include "core/css/CSSValue.h"
+#include "core/css/StyleColor.h"
+#include "platform/graphics/Color.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class ExceptionState;
-
-class SVGPaint : public SVGColor {
+class SVGPaint : public CSSValue {
public:
enum SVGPaintType {
- SVG_PAINTTYPE_UNKNOWN = 0,
- SVG_PAINTTYPE_RGBCOLOR = 1,
- SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2,
- SVG_PAINTTYPE_NONE = 101,
- SVG_PAINTTYPE_CURRENTCOLOR = 102,
- SVG_PAINTTYPE_URI_NONE = 103,
- SVG_PAINTTYPE_URI_CURRENTCOLOR = 104,
- SVG_PAINTTYPE_URI_RGBCOLOR = 105,
- SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR = 106,
- SVG_PAINTTYPE_URI = 107
+ SVG_PAINTTYPE_UNKNOWN,
+ SVG_PAINTTYPE_RGBCOLOR,
+ SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR,
+ SVG_PAINTTYPE_NONE,
+ SVG_PAINTTYPE_CURRENTCOLOR,
+ SVG_PAINTTYPE_URI_NONE,
+ SVG_PAINTTYPE_URI_CURRENTCOLOR,
+ SVG_PAINTTYPE_URI_RGBCOLOR,
+ SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR,
+ SVG_PAINTTYPE_URI
};
- static PassRefPtr<SVGPaint> createUnknown()
+ static PassRefPtrWillBeRawPtr<SVGPaint> createUnknown()
{
- return adoptRef(new SVGPaint(SVG_PAINTTYPE_UNKNOWN));
+ return adoptRefWillBeNoop(new SVGPaint(SVG_PAINTTYPE_UNKNOWN));
}
- static PassRefPtr<SVGPaint> createNone()
+ static PassRefPtrWillBeRawPtr<SVGPaint> createNone()
{
- return adoptRef(new SVGPaint(SVG_PAINTTYPE_NONE));
+ return adoptRefWillBeNoop(new SVGPaint(SVG_PAINTTYPE_NONE));
}
- static PassRefPtr<SVGPaint> createCurrentColor()
+ static PassRefPtrWillBeRawPtr<SVGPaint> createCurrentColor()
{
- return adoptRef(new SVGPaint(SVG_PAINTTYPE_CURRENTCOLOR));
+ return adoptRefWillBeNoop(new SVGPaint(SVG_PAINTTYPE_CURRENTCOLOR));
+ }
+
+ static PassRefPtrWillBeRawPtr<SVGPaint> createColor(const Color& color)
+ {
+ RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeNoop(new SVGPaint(SVG_PAINTTYPE_RGBCOLOR));
+ paint->m_color = color;
+ return paint.release();
}
- static PassRefPtr<SVGPaint> createColor(const Color& color)
+ static PassRefPtrWillBeRawPtr<SVGPaint> createURI(const String& uri)
{
- RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_RGBCOLOR));
- paint->setColor(color);
+ RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeNoop(new SVGPaint(SVG_PAINTTYPE_URI, uri));
return paint.release();
}
- static PassRefPtr<SVGPaint> createURI(const String& uri)
+ static PassRefPtrWillBeRawPtr<SVGPaint> createURIAndColor(const String& uri, const Color& color)
{
- RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_URI, uri));
+ RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeNoop(new SVGPaint(SVG_PAINTTYPE_URI_RGBCOLOR, uri));
+ paint->m_color = color;
return paint.release();
}
- static PassRefPtr<SVGPaint> createURIAndColor(const String& uri, const Color& color)
+ static PassRefPtrWillBeRawPtr<SVGPaint> createURIAndNone(const String& uri)
{
- RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_URI_RGBCOLOR, uri));
- paint->setColor(color);
+ RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeNoop(new SVGPaint(SVG_PAINTTYPE_URI_NONE, uri));
return paint.release();
}
- static PassRefPtr<SVGPaint> createURIAndNone(const String& uri)
+ static PassRefPtrWillBeRawPtr<SVGPaint> createURIAndCurrentColor(const String& uri)
{
- RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(SVG_PAINTTYPE_URI_NONE, uri));
+ RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeNoop(new SVGPaint(SVG_PAINTTYPE_URI_CURRENTCOLOR, uri));
return paint.release();
}
const SVGPaintType& paintType() const { return m_paintType; }
String uri() const { return m_uri; }
- void setUri(const String&);
- void setPaint(unsigned short paintType, const String& uri, const String& rgbColor, const String& iccColor, ExceptionState&);
-
String customCSSText() const;
- PassRefPtr<SVGPaint> cloneForCSSOM() const;
+ PassRefPtrWillBeRawPtr<SVGPaint> cloneForCSSOM() const;
bool equals(const SVGPaint&) const;
+ void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
+ Color color() const { return m_color; }
+ void setColor(const Color& color) { m_color = color; m_paintType = SVG_PAINTTYPE_RGBCOLOR; }
+
+ static StyleColor colorFromRGBColorString(const String&);
+
private:
friend class CSSComputedStyleDeclaration;
- static PassRefPtr<SVGPaint> create(const SVGPaintType& type, const String& uri, const Color& color)
+ static PassRefPtrWillBeRawPtr<SVGPaint> create(const SVGPaintType& type, const String& uri, const Color& color)
{
- RefPtr<SVGPaint> paint = adoptRef(new SVGPaint(type, uri));
- paint->setColor(color);
+ RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeNoop(new SVGPaint(type, uri));
+ paint->m_color = color;
return paint.release();
}
@@ -113,6 +123,7 @@ private:
SVGPaint(const SVGPaint& cloneFrom);
SVGPaintType m_paintType;
+ Color m_color;
String m_uri;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPaint.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPaint.idl
deleted file mode 100644
index 8c1badb3554..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPaint.idl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-interface SVGPaint : SVGColor {
- const unsigned short SVG_PAINTTYPE_UNKNOWN = 0;
- const unsigned short SVG_PAINTTYPE_RGBCOLOR = 1;
- const unsigned short SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR = 2;
- const unsigned short SVG_PAINTTYPE_NONE = 101;
- const unsigned short SVG_PAINTTYPE_CURRENTCOLOR = 102;
- const unsigned short SVG_PAINTTYPE_URI_NONE = 103;
- const unsigned short SVG_PAINTTYPE_URI_CURRENTCOLOR = 104;
- const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR = 105;
- const unsigned short SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR = 106;
- const unsigned short SVG_PAINTTYPE_URI = 107;
-
- readonly attribute unsigned short paintType;
- readonly attribute DOMString uri;
-
- [StrictTypeChecking] void setUri(DOMString uri);
- [StrictTypeChecking, RaisesException] void setPaint(unsigned short paintType, DOMString uri, DOMString rgbColor, DOMString iccColor);
-};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.cpp
index 262ef622f91..897c9e60ec0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.cpp
@@ -25,7 +25,6 @@
#include "core/dom/Document.h"
#include "core/svg/SVGPointList.h"
-#include "core/svg/SVGTransformList.h"
#include "platform/geometry/FloatRect.h"
#include "platform/transforms/AffineTransform.h"
#include "wtf/ASCIICType.h"
@@ -44,7 +43,7 @@ static inline bool isValidRange(const FloatType& x)
// at a higher precision internally, without any unnecessary runtime cost or code
// complexity.
template <typename CharType, typename FloatType>
-static bool genericParseNumber(const CharType*& ptr, const CharType* end, FloatType& number, bool skip)
+static bool genericParseNumber(const CharType*& ptr, const CharType* end, FloatType& number, WhitespaceMode mode)
{
FloatType integer, decimal, frac, exponent;
int sign, expsign;
@@ -57,6 +56,9 @@ static bool genericParseNumber(const CharType*& ptr, const CharType* end, FloatT
sign = 1;
expsign = 1;
+ if (mode & AllowLeadingWhitespace)
+ skipOptionalSVGSpaces(ptr, end);
+
// read the sign
if (ptr < end && *ptr == '+')
ptr++;
@@ -137,7 +139,7 @@ static bool genericParseNumber(const CharType*& ptr, const CharType* end, FloatT
if (start == ptr)
return false;
- if (skip)
+ if (mode & AllowTrailingWhitespace)
skipOptionalSVGSpacesOrDelimiter(ptr, end);
return true;
@@ -148,35 +150,21 @@ bool parseSVGNumber(CharType* begin, size_t length, double& number)
{
const CharType* ptr = begin;
const CharType* end = ptr + length;
- return genericParseNumber(ptr, end, number, false);
+ return genericParseNumber(ptr, end, number, AllowLeadingAndTrailingWhitespace);
}
// Explicitly instantiate the two flavors of parseSVGNumber() to satisfy external callers
template bool parseSVGNumber(LChar* begin, size_t length, double&);
template bool parseSVGNumber(UChar* begin, size_t length, double&);
-bool parseNumber(const LChar*& ptr, const LChar* end, float& number, bool skip)
+bool parseNumber(const LChar*& ptr, const LChar* end, float& number, WhitespaceMode mode)
{
- return genericParseNumber(ptr, end, number, skip);
+ return genericParseNumber(ptr, end, number, mode);
}
-bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip)
+bool parseNumber(const UChar*& ptr, const UChar* end, float& number, WhitespaceMode mode)
{
- return genericParseNumber(ptr, end, number, skip);
-}
-
-bool parseNumberFromString(const String& string, float& number, bool skip)
-{
- if (string.isEmpty())
- return false;
- if (string.is8Bit()) {
- const LChar* ptr = string.characters8();
- const LChar* end = ptr + string.length();
- return genericParseNumber(ptr, end, number, skip) && ptr == end;
- }
- const UChar* ptr = string.characters16();
- const UChar* end = ptr + string.length();
- return genericParseNumber(ptr, end, number, skip) && ptr == end;
+ return genericParseNumber(ptr, end, number, mode);
}
// only used to parse largeArcFlag and sweepFlag which must be a "0" or "1"
@@ -217,7 +205,7 @@ static bool genericParseNumberOptionalNumber(const CharType*& ptr, const CharTyp
if (ptr == end)
y = x;
- else if (!parseNumber(ptr, end, y, false))
+ else if (!parseNumber(ptr, end, y, AllowLeadingAndTrailingWhitespace))
return false;
return ptr == end;
@@ -227,6 +215,7 @@ bool parseNumberOptionalNumber(const String& string, float& x, float& y)
{
if (string.isEmpty())
return false;
+
if (string.is8Bit()) {
const LChar* ptr = string.characters8();
const LChar* end = ptr + string.length();
@@ -238,75 +227,40 @@ bool parseNumberOptionalNumber(const String& string, float& x, float& y)
}
template<typename CharType>
-static bool genericParseRect(const CharType*& ptr, const CharType* end, FloatRect& rect)
+bool genericParseNumberOrPercentage(const CharType*& ptr, const CharType* end, float& number)
{
- skipOptionalSVGSpaces(ptr, end);
+ if (genericParseNumber(ptr, end, number, AllowLeadingWhitespace)) {
+ if (ptr == end)
+ return true;
- float x = 0;
- float y = 0;
- float width = 0;
- float height = 0;
- bool valid = parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, false);
- rect = FloatRect(x, y, width, height);
- return valid;
+ bool isPercentage = (*ptr == '%');
+ if (isPercentage)
+ ptr++;
+
+ skipOptionalSVGSpaces(ptr, end);
+
+ if (isPercentage)
+ number /= 100.f;
+
+ return ptr == end;
+ }
+
+ return false;
}
-bool parseRect(const String& string, FloatRect& rect)
+bool parseNumberOrPercentage(const String& string, float& number)
{
if (string.isEmpty())
return false;
+
if (string.is8Bit()) {
const LChar* ptr = string.characters8();
const LChar* end = ptr + string.length();
- return genericParseRect(ptr, end, rect);
+ return genericParseNumberOrPercentage(ptr, end, number);
}
const UChar* ptr = string.characters16();
const UChar* end = ptr + string.length();
- return genericParseRect(ptr, end, rect);
-}
-
-template<typename CharType>
-static bool genericParsePointsList(SVGPointList& pointsList, const CharType*& ptr, const CharType* end)
-{
- skipOptionalSVGSpaces(ptr, end);
-
- bool delimParsed = false;
- while (ptr < end) {
- delimParsed = false;
- float xPos = 0.0f;
- if (!parseNumber(ptr, end, xPos))
- return false;
-
- float yPos = 0.0f;
- if (!parseNumber(ptr, end, yPos, false))
- return false;
-
- skipOptionalSVGSpaces(ptr, end);
-
- if (ptr < end && *ptr == ',') {
- delimParsed = true;
- ptr++;
- }
- skipOptionalSVGSpaces(ptr, end);
-
- pointsList.append(FloatPoint(xPos, yPos));
- }
- return ptr == end && !delimParsed;
-}
-
-// FIXME: Why is the out parameter first?
-bool pointsListFromSVGData(SVGPointList& pointsList, const String& points)
-{
- if (points.isEmpty())
- return true;
- if (points.is8Bit()) {
- const LChar* ptr = points.characters8();
- const LChar* end = ptr + points.length();
- return genericParsePointsList(pointsList, ptr, end);
- }
- const UChar* ptr = points.characters16();
- const UChar* end = ptr + points.length();
- return genericParsePointsList(pointsList, ptr, end);
+ return genericParseNumberOrPercentage(ptr, end, number);
}
template<typename CharType>
@@ -325,7 +279,7 @@ static bool parseGlyphName(const CharType*& ptr, const CharType* end, HashSet<St
// walk backwards from the ; to ignore any whitespace
const CharType* inputEnd = ptr - 1;
- while (inputStart < inputEnd && isSVGSpace(*inputEnd))
+ while (inputStart < inputEnd && isHTMLSpace<CharType>(*inputEnd))
--inputEnd;
values.add(String(inputStart, inputEnd - inputStart + 1));
@@ -477,7 +431,7 @@ static Vector<String> genericParseDelimitedString(const CharType*& ptr, const Ch
// walk backwards from the ; to ignore any whitespace
const CharType* inputEnd = ptr - 1;
- while (inputStart < inputEnd && isSVGSpace(*inputEnd))
+ while (inputStart < inputEnd && isHTMLSpace<CharType>(*inputEnd))
inputEnd--;
values.append(String(inputStart, inputEnd - inputStart + 1));
@@ -561,117 +515,6 @@ bool parseFloatPoint3(const CharType*& current, const CharType* end, FloatPoint&
template bool parseFloatPoint3(const LChar*& current, const LChar* end, FloatPoint& point1, FloatPoint& point2, FloatPoint& point3);
template bool parseFloatPoint3(const UChar*& current, const UChar* end, FloatPoint& point1, FloatPoint& point2, FloatPoint& point3);
-template<typename CharType>
-static int parseTransformParamList(const CharType*& ptr, const CharType* end, float* values, int required, int optional)
-{
- int optionalParams = 0, requiredParams = 0;
-
- if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(')
- return -1;
-
- ptr++;
-
- skipOptionalSVGSpaces(ptr, end);
-
- while (requiredParams < required) {
- if (ptr >= end || !parseNumber(ptr, end, values[requiredParams], false))
- return -1;
- requiredParams++;
- if (requiredParams < required)
- skipOptionalSVGSpacesOrDelimiter(ptr, end);
- }
- if (!skipOptionalSVGSpaces(ptr, end))
- return -1;
-
- bool delimParsed = skipOptionalSVGSpacesOrDelimiter(ptr, end);
-
- if (ptr >= end)
- return -1;
-
- if (*ptr == ')') { // skip optionals
- ptr++;
- if (delimParsed)
- return -1;
- } else {
- while (optionalParams < optional) {
- if (ptr >= end || !parseNumber(ptr, end, values[requiredParams + optionalParams], false))
- return -1;
- optionalParams++;
- if (optionalParams < optional)
- skipOptionalSVGSpacesOrDelimiter(ptr, end);
- }
-
- if (!skipOptionalSVGSpaces(ptr, end))
- return -1;
-
- delimParsed = skipOptionalSVGSpacesOrDelimiter(ptr, end);
-
- if (ptr >= end || *ptr != ')' || delimParsed)
- return -1;
- ptr++;
- }
-
- return requiredParams + optionalParams;
-}
-
-// These should be kept in sync with enum SVGTransformType
-static const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1};
-static const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0};
-
-template<typename CharType>
-static bool parseTransformValueInternal(unsigned type, const CharType*& ptr, const CharType* end, SVGTransform& transform)
-{
- if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN)
- return false;
-
- int valueCount = 0;
- float values[] = {0, 0, 0, 0, 0, 0};
- if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesForType[type], optionalValuesForType[type])) < 0)
- return false;
-
- switch (type) {
- case SVGTransform::SVG_TRANSFORM_SKEWX:
- transform.setSkewX(values[0]);
- break;
- case SVGTransform::SVG_TRANSFORM_SKEWY:
- transform.setSkewY(values[0]);
- break;
- case SVGTransform::SVG_TRANSFORM_SCALE:
- if (valueCount == 1) // Spec: if only one param given, assume uniform scaling
- transform.setScale(values[0], values[0]);
- else
- transform.setScale(values[0], values[1]);
- break;
- case SVGTransform::SVG_TRANSFORM_TRANSLATE:
- if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0
- transform.setTranslate(values[0], 0);
- else
- transform.setTranslate(values[0], values[1]);
- break;
- case SVGTransform::SVG_TRANSFORM_ROTATE:
- if (valueCount == 1)
- transform.setRotate(values[0], 0, 0);
- else
- transform.setRotate(values[0], values[1], values[2]);
- break;
- case SVGTransform::SVG_TRANSFORM_MATRIX:
- transform.setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5]));
- break;
- }
-
- return true;
-}
-
-bool parseTransformValue(unsigned type, const LChar*& ptr, const LChar* end, SVGTransform& transform)
-{
- return parseTransformValueInternal(type, ptr, end, transform);
-}
-
-bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& transform)
-{
- return parseTransformValueInternal(type, ptr, end, transform);
-}
-
static const LChar skewXDesc[] = {'s', 'k', 'e', 'w', 'X'};
static const LChar skewYDesc[] = {'s', 'k', 'e', 'w', 'Y'};
static const LChar scaleDesc[] = {'s', 'c', 'a', 'l', 'e'};
@@ -680,88 +523,50 @@ static const LChar rotateDesc[] = {'r', 'o', 't', 'a', 't', 'e'};
static const LChar matrixDesc[] = {'m', 'a', 't', 'r', 'i', 'x'};
template<typename CharType>
-static inline bool parseAndSkipType(const CharType*& ptr, const CharType* end, unsigned short& type)
+bool parseAndSkipTransformType(const CharType*& ptr, const CharType* end, SVGTransformType& type)
{
if (ptr >= end)
return false;
if (*ptr == 's') {
if (skipString(ptr, end, skewXDesc, WTF_ARRAY_LENGTH(skewXDesc)))
- type = SVGTransform::SVG_TRANSFORM_SKEWX;
+ type = SVG_TRANSFORM_SKEWX;
else if (skipString(ptr, end, skewYDesc, WTF_ARRAY_LENGTH(skewYDesc)))
- type = SVGTransform::SVG_TRANSFORM_SKEWY;
+ type = SVG_TRANSFORM_SKEWY;
else if (skipString(ptr, end, scaleDesc, WTF_ARRAY_LENGTH(scaleDesc)))
- type = SVGTransform::SVG_TRANSFORM_SCALE;
+ type = SVG_TRANSFORM_SCALE;
else
return false;
} else if (skipString(ptr, end, translateDesc, WTF_ARRAY_LENGTH(translateDesc)))
- type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
+ type = SVG_TRANSFORM_TRANSLATE;
else if (skipString(ptr, end, rotateDesc, WTF_ARRAY_LENGTH(rotateDesc)))
- type = SVGTransform::SVG_TRANSFORM_ROTATE;
+ type = SVG_TRANSFORM_ROTATE;
else if (skipString(ptr, end, matrixDesc, WTF_ARRAY_LENGTH(matrixDesc)))
- type = SVGTransform::SVG_TRANSFORM_MATRIX;
+ type = SVG_TRANSFORM_MATRIX;
else
return false;
return true;
}
-SVGTransform::SVGTransformType parseTransformType(const String& string)
+template bool parseAndSkipTransformType(const UChar*& current, const UChar* end, SVGTransformType&);
+template bool parseAndSkipTransformType(const LChar*& current, const LChar* end, SVGTransformType&);
+
+SVGTransformType parseTransformType(const String& string)
{
if (string.isEmpty())
- return SVGTransform::SVG_TRANSFORM_UNKNOWN;
- unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
+ return SVG_TRANSFORM_UNKNOWN;
+ SVGTransformType type = SVG_TRANSFORM_UNKNOWN;
if (string.is8Bit()) {
const LChar* ptr = string.characters8();
const LChar* end = ptr + string.length();
- parseAndSkipType(ptr, end, type);
+ parseAndSkipTransformType(ptr, end, type);
} else {
const UChar* ptr = string.characters16();
const UChar* end = ptr + string.length();
- parseAndSkipType(ptr, end, type);
- }
- return static_cast<SVGTransform::SVGTransformType>(type);
-}
-
-template<typename CharType>
-bool parseTransformAttributeInternal(SVGTransformList& list, const CharType*& ptr, const CharType* end, TransformParsingMode mode)
-{
- if (mode == ClearList)
- list.clear();
-
- bool delimParsed = false;
- while (ptr < end) {
- delimParsed = false;
- unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
- skipOptionalSVGSpaces(ptr, end);
-
- if (!parseAndSkipType(ptr, end, type))
- return false;
-
- SVGTransform transform;
- if (!parseTransformValue(type, ptr, end, transform))
- return false;
-
- list.append(transform);
- skipOptionalSVGSpaces(ptr, end);
- if (ptr < end && *ptr == ',') {
- delimParsed = true;
- ++ptr;
- }
- skipOptionalSVGSpaces(ptr, end);
+ parseAndSkipTransformType(ptr, end, type);
}
-
- return !delimParsed;
-}
-
-bool parseTransformAttribute(SVGTransformList& list, const LChar*& ptr, const LChar* end, TransformParsingMode mode)
-{
- return parseTransformAttributeInternal(list, ptr, end, mode);
-}
-
-bool parseTransformAttribute(SVGTransformList& list, const UChar*& ptr, const UChar* end, TransformParsingMode mode)
-{
- return parseTransformAttributeInternal(list, ptr, end, mode);
+ return type;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.h b/chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.h
index 2946cf15cb7..3d591d47cbf 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGParserUtilities.h
@@ -22,6 +22,7 @@
#ifndef SVGParserUtilities_h
#define SVGParserUtilities_h
+#include "core/html/parser/HTMLParserIdioms.h"
#include "core/svg/SVGTransform.h"
#include "platform/text/ParserUtilities.h"
#include "wtf/HashSet.h"
@@ -32,19 +33,22 @@ typedef Vector<UnicodeRange> UnicodeRanges;
namespace WebCore {
class FloatPoint;
-class FloatRect;
-class SVGPointList;
-class SVGTransformList;
+
+enum WhitespaceMode {
+ DisallowWhitespace = 0,
+ AllowLeadingWhitespace = 0x1,
+ AllowTrailingWhitespace = 0x2,
+ AllowLeadingAndTrailingWhitespace = AllowLeadingWhitespace | AllowTrailingWhitespace
+};
template <typename CharType>
bool parseSVGNumber(CharType* ptr, size_t length, double& number);
-bool parseNumber(const LChar*& ptr, const LChar* end, float& number, bool skip = true);
-bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip = true);
-bool parseNumberFromString(const String&, float& number, bool skip = true);
+bool parseNumber(const LChar*& ptr, const LChar* end, float& number, WhitespaceMode = AllowLeadingAndTrailingWhitespace);
+bool parseNumber(const UChar*& ptr, const UChar* end, float& number, WhitespaceMode = AllowLeadingAndTrailingWhitespace);
bool parseNumberOptionalNumber(const String& s, float& h, float& v);
+bool parseNumberOrPercentage(const String& s, float& number);
bool parseArcFlag(const LChar*& ptr, const LChar* end, bool& flag);
bool parseArcFlag(const UChar*& ptr, const UChar* end, bool& flag);
-bool parseRect(const String&, FloatRect&);
template <typename CharType>
bool parseFloatPoint(const CharType*& current, const CharType* end, FloatPoint&);
@@ -53,18 +57,10 @@ bool parseFloatPoint2(const CharType*& current, const CharType* end, FloatPoint&
template <typename CharType>
bool parseFloatPoint3(const CharType*& current, const CharType* end, FloatPoint&, FloatPoint&, FloatPoint&);
-// SVG allows several different whitespace characters:
-// http://www.w3.org/TR/SVG/paths.html#PathDataBNF
-template <typename CharType>
-inline bool isSVGSpace(CharType c)
-{
- return c == ' ' || c == '\t' || c == '\n' || c == '\r';
-}
-
template <typename CharType>
inline bool skipOptionalSVGSpaces(const CharType*& ptr, const CharType* end)
{
- while (ptr < end && isSVGSpace(*ptr))
+ while (ptr < end && isHTMLSpace<CharType>(*ptr))
ptr++;
return ptr < end;
}
@@ -72,7 +68,7 @@ inline bool skipOptionalSVGSpaces(const CharType*& ptr, const CharType* end)
template <typename CharType>
inline bool skipOptionalSVGSpacesOrDelimiter(const CharType*& ptr, const CharType* end, char delimiter = ',')
{
- if (ptr < end && !isSVGSpace(*ptr) && *ptr != delimiter)
+ if (ptr < end && !isHTMLSpace<CharType>(*ptr) && *ptr != delimiter)
return false;
if (skipOptionalSVGSpaces(ptr, end)) {
if (ptr < end && *ptr == delimiter) {
@@ -83,23 +79,13 @@ inline bool skipOptionalSVGSpacesOrDelimiter(const CharType*& ptr, const CharTyp
return ptr < end;
}
-bool pointsListFromSVGData(SVGPointList& pointsList, const String& points);
Vector<String> parseDelimitedString(const String& input, const char seperator);
bool parseKerningUnicodeString(const String& input, UnicodeRanges&, HashSet<String>& stringList);
bool parseGlyphName(const String& input, HashSet<String>& values);
-enum TransformParsingMode {
- ClearList,
- DoNotClearList
-};
-
-bool parseTransformAttribute(SVGTransformList&, const LChar*& ptr, const LChar* end, TransformParsingMode = ClearList);
-bool parseTransformAttribute(SVGTransformList&, const UChar*& ptr, const UChar* end, TransformParsingMode = ClearList);
-
-bool parseTransformValue(unsigned type, const LChar*& ptr, const LChar* end, SVGTransform&);
-bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform&);
-
-SVGTransform::SVGTransformType parseTransformType(const String&);
+template<typename CharType>
+bool parseAndSkipTransformType(const CharType*& ptr, const CharType* end, SVGTransformType&);
+SVGTransformType parseTransformType(const String&);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathBuilder.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathBuilder.h
index 0c6a15d4aee..76798910e6d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathBuilder.h
@@ -31,30 +31,30 @@ namespace WebCore {
class Path;
-class SVGPathBuilder : public SVGPathConsumer {
+class SVGPathBuilder FINAL : public SVGPathConsumer {
public:
SVGPathBuilder();
void setCurrentPath(Path* path) { m_path = path; }
private:
- virtual void incrementPathSegmentCount() { }
- virtual bool continueConsuming() { return true; }
- virtual void cleanup() { m_path = 0; }
+ virtual void incrementPathSegmentCount() OVERRIDE { }
+ virtual bool continueConsuming() OVERRIDE { return true; }
+ virtual void cleanup() OVERRIDE { m_path = 0; }
// Used in UnalteredParsing/NormalizedParsing modes.
- virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode);
- virtual void lineTo(const FloatPoint&, PathCoordinateMode);
- virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void closePath();
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) OVERRIDE;
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void closePath() OVERRIDE;
// Only used in UnalteredParsing mode.
- virtual void lineToHorizontal(float, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void lineToVertical(float, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
+ virtual void lineToHorizontal(float, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void lineToVertical(float, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
Path* m_path;
FloatPoint m_current;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStream.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStream.h
index 184dad4b170..05940cf03e6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStream.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStream.h
@@ -26,21 +26,11 @@
namespace WebCore {
-// Type definitions for the byte stream data
-typedef union {
- bool value;
- unsigned char bytes[sizeof(bool)];
-} BoolByte;
-
-typedef union {
- float value;
- unsigned char bytes[sizeof(float)];
-} FloatByte;
-
-typedef union {
- unsigned short value;
- unsigned char bytes[sizeof(unsigned short)];
-} UnsignedShortByte;
+template<typename DataType>
+union ByteType {
+ DataType value;
+ unsigned char bytes[sizeof(DataType)];
+};
class SVGPathByteStream {
WTF_MAKE_FAST_ALLOCATED;
@@ -50,7 +40,7 @@ public:
return adoptPtr(new SVGPathByteStream);
}
- PassOwnPtr<SVGPathByteStream> copy()
+ PassOwnPtr<SVGPathByteStream> copy() const
{
return adoptPtr(new SVGPathByteStream(m_data));
}
@@ -58,24 +48,19 @@ public:
typedef Vector<unsigned char> Data;
typedef Data::const_iterator DataIterator;
- DataIterator begin() { return m_data.begin(); }
- DataIterator end() { return m_data.end(); }
+ DataIterator begin() const { return m_data.begin(); }
+ DataIterator end() const { return m_data.end(); }
void append(unsigned char byte) { m_data.append(byte); }
- void append(SVGPathByteStream* other)
- {
- for (DataIterator it = other->begin(); it != other->end(); ++it)
- append(*it);
- }
+ void append(SVGPathByteStream* other) { m_data.appendVector(other->m_data); }
void clear() { m_data.clear(); }
- bool isEmpty() const { return !m_data.size(); }
+ void reserveInitialCapacity(size_t size) { m_data.reserveInitialCapacity(size); }
+ void shrinkToFit() { m_data.shrinkToFit(); }
+ bool isEmpty() const { return m_data.isEmpty(); }
unsigned size() const { return m_data.size(); }
- // Only defined to let SVGAnimatedPathAnimator use the standard list code paths - this method is never called.
- void resize(unsigned) { }
-
private:
SVGPathByteStream() { }
- SVGPathByteStream(Data& data)
+ SVGPathByteStream(const Data& data)
: m_data(data)
{
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp
index 31e50d06dd7..85a58a220bc 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.cpp
@@ -26,6 +26,49 @@
namespace WebCore {
+// Helper class that coalesces writes to a SVGPathByteStream to a local buffer.
+class CoalescingBuffer {
+public:
+ CoalescingBuffer(SVGPathByteStream* byteStream)
+ : m_currentOffset(0)
+ , m_byteStream(byteStream)
+ {
+ ASSERT(byteStream);
+ }
+ ~CoalescingBuffer()
+ {
+ for (size_t i = 0; i < m_currentOffset; ++i)
+ m_byteStream->append(m_bytes[i]);
+ }
+
+ template<typename DataType>
+ void writeType(DataType value)
+ {
+ ByteType<DataType> data;
+ data.value = value;
+ size_t typeSize = sizeof(ByteType<DataType>);
+ ASSERT(m_currentOffset + typeSize <= sizeof(m_bytes));
+ memcpy(m_bytes + m_currentOffset, data.bytes, typeSize);
+ m_currentOffset += typeSize;
+ }
+
+ void writeFlag(bool value) { writeType<bool>(value); }
+ void writeFloat(float value) { writeType<float>(value); }
+ void writeFloatPoint(const FloatPoint& point)
+ {
+ writeType<float>(point.x());
+ writeType<float>(point.y());
+ }
+ void writeSegmentType(unsigned short value) { writeType<unsigned short>(value); }
+
+private:
+ // Adjust size to fit the largest command (in serialized/byte-stream format).
+ // Currently a cubic segment.
+ size_t m_currentOffset;
+ unsigned char m_bytes[sizeof(unsigned short) + sizeof(FloatPoint) * 3];
+ SVGPathByteStream* m_byteStream;
+};
+
SVGPathByteStreamBuilder::SVGPathByteStreamBuilder()
: m_byteStream(0)
{
@@ -33,80 +76,80 @@ SVGPathByteStreamBuilder::SVGPathByteStreamBuilder()
void SVGPathByteStreamBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegMoveToRel : PathSegMoveToAbs);
- writeFloatPoint(targetPoint);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegMoveToRel : PathSegMoveToAbs);
+ buffer.writeFloatPoint(targetPoint);
}
void SVGPathByteStreamBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegLineToRel : PathSegLineToAbs);
- writeFloatPoint(targetPoint);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToRel : PathSegLineToAbs);
+ buffer.writeFloatPoint(targetPoint);
}
void SVGPathByteStreamBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegLineToHorizontalRel : PathSegLineToHorizontalAbs);
- writeFloat(x);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToHorizontalRel : PathSegLineToHorizontalAbs);
+ buffer.writeFloat(x);
}
void SVGPathByteStreamBuilder::lineToVertical(float y, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegLineToVerticalRel : PathSegLineToVerticalAbs);
- writeFloat(y);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegLineToVerticalRel : PathSegLineToVerticalAbs);
+ buffer.writeFloat(y);
}
void SVGPathByteStreamBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicRel : PathSegCurveToCubicAbs);
- writeFloatPoint(point1);
- writeFloatPoint(point2);
- writeFloatPoint(targetPoint);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicRel : PathSegCurveToCubicAbs);
+ buffer.writeFloatPoint(point1);
+ buffer.writeFloatPoint(point2);
+ buffer.writeFloatPoint(targetPoint);
}
void SVGPathByteStreamBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicSmoothRel : PathSegCurveToCubicSmoothAbs);
- writeFloatPoint(point2);
- writeFloatPoint(targetPoint);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToCubicSmoothRel : PathSegCurveToCubicSmoothAbs);
+ buffer.writeFloatPoint(point2);
+ buffer.writeFloatPoint(targetPoint);
}
void SVGPathByteStreamBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticRel : PathSegCurveToQuadraticAbs);
- writeFloatPoint(point1);
- writeFloatPoint(targetPoint);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticRel : PathSegCurveToQuadraticAbs);
+ buffer.writeFloatPoint(point1);
+ buffer.writeFloatPoint(targetPoint);
}
void SVGPathByteStreamBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticSmoothRel : PathSegCurveToQuadraticSmoothAbs);
- writeFloatPoint(targetPoint);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegCurveToQuadraticSmoothRel : PathSegCurveToQuadraticSmoothAbs);
+ buffer.writeFloatPoint(targetPoint);
}
void SVGPathByteStreamBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- ASSERT(m_byteStream);
- writeSegmentType(mode == RelativeCoordinates ? PathSegArcRel : PathSegArcAbs);
- writeFloat(r1);
- writeFloat(r2);
- writeFloat(angle);
- writeFlag(largeArcFlag);
- writeFlag(sweepFlag);
- writeFloatPoint(targetPoint);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(mode == RelativeCoordinates ? PathSegArcRel : PathSegArcAbs);
+ buffer.writeFloat(r1);
+ buffer.writeFloat(r2);
+ buffer.writeFloat(angle);
+ buffer.writeFlag(largeArcFlag);
+ buffer.writeFlag(sweepFlag);
+ buffer.writeFloatPoint(targetPoint);
}
void SVGPathByteStreamBuilder::closePath()
{
- ASSERT(m_byteStream);
- writeSegmentType(PathSegClosePath);
+ CoalescingBuffer buffer(m_byteStream);
+ buffer.writeSegmentType(PathSegClosePath);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.h
index b3fd7472ffe..493b77ac04e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamBuilder.h
@@ -28,65 +28,30 @@
namespace WebCore {
-class SVGPathByteStreamBuilder : public SVGPathConsumer {
+class SVGPathByteStreamBuilder FINAL : public SVGPathConsumer {
public:
SVGPathByteStreamBuilder();
void setCurrentByteStream(SVGPathByteStream* byteStream) { m_byteStream = byteStream; }
private:
- virtual void incrementPathSegmentCount() { }
- virtual bool continueConsuming() { return true; }
- virtual void cleanup() { m_byteStream = 0; }
+ virtual void incrementPathSegmentCount() OVERRIDE { }
+ virtual bool continueConsuming() OVERRIDE { return true; }
+ virtual void cleanup() OVERRIDE { m_byteStream = 0; }
// Used in UnalteredParsing/NormalizedParsing modes.
- virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode);
- virtual void lineTo(const FloatPoint&, PathCoordinateMode);
- virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void closePath();
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) OVERRIDE;
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void closePath() OVERRIDE;
// Only used in UnalteredParsing mode.
- virtual void lineToHorizontal(float, PathCoordinateMode);
- virtual void lineToVertical(float, PathCoordinateMode);
- virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode);
- virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode);
-
- template<typename ByteType>
- void writeType(const ByteType& type)
- {
- size_t typeSize = sizeof(ByteType);
- for (size_t i = 0; i < typeSize; ++i)
- m_byteStream->append(type.bytes[i]);
- }
-
- void writeFlag(bool value)
- {
- BoolByte data;
- data.value = value;
- writeType(data);
- }
-
- void writeFloat(float value)
- {
- FloatByte data;
- data.value = value;
- writeType(data);
- }
-
- void writeFloatPoint(const FloatPoint& point)
- {
- writeFloat(point.x());
- writeFloat(point.y());
- }
-
- void writeSegmentType(unsigned short value)
- {
- UnsignedShortByte data;
- data.value = value;
- writeType(data);
- }
+ virtual void lineToHorizontal(float, PathCoordinateMode) OVERRIDE;
+ virtual void lineToVertical(float, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) OVERRIDE;
SVGPathByteStream* m_byteStream;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp
index 613ef855670..efabe89bf5d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp
@@ -23,7 +23,7 @@
namespace WebCore {
-SVGPathByteStreamSource::SVGPathByteStreamSource(SVGPathByteStream* stream)
+SVGPathByteStreamSource::SVGPathByteStreamSource(const SVGPathByteStream* stream)
{
ASSERT(stream);
m_streamCurrent = stream->begin();
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.h
index 9dedab5bfe5..a83490535bd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.h
@@ -27,68 +27,47 @@
namespace WebCore {
-class SVGPathByteStreamSource : public SVGPathSource {
+class SVGPathByteStreamSource FINAL : public SVGPathSource {
public:
- static PassOwnPtr<SVGPathByteStreamSource> create(SVGPathByteStream* stream)
- {
- return adoptPtr(new SVGPathByteStreamSource(stream));
- }
+ explicit SVGPathByteStreamSource(const SVGPathByteStream*);
private:
- SVGPathByteStreamSource(SVGPathByteStream*);
-
- virtual bool hasMoreData() const;
- virtual bool moveToNextToken() { return true; }
- virtual bool parseSVGSegmentType(SVGPathSegType&);
- virtual SVGPathSegType nextCommand(SVGPathSegType);
-
- virtual bool parseMoveToSegment(FloatPoint&);
- virtual bool parseLineToSegment(FloatPoint&);
- virtual bool parseLineToHorizontalSegment(float&);
- virtual bool parseLineToVerticalSegment(float&);
- virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&);
- virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&);
- virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&);
- virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&);
- virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&);
+ virtual bool hasMoreData() const OVERRIDE;
+ virtual bool moveToNextToken() OVERRIDE { return true; }
+ virtual bool parseSVGSegmentType(SVGPathSegType&) OVERRIDE;
+ virtual SVGPathSegType nextCommand(SVGPathSegType) OVERRIDE;
+
+ virtual bool parseMoveToSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseLineToSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseLineToHorizontalSegment(float&) OVERRIDE;
+ virtual bool parseLineToVerticalSegment(float&) OVERRIDE;
+ virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) OVERRIDE;
#if COMPILER(MSVC)
#pragma warning(disable: 4701)
#endif
- template<typename DataType, typename ByteType>
+ template<typename DataType>
DataType readType()
{
- ByteType data;
- size_t typeSize = sizeof(ByteType);
-
- for (size_t i = 0; i < typeSize; ++i) {
- ASSERT(m_streamCurrent < m_streamEnd);
- data.bytes[i] = *m_streamCurrent;
- ++m_streamCurrent;
- }
-
+ ByteType<DataType> data;
+ size_t typeSize = sizeof(ByteType<DataType>);
+ ASSERT(m_streamCurrent + typeSize <= m_streamEnd);
+ memcpy(data.bytes, m_streamCurrent, typeSize);
+ m_streamCurrent += typeSize;
return data.value;
}
- bool readFlag()
- {
- return readType<bool, BoolByte>();
- }
-
- float readFloat()
- {
- return readType<float, FloatByte>();
- }
-
- unsigned short readSVGSegmentType()
- {
- return readType<unsigned short, UnsignedShortByte>();
- }
-
+ bool readFlag() { return readType<bool>(); }
+ float readFloat() { return readType<float>(); }
+ unsigned short readSVGSegmentType() { return readType<unsigned short>(); }
FloatPoint readFloatPoint()
{
- float x = readType<float, FloatByte>();
- float y = readType<float, FloatByte>();
+ float x = readType<float>();
+ float y = readType<float>();
return FloatPoint(x, y);
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.cpp
index 82af73a0123..c7478ef6419 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.cpp
@@ -24,7 +24,6 @@
#include "core/rendering/svg/RenderSVGPath.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGMPathElement.h"
#include "core/svg/SVGPathSegArcAbs.h"
#include "core/svg/SVGPathSegArcRel.h"
@@ -46,51 +45,23 @@
#include "core/svg/SVGPathSegMovetoAbs.h"
#include "core/svg/SVGPathSegMovetoRel.h"
#include "core/svg/SVGPathUtilities.h"
-#include "core/svg/properties/SVGPathSegListPropertyTearOff.h"
+#include "core/svg/SVGPointTearOff.h"
namespace WebCore {
-// Define custom animated property 'd'.
-const SVGPropertyInfo* SVGPathElement::dPropertyInfo()
-{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedPath,
- PropertyIsReadWrite,
- SVGNames::dAttr,
- SVGNames::dAttr.localName(),
- &SVGPathElement::synchronizeD,
- &SVGPathElement::lookupOrCreateDWrapper);
- }
- return s_propertyInfo;
-}
-
-// Animated property definitions
-DEFINE_ANIMATED_NUMBER(SVGPathElement, SVGNames::pathLengthAttr, PathLength, pathLength)
-DEFINE_ANIMATED_BOOLEAN(SVGPathElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGPathElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(d)
- REGISTER_LOCAL_ANIMATED_PROPERTY(pathLength)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGPathElement::SVGPathElement(Document& document)
: SVGGeometryElement(SVGNames::pathTag, document)
- , m_pathByteStream(SVGPathByteStream::create())
- , m_pathSegList(PathSegUnalteredRole)
- , m_isAnimValObserved(false)
+ , m_pathLength(SVGAnimatedNumber::create(this, SVGNames::pathLengthAttr, SVGNumber::create()))
+ , m_pathSegList(SVGAnimatedPath::create(this, SVGNames::dAttr))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGPathElement();
-}
-PassRefPtr<SVGPathElement> SVGPathElement::create(Document& document)
-{
- return adoptRef(new SVGPathElement(document));
+ addToPropertyMap(m_pathLength);
+ addToPropertyMap(m_pathSegList);
}
+DEFINE_NODE_FACTORY(SVGPathElement)
+
float SVGPathElement::getTotalLength()
{
float totalLength = 0;
@@ -98,11 +69,11 @@ float SVGPathElement::getTotalLength()
return totalLength;
}
-SVGPoint SVGPathElement::getPointAtLength(float length)
+PassRefPtr<SVGPointTearOff> SVGPathElement::getPointAtLength(float length)
{
- SVGPoint point;
+ FloatPoint point;
getPointAtLengthOfSVGPathByteStream(pathByteStream(), length, point);
- return point;
+ return SVGPointTearOff::create(SVGPoint::create(point), 0, PropertyIsNotAnimVal);
}
unsigned SVGPathElement::getPathSegAtLength(float length)
@@ -112,106 +83,105 @@ unsigned SVGPathElement::getPathSegAtLength(float length)
return pathSeg;
}
-PassRefPtr<SVGPathSegClosePath> SVGPathElement::createSVGPathSegClosePath(SVGPathSegRole role)
+PassRefPtr<SVGPathSegClosePath> SVGPathElement::createSVGPathSegClosePath()
{
- return SVGPathSegClosePath::create(this, role);
+ return SVGPathSegClosePath::create(0, PathSegUndefinedRole);
}
-PassRefPtr<SVGPathSegMovetoAbs> SVGPathElement::createSVGPathSegMovetoAbs(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegMovetoAbs> SVGPathElement::createSVGPathSegMovetoAbs(float x, float y)
{
- return SVGPathSegMovetoAbs::create(this, role, x, y);
+ return SVGPathSegMovetoAbs::create(0, PathSegUndefinedRole, x, y);
}
-PassRefPtr<SVGPathSegMovetoRel> SVGPathElement::createSVGPathSegMovetoRel(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegMovetoRel> SVGPathElement::createSVGPathSegMovetoRel(float x, float y)
{
- return SVGPathSegMovetoRel::create(this, role, x, y);
+ return SVGPathSegMovetoRel::create(0, PathSegUndefinedRole, x, y);
}
-PassRefPtr<SVGPathSegLinetoAbs> SVGPathElement::createSVGPathSegLinetoAbs(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoAbs> SVGPathElement::createSVGPathSegLinetoAbs(float x, float y)
{
- return SVGPathSegLinetoAbs::create(this, role, x, y);
+ return SVGPathSegLinetoAbs::create(0, PathSegUndefinedRole, x, y);
}
-PassRefPtr<SVGPathSegLinetoRel> SVGPathElement::createSVGPathSegLinetoRel(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoRel> SVGPathElement::createSVGPathSegLinetoRel(float x, float y)
{
- return SVGPathSegLinetoRel::create(this, role, x, y);
+ return SVGPathSegLinetoRel::create(0, PathSegUndefinedRole, x, y);
}
-PassRefPtr<SVGPathSegCurvetoCubicAbs> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoCubicAbs> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2)
{
- return SVGPathSegCurvetoCubicAbs::create(this, role, x, y, x1, y1, x2, y2);
+ return SVGPathSegCurvetoCubicAbs::create(0, PathSegUndefinedRole, x, y, x1, y1, x2, y2);
}
-PassRefPtr<SVGPathSegCurvetoCubicRel> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoCubicRel> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2)
{
- return SVGPathSegCurvetoCubicRel::create(this, role, x, y, x1, y1, x2, y2);
+ return SVGPathSegCurvetoCubicRel::create(0, PathSegUndefinedRole, x, y, x1, y1, x2, y2);
}
-PassRefPtr<SVGPathSegCurvetoQuadraticAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoQuadraticAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1)
{
- return SVGPathSegCurvetoQuadraticAbs::create(this, role, x, y, x1, y1);
+ return SVGPathSegCurvetoQuadraticAbs::create(0, PathSegUndefinedRole, x, y, x1, y1);
}
-PassRefPtr<SVGPathSegCurvetoQuadraticRel> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoQuadraticRel> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1)
{
- return SVGPathSegCurvetoQuadraticRel::create(this, role, x, y, x1, y1);
+ return SVGPathSegCurvetoQuadraticRel::create(0, PathSegUndefinedRole, x, y, x1, y1);
}
-PassRefPtr<SVGPathSegArcAbs> SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role)
+PassRefPtr<SVGPathSegArcAbs> SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
{
- return SVGPathSegArcAbs::create(this, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
+ return SVGPathSegArcAbs::create(0, PathSegUndefinedRole, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
}
-PassRefPtr<SVGPathSegArcRel> SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role)
+PassRefPtr<SVGPathSegArcRel> SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
{
- return SVGPathSegArcRel::create(this, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
+ return SVGPathSegArcRel::create(0, PathSegUndefinedRole, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
}
-PassRefPtr<SVGPathSegLinetoHorizontalAbs> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoHorizontalAbs> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x)
{
- return SVGPathSegLinetoHorizontalAbs::create(this, role, x);
+ return SVGPathSegLinetoHorizontalAbs::create(0, PathSegUndefinedRole, x);
}
-PassRefPtr<SVGPathSegLinetoHorizontalRel> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoHorizontalRel> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x)
{
- return SVGPathSegLinetoHorizontalRel::create(this, role, x);
+ return SVGPathSegLinetoHorizontalRel::create(0, PathSegUndefinedRole, x);
}
-PassRefPtr<SVGPathSegLinetoVerticalAbs> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoVerticalAbs> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y)
{
- return SVGPathSegLinetoVerticalAbs::create(this, role, y);
+ return SVGPathSegLinetoVerticalAbs::create(0, PathSegUndefinedRole, y);
}
-PassRefPtr<SVGPathSegLinetoVerticalRel> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoVerticalRel> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y)
{
- return SVGPathSegLinetoVerticalRel::create(this, role, y);
+ return SVGPathSegLinetoVerticalRel::create(0, PathSegUndefinedRole, y);
}
-PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2)
{
- return SVGPathSegCurvetoCubicSmoothAbs::create(this, role, x, y, x2, y2);
+ return SVGPathSegCurvetoCubicSmoothAbs::create(0, PathSegUndefinedRole, x, y, x2, y2);
}
-PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2)
{
- return SVGPathSegCurvetoCubicSmoothRel::create(this, role, x, y, x2, y2);
+ return SVGPathSegCurvetoCubicSmoothRel::create(0, PathSegUndefinedRole, x, y, x2, y2);
}
-PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y)
{
- return SVGPathSegCurvetoQuadraticSmoothAbs::create(this, role, x, y);
+ return SVGPathSegCurvetoQuadraticSmoothAbs::create(0, PathSegUndefinedRole, x, y);
}
-PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y)
{
- return SVGPathSegCurvetoQuadraticSmoothRel::create(this, role, x, y);
+ return SVGPathSegCurvetoQuadraticSmoothRel::create(0, PathSegUndefinedRole, x, y);
}
bool SVGPathElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::dAttr);
supportedAttributes.add(SVGNames::pathLengthAttr);
}
@@ -225,23 +195,19 @@ void SVGPathElement::parseAttribute(const QualifiedName& name, const AtomicStrin
return;
}
- if (name == SVGNames::dAttr) {
- if (!buildSVGPathByteStreamFromString(value, m_pathByteStream.get(), UnalteredParsing))
- document().accessSVGExtensions()->reportError("Problem parsing d=\"" + value + "\"");
- return;
- }
+ SVGParsingError parseError = NoError;
- if (name == SVGNames::pathLengthAttr) {
- setPathLengthBaseValue(value.toFloat());
- if (pathLengthBaseValue() < 0)
- document().accessSVGExtensions()->reportError("A negative value for path attribute <pathLength> is not allowed");
- return;
+ if (name == SVGNames::dAttr) {
+ m_pathSegList->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::pathLengthAttr) {
+ m_pathLength->setBaseValueAsString(value, parseError);
+ if (parseError == NoError && m_pathLength->baseValue()->value() < 0)
+ document().accessSVGExtensions().reportError("A negative value for path attribute <pathLength> is not allowed");
+ } else {
+ ASSERT_NOT_REACHED();
}
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -251,17 +217,11 @@ void SVGPathElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
RenderSVGPath* renderer = toRenderSVGPath(this->renderer());
if (attrName == SVGNames::dAttr) {
- if (m_pathSegList.shouldSynchronize && !SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(this, dPropertyInfo())->isAnimating()) {
- SVGPathSegList newList(PathSegUnalteredRole);
- buildSVGPathSegListFromByteStream(m_pathByteStream.get(), this, newList, UnalteredParsing);
- m_pathSegList.value = newList;
- }
-
if (renderer)
renderer->setNeedsShapeUpdate();
@@ -276,10 +236,10 @@ void SVGPathElement::invalidateMPathDependencies()
{
// <mpath> can only reference <path> but this dependency is not handled in
// markForLayoutAndParentResourceInvalidation so we update any mpath dependencies manually.
- if (HashSet<SVGElement*>* dependencies = document().accessSVGExtensions()->setOfElementsReferencingTarget(this)) {
- HashSet<SVGElement*>::iterator end = dependencies->end();
- for (HashSet<SVGElement*>::iterator it = dependencies->begin(); it != end; ++it) {
- if ((*it)->hasTagName(SVGNames::mpathTag))
+ if (SVGElementSet* dependencies = document().accessSVGExtensions().setOfElementsReferencingTarget(this)) {
+ SVGElementSet::iterator end = dependencies->end();
+ for (SVGElementSet::iterator it = dependencies->begin(); it != end; ++it) {
+ if (isSVGMPathElement(**it))
toSVGMPathElement(*it)->targetPathChanged();
}
}
@@ -298,79 +258,9 @@ void SVGPathElement::removedFrom(ContainerNode* rootParent)
invalidateMPathDependencies();
}
-SVGPathByteStream* SVGPathElement::pathByteStream() const
-{
- SVGAnimatedProperty* property = SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(this, dPropertyInfo());
- if (!property || !property->isAnimating())
- return m_pathByteStream.get();
- return static_cast<SVGAnimatedPathSegListPropertyTearOff*>(property)->animatedPathByteStream();
-}
-
-PassRefPtr<SVGAnimatedProperty> SVGPathElement::lookupOrCreateDWrapper(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- SVGPathElement* ownerType = toSVGPathElement(contextElement);
-
- if (SVGAnimatedProperty* property = SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(ownerType, dPropertyInfo()))
- return property;
-
- // Build initial SVGPathSegList.
- buildSVGPathSegListFromByteStream(ownerType->m_pathByteStream.get(), ownerType, ownerType->m_pathSegList.value, UnalteredParsing);
-
- return SVGAnimatedProperty::lookupOrCreateWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff, SVGPathSegList>
- (ownerType, dPropertyInfo(), ownerType->m_pathSegList.value);
-}
-
-void SVGPathElement::synchronizeD(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- SVGPathElement* ownerType = toSVGPathElement(contextElement);
- if (!ownerType->m_pathSegList.shouldSynchronize)
- return;
- ownerType->m_pathSegList.synchronize(ownerType, dPropertyInfo()->attributeName, ownerType->m_pathSegList.value.valueAsString());
-}
-
-SVGPathSegListPropertyTearOff* SVGPathElement::pathSegList()
-{
- m_pathSegList.shouldSynchronize = true;
- return static_cast<SVGPathSegListPropertyTearOff*>(static_pointer_cast<SVGAnimatedPathSegListPropertyTearOff>(lookupOrCreateDWrapper(this))->baseVal());
-}
-
-SVGPathSegListPropertyTearOff* SVGPathElement::normalizedPathSegList()
-{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
- return 0;
-}
-
-SVGPathSegListPropertyTearOff* SVGPathElement::animatedPathSegList()
-{
- m_pathSegList.shouldSynchronize = true;
- m_isAnimValObserved = true;
- return static_cast<SVGPathSegListPropertyTearOff*>(static_pointer_cast<SVGAnimatedPathSegListPropertyTearOff>(lookupOrCreateDWrapper(this))->animVal());
-}
-
-SVGPathSegListPropertyTearOff* SVGPathElement::animatedNormalizedPathSegList()
-{
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
- return 0;
-}
-
-void SVGPathElement::pathSegListChanged(SVGPathSegRole role, ListModification listModification)
+void SVGPathElement::pathSegListChanged(ListModification listModification)
{
- switch (role) {
- case PathSegNormalizedRole:
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
- break;
- case PathSegUnalteredRole:
- if (listModification == ListModificationAppend) {
- ASSERT(!m_pathSegList.value.isEmpty());
- appendSVGPathByteStreamFromSVGPathSeg(m_pathSegList.value.last(), m_pathByteStream.get(), UnalteredParsing);
- } else
- buildSVGPathByteStreamFromSVGPathSegList(m_pathSegList.value, m_pathByteStream.get(), UnalteredParsing);
- break;
- case PathSegUndefinedRole:
- return;
- }
+ m_pathSegList->baseValue()->clearByteStream();
invalidateSVGAttributes();
@@ -382,7 +272,7 @@ void SVGPathElement::pathSegListChanged(SVGPathSegRole role, ListModification li
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
}
-SVGRect SVGPathElement::getBBox()
+FloatRect SVGPathElement::getBBox()
{
// By default, getBBox() returns objectBoundingBox but that will include
// markers so we override it to return just the path's bounding rect.
@@ -391,16 +281,10 @@ SVGRect SVGPathElement::getBBox()
// FIXME: Eventually we should support getBBox for detached elements.
if (!renderer())
- return SVGRect();
+ return FloatRect();
RenderSVGPath* renderer = toRenderSVGPath(this->renderer());
return renderer->path().boundingRect();
}
-RenderObject* SVGPathElement::createRenderer(RenderStyle*)
-{
- // By default, any subclass is expected to do path-based drawing
- return new RenderSVGPath(this);
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.h
index adc861c4fea..ce3834ffd2f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.h
@@ -21,13 +21,13 @@
#ifndef SVGPathElement_h
#define SVGPathElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedNumber.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
+#include "core/svg/SVGAnimatedPath.h"
#include "core/svg/SVGGeometryElement.h"
#include "core/svg/SVGPathByteStream.h"
-#include "core/svg/SVGPathSegList.h"
+#include "wtf/WeakPtr.h"
namespace WebCore {
@@ -50,87 +50,67 @@ class SVGPathSegCurvetoCubicSmoothAbs;
class SVGPathSegCurvetoCubicSmoothRel;
class SVGPathSegCurvetoQuadraticSmoothAbs;
class SVGPathSegCurvetoQuadraticSmoothRel;
-class SVGPathSegListPropertyTearOff;
-class SVGPathElement FINAL : public SVGGeometryElement,
- public SVGExternalResourcesRequired {
+class SVGPathElement FINAL : public SVGGeometryElement {
public:
- static PassRefPtr<SVGPathElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGPathElement);
float getTotalLength();
- SVGPoint getPointAtLength(float distance);
+ PassRefPtr<SVGPointTearOff> getPointAtLength(float distance);
unsigned getPathSegAtLength(float distance);
- PassRefPtr<SVGPathSegClosePath> createSVGPathSegClosePath(SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegMovetoAbs> createSVGPathSegMovetoAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegMovetoRel> createSVGPathSegMovetoRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegLinetoAbs> createSVGPathSegLinetoAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegLinetoRel> createSVGPathSegLinetoRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegCurvetoCubicAbs> createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegCurvetoCubicRel> createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegCurvetoQuadraticAbs> createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegCurvetoQuadraticRel> createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegArcAbs> createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegArcRel> createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegLinetoHorizontalAbs> createSVGPathSegLinetoHorizontalAbs(float x, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegLinetoHorizontalRel> createSVGPathSegLinetoHorizontalRel(float x, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegLinetoVerticalAbs> createSVGPathSegLinetoVerticalAbs(float y, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegLinetoVerticalRel> createSVGPathSegLinetoVerticalRel(float y, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
- PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
+ SVGAnimatedNumber* pathLength() { return m_pathLength.get(); }
+
+ PassRefPtr<SVGPathSegClosePath> createSVGPathSegClosePath();
+ PassRefPtr<SVGPathSegMovetoAbs> createSVGPathSegMovetoAbs(float x, float y);
+ PassRefPtr<SVGPathSegMovetoRel> createSVGPathSegMovetoRel(float x, float y);
+ PassRefPtr<SVGPathSegLinetoAbs> createSVGPathSegLinetoAbs(float x, float y);
+ PassRefPtr<SVGPathSegLinetoRel> createSVGPathSegLinetoRel(float x, float y);
+ PassRefPtr<SVGPathSegCurvetoCubicAbs> createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2);
+ PassRefPtr<SVGPathSegCurvetoCubicRel> createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2);
+ PassRefPtr<SVGPathSegCurvetoQuadraticAbs> createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1);
+ PassRefPtr<SVGPathSegCurvetoQuadraticRel> createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1);
+ PassRefPtr<SVGPathSegArcAbs> createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag);
+ PassRefPtr<SVGPathSegArcRel> createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag);
+ PassRefPtr<SVGPathSegLinetoHorizontalAbs> createSVGPathSegLinetoHorizontalAbs(float x);
+ PassRefPtr<SVGPathSegLinetoHorizontalRel> createSVGPathSegLinetoHorizontalRel(float x);
+ PassRefPtr<SVGPathSegLinetoVerticalAbs> createSVGPathSegLinetoVerticalAbs(float y);
+ PassRefPtr<SVGPathSegLinetoVerticalRel> createSVGPathSegLinetoVerticalRel(float y);
+ PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2);
+ PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2);
+ PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y);
+ PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y);
// Used in the bindings only.
- SVGPathSegListPropertyTearOff* pathSegList();
- SVGPathSegListPropertyTearOff* animatedPathSegList();
- SVGPathSegListPropertyTearOff* normalizedPathSegList();
- SVGPathSegListPropertyTearOff* animatedNormalizedPathSegList();
+ SVGPathSegListTearOff* pathSegList() { return m_pathSegList->baseVal(); }
+ SVGPathSegListTearOff* animatedPathSegList() { return m_pathSegList->animVal(); }
- SVGPathByteStream* pathByteStream() const;
+ // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
+ SVGPathSegListTearOff* normalizedPathSegList() { return 0; }
+ SVGPathSegListTearOff* animatedNormalizedPathSegList() { return 0; }
- void pathSegListChanged(SVGPathSegRole, ListModification = ListModificationUnknown);
+ const SVGPathByteStream* pathByteStream() const { return m_pathSegList->currentValue()->byteStream(); }
- virtual SVGRect getBBox() OVERRIDE FINAL;
+ void pathSegListChanged(ListModification = ListModificationUnknown);
- static const SVGPropertyInfo* dPropertyInfo();
-
- bool isAnimValObserved() const { return m_isAnimValObserved; }
+ virtual FloatRect getBBox() OVERRIDE;
private:
explicit SVGPathElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual bool supportsMarkers() const { return true; }
-
- // Custom 'd' property
- static void synchronizeD(SVGElement* contextElement);
- static PassRefPtr<SVGAnimatedProperty> lookupOrCreateDWrapper(SVGElement* contextElement);
-
- virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
virtual Node::InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
void invalidateMPathDependencies();
- OwnPtr<SVGPathByteStream> m_pathByteStream;
- mutable SVGSynchronizableAnimatedProperty<SVGPathSegList> m_pathSegList;
- bool m_isAnimValObserved;
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPathElement)
- DECLARE_ANIMATED_NUMBER(PathLength, pathLength)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumber> m_pathLength;
+ RefPtr<SVGAnimatedPath> m_pathSegList;
};
-DEFINE_NODE_TYPE_CASTS(SVGPathElement, hasTagName(SVGNames::pathTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.idl
index 297b5b1d684..3cc9d2f19c4 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathElement.idl
@@ -24,52 +24,56 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathElement : SVGGeometryElement {
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathElement : SVGGeometryElement {
readonly attribute SVGAnimatedNumber pathLength;
float getTotalLength();
- [StrictTypeChecking] SVGPoint getPointAtLength(float distance);
- [StrictTypeChecking] unsigned long getPathSegAtLength(float distance);
+ SVGPoint getPointAtLength(float distance);
+ unsigned long getPathSegAtLength(float distance);
SVGPathSegClosePath createSVGPathSegClosePath();
- [StrictTypeChecking] SVGPathSegMovetoAbs createSVGPathSegMovetoAbs(float x, float y);
- [StrictTypeChecking] SVGPathSegMovetoRel createSVGPathSegMovetoRel(float x, float y);
+ SVGPathSegMovetoAbs createSVGPathSegMovetoAbs(float x, float y);
+ SVGPathSegMovetoRel createSVGPathSegMovetoRel(float x, float y);
- [StrictTypeChecking] SVGPathSegLinetoAbs createSVGPathSegLinetoAbs(float x, float y);
- [StrictTypeChecking] SVGPathSegLinetoRel createSVGPathSegLinetoRel(float x, float y);
+ SVGPathSegLinetoAbs createSVGPathSegLinetoAbs(float x, float y);
+ SVGPathSegLinetoRel createSVGPathSegLinetoRel(float x, float y);
- [StrictTypeChecking] SVGPathSegCurvetoCubicAbs
- createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2);
- [StrictTypeChecking] SVGPathSegCurvetoCubicRel
- createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2);
+ SVGPathSegCurvetoCubicAbs createSVGPathSegCurvetoCubicAbs(
+ float x, float y, float x1, float y1, float x2, float y2);
+ SVGPathSegCurvetoCubicRel createSVGPathSegCurvetoCubicRel(
+ float x, float y, float x1, float y1, float x2, float y2);
- [StrictTypeChecking] SVGPathSegCurvetoQuadraticAbs
- createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1);
- [StrictTypeChecking] SVGPathSegCurvetoQuadraticRel
- createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1);
+ SVGPathSegCurvetoQuadraticAbs createSVGPathSegCurvetoQuadraticAbs(
+ float x, float y, float x1, float y1);
+ SVGPathSegCurvetoQuadraticRel createSVGPathSegCurvetoQuadraticRel(
+ float x, float y, float x1, float y1);
- [StrictTypeChecking] SVGPathSegArcAbs
- createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, boolean largeArcFlag, boolean sweepFlag);
- [StrictTypeChecking] SVGPathSegArcRel
- createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, boolean largeArcFlag, boolean sweepFlag);
+ SVGPathSegArcAbs createSVGPathSegArcAbs(
+ float x, float y, float r1, float r2,
+ float angle, boolean largeArcFlag, boolean sweepFlag);
+ SVGPathSegArcRel createSVGPathSegArcRel(
+ float x, float y, float r1, float r2,
+ float angle, boolean largeArcFlag, boolean sweepFlag);
- [StrictTypeChecking] SVGPathSegLinetoHorizontalAbs createSVGPathSegLinetoHorizontalAbs(float x);
- [StrictTypeChecking] SVGPathSegLinetoHorizontalRel createSVGPathSegLinetoHorizontalRel(float x);
+ SVGPathSegLinetoHorizontalAbs createSVGPathSegLinetoHorizontalAbs(float x);
+ SVGPathSegLinetoHorizontalRel createSVGPathSegLinetoHorizontalRel(float x);
- [StrictTypeChecking] SVGPathSegLinetoVerticalAbs createSVGPathSegLinetoVerticalAbs(float y);
- [StrictTypeChecking] SVGPathSegLinetoVerticalRel createSVGPathSegLinetoVerticalRel(float y);
+ SVGPathSegLinetoVerticalAbs createSVGPathSegLinetoVerticalAbs(float y);
+ SVGPathSegLinetoVerticalRel createSVGPathSegLinetoVerticalRel(float y);
- [StrictTypeChecking] SVGPathSegCurvetoCubicSmoothAbs createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2);
- [StrictTypeChecking] SVGPathSegCurvetoCubicSmoothRel createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2);
+ SVGPathSegCurvetoCubicSmoothAbs createSVGPathSegCurvetoCubicSmoothAbs(
+ float x, float y, float x2, float y2);
+ SVGPathSegCurvetoCubicSmoothRel createSVGPathSegCurvetoCubicSmoothRel(
+ float x, float y, float x2, float y2);
- [StrictTypeChecking] SVGPathSegCurvetoQuadraticSmoothAbs createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y);
- [StrictTypeChecking] SVGPathSegCurvetoQuadraticSmoothRel createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y);
+ SVGPathSegCurvetoQuadraticSmoothAbs createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y);
+ SVGPathSegCurvetoQuadraticSmoothRel createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y);
readonly attribute SVGPathSegList pathSegList;
readonly attribute SVGPathSegList normalizedPathSegList;
readonly attribute SVGPathSegList animatedPathSegList;
readonly attribute SVGPathSegList animatedNormalizedPathSegList;
};
-
-SVGPathElement implements SVGExternalResourcesRequired;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathParser.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathParser.cpp
index 6b7ac433993..57ba8a5164b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathParser.cpp
@@ -456,9 +456,9 @@ bool SVGPathParser::decomposeArcToCubic(float angle, float rx, float ry, FloatPo
float thetaArc = theta2 - theta1;
if (thetaArc < 0 && sweepFlag)
- thetaArc += 2 * piFloat;
+ thetaArc += twoPiFloat;
else if (thetaArc > 0 && !sweepFlag)
- thetaArc -= 2 * piFloat;
+ thetaArc -= twoPiFloat;
pointTransform.makeIdentity();
pointTransform.rotate(angle);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.cpp
new file mode 100644
index 00000000000..9923d58223d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGPathSeg.h"
+
+#include "core/svg/SVGPathElement.h"
+
+namespace WebCore {
+
+SVGPathSeg::SVGPathSeg(SVGPathElement* contextElement)
+ : m_ownerList(0)
+ , m_contextElement(contextElement)
+{
+}
+
+void SVGPathSeg::commitChange()
+{
+ if (m_contextElement)
+ toSVGPathElement(m_contextElement)->pathSegListChanged();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.h
index 565bfa0e682..95d9b04f0bc 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.h
@@ -27,6 +27,14 @@
namespace WebCore {
+enum ListModification {
+ ListModificationUnknown = 0,
+ ListModificationInsert = 1,
+ ListModificationReplace = 2,
+ ListModificationRemove = 3,
+ ListModificationAppend = 4
+};
+
enum SVGPathSegType {
PathSegUnknown = 0,
PathSegClosePath = 1,
@@ -56,12 +64,17 @@ enum SVGPathSegRole {
PathSegUndefinedRole = 2
};
+class SVGPropertyBase;
+class SVGPathElement;
+class SVGElement;
+
class SVGPathSeg : public RefCounted<SVGPathSeg>, public ScriptWrappable {
public:
- SVGPathSeg()
- {
- ScriptWrappable::init(this);
- }
+ // SVGPathSeg itself is used as a tear-off type.
+ // FIXME: A tear-off type should be introduced to distinguish animVal/baseVal
+ typedef SVGPathSeg TearOffType;
+
+ explicit SVGPathSeg(SVGPathElement* contextElement);
virtual ~SVGPathSeg() { }
@@ -91,6 +104,32 @@ public:
virtual unsigned short pathSegType() const = 0;
virtual String pathSegTypeAsLetter() const = 0;
+
+ SVGPropertyBase* ownerList() const
+ {
+ return m_ownerList;
+ }
+
+ void setOwnerList(SVGPropertyBase* ownerList)
+ {
+ // Previous owner list must be cleared before setting new owner list.
+ ASSERT((!ownerList && m_ownerList) || (ownerList && !m_ownerList));
+
+ m_ownerList = ownerList;
+ }
+
+ void setContextElement(SVGElement* contextElement)
+ {
+ m_contextElement = contextElement;
+ }
+
+protected:
+ void commitChange();
+
+private:
+ // FIXME: oilpan: These are kept as raw ptrs to break reference cycle. Should be Member in oilpan.
+ SVGPropertyBase* m_ownerList;
+ SVGElement* m_contextElement;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.idl
index 60ed633dd31..4b9ce79a5a7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSeg.idl
@@ -26,6 +26,7 @@
[
Custom=Wrap,
+ DependentLifetime,
] interface SVGPathSeg {
// Path Segment Types
const unsigned short PATHSEG_UNKNOWN = 0;
@@ -52,4 +53,3 @@
readonly attribute unsigned short pathSegType;
readonly attribute DOMString pathSegTypeAsLetter;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.h
index 85e686e3044..74bfcda8d35 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegArcAbs : public SVGPathSegArc {
+class SVGPathSegArcAbs FINAL : public SVGPathSegArc {
public:
static PassRefPtr<SVGPathSegArcAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_ARC_ABS; }
- virtual String pathSegTypeAsLetter() const { return "A"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_ARC_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "A"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.idl
index a50286fe20f..9f602670cdb 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcAbs.idl
@@ -24,13 +24,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegArcAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float r1;
- [StrictTypeChecking] attribute float r2;
- [StrictTypeChecking] attribute float angle;
- [StrictTypeChecking] attribute boolean largeArcFlag;
- [StrictTypeChecking] attribute boolean sweepFlag;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegArcAbs : SVGPathSeg {
+ attribute float x;
+ attribute float y;
+ attribute float r1;
+ attribute float r2;
+ attribute float angle;
+ attribute boolean largeArcFlag;
+ attribute boolean sweepFlag;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.h
index 076c930bb12..5add5de952d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegArcRel : public SVGPathSegArc {
+class SVGPathSegArcRel FINAL : public SVGPathSegArc {
public:
static PassRefPtr<SVGPathSegArcRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_ARC_REL; }
- virtual String pathSegTypeAsLetter() const { return "a"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_ARC_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "a"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.idl
index d682c2c01bc..405a5c66e9b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegArcRel.idl
@@ -24,13 +24,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegArcRel : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float r1;
- [StrictTypeChecking] attribute float r2;
- [StrictTypeChecking] attribute float angle;
- [StrictTypeChecking] attribute boolean largeArcFlag;
- [StrictTypeChecking] attribute boolean sweepFlag;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegArcRel : SVGPathSeg {
+ attribute float x;
+ attribute float y;
+ attribute float r1;
+ attribute float r2;
+ attribute float angle;
+ attribute boolean largeArcFlag;
+ attribute boolean sweepFlag;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.h
index 4c6adc22451..5f2258f380f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.h
@@ -25,7 +25,7 @@
namespace WebCore {
-class SVGPathSegClosePath : public SVGPathSegWithContext {
+class SVGPathSegClosePath FINAL : public SVGPathSegWithContext {
public:
static PassRefPtr<SVGPathSegClosePath> create(SVGPathElement* element, SVGPathSegRole role)
{
@@ -39,8 +39,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CLOSEPATH; }
- virtual String pathSegTypeAsLetter() const { return "Z"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CLOSEPATH; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "Z"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.idl
index e05ca79d29d..bb47b281771 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegClosePath.idl
@@ -26,4 +26,3 @@
interface SVGPathSegClosePath : SVGPathSeg {
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.h
index 56718a87d3f..77c618609ad 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegCurvetoCubicAbs : public SVGPathSegCurvetoCubic {
+class SVGPathSegCurvetoCubicAbs FINAL : public SVGPathSegCurvetoCubic {
public:
static PassRefPtr<SVGPathSegCurvetoCubicAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_ABS; }
- virtual String pathSegTypeAsLetter() const { return "C"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CURVETO_CUBIC_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "C"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl
index 982cb68063f..3fb452cd526 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl
@@ -24,12 +24,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegCurvetoCubicAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float x1;
- [StrictTypeChecking] attribute float y1;
- [StrictTypeChecking] attribute float x2;
- [StrictTypeChecking] attribute float y2;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegCurvetoCubicAbs : SVGPathSeg {
+ attribute float x;
+ attribute float y;
+ attribute float x1;
+ attribute float y1;
+ attribute float x2;
+ attribute float y2;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.h
index 3910fcd30d2..bd944d35fe2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegCurvetoCubicRel : public SVGPathSegCurvetoCubic {
+class SVGPathSegCurvetoCubicRel FINAL : public SVGPathSegCurvetoCubic {
public:
static PassRefPtr<SVGPathSegCurvetoCubicRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1, float x2, float y2)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_REL; }
- virtual String pathSegTypeAsLetter() const { return "c"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CURVETO_CUBIC_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "c"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.idl
index 352bb42317f..a047127ce1f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicRel.idl
@@ -24,12 +24,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegCurvetoCubicRel : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float x1;
- [StrictTypeChecking] attribute float y1;
- [StrictTypeChecking] attribute float x2;
- [StrictTypeChecking] attribute float y2;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegCurvetoCubicRel : SVGPathSeg {
+ attribute float x;
+ attribute float y;
+ attribute float x1;
+ attribute float y1;
+ attribute float x2;
+ attribute float y2;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.h
index 3e36a589f64..d1f3fa4ee66 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegCurvetoCubicSmoothAbs : public SVGPathSegCurvetoCubicSmooth {
+class SVGPathSegCurvetoCubicSmoothAbs FINAL : public SVGPathSegCurvetoCubicSmooth {
public:
static PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x2, float y2)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; }
- virtual String pathSegTypeAsLetter() const { return "S"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CURVETO_CUBIC_SMOOTH_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "S"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.idl
index 050926aad70..c84d23963f8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothAbs.idl
@@ -24,10 +24,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegCurvetoCubicSmoothAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float x2;
- [StrictTypeChecking] attribute float y2;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegCurvetoCubicSmoothAbs : SVGPathSeg {
+ attribute float x;
+ attribute float y;
+ attribute float x2;
+ attribute float y2;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.h
index 4b7be696afe..2fa5b9ce21f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegCurvetoCubicSmoothRel : public SVGPathSegCurvetoCubicSmooth {
+class SVGPathSegCurvetoCubicSmoothRel FINAL : public SVGPathSegCurvetoCubicSmooth {
public:
static PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x2, float y2)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_CUBIC_SMOOTH_REL; }
- virtual String pathSegTypeAsLetter() const { return "s"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CURVETO_CUBIC_SMOOTH_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "s"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl
index 85605dee193..daa38e310aa 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl
@@ -24,10 +24,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegCurvetoCubicSmoothRel : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float x2;
- [StrictTypeChecking] attribute float y2;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegCurvetoCubicSmoothRel : SVGPathSeg {
+ attribute float x;
+ attribute float y;
+ attribute float x2;
+ attribute float y2;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.h
index 6d25dfe1f3f..16aadbdd2d3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegCurvetoQuadraticAbs : public SVGPathSegCurvetoQuadratic {
+class SVGPathSegCurvetoQuadraticAbs FINAL : public SVGPathSegCurvetoQuadratic {
public:
static PassRefPtr<SVGPathSegCurvetoQuadraticAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_ABS; }
- virtual String pathSegTypeAsLetter() const { return "Q"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CURVETO_QUADRATIC_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "Q"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl
index 7549e8ef5f6..3014b0167e6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl
@@ -24,10 +24,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegCurvetoQuadraticAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float x1;
- [StrictTypeChecking] attribute float y1;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegCurvetoQuadraticAbs : SVGPathSeg {
+ attribute float x;
+ attribute float y;
+ attribute float x1;
+ attribute float y1;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.h
index 2c51a8be7c3..ad2725ab09d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegCurvetoQuadraticRel : public SVGPathSegCurvetoQuadratic {
+class SVGPathSegCurvetoQuadraticRel FINAL : public SVGPathSegCurvetoQuadratic {
public:
static PassRefPtr<SVGPathSegCurvetoQuadraticRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y, float x1, float y1)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_REL; }
- virtual String pathSegTypeAsLetter() const { return "q"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CURVETO_QUADRATIC_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "q"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl
index cfd7e87e0b8..a14cbe38c1d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl
@@ -24,10 +24,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegCurvetoQuadraticRel : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float x1;
- [StrictTypeChecking] attribute float y1;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegCurvetoQuadraticRel : SVGPathSeg {
+ attribute float x;
+ attribute float y;
+ attribute float x1;
+ attribute float y1;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h
index 87b4942ada6..e797b1db160 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegCurvetoQuadraticSmoothAbs : public SVGPathSegSingleCoordinate {
+class SVGPathSegCurvetoQuadraticSmoothAbs FINAL : public SVGPathSegSingleCoordinate {
public:
static PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; }
- virtual String pathSegTypeAsLetter() const { return "T"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "T"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl
index b5c5d3d0589..aad9a56a0d7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothAbs.idl
@@ -24,8 +24,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegCurvetoQuadraticSmoothAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegCurvetoQuadraticSmoothAbs : SVGPathSeg {
+ attribute float x;
+ attribute float y;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.h
index 8506e158a11..c011c42c53d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegCurvetoQuadraticSmoothRel : public SVGPathSegSingleCoordinate {
+class SVGPathSegCurvetoQuadraticSmoothRel FINAL : public SVGPathSegSingleCoordinate {
public:
static PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; }
- virtual String pathSegTypeAsLetter() const { return "t"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "t"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl
index d464af064f1..a1e6abad187 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegCurvetoQuadraticSmoothRel.idl
@@ -24,8 +24,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegCurvetoQuadraticSmoothRel : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegCurvetoQuadraticSmoothRel : SVGPathSeg {
+ attribute float x;
+ attribute float y;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.h
index ee575eabfd2..b452ba35c75 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegLinetoAbs : public SVGPathSegSingleCoordinate {
+class SVGPathSegLinetoAbs FINAL : public SVGPathSegSingleCoordinate {
public:
static PassRefPtr<SVGPathSegLinetoAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_LINETO_ABS; }
- virtual String pathSegTypeAsLetter() const { return "L"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_LINETO_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "L"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.idl
index 1f9dd9882fc..e1c1f5c691b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoAbs.idl
@@ -24,8 +24,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegLinetoAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegLinetoAbs : SVGPathSeg {
+ attribute float x;
+ attribute float y;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.h
index 8e8f8060f39..a54d7d177c5 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegLinetoHorizontalAbs : public SVGPathSegLinetoHorizontal {
+class SVGPathSegLinetoHorizontalAbs FINAL : public SVGPathSegLinetoHorizontal {
public:
static PassRefPtr<SVGPathSegLinetoHorizontalAbs> create(SVGPathElement* element, SVGPathSegRole role, float x)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_LINETO_HORIZONTAL_ABS; }
- virtual String pathSegTypeAsLetter() const { return "H"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_LINETO_HORIZONTAL_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "H"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.idl
index f36159d0e52..08d774c526f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalAbs.idl
@@ -24,7 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegLinetoHorizontalAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegLinetoHorizontalAbs : SVGPathSeg {
+ attribute float x;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.h
index 974c41ce3c8..5c172a42896 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegLinetoHorizontalRel : public SVGPathSegLinetoHorizontal {
+class SVGPathSegLinetoHorizontalRel FINAL : public SVGPathSegLinetoHorizontal {
public:
static PassRefPtr<SVGPathSegLinetoHorizontalRel> create(SVGPathElement* element, SVGPathSegRole role, float x)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_LINETO_HORIZONTAL_REL; }
- virtual String pathSegTypeAsLetter() const { return "h"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_LINETO_HORIZONTAL_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "h"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.idl
index fdbb1c8ec3e..34d378dfc9f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoHorizontalRel.idl
@@ -24,7 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegLinetoHorizontalRel : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegLinetoHorizontalRel : SVGPathSeg {
+ attribute float x;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.h
index 53dc883abd1..d92d59f4948 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegLinetoRel : public SVGPathSegSingleCoordinate {
+class SVGPathSegLinetoRel FINAL : public SVGPathSegSingleCoordinate {
public:
static PassRefPtr<SVGPathSegLinetoRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_LINETO_REL; }
- virtual String pathSegTypeAsLetter() const { return "l"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_LINETO_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "l"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.idl
index 4d24898faa7..f356c17854a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoRel.idl
@@ -24,8 +24,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegLinetoRel : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegLinetoRel : SVGPathSeg {
+ attribute float x;
+ attribute float y;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.h
index 66d86a1f079..a8f96233e79 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegLinetoVerticalAbs : public SVGPathSegLinetoVertical {
+class SVGPathSegLinetoVerticalAbs FINAL : public SVGPathSegLinetoVertical {
public:
static PassRefPtr<SVGPathSegLinetoVerticalAbs> create(SVGPathElement* element, SVGPathSegRole role, float y)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_LINETO_VERTICAL_ABS; }
- virtual String pathSegTypeAsLetter() const { return "V"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_LINETO_VERTICAL_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "V"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.idl
index db7dc1c4698..9c6aaa904bf 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalAbs.idl
@@ -24,7 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegLinetoVerticalAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float y;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegLinetoVerticalAbs : SVGPathSeg {
+ attribute float y;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.h
index f420315e32c..78675806ddd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegLinetoVerticalRel : public SVGPathSegLinetoVertical {
+class SVGPathSegLinetoVerticalRel FINAL : public SVGPathSegLinetoVertical {
public:
static PassRefPtr<SVGPathSegLinetoVerticalRel> create(SVGPathElement* element, SVGPathSegRole role, float y)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_LINETO_VERTICAL_REL; }
- virtual String pathSegTypeAsLetter() const { return "v"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_LINETO_VERTICAL_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "v"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.idl
index 24cf7ff8871..36f44d4fe59 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegLinetoVerticalRel.idl
@@ -24,7 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegLinetoVerticalRel : SVGPathSeg {
- [StrictTypeChecking] attribute float y;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegLinetoVerticalRel : SVGPathSeg {
+ attribute float y;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.cpp
index 475a0437d95..d0a7e5dab97 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.cpp
@@ -24,23 +24,216 @@
#include "core/svg/SVGPathSegList.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
+#include "core/svg/SVGAnimationElement.h"
+#include "core/svg/SVGPathBlender.h"
+#include "core/svg/SVGPathByteStreamBuilder.h"
+#include "core/svg/SVGPathByteStreamSource.h"
#include "core/svg/SVGPathElement.h"
+#include "core/svg/SVGPathParser.h"
+#include "core/svg/SVGPathSegListBuilder.h"
+#include "core/svg/SVGPathSegListSource.h"
#include "core/svg/SVGPathUtilities.h"
namespace WebCore {
-String SVGPathSegList::valueAsString() const
+SVGPathSegList::SVGPathSegList(SVGPathElement* contextElement, SVGPathSegRole role)
+ : m_contextElement(contextElement)
+ , m_role(role)
+ , m_listSyncedToByteStream(true)
{
- String pathString;
- buildStringFromSVGPathSegList(*this, pathString, UnalteredParsing);
- return pathString;
+ ASSERT(contextElement);
}
-void SVGPathSegList::commitChange(SVGElement* contextElement, ListModification listModification)
+SVGPathSegList::SVGPathSegList(SVGPathElement* contextElement, SVGPathSegRole role, PassOwnPtr<SVGPathByteStream> byteStream)
+ : m_contextElement(contextElement)
+ , m_role(role)
+ , m_byteStream(byteStream)
+ , m_listSyncedToByteStream(true)
{
ASSERT(contextElement);
- toSVGPathElement(contextElement)->pathSegListChanged(m_role, listModification);
+}
+
+SVGPathSegList::~SVGPathSegList()
+{
+}
+
+PassRefPtr<SVGPathSegList> SVGPathSegList::clone()
+{
+ RefPtr<SVGPathSegList> svgPathSegList = adoptRef(new SVGPathSegList(m_contextElement, m_role, byteStream()->copy()));
+ svgPathSegList->invalidateList();
+ return svgPathSegList.release();
+}
+
+PassRefPtr<SVGPropertyBase> SVGPathSegList::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGPathSegList> svgPathSegList = SVGPathSegList::create(m_contextElement);
+ svgPathSegList->setValueAsString(value, IGNORE_EXCEPTION);
+ return svgPathSegList;
+}
+
+const SVGPathByteStream* SVGPathSegList::byteStream() const
+{
+ if (!m_byteStream) {
+ m_byteStream = SVGPathByteStream::create();
+
+ if (!Base::isEmpty()) {
+ SVGPathByteStreamBuilder builder;
+ builder.setCurrentByteStream(m_byteStream.get());
+
+ SVGPathSegListSource source(begin(), end());
+
+ SVGPathParser parser;
+ parser.setCurrentConsumer(&builder);
+ parser.setCurrentSource(&source);
+ parser.parsePathDataFromSource(UnalteredParsing);
+ }
+ }
+
+ return m_byteStream.get();
+}
+
+void SVGPathSegList::updateListFromByteStream()
+{
+ if (m_listSyncedToByteStream)
+ return;
+
+ Base::clear();
+
+ if (m_byteStream && !m_byteStream->isEmpty()) {
+ SVGPathSegListBuilder builder;
+ builder.setCurrentSVGPathElement(m_contextElement);
+ builder.setCurrentSVGPathSegList(this);
+ builder.setCurrentSVGPathSegRole(PathSegUnalteredRole);
+
+ SVGPathByteStreamSource source(m_byteStream.get());
+
+ SVGPathParser parser;
+ parser.setCurrentConsumer(&builder);
+ parser.setCurrentSource(&source);
+ parser.parsePathDataFromSource(UnalteredParsing);
+ }
+
+ m_listSyncedToByteStream = true;
+}
+
+void SVGPathSegList::invalidateList()
+{
+ m_listSyncedToByteStream = false;
+ Base::clear();
+}
+
+PassRefPtr<SVGPathSeg> SVGPathSegList::appendItem(PassRefPtr<SVGPathSeg> passItem)
+{
+ updateListFromByteStream();
+ RefPtr<SVGPathSeg> item = Base::appendItem(passItem);
+
+ if (m_byteStream) {
+ SVGPathByteStreamBuilder builder;
+ builder.setCurrentByteStream(m_byteStream.get());
+
+ SVGPathSegListSource source(lastAppended(), end());
+
+ SVGPathParser parser;
+ parser.setCurrentConsumer(&builder);
+ parser.setCurrentSource(&source);
+ parser.parsePathDataFromSource(UnalteredParsing, false);
+ }
+
+ return item.release();
+}
+
+String SVGPathSegList::valueAsString() const
+{
+ String string;
+ buildStringFromByteStream(byteStream(), string, UnalteredParsing);
+ return string;
+}
+
+void SVGPathSegList::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+ invalidateList();
+ if (!m_byteStream)
+ m_byteStream = SVGPathByteStream::create();
+ if (!buildSVGPathByteStreamFromString(string, m_byteStream.get(), UnalteredParsing))
+ exceptionState.throwDOMException(SyntaxError, "Problem parsing path \"" + string + "\"");
+}
+
+void SVGPathSegList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ RefPtr<SVGPathSegList> otherList = toSVGPathSegList(other);
+ if (length() != otherList->length())
+ return;
+
+ byteStream(); // create |m_byteStream| if not exist.
+ addToSVGPathByteStream(m_byteStream.get(), otherList->byteStream());
+ invalidateList();
+}
+
+void SVGPathSegList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
+{
+ invalidateList();
+
+ ASSERT(animationElement);
+ bool isToAnimation = animationElement->animationMode() == ToAnimation;
+
+ const RefPtr<SVGPathSegList> from = toSVGPathSegList(fromValue);
+ const RefPtr<SVGPathSegList> to = toSVGPathSegList(toValue);
+ const RefPtr<SVGPathSegList> toAtEndOfDuration = toSVGPathSegList(toAtEndOfDurationValue);
+
+ const SVGPathByteStream* toStream = to->byteStream();
+ const SVGPathByteStream* fromStream = from->byteStream();
+ OwnPtr<SVGPathByteStream> copy;
+
+ // If no 'to' value is given, nothing to animate.
+ if (!toStream->size())
+ return;
+
+ if (isToAnimation) {
+ copy = byteStream()->copy();
+ fromStream = copy.get();
+ }
+
+ // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
+ if (fromStream->size() != toStream->size() && fromStream->size()) {
+ if (percentage < 0.5) {
+ if (!isToAnimation) {
+ m_byteStream = fromStream->copy();
+ return;
+ }
+ } else {
+ m_byteStream = toStream->copy();
+ return;
+ }
+ }
+
+ OwnPtr<SVGPathByteStream> lastAnimatedStream = m_byteStream.release();
+
+ m_byteStream = SVGPathByteStream::create();
+ SVGPathByteStreamBuilder builder;
+ builder.setCurrentByteStream(m_byteStream.get());
+
+ SVGPathByteStreamSource fromSource(fromStream);
+ SVGPathByteStreamSource toSource(toStream);
+
+ SVGPathBlender blender;
+ blender.blendAnimatedPath(percentage, &fromSource, &toSource, &builder);
+
+ // Handle additive='sum'.
+ if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation))
+ addToSVGPathByteStream(m_byteStream.get(), lastAnimatedStream.get());
+
+ // Handle accumulate='sum'.
+ if (animationElement->isAccumulated() && repeatCount) {
+ const SVGPathByteStream* toAtEndOfDurationStream = toAtEndOfDuration->byteStream();
+ addToSVGPathByteStream(m_byteStream.get(), toAtEndOfDurationStream, repeatCount);
+ }
+}
+
+float SVGPathSegList::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*)
+{
+ // FIXME: Support paced animations.
+ return -1;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.h
index cca091e4e80..9e2f0b91b4d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.h
@@ -1,56 +1,178 @@
/*
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGPathSegList_h
#define SVGPathSegList_h
+#include "core/svg/SVGPathByteStream.h"
#include "core/svg/SVGPathSeg.h"
-#include "core/svg/properties/SVGListProperty.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
+#include "core/svg/properties/SVGListPropertyHelper.h"
+#include "wtf/WeakPtr.h"
namespace WebCore {
-class SVGElement;
+class SVGPathElement;
+class SVGPathSegListTearOff;
-class SVGPathSegList : public Vector<RefPtr<SVGPathSeg> > {
+class SVGPathSegList : public SVGListPropertyHelper<SVGPathSegList, SVGPathSeg> {
public:
- SVGPathSegList(SVGPathSegRole role)
- : m_role(role)
+ typedef void PrimitiveType;
+ typedef SVGPathSeg ItemPropertyType;
+ typedef SVGPathSegListTearOff TearOffType;
+ typedef SVGListPropertyHelper<SVGPathSegList, SVGPathSeg> Base;
+
+ static PassRefPtr<SVGPathSegList> create(SVGPathElement* contextElement, SVGPathSegRole role = PathSegUndefinedRole)
+ {
+ return adoptRef(new SVGPathSegList(contextElement, role));
+ }
+
+ virtual ~SVGPathSegList();
+
+ const SVGPathByteStream* byteStream() const;
+ void clearByteStream() { m_byteStream.clear(); }
+
+ // SVGListPropertyHelper methods with |m_byteStream| sync:
+
+ ItemPropertyType* at(size_t index)
+ {
+ updateListFromByteStream();
+ return Base::at(index);
+ }
+
+ size_t length()
+ {
+ updateListFromByteStream();
+ return Base::length();
+ }
+
+ bool isEmpty() const
+ {
+ if (m_listSyncedToByteStream)
+ return Base::isEmpty();
+
+ return !m_byteStream || m_byteStream->isEmpty();
+ }
+
+ void clear()
+ {
+ clearByteStream();
+ Base::clear();
+ }
+
+ void append(PassRefPtr<ItemPropertyType> passNewItem)
+ {
+ updateListFromByteStream();
+ clearByteStream();
+ Base::append(passNewItem);
+ }
+
+ PassRefPtr<ItemPropertyType> initialize(PassRefPtr<ItemPropertyType> passItem)
+ {
+ clearByteStream();
+ return Base::initialize(passItem);
+ }
+
+ PassRefPtr<ItemPropertyType> getItem(size_t index, ExceptionState& exceptionState)
+ {
+ updateListFromByteStream();
+ return Base::getItem(index, exceptionState);
+ }
+
+ PassRefPtr<ItemPropertyType> insertItemBefore(PassRefPtr<ItemPropertyType> passItem, size_t index)
+ {
+ updateListFromByteStream();
+ clearByteStream();
+ return Base::insertItemBefore(passItem, index);
+ }
+
+ PassRefPtr<ItemPropertyType> replaceItem(PassRefPtr<ItemPropertyType> passItem, size_t index, ExceptionState& exceptionState)
+ {
+ updateListFromByteStream();
+ clearByteStream();
+ return Base::replaceItem(passItem, index, exceptionState);
+ }
+
+ PassRefPtr<ItemPropertyType> removeItem(size_t index, ExceptionState& exceptionState)
{
+ updateListFromByteStream();
+ clearByteStream();
+ return Base::removeItem(index, exceptionState);
}
- String valueAsString() const;
+ PassRefPtr<ItemPropertyType> appendItem(PassRefPtr<ItemPropertyType> passItem);
+
+ // SVGPropertyBase:
+ PassRefPtr<SVGPathSegList> clone();
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+ virtual String valueAsString() const OVERRIDE;
+ void setValueAsString(const String&, ExceptionState&);
- // Only used by SVGPathSegListPropertyTearOff.
- void commitChange(SVGElement* contextElement, ListModification);
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedPath; }
private:
+ SVGPathSegList(SVGPathElement*, SVGPathSegRole);
+ SVGPathSegList(SVGPathElement*, SVGPathSegRole, PassOwnPtr<SVGPathByteStream>);
+
+ friend class SVGPathSegListBuilder;
+ // This is only to be called from SVGPathSegListBuilder.
+ void appendWithoutByteStreamSync(PassRefPtr<ItemPropertyType> passNewItem)
+ {
+ Base::append(passNewItem);
+ }
+
+ void updateListFromByteStream();
+ void invalidateList();
+
+ // FIXME: This pointer should be removed after SVGPathSeg has a tear-off.
+ // FIXME: oilpan: This is raw-ptr to avoid reference cycles.
+ // SVGPathSegList is either owned by SVGAnimatedPath or
+ // SVGPathSegListTearOff. Both keep |contextElement| alive,
+ // so this ptr is always valid.
+ SVGPathElement* m_contextElement;
+
SVGPathSegRole m_role;
+ mutable OwnPtr<SVGPathByteStream> m_byteStream;
+ bool m_listSyncedToByteStream;
};
-template<>
-struct SVGPropertyTraits<SVGPathSegList> {
- static SVGPathSegList initialValue() { return SVGPathSegList(PathSegUndefinedRole); }
- typedef RefPtr<SVGPathSeg> ListItemType;
-};
+inline PassRefPtr<SVGPathSegList> toSVGPathSegList(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGPathSegList::classType());
+ return static_pointer_cast<SVGPathSegList>(base.release());
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.idl
index 33f734e7e63..5e896e441a7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegList.idl
@@ -24,15 +24,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegList {
- readonly attribute unsigned long numberOfItems;
+[
+ TypeChecking=Interface|Nullable,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ ImplementedAs=SVGPathSegListTearOff
+] interface SVGPathSegList {
+ readonly attribute unsigned long length;
+ [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
[RaisesException] void clear();
- [StrictTypeChecking, RaisesException] SVGPathSeg initialize(SVGPathSeg newItem);
- [StrictTypeChecking, RaisesException] SVGPathSeg getItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGPathSeg insertItemBefore(SVGPathSeg newItem, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGPathSeg replaceItem(SVGPathSeg newItem, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGPathSeg removeItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGPathSeg appendItem(SVGPathSeg newItem);
+ [RaisesException] SVGPathSeg initialize(SVGPathSeg newItem);
+ [RaisesException] getter SVGPathSeg getItem(unsigned long index);
+ [RaisesException] setter SVGPathSeg (unsigned long index, SVGPathSeg value);
+ [RaisesException] SVGPathSeg insertItemBefore(SVGPathSeg newItem, unsigned long index);
+ [RaisesException] SVGPathSeg replaceItem(SVGPathSeg newItem, unsigned long index);
+ [RaisesException] SVGPathSeg removeItem(unsigned long index);
+ [RaisesException] SVGPathSeg appendItem(SVGPathSeg newItem);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp
index b394f526c14..ce061aaaa2e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp
@@ -51,7 +51,7 @@ namespace WebCore {
SVGPathSegListBuilder::SVGPathSegListBuilder()
: m_pathElement(0)
- , m_pathSegList(0)
+ , m_pathSegList(nullptr)
, m_pathSegRole(PathSegUndefinedRole)
{
}
@@ -61,9 +61,9 @@ void SVGPathSegListBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoor
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegMovetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegMovetoAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegMovetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegMovetoRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
}
void SVGPathSegListBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -71,9 +71,9 @@ void SVGPathSegListBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinate
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegLinetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegLinetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
}
void SVGPathSegListBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
@@ -81,9 +81,9 @@ void SVGPathSegListBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegLinetoHorizontalAbs(x, m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoHorizontalAbs::create(m_pathElement, m_pathSegRole, x));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegLinetoHorizontalRel(x, m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoHorizontalRel::create(m_pathElement, m_pathSegRole, x));
}
void SVGPathSegListBuilder::lineToVertical(float y, PathCoordinateMode mode)
@@ -91,9 +91,9 @@ void SVGPathSegListBuilder::lineToVertical(float y, PathCoordinateMode mode)
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegLinetoVerticalAbs(y, m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoVerticalAbs::create(m_pathElement, m_pathSegRole, y));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegLinetoVerticalRel(y, m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoVerticalRel::create(m_pathElement, m_pathSegRole, y));
}
void SVGPathSegListBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -101,9 +101,9 @@ void SVGPathSegListBuilder::curveToCubic(const FloatPoint& point1, const FloatPo
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoCubicAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y()));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoCubicRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y()));
}
void SVGPathSegListBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -111,9 +111,9 @@ void SVGPathSegListBuilder::curveToCubicSmooth(const FloatPoint& point2, const F
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicSmoothAbs(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoCubicSmoothAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point2.x(), point2.y()));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicSmoothRel(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoCubicSmoothRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point2.x(), point2.y()));
}
void SVGPathSegListBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -121,9 +121,9 @@ void SVGPathSegListBuilder::curveToQuadratic(const FloatPoint& point1, const Flo
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoQuadraticAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point1.x(), point1.y()));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoQuadraticRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point1.x(), point1.y()));
}
void SVGPathSegListBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -131,9 +131,9 @@ void SVGPathSegListBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticSmoothAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoQuadraticSmoothAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticSmoothRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoQuadraticSmoothRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
}
void SVGPathSegListBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -141,16 +141,16 @@ void SVGPathSegListBuilder::arcTo(float r1, float r2, float angle, bool largeArc
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
if (mode == AbsoluteCoordinates)
- m_pathSegList->append(m_pathElement->createSVGPathSegArcAbs(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegArcAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag));
else
- m_pathSegList->append(m_pathElement->createSVGPathSegArcRel(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegArcRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag));
}
void SVGPathSegListBuilder::closePath()
{
ASSERT(m_pathElement);
ASSERT(m_pathSegList);
- m_pathSegList->append(m_pathElement->createSVGPathSegClosePath(m_pathSegRole));
+ m_pathSegList->appendWithoutByteStreamSync(SVGPathSegClosePath::create(m_pathElement, m_pathSegRole));
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.h
index 7b5c3aacbe2..e5e7641a8a1 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.h
@@ -32,40 +32,40 @@ namespace WebCore {
class SVGPathElement;
-class SVGPathSegListBuilder : public SVGPathConsumer {
+class SVGPathSegListBuilder FINAL : public SVGPathConsumer {
public:
SVGPathSegListBuilder();
void setCurrentSVGPathElement(SVGPathElement* pathElement) { m_pathElement = pathElement; }
- void setCurrentSVGPathSegList(SVGPathSegList& pathSegList) { m_pathSegList = &pathSegList; }
+ void setCurrentSVGPathSegList(PassRefPtr<SVGPathSegList> pathSegList) { m_pathSegList = pathSegList; }
void setCurrentSVGPathSegRole(SVGPathSegRole pathSegRole) { m_pathSegRole = pathSegRole; }
private:
- virtual void incrementPathSegmentCount() { }
- virtual bool continueConsuming() { return true; }
- virtual void cleanup()
+ virtual void incrementPathSegmentCount() OVERRIDE { }
+ virtual bool continueConsuming() OVERRIDE { return true; }
+ virtual void cleanup() OVERRIDE
{
m_pathElement = 0;
- m_pathSegList = 0;
+ m_pathSegList = nullptr;
m_pathSegRole = PathSegUndefinedRole;
}
// Used in UnalteredParsing/NormalizedParsing modes.
- virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode);
- virtual void lineTo(const FloatPoint&, PathCoordinateMode);
- virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void closePath();
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) OVERRIDE;
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void closePath() OVERRIDE;
// Only used in UnalteredParsing mode.
- virtual void lineToHorizontal(float, PathCoordinateMode);
- virtual void lineToVertical(float, PathCoordinateMode);
- virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode);
- virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode);
+ virtual void lineToHorizontal(float, PathCoordinateMode) OVERRIDE;
+ virtual void lineToVertical(float, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) OVERRIDE;
SVGPathElement* m_pathElement;
- SVGPathSegList* m_pathSegList;
+ RefPtr<SVGPathSegList> m_pathSegList;
SVGPathSegRole m_pathSegRole;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp
index 2df5505067a..c58a68c458f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp
@@ -30,31 +30,30 @@
namespace WebCore {
-SVGPathSegListSource::SVGPathSegListSource(const SVGPathSegList& pathSegList)
- : m_pathSegList(pathSegList)
+SVGPathSegListSource::SVGPathSegListSource(SVGPathSegList::ConstIterator itBegin, SVGPathSegList::ConstIterator itEnd)
+ : m_itCurrent(itBegin)
+ , m_itEnd(itEnd)
{
- m_itemCurrent = 0;
- m_itemEnd = m_pathSegList.size();
}
bool SVGPathSegListSource::hasMoreData() const
{
- return m_itemCurrent < m_itemEnd;
+ return m_itCurrent != m_itEnd;
}
bool SVGPathSegListSource::parseSVGSegmentType(SVGPathSegType& pathSegType)
{
- m_segment = m_pathSegList.at(m_itemCurrent);
+ m_segment = *m_itCurrent;
pathSegType = static_cast<SVGPathSegType>(m_segment->pathSegType());
- ++m_itemCurrent;
+ ++m_itCurrent;
return true;
}
SVGPathSegType SVGPathSegListSource::nextCommand(SVGPathSegType)
{
- m_segment = m_pathSegList.at(m_itemCurrent);
+ m_segment = *m_itCurrent;
SVGPathSegType pathSegType = static_cast<SVGPathSegType>(m_segment->pathSegType());
- ++m_itemCurrent;
+ ++m_itCurrent;
return pathSegType;
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.h
index 9ff02c4d8ba..0ed2b8bea5c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListSource.h
@@ -29,35 +29,29 @@
namespace WebCore {
-class SVGPathSegListSource : public SVGPathSource {
+class SVGPathSegListSource FINAL : public SVGPathSource {
public:
- static PassOwnPtr<SVGPathSegListSource> create(const SVGPathSegList& pathSegList)
- {
- return adoptPtr(new SVGPathSegListSource(pathSegList));
- }
+ SVGPathSegListSource(SVGPathSegList::ConstIterator, SVGPathSegList::ConstIterator);
private:
- SVGPathSegListSource(const SVGPathSegList&);
+ virtual bool hasMoreData() const OVERRIDE;
+ virtual bool moveToNextToken() OVERRIDE { return true; }
+ virtual bool parseSVGSegmentType(SVGPathSegType&) OVERRIDE;
+ virtual SVGPathSegType nextCommand(SVGPathSegType) OVERRIDE;
+
+ virtual bool parseMoveToSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseLineToSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseLineToHorizontalSegment(float&) OVERRIDE;
+ virtual bool parseLineToVerticalSegment(float&) OVERRIDE;
+ virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) OVERRIDE;
- virtual bool hasMoreData() const;
- virtual bool moveToNextToken() { return true; }
- virtual bool parseSVGSegmentType(SVGPathSegType&);
- virtual SVGPathSegType nextCommand(SVGPathSegType);
-
- virtual bool parseMoveToSegment(FloatPoint&);
- virtual bool parseLineToSegment(FloatPoint&);
- virtual bool parseLineToHorizontalSegment(float&);
- virtual bool parseLineToVerticalSegment(float&);
- virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&);
- virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&);
- virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&);
- virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&);
- virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&);
-
- const SVGPathSegList& m_pathSegList;
RefPtr<SVGPathSeg> m_segment;
- int m_itemCurrent;
- int m_itemEnd;
+ SVGPathSegList::ConstIterator m_itCurrent;
+ SVGPathSegList::ConstIterator m_itEnd;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListTearOff.h
new file mode 100644
index 00000000000..304aaae0030
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegListTearOff.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGPathSegListTearOff_h
+#define SVGPathSegListTearOff_h
+
+#include "core/SVGNames.h"
+#include "core/svg/SVGPathSegList.h"
+#include "core/svg/properties/SVGListPropertyTearOffHelper.h"
+
+namespace WebCore {
+
+template<>
+class ListItemPropertyTraits<SVGPathSeg> {
+public:
+ typedef SVGPathSeg ItemPropertyType;
+ // FIXME: Currently SVGPathSegitself is a tear-off.
+ typedef SVGPathSeg ItemTearOffType;
+
+ static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem, SVGElement* contextElement, const QualifiedName& attributeName)
+ {
+ ASSERT(attributeName == SVGNames::dAttr);
+ RefPtr<ItemTearOffType> newItem = passNewItem;
+ newItem->setContextElement(contextElement);
+ return newItem.release();
+ }
+
+ static PassRefPtr<ItemTearOffType> createTearOff(PassRefPtr<ItemPropertyType> passValue, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName&)
+ {
+ RefPtr<SVGPathSeg> value = passValue;
+ value->setContextElement(contextElement);
+ return value.release();
+ }
+};
+
+class SVGPathSegListTearOff FINAL :
+ public SVGListPropertyTearOffHelper<SVGPathSegListTearOff, SVGPathSegList>,
+ public ScriptWrappable {
+public:
+ static PassRefPtr<SVGPathSegListTearOff> create(PassRefPtr<SVGPathSegList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGPathSegListTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+private:
+ SVGPathSegListTearOff(PassRefPtr<SVGPathSegList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ : SVGListPropertyTearOffHelper<SVGPathSegListTearOff, SVGPathSegList>(target, contextElement, propertyIsAnimVal, attributeName)
+ {
+ ScriptWrappable::init(this);
+ }
+};
+
+} // namespace WebCore
+
+#endif // SVGPathSegListTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.h
index 4b6527e32cc..5e2b0f89c43 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegMovetoAbs : public SVGPathSegSingleCoordinate {
+class SVGPathSegMovetoAbs FINAL : public SVGPathSegSingleCoordinate {
public:
static PassRefPtr<SVGPathSegMovetoAbs> create(SVGPathElement* element, SVGPathSegRole role, float x, float y)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_MOVETO_ABS; }
- virtual String pathSegTypeAsLetter() const { return "M"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_MOVETO_ABS; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "M"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.idl
index 220401ea812..b2573393297 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoAbs.idl
@@ -24,8 +24,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegMovetoAbs : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegMovetoAbs : SVGPathSeg {
+ attribute float x;
+ attribute float y;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.h
index 023c3e930d3..0d4b5d8b902 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.h
@@ -26,7 +26,7 @@
namespace WebCore {
-class SVGPathSegMovetoRel : public SVGPathSegSingleCoordinate {
+class SVGPathSegMovetoRel FINAL : public SVGPathSegSingleCoordinate {
public:
static PassRefPtr<SVGPathSegMovetoRel> create(SVGPathElement* element, SVGPathSegRole role, float x, float y)
{
@@ -40,8 +40,8 @@ private:
ScriptWrappable::init(this);
}
- virtual unsigned short pathSegType() const { return PATHSEG_MOVETO_REL; }
- virtual String pathSegTypeAsLetter() const { return "m"; }
+ virtual unsigned short pathSegType() const OVERRIDE { return PATHSEG_MOVETO_REL; }
+ virtual String pathSegTypeAsLetter() const OVERRIDE { return "m"; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.idl
index 586868563eb..15891e3f106 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegMovetoRel.idl
@@ -24,8 +24,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPathSegMovetoRel : SVGPathSeg {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGPathSegMovetoRel : SVGPathSeg {
+ attribute float x;
+ attribute float y;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegWithContext.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegWithContext.h
index c12689d24dc..a6502a0452a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathSegWithContext.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathSegWithContext.h
@@ -20,56 +20,18 @@
#ifndef SVGPathSegWithContext_h
#define SVGPathSegWithContext_h
-#include "core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h"
+#include "core/svg/SVGPathSeg.h"
namespace WebCore {
+// FIXME: This should be deprecated.
class SVGPathSegWithContext : public SVGPathSeg {
public:
- SVGPathSegWithContext(SVGPathElement* element, SVGPathSegRole role)
- : m_role(role)
- , m_element(element)
+ // FIXME: remove second unused argument from all derived classes.
+ SVGPathSegWithContext(SVGPathElement* contextElement, SVGPathSegRole)
+ : SVGPathSeg(contextElement)
{
}
-
- SVGAnimatedProperty* animatedProperty() const
- {
- switch (m_role) {
- case PathSegUndefinedRole:
- return 0;
- case PathSegUnalteredRole:
- return SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(m_element, SVGPathElement::dPropertyInfo());
- case PathSegNormalizedRole:
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
- return 0;
- };
-
- return 0;
- }
-
- SVGPathElement* contextElement() const { return m_element; }
- SVGPathSegRole role() const { return m_role; }
-
- void setContextAndRole(SVGPathElement* element, SVGPathSegRole role)
- {
- m_role = role;
- m_element = element;
- }
-
-protected:
- void commitChange()
- {
- if (!m_element) {
- ASSERT(m_role == PathSegUndefinedRole);
- return;
- }
-
- m_element->pathSegListChanged(m_role);
- }
-
-private:
- SVGPathSegRole m_role;
- SVGPathElement* m_element;
};
class SVGPathSegSingleCoordinate : public SVGPathSegWithContext {
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.cpp
index 580454b7b81..e3c5905e833 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.cpp
@@ -35,96 +35,100 @@ String SVGPathStringBuilder::result()
return m_stringBuilder.toString();
}
+static void appendFloat(StringBuilder& stringBuilder, float value)
+{
+ stringBuilder.append(' ');
+ stringBuilder.appendNumber(value);
+}
+
+static void appendBool(StringBuilder& stringBuilder, bool value)
+{
+ stringBuilder.append(' ');
+ stringBuilder.appendNumber(value);
+}
+
+static void appendPoint(StringBuilder& stringBuilder, const FloatPoint& point)
+{
+ appendFloat(stringBuilder, point.x());
+ appendFloat(stringBuilder, point.y());
+}
+
+static void emitCommand1Arg(StringBuilder& stringBuilder, char commandChar, float argument)
+{
+ stringBuilder.append(commandChar);
+ appendFloat(stringBuilder, argument);
+ stringBuilder.append(' ');
+}
+
+static void emitCommand1Arg(StringBuilder& stringBuilder, char commandChar, const FloatPoint& argumentPoint)
+{
+ stringBuilder.append(commandChar);
+ appendPoint(stringBuilder, argumentPoint);
+ stringBuilder.append(' ');
+}
+
+static void emitCommand2Arg(StringBuilder& stringBuilder, char commandChar, const FloatPoint& argument1Point, const FloatPoint& argument2Point)
+{
+ stringBuilder.append(commandChar);
+ appendPoint(stringBuilder, argument1Point);
+ appendPoint(stringBuilder, argument2Point);
+ stringBuilder.append(' ');
+}
+
void SVGPathStringBuilder::moveTo(const FloatPoint& targetPoint, bool, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("M " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- else
- m_stringBuilder.append("m " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ emitCommand1Arg(m_stringBuilder, (mode == AbsoluteCoordinates) ? 'M' : 'm', targetPoint);
}
void SVGPathStringBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("L " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- else
- m_stringBuilder.append("l " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ emitCommand1Arg(m_stringBuilder, (mode == AbsoluteCoordinates) ? 'L' : 'l', targetPoint);
}
void SVGPathStringBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("H " + String::number(x) + ' ');
- else
- m_stringBuilder.append("h " + String::number(x) + ' ');
+ emitCommand1Arg(m_stringBuilder, (mode == AbsoluteCoordinates) ? 'H' : 'h', x);
}
void SVGPathStringBuilder::lineToVertical(float y, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("V " + String::number(y) + ' ');
- else
- m_stringBuilder.append("v " + String::number(y) + ' ');
+ emitCommand1Arg(m_stringBuilder, (mode == AbsoluteCoordinates) ? 'V' : 'v', y);
}
void SVGPathStringBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates) {
- m_stringBuilder.append("C " + String::number(point1.x()) + ' ' + String::number(point1.y())
- + ' ' + String::number(point2.x()) + ' ' + String::number(point2.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- return;
- }
-
- m_stringBuilder.append("c " + String::number(point1.x()) + ' ' + String::number(point1.y())
- + ' ' + String::number(point2.x()) + ' ' + String::number(point2.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ m_stringBuilder.append((mode == AbsoluteCoordinates) ? 'C' : 'c');
+ appendPoint(m_stringBuilder, point1);
+ appendPoint(m_stringBuilder, point2);
+ appendPoint(m_stringBuilder, targetPoint);
+ m_stringBuilder.append(' ');
}
void SVGPathStringBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates) {
- m_stringBuilder.append("S " + String::number(point2.x()) + ' ' + String::number(point2.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- return;
- }
-
- m_stringBuilder.append("s " + String::number(point2.x()) + ' ' + String::number(point2.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ emitCommand2Arg(m_stringBuilder, (mode == AbsoluteCoordinates) ? 'S' : 's', point2, targetPoint);
}
void SVGPathStringBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates) {
- m_stringBuilder.append("Q " + String::number(point1.x()) + ' ' + String::number(point1.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- return;
- }
-
- m_stringBuilder.append("q " + String::number(point1.x()) + ' ' + String::number(point1.y())
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ emitCommand2Arg(m_stringBuilder, (mode == AbsoluteCoordinates) ? 'Q' : 'q', point1, targetPoint);
}
void SVGPathStringBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates)
- m_stringBuilder.append("T " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- else
- m_stringBuilder.append("t " + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ emitCommand1Arg(m_stringBuilder, (mode == AbsoluteCoordinates) ? 'T' : 't', targetPoint);
}
void SVGPathStringBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
{
- if (mode == AbsoluteCoordinates) {
- m_stringBuilder.append("A " + String::number(r1) + ' ' + String::number(r2)
- + ' ' + String::number(angle) + ' ' + String::number(largeArcFlag) + ' ' + String::number(sweepFlag)
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
- return;
- }
-
- m_stringBuilder.append("a " + String::number(r1) + ' ' + String::number(r2)
- + ' ' + String::number(angle) + ' ' + String::number(largeArcFlag) + ' ' + String::number(sweepFlag)
- + ' ' + String::number(targetPoint.x()) + ' ' + String::number(targetPoint.y()) + ' ');
+ m_stringBuilder.append((mode == AbsoluteCoordinates) ? 'A' : 'a');
+ appendFloat(m_stringBuilder, r1);
+ appendFloat(m_stringBuilder, r2);
+ appendFloat(m_stringBuilder, angle);
+ appendBool(m_stringBuilder, largeArcFlag);
+ appendBool(m_stringBuilder, sweepFlag);
+ appendPoint(m_stringBuilder, targetPoint);
+ m_stringBuilder.append(' ');
}
void SVGPathStringBuilder::closePath()
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.h
index 68938945e1a..ec1709b5fde 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathStringBuilder.h
@@ -26,28 +26,28 @@
namespace WebCore {
-class SVGPathStringBuilder : public SVGPathConsumer {
+class SVGPathStringBuilder FINAL : public SVGPathConsumer {
public:
String result();
private:
- virtual void cleanup() { m_stringBuilder.clear(); }
- virtual void incrementPathSegmentCount() { }
- virtual bool continueConsuming() { return true; }
+ virtual void cleanup() OVERRIDE { m_stringBuilder.clear(); }
+ virtual void incrementPathSegmentCount() OVERRIDE { }
+ virtual bool continueConsuming() OVERRIDE { return true; }
// Used in UnalteredParsing/NormalizedParsing modes.
- virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode);
- virtual void lineTo(const FloatPoint&, PathCoordinateMode);
- virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void closePath();
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) OVERRIDE;
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void closePath() OVERRIDE;
// Only used in UnalteredParsing mode.
- virtual void lineToHorizontal(float, PathCoordinateMode);
- virtual void lineToVertical(float, PathCoordinateMode);
- virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode);
- virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode);
+ virtual void lineToHorizontal(float, PathCoordinateMode) OVERRIDE;
+ virtual void lineToVertical(float, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) OVERRIDE;
StringBuilder m_stringBuilder;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathStringSource.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathStringSource.h
index a423ad8c1f1..bc85f4f4c21 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathStringSource.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathStringSource.h
@@ -27,7 +27,7 @@
namespace WebCore {
-class SVGPathStringSource : public SVGPathSource {
+class SVGPathStringSource FINAL : public SVGPathSource {
public:
static PassOwnPtr<SVGPathStringSource> create(const String& string)
{
@@ -37,20 +37,20 @@ public:
private:
SVGPathStringSource(const String&);
- virtual bool hasMoreData() const;
- virtual bool moveToNextToken();
- virtual bool parseSVGSegmentType(SVGPathSegType&);
- virtual SVGPathSegType nextCommand(SVGPathSegType previousCommand);
+ virtual bool hasMoreData() const OVERRIDE;
+ virtual bool moveToNextToken() OVERRIDE;
+ virtual bool parseSVGSegmentType(SVGPathSegType&) OVERRIDE;
+ virtual SVGPathSegType nextCommand(SVGPathSegType previousCommand) OVERRIDE;
- virtual bool parseMoveToSegment(FloatPoint&);
- virtual bool parseLineToSegment(FloatPoint&);
- virtual bool parseLineToHorizontalSegment(float&);
- virtual bool parseLineToVerticalSegment(float&);
- virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&);
- virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&);
- virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&);
- virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&);
- virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&);
+ virtual bool parseMoveToSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseLineToSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseLineToHorizontalSegment(float&) OVERRIDE;
+ virtual bool parseLineToVerticalSegment(float&) OVERRIDE;
+ virtual bool parseCurveToCubicSegment(FloatPoint&, FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToCubicSmoothSegment(FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToQuadraticSegment(FloatPoint&, FloatPoint&) OVERRIDE;
+ virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&) OVERRIDE;
+ virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) OVERRIDE;
String m_string;
bool m_is8BitSource;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.cpp
index 1fe2b5cb183..7798ede0793 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.cpp
@@ -87,7 +87,7 @@ float SVGPathTraversalStateBuilder::totalLength()
return m_traversalState->m_totalLength;
}
-SVGPoint SVGPathTraversalStateBuilder::currentPoint()
+FloatPoint SVGPathTraversalStateBuilder::currentPoint()
{
ASSERT(m_traversalState);
return m_traversalState->m_current;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.h
index 59c2434cfe7..22d7a1307a9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathTraversalStateBuilder.h
@@ -28,35 +28,35 @@ namespace WebCore {
class PathTraversalState;
-class SVGPathTraversalStateBuilder : public SVGPathConsumer {
+class SVGPathTraversalStateBuilder FINAL : public SVGPathConsumer {
public:
SVGPathTraversalStateBuilder();
unsigned pathSegmentIndex();
float totalLength();
- SVGPoint currentPoint();
+ FloatPoint currentPoint();
void setCurrentTraversalState(PathTraversalState* traversalState) { m_traversalState = traversalState; }
void setDesiredLength(float);
- virtual void incrementPathSegmentCount();
- virtual bool continueConsuming();
- virtual void cleanup() { m_traversalState = 0; }
+ virtual void incrementPathSegmentCount() OVERRIDE;
+ virtual bool continueConsuming() OVERRIDE;
+ virtual void cleanup() OVERRIDE { m_traversalState = 0; }
private:
// Used in UnalteredParsing/NormalizedParsing modes.
- virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode);
- virtual void lineTo(const FloatPoint&, PathCoordinateMode);
- virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode);
- virtual void closePath();
+ virtual void moveTo(const FloatPoint&, bool closed, PathCoordinateMode) OVERRIDE;
+ virtual void lineTo(const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void curveToCubic(const FloatPoint&, const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE;
+ virtual void closePath() OVERRIDE;
private:
// Not used for PathTraversalState.
- virtual void lineToHorizontal(float, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void lineToVertical(float, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
- virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) { ASSERT_NOT_REACHED(); }
+ virtual void lineToHorizontal(float, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void lineToVertical(float, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void curveToCubicSmooth(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void curveToQuadratic(const FloatPoint&, const FloatPoint&, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void curveToQuadraticSmooth(const FloatPoint&, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
+ virtual void arcTo(float, float, float, bool, bool, const FloatPoint&, PathCoordinateMode) OVERRIDE { ASSERT_NOT_REACHED(); }
PathTraversalState* m_traversalState;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp
index dcbeb40b7b3..51cce510a81 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.cpp
@@ -45,18 +45,6 @@ static SVGPathBuilder* globalSVGPathBuilder(Path& result)
return s_builder;
}
-static SVGPathSegListBuilder* globalSVGPathSegListBuilder(SVGPathElement* element, SVGPathSegRole role, SVGPathSegList& result)
-{
- static SVGPathSegListBuilder* s_builder = 0;
- if (!s_builder)
- s_builder = new SVGPathSegListBuilder;
-
- s_builder->setCurrentSVGPathElement(element);
- s_builder->setCurrentSVGPathSegList(result);
- s_builder->setCurrentSVGPathSegRole(role);
- return s_builder;
-}
-
static SVGPathByteStreamBuilder* globalSVGPathByteStreamBuilder(SVGPathByteStream* result)
{
static SVGPathByteStreamBuilder* s_builder = 0;
@@ -121,45 +109,7 @@ bool buildPathFromString(const String& d, Path& result)
return ok;
}
-bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPathByteStream* result, PathParsingMode parsingMode)
-{
- ASSERT(result);
- result->clear();
- if (list.isEmpty())
- return false;
-
- SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
-
- OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
- bool ok = parser->parsePathDataFromSource(parsingMode);
- parser->cleanup();
- return ok;
-}
-
-bool appendSVGPathByteStreamFromSVGPathSeg(PassRefPtr<SVGPathSeg> pathSeg, SVGPathByteStream* result, PathParsingMode parsingMode)
-{
- ASSERT(result);
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
- ASSERT(parsingMode == UnalteredParsing);
-
- SVGPathSegList appendedItemList(PathSegUnalteredRole);
- appendedItemList.append(pathSeg);
- OwnPtr<SVGPathByteStream> appendedByteStream = SVGPathByteStream::create();
-
- SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(appendedByteStream.get());
- OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(appendedItemList);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
- bool ok = parser->parsePathDataFromSource(parsingMode, false);
- parser->cleanup();
-
- if (ok)
- result->append(appendedByteStream.get());
-
- return ok;
-}
-
-bool buildPathFromByteStream(SVGPathByteStream* stream, Path& result)
+bool buildPathFromByteStream(const SVGPathByteStream* stream, Path& result)
{
ASSERT(stream);
if (stream->isEmpty())
@@ -167,29 +117,14 @@ bool buildPathFromByteStream(SVGPathByteStream* stream, Path& result)
SVGPathBuilder* builder = globalSVGPathBuilder(result);
- OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+ SVGPathByteStreamSource source(stream);
+ SVGPathParser* parser = globalSVGPathParser(&source, builder);
bool ok = parser->parsePathDataFromSource(NormalizedParsing);
parser->cleanup();
return ok;
}
-bool buildSVGPathSegListFromByteStream(SVGPathByteStream* stream, SVGPathElement* element, SVGPathSegList& result, PathParsingMode parsingMode)
-{
- ASSERT(stream);
- if (stream->isEmpty())
- return false;
-
- SVGPathSegListBuilder* builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result);
-
- OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
- bool ok = parser->parsePathDataFromSource(parsingMode);
- parser->cleanup();
- return ok;
-}
-
-bool buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathParsingMode parsingMode)
+bool buildStringFromByteStream(const SVGPathByteStream* stream, String& result, PathParsingMode parsingMode)
{
ASSERT(stream);
if (stream->isEmpty())
@@ -197,24 +132,8 @@ bool buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathPa
SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
- OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
- bool ok = parser->parsePathDataFromSource(parsingMode);
- result = builder->result();
- parser->cleanup();
- return ok;
-}
-
-bool buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode)
-{
- result = String();
- if (list.isEmpty())
- return false;
-
- SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
-
- OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+ SVGPathByteStreamSource source(stream);
+ SVGPathParser* parser = globalSVGPathParser(&source, builder);
bool ok = parser->parsePathDataFromSource(parsingMode);
result = builder->result();
parser->cleanup();
@@ -228,37 +147,22 @@ bool buildSVGPathByteStreamFromString(const String& d, SVGPathByteStream* result
if (d.isEmpty())
return false;
+ // The string length is typically a minor overestimate of eventual byte stream size, so it avoids us a lot of reallocs.
+ result->reserveInitialCapacity(d.length());
+
SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
OwnPtr<SVGPathStringSource> source = SVGPathStringSource::create(d);
SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
bool ok = parser->parsePathDataFromSource(parsingMode);
parser->cleanup();
- return ok;
-}
-
-bool buildAnimatedSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* toStream, SVGPathByteStream* result, float progress)
-{
- ASSERT(fromStream);
- ASSERT(toStream);
- ASSERT(result);
- ASSERT(toStream != result);
- result->clear();
- if (toStream->isEmpty())
- return false;
+ result->shrinkToFit();
- SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
-
- OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStream);
- OwnPtr<SVGPathByteStreamSource> toSource = SVGPathByteStreamSource::create(toStream);
- SVGPathBlender* blender = globalSVGPathBlender();
- bool ok = blender->blendAnimatedPath(progress, fromSource.get(), toSource.get(), builder);
- blender->cleanup();
return ok;
}
-bool addToSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* byStream, unsigned repeatCount)
+bool addToSVGPathByteStream(SVGPathByteStream* fromStream, const SVGPathByteStream* byStream, unsigned repeatCount)
{
ASSERT(fromStream);
ASSERT(byStream);
@@ -270,15 +174,15 @@ bool addToSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* by
OwnPtr<SVGPathByteStream> fromStreamCopy = fromStream->copy();
fromStream->clear();
- OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStreamCopy.get());
- OwnPtr<SVGPathByteStreamSource> bySource = SVGPathByteStreamSource::create(byStream);
+ SVGPathByteStreamSource fromSource(fromStreamCopy.get());
+ SVGPathByteStreamSource bySource(byStream);
SVGPathBlender* blender = globalSVGPathBlender();
- bool ok = blender->addAnimatedPath(fromSource.get(), bySource.get(), builder, repeatCount);
+ bool ok = blender->addAnimatedPath(&fromSource, &bySource, builder, repeatCount);
blender->cleanup();
return ok;
}
-bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned& pathSeg)
+bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream* stream, float length, unsigned& pathSeg)
{
ASSERT(stream);
if (stream->isEmpty())
@@ -287,15 +191,15 @@ bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float
PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
- OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+ SVGPathByteStreamSource source(stream);
+ SVGPathParser* parser = globalSVGPathParser(&source, builder);
bool ok = parser->parsePathDataFromSource(NormalizedParsing);
pathSeg = builder->pathSegmentIndex();
parser->cleanup();
return ok;
}
-bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength)
+bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream* stream, float& totalLength)
{
ASSERT(stream);
if (stream->isEmpty())
@@ -304,15 +208,15 @@ bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLe
PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0);
- OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+ SVGPathByteStreamSource source(stream);
+ SVGPathParser* parser = globalSVGPathParser(&source, builder);
bool ok = parser->parsePathDataFromSource(NormalizedParsing);
totalLength = builder->totalLength();
parser->cleanup();
return ok;
}
-bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, SVGPoint& point)
+bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream* stream, float length, FloatPoint& point)
{
ASSERT(stream);
if (stream->isEmpty())
@@ -321,8 +225,8 @@ bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length
PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength);
SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
- OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
- SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+ SVGPathByteStreamSource source(stream);
+ SVGPathParser* parser = globalSVGPathParser(&source, builder);
bool ok = parser->parsePathDataFromSource(NormalizedParsing);
point = builder->currentPoint();
parser->cleanup();
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.h b/chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.h
index 7c06c57a46c..e55a6e949ce 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPathUtilities.h
@@ -21,7 +21,7 @@
#define SVGPathUtilities_h
#include "core/svg/SVGPathConsumer.h"
-#include "core/svg/SVGPoint.h"
+#include "platform/geometry/FloatPoint.h"
#include "wtf/OwnPtr.h"
#include "wtf/text/WTFString.h"
@@ -29,32 +29,26 @@ namespace WebCore {
class Path;
class SVGPathByteStream;
-class SVGPathElement;
class SVGPathSeg;
class SVGPathSegList;
// String/SVGPathByteStream -> Path
bool buildPathFromString(const String&, Path&);
-bool buildPathFromByteStream(SVGPathByteStream*, Path&);
+bool buildPathFromByteStream(const SVGPathByteStream*, Path&);
// SVGPathSegList/String -> SVGPathByteStream
-bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList&, SVGPathByteStream*, PathParsingMode);
bool appendSVGPathByteStreamFromSVGPathSeg(PassRefPtr<SVGPathSeg>, SVGPathByteStream*, PathParsingMode);
bool buildSVGPathByteStreamFromString(const String&, SVGPathByteStream*, PathParsingMode);
// SVGPathByteStream/SVGPathSegList -> String
-bool buildStringFromByteStream(SVGPathByteStream*, String&, PathParsingMode);
-bool buildStringFromSVGPathSegList(const SVGPathSegList&, String&, PathParsingMode);
+bool buildStringFromByteStream(const SVGPathByteStream*, String&, PathParsingMode);
+bool buildStringFromSVGPathSegList(PassRefPtr<SVGPathSegList>, String&, PathParsingMode);
-// SVGPathByteStream -> SVGPathSegList
-bool buildSVGPathSegListFromByteStream(SVGPathByteStream*, SVGPathElement*, SVGPathSegList&, PathParsingMode);
+bool addToSVGPathByteStream(SVGPathByteStream*, const SVGPathByteStream*, unsigned repeatCount = 1);
-bool buildAnimatedSVGPathByteStream(SVGPathByteStream*, SVGPathByteStream*, SVGPathByteStream*, float);
-bool addToSVGPathByteStream(SVGPathByteStream*, SVGPathByteStream*, unsigned repeatCount = 1);
-
-bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream*, float length, unsigned& pathSeg);
-bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream*, float& totalLength);
-bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream*, float length, SVGPoint&);
+bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream*, float length, unsigned& pathSeg);
+bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream*, float& totalLength);
+bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream*, float length, FloatPoint&);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.cpp
index 110bd77a5ea..576020715d9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.cpp
@@ -23,68 +23,46 @@
#include "core/svg/SVGPatternElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
+#include "core/dom/ElementTraversal.h"
#include "core/rendering/svg/RenderSVGResourcePattern.h"
#include "core/svg/PatternAttributes.h"
-#include "core/svg/SVGElementInstance.h"
#include "platform/transforms/AffineTransform.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGPatternElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGPatternElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGPatternElement, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGPatternElement, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_ENUMERATION(SVGPatternElement, SVGNames::patternUnitsAttr, PatternUnits, patternUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_ENUMERATION(SVGPatternElement, SVGNames::patternContentUnitsAttr, PatternContentUnits, patternContentUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_TRANSFORM_LIST(SVGPatternElement, SVGNames::patternTransformAttr, PatternTransform, patternTransform)
-DEFINE_ANIMATED_STRING(SVGPatternElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGPatternElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-DEFINE_ANIMATED_RECT(SVGPatternElement, SVGNames::viewBoxAttr, ViewBox, viewBox)
-DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGPatternElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGPatternElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(patternUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(patternContentUnits)
- REGISTER_LOCAL_ANIMATED_PROPERTY(patternTransform)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_LOCAL_ANIMATED_PROPERTY(viewBox)
- REGISTER_LOCAL_ANIMATED_PROPERTY(preserveAspectRatio)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTests)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGPatternElement::SVGPatternElement(Document& document)
: SVGElement(SVGNames::patternTag, document)
- , m_x(LengthModeWidth)
- , m_y(LengthModeHeight)
- , m_width(LengthModeWidth)
- , m_height(LengthModeHeight)
- , m_patternUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
- , m_patternContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
+ , SVGURIReference(this)
+ , SVGTests(this)
+ , SVGFitToViewBox(this)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
+ , m_patternTransform(SVGAnimatedTransformList::create(this, SVGNames::patternTransformAttr, SVGTransformList::create()))
+ , m_patternUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::patternUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
+ , m_patternContentUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::patternContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGPatternElement();
-}
-PassRefPtr<SVGPatternElement> SVGPatternElement::create(Document& document)
-{
- return adoptRef(new SVGPatternElement(document));
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
+ addToPropertyMap(m_patternTransform);
+ addToPropertyMap(m_patternUnits);
+ addToPropertyMap(m_patternContentUnits);
}
+DEFINE_NODE_FACTORY(SVGPatternElement)
+
bool SVGPatternElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGURIReference::addSupportedAttributes(supportedAttributes);
SVGTests::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
SVGFitToViewBox::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::patternUnitsAttr);
supportedAttributes.add(SVGNames::patternContentUnitsAttr);
@@ -101,38 +79,28 @@ void SVGPatternElement::parseAttribute(const QualifiedName& name, const AtomicSt
{
SVGParsingError parseError = NoError;
- if (!isSupportedAttribute(name))
+ if (!isSupportedAttribute(name)) {
SVGElement::parseAttribute(name, value);
- else if (name == SVGNames::patternUnitsAttr) {
- SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
- if (propertyValue > 0)
- setPatternUnitsBaseValue(propertyValue);
- return;
+ } else if (name == SVGNames::patternUnitsAttr) {
+ m_patternUnits->setBaseValueAsString(value, parseError);
} else if (name == SVGNames::patternContentUnitsAttr) {
- SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
- if (propertyValue > 0)
- setPatternContentUnitsBaseValue(propertyValue);
- return;
+ m_patternContentUnits->setBaseValueAsString(value, parseError);
} else if (name == SVGNames::patternTransformAttr) {
- SVGTransformList newList;
- newList.parse(value);
- detachAnimatedPatternTransformListWrappers(newList.size());
- setPatternTransformBaseValue(newList);
- return;
- } else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
- else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
- else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
- else if (SVGURIReference::parseAttribute(name, value)
- || SVGTests::parseAttribute(name, value)
- || SVGExternalResourcesRequired::parseAttribute(name, value)
- || SVGFitToViewBox::parseAttribute(this, name, value)) {
- } else
+ m_patternTransform->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::xAttr) {
+ m_x->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::yAttr) {
+ m_y->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::widthAttr) {
+ m_width->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::heightAttr) {
+ m_height->setBaseValueAsString(value, parseError);
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else if (SVGTests::parseAttribute(name, value)) {
+ } else if (SVGFitToViewBox::parseAttribute(name, value, document(), parseError)) {
+ } else {
ASSERT_NOT_REACHED();
+ }
reportAttributeParsingError(parseError, name, value);
}
@@ -144,7 +112,7 @@ void SVGPatternElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
@@ -165,7 +133,7 @@ void SVGPatternElement::childrenChanged(bool changedByParser, Node* beforeChange
return;
if (RenderObject* object = renderer())
- object->setNeedsLayout();
+ object->setNeedsLayoutAndFullPaintInvalidation();
}
RenderObject* SVGPatternElement::createRenderer(RenderStyle*)
@@ -173,75 +141,80 @@ RenderObject* SVGPatternElement::createRenderer(RenderStyle*)
return new RenderSVGResourcePattern(this);
}
-void SVGPatternElement::collectPatternAttributes(PatternAttributes& attributes) const
+static void setPatternAttributes(const SVGPatternElement* element, PatternAttributes& attributes)
{
- HashSet<const SVGPatternElement*> processedPatterns;
+ if (!attributes.hasX() && element->x()->isSpecified())
+ attributes.setX(element->x()->currentValue());
- const SVGPatternElement* current = this;
- while (current) {
- if (!attributes.hasX() && current->hasAttribute(SVGNames::xAttr))
- attributes.setX(current->xCurrentValue());
+ if (!attributes.hasY() && element->y()->isSpecified())
+ attributes.setY(element->y()->currentValue());
- if (!attributes.hasY() && current->hasAttribute(SVGNames::yAttr))
- attributes.setY(current->yCurrentValue());
+ if (!attributes.hasWidth() && element->width()->isSpecified())
+ attributes.setWidth(element->width()->currentValue());
- if (!attributes.hasWidth() && current->hasAttribute(SVGNames::widthAttr))
- attributes.setWidth(current->widthCurrentValue());
+ if (!attributes.hasHeight() && element->height()->isSpecified())
+ attributes.setHeight(element->height()->currentValue());
- if (!attributes.hasHeight() && current->hasAttribute(SVGNames::heightAttr))
- attributes.setHeight(current->heightCurrentValue());
+ if (!attributes.hasViewBox() && element->viewBox()->isSpecified() && element->viewBox()->currentValue()->isValid())
+ attributes.setViewBox(element->viewBox()->currentValue()->value());
- if (!attributes.hasViewBox() && current->hasAttribute(SVGNames::viewBoxAttr) && current->viewBoxCurrentValue().isValid())
- attributes.setViewBox(current->viewBoxCurrentValue());
+ if (!attributes.hasPreserveAspectRatio() && element->preserveAspectRatio()->isSpecified())
+ attributes.setPreserveAspectRatio(element->preserveAspectRatio()->currentValue());
- if (!attributes.hasPreserveAspectRatio() && current->hasAttribute(SVGNames::preserveAspectRatioAttr))
- attributes.setPreserveAspectRatio(current->preserveAspectRatioCurrentValue());
+ if (!attributes.hasPatternUnits() && element->patternUnits()->isSpecified())
+ attributes.setPatternUnits(element->patternUnits()->currentValue()->enumValue());
- if (!attributes.hasPatternUnits() && current->hasAttribute(SVGNames::patternUnitsAttr))
- attributes.setPatternUnits(current->patternUnitsCurrentValue());
+ if (!attributes.hasPatternContentUnits() && element->patternContentUnits()->isSpecified())
+ attributes.setPatternContentUnits(element->patternContentUnits()->currentValue()->enumValue());
- if (!attributes.hasPatternContentUnits() && current->hasAttribute(SVGNames::patternContentUnitsAttr))
- attributes.setPatternContentUnits(current->patternContentUnitsCurrentValue());
+ if (!attributes.hasPatternTransform() && element->patternTransform()->isSpecified()) {
+ AffineTransform transform;
+ element->patternTransform()->currentValue()->concatenate(transform);
+ attributes.setPatternTransform(transform);
+ }
- if (!attributes.hasPatternTransform() && current->hasAttribute(SVGNames::patternTransformAttr)) {
- AffineTransform transform;
- current->patternTransformCurrentValue().concatenate(transform);
- attributes.setPatternTransform(transform);
- }
+ if (!attributes.hasPatternContentElement() && ElementTraversal::firstWithin(*element))
+ attributes.setPatternContentElement(element);
+}
- if (!attributes.hasPatternContentElement() && current->childElementCount())
- attributes.setPatternContentElement(current);
+void SVGPatternElement::collectPatternAttributes(PatternAttributes& attributes) const
+{
+ HashSet<const SVGPatternElement*> processedPatterns;
+ const SVGPatternElement* current = this;
+ while (true) {
+ setPatternAttributes(current, attributes);
processedPatterns.add(current);
// Respect xlink:href, take attributes from referenced element
- Node* refNode = SVGURIReference::targetElementFromIRIString(current->hrefCurrentValue(), document());
- if (refNode && refNode->hasTagName(SVGNames::patternTag)) {
- current = toSVGPatternElement(const_cast<const Node*>(refNode));
+ Node* refNode = SVGURIReference::targetElementFromIRIString(current->hrefString(), treeScope());
+ if (isSVGPatternElement(refNode)) {
+ current = toSVGPatternElement(refNode);
// Cycle detection
- if (processedPatterns.contains(current)) {
- current = 0;
- break;
- }
- } else
- current = 0;
+ if (processedPatterns.contains(current))
+ return;
+ } else {
+ return;
+ }
}
+
+ ASSERT_NOT_REACHED();
}
AffineTransform SVGPatternElement::localCoordinateSpaceTransform(SVGElement::CTMScope) const
{
AffineTransform matrix;
- patternTransformCurrentValue().concatenate(matrix);
+ m_patternTransform->currentValue()->concatenate(matrix);
return matrix;
}
bool SVGPatternElement::selfHasRelativeLengths() const
{
- return xCurrentValue().isRelative()
- || yCurrentValue().isRelative()
- || widthCurrentValue().isRelative()
- || heightCurrentValue().isRelative();
+ return m_x->currentValue()->isRelative()
+ || m_y->currentValue()->isRelative()
+ || m_width->currentValue()->isRelative()
+ || m_height->currentValue()->isRelative();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.h
index 3536b4b89ea..47dee168f84 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.h
@@ -21,15 +21,12 @@
#ifndef SVGPatternElement_h
#define SVGPatternElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGAnimatedRect.h"
#include "core/svg/SVGAnimatedTransformList.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGFitToViewBox.h"
#include "core/svg/SVGTests.h"
#include "core/svg/SVGURIReference.h"
@@ -42,51 +39,48 @@ struct PatternAttributes;
class SVGPatternElement FINAL : public SVGElement,
public SVGURIReference,
public SVGTests,
- public SVGExternalResourcesRequired,
public SVGFitToViewBox {
public:
- static PassRefPtr<SVGPatternElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGPatternElement);
void collectPatternAttributes(PatternAttributes&) const;
- virtual AffineTransform localCoordinateSpaceTransform(SVGElement::CTMScope) const;
+ virtual AffineTransform localCoordinateSpaceTransform(SVGElement::CTMScope) const OVERRIDE;
+
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
+ SVGAnimatedTransformList* patternTransform() { return m_patternTransform.get(); }
+ const SVGAnimatedTransformList* patternTransform() const { return m_patternTransform.get(); }
+ SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* patternUnits() { return m_patternUnits.get(); }
+ SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* patternContentUnits() { return m_patternContentUnits.get(); }
+ const SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* patternUnits() const { return m_patternUnits.get(); }
+ const SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* patternContentUnits() const { return m_patternContentUnits.get(); }
private:
explicit SVGPatternElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool needsPendingResourceHandling() const { return false; }
+ virtual bool isValid() const OVERRIDE { return SVGTests::isValid(); }
+ virtual bool needsPendingResourceHandling() const OVERRIDE { return false; }
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
-
- virtual RenderObject* createRenderer(RenderStyle*);
-
- virtual bool selfHasRelativeLengths() const;
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPatternElement)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_ENUMERATION(PatternUnits, patternUnits, SVGUnitTypes::SVGUnitType)
- DECLARE_ANIMATED_ENUMERATION(PatternContentUnits, patternContentUnits, SVGUnitTypes::SVGUnitType)
- DECLARE_ANIMATED_TRANSFORM_LIST(PatternTransform, patternTransform)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- DECLARE_ANIMATED_RECT(ViewBox, viewBox)
- DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
- END_DECLARE_ANIMATED_PROPERTIES
-
- // SVGTests
- virtual void synchronizeRequiredFeatures() { SVGTests::synchronizeRequiredFeatures(this); }
- virtual void synchronizeRequiredExtensions() { SVGTests::synchronizeRequiredExtensions(this); }
- virtual void synchronizeSystemLanguage() { SVGTests::synchronizeSystemLanguage(this); }
-};
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
+
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
-DEFINE_NODE_TYPE_CASTS(SVGPatternElement, hasTagName(SVGNames::patternTag));
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
+
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
+ RefPtr<SVGAnimatedTransformList> m_patternTransform;
+ RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_patternUnits;
+ RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_patternContentUnits;
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.idl
index 55aa2e9eb1b..04a1e008108 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPatternElement.idl
@@ -23,18 +23,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG11/pservers.html#InterfaceSVGPatternElement
+// http://www.w3.org/TR/SVG2/pservers.html#InterfaceSVGPatternElement
+
interface SVGPatternElement : SVGElement {
- readonly attribute SVGAnimatedEnumeration patternUnits;
- readonly attribute SVGAnimatedEnumeration patternContentUnits;
+ readonly attribute SVGAnimatedEnumeration patternUnits;
+ readonly attribute SVGAnimatedEnumeration patternContentUnits;
readonly attribute SVGAnimatedTransformList patternTransform;
- readonly attribute SVGAnimatedLength x;
- readonly attribute SVGAnimatedLength y;
- readonly attribute SVGAnimatedLength width;
- readonly attribute SVGAnimatedLength height;
+ readonly attribute SVGAnimatedLength x;
+ readonly attribute SVGAnimatedLength y;
+ readonly attribute SVGAnimatedLength width;
+ readonly attribute SVGAnimatedLength height;
};
-SVGPatternElement implements SVGExternalResourcesRequired;
SVGPatternElement implements SVGFitToViewBox;
-SVGPatternElement implements SVGTests;
+SVGPatternElement implements SVGTests; // in SVG 1.1 but not SVG 2
SVGPatternElement implements SVGURIReference;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPoint.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPoint.cpp
new file mode 100644
index 00000000000..283667a1dd7
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPoint.cpp
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGPoint.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
+#include "core/svg/SVGParserUtilities.h"
+#include "platform/transforms/AffineTransform.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+SVGPoint::SVGPoint()
+ : SVGPropertyBase(classType())
+{
+}
+
+SVGPoint::SVGPoint(const FloatPoint& point)
+ : SVGPropertyBase(classType())
+ , m_value(point)
+{
+}
+
+PassRefPtr<SVGPoint> SVGPoint::clone() const
+{
+ return SVGPoint::create(m_value);
+}
+
+PassRefPtr<SVGPropertyBase> SVGPoint::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGPoint> point = SVGPoint::create();
+ point->setValueAsString(value, IGNORE_EXCEPTION);
+ return point.release();
+}
+
+template<typename CharType>
+void SVGPoint::parse(const CharType*& ptr, const CharType* end, ExceptionState& exceptionState)
+{
+ const CharType* start = ptr;
+
+ skipOptionalSVGSpaces(ptr, end);
+
+ float x = 0.0f;
+ float y = 0.0f;
+ bool valid = parseNumber(ptr, end, x) && parseNumber(ptr, end, y, DisallowWhitespace);
+
+ if (!valid) {
+ exceptionState.throwDOMException(SyntaxError, "Problem parsing point \"" + String(start, end - start) + "\"");
+ return;
+ }
+
+ skipOptionalSVGSpaces(ptr, end);
+ if (ptr < end) { // nothing should come after the last, fourth number
+ exceptionState.throwDOMException(SyntaxError, "Problem parsing point \"" + String(start, end - start) + "\"");
+ return;
+ }
+
+ m_value = FloatPoint(x, y);
+}
+
+FloatPoint SVGPoint::matrixTransform(const AffineTransform& transform) const
+{
+ double newX, newY;
+ transform.map(static_cast<double>(x()), static_cast<double>(y()), newX, newY);
+ return FloatPoint::narrowPrecision(newX, newY);
+}
+
+void SVGPoint::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+ if (string.isEmpty()) {
+ m_value = FloatPoint(0.0f, 0.0f);
+ return;
+ }
+
+ if (string.is8Bit()) {
+ const LChar* ptr = string.characters8();
+ const LChar* end = ptr + string.length();
+ parse(ptr, end, exceptionState);
+ return;
+ }
+
+ const UChar* ptr = string.characters16();
+ const UChar* end = ptr + string.length();
+ parse(ptr, end, exceptionState);
+}
+
+String SVGPoint::valueAsString() const
+{
+ StringBuilder builder;
+ builder.append(String::number(x()));
+ builder.append(' ');
+ builder.append(String::number(y()));
+ return builder.toString();
+}
+
+void SVGPoint::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ // SVGPoint is not animated by itself
+ ASSERT_NOT_REACHED();
+}
+
+void SVGPoint::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
+{
+ // SVGPoint is not animated by itself
+ ASSERT_NOT_REACHED();
+}
+
+float SVGPoint::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement)
+{
+ // SVGPoint is not animated by itself
+ ASSERT_NOT_REACHED();
+ return 0.0f;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPoint.h b/chromium/third_party/WebKit/Source/core/svg/SVGPoint.h
index c258a0f3ad8..2c81b0b4468 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPoint.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPoint.h
@@ -1,36 +1,99 @@
/*
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGPoint_h
#define SVGPoint_h
-#include "platform/geometry/FloatRect.h"
+#include "core/svg/properties/SVGProperty.h"
+#include "platform/geometry/FloatPoint.h"
namespace WebCore {
-typedef FloatPoint SVGPoint;
+class AffineTransform;
+class SVGPointTearOff;
+
+class SVGPoint : public SVGPropertyBase {
+public:
+ typedef SVGPointTearOff TearOffType;
+
+ static PassRefPtr<SVGPoint> create()
+ {
+ return adoptRef(new SVGPoint());
+ }
+
+ static PassRefPtr<SVGPoint> create(const FloatPoint& point)
+ {
+ return adoptRef(new SVGPoint(point));
+ }
+
+ PassRefPtr<SVGPoint> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+ const FloatPoint& value() const { return m_value; }
+ void setValue(const FloatPoint& value) { m_value = value; }
+
+ float x() const { return m_value.x(); }
+ float y() const { return m_value.y(); }
+ void setX(float f) { m_value.setX(f); }
+ void setY(float f) { m_value.setY(f); }
+
+ FloatPoint matrixTransform(const AffineTransform&) const;
+
+ bool operator==(const SVGPoint&) const;
+ bool operator!=(const SVGPoint& other) const { return !operator==(other); }
+
+ virtual String valueAsString() const OVERRIDE;
+ void setValueAsString(const String&, ExceptionState&);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedPoint; }
+
+private:
+ SVGPoint();
+ explicit SVGPoint(const FloatPoint&);
+
+ template<typename CharType>
+ void parse(const CharType*& ptr, const CharType* end, ExceptionState&);
+
+ FloatPoint m_value;
+};
+
+inline PassRefPtr<SVGPoint> toSVGPoint(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGPoint::classType());
+ return static_pointer_cast<SVGPoint>(base.release());
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPoint.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPoint.idl
index d8945c9ed72..a1923805029 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPoint.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPoint.idl
@@ -20,10 +20,13 @@
* Boston, MA 02110-1301, USA.
*/
-interface SVGPoint {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
+[
+ ImplementedAs=SVGPointTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGPoint {
+ [RaisesException=Setter] attribute float x;
+ [RaisesException=Setter] attribute float y;
- [MeasureAs=SVGPointMatrixTransform, StrictTypeChecking] SVGPoint matrixTransform(SVGMatrix matrix);
+ [MeasureAs=SVGPointMatrixTransform] SVGPoint matrixTransform(SVGMatrix matrix);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPointList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPointList.cpp
index 3b7d9b91f0e..bb1e74d5dd2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPointList.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPointList.cpp
@@ -21,26 +21,196 @@
#include "config.h"
#include "core/svg/SVGPointList.h"
+#include "core/svg/SVGAnimationElement.h"
+#include "core/svg/SVGParserUtilities.h"
#include "platform/geometry/FloatPoint.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
+inline PassRefPtr<SVGPointList> toSVGPointList(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGPointList::classType());
+ return static_pointer_cast<SVGPointList>(base.release());
+}
+
+SVGPointList::SVGPointList()
+{
+}
+
+SVGPointList::~SVGPointList()
+{
+}
+
+PassRefPtr<SVGPointList> SVGPointList::clone()
+{
+ RefPtr<SVGPointList> svgPointList = SVGPointList::create();
+ svgPointList->deepCopy(this);
+ return svgPointList.release();
+}
+
+PassRefPtr<SVGPropertyBase> SVGPointList::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGPointList> svgPointList = SVGPointList::create();
+ svgPointList->setValueAsString(value, IGNORE_EXCEPTION);
+ return svgPointList.release();
+}
+
String SVGPointList::valueAsString() const
{
StringBuilder builder;
- unsigned size = this->size();
- for (unsigned i = 0; i < size; ++i) {
- if (i > 0)
- builder.append(' '); // FIXME: Shouldn't we use commas to seperate?
+ ConstIterator it = begin();
+ ConstIterator itEnd = end();
+ if (it != itEnd) {
+ builder.append(it->valueAsString());
+ ++it;
- const FloatPoint& point = at(i);
- builder.append(String::number(point.x()) + ' ' + String::number(point.y()));
+ for (; it != itEnd; ++it) {
+ builder.append(' ');
+ builder.append(it->valueAsString());
+ }
}
return builder.toString();
}
+template <typename CharType>
+bool SVGPointList::parse(const CharType*& ptr, const CharType* end)
+{
+ clear();
+
+ skipOptionalSVGSpaces(ptr, end);
+ if (ptr >= end)
+ return true;
+
+ for (;;) {
+ float x = 0.0f;
+ float y = 0.0f;
+ bool valid = parseNumber(ptr, end, x) && parseNumber(ptr, end, y, DisallowWhitespace);
+ if (!valid) {
+ return false;
+ }
+ append(SVGPoint::create(FloatPoint(x, y)));
+
+ skipOptionalSVGSpaces(ptr, end);
+ if (ptr < end && *ptr == ',') {
+ ++ptr;
+ skipOptionalSVGSpaces(ptr, end);
+
+ // ',' requires the list to be continued
+ continue;
+ }
+
+ // check end of list
+ if (ptr >= end)
+ return true;
+ }
+}
+
+void SVGPointList::setValueAsString(const String& value, ExceptionState& exceptionState)
+{
+ if (value.isEmpty()) {
+ clear();
+ return;
+ }
+
+ bool valid = false;
+ if (value.is8Bit()) {
+ const LChar* ptr = value.characters8();
+ const LChar* end = ptr + value.length();
+ valid = parse(ptr, end);
+ } else {
+ const UChar* ptr = value.characters16();
+ const UChar* end = ptr + value.length();
+ valid = parse(ptr, end);
+ }
+
+ if (!valid)
+ exceptionState.throwDOMException(SyntaxError, "Problem parsing points=\""+value+"\"");
+}
+
+void SVGPointList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement* contextElement)
+{
+ RefPtr<SVGPointList> otherList = toSVGPointList(other);
+
+ if (length() != otherList->length())
+ return;
+
+ for (size_t i = 0; i < length(); ++i)
+ at(i)->setValue(at(i)->value() + otherList->at(i)->value());
+}
+
+bool SVGPointList::adjustFromToListValues(PassRefPtr<SVGPointList> passFromList, PassRefPtr<SVGPointList> passToList, float percentage, bool isToAnimation, bool resizeAnimatedListIfNeeded)
+{
+ RefPtr<SVGPointList> fromList = passFromList;
+ RefPtr<SVGPointList> toList = passToList;
+
+ // If no 'to' value is given, nothing to animate.
+ size_t toListSize = toList->length();
+ if (!toListSize)
+ return false;
+
+ // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
+ size_t fromListSize = fromList->length();
+ if (fromListSize != toListSize && fromListSize) {
+ if (percentage < 0.5) {
+ if (!isToAnimation)
+ deepCopy(fromList);
+ } else {
+ deepCopy(toList);
+ }
+
+ return false;
+ }
+
+ ASSERT(!fromListSize || fromListSize == toListSize);
+ if (resizeAnimatedListIfNeeded && length() < toListSize) {
+ size_t paddingCount = toListSize - length();
+ for (size_t i = 0; i < paddingCount; ++i)
+ append(SVGPoint::create());
+ }
+
+ return true;
+}
+
+void SVGPointList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+{
+ RefPtr<SVGPointList> fromList = toSVGPointList(fromValue);
+ RefPtr<SVGPointList> toList = toSVGPointList(toValue);
+ RefPtr<SVGPointList> toAtEndOfDurationList = toSVGPointList(toAtEndOfDurationValue);
+
+ size_t fromPointListSize = fromList->length();
+ size_t toPointListSize = toList->length();
+ size_t toAtEndOfDurationListSize = toAtEndOfDurationList->length();
+
+ if (!adjustFromToListValues(fromList, toList, percentage, animationElement->animationMode() == ToAnimation, true))
+ return;
+
+ for (size_t i = 0; i < toPointListSize; ++i) {
+ float animatedX = at(i)->x();
+ float animatedY = at(i)->y();
+
+ FloatPoint effectiveFrom;
+ if (fromPointListSize)
+ effectiveFrom = fromList->at(i)->value();
+ FloatPoint effectiveTo = toList->at(i)->value();
+ FloatPoint effectiveToAtEnd;
+ if (i < toAtEndOfDurationListSize)
+ effectiveToAtEnd = toAtEndOfDurationList->at(i)->value();
+
+ animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom.x(), effectiveTo.x(), effectiveToAtEnd.x(), animatedX);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, effectiveFrom.y(), effectiveTo.y(), effectiveToAtEnd.y(), animatedY);
+ at(i)->setValue(FloatPoint(animatedX, animatedY));
+ }
+}
+
+float SVGPointList::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*)
+{
+ // FIXME: Distance calculation is not possible for SVGPointList right now. We need the distance for every single value.
+ return -1;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPointList.h b/chromium/third_party/WebKit/Source/core/svg/SVGPointList.h
index a745b10ce07..0aea4c043d9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPointList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPointList.h
@@ -1,45 +1,78 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGPointList_h
#define SVGPointList_h
+#include "bindings/v8/ScriptWrappable.h"
#include "core/svg/SVGPoint.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/Vector.h"
+#include "core/svg/properties/SVGListPropertyHelper.h"
namespace WebCore {
-class SVGPointList : public Vector<SVGPoint> {
+class SVGPointListTearOff;
+
+class SVGPointList FINAL : public SVGListPropertyHelper<SVGPointList, SVGPoint> {
public:
- SVGPointList() { }
+ typedef SVGPointListTearOff TearOffType;
- String valueAsString() const;
-};
+ static PassRefPtr<SVGPointList> create()
+ {
+ return adoptRef(new SVGPointList());
+ }
+
+ virtual ~SVGPointList();
+
+ PassRefPtr<SVGPointList> clone();
+
+ void setValueAsString(const String&, ExceptionState&);
+
+ // SVGPropertyBase:
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+ virtual String valueAsString() const OVERRIDE;
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedPoints; }
+
+private:
+ SVGPointList();
+
+ bool adjustFromToListValues(PassRefPtr<SVGPointList> fromList, PassRefPtr<SVGPointList> toList, float percentage, bool isToAnimation, bool resizeAnimatedListIfNeeded);
-template<>
-struct SVGPropertyTraits<SVGPointList> {
- static SVGPointList initialValue() { return SVGPointList(); }
- typedef SVGPoint ListItemType;
+ template <typename CharType>
+ bool parse(const CharType*& ptr, const CharType* end);
};
} // namespace WebCore
-#endif
+#endif // SVGPointList_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPointList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPointList.idl
index f65d302aa09..444570b1f4e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPointList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPointList.idl
@@ -23,15 +23,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPointList {
- readonly attribute unsigned long numberOfItems;
+[
+ ImplementedAs=SVGPointListTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGPointList {
+ readonly attribute unsigned long length;
+ [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
[RaisesException] void clear();
- [StrictTypeChecking, RaisesException] SVGPoint initialize(SVGPoint item);
- [StrictTypeChecking, RaisesException] SVGPoint getItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGPoint insertItemBefore(SVGPoint item, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGPoint replaceItem(SVGPoint item, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGPoint removeItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGPoint appendItem(SVGPoint item);
+ [RaisesException] SVGPoint initialize(SVGPoint item);
+ [RaisesException] getter SVGPoint getItem(unsigned long index);
+ [RaisesException] setter SVGPoint (unsigned long index, SVGPoint value);
+ [RaisesException] SVGPoint insertItemBefore(SVGPoint item, unsigned long index);
+ [RaisesException] SVGPoint replaceItem(SVGPoint item, unsigned long index);
+ [RaisesException] SVGPoint removeItem(unsigned long index);
+ [RaisesException] SVGPoint appendItem(SVGPoint item);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPointListTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGPointListTearOff.h
new file mode 100644
index 00000000000..21f614a022e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPointListTearOff.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGPointListTearOff_h
+#define SVGPointListTearOff_h
+
+#include "core/svg/SVGPointList.h"
+#include "core/svg/properties/SVGListPropertyTearOffHelper.h"
+
+namespace WebCore {
+
+class SVGPointListTearOff FINAL :
+ public SVGListPropertyTearOffHelper<SVGPointListTearOff, SVGPointList>,
+ public ScriptWrappable {
+public:
+ static PassRefPtr<SVGPointListTearOff> create(PassRefPtr<SVGPointList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGPointListTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+private:
+ SVGPointListTearOff(PassRefPtr<SVGPointList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ : SVGListPropertyTearOffHelper<SVGPointListTearOff, SVGPointList>(target, contextElement, propertyIsAnimVal, attributeName)
+ {
+ ScriptWrappable::init(this);
+ }
+};
+
+} // namespace WebCore
+
+#endif // SVGPointListTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPointTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPointTearOff.cpp
new file mode 100644
index 00000000000..799cc894c70
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPointTearOff.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGPointTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGMatrixTearOff.h"
+
+namespace WebCore {
+
+SVGPointTearOff::SVGPointTearOff(PassRefPtr<SVGPoint> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ : SVGPropertyTearOff<SVGPoint>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+void SVGPointTearOff::setX(float f, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setX(f);
+ commitChange();
+}
+
+void SVGPointTearOff::setY(float f, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setY(f);
+ commitChange();
+}
+
+PassRefPtr<SVGPointTearOff> SVGPointTearOff::matrixTransform(PassRefPtr<SVGMatrixTearOff> matrix)
+{
+ FloatPoint point = target()->matrixTransform(matrix->value());
+ return SVGPointTearOff::create(SVGPoint::create(point), 0, PropertyIsNotAnimVal);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPointTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGPointTearOff.h
new file mode 100644
index 00000000000..f4f44348cdd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPointTearOff.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGPointTearOff_h
+#define SVGPointTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGPoint.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGMatrixTearOff;
+
+class SVGPointTearOff : public SVGPropertyTearOff<SVGPoint>, public ScriptWrappable {
+public:
+ static PassRefPtr<SVGPointTearOff> create(PassRefPtr<SVGPoint> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGPointTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ void setX(float, ExceptionState&);
+ void setY(float, ExceptionState&);
+ float x() { return target()->x(); }
+ float y() { return target()->y(); }
+
+ PassRefPtr<SVGPointTearOff> matrixTransform(PassRefPtr<SVGMatrixTearOff>);
+
+protected:
+ SVGPointTearOff(PassRefPtr<SVGPoint>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName = QualifiedName::null());
+};
+
+} // namespace WebCore
+
+#endif // SVGPointTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.cpp
index 8f984b9be0f..a5b34ccf283 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.cpp
@@ -25,57 +25,21 @@
#include "core/dom/Document.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/svg/SVGAnimatedPointList.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGParserUtilities.h"
namespace WebCore {
-// Define custom animated property 'points'.
-const SVGPropertyInfo* SVGPolyElement::pointsPropertyInfo()
-{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedPoints,
- PropertyIsReadWrite,
- SVGNames::pointsAttr,
- SVGNames::pointsAttr.localName(),
- &SVGPolyElement::synchronizePoints,
- &SVGPolyElement::lookupOrCreatePointsWrapper);
- }
- return s_propertyInfo;
-}
-
-SVGPointList& SVGPolyElement::pointsCurrentValue()
-{
- SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<SVGPolyElement, SVGAnimatedPointList>(this, pointsPropertyInfo());
- if (wrapper && wrapper->isAnimating()) {
- if (SVGListPropertyTearOff<SVGPointList>* ap = animatedPoints())
- return ap->values();
- }
-
- return m_points.value;
-}
-
-// Animated property definitions
-DEFINE_ANIMATED_BOOLEAN(SVGPolyElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGPolyElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(points)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
SVGPolyElement::SVGPolyElement(const QualifiedName& tagName, Document& document)
: SVGGeometryElement(tagName, document)
+ , m_points(SVGAnimatedPointList::create(this, SVGNames::pointsAttr, SVGPointList::create()))
{
- registerAnimatedPropertiesForSVGPolyElement();
+ addToPropertyMap(m_points);
}
bool SVGPolyElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::pointsAttr);
}
return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
@@ -89,20 +53,12 @@ void SVGPolyElement::parseAttribute(const QualifiedName& name, const AtomicStrin
}
if (name == SVGNames::pointsAttr) {
- SVGPointList newList;
- if (!pointsListFromSVGData(newList, value))
- document().accessSVGExtensions()->reportError("Problem parsing points=\"" + value + "\"");
-
- if (SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<SVGPolyElement, SVGAnimatedPointList>(this, pointsPropertyInfo()))
- static_cast<SVGAnimatedPointList*>(wrapper)->detachListWrappers(newList.size());
-
- m_points.value = newList;
+ SVGParsingError parseError = NoError;
+ m_points->setBaseValueAsString(value, parseError);
+ reportAttributeParsingError(parseError, name, value);
return;
}
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
-
ASSERT_NOT_REACHED();
}
@@ -113,7 +69,7 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
RenderSVGShape* renderer = toRenderSVGShape(this->renderer());
if (!renderer)
@@ -125,41 +81,7 @@ void SVGPolyElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
ASSERT_NOT_REACHED();
}
-void SVGPolyElement::synchronizePoints(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- SVGPolyElement* ownerType = toSVGPolyElement(contextElement);
- if (!ownerType->m_points.shouldSynchronize)
- return;
- ownerType->m_points.synchronize(ownerType, pointsPropertyInfo()->attributeName, ownerType->m_points.value.valueAsString());
-}
-
-PassRefPtr<SVGAnimatedProperty> SVGPolyElement::lookupOrCreatePointsWrapper(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- SVGPolyElement* ownerType = toSVGPolyElement(contextElement);
- return SVGAnimatedProperty::lookupOrCreateWrapper<SVGPolyElement, SVGAnimatedPointList, SVGPointList>
- (ownerType, pointsPropertyInfo(), ownerType->m_points.value);
-}
-
-SVGListPropertyTearOff<SVGPointList>* SVGPolyElement::points()
-{
- m_points.shouldSynchronize = true;
- return static_cast<SVGListPropertyTearOff<SVGPointList>*>(static_pointer_cast<SVGAnimatedPointList>(lookupOrCreatePointsWrapper(this))->baseVal());
-}
-
-SVGListPropertyTearOff<SVGPointList>* SVGPolyElement::animatedPoints()
-{
- m_points.shouldSynchronize = true;
- return static_cast<SVGListPropertyTearOff<SVGPointList>*>(static_pointer_cast<SVGAnimatedPointList>(lookupOrCreatePointsWrapper(this))->animVal());
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.h
index 4cc460158df..b8abfd113a3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPolyElement.h
@@ -21,47 +21,31 @@
#ifndef SVGPolyElement_h
#define SVGPolyElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
+#include "core/svg/SVGAnimatedPointList.h"
#include "core/svg/SVGGeometryElement.h"
-#include "core/svg/SVGPointList.h"
namespace WebCore {
-class SVGPolyElement : public SVGGeometryElement
- , public SVGExternalResourcesRequired {
+class SVGPolyElement : public SVGGeometryElement {
public:
- SVGListPropertyTearOff<SVGPointList>* points();
- SVGListPropertyTearOff<SVGPointList>* animatedPoints();
+ SVGAnimatedPointList* points() { return m_points.get(); }
- SVGPointList& pointsCurrentValue();
-
- static const SVGPropertyInfo* pointsPropertyInfo();
+ PassRefPtr<SVGPointListTearOff> pointsFromJavascript() { return m_points->baseVal(); }
+ PassRefPtr<SVGPointListTearOff> animatedPoints() { return m_points->animVal(); }
protected:
SVGPolyElement(const QualifiedName&, Document&);
private:
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
bool isSupportedAttribute(const QualifiedName&);
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
-
- virtual bool supportsMarkers() const { return true; }
-
- // Custom 'points' property
- static void synchronizePoints(SVGElement* contextElement);
- static PassRefPtr<SVGAnimatedProperty> lookupOrCreatePointsWrapper(SVGElement* contextElement);
-
- mutable SVGSynchronizableAnimatedProperty<SVGPointList> m_points;
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE FINAL;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE FINAL;
private:
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPolyElement)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedPointList> m_points;
+
};
inline bool isSVGPolyElement(const Node& node)
@@ -69,7 +53,7 @@ inline bool isSVGPolyElement(const Node& node)
return node.hasTagName(SVGNames::polygonTag) || node.hasTagName(SVGNames::polylineTag);
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGPolyElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGPolyElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.cpp
index 14d7a94ebc7..47dabcd3ec8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.cpp
@@ -30,9 +30,6 @@ inline SVGPolygonElement::SVGPolygonElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGPolygonElement> SVGPolygonElement::create(Document& document)
-{
- return adoptRef(new SVGPolygonElement(document));
-}
+DEFINE_NODE_FACTORY(SVGPolygonElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.h
index 89571f75749..1b785f5c990 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.h
@@ -21,21 +21,19 @@
#ifndef SVGPolygonElement_h
#define SVGPolygonElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGPolyElement.h"
namespace WebCore {
class SVGPolygonElement FINAL : public SVGPolyElement {
public:
- static PassRefPtr<SVGPolygonElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGPolygonElement);
private:
explicit SVGPolygonElement(Document&);
};
-DEFINE_NODE_TYPE_CASTS(SVGPolygonElement, hasTagName(SVGNames::polygonTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.idl
index be639f1d8c7..defe168ccdd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPolygonElement.idl
@@ -24,8 +24,6 @@
*/
interface SVGPolygonElement : SVGGeometryElement {
- readonly attribute SVGPointList points;
+ [ImplementedAs=pointsFromJavascript] readonly attribute SVGPointList points;
readonly attribute SVGPointList animatedPoints;
};
-
-SVGPolygonElement implements SVGExternalResourcesRequired;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.cpp
index d3c3323f655..5c4397f468e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.cpp
@@ -24,15 +24,12 @@
namespace WebCore {
-inline SVGPolylineElement::SVGPolylineElement(Document& document)
+SVGPolylineElement::SVGPolylineElement(Document& document)
: SVGPolyElement(SVGNames::polylineTag, document)
{
ScriptWrappable::init(this);
}
-PassRefPtr<SVGPolylineElement> SVGPolylineElement::create(Document& document)
-{
- return adoptRef(new SVGPolylineElement(document));
-}
+DEFINE_NODE_FACTORY(SVGPolylineElement)
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.h
index 428314366de..bad153c723f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.h
@@ -21,21 +21,19 @@
#ifndef SVGPolylineElement_h
#define SVGPolylineElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGPolyElement.h"
namespace WebCore {
class SVGPolylineElement FINAL : public SVGPolyElement {
public:
- static PassRefPtr<SVGPolylineElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGPolylineElement);
private:
explicit SVGPolylineElement(Document&);
};
-DEFINE_NODE_TYPE_CASTS(SVGPolylineElement, hasTagName(SVGNames::polylineTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.idl
index 1fd499b8d96..4d148d1d48d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPolylineElement.idl
@@ -24,9 +24,7 @@
*/
interface SVGPolylineElement : SVGGeometryElement {
- readonly attribute SVGPointList points;
+ [ImplementedAs=pointsFromJavascript] readonly attribute SVGPointList points;
readonly attribute SVGPointList animatedPoints;
};
-SVGPolylineElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.cpp
index 5e9de721a00..1c63e3f3f03 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.cpp
@@ -23,7 +23,9 @@
#include "core/svg/SVGPreserveAspectRatio.h"
#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
#include "core/svg/SVGParserUtilities.h"
#include "platform/geometry/FloatRect.h"
#include "platform/transforms/AffineTransform.h"
@@ -32,142 +34,165 @@
namespace WebCore {
SVGPreserveAspectRatio::SVGPreserveAspectRatio()
- : m_align(SVG_PRESERVEASPECTRATIO_XMIDYMID)
- , m_meetOrSlice(SVG_MEETORSLICE_MEET)
+ : SVGPropertyBase(classType())
{
+ setDefault();
}
-void SVGPreserveAspectRatio::setAlign(unsigned short align, ExceptionState& exceptionState)
+void SVGPreserveAspectRatio::setDefault()
{
- if (align == SVG_PRESERVEASPECTRATIO_UNKNOWN || align > SVG_PRESERVEASPECTRATIO_XMAXYMAX) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
+ m_align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
+ m_meetOrSlice = SVG_MEETORSLICE_MEET;
+}
+
+PassRefPtr<SVGPreserveAspectRatio> SVGPreserveAspectRatio::clone() const
+{
+ RefPtr<SVGPreserveAspectRatio> preserveAspectRatio = create();
- m_align = static_cast<SVGPreserveAspectRatioType>(align);
+ preserveAspectRatio->m_align = m_align;
+ preserveAspectRatio->m_meetOrSlice = m_meetOrSlice;
+
+ return preserveAspectRatio.release();
}
-void SVGPreserveAspectRatio::setMeetOrSlice(unsigned short meetOrSlice, ExceptionState& exceptionState)
+PassRefPtr<SVGPropertyBase> SVGPreserveAspectRatio::cloneForAnimation(const String& value) const
{
- if (meetOrSlice == SVG_MEETORSLICE_UNKNOWN || meetOrSlice > SVG_MEETORSLICE_SLICE) {
- exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
- return;
- }
+ RefPtr<SVGPreserveAspectRatio> preserveAspectRatio = create();
- m_meetOrSlice = static_cast<SVGMeetOrSliceType>(meetOrSlice);
+ preserveAspectRatio->setValueAsString(value, IGNORE_EXCEPTION);
+
+ return preserveAspectRatio.release();
}
template<typename CharType>
bool SVGPreserveAspectRatio::parseInternal(const CharType*& ptr, const CharType* end, bool validate)
{
- // FIXME: Rewrite this parser, without gotos!
+ SVGPreserveAspectRatioType align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
+ SVGMeetOrSliceType meetOrSlice = SVG_MEETORSLICE_MEET;
+
+ setAlign(align);
+ setMeetOrSlice(meetOrSlice);
+
if (!skipOptionalSVGSpaces(ptr, end))
- goto bailOut;
+ return false;
if (*ptr == 'd') {
if (!skipString(ptr, end, "defer"))
- goto bailOut;
+ return false;
// FIXME: We just ignore the "defer" here.
if (ptr == end)
return true;
if (!skipOptionalSVGSpaces(ptr, end))
- goto bailOut;
+ return false;
}
if (*ptr == 'n') {
if (!skipString(ptr, end, "none"))
- goto bailOut;
- m_align = SVG_PRESERVEASPECTRATIO_NONE;
+ return false;
+ align = SVG_PRESERVEASPECTRATIO_NONE;
skipOptionalSVGSpaces(ptr, end);
} else if (*ptr == 'x') {
if ((end - ptr) < 8)
- goto bailOut;
+ return false;
if (ptr[1] != 'M' || ptr[4] != 'Y' || ptr[5] != 'M')
- goto bailOut;
+ return false;
if (ptr[2] == 'i') {
if (ptr[3] == 'n') {
if (ptr[6] == 'i') {
if (ptr[7] == 'n')
- m_align = SVG_PRESERVEASPECTRATIO_XMINYMIN;
+ align = SVG_PRESERVEASPECTRATIO_XMINYMIN;
else if (ptr[7] == 'd')
- m_align = SVG_PRESERVEASPECTRATIO_XMINYMID;
+ align = SVG_PRESERVEASPECTRATIO_XMINYMID;
else
- goto bailOut;
- } else if (ptr[6] == 'a' && ptr[7] == 'x')
- m_align = SVG_PRESERVEASPECTRATIO_XMINYMAX;
- else
- goto bailOut;
+ return false;
+ } else if (ptr[6] == 'a' && ptr[7] == 'x') {
+ align = SVG_PRESERVEASPECTRATIO_XMINYMAX;
+ } else {
+ return false;
+ }
} else if (ptr[3] == 'd') {
if (ptr[6] == 'i') {
if (ptr[7] == 'n')
- m_align = SVG_PRESERVEASPECTRATIO_XMIDYMIN;
+ align = SVG_PRESERVEASPECTRATIO_XMIDYMIN;
else if (ptr[7] == 'd')
- m_align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
+ align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
else
- goto bailOut;
- } else if (ptr[6] == 'a' && ptr[7] == 'x')
- m_align = SVG_PRESERVEASPECTRATIO_XMIDYMAX;
- else
- goto bailOut;
- } else
- goto bailOut;
+ return false;
+ } else if (ptr[6] == 'a' && ptr[7] == 'x') {
+ align = SVG_PRESERVEASPECTRATIO_XMIDYMAX;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
} else if (ptr[2] == 'a' && ptr[3] == 'x') {
if (ptr[6] == 'i') {
if (ptr[7] == 'n')
- m_align = SVG_PRESERVEASPECTRATIO_XMAXYMIN;
+ align = SVG_PRESERVEASPECTRATIO_XMAXYMIN;
else if (ptr[7] == 'd')
- m_align = SVG_PRESERVEASPECTRATIO_XMAXYMID;
+ align = SVG_PRESERVEASPECTRATIO_XMAXYMID;
else
- goto bailOut;
- } else if (ptr[6] == 'a' && ptr[7] == 'x')
- m_align = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
- else
- goto bailOut;
- } else
- goto bailOut;
+ return false;
+ } else if (ptr[6] == 'a' && ptr[7] == 'x') {
+ align = SVG_PRESERVEASPECTRATIO_XMAXYMAX;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
ptr += 8;
skipOptionalSVGSpaces(ptr, end);
- } else
- goto bailOut;
+ } else {
+ return false;
+ }
if (ptr < end) {
if (*ptr == 'm') {
if (!skipString(ptr, end, "meet"))
- goto bailOut;
+ return false;
skipOptionalSVGSpaces(ptr, end);
} else if (*ptr == 's') {
if (!skipString(ptr, end, "slice"))
- goto bailOut;
+ return false;
skipOptionalSVGSpaces(ptr, end);
- if (m_align != SVG_PRESERVEASPECTRATIO_NONE)
- m_meetOrSlice = SVG_MEETORSLICE_SLICE;
+ if (align != SVG_PRESERVEASPECTRATIO_NONE)
+ meetOrSlice = SVG_MEETORSLICE_SLICE;
}
}
- if (end != ptr && validate) {
-bailOut:
- m_align = SVG_PRESERVEASPECTRATIO_XMIDYMID;
- m_meetOrSlice = SVG_MEETORSLICE_MEET;
+ if (end != ptr && validate)
return false;
- }
+
+ setAlign(align);
+ setMeetOrSlice(meetOrSlice);
+
return true;
}
-void SVGPreserveAspectRatio::parse(const String& string)
+void SVGPreserveAspectRatio::setValueAsString(const String& string, ExceptionState& exceptionState)
{
- if (string.isEmpty()) {
- const LChar* ptr = 0;
- parseInternal(ptr, ptr, true);
- } else if (string.is8Bit()) {
+ setDefault();
+
+ if (string.isEmpty())
+ return;
+
+ bool valid = false;
+ if (string.is8Bit()) {
const LChar* ptr = string.characters8();
const LChar* end = ptr + string.length();
- parseInternal(ptr, end, true);
+ valid = parseInternal(ptr, end, true);
} else {
const UChar* ptr = string.characters16();
const UChar* end = ptr + string.length();
- parseInternal(ptr, end, true);
+ valid = parseInternal(ptr, end, true);
+ }
+
+ if (!valid) {
+ exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
}
}
@@ -372,4 +397,28 @@ String SVGPreserveAspectRatio::valueAsString() const
}
}
+void SVGPreserveAspectRatio::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void SVGPreserveAspectRatio::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ ASSERT(animationElement);
+
+ bool useToValue;
+ animationElement->animateDiscreteType(percentage, false, true, useToValue);
+
+ RefPtr<SVGPreserveAspectRatio> preserveAspectRatioToUse = useToValue ? toSVGPreserveAspectRatio(toValue) : toSVGPreserveAspectRatio(fromValue);
+
+ m_align = preserveAspectRatioToUse->m_align;
+ m_meetOrSlice = preserveAspectRatioToUse->m_meetOrSlice;
+}
+
+float SVGPreserveAspectRatio::calculateDistance(PassRefPtr<SVGPropertyBase> toValue, SVGElement* contextElement)
+{
+ // No paced animations for SVGPreserveAspectRatio.
+ return -1;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.h b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.h
index aae01cd5fb1..c2d7bea5c9c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.h
@@ -21,16 +21,15 @@
#ifndef SVGPreserveAspectRatio_h
#define SVGPreserveAspectRatio_h
-#include "core/svg/properties/SVGPropertyTraits.h"
+#include "core/svg/properties/SVGProperty.h"
namespace WebCore {
class AffineTransform;
-class ExceptionState;
class FloatRect;
+class SVGPreserveAspectRatioTearOff;
-class SVGPreserveAspectRatio {
- WTF_MAKE_FAST_ALLOCATED;
+class SVGPreserveAspectRatio : public SVGPropertyBase {
public:
enum SVGPreserveAspectRatioType {
SVG_PRESERVEASPECTRATIO_UNKNOWN = 0,
@@ -52,13 +51,24 @@ public:
SVG_MEETORSLICE_SLICE = 2
};
- SVGPreserveAspectRatio();
+ typedef SVGPreserveAspectRatioTearOff TearOffType;
+
+ static PassRefPtr<SVGPreserveAspectRatio> create()
+ {
+ return adoptRef(new SVGPreserveAspectRatio());
+ }
+
+ virtual PassRefPtr<SVGPreserveAspectRatio> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
- void setAlign(unsigned short align, ExceptionState&);
- unsigned short align() const { return m_align; }
+ bool operator==(const SVGPreserveAspectRatio&) const;
+ bool operator!=(const SVGPreserveAspectRatio& other) const { return !operator==(other); }
- void setMeetOrSlice(unsigned short, ExceptionState&);
- unsigned short meetOrSlice() const { return m_meetOrSlice; }
+ void setAlign(SVGPreserveAspectRatioType align) { m_align = align; }
+ SVGPreserveAspectRatioType align() const { return m_align; }
+
+ void setMeetOrSlice(SVGMeetOrSliceType meetOrSlice) { m_meetOrSlice = meetOrSlice; }
+ SVGMeetOrSliceType meetOrSlice() const { return m_meetOrSlice; }
void transformRect(FloatRect& destRect, FloatRect& srcRect);
@@ -66,13 +76,21 @@ public:
float logicWidth, float logicHeight,
float physWidth, float physHeight) const;
- void parse(const String&);
- bool parse(const LChar*& ptr, const LChar* end, bool validate);
+ virtual String valueAsString() const OVERRIDE;
+ virtual void setValueAsString(const String&, ExceptionState&);
bool parse(const UChar*& ptr, const UChar* end, bool validate);
+ bool parse(const LChar*& ptr, const LChar* end, bool validate);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
- String valueAsString() const;
+ static AnimatedPropertyType classType() { return AnimatedPreserveAspectRatio; }
private:
+ SVGPreserveAspectRatio();
+
+ void setDefault();
template<typename CharType>
bool parseInternal(const CharType*& ptr, const CharType* end, bool validate);
@@ -80,11 +98,12 @@ private:
SVGMeetOrSliceType m_meetOrSlice;
};
-template<>
-struct SVGPropertyTraits<SVGPreserveAspectRatio> {
- static SVGPreserveAspectRatio initialValue() { return SVGPreserveAspectRatio(); }
- static String toString(const SVGPreserveAspectRatio& type) { return type.valueAsString(); }
-};
+inline PassRefPtr<SVGPreserveAspectRatio> toSVGPreserveAspectRatio(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGPreserveAspectRatio::classType());
+ return static_pointer_cast<SVGPreserveAspectRatio>(base.release());
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.idl b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.idl
index 477369ee6d9..67b71245c7a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatio.idl
@@ -23,8 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGPreserveAspectRatio {
- // Alignment Types
+[
+ TypeChecking=Interface|Nullable,
+ ImplementedAs=SVGPreserveAspectRatioTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement)
+] interface SVGPreserveAspectRatio {
+ // Alignment types
const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0;
const unsigned short SVG_PRESERVEASPECTRATIO_NONE = 1;
const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMIN = 2;
@@ -37,13 +41,12 @@ interface SVGPreserveAspectRatio {
const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9;
const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10;
- // Meet-or-slice Types
+ // Meet-or-slice types
const unsigned short SVG_MEETORSLICE_UNKNOWN = 0;
const unsigned short SVG_MEETORSLICE_MEET = 1;
const unsigned short SVG_MEETORSLICE_SLICE = 2;
- [StrictTypeChecking, RaisesException=Setter] attribute unsigned short align;
+ [RaisesException=Setter] attribute unsigned short align;
- [StrictTypeChecking, RaisesException=Setter] attribute unsigned short meetOrSlice;
+ [RaisesException=Setter] attribute unsigned short meetOrSlice;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatioTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatioTearOff.cpp
new file mode 100644
index 00000000000..01e8f871c56
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatioTearOff.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGPreserveAspectRatioTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+void SVGPreserveAspectRatioTearOff::setAlign(unsigned short align, ExceptionState& exceptionState)
+{
+ if (align == SVG_PRESERVEASPECTRATIO_UNKNOWN || align > SVG_PRESERVEASPECTRATIO_XMAXYMAX) {
+ exceptionState.throwDOMException(NotSupportedError, "The alignment provided is invalid.");
+ return;
+ }
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setAlign(static_cast<SVGPreserveAspectRatio::SVGPreserveAspectRatioType>(align));
+}
+
+void SVGPreserveAspectRatioTearOff::setMeetOrSlice(unsigned short meetOrSlice, ExceptionState& exceptionState)
+{
+ if (meetOrSlice == SVG_MEETORSLICE_UNKNOWN || meetOrSlice > SVG_MEETORSLICE_SLICE) {
+ exceptionState.throwDOMException(NotSupportedError, "The meetOrSlice provided is invalid.");
+ return;
+ }
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setMeetOrSlice(static_cast<SVGPreserveAspectRatio::SVGMeetOrSliceType>(meetOrSlice));
+}
+
+SVGPreserveAspectRatioTearOff::SVGPreserveAspectRatioTearOff(PassRefPtr<SVGPreserveAspectRatio> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ : SVGPropertyTearOff<SVGPreserveAspectRatio>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatioTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatioTearOff.h
new file mode 100644
index 00000000000..fd29b1d6e27
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGPreserveAspectRatioTearOff.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGPreserveAspectRatioTearOff_h
+#define SVGPreserveAspectRatioTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGPreserveAspectRatio.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGPreserveAspectRatioTearOff FINAL : public SVGPropertyTearOff<SVGPreserveAspectRatio>, public ScriptWrappable {
+public:
+ enum {
+ SVG_PRESERVEASPECTRATIO_UNKNOWN = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_UNKNOWN,
+ SVG_PRESERVEASPECTRATIO_NONE = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE,
+ SVG_PRESERVEASPECTRATIO_XMINYMIN = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMIN,
+ SVG_PRESERVEASPECTRATIO_XMIDYMIN = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN,
+ SVG_PRESERVEASPECTRATIO_XMAXYMIN = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN,
+ SVG_PRESERVEASPECTRATIO_XMINYMID = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID,
+ SVG_PRESERVEASPECTRATIO_XMIDYMID = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID,
+ SVG_PRESERVEASPECTRATIO_XMAXYMID = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID,
+ SVG_PRESERVEASPECTRATIO_XMINYMAX = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX,
+ SVG_PRESERVEASPECTRATIO_XMIDYMAX = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX,
+ SVG_PRESERVEASPECTRATIO_XMAXYMAX = SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX
+ };
+
+ enum {
+ SVG_MEETORSLICE_UNKNOWN = SVGPreserveAspectRatio::SVG_MEETORSLICE_UNKNOWN,
+ SVG_MEETORSLICE_MEET = SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET,
+ SVG_MEETORSLICE_SLICE = SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE
+ };
+
+ static PassRefPtr<SVGPreserveAspectRatioTearOff> create(PassRefPtr<SVGPreserveAspectRatio> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGPreserveAspectRatioTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ void setAlign(unsigned short, ExceptionState&);
+ unsigned short align() { return target()->align(); }
+ void setMeetOrSlice(unsigned short, ExceptionState&);
+ unsigned short meetOrSlice() { return target()->meetOrSlice(); }
+
+private:
+ SVGPreserveAspectRatioTearOff(PassRefPtr<SVGPreserveAspectRatio>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName = QualifiedName::null());
+};
+
+} // namespace WebCore
+
+#endif // SVGPreserveAspectRatioTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.cpp
index af45582ec58..85d29c58710 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.cpp
@@ -27,48 +27,39 @@
#include "core/rendering/svg/RenderSVGResourceRadialGradient.h"
#include "core/svg/RadialGradientAttributes.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGTransformList.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGRadialGradientElement, SVGNames::cxAttr, Cx, cx)
-DEFINE_ANIMATED_LENGTH(SVGRadialGradientElement, SVGNames::cyAttr, Cy, cy)
-DEFINE_ANIMATED_LENGTH(SVGRadialGradientElement, SVGNames::rAttr, R, r)
-DEFINE_ANIMATED_LENGTH(SVGRadialGradientElement, SVGNames::fxAttr, Fx, fx)
-DEFINE_ANIMATED_LENGTH(SVGRadialGradientElement, SVGNames::fyAttr, Fy, fy)
-DEFINE_ANIMATED_LENGTH(SVGRadialGradientElement, SVGNames::frAttr, Fr, fr)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGRadialGradientElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(cx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(cy)
- REGISTER_LOCAL_ANIMATED_PROPERTY(r)
- REGISTER_LOCAL_ANIMATED_PROPERTY(fx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(fy)
- REGISTER_LOCAL_ANIMATED_PROPERTY(fr)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGradientElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGRadialGradientElement::SVGRadialGradientElement(Document& document)
: SVGGradientElement(SVGNames::radialGradientTag, document)
- , m_cx(LengthModeWidth, "50%")
- , m_cy(LengthModeHeight, "50%")
- , m_r(LengthModeOther, "50%")
- , m_fx(LengthModeWidth)
- , m_fy(LengthModeHeight)
- , m_fr(LengthModeOther, "0%")
+ , m_cx(SVGAnimatedLength::create(this, SVGNames::cxAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_cy(SVGAnimatedLength::create(this, SVGNames::cyAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_r(SVGAnimatedLength::create(this, SVGNames::rAttr, SVGLength::create(LengthModeOther), ForbidNegativeLengths))
+ , m_fx(SVGAnimatedLength::create(this, SVGNames::fxAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_fy(SVGAnimatedLength::create(this, SVGNames::fyAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_fr(SVGAnimatedLength::create(this, SVGNames::frAttr, SVGLength::create(LengthModeOther), ForbidNegativeLengths))
{
- // Spec: If the cx/cy/r/fr attribute is not specified, the effect is as if a value of "50%" were specified.
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGRadialGradientElement();
-}
-PassRefPtr<SVGRadialGradientElement> SVGRadialGradientElement::create(Document& document)
-{
- return adoptRef(new SVGRadialGradientElement(document));
+ // Spec: If the cx/cy/r attribute is not specified, the effect is as if a value of "50%" were specified.
+ m_cx->setDefaultValueAsString("50%");
+ m_cy->setDefaultValueAsString("50%");
+ m_r->setDefaultValueAsString("50%");
+
+ // SVG2-Draft Spec: If the fr attributed is not specified, the effect is as if a value of "0%" were specified.
+ m_fr->setDefaultValueAsString("0%");
+
+ addToPropertyMap(m_cx);
+ addToPropertyMap(m_cy);
+ addToPropertyMap(m_r);
+ addToPropertyMap(m_fx);
+ addToPropertyMap(m_fy);
+ addToPropertyMap(m_fr);
}
+DEFINE_NODE_FACTORY(SVGRadialGradientElement)
+
bool SVGRadialGradientElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
@@ -90,17 +81,17 @@ void SVGRadialGradientElement::parseAttribute(const QualifiedName& name, const A
if (!isSupportedAttribute(name))
SVGGradientElement::parseAttribute(name, value);
else if (name == SVGNames::cxAttr)
- setCxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_cx->setBaseValueAsString(value, parseError);
else if (name == SVGNames::cyAttr)
- setCyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_cy->setBaseValueAsString(value, parseError);
else if (name == SVGNames::rAttr)
- setRBaseValue(SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
+ m_r->setBaseValueAsString(value, parseError);
else if (name == SVGNames::fxAttr)
- setFxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_fx->setBaseValueAsString(value, parseError);
else if (name == SVGNames::fyAttr)
- setFyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_fy->setBaseValueAsString(value, parseError);
else if (name == SVGNames::frAttr)
- setFrBaseValue(SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths));
+ m_fr->setBaseValueAsString(value, parseError);
else
ASSERT_NOT_REACHED();
@@ -114,7 +105,7 @@ void SVGRadialGradientElement::svgAttributeChanged(const QualifiedName& attrName
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
updateRelativeLengthsInformation();
@@ -128,73 +119,78 @@ RenderObject* SVGRadialGradientElement::createRenderer(RenderStyle*)
return new RenderSVGResourceRadialGradient(this);
}
-bool SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttributes& attributes)
+static void setGradientAttributes(SVGGradientElement* element, RadialGradientAttributes& attributes, bool isRadial = true)
{
- HashSet<SVGGradientElement*> processedGradients;
-
- bool isRadial = true;
- SVGGradientElement* current = this;
+ if (!attributes.hasSpreadMethod() && element->spreadMethod()->isSpecified())
+ attributes.setSpreadMethod(element->spreadMethod()->currentValue()->enumValue());
- while (current) {
- if (!current->renderer())
- return false;
+ if (!attributes.hasGradientUnits() && element->gradientUnits()->isSpecified())
+ attributes.setGradientUnits(element->gradientUnits()->currentValue()->enumValue());
- if (!attributes.hasSpreadMethod() && current->hasAttribute(SVGNames::spreadMethodAttr))
- attributes.setSpreadMethod(current->spreadMethodCurrentValue());
+ if (!attributes.hasGradientTransform() && element->gradientTransform()->isSpecified()) {
+ AffineTransform transform;
+ element->gradientTransform()->currentValue()->concatenate(transform);
+ attributes.setGradientTransform(transform);
+ }
- if (!attributes.hasGradientUnits() && current->hasAttribute(SVGNames::gradientUnitsAttr))
- attributes.setGradientUnits(current->gradientUnitsCurrentValue());
+ if (!attributes.hasStops()) {
+ const Vector<Gradient::ColorStop>& stops(element->buildStops());
+ if (!stops.isEmpty())
+ attributes.setStops(stops);
+ }
- if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr)) {
- AffineTransform transform;
- current->gradientTransformCurrentValue().concatenate(transform);
- attributes.setGradientTransform(transform);
- }
+ if (isRadial) {
+ SVGRadialGradientElement* radial = toSVGRadialGradientElement(element);
- if (!attributes.hasStops()) {
- const Vector<Gradient::ColorStop>& stops(current->buildStops());
- if (!stops.isEmpty())
- attributes.setStops(stops);
- }
+ if (!attributes.hasCx() && radial->cx()->isSpecified())
+ attributes.setCx(radial->cx()->currentValue());
- if (isRadial) {
- SVGRadialGradientElement* radial = toSVGRadialGradientElement(current);
+ if (!attributes.hasCy() && radial->cy()->isSpecified())
+ attributes.setCy(radial->cy()->currentValue());
- if (!attributes.hasCx() && current->hasAttribute(SVGNames::cxAttr))
- attributes.setCx(radial->cxCurrentValue());
+ if (!attributes.hasR() && radial->r()->isSpecified())
+ attributes.setR(radial->r()->currentValue());
- if (!attributes.hasCy() && current->hasAttribute(SVGNames::cyAttr))
- attributes.setCy(radial->cyCurrentValue());
+ if (!attributes.hasFx() && radial->fx()->isSpecified())
+ attributes.setFx(radial->fx()->currentValue());
- if (!attributes.hasR() && current->hasAttribute(SVGNames::rAttr))
- attributes.setR(radial->rCurrentValue());
+ if (!attributes.hasFy() && radial->fy()->isSpecified())
+ attributes.setFy(radial->fy()->currentValue());
- if (!attributes.hasFx() && current->hasAttribute(SVGNames::fxAttr))
- attributes.setFx(radial->fxCurrentValue());
+ if (!attributes.hasFr() && radial->fr()->isSpecified())
+ attributes.setFr(radial->fr()->currentValue());
+ }
+}
- if (!attributes.hasFy() && current->hasAttribute(SVGNames::fyAttr))
- attributes.setFy(radial->fyCurrentValue());
+bool SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttributes& attributes)
+{
+ if (!renderer())
+ return false;
- if (!attributes.hasFr() && current->hasAttribute(SVGNames::frAttr))
- attributes.setFr(radial->frCurrentValue());
- }
+ HashSet<SVGGradientElement*> processedGradients;
+ SVGGradientElement* current = this;
- processedGradients.add(current);
+ setGradientAttributes(current, attributes);
+ processedGradients.add(current);
+ while (true) {
// Respect xlink:href, take attributes from referenced element
- Node* refNode = SVGURIReference::targetElementFromIRIString(current->hrefCurrentValue(), document());
- if (refNode && (refNode->hasTagName(SVGNames::radialGradientTag) || refNode->hasTagName(SVGNames::linearGradientTag))) {
+ Node* refNode = SVGURIReference::targetElementFromIRIString(current->href()->currentValue()->value(), treeScope());
+ if (refNode && isSVGGradientElement(*refNode)) {
current = toSVGGradientElement(refNode);
// Cycle detection
- if (processedGradients.contains(current)) {
- current = 0;
+ if (processedGradients.contains(current))
break;
- }
- isRadial = current->hasTagName(SVGNames::radialGradientTag);
- } else
- current = 0;
+ if (!current->renderer())
+ return false;
+
+ setGradientAttributes(current, attributes, isSVGRadialGradientElement(*current));
+ processedGradients.add(current);
+ } else {
+ break;
+ }
}
// Handle default values for fx/fy
@@ -203,17 +199,18 @@ bool SVGRadialGradientElement::collectGradientAttributes(RadialGradientAttribute
if (!attributes.hasFy())
attributes.setFy(attributes.cy());
+
return true;
}
bool SVGRadialGradientElement::selfHasRelativeLengths() const
{
- return cxCurrentValue().isRelative()
- || cyCurrentValue().isRelative()
- || rCurrentValue().isRelative()
- || fxCurrentValue().isRelative()
- || fyCurrentValue().isRelative()
- || frCurrentValue().isRelative();
+ return m_cx->currentValue()->isRelative()
+ || m_cy->currentValue()->isRelative()
+ || m_r->currentValue()->isRelative()
+ || m_fx->currentValue()->isRelative()
+ || m_fy->currentValue()->isRelative()
+ || m_fr->currentValue()->isRelative();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.h
index e448d2077c8..9bff1f8413b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRadialGradientElement.h
@@ -21,7 +21,7 @@
#ifndef SVGRadialGradientElement_h
#define SVGRadialGradientElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedLength.h"
#include "core/svg/SVGGradientElement.h"
@@ -31,33 +31,36 @@ struct RadialGradientAttributes;
class SVGRadialGradientElement FINAL : public SVGGradientElement {
public:
- static PassRefPtr<SVGRadialGradientElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGRadialGradientElement);
bool collectGradientAttributes(RadialGradientAttributes&);
+ SVGAnimatedLength* cx() const { return m_cx.get(); }
+ SVGAnimatedLength* cy() const { return m_cy.get(); }
+ SVGAnimatedLength* r() const { return m_r.get(); }
+ SVGAnimatedLength* fx() const { return m_fx.get(); }
+ SVGAnimatedLength* fy() const { return m_fy.get(); }
+ SVGAnimatedLength* fr() const { return m_fr.get(); }
+
private:
explicit SVGRadialGradientElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGRadialGradientElement)
- DECLARE_ANIMATED_LENGTH(Cx, cx)
- DECLARE_ANIMATED_LENGTH(Cy, cy)
- DECLARE_ANIMATED_LENGTH(R, r)
- DECLARE_ANIMATED_LENGTH(Fx, fx)
- DECLARE_ANIMATED_LENGTH(Fy, fy)
- DECLARE_ANIMATED_LENGTH(Fr, fr)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_cx;
+ RefPtr<SVGAnimatedLength> m_cy;
+ RefPtr<SVGAnimatedLength> m_r;
+ RefPtr<SVGAnimatedLength> m_fx;
+ RefPtr<SVGAnimatedLength> m_fy;
+ RefPtr<SVGAnimatedLength> m_fr;
};
-DEFINE_NODE_TYPE_CASTS(SVGRadialGradientElement, hasTagName(SVGNames::radialGradientTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRect.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGRect.cpp
new file mode 100644
index 00000000000..4869e222bfc
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRect.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGRect.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
+#include "core/svg/SVGParserUtilities.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+SVGRect::SVGRect()
+ : SVGPropertyBase(classType())
+ , m_isValid(true)
+{
+}
+
+SVGRect::SVGRect(InvalidSVGRectTag)
+ : SVGPropertyBase(classType())
+{
+ setInvalid();
+}
+
+SVGRect::SVGRect(const FloatRect& rect)
+ : SVGPropertyBase(classType())
+ , m_isValid(true)
+ , m_value(rect)
+{
+}
+
+PassRefPtr<SVGRect> SVGRect::clone() const
+{
+ return SVGRect::create(m_value);
+}
+
+PassRefPtr<SVGPropertyBase> SVGRect::cloneForAnimation(const String& value) const
+{
+ RefPtr<SVGRect> rect = SVGRect::create();
+ rect->setValueAsString(value, IGNORE_EXCEPTION);
+ return rect.release();
+}
+
+template<typename CharType>
+void SVGRect::parse(const CharType*& ptr, const CharType* end, ExceptionState& exceptionState)
+{
+ const CharType* start = ptr;
+
+ skipOptionalSVGSpaces(ptr, end);
+
+ float x = 0.0f;
+ float y = 0.0f;
+ float width = 0.0f;
+ float height = 0.0f;
+ bool valid = parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, DisallowWhitespace);
+
+ if (!valid) {
+ exceptionState.throwDOMException(SyntaxError, "Problem parsing rect \"" + String(start, end - start) + "\"");
+ setInvalid();
+ return;
+ }
+
+ skipOptionalSVGSpaces(ptr, end);
+ if (ptr < end) { // nothing should come after the last, fourth number
+ exceptionState.throwDOMException(SyntaxError, "Problem parsing rect \"" + String(start, end - start) + "\"");
+ setInvalid();
+ return;
+ }
+
+ m_value = FloatRect(x, y, width, height);
+ m_isValid = true;
+}
+
+void SVGRect::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+ if (string.isNull()) {
+ setInvalid();
+ return;
+ }
+ if (string.isEmpty()) {
+ m_value = FloatRect(0.0f, 0.0f, 0.0f, 0.0f);
+ m_isValid = true;
+ return;
+ }
+
+ if (string.is8Bit()) {
+ const LChar* ptr = string.characters8();
+ const LChar* end = ptr + string.length();
+ parse(ptr, end, exceptionState);
+ return;
+ }
+
+ const UChar* ptr = string.characters16();
+ const UChar* end = ptr + string.length();
+ parse(ptr, end, exceptionState);
+}
+
+String SVGRect::valueAsString() const
+{
+ StringBuilder builder;
+ builder.append(String::number(x()));
+ builder.append(' ');
+ builder.append(String::number(y()));
+ builder.append(' ');
+ builder.append(String::number(width()));
+ builder.append(' ');
+ builder.append(String::number(height()));
+ return builder.toString();
+}
+
+void SVGRect::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement*)
+{
+ m_value += toSVGRect(other)->value();
+}
+
+void SVGRect::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
+{
+ ASSERT(animationElement);
+ RefPtr<SVGRect> fromRect = animationElement->animationMode() == ToAnimation ? this : toSVGRect(fromValue);
+ RefPtr<SVGRect> toRect = toSVGRect(toValue);
+ RefPtr<SVGRect> toAtEndOfDurationRect = toSVGRect(toAtEndOfDurationValue);
+
+ float animatedX = x();
+ float animatedY = y();
+ float animatedWidth = width();
+ float animatedHeight = height();
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->x(), toRect->x(), toAtEndOfDurationRect->x(), animatedX);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->y(), toRect->y(), toAtEndOfDurationRect->y(), animatedY);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->width(), toRect->width(), toAtEndOfDurationRect->width(), animatedWidth);
+ animationElement->animateAdditiveNumber(percentage, repeatCount, fromRect->height(), toRect->height(), toAtEndOfDurationRect->height(), animatedHeight);
+
+ m_value = FloatRect(animatedX, animatedY, animatedWidth, animatedHeight);
+}
+
+float SVGRect::calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement)
+{
+ // FIXME: Distance calculation is not possible for SVGRect right now. We need the distance for every single value.
+ return -1;
+}
+
+void SVGRect::setInvalid()
+{
+ m_value = FloatRect(0.0f, 0.0f, 0.0f, 0.0f);
+ m_isValid = false;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRect.h b/chromium/third_party/WebKit/Source/core/svg/SVGRect.h
index 775c1966012..e2d86160280 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGRect.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRect.h
@@ -20,55 +20,82 @@
#ifndef SVGRect_h
#define SVGRect_h
-#include "core/svg/properties/SVGPropertyTraits.h"
+#include "core/svg/properties/SVGProperty.h"
#include "platform/geometry/FloatRect.h"
-#include "wtf/text/StringBuilder.h"
namespace WebCore {
-class SVGRect : public FloatRect {
+class SVGRectTearOff;
+
+class SVGRect : public SVGPropertyBase {
public:
+ typedef SVGRectTearOff TearOffType;
+
struct InvalidSVGRectTag { };
- SVGRect()
- : m_isValid(true) { }
- SVGRect(InvalidSVGRectTag)
- : m_isValid(false) { }
- SVGRect(const FloatRect& rect)
- : FloatRect(rect), m_isValid(true) { }
- SVGRect(const FloatPoint& location, const FloatSize& size)
- : FloatRect(location, size), m_isValid(true) { }
- SVGRect(float x, float y, float width, float height)
- : FloatRect(x, y, width, height), m_isValid(true) { }
- SVGRect(const IntRect& intRect)
- : FloatRect(intRect), m_isValid(true) { }
- SVGRect(const LayoutRect& layoutRect)
- : FloatRect(layoutRect), m_isValid(true) { }
- SVGRect(const SkRect& skRect)
- : FloatRect(skRect), m_isValid(true) { }
+ static PassRefPtr<SVGRect> create()
+ {
+ return adoptRef(new SVGRect());
+ }
+
+ static PassRefPtr<SVGRect> create(InvalidSVGRectTag)
+ {
+ return adoptRef(new SVGRect(InvalidSVGRectTag()));
+ }
+
+ static PassRefPtr<SVGRect> create(const FloatRect& rect)
+ {
+ return adoptRef(new SVGRect(rect));
+ }
+
+ PassRefPtr<SVGRect> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+ const FloatRect& value() const { return m_value; }
+ void setValue(const FloatRect& v) { m_value = v; }
+
+ float x() const { return m_value.x(); }
+ float y() const { return m_value.y(); }
+ float width() const { return m_value.width(); }
+ float height() const { return m_value.height(); }
+ void setX(float f) { m_value.setX(f); }
+ void setY(float f) { m_value.setY(f); }
+ void setWidth(float f) { m_value.setWidth(f); }
+ void setHeight(float f) { m_value.setHeight(f); }
+
+ bool operator==(const SVGRect&) const;
+ bool operator!=(const SVGRect& other) const { return !operator==(other); }
+
+ virtual String valueAsString() const OVERRIDE;
+ void setValueAsString(const String&, ExceptionState&);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
bool isValid() const { return m_isValid; }
+ void setInvalid();
+
+ static AnimatedPropertyType classType() { return AnimatedRect; }
private:
+ SVGRect();
+ SVGRect(InvalidSVGRectTag);
+ SVGRect(const FloatRect&);
+
+ template<typename CharType>
+ void parse(const CharType*& ptr, const CharType* end, ExceptionState&);
+
bool m_isValid;
+ FloatRect m_value;
};
-template<>
-struct SVGPropertyTraits<SVGRect> {
- static SVGRect initialValue() { return SVGRect(SVGRect::InvalidSVGRectTag()); }
- static String toString(const SVGRect& type)
- {
- StringBuilder builder;
- builder.append(String::number(type.x()));
- builder.append(' ');
- builder.append(String::number(type.y()));
- builder.append(' ');
- builder.append(String::number(type.width()));
- builder.append(' ');
- builder.append(String::number(type.height()));
- return builder.toString();
- }
-};
+inline PassRefPtr<SVGRect> toSVGRect(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGRect::classType());
+ return static_pointer_cast<SVGRect>(base.release());
+}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRect.idl b/chromium/third_party/WebKit/Source/core/svg/SVGRect.idl
index e148788295b..faff038f5f1 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGRect.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRect.idl
@@ -20,10 +20,13 @@
* Boston, MA 02110-1301, USA.
*/
-interface SVGRect {
- [StrictTypeChecking] attribute float x;
- [StrictTypeChecking] attribute float y;
- [StrictTypeChecking] attribute float width;
- [StrictTypeChecking] attribute float height;
+[
+ ImplementedAs=SVGRectTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGRect {
+ [RaisesException=Setter] attribute float x;
+ [RaisesException=Setter] attribute float y;
+ [RaisesException=Setter] attribute float width;
+ [RaisesException=Setter] attribute float height;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.cpp
index 61c539edf11..93c88971580 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.cpp
@@ -24,54 +24,35 @@
#include "core/rendering/svg/RenderSVGRect.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLength.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::rxAttr, Rx, rx)
-DEFINE_ANIMATED_LENGTH(SVGRectElement, SVGNames::ryAttr, Ry, ry)
-DEFINE_ANIMATED_BOOLEAN(SVGRectElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGRectElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(rx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(ry)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGRectElement::SVGRectElement(Document& document)
: SVGGeometryElement(SVGNames::rectTag, document)
- , m_x(LengthModeWidth)
- , m_y(LengthModeHeight)
- , m_width(LengthModeWidth)
- , m_height(LengthModeHeight)
- , m_rx(LengthModeWidth)
- , m_ry(LengthModeHeight)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
+ , m_rx(SVGAnimatedLength::create(this, SVGNames::rxAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_ry(SVGAnimatedLength::create(this, SVGNames::ryAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGRectElement();
-}
-PassRefPtr<SVGRectElement> SVGRectElement::create(Document& document)
-{
- return adoptRef(new SVGRectElement(document));
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
+ addToPropertyMap(m_rx);
+ addToPropertyMap(m_ry);
}
+DEFINE_NODE_FACTORY(SVGRectElement)
+
bool SVGRectElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::xAttr);
supportedAttributes.add(SVGNames::yAttr);
supportedAttributes.add(SVGNames::widthAttr);
@@ -89,19 +70,18 @@ void SVGRectElement::parseAttribute(const QualifiedName& name, const AtomicStrin
if (!isSupportedAttribute(name))
SVGGeometryElement::parseAttribute(name, value);
else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
+ m_x->setBaseValueAsString(value, parseError);
else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
+ m_y->setBaseValueAsString(value, parseError);
else if (name == SVGNames::rxAttr)
- setRxBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+ m_rx->setBaseValueAsString(value, parseError);
else if (name == SVGNames::ryAttr)
- setRyBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
+ m_ry->setBaseValueAsString(value, parseError);
else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
+ m_width->setBaseValueAsString(value, parseError);
else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
- else if (SVGExternalResourcesRequired::parseAttribute(name, value)) {
- } else
+ m_height->setBaseValueAsString(value, parseError);
+ else
ASSERT_NOT_REACHED();
reportAttributeParsingError(parseError, name, value);
@@ -114,7 +94,7 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
bool isLengthAttribute = attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
@@ -136,22 +116,17 @@ void SVGRectElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
- return;
- }
-
ASSERT_NOT_REACHED();
}
bool SVGRectElement::selfHasRelativeLengths() const
{
- return xCurrentValue().isRelative()
- || yCurrentValue().isRelative()
- || widthCurrentValue().isRelative()
- || heightCurrentValue().isRelative()
- || rxCurrentValue().isRelative()
- || ryCurrentValue().isRelative();
+ return m_x->currentValue()->isRelative()
+ || m_y->currentValue()->isRelative()
+ || m_width->currentValue()->isRelative()
+ || m_height->currentValue()->isRelative()
+ || m_rx->currentValue()->isRelative()
+ || m_ry->currentValue()->isRelative();
}
RenderObject* SVGRectElement::createRenderer(RenderStyle*)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.h
index 1a500884f4e..321125fe225 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.h
@@ -21,46 +21,43 @@
#ifndef SVGRectElement_h
#define SVGRectElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGeometryElement.h"
namespace WebCore {
-class SVGRectElement FINAL : public SVGGeometryElement,
- public SVGExternalResourcesRequired {
+class SVGRectElement FINAL : public SVGGeometryElement {
public:
- static PassRefPtr<SVGRectElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGRectElement);
+
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
+ SVGAnimatedLength* rx() const { return m_rx.get(); }
+ SVGAnimatedLength* ry() const { return m_ry.get(); }
private:
explicit SVGRectElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGRectElement)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_LENGTH(Rx, rx)
- DECLARE_ANIMATED_LENGTH(Ry, ry)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
+ RefPtr<SVGAnimatedLength> m_rx;
+ RefPtr<SVGAnimatedLength> m_ry;
};
-DEFINE_NODE_TYPE_CASTS(SVGRectElement, hasTagName(SVGNames::rectTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.idl
index a3cf85e5d7a..3bbe39abb6c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRectElement.idl
@@ -33,5 +33,3 @@ interface SVGRectElement : SVGGeometryElement {
readonly attribute SVGAnimatedLength ry;
};
-SVGRectElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp
new file mode 100644
index 00000000000..cd9c07236aa
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGRectTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+SVGRectTearOff::SVGRectTearOff(PassRefPtr<SVGRect> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ : SVGPropertyTearOff<SVGRect>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+void SVGRectTearOff::setX(float f, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setX(f);
+ commitChange();
+}
+
+void SVGRectTearOff::setY(float f, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setY(f);
+ commitChange();
+}
+
+void SVGRectTearOff::setWidth(float f, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setWidth(f);
+ commitChange();
+}
+
+void SVGRectTearOff::setHeight(float f, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setHeight(f);
+ commitChange();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRectTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGRectTearOff.h
new file mode 100644
index 00000000000..a4c7ee51f3b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRectTearOff.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGRectTearOff_h
+#define SVGRectTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGRect.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGRectTearOff : public SVGPropertyTearOff<SVGRect>, public ScriptWrappable {
+public:
+ static PassRefPtr<SVGRectTearOff> create(PassRefPtr<SVGRect> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGRectTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ void setX(float, ExceptionState&);
+ void setY(float, ExceptionState&);
+ void setWidth(float, ExceptionState&);
+ void setHeight(float, ExceptionState&);
+ float x() { return target()->x(); }
+ float y() { return target()->y(); }
+ float width() { return target()->width(); }
+ float height() { return target()->height(); }
+
+private:
+ SVGRectTearOff(PassRefPtr<SVGRect>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName = QualifiedName::null());
+};
+
+} // namespace WebCore
+
+#endif // SVGRectTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp
new file mode 100644
index 00000000000..565e9836c34
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp
@@ -0,0 +1,74 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#if ENABLE(SVG_FONTS)
+#include "core/svg/SVGRemoteFontFaceSource.h"
+
+#include "core/SVGNames.h"
+#include "core/css/FontLoader.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/svg/SVGFontData.h"
+#include "core/svg/SVGFontElement.h"
+#include "core/svg/SVGFontFaceElement.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+
+namespace WebCore {
+
+SVGRemoteFontFaceSource::SVGRemoteFontFaceSource(const String& uri, FontResource* font, PassRefPtrWillBeRawPtr<FontLoader> fontLoader)
+ : RemoteFontFaceSource(font, fontLoader)
+ , m_uri(uri)
+{
+}
+
+SVGRemoteFontFaceSource::~SVGRemoteFontFaceSource()
+{
+}
+
+bool SVGRemoteFontFaceSource::ensureFontData()
+{
+ return resource()->ensureSVGFontData();
+}
+
+PassRefPtr<SimpleFontData> SVGRemoteFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+ if (!isLoaded())
+ return createLoadingFallbackFontData(fontDescription);
+
+ // Parse the external SVG document, and extract the <font> element.
+ if (!resource()->ensureSVGFontData())
+ return nullptr;
+
+ if (!m_externalSVGFontElement) {
+ String fragmentIdentifier;
+ size_t start = m_uri.find('#');
+ if (start != kNotFound)
+ fragmentIdentifier = m_uri.substring(start + 1);
+ m_externalSVGFontElement = resource()->getSVGFontById(fragmentIdentifier);
+ }
+
+ if (!m_externalSVGFontElement)
+ return nullptr;
+
+ // Select first <font-face> child
+ if (SVGFontFaceElement* fontFaceElement = Traversal<SVGFontFaceElement>::firstChild(*m_externalSVGFontElement)) {
+ return SimpleFontData::create(
+ SVGFontData::create(fontFaceElement),
+ fontDescription.effectiveFontSize(),
+ fontDescription.isSyntheticBold(),
+ fontDescription.isSyntheticItalic());
+ }
+ return nullptr;
+}
+
+void SVGRemoteFontFaceSource::trace(Visitor* visitor)
+{
+ visitor->trace(m_externalSVGFontElement);
+ RemoteFontFaceSource::trace(visitor);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.h b/chromium/third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.h
new file mode 100644
index 00000000000..0ef6b0e7378
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.h
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SVGRemoteFontFaceSource_h
+#define SVGRemoteFontFaceSource_h
+
+#if ENABLE(SVG_FONTS)
+
+#include "core/css/RemoteFontFaceSource.h"
+#include "platform/heap/Handle.h"
+
+namespace WebCore {
+
+class SVGFontElement;
+
+class SVGRemoteFontFaceSource : public RemoteFontFaceSource {
+public:
+ SVGRemoteFontFaceSource(const String& uri, FontResource*, PassRefPtrWillBeRawPtr<FontLoader>);
+ ~SVGRemoteFontFaceSource();
+ virtual bool isSVGFontFaceSource() const OVERRIDE { return true; }
+ virtual bool ensureFontData() OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+
+ String m_uri;
+ RefPtrWillBeMember<SVGFontElement> m_externalSVGFontElement;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG_FONTS)
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGRenderingIntent.idl b/chromium/third_party/WebKit/Source/core/svg/SVGRenderingIntent.idl
index 4092cda304f..2cdc2f43ef3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGRenderingIntent.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGRenderingIntent.idl
@@ -23,7 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGRenderingIntent {
+[
+ DependentLifetime,
+] interface SVGRenderingIntent {
// Rendering Intent Types
const unsigned short RENDERING_INTENT_UNKNOWN = 0;
const unsigned short RENDERING_INTENT_AUTO = 1;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
index f53db048703..9f69a674f74 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org>
* Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,18 +24,16 @@
#include "core/svg/SVGSVGElement.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/css/CSSHelper.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
-#include "core/dom/NodeTraversal.h"
#include "core/dom/StaticNodeList.h"
#include "core/editing/FrameSelection.h"
#include "core/events/EventListener.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/page/FrameTree.h"
#include "core/frame/FrameView.h"
#include "core/frame/UseCounter.h"
@@ -44,11 +43,13 @@
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/RenderSVGRoot.h"
#include "core/rendering/svg/RenderSVGViewportContainer.h"
-#include "core/svg/SVGAngle.h"
-#include "core/svg/SVGElementInstance.h"
+#include "core/svg/SVGAngleTearOff.h"
+#include "core/svg/SVGNumberTearOff.h"
#include "core/svg/SVGPreserveAspectRatio.h"
+#include "core/svg/SVGRectTearOff.h"
#include "core/svg/SVGTransform.h"
#include "core/svg/SVGTransformList.h"
+#include "core/svg/SVGTransformTearOff.h"
#include "core/svg/SVGViewElement.h"
#include "core/svg/SVGViewSpec.h"
#include "core/svg/animation/SMILTimeContainer.h"
@@ -60,86 +61,53 @@
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGSVGElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGSVGElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGSVGElement, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGSVGElement, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_BOOLEAN(SVGSVGElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGSVGElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
-DEFINE_ANIMATED_RECT(SVGSVGElement, SVGNames::viewBoxAttr, ViewBox, viewBox)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGSVGElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_LOCAL_ANIMATED_PROPERTY(viewBox)
- REGISTER_LOCAL_ANIMATED_PROPERTY(preserveAspectRatio)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGSVGElement::SVGSVGElement(Document& doc)
: SVGGraphicsElement(SVGNames::svgTag, doc)
- , m_x(LengthModeWidth)
- , m_y(LengthModeHeight)
- , m_width(LengthModeWidth, "100%")
- , m_height(LengthModeHeight, "100%")
+ , SVGFitToViewBox(this)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
, m_useCurrentView(false)
- , m_zoomAndPan(SVGZoomAndPanMagnify)
- , m_timeContainer(SMILTimeContainer::create(this))
- , m_weakFactory(this)
+ , m_timeContainer(SMILTimeContainer::create(*this))
+ , m_translation(SVGPoint::create())
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGSVGElement();
+
+ m_width->setDefaultValueAsString("100%");
+ m_height->setDefaultValueAsString("100%");
+
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
UseCounter::count(doc, UseCounter::SVGSVGElement);
}
-PassRefPtr<SVGSVGElement> SVGSVGElement::create(Document& document)
-{
- return adoptRef(new SVGSVGElement(document));
-}
+DEFINE_NODE_FACTORY(SVGSVGElement)
SVGSVGElement::~SVGSVGElement()
{
+#if !ENABLE(OILPAN)
+ if (m_viewSpec)
+ m_viewSpec->detachContextElement();
+
// There are cases where removedFromDocument() is not called.
// see ContainerNode::removeAllChildren, called by its destructor.
- document().accessSVGExtensions()->removeTimeContainer(this);
-
- ASSERT(inDocument() || !accessDocumentSVGExtensions()->isSVGRootWithRelativeLengthDescendents(this));
-}
-
-const AtomicString& SVGSVGElement::contentScriptType() const
-{
- DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("text/ecmascript", AtomicString::ConstructFromLiteral));
- const AtomicString& n = fastGetAttribute(SVGNames::contentScriptTypeAttr);
- return n.isNull() ? defaultValue : n;
-}
+ // With Oilpan, either removedFrom is called or the document
+ // is dead as well and there is no reason to clear the extensions.
+ document().accessSVGExtensions().removeTimeContainer(this);
-void SVGSVGElement::setContentScriptType(const AtomicString& type)
-{
- setAttribute(SVGNames::contentScriptTypeAttr, type);
-}
-
-const AtomicString& SVGSVGElement::contentStyleType() const
-{
- DEFINE_STATIC_LOCAL(const AtomicString, defaultValue, ("text/css", AtomicString::ConstructFromLiteral));
- const AtomicString& n = fastGetAttribute(SVGNames::contentStyleTypeAttr);
- return n.isNull() ? defaultValue : n;
+ ASSERT(inDocument() || !accessDocumentSVGExtensions().isSVGRootWithRelativeLengthDescendents(this));
+#endif
}
-void SVGSVGElement::setContentStyleType(const AtomicString& type)
-{
- setAttribute(SVGNames::contentStyleTypeAttr, type);
-}
-
-SVGRect SVGSVGElement::viewport() const
+PassRefPtr<SVGRectTearOff> SVGSVGElement::viewport() const
{
// FIXME: This method doesn't follow the spec and is basically untested. Parent documents are not considered here.
// As we have no test coverage for this, we're going to disable it completly for now.
- return SVGRect();
+ return SVGRectTearOff::create(SVGRect::create(), 0, PropertyIsNotAnimVal);
}
float SVGSVGElement::pixelUnitToMillimeterX() const
@@ -165,7 +133,7 @@ float SVGSVGElement::screenPixelToMillimeterY() const
SVGViewSpec* SVGSVGElement::currentView()
{
if (!m_viewSpec)
- m_viewSpec = SVGViewSpec::create(m_weakFactory.createWeakPtr());
+ m_viewSpec = SVGViewSpec::create(this);
return m_viewSpec.get();
}
@@ -174,7 +142,7 @@ float SVGSVGElement::currentScale() const
if (!inDocument() || !isOutermostSVGSVGElement())
return 1;
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return 1;
@@ -191,7 +159,7 @@ void SVGSVGElement::setCurrentScale(float scale)
if (!inDocument() || !isOutermostSVGSVGElement())
return;
- Frame* frame = document().frame();
+ LocalFrame* frame = document().frame();
if (!frame)
return;
@@ -206,19 +174,41 @@ void SVGSVGElement::setCurrentScale(float scale)
frame->setPageZoomFactor(scale);
}
-void SVGSVGElement::setCurrentTranslate(const FloatPoint& translation)
+class SVGCurrentTranslateTearOff : public SVGPointTearOff {
+public:
+ static PassRefPtr<SVGCurrentTranslateTearOff> create(SVGSVGElement* contextElement)
+ {
+ return adoptRef(new SVGCurrentTranslateTearOff(contextElement));
+ }
+
+ virtual void commitChange() OVERRIDE
+ {
+ ASSERT(contextElement());
+ toSVGSVGElement(contextElement())->updateCurrentTranslate();
+ }
+
+private:
+ SVGCurrentTranslateTearOff(SVGSVGElement* contextElement)
+ : SVGPointTearOff(contextElement->m_translation, contextElement, PropertyIsNotAnimVal)
+ {
+ }
+};
+
+PassRefPtr<SVGPointTearOff> SVGSVGElement::currentTranslateFromJavascript()
+{
+ return SVGCurrentTranslateTearOff::create(this);
+}
+
+void SVGSVGElement::setCurrentTranslate(const FloatPoint& point)
{
- m_translation = translation;
+ m_translation->setValue(point);
updateCurrentTranslate();
}
void SVGSVGElement::updateCurrentTranslate()
{
if (RenderObject* object = renderer())
- object->setNeedsLayout();
-
- if (parentNode() == document() && document().renderer())
- document().renderer()->repaint();
+ object->setNeedsLayoutAndFullPaintInvalidation();
}
void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -230,13 +220,13 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
// Only handle events if we're the outermost <svg> element
if (name == HTMLNames::onunloadAttr)
- document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::unload, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == HTMLNames::onresizeAttr)
- document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::resize, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == HTMLNames::onscrollAttr)
- document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::scroll, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else if (name == SVGNames::onzoomAttr)
- document().setWindowAttributeEventListener(EventTypeNames::zoom, createAttributeEventListener(document().frame(), name, value));
+ document().setWindowAttributeEventListener(EventTypeNames::zoom, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
else
setListener = false;
@@ -244,45 +234,76 @@ void SVGSVGElement::parseAttribute(const QualifiedName& name, const AtomicString
return;
}
- if (name == HTMLNames::onabortAttr)
- document().setWindowAttributeEventListener(EventTypeNames::abort, createAttributeEventListener(document().frame(), name, value));
- else if (name == HTMLNames::onerrorAttr)
- document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value));
- else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
- else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
- else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
- else if (SVGExternalResourcesRequired::parseAttribute(name, value)
- || SVGFitToViewBox::parseAttribute(this, name, value)
- || SVGZoomAndPan::parseAttribute(this, name, value)) {
- } else
+ if (name == HTMLNames::onabortAttr) {
+ document().setWindowAttributeEventListener(EventTypeNames::abort, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ } else if (name == HTMLNames::onerrorAttr) {
+ document().setWindowAttributeEventListener(EventTypeNames::error, createAttributeEventListener(document().frame(), name, value, eventParameterName()));
+ } else if (name == SVGNames::xAttr) {
+ m_x->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::yAttr) {
+ m_y->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::widthAttr) {
+ m_width->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::heightAttr) {
+ m_height->setBaseValueAsString(value, parseError);
+ } else if (SVGFitToViewBox::parseAttribute(name, value, document(), parseError)) {
+ } else if (SVGZoomAndPan::parseAttribute(name, value)) {
+ } else {
SVGGraphicsElement::parseAttribute(name, value);
+ }
reportAttributeParsingError(parseError, name, value);
}
+bool SVGSVGElement::isPresentationAttribute(const QualifiedName& name) const
+{
+ if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr))
+ return true;
+ return SVGGraphicsElement::isPresentationAttribute(name);
+}
+
+void SVGSVGElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStylePropertySet* style)
+{
+ if (isOutermostSVGSVGElement() && (name == SVGNames::widthAttr || name == SVGNames::heightAttr)) {
+ RefPtr<SVGLength> length = SVGLength::create(LengthModeOther);
+ TrackExceptionState exceptionState;
+ length->setValueAsString(value, exceptionState);
+ if (!exceptionState.hadException()) {
+ if (name == SVGNames::widthAttr)
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyWidth, value);
+ else if (name == SVGNames::heightAttr)
+ addPropertyToPresentationAttributeStyle(style, CSSPropertyHeight, value);
+ }
+ } else {
+ SVGGraphicsElement::collectStyleForPresentationAttribute(name, value, style);
+ }
+}
+
void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
{
bool updateRelativeLengthsOrViewBox = false;
bool widthChanged = attrName == SVGNames::widthAttr;
- if (widthChanged
- || attrName == SVGNames::heightAttr
+ bool heightChanged = attrName == SVGNames::heightAttr;
+ if (widthChanged || heightChanged
|| attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr) {
updateRelativeLengthsOrViewBox = true;
updateRelativeLengthsInformation();
invalidateRelativeLengthClients();
- // At the SVG/HTML boundary (aka RenderSVGRoot), the width attribute can
- // affect the replaced size so we need to mark it for updating.
- if (widthChanged) {
+ // At the SVG/HTML boundary (aka RenderSVGRoot), the width and
+ // height attributes can affect the replaced size so we need
+ // to mark it for updating.
+ //
+ // FIXME: For width/height animated as XML attributes on SVG
+ // roots, there is an attribute synchronization missing. See
+ // http://crbug.com/364807
+ if (widthChanged || heightChanged) {
RenderObject* renderObject = renderer();
- if (renderObject && renderObject->isSVGRoot())
- toRenderSVGRoot(renderObject)->setNeedsLayoutAndPrefWidthsRecalc();
+ if (renderObject && renderObject->isSVGRoot()) {
+ invalidateSVGPresentationAttributeStyle();
+ setNeedsStyleRecalc(LocalStyleChange);
+ }
}
}
@@ -292,10 +313,9 @@ void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
object->setNeedsTransformUpdate();
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (updateRelativeLengthsOrViewBox
- || SVGExternalResourcesRequired::isKnownAttribute(attrName)
|| SVGZoomAndPan::isKnownAttribute(attrName)) {
if (renderer())
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer());
@@ -305,116 +325,155 @@ void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
SVGGraphicsElement::svgAttributeChanged(attrName);
}
-unsigned SVGSVGElement::suspendRedraw(unsigned /* maxWaitMilliseconds */)
+// FloatRect::intersects does not consider horizontal or vertical lines (because of isEmpty()).
+static bool intersectsAllowingEmpty(const FloatRect& r1, const FloatRect& r2)
{
- // FIXME: Implement me (see bug 11275)
- return 0;
-}
+ if (r1.width() < 0 || r1.height() < 0 || r2.width() < 0 || r2.height() < 0)
+ return false;
-void SVGSVGElement::unsuspendRedraw(unsigned /* suspendHandleId */)
-{
- // FIXME: Implement me (see bug 11275)
+ return r1.x() < r2.maxX() && r2.x() < r1.maxX()
+ && r1.y() < r2.maxY() && r2.y() < r1.maxY();
}
-void SVGSVGElement::unsuspendRedrawAll()
+// One of the element types that can cause graphics to be drawn onto the target canvas.
+// Specifically: circle, ellipse, image, line, path, polygon, polyline, rect, text and use.
+static bool isIntersectionOrEnclosureTarget(RenderObject* renderer)
{
- // FIXME: Implement me (see bug 11275)
+ return renderer->isSVGShape()
+ || renderer->isSVGText()
+ || renderer->isSVGImage()
+ || isSVGUseElement(*renderer->node());
}
-void SVGSVGElement::forceRedraw()
+bool SVGSVGElement::checkIntersectionOrEnclosure(const SVGElement& element, const FloatRect& rect,
+ CheckIntersectionOrEnclosure mode) const
{
- // FIXME: Implement me (see bug 11275)
+ RenderObject* renderer = element.renderer();
+ ASSERT(!renderer || renderer->style());
+ if (!renderer || renderer->style()->pointerEvents() == PE_NONE)
+ return false;
+
+ if (!isIntersectionOrEnclosureTarget(renderer))
+ return false;
+
+ AffineTransform ctm = toSVGGraphicsElement(element).computeCTM(AncestorScope, DisallowStyleUpdate, this);
+ FloatRect mappedRepaintRect = ctm.mapRect(renderer->paintInvalidationRectInLocalCoordinates());
+
+ bool result = false;
+ switch (mode) {
+ case CheckIntersection:
+ result = intersectsAllowingEmpty(rect, mappedRepaintRect);
+ break;
+ case CheckEnclosure:
+ result = rect.contains(mappedRepaintRect);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+
+ return result;
}
-PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const SVGRect& rect, SVGElement* referenceElement, CollectIntersectionOrEnclosure collect) const
+PassRefPtrWillBeRawPtr<StaticNodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const FloatRect& rect,
+ SVGElement* referenceElement, CheckIntersectionOrEnclosure mode) const
{
- Vector<RefPtr<Node> > nodes;
- Element* element = ElementTraversal::next(*(referenceElement ? referenceElement : this));
- while (element) {
- if (element->isSVGElement()) {
- SVGElement* svgElement = toSVGElement(element);
- if (collect == CollectIntersectionList) {
- if (checkIntersection(svgElement, rect))
- nodes.append(element);
- } else {
- if (checkEnclosure(svgElement, rect))
- nodes.append(element);
- }
+ WillBeHeapVector<RefPtrWillBeMember<Node> > nodes;
+
+ const SVGElement* root = this;
+ if (referenceElement) {
+ // Only the common subtree needs to be traversed.
+ if (contains(referenceElement)) {
+ root = referenceElement;
+ } else if (!isDescendantOf(referenceElement)) {
+ // No common subtree.
+ return StaticNodeList::adopt(nodes);
}
+ }
- element = ElementTraversal::next(*element, referenceElement ? referenceElement : this);
+ for (SVGGraphicsElement* element = Traversal<SVGGraphicsElement>::firstWithin(*root); element;
+ element = Traversal<SVGGraphicsElement>::next(*element, root)) {
+ if (checkIntersectionOrEnclosure(*element, rect, mode))
+ nodes.append(element);
}
+
return StaticNodeList::adopt(nodes);
}
-PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(const SVGRect& rect, SVGElement* referenceElement) const
+PassRefPtrWillBeRawPtr<StaticNodeList> SVGSVGElement::getIntersectionList(PassRefPtr<SVGRectTearOff> rect, SVGElement* referenceElement) const
{
- return collectIntersectionOrEnclosureList(rect, referenceElement, CollectIntersectionList);
+ document().updateLayoutIgnorePendingStylesheets();
+
+ return collectIntersectionOrEnclosureList(rect->target()->value(), referenceElement, CheckIntersection);
}
-PassRefPtr<NodeList> SVGSVGElement::getEnclosureList(const SVGRect& rect, SVGElement* referenceElement) const
+PassRefPtrWillBeRawPtr<StaticNodeList> SVGSVGElement::getEnclosureList(PassRefPtr<SVGRectTearOff> rect, SVGElement* referenceElement) const
{
- return collectIntersectionOrEnclosureList(rect, referenceElement, CollectEnclosureList);
+ document().updateLayoutIgnorePendingStylesheets();
+
+ return collectIntersectionOrEnclosureList(rect->target()->value(), referenceElement, CheckEnclosure);
}
-bool SVGSVGElement::checkIntersection(SVGElement* element, const SVGRect& rect) const
+bool SVGSVGElement::checkIntersection(SVGElement* element, PassRefPtr<SVGRectTearOff> rect) const
{
- if (!element)
- return false;
- return RenderSVGModelObject::checkIntersection(element->renderer(), rect);
+ ASSERT(element);
+ document().updateLayoutIgnorePendingStylesheets();
+
+ return checkIntersectionOrEnclosure(*element, rect->target()->value(), CheckIntersection);
}
-bool SVGSVGElement::checkEnclosure(SVGElement* element, const SVGRect& rect) const
+bool SVGSVGElement::checkEnclosure(SVGElement* element, PassRefPtr<SVGRectTearOff> rect) const
{
- if (!element)
- return false;
- return RenderSVGModelObject::checkEnclosure(element->renderer(), rect);
+ ASSERT(element);
+ document().updateLayoutIgnorePendingStylesheets();
+
+ return checkIntersectionOrEnclosure(*element, rect->target()->value(), CheckEnclosure);
}
void SVGSVGElement::deselectAll()
{
- if (Frame* frame = document().frame())
+ if (LocalFrame* frame = document().frame())
frame->selection().clear();
}
-float SVGSVGElement::createSVGNumber()
+PassRefPtr<SVGNumberTearOff> SVGSVGElement::createSVGNumber()
{
- return 0.0f;
+ return SVGNumberTearOff::create(SVGNumber::create(0.0f), 0, PropertyIsNotAnimVal);
}
-SVGLength SVGSVGElement::createSVGLength()
+PassRefPtr<SVGLengthTearOff> SVGSVGElement::createSVGLength()
{
- return SVGLength();
+ return SVGLengthTearOff::create(SVGLength::create(), 0, PropertyIsNotAnimVal);
}
-SVGAngle SVGSVGElement::createSVGAngle()
+PassRefPtr<SVGAngleTearOff> SVGSVGElement::createSVGAngle()
{
- return SVGAngle();
+ return SVGAngleTearOff::create(SVGAngle::create(), 0, PropertyIsNotAnimVal);
}
-SVGPoint SVGSVGElement::createSVGPoint()
+PassRefPtr<SVGPointTearOff> SVGSVGElement::createSVGPoint()
{
- return SVGPoint();
+ return SVGPointTearOff::create(SVGPoint::create(), 0, PropertyIsNotAnimVal);
}
-SVGMatrix SVGSVGElement::createSVGMatrix()
+PassRefPtr<SVGMatrixTearOff> SVGSVGElement::createSVGMatrix()
{
- return SVGMatrix();
+ return SVGMatrixTearOff::create(AffineTransform());
}
-SVGRect SVGSVGElement::createSVGRect()
+PassRefPtr<SVGRectTearOff> SVGSVGElement::createSVGRect()
{
- return SVGRect();
+ return SVGRectTearOff::create(SVGRect::create(), 0, PropertyIsNotAnimVal);
}
-SVGTransform SVGSVGElement::createSVGTransform()
+PassRefPtr<SVGTransformTearOff> SVGSVGElement::createSVGTransform()
{
- return SVGTransform(SVGTransform::SVG_TRANSFORM_MATRIX);
+ return SVGTransformTearOff::create(SVGTransform::create(SVG_TRANSFORM_MATRIX), 0, PropertyIsNotAnimVal);
}
-SVGTransform SVGSVGElement::createSVGTransformFromMatrix(const SVGMatrix& matrix)
+PassRefPtr<SVGTransformTearOff> SVGSVGElement::createSVGTransformFromMatrix(PassRefPtr<SVGMatrixTearOff> matrix)
{
- return SVGTransform(static_cast<const AffineTransform&>(matrix));
+ return SVGTransformTearOff::create(SVGTransform::create(matrix->value()), 0, PropertyIsNotAnimVal);
}
AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGElement::CTMScope mode) const
@@ -428,7 +487,7 @@ AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGElement::CTMScop
AffineTransform transform;
if (!isOutermostSVGSVGElement()) {
SVGLengthContext lengthContext(this);
- transform.translate(xCurrentValue().value(lengthContext), yCurrentValue().value(lengthContext));
+ transform.translate(m_x->currentValue()->value(lengthContext), m_y->currentValue()->value(lengthContext));
} else if (mode == SVGElement::ScreenScope) {
if (RenderObject* renderer = this->renderer()) {
FloatPoint location;
@@ -486,7 +545,11 @@ RenderObject* SVGSVGElement::createRenderer(RenderStyle*)
Node::InsertionNotificationRequest SVGSVGElement::insertedInto(ContainerNode* rootParent)
{
if (rootParent->inDocument()) {
- document().accessSVGExtensions()->addTimeContainer(this);
+ UseCounter::count(document(), UseCounter::SVGSVGElementInDocument);
+ if (rootParent->document().isXMLDocument())
+ UseCounter::count(document(), UseCounter::SVGSVGElementInXMLDocument);
+
+ document().accessSVGExtensions().addTimeContainer(this);
// Animations are started at the end of document parsing and after firing the load event,
// but if we miss that train (deferred programmatic element insertion for example) we need
@@ -500,9 +563,9 @@ Node::InsertionNotificationRequest SVGSVGElement::insertedInto(ContainerNode* ro
void SVGSVGElement::removedFrom(ContainerNode* rootParent)
{
if (rootParent->inDocument()) {
- SVGDocumentExtensions* svgExtensions = document().accessSVGExtensions();
- svgExtensions->removeTimeContainer(this);
- svgExtensions->removeSVGRootWithRelativeLengthDescendents(this);
+ SVGDocumentExtensions& svgExtensions = document().accessSVGExtensions();
+ svgExtensions.removeTimeContainer(this);
+ svgExtensions.removeSVGRootWithRelativeLengthDescendents(this);
}
SVGGraphicsElement::removedFrom(rootParent);
@@ -540,42 +603,38 @@ void SVGSVGElement::setCurrentTime(float seconds)
bool SVGSVGElement::selfHasRelativeLengths() const
{
- return xCurrentValue().isRelative()
- || yCurrentValue().isRelative()
- || widthCurrentValue().isRelative()
- || heightCurrentValue().isRelative()
+ return m_x->currentValue()->isRelative()
+ || m_y->currentValue()->isRelative()
+ || m_width->currentValue()->isRelative()
+ || m_height->currentValue()->isRelative()
|| hasAttribute(SVGNames::viewBoxAttr);
}
-SVGRect SVGSVGElement::currentViewBoxRect() const
+FloatRect SVGSVGElement::currentViewBoxRect() const
{
if (m_useCurrentView)
- return m_viewSpec ? m_viewSpec->viewBoxCurrentValue() : SVGRect();
+ return m_viewSpec ? m_viewSpec->viewBox()->currentValue()->value() : FloatRect();
- FloatRect useViewBox = viewBoxCurrentValue();
+ FloatRect useViewBox = viewBox()->currentValue()->value();
if (!useViewBox.isEmpty())
return useViewBox;
if (!renderer() || !renderer()->isSVGRoot())
- return SVGRect();
+ return FloatRect();
if (!toRenderSVGRoot(renderer())->isEmbeddedThroughSVGImage())
- return SVGRect();
-
- Length intrinsicWidth = this->intrinsicWidth();
- Length intrinsicHeight = this->intrinsicHeight();
- if (!intrinsicWidth.isFixed() || !intrinsicHeight.isFixed())
- return SVGRect();
+ return FloatRect();
// If no viewBox is specified but non-relative width/height values, then we
// should always synthesize a viewBox if we're embedded through a SVGImage.
- return SVGRect(FloatPoint(), FloatSize(floatValueForLength(intrinsicWidth, 0, 0), floatValueForLength(intrinsicHeight, 0, 0)));
+ return FloatRect(FloatPoint(), FloatSize(floatValueForLength(intrinsicWidth(), 0), floatValueForLength(intrinsicHeight(), 0)));
}
FloatSize SVGSVGElement::currentViewportSize() const
{
- Length intrinsicWidth = this->intrinsicWidth();
- Length intrinsicHeight = this->intrinsicHeight();
- if (intrinsicWidth.isFixed() && intrinsicHeight.isFixed())
+ if (hasIntrinsicWidth() && hasIntrinsicHeight()) {
+ Length intrinsicWidth = this->intrinsicWidth();
+ Length intrinsicHeight = this->intrinsicHeight();
return FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0));
+ }
if (!renderer())
return FloatSize();
@@ -589,94 +648,46 @@ FloatSize SVGSVGElement::currentViewportSize() const
return FloatSize(viewportRect.width(), viewportRect.height());
}
-bool SVGSVGElement::widthAttributeEstablishesViewport() const
+bool SVGSVGElement::hasIntrinsicWidth() const
{
- if (!renderer() || renderer()->isSVGViewportContainer())
- return true;
-
- // Spec: http://www.w3.org/TR/SVG/coords.html#ViewportSpace
- // The ‘width’ attribute on the outermost svg element establishes the viewport's width, unless the following conditions are met:
- // - the SVG content is a separately stored resource that is embedded by reference (such as the ‘object’ element in XHTML [XHTML]), or
- // the SVG content is embedded inline within a containing document;
- // - and the referencing element or containing document is styled using CSS [CSS2] or XSL [XSL];
- // - and there are CSS-compatible positioning properties ([CSS2], section 9.3) specified on the referencing element (e.g., the ‘object’ element)
- // or on the containing document's outermost svg element that are sufficient to establish the width of the viewport. Under these conditions,
- // the positioning properties establish the viewport's width.
- RenderSVGRoot* root = toRenderSVGRoot(renderer());
-
- // SVG embedded through object/embed/iframe.
- if (root->isEmbeddedThroughFrameContainingSVGDocument())
- return !root->hasReplacedLogicalWidth() && !document().frame()->ownerRenderer()->hasReplacedLogicalWidth();
-
- // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
- if (root->isEmbeddedThroughSVGImage() || document().documentElement() != this)
- return !root->hasReplacedLogicalWidth();
-
- return true;
+ return width()->currentValue()->unitType() != LengthTypePercentage;
}
-bool SVGSVGElement::heightAttributeEstablishesViewport() const
+bool SVGSVGElement::hasIntrinsicHeight() const
{
- if (!renderer() || renderer()->isSVGViewportContainer())
- return true;
-
- // Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing
- // Similarly, if there are positioning properties specified on the referencing element or on the outermost svg element
- // that are sufficient to establish the height of the viewport, then these positioning properties establish the viewport's
- // height; otherwise, the ‘height’ attribute on the outermost svg element establishes the viewport's height.
- RenderSVGRoot* root = toRenderSVGRoot(renderer());
-
- // SVG embedded through object/embed/iframe.
- if (root->isEmbeddedThroughFrameContainingSVGDocument())
- return !root->hasReplacedLogicalHeight() && !document().frame()->ownerRenderer()->hasReplacedLogicalHeight();
-
- // SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
- if (root->isEmbeddedThroughSVGImage() || document().documentElement() != this)
- return !root->hasReplacedLogicalHeight();
-
- return true;
+ return height()->currentValue()->unitType() != LengthTypePercentage;
}
-Length SVGSVGElement::intrinsicWidth(ConsiderCSSMode mode) const
+Length SVGSVGElement::intrinsicWidth() const
{
- if (widthAttributeEstablishesViewport() || mode == IgnoreCSSProperties) {
- if (widthCurrentValue().unitType() == LengthTypePercentage)
- return Length(widthCurrentValue().valueAsPercentage() * 100, Percent);
+ if (width()->currentValue()->unitType() == LengthTypePercentage)
+ return Length(0, Fixed);
- SVGLengthContext lengthContext(this);
- return Length(widthCurrentValue().value(lengthContext), Fixed);
- }
-
- ASSERT(renderer());
- return renderer()->style()->width();
+ SVGLengthContext lengthContext(this);
+ return Length(width()->currentValue()->value(lengthContext), Fixed);
}
-Length SVGSVGElement::intrinsicHeight(ConsiderCSSMode mode) const
+Length SVGSVGElement::intrinsicHeight() const
{
- if (heightAttributeEstablishesViewport() || mode == IgnoreCSSProperties) {
- if (heightCurrentValue().unitType() == LengthTypePercentage)
- return Length(heightCurrentValue().valueAsPercentage() * 100, Percent);
-
- SVGLengthContext lengthContext(this);
- return Length(heightCurrentValue().value(lengthContext), Fixed);
- }
+ if (height()->currentValue()->unitType() == LengthTypePercentage)
+ return Length(0, Fixed);
- ASSERT(renderer());
- return renderer()->style()->height();
+ SVGLengthContext lengthContext(this);
+ return Length(height()->currentValue()->value(lengthContext), Fixed);
}
AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
{
if (!m_useCurrentView || !m_viewSpec)
- return SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), preserveAspectRatioCurrentValue(), viewWidth, viewHeight);
+ return SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), preserveAspectRatio()->currentValue(), viewWidth, viewHeight);
- AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), m_viewSpec->preserveAspectRatioCurrentValue(), viewWidth, viewHeight);
- const SVGTransformList& transformList = m_viewSpec->transformBaseValue();
- if (transformList.isEmpty())
+ AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), m_viewSpec->preserveAspectRatio()->currentValue(), viewWidth, viewHeight);
+ RefPtr<SVGTransformList> transformList = m_viewSpec->transform();
+ if (transformList->isEmpty())
return ctm;
AffineTransform transform;
- if (transformList.concatenate(transform))
+ if (transformList->concatenate(transform))
ctm *= transform;
return ctm;
@@ -717,13 +728,11 @@ void SVGSVGElement::setupInitialView(const String& fragmentIdentifier, Element*
// or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor ‘svg’ element is displayed in the viewport.
// Any view specification attributes included on the given ‘view’ element override the corresponding view specification
// attributes on the closest ancestor ‘svg’ element.
- if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) {
- SVGViewElement* viewElement = toSVGViewElement(anchorNode);
- if (!viewElement)
- return;
+ if (isSVGViewElement(anchorNode)) {
+ SVGViewElement& viewElement = toSVGViewElement(*anchorNode);
- if (SVGSVGElement* svg = viewElement->ownerSVGElement()) {
- svg->inheritViewAttributes(viewElement);
+ if (SVGSVGElement* svg = viewElement.ownerSVGElement()) {
+ svg->inheritViewAttributes(&viewElement);
if (RenderObject* renderer = svg->renderer())
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
@@ -740,40 +749,42 @@ void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement)
m_useCurrentView = true;
if (viewElement->hasAttribute(SVGNames::viewBoxAttr))
- view->setViewBoxBaseValue(viewElement->viewBoxCurrentValue());
- else
- view->setViewBoxBaseValue(viewBoxCurrentValue());
-
- if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr))
- view->setPreserveAspectRatioBaseValue(viewElement->preserveAspectRatioBaseValue());
+ view->viewBox()->baseValue()->setValue(viewElement->viewBox()->currentValue()->value());
else
- view->setPreserveAspectRatioBaseValue(preserveAspectRatioBaseValue());
+ view->viewBox()->baseValue()->setValue(viewBox()->currentValue()->value());
+
+ if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr)) {
+ view->preserveAspectRatio()->baseValue()->setAlign(viewElement->preserveAspectRatio()->currentValue()->align());
+ view->preserveAspectRatio()->baseValue()->setMeetOrSlice(viewElement->preserveAspectRatio()->currentValue()->meetOrSlice());
+ } else {
+ view->preserveAspectRatio()->baseValue()->setAlign(preserveAspectRatio()->currentValue()->align());
+ view->preserveAspectRatio()->baseValue()->setMeetOrSlice(preserveAspectRatio()->currentValue()->meetOrSlice());
+ }
if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr))
- view->setZoomAndPanBaseValue(viewElement->zoomAndPan());
+ view->setZoomAndPan(viewElement->zoomAndPan());
else
- view->setZoomAndPanBaseValue(zoomAndPan());
+ view->setZoomAndPan(zoomAndPan());
}
-// getElementById on SVGSVGElement is restricted to only the child subtree defined by the <svg> element.
-// See http://www.w3.org/TR/SVG11/struct.html#InterfaceSVGSVGElement
-Element* SVGSVGElement::getElementById(const AtomicString& id) const
+void SVGSVGElement::finishParsingChildren()
{
- Element* element = treeScope().getElementById(id);
- if (element && element->isDescendantOf(this))
- return element;
+ SVGGraphicsElement::finishParsingChildren();
+
+ // The outermost SVGSVGElement SVGLoad event is fired through Document::dispatchWindowLoadEvent.
+ if (isOutermostSVGSVGElement())
+ return;
- // Fall back to traversing our subtree. Duplicate ids are allowed, the first found will
- // be returned.
- for (Node* node = firstChild(); node; node = NodeTraversal::next(*node, this)) {
- if (!node->isElementNode())
- continue;
+ // finishParsingChildren() is called when the close tag is reached for an element (e.g. </svg>)
+ // we send SVGLoad events here if we can, otherwise they'll be sent when any required loads finish
+ sendSVGLoadEventIfPossible();
+}
- Element* element = toElement(node);
- if (element->getIdAttribute() == id)
- return element;
- }
- return 0;
+void SVGSVGElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_timeContainer);
+ visitor->trace(m_viewSpec);
+ SVGGraphicsElement::trace(visitor);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.h
index 65f8c69c30e..96ef6a1357d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007, 2010 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,44 +24,35 @@
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGAnimatedRect.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGFitToViewBox.h"
#include "core/svg/SVGGraphicsElement.h"
+#include "core/svg/SVGLengthTearOff.h"
+#include "core/svg/SVGPointTearOff.h"
#include "core/svg/SVGZoomAndPan.h"
-#include "wtf/WeakPtr.h"
namespace WebCore {
-class SVGAngle;
-class SVGMatrix;
-class SVGTransform;
+class SVGMatrixTearOff;
+class SVGAngleTearOff;
+class SVGNumberTearOff;
+class SVGTransformTearOff;
class SVGViewSpec;
class SVGViewElement;
class SMILTimeContainer;
class SVGSVGElement FINAL : public SVGGraphicsElement,
- public SVGExternalResourcesRequired,
public SVGFitToViewBox,
public SVGZoomAndPan {
public:
- static PassRefPtr<SVGSVGElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGSVGElement);
+#if !ENABLE(OILPAN)
using SVGGraphicsElement::ref;
using SVGGraphicsElement::deref;
-
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
+#endif
// 'SVGSVGElement' functions
- const AtomicString& contentScriptType() const;
- void setContentScriptType(const AtomicString& type);
-
- const AtomicString& contentStyleType() const;
- void setContentStyleType(const AtomicString& type);
-
- SVGRect viewport() const;
+ PassRefPtr<SVGRectTearOff> viewport() const;
float pixelUnitToMillimeterX() const;
float pixelUnitToMillimeterY() const;
@@ -70,25 +62,17 @@ public:
bool useCurrentView() const { return m_useCurrentView; }
SVGViewSpec* currentView();
- enum ConsiderCSSMode {
- RespectCSSProperties,
- IgnoreCSSProperties
- };
-
- // RenderSVGRoot wants to query the intrinsic size, by only examining the width/height attributes.
- Length intrinsicWidth(ConsiderCSSMode = RespectCSSProperties) const;
- Length intrinsicHeight(ConsiderCSSMode = RespectCSSProperties) const;
+ Length intrinsicWidth() const;
+ Length intrinsicHeight() const;
FloatSize currentViewportSize() const;
- SVGRect currentViewBoxRect() const;
+ FloatRect currentViewBoxRect() const;
float currentScale() const;
void setCurrentScale(float scale);
- SVGPoint& currentTranslate() { return m_translation; }
+ FloatPoint currentTranslate() { return m_translation->value(); }
void setCurrentTranslate(const FloatPoint&);
-
- // Only used from the bindings.
- void updateCurrentTranslate();
+ PassRefPtr<SVGPointTearOff> currentTranslateFromJavascript();
SMILTimeContainer* timeContainer() const { return m_timeContainer.get(); }
@@ -99,93 +83,87 @@ public:
float getCurrentTime() const;
void setCurrentTime(float seconds);
- unsigned suspendRedraw(unsigned maxWaitMilliseconds);
- void unsuspendRedraw(unsigned suspendHandleId);
- void unsuspendRedrawAll();
- void forceRedraw();
+ // Stubs for the deprecated 'redraw' interface.
+ unsigned suspendRedraw(unsigned) { return 1; }
+ void unsuspendRedraw(unsigned) { }
+ void unsuspendRedrawAll() { }
+ void forceRedraw() { }
- PassRefPtr<NodeList> getIntersectionList(const SVGRect&, SVGElement* referenceElement) const;
- PassRefPtr<NodeList> getEnclosureList(const SVGRect&, SVGElement* referenceElement) const;
- bool checkIntersection(SVGElement*, const SVGRect&) const;
- bool checkEnclosure(SVGElement*, const SVGRect&) const;
+ PassRefPtrWillBeRawPtr<StaticNodeList> getIntersectionList(PassRefPtr<SVGRectTearOff>, SVGElement* referenceElement) const;
+ PassRefPtrWillBeRawPtr<StaticNodeList> getEnclosureList(PassRefPtr<SVGRectTearOff>, SVGElement* referenceElement) const;
+ bool checkIntersection(SVGElement*, PassRefPtr<SVGRectTearOff>) const;
+ bool checkEnclosure(SVGElement*, PassRefPtr<SVGRectTearOff>) const;
void deselectAll();
- static float createSVGNumber();
- static SVGLength createSVGLength();
- static SVGAngle createSVGAngle();
- static SVGPoint createSVGPoint();
- static SVGMatrix createSVGMatrix();
- static SVGRect createSVGRect();
- static SVGTransform createSVGTransform();
- static SVGTransform createSVGTransformFromMatrix(const SVGMatrix&);
+ static PassRefPtr<SVGNumberTearOff> createSVGNumber();
+ static PassRefPtr<SVGLengthTearOff> createSVGLength();
+ static PassRefPtr<SVGAngleTearOff> createSVGAngle();
+ static PassRefPtr<SVGPointTearOff> createSVGPoint();
+ static PassRefPtr<SVGMatrixTearOff> createSVGMatrix();
+ static PassRefPtr<SVGRectTearOff> createSVGRect();
+ static PassRefPtr<SVGTransformTearOff> createSVGTransform();
+ static PassRefPtr<SVGTransformTearOff> createSVGTransformFromMatrix(PassRefPtr<SVGMatrixTearOff>);
AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
void setupInitialView(const String& fragmentIdentifier, Element* anchorNode);
- Element* getElementById(const AtomicString&) const;
+ bool hasIntrinsicWidth() const;
+ bool hasIntrinsicHeight() const;
- bool widthAttributeEstablishesViewport() const;
- bool heightAttributeEstablishesViewport() const;
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
- SVGZoomAndPanType zoomAndPan() const { return m_zoomAndPan; }
- void setZoomAndPan(unsigned short zoomAndPan) { m_zoomAndPan = SVGZoomAndPan::parseFromNumber(zoomAndPan); }
-
- bool hasEmptyViewBox() const { return viewBoxCurrentValue().isValid() && viewBoxCurrentValue().isEmpty(); }
+ virtual void trace(Visitor*) OVERRIDE;
private:
explicit SVGSVGElement(Document&);
virtual ~SVGSVGElement();
- virtual bool isSVGSVGElement() const OVERRIDE { return true; }
-
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
+ virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
+ virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
void inheritViewAttributes(SVGViewElement*);
- enum CollectIntersectionOrEnclosure {
- CollectIntersectionList,
- CollectEnclosureList
+ void updateCurrentTranslate();
+
+ virtual void finishParsingChildren() OVERRIDE;
+
+ enum CheckIntersectionOrEnclosure {
+ CheckIntersection,
+ CheckEnclosure
};
- PassRefPtr<NodeList> collectIntersectionOrEnclosureList(const SVGRect&, SVGElement*, CollectIntersectionOrEnclosure) const;
+ bool checkIntersectionOrEnclosure(const SVGElement&, const FloatRect&, CheckIntersectionOrEnclosure) const;
+ PassRefPtrWillBeRawPtr<StaticNodeList> collectIntersectionOrEnclosureList(const FloatRect&, SVGElement*, CheckIntersectionOrEnclosure) const;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSVGElement)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- DECLARE_ANIMATED_RECT(ViewBox, viewBox)
- DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
- virtual AffineTransform localCoordinateSpaceTransform(SVGElement::CTMScope) const;
+ virtual AffineTransform localCoordinateSpaceTransform(SVGElement::CTMScope) const OVERRIDE;
bool m_useCurrentView;
- SVGZoomAndPanType m_zoomAndPan;
- RefPtr<SMILTimeContainer> m_timeContainer;
- SVGPoint m_translation;
- RefPtr<SVGViewSpec> m_viewSpec;
- WeakPtrFactory<SVGSVGElement> m_weakFactory;
-};
+ RefPtrWillBeMember<SMILTimeContainer> m_timeContainer;
+ RefPtr<SVGPoint> m_translation;
+ RefPtrWillBeMember<SVGViewSpec> m_viewSpec;
-inline bool isSVGSVGElement(const Node& node)
-{
- return node.isSVGElement() && toSVGElement(node).isSVGSVGElement();
-}
-
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGSVGElement);
+ friend class SVGCurrentTranslateTearOff;
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.idl
index 0edfc9a1102..093f1535f95 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSVGElement.idl
@@ -20,15 +20,18 @@
* Boston, MA 02110-1301, USA.
*/
+// http://www.w3.org/TR/SVG2/struct.html#InterfaceSVGSVGElement
+
// TODO: no css::ViewCSS available!
// TODO: no events::DocumentEvent available!
-interface SVGSVGElement : SVGGraphicsElement {
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGSVGElement : SVGGraphicsElement {
+
readonly attribute SVGAnimatedLength x;
readonly attribute SVGAnimatedLength y;
readonly attribute SVGAnimatedLength width;
readonly attribute SVGAnimatedLength height;
- attribute DOMString contentScriptType;
- attribute DOMString contentStyleType;
readonly attribute SVGRect viewport;
readonly attribute float pixelUnitToMillimeterX;
readonly attribute float pixelUnitToMillimeterY;
@@ -37,25 +40,21 @@ interface SVGSVGElement : SVGGraphicsElement {
readonly attribute boolean useCurrentView;
readonly attribute SVGViewSpec currentView;
attribute float currentScale;
- readonly attribute SVGPoint currentTranslate;
+ [ImplementedAs=currentTranslateFromJavascript] readonly attribute SVGPoint currentTranslate;
- unsigned long suspendRedraw([Default=Undefined] optional unsigned long maxWaitMilliseconds);
- void unsuspendRedraw([Default=Undefined] optional unsigned long suspendHandleId);
+ unsigned long suspendRedraw(unsigned long maxWaitMilliseconds);
+ void unsuspendRedraw(unsigned long suspendHandleId);
void unsuspendRedrawAll();
void forceRedraw();
void pauseAnimations();
void unpauseAnimations();
boolean animationsPaused();
float getCurrentTime();
- void setCurrentTime([Default=Undefined] optional float seconds);
- NodeList getIntersectionList([Default=Undefined] optional SVGRect rect,
- [Default=Undefined] optional SVGElement referenceElement);
- NodeList getEnclosureList([Default=Undefined] optional SVGRect rect,
- [Default=Undefined] optional SVGElement referenceElement);
- boolean checkIntersection([Default=Undefined] optional SVGElement element,
- [Default=Undefined] optional SVGRect rect);
- boolean checkEnclosure([Default=Undefined] optional SVGElement element,
- [Default=Undefined] optional SVGRect rect);
+ void setCurrentTime(float seconds);
+ NodeList getIntersectionList(SVGRect rect, SVGElement? referenceElement);
+ NodeList getEnclosureList(SVGRect rect, SVGElement? referenceElement);
+ boolean checkIntersection(SVGElement element, SVGRect rect);
+ boolean checkEnclosure(SVGElement element, SVGRect rect);
void deselectAll();
SVGNumber createSVGNumber();
@@ -65,11 +64,9 @@ interface SVGSVGElement : SVGGraphicsElement {
SVGMatrix createSVGMatrix();
SVGRect createSVGRect();
SVGTransform createSVGTransform();
- SVGTransform createSVGTransformFromMatrix([Default=Undefined] optional SVGMatrix matrix);
- Element getElementById([Default=Undefined] optional DOMString elementId);
+ SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix);
+ Element getElementById(DOMString elementId);
};
-SVGSVGElement implements SVGExternalResourcesRequired;
SVGSVGElement implements SVGFitToViewBox;
SVGSVGElement implements SVGZoomAndPan;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp
index 9a7040f1093..7f705c5fd92 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.cpp
@@ -22,39 +22,27 @@
#include "core/svg/SVGScriptElement.h"
-#include "HTMLNames.h"
-#include "XLinkNames.h"
#include "bindings/v8/ScriptEventListener.h"
+#include "core/HTMLNames.h"
+#include "core/XLinkNames.h"
#include "core/dom/Attribute.h"
#include "core/dom/Document.h"
#include "core/dom/ScriptLoader.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/svg/SVGElementInstance.h"
-#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_STRING(SVGScriptElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGScriptElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGScriptElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGScriptElement::SVGScriptElement(Document& document, bool wasInsertedByParser, bool alreadyStarted)
: SVGElement(SVGNames::scriptTag, document)
+ , SVGURIReference(this)
, m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired)
, m_loader(ScriptLoader::create(this, wasInsertedByParser, alreadyStarted))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGScriptElement();
}
-PassRefPtr<SVGScriptElement> SVGScriptElement::create(Document& document, bool insertedByParser)
+PassRefPtrWillBeRawPtr<SVGScriptElement> SVGScriptElement::create(Document& document, bool insertedByParser)
{
- return adoptRef(new SVGScriptElement(document, insertedByParser, false));
+ return adoptRefWillBeNoop(new SVGScriptElement(document, insertedByParser, false));
}
bool SVGScriptElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -62,7 +50,6 @@ bool SVGScriptElement::isSupportedAttribute(const QualifiedName& attrName)
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
SVGURIReference::addSupportedAttributes(supportedAttributes);
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::typeAttr);
supportedAttributes.add(HTMLNames::onerrorAttr);
}
@@ -76,22 +63,18 @@ void SVGScriptElement::parseAttribute(const QualifiedName& name, const AtomicStr
return;
}
- if (name == SVGNames::typeAttr) {
- setType(value);
+ SVGParsingError parseError = NoError;
+ if (name == SVGNames::typeAttr)
return;
- }
if (name == HTMLNames::onerrorAttr) {
- setAttributeEventListener(EventTypeNames::error, createAttributeEventListener(this, name, value));
- return;
+ setAttributeEventListener(EventTypeNames::error, createAttributeEventListener(this, name, value, eventParameterName()));
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else {
+ ASSERT_NOT_REACHED();
}
- if (SVGURIReference::parseAttribute(name, value))
- return;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
-
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -101,19 +84,16 @@ void SVGScriptElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (attrName == SVGNames::typeAttr || attrName == HTMLNames::onerrorAttr)
return;
if (SVGURIReference::isKnownAttribute(attrName)) {
- m_loader->handleSourceAttribute(hrefCurrentValue());
+ m_loader->handleSourceAttribute(hrefString());
return;
}
- if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName))
- return;
-
ASSERT_NOT_REACHED();
}
@@ -126,7 +106,11 @@ Node::InsertionNotificationRequest SVGScriptElement::insertedInto(ContainerNode*
void SVGScriptElement::didNotifySubtreeInsertionsToDocument()
{
m_loader->didNotifySubtreeInsertionsToDocument();
- SVGExternalResourcesRequired::insertedIntoDocument(this);
+
+ if (!m_loader->isParserInserted()) {
+ m_loader->setHaveFiredLoadEvent(true);
+ sendSVGLoadEventIfPossibleAsynchronously();
+ }
}
void SVGScriptElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -137,35 +121,23 @@ void SVGScriptElement::childrenChanged(bool changedByParser, Node* beforeChange,
bool SVGScriptElement::isURLAttribute(const Attribute& attribute) const
{
- return attribute.name() == sourceAttributeValue();
+ return attribute.name() == AtomicString(sourceAttributeValue());
}
void SVGScriptElement::finishParsingChildren()
{
SVGElement::finishParsingChildren();
- SVGExternalResourcesRequired::finishParsingChildren();
-}
-
-String SVGScriptElement::type() const
-{
- return m_type;
+ m_loader->setHaveFiredLoadEvent(true);
}
-void SVGScriptElement::setType(const String& type)
+bool SVGScriptElement::haveLoadedRequiredResources()
{
- m_type = type;
-}
-
-void SVGScriptElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
-{
- SVGElement::addSubresourceAttributeURLs(urls);
-
- addSubresourceURL(urls, document().completeURL(hrefCurrentValue()));
+ return m_loader->haveFiredLoadEvent();
}
String SVGScriptElement::sourceAttributeValue() const
{
- return hrefCurrentValue();
+ return hrefString();
}
String SVGScriptElement::charsetAttributeValue() const
@@ -175,7 +147,7 @@ String SVGScriptElement::charsetAttributeValue() const
String SVGScriptElement::typeAttributeValue() const
{
- return type();
+ return getAttribute(SVGNames::typeAttr).string();
}
String SVGScriptElement::languageAttributeValue() const
@@ -205,32 +177,27 @@ bool SVGScriptElement::deferAttributeValue() const
bool SVGScriptElement::hasSourceAttribute() const
{
- return hasAttribute(XLinkNames::hrefAttr);
+ return href()->isSpecified();
}
-PassRefPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren()
+PassRefPtrWillBeRawPtr<Element> SVGScriptElement::cloneElementWithoutAttributesAndChildren()
{
- return adoptRef(new SVGScriptElement(document(), false, m_loader->alreadyStarted()));
+ return adoptRefWillBeNoop(new SVGScriptElement(document(), false, m_loader->alreadyStarted()));
}
-void SVGScriptElement::setHaveFiredLoadEvent(bool haveFiredLoadEvent)
+void SVGScriptElement::dispatchLoadEvent()
{
- m_loader->setHaveFiredLoadEvent(haveFiredLoadEvent);
+ dispatchEvent(Event::create(EventTypeNames::load));
}
-bool SVGScriptElement::isParserInserted() const
+#ifndef NDEBUG
+bool SVGScriptElement::isAnimatableAttribute(const QualifiedName& name) const
{
- return m_loader->isParserInserted();
-}
-
-bool SVGScriptElement::haveFiredLoadEvent() const
-{
- return m_loader->haveFiredLoadEvent();
-}
+ if (name == SVGNames::typeAttr)
+ return false;
-Timer<SVGElement>* SVGScriptElement::svgLoadEventTimer()
-{
- return &m_svgLoadEventTimer;
+ return SVGElement::isAnimatableAttribute(name);
}
+#endif
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.h
index ec59d85ad68..b9af685b285 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.h
@@ -21,12 +21,11 @@
#ifndef SVGScriptElement_h
#define SVGScriptElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/dom/ScriptLoaderClient.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedString.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGURIReference.h"
namespace WebCore {
@@ -36,16 +35,16 @@ class ScriptLoader;
class SVGScriptElement FINAL
: public SVGElement
, public SVGURIReference
- , public SVGExternalResourcesRequired
, public ScriptLoaderClient {
public:
- static PassRefPtr<SVGScriptElement> create(Document&, bool wasInsertedByParser);
-
- String type() const;
- void setType(const String&);
+ static PassRefPtrWillBeRawPtr<SVGScriptElement> create(Document&, bool wasInsertedByParser);
ScriptLoader* loader() const { return m_loader.get(); }
+#ifndef NDEBUG
+ virtual bool isAnimatableAttribute(const QualifiedName&) const OVERRIDE;
+#endif
+
private:
SVGScriptElement(Document&, bool wasInsertedByParser, bool alreadyStarted);
@@ -53,49 +52,37 @@ private:
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
- virtual void finishParsingChildren();
+ virtual bool isStructurallyExternal() const OVERRIDE { return hasSourceAttribute(); }
+ virtual void finishParsingChildren() OVERRIDE;
- virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
+ virtual bool haveLoadedRequiredResources() OVERRIDE;
- virtual bool haveLoadedRequiredResources() { return SVGExternalResourcesRequired::haveLoadedRequiredResources(); }
+ virtual String sourceAttributeValue() const OVERRIDE;
+ virtual String charsetAttributeValue() const OVERRIDE;
+ virtual String typeAttributeValue() const OVERRIDE;
+ virtual String languageAttributeValue() const OVERRIDE;
+ virtual String forAttributeValue() const OVERRIDE;
+ virtual String eventAttributeValue() const OVERRIDE;
+ virtual bool asyncAttributeValue() const OVERRIDE;
+ virtual bool deferAttributeValue() const OVERRIDE;
+ virtual bool hasSourceAttribute() const OVERRIDE;
- virtual String sourceAttributeValue() const;
- virtual String charsetAttributeValue() const;
- virtual String typeAttributeValue() const;
- virtual String languageAttributeValue() const;
- virtual String forAttributeValue() const;
- virtual String eventAttributeValue() const;
- virtual bool asyncAttributeValue() const;
- virtual bool deferAttributeValue() const;
- virtual bool hasSourceAttribute() const;
+ virtual void dispatchLoadEvent() OVERRIDE;
- virtual void dispatchLoadEvent() { SVGExternalResourcesRequired::dispatchLoadEvent(this); }
-
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren();
+ virtual PassRefPtrWillBeRawPtr<Element> cloneElementWithoutAttributesAndChildren() OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
- // SVGExternalResourcesRequired
- virtual void setHaveFiredLoadEvent(bool) OVERRIDE;
- virtual bool isParserInserted() const OVERRIDE;
- virtual bool haveFiredLoadEvent() const OVERRIDE;
- virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE;
+ virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE { return &m_svgLoadEventTimer; }
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGScriptElement)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
- String m_type;
Timer<SVGElement> m_svgLoadEventTimer;
OwnPtr<ScriptLoader> m_loader;
};
-DEFINE_NODE_TYPE_CASTS(SVGScriptElement, hasTagName(SVGNames::scriptTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.idl
index abaa80b03f1..08c871f91d8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGScriptElement.idl
@@ -24,9 +24,7 @@
*/
interface SVGScriptElement : SVGElement {
- [TreatNullAs=NullString] attribute DOMString type;
+ [Reflect] attribute DOMString type;
};
-SVGScriptElement implements SVGExternalResourcesRequired;
SVGScriptElement implements SVGURIReference;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSetElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGSetElement.cpp
index da8334b751c..a94ce4ecd8c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSetElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSetElement.cpp
@@ -19,9 +19,10 @@
*/
#include "config.h"
-#include "SVGNames.h"
#include "core/svg/SVGSetElement.h"
+#include "core/SVGNames.h"
+
namespace WebCore {
inline SVGSetElement::SVGSetElement(Document& document)
@@ -31,10 +32,7 @@ inline SVGSetElement::SVGSetElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGSetElement> SVGSetElement::create(Document& document)
-{
- return adoptRef(new SVGSetElement(document));
-}
+DEFINE_NODE_FACTORY(SVGSetElement)
void SVGSetElement::updateAnimationMode()
{
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSetElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGSetElement.h
index a2cd048c003..c60104f4b56 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSetElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSetElement.h
@@ -28,7 +28,7 @@ namespace WebCore {
// SVGAnimateElement implements superset of the functionality.
class SVGSetElement FINAL : public SVGAnimateElement {
public:
- static PassRefPtr<SVGSetElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGSetElement);
private:
explicit SVGSetElement(Document&);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStaticStringList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGStaticStringList.cpp
new file mode 100644
index 00000000000..36b1684cf71
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStaticStringList.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGStaticStringList.h"
+
+namespace WebCore {
+
+SVGStaticStringList::SVGStaticStringList(SVGElement* contextElement, const QualifiedName& attributeName)
+ : SVGAnimatedPropertyBase(AnimatedStringList, contextElement, attributeName)
+ , m_value(SVGStringList::create())
+{
+ ASSERT(contextElement);
+}
+
+SVGStaticStringList::~SVGStaticStringList()
+{
+}
+
+SVGPropertyBase* SVGStaticStringList::currentValueBase()
+{
+ return m_value.get();
+}
+
+bool SVGStaticStringList::isAnimating() const
+{
+ return false;
+}
+
+PassRefPtr<SVGPropertyBase> SVGStaticStringList::createAnimatedValue()
+{
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+void SVGStaticStringList::setAnimatedValue(PassRefPtr<SVGPropertyBase>)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void SVGStaticStringList::animationEnded()
+{
+ ASSERT_NOT_REACHED();
+}
+
+bool SVGStaticStringList::needsSynchronizeAttribute()
+{
+ return m_tearOff;
+}
+
+SVGStringListTearOff* SVGStaticStringList::tearOff()
+{
+ if (!m_tearOff)
+ m_tearOff = SVGStringListTearOff::create(m_value, contextElement(), PropertyIsNotAnimVal, attributeName());
+
+ return m_tearOff.get();
+}
+
+void SVGStaticStringList::setBaseValueAsString(const String& value, SVGParsingError& parseError)
+{
+ TrackExceptionState es;
+
+ m_value->setValueAsString(value, es);
+
+ if (es.hadException())
+ parseError = ParsingAttributeFailedError;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStaticStringList.h b/chromium/third_party/WebKit/Source/core/svg/SVGStaticStringList.h
new file mode 100644
index 00000000000..809a017cb83
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStaticStringList.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGStaticStringList_h
+#define SVGStaticStringList_h
+
+#include "core/svg/SVGStringListTearOff.h"
+#include "core/svg/properties/SVGAnimatedProperty.h"
+
+namespace WebCore {
+
+class SVGElement;
+
+// SVGStringList property implementations for SVGTests properties.
+// Inherits SVGAnimatedPropertyBase to enable XML attribute synchronization, but this is never animated.
+class SVGStaticStringList FINAL : public SVGAnimatedPropertyBase {
+public:
+ static PassRefPtr<SVGStaticStringList> create(SVGElement* contextElement, const QualifiedName& attributeName)
+ {
+ return adoptRef(new SVGStaticStringList(contextElement, attributeName));
+ }
+
+ virtual ~SVGStaticStringList();
+
+ // SVGAnimatedPropertyBase:
+ virtual SVGPropertyBase* currentValueBase() OVERRIDE;
+ virtual bool isAnimating() const OVERRIDE;
+ virtual PassRefPtr<SVGPropertyBase> createAnimatedValue() OVERRIDE;
+ virtual void setAnimatedValue(PassRefPtr<SVGPropertyBase>) OVERRIDE;
+ virtual void animationEnded() OVERRIDE;
+ virtual bool needsSynchronizeAttribute() OVERRIDE;
+
+ void setBaseValueAsString(const String& value, SVGParsingError& parseError);
+
+ SVGStringList* value() { return m_value.get(); }
+ SVGStringListTearOff* tearOff();
+
+private:
+ SVGStaticStringList(SVGElement*, const QualifiedName&);
+
+ RefPtr<SVGStringList> m_value;
+ RefPtr<SVGStringListTearOff> m_tearOff;
+};
+
+}
+
+#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStopElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGStopElement.cpp
index b3d85099a44..158ba3f1024 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGStopElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStopElement.cpp
@@ -24,31 +24,20 @@
#include "core/rendering/svg/RenderSVGGradientStop.h"
#include "core/rendering/svg/RenderSVGResource.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_NUMBER(SVGStopElement, SVGNames::offsetAttr, Offset, offset)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGStopElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(offset)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGStopElement::SVGStopElement(Document& document)
: SVGElement(SVGNames::stopTag, document)
- , m_offset(0)
+ , m_offset(SVGAnimatedNumber::create(this, SVGNames::offsetAttr, SVGNumberAcceptPercentage::create()))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGStopElement();
-}
-PassRefPtr<SVGStopElement> SVGStopElement::create(Document& document)
-{
- return adoptRef(new SVGStopElement(document));
+ addToPropertyMap(m_offset);
}
+DEFINE_NODE_FACTORY(SVGStopElement)
+
bool SVGStopElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
@@ -64,15 +53,14 @@ void SVGStopElement::parseAttribute(const QualifiedName& name, const AtomicStrin
return;
}
- if (name == SVGNames::offsetAttr) {
- if (value.endsWith('%'))
- setOffsetBaseValue(value.string().left(value.length() - 1).toFloat() / 100.0f);
- else
- setOffsetBaseValue(value.toFloat());
- return;
- }
+ SVGParsingError parseError = NoError;
- ASSERT_NOT_REACHED();
+ if (name == SVGNames::offsetAttr)
+ m_offset->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
void SVGStopElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -82,7 +70,7 @@ void SVGStopElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (!renderer())
return;
@@ -112,10 +100,10 @@ Color SVGStopElement::stopColorIncludingOpacity() const
// which the renderer or style is null. This entire class is scheduled for removal (Bug WK 86941)
// and we will tolerate this null check until then.
if (!style || !style->svgStyle())
- return Color(Color::transparent, true); // Transparent black.
+ return Color(Color::transparent); // Transparent black.
const SVGRenderStyle* svgStyle = style->svgStyle();
- return colorWithOverrideAlpha(svgStyle->stopColor().rgb(), svgStyle->stopOpacity());
+ return svgStyle->stopColor().combineWithAlpha(svgStyle->stopOpacity());
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStopElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGStopElement.h
index 6b941f2e503..38081ec360f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGStopElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStopElement.h
@@ -21,7 +21,7 @@
#ifndef SVGStopElement_h
#define SVGStopElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedNumber.h"
#include "core/svg/SVGElement.h"
@@ -29,34 +29,25 @@ namespace WebCore {
class SVGStopElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGStopElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGStopElement);
Color stopColorIncludingOpacity() const;
+ SVGAnimatedNumber* offset() { return m_offset.get(); }
+
private:
explicit SVGStopElement(Document&);
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
-
- virtual bool isGradientStop() const OVERRIDE { return true; }
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGStopElement)
- DECLARE_ANIMATED_NUMBER(Offset, offset)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedNumber> m_offset;
};
-inline bool isSVGStopElement(const Node& node)
-{
- return node.isSVGElement() && toSVGElement(node).isGradientStop();
-}
-
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGStopElement);
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGString.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGString.cpp
new file mode 100644
index 00000000000..be9aae97668
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGString.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/svg/SVGString.h"
+
+#include "core/svg/SVGAnimateElement.h"
+
+namespace WebCore {
+
+void SVGString::add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*)
+{
+ ASSERT_NOT_REACHED();
+}
+
+void SVGString::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ ASSERT(animationElement);
+
+ String fromString = toSVGString(from)->m_value;
+ String toString = toSVGString(to)->m_value;
+
+ animationElement->animateDiscreteType<String>(percentage, fromString, toString, m_value);
+}
+
+float SVGString::calculateDistance(PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ // No paced animations for strings.
+ return -1;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGString.h b/chromium/third_party/WebKit/Source/core/svg/SVGString.h
new file mode 100644
index 00000000000..ddf6d4605ef
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGString.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGString_h
+#define SVGString_h
+
+#include "core/svg/properties/SVGProperty.h"
+
+namespace WebCore {
+
+class SVGString : public SVGPropertyBase {
+public:
+ // SVGString does not have a tear-off type.
+ typedef void TearOffType;
+ typedef String PrimitiveType;
+
+ static PassRefPtr<SVGString> create()
+ {
+ return adoptRef(new SVGString());
+ }
+
+ static PassRefPtr<SVGString> create(const String& value)
+ {
+ return adoptRef(new SVGString(value));
+ }
+
+ PassRefPtr<SVGString> clone() const { return create(m_value); }
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String& value) const OVERRIDE
+ {
+ return create(value);
+ }
+
+ virtual String valueAsString() const OVERRIDE { return m_value; }
+ void setValueAsString(const String& value, ExceptionState&) { m_value = value; }
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ const String& value() const { return m_value; }
+ void setValue(const String& value) { m_value = value; }
+
+ static AnimatedPropertyType classType() { return AnimatedString; }
+
+private:
+ SVGString()
+ : SVGPropertyBase(classType())
+ {
+ }
+
+ explicit SVGString(const String& value)
+ : SVGPropertyBase(classType())
+ , m_value(value)
+ {
+ }
+
+ String m_value;
+};
+
+inline PassRefPtr<SVGString> toSVGString(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGString::classType());
+ return static_pointer_cast<SVGString>(base.release());
+}
+
+} // namespace WebCore
+
+#endif // SVGString_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStringList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGStringList.cpp
index c8ff9dfa40c..216cd2b4fa2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGStringList.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStringList.cpp
@@ -27,66 +27,158 @@
namespace WebCore {
-void SVGStringList::commitChange(SVGElement* contextElement)
+SVGStringList::SVGStringList()
+ : SVGPropertyBase(classType())
{
- ASSERT(contextElement);
- contextElement->invalidateSVGAttributes();
- contextElement->svgAttributeChanged(m_attributeName);
}
-void SVGStringList::reset(const String& string)
+SVGStringList::~SVGStringList()
{
- parse(string, ' ');
+}
+
+void SVGStringList::initialize(const String& item)
+{
+ m_values.clear();
+ m_values.append(item);
+}
+
+String SVGStringList::getItem(size_t index, ExceptionState& exceptionState)
+{
+ if (!checkIndexBound(index, exceptionState))
+ return String();
- // Add empty string, if list is empty.
- if (isEmpty())
- append(emptyString());
+ return m_values.at(index);
+}
+
+void SVGStringList::insertItemBefore(const String& newItem, size_t index)
+{
+ // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
+ if (index > m_values.size())
+ index = m_values.size();
+
+ // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be
+ // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list.
+ m_values.insert(index, newItem);
+}
+
+String SVGStringList::removeItem(size_t index, ExceptionState& exceptionState)
+{
+ if (!checkIndexBound(index, exceptionState))
+ return String();
+
+ String oldItem = m_values.at(index);
+ m_values.remove(index);
+ return oldItem;
+}
+
+void SVGStringList::appendItem(const String& newItem)
+{
+ m_values.append(newItem);
+}
+
+void SVGStringList::replaceItem(const String& newItem, size_t index, ExceptionState& exceptionState)
+{
+ if (!checkIndexBound(index, exceptionState))
+ return;
+
+ // Update the value at the desired position 'index'.
+ m_values[index] = newItem;
}
template<typename CharType>
-void SVGStringList::parseInternal(const CharType*& ptr, const CharType* end, UChar delimiter)
+void SVGStringList::parseInternal(const CharType*& ptr, const CharType* end)
{
+ const UChar delimiter = ' ';
+
while (ptr < end) {
const CharType* start = ptr;
- while (ptr < end && *ptr != delimiter && !isSVGSpace(*ptr))
+ while (ptr < end && *ptr != delimiter && !isHTMLSpace<CharType>(*ptr))
ptr++;
if (ptr == start)
break;
- append(String(start, ptr - start));
+ m_values.append(String(start, ptr - start));
skipOptionalSVGSpacesOrDelimiter(ptr, end, delimiter);
}
}
-void SVGStringList::parse(const String& data, UChar delimiter)
+PassRefPtr<SVGStringList> SVGStringList::clone()
+{
+ RefPtr<SVGStringList> svgStringList = create();
+ svgStringList->m_values = m_values;
+ return svgStringList.release();
+}
+
+void SVGStringList::setValueAsString(const String& data, ExceptionState&)
{
// FIXME: Add more error checking and reporting.
- clear();
+ m_values.clear();
if (data.isEmpty())
return;
if (data.is8Bit()) {
const LChar* ptr = data.characters8();
const LChar* end = ptr + data.length();
- parseInternal(ptr, end, delimiter);
+ parseInternal(ptr, end);
} else {
const UChar* ptr = data.characters16();
const UChar* end = ptr + data.length();
- parseInternal(ptr, end, delimiter);
+ parseInternal(ptr, end);
}
}
+PassRefPtr<SVGPropertyBase> SVGStringList::cloneForAnimation(const String& string) const
+{
+ RefPtr<SVGStringList> svgStringList = create();
+ svgStringList->setValueAsString(string, IGNORE_EXCEPTION);
+ return svgStringList.release();
+}
+
String SVGStringList::valueAsString() const
{
StringBuilder builder;
- unsigned size = this->size();
- for (unsigned i = 0; i < size; ++i) {
- if (i > 0)
- builder.append(' ');
+ Vector<String>::const_iterator it = m_values.begin();
+ Vector<String>::const_iterator itEnd = m_values.end();
+ if (it != itEnd) {
+ builder.append(*it);
+ ++it;
- builder.append(at(i));
+ for (; it != itEnd; ++it) {
+ builder.append(' ');
+ builder.append(*it);
+ }
}
return builder.toString();
}
+bool SVGStringList::checkIndexBound(size_t index, ExceptionState& exceptionState)
+{
+ if (index >= m_values.size()) {
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, m_values.size()));
+ return false;
+ }
+
+ return true;
+}
+
+void SVGStringList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement* contextElement)
+{
+ // SVGStringList is never animated.
+ ASSERT_NOT_REACHED();
+}
+
+void SVGStringList::calculateAnimatedValue(SVGAnimationElement*, float, unsigned, PassRefPtr<SVGPropertyBase>, PassRefPtr<SVGPropertyBase>, PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ // SVGStringList is never animated.
+ ASSERT_NOT_REACHED();
+}
+
+float SVGStringList::calculateDistance(PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ // SVGStringList is never animated.
+ ASSERT_NOT_REACHED();
+
+ return -1.0f;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStringList.h b/chromium/third_party/WebKit/Source/core/svg/SVGStringList.h
index 53e398e7558..153480cd1e0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGStringList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStringList.h
@@ -1,61 +1,100 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGStringList_h
#define SVGStringList_h
-#include "core/dom/QualifiedName.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/Vector.h"
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGString.h"
+#include "core/svg/properties/SVGListPropertyHelper.h"
namespace WebCore {
-class SVGElement;
+class SVGStringListTearOff;
-class SVGStringList : public Vector<String> {
+// Implementation of SVGStringList spec:
+// http://www.w3.org/TR/SVG/single-page.html#types-InterfaceSVGStringList
+// See SVGStringListTearOff for actual Javascript interface.
+// Unlike other SVG*List implementations, SVGStringList is NOT tied to SVGString.
+// SVGStringList operates directly on DOMString.
+//
+// In short:
+// SVGStringList has_a Vector<String>.
+// SVGStringList items are exposed to Javascript as DOMString (not SVGString) as in the spec.
+// SVGString is used only for boxing values for non-list string property SVGAnimatedString,
+// and not used for SVGStringList.
+class SVGStringList FINAL : public SVGPropertyBase {
public:
- SVGStringList(const QualifiedName& attributeName)
- : m_attributeName(attributeName)
+ typedef SVGStringListTearOff TearOffType;
+
+ static PassRefPtr<SVGStringList> create()
{
+ return adoptRef(new SVGStringList());
}
- void reset(const String&);
- void parse(const String&, UChar delimiter = ',');
+ virtual ~SVGStringList();
+
+ const Vector<String>& values() const { return m_values; }
+
+ // SVGStringList DOM Spec implementation. These are only to be called from SVGStringListTearOff:
+ unsigned long length() { return m_values.size(); }
+ void clear() { m_values.clear(); }
+ void initialize(const String&);
+ String getItem(size_t, ExceptionState&);
+ void insertItemBefore(const String&, size_t);
+ String removeItem(size_t, ExceptionState&);
+ void appendItem(const String&);
+ void replaceItem(const String&, size_t, ExceptionState&);
- // Only used by SVGStringListPropertyTearOff.
- void commitChange(SVGElement* contextElement);
+ // SVGPropertyBase:
+ PassRefPtr<SVGStringList> clone();
+ void setValueAsString(const String&, ExceptionState&);
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+ virtual String valueAsString() const OVERRIDE;
- String valueAsString() const;
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedStringList; }
private:
- template<typename CharType>
- void parseInternal(const CharType*& ptr, const CharType* end, UChar delimiter);
+ SVGStringList();
- const QualifiedName& m_attributeName;
-};
+ template <typename CharType>
+ void parseInternal(const CharType*& ptr, const CharType* end);
+ bool checkIndexBound(size_t, ExceptionState&);
-template<>
-struct SVGPropertyTraits<SVGStringList> {
- typedef String ListItemType;
+ Vector<String> m_values;
};
} // namespace WebCore
-#endif
+#endif // SVGStringList_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStringList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGStringList.idl
index 020b754e9b2..870ba4c2645 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGStringList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStringList.idl
@@ -23,15 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGStringList {
- readonly attribute unsigned long numberOfItems;
+[
+ TypeChecking=Interface|Nullable,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ ImplementedAs=SVGStringListTearOff
+] interface SVGStringList {
+ readonly attribute unsigned long length;
+ [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
[RaisesException] void clear();
- [StrictTypeChecking, RaisesException] DOMString initialize(DOMString item);
- [StrictTypeChecking, RaisesException] DOMString getItem(unsigned long index);
- [StrictTypeChecking, RaisesException] DOMString insertItemBefore(DOMString item, unsigned long index);
- [StrictTypeChecking, RaisesException] DOMString replaceItem(DOMString item, unsigned long index);
- [StrictTypeChecking, RaisesException] DOMString removeItem(unsigned long index);
- [StrictTypeChecking, RaisesException] DOMString appendItem(DOMString item);
+ [RaisesException] DOMString initialize(DOMString item);
+ [RaisesException] getter DOMString getItem(unsigned long index);
+ [RaisesException] setter DOMString (unsigned long index, DOMString value);
+ [RaisesException] DOMString insertItemBefore(DOMString item, unsigned long index);
+ [RaisesException] DOMString replaceItem(DOMString item, unsigned long index);
+ [RaisesException] DOMString removeItem(unsigned long index);
+ [RaisesException] DOMString appendItem(DOMString item);
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStringListTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGStringListTearOff.cpp
new file mode 100644
index 00000000000..799dae72e6b
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStringListTearOff.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGStringListTearOff.h"
+
+namespace WebCore {
+
+SVGStringListTearOff::SVGStringListTearOff(PassRefPtr<SVGStringList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ : SVGPropertyTearOff<SVGStringList>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStringListTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGStringListTearOff.h
new file mode 100644
index 00000000000..c012d3d4921
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStringListTearOff.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGStringListTearOff_h
+#define SVGStringListTearOff_h
+
+#include "core/svg/SVGStringList.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGStringListTearOff : public SVGPropertyTearOff<SVGStringList>, public ScriptWrappable {
+public:
+ static PassRefPtr<SVGStringListTearOff> create(PassRefPtr<SVGStringList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGStringListTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ // SVGStringList DOM interface:
+
+ // WebIDL requires "unsigned long" type instead of size_t.
+ unsigned long length()
+ {
+ return target()->length();
+ }
+
+ void clear(ExceptionState& exceptionState)
+ {
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return;
+ }
+
+ target()->clear();
+ commitChange();
+ }
+
+ String initialize(const String& item, ExceptionState& exceptionState)
+ {
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return String();
+ }
+
+ target()->initialize(item);
+ commitChange();
+
+ return item;
+ }
+
+ String getItem(unsigned long index, ExceptionState& exceptionState)
+ {
+ return target()->getItem(index, exceptionState);
+ }
+
+ String insertItemBefore(const String& item, unsigned long index, ExceptionState& exceptionState)
+ {
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return String();
+ }
+
+ target()->insertItemBefore(item, index);
+ commitChange();
+
+ return item;
+ }
+
+ String replaceItem(const String& item, unsigned long index, ExceptionState& exceptionState)
+ {
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return String();
+ }
+
+ target()->replaceItem(item, index, exceptionState);
+ commitChange();
+
+ return item;
+ }
+
+ bool anonymousIndexedSetter(unsigned index, const String& item, ExceptionState& exceptionState)
+ {
+ replaceItem(item, index, exceptionState);
+ return true;
+ }
+
+ String removeItem(unsigned long index, ExceptionState& exceptionState)
+ {
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return String();
+ }
+
+ String removedItem = target()->removeItem(index, exceptionState);
+ commitChange();
+
+ return removedItem;
+ }
+
+ String appendItem(const String& item, ExceptionState& exceptionState)
+ {
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return String();
+ }
+
+ target()->appendItem(item);
+ commitChange();
+
+ return item;
+ }
+
+protected:
+ SVGStringListTearOff(PassRefPtr<SVGStringList>, SVGElement*, PropertyIsAnimValType, const QualifiedName&);
+};
+
+} // namespace WebCore
+
+#endif // SVGStringListTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp
index f0815b4daeb..9f06ee2f31b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.cpp
@@ -38,12 +38,14 @@ inline SVGStyleElement::SVGStyleElement(Document& document, bool createdByParser
SVGStyleElement::~SVGStyleElement()
{
+#if !ENABLE(OILPAN)
StyleElement::clearDocumentData(document(), this);
+#endif
}
-PassRefPtr<SVGStyleElement> SVGStyleElement::create(Document& document, bool createdByParser)
+PassRefPtrWillBeRawPtr<SVGStyleElement> SVGStyleElement::create(Document& document, bool createdByParser)
{
- return adoptRef(new SVGStyleElement(document, createdByParser));
+ return adoptRefWillBeNoop(new SVGStyleElement(document, createdByParser));
}
bool SVGStyleElement::disabled() const
@@ -148,4 +150,10 @@ void SVGStyleElement::childrenChanged(bool changedByParser, Node* beforeChange,
StyleElement::childrenChanged(this);
}
+void SVGStyleElement::trace(Visitor* visitor)
+{
+ StyleElement::trace(visitor);
+ SVGElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.h
index 522f0af3dff..da429f452ac 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGStyleElement.h
@@ -21,7 +21,7 @@
#ifndef SVGStyleElement_h
#define SVGStyleElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/dom/StyleElement.h"
#include "core/svg/SVGElement.h"
@@ -29,8 +29,9 @@ namespace WebCore {
class SVGStyleElement FINAL : public SVGElement
, public StyleElement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(SVGStyleElement);
public:
- static PassRefPtr<SVGStyleElement> create(Document&, bool createdByParser);
+ static PassRefPtrWillBeRawPtr<SVGStyleElement> create(Document&, bool createdByParser);
virtual ~SVGStyleElement();
using StyleElement::sheet;
@@ -38,15 +39,17 @@ public:
bool disabled() const;
void setDisabled(bool);
- virtual const AtomicString& type() const;
+ virtual const AtomicString& type() const OVERRIDE;
void setType(const AtomicString&);
- virtual const AtomicString& media() const;
+ virtual const AtomicString& media() const OVERRIDE;
void setMedia(const AtomicString&);
- virtual String title() const;
+ virtual String title() const OVERRIDE;
void setTitle(const AtomicString&);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
SVGStyleElement(Document&, bool createdByParser);
@@ -55,21 +58,18 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void didNotifySubtreeInsertionsToDocument() OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual void finishParsingChildren();
+ virtual void finishParsingChildren() OVERRIDE;
virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
- virtual bool isLoading() const { return StyleElement::isLoading(); }
- virtual bool sheetLoaded() { return StyleElement::sheetLoaded(document()); }
- virtual void startLoadingDynamicSheet() { StyleElement::startLoadingDynamicSheet(document()); }
+ virtual bool sheetLoaded() OVERRIDE { return StyleElement::sheetLoaded(document()); }
+ virtual void startLoadingDynamicSheet() OVERRIDE { StyleElement::startLoadingDynamicSheet(document()); }
virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE { return &m_svgLoadEventTimer; }
Timer<SVGElement> m_svgLoadEventTimer;
};
-DEFINE_NODE_TYPE_CASTS(SVGStyleElement, hasTagName(SVGNames::styleTag));
-
} // namespace WebCore
#endif // SVGStyleElement_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.cpp
index f4c8dd11e1a..900cef51ddf 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.cpp
@@ -22,53 +22,21 @@
#include "core/svg/SVGSwitchElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/frame/UseCounter.h"
#include "core/rendering/svg/RenderSVGTransformableContainer.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_BOOLEAN(SVGSwitchElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGSwitchElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGSwitchElement::SVGSwitchElement(Document& document)
: SVGGraphicsElement(SVGNames::switchTag, document)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGSwitchElement();
UseCounter::count(document, UseCounter::SVGSwitchElement);
}
-PassRefPtr<SVGSwitchElement> SVGSwitchElement::create(Document& document)
-{
- return adoptRef(new SVGSwitchElement(document));
-}
-
-bool SVGSwitchElement::childShouldCreateRenderer(const Node& child) const
-{
- // FIXME: This function does not do what the comment below implies it does.
- // It will create a renderer for any valid SVG element children, not just the first one.
- bool shouldCreateRenderer = false;
- for (Node* node = firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement())
- continue;
-
- SVGElement* element = toSVGElement(node);
- if (!element || !element->isValid())
- continue;
-
- shouldCreateRenderer = node == &child; // Only allow this child if it's the first valid child.
- break;
- }
-
- return shouldCreateRenderer && SVGGraphicsElement::childShouldCreateRenderer(child);
-}
+DEFINE_NODE_FACTORY(SVGSwitchElement)
RenderObject* SVGSwitchElement::createRenderer(RenderStyle*)
{
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.h
index 48312ea530b..adb7281ee68 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.h
@@ -22,29 +22,19 @@
#define SVGSwitchElement_h
#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
namespace WebCore {
-class SVGSwitchElement FINAL : public SVGGraphicsElement,
- public SVGExternalResourcesRequired {
+class SVGSwitchElement FINAL : public SVGGraphicsElement {
public:
- static PassRefPtr<SVGSwitchElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGSwitchElement);
private:
explicit SVGSwitchElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
- virtual bool childShouldCreateRenderer(const Node& child) const;
-
- virtual RenderObject* createRenderer(RenderStyle*);
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSwitchElement)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.idl
index 619855a4a69..28d43b6f400 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSwitchElement.idl
@@ -25,6 +25,3 @@
interface SVGSwitchElement : SVGGraphicsElement {
};
-
-SVGSwitchElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.cpp
index b9a405ad027..8b534182b55 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.cpp
@@ -22,43 +22,26 @@
#include "core/svg/SVGSymbolElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/svg/RenderSVGHiddenContainer.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_BOOLEAN(SVGSymbolElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGSymbolElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
-DEFINE_ANIMATED_RECT(SVGSymbolElement, SVGNames::viewBoxAttr, ViewBox, viewBox)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGSymbolElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_LOCAL_ANIMATED_PROPERTY(viewBox)
- REGISTER_LOCAL_ANIMATED_PROPERTY(preserveAspectRatio)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGSymbolElement::SVGSymbolElement(Document& document)
: SVGElement(SVGNames::symbolTag, document)
+ , SVGFitToViewBox(this)
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGSymbolElement();
}
-PassRefPtr<SVGSymbolElement> SVGSymbolElement::create(Document& document)
-{
- return adoptRef(new SVGSymbolElement(document));
-}
+DEFINE_NODE_FACTORY(SVGSymbolElement)
bool SVGSymbolElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
- if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
+ if (supportedAttributes.isEmpty())
SVGFitToViewBox::addSupportedAttributes(supportedAttributes);
- }
+
return supportedAttributes.contains<SVGAttributeHashTranslator>(attrName);
}
@@ -69,12 +52,13 @@ void SVGSymbolElement::parseAttribute(const QualifiedName& name, const AtomicStr
return;
}
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
- if (SVGFitToViewBox::parseAttribute(this, name, value))
- return;
+ SVGParsingError parseError = NoError;
+ if (SVGFitToViewBox::parseAttribute(name, value, document(), parseError)) {
+ } else {
+ ASSERT_NOT_REACHED();
+ }
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
void SVGSymbolElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -84,16 +68,7 @@ void SVGSymbolElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
-
- // Every other property change is ignored.
- if (attrName == SVGNames::viewBoxAttr)
- updateRelativeLengthsInformation();
-}
-
-bool SVGSymbolElement::selfHasRelativeLengths() const
-{
- return hasAttribute(SVGNames::viewBoxAttr);
+ invalidateInstances();
}
RenderObject* SVGSymbolElement::createRenderer(RenderStyle*)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.h
index d65a0da0f26..6799f5728c9 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.h
@@ -22,38 +22,24 @@
#define SVGSymbolElement_h
#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGAnimatedRect.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGFitToViewBox.h"
namespace WebCore {
class SVGSymbolElement FINAL : public SVGElement,
- public SVGExternalResourcesRequired,
public SVGFitToViewBox {
public:
- static PassRefPtr<SVGSymbolElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGSymbolElement);
private:
explicit SVGSymbolElement(Document&);
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
-
- virtual RenderObject* createRenderer(RenderStyle*);
-
- virtual bool selfHasRelativeLengths() const;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSymbolElement)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- DECLARE_ANIMATED_RECT(ViewBox, viewBox)
- DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.idl
index aeb7d808703..9a5b3514660 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGSymbolElement.idl
@@ -23,8 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG2/struct.html#InterfaceSVGSymbolElement
+
interface SVGSymbolElement : SVGElement {
};
-SVGSymbolElement implements SVGExternalResourcesRequired;
SVGSymbolElement implements SVGFitToViewBox;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.cpp
index 77f13fcb23f..080ca5a66f7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.cpp
@@ -22,7 +22,7 @@
#include "core/svg/SVGTSpanElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/svg/RenderSVGTSpan.h"
namespace WebCore {
@@ -33,39 +33,23 @@ inline SVGTSpanElement::SVGTSpanElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGTSpanElement> SVGTSpanElement::create(Document& document)
-{
- return adoptRef(new SVGTSpanElement(document));
-}
+DEFINE_NODE_FACTORY(SVGTSpanElement)
RenderObject* SVGTSpanElement::createRenderer(RenderStyle*)
{
return new RenderSVGTSpan(this);
}
-bool SVGTSpanElement::childShouldCreateRenderer(const Node& child) const
-{
- if (child.isTextNode()
- || child.hasTagName(SVGNames::aTag)
-#if ENABLE(SVG_FONTS)
- || child.hasTagName(SVGNames::altGlyphTag)
-#endif
- || child.hasTagName(SVGNames::tspanTag))
- return true;
-
- return false;
-}
-
bool SVGTSpanElement::rendererIsNeeded(const RenderStyle& style)
{
if (parentNode()
- && (parentNode()->hasTagName(SVGNames::aTag)
+ && (isSVGAElement(*parentNode())
#if ENABLE(SVG_FONTS)
- || parentNode()->hasTagName(SVGNames::altGlyphTag)
+ || isSVGAltGlyphElement(*parentNode())
#endif
- || parentNode()->hasTagName(SVGNames::textTag)
- || parentNode()->hasTagName(SVGNames::textPathTag)
- || parentNode()->hasTagName(SVGNames::tspanTag)))
+ || isSVGTextElement(*parentNode())
+ || isSVGTextPathElement(*parentNode())
+ || isSVGTSpanElement(*parentNode())))
return Element::rendererIsNeeded(style);
return false;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.h
index 547e9ee5e03..233cb026ffc 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTSpanElement.h
@@ -27,14 +27,13 @@ namespace WebCore {
class SVGTSpanElement FINAL : public SVGTextPositioningElement {
public:
- static PassRefPtr<SVGTSpanElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGTSpanElement);
private:
explicit SVGTSpanElement(Document&);
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool childShouldCreateRenderer(const Node& child) const;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTagNames.in b/chromium/third_party/WebKit/Source/core/svg/SVGTagNames.in
index caf925d610c..641203e0ecc 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTagNames.in
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTagNames.in
@@ -4,22 +4,20 @@ fallbackInterfaceName="SVGUnknownElement"
fallbackJSInterfaceName="SVGElement"
a
-#if ENABLE_SVG_FONTS
-altGlyph
-altGlyphDef
-altGlyphItem
-#endif
-animate
-animateColor
+altGlyph Conditional=SVG_FONTS
+altGlyphDef Conditional=SVG_FONTS
+altGlyphItem Conditional=SVG_FONTS
+animate noTypeHelpers
+animateColor interfaceName=SVGUnknownElement, JSInterfaceName=SVGElement, noConstructor
animateMotion
animateTransform
set
circle
clipPath
-# color-profile
cursor
defs
desc
+discard
ellipse
feBlend
feColorMatrix
@@ -47,30 +45,24 @@ feSpotLight
feTile
feTurbulence
filter
-#if ENABLE_SVG_FONTS
-font
-font-face
-font-face-format
-font-face-name
-font-face-src
-font-face-uri
-#endif
+font Conditional=SVG_FONTS
+font-face Conditional=SVG_FONTS
+font-face-format Conditional=SVG_FONTS
+font-face-name Conditional=SVG_FONTS
+font-face-src Conditional=SVG_FONTS
+font-face-uri Conditional=SVG_FONTS
foreignObject
g
-#if ENABLE_SVG_FONTS
-glyph
-glyphRef
-hkern interfaceName=SVGHKernElement
-#endif
+glyph Conditional=SVG_FONTS
+glyphRef Conditional=SVG_FONTS
+hkern Conditional=SVG_FONTS, interfaceName=SVGHKernElement
image
line
linearGradient
marker
mask
metadata
-#if ENABLE_SVG_FONTS
-missing-glyph
-#endif
+missing-glyph Conditional=SVG_FONTS
mpath interfaceName=SVGMPathElement
path
pattern
@@ -88,8 +80,6 @@ text
textPath
title
tspan interfaceName=SVGTSpanElement
-use constructorNeedsCreatedByParser
+use
view
-#if ENABLE_SVG_FONTS
-vkern interfaceName=SVGVKernElement
-#endif
+vkern Conditional=SVG_FONTS, interfaceName=SVGVKernElement
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTests.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTests.cpp
index 1332610788d..4f424f968ae 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTests.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTests.cpp
@@ -22,77 +22,26 @@
#include "core/svg/SVGTests.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/dom/DOMImplementation.h"
#include "platform/Language.h"
#include "core/svg/SVGElement.h"
namespace WebCore {
-// Define custom non-animated property 'requiredFeatures'.
-const SVGPropertyInfo* SVGTests::requiredFeaturesPropertyInfo()
+SVGTests::SVGTests(SVGElement* contextElement)
+ : m_requiredFeatures(SVGStaticStringList::create(contextElement, SVGNames::requiredFeaturesAttr))
+ , m_requiredExtensions(SVGStaticStringList::create(contextElement, SVGNames::requiredExtensionsAttr))
+ , m_systemLanguage(SVGStaticStringList::create(contextElement, SVGNames::systemLanguageAttr))
{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown,
- PropertyIsReadWrite,
- SVGNames::requiredFeaturesAttr,
- SVGNames::requiredFeaturesAttr.localName(),
- &SVGElement::synchronizeRequiredFeatures,
- 0);
- }
- return s_propertyInfo;
-}
-
-// Define custom non-animated property 'requiredExtensions'.
-const SVGPropertyInfo* SVGTests::requiredExtensionsPropertyInfo()
-{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown,
- PropertyIsReadWrite,
- SVGNames::requiredExtensionsAttr,
- SVGNames::requiredExtensionsAttr.localName(),
- &SVGElement::synchronizeRequiredExtensions,
- 0);
- }
- return s_propertyInfo;
-}
-
-// Define custom non-animated property 'systemLanguage'.
-const SVGPropertyInfo* SVGTests::systemLanguagePropertyInfo()
-{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown,
- PropertyIsReadWrite,
- SVGNames::systemLanguageAttr,
- SVGNames::systemLanguageAttr.localName(),
- &SVGElement::synchronizeSystemLanguage,
- 0);
- }
- return s_propertyInfo;
-}
-
-SVGTests::SVGTests()
- : m_requiredFeatures(SVGNames::requiredFeaturesAttr)
- , m_requiredExtensions(SVGNames::requiredExtensionsAttr)
- , m_systemLanguage(SVGNames::systemLanguageAttr)
-{
-}
+ ASSERT(contextElement);
-SVGAttributeToPropertyMap& SVGTests::attributeToPropertyMap()
-{
- DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, map, ());
- if (!map.isEmpty())
- return map;
- map.addProperty(requiredFeaturesPropertyInfo());
- map.addProperty(requiredExtensionsPropertyInfo());
- map.addProperty(systemLanguagePropertyInfo());
- return map;
+ contextElement->addToPropertyMap(m_requiredFeatures);
+ contextElement->addToPropertyMap(m_requiredExtensions);
+ contextElement->addToPropertyMap(m_systemLanguage);
}
-bool SVGTests::hasExtension(const String&) const
+bool SVGTests::hasExtension(const String&)
{
// FIXME: Implement me!
return false;
@@ -100,21 +49,34 @@ bool SVGTests::hasExtension(const String&) const
bool SVGTests::isValid() const
{
- unsigned featuresSize = m_requiredFeatures.value.size();
- for (unsigned i = 0; i < featuresSize; ++i) {
- String value = m_requiredFeatures.value.at(i);
- if (value.isEmpty() || !DOMImplementation::hasFeature(value, String()))
- return false;
+ if (m_requiredFeatures->isSpecified()) {
+ const Vector<String>& requiredFeatures = m_requiredFeatures->value()->values();
+ Vector<String>::const_iterator it = requiredFeatures.begin();
+ Vector<String>::const_iterator itEnd = requiredFeatures.end();
+ for (; it != itEnd; ++it) {
+ if (it->isEmpty() || !DOMImplementation::hasFeature(*it, String()))
+ return false;
+ }
}
- unsigned systemLanguageSize = m_systemLanguage.value.size();
- for (unsigned i = 0; i < systemLanguageSize; ++i) {
- String value = m_systemLanguage.value.at(i);
- if (value != defaultLanguage().substring(0, 2))
+ if (m_systemLanguage->isSpecified()) {
+ bool matchFound = false;
+
+ const Vector<String>& systemLanguage = m_systemLanguage->value()->values();
+ Vector<String>::const_iterator it = systemLanguage.begin();
+ Vector<String>::const_iterator itEnd = systemLanguage.end();
+ for (; it != itEnd; ++it) {
+ if (*it == defaultLanguage().string().substring(0, 2)) {
+ matchFound = true;
+ break;
+ }
+ }
+
+ if (!matchFound)
return false;
}
- if (!m_requiredExtensions.value.isEmpty())
+ if (!m_requiredExtensions->value()->values().isEmpty())
return false;
return true;
@@ -122,20 +84,22 @@ bool SVGTests::isValid() const
bool SVGTests::parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- if (name == SVGNames::requiredFeaturesAttr) {
- m_requiredFeatures.value.reset(value);
- return true;
- }
- if (name == SVGNames::requiredExtensionsAttr) {
- m_requiredExtensions.value.reset(value);
- return true;
- }
- if (name == SVGNames::systemLanguageAttr) {
- m_systemLanguage.value.reset(value);
- return true;
- }
+ // FIXME: Should handle exceptions here.
+ // This is safe as of now, as the current impl of SVGStringList::setValueAsString never fails.
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::requiredFeaturesAttr)
+ m_requiredFeatures->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::requiredExtensionsAttr)
+ m_requiredExtensions->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::systemLanguageAttr)
+ m_systemLanguage->setBaseValueAsString(value, parseError);
+ else
+ return false;
- return false;
+ ASSERT(parseError == NoError);
+
+ return true;
}
bool SVGTests::isKnownAttribute(const QualifiedName& attrName)
@@ -152,49 +116,4 @@ void SVGTests::addSupportedAttributes(HashSet<QualifiedName>& supportedAttribute
supportedAttributes.add(SVGNames::systemLanguageAttr);
}
-void SVGTests::synchronizeRequiredFeatures(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- if (!m_requiredFeatures.shouldSynchronize)
- return;
- AtomicString value(m_requiredFeatures.value.valueAsString());
- m_requiredFeatures.synchronize(contextElement, requiredFeaturesPropertyInfo()->attributeName, value);
-}
-
-void SVGTests::synchronizeRequiredExtensions(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- if (!m_requiredExtensions.shouldSynchronize)
- return;
- AtomicString value(m_requiredExtensions.value.valueAsString());
- m_requiredExtensions.synchronize(contextElement, requiredExtensionsPropertyInfo()->attributeName, value);
-}
-
-void SVGTests::synchronizeSystemLanguage(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- if (!m_systemLanguage.shouldSynchronize)
- return;
- AtomicString value(m_systemLanguage.value.valueAsString());
- m_systemLanguage.synchronize(contextElement, systemLanguagePropertyInfo()->attributeName, value);
-}
-
-SVGStringList& SVGTests::requiredFeatures()
-{
- m_requiredFeatures.shouldSynchronize = true;
- return m_requiredFeatures.value;
-}
-
-SVGStringList& SVGTests::requiredExtensions()
-{
- m_requiredExtensions.shouldSynchronize = true;
- return m_requiredExtensions.value;
-}
-
-SVGStringList& SVGTests::systemLanguage()
-{
- m_systemLanguage.shouldSynchronize = true;
- return m_systemLanguage.value;
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTests.h b/chromium/third_party/WebKit/Source/core/svg/SVGTests.h
index 7df0e223f1b..ca0bc9dfbeb 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTests.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTests.h
@@ -21,23 +21,22 @@
#ifndef SVGTests_h
#define SVGTests_h
-#include "core/svg/SVGStringList.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
+#include "core/svg/SVGStaticStringList.h"
#include "wtf/HashSet.h"
namespace WebCore {
-class Attribute;
class QualifiedName;
class SVGElement;
class SVGTests {
public:
- SVGStringList& requiredFeatures();
- SVGStringList& requiredExtensions();
- SVGStringList& systemLanguage();
+ // JS API
+ SVGStringListTearOff* requiredFeatures() { return m_requiredFeatures->tearOff(); }
+ SVGStringListTearOff* requiredExtensions() { return m_requiredExtensions->tearOff(); }
+ SVGStringListTearOff* systemLanguage() { return m_systemLanguage->tearOff(); }
+ bool hasExtension(const String&);
- bool hasExtension(const String&) const;
bool isValid() const;
bool parseAttribute(const QualifiedName&, const AtomicString&);
@@ -45,27 +44,13 @@ public:
void addSupportedAttributes(HashSet<QualifiedName>&);
- static SVGAttributeToPropertyMap& attributeToPropertyMap();
-
protected:
- SVGTests();
-
- void synchronizeRequiredFeatures(SVGElement* contextElement);
- void synchronizeRequiredExtensions(SVGElement* contextElement);
- void synchronizeSystemLanguage(SVGElement* contextElement);
+ SVGTests(SVGElement* contextElement);
private:
- // Custom 'requiredFeatures' property
- static const SVGPropertyInfo* requiredFeaturesPropertyInfo();
- SVGSynchronizableAnimatedProperty<SVGStringList> m_requiredFeatures;
-
- // Custom 'requiredExtensions' property
- static const SVGPropertyInfo* requiredExtensionsPropertyInfo();
- SVGSynchronizableAnimatedProperty<SVGStringList> m_requiredExtensions;
-
- // Custom 'systemLanguage' property
- static const SVGPropertyInfo* systemLanguagePropertyInfo();
- SVGSynchronizableAnimatedProperty<SVGStringList> m_systemLanguage;
+ RefPtr<SVGStaticStringList> m_requiredFeatures;
+ RefPtr<SVGStaticStringList> m_requiredExtensions;
+ RefPtr<SVGStaticStringList> m_systemLanguage;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTests.idl b/chromium/third_party/WebKit/Source/core/svg/SVGTests.idl
index 0842cc1831d..9e0f5a164a4 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTests.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTests.idl
@@ -24,14 +24,15 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG2/types.html#InterfaceSVGTests
+
[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
+ NoInterfaceObject, // Always used on target of 'implements'
] interface SVGTests {
+
readonly attribute SVGStringList requiredFeatures;
readonly attribute SVGStringList requiredExtensions;
readonly attribute SVGStringList systemLanguage;
- boolean hasExtension([Default=Undefined] optional DOMString extension);
+ boolean hasExtension(DOMString extension);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
index 1c298456cae..cdf48002a99 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.cpp
@@ -21,84 +21,65 @@
#include "config.h"
#include "core/svg/SVGTextContentElement.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "SVGNames.h"
-#include "XMLNames.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/SVGNames.h"
+#include "core/XMLNames.h"
#include "core/editing/FrameSelection.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/SVGTextQuery.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Define custom animated property 'textLength'.
-const SVGPropertyInfo* SVGTextContentElement::textLengthPropertyInfo()
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGLengthAdjustType>()
{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedLength,
- PropertyIsReadWrite,
- SVGNames::textLengthAttr,
- SVGNames::textLengthAttr.localName(),
- &SVGTextContentElement::synchronizeTextLength,
- &SVGTextContentElement::lookupOrCreateTextLengthWrapper);
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(SVGLengthAdjustSpacing, "spacing"));
+ entries.append(std::make_pair(SVGLengthAdjustSpacingAndGlyphs, "spacingAndGlyphs"));
}
- return s_propertyInfo;
+ return entries;
}
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGTextContentElement, SVGNames::lengthAdjustAttr, LengthAdjust, lengthAdjust, SVGLengthAdjustType)
-DEFINE_ANIMATED_BOOLEAN(SVGTextContentElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
+// SVGTextContentElement's 'textLength' attribute needs special handling.
+// It should return getComputedTextLength() when textLength is not specified manually.
+class SVGAnimatedTextLength FINAL : public SVGAnimatedLength {
+public:
+ static PassRefPtr<SVGAnimatedTextLength> create(SVGTextContentElement* contextElement)
+ {
+ return adoptRef(new SVGAnimatedTextLength(contextElement));
+ }
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextContentElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(textLength)
- REGISTER_LOCAL_ANIMATED_PROPERTY(lengthAdjust)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
+ virtual SVGLengthTearOff* baseVal() OVERRIDE
+ {
+ SVGTextContentElement* textContentElement = toSVGTextContentElement(contextElement());
+ if (!textContentElement->textLengthIsSpecifiedByUser())
+ baseValue()->newValueSpecifiedUnits(LengthTypeNumber, textContentElement->getComputedTextLength());
-SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Document& document)
- : SVGGraphicsElement(tagName, document)
- , m_textLength(LengthModeOther)
- , m_specifiedTextLength(LengthModeOther)
- , m_lengthAdjust(SVGLengthAdjustSpacing)
-{
- ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGTextContentElement();
-}
+ return SVGAnimatedLength::baseVal();
+ }
-void SVGTextContentElement::synchronizeTextLength(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- SVGTextContentElement* ownerType = toSVGTextContentElement(contextElement);
- if (!ownerType->m_textLength.shouldSynchronize)
- return;
- AtomicString value(SVGPropertyTraits<SVGLength>::toString(ownerType->m_specifiedTextLength));
- ownerType->m_textLength.synchronize(ownerType, textLengthPropertyInfo()->attributeName, value);
-}
+private:
+ SVGAnimatedTextLength(SVGTextContentElement* contextElement)
+ : SVGAnimatedLength(contextElement, SVGNames::textLengthAttr, SVGLength::create(LengthModeOther), ForbidNegativeLengths)
+ {
+ }
+};
-PassRefPtr<SVGAnimatedProperty> SVGTextContentElement::lookupOrCreateTextLengthWrapper(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- SVGTextContentElement* ownerType = toSVGTextContentElement(contextElement);
- return SVGAnimatedProperty::lookupOrCreateWrapper<SVGTextContentElement, SVGAnimatedLength, SVGLength>
- (ownerType, textLengthPropertyInfo(), ownerType->m_textLength.value);
-}
-PassRefPtr<SVGAnimatedLength> SVGTextContentElement::textLength()
+SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Document& document)
+ : SVGGraphicsElement(tagName, document)
+ , m_textLength(SVGAnimatedTextLength::create(this))
+ , m_textLengthIsSpecifiedByUser(false)
+ , m_lengthAdjust(SVGAnimatedEnumeration<SVGLengthAdjustType>::create(this, SVGNames::lengthAdjustAttr, SVGLengthAdjustSpacing))
{
- DEFINE_STATIC_LOCAL(SVGLength, defaultTextLength, (LengthModeOther));
- if (m_specifiedTextLength == defaultTextLength)
- m_textLength.value.newValueSpecifiedUnits(LengthTypeNumber, getComputedTextLength(), ASSERT_NO_EXCEPTION);
-
- m_textLength.shouldSynchronize = true;
- return static_pointer_cast<SVGAnimatedLength>(lookupOrCreateTextLengthWrapper(this));
-
+ addToPropertyMap(m_textLength);
+ addToPropertyMap(m_lengthAdjust);
}
unsigned SVGTextContentElement::getNumberOfChars()
@@ -119,7 +100,7 @@ float SVGTextContentElement::getSubStringLength(unsigned charnum, unsigned nchar
unsigned numberOfChars = getNumberOfChars();
if (charnum >= numberOfChars) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
return 0.0f;
}
@@ -129,40 +110,43 @@ float SVGTextContentElement::getSubStringLength(unsigned charnum, unsigned nchar
return SVGTextQuery(renderer()).subStringLength(charnum, nchars);
}
-SVGPoint SVGTextContentElement::getStartPositionOfChar(unsigned charnum, ExceptionState& exceptionState)
+PassRefPtr<SVGPointTearOff> SVGTextContentElement::getStartPositionOfChar(unsigned charnum, ExceptionState& exceptionState)
{
document().updateLayoutIgnorePendingStylesheets();
if (charnum > getNumberOfChars()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return FloatPoint();
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
+ return nullptr;
}
- return SVGTextQuery(renderer()).startPositionOfCharacter(charnum);
+ FloatPoint point = SVGTextQuery(renderer()).startPositionOfCharacter(charnum);
+ return SVGPointTearOff::create(SVGPoint::create(point), 0, PropertyIsNotAnimVal);
}
-SVGPoint SVGTextContentElement::getEndPositionOfChar(unsigned charnum, ExceptionState& exceptionState)
+PassRefPtr<SVGPointTearOff> SVGTextContentElement::getEndPositionOfChar(unsigned charnum, ExceptionState& exceptionState)
{
document().updateLayoutIgnorePendingStylesheets();
if (charnum > getNumberOfChars()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return FloatPoint();
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
+ return nullptr;
}
- return SVGTextQuery(renderer()).endPositionOfCharacter(charnum);
+ FloatPoint point = SVGTextQuery(renderer()).endPositionOfCharacter(charnum);
+ return SVGPointTearOff::create(SVGPoint::create(point), 0, PropertyIsNotAnimVal);
}
-SVGRect SVGTextContentElement::getExtentOfChar(unsigned charnum, ExceptionState& exceptionState)
+PassRefPtr<SVGRectTearOff> SVGTextContentElement::getExtentOfChar(unsigned charnum, ExceptionState& exceptionState)
{
document().updateLayoutIgnorePendingStylesheets();
if (charnum > getNumberOfChars()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return SVGRect();
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
+ return nullptr;
}
- return SVGTextQuery(renderer()).extentOfCharacter(charnum);
+ FloatRect rect = SVGTextQuery(renderer()).extentOfCharacter(charnum);
+ return SVGRectTearOff::create(SVGRect::create(rect), 0, PropertyIsNotAnimVal);
}
float SVGTextContentElement::getRotationOfChar(unsigned charnum, ExceptionState& exceptionState)
@@ -170,24 +154,24 @@ float SVGTextContentElement::getRotationOfChar(unsigned charnum, ExceptionState&
document().updateLayoutIgnorePendingStylesheets();
if (charnum > getNumberOfChars()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
return 0.0f;
}
return SVGTextQuery(renderer()).rotationOfCharacter(charnum);
}
-int SVGTextContentElement::getCharNumAtPosition(const SVGPoint& point)
+int SVGTextContentElement::getCharNumAtPosition(PassRefPtr<SVGPointTearOff> point, ExceptionState& exceptionState)
{
document().updateLayoutIgnorePendingStylesheets();
- return SVGTextQuery(renderer()).characterNumberAtPosition(point);
+ return SVGTextQuery(renderer()).characterNumberAtPosition(point->target()->value());
}
void SVGTextContentElement::selectSubString(unsigned charnum, unsigned nchars, ExceptionState& exceptionState)
{
unsigned numberOfChars = getNumberOfChars();
if (charnum >= numberOfChars) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
return;
}
@@ -213,7 +197,6 @@ bool SVGTextContentElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::lengthAdjustAttr);
supportedAttributes.add(SVGNames::textLengthAttr);
supportedAttributes.add(XMLNames::spaceAttr);
@@ -249,12 +232,9 @@ void SVGTextContentElement::parseAttribute(const QualifiedName& name, const Atom
if (!isSupportedAttribute(name))
SVGGraphicsElement::parseAttribute(name, value);
else if (name == SVGNames::lengthAdjustAttr) {
- SVGLengthAdjustType propertyValue = SVGPropertyTraits<SVGLengthAdjustType>::fromString(value);
- if (propertyValue > 0)
- setLengthAdjustBaseValue(propertyValue);
+ m_lengthAdjust->setBaseValueAsString(value, parseError);
} else if (name == SVGNames::textLengthAttr) {
- m_textLength.value = SVGLength::construct(LengthModeOther, value, parseError, ForbidNegativeLengths);
- } else if (SVGExternalResourcesRequired::parseAttribute(name, value)) {
+ m_textLength->setBaseValueAsString(value, parseError);
} else if (name.matches(XMLNames::spaceAttr)) {
} else
ASSERT_NOT_REACHED();
@@ -269,10 +249,10 @@ void SVGTextContentElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
-
if (attrName == SVGNames::textLengthAttr)
- m_specifiedTextLength = m_textLength.value;
+ m_textLengthIsSpecifiedByUser = true;
+
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (RenderObject* renderer = this->renderer())
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
@@ -296,11 +276,7 @@ SVGTextContentElement* SVGTextContentElement::elementFromRenderer(RenderObject*
SVGElement* element = toSVGElement(renderer->node());
ASSERT(element);
-
- if (!element->isTextContent())
- return 0;
-
- return toSVGTextContentElement(element);
+ return isSVGTextContentElement(*element) ? toSVGTextContentElement(element) : 0;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.h
index db0b622d8b9..6b49793bbd7 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.h
@@ -24,8 +24,8 @@
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedEnumeration.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
+#include "core/svg/SVGPointTearOff.h"
namespace WebCore {
@@ -36,38 +36,9 @@ enum SVGLengthAdjustType {
SVGLengthAdjustSpacing,
SVGLengthAdjustSpacingAndGlyphs
};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGLengthAdjustType>();
-template<>
-struct SVGPropertyTraits<SVGLengthAdjustType> {
- static unsigned highestEnumValue() { return SVGLengthAdjustSpacingAndGlyphs; }
-
- static String toString(SVGLengthAdjustType type)
- {
- switch (type) {
- case SVGLengthAdjustUnknown:
- return emptyString();
- case SVGLengthAdjustSpacing:
- return "spacing";
- case SVGLengthAdjustSpacingAndGlyphs:
- return "spacingAndGlyphs";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static SVGLengthAdjustType fromString(const String& value)
- {
- if (value == "spacingAndGlyphs")
- return SVGLengthAdjustSpacingAndGlyphs;
- if (value == "spacing")
- return SVGLengthAdjustSpacing;
- return SVGLengthAdjustUnknown;
- }
-};
-
-class SVGTextContentElement : public SVGGraphicsElement,
- public SVGExternalResourcesRequired {
+class SVGTextContentElement : public SVGGraphicsElement {
public:
// Forward declare enumerations in the W3C naming scheme, for IDL generation.
enum {
@@ -79,47 +50,36 @@ public:
unsigned getNumberOfChars();
float getComputedTextLength();
float getSubStringLength(unsigned charnum, unsigned nchars, ExceptionState&);
- SVGPoint getStartPositionOfChar(unsigned charnum, ExceptionState&);
- SVGPoint getEndPositionOfChar(unsigned charnum, ExceptionState&);
- SVGRect getExtentOfChar(unsigned charnum, ExceptionState&);
+ PassRefPtr<SVGPointTearOff> getStartPositionOfChar(unsigned charnum, ExceptionState&);
+ PassRefPtr<SVGPointTearOff> getEndPositionOfChar(unsigned charnum, ExceptionState&);
+ PassRefPtr<SVGRectTearOff> getExtentOfChar(unsigned charnum, ExceptionState&);
float getRotationOfChar(unsigned charnum, ExceptionState&);
- int getCharNumAtPosition(const SVGPoint&);
+ int getCharNumAtPosition(PassRefPtr<SVGPointTearOff>, ExceptionState&);
void selectSubString(unsigned charnum, unsigned nchars, ExceptionState&);
static SVGTextContentElement* elementFromRenderer(RenderObject*);
- // textLength is not declared using the standard DECLARE_ANIMATED_LENGTH macro
- // as its getter needs special handling (return getComputedTextLength(), instead of m_textLength).
- SVGLength& specifiedTextLength() { return m_specifiedTextLength; }
- PassRefPtr<SVGAnimatedLength> textLength();
- static const SVGPropertyInfo* textLengthPropertyInfo();
+ SVGAnimatedLength* textLength() { return m_textLength.get(); }
+ bool textLengthIsSpecifiedByUser() { return m_textLengthIsSpecifiedByUser; }
+ SVGAnimatedEnumeration<SVGLengthAdjustType>* lengthAdjust() { return m_lengthAdjust.get(); }
protected:
SVGTextContentElement(const QualifiedName&, Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
-
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
- virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE FINAL;
+ virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE FINAL;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
private:
- virtual bool isTextContent() const { return true; }
-
- // Custom 'textLength' property
- static void synchronizeTextLength(SVGElement* contextElement);
- static PassRefPtr<SVGAnimatedProperty> lookupOrCreateTextLengthWrapper(SVGElement* contextElement);
- mutable SVGSynchronizableAnimatedProperty<SVGLength> m_textLength;
- SVGLength m_specifiedTextLength;
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextContentElement)
- DECLARE_ANIMATED_ENUMERATION(LengthAdjust, lengthAdjust, SVGLengthAdjustType)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual bool isTextContent() const OVERRIDE FINAL { return true; }
+
+ RefPtr<SVGAnimatedLength> m_textLength;
+ bool m_textLengthIsSpecifiedByUser;
+ RefPtr<SVGAnimatedEnumeration<SVGLengthAdjustType> > m_lengthAdjust;
};
inline bool isSVGTextContentElement(const Node& node)
@@ -127,7 +87,7 @@ inline bool isSVGTextContentElement(const Node& node)
return node.isSVGElement() && toSVGElement(node).isTextContent();
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGTextContentElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGTextContentElement);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.idl
index f4ce37dc97d..4f0466b4116 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextContentElement.idl
@@ -23,7 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGTextContentElement : SVGGraphicsElement {
+[
+ TypeChecking=Interface|Nullable,
+] interface SVGTextContentElement : SVGGraphicsElement {
// lengthAdjust Types
const unsigned short LENGTHADJUST_UNKNOWN = 0;
const unsigned short LENGTHADJUST_SPACING = 1;
@@ -39,10 +41,7 @@ interface SVGTextContentElement : SVGGraphicsElement {
[RaisesException] SVGPoint getEndPositionOfChar(unsigned long offset);
[RaisesException] SVGRect getExtentOfChar(unsigned long offset);
[RaisesException] float getRotationOfChar(unsigned long offset);
- long getCharNumAtPosition(SVGPoint point);
+ [RaisesException] long getCharNumAtPosition(SVGPoint point);
[RaisesException] void selectSubString(unsigned long offset, unsigned long length);
};
-// FIXME: SVGTextContentElement is not supposed to implement SVGExternalResourcesRequired.
-SVGTextContentElement implements SVGExternalResourcesRequired;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTextElement.cpp
index 7806ed129ed..1fcd139810e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextElement.cpp
@@ -24,7 +24,6 @@
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/RenderSVGText.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
@@ -34,10 +33,7 @@ inline SVGTextElement::SVGTextElement(Document& doc)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGTextElement> SVGTextElement::create(Document& document)
-{
- return adoptRef(new SVGTextElement(document));
-}
+DEFINE_NODE_FACTORY(SVGTextElement)
// We override SVGGraphics::animatedLocalTransform() so that the transform-origin
// is not taken into account.
@@ -55,7 +51,7 @@ AffineTransform SVGTextElement::animatedLocalTransform() const
// Flatten any 3D transform
matrix = t.toAffineTransform();
} else {
- transformCurrentValue().concatenate(matrix);
+ transform()->currentValue()->concatenate(matrix);
}
const AffineTransform* transform = const_cast<SVGTextElement*>(this)->supplementalTransform();
@@ -69,18 +65,4 @@ RenderObject* SVGTextElement::createRenderer(RenderStyle*)
return new RenderSVGText(this);
}
-bool SVGTextElement::childShouldCreateRenderer(const Node& child) const
-{
- if (child.isTextNode()
- || child.hasTagName(SVGNames::aTag)
-#if ENABLE(SVG_FONTS)
- || child.hasTagName(SVGNames::altGlyphTag)
-#endif
- || child.hasTagName(SVGNames::textPathTag)
- || child.hasTagName(SVGNames::tspanTag))
- return true;
-
- return false;
-}
-
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGTextElement.h
index b52204c15c3..945cca29b73 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextElement.h
@@ -21,28 +21,23 @@
#ifndef SVGTextElement_h
#define SVGTextElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGTextPositioningElement.h"
namespace WebCore {
class SVGTextElement FINAL : public SVGTextPositioningElement {
public:
- static PassRefPtr<SVGTextElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGTextElement);
- virtual AffineTransform animatedLocalTransform() const;
+ virtual AffineTransform animatedLocalTransform() const OVERRIDE;
private:
explicit SVGTextElement(Document&);
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
-
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool childShouldCreateRenderer(const Node& child) const;
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
};
-DEFINE_NODE_TYPE_CASTS(SVGTextElement, hasTagName(SVGNames::textTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp
index b3f2e1b1fb4..8c42b33d570 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.cpp
@@ -22,50 +22,58 @@
#include "core/svg/SVGTextPathElement.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/RenderSVGTextPath.h"
-#include "core/svg/SVGElementInstance.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGTextPathElement, SVGNames::startOffsetAttr, StartOffset, startOffset)
-DEFINE_ANIMATED_ENUMERATION(SVGTextPathElement, SVGNames::methodAttr, Method, method, SVGTextPathMethodType)
-DEFINE_ANIMATED_ENUMERATION(SVGTextPathElement, SVGNames::spacingAttr, Spacing, spacing, SVGTextPathSpacingType)
-DEFINE_ANIMATED_STRING(SVGTextPathElement, XLinkNames::hrefAttr, Href, href)
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGTextPathMethodType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(SVGTextPathMethodAlign, "align"));
+ entries.append(std::make_pair(SVGTextPathMethodStretch, "stretch"));
+ }
+ return entries;
+}
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextPathElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(startOffset)
- REGISTER_LOCAL_ANIMATED_PROPERTY(method)
- REGISTER_LOCAL_ANIMATED_PROPERTY(spacing)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextContentElement)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGTextPathSpacingType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(SVGTextPathSpacingAuto, "auto"));
+ entries.append(std::make_pair(SVGTextPathSpacingExact, "exact"));
+ }
+ return entries;
+}
inline SVGTextPathElement::SVGTextPathElement(Document& document)
: SVGTextContentElement(SVGNames::textPathTag, document)
- , m_startOffset(LengthModeOther)
- , m_method(SVGTextPathMethodAlign)
- , m_spacing(SVGTextPathSpacingExact)
+ , SVGURIReference(this)
+ , m_startOffset(SVGAnimatedLength::create(this, SVGNames::startOffsetAttr, SVGLength::create(LengthModeOther), AllowNegativeLengths))
+ , m_method(SVGAnimatedEnumeration<SVGTextPathMethodType>::create(this, SVGNames::methodAttr, SVGTextPathMethodAlign))
+ , m_spacing(SVGAnimatedEnumeration<SVGTextPathSpacingType>::create(this, SVGNames::spacingAttr, SVGTextPathSpacingExact))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGTextPathElement();
-}
-PassRefPtr<SVGTextPathElement> SVGTextPathElement::create(Document& document)
-{
- return adoptRef(new SVGTextPathElement(document));
+ addToPropertyMap(m_startOffset);
+ addToPropertyMap(m_method);
+ addToPropertyMap(m_spacing);
}
+DEFINE_NODE_FACTORY(SVGTextPathElement)
+
SVGTextPathElement::~SVGTextPathElement()
{
+#if !ENABLE(OILPAN)
clearResourceReferences();
+#endif
}
void SVGTextPathElement::clearResourceReferences()
{
- document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+ document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
}
bool SVGTextPathElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -87,16 +95,12 @@ void SVGTextPathElement::parseAttribute(const QualifiedName& name, const AtomicS
if (!isSupportedAttribute(name))
SVGTextContentElement::parseAttribute(name, value);
else if (name == SVGNames::startOffsetAttr)
- setStartOffsetBaseValue(SVGLength::construct(LengthModeOther, value, parseError));
- else if (name == SVGNames::methodAttr) {
- SVGTextPathMethodType propertyValue = SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
- if (propertyValue > 0)
- setMethodBaseValue(propertyValue);
- } else if (name == SVGNames::spacingAttr) {
- SVGTextPathSpacingType propertyValue = SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value);
- if (propertyValue > 0)
- setSpacingBaseValue(propertyValue);
- } else if (SVGURIReference::parseAttribute(name, value)) {
+ m_startOffset->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::methodAttr)
+ m_method->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::spacingAttr)
+ m_spacing->setBaseValueAsString(value, parseError);
+ else if (SVGURIReference::parseAttribute(name, value, parseError)) {
} else
ASSERT_NOT_REACHED();
@@ -110,7 +114,7 @@ void SVGTextPathElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
if (SVGURIReference::isKnownAttribute(attrName)) {
buildPendingResource();
@@ -129,21 +133,9 @@ RenderObject* SVGTextPathElement::createRenderer(RenderStyle*)
return new RenderSVGTextPath(this);
}
-bool SVGTextPathElement::childShouldCreateRenderer(const Node& child) const
-{
- if (child.isTextNode()
- || child.hasTagName(SVGNames::aTag)
- || child.hasTagName(SVGNames::tspanTag))
- return true;
-
- return false;
-}
-
bool SVGTextPathElement::rendererIsNeeded(const RenderStyle& style)
{
- if (parentNode()
- && (parentNode()->hasTagName(SVGNames::aTag)
- || parentNode()->hasTagName(SVGNames::textTag)))
+ if (parentNode() && (isSVGAElement(*parentNode()) || isSVGTextElement(*parentNode())))
return Element::rendererIsNeeded(style);
return false;
@@ -155,21 +147,21 @@ void SVGTextPathElement::buildPendingResource()
if (!inDocument())
return;
- String id;
- Element* target = SVGURIReference::targetElementFromIRIString(hrefCurrentValue(), document(), &id);
+ AtomicString id;
+ Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), treeScope(), &id);
if (!target) {
// Do not register as pending if we are already pending this resource.
- if (document().accessSVGExtensions()->isElementPendingResource(this, id))
+ if (document().accessSVGExtensions().isElementPendingResource(this, id))
return;
if (!id.isEmpty()) {
- document().accessSVGExtensions()->addPendingResource(id, this);
+ document().accessSVGExtensions().addPendingResource(id, this);
ASSERT(hasPendingResources());
}
- } else if (target->hasTagName(SVGNames::pathTag)) {
+ } else if (isSVGPathElement(*target)) {
// Register us with the target in the dependencies map. Any change of hrefElement
// that leads to relayout/repainting now informs us, so we can react to it.
- document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target));
+ document().accessSVGExtensions().addElementReferencingTarget(this, toSVGElement((target)));
}
}
@@ -189,7 +181,7 @@ void SVGTextPathElement::removedFrom(ContainerNode* rootParent)
bool SVGTextPathElement::selfHasRelativeLengths() const
{
- return startOffsetCurrentValue().isRelative()
+ return m_startOffset->currentValue()->isRelative()
|| SVGTextContentElement::selfHasRelativeLengths();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.h
index 2b7a38c1ead..c6ac5303181 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextPathElement.h
@@ -20,7 +20,7 @@
#ifndef SVGTextPathElement_h
#define SVGTextPathElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGTextContentElement.h"
#include "core/svg/SVGURIReference.h"
@@ -38,63 +38,8 @@ enum SVGTextPathSpacingType {
SVGTextPathSpacingExact
};
-template<>
-struct SVGPropertyTraits<SVGTextPathMethodType> {
- static unsigned highestEnumValue() { return SVGTextPathMethodStretch; }
-
- static String toString(SVGTextPathMethodType type)
- {
- switch (type) {
- case SVGTextPathMethodUnknown:
- return emptyString();
- case SVGTextPathMethodAlign:
- return "align";
- case SVGTextPathMethodStretch:
- return "stretch";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static SVGTextPathMethodType fromString(const String& value)
- {
- if (value == "align")
- return SVGTextPathMethodAlign;
- if (value == "stretch")
- return SVGTextPathMethodStretch;
- return SVGTextPathMethodUnknown;
- }
-};
-
-template<>
-struct SVGPropertyTraits<SVGTextPathSpacingType> {
- static unsigned highestEnumValue() { return SVGTextPathSpacingExact; }
-
- static String toString(SVGTextPathSpacingType type)
- {
- switch (type) {
- case SVGTextPathSpacingUnknown:
- return emptyString();
- case SVGTextPathSpacingAuto:
- return "auto";
- case SVGTextPathSpacingExact:
- return "exact";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static SVGTextPathSpacingType fromString(const String& value)
- {
- if (value == "auto")
- return SVGTextPathSpacingAuto;
- if (value == "exact")
- return SVGTextPathSpacingExact;
- return SVGTextPathSpacingUnknown;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGTextPathMethodType>();
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGTextPathSpacingType>();
class SVGTextPathElement FINAL : public SVGTextContentElement,
public SVGURIReference {
@@ -109,7 +54,11 @@ public:
TEXTPATH_SPACINGTYPE_EXACT = SVGTextPathSpacingExact
};
- static PassRefPtr<SVGTextPathElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGTextPathElement);
+
+ SVGAnimatedLength* startOffset() const { return m_startOffset.get(); }
+ SVGAnimatedEnumeration<SVGTextPathMethodType>* method() { return m_method.get(); }
+ SVGAnimatedEnumeration<SVGTextPathSpacingType>* spacing() { return m_spacing.get(); }
private:
explicit SVGTextPathElement(Document&);
@@ -118,30 +67,24 @@ private:
void clearResourceReferences();
- virtual void buildPendingResource();
+ virtual void buildPendingResource() OVERRIDE;
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual bool childShouldCreateRenderer(const Node& child) const;
- virtual bool rendererIsNeeded(const RenderStyle&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextPathElement)
- DECLARE_ANIMATED_LENGTH(StartOffset, startOffset)
- DECLARE_ANIMATED_ENUMERATION(Method, method, SVGTextPathMethodType)
- DECLARE_ANIMATED_ENUMERATION(Spacing, spacing, SVGTextPathSpacingType)
- DECLARE_ANIMATED_STRING(Href, href)
- END_DECLARE_ANIMATED_PROPERTIES
+ RefPtr<SVGAnimatedLength> m_startOffset;
+ RefPtr<SVGAnimatedEnumeration<SVGTextPathMethodType> > m_method;
+ RefPtr<SVGAnimatedEnumeration<SVGTextPathSpacingType> > m_spacing;
};
-DEFINE_NODE_TYPE_CASTS(SVGTextPathElement, hasTagName(SVGNames::textPathTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp
index 664ba23a5a9..c2c0614905c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp
@@ -22,36 +22,27 @@
#include "core/svg/SVGTextPositioningElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/RenderSVGText.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGLengthList.h"
#include "core/svg/SVGNumberList.h"
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dxAttr, Dx, dx)
-DEFINE_ANIMATED_LENGTH_LIST(SVGTextPositioningElement, SVGNames::dyAttr, Dy, dy)
-DEFINE_ANIMATED_NUMBER_LIST(SVGTextPositioningElement, SVGNames::rotateAttr, Rotate, rotate)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextPositioningElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(dx)
- REGISTER_LOCAL_ANIMATED_PROPERTY(dy)
- REGISTER_LOCAL_ANIMATED_PROPERTY(rotate)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextContentElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document& document)
: SVGTextContentElement(tagName, document)
+ , m_x(SVGAnimatedLengthList::create(this, SVGNames::xAttr, SVGLengthList::create(LengthModeWidth)))
+ , m_y(SVGAnimatedLengthList::create(this, SVGNames::yAttr, SVGLengthList::create(LengthModeHeight)))
+ , m_dx(SVGAnimatedLengthList::create(this, SVGNames::dxAttr, SVGLengthList::create(LengthModeWidth)))
+ , m_dy(SVGAnimatedLengthList::create(this, SVGNames::dyAttr, SVGLengthList::create(LengthModeHeight)))
+ , m_rotate(SVGAnimatedNumberList::create(this, SVGNames::rotateAttr, SVGNumberList::create()))
{
- ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGTextPositioningElement();
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_dx);
+ addToPropertyMap(m_dy);
+ addToPropertyMap(m_rotate);
}
bool SVGTextPositioningElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -74,47 +65,22 @@ void SVGTextPositioningElement::parseAttribute(const QualifiedName& name, const
return;
}
- if (name == SVGNames::xAttr) {
- SVGLengthList newList;
- newList.parse(value, LengthModeWidth);
- detachAnimatedXListWrappers(newList.size());
- setXBaseValue(newList);
- return;
- }
-
- if (name == SVGNames::yAttr) {
- SVGLengthList newList;
- newList.parse(value, LengthModeHeight);
- detachAnimatedYListWrappers(newList.size());
- setYBaseValue(newList);
- return;
- }
-
- if (name == SVGNames::dxAttr) {
- SVGLengthList newList;
- newList.parse(value, LengthModeWidth);
- detachAnimatedDxListWrappers(newList.size());
- setDxBaseValue(newList);
- return;
- }
-
- if (name == SVGNames::dyAttr) {
- SVGLengthList newList;
- newList.parse(value, LengthModeHeight);
- detachAnimatedDyListWrappers(newList.size());
- setDyBaseValue(newList);
- return;
- }
-
- if (name == SVGNames::rotateAttr) {
- SVGNumberList newList;
- newList.parse(value);
- detachAnimatedRotateListWrappers(newList.size());
- setRotateBaseValue(newList);
- return;
- }
-
- ASSERT_NOT_REACHED();
+ SVGParsingError parseError = NoError;
+
+ if (name == SVGNames::xAttr)
+ m_x->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::yAttr)
+ m_y->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::dxAttr)
+ m_dx->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::dyAttr)
+ m_dy->setBaseValueAsString(value, parseError);
+ else if (name == SVGNames::rotateAttr)
+ m_rotate->setBaseValueAsString(value, parseError);
+ else
+ ASSERT_NOT_REACHED();
+
+ reportAttributeParsingError(parseError, name, value);
}
void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -124,7 +90,7 @@ void SVGTextPositioningElement::svgAttributeChanged(const QualifiedName& attrNam
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
bool updateRelativeLengths = attrName == SVGNames::xAttr
|| attrName == SVGNames::yAttr
@@ -160,14 +126,7 @@ SVGTextPositioningElement* SVGTextPositioningElement::elementFromRenderer(Render
ASSERT(node);
ASSERT(node->isSVGElement());
- if (!node->hasTagName(SVGNames::textTag)
-#if ENABLE(SVG_FONTS)
- && !node->hasTagName(SVGNames::altGlyphTag)
-#endif
- && !node->hasTagName(SVGNames::tspanTag))
- return 0;
-
- return static_cast<SVGTextPositioningElement*>(node);
+ return isSVGTextPositioningElement(*node) ? toSVGTextPositioningElement(node) : 0;
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.h
index 665315c38a2..b4800bcb133 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTextPositioningElement.h
@@ -21,6 +21,7 @@
#ifndef SVGTextPositioningElement_h
#define SVGTextPositioningElement_h
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedLengthList.h"
#include "core/svg/SVGAnimatedNumberList.h"
#include "core/svg/SVGTextContentElement.h"
@@ -31,22 +32,34 @@ class SVGTextPositioningElement : public SVGTextContentElement {
public:
static SVGTextPositioningElement* elementFromRenderer(RenderObject*);
+ SVGAnimatedLengthList* x() { return m_x.get(); }
+ SVGAnimatedLengthList* y() { return m_y.get(); }
+ SVGAnimatedLengthList* dx() { return m_dx.get(); }
+ SVGAnimatedLengthList* dy() { return m_dy.get(); }
+ SVGAnimatedNumberList* rotate() { return m_rotate.get(); }
+
protected:
SVGTextPositioningElement(const QualifiedName&, Document&);
bool isSupportedAttribute(const QualifiedName&);
- virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextPositioningElement)
- DECLARE_ANIMATED_LENGTH_LIST(X, x)
- DECLARE_ANIMATED_LENGTH_LIST(Y, y)
- DECLARE_ANIMATED_LENGTH_LIST(Dx, dx)
- DECLARE_ANIMATED_LENGTH_LIST(Dy, dy)
- DECLARE_ANIMATED_NUMBER_LIST(Rotate, rotate)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE FINAL;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE FINAL;
+ virtual bool isTextPositioning() const OVERRIDE FINAL { return true; }
+
+ RefPtr<SVGAnimatedLengthList> m_x;
+ RefPtr<SVGAnimatedLengthList> m_y;
+ RefPtr<SVGAnimatedLengthList> m_dx;
+ RefPtr<SVGAnimatedLengthList> m_dy;
+ RefPtr<SVGAnimatedNumberList> m_rotate;
};
+inline bool isSVGTextPositioningElement(const Node& node)
+{
+ return node.isSVGElement() && toSVGElement(node).isTextPositioning();
+}
+
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGTextPositioningElement);
+
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp
index cd018b8a0f1..99050189f14 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.cpp
@@ -21,7 +21,7 @@
#include "config.h"
#include "core/svg/SVGTitleElement.h"
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Document.h"
namespace WebCore {
@@ -32,18 +32,14 @@ inline SVGTitleElement::SVGTitleElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGTitleElement> SVGTitleElement::create(Document& document)
-{
- return adoptRef(new SVGTitleElement(document));
-}
+DEFINE_NODE_FACTORY(SVGTitleElement)
Node::InsertionNotificationRequest SVGTitleElement::insertedInto(ContainerNode* rootParent)
{
SVGElement::insertedInto(rootParent);
if (!rootParent->inDocument())
return InsertionDone;
- // FIXME: It's possible to register SVGTitleElement to an HTMLDocument.
- if (firstChild())
+ if (firstChild() && document().isSVGDocument())
document().setTitleElement(textContent(), this);
return InsertionDone;
}
@@ -51,14 +47,14 @@ Node::InsertionNotificationRequest SVGTitleElement::insertedInto(ContainerNode*
void SVGTitleElement::removedFrom(ContainerNode* rootParent)
{
SVGElement::removedFrom(rootParent);
- if (rootParent->inDocument())
+ if (rootParent->inDocument() && document().isSVGDocument())
document().removeTitle(this);
}
void SVGTitleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
- if (inDocument())
+ if (inDocument() && document().isSVGDocument())
document().setTitleElement(textContent(), this);
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.h
index 21c3127f6dd..6c1d7fbc8f1 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTitleElement.h
@@ -27,16 +27,16 @@ namespace WebCore {
class SVGTitleElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGTitleElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGTitleElement);
private:
explicit SVGTitleElement(Document&);
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
+ virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransform.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTransform.cpp
index 8cf0ef2ffcc..6771f7a85e2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTransform.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransform.cpp
@@ -29,13 +29,15 @@
namespace WebCore {
SVGTransform::SVGTransform()
- : m_type(SVG_TRANSFORM_UNKNOWN)
+ : SVGPropertyBase(classType())
+ , m_transformType(SVG_TRANSFORM_UNKNOWN)
, m_angle(0)
{
}
-SVGTransform::SVGTransform(SVGTransformType type, ConstructionMode mode)
- : m_type(type)
+SVGTransform::SVGTransform(SVGTransformType transformType, ConstructionMode mode)
+ : SVGPropertyBase(classType())
+ , m_transformType(transformType)
, m_angle(0)
{
if (mode == ConstructZeroTransform)
@@ -43,31 +45,53 @@ SVGTransform::SVGTransform(SVGTransformType type, ConstructionMode mode)
}
SVGTransform::SVGTransform(const AffineTransform& matrix)
- : m_type(SVG_TRANSFORM_MATRIX)
+ : SVGPropertyBase(classType())
+ , m_transformType(SVG_TRANSFORM_MATRIX)
, m_angle(0)
, m_matrix(matrix)
{
}
+SVGTransform::SVGTransform(SVGTransformType transformType, float angle, const FloatPoint& center, const AffineTransform& matrix)
+ : SVGPropertyBase(classType())
+ , m_transformType(transformType)
+ , m_angle(angle)
+ , m_center(center)
+ , m_matrix(matrix)
+{
+}
+
+SVGTransform::~SVGTransform()
+{
+}
+
+PassRefPtr<SVGTransform> SVGTransform::clone() const
+{
+ return adoptRef(new SVGTransform(m_transformType, m_angle, m_center, m_matrix));
+}
+
+PassRefPtr<SVGPropertyBase> SVGTransform::cloneForAnimation(const String&) const
+{
+ // SVGTransform is never animated.
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
void SVGTransform::setMatrix(const AffineTransform& matrix)
{
- m_type = SVG_TRANSFORM_MATRIX;
- m_angle = 0;
+ onMatrixChange();
m_matrix = matrix;
}
-void SVGTransform::updateSVGMatrix()
+void SVGTransform::onMatrixChange()
{
- // The underlying matrix has been changed, alter the transformation type.
- // Spec: In case the matrix object is changed directly (i.e., without using the methods on the SVGTransform interface itself)
- // then the type of the SVGTransform changes to SVG_TRANSFORM_MATRIX.
- m_type = SVG_TRANSFORM_MATRIX;
+ m_transformType = SVG_TRANSFORM_MATRIX;
m_angle = 0;
}
void SVGTransform::setTranslate(float tx, float ty)
{
- m_type = SVG_TRANSFORM_TRANSLATE;
+ m_transformType = SVG_TRANSFORM_TRANSLATE;
m_angle = 0;
m_matrix.makeIdentity();
@@ -81,7 +105,7 @@ FloatPoint SVGTransform::translate() const
void SVGTransform::setScale(float sx, float sy)
{
- m_type = SVG_TRANSFORM_SCALE;
+ m_transformType = SVG_TRANSFORM_SCALE;
m_angle = 0;
m_center = FloatPoint();
@@ -96,7 +120,7 @@ FloatSize SVGTransform::scale() const
void SVGTransform::setRotate(float angle, float cx, float cy)
{
- m_type = SVG_TRANSFORM_ROTATE;
+ m_transformType = SVG_TRANSFORM_ROTATE;
m_angle = angle;
m_center = FloatPoint(cx, cy);
@@ -109,7 +133,7 @@ void SVGTransform::setRotate(float angle, float cx, float cy)
void SVGTransform::setSkewX(float angle)
{
- m_type = SVG_TRANSFORM_SKEWX;
+ m_transformType = SVG_TRANSFORM_SKEWX;
m_angle = angle;
m_matrix.makeIdentity();
@@ -118,14 +142,16 @@ void SVGTransform::setSkewX(float angle)
void SVGTransform::setSkewY(float angle)
{
- m_type = SVG_TRANSFORM_SKEWY;
+ m_transformType = SVG_TRANSFORM_SKEWY;
m_angle = angle;
m_matrix.makeIdentity();
m_matrix.skewY(angle);
}
-const String& SVGTransform::transformTypePrefixForParsing(SVGTransformType type)
+namespace {
+
+const String& transformTypePrefixForParsing(SVGTransformType type)
{
switch (type) {
case SVG_TRANSFORM_UNKNOWN:
@@ -160,10 +186,12 @@ const String& SVGTransform::transformTypePrefixForParsing(SVGTransformType type)
return emptyString();
}
+}
+
String SVGTransform::valueAsString() const
{
- const String& prefix = transformTypePrefixForParsing(m_type);
- switch (m_type) {
+ const String& prefix = transformTypePrefixForParsing(m_transformType);
+ switch (m_transformType) {
case SVG_TRANSFORM_UNKNOWN:
return prefix;
case SVG_TRANSFORM_MATRIX: {
@@ -196,4 +224,24 @@ String SVGTransform::valueAsString() const
return emptyString();
}
+void SVGTransform::add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*)
+{
+ // SVGTransform is not animated by itself.
+ ASSERT_NOT_REACHED();
+}
+
+void SVGTransform::calculateAnimatedValue(SVGAnimationElement*, float, unsigned, PassRefPtr<SVGPropertyBase>, PassRefPtr<SVGPropertyBase>, PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ // SVGTransform is not animated by itself.
+ ASSERT_NOT_REACHED();
+}
+
+float SVGTransform::calculateDistance(PassRefPtr<SVGPropertyBase>, SVGElement*)
+{
+ // SVGTransform is not animated by itself.
+ ASSERT_NOT_REACHED();
+
+ return -1;
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransform.h b/chromium/third_party/WebKit/Source/core/svg/SVGTransform.h
index 71f7668b38d..51753bb1186 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTransform.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransform.h
@@ -21,40 +21,62 @@
#ifndef SVGTransform_h
#define SVGTransform_h
-#include "core/svg/SVGMatrix.h"
+#include "core/svg/properties/SVGProperty.h"
#include "platform/geometry/FloatPoint.h"
+#include "platform/transforms/AffineTransform.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
class FloatSize;
+class SVGTransformTearOff;
+
+enum SVGTransformType {
+ SVG_TRANSFORM_UNKNOWN = 0,
+ SVG_TRANSFORM_MATRIX = 1,
+ SVG_TRANSFORM_TRANSLATE = 2,
+ SVG_TRANSFORM_SCALE = 3,
+ SVG_TRANSFORM_ROTATE = 4,
+ SVG_TRANSFORM_SKEWX = 5,
+ SVG_TRANSFORM_SKEWY = 6
+};
-class SVGTransform {
+class SVGTransform : public SVGPropertyBase {
public:
- enum SVGTransformType {
- SVG_TRANSFORM_UNKNOWN = 0,
- SVG_TRANSFORM_MATRIX = 1,
- SVG_TRANSFORM_TRANSLATE = 2,
- SVG_TRANSFORM_SCALE = 3,
- SVG_TRANSFORM_ROTATE = 4,
- SVG_TRANSFORM_SKEWX = 5,
- SVG_TRANSFORM_SKEWY = 6
- };
+ typedef SVGTransformTearOff TearOffType;
enum ConstructionMode {
ConstructIdentityTransform,
ConstructZeroTransform
};
- SVGTransform();
- SVGTransform(SVGTransformType, ConstructionMode = ConstructIdentityTransform);
- explicit SVGTransform(const AffineTransform&);
+ static PassRefPtr<SVGTransform> create()
+ {
+ return adoptRef(new SVGTransform());
+ }
+
+ static PassRefPtr<SVGTransform> create(SVGTransformType type, ConstructionMode mode = ConstructIdentityTransform)
+ {
+ return adoptRef(new SVGTransform(type, mode));
+ }
+
+ static PassRefPtr<SVGTransform> create(const AffineTransform& affineTransform)
+ {
+ return adoptRef(new SVGTransform(affineTransform));
+ }
+
+ virtual ~SVGTransform();
- SVGTransformType type() const { return m_type; }
+ PassRefPtr<SVGTransform> clone() const;
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
- SVGMatrix& svgMatrix() { return static_cast<SVGMatrix&>(m_matrix); }
- AffineTransform matrix() const { return m_matrix; }
- void updateSVGMatrix();
+ SVGTransformType transformType() const { return m_transformType; }
+
+ const AffineTransform& matrix() const { return m_matrix; }
+
+ // |onMatrixChange| must be called after modifications via |mutableMatrix|.
+ AffineTransform* mutableMatrix() { return &m_matrix; }
+ void onMatrixChange();
float angle() const { return m_angle; }
FloatPoint rotationCenter() const { return m_center; }
@@ -70,15 +92,23 @@ public:
FloatPoint translate() const;
FloatSize scale() const;
- bool isValid() const { return m_type != SVG_TRANSFORM_UNKNOWN; }
- String valueAsString() const;
+ virtual String valueAsString() const OVERRIDE;
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
- static const String& transformTypePrefixForParsing(SVGTransformType);
+ static AnimatedPropertyType classType() { return AnimatedTransform; }
private:
+ SVGTransform();
+ SVGTransform(SVGTransformType, ConstructionMode);
+ explicit SVGTransform(const AffineTransform&);
+ SVGTransform(SVGTransformType, float, const FloatPoint&, const AffineTransform&);
+
friend bool operator==(const SVGTransform& a, const SVGTransform& b);
- SVGTransformType m_type;
+ SVGTransformType m_transformType;
float m_angle;
FloatPoint m_center;
AffineTransform m_matrix;
@@ -86,7 +116,7 @@ private:
inline bool operator==(const SVGTransform& a, const SVGTransform& b)
{
- return a.m_type == b.m_type && a.m_angle == b.m_angle && a.m_matrix == b.m_matrix;
+ return a.m_transformType == b.m_transformType && a.m_angle == b.m_angle && a.m_matrix == b.m_matrix;
}
inline bool operator!=(const SVGTransform& a, const SVGTransform& b)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransform.idl b/chromium/third_party/WebKit/Source/core/svg/SVGTransform.idl
index 99d7fc27893..d810948599c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTransform.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransform.idl
@@ -19,7 +19,11 @@
* Boston, MA 02110-1301, USA.
*/
-interface SVGTransform {
+[
+ TypeChecking=Interface|Nullable,
+ ImplementedAs=SVGTransformTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGTransform {
// Transform Types
const unsigned short SVG_TRANSFORM_UNKNOWN = 0;
const unsigned short SVG_TRANSFORM_MATRIX = 1;
@@ -29,15 +33,15 @@ interface SVGTransform {
const unsigned short SVG_TRANSFORM_SKEWX = 5;
const unsigned short SVG_TRANSFORM_SKEWY = 6;
- readonly attribute unsigned short type;
- [ImplementedAs=svgMatrix] readonly attribute SVGMatrix matrix;
+ [ImplementedAs=transformType] readonly attribute unsigned short type;
+ readonly attribute SVGMatrix matrix;
readonly attribute float angle;
- [StrictTypeChecking] void setMatrix(SVGMatrix matrix);
- [StrictTypeChecking] void setTranslate(float tx, float ty);
- [StrictTypeChecking] void setScale(float sx, float sy);
- [StrictTypeChecking] void setRotate(float angle, float cx, float cy);
- [StrictTypeChecking] void setSkewX(float angle);
- [StrictTypeChecking] void setSkewY(float angle);
+ [RaisesException] void setMatrix(SVGMatrix matrix);
+ [RaisesException] void setTranslate(float tx, float ty);
+ [RaisesException] void setScale(float sx, float sy);
+ [RaisesException] void setRotate(float angle, float cx, float cy);
+ [RaisesException] void setSkewX(float angle);
+ [RaisesException] void setSkewY(float angle);
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp
index 1108f322039..a4f860b1986 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp
@@ -28,15 +28,15 @@
namespace WebCore {
SVGTransformDistance::SVGTransformDistance()
- : m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
+ : m_transformType(SVG_TRANSFORM_UNKNOWN)
, m_angle(0)
, m_cx(0)
, m_cy(0)
{
}
-SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type, float angle, float cx, float cy, const AffineTransform& transform)
- : m_type(type)
+SVGTransformDistance::SVGTransformDistance(SVGTransformType transformType, float angle, float cx, float cy, const AffineTransform& transform)
+ : m_transformType(transformType)
, m_angle(angle)
, m_cx(cx)
, m_cy(cy)
@@ -44,169 +44,170 @@ SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type,
{
}
-SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform, const SVGTransform& toSVGTransform)
- : m_type(fromSVGTransform.type())
- , m_angle(0)
+SVGTransformDistance::SVGTransformDistance(PassRefPtr<SVGTransform> passFromSVGTransform, PassRefPtr<SVGTransform> passToSVGTransform)
+ : m_angle(0)
, m_cx(0)
, m_cy(0)
{
- ASSERT(m_type == toSVGTransform.type());
+ RefPtr<SVGTransform> fromSVGTransform = passFromSVGTransform;
+ RefPtr<SVGTransform> toSVGTransform = passToSVGTransform;
+
+ m_transformType = fromSVGTransform->transformType();
+ ASSERT(m_transformType == toSVGTransform->transformType());
- switch (m_type) {
- case SVGTransform::SVG_TRANSFORM_MATRIX:
+ switch (m_transformType) {
+ case SVG_TRANSFORM_MATRIX:
ASSERT_NOT_REACHED();
- case SVGTransform::SVG_TRANSFORM_UNKNOWN:
+ case SVG_TRANSFORM_UNKNOWN:
break;
- case SVGTransform::SVG_TRANSFORM_ROTATE: {
- FloatSize centerDistance = toSVGTransform.rotationCenter() - fromSVGTransform.rotationCenter();
- m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
+ case SVG_TRANSFORM_ROTATE: {
+ FloatSize centerDistance = toSVGTransform->rotationCenter() - fromSVGTransform->rotationCenter();
+ m_angle = toSVGTransform->angle() - fromSVGTransform->angle();
m_cx = centerDistance.width();
m_cy = centerDistance.height();
break;
}
- case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
- FloatSize translationDistance = toSVGTransform.translate() - fromSVGTransform.translate();
+ case SVG_TRANSFORM_TRANSLATE: {
+ FloatSize translationDistance = toSVGTransform->translate() - fromSVGTransform->translate();
m_transform.translate(translationDistance.width(), translationDistance.height());
break;
}
- case SVGTransform::SVG_TRANSFORM_SCALE: {
- float scaleX = toSVGTransform.scale().width() - fromSVGTransform.scale().width();
- float scaleY = toSVGTransform.scale().height() - fromSVGTransform.scale().height();
+ case SVG_TRANSFORM_SCALE: {
+ float scaleX = toSVGTransform->scale().width() - fromSVGTransform->scale().width();
+ float scaleY = toSVGTransform->scale().height() - fromSVGTransform->scale().height();
m_transform.scaleNonUniform(scaleX, scaleY);
break;
}
- case SVGTransform::SVG_TRANSFORM_SKEWX:
- case SVGTransform::SVG_TRANSFORM_SKEWY:
- m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
+ case SVG_TRANSFORM_SKEWX:
+ case SVG_TRANSFORM_SKEWY:
+ m_angle = toSVGTransform->angle() - fromSVGTransform->angle();
break;
}
}
SVGTransformDistance SVGTransformDistance::scaledDistance(float scaleFactor) const
{
- switch (m_type) {
- case SVGTransform::SVG_TRANSFORM_MATRIX:
+ switch (m_transformType) {
+ case SVG_TRANSFORM_MATRIX:
ASSERT_NOT_REACHED();
- case SVGTransform::SVG_TRANSFORM_UNKNOWN:
+ case SVG_TRANSFORM_UNKNOWN:
return SVGTransformDistance();
- case SVGTransform::SVG_TRANSFORM_ROTATE:
- return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
- case SVGTransform::SVG_TRANSFORM_SCALE:
- return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform(m_transform).scale(scaleFactor));
- case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
+ case SVG_TRANSFORM_ROTATE:
+ return SVGTransformDistance(m_transformType, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
+ case SVG_TRANSFORM_SCALE:
+ return SVGTransformDistance(m_transformType, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform(m_transform).scale(scaleFactor));
+ case SVG_TRANSFORM_TRANSLATE: {
AffineTransform newTransform(m_transform);
newTransform.setE(m_transform.e() * scaleFactor);
newTransform.setF(m_transform.f() * scaleFactor);
- return SVGTransformDistance(m_type, 0, 0, 0, newTransform);
+ return SVGTransformDistance(m_transformType, 0, 0, 0, newTransform);
}
- case SVGTransform::SVG_TRANSFORM_SKEWX:
- case SVGTransform::SVG_TRANSFORM_SKEWY:
- return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
+ case SVG_TRANSFORM_SKEWX:
+ case SVG_TRANSFORM_SKEWY:
+ return SVGTransformDistance(m_transformType, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
}
ASSERT_NOT_REACHED();
return SVGTransformDistance();
}
-SVGTransform SVGTransformDistance::addSVGTransforms(const SVGTransform& first, const SVGTransform& second, unsigned repeatCount)
+PassRefPtr<SVGTransform> SVGTransformDistance::addSVGTransforms(PassRefPtr<SVGTransform> passFirst, PassRefPtr<SVGTransform> passSecond, unsigned repeatCount)
{
- ASSERT(first.type() == second.type());
+ RefPtr<SVGTransform> first = passFirst;
+ RefPtr<SVGTransform> second = passSecond;
+ ASSERT(first->transformType() == second->transformType());
- SVGTransform transform;
+ RefPtr<SVGTransform> transform = SVGTransform::create();
- switch (first.type()) {
- case SVGTransform::SVG_TRANSFORM_MATRIX:
+ switch (first->transformType()) {
+ case SVG_TRANSFORM_MATRIX:
ASSERT_NOT_REACHED();
- case SVGTransform::SVG_TRANSFORM_UNKNOWN:
- return SVGTransform();
- case SVGTransform::SVG_TRANSFORM_ROTATE: {
- transform.setRotate(first.angle() + second.angle() * repeatCount, first.rotationCenter().x() + second.rotationCenter().x() * repeatCount, first.rotationCenter().y() + second.rotationCenter().y() * repeatCount);
- return transform;
+ case SVG_TRANSFORM_UNKNOWN:
+ return transform.release();
+ case SVG_TRANSFORM_ROTATE: {
+ transform->setRotate(first->angle() + second->angle() * repeatCount, first->rotationCenter().x() + second->rotationCenter().x() * repeatCount, first->rotationCenter().y() + second->rotationCenter().y() * repeatCount);
+ return transform.release();
}
- case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
- float dx = first.translate().x() + second.translate().x() * repeatCount;
- float dy = first.translate().y() + second.translate().y() * repeatCount;
- transform.setTranslate(dx, dy);
- return transform;
+ case SVG_TRANSFORM_TRANSLATE: {
+ float dx = first->translate().x() + second->translate().x() * repeatCount;
+ float dy = first->translate().y() + second->translate().y() * repeatCount;
+ transform->setTranslate(dx, dy);
+ return transform.release();
}
- case SVGTransform::SVG_TRANSFORM_SCALE: {
- FloatSize scale = second.scale();
+ case SVG_TRANSFORM_SCALE: {
+ FloatSize scale = second->scale();
scale.scale(repeatCount);
- scale += first.scale();
- transform.setScale(scale.width(), scale.height());
- return transform;
+ scale += first->scale();
+ transform->setScale(scale.width(), scale.height());
+ return transform.release();
}
- case SVGTransform::SVG_TRANSFORM_SKEWX:
- transform.setSkewX(first.angle() + second.angle() * repeatCount);
- return transform;
- case SVGTransform::SVG_TRANSFORM_SKEWY:
- transform.setSkewY(first.angle() + second.angle() * repeatCount);
- return transform;
+ case SVG_TRANSFORM_SKEWX:
+ transform->setSkewX(first->angle() + second->angle() * repeatCount);
+ return transform.release();
+ case SVG_TRANSFORM_SKEWY:
+ transform->setSkewY(first->angle() + second->angle() * repeatCount);
+ return transform.release();
}
ASSERT_NOT_REACHED();
- return SVGTransform();
+ return transform.release();
}
-SVGTransform SVGTransformDistance::addToSVGTransform(const SVGTransform& transform) const
+PassRefPtr<SVGTransform> SVGTransformDistance::addToSVGTransform(PassRefPtr<SVGTransform> passTransform) const
{
- ASSERT(m_type == transform.type() || transform == SVGTransform());
+ RefPtr<SVGTransform> transform = passTransform;
+ ASSERT(m_transformType == transform->transformType() || m_transformType == SVG_TRANSFORM_UNKNOWN);
- SVGTransform newTransform(transform);
+ RefPtr<SVGTransform> newTransform = transform->clone();
- switch (m_type) {
- case SVGTransform::SVG_TRANSFORM_MATRIX:
+ switch (m_transformType) {
+ case SVG_TRANSFORM_MATRIX:
ASSERT_NOT_REACHED();
- case SVGTransform::SVG_TRANSFORM_UNKNOWN:
- return SVGTransform();
- case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
- FloatPoint translation = transform.translate();
+ case SVG_TRANSFORM_UNKNOWN:
+ return SVGTransform::create();
+ case SVG_TRANSFORM_TRANSLATE: {
+ FloatPoint translation = transform->translate();
translation += FloatSize::narrowPrecision(m_transform.e(), m_transform.f());
- newTransform.setTranslate(translation.x(), translation.y());
- return newTransform;
+ newTransform->setTranslate(translation.x(), translation.y());
+ return newTransform.release();
}
- case SVGTransform::SVG_TRANSFORM_SCALE: {
- FloatSize scale = transform.scale();
+ case SVG_TRANSFORM_SCALE: {
+ FloatSize scale = transform->scale();
scale += FloatSize::narrowPrecision(m_transform.a(), m_transform.d());
- newTransform.setScale(scale.width(), scale.height());
- return newTransform;
+ newTransform->setScale(scale.width(), scale.height());
+ return newTransform.release();
}
- case SVGTransform::SVG_TRANSFORM_ROTATE: {
- FloatPoint center = transform.rotationCenter();
- newTransform.setRotate(transform.angle() + m_angle, center.x() + m_cx, center.y() + m_cy);
- return newTransform;
+ case SVG_TRANSFORM_ROTATE: {
+ FloatPoint center = transform->rotationCenter();
+ newTransform->setRotate(transform->angle() + m_angle, center.x() + m_cx, center.y() + m_cy);
+ return newTransform.release();
}
- case SVGTransform::SVG_TRANSFORM_SKEWX:
- newTransform.setSkewX(transform.angle() + m_angle);
- return newTransform;
- case SVGTransform::SVG_TRANSFORM_SKEWY:
- newTransform.setSkewY(transform.angle() + m_angle);
- return newTransform;
+ case SVG_TRANSFORM_SKEWX:
+ newTransform->setSkewX(transform->angle() + m_angle);
+ return newTransform.release();
+ case SVG_TRANSFORM_SKEWY:
+ newTransform->setSkewY(transform->angle() + m_angle);
+ return newTransform.release();
}
ASSERT_NOT_REACHED();
- return SVGTransform();
-}
-
-bool SVGTransformDistance::isZero() const
-{
- return m_transform.isIdentity() && !m_angle;
+ return newTransform.release();
}
float SVGTransformDistance::distance() const
{
- switch (m_type) {
- case SVGTransform::SVG_TRANSFORM_MATRIX:
+ switch (m_transformType) {
+ case SVG_TRANSFORM_MATRIX:
ASSERT_NOT_REACHED();
- case SVGTransform::SVG_TRANSFORM_UNKNOWN:
+ case SVG_TRANSFORM_UNKNOWN:
return 0;
- case SVGTransform::SVG_TRANSFORM_ROTATE:
+ case SVG_TRANSFORM_ROTATE:
return sqrtf(m_angle * m_angle + m_cx * m_cx + m_cy * m_cy);
- case SVGTransform::SVG_TRANSFORM_SCALE:
+ case SVG_TRANSFORM_SCALE:
return static_cast<float>(sqrt(m_transform.a() * m_transform.a() + m_transform.d() * m_transform.d()));
- case SVGTransform::SVG_TRANSFORM_TRANSLATE:
+ case SVG_TRANSFORM_TRANSLATE:
return static_cast<float>(sqrt(m_transform.e() * m_transform.e() + m_transform.f() * m_transform.f()));
- case SVGTransform::SVG_TRANSFORM_SKEWX:
- case SVGTransform::SVG_TRANSFORM_SKEWY:
+ case SVG_TRANSFORM_SKEWX:
+ case SVG_TRANSFORM_SKEWY:
return m_angle;
}
ASSERT_NOT_REACHED();
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.h b/chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.h
index 32dd5d03a92..f2fc740880e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformDistance.h
@@ -29,20 +29,19 @@ class AffineTransform;
class SVGTransformDistance {
public:
SVGTransformDistance();
- SVGTransformDistance(const SVGTransform& fromTransform, const SVGTransform& toTransform);
+ SVGTransformDistance(PassRefPtr<SVGTransform> fromTransform, PassRefPtr<SVGTransform> toTransform);
SVGTransformDistance scaledDistance(float scaleFactor) const;
- SVGTransform addToSVGTransform(const SVGTransform&) const;
+ PassRefPtr<SVGTransform> addToSVGTransform(PassRefPtr<SVGTransform>) const;
- static SVGTransform addSVGTransforms(const SVGTransform&, const SVGTransform&, unsigned repeatCount = 1);
-
- bool isZero() const;
+ static PassRefPtr<SVGTransform> addSVGTransforms(PassRefPtr<SVGTransform>, PassRefPtr<SVGTransform>, unsigned repeatCount = 1);
float distance() const;
+
private:
- SVGTransformDistance(SVGTransform::SVGTransformType, float angle, float cx, float cy, const AffineTransform&);
+ SVGTransformDistance(SVGTransformType, float angle, float cx, float cy, const AffineTransform&);
- SVGTransform::SVGTransformType m_type;
+ SVGTransformType m_transformType;
float m_angle;
float m_cx;
float m_cy;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
index f09a01046a5..33b875b39f6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.cpp
@@ -1,6 +1,9 @@
/*
* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2012. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,77 +22,340 @@
*/
#include "config.h"
+
#include "core/svg/SVGTransformList.h"
+#include "core/SVGNames.h"
+#include "core/svg/SVGAnimateTransformElement.h"
+#include "core/svg/SVGAnimatedNumber.h"
#include "core/svg/SVGParserUtilities.h"
-#include "core/svg/SVGSVGElement.h"
-#include "platform/transforms/AffineTransform.h"
+#include "core/svg/SVGTransformDistance.h"
#include "wtf/text/StringBuilder.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
-SVGTransform SVGTransformList::createSVGTransformFromMatrix(const SVGMatrix& matrix) const
+inline PassRefPtr<SVGTransformList> toSVGTransformList(PassRefPtr<SVGPropertyBase> passBase)
+{
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == SVGTransformList::classType());
+ return static_pointer_cast<SVGTransformList>(base.release());
+}
+
+SVGTransformList::SVGTransformList()
+{
+}
+
+SVGTransformList::~SVGTransformList()
{
- return SVGSVGElement::createSVGTransformFromMatrix(matrix);
}
-SVGTransform SVGTransformList::consolidate()
+PassRefPtr<SVGTransform> SVGTransformList::consolidate()
{
AffineTransform matrix;
if (!concatenate(matrix))
- return SVGTransform();
+ return SVGTransform::create();
- SVGTransform transform(matrix);
+ RefPtr<SVGTransform> transform = SVGTransform::create(matrix);
clear();
- append(transform);
- return transform;
+ return appendItem(transform);
}
bool SVGTransformList::concatenate(AffineTransform& result) const
{
- unsigned size = this->size();
- if (!size)
+ if (isEmpty())
return false;
- for (unsigned i = 0; i < size; ++i)
- result *= at(i).matrix();
+ ConstIterator it = begin();
+ ConstIterator itEnd = end();
+ for (; it != itEnd; ++it)
+ result *= it->matrix();
return true;
}
+PassRefPtr<SVGTransformList> SVGTransformList::clone()
+{
+ RefPtr<SVGTransformList> svgTransformList = SVGTransformList::create();
+ svgTransformList->deepCopy(this);
+ return svgTransformList.release();
+}
+
+namespace {
+
+template<typename CharType>
+int parseTransformParamList(const CharType*& ptr, const CharType* end, float* values, int required, int optional)
+{
+ int parsedParams = 0;
+ int maxPossibleParams = required + optional;
+
+ bool trailingDelimiter = false;
+
+ skipOptionalSVGSpaces(ptr, end);
+ while (parsedParams < maxPossibleParams) {
+ if (!parseNumber(ptr, end, values[parsedParams], DisallowWhitespace))
+ break;
+
+ ++parsedParams;
+
+ if (skipOptionalSVGSpaces(ptr, end) && *ptr == ',') {
+ ++ptr;
+ skipOptionalSVGSpaces(ptr, end);
+
+ trailingDelimiter = true;
+ } else {
+ trailingDelimiter = false;
+ }
+ }
+
+ if (trailingDelimiter || !(parsedParams == required || parsedParams == maxPossibleParams))
+ return -1;
+
+ return parsedParams;
+}
+
+// These should be kept in sync with enum SVGTransformType
+static const int requiredValuesForType[] = {0, 6, 1, 1, 1, 1, 1};
+static const int optionalValuesForType[] = {0, 0, 1, 1, 2, 0, 0};
+
+template<typename CharType>
+PassRefPtr<SVGTransform> parseTransformOfType(unsigned type, const CharType*& ptr, const CharType* end)
+{
+ if (type == SVG_TRANSFORM_UNKNOWN)
+ return nullptr;
+
+ int valueCount = 0;
+ float values[] = {0, 0, 0, 0, 0, 0};
+ if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesForType[type], optionalValuesForType[type])) < 0) {
+ return nullptr;
+ }
+
+ RefPtr<SVGTransform> transform = SVGTransform::create();
+
+ switch (type) {
+ case SVG_TRANSFORM_SKEWX:
+ transform->setSkewX(values[0]);
+ break;
+ case SVG_TRANSFORM_SKEWY:
+ transform->setSkewY(values[0]);
+ break;
+ case SVG_TRANSFORM_SCALE:
+ if (valueCount == 1) // Spec: if only one param given, assume uniform scaling
+ transform->setScale(values[0], values[0]);
+ else
+ transform->setScale(values[0], values[1]);
+ break;
+ case SVG_TRANSFORM_TRANSLATE:
+ if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0
+ transform->setTranslate(values[0], 0);
+ else
+ transform->setTranslate(values[0], values[1]);
+ break;
+ case SVG_TRANSFORM_ROTATE:
+ if (valueCount == 1)
+ transform->setRotate(values[0], 0, 0);
+ else
+ transform->setRotate(values[0], values[1], values[2]);
+ break;
+ case SVG_TRANSFORM_MATRIX:
+ transform->setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5]));
+ break;
+ }
+
+ return transform.release();
+}
+
+}
+
+template<typename CharType>
+bool SVGTransformList::parseInternal(const CharType*& ptr, const CharType* end)
+{
+ clear();
+
+ bool delimParsed = false;
+ while (ptr < end) {
+ delimParsed = false;
+ SVGTransformType transformType = SVG_TRANSFORM_UNKNOWN;
+ skipOptionalSVGSpaces(ptr, end);
+
+ if (!parseAndSkipTransformType(ptr, end, transformType))
+ return false;
+
+ if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(')
+ return false;
+ ptr++;
+
+ RefPtr<SVGTransform> transform = parseTransformOfType(transformType, ptr, end);
+ if (!transform)
+ return false;
+
+ if (!skipOptionalSVGSpaces(ptr, end) || *ptr != ')')
+ return false;
+ ptr++;
+
+ append(transform.release());
+
+ skipOptionalSVGSpaces(ptr, end);
+ if (ptr < end && *ptr == ',') {
+ delimParsed = true;
+ ++ptr;
+ skipOptionalSVGSpaces(ptr, end);
+ }
+ }
+
+ return !delimParsed;
+}
+
+bool SVGTransformList::parse(const UChar*& ptr, const UChar* end)
+{
+ return parseInternal(ptr, end);
+}
+
+bool SVGTransformList::parse(const LChar*& ptr, const LChar* end)
+{
+ return parseInternal(ptr, end);
+}
+
String SVGTransformList::valueAsString() const
{
StringBuilder builder;
- unsigned size = this->size();
- for (unsigned i = 0; i < size; ++i) {
- if (i > 0)
- builder.append(' ');
- builder.append(at(i).valueAsString());
+ ConstIterator it = begin();
+ ConstIterator itEnd = end();
+ while (it != itEnd) {
+ builder.append(it->valueAsString());
+ ++it;
+ if (it != itEnd)
+ builder.append(' ');
}
return builder.toString();
}
-void SVGTransformList::parse(const String& transform)
+void SVGTransformList::setValueAsString(const String& value, ExceptionState& exceptionState)
{
- if (transform.isEmpty()) {
- // FIXME: The parseTransformAttribute function secretly calls clear()
- // based on a |mode| parameter. We should study whether we should
- // remove the |mode| parameter and force callers to call clear()
- // themselves.
+ if (value.isEmpty()) {
+ clear();
+ return;
+ }
+
+ bool valid = false;
+ if (value.is8Bit()) {
+ const LChar* ptr = value.characters8();
+ const LChar* end = ptr + value.length();
+ valid = parse(ptr, end);
+ } else {
+ const UChar* ptr = value.characters16();
+ const UChar* end = ptr + value.length();
+ valid = parse(ptr, end);
+ }
+
+ if (!valid) {
clear();
- } else if (transform.is8Bit()) {
- const LChar* ptr = transform.characters8();
- const LChar* end = ptr + transform.length();
- if (!parseTransformAttribute(*this, ptr, end))
- clear();
+ exceptionState.throwDOMException(SyntaxError, "Problem parsing transform list=\""+value+"\"");
+ }
+}
+
+PassRefPtr<SVGPropertyBase> SVGTransformList::cloneForAnimation(const String& value) const
+{
+ ASSERT_NOT_REACHED();
+ return nullptr;
+}
+
+PassRefPtr<SVGTransformList> SVGTransformList::create(SVGTransformType transformType, const String& value)
+{
+ RefPtr<SVGTransform> transform;
+ if (value.isEmpty()) {
+ } else if (value.is8Bit()) {
+ const LChar* ptr = value.characters8();
+ const LChar* end = ptr + value.length();
+ transform = parseTransformOfType(transformType, ptr, end);
} else {
- const UChar* ptr = transform.characters16();
- const UChar* end = ptr + transform.length();
- if (!parseTransformAttribute(*this, ptr, end))
- clear();
+ const UChar* ptr = value.characters16();
+ const UChar* end = ptr + value.length();
+ transform = parseTransformOfType(transformType, ptr, end);
}
+
+ RefPtr<SVGTransformList> svgTransformList = SVGTransformList::create();
+ if (transform)
+ svgTransformList->append(transform);
+ return svgTransformList.release();
}
-} // namespace WebCore
+void SVGTransformList::add(PassRefPtrWillBeRawPtr<SVGPropertyBase> other, SVGElement* contextElement)
+{
+ if (isEmpty())
+ return;
+
+ RefPtr<SVGTransformList> otherList = toSVGTransformList(other);
+ if (length() != otherList->length())
+ return;
+
+ ASSERT(length() == 1);
+ RefPtr<SVGTransform> fromTransform = at(0);
+ RefPtr<SVGTransform> toTransform = otherList->at(0);
+
+ ASSERT(fromTransform->transformType() == toTransform->transformType());
+ clear();
+ append(SVGTransformDistance::addSVGTransforms(fromTransform, toTransform));
+}
+
+void SVGTransformList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+{
+ ASSERT(animationElement);
+ bool isToAnimation = animationElement->animationMode() == ToAnimation;
+
+ // Spec: To animations provide specific functionality to get a smooth change from the underlying value to the
+ // ‘to’ attribute value, which conflicts mathematically with the requirement for additive transform animations
+ // to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to animations for ‘animateTransform’ is undefined
+ // FIXME: This is not taken into account yet.
+ RefPtr<SVGTransformList> fromList = isToAnimation ? this : toSVGTransformList(fromValue);
+ RefPtr<SVGTransformList> toList = toSVGTransformList(toValue);
+ RefPtr<SVGTransformList> toAtEndOfDurationList = toSVGTransformList(toAtEndOfDurationValue);
+
+ size_t toListSize = toList->length();
+ if (!toListSize)
+ return;
+
+ // Get a reference to the from value before potentially cleaning it out (in the case of a To animation.)
+ RefPtr<SVGTransform> toTransform = toList->at(0);
+ RefPtr<SVGTransform> effectiveFrom;
+ // If there's an existing 'from'/underlying value of the same type use that, else use a "zero transform".
+ if (fromList->length() && fromList->at(0)->transformType() == toTransform->transformType())
+ effectiveFrom = fromList->at(0);
+ else
+ effectiveFrom = SVGTransform::create(toTransform->transformType(), SVGTransform::ConstructZeroTransform);
+
+ // Never resize the animatedTransformList to the toList size, instead either clear the list or append to it.
+ if (!isEmpty() && (!animationElement->isAdditive() || isToAnimation))
+ clear();
+
+ RefPtr<SVGTransform> currentTransform = SVGTransformDistance(effectiveFrom, toTransform).scaledDistance(percentage).addToSVGTransform(effectiveFrom);
+ if (animationElement->isAccumulated() && repeatCount) {
+ RefPtr<SVGTransform> effectiveToAtEnd = !toAtEndOfDurationList->isEmpty() ? toAtEndOfDurationList->at(0) : SVGTransform::create(toTransform->transformType(), SVGTransform::ConstructZeroTransform);
+ append(SVGTransformDistance::addSVGTransforms(currentTransform, effectiveToAtEnd, repeatCount));
+ } else {
+ append(currentTransform);
+ }
+}
+
+float SVGTransformList::calculateDistance(PassRefPtr<SVGPropertyBase> toValue, SVGElement*)
+{
+ // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example)
+ // is paced separately. To implement this we need to treat each component as individual animation everywhere.
+
+ RefPtr<SVGTransformList> toList = toSVGTransformList(toValue);
+ if (isEmpty() || length() != toList->length())
+ return -1;
+
+ ASSERT(length() == 1);
+ if (at(0)->transformType() == toList->at(0)->transformType())
+ return -1;
+
+ // Spec: http://www.w3.org/TR/SVG/animate.html#complexDistances
+ // Paced animations assume a notion of distance between the various animation values defined by the ‘to’, ‘from’, ‘by’ and ‘values’ attributes.
+ // Distance is defined only for scalar types (such as <length>), colors and the subset of transformation types that are supported by ‘animateTransform’.
+ return SVGTransformDistance(at(0), toList->at(0)).distance();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.h b/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.h
index 4904a8826f7..1497ff5d108 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.h
@@ -1,51 +1,81 @@
/*
- * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGTransformList_h
#define SVGTransformList_h
+#include "bindings/v8/ScriptWrappable.h"
#include "core/svg/SVGTransform.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/Vector.h"
+#include "core/svg/properties/SVGListPropertyHelper.h"
namespace WebCore {
-class SVGTransformList : public Vector<SVGTransform> {
+class SVGTransformListTearOff;
+
+class SVGTransformList FINAL : public SVGListPropertyHelper<SVGTransformList, SVGTransform> {
public:
- SVGTransformList() { }
+ typedef SVGTransformListTearOff TearOffType;
+
+ static PassRefPtr<SVGTransformList> create()
+ {
+ return adoptRef(new SVGTransformList());
+ }
+
+ static PassRefPtr<SVGTransformList> create(SVGTransformType, const String&);
- SVGTransform createSVGTransformFromMatrix(const SVGMatrix&) const;
- SVGTransform consolidate();
+ virtual ~SVGTransformList();
+
+ PassRefPtr<SVGTransform> consolidate();
- // Internal use only
bool concatenate(AffineTransform& result) const;
- String valueAsString() const;
- void parse(const String&);
-};
+ // SVGPropertyBase:
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+ PassRefPtr<SVGTransformList> clone();
+
+ virtual String valueAsString() const OVERRIDE;
+ void setValueAsString(const String&, ExceptionState&);
+ bool parse(const UChar*& ptr, const UChar* end);
+ bool parse(const LChar*& ptr, const LChar* end);
+
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) OVERRIDE;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> fromValue, PassRefPtr<SVGPropertyBase> toValue, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+ static AnimatedPropertyType classType() { return AnimatedTransformList; }
+
+private:
+ SVGTransformList();
-template<>
-struct SVGPropertyTraits<SVGTransformList> {
- static SVGTransformList initialValue() { return SVGTransformList(); }
- static String toString(const SVGTransformList& type) { return type.valueAsString(); }
- typedef SVGTransform ListItemType;
+ template <typename CharType>
+ bool parseInternal(const CharType*& ptr, const CharType* end);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.idl b/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.idl
index bb6f659d51c..9bc5521fe49 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformList.idl
@@ -24,19 +24,24 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGTransformList {
- readonly attribute unsigned long numberOfItems;
+[
+ ImplementedAs=SVGTransformListTearOff,
+ SetWrapperReferenceTo(SVGElement contextElement),
+ TypeChecking=Interface|Nullable,
+] interface SVGTransformList {
+ readonly attribute unsigned long length;
+ [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
[RaisesException] void clear();
- [StrictTypeChecking, RaisesException] SVGTransform initialize(SVGTransform item);
- [StrictTypeChecking, RaisesException] SVGTransform getItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGTransform insertItemBefore(SVGTransform item, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGTransform replaceItem(SVGTransform item, unsigned long index);
- [StrictTypeChecking, RaisesException] SVGTransform removeItem(unsigned long index);
- [StrictTypeChecking, RaisesException] SVGTransform appendItem(SVGTransform item);
+ [RaisesException] SVGTransform initialize(SVGTransform item);
+ [RaisesException] getter SVGTransform getItem(unsigned long index);
+ [RaisesException] setter SVGTransform (unsigned long index, SVGTransform value);
+ [RaisesException] SVGTransform insertItemBefore(SVGTransform item, unsigned long index);
+ [RaisesException] SVGTransform replaceItem(SVGTransform item, unsigned long index);
+ [RaisesException] SVGTransform removeItem(unsigned long index);
+ [RaisesException] SVGTransform appendItem(SVGTransform item);
- [StrictTypeChecking, RaisesException] SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix);
+ SVGTransform createSVGTransformFromMatrix(SVGMatrix matrix);
[RaisesException] SVGTransform consolidate();
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp
new file mode 100644
index 00000000000..7dd151ae835
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGTransformListTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGSVGElement.h"
+
+namespace WebCore {
+
+SVGTransformListTearOff::SVGTransformListTearOff(PassRefPtr<SVGTransformList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ : SVGListPropertyTearOffHelper<SVGTransformListTearOff, SVGTransformList>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+SVGTransformListTearOff::~SVGTransformListTearOff()
+{
+}
+
+PassRefPtr<SVGTransformTearOff> SVGTransformListTearOff::createSVGTransformFromMatrix(PassRefPtr<SVGMatrixTearOff> matrix) const
+{
+ return SVGSVGElement::createSVGTransformFromMatrix(matrix);
+}
+
+PassRefPtr<SVGTransformTearOff> SVGTransformListTearOff::consolidate(ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return nullptr;
+ }
+
+ return createItemTearOff(target()->consolidate());
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformListTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGTransformListTearOff.h
new file mode 100644
index 00000000000..6aab790c103
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformListTearOff.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGTransformListTearOff_h
+#define SVGTransformListTearOff_h
+
+#include "core/svg/SVGTransformList.h"
+#include "core/svg/SVGTransformTearOff.h"
+#include "core/svg/properties/SVGListPropertyTearOffHelper.h"
+
+namespace WebCore {
+
+class SVGTransformListTearOff FINAL :
+ public SVGListPropertyTearOffHelper<SVGTransformListTearOff, SVGTransformList>,
+ public ScriptWrappable {
+public:
+ static PassRefPtr<SVGTransformListTearOff> create(PassRefPtr<SVGTransformList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGTransformListTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ virtual ~SVGTransformListTearOff();
+
+ PassRefPtr<SVGTransformTearOff> createSVGTransformFromMatrix(PassRefPtr<SVGMatrixTearOff>) const;
+ PassRefPtr<SVGTransformTearOff> consolidate(ExceptionState&);
+
+private:
+ SVGTransformListTearOff(PassRefPtr<SVGTransformList>, SVGElement*, PropertyIsAnimValType, const QualifiedName&);
+};
+
+} // namespace WebCore
+
+#endif // SVGTransformListTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp
new file mode 100644
index 00000000000..6ddf2bdf81c
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGTransformTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+SVGTransformTearOff::SVGTransformTearOff(PassRefPtr<SVGTransform> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ : SVGPropertyTearOff<SVGTransform>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+ ScriptWrappable::init(this);
+}
+
+SVGTransformTearOff::~SVGTransformTearOff()
+{
+}
+
+SVGMatrixTearOff* SVGTransformTearOff::matrix()
+{
+ if (!m_matrixTearoff) {
+ m_matrixTearoff = SVGMatrixTearOff::create(this);
+ }
+
+ return m_matrixTearoff.get();
+}
+
+void SVGTransformTearOff::setMatrix(PassRefPtr<SVGMatrixTearOff> matrix, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setMatrix(matrix->value());
+ commitChange();
+}
+
+void SVGTransformTearOff::setTranslate(float tx, float ty, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setTranslate(tx, ty);
+ commitChange();
+}
+
+void SVGTransformTearOff::setScale(float sx, float sy, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setScale(sx, sy);
+ commitChange();
+}
+
+void SVGTransformTearOff::setRotate(float angle, float cx, float cy, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setRotate(angle, cx, cy);
+ commitChange();
+}
+
+void SVGTransformTearOff::setSkewX(float x, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setSkewX(x);
+ commitChange();
+}
+
+void SVGTransformTearOff::setSkewY(float y, ExceptionState& exceptionState)
+{
+ if (isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ target()->setSkewY(y);
+ commitChange();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGTransformTearOff.h b/chromium/third_party/WebKit/Source/core/svg/SVGTransformTearOff.h
new file mode 100644
index 00000000000..4f90644726d
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGTransformTearOff.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGTransformTearOff_h
+#define SVGTransformTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGMatrixTearOff.h"
+#include "core/svg/SVGTransform.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGTransformTearOff FINAL : public SVGPropertyTearOff<SVGTransform>, public ScriptWrappable {
+public:
+ enum SVGTransformType {
+ SVG_TRANSFORM_UNKNOWN = WebCore::SVG_TRANSFORM_UNKNOWN,
+ SVG_TRANSFORM_MATRIX = WebCore::SVG_TRANSFORM_MATRIX,
+ SVG_TRANSFORM_TRANSLATE = WebCore::SVG_TRANSFORM_TRANSLATE,
+ SVG_TRANSFORM_SCALE = WebCore::SVG_TRANSFORM_SCALE,
+ SVG_TRANSFORM_ROTATE = WebCore::SVG_TRANSFORM_ROTATE,
+ SVG_TRANSFORM_SKEWX = WebCore::SVG_TRANSFORM_SKEWX,
+ SVG_TRANSFORM_SKEWY = WebCore::SVG_TRANSFORM_SKEWY,
+ };
+
+ static PassRefPtr<SVGTransformTearOff> create(PassRefPtr<SVGTransform> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ {
+ return adoptRef(new SVGTransformTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+ }
+
+ virtual ~SVGTransformTearOff();
+
+ unsigned short transformType() { return target()->transformType(); }
+ SVGMatrixTearOff* matrix();
+ float angle() { return target()->angle(); }
+
+ void setMatrix(PassRefPtr<SVGMatrixTearOff>, ExceptionState&);
+ void setTranslate(float tx, float ty, ExceptionState&);
+ void setScale(float sx, float sy, ExceptionState&);
+ void setRotate(float angle, float cx, float cy, ExceptionState&);
+ void setSkewX(float, ExceptionState&);
+ void setSkewY(float, ExceptionState&);
+
+private:
+ SVGTransformTearOff(PassRefPtr<SVGTransform>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName);
+
+ RefPtr<SVGMatrixTearOff> m_matrixTearoff;
+};
+
+} // namespace WebCore
+
+#endif // SVGTransformTearOff_h_
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.cpp
index 02cd99fa022..4a612b53e41 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.cpp
@@ -19,22 +19,19 @@
*/
#include "config.h"
-
#include "core/svg/SVGURIReference.h"
-#include "XLinkNames.h"
+#include "core/XLinkNames.h"
+#include "core/svg/SVGElement.h"
#include "platform/weborigin/KURL.h"
namespace WebCore {
-bool SVGURIReference::parseAttribute(const QualifiedName& name, const AtomicString& value)
+SVGURIReference::SVGURIReference(SVGElement* element)
+ : m_href(SVGAnimatedString::create(element, XLinkNames::hrefAttr, SVGString::create()))
{
- if (name.matches(XLinkNames::hrefAttr)) {
- setHrefBaseValue(value);
- return true;
- }
-
- return false;
+ ASSERT(element);
+ element->addToPropertyMap(m_href);
}
bool SVGURIReference::isKnownAttribute(const QualifiedName& attrName)
@@ -42,27 +39,30 @@ bool SVGURIReference::isKnownAttribute(const QualifiedName& attrName)
return attrName.matches(XLinkNames::hrefAttr);
}
-String SVGURIReference::fragmentIdentifierFromIRIString(const String& url, const Document& document)
+AtomicString SVGURIReference::fragmentIdentifierFromIRIString(const String& url, const TreeScope& treeScope)
{
size_t start = url.find('#');
if (start == kNotFound)
- return emptyString();
+ return emptyAtom;
+ const Document& document = treeScope.document();
KURL base = start ? KURL(document.baseURI(), url.substring(0, start)) : document.baseURI();
if (equalIgnoringFragmentIdentifier(base, document.url()))
- return url.substring(start + 1);
+ return AtomicString(url.substring(start + 1));
- return emptyString();
+ return emptyAtom;
}
-static inline KURL urlFromIRIStringWithFragmentIdentifier(const String& url, const Document& document, String& fragmentIdentifier)
+static inline KURL urlFromIRIStringWithFragmentIdentifier(const String& url, const TreeScope& treeScope, AtomicString& fragmentIdentifier)
{
size_t startOfFragmentIdentifier = url.find('#');
if (startOfFragmentIdentifier == kNotFound)
return KURL();
+ const Document& document = treeScope.document();
+
// Exclude the '#' character when determining the fragmentIdentifier.
- fragmentIdentifier = url.substring(startOfFragmentIdentifier + 1);
+ fragmentIdentifier = AtomicString(url.substring(startOfFragmentIdentifier + 1));
if (startOfFragmentIdentifier) {
KURL base(document.baseURI(), url.substring(0, startOfFragmentIdentifier));
return KURL(base, url.substring(startOfFragmentIdentifier));
@@ -71,10 +71,12 @@ static inline KURL urlFromIRIStringWithFragmentIdentifier(const String& url, con
return KURL(document.baseURI(), url.substring(startOfFragmentIdentifier));
}
-Element* SVGURIReference::targetElementFromIRIString(const String& iri, const Document& document, String* fragmentIdentifier, Document* externalDocument)
+Element* SVGURIReference::targetElementFromIRIString(const String& iri, const TreeScope& treeScope, AtomicString* fragmentIdentifier, Document* externalDocument)
{
+ const Document& document = treeScope.document();
+
// If there's no fragment identifier contained within the IRI string, we can't lookup an element.
- String id;
+ AtomicString id;
KURL url = urlFromIRIStringWithFragmentIdentifier(iri, document, id);
if (url == KURL())
return 0;
@@ -95,7 +97,7 @@ Element* SVGURIReference::targetElementFromIRIString(const String& iri, const Do
if (isExternalURIReference(iri, document))
return 0;
- return document.getElementById(id);
+ return treeScope.getElementById(id);
}
void SVGURIReference::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes)
@@ -103,4 +105,13 @@ void SVGURIReference::addSupportedAttributes(HashSet<QualifiedName>& supportedAt
supportedAttributes.add(XLinkNames::hrefAttr);
}
+bool SVGURIReference::parseAttribute(const QualifiedName& name, const AtomicString& value, SVGParsingError& parseError)
+{
+ if (name.matches(XLinkNames::hrefAttr)) {
+ m_href->setBaseValueAsString(value, parseError);
+ return true;
+ }
+ return false;
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.h b/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.h
index f73a23bd2bf..abecd903482 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.h
@@ -22,22 +22,21 @@
#define SVGURIReference_h
#include "core/dom/Document.h"
+#include "core/svg/SVGAnimatedString.h"
namespace WebCore {
-class Attribute;
class Element;
class SVGURIReference {
public:
virtual ~SVGURIReference() { }
- bool parseAttribute(const QualifiedName&, const AtomicString&);
bool isKnownAttribute(const QualifiedName&);
void addSupportedAttributes(HashSet<QualifiedName>&);
- static String fragmentIdentifierFromIRIString(const String&, const Document&);
- static Element* targetElementFromIRIString(const String&, const Document&, String* = 0, Document* = 0);
+ static AtomicString fragmentIdentifierFromIRIString(const String&, const TreeScope&);
+ static Element* targetElementFromIRIString(const String&, const TreeScope&, AtomicString* = 0, Document* = 0);
static inline bool isExternalURIReference(const String& uri, const Document& document)
{
@@ -50,8 +49,17 @@ public:
return !equalIgnoringFragmentIdentifier(url, document.url());
}
+ const String& hrefString() const { return m_href->currentValue()->value(); }
+ bool parseAttribute(const QualifiedName&, const AtomicString& value, SVGParsingError&);
+
+ // JS API
+ SVGAnimatedString* href() const { return m_href.get(); }
+
protected:
- virtual void setHrefBaseValue(const String&) = 0;
+ explicit SVGURIReference(SVGElement*);
+
+private:
+ RefPtr<SVGAnimatedString> m_href;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.idl b/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.idl
index bcc0efa771a..8a3f713ce13 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGURIReference.idl
@@ -24,10 +24,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG2/types.html#InterfaceSVGURIReference
+
[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
+ NoInterfaceObject, // Always used on target of 'implements'
] interface SVGURIReference {
readonly attribute SVGAnimatedString href;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp
new file mode 100644
index 00000000000..f98ae4b7350
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGUnitTypes.h"
+
+namespace WebCore {
+
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGUnitTypes::SVGUnitType>()
+{
+ DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+ if (entries.isEmpty()) {
+ entries.append(std::make_pair(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE, "userSpaceOnUse"));
+ entries.append(std::make_pair(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX, "objectBoundingBox"));
+ }
+ return entries;
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.h b/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.h
index 3920519cc47..c87ad037c6c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.h
@@ -20,7 +20,7 @@
#ifndef SVGUnitTypes_h
#define SVGUnitTypes_h
-#include "core/svg/properties/SVGPropertyTraits.h"
+#include "core/svg/SVGEnumeration.h"
#include "wtf/RefCounted.h"
namespace WebCore {
@@ -36,35 +36,7 @@ public:
private:
SVGUnitTypes() { }
};
-
-template<>
-struct SVGPropertyTraits<SVGUnitTypes::SVGUnitType> {
- static unsigned highestEnumValue() { return SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; }
-
- static String toString(SVGUnitTypes::SVGUnitType type)
- {
- switch (type) {
- case SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN:
- return emptyString();
- case SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE:
- return "userSpaceOnUse";
- case SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX:
- return "objectBoundingBox";
- }
-
- ASSERT_NOT_REACHED();
- return emptyString();
- }
-
- static SVGUnitTypes::SVGUnitType fromString(const String& value)
- {
- if (value == "userSpaceOnUse")
- return SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE;
- if (value == "objectBoundingBox")
- return SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
- return SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN;
- }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGUnitTypes::SVGUnitType>();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.idl b/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.idl
index 5f5ec2ec800..95c2a497ae3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGUnitTypes.idl
@@ -23,7 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGUnitTypes {
+[
+ DependentLifetime,
+] interface SVGUnitTypes {
// Unit Types
const unsigned short SVG_UNIT_TYPE_UNKNOWN = 0;
const unsigned short SVG_UNIT_TYPE_USERSPACEONUSE = 1;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp
index 3136a70b945..12ae62c0c53 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp
@@ -33,9 +33,11 @@
namespace WebCore {
-SVGUnknownElement::SVGUnknownElement(const QualifiedName& tagName, Document& document)
+inline SVGUnknownElement::SVGUnknownElement(const QualifiedName& tagName, Document& document)
: SVGElement(tagName, document)
{
}
+DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(SVGUnknownElement)
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.h
index 93dd832f52a..d99ac032d11 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGUnknownElement.h
@@ -41,12 +41,9 @@ namespace WebCore {
//
// The main purpose of this class at the moment is to override rendererIsNeeded() to return
// false to make sure we don't attempt to render such elements.
-class SVGUnknownElement : public SVGElement {
+class SVGUnknownElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGUnknownElement> create(const QualifiedName& tagName, Document& document)
- {
- return adoptRef(new SVGUnknownElement(tagName, document));
- }
+ DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(SVGUnknownElement);
private:
SVGUnknownElement(const QualifiedName&, Document&);
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
index 80d36bf97f3..a45d3228474 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.cpp
@@ -26,8 +26,8 @@
#include "core/svg/SVGUseElement.h"
-#include "XLinkNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/XLinkNames.h"
#include "core/dom/Document.h"
#include "core/dom/ElementTraversal.h"
#include "core/events/Event.h"
@@ -37,58 +37,37 @@
#include "core/fetch/ResourceFetcher.h"
#include "core/rendering/svg/RenderSVGResource.h"
#include "core/rendering/svg/RenderSVGTransformableContainer.h"
-#include "core/svg/SVGElementInstance.h"
#include "core/svg/SVGGElement.h"
#include "core/svg/SVGLengthContext.h"
#include "core/svg/SVGSVGElement.h"
#include "core/xml/parser/XMLDocumentParser.h"
-// Dump SVGElementInstance object tree - useful to debug instanceRoot problems
-// #define DUMP_INSTANCE_TREE
-
-// Dump the deep-expanded shadow tree (where the renderers are built from)
-// #define DUMP_SHADOW_TREE
-
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_LENGTH(SVGUseElement, SVGNames::xAttr, X, x)
-DEFINE_ANIMATED_LENGTH(SVGUseElement, SVGNames::yAttr, Y, y)
-DEFINE_ANIMATED_LENGTH(SVGUseElement, SVGNames::widthAttr, Width, width)
-DEFINE_ANIMATED_LENGTH(SVGUseElement, SVGNames::heightAttr, Height, height)
-DEFINE_ANIMATED_STRING(SVGUseElement, XLinkNames::hrefAttr, Href, href)
-DEFINE_ANIMATED_BOOLEAN(SVGUseElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGUseElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(x)
- REGISTER_LOCAL_ANIMATED_PROPERTY(y)
- REGISTER_LOCAL_ANIMATED_PROPERTY(width)
- REGISTER_LOCAL_ANIMATED_PROPERTY(height)
- REGISTER_LOCAL_ANIMATED_PROPERTY(href)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
-inline SVGUseElement::SVGUseElement(Document& document, bool wasInsertedByParser)
+inline SVGUseElement::SVGUseElement(Document& document)
: SVGGraphicsElement(SVGNames::useTag, document)
- , m_x(LengthModeWidth)
- , m_y(LengthModeHeight)
- , m_width(LengthModeWidth)
- , m_height(LengthModeHeight)
- , m_wasInsertedByParser(wasInsertedByParser)
+ , SVGURIReference(this)
+ , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth), AllowNegativeLengths))
+ , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight), AllowNegativeLengths))
+ , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth), ForbidNegativeLengths))
+ , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight), ForbidNegativeLengths))
, m_haveFiredLoadEvent(false)
, m_needsShadowTreeRecreation(false)
, m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired)
{
ASSERT(hasCustomStyleCallbacks());
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGUseElement();
+
+ addToPropertyMap(m_x);
+ addToPropertyMap(m_y);
+ addToPropertyMap(m_width);
+ addToPropertyMap(m_height);
}
-PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInsertedByParser)
+PassRefPtrWillBeRawPtr<SVGUseElement> SVGUseElement::create(Document& document)
{
- // Always build a #shadow-root for SVGUseElement.
- RefPtr<SVGUseElement> use = adoptRef(new SVGUseElement(document, wasInsertedByParser));
+ // Always build a user agent #shadow-root for SVGUseElement.
+ RefPtrWillBeRawPtr<SVGUseElement> use = adoptRefWillBeNoop(new SVGUseElement(document));
use->ensureUserAgentShadowRoot();
return use.release();
}
@@ -96,33 +75,15 @@ PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInse
SVGUseElement::~SVGUseElement()
{
setDocumentResource(0);
-
+#if !ENABLE(OILPAN)
clearResourceReferences();
-}
-
-SVGElementInstance* SVGUseElement::instanceRoot()
-{
- // If there is no element instance tree, force immediate SVGElementInstance tree
- // creation by asking the document to invoke our recalcStyle function - as we can't
- // wait for the lazy creation to happen if e.g. JS wants to access the instanceRoot
- // object right after creating the element on-the-fly
- if (!m_targetElementInstance)
- document().updateStyleIfNeeded();
-
- return m_targetElementInstance.get();
-}
-
-SVGElementInstance* SVGUseElement::animatedInstanceRoot() const
-{
- // FIXME: Implement me.
- return 0;
+#endif
}
bool SVGUseElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
SVGURIReference::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::xAttr);
supportedAttributes.add(SVGNames::yAttr);
@@ -136,28 +97,28 @@ void SVGUseElement::parseAttribute(const QualifiedName& name, const AtomicString
{
SVGParsingError parseError = NoError;
- if (!isSupportedAttribute(name))
+ if (!isSupportedAttribute(name)) {
SVGGraphicsElement::parseAttribute(name, value);
- else if (name == SVGNames::xAttr)
- setXBaseValue(SVGLength::construct(LengthModeWidth, value, parseError));
- else if (name == SVGNames::yAttr)
- setYBaseValue(SVGLength::construct(LengthModeHeight, value, parseError));
- else if (name == SVGNames::widthAttr)
- setWidthBaseValue(SVGLength::construct(LengthModeWidth, value, parseError, ForbidNegativeLengths));
- else if (name == SVGNames::heightAttr)
- setHeightBaseValue(SVGLength::construct(LengthModeHeight, value, parseError, ForbidNegativeLengths));
- else if (SVGExternalResourcesRequired::parseAttribute(name, value)
- || SVGURIReference::parseAttribute(name, value)) {
- } else
+ } else if (name == SVGNames::xAttr) {
+ m_x->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::yAttr) {
+ m_y->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::widthAttr) {
+ m_width->setBaseValueAsString(value, parseError);
+ } else if (name == SVGNames::heightAttr) {
+ m_height->setBaseValueAsString(value, parseError);
+ } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+ } else {
ASSERT_NOT_REACHED();
+ }
reportAttributeParsingError(parseError, name, value);
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
static inline bool isWellFormedDocument(Document* document)
{
- if (document->isSVGDocument() || document->isXHTMLDocument())
+ if (document->isXMLDocument())
return static_cast<XMLDocumentParser*>(document->parser())->wellFormed();
return true;
}
@@ -171,9 +132,9 @@ Node::InsertionNotificationRequest SVGUseElement::insertedInto(ContainerNode* ro
return InsertionDone;
ASSERT(!m_targetElementInstance || !isWellFormedDocument(&document()));
ASSERT(!hasPendingResources() || !isWellFormedDocument(&document()));
- if (!m_wasInsertedByParser)
- buildPendingResource();
- SVGExternalResourcesRequired::insertedIntoDocument(this);
+ invalidateShadowTree();
+ if (!isStructurallyExternal())
+ sendSVGLoadEventIfPossibleAsynchronously();
return InsertionDone;
}
@@ -184,10 +145,10 @@ void SVGUseElement::removedFrom(ContainerNode* rootParent)
clearResourceReferences();
}
-Document* SVGUseElement::referencedDocument() const
+TreeScope* SVGUseElement::referencedScope() const
{
- if (!isExternalURIReference(hrefCurrentValue(), document()))
- return &document();
+ if (!isExternalURIReference(hrefString(), document()))
+ return &treeScope();
return externalDocument();
}
@@ -203,6 +164,30 @@ Document* SVGUseElement::externalDocument() const
return 0;
}
+void transferUseWidthAndHeightIfNeeded(const SVGUseElement& use, SVGElement* shadowElement, const SVGElement& originalElement)
+{
+ ASSERT(shadowElement);
+ if (isSVGSymbolElement(*shadowElement)) {
+ // Spec (<use> on <symbol>): This generated 'svg' will always have explicit values for attributes width and height.
+ // If attributes width and/or height are provided on the 'use' element, then these attributes
+ // will be transferred to the generated 'svg'. If attributes width and/or height are not specified,
+ // the generated 'svg' element will use values of 100% for these attributes.
+ shadowElement->setAttribute(SVGNames::widthAttr, use.width()->isSpecified() ? AtomicString(use.width()->currentValue()->valueAsString()) : "100%");
+ shadowElement->setAttribute(SVGNames::heightAttr, use.height()->isSpecified() ? AtomicString(use.height()->currentValue()->valueAsString()) : "100%");
+ } else if (isSVGSVGElement(*shadowElement)) {
+ // Spec (<use> on <svg>): If attributes width and/or height are provided on the 'use' element, then these
+ // values will override the corresponding attributes on the 'svg' in the generated tree.
+ if (use.width()->isSpecified())
+ shadowElement->setAttribute(SVGNames::widthAttr, AtomicString(use.width()->currentValue()->valueAsString()));
+ else
+ shadowElement->setAttribute(SVGNames::widthAttr, originalElement.getAttribute(SVGNames::widthAttr));
+ if (use.height()->isSpecified())
+ shadowElement->setAttribute(SVGNames::heightAttr, AtomicString(use.height()->currentValue()->valueAsString()));
+ else
+ shadowElement->setAttribute(SVGNames::heightAttr, originalElement.getAttribute(SVGNames::heightAttr));
+ }
+}
+
void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
{
if (!isSupportedAttribute(attrName)) {
@@ -210,7 +195,7 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
return;
}
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
RenderObject* renderer = this->renderer();
if (attrName == SVGNames::xAttr
@@ -218,18 +203,19 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
|| attrName == SVGNames::widthAttr
|| attrName == SVGNames::heightAttr) {
updateRelativeLengthsInformation();
+ if (m_targetElementInstance) {
+ ASSERT(m_targetElementInstance->correspondingElement());
+ transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_targetElementInstance->correspondingElement());
+ }
if (renderer)
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
return;
}
- if (SVGExternalResourcesRequired::handleAttributeChange(this, attrName))
- return;
-
if (SVGURIReference::isKnownAttribute(attrName)) {
- bool isExternalReference = isExternalURIReference(hrefCurrentValue(), document());
+ bool isExternalReference = isExternalURIReference(hrefString(), document());
if (isExternalReference) {
- KURL url = document().completeURL(hrefCurrentValue());
+ KURL url = document().completeURL(hrefString());
if (url.hasFragmentIdentifier()) {
FetchRequest request(ResourceRequest(url.string()), localName());
setDocumentResource(document().fetcher()->fetchSVGDocument(request));
@@ -238,8 +224,7 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
setDocumentResource(0);
}
- if (!m_wasInsertedByParser)
- buildPendingResource();
+ invalidateShadowTree();
return;
}
@@ -247,81 +232,9 @@ void SVGUseElement::svgAttributeChanged(const QualifiedName& attrName)
if (!renderer)
return;
- if (SVGExternalResourcesRequired::isKnownAttribute(attrName)) {
- invalidateShadowTree();
- return;
- }
-
ASSERT_NOT_REACHED();
}
-void SVGUseElement::attach(const AttachContext& context)
-{
- if (m_needsShadowTreeRecreation)
- buildPendingResource();
- SVGGraphicsElement::attach(context);
-}
-
-void SVGUseElement::willRecalcStyle(StyleRecalcChange)
-{
- if (!m_wasInsertedByParser && m_needsShadowTreeRecreation && renderer() && needsStyleRecalc())
- buildPendingResource();
-}
-
-#ifdef DUMP_INSTANCE_TREE
-static void dumpInstanceTree(unsigned int& depth, String& text, SVGElementInstance* targetInstance)
-{
- SVGElement* element = targetInstance->correspondingElement();
- ASSERT(element);
-
- if (element->hasTagName(SVGNames::useTag)) {
- if (toSVGUseElement(element)->resourceIsStillLoading())
- return;
- }
-
- SVGElement* shadowTreeElement = targetInstance->shadowTreeElement();
- ASSERT(shadowTreeElement);
-
- SVGUseElement* directUseElement = targetInstance->directUseElement();
- String directUseElementName = directUseElement ? directUseElement->nodeName() : "null";
-
- String elementId = element->getIdAttribute();
- String elementNodeName = element->nodeName();
- String shadowTreeElementNodeName = shadowTreeElement->nodeName();
- String parentNodeName = element->parentNode() ? element->parentNode()->nodeName() : "null";
- String firstChildNodeName = element->firstChild() ? element->firstChild()->nodeName() : "null";
-
- for (unsigned int i = 0; i < depth; ++i)
- text += " ";
-
- text += String::format("SVGElementInstance this=%p, (parentNode=%s (%p), firstChild=%s (%p), correspondingElement=%s (%p), directUseElement=%s (%p), shadowTreeElement=%s (%p), id=%s)\n",
- targetInstance, parentNodeName.latin1().data(), element->parentNode(), firstChildNodeName.latin1().data(), element->firstChild(),
- elementNodeName.latin1().data(), element, directUseElementName.latin1().data(), directUseElement, shadowTreeElementNodeName.latin1().data(), shadowTreeElement, elementId.latin1().data());
-
- for (unsigned int i = 0; i < depth; ++i)
- text += " ";
-
- const HashSet<SVGElementInstance*>& elementInstances = element->instancesForElement();
- text += "Corresponding element is associated with " + String::number(elementInstances.size()) + " instance(s):\n";
-
- const HashSet<SVGElementInstance*>::const_iterator end = elementInstances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = elementInstances.begin(); it != end; ++it) {
- for (unsigned int i = 0; i < depth; ++i)
- text += " ";
-
- text += String::format(" -> SVGElementInstance this=%p, (refCount: %i, shadowTreeElement in document? %i)\n",
- *it, (*it)->refCount(), (*it)->shadowTreeElement()->inDocument());
- }
-
- ++depth;
-
- for (SVGElementInstance* instance = targetInstance->firstChild(); instance; instance = instance->nextSibling())
- dumpInstanceTree(depth, text, instance);
-
- --depth;
-}
-#endif
-
static bool isDisallowedElement(Node* node)
{
// Spec: "Any 'svg', 'symbol', 'g', graphics element or other 'use' is potentially a template object that can be re-used
@@ -376,32 +289,39 @@ static bool subtreeContainsDisallowedElement(Node* start)
return false;
}
+void SVGUseElement::scheduleShadowTreeRecreation()
+{
+ if (!referencedScope() || inUseShadowTree())
+ return;
+ m_needsShadowTreeRecreation = true;
+ document().scheduleUseShadowTreeUpdate(*this);
+}
+
void SVGUseElement::clearResourceReferences()
{
+ if (m_targetElementInstance)
+ m_targetElementInstance = nullptr;
+
// FIXME: We should try to optimize this, to at least allow partial reclones.
if (ShadowRoot* shadowTreeRootElement = userAgentShadowRoot())
shadowTreeRootElement->removeChildren();
- if (m_targetElementInstance) {
- m_targetElementInstance->detach();
- m_targetElementInstance = 0;
- }
-
m_needsShadowTreeRecreation = false;
+ document().unscheduleUseShadowTreeUpdate(*this);
- document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+ document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
}
void SVGUseElement::buildPendingResource()
{
- if (!referencedDocument() || isInShadowTree())
+ if (!referencedScope() || inUseShadowTree())
return;
clearResourceReferences();
if (!inDocument())
return;
- String id;
- Element* target = SVGURIReference::targetElementFromIRIString(hrefCurrentValue(), document(), &id, externalDocument());
+ AtomicString id;
+ Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), treeScope(), &id, externalDocument());
if (!target || !target->inDocument()) {
// If we can't find the target of an external element, just give up.
// We can't observe if the target somewhen enters the external document, nor should we do it.
@@ -410,7 +330,7 @@ void SVGUseElement::buildPendingResource()
if (id.isEmpty())
return;
- referencedDocument()->accessSVGExtensions()->addPendingResource(id, this);
+ referencedScope()->document().accessSVGExtensions().addPendingResource(id, this);
ASSERT(hasPendingResources());
return;
}
@@ -423,13 +343,31 @@ void SVGUseElement::buildPendingResource()
ASSERT(!m_needsShadowTreeRecreation);
}
+static PassRefPtrWillBeRawPtr<Node> cloneNodeAndAssociate(Node& toClone)
+{
+ RefPtrWillBeRawPtr<Node> clone = toClone.cloneNode(false);
+ if (!clone->isSVGElement())
+ return clone.release();
+
+ SVGElement& svgElement = toSVGElement(toClone);
+ ASSERT(!svgElement.correspondingElement());
+ toSVGElement(clone.get())->setCorrespondingElement(&svgElement);
+ if (EventTargetData* data = toClone.eventTargetData())
+ data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(clone.get());
+ TrackExceptionState exceptionState;
+ for (Node* node = toClone.firstChild(); node && !exceptionState.hadException(); node = node->nextSibling())
+ clone->appendChild(cloneNodeAndAssociate(*node), exceptionState);
+ return clone.release();
+}
+
void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target)
{
ASSERT(!m_targetElementInstance);
- // Do not build the shadow/instance tree for <use> elements living in a shadow tree.
- // The will be expanded soon anyway - see expandUseElementsInShadowTree().
- if (isInShadowTree())
+ // <use> creates a "user agent" shadow root. Do not build the shadow/instance tree for <use>
+ // elements living in a user agent shadow tree because they will get expanded in a second
+ // pass -- see expandUseElementsInShadowTree().
+ if (inUseShadowTree())
return;
// Do not allow self-referencing.
@@ -437,89 +375,47 @@ void SVGUseElement::buildShadowAndInstanceTree(SVGElement* target)
if (!target || target == this)
return;
- // Why a seperated instance/shadow tree? SVG demands it:
- // The instance tree is accesable from JavaScript, and has to
- // expose a 1:1 copy of the referenced tree, whereas internally we need
- // to alter the tree for correct "use-on-symbol", "use-on-svg" support.
-
- // Build instance tree. Create root SVGElementInstance object for the first sub-tree node.
- //
- // Spec: If the 'use' element references a simple graphics element such as a 'rect', then there is only a
- // single SVGElementInstance object, and the correspondingElement attribute on this SVGElementInstance object
- // is the SVGRectElement that corresponds to the referenced 'rect' element.
- m_targetElementInstance = SVGElementInstance::create(this, this, target);
+ // Set up root SVG element in shadow tree.
+ RefPtrWillBeRawPtr<Element> newChild = target->cloneElementWithoutChildren();
+ m_targetElementInstance = toSVGElement(newChild.get());
+ ShadowRoot* shadowTreeRootElement = userAgentShadowRoot();
+ shadowTreeRootElement->appendChild(newChild.release());
- // Eventually enter recursion to build SVGElementInstance objects for the sub-tree children
- bool foundProblem = false;
- buildInstanceTree(target, m_targetElementInstance.get(), foundProblem, false);
-
- if (instanceTreeIsLoading(m_targetElementInstance.get()))
- return;
+ // Clone the target subtree into the shadow tree, not handling <use> and <symbol> yet.
// SVG specification does not say a word about <use> & cycles. My view on this is: just ignore it!
// Non-appearing <use> content is easier to debug, then half-appearing content.
- if (foundProblem) {
+ if (!buildShadowTree(target, m_targetElementInstance.get(), false)) {
clearResourceReferences();
return;
}
- // Assure instance tree building was successfull
+ if (instanceTreeIsLoading(m_targetElementInstance.get()))
+ return;
+
+ // Assure shadow tree building was successfull
ASSERT(m_targetElementInstance);
- ASSERT(!m_targetElementInstance->shadowTreeElement());
ASSERT(m_targetElementInstance->correspondingUseElement() == this);
- ASSERT(m_targetElementInstance->directUseElement() == this);
ASSERT(m_targetElementInstance->correspondingElement() == target);
- ShadowRoot* shadowTreeRootElement = userAgentShadowRoot();
- ASSERT(shadowTreeRootElement);
-
- // Build shadow tree from instance tree
- // This also handles the special cases: <use> on <symbol>, <use> on <svg>.
- buildShadowTree(target, m_targetElementInstance.get());
-
// Expand all <use> elements in the shadow tree.
// Expand means: replace the actual <use> element by what it references.
- expandUseElementsInShadowTree(shadowTreeRootElement);
-
- // Expand all <symbol> elements in the shadow tree.
- // Expand means: replace the actual <symbol> element by the <svg> element.
- expandSymbolElementsInShadowTree(shadowTreeRootElement);
-
- // Now that the shadow tree is completly expanded, we can associate
- // shadow tree elements <-> instances in the instance tree.
- associateInstancesWithShadowTreeElements(shadowTreeRootElement->firstChild(), m_targetElementInstance.get());
-
- // If no shadow tree element is present, this means that the reference root
- // element was removed, as it is disallowed (ie. <use> on <foreignObject>)
- // Do NOT leave an inconsistent instance tree around, instead destruct it.
- if (!m_targetElementInstance->shadowTreeElement()) {
+ if (!expandUseElementsInShadowTree(m_targetElementInstance.get())) {
clearResourceReferences();
return;
}
- ASSERT(m_targetElementInstance->shadowTreeElement()->parentNode() == shadowTreeRootElement);
+ // Expand all <symbol> elements in the shadow tree.
+ // Expand means: replace the actual <symbol> element by the <svg> element.
+ expandSymbolElementsInShadowTree(toSVGElement(shadowTreeRootElement->firstChild()));
+
+ m_targetElementInstance = toSVGElement(shadowTreeRootElement->firstChild());
+ transferUseWidthAndHeightIfNeeded(*this, m_targetElementInstance.get(), *m_targetElementInstance->correspondingElement());
- // Transfer event listeners assigned to the referenced element to our shadow tree elements.
- transferEventListenersToShadowTree(m_targetElementInstance.get());
+ ASSERT(m_targetElementInstance->parentNode() == shadowTreeRootElement);
// Update relative length information.
updateRelativeLengthsInformation();
-
- // Eventually dump instance tree
-#ifdef DUMP_INSTANCE_TREE
- String text;
- unsigned int depth = 0;
-
- dumpInstanceTree(depth, text, m_targetElementInstance.get());
- fprintf(stderr, "\nDumping <use> instance tree:\n%s\n", text.latin1().data());
-#endif
-
- // Eventually dump shadow tree
-#ifdef DUMP_SHADOW_TREE
- RefPtr<XMLSerializer> serializer = XMLSerializer::create();
- String markup = serializer->serializeToString(shadowTreeRootElement, ASSERT_NO_EXCEPTION);
- fprintf(stderr, "Dumping <use> shadow tree markup:\n%s\n", markup.latin1().data());
-#endif
}
RenderObject* SVGUseElement::createRenderer(RenderStyle*)
@@ -527,34 +423,34 @@ RenderObject* SVGUseElement::createRenderer(RenderStyle*)
return new RenderSVGTransformableContainer(this);
}
-static bool isDirectReference(const Node* node)
+static bool isDirectReference(const Node& node)
{
- return node->hasTagName(SVGNames::pathTag)
- || node->hasTagName(SVGNames::rectTag)
- || node->hasTagName(SVGNames::circleTag)
- || node->hasTagName(SVGNames::ellipseTag)
- || node->hasTagName(SVGNames::polygonTag)
- || node->hasTagName(SVGNames::polylineTag)
- || node->hasTagName(SVGNames::textTag);
+ return isSVGPathElement(node)
+ || isSVGRectElement(node)
+ || isSVGCircleElement(node)
+ || isSVGEllipseElement(node)
+ || isSVGPolygonElement(node)
+ || isSVGPolylineElement(node)
+ || isSVGTextElement(node);
}
void SVGUseElement::toClipPath(Path& path)
{
ASSERT(path.isEmpty());
- Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0;
+ Node* n = userAgentShadowRoot()->firstChild();
if (!n)
return;
if (n->isSVGElement() && toSVGElement(n)->isSVGGraphicsElement()) {
- if (!isDirectReference(n)) {
+ if (!isDirectReference(*n)) {
// Spec: Indirect references are an error (14.3.5)
- document().accessSVGExtensions()->reportError("Not allowed to use indirect reference in <clip-path>");
+ document().accessSVGExtensions().reportError("Not allowed to use indirect reference in <clip-path>");
} else {
toSVGGraphicsElement(n)->toClipPath(path);
// FIXME: Avoid manual resolution of x/y here. Its potentially harmful.
SVGLengthContext lengthContext(this);
- path.translate(FloatSize(xCurrentValue().value(lengthContext), yCurrentValue().value(lengthContext)));
+ path.translate(FloatSize(m_x->currentValue()->value(lengthContext), m_y->currentValue()->value(lengthContext)));
path.transform(animatedLocalTransform());
}
}
@@ -562,81 +458,56 @@ void SVGUseElement::toClipPath(Path& path)
RenderObject* SVGUseElement::rendererClipChild() const
{
- Node* n = m_targetElementInstance ? m_targetElementInstance->shadowTreeElement() : 0;
- if (!n)
- return 0;
-
- if (n->isSVGElement() && isDirectReference(n))
- return toSVGElement(n)->renderer();
+ if (Node* n = userAgentShadowRoot()->firstChild()) {
+ if (n->isSVGElement() && isDirectReference(*n))
+ return toSVGElement(n)->renderer();
+ }
return 0;
}
-void SVGUseElement::buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundProblem, bool foundUse)
+bool SVGUseElement::buildShadowTree(SVGElement* target, SVGElement* targetInstance, bool foundUse)
{
ASSERT(target);
ASSERT(targetInstance);
// Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced
// object, the instance tree will contain recursive expansion of the indirect references to form a complete tree.
- bool targetHasUseTag = target->hasTagName(SVGNames::useTag);
- SVGElement* newTarget = 0;
- if (targetHasUseTag) {
- foundProblem = hasCycleUseReferencing(toSVGUseElement(target), targetInstance, newTarget);
- if (foundProblem)
- return;
-
+ if (isSVGUseElement(*target)) {
// We only need to track first degree <use> dependencies. Indirect references are handled
// as the invalidation bubbles up the dependency chain.
if (!foundUse) {
- document().accessSVGExtensions()->addElementReferencingTarget(this, target);
+ document().accessSVGExtensions().addElementReferencingTarget(this, target);
foundUse = true;
}
} else if (isDisallowedElement(target)) {
- foundProblem = true;
- return;
+ return false;
}
- // A general description from the SVG spec, describing what buildInstanceTree() actually does.
- //
- // Spec: If the 'use' element references a 'g' which contains two 'rect' elements, then the instance tree
- // contains three SVGElementInstance objects, a root SVGElementInstance object whose correspondingElement
- // is the SVGGElement object for the 'g', and then two child SVGElementInstance objects, each of which has
- // its correspondingElement that is an SVGRectElement object.
-
- for (Node* node = target->firstChild(); node; node = node->nextSibling()) {
- SVGElement* element = 0;
- if (node->isSVGElement())
- element = toSVGElement(node);
-
- // Skip any non-svg nodes or any disallowed element.
- if (!element || isDisallowedElement(element))
- continue;
+ targetInstance->setCorrespondingElement(target);
+ if (EventTargetData* data = target->eventTargetData())
+ data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(targetInstance);
- // Create SVGElementInstance object, for both container/non-container nodes.
- RefPtr<SVGElementInstance> instance = SVGElementInstance::create(this, 0, element);
- SVGElementInstance* instancePtr = instance.get();
- targetInstance->appendChild(instance.release());
+ for (Node* child = target->firstChild(); child; child = child->nextSibling()) {
+ // Skip any disallowed element.
+ if (isDisallowedElement(child))
+ continue;
- // Enter recursion, appending new instance tree nodes to the "instance" object.
- buildInstanceTree(element, instancePtr, foundProblem, foundUse);
- if (foundProblem)
- return;
+ RefPtrWillBeRawPtr<Node> newChild = child->cloneNode(false);
+ targetInstance->appendChild(newChild.get());
+ if (newChild->isSVGElement()) {
+ // Enter recursion, appending new instance tree nodes to the "instance" object.
+ if (!buildShadowTree(toSVGElement(child), toSVGElement(newChild), foundUse))
+ return false;
+ }
}
-
- if (!targetHasUseTag || !newTarget)
- return;
-
- RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, toSVGUseElement(target), newTarget);
- SVGElementInstance* newInstancePtr = newInstance.get();
- targetInstance->appendChild(newInstance.release());
- buildInstanceTree(newTarget, newInstancePtr, foundProblem, foundUse);
+ return true;
}
-bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstance* targetInstance, SVGElement*& newTarget)
+bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, ContainerNode* targetInstance, SVGElement*& newTarget)
{
- ASSERT(referencedDocument());
- Element* targetElement = SVGURIReference::targetElementFromIRIString(use->hrefCurrentValue(), *referencedDocument());
+ ASSERT(referencedScope());
+ Element* targetElement = SVGURIReference::targetElementFromIRIString(use->hrefString(), *referencedScope());
newTarget = 0;
if (targetElement && targetElement->isSVGElement())
newTarget = toSVGElement(targetElement);
@@ -649,10 +520,9 @@ bool SVGUseElement::hasCycleUseReferencing(SVGUseElement* use, SVGElementInstanc
return true;
AtomicString targetId = newTarget->getIdAttribute();
- SVGElementInstance* instance = targetInstance->parentNode();
- while (instance) {
- SVGElement* element = instance->correspondingElement();
-
+ ContainerNode* instance = targetInstance->parentNode();
+ while (instance && instance->isSVGElement()) {
+ SVGElement* element = toSVGElement(instance);
if (element->hasID() && element->getIdAttribute() == targetId && element->document() == newTarget->document())
return true;
@@ -677,56 +547,46 @@ static inline void removeDisallowedElementsFromSubtree(Element& subtree)
}
}
-void SVGUseElement::buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance)
-{
- // For instance <use> on <foreignObject> (direct case).
- if (isDisallowedElement(target))
- return;
-
- RefPtr<Element> newChild = targetInstance->correspondingElement()->cloneElementWithChildren();
-
- // We don't walk the target tree element-by-element, and clone each element,
- // but instead use cloneElementWithChildren(). This is an optimization for the common
- // case where <use> doesn't contain disallowed elements (ie. <foreignObject>).
- // Though if there are disallowed elements in the subtree, we have to remove them.
- // For instance: <use> on <g> containing <foreignObject> (indirect case).
- if (subtreeContainsDisallowedElement(newChild.get()))
- removeDisallowedElementsFromSubtree(*newChild);
-
- userAgentShadowRoot()->appendChild(newChild.release());
-}
-
-void SVGUseElement::expandUseElementsInShadowTree(Node* element)
+bool SVGUseElement::expandUseElementsInShadowTree(SVGElement* element)
{
+ ASSERT(element);
// Why expand the <use> elements in the shadow tree here, and not just
// do this directly in buildShadowTree, if we encounter a <use> element?
//
- // Short answer: Because we may miss to expand some elements. Ie. if a <symbol>
- // contains <use> tags, we'd miss them. So once we're done with settin' up the
+ // Short answer: Because we may miss to expand some elements. For example, if a <symbol>
+ // contains <use> tags, we'd miss them. So once we're done with setting up the
// actual shadow tree (after the special case modification for svg/symbol) we have
// to walk it completely and expand all <use> elements.
- if (element->hasTagName(SVGNames::useTag)) {
+ if (isSVGUseElement(*element)) {
SVGUseElement* use = toSVGUseElement(element);
ASSERT(!use->resourceIsStillLoading());
- ASSERT(referencedDocument());
- Element* targetElement = SVGURIReference::targetElementFromIRIString(use->hrefCurrentValue(), *referencedDocument());
SVGElement* target = 0;
- if (targetElement && targetElement->isSVGElement())
- target = toSVGElement(targetElement);
+ if (hasCycleUseReferencing(toSVGUseElement(use->correspondingElement()), use, target))
+ return false;
+ if (target && isDisallowedElement(target))
+ return false;
// Don't ASSERT(target) here, it may be "pending", too.
// Setup sub-shadow tree root node
- RefPtr<SVGGElement> cloneParent = SVGGElement::create(*referencedDocument());
- use->cloneChildNodes(cloneParent.get());
+ RefPtrWillBeRawPtr<SVGGElement> cloneParent = SVGGElement::create(referencedScope()->document());
+ cloneParent->setCorrespondingElement(use->correspondingElement());
+
+ // Move already cloned elements to the new <g> element
+ for (Node* child = use->firstChild(); child; ) {
+ Node* nextChild = child->nextSibling();
+ cloneParent->appendChild(child);
+ child = nextChild;
+ }
// Spec: In the generated content, the 'use' will be replaced by 'g', where all attributes from the
// 'use' element except for x, y, width, height and xlink:href are transferred to the generated 'g' element.
transferUseAttributesToReplacedElement(use, cloneParent.get());
- if (target && !isDisallowedElement(target)) {
- RefPtr<Element> newChild = target->cloneElementWithChildren();
+ if (target) {
+ RefPtrWillBeRawPtr<Node> newChild = cloneNodeAndAssociate(*target);
ASSERT(newChild->isSVGElement());
+ transferUseWidthAndHeightIfNeeded(*use, toSVGElement(newChild.get()), *target);
cloneParent->appendChild(newChild.release());
}
@@ -738,7 +598,7 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
if (subtreeContainsDisallowedElement(cloneParent.get()))
removeDisallowedElementsFromSubtree(*cloneParent);
- RefPtr<Node> replacingElement(cloneParent.get());
+ RefPtrWillBeRawPtr<SVGElement> replacingElement(cloneParent.get());
// Replace <use> with referenced content.
ASSERT(use->parentNode());
@@ -747,33 +607,40 @@ void SVGUseElement::expandUseElementsInShadowTree(Node* element)
// Expand the siblings because the *element* is replaced and we will
// lose the sibling chain when we are back from recursion.
element = replacingElement.get();
- for (RefPtr<Node> sibling = element->nextSibling(); sibling; sibling = sibling->nextSibling())
- expandUseElementsInShadowTree(sibling.get());
+ for (RefPtrWillBeRawPtr<SVGElement> sibling = Traversal<SVGElement>::nextSibling(*element); sibling; sibling = Traversal<SVGElement>::nextSibling(*sibling)) {
+ if (!expandUseElementsInShadowTree(sibling.get()))
+ return false;
+ }
}
- for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling())
- expandUseElementsInShadowTree(child.get());
+ for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChild(*element); child; child = Traversal<SVGElement>::nextSibling(*child)) {
+ if (!expandUseElementsInShadowTree(child.get()))
+ return false;
+ }
+ return true;
}
-void SVGUseElement::expandSymbolElementsInShadowTree(Node* element)
+void SVGUseElement::expandSymbolElementsInShadowTree(SVGElement* element)
{
- if (element->hasTagName(SVGNames::symbolTag)) {
+ ASSERT(element);
+ if (isSVGSymbolElement(*element)) {
// Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree,
// with the exception that the 'symbol' is replaced by an 'svg'. This generated 'svg' will
// always have explicit values for attributes width and height. If attributes width and/or
// height are provided on the 'use' element, then these attributes will be transferred to
// the generated 'svg'. If attributes width and/or height are not specified, the generated
// 'svg' element will use values of 100% for these attributes.
- ASSERT(referencedDocument());
- RefPtr<SVGSVGElement> svgElement = SVGSVGElement::create(*referencedDocument());
-
+ ASSERT(referencedScope());
+ RefPtrWillBeRawPtr<SVGSVGElement> svgElement = SVGSVGElement::create(referencedScope()->document());
// Transfer all data (attributes, etc.) from <symbol> to the new <svg> element.
- svgElement->cloneDataFromElement(*toElement(element));
-
- // Only clone symbol children, and add them to the new <svg> element
- for (Node* child = element->firstChild(); child; child = child->nextSibling()) {
- RefPtr<Node> newChild = child->cloneNode(true);
- svgElement->appendChild(newChild.release());
+ svgElement->cloneDataFromElement(*element);
+ svgElement->setCorrespondingElement(element->correspondingElement());
+
+ // Move already cloned elements to the new <svg> element
+ for (Node* child = element->firstChild(); child; ) {
+ Node* nextChild = child->nextSibling();
+ svgElement->appendChild(child);
+ child = nextChild;
}
// We don't walk the target tree element-by-element, and clone each element,
@@ -784,123 +651,35 @@ void SVGUseElement::expandSymbolElementsInShadowTree(Node* element)
if (subtreeContainsDisallowedElement(svgElement.get()))
removeDisallowedElementsFromSubtree(*svgElement);
- RefPtr<Node> replacingElement(svgElement.get());
+ RefPtrWillBeRawPtr<SVGElement> replacingElement(svgElement.get());
// Replace <symbol> with <svg>.
+ ASSERT(element->parentNode());
element->parentNode()->replaceChild(svgElement.release(), element);
// Expand the siblings because the *element* is replaced and we will
// lose the sibling chain when we are back from recursion.
element = replacingElement.get();
- for (RefPtr<Node> sibling = element->nextSibling(); sibling; sibling = sibling->nextSibling())
- expandSymbolElementsInShadowTree(sibling.get());
}
- for (RefPtr<Node> child = element->firstChild(); child; child = child->nextSibling())
+ for (RefPtrWillBeRawPtr<SVGElement> child = Traversal<SVGElement>::firstChild(*element); child; child = Traversal<SVGElement>::nextSibling(*child))
expandSymbolElementsInShadowTree(child.get());
}
-void SVGUseElement::transferEventListenersToShadowTree(SVGElementInstance* target)
-{
- if (!target)
- return;
-
- SVGElement* originalElement = target->correspondingElement();
- ASSERT(originalElement);
-
- if (SVGElement* shadowTreeElement = target->shadowTreeElement()) {
- if (EventTargetData* data = originalElement->eventTargetData())
- data->eventListenerMap.copyEventListenersNotCreatedFromMarkupToTarget(shadowTreeElement);
- }
-
- for (SVGElementInstance* instance = target->firstChild(); instance; instance = instance->nextSibling())
- transferEventListenersToShadowTree(instance);
-}
-
-void SVGUseElement::associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance)
-{
- if (!target || !targetInstance)
- return;
-
- SVGElement* originalElement = targetInstance->correspondingElement();
-
- if (originalElement->hasTagName(SVGNames::useTag)) {
- // <use> gets replaced by <g>
- ASSERT(target->nodeName() == SVGNames::gTag);
- } else if (originalElement->hasTagName(SVGNames::symbolTag)) {
- // <symbol> gets replaced by <svg>
- ASSERT(target->nodeName() == SVGNames::svgTag);
- } else
- ASSERT(target->nodeName() == originalElement->nodeName());
-
- SVGElement* element = 0;
- if (target->isSVGElement())
- element = toSVGElement(target);
-
- ASSERT(!targetInstance->shadowTreeElement());
- targetInstance->setShadowTreeElement(element);
- element->setCorrespondingElement(originalElement);
-
- Node* node = target->firstChild();
- for (SVGElementInstance* instance = targetInstance->firstChild(); node && instance; instance = instance->nextSibling()) {
- // Skip any non-svg elements in shadow tree
- while (node && !node->isSVGElement())
- node = node->nextSibling();
-
- if (!node)
- break;
-
- associateInstancesWithShadowTreeElements(node, instance);
- node = node->nextSibling();
- }
-}
-
-SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element) const
-{
- if (!m_targetElementInstance) {
- ASSERT(!inDocument());
- return 0;
- }
-
- return instanceForShadowTreeElement(element, m_targetElementInstance.get());
-}
-
-SVGElementInstance* SVGUseElement::instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const
-{
- ASSERT(element);
- ASSERT(instance);
-
- // We're dispatching a mutation event during shadow tree construction
- // this instance hasn't yet been associated to a shadowTree element.
- if (!instance->shadowTreeElement())
- return 0;
-
- if (element == instance->shadowTreeElement())
- return instance;
-
- for (SVGElementInstance* current = instance->firstChild(); current; current = current->nextSibling()) {
- if (SVGElementInstance* search = instanceForShadowTreeElement(element, current))
- return search;
- }
-
- return 0;
-}
-
void SVGUseElement::invalidateShadowTree()
{
if (!inActiveDocument() || m_needsShadowTreeRecreation)
return;
- m_needsShadowTreeRecreation = true;
- setNeedsStyleRecalc();
+ scheduleShadowTreeRecreation();
invalidateDependentShadowTrees();
}
void SVGUseElement::invalidateDependentShadowTrees()
{
// Recursively invalidate dependent <use> shadow trees
- const HashSet<SVGElementInstance*>& instances = instancesForElement();
- const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
- for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >& instances = instancesForElement();
+ const WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator end = instances.end();
+ for (WillBeHeapHashSet<RawPtrWillBeWeakMember<SVGElement> >::const_iterator it = instances.begin(); it != end; ++it) {
if (SVGUseElement* element = (*it)->correspondingUseElement()) {
ASSERT(element->inDocument());
element->invalidateShadowTree();
@@ -924,20 +703,16 @@ void SVGUseElement::transferUseAttributesToReplacedElement(SVGElement* from, SVG
bool SVGUseElement::selfHasRelativeLengths() const
{
- if (xCurrentValue().isRelative()
- || yCurrentValue().isRelative()
- || widthCurrentValue().isRelative()
- || heightCurrentValue().isRelative())
+ if (m_x->currentValue()->isRelative()
+ || m_y->currentValue()->isRelative()
+ || m_width->currentValue()->isRelative()
+ || m_height->currentValue()->isRelative())
return true;
if (!m_targetElementInstance)
return false;
- SVGElement* element = m_targetElementInstance->correspondingElement();
- if (!element)
- return false;
-
- return element->hasRelativeLengths();
+ return m_targetElementInstance->hasRelativeLengths();
}
void SVGUseElement::notifyFinished(Resource* resource)
@@ -948,8 +723,15 @@ void SVGUseElement::notifyFinished(Resource* resource)
invalidateShadowTree();
if (resource->errorOccurred())
dispatchEvent(Event::create(EventTypeNames::error));
- else if (!resource->wasCanceled())
- SVGExternalResourcesRequired::dispatchLoadEvent(this);
+ else if (!resource->wasCanceled()) {
+ if (m_haveFiredLoadEvent)
+ return;
+ if (!isStructurallyExternal())
+ return;
+ ASSERT(!m_haveFiredLoadEvent);
+ m_haveFiredLoadEvent = true;
+ sendSVGLoadEventIfPossibleAsynchronously();
+ }
}
bool SVGUseElement::resourceIsStillLoading()
@@ -959,29 +741,19 @@ bool SVGUseElement::resourceIsStillLoading()
return false;
}
-bool SVGUseElement::instanceTreeIsLoading(SVGElementInstance* targetElementInstance)
+bool SVGUseElement::instanceTreeIsLoading(SVGElement* targetInstance)
{
- for (SVGElementInstance* instance = targetElementInstance->firstChild(); instance; instance = instance->nextSibling()) {
- if (SVGUseElement* use = instance->correspondingUseElement()) {
+ for (SVGElement* element = Traversal<SVGElement>::firstChild(*targetInstance); element; element = Traversal<SVGElement>::nextSibling(*element)) {
+ if (SVGUseElement* use = element->correspondingUseElement()) {
if (use->resourceIsStillLoading())
return true;
}
- if (instance->hasChildNodes())
- instanceTreeIsLoading(instance);
+ if (element->hasChildren() && instanceTreeIsLoading(element))
+ return true;
}
return false;
}
-void SVGUseElement::finishParsingChildren()
-{
- SVGGraphicsElement::finishParsingChildren();
- SVGExternalResourcesRequired::finishParsingChildren();
- if (m_wasInsertedByParser) {
- buildPendingResource();
- m_wasInsertedByParser = false;
- }
-}
-
void SVGUseElement::setDocumentResource(ResourcePtr<DocumentResource> resource)
{
if (m_resource == resource)
@@ -995,4 +767,10 @@ void SVGUseElement::setDocumentResource(ResourcePtr<DocumentResource> resource)
m_resource->addClient(this);
}
+void SVGUseElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_targetElementInstance);
+ SVGGraphicsElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.h
index 800af8f7c80..b1e3bec3e01 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.h
@@ -21,113 +21,91 @@
#ifndef SVGUseElement_h
#define SVGUseElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/fetch/DocumentResource.h"
#include "core/svg/SVGAnimatedBoolean.h"
#include "core/svg/SVGAnimatedLength.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGGraphicsElement.h"
#include "core/svg/SVGURIReference.h"
namespace WebCore {
class DocumentResource;
-class SVGElementInstance;
class SVGUseElement FINAL : public SVGGraphicsElement,
- public SVGExternalResourcesRequired,
public SVGURIReference,
public DocumentResourceClient {
public:
- static PassRefPtr<SVGUseElement> create(Document&, bool wasInsertedByParser);
+ static PassRefPtrWillBeRawPtr<SVGUseElement> create(Document&);
virtual ~SVGUseElement();
- SVGElementInstance* instanceRoot();
- SVGElementInstance* animatedInstanceRoot() const;
- SVGElementInstance* instanceForShadowTreeElement(Node*) const;
void invalidateShadowTree();
- void invalidateDependentShadowTrees();
RenderObject* rendererClipChild() const;
+ SVGAnimatedLength* x() const { return m_x.get(); }
+ SVGAnimatedLength* y() const { return m_y.get(); }
+ SVGAnimatedLength* width() const { return m_width.get(); }
+ SVGAnimatedLength* height() const { return m_height.get(); }
+
+ virtual void buildPendingResource() OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- SVGUseElement(Document&, bool wasInsertedByParser);
+ explicit SVGUseElement(Document&);
- virtual bool isValid() const { return SVGTests::isValid(); }
- virtual bool supportsFocus() const OVERRIDE { return hasFocusEventListeners(); }
+ virtual bool isStructurallyExternal() const OVERRIDE { return !hrefString().isNull() && isExternalURIReference(hrefString(), document()); }
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual void buildPendingResource();
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual void svgAttributeChanged(const QualifiedName&);
-
- virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
- virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
+ virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
- virtual RenderObject* createRenderer(RenderStyle*);
- virtual void toClipPath(Path&);
+ virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
+ virtual void toClipPath(Path&) OVERRIDE;
void clearResourceReferences();
void buildShadowAndInstanceTree(SVGElement* target);
- void detachInstance();
- virtual bool haveLoadedRequiredResources() { return SVGExternalResourcesRequired::haveLoadedRequiredResources(); }
+ void scheduleShadowTreeRecreation();
+ virtual bool haveLoadedRequiredResources() OVERRIDE { return !isStructurallyExternal() || m_haveFiredLoadEvent; }
- virtual void finishParsingChildren();
- virtual bool selfHasRelativeLengths() const;
+ virtual bool selfHasRelativeLengths() const OVERRIDE;
// Instance tree handling
- void buildInstanceTree(SVGElement* target, SVGElementInstance* targetInstance, bool& foundCycle, bool foundUse);
- bool hasCycleUseReferencing(SVGUseElement*, SVGElementInstance* targetInstance, SVGElement*& newTarget);
-
- // Shadow tree handling
- void buildShadowTree(SVGElement* target, SVGElementInstance* targetInstance);
-
- void expandUseElementsInShadowTree(Node* element);
- void expandSymbolElementsInShadowTree(Node* element);
-
- // "Tree connector"
- void associateInstancesWithShadowTreeElements(Node* target, SVGElementInstance* targetInstance);
- SVGElementInstance* instanceForShadowTreeElement(Node* element, SVGElementInstance* instance) const;
+ bool buildShadowTree(SVGElement* target, SVGElement* targetInstance, bool foundUse);
+ bool hasCycleUseReferencing(SVGUseElement*, ContainerNode* targetInstance, SVGElement*& newTarget);
+ bool expandUseElementsInShadowTree(SVGElement*);
+ void expandSymbolElementsInShadowTree(SVGElement*);
void transferUseAttributesToReplacedElement(SVGElement* from, SVGElement* to) const;
- void transferEventListenersToShadowTree(SVGElementInstance* target);
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGUseElement)
- DECLARE_ANIMATED_LENGTH(X, x)
- DECLARE_ANIMATED_LENGTH(Y, y)
- DECLARE_ANIMATED_LENGTH(Width, width)
- DECLARE_ANIMATED_LENGTH(Height, height)
- DECLARE_ANIMATED_STRING(Href, href)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- END_DECLARE_ANIMATED_PROPERTIES
+ void invalidateDependentShadowTrees();
bool resourceIsStillLoading();
Document* externalDocument() const;
- bool instanceTreeIsLoading(SVGElementInstance*);
- virtual void notifyFinished(Resource*);
- Document* referencedDocument() const;
+ bool instanceTreeIsLoading(SVGElement*);
+ virtual void notifyFinished(Resource*) OVERRIDE;
+ TreeScope* referencedScope() const;
void setDocumentResource(ResourcePtr<DocumentResource>);
- // SVGExternalResourcesRequired
- virtual void setHaveFiredLoadEvent(bool haveFiredLoadEvent) { m_haveFiredLoadEvent = haveFiredLoadEvent; }
- virtual bool isParserInserted() const { return m_wasInsertedByParser; }
- virtual bool haveFiredLoadEvent() const { return m_haveFiredLoadEvent; }
virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE { return &m_svgLoadEventTimer; }
- bool m_wasInsertedByParser;
+ RefPtr<SVGAnimatedLength> m_x;
+ RefPtr<SVGAnimatedLength> m_y;
+ RefPtr<SVGAnimatedLength> m_width;
+ RefPtr<SVGAnimatedLength> m_height;
+
bool m_haveFiredLoadEvent;
bool m_needsShadowTreeRecreation;
- RefPtr<SVGElementInstance> m_targetElementInstance;
+ RefPtrWillBeMember<SVGElement> m_targetElementInstance;
ResourcePtr<DocumentResource> m_resource;
Timer<SVGElement> m_svgLoadEventTimer;
};
-DEFINE_NODE_TYPE_CASTS(SVGUseElement, hasTagName(SVGNames::useTag));
-
}
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.idl
index eb5d82c8c22..ffbd3410c55 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGUseElement.idl
@@ -23,17 +23,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG11/struct.html#InterfaceSVGUseElement
+// http://www.w3.org/TR/SVG2/struct.html#InterfaceSVGUseElement
+
interface SVGUseElement : SVGGraphicsElement {
readonly attribute SVGAnimatedLength x;
readonly attribute SVGAnimatedLength y;
readonly attribute SVGAnimatedLength width;
readonly attribute SVGAnimatedLength height;
-
- [MeasureAs=SVGInstanceRoot] readonly attribute SVGElementInstance instanceRoot;
- readonly attribute SVGElementInstance animatedInstanceRoot;
};
-SVGUseElement implements SVGExternalResourcesRequired;
-SVGUseElement implements SVGTests;
SVGUseElement implements SVGURIReference;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.cpp
index ff60552df30..25f57e76326 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.cpp
@@ -32,17 +32,14 @@ inline SVGVKernElement::SVGVKernElement(Document& document)
ScriptWrappable::init(this);
}
-PassRefPtr<SVGVKernElement> SVGVKernElement::create(Document& document)
-{
- return adoptRef(new SVGVKernElement(document));
-}
+DEFINE_NODE_FACTORY(SVGVKernElement)
Node::InsertionNotificationRequest SVGVKernElement::insertedInto(ContainerNode* rootParent)
{
if (rootParent->inDocument()) {
ContainerNode* fontNode = parentNode();
- if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
- toSVGFontElement(fontNode)->invalidateGlyphCache();
+ if (isSVGFontElement(fontNode))
+ toSVGFontElement(*fontNode).invalidateGlyphCache();
}
return SVGElement::insertedInto(rootParent);
@@ -51,8 +48,8 @@ Node::InsertionNotificationRequest SVGVKernElement::insertedInto(ContainerNode*
void SVGVKernElement::removedFrom(ContainerNode* rootParent)
{
ContainerNode* fontNode = parentNode();
- if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
- toSVGFontElement(fontNode)->invalidateGlyphCache();
+ if (isSVGFontElement(fontNode))
+ toSVGFontElement(*fontNode).invalidateGlyphCache();
SVGElement::removedFrom(rootParent);
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.h
index f8837bf686e..95bd58b0819 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGVKernElement.h
@@ -21,7 +21,7 @@
#define SVGVKernElement_h
#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGFontElement.h"
@@ -29,7 +29,7 @@ namespace WebCore {
class SVGVKernElement FINAL : public SVGElement {
public:
- static PassRefPtr<SVGVKernElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGVKernElement);
void buildVerticalKerningPair(KerningPairVector&);
@@ -39,11 +39,9 @@ private:
virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
virtual void removedFrom(ContainerNode*) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
};
-DEFINE_NODE_TYPE_CASTS(SVGVKernElement, hasTagName(SVGNames::vkernTag));
-
} // namespace WebCore
#endif // ENABLE(SVG_FONTS)
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.cpp
index c72604a6f38..24e41bac74d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.cpp
@@ -22,40 +22,24 @@
#include "core/svg/SVGViewElement.h"
-
namespace WebCore {
-// Animated property definitions
-DEFINE_ANIMATED_BOOLEAN(SVGViewElement, SVGNames::externalResourcesRequiredAttr, ExternalResourcesRequired, externalResourcesRequired)
-DEFINE_ANIMATED_RECT(SVGViewElement, SVGNames::viewBoxAttr, ViewBox, viewBox)
-DEFINE_ANIMATED_PRESERVEASPECTRATIO(SVGViewElement, SVGNames::preserveAspectRatioAttr, PreserveAspectRatio, preserveAspectRatio)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGViewElement)
- REGISTER_LOCAL_ANIMATED_PROPERTY(externalResourcesRequired)
- REGISTER_LOCAL_ANIMATED_PROPERTY(viewBox)
- REGISTER_LOCAL_ANIMATED_PROPERTY(preserveAspectRatio)
- REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
inline SVGViewElement::SVGViewElement(Document& document)
: SVGElement(SVGNames::viewTag, document)
- , m_zoomAndPan(SVGZoomAndPanMagnify)
- , m_viewTarget(SVGNames::viewTargetAttr)
+ , SVGFitToViewBox(this)
+ , m_viewTarget(SVGStaticStringList::create(this, SVGNames::viewTargetAttr))
{
ScriptWrappable::init(this);
- registerAnimatedPropertiesForSVGViewElement();
-}
-PassRefPtr<SVGViewElement> SVGViewElement::create(Document& document)
-{
- return adoptRef(new SVGViewElement(document));
+ addToPropertyMap(m_viewTarget);
}
+DEFINE_NODE_FACTORY(SVGViewElement)
+
bool SVGViewElement::isSupportedAttribute(const QualifiedName& attrName)
{
DEFINE_STATIC_LOCAL(HashSet<QualifiedName>, supportedAttributes, ());
if (supportedAttributes.isEmpty()) {
- SVGExternalResourcesRequired::addSupportedAttributes(supportedAttributes);
SVGFitToViewBox::addSupportedAttributes(supportedAttributes);
SVGZoomAndPan::addSupportedAttributes(supportedAttributes);
supportedAttributes.add(SVGNames::viewTargetAttr);
@@ -70,19 +54,17 @@ void SVGViewElement::parseAttribute(const QualifiedName& name, const AtomicStrin
return;
}
- if (name == SVGNames::viewTargetAttr) {
- viewTarget().reset(value);
- return;
- }
+ SVGParsingError parseError = NoError;
- if (SVGExternalResourcesRequired::parseAttribute(name, value))
- return;
- if (SVGFitToViewBox::parseAttribute(this, name, value))
- return;
- if (SVGZoomAndPan::parseAttribute(this, name, value))
- return;
+ if (SVGFitToViewBox::parseAttribute(name, value, document(), parseError)) {
+ } else if (SVGZoomAndPan::parseAttribute(name, value)) {
+ } else if (name == SVGNames::viewTargetAttr) {
+ m_viewTarget->setBaseValueAsString(value, parseError);
+ } else {
+ ASSERT_NOT_REACHED();
+ }
- ASSERT_NOT_REACHED();
+ reportAttributeParsingError(parseError, name, value);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.h b/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.h
index 3069cbfcf7d..2a6433b96f2 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.h
@@ -21,31 +21,27 @@
#ifndef SVGViewElement_h
#define SVGViewElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGAnimatedBoolean.h"
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGAnimatedRect.h"
#include "core/svg/SVGElement.h"
-#include "core/svg/SVGExternalResourcesRequired.h"
#include "core/svg/SVGFitToViewBox.h"
-#include "core/svg/SVGStringList.h"
+#include "core/svg/SVGStaticStringList.h"
#include "core/svg/SVGZoomAndPan.h"
namespace WebCore {
class SVGViewElement FINAL : public SVGElement,
- public SVGExternalResourcesRequired,
public SVGFitToViewBox,
public SVGZoomAndPan {
public:
- static PassRefPtr<SVGViewElement> create(Document&);
+ DECLARE_NODE_FACTORY(SVGViewElement);
+#if !ENABLE(OILPAN)
using SVGElement::ref;
using SVGElement::deref;
+#endif
- SVGStringList& viewTarget() { return m_viewTarget; }
- SVGZoomAndPanType zoomAndPan() const { return m_zoomAndPan; }
- void setZoomAndPan(unsigned short zoomAndPan) { m_zoomAndPan = SVGZoomAndPan::parseFromNumber(zoomAndPan); }
+ SVGStringListTearOff* viewTarget() { return m_viewTarget->tearOff(); }
private:
explicit SVGViewElement(Document&);
@@ -54,20 +50,11 @@ private:
bool isSupportedAttribute(const QualifiedName&);
virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
- virtual bool rendererIsNeeded(const RenderStyle&) { return false; }
-
- BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGViewElement)
- DECLARE_ANIMATED_BOOLEAN(ExternalResourcesRequired, externalResourcesRequired)
- DECLARE_ANIMATED_RECT(ViewBox, viewBox)
- DECLARE_ANIMATED_PRESERVEASPECTRATIO(PreserveAspectRatio, preserveAspectRatio)
- END_DECLARE_ANIMATED_PROPERTIES
+ virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
- SVGZoomAndPanType m_zoomAndPan;
- SVGStringList m_viewTarget;
+ RefPtr<SVGStaticStringList> m_viewTarget;
};
-DEFINE_NODE_TYPE_CASTS(SVGViewElement, hasTagName(SVGNames::viewTag));
-
} // namespace WebCore
#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.idl b/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.idl
index 4b7a25d9b19..fb860f53baf 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGViewElement.idl
@@ -23,11 +23,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG2/linking.html#InterfaceSVGViewElement
+
interface SVGViewElement : SVGElement {
readonly attribute SVGStringList viewTarget;
};
-SVGViewElement implements SVGExternalResourcesRequired;
SVGViewElement implements SVGFitToViewBox;
SVGViewElement implements SVGZoomAndPan;
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.cpp
index b3201072998..62c2343e673 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.cpp
@@ -20,181 +20,106 @@
#include "config.h"
#include "core/svg/SVGViewSpec.h"
-#include "SVGNames.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/SVGNames.h"
#include "core/dom/Document.h"
+#include "core/dom/ExceptionCode.h"
#include "core/svg/SVGAnimatedTransformList.h"
#include "core/svg/SVGParserUtilities.h"
namespace WebCore {
-// Define custom animated property 'viewBox'.
-const SVGPropertyInfo* SVGViewSpec::viewBoxPropertyInfo()
-{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedRect,
- PropertyIsReadOnly,
- SVGNames::viewBoxAttr,
- viewBoxIdentifier(),
- 0,
- 0);
- }
- return s_propertyInfo;
-}
-
-// Define custom animated property 'preserveAspectRatio'.
-const SVGPropertyInfo* SVGViewSpec::preserveAspectRatioPropertyInfo()
-{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedPreserveAspectRatio,
- PropertyIsReadOnly,
- SVGNames::preserveAspectRatioAttr,
- preserveAspectRatioIdentifier(),
- 0,
- 0);
- }
- return s_propertyInfo;
-}
-
-
-// Define custom non-animated property 'transform'.
-const SVGPropertyInfo* SVGViewSpec::transformPropertyInfo()
-{
- static const SVGPropertyInfo* s_propertyInfo = 0;
- if (!s_propertyInfo) {
- s_propertyInfo = new SVGPropertyInfo(AnimatedTransformList,
- PropertyIsReadOnly,
- SVGNames::transformAttr,
- transformIdentifier(),
- 0,
- 0);
- }
- return s_propertyInfo;
-}
-
-SVGViewSpec::SVGViewSpec(WeakPtr<SVGSVGElement> contextElement)
- : m_contextElement(contextElement)
- , m_zoomAndPan(SVGZoomAndPanMagnify)
+SVGViewSpec::SVGViewSpec(SVGSVGElement* contextElement)
+ // Note: addToPropertyMap is not needed, as SVGViewSpec do not correspond to an element.
+ // Note: We make tear-offs' contextElement the target element of SVGViewSpec.
+ // This contextElement will be only used for keeping this alive from the tearoff.
+ // SVGSVGElement holds a strong-ref to this SVGViewSpec, so this is kept alive as:
+ // AnimatedProperty tearoff -(contextElement)-> SVGSVGElement -(RefPtr)-> SVGViewSpec.
+ : SVGFitToViewBox(contextElement, PropertyMapPolicySkip)
+ , m_contextElement(contextElement)
+ , m_transform(SVGAnimatedTransformList::create(contextElement, SVGNames::transformAttr, SVGTransformList::create()))
{
ASSERT(m_contextElement);
ScriptWrappable::init(this);
-}
-
-const AtomicString& SVGViewSpec::viewBoxIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGViewSpecViewBoxAttribute", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
-
-const AtomicString& SVGViewSpec::preserveAspectRatioIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGViewSpecPreserveAspectRatioAttribute", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
-const AtomicString& SVGViewSpec::transformIdentifier()
-{
- DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGViewSpecTransformAttribute", AtomicString::ConstructFromLiteral));
- return s_identifier;
-}
-
-void SVGViewSpec::setZoomAndPan(unsigned short, ExceptionState& exceptionState)
-{
- // SVGViewSpec and all of its content is read-only.
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
-}
-
-void SVGViewSpec::setTransformString(const String& transform)
-{
- if (!m_contextElement)
- return;
-
- SVGTransformList newList;
- newList.parse(transform);
-
- if (SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<SVGElement, SVGAnimatedTransformList>(m_contextElement.get(), transformPropertyInfo()))
- static_cast<SVGAnimatedTransformList*>(wrapper)->detachListWrappers(newList.size());
-
- m_transform = newList;
+ viewBox()->setReadOnly();
+ preserveAspectRatio()->setReadOnly();
+ m_transform->setReadOnly();
+ // Note: addToPropertyMap is not needed, as SVGViewSpec do not correspond to an element.
}
-String SVGViewSpec::transformString() const
+bool SVGViewSpec::parseViewSpec(const String& spec)
{
- return SVGPropertyTraits<SVGTransformList>::toString(m_transform);
+ if (spec.isEmpty() || !m_contextElement)
+ return false;
+ if (spec.is8Bit()) {
+ const LChar* ptr = spec.characters8();
+ const LChar* end = ptr + spec.length();
+ return parseViewSpecInternal(ptr, end);
+ }
+ const UChar* ptr = spec.characters16();
+ const UChar* end = ptr + spec.length();
+ return parseViewSpecInternal(ptr, end);
}
-String SVGViewSpec::viewBoxString() const
+void SVGViewSpec::reset()
{
- return SVGPropertyTraits<SVGRect>::toString(viewBoxBaseValue());
+ resetZoomAndPan();
+ m_transform->baseValue()->clear();
+ updateViewBox(FloatRect());
+ ASSERT(preserveAspectRatio());
+ preserveAspectRatio()->baseValue()->setAlign(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID);
+ preserveAspectRatio()->baseValue()->setMeetOrSlice(SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET);
+ m_viewTargetString = emptyString();
}
-String SVGViewSpec::preserveAspectRatioString() const
+void SVGViewSpec::detachContextElement()
{
- return SVGPropertyTraits<SVGPreserveAspectRatio>::toString(preserveAspectRatioBaseValue());
+ m_transform = nullptr;
+ clearViewBox();
+ clearPreserveAspectRatio();
+ m_contextElement = nullptr;
}
SVGElement* SVGViewSpec::viewTarget() const
{
if (!m_contextElement)
return 0;
- Element* element = m_contextElement.get()->treeScope().getElementById(m_viewTargetString);
+ Element* element = m_contextElement->treeScope().getElementById(AtomicString(m_viewTargetString));
if (!element || !element->isSVGElement())
return 0;
return toSVGElement(element);
}
-SVGTransformListPropertyTearOff* SVGViewSpec::transform()
+String SVGViewSpec::viewBoxString() const
{
- if (!m_contextElement)
- return 0;
- // Return the animVal here, as its readonly by default - which is exactly what we want here.
- return static_cast<SVGTransformListPropertyTearOff*>(static_pointer_cast<SVGAnimatedTransformList>(lookupOrCreateTransformWrapper(this))->animVal());
-}
+ if (!viewBox())
+ return String();
-PassRefPtr<SVGAnimatedRect> SVGViewSpec::viewBox()
-{
- if (!m_contextElement)
- return 0;
- return static_pointer_cast<SVGAnimatedRect>(lookupOrCreateViewBoxWrapper(this));
+ return viewBox()->currentValue()->valueAsString();
}
-PassRefPtr<SVGAnimatedPreserveAspectRatio> SVGViewSpec::preserveAspectRatio()
+String SVGViewSpec::preserveAspectRatioString() const
{
- if (!m_contextElement)
- return 0;
- return static_pointer_cast<SVGAnimatedPreserveAspectRatio>(lookupOrCreatePreserveAspectRatioWrapper(this));
-}
+ if (!preserveAspectRatio())
+ return String();
-PassRefPtr<SVGAnimatedProperty> SVGViewSpec::lookupOrCreateViewBoxWrapper(SVGViewSpec* ownerType)
-{
- ASSERT(ownerType);
- ASSERT(ownerType->contextElement());
- return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedRect, SVGRect>(ownerType->contextElement(), viewBoxPropertyInfo(), ownerType->m_viewBox);
+ return preserveAspectRatio()->baseValue()->valueAsString();
}
-PassRefPtr<SVGAnimatedProperty> SVGViewSpec::lookupOrCreatePreserveAspectRatioWrapper(SVGViewSpec* ownerType)
+String SVGViewSpec::transformString() const
{
- ASSERT(ownerType);
- ASSERT(ownerType->contextElement());
- return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedPreserveAspectRatio, SVGPreserveAspectRatio>(ownerType->contextElement(), preserveAspectRatioPropertyInfo(), ownerType->m_preserveAspectRatio);
-}
+ if (!m_transform)
+ return String();
-PassRefPtr<SVGAnimatedProperty> SVGViewSpec::lookupOrCreateTransformWrapper(SVGViewSpec* ownerType)
-{
- ASSERT(ownerType);
- ASSERT(ownerType->contextElement());
- return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedTransformList, SVGTransformList>(ownerType->contextElement(), transformPropertyInfo(), ownerType->m_transform);
+ return m_transform->baseValue()->valueAsString();
}
-void SVGViewSpec::reset()
+void SVGViewSpec::setZoomAndPan(unsigned short, ExceptionState& exceptionState)
{
- m_zoomAndPan = SVGZoomAndPanMagnify;
- m_transform.clear();
- m_viewBox = SVGRect();
- m_preserveAspectRatio = SVGPreserveAspectRatio();
- m_viewTargetString = emptyString();
+ // SVGViewSpec and all of its content is read-only.
+ exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly());
}
static const LChar svgViewSpec[] = {'s', 'v', 'g', 'V', 'i', 'e', 'w'};
@@ -220,10 +145,13 @@ bool SVGViewSpec::parseViewSpecInternal(const CharType* ptr, const CharType* end
if (ptr >= end || *ptr != '(')
return false;
ptr++;
- SVGRect viewBox;
- if (!SVGFitToViewBox::parseViewBox(&m_contextElement.get()->document(), ptr, end, viewBox, false))
+ float x = 0.0f;
+ float y = 0.0f;
+ float width = 0.0f;
+ float height = 0.0f;
+ if (!(parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, DisallowWhitespace)))
return false;
- setViewBoxBaseValue(viewBox);
+ updateViewBox(FloatRect(x, y, width, height));
if (ptr >= end || *ptr != ')')
return false;
ptr++;
@@ -235,7 +163,7 @@ bool SVGViewSpec::parseViewSpecInternal(const CharType* ptr, const CharType* end
ptr++;
if (ptr >= end)
return false;
- setViewTargetString(String(viewTargetStart, ptr - viewTargetStart));
+ m_viewTargetString = String(viewTargetStart, ptr - viewTargetStart);
ptr++;
} else
return false;
@@ -245,7 +173,7 @@ bool SVGViewSpec::parseViewSpecInternal(const CharType* ptr, const CharType* end
if (ptr >= end || *ptr != '(')
return false;
ptr++;
- if (!parseZoomAndPan(ptr, end, m_zoomAndPan))
+ if (!parseZoomAndPan(ptr, end))
return false;
if (ptr >= end || *ptr != ')')
return false;
@@ -256,10 +184,8 @@ bool SVGViewSpec::parseViewSpecInternal(const CharType* ptr, const CharType* end
if (ptr >= end || *ptr != '(')
return false;
ptr++;
- SVGPreserveAspectRatio preserveAspectRatio;
- if (!preserveAspectRatio.parse(ptr, end, false))
+ if (!preserveAspectRatio()->baseValue()->parse(ptr, end, false))
return false;
- setPreserveAspectRatioBaseValue(preserveAspectRatio);
if (ptr >= end || *ptr != ')')
return false;
ptr++;
@@ -269,7 +195,7 @@ bool SVGViewSpec::parseViewSpecInternal(const CharType* ptr, const CharType* end
if (ptr >= end || *ptr != '(')
return false;
ptr++;
- parseTransformAttribute(m_transform, ptr, end, DoNotClearList);
+ m_transform->baseValue()->parse(ptr, end);
if (ptr >= end || *ptr != ')')
return false;
ptr++;
@@ -286,18 +212,9 @@ bool SVGViewSpec::parseViewSpecInternal(const CharType* ptr, const CharType* end
return true;
}
-bool SVGViewSpec::parseViewSpec(const String& spec)
+void SVGViewSpec::trace(Visitor* visitor)
{
- if (spec.isEmpty() || !m_contextElement)
- return false;
- if (spec.is8Bit()) {
- const LChar* ptr = spec.characters8();
- const LChar* end = ptr + spec.length();
- return parseViewSpecInternal(ptr, end);
- }
- const UChar* ptr = spec.characters16();
- const UChar* end = ptr + spec.length();
- return parseViewSpecInternal(ptr, end);
+ visitor->trace(m_contextElement);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.h b/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.h
index c5d742f5daa..ed53e47b0e6 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.h
@@ -21,90 +21,54 @@
#define SVGViewSpec_h
#include "bindings/v8/ScriptWrappable.h"
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGAnimatedRect.h"
#include "core/svg/SVGFitToViewBox.h"
#include "core/svg/SVGSVGElement.h"
-#include "core/svg/SVGTransformList.h"
#include "core/svg/SVGZoomAndPan.h"
+#include "platform/heap/Handle.h"
#include "wtf/WeakPtr.h"
namespace WebCore {
-class ExceptionState;
-class SVGTransformListPropertyTearOff;
-
-class SVGViewSpec FINAL : public RefCounted<SVGViewSpec>, public ScriptWrappable, public SVGZoomAndPan, public SVGFitToViewBox {
+class SVGViewSpec FINAL : public RefCountedWillBeGarbageCollectedFinalized<SVGViewSpec>, public ScriptWrappable, public SVGZoomAndPan, public SVGFitToViewBox {
public:
+#if !ENABLE(OILPAN)
using RefCounted<SVGViewSpec>::ref;
using RefCounted<SVGViewSpec>::deref;
+#endif
- static PassRefPtr<SVGViewSpec> create(WeakPtr<SVGSVGElement> contextElement)
+ static PassRefPtrWillBeRawPtr<SVGViewSpec> create(SVGSVGElement* contextElement)
{
- return adoptRef(new SVGViewSpec(contextElement));
+ return adoptRefWillBeNoop(new SVGViewSpec(contextElement));
}
bool parseViewSpec(const String&);
void reset();
+ void detachContextElement();
+ // JS API
+ SVGTransformList* transform() { return m_transform ? m_transform->baseValue() : 0; }
+ PassRefPtr<SVGTransformListTearOff> transformFromJavascript() { return m_transform ? m_transform->baseVal() : 0; }
SVGElement* viewTarget() const;
String viewBoxString() const;
-
String preserveAspectRatioString() const;
-
- void setTransformString(const String&);
String transformString() const;
-
- void setViewTargetString(const String& string) { m_viewTargetString = string; }
String viewTargetString() const { return m_viewTargetString; }
+ // override SVGZoomAndPan.setZoomAndPan so can throw exception on write
+ void setZoomAndPan(unsigned short value) { } // read only
+ void setZoomAndPan(unsigned short value, ExceptionState&);
- SVGZoomAndPanType zoomAndPan() const { return m_zoomAndPan; }
- void setZoomAndPan(unsigned short zoomAndPan) { setZoomAndPanBaseValue(zoomAndPan); }
- void setZoomAndPan(unsigned short, ExceptionState&);
- void setZoomAndPanBaseValue(unsigned short zoomAndPan) { m_zoomAndPan = SVGZoomAndPan::parseFromNumber(zoomAndPan); }
-
- SVGElement* contextElement() const { return m_contextElement.get(); }
+ void trace(Visitor*);
- // Custom non-animated 'transform' property.
- SVGTransformListPropertyTearOff* transform();
- SVGTransformList transformBaseValue() const { return m_transform; }
-
- // Custom animated 'viewBox' property.
- PassRefPtr<SVGAnimatedRect> viewBox();
- SVGRect& viewBoxCurrentValue() { return m_viewBox; }
- SVGRect viewBoxBaseValue() const { return m_viewBox; }
- void setViewBoxBaseValue(const SVGRect& viewBox) { m_viewBox = viewBox; }
-
- // Custom animated 'preserveAspectRatio' property.
- PassRefPtr<SVGAnimatedPreserveAspectRatio> preserveAspectRatio();
- SVGPreserveAspectRatio& preserveAspectRatioCurrentValue() { return m_preserveAspectRatio; }
- SVGPreserveAspectRatio preserveAspectRatioBaseValue() const { return m_preserveAspectRatio; }
- void setPreserveAspectRatioBaseValue(const SVGPreserveAspectRatio& preserveAspectRatio) { m_preserveAspectRatio = preserveAspectRatio; }
+ SVGSVGElement* contextElement() { return m_contextElement.get(); }
private:
- explicit SVGViewSpec(WeakPtr<SVGSVGElement>);
-
- static const SVGPropertyInfo* transformPropertyInfo();
- static const SVGPropertyInfo* viewBoxPropertyInfo();
- static const SVGPropertyInfo* preserveAspectRatioPropertyInfo();
-
- static const AtomicString& transformIdentifier();
- static const AtomicString& viewBoxIdentifier();
- static const AtomicString& preserveAspectRatioIdentifier();
-
- static PassRefPtr<SVGAnimatedProperty> lookupOrCreateTransformWrapper(SVGViewSpec* contextElement);
- static PassRefPtr<SVGAnimatedProperty> lookupOrCreateViewBoxWrapper(SVGViewSpec* contextElement);
- static PassRefPtr<SVGAnimatedProperty> lookupOrCreatePreserveAspectRatioWrapper(SVGViewSpec* contextElement);
+ explicit SVGViewSpec(SVGSVGElement*);
template<typename CharType>
bool parseViewSpecInternal(const CharType* ptr, const CharType* end);
- WeakPtr<SVGSVGElement> m_contextElement;
-
- SVGZoomAndPanType m_zoomAndPan;
- SVGTransformList m_transform;
- SVGRect m_viewBox;
- SVGPreserveAspectRatio m_preserveAspectRatio;
+ RawPtrWillBeMember<SVGSVGElement> m_contextElement;
+ RefPtr<SVGAnimatedTransformList> m_transform;
String m_viewTargetString;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.idl b/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.idl
index 80b1d809c44..5c16d614045 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGViewSpec.idl
@@ -23,17 +23,20 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGViewSpec {
- readonly attribute SVGTransformList transform;
+// http://www.w3.org/TR/SVG2/types.html#InterfaceSVGViewSpec
+
+[
+ DependentLifetime,
+ WillBeGarbageCollected,
+ SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGViewSpec {
+ [ImplementedAs=transformFromJavascript] readonly attribute SVGTransformList transform;
readonly attribute SVGElement viewTarget;
readonly attribute DOMString viewBoxString;
readonly attribute DOMString preserveAspectRatioString;
readonly attribute DOMString transformString;
readonly attribute DOMString viewTargetString;
-
- // SVGZoomAndPan
- [RaisesException=Setter] attribute unsigned short zoomAndPan;
};
SVGViewSpec implements SVGFitToViewBox;
-
+SVGViewSpec implements SVGZoomAndPan;
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.cpp
index 450152cb59b..782176553dd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.cpp
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -19,13 +20,22 @@
*/
#include "config.h"
-
#include "core/svg/SVGZoomAndPan.h"
#include "core/svg/SVGParserUtilities.h"
namespace WebCore {
+SVGZoomAndPan::SVGZoomAndPan()
+ : m_zoomAndPan(SVGZoomAndPanMagnify)
+{
+}
+
+void SVGZoomAndPan::resetZoomAndPan()
+{
+ m_zoomAndPan = SVGZoomAndPanMagnify;
+}
+
bool SVGZoomAndPan::isKnownAttribute(const QualifiedName& attrName)
{
return attrName == SVGNames::zoomAndPanAttr;
@@ -53,29 +63,14 @@ static bool parseZoomAndPanInternal(const CharType*& start, const CharType* end,
return false;
}
-bool SVGZoomAndPan::parseZoomAndPan(const LChar*& start, const LChar* end, SVGZoomAndPanType& zoomAndPan)
-{
- return parseZoomAndPanInternal(start, end, zoomAndPan);
-}
-
-bool SVGZoomAndPan::parseZoomAndPan(const UChar*& start, const UChar* end, SVGZoomAndPanType& zoomAndPan)
-{
- return parseZoomAndPanInternal(start, end, zoomAndPan);
-}
-
-NO_RETURN_DUE_TO_ASSERT void SVGZoomAndPan::ref()
-{
- ASSERT_NOT_REACHED();
-}
-
-NO_RETURN_DUE_TO_ASSERT void SVGZoomAndPan::deref()
+bool SVGZoomAndPan::parseZoomAndPan(const LChar*& start, const LChar* end)
{
- ASSERT_NOT_REACHED();
+ return parseZoomAndPanInternal(start, end, m_zoomAndPan);
}
-NO_RETURN_DUE_TO_ASSERT void SVGZoomAndPan::setZoomAndPan(unsigned short)
+bool SVGZoomAndPan::parseZoomAndPan(const UChar*& start, const UChar* end)
{
- ASSERT_NOT_REACHED();
+ return parseZoomAndPanInternal(start, end, m_zoomAndPan);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.h b/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.h
index b1432eb9bf0..dfd8c7341d0 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,12 +22,14 @@
#ifndef SVGZoomAndPan_h
#define SVGZoomAndPan_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/dom/QualifiedName.h"
#include "wtf/HashSet.h"
namespace WebCore {
+class ExceptionState;
+
enum SVGZoomAndPanType {
SVGZoomAndPanUnknown = 0,
SVGZoomAndPanDisable,
@@ -42,6 +45,8 @@ public:
SVG_ZOOMANDPAN_MAGNIFY = SVGZoomAndPanMagnify
};
+ virtual ~SVGZoomAndPan() { }
+
static bool isKnownAttribute(const QualifiedName&);
static void addSupportedAttributes(HashSet<QualifiedName>&);
@@ -52,38 +57,39 @@ public:
return static_cast<SVGZoomAndPanType>(number);
}
- static bool parseZoomAndPan(const LChar*& start, const LChar* end, SVGZoomAndPanType&);
- static bool parseZoomAndPan(const UChar*& start, const UChar* end, SVGZoomAndPanType&);
+ bool parseZoomAndPan(const LChar*& start, const LChar* end);
+ bool parseZoomAndPan(const UChar*& start, const UChar* end);
- template<class SVGElementTarget>
- static bool parseAttribute(SVGElementTarget* target, const QualifiedName& name, const AtomicString& value)
+ bool parseAttribute(const QualifiedName& name, const AtomicString& value)
{
- ASSERT(target);
if (name == SVGNames::zoomAndPanAttr) {
- SVGZoomAndPanType zoomAndPan = SVGZoomAndPanUnknown;
+ m_zoomAndPan = SVGZoomAndPanUnknown;
if (!value.isEmpty()) {
if (value.is8Bit()) {
const LChar* start = value.characters8();
- parseZoomAndPan(start, start + value.length(), zoomAndPan);
+ parseZoomAndPan(start, start + value.length());
} else {
const UChar* start = value.characters16();
- parseZoomAndPan(start, start + value.length(), zoomAndPan);
+ parseZoomAndPan(start, start + value.length());
}
}
- target->setZoomAndPan(zoomAndPan);
return true;
}
return false;
}
- SVGZoomAndPanType zoomAndPan() const { return SVGZoomAndPanUnknown; }
+ // JS API
+ SVGZoomAndPanType zoomAndPan() const { return m_zoomAndPan; }
+ virtual void setZoomAndPan(unsigned short value) { m_zoomAndPan = parseFromNumber(value); }
+ virtual void setZoomAndPan(unsigned short value, ExceptionState&) { setZoomAndPan(value); }
+
+protected:
+ SVGZoomAndPan();
+ void resetZoomAndPan();
- // These methods only exist to allow us to compile V8/JSSVGZoomAndPan.*.
- // These are never called, and thus ASSERT_NOT_REACHED.
- void ref();
- void deref();
- void setZoomAndPan(unsigned short);
+private:
+ SVGZoomAndPanType m_zoomAndPan;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.idl b/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.idl
index 42149bd3ad5..2eeedfdea9b 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGZoomAndPan.idl
@@ -24,14 +24,16 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/SVG2/types.html#InterfaceSVGZoomAndPan
+
[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
+ NoInterfaceObject, // Always used on target of 'implements'
] interface SVGZoomAndPan {
+
+ // Zoom and Pan Types
const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0;
const unsigned short SVG_ZOOMANDPAN_DISABLE = 1;
const unsigned short SVG_ZOOMANDPAN_MAGNIFY = 2;
- attribute unsigned short zoomAndPan;
+ [RaisesException=Setter] attribute unsigned short zoomAndPan; // readonly in SVGViewSpec, hence raises exception on setter there
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.cpp b/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.cpp
index fe5d283270f..07e6f25bbc3 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.cpp
@@ -22,7 +22,8 @@
#include "config.h"
#include "core/svg/SVGZoomEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "core/svg/SVGPointTearOff.h"
+#include "core/svg/SVGRectTearOff.h"
namespace WebCore {
@@ -33,9 +34,11 @@ SVGZoomEvent::SVGZoomEvent()
ScriptWrappable::init(this);
}
-SVGRect SVGZoomEvent::zoomRectScreen() const
+PassRefPtr<SVGRectTearOff> SVGZoomEvent::zoomRectScreen() const
{
- return m_zoomRectScreen;
+ RefPtr<SVGRectTearOff> rectTearOff = SVGRectTearOff::create(SVGRect::create(), 0, PropertyIsNotAnimVal);
+ rectTearOff->setIsReadOnlyProperty();
+ return rectTearOff.release();
}
float SVGZoomEvent::previousScale() const
@@ -43,14 +46,11 @@ float SVGZoomEvent::previousScale() const
return m_previousScale;
}
-void SVGZoomEvent::setPreviousScale(float scale)
+PassRefPtr<SVGPointTearOff> SVGZoomEvent::previousTranslate() const
{
- m_previousScale = scale;
-}
-
-SVGPoint SVGZoomEvent::previousTranslate() const
-{
- return m_previousTranslate;
+ RefPtr<SVGPointTearOff> pointTearOff = SVGPointTearOff::create(SVGPoint::create(m_previousTranslate), 0, PropertyIsNotAnimVal);
+ pointTearOff->setIsReadOnlyProperty();
+ return pointTearOff.release();
}
float SVGZoomEvent::newScale() const
@@ -58,19 +58,21 @@ float SVGZoomEvent::newScale() const
return m_newScale;
}
-void SVGZoomEvent::setNewScale(float scale)
+PassRefPtr<SVGPointTearOff> SVGZoomEvent::newTranslate() const
{
- m_newScale = scale;
+ RefPtr<SVGPointTearOff> pointTearOff = SVGPointTearOff::create(SVGPoint::create(m_newTranslate), 0, PropertyIsNotAnimVal);
+ pointTearOff->setIsReadOnlyProperty();
+ return pointTearOff.release();
}
-SVGPoint SVGZoomEvent::newTranslate() const
+const AtomicString& SVGZoomEvent::interfaceName() const
{
- return m_newTranslate;
+ return EventNames::SVGZoomEvent;
}
-const AtomicString& SVGZoomEvent::interfaceName() const
+void SVGZoomEvent::trace(Visitor* visitor)
{
- return EventNames::SVGZoomEvent;
+ UIEvent::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.h b/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.h
index 59d31ae0b14..efbcbecbddd 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.h
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.h
@@ -28,24 +28,27 @@
namespace WebCore {
-class SVGZoomEvent : public UIEvent {
+class SVGZoomEvent FINAL : public UIEvent {
public:
- static PassRefPtr<SVGZoomEvent> create() { return adoptRef(new SVGZoomEvent); }
+ static PassRefPtrWillBeRawPtr<SVGZoomEvent> create()
+ {
+ return adoptRefWillBeNoop(new SVGZoomEvent);
+ }
// 'SVGZoomEvent' functions
- SVGRect zoomRectScreen() const;
+ PassRefPtr<SVGRectTearOff> zoomRectScreen() const;
float previousScale() const;
- void setPreviousScale(float);
- SVGPoint previousTranslate() const;
+ PassRefPtr<SVGPointTearOff> previousTranslate() const;
float newScale() const;
- void setNewScale(float);
- SVGPoint newTranslate() const;
+ PassRefPtr<SVGPointTearOff> newTranslate() const;
- virtual const AtomicString& interfaceName() const;
+ virtual const AtomicString& interfaceName() const OVERRIDE;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
SVGZoomEvent();
@@ -53,10 +56,8 @@ private:
float m_newScale;
float m_previousScale;
- SVGRect m_zoomRectScreen;
-
- SVGPoint m_newTranslate;
- SVGPoint m_previousTranslate;
+ FloatPoint m_newTranslate;
+ FloatPoint m_previousTranslate;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.idl b/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.idl
index 48bb3579d0f..719739bc6cb 100644
--- a/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/svg/SVGZoomEvent.idl
@@ -23,11 +23,12 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface SVGZoomEvent : UIEvent {
+[
+ DependentLifetime,
+] interface SVGZoomEvent : UIEvent {
readonly attribute SVGRect zoomRectScreen;
readonly attribute float previousScale;
- [Immutable] readonly attribute SVGPoint previousTranslate;
+ readonly attribute SVGPoint previousTranslate;
readonly attribute float newScale;
- [Immutable] readonly attribute SVGPoint newTranslate;
+ readonly attribute SVGPoint newTranslate;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/svg/animation/SMILTime.h b/chromium/third_party/WebKit/Source/core/svg/animation/SMILTime.h
index e572de3b38d..c5627d6e77e 100644
--- a/chromium/third_party/WebKit/Source/core/svg/animation/SMILTime.h
+++ b/chromium/third_party/WebKit/Source/core/svg/animation/SMILTime.h
@@ -80,6 +80,14 @@ private:
Origin m_origin;
};
+struct SMILInterval {
+ SMILInterval() { }
+ SMILInterval(const SMILTime& begin, const SMILTime& end) : begin(begin), end(end) { }
+
+ SMILTime begin;
+ SMILTime end;
+};
+
inline bool operator==(const SMILTime& a, const SMILTime& b) { return a.isFinite() && a.value() == b.value(); }
inline bool operator!(const SMILTime& a) { return !a.isFinite() || !a.value(); }
inline bool operator!=(const SMILTime& a, const SMILTime& b) { return !operator==(a, b); }
@@ -94,6 +102,13 @@ SMILTime operator-(const SMILTime&, const SMILTime&);
// So multiplying times does not make too much sense but SMIL defines it for duration * repeatCount
SMILTime operator*(const SMILTime&, const SMILTime&);
+inline bool operator!=(const SMILInterval& a, const SMILInterval& b)
+{
+ // Compare the "raw" values since the operator!= for SMILTime always return
+ // true for non-finite times.
+ return a.begin.value() != b.begin.value() || a.end.value() != b.end.value();
+}
+
}
#endif // SMILTime_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp b/chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
index 1ab6eda4342..be1fb7e3e23 100644
--- a/chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
@@ -26,25 +26,38 @@
#include "config.h"
#include "core/svg/animation/SMILTimeContainer.h"
+#include "core/animation/AnimationClock.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/dom/ElementTraversal.h"
+#include "core/frame/FrameView.h"
#include "core/svg/SVGSVGElement.h"
#include "core/svg/animation/SVGSMILElement.h"
-#include "wtf/CurrentTime.h"
-
-using namespace std;
namespace WebCore {
-static const double animationFrameDelay = 0.025;
+static const double initialFrameDelay = 0.025;
+
+#if !ENABLE(OILPAN)
+// Every entry-point that calls updateAnimations() should instantiate a
+// DiscardScope to prevent deletion of the ownerElement (and hence itself.)
+class DiscardScope {
+public:
+ explicit DiscardScope(SVGSVGElement& timeContainerOwner) : m_discardScopeElement(&timeContainerOwner) { }
+
+private:
+ RefPtr<SVGSVGElement> m_discardScopeElement;
+};
+#endif
-SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner)
+SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
: m_beginTime(0)
, m_pauseTime(0)
, m_resumeTime(0)
, m_accumulatedActiveTime(0)
, m_presetStartTime(0)
+ , m_frameSchedulingState(Idle)
, m_documentOrderIndexesDirty(false)
- , m_timer(this, &SMILTimeContainer::timerFired)
+ , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired)
, m_ownerSVGElement(owner)
#ifndef NDEBUG
, m_preventScheduledAnimationsChanges(false)
@@ -54,6 +67,8 @@ SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner)
SMILTimeContainer::~SMILTimeContainer()
{
+ cancelAnimationFrame();
+ ASSERT(!m_wakeupTimer.isActive());
#ifndef NDEBUG
ASSERT(!m_preventScheduledAnimationsChanges);
#endif
@@ -70,11 +85,11 @@ void SMILTimeContainer::schedule(SVGSMILElement* animation, SVGElement* target,
#endif
ElementAttributePair key(target, attributeName);
- OwnPtr<AnimationsVector>& scheduled = m_scheduledAnimations.add(key, nullptr).iterator->value;
+ OwnPtrWillBeMember<AnimationsLinkedHashSet>& scheduled = m_scheduledAnimations.add(key, nullptr).storedValue->value;
if (!scheduled)
- scheduled = adoptPtr(new AnimationsVector);
+ scheduled = adoptPtrWillBeNoop(new AnimationsLinkedHashSet);
ASSERT(!scheduled->contains(animation));
- scheduled->append(animation);
+ scheduled->add(animation);
SMILTime nextFireTime = animation->nextProgressTime();
if (nextFireTime.isFinite())
@@ -90,18 +105,38 @@ void SMILTimeContainer::unschedule(SVGSMILElement* animation, SVGElement* target
#endif
ElementAttributePair key(target, attributeName);
- AnimationsVector* scheduled = m_scheduledAnimations.get(key);
+ GroupedAnimationsMap::iterator it = m_scheduledAnimations.find(key);
+ ASSERT(it != m_scheduledAnimations.end());
+ AnimationsLinkedHashSet* scheduled = it->value.get();
ASSERT(scheduled);
- size_t idx = scheduled->find(animation);
- ASSERT(idx != kNotFound);
- scheduled->remove(idx);
+ AnimationsLinkedHashSet::iterator itAnimation = scheduled->find(animation);
+ ASSERT(itAnimation != scheduled->end());
+ scheduled->remove(itAnimation);
+
+ if (scheduled->isEmpty())
+ m_scheduledAnimations.remove(it);
+}
+
+bool SMILTimeContainer::hasAnimations() const
+{
+ return !m_scheduledAnimations.isEmpty();
+}
+
+bool SMILTimeContainer::hasPendingSynchronization() const
+{
+ return m_frameSchedulingState == SynchronizeAnimations && m_wakeupTimer.isActive() && !m_wakeupTimer.nextFireInterval();
}
void SMILTimeContainer::notifyIntervalsChanged()
{
+ if (!isStarted())
+ return;
// Schedule updateAnimations() to be called asynchronously so multiple intervals
// can change with updateAnimations() only called once at the end.
- startTimer(0);
+ if (hasPendingSynchronization())
+ return;
+ cancelAnimationFrame();
+ scheduleWakeUp(0, SynchronizeAnimations);
}
SMILTime SMILTimeContainer::elapsed() const
@@ -115,11 +150,6 @@ SMILTime SMILTimeContainer::elapsed() const
return currentTime() + m_accumulatedActiveTime - lastResumeTime();
}
-bool SMILTimeContainer::isActive() const
-{
- return m_beginTime && !isPaused();
-}
-
bool SMILTimeContainer::isPaused() const
{
return m_pauseTime;
@@ -132,18 +162,33 @@ bool SMILTimeContainer::isStarted() const
void SMILTimeContainer::begin()
{
- ASSERT(!m_beginTime);
+ RELEASE_ASSERT(!m_beginTime);
double now = currentTime();
// If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began.
// In this case pass on 'seekToTime=true' to updateAnimations().
m_beginTime = now - m_presetStartTime;
- updateAnimations(SMILTime(m_presetStartTime), m_presetStartTime ? true : false);
+#if !ENABLE(OILPAN)
+ DiscardScope discardScope(m_ownerSVGElement);
+#endif
+ SMILTime earliestFireTime = updateAnimations(SMILTime(m_presetStartTime), m_presetStartTime ? true : false);
m_presetStartTime = 0;
if (m_pauseTime) {
m_pauseTime = now;
- m_timer.stop();
+ // If updateAnimations() caused new syncbase instance to be generated,
+ // we don't want to cancel those. Excepting that, no frame should've
+ // been scheduled at this point.
+ ASSERT(m_frameSchedulingState == Idle || m_frameSchedulingState == SynchronizeAnimations);
+ } else if (!hasPendingSynchronization()) {
+ ASSERT(isTimelineRunning());
+ // If the timeline is running, and there's pending animation updates,
+ // always perform the first update after the timeline was started using
+ // the wake-up mechanism.
+ if (earliestFireTime.isFinite()) {
+ SMILTime delay = earliestFireTime - elapsed();
+ scheduleWakeUp(std::max(initialFrameDelay, delay.value()), SynchronizeAnimations);
+ }
}
}
@@ -154,7 +199,7 @@ void SMILTimeContainer::pause()
if (m_beginTime) {
m_accumulatedActiveTime += m_pauseTime - lastResumeTime();
- m_timer.stop();
+ cancelAnimationFrame();
}
m_resumeTime = 0;
}
@@ -165,7 +210,7 @@ void SMILTimeContainer::resume()
m_resumeTime = currentTime();
m_pauseTime = 0;
- startTimer(0);
+ scheduleWakeUp(0, SynchronizeAnimations);
}
void SMILTimeContainer::setElapsed(SMILTime time)
@@ -176,8 +221,7 @@ void SMILTimeContainer::setElapsed(SMILTime time)
return;
}
- if (m_beginTime)
- m_timer.stop();
+ cancelAnimationFrame();
double now = currentTime();
m_beginTime = now - time.value();
@@ -194,50 +238,75 @@ void SMILTimeContainer::setElapsed(SMILTime time)
#endif
GroupedAnimationsMap::iterator end = m_scheduledAnimations.end();
for (GroupedAnimationsMap::iterator it = m_scheduledAnimations.begin(); it != end; ++it) {
- AnimationsVector* scheduled = it->value.get();
- unsigned size = scheduled->size();
- for (unsigned n = 0; n < size; n++)
- scheduled->at(n)->reset();
+ if (!it->key.first)
+ continue;
+
+ AnimationsLinkedHashSet* scheduled = it->value.get();
+ for (AnimationsLinkedHashSet::const_iterator itAnimation = scheduled->begin(), itAnimationEnd = scheduled->end(); itAnimation != itAnimationEnd; ++itAnimation)
+ (*itAnimation)->reset();
}
#ifndef NDEBUG
m_preventScheduledAnimationsChanges = false;
#endif
- updateAnimations(time, true);
+ updateAnimationsAndScheduleFrameIfNeeded(time, true);
}
-void SMILTimeContainer::startTimer(SMILTime fireTime, SMILTime minimumDelay)
+bool SMILTimeContainer::isTimelineRunning() const
{
- if (!m_beginTime || isPaused())
- return;
+ return m_beginTime && !isPaused();
+}
- if (!fireTime.isFinite())
- return;
+void SMILTimeContainer::scheduleAnimationFrame(SMILTime fireTime)
+{
+ ASSERT(isTimelineRunning() && fireTime.isFinite());
+ ASSERT(!m_wakeupTimer.isActive());
- SMILTime delay = max(fireTime - elapsed(), minimumDelay);
- m_timer.startOneShot(delay.value());
+ SMILTime delay = fireTime - elapsed();
+ if (delay.value() < AnimationTimeline::s_minimumDelay) {
+ serviceOnNextFrame();
+ } else {
+ scheduleWakeUp(delay.value() - AnimationTimeline::s_minimumDelay, FutureAnimationFrame);
+ }
}
-void SMILTimeContainer::timerFired(Timer<SMILTimeContainer>*)
+void SMILTimeContainer::cancelAnimationFrame()
{
- ASSERT(m_beginTime);
- ASSERT(!m_pauseTime);
- updateAnimations(elapsed());
+ m_frameSchedulingState = Idle;
+ m_wakeupTimer.stop();
+}
+
+void SMILTimeContainer::scheduleWakeUp(double delayTime, FrameSchedulingState frameSchedulingState)
+{
+ ASSERT(frameSchedulingState == SynchronizeAnimations || frameSchedulingState == FutureAnimationFrame);
+ m_wakeupTimer.startOneShot(delayTime, FROM_HERE);
+ m_frameSchedulingState = frameSchedulingState;
+}
+
+void SMILTimeContainer::wakeupTimerFired(Timer<SMILTimeContainer>*)
+{
+ ASSERT(m_frameSchedulingState == SynchronizeAnimations || m_frameSchedulingState == FutureAnimationFrame);
+ if (m_frameSchedulingState == FutureAnimationFrame) {
+ ASSERT(isTimelineRunning());
+ m_frameSchedulingState = Idle;
+ serviceOnNextFrame();
+ } else {
+ m_frameSchedulingState = Idle;
+ updateAnimationsAndScheduleFrameIfNeeded(elapsed());
+ }
}
void SMILTimeContainer::updateDocumentOrderIndexes()
{
unsigned timingElementCount = 0;
- for (Element* element = m_ownerSVGElement; element; element = ElementTraversal::next(*element, m_ownerSVGElement)) {
- if (isSVGSMILElement(*element))
- toSVGSMILElement(element)->setDocumentOrderIndex(timingElementCount++);
- }
+ for (SVGSMILElement* element = Traversal<SVGSMILElement>::firstWithin(m_ownerSVGElement); element; element = Traversal<SVGSMILElement>::next(*element, &m_ownerSVGElement))
+ element->setDocumentOrderIndex(timingElementCount++);
m_documentOrderIndexesDirty = false;
}
struct PriorityCompare {
PriorityCompare(SMILTime elapsed) : m_elapsed(elapsed) {}
- bool operator()(SVGSMILElement* a, SVGSMILElement* b)
+ bool operator()(const RefPtrWillBeMember<SVGSMILElement>& a, const RefPtrWillBeMember<SVGSMILElement>& b)
{
// FIXME: This should also consider possible timing relations between the elements.
SMILTime aBegin = a->intervalBegin();
@@ -252,14 +321,54 @@ struct PriorityCompare {
SMILTime m_elapsed;
};
-void SMILTimeContainer::sortByPriority(Vector<SVGSMILElement*>& smilElements, SMILTime elapsed)
+Document& SMILTimeContainer::document() const
{
- if (m_documentOrderIndexesDirty)
- updateDocumentOrderIndexes();
- std::sort(smilElements.begin(), smilElements.end(), PriorityCompare(elapsed));
+ return m_ownerSVGElement.document();
}
-void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
+double SMILTimeContainer::currentTime() const
+{
+ return document().animationClock().currentTime();
+}
+
+void SMILTimeContainer::serviceOnNextFrame()
+{
+ if (document().view()) {
+ document().view()->scheduleAnimation();
+ m_frameSchedulingState = AnimationFrame;
+ }
+}
+
+void SMILTimeContainer::serviceAnimations(double monotonicAnimationStartTime)
+{
+ if (m_frameSchedulingState != AnimationFrame)
+ return;
+
+ m_frameSchedulingState = Idle;
+ updateAnimationsAndScheduleFrameIfNeeded(elapsed());
+}
+
+void SMILTimeContainer::updateAnimationsAndScheduleFrameIfNeeded(SMILTime elapsed, bool seekToTime)
+{
+#if !ENABLE(OILPAN)
+ DiscardScope discardScope(m_ownerSVGElement);
+#endif
+ SMILTime earliestFireTime = updateAnimations(elapsed, seekToTime);
+ // If updateAnimations() ended up triggering a synchronization (most likely
+ // via syncbases), then give that priority.
+ if (hasPendingSynchronization())
+ return;
+
+ if (!isTimelineRunning())
+ return;
+
+ if (!earliestFireTime.isFinite())
+ return;
+
+ scheduleAnimationFrame(earliestFireTime);
+}
+
+SMILTime SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
{
SMILTime earliestFireTime = SMILTime::unresolved();
@@ -269,21 +378,31 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
m_preventScheduledAnimationsChanges = true;
#endif
+ if (m_documentOrderIndexesDirty)
+ updateDocumentOrderIndexes();
+
+ WillBeHeapHashSet<ElementAttributePair> invalidKeys;
+ typedef WillBeHeapVector<RefPtrWillBeMember<SVGSMILElement> > AnimationsVector;
AnimationsVector animationsToApply;
- GroupedAnimationsMap::iterator end = m_scheduledAnimations.end();
- for (GroupedAnimationsMap::iterator it = m_scheduledAnimations.begin(); it != end; ++it) {
- AnimationsVector* scheduled = it->value.get();
+ for (GroupedAnimationsMap::iterator it = m_scheduledAnimations.begin(), end = m_scheduledAnimations.end(); it != end; ++it) {
+ if (!it->key.first || it->value->isEmpty()) {
+ invalidKeys.add(it->key);
+ continue;
+ }
+
+ AnimationsLinkedHashSet* scheduled = it->value.get();
// Sort according to priority. Elements with later begin time have higher priority.
// In case of a tie, document order decides.
// FIXME: This should also consider timing relationships between the elements. Dependents
// have higher priority.
- sortByPriority(*scheduled, elapsed);
+ AnimationsVector scheduledAnimations;
+ copyToVector(*scheduled, scheduledAnimations);
+ std::sort(scheduledAnimations.begin(), scheduledAnimations.end(), PriorityCompare(elapsed));
SVGSMILElement* resultElement = 0;
- unsigned size = scheduled->size();
- for (unsigned n = 0; n < size; n++) {
- SVGSMILElement* animation = scheduled->at(n);
+ for (AnimationsVector::const_iterator itAnimation = scheduledAnimations.begin(), itAnimationEnd = scheduledAnimations.end(); itAnimation != itAnimationEnd; ++itAnimation) {
+ SVGSMILElement* animation = itAnimation->get();
ASSERT(animation->timeContainer() == this);
ASSERT(animation->targetElement());
ASSERT(animation->hasValidAttributeName());
@@ -302,20 +421,22 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
SMILTime nextFireTime = animation->nextProgressTime();
if (nextFireTime.isFinite())
- earliestFireTime = min(nextFireTime, earliestFireTime);
+ earliestFireTime = std::min(nextFireTime, earliestFireTime);
}
if (resultElement)
animationsToApply.append(resultElement);
}
+ m_scheduledAnimations.removeAll(invalidKeys);
+
+ std::sort(animationsToApply.begin(), animationsToApply.end(), PriorityCompare(elapsed));
unsigned animationsToApplySize = animationsToApply.size();
if (!animationsToApplySize) {
#ifndef NDEBUG
m_preventScheduledAnimationsChanges = false;
#endif
- startTimer(earliestFireTime, animationFrameDelay);
- return;
+ return earliestFireTime;
}
// Apply results to target elements.
@@ -326,7 +447,27 @@ void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
m_preventScheduledAnimationsChanges = false;
#endif
- startTimer(earliestFireTime, animationFrameDelay);
+ for (unsigned i = 0; i < animationsToApplySize; ++i) {
+ if (animationsToApply[i]->inDocument() && animationsToApply[i]->isSVGDiscardElement()) {
+ RefPtrWillBeRawPtr<SVGSMILElement> animDiscard = animationsToApply[i];
+ RefPtrWillBeRawPtr<SVGElement> targetElement = animDiscard->targetElement();
+ if (targetElement && targetElement->inDocument()) {
+ targetElement->remove(IGNORE_EXCEPTION);
+ ASSERT(!targetElement->inDocument());
+ }
+
+ if (animDiscard->inDocument()) {
+ animDiscard->remove(IGNORE_EXCEPTION);
+ ASSERT(!animDiscard->inDocument());
+ }
+ }
+ }
+ return earliestFireTime;
+}
+
+void SMILTimeContainer::trace(Visitor* visitor)
+{
+ visitor->trace(m_scheduledAnimations);
}
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.h b/chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.h
index 86b24ab46d1..66ab950b331 100644
--- a/chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.h
+++ b/chromium/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.h
@@ -29,6 +29,7 @@
#include "core/dom/QualifiedName.h"
#include "core/svg/animation/SMILTime.h"
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
#include "wtf/PassRefPtr.h"
@@ -38,13 +39,14 @@
namespace WebCore {
+class Document;
class SVGElement;
class SVGSMILElement;
class SVGSVGElement;
-class SMILTimeContainer : public RefCounted<SMILTimeContainer> {
+class SMILTimeContainer : public RefCountedWillBeGarbageCollectedFinalized<SMILTimeContainer> {
public:
- static PassRefPtr<SMILTimeContainer> create(SVGSVGElement* owner) { return adoptRef(new SMILTimeContainer(owner)); }
+ static PassRefPtrWillBeRawPtr<SMILTimeContainer> create(SVGSVGElement& owner) { return adoptRefWillBeNoop(new SMILTimeContainer(owner)); }
~SMILTimeContainer();
void schedule(SVGSMILElement*, SVGElement*, const QualifiedName&);
@@ -53,7 +55,6 @@ public:
SMILTime elapsed() const;
- bool isActive() const;
bool isPaused() const;
bool isStarted() const;
@@ -62,35 +63,60 @@ public:
void resume();
void setElapsed(SMILTime);
+ void serviceAnimations(double monotonicAnimationStartTime);
+ bool hasAnimations() const;
+
void setDocumentOrderIndexesDirty() { m_documentOrderIndexesDirty = true; }
-private:
- SMILTimeContainer(SVGSVGElement* owner);
+ void trace(Visitor*);
- void timerFired(Timer<SMILTimeContainer>*);
- void startTimer(SMILTime fireTime, SMILTime minimumDelay = 0);
- void updateAnimations(SMILTime elapsed, bool seekToTime = false);
+private:
+ explicit SMILTimeContainer(SVGSVGElement& owner);
+
+ enum FrameSchedulingState {
+ // No frame scheduled.
+ Idle,
+ // Scheduled a wakeup to update the animation values.
+ SynchronizeAnimations,
+ // Scheduled a wakeup to trigger an animation frame.
+ FutureAnimationFrame,
+ // Scheduled a animation frame for continuous update.
+ AnimationFrame
+ };
+
+ bool isTimelineRunning() const;
+ void scheduleAnimationFrame(SMILTime fireTime);
+ void cancelAnimationFrame();
+ void wakeupTimerFired(Timer<SMILTimeContainer>*);
+ void updateAnimationsAndScheduleFrameIfNeeded(SMILTime elapsed, bool seekToTime = false);
+ SMILTime updateAnimations(SMILTime elapsed, bool seekToTime = false);
+ void serviceOnNextFrame();
+ void scheduleWakeUp(double delayTime, FrameSchedulingState);
+ bool hasPendingSynchronization() const;
void updateDocumentOrderIndexes();
- void sortByPriority(Vector<SVGSMILElement*>& smilElements, SMILTime elapsed);
double lastResumeTime() const { return m_resumeTime ? m_resumeTime : m_beginTime; }
+ Document& document() const;
+ double currentTime() const;
+
double m_beginTime;
double m_pauseTime;
double m_resumeTime;
double m_accumulatedActiveTime;
double m_presetStartTime;
+ FrameSchedulingState m_frameSchedulingState;
bool m_documentOrderIndexesDirty;
- Timer<SMILTimeContainer> m_timer;
+ Timer<SMILTimeContainer> m_wakeupTimer;
- typedef pair<SVGElement*, QualifiedName> ElementAttributePair;
- typedef Vector<SVGSMILElement*> AnimationsVector;
- typedef HashMap<ElementAttributePair, OwnPtr<AnimationsVector> > GroupedAnimationsMap;
+ typedef pair<RawPtrWillBeWeakMember<SVGElement>, QualifiedName> ElementAttributePair;
+ typedef WillBeHeapLinkedHashSet<RawPtrWillBeWeakMember<SVGSMILElement> > AnimationsLinkedHashSet;
+ typedef WillBeHeapHashMap<ElementAttributePair, OwnPtrWillBeMember<AnimationsLinkedHashSet> > GroupedAnimationsMap;
GroupedAnimationsMap m_scheduledAnimations;
- SVGSVGElement* m_ownerSVGElement;
+ SVGSVGElement& m_ownerSVGElement;
#ifndef NDEBUG
bool m_preventScheduledAnimationsChanges;
diff --git a/chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp b/chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
index 7dbc0aedd5b..2d8f9c4844c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.cpp
@@ -26,9 +26,9 @@
#include "config.h"
#include "core/svg/animation/SVGSMILElement.h"
-#include "SVGNames.h"
-#include "XLinkNames.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "bindings/v8/ScriptEventListener.h"
+#include "core/XLinkNames.h"
#include "core/dom/Document.h"
#include "core/events/EventListener.h"
#include "core/events/EventSender.h"
@@ -41,26 +41,31 @@
#include "wtf/StdLibExtras.h"
#include "wtf/Vector.h"
-using namespace std;
-
namespace WebCore {
-class RepeatEvent : public Event {
+class RepeatEvent FINAL : public Event {
public:
- static PassRefPtr<RepeatEvent> create(const AtomicString& type, int repeat)
+ static PassRefPtrWillBeRawPtr<RepeatEvent> create(const AtomicString& type, int repeat)
{
- return adoptRef(new RepeatEvent(type, false, false, repeat));
+ return adoptRefWillBeNoop(new RepeatEvent(type, false, false, repeat));
}
- ~RepeatEvent() { }
+ virtual ~RepeatEvent() { }
int repeat() const { return m_repeat; }
+
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ Event::trace(visitor);
+ }
+
protected:
RepeatEvent(const AtomicString& type, bool canBubble, bool cancelable, int repeat = -1)
: Event(type, canBubble, cancelable)
, m_repeat(repeat)
{
}
+
private:
int m_repeat;
};
@@ -98,7 +103,7 @@ static SMILEventSender& smilRepeatNEventSender()
// This is used for duration type time values that can't be negative.
static const double invalidCachedTime = -1.;
-class ConditionEventListener : public EventListener {
+class ConditionEventListener FINAL : public EventListener {
public:
static PassRefPtr<ConditionEventListener> create(SVGSMILElement* animation, SVGSMILElement::Condition* condition)
{
@@ -112,7 +117,7 @@ public:
: 0;
}
- virtual bool operator==(const EventListener& other);
+ virtual bool operator==(const EventListener& other) OVERRIDE;
void disconnectAnimation()
{
@@ -127,7 +132,7 @@ private:
{
}
- virtual void handleEvent(ExecutionContext*, Event*);
+ virtual void handleEvent(ExecutionContext*, Event*) OVERRIDE;
SVGSMILElement* m_animation;
SVGSMILElement::Condition* m_condition;
@@ -147,6 +152,11 @@ void ConditionEventListener::handleEvent(ExecutionContext*, Event* event)
m_animation->handleConditionEvent(event, m_condition);
}
+void SVGSMILElement::Condition::setEventListener(PassRefPtr<ConditionEventListener> eventListener)
+{
+ m_eventListener = eventListener;
+}
+
SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeat)
: m_type(type)
, m_beginOrEnd(beginOrEnd)
@@ -160,12 +170,11 @@ SVGSMILElement::Condition::Condition(Type type, BeginOrEnd beginOrEnd, const Str
SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc)
: SVGElement(tagName, doc)
, m_attributeName(anyQName())
- , m_targetElement(0)
- , m_conditionsConnected(false)
+ , m_targetElement(nullptr)
+ , m_syncBaseConditionsConnected(false)
, m_hasEndEventConditions(false)
, m_isWaitingForFirstInterval(true)
- , m_intervalBegin(SMILTime::unresolved())
- , m_intervalEnd(SMILTime::unresolved())
+ , m_interval(SMILInterval(SMILTime::unresolved(), SMILTime::unresolved()))
, m_previousIntervalBegin(SMILTime::unresolved())
, m_activeState(Inactive)
, m_lastPercent(0)
@@ -183,24 +192,36 @@ SVGSMILElement::SVGSMILElement(const QualifiedName& tagName, Document& doc)
SVGSMILElement::~SVGSMILElement()
{
- clearResourceReferences();
+#if !ENABLE(OILPAN)
+ clearResourceAndEventBaseReferences();
+#endif
smilEndEventSender().cancelEvent(this);
smilBeginEventSender().cancelEvent(this);
smilRepeatEventSender().cancelEvent(this);
smilRepeatNEventSender().cancelEvent(this);
- disconnectConditions();
+#if !ENABLE(OILPAN)
+ clearConditions();
+
if (m_timeContainer && m_targetElement && hasValidAttributeName())
m_timeContainer->unschedule(this, m_targetElement, m_attributeName);
+#endif
+}
+
+void SVGSMILElement::clearResourceAndEventBaseReferences()
+{
+ document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
}
-void SVGSMILElement::clearResourceReferences()
+void SVGSMILElement::clearConditions()
{
- document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+ disconnectSyncBaseConditions();
+ disconnectEventBaseConditions();
+ m_conditions.clear();
}
void SVGSMILElement::buildPendingResource()
{
- clearResourceReferences();
+ clearResourceAndEventBaseReferences();
if (!inDocument()) {
// Reset the target element if we are no longer in the document.
@@ -208,13 +229,13 @@ void SVGSMILElement::buildPendingResource()
return;
}
- String id;
- String href = getAttribute(XLinkNames::hrefAttr);
+ AtomicString id;
+ AtomicString href = getAttribute(XLinkNames::hrefAttr);
Element* target;
if (href.isEmpty())
target = parentNode() && parentNode()->isElementNode() ? toElement(parentNode()) : 0;
else
- target = SVGURIReference::targetElementFromIRIString(href, document(), &id);
+ target = SVGURIReference::targetElementFromIRIString(href, treeScope(), &id);
SVGElement* svgTarget = target && target->isSVGElement() ? toSVGElement(target) : 0;
if (svgTarget && !svgTarget->inDocument())
@@ -225,18 +246,19 @@ void SVGSMILElement::buildPendingResource()
if (!svgTarget) {
// Do not register as pending if we are already pending this resource.
- if (document().accessSVGExtensions()->isElementPendingResource(this, id))
+ if (document().accessSVGExtensions().isElementPendingResource(this, id))
return;
if (!id.isEmpty()) {
- document().accessSVGExtensions()->addPendingResource(id, this);
+ document().accessSVGExtensions().addPendingResource(id, this);
ASSERT(hasPendingResources());
}
} else {
// Register us with the target in the dependencies map. Any change of hrefElement
// that leads to relayout/repainting now informs us, so we can react to it.
- document().accessSVGExtensions()->addElementReferencingTarget(this, svgTarget);
+ document().accessSVGExtensions().addElementReferencingTarget(this, svgTarget);
}
+ connectEventBaseConditions();
}
static inline QualifiedName constructQualifiedName(const SVGElement* svgElement, const AtomicString& attributeName)
@@ -249,7 +271,7 @@ static inline QualifiedName constructQualifiedName(const SVGElement* svgElement,
AtomicString prefix;
AtomicString localName;
- if (!Document::parseQualifiedName(attributeName, prefix, localName, ASSERT_NO_EXCEPTION))
+ if (!Document::parseQualifiedName(attributeName, prefix, localName, IGNORE_EXCEPTION))
return anyQName();
const AtomicString& namespaceURI = svgElement->lookupNamespaceURI(prefix);
@@ -273,8 +295,8 @@ void SVGSMILElement::reset()
m_activeState = Inactive;
m_isWaitingForFirstInterval = true;
- m_intervalBegin = SMILTime::unresolved();
- m_intervalEnd = SMILTime::unresolved();
+ m_interval.begin = SMILTime::unresolved();
+ m_interval.end = SMILTime::unresolved();
m_previousIntervalBegin = SMILTime::unresolved();
m_lastPercent = 0;
m_lastRepeat = 0;
@@ -285,12 +307,10 @@ void SVGSMILElement::reset()
Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode* rootParent)
{
SVGElement::insertedInto(rootParent);
+
if (!rootParent->inDocument())
return InsertionDone;
- // Verify we are not in <use> instance tree.
- ASSERT(!isInShadowTree() || !parentOrShadowHostElement() || !parentOrShadowHostElement()->isSVGElement());
-
setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr)));
SVGSVGElement* owner = ownerSVGElement();
if (!owner)
@@ -318,12 +338,12 @@ Node::InsertionNotificationRequest SVGSMILElement::insertedInto(ContainerNode* r
void SVGSMILElement::removedFrom(ContainerNode* rootParent)
{
if (rootParent->inDocument()) {
- clearResourceReferences();
- disconnectConditions();
+ clearResourceAndEventBaseReferences();
+ clearConditions();
setTargetElement(0);
setAttributeName(anyQName());
animationAttributeChanged();
- m_timeContainer = 0;
+ m_timeContainer = nullptr;
}
SVGElement::removedFrom(rootParent);
@@ -452,7 +472,7 @@ bool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd)
} else
type = Condition::EventBase;
- m_conditions.append(Condition(type, beginOrEnd, baseID, nameString, offset, repeat));
+ m_conditions.append(Condition::create(type, beginOrEnd, baseID, nameString, offset, repeat));
if (type == Condition::EventBase && beginOrEnd == End)
m_hasEndEventConditions = true;
@@ -501,22 +521,26 @@ void SVGSMILElement::parseAttribute(const QualifiedName& name, const AtomicStrin
{
if (name == SVGNames::beginAttr) {
if (!m_conditions.isEmpty()) {
- disconnectConditions();
- m_conditions.clear();
+ clearConditions();
parseBeginOrEnd(fastGetAttribute(SVGNames::endAttr), End);
}
parseBeginOrEnd(value.string(), Begin);
if (inDocument())
- connectConditions();
+ connectSyncBaseConditions();
} else if (name == SVGNames::endAttr) {
if (!m_conditions.isEmpty()) {
- disconnectConditions();
- m_conditions.clear();
+ clearConditions();
parseBeginOrEnd(fastGetAttribute(SVGNames::beginAttr), Begin);
}
parseBeginOrEnd(value.string(), End);
if (inDocument())
- connectConditions();
+ connectSyncBaseConditions();
+ } else if (name == SVGNames::onbeginAttr) {
+ setAttributeEventListener(EventTypeNames::beginEvent, createAttributeEventListener(this, name, value, eventParameterName()));
+ } else if (name == SVGNames::onendAttr) {
+ setAttributeEventListener(EventTypeNames::endEvent, createAttributeEventListener(this, name, value, eventParameterName()));
+ } else if (name == SVGNames::onrepeatAttr) {
+ setAttributeEventListener(EventTypeNames::repeatEvent, createAttributeEventListener(this, name, value, eventParameterName()));
} else
SVGElement::parseAttribute(name, value);
}
@@ -541,7 +565,7 @@ void SVGSMILElement::svgAttributeChanged(const QualifiedName& attrName)
else if (attrName == SVGNames::attributeNameAttr)
setAttributeName(constructQualifiedName(this, fastGetAttribute(SVGNames::attributeNameAttr)));
else if (attrName.matches(XLinkNames::hrefAttr)) {
- SVGElementInstance::InvalidationGuard invalidationGuard(this);
+ SVGElement::InvalidationGuard invalidationGuard(this);
buildPendingResource();
if (m_targetElement)
clearAnimatedType(m_targetElement);
@@ -555,64 +579,90 @@ void SVGSMILElement::svgAttributeChanged(const QualifiedName& attrName)
animationAttributeChanged();
}
-inline Element* SVGSMILElement::eventBaseFor(const Condition& condition)
+inline SVGElement* SVGSMILElement::eventBaseFor(const Condition& condition)
{
- return condition.m_baseID.isEmpty() ? targetElement() : treeScope().getElementById(condition.m_baseID);
+ Element* eventBase = condition.baseID().isEmpty() ? targetElement() : treeScope().getElementById(AtomicString(condition.baseID()));
+ if (eventBase && eventBase->isSVGElement())
+ return toSVGElement(eventBase);
+ return 0;
}
-void SVGSMILElement::connectConditions()
+void SVGSMILElement::connectSyncBaseConditions()
{
- if (m_conditionsConnected)
- disconnectConditions();
- m_conditionsConnected = true;
+ if (m_syncBaseConditionsConnected)
+ disconnectSyncBaseConditions();
+ m_syncBaseConditionsConnected = true;
for (unsigned n = 0; n < m_conditions.size(); ++n) {
- Condition& condition = m_conditions[n];
- if (condition.m_type == Condition::EventBase) {
- ASSERT(!condition.m_syncbase);
- Element* eventBase = eventBaseFor(condition);
- if (!eventBase)
- continue;
- ASSERT(!condition.m_eventListener);
- condition.m_eventListener = ConditionEventListener::create(this, &condition);
- eventBase->addEventListener(condition.m_name, condition.m_eventListener, false);
- } else if (condition.m_type == Condition::Syncbase) {
- ASSERT(!condition.m_baseID.isEmpty());
- condition.m_syncbase = treeScope().getElementById(condition.m_baseID);
- if (!condition.m_syncbase || !isSVGSMILElement(*condition.m_syncbase)) {
- condition.m_syncbase = 0;
+ Condition* condition = m_conditions[n].get();
+ if (condition->type() == Condition::Syncbase) {
+ ASSERT(!condition->baseID().isEmpty());
+ Element* element = treeScope().getElementById(AtomicString(condition->baseID()));
+ if (!element || !isSVGSMILElement(*element)) {
+ condition->setSyncBase(0);
continue;
}
- toSVGSMILElement(condition.m_syncbase.get())->addTimeDependent(this);
+ SVGSMILElement* svgSMILElement = toSVGSMILElement(element);
+ condition->setSyncBase(svgSMILElement);
+ svgSMILElement->addSyncBaseDependent(this);
}
}
}
-void SVGSMILElement::disconnectConditions()
+void SVGSMILElement::disconnectSyncBaseConditions()
{
- if (!m_conditionsConnected)
+ if (!m_syncBaseConditionsConnected)
return;
- m_conditionsConnected = false;
+ m_syncBaseConditionsConnected = false;
for (unsigned n = 0; n < m_conditions.size(); ++n) {
- Condition& condition = m_conditions[n];
- if (condition.m_type == Condition::EventBase) {
- ASSERT(!condition.m_syncbase);
- if (!condition.m_eventListener)
+ Condition* condition = m_conditions[n].get();
+ if (condition->type() == Condition::Syncbase) {
+ if (condition->syncBase())
+ condition->syncBase()->removeSyncBaseDependent(this);
+ condition->setSyncBase(0);
+ }
+ }
+}
+
+void SVGSMILElement::connectEventBaseConditions()
+{
+ disconnectEventBaseConditions();
+ for (unsigned n = 0; n < m_conditions.size(); ++n) {
+ Condition* condition = m_conditions[n].get();
+ if (condition->type() == Condition::EventBase) {
+ ASSERT(!condition->syncBase());
+ SVGElement* eventBase = eventBaseFor(*condition);
+ if (!eventBase) {
+ if (!condition->baseID().isEmpty() && !document().accessSVGExtensions().isElementPendingResource(this, AtomicString(condition->baseID())))
+ document().accessSVGExtensions().addPendingResource(AtomicString(condition->baseID()), this);
+ continue;
+ }
+ ASSERT(!condition->eventListener());
+ condition->setEventListener(ConditionEventListener::create(this, condition));
+ eventBase->addEventListener(AtomicString(condition->name()), condition->eventListener(), false);
+ document().accessSVGExtensions().addElementReferencingTarget(this, eventBase);
+ }
+ }
+}
+
+void SVGSMILElement::disconnectEventBaseConditions()
+{
+ for (unsigned n = 0; n < m_conditions.size(); ++n) {
+ Condition* condition = m_conditions[n].get();
+ if (condition->type() == Condition::EventBase) {
+ ASSERT(!condition->syncBase());
+ if (!condition->eventListener())
continue;
// Note: It's a memory optimization to try to remove our condition
// event listener, but it's not guaranteed to work, since we have
// no guarantee that eventBaseFor() will be able to find our condition's
// original eventBase. So, we also have to disconnect ourselves from
// our condition event listener, in case it later fires.
- Element* eventBase = eventBaseFor(condition);
+ SVGElement* eventBase = eventBaseFor(*condition);
if (eventBase)
- eventBase->removeEventListener(condition.m_name, condition.m_eventListener.get(), false);
- condition.m_eventListener->disconnectAnimation();
- condition.m_eventListener = 0;
- } else if (condition.m_type == Condition::Syncbase) {
- if (condition.m_syncbase)
- toSVGSMILElement(condition.m_syncbase.get())->removeTimeDependent(this);
+ eventBase->removeEventListener(AtomicString(condition->name()), condition->eventListener(), false);
+ condition->eventListener()->disconnectAnimation();
+ condition->setEventListener(nullptr);
}
- condition.m_syncbase = 0;
}
}
@@ -644,7 +694,7 @@ void SVGSMILElement::setTargetElement(SVGElement* target)
if (m_targetElement) {
// Clear values that may depend on the previous target.
clearAnimatedType(m_targetElement);
- disconnectConditions();
+ disconnectSyncBaseConditions();
}
// If the animation state is not Inactive, always reset to a clear state before leaving the old target element.
@@ -659,11 +709,6 @@ SMILTime SVGSMILElement::elapsed() const
return m_timeContainer ? m_timeContainer->elapsed() : 0;
}
-bool SVGSMILElement::isInactive() const
-{
- return m_activeState == Inactive;
-}
-
bool SVGSMILElement::isFrozen() const
{
return m_activeState == Frozen;
@@ -712,16 +757,21 @@ SMILTime SVGSMILElement::repeatCount() const
{
if (m_cachedRepeatCount != invalidCachedTime)
return m_cachedRepeatCount;
+ SMILTime computedRepeatCount = SMILTime::unresolved();
const AtomicString& value = fastGetAttribute(SVGNames::repeatCountAttr);
- if (value.isNull())
- return SMILTime::unresolved();
-
- DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite", AtomicString::ConstructFromLiteral));
- if (value == indefiniteValue)
- return SMILTime::indefinite();
- bool ok;
- double result = value.string().toDouble(&ok);
- return m_cachedRepeatCount = ok && result > 0 ? result : SMILTime::unresolved();
+ if (!value.isNull()) {
+ DEFINE_STATIC_LOCAL(const AtomicString, indefiniteValue, ("indefinite", AtomicString::ConstructFromLiteral));
+ if (value == indefiniteValue) {
+ computedRepeatCount = SMILTime::indefinite();
+ } else {
+ bool ok;
+ double result = value.string().toDouble(&ok);
+ if (ok && result > 0)
+ computedRepeatCount = result;
+ }
+ }
+ m_cachedRepeatCount = computedRepeatCount;
+ return m_cachedRepeatCount;
}
SMILTime SVGSMILElement::maxValue() const
@@ -730,7 +780,7 @@ SMILTime SVGSMILElement::maxValue() const
return m_cachedMax;
const AtomicString& value = fastGetAttribute(SVGNames::maxAttr);
SMILTime result = parseClockValue(value);
- return m_cachedMax = (result.isUnresolved() || result < 0) ? SMILTime::indefinite() : result;
+ return m_cachedMax = (result.isUnresolved() || result <= 0) ? SMILTime::indefinite() : result;
}
SMILTime SVGSMILElement::minValue() const
@@ -744,7 +794,7 @@ SMILTime SVGSMILElement::minValue() const
SMILTime SVGSMILElement::simpleDuration() const
{
- return min(dur(), SMILTime::indefinite());
+ return std::min(dur(), SMILTime::indefinite());
}
void SVGSMILElement::addBeginTime(SMILTime eventTime, SMILTime beginTime, SMILTimeWithOrigin::Origin origin)
@@ -763,9 +813,9 @@ void SVGSMILElement::addEndTime(SMILTime eventTime, SMILTime endTime, SMILTimeWi
endListChanged(eventTime);
}
-inline SMILTime extractTimeFromVector(const SMILTimeWithOrigin* position)
+inline bool compareTimes(const SMILTimeWithOrigin& left, const SMILTimeWithOrigin& right)
{
- return position->time();
+ return left.time() < right.time();
}
SMILTime SVGSMILElement::findInstanceTime(BeginOrEnd beginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const
@@ -776,21 +826,17 @@ SMILTime SVGSMILElement::findInstanceTime(BeginOrEnd beginOrEnd, SMILTime minimu
if (!sizeOfList)
return beginOrEnd == Begin ? SMILTime::unresolved() : SMILTime::indefinite();
- const SMILTimeWithOrigin* result = approximateBinarySearch<const SMILTimeWithOrigin, SMILTime>(list, sizeOfList, minimumTime, extractTimeFromVector);
+ const SMILTimeWithOrigin dummyTimeWithOrigin(minimumTime, SMILTimeWithOrigin::ParserOrigin);
+ const SMILTimeWithOrigin* result = std::lower_bound(list.begin(), list.end(), dummyTimeWithOrigin, compareTimes);
int indexOfResult = result - list.begin();
- ASSERT_WITH_SECURITY_IMPLICATION(indexOfResult < sizeOfList);
-
- if (list[indexOfResult].time() < minimumTime && indexOfResult < sizeOfList - 1)
- ++indexOfResult;
-
+ if (indexOfResult == sizeOfList)
+ return SMILTime::unresolved();
const SMILTime& currentTime = list[indexOfResult].time();
// The special value "indefinite" does not yield an instance time in the begin list.
if (currentTime.isIndefinite() && beginOrEnd == Begin)
return SMILTime::unresolved();
- if (currentTime < minimumTime)
- return SMILTime::unresolved();
if (currentTime > minimumTime)
return currentTime;
@@ -820,7 +866,7 @@ SMILTime SVGSMILElement::repeatingDuration() const
if (!simpleDuration || (repeatDur.isUnresolved() && repeatCount.isUnresolved()))
return simpleDuration;
SMILTime repeatCountDuration = simpleDuration * repeatCount;
- return min(repeatCountDuration, min(repeatDur, SMILTime::indefinite()));
+ return std::min(repeatCountDuration, std::min(repeatDur, SMILTime::indefinite()));
}
SMILTime SVGSMILElement::resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const
@@ -833,7 +879,7 @@ SMILTime SVGSMILElement::resolveActiveEnd(SMILTime resolvedBegin, SMILTime resol
else if (!resolvedEnd.isFinite())
preliminaryActiveDuration = repeatingDuration();
else
- preliminaryActiveDuration = min(repeatingDuration(), resolvedEnd - resolvedBegin);
+ preliminaryActiveDuration = std::min(repeatingDuration(), resolvedEnd - resolvedBegin);
SMILTime minValue = this->minValue();
SMILTime maxValue = this->maxValue();
@@ -843,16 +889,17 @@ SMILTime SVGSMILElement::resolveActiveEnd(SMILTime resolvedBegin, SMILTime resol
minValue = 0;
maxValue = SMILTime::indefinite();
}
- return resolvedBegin + min(maxValue, max(minValue, preliminaryActiveDuration));
+ return resolvedBegin + std::min(maxValue, std::max(minValue, preliminaryActiveDuration));
}
-void SVGSMILElement::resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const
+SMILInterval SVGSMILElement::resolveInterval(ResolveInterval resolveIntervalType) const
{
+ bool first = resolveIntervalType == FirstInterval;
// See the pseudocode in http://www.w3.org/TR/SMIL3/smil-timing.html#q90.
- SMILTime beginAfter = first ? -numeric_limits<double>::infinity() : m_intervalEnd;
- SMILTime lastIntervalTempEnd = numeric_limits<double>::infinity();
+ SMILTime beginAfter = first ? -std::numeric_limits<double>::infinity() : m_interval.end;
+ SMILTime lastIntervalTempEnd = std::numeric_limits<double>::infinity();
while (true) {
- bool equalsMinimumOK = !first || m_intervalEnd > m_intervalBegin;
+ bool equalsMinimumOK = !first || m_interval.end > m_interval.begin;
SMILTime tempBegin = findInstanceTime(Begin, beginAfter, equalsMinimumOK);
if (tempBegin.isUnresolved())
break;
@@ -861,7 +908,7 @@ void SVGSMILElement::resolveInterval(bool first, SMILTime& beginResult, SMILTime
tempEnd = resolveActiveEnd(tempBegin, SMILTime::indefinite());
else {
tempEnd = findInstanceTime(End, tempBegin, true);
- if ((first && tempBegin == tempEnd && tempEnd == lastIntervalTempEnd) || (!first && tempEnd == m_intervalEnd))
+ if ((first && tempBegin == tempEnd && tempEnd == lastIntervalTempEnd) || (!first && tempEnd == m_interval.end))
tempEnd = findInstanceTime(End, tempBegin, false);
if (tempEnd.isUnresolved()) {
if (!m_endTimes.isEmpty() && !m_hasEndEventConditions)
@@ -869,31 +916,24 @@ void SVGSMILElement::resolveInterval(bool first, SMILTime& beginResult, SMILTime
}
tempEnd = resolveActiveEnd(tempBegin, tempEnd);
}
- if (!first || (tempEnd > 0 || (!tempBegin.value() && !tempEnd.value()))) {
- beginResult = tempBegin;
- endResult = tempEnd;
- return;
- }
+ if (!first || (tempEnd > 0 || (!tempBegin.value() && !tempEnd.value())))
+ return SMILInterval(tempBegin, tempEnd);
beginAfter = tempEnd;
lastIntervalTempEnd = tempEnd;
}
- beginResult = SMILTime::unresolved();
- endResult = SMILTime::unresolved();
+ return SMILInterval(SMILTime::unresolved(), SMILTime::unresolved());
}
void SVGSMILElement::resolveFirstInterval()
{
- SMILTime begin;
- SMILTime end;
- resolveInterval(true, begin, end);
- ASSERT(!begin.isIndefinite());
+ SMILInterval firstInterval = resolveInterval(FirstInterval);
+ ASSERT(!firstInterval.begin.isIndefinite());
- if (!begin.isUnresolved() && (begin != m_intervalBegin || end != m_intervalEnd)) {
- m_intervalBegin = begin;
- m_intervalEnd = end;
+ if (!firstInterval.begin.isUnresolved() && firstInterval != m_interval) {
+ m_interval = firstInterval;
notifyDependentsIntervalChanged();
- m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin);
+ m_nextProgressTime = std::min(m_nextProgressTime, m_interval.begin);
if (m_timeContainer)
m_timeContainer->notifyIntervalsChanged();
@@ -902,16 +942,13 @@ void SVGSMILElement::resolveFirstInterval()
bool SVGSMILElement::resolveNextInterval()
{
- SMILTime begin;
- SMILTime end;
- resolveInterval(false, begin, end);
- ASSERT(!begin.isIndefinite());
+ SMILInterval nextInterval = resolveInterval(NextInterval);
+ ASSERT(!nextInterval.begin.isIndefinite());
- if (!begin.isUnresolved() && begin != m_intervalBegin) {
- m_intervalBegin = begin;
- m_intervalEnd = end;
+ if (!nextInterval.begin.isUnresolved() && nextInterval.begin != m_interval.begin) {
+ m_interval = nextInterval;
notifyDependentsIntervalChanged();
- m_nextProgressTime = min(m_nextProgressTime, m_intervalBegin);
+ m_nextProgressTime = std::min(m_nextProgressTime, m_interval.begin);
return true;
}
@@ -929,14 +966,14 @@ void SVGSMILElement::beginListChanged(SMILTime eventTime)
resolveFirstInterval();
else {
SMILTime newBegin = findInstanceTime(Begin, eventTime, true);
- if (newBegin.isFinite() && (m_intervalEnd <= eventTime || newBegin < m_intervalBegin)) {
+ if (newBegin.isFinite() && (m_interval.end <= eventTime || newBegin < m_interval.begin)) {
// Begin time changed, re-resolve the interval.
- SMILTime oldBegin = m_intervalBegin;
- m_intervalEnd = eventTime;
- resolveInterval(false, m_intervalBegin, m_intervalEnd);
- ASSERT(!m_intervalBegin.isUnresolved());
- if (m_intervalBegin != oldBegin) {
- if (m_activeState == Active && m_intervalBegin > eventTime) {
+ SMILTime oldBegin = m_interval.begin;
+ m_interval.end = eventTime;
+ m_interval = resolveInterval(NextInterval);
+ ASSERT(!m_interval.begin.isUnresolved());
+ if (m_interval.begin != oldBegin) {
+ if (m_activeState == Active && m_interval.begin > eventTime) {
m_activeState = determineActiveState(eventTime);
if (m_activeState != Active)
endedActiveInterval();
@@ -954,14 +991,14 @@ void SVGSMILElement::beginListChanged(SMILTime eventTime)
void SVGSMILElement::endListChanged(SMILTime)
{
SMILTime elapsed = this->elapsed();
- if (m_isWaitingForFirstInterval)
+ if (m_isWaitingForFirstInterval) {
resolveFirstInterval();
- else if (elapsed < m_intervalEnd && m_intervalBegin.isFinite()) {
- SMILTime newEnd = findInstanceTime(End, m_intervalBegin, false);
- if (newEnd < m_intervalEnd) {
- newEnd = resolveActiveEnd(m_intervalBegin, newEnd);
- if (newEnd != m_intervalEnd) {
- m_intervalEnd = newEnd;
+ } else if (elapsed < m_interval.end && m_interval.begin.isFinite()) {
+ SMILTime newEnd = findInstanceTime(End, m_interval.begin, false);
+ if (newEnd < m_interval.end) {
+ newEnd = resolveActiveEnd(m_interval.begin, newEnd);
+ if (newEnd != m_interval.end) {
+ m_interval.end = newEnd;
notifyDependentsIntervalChanged();
}
}
@@ -972,38 +1009,41 @@ void SVGSMILElement::endListChanged(SMILTime)
m_timeContainer->notifyIntervalsChanged();
}
-void SVGSMILElement::checkRestart(SMILTime elapsed)
+SVGSMILElement::RestartedInterval SVGSMILElement::maybeRestartInterval(SMILTime elapsed)
{
ASSERT(!m_isWaitingForFirstInterval);
- ASSERT(elapsed >= m_intervalBegin);
+ ASSERT(elapsed >= m_interval.begin);
Restart restart = this->restart();
if (restart == RestartNever)
- return;
+ return DidNotRestartInterval;
- if (elapsed < m_intervalEnd) {
+ if (elapsed < m_interval.end) {
if (restart != RestartAlways)
- return;
- SMILTime nextBegin = findInstanceTime(Begin, m_intervalBegin, false);
- if (nextBegin < m_intervalEnd) {
- m_intervalEnd = nextBegin;
+ return DidNotRestartInterval;
+ SMILTime nextBegin = findInstanceTime(Begin, m_interval.begin, false);
+ if (nextBegin < m_interval.end) {
+ m_interval.end = nextBegin;
notifyDependentsIntervalChanged();
}
}
- if (elapsed >= m_intervalEnd)
- resolveNextInterval();
+ if (elapsed >= m_interval.end) {
+ if (resolveNextInterval() && elapsed >= m_interval.begin)
+ return DidRestartInterval;
+ }
+ return DidNotRestartInterval;
}
void SVGSMILElement::seekToIntervalCorrespondingToTime(SMILTime elapsed)
{
ASSERT(!m_isWaitingForFirstInterval);
- ASSERT(elapsed >= m_intervalBegin);
+ ASSERT(elapsed >= m_interval.begin);
// Manually seek from interval to interval, just as if the animation would run regulary.
while (true) {
// Figure out the next value in the begin time list after the current interval begin.
- SMILTime nextBegin = findInstanceTime(Begin, m_intervalBegin, false);
+ SMILTime nextBegin = findInstanceTime(Begin, m_interval.begin, false);
// If the 'nextBegin' time is unresolved (eg. just one defined interval), we're done seeking.
if (nextBegin.isUnresolved())
@@ -1011,16 +1051,16 @@ void SVGSMILElement::seekToIntervalCorrespondingToTime(SMILTime elapsed)
// If the 'nextBegin' time is larger than or equal to the current interval end time, we're done seeking.
// If the 'elapsed' time is smaller than the next begin interval time, we're done seeking.
- if (nextBegin < m_intervalEnd && elapsed >= nextBegin) {
+ if (nextBegin < m_interval.end && elapsed >= nextBegin) {
// End current interval, and start a new interval from the 'nextBegin' time.
- m_intervalEnd = nextBegin;
+ m_interval.end = nextBegin;
if (!resolveNextInterval())
break;
continue;
}
// If the desired 'elapsed' time is past the current interval, advance to the next.
- if (elapsed >= m_intervalEnd) {
+ if (elapsed >= m_interval.end) {
if (!resolveNextInterval())
break;
continue;
@@ -1042,18 +1082,18 @@ float SVGSMILElement::calculateAnimationPercentAndRepeat(SMILTime elapsed, unsig
repeat = 0;
return 1.f;
}
- ASSERT(m_intervalBegin.isFinite());
+ ASSERT(m_interval.begin.isFinite());
ASSERT(simpleDuration.isFinite());
- SMILTime activeTime = elapsed - m_intervalBegin;
+ SMILTime activeTime = elapsed - m_interval.begin;
SMILTime repeatingDuration = this->repeatingDuration();
- if (elapsed >= m_intervalEnd || activeTime > repeatingDuration) {
+ if (elapsed >= m_interval.end || activeTime > repeatingDuration) {
repeat = static_cast<unsigned>(repeatingDuration.value() / simpleDuration.value());
if (!fmod(repeatingDuration.value(), simpleDuration.value()))
repeat--;
- double percent = (m_intervalEnd.value() - m_intervalBegin.value()) / simpleDuration.value();
+ double percent = (m_interval.end.value() - m_interval.begin.value()) / simpleDuration.value();
percent = percent - floor(percent);
- if (percent < numeric_limits<float>::epsilon() || 1 - percent < numeric_limits<float>::epsilon())
+ if (percent < std::numeric_limits<float>::epsilon() || 1 - percent < std::numeric_limits<float>::epsilon())
return 1.0f;
return narrowPrecisionToFloat(percent);
}
@@ -1067,22 +1107,22 @@ SMILTime SVGSMILElement::calculateNextProgressTime(SMILTime elapsed) const
if (m_activeState == Active) {
// If duration is indefinite the value does not actually change over time. Same is true for <set>.
SMILTime simpleDuration = this->simpleDuration();
- if (simpleDuration.isIndefinite() || hasTagName(SVGNames::setTag)) {
- SMILTime repeatingDurationEnd = m_intervalBegin + repeatingDuration();
+ if (simpleDuration.isIndefinite() || isSVGSetElement(*this)) {
+ SMILTime repeatingDurationEnd = m_interval.begin + repeatingDuration();
// We are supposed to do freeze semantics when repeating ends, even if the element is still active.
// Take care that we get a timer callback at that point.
- if (elapsed < repeatingDurationEnd && repeatingDurationEnd < m_intervalEnd && repeatingDurationEnd.isFinite())
+ if (elapsed < repeatingDurationEnd && repeatingDurationEnd < m_interval.end && repeatingDurationEnd.isFinite())
return repeatingDurationEnd;
- return m_intervalEnd;
+ return m_interval.end;
}
return elapsed + 0.025;
}
- return m_intervalBegin >= elapsed ? m_intervalBegin : SMILTime::unresolved();
+ return m_interval.begin >= elapsed ? m_interval.begin : SMILTime::unresolved();
}
SVGSMILElement::ActiveState SVGSMILElement::determineActiveState(SMILTime elapsed) const
{
- if (elapsed >= m_intervalBegin && elapsed < m_intervalEnd)
+ if (elapsed >= m_interval.begin && elapsed < m_interval.end)
return Active;
return fill() == FillFreeze ? Frozen : Inactive;
@@ -1091,36 +1131,38 @@ SVGSMILElement::ActiveState SVGSMILElement::determineActiveState(SMILTime elapse
bool SVGSMILElement::isContributing(SMILTime elapsed) const
{
// Animation does not contribute during the active time if it is past its repeating duration and has fill=remove.
- return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_intervalBegin + repeatingDuration())) || m_activeState == Frozen;
+ return (m_activeState == Active && (fill() == FillFreeze || elapsed <= m_interval.begin + repeatingDuration())) || m_activeState == Frozen;
}
bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, bool seekToTime)
{
ASSERT(resultElement);
ASSERT(m_timeContainer);
- ASSERT(m_isWaitingForFirstInterval || m_intervalBegin.isFinite());
+ ASSERT(m_isWaitingForFirstInterval || m_interval.begin.isFinite());
- if (!m_conditionsConnected)
- connectConditions();
+ if (!m_syncBaseConditionsConnected)
+ connectSyncBaseConditions();
- if (!m_intervalBegin.isFinite()) {
+ if (!m_interval.begin.isFinite()) {
ASSERT(m_activeState == Inactive);
m_nextProgressTime = SMILTime::unresolved();
return false;
}
- if (elapsed < m_intervalBegin) {
+ if (elapsed < m_interval.begin) {
ASSERT(m_activeState != Active);
- if (m_activeState == Frozen) {
+ bool isFrozen = (m_activeState == Frozen);
+ if (isFrozen) {
if (this == resultElement)
resetAnimatedType();
updateAnimation(m_lastPercent, m_lastRepeat, resultElement);
}
- m_nextProgressTime = m_intervalBegin;
- return false;
+ m_nextProgressTime = m_interval.begin;
+ // If the animation is frozen, it's still contributing.
+ return isFrozen;
}
- m_previousIntervalBegin = m_intervalBegin;
+ m_previousIntervalBegin = m_interval.begin;
if (m_isWaitingForFirstInterval) {
m_isWaitingForFirstInterval = false;
@@ -1130,16 +1172,16 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
// This call may obtain a new interval -- never call calculateAnimationPercentAndRepeat() before!
if (seekToTime) {
seekToIntervalCorrespondingToTime(elapsed);
- if (elapsed < m_intervalBegin) {
+ if (elapsed < m_interval.begin) {
// elapsed is not within an interval.
- m_nextProgressTime = m_intervalBegin;
+ m_nextProgressTime = m_interval.begin;
return false;
}
}
unsigned repeat = 0;
float percent = calculateAnimationPercentAndRepeat(elapsed, repeat);
- checkRestart(elapsed);
+ RestartedInterval restartedInterval = maybeRestartInterval(elapsed);
ActiveState oldActiveState = m_activeState;
m_activeState = determineActiveState(elapsed);
@@ -1150,7 +1192,7 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
resetAnimatedType();
if (animationIsContributing) {
- if (oldActiveState == Inactive) {
+ if (oldActiveState == Inactive || restartedInterval == DidRestartInterval) {
smilBeginEventSender().dispatchEventSoon(this);
startedActiveInterval();
}
@@ -1163,10 +1205,10 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
m_lastRepeat = repeat;
}
- if (oldActiveState == Active && m_activeState != Active) {
+ if ((oldActiveState == Active && m_activeState != Active) || restartedInterval == DidRestartInterval) {
smilEndEventSender().dispatchEventSoon(this);
endedActiveInterval();
- if (m_activeState != Frozen && this == resultElement)
+ if (!animationIsContributing && this == resultElement)
clearAnimatedType(m_targetElement);
}
@@ -1192,36 +1234,40 @@ bool SVGSMILElement::progress(SMILTime elapsed, SVGSMILElement* resultElement, b
void SVGSMILElement::notifyDependentsIntervalChanged()
{
- ASSERT(m_intervalBegin.isFinite());
- DEFINE_STATIC_LOCAL(HashSet<SVGSMILElement*>, loopBreaker, ());
- if (!loopBreaker.add(this).isNewEntry)
+ ASSERT(m_interval.begin.isFinite());
+ // |loopBreaker| is used to avoid infinite recursions which may be caused from:
+ // |notifyDependentsIntervalChanged| -> |createInstanceTimesFromSyncbase| -> |add{Begin,End}Time| -> |{begin,end}TimeChanged| -> |notifyDependentsIntervalChanged|
+ // |loopBreaker| is defined as a Persistent<HeapHashSet<Member<SVGSMILElement> > >. This won't cause leaks because it is guaranteed to be empty after the root |notifyDependentsIntervalChanged| has exited.
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<WillBeHeapHashSet<RawPtrWillBeMember<SVGSMILElement> > >, loopBreaker, (adoptPtrWillBeNoop(new WillBeHeapHashSet<RawPtrWillBeMember<SVGSMILElement> >())));
+ if (!loopBreaker->add(this).isNewEntry)
return;
- TimeDependentSet::iterator end = m_timeDependents.end();
- for (TimeDependentSet::iterator it = m_timeDependents.begin(); it != end; ++it) {
+ TimeDependentSet::iterator end = m_syncBaseDependents.end();
+ for (TimeDependentSet::iterator it = m_syncBaseDependents.begin(); it != end; ++it) {
SVGSMILElement* dependent = *it;
dependent->createInstanceTimesFromSyncbase(this);
}
- loopBreaker.remove(this);
+ loopBreaker->remove(this);
}
-void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncbase)
+void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncBase)
{
// FIXME: To be really correct, this should handle updating exising interval by changing
// the associated times instead of creating new ones.
for (unsigned n = 0; n < m_conditions.size(); ++n) {
- Condition& condition = m_conditions[n];
- if (condition.m_type == Condition::Syncbase && condition.m_syncbase == syncbase) {
- ASSERT(condition.m_name == "begin" || condition.m_name == "end");
+ Condition* condition = m_conditions[n].get();
+ if (condition->type() == Condition::Syncbase && condition->syncBase() == syncBase) {
+ ASSERT(condition->name() == "begin" || condition->name() == "end");
// No nested time containers in SVG, no need for crazy time space conversions. Phew!
SMILTime time = 0;
- if (condition.m_name == "begin")
- time = syncbase->m_intervalBegin + condition.m_offset;
+ if (condition->name() == "begin")
+ time = syncBase->m_interval.begin + condition->offset();
else
- time = syncbase->m_intervalEnd + condition.m_offset;
- ASSERT(time.isFinite());
- if (condition.m_beginOrEnd == Begin)
+ time = syncBase->m_interval.end + condition->offset();
+ if (!time.isFinite())
+ continue;
+ if (condition->beginOrEnd() == Begin)
addBeginTime(elapsed(), time);
else
addEndTime(elapsed(), time);
@@ -1229,28 +1275,28 @@ void SVGSMILElement::createInstanceTimesFromSyncbase(SVGSMILElement* syncbase)
}
}
-void SVGSMILElement::addTimeDependent(SVGSMILElement* animation)
+void SVGSMILElement::addSyncBaseDependent(SVGSMILElement* animation)
{
- m_timeDependents.add(animation);
- if (m_intervalBegin.isFinite())
+ m_syncBaseDependents.add(animation);
+ if (m_interval.begin.isFinite())
animation->createInstanceTimesFromSyncbase(this);
}
-void SVGSMILElement::removeTimeDependent(SVGSMILElement* animation)
+void SVGSMILElement::removeSyncBaseDependent(SVGSMILElement* animation)
{
- m_timeDependents.remove(animation);
+ m_syncBaseDependents.remove(animation);
}
void SVGSMILElement::handleConditionEvent(Event* event, Condition* condition)
{
- if (event->type() == "repeatn" && toRepeatEvent(event)->repeat() != condition->m_repeat)
+ if (event->type() == "repeatn" && toRepeatEvent(event)->repeat() != condition->repeat())
return;
SMILTime elapsed = this->elapsed();
- if (condition->m_beginOrEnd == Begin)
- addBeginTime(elapsed, elapsed + condition->m_offset);
+ if (condition->beginOrEnd() == Begin)
+ addBeginTime(elapsed, elapsed + condition->offset());
else
- addEndTime(elapsed, elapsed + condition->m_offset);
+ addEndTime(elapsed, elapsed + condition->offset());
}
void SVGSMILElement::beginByLinkActivation()
@@ -1285,4 +1331,22 @@ void SVGSMILElement::dispatchPendingEvent(SMILEventSender* eventSender)
}
}
+SVGSMILElement::Condition::~Condition()
+{
+}
+
+void SVGSMILElement::Condition::trace(Visitor* visitor)
+{
+ visitor->trace(m_syncBase);
+}
+
+void SVGSMILElement::trace(Visitor* visitor)
+{
+ visitor->trace(m_targetElement);
+ visitor->trace(m_timeContainer);
+ visitor->trace(m_conditions);
+ visitor->trace(m_syncBaseDependents);
+ SVGElement::trace(visitor);
+}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.h b/chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.h
index 44c4fa19a47..bc3a815f9db 100644
--- a/chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.h
+++ b/chromium/third_party/WebKit/Source/core/svg/animation/SVGSMILElement.h
@@ -26,9 +26,10 @@
#ifndef SVGSMILElement_h
#define SVGSMILElement_h
-#include "SVGNames.h"
+#include "core/SVGNames.h"
#include "core/svg/SVGElement.h"
#include "core/svg/animation/SMILTime.h"
+#include "platform/heap/Heap.h"
#include "wtf/HashMap.h"
namespace WebCore {
@@ -86,8 +87,7 @@ public:
SMILTime elapsed() const;
- SMILTime intervalBegin() const { return m_intervalBegin; }
- SMILTime intervalEnd() const { return m_intervalEnd; }
+ SMILTime intervalBegin() const { return m_interval.begin; }
SMILTime previousIntervalBegin() const { return m_previousIntervalBegin; }
SMILTime simpleDuration() const;
@@ -101,22 +101,25 @@ public:
static SMILTime parseOffsetValue(const String&);
bool isContributing(SMILTime elapsed) const;
- bool isInactive() const;
bool isFrozen() const;
unsigned documentOrderIndex() const { return m_documentOrderIndex; }
void setDocumentOrderIndex(unsigned index) { m_documentOrderIndex = index; }
- virtual bool isAdditive() const = 0;
virtual void resetAnimatedType() = 0;
virtual void clearAnimatedType(SVGElement* targetElement) = 0;
virtual void applyResultsToTarget() = 0;
- void connectConditions();
+ void connectSyncBaseConditions();
+ void connectEventBaseConditions();
void dispatchPendingEvent(SMILEventSender*);
void dispatchRepeatEvents(unsigned);
+ virtual bool isSVGDiscardElement() const { return false; }
+
+ void trace(Visitor*) OVERRIDE;
+
protected:
void addBeginTime(SMILTime eventTime, SMILTime endTime, SMILTimeWithOrigin::Origin = SMILTimeWithOrigin::ParserOrigin);
void addEndTime(SMILTime eventTime, SMILTime endTime, SMILTimeWithOrigin::Origin = SMILTimeWithOrigin::ParserOrigin);
@@ -128,8 +131,9 @@ protected:
virtual void setAttributeName(const QualifiedName&);
private:
- void buildPendingResource();
- void clearResourceReferences();
+ virtual void buildPendingResource() OVERRIDE;
+ void clearResourceAndEventBaseReferences();
+ void clearConditions();
virtual void startedActiveInterval() = 0;
void endedActiveInterval();
@@ -143,18 +147,31 @@ private:
};
SMILTime findInstanceTime(BeginOrEnd, SMILTime minimumTime, bool equalsMinimumOK) const;
+
+ enum ResolveInterval {
+ FirstInterval,
+ NextInterval
+ };
+
+ SMILInterval resolveInterval(ResolveInterval) const;
void resolveFirstInterval();
bool resolveNextInterval();
- void resolveInterval(bool first, SMILTime& beginResult, SMILTime& endResult) const;
SMILTime resolveActiveEnd(SMILTime resolvedBegin, SMILTime resolvedEnd) const;
SMILTime repeatingDuration() const;
- void checkRestart(SMILTime elapsed);
+
+ enum RestartedInterval {
+ DidNotRestartInterval,
+ DidRestartInterval
+ };
+
+ RestartedInterval maybeRestartInterval(SMILTime elapsed);
void beginListChanged(SMILTime eventTime);
void endListChanged(SMILTime eventTime);
// This represents conditions on elements begin or end list that need to be resolved on runtime
// for example <animate begin="otherElement.begin + 8s; button.click" ... />
- struct Condition {
+ class Condition : public NoBaseWillBeGarbageCollectedFinalized<Condition> {
+ public:
enum Type {
EventBase,
Syncbase,
@@ -162,28 +179,48 @@ private:
};
Condition(Type, BeginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeat = -1);
+ static PassOwnPtrWillBeRawPtr<Condition> create(Type type, BeginOrEnd beginOrEnd, const String& baseID, const String& name, SMILTime offset, int repeat = -1)
+ {
+ return adoptPtrWillBeNoop(new Condition(type, beginOrEnd, baseID, name, offset, repeat));
+ }
+ ~Condition();
+ void trace(Visitor*);
+
+ Type type() const { return m_type; }
+ BeginOrEnd beginOrEnd() const { return m_beginOrEnd; }
+ String baseID() const { return m_baseID; }
+ String name() const { return m_name; }
+ SMILTime offset() const { return m_offset; }
+ int repeat() const { return m_repeat; }
+ SVGSMILElement* syncBase() const { return m_syncBase.get(); }
+ void setSyncBase(SVGSMILElement* element) { m_syncBase = element; }
+ ConditionEventListener* eventListener() const { return m_eventListener.get(); }
+ void setEventListener(PassRefPtr<ConditionEventListener>);
+
+ private:
Type m_type;
BeginOrEnd m_beginOrEnd;
String m_baseID;
String m_name;
SMILTime m_offset;
int m_repeat;
- RefPtr<Element> m_syncbase;
+ RefPtrWillBeMember<SVGSMILElement> m_syncBase;
RefPtr<ConditionEventListener> m_eventListener;
};
bool parseCondition(const String&, BeginOrEnd beginOrEnd);
void parseBeginOrEnd(const String&, BeginOrEnd beginOrEnd);
- Element* eventBaseFor(const Condition&);
+ SVGElement* eventBaseFor(const Condition&);
- void disconnectConditions();
+ void disconnectSyncBaseConditions();
+ void disconnectEventBaseConditions();
// Event base timing
void handleConditionEvent(Event*, Condition*);
void notifyDependentsIntervalChanged();
void createInstanceTimesFromSyncbase(SVGSMILElement* syncbase);
- void addTimeDependent(SVGSMILElement*);
- void removeTimeDependent(SVGSMILElement*);
+ void addSyncBaseDependent(SVGSMILElement*);
+ void removeSyncBaseDependent(SVGSMILElement*);
enum ActiveState {
Inactive,
@@ -197,24 +234,23 @@ private:
float calculateAnimationPercentAndRepeat(SMILTime elapsed, unsigned& repeat) const;
SMILTime calculateNextProgressTime(SMILTime elapsed) const;
- mutable SVGElement* m_targetElement;
+ RawPtrWillBeMember<SVGElement> m_targetElement;
- Vector<Condition> m_conditions;
- bool m_conditionsConnected;
+ WillBeHeapVector<OwnPtrWillBeMember<Condition> > m_conditions;
+ bool m_syncBaseConditionsConnected;
bool m_hasEndEventConditions;
bool m_isWaitingForFirstInterval;
- typedef HashSet<SVGSMILElement*> TimeDependentSet;
- TimeDependentSet m_timeDependents;
+ typedef WillBeHeapHashSet<RawPtrWillBeMember<SVGSMILElement> > TimeDependentSet;
+ TimeDependentSet m_syncBaseDependents;
// Instance time lists
Vector<SMILTimeWithOrigin> m_beginTimes;
Vector<SMILTimeWithOrigin> m_endTimes;
// This is the upcoming or current interval
- SMILTime m_intervalBegin;
- SMILTime m_intervalEnd;
+ SMILInterval m_interval;
SMILTime m_previousIntervalBegin;
@@ -224,7 +260,7 @@ private:
SMILTime m_nextProgressTime;
- RefPtr<SMILTimeContainer> m_timeContainer;
+ RefPtrWillBeMember<SMILTimeContainer> m_timeContainer;
unsigned m_documentOrderIndex;
Vector<unsigned> m_repeatEventCountList;
@@ -241,10 +277,10 @@ private:
inline bool isSVGSMILElement(const Node& node)
{
return node.hasTagName(SVGNames::setTag) || node.hasTagName(SVGNames::animateTag) || node.hasTagName(SVGNames::animateMotionTag)
- || node.hasTagName(SVGNames::animateTransformTag) || node.hasTagName(SVGNames::animateColorTag);
+ || node.hasTagName(SVGNames::animateTransformTag) || node.hasTagName((SVGNames::discardTag));
}
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement);
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index 5526ab7ebf2..42d28302a49 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -29,21 +29,25 @@
#include "core/svg/graphics/SVGImage.h"
+#include "core/animation/AnimationTimeline.h"
+#include "core/dom/NoEventDispatchAssertion.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/shadow/ComposedTreeWalker.h"
-#include "core/loader/DocumentLoader.h"
-#include "core/page/Chrome.h"
-#include "core/frame/Frame.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/loader/FrameLoadRequest.h"
+#include "core/page/Chrome.h"
#include "core/rendering/style/RenderStyle.h"
#include "core/rendering/svg/RenderSVGRoot.h"
-#include "core/svg/SVGDocument.h"
+#include "core/svg/SVGDocumentExtensions.h"
#include "core/svg/SVGFEImageElement.h"
#include "core/svg/SVGImageElement.h"
#include "core/svg/SVGSVGElement.h"
+#include "core/svg/animation/SMILTimeContainer.h"
#include "core/svg/graphics/SVGImageChromeClient.h"
#include "platform/LengthFunctions.h"
+#include "platform/TraceEvent.h"
#include "platform/geometry/IntRect.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/graphics/ImageBuffer.h"
@@ -61,19 +65,20 @@ SVGImage::~SVGImage()
{
if (m_page) {
// Store m_page in a local variable, clearing m_page, so that SVGImageChromeClient knows we're destructed.
- OwnPtr<Page> currentPage = m_page.release();
- currentPage->mainFrame()->loader().frameDetached(); // Break both the loader and view references to the frame
+ OwnPtrWillBeRawPtr<Page> currentPage = m_page.release();
+ // Break both the loader and view references to the frame
+ currentPage->willBeDestroyed();
}
// Verify that page teardown destroyed the Chrome
ASSERT(!m_chromeClient || !m_chromeClient->image());
}
-bool SVGImage::isInSVGImage(const Element* element)
+bool SVGImage::isInSVGImage(const Node* node)
{
- ASSERT(element);
+ ASSERT(node);
- Page* page = element->document().page();
+ Page* page = node->document().page();
if (!page)
return false;
@@ -85,11 +90,11 @@ bool SVGImage::currentFrameHasSingleSecurityOrigin() const
if (!m_page)
return true;
- Frame* frame = m_page->mainFrame();
+ LocalFrame* frame = toLocalFrame(m_page->mainFrame());
RELEASE_ASSERT(frame->document()->loadEventFinished());
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
+ SVGSVGElement* rootElement = frame->document()->accessSVGExtensions().rootElement();
if (!rootElement)
return true;
@@ -97,12 +102,15 @@ bool SVGImage::currentFrameHasSingleSecurityOrigin() const
// single-origin since these can leak cross-origin information.
ComposedTreeWalker walker(rootElement);
while (Node* node = walker.get()) {
- if (node->hasTagName(SVGNames::foreignObjectTag))
+ if (isSVGForeignObjectElement(*node))
return false;
- if (node->hasTagName(SVGNames::imageTag))
- return toSVGImageElement(node)->currentFrameHasSingleSecurityOrigin();
- if (node->hasTagName(SVGNames::feImageTag))
- return toSVGFEImageElement(node)->currentFrameHasSingleSecurityOrigin();
+ if (isSVGImageElement(*node)) {
+ if (!toSVGImageElement(*node).currentFrameHasSingleSecurityOrigin())
+ return false;
+ } else if (isSVGFEImageElement(*node)) {
+ if (!toSVGFEImageElement(*node).currentFrameHasSingleSecurityOrigin())
+ return false;
+ }
walker.next();
}
@@ -111,13 +119,20 @@ bool SVGImage::currentFrameHasSingleSecurityOrigin() const
return true;
}
+static SVGSVGElement* svgRootElement(Page* page)
+{
+ if (!page)
+ return 0;
+ LocalFrame* frame = toLocalFrame(page->mainFrame());
+ return frame->document()->accessSVGExtensions().rootElement();
+}
+
void SVGImage::setContainerSize(const IntSize& size)
{
- if (!m_page || !usesContainerSize())
+ if (!usesContainerSize())
return;
- Frame* frame = m_page->mainFrame();
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
+ SVGSVGElement* rootElement = svgRootElement(m_page.get());
if (!rootElement)
return;
@@ -132,10 +147,7 @@ void SVGImage::setContainerSize(const IntSize& size)
IntSize SVGImage::containerSize() const
{
- if (!m_page)
- return IntSize();
- Frame* frame = m_page->mainFrame();
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
+ SVGSVGElement* rootElement = svgRootElement(m_page.get());
if (!rootElement)
return IntSize();
@@ -151,16 +163,21 @@ IntSize SVGImage::containerSize() const
// Assure that a container size is always given for a non-identity zoom level.
ASSERT(renderer->style()->effectiveZoom() == 1);
- FloatSize currentSize;
- if (rootElement->intrinsicWidth().isFixed() && rootElement->intrinsicHeight().isFixed())
- currentSize = rootElement->currentViewportSize();
- else
- currentSize = rootElement->currentViewBoxRect().size();
+ FloatSize intrinsicSize;
+ double intrinsicRatio = 0;
+ renderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio);
+
+ if (intrinsicSize.isEmpty() && intrinsicRatio) {
+ if (!intrinsicSize.width() && intrinsicSize.height())
+ intrinsicSize.setWidth(intrinsicSize.height() * intrinsicRatio);
+ else if (intrinsicSize.width() && !intrinsicSize.height())
+ intrinsicSize.setHeight(intrinsicSize.width() / intrinsicRatio);
+ }
- if (!currentSize.isEmpty())
- return IntSize(static_cast<int>(ceilf(currentSize.width())), static_cast<int>(ceilf(currentSize.height())));
+ if (!intrinsicSize.isEmpty())
+ return expandedIntSize(intrinsicSize);
- // As last resort, use CSS default intrinsic size.
+ // As last resort, use CSS replaced element fallback size.
return IntSize(300, 150);
}
@@ -190,11 +207,11 @@ void SVGImage::drawForContainer(GraphicsContext* context, const FloatSize contai
PassRefPtr<NativeImageSkia> SVGImage::nativeImageForCurrentFrame()
{
if (!m_page)
- return 0;
+ return nullptr;
OwnPtr<ImageBuffer> buffer = ImageBuffer::create(size());
if (!buffer)
- return 0;
+ return nullptr;
drawForContainer(buffer->context(), size(), 1, rect(), rect(), CompositeSourceOver, blink::WebBlendModeNormal);
@@ -210,6 +227,8 @@ void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize
// The ImageBuffer size needs to be scaled to match the final resolution.
// FIXME: No need to get the full CTM here, we just need the scale.
+ // FIXME: See crbug.com/382491. This scale does not reflect compositor applied
+ // scale factors, such a High DPI or device zoom.
AffineTransform transform = context->getCTM();
FloatSize imageBufferScale = FloatSize(transform.xScale(), transform.yScale());
ASSERT(imageBufferScale.width());
@@ -242,8 +261,15 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl
GraphicsContextStateSaver stateSaver(*context);
context->setCompositeOperation(compositeOp, blendMode);
context->clip(enclosingIntRect(dstRect));
- if (compositeOp != CompositeSourceOver)
- context->beginTransparencyLayer(1);
+
+ bool compositingRequiresTransparencyLayer = compositeOp != CompositeSourceOver || blendMode != blink::WebBlendModeNormal;
+ float opacity = context->getNormalizedAlpha() / 255.f;
+ bool requiresTransparencyLayer = compositingRequiresTransparencyLayer || opacity < 1;
+ if (requiresTransparencyLayer) {
+ context->beginTransparencyLayer(opacity);
+ if (compositingRequiresTransparencyLayer)
+ context->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal);
+ }
FloatSize scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height());
@@ -253,31 +279,37 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl
FloatPoint destOffset = dstRect.location() - topLeftOffset;
context->translate(destOffset.x(), destOffset.y());
- context->scale(scale);
+ context->scale(scale.width(), scale.height());
FrameView* view = frameView();
view->resize(containerSize());
+ if (!m_url.isEmpty())
+ view->scrollToFragment(m_url);
+
if (view->needsLayout())
view->layout();
view->paint(context, enclosingIntRect(srcRect));
+ ASSERT(!view->needsLayout());
- if (compositeOp != CompositeSourceOver)
+ if (requiresTransparencyLayer)
context->endLayer();
stateSaver.restore();
if (imageObserver())
imageObserver()->didDraw(this);
+
+ // Start any (SMIL) animations if needed. This will restart or continue
+ // animations if preceded by calls to resetAnimation or stopAnimation
+ // respectively.
+ startAnimation();
}
RenderBox* SVGImage::embeddedContentBox() const
{
- if (!m_page)
- return 0;
- Frame* frame = m_page->mainFrame();
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
+ SVGSVGElement* rootElement = svgRootElement(m_page.get());
if (!rootElement)
return 0;
return toRenderBox(rootElement->renderer());
@@ -288,69 +320,37 @@ FrameView* SVGImage::frameView() const
if (!m_page)
return 0;
- return m_page->mainFrame()->view();
-}
-
-bool SVGImage::hasRelativeWidth() const
-{
- if (!m_page)
- return false;
- Frame* frame = m_page->mainFrame();
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
- if (!rootElement)
- return false;
- return rootElement->intrinsicWidth().isPercent();
-}
-
-bool SVGImage::hasRelativeHeight() const
-{
- if (!m_page)
- return false;
- Frame* frame = m_page->mainFrame();
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
- if (!rootElement)
- return false;
- return rootElement->intrinsicHeight().isPercent();
+ return toLocalFrame(m_page->mainFrame())->view();
}
void SVGImage::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio)
{
- if (!m_page)
- return;
- Frame* frame = m_page->mainFrame();
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
+ SVGSVGElement* rootElement = svgRootElement(m_page.get());
if (!rootElement)
return;
intrinsicWidth = rootElement->intrinsicWidth();
intrinsicHeight = rootElement->intrinsicHeight();
- if (rootElement->preserveAspectRatioCurrentValue().align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
+ if (rootElement->preserveAspectRatio()->currentValue()->align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
return;
- intrinsicRatio = rootElement->viewBoxCurrentValue().size();
+ intrinsicRatio = rootElement->viewBox()->currentValue()->value().size();
if (intrinsicRatio.isEmpty() && intrinsicWidth.isFixed() && intrinsicHeight.isFixed())
intrinsicRatio = FloatSize(floatValueForLength(intrinsicWidth, 0), floatValueForLength(intrinsicHeight, 0));
}
-// FIXME: support catchUpIfNecessary.
-void SVGImage::startAnimation(bool /* catchUpIfNecessary */)
+// FIXME: support CatchUpAnimation = CatchUp.
+void SVGImage::startAnimation(CatchUpAnimation)
{
- if (!m_page)
- return;
- Frame* frame = m_page->mainFrame();
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
- if (!rootElement)
+ SVGSVGElement* rootElement = svgRootElement(m_page.get());
+ if (!rootElement || !rootElement->animationsPaused())
return;
rootElement->unpauseAnimations();
- rootElement->setCurrentTime(0);
}
void SVGImage::stopAnimation()
{
- if (!m_page)
- return;
- Frame* frame = m_page->mainFrame();
- SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
+ SVGSVGElement* rootElement = svgRootElement(m_page.get());
if (!rootElement)
return;
rootElement->pauseAnimations();
@@ -358,7 +358,19 @@ void SVGImage::stopAnimation()
void SVGImage::resetAnimation()
{
- stopAnimation();
+ SVGSVGElement* rootElement = svgRootElement(m_page.get());
+ if (!rootElement)
+ return;
+ rootElement->pauseAnimations();
+ rootElement->setCurrentTime(0);
+}
+
+bool SVGImage::hasAnimations() const
+{
+ SVGSVGElement* rootElement = svgRootElement(m_page.get());
+ if (!rootElement)
+ return false;
+ return rootElement->timeContainer()->hasAnimations() || toLocalFrame(m_page->mainFrame())->document()->timeline().hasPendingUpdates();
}
bool SVGImage::dataChanged(bool allDataReceived)
@@ -370,7 +382,13 @@ bool SVGImage::dataChanged(bool allDataReceived)
return true;
if (allDataReceived) {
- static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient;
+ // SVGImage will fire events (and the default C++ handlers run) but doesn't
+ // actually allow script to run so it's fine to call into it. We allow this
+ // since it means an SVG data url can synchronously load like other image
+ // types.
+ NoEventDispatchAssertion::AllowSVGImageEvents allowSVGImageEvents;
+
+ static FrameLoaderClient* dummyFrameLoaderClient = new EmptyFrameLoaderClient;
Page::PageClients pageClients;
fillWithEmptyClients(pageClients);
@@ -383,13 +401,12 @@ bool SVGImage::dataChanged(bool allDataReceived)
// This will become an issue when SVGImage will be able to load other
// SVGImage objects, but we're safe now, because SVGImage can only be
// loaded by a top-level document.
- m_page = adoptPtr(new Page(pageClients));
- m_page->settings().setMediaEnabled(false);
- m_page->settings().setScriptEnabled(false);
- m_page->settings().setPluginsEnabled(false);
- m_page->settings().setAcceleratedCompositingEnabled(false);
+ OwnPtrWillBeRawPtr<Page> page = adoptPtrWillBeNoop(new Page(pageClients));
+ page->settings().setScriptEnabled(false);
+ page->settings().setPluginsEnabled(false);
+ page->settings().setAcceleratedCompositingEnabled(false);
- RefPtr<Frame> frame = Frame::create(FrameInit::create(0, m_page.get(), dummyFrameLoaderClient));
+ RefPtr<LocalFrame> frame = LocalFrame::create(dummyFrameLoaderClient, &page->frameHost(), 0);
frame->setView(FrameView::create(frame.get()));
frame->init();
FrameLoader& loader = frame->loader();
@@ -399,10 +416,9 @@ bool SVGImage::dataChanged(bool allDataReceived)
frame->view()->setCanHaveScrollbars(false); // SVG Images will always synthesize a viewBox, if it's not available, and thus never see scrollbars.
frame->view()->setTransparent(true); // SVG Images are transparent.
- ASSERT(loader.activeDocumentLoader()); // DocumentLoader should have been created by frame->init().
- DocumentWriter* writer = loader.activeDocumentLoader()->beginWriting("image/svg+xml", "UTF-8");
- writer->addData(data()->data(), data()->size());
- loader.activeDocumentLoader()->endWriting(writer);
+ m_page = page.release();
+
+ loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), "image/svg+xml", "UTF-8", KURL(), ForceSynchronousLoad)));
// Set the intrinsic size before a container size is available.
m_intrinsicSize = containerSize();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.h b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
index 19838c9e31d..b7074a8a17a 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
@@ -28,42 +28,46 @@
#define SVGImage_h
#include "platform/graphics/Image.h"
+#include "platform/heap/Handle.h"
+#include "platform/weborigin/KURL.h"
namespace WebCore {
-class Element;
class FrameView;
-class ImageBuffer;
class Page;
class RenderBox;
class SVGImageChromeClient;
class SVGImageForContainer;
-class SVGImage : public Image {
+class SVGImage FINAL : public Image {
public:
static PassRefPtr<SVGImage> create(ImageObserver* observer)
{
return adoptRef(new SVGImage(observer));
}
- static bool isInSVGImage(const Element*);
+ static bool isInSVGImage(const Node*);
RenderBox* embeddedContentBox() const;
virtual bool isSVGImage() const OVERRIDE { return true; }
virtual IntSize size() const OVERRIDE { return m_intrinsicSize; }
+ void setURL(const KURL& url) { m_url = url; }
virtual bool currentFrameHasSingleSecurityOrigin() const OVERRIDE;
- virtual bool hasRelativeWidth() const OVERRIDE;
- virtual bool hasRelativeHeight() const OVERRIDE;
-
- virtual void startAnimation(bool /*catchUpIfNecessary*/ = true) OVERRIDE;
+ virtual void startAnimation(CatchUpAnimation = CatchUp) OVERRIDE;
virtual void stopAnimation() OVERRIDE;
virtual void resetAnimation() OVERRIDE;
virtual PassRefPtr<NativeImageSkia> nativeImageForCurrentFrame() OVERRIDE;
+ // Returns the SVG image document's frame.
+ FrameView* frameView() const;
+
+ // Does the SVG image/document contain any animations?
+ bool hasAnimations() const;
+
private:
friend class AXRenderObject;
friend class SVGImageChromeClient;
@@ -71,8 +75,6 @@ private:
virtual ~SVGImage();
- // Returns the SVG image document's frame.
- FrameView* frameView() const;
virtual String filenameExtension() const OVERRIDE;
@@ -97,8 +99,9 @@ private:
CompositeOperator, const FloatRect&, blink::WebBlendMode, const IntSize& repeatSpacing);
OwnPtr<SVGImageChromeClient> m_chromeClient;
- OwnPtr<Page> m_page;
+ OwnPtrWillBePersistent<Page> m_page;
IntSize m_intrinsicSize;
+ KURL m_url;
};
DEFINE_IMAGE_TYPE_CASTS(SVGImage);
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.cpp b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.cpp
index 059bbb42b4f..26143b6de85 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.cpp
@@ -23,6 +23,7 @@
#include "core/fetch/ImageResource.h"
#include "core/frame/FrameView.h"
+#include "core/html/HTMLImageElement.h"
#include "core/page/Page.h"
#include "core/rendering/svg/RenderSVGRoot.h"
#include "core/svg/graphics/SVGImage.h"
@@ -89,6 +90,14 @@ Image* SVGImageCache::imageForRenderer(const RenderObject* renderer)
RefPtr<SVGImageForContainer> imageForContainer = it->value;
ASSERT(!imageForContainer->size().isEmpty());
+
+ Node* node = renderer->node();
+ if (node && isHTMLImageElement(node)) {
+ const AtomicString& urlString = toHTMLImageElement(node)->imageSourceURL();
+ KURL url = node->document().completeURL(urlString);
+ imageForContainer->setURL(url);
+ }
+
return imageForContainer.get();
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.h b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.h
index 0559062ba78..fbc93091725 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.h
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageCache.h
@@ -29,9 +29,7 @@
namespace WebCore {
-class ImageResource;
class ImageResourceClient;
-class ImageBuffer;
class SVGImage;
class SVGImageForContainer;
class RenderObject;
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
new file mode 100644
index 00000000000..19134d053f1
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/graphics/SVGImageChromeClient.h"
+
+#include "core/dom/ScriptForbiddenScope.h"
+#include "core/frame/FrameView.h"
+#include "core/svg/graphics/SVGImage.h"
+#include "platform/graphics/ImageObserver.h"
+#include "wtf/CurrentTime.h"
+
+namespace WebCore {
+
+static const double animationFrameDelay = 0.025;
+
+SVGImageChromeClient::SVGImageChromeClient(SVGImage* image)
+ : m_image(image)
+ , m_animationTimer(this, &SVGImageChromeClient::animationTimerFired)
+{
+}
+
+bool SVGImageChromeClient::isSVGImageChromeClient() const
+{
+ return true;
+}
+
+void SVGImageChromeClient::chromeDestroyed()
+{
+ m_image = 0;
+}
+
+void SVGImageChromeClient::invalidateContentsAndRootView(const IntRect& r)
+{
+ // If m_image->m_page is null, we're being destructed, don't fire changedInRect() in that case.
+ if (m_image && m_image->imageObserver() && m_image->m_page)
+ m_image->imageObserver()->changedInRect(m_image, r);
+}
+
+void SVGImageChromeClient::scheduleAnimation()
+{
+ // Because a single SVGImage can be shared by multiple pages, we can't key
+ // our svg image layout on the page's real animation frame. Therefore, we
+ // run this fake animation timer to trigger layout in SVGImages. The name,
+ // "animationTimer", is to match the new requestAnimationFrame-based layout
+ // approach.
+ if (m_animationTimer.isActive())
+ return;
+ // Schedule the 'animation' ASAP if the image does not contain any
+ // animations, but prefer a fixed, jittery, frame-delay if there're any
+ // animations. Checking for pending/active animations could be more
+ // stringent.
+ double fireTime = m_image->hasAnimations() ? animationFrameDelay : 0;
+ m_animationTimer.startOneShot(fireTime, FROM_HERE);
+}
+
+void SVGImageChromeClient::animationTimerFired(Timer<SVGImageChromeClient>*)
+{
+ if (!m_image)
+ return;
+ // serviceScriptedAnimations runs requestAnimationFrame callbacks, but SVG
+ // images can't have any so we assert there's no script.
+ ScriptForbiddenScope forbidScript;
+ m_image->frameView()->page()->animator().serviceScriptedAnimations(monotonicallyIncreasingTime());
+ m_image->frameView()->updateLayoutAndStyleForPainting();
+}
+
+}
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h
index 76a4a9c56be..d1457d7469d 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageChromeClient.h
@@ -30,35 +30,27 @@
#define SVGImageChromeClient_h
#include "core/loader/EmptyClients.h"
-#include "platform/graphics/ImageObserver.h"
+#include "platform/Timer.h"
namespace WebCore {
-class SVGImageChromeClient : public EmptyChromeClient {
+class SVGImageChromeClient FINAL : public EmptyChromeClient {
WTF_MAKE_NONCOPYABLE(SVGImageChromeClient); WTF_MAKE_FAST_ALLOCATED;
public:
- SVGImageChromeClient(SVGImage* image)
- : m_image(image)
- {
- }
+ explicit SVGImageChromeClient(SVGImage*);
+ virtual bool isSVGImageChromeClient() const OVERRIDE;
- virtual bool isSVGImageChromeClient() const { return true; }
SVGImage* image() const { return m_image; }
private:
- virtual void chromeDestroyed()
- {
- m_image = 0;
- }
+ virtual void chromeDestroyed() OVERRIDE;
+ virtual void invalidateContentsAndRootView(const IntRect&) OVERRIDE;
+ virtual void scheduleAnimation() OVERRIDE;
- virtual void invalidateContentsAndRootView(const IntRect& r)
- {
- // If m_image->m_page is null, we're being destructed, don't fire changedInRect() in that case.
- if (m_image && m_image->imageObserver() && m_image->m_page)
- m_image->imageObserver()->changedInRect(m_image, r);
- }
+ void animationTimerFired(Timer<SVGImageChromeClient>*);
SVGImage* m_image;
+ Timer<SVGImageChromeClient> m_animationTimer;
};
DEFINE_TYPE_CASTS(SVGImageChromeClient, ChromeClient, client, client->isSVGImageChromeClient(), client.isSVGImageChromeClient());
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp
index 96a0080d48c..75d1bebaa18 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.cpp
@@ -20,7 +20,6 @@
#include "config.h"
#include "core/svg/graphics/SVGImageForContainer.h"
-#include "core/svg/graphics/SVGImage.h"
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/FloatSize.h"
#include "wtf/PassRefPtr.h"
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h
index 4ea589eec44..1333acfcd6f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/SVGImageForContainer.h
@@ -30,10 +30,11 @@
#include "platform/geometry/FloatRect.h"
#include "platform/geometry/FloatSize.h"
#include "platform/graphics/Image.h"
+#include "platform/weborigin/KURL.h"
namespace WebCore {
-class SVGImageForContainer : public Image {
+class SVGImageForContainer FINAL : public Image {
public:
static PassRefPtr<SVGImageForContainer> create(SVGImage* image, const FloatSize& containerSize, float zoom)
{
@@ -43,6 +44,7 @@ public:
virtual bool isSVGImage() const OVERRIDE { return true; }
virtual IntSize size() const OVERRIDE;
+ void setURL(const KURL& url) { m_image->setURL(url); }
virtual bool usesContainerSize() const OVERRIDE { return m_image->usesContainerSize(); }
virtual bool hasRelativeWidth() const OVERRIDE { return m_image->hasRelativeWidth(); }
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp
index ab2d6ca4e97..a0a3a030e9c 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.cpp
@@ -26,65 +26,95 @@
#include "core/svg/graphics/filters/SVGFEImage.h"
#include "SkBitmapSource.h"
+#include "SkPictureImageFilter.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/svg/SVGRenderingContext.h"
#include "core/svg/SVGElement.h"
#include "core/svg/SVGURIReference.h"
+#include "platform/graphics/DisplayList.h"
#include "platform/graphics/GraphicsContext.h"
#include "platform/graphics/filters/Filter.h"
+#include "platform/graphics/filters/SkiaImageFilterBuilder.h"
#include "platform/text/TextStream.h"
#include "platform/transforms/AffineTransform.h"
namespace WebCore {
-FEImage::FEImage(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio)
+FEImage::FEImage(Filter* filter, PassRefPtr<Image> image, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio)
: FilterEffect(filter)
, m_image(image)
- , m_document(0)
+ , m_treeScope(0)
, m_preserveAspectRatio(preserveAspectRatio)
{
}
-FEImage::FEImage(Filter* filter, Document& document, const String& href, const SVGPreserveAspectRatio& preserveAspectRatio)
+FEImage::FEImage(Filter* filter, TreeScope& treeScope, const String& href, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio)
: FilterEffect(filter)
- , m_document(&document)
+ , m_treeScope(&treeScope)
, m_href(href)
, m_preserveAspectRatio(preserveAspectRatio)
{
}
-PassRefPtr<FEImage> FEImage::createWithImage(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio)
+PassRefPtr<FEImage> FEImage::createWithImage(Filter* filter, PassRefPtr<Image> image, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio)
{
return adoptRef(new FEImage(filter, image, preserveAspectRatio));
}
-PassRefPtr<FEImage> FEImage::createWithIRIReference(Filter* filter, Document& document, const String& href, const SVGPreserveAspectRatio& preserveAspectRatio)
+PassRefPtr<FEImage> FEImage::createWithIRIReference(Filter* filter, TreeScope& treeScope, const String& href, PassRefPtr<SVGPreserveAspectRatio> preserveAspectRatio)
{
- return adoptRef(new FEImage(filter, document, href, preserveAspectRatio));
+ return adoptRef(new FEImage(filter, treeScope, href, preserveAspectRatio));
}
-void FEImage::determineAbsolutePaintRect()
+static FloatRect getRendererRepaintRect(RenderObject* renderer)
{
- FloatRect paintRect = filter()->absoluteTransform().mapRect(filterPrimitiveSubregion());
- FloatRect srcRect;
- if (m_image) {
- srcRect.setSize(m_image->size());
- m_preserveAspectRatio.transformRect(paintRect, srcRect);
- } else if (RenderObject* renderer = referencedRenderer())
- srcRect = filter()->absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates());
+ return renderer->localToParentTransform().mapRect(
+ renderer->paintInvalidationRectInLocalCoordinates());
+}
+FloatRect FEImage::determineAbsolutePaintRect(const FloatRect& originalRequestedRect)
+{
+ RenderObject* renderer = referencedRenderer();
+ if (!m_image && !renderer)
+ return FloatRect();
+
+ FloatRect requestedRect = originalRequestedRect;
if (clipsToBounds())
- paintRect.intersect(maxEffectRect());
- else
- paintRect.unite(maxEffectRect());
- setAbsolutePaintRect(enclosingIntRect(paintRect));
+ requestedRect.intersect(maxEffectRect());
+
+ FloatRect destRect = filter()->mapLocalRectToAbsoluteRect(filterPrimitiveSubregion());
+ FloatRect srcRect;
+ if (renderer) {
+ srcRect = getRendererRepaintRect(renderer);
+ SVGElement* contextNode = toSVGElement(renderer->node());
+
+ if (contextNode->hasRelativeLengths()) {
+ // FIXME: This fixes relative lengths but breaks non-relative ones (see crbug/260709).
+ SVGLengthContext lengthContext(contextNode);
+ FloatSize viewportSize;
+ if (lengthContext.determineViewport(viewportSize)) {
+ srcRect = makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect).mapRect(srcRect);
+ }
+ } else {
+ srcRect = filter()->mapLocalRectToAbsoluteRect(srcRect);
+ srcRect.move(destRect.x(), destRect.y());
+ }
+ destRect.intersect(srcRect);
+ } else {
+ srcRect = FloatRect(FloatPoint(), m_image->size());
+ m_preserveAspectRatio->transformRect(destRect, srcRect);
+ }
+
+ destRect.intersect(requestedRect);
+ addAbsolutePaintRect(destRect);
+ return destRect;
}
RenderObject* FEImage::referencedRenderer() const
{
- if (!m_document)
+ if (!m_treeScope)
return 0;
- Element* hrefElement = SVGURIReference::targetElementFromIRIString(m_href, *m_document);
+ Element* hrefElement = SVGURIReference::targetElementFromIRIString(m_href, *m_treeScope);
if (!hrefElement || !hrefElement->isSVGElement())
return 0;
return hrefElement->renderer();
@@ -99,44 +129,40 @@ void FEImage::applySoftware()
ImageBuffer* resultImage = createImageBufferResult();
if (!resultImage)
return;
-
- FloatRect destRect = filter()->absoluteTransform().mapRect(filterPrimitiveSubregion());
-
- FloatRect srcRect;
- if (renderer)
- srcRect = filter()->absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates());
- else {
- srcRect = FloatRect(FloatPoint(), m_image->size());
- m_preserveAspectRatio.transformRect(destRect, srcRect);
- }
-
IntPoint paintLocation = absolutePaintRect().location();
- destRect.move(-paintLocation.x(), -paintLocation.y());
+ resultImage->context()->translate(-paintLocation.x(), -paintLocation.y());
// FEImage results are always in ColorSpaceDeviceRGB
setResultColorSpace(ColorSpaceDeviceRGB);
- if (renderer) {
- SVGElement* contextNode = toSVGElement(renderer->node());
- if (contextNode->hasRelativeLengths()) {
- SVGLengthContext lengthContext(contextNode);
- FloatSize viewportSize;
+ FloatRect destRect = filter()->mapLocalRectToAbsoluteRect(filterPrimitiveSubregion());
+ FloatRect srcRect;
- // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport.
- // Build up a transformation that maps from the viewport space to the filter primitive subregion.
- if (lengthContext.determineViewport(viewportSize))
- resultImage->context()->concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect));
- } else {
- const AffineTransform& absoluteTransform = filter()->absoluteTransform();
- resultImage->context()->concatCTM(absoluteTransform);
- }
+ if (!renderer) {
+ srcRect = FloatRect(FloatPoint(), m_image->size());
+ m_preserveAspectRatio->transformRect(destRect, srcRect);
- AffineTransform contentTransformation;
- SVGRenderingContext::renderSubtree(resultImage->context(), renderer, contentTransformation);
+ resultImage->context()->drawImage(m_image.get(), destRect, srcRect);
return;
}
- resultImage->context()->drawImage(m_image.get(), destRect, srcRect);
+ SVGElement* contextNode = toSVGElement(renderer->node());
+ if (contextNode->hasRelativeLengths()) {
+ // FIXME: This fixes relative lengths but breaks non-relative ones (see crbug/260709).
+ SVGLengthContext lengthContext(contextNode);
+ FloatSize viewportSize;
+
+ // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport.
+ // Build up a transformation that maps from the viewport space to the filter primitive subregion.
+ if (lengthContext.determineViewport(viewportSize))
+ resultImage->context()->concatCTM(makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect));
+ } else {
+ resultImage->context()->translate(destRect.x(), destRect.y());
+ resultImage->context()->concatCTM(filter()->absoluteTransform());
+ }
+
+ AffineTransform contentTransformation;
+ SVGRenderingContext::renderSubtree(resultImage->context(), renderer, contentTransformation);
}
TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const
@@ -145,7 +171,7 @@ TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const
if (m_image)
imageSize = m_image->size();
else if (RenderObject* renderer = referencedRenderer())
- imageSize = enclosingIntRect(renderer->repaintRectInLocalCoordinates()).size();
+ imageSize = enclosingIntRect(getRendererRepaintRect(renderer)).size();
writeIndent(ts, indent);
ts << "[feImage";
FilterEffect::externalRepresentation(ts);
@@ -154,15 +180,65 @@ TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const
return ts;
}
+PassRefPtr<SkImageFilter> FEImage::createImageFilterForRenderer(RenderObject* renderer, SkiaImageFilterBuilder* builder)
+{
+ FloatRect dstRect = filterPrimitiveSubregion();
+
+ AffineTransform transform;
+ SVGElement* contextNode = toSVGElement(renderer->node());
+
+ if (contextNode->hasRelativeLengths()) {
+ SVGLengthContext lengthContext(contextNode);
+ FloatSize viewportSize;
+
+ // If we're referencing an element with percentage units, eg. <rect with="30%"> those values were resolved against the viewport.
+ // Build up a transformation that maps from the viewport space to the filter primitive subregion.
+ if (lengthContext.determineViewport(viewportSize))
+ transform = makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), dstRect);
+ } else {
+ transform.translate(dstRect.x(), dstRect.y());
+ }
+
+ GraphicsContext* context = builder->context();
+ if (!context)
+ return adoptRef(SkBitmapSource::Create(SkBitmap()));
+ AffineTransform contentTransformation;
+ context->save();
+ context->beginRecording(FloatRect(FloatPoint(), dstRect.size()));
+ context->concatCTM(transform);
+ SVGRenderingContext::renderSubtree(context, renderer, contentTransformation);
+ RefPtr<DisplayList> displayList = context->endRecording();
+ context->restore();
+ RefPtr<SkImageFilter> result = adoptRef(SkPictureImageFilter::Create(displayList->picture(), dstRect));
+ return result.release();
+}
+
PassRefPtr<SkImageFilter> FEImage::createImageFilter(SkiaImageFilterBuilder* builder)
{
- if (!m_image)
- return 0;
+ RenderObject* renderer = referencedRenderer();
+ if (!m_image && !renderer)
+ return adoptRef(SkBitmapSource::Create(SkBitmap()));
+
+ setOperatingColorSpace(ColorSpaceDeviceRGB);
+
+ if (renderer)
+ return createImageFilterForRenderer(renderer, builder);
+
+ FloatRect srcRect = FloatRect(FloatPoint(), m_image->size());
+ FloatRect dstRect = filterPrimitiveSubregion();
+
+ // FIXME: CSS image filters currently do not seem to set filter primitive
+ // subregion correctly if unspecified. So default to srcRect size if so.
+ if (dstRect.isEmpty())
+ dstRect = srcRect;
+
+ m_preserveAspectRatio->transformRect(dstRect, srcRect);
if (!m_image->nativeImageForCurrentFrame())
- return 0;
+ return adoptRef(SkBitmapSource::Create(SkBitmap()));
- return adoptRef(new SkBitmapSource(m_image->nativeImageForCurrentFrame()->bitmap()));
+ RefPtr<SkImageFilter> result = adoptRef(SkBitmapSource::Create(m_image->nativeImageForCurrentFrame()->bitmap(), srcRect, dstRect));
+ return result.release();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.h b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.h
index b82f673b7a5..170fbf15f6f 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.h
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFEImage.h
@@ -24,41 +24,42 @@
#ifndef SVGFEImage_h
#define SVGFEImage_h
-#include "platform/graphics/filters/FilterEffect.h"
+#include "core/dom/TreeScope.h"
#include "core/svg/SVGPreserveAspectRatio.h"
+#include "platform/graphics/filters/FilterEffect.h"
namespace WebCore {
-class Document;
class Image;
class RenderObject;
-class FEImage : public FilterEffect {
+class FEImage FINAL : public FilterEffect {
public:
- static PassRefPtr<FEImage> createWithImage(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&);
- static PassRefPtr<FEImage> createWithIRIReference(Filter*, Document&, const String&, const SVGPreserveAspectRatio&);
+ static PassRefPtr<FEImage> createWithImage(Filter*, PassRefPtr<Image>, PassRefPtr<SVGPreserveAspectRatio>);
+ static PassRefPtr<FEImage> createWithIRIReference(Filter*, TreeScope&, const String&, PassRefPtr<SVGPreserveAspectRatio>);
- virtual void determineAbsolutePaintRect();
+ virtual FloatRect determineAbsolutePaintRect(const FloatRect& requestedRect) OVERRIDE;
- virtual FilterEffectType filterEffectType() const { return FilterEffectTypeImage; }
+ virtual FilterEffectType filterEffectType() const OVERRIDE { return FilterEffectTypeImage; }
- virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const OVERRIDE;
virtual PassRefPtr<SkImageFilter> createImageFilter(SkiaImageFilterBuilder*) OVERRIDE;
private:
virtual ~FEImage() { }
- FEImage(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&);
- FEImage(Filter*, Document&, const String&, const SVGPreserveAspectRatio&);
+ FEImage(Filter*, PassRefPtr<Image>, PassRefPtr<SVGPreserveAspectRatio>);
+ FEImage(Filter*, TreeScope&, const String&, PassRefPtr<SVGPreserveAspectRatio>);
RenderObject* referencedRenderer() const;
virtual void applySoftware() OVERRIDE;
+ PassRefPtr<SkImageFilter> createImageFilterForRenderer(RenderObject* rendererer, SkiaImageFilterBuilder*);
RefPtr<Image> m_image;
- // m_document will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243
- Document* m_document;
+ // m_treeScope will never be a dangling reference. See https://bugs.webkit.org/show_bug.cgi?id=99243
+ TreeScope* m_treeScope;
String m_href;
- SVGPreserveAspectRatio m_preserveAspectRatio;
+ PassRefPtr<SVGPreserveAspectRatio> m_preserveAspectRatio;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp
index d7b91076f2a..5a3ae4590ed 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp
@@ -25,14 +25,13 @@
namespace WebCore {
-SVGFilter::SVGFilter(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode)
+SVGFilter::SVGFilter(const AffineTransform& absoluteTransform, const IntRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode)
: Filter(absoluteTransform)
, m_absoluteSourceDrawingRegion(absoluteSourceDrawingRegion)
, m_targetBoundingBox(targetBoundingBox)
, m_effectBBoxMode(effectBBoxMode)
{
setFilterRegion(filterRegion);
- setAbsoluteFilterRegion(absoluteTransform.mapRect(filterRegion));
}
float SVGFilter::applyHorizontalScale(float value) const
@@ -49,7 +48,16 @@ float SVGFilter::applyVerticalScale(float value) const
return Filter::applyVerticalScale(value);
}
-PassRefPtr<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode)
+FloatPoint3D SVGFilter::resolve3dPoint(const FloatPoint3D& point) const
+{
+ if (!m_effectBBoxMode)
+ return point;
+ return FloatPoint3D(point.x() * m_targetBoundingBox.width() + m_targetBoundingBox.x(),
+ point.y() * m_targetBoundingBox.height() + m_targetBoundingBox.y(),
+ point.z() * sqrtf(m_targetBoundingBox.size().diagonalLengthSquared() / 2));
+}
+
+PassRefPtr<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const IntRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode)
{
return adoptRef(new SVGFilter(absoluteTransform, absoluteSourceDrawingRegion, targetBoundingBox, filterRegion, effectBBoxMode));
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.h b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.h
index ad30b39218c..f461311b916 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.h
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.h
@@ -32,20 +32,21 @@
namespace WebCore {
-class SVGFilter : public Filter {
+class SVGFilter FINAL : public Filter {
public:
- static PassRefPtr<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool);
+ static PassRefPtr<SVGFilter> create(const AffineTransform&, const IntRect&, const FloatRect&, const FloatRect&, bool);
- virtual float applyHorizontalScale(float value) const;
- virtual float applyVerticalScale(float value) const;
+ virtual float applyHorizontalScale(float value) const OVERRIDE;
+ virtual float applyVerticalScale(float value) const OVERRIDE;
+ virtual FloatPoint3D resolve3dPoint(const FloatPoint3D&) const OVERRIDE;
- virtual FloatRect sourceImageRect() const { return m_absoluteSourceDrawingRegion; }
+ virtual IntRect sourceImageRect() const OVERRIDE { return m_absoluteSourceDrawingRegion; }
FloatRect targetBoundingBox() const { return m_targetBoundingBox; }
private:
- SVGFilter(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode);
+ SVGFilter(const AffineTransform& absoluteTransform, const IntRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode);
- FloatRect m_absoluteSourceDrawingRegion;
+ IntRect m_absoluteSourceDrawingRegion;
FloatRect m_targetBoundingBox;
bool m_effectBBoxMode;
};
diff --git a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
index fec801263c6..d63e1f7d033 100644
--- a/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
@@ -80,7 +80,7 @@ void SVGFilterBuilder::appendEffectToEffectReferences(PassRefPtr<FilterEffect> p
void SVGFilterBuilder::clearEffects()
{
- m_lastEffect = 0;
+ m_lastEffect = nullptr;
m_namedEffects.clear();
m_effectReferences.clear();
m_effectRenderer.clear();
@@ -89,7 +89,7 @@ void SVGFilterBuilder::clearEffects()
void SVGFilterBuilder::clearResultsRecursive(FilterEffect* effect)
{
- if (!effect->hasResult())
+ if (!effect->hasResult() && !effect->hasImageFilter())
return;
effect->clearResult();
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h
deleted file mode 100644
index 962e7f3e2e0..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedEnumerationPropertyTearOff_h
-#define SVGAnimatedEnumerationPropertyTearOff_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-
-namespace WebCore {
-
-template<typename EnumType>
-class SVGAnimatedEnumerationPropertyTearOff : public SVGAnimatedStaticPropertyTearOff<unsigned> {
-public:
- virtual void setBaseVal(const unsigned& property, ExceptionState& exceptionState)
- {
- // All SVG enumeration values, that are allowed to be set via SVG DOM start with 1, 0 corresponds to unknown and is not settable through SVG DOM.
- if (!property || property > SVGPropertyTraits<EnumType>::highestEnumValue()) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return;
- }
- SVGAnimatedStaticPropertyTearOff<unsigned>::setBaseVal(property, exceptionState);
- }
-
- static PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<EnumType> > create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, EnumType& property)
- {
- ASSERT(contextElement);
- return adoptRef(new SVGAnimatedEnumerationPropertyTearOff<EnumType>(contextElement, attributeName, animatedPropertyType, reinterpret_cast<unsigned&>(property)));
- }
-
- EnumType& currentAnimatedValue()
- {
- unsigned& animatedValue = SVGAnimatedStaticPropertyTearOff<unsigned>::currentAnimatedValue();
- ASSERT(animatedValue <= SVGPropertyTraits<EnumType>::highestEnumValue());
- return reinterpret_cast<EnumType&>(animatedValue);
- }
-
-private:
- SVGAnimatedEnumerationPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, unsigned& property)
- : SVGAnimatedStaticPropertyTearOff<unsigned>(contextElement, attributeName, animatedPropertyType, property)
- {
- }
-};
-
-}
-
-#endif // SVGAnimatedEnumerationPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedListPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedListPropertyTearOff.h
deleted file mode 100644
index bebcc5a7202..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedListPropertyTearOff.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedListPropertyTearOff_h
-#define SVGAnimatedListPropertyTearOff_h
-
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "core/svg/properties/SVGListPropertyTearOff.h"
-#include "core/svg/properties/SVGStaticListPropertyTearOff.h"
-
-namespace WebCore {
-
-template<typename PropertyType>
-class SVGPropertyTearOff;
-
-template<typename PropertyType>
-class SVGAnimatedListPropertyTearOff : public SVGAnimatedProperty {
-public:
- typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
- typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
- typedef Vector<RefPtr<ListItemTearOff> > ListWrapperCache;
- typedef SVGListProperty<PropertyType> ListProperty;
- typedef SVGListPropertyTearOff<PropertyType> ListPropertyTearOff;
- typedef PropertyType ContentType;
-
- virtual ~SVGAnimatedListPropertyTearOff()
- {
- if (m_baseVal)
- static_cast<ListPropertyTearOff*>(m_baseVal.get())->clearAnimatedProperty();
- if (m_animVal)
- static_cast<ListPropertyTearOff*>(m_animVal.get())->clearAnimatedProperty();
- }
-
- virtual ListProperty* baseVal()
- {
- if (!m_baseVal)
- m_baseVal = ListPropertyTearOff::create(this, BaseValRole, m_values, m_wrappers);
- return static_cast<ListProperty*>(m_baseVal.get());
- }
-
- virtual ListProperty* animVal()
- {
- if (!m_animVal)
- m_animVal = ListPropertyTearOff::create(this, AnimValRole, m_values, m_wrappers);
- return static_cast<ListProperty*>(m_animVal.get());
- }
-
- virtual bool isAnimatedListTearOff() const { return true; }
-
- int findItem(SVGProperty* property) const
- {
- // This should ever be called for our baseVal, as animVal can't modify the list.
- // It's safe to cast to ListPropertyTearOff here as all classes inheriting from us supply their own removeItemFromList() method.
- typedef SVGPropertyTearOff<typename SVGPropertyTraits<PropertyType>::ListItemType> ListItemTearOff;
- return static_cast<ListPropertyTearOff*>(m_baseVal.get())->findItem(static_cast<ListItemTearOff*>(property));
- }
-
- void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
- {
- // This should ever be called for our baseVal, as animVal can't modify the list.
- // It's safe to cast to ListPropertyTearOff here as all classes inheriting from us supply their own removeItemFromList() method.
- static_cast<ListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(itemIndex, shouldSynchronizeWrappers);
- }
-
- void detachListWrappers(unsigned newListSize)
- {
- ListProperty::detachListWrappersAndResize(&m_wrappers, newListSize);
- }
-
- PropertyType& currentAnimatedValue()
- {
- ASSERT(m_isAnimating);
- ASSERT(m_animVal);
- return static_cast<ListProperty*>(m_animVal.get())->values();
- }
-
- const PropertyType& currentBaseValue() const
- {
- return m_values;
- }
-
- void animationStarted(PropertyType* newAnimVal, bool shouldOwnValues = false)
- {
- ASSERT(!m_isAnimating);
- ASSERT(newAnimVal);
- ASSERT(m_values.size() == m_wrappers.size());
- ASSERT(m_animatedWrappers.isEmpty());
-
- // Switch to new passed in value type & new wrappers list. The new wrappers list must be created for the new value.
- if (!newAnimVal->isEmpty())
- m_animatedWrappers.fill(0, newAnimVal->size());
-
- ListProperty* animVal = static_cast<ListProperty*>(this->animVal());
- animVal->setValuesAndWrappers(newAnimVal, &m_animatedWrappers, shouldOwnValues);
- ASSERT(animVal->values().size() == animVal->wrappers().size());
- ASSERT(animVal->wrappers().size() == m_animatedWrappers.size());
- m_isAnimating = true;
- }
-
- void animationEnded()
- {
- ASSERT(m_isAnimating);
- ASSERT(m_animVal);
- ASSERT(contextElement());
- ASSERT(m_values.size() == m_wrappers.size());
-
- ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get());
- ASSERT(animVal->values().size() == animVal->wrappers().size());
- ASSERT(animVal->wrappers().size() == m_animatedWrappers.size());
-
- animVal->setValuesAndWrappers(&m_values, &m_wrappers, false);
- ASSERT(animVal->values().size() == animVal->wrappers().size());
- ASSERT(animVal->wrappers().size() == m_wrappers.size());
-
- m_animatedWrappers.clear();
- m_isAnimating = false;
- }
-
- void synchronizeWrappersIfNeeded()
- {
- // Eventually the wrapper list needs synchronization because any SVGAnimateLengthList::calculateAnimatedValue() call may
- // mutate the length of our values() list, and thus the wrapper() cache needs synchronization, to have the same size.
- // Also existing wrappers which point directly at elements in the existing SVGLengthList have to be detached (so a copy
- // of them is created, so existing animVal variables in JS are kept-alive). If we'd detach them later the underlying
- // SVGLengthList was already mutated, and our list item wrapper tear offs would point nowhere. Assertions would fire.
- ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get());
- animVal->detachListWrappers(animVal->values().size());
-
- ASSERT(animVal->values().size() == animVal->wrappers().size());
- ASSERT(animVal->wrappers().size() == m_animatedWrappers.size());
- }
-
- void animValWillChange()
- {
- ASSERT(m_isAnimating);
- ASSERT(m_animVal);
- ASSERT(m_values.size() == m_wrappers.size());
- synchronizeWrappersIfNeeded();
- }
-
- void animValDidChange()
- {
- ASSERT(m_isAnimating);
- ASSERT(m_animVal);
- ASSERT(m_values.size() == m_wrappers.size());
- synchronizeWrappersIfNeeded();
- }
-
- static PassRefPtr<SVGAnimatedListPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& values)
- {
- ASSERT(contextElement);
- return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, values));
- }
-
-protected:
- SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& values)
- : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyType)
- , m_values(values)
- {
- if (!values.isEmpty())
- m_wrappers.fill(0, values.size());
- }
-
- PropertyType& m_values;
-
- ListWrapperCache m_wrappers;
- ListWrapperCache m_animatedWrappers;
-
- RefPtr<SVGProperty> m_baseVal;
- RefPtr<SVGProperty> m_animVal;
-};
-
-}
-
-#endif // SVGAnimatedListPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h
deleted file mode 100644
index dfdb6d43164..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedPathSegListPropertyTearOff_h
-#define SVGAnimatedPathSegListPropertyTearOff_h
-
-#include "core/svg/SVGPathByteStream.h"
-#include "core/svg/SVGPathElement.h"
-#include "core/svg/SVGPathSegList.h"
-#include "core/svg/SVGPathUtilities.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
-#include "core/svg/properties/SVGPathSegListPropertyTearOff.h"
-
-namespace WebCore {
-
-class SVGAnimatedPathSegListPropertyTearOff : public SVGAnimatedListPropertyTearOff<SVGPathSegList> {
-public:
- virtual SVGListProperty<SVGPathSegList>* baseVal()
- {
- if (!m_baseVal)
- m_baseVal = SVGPathSegListPropertyTearOff::create(this, BaseValRole, PathSegUnalteredRole, m_values, m_wrappers);
- return static_cast<SVGListProperty<SVGPathSegList>*>(m_baseVal.get());
- }
-
- virtual SVGListProperty<SVGPathSegList>* animVal()
- {
- if (!m_animVal)
- m_animVal = SVGPathSegListPropertyTearOff::create(this, AnimValRole, PathSegUnalteredRole, m_values, m_wrappers);
- return static_cast<SVGListProperty<SVGPathSegList>*>(m_animVal.get());
- }
-
- int findItem(const RefPtr<SVGPathSeg>& segment) const
- {
- // This should ever be called for our baseVal, as animVal can't modify the list.
- ASSERT(m_baseVal);
- return static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->findItem(segment);
- }
-
- void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
- {
- // This should ever be called for our baseVal, as animVal can't modify the list.
- ASSERT(m_baseVal);
- static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(itemIndex, shouldSynchronizeWrappers);
- }
-
- static PassRefPtr<SVGAnimatedPathSegListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegList& values)
- {
- ASSERT(contextElement);
- return adoptRef(new SVGAnimatedPathSegListPropertyTearOff(contextElement, attributeName, animatedPropertyType, values));
- }
-
- using SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationStarted;
- void animationStarted(SVGPathByteStream* byteStream, const SVGPathSegList* baseValue)
- {
- ASSERT(byteStream);
- ASSERT(baseValue);
- ASSERT(!m_animatedPathByteStream);
- m_animatedPathByteStream = byteStream;
-
- // Pass shouldOwnValues=true, as the SVGPathSegList lifetime is solely managed by its tear off class.
- SVGPathSegList* copy = new SVGPathSegList(*baseValue);
- SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationStarted(copy, true);
- }
-
- void animationEnded()
- {
- ASSERT(m_animatedPathByteStream);
- m_animatedPathByteStream = 0;
- SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationEnded();
- }
-
- void animValDidChange()
- {
- ASSERT(m_animatedPathByteStream);
- SVGPathElement* pathElement = toSVGPathElement(contextElement());
-
- // If the animVal is observed from JS, we have to update it on each animation step.
- // This is an expensive operation and only done, if someone actually observes the animatedPathSegList() while an animation is running.
- if (pathElement->isAnimValObserved()) {
- SVGPathSegList& animatedList = currentAnimatedValue();
- animatedList.clear();
- buildSVGPathSegListFromByteStream(m_animatedPathByteStream, pathElement, animatedList, UnalteredParsing);
- }
-
- SVGAnimatedListPropertyTearOff<SVGPathSegList>::animValDidChange();
- }
-
- SVGPathByteStream* animatedPathByteStream() const { return m_animatedPathByteStream; }
-
-private:
- SVGAnimatedPathSegListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegList& values)
- : SVGAnimatedListPropertyTearOff<SVGPathSegList>(contextElement, attributeName, animatedPropertyType, values)
- , m_animatedPathByteStream(0)
- {
- }
-
- SVGPathByteStream* m_animatedPathByteStream;
-};
-
-}
-
-#endif // SVGAnimatedPathSegListPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp
index b1e1e7835cd..cd167dae192 100644
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp
+++ b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp
@@ -1,21 +1,31 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
@@ -25,58 +35,37 @@
namespace WebCore {
-SVGAnimatedProperty::SVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType)
- : m_contextElement(contextElement)
- , m_attributeName(attributeName)
- , m_animatedPropertyType(animatedPropertyType)
- , m_isAnimating(false)
+SVGAnimatedPropertyBase::SVGAnimatedPropertyBase(AnimatedPropertyType type, SVGElement* contextElement, const QualifiedName& attributeName)
+ : m_type(type)
, m_isReadOnly(false)
+ , m_contextElement(contextElement)
+ , m_attributeName(attributeName)
{
- contextElement->setContextElement();
+ ASSERT(m_contextElement);
+ ASSERT(m_attributeName != QualifiedName::null());
+ // FIXME: setContextElement should be delayed until V8 wrapper is created.
+ // FIXME: oilpan: or we can remove this backref ptr hack in oilpan.
+ m_contextElement->setContextElement();
}
-SVGAnimatedProperty::~SVGAnimatedProperty()
+SVGAnimatedPropertyBase::~SVGAnimatedPropertyBase()
{
- // Assure that animationEnded() was called, if animationStarted() was called before.
- ASSERT(!m_isAnimating);
}
-void SVGAnimatedProperty::detachAnimatedPropertiesForElement(SVGElement* element)
+void SVGAnimatedPropertyBase::animationEnded()
{
- // Remove wrappers from cache.
- Cache* cache = animatedPropertyCache();
-
- Vector<SVGAnimatedPropertyDescription> keysToRemove;
-
- const Cache::const_iterator end = cache->end();
- for (Cache::const_iterator it = cache->begin(); it != end; ++it) {
- if (it->key.m_element == element) {
- it->value->resetContextElement();
- keysToRemove.append(it->key);
- }
- }
-
- for (Vector<SVGAnimatedPropertyDescription>::const_iterator it = keysToRemove.begin(); it != keysToRemove.end(); ++it) {
- // http://crbug.com/333156 :
- // There are cases where detachAnimatedPropertiesForElement is called recursively from ~SVGAnimatedProperty.
- // This below protect makes this function safe by deferring the recursive call until we finish touching the HashMap.
- RefPtr<SVGAnimatedProperty> protect = cache->get(*it);
- cache->remove(*it);
- }
+ synchronizeAttribute();
}
-void SVGAnimatedProperty::commitChange()
+void SVGAnimatedPropertyBase::synchronizeAttribute()
{
- ASSERT(m_contextElement);
- ASSERT_WITH_SECURITY_IMPLICATION(!m_contextElement->m_deletionHasBegun);
- m_contextElement->invalidateSVGAttributes();
- m_contextElement->svgAttributeChanged(m_attributeName);
+ AtomicString value(currentValueBase()->valueAsString());
+ m_contextElement->setSynchronizedLazyAttribute(m_attributeName, value);
}
-SVGAnimatedProperty::Cache* SVGAnimatedProperty::animatedPropertyCache()
+bool SVGAnimatedPropertyBase::isSpecified() const
{
- static Cache* s_cache = new Cache;
- return s_cache;
+ return isAnimating() || contextElement()->hasAttribute(attributeName());
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.h
index eb0ba54e4bf..e9461706af8 100644
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.h
+++ b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.h
@@ -1,97 +1,307 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+G* * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGAnimatedProperty_h
#define SVGAnimatedProperty_h
-#include "core/svg/properties/SVGAnimatedPropertyDescription.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGParsingError.h"
#include "core/svg/properties/SVGPropertyInfo.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
class SVGElement;
-class SVGAnimatedProperty : public RefCounted<SVGAnimatedProperty> {
+class SVGAnimatedPropertyBase : public RefCounted<SVGAnimatedPropertyBase> {
public:
- SVGElement* contextElement() const { return m_contextElement; }
- void resetContextElement() { m_contextElement = 0; }
- const QualifiedName& attributeName() const { return m_attributeName; }
- AnimatedPropertyType animatedPropertyType() const { return m_animatedPropertyType; }
- bool isAnimating() const { return m_isAnimating; }
- bool isReadOnly() const { return m_isReadOnly; }
- void setIsReadOnly() { m_isReadOnly = true; }
-
- void commitChange();
-
- virtual bool isAnimatedListTearOff() const { return false; }
-
- // Caching facilities.
- typedef HashMap<SVGAnimatedPropertyDescription, RefPtr<SVGAnimatedProperty>, SVGAnimatedPropertyDescriptionHash, SVGAnimatedPropertyDescriptionHashTraits> Cache;
-
- virtual ~SVGAnimatedProperty();
-
- template<typename OwnerType, typename TearOffType, typename PropertyType>
- static PassRefPtr<TearOffType> lookupOrCreateWrapper(OwnerType* element, const SVGPropertyInfo* info, PropertyType& property)
- {
- ASSERT(info);
- SVGAnimatedPropertyDescription key(element, info->propertyIdentifier);
- RefPtr<SVGAnimatedProperty> wrapper = animatedPropertyCache()->get(key);
- if (!wrapper) {
- wrapper = TearOffType::create(element, info->attributeName, info->animatedPropertyType, property);
- if (info->animatedPropertyState == PropertyIsReadOnly)
- wrapper->setIsReadOnly();
- animatedPropertyCache()->set(key, wrapper);
- }
- return static_pointer_cast<TearOffType>(wrapper);
+ virtual ~SVGAnimatedPropertyBase();
+
+ virtual SVGPropertyBase* currentValueBase() = 0;
+ virtual bool isAnimating() const = 0;
+
+ virtual PassRefPtr<SVGPropertyBase> createAnimatedValue() = 0;
+ virtual void setAnimatedValue(PassRefPtr<SVGPropertyBase>) = 0;
+ virtual void animationEnded();
+
+ virtual bool needsSynchronizeAttribute() = 0;
+ virtual void synchronizeAttribute();
+
+ AnimatedPropertyType type() const
+ {
+ return m_type;
+ }
+
+ SVGElement* contextElement() const
+ {
+ return m_contextElement;
}
- template<typename OwnerType, typename TearOffType>
- static TearOffType* lookupWrapper(OwnerType* element, const SVGPropertyInfo* info)
+ const QualifiedName& attributeName() const
{
- ASSERT(info);
- SVGAnimatedPropertyDescription key(element, info->propertyIdentifier);
- return static_cast<TearOffType*>(animatedPropertyCache()->get(key));
+ return m_attributeName;
}
- template<typename OwnerType, typename TearOffType>
- static TearOffType* lookupWrapper(const OwnerType* element, const SVGPropertyInfo* info)
+ bool isReadOnly() const
{
- return lookupWrapper<OwnerType, TearOffType>(const_cast<OwnerType*>(element), info);
+ return m_isReadOnly;
}
- static void detachAnimatedPropertiesForElement(SVGElement*);
+ void setReadOnly()
+ {
+ m_isReadOnly = true;
+ }
+
+ bool isSpecified() const;
protected:
- SVGAnimatedProperty(SVGElement*, const QualifiedName&, AnimatedPropertyType);
+ SVGAnimatedPropertyBase(AnimatedPropertyType, SVGElement*, const QualifiedName& attributeName);
private:
- static Cache* animatedPropertyCache();
+ const AnimatedPropertyType m_type;
+ bool m_isReadOnly;
+ // This reference is kept alive from V8 wrapper
SVGElement* m_contextElement;
+
const QualifiedName& m_attributeName;
- AnimatedPropertyType m_animatedPropertyType;
+
+ WTF_MAKE_NONCOPYABLE(SVGAnimatedPropertyBase);
+};
+
+template <typename Property>
+class SVGAnimatedPropertyCommon : public SVGAnimatedPropertyBase {
+public:
+ Property* baseValue()
+ {
+ return m_baseValue.get();
+ }
+
+ Property* currentValue()
+ {
+ return m_currentValue ? m_currentValue.get() : m_baseValue.get();
+ }
+
+ const Property* currentValue() const
+ {
+ return const_cast<SVGAnimatedPropertyCommon*>(this)->currentValue();
+ }
+
+ virtual SVGPropertyBase* currentValueBase() OVERRIDE
+ {
+ return currentValue();
+ }
+
+ virtual bool isAnimating() const OVERRIDE
+ {
+ return m_currentValue;
+ }
+
+ void setBaseValueAsString(const String& value, SVGParsingError& parseError)
+ {
+ TrackExceptionState es;
+
+ m_baseValue->setValueAsString(value, es);
+
+ if (es.hadException())
+ parseError = ParsingAttributeFailedError;
+ }
+
+ virtual PassRefPtr<SVGPropertyBase> createAnimatedValue() OVERRIDE
+ {
+ return m_baseValue->clone();
+ }
+
+ virtual void setAnimatedValue(PassRefPtr<SVGPropertyBase> passValue) OVERRIDE
+ {
+ RefPtr<SVGPropertyBase> value = passValue;
+ ASSERT(value->type() == Property::classType());
+ m_currentValue = static_pointer_cast<Property>(value.release());
+ }
+
+ virtual void animationEnded() OVERRIDE
+ {
+ m_currentValue.clear();
+
+ SVGAnimatedPropertyBase::animationEnded();
+ }
protected:
- bool m_isAnimating;
- bool m_isReadOnly;
+ SVGAnimatedPropertyCommon(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue)
+ : SVGAnimatedPropertyBase(Property::classType(), contextElement, attributeName)
+ , m_baseValue(initialValue)
+ {
+ }
+
+private:
+ RefPtr<Property> m_baseValue;
+ RefPtr<Property> m_currentValue;
+};
+
+// Implementation of SVGAnimatedProperty which uses primitive types.
+// This is for classes which return primitive type for its "animVal".
+// Examples are SVGAnimatedBoolean, SVGAnimatedNumber, etc.
+template <typename Property, typename TearOffType = typename Property::TearOffType, typename PrimitiveType = typename Property::PrimitiveType>
+class SVGAnimatedProperty : public SVGAnimatedPropertyCommon<Property> {
+public:
+ virtual bool needsSynchronizeAttribute() OVERRIDE
+ {
+ // DOM attribute synchronization is only needed if tear-off is being touched from javascript or the property is being animated.
+ // This prevents unnecessary attribute creation on target element.
+ return m_baseValueUpdated || this->isAnimating();
+ }
+
+ virtual void synchronizeAttribute() OVERRIDE
+ {
+ SVGAnimatedPropertyBase::synchronizeAttribute();
+ m_baseValueUpdated = false;
+ }
+
+ // SVGAnimated* DOM Spec implementations:
+
+ // baseVal()/setBaseVal()/animVal() are only to be used from SVG DOM implementation.
+ // Use currentValue() from C++ code.
+ PrimitiveType baseVal()
+ {
+ return this->baseValue()->value();
+ }
+
+ void setBaseVal(PrimitiveType value, WebCore::ExceptionState& exceptionState)
+ {
+ if (this->isReadOnly()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+ return;
+ }
+
+ this->baseValue()->setValue(value);
+ m_baseValueUpdated = true;
+
+ ASSERT(this->attributeName() != QualifiedName::null());
+ this->contextElement()->invalidateSVGAttributes();
+ this->contextElement()->svgAttributeChanged(this->attributeName());
+ }
+
+ PrimitiveType animVal()
+ {
+ return this->currentValue()->value();
+ }
+
+protected:
+ SVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue)
+ : SVGAnimatedPropertyCommon<Property>(contextElement, attributeName, initialValue)
+ , m_baseValueUpdated(false)
+ {
+ }
+
+ bool m_baseValueUpdated;
+};
+
+// Implementation of SVGAnimatedProperty which uses tear-off value types.
+// These classes has "void" for its PrimitiveType.
+// This is for classes which return special type for its "animVal".
+// Examples are SVGAnimatedLength, SVGAnimatedRect, SVGAnimated*List, etc.
+template <typename Property, typename TearOffType>
+class SVGAnimatedProperty<Property, TearOffType, void> : public SVGAnimatedPropertyCommon<Property> {
+public:
+ static PassRefPtr<SVGAnimatedProperty<Property> > create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue)
+ {
+ return adoptRef(new SVGAnimatedProperty<Property>(contextElement, attributeName, initialValue));
+ }
+
+ virtual void setAnimatedValue(PassRefPtr<SVGPropertyBase> value) OVERRIDE
+ {
+ SVGAnimatedPropertyCommon<Property>::setAnimatedValue(value);
+ updateAnimValTearOffIfNeeded();
+ }
+
+ virtual void animationEnded() OVERRIDE
+ {
+ SVGAnimatedPropertyCommon<Property>::animationEnded();
+ updateAnimValTearOffIfNeeded();
+ }
+
+ virtual bool needsSynchronizeAttribute() OVERRIDE
+ {
+ // DOM attribute synchronization is only needed if tear-off is being touched from javascript or the property is being animated.
+ // This prevents unnecessary attribute creation on target element.
+ return m_baseValTearOff || this->isAnimating();
+ }
+
+ // SVGAnimated* DOM Spec implementations:
+
+ // baseVal()/animVal() are only to be used from SVG DOM implementation.
+ // Use currentValue() from C++ code.
+ virtual TearOffType* baseVal()
+ {
+ if (!m_baseValTearOff) {
+ m_baseValTearOff = TearOffType::create(this->baseValue(), this->contextElement(), PropertyIsNotAnimVal, this->attributeName());
+ if (this->isReadOnly())
+ m_baseValTearOff->setIsReadOnlyProperty();
+ }
+
+ return m_baseValTearOff.get();
+ }
+
+ TearOffType* animVal()
+ {
+ if (!m_animValTearOff)
+ m_animValTearOff = TearOffType::create(this->currentValue(), this->contextElement(), PropertyIsAnimVal, this->attributeName());
+
+ return m_animValTearOff.get();
+ }
+
+protected:
+ SVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<Property> initialValue)
+ : SVGAnimatedPropertyCommon<Property>(contextElement, attributeName, initialValue)
+ {
+ }
+
+private:
+ void updateAnimValTearOffIfNeeded()
+ {
+ if (m_animValTearOff)
+ m_animValTearOff->setTarget(this->currentValue());
+ }
+
+ // When still (not animated):
+ // Both m_animValTearOff and m_baseValTearOff target m_baseValue.
+ // When animated:
+ // m_animValTearOff targets m_currentValue.
+ // m_baseValTearOff targets m_baseValue.
+ RefPtr<TearOffType> m_baseValTearOff;
+ RefPtr<TearOffType> m_animValTearOff;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyDescription.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyDescription.h
deleted file mode 100644
index 55f1a8face3..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyDescription.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedPropertyDescription_h
-#define SVGAnimatedPropertyDescription_h
-
-#include "wtf/HashMap.h"
-#include "wtf/HashTableDeletedValueType.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-class SVGElement;
-
-struct SVGAnimatedPropertyDescription {
- // Empty value
- SVGAnimatedPropertyDescription()
- : m_element(0)
- , m_attributeName(0)
- {
- }
-
- // Deleted value
- SVGAnimatedPropertyDescription(WTF::HashTableDeletedValueType)
- : m_element(reinterpret_cast<SVGElement*>(-1))
- {
- }
-
- bool isHashTableDeletedValue() const
- {
- return m_element == reinterpret_cast<SVGElement*>(-1);
- }
-
- SVGAnimatedPropertyDescription(SVGElement* element, const AtomicString& attributeName)
- : m_element(element)
- , m_attributeName(attributeName.impl())
- {
- ASSERT(m_element);
- ASSERT(m_attributeName);
- }
-
- bool operator==(const SVGAnimatedPropertyDescription& other) const
- {
- return m_element == other.m_element && m_attributeName == other.m_attributeName;
- }
-
- SVGElement* m_element;
- StringImpl* m_attributeName;
-};
-
-struct SVGAnimatedPropertyDescriptionHash {
- static unsigned hash(const SVGAnimatedPropertyDescription& key)
- {
- return StringHasher::hashMemory<sizeof(SVGAnimatedPropertyDescription)>(&key);
- }
-
- static bool equal(const SVGAnimatedPropertyDescription& a, const SVGAnimatedPropertyDescription& b)
- {
- return a == b;
- }
-
- static const bool safeToCompareToEmptyOrDeleted = true;
-};
-
-struct SVGAnimatedPropertyDescriptionHashTraits : WTF::SimpleClassHashTraits<SVGAnimatedPropertyDescription> { };
-
-}
-
-#endif // SVGAnimatedPropertyDescription_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyMacros.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyMacros.h
deleted file mode 100644
index 74e377f6e6b..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyMacros.h
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
- * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedPropertyMacros_h
-#define SVGAnimatedPropertyMacros_h
-
-#include "core/dom/Element.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "core/svg/properties/SVGAttributeToPropertyMap.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/StdLibExtras.h"
-
-namespace WebCore {
-
-// SVGSynchronizableAnimatedProperty implementation
-template<typename PropertyType>
-struct SVGSynchronizableAnimatedProperty {
- SVGSynchronizableAnimatedProperty()
- : value(SVGPropertyTraits<PropertyType>::initialValue())
- , shouldSynchronize(false)
- {
- }
-
- template<typename ConstructorParameter1>
- SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1)
- : value(value1)
- , shouldSynchronize(false)
- {
- }
-
- template<typename ConstructorParameter1, typename ConstructorParameter2>
- SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1, const ConstructorParameter2& value2)
- : value(value1, value2)
- , shouldSynchronize(false)
- {
- }
-
- void synchronize(Element* ownerElement, const QualifiedName& attrName, const AtomicString& value)
- {
- ownerElement->setSynchronizedLazyAttribute(attrName, value);
- }
-
- PropertyType value;
- bool shouldSynchronize : 1;
-};
-
-// Property registration helpers
-#define BEGIN_REGISTER_ANIMATED_PROPERTIES(OwnerType) \
-SVGAttributeToPropertyMap& OwnerType::attributeToPropertyMap() \
-{ \
- DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, s_attributeToPropertyMap, ()); \
- return s_attributeToPropertyMap; \
-} \
-\
-SVGAttributeToPropertyMap& OwnerType::localAttributeToPropertyMap() const \
-{ \
- return attributeToPropertyMap(); \
-} \
-\
-void OwnerType::registerAnimatedPropertiesFor##OwnerType() \
-{ \
- OwnerType::m_cleanupAnimatedPropertiesCaller.setOwner(this); \
- SVGAttributeToPropertyMap& map = OwnerType::attributeToPropertyMap(); \
- if (!map.isEmpty()) \
- return; \
- typedef OwnerType UseOwnerType;
-
-#define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) \
- map.addProperty(UseOwnerType::LowerProperty##PropertyInfo());
-
-#define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) \
- map.addProperties(ClassName::attributeToPropertyMap()); \
-
-#define END_REGISTER_ANIMATED_PROPERTIES }
-
-// Property definition helpers (used in SVG*.cpp files)
-#define DEFINE_ANIMATED_PROPERTY(AnimatedPropertyTypeEnum, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty, TearOffType, PropertyType) \
-const SVGPropertyInfo* OwnerType::LowerProperty##PropertyInfo() { \
- DEFINE_STATIC_LOCAL(const SVGPropertyInfo, s_propertyInfo, \
- (AnimatedPropertyTypeEnum, \
- PropertyIsReadWrite, \
- DOMAttribute, \
- SVGDOMAttributeIdentifier, \
- &OwnerType::synchronize##UpperProperty, \
- &OwnerType::lookupOrCreate##UpperProperty##Wrapper)); \
- return &s_propertyInfo; \
-} \
-PropertyType& OwnerType::LowerProperty##CurrentValue() const \
-{ \
- if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) { \
- if (wrapper->isAnimating()) \
- return wrapper->currentAnimatedValue(); \
- } \
- return m_##LowerProperty.value; \
-} \
-\
-PropertyType& OwnerType::LowerProperty##BaseValue() const \
-{ \
- return m_##LowerProperty.value; \
-} \
-\
-void OwnerType::set##UpperProperty##BaseValue(const PropertyType& type) \
-{ \
- m_##LowerProperty.value = type; \
-} \
-\
-PassRefPtr<TearOffType> OwnerType::LowerProperty() \
-{ \
- m_##LowerProperty.shouldSynchronize = true; \
- return static_pointer_cast<TearOffType>(lookupOrCreate##UpperProperty##Wrapper(this)); \
-} \
-\
-void OwnerType::synchronize##UpperProperty() \
-{ \
- if (!m_##LowerProperty.shouldSynchronize) \
- return; \
- AtomicString value(SVGPropertyTraits<PropertyType>::toString(m_##LowerProperty.value)); \
- m_##LowerProperty.synchronize(this, LowerProperty##PropertyInfo()->attributeName, value); \
-} \
-\
-PassRefPtr<SVGAnimatedProperty> OwnerType::lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType) \
-{ \
- ASSERT(maskedOwnerType); \
- UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
- return SVGAnimatedProperty::lookupOrCreateWrapper<UseOwnerType, TearOffType, PropertyType>(ownerType, LowerProperty##PropertyInfo(), ownerType->m_##LowerProperty.value); \
-} \
-\
-void OwnerType::synchronize##UpperProperty(SVGElement* maskedOwnerType) \
-{ \
- ASSERT(maskedOwnerType); \
- UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
- ownerType->synchronize##UpperProperty(); \
-}
-
-// Property declaration helpers (used in SVG*.h files)
-#define BEGIN_DECLARE_ANIMATED_PROPERTIES(OwnerType) \
-public: \
- static SVGAttributeToPropertyMap& attributeToPropertyMap(); \
- virtual SVGAttributeToPropertyMap& localAttributeToPropertyMap() const; \
- void registerAnimatedPropertiesFor##OwnerType(); \
- typedef OwnerType UseOwnerType;
-
-#define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
-public: \
- static const SVGPropertyInfo* LowerProperty##PropertyInfo(); \
- PropertyType& LowerProperty##CurrentValue() const; \
- PropertyType& LowerProperty##BaseValue() const; \
- void set##UpperProperty##BaseValue(const PropertyType& type); \
- PassRefPtr<TearOffType> LowerProperty(); \
-\
-private: \
- void synchronize##UpperProperty(); \
- static PassRefPtr<SVGAnimatedProperty> lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType); \
- static void synchronize##UpperProperty(SVGElement* maskedOwnerType); \
-\
- mutable SVGSynchronizableAnimatedProperty<PropertyType> m_##LowerProperty;
-
-#define END_DECLARE_ANIMATED_PROPERTIES \
- CleanUpAnimatedPropertiesCaller m_cleanupAnimatedPropertiesCaller;
-
-// List specific definition/declaration helpers
-#define DECLARE_ANIMATED_LIST_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
-void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \
-{ \
- if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) \
- wrapper->detachListWrappers(newListSize); \
-}
-
-}
-
-#endif // SVGAnimatedPropertyMacros_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyTearOff.h
deleted file mode 100644
index c425b3b67bd..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedPropertyTearOff.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedPropertyTearOff_h
-#define SVGAnimatedPropertyTearOff_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "core/svg/properties/SVGPropertyTearOff.h"
-
-namespace WebCore {
-
-template<typename PropertyType>
-class SVGAnimatedPropertyTearOff : public SVGAnimatedProperty, public ScriptWrappable {
-public:
- typedef SVGPropertyTearOff<PropertyType> PropertyTearOff;
- typedef PropertyType ContentType;
-
- virtual ~SVGAnimatedPropertyTearOff()
- {
- if (m_baseVal) {
- ASSERT(m_baseVal->animatedProperty() == this);
- m_baseVal->setAnimatedProperty(0);
- }
- if (m_animVal) {
- ASSERT(m_animVal->animatedProperty() == this);
- m_animVal->setAnimatedProperty(0);
- }
- }
-
- PropertyTearOff* baseVal()
- {
- if (!m_baseVal)
- m_baseVal = PropertyTearOff::create(this, BaseValRole, m_property);
- return m_baseVal.get();
- }
-
- PropertyTearOff* animVal()
- {
- if (!m_animVal)
- m_animVal = PropertyTearOff::create(this, AnimValRole, m_property);
- return m_animVal.get();
- }
-
- static PassRefPtr<SVGAnimatedPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
- {
- ASSERT(contextElement);
- return adoptRef(new SVGAnimatedPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, property));
- }
-
- PropertyType& currentAnimatedValue()
- {
- ASSERT(m_isAnimating);
- ASSERT(m_animVal);
- return m_animVal->propertyReference();
- }
-
- const PropertyType& currentBaseValue() const
- {
- return m_property;
- }
-
- void animationStarted(PropertyType* newAnimVal)
- {
- ASSERT(!m_isAnimating);
- ASSERT(newAnimVal);
- animVal()->setValue(*newAnimVal);
- m_isAnimating = true;
- }
-
- void animationEnded()
- {
- ASSERT(m_isAnimating);
- ASSERT(m_animVal);
- m_animVal->setValue(m_property);
- m_isAnimating = false;
- }
-
- void animValWillChange()
- {
- // no-op for non list types.
- ASSERT(m_isAnimating);
- ASSERT(m_animVal);
- }
-
- void animValDidChange()
- {
- // no-op for non list types.
- ASSERT(m_isAnimating);
- ASSERT(m_animVal);
- }
-
-private:
- SVGAnimatedPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
- : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyType)
- , m_property(property)
- {
- ScriptWrappable::init(this);
- }
-
- PropertyType& m_property;
- RefPtr<PropertyTearOff> m_baseVal;
- RefPtr<PropertyTearOff> m_animVal;
-};
-
-}
-
-#endif // SVGAnimatedPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedStaticPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedStaticPropertyTearOff.h
deleted file mode 100644
index fb3e610517b..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedStaticPropertyTearOff.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedStaticPropertyTearOff_h
-#define SVGAnimatedStaticPropertyTearOff_h
-
-#include "core/svg/properties/SVGAnimatedProperty.h"
-
-namespace WebCore {
-
-class ExceptionState;
-
-template<typename PropertyType>
-class SVGAnimatedStaticPropertyTearOff : public SVGAnimatedProperty {
-public:
- typedef PropertyType ContentType;
-
- PropertyType& baseVal()
- {
- return m_property;
- }
-
- PropertyType& animVal()
- {
- if (m_animatedProperty)
- return *m_animatedProperty;
- return m_property;
- }
-
- virtual void setBaseVal(const PropertyType& property, ExceptionState&)
- {
- m_property = property;
- commitChange();
- }
-
- static PassRefPtr<SVGAnimatedStaticPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
- {
- ASSERT(contextElement);
- return adoptRef(new SVGAnimatedStaticPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, property));
- }
-
- PropertyType& currentAnimatedValue()
- {
- ASSERT(m_isAnimating);
- ASSERT(m_animatedProperty);
- return *m_animatedProperty;
- }
-
- const PropertyType& currentBaseValue() const
- {
- return m_property;
- }
-
- void animationStarted(PropertyType* newAnimVal)
- {
- ASSERT(!m_isAnimating);
- ASSERT(!m_animatedProperty);
- ASSERT(newAnimVal);
- m_animatedProperty = newAnimVal;
- m_isAnimating = true;
- }
-
- void animationEnded()
- {
- ASSERT(m_isAnimating);
- ASSERT(m_animatedProperty);
- m_animatedProperty = 0;
- m_isAnimating = false;
- }
-
- void animValWillChange()
- {
- // no-op for non list types.
- ASSERT(m_isAnimating);
- ASSERT(m_animatedProperty);
- }
-
- void animValDidChange()
- {
- // no-op for non list types.
- ASSERT(m_isAnimating);
- ASSERT(m_animatedProperty);
- }
-
-protected:
- SVGAnimatedStaticPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
- : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyType)
- , m_property(property)
- , m_animatedProperty(0)
- {
- }
-
-private:
- PropertyType& m_property;
- PropertyType* m_animatedProperty;
-};
-
-}
-
-#endif // SVGAnimatedStaticPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h
deleted file mode 100644
index 0bc26c475d2..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedTransformListPropertyTearOff_h
-#define SVGAnimatedTransformListPropertyTearOff_h
-
-#include "core/svg/SVGTransformList.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
-#include "core/svg/properties/SVGTransformListPropertyTearOff.h"
-
-namespace WebCore {
-
-class SVGAnimatedTransformListPropertyTearOff : public SVGAnimatedListPropertyTearOff<SVGTransformList> {
-public:
- virtual SVGListPropertyTearOff<SVGTransformList>* baseVal()
- {
- if (!m_baseVal)
- m_baseVal = SVGTransformListPropertyTearOff::create(this, BaseValRole, m_values, m_wrappers);
- return static_cast<SVGListPropertyTearOff<SVGTransformList>*>(m_baseVal.get());
- }
-
- virtual SVGListPropertyTearOff<SVGTransformList>* animVal()
- {
- if (!m_animVal)
- m_animVal = SVGTransformListPropertyTearOff::create(this, AnimValRole, m_values, m_wrappers);
- return static_cast<SVGListPropertyTearOff<SVGTransformList>*>(m_animVal.get());
- }
-
- static PassRefPtr<SVGAnimatedTransformListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGTransformList& values)
- {
- ASSERT(contextElement);
- return adoptRef(new SVGAnimatedTransformListPropertyTearOff(contextElement, attributeName, animatedPropertyType, values));
- }
-
-private:
- SVGAnimatedTransformListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGTransformList& values)
- : SVGAnimatedListPropertyTearOff<SVGTransformList>(contextElement, attributeName, animatedPropertyType, values)
- {
- }
-};
-
-}
-
-#endif // SVGAnimatedTransformListPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp
deleted file mode 100644
index cabeb2245d0..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/properties/SVGAttributeToPropertyMap.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace WebCore {
-
-void SVGAttributeToPropertyMap::addProperties(const SVGAttributeToPropertyMap& map)
-{
- AttributeToPropertiesMap::const_iterator end = map.m_map.end();
- for (AttributeToPropertiesMap::const_iterator it = map.m_map.begin(); it != end; ++it) {
- const PropertiesVector* mapVector = it->value.get();
- ASSERT(mapVector);
-
- if (!mapVector->isEmpty()) {
- const SVGPropertyInfo* firstProperty = mapVector->first();
- ASSERT(firstProperty);
- const QualifiedName& attributeName = firstProperty->attributeName;
-
- // All of the properties in mapVector are guaranteed to have the same attribute name.
- // Add them to our properties vector for that attribute name, reserving capacity up
- // front.
- PropertiesVector* vector = getOrCreatePropertiesVector(attributeName);
- ASSERT(vector);
- vector->reserveCapacity(vector->size() + mapVector->size());
- const PropertiesVector::const_iterator mapVectorEnd = mapVector->end();
- for (PropertiesVector::const_iterator mapVectorIt = mapVector->begin(); mapVectorIt != mapVectorEnd; ++mapVectorIt) {
- ASSERT(*mapVectorIt);
- ASSERT(attributeName == (*mapVectorIt)->attributeName);
- vector->append(*mapVectorIt);
- }
- }
- }
-}
-
-void SVGAttributeToPropertyMap::addProperty(const SVGPropertyInfo* info)
-{
- ASSERT(info);
- PropertiesVector* vector = getOrCreatePropertiesVector(info->attributeName);
- ASSERT(vector);
- vector->append(info);
-}
-
-void SVGAttributeToPropertyMap::animatedPropertiesForAttribute(SVGElement* ownerType, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty> >& properties)
-{
- ASSERT(ownerType);
- PropertiesVector* vector = m_map.get(attributeName);
- if (!vector)
- return;
-
- properties.reserveCapacity(properties.size() + vector->size());
- const PropertiesVector::iterator vectorEnd = vector->end();
- for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- properties.append(animatedProperty(ownerType, attributeName, *vectorIt));
-}
-
-void SVGAttributeToPropertyMap::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes)
-{
- PropertiesVector* vector = m_map.get(attributeName);
- if (!vector)
- return;
-
- propertyTypes.reserveCapacity(propertyTypes.size() + vector->size());
- const PropertiesVector::iterator vectorEnd = vector->end();
- for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- propertyTypes.append((*vectorIt)->animatedPropertyType);
-}
-
-void SVGAttributeToPropertyMap::synchronizeProperties(SVGElement* contextElement)
-{
- ASSERT(contextElement);
- const AttributeToPropertiesMap::iterator end = m_map.end();
- for (AttributeToPropertiesMap::iterator it = m_map.begin(); it != end; ++it) {
- PropertiesVector* vector = it->value.get();
- ASSERT(vector);
-
- const PropertiesVector::iterator vectorEnd = vector->end();
- for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- synchronizeProperty(contextElement, it->key, *vectorIt);
- }
-}
-
-bool SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName)
-{
- ASSERT(contextElement);
- PropertiesVector* vector = m_map.get(attributeName);
- if (!vector)
- return false;
-
- const PropertiesVector::iterator vectorEnd = vector->end();
- for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
- synchronizeProperty(contextElement, attributeName, *vectorIt);
-
- return true;
-}
-
-SVGAttributeToPropertyMap::PropertiesVector* SVGAttributeToPropertyMap::getOrCreatePropertiesVector(const QualifiedName& attributeName)
-{
- ASSERT(attributeName != anyQName());
- AttributeToPropertiesMap::AddResult addResult = m_map.add(attributeName, PassOwnPtr<PropertiesVector>());
- PropertiesVector* vector = addResult.iterator->value.get();
- if (addResult.isNewEntry) {
- ASSERT(!vector);
- vector = (addResult.iterator->value = adoptPtr(new PropertiesVector)).get();
- }
- ASSERT(vector);
- ASSERT(addResult.iterator->value.get() == vector);
- return vector;
-}
-
-void SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info)
-{
- ASSERT(info);
- ASSERT_UNUSED(attributeName, attributeName == info->attributeName);
- ASSERT(info->synchronizeProperty);
- (*info->synchronizeProperty)(contextElement);
-}
-
-PassRefPtr<SVGAnimatedProperty> SVGAttributeToPropertyMap::animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info)
-{
- ASSERT(info);
- ASSERT_UNUSED(attributeName, attributeName == info->attributeName);
- ASSERT(info->lookupOrCreateWrapperForAnimatedProperty);
- return (*info->lookupOrCreateWrapperForAnimatedProperty)(contextElement);
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.h
deleted file mode 100644
index d2e04cf369e..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAttributeToPropertyMap_h
-#define SVGAttributeToPropertyMap_h
-
-#include "core/svg/properties/SVGPropertyInfo.h"
-#include "wtf/HashMap.h"
-
-namespace WebCore {
-
-class SVGAnimatedProperty;
-class SVGElement;
-
-class SVGAttributeToPropertyMap {
-private:
- typedef Vector<const SVGPropertyInfo*> PropertiesVector;
- typedef HashMap<QualifiedName, OwnPtr<PropertiesVector> > AttributeToPropertiesMap;
-
-public:
- bool isEmpty() const { return m_map.isEmpty(); }
-
- void addProperties(const SVGAttributeToPropertyMap&);
- void addProperty(const SVGPropertyInfo*);
-
- // FIXME: To match WebKit coding style either these functions should have return values instead of out parameters,
- // or the word "get" should be added as a prefix to their names.
- void animatedPropertiesForAttribute(SVGElement* contextElement, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty> >&);
- void animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>&);
-
- void synchronizeProperties(SVGElement* contextElement);
- bool synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName);
-
-private:
- PropertiesVector* getOrCreatePropertiesVector(const QualifiedName&);
- void synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo*);
- PassRefPtr<SVGAnimatedProperty> animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo*);
-
- AttributeToPropertiesMap m_map;
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGListProperty.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGListProperty.h
deleted file mode 100644
index 27e8d66cf1d..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGListProperty.h
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGListProperty_h
-#define SVGListProperty_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/svg/properties/SVGPropertyTearOff.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-
-namespace WebCore {
-
-enum ListModification {
- ListModificationUnknown = 0,
- ListModificationInsert = 1,
- ListModificationReplace = 2,
- ListModificationRemove = 3,
- ListModificationAppend = 4
-};
-
-template<typename PropertyType>
-class SVGAnimatedListPropertyTearOff;
-
-template<typename PropertyType>
-class SVGListProperty : public SVGProperty {
-public:
- typedef SVGListProperty<PropertyType> Self;
-
- typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
- typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
- typedef PassRefPtr<ListItemTearOff> PassListItemTearOff;
- typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff;
- typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache;
-
- bool canAlterList(ExceptionState& exceptionState) const
- {
- if (m_role == AnimValRole) {
- exceptionState.throwUninformativeAndGenericDOMException(NoModificationAllowedError);
- return false;
- }
-
- return true;
- }
-
- static void detachListWrappersAndResize(ListWrapperCache* wrappers, unsigned newListSize = 0)
- {
- // See SVGPropertyTearOff::detachWrapper() for an explanation about what's happening here.
- ASSERT(wrappers);
- unsigned size = wrappers->size();
- for (unsigned i = 0; i < size; ++i) {
- if (ListItemTearOff* item = wrappers->at(i).get())
- item->detachWrapper();
- }
-
- // Reinitialize the wrapper cache to be equal to the new values size, after the XML DOM changed the list.
- if (newListSize)
- wrappers->fill(0, newListSize);
- else
- wrappers->clear();
- }
-
- void detachListWrappers(unsigned newListSize)
- {
- detachListWrappersAndResize(m_wrappers, newListSize);
- }
-
- void setValuesAndWrappers(PropertyType* values, ListWrapperCache* wrappers, bool shouldOwnValues)
- {
- // This is only used for animVal support, to switch the underlying values & wrappers
- // to the current animated values, once animation for a list starts.
- ASSERT(m_values);
- ASSERT(m_wrappers);
- ASSERT(m_role == AnimValRole);
- if (m_ownsValues)
- delete m_values;
- m_values = values;
- m_ownsValues = shouldOwnValues;
- m_wrappers = wrappers;
- ASSERT(m_values->size() == m_wrappers->size());
- }
-
- // SVGList::clear()
- void clearValues(ExceptionState& exceptionState)
- {
- if (!canAlterList(exceptionState))
- return;
-
- m_values->clear();
- commitChange();
- }
-
- void clearValuesAndWrappers(ExceptionState& exceptionState)
- {
- if (!canAlterList(exceptionState))
- return;
-
- detachListWrappers(0);
- m_values->clear();
- commitChange();
- }
-
- // SVGList::numberOfItems()
- unsigned numberOfItems() const
- {
- return m_values->size();
- }
-
- // SVGList::initialize()
- ListItemType initializeValues(const ListItemType& newItem, ExceptionState& exceptionState)
- {
- if (!canAlterList(exceptionState))
- return ListItemType();
-
- // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list.
- processIncomingListItemValue(newItem, 0);
-
- // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter.
- m_values->clear();
- m_values->append(newItem);
-
- commitChange();
- return newItem;
- }
-
- PassListItemTearOff initializeValuesAndWrappers(PassListItemTearOff passNewItem, ExceptionState& exceptionState)
- {
- ASSERT(m_wrappers);
- if (!canAlterList(exceptionState))
- return 0;
-
- // Not specified, but FF/Opera do it this way, and it's just sane.
- if (!passNewItem) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return 0;
- }
-
- RefPtr<ListItemTearOff> newItem = passNewItem;
- ASSERT(m_values->size() == m_wrappers->size());
-
- // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list.
- processIncomingListItemWrapper(newItem, 0);
-
- // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter.
- detachListWrappers(0);
- m_values->clear();
-
- m_values->append(newItem->propertyReference());
- m_wrappers->append(newItem);
-
- commitChange();
- return newItem.release();
- }
-
- // SVGList::getItem()
- bool canGetItem(unsigned index, ExceptionState& exceptionState)
- {
- if (index >= m_values->size()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return false;
- }
-
- return true;
- }
-
- ListItemType getItemValues(unsigned index, ExceptionState& exceptionState)
- {
- if (!canGetItem(index, exceptionState))
- return ListItemType();
-
- // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy.
- return m_values->at(index);
- }
-
- PassListItemTearOff getItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionState& exceptionState)
- {
- ASSERT(m_wrappers);
- if (!canGetItem(index, exceptionState))
- return 0;
-
- // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy.
- // Any changes made to the item are immediately reflected in the list.
- ASSERT(m_values->size() == m_wrappers->size());
- RefPtr<ListItemTearOff> wrapper = m_wrappers->at(index);
- if (!wrapper) {
- // Create new wrapper, which is allowed to directly modify the item in the list, w/o copying and cache the wrapper in our map.
- // It is also associated with our animated property, so it can notify the SVG Element which holds the SVGAnimated*List
- // that it has been modified (and thus can call svgAttributeChanged(associatedAttributeName)).
- wrapper = ListItemTearOff::create(animatedList, UndefinedRole, m_values->at(index));
- m_wrappers->at(index) = wrapper;
- }
-
- return wrapper.release();
- }
-
- // SVGList::insertItemBefore()
- ListItemType insertItemBeforeValues(const ListItemType& newItem, unsigned index, ExceptionState& exceptionState)
- {
- if (!canAlterList(exceptionState))
- return ListItemType();
-
- // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
- if (index > m_values->size())
- index = m_values->size();
-
- // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
- if (!processIncomingListItemValue(newItem, &index)) {
- // Inserting the item before itself is a no-op.
- return newItem;
- }
-
- // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be
- // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list.
- m_values->insert(index, newItem);
-
- commitChange();
- return newItem;
- }
-
- PassListItemTearOff insertItemBeforeValuesAndWrappers(PassListItemTearOff passNewItem, unsigned index, ExceptionState& exceptionState)
- {
- ASSERT(m_wrappers);
- if (!canAlterList(exceptionState))
- return 0;
-
- // Not specified, but FF/Opera do it this way, and it's just sane.
- if (!passNewItem) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return 0;
- }
-
- // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
- if (index > m_values->size())
- index = m_values->size();
-
- RefPtr<ListItemTearOff> newItem = passNewItem;
- ASSERT(m_values->size() == m_wrappers->size());
-
- // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
- if (!processIncomingListItemWrapper(newItem, &index))
- return newItem.release();
-
- // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be
- // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list.
- m_values->insert(index, newItem->propertyReference());
-
- // Store new wrapper at position 'index', change its underlying value, so mutations of newItem, directly affect the item in the list.
- m_wrappers->insert(index, newItem);
-
- commitChange();
- return newItem.release();
- }
-
- // SVGList::replaceItem()
- bool canReplaceItem(unsigned index, ExceptionState& exceptionState)
- {
- if (!canAlterList(exceptionState))
- return false;
-
- if (index >= m_values->size()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return false;
- }
-
- return true;
- }
-
- ListItemType replaceItemValues(const ListItemType& newItem, unsigned index, ExceptionState& exceptionState)
- {
- if (!canReplaceItem(index, exceptionState))
- return ListItemType();
-
- // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
- // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item.
- if (!processIncomingListItemValue(newItem, &index)) {
- // Replacing the item with itself is a no-op.
- return newItem;
- }
-
- if (m_values->isEmpty()) {
- // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace.
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return ListItemType();
- }
-
- // Update the value at the desired position 'index'.
- m_values->at(index) = newItem;
-
- commitChange();
- return newItem;
- }
-
- PassListItemTearOff replaceItemValuesAndWrappers(PassListItemTearOff passNewItem, unsigned index, ExceptionState& exceptionState)
- {
- ASSERT(m_wrappers);
- if (!canReplaceItem(index, exceptionState))
- return 0;
-
- // Not specified, but FF/Opera do it this way, and it's just sane.
- if (!passNewItem) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return 0;
- }
-
- ASSERT(m_values->size() == m_wrappers->size());
- RefPtr<ListItemTearOff> newItem = passNewItem;
-
- // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
- // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item.
- if (!processIncomingListItemWrapper(newItem, &index))
- return newItem.release();
-
- if (m_values->isEmpty()) {
- ASSERT(m_wrappers->isEmpty());
- // 'passNewItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace.
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return 0;
- }
-
- // Detach the existing wrapper.
- RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index);
- if (oldItem)
- oldItem->detachWrapper();
-
- // Update the value and the wrapper at the desired position 'index'.
- m_values->at(index) = newItem->propertyReference();
- m_wrappers->at(index) = newItem;
-
- commitChange();
- return newItem.release();
- }
-
- // SVGList::removeItem()
- bool canRemoveItem(unsigned index, ExceptionState& exceptionState)
- {
- if (!canAlterList(exceptionState))
- return false;
-
- if (index >= m_values->size()) {
- exceptionState.throwUninformativeAndGenericDOMException(IndexSizeError);
- return false;
- }
-
- return true;
- }
-
- ListItemType removeItemValues(unsigned index, ExceptionState& exceptionState)
- {
- if (!canRemoveItem(index, exceptionState))
- return ListItemType();
-
- ListItemType oldItem = m_values->at(index);
- m_values->remove(index);
-
- commitChange();
- return oldItem;
- }
-
- PassListItemTearOff removeItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionState& exceptionState)
- {
- ASSERT(m_wrappers);
- if (!canRemoveItem(index, exceptionState))
- return 0;
-
- ASSERT(m_values->size() == m_wrappers->size());
-
- // Detach the existing wrapper.
- RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index);
- if (!oldItem)
- oldItem = ListItemTearOff::create(animatedList, UndefinedRole, m_values->at(index));
-
- oldItem->detachWrapper();
- m_wrappers->remove(index);
- m_values->remove(index);
-
- commitChange();
- return oldItem.release();
- }
-
- // SVGList::appendItem()
- ListItemType appendItemValues(const ListItemType& newItem, ExceptionState& exceptionState)
- {
- if (!canAlterList(exceptionState))
- return ListItemType();
-
- // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
- processIncomingListItemValue(newItem, 0);
-
- // Append the value at the end of the list.
- m_values->append(newItem);
-
- commitChange(ListModificationAppend);
- return newItem;
- }
-
- PassListItemTearOff appendItemValuesAndWrappers(PassListItemTearOff passNewItem, ExceptionState& exceptionState)
- {
- ASSERT(m_wrappers);
- if (!canAlterList(exceptionState))
- return 0;
-
- // Not specified, but FF/Opera do it this way, and it's just sane.
- if (!passNewItem) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return 0;
- }
-
- RefPtr<ListItemTearOff> newItem = passNewItem;
- ASSERT(m_values->size() == m_wrappers->size());
-
- // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
- processIncomingListItemWrapper(newItem, 0);
-
- // Append the value and wrapper at the end of the list.
- m_values->append(newItem->propertyReference());
- m_wrappers->append(newItem);
-
- commitChange(ListModificationAppend);
- return newItem.release();
- }
-
- PropertyType& values()
- {
- ASSERT(m_values);
- return *m_values;
- }
-
- ListWrapperCache& wrappers() const
- {
- ASSERT(m_wrappers);
- return *m_wrappers;
- }
-
-protected:
- SVGListProperty(SVGPropertyRole role, PropertyType& values, ListWrapperCache* wrappers)
- : m_role(role)
- , m_ownsValues(false)
- , m_values(&values)
- , m_wrappers(wrappers)
- {
- }
-
- virtual ~SVGListProperty()
- {
- if (m_ownsValues)
- delete m_values;
- }
-
- virtual void commitChange() = 0;
- virtual void commitChange(ListModification)
- {
- commitChange();
- }
-
- virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) = 0;
- virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) = 0;
-
- SVGPropertyRole m_role;
- bool m_ownsValues;
- PropertyType* m_values;
- ListWrapperCache* m_wrappers;
-};
-
-}
-
-#endif // SVGListProperty_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyHelper.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyHelper.h
new file mode 100644
index 00000000000..b8ffb22fc1a
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyHelper.h
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGListPropertyHelper_h
+#define SVGListPropertyHelper_h
+
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/properties/SVGProperty.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+// This is an implementation of the SVG*List property spec:
+// http://www.w3.org/TR/SVG/single-page.html#types-InterfaceSVGLengthList
+template<typename Derived, typename ItemProperty>
+class SVGListPropertyHelper : public SVGPropertyBase {
+public:
+ typedef ItemProperty ItemPropertyType;
+
+ SVGListPropertyHelper()
+ : SVGPropertyBase(Derived::classType())
+ {
+ }
+
+ ~SVGListPropertyHelper()
+ {
+ clear();
+ }
+
+ // used from Blink C++ code:
+
+ ItemPropertyType* at(size_t index)
+ {
+ ASSERT(index < m_values.size());
+ ASSERT(m_values.at(index)->ownerList() == this);
+ return m_values.at(index).get();
+ }
+
+ const ItemPropertyType* at(size_t index) const
+ {
+ return const_cast<SVGListPropertyHelper<Derived, ItemProperty>*>(this)->at(index);
+ }
+
+ class ConstIterator {
+ private:
+ typedef typename Vector<RefPtr<ItemPropertyType> >::const_iterator WrappedType;
+
+ public:
+ ConstIterator(WrappedType it)
+ : m_it(it)
+ {
+ }
+
+ ConstIterator& operator++() { ++m_it; return *this; }
+
+ bool operator==(const ConstIterator& o) const { return m_it == o.m_it; }
+ bool operator!=(const ConstIterator& o) const { return m_it != o.m_it; }
+
+ PassRefPtr<ItemPropertyType> operator*() { return *m_it; }
+ PassRefPtr<ItemPropertyType> operator->() { return *m_it; }
+
+ private:
+ WrappedType m_it;
+ };
+
+ ConstIterator begin() const
+ {
+ return ConstIterator(m_values.begin());
+ }
+
+ ConstIterator lastAppended() const
+ {
+ return ConstIterator(m_values.begin() + m_values.size() - 1);
+ }
+
+ ConstIterator end() const
+ {
+ return ConstIterator(m_values.end());
+ }
+
+ void append(PassRefPtr<ItemPropertyType> passNewItem)
+ {
+ RefPtr<ItemPropertyType> newItem = passNewItem;
+
+ ASSERT(newItem);
+ m_values.append(newItem);
+ newItem->setOwnerList(this);
+ }
+
+ bool operator==(const Derived&) const;
+ bool operator!=(const Derived& other) const
+ {
+ return !(*this == other);
+ }
+
+ bool isEmpty() const
+ {
+ return !length();
+ }
+
+ // SVGList*Property DOM spec:
+
+ size_t length() const
+ {
+ return m_values.size();
+ }
+
+ void clear();
+
+ PassRefPtr<ItemPropertyType> initialize(PassRefPtr<ItemPropertyType>);
+ PassRefPtr<ItemPropertyType> getItem(size_t, ExceptionState&);
+ PassRefPtr<ItemPropertyType> insertItemBefore(PassRefPtr<ItemPropertyType>, size_t);
+ PassRefPtr<ItemPropertyType> removeItem(size_t, ExceptionState&);
+ PassRefPtr<ItemPropertyType> appendItem(PassRefPtr<ItemPropertyType>);
+ PassRefPtr<ItemPropertyType> replaceItem(PassRefPtr<ItemPropertyType>, size_t, ExceptionState&);
+
+protected:
+ void deepCopy(PassRefPtr<Derived>);
+
+private:
+ inline bool checkIndexBound(size_t, ExceptionState&);
+ bool removeFromOldOwnerListAndAdjustIndex(PassRefPtr<ItemPropertyType>, size_t* indexToModify);
+ size_t findItem(PassRefPtr<ItemPropertyType>);
+
+ Vector<RefPtr<ItemPropertyType> > m_values;
+
+ static PassRefPtr<Derived> toDerived(PassRefPtr<SVGPropertyBase> passBase)
+ {
+ if (!passBase)
+ return nullptr;
+
+ RefPtr<SVGPropertyBase> base = passBase;
+ ASSERT(base->type() == Derived::classType());
+ return static_pointer_cast<Derived>(base);
+ }
+};
+
+template<typename Derived, typename ItemProperty>
+bool SVGListPropertyHelper<Derived, ItemProperty>::operator==(const Derived& other) const
+{
+ if (length() != other.length())
+ return false;
+
+ size_t size = length();
+ for (size_t i = 0; i < size; ++i) {
+ if (*at(i) != *other.at(i))
+ return false;
+ }
+
+ return true;
+}
+
+template<typename Derived, typename ItemProperty>
+void SVGListPropertyHelper<Derived, ItemProperty>::clear()
+{
+ // detach all list items as they are no longer part of this list
+ typename Vector<RefPtr<ItemPropertyType> >::const_iterator it = m_values.begin();
+ typename Vector<RefPtr<ItemPropertyType> >::const_iterator itEnd = m_values.end();
+ for (; it != itEnd; ++it) {
+ ASSERT((*it)->ownerList() == this);
+ (*it)->setOwnerList(0);
+ }
+
+ m_values.clear();
+}
+
+template<typename Derived, typename ItemProperty>
+PassRefPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty>::initialize(PassRefPtr<ItemProperty> passNewItem)
+{
+ RefPtr<ItemPropertyType> newItem = passNewItem;
+
+ // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list.
+ removeFromOldOwnerListAndAdjustIndex(newItem, 0);
+
+ // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter.
+ clear();
+ append(newItem);
+ return newItem.release();
+}
+
+template<typename Derived, typename ItemProperty>
+PassRefPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty>::getItem(size_t index, ExceptionState& exceptionState)
+{
+ if (!checkIndexBound(index, exceptionState))
+ return nullptr;
+
+ ASSERT(index < m_values.size());
+ ASSERT(m_values.at(index)->ownerList() == this);
+ return m_values.at(index);
+}
+
+template<typename Derived, typename ItemProperty>
+PassRefPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty>::insertItemBefore(PassRefPtr<ItemProperty> passNewItem, size_t index)
+{
+ // Spec: If the index is greater than or equal to length, then the new item is appended to the end of the list.
+ if (index > m_values.size())
+ index = m_values.size();
+
+ RefPtr<ItemPropertyType> newItem = passNewItem;
+
+ // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
+ if (!removeFromOldOwnerListAndAdjustIndex(newItem, &index)) {
+ // Inserting the item before itself is a no-op.
+ return newItem.release();
+ }
+
+ // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be
+ // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list.
+ m_values.insert(index, newItem);
+ newItem->setOwnerList(this);
+
+ return newItem.release();
+}
+
+template<typename Derived, typename ItemProperty>
+PassRefPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty>::removeItem(size_t index, ExceptionState& exceptionState)
+{
+ if (index >= m_values.size()) {
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, m_values.size()));
+ return nullptr;
+ }
+ ASSERT(m_values.at(index)->ownerList() == this);
+ RefPtr<ItemPropertyType> oldItem = m_values.at(index);
+ m_values.remove(index);
+ oldItem->setOwnerList(0);
+ return oldItem.release();
+}
+
+template<typename Derived, typename ItemProperty>
+PassRefPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty>::appendItem(PassRefPtr<ItemProperty> passNewItem)
+{
+ RefPtr<ItemPropertyType> newItem = passNewItem;
+
+ // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
+ removeFromOldOwnerListAndAdjustIndex(newItem, 0);
+
+ // Append the value and wrapper at the end of the list.
+ append(newItem);
+
+ return newItem.release();
+}
+
+template<typename Derived, typename ItemProperty>
+PassRefPtr<ItemProperty> SVGListPropertyHelper<Derived, ItemProperty>::replaceItem(PassRefPtr<ItemProperty> passNewItem, size_t index, ExceptionState& exceptionState)
+{
+ if (!checkIndexBound(index, exceptionState))
+ return nullptr;
+
+ RefPtr<ItemPropertyType> newItem = passNewItem;
+
+ // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
+ // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item.
+ if (!removeFromOldOwnerListAndAdjustIndex(newItem, &index)) {
+ // Replacing the item with itself is a no-op.
+ return newItem.release();
+ }
+
+ if (m_values.isEmpty()) {
+ // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace.
+ exceptionState.throwDOMException(IndexSizeError, String::format("Failed to replace the provided item at index %zu.", index));
+ return nullptr;
+ }
+
+ // Update the value at the desired position 'index'.
+ RefPtr<ItemPropertyType>& position = m_values[index];
+ ASSERT(position->ownerList() == this);
+ position->setOwnerList(0);
+ position = newItem;
+ newItem->setOwnerList(this);
+
+ return newItem.release();
+}
+
+template<typename Derived, typename ItemProperty>
+bool SVGListPropertyHelper<Derived, ItemProperty>::checkIndexBound(size_t index, ExceptionState& exceptionState)
+{
+ if (index >= m_values.size()) {
+ exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, m_values.size()));
+ return false;
+ }
+
+ return true;
+}
+
+template<typename Derived, typename ItemProperty>
+bool SVGListPropertyHelper<Derived, ItemProperty>::removeFromOldOwnerListAndAdjustIndex(PassRefPtr<ItemPropertyType> passItem, size_t* indexToModify)
+{
+ RefPtr<ItemPropertyType> item = passItem;
+ ASSERT(item);
+ RefPtr<Derived> ownerList = toDerived(item->ownerList());
+ if (!ownerList)
+ return true;
+
+ // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
+ // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal.
+ bool livesInOtherList = ownerList.get() != this;
+ size_t indexToRemove = ownerList->findItem(item);
+ ASSERT(indexToRemove != WTF::kNotFound);
+
+ // Do not remove newItem if already in this list at the target index.
+ if (!livesInOtherList && indexToModify && indexToRemove == *indexToModify)
+ return false;
+
+ ownerList->removeItem(indexToRemove, ASSERT_NO_EXCEPTION);
+
+ if (!indexToModify)
+ return true;
+
+ // If the item lived in our list, adjust the insertion index.
+ if (!livesInOtherList) {
+ size_t& index = *indexToModify;
+ // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item.
+ if (static_cast<size_t>(indexToRemove) < index)
+ --index;
+ }
+
+ return true;
+}
+
+template<typename Derived, typename ItemProperty>
+size_t SVGListPropertyHelper<Derived, ItemProperty>::findItem(PassRefPtr<ItemPropertyType> item)
+{
+ return m_values.find(item);
+}
+
+template<typename Derived, typename ItemProperty>
+void SVGListPropertyHelper<Derived, ItemProperty>::deepCopy(PassRefPtr<Derived> passFrom)
+{
+ RefPtr<Derived> from = passFrom;
+
+ clear();
+ typename Vector<RefPtr<ItemPropertyType> >::const_iterator it = from->m_values.begin();
+ typename Vector<RefPtr<ItemPropertyType> >::const_iterator itEnd = from->m_values.end();
+ for (; it != itEnd; ++it) {
+ append((*it)->clone());
+ }
+}
+
+}
+
+#endif // SVGListPropertyHelper_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyTearOff.h
deleted file mode 100644
index 7f1410974fb..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyTearOff.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGListPropertyTearOff_h
-#define SVGListPropertyTearOff_h
-
-#include "core/svg/properties/SVGListProperty.h"
-
-namespace WebCore {
-
-class ExceptionState;
-
-template<typename PropertyType>
-class SVGListPropertyTearOff : public SVGListProperty<PropertyType> {
-public:
- typedef SVGListProperty<PropertyType> Base;
- typedef SVGListPropertyTearOff<PropertyType> Self;
-
- typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
- typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
- typedef PassRefPtr<ListItemTearOff> PassListItemTearOff;
- typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff;
- typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache;
-
- using Base::m_role;
- using Base::m_values;
- using Base::m_wrappers;
-
- static PassRefPtr<Self> create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers)
- {
- ASSERT(animatedProperty);
- return adoptRef(new Self(animatedProperty, role, values, wrappers));
- }
-
- int findItem(ListItemTearOff* item) const
- {
- ASSERT(m_values);
- ASSERT(m_wrappers);
-
- unsigned size = m_wrappers->size();
- ASSERT(size == m_values->size());
- for (size_t i = 0; i < size; ++i) {
- if (item == m_wrappers->at(i))
- return i;
- }
-
- return -1;
- }
-
- void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
- {
- ASSERT(m_values);
- ASSERT(m_wrappers);
- ASSERT(m_values->size() == m_wrappers->size());
- ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_wrappers->size());
-
- RefPtr<ListItemTearOff>& item = m_wrappers->at(itemIndex);
- item->detachWrapper();
- m_wrappers->remove(itemIndex);
- m_values->remove(itemIndex);
-
- if (shouldSynchronizeWrappers)
- commitChange();
- }
-
- // SVGList API
- void clear(ExceptionState& exceptionState)
- {
- Base::clearValuesAndWrappers(exceptionState);
- }
-
- PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionState& exceptionState)
- {
- return Base::initializeValuesAndWrappers(passNewItem, exceptionState);
- }
-
- PassListItemTearOff getItem(unsigned index, ExceptionState& exceptionState)
- {
- ASSERT(m_animatedProperty);
- return Base::getItemValuesAndWrappers(m_animatedProperty, index, exceptionState);
- }
-
- PassListItemTearOff insertItemBefore(PassListItemTearOff passNewItem, unsigned index, ExceptionState& exceptionState)
- {
- return Base::insertItemBeforeValuesAndWrappers(passNewItem, index, exceptionState);
- }
-
- PassListItemTearOff replaceItem(PassListItemTearOff passNewItem, unsigned index, ExceptionState& exceptionState)
- {
- return Base::replaceItemValuesAndWrappers(passNewItem, index, exceptionState);
- }
-
- PassListItemTearOff removeItem(unsigned index, ExceptionState& exceptionState)
- {
- ASSERT(m_animatedProperty);
- return Base::removeItemValuesAndWrappers(m_animatedProperty, index, exceptionState);
- }
-
- PassListItemTearOff appendItem(PassListItemTearOff passNewItem, ExceptionState& exceptionState)
- {
- return Base::appendItemValuesAndWrappers(passNewItem, exceptionState);
- }
-
- SVGElement* contextElement() const
- {
- ASSERT(m_animatedProperty);
- return m_animatedProperty->contextElement();
- }
-
- void clearAnimatedProperty()
- {
- ASSERT(m_animatedProperty);
- m_animatedProperty = 0;
- }
-
-protected:
- SVGListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers)
- : SVGListProperty<PropertyType>(role, values, &wrappers)
- , m_animatedProperty(animatedProperty)
- {
- ASSERT(m_animatedProperty);
- }
-
- virtual bool isReadOnly() const
- {
- if (m_role == AnimValRole)
- return true;
- if (m_animatedProperty && m_animatedProperty->isReadOnly())
- return true;
- return false;
- }
-
- virtual void commitChange()
- {
- ASSERT(m_values);
- ASSERT(m_wrappers);
- ASSERT(m_animatedProperty);
-
- // Update existing wrappers, as the index in the values list has changed.
- unsigned size = m_wrappers->size();
- ASSERT(size == m_values->size());
- for (unsigned i = 0; i < size; ++i) {
- ListItemTearOff* item = m_wrappers->at(i).get();
- if (!item)
- continue;
- item->setAnimatedProperty(m_animatedProperty);
- item->setValue(m_values->at(i));
- }
-
- m_animatedProperty->commitChange();
- }
-
- virtual bool processIncomingListItemValue(const ListItemType&, unsigned*)
- {
- ASSERT_NOT_REACHED();
- return true;
- }
-
- virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify)
- {
- SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty();
-
- // newItem has been created manually, it doesn't belong to any SVGElement.
- // (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createSVGLength())")
- if (!animatedPropertyOfItem)
- return true;
-
- // newItem belongs to a SVGElement, but its associated SVGAnimatedProperty is not an animated list tear off.
- // (for example: "textElement.x.baseVal.appendItem(rectElement.width.baseVal)")
- if (!animatedPropertyOfItem->isAnimatedListTearOff()) {
- // We have to copy the incoming newItem, as we're not allowed to insert this tear off as is into our wrapper cache.
- // Otherwhise we'll end up having two SVGAnimatedPropertys that operate on the same SVGPropertyTearOff. Consider the example above:
- // SVGRectElements SVGAnimatedLength 'width' property baseVal points to the same tear off object
- // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would
- // mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that.
- newItem = ListItemTearOff::create(newItem->propertyReference());
- return true;
- }
-
- // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
- // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal.
- ASSERT(m_animatedProperty);
- bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty;
- AnimatedListPropertyTearOff* propertyTearOff = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem);
- int indexToRemove = propertyTearOff->findItem(newItem.get());
- ASSERT(indexToRemove != -1);
-
- // Do not remove newItem if already in this list at the target index.
- if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify)
- return false;
-
- propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList);
-
- if (!indexToModify)
- return true;
-
- // If the item lived in our list, adjust the insertion index.
- if (!livesInOtherList) {
- unsigned& index = *indexToModify;
- // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item.
- if (static_cast<unsigned>(indexToRemove) < index)
- --index;
- }
-
- return true;
- }
-
- // Back pointer to the animated property that created us
- // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAnimatedLengthList object
- AnimatedListPropertyTearOff* m_animatedProperty;
-};
-
-}
-
-#endif // SVGListPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyTearOffHelper.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyTearOffHelper.h
new file mode 100644
index 00000000000..99df6ae3eb6
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/properties/SVGListPropertyTearOffHelper.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGListPropertyTearOffHelper_h
+#define SVGListPropertyTearOffHelper_h
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+#include "wtf/HashMap.h"
+#include "wtf/TypeTraits.h"
+
+namespace WebCore {
+
+template<typename ItemProperty>
+class ListItemPropertyTraits {
+public:
+ typedef ItemProperty ItemPropertyType;
+ typedef typename ItemPropertyType::TearOffType ItemTearOffType;
+
+ static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem, SVGElement* contextElement, const QualifiedName& attributeName)
+ {
+ RefPtr<ItemTearOffType> newItem = passNewItem;
+
+ // |newItem| is immutable, OR
+ // |newItem| belongs to a SVGElement, but it does not belong to an animated list
+ // (for example: "textElement.x.baseVal.appendItem(rectElement.width.baseVal)")
+ if (newItem->isImmutable()
+ || (newItem->contextElement() && !newItem->target()->ownerList())) {
+ // We have to copy the incoming |newItem|,
+ // Otherwise we'll end up having two tearoffs that operate on the same SVGProperty. Consider the example below:
+ // SVGRectElements SVGAnimatedLength 'width' property baseVal points to the same tear off object
+ // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would
+ // mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that.
+ return newItem->target()->clone();
+ }
+
+ newItem->attachToSVGElementAttribute(contextElement, attributeName);
+ return newItem->target();
+ }
+
+ static PassRefPtr<ItemTearOffType> createTearOff(PassRefPtr<ItemPropertyType> value, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+ {
+ return ItemTearOffType::create(value, contextElement, propertyIsAnimVal, attributeName);
+ }
+};
+
+template<typename Derived, typename ListProperty>
+class SVGListPropertyTearOffHelper : public SVGPropertyTearOff<ListProperty> {
+public:
+ typedef ListProperty ListPropertyType;
+ typedef typename ListPropertyType::ItemPropertyType ItemPropertyType;
+ typedef typename ItemPropertyType::TearOffType ItemTearOffType;
+ typedef ListItemPropertyTraits<ItemPropertyType> ItemTraits;
+
+ // SVG*List DOM interface:
+
+ // WebIDL requires "unsigned long" type instead of size_t.
+ unsigned long length()
+ {
+ return toDerived()->target()->length();
+ }
+
+ void clear(ExceptionState& exceptionState)
+ {
+ if (toDerived()->isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return;
+ }
+
+ toDerived()->target()->clear();
+ }
+
+ PassRefPtr<ItemTearOffType> initialize(PassRefPtr<ItemTearOffType> passItem, ExceptionState& exceptionState)
+ {
+ RefPtr<ItemTearOffType> item = passItem;
+
+ if (toDerived()->isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return nullptr;
+ }
+
+ if (!item) {
+ exceptionState.throwTypeError("Lists must be initialized with a valid item.");
+ return nullptr;
+ }
+
+ RefPtr<ItemPropertyType> value = toDerived()->target()->initialize(getValueForInsertionFromTearOff(item));
+ toDerived()->commitChange();
+
+ return createItemTearOff(value.release());
+ }
+
+ PassRefPtr<ItemTearOffType> getItem(unsigned long index, ExceptionState& exceptionState)
+ {
+ RefPtr<ItemPropertyType> value = toDerived()->target()->getItem(index, exceptionState);
+ return createItemTearOff(value.release());
+ }
+
+ PassRefPtr<ItemTearOffType> insertItemBefore(PassRefPtr<ItemTearOffType> passItem, unsigned long index, ExceptionState& exceptionState)
+ {
+ RefPtr<ItemTearOffType> item = passItem;
+
+ if (toDerived()->isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return nullptr;
+ }
+
+ if (!item) {
+ exceptionState.throwTypeError("An invalid item cannot be inserted to a list.");
+ return nullptr;
+ }
+
+ RefPtr<ItemPropertyType> value = toDerived()->target()->insertItemBefore(getValueForInsertionFromTearOff(item), index);
+ toDerived()->commitChange();
+
+ return createItemTearOff(value.release());
+ }
+
+ PassRefPtr<ItemTearOffType> replaceItem(PassRefPtr<ItemTearOffType> passItem, unsigned long index, ExceptionState& exceptionState)
+ {
+ RefPtr<ItemTearOffType> item = passItem;
+
+ if (toDerived()->isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return nullptr;
+ }
+
+ if (!item) {
+ exceptionState.throwTypeError("An invalid item cannot be replaced with an existing list item.");
+ return nullptr;
+ }
+
+ RefPtr<ItemPropertyType> value = toDerived()->target()->replaceItem(getValueForInsertionFromTearOff(item), index, exceptionState);
+ toDerived()->commitChange();
+
+ return createItemTearOff(value.release());
+ }
+
+ bool anonymousIndexedSetter(unsigned index, PassRefPtr<ItemTearOffType> passItem, ExceptionState& exceptionState)
+ {
+ replaceItem(passItem, index, exceptionState);
+ return true;
+ }
+
+ PassRefPtr<ItemTearOffType> removeItem(unsigned long index, ExceptionState& exceptionState)
+ {
+ RefPtr<ItemPropertyType> value = toDerived()->target()->removeItem(index, exceptionState);
+ toDerived()->commitChange();
+
+ return createItemTearOff(value.release());
+ }
+
+ PassRefPtr<ItemTearOffType> appendItem(PassRefPtr<ItemTearOffType> passItem, ExceptionState& exceptionState)
+ {
+ RefPtr<ItemTearOffType> item = passItem;
+
+ if (toDerived()->isImmutable()) {
+ exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
+ return nullptr;
+ }
+
+ if (!item) {
+ exceptionState.throwTypeError("An invalid item cannot be appended to a list.");
+ return nullptr;
+ }
+
+ RefPtr<ItemPropertyType> value = toDerived()->target()->appendItem(getValueForInsertionFromTearOff(item));
+ toDerived()->commitChange();
+
+ return createItemTearOff(value.release());
+ }
+
+protected:
+ SVGListPropertyTearOffHelper(PassRefPtr<ListPropertyType> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ : SVGPropertyTearOff<ListPropertyType>(target, contextElement, propertyIsAnimVal, attributeName)
+ {
+ }
+
+ PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem)
+ {
+ return ItemTraits::getValueForInsertionFromTearOff(passNewItem, toDerived()->contextElement(), toDerived()->attributeName());
+ }
+
+ PassRefPtr<ItemTearOffType> createItemTearOff(PassRefPtr<ItemPropertyType> value)
+ {
+ if (!value)
+ return nullptr;
+
+ if (value->ownerList() == toDerived()->target())
+ return ItemTraits::createTearOff(value, toDerived()->contextElement(), toDerived()->propertyIsAnimVal(), toDerived()->attributeName());
+
+ return ItemTraits::createTearOff(value, 0, PropertyIsNotAnimVal, QualifiedName::null());
+ }
+
+private:
+ Derived* toDerived() { return static_cast<Derived*>(this); }
+};
+
+}
+
+#endif // SVGListPropertyTearOffHelper_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGMatrixTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGMatrixTearOff.h
deleted file mode 100644
index 76935750407..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGMatrixTearOff.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGMatrixTearOff_h
-#define SVGMatrixTearOff_h
-
-#include "core/svg/SVGTransform.h"
-#include "core/svg/properties/SVGPropertyTearOff.h"
-
-namespace WebCore {
-
-class SVGMatrixTearOff : public SVGPropertyTearOff<SVGMatrix> {
-public:
- // Used for child types (baseVal/animVal) of a SVGAnimated* property (for example: SVGAnimatedLength::baseVal()).
- // Also used for list tear offs (for example: text.x.baseVal.getItem(0)).
- static PassRefPtr<SVGMatrixTearOff> create(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, SVGMatrix& value)
- {
- ASSERT(animatedProperty);
- return adoptRef(new SVGMatrixTearOff(animatedProperty, role, value));
- }
-
- // Used for non-animated POD types (for example: SVGSVGElement::createSVGLength()).
- static PassRefPtr<SVGMatrixTearOff> create(const SVGMatrix& initialValue)
- {
- return adoptRef(new SVGMatrixTearOff(initialValue));
- }
-
- // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute
- // and that contain a parent type that's exposed to the bindings via a SVGStaticPropertyTearOff object
- // (for example: SVGTransform::matrix).
- static PassRefPtr<SVGMatrixTearOff> create(SVGPropertyTearOff<SVGTransform>* parent, SVGMatrix& value)
- {
- ASSERT(parent);
- RefPtr<SVGMatrixTearOff> result = adoptRef(new SVGMatrixTearOff(parent, value));
- parent->addChild(result->m_weakFactory.createWeakPtr());
- return result.release();
- }
-
- virtual void commitChange()
- {
- if (m_parent) {
- // This is a tear-off from a SVGPropertyTearOff<SVGTransform>.
- m_parent->propertyReference().updateSVGMatrix();
- m_parent->commitChange();
- } else {
- // This is either a detached tear-off or a reference tear-off from a AnimatedProperty.
- SVGPropertyTearOff<SVGMatrix>::commitChange();
- }
- }
-
- // SVGMatrixTearOff can be a child tear-off of a SVGTransform tear-off,
- // which means that |m_value| may be pointing inside |m_value| of the other tear-off.
- // This method is called from the parent SVGTransform tear-off when |m_parent->m_value| is updated,
- // so that |this->m_value| would point to valid location.
- virtual void setValueForMatrixIfNeeded(SVGTransform* transform)
- {
- setValue(transform->svgMatrix());
- }
-
- SVGPropertyTearOff<SVGTransform>* parent() { return m_parent; }
-
-private:
- SVGMatrixTearOff(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, SVGMatrix& value)
- : SVGPropertyTearOff<SVGMatrix>(animatedProperty, role, value)
- , m_parent(0)
- , m_weakFactory(this)
- {
- }
-
- SVGMatrixTearOff(const SVGMatrix& initialValue)
- : SVGPropertyTearOff<SVGMatrix>(initialValue)
- , m_parent(0)
- , m_weakFactory(this)
- {
- }
-
- SVGMatrixTearOff(SVGPropertyTearOff<SVGTransform>* parent, SVGMatrix& value)
- : SVGPropertyTearOff<SVGMatrix>(0, UndefinedRole, value)
- , m_parent(parent)
- , m_weakFactory(this)
- {
- }
-
- // m_parent is kept alive from V8 wrapper.
- SVGPropertyTearOff<SVGTransform>* m_parent;
-
- WeakPtrFactory<SVGPropertyTearOffBase > m_weakFactory;
-};
-
-}
-
-#endif // SVGMatrixTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
deleted file mode 100644
index 48cb03a468d..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/properties/SVGPathSegListPropertyTearOff.h"
-
-#include "SVGNames.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/svg/SVGPathElement.h"
-#include "core/svg/SVGPathSegWithContext.h"
-#include "core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h"
-
-namespace WebCore {
-
-void SVGPathSegListPropertyTearOff::clearContextAndRoles()
-{
- ASSERT(m_values);
- unsigned size = m_values->size();
- for (unsigned i = 0; i < size; ++i) {
- ListItemType item = m_values->at(i);
- static_cast<SVGPathSegWithContext*>(item.get())->setContextAndRole(0, PathSegUndefinedRole);
- }
-}
-
-void SVGPathSegListPropertyTearOff::clear(ExceptionState& exceptionState)
-{
- ASSERT(m_values);
- if (m_values->isEmpty())
- return;
-
- clearContextAndRoles();
- SVGPathSegListPropertyTearOff::Base::clearValues(exceptionState);
-}
-
-SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::getItem(unsigned index, ExceptionState& exceptionState)
-{
- ListItemType returnedItem = Base::getItemValues(index, exceptionState);
- if (returnedItem) {
- ASSERT(static_cast<SVGPathSegWithContext*>(returnedItem.get())->contextElement() == contextElement());
- ASSERT(static_cast<SVGPathSegWithContext*>(returnedItem.get())->role() == m_pathSegRole);
- }
- return returnedItem.release();
-}
-
-SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::replaceItem(PassListItemType passNewItem, unsigned index, ExceptionState& exceptionState)
-{
- // Not specified, but FF/Opera do it this way, and it's just sane.
- if (!passNewItem) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return 0;
- }
-
- if (index < m_values->size()) {
- ListItemType replacedItem = m_values->at(index);
- ASSERT(replacedItem);
- static_cast<SVGPathSegWithContext*>(replacedItem.get())->setContextAndRole(0, PathSegUndefinedRole);
- }
-
- ListItemType newItem = passNewItem;
- return Base::replaceItemValues(newItem, index, exceptionState);
-}
-
-SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::removeItem(unsigned index, ExceptionState& exceptionState)
-{
- SVGPathSegListPropertyTearOff::ListItemType removedItem = SVGPathSegListPropertyTearOff::Base::removeItemValues(index, exceptionState);
- if (removedItem)
- static_cast<SVGPathSegWithContext*>(removedItem.get())->setContextAndRole(0, PathSegUndefinedRole);
- return removedItem.release();
-}
-
-SVGPathElement* SVGPathSegListPropertyTearOff::contextElement() const
-{
- SVGElement* contextElement = m_animatedProperty->contextElement();
- ASSERT(contextElement);
- return toSVGPathElement(contextElement);
-}
-
-bool SVGPathSegListPropertyTearOff::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify)
-{
- SVGPathSegWithContext* newItemWithContext = static_cast<SVGPathSegWithContext*>(newItem.get());
- SVGAnimatedProperty* animatedPropertyOfItem = newItemWithContext->animatedProperty();
-
- // Alter the role, after calling animatedProperty(), as that may influence the returned animated property.
- newItemWithContext->setContextAndRole(contextElement(), m_pathSegRole);
-
- if (!animatedPropertyOfItem)
- return true;
-
- // newItem belongs to a SVGPathElement, but its associated SVGAnimatedProperty is not an animated list tear off.
- // (for example: "pathElement.pathSegList.appendItem(pathElement.createSVGPathSegClosepath())")
- if (!animatedPropertyOfItem->isAnimatedListTearOff())
- return true;
-
- // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
- // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal.
- bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty;
- SVGAnimatedPathSegListPropertyTearOff* propertyTearOff = static_cast<SVGAnimatedPathSegListPropertyTearOff*>(animatedPropertyOfItem);
- int indexToRemove = propertyTearOff->findItem(newItem.get());
- ASSERT(indexToRemove != -1);
-
- // Do not remove newItem if already in this list at the target index.
- if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify)
- return false;
-
- propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList);
-
- if (!indexToModify)
- return true;
-
- // If the item lived in our list, adjust the insertion index.
- if (!livesInOtherList) {
- unsigned& index = *indexToModify;
- // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item.
- if (static_cast<unsigned>(indexToRemove) < index)
- --index;
- }
-
- return true;
-}
-
-}
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.h
deleted file mode 100644
index 4a755f76b77..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGPathSegListPropertyTearOff_h
-#define SVGPathSegListPropertyTearOff_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/svg/SVGPathSegList.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
-
-namespace WebCore {
-
-class SVGPathElement;
-
-class SVGPathSegListPropertyTearOff : public SVGListProperty<SVGPathSegList> {
-public:
- typedef SVGListProperty<SVGPathSegList> Base;
- typedef SVGAnimatedListPropertyTearOff<SVGPathSegList> AnimatedListPropertyTearOff;
- typedef SVGPropertyTraits<SVGPathSegList>::ListItemType ListItemType;
- typedef PassRefPtr<SVGPathSeg> PassListItemType;
-
- static PassRefPtr<SVGPathSegListPropertyTearOff> create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegList& values, ListWrapperCache& wrappers)
- {
- ASSERT(animatedProperty);
- return adoptRef(new SVGPathSegListPropertyTearOff(animatedProperty, role, pathSegRole, values, wrappers));
- }
-
- SVGPathElement* contextElement() const;
- SVGAnimatedProperty* animatedProperty() const { return m_animatedProperty; }
-
- int findItem(const ListItemType& item) const
- {
- ASSERT(m_values);
-
- unsigned size = m_values->size();
- for (size_t i = 0; i < size; ++i) {
- if (item == m_values->at(i))
- return i;
- }
-
- return -1;
- }
-
- void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
- {
- ASSERT(m_values);
- ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_values->size());
-
- m_values->remove(itemIndex);
-
- if (shouldSynchronizeWrappers)
- commitChange();
- }
-
- // SVGList API
- void clear(ExceptionState&);
-
- PassListItemType initialize(PassListItemType passNewItem, ExceptionState& exceptionState)
- {
- // Not specified, but FF/Opera do it this way, and it's just sane.
- if (!passNewItem) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return 0;
- }
-
- clearContextAndRoles();
- ListItemType newItem = passNewItem;
- return Base::initializeValues(newItem, exceptionState);
- }
-
- PassListItemType getItem(unsigned index, ExceptionState&);
-
- PassListItemType insertItemBefore(PassListItemType passNewItem, unsigned index, ExceptionState& exceptionState)
- {
- // Not specified, but FF/Opera do it this way, and it's just sane.
- if (!passNewItem) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return 0;
- }
-
- ListItemType newItem = passNewItem;
- return Base::insertItemBeforeValues(newItem, index, exceptionState);
- }
-
- PassListItemType replaceItem(PassListItemType, unsigned index, ExceptionState&);
-
- PassListItemType removeItem(unsigned index, ExceptionState&);
-
- PassListItemType appendItem(PassListItemType passNewItem, ExceptionState& exceptionState)
- {
- // Not specified, but FF/Opera do it this way, and it's just sane.
- if (!passNewItem) {
- exceptionState.throwUninformativeAndGenericTypeError();
- return 0;
- }
-
- ListItemType newItem = passNewItem;
- return Base::appendItemValues(newItem, exceptionState);
- }
-
-private:
- SVGPathSegListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegList& values, ListWrapperCache& wrappers)
- : SVGListProperty<SVGPathSegList>(role, values, &wrappers)
- , m_animatedProperty(animatedProperty)
- , m_pathSegRole(pathSegRole)
- {
- }
-
- void clearContextAndRoles();
-
- using Base::m_role;
-
- virtual bool isReadOnly() const
- {
- if (m_role == AnimValRole)
- return true;
- if (m_animatedProperty && m_animatedProperty->isReadOnly())
- return true;
- return false;
- }
-
- virtual void commitChange()
- {
- ASSERT(m_values);
- m_values->commitChange(m_animatedProperty->contextElement(), ListModificationUnknown);
- }
-
- virtual void commitChange(ListModification listModification)
- {
- ASSERT(m_values);
- m_values->commitChange(m_animatedProperty->contextElement(), listModification);
- }
-
- virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) OVERRIDE;
- virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*)
- {
- ASSERT_NOT_REACHED();
- return true;
- }
-
-private:
- AnimatedListPropertyTearOff* m_animatedProperty;
- SVGPathSegRole m_pathSegRole;
-};
-
-}
-
-#endif // SVGListPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGProperty.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGProperty.h
index 3ccc289e626..1f8ca826a39 100644
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGProperty.h
+++ b/chromium/third_party/WebKit/Source/core/svg/properties/SVGProperty.h
@@ -1,41 +1,106 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGProperty_h
#define SVGProperty_h
+#include "core/svg/properties/SVGPropertyInfo.h"
+#include "platform/heap/Handle.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
+#include "wtf/text/WTFString.h"
namespace WebCore {
-enum SVGPropertyRole {
- UndefinedRole,
- BaseValRole,
- AnimValRole
-};
+class ExceptionState;
+class SVGElement;
+class SVGAnimationElement;
+
+class SVGPropertyBase : public RefCountedWillBeRefCountedGarbageCollected<SVGPropertyBase> {
+ WTF_MAKE_NONCOPYABLE(SVGPropertyBase);
-class SVGProperty : public RefCounted<SVGProperty> {
public:
- virtual ~SVGProperty() { }
+ // Properties do not have a primitive type by default
+ typedef void PrimitiveType;
+
+ virtual ~SVGPropertyBase()
+ {
+ ASSERT(!m_ownerList);
+ }
+
+ // FIXME: remove this in WebAnimations transition.
+ // This is used from SVGAnimatedNewPropertyAnimator for its animate-by-string implementation.
+ virtual PassRefPtr<SVGPropertyBase> cloneForAnimation(const String&) const = 0;
+
+ virtual String valueAsString() const = 0;
+
+ // FIXME: remove below and just have this inherit AnimatableValue in WebAnimations transition.
+ virtual void add(PassRefPtrWillBeRawPtr<SVGPropertyBase>, SVGElement*) = 0;
+ virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<SVGPropertyBase> from, PassRefPtr<SVGPropertyBase> to, PassRefPtr<SVGPropertyBase> toAtEndOfDurationValue, SVGElement*) = 0;
+ virtual float calculateDistance(PassRefPtr<SVGPropertyBase> to, SVGElement*) = 0;
+
+ AnimatedPropertyType type()
+ {
+ return m_type;
+ }
+
+ SVGPropertyBase* ownerList() const
+ {
+ return m_ownerList;
+ }
+
+ void setOwnerList(SVGPropertyBase* ownerList)
+ {
+ // Previous owner list must be cleared before setting new owner list.
+ ASSERT((!ownerList && m_ownerList) || (ownerList && !m_ownerList));
+
+ m_ownerList = ownerList;
+ }
+
+ virtual void trace(Visitor* visitor)
+ {
+ visitor->trace(m_ownerList);
+ }
+
+protected:
+ explicit SVGPropertyBase(AnimatedPropertyType type)
+ : m_type(type)
+ , m_ownerList(nullptr)
+ {
+ }
+
+private:
+ const AnimatedPropertyType m_type;
- virtual bool isReadOnly() const = 0;
- virtual void commitChange() = 0;
+ RawPtrWillBeMember<SVGPropertyBase> m_ownerList;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyInfo.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyInfo.h
index f77be4fd515..46cf3ade719 100644
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyInfo.h
+++ b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyInfo.h
@@ -20,19 +20,8 @@
#ifndef SVGPropertyInfo_h
#define SVGPropertyInfo_h
-#include "core/dom/QualifiedName.h"
-#include "wtf/PassRefPtr.h"
-
namespace WebCore {
-class SVGAnimatedProperty;
-class SVGElement;
-
-enum AnimatedPropertyState {
- PropertyIsReadWrite,
- PropertyIsReadOnly
-};
-
enum AnimatedPropertyType {
AnimatedAngle,
AnimatedBoolean,
@@ -46,40 +35,17 @@ enum AnimatedPropertyType {
AnimatedNumberList,
AnimatedNumberOptionalNumber,
AnimatedPath,
+ AnimatedPoint,
AnimatedPoints,
AnimatedPreserveAspectRatio,
AnimatedRect,
AnimatedString,
+ AnimatedStringList,
+ AnimatedTransform,
AnimatedTransformList,
AnimatedUnknown
};
-struct SVGPropertyInfo {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- typedef void (*SynchronizeProperty)(SVGElement*);
- typedef PassRefPtr<SVGAnimatedProperty> (*LookupOrCreateWrapperForAnimatedProperty)(SVGElement*);
-
- SVGPropertyInfo(AnimatedPropertyType newType, AnimatedPropertyState newState, const QualifiedName& newAttributeName,
- const AtomicString& newPropertyIdentifier, SynchronizeProperty newSynchronizeProperty,
- LookupOrCreateWrapperForAnimatedProperty newLookupOrCreateWrapperForAnimatedProperty)
- : animatedPropertyType(newType)
- , animatedPropertyState(newState)
- , attributeName(newAttributeName)
- , propertyIdentifier(newPropertyIdentifier)
- , synchronizeProperty(newSynchronizeProperty)
- , lookupOrCreateWrapperForAnimatedProperty(newLookupOrCreateWrapperForAnimatedProperty)
- {
- }
-
- AnimatedPropertyType animatedPropertyType;
- AnimatedPropertyState animatedPropertyState;
- const QualifiedName& attributeName;
- const AtomicString& propertyIdentifier;
- SynchronizeProperty synchronizeProperty;
- LookupOrCreateWrapperForAnimatedProperty lookupOrCreateWrapperForAnimatedProperty;
-};
-
}
#endif // SVGPropertyInfo_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.cpp b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.cpp
new file mode 100644
index 00000000000..fd8189d55dd
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/properties/SVGPropertyTearOff.h"
+
+#include "core/svg/SVGElement.h"
+
+namespace WebCore {
+
+void SVGPropertyTearOffBase::commitChange()
+{
+ ASSERT(!isImmutable());
+ if (!contextElement() || isAnimVal())
+ return;
+ ASSERT(m_attributeName != QualifiedName::null());
+ contextElement()->invalidateSVGAttributes();
+ contextElement()->svgAttributeChanged(m_attributeName);
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h
index b42f29bc452..57179b429aa 100644
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h
+++ b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h
@@ -1,188 +1,145 @@
/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2013 Google Inc. All rights reserved.
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
*
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SVGPropertyTearOff_h
#define SVGPropertyTearOff_h
-#include "core/svg/SVGElement.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
+#include "core/dom/QualifiedName.h"
#include "core/svg/properties/SVGProperty.h"
-#include "wtf/WeakPtr.h"
+#include "wtf/RefCounted.h"
namespace WebCore {
-class SVGPropertyTearOffBase : public SVGProperty {
-public:
- virtual void setValueForMatrixIfNeeded(SVGTransform*) { }
-
- virtual void detachWrapper() = 0;
+enum PropertyIsAnimValType {
+ PropertyIsNotAnimVal,
+ PropertyIsAnimVal
};
-template<typename PropertyType>
-class SVGPropertyTearOff : public SVGPropertyTearOffBase {
+class SVGPropertyTearOffBase : public RefCounted<SVGPropertyTearOffBase> {
public:
- typedef SVGPropertyTearOff<PropertyType> Self;
+ virtual ~SVGPropertyTearOffBase() { }
- // Used for child types (baseVal/animVal) of a SVGAnimated* property (for example: SVGAnimatedLength::baseVal()).
- // Also used for list tear offs (for example: text.x.baseVal.getItem(0)).
- static PassRefPtr<Self> create(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, PropertyType& value)
+ PropertyIsAnimValType propertyIsAnimVal() const
{
- ASSERT(animatedProperty);
- return adoptRef(new Self(animatedProperty, role, value));
+ return m_propertyIsAnimVal;
}
- // Used for non-animated POD types (for example: SVGSVGElement::createSVGLength()).
- static PassRefPtr<Self> create(const PropertyType& initialValue)
+ bool isAnimVal() const
{
- return adoptRef(new Self(initialValue));
+ return m_propertyIsAnimVal == PropertyIsAnimVal;
}
- PropertyType& propertyReference() { return *m_value; }
- SVGAnimatedProperty* animatedProperty() const { return m_animatedProperty; }
-
- void setValue(PropertyType& value)
+ bool isReadOnlyProperty() const
{
- if (m_valueIsCopy) {
- detachChildren();
- delete m_value;
- }
-
- updateChildrenTearOffs(&value);
-
- m_valueIsCopy = false;
- m_value = &value;
+ return m_isReadOnlyProperty;
}
- void setAnimatedProperty(SVGAnimatedProperty* animatedProperty)
+ void setIsReadOnlyProperty()
{
- m_animatedProperty = animatedProperty;
-
- if (m_animatedProperty)
- m_contextElement = m_animatedProperty->contextElement();
+ m_isReadOnlyProperty = true;
}
- SVGElement* contextElement() const
+ bool isImmutable() const
{
- if (!m_animatedProperty || m_valueIsCopy)
- return 0;
- ASSERT(m_contextElement);
- return m_contextElement;
+ return isReadOnlyProperty() || isAnimVal();
}
- void addChild(WeakPtr<SVGPropertyTearOffBase> child)
- {
- m_childTearOffs.append(child);
- }
+ virtual void commitChange();
- virtual void detachWrapper() OVERRIDE
+ SVGElement* contextElement()
{
- if (m_valueIsCopy)
- return;
-
- detachChildren();
-
- // Switch from a live value, to a non-live value.
- // For example: <text x="50"/>
- // var item = text.x.baseVal.getItem(0);
- // text.setAttribute("x", "100");
- // item.value still has to report '50' and it has to be possible to modify 'item'
- // w/o changing the "new item" (with x=100) in the text element.
- // Whenever the XML DOM modifies the "x" attribute, all existing wrappers are detached, using this function.
- m_value = new PropertyType(*m_value);
- m_valueIsCopy = true;
- m_animatedProperty = 0;
+ return m_contextElement;
}
- virtual void commitChange()
+ const QualifiedName& attributeName()
{
- if (!m_animatedProperty || m_valueIsCopy)
- return;
- m_animatedProperty->commitChange();
+ return m_attributeName;
}
- virtual bool isReadOnly() const
+ void attachToSVGElementAttribute(SVGElement* contextElement, const QualifiedName& attributeName)
{
- if (m_role == AnimValRole)
- return true;
- if (m_animatedProperty && m_animatedProperty->isReadOnly())
- return true;
- return false;
+ ASSERT(!isImmutable());
+ ASSERT(contextElement);
+ ASSERT(attributeName != QualifiedName::null());
+ m_contextElement = contextElement;
+ m_attributeName = attributeName;
}
+ virtual AnimatedPropertyType type() const = 0;
+
protected:
- SVGPropertyTearOff(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, PropertyType& value)
- : m_animatedProperty(animatedProperty)
- , m_role(role)
- , m_value(&value)
- , m_valueIsCopy(false)
+ SVGPropertyTearOffBase(SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ : m_contextElement(contextElement)
+ , m_propertyIsAnimVal(propertyIsAnimVal)
+ , m_isReadOnlyProperty(false)
+ , m_attributeName(attributeName)
{
- // Using operator & is completely fine, as SVGAnimatedProperty owns this reference,
- // and we're guaranteed to live as long as SVGAnimatedProperty does.
-
- if (m_animatedProperty)
- m_contextElement = m_animatedProperty->contextElement();
}
- SVGPropertyTearOff(const PropertyType& initialValue)
- : m_animatedProperty(0)
- , m_role(UndefinedRole)
- , m_value(new PropertyType(initialValue))
- , m_valueIsCopy(true)
- {
- }
+private:
+ // These references are kept alive from V8 wrapper to prevent reference cycles
+ SVGElement* m_contextElement;
- virtual ~SVGPropertyTearOff()
+ PropertyIsAnimValType m_propertyIsAnimVal;
+ bool m_isReadOnlyProperty;
+ QualifiedName m_attributeName;
+};
+
+template <typename Property>
+class SVGPropertyTearOff : public SVGPropertyTearOffBase {
+public:
+ Property* target()
{
- if (m_valueIsCopy)
- delete m_value;
+ return m_target.get();
}
- void detachChildren()
+ void setTarget(PassRefPtr<Property> target)
{
- for (Vector<WeakPtr<SVGPropertyTearOffBase> >::iterator iter = m_childTearOffs.begin(); iter != m_childTearOffs.end(); iter++) {
- if (iter->get())
- iter->get()->detachWrapper();
- }
- m_childTearOffs.clear();
+ m_target = target;
}
- // Update m_value of children tear-offs.
- // Currently only SVGTransform has child tear-offs.
- void updateChildrenTearOffs(SVGTransform* transform)
+ virtual AnimatedPropertyType type() const OVERRIDE
{
- for (Vector<WeakPtr<SVGPropertyTearOffBase> >::iterator iter = m_childTearOffs.begin(); iter != m_childTearOffs.end(); iter++) {
- if (iter->get())
- iter->get()->setValueForMatrixIfNeeded(transform);
- }
+ return Property::classType();
}
- void updateChildrenTearOffs(void*)
+protected:
+ SVGPropertyTearOff(PassRefPtr<Property> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = QualifiedName::null())
+ : SVGPropertyTearOffBase(contextElement, propertyIsAnimVal, attributeName)
+ , m_target(target)
{
- // Tear-offs for other types do not have child tear-offs.
+ ASSERT(m_target);
}
- SVGElement* m_contextElement;
- SVGAnimatedProperty* m_animatedProperty;
- SVGPropertyRole m_role;
- PropertyType* m_value;
- Vector<WeakPtr<SVGPropertyTearOffBase> > m_childTearOffs;
- bool m_valueIsCopy : 1;
+private:
+ RefPtr<Property> m_target;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTraits.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTraits.h
deleted file mode 100644
index a905f8a3f64..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGPropertyTraits.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGPropertyTraits_h
-#define SVGPropertyTraits_h
-
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-template<typename PropertyType>
-struct SVGPropertyTraits { };
-
-template<>
-struct SVGPropertyTraits<bool> {
- static bool initialValue() { return false; }
- static String toString(bool type) { return type ? "true" : "false"; }
-};
-
-template<>
-struct SVGPropertyTraits<unsigned> {
- static unsigned initialValue() { return 0; }
- static String toString(unsigned type) { return String::number(type); }
-};
-
-template<>
-struct SVGPropertyTraits<int> {
- static int initialValue() { return 0; }
- static String toString(int type) { return String::number(type); }
-};
-
-template<>
-struct SVGPropertyTraits<float> {
- static float initialValue() { return 0; }
- static String toString(float type) { return String::number(type); }
-};
-
-template<>
-struct SVGPropertyTraits<String> {
- static String initialValue() { return String(); }
- static String toString(const String& type) { return type; }
-};
-
-}
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGStaticListPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGStaticListPropertyTearOff.h
deleted file mode 100644
index 596a55185d9..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGStaticListPropertyTearOff.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGStaticListPropertyTearOff_h
-#define SVGStaticListPropertyTearOff_h
-
-#include "core/svg/properties/SVGListProperty.h"
-
-namespace WebCore {
-
-class ExceptionState;
-
-template<typename PropertyType>
-class SVGStaticListPropertyTearOff : public SVGListProperty<PropertyType> {
-public:
- typedef SVGListProperty<PropertyType> Base;
-
- typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
- typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
-
- using Base::m_role;
- using Base::m_values;
-
- static PassRefPtr<SVGStaticListPropertyTearOff<PropertyType> > create(SVGElement* contextElement, PropertyType& values)
- {
- ASSERT(contextElement);
- return adoptRef(new SVGStaticListPropertyTearOff<PropertyType>(contextElement, values));
- }
-
- SVGElement* contextElement() const { return m_contextElement; }
-
- // SVGList API
- void clear(ExceptionState& exceptionState)
- {
- Base::clearValues(exceptionState);
- }
-
- ListItemType initialize(const ListItemType& newItem, ExceptionState& exceptionState)
- {
- return Base::initializeValues(newItem, exceptionState);
- }
-
- ListItemType getItem(unsigned index, ExceptionState& exceptionState)
- {
- return Base::getItemValues(index, exceptionState);
- }
-
- ListItemType insertItemBefore(const ListItemType& newItem, unsigned index, ExceptionState& exceptionState)
- {
- return Base::insertItemBeforeValues(newItem, index, exceptionState);
- }
-
- ListItemType replaceItem(const ListItemType& newItem, unsigned index, ExceptionState& exceptionState)
- {
- return Base::replaceItemValues(newItem, index, exceptionState);
- }
-
- ListItemType removeItem(unsigned index, ExceptionState& exceptionState)
- {
- return Base::removeItemValues(index, exceptionState);
- }
-
- ListItemType appendItem(const ListItemType& newItem, ExceptionState& exceptionState)
- {
- return Base::appendItemValues(newItem, exceptionState);
- }
-
-private:
- SVGStaticListPropertyTearOff(SVGElement* contextElement, PropertyType& values)
- : SVGListProperty<PropertyType>(UndefinedRole, values, 0)
- , m_contextElement(contextElement)
- {
- m_contextElement->setContextElement();
- }
-
- virtual bool isReadOnly() const
- {
- return m_role == AnimValRole;
- }
-
- virtual void commitChange()
- {
- ASSERT(m_values);
- ASSERT(m_contextElement);
- m_values->commitChange(m_contextElement);
- }
-
- virtual bool processIncomingListItemValue(const ListItemType&, unsigned*)
- {
- // no-op for static lists
- return true;
- }
-
- virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*)
- {
- ASSERT_NOT_REACHED();
- return true;
- }
-
-private:
- SVGElement* m_contextElement;
-};
-
-}
-
-#endif // SVGStaticListPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGStaticPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGStaticPropertyTearOff.h
deleted file mode 100644
index 93d1cc58be8..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGStaticPropertyTearOff.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGStaticPropertyTearOff_h
-#define SVGStaticPropertyTearOff_h
-
-#include "core/svg/properties/SVGPropertyTearOff.h"
-
-namespace WebCore {
-
-#if COMPILER(MSVC)
-// UpdateMethod is 12 bytes. We have to pack to a size greater than or equal to that to avoid an
-// alignment warning (C4121). 16 is the next-largest size allowed for packing, so we use that.
-#pragma pack(push, 16)
-#endif
-template<typename ContextElement, typename PropertyType>
-class SVGStaticPropertyTearOff : public SVGPropertyTearOff<PropertyType> {
-public:
- typedef SVGStaticPropertyTearOff<ContextElement, PropertyType> Self;
- typedef void (ContextElement::*UpdateMethod)();
-
- // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute
- // (for example: SVGSVGElement::currentTranslate).
- static PassRefPtr<Self> create(ContextElement* contextElement, PropertyType& value, UpdateMethod update)
- {
- ASSERT(contextElement);
- return adoptRef(new Self(contextElement, value, update));
- }
-
- virtual void commitChange() { (m_contextElement.get()->*m_update)(); }
-
-private:
- SVGStaticPropertyTearOff(ContextElement* contextElement, PropertyType& value, UpdateMethod update)
- : SVGPropertyTearOff<PropertyType>(0, UndefinedRole, value)
- , m_update(update)
- , m_contextElement(contextElement)
- {
- m_contextElement->setContextElement();
- }
-
- UpdateMethod m_update;
- RefPtr<ContextElement> m_contextElement;
-};
-#if COMPILER(MSVC)
-#pragma pack(pop)
-#endif
-
-}
-
-#endif // SVGStaticPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/svg/properties/SVGTransformListPropertyTearOff.h b/chromium/third_party/WebKit/Source/core/svg/properties/SVGTransformListPropertyTearOff.h
deleted file mode 100644
index 2ec007fcfd8..00000000000
--- a/chromium/third_party/WebKit/Source/core/svg/properties/SVGTransformListPropertyTearOff.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGTransformListPropertyTearOff_h
-#define SVGTransformListPropertyTearOff_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/svg/SVGTransformList.h"
-#include "core/svg/properties/SVGListPropertyTearOff.h"
-
-namespace WebCore {
-
-// SVGTransformList contains two additional methods, that can be exposed to the bindings.
-class SVGTransformListPropertyTearOff : public SVGListPropertyTearOff<SVGTransformList> {
-public:
- typedef SVGAnimatedListPropertyTearOff<SVGTransformList> AnimatedListPropertyTearOff;
- typedef SVGAnimatedListPropertyTearOff<SVGTransformList>::ListWrapperCache ListWrapperCache;
-
- static PassRefPtr<SVGListPropertyTearOff<SVGTransformList> > create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGTransformList& values, ListWrapperCache& wrappers)
- {
- ASSERT(animatedProperty);
- return adoptRef(new SVGTransformListPropertyTearOff(animatedProperty, role, values, wrappers));
- }
-
- PassRefPtr<SVGPropertyTearOff<SVGTransform> > createSVGTransformFromMatrix(SVGPropertyTearOff<SVGMatrix>* matrix, ExceptionState& exceptionState)
- {
- ASSERT(m_values);
- if (!matrix) {
- exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError);
- return 0;
- }
- return SVGPropertyTearOff<SVGTransform>::create(m_values->createSVGTransformFromMatrix(matrix->propertyReference()));
- }
-
- PassRefPtr<SVGPropertyTearOff<SVGTransform> > consolidate(ExceptionState& exceptionState)
- {
- ASSERT(m_values);
- ASSERT(m_wrappers);
- if (!canAlterList(exceptionState))
- return 0;
-
- ASSERT(m_values->size() == m_wrappers->size());
-
- // Spec: If the list was empty, then a value of null is returned.
- if (m_values->isEmpty())
- return 0;
-
- detachListWrappers(0);
- RefPtr<SVGPropertyTearOff<SVGTransform> > wrapper = SVGPropertyTearOff<SVGTransform>::create(m_values->consolidate());
- m_wrappers->append(wrapper);
-
- ASSERT(m_values->size() == m_wrappers->size());
- return wrapper.release();
- }
-
-private:
- SVGTransformListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGTransformList& values, ListWrapperCache& wrappers)
- : SVGListPropertyTearOff<SVGTransformList>(animatedProperty, role, values, wrappers)
- {
- }
-};
-
-}
-
-#endif // SVGListPropertyTearOff_h
diff --git a/chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp b/chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp
index e4095502200..811336dac68 100644
--- a/chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp
+++ b/chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.cpp
@@ -31,9 +31,10 @@
#include "config.h"
#include "core/testing/DummyPageHolder.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
#include "wtf/Assertions.h"
namespace WebCore {
@@ -45,24 +46,25 @@ PassOwnPtr<DummyPageHolder> DummyPageHolder::create(const IntSize& initialViewSi
DummyPageHolder::DummyPageHolder(const IntSize& initialViewSize)
{
- m_pageClients.chromeClient = &m_chromeClient;
- m_pageClients.contextMenuClient = &m_contextMenuClient;
- m_pageClients.editorClient = &m_editorClient;
- m_pageClients.dragClient = &m_dragClient;
- m_pageClients.inspectorClient = &m_inspectorClient;
- m_pageClients.backForwardClient = &m_backForwardClient;
+ fillWithEmptyClients(m_pageClients);
+ m_page = adoptPtrWillBeNoop(new Page(m_pageClients));
+ Settings& settings = m_page->settings();
+ // FIXME: http://crbug.com/363843. This needs to find a better way to
+ // not create graphics layers.
+ settings.setAcceleratedCompositingEnabled(false);
- m_page = adoptPtr(new Page(m_pageClients));
-
- m_frame = Frame::create(FrameInit::create(0, m_page.get(), &m_frameLoaderClient));
+ m_frame = LocalFrame::create(&m_frameLoaderClient, &m_page->frameHost(), 0);
m_frame->setView(FrameView::create(m_frame.get(), initialViewSize));
m_frame->init();
}
DummyPageHolder::~DummyPageHolder()
{
+ m_page->willBeDestroyed();
m_page.clear();
+#if !ENABLE(OILPAN)
ASSERT(m_frame->hasOneRef());
+#endif
m_frame.clear();
}
@@ -71,7 +73,7 @@ Page& DummyPageHolder::page() const
return *m_page;
}
-Frame& DummyPageHolder::frame() const
+LocalFrame& DummyPageHolder::frame() const
{
return *m_frame;
}
diff --git a/chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.h b/chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.h
index d80f4dc083b..6f2df5d4125 100644
--- a/chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.h
+++ b/chromium/third_party/WebKit/Source/core/testing/DummyPageHolder.h
@@ -34,6 +34,7 @@
#include "core/loader/EmptyClients.h"
#include "core/page/Page.h"
#include "platform/geometry/IntSize.h"
+#include "platform/heap/Handle.h"
#include "wtf/FastAllocBase.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
@@ -42,18 +43,18 @@
namespace WebCore {
class Document;
-class Frame;
+class LocalFrame;
class FrameView;
class IntSize;
-// Creates a dummy Page, Frame, and FrameView whose clients are all no-op.
+// Creates a dummy Page, LocalFrame, and FrameView whose clients are all no-op.
//
// This class can be used when you write unit tests for components which do not work correctly without renderers.
// To make sure the renderers are created, you need to call |frameView().layout()| after you add nodes into
// |document()|.
//
-// Since DummyPageHolder stores empty clients in it, it must outlive the Page, Frame, FrameView and any other objects
-// created by it. DummyPageHolder's destructor ensures this condition by checking remaining references to the Frame.
+// Since DummyPageHolder stores empty clients in it, it must outlive the Page, LocalFrame, FrameView and any other objects
+// created by it. DummyPageHolder's destructor ensures this condition by checking remaining references to the LocalFrame.
class DummyPageHolder {
WTF_MAKE_NONCOPYABLE(DummyPageHolder);
@@ -63,23 +64,17 @@ public:
~DummyPageHolder();
Page& page() const;
- Frame& frame() const;
+ LocalFrame& frame() const;
FrameView& frameView() const;
Document& document() const;
private:
explicit DummyPageHolder(const IntSize& initialViewSize);
- OwnPtr<Page> m_page;
- RefPtr<Frame> m_frame;
+ OwnPtrWillBePersistent<Page> m_page;
+ RefPtr<LocalFrame> m_frame;
Page::PageClients m_pageClients;
- EmptyChromeClient m_chromeClient;
- EmptyContextMenuClient m_contextMenuClient;
- EmptyEditorClient m_editorClient;
- EmptyDragClient m_dragClient;
- EmptyInspectorClient m_inspectorClient;
- EmptyBackForwardClient m_backForwardClient;
EmptyFrameLoaderClient m_frameLoaderClient;
};
diff --git a/chromium/third_party/WebKit/Source/core/testing/GCObservation.h b/chromium/third_party/WebKit/Source/core/testing/GCObservation.h
index 469656acc66..53db8a00ef2 100644
--- a/chromium/third_party/WebKit/Source/core/testing/GCObservation.h
+++ b/chromium/third_party/WebKit/Source/core/testing/GCObservation.h
@@ -32,15 +32,19 @@
#define GCObservation_h
#include "bindings/v8/ScopedPersistent.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include <v8.h>
namespace WebCore {
-class GCObservation : public RefCounted<GCObservation> {
+class GCObservation : public RefCountedWillBeGarbageCollectedFinalized<GCObservation> {
public:
- static PassRefPtr<GCObservation> create(v8::Handle<v8::Value> observedValue) { return adoptRef(new GCObservation(observedValue)); }
+ static PassRefPtrWillBeRawPtr<GCObservation> create(v8::Handle<v8::Value> observedValue)
+ {
+ return adoptRefWillBeNoop(new GCObservation(observedValue));
+ }
~GCObservation() { }
// Caution: It is only feasible to determine whether an object was
@@ -50,6 +54,8 @@ public:
bool wasCollected() const { return m_collected; }
void setWasCollected();
+ void trace(Visitor*) { }
+
private:
explicit GCObservation(v8::Handle<v8::Value>);
diff --git a/chromium/third_party/WebKit/Source/core/testing/GCObservation.idl b/chromium/third_party/WebKit/Source/core/testing/GCObservation.idl
index 6c2d8e8b7cf..378b05526c7 100644
--- a/chromium/third_party/WebKit/Source/core/testing/GCObservation.idl
+++ b/chromium/third_party/WebKit/Source/core/testing/GCObservation.idl
@@ -28,10 +28,11 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-interface GCObservation {
+[
+ WillBeGarbageCollected,
+] interface GCObservation {
// Technically, this is true if the object was "near death"; the
// object may have been kept alive through a weak handle. Having
// been collected is the common case, though.
readonly attribute boolean wasCollected;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/testing/InspectorFrontendClientLocal.cpp b/chromium/third_party/WebKit/Source/core/testing/InspectorFrontendClientLocal.cpp
deleted file mode 100644
index f61a422654d..00000000000
--- a/chromium/third_party/WebKit/Source/core/testing/InspectorFrontendClientLocal.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "InspectorFrontendClientLocal.h"
-
-#include "bindings/v8/ScriptObject.h"
-#include "bindings/v8/ScriptState.h"
-#include "core/inspector/InspectorController.h"
-#include "core/inspector/InspectorFrontendHost.h"
-#include "core/page/Page.h"
-#include "core/frame/Settings.h"
-#include "platform/Timer.h"
-#include "public/platform/Platform.h"
-#include "public/platform/WebThread.h"
-#include "wtf/Deque.h"
-
-namespace WebCore {
-
-class InspectorBackendMessageQueue : public RefCounted<InspectorBackendMessageQueue> {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- explicit InspectorBackendMessageQueue(InspectorController& inspectorController)
- : m_inspectorController(&inspectorController)
- {
- }
-
- void dispatch(const String& message)
- {
- ASSERT(m_inspectorController);
- m_messages.append(message);
- schedule();
- }
-
- void stop()
- {
- m_inspectorController = 0;
- m_messages.clear();
- }
-
-private:
- void schedule()
- {
- class TaskImpl : public blink::WebThread::Task {
- public:
- RefPtr<InspectorBackendMessageQueue> owner;
- virtual void run()
- {
- owner->deliver();
- }
- };
- TaskImpl* taskImpl = new TaskImpl;
- taskImpl->owner = this;
- blink::Platform::current()->currentThread()->postTask(taskImpl);
- }
-
- void deliver()
- {
- if (!m_inspectorController)
- return;
- if (!m_messages.isEmpty()) {
- // Dispatch can lead to the timer destruction -> schedule the next shot first.
- schedule();
- m_inspectorController->dispatchMessageFromFrontend(m_messages.takeFirst());
- }
- }
-
- InspectorController* m_inspectorController;
- Deque<String> m_messages;
-};
-
-InspectorFrontendClientLocal::InspectorFrontendClientLocal(InspectorController& inspectorController, Page* frontendPage)
- : m_frontendPage(frontendPage)
-{
- m_frontendPage->settings().setAllowFileAccessFromFileURLs(true);
- m_messageQueue = adoptRef(new InspectorBackendMessageQueue(inspectorController));
-}
-
-InspectorFrontendClientLocal::~InspectorFrontendClientLocal()
-{
- m_messageQueue->stop();
- if (m_frontendHost)
- m_frontendHost->disconnectClient();
- m_frontendPage = 0;
-}
-
-void InspectorFrontendClientLocal::windowObjectCleared()
-{
- if (m_frontendHost)
- m_frontendHost->disconnectClient();
- ScriptState* frontendScriptState = mainWorldScriptState(m_frontendPage->mainFrame());
- m_frontendHost = InspectorFrontendHost::create(this, m_frontendPage);
- ScriptGlobalObject::set(frontendScriptState, "InspectorFrontendHost", m_frontendHost.get());
-}
-
-void InspectorFrontendClientLocal::sendMessageToBackend(const String& message)
-{
- m_messageQueue->dispatch(message);
-}
-
-} // namespace WebCore
-
diff --git a/chromium/third_party/WebKit/Source/core/testing/InspectorFrontendClientLocal.h b/chromium/third_party/WebKit/Source/core/testing/InspectorFrontendClientLocal.h
deleted file mode 100644
index a97b8d85005..00000000000
--- a/chromium/third_party/WebKit/Source/core/testing/InspectorFrontendClientLocal.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef InspectorFrontendClientLocal_h
-#define InspectorFrontendClientLocal_h
-
-#include "core/inspector/InspectorFrontendClient.h"
-#include "wtf/Forward.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class Frame;
-class InspectorController;
-class InspectorBackendMessageQueue;
-class InspectorFrontendHost;
-class Page;
-
-class InspectorFrontendClientLocal : public InspectorFrontendClient {
- WTF_MAKE_NONCOPYABLE(InspectorFrontendClientLocal); WTF_MAKE_FAST_ALLOCATED;
-public:
- InspectorFrontendClientLocal(InspectorController&, Page*);
- virtual ~InspectorFrontendClientLocal();
-
- virtual void windowObjectCleared();
-
- virtual void inspectedURLChanged(const String&) OVERRIDE { }
-
- virtual void sendMessageToBackend(const String& message);
-
- virtual void sendMessageToEmbedder(const String&) OVERRIDE { }
-
- virtual bool isUnderTest() { return true; }
-
-private:
- Page* m_frontendPage;
- // TODO(yurys): this ref shouldn't be needed.
- RefPtr<InspectorFrontendHost> m_frontendHost;
- RefPtr<InspectorBackendMessageQueue> m_messageQueue;
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.cpp b/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.cpp
index 95d706f90cb..437aced1483 100644
--- a/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.cpp
+++ b/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "InternalProfilers.h"
+#include "core/testing/InternalProfilers.h"
#include "public/platform/Platform.h"
#include "wtf/text/CString.h"
diff --git a/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.h b/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.h
index f948cffd6d1..f74c7c2044a 100644
--- a/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.h
+++ b/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.h
@@ -31,22 +31,26 @@
#ifndef InternalProfilers_h
#define InternalProfilers_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-
-
-class InternalProfilers : public RefCounted<InternalProfilers> {
+class InternalProfilers : public RefCountedWillBeGarbageCollected<InternalProfilers> {
public:
- static PassRefPtr<InternalProfilers> create() { return adoptRef(new InternalProfilers()); }
+ static PassRefPtrWillBeRawPtr<InternalProfilers> create()
+ {
+ return adoptRefWillBeNoop(new InternalProfilers());
+ }
void startHeapProfiling(const String& prefix);
void stopHeapProfiling();
void dumpHeapProfiling(const String& reason);
String getHeapProfile();
+
+ void trace(Visitor*) { }
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.idl b/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.idl
index 7030e9e4116..c73eb1a2572 100644
--- a/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.idl
+++ b/chromium/third_party/WebKit/Source/core/testing/InternalProfilers.idl
@@ -29,7 +29,7 @@
*/
[
- NoInterfaceObject
+ WillBeGarbageCollected,
] interface InternalProfilers {
void startHeapProfiling(DOMString prefix);
void stopHeapProfiling();
diff --git a/chromium/third_party/WebKit/Source/core/testing/InternalSettings.cpp b/chromium/third_party/WebKit/Source/core/testing/InternalSettings.cpp
index 41c75658894..23532b7468c 100644
--- a/chromium/third_party/WebKit/Source/core/testing/InternalSettings.cpp
+++ b/chromium/third_party/WebKit/Source/core/testing/InternalSettings.cpp
@@ -25,32 +25,32 @@
*/
#include "config.h"
-#include "InternalSettings.h"
+#include "core/testing/InternalSettings.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
#include "core/dom/ExceptionCode.h"
-#include "core/page/Page.h"
#include "core/frame/Settings.h"
-#include "platform/ColorChooser.h"
+#include "core/inspector/InspectorController.h"
+#include "core/page/Page.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/Supplementable.h"
#include "platform/text/LocaleToScriptMapping.h"
#define InternalSettingsGuardForSettingsReturn(returnValue) \
if (!settings()) { \
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \
+ exceptionState.throwDOMException(InvalidAccessError, "The settings object cannot be obtained."); \
return returnValue; \
}
#define InternalSettingsGuardForSettings() \
if (!settings()) { \
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \
+ exceptionState.throwDOMException(InvalidAccessError, "The settings object cannot be obtained."); \
return; \
}
#define InternalSettingsGuardForPage() \
if (!page()) { \
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError); \
+ exceptionState.throwDOMException(InvalidAccessError, "The page object cannot be obtained."); \
return; \
}
@@ -59,8 +59,7 @@ namespace WebCore {
InternalSettings::Backup::Backup(Settings* settings)
: m_originalCSSExclusionsEnabled(RuntimeEnabledFeatures::cssExclusionsEnabled())
, m_originalAuthorShadowDOMForAnyElementEnabled(RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled())
- , m_originalExperimentalWebSocketEnabled(settings->experimentalWebSocketEnabled())
- , m_originalStyleScoped(RuntimeEnabledFeatures::styleScopedEnabled())
+ , m_originalCSP(RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled())
, m_originalOverlayScrollbarsEnabled(RuntimeEnabledFeatures::overlayScrollbarsEnabled())
, m_originalEditingBehavior(settings->editingBehaviorType())
, m_originalTextAutosizingEnabled(settings->textAutosizingEnabled())
@@ -70,13 +69,9 @@ InternalSettings::Backup::Backup(Settings* settings)
, m_originalMockScrollbarsEnabled(settings->mockScrollbarsEnabled())
, m_langAttributeAwareFormControlUIEnabled(RuntimeEnabledFeatures::langAttributeAwareFormControlUIEnabled())
, m_imagesEnabled(settings->imagesEnabled())
- , m_shouldDisplaySubtitles(settings->shouldDisplaySubtitles())
- , m_shouldDisplayCaptions(settings->shouldDisplayCaptions())
- , m_shouldDisplayTextDescriptions(settings->shouldDisplayTextDescriptions())
, m_defaultVideoPosterURL(settings->defaultVideoPosterURL())
- , m_originalCompositorDrivenAcceleratedScrollEnabled(settings->compositorDrivenAcceleratedScrollingEnabled())
, m_originalLayerSquashingEnabled(settings->layerSquashingEnabled())
- , m_originalPasswordGenerationDecorationEnabled(settings->passwordGenerationDecorationEnabled())
+ , m_originalPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(RuntimeEnabledFeatures::pseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled())
{
}
@@ -84,8 +79,7 @@ void InternalSettings::Backup::restoreTo(Settings* settings)
{
RuntimeEnabledFeatures::setCSSExclusionsEnabled(m_originalCSSExclusionsEnabled);
RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(m_originalAuthorShadowDOMForAnyElementEnabled);
- settings->setExperimentalWebSocketEnabled(m_originalExperimentalWebSocketEnabled);
- RuntimeEnabledFeatures::setStyleScopedEnabled(m_originalStyleScoped);
+ RuntimeEnabledFeatures::setExperimentalContentSecurityPolicyFeaturesEnabled(m_originalCSP);
RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(m_originalOverlayScrollbarsEnabled);
settings->setEditingBehaviorType(m_originalEditingBehavior);
settings->setTextAutosizingEnabled(m_originalTextAutosizingEnabled);
@@ -95,25 +89,29 @@ void InternalSettings::Backup::restoreTo(Settings* settings)
settings->setMockScrollbarsEnabled(m_originalMockScrollbarsEnabled);
RuntimeEnabledFeatures::setLangAttributeAwareFormControlUIEnabled(m_langAttributeAwareFormControlUIEnabled);
settings->setImagesEnabled(m_imagesEnabled);
- settings->setShouldDisplaySubtitles(m_shouldDisplaySubtitles);
- settings->setShouldDisplayCaptions(m_shouldDisplayCaptions);
- settings->setShouldDisplayTextDescriptions(m_shouldDisplayTextDescriptions);
settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL);
- settings->setCompositorDrivenAcceleratedScrollingEnabled(m_originalCompositorDrivenAcceleratedScrollEnabled);
settings->setLayerSquashingEnabled(m_originalLayerSquashingEnabled);
- settings->setPasswordGenerationDecorationEnabled(m_originalPasswordGenerationDecorationEnabled);
settings->genericFontFamilySettings().reset();
+ RuntimeEnabledFeatures::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(m_originalPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled);
}
+#if ENABLE(OILPAN)
+InternalSettings* InternalSettings::from(Page& page)
+{
+ if (!HeapSupplement<Page>::from(page, supplementName()))
+ HeapSupplement<Page>::provideTo(page, supplementName(), new InternalSettings(page));
+ return static_cast<InternalSettings*>(HeapSupplement<Page>::from(page, supplementName()));
+}
+#else
// We can't use RefCountedSupplement because that would try to make InternalSettings RefCounted
// and InternalSettings is already RefCounted via its base class, InternalSettingsGenerated.
// Instead, we manually make InternalSettings supplement Page.
class InternalSettingsWrapper : public Supplement<Page> {
public:
- explicit InternalSettingsWrapper(Page* page)
+ explicit InternalSettingsWrapper(Page& page)
: m_internalSettings(InternalSettings::create(page)) { }
virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
virtual bool isRefCountedWrapper() const OVERRIDE { return true; }
#endif
InternalSettings* internalSettings() const { return m_internalSettings.get(); }
@@ -122,26 +120,27 @@ private:
RefPtr<InternalSettings> m_internalSettings;
};
-const char* InternalSettings::supplementName()
-{
- return "InternalSettings";
-}
-
-InternalSettings* InternalSettings::from(Page* page)
+InternalSettings* InternalSettings::from(Page& page)
{
if (!Supplement<Page>::from(page, supplementName()))
Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page)));
return static_cast<InternalSettingsWrapper*>(Supplement<Page>::from(page, supplementName()))->internalSettings();
}
+#endif
+
+const char* InternalSettings::supplementName()
+{
+ return "InternalSettings";
+}
InternalSettings::~InternalSettings()
{
}
-InternalSettings::InternalSettings(Page* page)
- : InternalSettingsGenerated(page)
- , m_page(page)
- , m_backup(&page->settings())
+InternalSettings::InternalSettings(Page& page)
+ : InternalSettingsGenerated(&page)
+ , m_page(&page)
+ , m_backup(&page.settings())
{
}
@@ -151,6 +150,7 @@ void InternalSettings::resetToConsistentState()
m_backup.restoreTo(settings());
m_backup = Backup(settings());
+ m_backup.m_originalTextAutosizingEnabled = settings()->textAutosizingEnabled();
InternalSettingsGenerated::resetToConsistentState();
}
@@ -173,14 +173,14 @@ void InternalSettings::setAuthorShadowDOMForAnyElementEnabled(bool isEnabled)
RuntimeEnabledFeatures::setAuthorShadowDOMForAnyElementEnabled(isEnabled);
}
-void InternalSettings::setExperimentalWebSocketEnabled(bool isEnabled)
+void InternalSettings::setExperimentalContentSecurityPolicyFeaturesEnabled(bool enabled)
{
- settings()->setExperimentalWebSocketEnabled(isEnabled);
+ RuntimeEnabledFeatures::setExperimentalContentSecurityPolicyFeaturesEnabled(enabled);
}
-void InternalSettings::setStyleScopedEnabled(bool enabled)
+void InternalSettings::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(bool enabled)
{
- RuntimeEnabledFeatures::setStyleScopedEnabled(enabled);
+ RuntimeEnabledFeatures::setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(enabled);
}
void InternalSettings::setOverlayScrollbarsEnabled(bool enabled)
@@ -188,26 +188,12 @@ void InternalSettings::setOverlayScrollbarsEnabled(bool enabled)
RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(enabled);
}
-void InternalSettings::setTouchEventEmulationEnabled(bool enabled, ExceptionState& exceptionState)
-{
- InternalSettingsGuardForSettings();
- settings()->setTouchEventEmulationEnabled(enabled);
-}
-
void InternalSettings::setViewportEnabled(bool enabled, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
settings()->setViewportEnabled(enabled);
}
-// FIXME: This is a temporary flag and should be removed once accelerated
-// overflow scroll is ready (crbug.com/254111).
-void InternalSettings::setCompositorDrivenAcceleratedScrollingEnabled(bool enabled, ExceptionState& exceptionState)
-{
- InternalSettingsGuardForSettings();
- settings()->setCompositorDrivenAcceleratedScrollingEnabled(enabled);
-}
-
// FIXME: This is a temporary flag and should be removed once squashing is
// ready (crbug.com/261605).
void InternalSettings::setLayerSquashingEnabled(bool enabled, ExceptionState& exceptionState)
@@ -216,80 +202,81 @@ void InternalSettings::setLayerSquashingEnabled(bool enabled, ExceptionState& ex
settings()->setLayerSquashingEnabled(enabled);
}
-void InternalSettings::setStandardFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
+void InternalSettings::setStandardFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
return;
settings()->genericFontFamilySettings().setStandard(family, code);
- m_page->setNeedsRecalcStyleInAllFrames();
+ settings()->notifyGenericFontFamilyChange();
}
-void InternalSettings::setSerifFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
+void InternalSettings::setSerifFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
return;
settings()->genericFontFamilySettings().setSerif(family, code);
- m_page->setNeedsRecalcStyleInAllFrames();
+ settings()->notifyGenericFontFamilyChange();
}
-void InternalSettings::setSansSerifFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
+void InternalSettings::setSansSerifFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
return;
settings()->genericFontFamilySettings().setSansSerif(family, code);
- m_page->setNeedsRecalcStyleInAllFrames();
+ settings()->notifyGenericFontFamilyChange();
}
-void InternalSettings::setFixedFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
+void InternalSettings::setFixedFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
return;
settings()->genericFontFamilySettings().setFixed(family, code);
- m_page->setNeedsRecalcStyleInAllFrames();
+ settings()->notifyGenericFontFamilyChange();
}
-void InternalSettings::setCursiveFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
+void InternalSettings::setCursiveFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
return;
settings()->genericFontFamilySettings().setCursive(family, code);
- m_page->setNeedsRecalcStyleInAllFrames();
+ settings()->notifyGenericFontFamilyChange();
}
-void InternalSettings::setFantasyFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
+void InternalSettings::setFantasyFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
return;
settings()->genericFontFamilySettings().setFantasy(family, code);
- m_page->setNeedsRecalcStyleInAllFrames();
+ settings()->notifyGenericFontFamilyChange();
}
-void InternalSettings::setPictographFontFamily(const String& family, const String& script, ExceptionState& exceptionState)
+void InternalSettings::setPictographFontFamily(const AtomicString& family, const String& script, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
UScriptCode code = scriptNameToCode(script);
if (code == USCRIPT_INVALID_CODE)
return;
settings()->genericFontFamilySettings().setPictograph(family, code);
- m_page->setNeedsRecalcStyleInAllFrames();
+ settings()->notifyGenericFontFamilyChange();
}
void InternalSettings::setTextAutosizingEnabled(bool enabled, ExceptionState& exceptionState)
{
InternalSettingsGuardForSettings();
settings()->setTextAutosizingEnabled(enabled);
+ m_page->inspectorController().setTextAutosizingEnabled(enabled);
}
void InternalSettings::setTextAutosizingWindowSizeOverride(int width, int height, ExceptionState& exceptionState)
@@ -327,7 +314,7 @@ void InternalSettings::setEditingBehavior(const String& editingBehavior, Excepti
else if (equalIgnoringCase(editingBehavior, "android"))
settings()->setEditingBehaviorType(EditingAndroidBehavior);
else
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The editing behavior type provided ('" + editingBehavior + "') is invalid.");
}
void InternalSettings::setLangAttributeAwareFormControlUIEnabled(bool enabled)
@@ -347,10 +334,13 @@ void InternalSettings::setDefaultVideoPosterURL(const String& url, ExceptionStat
settings()->setDefaultVideoPosterURL(url);
}
-void InternalSettings::setPasswordGenerationDecorationEnabled(bool enabled, ExceptionState& exceptionState)
+void InternalSettings::trace(Visitor* visitor)
{
- InternalSettingsGuardForSettings();
- settings()->setPasswordGenerationDecorationEnabled(enabled);
+ visitor->trace(m_page);
+ InternalSettingsGenerated::trace(visitor);
+#if ENABLE(OILPAN)
+ HeapSupplement<Page>::trace(visitor);
+#endif
}
}
diff --git a/chromium/third_party/WebKit/Source/core/testing/InternalSettings.h b/chromium/third_party/WebKit/Source/core/testing/InternalSettings.h
index cc064baa413..3716da921b1 100644
--- a/chromium/third_party/WebKit/Source/core/testing/InternalSettings.h
+++ b/chromium/third_party/WebKit/Source/core/testing/InternalSettings.h
@@ -27,9 +27,10 @@
#ifndef InternalSettings_h
#define InternalSettings_h
-#include "InternalSettingsGenerated.h"
+#include "core/InternalSettingsGenerated.h"
#include "core/editing/EditingBehaviorTypes.h"
#include "platform/geometry/IntSize.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
@@ -38,11 +39,16 @@ namespace WebCore {
class Document;
class ExceptionState;
-class Frame;
+class LocalFrame;
class Page;
class Settings;
-class InternalSettings : public InternalSettingsGenerated {
+#if ENABLE(OILPAN)
+class InternalSettings FINAL : public InternalSettingsGenerated, public HeapSupplement<Page> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(InternalSettings);
+#else
+class InternalSettings FINAL : public InternalSettingsGenerated {
+#endif
public:
class Backup {
public:
@@ -51,8 +57,7 @@ public:
bool m_originalCSSExclusionsEnabled;
bool m_originalAuthorShadowDOMForAnyElementEnabled;
- bool m_originalExperimentalWebSocketEnabled;
- bool m_originalStyleScoped;
+ bool m_originalCSP;
bool m_originalOverlayScrollbarsEnabled;
EditingBehaviorType m_originalEditingBehavior;
bool m_originalTextAutosizingEnabled;
@@ -62,49 +67,42 @@ public:
bool m_originalMockScrollbarsEnabled;
bool m_langAttributeAwareFormControlUIEnabled;
bool m_imagesEnabled;
- bool m_shouldDisplaySubtitles;
- bool m_shouldDisplayCaptions;
- bool m_shouldDisplayTextDescriptions;
String m_defaultVideoPosterURL;
- bool m_originalCompositorDrivenAcceleratedScrollEnabled;
bool m_originalLayerSquashingEnabled;
- bool m_originalPasswordGenerationDecorationEnabled;
+ bool m_originalPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled;
};
- static PassRefPtr<InternalSettings> create(Page* page)
+ static PassRefPtrWillBeRawPtr<InternalSettings> create(Page& page)
{
- return adoptRef(new InternalSettings(page));
+ return adoptRefWillBeNoop(new InternalSettings(page));
}
- static InternalSettings* from(Page*);
- void hostDestroyed() { m_page = 0; }
+ static InternalSettings* from(Page&);
+
+#if !ENABLE(OILPAN)
+ void hostDestroyed() { m_page = nullptr; }
+#endif
virtual ~InternalSettings();
void resetToConsistentState();
- void setStandardFontFamily(const String& family, const String& script, ExceptionState&);
- void setSerifFontFamily(const String& family, const String& script, ExceptionState&);
- void setSansSerifFontFamily(const String& family, const String& script, ExceptionState&);
- void setFixedFontFamily(const String& family, const String& script, ExceptionState&);
- void setCursiveFontFamily(const String& family, const String& script, ExceptionState&);
- void setFantasyFontFamily(const String& family, const String& script, ExceptionState&);
- void setPictographFontFamily(const String& family, const String& script, ExceptionState&);
+ void setStandardFontFamily(const AtomicString& family, const String& script, ExceptionState&);
+ void setSerifFontFamily(const AtomicString& family, const String& script, ExceptionState&);
+ void setSansSerifFontFamily(const AtomicString& family, const String& script, ExceptionState&);
+ void setFixedFontFamily(const AtomicString& family, const String& script, ExceptionState&);
+ void setCursiveFontFamily(const AtomicString& family, const String& script, ExceptionState&);
+ void setFantasyFontFamily(const AtomicString& family, const String& script, ExceptionState&);
+ void setPictographFontFamily(const AtomicString& family, const String& script, ExceptionState&);
void setDefaultVideoPosterURL(const String& url, ExceptionState&);
void setEditingBehavior(const String&, ExceptionState&);
void setImagesEnabled(bool, ExceptionState&);
void setMediaTypeOverride(const String& mediaType, ExceptionState&);
void setMockScrollbarsEnabled(bool, ExceptionState&);
- void setPasswordGenerationDecorationEnabled(bool, ExceptionState&);
void setTextAutosizingEnabled(bool, ExceptionState&);
void setAccessibilityFontScaleFactor(float fontScaleFactor, ExceptionState&);
void setTextAutosizingWindowSizeOverride(int width, int height, ExceptionState&);
- void setTouchEventEmulationEnabled(bool, ExceptionState&);
void setViewportEnabled(bool, ExceptionState&);
- // FIXME: This is a temporary flag and should be removed once accelerated
- // overflow scroll is ready (crbug.com/254111).
- void setCompositorDrivenAcceleratedScrollingEnabled(bool, ExceptionState&);
-
// FIXME: This is a temporary flag and should be removed once squashing is
// ready (crbug.com/261605).
void setLayerSquashingEnabled(bool, ExceptionState&);
@@ -114,19 +112,21 @@ public:
// be removed or moved onto internals.runtimeFlags:
void setAuthorShadowDOMForAnyElementEnabled(bool);
void setCSSExclusionsEnabled(bool);
- void setExperimentalWebSocketEnabled(bool);
void setLangAttributeAwareFormControlUIEnabled(bool);
void setOverlayScrollbarsEnabled(bool);
- void setStyleScopedEnabled(bool);
+ void setExperimentalContentSecurityPolicyFeaturesEnabled(bool);
+ void setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(bool);
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- explicit InternalSettings(Page*);
+ explicit InternalSettings(Page&);
Settings* settings() const;
Page* page() const { return m_page; }
static const char* supplementName();
- Page* m_page;
+ RawPtrWillBeWeakMember<Page> m_page;
Backup m_backup;
};
diff --git a/chromium/third_party/WebKit/Source/core/testing/InternalSettings.idl b/chromium/third_party/WebKit/Source/core/testing/InternalSettings.idl
index d4f598460ea..4120690ad81 100644
--- a/chromium/third_party/WebKit/Source/core/testing/InternalSettings.idl
+++ b/chromium/third_party/WebKit/Source/core/testing/InternalSettings.idl
@@ -24,11 +24,11 @@
*/
[
+ WillBeGarbageCollected,
] interface InternalSettings : InternalSettingsGenerated {
// All methods which access Page::settings() can raise an exception
// when the page cannot be accessed. (Such as during page tear-down.)
[RaisesException] void setMockScrollbarsEnabled(boolean enabled);
- [RaisesException] void setTouchEventEmulationEnabled(boolean enabled);
[RaisesException] void setStandardFontFamily(DOMString family, DOMString script);
[RaisesException] void setSerifFontFamily(DOMString family, DOMString script);
[RaisesException] void setSansSerifFontFamily(DOMString family, DOMString script);
@@ -41,15 +41,10 @@
[RaisesException] void setAccessibilityFontScaleFactor(float fontScaleFactor);
[RaisesException] void setMediaTypeOverride(DOMString mediaTypeOverride);
[RaisesException] void setEditingBehavior(DOMString behavior);
- [RaisesException] void setPasswordGenerationDecorationEnabled(boolean enabled);
[RaisesException] void setImagesEnabled(boolean enabled);
[RaisesException] void setDefaultVideoPosterURL(DOMString poster);
[RaisesException] void setViewportEnabled(boolean enabled);
- // FIXME: This is a temporary flag and should be removed once accelerated
- // overflow scroll is ready (crbug.com/254111).
- [RaisesException] void setCompositorDrivenAcceleratedScrollingEnabled(boolean enabled);
-
// FIXME: This is a temporary flag and should be removed once squashing is
// ready (crbug.com/261605).
[RaisesException] void setLayerSquashingEnabled(boolean enabled);
@@ -59,8 +54,8 @@
// be removed or moved onto internals.runtimeFlags:
void setAuthorShadowDOMForAnyElementEnabled(boolean enabled);
void setCSSExclusionsEnabled(boolean enabled);
- void setExperimentalWebSocketEnabled(boolean enabled);
void setLangAttributeAwareFormControlUIEnabled(boolean enabled);
void setOverlayScrollbarsEnabled(boolean enabled);
- void setStyleScopedEnabled(boolean enabled);
+ void setExperimentalContentSecurityPolicyFeaturesEnabled(boolean enabled);
+ void setPseudoClassesInMatchingCriteriaInAuthorShadowTreesEnabled(boolean enabled);
};
diff --git a/chromium/third_party/WebKit/Source/core/testing/Internals.cpp b/chromium/third_party/WebKit/Source/core/testing/Internals.cpp
index 5abaf92407e..4a05c1b4257 100644
--- a/chromium/third_party/WebKit/Source/core/testing/Internals.cpp
+++ b/chromium/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -25,24 +25,17 @@
*/
#include "config.h"
-#include "Internals.h"
+#include "core/testing/Internals.h"
-#include <v8.h>
-#include "HTMLNames.h"
-#include "InspectorFrontendClientLocal.h"
-#include "InternalProfilers.h"
-#include "InternalRuntimeFlags.h"
-#include "InternalSettings.h"
-#include "LayerRect.h"
-#include "LayerRectList.h"
-#include "MallocStatistics.h"
-#include "MockPagePopupDriver.h"
-#include "RuntimeEnabledFeatures.h"
-#include "TypeConversions.h"
+#include "bindings/v8/ExceptionMessages.h"
#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ScriptFunction.h"
+#include "bindings/v8/ScriptPromise.h"
+#include "bindings/v8/ScriptPromiseResolver.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "bindings/v8/V8ThrowException.h"
-#include "core/animation/DocumentTimeline.h"
+#include "core/InternalRuntimeFlags.h"
+#include "core/animation/AnimationTimeline.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/css/resolver/StyleResolverStats.h"
@@ -56,12 +49,12 @@
#include "core/dom/Element.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/FullscreenElementStack.h"
+#include "core/dom/NodeRenderStyle.h"
#include "core/dom/PseudoElement.h"
#include "core/dom/Range.h"
#include "core/dom/StaticNodeList.h"
#include "core/dom/TreeScope.h"
#include "core/dom/ViewportDescription.h"
-#include "core/dom/WheelController.h"
#include "core/dom/shadow/ComposedTreeWalker.h"
#include "core/dom/shadow/ElementShadow.h"
#include "core/dom/shadow/SelectRuleFeatureSet.h"
@@ -70,19 +63,25 @@
#include "core/editing/PlainTextRange.h"
#include "core/editing/SpellCheckRequester.h"
#include "core/editing/SpellChecker.h"
+#include "core/editing/SurroundingText.h"
#include "core/editing/TextIterator.h"
#include "core/fetch/MemoryCache.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/frame/DOMPoint.h"
-#include "core/frame/Frame.h"
-#include "core/history/HistoryItem.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/EventHandlerRegistry.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLContentElement.h"
#include "core/html/HTMLIFrameElement.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/HTMLSelectElement.h"
#include "core/html/HTMLTextAreaElement.h"
#include "core/html/forms/FormController.h"
-#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/shadow/ShadowElementNames.h"
+#include "core/html/shadow/TextControlInnerElements.h"
#include "core/inspector/InspectorClient.h"
#include "core/inspector/InspectorConsoleAgent.h"
#include "core/inspector/InspectorController.h"
@@ -92,67 +91,59 @@
#include "core/inspector/InspectorOverlay.h"
#include "core/inspector/InstrumentingAgents.h"
#include "core/loader/FrameLoader.h"
+#include "core/loader/HistoryItem.h"
#include "core/page/Chrome.h"
#include "core/page/ChromeClient.h"
-#include "core/frame/DOMWindow.h"
#include "core/page/EventHandler.h"
-#include "core/frame/FrameView.h"
+#include "core/page/FocusController.h"
+#include "core/page/NetworkStateNotifier.h"
#include "core/page/Page.h"
#include "core/page/PagePopupController.h"
#include "core/page/PrintContext.h"
-#include "core/frame/Settings.h"
-#include "core/frame/animation/AnimationController.h"
-#include "core/rendering/CompositedLayerMapping.h"
#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
#include "core/rendering/RenderMenuList.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderTreeAsText.h"
#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
#include "core/testing/GCObservation.h"
+#include "core/testing/InternalProfilers.h"
+#include "core/testing/InternalSettings.h"
+#include "core/testing/LayerRect.h"
+#include "core/testing/LayerRectList.h"
+#include "core/testing/MallocStatistics.h"
+#include "core/testing/MockPagePopupDriver.h"
+#include "core/testing/TypeConversions.h"
#include "core/workers/WorkerThread.h"
-#include "platform/ColorChooser.h"
#include "platform/Cursor.h"
#include "platform/Language.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/TraceEvent.h"
#include "platform/geometry/IntRect.h"
#include "platform/geometry/LayoutRect.h"
#include "platform/graphics/GraphicsLayer.h"
#include "platform/graphics/filters/FilterOperation.h"
#include "platform/graphics/filters/FilterOperations.h"
-#include "platform/graphics/gpu/SharedGraphicsContext3D.h"
#include "platform/weborigin/SchemeRegistry.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebConnectionType.h"
+#include "public/platform/WebGraphicsContext3D.h"
+#include "public/platform/WebGraphicsContext3DProvider.h"
#include "public/platform/WebLayer.h"
#include "wtf/InstanceCounter.h"
+#include "wtf/PassOwnPtr.h"
#include "wtf/dtoa.h"
#include "wtf/text/StringBuffer.h"
+#include <v8.h>
namespace WebCore {
+// FIXME: oilpan: These will be removed soon.
static MockPagePopupDriver* s_pagePopupDriver = 0;
using namespace HTMLNames;
-class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
-public:
- explicit InspectorFrontendChannelDummy(Page*);
- virtual ~InspectorFrontendChannelDummy() { }
- virtual bool sendMessageToFrontend(const String& message) OVERRIDE;
-
-private:
- Page* m_frontendPage;
-};
-
-InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
- : m_frontendPage(page)
-{
-}
-
-bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
-{
- return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
-}
-
static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
{
if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
@@ -178,9 +169,9 @@ static SpellCheckRequester* spellCheckRequester(Document* document)
const char* Internals::internalsId = "internals";
-PassRefPtr<Internals> Internals::create(Document* document)
+PassRefPtrWillBeRawPtr<Internals> Internals::create(Document* document)
{
- return adoptRef(new Internals(document));
+ return adoptRefWillBeNoop(new Internals(document));
}
Internals::~Internals()
@@ -194,27 +185,25 @@ void Internals::resetToConsistentState(Page* page)
page->setDeviceScaleFactor(1);
page->setIsCursorVisible(true);
page->setPageScaleFactor(1, IntPoint(0, 0));
- page->setPagination(Pagination());
TextRun::setAllowsRoundingHacks(false);
- WebCore::overrideUserPreferredLanguages(Vector<String>());
+ WebCore::overrideUserPreferredLanguages(Vector<AtomicString>());
delete s_pagePopupDriver;
s_pagePopupDriver = 0;
page->chrome().client().resetPagePopupDriver();
- if (!page->mainFrame()->spellChecker().isContinuousSpellCheckingEnabled())
- page->mainFrame()->spellChecker().toggleContinuousSpellChecking();
- if (page->mainFrame()->editor().isOverwriteModeEnabled())
- page->mainFrame()->editor().toggleOverwriteModeEnabled();
+ if (!page->deprecatedLocalMainFrame()->spellChecker().isContinuousSpellCheckingEnabled())
+ page->deprecatedLocalMainFrame()->spellChecker().toggleContinuousSpellChecking();
+ if (page->deprecatedLocalMainFrame()->editor().isOverwriteModeEnabled())
+ page->deprecatedLocalMainFrame()->editor().toggleOverwriteModeEnabled();
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
scrollingCoordinator->reset();
- page->mainFrame()->view()->clear();
+ page->deprecatedLocalMainFrame()->view()->clear();
}
Internals::Internals(Document* document)
: ContextLifecycleObserver(document)
, m_runtimeFlags(InternalRuntimeFlags::create())
- , m_scrollingCoordinator(document->page() ? document->page()->scrollingCoordinator() : 0)
{
}
@@ -223,7 +212,7 @@ Document* Internals::contextDocument() const
return toDocument(executionContext());
}
-Frame* Internals::frame() const
+LocalFrame* Internals::frame() const
{
if (!contextDocument())
return 0;
@@ -238,7 +227,7 @@ InternalSettings* Internals::settings() const
Page* page = document->page();
if (!page)
return 0;
- return InternalSettings::from(page);
+ return InternalSettings::from(*page);
}
InternalRuntimeFlags* Internals::runtimeFlags() const
@@ -266,13 +255,13 @@ String Internals::address(Node* node)
return String(buf);
}
-PassRefPtr<GCObservation> Internals::observeGC(ScriptValue scriptValue)
+PassRefPtrWillBeRawPtr<GCObservation> Internals::observeGC(ScriptValue scriptValue)
{
v8::Handle<v8::Value> observedValue = scriptValue.v8Value();
ASSERT(!observedValue.IsEmpty());
if (observedValue->IsNull() || observedValue->IsUndefined()) {
V8ThrowException::throwTypeError("value to observe is null or undefined", v8::Isolate::GetCurrent());
- return 0;
+ return nullptr;
}
return GCObservation::create(observedValue);
@@ -282,15 +271,30 @@ unsigned Internals::updateStyleAndReturnAffectedElementCount(ExceptionState& exc
{
Document* document = contextDocument();
if (!document) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
return 0;
}
unsigned beforeCount = document->styleEngine()->resolverAccessCount();
- document->updateStyleIfNeeded();
+ document->updateRenderTreeIfNeeded();
return document->styleEngine()->resolverAccessCount() - beforeCount;
}
+unsigned Internals::needsLayoutCount(ExceptionState& exceptionState) const
+{
+ LocalFrame* contextFrame = frame();
+ if (!contextFrame) {
+ exceptionState.throwDOMException(InvalidAccessError, "No context frame is available.");
+ return 0;
+ }
+
+ bool isPartial;
+ unsigned needsLayoutObjects;
+ unsigned totalObjects;
+ contextFrame->countObjectsNeedingLayout(needsLayoutObjects, totalObjects, isPartial);
+ return needsLayoutObjects;
+}
+
bool Internals::isPreloaded(const String& url)
{
Document* document = contextDocument();
@@ -339,71 +343,69 @@ String Internals::styleResolverStatsTotalsReport(ExceptionState& exceptionState)
return document->ensureStyleResolver().statsTotals()->report();
}
-PassRefPtr<Element> Internals::createContentElement(ExceptionState& exceptionState)
+bool Internals::isSharingStyle(Element* element1, Element* element2, ExceptionState& exceptionState) const
{
- Document* document = contextDocument();
- if (!document) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ if (!element1 || !element2) {
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(element1 ? 2 : 1, "Element"));
+ return false;
}
-
- return HTMLContentElement::create(*document);
+ return element1->renderStyle() == element2->renderStyle();
}
bool Internals::isValidContentSelect(Element* insertionPoint, ExceptionState& exceptionState)
{
if (!insertionPoint || !insertionPoint->isInsertionPoint()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "The insertion point provided is invalid.");
return false;
}
- return isHTMLContentElement(insertionPoint) && toHTMLContentElement(insertionPoint)->isSelectValid();
+ return isHTMLContentElement(*insertionPoint) && toHTMLContentElement(*insertionPoint).isSelectValid();
}
Node* Internals::treeScopeRootNode(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
- return node->treeScope().rootNode();
+ return &node->treeScope().rootNode();
}
Node* Internals::parentTreeScope(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
- return parentTreeScope ? parentTreeScope->rootNode() : 0;
+ return parentTreeScope ? &parentTreeScope->rootNode() : 0;
}
-bool Internals::hasSelectorForIdInShadow(Element* host, const String& idValue, ExceptionState& exceptionState)
+bool Internals::hasSelectorForIdInShadow(Element* host, const AtomicString& idValue, ExceptionState& exceptionState)
{
if (!host || !host->shadow()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid, or does not have a shadow.");
return 0;
}
return host->shadow()->ensureSelectFeatureSet().hasSelectorForId(idValue);
}
-bool Internals::hasSelectorForClassInShadow(Element* host, const String& className, ExceptionState& exceptionState)
+bool Internals::hasSelectorForClassInShadow(Element* host, const AtomicString& className, ExceptionState& exceptionState)
{
if (!host || !host->shadow()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid, or does not have a shadow.");
return 0;
}
return host->shadow()->ensureSelectFeatureSet().hasSelectorForClass(className);
}
-bool Internals::hasSelectorForAttributeInShadow(Element* host, const String& attributeName, ExceptionState& exceptionState)
+bool Internals::hasSelectorForAttributeInShadow(Element* host, const AtomicString& attributeName, ExceptionState& exceptionState)
{
if (!host || !host->shadow()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid, or does not have a shadow.");
return 0;
}
@@ -413,7 +415,7 @@ bool Internals::hasSelectorForAttributeInShadow(Element* host, const String& att
bool Internals::hasSelectorForPseudoClassInShadow(Element* host, const String& pseudoClass, ExceptionState& exceptionState)
{
if (!host || !host->shadow()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid, or does not have a shadow.");
return 0;
}
@@ -440,7 +442,7 @@ bool Internals::hasSelectorForPseudoClassInShadow(Element* host, const String& p
unsigned short Internals::compareTreeScopePosition(const Node* node1, const Node* node2, ExceptionState& exceptionState) const
{
if (!node1 || !node2) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(node1 ? 2 : 1, "Node"));
return 0;
}
const TreeScope* treeScope1 = node1->isDocumentNode() ? static_cast<const TreeScope*>(toDocument(node1)) :
@@ -448,7 +450,7 @@ unsigned short Internals::compareTreeScopePosition(const Node* node1, const Node
const TreeScope* treeScope2 = node2->isDocumentNode() ? static_cast<const TreeScope*>(toDocument(node2)) :
node2->isShadowRoot() ? static_cast<const TreeScope*>(toShadowRoot(node2)) : 0;
if (!treeScope1 || !treeScope2) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, String::format("The %s node is neither a document node, nor a shadow root.", treeScope1 ? "second" : "first"));
return 0;
}
return treeScope1->comparePosition(*treeScope2);
@@ -456,26 +458,20 @@ unsigned short Internals::compareTreeScopePosition(const Node* node1, const Node
unsigned Internals::numberOfActiveAnimations() const
{
- Frame* contextFrame = frame();
+ LocalFrame* contextFrame = frame();
Document* document = contextFrame->document();
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled())
- return document->timeline()->numberOfActiveAnimationsForTesting() + document->transitionTimeline()->numberOfActiveAnimationsForTesting();
- return contextFrame->animation().numberOfActiveAnimations(document);
+ return document->timeline().numberOfActiveAnimationsForTesting();
}
void Internals::pauseAnimations(double pauseTime, ExceptionState& exceptionState)
{
if (pauseTime < 0) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::indexExceedsMinimumBound("pauseTime", pauseTime, 0.0));
return;
}
- if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
- frame()->document()->timeline()->pauseAnimationsForTesting(pauseTime);
- frame()->document()->transitionTimeline()->pauseAnimationsForTesting(pauseTime);
- } else {
- frame()->animation().pauseAnimationsForTesting(pauseTime);
- }
+ frame()->view()->updateLayoutAndStyleForPainting();
+ frame()->document()->timeline().pauseAnimationsForTesting(pauseTime);
}
bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionState& exceptionState) const
@@ -483,7 +479,7 @@ bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionState& except
if (root && root->isShadowRoot())
return toShadowRoot(root)->containsShadowElements();
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
@@ -492,14 +488,14 @@ bool Internals::hasContentElement(const Node* root, ExceptionState& exceptionSta
if (root && root->isShadowRoot())
return toShadowRoot(root)->containsContentElements();
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
size_t Internals::countElementShadow(const Node* root, ExceptionState& exceptionState) const
{
if (!root || !root->isShadowRoot()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
return toShadowRoot(root)->childShadowRootCount();
@@ -508,7 +504,7 @@ size_t Internals::countElementShadow(const Node* root, ExceptionState& exception
Node* Internals::nextSiblingByWalker(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
ComposedTreeWalker walker(node);
@@ -519,7 +515,7 @@ Node* Internals::nextSiblingByWalker(Node* node, ExceptionState& exceptionState)
Node* Internals::firstChildByWalker(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
ComposedTreeWalker walker(node);
@@ -530,7 +526,7 @@ Node* Internals::firstChildByWalker(Node* node, ExceptionState& exceptionState)
Node* Internals::lastChildByWalker(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
ComposedTreeWalker walker(node);
@@ -541,7 +537,7 @@ Node* Internals::lastChildByWalker(Node* node, ExceptionState& exceptionState)
Node* Internals::nextNodeByWalker(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
ComposedTreeWalker walker(node);
@@ -552,7 +548,7 @@ Node* Internals::nextNodeByWalker(Node* node, ExceptionState& exceptionState)
Node* Internals::previousNodeByWalker(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
ComposedTreeWalker walker(node);
@@ -563,52 +559,30 @@ Node* Internals::previousNodeByWalker(Node* node, ExceptionState& exceptionState
String Internals::elementRenderTreeAsText(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return String();
}
String representation = externalRepresentation(element);
if (representation.isEmpty()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "The element provided has no external representation.");
return String();
}
return representation;
}
-size_t Internals::numberOfScopedHTMLStyleChildren(const Node* scope, ExceptionState& exceptionState) const
-{
- if (scope && (scope->isElementNode() || scope->isShadowRoot()))
- return scope->numberOfScopedHTMLStyleChildren();
-
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
-}
-
-PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionState& exceptionState) const
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+ return nullptr;
}
bool allowVisitedStyle = true;
return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
}
-ShadowRoot* Internals::ensureShadowRoot(Element* host, ExceptionState& exceptionState)
-{
- if (!host) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
- }
-
- if (ElementShadow* shadow = host->shadow())
- return shadow->youngestShadowRoot();
-
- return host->createShadowRoot(exceptionState).get();
-}
-
ShadowRoot* Internals::shadowRoot(Element* host, ExceptionState& exceptionState)
{
// FIXME: Internals::shadowRoot() in tests should be converted to youngestShadowRoot() or oldestShadowRoot().
@@ -619,7 +593,7 @@ ShadowRoot* Internals::shadowRoot(Element* host, ExceptionState& exceptionState)
ShadowRoot* Internals::youngestShadowRoot(Element* host, ExceptionState& exceptionState)
{
if (!host) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return 0;
}
@@ -631,7 +605,7 @@ ShadowRoot* Internals::youngestShadowRoot(Element* host, ExceptionState& excepti
ShadowRoot* Internals::oldestShadowRoot(Element* host, ExceptionState& exceptionState)
{
if (!host) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return 0;
}
@@ -643,27 +617,17 @@ ShadowRoot* Internals::oldestShadowRoot(Element* host, ExceptionState& exception
ShadowRoot* Internals::youngerShadowRoot(Node* shadow, ExceptionState& exceptionState)
{
if (!shadow || !shadow->isShadowRoot()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "The node provided is not a valid shadow root.");
return 0;
}
return toShadowRoot(shadow)->youngerShadowRoot();
}
-ShadowRoot* Internals::olderShadowRoot(Node* shadow, ExceptionState& exceptionState)
-{
- if (!shadow || !shadow->isShadowRoot()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
- }
-
- return toShadowRoot(shadow)->olderShadowRoot();
-}
-
String Internals::shadowRootType(const Node* root, ExceptionState& exceptionState) const
{
if (!root || !root->isShadowRoot()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "The node provided is not a valid shadow root.");
return String();
}
@@ -678,29 +642,29 @@ String Internals::shadowRootType(const Node* root, ExceptionState& exceptionStat
}
}
-String Internals::shadowPseudoId(Element* element, ExceptionState& exceptionState)
+const AtomicString& Internals::shadowPseudoId(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return String();
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
+ return nullAtom;
}
- return element->shadowPseudoId().string();
+ return element->shadowPseudoId();
}
-void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionState& exceptionState)
+void Internals::setShadowPseudoId(Element* element, const AtomicString& id, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return;
}
- return element->setPseudo(id);
+ return element->setShadowPseudoId(id);
}
String Internals::visiblePlaceholder(Element* element)
{
- if (element && isHTMLTextFormControlElement(element)) {
+ if (element && isHTMLTextFormControlElement(*element)) {
if (toHTMLTextFormControlElement(element)->placeholderShouldBeVisible())
return toHTMLTextFormControlElement(element)->placeholderElement()->textContent();
}
@@ -710,16 +674,32 @@ String Internals::visiblePlaceholder(Element* element)
void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
{
- if (!element->hasTagName(inputTag))
+ ASSERT(element);
+ if (!isHTMLInputElement(*element))
+ return;
+ Color color;
+ if (!color.setFromString(colorValue))
return;
- toHTMLInputElement(element)->selectColorInColorChooser(Color(colorValue));
+ toHTMLInputElement(*element).selectColorInColorChooser(color);
+}
+
+bool Internals::hasAutofocusRequest(Document* document)
+{
+ if (!document)
+ document = contextDocument();
+ return document->autofocusElement();
+}
+
+bool Internals::hasAutofocusRequest()
+{
+ return hasAutofocusRequest(0);
}
Vector<String> Internals::formControlStateOfHistoryItem(ExceptionState& exceptionState)
{
HistoryItem* mainItem = frame()->loader().currentItem();
if (!mainItem) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No history item is available.");
return Vector<String>();
}
return mainItem->documentState();
@@ -729,9 +709,10 @@ void Internals::setFormControlStateOfHistoryItem(const Vector<String>& state, Ex
{
HistoryItem* mainItem = frame()->loader().currentItem();
if (!mainItem) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No history item is available.");
return;
}
+ mainItem->clearDocumentState();
mainItem->setDocumentState(state);
}
@@ -746,41 +727,41 @@ void Internals::setEnableMockPagePopup(bool enabled, ExceptionState& exceptionSt
return;
}
if (!s_pagePopupDriver)
- s_pagePopupDriver = MockPagePopupDriver::create(page->mainFrame()).leakPtr();
+ s_pagePopupDriver = MockPagePopupDriver::create(page->deprecatedLocalMainFrame()).leakPtr();
page->chrome().client().setPagePopupDriver(s_pagePopupDriver);
}
-PassRefPtr<PagePopupController> Internals::pagePopupController()
+PassRefPtrWillBeRawPtr<PagePopupController> Internals::pagePopupController()
{
return s_pagePopupDriver ? s_pagePopupDriver->pagePopupController() : 0;
}
-PassRefPtr<ClientRect> Internals::unscaledViewportRect(ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ClientRect> Internals::unscaledViewportRect(ExceptionState& exceptionState)
{
Document* document = contextDocument();
if (!document || !document->view()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's viewport cannot be retrieved." : "No context document can be obtained.");
return ClientRect::create();
}
return ClientRect::create(document->view()->visibleContentRect());
}
-PassRefPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionState& exceptionState)
{
Document* document = contextDocument();
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "No context document can be obtained.");
return ClientRect::create();
}
return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
}
-PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return ClientRect::create();
}
@@ -791,47 +772,35 @@ PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionState&
return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
}
-PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(Document* document, ExceptionState& exceptionState)
-{
- if (!document || !document->page()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return ClientRectList::create();
- }
-
- Highlight highlight;
- document->page()->inspectorController().getHighlight(&highlight);
- return ClientRectList::create(highlight.quads);
-}
-
unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
DocumentMarker::MarkerTypes markerTypes = 0;
if (!markerTypesFrom(markerType, markerTypes)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The marker type provided ('" + markerType + "') is invalid.");
return 0;
}
- return node->document().markers()->markersFor(node, markerTypes).size();
+ return node->document().markers().markersFor(node, markerTypes).size();
}
unsigned Internals::activeMarkerCountForNode(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
// Only TextMatch markers can be active.
DocumentMarker::MarkerType markerType = DocumentMarker::TextMatch;
- Vector<DocumentMarker*> markers = node->document().markers()->markersFor(node, markerType);
+ WillBeHeapVector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerType);
unsigned activeMarkerCount = 0;
- for (Vector<DocumentMarker*>::iterator iter = markers.begin(); iter != markers.end(); ++iter) {
+ for (WillBeHeapVector<DocumentMarker*>::iterator iter = markers.begin(); iter != markers.end(); ++iter) {
if ((*iter)->activeMatch())
activeMarkerCount++;
}
@@ -842,27 +811,27 @@ unsigned Internals::activeMarkerCountForNode(Node* node, ExceptionState& excepti
DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return 0;
}
DocumentMarker::MarkerTypes markerTypes = 0;
if (!markerTypesFrom(markerType, markerTypes)) {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
+ exceptionState.throwDOMException(SyntaxError, "The marker type provided ('" + markerType + "') is invalid.");
return 0;
}
- Vector<DocumentMarker*> markers = node->document().markers()->markersFor(node, markerTypes);
+ WillBeHeapVector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
if (markers.size() <= index)
return 0;
return markers[index];
}
-PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
{
DocumentMarker* marker = markerAt(node, markerType, index, exceptionState);
if (!marker)
- return 0;
+ return nullptr;
return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
}
@@ -877,23 +846,31 @@ String Internals::markerDescriptionForNode(Node* node, const String& markerType,
void Internals::addTextMatchMarker(const Range* range, bool isActive)
{
range->ownerDocument().updateLayoutIgnorePendingStylesheets();
- range->ownerDocument().markers()->addTextMatchMarker(range, isActive);
+ range->ownerDocument().markers().addTextMatchMarker(range, isActive);
}
void Internals::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
return;
}
- node->document().markers()->setMarkersActive(node, startOffset, endOffset, active);
+ node->document().markers().setMarkersActive(node, startOffset, endOffset, active);
+}
+
+void Internals::setMarkedTextMatchesAreHighlighted(Document* document, bool highlight, ExceptionState&)
+{
+ if (!document || !document->frame())
+ return;
+
+ document->frame()->editor().setMarkedTextMatchesAreHighlighted(highlight);
}
void Internals::setScrollViewPosition(Document* document, long x, long y, ExceptionState& exceptionState)
{
if (!document || !document->view()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
return;
}
@@ -908,39 +885,10 @@ void Internals::setScrollViewPosition(Document* document, long x, long y, Except
frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
}
-void Internals::setPagination(Document* document, const String& mode, int gap, int pageLength, ExceptionState& exceptionState)
-{
- if (!document || !document->page()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return;
- }
- Page* page = document->page();
-
- Pagination pagination;
- if (mode == "Unpaginated")
- pagination.mode = Pagination::Unpaginated;
- else if (mode == "LeftToRightPaginated")
- pagination.mode = Pagination::LeftToRightPaginated;
- else if (mode == "RightToLeftPaginated")
- pagination.mode = Pagination::RightToLeftPaginated;
- else if (mode == "TopToBottomPaginated")
- pagination.mode = Pagination::TopToBottomPaginated;
- else if (mode == "BottomToTopPaginated")
- pagination.mode = Pagination::BottomToTopPaginated;
- else {
- exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
- return;
- }
-
- pagination.gap = gap;
- pagination.pageLength = pageLength;
- page->setPagination(pagination);
-}
-
String Internals::viewportAsText(Document* document, float, int availableWidth, int availableHeight, ExceptionState& exceptionState)
{
if (!document || !document->page()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's page cannot be retrieved." : "The document provided is invalid.");
return String();
}
@@ -950,10 +898,10 @@ String Internals::viewportAsText(Document* document, float, int availableWidth,
// Update initial viewport size.
IntSize initialViewportSize(availableWidth, availableHeight);
- document->page()->mainFrame()->view()->setFrameRect(IntRect(IntPoint::zero(), initialViewportSize));
+ document->page()->deprecatedLocalMainFrame()->view()->setFrameRect(IntRect(IntPoint::zero(), initialViewportSize));
ViewportDescription description = page->viewportDescription();
- PageScaleConstraints constraints = description.resolve(initialViewportSize);
+ PageScaleConstraints constraints = description.resolve(initialViewportSize, Length());
constraints.fitToContentsWidth(constraints.layoutSize.width(), availableWidth);
@@ -980,84 +928,100 @@ String Internals::viewportAsText(Document* document, float, int availableWidth,
bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionState& exceptionState)
{
if (!textField) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return false;
}
- if (textField->hasTagName(inputTag))
- return toHTMLInputElement(textField)->lastChangeWasUserEdit();
+ if (isHTMLInputElement(*textField))
+ return toHTMLInputElement(*textField).lastChangeWasUserEdit();
- // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
- if (textField->tagName() == "TEXTAREA")
- return toHTMLTextAreaElement(textField)->lastChangeWasUserEdit();
+ if (isHTMLTextAreaElement(*textField))
+ return toHTMLTextAreaElement(*textField).lastChangeWasUserEdit();
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a TEXTAREA.");
return false;
}
bool Internals::elementShouldAutoComplete(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return false;
}
- if (element->hasTagName(inputTag))
- return toHTMLInputElement(element)->shouldAutocomplete();
+ if (isHTMLInputElement(*element))
+ return toHTMLInputElement(*element).shouldAutocomplete();
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not an INPUT.");
return false;
}
String Internals::suggestedValue(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return String();
}
- if (!element->hasTagName(inputTag)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ if (!element->isFormControlElement()) {
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a form control element.");
return String();
}
- return toHTMLInputElement(element)->suggestedValue();
+ String suggestedValue;
+ if (isHTMLInputElement(*element))
+ suggestedValue = toHTMLInputElement(*element).suggestedValue();
+
+ if (isHTMLTextAreaElement(*element))
+ suggestedValue = toHTMLTextAreaElement(*element).suggestedValue();
+
+ if (isHTMLSelectElement(*element))
+ suggestedValue = toHTMLSelectElement(*element).suggestedValue();
+
+ return suggestedValue;
}
void Internals::setSuggestedValue(Element* element, const String& value, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return;
}
- if (!element->hasTagName(inputTag)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ if (!element->isFormControlElement()) {
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a form control element.");
return;
}
- toHTMLInputElement(element)->setSuggestedValue(value);
+ if (isHTMLInputElement(*element))
+ toHTMLInputElement(*element).setSuggestedValue(value);
+
+ if (isHTMLTextAreaElement(*element))
+ toHTMLTextAreaElement(*element).setSuggestedValue(value);
+
+ if (isHTMLSelectElement(*element))
+ toHTMLSelectElement(*element).setSuggestedValue(value);
}
void Internals::setEditingValue(Element* element, const String& value, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return;
}
- if (!element->hasTagName(inputTag)) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
+ if (!isHTMLInputElement(*element)) {
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not an INPUT.");
return;
}
- toHTMLInputElement(element)->setEditingValue(value);
+ toHTMLInputElement(*element).setEditingValue(value);
}
void Internals::setAutofilled(Element* element, bool enabled, ExceptionState& exceptionState)
{
if (!element->isFormControlElement()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a form control element.");
return;
}
toHTMLFormControlElement(element)->setAutofilled(enabled);
@@ -1066,29 +1030,18 @@ void Internals::setAutofilled(Element* element, bool enabled, ExceptionState& ex
void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionState& exceptionState)
{
if (!element || !element->document().view()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidNodeTypeError, element ? "No view can be obtained from the provided element's document." : ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return;
}
FrameView* frameView = element->document().view();
frameView->scrollElementToRect(element, IntRect(x, y, w, h));
}
-void Internals::paintControlTints(Document* document, ExceptionState& exceptionState)
-{
- if (!document || !document->view()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return;
- }
-
- FrameView* frameView = document->view();
- frameView->paintControlTints();
-}
-
-PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionState& exceptionState)
{
if (!scope) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
+ return nullptr;
}
// TextIterator depends on Layout information, make sure layout it up to date.
@@ -1100,7 +1053,7 @@ PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rang
unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionState& exceptionState)
{
if (!scope || !range) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(scope ? 2 : 1, scope ? "Range" : "Element"));
return 0;
}
@@ -1113,7 +1066,7 @@ unsigned Internals::locationFromRange(Element* scope, const Range* range, Except
unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionState& exceptionState)
{
if (!scope || !range) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(scope ? 2 : 1, scope ? "Range" : "Element"));
return 0;
}
@@ -1126,18 +1079,18 @@ unsigned Internals::lengthFromRange(Element* scope, const Range* range, Exceptio
String Internals::rangeAsText(const Range* range, ExceptionState& exceptionState)
{
if (!range) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Range"));
return String();
}
return range->text();
}
-PassRefPtr<DOMPoint> Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DOMPoint> Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
+ return nullptr;
}
document->updateLayout();
@@ -1152,13 +1105,13 @@ PassRefPtr<DOMPoint> Internals::touchPositionAdjustedToBestClickableNode(long x,
if (foundNode)
return DOMPoint::create(adjustedPoint.x(), adjustedPoint.y());
- return 0;
+ return nullptr;
}
Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
return 0;
}
@@ -1173,11 +1126,11 @@ Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width
return targetNode;
}
-PassRefPtr<DOMPoint> Internals::touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DOMPoint> Internals::touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
+ return nullptr;
}
document->updateLayout();
@@ -1198,7 +1151,7 @@ PassRefPtr<DOMPoint> Internals::touchPositionAdjustedToBestContextMenuNode(long
Node* Internals::touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
return 0;
}
@@ -1213,11 +1166,11 @@ Node* Internals::touchNodeAdjustedToBestContextMenuNode(long x, long y, long wid
return targetNode;
}
-PassRefPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
+ return nullptr;
}
document->updateLayout();
@@ -1231,7 +1184,7 @@ PassRefPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y,
if (foundNode)
return ClientRect::create(zoomableArea);
- return 0;
+ return nullptr;
}
@@ -1240,7 +1193,7 @@ int Internals::lastSpellCheckRequestSequence(Document* document, ExceptionState&
SpellCheckRequester* requester = spellCheckRequester(document);
if (!requester) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No spell check requestor can be obtained for the provided document.");
return -1;
}
@@ -1252,37 +1205,76 @@ int Internals::lastSpellCheckProcessedSequence(Document* document, ExceptionStat
SpellCheckRequester* requester = spellCheckRequester(document);
if (!requester) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No spell check requestor can be obtained for the provided document.");
return -1;
}
return requester->lastProcessedSequence();
}
-Vector<String> Internals::userPreferredLanguages() const
+Vector<AtomicString> Internals::userPreferredLanguages() const
{
return WebCore::userPreferredLanguages();
}
+// Optimally, the bindings generator would pass a Vector<AtomicString> here but
+// this is not supported yet.
void Internals::setUserPreferredLanguages(const Vector<String>& languages)
{
- WebCore::overrideUserPreferredLanguages(languages);
+ Vector<AtomicString> atomicLanguages;
+ for (size_t i = 0; i < languages.size(); ++i)
+ atomicLanguages.append(AtomicString(languages[i]));
+ WebCore::overrideUserPreferredLanguages(atomicLanguages);
+}
+
+unsigned Internals::activeDOMObjectCount(Document* document, ExceptionState& exceptionState)
+{
+ if (!document) {
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
+ return 0;
+ }
+
+ return document->activeDOMObjectCount();
+}
+
+static unsigned eventHandlerCount(Document& document, EventHandlerRegistry::EventHandlerClass handlerClass)
+{
+ if (!document.frameHost())
+ return 0;
+ EventHandlerRegistry* registry = &document.frameHost()->eventHandlerRegistry();
+ unsigned count = 0;
+ const EventTargetSet* targets = registry->eventHandlerTargets(handlerClass);
+ if (targets) {
+ for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter)
+ count += iter->value;
+ }
+ return count;
}
unsigned Internals::wheelEventHandlerCount(Document* document, ExceptionState& exceptionState)
{
if (!document) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
return 0;
}
- return WheelController::from(document)->wheelEventHandlerCount();
+ return eventHandlerCount(*document, EventHandlerRegistry::WheelEvent);
+}
+
+unsigned Internals::scrollEventHandlerCount(Document* document, ExceptionState& exceptionState)
+{
+ if (!document) {
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
+ return 0;
+ }
+
+ return eventHandlerCount(*document, EventHandlerRegistry::ScrollEvent);
}
unsigned Internals::touchEventHandlerCount(Document* document, ExceptionState& exceptionState)
{
if (!document) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
return 0;
}
@@ -1296,10 +1288,15 @@ unsigned Internals::touchEventHandlerCount(Document* document, ExceptionState& e
return count;
}
-static RenderLayer* findRenderLayerForGraphicsLayer(RenderLayer* searchRoot, GraphicsLayer* graphicsLayer, String* layerType)
+static RenderLayer* findRenderLayerForGraphicsLayer(RenderLayer* searchRoot, GraphicsLayer* graphicsLayer, IntSize* layerOffset, String* layerType)
{
- if (searchRoot->hasCompositedLayerMapping() && graphicsLayer == searchRoot->compositedLayerMapping()->mainGraphicsLayer())
+ *layerOffset = IntSize();
+ if (searchRoot->hasCompositedLayerMapping() && graphicsLayer == searchRoot->compositedLayerMapping()->mainGraphicsLayer()) {
+ CompositedLayerMappingPtr compositedLayerMapping = searchRoot->compositedLayerMapping();
+ LayoutSize offset = compositedLayerMapping->contentOffsetInCompositingLayer();
+ *layerOffset = IntSize(offset.width(), offset.height());
return searchRoot;
+ }
GraphicsLayer* layerForScrolling = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForScrolling() : 0;
if (graphicsLayer == layerForScrolling) {
@@ -1307,6 +1304,15 @@ static RenderLayer* findRenderLayerForGraphicsLayer(RenderLayer* searchRoot, Gra
return searchRoot;
}
+ if (searchRoot->compositingState() == PaintsIntoGroupedBacking) {
+ GraphicsLayer* squashingLayer = searchRoot->groupedMapping()->squashingLayer();
+ if (graphicsLayer == squashingLayer) {
+ *layerType ="squashing";
+ *layerOffset = -searchRoot->offsetFromSquashingLayerOrigin();
+ return searchRoot;
+ }
+ }
+
GraphicsLayer* layerForHorizontalScrollbar = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForHorizontalScrollbar() : 0;
if (graphicsLayer == layerForHorizontalScrollbar) {
*layerType = "horizontalScrollbar";
@@ -1325,8 +1331,10 @@ static RenderLayer* findRenderLayerForGraphicsLayer(RenderLayer* searchRoot, Gra
return searchRoot;
}
- for (RenderLayer* child = searchRoot->firstChild(); child; child = child->nextSibling()) {
- RenderLayer* foundLayer = findRenderLayerForGraphicsLayer(child, graphicsLayer, layerType);
+ // Search right to left to increase the chances that we'll choose the top-most layers in a
+ // grouped mapping for squashing.
+ for (RenderLayer* child = searchRoot->lastChild(); child; child = child->previousSibling()) {
+ RenderLayer* foundLayer = findRenderLayerForGraphicsLayer(child, graphicsLayer, layerOffset, layerType);
if (foundLayer)
return foundLayer;
}
@@ -1385,11 +1393,13 @@ static void accumulateLayerRectList(RenderLayerCompositor* compositor, GraphicsL
if (!layerRects.isEmpty()) {
mergeRects(layerRects);
String layerType;
- RenderLayer* renderLayer = findRenderLayerForGraphicsLayer(compositor->rootRenderLayer(), graphicsLayer, &layerType);
+ IntSize layerOffset;
+ RenderLayer* renderLayer = findRenderLayerForGraphicsLayer(compositor->rootRenderLayer(), graphicsLayer, &layerOffset, &layerType);
Node* node = renderLayer ? renderLayer->renderer()->node() : 0;
for (size_t i = 0; i < layerRects.size(); ++i) {
- if (!layerRects[i].isEmpty())
- rects->append(node, layerType, ClientRect::create(layerRects[i]));
+ if (!layerRects[i].isEmpty()) {
+ rects->append(node, layerType, layerOffset.width(), layerOffset.height(), ClientRect::create(layerRects[i]));
+ }
}
}
@@ -1398,46 +1408,46 @@ static void accumulateLayerRectList(RenderLayerCompositor* compositor, GraphicsL
accumulateLayerRectList(compositor, graphicsLayer->children()[i], rects);
}
-PassRefPtr<LayerRectList> Internals::touchEventTargetLayerRects(Document* document, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<LayerRectList> Internals::touchEventTargetLayerRects(Document* document, ExceptionState& exceptionState)
{
if (!document || !document->view() || !document->page() || document != contextDocument()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, "The document provided is invalid.");
+ return nullptr;
}
// Do any pending layout and compositing update (which may call touchEventTargetRectsChange) to ensure this
// really takes any previous changes into account.
forceCompositingUpdate(document, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
if (RenderView* view = document->renderView()) {
if (RenderLayerCompositor* compositor = view->compositor()) {
if (GraphicsLayer* rootLayer = compositor->rootGraphicsLayer()) {
- RefPtr<LayerRectList> rects = LayerRectList::create();
+ RefPtrWillBeRawPtr<LayerRectList> rects = LayerRectList::create();
accumulateLayerRectList(compositor, rootLayer, rects.get());
return rects;
}
}
}
- return 0;
+ return nullptr;
}
-PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
+PassRefPtrWillBeRawPtr<StaticNodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionState& exceptionState) const
{
if (!document || !document->frame() || !document->frame()->view()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, "No view can be obtained from the provided document.");
+ return nullptr;
}
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
FrameView* frameView = document->view();
RenderView* renderView = document->renderView();
if (!renderView)
- return 0;
+ return nullptr;
float zoomFactor = frame->pageZoomFactor();
LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
@@ -1454,9 +1464,9 @@ PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, i
// When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
- return 0;
+ return nullptr;
- Vector<RefPtr<Node> > matches;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > matches;
// Need padding to trigger a rect based hit test, but we want to return a NodeList
// so we special case this.
@@ -1547,45 +1557,6 @@ Vector<String> Internals::consoleMessageArgumentCounts(Document* document) const
return result;
}
-PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
-{
- Page* page = contextDocument()->frame()->page();
- ASSERT(page);
-
- DOMWindow* window = page->mainFrame()->domWindow();
- ASSERT(window);
-
- m_frontendWindow = window->open(url, "", "", window, window);
- ASSERT(m_frontendWindow);
-
- Page* frontendPage = m_frontendWindow->document()->page();
- ASSERT(frontendPage);
-
- OwnPtr<InspectorFrontendClientLocal> frontendClient = adoptPtr(new InspectorFrontendClientLocal(page->inspectorController(), frontendPage));
-
- frontendPage->inspectorController().setInspectorFrontendClient(frontendClient.release());
-
- m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
-
- page->inspectorController().connectFrontend(m_frontendChannel.get());
-
- return m_frontendWindow;
-}
-
-void Internals::closeDummyInspectorFrontend()
-{
- Page* page = contextDocument()->frame()->page();
- ASSERT(page);
- ASSERT(m_frontendWindow);
-
- page->inspectorController().disconnectFrontend();
-
- m_frontendChannel.release();
-
- m_frontendWindow->close(m_frontendWindow->executionContext());
- m_frontendWindow.release();
-}
-
Vector<unsigned long> Internals::setMemoryCacheCapacities(unsigned long minDeadBytes, unsigned long maxDeadBytes, unsigned long totalBytes)
{
Vector<unsigned long> result;
@@ -1600,7 +1571,7 @@ void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentS
{
Page* page = contextDocument()->frame()->page();
if (!page) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No page can be obtained from the current context document.");
return;
}
page->inspectorController().setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
@@ -1617,13 +1588,13 @@ bool Internals::hasGrammarMarker(Document* document, int from, int length, Excep
unsigned Internals::numberOfScrollableAreas(Document* document, ExceptionState&)
{
unsigned count = 0;
- Frame* frame = document->frame();
+ LocalFrame* frame = document->frame();
if (frame->view()->scrollableAreas())
count += frame->view()->scrollableAreas()->size();
for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
- if (child->view() && child->view()->scrollableAreas())
- count += child->view()->scrollableAreas()->size();
+ if (child->isLocalFrame() && toLocalFrame(child)->view() && toLocalFrame(child)->view()->scrollableAreas())
+ count += toLocalFrame(child)->view()->scrollableAreas()->size();
}
return count;
@@ -1632,7 +1603,7 @@ unsigned Internals::numberOfScrollableAreas(Document* document, ExceptionState&)
bool Internals::isPageBoxVisible(Document* document, int pageNumber, ExceptionState& exceptionState)
{
if (!document) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
return false;
}
@@ -1646,49 +1617,21 @@ String Internals::layerTreeAsText(Document* document, ExceptionState& exceptionS
String Internals::elementLayerTreeAsText(Element* element, ExceptionState& exceptionState) const
{
- return elementLayerTreeAsText(element, 0, exceptionState);
-}
-
-static PassRefPtr<NodeList> paintOrderList(Element* element, ExceptionState& exceptionState, RenderLayerStackingNode::PaintOrderListType type)
-{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
- }
-
- element->document().updateLayout();
-
- RenderObject* renderer = element->renderer();
- if (!renderer || !renderer->isBox()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
- }
-
- RenderLayer* layer = toRenderBox(renderer)->layer();
- if (!layer) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
+ return String();
}
- Vector<RefPtr<Node> > nodes;
- layer->stackingNode()->computePaintOrderList(type, nodes);
- return StaticNodeList::adopt(nodes);
-}
-
-PassRefPtr<NodeList> Internals::paintOrderListBeforePromote(Element* element, ExceptionState& exceptionState)
-{
- return paintOrderList(element, exceptionState, RenderLayerStackingNode::BeforePromote);
-}
+ FrameView* frameView = element->document().view();
+ frameView->updateLayoutAndStyleForPainting();
-PassRefPtr<NodeList> Internals::paintOrderListAfterPromote(Element* element, ExceptionState& exceptionState)
-{
- return paintOrderList(element, exceptionState, RenderLayerStackingNode::AfterPromote);
+ return elementLayerTreeAsText(element, 0, exceptionState);
}
bool Internals::scrollsWithRespectTo(Element* element1, Element* element2, ExceptionState& exceptionState)
{
if (!element1 || !element2) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, String::format("The %s element provided is invalid.", element1 ? "second" : "first"));
return 0;
}
@@ -1696,15 +1639,19 @@ bool Internals::scrollsWithRespectTo(Element* element1, Element* element2, Excep
RenderObject* renderer1 = element1->renderer();
RenderObject* renderer2 = element2->renderer();
- if (!renderer1 || !renderer2 || !renderer1->isBox() || !renderer2->isBox()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ if (!renderer1 || !renderer1->isBox()) {
+ exceptionState.throwDOMException(InvalidAccessError, renderer1 ? "The first provided element's renderer is not a box." : "The first provided element has no renderer.");
+ return 0;
+ }
+ if (!renderer2 || !renderer2->isBox()) {
+ exceptionState.throwDOMException(InvalidAccessError, renderer2 ? "The second provided element's renderer is not a box." : "The second provided element has no renderer.");
return 0;
}
RenderLayer* layer1 = toRenderBox(renderer1)->layer();
RenderLayer* layer2 = toRenderBox(renderer2)->layer();
if (!layer1 || !layer2) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, String::format("No render layer can be obtained from the %s provided element.", layer1 ? "second" : "first"));
return 0;
}
@@ -1714,65 +1661,49 @@ bool Internals::scrollsWithRespectTo(Element* element1, Element* element2, Excep
bool Internals::isUnclippedDescendant(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return 0;
}
- element->document().updateLayout();
+ element->document().view()->updateLayoutAndStyleForPainting();
RenderObject* renderer = element->renderer();
if (!renderer || !renderer->isBox()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, renderer ? "The provided element's renderer is not a box." : "The provided element has no renderer.");
return 0;
}
RenderLayer* layer = toRenderBox(renderer)->layer();
if (!layer) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No render layer can be obtained from the provided element.");
return 0;
}
- return layer->isUnclippedDescendant();
-}
-
-bool Internals::needsCompositedScrolling(Element* element, ExceptionState& exceptionState)
-{
- if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
- }
-
- element->document().updateLayout();
-
- RenderObject* renderer = element->renderer();
- if (!renderer || !renderer->isBox()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
- }
-
- RenderLayer* layer = toRenderBox(renderer)->layer();
- if (!layer) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
- }
+ // We used to compute isUnclippedDescendant only when acceleratedCompositingForOverflowScrollEnabled,
+ // but now we compute it all the time.
+ // FIXME: Remove this if statement and rebaseline the tests that make this assumption.
+ if (!layer->compositor()->acceleratedCompositingForOverflowScrollEnabled())
+ return false;
- return layer->needsCompositedScrolling();
+ return layer->compositingInputs().isUnclippedDescendant;
}
String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionState& exceptionState) const
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
return String();
}
+ document->view()->updateLayoutAndStyleForPainting();
+
return document->frame()->layerTreeAsText(flags);
}
String Internals::elementLayerTreeAsText(Element* element, unsigned flags, ExceptionState& exceptionState) const
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return String();
}
@@ -1780,7 +1711,7 @@ String Internals::elementLayerTreeAsText(Element* element, unsigned flags, Excep
RenderObject* renderer = element->renderer();
if (!renderer || !renderer->isBox()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, renderer ? "The provided element's renderer is not a box." : "The provided element has no renderer.");
return String();
}
@@ -1798,55 +1729,44 @@ String Internals::elementLayerTreeAsText(Element* element, unsigned flags, Excep
static RenderLayer* getRenderLayerForElement(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return 0;
}
RenderObject* renderer = element->renderer();
if (!renderer || !renderer->isBox()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, renderer ? "The provided element's renderer is not a box." : "The provided element has no renderer.");
return 0;
}
RenderLayer* layer = toRenderBox(renderer)->layer();
if (!layer) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No render layer can be obtained from the provided element.");
return 0;
}
return layer;
}
-void Internals::setNeedsCompositedScrolling(Element* element, unsigned needsCompositedScrolling, ExceptionState& exceptionState)
-{
- if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return;
- }
-
- element->document().updateLayout();
-
- if (RenderLayer* layer = getRenderLayerForElement(element, exceptionState))
- layer->scrollableArea()->setForceNeedsCompositedScrolling(static_cast<ForceNeedsCompositedScrollingMode>(needsCompositedScrolling));
-}
-
String Internals::repaintRectsAsText(Document* document, ExceptionState& exceptionState) const
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
return String();
}
return document->frame()->trackedRepaintRectsAsText();
}
-PassRefPtr<ClientRectList> Internals::repaintRects(Element* element, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<ClientRectList> Internals::repaintRects(Element* element, ExceptionState& exceptionState) const
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
+ return nullptr;
}
+ element->document().frame()->view()->updateLayoutAndStyleForPainting();
+
if (RenderLayer* layer = getRenderLayerForElement(element, exceptionState)) {
if (layer->compositingState() == PaintsIntoOwnBacking) {
OwnPtr<Vector<FloatRect> > rects = layer->collectTrackedRepaintRects();
@@ -1858,9 +1778,8 @@ PassRefPtr<ClientRectList> Internals::repaintRects(Element* element, ExceptionSt
}
}
- // It's an error to call this on an element that's not composited.
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, "The provided element is not composited.");
+ return nullptr;
}
String Internals::scrollingStateTreeAsText(Document* document, ExceptionState& exceptionState) const
@@ -1871,15 +1790,11 @@ String Internals::scrollingStateTreeAsText(Document* document, ExceptionState& e
String Internals::mainThreadScrollingReasons(Document* document, ExceptionState& exceptionState) const
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
return String();
}
- // Force a re-layout and a compositing update.
- document->updateLayout();
- RenderView* view = document->renderView();
- if (view->compositor())
- view->compositor()->updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
+ document->frame()->view()->updateLayoutAndStyleForPainting();
Page* page = document->page();
if (!page)
@@ -1888,16 +1803,16 @@ String Internals::mainThreadScrollingReasons(Document* document, ExceptionState&
return page->mainThreadScrollingReasonsAsText();
}
-PassRefPtr<ClientRectList> Internals::nonFastScrollableRects(Document* document, ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<ClientRectList> Internals::nonFastScrollableRects(Document* document, ExceptionState& exceptionState) const
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
+ return nullptr;
}
Page* page = document->page();
if (!page)
- return 0;
+ return nullptr;
return page->nonFastScrollableRects(document->frame());
}
@@ -1905,7 +1820,7 @@ PassRefPtr<ClientRectList> Internals::nonFastScrollableRects(Document* document,
void Internals::garbageCollectDocumentResources(Document* document, ExceptionState& exceptionState) const
{
if (!document) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
return;
}
ResourceFetcher* fetcher = document->fetcher();
@@ -1973,7 +1888,7 @@ int Internals::numberOfPages(float pageWidth, float pageHeight)
String Internals::pageProperty(String propertyName, int pageNumber, ExceptionState& exceptionState) const
{
if (!frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No frame is available.");
return String();
}
@@ -1983,7 +1898,7 @@ String Internals::pageProperty(String propertyName, int pageNumber, ExceptionSta
String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionState& exceptionState) const
{
if (!frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No frame is available.");
return String();
}
@@ -1994,7 +1909,7 @@ void Internals::setDeviceScaleFactor(float scaleFactor, ExceptionState& exceptio
{
Document* document = contextDocument();
if (!document || !document->page()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's page cannot be retrieved." : "No context document can be obtained.");
return;
}
Page* page = document->page();
@@ -2004,7 +1919,7 @@ void Internals::setDeviceScaleFactor(float scaleFactor, ExceptionState& exceptio
void Internals::setIsCursorVisible(Document* document, bool isVisible, ExceptionState& exceptionState)
{
if (!document || !document->page()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's page cannot be retrieved." : "No context document can be obtained.");
return;
}
document->page()->setIsCursorVisible(isVisible);
@@ -2014,28 +1929,33 @@ void Internals::webkitWillEnterFullScreenForElement(Document* document, Element*
{
if (!document)
return;
- FullscreenElementStack::from(document)->webkitWillEnterFullScreenForElement(element);
+ FullscreenElementStack::from(*document).webkitWillEnterFullScreenForElement(element);
}
void Internals::webkitDidEnterFullScreenForElement(Document* document, Element* element)
{
if (!document)
return;
- FullscreenElementStack::from(document)->webkitDidEnterFullScreenForElement(element);
+ FullscreenElementStack::from(*document).webkitDidEnterFullScreenForElement(element);
}
void Internals::webkitWillExitFullScreenForElement(Document* document, Element* element)
{
if (!document)
return;
- FullscreenElementStack::from(document)->webkitWillExitFullScreenForElement(element);
+ FullscreenElementStack::from(*document).webkitWillExitFullScreenForElement(element);
}
void Internals::webkitDidExitFullScreenForElement(Document* document, Element* element)
{
if (!document)
return;
- FullscreenElementStack::from(document)->webkitDidExitFullScreenForElement(element);
+ FullscreenElementStack::from(*document).webkitDidExitFullScreenForElement(element);
+}
+
+void Internals::mediaPlayerRequestFullscreen(HTMLMediaElement* mediaElement)
+{
+ mediaElement->mediaPlayerRequestFullscreen();
}
void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
@@ -2048,42 +1968,43 @@ void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const
SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
}
-PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
+PassRefPtrWillBeRawPtr<MallocStatistics> Internals::mallocStatistics() const
{
return MallocStatistics::create();
}
-PassRefPtr<TypeConversions> Internals::typeConversions() const
+PassRefPtrWillBeRawPtr<TypeConversions> Internals::typeConversions() const
{
return TypeConversions::create();
}
Vector<String> Internals::getReferencedFilePaths() const
{
- frame()->loader().saveDocumentAndScrollState();
- return FormController::getReferencedFilePaths(frame()->loader().currentItem()->documentState());
+ return frame()->loader().currentItem()->getReferencedFilePaths();
}
void Internals::startTrackingRepaints(Document* document, ExceptionState& exceptionState)
{
if (!document || !document->view()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
return;
}
FrameView* frameView = document->view();
- frameView->setTracksRepaints(true);
+ frameView->updateLayoutAndStyleForPainting();
+ frameView->setTracksPaintInvalidations(true);
}
void Internals::stopTrackingRepaints(Document* document, ExceptionState& exceptionState)
{
if (!document || !document->view()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
return;
}
FrameView* frameView = document->view();
- frameView->setTracksRepaints(false);
+ frameView->updateLayoutAndStyleForPainting();
+ frameView->setTracksPaintInvalidations(false);
}
void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionState& exceptionState)
@@ -2098,29 +2019,40 @@ void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node*
document = contextDocument();
} else if (node->isDocumentNode()) {
document = toDocument(node);
- } else if (node->hasTagName(HTMLNames::iframeTag)) {
- document = toHTMLIFrameElement(node)->contentDocument();
+ } else if (isHTMLIFrameElement(*node)) {
+ document = toHTMLIFrameElement(*node).contentDocument();
} else {
- exceptionState.throwUninformativeAndGenericDOMException(TypeError);
+ exceptionState.throwTypeError("The node provided is neither a document nor an IFrame.");
return;
}
document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
}
-PassRefPtr<ClientRectList> Internals::draggableRegions(Document* document, ExceptionState& exceptionState)
+void Internals::forceFullRepaint(Document* document, ExceptionState& exceptionState)
+{
+ if (!document || !document->view()) {
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
+ return;
+ }
+
+ if (RenderView *renderView = document->renderView())
+ renderView->repaintViewAndCompositedLayers();
+}
+
+PassRefPtrWillBeRawPtr<ClientRectList> Internals::draggableRegions(Document* document, ExceptionState& exceptionState)
{
return annotatedRegions(document, true, exceptionState);
}
-PassRefPtr<ClientRectList> Internals::nonDraggableRegions(Document* document, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ClientRectList> Internals::nonDraggableRegions(Document* document, ExceptionState& exceptionState)
{
return annotatedRegions(document, false, exceptionState);
}
-PassRefPtr<ClientRectList> Internals::annotatedRegions(Document* document, bool draggable, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ClientRectList> Internals::annotatedRegions(Document* document, bool draggable, ExceptionState& exceptionState)
{
if (!document || !document->view()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
return ClientRectList::create();
}
@@ -2192,7 +2124,7 @@ static const char* cursorTypeToString(Cursor::Type cursorType)
String Internals::getCurrentCursorInfo(Document* document, ExceptionState& exceptionState)
{
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
return String();
}
@@ -2240,12 +2172,12 @@ void Internals::forceReload(bool endToEnd)
frame()->loader().reload(endToEnd ? EndToEndReload : NormalReload);
}
-PassRefPtr<ClientRect> Internals::selectionBounds(ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<ClientRect> Internals::selectionBounds(ExceptionState& exceptionState)
{
Document* document = contextDocument();
if (!document || !document->frame()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
- return 0;
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "No context document can be obtained.");
+ return nullptr;
}
return ClientRect::create(document->frame()->selection().bounds());
@@ -2254,7 +2186,7 @@ PassRefPtr<ClientRect> Internals::selectionBounds(ExceptionState& exceptionState
String Internals::markerTextForListItem(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return String();
}
return WebCore::markerTextForListItem(element);
@@ -2263,7 +2195,7 @@ String Internals::markerTextForListItem(Element* element, ExceptionState& except
String Internals::getImageSourceURL(Element* element, ExceptionState& exceptionState)
{
if (!element) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
return String();
}
return element->imageSourceURL();
@@ -2272,7 +2204,7 @@ String Internals::getImageSourceURL(Element* element, ExceptionState& exceptionS
String Internals::baseURL(Document* document, ExceptionState& exceptionState)
{
if (!document) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
return String();
}
@@ -2281,13 +2213,14 @@ String Internals::baseURL(Document* document, ExceptionState& exceptionState)
bool Internals::isSelectPopupVisible(Node* node)
{
- if (!node->hasTagName(HTMLNames::selectTag))
+ ASSERT(node);
+ if (!isHTMLSelectElement(*node))
return false;
- HTMLSelectElement* select = toHTMLSelectElement(node);
+ HTMLSelectElement& select = toHTMLSelectElement(*node);
- RenderObject* renderer = select->renderer();
- if (!renderer->isMenuList())
+ RenderObject* renderer = select.renderer();
+ if (!renderer || !renderer->isMenuList())
return false;
RenderMenuList* menuList = toRenderMenuList(renderer);
@@ -2296,10 +2229,11 @@ bool Internals::isSelectPopupVisible(Node* node)
bool Internals::loseSharedGraphicsContext3D()
{
- RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get();
- if (!sharedContext)
+ OwnPtr<blink::WebGraphicsContext3DProvider> sharedProvider = adoptPtr(blink::Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
+ if (!sharedProvider)
return false;
- sharedContext->extensions()->loseContextCHROMIUM(Extensions3D::GUILTY_CONTEXT_RESET_ARB, Extensions3D::INNOCENT_CONTEXT_RESET_ARB);
+ blink::WebGraphicsContext3D* sharedContext = sharedProvider->context3d();
+ sharedContext->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_EXT, GL_INNOCENT_CONTEXT_RESET_EXT);
// To prevent tests that call loseSharedGraphicsContext3D from being
// flaky, we call finish so that the context is guaranteed to be lost
// synchronously (i.e. before returning).
@@ -2309,31 +2243,145 @@ bool Internals::loseSharedGraphicsContext3D()
void Internals::forceCompositingUpdate(Document* document, ExceptionState& exceptionState)
{
+ // Hit when running content_shell with --expose-internals-for-testing.
+ DisableCompositingQueryAsserts disabler;
+
if (!document || !document->renderView()) {
- exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
+ exceptionState.throwDOMException(InvalidAccessError, document ? "The document's render view cannot be retrieved." : "The document provided is invalid.");
return;
}
- document->updateLayout();
+ document->frame()->view()->updateLayoutAndStyleForPainting();
+}
- RenderView* view = document->renderView();
- if (view->compositor())
- view->compositor()->updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
+void Internals::setZoomFactor(float factor)
+{
+ frame()->setPageZoomFactor(factor);
}
-bool Internals::isCompositorFramePending(Document* document, ExceptionState& exceptionState)
+void Internals::setShouldRevealPassword(Element* element, bool reveal, ExceptionState& exceptionState)
{
- if (!document || !document->renderView()) {
- exceptionState.throwDOMException(InvalidAccessError, document ? "The document's render view cannot be retrieved." : "The document provided is invalid.");
+ if (!isHTMLInputElement(element)) {
+ exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
+ return;
+ }
+
+ return toHTMLInputElement(*element).setShouldRevealPassword(reveal);
+}
+
+namespace {
+
+class AddOneFunction : public ScriptFunction {
+public:
+ static PassOwnPtr<ScriptFunction> create(ExecutionContext* context)
+ {
+ return adoptPtr(new AddOneFunction(toIsolate(context)));
+ }
+
+private:
+ AddOneFunction(v8::Isolate* isolate)
+ : ScriptFunction(isolate)
+ {
+ }
+
+ virtual ScriptValue call(ScriptValue value) OVERRIDE
+ {
+ v8::Local<v8::Value> v8Value = value.v8Value();
+ ASSERT(v8Value->IsNumber());
+ int intValue = v8Value.As<v8::Integer>()->Value();
+ ScriptValue result = ScriptValue(ScriptState::current(isolate()), v8::Integer::New(isolate(), intValue + 1));
+ return result;
+ }
+};
+
+} // namespace
+
+ScriptPromise Internals::createPromise(ScriptState* scriptState)
+{
+ return ScriptPromiseResolver::create(scriptState)->promise();
+}
+
+ScriptPromise Internals::createResolvedPromise(ScriptState* scriptState, ScriptValue value)
+{
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ resolver->resolve(value);
+ return promise;
+}
+
+ScriptPromise Internals::createRejectedPromise(ScriptState* scriptState, ScriptValue value)
+{
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ resolver->reject(value);
+ return promise;
+}
+
+ScriptPromise Internals::addOneToPromise(ExecutionContext* context, ScriptPromise promise)
+{
+ return promise.then(AddOneFunction::create(context));
+}
+
+void Internals::trace(Visitor* visitor)
+{
+ visitor->trace(m_runtimeFlags);
+ visitor->trace(m_profilers);
+}
+
+void Internals::setValueForUser(Element* element, const String& value)
+{
+ toHTMLInputElement(element)->setValueForUser(value);
+}
+
+String Internals::textSurroundingNode(Node* node, int x, int y, unsigned long maxLength)
+{
+ if (!node)
+ return String();
+ blink::WebPoint point(x, y);
+ SurroundingText surroundingText(VisiblePosition(node->renderer()->positionForPoint(static_cast<IntPoint>(point))).deepEquivalent().parentAnchoredEquivalent(), maxLength);
+ return surroundingText.content();
+}
+
+void Internals::setFocused(bool focused)
+{
+ frame()->page()->focusController().setFocused(focused);
+}
+
+bool Internals::ignoreLayoutWithPendingStylesheets(Document* document, ExceptionState& exceptionState)
+{
+ if (!document) {
+ exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
return false;
}
- return document->page()->chrome().client().isCompositorFramePending();
+ return document->ignoreLayoutWithPendingStylesheets();
}
-void Internals::setZoomFactor(float factor)
+void Internals::setNetworkStateNotifierTestOnly(bool testOnly)
{
- frame()->setPageZoomFactor(factor);
+ networkStateNotifier().setTestUpdatesOnly(testOnly);
}
+void Internals::setNetworkConnectionInfo(const String& type, ExceptionState& exceptionState)
+{
+ blink::WebConnectionType webtype;
+ if (type == "cellular") {
+ webtype = blink::ConnectionTypeCellular;
+ } else if (type == "bluetooth") {
+ webtype = blink::ConnectionTypeBluetooth;
+ } else if (type == "ethernet") {
+ webtype = blink::ConnectionTypeEthernet;
+ } else if (type == "wifi") {
+ webtype = blink::ConnectionTypeWifi;
+ } else if (type == "other") {
+ webtype = blink::ConnectionTypeOther;
+ } else if (type == "none") {
+ webtype = blink::ConnectionTypeNone;
+ } else {
+ exceptionState.throwDOMException(NotFoundError, ExceptionMessages::failedToEnumerate("connection type", type));
+ return;
+ }
+ networkStateNotifier().setWebConnectionTypeForTest(webtype);
}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/testing/Internals.h b/chromium/third_party/WebKit/Source/core/testing/Internals.h
index 32c969a3d74..26ddb2497b9 100644
--- a/chromium/third_party/WebKit/Source/core/testing/Internals.h
+++ b/chromium/third_party/WebKit/Source/core/testing/Internals.h
@@ -28,11 +28,12 @@
#define Internals_h
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "bindings/v8/ScriptPromise.h"
#include "bindings/v8/ScriptValue.h"
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/dom/ContextLifecycleObserver.h"
-#include "core/dom/NodeList.h"
#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "platform/heap/Handle.h"
#include "wtf/ArrayBuffer.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -44,32 +45,32 @@ class ClientRect;
class ClientRectList;
class DOMPoint;
class DOMStringList;
-class DOMWindow;
+class LocalDOMWindow;
class Document;
class DocumentMarker;
class Element;
class ExceptionState;
-class Frame;
+class ExecutionContext;
class GCObservation;
-class InspectorFrontendChannelDummy;
+class HTMLMediaElement;
class InternalProfilers;
class InternalRuntimeFlags;
class InternalSettings;
class LayerRectList;
+class LocalFrame;
class MallocStatistics;
class Node;
class Page;
class PagePopupController;
class Range;
-class ExecutionContext;
class SerializedScriptValue;
+class StaticNodeList;
class ShadowRoot;
class TypeConversions;
-class Internals : public RefCounted<Internals>
- , public ContextLifecycleObserver {
+class Internals FINAL : public RefCountedWillBeGarbageCollectedFinalized<Internals>, public ContextLifecycleObserver {
public:
- static PassRefPtr<Internals> create(Document*);
+ static PassRefPtrWillBeRawPtr<Internals> create(Document*);
virtual ~Internals();
static void resetToConsistentState(Page*);
@@ -78,7 +79,7 @@ public:
String address(Node*);
- PassRefPtr<GCObservation> observeGC(ScriptValue);
+ PassRefPtrWillBeRawPtr<GCObservation> observeGC(ScriptValue);
bool isPreloaded(const String& url);
bool isLoadingFromMemoryCache(const String& url);
@@ -89,33 +90,31 @@ public:
String styleResolverStatsReport(ExceptionState&) const;
String styleResolverStatsTotalsReport(ExceptionState&) const;
- size_t numberOfScopedHTMLStyleChildren(const Node*, ExceptionState&) const;
- PassRefPtr<CSSComputedStyleDeclaration> computedStyleIncludingVisitedInfo(Node*, ExceptionState&) const;
+ bool isSharingStyle(Element*, Element*, ExceptionState&) const;
+
+ PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> computedStyleIncludingVisitedInfo(Node*, ExceptionState&) const;
- ShadowRoot* ensureShadowRoot(Element* host, ExceptionState&);
ShadowRoot* shadowRoot(Element* host, ExceptionState&);
ShadowRoot* youngestShadowRoot(Element* host, ExceptionState&);
ShadowRoot* oldestShadowRoot(Element* host, ExceptionState&);
ShadowRoot* youngerShadowRoot(Node* shadow, ExceptionState&);
- ShadowRoot* olderShadowRoot(Node* shadow, ExceptionState&);
String shadowRootType(const Node*, ExceptionState&) const;
bool hasShadowInsertionPoint(const Node*, ExceptionState&) const;
bool hasContentElement(const Node*, ExceptionState&) const;
size_t countElementShadow(const Node*, ExceptionState&) const;
- String shadowPseudoId(Element*, ExceptionState&);
- void setShadowPseudoId(Element*, const String&, ExceptionState&);
+ const AtomicString& shadowPseudoId(Element*, ExceptionState&);
+ void setShadowPseudoId(Element*, const AtomicString&, ExceptionState&);
// CSS Animation / Transition testing.
unsigned numberOfActiveAnimations() const;
void pauseAnimations(double pauseTime, ExceptionState&);
- PassRefPtr<Element> createContentElement(ExceptionState&);
bool isValidContentSelect(Element* insertionPoint, ExceptionState&);
Node* treeScopeRootNode(Node*, ExceptionState&);
Node* parentTreeScope(Node*, ExceptionState&);
- bool hasSelectorForIdInShadow(Element* host, const String& idValue, ExceptionState&);
- bool hasSelectorForClassInShadow(Element* host, const String& className, ExceptionState&);
- bool hasSelectorForAttributeInShadow(Element* host, const String& attributeName, ExceptionState&);
+ bool hasSelectorForIdInShadow(Element* host, const AtomicString& idValue, ExceptionState&);
+ bool hasSelectorForClassInShadow(Element* host, const AtomicString& className, ExceptionState&);
+ bool hasSelectorForAttributeInShadow(Element* host, const AtomicString& attributeName, ExceptionState&);
bool hasSelectorForPseudoClassInShadow(Element* host, const String& pseudoClass, ExceptionState&);
unsigned short compareTreeScopePosition(const Node*, const Node*, ExceptionState&) const;
@@ -127,67 +126,67 @@ public:
Node* previousNodeByWalker(Node*, ExceptionState&);
unsigned updateStyleAndReturnAffectedElementCount(ExceptionState&) const;
+ unsigned needsLayoutCount(ExceptionState&) const;
String visiblePlaceholder(Element*);
void selectColorInColorChooser(Element*, const String& colorValue);
+ bool hasAutofocusRequest(Document*);
+ bool hasAutofocusRequest();
Vector<String> formControlStateOfHistoryItem(ExceptionState&);
void setFormControlStateOfHistoryItem(const Vector<String>&, ExceptionState&);
void setEnableMockPagePopup(bool, ExceptionState&);
- PassRefPtr<PagePopupController> pagePopupController();
+ PassRefPtrWillBeRawPtr<PagePopupController> pagePopupController();
- PassRefPtr<ClientRect> unscaledViewportRect(ExceptionState&);
+ PassRefPtrWillBeRawPtr<ClientRect> unscaledViewportRect(ExceptionState&);
- PassRefPtr<ClientRect> absoluteCaretBounds(ExceptionState&);
+ PassRefPtrWillBeRawPtr<ClientRect> absoluteCaretBounds(ExceptionState&);
- PassRefPtr<ClientRect> boundingBox(Element*, ExceptionState&);
-
- PassRefPtr<ClientRectList> inspectorHighlightRects(Document*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<ClientRect> boundingBox(Element*, ExceptionState&);
unsigned markerCountForNode(Node*, const String&, ExceptionState&);
unsigned activeMarkerCountForNode(Node*, ExceptionState&);
- PassRefPtr<Range> markerRangeForNode(Node*, const String& markerType, unsigned index, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Range> markerRangeForNode(Node*, const String& markerType, unsigned index, ExceptionState&);
String markerDescriptionForNode(Node*, const String& markerType, unsigned index, ExceptionState&);
void addTextMatchMarker(const Range*, bool isActive);
void setMarkersActive(Node*, unsigned startOffset, unsigned endOffset, bool, ExceptionState&);
+ void setMarkedTextMatchesAreHighlighted(Document*, bool, ExceptionState&);
void setScrollViewPosition(Document*, long x, long y, ExceptionState&);
- void setPagination(Document* document, const String& mode, int gap, ExceptionState& ec) { setPagination(document, mode, gap, 0, ec); }
- void setPagination(Document*, const String& mode, int gap, int pageLength, ExceptionState&);
String viewportAsText(Document*, float devicePixelRatio, int availableWidth, int availableHeight, ExceptionState&);
bool wasLastChangeUserEdit(Element* textField, ExceptionState&);
bool elementShouldAutoComplete(Element* inputElement, ExceptionState&);
- String suggestedValue(Element* inputElement, ExceptionState&);
- void setSuggestedValue(Element* inputElement, const String&, ExceptionState&);
+ String suggestedValue(Element*, ExceptionState&);
+ void setSuggestedValue(Element*, const String&, ExceptionState&);
void setEditingValue(Element* inputElement, const String&, ExceptionState&);
void setAutofilled(Element*, bool enabled, ExceptionState&);
void scrollElementToRect(Element*, long x, long y, long w, long h, ExceptionState&);
- void paintControlTints(Document*, ExceptionState&);
-
- PassRefPtr<Range> rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionState&);
+ PassRefPtrWillBeRawPtr<Range> rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionState&);
unsigned locationFromRange(Element* scope, const Range*, ExceptionState&);
unsigned lengthFromRange(Element* scope, const Range*, ExceptionState&);
String rangeAsText(const Range*, ExceptionState&);
- PassRefPtr<DOMPoint> touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DOMPoint> touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document*, ExceptionState&);
Node* touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document*, ExceptionState&);
- PassRefPtr<DOMPoint> touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<DOMPoint> touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document*, ExceptionState&);
Node* touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document*, ExceptionState&);
- PassRefPtr<ClientRect> bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<ClientRect> bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document*, ExceptionState&);
int lastSpellCheckRequestSequence(Document*, ExceptionState&);
int lastSpellCheckProcessedSequence(Document*, ExceptionState&);
- Vector<String> userPreferredLanguages() const;
+ Vector<AtomicString> userPreferredLanguages() const;
void setUserPreferredLanguages(const Vector<String>&);
+ unsigned activeDOMObjectCount(Document*, ExceptionState&);
unsigned wheelEventHandlerCount(Document*, ExceptionState&);
+ unsigned scrollEventHandlerCount(Document*, ExceptionState&);
unsigned touchEventHandlerCount(Document*, ExceptionState&);
- PassRefPtr<LayerRectList> touchEventTargetLayerRects(Document*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<LayerRectList> touchEventTargetLayerRects(Document*, ExceptionState&);
// This is used to test rect based hit testing like what's done on touch screens.
- PassRefPtr<NodeList> nodesFromRect(Document*, int x, int y, unsigned topPadding, unsigned rightPadding,
+ PassRefPtrWillBeRawPtr<StaticNodeList> nodesFromRect(Document*, int x, int y, unsigned topPadding, unsigned rightPadding,
unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionState&) const;
void emitInspectorDidBeginFrame(int frameId = 0);
@@ -218,21 +217,15 @@ public:
String elementLayerTreeAsText(Element*, unsigned flags, ExceptionState&) const;
String elementLayerTreeAsText(Element*, ExceptionState&) const;
- PassRefPtr<NodeList> paintOrderListBeforePromote(Element*, ExceptionState&);
- PassRefPtr<NodeList> paintOrderListAfterPromote(Element*, ExceptionState&);
-
bool scrollsWithRespectTo(Element*, Element*, ExceptionState&);
bool isUnclippedDescendant(Element*, ExceptionState&);
- bool needsCompositedScrolling(Element*, ExceptionState&);
-
- void setNeedsCompositedScrolling(Element*, unsigned value, ExceptionState&);
String repaintRectsAsText(Document*, ExceptionState&) const;
- PassRefPtr<ClientRectList> repaintRects(Element*, ExceptionState&) const;
+ PassRefPtrWillBeRawPtr<ClientRectList> repaintRects(Element*, ExceptionState&) const;
String scrollingStateTreeAsText(Document*, ExceptionState&) const;
String mainThreadScrollingReasons(Document*, ExceptionState&) const;
- PassRefPtr<ClientRectList> nonFastScrollableRects(Document*, ExceptionState&) const;
+ PassRefPtrWillBeRawPtr<ClientRectList> nonFastScrollableRects(Document*, ExceptionState&) const;
void garbageCollectDocumentResources(Document*, ExceptionState&) const;
void evictAllResources() const;
@@ -243,7 +236,7 @@ public:
unsigned numberOfLiveDocuments() const;
String dumpRefCountedInstanceCounts() const;
Vector<String> consoleMessageArgumentCounts(Document*) const;
- PassRefPtr<DOMWindow> openDummyInspectorFrontend(const String& url);
+ PassRefPtrWillBeRawPtr<LocalDOMWindow> openDummyInspectorFrontend(const String& url);
void closeDummyInspectorFrontend();
Vector<unsigned long> setMemoryCacheCapacities(unsigned long minDeadBytes, unsigned long maxDeadBytes, unsigned long totalBytes);
void setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionState&);
@@ -267,11 +260,13 @@ public:
void webkitWillExitFullScreenForElement(Document*, Element*);
void webkitDidExitFullScreenForElement(Document*, Element*);
+ void mediaPlayerRequestFullscreen(HTMLMediaElement*);
+
void registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme);
void removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme);
- PassRefPtr<MallocStatistics> mallocStatistics() const;
- PassRefPtr<TypeConversions> typeConversions() const;
+ PassRefPtrWillBeRawPtr<MallocStatistics> mallocStatistics() const;
+ PassRefPtrWillBeRawPtr<TypeConversions> typeConversions() const;
Vector<String> getReferencedFilePaths() const;
@@ -279,9 +274,10 @@ public:
void stopTrackingRepaints(Document*, ExceptionState&);
void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionState&);
void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node*, ExceptionState&);
+ void forceFullRepaint(Document*, ExceptionState&);
- PassRefPtr<ClientRectList> draggableRegions(Document*, ExceptionState&);
- PassRefPtr<ClientRectList> nonDraggableRegions(Document*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<ClientRectList> draggableRegions(Document*, ExceptionState&);
+ PassRefPtrWillBeRawPtr<ClientRectList> nonDraggableRegions(Document*, ExceptionState&);
PassRefPtr<ArrayBuffer> serializeObject(PassRefPtr<SerializedScriptValue>) const;
PassRefPtr<SerializedScriptValue> deserializeBuffer(PassRefPtr<ArrayBuffer>) const;
@@ -296,30 +292,46 @@ public:
bool isSelectPopupVisible(Node*);
- PassRefPtr<ClientRect> selectionBounds(ExceptionState&);
+ PassRefPtrWillBeRawPtr<ClientRect> selectionBounds(ExceptionState&);
String baseURL(Document*, ExceptionState&);
bool loseSharedGraphicsContext3D();
void forceCompositingUpdate(Document*, ExceptionState&);
- bool isCompositorFramePending(Document*, ExceptionState&);
-
void setZoomFactor(float);
+ void setShouldRevealPassword(Element*, bool, ExceptionState&);
+
+ ScriptPromise createPromise(ScriptState*);
+ ScriptPromise createResolvedPromise(ScriptState*, ScriptValue);
+ ScriptPromise createRejectedPromise(ScriptState*, ScriptValue);
+ ScriptPromise addOneToPromise(ExecutionContext*, ScriptPromise);
+
+ void trace(Visitor*);
+
+ void setValueForUser(Element*, const String&);
+
+ String textSurroundingNode(Node*, int x, int y, unsigned long maxLength);
+
+ void setFocused(bool);
+
+ bool ignoreLayoutWithPendingStylesheets(Document*, ExceptionState&);
+
+ void setNetworkStateNotifierTestOnly(bool);
+ // Test must call setNetworkStateNotifierTestOnly(true) before calling setNetworkConnectionInfo.
+ void setNetworkConnectionInfo(const String&, ExceptionState&);
+
private:
explicit Internals(Document*);
Document* contextDocument() const;
- Frame* frame() const;
+ LocalFrame* frame() const;
Vector<String> iconURLs(Document*, int iconTypesMask) const;
- PassRefPtr<ClientRectList> annotatedRegions(Document*, bool draggable, ExceptionState&);
+ PassRefPtrWillBeRawPtr<ClientRectList> annotatedRegions(Document*, bool draggable, ExceptionState&);
DocumentMarker* markerAt(Node*, const String& markerType, unsigned index, ExceptionState&);
- RefPtr<DOMWindow> m_frontendWindow;
- OwnPtr<InspectorFrontendChannelDummy> m_frontendChannel;
- RefPtr<InternalRuntimeFlags> m_runtimeFlags;
- RefPtr<ScrollingCoordinator> m_scrollingCoordinator;
- RefPtr<InternalProfilers> m_profilers;
+ RefPtrWillBeMember<InternalRuntimeFlags> m_runtimeFlags;
+ RefPtrWillBeMember<InternalProfilers> m_profilers;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/testing/Internals.idl b/chromium/third_party/WebKit/Source/core/testing/Internals.idl
index be6087df535..daec6fd787c 100644
--- a/chromium/third_party/WebKit/Source/core/testing/Internals.idl
+++ b/chromium/third_party/WebKit/Source/core/testing/Internals.idl
@@ -25,7 +25,8 @@
*/
[
- DoNotCheckConstants
+ DoNotCheckConstants,
+ WillBeGarbageCollected,
] interface Internals {
DOMString address(Node node);
@@ -41,15 +42,14 @@
[RaisesException] DOMString styleResolverStatsReport();
[RaisesException] DOMString styleResolverStatsTotalsReport();
- [RaisesException] unsigned long numberOfScopedHTMLStyleChildren(Node scope);
+ [RaisesException] boolean isSharingStyle(Element element1, Element element2);
+
[RaisesException] CSSStyleDeclaration computedStyleIncludingVisitedInfo(Node node);
- [RaisesException] ShadowRoot ensureShadowRoot(Element host);
[RaisesException] ShadowRoot shadowRoot(Element host);
[RaisesException] ShadowRoot youngestShadowRoot(Element host);
[RaisesException] ShadowRoot oldestShadowRoot(Element host);
[RaisesException] ShadowRoot youngerShadowRoot(Node root);
- [RaisesException] ShadowRoot olderShadowRoot(Node root);
[RaisesException] DOMString shadowRootType(Node root);
[RaisesException] boolean hasShadowInsertionPoint(Node root);
@@ -57,7 +57,6 @@
[RaisesException] unsigned long countElementShadow(Node Root);
[RaisesException] DOMString shadowPseudoId(Element element);
[RaisesException] void setShadowPseudoId(Element element, DOMString id);
- [RaisesException] Element createContentElement();
[RaisesException] boolean isValidContentSelect(Element contentElement);
[RaisesException] Node treeScopeRootNode(Node node);
[RaisesException] Node parentTreeScope(Node node);
@@ -67,6 +66,7 @@
[RaisesException] boolean hasSelectorForPseudoClassInShadow(Element host, DOMString pseudoClass);
[RaisesException] unsigned short compareTreeScopePosition(Node treeScope1, Node treeScope2);
[RaisesException] unsigned long updateStyleAndReturnAffectedElementCount();
+ [RaisesException] unsigned long needsLayoutCount();
// CSS Animation and Transition testing.
unsigned long numberOfActiveAnimations();
@@ -82,6 +82,8 @@
void selectColorInColorChooser(Element element, DOMString colorValue);
+ // If the argument is omitted, the top-level document is used.
+ boolean hasAutofocusRequest(optional Document document);
[RaisesException] DOMString[] formControlStateOfHistoryItem();
[RaisesException] void setFormControlStateOfHistoryItem(sequence<DOMString> values);
[RaisesException] void setEnableMockPagePopup(boolean enabled);
@@ -93,19 +95,16 @@
[RaisesException] ClientRect boundingBox(Element element);
- [RaisesException] ClientRectList inspectorHighlightRects(Document document);
-
[RaisesException] unsigned long markerCountForNode(Node node, DOMString markerType);
[RaisesException] unsigned long activeMarkerCountForNode(Node node);
[RaisesException] Range markerRangeForNode(Node node, DOMString markerType, unsigned long index);
[RaisesException] DOMString markerDescriptionForNode(Node node, DOMString markerType, unsigned long index);
void addTextMatchMarker(Range range, boolean isActive);
[RaisesException] void setMarkersActive(Node node, unsigned long startOffset, unsigned long endOffset, boolean active);
+ [RaisesException] void setMarkedTextMatchesAreHighlighted(Document document, boolean highlight);
[RaisesException] void setScrollViewPosition(Document document, long x, long y);
- [RaisesException] void setPagination(Document document, DOMString mode, long gap, optional long pageLength);
-
[RaisesException] DOMString viewportAsText(Document document,
float devicePixelRatio,
long availableWidth,
@@ -118,8 +117,6 @@
[RaisesException] void setEditingValue(Element inputElement, DOMString value);
[RaisesException] void setAutofilled(Element inputElement, boolean enabled);
- [RaisesException] void paintControlTints(Document document);
-
[RaisesException] void scrollElementToRect(Element element, long x, long y, long w, long h);
[RaisesException] Range rangeFromLocationAndLength(Element scope, long rangeLocation, long rangeLength);
@@ -139,7 +136,9 @@
sequence<DOMString> userPreferredLanguages();
void setUserPreferredLanguages(sequence<DOMString> languages);
+ [RaisesException] unsigned long activeDOMObjectCount(Document document);
[RaisesException] unsigned long wheelEventHandlerCount(Document document);
+ [RaisesException] unsigned long scrollEventHandlerCount(Document document);
[RaisesException] unsigned long touchEventHandlerCount(Document document);
[RaisesException] LayerRectList touchEventTargetLayerRects(Document document);
@@ -176,18 +175,8 @@
[RaisesException] DOMString layerTreeAsText(Document document, optional unsigned short flags);
[RaisesException] DOMString elementLayerTreeAsText(Element element, optional unsigned short flags);
- [RaisesException] NodeList paintOrderListBeforePromote(Element element);
- [RaisesException] NodeList paintOrderListAfterPromote(Element element);
-
[RaisesException] boolean scrollsWithRespectTo(Element element1, Element element2);
[RaisesException] boolean isUnclippedDescendant(Element element);
- [RaisesException] boolean needsCompositedScrolling(Element element);
-
- // The values of these constants must be kept in sync with those in RenderLayer.
- const unsigned short DO_NOT_FORCE_COMPOSITED_SCROLLING = 0;
- const unsigned short COMPOSITED_SCROLLING_ALWAYS_ON = 1;
- const unsigned short COMPOSITED_SCROLLING_ALWAYS_OFF = 2;
- [RaisesException] void setNeedsCompositedScrolling(Element element, unsigned short value);
[RaisesException] DOMString scrollingStateTreeAsText(Document document);
[RaisesException] DOMString mainThreadScrollingReasons(Document document);
@@ -205,8 +194,6 @@
unsigned long numberOfLiveDocuments();
DOMString dumpRefCountedInstanceCounts();
sequence<DOMString> consoleMessageArgumentCounts(Document document);
- Window openDummyInspectorFrontend(DOMString url);
- void closeDummyInspectorFrontend();
unsigned long[] setMemoryCacheCapacities(unsigned long minDeadBytes, unsigned long maxDeadBytes, unsigned long totalBytes);
[RaisesException] void setInspectorResourcesDataSizeLimits(long maximumResourcesContentSize, long maximumSingleResourceContentSize);
@@ -227,6 +214,8 @@
void webkitWillExitFullScreenForElement(Document document, Element element);
void webkitDidExitFullScreenForElement(Document document, Element element);
+ void mediaPlayerRequestFullscreen(HTMLMediaElement mediaElement);
+
void registerURLSchemeAsBypassingContentSecurityPolicy(DOMString scheme);
void removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(DOMString scheme);
@@ -245,6 +234,8 @@
// specified without security checks. Unspecified means this document.
[RaisesException] void updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(optional Node node);
+ [RaisesException] void forceFullRepaint(Document document);
+
// Returns a list of draggable/non-draggable regions in the document.
[RaisesException] ClientRectList draggableRegions(Document document);
[RaisesException] ClientRectList nonDraggableRegions(Document document);
@@ -270,7 +261,26 @@
boolean loseSharedGraphicsContext3D();
[RaisesException] void forceCompositingUpdate(Document document);
- [RaisesException] boolean isCompositorFramePending(Document document);
void setZoomFactor(float factor);
+
+ [RaisesException] void setShouldRevealPassword(Element element, boolean reveal);
+
+ [CallWith=ScriptState] Promise createPromise();
+ [CallWith=ScriptState] Promise createResolvedPromise(any value);
+ [CallWith=ScriptState] Promise createRejectedPromise(any reason);
+ [CallWith=ExecutionContext] Promise addOneToPromise(Promise promise);
+
+ void setValueForUser(Element element, DOMString value);
+
+ DOMString textSurroundingNode(Node node, long x, long y, unsigned long maxLength);
+
+ void setFocused(boolean focused);
+
+ [RaisesException] boolean ignoreLayoutWithPendingStylesheets(Document document);
+
+ // These functions are for testing NetInfo. You must call setNetworkStateNotifierTestOnly(true)
+ // before calling setNetworkConnectionInfo.
+ void setNetworkStateNotifierTestOnly(boolean testOnly);
+ [RaisesException] void setNetworkConnectionInfo(DOMString type);
};
diff --git a/chromium/third_party/WebKit/Source/core/testing/LayerRect.h b/chromium/third_party/WebKit/Source/core/testing/LayerRect.h
index 4827feee4f2..1d007f4bc09 100644
--- a/chromium/third_party/WebKit/Source/core/testing/LayerRect.h
+++ b/chromium/third_party/WebKit/Source/core/testing/LayerRect.h
@@ -33,6 +33,7 @@
#include "core/dom/ClientRect.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -42,28 +43,40 @@ namespace WebCore {
class Node;
-class LayerRect : public RefCounted<LayerRect> {
+class LayerRect FINAL : public RefCountedWillBeGarbageCollectedFinalized<LayerRect> {
public:
- static PassRefPtr<LayerRect> create(PassRefPtr<Node> node, const String& layerType, PassRefPtr<ClientRect> rect)
+ static PassRefPtrWillBeRawPtr<LayerRect> create(PassRefPtrWillBeRawPtr<Node> node, const String& layerType, int nodeOffsetX, int nodeOffsetY, PassRefPtrWillBeRawPtr<ClientRect> rect)
{
- return adoptRef(new LayerRect(node, layerType, rect));
+ return adoptRefWillBeNoop(new LayerRect(node, layerType, nodeOffsetX, nodeOffsetY, rect));
}
- Node* layerRootNode() const { return m_layerRootNode.get(); }
+ Node* layerAssociatedNode() const { return m_layerAssociatedNode.get(); }
String layerType() const { return m_layerType; }
+ int associatedNodeOffsetX() const { return m_associatedNodeOffsetX; }
+ int associatedNodeOffsetY() const { return m_associatedNodeOffsetY; }
ClientRect* layerRelativeRect() const { return m_rect.get(); }
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_layerAssociatedNode);
+ visitor->trace(m_rect);
+ }
+
private:
- LayerRect(PassRefPtr<Node> node, const String& layerName, PassRefPtr<ClientRect> rect)
- : m_layerRootNode(node)
+ LayerRect(PassRefPtrWillBeRawPtr<Node> node, const String& layerName, int nodeOffsetX, int nodeOffsetY, PassRefPtrWillBeRawPtr<ClientRect> rect)
+ : m_layerAssociatedNode(node)
, m_layerType(layerName)
+ , m_associatedNodeOffsetX(nodeOffsetX)
+ , m_associatedNodeOffsetY(nodeOffsetY)
, m_rect(rect)
{
}
- RefPtr<Node> m_layerRootNode;
+ RefPtrWillBeMember<Node> m_layerAssociatedNode;
String m_layerType;
- RefPtr<ClientRect> m_rect;
+ int m_associatedNodeOffsetX;
+ int m_associatedNodeOffsetY;
+ RefPtrWillBeMember<ClientRect> m_rect;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/testing/LayerRect.idl b/chromium/third_party/WebKit/Source/core/testing/LayerRect.idl
index 8a4d8e17f18..effc2e66a8d 100644
--- a/chromium/third_party/WebKit/Source/core/testing/LayerRect.idl
+++ b/chromium/third_party/WebKit/Source/core/testing/LayerRect.idl
@@ -29,8 +29,17 @@
*/
[
+ WillBeGarbageCollected,
] interface LayerRect {
- readonly attribute Node layerRootNode;
+ /* The node that most closely represents the layer in which the rect
+ occurs. When a layer doesn't correspond directly to a node (eg.
+ for layer squashing) this will the node representing an ancestor
+ layer. */
+ readonly attribute Node layerAssociatedNode;
readonly attribute DOMString layerType;
+ /* Offset of the associated node from the GraphicsLayer */
+ readonly attribute long associatedNodeOffsetX;
+ readonly attribute long associatedNodeOffsetY;
+ /* Rectange in the GraphicsLayer co-ordinate space */
readonly attribute ClientRect layerRelativeRect;
};
diff --git a/chromium/third_party/WebKit/Source/core/testing/LayerRectList.cpp b/chromium/third_party/WebKit/Source/core/testing/LayerRectList.cpp
index 4e8b9911983..e95d273abf6 100644
--- a/chromium/third_party/WebKit/Source/core/testing/LayerRectList.cpp
+++ b/chromium/third_party/WebKit/Source/core/testing/LayerRectList.cpp
@@ -41,9 +41,7 @@ LayerRectList::LayerRectList()
{
}
-LayerRectList::~LayerRectList()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(LayerRectList)
unsigned LayerRectList::length() const
{
@@ -58,9 +56,14 @@ LayerRect* LayerRectList::item(unsigned index)
return m_list[index].get();
}
-void LayerRectList::append(PassRefPtr<Node> layerRootNode, const String& layerType, PassRefPtr<ClientRect> layerRelativeRect)
+void LayerRectList::append(PassRefPtrWillBeRawPtr<Node> layerRootNode, const String& layerType, int layerOffsetX, int layerOffsetY, PassRefPtrWillBeRawPtr<ClientRect> layerRelativeRect)
+{
+ m_list.append(LayerRect::create(layerRootNode, layerType, layerOffsetX, layerOffsetY, layerRelativeRect));
+}
+
+void LayerRectList::trace(Visitor* visitor)
{
- m_list.append(LayerRect::create(layerRootNode, layerType, layerRelativeRect));
+ visitor->trace(m_list);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/testing/LayerRectList.h b/chromium/third_party/WebKit/Source/core/testing/LayerRectList.h
index ec1582b8b99..9aa3518acdc 100644
--- a/chromium/third_party/WebKit/Source/core/testing/LayerRectList.h
+++ b/chromium/third_party/WebKit/Source/core/testing/LayerRectList.h
@@ -44,19 +44,24 @@ class ClientRectList;
class LayerRect;
class Node;
-class LayerRectList : public RefCounted<LayerRectList> {
+class LayerRectList FINAL : public RefCountedWillBeGarbageCollected<LayerRectList> {
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(LayerRectList);
public:
- static PassRefPtr<LayerRectList> create() { return adoptRef(new LayerRectList); }
- ~LayerRectList();
+ static PassRefPtrWillBeRawPtr<LayerRectList> create()
+ {
+ return adoptRefWillBeNoop(new LayerRectList);
+ }
unsigned length() const;
LayerRect* item(unsigned index);
- void append(PassRefPtr<Node> layerRootNode, const String& layerName, PassRefPtr<ClientRect> layerRelativeRect);
+ void append(PassRefPtrWillBeRawPtr<Node> layerAssociatedNode, const String& layerName, int layerOffsetX, int layerOffsetY, PassRefPtrWillBeRawPtr<ClientRect> layerRelativeRect);
+
+ void trace(Visitor*);
private:
LayerRectList();
- Vector<RefPtr<LayerRect> > m_list;
+ WillBeHeapVector<RefPtrWillBeMember<LayerRect> > m_list;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/testing/LayerRectList.idl b/chromium/third_party/WebKit/Source/core/testing/LayerRectList.idl
index 9dd2ca7fb17..ffe74d37cc7 100644
--- a/chromium/third_party/WebKit/Source/core/testing/LayerRectList.idl
+++ b/chromium/third_party/WebKit/Source/core/testing/LayerRectList.idl
@@ -29,8 +29,8 @@
*/
[
+ WillBeGarbageCollected,
] interface LayerRectList {
readonly attribute unsigned long length;
getter LayerRect item(unsigned long index);
};
-
diff --git a/chromium/third_party/WebKit/Source/core/testing/MallocStatistics.h b/chromium/third_party/WebKit/Source/core/testing/MallocStatistics.h
index bc4da8562ca..f697b0582c8 100644
--- a/chromium/third_party/WebKit/Source/core/testing/MallocStatistics.h
+++ b/chromium/third_party/WebKit/Source/core/testing/MallocStatistics.h
@@ -26,20 +26,26 @@
#ifndef MallocStatistics_h
#define MallocStatistics_h
+#include "platform/heap/Handle.h"
#include "wtf/FastMalloc.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class MallocStatistics : public RefCounted<MallocStatistics> {
+class MallocStatistics : public RefCountedWillBeGarbageCollected<MallocStatistics> {
public:
- static PassRefPtr<MallocStatistics> create() { return adoptRef(new MallocStatistics()); }
+ static PassRefPtrWillBeRawPtr<MallocStatistics> create()
+ {
+ return adoptRefWillBeNoop(new MallocStatistics());
+ }
size_t reservedVMBytes() const { return m_stats.reservedVMBytes; }
size_t committedVMBytes() const { return m_stats.committedVMBytes; }
size_t freeListBytes() const { return m_stats.freeListBytes; }
+ void trace(Visitor*) { }
+
private:
MallocStatistics()
{
diff --git a/chromium/third_party/WebKit/Source/core/testing/MallocStatistics.idl b/chromium/third_party/WebKit/Source/core/testing/MallocStatistics.idl
index dd3459b2135..5e969e978c7 100644
--- a/chromium/third_party/WebKit/Source/core/testing/MallocStatistics.idl
+++ b/chromium/third_party/WebKit/Source/core/testing/MallocStatistics.idl
@@ -24,6 +24,7 @@
*/
[
+ WillBeGarbageCollected,
] interface MallocStatistics {
readonly attribute unsigned long reservedVMBytes;
readonly attribute unsigned long committedVMBytes;
diff --git a/chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.cpp b/chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.cpp
index 56cc2482698..02d13e6bd29 100644
--- a/chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.cpp
+++ b/chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.cpp
@@ -24,16 +24,15 @@
*/
#include "config.h"
-#include "MockPagePopupDriver.h"
+#include "core/testing/MockPagePopupDriver.h"
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/CSSPropertyNames.h"
+#include "core/CSSValueKeywords.h"
+#include "core/frame/LocalFrame.h"
#include "core/html/HTMLIFrameElement.h"
-#include "core/loader/DocumentLoader.h"
-#include "core/loader/DocumentWriter.h"
+#include "core/loader/FrameLoadRequest.h"
#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
#include "core/page/PagePopup.h"
#include "core/page/PagePopupController.h"
#include "platform/Timer.h"
@@ -42,20 +41,21 @@ namespace WebCore {
class MockPagePopup : public PagePopup, public RefCounted<MockPagePopup> {
public:
- static PassRefPtr<MockPagePopup> create(PagePopupClient*, const IntRect& originBoundsInRootView, Frame*);
+ static PassRefPtr<MockPagePopup> create(PagePopupClient*, const IntRect& originBoundsInRootView, LocalFrame*);
virtual ~MockPagePopup();
+ bool initialize();
void closeLater();
private:
- MockPagePopup(PagePopupClient*, const IntRect& originBoundsInRootView, Frame*);
+ MockPagePopup(PagePopupClient*, const IntRect& originBoundsInRootView, LocalFrame*);
void close(Timer<MockPagePopup>*);
PagePopupClient* m_popupClient;
- RefPtr<HTMLIFrameElement> m_iframe;
+ RefPtrWillBePersistent<HTMLIFrameElement> m_iframe;
Timer<MockPagePopup> m_closeTimer;
};
-inline MockPagePopup::MockPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView, Frame* mainFrame)
+inline MockPagePopup::MockPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView, LocalFrame* mainFrame)
: m_popupClient(client)
, m_closeTimer(this, &MockPagePopup::close)
{
@@ -69,15 +69,21 @@ inline MockPagePopup::MockPagePopup(PagePopupClient* client, const IntRect& orig
m_iframe->setInlineStyleProperty(CSSPropertyTop, originBoundsInRootView.maxY(), CSSPrimitiveValue::CSS_PX, true);
if (document->body())
document->body()->appendChild(m_iframe.get());
- Frame* contentFrame = m_iframe->contentFrame();
- DocumentWriter* writer = contentFrame->loader().activeDocumentLoader()->beginWriting("text/html", "UTF-8");
+}
+
+bool MockPagePopup::initialize()
+{
const char scriptToSetUpPagePopupController[] = "<script>window.pagePopupController = parent.internals.pagePopupController;</script>";
- writer->addData(scriptToSetUpPagePopupController, sizeof(scriptToSetUpPagePopupController));
- m_popupClient->writeDocument(*writer);
- contentFrame->loader().activeDocumentLoader()->endWriting(writer);
+ RefPtr<SharedBuffer> data = SharedBuffer::create(scriptToSetUpPagePopupController, sizeof(scriptToSetUpPagePopupController));
+ m_popupClient->writeDocument(data.get());
+ LocalFrame* localFrame = toLocalFrame(m_iframe->contentFrame());
+ if (!localFrame)
+ return false;
+ localFrame->loader().load(FrameLoadRequest(0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad)));
+ return true;
}
-PassRefPtr<MockPagePopup> MockPagePopup::create(PagePopupClient* client, const IntRect& originBoundsInRootView, Frame* mainFrame)
+PassRefPtr<MockPagePopup> MockPagePopup::create(PagePopupClient* client, const IntRect& originBoundsInRootView, LocalFrame* mainFrame)
{
return adoptRef(new MockPagePopup(client, originBoundsInRootView, mainFrame));
}
@@ -89,7 +95,7 @@ void MockPagePopup::closeLater()
m_popupClient = 0;
// This can be called in detach(), and we should not change DOM structure
// during detach().
- m_closeTimer.startOneShot(0);
+ m_closeTimer.startOneShot(0, FROM_HERE);
}
void MockPagePopup::close(Timer<MockPagePopup>*)
@@ -103,12 +109,12 @@ MockPagePopup::~MockPagePopup()
m_iframe->parentNode()->removeChild(m_iframe.get());
}
-inline MockPagePopupDriver::MockPagePopupDriver(Frame* mainFrame)
+inline MockPagePopupDriver::MockPagePopupDriver(LocalFrame* mainFrame)
: m_mainFrame(mainFrame)
{
}
-PassOwnPtr<MockPagePopupDriver> MockPagePopupDriver::create(Frame* mainFrame)
+PassOwnPtr<MockPagePopupDriver> MockPagePopupDriver::create(LocalFrame* mainFrame)
{
return adoptPtr(new MockPagePopupDriver(mainFrame));
}
@@ -126,6 +132,10 @@ PagePopup* MockPagePopupDriver::openPagePopup(PagePopupClient* client, const Int
return 0;
m_pagePopupController = PagePopupController::create(client);
m_mockPagePopup = MockPagePopup::create(client, originBoundsInRootView, m_mainFrame);
+ if (!m_mockPagePopup->initialize()) {
+ m_mockPagePopup->closeLater();
+ m_mockPagePopup.clear();
+ }
return m_mockPagePopup.get();
}
diff --git a/chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.h b/chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.h
index e1f90aa54d0..7eb9baad884 100644
--- a/chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.h
+++ b/chromium/third_party/WebKit/Source/core/testing/MockPagePopupDriver.h
@@ -28,32 +28,33 @@
#include "core/page/PagePopupClient.h"
#include "core/page/PagePopupDriver.h"
+#include "platform/heap/Handle.h"
#include "wtf/RefPtr.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
class IntRect;
class MockPagePopup;
class PagePopup;
class PagePopupController;
-class MockPagePopupDriver : public PagePopupDriver {
+class MockPagePopupDriver FINAL : public PagePopupDriver {
public:
- static PassOwnPtr<MockPagePopupDriver> create(Frame* mainFrame);
+ static PassOwnPtr<MockPagePopupDriver> create(LocalFrame* mainFrame);
virtual ~MockPagePopupDriver();
PagePopupController* pagePopupController() { return m_pagePopupController.get(); }
private:
- MockPagePopupDriver(Frame* mainFrame);
+ MockPagePopupDriver(LocalFrame* mainFrame);
// PagePopupDriver functions:
virtual PagePopup* openPagePopup(PagePopupClient*, const IntRect& originBoundsInRootView) OVERRIDE;
virtual void closePagePopup(PagePopup*) OVERRIDE;
RefPtr<MockPagePopup> m_mockPagePopup;
- Frame* m_mainFrame;
- RefPtr<PagePopupController> m_pagePopupController;
+ LocalFrame* m_mainFrame;
+ RefPtrWillBePersistent<PagePopupController> m_pagePopupController;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp b/chromium/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
new file mode 100644
index 00000000000..b0f18f82d3e
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/testing/NullExecutionContext.cpp
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "core/testing/NullExecutionContext.h"
+
+namespace WebCore {
+
+namespace {
+
+class NullEventQueue FINAL : public EventQueue {
+public:
+ NullEventQueue() { }
+ virtual ~NullEventQueue() { }
+ virtual bool enqueueEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE { return true; }
+ virtual bool cancelEvent(Event*) OVERRIDE { return true; }
+ virtual void close() OVERRIDE { }
+};
+
+} // namespace
+
+NullExecutionContext::NullExecutionContext()
+ : m_tasksNeedSuspension(false)
+ , m_queue(adoptPtrWillBeNoop(new NullEventQueue()))
+{
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/testing/NullExecutionContext.h b/chromium/third_party/WebKit/Source/core/testing/NullExecutionContext.h
new file mode 100644
index 00000000000..bb239d49c95
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/testing/NullExecutionContext.h
@@ -0,0 +1,57 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NullExecutionContext_h
+#define NullExecutionContext_h
+
+#include "core/dom/ExecutionContext.h"
+#include "core/dom/SecurityContext.h"
+#include "core/events/EventQueue.h"
+#include "platform/heap/Handle.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class NullExecutionContext FINAL : public RefCountedWillBeGarbageCollectedFinalized<NullExecutionContext>, public SecurityContext, public ExecutionContext {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(NullExecutionContext);
+public:
+ NullExecutionContext();
+
+ virtual EventQueue* eventQueue() const OVERRIDE { return m_queue.get(); }
+
+ virtual bool tasksNeedSuspension() OVERRIDE { return m_tasksNeedSuspension; }
+ void setTasksNeedSuspension(bool flag) { m_tasksNeedSuspension = flag; }
+
+ void trace(Visitor* visitor)
+ {
+ visitor->trace(m_queue);
+ ExecutionContext::trace(visitor);
+ }
+
+ virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) OVERRIDE { }
+ virtual SecurityContext& securityContext() OVERRIDE { return *this; }
+
+#if !ENABLE(OILPAN)
+ using RefCounted<NullExecutionContext>::ref;
+ using RefCounted<NullExecutionContext>::deref;
+
+ virtual void refExecutionContext() OVERRIDE { ref(); }
+ virtual void derefExecutionContext() OVERRIDE { deref(); }
+#endif
+
+protected:
+ virtual const KURL& virtualURL() const OVERRIDE { return m_dummyURL; }
+ virtual KURL virtualCompleteURL(const String&) const OVERRIDE { return m_dummyURL; }
+
+private:
+ bool m_tasksNeedSuspension;
+ OwnPtrWillBeMember<EventQueue> m_queue;
+
+ KURL m_dummyURL;
+};
+
+} // namespace WebCore
+
+#endif // NullExecutionContext_h
diff --git a/chromium/third_party/WebKit/Source/core/testing/TypeConversions.h b/chromium/third_party/WebKit/Source/core/testing/TypeConversions.h
index 9a2625d0643..10bea391678 100644
--- a/chromium/third_party/WebKit/Source/core/testing/TypeConversions.h
+++ b/chromium/third_party/WebKit/Source/core/testing/TypeConversions.h
@@ -32,9 +32,12 @@
namespace WebCore {
-class TypeConversions : public RefCounted<TypeConversions> {
+class TypeConversions : public RefCountedWillBeGarbageCollectedFinalized<TypeConversions> {
public:
- static PassRefPtr<TypeConversions> create() { return adoptRef(new TypeConversions()); }
+ static PassRefPtrWillBeRawPtr<TypeConversions> create()
+ {
+ return adoptRefWillBeNoop(new TypeConversions());
+ }
long testLong() { return m_long; }
void setTestLong(long value) { m_long = value; }
@@ -56,6 +59,14 @@ public:
uint16_t testUnsignedShort() { return m_unsignedShort; }
void setTestUnsignedShort(uint16_t value) { m_unsignedShort = value; }
+ const String& testByteString() const { return m_byteString; }
+ void setTestByteString(const String& value) { m_byteString = value; }
+
+ const String& testScalarValueString() const { return m_scalarValueString; }
+ void setTestScalarValueString(const String& value) { m_scalarValueString = value; }
+
+ void trace(Visitor*) { }
+
private:
TypeConversions()
{
@@ -69,6 +80,8 @@ private:
uint8_t m_octet;
int16_t m_short;
uint16_t m_unsignedShort;
+ String m_byteString;
+ String m_scalarValueString;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/testing/TypeConversions.idl b/chromium/third_party/WebKit/Source/core/testing/TypeConversions.idl
index 7a70cc5d3fd..86dc3284b93 100644
--- a/chromium/third_party/WebKit/Source/core/testing/TypeConversions.idl
+++ b/chromium/third_party/WebKit/Source/core/testing/TypeConversions.idl
@@ -24,6 +24,7 @@
*/
[
+ WillBeGarbageCollected,
] interface TypeConversions {
attribute long testLong;
[EnforceRange, ImplementedAs=testLong] attribute long testEnforceRangeLong;
@@ -44,4 +45,20 @@
[EnforceRange, ImplementedAs=testShort] attribute short testEnforceRangeShort;
attribute unsigned short testUnsignedShort;
[EnforceRange, ImplementedAs=testUnsignedShort] attribute unsigned short testEnforceRangeUnsignedShort;
+
+ attribute ByteString testByteString;
+ [ImplementedAs=testByteString, TreatReturnedNullStringAs=Null] attribute ByteString testByteStringTreatReturnedNullStringAsNullAttribute;
+ [ImplementedAs=testByteString, TreatReturnedNullStringAs=Undefined] attribute ByteString testByteStringTreatReturnedNullStringAsUndefinedAttribute;
+ [ImplementedAs=testByteString, TreatReturnedNullStringAs=Null] ByteString getTestByteStringTreatReturnedNullStringAsNullMethod();
+ [ImplementedAs=testByteString, TreatReturnedNullStringAs=Undefined] ByteString getTestByteStringTreatReturnedNullStringAsUndefinedMethod();
+ void setTestByteString(ByteString byteString);
+ [ImplementedAs=setTestByteString] void setTestByteStringDefaultNull(optional ByteString byteString = null);
+
+ attribute ScalarValueString testScalarValueString;
+ [ImplementedAs=testScalarValueString, TreatReturnedNullStringAs=Null] attribute ScalarValueString testScalarValueStringTreatReturnedNullStringAsNullAttribute;
+ [ImplementedAs=testScalarValueString, TreatReturnedNullStringAs=Undefined] attribute ScalarValueString testScalarValueStringTreatReturnedNullStringAsUndefinedAttribute;
+ [ImplementedAs=testScalarValueString, TreatReturnedNullStringAs=Null] ScalarValueString getTestScalarValueStringTreatReturnedNullStringAsNullMethod();
+ [ImplementedAs=testScalarValueString, TreatReturnedNullStringAs=Undefined] ScalarValueString getTestScalarValueStringTreatReturnedNullStringAsUndefinedMethod();
+ void setTestScalarValueString(ScalarValueString scalarValueString);
+ [ImplementedAs=setTestScalarValueString] void setTestScalarValueStringDefaultNull(optional ScalarValueString scalarValueString = null);
};
diff --git a/chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp b/chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp
index f28fecbb2a4..4a99b093e85 100644
--- a/chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp
+++ b/chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.cpp
@@ -24,16 +24,14 @@
*/
#include "config.h"
-#include "WebCoreTestSupport.h"
+#include "core/testing/v8/WebCoreTestSupport.h"
-#include "InternalSettings.h"
-#include "Internals.h"
-#include "V8Internals.h"
+#include "bindings/core/v8/V8Internals.h"
#include "core/dom/Document.h"
#include "core/dom/ExecutionContext.h"
-#include "core/frame/Frame.h"
-
-#include <v8.h>
+#include "core/frame/LocalFrame.h"
+#include "core/testing/InternalSettings.h"
+#include "core/testing/Internals.h"
using namespace WebCore;
@@ -41,11 +39,12 @@ namespace WebCoreTestSupport {
void injectInternalsObject(v8::Local<v8::Context> context)
{
- v8::Context::Scope contextScope(context);
- v8::HandleScope scope(context->GetIsolate());
- ExecutionContext* scriptContext = getExecutionContext();
- if (scriptContext->isDocument())
- context->Global()->Set(v8::String::NewFromUtf8(context->GetIsolate(), Internals::internalsId), toV8(Internals::create(toDocument(scriptContext)), v8::Handle<v8::Object>(), context->GetIsolate()));
+ ScriptState* scriptState = ScriptState::from(context);
+ ScriptState::Scope scope(scriptState);
+ v8::Handle<v8::Object> global = scriptState->context()->Global();
+ ExecutionContext* executionContext = scriptState->executionContext();
+ if (executionContext->isDocument())
+ global->Set(v8::String::NewFromUtf8(scriptState->isolate(), Internals::internalsId), toV8(Internals::create(toDocument(executionContext)), global, scriptState->isolate()));
}
void resetInternalsObject(v8::Local<v8::Context> context)
@@ -54,13 +53,12 @@ void resetInternalsObject(v8::Local<v8::Context> context)
if (context.IsEmpty())
return;
- v8::Context::Scope contextScope(context);
- v8::HandleScope scope(context->GetIsolate());
-
- ExecutionContext* scriptContext = getExecutionContext();
- Page* page = toDocument(scriptContext)->frame()->page();
+ ScriptState* scriptState = ScriptState::from(context);
+ ScriptState::Scope scope(scriptState);
+ Page* page = toDocument(scriptState->executionContext())->frame()->page();
+ ASSERT(page);
Internals::resetToConsistentState(page);
- InternalSettings::from(page)->resetToConsistentState();
+ InternalSettings::from(*page)->resetToConsistentState();
}
}
diff --git a/chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.h b/chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.h
index 1ff2d767846..e6bce4aa02e 100644
--- a/chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.h
+++ b/chromium/third_party/WebKit/Source/core/testing/v8/WebCoreTestSupport.h
@@ -26,13 +26,16 @@
#ifndef WebCoreTestSupport_h
#define WebCoreTestSupport_h
+// Normally we'd have:
+// #include <v8.h>
+// ...but this file is used in cases where we don't have V8 (e.g., Skia)
namespace v8 {
class Context;
template <class T> class Local;
}
namespace WebCore {
-class Frame;
+class LocalFrame;
class PagePopupController;
}
diff --git a/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.cpp b/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.cpp
index 3bb082123a1..6c804cc6708 100644
--- a/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.cpp
+++ b/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.cpp
@@ -31,16 +31,16 @@
#include "config.h"
#include "core/timing/MemoryInfo.h"
-#include <limits>
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/CurrentTime.h"
#include "wtf/MainThread.h"
#include "wtf/MathExtras.h"
+#include <limits>
namespace WebCore {
-
class HeapSizeCache {
WTF_MAKE_NONCOPYABLE(HeapSizeCache); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -91,7 +91,6 @@ size_t quantizeMemorySize(size_t size)
const int numberOfBuckets = 100;
DEFINE_STATIC_LOCAL(Vector<size_t>, bucketSizeList, ());
- ASSERT(isMainThread());
if (bucketSizeList.isEmpty()) {
bucketSizeList.resize(numberOfBuckets);
@@ -131,14 +130,11 @@ size_t quantizeMemorySize(size_t size)
return bucketSizeList[numberOfBuckets - 1];
}
-
-MemoryInfo::MemoryInfo(Frame* frame)
+MemoryInfo::MemoryInfo()
{
ScriptWrappable::init(this);
- if (!frame || !frame->settings())
- return;
- if (frame->settings()->memoryInfoEnabled()) {
+ if (RuntimeEnabledFeatures::preciseMemoryInfoEnabled()) {
ScriptGCEvent::getHeapSize(m_info);
} else {
DEFINE_STATIC_LOCAL(HeapSizeCache, heapSizeCache, ());
diff --git a/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.h b/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.h
index 59629a44dc8..32678d533f9 100644
--- a/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.h
+++ b/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.h
@@ -33,23 +33,27 @@
#include "bindings/v8/ScriptGCEvent.h"
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class Frame;
-
-class MemoryInfo : public RefCounted<MemoryInfo>, public ScriptWrappable {
+class MemoryInfo : public RefCountedWillBeGarbageCollectedFinalized<MemoryInfo>, public ScriptWrappable {
public:
- static PassRefPtr<MemoryInfo> create(Frame* frame) { return adoptRef(new MemoryInfo(frame)); }
+ static PassRefPtrWillBeRawPtr<MemoryInfo> create()
+ {
+ return adoptRefWillBeNoop(new MemoryInfo());
+ }
size_t totalJSHeapSize() const { return m_info.totalJSHeapSize; }
size_t usedJSHeapSize() const { return m_info.usedJSHeapSize; }
size_t jsHeapSizeLimit() const { return m_info.jsHeapSizeLimit; }
+ void trace(Visitor*) { }
+
private:
- explicit MemoryInfo(Frame*);
+ MemoryInfo();
HeapInfo m_info;
};
diff --git a/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.idl b/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.idl
index 30ac718a67a..552f17584d9 100644
--- a/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.idl
+++ b/chromium/third_party/WebKit/Source/core/timing/MemoryInfo.idl
@@ -29,6 +29,7 @@
*/
[
+ WillBeGarbageCollected,
NoInterfaceObject
] interface MemoryInfo {
diff --git a/chromium/third_party/WebKit/Source/core/timing/Performance.cpp b/chromium/third_party/WebKit/Source/core/timing/Performance.cpp
index e441579b930..318553900de 100644
--- a/chromium/third_party/WebKit/Source/core/timing/Performance.cpp
+++ b/chromium/third_party/WebKit/Source/core/timing/Performance.cpp
@@ -33,6 +33,7 @@
#include "core/timing/Performance.h"
#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoader.h"
#include "core/timing/ResourceTimingInfo.h"
#include "core/timing/PerformanceResourceTiming.h"
@@ -40,19 +41,16 @@
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/CurrentTime.h"
-#include "core/frame/Frame.h"
-
namespace WebCore {
static const size_t defaultResourceTimingBufferSize = 150;
-Performance::Performance(Frame* frame)
+Performance::Performance(LocalFrame* frame)
: DOMWindowProperty(frame)
, m_resourceTimingBufferSize(defaultResourceTimingBufferSize)
- , m_referenceTime(frame->document()->loader()->timing()->referenceMonotonicTime())
- , m_userTiming(0)
+ , m_referenceTime(frame && frame->host() ? frame->document()->loader()->timing()->referenceMonotonicTime() : 0.0)
+ , m_userTiming(nullptr)
{
- ASSERT(m_referenceTime);
ScriptWrappable::init(this);
}
@@ -72,9 +70,9 @@ ExecutionContext* Performance::executionContext() const
return frame()->document();
}
-PassRefPtr<MemoryInfo> Performance::memory() const
+PassRefPtrWillBeRawPtr<MemoryInfo> Performance::memory() const
{
- return MemoryInfo::create(m_frame);
+ return MemoryInfo::create();
}
PerformanceNavigation* Performance::navigation() const
@@ -93,54 +91,54 @@ PerformanceTiming* Performance::timing() const
return m_timing.get();
}
-Vector<RefPtr<PerformanceEntry> > Performance::getEntries() const
+PerformanceEntryVector Performance::getEntries() const
{
- Vector<RefPtr<PerformanceEntry> > entries;
+ PerformanceEntryVector entries;
- entries.append(m_resourceTimingBuffer);
+ entries.appendVector(m_resourceTimingBuffer);
if (m_userTiming) {
- entries.append(m_userTiming->getMarks());
- entries.append(m_userTiming->getMeasures());
+ entries.appendVector(m_userTiming->getMarks());
+ entries.appendVector(m_userTiming->getMeasures());
}
std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompareLessThan);
return entries;
}
-Vector<RefPtr<PerformanceEntry> > Performance::getEntriesByType(const String& entryType)
+PerformanceEntryVector Performance::getEntriesByType(const String& entryType)
{
- Vector<RefPtr<PerformanceEntry> > entries;
+ PerformanceEntryVector entries;
if (equalIgnoringCase(entryType, "resource"))
- for (Vector<RefPtr<PerformanceEntry> >::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
+ for (PerformanceEntryVector::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
entries.append(*resource);
if (m_userTiming) {
if (equalIgnoringCase(entryType, "mark"))
- entries.append(m_userTiming->getMarks());
+ entries.appendVector(m_userTiming->getMarks());
else if (equalIgnoringCase(entryType, "measure"))
- entries.append(m_userTiming->getMeasures());
+ entries.appendVector(m_userTiming->getMeasures());
}
std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompareLessThan);
return entries;
}
-Vector<RefPtr<PerformanceEntry> > Performance::getEntriesByName(const String& name, const String& entryType)
+PerformanceEntryVector Performance::getEntriesByName(const String& name, const String& entryType)
{
- Vector<RefPtr<PerformanceEntry> > entries;
+ PerformanceEntryVector entries;
if (entryType.isNull() || equalIgnoringCase(entryType, "resource"))
- for (Vector<RefPtr<PerformanceEntry> >::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
+ for (PerformanceEntryVector::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
if ((*resource)->name() == name)
entries.append(*resource);
if (m_userTiming) {
if (entryType.isNull() || equalIgnoringCase(entryType, "mark"))
- entries.append(m_userTiming->getMarks(name));
+ entries.appendVector(m_userTiming->getMarks(name));
if (entryType.isNull() || equalIgnoringCase(entryType, "measure"))
- entries.append(m_userTiming->getMeasures(name));
+ entries.appendVector(m_userTiming->getMeasures(name));
}
std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompareLessThan);
@@ -159,7 +157,7 @@ void Performance::webkitSetResourceTimingBufferSize(unsigned size)
dispatchEvent(Event::create(EventTypeNames::webkitresourcetimingbufferfull));
}
-static bool passesTimingAllowCheck(const ResourceResponse& response, Document* requestingDocument)
+static bool passesTimingAllowCheck(const ResourceResponse& response, Document* requestingDocument, const AtomicString& originalTimingAllowOrigin)
{
AtomicallyInitializedStatic(AtomicString&, timingAllowOrigin = *new AtomicString("timing-allow-origin"));
@@ -167,7 +165,7 @@ static bool passesTimingAllowCheck(const ResourceResponse& response, Document* r
if (resourceOrigin->isSameSchemeHostPort(requestingDocument->securityOrigin()))
return true;
- const AtomicString& timingAllowOriginString = response.httpHeaderField(timingAllowOrigin);
+ const AtomicString& timingAllowOriginString = originalTimingAllowOrigin.isEmpty() ? response.httpHeaderField(timingAllowOrigin) : originalTimingAllowOrigin;
if (timingAllowOriginString.isEmpty() || equalIgnoringCase(timingAllowOriginString, "null"))
return false;
@@ -187,11 +185,11 @@ static bool passesTimingAllowCheck(const ResourceResponse& response, Document* r
static bool allowsTimingRedirect(const Vector<ResourceResponse>& redirectChain, const ResourceResponse& finalResponse, Document* initiatorDocument)
{
- if (!passesTimingAllowCheck(finalResponse, initiatorDocument))
+ if (!passesTimingAllowCheck(finalResponse, initiatorDocument, emptyAtom))
return false;
for (size_t i = 0; i < redirectChain.size(); i++) {
- if (!passesTimingAllowCheck(redirectChain[i], initiatorDocument))
+ if (!passesTimingAllowCheck(redirectChain[i], initiatorDocument, emptyAtom))
return false;
}
@@ -204,11 +202,11 @@ void Performance::addResourceTiming(const ResourceTimingInfo& info, Document* in
return;
const ResourceResponse& finalResponse = info.finalResponse();
- bool allowTimingDetails = passesTimingAllowCheck(finalResponse, initiatorDocument);
+ bool allowTimingDetails = passesTimingAllowCheck(finalResponse, initiatorDocument, info.originalTimingAllowOrigin());
double startTime = info.initialTime();
if (info.redirectChain().isEmpty()) {
- RefPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(info, initiatorDocument, startTime, allowTimingDetails);
+ RefPtrWillBeRawPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(info, initiatorDocument, startTime, allowTimingDetails);
addResourceTimingBuffer(entry);
return;
}
@@ -227,11 +225,11 @@ void Performance::addResourceTiming(const ResourceTimingInfo& info, Document* in
ASSERT(lastRedirectTiming);
double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd;
- RefPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(info, initiatorDocument, startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails);
+ RefPtrWillBeRawPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(info, initiatorDocument, startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails);
addResourceTimingBuffer(entry);
}
-void Performance::addResourceTimingBuffer(PassRefPtr<PerformanceEntry> entry)
+void Performance::addResourceTimingBuffer(PassRefPtrWillBeRawPtr<PerformanceEntry> entry)
{
m_resourceTimingBuffer.append(entry);
@@ -277,4 +275,13 @@ double Performance::now() const
return 1000.0 * (monotonicallyIncreasingTime() - m_referenceTime);
}
+void Performance::trace(Visitor* visitor)
+{
+ visitor->trace(m_navigation);
+ visitor->trace(m_timing);
+ visitor->trace(m_resourceTimingBuffer);
+ visitor->trace(m_userTiming);
+ EventTargetWithInlineData::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/timing/Performance.h b/chromium/third_party/WebKit/Source/core/timing/Performance.h
index 8dfe0be352c..1ef9d45aec8 100644
--- a/chromium/third_party/WebKit/Source/core/timing/Performance.h
+++ b/chromium/third_party/WebKit/Source/core/timing/Performance.h
@@ -39,6 +39,7 @@
#include "core/timing/PerformanceEntry.h"
#include "core/timing/PerformanceNavigation.h"
#include "core/timing/PerformanceTiming.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -53,26 +54,32 @@ class ResourceResponse;
class ResourceTimingInfo;
class UserTiming;
-class Performance : public ScriptWrappable, public RefCounted<Performance>, public DOMWindowProperty, public EventTargetWithInlineData {
+typedef WillBeHeapVector<RefPtrWillBeMember<PerformanceEntry> > PerformanceEntryVector;
+
+class Performance FINAL : public RefCountedWillBeRefCountedGarbageCollected<Performance>, public ScriptWrappable, public DOMWindowProperty, public EventTargetWithInlineData {
REFCOUNTED_EVENT_TARGET(Performance);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Performance);
public:
- static PassRefPtr<Performance> create(Frame* frame) { return adoptRef(new Performance(frame)); }
- ~Performance();
+ static PassRefPtrWillBeRawPtr<Performance> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeRefCountedGarbageCollected(new Performance(frame));
+ }
+ virtual ~Performance();
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ExecutionContext* executionContext() const OVERRIDE;
- PassRefPtr<MemoryInfo> memory() const;
+ PassRefPtrWillBeRawPtr<MemoryInfo> memory() const;
PerformanceNavigation* navigation() const;
PerformanceTiming* timing() const;
double now() const;
- Vector<RefPtr<PerformanceEntry> > getEntries() const;
- Vector<RefPtr<PerformanceEntry> > getEntriesByType(const String& entryType);
- Vector<RefPtr<PerformanceEntry> > getEntriesByName(const String& name, const String& entryType);
+ PerformanceEntryVector getEntries() const;
+ PerformanceEntryVector getEntriesByType(const String& entryType);
+ PerformanceEntryVector getEntriesByName(const String& name, const String& entryType);
void webkitClearResourceTimings();
- void webkitSetResourceTimingBufferSize(unsigned int);
+ void webkitSetResourceTimingBufferSize(unsigned);
DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitresourcetimingbufferfull);
@@ -84,20 +91,22 @@ public:
void measure(const String& measureName, const String& startMark, const String& endMark, ExceptionState&);
void clearMeasures(const String& measureName);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- explicit Performance(Frame*);
+ explicit Performance(LocalFrame*);
bool isResourceTimingBufferFull();
- void addResourceTimingBuffer(PassRefPtr<PerformanceEntry>);
+ void addResourceTimingBuffer(PassRefPtrWillBeRawPtr<PerformanceEntry>);
- mutable RefPtr<PerformanceNavigation> m_navigation;
- mutable RefPtr<PerformanceTiming> m_timing;
+ mutable RefPtrWillBeMember<PerformanceNavigation> m_navigation;
+ mutable RefPtrWillBeMember<PerformanceTiming> m_timing;
- Vector<RefPtr<PerformanceEntry> > m_resourceTimingBuffer;
+ PerformanceEntryVector m_resourceTimingBuffer;
unsigned m_resourceTimingBufferSize;
double m_referenceTime;
- RefPtr<UserTiming> m_userTiming;
+ RefPtrWillBeMember<UserTiming> m_userTiming;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/timing/Performance.idl b/chromium/third_party/WebKit/Source/core/timing/Performance.idl
index b29b83e4985..50e62a8ff41 100644
--- a/chromium/third_party/WebKit/Source/core/timing/Performance.idl
+++ b/chromium/third_party/WebKit/Source/core/timing/Performance.idl
@@ -30,35 +30,28 @@
*/
// See: http://www.w3.org/TR/navigation-timing/
-interface Performance : EventTarget {
+[
+ WillBeGarbageCollected
+] interface Performance : EventTarget {
readonly attribute PerformanceNavigation navigation;
readonly attribute PerformanceTiming timing;
readonly attribute MemoryInfo memory;
[MeasureAs=UnprefixedPerformanceTimeline] sequence<PerformanceEntry> getEntries();
[MeasureAs=UnprefixedPerformanceTimeline] sequence<PerformanceEntry> getEntriesByType(DOMString entryType);
- [MeasureAs=UnprefixedPerformanceTimeline] sequence<PerformanceEntry> getEntriesByName(DOMString name, [Default=NullString] optional DOMString entryType);
- [DeprecateAs=PrefixedPerformanceTimeline,ImplementedAs=getEntries] sequence<PerformanceEntry> webkitGetEntries();
- [DeprecateAs=PrefixedPerformanceTimeline,ImplementedAs=getEntriesByType] sequence<PerformanceEntry> webkitGetEntriesByType(DOMString entryType);
- [DeprecateAs=PrefixedPerformanceTimeline,ImplementedAs=getEntriesByName] sequence<PerformanceEntry> webkitGetEntriesByName(DOMString name, [Default=NullString] optional DOMString entryType);
+ [MeasureAs=UnprefixedPerformanceTimeline] sequence<PerformanceEntry> getEntriesByName(DOMString name, optional DOMString entryType = null);
- void webkitClearResourceTimings();
- void webkitSetResourceTimingBufferSize(unsigned long maxSize);
+ [MeasureAs=PrefixedPerformanceClearResourceTimings] void webkitClearResourceTimings();
+ [MeasureAs=PrefixedPerformanceSetResourceTimingBufferSize] void webkitSetResourceTimingBufferSize(unsigned long maxSize);
attribute EventHandler onwebkitresourcetimingbufferfull;
// See http://www.w3.org/TR/2012/CR-user-timing-20120726/
[RaisesException,MeasureAs=UnprefixedUserTiming] void mark(DOMString markName);
- [MeasureAs=UnprefixedUserTiming] void clearMarks([Default=NullString] optional DOMString markName);
+ [MeasureAs=UnprefixedUserTiming] void clearMarks(optional DOMString markName = null);
- [RaisesException,MeasureAs=UnprefixedUserTiming] void measure(DOMString measureName, [Default=NullString] optional DOMString startMark, [Default=NullString] optional DOMString endMark);
- [MeasureAs=UnprefixedUserTiming] void clearMeasures([Default=NullString] optional DOMString measureName);
-
- [RaisesException,DeprecateAs=PrefixedUserTiming,ImplementedAs=mark] void webkitMark(DOMString markName);
- [DeprecateAs=PrefixedUserTiming,ImplementedAs=clearMarks] void webkitClearMarks([Default=NullString] optional DOMString markName);
-
- [RaisesException,DeprecateAs=PrefixedUserTiming,ImplementedAs=measure] void webkitMeasure(DOMString measureName, [Default=NullString] optional DOMString startMark, [Default=NullString] optional DOMString endMark);
- [DeprecateAs=PrefixedUserTiming,ImplementedAs=clearMeasures] void webkitClearMeasures([Default=NullString] optional DOMString measureName);
+ [RaisesException,MeasureAs=UnprefixedUserTiming] void measure(DOMString measureName, optional DOMString startMark = null, optional DOMString endMark = null);
+ [MeasureAs=UnprefixedUserTiming] void clearMeasures(optional DOMString measureName = null);
// See http://www.w3.org/TR/hr-time/ for details.
double now();
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.h b/chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.h
index 1f19b434aff..8cebc75f140 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.h
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.h
@@ -33,13 +33,14 @@
#define PerformanceEntry_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class PerformanceEntry : public RefCounted<PerformanceEntry>, public ScriptWrappable {
+class PerformanceEntry : public RefCountedWillBeGarbageCollectedFinalized<PerformanceEntry>, public ScriptWrappable {
public:
virtual ~PerformanceEntry();
@@ -52,11 +53,13 @@ public:
virtual bool isMark() { return false; }
virtual bool isMeasure() { return false; }
- static bool startTimeCompareLessThan(PassRefPtr<PerformanceEntry> a, PassRefPtr<PerformanceEntry> b)
+ static bool startTimeCompareLessThan(PassRefPtrWillBeRawPtr<PerformanceEntry> a, PassRefPtrWillBeRawPtr<PerformanceEntry> b)
{
return a->startTime() < b->startTime();
}
+ virtual void trace(Visitor*) { }
+
protected:
PerformanceEntry(const String& name, const String& entryType, double startTime, double finishTime);
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.idl b/chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.idl
index 2f5771fc2c1..06d8222ccd9 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.idl
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceEntry.idl
@@ -30,6 +30,7 @@
// See: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PerformanceTimeline/Overview.html
[
+ WillBeGarbageCollected,
Custom=Wrap,
] interface PerformanceEntry {
readonly attribute DOMString name;
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceMark.h b/chromium/third_party/WebKit/Source/core/timing/PerformanceMark.h
index 793a7cd53d8..f8b7bafe00d 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceMark.h
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceMark.h
@@ -27,16 +27,25 @@
#define PerformanceMark_h
#include "core/timing/PerformanceEntry.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class PerformanceMark : public PerformanceEntry {
+class PerformanceMark FINAL : public PerformanceEntry {
public:
- static PassRefPtr<PerformanceMark> create(const String& name, double startTime) { return adoptRef(new PerformanceMark(name, startTime)); }
+ static PassRefPtrWillBeRawPtr<PerformanceMark> create(const String& name, double startTime)
+ {
+ return adoptRefWillBeNoop(new PerformanceMark(name, startTime));
+ }
+
+ virtual bool isMark() OVERRIDE { return true; }
- virtual bool isMark() { return true; }
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ PerformanceEntry::trace(visitor);
+ }
private:
PerformanceMark(const String& name, double startTime) : PerformanceEntry(name, "mark", startTime, startTime)
@@ -44,7 +53,7 @@ private:
ScriptWrappable::init(this);
}
- ~PerformanceMark() { }
+ virtual ~PerformanceMark() { }
};
}
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceMeasure.h b/chromium/third_party/WebKit/Source/core/timing/PerformanceMeasure.h
index 9d24142f4ee..60e786e187f 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceMeasure.h
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceMeasure.h
@@ -27,23 +27,32 @@
#define PerformanceMeasure_h
#include "core/timing/PerformanceEntry.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class PerformanceMeasure : public PerformanceEntry {
+class PerformanceMeasure FINAL : public PerformanceEntry {
public:
- static PassRefPtr<PerformanceMeasure> create(const String& name, double startTime, double endTime) { return adoptRef(new PerformanceMeasure(name, startTime, endTime)); }
+ static PassRefPtrWillBeRawPtr<PerformanceMeasure> create(const String& name, double startTime, double endTime)
+ {
+ return adoptRefWillBeNoop(new PerformanceMeasure(name, startTime, endTime));
+ }
+
+ virtual bool isMeasure() OVERRIDE { return true; }
- virtual bool isMeasure() { return true; }
+ virtual void trace(Visitor* visitor)
+ {
+ PerformanceEntry::trace(visitor);
+ }
private:
PerformanceMeasure(const String& name, double startTime, double endTime) : PerformanceEntry(name, "measure", startTime, endTime)
{
ScriptWrappable::init(this);
}
- ~PerformanceMeasure() { }
+ virtual ~PerformanceMeasure() { }
};
}
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp b/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp
index 7e94d7596e4..4683fd755c9 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.cpp
@@ -31,13 +31,13 @@
#include "config.h"
#include "core/timing/PerformanceNavigation.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoaderTypes.h"
-#include "core/frame/Frame.h"
namespace WebCore {
-PerformanceNavigation::PerformanceNavigation(Frame* frame)
+PerformanceNavigation::PerformanceNavigation(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.h b/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.h
index 2444b39f829..fb320284f6f 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.h
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.h
@@ -33,16 +33,20 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class Frame;
+class LocalFrame;
-class PerformanceNavigation : public RefCounted<PerformanceNavigation>, public ScriptWrappable, public DOMWindowProperty {
+class PerformanceNavigation FINAL : public RefCountedWillBeGarbageCollectedFinalized<PerformanceNavigation>, public ScriptWrappable, public DOMWindowProperty {
public:
- static PassRefPtr<PerformanceNavigation> create(Frame* frame) { return adoptRef(new PerformanceNavigation(frame)); }
+ static PassRefPtrWillBeRawPtr<PerformanceNavigation> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new PerformanceNavigation(frame));
+ }
enum PerformanceNavigationType {
TYPE_NAVIGATE,
@@ -54,8 +58,10 @@ public:
unsigned short type() const;
unsigned short redirectCount() const;
+ void trace(Visitor*) { }
+
private:
- explicit PerformanceNavigation(Frame*);
+ explicit PerformanceNavigation(LocalFrame*);
};
}
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.idl b/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.idl
index cde7a72d4e3..ea485ab7f4d 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.idl
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceNavigation.idl
@@ -29,7 +29,9 @@
*/
// See: http://www.w3.org/TR/navigation-timing/
-interface PerformanceNavigation {
+[
+ WillBeGarbageCollected
+] interface PerformanceNavigation {
const unsigned short TYPE_NAVIGATE = 0;
const unsigned short TYPE_RELOAD = 1;
const unsigned short TYPE_BACK_FORWARD = 2;
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp b/chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp
index 8648b4fcbef..32cacfe246a 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.cpp
@@ -191,4 +191,10 @@ double PerformanceResourceTiming::responseEnd() const
return monotonicTimeToDocumentMilliseconds(m_requestingDocument.get(), m_finishTime);
}
+void PerformanceResourceTiming::trace(Visitor* visitor)
+{
+ visitor->trace(m_requestingDocument);
+ PerformanceEntry::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h b/chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h
index 2c1c7ad99eb..a8032bd8695 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceResourceTiming.h
@@ -33,6 +33,7 @@
#define PerformanceResourceTiming_h
#include "core/timing/PerformanceEntry.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -45,16 +46,16 @@ class ResourceRequest;
class ResourceResponse;
class ResourceTimingInfo;
-class PerformanceResourceTiming : public PerformanceEntry {
+class PerformanceResourceTiming FINAL : public PerformanceEntry {
public:
- static PassRefPtr<PerformanceResourceTiming> create(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, double lastRedirectEndTime, bool m_allowTimingDetails, bool m_allowRedirectDetails)
+ static PassRefPtrWillBeRawPtr<PerformanceResourceTiming> create(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, double lastRedirectEndTime, bool m_allowTimingDetails, bool m_allowRedirectDetails)
{
- return adoptRef(new PerformanceResourceTiming(info, requestingDocument, startTime, lastRedirectEndTime, m_allowTimingDetails, m_allowRedirectDetails));
+ return adoptRefWillBeNoop(new PerformanceResourceTiming(info, requestingDocument, startTime, lastRedirectEndTime, m_allowTimingDetails, m_allowRedirectDetails));
}
- static PassRefPtr<PerformanceResourceTiming> create(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, bool m_allowTimingDetails)
+ static PassRefPtrWillBeRawPtr<PerformanceResourceTiming> create(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, bool m_allowTimingDetails)
{
- return adoptRef(new PerformanceResourceTiming(info, requestingDocument, startTime, 0.0, m_allowTimingDetails, false));
+ return adoptRefWillBeNoop(new PerformanceResourceTiming(info, requestingDocument, startTime, 0.0, m_allowTimingDetails, false));
}
AtomicString initiatorType() const;
@@ -71,11 +72,13 @@ public:
double responseStart() const;
double responseEnd() const;
- virtual bool isResource() { return true; }
+ virtual bool isResource() OVERRIDE { return true; }
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
PerformanceResourceTiming(const ResourceTimingInfo&, Document* requestingDocument, double startTime, double lastRedirectEndTime, bool m_allowTimingDetails, bool m_allowRedirectDetails);
- ~PerformanceResourceTiming();
+ virtual ~PerformanceResourceTiming();
AtomicString m_initiatorType;
RefPtr<ResourceLoadTiming> m_timing;
@@ -84,7 +87,7 @@ private:
bool m_didReuseConnection;
bool m_allowTimingDetails;
bool m_allowRedirectDetails;
- RefPtr<Document> m_requestingDocument;
+ RefPtrWillBeMember<Document> m_requestingDocument;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp b/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp
index 0aa305e4e89..38ef3056bdc 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp
@@ -33,7 +33,7 @@
#include "core/dom/Document.h"
#include "core/dom/DocumentTiming.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
#include "core/loader/DocumentLoadTiming.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/FrameLoader.h"
@@ -48,7 +48,7 @@ static unsigned long long toIntegerMilliseconds(double seconds)
return static_cast<unsigned long long>(seconds * 1000.0);
}
-PerformanceTiming::PerformanceTiming(Frame* frame)
+PerformanceTiming::PerformanceTiming(LocalFrame* frame)
: DOMWindowProperty(frame)
{
ScriptWrappable::init(this);
@@ -324,7 +324,7 @@ const DocumentTiming* PerformanceTiming::documentTiming() const
if (!document)
return 0;
- return document->timing();
+ return &document->timing();
}
DocumentLoadTiming* PerformanceTiming::documentLoadTiming() const
@@ -349,7 +349,9 @@ unsigned long long PerformanceTiming::monotonicTimeToIntegerMilliseconds(double
{
ASSERT(monotonicSeconds >= 0);
const DocumentLoadTiming* timing = documentLoadTiming();
- ASSERT(timing);
+ if (!timing)
+ return 0;
+
return toIntegerMilliseconds(timing->monotonicTimeToPseudoWallTime(monotonicSeconds));
}
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.h b/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.h
index cd8ffae7cef..2c91716cf56 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.h
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.h
@@ -33,6 +33,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/frame/DOMWindowProperty.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -41,12 +42,15 @@ namespace WebCore {
class DocumentLoadTiming;
class DocumentLoader;
struct DocumentTiming;
-class Frame;
+class LocalFrame;
class ResourceLoadTiming;
-class PerformanceTiming : public RefCounted<PerformanceTiming>, public ScriptWrappable, public DOMWindowProperty {
+class PerformanceTiming FINAL : public RefCountedWillBeGarbageCollectedFinalized<PerformanceTiming>, public ScriptWrappable, public DOMWindowProperty {
public:
- static PassRefPtr<PerformanceTiming> create(Frame* frame) { return adoptRef(new PerformanceTiming(frame)); }
+ static PassRefPtrWillBeRawPtr<PerformanceTiming> create(LocalFrame* frame)
+ {
+ return adoptRefWillBeNoop(new PerformanceTiming(frame));
+ }
unsigned long long navigationStart() const;
unsigned long long unloadEventStart() const;
@@ -70,8 +74,10 @@ public:
unsigned long long loadEventStart() const;
unsigned long long loadEventEnd() const;
+ void trace(Visitor*) { }
+
private:
- explicit PerformanceTiming(Frame*);
+ explicit PerformanceTiming(LocalFrame*);
const DocumentTiming* documentTiming() const;
DocumentLoader* documentLoader() const;
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.idl b/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.idl
index 160e5ccd93a..3178e427397 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.idl
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceTiming.idl
@@ -29,7 +29,9 @@
*/
// See: http://dev.w3.org/2006/webapi/WebTiming/
-interface PerformanceTiming {
+[
+ WillBeGarbageCollected
+] interface PerformanceTiming {
readonly attribute unsigned long long navigationStart;
readonly attribute unsigned long long unloadEventStart;
readonly attribute unsigned long long unloadEventEnd;
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp b/chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp
index f1f783613cd..853c6d6f123 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.cpp
@@ -74,16 +74,16 @@ UserTiming::UserTiming(Performance* performance)
{
}
-static void insertPerformanceEntry(PerformanceEntryMap& performanceEntryMap, PassRefPtr<PerformanceEntry> performanceEntry)
+static void insertPerformanceEntry(PerformanceEntryMap& performanceEntryMap, PassRefPtrWillBeRawPtr<PerformanceEntry> performanceEntry)
{
- RefPtr<PerformanceEntry> entry = performanceEntry;
+ RefPtrWillBeRawPtr<PerformanceEntry> entry = performanceEntry;
PerformanceEntryMap::iterator it = performanceEntryMap.find(entry->name());
if (it != performanceEntryMap.end())
it->value.append(entry);
else {
- Vector<RefPtr<PerformanceEntry> > v(1);
- v[0] = entry;
- performanceEntryMap.set(entry->name(), v);
+ PerformanceEntryVector vector(1);
+ vector[0] = entry;
+ performanceEntryMap.set(entry->name(), vector);
}
}
@@ -164,45 +164,52 @@ void UserTiming::clearMeasures(const String& measureName)
clearPeformanceEntries(m_measuresMap, measureName);
}
-static Vector<RefPtr<PerformanceEntry> > convertToEntrySequence(const PerformanceEntryMap& performanceEntryMap)
+static PerformanceEntryVector convertToEntrySequence(const PerformanceEntryMap& performanceEntryMap)
{
- Vector<RefPtr<PerformanceEntry> > entries;
+ PerformanceEntryVector entries;
for (PerformanceEntryMap::const_iterator it = performanceEntryMap.begin(); it != performanceEntryMap.end(); ++it)
- entries.append(it->value);
+ entries.appendVector(it->value);
return entries;
}
-static Vector<RefPtr<PerformanceEntry> > getEntrySequenceByName(const PerformanceEntryMap& performanceEntryMap, const String& name)
+static PerformanceEntryVector getEntrySequenceByName(const PerformanceEntryMap& performanceEntryMap, const String& name)
{
- Vector<RefPtr<PerformanceEntry> > entries;
+ PerformanceEntryVector entries;
PerformanceEntryMap::const_iterator it = performanceEntryMap.find(name);
if (it != performanceEntryMap.end())
- entries.append(it->value);
+ entries.appendVector(it->value);
return entries;
}
-Vector<RefPtr<PerformanceEntry> > UserTiming::getMarks() const
+PerformanceEntryVector UserTiming::getMarks() const
{
return convertToEntrySequence(m_marksMap);
}
-Vector<RefPtr<PerformanceEntry> > UserTiming::getMarks(const String& name) const
+PerformanceEntryVector UserTiming::getMarks(const String& name) const
{
return getEntrySequenceByName(m_marksMap, name);
}
-Vector<RefPtr<PerformanceEntry> > UserTiming::getMeasures() const
+PerformanceEntryVector UserTiming::getMeasures() const
{
return convertToEntrySequence(m_measuresMap);
}
-Vector<RefPtr<PerformanceEntry> > UserTiming::getMeasures(const String& name) const
+PerformanceEntryVector UserTiming::getMeasures(const String& name) const
{
return getEntrySequenceByName(m_measuresMap, name);
}
+void UserTiming::trace(Visitor* visitor)
+{
+ visitor->trace(m_performance);
+ visitor->trace(m_marksMap);
+ visitor->trace(m_measuresMap);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.h b/chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.h
index c12d6cfd491..0aa24c337aa 100644
--- a/chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.h
+++ b/chromium/third_party/WebKit/Source/core/timing/PerformanceUserTiming.h
@@ -26,7 +26,9 @@
#ifndef PerformanceUserTiming_h
#define PerformanceUserTiming_h
+#include "core/timing/Performance.h"
#include "core/timing/PerformanceTiming.h"
+#include "platform/heap/Handle.h"
#include "wtf/HashMap.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -40,11 +42,14 @@ class Performance;
class PerformanceEntry;
typedef unsigned long long (PerformanceTiming::*NavigationTimingFunction)() const;
-typedef HashMap<String, Vector<RefPtr<PerformanceEntry> > > PerformanceEntryMap;
+typedef WillBeHeapHashMap<String, PerformanceEntryVector> PerformanceEntryMap;
-class UserTiming : public RefCounted<UserTiming> {
+class UserTiming : public RefCountedWillBeGarbageCollected<UserTiming> {
public:
- static PassRefPtr<UserTiming> create(Performance* performance) { return adoptRef(new UserTiming(performance)); }
+ static PassRefPtrWillBeRawPtr<UserTiming> create(Performance* performance)
+ {
+ return adoptRefWillBeNoop(new UserTiming(performance));
+ }
void mark(const String& markName, ExceptionState&);
void clearMarks(const String& markName);
@@ -52,17 +57,19 @@ public:
void measure(const String& measureName, const String& startMark, const String& endMark, ExceptionState&);
void clearMeasures(const String& measureName);
- Vector<RefPtr<PerformanceEntry> > getMarks() const;
- Vector<RefPtr<PerformanceEntry> > getMeasures() const;
+ PerformanceEntryVector getMarks() const;
+ PerformanceEntryVector getMeasures() const;
- Vector<RefPtr<PerformanceEntry> > getMarks(const String& name) const;
- Vector<RefPtr<PerformanceEntry> > getMeasures(const String& name) const;
+ PerformanceEntryVector getMarks(const String& name) const;
+ PerformanceEntryVector getMeasures(const String& name) const;
+
+ void trace(Visitor*);
private:
explicit UserTiming(Performance*);
double findExistingMarkStartTime(const String& markName, ExceptionState&);
- Performance* m_performance;
+ RawPtrWillBeMember<Performance> m_performance;
PerformanceEntryMap m_marksMap;
PerformanceEntryMap m_measuresMap;
};
diff --git a/chromium/third_party/WebKit/Source/core/timing/ResourceTimingInfo.h b/chromium/third_party/WebKit/Source/core/timing/ResourceTimingInfo.h
index a3784a63e59..ff8094e9517 100644
--- a/chromium/third_party/WebKit/Source/core/timing/ResourceTimingInfo.h
+++ b/chromium/third_party/WebKit/Source/core/timing/ResourceTimingInfo.h
@@ -49,6 +49,9 @@ public:
void setInitiatorType(const AtomicString& type) { m_type = type; }
const AtomicString& initiatorType() const { return m_type; }
+ void setOriginalTimingAllowOrigin(const AtomicString& originalTimingAllowOrigin) { m_originalTimingAllowOrigin = originalTimingAllowOrigin; }
+ const AtomicString& originalTimingAllowOrigin() const { return m_originalTimingAllowOrigin; }
+
void setLoadFinishTime(double time) { m_loadFinishTime = time; }
double loadFinishTime() const { return m_loadFinishTime; }
@@ -63,9 +66,9 @@ public:
void clearLoadTimings()
{
- m_finalResponse.setResourceLoadTiming(0);
+ m_finalResponse.setResourceLoadTiming(nullptr);
for (size_t i = 0; i < m_redirectChain.size(); ++i)
- m_redirectChain[i].setResourceLoadTiming(0);
+ m_redirectChain[i].setResourceLoadTiming(nullptr);
}
private:
@@ -76,6 +79,7 @@ private:
}
AtomicString m_type;
+ AtomicString m_originalTimingAllowOrigin;
double m_initialTime;
double m_loadFinishTime;
ResourceRequest m_initialRequest;
diff --git a/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.cpp b/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.cpp
index a617c23b4f5..1aba3c24e0c 100644
--- a/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.cpp
@@ -34,7 +34,7 @@
#include "bindings/v8/ExceptionState.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "platform/weborigin/SecurityOrigin.h"
namespace WebCore {
@@ -63,7 +63,7 @@ KURL AbstractWorker::resolveURL(const String& url, ExceptionState& exceptionStat
return KURL();
}
- if (executionContext()->contentSecurityPolicy() && !executionContext()->contentSecurityPolicy()->allowScriptFromSource(scriptURL)) {
+ if (executionContext()->contentSecurityPolicy() && !executionContext()->contentSecurityPolicy()->allowWorkerContextFromSource(scriptURL)) {
exceptionState.throwSecurityError("Access to the script at '" + scriptURL.elidedString() + "' is denied by the document's Content Security Policy.");
return KURL();
}
diff --git a/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.h b/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.h
index 775f2e6ac4e..783d4890770 100644
--- a/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.h
+++ b/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.h
@@ -35,7 +35,7 @@
#include "core/dom/ActiveDOMObject.h"
#include "core/events/EventListener.h"
#include "core/events/EventTarget.h"
-#include "core/events/ThreadLocalEventNames.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -47,13 +47,14 @@ class ExceptionState;
class KURL;
class ExecutionContext;
-class AbstractWorker : public RefCounted<AbstractWorker>, public EventTargetWithInlineData, public ActiveDOMObject {
+class AbstractWorker : public RefCountedWillBeRefCountedGarbageCollected<AbstractWorker>, public EventTargetWithInlineData, public ActiveDOMObject {
REFCOUNTED_EVENT_TARGET(AbstractWorker);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AbstractWorker);
public:
// EventTarget APIs
- virtual ExecutionContext* executionContext() const OVERRIDE { return ActiveDOMObject::executionContext(); }
+ virtual ExecutionContext* executionContext() const OVERRIDE FINAL { return ActiveDOMObject::executionContext(); }
- DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
+ DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(error);
AbstractWorker(ExecutionContext*);
virtual ~AbstractWorker();
diff --git a/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.idl b/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.idl
index 9c13c6f54b2..fc46a145f91 100644
--- a/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.idl
+++ b/chromium/third_party/WebKit/Source/core/workers/AbstractWorker.idl
@@ -30,9 +30,9 @@
*/
[
- NoInterfaceObject,
- LegacyImplementedInBaseClass
+ LegacyTreatAsPartialInterface,
+ NoInterfaceObject, // Always used on target of 'implements'
+ WillBeGarbageCollected,
] interface AbstractWorker {
attribute EventHandler onerror;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp
index 0605c011b1d..f52576759c4 100644
--- a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.cpp
@@ -33,7 +33,7 @@
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/SerializedScriptValue.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/workers/DedicatedWorkerThread.h"
#include "core/workers/WorkerClients.h"
#include "core/workers/WorkerObjectProxy.h"
@@ -41,14 +41,14 @@
namespace WebCore {
-PassRefPtr<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(DedicatedWorkerThread* thread, PassOwnPtr<WorkerThreadStartupData> startupData, double timeOrigin)
+PassRefPtrWillBeRawPtr<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(DedicatedWorkerThread* thread, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData, double timeOrigin)
{
- RefPtr<DedicatedWorkerGlobalScope> context = adoptRef(new DedicatedWorkerGlobalScope(startupData->m_scriptURL, startupData->m_userAgent, thread, timeOrigin, startupData->m_workerClients.release()));
+ RefPtrWillBeRawPtr<DedicatedWorkerGlobalScope> context = adoptRefWillBeRefCountedGarbageCollected(new DedicatedWorkerGlobalScope(startupData->m_scriptURL, startupData->m_userAgent, thread, timeOrigin, startupData->m_workerClients.release()));
context->applyContentSecurityPolicyFromString(startupData->m_contentSecurityPolicy, startupData->m_contentSecurityPolicyType);
return context.release();
}
-DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(const KURL& url, const String& userAgent, DedicatedWorkerThread* thread, double timeOrigin, PassOwnPtr<WorkerClients> workerClients)
+DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(const KURL& url, const String& userAgent, DedicatedWorkerThread* thread, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerClients> workerClients)
: WorkerGlobalScope(url, userAgent, thread, timeOrigin, workerClients)
{
ScriptWrappable::init(this);
@@ -78,9 +78,48 @@ void DedicatedWorkerGlobalScope::importScripts(const Vector<String>& urls, Excep
thread()->workerObjectProxy().reportPendingActivity(hasPendingActivity());
}
-DedicatedWorkerThread* DedicatedWorkerGlobalScope::thread()
+DedicatedWorkerThread* DedicatedWorkerGlobalScope::thread() const
{
return static_cast<DedicatedWorkerThread*>(Base::thread());
}
+class UseCounterTask : public ExecutionContextTask {
+public:
+ static PassOwnPtr<UseCounterTask> createCount(UseCounter::Feature feature) { return adoptPtr(new UseCounterTask(feature, false)); }
+ static PassOwnPtr<UseCounterTask> createDeprecation(UseCounter::Feature feature) { return adoptPtr(new UseCounterTask(feature, true)); }
+
+private:
+ UseCounterTask(UseCounter::Feature feature, bool isDeprecation)
+ : m_feature(feature)
+ , m_isDeprecation(isDeprecation)
+ {
+ }
+
+ virtual void performTask(ExecutionContext* context) OVERRIDE
+ {
+ if (m_isDeprecation)
+ UseCounter::countDeprecation(*toDocument(context), m_feature);
+ else
+ UseCounter::count(*toDocument(context), m_feature);
+ }
+
+ UseCounter::Feature m_feature;
+ bool m_isDeprecation;
+};
+
+void DedicatedWorkerGlobalScope::countFeature(UseCounter::Feature feature) const
+{
+ thread()->workerObjectProxy().postTaskToMainExecutionContext(UseCounterTask::createCount(feature));
+}
+
+void DedicatedWorkerGlobalScope::countDeprecation(UseCounter::Feature feature) const
+{
+ thread()->workerObjectProxy().postTaskToMainExecutionContext(UseCounterTask::createDeprecation(feature));
+}
+
+void DedicatedWorkerGlobalScope::trace(Visitor* visitor)
+{
+ WorkerGlobalScope::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.h b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.h
index 1555111e9f3..d31a367d6cb 100644
--- a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.h
+++ b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.h
@@ -32,21 +32,24 @@
#define DedicatedWorkerGlobalScope_h
#include "core/dom/MessagePort.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/workers/WorkerGlobalScope.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class DedicatedWorkerThread;
-struct WorkerThreadStartupData;
+class WorkerThreadStartupData;
-class DedicatedWorkerGlobalScope : public WorkerGlobalScope {
+class DedicatedWorkerGlobalScope FINAL : public WorkerGlobalScope {
public:
typedef WorkerGlobalScope Base;
- static PassRefPtr<DedicatedWorkerGlobalScope> create(DedicatedWorkerThread*, PassOwnPtr<WorkerThreadStartupData>, double timeOrigin);
+ static PassRefPtrWillBeRawPtr<DedicatedWorkerGlobalScope> create(DedicatedWorkerThread*, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>, double timeOrigin);
virtual ~DedicatedWorkerGlobalScope();
virtual bool isDedicatedWorkerGlobalScope() const OVERRIDE { return true; }
+ virtual void countFeature(UseCounter::Feature) const OVERRIDE;
+ virtual void countDeprecation(UseCounter::Feature) const OVERRIDE;
// Overridden to allow us to check our pending activity after executing imported script.
virtual void importScripts(const Vector<String>& urls, ExceptionState&) OVERRIDE;
@@ -58,10 +61,12 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
- DedicatedWorkerThread* thread();
+ DedicatedWorkerThread* thread() const;
+
+ virtual void trace(Visitor*) OVERRIDE;
private:
- DedicatedWorkerGlobalScope(const KURL&, const String& userAgent, DedicatedWorkerThread*, double timeOrigin, PassOwnPtr<WorkerClients>);
+ DedicatedWorkerGlobalScope(const KURL&, const String& userAgent, DedicatedWorkerThread*, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerClients>);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.idl b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.idl
index 659a5f58cb4..8c4444d210c 100644
--- a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.idl
+++ b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerGlobalScope.idl
@@ -29,9 +29,9 @@
*/
[
- GlobalContext=DedicatedWorkerGlobalScope
+ Exposed=DedicatedWorker,
+ Global=Worker&DedicatedWorker
] interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
- [Custom, RaisesException] void postMessage(any message, optional Array messagePorts);
+ [Custom, RaisesException] void postMessage(any message, optional MessagePort[] messagePorts);
attribute EventHandler onmessage;
};
-
diff --git a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp
index 94038c67719..82acf460bf2 100644
--- a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp
@@ -38,12 +38,12 @@
namespace WebCore {
-PassRefPtr<DedicatedWorkerThread> DedicatedWorkerThread::create(WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin, PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtr<DedicatedWorkerThread> DedicatedWorkerThread::create(WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
{
return adoptRef(new DedicatedWorkerThread(workerLoaderProxy, workerObjectProxy, timeOrigin, startupData));
}
-DedicatedWorkerThread::DedicatedWorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin, PassOwnPtr<WorkerThreadStartupData> startupData)
+DedicatedWorkerThread::DedicatedWorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
: WorkerThread(workerLoaderProxy, workerObjectProxy, startupData)
, m_workerObjectProxy(workerObjectProxy)
, m_timeOrigin(timeOrigin)
@@ -54,7 +54,7 @@ DedicatedWorkerThread::~DedicatedWorkerThread()
{
}
-PassRefPtr<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtrWillBeRawPtr<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
{
return DedicatedWorkerGlobalScope::create(this, startupData, m_timeOrigin);
}
diff --git a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.h b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.h
index c8f44c7b0e4..ade57284a81 100644
--- a/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.h
+++ b/chromium/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.h
@@ -30,26 +30,26 @@
#ifndef DedicatedWorkerThread_h
#define DedicatedWorkerThread_h
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/workers/WorkerThread.h"
namespace WebCore {
class WorkerObjectProxy;
-struct WorkerThreadStartupData;
+class WorkerThreadStartupData;
-class DedicatedWorkerThread : public WorkerThread {
+class DedicatedWorkerThread FINAL : public WorkerThread {
public:
- static PassRefPtr<DedicatedWorkerThread> create(WorkerLoaderProxy&, WorkerObjectProxy&, double timeOrigin, PassOwnPtr<WorkerThreadStartupData>);
+ static PassRefPtr<DedicatedWorkerThread> create(WorkerLoaderProxy&, WorkerObjectProxy&, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
virtual ~DedicatedWorkerThread();
protected:
- virtual PassRefPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData>) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>) OVERRIDE;
virtual void runEventLoop() OVERRIDE;
private:
- DedicatedWorkerThread(WorkerLoaderProxy&, WorkerObjectProxy&, double timeOrigin, PassOwnPtr<WorkerThreadStartupData>);
+ DedicatedWorkerThread(WorkerLoaderProxy&, WorkerObjectProxy&, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
WorkerObjectProxy& m_workerObjectProxy;
double m_timeOrigin;
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorker.cpp b/chromium/third_party/WebKit/Source/core/workers/SharedWorker.cpp
index 35dbb17ecad..dd75c77a7c6 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorker.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorker.cpp
@@ -37,9 +37,11 @@
#include "core/dom/ExecutionContext.h"
#include "core/dom/MessageChannel.h"
#include "core/dom/MessagePort.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/page/Page.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/UseCounter.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/FrameLoaderClient.h"
#include "core/workers/SharedWorkerRepositoryClient.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/SecurityOrigin.h"
@@ -52,16 +54,16 @@ inline SharedWorker::SharedWorker(ExecutionContext* context)
ScriptWrappable::init(this);
}
-PassRefPtr<SharedWorker> SharedWorker::create(ExecutionContext* context, const String& url, const String& name, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<SharedWorker> SharedWorker::create(ExecutionContext* context, const String& url, const String& name, ExceptionState& exceptionState)
{
ASSERT(isMainThread());
ASSERT_WITH_SECURITY_IMPLICATION(context->isDocument());
- UseCounter::count(toDocument(context)->domWindow(), UseCounter::SharedWorkerStart);
+ UseCounter::count(context, UseCounter::SharedWorkerStart);
- RefPtr<SharedWorker> worker = adoptRef(new SharedWorker(context));
+ RefPtrWillBeRawPtr<SharedWorker> worker = adoptRefWillBeRefCountedGarbageCollected(new SharedWorker(context));
- RefPtr<MessageChannel> channel = MessageChannel::create(context);
+ RefPtrWillBeRawPtr<MessageChannel> channel = MessageChannel::create(context);
worker->m_port = channel->port1();
OwnPtr<blink::WebMessagePortChannel> remotePort = channel->port2()->disentangle();
ASSERT(remotePort);
@@ -72,15 +74,15 @@ PassRefPtr<SharedWorker> SharedWorker::create(ExecutionContext* context, const S
Document* document = toDocument(context);
if (!document->securityOrigin()->canAccessSharedWorkers()) {
exceptionState.throwSecurityError("Access to shared workers is denied to origin '" + document->securityOrigin()->toString() + "'.");
- return 0;
+ return nullptr;
}
KURL scriptURL = worker->resolveURL(url, exceptionState);
if (scriptURL.isEmpty())
- return 0;
+ return nullptr;
- if (document->page() && document->page()->sharedWorkerRepositoryClient())
- document->page()->sharedWorkerRepositoryClient()->connect(worker.get(), remotePort.release(), scriptURL, name, exceptionState);
+ if (document->frame()->loader().client()->sharedWorkerRepositoryClient())
+ document->frame()->loader().client()->sharedWorkerRepositoryClient()->connect(worker.get(), remotePort.release(), scriptURL, name, exceptionState);
return worker.release();
}
@@ -104,4 +106,10 @@ void SharedWorker::unsetPreventGC()
unsetPendingActivity(this);
}
+void SharedWorker::trace(Visitor* visitor)
+{
+ AbstractWorker::trace(visitor);
+ WillBeHeapSupplementable<SharedWorker>::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorker.h b/chromium/third_party/WebKit/Source/core/workers/SharedWorker.h
index 8f7902a6875..8a767cfa426 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorker.h
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorker.h
@@ -33,14 +33,17 @@
#define SharedWorker_h
#include "core/workers/AbstractWorker.h"
+#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class ExceptionState;
-class SharedWorker : public AbstractWorker, public ScriptWrappable {
+class SharedWorker FINAL : public AbstractWorker, public ScriptWrappable, public WillBeHeapSupplementable<SharedWorker> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(SharedWorker);
public:
- static PassRefPtr<SharedWorker> create(ExecutionContext*, const String& url, const String& name, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<SharedWorker> create(ExecutionContext*, const String& url, const String& name, ExceptionState&);
virtual ~SharedWorker();
MessagePort* port() const { return m_port.get(); }
@@ -52,6 +55,8 @@ public:
// Allows this SharedWorker + JS wrapper to be garbage collected.
void unsetPreventGC();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit SharedWorker(ExecutionContext*);
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorker.idl b/chromium/third_party/WebKit/Source/core/workers/SharedWorker.idl
index b36361efc05..bd4719c609a 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorker.idl
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorker.idl
@@ -31,10 +31,11 @@
[
ActiveDOMObject,
- Constructor(DOMString scriptURL, [Default=NullString] optional DOMString name),
+ Constructor(DOMString scriptURL, optional DOMString name = null),
ConstructorCallWith=ExecutionContext,
RaisesException=Constructor,
RuntimeEnabled=SharedWorker,
+ WillBeGarbageCollected,
] interface SharedWorker : EventTarget {
readonly attribute MessagePort port;
};
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp
index c961699b922..96188b4dbcb 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.cpp
@@ -33,32 +33,31 @@
#include "core/workers/SharedWorkerGlobalScope.h"
#include "core/events/MessageEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/inspector/ScriptCallStack.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/workers/SharedWorkerThread.h"
#include "core/workers/WorkerClients.h"
#include "wtf/CurrentTime.h"
namespace WebCore {
-PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort> prpPort)
+PassRefPtrWillBeRawPtr<MessageEvent> createConnectEvent(PassRefPtrWillBeRawPtr<MessagePort> prpPort)
{
- RefPtr<MessagePort> port = prpPort;
- RefPtr<MessageEvent> event = MessageEvent::create(adoptPtr(new MessagePortArray(1, port)), String(), String(), port);
+ RefPtrWillBeRawPtr<MessagePort> port = prpPort;
+ RefPtrWillBeRawPtr<MessageEvent> event = MessageEvent::create(adoptPtr(new MessagePortArray(1, port)), String(), String(), port);
event->initEvent(EventTypeNames::connect, false, false);
return event.release();
}
// static
-PassRefPtr<SharedWorkerGlobalScope> SharedWorkerGlobalScope::create(const String& name, SharedWorkerThread* thread, PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtrWillBeRawPtr<SharedWorkerGlobalScope> SharedWorkerGlobalScope::create(const String& name, SharedWorkerThread* thread, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
{
- RefPtr<SharedWorkerGlobalScope> context = adoptRef(new SharedWorkerGlobalScope(name, startupData->m_scriptURL, startupData->m_userAgent, thread, startupData->m_workerClients.release()));
+ RefPtrWillBeRawPtr<SharedWorkerGlobalScope> context = adoptRefWillBeRefCountedGarbageCollected(new SharedWorkerGlobalScope(name, startupData->m_scriptURL, startupData->m_userAgent, thread, startupData->m_workerClients.release()));
context->applyContentSecurityPolicyFromString(startupData->m_contentSecurityPolicy, startupData->m_contentSecurityPolicyType);
return context.release();
}
-SharedWorkerGlobalScope::SharedWorkerGlobalScope(const String& name, const KURL& url, const String& userAgent, SharedWorkerThread* thread, PassOwnPtr<WorkerClients> workerClients)
+SharedWorkerGlobalScope::SharedWorkerGlobalScope(const String& name, const KURL& url, const String& userAgent, SharedWorkerThread* thread, PassOwnPtrWillBeRawPtr<WorkerClients> workerClients)
: WorkerGlobalScope(url, userAgent, thread, monotonicallyIncreasingTime(), workerClients)
, m_name(name)
{
@@ -79,10 +78,15 @@ SharedWorkerThread* SharedWorkerGlobalScope::thread()
return static_cast<SharedWorkerThread*>(Base::thread());
}
-void SharedWorkerGlobalScope::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack> callStack)
+void SharedWorkerGlobalScope::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
{
WorkerGlobalScope::logExceptionToConsole(errorMessage, sourceURL, lineNumber, columnNumber, callStack);
addMessageToWorkerConsole(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, callStack, 0);
}
+void SharedWorkerGlobalScope::trace(Visitor* visitor)
+{
+ WorkerGlobalScope::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h
index a87e0a683a0..2672224e0cd 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.h
@@ -31,19 +31,20 @@
#ifndef SharedWorkerGlobalScope_h
#define SharedWorkerGlobalScope_h
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerThreadStartupData.h"
+#include "platform/heap/Handle.h"
namespace WebCore {
class MessageEvent;
class SharedWorkerThread;
- class SharedWorkerGlobalScope : public WorkerGlobalScope {
+ class SharedWorkerGlobalScope FINAL : public WorkerGlobalScope {
public:
typedef WorkerGlobalScope Base;
- static PassRefPtr<SharedWorkerGlobalScope> create(const String& name, SharedWorkerThread*, PassOwnPtr<WorkerThreadStartupData>);
+ static PassRefPtrWillBeRawPtr<SharedWorkerGlobalScope> create(const String& name, SharedWorkerThread*, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
virtual ~SharedWorkerGlobalScope();
virtual bool isSharedWorkerGlobalScope() const OVERRIDE { return true; }
@@ -57,14 +58,16 @@ namespace WebCore {
SharedWorkerThread* thread();
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- SharedWorkerGlobalScope(const String& name, const KURL&, const String& userAgent, SharedWorkerThread*, PassOwnPtr<WorkerClients>);
- virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) OVERRIDE;
+ SharedWorkerGlobalScope(const String& name, const KURL&, const String& userAgent, SharedWorkerThread*, PassOwnPtrWillBeRawPtr<WorkerClients>);
+ virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>) OVERRIDE;
String m_name;
};
- PassRefPtr<MessageEvent> createConnectEvent(PassRefPtr<MessagePort>);
+ PassRefPtrWillBeRawPtr<MessageEvent> createConnectEvent(PassRefPtrWillBeRawPtr<MessagePort>);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.idl b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.idl
index dcb59b82fa8..e2a7f55472b 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.idl
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerGlobalScope.idl
@@ -29,7 +29,8 @@
*/
[
- GlobalContext=SharedWorkerGlobalScope
+ Exposed=SharedWorker,
+ Global=Worker&SharedWorker
] interface SharedWorkerGlobalScope : WorkerGlobalScope {
readonly attribute DOMString name;
attribute EventHandler onconnect;
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
index 607bc294264..58dd0641c1d 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerRepositoryClient.h
@@ -31,6 +31,7 @@
#ifndef SharedWorkerRepositoryClient_h
#define SharedWorkerRepositoryClient_h
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
@@ -51,7 +52,7 @@ public:
SharedWorkerRepositoryClient() { }
virtual ~SharedWorkerRepositoryClient() { }
- virtual void connect(PassRefPtr<SharedWorker>, PassOwnPtr<blink::WebMessagePortChannel>, const KURL&, const String& name, ExceptionState&) = 0;
+ virtual void connect(PassRefPtrWillBeRawPtr<SharedWorker>, PassOwnPtr<blink::WebMessagePortChannel>, const KURL&, const String& name, ExceptionState&) = 0;
virtual void documentDetached(Document*) = 0;
};
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp
index 117b5837585..267b26ac605 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp
@@ -37,12 +37,12 @@
namespace WebCore {
-PassRefPtr<SharedWorkerThread> SharedWorkerThread::create(const String& name, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtr<SharedWorkerThread> SharedWorkerThread::create(const String& name, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
{
return adoptRef(new SharedWorkerThread(name, workerLoaderProxy, workerReportingProxy, startupData));
}
-SharedWorkerThread::SharedWorkerThread(const String& name, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> startupData)
+SharedWorkerThread::SharedWorkerThread(const String& name, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
: WorkerThread(workerLoaderProxy, workerReportingProxy, startupData)
, m_name(name.isolatedCopy())
{
@@ -52,7 +52,7 @@ SharedWorkerThread::~SharedWorkerThread()
{
}
-PassRefPtr<WorkerGlobalScope> SharedWorkerThread::createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtrWillBeRawPtr<WorkerGlobalScope> SharedWorkerThread::createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
{
return SharedWorkerGlobalScope::create(m_name, this, startupData);
}
diff --git a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.h b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.h
index ca1f15e7b95..46cb8738a6b 100644
--- a/chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.h
+++ b/chromium/third_party/WebKit/Source/core/workers/SharedWorkerThread.h
@@ -30,23 +30,23 @@
#ifndef SharedWorkerThread_h
#define SharedWorkerThread_h
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/workers/WorkerThread.h"
namespace WebCore {
-struct WorkerThreadStartupData;
+class WorkerThreadStartupData;
class SharedWorkerThread : public WorkerThread {
public:
- static PassRefPtr<SharedWorkerThread> create(const String& name, WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtr<WorkerThreadStartupData>);
+ static PassRefPtr<SharedWorkerThread> create(const String& name, WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
virtual ~SharedWorkerThread();
protected:
- virtual PassRefPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData>) OVERRIDE;
+ virtual PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>) OVERRIDE;
private:
- SharedWorkerThread(const String& name, WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtr<WorkerThreadStartupData>);
+ SharedWorkerThread(const String& name, WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
String m_name;
};
diff --git a/chromium/third_party/WebKit/Source/core/workers/Worker.cpp b/chromium/third_party/WebKit/Source/core/workers/Worker.cpp
index cd1d10228e4..603581fc11a 100644
--- a/chromium/third_party/WebKit/Source/core/workers/Worker.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/Worker.cpp
@@ -33,7 +33,7 @@
#include "core/events/MessageEvent.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/UseCounter.h"
#include "core/workers/WorkerGlobalScopeProxy.h"
#include "core/workers/WorkerGlobalScopeProxyProvider.h"
@@ -50,28 +50,31 @@ inline Worker::Worker(ExecutionContext* context)
ScriptWrappable::init(this);
}
-PassRefPtr<Worker> Worker::create(ExecutionContext* context, const String& url, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Worker> Worker::create(ExecutionContext* context, const String& url, ExceptionState& exceptionState)
{
ASSERT(isMainThread());
Document* document = toDocument(context);
- UseCounter::count(document->domWindow(), UseCounter::WorkerStart);
- ASSERT(document->page());
- WorkerGlobalScopeProxyProvider* proxyProvider = WorkerGlobalScopeProxyProvider::from(document->page());
+ UseCounter::count(context, UseCounter::WorkerStart);
+ if (!document->page()) {
+ exceptionState.throwDOMException(InvalidAccessError, "The context provided is invalid.");
+ return nullptr;
+ }
+ WorkerGlobalScopeProxyProvider* proxyProvider = WorkerGlobalScopeProxyProvider::from(*document->page());
ASSERT(proxyProvider);
- RefPtr<Worker> worker = adoptRef(new Worker(context));
+ RefPtrWillBeRawPtr<Worker> worker = adoptRefWillBeRefCountedGarbageCollected(new Worker(context));
worker->suspendIfNeeded();
KURL scriptURL = worker->resolveURL(url, exceptionState);
if (scriptURL.isEmpty())
- return 0;
+ return nullptr;
// The worker context does not exist while loading, so we must ensure that the worker object is not collected, nor are its event listeners.
worker->setPendingActivity(worker.get());
worker->m_scriptLoader = WorkerScriptLoader::create();
- worker->m_scriptLoader->loadAsynchronously(context, scriptURL, DenyCrossOriginRequests, worker.get());
+ worker->m_scriptLoader->loadAsynchronously(*context, scriptURL, DenyCrossOriginRequests, worker.get());
worker->m_contextProxy = proxyProvider->createWorkerGlobalScopeProxy(worker.get());
return worker.release();
}
@@ -100,7 +103,8 @@ void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, const Messag
void Worker::terminate()
{
- m_contextProxy->terminateWorkerGlobalScope();
+ if (m_contextProxy)
+ m_contextProxy->terminateWorkerGlobalScope();
}
void Worker::stop()
@@ -134,4 +138,9 @@ void Worker::notifyFinished()
unsetPendingActivity(this);
}
+void Worker::trace(Visitor* visitor)
+{
+ AbstractWorker::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/Worker.h b/chromium/third_party/WebKit/Source/core/workers/Worker.h
index 6271fae48ec..c02da6dd97a 100644
--- a/chromium/third_party/WebKit/Source/core/workers/Worker.h
+++ b/chromium/third_party/WebKit/Source/core/workers/Worker.h
@@ -31,9 +31,9 @@
#include "core/dom/MessagePort.h"
#include "core/events/EventListener.h"
#include "core/events/EventTarget.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/workers/AbstractWorker.h"
#include "core/workers/WorkerScriptLoaderClient.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
@@ -46,9 +46,9 @@ class ExecutionContext;
class WorkerGlobalScopeProxy;
class WorkerScriptLoader;
-class Worker : public AbstractWorker, public ScriptWrappable, private WorkerScriptLoaderClient {
+class Worker FINAL : public AbstractWorker, public ScriptWrappable, private WorkerScriptLoaderClient {
public:
- static PassRefPtr<Worker> create(ExecutionContext*, const String& url, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<Worker> create(ExecutionContext*, const String& url, ExceptionState&);
virtual ~Worker();
virtual const AtomicString& interfaceName() const OVERRIDE;
@@ -62,6 +62,8 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit Worker(ExecutionContext*);
diff --git a/chromium/third_party/WebKit/Source/core/workers/Worker.idl b/chromium/third_party/WebKit/Source/core/workers/Worker.idl
index 6017569bee9..f4944737f16 100644
--- a/chromium/third_party/WebKit/Source/core/workers/Worker.idl
+++ b/chromium/third_party/WebKit/Source/core/workers/Worker.idl
@@ -30,11 +30,12 @@
Constructor(DOMString scriptUrl),
ConstructorCallWith=ExecutionContext,
RaisesException=Constructor,
+ WillBeGarbageCollected,
] interface Worker : EventTarget {
attribute EventHandler onmessage;
- [Custom, RaisesException] void postMessage(SerializedScriptValue message, optional Array messagePorts);
+ [Custom, RaisesException] void postMessage(SerializedScriptValue message, optional MessagePort[] messagePorts);
void terminate();
};
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerClients.h b/chromium/third_party/WebKit/Source/core/workers/WorkerClients.h
index 8cc4aa2ff55..e81e928122a 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerClients.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerClients.h
@@ -39,16 +39,22 @@ namespace WebCore {
// This is created on the main thread, passed to the worker thread and
// attached to WorkerGlobalScope when it is created.
// This class can be used to provide "client" implementations to Workers.
-class WorkerClients : public Supplementable<WorkerClients> {
+class WorkerClients : public NoBaseWillBeGarbageCollectedFinalized<WorkerClients>, public WillBeHeapSupplementable<WorkerClients> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WorkerClients);
WTF_MAKE_NONCOPYABLE(WorkerClients);
public:
- static PassOwnPtr<WorkerClients> create()
+ static PassOwnPtrWillBeRawPtr<WorkerClients> create()
{
- return adoptPtr(new WorkerClients());
+ return adoptPtrWillBeNoop(new WorkerClients());
}
virtual ~WorkerClients() { }
+ virtual void trace(Visitor* visitor) OVERRIDE
+ {
+ WillBeHeapSupplementable<WorkerClients>::trace(visitor);
+ }
+
private:
WorkerClients() { }
};
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerConsole.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerConsole.cpp
index f4a819e4dd0..6d7b60f18dd 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerConsole.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerConsole.cpp
@@ -49,7 +49,7 @@ WorkerConsole::~WorkerConsole()
{
}
-void WorkerConsole::reportMessageToClient(MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack)
+void WorkerConsole::reportMessageToClient(MessageLevel level, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack)
{
const ScriptCallFrame& lastCaller = callStack->at(0);
m_scope->thread()->workerReportingProxy().reportConsoleMessage(ConsoleAPIMessageSource, level, message, lastCaller.lineNumber(), lastCaller.sourceURL());
@@ -62,6 +62,12 @@ ExecutionContext* WorkerConsole::context()
return m_scope->executionContext();
}
+void WorkerConsole::trace(Visitor* visitor)
+{
+ visitor->trace(m_scope);
+ ConsoleBase::trace(visitor);
+}
+
// FIXME: add memory getter
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerConsole.h b/chromium/third_party/WebKit/Source/core/workers/WorkerConsole.h
index 8d51b99c30c..0f45e3bdf77 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerConsole.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerConsole.h
@@ -34,6 +34,8 @@
#include "core/inspector/ConsoleAPITypes.h"
#include "core/frame/ConsoleBase.h"
#include "core/frame/ConsoleTypes.h"
+#include "core/workers/WorkerGlobalScope.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -43,25 +45,24 @@ namespace WebCore {
class ScriptArguments;
-class WorkerConsole : public RefCounted<WorkerConsole>, public ConsoleBase, public ScriptWrappable {
+class WorkerConsole FINAL : public ConsoleBase, public ScriptWrappable {
public:
- using RefCounted<WorkerConsole>::ref;
- using RefCounted<WorkerConsole>::deref;
-
- static PassRefPtr<WorkerConsole> create(WorkerGlobalScope* scope) { return adoptRef(new WorkerConsole(scope)); }
+ static PassRefPtrWillBeRawPtr<WorkerConsole> create(WorkerGlobalScope* scope)
+ {
+ return adoptRefWillBeNoop(new WorkerConsole(scope));
+ }
virtual ~WorkerConsole();
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
- virtual ExecutionContext* context();
- virtual void reportMessageToClient(MessageLevel, const String& message, PassRefPtr<ScriptCallStack>) OVERRIDE;
+ virtual ExecutionContext* context() OVERRIDE;
+ virtual void reportMessageToClient(MessageLevel, const String& message, PassRefPtrWillBeRawPtr<ScriptCallStack>) OVERRIDE;
private:
explicit WorkerConsole(WorkerGlobalScope*);
- virtual void refConsole() { ref(); }
- virtual void derefConsole() { deref(); }
-
- WorkerGlobalScope* m_scope;
+ RawPtrWillBeMember<WorkerGlobalScope> m_scope;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.cpp
index 6e9d01fde74..a705b81e2fc 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.cpp
@@ -30,12 +30,13 @@
#include "core/dom/ExecutionContext.h"
#include "core/dom/ExecutionContextTask.h"
#include "core/events/Event.h"
+#include "core/inspector/InspectorInstrumentation.h"
namespace WebCore {
-PassOwnPtr<WorkerEventQueue> WorkerEventQueue::create(ExecutionContext* context)
+PassOwnPtrWillBeRawPtr<WorkerEventQueue> WorkerEventQueue::create(ExecutionContext* context)
{
- return adoptPtr(new WorkerEventQueue(context));
+ return adoptPtrWillBeNoop(new WorkerEventQueue(context));
}
WorkerEventQueue::WorkerEventQueue(ExecutionContext* context)
@@ -46,12 +47,19 @@ WorkerEventQueue::WorkerEventQueue(ExecutionContext* context)
WorkerEventQueue::~WorkerEventQueue()
{
- close();
+ ASSERT(m_eventTaskMap.isEmpty());
+}
+
+void WorkerEventQueue::trace(Visitor* visitor)
+{
+ visitor->trace(m_executionContext);
+ visitor->trace(m_eventTaskMap);
+ EventQueue::trace(visitor);
}
class WorkerEventQueue::EventDispatcherTask : public ExecutionContextTask {
public:
- static PassOwnPtr<EventDispatcherTask> create(PassRefPtr<Event> event, WorkerEventQueue* eventQueue)
+ static PassOwnPtr<EventDispatcherTask> create(PassRefPtrWillBeRawPtr<Event> event, WorkerEventQueue* eventQueue)
{
return adoptPtr(new EventDispatcherTask(event, eventQueue));
}
@@ -62,7 +70,7 @@ public:
m_eventQueue->removeEvent(m_event.get());
}
- void dispatchEvent(ExecutionContext*, PassRefPtr<Event> event)
+ void dispatchEvent(ExecutionContext*, PassRefPtrWillBeRawPtr<Event> event)
{
event->target()->dispatchEvent(event);
}
@@ -83,28 +91,30 @@ public:
}
private:
- EventDispatcherTask(PassRefPtr<Event> event, WorkerEventQueue* eventQueue)
+ EventDispatcherTask(PassRefPtrWillBeRawPtr<Event> event, WorkerEventQueue* eventQueue)
: m_event(event)
, m_eventQueue(eventQueue)
, m_isCancelled(false)
{
}
- RefPtr<Event> m_event;
+ RefPtrWillBePersistent<Event> m_event;
WorkerEventQueue* m_eventQueue;
bool m_isCancelled;
};
void WorkerEventQueue::removeEvent(Event* event)
{
+ InspectorInstrumentation::didRemoveEvent(event->target(), event);
m_eventTaskMap.remove(event);
}
-bool WorkerEventQueue::enqueueEvent(PassRefPtr<Event> prpEvent)
+bool WorkerEventQueue::enqueueEvent(PassRefPtrWillBeRawPtr<Event> prpEvent)
{
if (m_isClosed)
return false;
- RefPtr<Event> event = prpEvent;
+ RefPtrWillBeRawPtr<Event> event = prpEvent;
+ InspectorInstrumentation::didEnqueueEvent(event->target(), event.get());
OwnPtr<EventDispatcherTask> task = EventDispatcherTask::create(event, this);
m_eventTaskMap.add(event.release(), task.get());
m_executionContext->postTask(task.release());
@@ -125,7 +135,9 @@ void WorkerEventQueue::close()
{
m_isClosed = true;
for (EventTaskMap::iterator it = m_eventTaskMap.begin(); it != m_eventTaskMap.end(); ++it) {
+ Event* event = it->key.get();
EventDispatcherTask* task = it->value;
+ InspectorInstrumentation::didRemoveEvent(event->target(), event);
task->cancel();
}
m_eventTaskMap.clear();
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.h b/chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.h
index 6a669019fd6..a0ac56f9617 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerEventQueue.h
@@ -39,15 +39,16 @@ class Event;
class Node;
class ExecutionContext;
-class WorkerEventQueue : public EventQueue {
- WTF_MAKE_FAST_ALLOCATED;
+class WorkerEventQueue FINAL : public EventQueue {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<WorkerEventQueue> create(ExecutionContext*);
+ static PassOwnPtrWillBeRawPtr<WorkerEventQueue> create(ExecutionContext*);
virtual ~WorkerEventQueue();
+ void trace(Visitor*);
// EventQueue
- virtual bool enqueueEvent(PassRefPtr<Event>) OVERRIDE;
+ virtual bool enqueueEvent(PassRefPtrWillBeRawPtr<Event>) OVERRIDE;
virtual bool cancelEvent(Event*) OVERRIDE;
virtual void close() OVERRIDE;
@@ -55,11 +56,11 @@ private:
explicit WorkerEventQueue(ExecutionContext*);
void removeEvent(Event*);
- ExecutionContext* m_executionContext;
+ RawPtrWillBeMember<ExecutionContext> m_executionContext;
bool m_isClosed;
class EventDispatcherTask;
- typedef HashMap<RefPtr<Event>, EventDispatcherTask*> EventTaskMap;
+ typedef WillBeHeapHashMap<RefPtrWillBeMember<Event>, EventDispatcherTask*> EventTaskMap;
EventTaskMap m_eventTaskMap;
};
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
index cd8daa3ef8a..1b89c2ea747 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -44,13 +44,16 @@
#include "core/inspector/ScriptCallStack.h"
#include "core/inspector/WorkerInspectorController.h"
#include "core/loader/WorkerThreadableLoader.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/workers/WorkerNavigator.h"
#include "core/workers/WorkerClients.h"
+#include "core/workers/WorkerConsole.h"
#include "core/workers/WorkerLocation.h"
+#include "core/workers/WorkerNavigator.h"
#include "core/workers/WorkerReportingProxy.h"
#include "core/workers/WorkerScriptLoader.h"
#include "core/workers/WorkerThread.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
#include "platform/weborigin/KURL.h"
#include "platform/weborigin/SecurityOrigin.h"
@@ -73,7 +76,7 @@ public:
virtual bool isCleanupTask() const { return true; }
};
-WorkerGlobalScope::WorkerGlobalScope(const KURL& url, const String& userAgent, WorkerThread* thread, double timeOrigin, PassOwnPtr<WorkerClients> workerClients)
+WorkerGlobalScope::WorkerGlobalScope(const KURL& url, const String& userAgent, WorkerThread* thread, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerClients> workerClients)
: m_url(url)
, m_userAgent(userAgent)
, m_script(adoptPtr(new WorkerScriptController(*this)))
@@ -83,33 +86,22 @@ WorkerGlobalScope::WorkerGlobalScope(const KURL& url, const String& userAgent, W
, m_eventQueue(WorkerEventQueue::create(this))
, m_workerClients(workerClients)
, m_timeOrigin(timeOrigin)
+ , m_terminationObserver(0)
{
ScriptWrappable::init(this);
setClient(this);
setSecurityOrigin(SecurityOrigin::create(url));
m_workerClients->reattachThread();
-
- // Notify proxy that a new WorkerGlobalScope has been created and started.
- this->thread()->workerReportingProxy().workerGlobalScopeStarted();
}
WorkerGlobalScope::~WorkerGlobalScope()
{
- ASSERT(thread()->isCurrentThread());
-
- // Make sure we have no observers.
- notifyObserversOfStop();
-
- // Notify proxy that we are going away. This can free the WorkerThread object, so do not access it after this.
- thread()->workerReportingProxy().workerGlobalScopeDestroyed();
-
- setClient(0);
}
-void WorkerGlobalScope::applyContentSecurityPolicyFromString(const String& policy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType)
+void WorkerGlobalScope::applyContentSecurityPolicyFromString(const String& policy, ContentSecurityPolicyHeaderType contentSecurityPolicyType)
{
setContentSecurityPolicy(ContentSecurityPolicy::create(this));
- contentSecurityPolicy()->didReceiveHeader(policy, contentSecurityPolicyType);
+ contentSecurityPolicy()->didReceiveHeader(policy, contentSecurityPolicyType, ContentSecurityPolicyHeaderSourceHTTP);
}
ExecutionContext* WorkerGlobalScope::executionContext() const
@@ -195,17 +187,62 @@ void WorkerGlobalScope::clearInspector()
m_workerInspectorController.clear();
}
+void WorkerGlobalScope::registerTerminationObserver(TerminationObserver* observer)
+{
+ ASSERT(!m_terminationObserver);
+ ASSERT(observer);
+ m_terminationObserver = observer;
+}
+
+void WorkerGlobalScope::unregisterTerminationObserver(TerminationObserver* observer)
+{
+ ASSERT(observer);
+ ASSERT(m_terminationObserver == observer);
+ m_terminationObserver = 0;
+}
+
+void WorkerGlobalScope::wasRequestedToTerminate()
+{
+ if (m_terminationObserver)
+ m_terminationObserver->wasRequestedToTerminate();
+}
+
+void WorkerGlobalScope::dispose()
+{
+ ASSERT(thread()->isCurrentThread());
+
+ m_eventQueue->close();
+ clearScript();
+ clearInspector();
+ setClient(0);
+
+ // We do not clear the thread field of the
+ // WorkerGlobalScope. Other objects keep the worker global scope
+ // alive because they need its thread field to check that work is
+ // being carried out on the right thread. We therefore cannot clear
+ // the thread field before all references to the worker global
+ // scope are gone.
+}
+
void WorkerGlobalScope::importScripts(const Vector<String>& urls, ExceptionState& exceptionState)
{
ASSERT(contentSecurityPolicy());
+ ASSERT(executionContext());
+
+ ExecutionContext& executionContext = *this->executionContext();
+
Vector<String>::const_iterator urlsEnd = urls.end();
Vector<KURL> completedURLs;
for (Vector<String>::const_iterator it = urls.begin(); it != urlsEnd; ++it) {
- const KURL& url = executionContext()->completeURL(*it);
+ const KURL& url = executionContext.completeURL(*it);
if (!url.isValid()) {
exceptionState.throwDOMException(SyntaxError, "The URL '" + *it + "' is invalid.");
return;
}
+ if (!contentSecurityPolicy()->allowScriptFromSource(url)) {
+ exceptionState.throwDOMException(NetworkError, "The script at '" + url.elidedString() + "' failed to load.");
+ return;
+ }
completedURLs.append(url);
}
Vector<KURL>::const_iterator end = completedURLs.end();
@@ -213,7 +250,7 @@ void WorkerGlobalScope::importScripts(const Vector<String>& urls, ExceptionState
for (Vector<KURL>::const_iterator it = completedURLs.begin(); it != end; ++it) {
RefPtr<WorkerScriptLoader> scriptLoader(WorkerScriptLoader::create());
scriptLoader->setTargetType(ResourceRequest::TargetIsScript);
- scriptLoader->loadSynchronously(executionContext(), *it, AllowCrossOriginRequests);
+ scriptLoader->loadSynchronously(executionContext, *it, AllowCrossOriginRequests);
// If the fetching attempt failed, throw a NetworkError exception and abort all these steps.
if (scriptLoader->failed()) {
@@ -221,9 +258,9 @@ void WorkerGlobalScope::importScripts(const Vector<String>& urls, ExceptionState
return;
}
- InspectorInstrumentation::scriptImported(executionContext(), scriptLoader->identifier(), scriptLoader->script());
+ InspectorInstrumentation::scriptImported(&executionContext, scriptLoader->identifier(), scriptLoader->script());
- RefPtr<ErrorEvent> errorEvent;
+ RefPtrWillBeRawPtr<ErrorEvent> errorEvent = nullptr;
m_script->evaluate(ScriptSourceCode(scriptLoader->script(), scriptLoader->responseURL()), &errorEvent);
if (errorEvent) {
m_script->rethrowExceptionFromImportedScript(errorEvent.release());
@@ -237,7 +274,7 @@ EventTarget* WorkerGlobalScope::errorEventTarget()
return this;
}
-void WorkerGlobalScope::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>)
+void WorkerGlobalScope::logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>)
{
thread()->workerReportingProxy().reportException(errorMessage, lineNumber, columnNumber, sourceURL);
}
@@ -247,23 +284,23 @@ void WorkerGlobalScope::reportBlockedScriptExecutionToInspector(const String& di
InspectorInstrumentation::scriptExecutionBlockedByCSP(this, directiveText);
}
-void WorkerGlobalScope::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* state)
+void WorkerGlobalScope::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* scriptState)
{
if (!isContextThread()) {
postTask(AddConsoleMessageTask::create(source, level, message));
return;
}
thread()->workerReportingProxy().reportConsoleMessage(source, level, message, lineNumber, sourceURL);
- addMessageToWorkerConsole(source, level, message, sourceURL, lineNumber, 0, state);
+ addMessageToWorkerConsole(source, level, message, sourceURL, lineNumber, nullptr, scriptState);
}
-void WorkerGlobalScope::addMessageToWorkerConsole(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack> callStack, ScriptState* state)
+void WorkerGlobalScope::addMessageToWorkerConsole(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack, ScriptState* scriptState)
{
ASSERT(isContextThread());
if (callStack)
InspectorInstrumentation::addMessageToConsole(this, source, LogMessageType, level, message, callStack);
else
- InspectorInstrumentation::addMessageToConsole(this, source, LogMessageType, level, message, sourceURL, lineNumber, 0, state);
+ InspectorInstrumentation::addMessageToConsole(this, source, LogMessageType, level, message, sourceURL, lineNumber, 0, scriptState);
}
bool WorkerGlobalScope::isContextThread() const
@@ -276,61 +313,36 @@ bool WorkerGlobalScope::isJSExecutionForbidden() const
return m_script->isExecutionForbidden();
}
-WorkerGlobalScope::Observer::Observer(WorkerGlobalScope* context)
- : m_context(context)
-{
- ASSERT(m_context && m_context->isContextThread());
- m_context->registerObserver(this);
-}
-
-WorkerGlobalScope::Observer::~Observer()
-{
- if (!m_context)
- return;
- ASSERT(m_context->isContextThread());
- m_context->unregisterObserver(this);
-}
-
-void WorkerGlobalScope::Observer::stopObserving()
-{
- if (!m_context)
- return;
- ASSERT(m_context->isContextThread());
- m_context->unregisterObserver(this);
- m_context = 0;
-}
-
-void WorkerGlobalScope::registerObserver(Observer* observer)
+bool WorkerGlobalScope::idleNotification()
{
- ASSERT(observer);
- m_workerObservers.add(observer);
+ return script()->idleNotification();
}
-void WorkerGlobalScope::unregisterObserver(Observer* observer)
+WorkerEventQueue* WorkerGlobalScope::eventQueue() const
{
- ASSERT(observer);
- m_workerObservers.remove(observer);
+ return m_eventQueue.get();
}
-void WorkerGlobalScope::notifyObserversOfStop()
+void WorkerGlobalScope::countFeature(UseCounter::Feature) const
{
- HashSet<Observer*>::iterator iter = m_workerObservers.begin();
- while (iter != m_workerObservers.end()) {
- WorkerGlobalScope::Observer* observer = *iter;
- observer->stopObserving();
- observer->notifyStop();
- iter = m_workerObservers.begin();
- }
+ // FIXME: How should we count features for shared/service workers?
}
-bool WorkerGlobalScope::idleNotification()
+void WorkerGlobalScope::countDeprecation(UseCounter::Feature) const
{
- return script()->idleNotification();
+ // FIXME: How should we count features for shared/service workers?
}
-WorkerEventQueue* WorkerGlobalScope::eventQueue() const
+void WorkerGlobalScope::trace(Visitor* visitor)
{
- return m_eventQueue.get();
+ visitor->trace(m_console);
+ visitor->trace(m_location);
+ visitor->trace(m_navigator);
+ visitor->trace(m_eventQueue);
+ visitor->trace(m_workerClients);
+ WillBeHeapSupplementable<WorkerGlobalScope>::trace(visitor);
+ ExecutionContext::trace(visitor);
+ EventTargetWithInlineData::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
index 8bbc43e3c64..5163ade3072 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -32,11 +32,12 @@
#include "core/dom/ExecutionContext.h"
#include "core/events/EventListener.h"
#include "core/events/EventTarget.h"
-#include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/workers/WorkerConsole.h"
+#include "core/frame/DOMWindowBase64.h"
+#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/workers/WorkerEventQueue.h"
-#include "core/workers/WorkerSupplementable.h"
+#include "platform/heap/Handle.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
#include "wtf/Assertions.h"
#include "wtf/HashMap.h"
#include "wtf/OwnPtr.h"
@@ -48,7 +49,6 @@
namespace WebCore {
class Blob;
- class DOMURL;
class ExceptionState;
class ScheduledAction;
class WorkerClients;
@@ -58,32 +58,48 @@ namespace WebCore {
class WorkerNavigator;
class WorkerThread;
- class WorkerGlobalScope : public RefCounted<WorkerGlobalScope>, public ScriptWrappable, public SecurityContext, public ExecutionContext, public ExecutionContextClient, public WorkerSupplementable, public EventTargetWithInlineData {
+ class WorkerGlobalScope : public RefCountedWillBeRefCountedGarbageCollected<WorkerGlobalScope>, public ScriptWrappable, public SecurityContext, public ExecutionContext, public ExecutionContextClient, public WillBeHeapSupplementable<WorkerGlobalScope>, public EventTargetWithInlineData, public DOMWindowBase64 {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WorkerGlobalScope);
REFCOUNTED_EVENT_TARGET(WorkerGlobalScope);
public:
virtual ~WorkerGlobalScope();
- virtual bool isWorkerGlobalScope() const OVERRIDE { return true; }
+ virtual bool isWorkerGlobalScope() const OVERRIDE FINAL { return true; }
- virtual ExecutionContext* executionContext() const OVERRIDE;
+ virtual ExecutionContext* executionContext() const OVERRIDE FINAL;
virtual bool isSharedWorkerGlobalScope() const { return false; }
virtual bool isDedicatedWorkerGlobalScope() const { return false; }
virtual bool isServiceWorkerGlobalScope() const { return false; }
+ virtual void countFeature(UseCounter::Feature) const;
+ virtual void countDeprecation(UseCounter::Feature) const;
const KURL& url() const { return m_url; }
KURL completeURL(const String&) const;
- virtual String userAgent(const KURL&) const;
- virtual void disableEval(const String& errorMessage) OVERRIDE;
+ virtual String userAgent(const KURL&) const OVERRIDE FINAL;
+ virtual void disableEval(const String& errorMessage) OVERRIDE FINAL;
WorkerScriptController* script() { return m_script.get(); }
void clearScript() { m_script.clear(); }
void clearInspector();
+ // FIXME: We can remove this interface when we remove openDatabaseSync.
+ class TerminationObserver {
+ public:
+ virtual ~TerminationObserver() { }
+ // The function is probably called in the main thread.
+ virtual void wasRequestedToTerminate() = 0;
+ };
+ void registerTerminationObserver(TerminationObserver*);
+ void unregisterTerminationObserver(TerminationObserver*);
+ void wasRequestedToTerminate();
+
+ void dispose();
+
WorkerThread* thread() const { return m_thread; }
- virtual void postTask(PassOwnPtr<ExecutionContextTask>) OVERRIDE; // Executes the task on context's thread asynchronously.
+ virtual void postTask(PassOwnPtr<ExecutionContextTask>) OVERRIDE FINAL; // Executes the task on context's thread asynchronously.
// WorkerGlobalScope
WorkerGlobalScope* self() { return this; }
@@ -98,38 +114,19 @@ namespace WebCore {
WorkerNavigator* navigator() const;
// ExecutionContextClient
- virtual WorkerEventQueue* eventQueue() const OVERRIDE;
- virtual SecurityContext& securityContext() OVERRIDE { return *this; }
+ virtual WorkerEventQueue* eventQueue() const OVERRIDE FINAL;
+ virtual SecurityContext& securityContext() OVERRIDE FINAL { return *this; }
- virtual bool isContextThread() const OVERRIDE;
- virtual bool isJSExecutionForbidden() const OVERRIDE;
+ virtual bool isContextThread() const OVERRIDE FINAL;
+ virtual bool isJSExecutionForbidden() const OVERRIDE FINAL;
- virtual double timerAlignmentInterval() const OVERRIDE;
+ virtual double timerAlignmentInterval() const OVERRIDE FINAL;
WorkerInspectorController* workerInspectorController() { return m_workerInspectorController.get(); }
- // These methods are used for GC marking. See JSWorkerGlobalScope::visitChildrenVirtual(SlotVisitor&) in
- // JSWorkerGlobalScopeCustom.cpp.
- WorkerConsole* optionalConsole() const { return m_console.get(); }
- WorkerNavigator* optionalNavigator() const { return m_navigator.get(); }
- WorkerLocation* optionalLocation() const { return m_location.get(); }
bool isClosing() { return m_closing; }
- // An observer interface to be notified when the worker thread is getting stopped.
- class Observer {
- WTF_MAKE_NONCOPYABLE(Observer);
- public:
- Observer(WorkerGlobalScope*);
- virtual ~Observer();
- virtual void notifyStop() = 0;
- void stopObserving();
- private:
- WorkerGlobalScope* m_context;
- };
- friend class Observer;
- void registerObserver(Observer*);
- void unregisterObserver(Observer*);
- void notifyObserversOfStop();
+ virtual void stopFetch() { }
bool idleNotification();
@@ -140,47 +137,49 @@ namespace WebCore {
using SecurityContext::securityOrigin;
using SecurityContext::contentSecurityPolicy;
+ virtual void trace(Visitor*) OVERRIDE;
+
protected:
- WorkerGlobalScope(const KURL&, const String& userAgent, WorkerThread*, double timeOrigin, PassOwnPtr<WorkerClients>);
- void applyContentSecurityPolicyFromString(const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType);
+ WorkerGlobalScope(const KURL&, const String& userAgent, WorkerThread*, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerClients>);
+ void applyContentSecurityPolicyFromString(const String& contentSecurityPolicy, ContentSecurityPolicyHeaderType);
- virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) OVERRIDE;
- void addMessageToWorkerConsole(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack>, ScriptState*);
+ virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>) OVERRIDE;
+ void addMessageToWorkerConsole(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtrWillBeRawPtr<ScriptCallStack>, ScriptState*);
private:
- virtual void refExecutionContext() OVERRIDE { ref(); }
- virtual void derefExecutionContext() OVERRIDE { deref(); }
+#if !ENABLE(OILPAN)
+ virtual void refExecutionContext() OVERRIDE FINAL { ref(); }
+ virtual void derefExecutionContext() OVERRIDE FINAL { deref(); }
+#endif
- virtual const KURL& virtualURL() const OVERRIDE;
- virtual KURL virtualCompleteURL(const String&) const;
+ virtual const KURL& virtualURL() const OVERRIDE FINAL;
+ virtual KURL virtualCompleteURL(const String&) const OVERRIDE FINAL;
- virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) OVERRIDE;
- virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* = 0) OVERRIDE;
+ virtual void reportBlockedScriptExecutionToInspector(const String& directiveText) OVERRIDE FINAL;
+ virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* = 0) OVERRIDE FINAL;
- virtual EventTarget* errorEventTarget() OVERRIDE;
- virtual void didUpdateSecurityOrigin() OVERRIDE { }
+ virtual EventTarget* errorEventTarget() OVERRIDE FINAL;
+ virtual void didUpdateSecurityOrigin() OVERRIDE FINAL { }
KURL m_url;
String m_userAgent;
- mutable RefPtr<WorkerConsole> m_console;
- mutable RefPtr<WorkerLocation> m_location;
- mutable RefPtr<WorkerNavigator> m_navigator;
+ mutable RefPtrWillBeMember<WorkerConsole> m_console;
+ mutable RefPtrWillBeMember<WorkerLocation> m_location;
+ mutable RefPtrWillBeMember<WorkerNavigator> m_navigator;
OwnPtr<WorkerScriptController> m_script;
WorkerThread* m_thread;
- mutable RefPtr<DOMURL> m_domURL;
OwnPtr<WorkerInspectorController> m_workerInspectorController;
bool m_closing;
- HashSet<Observer*> m_workerObservers;
-
- OwnPtr<WorkerEventQueue> m_eventQueue;
+ OwnPtrWillBeMember<WorkerEventQueue> m_eventQueue;
- OwnPtr<WorkerClients> m_workerClients;
+ OwnPtrWillBeMember<WorkerClients> m_workerClients;
double m_timeOrigin;
+ TerminationObserver* m_terminationObserver;
};
DEFINE_TYPE_CASTS(WorkerGlobalScope, ExecutionContext, context, context->isWorkerGlobalScope(), context.isWorkerGlobalScope());
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
index d61d48f19d0..ced2f23a456 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScope.idl
@@ -26,7 +26,8 @@
[
Custom=ToV8,
- GlobalContext=WorkerGlobalScope,
+ Exposed=Worker,
+ WillBeGarbageCollected
] interface WorkerGlobalScope : EventTarget {
// WorkerGlobalScope
@@ -42,9 +43,8 @@
[Replaceable] readonly attribute WorkerNavigator navigator;
// Additional constructors
- attribute URLConstructor webkitURL; // FIXME: deprecate this.
+ [MeasureAs=PrefixedWorkerURL] attribute URLConstructor webkitURL; // FIXME: deprecate this.
};
-WorkerGlobalScope implements ImageBitmapFactories;
WorkerGlobalScope implements WindowBase64;
WorkerGlobalScope implements WindowTimers;
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp
index 3a539dfcfe1..a0e75d24d62 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp
@@ -29,13 +29,13 @@
*/
#include "config.h"
-#include "WorkerGlobalScopeProxyProvider.h"
+#include "core/workers/WorkerGlobalScopeProxyProvider.h"
namespace WebCore {
-WorkerGlobalScopeProxyProvider* WorkerGlobalScopeProxyProvider::from(Page* page)
+WorkerGlobalScopeProxyProvider* WorkerGlobalScopeProxyProvider::from(Page& page)
{
- return static_cast<WorkerGlobalScopeProxyProvider*>(Supplement<Page>::from(page, supplementName()));
+ return static_cast<WorkerGlobalScopeProxyProvider*>(WillBeHeapSupplement<Page>::from(page, supplementName()));
}
const char* WorkerGlobalScopeProxyProvider::supplementName()
@@ -43,9 +43,9 @@ const char* WorkerGlobalScopeProxyProvider::supplementName()
return "WorkerGlobalScopeProxyProvider";
}
-void provideWorkerGlobalScopeProxyProviderTo(Page* page, PassOwnPtr<WorkerGlobalScopeProxyProvider> provider)
+void provideWorkerGlobalScopeProxyProviderTo(Page& page, PassOwnPtrWillBeRawPtr<WorkerGlobalScopeProxyProvider> provider)
{
- Supplement<Page>::provideTo(page, WorkerGlobalScopeProxyProvider::supplementName(), provider);
+ WillBeHeapSupplement<Page>::provideTo(page, WorkerGlobalScopeProxyProvider::supplementName(), provider);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.h b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.h
index 54b5f47ab0d..1b1d1a78b86 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerGlobalScopeProxyProvider.h
@@ -42,7 +42,7 @@ namespace WebCore {
class WorkerGlobalScopeProxy;
class Worker;
-class WorkerGlobalScopeProxyProvider : public Supplement<Page> {
+class WorkerGlobalScopeProxyProvider : public WillBeHeapSupplement<Page> {
WTF_MAKE_NONCOPYABLE(WorkerGlobalScopeProxyProvider);
public:
WorkerGlobalScopeProxyProvider() { }
@@ -50,11 +50,11 @@ public:
virtual WorkerGlobalScopeProxy* createWorkerGlobalScopeProxy(Worker*) = 0;
- static WorkerGlobalScopeProxyProvider* from(Page*);
+ static WorkerGlobalScopeProxyProvider* from(Page&);
static const char* supplementName();
};
-void provideWorkerGlobalScopeProxyProviderTo(Page*, PassOwnPtr<WorkerGlobalScopeProxyProvider>);
+void provideWorkerGlobalScopeProxyProviderTo(Page&, PassOwnPtrWillBeRawPtr<WorkerGlobalScopeProxyProvider>);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerLoaderProxy.h b/chromium/third_party/WebKit/Source/core/workers/WorkerLoaderProxy.h
index 4cb40028fc6..c3ebc9ade6e 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerLoaderProxy.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerLoaderProxy.h
@@ -49,10 +49,9 @@ namespace WebCore {
// Posts a task to the thread which runs the loading code (normally, the main thread).
virtual void postTaskToLoader(PassOwnPtr<ExecutionContextTask>) = 0;
- // Posts callbacks from loading code to the WorkerGlobalScope. The 'mode' is used to differentiate
- // specific synchronous loading requests so they can be 'nested', per spec.
+ // Posts callbacks from loading code to the WorkerGlobalScope.
// Returns true if the task was posted successfully.
- virtual bool postTaskForModeToWorkerGlobalScope(PassOwnPtr<ExecutionContextTask>, const String& mode) = 0;
+ virtual bool postTaskToWorkerGlobalScope(PassOwnPtr<ExecutionContextTask>) = 0;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerLocation.h b/chromium/third_party/WebKit/Source/core/workers/WorkerLocation.h
index 6b5aefb7cf7..1768c986d5f 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerLocation.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerLocation.h
@@ -29,6 +29,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/DOMURLUtilsReadOnly.h"
+#include "platform/heap/Handle.h"
#include "platform/weborigin/KURL.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -37,11 +38,11 @@
namespace WebCore {
-class WorkerLocation FINAL : public RefCounted<WorkerLocation>, public ScriptWrappable, public DOMURLUtilsReadOnly {
+class WorkerLocation FINAL : public RefCountedWillBeGarbageCollectedFinalized<WorkerLocation>, public ScriptWrappable, public DOMURLUtilsReadOnly {
public:
- static PassRefPtr<WorkerLocation> create(const KURL& url)
+ static PassRefPtrWillBeRawPtr<WorkerLocation> create(const KURL& url)
{
- return adoptRef(new WorkerLocation(url));
+ return adoptRefWillBeNoop(new WorkerLocation(url));
}
virtual KURL url() const OVERRIDE { return m_url; }
@@ -51,6 +52,8 @@ public:
return String();
}
+ void trace(Visitor*) { }
+
private:
explicit WorkerLocation(const KURL& url) : m_url(url)
{
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerLocation.idl b/chromium/third_party/WebKit/Source/core/workers/WorkerLocation.idl
index c3dd851fede..252f3a71858 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerLocation.idl
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerLocation.idl
@@ -26,10 +26,12 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.w3.org/TR/workers/#workerlocation
[
- GlobalContext=WorkerGlobalScope
+ Exposed=Worker,
+ WillBeGarbageCollected,
] interface WorkerLocation {
};
-// force rebuild: crbug.com/307023
+// https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation
WorkerLocation implements URLUtilsReadOnly;
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.cpp
index a34d8e19b29..28132bf21cd 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.cpp
@@ -33,15 +33,14 @@
#include "core/dom/Document.h"
#include "core/events/ErrorEvent.h"
#include "core/events/MessageEvent.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalDOMWindow.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/inspector/InspectorInstrumentation.h"
#include "core/inspector/ScriptCallStack.h"
#include "core/inspector/WorkerDebuggerAgent.h"
#include "core/inspector/WorkerInspectorController.h"
#include "core/loader/DocumentLoadTiming.h"
#include "core/loader/DocumentLoader.h"
-#include "core/page/PageGroup.h"
#include "core/workers/DedicatedWorkerGlobalScope.h"
#include "core/workers/DedicatedWorkerThread.h"
#include "core/workers/Worker.h"
@@ -49,6 +48,7 @@
#include "core/workers/WorkerObjectProxy.h"
#include "core/workers/WorkerThreadStartupData.h"
#include "platform/NotImplemented.h"
+#include "platform/heap/Handle.h"
#include "wtf/Functional.h"
#include "wtf/MainThread.h"
@@ -82,7 +82,7 @@ private:
OwnPtr<MessagePortChannelArray> m_channels;
};
-WorkerMessagingProxy::WorkerMessagingProxy(Worker* workerObject, PassOwnPtr<WorkerClients> workerClients)
+WorkerMessagingProxy::WorkerMessagingProxy(Worker* workerObject, PassOwnPtrWillBeRawPtr<WorkerClients> workerClients)
: m_executionContext(workerObject->executionContext())
, m_workerObjectProxy(WorkerObjectProxy::create(m_executionContext.get(), this))
, m_workerObject(workerObject)
@@ -111,7 +111,7 @@ void WorkerMessagingProxy::startWorkerGlobalScope(const KURL& scriptURL, const S
ASSERT(m_executionContext->isDocument());
Document* document = toDocument(m_executionContext.get());
- OwnPtr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode, startMode, document->contentSecurityPolicy()->deprecatedHeader(), document->contentSecurityPolicy()->deprecatedHeaderType(), m_workerClients.release());
+ OwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode, startMode, document->contentSecurityPolicy()->deprecatedHeader(), document->contentSecurityPolicy()->deprecatedHeaderType(), m_workerClients.release());
double originTime = document->loader() ? document->loader()->timing()->referenceMonotonicTime() : monotonicallyIncreasingTime();
RefPtr<DedicatedWorkerThread> thread = DedicatedWorkerThread::create(*this, *m_workerObjectProxy.get(), originTime, startupData.release());
@@ -141,13 +141,13 @@ void WorkerMessagingProxy::postMessageToWorkerGlobalScope(PassRefPtr<SerializedS
m_queuedEarlyTasks.append(MessageWorkerGlobalScopeTask::create(message, channels));
}
-bool WorkerMessagingProxy::postTaskForModeToWorkerGlobalScope(PassOwnPtr<ExecutionContextTask> task, const String& mode)
+bool WorkerMessagingProxy::postTaskToWorkerGlobalScope(PassOwnPtr<ExecutionContextTask> task)
{
if (m_askedToTerminate)
return false;
ASSERT(m_workerThread);
- m_workerThread->runLoop().postTaskForMode(task, mode);
+ m_workerThread->runLoop().postTask(task);
return true;
}
@@ -166,10 +166,10 @@ void WorkerMessagingProxy::reportException(const String& errorMessage, int lineN
// We don't bother checking the askedToTerminate() flag here, because exceptions should *always* be reported even if the thread is terminated.
// This is intentionally different than the behavior in MessageWorkerTask, because terminated workers no longer deliver messages (section 4.6 of the WebWorker spec), but they do report exceptions.
- RefPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sourceURL, lineNumber, columnNumber, 0);
+ RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sourceURL, lineNumber, columnNumber, 0);
bool errorHandled = !m_workerObject->dispatchEvent(event);
if (!errorHandled)
- m_executionContext->reportException(event, 0, NotSharableCrossOrigin);
+ m_executionContext->reportException(event, nullptr, NotSharableCrossOrigin);
}
void WorkerMessagingProxy::reportConsoleMessage(MessageSource source, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
@@ -224,7 +224,7 @@ void WorkerMessagingProxy::connectToInspector(WorkerGlobalScopeProxy::PageInspec
return;
ASSERT(!m_pageInspector);
m_pageInspector = pageInspector;
- m_workerThread->runLoop().postTaskForMode(createCallbackTask(connectToWorkerGlobalScopeInspectorTask, true), WorkerDebuggerAgent::debuggerTaskMode);
+ m_workerThread->runLoop().postDebuggerTask(createCallbackTask(connectToWorkerGlobalScopeInspectorTask, true));
}
static void disconnectFromWorkerGlobalScopeInspectorTask(ExecutionContext* context, bool)
@@ -237,7 +237,7 @@ void WorkerMessagingProxy::disconnectFromInspector()
m_pageInspector = 0;
if (m_askedToTerminate)
return;
- m_workerThread->runLoop().postTaskForMode(createCallbackTask(disconnectFromWorkerGlobalScopeInspectorTask, true), WorkerDebuggerAgent::debuggerTaskMode);
+ m_workerThread->runLoop().postDebuggerTask(createCallbackTask(disconnectFromWorkerGlobalScopeInspectorTask, true));
}
static void dispatchOnInspectorBackendTask(ExecutionContext* context, const String& message)
@@ -249,7 +249,7 @@ void WorkerMessagingProxy::sendMessageToInspector(const String& message)
{
if (m_askedToTerminate)
return;
- m_workerThread->runLoop().postTaskForMode(createCallbackTask(dispatchOnInspectorBackendTask, String(message)), WorkerDebuggerAgent::debuggerTaskMode);
+ m_workerThread->runLoop().postDebuggerTask(createCallbackTask(dispatchOnInspectorBackendTask, String(message)));
WorkerDebuggerAgent::interruptAndDispatchInspectorCommands(m_workerThread.get());
}
@@ -258,7 +258,7 @@ void WorkerMessagingProxy::workerGlobalScopeDestroyed()
// This method is always the last to be performed, so the proxy is not needed for communication
// in either side any more. However, the Worker object may still exist, and it assumes that the proxy exists, too.
m_askedToTerminate = true;
- m_workerThread = 0;
+ m_workerThread = nullptr;
InspectorInstrumentation::workerGlobalScopeTerminated(m_executionContext.get(), this);
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.h b/chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.h
index c94337415a2..fb565ce3a08 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerMessagingProxy.h
@@ -45,10 +45,10 @@ namespace WebCore {
class Worker;
class WorkerClients;
- class WorkerMessagingProxy : public WorkerGlobalScopeProxy, public WorkerLoaderProxy {
+ class WorkerMessagingProxy FINAL : public WorkerGlobalScopeProxy, public WorkerLoaderProxy {
WTF_MAKE_NONCOPYABLE(WorkerMessagingProxy); WTF_MAKE_FAST_ALLOCATED;
public:
- WorkerMessagingProxy(Worker*, PassOwnPtr<WorkerClients>);
+ WorkerMessagingProxy(Worker*, PassOwnPtrWillBeRawPtr<WorkerClients>);
// Implementations of WorkerGlobalScopeProxy.
// (Only use these methods in the worker object thread.)
@@ -76,7 +76,7 @@ namespace WebCore {
// These methods are called on different threads to schedule loading
// requests and to send callbacks back to WorkerGlobalScope.
virtual void postTaskToLoader(PassOwnPtr<ExecutionContextTask>) OVERRIDE;
- virtual bool postTaskForModeToWorkerGlobalScope(PassOwnPtr<ExecutionContextTask>, const String& mode) OVERRIDE;
+ virtual bool postTaskToWorkerGlobalScope(PassOwnPtr<ExecutionContextTask>) OVERRIDE;
void workerThreadCreated(PassRefPtr<DedicatedWorkerThread>);
@@ -86,7 +86,7 @@ namespace WebCore {
private:
static void workerObjectDestroyedInternal(ExecutionContext*, WorkerMessagingProxy*);
- RefPtr<ExecutionContext> m_executionContext;
+ RefPtrWillBePersistent<ExecutionContext> m_executionContext;
OwnPtr<WorkerObjectProxy> m_workerObjectProxy;
Worker* m_workerObject;
bool m_mayBeDestroyed;
@@ -100,7 +100,7 @@ namespace WebCore {
Vector<OwnPtr<ExecutionContextTask> > m_queuedEarlyTasks; // Tasks are queued here until there's a thread object created.
WorkerGlobalScopeProxy::PageInspector* m_pageInspector;
- OwnPtr<WorkerClients> m_workerClients;
+ OwnPtrWillBePersistent<WorkerClients> m_workerClients;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp
index 7ad476c0476..be86f3619bb 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.cpp
@@ -45,4 +45,9 @@ String WorkerNavigator::userAgent() const
return m_userAgent;
}
+void WorkerNavigator::trace(Visitor* visitor)
+{
+ WillBeHeapSupplementable<WorkerNavigator>::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.h b/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.h
index 61c06183fad..0750e8fff7a 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.h
@@ -27,21 +27,30 @@
#define WorkerNavigator_h
#include "bindings/v8/ScriptWrappable.h"
-#include "core/frame/NavigatorBase.h"
+#include "core/frame/NavigatorCPU.h"
+#include "core/frame/NavigatorID.h"
+#include "core/frame/NavigatorOnLine.h"
#include "platform/Supplementable.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-class WorkerNavigator : public RefCounted<WorkerNavigator>, public ScriptWrappable, public NavigatorBase, public Supplementable<WorkerNavigator> {
+class WorkerNavigator FINAL : public RefCountedWillBeGarbageCollectedFinalized<WorkerNavigator>, public ScriptWrappable, public NavigatorCPU, public NavigatorID, public NavigatorOnLine, public WillBeHeapSupplementable<WorkerNavigator> {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WorkerNavigator);
public:
- static PassRefPtr<WorkerNavigator> create(const String& userAgent) { return adoptRef(new WorkerNavigator(userAgent)); }
+ static PassRefPtrWillBeRawPtr<WorkerNavigator> create(const String& userAgent)
+ {
+ return adoptRefWillBeNoop(new WorkerNavigator(userAgent));
+ }
virtual ~WorkerNavigator();
virtual String userAgent() const OVERRIDE;
+ void trace(Visitor*);
+
private:
explicit WorkerNavigator(const String&);
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.idl b/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.idl
index 3debfca937b..1e82b03f5d1 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.idl
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerNavigator.idl
@@ -26,10 +26,14 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+// http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#the-workernavigator-object
+
[
- GlobalContext=WorkerGlobalScope
+ Exposed=Worker,
+ WillBeGarbageCollected,
] interface WorkerNavigator {
};
+WorkerNavigator implements NavigatorCPU;
WorkerNavigator implements NavigatorID;
WorkerNavigator implements NavigatorOnLine;
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.cpp
index 3eb1920f94c..8acf0350fcc 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.cpp
@@ -29,7 +29,7 @@
*/
#include "config.h"
-#include "WorkerObjectProxy.h"
+#include "core/workers/WorkerObjectProxy.h"
#include "bindings/v8/SerializedScriptValue.h"
#include "core/dom/ExecutionContext.h"
@@ -49,6 +49,11 @@ void WorkerObjectProxy::postMessageToWorkerObject(PassRefPtr<SerializedScriptVal
m_executionContext->postTask(bind(&WorkerMessagingProxy::postMessageToWorkerObject, m_messagingProxy, message, channels));
}
+void WorkerObjectProxy::postTaskToMainExecutionContext(PassOwnPtr<ExecutionContextTask> task)
+{
+ m_executionContext->postTask(task);
+}
+
void WorkerObjectProxy::confirmMessageFromWorkerObject(bool hasPendingActivity)
{
m_executionContext->postTask(bind(&WorkerMessagingProxy::confirmMessageFromWorkerObject, m_messagingProxy, hasPendingActivity));
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.h b/chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.h
index 8b727a148d4..7d20a91edc2 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerObjectProxy.h
@@ -38,41 +38,43 @@
namespace WebCore {
- class ExecutionContext;
- class WorkerMessagingProxy;
+class ExecutionContext;
+class ExecutionContextTask;
+class WorkerMessagingProxy;
- // A proxy to talk to the worker object. This object is created on the
- // worker object thread (i.e. usually the main thread), passed on to
- // the worker thread, and used just to proxy messages to the
- // WorkerMessagingProxy on the worker object thread.
- //
- // Used only by Dedicated Worker.
- class WorkerObjectProxy : public WorkerReportingProxy {
- public:
- static PassOwnPtr<WorkerObjectProxy> create(ExecutionContext*, WorkerMessagingProxy*);
- ~WorkerObjectProxy() { }
+// A proxy to talk to the worker object. This object is created on the
+// worker object thread (i.e. usually the main thread), passed on to
+// the worker thread, and used just to proxy messages to the
+// WorkerMessagingProxy on the worker object thread.
+//
+// Used only by Dedicated Worker.
+class WorkerObjectProxy FINAL : public WorkerReportingProxy {
+public:
+ static PassOwnPtr<WorkerObjectProxy> create(ExecutionContext*, WorkerMessagingProxy*);
+ virtual ~WorkerObjectProxy() { }
- void postMessageToWorkerObject(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>);
+ void postMessageToWorkerObject(PassRefPtr<SerializedScriptValue>, PassOwnPtr<MessagePortChannelArray>);
+ void postTaskToMainExecutionContext(PassOwnPtr<ExecutionContextTask>);
+ void confirmMessageFromWorkerObject(bool hasPendingActivity);
+ void reportPendingActivity(bool hasPendingActivity);
- void confirmMessageFromWorkerObject(bool hasPendingActivity);
- void reportPendingActivity(bool hasPendingActivity);
+ // WorkerReportingProxy overrides.
+ virtual void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL) OVERRIDE;
+ virtual void reportConsoleMessage(MessageSource, MessageLevel, const String& message, int lineNumber, const String& sourceURL) OVERRIDE;
+ virtual void postMessageToPageInspector(const String&) OVERRIDE;
+ virtual void updateInspectorStateCookie(const String&) OVERRIDE;
+ virtual void workerGlobalScopeStarted(WorkerGlobalScope*) OVERRIDE { }
+ virtual void workerGlobalScopeClosed() OVERRIDE;
+ virtual void workerGlobalScopeDestroyed() OVERRIDE;
+ virtual void willDestroyWorkerGlobalScope() OVERRIDE { }
- // WorkerReportingProxy overrides.
- virtual void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL) OVERRIDE;
- virtual void reportConsoleMessage(MessageSource, MessageLevel, const String& message, int lineNumber, const String& sourceURL) OVERRIDE;
- virtual void postMessageToPageInspector(const String&) OVERRIDE;
- virtual void updateInspectorStateCookie(const String&) OVERRIDE;
- virtual void workerGlobalScopeStarted() OVERRIDE { }
- virtual void workerGlobalScopeClosed() OVERRIDE;
- virtual void workerGlobalScopeDestroyed() OVERRIDE;
+private:
+ WorkerObjectProxy(ExecutionContext*, WorkerMessagingProxy*);
- private:
- WorkerObjectProxy(ExecutionContext*, WorkerMessagingProxy*);
-
- // These objects always outlive this proxy.
- ExecutionContext* m_executionContext;
- WorkerMessagingProxy* m_messagingProxy;
- };
+ // These objects always outlive this proxy.
+ ExecutionContext* m_executionContext;
+ WorkerMessagingProxy* m_messagingProxy;
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h b/chromium/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
index 75b13891133..52f1fbeb11a 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerReportingProxy.h
@@ -36,25 +36,34 @@
namespace WebCore {
- // APIs used by workers to report console activity.
- class WorkerReportingProxy {
- public:
- virtual ~WorkerReportingProxy() {}
+class WorkerGlobalScope;
- virtual void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL) = 0;
- virtual void reportConsoleMessage(MessageSource, MessageLevel, const String& message, int lineNumber, const String& sourceURL) = 0;
- virtual void postMessageToPageInspector(const String&) = 0;
- virtual void updateInspectorStateCookie(const String&) = 0;
+// APIs used by workers to report console activity.
+class WorkerReportingProxy {
+public:
+ virtual ~WorkerReportingProxy() { }
- // Invoked when the new WorkerGlobalScope is started.
- virtual void workerGlobalScopeStarted() = 0;
+ virtual void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL) = 0;
+ virtual void reportConsoleMessage(MessageSource, MessageLevel, const String& message, int lineNumber, const String& sourceURL) = 0;
+ virtual void postMessageToPageInspector(const String&) = 0;
+ virtual void updateInspectorStateCookie(const String&) = 0;
- // Invoked when close() is invoked on the worker context.
- virtual void workerGlobalScopeClosed() = 0;
+ // Invoked when the new WorkerGlobalScope is started.
+ virtual void workerGlobalScopeStarted(WorkerGlobalScope*) = 0;
- // Invoked when the thread has stopped.
- virtual void workerGlobalScopeDestroyed() = 0;
- };
+ // Invoked when close() is invoked on the worker context.
+ virtual void workerGlobalScopeClosed() = 0;
+
+ // Invoked when the thread is stopped and WorkerGlobalScope is being
+ // destructed. (This is be the last method that is called on this
+ // interface)
+ virtual void workerGlobalScopeDestroyed() = 0;
+
+ // Invoked when the thread is about to be stopped and WorkerGlobalScope
+ // is to be destructed. (When this is called it is guaranteed that
+ // WorkerGlobalScope is still alive)
+ virtual void willDestroyWorkerGlobalScope() = 0;
+};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp
index b7ad2fd73ae..538f4ac2ed3 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.cpp
@@ -37,34 +37,55 @@
#include "platform/PlatformThreadData.h"
#include "platform/SharedTimer.h"
#include "platform/ThreadTimers.h"
+#include "platform/heap/ThreadState.h"
#include "wtf/CurrentTime.h"
namespace WebCore {
-class WorkerRunLoop::Task {
- WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED;
+class WorkerRunLoopTask : public blink::WebThread::Task {
+ WTF_MAKE_NONCOPYABLE(WorkerRunLoopTask); WTF_MAKE_FAST_ALLOCATED;
public:
- static PassOwnPtr<Task> create(PassOwnPtr<ExecutionContextTask> task, const String& mode)
+ static PassOwnPtr<WorkerRunLoopTask> create(const WorkerRunLoop& runLoop, PassOwnPtr<ExecutionContextTask> task)
{
- return adoptPtr(new Task(task, mode));
+ return adoptPtr(new WorkerRunLoopTask(runLoop, task));
}
- const String& mode() const { return m_mode; }
- void performTask(const WorkerRunLoop& runLoop, ExecutionContext* context)
+
+ virtual ~WorkerRunLoopTask() { }
+
+ virtual void run() OVERRIDE
{
- WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
- if ((!workerGlobalScope->isClosing() && !runLoop.terminated()) || m_task->isCleanupTask())
- m_task->performTask(context);
+ WorkerGlobalScope* workerGlobalScope = m_runLoop.context();
+ if ((!workerGlobalScope->isClosing() && !m_runLoop.terminated()) || m_task->isCleanupTask())
+ m_task->performTask(workerGlobalScope);
}
private:
- Task(PassOwnPtr<ExecutionContextTask> task, const String& mode)
- : m_task(task)
- , m_mode(mode.isolatedCopy())
+ WorkerRunLoopTask(const WorkerRunLoop& runLoop, PassOwnPtr<ExecutionContextTask> task)
+ : m_runLoop(runLoop)
+ , m_task(task)
{
}
+ const WorkerRunLoop& m_runLoop;
OwnPtr<ExecutionContextTask> m_task;
- String m_mode;
+};
+
+class TickleDebuggerQueueTask FINAL : public ExecutionContextTask {
+public:
+ static PassOwnPtr<TickleDebuggerQueueTask> create(WorkerRunLoop* loop)
+ {
+ return adoptPtr(new TickleDebuggerQueueTask(loop));
+ }
+ virtual void performTask(ExecutionContext* context) OVERRIDE
+ {
+ ASSERT(context->isWorkerGlobalScope());
+ m_loop->runDebuggerTask(WorkerRunLoop::DontWaitForMessage);
+ }
+
+private:
+ explicit TickleDebuggerQueueTask(WorkerRunLoop* loop) : m_loop(loop) { }
+
+ WorkerRunLoop* m_loop;
};
class WorkerSharedTimer : public SharedTimer {
@@ -89,33 +110,10 @@ private:
double m_nextFireTime;
};
-class ModePredicate {
-public:
- ModePredicate(const String& mode)
- : m_mode(mode)
- , m_defaultMode(mode == WorkerRunLoop::defaultMode())
- {
- }
-
- bool isDefaultMode() const
- {
- return m_defaultMode;
- }
-
- bool operator()(WorkerRunLoop::Task* task) const
- {
- return m_defaultMode || m_mode == task->mode();
- }
-
-private:
- String m_mode;
- bool m_defaultMode;
-};
-
WorkerRunLoop::WorkerRunLoop()
: m_sharedTimer(adoptPtr(new WorkerSharedTimer))
+ , m_context(0)
, m_nestedCount(0)
- , m_uniqueId(0)
{
}
@@ -124,11 +122,6 @@ WorkerRunLoop::~WorkerRunLoop()
ASSERT(!m_nestedCount);
}
-String WorkerRunLoop::defaultMode()
-{
- return String();
-}
-
class RunLoopSetup {
WTF_MAKE_NONCOPYABLE(RunLoopSetup);
public:
@@ -154,44 +147,52 @@ private:
WorkerGlobalScope* m_context;
};
-void WorkerRunLoop::run(WorkerGlobalScope* context)
+void WorkerRunLoop::setWorkerGlobalScope(WorkerGlobalScope* context)
{
- RunLoopSetup setup(*this, context);
- ModePredicate modePredicate(defaultMode());
+ ASSERT(!m_context);
+ ASSERT(context);
+ m_context = context;
+}
+
+void WorkerRunLoop::run()
+{
+ ASSERT(m_context);
+ RunLoopSetup setup(*this, m_context);
MessageQueueWaitResult result;
do {
- result = runInMode(context, modePredicate, WaitForMessage);
+ ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
+ result = run(m_messageQueue, WaitForMessage);
} while (result != MessageQueueTerminated);
- runCleanupTasks(context);
+ runCleanupTasks();
}
-MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, const String& mode, WaitMode waitMode)
+MessageQueueWaitResult WorkerRunLoop::runDebuggerTask(WaitMode waitMode)
{
- RunLoopSetup setup(*this, context);
- ModePredicate modePredicate(mode);
- MessageQueueWaitResult result = runInMode(context, modePredicate, waitMode);
- return result;
+ ASSERT(m_context);
+ RunLoopSetup setup(*this, m_context);
+ return run(m_debuggerMessageQueue, waitMode);
}
-MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, const ModePredicate& predicate, WaitMode waitMode)
+MessageQueueWaitResult WorkerRunLoop::run(MessageQueue<blink::WebThread::Task>& queue, WaitMode waitMode)
{
- ASSERT(context);
- ASSERT(context->thread());
- ASSERT(context->thread()->isCurrentThread());
+ ASSERT(m_context);
+ ASSERT(m_context->thread());
+ ASSERT(m_context->thread()->isCurrentThread());
+ bool isDebuggerQueue = (&queue == &m_debuggerMessageQueue);
bool nextTimeoutEventIsIdleWatchdog;
MessageQueueWaitResult result;
- OwnPtr<WorkerRunLoop::Task> task;
+ OwnPtr<blink::WebThread::Task> task;
do {
double absoluteTime = 0.0;
nextTimeoutEventIsIdleWatchdog = false;
if (waitMode == WaitForMessage) {
- absoluteTime = (predicate.isDefaultMode() && m_sharedTimer->isActive()) ? m_sharedTimer->fireTime() : MessageQueue<Task>::infiniteTime();
+ absoluteTime = !isDebuggerQueue && m_sharedTimer->isActive() ? m_sharedTimer->fireTime() : MessageQueue<blink::WebThread::Task>::infiniteTime();
// Do a script engine idle notification if the next event is distant enough.
const double kMinIdleTimespan = 0.3; // seconds
- if (m_messageQueue.isEmpty() && absoluteTime > currentTime() + kMinIdleTimespan) {
- bool hasMoreWork = !context->idleNotification();
+ if (queue.isEmpty() && absoluteTime > currentTime() + kMinIdleTimespan) {
+ bool hasMoreWork = !m_context->idleNotification();
if (hasMoreWork) {
// Schedule a watchdog, so if there are no events within a particular time interval
// idle notifications won't stop firing.
@@ -204,7 +205,11 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons
}
}
}
- task = m_messageQueue.waitForMessageFilteredWithTimeout(result, predicate, absoluteTime);
+
+ {
+ ThreadState::SafePointScope safePointScope(ThreadState::NoHeapPointersOnStack);
+ task = queue.waitForMessageWithTimeout(result, absoluteTime);
+ }
} while (result == MessageQueueTimeout && nextTimeoutEventIsIdleWatchdog);
// If the context is closing, don't execute any further JavaScript tasks (per section 4.1.1 of the Web Workers spec).
@@ -215,13 +220,14 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons
break;
case MessageQueueMessageReceived:
- InspectorInstrumentation::willProcessTask(context);
- task->performTask(*this, context);
- InspectorInstrumentation::didProcessTask(context);
+ InspectorInstrumentation::willProcessTask(m_context);
+ task->run();
+ InspectorInstrumentation::didProcessTask(m_context);
break;
case MessageQueueTimeout:
- if (!context->isClosing())
+ ASSERT(!isDebuggerQueue || waitMode != WaitForMessage);
+ if (!m_context->isClosing())
m_sharedTimer->fire();
break;
}
@@ -229,49 +235,47 @@ MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, cons
return result;
}
-void WorkerRunLoop::runCleanupTasks(WorkerGlobalScope* context)
+void WorkerRunLoop::runCleanupTasks()
{
- ASSERT(context);
- ASSERT(context->thread());
- ASSERT(context->thread()->isCurrentThread());
+ ASSERT(m_context);
+ ASSERT(m_context->thread());
+ ASSERT(m_context->thread()->isCurrentThread());
ASSERT(m_messageQueue.killed());
+ ASSERT(m_debuggerMessageQueue.killed());
while (true) {
- OwnPtr<WorkerRunLoop::Task> task = m_messageQueue.tryGetMessageIgnoringKilled();
+ OwnPtr<blink::WebThread::Task> task = m_debuggerMessageQueue.tryGetMessageIgnoringKilled();
+ if (!task)
+ task = m_messageQueue.tryGetMessageIgnoringKilled();
if (!task)
return;
- task->performTask(*this, context);
+ task->run();
}
}
void WorkerRunLoop::terminate()
{
m_messageQueue.kill();
+ m_debuggerMessageQueue.kill();
}
bool WorkerRunLoop::postTask(PassOwnPtr<ExecutionContextTask> task)
{
- return postTaskForMode(task, defaultMode());
-}
-
-bool WorkerRunLoop::postTask(const Closure& closure)
-{
- return postTask(CallClosureTask::create(closure));
+ return m_messageQueue.append(WorkerRunLoopTask::create(*this, task));
}
void WorkerRunLoop::postTaskAndTerminate(PassOwnPtr<ExecutionContextTask> task)
{
- m_messageQueue.appendAndKill(Task::create(task, defaultMode().isolatedCopy()));
-}
-
-bool WorkerRunLoop::postTaskForMode(PassOwnPtr<ExecutionContextTask> task, const String& mode)
-{
- return m_messageQueue.append(Task::create(task, mode.isolatedCopy()));
+ m_debuggerMessageQueue.kill();
+ m_messageQueue.appendAndKill(WorkerRunLoopTask::create(*this, task));
}
-bool WorkerRunLoop::postTaskForMode(const Closure& closure, const String& mode)
+bool WorkerRunLoop::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task)
{
- return postTaskForMode(CallClosureTask::create(closure), mode);
+ bool posted = m_debuggerMessageQueue.append(WorkerRunLoopTask::create(*this, task));
+ if (posted)
+ postTask(TickleDebuggerQueueTask::create(this));
+ return posted;
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.h b/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.h
index 88d1b3ace9e..4ec47eb1b5d 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerRunLoop.h
@@ -33,6 +33,7 @@
#include "core/dom/ExecutionContext.h"
#include "core/dom/ExecutionContextTask.h"
+#include "public/platform/WebThread.h"
#include "wtf/Functional.h"
#include "wtf/MessageQueue.h"
#include "wtf/OwnPtr.h"
@@ -40,7 +41,6 @@
namespace WebCore {
- class ModePredicate;
class WorkerGlobalScope;
class WorkerSharedTimer;
@@ -49,45 +49,42 @@ namespace WebCore {
WorkerRunLoop();
~WorkerRunLoop();
+ void setWorkerGlobalScope(WorkerGlobalScope*);
+
// Blocking call. Waits for tasks and timers, invokes the callbacks.
- void run(WorkerGlobalScope*);
+ void run();
enum WaitMode { WaitForMessage, DontWaitForMessage };
- // Waits for a single task and returns.
- MessageQueueWaitResult runInMode(WorkerGlobalScope*, const String& mode, WaitMode = WaitForMessage);
+ // Waits for a single debugger task and returns.
+ MessageQueueWaitResult runDebuggerTask(WaitMode = WaitForMessage);
void terminate();
bool terminated() const { return m_messageQueue.killed(); }
+ WorkerGlobalScope* context() const { return m_context; }
+
// Returns true if the loop is still alive, false if it has been terminated.
bool postTask(PassOwnPtr<ExecutionContextTask>);
- bool postTask(const Closure&);
void postTaskAndTerminate(PassOwnPtr<ExecutionContextTask>);
// Returns true if the loop is still alive, false if it has been terminated.
- bool postTaskForMode(PassOwnPtr<ExecutionContextTask>, const String& mode);
- bool postTaskForMode(const Closure&, const String& mode);
-
- unsigned long createUniqueId() { return ++m_uniqueId; }
-
- static String defaultMode();
-
- class Task;
+ bool postDebuggerTask(PassOwnPtr<ExecutionContextTask>);
private:
friend class RunLoopSetup;
- MessageQueueWaitResult runInMode(WorkerGlobalScope*, const ModePredicate&, WaitMode);
+ MessageQueueWaitResult run(MessageQueue<blink::WebThread::Task>&, WaitMode);
// Runs any clean up tasks that are currently in the queue and returns.
// This should only be called when the context is closed or loop has been terminated.
- void runCleanupTasks(WorkerGlobalScope*);
+ void runCleanupTasks();
- MessageQueue<Task> m_messageQueue;
+ MessageQueue<blink::WebThread::Task> m_messageQueue;
+ MessageQueue<blink::WebThread::Task> m_debuggerMessageQueue;
OwnPtr<WorkerSharedTimer> m_sharedTimer;
+ WorkerGlobalScope* m_context;
int m_nestedCount;
- unsigned long m_uniqueId;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
index 1ed0d43d643..d52adba41a2 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.cpp
@@ -29,7 +29,7 @@
#include "core/workers/WorkerScriptLoader.h"
#include "core/dom/ExecutionContext.h"
-#include "core/fetch/TextResourceDecoder.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/loader/WorkerThreadableLoader.h"
#include "core/workers/WorkerGlobalScope.h"
#include "core/workers/WorkerScriptLoaderClient.h"
@@ -53,7 +53,7 @@ WorkerScriptLoader::~WorkerScriptLoader()
{
}
-void WorkerScriptLoader::loadSynchronously(ExecutionContext* executionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy)
+void WorkerScriptLoader::loadSynchronously(ExecutionContext& executionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy)
{
m_url = url;
@@ -61,19 +61,20 @@ void WorkerScriptLoader::loadSynchronously(ExecutionContext* executionContext, c
if (!request)
return;
- ASSERT_WITH_SECURITY_IMPLICATION(executionContext->isWorkerGlobalScope());
+ ASSERT_WITH_SECURITY_IMPLICATION(executionContext.isWorkerGlobalScope());
ThreadableLoaderOptions options;
- options.allowCredentials = AllowStoredCredentials;
options.crossOriginRequestPolicy = crossOriginRequestPolicy;
- options.sendLoadCallbacks = SendCallbacks;
// FIXME: Should we add EnforceScriptSrcDirective here?
options.contentSecurityPolicyEnforcement = DoNotEnforceContentSecurityPolicy;
- WorkerThreadableLoader::loadResourceSynchronously(toWorkerGlobalScope(executionContext), *request, *this, options);
+ ResourceLoaderOptions resourceLoaderOptions;
+ resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
+
+ WorkerThreadableLoader::loadResourceSynchronously(toWorkerGlobalScope(executionContext), *request, *this, options, resourceLoaderOptions);
}
-void WorkerScriptLoader::loadAsynchronously(ExecutionContext* executionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy, WorkerScriptLoaderClient* client)
+void WorkerScriptLoader::loadAsynchronously(ExecutionContext& executionContext, const KURL& url, CrossOriginRequestPolicy crossOriginRequestPolicy, WorkerScriptLoaderClient* client)
{
ASSERT(client);
m_client = client;
@@ -84,13 +85,14 @@ void WorkerScriptLoader::loadAsynchronously(ExecutionContext* executionContext,
return;
ThreadableLoaderOptions options;
- options.allowCredentials = AllowStoredCredentials;
options.crossOriginRequestPolicy = crossOriginRequestPolicy;
- options.sendLoadCallbacks = SendCallbacks;
+
+ ResourceLoaderOptions resourceLoaderOptions;
+ resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
// During create, callbacks may happen which remove the last reference to this object.
RefPtr<WorkerScriptLoader> protect(this);
- m_threadableLoader = ThreadableLoader::create(executionContext, this, *request, options);
+ m_threadableLoader = ThreadableLoader::create(executionContext, this, *request, options, resourceLoaderOptions);
}
const KURL& WorkerScriptLoader::responseURL() const
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h b/chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
index e4038516948..00be0ba6624 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
@@ -45,7 +45,7 @@ namespace WebCore {
class TextResourceDecoder;
class WorkerScriptLoaderClient;
- class WorkerScriptLoader : public RefCounted<WorkerScriptLoader>, public ThreadableLoaderClient {
+ class WorkerScriptLoader FINAL : public RefCounted<WorkerScriptLoader>, public ThreadableLoaderClient {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<WorkerScriptLoader> create()
@@ -53,8 +53,8 @@ namespace WebCore {
return adoptRef(new WorkerScriptLoader());
}
- void loadSynchronously(ExecutionContext*, const KURL&, CrossOriginRequestPolicy);
- void loadAsynchronously(ExecutionContext*, const KURL&, CrossOriginRequestPolicy, WorkerScriptLoaderClient*);
+ void loadSynchronously(ExecutionContext&, const KURL&, CrossOriginRequestPolicy);
+ void loadAsynchronously(ExecutionContext&, const KURL&, CrossOriginRequestPolicy, WorkerScriptLoaderClient*);
void notifyError();
@@ -82,7 +82,7 @@ namespace WebCore {
friend class WTF::RefCounted<WorkerScriptLoader>;
WorkerScriptLoader();
- ~WorkerScriptLoader();
+ virtual ~WorkerScriptLoader();
PassOwnPtr<ResourceRequest> createResourceRequest();
void notifyFinished();
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerSupplementable.h b/chromium/third_party/WebKit/Source/core/workers/WorkerSupplementable.h
deleted file mode 100644
index f091474148e..00000000000
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerSupplementable.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WorkerSupplementable_h
-#define WorkerSupplementable_h
-
-#include "platform/Supplementable.h"
-
-namespace WebCore {
-
-class WorkerGlobalScope;
-
-typedef Supplementable<WorkerGlobalScope> WorkerSupplementable;
-typedef Supplement<WorkerGlobalScope> WorkerSupplement;
-
-} // namespace WebCore
-
-#endif // WorkerSupplementable_h
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index 6f842e8db42..b04391a18c0 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -32,12 +32,13 @@
#include "core/inspector/InspectorInstrumentation.h"
#include "core/workers/DedicatedWorkerGlobalScope.h"
#include "core/workers/WorkerClients.h"
+#include "core/workers/WorkerReportingProxy.h"
#include "core/workers/WorkerThreadStartupData.h"
-#include "modules/webdatabase/DatabaseManager.h"
-#include "modules/webdatabase/DatabaseTask.h"
#include "platform/PlatformThreadData.h"
+#include "platform/heap/ThreadState.h"
#include "platform/weborigin/KURL.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebWaitableEvent.h"
#include "public/platform/WebWorkerRunLoop.h"
#include "wtf/Noncopyable.h"
#include "wtf/text/WTFString.h"
@@ -64,12 +65,13 @@ unsigned WorkerThread::workerThreadCount()
return workerThreads().size();
}
-WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> startupData)
+WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
: m_threadID(0)
, m_workerLoaderProxy(workerLoaderProxy)
, m_workerReportingProxy(workerReportingProxy)
, m_startupData(startupData)
, m_notificationClient(0)
+ , m_shutdownEvent(adoptPtr(blink::Platform::current()->createWaitableEvent()))
{
MutexLocker lock(threadSetMutex());
workerThreads().add(this);
@@ -108,8 +110,9 @@ void WorkerThread::workerThread()
{
MutexLocker lock(m_threadCreationMutex);
-
+ ThreadState::attach();
m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release());
+ m_runLoop.setWorkerGlobalScope(workerGlobalScope());
if (m_runLoop.terminated()) {
// The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
@@ -121,19 +124,44 @@ void WorkerThread::workerThread()
// ~WorkerScriptController.
blink::Platform::current()->didStartWorkerRunLoop(blink::WebWorkerRunLoop(&m_runLoop));
+ // Notify proxy that a new WorkerGlobalScope has been created and started.
+ m_workerReportingProxy.workerGlobalScopeStarted(m_workerGlobalScope.get());
+
WorkerScriptController* script = m_workerGlobalScope->script();
+ if (!script->isExecutionForbidden())
+ script->initializeContextIfNeeded();
InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), startMode);
script->evaluate(ScriptSourceCode(sourceCode, scriptURL));
runEventLoop();
- ThreadIdentifier threadID = m_threadID;
+ // This should be called before we start the shutdown procedure.
+ workerReportingProxy().willDestroyWorkerGlobalScope();
- ASSERT(m_workerGlobalScope->hasOneRef());
+ ThreadIdentifier threadID = m_threadID;
// The below assignment will destroy the context, which will in turn notify messaging proxy.
// We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
- m_workerGlobalScope = 0;
+ // If Oilpan is enabled, we detach of the context/global scope, with the final heap cleanup below sweeping it out.
+#if !ENABLE(OILPAN)
+ ASSERT(m_workerGlobalScope->hasOneRef());
+#endif
+ m_workerGlobalScope->dispose();
+ m_workerGlobalScope = nullptr;
+
+ // Detach the ThreadState, cleaning out the thread's heap by
+ // performing a final GC. The cleanup operation will at the end
+ // assert that the heap is empty. If the heap does not become
+ // empty, there are still pointers into the heap and those
+ // pointers will be dangling after thread termination because we
+ // are destroying the heap. It is important to detach while the
+ // thread is still valid. In particular, finalizers for objects in
+ // the heap for this thread will need to access thread local data.
+ ThreadState::detach();
+
+ // Notify the proxy that the WorkerGlobalScope has been disposed of.
+ // This can free this thread object, hence it must not be touched afterwards.
+ workerReportingProxy().workerGlobalScopeDestroyed();
// Clean up PlatformThreadData before WTF::WTFThreadData goes away!
PlatformThreadData::current().destroy();
@@ -145,7 +173,7 @@ void WorkerThread::workerThread()
void WorkerThread::runEventLoop()
{
// Does not return until terminated.
- m_runLoop.run(m_workerGlobalScope.get());
+ m_runLoop.run();
}
class WorkerThreadShutdownFinishTask : public ExecutionContextTask {
@@ -176,23 +204,13 @@ public:
virtual void performTask(ExecutionContext *context)
{
WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
-
- // FIXME: Should we stop the databases as part of stopActiveDOMObjects() below?
- DatabaseTaskSynchronizer cleanupSync;
- DatabaseManager::manager().stopDatabases(workerGlobalScope, &cleanupSync);
-
+ workerGlobalScope->stopFetch();
workerGlobalScope->stopActiveDOMObjects();
- workerGlobalScope->notifyObserversOfStop();
-
// Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
// which become dangling once Heap is destroyed.
workerGlobalScope->removeAllEventListeners();
- // We wait for the database thread to clean up all its stuff so that we
- // can do more stringent leak checks as we exit.
- cleanupSync.waitForTaskCompletion();
-
// Stick a shutdown command at the end of the queue, so that we deal
// with all the cleanup tasks the databases post first.
workerGlobalScope->postTask(WorkerThreadShutdownFinishTask::create());
@@ -203,14 +221,20 @@ public:
void WorkerThread::stop()
{
+ // Prevent the deadlock between GC and an attempt to stop a thread.
+ ThreadState::SafePointScope safePointScope(ThreadState::HeapPointersOnStack);
+
// Mutex protection is necessary because stop() can be called before the context is fully created.
MutexLocker lock(m_threadCreationMutex);
+ // Signal the thread to notify that the thread's stopping.
+ if (m_shutdownEvent)
+ m_shutdownEvent->signal();
+
// Ensure that tasks are being handled by thread event loop. If script execution weren't forbidden, a while(1) loop in JS could keep the thread alive forever.
if (m_workerGlobalScope) {
m_workerGlobalScope->script()->scheduleExecutionTermination();
-
- DatabaseManager::manager().interruptAllDatabasesForContext(m_workerGlobalScope.get());
+ m_workerGlobalScope->wasRequestedToTerminate();
m_runLoop.postTaskAndTerminate(WorkerThreadShutdownStartTask::create());
return;
}
@@ -222,17 +246,4 @@ bool WorkerThread::isCurrentThread() const
return m_threadID == currentThread();
}
-class ReleaseFastMallocFreeMemoryTask : public ExecutionContextTask {
- virtual void performTask(ExecutionContext*) OVERRIDE { WTF::releaseFastMallocFreeMemory(); }
-};
-
-void WorkerThread::releaseFastMallocFreeMemoryInAllThreads()
-{
- MutexLocker lock(threadSetMutex());
- HashSet<WorkerThread*>& threads = workerThreads();
- HashSet<WorkerThread*>::iterator end = threads.end();
- for (HashSet<WorkerThread*>::iterator it = threads.begin(); it != end; ++it)
- (*it)->runLoop().postTask(adoptPtr(new ReleaseFastMallocFreeMemoryTask));
-}
-
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerThread.h b/chromium/third_party/WebKit/Source/core/workers/WorkerThread.h
index 83bf3f445e4..8d0f409fcb1 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerThread.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerThread.h
@@ -27,7 +27,7 @@
#ifndef WorkerThread_h
#define WorkerThread_h
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/workers/WorkerRunLoop.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/Forward.h"
@@ -35,6 +35,10 @@
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
+namespace blink {
+class WebWaitableEvent;
+}
+
namespace WebCore {
class KURL;
@@ -42,7 +46,7 @@ namespace WebCore {
class WorkerGlobalScope;
class WorkerLoaderProxy;
class WorkerReportingProxy;
- struct WorkerThreadStartupData;
+ class WorkerThreadStartupData;
enum WorkerThreadStartMode { DontPauseWorkerGlobalScopeOnStart, PauseWorkerGlobalScopeOnStart };
@@ -53,6 +57,10 @@ namespace WebCore {
bool start();
void stop();
+ // Can be used to wait for this worker thread to shut down.
+ // (This is signalled on the main thread, so it's assumed to be waited on the worker context thread)
+ blink::WebWaitableEvent* shutdownEvent() { return m_shutdownEvent.get(); }
+
bool isCurrentThread() const;
WorkerRunLoop& runLoop() { return m_runLoop; }
WorkerLoaderProxy& workerLoaderProxy() const { return m_workerLoaderProxy; }
@@ -60,16 +68,15 @@ namespace WebCore {
// Number of active worker threads.
static unsigned workerThreadCount();
- static void releaseFastMallocFreeMemoryInAllThreads();
NotificationClient* getNotificationClient() { return m_notificationClient; }
void setNotificationClient(NotificationClient* client) { m_notificationClient = client; }
protected:
- WorkerThread(WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtr<WorkerThreadStartupData>);
+ WorkerThread(WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
// Factory method for creating a new worker context for the thread.
- virtual PassRefPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData>) = 0;
+ virtual PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>) = 0;
// Executes the event loop for the worker thread. Derived classes can override to perform actions before/after entering the event loop.
virtual void runEventLoop();
@@ -87,12 +94,15 @@ namespace WebCore {
WorkerLoaderProxy& m_workerLoaderProxy;
WorkerReportingProxy& m_workerReportingProxy;
- RefPtr<WorkerGlobalScope> m_workerGlobalScope;
+ RefPtrWillBePersistent<WorkerGlobalScope> m_workerGlobalScope;
Mutex m_threadCreationMutex;
- OwnPtr<WorkerThreadStartupData> m_startupData;
+ OwnPtrWillBePersistent<WorkerThreadStartupData> m_startupData;
NotificationClient* m_notificationClient;
+
+ // Used to signal thread shutdown.
+ OwnPtr<blink::WebWaitableEvent> m_shutdownEvent;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp b/chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp
index 2e99b068ccd..76a9f501ecf 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.cpp
@@ -29,12 +29,13 @@
*/
#include "config.h"
-#include "WorkerThreadStartupData.h"
+#include "core/workers/WorkerThreadStartupData.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
namespace WebCore {
-WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients> workerClients)
+WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicyHeaderType contentSecurityPolicyType, PassOwnPtrWillBeRawPtr<WorkerClients> workerClients)
: m_scriptURL(scriptURL.copy())
, m_userAgent(userAgent.isolatedCopy())
, m_sourceCode(sourceCode.isolatedCopy())
@@ -49,4 +50,9 @@ WorkerThreadStartupData::~WorkerThreadStartupData()
{
}
+void WorkerThreadStartupData::trace(Visitor* visitor)
+{
+ visitor->trace(m_workerClients);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.h b/chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.h
index c1b13d703b7..1d26ab0cee3 100644
--- a/chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.h
+++ b/chromium/third_party/WebKit/Source/core/workers/WorkerThreadStartupData.h
@@ -31,9 +31,10 @@
#ifndef WorkerThreadStartupData_h
#define WorkerThreadStartupData_h
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/workers/WorkerClients.h"
#include "core/workers/WorkerThread.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
#include "platform/weborigin/KURL.h"
#include "wtf/Forward.h"
#include "wtf/Noncopyable.h"
@@ -42,12 +43,13 @@ namespace WebCore {
class WorkerClients;
-struct WorkerThreadStartupData {
- WTF_MAKE_NONCOPYABLE(WorkerThreadStartupData); WTF_MAKE_FAST_ALLOCATED;
+class WorkerThreadStartupData FINAL : public NoBaseWillBeGarbageCollectedFinalized<WorkerThreadStartupData> {
+ WTF_MAKE_NONCOPYABLE(WorkerThreadStartupData);
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<WorkerThreadStartupData> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients> workerClients)
+ static PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicyHeaderType contentSecurityPolicyType, PassOwnPtrWillBeRawPtr<WorkerClients> workerClients)
{
- return adoptPtr(new WorkerThreadStartupData(scriptURL, userAgent, sourceCode, startMode, contentSecurityPolicy, contentSecurityPolicyType, workerClients));
+ return adoptPtrWillBeNoop(new WorkerThreadStartupData(scriptURL, userAgent, sourceCode, startMode, contentSecurityPolicy, contentSecurityPolicyType, workerClients));
}
~WorkerThreadStartupData();
@@ -57,11 +59,13 @@ public:
String m_sourceCode;
WorkerThreadStartMode m_startMode;
String m_contentSecurityPolicy;
- ContentSecurityPolicy::HeaderType m_contentSecurityPolicyType;
- OwnPtr<WorkerClients> m_workerClients;
+ ContentSecurityPolicyHeaderType m_contentSecurityPolicyType;
+ OwnPtrWillBeMember<WorkerClients> m_workerClients;
+
+ void trace(Visitor*);
private:
- WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients>);
+ WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode, const String& contentSecurityPolicy, ContentSecurityPolicyHeaderType contentSecurityPolicyType, PassOwnPtrWillBeRawPtr<WorkerClients>);
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/DOMParser.cpp b/chromium/third_party/WebKit/Source/core/xml/DOMParser.cpp
index bc509de4ca5..8ae54a14d7c 100644
--- a/chromium/third_party/WebKit/Source/core/xml/DOMParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/DOMParser.cpp
@@ -25,7 +25,7 @@
namespace WebCore {
-PassRefPtr<Document> DOMParser::parseFromString(const String& str, const String& contentType, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Document> DOMParser::parseFromString(const String& str, const String& contentType, ExceptionState& exceptionState)
{
// HTML5 is very explicit about which types we're allowed to support here:
// http://domparsing.spec.whatwg.org/#the-domparser-interface
@@ -34,11 +34,11 @@ PassRefPtr<Document> DOMParser::parseFromString(const String& str, const String&
&& contentType != "application/xml"
&& contentType != "application/xhtml+xml"
&& contentType != "image/svg+xml") {
- exceptionState.throwDOMException(TypeError, "Unsupported mime-type specified.");
- return 0;
+ exceptionState.throwTypeError("Unsupported mime-type specified.");
+ return nullptr;
}
- RefPtr<Document> doc = DOMImplementation::createDocument(contentType, 0, KURL(), false);
+ RefPtrWillBeRawPtr<Document> doc = DOMImplementation::createDocument(contentType, 0, KURL(), false);
doc->setContent(str);
return doc.release();
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/DOMParser.h b/chromium/third_party/WebKit/Source/core/xml/DOMParser.h
index afe0d16433c..c28c20fca3d 100644
--- a/chromium/third_party/WebKit/Source/core/xml/DOMParser.h
+++ b/chromium/third_party/WebKit/Source/core/xml/DOMParser.h
@@ -20,6 +20,7 @@
#define DOMParser_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
#include "wtf/RefPtr.h"
@@ -29,11 +30,16 @@ namespace WebCore {
class Document;
class ExceptionState;
-class DOMParser : public RefCounted<DOMParser>, public ScriptWrappable {
+class DOMParser : public RefCountedWillBeGarbageCollectedFinalized<DOMParser>, public ScriptWrappable {
public:
- static PassRefPtr<DOMParser> create() { return adoptRef(new DOMParser); }
+ static PassRefPtrWillBeRawPtr<DOMParser> create()
+ {
+ return adoptRefWillBeNoop(new DOMParser);
+ }
+
+ PassRefPtrWillBeRawPtr<Document> parseFromString(const String&, const String& contentType, ExceptionState&);
- PassRefPtr<Document> parseFromString(const String&, const String& contentType, ExceptionState&);
+ void trace(Visitor*) { }
private:
DOMParser()
diff --git a/chromium/third_party/WebKit/Source/core/xml/DOMParser.idl b/chromium/third_party/WebKit/Source/core/xml/DOMParser.idl
index ff6af341d86..aa390c5cbae 100644
--- a/chromium/third_party/WebKit/Source/core/xml/DOMParser.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/DOMParser.idl
@@ -18,6 +18,7 @@
*/
[
+ WillBeGarbageCollected,
Constructor
] interface DOMParser {
[RaisesException] Document parseFromString([Default=Undefined] optional DOMString str,
diff --git a/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.cpp b/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.cpp
index d14ca546074..a5181ef8dab 100644
--- a/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.cpp
@@ -37,45 +37,47 @@ DocumentXPathEvaluator::DocumentXPathEvaluator()
{
}
-DocumentXPathEvaluator::~DocumentXPathEvaluator()
-{
-}
-
-DocumentXPathEvaluator* DocumentXPathEvaluator::from(DocumentSupplementable* document)
+DocumentXPathEvaluator& DocumentXPathEvaluator::from(DocumentSupplementable& document)
{
DocumentXPathEvaluator* cache = static_cast<DocumentXPathEvaluator*>(DocumentSupplement::from(document, supplementName()));
if (!cache) {
cache = new DocumentXPathEvaluator();
- DocumentSupplement::provideTo(document, supplementName(), adoptPtr(cache));
+ DocumentSupplement::provideTo(document, supplementName(), adoptPtrWillBeNoop(cache));
}
- return cache;
+ return *cache;
}
-PassRefPtr<XPathExpression> DocumentXPathEvaluator::createExpression(DocumentSupplementable* document,
- const String& expression, PassRefPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<XPathExpression> DocumentXPathEvaluator::createExpression(DocumentSupplementable& document,
+ const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
{
- DocumentXPathEvaluator* suplement = from(document);
- if (!suplement->m_xpathEvaluator)
- suplement->m_xpathEvaluator = XPathEvaluator::create();
- return suplement->m_xpathEvaluator->createExpression(expression, resolver, exceptionState);
+ DocumentXPathEvaluator& suplement = from(document);
+ if (!suplement.m_xpathEvaluator)
+ suplement.m_xpathEvaluator = XPathEvaluator::create();
+ return suplement.m_xpathEvaluator->createExpression(expression, resolver, exceptionState);
}
-PassRefPtr<XPathNSResolver> DocumentXPathEvaluator::createNSResolver(DocumentSupplementable* document, Node* nodeResolver)
+PassRefPtrWillBeRawPtr<XPathNSResolver> DocumentXPathEvaluator::createNSResolver(DocumentSupplementable& document, Node* nodeResolver)
{
- DocumentXPathEvaluator* suplement = from(document);
- if (!suplement->m_xpathEvaluator)
- suplement->m_xpathEvaluator = XPathEvaluator::create();
- return suplement->m_xpathEvaluator->createNSResolver(nodeResolver);
+ DocumentXPathEvaluator& suplement = from(document);
+ if (!suplement.m_xpathEvaluator)
+ suplement.m_xpathEvaluator = XPathEvaluator::create();
+ return suplement.m_xpathEvaluator->createNSResolver(nodeResolver);
}
-PassRefPtr<XPathResult> DocumentXPathEvaluator::evaluate(DocumentSupplementable* document, const String& expression,
- Node* contextNode, PassRefPtr<XPathNSResolver> resolver, unsigned short type,
+PassRefPtrWillBeRawPtr<XPathResult> DocumentXPathEvaluator::evaluate(DocumentSupplementable& document, const String& expression,
+ Node* contextNode, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, unsigned short type,
XPathResult* result, ExceptionState& exceptionState)
{
- DocumentXPathEvaluator* suplement = from(document);
- if (!suplement->m_xpathEvaluator)
- suplement->m_xpathEvaluator = XPathEvaluator::create();
- return suplement->m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, exceptionState);
+ DocumentXPathEvaluator& suplement = from(document);
+ if (!suplement.m_xpathEvaluator)
+ suplement.m_xpathEvaluator = XPathEvaluator::create();
+ return suplement.m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, exceptionState);
+}
+
+void DocumentXPathEvaluator::trace(Visitor* visitor)
+{
+ visitor->trace(m_xpathEvaluator);
+ DocumentSupplement::trace(visitor);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.h b/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.h
index 769a44930a2..18a6a78a9a8 100644
--- a/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.h
+++ b/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.h
@@ -36,25 +36,26 @@ class ExceptionState;
class XPathExpression;
class XPathResult;
-class DocumentXPathEvaluator : public DocumentSupplement {
+class DocumentXPathEvaluator FINAL : public NoBaseWillBeGarbageCollected<DocumentXPathEvaluator>, public DocumentSupplement {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(DocumentXPathEvaluator);
public:
- virtual ~DocumentXPathEvaluator();
+ static DocumentXPathEvaluator& from(DocumentSupplementable&);
- static DocumentXPathEvaluator* from(DocumentSupplementable*);
-
- static PassRefPtr<XPathExpression> createExpression(DocumentSupplementable*,
- const String& expression, PassRefPtr<XPathNSResolver>, ExceptionState&);
- static PassRefPtr<XPathNSResolver> createNSResolver(DocumentSupplementable*, Node* nodeResolver);
- static PassRefPtr<XPathResult> evaluate(DocumentSupplementable*,
- const String& expression, Node* contextNode, PassRefPtr<XPathNSResolver>,
+ static PassRefPtrWillBeRawPtr<XPathExpression> createExpression(DocumentSupplementable&,
+ const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver>, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<XPathNSResolver> createNSResolver(DocumentSupplementable&, Node* nodeResolver);
+ static PassRefPtrWillBeRawPtr<XPathResult> evaluate(DocumentSupplementable&,
+ const String& expression, Node* contextNode, PassRefPtrWillBeRawPtr<XPathNSResolver>,
unsigned short type, XPathResult*, ExceptionState&);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
DocumentXPathEvaluator();
static const char* supplementName() { return "DocumentXPathEvaluator"; }
- RefPtr<XPathEvaluator> m_xpathEvaluator;
+ RefPtrWillBeMember<XPathEvaluator> m_xpathEvaluator;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.idl b/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.idl
index ebe0ef4421e..8380ad0f4bf 100644
--- a/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/DocumentXPathEvaluator.idl
@@ -16,12 +16,13 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
+
partial interface Document {
// DOM Level 3 XPath (XPathEvaluator interface)
- [RaisesException] XPathExpression createExpression([Default=Undefined] optional DOMString expression,
+ [MeasureAs=DocumentXPathCreateExpression, RaisesException] XPathExpression createExpression([Default=Undefined] optional DOMString expression,
[Default=Undefined] optional XPathNSResolver resolver);
- XPathNSResolver createNSResolver(Node nodeResolver);
- [Custom, RaisesException] XPathResult evaluate([Default=Undefined] optional DOMString expression,
+ [MeasureAs=DocumentXPathCreateNSResolver] XPathNSResolver createNSResolver(Node nodeResolver);
+ [Custom, MeasureAs=DocumentXPathEvaluate, RaisesException] XPathResult evaluate([Default=Undefined] optional DOMString expression,
[Default=Undefined] optional Node contextNode,
[Default=Undefined] optional XPathNSResolver resolver,
[Default=Undefined] optional unsigned short type,
diff --git a/chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.cpp b/chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.cpp
index cbe118aaa38..694cbb5ea41 100644
--- a/chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.cpp
@@ -26,13 +26,13 @@
#include "config.h"
#include "core/xml/NativeXPathNSResolver.h"
-#include "XMLNames.h"
+#include "core/XMLNames.h"
#include "core/dom/Node.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
-NativeXPathNSResolver::NativeXPathNSResolver(PassRefPtr<Node> node)
+NativeXPathNSResolver::NativeXPathNSResolver(PassRefPtrWillBeRawPtr<Node> node)
: m_node(node)
{
}
@@ -51,4 +51,10 @@ AtomicString NativeXPathNSResolver::lookupNamespaceURI(const String& prefix)
return m_node ? m_node->lookupNamespaceURI(prefix) : nullAtom;
}
+void NativeXPathNSResolver::trace(Visitor* visitor)
+{
+ visitor->trace(m_node);
+ XPathNSResolver::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.h b/chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.h
index 79523100b4d..a09f766a5b7 100644
--- a/chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.h
+++ b/chromium/third_party/WebKit/Source/core/xml/NativeXPathNSResolver.h
@@ -33,16 +33,22 @@ namespace WebCore {
class Node;
-class NativeXPathNSResolver : public XPathNSResolver {
+class NativeXPathNSResolver FINAL : public XPathNSResolver {
public:
- static PassRefPtr<NativeXPathNSResolver> create(PassRefPtr<Node> node) { return adoptRef(new NativeXPathNSResolver(node)); }
+ static PassRefPtrWillBeRawPtr<NativeXPathNSResolver> create(PassRefPtrWillBeRawPtr<Node> node)
+ {
+ return adoptRefWillBeNoop(new NativeXPathNSResolver(node));
+ }
virtual ~NativeXPathNSResolver();
virtual AtomicString lookupNamespaceURI(const String& prefix) OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
- explicit NativeXPathNSResolver(PassRefPtr<Node>);
- RefPtr<Node> m_node;
+ explicit NativeXPathNSResolver(PassRefPtrWillBeRawPtr<Node>);
+
+ RefPtrWillBeMember<Node> m_node;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLErrors.cpp b/chromium/third_party/WebKit/Source/core/xml/XMLErrors.cpp
index 11936242c65..6db8d64cb4c 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLErrors.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLErrors.cpp
@@ -29,8 +29,8 @@
#include "config.h"
#include "core/xml/XMLErrors.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
+#include "core/HTMLNames.h"
+#include "core/SVGNames.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/Text.h"
@@ -49,6 +49,11 @@ XMLErrors::XMLErrors(Document* document)
{
}
+void XMLErrors::trace(Visitor* visitor)
+{
+ visitor->trace(m_document);
+}
+
void XMLErrors::handleError(ErrorType type, const char* message, int lineNumber, int columnNumber)
{
handleError(type, message, TextPosition(OrdinalNumber::fromOneBasedInt(lineNumber), OrdinalNumber::fromOneBasedInt(columnNumber)));
@@ -56,13 +61,13 @@ void XMLErrors::handleError(ErrorType type, const char* message, int lineNumber,
void XMLErrors::handleError(ErrorType type, const char* message, TextPosition position)
{
- if (type == fatal || (m_errorCount < maxErrors && m_lastErrorPosition.m_line != position.m_line && m_lastErrorPosition.m_column != position.m_column)) {
+ if (type == ErrorTypeFatal || (m_errorCount < maxErrors && m_lastErrorPosition.m_line != position.m_line && m_lastErrorPosition.m_column != position.m_column)) {
switch (type) {
- case warning:
+ case ErrorTypeWarning:
appendErrorMessage("warning", position, message);
break;
- case fatal:
- case nonFatal:
+ case ErrorTypeFatal:
+ case ErrorTypeNonFatal:
appendErrorMessage("error", position, message);
}
@@ -83,19 +88,19 @@ void XMLErrors::appendErrorMessage(const String& typeString, TextPosition positi
m_errorMessages.append(message);
}
-static inline PassRefPtr<Element> createXHTMLParserErrorHeader(Document* doc, const String& errorMessages)
+static inline PassRefPtrWillBeRawPtr<Element> createXHTMLParserErrorHeader(Document* doc, const String& errorMessages)
{
- RefPtr<Element> reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), true);
+ RefPtrWillBeRawPtr<Element> reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), true);
Vector<Attribute> reportAttributes;
reportAttributes.append(Attribute(styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black"));
reportElement->parserSetAttributes(reportAttributes);
- RefPtr<Element> h3 = doc->createElement(h3Tag, true);
+ RefPtrWillBeRawPtr<Element> h3 = doc->createElement(h3Tag, true);
reportElement->parserAppendChild(h3.get());
h3->parserAppendChild(doc->createTextNode("This page contains the following errors:"));
- RefPtr<Element> fixed = doc->createElement(divTag, true);
+ RefPtrWillBeRawPtr<Element> fixed = doc->createElement(divTag, true);
Vector<Attribute> fixedAttributes;
fixedAttributes.append(Attribute(styleAttr, "font-family:monospace;font-size:12px"));
fixed->parserSetAttributes(fixedAttributes);
@@ -117,16 +122,22 @@ void XMLErrors::insertErrorMessageBlock()
// where the errors are located)
// Create elements for display
- RefPtr<Element> documentElement = m_document->documentElement();
+ RefPtrWillBeRawPtr<Element> documentElement = m_document->documentElement();
if (!documentElement) {
- RefPtr<Element> rootElement = m_document->createElement(htmlTag, true);
- RefPtr<Element> body = m_document->createElement(bodyTag, true);
+ RefPtrWillBeRawPtr<Element> rootElement = m_document->createElement(htmlTag, true);
+ RefPtrWillBeRawPtr<Element> body = m_document->createElement(bodyTag, true);
rootElement->parserAppendChild(body);
m_document->parserAppendChild(rootElement);
documentElement = body.get();
} else if (documentElement->namespaceURI() == SVGNames::svgNamespaceURI) {
- RefPtr<Element> rootElement = m_document->createElement(htmlTag, true);
- RefPtr<Element> body = m_document->createElement(bodyTag, true);
+ RefPtrWillBeRawPtr<Element> rootElement = m_document->createElement(htmlTag, true);
+ RefPtrWillBeRawPtr<Element> head = m_document->createElement(headTag, true);
+ RefPtrWillBeRawPtr<Element> style = m_document->createElement(styleTag, true);
+ head->parserAppendChild(style);
+ style->parserAppendChild(m_document->createTextNode("html, body { height: 100% } parsererror + svg { width: 100%; height: 100% }"));
+ style->finishParsingChildren();
+ rootElement->parserAppendChild(head);
+ RefPtrWillBeRawPtr<Element> body = m_document->createElement(bodyTag, true);
rootElement->parserAppendChild(body);
m_document->parserRemoveChild(*documentElement);
@@ -138,12 +149,12 @@ void XMLErrors::insertErrorMessageBlock()
}
String errorMessages = m_errorMessages.toString();
- RefPtr<Element> reportElement = createXHTMLParserErrorHeader(m_document, errorMessages);
+ RefPtrWillBeRawPtr<Element> reportElement = createXHTMLParserErrorHeader(m_document, errorMessages);
if (m_document->transformSourceDocument()) {
Vector<Attribute> attributes;
attributes.append(Attribute(styleAttr, "white-space: normal"));
- RefPtr<Element> paragraph = m_document->createElement(pTag, true);
+ RefPtrWillBeRawPtr<Element> paragraph = m_document->createElement(pTag, true);
paragraph->parserSetAttributes(attributes);
paragraph->parserAppendChild(m_document->createTextNode("This document was created as the result of an XSL transformation. The line and column numbers given are from the transformed result."));
reportElement->parserAppendChild(paragraph.release());
@@ -156,7 +167,7 @@ void XMLErrors::insertErrorMessageBlock()
documentElement->parserAppendChild(reportElement);
// FIXME: Why do we need to call this manually?
- m_document->updateStyleIfNeeded();
+ m_document->updateRenderTreeIfNeeded();
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLErrors.h b/chromium/third_party/WebKit/Source/core/xml/XMLErrors.h
index 7adfd1e3a7f..a36a9a34f6d 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLErrors.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLErrors.h
@@ -29,6 +29,7 @@
#ifndef XMLErrors_h
#define XMLErrors_h
+#include "platform/heap/Handle.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/text/TextPosition.h"
@@ -37,11 +38,13 @@ namespace WebCore {
class Document;
class XMLErrors {
+ DISALLOW_ALLOCATION();
public:
explicit XMLErrors(Document*);
+ void trace(Visitor*);
// Exposed for callbacks:
- enum ErrorType { warning, nonFatal, fatal };
+ enum ErrorType { ErrorTypeWarning, ErrorTypeNonFatal, ErrorTypeFatal };
void handleError(ErrorType, const char* message, int lineNumber, int columnNumber);
void handleError(ErrorType, const char* message, TextPosition);
@@ -50,7 +53,7 @@ public:
private:
void appendErrorMessage(const String& typeString, TextPosition, const char* message);
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
int m_errorCount;
TextPosition m_lastErrorPosition;
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.cpp b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.cpp
index e89de304925..77fba6242f3 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.cpp
@@ -23,28 +23,31 @@
#include "config.h"
#include "core/xml/XMLHttpRequest.h"
-#include "FetchInitiatorTypeNames.h"
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/ContextFeatures.h"
#include "core/dom/DOMImplementation.h"
#include "core/dom/ExceptionCode.h"
+#include "core/dom/XMLDocument.h"
#include "core/editing/markup.h"
#include "core/events/Event.h"
#include "core/fetch/CrossOriginAccessControl.h"
-#include "core/fetch/TextResourceDecoder.h"
#include "core/fileapi/Blob.h"
#include "core/fileapi/File.h"
#include "core/fileapi/Stream.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/html/DOMFormData.h"
#include "core/html/HTMLDocument.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorTraceEvents.h"
#include "core/loader/ThreadableLoader.h"
-#include "core/frame/Settings.h"
#include "core/xml/XMLHttpRequestProgressEvent.h"
#include "core/xml/XMLHttpRequestUpload.h"
#include "platform/Logging.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/SharedBuffer.h"
#include "platform/blob/BlobData.h"
#include "platform/network/HTTPParsers.h"
@@ -54,6 +57,7 @@
#include "public/platform/Platform.h"
#include "wtf/ArrayBuffer.h"
#include "wtf/ArrayBufferView.h"
+#include "wtf/Assertions.h"
#include "wtf/RefCountedLeakCounter.h"
#include "wtf/StdLibExtras.h"
#include "wtf/text/CString.h"
@@ -112,7 +116,7 @@ static bool isSetCookieHeader(const AtomicString& name)
static void replaceCharsetInMediaType(String& mediaType, const String& charsetValue)
{
- unsigned int pos = 0, len = 0;
+ unsigned pos = 0, len = 0;
findCharsetInMediaType(mediaType, pos, len);
@@ -124,7 +128,7 @@ static void replaceCharsetInMediaType(String& mediaType, const String& charsetVa
// Found at least one existing charset, replace all occurrences with new charset.
while (len) {
mediaType.replace(pos, len, charsetValue);
- unsigned int start = pos + charsetValue.length();
+ unsigned start = pos + charsetValue.length();
findCharsetInMediaType(mediaType, pos, len, start);
}
}
@@ -153,9 +157,9 @@ static void logConsoleError(ExecutionContext* context, const String& message)
context->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message);
}
-PassRefPtr<XMLHttpRequest> XMLHttpRequest::create(ExecutionContext* context, PassRefPtr<SecurityOrigin> securityOrigin)
+PassRefPtrWillBeRawPtr<XMLHttpRequest> XMLHttpRequest::create(ExecutionContext* context, PassRefPtr<SecurityOrigin> securityOrigin)
{
- RefPtr<XMLHttpRequest> xmlHttpRequest(adoptRef(new XMLHttpRequest(context, securityOrigin)));
+ RefPtrWillBeRawPtr<XMLHttpRequest> xmlHttpRequest = adoptRefWillBeRefCountedGarbageCollected(new XMLHttpRequest(context, securityOrigin));
xmlHttpRequest->suspendIfNeeded();
return xmlHttpRequest.release();
@@ -242,26 +246,28 @@ Document* XMLHttpRequest::responseXML(ExceptionState& exceptionState)
return 0;
if (!m_createdDocument) {
- bool isHTML = equalIgnoringCase(responseMIMEType(), "text/html");
+ AtomicString mimeType = responseMIMEType();
+ bool isHTML = equalIgnoringCase(mimeType, "text/html");
// The W3C spec requires the final MIME type to be some valid XML type, or text/html.
// If it is text/html, then the responseType of "document" must have been supplied explicitly.
if ((m_response.isHTTP() && !responseIsXML() && !isHTML)
|| (isHTML && m_responseTypeCode == ResponseTypeDefault)
|| executionContext()->isWorkerGlobalScope()) {
- m_responseDocument = 0;
+ m_responseDocument = nullptr;
} else {
DocumentInit init = DocumentInit::fromContext(document()->contextDocument(), m_url);
if (isHTML)
m_responseDocument = HTMLDocument::create(init);
else
- m_responseDocument = Document::create(init);
+ m_responseDocument = XMLDocument::create(init);
// FIXME: Set Last-Modified.
m_responseDocument->setContent(m_responseText.flattenToString());
m_responseDocument->setSecurityOrigin(securityOrigin());
m_responseDocument->setContextFeatures(document()->contextFeatures());
+ m_responseDocument->setMimeType(mimeType);
if (!m_responseDocument->wellFormed())
- m_responseDocument = 0;
+ m_responseDocument = nullptr;
}
m_createdDocument = true;
}
@@ -279,14 +285,14 @@ Blob* XMLHttpRequest::responseBlob()
return 0;
if (!m_responseBlob) {
- // When "blob" is specified for the responseType attribute,
- // we redirect the downloaded data to a file-handle directly
- // in the browser process.
- // We get the file-path from the ResourceResponse directly
- // instead of copying the bytes between the browser and the renderer.
+ // When responseType is set to "blob", we redirect the downloaded data
+ // to a file-handle directly in the browser process. We get the
+ // file-path from the ResourceResponse directly instead of copying the
+ // bytes between the browser and the renderer.
OwnPtr<BlobData> blobData = BlobData::create();
String filePath = m_response.downloadedFilePath();
- // If we errored out or got no data, we still return a blob, just an empty one.
+ // If we errored out or got no data, we still return a blob, just an
+ // empty one.
if (!filePath.isEmpty() && m_downloadedBlobLength) {
blobData->appendFile(filePath);
blobData->setContentType(responseMIMEType()); // responseMIMEType defaults to text/xml which may be incorrect.
@@ -307,6 +313,12 @@ ArrayBuffer* XMLHttpRequest::responseArrayBuffer()
if (!m_responseArrayBuffer.get()) {
if (m_binaryResponseBuilder.get() && m_binaryResponseBuilder->size() > 0) {
m_responseArrayBuffer = m_binaryResponseBuilder->getAsArrayBuffer();
+ if (!m_responseArrayBuffer) {
+ // m_binaryResponseBuilder failed to allocate an ArrayBuffer.
+ // We need to crash the renderer since there's no way defined in
+ // the spec to tell this to the user.
+ CRASH();
+ }
m_binaryResponseBuilder.clear();
} else {
m_responseArrayBuffer = ArrayBuffer::create(static_cast<void*>(0), 0);
@@ -346,9 +358,7 @@ void XMLHttpRequest::setResponseType(const String& responseType, ExceptionState&
// Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated
// attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
- // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols
- // such as file: and data: still make sense to allow.
- if (!m_async && executionContext()->isDocument() && m_url.protocolIsInHTTPFamily()) {
+ if (!m_async && executionContext()->isDocument()) {
exceptionState.throwDOMException(InvalidAccessError, "The response type can only be changed for asynchronous HTTP requests made from a document.");
return;
}
@@ -396,6 +406,11 @@ String XMLHttpRequest::responseType()
return "";
}
+String XMLHttpRequest::responseURL()
+{
+ return m_response.url().string();
+}
+
XMLHttpRequestUpload* XMLHttpRequest::upload()
{
if (!m_upload)
@@ -408,7 +423,7 @@ void XMLHttpRequest::trackProgress(int length)
m_receivedLength += length;
if (m_async)
- dispatchThrottledProgressEventSnapshot(EventTypeNames::progress);
+ dispatchProgressEventFromSnapshot(EventTypeNames::progress);
if (m_state != LOADING) {
changeState(LOADING);
@@ -438,6 +453,8 @@ void XMLHttpRequest::dispatchReadyStateChangeEvent()
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchXHRReadyStateChangeEvent(executionContext(), this);
if (m_async || (m_state <= OPENED || m_state == DONE)) {
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "XHRReadyStateChange", "data", InspectorXhrReadyStateChangeEvent::data(executionContext(), this));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
ProgressEventAction flushAction = DoNotFlushProgressEvent;
if (m_state == DONE) {
if (m_error)
@@ -446,14 +463,20 @@ void XMLHttpRequest::dispatchReadyStateChangeEvent()
flushAction = FlushProgressEvent;
}
m_progressEventThrottle.dispatchReadyStateChangeEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::readystatechange), flushAction);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
}
InspectorInstrumentation::didDispatchXHRReadyStateChangeEvent(cookie);
if (m_state == DONE && !m_error) {
- InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchXHRLoadEvent(executionContext(), this);
- dispatchThrottledProgressEventSnapshot(EventTypeNames::load);
- InspectorInstrumentation::didDispatchXHRLoadEvent(cookie);
- dispatchThrottledProgressEventSnapshot(EventTypeNames::loadend);
+ {
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "XHRLoad", "data", InspectorXhrLoadEvent::data(executionContext(), this));
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack());
+ InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchXHRLoadEvent(executionContext(), this);
+ dispatchProgressEventFromSnapshot(EventTypeNames::load);
+ InspectorInstrumentation::didDispatchXHRLoadEvent(cookie);
+ }
+ dispatchProgressEventFromSnapshot(EventTypeNames::loadend);
+ TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data());
}
}
@@ -464,6 +487,11 @@ void XMLHttpRequest::setWithCredentials(bool value, ExceptionState& exceptionSta
return;
}
+ // FIXME: According to XMLHttpRequest Level 2 we should throw InvalidAccessError exception here.
+ // However for time being only print warning message to warn web developers.
+ if (!m_async)
+ UseCounter::countDeprecation(executionContext(), UseCounter::SyncXHRWithCredentials);
+
m_includeCredentials = value;
}
@@ -517,7 +545,7 @@ void XMLHttpRequest::open(const AtomicString& method, const KURL& url, Exception
void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool async, ExceptionState& exceptionState)
{
- WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.string().utf8().data(), url.elidedString().utf8().data(), async);
+ WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.utf8().data(), url.elidedString().utf8().data(), async);
if (!internalAbort())
return;
@@ -557,10 +585,8 @@ void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool asyn
// Newer functionality is not available to synchronous requests in window contexts, as a spec-mandated
// attempt to discourage synchronous XHR use. responseType is one such piece of functionality.
- // We'll only disable this functionality for HTTP(S) requests since sync requests for local protocols
- // such as file: and data: still make sense to allow.
- if (url.protocolIsInHTTPFamily() && m_responseTypeCode != ResponseTypeDefault) {
- exceptionState.throwDOMException(InvalidAccessError, "Synchronous HTTP requests from a document must not set a response type.");
+ if (m_responseTypeCode != ResponseTypeDefault) {
+ exceptionState.throwDOMException(InvalidAccessError, "Synchronous requests from a document must not set a response type.");
return;
}
@@ -637,6 +663,8 @@ void XMLHttpRequest::send(Document* document, ExceptionState& exceptionState)
if (!initSend(exceptionState))
return;
+ RefPtr<FormData> httpBody;
+
if (areMethodAndURLValidForSend()) {
if (getRequestHeader("Content-Type").isEmpty()) {
// FIXME: this should include the charset used for encoding.
@@ -648,12 +676,12 @@ void XMLHttpRequest::send(Document* document, ExceptionState& exceptionState)
String body = createMarkup(document);
// FIXME: This should use value of document.inputEncoding to determine the encoding to use.
- m_requestEntityBody = FormData::create(UTF8Encoding().encode(body, WTF::EntitiesForUnencodables));
+ httpBody = FormData::create(UTF8Encoding().encode(body, WTF::EntitiesForUnencodables));
if (m_upload)
- m_requestEntityBody->setAlwaysStream(true);
+ httpBody->setAlwaysStream(true);
}
- createRequest(exceptionState);
+ createRequest(httpBody.release(), exceptionState);
}
void XMLHttpRequest::send(const String& body, ExceptionState& exceptionState)
@@ -663,6 +691,8 @@ void XMLHttpRequest::send(const String& body, ExceptionState& exceptionState)
if (!initSend(exceptionState))
return;
+ RefPtr<FormData> httpBody;
+
if (!body.isNull() && areMethodAndURLValidForSend()) {
String contentType = getRequestHeader("Content-Type");
if (contentType.isEmpty()) {
@@ -672,12 +702,12 @@ void XMLHttpRequest::send(const String& body, ExceptionState& exceptionState)
m_requestHeaders.set("Content-Type", AtomicString(contentType));
}
- m_requestEntityBody = FormData::create(UTF8Encoding().encode(body, WTF::EntitiesForUnencodables));
+ httpBody = FormData::create(UTF8Encoding().encode(body, WTF::EntitiesForUnencodables));
if (m_upload)
- m_requestEntityBody->setAlwaysStream(true);
+ httpBody->setAlwaysStream(true);
}
- createRequest(exceptionState);
+ createRequest(httpBody.release(), exceptionState);
}
void XMLHttpRequest::send(Blob* body, ExceptionState& exceptionState)
@@ -687,26 +717,36 @@ void XMLHttpRequest::send(Blob* body, ExceptionState& exceptionState)
if (!initSend(exceptionState))
return;
+ RefPtr<FormData> httpBody;
+
if (areMethodAndURLValidForSend()) {
if (getRequestHeader("Content-Type").isEmpty()) {
const String& blobType = body->type();
- if (!blobType.isEmpty() && isValidContentType(blobType))
+ if (!blobType.isEmpty() && isValidContentType(blobType)) {
setRequestHeaderInternal("Content-Type", AtomicString(blobType));
- else {
- // From FileAPI spec, whenever media type cannot be determined, empty string must be returned.
+ } else {
+ // From FileAPI spec, whenever media type cannot be determined,
+ // empty string must be returned.
setRequestHeaderInternal("Content-Type", "");
}
}
// FIXME: add support for uploading bundles.
- m_requestEntityBody = FormData::create();
- if (body->hasBackingFile())
- m_requestEntityBody->appendFile(toFile(body)->path());
- else
- m_requestEntityBody->appendBlob(body->uuid(), body->blobDataHandle());
+ httpBody = FormData::create();
+ if (body->hasBackingFile()) {
+ File* file = toFile(body);
+ if (!file->path().isEmpty())
+ httpBody->appendFile(file->path());
+ else if (!file->fileSystemURL().isEmpty())
+ httpBody->appendFileSystemURL(file->fileSystemURL());
+ else
+ ASSERT_NOT_REACHED();
+ } else {
+ httpBody->appendBlob(body->uuid(), body->blobDataHandle());
+ }
}
- createRequest(exceptionState);
+ createRequest(httpBody.release(), exceptionState);
}
void XMLHttpRequest::send(DOMFormData* body, ExceptionState& exceptionState)
@@ -716,16 +756,18 @@ void XMLHttpRequest::send(DOMFormData* body, ExceptionState& exceptionState)
if (!initSend(exceptionState))
return;
+ RefPtr<FormData> httpBody;
+
if (areMethodAndURLValidForSend()) {
- m_requestEntityBody = body->createMultiPartFormData(body->encoding());
+ httpBody = body->createMultiPartFormData();
if (getRequestHeader("Content-Type").isEmpty()) {
- AtomicString contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + m_requestEntityBody->boundary().data();
+ AtomicString contentType = AtomicString("multipart/form-data; boundary=", AtomicString::ConstructFromLiteral) + httpBody->boundary().data();
setRequestHeaderInternal("Content-Type", contentType);
}
}
- createRequest(exceptionState);
+ createRequest(httpBody.release(), exceptionState);
}
void XMLHttpRequest::send(ArrayBuffer* body, ExceptionState& exceptionState)
@@ -754,23 +796,24 @@ void XMLHttpRequest::sendBytesData(const void* data, size_t length, ExceptionSta
if (!initSend(exceptionState))
return;
+ RefPtr<FormData> httpBody;
+
if (areMethodAndURLValidForSend()) {
- m_requestEntityBody = FormData::create(data, length);
+ httpBody = FormData::create(data, length);
if (m_upload)
- m_requestEntityBody->setAlwaysStream(true);
+ httpBody->setAlwaysStream(true);
}
- createRequest(exceptionState);
+ createRequest(httpBody.release(), exceptionState);
}
void XMLHttpRequest::sendForInspectorXHRReplay(PassRefPtr<FormData> formData, ExceptionState& exceptionState)
{
- m_requestEntityBody = formData ? formData->deepCopy() : 0;
- createRequest(exceptionState);
+ createRequest(formData ? formData->deepCopy() : nullptr, exceptionState);
m_exceptionCode = exceptionState.code();
}
-void XMLHttpRequest::createRequest(ExceptionState& exceptionState)
+void XMLHttpRequest::createRequest(PassRefPtr<FormData> httpBody, ExceptionState& exceptionState)
{
// Only GET request is supported for blob URL.
if (m_url.protocolIs("blob") && m_method != "GET") {
@@ -783,8 +826,8 @@ void XMLHttpRequest::createRequest(ExceptionState& exceptionState)
// Also, only async requests support upload progress events.
bool uploadEvents = false;
if (m_async) {
- m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::loadstart));
- if (m_requestEntityBody && m_upload) {
+ dispatchProgressEvent(EventTypeNames::loadstart, 0, 0);
+ if (httpBody && m_upload) {
uploadEvents = m_upload->hasEventListeners();
m_upload->dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::loadstart));
}
@@ -796,46 +839,44 @@ void XMLHttpRequest::createRequest(ExceptionState& exceptionState)
// added after the request is started.
m_uploadEventsAllowed = m_sameOriginRequest || uploadEvents || !isSimpleCrossOriginAccessRequest(m_method, m_requestHeaders);
+ ASSERT(executionContext());
+ ExecutionContext& executionContext = *this->executionContext();
+
ResourceRequest request(m_url);
request.setHTTPMethod(m_method);
request.setTargetType(ResourceRequest::TargetIsXHR);
- // When "blob" is specified for the responseType attribute,
- // we redirect the downloaded data to a file-handle directly
- // and get the file-path as the result.
- if (responseTypeCode() == ResponseTypeBlob)
- request.setDownloadToFile(true);
-
- InspectorInstrumentation::willLoadXHR(executionContext(), this, this, m_method, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : 0, m_requestHeaders, m_includeCredentials);
+ InspectorInstrumentation::willLoadXHR(&executionContext, this, this, m_method, m_url, m_async, httpBody ? httpBody->deepCopy() : nullptr, m_requestHeaders, m_includeCredentials);
- if (m_requestEntityBody) {
+ if (httpBody) {
ASSERT(m_method != "GET");
ASSERT(m_method != "HEAD");
- request.setHTTPBody(m_requestEntityBody.release());
+ request.setHTTPBody(httpBody);
}
if (m_requestHeaders.size() > 0)
request.addHTTPHeaderFields(m_requestHeaders);
ThreadableLoaderOptions options;
- options.sendLoadCallbacks = SendCallbacks;
- options.sniffContent = DoNotSniffContent;
options.preflightPolicy = uploadEvents ? ForcePreflight : ConsiderPreflight;
- options.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
- options.credentialsRequested = m_includeCredentials ? ClientRequestedCredentials : ClientDidNotRequestCredentials;
options.crossOriginRequestPolicy = UseAccessControl;
- options.securityOrigin = securityOrigin();
options.initiator = FetchInitiatorTypeNames::xmlhttprequest;
- options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypassMainWorld(executionContext()) ? DoNotEnforceContentSecurityPolicy : EnforceConnectSrcDirective;
- // TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303.
- options.mixedContentBlockingTreatment = TreatAsPassiveContent;
+ options.contentSecurityPolicyEnforcement = ContentSecurityPolicy::shouldBypassMainWorld(&executionContext) ? DoNotEnforceContentSecurityPolicy : EnforceConnectSrcDirective;
options.timeoutMilliseconds = m_timeoutMilliseconds;
- // Since we redirect the downloaded data to a file-handle directly
- // when "blob" is specified for the responseType attribute,
- // buffering is not needed.
- if (responseTypeCode() == ResponseTypeBlob)
- options.dataBufferingPolicy = DoNotBufferData;
+ ResourceLoaderOptions resourceLoaderOptions;
+ resourceLoaderOptions.allowCredentials = (m_sameOriginRequest || m_includeCredentials) ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+ resourceLoaderOptions.credentialsRequested = m_includeCredentials ? ClientRequestedCredentials : ClientDidNotRequestCredentials;
+ resourceLoaderOptions.securityOrigin = securityOrigin();
+ // TODO(tsepez): Specify TreatAsActiveContent per http://crbug.com/305303.
+ resourceLoaderOptions.mixedContentBlockingTreatment = TreatAsPassiveContent;
+
+ // When responseType is set to "blob", we redirect the downloaded data to a
+ // file-handle directly.
+ if (responseTypeCode() == ResponseTypeBlob) {
+ request.setDownloadToFile(true);
+ resourceLoaderOptions.dataBufferingPolicy = DoNotBufferData;
+ }
m_exceptionCode = 0;
m_error = false;
@@ -849,7 +890,7 @@ void XMLHttpRequest::createRequest(ExceptionState& exceptionState)
// FIXME: Maybe we need to be able to send XMLHttpRequests from onunload, <http://bugs.webkit.org/show_bug.cgi?id=10904>.
// FIXME: Maybe create() can return null for other reasons too?
ASSERT(!m_loader);
- m_loader = ThreadableLoader::create(executionContext(), this, request, options);
+ m_loader = ThreadableLoader::create(executionContext, this, request, options, resourceLoaderOptions);
if (m_loader) {
// Neither this object nor the JavaScript wrapper should be deleted while
// a request is in progress because we need to keep the listeners alive,
@@ -857,13 +898,15 @@ void XMLHttpRequest::createRequest(ExceptionState& exceptionState)
setPendingActivity(this);
}
} else {
- ThreadableLoader::loadResourceSynchronously(executionContext(), request, *this, options);
+ // Use count for XHR synchronous requests.
+ UseCounter::count(&executionContext, UseCounter::XMLHttpRequestSynchronous);
+ ThreadableLoader::loadResourceSynchronously(executionContext, request, *this, options, resourceLoaderOptions);
}
if (!m_exceptionCode && m_error)
m_exceptionCode = NetworkError;
if (m_exceptionCode)
- exceptionState.throwUninformativeAndGenericDOMException(m_exceptionCode);
+ exceptionState.throwDOMException(m_exceptionCode, "Failed to load '" + m_url.elidedString() + "'.");
}
void XMLHttpRequest::abort()
@@ -871,7 +914,7 @@ void XMLHttpRequest::abort()
WTF_LOG(Network, "XMLHttpRequest %p abort()", this);
// internalAbort() calls dropProtection(), which may release the last reference.
- RefPtr<XMLHttpRequest> protect(this);
+ RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
bool sendFlag = m_loader;
@@ -957,11 +1000,12 @@ void XMLHttpRequest::clearResponse()
m_responseText.clear();
m_createdDocument = false;
- m_responseDocument = 0;
+ m_responseDocument = nullptr;
- m_responseBlob = 0;
+ m_responseBlob = nullptr;
+ m_downloadedBlobLength = 0;
- m_responseStream = 0;
+ m_responseStream = nullptr;
// These variables may referred by the response accessors. So, we can clear
// this only when we clear the response holder variables above.
@@ -972,7 +1016,6 @@ void XMLHttpRequest::clearResponse()
void XMLHttpRequest::clearRequest()
{
m_requestHeaders.clear();
- m_requestEntityBody = 0;
}
void XMLHttpRequest::handleDidFailGeneric()
@@ -983,30 +1026,18 @@ void XMLHttpRequest::handleDidFailGeneric()
m_error = true;
}
-void XMLHttpRequest::dispatchEventAndLoadEnd(const AtomicString& type, long long receivedLength, long long expectedLength)
-{
- bool lengthComputable = expectedLength > 0 && receivedLength <= expectedLength;
- unsigned long long loaded = receivedLength >= 0 ? static_cast<unsigned long long>(receivedLength) : 0;
- unsigned long long total = lengthComputable ? static_cast<unsigned long long>(expectedLength) : 0;
-
- m_progressEventThrottle.dispatchEventAndLoadEnd(type, lengthComputable, loaded, total);
-}
-
-void XMLHttpRequest::dispatchThrottledProgressEvent(const AtomicString& type, long long receivedLength, long long expectedLength)
+void XMLHttpRequest::dispatchProgressEvent(const AtomicString& type, long long receivedLength, long long expectedLength)
{
bool lengthComputable = expectedLength > 0 && receivedLength <= expectedLength;
unsigned long long loaded = receivedLength >= 0 ? static_cast<unsigned long long>(receivedLength) : 0;
unsigned long long total = lengthComputable ? static_cast<unsigned long long>(expectedLength) : 0;
- if (type == EventTypeNames::progress)
- m_progressEventThrottle.dispatchProgressEvent(lengthComputable, loaded, total);
- else
- m_progressEventThrottle.dispatchEvent(XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total));
+ m_progressEventThrottle.dispatchProgressEvent(type, lengthComputable, loaded, total);
}
-void XMLHttpRequest::dispatchThrottledProgressEventSnapshot(const AtomicString& type)
+void XMLHttpRequest::dispatchProgressEventFromSnapshot(const AtomicString& type)
{
- return dispatchThrottledProgressEvent(type, m_receivedLength, m_response.expectedContentLength());
+ dispatchProgressEvent(type, m_receivedLength, m_response.expectedContentLength());
}
void XMLHttpRequest::handleNetworkError()
@@ -1058,8 +1089,9 @@ void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const Atomi
m_upload->handleRequestError(type);
}
- dispatchThrottledProgressEvent(EventTypeNames::progress, receivedLength, expectedLength);
- dispatchEventAndLoadEnd(type, receivedLength, expectedLength);
+ dispatchProgressEvent(EventTypeNames::progress, receivedLength, expectedLength);
+ dispatchProgressEvent(type, receivedLength, expectedLength);
+ dispatchProgressEvent(EventTypeNames::loadend, receivedLength, expectedLength);
}
void XMLHttpRequest::dropProtectionSoon()
@@ -1107,7 +1139,7 @@ void XMLHttpRequest::setRequestHeaderInternal(const AtomicString& name, const At
{
HTTPHeaderMap::AddResult result = m_requestHeaders.add(name, value);
if (!result.isNewEntry)
- result.iterator->value = result.iterator->value + ", " + value;
+ result.storedValue->value = result.storedValue->value + ", " + value;
}
const AtomicString& XMLHttpRequest::getRequestHeader(const AtomicString& name) const
@@ -1187,9 +1219,7 @@ AtomicString XMLHttpRequest::responseMIMEType() const
bool XMLHttpRequest::responseIsXML() const
{
- // FIXME: Remove the lower() call when DOMImplementation.isXMLMIMEType() is modified
- // to do case insensitive MIME type matching.
- return DOMImplementation::isXMLMIMEType(responseMIMEType().lower());
+ return DOMImplementation::isXMLMIMEType(responseMIMEType());
}
int XMLHttpRequest::status() const
@@ -1264,13 +1294,13 @@ void XMLHttpRequest::didFinishLoading(unsigned long identifier, double)
clearVariablesForLoading();
- InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this, identifier, m_responseText, m_url, m_lastSendURL, m_lastSendLineNumber);
+ InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this, identifier, m_responseText, m_method, m_url, m_lastSendURL, m_lastSendLineNumber);
// Prevent dropProtection releasing the last reference, and retain |this| until the end of this method.
- RefPtr<XMLHttpRequest> protect(this);
+ RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
if (m_loader) {
- m_loader = 0;
+ m_loader = nullptr;
dropProtection();
}
@@ -1321,19 +1351,22 @@ void XMLHttpRequest::didReceiveData(const char* data, int len)
bool useDecoder = m_responseTypeCode == ResponseTypeDefault || m_responseTypeCode == ResponseTypeText || m_responseTypeCode == ResponseTypeJSON || m_responseTypeCode == ResponseTypeDocument;
if (useDecoder && !m_decoder) {
- if (m_responseTypeCode == ResponseTypeJSON)
+ if (m_responseTypeCode == ResponseTypeJSON) {
m_decoder = TextResourceDecoder::create("application/json", "UTF-8");
- else if (!m_responseEncoding.isEmpty())
+ } else if (!m_responseEncoding.isEmpty()) {
m_decoder = TextResourceDecoder::create("text/plain", m_responseEncoding);
// allow TextResourceDecoder to look inside the m_response if it's XML or HTML
- else if (responseIsXML()) {
+ } else if (responseIsXML()) {
m_decoder = TextResourceDecoder::create("application/xml");
- // Don't stop on encoding errors, unlike it is done for other kinds of XML resources. This matches the behavior of previous WebKit versions, Firefox and Opera.
+ // Don't stop on encoding errors, unlike it is done for other kinds
+ // of XML resources. This matches the behavior of previous WebKit
+ // versions, Firefox and Opera.
m_decoder->useLenientXMLDecoding();
- } else if (equalIgnoringCase(responseMIMEType(), "text/html"))
+ } else if (equalIgnoringCase(responseMIMEType(), "text/html")) {
m_decoder = TextResourceDecoder::create("text/html", "UTF-8");
- else
+ } else {
m_decoder = TextResourceDecoder::create("text/plain", "UTF-8");
+ }
}
if (!len)
@@ -1374,10 +1407,13 @@ void XMLHttpRequest::didDownloadData(int dataLength)
if (!dataLength)
return;
+ // readystatechange event handler may do something to put this XHR in error
+ // state. We need to check m_error again here.
if (m_error)
return;
m_downloadedBlobLength += dataLength;
+
trackProgress(dataLength);
}
@@ -1386,7 +1422,7 @@ void XMLHttpRequest::handleDidTimeout()
WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
// internalAbort() calls dropProtection(), which may release the last reference.
- RefPtr<XMLHttpRequest> protect(this);
+ RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
// Response is cleared next, save needed progress event data.
long long expectedLength = m_response.expectedContentLength();
@@ -1430,4 +1466,14 @@ ExecutionContext* XMLHttpRequest::executionContext() const
return ActiveDOMObject::executionContext();
}
+void XMLHttpRequest::trace(Visitor* visitor)
+{
+ visitor->trace(m_responseBlob);
+ visitor->trace(m_responseStream);
+ visitor->trace(m_responseDocument);
+ visitor->trace(m_progressEventThrottle);
+ visitor->trace(m_upload);
+ XMLHttpRequestEventTarget::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.h b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.h
index 00bde33130b..5025564c319 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.h
@@ -26,11 +26,11 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/ActiveDOMObject.h"
#include "core/events/EventListener.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/loader/ThreadableLoaderClient.h"
#include "core/xml/XMLHttpRequestEventTarget.h"
#include "core/xml/XMLHttpRequestProgressEventThrottle.h"
#include "platform/AsyncMethodRunner.h"
+#include "platform/heap/Handle.h"
#include "platform/network/FormData.h"
#include "platform/network/ResourceResponse.h"
#include "platform/weborigin/SecurityOrigin.h"
@@ -53,12 +53,18 @@ class ThreadableLoader;
typedef int ExceptionCode;
-class XMLHttpRequest : public ScriptWrappable, public RefCounted<XMLHttpRequest>, public XMLHttpRequestEventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
- WTF_MAKE_FAST_ALLOCATED;
+class XMLHttpRequest FINAL
+ : public RefCountedWillBeRefCountedGarbageCollected<XMLHttpRequest>
+ , public ScriptWrappable
+ , public XMLHttpRequestEventTarget
+ , private ThreadableLoaderClient
+ , public ActiveDOMObject {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
REFCOUNTED_EVENT_TARGET(XMLHttpRequest);
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(XMLHttpRequest);
public:
- static PassRefPtr<XMLHttpRequest> create(ExecutionContext*, PassRefPtr<SecurityOrigin> = 0);
- ~XMLHttpRequest();
+ static PassRefPtrWillBeRawPtr<XMLHttpRequest> create(ExecutionContext*, PassRefPtr<SecurityOrigin> = nullptr);
+ virtual ~XMLHttpRequest();
// These exact numeric values are important because JS expects them.
enum State {
@@ -84,10 +90,10 @@ public:
DropProtectionAsync,
};
- virtual void contextDestroyed();
- virtual void suspend();
- virtual void resume();
- virtual void stop();
+ virtual void contextDestroyed() OVERRIDE;
+ virtual void suspend() OVERRIDE;
+ virtual void resume() OVERRIDE;
+ virtual void stop() OVERRIDE;
virtual const AtomicString& interfaceName() const OVERRIDE;
virtual ExecutionContext* executionContext() const OVERRIDE;
@@ -133,6 +139,8 @@ public:
String responseType();
ResponseTypeCode responseTypeCode() const { return m_responseTypeCode; }
+ String responseURL();
+
// response attribute has custom getter.
ArrayBuffer* responseArrayBuffer();
@@ -143,21 +151,23 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
XMLHttpRequest(ExecutionContext*, PassRefPtr<SecurityOrigin>);
Document* document() const;
SecurityOrigin* securityOrigin() const;
- virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
- virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&);
- virtual void didReceiveData(const char* data, int dataLength);
- // When "blob" is specified as the responseType attribute, didDownloadData
- // is called instead of didReceiveData.
- virtual void didDownloadData(int dataLength);
- virtual void didFinishLoading(unsigned long identifier, double finishTime);
- virtual void didFail(const ResourceError&);
- virtual void didFailRedirectCheck();
+ virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
+ virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) OVERRIDE;
+ virtual void didReceiveData(const char* data, int dataLength) OVERRIDE;
+ // When responseType is set to "blob", didDownloadData() is called instead
+ // of didReceiveData().
+ virtual void didDownloadData(int dataLength) OVERRIDE;
+ virtual void didFinishLoading(unsigned long identifier, double finishTime) OVERRIDE;
+ virtual void didFail(const ResourceError&) OVERRIDE;
+ virtual void didFailRedirectCheck() OVERRIDE;
AtomicString responseMIMEType() const;
bool responseIsXML() const;
@@ -186,17 +196,13 @@ private:
void clearResponse();
void clearRequest();
- void createRequest(ExceptionState&);
-
- // Dispatches an event of the specified type to m_progressEventThrottle.
- void dispatchEventAndLoadEnd(const AtomicString&, long long, long long);
+ void createRequest(PassRefPtr<FormData>, ExceptionState&);
- // Dispatches a response progress event to m_progressEventThrottle.
- void dispatchThrottledProgressEvent(const AtomicString&, long long, long long);
-
- // Dispatches a response progress event using values sampled from
+ // Dispatches a response ProgressEvent.
+ void dispatchProgressEvent(const AtomicString&, long long, long long);
+ // Dispatches a response ProgressEvent using values sampled from
// m_receivedLength and m_response.
- void dispatchThrottledProgressEventSnapshot(const AtomicString&);
+ void dispatchProgressEventFromSnapshot(const AtomicString&);
// Does clean up common for all kind of didFail() call.
void handleDidFailGeneric();
@@ -209,18 +215,17 @@ private:
void handleRequestError(ExceptionCode, const AtomicString&, long long, long long);
- OwnPtr<XMLHttpRequestUpload> m_upload;
+ OwnPtrWillBeMember<XMLHttpRequestUpload> m_upload;
KURL m_url;
AtomicString m_method;
HTTPHeaderMap m_requestHeaders;
- RefPtr<FormData> m_requestEntityBody;
AtomicString m_mimeTypeOverride;
bool m_async;
bool m_includeCredentials;
unsigned long m_timeoutMilliseconds;
- RefPtr<Blob> m_responseBlob;
- RefPtr<Stream> m_responseStream;
+ RefPtrWillBeMember<Blob> m_responseBlob;
+ RefPtrWillBeMember<Stream> m_responseStream;
RefPtr<ThreadableLoader> m_loader;
State m_state;
@@ -234,10 +239,11 @@ private:
// Used to skip m_responseDocument creation if it's done previously. We need
// this separate flag since m_responseDocument can be 0 for some cases.
bool m_createdDocument;
- RefPtr<Document> m_responseDocument;
+ RefPtrWillBeMember<Document> m_responseDocument;
RefPtr<SharedBuffer> m_binaryResponseBuilder;
long long m_downloadedBlobLength;
+
RefPtr<ArrayBuffer> m_responseArrayBuffer;
bool m_error;
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.idl b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.idl
index 2fba4d654a1..c69a568af4e 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequest.idl
@@ -37,9 +37,10 @@ enum XMLHttpRequestResponseType {
};
[
+ WillBeGarbageCollected,
ActiveDOMObject,
CustomConstructor(optional XMLHttpRequestOptions options),
- GlobalContext=Window&WorkerGlobalScope,
+ Exposed=Window&Worker
] interface XMLHttpRequest : XMLHttpRequestEventTarget {
// event handler attributes
attribute EventHandler onreadystatechange;
@@ -56,9 +57,9 @@ enum XMLHttpRequestResponseType {
[RaisesException=Setter] attribute boolean withCredentials;
- [Custom, ActivityLogging=ForAllWorlds, RaisesException] void open(DOMString method, DOMString url, optional boolean async, optional DOMString user, optional DOMString password);
+ [Custom, LogActivity, LogAllWorlds, RaisesException] void open(DOMString method, DOMString url, optional boolean async, optional DOMString user, optional DOMString password);
- [ActivityLogging=ForAllWorlds, RaisesException] void setRequestHeader(DOMString header, DOMString value);
+ [LogActivity, LogAllWorlds, RaisesException] void setRequestHeader(DOMString header, DOMString value);
[Custom, RaisesException] void send();
@@ -74,6 +75,7 @@ enum XMLHttpRequestResponseType {
[RaisesException=Setter] attribute XMLHttpRequestResponseType responseType;
[Custom=Getter, RaisesException=Getter] readonly attribute object response;
+ readonly attribute DOMString responseURL;
readonly attribute unsigned short status;
readonly attribute DOMString statusText;
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.h b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.h
index c6ab4a4dbd8..58696cf41a4 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.h
@@ -28,26 +28,27 @@
#define XMLHttpRequestProgressEvent_h
#include "core/events/ProgressEvent.h"
-#include "core/events/ThreadLocalEventNames.h"
namespace WebCore {
-class XMLHttpRequestProgressEvent : public ProgressEvent {
+class XMLHttpRequestProgressEvent FINAL : public ProgressEvent {
public:
- static PassRefPtr<XMLHttpRequestProgressEvent> create()
+ static PassRefPtrWillBeRawPtr<XMLHttpRequestProgressEvent> create()
{
- return adoptRef(new XMLHttpRequestProgressEvent);
+ return adoptRefWillBeNoop(new XMLHttpRequestProgressEvent);
}
- static PassRefPtr<XMLHttpRequestProgressEvent> create(const AtomicString& type, bool lengthComputable = false, unsigned long long loaded = 0, unsigned long long total = 0)
+ static PassRefPtrWillBeRawPtr<XMLHttpRequestProgressEvent> create(const AtomicString& type, bool lengthComputable = false, unsigned long long loaded = 0, unsigned long long total = 0)
{
- return adoptRef(new XMLHttpRequestProgressEvent(type, lengthComputable, loaded, total));
+ return adoptRefWillBeNoop(new XMLHttpRequestProgressEvent(type, lengthComputable, loaded, total));
}
// Those 2 synonyms are included for compatibility with Firefox.
unsigned long long position() const { return loaded(); }
unsigned long long totalSize() const { return total(); }
- virtual const AtomicString& interfaceName() const { return EventNames::XMLHttpRequestProgressEvent; }
+ virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::XMLHttpRequestProgressEvent; }
+
+ virtual void trace(Visitor* visitor) OVERRIDE { ProgressEvent::trace(visitor); }
private:
XMLHttpRequestProgressEvent()
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.idl b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.idl
index cd0f45b5ce8..a28d64bd448 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEvent.idl
@@ -25,7 +25,7 @@
// We should also inherit from LSProgressEvent when the idl is added.
interface XMLHttpRequestProgressEvent : ProgressEvent {
- readonly attribute unsigned long long position;
- readonly attribute unsigned long long totalSize;
+ [MeasureAs=XHRProgressEventPosition] readonly attribute unsigned long long position;
+ [MeasureAs=XHRProgressEventTotalSize] readonly attribute unsigned long long totalSize;
};
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp
index 9a3c16c0744..2fcf41124e2 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp
@@ -48,11 +48,18 @@ XMLHttpRequestProgressEventThrottle::~XMLHttpRequestProgressEventThrottle()
{
}
-void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(bool lengthComputable, unsigned long long loaded, unsigned long long total)
+void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(const AtomicString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total)
{
+ RefPtrWillBeRawPtr<XMLHttpRequestProgressEvent> progressEvent = XMLHttpRequestProgressEvent::create(type, lengthComputable, loaded, total);
+
+ if (type != EventTypeNames::progress) {
+ dispatchEvent(progressEvent);
+ return;
+ }
+
if (m_deferEvents) {
// Only store the latest progress event while suspended.
- m_deferredProgressEvent = XMLHttpRequestProgressEvent::create(EventTypeNames::progress, lengthComputable, loaded, total);
+ m_deferredProgressEvent = progressEvent;
return;
}
@@ -64,8 +71,8 @@ void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(bool lengthCompu
ASSERT(!m_loaded);
ASSERT(!m_total);
- dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::progress, lengthComputable, loaded, total));
- startRepeating(minimumProgressEventDispatchingIntervalInSeconds);
+ dispatchEvent(progressEvent);
+ startRepeating(minimumProgressEventDispatchingIntervalInSeconds, FROM_HERE);
return;
}
@@ -75,7 +82,7 @@ void XMLHttpRequestProgressEventThrottle::dispatchProgressEvent(bool lengthCompu
m_total = total;
}
-void XMLHttpRequestProgressEventThrottle::dispatchReadyStateChangeEvent(PassRefPtr<Event> event, ProgressEventAction progressEventAction)
+void XMLHttpRequestProgressEventThrottle::dispatchReadyStateChangeEvent(PassRefPtrWillBeRawPtr<Event> event, ProgressEventAction progressEventAction)
{
if (progressEventAction == FlushProgressEvent || progressEventAction == FlushDeferredProgressEvent) {
if (!flushDeferredProgressEvent() && progressEventAction == FlushProgressEvent)
@@ -85,7 +92,7 @@ void XMLHttpRequestProgressEventThrottle::dispatchReadyStateChangeEvent(PassRefP
dispatchEvent(event);
}
-void XMLHttpRequestProgressEventThrottle::dispatchEvent(PassRefPtr<Event> event)
+void XMLHttpRequestProgressEventThrottle::dispatchEvent(PassRefPtrWillBeRawPtr<Event> event)
{
ASSERT(event);
if (m_deferEvents) {
@@ -94,16 +101,9 @@ void XMLHttpRequestProgressEventThrottle::dispatchEvent(PassRefPtr<Event> event)
return;
}
m_deferredEvents.append(event);
- } else
+ } else {
m_target->dispatchEvent(event);
-}
-
-void XMLHttpRequestProgressEventThrottle::dispatchEventAndLoadEnd(const AtomicString& type, bool lengthComputable, unsigned long long bytesSent, unsigned long long total)
-{
- ASSERT(type == EventTypeNames::load || type == EventTypeNames::abort || type == EventTypeNames::error || type == EventTypeNames::timeout);
-
- dispatchEvent(XMLHttpRequestProgressEvent::create(type, lengthComputable, bytesSent, total));
- dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::loadend, lengthComputable, bytesSent, total));
+ }
}
bool XMLHttpRequestProgressEventThrottle::flushDeferredProgressEvent()
@@ -111,7 +111,7 @@ bool XMLHttpRequestProgressEventThrottle::flushDeferredProgressEvent()
if (m_deferEvents && m_deferredProgressEvent) {
// Move the progress event to the queue, to get it in the right order on resume.
m_deferredEvents.append(m_deferredProgressEvent);
- m_deferredProgressEvent = 0;
+ m_deferredProgressEvent = nullptr;
return true;
}
return false;
@@ -122,7 +122,7 @@ void XMLHttpRequestProgressEventThrottle::deliverProgressEvent()
if (!hasEventToDispatch())
return;
- PassRefPtr<Event> event = XMLHttpRequestProgressEvent::create(EventTypeNames::progress, m_lengthComputable, m_loaded, m_total);
+ RefPtrWillBeRawPtr<Event> event = XMLHttpRequestProgressEvent::create(EventTypeNames::progress, m_lengthComputable, m_loaded, m_total);
m_loaded = 0;
m_total = 0;
@@ -139,14 +139,14 @@ void XMLHttpRequestProgressEventThrottle::dispatchDeferredEvents(Timer<XMLHttpRe
m_deferEvents = false;
// Take over the deferred events before dispatching them which can potentially add more.
- Vector<RefPtr<Event> > deferredEvents;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > deferredEvents;
m_deferredEvents.swap(deferredEvents);
- RefPtr<Event> deferredProgressEvent = m_deferredProgressEvent;
- m_deferredProgressEvent = 0;
+ RefPtrWillBeRawPtr<Event> deferredProgressEvent = m_deferredProgressEvent;
+ m_deferredProgressEvent = nullptr;
- Vector<RefPtr<Event> >::const_iterator it = deferredEvents.begin();
- const Vector<RefPtr<Event> >::const_iterator end = deferredEvents.end();
+ WillBeHeapVector<RefPtrWillBeMember<Event> >::const_iterator it = deferredEvents.begin();
+ const WillBeHeapVector<RefPtrWillBeMember<Event> >::const_iterator end = deferredEvents.end();
for (; it != end; ++it)
dispatchEvent(*it);
@@ -213,7 +213,14 @@ void XMLHttpRequestProgressEventThrottle::resume()
// the list of active DOM objects to resume them, and any activated JS event-handler
// could insert new active DOM objects to the list.
// m_deferEvents is kept true until all deferred events have been dispatched.
- m_dispatchDeferredEventsTimer.startOneShot(0);
+ m_dispatchDeferredEventsTimer.startOneShot(0, FROM_HERE);
+}
+
+void XMLHttpRequestProgressEventThrottle::trace(Visitor* visitor)
+{
+ visitor->trace(m_target);
+ visitor->trace(m_deferredProgressEvent);
+ visitor->trace(m_deferredEvents);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.h b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.h
index 36f5e3a3855..06769fbb8f4 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestProgressEventThrottle.h
@@ -28,6 +28,7 @@
#define XMLHttpRequestProgressEventThrottle_h
#include "platform/Timer.h"
+#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/AtomicString.h"
@@ -45,39 +46,54 @@ enum ProgressEventAction {
// This implements the XHR2 progress event dispatching: "dispatch a progress event called progress
// about every 50ms or for every byte received, whichever is least frequent".
-class XMLHttpRequestProgressEventThrottle : public TimerBase {
+class XMLHttpRequestProgressEventThrottle FINAL : public TimerBase {
+ DISALLOW_ALLOCATION();
public:
explicit XMLHttpRequestProgressEventThrottle(EventTarget*);
virtual ~XMLHttpRequestProgressEventThrottle();
- void dispatchProgressEvent(bool lengthComputable, unsigned long long loaded, unsigned long long total);
- void dispatchReadyStateChangeEvent(PassRefPtr<Event>, ProgressEventAction = DoNotFlushProgressEvent);
- void dispatchEvent(PassRefPtr<Event>);
- void dispatchEventAndLoadEnd(const AtomicString&, bool, unsigned long long, unsigned long long);
+ // Dispatches a ProgressEvent.
+ //
+ // Special treatment for events named "progress" is implemented to dispatch
+ // them at the required frequency. If this object is suspended, the given
+ // ProgressEvent overwrites the existing. I.e. only the latest one gets
+ // queued. If the timer is running, this method just updates
+ // m_lengthComputable, m_loaded and m_total. They'll be used on next
+ // fired() call.
+ void dispatchProgressEvent(const AtomicString&, bool lengthComputable, unsigned long long loaded, unsigned long long total);
+ void dispatchReadyStateChangeEvent(PassRefPtrWillBeRawPtr<Event>, ProgressEventAction = DoNotFlushProgressEvent);
void suspend();
void resume();
+ void trace(Visitor*);
+
private:
static const double minimumProgressEventDispatchingIntervalInSeconds;
- virtual void fired();
+ // Dispatches an event. If suspended, just queues the given event.
+ void dispatchEvent(PassRefPtrWillBeRawPtr<Event>);
+
+ virtual void fired() OVERRIDE;
void dispatchDeferredEvents(Timer<XMLHttpRequestProgressEventThrottle>*);
bool flushDeferredProgressEvent();
void deliverProgressEvent();
bool hasEventToDispatch() const;
- // Weak pointer to our XMLHttpRequest object as it is the one holding us.
- EventTarget* m_target;
+ // Non-Oilpan, keep a weak pointer to our XMLHttpRequest object as it is
+ // the one holding us. With Oilpan, a simple strong Member can be used -
+ // this XMLHttpRequestProgressEventThrottle (part) object dies together
+ // with the XMLHttpRequest object.
+ RawPtrWillBeMember<EventTarget> m_target;
bool m_lengthComputable;
unsigned long long m_loaded;
unsigned long long m_total;
bool m_deferEvents;
- RefPtr<Event> m_deferredProgressEvent;
- Vector<RefPtr<Event> > m_deferredEvents;
+ RefPtrWillBeMember<Event> m_deferredProgressEvent;
+ WillBeHeapVector<RefPtrWillBeMember<Event> > m_deferredEvents;
Timer<XMLHttpRequestProgressEventThrottle> m_dispatchDeferredEventsTimer;
};
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.cpp b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.cpp
index b3497d54da5..7762b267a94 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.cpp
@@ -72,4 +72,10 @@ void XMLHttpRequestUpload::handleRequestError(const AtomicString& type)
dispatchEventAndLoadEnd(type, lengthComputable, m_lastBytesSent, m_lastTotalBytesToBeSent);
}
+void XMLHttpRequestUpload::trace(Visitor* visitor)
+{
+ visitor->trace(m_xmlHttpRequest);
+ XMLHttpRequestEventTarget::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.h b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.h
index d7a63da84c9..451a3230163 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLHttpRequestUpload.h
@@ -28,7 +28,6 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/events/EventListener.h"
-#include "core/events/ThreadLocalEventNames.h"
#include "core/xml/XMLHttpRequest.h"
#include "core/xml/XMLHttpRequestEventTarget.h"
#include "wtf/Forward.h"
@@ -44,15 +43,19 @@ namespace WebCore {
class ExecutionContext;
class XMLHttpRequest;
-class XMLHttpRequestUpload : public ScriptWrappable, public XMLHttpRequestEventTarget {
+class XMLHttpRequestUpload FINAL : public NoBaseWillBeRefCountedGarbageCollected<XMLHttpRequestUpload>, public ScriptWrappable, public XMLHttpRequestEventTarget {
+ WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(XMLHttpRequestUpload);
public:
- static PassOwnPtr<XMLHttpRequestUpload> create(XMLHttpRequest* xmlHttpRequest)
+ static PassOwnPtrWillBeRawPtr<XMLHttpRequestUpload> create(XMLHttpRequest* xmlHttpRequest)
{
- return adoptPtr(new XMLHttpRequestUpload(xmlHttpRequest));
+ return adoptPtrWillBeRefCountedGarbageCollected(new XMLHttpRequestUpload(xmlHttpRequest));
}
+#if !ENABLE(OILPAN)
void ref() { m_xmlHttpRequest->ref(); }
void deref() { m_xmlHttpRequest->deref(); }
+#endif
+
XMLHttpRequest* xmlHttpRequest() const { return m_xmlHttpRequest; }
virtual const AtomicString& interfaceName() const OVERRIDE;
@@ -63,13 +66,17 @@ public:
void handleRequestError(const AtomicString&);
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
explicit XMLHttpRequestUpload(XMLHttpRequest*);
+#if !ENABLE(OILPAN)
virtual void refEventTarget() OVERRIDE { ref(); }
virtual void derefEventTarget() OVERRIDE { deref(); }
+#endif
- XMLHttpRequest* m_xmlHttpRequest;
+ RawPtrWillBeMember<XMLHttpRequest> m_xmlHttpRequest;
EventTargetData m_eventTargetData;
// Last progress event values; used when issuing the
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.cpp b/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.cpp
index 7c42e56f1dd..93aba3794a6 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.cpp
@@ -24,7 +24,7 @@
#include "bindings/v8/ExceptionState.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
-#include "core/editing/markup.h"
+#include "core/editing/MarkupAccumulator.h"
#include "wtf/text/WTFString.h"
namespace WebCore {
@@ -32,11 +32,12 @@ namespace WebCore {
String XMLSerializer::serializeToString(Node* node, ExceptionState& exceptionState)
{
if (!node) {
- exceptionState.throwDOMException(TypeError, "Invalid node value.");
+ exceptionState.throwTypeError("Invalid node value.");
return String();
}
- return createMarkup(node);
+ MarkupAccumulator accumulator(0, DoNotResolveURLs, nullptr, ForcedXML);
+ return accumulator.serializeNodes(*node, IncludeNode);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.h b/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.h
index 53d8c732bb8..6f3e440b154 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.h
@@ -21,6 +21,7 @@
#define XMLSerializer_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -30,12 +31,17 @@ namespace WebCore {
class ExceptionState;
class Node;
-class XMLSerializer : public RefCounted<XMLSerializer>, public ScriptWrappable {
+class XMLSerializer : public RefCountedWillBeGarbageCollectedFinalized<XMLSerializer>, public ScriptWrappable {
public:
- static PassRefPtr<XMLSerializer> create() { return adoptRef(new XMLSerializer); }
+ static PassRefPtrWillBeRawPtr<XMLSerializer> create()
+ {
+ return adoptRefWillBeNoop(new XMLSerializer);
+ }
String serializeToString(Node*, ExceptionState&);
+ void trace(Visitor*) { }
+
private:
XMLSerializer()
{
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.idl b/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.idl
index 88a9171af6d..1a7b6279dba 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLSerializer.idl
@@ -19,6 +19,7 @@
*/
[
+ WillBeGarbageCollected,
Constructor
] interface XMLSerializer {
[RaisesException] DOMString serializeToString([Default=Undefined] optional Node node);
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.cpp b/chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.cpp
index 287f32d2054..8a6c91d273b 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.cpp
@@ -29,17 +29,15 @@
#include "config.h"
#include "core/xml/XMLTreeViewer.h"
-#include "XMLViewerCSS.h"
-#include "XMLViewerJS.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "core/XMLViewerCSS.h"
+#include "core/XMLViewerJS.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/Text.h"
-#include "core/frame/Frame.h"
-
-using namespace std;
+#include "core/frame/LocalFrame.h"
namespace WebCore {
@@ -57,8 +55,7 @@ void XMLTreeViewer::transformDocumentToTreeView()
m_document->frame()->script().executeScriptInMainWorld("prepareWebKitXMLViewer('" + noStyleMessage + "');", ScriptController::ExecuteScriptWhenScriptsDisabled);
String cssString(reinterpret_cast<const char*>(XMLViewer_css), sizeof(XMLViewer_css));
- RefPtr<Text> text = m_document->createTextNode(cssString);
- m_document->getElementById("xml-viewer-style")->appendChild(text, IGNORE_EXCEPTION);
+ m_document->getElementById("xml-viewer-style")->appendChild(m_document->createTextNode(cssString), IGNORE_EXCEPTION);
}
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.h b/chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.h
index a9d0b0ef7f5..286ad044c0e 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XMLTreeViewer.h
@@ -29,18 +29,21 @@
#ifndef XMLTreeViewer_h
#define XMLTreeViewer_h
+#include "platform/heap/Handle.h"
+
namespace WebCore {
class Document;
class XMLTreeViewer FINAL {
+ STACK_ALLOCATED();
public:
explicit XMLTreeViewer(Document*);
void transformDocumentToTreeView();
private:
- Document* m_document;
+ RawPtrWillBeMember<Document> m_document;
};
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.cpp
index f87cc76b6d6..8c2d6f53698 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.cpp
@@ -39,32 +39,32 @@ namespace WebCore {
using namespace XPath;
-PassRefPtr<XPathExpression> XPathEvaluator::createExpression(const String& expression, PassRefPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<XPathExpression> XPathEvaluator::createExpression(const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
{
return XPathExpression::createExpression(expression, resolver, exceptionState);
}
-PassRefPtr<XPathNSResolver> XPathEvaluator::createNSResolver(Node* nodeResolver)
+PassRefPtrWillBeRawPtr<XPathNSResolver> XPathEvaluator::createNSResolver(Node* nodeResolver)
{
return NativeXPathNSResolver::create(nodeResolver);
}
-PassRefPtr<XPathResult> XPathEvaluator::evaluate(const String& expression, Node* contextNode,
- PassRefPtr<XPathNSResolver> resolver, unsigned short type, XPathResult* result, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<XPathResult> XPathEvaluator::evaluate(const String& expression, Node* contextNode,
+ PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, unsigned short type, XPathResult* result, ExceptionState& exceptionState)
{
if (!contextNode) {
exceptionState.throwDOMException(NotSupportedError, "The context node provided is null.");
- return 0;
+ return nullptr;
}
if (!isValidContextNode(contextNode)) {
exceptionState.throwDOMException(NotSupportedError, "The node provided is '" + contextNode->nodeName() + "', which is not a valid context node type.");
- return 0;
+ return nullptr;
}
- RefPtr<XPathExpression> expr = createExpression(expression, resolver, exceptionState);
+ RefPtrWillBeRawPtr<XPathExpression> expr = createExpression(expression, resolver, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
return expr->evaluate(contextNode, type, result, exceptionState);
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.h b/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.h
index 0c556e7e4d8..c76e159d077 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.h
@@ -28,6 +28,7 @@
#define XPathEvaluator_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -40,14 +41,19 @@ class XPathExpression;
class XPathNSResolver;
class XPathResult;
-class XPathEvaluator : public RefCounted<XPathEvaluator>, public ScriptWrappable {
+class XPathEvaluator : public RefCountedWillBeGarbageCollectedFinalized<XPathEvaluator>, public ScriptWrappable {
public:
- static PassRefPtr<XPathEvaluator> create() { return adoptRef(new XPathEvaluator); }
+ static PassRefPtrWillBeRawPtr<XPathEvaluator> create()
+ {
+ return adoptRefWillBeNoop(new XPathEvaluator);
+ }
+
+ PassRefPtrWillBeRawPtr<XPathExpression> createExpression(const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver>, ExceptionState&);
+ PassRefPtrWillBeRawPtr<XPathNSResolver> createNSResolver(Node* nodeResolver);
+ PassRefPtrWillBeRawPtr<XPathResult> evaluate(const String& expression, Node* contextNode,
+ PassRefPtrWillBeRawPtr<XPathNSResolver>, unsigned short type, XPathResult*, ExceptionState&);
- PassRefPtr<XPathExpression> createExpression(const String& expression, PassRefPtr<XPathNSResolver>, ExceptionState&);
- PassRefPtr<XPathNSResolver> createNSResolver(Node* nodeResolver);
- PassRefPtr<XPathResult> evaluate(const String& expression, Node* contextNode,
- PassRefPtr<XPathNSResolver>, unsigned short type, XPathResult*, ExceptionState&);
+ void trace(Visitor*) { }
private:
XPathEvaluator()
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.idl b/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.idl
index 30e899b643b..d11018a46e8 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathEvaluator.idl
@@ -18,6 +18,7 @@
*/
[
+ WillBeGarbageCollected,
Constructor
] interface XPathEvaluator {
[RaisesException] XPathExpression createExpression([Default=Undefined] optional DOMString expression,
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathExpression.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathExpression.cpp
index ae2d7e1a56d..53d27935aa2 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathExpression.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathExpression.cpp
@@ -40,33 +40,42 @@ namespace WebCore {
using namespace XPath;
-PassRefPtr<XPathExpression> XPathExpression::createExpression(const String& expression, PassRefPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+XPathExpression::XPathExpression()
{
- RefPtr<XPathExpression> expr = XPathExpression::create();
+ ScriptWrappable::init(this);
+}
+
+PassRefPtrWillBeRawPtr<XPathExpression> XPathExpression::createExpression(const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+{
+ RefPtrWillBeRawPtr<XPathExpression> expr = XPathExpression::create();
Parser parser;
expr->m_topExpression = parser.parseStatement(expression, resolver, exceptionState);
if (!expr->m_topExpression)
- return 0;
+ return nullptr;
return expr.release();
}
XPathExpression::~XPathExpression()
{
- delete m_topExpression;
}
-PassRefPtr<XPathResult> XPathExpression::evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionState& exceptionState)
+void XPathExpression::trace(Visitor* visitor)
+{
+ visitor->trace(m_topExpression);
+}
+
+PassRefPtrWillBeRawPtr<XPathResult> XPathExpression::evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionState& exceptionState)
{
if (!contextNode) {
exceptionState.throwDOMException(NotSupportedError, "The context node provided is null.");
- return 0;
+ return nullptr;
}
if (!isValidContextNode(contextNode)) {
exceptionState.throwDOMException(NotSupportedError, "The node provided is '" + contextNode->nodeName() + "', which is not a valid context node type.");
- return 0;
+ return nullptr;
}
EvaluationContext& evaluationContext = Expression::evaluationContext();
@@ -74,19 +83,19 @@ PassRefPtr<XPathResult> XPathExpression::evaluate(Node* contextNode, unsigned sh
evaluationContext.size = 1;
evaluationContext.position = 1;
evaluationContext.hadTypeConversionError = false;
- RefPtr<XPathResult> result = XPathResult::create(&contextNode->document(), m_topExpression->evaluate());
- evaluationContext.node = 0; // Do not hold a reference to the context node, as this may prevent the whole document from being destroyed in time.
+ RefPtrWillBeRawPtr<XPathResult> result = XPathResult::create(&contextNode->document(), m_topExpression->evaluate());
+ evaluationContext.node = nullptr; // Do not hold a reference to the context node, as this may prevent the whole document from being destroyed in time.
if (evaluationContext.hadTypeConversionError) {
// It is not specified what to do if type conversion fails while evaluating an expression.
exceptionState.throwDOMException(SyntaxError, "Type conversion failed while evaluating the expression.");
- return 0;
+ return nullptr;
}
if (type != XPathResult::ANY_TYPE) {
result->convertTo(type, exceptionState);
if (exceptionState.hadException())
- return 0;
+ return nullptr;
}
return result;
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathExpression.h b/chromium/third_party/WebKit/Source/core/xml/XPathExpression.h
index 64a3cd38ae5..ea01408a051 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathExpression.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathExpression.h
@@ -28,6 +28,7 @@
#define XPathExpression_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h"
@@ -43,21 +44,23 @@ namespace XPath {
class Expression;
}
-class XPathExpression : public RefCounted<XPathExpression>, public ScriptWrappable {
+class XPathExpression : public RefCountedWillBeGarbageCollectedFinalized<XPathExpression>, public ScriptWrappable {
public:
- static PassRefPtr<XPathExpression> create() { return adoptRef(new XPathExpression); }
+ static PassRefPtrWillBeRawPtr<XPathExpression> create()
+ {
+ return adoptRefWillBeNoop(new XPathExpression);
+ }
~XPathExpression();
- static PassRefPtr<XPathExpression> createExpression(const String& expression, PassRefPtr<XPathNSResolver>, ExceptionState&);
- PassRefPtr<XPathResult> evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionState&);
+ static PassRefPtrWillBeRawPtr<XPathExpression> createExpression(const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver>, ExceptionState&);
+ PassRefPtrWillBeRawPtr<XPathResult> evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionState&);
+
+ void trace(Visitor*);
private:
- XPathExpression()
- {
- ScriptWrappable::init(this);
- }
+ XPathExpression();
- XPath::Expression* m_topExpression;
+ OwnPtrWillBeMember<XPath::Expression> m_topExpression;
};
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathExpression.idl b/chromium/third_party/WebKit/Source/core/xml/XPathExpression.idl
index 7b881eaa62a..35ab9089439 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathExpression.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathExpression.idl
@@ -17,7 +17,10 @@
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
-interface XPathExpression {
+
+[
+ WillBeGarbageCollected
+] interface XPathExpression {
[RaisesException] XPathResult evaluate([Default=Undefined] optional Node contextNode,
[Default=Undefined] optional unsigned short type,
[Default=Undefined] optional XPathResult inResult);
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.cpp
index e952bd0c9c9..ac2a8d1cf93 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.cpp
@@ -49,5 +49,11 @@ Expression::~Expression()
{
}
+void Expression::trace(Visitor* visitor)
+{
+ visitor->trace(m_subExpressions);
+ ParseNode::trace(visitor);
+}
+
}
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.h b/chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.h
index 62d2c86b488..76fa1120f83 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathExpressionNode.h
@@ -35,67 +35,69 @@
namespace WebCore {
- namespace XPath {
-
- struct EvaluationContext {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- RefPtr<Node> node;
- unsigned long size;
- unsigned long position;
- HashMap<String, String> variableBindings;
-
- bool hadTypeConversionError;
- };
-
- class ParseNode {
- public:
- virtual ~ParseNode() { }
- };
-
- class Expression : public ParseNode {
- WTF_MAKE_NONCOPYABLE(Expression); WTF_MAKE_FAST_ALLOCATED;
- public:
- static EvaluationContext& evaluationContext();
-
- Expression();
- virtual ~Expression();
-
- virtual Value evaluate() const = 0;
-
- void addSubExpression(PassOwnPtr<Expression> expr)
- {
- m_isContextNodeSensitive |= expr->m_isContextNodeSensitive;
- m_isContextPositionSensitive |= expr->m_isContextPositionSensitive;
- m_isContextSizeSensitive |= expr->m_isContextSizeSensitive;
- m_subExpressions.append(expr);
- }
-
- bool isContextNodeSensitive() const { return m_isContextNodeSensitive; }
- bool isContextPositionSensitive() const { return m_isContextPositionSensitive; }
- bool isContextSizeSensitive() const { return m_isContextSizeSensitive; }
- void setIsContextNodeSensitive(bool value) { m_isContextNodeSensitive = value; }
- void setIsContextPositionSensitive(bool value) { m_isContextPositionSensitive = value; }
- void setIsContextSizeSensitive(bool value) { m_isContextSizeSensitive = value; }
-
- virtual Value::Type resultType() const = 0;
-
- protected:
- unsigned subExprCount() const { return m_subExpressions.size(); }
- Expression* subExpr(unsigned i) { return m_subExpressions[i].get(); }
- const Expression* subExpr(unsigned i) const { return m_subExpressions[i].get(); }
-
- private:
- Vector<OwnPtr<Expression> > m_subExpressions;
-
- // Evaluation details that can be used for optimization.
- bool m_isContextNodeSensitive;
- bool m_isContextPositionSensitive;
- bool m_isContextSizeSensitive;
- };
-
+namespace XPath {
+
+struct EvaluationContext {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ RefPtrWillBePersistent<Node> node;
+ unsigned long size;
+ unsigned long position;
+ HashMap<String, String> variableBindings;
+
+ bool hadTypeConversionError;
+};
+
+class ParseNode : public NoBaseWillBeGarbageCollectedFinalized<ParseNode> {
+public:
+ virtual ~ParseNode() { }
+ virtual void trace(Visitor*) { }
+};
+
+class Expression : public ParseNode {
+ WTF_MAKE_NONCOPYABLE(Expression); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+ static EvaluationContext& evaluationContext();
+
+ Expression();
+ virtual ~Expression();
+ virtual void trace(Visitor*) OVERRIDE;
+
+ virtual Value evaluate() const = 0;
+
+ void addSubExpression(PassOwnPtrWillBeRawPtr<Expression> expr)
+ {
+ m_isContextNodeSensitive |= expr->m_isContextNodeSensitive;
+ m_isContextPositionSensitive |= expr->m_isContextPositionSensitive;
+ m_isContextSizeSensitive |= expr->m_isContextSizeSensitive;
+ m_subExpressions.append(expr);
}
+ bool isContextNodeSensitive() const { return m_isContextNodeSensitive; }
+ bool isContextPositionSensitive() const { return m_isContextPositionSensitive; }
+ bool isContextSizeSensitive() const { return m_isContextSizeSensitive; }
+ void setIsContextNodeSensitive(bool value) { m_isContextNodeSensitive = value; }
+ void setIsContextPositionSensitive(bool value) { m_isContextPositionSensitive = value; }
+ void setIsContextSizeSensitive(bool value) { m_isContextSizeSensitive = value; }
+
+ virtual Value::Type resultType() const = 0;
+
+protected:
+ unsigned subExprCount() const { return m_subExpressions.size(); }
+ Expression* subExpr(unsigned i) { return m_subExpressions[i].get(); }
+ const Expression* subExpr(unsigned i) const { return m_subExpressions[i].get(); }
+
+private:
+ WillBeHeapVector<OwnPtrWillBeMember<Expression> > m_subExpressions;
+
+ // Evaluation details that can be used for optimization.
+ bool m_isContextNodeSensitive;
+ bool m_isContextPositionSensitive;
+ bool m_isContextSizeSensitive;
+};
+
+}
+
}
-#endif // EXPRESSION_H
+#endif // XPathExpressionNode_h
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathFunctions.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathFunctions.cpp
index 978d858b6bb..8927cc30741 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathFunctions.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathFunctions.cpp
@@ -28,7 +28,8 @@
#include "config.h"
#include "core/xml/XPathFunctions.h"
-#include "XMLNames.h"
+#include "core/XMLNames.h"
+#include "core/dom/Attr.h"
#include "core/dom/Element.h"
#include "core/dom/ProcessingInstruction.h"
#include "core/dom/TreeScope.h"
@@ -71,159 +72,159 @@ struct FunctionRec {
static HashMap<String, FunctionRec>* functionMap;
-class FunLast : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunLast FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
public:
FunLast() { setIsContextSizeSensitive(true); }
};
-class FunPosition : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunPosition FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
public:
FunPosition() { setIsContextPositionSensitive(true); }
};
-class FunCount : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunCount FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
};
-class FunId : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NodeSetValue; }
+class FunId FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
};
-class FunLocalName : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunLocalName FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
public:
FunLocalName() { setIsContextNodeSensitive(true); } // local-name() with no arguments uses context node.
};
-class FunNamespaceURI : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunNamespaceURI FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
public:
FunNamespaceURI() { setIsContextNodeSensitive(true); } // namespace-uri() with no arguments uses context node.
};
-class FunName : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunName FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
public:
FunName() { setIsContextNodeSensitive(true); } // name() with no arguments uses context node.
};
-class FunString : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunString FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
public:
FunString() { setIsContextNodeSensitive(true); } // string() with no arguments uses context node.
};
-class FunConcat : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunConcat FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
};
-class FunStartsWith : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::BooleanValue; }
+class FunStartsWith FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
};
-class FunContains : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::BooleanValue; }
+class FunContains FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
};
-class FunSubstringBefore : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunSubstringBefore FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
};
-class FunSubstringAfter : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunSubstringAfter FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
};
-class FunSubstring : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunSubstring FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
};
-class FunStringLength : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunStringLength FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
public:
FunStringLength() { setIsContextNodeSensitive(true); } // string-length() with no arguments uses context node.
};
-class FunNormalizeSpace : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunNormalizeSpace FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
public:
FunNormalizeSpace() { setIsContextNodeSensitive(true); } // normalize-space() with no arguments uses context node.
};
-class FunTranslate : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
+class FunTranslate FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
};
-class FunBoolean : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::BooleanValue; }
+class FunBoolean FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
};
-class FunNot : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::BooleanValue; }
+class FunNot FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
};
-class FunTrue : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::BooleanValue; }
+class FunTrue FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
};
-class FunFalse : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::BooleanValue; }
+class FunFalse FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
};
-class FunLang : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::BooleanValue; }
+class FunLang FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
public:
FunLang() { setIsContextNodeSensitive(true); } // lang() always works on context node.
};
-class FunNumber : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunNumber FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
public:
FunNumber() { setIsContextNodeSensitive(true); } // number() with no arguments uses context node.
};
-class FunSum : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunSum FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
};
-class FunFloor : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunFloor FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
};
-class FunCeiling : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunCeiling FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
};
-class FunRound : public Function {
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
+class FunRound FINAL : public Function {
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
public:
static double round(double);
};
@@ -290,7 +291,7 @@ inline bool Interval::contains(int value) const
return value >= m_min && value <= m_max;
}
-void Function::setArguments(Vector<OwnPtr<Expression> >& args)
+void Function::setArguments(WillBeHeapVector<OwnPtrWillBeMember<Expression> >& args)
{
ASSERT(!subExprCount());
@@ -298,8 +299,8 @@ void Function::setArguments(Vector<OwnPtr<Expression> >& args)
if (m_name != "lang" && !args.isEmpty())
setIsContextNodeSensitive(false);
- Vector<OwnPtr<Expression> >::iterator end = args.end();
- for (Vector<OwnPtr<Expression> >::iterator it = args.begin(); it != end; it++)
+ WillBeHeapVector<OwnPtrWillBeMember<Expression> >::iterator end = args.end();
+ for (WillBeHeapVector<OwnPtrWillBeMember<Expression> >::iterator it = args.begin(); it != end; ++it)
addSubExpression(it->release());
}
@@ -331,7 +332,7 @@ Value FunId::evaluate() const
}
TreeScope& contextScope = evaluationContext().node->treeScope();
- NodeSet result;
+ OwnPtrWillBeRawPtr<NodeSet> result(NodeSet::create());
HashSet<Node*> resultSet;
unsigned startPos = 0;
@@ -349,22 +350,22 @@ Value FunId::evaluate() const
// If there are several nodes with the same id, id() should return the first one.
// In WebKit, getElementById behaves so, too, although its behavior in this case is formally undefined.
- Node* node = contextScope.getElementById(idList.substring(startPos, endPos - startPos));
+ Node* node = contextScope.getElementById(AtomicString(idList.substring(startPos, endPos - startPos)));
if (node && resultSet.add(node).isNewEntry)
- result.append(node);
+ result->append(node);
startPos = endPos;
}
- result.markSorted(false);
+ result->markSorted(false);
- return Value(result, Value::adopt);
+ return Value(result.release(), Value::adopt);
}
static inline String expandedNameLocalPart(Node* node)
{
// The local part of an XPath expanded-name matches DOM local name for most node types, except for namespace nodes and processing instruction nodes.
- ASSERT(node->nodeType() != Node::XPATH_NAMESPACE_NODE); // Not supported yet.
+ // But note that Blink does not support namespace nodes.
if (node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE)
return toProcessingInstruction(node)->target();
return node->localName().string();
@@ -372,7 +373,19 @@ static inline String expandedNameLocalPart(Node* node)
static inline String expandedName(Node* node)
{
- const AtomicString& prefix = node->prefix();
+ AtomicString prefix;
+
+ switch (node->nodeType()) {
+ case Node::ELEMENT_NODE:
+ prefix = toElement(node)->prefix();
+ break;
+ case Node::ATTRIBUTE_NODE:
+ prefix = toAttr(node)->prefix();
+ break;
+ default:
+ break;
+ }
+
return prefix.isEmpty() ? expandedNameLocalPart(node) : prefix + ":" + expandedNameLocalPart(node);
}
@@ -590,7 +603,7 @@ Value FunLang::evaluate() const
if (node->isElementNode()) {
Element* element = toElement(node);
if (element->hasAttributes())
- languageAttribute = element->getAttributeItem(XMLNames::langAttr);
+ languageAttribute = element->findAttributeByName(XMLNames::langAttr);
}
if (languageAttribute)
break;
@@ -715,11 +728,11 @@ static void createFunctionMap()
Function* createFunction(const String& name)
{
- Vector<OwnPtr<Expression> > args;
+ WillBeHeapVector<OwnPtrWillBeMember<Expression> > args;
return createFunction(name, args);
}
-Function* createFunction(const String& name, Vector<OwnPtr<Expression> >& args)
+Function* createFunction(const String& name, WillBeHeapVector<OwnPtrWillBeMember<Expression> >& args)
{
if (!functionMap)
createFunctionMap();
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathFunctions.h b/chromium/third_party/WebKit/Source/core/xml/XPathFunctions.h
index 1e2ee4de5bf..e39632c73e0 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathFunctions.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathFunctions.h
@@ -31,26 +31,27 @@
namespace WebCore {
- namespace XPath {
-
- class Function : public Expression {
- public:
- void setArguments(Vector<OwnPtr<Expression> >&);
- void setName(const String& name) { m_name = name; }
- protected:
- Expression* arg(int pos) { return subExpr(pos); }
- const Expression* arg(int pos) const { return subExpr(pos); }
- unsigned int argCount() const { return subExprCount(); }
- String name() const { return m_name; }
-
- private:
- String m_name;
- };
-
- Function* createFunction(const String& name);
- Function* createFunction(const String& name, Vector<OwnPtr<Expression> >&);
-
- } // namespace XPath
+namespace XPath {
+
+class Function : public Expression {
+public:
+ void setArguments(WillBeHeapVector<OwnPtrWillBeMember<Expression> >&);
+ void setName(const String& name) { m_name = name; }
+
+protected:
+ Expression* arg(int pos) { return subExpr(pos); }
+ const Expression* arg(int pos) const { return subExpr(pos); }
+ unsigned argCount() const { return subExprCount(); }
+ String name() const { return m_name; }
+
+private:
+ String m_name;
+};
+
+Function* createFunction(const String& name);
+Function* createFunction(const String& name, WillBeHeapVector<OwnPtrWillBeMember<Expression> >&);
+
+} // namespace XPath
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathGrammar.y b/chromium/third_party/WebKit/Source/core/xml/XPathGrammar.y
index 6911fcfe601..da094b7c23a 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathGrammar.y
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathGrammar.y
@@ -51,21 +51,21 @@ using namespace XPath;
%}
-%pure_parser
+%pure-parser
%parse-param { WebCore::XPath::Parser* parser }
%union
{
- Step::Axis axis;
- Step::NodeTest* nodeTest;
- NumericOp::Opcode numop;
- EqTestOp::Opcode eqop;
+ WebCore::XPath::Step::Axis axis;
+ WebCore::XPath::Step::NodeTest* nodeTest;
+ WebCore::XPath::NumericOp::Opcode numop;
+ WebCore::XPath::EqTestOp::Opcode eqop;
String* str;
- Expression* expr;
- Vector<OwnPtr<Predicate> >* predList;
- Vector<OwnPtr<Expression> >* argList;
- Step* step;
- LocationPath* locationPath;
+ WebCore::XPath::Expression* expr;
+ WillBeHeapVector<OwnPtrWillBeMember<WebCore::XPath::Predicate> >* predList;
+ WillBeHeapVector<OwnPtrWillBeMember<WebCore::XPath::Expression> >* argList;
+ WebCore::XPath::Step* step;
+ WebCore::XPath::LocationPath* locationPath;
}
%{
@@ -291,15 +291,15 @@ OptionalPredicateList:
PredicateList:
Predicate
{
- $$ = new Vector<OwnPtr<Predicate> >;
- $$->append(adoptPtr(new Predicate(adoptPtr($1))));
+ $$ = new WillBeHeapVector<OwnPtrWillBeMember<Predicate> >;
+ $$->append(adoptPtrWillBeNoop(new Predicate(adoptPtrWillBeNoop($1))));
parser->unregisterParseNode($1);
parser->registerPredicateVector($$);
}
|
PredicateList Predicate
{
- $$->append(adoptPtr(new Predicate(adoptPtr($2))));
+ $$->append(adoptPtrWillBeNoop(new Predicate(adoptPtrWillBeNoop($2))));
parser->unregisterParseNode($2);
}
;
@@ -387,15 +387,15 @@ FunctionCall:
ArgumentList:
Argument
{
- $$ = new Vector<OwnPtr<Expression> >;
- $$->append(adoptPtr($1));
+ $$ = new WillBeHeapVector<OwnPtrWillBeMember<Expression> >;
+ $$->append(adoptPtrWillBeNoop($1));
parser->unregisterParseNode($1);
parser->registerExpressionVector($$);
}
|
ArgumentList ',' Argument
{
- $$->append(adoptPtr($3));
+ $$->append(adoptPtrWillBeNoop($3));
parser->unregisterParseNode($3);
}
;
@@ -410,8 +410,8 @@ UnionExpr:
UnionExpr '|' PathExpr
{
$$ = new Union;
- $$->addSubExpression(adoptPtr($1));
- $$->addSubExpression(adoptPtr($3));
+ $$->addSubExpression(adoptPtrWillBeNoop($1));
+ $$->addSubExpression(adoptPtrWillBeNoop($3));
parser->unregisterParseNode($1);
parser->unregisterParseNode($3);
parser->registerParseNode($$);
@@ -452,7 +452,7 @@ FilterExpr:
|
PrimaryExpr PredicateList
{
- $$ = new Filter(adoptPtr($1), *$2);
+ $$ = new Filter(adoptPtrWillBeNoop($1), *$2);
parser->unregisterParseNode($1);
parser->deletePredicateVector($2);
parser->registerParseNode($$);
@@ -464,7 +464,7 @@ OrExpr:
|
OrExpr OR AndExpr
{
- $$ = new LogicalOp(LogicalOp::OP_Or, adoptPtr($1), adoptPtr($3));
+ $$ = new LogicalOp(LogicalOp::OP_Or, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
parser->unregisterParseNode($1);
parser->unregisterParseNode($3);
parser->registerParseNode($$);
@@ -476,7 +476,7 @@ AndExpr:
|
AndExpr AND EqualityExpr
{
- $$ = new LogicalOp(LogicalOp::OP_And, adoptPtr($1), adoptPtr($3));
+ $$ = new LogicalOp(LogicalOp::OP_And, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
parser->unregisterParseNode($1);
parser->unregisterParseNode($3);
parser->registerParseNode($$);
@@ -488,7 +488,7 @@ EqualityExpr:
|
EqualityExpr EQOP RelationalExpr
{
- $$ = new EqTestOp($2, adoptPtr($1), adoptPtr($3));
+ $$ = new EqTestOp($2, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
parser->unregisterParseNode($1);
parser->unregisterParseNode($3);
parser->registerParseNode($$);
@@ -500,7 +500,7 @@ RelationalExpr:
|
RelationalExpr RELOP AdditiveExpr
{
- $$ = new EqTestOp($2, adoptPtr($1), adoptPtr($3));
+ $$ = new EqTestOp($2, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
parser->unregisterParseNode($1);
parser->unregisterParseNode($3);
parser->registerParseNode($$);
@@ -512,7 +512,7 @@ AdditiveExpr:
|
AdditiveExpr PLUS MultiplicativeExpr
{
- $$ = new NumericOp(NumericOp::OP_Add, adoptPtr($1), adoptPtr($3));
+ $$ = new NumericOp(NumericOp::OP_Add, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
parser->unregisterParseNode($1);
parser->unregisterParseNode($3);
parser->registerParseNode($$);
@@ -520,7 +520,7 @@ AdditiveExpr:
|
AdditiveExpr MINUS MultiplicativeExpr
{
- $$ = new NumericOp(NumericOp::OP_Sub, adoptPtr($1), adoptPtr($3));
+ $$ = new NumericOp(NumericOp::OP_Sub, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
parser->unregisterParseNode($1);
parser->unregisterParseNode($3);
parser->registerParseNode($$);
@@ -532,7 +532,7 @@ MultiplicativeExpr:
|
MultiplicativeExpr MULOP UnaryExpr
{
- $$ = new NumericOp($2, adoptPtr($1), adoptPtr($3));
+ $$ = new NumericOp($2, adoptPtrWillBeNoop($1), adoptPtrWillBeNoop($3));
parser->unregisterParseNode($1);
parser->unregisterParseNode($3);
parser->registerParseNode($$);
@@ -545,7 +545,7 @@ UnaryExpr:
MINUS UnaryExpr
{
$$ = new Negative;
- $$->addSubExpression(adoptPtr($2));
+ $$->addSubExpression(adoptPtrWillBeNoop($2));
parser->unregisterParseNode($2);
parser->registerParseNode($$);
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.h b/chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.h
index fc761f6459e..10768325968 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.h
@@ -28,16 +28,19 @@
#define XPathNSResolver_h
#include "bindings/v8/ScriptWrappable.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
namespace WebCore {
-class XPathNSResolver : public RefCounted<XPathNSResolver>, public ScriptWrappable {
+class XPathNSResolver : public RefCountedWillBeGarbageCollectedFinalized<XPathNSResolver>, public ScriptWrappable {
public:
virtual ~XPathNSResolver();
virtual AtomicString lookupNamespaceURI(const String& prefix) = 0;
+ virtual void trace(Visitor*) { }
+
protected:
XPathNSResolver()
{
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.idl b/chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.idl
index 32107922bd5..fd16fcc96a4 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathNSResolver.idl
@@ -19,6 +19,7 @@
*/
[
+ WillBeGarbageCollected,
NoInterfaceObject
] interface XPathNSResolver {
[TreatReturnedNullStringAs=Null] DOMString lookupNamespaceURI([Default=Undefined] optional DOMString prefix);
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp
index b0966c66301..cfb758645b2 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.cpp
@@ -27,25 +27,39 @@
#include "core/xml/XPathNodeSet.h"
#include "core/dom/Attr.h"
+#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/NodeTraversal.h"
namespace WebCore {
namespace XPath {
-// When a node set is large, sorting it by traversing the whole document is better (we can
-// assume that we aren't dealing with documents that we cannot even traverse in reasonable time).
+// When a node set is large, sorting it by traversing the whole document is
+// better (we can assume that we aren't dealing with documents that we cannot
+// even traverse in reasonable time).
const unsigned traversalSortCutoff = 10000;
-static inline Node* parentWithDepth(unsigned depth, const Vector<Node*>& parents)
+typedef WillBeHeapVector<RawPtrWillBeMember<Node> > NodeSetVector;
+
+PassOwnPtrWillBeRawPtr<NodeSet> NodeSet::create(const NodeSet& other)
+{
+ OwnPtrWillBeRawPtr<NodeSet> nodeSet = NodeSet::create();
+ nodeSet->m_isSorted = other.m_isSorted;
+ nodeSet->m_subtreesAreDisjoint = other.m_subtreesAreDisjoint;
+ nodeSet->m_nodes.appendVector(other.m_nodes);
+ return nodeSet.release();
+}
+
+static inline Node* parentWithDepth(unsigned depth, const NodeSetVector& parents)
{
ASSERT(parents.size() >= depth + 1);
return parents[parents.size() - 1 - depth];
}
-static void sortBlock(unsigned from, unsigned to, Vector<Vector<Node*> >& parentMatrix, bool mayContainAttributeNodes)
+static void sortBlock(unsigned from, unsigned to, WillBeHeapVector<NodeSetVector>& parentMatrix, bool mayContainAttributeNodes)
{
- ASSERT(from + 1 < to); // Should not call this function with less that two nodes to sort.
+ // Should not call this function with less that two nodes to sort.
+ ASSERT(from + 1 < to);
unsigned minDepth = UINT_MAX;
for (unsigned i = from; i < to; ++i) {
unsigned depth = parentMatrix[i].size() - 1;
@@ -75,22 +89,24 @@ static void sortBlock(unsigned from, unsigned to, Vector<Vector<Node*> >& parent
}
if (commonAncestorDepth == minDepth) {
- // One of the nodes is the common ancestor => it is the first in document order.
- // Find it and move it to the beginning.
- for (unsigned i = from; i < to; ++i)
+ // One of the nodes is the common ancestor => it is the first in
+ // document order. Find it and move it to the beginning.
+ for (unsigned i = from; i < to; ++i) {
if (commonAncestor == parentMatrix[i][0]) {
parentMatrix[i].swap(parentMatrix[from]);
if (from + 2 < to)
sortBlock(from + 1, to, parentMatrix, mayContainAttributeNodes);
return;
}
+ }
}
if (mayContainAttributeNodes && commonAncestor->isElementNode()) {
- // The attribute nodes and namespace nodes of an element occur before the children of the element.
- // The namespace nodes are defined to occur before the attribute nodes.
- // The relative order of namespace nodes is implementation-dependent.
- // The relative order of attribute nodes is implementation-dependent.
+ // The attribute nodes and namespace nodes of an element occur before
+ // the children of the element. The namespace nodes are defined to occur
+ // before the attribute nodes. The relative order of namespace nodes is
+ // implementation-dependent. The relative order of attribute nodes is
+ // implementation-dependent.
unsigned sortedEnd = from;
// FIXME: namespace nodes are not implemented.
for (unsigned i = sortedEnd; i < to; ++i) {
@@ -105,20 +121,23 @@ static void sortBlock(unsigned from, unsigned to, Vector<Vector<Node*> >& parent
}
}
- // Children nodes of the common ancestor induce a subdivision of our node-set.
- // Sort it according to this subdivision, and recursively sort each group.
- HashSet<Node*> parentNodes;
+ // Children nodes of the common ancestor induce a subdivision of our
+ // node-set. Sort it according to this subdivision, and recursively sort
+ // each group.
+ WillBeHeapHashSet<RawPtrWillBeMember<Node> > parentNodes;
for (unsigned i = from; i < to; ++i)
parentNodes.add(parentWithDepth(commonAncestorDepth + 1, parentMatrix[i]));
unsigned previousGroupEnd = from;
unsigned groupEnd = from;
for (Node* n = commonAncestor->firstChild(); n; n = n->nextSibling()) {
- // If parentNodes contains the node, perform a linear search to move its children in the node-set to the beginning.
+ // If parentNodes contains the node, perform a linear search to move its
+ // children in the node-set to the beginning.
if (parentNodes.contains(n)) {
- for (unsigned i = groupEnd; i < to; ++i)
+ for (unsigned i = groupEnd; i < to; ++i) {
if (parentWithDepth(commonAncestorDepth + 1, parentMatrix[i]) == n)
parentMatrix[i].swap(parentMatrix[groupEnd++]);
+ }
if (groupEnd - previousGroupEnd > 1)
sortBlock(previousGroupEnd, groupEnd, parentMatrix, mayContainAttributeNodes);
@@ -152,9 +171,9 @@ void NodeSet::sort() const
bool containsAttributeNodes = false;
- Vector<Vector<Node*> > parentMatrix(nodeCount);
+ WillBeHeapVector<NodeSetVector> parentMatrix(nodeCount);
for (unsigned i = 0; i < nodeCount; ++i) {
- Vector<Node*>& parentsVector = parentMatrix[i];
+ NodeSetVector& parentsVector = parentMatrix[i];
Node* n = m_nodes[i].get();
parentsVector.append(n);
if (n->isAttributeNode()) {
@@ -167,22 +186,23 @@ void NodeSet::sort() const
}
sortBlock(0, nodeCount, parentMatrix, containsAttributeNodes);
- // It is not possible to just assign the result to m_nodes, because some nodes may get dereferenced and destroyed.
- Vector<RefPtr<Node> > sortedNodes;
+ // It is not possible to just assign the result to m_nodes, because some
+ // nodes may get dereferenced and destroyed.
+ WillBeHeapVector<RefPtrWillBeMember<Node> > sortedNodes;
sortedNodes.reserveInitialCapacity(nodeCount);
for (unsigned i = 0; i < nodeCount; ++i)
sortedNodes.append(parentMatrix[i][0]);
- const_cast<Vector<RefPtr<Node> >&>(m_nodes).swap(sortedNodes);
+ const_cast<WillBeHeapVector<RefPtrWillBeMember<Node> >&>(m_nodes).swap(sortedNodes);
}
static Node* findRootNode(Node* node)
{
if (node->isAttributeNode())
node = toAttr(node)->ownerElement();
- if (node->inDocument())
+ if (node->inDocument()) {
node = &node->document();
- else {
+ } else {
while (Node* parent = node->parentNode())
node = parent;
}
@@ -191,7 +211,7 @@ static Node* findRootNode(Node* node)
void NodeSet::traversalSort() const
{
- HashSet<Node*> nodes;
+ WillBeHeapHashSet<RawPtrWillBeMember<Node> > nodes;
bool containsAttributeNodes = false;
unsigned nodeCount = m_nodes.size();
@@ -203,7 +223,7 @@ void NodeSet::traversalSort() const
containsAttributeNodes = true;
}
- Vector<RefPtr<Node> > sortedNodes;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > sortedNodes;
sortedNodes.reserveInitialCapacity(nodeCount);
for (Node* n = findRootNode(m_nodes.first().get()); n; n = NodeTraversal::next(*n)) {
@@ -217,16 +237,17 @@ void NodeSet::traversalSort() const
if (!element->hasAttributes())
continue;
- unsigned attributeCount = element->attributeCount();
- for (unsigned i = 0; i < attributeCount; ++i) {
- RefPtr<Attr> attr = element->attrIfExists(element->attributeItem(i)->name());
+ AttributeCollection attributes = element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ RefPtrWillBeRawPtr<Attr> attr = element->attrIfExists(it->name());
if (attr && nodes.contains(attr.get()))
sortedNodes.append(attr);
}
}
ASSERT(sortedNodes.size() == nodeCount);
- const_cast<Vector<RefPtr<Node> >&>(m_nodes).swap(sortedNodes);
+ const_cast<WillBeHeapVector<RefPtrWillBeMember<Node> >&>(m_nodes).swap(sortedNodes);
}
void NodeSet::reverse()
@@ -248,7 +269,9 @@ Node* NodeSet::firstNode() const
if (isEmpty())
return 0;
- sort(); // FIXME: fully sorting the node-set just to find its first node is wasteful.
+ // FIXME: fully sorting the node-set just to find its first node is
+ // wasteful.
+ sort();
return m_nodes.at(0).get();
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.h b/chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.h
index c90e395ded4..d7dc4974a12 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathNodeSet.h
@@ -26,59 +26,62 @@
#ifndef XPathNodeSet_h
#define XPathNodeSet_h
+#include "core/dom/Node.h"
#include "wtf/Forward.h"
#include "wtf/Vector.h"
-#include "core/dom/Node.h"
-
namespace WebCore {
- namespace XPath {
+namespace XPath {
- class NodeSet {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- NodeSet() : m_isSorted(true), m_subtreesAreDisjoint(false) { }
+class NodeSet : public NoBaseWillBeGarbageCollected<NodeSet> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+ static PassOwnPtrWillBeRawPtr<NodeSet> create() { return adoptPtrWillBeNoop(new NodeSet); }
+ static PassOwnPtrWillBeRawPtr<NodeSet> create(const NodeSet&);
+ void trace(Visitor* visitor) { visitor->trace(m_nodes); }
- size_t size() const { return m_nodes.size(); }
- bool isEmpty() const { return !m_nodes.size(); }
- Node* operator[](unsigned i) const { return m_nodes.at(i).get(); }
- void reserveCapacity(size_t newCapacity) { m_nodes.reserveCapacity(newCapacity); }
- void clear() { m_nodes.clear(); }
- void swap(NodeSet& other) { std::swap(m_isSorted, other.m_isSorted); std::swap(m_subtreesAreDisjoint, other.m_subtreesAreDisjoint); m_nodes.swap(other.m_nodes); }
+ size_t size() const { return m_nodes.size(); }
+ bool isEmpty() const { return !m_nodes.size(); }
+ Node* operator[](unsigned i) const { return m_nodes.at(i).get(); }
+ void reserveCapacity(size_t newCapacity) { m_nodes.reserveCapacity(newCapacity); }
+ void clear() { m_nodes.clear(); }
+ void swap(NodeSet& other) { std::swap(m_isSorted, other.m_isSorted); std::swap(m_subtreesAreDisjoint, other.m_subtreesAreDisjoint); m_nodes.swap(other.m_nodes); }
- // NodeSet itself does not verify that nodes in it are unique.
- void append(Node* node) { m_nodes.append(node); }
- void append(PassRefPtr<Node> node) { m_nodes.append(node); }
- void append(const NodeSet& nodeSet) { m_nodes.append(nodeSet.m_nodes); }
+ // NodeSet itself does not verify that nodes in it are unique.
+ void append(PassRefPtrWillBeRawPtr<Node> node) { m_nodes.append(node); }
+ void append(const NodeSet& nodeSet) { m_nodes.appendVector(nodeSet.m_nodes); }
- // Returns the set's first node in document order, or 0 if the set is empty.
- Node* firstNode() const;
+ // Returns the set's first node in document order, or 0 if the set is empty.
+ Node* firstNode() const;
- // Returns 0 if the set is empty.
- Node* anyNode() const;
+ // Returns 0 if the set is empty.
+ Node* anyNode() const;
- // NodeSet itself doesn't check if it contains nodes in document order - the caller should tell it if it does not.
- void markSorted(bool isSorted) { m_isSorted = isSorted; }
- bool isSorted() const { return m_isSorted || m_nodes.size() < 2; }
+ // NodeSet itself doesn't check if it contains nodes in document order - the
+ // caller should tell it if it does not.
+ void markSorted(bool isSorted) { m_isSorted = isSorted; }
+ bool isSorted() const { return m_isSorted || m_nodes.size() < 2; }
- void sort() const;
+ void sort() const;
- // No node in the set is ancestor of another. Unlike m_isSorted, this is assumed to be false, unless the caller sets it to true.
- void markSubtreesDisjoint(bool disjoint) { m_subtreesAreDisjoint = disjoint; }
- bool subtreesAreDisjoint() const { return m_subtreesAreDisjoint || m_nodes.size() < 2; }
+ // No node in the set is ancestor of another. Unlike m_isSorted, this is
+ // assumed to be false, unless the caller sets it to true.
+ void markSubtreesDisjoint(bool disjoint) { m_subtreesAreDisjoint = disjoint; }
+ bool subtreesAreDisjoint() const { return m_subtreesAreDisjoint || m_nodes.size() < 2; }
- void reverse();
+ void reverse();
- private:
- void traversalSort() const;
+private:
+ NodeSet() : m_isSorted(true), m_subtreesAreDisjoint(false) { }
+ void traversalSort() const;
- bool m_isSorted;
- bool m_subtreesAreDisjoint;
- Vector<RefPtr<Node> > m_nodes;
- };
+ bool m_isSorted;
+ bool m_subtreesAreDisjoint;
+ WillBeHeapVector<RefPtrWillBeMember<Node> > m_nodes;
+};
- }
}
+}
#endif // XPathNodeSet_h
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathParser.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathParser.cpp
index 3c6579f1427..8c887d9491f 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathParser.cpp
@@ -29,6 +29,7 @@
#include "core/xml/XPathParser.h"
#include "bindings/v8/ExceptionState.h"
+#include "core/XPathGrammar.h"
#include "core/dom/ExceptionCode.h"
#include "core/xml/XPathEvaluator.h"
#include "core/xml/XPathNSResolver.h"
@@ -41,9 +42,6 @@ using namespace WTF;
using namespace Unicode;
using namespace XPath;
-extern int xpathyyparse(WebCore::XPath::Parser*);
-#include "XPathGrammar.h"
-
Parser* Parser::currentParser = 0;
enum XMLCat { NameStart, NameCont, NotPartOfName };
@@ -52,7 +50,7 @@ typedef HashMap<String, Step::Axis> AxisNamesMap;
static XMLCat charCat(UChar aChar)
{
- //### might need to add some special cases from the XML spec.
+ // might need to add some special cases from the XML spec.
if (aChar == '_')
return NameStart;
@@ -208,7 +206,8 @@ Token Parser::lexNumber()
// Go until end or a non-digits character.
for (; m_nextPos < m_data.length(); ++m_nextPos) {
UChar aChar = m_data[m_nextPos];
- if (aChar >= 0xff) break;
+ if (aChar >= 0xff)
+ break;
if (aChar < '0' || aChar > '9') {
if (aChar == '.' && !seenDot)
@@ -231,9 +230,10 @@ bool Parser::lexNCName(String& name)
return false;
// Keep going until we get a character that's not good for names.
- for (; m_nextPos < m_data.length(); ++m_nextPos)
+ for (; m_nextPos < m_data.length(); ++m_nextPos) {
if (charCat(m_data[m_nextPos]) == NotPartOfName)
break;
+ }
name = m_data.substring(startPos, m_nextPos - startPos);
return true;
@@ -297,19 +297,19 @@ Token Parser::nextTokenInternal()
case '-':
return makeTokenAndAdvance(MINUS);
case '=':
- return makeTokenAndAdvance(EQOP, EqTestOp::OP_EQ);
+ return makeTokenAndAdvance(EQOP, EqTestOp::OpcodeEqual);
case '!':
if (peekAheadHelper() == '=')
- return makeTokenAndAdvance(EQOP, EqTestOp::OP_NE, 2);
+ return makeTokenAndAdvance(EQOP, EqTestOp::OpcodeNotEqual, 2);
return Token(XPATH_ERROR);
case '<':
if (peekAheadHelper() == '=')
- return makeTokenAndAdvance(RELOP, EqTestOp::OP_LE, 2);
- return makeTokenAndAdvance(RELOP, EqTestOp::OP_LT);
+ return makeTokenAndAdvance(RELOP, EqTestOp::OpcodeLessOrEqual, 2);
+ return makeTokenAndAdvance(RELOP, EqTestOp::OpcodeLessThan);
case '>':
if (peekAheadHelper() == '=')
- return makeTokenAndAdvance(RELOP, EqTestOp::OP_GE, 2);
- return makeTokenAndAdvance(RELOP, EqTestOp::OP_GT);
+ return makeTokenAndAdvance(RELOP, EqTestOp::OpcodeGreaterOrEqual, 2);
+ return makeTokenAndAdvance(RELOP, EqTestOp::OpcodeGreaterThan);
case '*':
if (isBinaryOperatorContext())
return makeTokenAndAdvance(MULOP, NumericOp::OP_Mul);
@@ -331,7 +331,7 @@ Token Parser::nextTokenInternal()
skipWS();
// If we're in an operator context, check for any operator names
if (isBinaryOperatorContext()) {
- if (name == "and") //### hash?
+ if (name == "and") // ### hash?
return Token(AND);
if (name == "or")
return Token(OR);
@@ -348,7 +348,7 @@ Token Parser::nextTokenInternal()
if (peekCurHelper() == ':') {
m_nextPos++;
- //It might be an axis name.
+ // It might be an axis name.
Step::Axis axis;
if (isAxisName(name, axis))
return Token(AXISNAME, axis);
@@ -356,7 +356,8 @@ Token Parser::nextTokenInternal()
return Token(XPATH_ERROR);
}
- // Seems like this is a fully qualified qname, or perhaps the * modified one from NameTest
+ // Seems like this is a fully qualified qname, or perhaps the * modified
+ // one from NameTest
skipWS();
if (peekCurHelper() == '*') {
m_nextPos++;
@@ -373,16 +374,16 @@ Token Parser::nextTokenInternal()
skipWS();
if (peekCurHelper() == '(') {
- //note: we don't swallow the (here!
+ // Note: we don't swallow the ( here!
- //either node type of function name
+ // Either node type of function name
if (isNodeTypeName(name)) {
if (name == "processing-instruction")
return Token(PI, name);
return Token(NODETYPE, name);
}
- //must be a function name.
+ // Must be a function name.
return Token(FUNCTIONNAME, name);
}
@@ -412,7 +413,7 @@ void Parser::reset(const String& data)
m_data = data;
m_lastTokenType = 0;
- m_topExpr = 0;
+ m_topExpr = nullptr;
m_gotNamespaceError = false;
}
@@ -464,7 +465,7 @@ bool Parser::expandQName(const String& qName, AtomicString& localName, AtomicStr
return true;
}
-Expression* Parser::parseStatement(const String& statement, PassRefPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+PassOwnPtrWillBeRawPtr<Expression> Parser::parseStatement(const String& statement, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
{
reset(statement);
@@ -476,8 +477,9 @@ Expression* Parser::parseStatement(const String& statement, PassRefPtr<XPathNSRe
currentParser = oldParser;
if (parseError) {
- deleteAllValues(m_parseNodes);
- m_parseNodes.clear();
+#if !ENABLE(OILPAN)
+ while (!m_parseNodes.isEmpty())
+ delete m_parseNodes.takeAny();
HashSet<Vector<OwnPtr<Predicate> >*>::iterator pend = m_predicateVectors.end();
for (HashSet<Vector<OwnPtr<Predicate> >*>::iterator it = m_predicateVectors.begin(); it != pend; ++it)
@@ -489,67 +491,74 @@ Expression* Parser::parseStatement(const String& statement, PassRefPtr<XPathNSRe
delete *it;
m_expressionVectors.clear();
- deleteAllValues(m_strings);
- m_strings.clear();
-
- deleteAllValues(m_nodeTests);
m_nodeTests.clear();
+#endif
+
+ m_strings.clear();
- m_topExpr = 0;
+ m_topExpr = nullptr;
if (m_gotNamespaceError)
exceptionState.throwDOMException(NamespaceError, "The string '" + statement + "' contains unresolvable namespaces.");
else
exceptionState.throwDOMException(SyntaxError, "The string '" + statement + "' is not a valid XPath expression.");
- return 0;
+ return nullptr;
}
-
+ ASSERT(m_strings.size() == 0);
+#if !ENABLE(OILPAN)
ASSERT(m_parseNodes.size() == 1);
ASSERT(*m_parseNodes.begin() == m_topExpr);
ASSERT(m_expressionVectors.size() == 0);
ASSERT(m_predicateVectors.size() == 0);
- ASSERT(m_strings.size() == 0);
ASSERT(m_nodeTests.size() == 0);
-
m_parseNodes.clear();
+#endif
+
Expression* result = m_topExpr;
- m_topExpr = 0;
+ m_topExpr = nullptr;
- return result;
+ return adoptPtrWillBeNoop(result);
}
void Parser::registerParseNode(ParseNode* node)
{
+#if !ENABLE(OILPAN)
if (node == 0)
return;
ASSERT(!m_parseNodes.contains(node));
m_parseNodes.add(node);
+#endif
}
void Parser::unregisterParseNode(ParseNode* node)
{
+#if !ENABLE(OILPAN)
if (node == 0)
return;
ASSERT(m_parseNodes.contains(node));
m_parseNodes.remove(node);
+#endif
}
-void Parser::registerPredicateVector(Vector<OwnPtr<Predicate> >* vector)
+void Parser::registerPredicateVector(WillBeHeapVector<OwnPtrWillBeMember<Predicate> >* vector)
{
+#if !ENABLE(OILPAN)
if (vector == 0)
return;
ASSERT(!m_predicateVectors.contains(vector));
m_predicateVectors.add(vector);
+#endif
}
-void Parser::deletePredicateVector(Vector<OwnPtr<Predicate> >* vector)
+void Parser::deletePredicateVector(WillBeHeapVector<OwnPtrWillBeMember<Predicate> >* vector)
{
+#if !ENABLE(OILPAN)
if (vector == 0)
return;
@@ -557,21 +566,25 @@ void Parser::deletePredicateVector(Vector<OwnPtr<Predicate> >* vector)
m_predicateVectors.remove(vector);
delete vector;
+#endif
}
-void Parser::registerExpressionVector(Vector<OwnPtr<Expression> >* vector)
+void Parser::registerExpressionVector(WillBeHeapVector<OwnPtrWillBeMember<Expression> >* vector)
{
+#if !ENABLE(OILPAN)
if (vector == 0)
return;
ASSERT(!m_expressionVectors.contains(vector));
m_expressionVectors.add(vector);
+#endif
}
-void Parser::deleteExpressionVector(Vector<OwnPtr<Expression> >* vector)
+void Parser::deleteExpressionVector(WillBeHeapVector<OwnPtrWillBeMember<Expression> >* vector)
{
+#if !ENABLE(OILPAN)
if (vector == 0)
return;
@@ -579,6 +592,7 @@ void Parser::deleteExpressionVector(Vector<OwnPtr<Expression> >* vector)
m_expressionVectors.remove(vector);
delete vector;
+#endif
}
void Parser::registerString(String* s)
@@ -588,7 +602,7 @@ void Parser::registerString(String* s)
ASSERT(!m_strings.contains(s));
- m_strings.add(s);
+ m_strings.add(adoptPtr(s));
}
void Parser::deleteString(String* s)
@@ -599,27 +613,29 @@ void Parser::deleteString(String* s)
ASSERT(m_strings.contains(s));
m_strings.remove(s);
- delete s;
}
void Parser::registerNodeTest(Step::NodeTest* t)
{
+#if !ENABLE(OILPAN)
if (t == 0)
return;
ASSERT(!m_nodeTests.contains(t));
- m_nodeTests.add(t);
+ m_nodeTests.add(adoptPtr(t));
+#endif
}
void Parser::deleteNodeTest(Step::NodeTest* t)
{
+#if !ENABLE(OILPAN)
if (t == 0)
return;
ASSERT(m_nodeTests.contains(t));
m_nodeTests.remove(t);
- delete t;
+#endif
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathParser.h b/chromium/third_party/WebKit/Source/core/xml/XPathParser.h
index 07a3f8d708e..0162f0bc104 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathParser.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathParser.h
@@ -38,7 +38,9 @@ class XPathNSResolver;
namespace XPath {
class Expression;
+class LocationPath;
class ParseNode;
+class Parser;
class Predicate;
struct Token {
@@ -57,6 +59,7 @@ struct Token {
class Parser {
WTF_MAKE_NONCOPYABLE(Parser);
+ STACK_ALLOCATED();
public:
Parser();
~Parser();
@@ -64,23 +67,23 @@ public:
XPathNSResolver* resolver() const { return m_resolver.get(); }
bool expandQName(const String& qName, AtomicString& localName, AtomicString& namespaceURI);
- Expression* parseStatement(const String& statement, PassRefPtr<XPathNSResolver>, ExceptionState&);
+ PassOwnPtrWillBeRawPtr<Expression> parseStatement(const String& statement, PassRefPtrWillBeRawPtr<XPathNSResolver>, ExceptionState&);
static Parser* current() { return currentParser; }
int lex(void* yylval);
- Expression* m_topExpr;
+ RawPtrWillBeMember<Expression> m_topExpr;
bool m_gotNamespaceError;
void registerParseNode(ParseNode*);
void unregisterParseNode(ParseNode*);
- void registerPredicateVector(Vector<OwnPtr<Predicate> >*);
- void deletePredicateVector(Vector<OwnPtr<Predicate> >*);
+ void registerPredicateVector(WillBeHeapVector<OwnPtrWillBeMember<Predicate> >*);
+ void deletePredicateVector(WillBeHeapVector<OwnPtrWillBeMember<Predicate> >*);
- void registerExpressionVector(Vector<OwnPtr<Expression> >*);
- void deleteExpressionVector(Vector<OwnPtr<Expression> >*);
+ void registerExpressionVector(WillBeHeapVector<OwnPtrWillBeMember<Expression> >*);
+ void deleteExpressionVector(WillBeHeapVector<OwnPtrWillBeMember<Expression> >*);
void registerString(String*);
void deleteString(String*);
@@ -113,17 +116,20 @@ private:
unsigned m_nextPos;
String m_data;
int m_lastTokenType;
- RefPtr<XPathNSResolver> m_resolver;
+ RefPtrWillBeMember<XPathNSResolver> m_resolver;
+#if !ENABLE(OILPAN)
HashSet<ParseNode*> m_parseNodes;
HashSet<Vector<OwnPtr<Predicate> >*> m_predicateVectors;
HashSet<Vector<OwnPtr<Expression> >*> m_expressionVectors;
- HashSet<String*> m_strings;
- HashSet<Step::NodeTest*> m_nodeTests;
+ HashSet<OwnPtr<Step::NodeTest> > m_nodeTests;
+#endif
+ HashSet<OwnPtr<String> > m_strings;
};
-} // XPath
+} // namespace XPath
-} // WebCore
+} // namespace WebCore
+int xpathyyparse(WebCore::XPath::Parser*);
#endif
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathPath.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathPath.cpp
index 80e57b3d49e..66127dd1b13 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathPath.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathPath.cpp
@@ -36,7 +36,7 @@
namespace WebCore {
namespace XPath {
-Filter::Filter(PassOwnPtr<Expression> expr, Vector<OwnPtr<Predicate> >& predicates)
+Filter::Filter(PassOwnPtrWillBeRawPtr<Expression> expr, WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& predicates)
: m_expr(expr)
{
m_predicates.swap(predicates);
@@ -49,6 +49,13 @@ Filter::~Filter()
{
}
+void Filter::trace(Visitor* visitor)
+{
+ visitor->trace(m_expr);
+ visitor->trace(m_predicates);
+ Expression::trace(visitor);
+}
+
Value Filter::evaluate() const
{
Value v = m_expr->evaluate();
@@ -58,7 +65,7 @@ Value Filter::evaluate() const
EvaluationContext& evaluationContext = Expression::evaluationContext();
for (unsigned i = 0; i < m_predicates.size(); i++) {
- NodeSet newNodes;
+ OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create());
evaluationContext.size = nodes.size();
evaluationContext.position = 0;
@@ -69,9 +76,9 @@ Value Filter::evaluate() const
++evaluationContext.position;
if (m_predicates[i]->evaluate())
- newNodes.append(node);
+ newNodes->append(node);
}
- nodes.swap(newNodes);
+ nodes.swap(*newNodes);
}
return v;
@@ -85,7 +92,17 @@ LocationPath::LocationPath()
LocationPath::~LocationPath()
{
+#if !ENABLE(OILPAN)
deleteAllValues(m_steps);
+#endif
+}
+
+void LocationPath::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+ visitor->trace(m_steps);
+#endif
+ Expression::trace(visitor);
}
Value LocationPath::evaluate() const
@@ -105,15 +122,15 @@ Value LocationPath::evaluate() const
if (context->inDocument())
context = context->ownerDocument();
else
- context = context->highestAncestor();
+ context = &context->highestAncestorOrSelf();
}
- NodeSet nodes;
- nodes.append(context);
- evaluate(nodes);
+ OwnPtrWillBeRawPtr<NodeSet> nodes(NodeSet::create());
+ nodes->append(context);
+ evaluate(*nodes);
evaluationContext = backupContext;
- return Value(nodes, Value::adopt);
+ return Value(nodes.release(), Value::adopt);
}
void LocationPath::evaluate(NodeSet& nodes) const
@@ -122,7 +139,7 @@ void LocationPath::evaluate(NodeSet& nodes) const
for (unsigned i = 0; i < m_steps.size(); i++) {
Step* step = m_steps[i];
- NodeSet newNodes;
+ OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create());
HashSet<Node*> newNodesSet;
bool needToCheckForDuplicateNodes = !nodes.subtreesAreDisjoint() || (step->axis() != Step::ChildAxis && step->axis() != Step::SelfAxis
@@ -133,23 +150,23 @@ void LocationPath::evaluate(NodeSet& nodes) const
// This is a simplified check that can be improved to handle more cases.
if (nodes.subtreesAreDisjoint() && (step->axis() == Step::ChildAxis || step->axis() == Step::SelfAxis))
- newNodes.markSubtreesDisjoint(true);
+ newNodes->markSubtreesDisjoint(true);
for (unsigned j = 0; j < nodes.size(); j++) {
- NodeSet matches;
- step->evaluate(nodes[j], matches);
+ OwnPtrWillBeRawPtr<NodeSet> matches(NodeSet::create());
+ step->evaluate(nodes[j], *matches);
- if (!matches.isSorted())
+ if (!matches->isSorted())
resultIsSorted = false;
- for (size_t nodeIndex = 0; nodeIndex < matches.size(); ++nodeIndex) {
- Node* node = matches[nodeIndex];
+ for (size_t nodeIndex = 0; nodeIndex < matches->size(); ++nodeIndex) {
+ Node* node = (*matches)[nodeIndex];
if (!needToCheckForDuplicateNodes || newNodesSet.add(node).isNewEntry)
- newNodes.append(node);
+ newNodes->append(node);
}
}
- nodes.swap(newNodes);
+ nodes.swap(*newNodes);
}
nodes.markSorted(resultIsSorted);
@@ -162,7 +179,9 @@ void LocationPath::appendStep(Step* step)
bool dropSecondStep;
optimizeStepPair(m_steps[stepCount - 1], step, dropSecondStep);
if (dropSecondStep) {
+#if !ENABLE(OILPAN)
delete step;
+#endif
return;
}
}
@@ -176,7 +195,9 @@ void LocationPath::insertFirstStep(Step* step)
bool dropSecondStep;
optimizeStepPair(step, m_steps[0], dropSecondStep);
if (dropSecondStep) {
+#if !ENABLE(OILPAN)
delete m_steps[0];
+#endif
m_steps[0] = step;
return;
}
@@ -186,8 +207,8 @@ void LocationPath::insertFirstStep(Step* step)
}
Path::Path(Expression* filter, LocationPath* path)
- : m_filter(filter)
- , m_path(path)
+ : m_filter(adoptPtrWillBeNoop(filter))
+ , m_path(adoptPtrWillBeNoop(path))
{
setIsContextNodeSensitive(filter->isContextNodeSensitive());
setIsContextPositionSensitive(filter->isContextPositionSensitive());
@@ -196,8 +217,13 @@ Path::Path(Expression* filter, LocationPath* path)
Path::~Path()
{
- delete m_filter;
- delete m_path;
+}
+
+void Path::trace(Visitor* visitor)
+{
+ visitor->trace(m_filter);
+ visitor->trace(m_path);
+ Expression::trace(visitor);
}
Value Path::evaluate() const
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathPath.h b/chromium/third_party/WebKit/Source/core/xml/XPathPath.h
index 18016a8500f..12b2b2638fe 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathPath.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathPath.h
@@ -32,59 +32,61 @@
namespace WebCore {
- namespace XPath {
+namespace XPath {
- class Predicate;
- class Step;
+class Predicate;
+class Step;
- class Filter FINAL : public Expression {
- public:
- Filter(PassOwnPtr<Expression>, Vector<OwnPtr<Predicate> >&);
- virtual ~Filter();
+class Filter FINAL : public Expression {
+public:
+ Filter(PassOwnPtrWillBeRawPtr<Expression>, WillBeHeapVector<OwnPtrWillBeMember<Predicate> >&);
+ virtual ~Filter();
+ virtual void trace(Visitor*) OVERRIDE;
- virtual Value evaluate() const OVERRIDE;
+ virtual Value evaluate() const OVERRIDE;
- private:
- virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
+private:
+ virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
- OwnPtr<Expression> m_expr;
- Vector<OwnPtr<Predicate> > m_predicates;
- };
+ OwnPtrWillBeMember<Expression> m_expr;
+ WillBeHeapVector<OwnPtrWillBeMember<Predicate> > m_predicates;
+};
- class LocationPath FINAL : public Expression {
- public:
- LocationPath();
- virtual ~LocationPath();
- void setAbsolute(bool value) { m_absolute = value; setIsContextNodeSensitive(!m_absolute); }
+class LocationPath FINAL : public Expression {
+public:
+ LocationPath();
+ virtual ~LocationPath();
+ virtual void trace(Visitor*) OVERRIDE;
- virtual Value evaluate() const OVERRIDE;
- void evaluate(NodeSet& nodes) const; // nodes is an input/output parameter
+ virtual Value evaluate() const OVERRIDE;
+ void setAbsolute(bool value) { m_absolute = value; setIsContextNodeSensitive(!m_absolute); }
+ void evaluate(NodeSet&) const; // nodes is an input/output parameter
+ void appendStep(Step*);
+ void insertFirstStep(Step*);
- void appendStep(Step* step);
- void insertFirstStep(Step* step);
+private:
+ virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
- private:
- virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
+ WillBeHeapVector<RawPtrWillBeMember<Step> > m_steps;
+ bool m_absolute;
+};
- Vector<Step*> m_steps;
- bool m_absolute;
- };
+class Path FINAL : public Expression {
+public:
+ Path(Expression*, LocationPath*);
+ virtual ~Path();
+ virtual void trace(Visitor*) OVERRIDE;
- class Path FINAL : public Expression {
- public:
- Path(Expression*, LocationPath*);
- virtual ~Path();
+ virtual Value evaluate() const OVERRIDE;
- virtual Value evaluate() const OVERRIDE;
+private:
+ virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
- private:
- virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
+ OwnPtrWillBeMember<Expression> m_filter;
+ OwnPtrWillBeMember<LocationPath> m_path;
+};
- Expression* m_filter;
- LocationPath* m_path;
- };
-
- }
}
-#endif // XPath_Path_H
+}
+#endif // XPathPath_h
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathPredicate.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathPredicate.cpp
index 38814185ebb..6719e651001 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathPredicate.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathPredicate.cpp
@@ -28,12 +28,13 @@
#include "config.h"
#include "core/xml/XPathPredicate.h"
-#include <math.h>
#include "core/xml/XPathFunctions.h"
#include "core/xml/XPathUtil.h"
#include "wtf/MathExtras.h"
+#include <math.h>
namespace WebCore {
+
namespace XPath {
Number::Number(double value)
@@ -41,6 +42,12 @@ Number::Number(double value)
{
}
+void Number::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ Expression::trace(visitor);
+}
+
Value Number::evaluate() const
{
return m_value;
@@ -51,6 +58,12 @@ StringExpression::StringExpression(const String& value)
{
}
+void StringExpression::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ Expression::trace(visitor);
+}
+
Value StringExpression::evaluate() const
{
return m_value;
@@ -62,7 +75,7 @@ Value Negative::evaluate() const
return -p.toNumber();
}
-NumericOp::NumericOp(Opcode opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs)
+NumericOp::NumericOp(Opcode opcode, PassOwnPtrWillBeRawPtr<Expression> lhs, PassOwnPtrWillBeRawPtr<Expression> rhs)
: m_opcode(opcode)
{
addSubExpression(lhs);
@@ -78,22 +91,22 @@ Value NumericOp::evaluate() const
double rightVal = rhs.toNumber();
switch (m_opcode) {
- case OP_Add:
- return leftVal + rightVal;
- case OP_Sub:
- return leftVal - rightVal;
- case OP_Mul:
- return leftVal * rightVal;
- case OP_Div:
- return leftVal / rightVal;
- case OP_Mod:
- return fmod(leftVal, rightVal);
+ case OP_Add:
+ return leftVal + rightVal;
+ case OP_Sub:
+ return leftVal - rightVal;
+ case OP_Mul:
+ return leftVal * rightVal;
+ case OP_Div:
+ return leftVal / rightVal;
+ case OP_Mod:
+ return fmod(leftVal, rightVal);
}
ASSERT_NOT_REACHED();
return 0.0;
}
-EqTestOp::EqTestOp(Opcode opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs)
+EqTestOp::EqTestOp(Opcode opcode, PassOwnPtrWillBeRawPtr<Expression> lhs, PassOwnPtrWillBeRawPtr<Expression> rhs)
: m_opcode(opcode)
{
addSubExpression(lhs);
@@ -105,38 +118,51 @@ bool EqTestOp::compare(const Value& lhs, const Value& rhs) const
if (lhs.isNodeSet()) {
const NodeSet& lhsSet = lhs.toNodeSet();
if (rhs.isNodeSet()) {
- // If both objects to be compared are node-sets, then the comparison will be true if and only if
- // there is a node in the first node-set and a node in the second node-set such that the result of
- // performing the comparison on the string-values of the two nodes is true.
+ // If both objects to be compared are node-sets, then the comparison
+ // will be true if and only if there is a node in the first node-set
+ // and a node in the second node-set such that the result of
+ // performing the comparison on the string-values of the two nodes
+ // is true.
const NodeSet& rhsSet = rhs.toNodeSet();
- for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex)
- for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex)
+ for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) {
+ for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) {
if (compare(stringValue(lhsSet[lindex]), stringValue(rhsSet[rindex])))
return true;
+ }
+ }
return false;
}
if (rhs.isNumber()) {
- // If one object to be compared is a node-set and the other is a number, then the comparison will be true
- // if and only if there is a node in the node-set such that the result of performing the comparison on the number
- // to be compared and on the result of converting the string-value of that node to a number using the number function is true.
- for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex)
+ // If one object to be compared is a node-set and the other is a
+ // number, then the comparison will be true if and only if there is
+ // a node in the node-set such that the result of performing the
+ // comparison on the number to be compared and on the result of
+ // converting the string-value of that node to a number using the
+ // number function is true.
+ for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) {
if (compare(Value(stringValue(lhsSet[lindex])).toNumber(), rhs))
return true;
+ }
return false;
}
if (rhs.isString()) {
- // If one object to be compared is a node-set and the other is a string, then the comparison will be true
- // if and only if there is a node in the node-set such that the result of performing the comparison on
- // the string-value of the node and the other string is true.
- for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex)
+ // If one object to be compared is a node-set and the other is a
+ // string, then the comparison will be true if and only if there is
+ // a node in the node-set such that the result of performing the
+ // comparison on the string-value of the node and the other string
+ // is true.
+ for (unsigned lindex = 0; lindex < lhsSet.size(); ++lindex) {
if (compare(stringValue(lhsSet[lindex]), rhs))
return true;
+ }
return false;
}
if (rhs.isBoolean()) {
- // If one object to be compared is a node-set and the other is a boolean, then the comparison will be true
- // if and only if the result of performing the comparison on the boolean and on the result of converting
- // the node-set to a boolean using the boolean function is true.
+ // If one object to be compared is a node-set and the other is a
+ // boolean, then the comparison will be true if and only if the
+ // result of performing the comparison on the boolean and on the
+ // result of converting the node-set to a boolean using the boolean
+ // function is true.
return compare(lhs.toBoolean(), rhs);
}
ASSERT(0);
@@ -144,15 +170,17 @@ bool EqTestOp::compare(const Value& lhs, const Value& rhs) const
if (rhs.isNodeSet()) {
const NodeSet& rhsSet = rhs.toNodeSet();
if (lhs.isNumber()) {
- for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex)
+ for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) {
if (compare(lhs, Value(stringValue(rhsSet[rindex])).toNumber()))
return true;
+ }
return false;
}
if (lhs.isString()) {
- for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex)
+ for (unsigned rindex = 0; rindex < rhsSet.size(); ++rindex) {
if (compare(lhs, stringValue(rhsSet[rindex])))
return true;
+ }
return false;
}
if (lhs.isBoolean())
@@ -162,27 +190,27 @@ bool EqTestOp::compare(const Value& lhs, const Value& rhs) const
// Neither side is a NodeSet.
switch (m_opcode) {
- case OP_EQ:
- case OP_NE:
- bool equal;
- if (lhs.isBoolean() || rhs.isBoolean())
- equal = lhs.toBoolean() == rhs.toBoolean();
- else if (lhs.isNumber() || rhs.isNumber())
- equal = lhs.toNumber() == rhs.toNumber();
- else
- equal = lhs.toString() == rhs.toString();
-
- if (m_opcode == OP_EQ)
- return equal;
- return !equal;
- case OP_GT:
- return lhs.toNumber() > rhs.toNumber();
- case OP_GE:
- return lhs.toNumber() >= rhs.toNumber();
- case OP_LT:
- return lhs.toNumber() < rhs.toNumber();
- case OP_LE:
- return lhs.toNumber() <= rhs.toNumber();
+ case OpcodeEqual:
+ case OpcodeNotEqual:
+ bool equal;
+ if (lhs.isBoolean() || rhs.isBoolean())
+ equal = lhs.toBoolean() == rhs.toBoolean();
+ else if (lhs.isNumber() || rhs.isNumber())
+ equal = lhs.toNumber() == rhs.toNumber();
+ else
+ equal = lhs.toString() == rhs.toString();
+
+ if (m_opcode == OpcodeEqual)
+ return equal;
+ return !equal;
+ case OpcodeGreaterThan:
+ return lhs.toNumber() > rhs.toNumber();
+ case OpcodeGreaterOrEqual:
+ return lhs.toNumber() >= rhs.toNumber();
+ case OpcodeLessThan:
+ return lhs.toNumber() < rhs.toNumber();
+ case OpcodeLessOrEqual:
+ return lhs.toNumber() <= rhs.toNumber();
}
ASSERT(0);
return false;
@@ -196,7 +224,7 @@ Value EqTestOp::evaluate() const
return compare(lhs, rhs);
}
-LogicalOp::LogicalOp(Opcode opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs)
+LogicalOp::LogicalOp(Opcode opcode, PassOwnPtrWillBeRawPtr<Expression> lhs, PassOwnPtrWillBeRawPtr<Expression> rhs)
: m_opcode(opcode)
{
addSubExpression(lhs);
@@ -205,10 +233,7 @@ LogicalOp::LogicalOp(Opcode opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expre
bool LogicalOp::shortCircuitOn() const
{
- if (m_opcode == OP_And)
- return false; //false and foo
-
- return true; //true or bar
+ return m_opcode != OP_And;
}
Value LogicalOp::evaluate() const
@@ -242,19 +267,23 @@ Value Union::evaluate() const
resultSet.append(node);
}
- // It is also possible to use merge sort to avoid making the result unsorted;
- // but this would waste the time in cases when order is not important.
+ // It is also possible to use merge sort to avoid making the result
+ // unsorted; but this would waste the time in cases when order is not
+ // important.
resultSet.markSorted(false);
return lhsResult;
}
-Predicate::Predicate(PassOwnPtr<Expression> expr)
+Predicate::Predicate(PassOwnPtrWillBeRawPtr<Expression> expr)
: m_expr(expr)
{
}
-Predicate::~Predicate()
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(Predicate);
+
+void Predicate::trace(Visitor* visitor)
{
+ visitor->trace(m_expr);
}
bool Predicate::evaluate() const
@@ -265,7 +294,7 @@ bool Predicate::evaluate() const
// foo[3] means foo[position()=3]
if (result.isNumber())
- return EqTestOp(EqTestOp::OP_EQ, adoptPtr(createFunction("position")), adoptPtr(new Number(result.toNumber()))).evaluate().toBoolean();
+ return EqTestOp(EqTestOp::OpcodeEqual, adoptPtrWillBeNoop(createFunction("position")), adoptPtrWillBeNoop(new Number(result.toNumber()))).evaluate().toBoolean();
return result.toBoolean();
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathPredicate.h b/chromium/third_party/WebKit/Source/core/xml/XPathPredicate.h
index 0b506f2f9b0..9422316b3db 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathPredicate.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathPredicate.h
@@ -32,93 +32,100 @@
namespace WebCore {
- namespace XPath {
-
- class Number : public Expression {
- public:
- explicit Number(double);
- private:
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
-
- Value m_value;
- };
-
- class StringExpression : public Expression {
- public:
- explicit StringExpression(const String&);
- private:
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::StringValue; }
-
- Value m_value;
- };
-
- class Negative : public Expression {
- private:
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
- };
-
- class NumericOp : public Expression {
- public:
- enum Opcode {
- OP_Add, OP_Sub, OP_Mul, OP_Div, OP_Mod
- };
- NumericOp(Opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs);
- private:
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NumberValue; }
-
- Opcode m_opcode;
- };
-
- class EqTestOp : public Expression {
- public:
- enum Opcode { OP_EQ, OP_NE, OP_GT, OP_LT, OP_GE, OP_LE };
- EqTestOp(Opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs);
- virtual Value evaluate() const;
- private:
- virtual Value::Type resultType() const { return Value::BooleanValue; }
- bool compare(const Value&, const Value&) const;
-
- Opcode m_opcode;
- };
-
- class LogicalOp : public Expression {
- public:
- enum Opcode { OP_And, OP_Or };
- LogicalOp(Opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs);
- private:
- virtual Value::Type resultType() const { return Value::BooleanValue; }
- bool shortCircuitOn() const;
- virtual Value evaluate() const;
-
- Opcode m_opcode;
- };
-
- class Union : public Expression {
- private:
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { return Value::NodeSetValue; }
- };
-
- class Predicate {
- WTF_MAKE_NONCOPYABLE(Predicate); WTF_MAKE_FAST_ALLOCATED;
- public:
- explicit Predicate(PassOwnPtr<Expression>);
- ~Predicate();
- bool evaluate() const;
-
- bool isContextPositionSensitive() const { return m_expr->isContextPositionSensitive() || m_expr->resultType() == Value::NumberValue; }
- bool isContextSizeSensitive() const { return m_expr->isContextSizeSensitive(); }
-
- private:
- OwnPtr<Expression> m_expr;
- };
-
- }
+namespace XPath {
+
+class Number FINAL : public Expression {
+public:
+ explicit Number(double);
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
+
+ Value m_value;
+};
+
+class StringExpression FINAL : public Expression {
+public:
+ explicit StringExpression(const String&);
+ virtual void trace(Visitor*) OVERRIDE;
+
+private:
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
+
+ Value m_value;
+};
+
+class Negative FINAL : public Expression {
+private:
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
+};
+
+class NumericOp FINAL : public Expression {
+public:
+ enum Opcode {
+ OP_Add, OP_Sub, OP_Mul, OP_Div, OP_Mod
+ };
+ NumericOp(Opcode, PassOwnPtrWillBeRawPtr<Expression> lhs, PassOwnPtrWillBeRawPtr<Expression> rhs);
+
+private:
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
+
+ Opcode m_opcode;
+};
+
+class EqTestOp FINAL : public Expression {
+public:
+ enum Opcode { OpcodeEqual, OpcodeNotEqual, OpcodeGreaterThan, OpcodeLessThan, OpcodeGreaterOrEqual, OpcodeLessOrEqual };
+ EqTestOp(Opcode, PassOwnPtrWillBeRawPtr<Expression> lhs, PassOwnPtrWillBeRawPtr<Expression> rhs);
+ virtual Value evaluate() const OVERRIDE;
+
+private:
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
+ bool compare(const Value&, const Value&) const;
+
+ Opcode m_opcode;
+};
+
+class LogicalOp FINAL : public Expression {
+public:
+ enum Opcode { OP_And, OP_Or };
+ LogicalOp(Opcode, PassOwnPtrWillBeRawPtr<Expression> lhs, PassOwnPtrWillBeRawPtr<Expression> rhs);
+
+private:
+ virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
+ bool shortCircuitOn() const;
+ virtual Value evaluate() const OVERRIDE;
+
+ Opcode m_opcode;
+};
+
+class Union FINAL : public Expression {
+private:
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
+};
+
+class Predicate FINAL : public NoBaseWillBeGarbageCollected<Predicate> {
+ WTF_MAKE_NONCOPYABLE(Predicate); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+ DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(Predicate);
+public:
+ explicit Predicate(PassOwnPtrWillBeRawPtr<Expression>);
+ void trace(Visitor*);
+
+ bool evaluate() const;
+ bool isContextPositionSensitive() const { return m_expr->isContextPositionSensitive() || m_expr->resultType() == Value::NumberValue; }
+ bool isContextSizeSensitive() const { return m_expr->isContextSizeSensitive(); }
+
+private:
+ OwnPtrWillBeMember<Expression> m_expr;
+};
}
+}
#endif // XPathPredicate_h
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathResult.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathResult.cpp
index 17aa9dd2061..e7a661d41e0 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathResult.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathResult.cpp
@@ -43,22 +43,22 @@ XPathResult::XPathResult(Document* document, const Value& value)
{
ScriptWrappable::init(this);
switch (m_value.type()) {
- case Value::BooleanValue:
- m_resultType = BOOLEAN_TYPE;
- return;
- case Value::NumberValue:
- m_resultType = NUMBER_TYPE;
- return;
- case Value::StringValue:
- m_resultType = STRING_TYPE;
- return;
- case Value::NodeSetValue:
- m_resultType = UNORDERED_NODE_ITERATOR_TYPE;
- m_nodeSetPosition = 0;
- m_nodeSet = m_value.toNodeSet();
- m_document = document;
- m_domTreeVersion = document->domTreeVersion();
- return;
+ case Value::BooleanValue:
+ m_resultType = BOOLEAN_TYPE;
+ return;
+ case Value::NumberValue:
+ m_resultType = NUMBER_TYPE;
+ return;
+ case Value::StringValue:
+ m_resultType = STRING_TYPE;
+ return;
+ case Value::NodeSetValue:
+ m_resultType = UNORDERED_NODE_ITERATOR_TYPE;
+ m_nodeSetPosition = 0;
+ m_nodeSet = NodeSet::create(m_value.toNodeSet());
+ m_document = document;
+ m_domTreeVersion = document->domTreeVersion();
+ return;
}
ASSERT_NOT_REACHED();
}
@@ -67,49 +67,57 @@ XPathResult::~XPathResult()
{
}
+void XPathResult::trace(Visitor* visitor)
+{
+ visitor->trace(m_value);
+ visitor->trace(m_nodeSet);
+ visitor->trace(m_document);
+}
+
void XPathResult::convertTo(unsigned short type, ExceptionState& exceptionState)
{
switch (type) {
- case ANY_TYPE:
- break;
- case NUMBER_TYPE:
- m_resultType = type;
- m_value = m_value.toNumber();
- break;
- case STRING_TYPE:
- m_resultType = type;
- m_value = m_value.toString();
- break;
- case BOOLEAN_TYPE:
- m_resultType = type;
- m_value = m_value.toBoolean();
- break;
- case UNORDERED_NODE_ITERATOR_TYPE:
- case UNORDERED_NODE_SNAPSHOT_TYPE:
- case ANY_UNORDERED_NODE_TYPE:
- case FIRST_ORDERED_NODE_TYPE: // This is correct - singleNodeValue() will take care of ordering.
- if (!m_value.isNodeSet()) {
- exceptionState.throwTypeError("The result is not a node set, and therefore cannot be converted to the desired type.");
- return;
- }
- m_resultType = type;
- break;
- case ORDERED_NODE_ITERATOR_TYPE:
- if (!m_value.isNodeSet()) {
- exceptionState.throwTypeError("The result is not a node set, and therefore cannot be converted to the desired type.");
- return;
- }
- m_nodeSet.sort();
- m_resultType = type;
- break;
- case ORDERED_NODE_SNAPSHOT_TYPE:
- if (!m_value.isNodeSet()) {
- exceptionState.throwTypeError("The result is not a node set, and therefore cannot be converted to the desired type.");
- return;
- }
- m_value.toNodeSet().sort();
- m_resultType = type;
- break;
+ case ANY_TYPE:
+ break;
+ case NUMBER_TYPE:
+ m_resultType = type;
+ m_value = m_value.toNumber();
+ break;
+ case STRING_TYPE:
+ m_resultType = type;
+ m_value = m_value.toString();
+ break;
+ case BOOLEAN_TYPE:
+ m_resultType = type;
+ m_value = m_value.toBoolean();
+ break;
+ case UNORDERED_NODE_ITERATOR_TYPE:
+ case UNORDERED_NODE_SNAPSHOT_TYPE:
+ case ANY_UNORDERED_NODE_TYPE:
+ // This is correct - singleNodeValue() will take care of ordering.
+ case FIRST_ORDERED_NODE_TYPE:
+ if (!m_value.isNodeSet()) {
+ exceptionState.throwTypeError("The result is not a node set, and therefore cannot be converted to the desired type.");
+ return;
+ }
+ m_resultType = type;
+ break;
+ case ORDERED_NODE_ITERATOR_TYPE:
+ if (!m_value.isNodeSet()) {
+ exceptionState.throwTypeError("The result is not a node set, and therefore cannot be converted to the desired type.");
+ return;
+ }
+ nodeSet().sort();
+ m_resultType = type;
+ break;
+ case ORDERED_NODE_SNAPSHOT_TYPE:
+ if (!m_value.isNodeSet()) {
+ exceptionState.throwTypeError("The result is not a node set, and therefore cannot be converted to the desired type.");
+ return;
+ }
+ m_value.toNodeSet().sort();
+ m_resultType = type;
+ break;
}
}
@@ -155,8 +163,7 @@ Node* XPathResult::singleNodeValue(ExceptionState& exceptionState) const
const NodeSet& nodes = m_value.toNodeSet();
if (resultType() == FIRST_ORDERED_NODE_TYPE)
return nodes.firstNode();
- else
- return nodes.anyNode();
+ return nodes.anyNode();
}
bool XPathResult::invalidIteratorState() const
@@ -190,10 +197,10 @@ Node* XPathResult::iterateNext(ExceptionState& exceptionState)
return 0;
}
- if (m_nodeSetPosition + 1 > m_nodeSet.size())
+ if (m_nodeSetPosition + 1 > nodeSet().size())
return 0;
- Node* node = m_nodeSet[m_nodeSetPosition];
+ Node* node = nodeSet()[m_nodeSetPosition];
m_nodeSetPosition++;
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathResult.h b/chromium/third_party/WebKit/Source/core/xml/XPathResult.h
index 319ef6cb1d5..a8f90f3df7a 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathResult.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathResult.h
@@ -29,6 +29,7 @@
#include "bindings/v8/ScriptWrappable.h"
#include "core/xml/XPathValue.h"
+#include "platform/heap/Handle.h"
#include "wtf/Forward.h"
#include "wtf/RefCounted.h"
@@ -38,7 +39,7 @@ class Document;
class ExceptionState;
class Node;
-class XPathResult : public RefCounted<XPathResult>, public ScriptWrappable {
+class XPathResult : public RefCountedWillBeGarbageCollectedFinalized<XPathResult>, public ScriptWrappable {
public:
enum XPathResultType {
ANY_TYPE = 0,
@@ -53,7 +54,10 @@ public:
FIRST_ORDERED_NODE_TYPE = 9
};
- static PassRefPtr<XPathResult> create(Document* document, const XPath::Value& value) { return adoptRef(new XPathResult(document, value)); }
+ static PassRefPtrWillBeRawPtr<XPathResult> create(Document* document, const XPath::Value& value)
+ {
+ return adoptRefWillBeNoop(new XPathResult(document, value));
+ }
~XPathResult();
void convertTo(unsigned short type, ExceptionState&);
@@ -72,14 +76,17 @@ public:
const XPath::Value& value() const { return m_value; }
+ void trace(Visitor*);
+
private:
XPathResult(Document*, const XPath::Value&);
+ XPath::NodeSet& nodeSet() { return *m_nodeSet; }
XPath::Value m_value;
unsigned m_nodeSetPosition;
- XPath::NodeSet m_nodeSet; // FIXME: why duplicate the node set stored in m_value?
+ OwnPtrWillBeMember<XPath::NodeSet> m_nodeSet; // FIXME: why duplicate the node set stored in m_value?
unsigned short m_resultType;
- RefPtr<Document> m_document;
+ RefPtrWillBeMember<Document> m_document;
uint64_t m_domTreeVersion;
};
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathResult.idl b/chromium/third_party/WebKit/Source/core/xml/XPathResult.idl
index dd5f9cf9ac1..f60a5eaac04 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathResult.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathResult.idl
@@ -18,6 +18,7 @@
*/
[
+ WillBeGarbageCollected
] interface XPathResult {
const unsigned short ANY_TYPE = 0;
const unsigned short NUMBER_TYPE = 1;
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathStep.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathStep.cpp
index 4687257be64..43d71ddd0f2 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathStep.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathStep.cpp
@@ -28,7 +28,7 @@
#include "config.h"
#include "core/xml/XPathStep.h"
-#include "XMLNSNames.h"
+#include "core/XMLNSNames.h"
#include "core/dom/Attr.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
@@ -41,13 +41,13 @@ namespace XPath {
Step::Step(Axis axis, const NodeTest& nodeTest)
: m_axis(axis)
- , m_nodeTest(nodeTest)
+ , m_nodeTest(adoptPtrWillBeNoop(new NodeTest(nodeTest)))
{
}
-Step::Step(Axis axis, const NodeTest& nodeTest, Vector<OwnPtr<Predicate> >& predicates)
+Step::Step(Axis axis, const NodeTest& nodeTest, WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& predicates)
: m_axis(axis)
- , m_nodeTest(nodeTest)
+ , m_nodeTest(adoptPtrWillBeNoop(new NodeTest(nodeTest)))
{
m_predicates.swap(predicates);
}
@@ -56,16 +56,27 @@ Step::~Step()
{
}
+void Step::trace(Visitor* visitor)
+{
+ visitor->trace(m_nodeTest);
+ visitor->trace(m_predicates);
+ ParseNode::trace(visitor);
+}
+
void Step::optimize()
{
- // Evaluate predicates as part of node test if possible to avoid building unnecessary NodeSets.
- // E.g., there is no need to build a set of all "foo" nodes to evaluate "foo[@bar]", we can check the predicate while enumerating.
- // This optimization can be applied to predicates that are not context node list sensitive, or to first predicate that is only context position sensitive, e.g. foo[position() mod 2 = 0].
- Vector<OwnPtr<Predicate> > remainingPredicates;
+ // Evaluate predicates as part of node test if possible to avoid building
+ // unnecessary NodeSets.
+ // E.g., there is no need to build a set of all "foo" nodes to evaluate
+ // "foo[@bar]", we can check the predicate while enumerating.
+ // This optimization can be applied to predicates that are not context node
+ // list sensitive, or to first predicate that is only context position
+ // sensitive, e.g. foo[position() mod 2 = 0].
+ WillBeHeapVector<OwnPtrWillBeMember<Predicate> > remainingPredicates;
for (size_t i = 0; i < m_predicates.size(); ++i) {
- OwnPtr<Predicate> predicate(m_predicates[i].release());
- if ((!predicate->isContextPositionSensitive() || m_nodeTest.mergedPredicates().isEmpty()) && !predicate->isContextSizeSensitive() && remainingPredicates.isEmpty()) {
- m_nodeTest.mergedPredicates().append(predicate.release());
+ OwnPtrWillBeRawPtr<Predicate> predicate(m_predicates[i].release());
+ if ((!predicate->isContextPositionSensitive() || nodeTest().mergedPredicates().isEmpty()) && !predicate->isContextSizeSensitive() && remainingPredicates.isEmpty()) {
+ nodeTest().mergedPredicates().append(predicate.release());
} else {
remainingPredicates.append(predicate.release());
}
@@ -78,18 +89,19 @@ void optimizeStepPair(Step* first, Step* second, bool& dropSecondStep)
dropSecondStep = false;
if (first->m_axis == Step::DescendantOrSelfAxis
- && first->m_nodeTest.kind() == Step::NodeTest::AnyNodeTest
+ && first->nodeTest().kind() == Step::NodeTest::AnyNodeTest
&& !first->m_predicates.size()
- && !first->m_nodeTest.mergedPredicates().size()) {
+ && !first->nodeTest().mergedPredicates().size()) {
- ASSERT(first->m_nodeTest.data().isEmpty());
- ASSERT(first->m_nodeTest.namespaceURI().isEmpty());
+ ASSERT(first->nodeTest().data().isEmpty());
+ ASSERT(first->nodeTest().namespaceURI().isEmpty());
- // Optimize the common case of "//" AKA /descendant-or-self::node()/child::NodeTest to /descendant::NodeTest.
+ // Optimize the common case of "//" AKA
+ // /descendant-or-self::node()/child::NodeTest to /descendant::NodeTest.
if (second->m_axis == Step::ChildAxis && second->predicatesAreContextListInsensitive()) {
first->m_axis = Step::DescendantAxis;
- first->m_nodeTest = Step::NodeTest(second->m_nodeTest.kind(), second->m_nodeTest.data(), second->m_nodeTest.namespaceURI());
- swap(second->m_nodeTest.mergedPredicates(), first->m_nodeTest.mergedPredicates());
+ first->nodeTest() = Step::NodeTest(second->nodeTest().kind(), second->nodeTest().data(), second->nodeTest().namespaceURI());
+ swap(second->nodeTest().mergedPredicates(), first->nodeTest().mergedPredicates());
swap(second->m_predicates, first->m_predicates);
first->optimize();
dropSecondStep = true;
@@ -105,8 +117,8 @@ bool Step::predicatesAreContextListInsensitive() const
return false;
}
- for (size_t i = 0; i < m_nodeTest.mergedPredicates().size(); ++i) {
- Predicate* predicate = m_nodeTest.mergedPredicates()[i].get();
+ for (size_t i = 0; i < nodeTest().mergedPredicates().size(); ++i) {
+ Predicate* predicate = nodeTest().mergedPredicates()[i].get();
if (predicate->isContextPositionSensitive() || predicate->isContextSizeSensitive())
return false;
}
@@ -125,9 +137,9 @@ void Step::evaluate(Node* context, NodeSet& nodes) const
for (unsigned i = 0; i < m_predicates.size(); i++) {
Predicate* predicate = m_predicates[i].get();
- NodeSet newNodes;
+ OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create());
if (!nodes.isSorted())
- newNodes.markSorted(false);
+ newNodes->markSorted(false);
for (unsigned j = 0; j < nodes.size(); j++) {
Node* node = nodes[j];
@@ -136,23 +148,21 @@ void Step::evaluate(Node* context, NodeSet& nodes) const
evaluationContext.size = nodes.size();
evaluationContext.position = j + 1;
if (predicate->evaluate())
- newNodes.append(node);
+ newNodes->append(node);
}
- nodes.swap(newNodes);
+ nodes.swap(*newNodes);
}
}
-#if !ASSERT_DISABLED
+#if ASSERT_ENABLED
static inline Node::NodeType primaryNodeType(Step::Axis axis)
{
switch (axis) {
- case Step::AttributeAxis:
- return Node::ATTRIBUTE_NODE;
- case Step::NamespaceAxis:
- return Node::XPATH_NAMESPACE_NODE;
- default:
- return Node::ELEMENT_NODE;
+ case Step::AttributeAxis:
+ return Node::ATTRIBUTE_NODE;
+ default:
+ return Node::ELEMENT_NODE;
}
}
#endif
@@ -161,54 +171,62 @@ static inline Node::NodeType primaryNodeType(Step::Axis axis)
static inline bool nodeMatchesBasicTest(Node* node, Step::Axis axis, const Step::NodeTest& nodeTest)
{
switch (nodeTest.kind()) {
- case Step::NodeTest::TextNodeTest:
- return node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE;
- case Step::NodeTest::CommentNodeTest:
- return node->nodeType() == Node::COMMENT_NODE;
- case Step::NodeTest::ProcessingInstructionNodeTest: {
- const AtomicString& name = nodeTest.data();
- return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (name.isEmpty() || node->nodeName() == name);
- }
- case Step::NodeTest::AnyNodeTest:
- return true;
- case Step::NodeTest::NameTest: {
- const AtomicString& name = nodeTest.data();
- const AtomicString& namespaceURI = nodeTest.namespaceURI();
-
- if (axis == Step::AttributeAxis) {
- ASSERT(node->isAttributeNode());
-
- // In XPath land, namespace nodes are not accessible on the attribute axis.
- if (node->namespaceURI() == XMLNSNames::xmlnsNamespaceURI)
- return false;
+ case Step::NodeTest::TextNodeTest: {
+ Node::NodeType type = node->nodeType();
+ return type == Node::TEXT_NODE || type == Node::CDATA_SECTION_NODE;
+ }
+ case Step::NodeTest::CommentNodeTest:
+ return node->nodeType() == Node::COMMENT_NODE;
+ case Step::NodeTest::ProcessingInstructionNodeTest: {
+ const AtomicString& name = nodeTest.data();
+ return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (name.isEmpty() || node->nodeName() == name);
+ }
+ case Step::NodeTest::AnyNodeTest:
+ return true;
+ case Step::NodeTest::NameTest: {
+ const AtomicString& name = nodeTest.data();
+ const AtomicString& namespaceURI = nodeTest.namespaceURI();
+
+ if (axis == Step::AttributeAxis) {
+ ASSERT(node->isAttributeNode());
+
+ // In XPath land, namespace nodes are not accessible on the
+ // attribute axis.
+ if (node->namespaceURI() == XMLNSNames::xmlnsNamespaceURI)
+ return false;
- if (name == starAtom)
- return namespaceURI.isEmpty() || node->namespaceURI() == namespaceURI;
+ if (name == starAtom)
+ return namespaceURI.isEmpty() || node->namespaceURI() == namespaceURI;
- return node->localName() == name && node->namespaceURI() == namespaceURI;
- }
+ return node->localName() == name && node->namespaceURI() == namespaceURI;
+ }
- // Node test on the namespace axis is not implemented yet, the caller has a check for it.
- ASSERT(axis != Step::NamespaceAxis);
+ // Node test on the namespace axis is not implemented yet, the caller
+ // has a check for it.
+ ASSERT(axis != Step::NamespaceAxis);
- // For other axes, the principal node type is element.
- ASSERT(primaryNodeType(axis) == Node::ELEMENT_NODE);
- if (node->nodeType() != Node::ELEMENT_NODE)
- return false;
+ // For other axes, the principal node type is element.
+ ASSERT(primaryNodeType(axis) == Node::ELEMENT_NODE);
+ if (!node->isElementNode())
+ return false;
+ Element& element = toElement(*node);
- if (name == starAtom)
- return namespaceURI.isEmpty() || namespaceURI == node->namespaceURI();
+ if (name == starAtom)
+ return namespaceURI.isEmpty() || namespaceURI == element.namespaceURI();
- if (node->document().isHTMLDocument()) {
- if (node->isHTMLElement()) {
- // Paths without namespaces should match HTML elements in HTML documents despite those having an XHTML namespace. Names are compared case-insensitively.
- return equalIgnoringCase(toElement(node)->localName(), name) && (namespaceURI.isNull() || namespaceURI == node->namespaceURI());
- }
- // An expression without any prefix shouldn't match no-namespace nodes (because HTML5 says so).
- return toElement(node)->hasLocalName(name) && namespaceURI == node->namespaceURI() && !namespaceURI.isNull();
+ if (element.document().isHTMLDocument()) {
+ if (element.isHTMLElement()) {
+ // Paths without namespaces should match HTML elements in HTML
+ // documents despite those having an XHTML namespace. Names are
+ // compared case-insensitively.
+ return equalIgnoringCase(element.localName(), name) && (namespaceURI.isNull() || namespaceURI == element.namespaceURI());
}
- return toElement(node)->hasLocalName(name) && namespaceURI == node->namespaceURI();
+ // An expression without any prefix shouldn't match no-namespace
+ // nodes (because HTML5 says so).
+ return element.hasLocalName(name) && namespaceURI == element.namespaceURI() && !namespaceURI.isNull();
}
+ return element.hasLocalName(name) && namespaceURI == element.namespaceURI();
+ }
}
ASSERT_NOT_REACHED();
return false;
@@ -224,12 +242,13 @@ static inline bool nodeMatches(Node* node, Step::Axis axis, const Step::NodeTest
// Only the first merged predicate may depend on position.
++evaluationContext.position;
- const Vector<OwnPtr<Predicate> >& mergedPredicates = nodeTest.mergedPredicates();
+ const WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& mergedPredicates = nodeTest.mergedPredicates();
for (unsigned i = 0; i < mergedPredicates.size(); i++) {
Predicate* predicate = mergedPredicates[i].get();
evaluationContext.node = node;
- // No need to set context size - we only get here when evaluating predicates that do not depend on it.
+ // No need to set context size - we only get here when evaluating
+ // predicates that do not depend on it.
if (!predicate->evaluate())
return false;
}
@@ -237,167 +256,192 @@ static inline bool nodeMatches(Node* node, Step::Axis axis, const Step::NodeTest
return true;
}
-// Result nodes are ordered in axis order. Node test (including merged predicates) is applied.
+// Result nodes are ordered in axis order. Node test (including merged
+// predicates) is applied.
void Step::nodesInAxis(Node* context, NodeSet& nodes) const
{
ASSERT(nodes.isEmpty());
switch (m_axis) {
- case ChildAxis:
- if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
- return;
-
- for (Node* n = context->firstChild(); n; n = n->nextSibling())
- if (nodeMatches(n, ChildAxis, m_nodeTest))
- nodes.append(n);
+ case ChildAxis:
+ // In XPath model, attribute nodes do not have children.
+ if (context->isAttributeNode())
return;
- case DescendantAxis:
- if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
- return;
- for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context))
- if (nodeMatches(n, DescendantAxis, m_nodeTest))
- nodes.append(n);
- return;
- case ParentAxis:
- if (context->isAttributeNode()) {
- Element* n = toAttr(context)->ownerElement();
- if (nodeMatches(n, ParentAxis, m_nodeTest))
- nodes.append(n);
- } else {
- ContainerNode* n = context->parentNode();
- if (n && nodeMatches(n, ParentAxis, m_nodeTest))
- nodes.append(n);
- }
- return;
- case AncestorAxis: {
- Node* n = context;
- if (context->isAttributeNode()) {
- n = toAttr(context)->ownerElement();
- if (nodeMatches(n, AncestorAxis, m_nodeTest))
- nodes.append(n);
- }
- for (n = n->parentNode(); n; n = n->parentNode())
- if (nodeMatches(n, AncestorAxis, m_nodeTest))
- nodes.append(n);
- nodes.markSorted(false);
+ for (Node* n = context->firstChild(); n; n = n->nextSibling()) {
+ if (nodeMatches(n, ChildAxis, nodeTest()))
+ nodes.append(n);
+ }
+ return;
+
+ case DescendantAxis:
+ // In XPath model, attribute nodes do not have children.
+ if (context->isAttributeNode())
return;
+
+ for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) {
+ if (nodeMatches(n, DescendantAxis, nodeTest()))
+ nodes.append(n);
}
- case FollowingSiblingAxis:
- if (context->nodeType() == Node::ATTRIBUTE_NODE ||
- context->nodeType() == Node::XPATH_NAMESPACE_NODE)
- return;
+ return;
- for (Node* n = context->nextSibling(); n; n = n->nextSibling())
- if (nodeMatches(n, FollowingSiblingAxis, m_nodeTest))
- nodes.append(n);
+ case ParentAxis:
+ if (context->isAttributeNode()) {
+ Element* n = toAttr(context)->ownerElement();
+ if (nodeMatches(n, ParentAxis, nodeTest()))
+ nodes.append(n);
+ } else {
+ ContainerNode* n = context->parentNode();
+ if (n && nodeMatches(n, ParentAxis, nodeTest()))
+ nodes.append(n);
+ }
+ return;
+
+ case AncestorAxis: {
+ Node* n = context;
+ if (context->isAttributeNode()) {
+ n = toAttr(context)->ownerElement();
+ if (nodeMatches(n, AncestorAxis, nodeTest()))
+ nodes.append(n);
+ }
+ for (n = n->parentNode(); n; n = n->parentNode()) {
+ if (nodeMatches(n, AncestorAxis, nodeTest()))
+ nodes.append(n);
+ }
+ nodes.markSorted(false);
+ return;
+ }
+
+ case FollowingSiblingAxis:
+ if (context->nodeType() == Node::ATTRIBUTE_NODE)
return;
- case PrecedingSiblingAxis:
- if (context->nodeType() == Node::ATTRIBUTE_NODE ||
- context->nodeType() == Node::XPATH_NAMESPACE_NODE)
- return;
- for (Node* n = context->previousSibling(); n; n = n->previousSibling())
- if (nodeMatches(n, PrecedingSiblingAxis, m_nodeTest))
- nodes.append(n);
+ for (Node* n = context->nextSibling(); n; n = n->nextSibling()) {
+ if (nodeMatches(n, FollowingSiblingAxis, nodeTest()))
+ nodes.append(n);
+ }
+ return;
- nodes.markSorted(false);
+ case PrecedingSiblingAxis:
+ if (context->nodeType() == Node::ATTRIBUTE_NODE)
return;
- case FollowingAxis:
- if (context->isAttributeNode()) {
- Node* p = toAttr(context)->ownerElement();
- while ((p = NodeTraversal::next(*p))) {
- if (nodeMatches(p, FollowingAxis, m_nodeTest))
- nodes.append(p);
- }
- } else {
- for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
- for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
- if (nodeMatches(n, FollowingAxis, m_nodeTest))
- nodes.append(n);
- for (Node* c = n->firstChild(); c; c = NodeTraversal::next(*c, n))
- if (nodeMatches(c, FollowingAxis, m_nodeTest))
- nodes.append(c);
- }
- }
+
+ for (Node* n = context->previousSibling(); n; n = n->previousSibling()) {
+ if (nodeMatches(n, PrecedingSiblingAxis, nodeTest()))
+ nodes.append(n);
+ }
+ nodes.markSorted(false);
+ return;
+
+ case FollowingAxis:
+ if (context->isAttributeNode()) {
+ Node* p = toAttr(context)->ownerElement();
+ while ((p = NodeTraversal::next(*p))) {
+ if (nodeMatches(p, FollowingAxis, nodeTest()))
+ nodes.append(p);
}
- return;
- case PrecedingAxis: {
- if (context->isAttributeNode())
- context = toAttr(context)->ownerElement();
-
- Node* n = context;
- while (ContainerNode* parent = n->parentNode()) {
- for (n = NodeTraversal::previous(*n); n != parent; n = NodeTraversal::previous(*n))
- if (nodeMatches(n, PrecedingAxis, m_nodeTest))
+ } else {
+ for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
+ for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
+ if (nodeMatches(n, FollowingAxis, nodeTest()))
nodes.append(n);
- n = parent;
- }
- nodes.markSorted(false);
- return;
- }
- case AttributeAxis: {
- if (!context->isElementNode())
- return;
-
- Element* contextElement = toElement(context);
-
- // Avoid lazily creating attribute nodes for attributes that we do not need anyway.
- if (m_nodeTest.kind() == NodeTest::NameTest && m_nodeTest.data() != starAtom) {
- RefPtr<Node> n = contextElement->getAttributeNodeNS(m_nodeTest.namespaceURI(), m_nodeTest.data());
- if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) { // In XPath land, namespace nodes are not accessible on the attribute axis.
- if (nodeMatches(n.get(), AttributeAxis, m_nodeTest)) // Still need to check merged predicates.
- nodes.append(n.release());
+ for (Node* c = n->firstChild(); c; c = NodeTraversal::next(*c, n)) {
+ if (nodeMatches(c, FollowingAxis, nodeTest()))
+ nodes.append(c);
+ }
}
- return;
}
+ }
+ return;
- if (!contextElement->hasAttributes())
- return;
+ case PrecedingAxis: {
+ if (context->isAttributeNode())
+ context = toAttr(context)->ownerElement();
- for (unsigned i = 0; i < contextElement->attributeCount(); ++i) {
- RefPtr<Attr> attr = contextElement->ensureAttr(contextElement->attributeItem(i)->name());
- if (nodeMatches(attr.get(), AttributeAxis, m_nodeTest))
- nodes.append(attr.release());
+ Node* n = context;
+ while (ContainerNode* parent = n->parentNode()) {
+ for (n = NodeTraversal::previous(*n); n != parent; n = NodeTraversal::previous(*n)) {
+ if (nodeMatches(n, PrecedingAxis, nodeTest()))
+ nodes.append(n);
}
- return;
+ n = parent;
}
- case NamespaceAxis:
- // XPath namespace nodes are not implemented yet.
+ nodes.markSorted(false);
+ return;
+ }
+
+ case AttributeAxis: {
+ if (!context->isElementNode())
return;
- case SelfAxis:
- if (nodeMatches(context, SelfAxis, m_nodeTest))
- nodes.append(context);
+
+ Element* contextElement = toElement(context);
+ // Avoid lazily creating attribute nodes for attributes that we do not
+ // need anyway.
+ if (nodeTest().kind() == NodeTest::NameTest && nodeTest().data() != starAtom) {
+ RefPtrWillBeRawPtr<Node> n = contextElement->getAttributeNodeNS(nodeTest().namespaceURI(), nodeTest().data());
+ // In XPath land, namespace nodes are not accessible on the attribute axis.
+ if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) {
+ // Still need to check merged predicates.
+ if (nodeMatches(n.get(), AttributeAxis, nodeTest()))
+ nodes.append(n.release());
+ }
return;
- case DescendantOrSelfAxis:
- if (nodeMatches(context, DescendantOrSelfAxis, m_nodeTest))
- nodes.append(context);
- if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
- return;
-
- for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context))
- if (nodeMatches(n, DescendantOrSelfAxis, m_nodeTest))
- nodes.append(n);
+ }
+
+ if (!contextElement->hasAttributes())
return;
- case AncestorOrSelfAxis: {
- if (nodeMatches(context, AncestorOrSelfAxis, m_nodeTest))
- nodes.append(context);
- Node* n = context;
- if (context->isAttributeNode()) {
- n = toAttr(context)->ownerElement();
- if (nodeMatches(n, AncestorOrSelfAxis, m_nodeTest))
- nodes.append(n);
- }
- for (n = n->parentNode(); n; n = n->parentNode())
- if (nodeMatches(n, AncestorOrSelfAxis, m_nodeTest))
- nodes.append(n);
- nodes.markSorted(false);
+ AttributeCollection attributes = contextElement->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ RefPtrWillBeRawPtr<Attr> attr = contextElement->ensureAttr(it->name());
+ if (nodeMatches(attr.get(), AttributeAxis, nodeTest()))
+ nodes.append(attr.release());
+ }
+ return;
+ }
+
+ case NamespaceAxis:
+ // XPath namespace nodes are not implemented.
+ return;
+
+ case SelfAxis:
+ if (nodeMatches(context, SelfAxis, nodeTest()))
+ nodes.append(context);
+ return;
+
+ case DescendantOrSelfAxis:
+ if (nodeMatches(context, DescendantOrSelfAxis, nodeTest()))
+ nodes.append(context);
+ // In XPath model, attribute nodes do not have children.
+ if (context->isAttributeNode())
return;
+
+ for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) {
+ if (nodeMatches(n, DescendantOrSelfAxis, nodeTest()))
+ nodes.append(n);
+ }
+ return;
+
+ case AncestorOrSelfAxis: {
+ if (nodeMatches(context, AncestorOrSelfAxis, nodeTest()))
+ nodes.append(context);
+ Node* n = context;
+ if (context->isAttributeNode()) {
+ n = toAttr(context)->ownerElement();
+ if (nodeMatches(n, AncestorOrSelfAxis, nodeTest()))
+ nodes.append(n);
}
+ for (n = n->parentNode(); n; n = n->parentNode()) {
+ if (nodeMatches(n, AncestorOrSelfAxis, nodeTest()))
+ nodes.append(n);
+ }
+ nodes.markSorted(false);
+ return;
+ }
}
ASSERT_NOT_REACHED();
}
-
}
+
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathStep.h b/chromium/third_party/WebKit/Source/core/xml/XPathStep.h
index b148aae1471..a7105be1310 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathStep.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathStep.h
@@ -38,9 +38,9 @@ namespace XPath {
class Predicate;
-class Step : public ParseNode {
+class Step FINAL : public ParseNode {
WTF_MAKE_NONCOPYABLE(Step);
- WTF_MAKE_FAST_ALLOCATED;
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
enum Axis {
AncestorAxis, AncestorOrSelfAxis, AttributeAxis,
@@ -50,8 +50,8 @@ public:
SelfAxis
};
- class NodeTest {
- WTF_MAKE_FAST_ALLOCATED;
+ class NodeTest : public NoBaseWillBeGarbageCollectedFinalized<NodeTest> {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
enum Kind {
TextNodeTest, CommentNodeTest, ProcessingInstructionNodeTest, AnyNodeTest, NameTest
@@ -76,12 +76,13 @@ public:
ASSERT(o.m_mergedPredicates.isEmpty());
return *this;
}
+ void trace(Visitor* visitor) { visitor->trace(m_mergedPredicates); }
Kind kind() const { return m_kind; }
const AtomicString& data() const { return m_data; }
const AtomicString& namespaceURI() const { return m_namespaceURI; }
- Vector<OwnPtr<Predicate> >& mergedPredicates() { return m_mergedPredicates; }
- const Vector<OwnPtr<Predicate> >& mergedPredicates() const { return m_mergedPredicates; }
+ WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& mergedPredicates() { return m_mergedPredicates; }
+ const WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& mergedPredicates() const { return m_mergedPredicates; }
private:
Kind m_kind;
@@ -89,31 +90,33 @@ public:
AtomicString m_namespaceURI;
// When possible, we merge some or all predicates with node test for better performance.
- Vector<OwnPtr<Predicate> > m_mergedPredicates;
+ WillBeHeapVector<OwnPtrWillBeMember<Predicate> > m_mergedPredicates;
};
Step(Axis, const NodeTest&);
- Step(Axis, const NodeTest&, Vector<OwnPtr<Predicate> >&);
- ~Step();
+ Step(Axis, const NodeTest&, WillBeHeapVector<OwnPtrWillBeMember<Predicate> >&);
+ virtual ~Step();
+ virtual void trace(Visitor*) OVERRIDE;
void optimize();
void evaluate(Node* context, NodeSet&) const;
Axis axis() const { return m_axis; }
- const NodeTest& nodeTest() const { return m_nodeTest; }
+ const NodeTest& nodeTest() const { return *m_nodeTest; }
private:
friend void optimizeStepPair(Step*, Step*, bool&);
bool predicatesAreContextListInsensitive() const;
+ NodeTest& nodeTest() { return *m_nodeTest; }
void parseNodeTest(const String&);
void nodesInAxis(Node* context, NodeSet&) const;
String namespaceFromNodetest(const String& nodeTest) const;
Axis m_axis;
- NodeTest m_nodeTest;
- Vector<OwnPtr<Predicate> > m_predicates;
+ OwnPtrWillBeMember<NodeTest> m_nodeTest;
+ WillBeHeapVector<OwnPtrWillBeMember<Predicate> > m_predicates;
};
void optimizeStepPair(Step*, Step*, bool& dropSecondStep);
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathUtil.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathUtil.cpp
index 5e266fa222d..4c56f284a02 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathUtil.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathUtil.cpp
@@ -42,27 +42,26 @@ bool isRootDomNode(Node* node)
String stringValue(Node* node)
{
switch (node->nodeType()) {
- case Node::ATTRIBUTE_NODE:
- case Node::PROCESSING_INSTRUCTION_NODE:
- case Node::COMMENT_NODE:
- case Node::TEXT_NODE:
- case Node::CDATA_SECTION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- return node->nodeValue();
- default:
- if (isRootDomNode(node) || node->nodeType() == Node::ELEMENT_NODE) {
- StringBuilder result;
- result.reserveCapacity(1024);
+ case Node::ATTRIBUTE_NODE:
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ case Node::COMMENT_NODE:
+ case Node::TEXT_NODE:
+ case Node::CDATA_SECTION_NODE:
+ return node->nodeValue();
+ default:
+ if (isRootDomNode(node) || node->isElementNode()) {
+ StringBuilder result;
+ result.reserveCapacity(1024);
- for (Node* n = node->firstChild(); n; n = NodeTraversal::next(*n, node)) {
- if (n->isTextNode()) {
- const String& nodeValue = n->nodeValue();
- result.append(nodeValue);
- }
+ for (Node* n = node->firstChild(); n; n = NodeTraversal::next(*n, node)) {
+ if (n->isTextNode()) {
+ const String& nodeValue = n->nodeValue();
+ result.append(nodeValue);
}
-
- return result.toString();
}
+
+ return result.toString();
+ }
}
return String();
@@ -73,21 +72,18 @@ bool isValidContextNode(Node* node)
if (!node)
return false;
switch (node->nodeType()) {
- case Node::ATTRIBUTE_NODE:
- case Node::CDATA_SECTION_NODE:
- case Node::COMMENT_NODE:
- case Node::DOCUMENT_NODE:
- case Node::ELEMENT_NODE:
- case Node::PROCESSING_INSTRUCTION_NODE:
- case Node::XPATH_NAMESPACE_NODE:
- return true;
- case Node::DOCUMENT_FRAGMENT_NODE:
- case Node::DOCUMENT_TYPE_NODE:
- case Node::ENTITY_NODE:
- case Node::NOTATION_NODE:
- return false;
- case Node::TEXT_NODE:
- return !(node->parentNode() && node->parentNode()->isAttributeNode());
+ case Node::ATTRIBUTE_NODE:
+ case Node::CDATA_SECTION_NODE:
+ case Node::COMMENT_NODE:
+ case Node::DOCUMENT_NODE:
+ case Node::ELEMENT_NODE:
+ case Node::PROCESSING_INSTRUCTION_NODE:
+ return true;
+ case Node::DOCUMENT_FRAGMENT_NODE:
+ case Node::DOCUMENT_TYPE_NODE:
+ return false;
+ case Node::TEXT_NODE:
+ return !(node->parentNode() && node->parentNode()->isAttributeNode());
}
ASSERT_NOT_REACHED();
return false;
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathUtil.h b/chromium/third_party/WebKit/Source/core/xml/XPathUtil.h
index 9db3314ec9d..aacec1790f4 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathUtil.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathUtil.h
@@ -32,21 +32,20 @@
namespace WebCore {
- class Node;
+class Node;
- namespace XPath {
+namespace XPath {
- /* @return whether the given node is the root node */
- bool isRootDomNode(Node*);
+// @return whether the given node is the root node
+bool isRootDomNode(Node*);
- /* @return the 'string-value' of the given node as specified by http://www.w3.org/TR/xpath */
- String stringValue(Node*);
+// @return the 'string-value' of the given node as specified by http://www.w3.org/TR/xpath
+String stringValue(Node*);
- /* @return whether the given node is a valid context node */
- bool isValidContextNode(Node*);
-
- }
+// @return whether the given node is a valid context node
+bool isValidContextNode(Node*);
}
-#endif // XPath_Util_H
+}
+#endif // XPathUtil_h
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathValue.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathValue.cpp
index 301356cd6ea..751323ef511 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathValue.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathValue.cpp
@@ -27,18 +27,26 @@
#include "config.h"
#include "core/xml/XPathValue.h"
-#include <limits>
#include "core/xml/XPathExpressionNode.h"
#include "core/xml/XPathUtil.h"
#include "wtf/MathExtras.h"
#include "wtf/StdLibExtras.h"
-
-using std::numeric_limits;
+#include <limits>
namespace WebCore {
namespace XPath {
-const Value::AdoptTag Value::adopt = {};
+const Value::AdoptTag Value::adopt = { };
+
+void ValueData::trace(Visitor* visitor)
+{
+ visitor->trace(m_nodeSet);
+}
+
+void Value::trace(Visitor* visitor)
+{
+ visitor->trace(m_data);
+}
const NodeSet& Value::toNodeSet() const
{
@@ -46,11 +54,11 @@ const NodeSet& Value::toNodeSet() const
Expression::evaluationContext().hadTypeConversionError = true;
if (!m_data) {
- DEFINE_STATIC_LOCAL(NodeSet, emptyNodeSet, ());
- return emptyNodeSet;
+ DEFINE_STATIC_LOCAL(OwnPtrWillBePersistent<NodeSet>, emptyNodeSet, (NodeSet::create()));
+ return *emptyNodeSet;
}
- return m_data->m_nodeSet;
+ return m_data->nodeSet();
}
NodeSet& Value::modifiableNodeSet()
@@ -62,20 +70,20 @@ NodeSet& Value::modifiableNodeSet()
m_data = ValueData::create();
m_type = NodeSetValue;
- return m_data->m_nodeSet;
+ return m_data->nodeSet();
}
bool Value::toBoolean() const
{
switch (m_type) {
- case NodeSetValue:
- return !m_data->m_nodeSet.isEmpty();
- case BooleanValue:
- return m_bool;
- case NumberValue:
- return m_number && !std::isnan(m_number);
- case StringValue:
- return !m_data->m_string.isEmpty();
+ case NodeSetValue:
+ return !m_data->nodeSet().isEmpty();
+ case BooleanValue:
+ return m_bool;
+ case NumberValue:
+ return m_number && !std::isnan(m_number);
+ case StringValue:
+ return !m_data->m_string.isEmpty();
}
ASSERT_NOT_REACHED();
return false;
@@ -84,29 +92,30 @@ bool Value::toBoolean() const
double Value::toNumber() const
{
switch (m_type) {
- case NodeSetValue:
- return Value(toString()).toNumber();
- case NumberValue:
- return m_number;
- case StringValue: {
- const String& str = m_data->m_string.simplifyWhiteSpace();
-
- // String::toDouble() supports exponential notation, which is not allowed in XPath.
- unsigned len = str.length();
- for (unsigned i = 0; i < len; ++i) {
- UChar c = str[i];
- if (!isASCIIDigit(c) && c != '.' && c != '-')
- return numeric_limits<double>::quiet_NaN();
- }
-
- bool canConvert;
- double value = str.toDouble(&canConvert);
- if (canConvert)
- return value;
- return numeric_limits<double>::quiet_NaN();
+ case NodeSetValue:
+ return Value(toString()).toNumber();
+ case NumberValue:
+ return m_number;
+ case StringValue: {
+ const String& str = m_data->m_string.simplifyWhiteSpace();
+
+ // String::toDouble() supports exponential notation, which is not
+ // allowed in XPath.
+ unsigned len = str.length();
+ for (unsigned i = 0; i < len; ++i) {
+ UChar c = str[i];
+ if (!isASCIIDigit(c) && c != '.' && c != '-')
+ return std::numeric_limits<double>::quiet_NaN();
}
- case BooleanValue:
- return m_bool;
+
+ bool canConvert;
+ double value = str.toDouble(&canConvert);
+ if (canConvert)
+ return value;
+ return std::numeric_limits<double>::quiet_NaN();
+ }
+ case BooleanValue:
+ return m_bool;
}
ASSERT_NOT_REACHED();
return 0.0;
@@ -115,22 +124,22 @@ double Value::toNumber() const
String Value::toString() const
{
switch (m_type) {
- case NodeSetValue:
- if (m_data->m_nodeSet.isEmpty())
- return "";
- return stringValue(m_data->m_nodeSet.firstNode());
- case StringValue:
- return m_data->m_string;
- case NumberValue:
- if (std::isnan(m_number))
- return "NaN";
- if (m_number == 0)
- return "0";
- if (std::isinf(m_number))
- return std::signbit(m_number) ? "-Infinity" : "Infinity";
- return String::number(m_number);
- case BooleanValue:
- return m_bool ? "true" : "false";
+ case NodeSetValue:
+ if (m_data->nodeSet().isEmpty())
+ return "";
+ return stringValue(m_data->nodeSet().firstNode());
+ case StringValue:
+ return m_data->m_string;
+ case NumberValue:
+ if (std::isnan(m_number))
+ return "NaN";
+ if (m_number == 0)
+ return "0";
+ if (std::isinf(m_number))
+ return std::signbit(m_number) ? "-Infinity" : "Infinity";
+ return String::number(m_number);
+ case BooleanValue:
+ return m_bool ? "true" : "false";
}
ASSERT_NOT_REACHED();
return String();
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathValue.h b/chromium/third_party/WebKit/Source/core/xml/XPathValue.h
index c21a8dc2b4f..a567923801e 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathValue.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathValue.h
@@ -32,71 +32,80 @@
namespace WebCore {
- namespace XPath {
-
- class ValueData : public RefCounted<ValueData> {
- public:
- static PassRefPtr<ValueData> create() { return adoptRef(new ValueData); }
- static PassRefPtr<ValueData> create(const NodeSet& nodeSet) { return adoptRef(new ValueData(nodeSet)); }
- static PassRefPtr<ValueData> create(const String& string) { return adoptRef(new ValueData(string)); }
-
- NodeSet m_nodeSet;
- String m_string;
-
- private:
- ValueData() { }
- explicit ValueData(const NodeSet& nodeSet) : m_nodeSet(nodeSet) { }
- explicit ValueData(const String& string) : m_string(string) { }
- };
-
- // Copying Value objects makes their data partially shared, so care has to be taken when dealing with copies.
- class Value {
- public:
- enum Type { NodeSetValue, BooleanValue, NumberValue, StringValue };
-
- Value(unsigned value) : m_type(NumberValue), m_bool(false), m_number(value) {}
- Value(unsigned long value) : m_type(NumberValue), m_bool(false), m_number(value) {}
- Value(double value) : m_type(NumberValue), m_bool(false), m_number(value) {}
-
- Value(const char* value) : m_type(StringValue), m_bool(false), m_number(0), m_data(ValueData::create(value)) {}
- Value(const String& value) : m_type(StringValue), m_bool(false), m_number(0), m_data(ValueData::create(value)) {}
- Value(const NodeSet& value) : m_type(NodeSetValue), m_bool(false), m_number(0), m_data(ValueData::create(value)) {}
- Value(Node* value) : m_type(NodeSetValue), m_bool(false), m_number(0), m_data(ValueData::create()) { m_data->m_nodeSet.append(value); }
-
- // This is needed to safely implement constructing from bool - with normal function overloading, any pointer type would match.
- template<typename T> Value(T);
-
- static const struct AdoptTag {} adopt;
- Value(NodeSet& value, const AdoptTag&) : m_type(NodeSetValue), m_bool(false), m_number(0), m_data(ValueData::create()) { value.swap(m_data->m_nodeSet); }
-
- Type type() const { return m_type; }
-
- bool isNodeSet() const { return m_type == NodeSetValue; }
- bool isBoolean() const { return m_type == BooleanValue; }
- bool isNumber() const { return m_type == NumberValue; }
- bool isString() const { return m_type == StringValue; }
-
- const NodeSet& toNodeSet() const;
- NodeSet& modifiableNodeSet();
- bool toBoolean() const;
- double toNumber() const;
- String toString() const;
-
- private:
- Type m_type;
- bool m_bool;
- double m_number;
- RefPtr<ValueData> m_data;
- };
-
- template<>
- inline Value::Value(bool value)
- : m_type(BooleanValue)
- , m_bool(value)
- , m_number(0)
- {
- }
- }
+namespace XPath {
+
+class ValueData : public RefCountedWillBeGarbageCollectedFinalized<ValueData> {
+public:
+ static PassRefPtrWillBeRawPtr<ValueData> create() { return adoptRefWillBeNoop(new ValueData); }
+ static PassRefPtrWillBeRawPtr<ValueData> create(const NodeSet& nodeSet) { return adoptRefWillBeNoop(new ValueData(nodeSet)); }
+ static PassRefPtrWillBeRawPtr<ValueData> create(PassOwnPtrWillBeRawPtr<NodeSet> nodeSet) { return adoptRefWillBeNoop(new ValueData(nodeSet)); }
+ static PassRefPtrWillBeRawPtr<ValueData> create(const String& string) { return adoptRefWillBeNoop(new ValueData(string)); }
+ void trace(Visitor*);
+ NodeSet& nodeSet() { return *m_nodeSet; }
+
+ String m_string;
+
+private:
+ ValueData() : m_nodeSet(NodeSet::create()) { }
+ explicit ValueData(const NodeSet& nodeSet) : m_nodeSet(NodeSet::create(nodeSet)) { }
+ explicit ValueData(PassOwnPtrWillBeRawPtr<NodeSet> nodeSet) : m_nodeSet(nodeSet) { }
+ explicit ValueData(const String& string) : m_string(string), m_nodeSet(NodeSet::create()) { }
+
+ OwnPtrWillBeMember<NodeSet> m_nodeSet;
+};
+
+// Copying Value objects makes their data partially shared, so care has to be taken when dealing with copies.
+class Value {
+ DISALLOW_ALLOCATION();
+public:
+ enum Type { NodeSetValue, BooleanValue, NumberValue, StringValue };
+
+ Value(unsigned value) : m_type(NumberValue), m_bool(false), m_number(value) { }
+ Value(unsigned long value) : m_type(NumberValue), m_bool(false), m_number(value) { }
+ Value(double value) : m_type(NumberValue), m_bool(false), m_number(value) { }
+
+ Value(const char* value) : m_type(StringValue), m_bool(false), m_number(0), m_data(ValueData::create(value)) { }
+ Value(const String& value) : m_type(StringValue), m_bool(false), m_number(0), m_data(ValueData::create(value)) { }
+ Value(const NodeSet& value) : m_type(NodeSetValue), m_bool(false), m_number(0), m_data(ValueData::create(value)) { }
+ Value(Node* value) : m_type(NodeSetValue), m_bool(false), m_number(0), m_data(ValueData::create()) { m_data->nodeSet().append(value); }
+ void trace(Visitor*);
+
+ // This is needed to safely implement constructing from bool - with normal
+ // function overloading, any pointer type would match.
+ template<typename T> Value(T);
+
+ static const struct AdoptTag { } adopt;
+ Value(PassOwnPtrWillBeRawPtr<NodeSet> value, const AdoptTag&) : m_type(NodeSetValue), m_bool(false), m_number(0), m_data(ValueData::create(value)) { }
+
+ Type type() const { return m_type; }
+
+ bool isNodeSet() const { return m_type == NodeSetValue; }
+ bool isBoolean() const { return m_type == BooleanValue; }
+ bool isNumber() const { return m_type == NumberValue; }
+ bool isString() const { return m_type == StringValue; }
+
+ const NodeSet& toNodeSet() const;
+ NodeSet& modifiableNodeSet();
+ bool toBoolean() const;
+ double toNumber() const;
+ String toString() const;
+
+private:
+ Type m_type;
+ bool m_bool;
+ double m_number;
+ RefPtrWillBeMember<ValueData> m_data;
+};
+
+template<>
+inline Value::Value(bool value)
+ : m_type(BooleanValue)
+ , m_bool(value)
+ , m_number(0)
+{
}
-#endif // XPath_Value_H
+}
+
+}
+#endif // XPathValue_h
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.cpp b/chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.cpp
index 9d3ca1e145e..8eb35c7be26 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.cpp
@@ -40,9 +40,11 @@ VariableReference::VariableReference(const String& name)
Value VariableReference::evaluate() const
{
HashMap<String, String>& bindings = evaluationContext().variableBindings;
- if (!bindings.contains(m_name))
- // FIXME: Is this the right thing to do if an unknown variable is referenced?
+ if (!bindings.contains(m_name)) {
+ // FIXME: Is this the right thing to do if an unknown variable is
+ // referenced?
return "";
+ }
return bindings.get(m_name);
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.h b/chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.h
index e494a467215..d0345744a61 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XPathVariableReference.h
@@ -30,19 +30,21 @@
namespace WebCore {
- namespace XPath {
-
- // Variable references are not used with XPathEvaluator.
- class VariableReference : public Expression {
- public:
- explicit VariableReference(const String& name);
- private:
- virtual Value evaluate() const;
- virtual Value::Type resultType() const { ASSERT_NOT_REACHED(); return Value::NumberValue; }
- String m_name;
- };
-
- }
+namespace XPath {
+
+// Variable references are not used with XPathEvaluator.
+class VariableReference FINAL : public Expression {
+public:
+ explicit VariableReference(const String& name);
+
+private:
+ virtual Value evaluate() const OVERRIDE;
+ virtual Value::Type resultType() const OVERRIDE { ASSERT_NOT_REACHED(); return Value::NumberValue; }
+
+ String m_name;
+};
+
}
-#endif // XPath_VariableReference_H
+}
+#endif // XPathVariableReference_h
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLImportRule.cpp b/chromium/third_party/WebKit/Source/core/xml/XSLImportRule.cpp
index 48b1e4b81ab..f66654aabb4 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLImportRule.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLImportRule.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "core/xml/XSLImportRule.h"
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/Document.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/ResourceFetcher.h"
@@ -40,8 +40,10 @@ XSLImportRule::XSLImportRule(XSLStyleSheet* parent, const String& href)
XSLImportRule::~XSLImportRule()
{
+#if !ENABLE(OILPAN)
if (m_styleSheet)
m_styleSheet->setParentStyleSheet(0);
+#endif
if (m_resource)
m_resource->removeClient(this);
@@ -67,13 +69,12 @@ void XSLImportRule::setXSLStyleSheet(const String& href, const KURL& baseURL, co
bool XSLImportRule::isLoading()
{
- return (m_loading || (m_styleSheet && m_styleSheet->isLoading()));
+ return m_loading || (m_styleSheet && m_styleSheet->isLoading());
}
void XSLImportRule::loadSheet()
{
ResourceFetcher* fetcher = 0;
-
XSLStyleSheet* rootSheet = parentStyleSheet();
if (rootSheet) {
@@ -86,12 +87,13 @@ void XSLImportRule::loadSheet()
String absHref = m_strHref;
XSLStyleSheet* parentSheet = parentStyleSheet();
- if (!parentSheet->baseURL().isNull())
- // use parent styleheet's URL as the base URL
+ if (!parentSheet->baseURL().isNull()) {
+ // Use parent styleheet's URL as the base URL
absHref = KURL(parentSheet->baseURL(), m_strHref).string();
+ }
- // Check for a cycle in our import chain. If we encounter a stylesheet
- // in our parent chain with the same URL, then just bail.
+ // Check for a cycle in our import chain. If we encounter a stylesheet in
+ // our parent chain with the same URL, then just bail.
for (XSLStyleSheet* parentSheet = parentStyleSheet(); parentSheet; parentSheet = parentSheet->parentStyleSheet()) {
if (absHref == parentSheet->baseURL().string())
return;
@@ -103,13 +105,19 @@ void XSLImportRule::loadSheet()
if (m_resource) {
m_resource->addClient(this);
- // If the imported sheet is in the cache, then setXSLStyleSheet gets called,
- // and the sheet even gets parsed (via parseString). In this case we have
- // loaded (even if our subresources haven't), so if we have a stylesheet after
- // checking the cache, then we've clearly loaded.
+ // If the imported sheet is in the cache, then setXSLStyleSheet gets
+ // called, and the sheet even gets parsed (via parseString). In this
+ // case we have loaded (even if our subresources haven't), so if we have
+ // a stylesheet after checking the cache, then we've clearly loaded.
if (!m_styleSheet)
m_loading = true;
}
}
+void XSLImportRule::trace(Visitor* visitor)
+{
+ visitor->trace(m_parentStyleSheet);
+ visitor->trace(m_styleSheet);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLImportRule.h b/chromium/third_party/WebKit/Source/core/xml/XSLImportRule.h
index 954e046c840..ff802e05085 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLImportRule.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLImportRule.h
@@ -23,26 +23,27 @@
#ifndef XSLImportRule_h
#define XSLImportRule_h
-#include "RuntimeEnabledFeatures.h"
#include "core/fetch/ResourcePtr.h"
#include "core/fetch/StyleSheetResourceClient.h"
#include "core/xml/XSLStyleSheet.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/PassOwnPtr.h"
namespace WebCore {
class XSLStyleSheetResource;
-class XSLImportRule : private StyleSheetResourceClient {
- WTF_MAKE_FAST_ALLOCATED;
+class XSLImportRule FINAL : public NoBaseWillBeGarbageCollectedFinalized<XSLImportRule>, private StyleSheetResourceClient {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
public:
- static PassOwnPtr<XSLImportRule> create(XSLStyleSheet* parentSheet, const String& href)
+ static PassOwnPtrWillBeRawPtr<XSLImportRule> create(XSLStyleSheet* parentSheet, const String& href)
{
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
- return adoptPtr(new XSLImportRule(parentSheet, href));
+ return adoptPtrWillBeNoop(new XSLImportRule(parentSheet, href));
}
virtual ~XSLImportRule();
+ virtual void trace(Visitor*);
const String& href() const { return m_strHref; }
XSLStyleSheet* styleSheet() const { return m_styleSheet.get(); }
@@ -56,11 +57,11 @@ public:
private:
XSLImportRule(XSLStyleSheet* parentSheet, const String& href);
- virtual void setXSLStyleSheet(const String& href, const KURL& baseURL, const String& sheet);
+ virtual void setXSLStyleSheet(const String& href, const KURL& baseURL, const String& sheet) OVERRIDE;
- XSLStyleSheet* m_parentStyleSheet;
+ RawPtrWillBeMember<XSLStyleSheet> m_parentStyleSheet;
String m_strHref;
- RefPtr<XSLStyleSheet> m_styleSheet;
+ RefPtrWillBeMember<XSLStyleSheet> m_styleSheet;
ResourcePtr<XSLStyleSheetResource> m_resource;
bool m_loading;
};
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLStyleSheet.h b/chromium/third_party/WebKit/Source/core/xml/XSLStyleSheet.h
index 17f99842250..d53e5327603 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLStyleSheet.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLStyleSheet.h
@@ -23,11 +23,10 @@
#ifndef XSLStyleSheet_h
#define XSLStyleSheet_h
-#include "RuntimeEnabledFeatures.h"
#include "core/css/StyleSheet.h"
#include "core/dom/ProcessingInstruction.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/PassRefPtr.h"
-
#include <libxml/tree.h>
#include <libxslt/transform.h>
@@ -36,30 +35,31 @@ namespace WebCore {
class ResourceFetcher;
class XSLImportRule;
-class XSLStyleSheet : public StyleSheet {
+class XSLStyleSheet FINAL : public StyleSheet {
public:
- static PassRefPtr<XSLStyleSheet> create(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL)
+ static PassRefPtrWillBeRawPtr<XSLStyleSheet> create(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL)
{
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
- return adoptRef(new XSLStyleSheet(parentImport, originalURL, finalURL));
+ return adoptRefWillBeNoop(new XSLStyleSheet(parentImport, originalURL, finalURL));
}
- static PassRefPtr<XSLStyleSheet> create(ProcessingInstruction* parentNode, const String& originalURL, const KURL& finalURL)
+ static PassRefPtrWillBeRawPtr<XSLStyleSheet> create(ProcessingInstruction* parentNode, const String& originalURL, const KURL& finalURL)
{
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
- return adoptRef(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
+ return adoptRefWillBeNoop(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
}
- static PassRefPtr<XSLStyleSheet> createEmbedded(ProcessingInstruction* parentNode, const KURL& finalURL)
+ static PassRefPtrWillBeRawPtr<XSLStyleSheet> createEmbedded(ProcessingInstruction* parentNode, const KURL& finalURL)
{
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
- return adoptRef(new XSLStyleSheet(parentNode, finalURL.string(), finalURL, true));
+ return adoptRefWillBeNoop(new XSLStyleSheet(parentNode, finalURL.string(), finalURL, true));
}
- // Taking an arbitrary node is unsafe, because owner node pointer can become stale.
- // XSLTProcessor ensures that the stylesheet doesn't outlive its parent, in part by not exposing it to JavaScript.
- static PassRefPtr<XSLStyleSheet> createForXSLTProcessor(Node* parentNode, const String& originalURL, const KURL& finalURL)
+ // Taking an arbitrary node is unsafe, because owner node pointer can become
+ // stale. XSLTProcessor ensures that the stylesheet doesn't outlive its
+ // parent, in part by not exposing it to JavaScript.
+ static PassRefPtrWillBeRawPtr<XSLStyleSheet> createForXSLTProcessor(Node* parentNode, const String& originalURL, const KURL& finalURL)
{
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
- return adoptRef(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
+ return adoptRefWillBeNoop(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
}
virtual ~XSLStyleSheet();
@@ -77,7 +77,7 @@ public:
Document* ownerDocument();
virtual XSLStyleSheet* parentStyleSheet() const OVERRIDE { return m_parentStyleSheet; }
- void setParentStyleSheet(XSLStyleSheet* parent);
+ void setParentStyleSheet(XSLStyleSheet*);
xmlDocPtr document();
xsltStylesheetPtr compileStyleSheet();
@@ -95,20 +95,22 @@ public:
virtual String href() const OVERRIDE { return m_originalURL; }
virtual String title() const OVERRIDE { return emptyString(); }
- virtual void clearOwnerNode() OVERRIDE { m_ownerNode = 0; }
+ virtual void clearOwnerNode() OVERRIDE { m_ownerNode = nullptr; }
virtual KURL baseURL() const OVERRIDE { return m_finalURL; }
virtual bool isLoading() const OVERRIDE;
+ virtual void trace(Visitor*) OVERRIDE;
+
private:
XSLStyleSheet(Node* parentNode, const String& originalURL, const KURL& finalURL, bool embedded);
XSLStyleSheet(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL);
- Node* m_ownerNode;
+ RawPtrWillBeMember<Node> m_ownerNode;
String m_originalURL;
KURL m_finalURL;
bool m_isDisabled;
- Vector<OwnPtr<XSLImportRule> > m_children;
+ WillBeHeapVector<OwnPtrWillBeMember<XSLImportRule> > m_children;
bool m_embedded;
bool m_processed;
@@ -117,7 +119,7 @@ private:
bool m_stylesheetDocTaken;
bool m_compilationFailed;
- XSLStyleSheet* m_parentStyleSheet;
+ RawPtrWillBeMember<XSLStyleSheet> m_parentStyleSheet;
};
DEFINE_TYPE_CASTS(XSLStyleSheet, StyleSheet, sheet, !sheet->isCSSStyleSheet(), !sheet.isCSSStyleSheet());
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp b/chromium/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp
index 398afdd1f8d..3f19c86738f 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLStyleSheetLibxslt.cpp
@@ -25,26 +25,27 @@
#include "core/dom/Document.h"
#include "core/dom/Node.h"
#include "core/dom/TransformSource.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/xml/XSLImportRule.h"
#include "core/xml/XSLTProcessor.h"
#include "core/xml/parser/XMLDocumentParserScope.h"
#include "core/xml/parser/XMLParserInput.h"
#include "wtf/text/CString.h"
-
#include <libxml/uri.h>
#include <libxslt/xsltutils.h>
namespace WebCore {
XSLStyleSheet::XSLStyleSheet(XSLImportRule* parentRule, const String& originalURL, const KURL& finalURL)
- : m_ownerNode(0)
+ : m_ownerNode(nullptr)
, m_originalURL(originalURL)
, m_finalURL(finalURL)
, m_isDisabled(false)
, m_embedded(false)
- , m_processed(false) // Child sheets get marked as processed when the libxslt engine has finally seen them.
+ // Child sheets get marked as processed when the libxslt engine has finally
+ // seen them.
+ , m_processed(false)
, m_stylesheetDoc(0)
, m_stylesheetDocTaken(false)
, m_compilationFailed(false)
@@ -62,7 +63,7 @@ XSLStyleSheet::XSLStyleSheet(Node* parentNode, const String& originalURL, const
, m_stylesheetDoc(0)
, m_stylesheetDocTaken(false)
, m_compilationFailed(false)
- , m_parentStyleSheet(0)
+ , m_parentStyleSheet(nullptr)
{
}
@@ -70,11 +71,12 @@ XSLStyleSheet::~XSLStyleSheet()
{
if (!m_stylesheetDocTaken)
xmlFreeDoc(m_stylesheetDoc);
-
+#if !ENABLE(OILPAN)
for (unsigned i = 0; i < m_children.size(); ++i) {
ASSERT(m_children.at(i)->parentStyleSheet() == this);
m_children.at(i)->setParentStyleSheet(0);
}
+#endif
}
bool XSLStyleSheet::isLoading() const
@@ -115,10 +117,9 @@ void XSLStyleSheet::clearDocuments()
ResourceFetcher* XSLStyleSheet::fetcher()
{
- Document* document = ownerDocument();
- if (!document)
- return 0;
- return document->fetcher();
+ if (Document* document = ownerDocument())
+ return document->fetcher();
+ return 0;
}
bool XSLStyleSheet::parseString(const String& source)
@@ -128,10 +129,9 @@ bool XSLStyleSheet::parseString(const String& source)
xmlFreeDoc(m_stylesheetDoc);
m_stylesheetDocTaken = false;
- PageConsole* console = 0;
- Frame* frame = ownerDocument()->frame();
- if (frame && frame->page())
- console = &frame->page()->console();
+ FrameConsole* console = 0;
+ if (LocalFrame* frame = ownerDocument()->frame())
+ console = &frame->console();
XMLDocumentParserScope scope(fetcher(), XSLTProcessor::genericErrorFunc, XSLTProcessor::parseErrorFunc, console);
XMLParserInput input(source);
@@ -168,25 +168,26 @@ void XSLStyleSheet::loadChildSheets()
xmlNodePtr stylesheetRoot = document()->children;
- // Top level children may include other things such as DTD nodes, we ignore those.
+ // Top level children may include other things such as DTD nodes, we ignore
+ // those.
while (stylesheetRoot && stylesheetRoot->type != XML_ELEMENT_NODE)
stylesheetRoot = stylesheetRoot->next;
if (m_embedded) {
- // We have to locate (by ID) the appropriate embedded stylesheet element, so that we can walk the
- // import/include list.
+ // We have to locate (by ID) the appropriate embedded stylesheet
+ // element, so that we can walk the import/include list.
xmlAttrPtr idNode = xmlGetID(document(), (const xmlChar*)(finalURL().string().utf8().data()));
if (!idNode)
return;
stylesheetRoot = idNode->parent;
} else {
- // FIXME: Need to handle an external URI with a # in it. This is a pretty minor edge case, so we'll deal
- // with it later.
+ // FIXME: Need to handle an external URI with a # in it. This is a
+ // pretty minor edge case, so we'll deal with it later.
}
if (stylesheetRoot) {
- // Walk the children of the root element and look for import/include elements.
- // Imports must occur first.
+ // Walk the children of the root element and look for import/include
+ // elements. Imports must occur first.
xmlNodePtr curr = stylesheetRoot->children;
while (curr) {
if (curr->type != XML_ELEMENT_NODE) {
@@ -197,8 +198,9 @@ void XSLStyleSheet::loadChildSheets()
xmlChar* uriRef = xsltGetNsProp(curr, (const xmlChar*)"href", XSLT_NAMESPACE);
loadChildSheet(String::fromUTF8((const char*)uriRef));
xmlFree(uriRef);
- } else
+ } else {
break;
+ }
curr = curr->next;
}
@@ -216,7 +218,7 @@ void XSLStyleSheet::loadChildSheets()
void XSLStyleSheet::loadChildSheet(const String& href)
{
- OwnPtr<XSLImportRule> childRule = XSLImportRule::create(this, href);
+ OwnPtrWillBeRawPtr<XSLImportRule> childRule = XSLImportRule::create(this, href);
XSLImportRule* c = childRule.get();
m_children.append(childRule.release());
c->loadSheet();
@@ -228,8 +230,8 @@ xsltStylesheetPtr XSLStyleSheet::compileStyleSheet()
if (m_embedded)
return xsltLoadStylesheetPI(document());
- // Certain libxslt versions are corrupting the xmlDoc on compilation failures -
- // hence attempting to recompile after a failure is unsafe.
+ // Certain libxslt versions are corrupting the xmlDoc on compilation
+ // failures - hence attempting to recompile after a failure is unsafe.
if (m_compilationFailed)
return 0;
@@ -272,9 +274,9 @@ xmlDocPtr XSLStyleSheet::locateStylesheetSubResource(xmlDocPtr parentDoc, const
continue; // libxslt has been given this sheet already.
// Check the URI of the child stylesheet against the doc URI.
- // In order to ensure that libxml canonicalized both URLs, we get the original href
- // string from the import rule and canonicalize it using libxml before comparing it
- // with the URI argument.
+ // In order to ensure that libxml canonicalized both URLs, we get
+ // the original href string from the import rule and canonicalize it
+ // using libxml before comparing it with the URI argument.
CString importHref = import->href().utf8();
xmlChar* base = xmlNodeGetBase(parentDoc, (xmlNodePtr)parentDoc);
xmlChar* childURI = xmlBuildURI((const xmlChar*)importHref.data(), base);
@@ -303,4 +305,12 @@ void XSLStyleSheet::markAsProcessed()
m_stylesheetDocTaken = true;
}
+void XSLStyleSheet::trace(Visitor* visitor)
+{
+ visitor->trace(m_ownerNode);
+ visitor->trace(m_children);
+ visitor->trace(m_parentStyleSheet);
+ StyleSheet::trace(visitor);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLTExtensions.cpp b/chromium/third_party/WebKit/Source/core/xml/XSLTExtensions.cpp
index 064d609955b..758568c01e0 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLTExtensions.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLTExtensions.cpp
@@ -25,23 +25,22 @@
*/
#include "config.h"
-
#include "core/xml/XSLTExtensions.h"
-#include "RuntimeEnabledFeatures.h"
-#include "wtf/Assertions.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "wtf/Assertions.h"
#include <libxml/xpathInternals.h>
-
#include <libxslt/extensions.h>
#include <libxslt/extra.h>
#include <libxslt/xsltutils.h>
namespace WebCore {
-// FIXME: This code is taken from libexslt 1.1.11; should sync with newer versions.
+// FIXME: This code is taken from libexslt 1.1.11; should sync with newer
+// versions.
static void exsltNodeSetFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
- xmlChar *strval;
+ xmlChar* strval;
xmlNodePtr retNode;
xmlXPathObjectPtr ret;
@@ -56,15 +55,15 @@ static void exsltNodeSetFunction(xmlXPathParserContextPtr ctxt, int nargs)
}
strval = xmlXPathPopString(ctxt);
- retNode = xmlNewDocText(NULL, strval);
+ retNode = xmlNewDocText(0, strval);
ret = xmlXPathNewValueTree(retNode);
// FIXME: It might be helpful to push any errors from xmlXPathNewValueTree
// up to the Javascript Console.
- if (ret != NULL)
+ if (ret)
ret->type = XPATH_NODESET;
- if (strval != NULL)
+ if (strval)
xmlFree(strval);
valuePush(ctxt, ret);
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp b/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp
index 61ca31b723e..020c2680a97 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.cpp
@@ -27,10 +27,10 @@
#include "core/dom/DocumentEncodingData.h"
#include "core/dom/DocumentFragment.h"
#include "core/editing/markup.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalDOMWindow.h"
#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "wtf/Assertions.h"
#include "wtf/Vector.h"
@@ -54,18 +54,20 @@ static inline void transformTextStringToXHTMLDocumentString(String& text)
XSLTProcessor::~XSLTProcessor()
{
+#if !ENABLE(OILPAN)
// Stylesheet shouldn't outlive its root node.
ASSERT(!m_stylesheetRootNode || !m_stylesheet || m_stylesheet->hasOneRef());
+#endif
}
-PassRefPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourceString,
- const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame)
+PassRefPtrWillBeRawPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourceString,
+ const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, LocalFrame* frame)
{
- RefPtr<Document> ownerDocument(sourceNode->document());
+ RefPtrWillBeRawPtr<Document> ownerDocument(sourceNode->document());
bool sourceIsDocument = (sourceNode == ownerDocument.get());
String documentSource = sourceString;
- RefPtr<Document> result;
+ RefPtrWillBeRawPtr<Document> result = nullptr;
DocumentInit init(sourceIsDocument ? ownerDocument->url() : KURL(), frame);
bool forceXHTML = sourceMIMEType == "text/plain";
@@ -73,7 +75,7 @@ PassRefPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourc
transformTextStringToXHTMLDocumentString(documentSource);
if (frame) {
- RefPtr<Document> oldDocument = frame->document();
+ RefPtrWillBeRawPtr<Document> oldDocument = frame->document();
result = frame->domWindow()->installNewDocument(sourceMIMEType, init, forceXHTML);
// Before parsing, we need to save & detach the old document and get the new document
@@ -88,34 +90,34 @@ PassRefPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourc
result->contentSecurityPolicy()->copyStateFrom(oldDocument->contentSecurityPolicy());
}
} else {
- result = DOMWindow::createDocument(sourceMIMEType, init, forceXHTML);
+ result = LocalDOMWindow::createDocument(sourceMIMEType, init, forceXHTML);
}
DocumentEncodingData data;
- data.encoding = sourceEncoding.isEmpty() ? UTF8Encoding() : WTF::TextEncoding(sourceEncoding);
+ data.setEncoding(sourceEncoding.isEmpty() ? UTF8Encoding() : WTF::TextEncoding(sourceEncoding));
result->setEncodingData(data);
result->setContent(documentSource);
return result.release();
}
-PassRefPtr<Document> XSLTProcessor::transformToDocument(Node* sourceNode)
+PassRefPtrWillBeRawPtr<Document> XSLTProcessor::transformToDocument(Node* sourceNode)
{
if (!sourceNode)
- return 0;
+ return nullptr;
String resultMIMEType;
String resultString;
String resultEncoding;
if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
- return 0;
+ return nullptr;
return createDocumentFromSource(resultString, resultEncoding, resultMIMEType, sourceNode, 0);
}
-PassRefPtr<DocumentFragment> XSLTProcessor::transformToFragment(Node* sourceNode, Document* outputDoc)
+PassRefPtrWillBeRawPtr<DocumentFragment> XSLTProcessor::transformToFragment(Node* sourceNode, Document* outputDoc)
{
if (!sourceNode || !outputDoc)
- return 0;
+ return nullptr;
String resultMIMEType;
String resultString;
@@ -126,7 +128,7 @@ PassRefPtr<DocumentFragment> XSLTProcessor::transformToFragment(Node* sourceNode
resultMIMEType = "text/html";
if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
- return 0;
+ return nullptr;
return createFragmentForTransformToFragment(resultString, resultMIMEType, *outputDoc);
}
@@ -157,4 +159,10 @@ void XSLTProcessor::reset()
m_parameters.clear();
}
+void XSLTProcessor::trace(Visitor* visitor)
+{
+ visitor->trace(m_stylesheet);
+ visitor->trace(m_stylesheetRootNode);
+}
+
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.h b/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.h
index 23272c2247f..402ef07a917 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.h
@@ -23,10 +23,10 @@
#ifndef XSLTProcessor_h
#define XSLTProcessor_h
-#include "RuntimeEnabledFeatures.h"
#include "bindings/v8/ScriptWrappable.h"
#include "core/dom/Node.h"
#include "core/xml/XSLStyleSheet.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/HashMap.h"
#include "wtf/text/StringHash.h"
@@ -35,31 +35,31 @@
namespace WebCore {
-class Frame;
+class LocalFrame;
class Document;
class DocumentFragment;
-class XSLTProcessor : public RefCounted<XSLTProcessor>, public ScriptWrappable {
+class XSLTProcessor : public RefCountedWillBeGarbageCollectedFinalized<XSLTProcessor>, public ScriptWrappable {
public:
- static PassRefPtr<XSLTProcessor> create()
+ static PassRefPtrWillBeRawPtr<XSLTProcessor> create()
{
ASSERT(RuntimeEnabledFeatures::xsltEnabled());
- return adoptRef(new XSLTProcessor);
+ return adoptRefWillBeNoop(new XSLTProcessor);
}
~XSLTProcessor();
- void setXSLStyleSheet(PassRefPtr<XSLStyleSheet> styleSheet) { m_stylesheet = styleSheet; }
+ void setXSLStyleSheet(PassRefPtrWillBeRawPtr<XSLStyleSheet> styleSheet) { m_stylesheet = styleSheet; }
bool transformToString(Node* source, String& resultMIMEType, String& resultString, String& resultEncoding);
- PassRefPtr<Document> createDocumentFromSource(const String& source, const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame);
+ PassRefPtrWillBeRawPtr<Document> createDocumentFromSource(const String& source, const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, LocalFrame*);
// DOM methods
- void importStylesheet(PassRefPtr<Node> style)
+ void importStylesheet(PassRefPtrWillBeRawPtr<Node> style)
{
if (style)
m_stylesheetRootNode = style;
}
- PassRefPtr<DocumentFragment> transformToFragment(Node* source, Document* ouputDoc);
- PassRefPtr<Document> transformToDocument(Node* source);
+ PassRefPtrWillBeRawPtr<DocumentFragment> transformToFragment(Node* source, Document* ouputDoc);
+ PassRefPtrWillBeRawPtr<Document> transformToDocument(Node* source);
void setParameter(const String& namespaceURI, const String& localName, const String& value);
String getParameter(const String& namespaceURI, const String& localName) const;
@@ -76,14 +76,16 @@ public:
typedef HashMap<String, String> ParameterMap;
+ void trace(Visitor*);
+
private:
XSLTProcessor()
{
ScriptWrappable::init(this);
}
- RefPtr<XSLStyleSheet> m_stylesheet;
- RefPtr<Node> m_stylesheetRootNode;
+ RefPtrWillBeMember<XSLStyleSheet> m_stylesheet;
+ RefPtrWillBeMember<Node> m_stylesheetRootNode;
ParameterMap m_parameters;
};
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.idl b/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.idl
index 7c9986889af..dc51a606a38 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.idl
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLTProcessor.idl
@@ -31,6 +31,7 @@
// http://bugs.webkit.org/show_bug.cgi?id=5446
[
+ WillBeGarbageCollected,
Constructor,
RuntimeEnabled=XSLT,
MeasureAs=XSLTProcessor
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp b/chromium/third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp
index 18f571dc15a..05f1ed17660 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp
@@ -23,19 +23,15 @@
#include "config.h"
#include "core/xml/XSLTProcessor.h"
-#include <libxslt/imports.h>
-#include <libxslt/security.h>
-#include <libxslt/variables.h>
-#include <libxslt/xsltutils.h>
-#include "FetchInitiatorTypeNames.h"
+#include "core/FetchInitiatorTypeNames.h"
#include "core/dom/Document.h"
#include "core/dom/TransformSource.h"
#include "core/editing/markup.h"
#include "core/fetch/Resource.h"
#include "core/fetch/ResourceFetcher.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/PageConsole.h"
+#include "core/frame/FrameConsole.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
#include "core/xml/XSLStyleSheet.h"
#include "core/xml/XSLTExtensions.h"
#include "core/xml/XSLTUnicodeSort.h"
@@ -50,6 +46,10 @@
#include "wtf/text/CString.h"
#include "wtf/text/StringBuffer.h"
#include "wtf/unicode/UTF8.h"
+#include <libxslt/imports.h>
+#include <libxslt/security.h>
+#include <libxslt/variables.h>
+#include <libxslt/xsltutils.h>
namespace WebCore {
@@ -60,7 +60,7 @@ void XSLTProcessor::genericErrorFunc(void*, const char*, ...)
void XSLTProcessor::parseErrorFunc(void* userData, xmlError* error)
{
- PageConsole* console = static_cast<PageConsole*>(userData);
+ FrameConsole* console = static_cast<FrameConsole*>(userData);
if (!console)
return;
@@ -85,11 +85,9 @@ void XSLTProcessor::parseErrorFunc(void* userData, xmlError* error)
// FIXME: There seems to be no way to control the ctxt pointer for loading here, thus we have globals.
static XSLTProcessor* globalProcessor = 0;
static ResourceFetcher* globalResourceFetcher = 0;
-static xmlDocPtr docLoaderFunc(const xmlChar* uri,
- xmlDictPtr,
- int options,
- void* ctxt,
- xsltLoadType type)
+
+static xmlDocPtr docLoaderFunc(
+ const xmlChar* uri, xmlDictPtr, int options, void* ctxt, xsltLoadType type)
{
if (!globalProcessor)
return 0;
@@ -108,10 +106,10 @@ static xmlDocPtr docLoaderFunc(const xmlChar* uri,
if (!resource || !globalProcessor)
return 0;
- PageConsole* console = 0;
- Frame* frame = globalProcessor->xslStylesheet()->ownerDocument()->frame();
- if (frame && frame->page())
- console = &frame->page()->console();
+ FrameConsole* console = 0;
+ LocalFrame* frame = globalProcessor->xslStylesheet()->ownerDocument()->frame();
+ if (frame)
+ console = &frame->console();
xmlSetStructuredErrorFunc(console, XSLTProcessor::parseErrorFunc);
xmlSetGenericErrorFunc(console, XSLTProcessor::genericErrorFunc);
@@ -179,7 +177,8 @@ static bool saveResultToString(xmlDocPtr resultDoc, xsltStylesheetPtr sheet, Str
if (retval < 0)
return false;
- // Workaround for <http://bugzilla.gnome.org/show_bug.cgi?id=495668>: libxslt appends an extra line feed to the result.
+ // Workaround for <http://bugzilla.gnome.org/show_bug.cgi?id=495668>:
+ // libxslt appends an extra line feed to the result.
if (resultBuilder.length() > 0 && resultBuilder[resultBuilder.length() - 1] == '\n')
resultBuilder.resize(resultBuilder.length() - 1);
@@ -193,7 +192,7 @@ static const char** xsltParamArrayFromParameterMap(XSLTProcessor::ParameterMap&
if (parameters.isEmpty())
return 0;
- const char** parameterArray = (const char**)fastMalloc(((parameters.size() * 2) + 1) * sizeof(char*));
+ const char** parameterArray = static_cast<const char**>(fastMalloc(((parameters.size() * 2) + 1) * sizeof(char*)));
XSLTProcessor::ParameterMap::iterator end = parameters.end();
unsigned index = 0;
@@ -213,21 +212,23 @@ static void freeXsltParamArray(const char** params)
return;
while (*temp) {
- fastFree((void*)*(temp++));
- fastFree((void*)*(temp++));
+ fastFree(const_cast<char*>(*(temp++)));
+ fastFree(const_cast<char*>(*(temp++)));
}
fastFree(params);
}
-static xsltStylesheetPtr xsltStylesheetPointer(RefPtr<XSLStyleSheet>& cachedStylesheet, Node* stylesheetRootNode)
+static xsltStylesheetPtr xsltStylesheetPointer(RefPtrWillBeMember<XSLStyleSheet>& cachedStylesheet, Node* stylesheetRootNode)
{
if (!cachedStylesheet && stylesheetRootNode) {
- cachedStylesheet = XSLStyleSheet::createForXSLTProcessor(stylesheetRootNode->parentNode() ? stylesheetRootNode->parentNode() : stylesheetRootNode,
+ cachedStylesheet = XSLStyleSheet::createForXSLTProcessor(
+ stylesheetRootNode->parentNode() ? stylesheetRootNode->parentNode() : stylesheetRootNode,
stylesheetRootNode->document().url().string(),
stylesheetRootNode->document().url()); // FIXME: Should we use baseURL here?
- // According to Mozilla documentation, the node must be a Document node, an xsl:stylesheet or xsl:transform element.
- // But we just use text content regardless of node type.
+ // According to Mozilla documentation, the node must be a Document node,
+ // an xsl:stylesheet or xsl:transform element. But we just use text
+ // content regardless of node type.
cachedStylesheet->parseString(createMarkup(stylesheetRootNode));
}
@@ -239,7 +240,7 @@ static xsltStylesheetPtr xsltStylesheetPointer(RefPtr<XSLStyleSheet>& cachedStyl
static inline xmlDocPtr xmlDocPtrFromNode(Node* sourceNode, bool& shouldDelete)
{
- RefPtr<Document> ownerDocument(sourceNode->document());
+ RefPtrWillBeRawPtr<Document> ownerDocument(sourceNode->document());
bool sourceIsDocument = (sourceNode == ownerDocument.get());
xmlDocPtr sourceDoc = 0;
@@ -274,13 +275,13 @@ static inline String resultMIMEType(xmlDocPtr resultDoc, xsltStylesheetPtr sheet
bool XSLTProcessor::transformToString(Node* sourceNode, String& mimeType, String& resultString, String& resultEncoding)
{
- RefPtr<Document> ownerDocument(sourceNode->document());
+ RefPtrWillBeRawPtr<Document> ownerDocument(sourceNode->document());
setXSLTLoadCallBack(docLoaderFunc, this, ownerDocument->fetcher());
xsltStylesheetPtr sheet = xsltStylesheetPointer(m_stylesheet, m_stylesheetRootNode.get());
if (!sheet) {
setXSLTLoadCallBack(0, 0, 0);
- m_stylesheet = 0;
+ m_stylesheet = nullptr;
return false;
}
m_stylesheet->clearDocuments();
@@ -292,8 +293,9 @@ bool XSLTProcessor::transformToString(Node* sourceNode, String& mimeType, String
bool success = false;
bool shouldFreeSourceDoc = false;
if (xmlDocPtr sourceDoc = xmlDocPtrFromNode(sourceNode, shouldFreeSourceDoc)) {
- // The XML declaration would prevent parsing the result as a fragment, and it's not needed even for documents,
- // as the result of this function is always immediately parsed.
+ // The XML declaration would prevent parsing the result as a fragment,
+ // and it's not needed even for documents, as the result of this
+ // function is always immediately parsed.
sheet->omitXmlDeclaration = true;
xsltTransformContextPtr transformContext = xsltNewTransformContext(sheet, sourceDoc);
@@ -310,13 +312,15 @@ bool XSLTProcessor::transformToString(Node* sourceNode, String& mimeType, String
if (0 != xsltSetCtxtSecurityPrefs(securityPrefs, transformContext))
CRASH();
- // <http://bugs.webkit.org/show_bug.cgi?id=16077>: XSLT processor <xsl:sort> algorithm only compares by code point.
+ // <http://bugs.webkit.org/show_bug.cgi?id=16077>: XSLT processor
+ // <xsl:sort> algorithm only compares by code point.
xsltSetCtxtSortFunc(transformContext, xsltUnicodeSortFunction);
// This is a workaround for a bug in libxslt.
- // The bug has been fixed in version 1.1.13, so once we ship that this can be removed.
+ // The bug has been fixed in version 1.1.13, so once we ship that this
+ // can be removed.
if (!transformContext->globalVars)
- transformContext->globalVars = xmlHashCreate(20);
+ transformContext->globalVars = xmlHashCreate(20);
const char** params = xsltParamArrayFromParameterMap(m_parameters);
xsltQuoteUserParams(transformContext, params);
@@ -339,7 +343,7 @@ bool XSLTProcessor::transformToString(Node* sourceNode, String& mimeType, String
sheet->method = origMethod;
setXSLTLoadCallBack(0, 0, 0);
xsltFreeStylesheet(sheet);
- m_stylesheet = 0;
+ m_stylesheet = nullptr;
return success;
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp b/chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp
index 83342cb6900..c6d7486d4e0 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp
@@ -36,7 +36,13 @@
namespace WebCore {
-// Based on default implementation from libxslt 1.1.22 and xsltICUSort.c example.
+inline const xmlChar* toXMLChar(const char* string)
+{
+ return reinterpret_cast<const xmlChar*>(string);
+}
+
+// Based on default implementation from libxslt 1.1.22 and xsltICUSort.c
+// example.
void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
{
#ifdef XSLT_REFACTORED
@@ -44,124 +50,110 @@ void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, in
#else
xsltStylePreCompPtr comp;
#endif
- xmlXPathObjectPtr *resultsTab[XSLT_MAX_SORT];
- xmlXPathObjectPtr *results = NULL, *res;
- xmlNodeSetPtr list = NULL;
- int descending, number, desc, numb;
- int len = 0;
- int i, j, incr;
- int tst;
+ xmlXPathObjectPtr* resultsTab[XSLT_MAX_SORT];
+ xmlXPathObjectPtr* results = 0;
+ xmlNodeSetPtr list = 0;
int depth;
xmlNodePtr node;
- xmlXPathObjectPtr tmp;
int tempstype[XSLT_MAX_SORT], temporder[XSLT_MAX_SORT];
- if ((ctxt == NULL) || (sorts == NULL) || (nbsorts <= 0) ||
- (nbsorts >= XSLT_MAX_SORT))
+ if (!ctxt || !sorts || nbsorts <= 0 || nbsorts >= XSLT_MAX_SORT)
return;
- if (sorts[0] == NULL)
+ if (!sorts[0])
return;
comp = static_cast<xsltStylePreComp*>(sorts[0]->psvi);
- if (comp == NULL)
+ if (!comp)
return;
list = ctxt->nodeList;
- if ((list == NULL) || (list->nodeNr <= 1))
- return; /* nothing to do */
+ if (!list || list->nodeNr <= 1)
+ return; // Nothing to do.
- for (j = 0; j < nbsorts; j++) {
+ for (int j = 0; j < nbsorts; ++j) {
comp = static_cast<xsltStylePreComp*>(sorts[j]->psvi);
tempstype[j] = 0;
- if ((comp->stype == NULL) && (comp->has_stype != 0)) {
- comp->stype =
- xsltEvalAttrValueTemplate(ctxt, sorts[j],
- (const xmlChar *) "data-type",
- XSLT_NAMESPACE);
- if (comp->stype != NULL) {
+ if (!comp->stype && comp->has_stype) {
+ comp->stype = xsltEvalAttrValueTemplate(ctxt, sorts[j], toXMLChar("data-type"), XSLT_NAMESPACE);
+ if (comp->stype) {
tempstype[j] = 1;
- if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
+ if (xmlStrEqual(comp->stype, toXMLChar("text"))) {
comp->number = 0;
- else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
+ } else if (xmlStrEqual(comp->stype, toXMLChar("number"))) {
comp->number = 1;
- else {
- xsltTransformError(ctxt, NULL, sorts[j],
- "xsltDoSortFunction: no support for data-type = %s\n",
- comp->stype);
- comp->number = 0; /* use default */
+ } else {
+ xsltTransformError(ctxt, 0, sorts[j], "xsltDoSortFunction: no support for data-type = %s\n", comp->stype);
+ comp->number = 0; // Use default.
}
}
}
temporder[j] = 0;
- if ((comp->order == NULL) && (comp->has_order != 0)) {
- comp->order = xsltEvalAttrValueTemplate(ctxt, sorts[j],
- (const xmlChar *) "order",
- XSLT_NAMESPACE);
- if (comp->order != NULL) {
+ if (!comp->order && comp->has_order) {
+ comp->order = xsltEvalAttrValueTemplate(ctxt, sorts[j], toXMLChar("order"), XSLT_NAMESPACE);
+ if (comp->order) {
temporder[j] = 1;
- if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
+ if (xmlStrEqual(comp->order, toXMLChar("ascending"))) {
comp->descending = 0;
- else if (xmlStrEqual(comp->order,
- (const xmlChar *) "descending"))
+ } else if (xmlStrEqual(comp->order, toXMLChar("descending"))) {
comp->descending = 1;
- else {
- xsltTransformError(ctxt, NULL, sorts[j],
- "xsltDoSortFunction: invalid value %s for order\n",
- comp->order);
- comp->descending = 0; /* use default */
+ } else {
+ xsltTransformError(ctxt, 0, sorts[j], "xsltDoSortFunction: invalid value %s for order\n", comp->order);
+ comp->descending = 0; // Use default.
}
}
}
}
- len = list->nodeNr;
+ int len = list->nodeNr;
resultsTab[0] = xsltComputeSortResult(ctxt, sorts[0]);
- for (i = 1;i < XSLT_MAX_SORT;i++)
- resultsTab[i] = NULL;
+ for (int i = 1; i < XSLT_MAX_SORT; ++i)
+ resultsTab[i] = 0;
results = resultsTab[0];
comp = static_cast<xsltStylePreComp*>(sorts[0]->psvi);
- descending = comp->descending;
- number = comp->number;
- if (results == NULL)
+ int descending = comp->descending;
+ int number = comp->number;
+ if (!results)
return;
- // We are passing a language identifier to a function that expects a locale identifier.
- // The implementation of Collator should be lenient, and accept both "en-US" and "en_US", for example.
- // This lets an author to really specify sorting rules, e.g. "de_DE@collation=phonebook", which isn't
+ // We are passing a language identifier to a function that expects a locale
+ // identifier. The implementation of Collator should be lenient, and accept
+ // both "en-US" and "en_US", for example. This lets an author to really
+ // specify sorting rules, e.g. "de_DE@collation=phonebook", which isn't
// possible with language alone.
- Collator collator(comp->has_lang ? (const char*)comp->lang : "en");
+ Collator collator(comp->has_lang ? reinterpret_cast<const char*>(comp->lang) : "en");
collator.setOrderLowerFirst(comp->lower_first);
- /* Shell's sort of node-set */
- for (incr = len / 2; incr > 0; incr /= 2) {
- for (i = incr; i < len; i++) {
- j = i - incr;
- if (results[i] == NULL)
+ // Shell's sort of node-set.
+ for (int incr = len / 2; incr > 0; incr /= 2) {
+ for (int i = incr; i < len; ++i) {
+ int j = i - incr;
+ if (!results[i])
continue;
while (j >= 0) {
- if (results[j] == NULL)
+ int tst;
+ if (!results[j]) {
tst = 1;
- else {
+ } else {
if (number) {
- /* We make NaN smaller than number in accordance
- with XSLT spec */
+ // We make NaN smaller than number in accordance with
+ // XSLT spec.
if (xmlXPathIsNaN(results[j]->floatval)) {
if (xmlXPathIsNaN(results[j + incr]->floatval))
tst = 0;
else
tst = -1;
- } else if (xmlXPathIsNaN(results[j + incr]->floatval))
+ } else if (xmlXPathIsNaN(results[j + incr]->floatval)) {
tst = 1;
- else if (results[j]->floatval ==
- results[j + incr]->floatval)
+ } else if (results[j]->floatval == results[j + incr]->floatval) {
tst = 0;
- else if (results[j]->floatval >
- results[j + incr]->floatval)
+ } else if (results[j]->floatval > results[j + incr]->floatval) {
tst = 1;
- else tst = -1;
+ } else {
+ tst = -1;
+ }
} else {
Vector<UChar> string1;
Vector<UChar> string2;
@@ -173,52 +165,45 @@ void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, in
tst = -tst;
}
if (tst == 0) {
- /*
- * Okay we need to use multi level sorts
- */
+ // Okay we need to use multi level sorts.
depth = 1;
while (depth < nbsorts) {
- if (sorts[depth] == NULL)
+ if (!sorts[depth])
break;
comp = static_cast<xsltStylePreComp*>(sorts[depth]->psvi);
- if (comp == NULL)
+ if (!comp)
break;
- desc = comp->descending;
- numb = comp->number;
+ int desc = comp->descending;
+ int numb = comp->number;
- /*
- * Compute the result of the next level for the
- * full set, this might be optimized ... or not
- */
- if (resultsTab[depth] == NULL)
- resultsTab[depth] = xsltComputeSortResult(ctxt,
- sorts[depth]);
- res = resultsTab[depth];
- if (res == NULL)
+ // Compute the result of the next level for the full
+ // set, this might be optimized ... or not
+ if (!resultsTab[depth])
+ resultsTab[depth] = xsltComputeSortResult(ctxt, sorts[depth]);
+ xmlXPathObjectPtr* res = resultsTab[depth];
+ if (!res)
break;
- if (res[j] == NULL) {
- if (res[j+incr] != NULL)
+ if (!res[j]) {
+ if (res[j + incr])
tst = 1;
} else {
if (numb) {
- /* We make NaN smaller than number in
- accordance with XSLT spec */
+ // We make NaN smaller than number in accordance
+ // with XSLT spec.
if (xmlXPathIsNaN(res[j]->floatval)) {
- if (xmlXPathIsNaN(res[j +
- incr]->floatval))
+ if (xmlXPathIsNaN(res[j + incr]->floatval))
tst = 0;
else
tst = -1;
- } else if (xmlXPathIsNaN(res[j + incr]->
- floatval))
+ } else if (xmlXPathIsNaN(res[j + incr]->floatval)) {
tst = 1;
- else if (res[j]->floatval == res[j + incr]->
- floatval)
+ } else if (res[j]->floatval == res[j + incr]->floatval) {
tst = 0;
- else if (res[j]->floatval >
- res[j + incr]->floatval)
+ } else if (res[j]->floatval > res[j + incr]->floatval) {
tst = 1;
- else tst = -1;
+ } else {
+ tst = -1;
+ }
} else {
Vector<UChar> string1;
Vector<UChar> string2;
@@ -230,10 +215,8 @@ void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, in
tst = -tst;
}
- /*
- * if we still can't differenciate at this level
- * try one level deeper.
- */
+ // if we still can't differenciate at this level try one
+ // level deeper.
if (tst != 0)
break;
depth++;
@@ -243,7 +226,7 @@ void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, in
tst = results[j]->index > results[j + incr]->index;
}
if (tst > 0) {
- tmp = results[j];
+ xmlXPathObjectPtr tmp = results[j];
results[j] = results[j + incr];
results[j + incr] = tmp;
node = list->nodeTab[j];
@@ -251,37 +234,38 @@ void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, in
list->nodeTab[j + incr] = node;
depth = 1;
while (depth < nbsorts) {
- if (sorts[depth] == NULL)
+ if (!sorts[depth])
break;
- if (resultsTab[depth] == NULL)
+ if (!resultsTab[depth])
break;
- res = resultsTab[depth];
+ xmlXPathObjectPtr* res = resultsTab[depth];
tmp = res[j];
res[j] = res[j + incr];
res[j + incr] = tmp;
depth++;
}
j -= incr;
- } else
+ } else {
break;
+ }
}
}
}
- for (j = 0; j < nbsorts; j++) {
+ for (int j = 0; j < nbsorts; ++j) {
comp = static_cast<xsltStylePreComp*>(sorts[j]->psvi);
if (tempstype[j] == 1) {
- /* The data-type needs to be recomputed each time */
- xmlFree((void *)(comp->stype));
- comp->stype = NULL;
+ // The data-type needs to be recomputed each time.
+ xmlFree(const_cast<xmlChar*>(comp->stype));
+ comp->stype = 0;
}
if (temporder[j] == 1) {
- /* The order needs to be recomputed each time */
- xmlFree((void *)(comp->order));
- comp->order = NULL;
+ // The order needs to be recomputed each time.
+ xmlFree(const_cast<xmlChar*>(comp->order));
+ comp->order = 0;
}
- if (resultsTab[j] != NULL) {
- for (i = 0;i < len;i++)
+ if (resultsTab[j]) {
+ for (int i = 0; i < len; ++i)
xmlXPathFreeObject(resultsTab[j][i]);
xmlFree(resultsTab[j]);
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.h b/chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.h
index 5602afcac29..6f7240ec3fc 100644
--- a/chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.h
+++ b/chromium/third_party/WebKit/Source/core/xml/XSLTUnicodeSort.h
@@ -32,7 +32,7 @@
namespace WebCore {
- void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr* sorts, int nbsorts);
+void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr* sorts, int nbsorts);
}
diff --git a/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp b/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp
new file mode 100644
index 00000000000..c42c33fc3b4
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/xml/parser/SharedBufferReader.h"
+
+#include "platform/SharedBuffer.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+
+#include <algorithm>
+#include <cstring>
+
+namespace WebCore {
+
+SharedBufferReader::SharedBufferReader(PassRefPtr<SharedBuffer> buffer)
+ : m_buffer(buffer)
+ , m_currentOffset(0)
+{
+}
+
+SharedBufferReader::~SharedBufferReader()
+{
+}
+
+int SharedBufferReader::readData(char* outputBuffer, unsigned askedToRead)
+{
+ if (!m_buffer || m_currentOffset > m_buffer->size())
+ return 0;
+
+ unsigned bytesCopied = 0;
+ unsigned bytesLeft = m_buffer->size() - m_currentOffset;
+ unsigned lenToCopy = std::min(askedToRead, bytesLeft);
+
+ while (bytesCopied < lenToCopy) {
+ const char* data;
+ unsigned segmentSize = m_buffer->getSomeData(data, m_currentOffset);
+ if (!segmentSize)
+ break;
+
+ segmentSize = std::min(segmentSize, lenToCopy - bytesCopied);
+ memcpy(outputBuffer + bytesCopied, data, segmentSize);
+ bytesCopied += segmentSize;
+ m_currentOffset += segmentSize;
+ }
+
+ return bytesCopied;
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReader.h b/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReader.h
new file mode 100644
index 00000000000..7217de95fcf
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReader.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SharedBufferReader_h
+#define SharedBufferReader_h
+
+#include "wtf/FastAllocBase.h"
+#include "wtf/Forward.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class SharedBuffer;
+
+// Allows transfer of data in multiple chunks from a SharedBuffer to a provided buffer.
+class SharedBufferReader {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ SharedBufferReader(PassRefPtr<SharedBuffer>);
+
+ ~SharedBufferReader();
+
+ // Returns the number of bytes that were read (i.e. written to |outputBuffer|).
+ int readData(char* outputBuffer, unsigned askedToRead);
+
+private:
+ RefPtr<SharedBuffer> m_buffer;
+ unsigned m_currentOffset;
+};
+
+} // namespace WebCore
+
+#endif // SharedBufferReader_h
diff --git a/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReaderTest.cpp b/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReaderTest.cpp
new file mode 100644
index 00000000000..a908c944c56
--- /dev/null
+++ b/chromium/third_party/WebKit/Source/core/xml/parser/SharedBufferReaderTest.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/xml/parser/SharedBufferReader.h"
+
+#include "platform/SharedBuffer.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <gtest/gtest.h>
+#include <vector>
+
+namespace WebCore {
+
+TEST(SharedBufferReaderTest, readDataWithNullSharedBuffer)
+{
+ SharedBufferReader reader(nullptr);
+ char buffer[32];
+
+ EXPECT_EQ(0, reader.readData(buffer, sizeof(buffer)));
+}
+
+TEST(SharedBufferReaderTest, readDataWith0BytesRequest)
+{
+ RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create();
+ SharedBufferReader reader(sharedBuffer);
+
+ EXPECT_EQ(0, reader.readData(0, 0));
+}
+
+TEST(SharedBufferReaderTest, readDataWithSizeBiggerThanSharedBufferSize)
+{
+ static const char testData[] = "hello";
+ RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(testData, sizeof(testData));
+
+ SharedBufferReader reader(sharedBuffer);
+
+ const int extraBytes = 3;
+ char outputBuffer[sizeof(testData) + extraBytes];
+
+ const char initializationByte = 'a';
+ memset(outputBuffer, initializationByte, sizeof(outputBuffer));
+ EXPECT_EQ(sizeof(testData),
+ static_cast<size_t>(reader.readData(outputBuffer, sizeof(outputBuffer))));
+
+ EXPECT_TRUE(std::equal(testData, testData + sizeof(testData), outputBuffer));
+ // Check that the bytes past index sizeof(testData) were not touched.
+ EXPECT_EQ(extraBytes,
+ std::count(outputBuffer, outputBuffer + sizeof(outputBuffer), initializationByte));
+}
+
+TEST(SharedBufferReaderTest, readDataInMultiples)
+{
+ const int iterationsCount = 8;
+ const int bytesPerIteration = 64;
+
+ std::vector<char> testData(iterationsCount * bytesPerIteration);
+ std::generate(testData.begin(), testData.end(), &std::rand);
+
+ RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(&testData[0], testData.size());
+ SharedBufferReader reader(sharedBuffer);
+
+ std::vector<char> destinationVector(testData.size());
+
+ for (int i = 0; i < iterationsCount; ++i) {
+ const int offset = i * bytesPerIteration;
+ const int bytesRead = reader.readData(&destinationVector[0] + offset, bytesPerIteration);
+ EXPECT_EQ(bytesPerIteration, bytesRead);
+ }
+
+ EXPECT_TRUE(std::equal(testData.begin(), testData.end(), destinationVector.begin()));
+}
+
+TEST(SharedBufferReaderTest, clearSharedBufferBetweenCallsToReadData)
+{
+ std::vector<char> testData(128);
+ std::generate(testData.begin(), testData.end(), &std::rand);
+
+ RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(&testData[0], testData.size());
+ SharedBufferReader reader(sharedBuffer);
+
+ std::vector<char> destinationVector(testData.size());
+ const int bytesToRead = testData.size() / 2;
+ EXPECT_EQ(bytesToRead, reader.readData(&destinationVector[0], bytesToRead));
+
+ sharedBuffer->clear();
+
+ EXPECT_EQ(0, reader.readData(&destinationVector[0], bytesToRead));
+}
+
+} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp b/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp
index 36c329f7958..61b4b32af09 100644
--- a/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp
+++ b/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp
@@ -26,18 +26,13 @@
#include "config.h"
#include "core/xml/parser/XMLDocumentParser.h"
-#include <libxml/catalog.h>
-#include <libxml/parser.h>
-#include <libxml/parserInternals.h>
-#include <libxslt/xslt.h>
-#include "FetchInitiatorTypeNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "XMLNSNames.h"
#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "bindings/v8/ScriptController.h"
#include "bindings/v8/ScriptSourceCode.h"
+#include "core/FetchInitiatorTypeNames.h"
+#include "core/HTMLNames.h"
+#include "core/XMLNSNames.h"
#include "core/dom/CDATASection.h"
#include "core/dom/Comment.h"
#include "core/dom/Document.h"
@@ -48,17 +43,20 @@
#include "core/dom/TransformSource.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/fetch/ScriptResource.h"
-#include "core/fetch/TextResourceDecoder.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
#include "core/html/HTMLHtmlElement.h"
#include "core/html/HTMLTemplateElement.h"
#include "core/html/parser/HTMLEntityParser.h"
+#include "core/html/parser/TextResourceDecoder.h"
#include "core/loader/FrameLoader.h"
#include "core/loader/ImageLoader.h"
-#include "core/frame/UseCounter.h"
+#include "core/svg/graphics/SVGImage.h"
#include "core/xml/XMLTreeViewer.h"
+#include "core/xml/parser/SharedBufferReader.h"
#include "core/xml/parser/XMLDocumentParserScope.h"
#include "core/xml/parser/XMLParserInput.h"
+#include "platform/RuntimeEnabledFeatures.h"
#include "platform/SharedBuffer.h"
#include "platform/network/ResourceError.h"
#include "platform/network/ResourceRequest.h"
@@ -69,8 +67,10 @@
#include "wtf/Threading.h"
#include "wtf/Vector.h"
#include "wtf/unicode/UTF8.h"
-
-using namespace std;
+#include <libxml/catalog.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxslt/xslt.h>
namespace WebCore {
@@ -110,6 +110,9 @@ static inline bool hasNoStyleInformation(Document* document)
if (document->frame()->tree().parent())
return false; // This document is not in a top frame
+ if (SVGImage::isInSVGImage(document))
+ return false;
+
return true;
}
@@ -125,13 +128,13 @@ public:
, m_defaultedCount(defaultedCount)
{
m_namespaces = static_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * namespaceCount * 2));
- for (int i = 0; i < namespaceCount * 2 ; i++)
+ for (int i = 0; i < namespaceCount * 2 ; ++i)
m_namespaces[i] = xmlStrdup(namespaces[i]);
m_attributes = static_cast<xmlChar**>(xmlMalloc(sizeof(xmlChar*) * attributeCount * 5));
- for (int i = 0; i < attributeCount; i++) {
+ for (int i = 0; i < attributeCount; ++i) {
// Each attribute has 5 elements in the array:
// name, prefix, uri, value and an end pointer.
- for (int j = 0; j < 3; j++)
+ for (int j = 0; j < 3; ++j)
m_attributes[i * 5 + j] = xmlStrdup(attributes[i * 5 + j]);
int length = attributes[i * 5 + 4] - attributes[i * 5 + 3];
m_attributes[i * 5 + 3] = xmlStrndup(attributes[i * 5 + 3], length);
@@ -141,11 +144,11 @@ public:
virtual ~PendingStartElementNSCallback()
{
- for (int i = 0; i < m_namespaceCount * 2; i++)
+ for (int i = 0; i < m_namespaceCount * 2; ++i)
xmlFree(m_namespaces[i]);
xmlFree(m_namespaces);
- for (int i = 0; i < m_attributeCount; i++)
- for (int j = 0; j < 4; j++)
+ for (int i = 0; i < m_attributeCount; ++i)
+ for (int j = 0; j < 4; ++j)
xmlFree(m_attributes[i * 5 + j]);
xmlFree(m_attributes);
}
@@ -153,8 +156,8 @@ public:
virtual void call(XMLDocumentParser* parser) OVERRIDE
{
parser->startElementNs(m_localName, m_prefix, m_uri,
- m_namespaceCount, const_cast<const xmlChar**>(m_namespaces),
- m_attributeCount, m_defaultedCount, const_cast<const xmlChar**>(m_attributes));
+ m_namespaceCount, const_cast<const xmlChar**>(m_namespaces),
+ m_attributeCount, m_defaultedCount, const_cast<const xmlChar**>(m_attributes));
}
private:
@@ -294,12 +297,14 @@ void XMLDocumentParser::pushCurrentNode(ContainerNode* n)
{
ASSERT(n);
ASSERT(m_currentNode);
+#if !ENABLE(OILPAN)
if (n != document())
n->ref();
+#endif
m_currentNodeStack.append(m_currentNode);
m_currentNode = n;
if (m_currentNodeStack.size() > maxXMLTreeDepth)
- handleError(XMLErrors::fatal, "Excessive node nesting.", textPosition());
+ handleError(XMLErrors::ErrorTypeFatal, "Excessive node nesting.", textPosition());
}
void XMLDocumentParser::popCurrentNode()
@@ -307,26 +312,30 @@ void XMLDocumentParser::popCurrentNode()
if (!m_currentNode)
return;
ASSERT(m_currentNodeStack.size());
-
+#if !ENABLE(OILPAN)
if (m_currentNode != document())
m_currentNode->deref();
-
+#endif
m_currentNode = m_currentNodeStack.last();
m_currentNodeStack.removeLast();
}
void XMLDocumentParser::clearCurrentNodeStack()
{
+#if !ENABLE(OILPAN)
if (m_currentNode && m_currentNode != document())
m_currentNode->deref();
- m_currentNode = 0;
- m_leafTextNode = 0;
+#endif
+ m_currentNode = nullptr;
+ m_leafTextNode = nullptr;
if (m_currentNodeStack.size()) { // Aborted parsing.
+#if !ENABLE(OILPAN)
for (size_t i = m_currentNodeStack.size() - 1; i != 0; --i)
m_currentNodeStack[i]->deref();
if (m_currentNodeStack[0] && m_currentNodeStack[0] != document())
m_currentNodeStack[0]->deref();
+#endif
m_currentNodeStack.clear();
}
}
@@ -352,23 +361,17 @@ void XMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
// JavaScript can detach the parser. Make sure this is not released
// before the end of this method.
- RefPtr<XMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
doWrite(source.toString());
-
- if (isStopped())
- return;
-
- if (document()->frame() && document()->frame()->script().canExecuteScripts(NotAboutToExecuteScript))
- ImageLoader::dispatchPendingBeforeLoadEvents();
}
void XMLDocumentParser::handleError(XMLErrors::ErrorType type, const char* formattedMessage, TextPosition position)
{
m_xmlErrors.handleError(type, formattedMessage, position);
- if (type != XMLErrors::warning)
+ if (type != XMLErrors::ErrorTypeWarning)
m_sawError = true;
- if (type == XMLErrors::fatal)
+ if (type == XMLErrors::ErrorTypeFatal)
stopParsing();
}
@@ -390,7 +393,7 @@ void XMLDocumentParser::exitText()
m_leafTextNode->appendData(toString(m_bufferedText.data(), m_bufferedText.size()));
m_bufferedText.clear();
- m_leafTextNode = 0;
+ m_leafTextNode = nullptr;
}
void XMLDocumentParser::detach()
@@ -416,11 +419,11 @@ void XMLDocumentParser::end()
if (m_parserPaused)
return;
- if (m_sawError)
+ if (m_sawError) {
insertErrorMessageBlock();
- else {
+ } else {
exitText();
- document()->styleResolverChanged(RecalcStyleImmediately);
+ document()->styleResolverChanged();
}
if (isParsing())
@@ -450,7 +453,6 @@ void XMLDocumentParser::insertErrorMessageBlock()
void XMLDocumentParser::notifyFinished(Resource* unusedResource)
{
ASSERT_UNUSED(unusedResource, unusedResource == m_pendingScript);
- ASSERT(m_pendingScript->accessCount() > 0);
ScriptSourceCode sourceCode(m_pendingScript.get());
bool errorOccurred = m_pendingScript->errorOccurred();
@@ -459,23 +461,24 @@ void XMLDocumentParser::notifyFinished(Resource* unusedResource)
m_pendingScript->removeClient(this);
m_pendingScript = 0;
- RefPtr<Element> e = m_scriptElement;
- m_scriptElement = 0;
+ RefPtrWillBeRawPtr<Element> e = m_scriptElement;
+ m_scriptElement = nullptr;
ScriptLoader* scriptLoader = toScriptLoaderIfPossible(e.get());
ASSERT(scriptLoader);
- // JavaScript can detach this parser, make sure it's kept alive even if detached.
- RefPtr<XMLDocumentParser> protect(this);
+ // JavaScript can detach this parser, make sure it's kept alive even if
+ // detached.
+ RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
- if (errorOccurred)
+ if (errorOccurred) {
scriptLoader->dispatchErrorEvent();
- else if (!wasCanceled) {
- if (scriptLoader->executePotentiallyCrossOriginScript(sourceCode))
- scriptLoader->dispatchLoadEvent();
+ } else if (!wasCanceled) {
+ scriptLoader->executeScript(sourceCode);
+ scriptLoader->dispatchLoadEvent();
}
- m_scriptElement = 0;
+ m_scriptElement = nullptr;
if (!isDetached() && !m_requestingScript)
resumeParsing();
@@ -488,10 +491,8 @@ bool XMLDocumentParser::isWaitingForScripts() const
void XMLDocumentParser::pauseParsing()
{
- if (m_parsingFragment)
- return;
-
- m_parserPaused = true;
+ if (!m_parsingFragment)
+ m_parserPaused = true;
}
bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragment* fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
@@ -507,12 +508,16 @@ bool XMLDocumentParser::parseDocumentFragment(const String& chunk, DocumentFragm
return true;
}
- RefPtr<XMLDocumentParser> parser = XMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
+ RefPtrWillBeRawPtr<XMLDocumentParser> parser = XMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
bool wellFormed = parser->appendFragmentSource(chunk);
- // Do not call finish(). Current finish() and doEnd() implementations touch the main Document/loader
- // and can cause crashes in the fragment case.
- parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
- return wellFormed; // appendFragmentSource()'s wellFormed is more permissive than wellFormed().
+
+ // Do not call finish(). Current finish() and doEnd() implementations touch
+ // the main Document/loader and can cause crashes in the fragment case.
+
+ // Allows ~DocumentParser to assert it was detached before destruction.
+ parser->detach();
+ // appendFragmentSource()'s wellFormed is more permissive than wellFormed().
+ return wellFormed;
}
static int globalDescriptor = 0;
@@ -520,32 +525,12 @@ static ThreadIdentifier libxmlLoaderThread = 0;
static int matchFunc(const char*)
{
- // Only match loads initiated due to uses of libxml2 from within XMLDocumentParser to avoid
- // interfering with client applications that also use libxml2. http://bugs.webkit.org/show_bug.cgi?id=17353
+ // Only match loads initiated due to uses of libxml2 from within
+ // XMLDocumentParser to avoid interfering with client applications that also
+ // use libxml2. http://bugs.webkit.org/show_bug.cgi?id=17353
return XMLDocumentParserScope::currentFetcher && currentThread() == libxmlLoaderThread;
}
-class OffsetBuffer {
- WTF_MAKE_FAST_ALLOCATED;
-public:
- OffsetBuffer(const Vector<char>& b) : m_buffer(b), m_currentOffset(0) { }
-
- int readOutBytes(char* outputBuffer, unsigned askedToRead)
- {
- unsigned bytesLeft = m_buffer.size() - m_currentOffset;
- unsigned lenToCopy = min(askedToRead, bytesLeft);
- if (lenToCopy) {
- memcpy(outputBuffer, m_buffer.data() + m_currentOffset, lenToCopy);
- m_currentOffset += lenToCopy;
- }
- return lenToCopy;
- }
-
-private:
- Vector<char> m_buffer;
- unsigned m_currentOffset;
-};
-
static inline void setAttributes(Element* element, Vector<Attribute>& attributeVector, ParserContentPolicy parserContentPolicy)
{
if (!scriptingContentIsAllowed(parserContentPolicy))
@@ -556,9 +541,9 @@ static inline void setAttributes(Element* element, Vector<Attribute>& attributeV
static void switchEncoding(xmlParserCtxtPtr ctxt, bool is8Bit)
{
// Hack around libxml2's lack of encoding overide support by manually
- // resetting the encoding to UTF-16 before every chunk. Otherwise libxml
- // will detect <?xml version="1.0" encoding="<encoding name>"?> blocks
- // and switch encodings, causing the parse to fail.
+ // resetting the encoding to UTF-16 before every chunk. Otherwise libxml
+ // will detect <?xml version="1.0" encoding="<encoding name>"?> blocks and
+ // switch encodings, causing the parse to fail.
if (is8Bit) {
xmlSwitchEncoding(ctxt, XML_CHAR_ENCODING_8859_1);
return;
@@ -608,8 +593,8 @@ static bool shouldAllowExternalLoad(const KURL& url)
if (isLibxmlDefaultCatalogFile(url))
return false;
- // The most common DTD. There isn't much point in hammering www.w3c.org
- // by requesting this URL for every XHTML document.
+ // The most common DTD. There isn't much point in hammering www.w3c.org by
+ // requesting this URL for every XHTML document.
if (urlString.startsWith("http://www.w3.org/TR/xhtml", false))
return false;
@@ -617,12 +602,12 @@ static bool shouldAllowExternalLoad(const KURL& url)
if (urlString.startsWith("http://www.w3.org/Graphics/SVG", false))
return false;
- // The libxml doesn't give us a lot of context for deciding whether to
- // allow this request. In the worst case, this load could be for an
- // external entity and the resulting document could simply read the
- // retrieved content. If we had more context, we could potentially allow
- // the parser to load a DTD. As things stand, we take the conservative
- // route and allow same-origin requests only.
+ // The libxml doesn't give us a lot of context for deciding whether to allow
+ // this request. In the worst case, this load could be for an external
+ // entity and the resulting document could simply read the retrieved
+ // content. If we had more context, we could potentially allow the parser to
+ // load a DTD. As things stand, we take the conservative route and allow
+ // same-origin requests only.
if (!XMLDocumentParserScope::currentFetcher->document()->securityOrigin()->canRequest(url)) {
XMLDocumentParserScope::currentFetcher->printAccessDeniedMessage(url);
return false;
@@ -642,7 +627,7 @@ static void* openFunc(const char* uri)
return &globalDescriptor;
KURL finalURL;
- Vector<char> data;
+ RefPtr<SharedBuffer> data;
{
ResourceFetcher* fetcher = XMLDocumentParserScope::currentFetcher;
@@ -653,7 +638,7 @@ static void* openFunc(const char* uri)
FetchRequest request(ResourceRequest(url), FetchInitiatorTypeNames::xml, ResourceFetcher::defaultResourceOptions());
ResourcePtr<Resource> resource = fetcher->fetchSynchronously(request);
if (resource && !resource->errorOccurred()) {
- resource->resourceBuffer()->moveTo(data);
+ data = resource->resourceBuffer();
finalURL = resource->response().url();
}
}
@@ -664,7 +649,7 @@ static void* openFunc(const char* uri)
if (!shouldAllowExternalLoad(finalURL))
return &globalDescriptor;
- return new OffsetBuffer(data);
+ return new SharedBufferReader(data);
}
static int readFunc(void* context, char* buffer, int len)
@@ -673,8 +658,8 @@ static int readFunc(void* context, char* buffer, int len)
if (context == &globalDescriptor)
return 0;
- OffsetBuffer* data = static_cast<OffsetBuffer*>(context);
- return data->readOutBytes(buffer, len);
+ SharedBufferReader* data = static_cast<SharedBufferReader*>(context);
+ return data->readData(buffer, len);
}
static int writeFunc(void*, const char*, int)
@@ -686,7 +671,7 @@ static int writeFunc(void*, const char*, int)
static int closeFunc(void* context)
{
if (context != &globalDescriptor) {
- OffsetBuffer* data = static_cast<OffsetBuffer*>(context);
+ SharedBufferReader* data = static_cast<SharedBufferReader*>(context);
delete data;
}
return 0;
@@ -733,7 +718,7 @@ PassRefPtr<XMLParserContext> XMLParserContext::createMemoryParser(xmlSAXHandlerP
xmlParserCtxtPtr parser = xmlCreateMemoryParserCtxt(chunk.data(), chunk.length());
if (!parser)
- return 0;
+ return nullptr;
// Copy the sax handler
memcpy(parser->sax, handlers, sizeof(xmlSAXHandler));
@@ -762,11 +747,11 @@ bool XMLDocumentParser::supportsXMLVersion(const String& version)
return version == "1.0";
}
-XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
+XMLDocumentParser::XMLDocumentParser(Document& document, FrameView* frameView)
: ScriptableDocumentParser(document)
- , m_view(frameView)
- , m_context(0)
- , m_currentNode(document)
+ , m_hasView(frameView)
+ , m_context(nullptr)
+ , m_currentNode(&document)
, m_isCurrentlyParsing8BitChunk(false)
, m_sawError(false)
, m_sawCSS(false)
@@ -776,19 +761,20 @@ XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
, m_parserPaused(false)
, m_requestingScript(false)
, m_finishCalled(false)
- , m_xmlErrors(document)
+ , m_xmlErrors(&document)
, m_pendingScript(0)
, m_scriptStartPosition(TextPosition::belowRangePosition())
, m_parsingFragment(false)
{
// This is XML being used as a document resource.
- UseCounter::count(*document, UseCounter::XMLDocument);
+ if (frameView && document.isXMLDocument())
+ UseCounter::count(document, UseCounter::XMLDocument);
}
XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, ParserContentPolicy parserContentPolicy)
- : ScriptableDocumentParser(&fragment->document(), parserContentPolicy)
- , m_view(0)
- , m_context(0)
+ : ScriptableDocumentParser(fragment->document(), parserContentPolicy)
+ , m_hasView(false)
+ , m_context(nullptr)
, m_currentNode(fragment)
, m_isCurrentlyParsing8BitChunk(false)
, m_sawError(false)
@@ -804,10 +790,12 @@ XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parent
, m_scriptStartPosition(TextPosition::belowRangePosition())
, m_parsingFragment(true)
{
+#if !ENABLE(OILPAN)
fragment->ref();
+#endif
// Add namespaces based on the parent node
- Vector<Element*> elemStack;
+ WillBeHeapVector<RawPtrWillBeMember<Element> > elemStack;
while (parentElement) {
elemStack.append(parentElement);
@@ -823,12 +811,13 @@ XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parent
for (; !elemStack.isEmpty(); elemStack.removeLast()) {
Element* element = elemStack.last();
if (element->hasAttributes()) {
- for (unsigned i = 0; i < element->attributeCount(); i++) {
- const Attribute* attribute = element->attributeItem(i);
- if (attribute->localName() == xmlnsAtom)
- m_defaultNamespaceURI = attribute->value();
- else if (attribute->prefix() == xmlnsAtom)
- m_prefixToNamespaceMap.set(attribute->localName(), attribute->value());
+ AttributeCollection attributes = element->attributes();
+ AttributeCollection::const_iterator end = attributes.end();
+ for (AttributeCollection::const_iterator it = attributes.begin(); it != end; ++it) {
+ if (it->localName() == xmlnsAtom)
+ m_defaultNamespaceURI = it->value();
+ else if (it->prefix() == xmlnsAtom)
+ m_prefixToNamespaceMap.set(it->localName(), it->value());
}
}
}
@@ -847,15 +836,29 @@ XMLParserContext::~XMLParserContext()
XMLDocumentParser::~XMLDocumentParser()
{
+#if !ENABLE(OILPAN)
// The XMLDocumentParser will always be detached before being destroyed.
ASSERT(m_currentNodeStack.isEmpty());
ASSERT(!m_currentNode);
+#endif
// FIXME: m_pendingScript handling should be moved into XMLDocumentParser.cpp!
if (m_pendingScript)
m_pendingScript->removeClient(this);
}
+void XMLDocumentParser::trace(Visitor* visitor)
+{
+ visitor->trace(m_currentNode);
+#if ENABLE(OILPAN)
+ visitor->trace(m_currentNodeStack);
+#endif
+ visitor->trace(m_leafTextNode);
+ visitor->trace(m_xmlErrors);
+ visitor->trace(m_scriptElement);
+ ScriptableDocumentParser::trace(visitor);
+}
+
void XMLDocumentParser::doWrite(const String& parseString)
{
ASSERT(!isDetached());
@@ -865,11 +868,12 @@ void XMLDocumentParser::doWrite(const String& parseString)
// Protect the libxml context from deletion during a callback
RefPtr<XMLParserContext> context = m_context;
- // libXML throws an error if you try to switch the encoding for an empty string.
+ // libXML throws an error if you try to switch the encoding for an empty
+ // string.
if (parseString.length()) {
// JavaScript may cause the parser to detach during parseChunk
// keep this alive until this function is done.
- RefPtr<XMLDocumentParser> protect(this);
+ RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
XMLDocumentParserScope scope(document()->fetcher());
TemporaryChange<bool> encodingScope(m_isCurrentlyParsing8BitChunk, parseString.is8Bit());
@@ -881,24 +885,24 @@ void XMLDocumentParser::doWrite(const String& parseString)
return;
}
- // FIXME: Why is this here? And why is it after we process the passed source?
+ // FIXME: Why is this here? And why is it after we process the passed
+ // source?
if (document()->sawDecodingError()) {
// If the decoder saw an error, report it as fatal (stops parsing)
TextPosition position(OrdinalNumber::fromOneBasedInt(context->context()->input->line), OrdinalNumber::fromOneBasedInt(context->context()->input->col));
- handleError(XMLErrors::fatal, "Encoding error", position);
+ handleError(XMLErrors::ErrorTypeFatal, "Encoding error", position);
}
}
-struct _xmlSAX2Namespace {
+struct xmlSAX2Namespace {
const xmlChar* prefix;
const xmlChar* uri;
};
-typedef struct _xmlSAX2Namespace xmlSAX2Namespace;
static inline void handleNamespaceAttributes(Vector<Attribute>& prefixedAttributes, const xmlChar** libxmlNamespaces, int nbNamespaces, ExceptionState& exceptionState)
{
xmlSAX2Namespace* namespaces = reinterpret_cast<xmlSAX2Namespace*>(libxmlNamespaces);
- for (int i = 0; i < nbNamespaces; i++) {
+ for (int i = 0; i < nbNamespaces; ++i) {
AtomicString namespaceQName = xmlnsAtom;
AtomicString namespaceURI = toAtomicString(namespaces[i].uri);
if (namespaces[i].prefix)
@@ -912,19 +916,18 @@ static inline void handleNamespaceAttributes(Vector<Attribute>& prefixedAttribut
}
}
-struct _xmlSAX2Attributes {
+struct xmlSAX2Attributes {
const xmlChar* localname;
const xmlChar* prefix;
const xmlChar* uri;
const xmlChar* value;
const xmlChar* end;
};
-typedef struct _xmlSAX2Attributes xmlSAX2Attributes;
static inline void handleElementAttributes(Vector<Attribute>& prefixedAttributes, const xmlChar** libxmlAttributes, int nbAttributes, ExceptionState& exceptionState)
{
xmlSAX2Attributes* attributes = reinterpret_cast<xmlSAX2Attributes*>(libxmlAttributes);
- for (int i = 0; i < nbAttributes; i++) {
+ for (int i = 0; i < nbAttributes; ++i) {
int valueLength = static_cast<int>(attributes[i].end - attributes[i].value);
AtomicString attrValue = toAtomicString(attributes[i].value, valueLength);
String attrPrefix = toString(attributes[i].prefix);
@@ -965,7 +968,7 @@ void XMLDocumentParser::startElementNs(const AtomicString& localName, const Atom
m_sawFirstElement = true;
QualifiedName qName(prefix, localName, adjustedURI);
- RefPtr<Element> newElement = m_currentNode->document().createElement(qName, true);
+ RefPtrWillBeRawPtr<Element> newElement = m_currentNode->document().createElement(qName, true);
if (!newElement) {
stopParsing();
return;
@@ -995,13 +998,13 @@ void XMLDocumentParser::startElementNs(const AtomicString& localName, const Atom
m_currentNode->parserAppendChild(newElement.get());
- if (newElement->hasTagName(HTMLNames::templateTag))
- pushCurrentNode(toHTMLTemplateElement(newElement.get())->content());
+ if (isHTMLTemplateElement(*newElement))
+ pushCurrentNode(toHTMLTemplateElement(*newElement).content());
else
pushCurrentNode(newElement.get());
- if (isHTMLHtmlElement(newElement.get()))
- toHTMLHtmlElement(newElement)->insertedByParser();
+ if (isHTMLHtmlElement(*newElement))
+ toHTMLHtmlElement(*newElement).insertedByParser();
if (!m_parsingFragment && isFirstElement && document()->frame())
document()->frame()->loader().dispatchDocumentElementAvailable();
@@ -1017,14 +1020,15 @@ void XMLDocumentParser::endElementNs()
return;
}
- // JavaScript can detach the parser. Make sure this is not released
- // before the end of this method.
- RefPtr<XMLDocumentParser> protect(this);
+ // JavaScript can detach the parser. Make sure this is not released before
+ // the end of this method.
+ RefPtrWillBeRawPtr<XMLDocumentParser> protect(this);
exitText();
- RefPtr<ContainerNode> n = m_currentNode;
- n->finishParsingChildren();
+ RefPtrWillBeRawPtr<ContainerNode> n = m_currentNode;
+ if (m_currentNode->isElementNode())
+ toElement(n.get())->finishParsingChildren();
if (!scriptingContentIsAllowed(parserContentPolicy()) && n->isElementNode() && toScriptLoaderIfPossible(toElement(n))) {
popCurrentNode();
@@ -1032,7 +1036,7 @@ void XMLDocumentParser::endElementNs()
return;
}
- if (!n->isElementNode() || !m_view) {
+ if (!n->isElementNode() || !m_hasView) {
popCurrentNode();
return;
}
@@ -1067,11 +1071,12 @@ void XMLDocumentParser::endElementNs()
m_scriptElement = element;
m_pendingScript->addClient(this);
- // m_pendingScript will be 0 if script was already loaded and addClient() executed it.
+ // m_pendingScript will be 0 if script was already loaded and
+ // addClient() executed it.
if (m_pendingScript)
pauseParsing();
} else {
- m_scriptElement = 0;
+ m_scriptElement = nullptr;
}
// JavaScript may have detached the parser
@@ -1102,28 +1107,15 @@ void XMLDocumentParser::error(XMLErrors::ErrorType type, const char* message, va
if (isStopped())
return;
-#if HAVE(VASPRINTF)
- char* formattedMessage;
- if (vasprintf(&formattedMessage, message, args) == -1)
- return;
-#else
char formattedMessage[1024];
vsnprintf(formattedMessage, sizeof(formattedMessage) - 1, message, args);
-#endif
if (m_parserPaused) {
m_pendingCallbacks.append(adoptPtr(new PendingErrorCallback(type, reinterpret_cast<const xmlChar*>(formattedMessage), lineNumber(), columnNumber())));
-#if HAVE(VASPRINTF)
- free(formattedMessage);
-#endif
return;
}
handleError(type, formattedMessage, textPosition());
-
-#if HAVE(VASPRINTF)
- free(formattedMessage);
-#endif
}
void XMLDocumentParser::processingInstruction(const String& target, const String& data)
@@ -1132,7 +1124,7 @@ void XMLDocumentParser::processingInstruction(const String& target, const String
return;
if (m_parserPaused) {
- m_pendingCallbacks.append(adoptPtr(new PendingProcessingInstructionCallback(target ,data)));
+ m_pendingCallbacks.append(adoptPtr(new PendingProcessingInstructionCallback(target, data)));
return;
}
@@ -1140,7 +1132,7 @@ void XMLDocumentParser::processingInstruction(const String& target, const String
// ### handle exceptions
TrackExceptionState exceptionState;
- RefPtr<ProcessingInstruction> pi = m_currentNode->document().createProcessingInstruction(target, data, exceptionState);
+ RefPtrWillBeRawPtr<ProcessingInstruction> pi = m_currentNode->document().createProcessingInstruction(target, data, exceptionState);
if (exceptionState.hadException())
return;
@@ -1148,7 +1140,7 @@ void XMLDocumentParser::processingInstruction(const String& target, const String
m_currentNode->parserAppendChild(pi.get());
- pi->finishParsingChildren();
+ pi->setCreatedByParser(false);
if (pi->isCSS())
m_sawCSS = true;
@@ -1158,10 +1150,11 @@ void XMLDocumentParser::processingInstruction(const String& target, const String
m_sawXSLTransform = !m_sawFirstElement && pi->isXSL();
if (m_sawXSLTransform && !document()->transformSourceDocument()) {
- // This behavior is very tricky. We call stopParsing() here because we want to stop processing the document
- // until we're ready to apply the transform, but we actually still want to be fed decoded string pieces to
- // accumulate in m_originalSourceForTransform. So, we call stopParsing() here and
- // check isStopped() in element callbacks.
+ // This behavior is very tricky. We call stopParsing() here because we
+ // want to stop processing the document until we're ready to apply the
+ // transform, but we actually still want to be fed decoded string pieces
+ // to accumulate in m_originalSourceForTransform. So, we call
+ // stopParsing() here and check isStopped() in element callbacks.
// FIXME: This contradicts the contract of DocumentParser.
stopParsing();
}
@@ -1179,8 +1172,7 @@ void XMLDocumentParser::cdataBlock(const String& text)
exitText();
- RefPtr<CDATASection> newNode = CDATASection::create(m_currentNode->document(), text);
- m_currentNode->parserAppendChild(newNode.get());
+ m_currentNode->parserAppendChild(CDATASection::create(m_currentNode->document(), text));
}
void XMLDocumentParser::comment(const String& text)
@@ -1195,8 +1187,7 @@ void XMLDocumentParser::comment(const String& text)
exitText();
- RefPtr<Comment> newNode = Comment::create(m_currentNode->document(), text);
- m_currentNode->parserAppendChild(newNode.get());
+ m_currentNode->parserAppendChild(Comment::create(m_currentNode->document(), text));
}
enum StandaloneInfo {
@@ -1208,7 +1199,7 @@ enum StandaloneInfo {
void XMLDocumentParser::startDocument(const String& version, const String& encoding, int standalone)
{
- StandaloneInfo standaloneInfo = (StandaloneInfo)standalone;
+ StandaloneInfo standaloneInfo = static_cast<StandaloneInfo>(standalone);
if (standaloneInfo == NoXMlDeclaration) {
document()->setHasXMLDeclaration(false);
return;
@@ -1283,7 +1274,7 @@ static void warningHandler(void* closure, const char* message, ...)
{
va_list args;
va_start(args, message);
- getParser(closure)->error(XMLErrors::warning, message, args);
+ getParser(closure)->error(XMLErrors::ErrorTypeWarning, message, args);
va_end(args);
}
@@ -1292,7 +1283,7 @@ static void fatalErrorHandler(void* closure, const char* message, ...)
{
va_list args;
va_start(args, message);
- getParser(closure)->error(XMLErrors::fatal, message, args);
+ getParser(closure)->error(XMLErrors::ErrorTypeFatal, message, args);
va_end(args);
}
@@ -1301,12 +1292,12 @@ static void normalErrorHandler(void* closure, const char* message, ...)
{
va_list args;
va_start(args, message);
- getParser(closure)->error(XMLErrors::nonFatal, message, args);
+ getParser(closure)->error(XMLErrors::ErrorTypeNonFatal, message, args);
va_end(args);
}
-// Using a static entity and marking it XML_INTERNAL_PREDEFINED_ENTITY is
-// a hack to avoid malloc/free. Using a global variable like this could cause trouble
+// Using a static entity and marking it XML_INTERNAL_PREDEFINED_ENTITY is a hack
+// to avoid malloc/free. Using a global variable like this could cause trouble
// if libxml implementation details were to change
static xmlChar sharedXHTMLEntityResult[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -1398,22 +1389,24 @@ static void internalSubsetHandler(void* closure, const xmlChar* name, const xmlC
static void externalSubsetHandler(void* closure, const xmlChar*, const xmlChar* externalId, const xmlChar*)
{
String extId = toString(externalId);
- if ((extId == "-//W3C//DTD XHTML 1.0 Transitional//EN")
- || (extId == "-//W3C//DTD XHTML 1.1//EN")
- || (extId == "-//W3C//DTD XHTML 1.0 Strict//EN")
- || (extId == "-//W3C//DTD XHTML 1.0 Frameset//EN")
- || (extId == "-//W3C//DTD XHTML Basic 1.0//EN")
- || (extId == "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN")
- || (extId == "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN")
- || (extId == "-//WAPFORUM//DTD XHTML Mobile 1.0//EN")
- || (extId == "-//WAPFORUM//DTD XHTML Mobile 1.1//EN")
- || (extId == "-//WAPFORUM//DTD XHTML Mobile 1.2//EN"))
- getParser(closure)->setIsXHTMLDocument(true); // controls if we replace entities or not.
+ if (extId == "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ || extId == "-//W3C//DTD XHTML 1.1//EN"
+ || extId == "-//W3C//DTD XHTML 1.0 Strict//EN"
+ || extId == "-//W3C//DTD XHTML 1.0 Frameset//EN"
+ || extId == "-//W3C//DTD XHTML Basic 1.0//EN"
+ || extId == "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN"
+ || extId == "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
+ || extId == "-//WAPFORUM//DTD XHTML Mobile 1.0//EN"
+ || extId == "-//WAPFORUM//DTD XHTML Mobile 1.1//EN"
+ || extId == "-//WAPFORUM//DTD XHTML Mobile 1.2//EN") {
+ // Controls if we replace entities or not.
+ getParser(closure)->setIsXHTMLDocument(true);
+ }
}
static void ignorableWhitespaceHandler(void*, const xmlChar*, int)
{
- // nothing to do, but we need this to work around a crasher
+ // Nothing to do, but we need this to work around a crasher.
// http://bugzilla.gnome.org/show_bug.cgi?id=172255
// http://bugs.webkit.org/show_bug.cgi?id=5792
}
@@ -1447,9 +1440,9 @@ void XMLDocumentParser::initializeParserContext(const CString& chunk)
m_sawFirstElement = false;
XMLDocumentParserScope scope(document()->fetcher());
- if (m_parsingFragment)
+ if (m_parsingFragment) {
m_context = XMLParserContext::createMemoryParser(&sax, this, chunk);
- else {
+ } else {
ASSERT(!chunk.data());
m_context = XMLParserContext::createStringParser(&sax, this);
}
@@ -1465,7 +1458,7 @@ void XMLDocumentParser::doEnd()
finishParsing(context());
}
- m_context = 0;
+ m_context = nullptr;
}
}
@@ -1476,12 +1469,12 @@ void XMLDocumentParser::doEnd()
} else if (m_sawXSLTransform) {
xmlDocPtr doc = xmlDocPtrForString(document()->fetcher(), m_originalSourceForTransform.toString(), document()->url().string());
document()->setTransformSource(adoptPtr(new TransformSource(doc)));
+ // Make the document think it's done, so it will apply XSL stylesheets.
+ document()->setParsing(false);
+ document()->styleResolverChanged();
- document()->setParsing(false); // Make the document think it's done, so it will apply XSL stylesheets.
- document()->styleResolverChanged(RecalcStyleImmediately);
-
- // styleResolverChanged() call can detach the parser and null out its document.
- // In that case, we just bail out.
+ // styleResolverChanged() call can detach the parser and null out its
+ // document. In that case, we just bail out.
if (isDetached())
return;
@@ -1495,8 +1488,8 @@ xmlDocPtr xmlDocPtrForString(ResourceFetcher* fetcher, const String& source, con
if (source.isEmpty())
return 0;
// Parse in a single chunk into an xmlDocPtr
- // FIXME: Hook up error handlers so that a failure to parse the main document results in
- // good error messages.
+ // FIXME: Hook up error handlers so that a failure to parse the main
+ // document results in good error messages.
XMLDocumentParserScope scope(fetcher, errorFunc, 0);
XMLParserInput input(source);
return xmlReadMemory(input.data(), input.size(), url.latin1().data(), input.encoding(), XSLT_PARSE_OPTIONS);
@@ -1517,8 +1510,7 @@ TextPosition XMLDocumentParser::textPosition() const
xmlParserCtxtPtr context = this->context();
if (!context)
return TextPosition::minimumPosition();
- return TextPosition(OrdinalNumber::fromOneBasedInt(context->input->line),
- OrdinalNumber::fromOneBasedInt(context->input->col));
+ return TextPosition(OrdinalNumber::fromOneBasedInt(context->input->line), OrdinalNumber::fromOneBasedInt(context->input->col));
}
void XMLDocumentParser::stopParsing()
@@ -1566,7 +1558,8 @@ bool XMLDocumentParser::appendFragmentSource(const String& chunk)
CString chunkAsUtf8 = chunk.utf8();
- // libxml2 takes an int for a length, and therefore can't handle XML chunks larger than 2 GiB.
+ // libxml2 takes an int for a length, and therefore can't handle XML chunks
+ // larger than 2 GiB.
if (chunkAsUtf8.length() > INT_MAX)
return false;
@@ -1574,13 +1567,16 @@ bool XMLDocumentParser::appendFragmentSource(const String& chunk)
xmlParseContent(context());
endDocument(); // Close any open text nodes.
- // FIXME: If this code is actually needed, it should probably move to finish()
- // XMLDocumentParserQt has a similar check (m_stream.error() == QXmlStreamReader::PrematureEndOfDocumentError) in doEnd().
- // Check if all the chunk has been processed.
+ // FIXME: If this code is actually needed, it should probably move to
+ // finish()
+ // XMLDocumentParserQt has a similar check (m_stream.error() ==
+ // QXmlStreamReader::PrematureEndOfDocumentError) in doEnd(). Check if all
+ // the chunk has been processed.
long bytesProcessed = xmlByteConsumed(context());
- if (bytesProcessed == -1 || ((unsigned long)bytesProcessed) != chunkAsUtf8.length()) {
- // FIXME: I don't believe we can hit this case without also having seen an error or a null byte.
- // If we hit this ASSERT, we've found a test case which demonstrates the need for this code.
+ if (bytesProcessed == -1 || static_cast<unsigned long>(bytesProcessed) != chunkAsUtf8.length()) {
+ // FIXME: I don't believe we can hit this case without also having seen
+ // an error or a null byte. If we hit this ASSERT, we've found a test
+ // case which demonstrates the need for this code.
ASSERT(m_sawError || (bytesProcessed >= 0 && !chunkAsUtf8.data()[bytesProcessed]));
return false;
}
@@ -1609,7 +1605,7 @@ static void attributesStartElementNsHandler(void* closure, const xmlChar* xmlLoc
state->gotAttributes = true;
xmlSAX2Attributes* attributes = reinterpret_cast<xmlSAX2Attributes*>(libxmlAttributes);
- for (int i = 0; i < nbAttributes; i++) {
+ for (int i = 0; i < nbAttributes; ++i) {
String attrLocalName = toString(attributes[i].localname);
int valueLength = (int) (attributes[i].end - attributes[i].value);
String attrValue = toString(attributes[i].value, valueLength);
diff --git a/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h b/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h
index 2db50a0b7e2..917f87f73f8 100644
--- a/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h
+++ b/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h
@@ -30,6 +30,7 @@
#include "core/fetch/ResourceClient.h"
#include "core/fetch/ResourcePtr.h"
#include "core/xml/XMLErrors.h"
+#include "platform/heap/Handle.h"
#include "platform/text/SegmentedString.h"
#include "wtf/HashMap.h"
#include "wtf/OwnPtr.h"
@@ -48,151 +49,151 @@ class Element;
class FrameView;
class Text;
- class XMLParserContext : public RefCounted<XMLParserContext> {
+class XMLParserContext : public RefCounted<XMLParserContext> {
+public:
+ static PassRefPtr<XMLParserContext> createMemoryParser(xmlSAXHandlerPtr, void* userData, const CString& chunk);
+ static PassRefPtr<XMLParserContext> createStringParser(xmlSAXHandlerPtr, void* userData);
+ ~XMLParserContext();
+ xmlParserCtxtPtr context() const { return m_context; }
+
+private:
+ XMLParserContext(xmlParserCtxtPtr context)
+ : m_context(context)
+ {
+ }
+
+ xmlParserCtxtPtr m_context;
+};
+
+class XMLDocumentParser FINAL : public ScriptableDocumentParser, public ResourceClient {
+ WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+public:
+ static PassRefPtrWillBeRawPtr<XMLDocumentParser> create(Document& document, FrameView* view)
+ {
+ return adoptRefWillBeNoop(new XMLDocumentParser(document, view));
+ }
+ static PassRefPtrWillBeRawPtr<XMLDocumentParser> create(DocumentFragment* fragment, Element* element, ParserContentPolicy parserContentPolicy)
+ {
+ return adoptRefWillBeNoop(new XMLDocumentParser(fragment, element, parserContentPolicy));
+ }
+ virtual ~XMLDocumentParser();
+ virtual void trace(Visitor*) OVERRIDE;
+
+ // Exposed for callbacks:
+ void handleError(XMLErrors::ErrorType, const char* message, TextPosition);
+
+ void setIsXHTMLDocument(bool isXHTML) { m_isXHTMLDocument = isXHTML; }
+ bool isXHTMLDocument() const { return m_isXHTMLDocument; }
+
+ bool isCurrentlyParsing8BitChunk() { return m_isCurrentlyParsing8BitChunk; }
+
+ static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, ParserContentPolicy = AllowScriptingContent);
+
+ // Used by the XMLHttpRequest to check if the responseXML was well formed.
+ virtual bool wellFormed() const OVERRIDE { return !m_sawError; }
+
+ virtual TextPosition textPosition() const OVERRIDE;
+
+ static bool supportsXMLVersion(const String&);
+
+ class PendingCallback {
public:
- static PassRefPtr<XMLParserContext> createMemoryParser(xmlSAXHandlerPtr, void* userData, const CString& chunk);
- static PassRefPtr<XMLParserContext> createStringParser(xmlSAXHandlerPtr, void* userData);
- ~XMLParserContext();
- xmlParserCtxtPtr context() const { return m_context; }
-
- private:
- XMLParserContext(xmlParserCtxtPtr context)
- : m_context(context)
- {
- }
- xmlParserCtxtPtr m_context;
+ virtual ~PendingCallback() { }
+ virtual void call(XMLDocumentParser*) = 0;
};
- class XMLDocumentParser : public ScriptableDocumentParser, public ResourceClient {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- static PassRefPtr<XMLDocumentParser> create(Document* document, FrameView* view)
- {
- return adoptRef(new XMLDocumentParser(document, view));
- }
- static PassRefPtr<XMLDocumentParser> create(DocumentFragment* fragment, Element* element, ParserContentPolicy parserContentPolicy)
- {
- return adoptRef(new XMLDocumentParser(fragment, element, parserContentPolicy));
- }
+private:
+ explicit XMLDocumentParser(Document&, FrameView* = 0);
+ XMLDocumentParser(DocumentFragment*, Element*, ParserContentPolicy);
- ~XMLDocumentParser();
+ // From DocumentParser
+ virtual void insert(const SegmentedString&) OVERRIDE;
+ virtual void append(PassRefPtr<StringImpl>) OVERRIDE;
+ virtual void finish() OVERRIDE;
+ virtual bool isWaitingForScripts() const OVERRIDE;
+ virtual void stopParsing() OVERRIDE;
+ virtual void detach() OVERRIDE;
+ virtual OrdinalNumber lineNumber() const OVERRIDE;
+ OrdinalNumber columnNumber() const;
- // Exposed for callbacks:
- void handleError(XMLErrors::ErrorType, const char* message, TextPosition);
+ // from ResourceClient
+ virtual void notifyFinished(Resource*) OVERRIDE;
- void setIsXHTMLDocument(bool isXHTML) { m_isXHTMLDocument = isXHTML; }
- bool isXHTMLDocument() const { return m_isXHTMLDocument; }
+ void end();
- bool isCurrentlyParsing8BitChunk() { return m_isCurrentlyParsing8BitChunk; }
+ void pauseParsing();
+ void resumeParsing();
- static bool parseDocumentFragment(const String&, DocumentFragment*, Element* parent = 0, ParserContentPolicy = AllowScriptingContent);
+ bool appendFragmentSource(const String&);
- // Used by the XMLHttpRequest to check if the responseXML was well formed.
- virtual bool wellFormed() const { return !m_sawError; }
+public:
+ // Callbacks from parser SAX
+ void error(XMLErrors::ErrorType, const char* message, va_list args) WTF_ATTRIBUTE_PRINTF(3, 0);
+ void startElementNs(const AtomicString& localName, const AtomicString& prefix, const AtomicString& uri, int namespaceCount,
+ const xmlChar** namespaces, int attributeCount, int defaultedCount, const xmlChar** libxmlAttributes);
+ void endElementNs();
+ void characters(const xmlChar* chars, int length);
+ void processingInstruction(const String& target, const String& data);
+ void cdataBlock(const String&);
+ void comment(const String&);
+ void startDocument(const String& version, const String& encoding, int standalone);
+ void internalSubset(const String& name, const String& externalID, const String& systemID);
+ void endDocument();
- TextPosition textPosition() const;
+private:
+ void initializeParserContext(const CString& chunk = CString());
- static bool supportsXMLVersion(const String&);
+ void pushCurrentNode(ContainerNode*);
+ void popCurrentNode();
+ void clearCurrentNodeStack();
- class PendingCallback {
- public:
- virtual ~PendingCallback() { }
- virtual void call(XMLDocumentParser*) = 0;
- };
+ void insertErrorMessageBlock();
- private:
- XMLDocumentParser(Document*, FrameView* = 0);
- XMLDocumentParser(DocumentFragment*, Element*, ParserContentPolicy);
+ void enterText();
+ void exitText();
- // From DocumentParser
- virtual void insert(const SegmentedString&);
- virtual void append(PassRefPtr<StringImpl>);
- virtual void finish();
- virtual bool isWaitingForScripts() const;
- virtual void stopParsing();
- virtual void detach();
- virtual OrdinalNumber lineNumber() const;
- OrdinalNumber columnNumber() const;
+ void doWrite(const String&);
+ void doEnd();
- // from ResourceClient
- virtual void notifyFinished(Resource*);
+ bool m_hasView;
- void end();
+ SegmentedString m_originalSourceForTransform;
- void pauseParsing();
- void resumeParsing();
+ xmlParserCtxtPtr context() const { return m_context ? m_context->context() : 0; };
+ RefPtr<XMLParserContext> m_context;
+ Deque<OwnPtr<PendingCallback> > m_pendingCallbacks;
+ Vector<xmlChar> m_bufferedText;
- bool appendFragmentSource(const String&);
+ RawPtrWillBeMember<ContainerNode> m_currentNode;
+ WillBeHeapVector<RawPtrWillBeMember<ContainerNode> > m_currentNodeStack;
- public:
- // callbacks from parser SAX
- void error(XMLErrors::ErrorType, const char* message, va_list args) WTF_ATTRIBUTE_PRINTF(3, 0);
- void startElementNs(const AtomicString& localName, const AtomicString& prefix, const AtomicString& uri, int nb_namespaces,
- const xmlChar** namespaces, int nb_attributes, int nb_defaulted, const xmlChar** libxmlAttributes);
- void endElementNs();
- void characters(const xmlChar* chars, int length);
- void processingInstruction(const String& target, const String& data);
- void cdataBlock(const String&);
- void comment(const String&);
- void startDocument(const String& version, const String& encoding, int standalone);
- void internalSubset(const String& name, const String& externalID, const String& systemID);
- void endDocument();
-
- private:
- void initializeParserContext(const CString& chunk = CString());
-
- void pushCurrentNode(ContainerNode*);
- void popCurrentNode();
- void clearCurrentNodeStack();
-
- void insertErrorMessageBlock();
-
- void enterText();
- void exitText();
-
- void doWrite(const String&);
- void doEnd();
-
- FrameView* m_view;
-
- SegmentedString m_originalSourceForTransform;
-
- xmlParserCtxtPtr context() const { return m_context ? m_context->context() : 0; };
- RefPtr<XMLParserContext> m_context;
- Deque<OwnPtr<PendingCallback> > m_pendingCallbacks;
- Vector<xmlChar> m_bufferedText;
-
- ContainerNode* m_currentNode;
- Vector<ContainerNode*> m_currentNodeStack;
-
- RefPtr<Text> m_leafTextNode;
-
- bool m_isCurrentlyParsing8BitChunk;
- bool m_sawError;
- bool m_sawCSS;
- bool m_sawXSLTransform;
- bool m_sawFirstElement;
- bool m_isXHTMLDocument;
- bool m_parserPaused;
- bool m_requestingScript;
- bool m_finishCalled;
-
- XMLErrors m_xmlErrors;
-
- ResourcePtr<ScriptResource> m_pendingScript;
- RefPtr<Element> m_scriptElement;
- TextPosition m_scriptStartPosition;
-
- bool m_parsingFragment;
- AtomicString m_defaultNamespaceURI;
-
- typedef HashMap<AtomicString, AtomicString> PrefixForNamespaceMap;
- PrefixForNamespaceMap m_prefixToNamespaceMap;
- SegmentedString m_pendingSrc;
- };
+ RefPtrWillBeMember<Text> m_leafTextNode;
-xmlDocPtr xmlDocPtrForString(ResourceFetcher*, const String& source, const String& url);
+ bool m_isCurrentlyParsing8BitChunk;
+ bool m_sawError;
+ bool m_sawCSS;
+ bool m_sawXSLTransform;
+ bool m_sawFirstElement;
+ bool m_isXHTMLDocument;
+ bool m_parserPaused;
+ bool m_requestingScript;
+ bool m_finishCalled;
+ XMLErrors m_xmlErrors;
+
+ ResourcePtr<ScriptResource> m_pendingScript;
+ RefPtrWillBeMember<Element> m_scriptElement;
+ TextPosition m_scriptStartPosition;
+
+ bool m_parsingFragment;
+ AtomicString m_defaultNamespaceURI;
+
+ typedef HashMap<AtomicString, AtomicString> PrefixForNamespaceMap;
+ PrefixForNamespaceMap m_prefixToNamespaceMap;
+ SegmentedString m_pendingSrc;
+};
+
+xmlDocPtr xmlDocPtrForString(ResourceFetcher*, const String& source, const String& url);
HashMap<String, String> parseAttributes(const String&, bool& attrsOK);
} // namespace WebCore
diff --git a/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.h b/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.h
index 613d165cb27..4b06862c8b8 100644
--- a/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.h
+++ b/chromium/third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.h
@@ -33,23 +33,22 @@ namespace WebCore {
class ResourceFetcher;
- class XMLDocumentParserScope {
- WTF_MAKE_NONCOPYABLE(XMLDocumentParserScope);
- public:
- XMLDocumentParserScope(ResourceFetcher*);
- ~XMLDocumentParserScope();
-
- static ResourceFetcher* currentFetcher;
-
- XMLDocumentParserScope(ResourceFetcher*, xmlGenericErrorFunc, xmlStructuredErrorFunc = 0, void* errorContext = 0);
-
- private:
- ResourceFetcher* m_oldFetcher;
-
- xmlGenericErrorFunc m_oldGenericErrorFunc;
- xmlStructuredErrorFunc m_oldStructuredErrorFunc;
- void* m_oldErrorContext;
- };
+class XMLDocumentParserScope {
+ WTF_MAKE_NONCOPYABLE(XMLDocumentParserScope);
+public:
+ explicit XMLDocumentParserScope(ResourceFetcher*);
+ XMLDocumentParserScope(ResourceFetcher*, xmlGenericErrorFunc, xmlStructuredErrorFunc = 0, void* errorContext = 0);
+ ~XMLDocumentParserScope();
+
+ static ResourceFetcher* currentFetcher;
+
+private:
+ ResourceFetcher* m_oldFetcher;
+
+ xmlGenericErrorFunc m_oldGenericErrorFunc;
+ xmlStructuredErrorFunc m_oldStructuredErrorFunc;
+ void* m_oldErrorContext;
+};
} // namespace WebCore